Initial slang.

Change-Id: I4f84a741e5fbc440cd4c251406d2b611a237f713
diff --git a/Android.mk b/Android.mk
new file mode 100644
index 0000000..78aca54
--- /dev/null
+++ b/Android.mk
@@ -0,0 +1,19 @@
+LOCAL_PATH := $(call my-dir)
+CLANG_ROOT_PATH := $(LOCAL_PATH)
+
+include $(CLEAR_VARS)
+
+subdirs := $(addprefix $(LOCAL_PATH)/,$(addsuffix /Android.mk, \
+		lib/Basic	\
+		lib/Lex	\
+		lib/Parse	\
+		lib/AST	\
+		lib/Sema	\
+		lib/CodeGen	\
+		lib/Analysis	\
+		lib/Index	\
+	))
+
+include $(LOCAL_PATH)/clang.mk
+
+include $(subdirs)
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..1be646d
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,135 @@
+# Clang version information
+
+# Make sure that CMake reconfigures when the version changes.
+configure_file(
+  ${CMAKE_CURRENT_SOURCE_DIR}/VER
+  ${CMAKE_CURRENT_BINARY_DIR}/VER)
+
+set(CLANG_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
+set(CLANG_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
+
+if( CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR AND NOT MSVC_IDE )
+  message(FATAL_ERROR "In-source builds are not allowed. CMake would overwrite "
+"the makefiles distributed with LLVM. Please create a directory and run cmake "
+"from there, passing the path to this source directory as the last argument. "
+"This process created the file `CMakeCache.txt' and the directory "
+"`CMakeFiles'. Please delete them.")
+endif()
+
+if( NOT CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR )
+  file(GLOB_RECURSE
+    tablegenned_files_on_include_dir
+    "${CLANG_SOURCE_DIR}/include/clang/*.inc")
+  if( tablegenned_files_on_include_dir )
+    message(FATAL_ERROR "Apparently there is a previous in-source build, "
+"probably as the result of running `configure' and `make' on "
+"${CLANG_SOURCE_DIR}. This may cause problems. The suspicious files are:\n"
+"${tablegenned_files_on_include_dir}\nPlease clean the source directory.")
+  endif()
+endif()
+
+# Compute the Clang version from the contents of VER
+file(READ ${CMAKE_CURRENT_SOURCE_DIR}/VER CLANG_VERSION_DATA)
+string(REGEX MATCH "[0-9]+\\.[0-9]+(\\.[0-9]+)?" CLANG_VERSION 
+  ${CLANG_VERSION_DATA})
+message(STATUS "Clang version: ${CLANG_VERSION}")
+
+# Add appropriate flags for GCC
+if (CMAKE_COMPILER_IS_GNUCXX)
+  # FIXME: Turn off exceptions, RTTI:
+  # -fno-exceptions -fno-rtti
+  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-common -Woverloaded-virtual -pedantic -Wno-long-long -Wall -W -Wno-unused-parameter -Wwrite-strings")
+endif ()
+
+macro(add_clang_library name)
+  set(srcs ${ARGN})
+  if(MSVC_IDE OR XCODE)
+    file( GLOB_RECURSE headers *.h *.td *.def)
+    set(srcs ${srcs} ${headers})
+    string( REGEX MATCHALL "/[^/]+" split_path ${CMAKE_CURRENT_SOURCE_DIR})
+    list( GET split_path -1 dir)
+    file( GLOB_RECURSE headers 
+      ../../include/clang${dir}/*.h
+      ../../include/clang${dir}/*.td
+      ../../include/clang${dir}/*.def)
+    set(srcs ${srcs} ${headers})
+  endif(MSVC_IDE OR XCODE)
+  if (SHARED_LIBRARY)
+    set(libkind SHARED)
+  else()
+    set(libkind)
+  endif()
+  add_library( ${name} ${libkind} ${srcs} )
+  if( LLVM_COMMON_DEPENDS )
+    add_dependencies( ${name} ${LLVM_COMMON_DEPENDS} )
+  endif( LLVM_COMMON_DEPENDS )
+  if( LLVM_USED_LIBS )
+    foreach(lib ${LLVM_USED_LIBS})
+      target_link_libraries( ${name} ${lib} )
+    endforeach(lib)
+  endif( LLVM_USED_LIBS )
+  if( LLVM_LINK_COMPONENTS )
+    llvm_config(${name} ${LLVM_LINK_COMPONENTS})
+  endif( LLVM_LINK_COMPONENTS )
+  get_system_libs(llvm_system_libs)
+  if( llvm_system_libs )
+    target_link_libraries(${name} ${llvm_system_libs})
+  endif( llvm_system_libs )
+  add_dependencies(${name} ClangDiagnosticCommon)
+  if(MSVC)
+    get_target_property(cflag ${name} COMPILE_FLAGS)
+    if(NOT cflag)
+      set(cflag "")
+    endif(NOT cflag)
+    set(cflag "${cflag} /Za")
+    set_target_properties(${name} PROPERTIES COMPILE_FLAGS ${cflag})
+  endif(MSVC)
+  install(TARGETS ${name}
+    LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX}
+    ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX})
+endmacro(add_clang_library)
+
+macro(add_clang_executable name)
+  set(srcs ${ARGN})
+  if(MSVC_IDE)
+    file( GLOB_RECURSE headers *.h *.td *.def)
+    set(srcs ${srcs} ${headers})
+  endif(MSVC_IDE)
+  add_llvm_executable( ${name} ${srcs} )
+endmacro(add_clang_executable)
+
+include_directories(
+  ${CMAKE_CURRENT_SOURCE_DIR}/include
+  ${CMAKE_CURRENT_BINARY_DIR}/include
+  )
+
+install(DIRECTORY include/
+  DESTINATION include
+  FILES_MATCHING
+  PATTERN "*.def"
+  PATTERN "*.h"
+  PATTERN "*.td"
+  PATTERN ".svn" EXCLUDE
+  )
+
+install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include/
+  DESTINATION include
+  FILES_MATCHING
+  PATTERN "CMakeFiles" EXCLUDE
+  PATTERN "*.inc"
+  )
+
+add_definitions( -D_GNU_SOURCE )
+
+option(CLANG_BUILD_EXAMPLES "Build CLANG example programs." OFF)
+if(CLANG_BUILD_EXAMPLES)
+  add_subdirectory(examples)
+endif ()
+
+add_subdirectory(include)
+add_subdirectory(lib)
+add_subdirectory(tools)
+
+# TODO: docs.
+add_subdirectory(test)
+
diff --git a/INPUTS/Cocoa_h.m b/INPUTS/Cocoa_h.m
new file mode 100644
index 0000000..e6ba599
--- /dev/null
+++ b/INPUTS/Cocoa_h.m
@@ -0,0 +1,2 @@
+
+#import <Cocoa/Cocoa.h>
diff --git a/INPUTS/all-std-headers.cpp b/INPUTS/all-std-headers.cpp
new file mode 100644
index 0000000..bddf4ec
--- /dev/null
+++ b/INPUTS/all-std-headers.cpp
@@ -0,0 +1,51 @@
+#include <algorithm> 
+#include <bitset> 
+#include <cassert>
+#include <cctype>
+#include <cerrno>
+#include <cfloat>
+#include <ciso646>
+#include <climits>
+#include <clocale>
+#include <cmath>
+#include <complex>
+#include <csetjmp>
+#include <csignal>
+#include <cstdarg>
+#include <cstddef>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <ctime>
+#include <cwchar>
+#include <cwctype>
+#include <deque>
+#include <exception>
+#include <fstream> 
+#include <functional> 
+#include <iomanip> 
+#include <ios> 
+#include <iosfwd>
+#include <iostream>
+#include <istream>
+#include <iterator>
+#include <limits> 
+#include <list> 
+#include <locale> 
+#include <map>
+#include <memory>
+#include <new>
+#include <numeric> 
+#include <ostream>
+#include <queue> 
+#include <set> 
+#include <sstream>
+#include <stack>
+#include <stdexcept>
+#include <streambuf>
+#include <string>
+#include <strstream> 
+#include <typeinfo>
+#include <utility>
+#include <valarray>
+#include <vector>
diff --git a/INPUTS/c99-intconst-1.c b/INPUTS/c99-intconst-1.c
new file mode 100644
index 0000000..629b0bc
--- /dev/null
+++ b/INPUTS/c99-intconst-1.c
@@ -0,0 +1,639 @@
+/* Test for integer constant types.  */
+
+/* Origin: Joseph Myers <jsm28@cam.ac.uk>.  */
+/* { dg-do compile } */
+/* { dg-options "-std=iso9899:1999 -pedantic-errors" } */
+
+#include <limits.h>
+
+/* Assertion that constant C is of type T.  */
+#define ASSERT_CONST_TYPE(C, T)			\
+	do {					\
+	  typedef T type;			\
+	  typedef type **typepp;		\
+	  typedef __typeof__((C)) ctype;	\
+	  typedef ctype **ctypepp;		\
+	  typepp x = 0;				\
+	  ctypepp y = 0;			\
+	  x = y;				\
+	  y = x;				\
+	} while (0)
+
+/* (T *) if E is zero, (void *) otherwise.  */
+#define type_if_not(T, E) __typeof__(0 ? (T *)0 : (void *)(E))
+
+/* (T *) if E is nonzero, (void *) otherwise.  */
+#define type_if(T, E) type_if_not(T, !(E))
+
+/* Combine pointer types, all but one (void *).  */
+#define type_comb2(T1, T2) __typeof__(0 ? (T1)0 : (T2)0)
+#define type_comb3(T1, T2, T3) type_comb2(T1, type_comb2(T2, T3))
+#define type_comb4(T1, T2, T3, T4)				\
+	type_comb2(T1, type_comb2(T2, type_comb2(T3, T4)))
+#define type_comb6(T1, T2, T3, T4, T5, T6)				   \
+	type_comb2(T1,							   \
+		   type_comb2(T2,					   \
+			      type_comb2(T3,				   \
+					 type_comb2(T4,			   \
+						    type_comb2(T5, T6)))))
+
+/* (T1 *) if E1, otherwise (T2 *) if E2.  */
+#define first_of2p(T1, E1, T2, E2) type_comb2(type_if(T1, (E1)),	   \
+					     type_if(T2, (!(E1) && (E2))))
+/* (T1 *) if E1, otherwise (T2 *) if E2, otherwise (T3 *) if E3.  */
+#define first_of3p(T1, E1, T2, E2, T3, E3)			\
+	type_comb3(type_if(T1, (E1)),				\
+		   type_if(T2, (!(E1) && (E2))),		\
+		   type_if(T3, (!(E1) && !(E2) && (E3))))
+/* (T1 *) if E1, otherwise (T2 *) if E2, otherwise (T3 *) if E3, otherwise
+   (T4 *) if E4.  */
+#define first_of4p(T1, E1, T2, E2, T3, E3, T4, E4)			\
+	type_comb4(type_if(T1, (E1)),					\
+		   type_if(T2, (!(E1) && (E2))),			\
+		   type_if(T3, (!(E1) && !(E2) && (E3))),		\
+		   type_if(T4, (!(E1) && !(E2) && !(E3) && (E4))))
+/* (T1 *) if E1, otherwise (T2 *) if E2, otherwise (T3 *) if E3, otherwise
+   (T4 *) if E4, otherwise (T5 *) if E5, otherwise (T6 *) if E6.  */
+#define first_of6p(T1, E1, T2, E2, T3, E3, T4, E4, T5, E5, T6, E6)	    \
+	type_comb6(type_if(T1, (E1)),					    \
+		   type_if(T2, (!(E1) && (E2))),			    \
+		   type_if(T3, (!(E1) && !(E2) && (E3))),		    \
+		   type_if(T4, (!(E1) && !(E2) && !(E3) && (E4))),	    \
+		   type_if(T5, (!(E1) && !(E2) && !(E3) && !(E4) && (E5))), \
+		   type_if(T6, (!(E1) && !(E2) && !(E3)			    \
+				&& !(E4) && !(E5) && (E6))))
+
+/* Likewise, but return the original type rather than a pointer type.  */
+#define first_of2(T1, E1, T2, E2)			\
+	__typeof__(*((first_of2p(T1, (E1), T2, (E2)))0))
+#define first_of3(T1, E1, T2, E2, T3, E3)				\
+	__typeof__(*((first_of3p(T1, (E1), T2, (E2), T3, (E3)))0))
+#define first_of4(T1, E1, T2, E2, T3, E3, T4, E4)			    \
+	__typeof__(*((first_of4p(T1, (E1), T2, (E2), T3, (E3), T4, (E4)))0))
+#define first_of6(T1, E1, T2, E2, T3, E3, T4, E4, T5, E5, T6, E6)	\
+	__typeof__(*((first_of6p(T1, (E1), T2, (E2), T3, (E3),		\
+				 T4, (E4), T5, (E5), T6, (E6)))0))
+
+/* Types of constants according to the C99 rules.  */
+#define C99_UNSUF_DEC_TYPE(C)				\
+	first_of3(int, (C) <= INT_MAX,			\
+		  long int, (C) <= LONG_MAX,		\
+		  long long int, (C) <= LLONG_MAX)
+#define C99_UNSUF_OCTHEX_TYPE(C)				\
+	first_of6(int, (C) <= INT_MAX,				\
+		  unsigned int, (C) <= UINT_MAX,		\
+		  long int, (C) <= LONG_MAX,			\
+		  unsigned long int, (C) <= ULONG_MAX,		\
+		  long long int, (C) <= LLONG_MAX,		\
+		  unsigned long long int, (C) <= ULLONG_MAX)
+#define C99_SUFu_TYPE(C)					\
+	first_of3(unsigned int, (C) <= UINT_MAX,		\
+		  unsigned long int, (C) <= ULONG_MAX,		\
+		  unsigned long long int, (C) <= ULLONG_MAX)
+#define C99_SUFl_DEC_TYPE(C)				\
+	first_of2(long int, (C) <= LONG_MAX,		\
+		  long long int, (C) <= LLONG_MAX)
+#define C99_SUFl_OCTHEX_TYPE(C)					\
+	first_of4(long int, (C) <= LONG_MAX,			\
+		  unsigned long int, (C) <= ULONG_MAX,		\
+		  long long int, (C) <= LLONG_MAX,		\
+		  unsigned long long int, (C) <= ULLONG_MAX)
+#define C99_SUFul_TYPE(C)					\
+	first_of2(unsigned long int, (C) <= ULONG_MAX,		\
+		  unsigned long long int, (C) <= ULLONG_MAX)
+#define C99_SUFll_OCTHEX_TYPE(C)				\
+	first_of2(long long int, (C) <= LLONG_MAX,		\
+		  unsigned long long int, (C) <= ULLONG_MAX)
+
+/* Checks that constants have correct type.  */
+#define CHECK_UNSUF_DEC_TYPE(C) ASSERT_CONST_TYPE((C), C99_UNSUF_DEC_TYPE((C)))
+#define CHECK_UNSUF_OCTHEX_TYPE(C)				\
+	ASSERT_CONST_TYPE((C), C99_UNSUF_OCTHEX_TYPE((C)))
+#define CHECK_SUFu_TYPE(C) ASSERT_CONST_TYPE((C), C99_SUFu_TYPE((C)))
+#define CHECK_SUFl_DEC_TYPE(C) ASSERT_CONST_TYPE((C), C99_SUFl_DEC_TYPE((C)))
+#define CHECK_SUFl_OCTHEX_TYPE(C)				\
+	ASSERT_CONST_TYPE((C), C99_SUFl_OCTHEX_TYPE((C)))
+#define CHECK_SUFul_TYPE(C) ASSERT_CONST_TYPE((C), C99_SUFul_TYPE((C)))
+#define CHECK_SUFll_DEC_TYPE(C) ASSERT_CONST_TYPE((C), long long int)
+#define CHECK_SUFll_OCTHEX_TYPE(C)				\
+	ASSERT_CONST_TYPE((C), C99_SUFll_OCTHEX_TYPE((C)))
+#define CHECK_SUFull_TYPE(C) ASSERT_CONST_TYPE((C), unsigned long long int)
+
+/* Check a decimal value, with all suffixes.  */
+#define CHECK_DEC_CONST(C)			\
+	CHECK_UNSUF_DEC_TYPE(C);		\
+	CHECK_SUFu_TYPE(C##u);			\
+	CHECK_SUFu_TYPE(C##U);			\
+	CHECK_SUFl_DEC_TYPE(C##l);		\
+	CHECK_SUFl_DEC_TYPE(C##L);		\
+	CHECK_SUFul_TYPE(C##ul);		\
+	CHECK_SUFul_TYPE(C##uL);		\
+	CHECK_SUFul_TYPE(C##Ul);		\
+	CHECK_SUFul_TYPE(C##UL);		\
+	CHECK_SUFll_DEC_TYPE(C##ll);		\
+	CHECK_SUFll_DEC_TYPE(C##LL);		\
+	CHECK_SUFull_TYPE(C##ull);		\
+	CHECK_SUFull_TYPE(C##uLL);		\
+	CHECK_SUFull_TYPE(C##Ull);		\
+	CHECK_SUFull_TYPE(C##ULL);
+
+/* Check an octal or hexadecimal value, with all suffixes.  */
+#define CHECK_OCTHEX_CONST(C)			\
+	CHECK_UNSUF_OCTHEX_TYPE(C);		\
+	CHECK_SUFu_TYPE(C##u);			\
+	CHECK_SUFu_TYPE(C##U);			\
+	CHECK_SUFl_OCTHEX_TYPE(C##l);		\
+	CHECK_SUFl_OCTHEX_TYPE(C##L);		\
+	CHECK_SUFul_TYPE(C##ul);		\
+	CHECK_SUFul_TYPE(C##uL);		\
+	CHECK_SUFul_TYPE(C##Ul);		\
+	CHECK_SUFul_TYPE(C##UL);		\
+	CHECK_SUFll_OCTHEX_TYPE(C##ll);		\
+	CHECK_SUFll_OCTHEX_TYPE(C##LL);		\
+	CHECK_SUFull_TYPE(C##ull);		\
+	CHECK_SUFull_TYPE(C##uLL);		\
+	CHECK_SUFull_TYPE(C##Ull);		\
+	CHECK_SUFull_TYPE(C##ULL);
+
+#define CHECK_OCT_CONST(C) CHECK_OCTHEX_CONST(C)
+#define CHECK_HEX_CONST(C)			\
+	CHECK_OCTHEX_CONST(0x##C);		\
+	CHECK_OCTHEX_CONST(0X##C);
+
+/* True iff "long long" is at least B bits.  This presumes that (B-2)/3 is at
+   most 63.  */
+#define LLONG_AT_LEAST(B)			\
+	(LLONG_MAX >> ((B)-2)/3 >> ((B)-2)/3	\
+	 >> ((B)-2 - ((B)-2)/3 - ((B)-2)/3))
+
+#define LLONG_HAS_BITS(B) (LLONG_AT_LEAST((B)) && !LLONG_AT_LEAST((B) + 1))
+
+void
+foo (void)
+{
+  /* Decimal.  */
+  /* Check all 2^n and 2^n - 1 up to 2^71 - 1.  */
+  CHECK_DEC_CONST(1);
+  CHECK_DEC_CONST(2);
+  CHECK_DEC_CONST(3);
+  CHECK_DEC_CONST(4);
+  CHECK_DEC_CONST(7);
+  CHECK_DEC_CONST(8);
+  CHECK_DEC_CONST(15);
+  CHECK_DEC_CONST(16);
+  CHECK_DEC_CONST(31);
+  CHECK_DEC_CONST(32);
+  CHECK_DEC_CONST(63);
+  CHECK_DEC_CONST(64);
+  CHECK_DEC_CONST(127);
+  CHECK_DEC_CONST(128);
+  CHECK_DEC_CONST(255);
+  CHECK_DEC_CONST(256);
+  CHECK_DEC_CONST(511);
+  CHECK_DEC_CONST(512);
+  CHECK_DEC_CONST(1023);
+  CHECK_DEC_CONST(1024);
+  CHECK_DEC_CONST(2047);
+  CHECK_DEC_CONST(2048);
+  CHECK_DEC_CONST(4095);
+  CHECK_DEC_CONST(4096);
+  CHECK_DEC_CONST(8191);
+  CHECK_DEC_CONST(8192);
+  CHECK_DEC_CONST(16383);
+  CHECK_DEC_CONST(16384);
+  CHECK_DEC_CONST(32767);
+  CHECK_DEC_CONST(32768);
+  CHECK_DEC_CONST(65535);
+  CHECK_DEC_CONST(65536);
+  CHECK_DEC_CONST(131071);
+  CHECK_DEC_CONST(131072);
+  CHECK_DEC_CONST(262143);
+  CHECK_DEC_CONST(262144);
+  CHECK_DEC_CONST(524287);
+  CHECK_DEC_CONST(524288);
+  CHECK_DEC_CONST(1048575);
+  CHECK_DEC_CONST(1048576);
+  CHECK_DEC_CONST(2097151);
+  CHECK_DEC_CONST(2097152);
+  CHECK_DEC_CONST(4194303);
+  CHECK_DEC_CONST(4194304);
+  CHECK_DEC_CONST(8388607);
+  CHECK_DEC_CONST(8388608);
+  CHECK_DEC_CONST(16777215);
+  CHECK_DEC_CONST(16777216);
+  CHECK_DEC_CONST(33554431);
+  CHECK_DEC_CONST(33554432);
+  CHECK_DEC_CONST(67108863);
+  CHECK_DEC_CONST(67108864);
+  CHECK_DEC_CONST(134217727);
+  CHECK_DEC_CONST(134217728);
+  CHECK_DEC_CONST(268435455);
+  CHECK_DEC_CONST(268435456);
+  CHECK_DEC_CONST(536870911);
+  CHECK_DEC_CONST(536870912);
+  CHECK_DEC_CONST(1073741823);
+  CHECK_DEC_CONST(1073741824);
+  CHECK_DEC_CONST(2147483647);
+  CHECK_DEC_CONST(2147483648);
+  CHECK_DEC_CONST(4294967295);
+  CHECK_DEC_CONST(4294967296);
+  CHECK_DEC_CONST(8589934591);
+  CHECK_DEC_CONST(8589934592);
+  CHECK_DEC_CONST(17179869183);
+  CHECK_DEC_CONST(17179869184);
+  CHECK_DEC_CONST(34359738367);
+  CHECK_DEC_CONST(34359738368);
+  CHECK_DEC_CONST(68719476735);
+  CHECK_DEC_CONST(68719476736);
+  CHECK_DEC_CONST(137438953471);
+  CHECK_DEC_CONST(137438953472);
+  CHECK_DEC_CONST(274877906943);
+  CHECK_DEC_CONST(274877906944);
+  CHECK_DEC_CONST(549755813887);
+  CHECK_DEC_CONST(549755813888);
+  CHECK_DEC_CONST(1099511627775);
+  CHECK_DEC_CONST(1099511627776);
+  CHECK_DEC_CONST(2199023255551);
+  CHECK_DEC_CONST(2199023255552);
+  CHECK_DEC_CONST(4398046511103);
+  CHECK_DEC_CONST(4398046511104);
+  CHECK_DEC_CONST(8796093022207);
+  CHECK_DEC_CONST(8796093022208);
+  CHECK_DEC_CONST(17592186044415);
+  CHECK_DEC_CONST(17592186044416);
+  CHECK_DEC_CONST(35184372088831);
+  CHECK_DEC_CONST(35184372088832);
+  CHECK_DEC_CONST(70368744177663);
+  CHECK_DEC_CONST(70368744177664);
+  CHECK_DEC_CONST(140737488355327);
+  CHECK_DEC_CONST(140737488355328);
+  CHECK_DEC_CONST(281474976710655);
+  CHECK_DEC_CONST(281474976710656);
+  CHECK_DEC_CONST(562949953421311);
+  CHECK_DEC_CONST(562949953421312);
+  CHECK_DEC_CONST(1125899906842623);
+  CHECK_DEC_CONST(1125899906842624);
+  CHECK_DEC_CONST(2251799813685247);
+  CHECK_DEC_CONST(2251799813685248);
+  CHECK_DEC_CONST(4503599627370495);
+  CHECK_DEC_CONST(4503599627370496);
+  CHECK_DEC_CONST(9007199254740991);
+  CHECK_DEC_CONST(9007199254740992);
+  CHECK_DEC_CONST(18014398509481983);
+  CHECK_DEC_CONST(18014398509481984);
+  CHECK_DEC_CONST(36028797018963967);
+  CHECK_DEC_CONST(36028797018963968);
+  CHECK_DEC_CONST(72057594037927935);
+  CHECK_DEC_CONST(72057594037927936);
+  CHECK_DEC_CONST(144115188075855871);
+  CHECK_DEC_CONST(144115188075855872);
+  CHECK_DEC_CONST(288230376151711743);
+  CHECK_DEC_CONST(288230376151711744);
+  CHECK_DEC_CONST(576460752303423487);
+  CHECK_DEC_CONST(576460752303423488);
+  CHECK_DEC_CONST(1152921504606846975);
+  CHECK_DEC_CONST(1152921504606846976);
+  CHECK_DEC_CONST(2305843009213693951);
+  CHECK_DEC_CONST(2305843009213693952);
+  CHECK_DEC_CONST(4611686018427387903);
+  CHECK_DEC_CONST(4611686018427387904);
+  CHECK_DEC_CONST(9223372036854775807);
+#if LLONG_AT_LEAST(65)
+  CHECK_DEC_CONST(9223372036854775808);
+  CHECK_DEC_CONST(18446744073709551615);
+#endif
+#if LLONG_AT_LEAST(66)
+  CHECK_DEC_CONST(18446744073709551616);
+  CHECK_DEC_CONST(36893488147419103231);
+#endif
+#if LLONG_AT_LEAST(67)
+  CHECK_DEC_CONST(36893488147419103232);
+  CHECK_DEC_CONST(73786976294838206463);
+#endif
+#if LLONG_AT_LEAST(68)
+  CHECK_DEC_CONST(73786976294838206464);
+  CHECK_DEC_CONST(147573952589676412927);
+#endif
+#if LLONG_AT_LEAST(69)
+  CHECK_DEC_CONST(147573952589676412928);
+  CHECK_DEC_CONST(295147905179352825855);
+#endif
+#if LLONG_AT_LEAST(70)
+  CHECK_DEC_CONST(295147905179352825856);
+  CHECK_DEC_CONST(590295810358705651711);
+#endif
+#if LLONG_AT_LEAST(71)
+  CHECK_DEC_CONST(590295810358705651712);
+  CHECK_DEC_CONST(1180591620717411303423);
+#endif
+#if LLONG_AT_LEAST(72)
+  CHECK_DEC_CONST(1180591620717411303424);
+  CHECK_DEC_CONST(2361183241434822606847);
+#endif
+  /* Octal and hexadecimal.  */
+  /* Check all 2^n and 2^n - 1 up to 2^72 - 1.  */
+  CHECK_OCT_CONST(0);
+  CHECK_HEX_CONST(0);
+  CHECK_OCT_CONST(01);
+  CHECK_HEX_CONST(1);
+  CHECK_OCT_CONST(02);
+  CHECK_HEX_CONST(2);
+  CHECK_OCT_CONST(03);
+  CHECK_HEX_CONST(3);
+  CHECK_OCT_CONST(04);
+  CHECK_HEX_CONST(4);
+  CHECK_OCT_CONST(07);
+  CHECK_HEX_CONST(7);
+  CHECK_OCT_CONST(010);
+  CHECK_HEX_CONST(8);
+  CHECK_OCT_CONST(017);
+  CHECK_HEX_CONST(f);
+  CHECK_OCT_CONST(020);
+  CHECK_HEX_CONST(10);
+  CHECK_OCT_CONST(037);
+  CHECK_HEX_CONST(1f);
+  CHECK_OCT_CONST(040);
+  CHECK_HEX_CONST(20);
+  CHECK_OCT_CONST(077);
+  CHECK_HEX_CONST(3f);
+  CHECK_OCT_CONST(0100);
+  CHECK_HEX_CONST(40);
+  CHECK_OCT_CONST(0177);
+  CHECK_HEX_CONST(7f);
+  CHECK_OCT_CONST(0200);
+  CHECK_HEX_CONST(80);
+  CHECK_OCT_CONST(0377);
+  CHECK_HEX_CONST(ff);
+  CHECK_OCT_CONST(0400);
+  CHECK_HEX_CONST(100);
+  CHECK_OCT_CONST(0777);
+  CHECK_HEX_CONST(1ff);
+  CHECK_OCT_CONST(01000);
+  CHECK_HEX_CONST(200);
+  CHECK_OCT_CONST(01777);
+  CHECK_HEX_CONST(3ff);
+  CHECK_OCT_CONST(02000);
+  CHECK_HEX_CONST(400);
+  CHECK_OCT_CONST(03777);
+  CHECK_HEX_CONST(7ff);
+  CHECK_OCT_CONST(04000);
+  CHECK_HEX_CONST(800);
+  CHECK_OCT_CONST(07777);
+  CHECK_HEX_CONST(fff);
+  CHECK_OCT_CONST(010000);
+  CHECK_HEX_CONST(1000);
+  CHECK_OCT_CONST(017777);
+  CHECK_HEX_CONST(1fff);
+  CHECK_OCT_CONST(020000);
+  CHECK_HEX_CONST(2000);
+  CHECK_OCT_CONST(037777);
+  CHECK_HEX_CONST(3fff);
+  CHECK_OCT_CONST(040000);
+  CHECK_HEX_CONST(4000);
+  CHECK_OCT_CONST(077777);
+  CHECK_HEX_CONST(7fff);
+  CHECK_OCT_CONST(0100000);
+  CHECK_HEX_CONST(8000);
+  CHECK_OCT_CONST(0177777);
+  CHECK_HEX_CONST(ffff);
+  CHECK_OCT_CONST(0200000);
+  CHECK_HEX_CONST(10000);
+  CHECK_OCT_CONST(0377777);
+  CHECK_HEX_CONST(1ffff);
+  CHECK_OCT_CONST(0400000);
+  CHECK_HEX_CONST(20000);
+  CHECK_OCT_CONST(0777777);
+  CHECK_HEX_CONST(3ffff);
+  CHECK_OCT_CONST(01000000);
+  CHECK_HEX_CONST(40000);
+  CHECK_OCT_CONST(01777777);
+  CHECK_HEX_CONST(7ffff);
+  CHECK_OCT_CONST(02000000);
+  CHECK_HEX_CONST(80000);
+  CHECK_OCT_CONST(03777777);
+  CHECK_HEX_CONST(fffff);
+  CHECK_OCT_CONST(04000000);
+  CHECK_HEX_CONST(100000);
+  CHECK_OCT_CONST(07777777);
+  CHECK_HEX_CONST(1fffff);
+  CHECK_OCT_CONST(010000000);
+  CHECK_HEX_CONST(200000);
+  CHECK_OCT_CONST(017777777);
+  CHECK_HEX_CONST(3fffff);
+  CHECK_OCT_CONST(020000000);
+  CHECK_HEX_CONST(400000);
+  CHECK_OCT_CONST(037777777);
+  CHECK_HEX_CONST(7fffff);
+  CHECK_OCT_CONST(040000000);
+  CHECK_HEX_CONST(800000);
+  CHECK_OCT_CONST(077777777);
+  CHECK_HEX_CONST(ffffff);
+  CHECK_OCT_CONST(0100000000);
+  CHECK_HEX_CONST(1000000);
+  CHECK_OCT_CONST(0177777777);
+  CHECK_HEX_CONST(1ffffff);
+  CHECK_OCT_CONST(0200000000);
+  CHECK_HEX_CONST(2000000);
+  CHECK_OCT_CONST(0377777777);
+  CHECK_HEX_CONST(3ffffff);
+  CHECK_OCT_CONST(0400000000);
+  CHECK_HEX_CONST(4000000);
+  CHECK_OCT_CONST(0777777777);
+  CHECK_HEX_CONST(7ffffff);
+  CHECK_OCT_CONST(01000000000);
+  CHECK_HEX_CONST(8000000);
+  CHECK_OCT_CONST(01777777777);
+  CHECK_HEX_CONST(fffffff);
+  CHECK_OCT_CONST(02000000000);
+  CHECK_HEX_CONST(10000000);
+  CHECK_OCT_CONST(03777777777);
+  CHECK_HEX_CONST(1fffffff);
+  CHECK_OCT_CONST(04000000000);
+  CHECK_HEX_CONST(20000000);
+  CHECK_OCT_CONST(07777777777);
+  CHECK_HEX_CONST(3fffffff);
+  CHECK_OCT_CONST(010000000000);
+  CHECK_HEX_CONST(40000000);
+  CHECK_OCT_CONST(017777777777);
+  CHECK_HEX_CONST(7fffffff);
+  CHECK_OCT_CONST(020000000000);
+  CHECK_HEX_CONST(80000000);
+  CHECK_OCT_CONST(037777777777);
+  CHECK_HEX_CONST(ffffffff);
+  CHECK_OCT_CONST(040000000000);
+  CHECK_HEX_CONST(100000000);
+  CHECK_OCT_CONST(077777777777);
+  CHECK_HEX_CONST(1ffffffff);
+  CHECK_OCT_CONST(0100000000000);
+  CHECK_HEX_CONST(200000000);
+  CHECK_OCT_CONST(0177777777777);
+  CHECK_HEX_CONST(3ffffffff);
+  CHECK_OCT_CONST(0200000000000);
+  CHECK_HEX_CONST(400000000);
+  CHECK_OCT_CONST(0377777777777);
+  CHECK_HEX_CONST(7ffffffff);
+  CHECK_OCT_CONST(0400000000000);
+  CHECK_HEX_CONST(800000000);
+  CHECK_OCT_CONST(0777777777777);
+  CHECK_HEX_CONST(fffffffff);
+  CHECK_OCT_CONST(01000000000000);
+  CHECK_HEX_CONST(1000000000);
+  CHECK_OCT_CONST(01777777777777);
+  CHECK_HEX_CONST(1fffffffff);
+  CHECK_OCT_CONST(02000000000000);
+  CHECK_HEX_CONST(2000000000);
+  CHECK_OCT_CONST(03777777777777);
+  CHECK_HEX_CONST(3fffffffff);
+  CHECK_OCT_CONST(04000000000000);
+  CHECK_HEX_CONST(4000000000);
+  CHECK_OCT_CONST(07777777777777);
+  CHECK_HEX_CONST(7fffffffff);
+  CHECK_OCT_CONST(010000000000000);
+  CHECK_HEX_CONST(8000000000);
+  CHECK_OCT_CONST(017777777777777);
+  CHECK_HEX_CONST(ffffffffff);
+  CHECK_OCT_CONST(020000000000000);
+  CHECK_HEX_CONST(10000000000);
+  CHECK_OCT_CONST(037777777777777);
+  CHECK_HEX_CONST(1ffffffffff);
+  CHECK_OCT_CONST(040000000000000);
+  CHECK_HEX_CONST(20000000000);
+  CHECK_OCT_CONST(077777777777777);
+  CHECK_HEX_CONST(3ffffffffff);
+  CHECK_OCT_CONST(0100000000000000);
+  CHECK_HEX_CONST(40000000000);
+  CHECK_OCT_CONST(0177777777777777);
+  CHECK_HEX_CONST(7ffffffffff);
+  CHECK_OCT_CONST(0200000000000000);
+  CHECK_HEX_CONST(80000000000);
+  CHECK_OCT_CONST(0377777777777777);
+  CHECK_HEX_CONST(fffffffffff);
+  CHECK_OCT_CONST(0400000000000000);
+  CHECK_HEX_CONST(100000000000);
+  CHECK_OCT_CONST(0777777777777777);
+  CHECK_HEX_CONST(1fffffffffff);
+  CHECK_OCT_CONST(01000000000000000);
+  CHECK_HEX_CONST(200000000000);
+  CHECK_OCT_CONST(01777777777777777);
+  CHECK_HEX_CONST(3fffffffffff);
+  CHECK_OCT_CONST(02000000000000000);
+  CHECK_HEX_CONST(400000000000);
+  CHECK_OCT_CONST(03777777777777777);
+  CHECK_HEX_CONST(7fffffffffff);
+  CHECK_OCT_CONST(04000000000000000);
+  CHECK_HEX_CONST(800000000000);
+  CHECK_OCT_CONST(07777777777777777);
+  CHECK_HEX_CONST(ffffffffffff);
+  CHECK_OCT_CONST(010000000000000000);
+  CHECK_HEX_CONST(1000000000000);
+  CHECK_OCT_CONST(017777777777777777);
+  CHECK_HEX_CONST(1ffffffffffff);
+  CHECK_OCT_CONST(020000000000000000);
+  CHECK_HEX_CONST(2000000000000);
+  CHECK_OCT_CONST(037777777777777777);
+  CHECK_HEX_CONST(3ffffffffffff);
+  CHECK_OCT_CONST(040000000000000000);
+  CHECK_HEX_CONST(4000000000000);
+  CHECK_OCT_CONST(077777777777777777);
+  CHECK_HEX_CONST(7ffffffffffff);
+  CHECK_OCT_CONST(0100000000000000000);
+  CHECK_HEX_CONST(8000000000000);
+  CHECK_OCT_CONST(0177777777777777777);
+  CHECK_HEX_CONST(fffffffffffff);
+  CHECK_OCT_CONST(0200000000000000000);
+  CHECK_HEX_CONST(10000000000000);
+  CHECK_OCT_CONST(0377777777777777777);
+  CHECK_HEX_CONST(1fffffffffffff);
+  CHECK_OCT_CONST(0400000000000000000);
+  CHECK_HEX_CONST(20000000000000);
+  CHECK_OCT_CONST(0777777777777777777);
+  CHECK_HEX_CONST(3fffffffffffff);
+  CHECK_OCT_CONST(01000000000000000000);
+  CHECK_HEX_CONST(40000000000000);
+  CHECK_OCT_CONST(01777777777777777777);
+  CHECK_HEX_CONST(7fffffffffffff);
+  CHECK_OCT_CONST(02000000000000000000);
+  CHECK_HEX_CONST(80000000000000);
+  CHECK_OCT_CONST(03777777777777777777);
+  CHECK_HEX_CONST(ffffffffffffff);
+  CHECK_OCT_CONST(04000000000000000000);
+  CHECK_HEX_CONST(100000000000000);
+  CHECK_OCT_CONST(07777777777777777777);
+  CHECK_HEX_CONST(1ffffffffffffff);
+  CHECK_OCT_CONST(010000000000000000000);
+  CHECK_HEX_CONST(200000000000000);
+  CHECK_OCT_CONST(017777777777777777777);
+  CHECK_HEX_CONST(3ffffffffffffff);
+  CHECK_OCT_CONST(020000000000000000000);
+  CHECK_HEX_CONST(400000000000000);
+  CHECK_OCT_CONST(037777777777777777777);
+  CHECK_HEX_CONST(7ffffffffffffff);
+  CHECK_OCT_CONST(040000000000000000000);
+  CHECK_HEX_CONST(800000000000000);
+  CHECK_OCT_CONST(077777777777777777777);
+  CHECK_HEX_CONST(fffffffffffffff);
+  CHECK_OCT_CONST(0100000000000000000000);
+  CHECK_HEX_CONST(1000000000000000);
+  CHECK_OCT_CONST(0177777777777777777777);
+  CHECK_HEX_CONST(1fffffffffffffff);
+  CHECK_OCT_CONST(0200000000000000000000);
+  CHECK_HEX_CONST(2000000000000000);
+  CHECK_OCT_CONST(0377777777777777777777);
+  CHECK_HEX_CONST(3fffffffffffffff);
+  CHECK_OCT_CONST(0400000000000000000000);
+  CHECK_HEX_CONST(4000000000000000);
+  CHECK_OCT_CONST(0777777777777777777777);
+  CHECK_HEX_CONST(7fffffffffffffff);
+  CHECK_OCT_CONST(01000000000000000000000);
+  CHECK_HEX_CONST(8000000000000000);
+  CHECK_OCT_CONST(01777777777777777777777);
+  CHECK_HEX_CONST(ffffffffffffffff);
+#if LLONG_AT_LEAST(65)
+  CHECK_OCT_CONST(02000000000000000000000);
+  CHECK_HEX_CONST(10000000000000000);
+  CHECK_OCT_CONST(03777777777777777777777);
+  CHECK_HEX_CONST(1ffffffffffffffff);
+#endif
+#if LLONG_AT_LEAST(66)
+  CHECK_OCT_CONST(04000000000000000000000);
+  CHECK_HEX_CONST(20000000000000000);
+  CHECK_OCT_CONST(07777777777777777777777);
+  CHECK_HEX_CONST(3ffffffffffffffff);
+#endif
+#if LLONG_AT_LEAST(67)
+  CHECK_OCT_CONST(010000000000000000000000);
+  CHECK_HEX_CONST(40000000000000000);
+  CHECK_OCT_CONST(017777777777777777777777);
+  CHECK_HEX_CONST(7ffffffffffffffff);
+#endif
+#if LLONG_AT_LEAST(68)
+  CHECK_OCT_CONST(020000000000000000000000);
+  CHECK_HEX_CONST(80000000000000000);
+  CHECK_OCT_CONST(037777777777777777777777);
+  CHECK_HEX_CONST(fffffffffffffffff);
+#endif
+#if LLONG_AT_LEAST(69)
+  CHECK_OCT_CONST(040000000000000000000000);
+  CHECK_HEX_CONST(100000000000000000);
+  CHECK_OCT_CONST(077777777777777777777777);
+  CHECK_HEX_CONST(1fffffffffffffffff);
+#endif
+#if LLONG_AT_LEAST(70)
+  CHECK_OCT_CONST(0100000000000000000000000);
+  CHECK_HEX_CONST(200000000000000000);
+  CHECK_OCT_CONST(0177777777777777777777777);
+  CHECK_HEX_CONST(3fffffffffffffffff);
+#endif
+#if LLONG_AT_LEAST(71)
+  CHECK_OCT_CONST(0200000000000000000000000);
+  CHECK_HEX_CONST(400000000000000000);
+  CHECK_OCT_CONST(0377777777777777777777777);
+  CHECK_HEX_CONST(7fffffffffffffffff);
+#endif
+#if LLONG_AT_LEAST(72)
+  CHECK_OCT_CONST(0400000000000000000000000);
+  CHECK_HEX_CONST(800000000000000000);
+  CHECK_OCT_CONST(0777777777777777777777777);
+  CHECK_HEX_CONST(ffffffffffffffffff);
+#endif
+}
diff --git a/INPUTS/carbon_h.c b/INPUTS/carbon_h.c
new file mode 100644
index 0000000..599f123
--- /dev/null
+++ b/INPUTS/carbon_h.c
@@ -0,0 +1,4 @@
+
+#include <Carbon/Carbon.h>
+
+//#import<vecLib/vecLib.h>
diff --git a/INPUTS/iostream.cc b/INPUTS/iostream.cc
new file mode 100644
index 0000000..eb12fc9
--- /dev/null
+++ b/INPUTS/iostream.cc
@@ -0,0 +1,5 @@
+// clang -I/usr/include/c++/4.0.0 -I/usr/include/c++/4.0.0/powerpc-apple-darwin8 -I/usr/include/c++/4.0.0/backward INPUTS/iostream.cc -Eonly
+
+#include <iostream>
+
+#include <stdint.h>
diff --git a/INPUTS/macro_pounder_fn.c b/INPUTS/macro_pounder_fn.c
new file mode 100644
index 0000000..73f40a1
--- /dev/null
+++ b/INPUTS/macro_pounder_fn.c
@@ -0,0 +1,17 @@
+
+// This pounds on macro expansion for performance reasons.  This is currently
+// heavily constrained by darwin's malloc.
+
+// Function-like macros.
+#define A0(A, B) A B
+#define A1(A, B) A0(A,B) A0(A,B) A0(A,B) A0(A,B) A0(A,B) A0(A,B)
+#define A2(A, B) A1(A,B) A1(A,B) A1(A,B) A1(A,B) A1(A,B) A1(A,B)
+#define A3(A, B) A2(A,B) A2(A,B) A2(A,B) A2(A,B) A2(A,B) A2(A,B)
+#define A4(A, B) A3(A,B) A3(A,B) A3(A,B) A3(A,B) A3(A,B) A3(A,B)
+#define A5(A, B) A4(A,B) A4(A,B) A4(A,B) A4(A,B) A4(A,B) A4(A,B)
+#define A6(A, B) A5(A,B) A5(A,B) A5(A,B) A5(A,B) A5(A,B) A5(A,B)
+#define A7(A, B) A6(A,B) A6(A,B) A6(A,B) A6(A,B) A6(A,B) A6(A,B)
+#define A8(A, B) A7(A,B) A7(A,B) A7(A,B) A7(A,B) A7(A,B) A7(A,B)
+
+A8(a, b)
+
diff --git a/INPUTS/macro_pounder_obj.c b/INPUTS/macro_pounder_obj.c
new file mode 100644
index 0000000..d2465f3
--- /dev/null
+++ b/INPUTS/macro_pounder_obj.c
@@ -0,0 +1,16 @@
+
+// This pounds on macro expansion for performance reasons.  This is currently
+// heavily constrained by darwin's malloc.
+
+// Object-like expansions
+#define A0 a b
+#define A1 A0 A0 A0 A0 A0 A0
+#define A2 A1 A1 A1 A1 A1 A1
+#define A3 A2 A2 A2 A2 A2 A2
+#define A4 A3 A3 A3 A3 A3 A3
+#define A5 A4 A4 A4 A4 A4 A4
+#define A6 A5 A5 A5 A5 A5 A5
+#define A7 A6 A6 A6 A6 A6 A6
+#define A8 A7 A7 A7 A7 A7 A7
+
+A8
diff --git a/INPUTS/stpcpy-test.c b/INPUTS/stpcpy-test.c
new file mode 100644
index 0000000..b96a806
--- /dev/null
+++ b/INPUTS/stpcpy-test.c
@@ -0,0 +1,47 @@
+#define __extension__
+
+#define __stpcpy(dest, src) (__extension__ (__builtin_constant_p (src) ? (__string2_1bptr_p (src) && strlen (src) + 1 <= 8 ? __stpcpy_small (dest, __stpcpy_args (src), strlen (src) + 1) : ((char *) __mempcpy (dest, src, strlen (src) + 1) - 1)) : __stpcpy (dest, src)))
+#define stpcpy(dest, src) __stpcpy (dest, src)
+#define __stpcpy_args(src) __extension__ __STRING2_SMALL_GET16 (src, 0), __extension__ __STRING2_SMALL_GET16 (src, 4), __extension__ __STRING2_SMALL_GET32 (src, 0), __extension__ __STRING2_SMALL_GET32 (src, 4)
+
+#define __mempcpy(dest, src, n) (__extension__ (__builtin_constant_p (src) && __builtin_constant_p (n) && __string2_1bptr_p (src) && n <= 8 ? __mempcpy_small (dest, __mempcpy_args (src), n) : __mempcpy (dest, src, n)))
+#define mempcpy(dest, src, n) __mempcpy (dest, src, n)
+#define __mempcpy_args(src) ((char *) (src))[0], ((char *) (src))[2], ((char *) (src))[4], ((char *) (src))[6], __extension__ __STRING2_SMALL_GET16 (src, 0), __extension__ __STRING2_SMALL_GET16 (src, 4), __extension__ __STRING2_SMALL_GET32 (src, 0), __extension__ __STRING2_SMALL_GET32 (src, 4)
+
+#define __STRING2_SMALL_GET16(src, idx) (((__const unsigned char *) (__const char *) (src))[idx + 1] << 8 | ((__const unsigned char *) (__const char *) (src))[idx])
+
+#define __STRING2_SMALL_GET32(src, idx) (((((__const unsigned char *) (__const char *) (src))[idx + 3] << 8 | ((__const unsigned char *) (__const char *) (src))[idx + 2]) << 8 | ((__const unsigned char *) (__const char *) (src))[idx + 1]) << 8 | ((__const unsigned char *) (__const char *) (src))[idx])
+
+stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
+stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
+stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
+stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
+stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
+stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
+stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
+stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
+stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
+stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
+stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
+stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
+stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
+stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
+stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
+stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
+stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
+stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
+stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
+stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
+stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
+stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
+stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
+stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
+stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
+stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
+stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
+stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
+stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
+stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
+stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
+stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
+stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
diff --git a/INSTALL.txt b/INSTALL.txt
new file mode 100644
index 0000000..e8e3209
--- /dev/null
+++ b/INSTALL.txt
@@ -0,0 +1,49 @@
+//===----------------------------------------------------------------------===//
+// Clang Installation Instructions
+//===----------------------------------------------------------------------===//
+
+These instructions describe how to build and install Clang.
+
+//===----------------------------------------------------------------------===//
+// Step 1: Organization
+//===----------------------------------------------------------------------===//
+
+Clang is designed to be built as part of an LLVM build. Assuming that the LLVM
+source code is located at $LLVM_SRC_ROOT, then the clang source code should be
+installed as:
+
+  $LLVM_SRC_ROOT/tools/clang
+
+The directory is not required to be called clang, but doing so will allow the
+LLVM build system to automatically recognize it and build it along with LLVM.
+
+//===----------------------------------------------------------------------===//
+// Step 2: Configure and Build LLVM
+//===----------------------------------------------------------------------===//
+
+Configure and build your copy of LLVM (see $LLVM_SRC_ROOT/GettingStarted.html
+for more information).
+
+Assuming you installed clang at $LLVM_SRC_ROOT/tools/clang then Clang will
+automatically be built with LLVM. Otherwise, run 'make' in the Clang source
+directory to build Clang.
+
+//===----------------------------------------------------------------------===//
+// Step 3: (Optional) Verify Your Build
+//===----------------------------------------------------------------------===//
+
+It is a good idea to run the Clang tests to make sure your build works
+correctly. From inside the Clang build directory, run 'make test' to run the
+tests.
+
+//===----------------------------------------------------------------------===//
+// Step 4: Install Clang
+//===----------------------------------------------------------------------===//
+
+From inside the Clang build directory, run 'make install' to install the Clang
+compiler and header files into the prefix directory selected when LLVM was
+configured.
+
+The Clang compiler is available as 'clang' and supports a gcc like command line
+interface. See the man page for clang (installed into $prefix/share/man/man1)
+for more information.
diff --git a/LICENSE.TXT b/LICENSE.TXT
new file mode 100644
index 0000000..a378a5f
--- /dev/null
+++ b/LICENSE.TXT
@@ -0,0 +1,63 @@
+==============================================================================
+LLVM Release License
+==============================================================================
+University of Illinois/NCSA
+Open Source License
+
+Copyright (c) 2007-2010 University of Illinois at Urbana-Champaign.
+All rights reserved.
+
+Developed by:
+
+    LLVM Team
+
+    University of Illinois at Urbana-Champaign
+
+    http://llvm.org
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal with
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimers.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimers in the
+      documentation and/or other materials provided with the distribution.
+
+    * Neither the names of the LLVM Team, University of Illinois at
+      Urbana-Champaign, nor the names of its contributors may be used to
+      endorse or promote products derived from this Software without specific
+      prior written permission.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
+SOFTWARE.
+
+==============================================================================
+The LLVM software contains code written by third parties.  Such software will
+have its own individual LICENSE.TXT file in the directory in which it appears.
+This file will describe the copyrights, license, and restrictions which apply
+to that code.
+
+The disclaimer of warranty in the University of Illinois Open Source License
+applies to all code in the LLVM Distribution, and nothing in any of the
+other licenses gives permission to use the names of the LLVM Team or the
+University of Illinois to endorse or promote products derived from this
+Software.
+
+The following pieces of software have additional or alternate copyrights,
+licenses, and/or restrictions:
+
+Program             Directory
+-------             ---------
+<none yet>
+
diff --git a/MODULE_LICENSE_BSD_LIKE b/MODULE_LICENSE_BSD_LIKE
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/MODULE_LICENSE_BSD_LIKE
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..f7e9e85
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,66 @@
+LEVEL = ../..
+DIRS := include lib tools docs
+
+PARALLEL_DIRS :=
+
+ifeq ($(BUILD_EXAMPLES),1)
+  PARALLEL_DIRS += examples
+endif
+
+include $(LEVEL)/Makefile.common
+
+ifneq ($(PROJ_SRC_ROOT),$(PROJ_OBJ_ROOT))
+$(RecursiveTargets)::
+	$(Verb) if [ ! -f test/Makefile ]; then \
+	  $(MKDIR) test; \
+	  $(CP) $(PROJ_SRC_DIR)/test/Makefile test/Makefile; \
+	fi
+endif
+
+test::
+	@ $(MAKE) -C test
+
+report::
+	@ $(MAKE) -C test report
+
+clean::
+	@ $(MAKE) -C test clean
+
+tags::
+	$(Verb) etags `find . -type f -name '*.h' -or -name '*.cpp' | \
+	  grep -v /lib/Headers | grep -v /test/`
+
+cscope.files:
+	find tools lib include -name '*.cpp' \
+	                    -or -name '*.def' \
+	                    -or -name '*.td' \
+	                    -or -name '*.h' > cscope.files
+
+.PHONY: test report clean cscope.files
+
+install-local::
+	$(Echo) Installing include files
+	$(Verb) $(MKDIR) $(DESTDIR)$(PROJ_includedir)
+	$(Verb) if test -d "$(PROJ_SRC_ROOT)/tools/clang/include" ; then \
+	  cd $(PROJ_SRC_ROOT)/tools/clang/include && \
+	  for  hdr in `find . -type f '!' '(' -name '*~' \
+	      -o -name '.#*' -o -name '*.in' -o -name '*.txt' \
+	      -o -name 'Makefile' -o -name '*.td' ')' -print \
+              | grep -v CVS | grep -v .svn | grep -v .dir` ; do \
+	    instdir=$(DESTDIR)`dirname "$(PROJ_includedir)/$$hdr"` ; \
+	    if test \! -d "$$instdir" ; then \
+	      $(EchoCmd) Making install directory $$instdir ; \
+	      $(MKDIR) $$instdir ;\
+	    fi ; \
+	    $(DataInstall) $$hdr $(DESTDIR)$(PROJ_includedir)/$$hdr ; \
+	  done ; \
+	fi
+ifneq ($(PROJ_SRC_ROOT),$(PROJ_OBJ_ROOT))
+	$(Verb) if test -d "$(PROJ_OBJ_ROOT)/tools/clang/include" ; then \
+	  cd $(PROJ_OBJ_ROOT)/tools/clang/include && \
+	  for hdr in `find . -type f '!' '(' -name 'Makefile' ')' -print \
+            | grep -v CVS | grep -v .tmp | grep -v .dir` ; do \
+	    $(DataInstall) $$hdr $(DESTDIR)$(PROJ_includedir)/$$hdr ; \
+	  done ; \
+	fi
+endif
diff --git a/ModuleInfo.txt b/ModuleInfo.txt
new file mode 100644
index 0000000..4368ef0
--- /dev/null
+++ b/ModuleInfo.txt
@@ -0,0 +1,5 @@
+# This file provides information for llvm-top
+DepModule: llvm 
+ConfigCmd:
+ConfigTest:
+BuildCmd:
diff --git a/NOTES.txt b/NOTES.txt
new file mode 100644
index 0000000..beceb7d
--- /dev/null
+++ b/NOTES.txt
@@ -0,0 +1,86 @@
+//===---------------------------------------------------------------------===//
+// Random Notes
+//===---------------------------------------------------------------------===//
+
+C90/C99/C++ Comparisons:
+http://david.tribble.com/text/cdiffs.htm
+
+//===---------------------------------------------------------------------===//
+
+To time GCC preprocessing speed without output, use:
+   "time gcc -MM file"
+This is similar to -Eonly.
+
+//===---------------------------------------------------------------------===//
+
+Creating and using a PTH file for performance measurement (use a release-asserts
+build).
+
+$ clang -ccc-pch-is-pth -x objective-c-header INPUTS/Cocoa_h.m -o /tmp/tokencache
+$ clang -cc1 -token-cache /tmp/tokencache INPUTS/Cocoa_h.m
+
+//===---------------------------------------------------------------------===//
+
+  C++ Template Instantiation benchmark:
+     http://users.rcn.com/abrahams/instantiation_speed/index.html
+
+//===---------------------------------------------------------------------===//
+
+TODO: File Manager Speedup:
+
+ We currently do a lot of stat'ing for files that don't exist, particularly
+ when lots of -I paths exist (e.g. see the <iostream> example, check for
+ failures in stat in FileManager::getFile).  It would be far better to make
+ the following changes:
+   1. FileEntry contains a sys::Path instead of a std::string for Name.
+   2. sys::Path contains timestamp and size, lazily computed.  Eliminate from
+      FileEntry.
+   3. File UIDs are created on request, not when files are opened.
+ These changes make it possible to efficiently have FileEntry objects for
+ files that exist on the file system, but have not been used yet.
+ 
+ Once this is done:
+   1. DirectoryEntry gets a boolean value "has read entries".  When false, not
+      all entries in the directory are in the file mgr, when true, they are.
+   2. Instead of stat'ing the file in FileManager::getFile, check to see if 
+      the dir has been read.  If so, fail immediately, if not, read the dir,
+      then retry.
+   3. Reading the dir uses the getdirentries syscall, creating an FileEntry
+      for all files found.
+
+//===---------------------------------------------------------------------===//
+// Specifying targets:  -triple and -arch
+//===---------------------------------------------------------------------===//
+
+The clang supports "-triple" and "-arch" options. At most one -triple and one
+-arch option may be specified.  Both are optional.
+
+The "selection of target" behavior is defined as follows:
+
+(1) If the user does not specify -triple, we default to the host triple.
+(2) If the user specifies a -arch, that overrides the arch in the host or
+    specified triple. 
+
+//===---------------------------------------------------------------------===//
+
+
+verifyInputConstraint and verifyOutputConstraint should not return bool. 
+
+Instead we should return something like:
+
+enum VerifyConstraintResult {
+  Valid,
+  
+  // Output only
+  OutputOperandConstraintLacksEqualsCharacter,
+  MatchingConstraintNotValidInOutputOperand,
+
+  // Input only
+  InputOperandConstraintContainsEqualsCharacter,
+  MatchingConstraintReferencesInvalidOperandNumber,
+  
+  // Both
+  PercentConstraintUsedWithLastOperand
+};
+
+//===---------------------------------------------------------------------===//
diff --git a/NOTICE b/NOTICE
new file mode 100644
index 0000000..a378a5f
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,63 @@
+==============================================================================
+LLVM Release License
+==============================================================================
+University of Illinois/NCSA
+Open Source License
+
+Copyright (c) 2007-2010 University of Illinois at Urbana-Champaign.
+All rights reserved.
+
+Developed by:
+
+    LLVM Team
+
+    University of Illinois at Urbana-Champaign
+
+    http://llvm.org
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal with
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimers.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimers in the
+      documentation and/or other materials provided with the distribution.
+
+    * Neither the names of the LLVM Team, University of Illinois at
+      Urbana-Champaign, nor the names of its contributors may be used to
+      endorse or promote products derived from this Software without specific
+      prior written permission.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
+SOFTWARE.
+
+==============================================================================
+The LLVM software contains code written by third parties.  Such software will
+have its own individual LICENSE.TXT file in the directory in which it appears.
+This file will describe the copyrights, license, and restrictions which apply
+to that code.
+
+The disclaimer of warranty in the University of Illinois Open Source License
+applies to all code in the LLVM Distribution, and nothing in any of the
+other licenses gives permission to use the names of the LLVM Team or the
+University of Illinois to endorse or promote products derived from this
+Software.
+
+The following pieces of software have additional or alternate copyrights,
+licenses, and/or restrictions:
+
+Program             Directory
+-------             ---------
+<none yet>
+
diff --git a/README.txt b/README.txt
new file mode 100644
index 0000000..924ecc4
--- /dev/null
+++ b/README.txt
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+// C Language Family Front-end
+//===----------------------------------------------------------------------===//
+
+Welcome to Clang.  This is a compiler front-end for the C family of languages
+(C, C++, Objective-C, and Objective-C++) which is built as part of the LLVM
+compiler intrastructure project.
+
+Unlike many other compiler frontends, Clang is useful for a number of things
+beyond just compiling code: we intend for Clang to be host to a number of
+different source level tools.  One example of this is the Clang Static Analyzer.
+
+If you're interested in more (including how to build Clang) it is best to read
+the relevant web sites.  Here are some pointers:
+
+Information on Clang:              http://clang.llvm.org/
+Building and using Clang:          http://clang.llvm.org/get_started.html
+Clang Static Analyzer:             http://clang-analyzer.llvm.org/
+Information on the LLVM project:   http://llvm.org/
+
+If you have questions or comments about Clang, a great place to discuss them is
+on the Clang development mailing list:
+  http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
+
+If you find a bug in Clang, please file it in the LLVM bug tracker:
+  http://llvm.org/bugs/
diff --git a/TODO.txt b/TODO.txt
new file mode 100644
index 0000000..c63b1b3
--- /dev/null
+++ b/TODO.txt
@@ -0,0 +1,75 @@
+//===---------------------------------------------------------------------===//
+// Minor random things that can be improved
+//===---------------------------------------------------------------------===//
+   
+
+Warn about "X && 0x1000" saying that the user may mean "X & 0x1000".
+We should do this for any immediate except zero, so long as it doesn't come 
+from a macro expansion.  Likewise for ||.
+
+//===---------------------------------------------------------------------===//
+
+Lexer-related diagnostics should point to the problematic character, not the
+start of the token.  For example:
+
+int y = 0000\
+00080;
+
+diag.c:4:9: error: invalid digit '8' in octal constant
+int y = 0000\
+        ^
+
+should be:
+
+diag.c:4:9: error: invalid digit '8' in octal constant
+00080;
+   ^
+
+This specific diagnostic is implemented, but others should be updated.
+
+//===---------------------------------------------------------------------===//
+
+C++ (checker): For iterators, warn of the use of "iterator++" instead
+  of "++iterator" when when the value returned by operator++(int) is
+  ignored.
+
+//===---------------------------------------------------------------------===//
+
+We want to keep more source range information in Declarator to help
+produce better diagnostics. Declarator::getSourceRange() should be
+implemented to give a range for the whole declarator with all of its
+specifiers, and DeclaratorChunk::ParamInfo should also have a source
+range covering the whole parameter, so that an error message like this:
+
+overloaded-operator-decl.cpp:37:23: error: parameter of overloaded post-increment operator must have type 'int' (not 'float')
+X operator++(X&, const float& f); 
+                              ^
+can be turned into something like this:
+
+overloaded-operator-decl.cpp:37:23: error: parameter of overloaded post-increment operator must have type 'int' (not 'float')
+X operator++(X&, const float& f); 
+  ^              ~~~~~~~~~~~~~~
+
+//===---------------------------------------------------------------------===//
+
+For terminal output, we should consider limiting the amount of
+diagnostic text we print once the first error has been
+encountered. For example, once we have produced an error diagnostic,
+we should only continue producing diagnostics until we have produced a
+page full of results (say, 50 lines of text). Beyond that, (1) the
+remaining errors are likely to be less interesting, and (2) the poor
+user has to scroll his terminal to find out where things went wrong.
+
+//===---------------------------------------------------------------------===//
+More ideas for code modification hints:
+  - If no member of a given name is found in a class/struct, search through the names of entities that do exist in the class and suggest the closest candidate. e.g., if I write "DS.setTypeSpecType", it would suggest "DS.SetTypeSpecType" (edit distance = 1).
+  - If a class member is defined out-of-line but isn't in the class declaration (and there are no close matches!), provide the option to add an in-class declaration.
+  - Fix-it hints for the inclusion of headers when needed for particular features (e.g., <typeinfo> for typeid)
+
+//===---------------------------------------------------------------------===//
+
+Options to support:
+   -ftabstop=width
+   -fpreprocessed mode.
+   -nostdinc++
+   -imultilib
diff --git a/VER b/VER
new file mode 100644
index 0000000..c239c60
--- /dev/null
+++ b/VER
@@ -0,0 +1 @@
+1.5
diff --git a/bindings/python/README.txt b/bindings/python/README.txt
new file mode 100644
index 0000000..ccc2619
--- /dev/null
+++ b/bindings/python/README.txt
@@ -0,0 +1,18 @@
+//===----------------------------------------------------------------------===//
+// Clang Python Bindings
+//===----------------------------------------------------------------------===//
+
+This directory implements Python bindings for Clang. Currently, only bindings
+for the CIndex C API exist.
+
+You may need to alter LD_LIBRARY_PATH so that the CIndex library can be
+found. The unit tests are designed to be run with 'nosetests'. For example:
+--
+$ env PYTHONPATH=$(echo ~/llvm/tools/clang/bindings/python/) \
+      LD_LIBRARY_PATH=$(llvm-config --libdir) \
+  nosetests -v
+tests.cindex.test_index.test_create ... ok
+...
+
+OK
+--
diff --git a/bindings/python/clang/__init__.py b/bindings/python/clang/__init__.py
new file mode 100644
index 0000000..88f3081
--- /dev/null
+++ b/bindings/python/clang/__init__.py
@@ -0,0 +1,24 @@
+#===- __init__.py - Clang Python Bindings --------------------*- python -*--===#
+#
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+#===------------------------------------------------------------------------===#
+
+r"""
+Clang Library Bindings
+======================
+
+This package provides access to the Clang compiler and libraries.
+
+The available modules are:
+
+  cindex
+
+    Bindings for the Clang indexing library.
+"""
+
+__all__ = ['cindex']
+
diff --git a/bindings/python/clang/cindex.py b/bindings/python/clang/cindex.py
new file mode 100644
index 0000000..f4409ae
--- /dev/null
+++ b/bindings/python/clang/cindex.py
@@ -0,0 +1,935 @@
+#===- cindex.py - Python Indexing Library Bindings -----------*- python -*--===#
+#
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+#===------------------------------------------------------------------------===#
+
+r"""
+Clang Indexing Library Bindings
+===============================
+
+This module provides an interface to the Clang indexing library. It is a
+low-level interface to the indexing library which attempts to match the Clang
+API directly while also being "pythonic". Notable differences from the C API
+are:
+
+ * string results are returned as Python strings, not CXString objects.
+
+ * null cursors are translated to None.
+
+ * access to child cursors is done via iteration, not visitation.
+
+The major indexing objects are:
+
+  Index
+
+    The top-level object which manages some global library state.
+
+  TranslationUnit
+
+    High-level object encapsulating the AST for a single translation unit. These
+    can be loaded from .ast files or parsed on the fly.
+
+  Cursor
+
+    Generic object for representing a node in the AST.
+
+  SourceRange, SourceLocation, and File
+
+    Objects representing information about the input source.
+
+Most object information is exposed using properties, when the underlying API
+call is efficient.
+"""
+
+# TODO
+# ====
+#
+# o API support for invalid translation units. Currently we can't even get the
+#   diagnostics on failure because they refer to locations in an object that
+#   will have been invalidated.
+#
+# o fix memory management issues (currently client must hold on to index and
+#   translation unit, or risk crashes).
+#
+# o expose code completion APIs.
+#
+# o cleanup ctypes wrapping, would be nice to separate the ctypes details more
+#   clearly, and hide from the external interface (i.e., help(cindex)).
+#
+# o implement additional SourceLocation, SourceRange, and File methods.
+
+from ctypes import *
+
+def get_cindex_library():
+    # FIXME: It's probably not the case that the library is actually found in
+    # this location. We need a better system of identifying and loading the
+    # CIndex library. It could be on path or elsewhere, or versioned, etc.
+    import platform
+    name = platform.system()
+    if name == 'Darwin':
+        return cdll.LoadLibrary('libCIndex.dylib')
+    elif name == 'Windows':
+        return cdll.LoadLibrary('libCIndex.dll')
+    else:
+        return cdll.LoadLibrary('libCIndex.so')
+
+# ctypes doesn't implicitly convert c_void_p to the appropriate wrapper
+# object. This is a problem, because it means that from_parameter will see an
+# integer and pass the wrong value on platforms where int != void*. Work around
+# this by marshalling object arguments as void**.
+c_object_p = POINTER(c_void_p)
+
+lib = get_cindex_library()
+
+### Structures and Utility Classes ###
+
+class _CXString(Structure):
+    """Helper for transforming CXString results."""
+
+    _fields_ = [("spelling", c_char_p), ("free", c_int)]
+
+    def __del__(self):
+        _CXString_dispose(self)
+
+    @staticmethod
+    def from_result(res, fn, args):
+        assert isinstance(res, _CXString)
+        return _CXString_getCString(res)
+
+class SourceLocation(Structure):
+    """
+    A SourceLocation represents a particular location within a source file.
+    """
+    _fields_ = [("ptr_data", c_void_p * 2), ("int_data", c_uint)]
+    _data = None
+
+    def _get_instantiation(self):
+        if self._data is None:
+            f, l, c, o = c_object_p(), c_uint(), c_uint(), c_uint()
+            SourceLocation_loc(self, byref(f), byref(l), byref(c), byref(o))
+            f = File(f) if f else None
+            self._data = (f, int(l.value), int(c.value), int(c.value))
+        return self._data
+
+    @property
+    def file(self):
+        """Get the file represented by this source location."""
+        return self._get_instantiation()[0]
+
+    @property
+    def line(self):
+        """Get the line represented by this source location."""
+        return self._get_instantiation()[1]
+
+    @property
+    def column(self):
+        """Get the column represented by this source location."""
+        return self._get_instantiation()[2]
+
+    @property
+    def offset(self):
+        """Get the file offset represented by this source location."""
+        return self._get_instantiation()[3]
+
+    def __repr__(self):
+        return "<SourceLocation file %r, line %r, column %r>" % (
+            self.file.name if self.file else None, self.line, self.column)
+
+class SourceRange(Structure):
+    """
+    A SourceRange describes a range of source locations within the source
+    code.
+    """
+    _fields_ = [
+        ("ptr_data", c_void_p * 2),
+        ("begin_int_data", c_uint),
+        ("end_int_data", c_uint)]
+
+    # FIXME: Eliminate this and make normal constructor? Requires hiding ctypes
+    # object.
+    @staticmethod
+    def from_locations(start, end):
+        return SourceRange_getRange(start, end)
+
+    @property
+    def start(self):
+        """
+        Return a SourceLocation representing the first character within a
+        source range.
+        """
+        return SourceRange_start(self)
+
+    @property
+    def end(self):
+        """
+        Return a SourceLocation representing the last character within a
+        source range.
+        """
+        return SourceRange_end(self)
+
+    def __repr__(self):
+        return "<SourceRange start %r, end %r>" % (self.start, self.end)
+
+class Diagnostic(object):
+    """
+    A Diagnostic is a single instance of a Clang diagnostic. It includes the
+    diagnostic severity, the message, the location the diagnostic occurred, as
+    well as additional source ranges and associated fix-it hints.
+    """
+
+    Ignored = 0
+    Note    = 1
+    Warning = 2
+    Error   = 3
+    Fatal   = 4
+
+    def __init__(self, ptr):
+        self.ptr = ptr
+
+    def __del__(self):
+        _clang_disposeDiagnostic(self.ptr)
+
+    @property
+    def severity(self):
+        return _clang_getDiagnosticSeverity(self.ptr)
+
+    @property
+    def location(self):
+        return _clang_getDiagnosticLocation(self.ptr)
+
+    @property
+    def spelling(self):
+        return _clang_getDiagnosticSpelling(self.ptr)
+
+    @property
+    def ranges(self):
+        class RangeIterator:
+            def __init__(self, diag):
+                self.diag = diag
+
+            def __len__(self):
+                return int(_clang_getDiagnosticNumRanges(self.diag))
+
+            def __getitem__(self, key):
+                return _clang_getDiagnosticRange(self.diag, key)
+
+        return RangeIterator(self.ptr)
+
+    @property
+    def fixits(self):
+        class FixItIterator:
+            def __init__(self, diag):
+                self.diag = diag
+
+            def __len__(self):
+                return int(_clang_getDiagnosticNumFixIts(self.diag))
+
+            def __getitem__(self, key):
+                range = SourceRange()
+                value = _clang_getDiagnosticFixIt(self.diag, key, byref(range))
+                if len(value) == 0:
+                    raise IndexError
+
+                return FixIt(range, value)
+
+        return FixItIterator(self.ptr)
+
+    def __repr__(self):
+        return "<Diagnostic severity %r, location %r, spelling %r>" % (
+            self.severity, self.location, self.spelling)
+
+class FixIt(object):
+    """
+    A FixIt represents a transformation to be applied to the source to
+    "fix-it". The fix-it shouldbe applied by replacing the given source range
+    with the given value.
+    """
+
+    def __init__(self, range, value):
+        self.range = range
+        self.value = value
+
+    def __repr__(self):
+        return "<FixIt range %r, value %r>" % (self.range, self.value)
+
+### Cursor Kinds ###
+
+class CursorKind(object):
+    """
+    A CursorKind describes the kind of entity that a cursor points to.
+    """
+
+    # The unique kind objects, indexed by id.
+    _kinds = []
+    _name_map = None
+
+    def __init__(self, value):
+        if value >= len(CursorKind._kinds):
+            CursorKind._kinds += [None] * (value - len(CursorKind._kinds) + 1)
+        if CursorKind._kinds[value] is not None:
+            raise ValueError,'CursorKind already loaded'
+        self.value = value
+        CursorKind._kinds[value] = self
+        CursorKind._name_map = None
+
+    def from_param(self):
+        return self.value
+
+    @property
+    def name(self):
+        """Get the enumeration name of this cursor kind."""
+        if self._name_map is None:
+            self._name_map = {}
+            for key,value in CursorKind.__dict__.items():
+                if isinstance(value,CursorKind):
+                    self._name_map[value] = key
+        return self._name_map[self]
+
+    @staticmethod
+    def from_id(id):
+        if id >= len(CursorKind._kinds) or CursorKind._kinds[id] is None:
+            raise ValueError,'Unknown cursor kind'
+        return CursorKind._kinds[id]
+
+    @staticmethod
+    def get_all_kinds():
+        """Return all CursorKind enumeration instances."""
+        return filter(None, CursorKind._kinds)
+
+    def is_declaration(self):
+        """Test if this is a declaration kind."""
+        return CursorKind_is_decl(self)
+
+    def is_reference(self):
+        """Test if this is a reference kind."""
+        return CursorKind_is_ref(self)
+
+    def is_expression(self):
+        """Test if this is an expression kind."""
+        return CursorKind_is_expr(self)
+
+    def is_statement(self):
+        """Test if this is a statement kind."""
+        return CursorKind_is_stmt(self)
+
+    def is_invalid(self):
+        """Test if this is an invalid kind."""
+        return CursorKind_is_inv(self)
+
+    def __repr__(self):
+        return 'CursorKind.%s' % (self.name,)
+
+# FIXME: Is there a nicer way to expose this enumeration? We could potentially
+# represent the nested structure, or even build a class hierarchy. The main
+# things we want for sure are (a) simple external access to kinds, (b) a place
+# to hang a description and name, (c) easy to keep in sync with Index.h.
+
+###
+# Declaration Kinds
+
+# A declaration whose specific kind is not exposed via this interface.
+#
+# Unexposed declarations have the same operations as any other kind of
+# declaration; one can extract their location information, spelling, find their
+# definitions, etc. However, the specific kind of the declaration is not
+# reported.
+CursorKind.UNEXPOSED_DECL = CursorKind(1)
+
+# A C or C++ struct.
+CursorKind.STRUCT_DECL = CursorKind(2)
+
+# A C or C++ union.
+CursorKind.UNION_DECL = CursorKind(3)
+
+# A C++ class.
+CursorKind.CLASS_DECL = CursorKind(4)
+
+# An enumeration.
+CursorKind.ENUM_DECL = CursorKind(5)
+
+# A field (in C) or non-static data member (in C++) in a struct, union, or C++
+# class.
+CursorKind.FIELD_DECL = CursorKind(6)
+
+# An enumerator constant.
+CursorKind.ENUM_CONSTANT_DECL = CursorKind(7)
+
+# A function.
+CursorKind.FUNCTION_DECL = CursorKind(8)
+
+# A variable.
+CursorKind.VAR_DECL = CursorKind(9)
+
+# A function or method parameter.
+CursorKind.PARM_DECL = CursorKind(10)
+
+# An Objective-C @interface.
+CursorKind.OBJC_INTERFACE_DECL = CursorKind(11)
+
+# An Objective-C @interface for a category.
+CursorKind.OBJC_CATEGORY_DECL = CursorKind(12)
+
+# An Objective-C @protocol declaration.
+CursorKind.OBJC_PROTOCOL_DECL = CursorKind(13)
+
+# An Objective-C @property declaration.
+CursorKind.OBJC_PROPERTY_DECL = CursorKind(14)
+
+# An Objective-C instance variable.
+CursorKind.OBJC_IVAR_DECL = CursorKind(15)
+
+# An Objective-C instance method.
+CursorKind.OBJC_INSTANCE_METHOD_DECL = CursorKind(16)
+
+# An Objective-C class method.
+CursorKind.OBJC_CLASS_METHOD_DECL = CursorKind(17)
+
+# An Objective-C @implementation.
+CursorKind.OBJC_IMPLEMENTATION_DECL = CursorKind(18)
+
+# An Objective-C @implementation for a category.
+CursorKind.OBJC_CATEGORY_IMPL_DECL = CursorKind(19)
+
+# A typedef.
+CursorKind.TYPEDEF_DECL = CursorKind(20)
+
+###
+# Reference Kinds
+
+CursorKind.OBJC_SUPER_CLASS_REF = CursorKind(40)
+CursorKind.OBJC_PROTOCOL_REF = CursorKind(41)
+CursorKind.OBJC_CLASS_REF = CursorKind(42)
+
+# A reference to a type declaration.
+#
+# A type reference occurs anywhere where a type is named but not
+# declared. For example, given:
+#   typedef unsigned size_type;
+#   size_type size;
+#
+# The typedef is a declaration of size_type (CXCursor_TypedefDecl),
+# while the type of the variable "size" is referenced. The cursor
+# referenced by the type of size is the typedef for size_type.
+CursorKind.TYPE_REF = CursorKind(43)
+
+###
+# Invalid/Error Kinds
+
+CursorKind.INVALID_FILE = CursorKind(70)
+CursorKind.NO_DECL_FOUND = CursorKind(71)
+CursorKind.NOT_IMPLEMENTED = CursorKind(72)
+
+###
+# Expression Kinds
+
+# An expression whose specific kind is not exposed via this interface.
+#
+# Unexposed expressions have the same operations as any other kind of
+# expression; one can extract their location information, spelling, children,
+# etc. However, the specific kind of the expression is not reported.
+CursorKind.UNEXPOSED_EXPR = CursorKind(100)
+
+# An expression that refers to some value declaration, such as a function,
+# varible, or enumerator.
+CursorKind.DECL_REF_EXPR = CursorKind(101)
+
+# An expression that refers to a member of a struct, union, class, Objective-C
+# class, etc.
+CursorKind.MEMBER_REF_EXPR = CursorKind(102)
+
+# An expression that calls a function.
+CursorKind.CALL_EXPR = CursorKind(103)
+
+# An expression that sends a message to an Objective-C object or class.
+CursorKind.OBJC_MESSAGE_EXPR = CursorKind(104)
+
+# A statement whose specific kind is not exposed via this interface.
+#
+# Unexposed statements have the same operations as any other kind of statement;
+# one can extract their location information, spelling, children, etc. However,
+# the specific kind of the statement is not reported.
+CursorKind.UNEXPOSED_STMT = CursorKind(200)
+
+###
+# Other Kinds
+
+# Cursor that represents the translation unit itself.
+#
+# The translation unit cursor exists primarily to act as the root cursor for
+# traversing the contents of a translation unit.
+CursorKind.TRANSLATION_UNIT = CursorKind(300)
+
+### Cursors ###
+
+class Cursor(Structure):
+    """
+    The Cursor class represents a reference to an element within the AST. It
+    acts as a kind of iterator.
+    """
+    _fields_ = [("_kind_id", c_int), ("data", c_void_p * 3)]
+
+    def __eq__(self, other):
+        return Cursor_eq(self, other)
+
+    def __ne__(self, other):
+        return not Cursor_eq(self, other)
+
+    def is_definition(self):
+        """
+        Returns true if the declaration pointed at by the cursor is also a
+        definition of that entity.
+        """
+        return Cursor_is_def(self)
+
+    def get_definition(self):
+        """
+        If the cursor is a reference to a declaration or a declaration of
+        some entity, return a cursor that points to the definition of that
+        entity.
+        """
+        # TODO: Should probably check that this is either a reference or
+        # declaration prior to issuing the lookup.
+        return Cursor_def(self)
+
+    def get_usr(self):
+        """Return the Unified Symbol Resultion (USR) for the entity referenced
+        by the given cursor (or None).
+
+        A Unified Symbol Resolution (USR) is a string that identifies a
+        particular entity (function, class, variable, etc.) within a
+        program. USRs can be compared across translation units to determine,
+        e.g., when references in one translation refer to an entity defined in
+        another translation unit."""
+        return Cursor_usr(self)
+
+    @property
+    def kind(self):
+        """Return the kind of this cursor."""
+        return CursorKind.from_id(self._kind_id)
+
+    @property
+    def spelling(self):
+        """Return the spelling of the entity pointed at by the cursor."""
+        if not self.kind.is_declaration():
+            # FIXME: clang_getCursorSpelling should be fixed to not assert on
+            # this, for consistency with clang_getCursorUSR.
+            return None
+        return Cursor_spelling(self)
+
+    @property
+    def location(self):
+        """
+        Return the source location (the starting character) of the entity
+        pointed at by the cursor.
+        """
+        return Cursor_loc(self)
+
+    @property
+    def extent(self):
+        """
+        Return the source range (the range of text) occupied by the entity
+        pointed at by the cursor.
+        """
+        return Cursor_extent(self)
+
+    def get_children(self):
+        """Return an iterator for accessing the children of this cursor."""
+
+        # FIXME: Expose iteration from CIndex, PR6125.
+        def visitor(child, parent, children):
+            # FIXME: Document this assertion in API.
+            # FIXME: There should just be an isNull method.
+            assert child != Cursor_null()
+            children.append(child)
+            return 1 # continue
+        children = []
+        Cursor_visit(self, Cursor_visit_callback(visitor), children)
+        return iter(children)
+
+    @staticmethod
+    def from_result(res, fn, args):
+        assert isinstance(res, Cursor)
+        # FIXME: There should just be an isNull method.
+        if res == Cursor_null():
+            return None
+        return res
+
+## CIndex Objects ##
+
+# CIndex objects (derived from ClangObject) are essentially lightweight
+# wrappers attached to some underlying object, which is exposed via CIndex as
+# a void*.
+
+class ClangObject(object):
+    """
+    A helper for Clang objects. This class helps act as an intermediary for
+    the ctypes library and the Clang CIndex library.
+    """
+    def __init__(self, obj):
+        assert isinstance(obj, c_object_p) and obj
+        self.obj = self._as_parameter_ = obj
+
+    def from_param(self):
+        return self._as_parameter_
+
+
+class _CXUnsavedFile(Structure):
+    """Helper for passing unsaved file arguments."""
+    _fields_ = [("name", c_char_p), ("contents", c_char_p), ('length', c_ulong)]
+
+## Diagnostic Conversion ##
+
+_clang_getNumDiagnostics = lib.clang_getNumDiagnostics
+_clang_getNumDiagnostics.argtypes = [c_object_p]
+_clang_getNumDiagnostics.restype = c_uint
+
+_clang_getDiagnostic = lib.clang_getDiagnostic
+_clang_getDiagnostic.argtypes = [c_object_p, c_uint]
+_clang_getDiagnostic.restype = c_object_p
+
+_clang_disposeDiagnostic = lib.clang_disposeDiagnostic
+_clang_disposeDiagnostic.argtypes = [c_object_p]
+
+_clang_getDiagnosticSeverity = lib.clang_getDiagnosticSeverity
+_clang_getDiagnosticSeverity.argtypes = [c_object_p]
+_clang_getDiagnosticSeverity.restype = c_int
+
+_clang_getDiagnosticLocation = lib.clang_getDiagnosticLocation
+_clang_getDiagnosticLocation.argtypes = [c_object_p]
+_clang_getDiagnosticLocation.restype = SourceLocation
+
+_clang_getDiagnosticSpelling = lib.clang_getDiagnosticSpelling
+_clang_getDiagnosticSpelling.argtypes = [c_object_p]
+_clang_getDiagnosticSpelling.restype = _CXString
+_clang_getDiagnosticSpelling.errcheck = _CXString.from_result
+
+_clang_getDiagnosticNumRanges = lib.clang_getDiagnosticNumRanges
+_clang_getDiagnosticNumRanges.argtypes = [c_object_p]
+_clang_getDiagnosticNumRanges.restype = c_uint
+
+_clang_getDiagnosticRange = lib.clang_getDiagnosticRange
+_clang_getDiagnosticRange.argtypes = [c_object_p, c_uint]
+_clang_getDiagnosticRange.restype = SourceRange
+
+_clang_getDiagnosticNumFixIts = lib.clang_getDiagnosticNumFixIts
+_clang_getDiagnosticNumFixIts.argtypes = [c_object_p]
+_clang_getDiagnosticNumFixIts.restype = c_uint
+
+_clang_getDiagnosticFixIt = lib.clang_getDiagnosticFixIt
+_clang_getDiagnosticFixIt.argtypes = [c_object_p, c_uint, POINTER(SourceRange)]
+_clang_getDiagnosticFixIt.restype = _CXString
+_clang_getDiagnosticFixIt.errcheck = _CXString.from_result
+
+###
+
+class Index(ClangObject):
+    """
+    The Index type provides the primary interface to the Clang CIndex library,
+    primarily by providing an interface for reading and parsing translation
+    units.
+    """
+
+    @staticmethod
+    def create(excludeDecls=False):
+        """
+        Create a new Index.
+        Parameters:
+        excludeDecls -- Exclude local declarations from translation units.
+        """
+        return Index(Index_create(excludeDecls, 0))
+
+    def __del__(self):
+        Index_dispose(self)
+
+    def read(self, path):
+        """Load the translation unit from the given AST file."""
+        ptr = TranslationUnit_read(self, path)
+        return TranslationUnit(ptr) if ptr else None
+
+    def parse(self, path, args = [], unsaved_files = []):
+        """
+        Load the translation unit from the given source code file by running
+        clang and generating the AST before loading. Additional command line
+        parameters can be passed to clang via the args parameter.
+
+        In-memory contents for files can be provided by passing a list of pairs
+        to as unsaved_files, the first item should be the filenames to be mapped
+        and the second should be the contents to be substituted for the
+        file. The contents may be passed as strings or file objects.
+        """
+        arg_array = 0
+        if len(args):
+            arg_array = (c_char_p * len(args))(* args)
+        unsaved_files_array = 0
+        if len(unsaved_files):
+            unsaved_files_array = (_CXUnsavedFile * len(unsaved_files))()
+            for i,(name,value) in enumerate(unsaved_files):
+                if not isinstance(value, str):
+                    # FIXME: It would be great to support an efficient version
+                    # of this, one day.
+                    value = value.read()
+                    print value
+                if not isinstance(value, str):
+                    raise TypeError,'Unexpected unsaved file contents.'
+                unsaved_files_array[i].name = name
+                unsaved_files_array[i].contents = value
+                unsaved_files_array[i].length = len(value)
+        ptr = TranslationUnit_parse(self, path, len(args), arg_array,
+                                    len(unsaved_files), unsaved_files_array)
+        return TranslationUnit(ptr) if ptr else None
+
+
+class TranslationUnit(ClangObject):
+    """
+    The TranslationUnit class represents a source code translation unit and
+    provides read-only access to its top-level declarations.
+    """
+
+    def __init__(self, ptr):
+        ClangObject.__init__(self, ptr)
+
+    def __del__(self):
+        TranslationUnit_dispose(self)
+
+    @property
+    def cursor(self):
+        """Retrieve the cursor that represents the given translation unit."""
+        return TranslationUnit_cursor(self)
+
+    @property
+    def spelling(self):
+        """Get the original translation unit source file name."""
+        return TranslationUnit_spelling(self)
+
+    def get_includes(self):
+        """
+        Return an iterable sequence of FileInclusion objects that describe the
+        sequence of inclusions in a translation unit. The first object in
+        this sequence is always the input file. Note that this method will not
+        recursively iterate over header files included through precompiled
+        headers.
+        """
+        def visitor(fobj, lptr, depth, includes):
+            loc = lptr.contents
+            includes.append(FileInclusion(loc.file, File(fobj), loc, depth))
+
+        # Automatically adapt CIndex/ctype pointers to python objects
+        includes = []
+        TranslationUnit_includes(self,
+                                 TranslationUnit_includes_callback(visitor),
+                                 includes)
+        return iter(includes)
+
+    @property
+    def diagnostics(self):
+        """
+        Return an iterable (and indexable) object containing the diagnostics.
+        """
+        class DiagIterator:
+            def __init__(self, tu):
+                self.tu = tu
+
+            def __len__(self):
+                return int(_clang_getNumDiagnostics(self.tu))
+
+            def __getitem__(self, key):
+                diag = _clang_getDiagnostic(self.tu, key)
+                if not diag:
+                    raise IndexError
+                return Diagnostic(diag)
+
+        return DiagIterator(self)
+
+class File(ClangObject):
+    """
+    The File class represents a particular source file that is part of a
+    translation unit.
+    """
+
+    @property
+    def name(self):
+        """Return the complete file and path name of the file."""
+        return File_name(self)
+
+    @property
+    def time(self):
+        """Return the last modification time of the file."""
+        return File_time(self)
+
+class FileInclusion(object):
+    """
+    The FileInclusion class represents the inclusion of one source file by
+    another via a '#include' directive or as the input file for the translation
+    unit. This class provides information about the included file, the including
+    file, the location of the '#include' directive and the depth of the included
+    file in the stack. Note that the input file has depth 0.
+    """
+
+    def __init__(self, src, tgt, loc, depth):
+        self.source = src
+        self.include = tgt
+        self.location = loc
+        self.depth = depth
+
+    @property
+    def is_input_file(self):
+        """True if the included file is the input file."""
+        return self.depth == 0
+
+# Additional Functions and Types
+
+# String Functions
+_CXString_dispose = lib.clang_disposeString
+_CXString_dispose.argtypes = [_CXString]
+
+_CXString_getCString = lib.clang_getCString
+_CXString_getCString.argtypes = [_CXString]
+_CXString_getCString.restype = c_char_p
+
+# Source Location Functions
+SourceLocation_loc = lib.clang_getInstantiationLocation
+SourceLocation_loc.argtypes = [SourceLocation, POINTER(c_object_p),
+                               POINTER(c_uint), POINTER(c_uint),
+                               POINTER(c_uint)]
+
+# Source Range Functions
+SourceRange_getRange = lib.clang_getRange
+SourceRange_getRange.argtypes = [SourceLocation, SourceLocation]
+SourceRange_getRange.restype = SourceRange
+
+SourceRange_start = lib.clang_getRangeStart
+SourceRange_start.argtypes = [SourceRange]
+SourceRange_start.restype = SourceLocation
+
+SourceRange_end = lib.clang_getRangeEnd
+SourceRange_end.argtypes = [SourceRange]
+SourceRange_end.restype = SourceLocation
+
+# CursorKind Functions
+CursorKind_is_decl = lib.clang_isDeclaration
+CursorKind_is_decl.argtypes = [CursorKind]
+CursorKind_is_decl.restype = bool
+
+CursorKind_is_ref = lib.clang_isReference
+CursorKind_is_ref.argtypes = [CursorKind]
+CursorKind_is_ref.restype = bool
+
+CursorKind_is_expr = lib.clang_isExpression
+CursorKind_is_expr.argtypes = [CursorKind]
+CursorKind_is_expr.restype = bool
+
+CursorKind_is_stmt = lib.clang_isStatement
+CursorKind_is_stmt.argtypes = [CursorKind]
+CursorKind_is_stmt.restype = bool
+
+CursorKind_is_inv = lib.clang_isInvalid
+CursorKind_is_inv.argtypes = [CursorKind]
+CursorKind_is_inv.restype = bool
+
+# Cursor Functions
+# TODO: Implement this function
+Cursor_get = lib.clang_getCursor
+Cursor_get.argtypes = [TranslationUnit, SourceLocation]
+Cursor_get.restype = Cursor
+
+Cursor_null = lib.clang_getNullCursor
+Cursor_null.restype = Cursor
+
+Cursor_usr = lib.clang_getCursorUSR
+Cursor_usr.argtypes = [Cursor]
+Cursor_usr.restype = _CXString
+Cursor_usr.errcheck = _CXString.from_result
+
+Cursor_is_def = lib.clang_isCursorDefinition
+Cursor_is_def.argtypes = [Cursor]
+Cursor_is_def.restype = bool
+
+Cursor_def = lib.clang_getCursorDefinition
+Cursor_def.argtypes = [Cursor]
+Cursor_def.restype = Cursor
+Cursor_def.errcheck = Cursor.from_result
+
+Cursor_eq = lib.clang_equalCursors
+Cursor_eq.argtypes = [Cursor, Cursor]
+Cursor_eq.restype = c_uint
+
+Cursor_spelling = lib.clang_getCursorSpelling
+Cursor_spelling.argtypes = [Cursor]
+Cursor_spelling.restype = _CXString
+Cursor_spelling.errcheck = _CXString.from_result
+
+Cursor_loc = lib.clang_getCursorLocation
+Cursor_loc.argtypes = [Cursor]
+Cursor_loc.restype = SourceLocation
+
+Cursor_extent = lib.clang_getCursorExtent
+Cursor_extent.argtypes = [Cursor]
+Cursor_extent.restype = SourceRange
+
+Cursor_ref = lib.clang_getCursorReferenced
+Cursor_ref.argtypes = [Cursor]
+Cursor_ref.restype = Cursor
+Cursor_ref.errcheck = Cursor.from_result
+
+Cursor_visit_callback = CFUNCTYPE(c_int, Cursor, Cursor, py_object)
+Cursor_visit = lib.clang_visitChildren
+Cursor_visit.argtypes = [Cursor, Cursor_visit_callback, py_object]
+Cursor_visit.restype = c_uint
+
+# Index Functions
+Index_create = lib.clang_createIndex
+Index_create.argtypes = [c_int, c_int]
+Index_create.restype = c_object_p
+
+Index_dispose = lib.clang_disposeIndex
+Index_dispose.argtypes = [Index]
+
+# Translation Unit Functions
+TranslationUnit_read = lib.clang_createTranslationUnit
+TranslationUnit_read.argtypes = [Index, c_char_p]
+TranslationUnit_read.restype = c_object_p
+
+TranslationUnit_parse = lib.clang_createTranslationUnitFromSourceFile
+TranslationUnit_parse.argtypes = [Index, c_char_p, c_int, c_void_p,
+                                  c_int, c_void_p]
+TranslationUnit_parse.restype = c_object_p
+
+TranslationUnit_cursor = lib.clang_getTranslationUnitCursor
+TranslationUnit_cursor.argtypes = [TranslationUnit]
+TranslationUnit_cursor.restype = Cursor
+TranslationUnit_cursor.errcheck = Cursor.from_result
+
+TranslationUnit_spelling = lib.clang_getTranslationUnitSpelling
+TranslationUnit_spelling.argtypes = [TranslationUnit]
+TranslationUnit_spelling.restype = _CXString
+TranslationUnit_spelling.errcheck = _CXString.from_result
+
+TranslationUnit_dispose = lib.clang_disposeTranslationUnit
+TranslationUnit_dispose.argtypes = [TranslationUnit]
+
+TranslationUnit_includes_callback = CFUNCTYPE(None,
+                                              c_object_p,
+                                              POINTER(SourceLocation),
+                                              c_uint, py_object)
+TranslationUnit_includes = lib.clang_getInclusions
+TranslationUnit_includes.argtypes = [TranslationUnit,
+                                     TranslationUnit_includes_callback,
+                                     py_object]
+
+# File Functions
+File_name = lib.clang_getFileName
+File_name.argtypes = [File]
+File_name.restype = c_char_p
+
+File_time = lib.clang_getFileTime
+File_time.argtypes = [File]
+File_time.restype = c_uint
+
+###
+
+__all__ = ['Index', 'TranslationUnit', 'Cursor', 'CursorKind',
+           'Diagnostic', 'FixIt', 'SourceRange', 'SourceLocation', 'File']
diff --git a/bindings/python/examples/cindex/cindex-dump.py b/bindings/python/examples/cindex/cindex-dump.py
new file mode 100644
index 0000000..af7ddab
--- /dev/null
+++ b/bindings/python/examples/cindex/cindex-dump.py
@@ -0,0 +1,87 @@
+#!/usr/bin/env python
+
+#===- cindex-dump.py - cindex/Python Source Dump -------------*- python -*--===#
+#
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+#===------------------------------------------------------------------------===#
+
+"""
+A simple command line tool for dumping a source file using the Clang Index
+Library.
+"""
+
+def get_diag_info(diag):
+    return { 'severity' : diag.severity,
+             'location' : diag.location,
+             'spelling' : diag.spelling,
+             'ranges' : diag.ranges,
+             'fixits' : diag.fixits }
+
+def get_cursor_id(cursor, cursor_list = []):
+    if not opts.showIDs:
+        return None
+
+    if cursor is None:
+        return None
+
+    # FIXME: This is really slow. It would be nice if the index API exposed
+    # something that let us hash cursors.
+    for i,c in enumerate(cursor_list):
+        if cursor == c:
+            return i
+    cursor_list.append(cursor)
+    return len(cursor_list) - 1
+
+def get_info(node, depth=0):
+    if opts.maxDepth is not None and depth >= opts.maxDepth:
+        children = None
+    else:
+        children = [get_info(c, depth+1)
+                    for c in node.get_children()]
+    return { 'id' : get_cursor_id(node),
+             'kind' : node.kind,
+             'usr' : node.get_usr(),
+             'spelling' : node.spelling,
+             'location' : node.location,
+             'extent.start' : node.extent.start,
+             'extent.end' : node.extent.end,
+             'is_definition' : node.is_definition(),
+             'definition id' : get_cursor_id(node.get_definition()),
+             'children' : children }
+
+def main():
+    from clang.cindex import Index
+    from pprint import pprint
+
+    from optparse import OptionParser, OptionGroup
+
+    global opts
+
+    parser = OptionParser("usage: %prog [options] {filename} [clang-args*]")
+    parser.add_option("", "--show-ids", dest="showIDs",
+                      help="Don't compute cursor IDs (very slow)",
+                      default=False)
+    parser.add_option("", "--max-depth", dest="maxDepth",
+                      help="Limit cursor expansion to depth N",
+                      metavar="N", type=int, default=None)
+    parser.disable_interspersed_args()
+    (opts, args) = parser.parse_args()
+
+    if len(args) == 0:
+        parser.error('invalid number arguments')
+
+    index = Index.create()
+    tu = index.parse(None, args)
+    if not tu:
+        parser.error("unable to load input")
+
+    pprint(('diags', map(get_diag_info, tu.diagnostics)))
+    pprint(('nodes', get_info(tu.cursor)))
+
+if __name__ == '__main__':
+    main()
+
diff --git a/bindings/python/examples/cindex/cindex-includes.py b/bindings/python/examples/cindex/cindex-includes.py
new file mode 100644
index 0000000..1750022
--- /dev/null
+++ b/bindings/python/examples/cindex/cindex-includes.py
@@ -0,0 +1,58 @@
+#!/usr/bin/env python
+
+#===- cindex-includes.py - cindex/Python Inclusion Graph -----*- python -*--===#
+#
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+#===------------------------------------------------------------------------===#
+
+"""
+A simple command line tool for dumping a Graphviz description (dot) that
+describes include dependencies.
+"""
+
+def main():
+    import sys
+    from clang.cindex import Index
+
+    from optparse import OptionParser, OptionGroup
+
+    parser = OptionParser("usage: %prog [options] {filename} [clang-args*]")
+    parser.disable_interspersed_args()
+    (opts, args) = parser.parse_args()
+    if len(args) == 0:
+        parser.error('invalid number arguments')
+
+    # FIXME: Add an output file option
+    out = sys.stdout
+
+    index = Index.create()
+    tu = index.parse(None, args)
+    if not tu:
+        parser.error("unable to load input")
+
+    # A helper function for generating the node name.
+    def name(f):
+        if f:
+            return "\"" + f.name + "\""
+
+    # Generate the include graph
+    out.write("digraph G {\n")
+    for i in tu.get_includes():
+        line = "  ";
+        if i.is_input_file:
+            # Always write the input file as a node just in case it doesn't
+            # actually include anything. This would generate a 1 node graph.
+            line += name(i.include)
+        else:
+            line += '%s->%s' % (name(i.source), name(i.include))
+        line += "\n";
+        out.write(line)
+    out.write("}\n")
+
+if __name__ == '__main__':
+    main()
+
diff --git a/bindings/python/tests/__init__.py b/bindings/python/tests/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/bindings/python/tests/__init__.py
diff --git a/bindings/python/tests/cindex/INPUTS/header1.h b/bindings/python/tests/cindex/INPUTS/header1.h
new file mode 100644
index 0000000..b4eacbe
--- /dev/null
+++ b/bindings/python/tests/cindex/INPUTS/header1.h
@@ -0,0 +1,6 @@
+#ifndef HEADER1
+#define HEADER1
+
+#include "header3.h"
+
+#endif
diff --git a/bindings/python/tests/cindex/INPUTS/header2.h b/bindings/python/tests/cindex/INPUTS/header2.h
new file mode 100644
index 0000000..c4eddc0
--- /dev/null
+++ b/bindings/python/tests/cindex/INPUTS/header2.h
@@ -0,0 +1,6 @@
+#ifndef HEADER2
+#define HEADER2
+
+#include "header3.h"
+
+#endif
diff --git a/bindings/python/tests/cindex/INPUTS/header3.h b/bindings/python/tests/cindex/INPUTS/header3.h
new file mode 100644
index 0000000..6dca764
--- /dev/null
+++ b/bindings/python/tests/cindex/INPUTS/header3.h
@@ -0,0 +1,3 @@
+// Not a guarded header!
+
+void f();
diff --git a/bindings/python/tests/cindex/INPUTS/hello.cpp b/bindings/python/tests/cindex/INPUTS/hello.cpp
new file mode 100644
index 0000000..7ef086e
--- /dev/null
+++ b/bindings/python/tests/cindex/INPUTS/hello.cpp
@@ -0,0 +1,6 @@
+#include "stdio.h"
+
+int main(int argc, char* argv[]) {
+    printf("hello world\n");
+    return 0;
+}
diff --git a/bindings/python/tests/cindex/INPUTS/include.cpp b/bindings/python/tests/cindex/INPUTS/include.cpp
new file mode 100644
index 0000000..60cfdaa
--- /dev/null
+++ b/bindings/python/tests/cindex/INPUTS/include.cpp
@@ -0,0 +1,5 @@
+#include "header1.h"
+#include "header2.h"
+#include "header1.h"
+
+int main() { }
diff --git a/bindings/python/tests/cindex/INPUTS/parse_arguments.c b/bindings/python/tests/cindex/INPUTS/parse_arguments.c
new file mode 100644
index 0000000..7196486
--- /dev/null
+++ b/bindings/python/tests/cindex/INPUTS/parse_arguments.c
@@ -0,0 +1,2 @@
+int DECL_ONE = 1;
+int DECL_TWO = 2;
diff --git a/bindings/python/tests/cindex/__init__.py b/bindings/python/tests/cindex/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/bindings/python/tests/cindex/__init__.py
diff --git a/bindings/python/tests/cindex/test_cursor.py b/bindings/python/tests/cindex/test_cursor.py
new file mode 100644
index 0000000..a653ba7
--- /dev/null
+++ b/bindings/python/tests/cindex/test_cursor.py
@@ -0,0 +1,59 @@
+from clang.cindex import Index, CursorKind
+
+kInput = """\
+// FIXME: Find nicer way to drop builtins and other cruft.
+int start_decl;
+
+struct s0 {
+  int a;
+  int b;
+};
+
+struct s1;
+
+void f0(int a0, int a1) {
+  int l0, l1;
+
+  if (a0)
+    return;
+
+  for (;;) {
+    break;
+  }
+}
+"""
+
+def test_get_children():
+    index = Index.create()
+    tu = index.parse('t.c', unsaved_files = [('t.c',kInput)])
+    
+    # Skip until past start_decl.
+    it = tu.cursor.get_children()
+    while it.next().spelling != 'start_decl':
+        pass
+
+    tu_nodes = list(it)
+
+    assert len(tu_nodes) == 3
+
+    assert tu_nodes[0].kind == CursorKind.STRUCT_DECL
+    assert tu_nodes[0].spelling == 's0'
+    assert tu_nodes[0].is_definition() == True
+    assert tu_nodes[0].location.file.name == 't.c'
+    assert tu_nodes[0].location.line == 4
+    assert tu_nodes[0].location.column == 8
+
+    s0_nodes = list(tu_nodes[0].get_children())
+    assert len(s0_nodes) == 2
+    assert s0_nodes[0].kind == CursorKind.FIELD_DECL
+    assert s0_nodes[0].spelling == 'a'
+    assert s0_nodes[1].kind == CursorKind.FIELD_DECL
+    assert s0_nodes[1].spelling == 'b'
+
+    assert tu_nodes[1].kind == CursorKind.STRUCT_DECL
+    assert tu_nodes[1].spelling == 's1'
+    assert tu_nodes[1].is_definition() == False
+
+    assert tu_nodes[2].kind == CursorKind.FUNCTION_DECL
+    assert tu_nodes[2].spelling == 'f0'
+    assert tu_nodes[2].is_definition() == True
diff --git a/bindings/python/tests/cindex/test_cursor_kind.py b/bindings/python/tests/cindex/test_cursor_kind.py
new file mode 100644
index 0000000..bdfa318
--- /dev/null
+++ b/bindings/python/tests/cindex/test_cursor_kind.py
@@ -0,0 +1,27 @@
+from clang.cindex import CursorKind
+
+def test_name():
+    assert CursorKind.UNEXPOSED_DECL.name is 'UNEXPOSED_DECL'
+
+def test_get_all_kinds():
+    assert CursorKind.UNEXPOSED_DECL in CursorKind.get_all_kinds()
+    assert CursorKind.TRANSLATION_UNIT in CursorKind.get_all_kinds()
+
+def test_kind_groups():
+    """Check that every kind classifies to exactly one group."""
+
+    assert CursorKind.UNEXPOSED_DECL.is_declaration()
+    assert CursorKind.TYPE_REF.is_reference()
+    assert CursorKind.DECL_REF_EXPR.is_expression()
+    assert CursorKind.UNEXPOSED_STMT.is_statement()
+    assert CursorKind.INVALID_FILE.is_invalid()
+
+    for k in CursorKind.get_all_kinds():
+        group = [n for n in ('is_declaration', 'is_reference', 'is_expression',
+                             'is_statement', 'is_invalid')
+                 if getattr(k, n)()]
+
+        if k == CursorKind.TRANSLATION_UNIT:
+            assert len(group) == 0
+        else:
+            assert len(group) == 1
diff --git a/bindings/python/tests/cindex/test_diagnostics.py b/bindings/python/tests/cindex/test_diagnostics.py
new file mode 100644
index 0000000..8518765
--- /dev/null
+++ b/bindings/python/tests/cindex/test_diagnostics.py
@@ -0,0 +1,48 @@
+from clang.cindex import *
+
+def tu_from_source(source):
+    index = Index.create()
+    tu = index.parse('INPUT.c', unsaved_files = [('INPUT.c', source)])
+    # FIXME: Remove the need for this.
+    tu.index = index
+    return tu
+
+# FIXME: We need support for invalid translation units to test better.
+
+def test_diagnostic_warning():
+    tu = tu_from_source("""int f0() {}\n""")
+    assert len(tu.diagnostics) == 1
+    assert tu.diagnostics[0].severity == Diagnostic.Warning
+    assert tu.diagnostics[0].location.line == 1
+    assert tu.diagnostics[0].location.column == 11
+    assert (tu.diagnostics[0].spelling ==
+            'control reaches end of non-void function')
+
+def test_diagnostic_note():
+    # FIXME: We aren't getting notes here for some reason.
+    index = Index.create()
+    tu = tu_from_source("""#define A x\nvoid *A = 1;\n""")
+    assert len(tu.diagnostics) == 1
+    assert tu.diagnostics[0].severity == Diagnostic.Warning
+    assert tu.diagnostics[0].location.line == 2
+    assert tu.diagnostics[0].location.column == 7
+    assert 'incompatible' in tu.diagnostics[0].spelling
+#    assert tu.diagnostics[1].severity == Diagnostic.Note
+#    assert tu.diagnostics[1].location.line == 1
+#    assert tu.diagnostics[1].location.column == 11
+#    assert tu.diagnostics[1].spelling == 'instantiated from'
+
+def test_diagnostic_fixit():
+    index = Index.create()
+    tu = tu_from_source("""struct { int f0; } x = { f0 : 1 };""")
+    assert len(tu.diagnostics) == 1
+    assert tu.diagnostics[0].severity == Diagnostic.Warning
+    assert tu.diagnostics[0].location.line == 1
+    assert tu.diagnostics[0].location.column == 31
+    assert tu.diagnostics[0].spelling.startswith('use of GNU old-style')
+    assert len(tu.diagnostics[0].fixits) == 1
+    assert tu.diagnostics[0].fixits[0].range.start.line == 1
+    assert tu.diagnostics[0].fixits[0].range.start.column == 26
+    assert tu.diagnostics[0].fixits[0].range.end.line == 1
+    assert tu.diagnostics[0].fixits[0].range.end.column == 30
+    assert tu.diagnostics[0].fixits[0].value == '.f0 = '
diff --git a/bindings/python/tests/cindex/test_index.py b/bindings/python/tests/cindex/test_index.py
new file mode 100644
index 0000000..dc173f0
--- /dev/null
+++ b/bindings/python/tests/cindex/test_index.py
@@ -0,0 +1,15 @@
+from clang.cindex import *
+import os
+
+kInputsDir = os.path.join(os.path.dirname(__file__), 'INPUTS')
+
+def test_create():
+    index = Index.create()
+
+# FIXME: test Index.read
+
+def test_parse():
+    index = Index.create()
+    assert isinstance(index, Index)
+    tu = index.parse(os.path.join(kInputsDir, 'hello.cpp'))
+    assert isinstance(tu, TranslationUnit)
diff --git a/bindings/python/tests/cindex/test_translation_unit.py b/bindings/python/tests/cindex/test_translation_unit.py
new file mode 100644
index 0000000..3c05c3f
--- /dev/null
+++ b/bindings/python/tests/cindex/test_translation_unit.py
@@ -0,0 +1,73 @@
+from clang.cindex import *
+import os
+
+kInputsDir = os.path.join(os.path.dirname(__file__), 'INPUTS')
+
+def test_spelling():
+    path = os.path.join(kInputsDir, 'hello.cpp')
+    index = Index.create()
+    tu = index.parse(path)
+    assert tu.spelling == path
+
+def test_cursor():
+    path = os.path.join(kInputsDir, 'hello.cpp')
+    index = Index.create()
+    tu = index.parse(path)
+    c = tu.cursor
+    assert isinstance(c, Cursor)
+    assert c.kind is CursorKind.TRANSLATION_UNIT
+
+def test_parse_arguments():
+    path = os.path.join(kInputsDir, 'parse_arguments.c')
+    index = Index.create()
+    tu = index.parse(path, ['-DDECL_ONE=hello', '-DDECL_TWO=hi'])
+    spellings = [c.spelling for c in tu.cursor.get_children()]
+    assert spellings[-2] == 'hello'
+    assert spellings[-1] == 'hi'
+
+def test_unsaved_files():
+    index = Index.create()
+    # FIXME: Why can't we just use "fake.h" here (instead of /tmp/fake.h)?
+    tu = index.parse('fake.c', unsaved_files = [
+            ('fake.c', """
+#include "/tmp/fake.h"
+int x;
+int SOME_DEFINE;
+"""),
+            ('/tmp/fake.h', """
+#define SOME_DEFINE y
+""")
+            ])
+    spellings = [c.spelling for c in tu.cursor.get_children()]
+    assert spellings[-2] == 'x'
+    assert spellings[-1] == 'y'
+
+def test_unsaved_files_2():
+    import StringIO
+    index = Index.create()
+    tu = index.parse('fake.c', unsaved_files = [
+            ('fake.c', StringIO.StringIO('int x;'))])
+    spellings = [c.spelling for c in tu.cursor.get_children()]
+    assert spellings[-1] == 'x'
+
+
+def test_includes():
+    def eq(expected, actual):
+        if not actual.is_input_file:
+            return expected[0] == actual.source.name and \
+                   expected[1] == actual.include.name
+        else:
+            return expected[1] == actual.include.name
+
+    src = os.path.join(kInputsDir, 'include.cpp')
+    h1 = os.path.join(kInputsDir, "header1.h")
+    h2 = os.path.join(kInputsDir, "header2.h")
+    h3 = os.path.join(kInputsDir, "header3.h")
+    inc = [(None, src), (src, h1), (h1, h3), (src, h2), (h2, h3)]
+
+    index = Index.create()
+    tu = index.parse(src)
+    for i in zip(inc, tu.get_includes()):
+        assert eq(i[0], i[1])
+
+
diff --git a/clang-host-build.mk b/clang-host-build.mk
new file mode 100644
index 0000000..d7b70bb
--- /dev/null
+++ b/clang-host-build.mk
@@ -0,0 +1,14 @@
+LOCAL_CFLAGS :=	\
+	-pedantic	\
+	-Wcast-qual	\
+	-Wno-long-long	\
+	$(LOCAL_CFLAGS)
+
+# Make sure bionic is first so we can include system headers.
+LOCAL_C_INCLUDES :=	\
+	$(CLANG_ROOT_PATH)/include	\
+	$(LOCAL_C_INCLUDES)
+
+ifneq ($(LLVM_HOST_BUILD_MK),)
+include $(LLVM_HOST_BUILD_MK)
+endif
diff --git a/clang-tblgen-rules.mk b/clang-tblgen-rules.mk
new file mode 100644
index 0000000..db41335
--- /dev/null
+++ b/clang-tblgen-rules.mk
@@ -0,0 +1,41 @@
+###########################################################
+## TableGen: Compile .td files to .inc.
+###########################################################
+ifeq ($(LOCAL_MODULE_CLASS),)
+    LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+endif
+
+ifneq ($(strip $(TBLGEN_TABLES)),)
+
+intermediates := $(call local-intermediates-dir)
+
+ifneq ($(filter Diagnostic%Kinds.inc,$(TBLGEN_TABLES)),)
+LOCAL_GENERATED_SOURCES += $(addprefix $(intermediates)/clang/Basic/,$(filter Diagnostic%Kinds.inc,$(TBLGEN_TABLES)))
+$(intermediates)/clang/Basic/Diagnostic%Kinds.inc: $(CLANG_ROOT_PATH)/include/clang/Basic/Diagnostic.td $(TBLGEN)
+	@echo "Building Clang $(patsubst Diagnostic%Kinds.inc,%,$(@F)) diagnostic tables with tblgen"
+	$(call transform-host-td-to-out,clang-diags-defs -clang-component=$(patsubst Diagnostic%Kinds.inc,%,$(@F)))
+endif
+
+ifneq ($(findstring DiagnosticGroups.inc,$(TBLGEN_TABLES)),)
+LOCAL_GENERATED_SOURCES += $(intermediates)/clang/Basic/DiagnosticGroups.inc
+$(intermediates)/clang/Basic/DiagnosticGroups.inc: $(CLANG_ROOT_PATH)/include/clang/Basic/Diagnostic.td $(CLANG_ROOT_PATH)/include/clang/Basic/DiagnosticGroups.td $(TBLGEN)
+	@echo "Building Clang diagnostic groups with tblgen"
+	$(call transform-host-td-to-out,clang-diag-groups)
+endif
+
+ifneq ($(findstring Options.inc,$(TBLGEN_TABLES)),)
+LOCAL_GENERATED_SOURCES += $(intermediates)/clang/Driver/Options.inc
+$(intermediates)/clang/Driver/Options.inc: $(CLANG_ROOT_PATH)/include/clang/Driver/Options.td $(CLANG_ROOT_PATH)/include/clang/Driver/OptParser.td $(TBLGEN)
+	@echo "Building Clang Driver Option tables with tblgen"
+	$(call transform-host-td-to-out,opt-parser-defs)
+endif
+
+ifneq ($(findstring CC1Options.inc,$(TBLGEN_TABLES)),)
+LOCAL_GENERATED_SOURCES += $(intermediates)/clang/Driver/CC1Options.inc
+$(intermediates)/clang/Driver/CC1Options.inc: $(CLANG_ROOT_PATH)/include/clang/Driver/CC1Options.td $(CLANG_ROOT_PATH)/include/clang/Driver/OptParser.td $(TBLGEN)
+	@echo "Building Clang CC1 Option tables with tblgen"
+	$(call transform-host-td-to-out,opt-parser-defs)
+endif
+
+
+endif
diff --git a/clang.mk b/clang.mk
new file mode 100644
index 0000000..655e88f
--- /dev/null
+++ b/clang.mk
@@ -0,0 +1,6 @@
+ifeq ($(CLANG_ROOT_PATH),)
+$(error Must set variable CLANG_ROOT_PATH before including this! $(LOCAL_PATH))
+endif
+
+CLANG_HOST_BUILD_MK := $(CLANG_ROOT_PATH)/clang-host-build.mk
+CLANG_TBLGEN_RULES_MK := $(CLANG_ROOT_PATH)/clang-tblgen-rules.mk
diff --git a/clang.xcodeproj/project.pbxproj b/clang.xcodeproj/project.pbxproj
new file mode 100644
index 0000000..6556bb4
--- /dev/null
+++ b/clang.xcodeproj/project.pbxproj
@@ -0,0 +1,2209 @@
+// !$*UTF8*$!
+{
+	archiveVersion = 1;
+	classes = {
+	};
+	objectVersion = 42;
+	objects = {
+
+/* Begin PBXBuildFile section */
+		03F50AC60D416EAA00B9CF60 /* Targets.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 03F50AC50D416EAA00B9CF60 /* Targets.cpp */; };
+		1A2193CE0F45EEB700C0713D /* Mangle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A2193CC0F45EEB700C0713D /* Mangle.cpp */; };
+		1A2A54B50FD1DD1C00F4CE45 /* AnalysisConsumer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A2A54A40FD1DD1C00F4CE45 /* AnalysisConsumer.cpp */; };
+		1A2A54B60FD1DD1C00F4CE45 /* ASTConsumers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A2A54A50FD1DD1C00F4CE45 /* ASTConsumers.cpp */; };
+		1A2A54B80FD1DD1C00F4CE45 /* CacheTokens.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A2A54A70FD1DD1C00F4CE45 /* CacheTokens.cpp */; };
+		1A2A54B90FD1DD1C00F4CE45 /* DependencyFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A2A54A80FD1DD1C00F4CE45 /* DependencyFile.cpp */; };
+		1A2A54BA0FD1DD1C00F4CE45 /* DiagChecker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A2A54A90FD1DD1C00F4CE45 /* DiagChecker.cpp */; };
+		1A2A54BB0FD1DD1C00F4CE45 /* DocumentXML.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A2A54AA0FD1DD1C00F4CE45 /* DocumentXML.cpp */; };
+		1A2A54BC0FD1DD1C00F4CE45 /* GeneratePCH.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A2A54AB0FD1DD1C00F4CE45 /* GeneratePCH.cpp */; };
+		1A2A54BD0FD1DD1C00F4CE45 /* HTMLPrint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A2A54AC0FD1DD1C00F4CE45 /* HTMLPrint.cpp */; };
+		1A2A54BE0FD1DD1C00F4CE45 /* PrintParserCallbacks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A2A54AD0FD1DD1C00F4CE45 /* PrintParserCallbacks.cpp */; };
+		1A2A54BF0FD1DD1C00F4CE45 /* PrintPreprocessedOutput.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A2A54AE0FD1DD1C00F4CE45 /* PrintPreprocessedOutput.cpp */; };
+		1A2A54C10FD1DD1C00F4CE45 /* RewriteMacros.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A2A54B00FD1DD1C00F4CE45 /* RewriteMacros.cpp */; };
+		1A2A54C20FD1DD1C00F4CE45 /* RewriteObjC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A2A54B10FD1DD1C00F4CE45 /* RewriteObjC.cpp */; };
+		1A2A54C30FD1DD1C00F4CE45 /* RewriteTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A2A54B20FD1DD1C00F4CE45 /* RewriteTest.cpp */; };
+		1A2A54C40FD1DD1C00F4CE45 /* StmtXML.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A2A54B30FD1DD1C00F4CE45 /* StmtXML.cpp */; };
+		1A2A54C50FD1DD1C00F4CE45 /* Warnings.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A2A54B40FD1DD1C00F4CE45 /* Warnings.cpp */; };
+		1A30A9E90B93A4C800201A91 /* ExprCXX.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1A30A9E80B93A4C800201A91 /* ExprCXX.h */; };
+		1A376A2D0D4AED9B002A1C52 /* CGExprConstant.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A376A2C0D4AED9B002A1C52 /* CGExprConstant.cpp */; };
+		1A471AB50F437BC500753CE8 /* CGBlocks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A471AB40F437BC500753CE8 /* CGBlocks.cpp */; };
+		1A4C41BF105B4C0B0047B5E7 /* CGClass.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A4C41BE105B4C0B0047B5E7 /* CGClass.cpp */; };
+		1A5D5E580E5E81010023C059 /* CGCXX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A5D5E570E5E81010023C059 /* CGCXX.cpp */; };
+		1A621BB7110FE6AA009E6834 /* TargetInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A621BB5110FE6AA009E6834 /* TargetInfo.cpp */; };
+		1A621C4211111D61009E6834 /* CIndexCodeCompletion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A621C3A11111D61009E6834 /* CIndexCodeCompletion.cpp */; };
+		1A621C4311111D61009E6834 /* CIndexer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A621C3B11111D61009E6834 /* CIndexer.cpp */; };
+		1A621C4411111D61009E6834 /* CIndexInclusionStack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A621C3D11111D61009E6834 /* CIndexInclusionStack.cpp */; };
+		1A621C4511111D61009E6834 /* CIndexUSRs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A621C3E11111D61009E6834 /* CIndexUSRs.cpp */; };
+		1A621C4611111D61009E6834 /* CXCursor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A621C3F11111D61009E6834 /* CXCursor.cpp */; };
+		1A6B6CD410693FC900BB4A8F /* CodeCompleteConsumer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A6B6CD110693FC900BB4A8F /* CodeCompleteConsumer.cpp */; };
+		1A6B6CD510693FC900BB4A8F /* SemaCodeComplete.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A6B6CD210693FC900BB4A8F /* SemaCodeComplete.cpp */; };
+		1A6B6E9A1069833600BB4A8F /* CGExprCXX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A6B6E991069833600BB4A8F /* CGExprCXX.cpp */; };
+		1A6C01F7108128710072DEE4 /* CGRTTI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A6C01F6108128710072DEE4 /* CGRTTI.cpp */; };
+		1A6FE7090FD6F85800E00CA9 /* CGTemporaries.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A6FE7080FD6F85800E00CA9 /* CGTemporaries.cpp */; };
+		1A701B640F7C8FE400FEC4D1 /* SemaAccess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A701B630F7C8FE400FEC4D1 /* SemaAccess.cpp */; };
+		1A7342480C7B57D500122F56 /* CGObjC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A7342470C7B57D500122F56 /* CGObjC.cpp */; };
+		1A81AA19108144F40094E50B /* CGVTables.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A81AA18108144F40094E50B /* CGVTables.cpp */; };
+		1A869A700BA2164C008DA07A /* LiteralSupport.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1A869A6E0BA2164C008DA07A /* LiteralSupport.h */; };
+		1A869AA80BA21ABA008DA07A /* LiteralSupport.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A869AA70BA21ABA008DA07A /* LiteralSupport.cpp */; };
+		1A97825B1108BA18002B98FC /* CGVTT.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A97825A1108BA18002B98FC /* CGVTT.cpp */; };
+		1A986AB710D0746D00A8EA9E /* CGDeclCXX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A986AB610D0746D00A8EA9E /* CGDeclCXX.cpp */; };
+		1ABC36940C7A4BDC006DB0AB /* CGBuiltin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ABC36930C7A4BDC006DB0AB /* CGBuiltin.cpp */; };
+		1ABD23D61182449800A48E65 /* APValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ABD23B11182449800A48E65 /* APValue.cpp */; };
+		1ABD23D71182449800A48E65 /* ASTConsumer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ABD23B21182449800A48E65 /* ASTConsumer.cpp */; };
+		1ABD23D81182449800A48E65 /* ASTContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ABD23B31182449800A48E65 /* ASTContext.cpp */; };
+		1ABD23D91182449800A48E65 /* ASTDiagnostic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ABD23B41182449800A48E65 /* ASTDiagnostic.cpp */; };
+		1ABD23DA1182449800A48E65 /* ASTImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ABD23B51182449800A48E65 /* ASTImporter.cpp */; };
+		1ABD23DB1182449800A48E65 /* AttrImpl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ABD23B61182449800A48E65 /* AttrImpl.cpp */; };
+		1ABD23DC1182449800A48E65 /* CXXInheritance.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ABD23B71182449800A48E65 /* CXXInheritance.cpp */; };
+		1ABD23DD1182449800A48E65 /* Decl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ABD23B81182449800A48E65 /* Decl.cpp */; };
+		1ABD23DE1182449800A48E65 /* DeclarationName.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ABD23B91182449800A48E65 /* DeclarationName.cpp */; };
+		1ABD23DF1182449800A48E65 /* DeclBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ABD23BA1182449800A48E65 /* DeclBase.cpp */; };
+		1ABD23E01182449800A48E65 /* DeclCXX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ABD23BB1182449800A48E65 /* DeclCXX.cpp */; };
+		1ABD23E11182449800A48E65 /* DeclFriend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ABD23BC1182449800A48E65 /* DeclFriend.cpp */; };
+		1ABD23E21182449800A48E65 /* DeclGroup.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ABD23BD1182449800A48E65 /* DeclGroup.cpp */; };
+		1ABD23E31182449800A48E65 /* DeclObjC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ABD23BE1182449800A48E65 /* DeclObjC.cpp */; };
+		1ABD23E41182449800A48E65 /* DeclPrinter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ABD23BF1182449800A48E65 /* DeclPrinter.cpp */; };
+		1ABD23E51182449800A48E65 /* DeclTemplate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ABD23C01182449800A48E65 /* DeclTemplate.cpp */; };
+		1ABD23E61182449800A48E65 /* Expr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ABD23C11182449800A48E65 /* Expr.cpp */; };
+		1ABD23E71182449800A48E65 /* ExprConstant.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ABD23C21182449800A48E65 /* ExprConstant.cpp */; };
+		1ABD23E81182449800A48E65 /* ExprCXX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ABD23C31182449800A48E65 /* ExprCXX.cpp */; };
+		1ABD23E91182449800A48E65 /* FullExpr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ABD23C41182449800A48E65 /* FullExpr.cpp */; };
+		1ABD23EA1182449800A48E65 /* InheritViz.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ABD23C51182449800A48E65 /* InheritViz.cpp */; };
+		1ABD23EB1182449800A48E65 /* NestedNameSpecifier.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ABD23C61182449800A48E65 /* NestedNameSpecifier.cpp */; };
+		1ABD23EC1182449800A48E65 /* ParentMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ABD23C71182449800A48E65 /* ParentMap.cpp */; };
+		1ABD23ED1182449800A48E65 /* RecordLayout.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ABD23C81182449800A48E65 /* RecordLayout.cpp */; };
+		1ABD23EE1182449800A48E65 /* RecordLayoutBuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ABD23C91182449800A48E65 /* RecordLayoutBuilder.cpp */; };
+		1ABD23EF1182449800A48E65 /* Stmt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ABD23CB1182449800A48E65 /* Stmt.cpp */; };
+		1ABD23F01182449800A48E65 /* StmtDumper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ABD23CC1182449800A48E65 /* StmtDumper.cpp */; };
+		1ABD23F11182449800A48E65 /* StmtIterator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ABD23CD1182449800A48E65 /* StmtIterator.cpp */; };
+		1ABD23F21182449800A48E65 /* StmtPrinter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ABD23CE1182449800A48E65 /* StmtPrinter.cpp */; };
+		1ABD23F31182449800A48E65 /* StmtProfile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ABD23CF1182449800A48E65 /* StmtProfile.cpp */; };
+		1ABD23F41182449800A48E65 /* StmtViz.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ABD23D01182449800A48E65 /* StmtViz.cpp */; };
+		1ABD23F51182449800A48E65 /* TemplateBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ABD23D11182449800A48E65 /* TemplateBase.cpp */; };
+		1ABD23F61182449800A48E65 /* TemplateName.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ABD23D21182449800A48E65 /* TemplateName.cpp */; };
+		1ABD23F71182449800A48E65 /* Type.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ABD23D31182449800A48E65 /* Type.cpp */; };
+		1ABD23F81182449800A48E65 /* TypeLoc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ABD23D41182449800A48E65 /* TypeLoc.cpp */; };
+		1ABD23F91182449800A48E65 /* TypePrinter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ABD23D51182449800A48E65 /* TypePrinter.cpp */; };
+		1ACB57E41105820D0047B991 /* CompilerInstance.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ACB57DB1105820D0047B991 /* CompilerInstance.cpp */; };
+		1ACB57E51105820D0047B991 /* CompilerInvocation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ACB57DC1105820D0047B991 /* CompilerInvocation.cpp */; };
+		1ACB57E61105820D0047B991 /* DeclXML.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ACB57DD1105820D0047B991 /* DeclXML.cpp */; };
+		1ACB57E71105820D0047B991 /* FrontendAction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ACB57DE1105820D0047B991 /* FrontendAction.cpp */; };
+		1ACB57E81105820D0047B991 /* FrontendActions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ACB57DF1105820D0047B991 /* FrontendActions.cpp */; };
+		1ACB57E91105820D0047B991 /* FrontendOptions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ACB57E01105820D0047B991 /* FrontendOptions.cpp */; };
+		1ACB57EA1105820D0047B991 /* LangStandards.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ACB57E11105820D0047B991 /* LangStandards.cpp */; };
+		1ACB57EB1105820D0047B991 /* TypeXML.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ACB57E21105820D0047B991 /* TypeXML.cpp */; };
+		1ACB57EC1105820D0047B991 /* VerifyDiagnosticsClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ACB57E31105820D0047B991 /* VerifyDiagnosticsClient.cpp */; };
+		1ADF47AF0F782C3200E48A8A /* SemaTemplateInstantiateDecl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ADF47AE0F782C3200E48A8A /* SemaTemplateInstantiateDecl.cpp */; };
+		1AF1B50F109A4FB800AFAFAC /* CGException.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AF1B50E109A4FB800AFAFAC /* CGException.cpp */; };
+		1AFDD8721161085D00AE030A /* ASTMerge.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AFDD8701161085D00AE030A /* ASTMerge.cpp */; };
+		1AFDD8731161085D00AE030A /* CodeGenAction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AFDD8711161085D00AE030A /* CodeGenAction.cpp */; };
+		1AFF8AE31012BFC900D248DA /* CGRecordLayoutBuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AFF8AE11012BFC900D248DA /* CGRecordLayoutBuilder.cpp */; };
+		3507E4C20E27FE2D00FB7B57 /* CheckObjCInstMethSignature.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3507E4C10E27FE2D00FB7B57 /* CheckObjCInstMethSignature.cpp */; };
+		352246E70F5C6BE000D0D279 /* HTMLDiagnostics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 352246E10F5C6BE000D0D279 /* HTMLDiagnostics.cpp */; };
+		352246E80F5C6BE000D0D279 /* InitHeaderSearch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 352246E20F5C6BE000D0D279 /* InitHeaderSearch.cpp */; };
+		352246EA0F5C6BE000D0D279 /* PlistDiagnostics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 352246E40F5C6BE000D0D279 /* PlistDiagnostics.cpp */; };
+		352246EB0F5C6BE000D0D279 /* TextDiagnosticBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 352246E50F5C6BE000D0D279 /* TextDiagnosticBuffer.cpp */; };
+		352246EC0F5C6BE000D0D279 /* TextDiagnosticPrinter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 352246E60F5C6BE000D0D279 /* TextDiagnosticPrinter.cpp */; };
+		352712510DAFE54700C76352 /* IdentifierResolver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 352712500DAFE54700C76352 /* IdentifierResolver.cpp */; };
+		3534A01D0E129849002709B2 /* ParseCXXInlineMethods.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3534A01C0E129849002709B2 /* ParseCXXInlineMethods.cpp */; };
+		3536456B0E23EBF7009C6509 /* Environment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3536456A0E23EBF7009C6509 /* Environment.cpp */; };
+		3537AA0E0ECD08A4008F7CDC /* PreprocessorLexer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3537AA0D0ECD08A4008F7CDC /* PreprocessorLexer.cpp */; };
+		353959D50EE5F88A00E82461 /* ParseTemplate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 353959D40EE5F88A00E82461 /* ParseTemplate.cpp */; };
+		35475B200E79973F0000BFE4 /* CGCall.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 35475B1F0E79973F0000BFE4 /* CGCall.cpp */; };
+		355106860E9A8507006A4E44 /* MemRegion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 355106850E9A8507006A4E44 /* MemRegion.cpp */; };
+		3551068C0E9A8546006A4E44 /* ParsePragma.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3551068A0E9A8546006A4E44 /* ParsePragma.cpp */; };
+		3551068D0E9A8546006A4E44 /* ParseTentative.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3551068B0E9A8546006A4E44 /* ParseTentative.cpp */; };
+		3552E7550E520D80003A8CA5 /* PPCaching.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3552E7540E520D80003A8CA5 /* PPCaching.cpp */; };
+		3552E7590E520DD7003A8CA5 /* CGObjCMac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3552E7580E520DD7003A8CA5 /* CGObjCMac.cpp */; };
+		35544B880F5C7FD700D92AA9 /* RangeConstraintManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 35544B850F5C7FD700D92AA9 /* RangeConstraintManager.cpp */; };
+		35544B890F5C7FD700D92AA9 /* SimpleConstraintManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 35544B860F5C7FD700D92AA9 /* SimpleConstraintManager.cpp */; };
+		35544B8C0F5C803200D92AA9 /* SemaTemplateInstantiate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 35544B8B0F5C803200D92AA9 /* SemaTemplateInstantiate.cpp */; };
+		35585DC00EAFBC4500D0A97A /* SemaOverload.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 35585DBE0EAFBC4500D0A97A /* SemaOverload.cpp */; };
+		3558F76D0E267C8300A5B0DF /* BasicStore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3558F76C0E267C8300A5B0DF /* BasicStore.cpp */; };
+		356EF9B50C8F7DDF006650F5 /* LiveVariables.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 356EF9B40C8F7DDF006650F5 /* LiveVariables.cpp */; };
+		35707EFE0CD0F5CC000B2204 /* SourceLocation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 35707EFD0CD0F5CC000B2204 /* SourceLocation.cpp */; };
+		357EA27D0F2526F300439B60 /* SemaLookup.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 357EA27C0F2526F300439B60 /* SemaLookup.cpp */; };
+		35862B0D0E3628CB0009F542 /* CheckDeadStores.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 35862B0C0E3628CB0009F542 /* CheckDeadStores.cpp */; };
+		35862B120E3629850009F542 /* GRExprEngineInternalChecks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 35862B110E3629850009F542 /* GRExprEngineInternalChecks.cpp */; };
+		358CFBB80E65AB04002A8E19 /* BasicConstraintManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 358CFBB70E65AB04002A8E19 /* BasicConstraintManager.cpp */; };
+		358F51520E529AA4007F2102 /* GRState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 358F51510E529AA4007F2102 /* GRState.cpp */; };
+		3591853F0EFB1088000039AF /* SemaTemplate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3591853E0EFB1088000039AF /* SemaTemplate.cpp */; };
+		3593790A0DA48ABA0043B19C /* BugReporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 359379090DA48ABA0043B19C /* BugReporter.cpp */; };
+		3595AFB80E1C8D62004CDF09 /* CheckObjCDealloc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3595AFB70E1C8D62004CDF09 /* CheckObjCDealloc.cpp */; };
+		3599299B0DE2425300A8A33E /* SemaInit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3599299A0DE2425300A8A33E /* SemaInit.cpp */; };
+		35A057E20EAE2D950069249F /* RegionStore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 35A057E00EAE2D950069249F /* RegionStore.cpp */; };
+		35A057E30EAE2D950069249F /* SVals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 35A057E10EAE2D950069249F /* SVals.cpp */; };
+		35A3E7020DD3874400757F74 /* CGDebugInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 35A3E7000DD3874400757F74 /* CGDebugInfo.cpp */; };
+		35A8FCF90D9B4B2A001C2F97 /* PathDiagnostic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 35A8FCF80D9B4B29001C2F97 /* PathDiagnostic.cpp */; };
+		35BAC1E80E82C5B7003FB76F /* CheckNSError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 35BAC1E70E82C5B7003FB76F /* CheckNSError.cpp */; };
+		35D55B270D81D8C60092E734 /* BasicValueFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 35D55B240D81D8C60092E734 /* BasicValueFactory.cpp */; };
+		35D55B280D81D8C60092E734 /* CFRefCount.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 35D55B250D81D8C60092E734 /* CFRefCount.cpp */; };
+		35E194690ECB82FB00F21733 /* SemaCXXScopeSpec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 35E194670ECB82FB00F21733 /* SemaCXXScopeSpec.cpp */; };
+		35E1946A0ECB82FB00F21733 /* SemaCXXCast.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 35E194680ECB82FB00F21733 /* SemaCXXCast.cpp */; };
+		35E1946D0ECB83C100F21733 /* PTHLexer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 35E1946C0ECB83C100F21733 /* PTHLexer.cpp */; };
+		35EF67700DAD1D2C00B19414 /* SemaDeclCXX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 35EF676F0DAD1D2C00B19414 /* SemaDeclCXX.cpp */; };
+		35EFEFB60DB67ED60020783D /* GRTransferFuncs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 35EFEFB50DB67ED60020783D /* GRTransferFuncs.cpp */; };
+		35F2A01E0E36AFF100D17527 /* CheckObjCUnusedIVars.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 35F2A01D0E36AFF100D17527 /* CheckObjCUnusedIVars.cpp */; };
+		35F8D0D60D9B82CD00D91C5E /* BasicObjCFoundationChecks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 35F8D0D50D9B82CD00D91C5E /* BasicObjCFoundationChecks.cpp */; };
+		72D16C1F0D9975C400E6DA4A /* HTMLRewrite.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 72D16C1E0D9975C400E6DA4A /* HTMLRewrite.cpp */; };
+		84AF36A10CB17A3B00C820A5 /* DeclObjC.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 84AF36A00CB17A3B00C820A5 /* DeclObjC.h */; };
+		84D9A8880C1A57E100AC7ABC /* AttributeList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84D9A8870C1A57E100AC7ABC /* AttributeList.cpp */; };
+		84D9A88C0C1A581300AC7ABC /* AttributeList.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 84D9A88B0C1A581300AC7ABC /* AttributeList.h */; };
+		9012911D1048068D0083456D /* ASTUnit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9012911C1048068D0083456D /* ASTUnit.cpp */; };
+		90129121104812F90083456D /* CIndex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9012911F104812F90083456D /* CIndex.cpp */; };
+		906BF4B00F83BA2E001071FA /* ConvertUTF.c in Sources */ = {isa = PBXBuildFile; fileRef = 906BF4AF0F83BA2E001071FA /* ConvertUTF.c */; };
+		90F9EFAA104ABDED00D09A15 /* c-index-test.c in Sources */ = {isa = PBXBuildFile; fileRef = 90F9EFA9104ABDED00D09A15 /* c-index-test.c */; };
+		90FD6D7B103C3D49005F5B73 /* Analyzer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 90FD6D6D103C3D49005F5B73 /* Analyzer.cpp */; };
+		90FD6D7C103C3D49005F5B73 /* ASTLocation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 90FD6D6E103C3D49005F5B73 /* ASTLocation.cpp */; };
+		90FD6D7D103C3D49005F5B73 /* DeclReferenceMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 90FD6D70103C3D49005F5B73 /* DeclReferenceMap.cpp */; };
+		90FD6D7E103C3D49005F5B73 /* Entity.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 90FD6D71103C3D49005F5B73 /* Entity.cpp */; };
+		90FD6D7F103C3D49005F5B73 /* GlobalSelector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 90FD6D73103C3D49005F5B73 /* GlobalSelector.cpp */; };
+		90FD6D80103C3D49005F5B73 /* Handlers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 90FD6D74103C3D49005F5B73 /* Handlers.cpp */; };
+		90FD6D81103C3D49005F5B73 /* Indexer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 90FD6D75103C3D49005F5B73 /* Indexer.cpp */; };
+		90FD6D82103C3D49005F5B73 /* IndexProvider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 90FD6D76103C3D49005F5B73 /* IndexProvider.cpp */; };
+		90FD6D83103C3D49005F5B73 /* Program.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 90FD6D77103C3D49005F5B73 /* Program.cpp */; };
+		90FD6D84103C3D49005F5B73 /* ResolveLocation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 90FD6D79103C3D49005F5B73 /* ResolveLocation.cpp */; };
+		90FD6D85103C3D49005F5B73 /* SelectorMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 90FD6D7A103C3D49005F5B73 /* SelectorMap.cpp */; };
+		90FD6DB6103D977E005F5B73 /* index-test.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 90FD6DB5103D977E005F5B73 /* index-test.cpp */; };
+		BDF87CF70FD746F300BBF872 /* SemaTemplateDeduction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BDF87CF60FD746F300BBF872 /* SemaTemplateDeduction.cpp */; };
+		BF89C3E211595818001C2D68 /* AnalysisBasedWarnings.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BF89C3E111595818001C2D68 /* AnalysisBasedWarnings.cpp */; };
+		BF89C3E91159594A001C2D68 /* SemaObjCProperty.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BF89C3E81159594A001C2D68 /* SemaObjCProperty.cpp */; };
+		BF89C3F911595A01001C2D68 /* SemaType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BF89C3F811595A01001C2D68 /* SemaType.cpp */; };
+		BF89C3FB11595A37001C2D68 /* SemaCodeComplete.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BF89C3FA11595A37001C2D68 /* SemaCodeComplete.cpp */; };
+		BF89C3FD11595A5D001C2D68 /* SemaExceptionSpec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BF89C3FC11595A5D001C2D68 /* SemaExceptionSpec.cpp */; };
+		DE01DA490B12ADA300AC22CE /* PPCallbacks.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE01DA480B12ADA300AC22CE /* PPCallbacks.h */; };
+		DE06756C0C051CFE00EBBFD8 /* ParseExprCXX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE06756B0C051CFE00EBBFD8 /* ParseExprCXX.cpp */; };
+		DE06B73E0A8307640050E87E /* LangOptions.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE06B73D0A8307640050E87E /* LangOptions.h */; };
+		DE06BECB0A854E4B0050E87E /* Scope.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE06BECA0A854E4B0050E87E /* Scope.h */; };
+		DE06D4310A8BB52D0050E87E /* Parser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE06D42F0A8BB52D0050E87E /* Parser.cpp */; };
+		DE06E8140A8FF9330050E87E /* Action.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE06E8130A8FF9330050E87E /* Action.h */; };
+		DE0FCA630A95859D00248FD5 /* Expr.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE0FCA620A95859D00248FD5 /* Expr.h */; };
+		DE17336E0B068DC20080B521 /* DeclSpec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE17336D0B068DC20080B521 /* DeclSpec.cpp */; };
+		DE1733700B068DC60080B521 /* DeclSpec.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE17336F0B068DC60080B521 /* DeclSpec.h */; };
+		DE1F22030A7D852A00FBF588 /* Parser.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE1F22020A7D852A00FBF588 /* Parser.h */; };
+		DE224FF80C7AA98800D370A5 /* CGExprComplex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE224FF70C7AA98800D370A5 /* CGExprComplex.cpp */; };
+		DE2252700C7E82D000D370A5 /* CGExprScalar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE22526F0C7E82D000D370A5 /* CGExprScalar.cpp */; };
+		DE2255FC0C8004E600D370A5 /* ParseDeclCXX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE2255FB0C8004E600D370A5 /* ParseDeclCXX.cpp */; };
+		DE22BCF20E14197E0094DC60 /* SemaDeclAttr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE22BCF10E14197E0094DC60 /* SemaDeclAttr.cpp */; };
+		DE344AB80AE5DF6D00DBC861 /* HeaderSearch.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE344AB70AE5DF6D00DBC861 /* HeaderSearch.h */; };
+		DE344B540AE5E46C00DBC861 /* HeaderSearch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE344B530AE5E46C00DBC861 /* HeaderSearch.cpp */; };
+		DE3450D70AEB543100DBC861 /* DirectoryLookup.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE3450D60AEB543100DBC861 /* DirectoryLookup.h */; };
+		DE3452810AEF1B1800DBC861 /* Stmt.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE3452800AEF1B1800DBC861 /* Stmt.h */; };
+		DE345C1A0AFC658B00DBC861 /* StmtVisitor.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE345C190AFC658B00DBC861 /* StmtVisitor.h */; };
+		DE345F220AFD347900DBC861 /* StmtNodes.def in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE345F210AFD347900DBC861 /* StmtNodes.def */; };
+		DE3460000AFDCC1900DBC861 /* ParseObjc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE345FFF0AFDCC1900DBC861 /* ParseObjc.cpp */; };
+		DE3460050AFDCC6500DBC861 /* ParseInit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE3460040AFDCC6500DBC861 /* ParseInit.cpp */; };
+		DE34600B0AFDCCBF00DBC861 /* ParseStmt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE34600A0AFDCCBF00DBC861 /* ParseStmt.cpp */; };
+		DE34600F0AFDCCCE00DBC861 /* ParseDecl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE34600E0AFDCCCE00DBC861 /* ParseDecl.cpp */; };
+		DE3460130AFDCCDA00DBC861 /* ParseExpr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE3460120AFDCCDA00DBC861 /* ParseExpr.cpp */; };
+		DE3461270AFE68BE00DBC861 /* MinimalAction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE3461260AFE68BE00DBC861 /* MinimalAction.cpp */; };
+		DE3464220B03040900DBC861 /* Type.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE3464210B03040900DBC861 /* Type.h */; };
+		DE37252E0FE481AD00CF2CC2 /* Builtins.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE37252D0FE481AD00CF2CC2 /* Builtins.cpp */; };
+		DE38CD500D794D0100A273B6 /* CGObjCGNU.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE38CD4F0D794D0100A273B6 /* CGObjCGNU.cpp */; };
+		DE3986F00CB8D4B300223765 /* IdentifierTable.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE3986EF0CB8D4B300223765 /* IdentifierTable.h */; };
+		DE3986F40CB8D50C00223765 /* IdentifierTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE3986F30CB8D50C00223765 /* IdentifierTable.cpp */; };
+		DE4121350D7F1C1C0080F80A /* SymbolManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE4121270D7F1C1C0080F80A /* SymbolManager.cpp */; };
+		DE4121360D7F1C1C0080F80A /* ExplodedGraph.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE4121280D7F1C1C0080F80A /* ExplodedGraph.cpp */; };
+		DE4121370D7F1C1C0080F80A /* UninitializedValues.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE4121290D7F1C1C0080F80A /* UninitializedValues.cpp */; };
+		DE4121380D7F1C1C0080F80A /* GRCoreEngine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE41212A0D7F1C1C0080F80A /* GRCoreEngine.cpp */; };
+		DE41213C0D7F1C1C0080F80A /* GRSimpleVals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE41212F0D7F1C1C0080F80A /* GRSimpleVals.cpp */; };
+		DE41213D0D7F1C1C0080F80A /* GRBlockCounter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE4121300D7F1C1C0080F80A /* GRBlockCounter.cpp */; };
+		DE41213E0D7F1C1C0080F80A /* GRExprEngine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE4121310D7F1C1C0080F80A /* GRExprEngine.cpp */; };
+		DE4264FC0C113592005A861D /* CGDecl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE4264FB0C113592005A861D /* CGDecl.cpp */; };
+		DE46BF280AE0A82D00CC047C /* TargetInfo.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE46BF270AE0A82D00CC047C /* TargetInfo.h */; };
+		DE4772FA0C10EAE5002239E8 /* CGStmt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE4772F90C10EAE5002239E8 /* CGStmt.cpp */; };
+		DE4772FC0C10EAEC002239E8 /* CGExpr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE4772FB0C10EAEC002239E8 /* CGExpr.cpp */; };
+		DE47999C0D2EBE1A00706D2D /* SemaExprObjC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE47999B0D2EBE1A00706D2D /* SemaExprObjC.cpp */; };
+		DE4DC7A30EA1C33E00069E5A /* TokenRewriter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE4DC7A20EA1C33E00069E5A /* TokenRewriter.cpp */; };
+		DE67E70B0C020EC500F66BC5 /* SemaType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE67E70A0C020EC500F66BC5 /* SemaType.cpp */; };
+		DE67E70D0C020ECA00F66BC5 /* SemaStmt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE67E70C0C020ECA00F66BC5 /* SemaStmt.cpp */; };
+		DE67E70F0C020ECF00F66BC5 /* SemaExprCXX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE67E70E0C020ECF00F66BC5 /* SemaExprCXX.cpp */; };
+		DE67E7110C020ED400F66BC5 /* SemaExpr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE67E7100C020ED400F66BC5 /* SemaExpr.cpp */; };
+		DE67E7130C020ED900F66BC5 /* SemaDecl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE67E7120C020ED900F66BC5 /* SemaDecl.cpp */; };
+		DE67E7150C020EDF00F66BC5 /* Sema.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE67E7140C020EDF00F66BC5 /* Sema.h */; };
+		DE67E7170C020EE400F66BC5 /* Sema.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE67E7160C020EE400F66BC5 /* Sema.cpp */; };
+		DE67E71A0C020F4F00F66BC5 /* ParseAST.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE67E7190C020F4F00F66BC5 /* ParseAST.cpp */; };
+		DE67E7280C02109800F66BC5 /* ParseAST.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE67E7270C02109800F66BC5 /* ParseAST.h */; };
+		DE6951C70C4D1F5D00A5826B /* RecordLayout.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE6951C60C4D1F5D00A5826B /* RecordLayout.h */; };
+		DE6954640C5121BD00A5826B /* Token.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE6954630C5121BD00A5826B /* Token.h */; };
+		DE704B260D0FBEBE009C7762 /* SemaDeclObjC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE704B250D0FBEBE009C7762 /* SemaDeclObjC.cpp */; };
+		DE704DD20D1668A4009C7762 /* HeaderMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE704DD10D1668A4009C7762 /* HeaderMap.cpp */; };
+		DE75ED290B044DC90020CF81 /* ASTContext.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE75ED280B044DC90020CF81 /* ASTContext.h */; };
+		DE85CD810D8380B10070E26E /* TokenLexer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE85CD800D8380B10070E26E /* TokenLexer.cpp */; };
+		DE85CDA30D8383B20070E26E /* MacroArgs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE85CDA20D8383B20070E26E /* MacroArgs.cpp */; };
+		DE85CDAC0D838C120070E26E /* PPMacroExpansion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE85CDAB0D838C120070E26E /* PPMacroExpansion.cpp */; };
+		DE85CDB00D838C390070E26E /* PPDirectives.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE85CDAF0D838C390070E26E /* PPDirectives.cpp */; };
+		DE85CDB60D839BAE0070E26E /* PPLexerChange.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE85CDB50D839BAE0070E26E /* PPLexerChange.cpp */; };
+		DE928B130C05659200231DA4 /* ModuleBuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE928B120C05659200231DA4 /* ModuleBuilder.cpp */; };
+		DE928B200C0565B000231DA4 /* ModuleBuilder.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE928B1F0C0565B000231DA4 /* ModuleBuilder.h */; };
+		DE928B7D0C0A615100231DA4 /* CodeGenModule.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE928B7C0C0A615100231DA4 /* CodeGenModule.h */; };
+		DE928B7F0C0A615600231DA4 /* CodeGenModule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE928B7E0C0A615600231DA4 /* CodeGenModule.cpp */; };
+		DE928B810C0A615B00231DA4 /* CodeGenFunction.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE928B800C0A615B00231DA4 /* CodeGenFunction.h */; };
+		DE928B830C0A616000231DA4 /* CodeGenFunction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE928B820C0A616000231DA4 /* CodeGenFunction.cpp */; };
+		DEAEE98B0A5A2B970045101B /* MultipleIncludeOpt.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DEAEE98A0A5A2B970045101B /* MultipleIncludeOpt.h */; };
+		DEAEED4B0A5AF89A0045101B /* NOTES.txt in CopyFiles */ = {isa = PBXBuildFile; fileRef = DEAEED4A0A5AF89A0045101B /* NOTES.txt */; };
+		DEB077990F44F97800F5A2BE /* TokenConcatenation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DEB077980F44F97800F5A2BE /* TokenConcatenation.cpp */; };
+		DEB07AC80F4A427E00F5A2BE /* SemaAttr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DEB07AC70F4A427E00F5A2BE /* SemaAttr.cpp */; };
+		DEC8D9910A9433CD00353FCA /* Decl.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DEC8D9900A9433CD00353FCA /* Decl.h */; };
+		DEC8D9A40A94346E00353FCA /* AST.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DEC8D9A30A94346E00353FCA /* AST.h */; };
+		DECAB0D00DB3C84200E13CCB /* RewriteRope.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DECAB0CF0DB3C84200E13CCB /* RewriteRope.cpp */; };
+		DECB6D650F9AE26600F5FBC7 /* JumpDiagnostics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DECB6D640F9AE26600F5FBC7 /* JumpDiagnostics.cpp */; };
+		DECB6F070F9D93A800F5FBC7 /* InitPreprocessor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DECB6F060F9D93A800F5FBC7 /* InitPreprocessor.cpp */; };
+		DECB77130FA5752300F5FBC7 /* PCHReaderStmt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DECB77120FA5752300F5FBC7 /* PCHReaderStmt.cpp */; };
+		DECB77790FA579B000F5FBC7 /* PCHReaderDecl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DECB77780FA579B000F5FBC7 /* PCHReaderDecl.cpp */; };
+		DECB77F70FA5850200F5FBC7 /* PCHWriterDecl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DECB77F60FA5850200F5FBC7 /* PCHWriterDecl.cpp */; };
+		DECB78170FA5882F00F5FBC7 /* PCHWriterStmt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DECB78160FA5882F00F5FBC7 /* PCHWriterStmt.cpp */; };
+		DED626C90AE0C065001E80A4 /* TargetInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DED626C80AE0C065001E80A4 /* TargetInfo.cpp */; };
+		DED7D7410A524295003AD0FB /* Diagnostic.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DED7D7310A524295003AD0FB /* Diagnostic.h */; };
+		DED7D7430A524295003AD0FB /* FileManager.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DED7D7330A524295003AD0FB /* FileManager.h */; };
+		DED7D7450A524295003AD0FB /* SourceLocation.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DED7D7350A524295003AD0FB /* SourceLocation.h */; };
+		DED7D7460A524295003AD0FB /* SourceManager.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DED7D7360A524295003AD0FB /* SourceManager.h */; };
+		DED7D7470A524295003AD0FB /* TokenKinds.def in CopyFiles */ = {isa = PBXBuildFile; fileRef = DED7D7370A524295003AD0FB /* TokenKinds.def */; };
+		DED7D7480A524295003AD0FB /* TokenKinds.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DED7D7380A524295003AD0FB /* TokenKinds.h */; };
+		DED7D74A0A524295003AD0FB /* Lexer.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DED7D73B0A524295003AD0FB /* Lexer.h */; };
+		DED7D74D0A524295003AD0FB /* MacroInfo.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DED7D73E0A524295003AD0FB /* MacroInfo.h */; };
+		DED7D74E0A524295003AD0FB /* Pragma.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DED7D73F0A524295003AD0FB /* Pragma.h */; };
+		DED7D74F0A524295003AD0FB /* Preprocessor.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DED7D7400A524295003AD0FB /* Preprocessor.h */; };
+		DED7D77A0A5242C7003AD0FB /* Diagnostic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DED7D75D0A5242C7003AD0FB /* Diagnostic.cpp */; };
+		DED7D77B0A5242C7003AD0FB /* FileManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DED7D75E0A5242C7003AD0FB /* FileManager.cpp */; };
+		DED7D7890A5242C7003AD0FB /* SourceManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DED7D76D0A5242C7003AD0FB /* SourceManager.cpp */; };
+		DED7D78A0A5242C7003AD0FB /* TokenKinds.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DED7D76E0A5242C7003AD0FB /* TokenKinds.cpp */; };
+		DED7D7C30A5242E6003AD0FB /* Lexer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DED7D79E0A5242E6003AD0FB /* Lexer.cpp */; };
+		DED7D7C50A5242E6003AD0FB /* MacroInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DED7D7A00A5242E6003AD0FB /* MacroInfo.cpp */; };
+		DED7D7C70A5242E6003AD0FB /* PPExpressions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DED7D7A20A5242E6003AD0FB /* PPExpressions.cpp */; };
+		DED7D7C80A5242E6003AD0FB /* Pragma.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DED7D7A30A5242E6003AD0FB /* Pragma.cpp */; };
+		DED7D7C90A5242E6003AD0FB /* Preprocessor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DED7D7A40A5242E6003AD0FB /* Preprocessor.cpp */; };
+		DED7D7D80A524302003AD0FB /* README.txt in CopyFiles */ = {isa = PBXBuildFile; fileRef = DED7D7D70A524302003AD0FB /* README.txt */; };
+		DED7D9180A52518C003AD0FB /* ScratchBuffer.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DED7D9170A52518C003AD0FB /* ScratchBuffer.h */; };
+		DED7D9E50A5257F6003AD0FB /* ScratchBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DED7D9E40A5257F6003AD0FB /* ScratchBuffer.cpp */; };
+		DEDFE6460F7B3B4E0035BD10 /* driver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DEDFE6450F7B3B4E0035BD10 /* driver.cpp */; };
+		DEDFE65A0F7B3B830035BD10 /* Types.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DEDFE6480F7B3B830035BD10 /* Types.cpp */; };
+		DEDFE65B0F7B3B830035BD10 /* Tools.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DEDFE64A0F7B3B830035BD10 /* Tools.cpp */; };
+		DEDFE65C0F7B3B830035BD10 /* Compilation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DEDFE64C0F7B3B830035BD10 /* Compilation.cpp */; };
+		DEDFE65D0F7B3B830035BD10 /* ArgList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DEDFE64D0F7B3B830035BD10 /* ArgList.cpp */; };
+		DEDFE65E0F7B3B830035BD10 /* Arg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DEDFE64E0F7B3B830035BD10 /* Arg.cpp */; };
+		DEDFE65F0F7B3B830035BD10 /* Action.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DEDFE64F0F7B3B830035BD10 /* Action.cpp */; };
+		DEDFE6600F7B3B830035BD10 /* Phases.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DEDFE6500F7B3B830035BD10 /* Phases.cpp */; };
+		DEDFE6610F7B3B830035BD10 /* OptTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DEDFE6510F7B3B830035BD10 /* OptTable.cpp */; };
+		DEDFE6620F7B3B830035BD10 /* Option.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DEDFE6520F7B3B830035BD10 /* Option.cpp */; };
+		DEDFE6630F7B3B830035BD10 /* Job.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DEDFE6530F7B3B830035BD10 /* Job.cpp */; };
+		DEDFE6640F7B3B830035BD10 /* ToolChains.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DEDFE6550F7B3B830035BD10 /* ToolChains.cpp */; };
+		DEDFE6650F7B3B830035BD10 /* ToolChain.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DEDFE6560F7B3B830035BD10 /* ToolChain.cpp */; };
+		DEDFE6660F7B3B830035BD10 /* Tool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DEDFE6570F7B3B830035BD10 /* Tool.cpp */; };
+		DEDFE6670F7B3B830035BD10 /* HostInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DEDFE6580F7B3B830035BD10 /* HostInfo.cpp */; };
+		DEDFE6680F7B3B830035BD10 /* Driver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DEDFE6590F7B3B830035BD10 /* Driver.cpp */; };
+		DEEBBD440C19C5D200A9FE82 /* TODO.txt in CopyFiles */ = {isa = PBXBuildFile; fileRef = DEEBBD430C19C5D200A9FE82 /* TODO.txt */; };
+		DEEBC3BA0C2363B800A9FE82 /* CodeGenTypes.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DEEBC3B90C2363B800A9FE82 /* CodeGenTypes.h */; };
+		DEEBC3BC0C2363BC00A9FE82 /* CodeGenTypes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DEEBC3BB0C2363BC00A9FE82 /* CodeGenTypes.cpp */; };
+		DEF165710F8FB34D0098507F /* PCHWriter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DEF165700F8FB34D0098507F /* PCHWriter.cpp */; };
+		DEF165750F8FB3510098507F /* PCHReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DEF165740F8FB3510098507F /* PCHReader.cpp */; };
+		DEF168400F9548DC0098507F /* FixItRewriter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DEF1683F0F9548DC0098507F /* FixItRewriter.cpp */; };
+		DEF2E95F0C5FBD74000C4259 /* InternalsManual.html in CopyFiles */ = {isa = PBXBuildFile; fileRef = DEF2E95E0C5FBD74000C4259 /* InternalsManual.html */; };
+		DEF2EFF30C6CDD74000C4259 /* CGExprAgg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DEF2EFF20C6CDD74000C4259 /* CGExprAgg.cpp */; };
+		DEF2F0100C6CFED5000C4259 /* SemaChecking.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DEF2F00F0C6CFED5000C4259 /* SemaChecking.cpp */; };
+		DEF7D9F70C9C8B1A0001F598 /* Rewriter.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DEF7D9F60C9C8B1A0001F598 /* Rewriter.h */; };
+		DEF7D9F90C9C8B1D0001F598 /* Rewriter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DEF7D9F80C9C8B1D0001F598 /* Rewriter.cpp */; };
+		DEFFECA70DB1546600B4E7C3 /* DeltaTree.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DEFFECA60DB1546600B4E7C3 /* DeltaTree.cpp */; };
+		E16B523510D30B2400430AC9 /* cc1_main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E16B523410D30B2400430AC9 /* cc1_main.cpp */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+		8DD76F690486A84900D96B5E /* CopyFiles */ = {
+			isa = PBXCopyFilesBuildPhase;
+			buildActionMask = 8;
+			dstPath = /usr/share/man/man1/;
+			dstSubfolderSpec = 0;
+			files = (
+				DED7D7410A524295003AD0FB /* Diagnostic.h in CopyFiles */,
+				DED7D7430A524295003AD0FB /* FileManager.h in CopyFiles */,
+				DED7D7450A524295003AD0FB /* SourceLocation.h in CopyFiles */,
+				DED7D7460A524295003AD0FB /* SourceManager.h in CopyFiles */,
+				DED7D7470A524295003AD0FB /* TokenKinds.def in CopyFiles */,
+				DED7D7480A524295003AD0FB /* TokenKinds.h in CopyFiles */,
+				DED7D74A0A524295003AD0FB /* Lexer.h in CopyFiles */,
+				DED7D74D0A524295003AD0FB /* MacroInfo.h in CopyFiles */,
+				DED7D74E0A524295003AD0FB /* Pragma.h in CopyFiles */,
+				DED7D74F0A524295003AD0FB /* Preprocessor.h in CopyFiles */,
+				DED7D7D80A524302003AD0FB /* README.txt in CopyFiles */,
+				DED7D9180A52518C003AD0FB /* ScratchBuffer.h in CopyFiles */,
+				DEAEE98B0A5A2B970045101B /* MultipleIncludeOpt.h in CopyFiles */,
+				DEAEED4B0A5AF89A0045101B /* NOTES.txt in CopyFiles */,
+				DE1F22030A7D852A00FBF588 /* Parser.h in CopyFiles */,
+				DE06B73E0A8307640050E87E /* LangOptions.h in CopyFiles */,
+				DE06BECB0A854E4B0050E87E /* Scope.h in CopyFiles */,
+				DE06E8140A8FF9330050E87E /* Action.h in CopyFiles */,
+				DEC8D9910A9433CD00353FCA /* Decl.h in CopyFiles */,
+				DEC8D9A40A94346E00353FCA /* AST.h in CopyFiles */,
+				DE0FCA630A95859D00248FD5 /* Expr.h in CopyFiles */,
+				DE46BF280AE0A82D00CC047C /* TargetInfo.h in CopyFiles */,
+				DE344AB80AE5DF6D00DBC861 /* HeaderSearch.h in CopyFiles */,
+				DE3450D70AEB543100DBC861 /* DirectoryLookup.h in CopyFiles */,
+				DE3452810AEF1B1800DBC861 /* Stmt.h in CopyFiles */,
+				DE345C1A0AFC658B00DBC861 /* StmtVisitor.h in CopyFiles */,
+				DE345F220AFD347900DBC861 /* StmtNodes.def in CopyFiles */,
+				DE3464220B03040900DBC861 /* Type.h in CopyFiles */,
+				DE75ED290B044DC90020CF81 /* ASTContext.h in CopyFiles */,
+				DE1733700B068DC60080B521 /* DeclSpec.h in CopyFiles */,
+				DE01DA490B12ADA300AC22CE /* PPCallbacks.h in CopyFiles */,
+				1A30A9E90B93A4C800201A91 /* ExprCXX.h in CopyFiles */,
+				1A869A700BA2164C008DA07A /* LiteralSupport.h in CopyFiles */,
+				DE67E7150C020EDF00F66BC5 /* Sema.h in CopyFiles */,
+				DE67E7280C02109800F66BC5 /* ParseAST.h in CopyFiles */,
+				DE928B200C0565B000231DA4 /* ModuleBuilder.h in CopyFiles */,
+				DE928B7D0C0A615100231DA4 /* CodeGenModule.h in CopyFiles */,
+				DE928B810C0A615B00231DA4 /* CodeGenFunction.h in CopyFiles */,
+				DEEBBD440C19C5D200A9FE82 /* TODO.txt in CopyFiles */,
+				84D9A88C0C1A581300AC7ABC /* AttributeList.h in CopyFiles */,
+				DEEBC3BA0C2363B800A9FE82 /* CodeGenTypes.h in CopyFiles */,
+				DE6951C70C4D1F5D00A5826B /* RecordLayout.h in CopyFiles */,
+				DE6954640C5121BD00A5826B /* Token.h in CopyFiles */,
+				DEF2E95F0C5FBD74000C4259 /* InternalsManual.html in CopyFiles */,
+				DEF7D9F70C9C8B1A0001F598 /* Rewriter.h in CopyFiles */,
+				84AF36A10CB17A3B00C820A5 /* DeclObjC.h in CopyFiles */,
+				DE3986F00CB8D4B300223765 /* IdentifierTable.h in CopyFiles */,
+			);
+			runOnlyForDeploymentPostprocessing = 1;
+		};
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+		035611470DA6A45C00D2EF2A /* DeclBase.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = DeclBase.h; path = clang/AST/DeclBase.h; sourceTree = "<group>"; tabWidth = 2; };
+		03F50AC50D416EAA00B9CF60 /* Targets.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = Targets.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		1A15C407118226980092260D /* ASTImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = ASTImporter.h; path = clang/AST/ASTImporter.h; sourceTree = "<group>"; tabWidth = 2; };
+		1A15C408118226980092260D /* ASTVector.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = ASTVector.h; path = clang/AST/ASTVector.h; sourceTree = "<group>"; tabWidth = 2; };
+		1A15C409118226980092260D /* CharUnits.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = CharUnits.h; path = clang/AST/CharUnits.h; sourceTree = "<group>"; tabWidth = 2; };
+		1A15C40A118226980092260D /* DeclAccessPair.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = DeclAccessPair.h; path = clang/AST/DeclAccessPair.h; sourceTree = "<group>"; tabWidth = 2; };
+		1A15C40B118226980092260D /* DeclFriend.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = DeclFriend.h; path = clang/AST/DeclFriend.h; sourceTree = "<group>"; tabWidth = 2; };
+		1A15C40C118226980092260D /* DependentDiagnostic.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = DependentDiagnostic.h; path = clang/AST/DependentDiagnostic.h; sourceTree = "<group>"; tabWidth = 2; };
+		1A15C40D118226980092260D /* TemplateBase.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = TemplateBase.h; path = clang/AST/TemplateBase.h; sourceTree = "<group>"; tabWidth = 2; };
+		1A15C40E118226980092260D /* UnresolvedSet.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = UnresolvedSet.h; path = clang/AST/UnresolvedSet.h; sourceTree = "<group>"; tabWidth = 2; };
+		1A15C40F118226980092260D /* UsuallyTinyPtrVector.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = UsuallyTinyPtrVector.h; path = clang/AST/UsuallyTinyPtrVector.h; sourceTree = "<group>"; tabWidth = 2; };
+		1A2193CB0F45EEB700C0713D /* ABIInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = ABIInfo.h; path = lib/CodeGen/ABIInfo.h; sourceTree = "<group>"; tabWidth = 2; };
+		1A2193CC0F45EEB700C0713D /* Mangle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = Mangle.cpp; path = lib/CodeGen/Mangle.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		1A2193CD0F45EEB700C0713D /* Mangle.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = Mangle.h; path = lib/CodeGen/Mangle.h; sourceTree = "<group>"; tabWidth = 2; };
+		1A2A54A40FD1DD1C00F4CE45 /* AnalysisConsumer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AnalysisConsumer.cpp; path = lib/Frontend/AnalysisConsumer.cpp; sourceTree = "<group>"; };
+		1A2A54A50FD1DD1C00F4CE45 /* ASTConsumers.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = ASTConsumers.cpp; path = lib/Frontend/ASTConsumers.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		1A2A54A70FD1DD1C00F4CE45 /* CacheTokens.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CacheTokens.cpp; path = lib/Frontend/CacheTokens.cpp; sourceTree = "<group>"; };
+		1A2A54A80FD1DD1C00F4CE45 /* DependencyFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DependencyFile.cpp; path = lib/Frontend/DependencyFile.cpp; sourceTree = "<group>"; };
+		1A2A54A90FD1DD1C00F4CE45 /* DiagChecker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DiagChecker.cpp; path = lib/Frontend/DiagChecker.cpp; sourceTree = "<group>"; };
+		1A2A54AA0FD1DD1C00F4CE45 /* DocumentXML.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DocumentXML.cpp; path = lib/Frontend/DocumentXML.cpp; sourceTree = "<group>"; };
+		1A2A54AB0FD1DD1C00F4CE45 /* GeneratePCH.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = GeneratePCH.cpp; path = lib/Frontend/GeneratePCH.cpp; sourceTree = "<group>"; };
+		1A2A54AC0FD1DD1C00F4CE45 /* HTMLPrint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = HTMLPrint.cpp; path = lib/Frontend/HTMLPrint.cpp; sourceTree = "<group>"; };
+		1A2A54AD0FD1DD1C00F4CE45 /* PrintParserCallbacks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PrintParserCallbacks.cpp; path = lib/Frontend/PrintParserCallbacks.cpp; sourceTree = "<group>"; };
+		1A2A54AE0FD1DD1C00F4CE45 /* PrintPreprocessedOutput.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PrintPreprocessedOutput.cpp; path = lib/Frontend/PrintPreprocessedOutput.cpp; sourceTree = "<group>"; };
+		1A2A54B00FD1DD1C00F4CE45 /* RewriteMacros.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RewriteMacros.cpp; path = lib/Frontend/RewriteMacros.cpp; sourceTree = "<group>"; };
+		1A2A54B10FD1DD1C00F4CE45 /* RewriteObjC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = RewriteObjC.cpp; path = lib/Frontend/RewriteObjC.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		1A2A54B20FD1DD1C00F4CE45 /* RewriteTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RewriteTest.cpp; path = lib/Frontend/RewriteTest.cpp; sourceTree = "<group>"; };
+		1A2A54B30FD1DD1C00F4CE45 /* StmtXML.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StmtXML.cpp; path = lib/Frontend/StmtXML.cpp; sourceTree = "<group>"; };
+		1A2A54B40FD1DD1C00F4CE45 /* Warnings.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Warnings.cpp; path = lib/Frontend/Warnings.cpp; sourceTree = "<group>"; };
+		1A30A9E80B93A4C800201A91 /* ExprCXX.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = ExprCXX.h; path = clang/AST/ExprCXX.h; sourceTree = "<group>"; tabWidth = 2; };
+		1A31B27210ACE6DA009E0C8B /* GlobalDecl.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = GlobalDecl.h; path = lib/CodeGen/GlobalDecl.h; sourceTree = "<group>"; tabWidth = 2; };
+		1A376A2C0D4AED9B002A1C52 /* CGExprConstant.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CGExprConstant.cpp; path = lib/CodeGen/CGExprConstant.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		1A471AB40F437BC500753CE8 /* CGBlocks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CGBlocks.cpp; path = lib/CodeGen/CGBlocks.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		1A4C41BE105B4C0B0047B5E7 /* CGClass.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CGClass.cpp; path = lib/CodeGen/CGClass.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		1A535EDB107BC47B000C3AE7 /* CanonicalType.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = CanonicalType.h; path = clang/AST/CanonicalType.h; sourceTree = "<group>"; tabWidth = 2; };
+		1A5D5E570E5E81010023C059 /* CGCXX.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CGCXX.cpp; path = lib/CodeGen/CGCXX.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		1A621BB5110FE6AA009E6834 /* TargetInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = TargetInfo.cpp; path = lib/CodeGen/TargetInfo.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		1A621BB6110FE6AA009E6834 /* TargetInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = TargetInfo.h; path = lib/CodeGen/TargetInfo.h; sourceTree = "<group>"; tabWidth = 2; };
+		1A621C3A11111D61009E6834 /* CIndexCodeCompletion.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CIndexCodeCompletion.cpp; path = tools/CIndex/CIndexCodeCompletion.cpp; sourceTree = "<group>"; };
+		1A621C3B11111D61009E6834 /* CIndexer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CIndexer.cpp; path = tools/CIndex/CIndexer.cpp; sourceTree = "<group>"; };
+		1A621C3C11111D61009E6834 /* CIndexer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CIndexer.h; path = tools/CIndex/CIndexer.h; sourceTree = "<group>"; };
+		1A621C3D11111D61009E6834 /* CIndexInclusionStack.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CIndexInclusionStack.cpp; path = tools/CIndex/CIndexInclusionStack.cpp; sourceTree = "<group>"; };
+		1A621C3E11111D61009E6834 /* CIndexUSRs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CIndexUSRs.cpp; path = tools/CIndex/CIndexUSRs.cpp; sourceTree = "<group>"; };
+		1A621C3F11111D61009E6834 /* CXCursor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CXCursor.cpp; path = tools/CIndex/CXCursor.cpp; sourceTree = "<group>"; };
+		1A621C4011111D61009E6834 /* CXCursor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CXCursor.h; path = tools/CIndex/CXCursor.h; sourceTree = "<group>"; };
+		1A621C4111111D61009E6834 /* CXSourceLocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CXSourceLocation.h; path = tools/CIndex/CXSourceLocation.h; sourceTree = "<group>"; };
+		1A649E1D0F9599D9005B965E /* CGBlocks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CGBlocks.h; path = lib/CodeGen/CGBlocks.h; sourceTree = "<group>"; };
+		1A649E1E0F9599DA005B965E /* CGCXX.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = CGCXX.h; path = lib/CodeGen/CGCXX.h; sourceTree = "<group>"; tabWidth = 2; };
+		1A6B6CD110693FC900BB4A8F /* CodeCompleteConsumer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CodeCompleteConsumer.cpp; path = lib/Sema/CodeCompleteConsumer.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		1A6B6CD210693FC900BB4A8F /* SemaCodeComplete.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = SemaCodeComplete.cpp; path = lib/Sema/SemaCodeComplete.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		1A6B6CD310693FC900BB4A8F /* SemaTemplate.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = SemaTemplate.h; path = lib/Sema/SemaTemplate.h; sourceTree = "<group>"; tabWidth = 2; };
+		1A6B6E991069833600BB4A8F /* CGExprCXX.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CGExprCXX.cpp; path = lib/CodeGen/CGExprCXX.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		1A6C01F6108128710072DEE4 /* CGRTTI.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CGRTTI.cpp; path = lib/CodeGen/CGRTTI.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		1A6FE7080FD6F85800E00CA9 /* CGTemporaries.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CGTemporaries.cpp; path = lib/CodeGen/CGTemporaries.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		1A7019E90F79BC1100FEC4D1 /* DiagnosticAnalysisKinds.td */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = DiagnosticAnalysisKinds.td; sourceTree = "<group>"; };
+		1A7019EA0F79BC1100FEC4D1 /* DiagnosticASTKinds.td */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = DiagnosticASTKinds.td; sourceTree = "<group>"; };
+		1A7019EB0F79BC1100FEC4D1 /* DiagnosticCommonKinds.td */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = DiagnosticCommonKinds.td; sourceTree = "<group>"; };
+		1A7019EC0F79BC1100FEC4D1 /* DiagnosticDriverKinds.td */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = DiagnosticDriverKinds.td; sourceTree = "<group>"; };
+		1A7019ED0F79BC1100FEC4D1 /* DiagnosticFrontendKinds.td */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = DiagnosticFrontendKinds.td; sourceTree = "<group>"; };
+		1A7019EE0F79BC1100FEC4D1 /* DiagnosticLexKinds.td */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = DiagnosticLexKinds.td; sourceTree = "<group>"; };
+		1A7019EF0F79BC1100FEC4D1 /* DiagnosticParseKinds.td */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = DiagnosticParseKinds.td; sourceTree = "<group>"; };
+		1A701A250F79CE1C00FEC4D1 /* DiagnosticSemaKinds.td */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = DiagnosticSemaKinds.td; sourceTree = "<group>"; };
+		1A701B630F7C8FE400FEC4D1 /* SemaAccess.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = SemaAccess.cpp; path = lib/Sema/SemaAccess.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		1A72BEAC0D641E9400B085E9 /* Attr.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = Attr.h; path = clang/AST/Attr.h; sourceTree = "<group>"; tabWidth = 2; };
+		1A7342470C7B57D500122F56 /* CGObjC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CGObjC.cpp; path = lib/CodeGen/CGObjC.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		1A81AA18108144F40094E50B /* CGVTables.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CGVTables.cpp; path = lib/CodeGen/CGVTables.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		1A81AA5D108278A20094E50B /* CGVTables.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = CGVTables.h; path = lib/CodeGen/CGVTables.h; sourceTree = "<group>"; tabWidth = 2; };
+		1A869A6E0BA2164C008DA07A /* LiteralSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LiteralSupport.h; sourceTree = "<group>"; };
+		1A869AA70BA21ABA008DA07A /* LiteralSupport.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = LiteralSupport.cpp; sourceTree = "<group>"; };
+		1A97825A1108BA18002B98FC /* CGVTT.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CGVTT.cpp; path = lib/CodeGen/CGVTT.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		1A986AB610D0746D00A8EA9E /* CGDeclCXX.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CGDeclCXX.cpp; path = lib/CodeGen/CGDeclCXX.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		1AA963AB10D8576800786C86 /* FullExpr.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = FullExpr.h; path = clang/AST/FullExpr.h; sourceTree = "<group>"; tabWidth = 2; };
+		1AB290021045858B00FE33D8 /* PartialDiagnostic.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; path = PartialDiagnostic.h; sourceTree = "<group>"; tabWidth = 2; };
+		1ABC36930C7A4BDC006DB0AB /* CGBuiltin.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CGBuiltin.cpp; path = lib/CodeGen/CGBuiltin.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		1ABD23B11182449800A48E65 /* APValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = APValue.cpp; sourceTree = "<group>"; };
+		1ABD23B21182449800A48E65 /* ASTConsumer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ASTConsumer.cpp; sourceTree = "<group>"; };
+		1ABD23B31182449800A48E65 /* ASTContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ASTContext.cpp; sourceTree = "<group>"; };
+		1ABD23B41182449800A48E65 /* ASTDiagnostic.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ASTDiagnostic.cpp; sourceTree = "<group>"; };
+		1ABD23B51182449800A48E65 /* ASTImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ASTImporter.cpp; sourceTree = "<group>"; };
+		1ABD23B61182449800A48E65 /* AttrImpl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AttrImpl.cpp; sourceTree = "<group>"; };
+		1ABD23B71182449800A48E65 /* CXXInheritance.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CXXInheritance.cpp; sourceTree = "<group>"; };
+		1ABD23B81182449800A48E65 /* Decl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Decl.cpp; sourceTree = "<group>"; };
+		1ABD23B91182449800A48E65 /* DeclarationName.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DeclarationName.cpp; sourceTree = "<group>"; };
+		1ABD23BA1182449800A48E65 /* DeclBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DeclBase.cpp; sourceTree = "<group>"; };
+		1ABD23BB1182449800A48E65 /* DeclCXX.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DeclCXX.cpp; sourceTree = "<group>"; };
+		1ABD23BC1182449800A48E65 /* DeclFriend.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DeclFriend.cpp; sourceTree = "<group>"; };
+		1ABD23BD1182449800A48E65 /* DeclGroup.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DeclGroup.cpp; sourceTree = "<group>"; };
+		1ABD23BE1182449800A48E65 /* DeclObjC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DeclObjC.cpp; sourceTree = "<group>"; };
+		1ABD23BF1182449800A48E65 /* DeclPrinter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DeclPrinter.cpp; sourceTree = "<group>"; };
+		1ABD23C01182449800A48E65 /* DeclTemplate.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DeclTemplate.cpp; sourceTree = "<group>"; };
+		1ABD23C11182449800A48E65 /* Expr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Expr.cpp; sourceTree = "<group>"; };
+		1ABD23C21182449800A48E65 /* ExprConstant.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExprConstant.cpp; sourceTree = "<group>"; };
+		1ABD23C31182449800A48E65 /* ExprCXX.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExprCXX.cpp; sourceTree = "<group>"; };
+		1ABD23C41182449800A48E65 /* FullExpr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FullExpr.cpp; sourceTree = "<group>"; };
+		1ABD23C51182449800A48E65 /* InheritViz.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InheritViz.cpp; sourceTree = "<group>"; };
+		1ABD23C61182449800A48E65 /* NestedNameSpecifier.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NestedNameSpecifier.cpp; sourceTree = "<group>"; };
+		1ABD23C71182449800A48E65 /* ParentMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ParentMap.cpp; sourceTree = "<group>"; };
+		1ABD23C81182449800A48E65 /* RecordLayout.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RecordLayout.cpp; sourceTree = "<group>"; };
+		1ABD23C91182449800A48E65 /* RecordLayoutBuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RecordLayoutBuilder.cpp; sourceTree = "<group>"; };
+		1ABD23CA1182449800A48E65 /* RecordLayoutBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RecordLayoutBuilder.h; sourceTree = "<group>"; };
+		1ABD23CB1182449800A48E65 /* Stmt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Stmt.cpp; sourceTree = "<group>"; };
+		1ABD23CC1182449800A48E65 /* StmtDumper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StmtDumper.cpp; sourceTree = "<group>"; };
+		1ABD23CD1182449800A48E65 /* StmtIterator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StmtIterator.cpp; sourceTree = "<group>"; };
+		1ABD23CE1182449800A48E65 /* StmtPrinter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StmtPrinter.cpp; sourceTree = "<group>"; };
+		1ABD23CF1182449800A48E65 /* StmtProfile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StmtProfile.cpp; sourceTree = "<group>"; };
+		1ABD23D01182449800A48E65 /* StmtViz.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StmtViz.cpp; sourceTree = "<group>"; };
+		1ABD23D11182449800A48E65 /* TemplateBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TemplateBase.cpp; sourceTree = "<group>"; };
+		1ABD23D21182449800A48E65 /* TemplateName.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TemplateName.cpp; sourceTree = "<group>"; };
+		1ABD23D31182449800A48E65 /* Type.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Type.cpp; sourceTree = "<group>"; };
+		1ABD23D41182449800A48E65 /* TypeLoc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TypeLoc.cpp; sourceTree = "<group>"; };
+		1ABD23D51182449800A48E65 /* TypePrinter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TypePrinter.cpp; sourceTree = "<group>"; };
+		1ACB57DB1105820D0047B991 /* CompilerInstance.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CompilerInstance.cpp; path = lib/Frontend/CompilerInstance.cpp; sourceTree = "<group>"; };
+		1ACB57DC1105820D0047B991 /* CompilerInvocation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CompilerInvocation.cpp; path = lib/Frontend/CompilerInvocation.cpp; sourceTree = "<group>"; };
+		1ACB57DD1105820D0047B991 /* DeclXML.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DeclXML.cpp; path = lib/Frontend/DeclXML.cpp; sourceTree = "<group>"; };
+		1ACB57DE1105820D0047B991 /* FrontendAction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FrontendAction.cpp; path = lib/Frontend/FrontendAction.cpp; sourceTree = "<group>"; };
+		1ACB57DF1105820D0047B991 /* FrontendActions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FrontendActions.cpp; path = lib/Frontend/FrontendActions.cpp; sourceTree = "<group>"; };
+		1ACB57E01105820D0047B991 /* FrontendOptions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FrontendOptions.cpp; path = lib/Frontend/FrontendOptions.cpp; sourceTree = "<group>"; };
+		1ACB57E11105820D0047B991 /* LangStandards.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LangStandards.cpp; path = lib/Frontend/LangStandards.cpp; sourceTree = "<group>"; };
+		1ACB57E21105820D0047B991 /* TypeXML.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TypeXML.cpp; path = lib/Frontend/TypeXML.cpp; sourceTree = "<group>"; };
+		1ACB57E31105820D0047B991 /* VerifyDiagnosticsClient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = VerifyDiagnosticsClient.cpp; path = lib/Frontend/VerifyDiagnosticsClient.cpp; sourceTree = "<group>"; };
+		1ADF47AE0F782C3200E48A8A /* SemaTemplateInstantiateDecl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = SemaTemplateInstantiateDecl.cpp; path = lib/Sema/SemaTemplateInstantiateDecl.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		1AE4EE3B103B89CA00888A23 /* TreeTransform.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = TreeTransform.h; path = lib/Sema/TreeTransform.h; sourceTree = "<group>"; tabWidth = 2; };
+		1AF1B50E109A4FB800AFAFAC /* CGException.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CGException.cpp; path = lib/CodeGen/CGException.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		1AFDD8701161085D00AE030A /* ASTMerge.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ASTMerge.cpp; path = lib/Frontend/ASTMerge.cpp; sourceTree = "<group>"; };
+		1AFDD8711161085D00AE030A /* CodeGenAction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CodeGenAction.cpp; path = lib/Frontend/CodeGenAction.cpp; sourceTree = "<group>"; };
+		1AFF8AE11012BFC900D248DA /* CGRecordLayoutBuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CGRecordLayoutBuilder.cpp; path = lib/CodeGen/CGRecordLayoutBuilder.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		3507E4C10E27FE2D00FB7B57 /* CheckObjCInstMethSignature.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CheckObjCInstMethSignature.cpp; path = lib/Analysis/CheckObjCInstMethSignature.cpp; sourceTree = "<group>"; };
+		352246E10F5C6BE000D0D279 /* HTMLDiagnostics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = HTMLDiagnostics.cpp; path = lib/Frontend/HTMLDiagnostics.cpp; sourceTree = "<group>"; };
+		352246E20F5C6BE000D0D279 /* InitHeaderSearch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = InitHeaderSearch.cpp; path = lib/Frontend/InitHeaderSearch.cpp; sourceTree = "<group>"; };
+		352246E40F5C6BE000D0D279 /* PlistDiagnostics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PlistDiagnostics.cpp; path = lib/Frontend/PlistDiagnostics.cpp; sourceTree = "<group>"; };
+		352246E50F5C6BE000D0D279 /* TextDiagnosticBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TextDiagnosticBuffer.cpp; path = lib/Frontend/TextDiagnosticBuffer.cpp; sourceTree = "<group>"; };
+		352246E60F5C6BE000D0D279 /* TextDiagnosticPrinter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TextDiagnosticPrinter.cpp; path = lib/Frontend/TextDiagnosticPrinter.cpp; sourceTree = "<group>"; };
+		3527124F0DAFE54700C76352 /* IdentifierResolver.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = IdentifierResolver.h; path = lib/Sema/IdentifierResolver.h; sourceTree = "<group>"; tabWidth = 2; };
+		352712500DAFE54700C76352 /* IdentifierResolver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = IdentifierResolver.cpp; path = lib/Sema/IdentifierResolver.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		352C19DC0CA321C80045DB98 /* CFGRecStmtDeclVisitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CFGRecStmtDeclVisitor.h; path = clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h; sourceTree = "<group>"; };
+		352C19DD0CA321C80045DB98 /* CFGRecStmtVisitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CFGRecStmtVisitor.h; path = clang/Analysis/Visitors/CFGRecStmtVisitor.h; sourceTree = "<group>"; };
+		352C19DE0CA321C80045DB98 /* CFGStmtVisitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CFGStmtVisitor.h; path = clang/Analysis/Visitors/CFGStmtVisitor.h; sourceTree = "<group>"; };
+		352C19DF0CA321C80045DB98 /* CFGVarDeclVisitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CFGVarDeclVisitor.h; path = clang/Analysis/Visitors/CFGVarDeclVisitor.h; sourceTree = "<group>"; };
+		3534A01C0E129849002709B2 /* ParseCXXInlineMethods.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = ParseCXXInlineMethods.cpp; path = lib/Parse/ParseCXXInlineMethods.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		3536456A0E23EBF7009C6509 /* Environment.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Environment.cpp; path = lib/Analysis/Environment.cpp; sourceTree = "<group>"; };
+		3536457C0E2406B0009C6509 /* Environment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Environment.h; path = clang/Analysis/PathSensitive/Environment.h; sourceTree = "<group>"; };
+		3537AA0C0ECD088F008F7CDC /* BlkExprDeclBitVector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BlkExprDeclBitVector.h; path = clang/Analysis/Support/BlkExprDeclBitVector.h; sourceTree = "<group>"; };
+		3537AA0D0ECD08A4008F7CDC /* PreprocessorLexer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PreprocessorLexer.cpp; sourceTree = "<group>"; };
+		3538FDB60ED24A2C005EC283 /* DeclarationName.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = DeclarationName.h; path = clang/AST/DeclarationName.h; sourceTree = "<group>"; tabWidth = 2; };
+		353959D40EE5F88A00E82461 /* ParseTemplate.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = ParseTemplate.cpp; path = lib/Parse/ParseTemplate.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		3547129D0C88881300B3E1D5 /* PrettyPrinter.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = PrettyPrinter.h; path = clang/AST/PrettyPrinter.h; sourceTree = "<group>"; tabWidth = 2; };
+		35475B1F0E79973F0000BFE4 /* CGCall.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CGCall.cpp; path = lib/CodeGen/CGCall.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		35475B220E7997680000BFE4 /* CGCall.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = CGCall.h; path = lib/CodeGen/CGCall.h; sourceTree = "<group>"; tabWidth = 2; };
+		35475B230E7997680000BFE4 /* CGValue.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = CGValue.h; path = lib/CodeGen/CGValue.h; sourceTree = "<group>"; tabWidth = 2; };
+		355106850E9A8507006A4E44 /* MemRegion.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MemRegion.cpp; path = lib/Analysis/MemRegion.cpp; sourceTree = "<group>"; };
+		355106880E9A851B006A4E44 /* MemRegion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MemRegion.h; path = clang/Analysis/PathSensitive/MemRegion.h; sourceTree = "<group>"; };
+		3551068A0E9A8546006A4E44 /* ParsePragma.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = ParsePragma.cpp; path = lib/Parse/ParsePragma.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		3551068B0E9A8546006A4E44 /* ParseTentative.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = ParseTentative.cpp; path = lib/Parse/ParseTentative.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		3551068E0E9A855F006A4E44 /* AccessSpecifier.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = AccessSpecifier.h; path = clang/Parse/AccessSpecifier.h; sourceTree = "<group>"; tabWidth = 2; };
+		3551068F0E9A857C006A4E44 /* ParsePragma.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = ParsePragma.h; path = lib/Parse/ParsePragma.h; sourceTree = "<group>"; tabWidth = 2; };
+		3552E7540E520D80003A8CA5 /* PPCaching.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PPCaching.cpp; sourceTree = "<group>"; };
+		3552E7580E520DD7003A8CA5 /* CGObjCMac.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CGObjCMac.cpp; path = lib/CodeGen/CGObjCMac.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		3553EB9A0E5F7089007D7359 /* GRStateTrait.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GRStateTrait.h; path = clang/Analysis/PathSensitive/GRStateTrait.h; sourceTree = "<group>"; };
+		35544B850F5C7FD700D92AA9 /* RangeConstraintManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RangeConstraintManager.cpp; path = lib/Analysis/RangeConstraintManager.cpp; sourceTree = "<group>"; };
+		35544B860F5C7FD700D92AA9 /* SimpleConstraintManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SimpleConstraintManager.cpp; path = lib/Analysis/SimpleConstraintManager.cpp; sourceTree = "<group>"; };
+		35544B870F5C7FD700D92AA9 /* SimpleConstraintManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SimpleConstraintManager.h; path = lib/Analysis/SimpleConstraintManager.h; sourceTree = "<group>"; };
+		35544B8B0F5C803200D92AA9 /* SemaTemplateInstantiate.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = SemaTemplateInstantiate.cpp; path = lib/Sema/SemaTemplateInstantiate.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		35585DBD0EAFBC4500D0A97A /* CXXFieldCollector.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = CXXFieldCollector.h; path = lib/Sema/CXXFieldCollector.h; sourceTree = "<group>"; tabWidth = 2; };
+		35585DBE0EAFBC4500D0A97A /* SemaOverload.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = SemaOverload.cpp; path = lib/Sema/SemaOverload.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		35585DBF0EAFBC4500D0A97A /* SemaOverload.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = SemaOverload.h; path = lib/Sema/SemaOverload.h; sourceTree = "<group>"; tabWidth = 2; };
+		3558F76C0E267C8300A5B0DF /* BasicStore.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = BasicStore.cpp; path = lib/Analysis/BasicStore.cpp; sourceTree = "<group>"; };
+		3558F76F0E267C9A00A5B0DF /* Store.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Store.h; path = clang/Analysis/PathSensitive/Store.h; sourceTree = "<group>"; };
+		355CF6820C90A8B600A08AA3 /* LocalCheckers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LocalCheckers.h; path = clang/Analysis/LocalCheckers.h; sourceTree = "<group>"; };
+		356B89760D9BFDC100CBEBE9 /* BasicObjCFoundationChecks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BasicObjCFoundationChecks.h; path = lib/Analysis/BasicObjCFoundationChecks.h; sourceTree = "<group>"; };
+		356EF9B40C8F7DDF006650F5 /* LiveVariables.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LiveVariables.cpp; path = lib/Analysis/LiveVariables.cpp; sourceTree = "<group>"; };
+		35707EFD0CD0F5CC000B2204 /* SourceLocation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = SourceLocation.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		357EA27C0F2526F300439B60 /* SemaLookup.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = SemaLookup.cpp; path = lib/Sema/SemaLookup.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		35847BE30CC7DB9000C40FFF /* StmtIterator.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = StmtIterator.h; path = clang/AST/StmtIterator.h; sourceTree = "<group>"; tabWidth = 2; };
+		35862B0C0E3628CB0009F542 /* CheckDeadStores.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CheckDeadStores.cpp; path = lib/Analysis/CheckDeadStores.cpp; sourceTree = "<group>"; };
+		35862B110E3629850009F542 /* GRExprEngineInternalChecks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = GRExprEngineInternalChecks.cpp; path = lib/Analysis/GRExprEngineInternalChecks.cpp; sourceTree = "<group>"; };
+		358CFBB70E65AB04002A8E19 /* BasicConstraintManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = BasicConstraintManager.cpp; path = lib/Analysis/BasicConstraintManager.cpp; sourceTree = "<group>"; };
+		358D23090E8BEB850003DDCC /* DeclGroup.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = DeclGroup.h; path = clang/AST/DeclGroup.h; sourceTree = "<group>"; tabWidth = 2; };
+		358F514F0E529A87007F2102 /* GRState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GRState.h; path = clang/Analysis/PathSensitive/GRState.h; sourceTree = "<group>"; };
+		358F51510E529AA4007F2102 /* GRState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = GRState.cpp; path = lib/Analysis/GRState.cpp; sourceTree = "<group>"; };
+		3591853E0EFB1088000039AF /* SemaTemplate.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = SemaTemplate.cpp; path = lib/Sema/SemaTemplate.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		359378FF0DA486490043B19C /* BugReporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BugReporter.h; path = clang/Analysis/PathSensitive/BugReporter.h; sourceTree = "<group>"; };
+		359379090DA48ABA0043B19C /* BugReporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = BugReporter.cpp; path = lib/Analysis/BugReporter.cpp; sourceTree = "<group>"; };
+		3595AFB70E1C8D62004CDF09 /* CheckObjCDealloc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CheckObjCDealloc.cpp; path = lib/Analysis/CheckObjCDealloc.cpp; sourceTree = "<group>"; };
+		3598EBEB0EDE23EF0070CA16 /* PTHManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PTHManager.h; sourceTree = "<group>"; };
+		3599299A0DE2425300A8A33E /* SemaInit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = SemaInit.cpp; path = lib/Sema/SemaInit.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		35A057D20EAE2D2B0069249F /* SVals.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SVals.h; path = clang/Analysis/PathSensitive/SVals.h; sourceTree = "<group>"; };
+		35A057E00EAE2D950069249F /* RegionStore.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RegionStore.cpp; path = lib/Analysis/RegionStore.cpp; sourceTree = "<group>"; };
+		35A057E10EAE2D950069249F /* SVals.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SVals.cpp; path = lib/Analysis/SVals.cpp; sourceTree = "<group>"; };
+		35A3E7000DD3874400757F74 /* CGDebugInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CGDebugInfo.cpp; path = lib/CodeGen/CGDebugInfo.cpp; sourceTree = "<group>"; tabWidth = 2; wrapsLines = 1; };
+		35A3E7010DD3874400757F74 /* CGDebugInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = CGDebugInfo.h; path = lib/CodeGen/CGDebugInfo.h; sourceTree = "<group>"; tabWidth = 2; };
+		35A8FCF60D9B4ADD001C2F97 /* ProgramPoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProgramPoint.h; path = clang/Analysis/ProgramPoint.h; sourceTree = "<group>"; };
+		35A8FCF70D9B4ADD001C2F97 /* PathDiagnostic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PathDiagnostic.h; path = clang/Analysis/PathDiagnostic.h; sourceTree = "<group>"; };
+		35A8FCF80D9B4B29001C2F97 /* PathDiagnostic.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PathDiagnostic.cpp; path = lib/Analysis/PathDiagnostic.cpp; sourceTree = "<group>"; };
+		35B820740ECB811A0020BEC0 /* PreprocessorLexer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PreprocessorLexer.h; sourceTree = "<group>"; };
+		35BAC1E70E82C5B7003FB76F /* CheckNSError.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CheckNSError.cpp; path = lib/Analysis/CheckNSError.cpp; sourceTree = "<group>"; };
+		35BFBD2B0C9EDE1E006CB644 /* ASTConsumer.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = ASTConsumer.h; path = clang/AST/ASTConsumer.h; sourceTree = "<group>"; tabWidth = 2; };
+		35CEA05A0DF9E82700A41296 /* ExprObjC.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = ExprObjC.h; path = clang/AST/ExprObjC.h; sourceTree = "<group>"; tabWidth = 2; };
+		35CFFE010CA1CBDD00E6F2BE /* StmtGraphTraits.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = StmtGraphTraits.h; path = clang/AST/StmtGraphTraits.h; sourceTree = "<group>"; tabWidth = 2; };
+		35D1DDD10CA9C6D50096E967 /* DataflowSolver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DataflowSolver.h; path = clang/Analysis/FlowSensitive/DataflowSolver.h; sourceTree = "<group>"; };
+		35D1DDD20CA9C6D50096E967 /* DataflowValues.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DataflowValues.h; path = clang/Analysis/FlowSensitive/DataflowValues.h; sourceTree = "<group>"; };
+		35D55B240D81D8C60092E734 /* BasicValueFactory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = BasicValueFactory.cpp; path = lib/Analysis/BasicValueFactory.cpp; sourceTree = "<group>"; };
+		35D55B250D81D8C60092E734 /* CFRefCount.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CFRefCount.cpp; path = lib/Analysis/CFRefCount.cpp; sourceTree = "<group>"; };
+		35D55B290D81D8E50092E734 /* BasicValueFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BasicValueFactory.h; path = clang/Analysis/PathSensitive/BasicValueFactory.h; sourceTree = "<group>"; };
+		35E194670ECB82FB00F21733 /* SemaCXXScopeSpec.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = SemaCXXScopeSpec.cpp; path = lib/Sema/SemaCXXScopeSpec.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		35E194680ECB82FB00F21733 /* SemaCXXCast.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = SemaCXXCast.cpp; path = lib/Sema/SemaCXXCast.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		35E1946C0ECB83C100F21733 /* PTHLexer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PTHLexer.cpp; sourceTree = "<group>"; };
+		35EE48AD0E0C4CB200715C54 /* DeclCXX.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = DeclCXX.h; path = clang/AST/DeclCXX.h; sourceTree = "<group>"; tabWidth = 2; };
+		35EE48AE0E0C4CB200715C54 /* ParentMap.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = ParentMap.h; path = clang/AST/ParentMap.h; sourceTree = "<group>"; tabWidth = 2; };
+		35EF676F0DAD1D2C00B19414 /* SemaDeclCXX.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = SemaDeclCXX.cpp; path = lib/Sema/SemaDeclCXX.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		35EFEFB50DB67ED60020783D /* GRTransferFuncs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = GRTransferFuncs.cpp; path = lib/Analysis/GRTransferFuncs.cpp; sourceTree = "<group>"; };
+		35F1ACE60E66166C001F4532 /* ConstraintManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ConstraintManager.h; path = clang/Analysis/PathSensitive/ConstraintManager.h; sourceTree = "<group>"; };
+		35F2A01D0E36AFF100D17527 /* CheckObjCUnusedIVars.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CheckObjCUnusedIVars.cpp; path = lib/Analysis/CheckObjCUnusedIVars.cpp; sourceTree = "<group>"; };
+		35F2BE7B0DAC2963006E7668 /* HTMLRewrite.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HTMLRewrite.h; path = clang/Rewrite/HTMLRewrite.h; sourceTree = "<group>"; };
+		35F8D0CA0D9B7E8200D91C5E /* GRSimpleAPICheck.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GRSimpleAPICheck.h; path = clang/Analysis/PathSensitive/GRSimpleAPICheck.h; sourceTree = "<group>"; };
+		35F8D0CB0D9B7E8200D91C5E /* GRAuditor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GRAuditor.h; path = clang/Analysis/PathSensitive/GRAuditor.h; sourceTree = "<group>"; };
+		35F8D0D50D9B82CD00D91C5E /* BasicObjCFoundationChecks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = BasicObjCFoundationChecks.cpp; path = lib/Analysis/BasicObjCFoundationChecks.cpp; sourceTree = "<group>"; };
+		35F9B1550D1C6B2E00DDFDAE /* LiveVariables.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LiveVariables.h; path = clang/Analysis/Analyses/LiveVariables.h; sourceTree = "<group>"; };
+		35F9B1560D1C6B2E00DDFDAE /* UninitializedValues.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = UninitializedValues.h; path = clang/Analysis/Analyses/UninitializedValues.h; sourceTree = "<group>"; };
+		72D16C1E0D9975C400E6DA4A /* HTMLRewrite.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = HTMLRewrite.cpp; path = lib/Rewrite/HTMLRewrite.cpp; sourceTree = "<group>"; };
+		7F270AFE107A90010031B377 /* CodeCompleteConsumer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CodeCompleteConsumer.h; path = clang/Sema/CodeCompleteConsumer.h; sourceTree = "<group>"; };
+		84AF36A00CB17A3B00C820A5 /* DeclObjC.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = DeclObjC.h; path = clang/AST/DeclObjC.h; sourceTree = "<group>"; tabWidth = 2; };
+		84D9A8870C1A57E100AC7ABC /* AttributeList.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = AttributeList.cpp; path = lib/Parse/AttributeList.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		84D9A88B0C1A581300AC7ABC /* AttributeList.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = AttributeList.h; path = clang/Parse/AttributeList.h; sourceTree = "<group>"; tabWidth = 2; };
+		8DD76F6C0486A84900D96B5E /* clang */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = clang; sourceTree = BUILT_PRODUCTS_DIR; };
+		9012911510470FCE0083456D /* Index.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Index.h; path = "clang-c/Index.h"; sourceTree = "<group>"; };
+		9012911C1048068D0083456D /* ASTUnit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ASTUnit.cpp; path = lib/Frontend/ASTUnit.cpp; sourceTree = "<group>"; };
+		9012911F104812F90083456D /* CIndex.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CIndex.cpp; path = tools/CIndex/CIndex.cpp; sourceTree = "<group>"; };
+		904753791096376F00CBDDDD /* CXXInheritance.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = CXXInheritance.h; path = clang/AST/CXXInheritance.h; sourceTree = "<group>"; tabWidth = 2; };
+		9047537A1096376F00CBDDDD /* Redeclarable.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = Redeclarable.h; path = clang/AST/Redeclarable.h; sourceTree = "<group>"; tabWidth = 2; };
+		9047537B1096376F00CBDDDD /* TypeLoc.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = TypeLoc.h; path = clang/AST/TypeLoc.h; sourceTree = "<group>"; tabWidth = 2; };
+		9047537C1096376F00CBDDDD /* TypeLocBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = TypeLocBuilder.h; path = clang/AST/TypeLocBuilder.h; sourceTree = "<group>"; tabWidth = 2; };
+		9047537D1096376F00CBDDDD /* TypeLocNodes.def */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = text; name = TypeLocNodes.def; path = clang/AST/TypeLocNodes.def; sourceTree = "<group>"; tabWidth = 2; };
+		9047537E1096376F00CBDDDD /* TypeLocVisitor.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = TypeLocVisitor.h; path = clang/AST/TypeLocVisitor.h; sourceTree = "<group>"; tabWidth = 2; };
+		9047537F1096376F00CBDDDD /* TypeVisitor.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = TypeVisitor.h; path = clang/AST/TypeVisitor.h; sourceTree = "<group>"; tabWidth = 2; };
+		9063F2210F9E8BDF002F7251 /* ExternalSemaSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ExternalSemaSource.h; path = clang/Sema/ExternalSemaSource.h; sourceTree = "<group>"; };
+		9063F2220F9E8BDF002F7251 /* SemaConsumer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SemaConsumer.h; path = clang/Sema/SemaConsumer.h; sourceTree = "<group>"; };
+		9063F2280F9E911F002F7251 /* OnDiskHashTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OnDiskHashTable.h; sourceTree = "<group>"; };
+		9063F2290F9E911F002F7251 /* SourceManagerInternals.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SourceManagerInternals.h; sourceTree = "<group>"; };
+		9063F22A0F9E911F002F7251 /* TemplateKinds.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TemplateKinds.h; sourceTree = "<group>"; };
+		906BF4AE0F83BA16001071FA /* ConvertUTF.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConvertUTF.h; sourceTree = "<group>"; };
+		906BF4AF0F83BA2E001071FA /* ConvertUTF.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ConvertUTF.c; sourceTree = "<group>"; };
+		90F9EFA9104ABDED00D09A15 /* c-index-test.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "c-index-test.c"; path = "tools/c-index-test/c-index-test.c"; sourceTree = "<group>"; };
+		90FB99DE0F98FB1D008F9415 /* DeclContextInternals.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = DeclContextInternals.h; path = clang/AST/DeclContextInternals.h; sourceTree = "<group>"; tabWidth = 2; };
+		90FB99DF0F98FB1D008F9415 /* DeclVisitor.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = DeclVisitor.h; path = clang/AST/DeclVisitor.h; sourceTree = "<group>"; tabWidth = 2; };
+		90FB99E00F98FB1D008F9415 /* ExternalASTSource.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = ExternalASTSource.h; path = clang/AST/ExternalASTSource.h; sourceTree = "<group>"; tabWidth = 2; };
+		90FD6D5F103C3D21005F5B73 /* Analyzer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Analyzer.h; path = clang/Index/Analyzer.h; sourceTree = "<group>"; };
+		90FD6D60103C3D21005F5B73 /* ASTLocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASTLocation.h; path = clang/Index/ASTLocation.h; sourceTree = "<group>"; };
+		90FD6D61103C3D21005F5B73 /* DeclReferenceMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DeclReferenceMap.h; path = clang/Index/DeclReferenceMap.h; sourceTree = "<group>"; };
+		90FD6D62103C3D21005F5B73 /* Entity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Entity.h; path = clang/Index/Entity.h; sourceTree = "<group>"; };
+		90FD6D63103C3D21005F5B73 /* GlobalSelector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GlobalSelector.h; path = clang/Index/GlobalSelector.h; sourceTree = "<group>"; };
+		90FD6D64103C3D21005F5B73 /* Handlers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Handlers.h; path = clang/Index/Handlers.h; sourceTree = "<group>"; };
+		90FD6D65103C3D21005F5B73 /* Indexer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Indexer.h; path = clang/Index/Indexer.h; sourceTree = "<group>"; };
+		90FD6D66103C3D21005F5B73 /* IndexProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IndexProvider.h; path = clang/Index/IndexProvider.h; sourceTree = "<group>"; };
+		90FD6D67103C3D21005F5B73 /* Program.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Program.h; path = clang/Index/Program.h; sourceTree = "<group>"; };
+		90FD6D68103C3D21005F5B73 /* SelectorMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SelectorMap.h; path = clang/Index/SelectorMap.h; sourceTree = "<group>"; };
+		90FD6D69103C3D21005F5B73 /* STLExtras.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = STLExtras.h; path = clang/Index/STLExtras.h; sourceTree = "<group>"; };
+		90FD6D6A103C3D21005F5B73 /* TranslationUnit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TranslationUnit.h; path = clang/Index/TranslationUnit.h; sourceTree = "<group>"; };
+		90FD6D6B103C3D21005F5B73 /* Utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Utils.h; path = clang/Index/Utils.h; sourceTree = "<group>"; };
+		90FD6D6D103C3D49005F5B73 /* Analyzer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Analyzer.cpp; path = lib/Index/Analyzer.cpp; sourceTree = "<group>"; };
+		90FD6D6E103C3D49005F5B73 /* ASTLocation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ASTLocation.cpp; path = lib/Index/ASTLocation.cpp; sourceTree = "<group>"; };
+		90FD6D6F103C3D49005F5B73 /* ASTVisitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASTVisitor.h; path = lib/Index/ASTVisitor.h; sourceTree = "<group>"; };
+		90FD6D70103C3D49005F5B73 /* DeclReferenceMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DeclReferenceMap.cpp; path = lib/Index/DeclReferenceMap.cpp; sourceTree = "<group>"; };
+		90FD6D71103C3D49005F5B73 /* Entity.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Entity.cpp; path = lib/Index/Entity.cpp; sourceTree = "<group>"; };
+		90FD6D72103C3D49005F5B73 /* EntityImpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = EntityImpl.h; path = lib/Index/EntityImpl.h; sourceTree = "<group>"; };
+		90FD6D73103C3D49005F5B73 /* GlobalSelector.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = GlobalSelector.cpp; path = lib/Index/GlobalSelector.cpp; sourceTree = "<group>"; };
+		90FD6D74103C3D49005F5B73 /* Handlers.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Handlers.cpp; path = lib/Index/Handlers.cpp; sourceTree = "<group>"; };
+		90FD6D75103C3D49005F5B73 /* Indexer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Indexer.cpp; path = lib/Index/Indexer.cpp; sourceTree = "<group>"; };
+		90FD6D76103C3D49005F5B73 /* IndexProvider.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = IndexProvider.cpp; path = lib/Index/IndexProvider.cpp; sourceTree = "<group>"; };
+		90FD6D77103C3D49005F5B73 /* Program.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Program.cpp; path = lib/Index/Program.cpp; sourceTree = "<group>"; };
+		90FD6D78103C3D49005F5B73 /* ProgramImpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProgramImpl.h; path = lib/Index/ProgramImpl.h; sourceTree = "<group>"; };
+		90FD6D79103C3D49005F5B73 /* ResolveLocation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ResolveLocation.cpp; path = lib/Index/ResolveLocation.cpp; sourceTree = "<group>"; };
+		90FD6D7A103C3D49005F5B73 /* SelectorMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SelectorMap.cpp; path = lib/Index/SelectorMap.cpp; sourceTree = "<group>"; };
+		90FD6D86103C3D80005F5B73 /* Analyses.def */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = Analyses.def; path = clang/Frontend/Analyses.def; sourceTree = "<group>"; };
+		90FD6D87103C3D80005F5B73 /* AnalysisConsumer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AnalysisConsumer.h; path = clang/Frontend/AnalysisConsumer.h; sourceTree = "<group>"; };
+		90FD6D88103C3D80005F5B73 /* ASTConsumers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASTConsumers.h; path = clang/Frontend/ASTConsumers.h; sourceTree = "<group>"; };
+		90FD6D89103C3D80005F5B73 /* ASTUnit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASTUnit.h; path = clang/Frontend/ASTUnit.h; sourceTree = "<group>"; };
+		90FD6D8A103C3D80005F5B73 /* CommandLineSourceLoc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandLineSourceLoc.h; path = clang/Frontend/CommandLineSourceLoc.h; sourceTree = "<group>"; };
+		90FD6D8B103C3D80005F5B73 /* DeclContextXML.def */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = DeclContextXML.def; path = clang/Frontend/DeclContextXML.def; sourceTree = "<group>"; };
+		90FD6D8C103C3D80005F5B73 /* DeclXML.def */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = DeclXML.def; path = clang/Frontend/DeclXML.def; sourceTree = "<group>"; };
+		90FD6D8D103C3D80005F5B73 /* DocumentXML.def */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = DocumentXML.def; path = clang/Frontend/DocumentXML.def; sourceTree = "<group>"; };
+		90FD6D8E103C3D80005F5B73 /* DocumentXML.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DocumentXML.h; path = clang/Frontend/DocumentXML.h; sourceTree = "<group>"; };
+		90FD6D8F103C3D80005F5B73 /* StmtXML.def */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = StmtXML.def; path = clang/Frontend/StmtXML.def; sourceTree = "<group>"; };
+		90FD6D90103C3D80005F5B73 /* TypeXML.def */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = TypeXML.def; path = clang/Frontend/TypeXML.def; sourceTree = "<group>"; };
+		90FD6D91103C3D80005F5B73 /* Utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Utils.h; path = clang/Frontend/Utils.h; sourceTree = "<group>"; };
+		90FD6DB5103D977E005F5B73 /* index-test.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "index-test.cpp"; path = "tools/index-test/index-test.cpp"; sourceTree = "<group>"; };
+		BDF87CF60FD746F300BBF872 /* SemaTemplateDeduction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = SemaTemplateDeduction.cpp; path = lib/Sema/SemaTemplateDeduction.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		BF89C3E0115957FF001C2D68 /* AnalysisBasedWarnings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AnalysisBasedWarnings.h; path = lib/Sema/AnalysisBasedWarnings.h; sourceTree = "<group>"; };
+		BF89C3E111595818001C2D68 /* AnalysisBasedWarnings.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AnalysisBasedWarnings.cpp; path = lib/Sema/AnalysisBasedWarnings.cpp; sourceTree = "<group>"; };
+		BF89C3E311595835001C2D68 /* Lookup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Lookup.h; path = lib/Sema/Lookup.h; sourceTree = "<group>"; };
+		BF89C3E411595855001C2D68 /* SemaInit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SemaInit.h; path = lib/Sema/SemaInit.h; sourceTree = "<group>"; };
+		BF89C3E5115958A1001C2D68 /* TargetAttributesSema.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TargetAttributesSema.h; path = lib/Sema/TargetAttributesSema.h; sourceTree = "<group>"; };
+		BF89C3E81159594A001C2D68 /* SemaObjCProperty.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SemaObjCProperty.cpp; path = lib/Sema/SemaObjCProperty.cpp; sourceTree = "<group>"; };
+		BF89C3F811595A01001C2D68 /* SemaType.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SemaType.cpp; path = lib/Sema/SemaType.cpp; sourceTree = "<group>"; };
+		BF89C3FA11595A37001C2D68 /* SemaCodeComplete.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SemaCodeComplete.cpp; path = lib/Sema/SemaCodeComplete.cpp; sourceTree = "<group>"; };
+		BF89C3FC11595A5D001C2D68 /* SemaExceptionSpec.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SemaExceptionSpec.cpp; path = lib/Sema/SemaExceptionSpec.cpp; sourceTree = "<group>"; };
+		DE01DA480B12ADA300AC22CE /* PPCallbacks.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PPCallbacks.h; sourceTree = "<group>"; };
+		DE06756B0C051CFE00EBBFD8 /* ParseExprCXX.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = ParseExprCXX.cpp; path = lib/Parse/ParseExprCXX.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		DE06B73D0A8307640050E87E /* LangOptions.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.c.h; path = LangOptions.h; sourceTree = "<group>"; tabWidth = 2; };
+		DE06BECA0A854E4B0050E87E /* Scope.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = Scope.h; path = clang/Parse/Scope.h; sourceTree = "<group>"; tabWidth = 2; };
+		DE06D42F0A8BB52D0050E87E /* Parser.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = Parser.cpp; path = lib/Parse/Parser.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		DE06E8130A8FF9330050E87E /* Action.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = Action.h; path = clang/Parse/Action.h; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
+		DE0FCA620A95859D00248FD5 /* Expr.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = Expr.h; path = clang/AST/Expr.h; sourceTree = "<group>"; tabWidth = 2; };
+		DE1263C20EF2341900F56D2B /* Ownership.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = Ownership.h; path = clang/Parse/Ownership.h; sourceTree = "<group>"; tabWidth = 2; };
+		DE17336D0B068DC20080B521 /* DeclSpec.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = DeclSpec.cpp; path = lib/Parse/DeclSpec.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		DE17336F0B068DC60080B521 /* DeclSpec.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = DeclSpec.h; path = clang/Parse/DeclSpec.h; sourceTree = "<group>"; tabWidth = 2; };
+		DE1F22020A7D852A00FBF588 /* Parser.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = Parser.h; path = clang/Parse/Parser.h; sourceTree = "<group>"; tabWidth = 2; };
+		DE224FF70C7AA98800D370A5 /* CGExprComplex.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CGExprComplex.cpp; path = lib/CodeGen/CGExprComplex.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		DE22526F0C7E82D000D370A5 /* CGExprScalar.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CGExprScalar.cpp; path = lib/CodeGen/CGExprScalar.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		DE2255FB0C8004E600D370A5 /* ParseDeclCXX.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = ParseDeclCXX.cpp; path = lib/Parse/ParseDeclCXX.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		DE22BCF10E14197E0094DC60 /* SemaDeclAttr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = SemaDeclAttr.cpp; path = lib/Sema/SemaDeclAttr.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		DE344AB70AE5DF6D00DBC861 /* HeaderSearch.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = HeaderSearch.h; sourceTree = "<group>"; };
+		DE344B530AE5E46C00DBC861 /* HeaderSearch.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = HeaderSearch.cpp; sourceTree = "<group>"; };
+		DE3450D60AEB543100DBC861 /* DirectoryLookup.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DirectoryLookup.h; sourceTree = "<group>"; };
+		DE3452800AEF1B1800DBC861 /* Stmt.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = Stmt.h; path = clang/AST/Stmt.h; sourceTree = "<group>"; tabWidth = 2; };
+		DE345C190AFC658B00DBC861 /* StmtVisitor.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = StmtVisitor.h; path = clang/AST/StmtVisitor.h; sourceTree = "<group>"; tabWidth = 2; };
+		DE345F210AFD347900DBC861 /* StmtNodes.def */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = text; name = StmtNodes.def; path = clang/AST/StmtNodes.def; sourceTree = "<group>"; tabWidth = 2; };
+		DE345FFF0AFDCC1900DBC861 /* ParseObjc.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = ParseObjc.cpp; path = lib/Parse/ParseObjc.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		DE3460040AFDCC6500DBC861 /* ParseInit.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = ParseInit.cpp; path = lib/Parse/ParseInit.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		DE34600A0AFDCCBF00DBC861 /* ParseStmt.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = ParseStmt.cpp; path = lib/Parse/ParseStmt.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		DE34600E0AFDCCCE00DBC861 /* ParseDecl.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = ParseDecl.cpp; path = lib/Parse/ParseDecl.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		DE3460120AFDCCDA00DBC861 /* ParseExpr.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = ParseExpr.cpp; path = lib/Parse/ParseExpr.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		DE3461260AFE68BE00DBC861 /* MinimalAction.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = MinimalAction.cpp; path = lib/Parse/MinimalAction.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		DE3464210B03040900DBC861 /* Type.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = Type.h; path = clang/AST/Type.h; sourceTree = "<group>"; tabWidth = 2; };
+		DE37251C0FE4818000CF2CC2 /* Builtins.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Builtins.h; sourceTree = "<group>"; };
+		DE37252A0FE4818F00CF2CC2 /* Builtins.def */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Builtins.def; sourceTree = "<group>"; };
+		DE37252D0FE481AD00CF2CC2 /* Builtins.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Builtins.cpp; sourceTree = "<group>"; };
+		DE3725310FE4822800CF2CC2 /* TargetBuiltins.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TargetBuiltins.h; sourceTree = "<group>"; };
+		DE3725320FE4826C00CF2CC2 /* BuiltinsX86.def */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = BuiltinsX86.def; sourceTree = "<group>"; };
+		DE3725330FE4827200CF2CC2 /* BuiltinsPPC.def */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = BuiltinsPPC.def; sourceTree = "<group>"; };
+		DE38CD4E0D794CF900A273B6 /* CGObjCRuntime.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = CGObjCRuntime.h; path = lib/CodeGen/CGObjCRuntime.h; sourceTree = "<group>"; tabWidth = 2; };
+		DE38CD4F0D794D0100A273B6 /* CGObjCGNU.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CGObjCGNU.cpp; path = lib/CodeGen/CGObjCGNU.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		DE3986EF0CB8D4B300223765 /* IdentifierTable.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.c.h; path = IdentifierTable.h; sourceTree = "<group>"; tabWidth = 2; };
+		DE3986F30CB8D50C00223765 /* IdentifierTable.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = IdentifierTable.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		DE3B90DE0EAC5EF200D01046 /* ExtensionRAIIObject.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = ExtensionRAIIObject.h; path = lib/Parse/ExtensionRAIIObject.h; sourceTree = "<group>"; tabWidth = 2; };
+		DE3B92230EB5152000D01046 /* Designator.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = Designator.h; path = clang/Parse/Designator.h; sourceTree = "<group>"; tabWidth = 2; };
+		DE41211D0D7F1BBE0080F80A /* GRWorkList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GRWorkList.h; path = clang/Analysis/PathSensitive/GRWorkList.h; sourceTree = "<group>"; };
+		DE41211E0D7F1BBE0080F80A /* SymbolManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SymbolManager.h; path = clang/Analysis/PathSensitive/SymbolManager.h; sourceTree = "<group>"; };
+		DE41211F0D7F1BBE0080F80A /* GRBlockCounter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GRBlockCounter.h; path = clang/Analysis/PathSensitive/GRBlockCounter.h; sourceTree = "<group>"; };
+		DE4121200D7F1BBE0080F80A /* ExplodedGraph.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ExplodedGraph.h; path = clang/Analysis/PathSensitive/ExplodedGraph.h; sourceTree = "<group>"; };
+		DE4121210D7F1BBE0080F80A /* GRExprEngine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GRExprEngine.h; path = clang/Analysis/PathSensitive/GRExprEngine.h; sourceTree = "<group>"; };
+		DE4121220D7F1BBE0080F80A /* GRTransferFuncs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GRTransferFuncs.h; path = clang/Analysis/PathSensitive/GRTransferFuncs.h; sourceTree = "<group>"; };
+		DE4121230D7F1BBE0080F80A /* GRCoreEngine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GRCoreEngine.h; path = clang/Analysis/PathSensitive/GRCoreEngine.h; sourceTree = "<group>"; };
+		DE4121270D7F1C1C0080F80A /* SymbolManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SymbolManager.cpp; path = lib/Analysis/SymbolManager.cpp; sourceTree = "<group>"; };
+		DE4121280D7F1C1C0080F80A /* ExplodedGraph.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ExplodedGraph.cpp; path = lib/Analysis/ExplodedGraph.cpp; sourceTree = "<group>"; };
+		DE4121290D7F1C1C0080F80A /* UninitializedValues.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = UninitializedValues.cpp; path = lib/Analysis/UninitializedValues.cpp; sourceTree = "<group>"; };
+		DE41212A0D7F1C1C0080F80A /* GRCoreEngine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = GRCoreEngine.cpp; path = lib/Analysis/GRCoreEngine.cpp; sourceTree = "<group>"; };
+		DE41212C0D7F1C1C0080F80A /* GRSimpleVals.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GRSimpleVals.h; path = lib/Analysis/GRSimpleVals.h; sourceTree = "<group>"; };
+		DE41212F0D7F1C1C0080F80A /* GRSimpleVals.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = GRSimpleVals.cpp; path = lib/Analysis/GRSimpleVals.cpp; sourceTree = "<group>"; };
+		DE4121300D7F1C1C0080F80A /* GRBlockCounter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = GRBlockCounter.cpp; path = lib/Analysis/GRBlockCounter.cpp; sourceTree = "<group>"; };
+		DE4121310D7F1C1C0080F80A /* GRExprEngine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = GRExprEngine.cpp; path = lib/Analysis/GRExprEngine.cpp; sourceTree = "<group>"; };
+		DE4264FB0C113592005A861D /* CGDecl.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CGDecl.cpp; path = lib/CodeGen/CGDecl.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		DE46BF270AE0A82D00CC047C /* TargetInfo.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.c.h; path = TargetInfo.h; sourceTree = "<group>"; tabWidth = 2; };
+		DE4772F90C10EAE5002239E8 /* CGStmt.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CGStmt.cpp; path = lib/CodeGen/CGStmt.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		DE4772FB0C10EAEC002239E8 /* CGExpr.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CGExpr.cpp; path = lib/CodeGen/CGExpr.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		DE47999B0D2EBE1A00706D2D /* SemaExprObjC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = SemaExprObjC.cpp; path = lib/Sema/SemaExprObjC.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		DE4DC7980EA1BE4400069E5A /* TokenRewriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TokenRewriter.h; path = clang/Rewrite/TokenRewriter.h; sourceTree = "<group>"; };
+		DE4DC7A20EA1C33E00069E5A /* TokenRewriter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TokenRewriter.cpp; path = lib/Rewrite/TokenRewriter.cpp; sourceTree = "<group>"; };
+		DE53370B0CE2D96F00D9A028 /* RewriteRope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RewriteRope.h; path = clang/Rewrite/RewriteRope.h; sourceTree = "<group>"; };
+		DE613EF30E0E148D00B05B79 /* APValue.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = APValue.h; path = clang/AST/APValue.h; sourceTree = "<group>"; tabWidth = 2; };
+		DE67E70A0C020EC500F66BC5 /* SemaType.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = SemaType.cpp; path = lib/Sema/SemaType.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		DE67E70C0C020ECA00F66BC5 /* SemaStmt.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = SemaStmt.cpp; path = lib/Sema/SemaStmt.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		DE67E70E0C020ECF00F66BC5 /* SemaExprCXX.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = SemaExprCXX.cpp; path = lib/Sema/SemaExprCXX.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		DE67E7100C020ED400F66BC5 /* SemaExpr.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = SemaExpr.cpp; path = lib/Sema/SemaExpr.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		DE67E7120C020ED900F66BC5 /* SemaDecl.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = SemaDecl.cpp; path = lib/Sema/SemaDecl.cpp; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
+		DE67E7140C020EDF00F66BC5 /* Sema.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = Sema.h; path = lib/Sema/Sema.h; sourceTree = "<group>"; tabWidth = 2; };
+		DE67E7160C020EE400F66BC5 /* Sema.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = Sema.cpp; path = lib/Sema/Sema.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		DE67E7190C020F4F00F66BC5 /* ParseAST.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = ParseAST.cpp; path = lib/Sema/ParseAST.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		DE67E7270C02109800F66BC5 /* ParseAST.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ParseAST.h; path = clang/Sema/ParseAST.h; sourceTree = "<group>"; };
+		DE6951C60C4D1F5D00A5826B /* RecordLayout.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = RecordLayout.h; path = clang/AST/RecordLayout.h; sourceTree = "<group>"; tabWidth = 2; };
+		DE6954630C5121BD00A5826B /* Token.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Token.h; sourceTree = "<group>"; };
+		DE704B250D0FBEBE009C7762 /* SemaDeclObjC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = SemaDeclObjC.cpp; path = lib/Sema/SemaDeclObjC.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		DE704BD10D1647E7009C7762 /* HeaderMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HeaderMap.h; sourceTree = "<group>"; };
+		DE704DD10D1668A4009C7762 /* HeaderMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HeaderMap.cpp; sourceTree = "<group>"; };
+		DE75ED280B044DC90020CF81 /* ASTContext.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = ASTContext.h; path = clang/AST/ASTContext.h; sourceTree = "<group>"; tabWidth = 2; };
+		DE85CD800D8380B10070E26E /* TokenLexer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TokenLexer.cpp; sourceTree = "<group>"; };
+		DE85CD840D8380F20070E26E /* TokenLexer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TokenLexer.h; sourceTree = "<group>"; };
+		DE85CD9E0D8382DD0070E26E /* MacroArgs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MacroArgs.h; sourceTree = "<group>"; };
+		DE85CDA20D8383B20070E26E /* MacroArgs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MacroArgs.cpp; sourceTree = "<group>"; };
+		DE85CDAB0D838C120070E26E /* PPMacroExpansion.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PPMacroExpansion.cpp; sourceTree = "<group>"; };
+		DE85CDAF0D838C390070E26E /* PPDirectives.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PPDirectives.cpp; sourceTree = "<group>"; };
+		DE85CDB50D839BAE0070E26E /* PPLexerChange.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PPLexerChange.cpp; sourceTree = "<group>"; };
+		DE8822350EC80C0A00CBC30A /* CGBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = CGBuilder.h; path = lib/CodeGen/CGBuilder.h; sourceTree = "<group>"; tabWidth = 2; };
+		DE8823DE0ED0B78600CBC30A /* PTHLexer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PTHLexer.h; sourceTree = "<group>"; };
+		DE8824530ED1243E00CBC30A /* OperatorKinds.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OperatorKinds.h; sourceTree = "<group>"; };
+		DE8824560ED1244600CBC30A /* OperatorKinds.def */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = OperatorKinds.def; sourceTree = "<group>"; };
+		DE928B120C05659200231DA4 /* ModuleBuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = ModuleBuilder.cpp; path = lib/CodeGen/ModuleBuilder.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		DE928B1F0C0565B000231DA4 /* ModuleBuilder.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ModuleBuilder.h; path = clang/CodeGen/ModuleBuilder.h; sourceTree = "<group>"; };
+		DE928B7C0C0A615100231DA4 /* CodeGenModule.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = CodeGenModule.h; path = lib/CodeGen/CodeGenModule.h; sourceTree = "<group>"; tabWidth = 2; };
+		DE928B7E0C0A615600231DA4 /* CodeGenModule.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CodeGenModule.cpp; path = lib/CodeGen/CodeGenModule.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		DE928B800C0A615B00231DA4 /* CodeGenFunction.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = CodeGenFunction.h; path = lib/CodeGen/CodeGenFunction.h; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
+		DE928B820C0A616000231DA4 /* CodeGenFunction.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CodeGenFunction.cpp; path = lib/CodeGen/CodeGenFunction.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		DEA09A6E0F31756F000C2258 /* ASTDiagnostic.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = ASTDiagnostic.h; path = clang/AST/ASTDiagnostic.h; sourceTree = "<group>"; tabWidth = 2; };
+		DEA09A830F3175BF000C2258 /* LexDiagnostic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LexDiagnostic.h; sourceTree = "<group>"; };
+		DEA09A860F3175CA000C2258 /* ParseDiagnostic.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = ParseDiagnostic.h; path = clang/Parse/ParseDiagnostic.h; sourceTree = "<group>"; tabWidth = 2; };
+		DEA09A890F3175D9000C2258 /* SemaDiagnostic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SemaDiagnostic.h; path = clang/Sema/SemaDiagnostic.h; sourceTree = "<group>"; };
+		DEAABDF70F5F477C0098928A /* PrettyStackTrace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PrettyStackTrace.h; sourceTree = "<group>"; };
+		DEAEE98A0A5A2B970045101B /* MultipleIncludeOpt.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MultipleIncludeOpt.h; sourceTree = "<group>"; };
+		DEAEED4A0A5AF89A0045101B /* NOTES.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = NOTES.txt; sourceTree = "<group>"; };
+		DEB076C90F3A221200F5A2BE /* DeclTemplate.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = DeclTemplate.h; path = clang/AST/DeclTemplate.h; sourceTree = "<group>"; tabWidth = 2; };
+		DEB077930F44F96000F5A2BE /* TokenConcatenation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TokenConcatenation.h; sourceTree = "<group>"; };
+		DEB077980F44F97800F5A2BE /* TokenConcatenation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TokenConcatenation.cpp; sourceTree = "<group>"; };
+		DEB07AC70F4A427E00F5A2BE /* SemaAttr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = SemaAttr.cpp; path = lib/Sema/SemaAttr.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		DEB089EE0F12F1D900522C07 /* TypeTraits.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TypeTraits.h; sourceTree = "<group>"; };
+		DEC8D9900A9433CD00353FCA /* Decl.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = Decl.h; path = clang/AST/Decl.h; sourceTree = "<group>"; tabWidth = 2; };
+		DEC8D9A30A94346E00353FCA /* AST.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = AST.h; path = clang/AST/AST.h; sourceTree = "<group>"; tabWidth = 2; };
+		DECAB0CF0DB3C84200E13CCB /* RewriteRope.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RewriteRope.cpp; path = lib/Rewrite/RewriteRope.cpp; sourceTree = "<group>"; };
+		DECB6D640F9AE26600F5FBC7 /* JumpDiagnostics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = JumpDiagnostics.cpp; path = lib/Sema/JumpDiagnostics.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		DECB6F030F9D939A00F5FBC7 /* InitPreprocessor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = InitPreprocessor.h; path = clang/Frontend/InitPreprocessor.h; sourceTree = "<group>"; };
+		DECB6F060F9D93A800F5FBC7 /* InitPreprocessor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = InitPreprocessor.cpp; path = lib/Frontend/InitPreprocessor.cpp; sourceTree = "<group>"; };
+		DECB734E0FA3ED8400F5FBC7 /* StmtObjC.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = StmtObjC.h; path = clang/AST/StmtObjC.h; sourceTree = "<group>"; tabWidth = 2; };
+		DECB73550FA3EE5A00F5FBC7 /* StmtCXX.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = StmtCXX.h; path = clang/AST/StmtCXX.h; sourceTree = "<group>"; tabWidth = 2; };
+		DECB77120FA5752300F5FBC7 /* PCHReaderStmt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = PCHReaderStmt.cpp; path = lib/Frontend/PCHReaderStmt.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		DECB77780FA579B000F5FBC7 /* PCHReaderDecl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PCHReaderDecl.cpp; path = lib/Frontend/PCHReaderDecl.cpp; sourceTree = "<group>"; };
+		DECB77F60FA5850200F5FBC7 /* PCHWriterDecl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PCHWriterDecl.cpp; path = lib/Frontend/PCHWriterDecl.cpp; sourceTree = "<group>"; };
+		DECB78160FA5882F00F5FBC7 /* PCHWriterStmt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PCHWriterStmt.cpp; path = lib/Frontend/PCHWriterStmt.cpp; sourceTree = "<group>"; };
+		DED626C80AE0C065001E80A4 /* TargetInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = TargetInfo.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		DED7D7310A524295003AD0FB /* Diagnostic.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.c.h; path = Diagnostic.h; sourceTree = "<group>"; tabWidth = 2; };
+		DED7D7330A524295003AD0FB /* FileManager.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.c.h; path = FileManager.h; sourceTree = "<group>"; tabWidth = 2; };
+		DED7D7350A524295003AD0FB /* SourceLocation.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.c.h; path = SourceLocation.h; sourceTree = "<group>"; tabWidth = 2; };
+		DED7D7360A524295003AD0FB /* SourceManager.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.c.h; path = SourceManager.h; sourceTree = "<group>"; tabWidth = 2; };
+		DED7D7370A524295003AD0FB /* TokenKinds.def */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = text; path = TokenKinds.def; sourceTree = "<group>"; tabWidth = 2; };
+		DED7D7380A524295003AD0FB /* TokenKinds.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.c.h; path = TokenKinds.h; sourceTree = "<group>"; tabWidth = 2; };
+		DED7D73B0A524295003AD0FB /* Lexer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Lexer.h; sourceTree = "<group>"; };
+		DED7D73E0A524295003AD0FB /* MacroInfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MacroInfo.h; sourceTree = "<group>"; };
+		DED7D73F0A524295003AD0FB /* Pragma.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Pragma.h; sourceTree = "<group>"; };
+		DED7D7400A524295003AD0FB /* Preprocessor.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Preprocessor.h; sourceTree = "<group>"; };
+		DED7D75D0A5242C7003AD0FB /* Diagnostic.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = Diagnostic.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		DED7D75E0A5242C7003AD0FB /* FileManager.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = FileManager.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		DED7D76D0A5242C7003AD0FB /* SourceManager.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = SourceManager.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		DED7D76E0A5242C7003AD0FB /* TokenKinds.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = TokenKinds.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		DED7D79E0A5242E6003AD0FB /* Lexer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Lexer.cpp; sourceTree = "<group>"; };
+		DED7D7A00A5242E6003AD0FB /* MacroInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = MacroInfo.cpp; sourceTree = "<group>"; };
+		DED7D7A20A5242E6003AD0FB /* PPExpressions.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = PPExpressions.cpp; sourceTree = "<group>"; };
+		DED7D7A30A5242E6003AD0FB /* Pragma.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Pragma.cpp; sourceTree = "<group>"; };
+		DED7D7A40A5242E6003AD0FB /* Preprocessor.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Preprocessor.cpp; sourceTree = "<group>"; };
+		DED7D7D70A524302003AD0FB /* README.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = README.txt; sourceTree = "<group>"; };
+		DED7D9170A52518C003AD0FB /* ScratchBuffer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ScratchBuffer.h; sourceTree = "<group>"; };
+		DED7D9E40A5257F6003AD0FB /* ScratchBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ScratchBuffer.cpp; sourceTree = "<group>"; };
+		DEDFE5270F63A9230035BD10 /* DeclNodes.def */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = text; name = DeclNodes.def; path = clang/AST/DeclNodes.def; sourceTree = "<group>"; tabWidth = 2; };
+		DEDFE5CB0F7206CC0035BD10 /* NestedNameSpecifier.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = NestedNameSpecifier.h; path = clang/AST/NestedNameSpecifier.h; sourceTree = "<group>"; tabWidth = 2; };
+		DEDFE6450F7B3B4E0035BD10 /* driver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = driver.cpp; path = tools/driver/driver.cpp; sourceTree = "<group>"; };
+		DEDFE6480F7B3B830035BD10 /* Types.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Types.cpp; path = lib/Driver/Types.cpp; sourceTree = "<group>"; };
+		DEDFE6490F7B3B830035BD10 /* Tools.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Tools.h; path = lib/Driver/Tools.h; sourceTree = "<group>"; };
+		DEDFE64A0F7B3B830035BD10 /* Tools.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Tools.cpp; path = lib/Driver/Tools.cpp; sourceTree = "<group>"; };
+		DEDFE64B0F7B3B830035BD10 /* ToolChains.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ToolChains.h; path = lib/Driver/ToolChains.h; sourceTree = "<group>"; };
+		DEDFE64C0F7B3B830035BD10 /* Compilation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Compilation.cpp; path = lib/Driver/Compilation.cpp; sourceTree = "<group>"; };
+		DEDFE64D0F7B3B830035BD10 /* ArgList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ArgList.cpp; path = lib/Driver/ArgList.cpp; sourceTree = "<group>"; };
+		DEDFE64E0F7B3B830035BD10 /* Arg.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Arg.cpp; path = lib/Driver/Arg.cpp; sourceTree = "<group>"; };
+		DEDFE64F0F7B3B830035BD10 /* Action.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Action.cpp; path = lib/Driver/Action.cpp; sourceTree = "<group>"; };
+		DEDFE6500F7B3B830035BD10 /* Phases.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Phases.cpp; path = lib/Driver/Phases.cpp; sourceTree = "<group>"; };
+		DEDFE6510F7B3B830035BD10 /* OptTable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OptTable.cpp; path = lib/Driver/OptTable.cpp; sourceTree = "<group>"; };
+		DEDFE6520F7B3B830035BD10 /* Option.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Option.cpp; path = lib/Driver/Option.cpp; sourceTree = "<group>"; };
+		DEDFE6530F7B3B830035BD10 /* Job.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Job.cpp; path = lib/Driver/Job.cpp; sourceTree = "<group>"; };
+		DEDFE6540F7B3B830035BD10 /* InputInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = InputInfo.h; path = lib/Driver/InputInfo.h; sourceTree = "<group>"; };
+		DEDFE6550F7B3B830035BD10 /* ToolChains.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ToolChains.cpp; path = lib/Driver/ToolChains.cpp; sourceTree = "<group>"; };
+		DEDFE6560F7B3B830035BD10 /* ToolChain.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ToolChain.cpp; path = lib/Driver/ToolChain.cpp; sourceTree = "<group>"; };
+		DEDFE6570F7B3B830035BD10 /* Tool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Tool.cpp; path = lib/Driver/Tool.cpp; sourceTree = "<group>"; };
+		DEDFE6580F7B3B830035BD10 /* HostInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = HostInfo.cpp; path = lib/Driver/HostInfo.cpp; sourceTree = "<group>"; };
+		DEDFE6590F7B3B830035BD10 /* Driver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Driver.cpp; path = lib/Driver/Driver.cpp; sourceTree = "<group>"; };
+		DEDFF87F0F848CE30035BD10 /* TemplateName.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = TemplateName.h; path = clang/AST/TemplateName.h; sourceTree = "<group>"; tabWidth = 2; };
+		DEDFFF070F959EE60035BD10 /* Diagnostic.td */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Diagnostic.td; sourceTree = "<group>"; };
+		DEDFFF530F9704580035BD10 /* DiagnosticGroups.td */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = DiagnosticGroups.td; sourceTree = "<group>"; };
+		DEEBBD430C19C5D200A9FE82 /* TODO.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = TODO.txt; sourceTree = "<group>"; };
+		DEEBC3B90C2363B800A9FE82 /* CodeGenTypes.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = CodeGenTypes.h; path = lib/CodeGen/CodeGenTypes.h; sourceTree = "<group>"; tabWidth = 2; };
+		DEEBC3BB0C2363BC00A9FE82 /* CodeGenTypes.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CodeGenTypes.cpp; path = lib/CodeGen/CodeGenTypes.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		DEF1615E0F65C81C0098507F /* InitHeaderSearch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = InitHeaderSearch.h; path = clang/Frontend/InitHeaderSearch.h; sourceTree = "<group>"; };
+		DEF1615F0F65C81C0098507F /* ManagerRegistry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ManagerRegistry.h; path = clang/Frontend/ManagerRegistry.h; sourceTree = "<group>"; };
+		DEF161600F65C81C0098507F /* TextDiagnosticBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TextDiagnosticBuffer.h; path = clang/Frontend/TextDiagnosticBuffer.h; sourceTree = "<group>"; };
+		DEF161610F65C81C0098507F /* PathDiagnosticClients.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PathDiagnosticClients.h; path = clang/Frontend/PathDiagnosticClients.h; sourceTree = "<group>"; };
+		DEF161620F65C81C0098507F /* CompileOptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CompileOptions.h; path = clang/Frontend/CompileOptions.h; sourceTree = "<group>"; };
+		DEF161630F65C81C0098507F /* TextDiagnosticPrinter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TextDiagnosticPrinter.h; path = clang/Frontend/TextDiagnosticPrinter.h; sourceTree = "<group>"; };
+		DEF165140F8D46980098507F /* Tool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Tool.h; path = clang/Driver/Tool.h; sourceTree = "<group>"; };
+		DEF165150F8D46980098507F /* Types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Types.h; path = clang/Driver/Types.h; sourceTree = "<group>"; };
+		DEF165160F8D46980098507F /* Action.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Action.h; path = clang/Driver/Action.h; sourceTree = "<group>"; };
+		DEF165170F8D46980098507F /* Compilation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Compilation.h; path = clang/Driver/Compilation.h; sourceTree = "<group>"; };
+		DEF165180F8D46980098507F /* Options.def */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = Options.def; path = clang/Driver/Options.def; sourceTree = "<group>"; };
+		DEF165190F8D46980098507F /* Option.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Option.h; path = clang/Driver/Option.h; sourceTree = "<group>"; };
+		DEF1651A0F8D46980098507F /* Types.def */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = Types.def; path = clang/Driver/Types.def; sourceTree = "<group>"; };
+		DEF1651B0F8D46980098507F /* ToolChain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ToolChain.h; path = clang/Driver/ToolChain.h; sourceTree = "<group>"; };
+		DEF1651C0F8D46980098507F /* Options.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Options.h; path = clang/Driver/Options.h; sourceTree = "<group>"; };
+		DEF1651D0F8D46980098507F /* ArgList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ArgList.h; path = clang/Driver/ArgList.h; sourceTree = "<group>"; };
+		DEF1651E0F8D46980098507F /* Arg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Arg.h; path = clang/Driver/Arg.h; sourceTree = "<group>"; };
+		DEF1651F0F8D46980098507F /* HostInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HostInfo.h; path = clang/Driver/HostInfo.h; sourceTree = "<group>"; };
+		DEF165200F8D46980098507F /* Driver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Driver.h; path = clang/Driver/Driver.h; sourceTree = "<group>"; };
+		DEF165210F8D46980098507F /* Job.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Job.h; path = clang/Driver/Job.h; sourceTree = "<group>"; };
+		DEF165220F8D46980098507F /* Util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Util.h; path = clang/Driver/Util.h; sourceTree = "<group>"; };
+		DEF165230F8D46980098507F /* Phases.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Phases.h; path = clang/Driver/Phases.h; sourceTree = "<group>"; };
+		DEF165240F8D46980098507F /* DriverDiagnostic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DriverDiagnostic.h; path = clang/Driver/DriverDiagnostic.h; sourceTree = "<group>"; };
+		DEF165700F8FB34D0098507F /* PCHWriter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = PCHWriter.cpp; path = lib/Frontend/PCHWriter.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		DEF165740F8FB3510098507F /* PCHReader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = PCHReader.cpp; path = lib/Frontend/PCHReader.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		DEF165780F8FB3690098507F /* PCHWriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PCHWriter.h; path = clang/Frontend/PCHWriter.h; sourceTree = "<group>"; };
+		DEF1657B0F8FB36E0098507F /* PCHReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PCHReader.h; path = clang/Frontend/PCHReader.h; sourceTree = "<group>"; };
+		DEF1657E0F8FB3730098507F /* PCHBitCodes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PCHBitCodes.h; path = clang/Frontend/PCHBitCodes.h; sourceTree = "<group>"; };
+		DEF1683F0F9548DC0098507F /* FixItRewriter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FixItRewriter.cpp; path = lib/Frontend/FixItRewriter.cpp; sourceTree = "<group>"; };
+		DEF168620F9549250098507F /* FixItRewriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FixItRewriter.h; path = clang/Frontend/FixItRewriter.h; sourceTree = "<group>"; };
+		DEF169220F9645960098507F /* FrontendDiagnostic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FrontendDiagnostic.h; path = clang/Frontend/FrontendDiagnostic.h; sourceTree = "<group>"; };
+		DEF1692C0F9645BF0098507F /* AnalysisDiagnostic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AnalysisDiagnostic.h; path = clang/Analysis/AnalysisDiagnostic.h; sourceTree = "<group>"; };
+		DEF16BE40FA13A5B0098507F /* TypeNodes.def */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = text; name = TypeNodes.def; path = clang/AST/TypeNodes.def; sourceTree = "<group>"; tabWidth = 2; };
+		DEF16BE50FA13A650098507F /* TypeOrdering.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = TypeOrdering.h; path = clang/AST/TypeOrdering.h; sourceTree = "<group>"; tabWidth = 2; };
+		DEF2E95E0C5FBD74000C4259 /* InternalsManual.html */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.html; name = InternalsManual.html; path = docs/InternalsManual.html; sourceTree = "<group>"; };
+		DEF2EFF20C6CDD74000C4259 /* CGExprAgg.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CGExprAgg.cpp; path = lib/CodeGen/CGExprAgg.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		DEF2F00F0C6CFED5000C4259 /* SemaChecking.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = SemaChecking.cpp; path = lib/Sema/SemaChecking.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		DEF7D9F60C9C8B1A0001F598 /* Rewriter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Rewriter.h; path = clang/Rewrite/Rewriter.h; sourceTree = "<group>"; };
+		DEF7D9F80C9C8B1D0001F598 /* Rewriter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Rewriter.cpp; path = lib/Rewrite/Rewriter.cpp; sourceTree = "<group>"; };
+		DEFFECA30DB093D100B4E7C3 /* DeltaTree.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DeltaTree.h; path = clang/Rewrite/DeltaTree.h; sourceTree = "<group>"; };
+		DEFFECA60DB1546600B4E7C3 /* DeltaTree.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DeltaTree.cpp; path = lib/Rewrite/DeltaTree.cpp; sourceTree = "<group>"; };
+		E16B523410D30B2400430AC9 /* cc1_main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = cc1_main.cpp; path = tools/driver/cc1_main.cpp; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+		8DD76F660486A84900D96B5E /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+		08FB7794FE84155DC02AAC07 /* clang */ = {
+			isa = PBXGroup;
+			children = (
+				DED7D72E0A524295003AD0FB /* include */,
+				08FB7795FE84155DC02AAC07 /* Libraries */,
+				DEDFE61F0F7B3AE10035BD10 /* Tools */,
+				C6859E8C029090F304C91782 /* Documentation */,
+				1AB674ADFE9D54B511CA2CBB /* Products */,
+			);
+			name = clang;
+			sourceTree = "<group>";
+		};
+		08FB7795FE84155DC02AAC07 /* Libraries */ = {
+			isa = PBXGroup;
+			children = (
+				90FD6D6C103C3D2D005F5B73 /* Index */,
+				DED7D7500A5242C7003AD0FB /* Basic */,
+				DED7D78C0A5242E6003AD0FB /* Lex */,
+				DE1F22600A7D8C9B00FBF588 /* Parse */,
+				DEC8D9920A9433F400353FCA /* AST */,
+				DE67E7070C020EAB00F66BC5 /* Sema */,
+				DE927FCC0C0557CD00231DA4 /* CodeGen */,
+				356EF9B30C8F7DCA006650F5 /* Analysis */,
+				DEF7D9F50C9C8B0C0001F598 /* Rewrite */,
+				352246E00F5C6BC000D0D279 /* Frontend */,
+				DEDFE6470F7B3B560035BD10 /* Driver */,
+			);
+			name = Libraries;
+			sourceTree = "<group>";
+		};
+		1AB674ADFE9D54B511CA2CBB /* Products */ = {
+			isa = PBXGroup;
+			children = (
+				8DD76F6C0486A84900D96B5E /* clang */,
+			);
+			name = Products;
+			sourceTree = "<group>";
+		};
+		3507E4C30E27FE3800FB7B57 /* Checks */ = {
+			isa = PBXGroup;
+			children = (
+				35BAC1E70E82C5B7003FB76F /* CheckNSError.cpp */,
+				356B89760D9BFDC100CBEBE9 /* BasicObjCFoundationChecks.h */,
+				35F8D0D50D9B82CD00D91C5E /* BasicObjCFoundationChecks.cpp */,
+				35862B0C0E3628CB0009F542 /* CheckDeadStores.cpp */,
+				3595AFB70E1C8D62004CDF09 /* CheckObjCDealloc.cpp */,
+				3507E4C10E27FE2D00FB7B57 /* CheckObjCInstMethSignature.cpp */,
+				35F2A01D0E36AFF100D17527 /* CheckObjCUnusedIVars.cpp */,
+				DE4121290D7F1C1C0080F80A /* UninitializedValues.cpp */,
+			);
+			name = Checks;
+			sourceTree = "<group>";
+		};
+		3507E4C60E27FE5500FB7B57 /* Core */ = {
+			isa = PBXGroup;
+			children = (
+				35A057E10EAE2D950069249F /* SVals.cpp */,
+				355106850E9A8507006A4E44 /* MemRegion.cpp */,
+				35D55B240D81D8C60092E734 /* BasicValueFactory.cpp */,
+				3536456A0E23EBF7009C6509 /* Environment.cpp */,
+				DE4121280D7F1C1C0080F80A /* ExplodedGraph.cpp */,
+				DE4121300D7F1C1C0080F80A /* GRBlockCounter.cpp */,
+				DE41212A0D7F1C1C0080F80A /* GRCoreEngine.cpp */,
+				DE4121310D7F1C1C0080F80A /* GRExprEngine.cpp */,
+				35862B110E3629850009F542 /* GRExprEngineInternalChecks.cpp */,
+				358F51510E529AA4007F2102 /* GRState.cpp */,
+				35EFEFB50DB67ED60020783D /* GRTransferFuncs.cpp */,
+				DE4121270D7F1C1C0080F80A /* SymbolManager.cpp */,
+			);
+			name = Core;
+			sourceTree = "<group>";
+		};
+		3507E4C90E27FE9000FB7B57 /* Bug Reporting */ = {
+			isa = PBXGroup;
+			children = (
+				35A8FCF80D9B4B29001C2F97 /* PathDiagnostic.cpp */,
+				359379090DA48ABA0043B19C /* BugReporter.cpp */,
+			);
+			name = "Bug Reporting";
+			sourceTree = "<group>";
+		};
+		3507E4CC0E27FEB900FB7B57 /* Flow-Sensitive Analyses */ = {
+			isa = PBXGroup;
+			children = (
+				356EF9B40C8F7DDF006650F5 /* LiveVariables.cpp */,
+			);
+			name = "Flow-Sensitive Analyses";
+			sourceTree = "<group>";
+		};
+		352246E00F5C6BC000D0D279 /* Frontend */ = {
+			isa = PBXGroup;
+			children = (
+				1AFDD8701161085D00AE030A /* ASTMerge.cpp */,
+				9012911C1048068D0083456D /* ASTUnit.cpp */,
+				1A2A54A40FD1DD1C00F4CE45 /* AnalysisConsumer.cpp */,
+				1A2A54A50FD1DD1C00F4CE45 /* ASTConsumers.cpp */,
+				1AFDD8711161085D00AE030A /* CodeGenAction.cpp */,
+				1A2A54A70FD1DD1C00F4CE45 /* CacheTokens.cpp */,
+				1ACB57DB1105820D0047B991 /* CompilerInstance.cpp */,
+				1ACB57DC1105820D0047B991 /* CompilerInvocation.cpp */,
+				1ACB57DD1105820D0047B991 /* DeclXML.cpp */,
+				1A2A54A80FD1DD1C00F4CE45 /* DependencyFile.cpp */,
+				1A2A54A90FD1DD1C00F4CE45 /* DiagChecker.cpp */,
+				1A2A54AA0FD1DD1C00F4CE45 /* DocumentXML.cpp */,
+				DEF1683F0F9548DC0098507F /* FixItRewriter.cpp */,
+				1ACB57DE1105820D0047B991 /* FrontendAction.cpp */,
+				1ACB57DF1105820D0047B991 /* FrontendActions.cpp */,
+				1ACB57E01105820D0047B991 /* FrontendOptions.cpp */,
+				1A2A54AB0FD1DD1C00F4CE45 /* GeneratePCH.cpp */,
+				352246E10F5C6BE000D0D279 /* HTMLDiagnostics.cpp */,
+				1A2A54AC0FD1DD1C00F4CE45 /* HTMLPrint.cpp */,
+				352246E20F5C6BE000D0D279 /* InitHeaderSearch.cpp */,
+				DECB6F060F9D93A800F5FBC7 /* InitPreprocessor.cpp */,
+				1ACB57E11105820D0047B991 /* LangStandards.cpp */,
+				DEF165740F8FB3510098507F /* PCHReader.cpp */,
+				DECB77780FA579B000F5FBC7 /* PCHReaderDecl.cpp */,
+				DECB77120FA5752300F5FBC7 /* PCHReaderStmt.cpp */,
+				DEF165700F8FB34D0098507F /* PCHWriter.cpp */,
+				DECB77F60FA5850200F5FBC7 /* PCHWriterDecl.cpp */,
+				DECB78160FA5882F00F5FBC7 /* PCHWriterStmt.cpp */,
+				352246E40F5C6BE000D0D279 /* PlistDiagnostics.cpp */,
+				1A2A54AD0FD1DD1C00F4CE45 /* PrintParserCallbacks.cpp */,
+				1A2A54AE0FD1DD1C00F4CE45 /* PrintPreprocessedOutput.cpp */,
+				352246E50F5C6BE000D0D279 /* TextDiagnosticBuffer.cpp */,
+				352246E60F5C6BE000D0D279 /* TextDiagnosticPrinter.cpp */,
+				1ACB57E21105820D0047B991 /* TypeXML.cpp */,
+				1A2A54B00FD1DD1C00F4CE45 /* RewriteMacros.cpp */,
+				1A2A54B10FD1DD1C00F4CE45 /* RewriteObjC.cpp */,
+				1A2A54B20FD1DD1C00F4CE45 /* RewriteTest.cpp */,
+				1A2A54B30FD1DD1C00F4CE45 /* StmtXML.cpp */,
+				1ACB57E31105820D0047B991 /* VerifyDiagnosticsClient.cpp */,
+				1A2A54B40FD1DD1C00F4CE45 /* Warnings.cpp */,
+			);
+			name = Frontend;
+			sourceTree = "<group>";
+		};
+		352C19DB0CA321AC0045DB98 /* Visitors */ = {
+			isa = PBXGroup;
+			children = (
+				352C19DC0CA321C80045DB98 /* CFGRecStmtDeclVisitor.h */,
+				352C19DD0CA321C80045DB98 /* CFGRecStmtVisitor.h */,
+				352C19DE0CA321C80045DB98 /* CFGStmtVisitor.h */,
+				352C19DF0CA321C80045DB98 /* CFGVarDeclVisitor.h */,
+			);
+			name = Visitors;
+			sourceTree = "<group>";
+		};
+		35544B820F5C7F6600D92AA9 /* StoreManagers */ = {
+			isa = PBXGroup;
+			children = (
+				35A057E00EAE2D950069249F /* RegionStore.cpp */,
+				3558F76C0E267C8300A5B0DF /* BasicStore.cpp */,
+			);
+			name = StoreManagers;
+			sourceTree = "<group>";
+		};
+		35544B830F5C7F8900D92AA9 /* ConstraintManagers */ = {
+			isa = PBXGroup;
+			children = (
+				35544B870F5C7FD700D92AA9 /* SimpleConstraintManager.h */,
+				35544B860F5C7FD700D92AA9 /* SimpleConstraintManager.cpp */,
+				358CFBB70E65AB04002A8E19 /* BasicConstraintManager.cpp */,
+				35544B850F5C7FD700D92AA9 /* RangeConstraintManager.cpp */,
+			);
+			name = ConstraintManagers;
+			sourceTree = "<group>";
+		};
+		35544B840F5C7F9D00D92AA9 /* Path-Sensitive */ = {
+			isa = PBXGroup;
+			children = (
+				3507E4C60E27FE5500FB7B57 /* Core */,
+				35544B820F5C7F6600D92AA9 /* StoreManagers */,
+				35862B130E3629BC0009F542 /* Transfer Function Analyses */,
+				35544B830F5C7F8900D92AA9 /* ConstraintManagers */,
+			);
+			name = "Path-Sensitive";
+			sourceTree = "<group>";
+		};
+		356EF9AF0C8F7DA4006650F5 /* Analysis */ = {
+			isa = PBXGroup;
+			children = (
+				DEF1692C0F9645BF0098507F /* AnalysisDiagnostic.h */,
+				35A8FCF60D9B4ADD001C2F97 /* ProgramPoint.h */,
+				35A8FCF70D9B4ADD001C2F97 /* PathDiagnostic.h */,
+				355CF6820C90A8B600A08AA3 /* LocalCheckers.h */,
+				35F9B1540D1C6AFC00DDFDAE /* Analyses */,
+				35D1DDCF0CA9C6BE0096E967 /* FlowSensitive */,
+				DE4121130D7F1B980080F80A /* PathSensitive */,
+				35F9B1520D1C6ACB00DDFDAE /* Support */,
+				352C19DB0CA321AC0045DB98 /* Visitors */,
+			);
+			name = Analysis;
+			sourceTree = "<group>";
+		};
+		356EF9B30C8F7DCA006650F5 /* Analysis */ = {
+			isa = PBXGroup;
+			children = (
+				DE67E70A0C020EC500F66BC5 /* SemaType.cpp */,
+				35544B840F5C7F9D00D92AA9 /* Path-Sensitive */,
+				3507E4CC0E27FEB900FB7B57 /* Flow-Sensitive Analyses */,
+				3507E4C30E27FE3800FB7B57 /* Checks */,
+				3507E4C90E27FE9000FB7B57 /* Bug Reporting */,
+			);
+			name = Analysis;
+			sourceTree = "<group>";
+		};
+		35862B130E3629BC0009F542 /* Transfer Function Analyses */ = {
+			isa = PBXGroup;
+			children = (
+				35D55B250D81D8C60092E734 /* CFRefCount.cpp */,
+				DE41212F0D7F1C1C0080F80A /* GRSimpleVals.cpp */,
+				DE41212C0D7F1C1C0080F80A /* GRSimpleVals.h */,
+			);
+			name = "Transfer Function Analyses";
+			sourceTree = "<group>";
+		};
+		35D1DDCF0CA9C6BE0096E967 /* FlowSensitive */ = {
+			isa = PBXGroup;
+			children = (
+				35D1DDD10CA9C6D50096E967 /* DataflowSolver.h */,
+				35D1DDD20CA9C6D50096E967 /* DataflowValues.h */,
+			);
+			name = FlowSensitive;
+			sourceTree = "<group>";
+		};
+		35F9B1520D1C6ACB00DDFDAE /* Support */ = {
+			isa = PBXGroup;
+			children = (
+				3537AA0C0ECD088F008F7CDC /* BlkExprDeclBitVector.h */,
+			);
+			name = Support;
+			sourceTree = "<group>";
+		};
+		35F9B1540D1C6AFC00DDFDAE /* Analyses */ = {
+			isa = PBXGroup;
+			children = (
+				35F9B1550D1C6B2E00DDFDAE /* LiveVariables.h */,
+				35F9B1560D1C6B2E00DDFDAE /* UninitializedValues.h */,
+			);
+			name = Analyses;
+			sourceTree = "<group>";
+		};
+		9012911210470FAF0083456D /* clang-c */ = {
+			isa = PBXGroup;
+			children = (
+				9012911510470FCE0083456D /* Index.h */,
+			);
+			name = "clang-c";
+			sourceTree = "<group>";
+		};
+		9012911E104812DA0083456D /* CIndex */ = {
+			isa = PBXGroup;
+			children = (
+				9012911F104812F90083456D /* CIndex.cpp */,
+				1A621C3B11111D61009E6834 /* CIndexer.cpp */,
+				1A621C3A11111D61009E6834 /* CIndexCodeCompletion.cpp */,
+				1A621C3C11111D61009E6834 /* CIndexer.h */,
+				1A621C3D11111D61009E6834 /* CIndexInclusionStack.cpp */,
+				1A621C3E11111D61009E6834 /* CIndexUSRs.cpp */,
+				1A621C3F11111D61009E6834 /* CXCursor.cpp */,
+				1A621C4011111D61009E6834 /* CXCursor.h */,
+				1A621C4111111D61009E6834 /* CXSourceLocation.h */,
+			);
+			name = CIndex;
+			sourceTree = "<group>";
+		};
+		90F9EFA8104ABDC400D09A15 /* c-index-test */ = {
+			isa = PBXGroup;
+			children = (
+				90F9EFA9104ABDED00D09A15 /* c-index-test.c */,
+			);
+			name = "c-index-test";
+			sourceTree = "<group>";
+		};
+		90FD6D5E103C3D03005F5B73 /* Index */ = {
+			isa = PBXGroup;
+			children = (
+				90FD6D5F103C3D21005F5B73 /* Analyzer.h */,
+				90FD6D60103C3D21005F5B73 /* ASTLocation.h */,
+				90FD6D61103C3D21005F5B73 /* DeclReferenceMap.h */,
+				90FD6D62103C3D21005F5B73 /* Entity.h */,
+				90FD6D63103C3D21005F5B73 /* GlobalSelector.h */,
+				90FD6D64103C3D21005F5B73 /* Handlers.h */,
+				90FD6D65103C3D21005F5B73 /* Indexer.h */,
+				90FD6D66103C3D21005F5B73 /* IndexProvider.h */,
+				90FD6D67103C3D21005F5B73 /* Program.h */,
+				90FD6D68103C3D21005F5B73 /* SelectorMap.h */,
+				90FD6D69103C3D21005F5B73 /* STLExtras.h */,
+				90FD6D6A103C3D21005F5B73 /* TranslationUnit.h */,
+				90FD6D6B103C3D21005F5B73 /* Utils.h */,
+			);
+			name = Index;
+			sourceTree = "<group>";
+		};
+		90FD6D6C103C3D2D005F5B73 /* Index */ = {
+			isa = PBXGroup;
+			children = (
+				90FD6D6D103C3D49005F5B73 /* Analyzer.cpp */,
+				90FD6D6E103C3D49005F5B73 /* ASTLocation.cpp */,
+				90FD6D6F103C3D49005F5B73 /* ASTVisitor.h */,
+				90FD6D70103C3D49005F5B73 /* DeclReferenceMap.cpp */,
+				90FD6D71103C3D49005F5B73 /* Entity.cpp */,
+				90FD6D72103C3D49005F5B73 /* EntityImpl.h */,
+				90FD6D73103C3D49005F5B73 /* GlobalSelector.cpp */,
+				90FD6D74103C3D49005F5B73 /* Handlers.cpp */,
+				90FD6D75103C3D49005F5B73 /* Indexer.cpp */,
+				90FD6D76103C3D49005F5B73 /* IndexProvider.cpp */,
+				90FD6D77103C3D49005F5B73 /* Program.cpp */,
+				90FD6D78103C3D49005F5B73 /* ProgramImpl.h */,
+				90FD6D79103C3D49005F5B73 /* ResolveLocation.cpp */,
+				90FD6D7A103C3D49005F5B73 /* SelectorMap.cpp */,
+			);
+			name = Index;
+			sourceTree = "<group>";
+		};
+		90FD6DB4103D9763005F5B73 /* index-test */ = {
+			isa = PBXGroup;
+			children = (
+				90FD6DB5103D977E005F5B73 /* index-test.cpp */,
+			);
+			name = "index-test";
+			sourceTree = "<group>";
+		};
+		C6859E8C029090F304C91782 /* Documentation */ = {
+			isa = PBXGroup;
+			children = (
+				DEAEED4A0A5AF89A0045101B /* NOTES.txt */,
+				DED7D7D70A524302003AD0FB /* README.txt */,
+				DEEBBD430C19C5D200A9FE82 /* TODO.txt */,
+				DEF2E95E0C5FBD74000C4259 /* InternalsManual.html */,
+			);
+			name = Documentation;
+			sourceTree = "<group>";
+		};
+		DE1F21F20A7D84E800FBF588 /* Parse */ = {
+			isa = PBXGroup;
+			children = (
+				3551068E0E9A855F006A4E44 /* AccessSpecifier.h */,
+				84D9A88B0C1A581300AC7ABC /* AttributeList.h */,
+				DE06E8130A8FF9330050E87E /* Action.h */,
+				DE17336F0B068DC60080B521 /* DeclSpec.h */,
+				DE3B92230EB5152000D01046 /* Designator.h */,
+				DE1263C20EF2341900F56D2B /* Ownership.h */,
+				DEA09A860F3175CA000C2258 /* ParseDiagnostic.h */,
+				DE1F22020A7D852A00FBF588 /* Parser.h */,
+				DE06BECA0A854E4B0050E87E /* Scope.h */,
+			);
+			name = Parse;
+			sourceTree = "<group>";
+		};
+		DE1F22600A7D8C9B00FBF588 /* Parse */ = {
+			isa = PBXGroup;
+			children = (
+				84D9A8870C1A57E100AC7ABC /* AttributeList.cpp */,
+				DE17336D0B068DC20080B521 /* DeclSpec.cpp */,
+				DE3B90DE0EAC5EF200D01046 /* ExtensionRAIIObject.h */,
+				DE3461260AFE68BE00DBC861 /* MinimalAction.cpp */,
+				DE34600E0AFDCCCE00DBC861 /* ParseDecl.cpp */,
+				DE2255FB0C8004E600D370A5 /* ParseDeclCXX.cpp */,
+				DE3460120AFDCCDA00DBC861 /* ParseExpr.cpp */,
+				DE06756B0C051CFE00EBBFD8 /* ParseExprCXX.cpp */,
+				3534A01C0E129849002709B2 /* ParseCXXInlineMethods.cpp */,
+				DE3460040AFDCC6500DBC861 /* ParseInit.cpp */,
+				DE345FFF0AFDCC1900DBC861 /* ParseObjc.cpp */,
+				3551068F0E9A857C006A4E44 /* ParsePragma.h */,
+				3551068A0E9A8546006A4E44 /* ParsePragma.cpp */,
+				DE34600A0AFDCCBF00DBC861 /* ParseStmt.cpp */,
+				353959D40EE5F88A00E82461 /* ParseTemplate.cpp */,
+				3551068B0E9A8546006A4E44 /* ParseTentative.cpp */,
+				DE06D42F0A8BB52D0050E87E /* Parser.cpp */,
+			);
+			name = Parse;
+			sourceTree = "<group>";
+		};
+		DE4121130D7F1B980080F80A /* PathSensitive */ = {
+			isa = PBXGroup;
+			children = (
+				35D55B290D81D8E50092E734 /* BasicValueFactory.h */,
+				359378FF0DA486490043B19C /* BugReporter.h */,
+				3536457C0E2406B0009C6509 /* Environment.h */,
+				DE4121200D7F1BBE0080F80A /* ExplodedGraph.h */,
+				35F1ACE60E66166C001F4532 /* ConstraintManager.h */,
+				35F8D0CB0D9B7E8200D91C5E /* GRAuditor.h */,
+				DE41211F0D7F1BBE0080F80A /* GRBlockCounter.h */,
+				DE4121230D7F1BBE0080F80A /* GRCoreEngine.h */,
+				DE4121210D7F1BBE0080F80A /* GRExprEngine.h */,
+				358F514F0E529A87007F2102 /* GRState.h */,
+				3553EB9A0E5F7089007D7359 /* GRStateTrait.h */,
+				35F8D0CA0D9B7E8200D91C5E /* GRSimpleAPICheck.h */,
+				DE4121220D7F1BBE0080F80A /* GRTransferFuncs.h */,
+				DE41211D0D7F1BBE0080F80A /* GRWorkList.h */,
+				355106880E9A851B006A4E44 /* MemRegion.h */,
+				3558F76F0E267C9A00A5B0DF /* Store.h */,
+				35A057D20EAE2D2B0069249F /* SVals.h */,
+				DE41211E0D7F1BBE0080F80A /* SymbolManager.h */,
+			);
+			name = PathSensitive;
+			sourceTree = "<group>";
+		};
+		DE67E7070C020EAB00F66BC5 /* Sema */ = {
+			isa = PBXGroup;
+			children = (
+				BF89C3E111595818001C2D68 /* AnalysisBasedWarnings.cpp */,
+				BF89C3E0115957FF001C2D68 /* AnalysisBasedWarnings.h */,
+				35585DBD0EAFBC4500D0A97A /* CXXFieldCollector.h */,
+				1A6B6CD110693FC900BB4A8F /* CodeCompleteConsumer.cpp */,
+				3527124F0DAFE54700C76352 /* IdentifierResolver.h */,
+				352712500DAFE54700C76352 /* IdentifierResolver.cpp */,
+				DECB6D640F9AE26600F5FBC7 /* JumpDiagnostics.cpp */,
+				BF89C3E311595835001C2D68 /* Lookup.h */,
+				DE67E7190C020F4F00F66BC5 /* ParseAST.cpp */,
+				DE67E7140C020EDF00F66BC5 /* Sema.h */,
+				DE67E7160C020EE400F66BC5 /* Sema.cpp */,
+				1A701B630F7C8FE400FEC4D1 /* SemaAccess.cpp */,
+				DEB07AC70F4A427E00F5A2BE /* SemaAttr.cpp */,
+				DEF2F00F0C6CFED5000C4259 /* SemaChecking.cpp */,
+				BF89C3FA11595A37001C2D68 /* SemaCodeComplete.cpp */,
+				35E194670ECB82FB00F21733 /* SemaCXXScopeSpec.cpp */,
+				DE67E7120C020ED900F66BC5 /* SemaDecl.cpp */,
+				DE22BCF10E14197E0094DC60 /* SemaDeclAttr.cpp */,
+				35EF676F0DAD1D2C00B19414 /* SemaDeclCXX.cpp */,
+				DE704B250D0FBEBE009C7762 /* SemaDeclObjC.cpp */,
+				BF89C3FC11595A5D001C2D68 /* SemaExceptionSpec.cpp */,
+				DE67E7100C020ED400F66BC5 /* SemaExpr.cpp */,
+				DE47999B0D2EBE1A00706D2D /* SemaExprObjC.cpp */,
+				DE67E70E0C020ECF00F66BC5 /* SemaExprCXX.cpp */,
+				BF89C3E411595855001C2D68 /* SemaInit.h */,
+				3599299A0DE2425300A8A33E /* SemaInit.cpp */,
+				357EA27C0F2526F300439B60 /* SemaLookup.cpp */,
+				1A6B6CD210693FC900BB4A8F /* SemaCodeComplete.cpp */,
+				35E194680ECB82FB00F21733 /* SemaCXXCast.cpp */,
+				BF89C3E81159594A001C2D68 /* SemaObjCProperty.cpp */,
+				35585DBE0EAFBC4500D0A97A /* SemaOverload.cpp */,
+				35585DBF0EAFBC4500D0A97A /* SemaOverload.h */,
+				DE67E70C0C020ECA00F66BC5 /* SemaStmt.cpp */,
+				3591853E0EFB1088000039AF /* SemaTemplate.cpp */,
+				1A6B6CD310693FC900BB4A8F /* SemaTemplate.h */,
+				BDF87CF60FD746F300BBF872 /* SemaTemplateDeduction.cpp */,
+				35544B8B0F5C803200D92AA9 /* SemaTemplateInstantiate.cpp */,
+				1ADF47AE0F782C3200E48A8A /* SemaTemplateInstantiateDecl.cpp */,
+				BF89C3F811595A01001C2D68 /* SemaType.cpp */,
+				1AE4EE3B103B89CA00888A23 /* TreeTransform.h */,
+				BF89C3E5115958A1001C2D68 /* TargetAttributesSema.h */,
+			);
+			name = Sema;
+			sourceTree = "<group>";
+		};
+		DE67E7260C02108300F66BC5 /* Sema */ = {
+			isa = PBXGroup;
+			children = (
+				7F270AFE107A90010031B377 /* CodeCompleteConsumer.h */,
+				9063F2210F9E8BDF002F7251 /* ExternalSemaSource.h */,
+				9063F2220F9E8BDF002F7251 /* SemaConsumer.h */,
+				DE67E7270C02109800F66BC5 /* ParseAST.h */,
+				DEA09A890F3175D9000C2258 /* SemaDiagnostic.h */,
+			);
+			name = Sema;
+			sourceTree = "<group>";
+		};
+		DE927FCC0C0557CD00231DA4 /* CodeGen */ = {
+			isa = PBXGroup;
+			children = (
+				1A2193CB0F45EEB700C0713D /* ABIInfo.h */,
+				1A471AB40F437BC500753CE8 /* CGBlocks.cpp */,
+				1A649E1D0F9599D9005B965E /* CGBlocks.h */,
+				DE8822350EC80C0A00CBC30A /* CGBuilder.h */,
+				1ABC36930C7A4BDC006DB0AB /* CGBuiltin.cpp */,
+				35475B1F0E79973F0000BFE4 /* CGCall.cpp */,
+				35475B220E7997680000BFE4 /* CGCall.h */,
+				1A4C41BE105B4C0B0047B5E7 /* CGClass.cpp */,
+				1A5D5E570E5E81010023C059 /* CGCXX.cpp */,
+				1A649E1E0F9599DA005B965E /* CGCXX.h */,
+				35A3E7000DD3874400757F74 /* CGDebugInfo.cpp */,
+				35A3E7010DD3874400757F74 /* CGDebugInfo.h */,
+				DE4264FB0C113592005A861D /* CGDecl.cpp */,
+				1A986AB610D0746D00A8EA9E /* CGDeclCXX.cpp */,
+				1AF1B50E109A4FB800AFAFAC /* CGException.cpp */,
+				DE4772FB0C10EAEC002239E8 /* CGExpr.cpp */,
+				DEF2EFF20C6CDD74000C4259 /* CGExprAgg.cpp */,
+				1A6B6E991069833600BB4A8F /* CGExprCXX.cpp */,
+				DE224FF70C7AA98800D370A5 /* CGExprComplex.cpp */,
+				1A376A2C0D4AED9B002A1C52 /* CGExprConstant.cpp */,
+				DE22526F0C7E82D000D370A5 /* CGExprScalar.cpp */,
+				1A7342470C7B57D500122F56 /* CGObjC.cpp */,
+				DE38CD4E0D794CF900A273B6 /* CGObjCRuntime.h */,
+				DE38CD4F0D794D0100A273B6 /* CGObjCGNU.cpp */,
+				3552E7580E520DD7003A8CA5 /* CGObjCMac.cpp */,
+				1AFF8AE11012BFC900D248DA /* CGRecordLayoutBuilder.cpp */,
+				1A6C01F6108128710072DEE4 /* CGRTTI.cpp */,
+				DE4772F90C10EAE5002239E8 /* CGStmt.cpp */,
+				1A6FE7080FD6F85800E00CA9 /* CGTemporaries.cpp */,
+				35475B230E7997680000BFE4 /* CGValue.h */,
+				1A81AA18108144F40094E50B /* CGVTables.cpp */,
+				1A81AA5D108278A20094E50B /* CGVTables.h */,
+				1A97825A1108BA18002B98FC /* CGVTT.cpp */,
+				DE928B800C0A615B00231DA4 /* CodeGenFunction.h */,
+				DE928B820C0A616000231DA4 /* CodeGenFunction.cpp */,
+				DE928B7C0C0A615100231DA4 /* CodeGenModule.h */,
+				DE928B7E0C0A615600231DA4 /* CodeGenModule.cpp */,
+				DEEBC3BB0C2363BC00A9FE82 /* CodeGenTypes.cpp */,
+				DEEBC3B90C2363B800A9FE82 /* CodeGenTypes.h */,
+				1A31B27210ACE6DA009E0C8B /* GlobalDecl.h */,
+				1A2193CC0F45EEB700C0713D /* Mangle.cpp */,
+				1A2193CD0F45EEB700C0713D /* Mangle.h */,
+				DE928B120C05659200231DA4 /* ModuleBuilder.cpp */,
+				1A621BB5110FE6AA009E6834 /* TargetInfo.cpp */,
+				1A621BB6110FE6AA009E6834 /* TargetInfo.h */,
+			);
+			name = CodeGen;
+			sourceTree = "<group>";
+		};
+		DE928B140C05659A00231DA4 /* CodeGen */ = {
+			isa = PBXGroup;
+			children = (
+				DE928B1F0C0565B000231DA4 /* ModuleBuilder.h */,
+			);
+			name = CodeGen;
+			sourceTree = "<group>";
+		};
+		DEC8D98B0A9433BC00353FCA /* AST */ = {
+			isa = PBXGroup;
+			children = (
+				1A15C407118226980092260D /* ASTImporter.h */,
+				1A15C408118226980092260D /* ASTVector.h */,
+				1A15C409118226980092260D /* CharUnits.h */,
+				1A15C40A118226980092260D /* DeclAccessPair.h */,
+				1A15C40B118226980092260D /* DeclFriend.h */,
+				1A15C40C118226980092260D /* DependentDiagnostic.h */,
+				1A15C40D118226980092260D /* TemplateBase.h */,
+				1A15C40E118226980092260D /* UnresolvedSet.h */,
+				1A15C40F118226980092260D /* UsuallyTinyPtrVector.h */,
+				904753791096376F00CBDDDD /* CXXInheritance.h */,
+				9047537A1096376F00CBDDDD /* Redeclarable.h */,
+				9047537B1096376F00CBDDDD /* TypeLoc.h */,
+				9047537C1096376F00CBDDDD /* TypeLocBuilder.h */,
+				9047537D1096376F00CBDDDD /* TypeLocNodes.def */,
+				9047537E1096376F00CBDDDD /* TypeLocVisitor.h */,
+				9047537F1096376F00CBDDDD /* TypeVisitor.h */,
+				DE613EF30E0E148D00B05B79 /* APValue.h */,
+				DEC8D9A30A94346E00353FCA /* AST.h */,
+				35BFBD2B0C9EDE1E006CB644 /* ASTConsumer.h */,
+				DE75ED280B044DC90020CF81 /* ASTContext.h */,
+				DEA09A6E0F31756F000C2258 /* ASTDiagnostic.h */,
+				1A72BEAC0D641E9400B085E9 /* Attr.h */,
+				1A535EDB107BC47B000C3AE7 /* CanonicalType.h */,
+				90FB99DE0F98FB1D008F9415 /* DeclContextInternals.h */,
+				90FB99DF0F98FB1D008F9415 /* DeclVisitor.h */,
+				90FB99E00F98FB1D008F9415 /* ExternalASTSource.h */,
+				DEC8D9900A9433CD00353FCA /* Decl.h */,
+				3538FDB60ED24A2C005EC283 /* DeclarationName.h */,
+				035611470DA6A45C00D2EF2A /* DeclBase.h */,
+				84AF36A00CB17A3B00C820A5 /* DeclObjC.h */,
+				35EE48AD0E0C4CB200715C54 /* DeclCXX.h */,
+				358D23090E8BEB850003DDCC /* DeclGroup.h */,
+				DEDFE5270F63A9230035BD10 /* DeclNodes.def */,
+				DEB076C90F3A221200F5A2BE /* DeclTemplate.h */,
+				DE0FCA620A95859D00248FD5 /* Expr.h */,
+				1A30A9E80B93A4C800201A91 /* ExprCXX.h */,
+				35CEA05A0DF9E82700A41296 /* ExprObjC.h */,
+				1AA963AB10D8576800786C86 /* FullExpr.h */,
+				DEDFE5CB0F7206CC0035BD10 /* NestedNameSpecifier.h */,
+				35EE48AE0E0C4CB200715C54 /* ParentMap.h */,
+				3547129D0C88881300B3E1D5 /* PrettyPrinter.h */,
+				DE6951C60C4D1F5D00A5826B /* RecordLayout.h */,
+				DE3452800AEF1B1800DBC861 /* Stmt.h */,
+				DECB73550FA3EE5A00F5FBC7 /* StmtCXX.h */,
+				DE345F210AFD347900DBC861 /* StmtNodes.def */,
+				DECB734E0FA3ED8400F5FBC7 /* StmtObjC.h */,
+				DE345C190AFC658B00DBC861 /* StmtVisitor.h */,
+				35847BE30CC7DB9000C40FFF /* StmtIterator.h */,
+				35CFFE010CA1CBDD00E6F2BE /* StmtGraphTraits.h */,
+				DEDFF87F0F848CE30035BD10 /* TemplateName.h */,
+				DEF16BE40FA13A5B0098507F /* TypeNodes.def */,
+				DEF16BE50FA13A650098507F /* TypeOrdering.h */,
+				DE3464210B03040900DBC861 /* Type.h */,
+			);
+			name = AST;
+			sourceTree = "<group>";
+		};
+		DEC8D9920A9433F400353FCA /* AST */ = {
+			isa = PBXGroup;
+			children = (
+				1ABD23B11182449800A48E65 /* APValue.cpp */,
+				1ABD23B21182449800A48E65 /* ASTConsumer.cpp */,
+				1ABD23B31182449800A48E65 /* ASTContext.cpp */,
+				1ABD23B41182449800A48E65 /* ASTDiagnostic.cpp */,
+				1ABD23B51182449800A48E65 /* ASTImporter.cpp */,
+				1ABD23B61182449800A48E65 /* AttrImpl.cpp */,
+				1ABD23B71182449800A48E65 /* CXXInheritance.cpp */,
+				1ABD23B81182449800A48E65 /* Decl.cpp */,
+				1ABD23B91182449800A48E65 /* DeclarationName.cpp */,
+				1ABD23BA1182449800A48E65 /* DeclBase.cpp */,
+				1ABD23BB1182449800A48E65 /* DeclCXX.cpp */,
+				1ABD23BC1182449800A48E65 /* DeclFriend.cpp */,
+				1ABD23BD1182449800A48E65 /* DeclGroup.cpp */,
+				1ABD23BE1182449800A48E65 /* DeclObjC.cpp */,
+				1ABD23BF1182449800A48E65 /* DeclPrinter.cpp */,
+				1ABD23C01182449800A48E65 /* DeclTemplate.cpp */,
+				1ABD23C11182449800A48E65 /* Expr.cpp */,
+				1ABD23C21182449800A48E65 /* ExprConstant.cpp */,
+				1ABD23C31182449800A48E65 /* ExprCXX.cpp */,
+				1ABD23C41182449800A48E65 /* FullExpr.cpp */,
+				1ABD23C51182449800A48E65 /* InheritViz.cpp */,
+				1ABD23C61182449800A48E65 /* NestedNameSpecifier.cpp */,
+				1ABD23C71182449800A48E65 /* ParentMap.cpp */,
+				1ABD23C81182449800A48E65 /* RecordLayout.cpp */,
+				1ABD23C91182449800A48E65 /* RecordLayoutBuilder.cpp */,
+				1ABD23CA1182449800A48E65 /* RecordLayoutBuilder.h */,
+				1ABD23CB1182449800A48E65 /* Stmt.cpp */,
+				1ABD23CC1182449800A48E65 /* StmtDumper.cpp */,
+				1ABD23CD1182449800A48E65 /* StmtIterator.cpp */,
+				1ABD23CE1182449800A48E65 /* StmtPrinter.cpp */,
+				1ABD23CF1182449800A48E65 /* StmtProfile.cpp */,
+				1ABD23D01182449800A48E65 /* StmtViz.cpp */,
+				1ABD23D11182449800A48E65 /* TemplateBase.cpp */,
+				1ABD23D21182449800A48E65 /* TemplateName.cpp */,
+				1ABD23D31182449800A48E65 /* Type.cpp */,
+				1ABD23D41182449800A48E65 /* TypeLoc.cpp */,
+				1ABD23D51182449800A48E65 /* TypePrinter.cpp */,
+			);
+			name = AST;
+			path = lib/AST;
+			sourceTree = "<group>";
+		};
+		DED7D72E0A524295003AD0FB /* include */ = {
+			isa = PBXGroup;
+			children = (
+				DED7D7300A524295003AD0FB /* Basic */,
+				DED7D7390A524295003AD0FB /* Lex */,
+				DE1F21F20A7D84E800FBF588 /* Parse */,
+				DEC8D98B0A9433BC00353FCA /* AST */,
+				DE67E7260C02108300F66BC5 /* Sema */,
+				DE928B140C05659A00231DA4 /* CodeGen */,
+				356EF9AF0C8F7DA4006650F5 /* Analysis */,
+				90FD6D5E103C3D03005F5B73 /* Index */,
+				DEF7D9F40C9C8B020001F598 /* Rewrite */,
+				DEF1615D0F65C7FC0098507F /* Frontend */,
+				DEF165020F8D46810098507F /* Driver */,
+				9012911210470FAF0083456D /* clang-c */,
+			);
+			path = include;
+			sourceTree = "<group>";
+		};
+		DED7D7300A524295003AD0FB /* Basic */ = {
+			isa = PBXGroup;
+			children = (
+				DE37251C0FE4818000CF2CC2 /* Builtins.h */,
+				DE37252A0FE4818F00CF2CC2 /* Builtins.def */,
+				DE3725330FE4827200CF2CC2 /* BuiltinsPPC.def */,
+				DE3725320FE4826C00CF2CC2 /* BuiltinsX86.def */,
+				906BF4AE0F83BA16001071FA /* ConvertUTF.h */,
+				DED7D7310A524295003AD0FB /* Diagnostic.h */,
+				DEDFFF070F959EE60035BD10 /* Diagnostic.td */,
+				1A7019E90F79BC1100FEC4D1 /* DiagnosticAnalysisKinds.td */,
+				1A7019EA0F79BC1100FEC4D1 /* DiagnosticASTKinds.td */,
+				1A7019EB0F79BC1100FEC4D1 /* DiagnosticCommonKinds.td */,
+				1A7019EC0F79BC1100FEC4D1 /* DiagnosticDriverKinds.td */,
+				1A7019ED0F79BC1100FEC4D1 /* DiagnosticFrontendKinds.td */,
+				DEDFFF530F9704580035BD10 /* DiagnosticGroups.td */,
+				1A7019EE0F79BC1100FEC4D1 /* DiagnosticLexKinds.td */,
+				1A7019EF0F79BC1100FEC4D1 /* DiagnosticParseKinds.td */,
+				1A701A250F79CE1C00FEC4D1 /* DiagnosticSemaKinds.td */,
+				DED7D7330A524295003AD0FB /* FileManager.h */,
+				DE3986EF0CB8D4B300223765 /* IdentifierTable.h */,
+				DE06B73D0A8307640050E87E /* LangOptions.h */,
+				9063F2280F9E911F002F7251 /* OnDiskHashTable.h */,
+				DE8824560ED1244600CBC30A /* OperatorKinds.def */,
+				DE8824530ED1243E00CBC30A /* OperatorKinds.h */,
+				1AB290021045858B00FE33D8 /* PartialDiagnostic.h */,
+				DEAABDF70F5F477C0098928A /* PrettyStackTrace.h */,
+				DED7D7350A524295003AD0FB /* SourceLocation.h */,
+				DED7D7360A524295003AD0FB /* SourceManager.h */,
+				9063F2290F9E911F002F7251 /* SourceManagerInternals.h */,
+				DE3725310FE4822800CF2CC2 /* TargetBuiltins.h */,
+				DE46BF270AE0A82D00CC047C /* TargetInfo.h */,
+				9063F22A0F9E911F002F7251 /* TemplateKinds.h */,
+				DED7D7380A524295003AD0FB /* TokenKinds.h */,
+				DED7D7370A524295003AD0FB /* TokenKinds.def */,
+				DEB089EE0F12F1D900522C07 /* TypeTraits.h */,
+			);
+			name = Basic;
+			path = clang/Basic;
+			sourceTree = "<group>";
+		};
+		DED7D7390A524295003AD0FB /* Lex */ = {
+			isa = PBXGroup;
+			children = (
+				DE3450D60AEB543100DBC861 /* DirectoryLookup.h */,
+				DE704BD10D1647E7009C7762 /* HeaderMap.h */,
+				DE344AB70AE5DF6D00DBC861 /* HeaderSearch.h */,
+				DEA09A830F3175BF000C2258 /* LexDiagnostic.h */,
+				DED7D73B0A524295003AD0FB /* Lexer.h */,
+				1A869A6E0BA2164C008DA07A /* LiteralSupport.h */,
+				DED7D73E0A524295003AD0FB /* MacroInfo.h */,
+				DEAEE98A0A5A2B970045101B /* MultipleIncludeOpt.h */,
+				DE01DA480B12ADA300AC22CE /* PPCallbacks.h */,
+				DE8823DE0ED0B78600CBC30A /* PTHLexer.h */,
+				3598EBEB0EDE23EF0070CA16 /* PTHManager.h */,
+				DED7D73F0A524295003AD0FB /* Pragma.h */,
+				DED7D7400A524295003AD0FB /* Preprocessor.h */,
+				35B820740ECB811A0020BEC0 /* PreprocessorLexer.h */,
+				DED7D9170A52518C003AD0FB /* ScratchBuffer.h */,
+				DE6954630C5121BD00A5826B /* Token.h */,
+				DEB077930F44F96000F5A2BE /* TokenConcatenation.h */,
+				DE85CD840D8380F20070E26E /* TokenLexer.h */,
+			);
+			name = Lex;
+			path = clang/Lex;
+			sourceTree = "<group>";
+		};
+		DED7D7500A5242C7003AD0FB /* Basic */ = {
+			isa = PBXGroup;
+			children = (
+				DE37252D0FE481AD00CF2CC2 /* Builtins.cpp */,
+				906BF4AF0F83BA2E001071FA /* ConvertUTF.c */,
+				DED7D75D0A5242C7003AD0FB /* Diagnostic.cpp */,
+				DED7D75E0A5242C7003AD0FB /* FileManager.cpp */,
+				DE3986F30CB8D50C00223765 /* IdentifierTable.cpp */,
+				35707EFD0CD0F5CC000B2204 /* SourceLocation.cpp */,
+				DED7D76D0A5242C7003AD0FB /* SourceManager.cpp */,
+				DED626C80AE0C065001E80A4 /* TargetInfo.cpp */,
+				03F50AC50D416EAA00B9CF60 /* Targets.cpp */,
+				DED7D76E0A5242C7003AD0FB /* TokenKinds.cpp */,
+			);
+			name = Basic;
+			path = lib/Basic;
+			sourceTree = "<group>";
+		};
+		DED7D78C0A5242E6003AD0FB /* Lex */ = {
+			isa = PBXGroup;
+			children = (
+				DE704DD10D1668A4009C7762 /* HeaderMap.cpp */,
+				DE344B530AE5E46C00DBC861 /* HeaderSearch.cpp */,
+				DED7D79E0A5242E6003AD0FB /* Lexer.cpp */,
+				1A869AA70BA21ABA008DA07A /* LiteralSupport.cpp */,
+				DE85CD9E0D8382DD0070E26E /* MacroArgs.h */,
+				DE85CDA20D8383B20070E26E /* MacroArgs.cpp */,
+				DED7D7A00A5242E6003AD0FB /* MacroInfo.cpp */,
+				3552E7540E520D80003A8CA5 /* PPCaching.cpp */,
+				DE85CDAF0D838C390070E26E /* PPDirectives.cpp */,
+				DED7D7A20A5242E6003AD0FB /* PPExpressions.cpp */,
+				DE85CDB50D839BAE0070E26E /* PPLexerChange.cpp */,
+				DE85CDAB0D838C120070E26E /* PPMacroExpansion.cpp */,
+				DED7D7A30A5242E6003AD0FB /* Pragma.cpp */,
+				DED7D7A40A5242E6003AD0FB /* Preprocessor.cpp */,
+				3537AA0D0ECD08A4008F7CDC /* PreprocessorLexer.cpp */,
+				35E1946C0ECB83C100F21733 /* PTHLexer.cpp */,
+				DED7D9E40A5257F6003AD0FB /* ScratchBuffer.cpp */,
+				DEB077980F44F97800F5A2BE /* TokenConcatenation.cpp */,
+				DE85CD800D8380B10070E26E /* TokenLexer.cpp */,
+			);
+			name = Lex;
+			path = lib/Lex;
+			sourceTree = "<group>";
+		};
+		DEDFE61F0F7B3AE10035BD10 /* Tools */ = {
+			isa = PBXGroup;
+			children = (
+				90F9EFA8104ABDC400D09A15 /* c-index-test */,
+				9012911E104812DA0083456D /* CIndex */,
+				90FD6DB4103D9763005F5B73 /* index-test */,
+				DEDFE6210F7B3AF10035BD10 /* clang */,
+			);
+			name = Tools;
+			sourceTree = "<group>";
+		};
+		DEDFE6210F7B3AF10035BD10 /* clang */ = {
+			isa = PBXGroup;
+			children = (
+				E16B523410D30B2400430AC9 /* cc1_main.cpp */,
+				DEDFE6450F7B3B4E0035BD10 /* driver.cpp */,
+			);
+			name = clang;
+			sourceTree = "<group>";
+		};
+		DEDFE6470F7B3B560035BD10 /* Driver */ = {
+			isa = PBXGroup;
+			children = (
+				DEDFE6480F7B3B830035BD10 /* Types.cpp */,
+				DEDFE6490F7B3B830035BD10 /* Tools.h */,
+				DEDFE64A0F7B3B830035BD10 /* Tools.cpp */,
+				DEDFE64B0F7B3B830035BD10 /* ToolChains.h */,
+				DEDFE64C0F7B3B830035BD10 /* Compilation.cpp */,
+				DEDFE64D0F7B3B830035BD10 /* ArgList.cpp */,
+				DEDFE64E0F7B3B830035BD10 /* Arg.cpp */,
+				DEDFE64F0F7B3B830035BD10 /* Action.cpp */,
+				DEDFE6500F7B3B830035BD10 /* Phases.cpp */,
+				DEDFE6510F7B3B830035BD10 /* OptTable.cpp */,
+				DEDFE6520F7B3B830035BD10 /* Option.cpp */,
+				DEDFE6530F7B3B830035BD10 /* Job.cpp */,
+				DEDFE6540F7B3B830035BD10 /* InputInfo.h */,
+				DEDFE6550F7B3B830035BD10 /* ToolChains.cpp */,
+				DEDFE6560F7B3B830035BD10 /* ToolChain.cpp */,
+				DEDFE6570F7B3B830035BD10 /* Tool.cpp */,
+				DEDFE6580F7B3B830035BD10 /* HostInfo.cpp */,
+				DEDFE6590F7B3B830035BD10 /* Driver.cpp */,
+			);
+			name = Driver;
+			sourceTree = "<group>";
+		};
+		DEF1615D0F65C7FC0098507F /* Frontend */ = {
+			isa = PBXGroup;
+			children = (
+				90FD6D86103C3D80005F5B73 /* Analyses.def */,
+				90FD6D87103C3D80005F5B73 /* AnalysisConsumer.h */,
+				90FD6D88103C3D80005F5B73 /* ASTConsumers.h */,
+				90FD6D89103C3D80005F5B73 /* ASTUnit.h */,
+				90FD6D8A103C3D80005F5B73 /* CommandLineSourceLoc.h */,
+				90FD6D8B103C3D80005F5B73 /* DeclContextXML.def */,
+				90FD6D8C103C3D80005F5B73 /* DeclXML.def */,
+				90FD6D8D103C3D80005F5B73 /* DocumentXML.def */,
+				90FD6D8E103C3D80005F5B73 /* DocumentXML.h */,
+				90FD6D8F103C3D80005F5B73 /* StmtXML.def */,
+				90FD6D90103C3D80005F5B73 /* TypeXML.def */,
+				90FD6D91103C3D80005F5B73 /* Utils.h */,
+				DEF161620F65C81C0098507F /* CompileOptions.h */,
+				DEF168620F9549250098507F /* FixItRewriter.h */,
+				DEF169220F9645960098507F /* FrontendDiagnostic.h */,
+				DEF1615E0F65C81C0098507F /* InitHeaderSearch.h */,
+				DECB6F030F9D939A00F5FBC7 /* InitPreprocessor.h */,
+				DEF1615F0F65C81C0098507F /* ManagerRegistry.h */,
+				DEF1657E0F8FB3730098507F /* PCHBitCodes.h */,
+				DEF1657B0F8FB36E0098507F /* PCHReader.h */,
+				DEF165780F8FB3690098507F /* PCHWriter.h */,
+				DEF161610F65C81C0098507F /* PathDiagnosticClients.h */,
+				DEF161600F65C81C0098507F /* TextDiagnosticBuffer.h */,
+				DEF161630F65C81C0098507F /* TextDiagnosticPrinter.h */,
+			);
+			name = Frontend;
+			sourceTree = "<group>";
+		};
+		DEF165020F8D46810098507F /* Driver */ = {
+			isa = PBXGroup;
+			children = (
+				DEF165160F8D46980098507F /* Action.h */,
+				DEF1651D0F8D46980098507F /* ArgList.h */,
+				DEF1651E0F8D46980098507F /* Arg.h */,
+				DEF165170F8D46980098507F /* Compilation.h */,
+				DEF165240F8D46980098507F /* DriverDiagnostic.h */,
+				DEF165200F8D46980098507F /* Driver.h */,
+				DEF1651F0F8D46980098507F /* HostInfo.h */,
+				DEF165210F8D46980098507F /* Job.h */,
+				DEF165180F8D46980098507F /* Options.def */,
+				DEF165190F8D46980098507F /* Option.h */,
+				DEF1651C0F8D46980098507F /* Options.h */,
+				DEF165230F8D46980098507F /* Phases.h */,
+				DEF165140F8D46980098507F /* Tool.h */,
+				DEF165150F8D46980098507F /* Types.h */,
+				DEF1651A0F8D46980098507F /* Types.def */,
+				DEF1651B0F8D46980098507F /* ToolChain.h */,
+				DEF165220F8D46980098507F /* Util.h */,
+			);
+			name = Driver;
+			sourceTree = "<group>";
+		};
+		DEF7D9F40C9C8B020001F598 /* Rewrite */ = {
+			isa = PBXGroup;
+			children = (
+				DEFFECA30DB093D100B4E7C3 /* DeltaTree.h */,
+				35F2BE7B0DAC2963006E7668 /* HTMLRewrite.h */,
+				DEF7D9F60C9C8B1A0001F598 /* Rewriter.h */,
+				DE53370B0CE2D96F00D9A028 /* RewriteRope.h */,
+				DE4DC7980EA1BE4400069E5A /* TokenRewriter.h */,
+			);
+			name = Rewrite;
+			sourceTree = "<group>";
+		};
+		DEF7D9F50C9C8B0C0001F598 /* Rewrite */ = {
+			isa = PBXGroup;
+			children = (
+				DEFFECA60DB1546600B4E7C3 /* DeltaTree.cpp */,
+				72D16C1E0D9975C400E6DA4A /* HTMLRewrite.cpp */,
+				DEF7D9F80C9C8B1D0001F598 /* Rewriter.cpp */,
+				DECAB0CF0DB3C84200E13CCB /* RewriteRope.cpp */,
+				DE4DC7A20EA1C33E00069E5A /* TokenRewriter.cpp */,
+			);
+			name = Rewrite;
+			sourceTree = "<group>";
+		};
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+		8DD76F620486A84900D96B5E /* clang */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 1DEB923108733DC60010E9CD /* Build configuration list for PBXNativeTarget "clang" */;
+			buildPhases = (
+				8DD76F640486A84900D96B5E /* Sources */,
+				8DD76F660486A84900D96B5E /* Frameworks */,
+				8DD76F690486A84900D96B5E /* CopyFiles */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = clang;
+			productInstallPath = "$(HOME)/bin";
+			productName = clang;
+			productReference = 8DD76F6C0486A84900D96B5E /* clang */;
+			productType = "com.apple.product-type.tool";
+		};
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+		08FB7793FE84155DC02AAC07 /* Project object */ = {
+			isa = PBXProject;
+			buildConfigurationList = 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "clang" */;
+			compatibilityVersion = "Xcode 2.4";
+			hasScannedForEncodings = 1;
+			mainGroup = 08FB7794FE84155DC02AAC07 /* clang */;
+			projectDirPath = "";
+			projectRoot = "";
+			targets = (
+				8DD76F620486A84900D96B5E /* clang */,
+			);
+		};
+/* End PBXProject section */
+
+/* Begin PBXSourcesBuildPhase section */
+		8DD76F640486A84900D96B5E /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				DED7D77A0A5242C7003AD0FB /* Diagnostic.cpp in Sources */,
+				DED7D77B0A5242C7003AD0FB /* FileManager.cpp in Sources */,
+				DED7D7890A5242C7003AD0FB /* SourceManager.cpp in Sources */,
+				DED7D78A0A5242C7003AD0FB /* TokenKinds.cpp in Sources */,
+				DED7D7C30A5242E6003AD0FB /* Lexer.cpp in Sources */,
+				DED7D7C50A5242E6003AD0FB /* MacroInfo.cpp in Sources */,
+				DED7D7C70A5242E6003AD0FB /* PPExpressions.cpp in Sources */,
+				DED7D7C80A5242E6003AD0FB /* Pragma.cpp in Sources */,
+				DED7D7C90A5242E6003AD0FB /* Preprocessor.cpp in Sources */,
+				DED7D9E50A5257F6003AD0FB /* ScratchBuffer.cpp in Sources */,
+				DE06D4310A8BB52D0050E87E /* Parser.cpp in Sources */,
+				DED626C90AE0C065001E80A4 /* TargetInfo.cpp in Sources */,
+				DE344B540AE5E46C00DBC861 /* HeaderSearch.cpp in Sources */,
+				DE3460000AFDCC1900DBC861 /* ParseObjc.cpp in Sources */,
+				DE3460050AFDCC6500DBC861 /* ParseInit.cpp in Sources */,
+				DE34600B0AFDCCBF00DBC861 /* ParseStmt.cpp in Sources */,
+				DE34600F0AFDCCCE00DBC861 /* ParseDecl.cpp in Sources */,
+				DE3460130AFDCCDA00DBC861 /* ParseExpr.cpp in Sources */,
+				DE3461270AFE68BE00DBC861 /* MinimalAction.cpp in Sources */,
+				DE17336E0B068DC20080B521 /* DeclSpec.cpp in Sources */,
+				1A869AA80BA21ABA008DA07A /* LiteralSupport.cpp in Sources */,
+				DE67E70B0C020EC500F66BC5 /* SemaType.cpp in Sources */,
+				DE67E70D0C020ECA00F66BC5 /* SemaStmt.cpp in Sources */,
+				DE67E70F0C020ECF00F66BC5 /* SemaExprCXX.cpp in Sources */,
+				DE67E7110C020ED400F66BC5 /* SemaExpr.cpp in Sources */,
+				DE67E7130C020ED900F66BC5 /* SemaDecl.cpp in Sources */,
+				DE67E7170C020EE400F66BC5 /* Sema.cpp in Sources */,
+				DE67E71A0C020F4F00F66BC5 /* ParseAST.cpp in Sources */,
+				DE06756C0C051CFE00EBBFD8 /* ParseExprCXX.cpp in Sources */,
+				DE928B130C05659200231DA4 /* ModuleBuilder.cpp in Sources */,
+				DE928B7F0C0A615600231DA4 /* CodeGenModule.cpp in Sources */,
+				DE928B830C0A616000231DA4 /* CodeGenFunction.cpp in Sources */,
+				DE4772FA0C10EAE5002239E8 /* CGStmt.cpp in Sources */,
+				DE4772FC0C10EAEC002239E8 /* CGExpr.cpp in Sources */,
+				DE4264FC0C113592005A861D /* CGDecl.cpp in Sources */,
+				84D9A8880C1A57E100AC7ABC /* AttributeList.cpp in Sources */,
+				DEEBC3BC0C2363BC00A9FE82 /* CodeGenTypes.cpp in Sources */,
+				DEF2EFF30C6CDD74000C4259 /* CGExprAgg.cpp in Sources */,
+				DEF2F0100C6CFED5000C4259 /* SemaChecking.cpp in Sources */,
+				1ABC36940C7A4BDC006DB0AB /* CGBuiltin.cpp in Sources */,
+				DE224FF80C7AA98800D370A5 /* CGExprComplex.cpp in Sources */,
+				1A7342480C7B57D500122F56 /* CGObjC.cpp in Sources */,
+				DE2252700C7E82D000D370A5 /* CGExprScalar.cpp in Sources */,
+				DE2255FC0C8004E600D370A5 /* ParseDeclCXX.cpp in Sources */,
+				356EF9B50C8F7DDF006650F5 /* LiveVariables.cpp in Sources */,
+				DEF7D9F90C9C8B1D0001F598 /* Rewriter.cpp in Sources */,
+				DE3986F40CB8D50C00223765 /* IdentifierTable.cpp in Sources */,
+				35707EFE0CD0F5CC000B2204 /* SourceLocation.cpp in Sources */,
+				DE704B260D0FBEBE009C7762 /* SemaDeclObjC.cpp in Sources */,
+				DE704DD20D1668A4009C7762 /* HeaderMap.cpp in Sources */,
+				DE47999C0D2EBE1A00706D2D /* SemaExprObjC.cpp in Sources */,
+				03F50AC60D416EAA00B9CF60 /* Targets.cpp in Sources */,
+				1A376A2D0D4AED9B002A1C52 /* CGExprConstant.cpp in Sources */,
+				DE38CD500D794D0100A273B6 /* CGObjCGNU.cpp in Sources */,
+				DE4121350D7F1C1C0080F80A /* SymbolManager.cpp in Sources */,
+				DE4121360D7F1C1C0080F80A /* ExplodedGraph.cpp in Sources */,
+				DE4121370D7F1C1C0080F80A /* UninitializedValues.cpp in Sources */,
+				DE4121380D7F1C1C0080F80A /* GRCoreEngine.cpp in Sources */,
+				DE41213C0D7F1C1C0080F80A /* GRSimpleVals.cpp in Sources */,
+				DE41213D0D7F1C1C0080F80A /* GRBlockCounter.cpp in Sources */,
+				DE41213E0D7F1C1C0080F80A /* GRExprEngine.cpp in Sources */,
+				35D55B270D81D8C60092E734 /* BasicValueFactory.cpp in Sources */,
+				35D55B280D81D8C60092E734 /* CFRefCount.cpp in Sources */,
+				DE85CD810D8380B10070E26E /* TokenLexer.cpp in Sources */,
+				DE85CDA30D8383B20070E26E /* MacroArgs.cpp in Sources */,
+				DE85CDAC0D838C120070E26E /* PPMacroExpansion.cpp in Sources */,
+				DE85CDB00D838C390070E26E /* PPDirectives.cpp in Sources */,
+				DE85CDB60D839BAE0070E26E /* PPLexerChange.cpp in Sources */,
+				72D16C1F0D9975C400E6DA4A /* HTMLRewrite.cpp in Sources */,
+				35A8FCF90D9B4B2A001C2F97 /* PathDiagnostic.cpp in Sources */,
+				35F8D0D60D9B82CD00D91C5E /* BasicObjCFoundationChecks.cpp in Sources */,
+				3593790A0DA48ABA0043B19C /* BugReporter.cpp in Sources */,
+				35EF67700DAD1D2C00B19414 /* SemaDeclCXX.cpp in Sources */,
+				352712510DAFE54700C76352 /* IdentifierResolver.cpp in Sources */,
+				DEFFECA70DB1546600B4E7C3 /* DeltaTree.cpp in Sources */,
+				DECAB0D00DB3C84200E13CCB /* RewriteRope.cpp in Sources */,
+				35EFEFB60DB67ED60020783D /* GRTransferFuncs.cpp in Sources */,
+				35A3E7020DD3874400757F74 /* CGDebugInfo.cpp in Sources */,
+				3599299B0DE2425300A8A33E /* SemaInit.cpp in Sources */,
+				3534A01D0E129849002709B2 /* ParseCXXInlineMethods.cpp in Sources */,
+				DE22BCF20E14197E0094DC60 /* SemaDeclAttr.cpp in Sources */,
+				3595AFB80E1C8D62004CDF09 /* CheckObjCDealloc.cpp in Sources */,
+				3536456B0E23EBF7009C6509 /* Environment.cpp in Sources */,
+				3558F76D0E267C8300A5B0DF /* BasicStore.cpp in Sources */,
+				3507E4C20E27FE2D00FB7B57 /* CheckObjCInstMethSignature.cpp in Sources */,
+				35862B0D0E3628CB0009F542 /* CheckDeadStores.cpp in Sources */,
+				35862B120E3629850009F542 /* GRExprEngineInternalChecks.cpp in Sources */,
+				35F2A01E0E36AFF100D17527 /* CheckObjCUnusedIVars.cpp in Sources */,
+				3552E7550E520D80003A8CA5 /* PPCaching.cpp in Sources */,
+				3552E7590E520DD7003A8CA5 /* CGObjCMac.cpp in Sources */,
+				358F51520E529AA4007F2102 /* GRState.cpp in Sources */,
+				1A5D5E580E5E81010023C059 /* CGCXX.cpp in Sources */,
+				358CFBB80E65AB04002A8E19 /* BasicConstraintManager.cpp in Sources */,
+				35475B200E79973F0000BFE4 /* CGCall.cpp in Sources */,
+				35BAC1E80E82C5B7003FB76F /* CheckNSError.cpp in Sources */,
+				355106860E9A8507006A4E44 /* MemRegion.cpp in Sources */,
+				3551068C0E9A8546006A4E44 /* ParsePragma.cpp in Sources */,
+				3551068D0E9A8546006A4E44 /* ParseTentative.cpp in Sources */,
+				DE4DC7A30EA1C33E00069E5A /* TokenRewriter.cpp in Sources */,
+				35A057E20EAE2D950069249F /* RegionStore.cpp in Sources */,
+				35A057E30EAE2D950069249F /* SVals.cpp in Sources */,
+				35585DC00EAFBC4500D0A97A /* SemaOverload.cpp in Sources */,
+				35E194690ECB82FB00F21733 /* SemaCXXScopeSpec.cpp in Sources */,
+				35E1946A0ECB82FB00F21733 /* SemaCXXCast.cpp in Sources */,
+				35E1946D0ECB83C100F21733 /* PTHLexer.cpp in Sources */,
+				3537AA0E0ECD08A4008F7CDC /* PreprocessorLexer.cpp in Sources */,
+				353959D50EE5F88A00E82461 /* ParseTemplate.cpp in Sources */,
+				3591853F0EFB1088000039AF /* SemaTemplate.cpp in Sources */,
+				357EA27D0F2526F300439B60 /* SemaLookup.cpp in Sources */,
+				1A471AB50F437BC500753CE8 /* CGBlocks.cpp in Sources */,
+				DEB077990F44F97800F5A2BE /* TokenConcatenation.cpp in Sources */,
+				1A2193CE0F45EEB700C0713D /* Mangle.cpp in Sources */,
+				DEB07AC80F4A427E00F5A2BE /* SemaAttr.cpp in Sources */,
+				352246E70F5C6BE000D0D279 /* HTMLDiagnostics.cpp in Sources */,
+				352246E80F5C6BE000D0D279 /* InitHeaderSearch.cpp in Sources */,
+				352246EA0F5C6BE000D0D279 /* PlistDiagnostics.cpp in Sources */,
+				352246EB0F5C6BE000D0D279 /* TextDiagnosticBuffer.cpp in Sources */,
+				352246EC0F5C6BE000D0D279 /* TextDiagnosticPrinter.cpp in Sources */,
+				35544B880F5C7FD700D92AA9 /* RangeConstraintManager.cpp in Sources */,
+				35544B890F5C7FD700D92AA9 /* SimpleConstraintManager.cpp in Sources */,
+				35544B8C0F5C803200D92AA9 /* SemaTemplateInstantiate.cpp in Sources */,
+				1ADF47AF0F782C3200E48A8A /* SemaTemplateInstantiateDecl.cpp in Sources */,
+				DEDFE6460F7B3B4E0035BD10 /* driver.cpp in Sources */,
+				DEDFE65A0F7B3B830035BD10 /* Types.cpp in Sources */,
+				DEDFE65B0F7B3B830035BD10 /* Tools.cpp in Sources */,
+				DEDFE65C0F7B3B830035BD10 /* Compilation.cpp in Sources */,
+				DEDFE65D0F7B3B830035BD10 /* ArgList.cpp in Sources */,
+				DEDFE65E0F7B3B830035BD10 /* Arg.cpp in Sources */,
+				DEDFE65F0F7B3B830035BD10 /* Action.cpp in Sources */,
+				DEDFE6600F7B3B830035BD10 /* Phases.cpp in Sources */,
+				DEDFE6610F7B3B830035BD10 /* OptTable.cpp in Sources */,
+				DEDFE6620F7B3B830035BD10 /* Option.cpp in Sources */,
+				DEDFE6630F7B3B830035BD10 /* Job.cpp in Sources */,
+				DEDFE6640F7B3B830035BD10 /* ToolChains.cpp in Sources */,
+				DEDFE6650F7B3B830035BD10 /* ToolChain.cpp in Sources */,
+				DEDFE6660F7B3B830035BD10 /* Tool.cpp in Sources */,
+				DEDFE6670F7B3B830035BD10 /* HostInfo.cpp in Sources */,
+				DEDFE6680F7B3B830035BD10 /* Driver.cpp in Sources */,
+				1A701B640F7C8FE400FEC4D1 /* SemaAccess.cpp in Sources */,
+				906BF4B00F83BA2E001071FA /* ConvertUTF.c in Sources */,
+				DEF165710F8FB34D0098507F /* PCHWriter.cpp in Sources */,
+				DEF165750F8FB3510098507F /* PCHReader.cpp in Sources */,
+				DEF168400F9548DC0098507F /* FixItRewriter.cpp in Sources */,
+				DECB6D650F9AE26600F5FBC7 /* JumpDiagnostics.cpp in Sources */,
+				DECB6F070F9D93A800F5FBC7 /* InitPreprocessor.cpp in Sources */,
+				DECB77130FA5752300F5FBC7 /* PCHReaderStmt.cpp in Sources */,
+				DECB77790FA579B000F5FBC7 /* PCHReaderDecl.cpp in Sources */,
+				DECB77F70FA5850200F5FBC7 /* PCHWriterDecl.cpp in Sources */,
+				DECB78170FA5882F00F5FBC7 /* PCHWriterStmt.cpp in Sources */,
+				1A2A54B50FD1DD1C00F4CE45 /* AnalysisConsumer.cpp in Sources */,
+				1A2A54B60FD1DD1C00F4CE45 /* ASTConsumers.cpp in Sources */,
+				1A2A54B80FD1DD1C00F4CE45 /* CacheTokens.cpp in Sources */,
+				1A2A54B90FD1DD1C00F4CE45 /* DependencyFile.cpp in Sources */,
+				1A2A54BA0FD1DD1C00F4CE45 /* DiagChecker.cpp in Sources */,
+				1A2A54BB0FD1DD1C00F4CE45 /* DocumentXML.cpp in Sources */,
+				1A2A54BC0FD1DD1C00F4CE45 /* GeneratePCH.cpp in Sources */,
+				1A2A54BD0FD1DD1C00F4CE45 /* HTMLPrint.cpp in Sources */,
+				1A2A54BE0FD1DD1C00F4CE45 /* PrintParserCallbacks.cpp in Sources */,
+				1A2A54BF0FD1DD1C00F4CE45 /* PrintPreprocessedOutput.cpp in Sources */,
+				1A2A54C10FD1DD1C00F4CE45 /* RewriteMacros.cpp in Sources */,
+				1A2A54C20FD1DD1C00F4CE45 /* RewriteObjC.cpp in Sources */,
+				1A2A54C30FD1DD1C00F4CE45 /* RewriteTest.cpp in Sources */,
+				1A2A54C40FD1DD1C00F4CE45 /* StmtXML.cpp in Sources */,
+				1A2A54C50FD1DD1C00F4CE45 /* Warnings.cpp in Sources */,
+				1A6FE7090FD6F85800E00CA9 /* CGTemporaries.cpp in Sources */,
+				BDF87CF70FD746F300BBF872 /* SemaTemplateDeduction.cpp in Sources */,
+				DE37252E0FE481AD00CF2CC2 /* Builtins.cpp in Sources */,
+				1AFF8AE31012BFC900D248DA /* CGRecordLayoutBuilder.cpp in Sources */,
+				90FD6D7B103C3D49005F5B73 /* Analyzer.cpp in Sources */,
+				90FD6D7C103C3D49005F5B73 /* ASTLocation.cpp in Sources */,
+				90FD6D7D103C3D49005F5B73 /* DeclReferenceMap.cpp in Sources */,
+				90FD6D7E103C3D49005F5B73 /* Entity.cpp in Sources */,
+				90FD6D7F103C3D49005F5B73 /* GlobalSelector.cpp in Sources */,
+				90FD6D80103C3D49005F5B73 /* Handlers.cpp in Sources */,
+				90FD6D81103C3D49005F5B73 /* Indexer.cpp in Sources */,
+				90FD6D82103C3D49005F5B73 /* IndexProvider.cpp in Sources */,
+				90FD6D83103C3D49005F5B73 /* Program.cpp in Sources */,
+				90FD6D84103C3D49005F5B73 /* ResolveLocation.cpp in Sources */,
+				90FD6D85103C3D49005F5B73 /* SelectorMap.cpp in Sources */,
+				90FD6DB6103D977E005F5B73 /* index-test.cpp in Sources */,
+				9012911D1048068D0083456D /* ASTUnit.cpp in Sources */,
+				90129121104812F90083456D /* CIndex.cpp in Sources */,
+				90F9EFAA104ABDED00D09A15 /* c-index-test.c in Sources */,
+				1A4C41BF105B4C0B0047B5E7 /* CGClass.cpp in Sources */,
+				1A6B6CD410693FC900BB4A8F /* CodeCompleteConsumer.cpp in Sources */,
+				1A6B6CD510693FC900BB4A8F /* SemaCodeComplete.cpp in Sources */,
+				1A6B6E9A1069833600BB4A8F /* CGExprCXX.cpp in Sources */,
+				1A6C01F7108128710072DEE4 /* CGRTTI.cpp in Sources */,
+				1A81AA19108144F40094E50B /* CGVTables.cpp in Sources */,
+				1AF1B50F109A4FB800AFAFAC /* CGException.cpp in Sources */,
+				1A986AB710D0746D00A8EA9E /* CGDeclCXX.cpp in Sources */,
+				E16B523510D30B2400430AC9 /* cc1_main.cpp in Sources */,
+				1ACB57E41105820D0047B991 /* CompilerInstance.cpp in Sources */,
+				1ACB57E51105820D0047B991 /* CompilerInvocation.cpp in Sources */,
+				1ACB57E61105820D0047B991 /* DeclXML.cpp in Sources */,
+				1ACB57E71105820D0047B991 /* FrontendAction.cpp in Sources */,
+				1ACB57E81105820D0047B991 /* FrontendActions.cpp in Sources */,
+				1ACB57E91105820D0047B991 /* FrontendOptions.cpp in Sources */,
+				1ACB57EA1105820D0047B991 /* LangStandards.cpp in Sources */,
+				1ACB57EB1105820D0047B991 /* TypeXML.cpp in Sources */,
+				1ACB57EC1105820D0047B991 /* VerifyDiagnosticsClient.cpp in Sources */,
+				1A97825B1108BA18002B98FC /* CGVTT.cpp in Sources */,
+				1A621BB7110FE6AA009E6834 /* TargetInfo.cpp in Sources */,
+				1A621C4211111D61009E6834 /* CIndexCodeCompletion.cpp in Sources */,
+				1A621C4311111D61009E6834 /* CIndexer.cpp in Sources */,
+				1A621C4411111D61009E6834 /* CIndexInclusionStack.cpp in Sources */,
+				1A621C4511111D61009E6834 /* CIndexUSRs.cpp in Sources */,
+				1A621C4611111D61009E6834 /* CXCursor.cpp in Sources */,
+				BF89C3E211595818001C2D68 /* AnalysisBasedWarnings.cpp in Sources */,
+				BF89C3E91159594A001C2D68 /* SemaObjCProperty.cpp in Sources */,
+				BF89C3F911595A01001C2D68 /* SemaType.cpp in Sources */,
+				BF89C3FB11595A37001C2D68 /* SemaCodeComplete.cpp in Sources */,
+				BF89C3FD11595A5D001C2D68 /* SemaExceptionSpec.cpp in Sources */,
+				1AFDD8721161085D00AE030A /* ASTMerge.cpp in Sources */,
+				1AFDD8731161085D00AE030A /* CodeGenAction.cpp in Sources */,
+				1ABD23D61182449800A48E65 /* APValue.cpp in Sources */,
+				1ABD23D71182449800A48E65 /* ASTConsumer.cpp in Sources */,
+				1ABD23D81182449800A48E65 /* ASTContext.cpp in Sources */,
+				1ABD23D91182449800A48E65 /* ASTDiagnostic.cpp in Sources */,
+				1ABD23DA1182449800A48E65 /* ASTImporter.cpp in Sources */,
+				1ABD23DB1182449800A48E65 /* AttrImpl.cpp in Sources */,
+				1ABD23DC1182449800A48E65 /* CXXInheritance.cpp in Sources */,
+				1ABD23DD1182449800A48E65 /* Decl.cpp in Sources */,
+				1ABD23DE1182449800A48E65 /* DeclarationName.cpp in Sources */,
+				1ABD23DF1182449800A48E65 /* DeclBase.cpp in Sources */,
+				1ABD23E01182449800A48E65 /* DeclCXX.cpp in Sources */,
+				1ABD23E11182449800A48E65 /* DeclFriend.cpp in Sources */,
+				1ABD23E21182449800A48E65 /* DeclGroup.cpp in Sources */,
+				1ABD23E31182449800A48E65 /* DeclObjC.cpp in Sources */,
+				1ABD23E41182449800A48E65 /* DeclPrinter.cpp in Sources */,
+				1ABD23E51182449800A48E65 /* DeclTemplate.cpp in Sources */,
+				1ABD23E61182449800A48E65 /* Expr.cpp in Sources */,
+				1ABD23E71182449800A48E65 /* ExprConstant.cpp in Sources */,
+				1ABD23E81182449800A48E65 /* ExprCXX.cpp in Sources */,
+				1ABD23E91182449800A48E65 /* FullExpr.cpp in Sources */,
+				1ABD23EA1182449800A48E65 /* InheritViz.cpp in Sources */,
+				1ABD23EB1182449800A48E65 /* NestedNameSpecifier.cpp in Sources */,
+				1ABD23EC1182449800A48E65 /* ParentMap.cpp in Sources */,
+				1ABD23ED1182449800A48E65 /* RecordLayout.cpp in Sources */,
+				1ABD23EE1182449800A48E65 /* RecordLayoutBuilder.cpp in Sources */,
+				1ABD23EF1182449800A48E65 /* Stmt.cpp in Sources */,
+				1ABD23F01182449800A48E65 /* StmtDumper.cpp in Sources */,
+				1ABD23F11182449800A48E65 /* StmtIterator.cpp in Sources */,
+				1ABD23F21182449800A48E65 /* StmtPrinter.cpp in Sources */,
+				1ABD23F31182449800A48E65 /* StmtProfile.cpp in Sources */,
+				1ABD23F41182449800A48E65 /* StmtViz.cpp in Sources */,
+				1ABD23F51182449800A48E65 /* TemplateBase.cpp in Sources */,
+				1ABD23F61182449800A48E65 /* TemplateName.cpp in Sources */,
+				1ABD23F71182449800A48E65 /* Type.cpp in Sources */,
+				1ABD23F81182449800A48E65 /* TypeLoc.cpp in Sources */,
+				1ABD23F91182449800A48E65 /* TypePrinter.cpp in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXSourcesBuildPhase section */
+
+/* Begin XCBuildConfiguration section */
+		1DEB923208733DC60010E9CD /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ARCHS = "$(NATIVE_ARCH_ACTUAL)";
+				COPY_PHASE_STRIP = NO;
+				GCC_CW_ASM_SYNTAX = NO;
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_ENABLE_CPP_EXCEPTIONS = NO;
+				GCC_ENABLE_CPP_RTTI = NO;
+				GCC_ENABLE_PASCAL_STRINGS = NO;
+				GCC_ENABLE_SYMBOL_SEPARATION = NO;
+				GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+				GCC_INLINES_ARE_PRIVATE_EXTERN = NO;
+				GCC_OPTIMIZATION_LEVEL = 0;
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					__STDC_CONSTANT_MACROS,
+					"__STDC_LIMIT_MACROS=1",
+				);
+				GCC_STRICT_ALIASING = YES;
+				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+				GCC_THREADSAFE_STATICS = NO;
+				GCC_USE_GCC3_PFE_SUPPORT = NO;
+				INSTALL_PATH = "$(HOME)/bin";
+				OTHER_LDFLAGS = (
+					"-lLLVMBitWriter",
+					"-lLLVMBitReader",
+					"-lLLVMAsmPrinter",
+					"-lLLVMSelectionDAG",
+					"-lLLVMCodeGen",
+					"-lLLVMipo",
+					"-lLLVMScalarOpts",
+					"-lLLVMTransformUtils",
+					"-lLLVMipa",
+					"-lLLVMAnalysis",
+					"-lLLVMTarget",
+					"-lLLVMCore",
+					"-lLLVMSupport",
+					"-lLLVMSystem",
+				);
+				PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
+				PRODUCT_NAME = clang;
+			};
+			name = Debug;
+		};
+		1DEB923308733DC60010E9CD /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ARCHS = "$(NATIVE_ARCH_ACTUAL)";
+				GCC_CW_ASM_SYNTAX = NO;
+				GCC_ENABLE_CPP_EXCEPTIONS = NO;
+				GCC_ENABLE_CPP_RTTI = NO;
+				GCC_ENABLE_PASCAL_STRINGS = NO;
+				GCC_ENABLE_SYMBOL_SEPARATION = NO;
+				GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+				GCC_INLINES_ARE_PRIVATE_EXTERN = NO;
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					__STDC_CONSTANT_MACROS,
+					"__STDC_LIMIT_MACROS=1",
+				);
+				GCC_STRICT_ALIASING = YES;
+				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+				GCC_THREADSAFE_STATICS = NO;
+				GCC_USE_GCC3_PFE_SUPPORT = NO;
+				INSTALL_PATH = "$(HOME)/bin";
+				OTHER_LDFLAGS = (
+					"-lLLVMBitWriter",
+					"-lLLVMBitReader",
+					"-lLLVMAsmPrinter",
+					"-lLLVMSelectionDAG",
+					"-lLLVMCodeGen",
+					"-lLLVMipo",
+					"-lLLVMScalarOpts",
+					"-lLLVMTransformUtils",
+					"-lLLVMipa",
+					"-lLLVMAnalysis",
+					"-lLLVMTarget",
+					"-lLLVMCore",
+					"-lLLVMSupport",
+					"-lLLVMSystem",
+				);
+				PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
+				PRODUCT_NAME = clang;
+			};
+			name = Release;
+		};
+		1DEB923608733DC60010E9CD /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				GCC_VERSION = "";
+				GCC_WARN_ABOUT_RETURN_TYPE = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				HEADER_SEARCH_PATHS = (
+					../../include,
+					include,
+				);
+				LIBRARY_SEARCH_PATHS = ../../Debug/lib;
+				OTHER_LDFLAGS = "";
+				PREBINDING = NO;
+			};
+			name = Debug;
+		};
+		1DEB923708733DC60010E9CD /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				GCC_WARN_ABOUT_RETURN_TYPE = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				HEADER_SEARCH_PATHS = (
+					../../include,
+					include,
+				);
+				LIBRARY_SEARCH_PATHS = ../../Release;
+				OTHER_LDFLAGS = "";
+				PREBINDING = NO;
+			};
+			name = Release;
+		};
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+		1DEB923108733DC60010E9CD /* Build configuration list for PBXNativeTarget "clang" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				1DEB923208733DC60010E9CD /* Debug */,
+				1DEB923308733DC60010E9CD /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "clang" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				1DEB923608733DC60010E9CD /* Debug */,
+				1DEB923708733DC60010E9CD /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+/* End XCConfigurationList section */
+	};
+	rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
+}
diff --git a/docs/AnalyzerRegions.html b/docs/AnalyzerRegions.html
new file mode 100644
index 0000000..35708d5
--- /dev/null
+++ b/docs/AnalyzerRegions.html
@@ -0,0 +1,258 @@
+<html>
+<head>
+<title>Static Analyzer Design Document: Memory Regions</title>
+</head>
+<body>
+  
+<h1>Static Analyzer Design Document: Memory Regions</h1>
+
+<h3>Authors</h3>
+
+<p>Ted Kremenek, <tt>kremenek at apple</tt><br>
+Zhongxing Xu, <tt>xuzhongzhing at gmail</tt></p>
+
+<h2 id="intro">Introduction</h2>
+
+<p>The path-sensitive analysis engine in libAnalysis employs an extensible API
+for abstractly modeling the memory of an analyzed program. This API employs the
+concept of "memory regions" to abstractly model chunks of program memory such as
+program variables and dynamically allocated memory such as those returned from
+'malloc' and 'alloca'. Regions are hierarchical, with subregions modeling
+subtyping relationships, field and array offsets into larger chunks of memory,
+and so on.</p>
+
+<p>The region API consists of two components:</p>
+
+<ul> <li>A taxonomy and representation of regions themselves within the analyzer
+engine. The primary definitions and interfaces are described in <tt><a
+href="http://clang.llvm.org/doxygen/MemRegion_8h-source.html">MemRegion.h</a></tt>.
+At the root of the region hierarchy is the class <tt>MemRegion</tt> with
+specific subclasses refining the region concept for variables, heap allocated
+memory, and so forth.</li> <li>The modeling of binding of values to regions. For
+example, modeling the value stored to a local variable <tt>x</tt> consists of
+recording the binding between the region for <tt>x</tt> (which represents the
+raw memory associated with <tt>x</tt>) and the value stored to <tt>x</tt>. This
+binding relationship is captured with the notion of &quot;symbolic
+stores.&quot;</li> </ul>
+
+<p>Symbolic stores, which can be thought of as representing the relation
+<tt>regions -> values</tt>, are implemented by subclasses of the
+<tt>StoreManager</tt> class (<tt><a
+href="http://clang.llvm.org/doxygen/Store_8h-source.html">Store.h</a></tt>). A
+particular StoreManager implementation has complete flexibility concerning the
+following:
+
+<ul>
+<li><em>How</em> to model the binding between regions and values</li>
+<li><em>What</em> bindings are recorded
+</ul>
+
+<p>Together, both points allow different StoreManagers to tradeoff between
+different levels of analysis precision and scalability concerning the reasoning
+of program memory. Meanwhile, the core path-sensitive engine makes no
+assumptions about either points, and queries a StoreManager about the bindings
+to a memory region through a generic interface that all StoreManagers share. If
+a particular StoreManager cannot reason about the potential bindings of a given
+memory region (e.g., '<tt>BasicStoreManager</tt>' does not reason about fields
+of structures) then the StoreManager can simply return 'unknown' (represented by
+'<tt>UnknownVal</tt>') for a particular region-binding. This separation of
+concerns not only isolates the core analysis engine from the details of
+reasoning about program memory but also facilities the option of a client of the
+path-sensitive engine to easily swap in different StoreManager implementations
+that internally reason about program memory in very different ways.</pp>
+
+<p>The rest of this document is divided into two parts. We first discuss region
+taxonomy and the semantics of regions. We then discuss the StoreManager
+interface, and details of how the currently available StoreManager classes
+implement region bindings.</p>
+
+<h2 id="regions">Memory Regions and Region Taxonomy</h2>
+
+<h3>Pointers</h3>
+
+<p>Before talking about the memory regions, we would talk about the pointers
+since memory regions are essentially used to represent pointer values.</p>
+
+<p>The pointer is a type of values. Pointer values have two semantic aspects.
+One is its physical value, which is an address or location. The other is the
+type of the memory object residing in the address.</p>
+
+<p>Memory regions are designed to abstract these two properties of the pointer.
+The physical value of a pointer is represented by MemRegion pointers. The rvalue
+type of the region corresponds to the type of the pointee object.</p>
+
+<p>One complication is that we could have different view regions on the same
+memory chunk. They represent the same memory location, but have different
+abstract location, i.e., MemRegion pointers. Thus we need to canonicalize the
+abstract locations to get a unique abstract location for one physical
+location.</p>
+
+<p>Furthermore, these different view regions may or may not represent memory
+objects of different types. Some different types are semantically the same,
+for example, 'struct s' and 'my_type' are the same type.</p>
+
+<pre>
+struct s;
+typedef struct s my_type;
+</pre>
+
+<p>But <tt>char</tt> and <tt>int</tt> are not the same type in the code below:</p>
+
+<pre>
+void *p;
+int *q = (int*) p;
+char *r = (char*) p;
+</pre
+
+<p>Thus we need to canonicalize the MemRegion which is used in binding and
+retrieving.</p>
+
+<h3>Regions</h3>
+<p>Region is the entity used to model pointer values. A Region has the following
+properties:</p>
+
+<ul>
+<li>Kind</li>
+
+<li>ObjectType: the type of the object residing on the region.</li>
+
+<li>LocationType: the type of the pointer value that the region corresponds to.
+  Usually this is the pointer to the ObjectType. But sometimes we want to cache
+  this type explicitly, for example, for a CodeTextRegion.</li>
+
+<li>StartLocation</li>
+
+<li>EndLocation</li>
+</ul>
+
+<h3>Symbolic Regions</h3>
+
+<p>A symbolic region is a map of the concept of symbolic values into the domain
+of regions. It is the way that we represent symbolic pointers. Whenever a
+symbolic pointer value is needed, a symbolic region is created to represent
+it.</p>
+
+<p>A symbolic region has no type. It wraps a SymbolData. But sometimes we have
+type information associated with a symbolic region. For this case, a
+TypedViewRegion is created to layer the type information on top of the symbolic
+region. The reason we do not carry type information with the symbolic region is
+that the symbolic regions can have no type. To be consistent, we don't let them
+to carry type information.</p>
+
+<p>Like a symbolic pointer, a symbolic region may be NULL, has unknown extent,
+and represents a generic chunk of memory.</p>
+
+<p><em><b>NOTE</b>: We plan not to use loc::SymbolVal in RegionStore and remove it
+  gradually.</em></p>
+
+<p>Symbolic regions get their rvalue types through the following ways:</p>
+
+<ul>
+<li>Through the parameter or global variable that points to it, e.g.:
+<pre>
+void f(struct s* p) {
+  ...
+}
+</pre>
+
+<p>The symbolic region pointed to by <tt>p</tt> has type <tt>struct
+s</tt>.</p></li>
+
+<li>Through explicit or implicit casts, e.g.:
+<pre>
+void f(void* p) {
+  struct s* q = (struct s*) p;
+  ...
+}
+</pre>
+</li>
+</ul>
+
+<p>We attach the type information to the symbolic region lazily. For the first
+case above, we create the <tt>TypedViewRegion</tt> only when the pointer is
+actually used to access the pointee memory object, that is when the element or
+field region is created. For the cast case, the <tt>TypedViewRegion</tt> is
+created when visiting the <tt>CastExpr</tt>.</p>
+
+<p>The reason for doing lazy typing is that symbolic regions are sometimes only
+used to do location comparison.</p>
+
+<h3>Pointer Casts</h3>
+
+<p>Pointer casts allow people to impose different 'views' onto a chunk of
+memory.</p>
+
+<p>Usually we have two kinds of casts. One kind of casts cast down with in the
+type hierarchy. It imposes more specific views onto more generic memory regions.
+The other kind of casts cast up with in the type hierarchy. It strips away more
+specific views on top of the more generic memory regions.</p>
+
+<p>We simulate the down casts by layering another <tt>TypedViewRegion</tt> on
+top of the original region. We simulate the up casts by striping away the top
+<tt>TypedViewRegion</tt>. Down casts is usually simple. For up casts, if the
+there is no <tt>TypedViewRegion</tt> to be stripped, we return the original
+region. If the underlying region is of the different type than the cast-to type,
+we flag an error state.</p>
+
+<p>For toll-free bridging casts, we return the original region.</p>
+
+<p>We can set up a partial order for pointer types, with the most general type
+<tt>void*</tt> at the top. The partial order forms a tree with <tt>void*</tt> as
+its root node.</p>
+
+<p>Every <tt>MemRegion</tt> has a root position in the type tree. For example,
+the pointee region of <tt>void *p</tt> has its root position at the root node of
+the tree. <tt>VarRegion</tt> of <tt>int x</tt> has its root position at the 'int
+type' node.</p>
+
+<p><tt>TypedViewRegion</tt> is used to move the region down or up in the tree.
+Moving down in the tree adds a <tt>TypedViewRegion</tt>. Moving up in the tree
+removes a <Tt>TypedViewRegion</tt>.</p>
+
+<p>Do we want to allow moving up beyond the root position? This happens
+when:</p> <pre> int x; void *p = &amp;x; </pre>
+
+<p>The region of <tt>x</tt> has its root position at 'int*' node. the cast to
+void* moves that region up to the 'void*' node. I propose to not allow such
+casts, and assign the region of <tt>x</tt> for <tt>p</tt>.</p>
+
+<p>Another non-ideal case is that people might cast to a non-generic pointer
+from another non-generic pointer instead of first casting it back to the generic
+pointer. Direct handling of this case would result in multiple layers of
+TypedViewRegions. This enforces an incorrect semantic view to the region,
+because we can only have one typed view on a region at a time. To avoid this
+inconsistency, before casting the region, we strip the TypedViewRegion, then do
+the cast. In summary, we only allow one layer of TypedViewRegion.</p>
+
+<h3>Region Bindings</h3>
+
+<p>The following region kinds are boundable: VarRegion, CompoundLiteralRegion,
+StringRegion, ElementRegion, FieldRegion, and ObjCIvarRegion.</p>
+
+<p>When binding regions, we perform canonicalization on element regions and field
+regions. This is because we can have different views on the same region, some
+of which are essentially the same view with different sugar type names.</p>
+
+<p>To canonicalize a region, we get the canonical types for all TypedViewRegions
+along the way up to the root region, and make new TypedViewRegions with those
+canonical types.</p>
+
+<p>For Objective-C and C++, perhaps another canonicalization rule should be
+added: for FieldRegion, the least derived class that has the field is used as
+the type of the super region of the FieldRegion.</p>
+
+<p>All bindings and retrievings are done on the canonicalized regions.</p>
+
+<p>Canonicalization is transparent outside the region store manager, and more
+specifically, unaware outside the Bind() and Retrieve() method. We don't need to
+consider region canonicalization when doing pointer cast.</p>
+
+<h3>Constraint Manager</h3>
+
+<p>The constraint manager reasons about the abstract location of memory objects.
+We can have different views on a region, but none of these views changes the
+location of that object. Thus we should get the same abstract location for those
+regions.</p>
+
+</body>
+</html>
diff --git a/docs/Block-ABI-Apple.txt b/docs/Block-ABI-Apple.txt
new file mode 100644
index 0000000..dd12036
--- /dev/null
+++ b/docs/Block-ABI-Apple.txt
@@ -0,0 +1,670 @@
+Block Implementation Specification
+
+Copyright 2008-2010 Apple, Inc.
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+0. History
+
+2008/7/14  - created
+2008/8/21  - revised, C++
+2008/9/24  - add NULL isa field to __block storage
+2008/10/1  - revise block layout to use a static descriptor structure
+2008/10/6  - revise block layout to use an unsigned long int flags
+2008/10/28 - specify use of _Block_object_assign/dispose for all "Object" types in helper functions
+2008/10/30 - revise new layout to have invoke function in same place
+2008/10/30 - add __weak support
+
+2010/3/16  - rev for stret return, signature field
+2010/4/6   - improved wording
+
+This document describes the Apple ABI implementation specification of Blocks.
+
+The first shipping version of this ABI is found in Mac OS X 10.6, and shall be referred to as 10.6.ABI. As of 2010/3/16, the following describes the ABI contract with the runtime and the compiler, and, as necessary, will be referred to as ABI.2010.3.16.
+
+Since the Apple ABI references symbols from other elements of the system, any attempt to use this ABI on systems prior to SnowLeopard is undefined.
+
+1. High Level
+
+The ABI of blocks consist of their layout and the runtime functions required by the compiler.
+A Block consists of a structure of the following form:
+
+struct Block_literal_1 {
+    void *isa; // initialized to &_NSConcreteStackBlock or &_NSConcreteGlobalBlock
+    int flags;
+    int reserved; 
+    void (*invoke)(void *, ...);
+    struct Block_descriptor_1 {
+	unsigned long int reserved;	// NULL
+    	unsigned long int size;         // sizeof(struct Block_literal_1)
+	// optional helper functions
+    	void (*copy_helper)(void *dst, void *src);     // IFF (1<<25)
+    	void (*dispose_helper)(void *src);             // IFF (1<<25)
+        // required ABI.2010.3.16
+        const char *signature;                         // IFF (1<<30)
+    } *descriptor;
+    // imported variables
+};
+
+The following flags bits are in use thusly for a possible ABI.2010.3.16:
+
+enum {
+    BLOCK_HAS_COPY_DISPOSE =  (1 << 25),
+    BLOCK_HAS_CTOR =          (1 << 26), // helpers have C++ code
+    BLOCK_IS_GLOBAL =         (1 << 28),
+    BLOCK_HAS_STRET =         (1 << 29),
+    BLOCK_HAS_SIGNATURE =     (1 << 30), 
+};
+
+In 10.6.ABI the (1<<29) was unconditionally set and ignored by the runtime - it was a transitional marker that did not get deleted after the transition. This bit is now paired with (1<<30), and represented as the pair (3<<30), for the following combinations of valid bit settings, and their meanings.
+
+switch (flags & (3<<29)) {
+  case (0<<29):  <unused>    , error
+  case (1<<29):      10.6.ABI, no signature field available
+  case (2<<29): ABI.2010.3.16, regular calling convention, presence of signature field
+  case (3<<29): ABI.2010.3.16, stret calling convention, presence of signature field,
+}
+
+The following discussions are presented as 10.6.ABI otherwise.
+
+Block literals may occur within functions where the structure is created in stack local memory.  They may also appear as initialization expressions for Block variables of global or static local variables.
+
+When a Block literal expression is evaluated the stack based structure is initialized as follows:
+
+1) static descriptor structure is declared and initialized as follows:
+1a) the invoke function pointer is set to a function that takes the Block structure as its first argument and the rest of the arguments (if any) to the Block and executes the Block compound statement.
+1b) the size field is set to the size of the following Block literal structure.
+1c) the copy_helper and dispose_helper function pointers are set to respective helper functions if they are required by the Block literal
+2) a stack (or global) Block literal data structure is created and initialized as follows:
+2a) the isa field is set to the address of the external _NSConcreteStackBlock, which is a block of uninitialized memory supplied in libSystem, or _NSConcreteGlobalBlock if this is a static or file level block literal.
+2) The flags field is set to zero unless there are variables imported into the block that need helper functions for program level Block_copy() and Block_release() operations, in which case the (1<<25) flags bit is set.
+
+
+As an example, the Block literal expression
+   ^ { printf("hello world\n"); }
+would cause to be created on a 32-bit system:
+
+struct __block_literal_1 {
+    void *isa;
+    int flags;
+    int reserved; 
+    void (*invoke)(struct __block_literal_1 *);
+    struct __block_descriptor_1 *descriptor;
+};
+
+void __block_invoke_1(struct __block_literal_1 *_block) {
+    printf("hello world\n");
+}
+
+static struct __block_descriptor_1 {
+    unsigned long int reserved;
+    unsigned long int Block_size;
+} __block_descriptor_1 = { 0, sizeof(struct __block_literal_1), __block_invoke_1 };
+
+and where the block literal appeared
+
+  struct __block_literal_1 _block_literal = {
+	&_NSConcreteStackBlock,
+	(1<<29), <uninitialized>,
+	__block_invoke_1,
+	&__block_descriptor_1
+   };
+
+Blocks import other Block references, const copies of other variables, and variables marked __block.  In Objective-C variables may additionally be objects.
+
+When a Block literal expression used as the initial value of a global or static local variable it is initialized as follows:
+  struct __block_literal_1 __block_literal_1 = {
+	&_NSConcreteGlobalBlock,
+	(1<<28)|(1<<29), <uninitialized>,
+	__block_invoke_1,
+	&__block_descriptor_1
+   };
+that is, a different address is provided as the first value and a particular (1<<28) bit is set in the flags field, and otherwise it is the same as for stack based Block literals.  This is an optimization that can be used for any Block literal that imports no const or __block storage variables.
+
+
+2. Imported Variables
+
+Variables of "auto" storage class are imported as const copies.  Variables of "__block" storage class are imported as a pointer to an enclosing data structure.  Global variables are simply referenced and not considered as imported.
+
+2.1 Imported const copy variables
+
+Automatic storage variables not marked with __block are imported as const copies.
+
+The simplest example is that of importing a variable of type int.
+
+   int x = 10;
+   void (^vv)(void) = ^{ printf("x is %d\n", x); }
+   x = 11;
+   vv();
+
+would be compiled
+
+struct __block_literal_2 {
+    void *isa;
+    int flags;
+    int reserved; 
+    void (*invoke)(struct __block_literal_2 *);
+    struct __block_descriptor_2 *descriptor;
+    const int x;
+};
+
+void __block_invoke_2(struct __block_literal_2 *_block) {
+    printf("x is %d\n", _block->x);
+}
+
+static struct __block_descriptor_2 {
+    unsigned long int reserved;
+    unsigned long int Block_size;
+} __block_descriptor_2 = { 0, sizeof(struct __block_literal_2) };
+
+and
+
+  struct __block_literal_2 __block_literal_2 = {
+	&_NSConcreteStackBlock,
+	(1<<29), <uninitialized>,
+	__block_invoke_2,
+	&__block_descriptor_2,
+        x
+   };
+
+In summary, scalars, structures, unions, and function pointers are generally imported as const copies with no need for helper functions.
+
+2.2 Imported const copy of Block reference
+
+The first case where copy and dispose helper functions are required is for the case of when a block itself is imported.  In this case both a copy_helper function and a dispose_helper function are needed.  The copy_helper function is passed both the existing stack based pointer and the pointer to the new heap version and should call back into the runtime to actually do the copy operation on the imported fields within the block.  The runtime functions are all described in Section 5.0 Runtime Helper Functions.
+
+An example:
+
+   void (^existingBlock)(void) = ...;
+   void (^vv)(void) = ^{ existingBlock(); }
+   vv();
+
+struct __block_literal_3 {
+   ...; // existing block
+};
+
+struct __block_literal_4 {
+    void *isa;
+    int flags;
+    int reserved; 
+    void (*invoke)(struct __block_literal_4 *);
+    struct __block_literal_3 *const existingBlock;
+};
+
+void __block_invoke_4(struct __block_literal_2 *_block) {
+   __block->existingBlock->invoke(__block->existingBlock);
+}
+
+void __block_copy_4(struct __block_literal_4 *dst, struct __block_literal_4 *src) {
+     //_Block_copy_assign(&dst->existingBlock, src->existingBlock, 0);
+     _Block_object_assign(&dst->existingBlock, src->existingBlock, BLOCK_FIELD_IS_BLOCK);
+}
+
+void __block_dispose_4(struct __block_literal_4 *src) {
+     // was _Block_destroy
+     _Block_object_dispose(src->existingBlock, BLOCK_FIELD_IS_BLOCK);
+}
+
+static struct __block_descriptor_4 {
+    unsigned long int reserved;
+    unsigned long int Block_size;
+    void (*copy_helper)(struct __block_literal_4 *dst, struct __block_literal_4 *src);
+    void (*dispose_helper)(struct __block_literal_4 *);
+} __block_descriptor_4 = {
+	0,
+	sizeof(struct __block_literal_4),
+	__block_copy_4,
+	__block_dispose_4,
+};
+
+and where it is used
+
+  struct __block_literal_4 _block_literal = {
+	&_NSConcreteStackBlock,
+	(1<<25)|(1<<29), <uninitialized>
+	__block_invoke_4,
+	& __block_descriptor_4
+        existingBlock,
+   };
+
+2.2.1 Importing __attribute__((NSObject)) variables.
+
+GCC introduces __attribute__((NSObject)) on structure pointers to mean "this is an object".  This is useful because many low level data structures are declared as opaque structure pointers, e.g. CFStringRef, CFArrayRef, etc.  When used from C, however, these are still really objects and are the second case where that requires copy and dispose helper functions to be generated.  The copy helper functions generated by the compiler should use the _Block_object_assign runtime helper function and in the dispose helper the _Block_object_dispose runtime helper function should be called.
+
+For example, block xyzzy in the following
+
+    struct Opaque *__attribute__((NSObject)) objectPointer = ...;
+    ...
+    void (^xyzzy)(void) = ^{  CFPrint(objectPointer); };
+
+would have helper functions
+
+void __block_copy_xyzzy(struct __block_literal_5 *dst, struct __block_literal_5 *src) {
+     _Block_object_assign(&dst->objectPointer, src-> objectPointer, BLOCK_FIELD_IS_OBJECT);
+}
+
+void __block_dispose_xyzzy(struct __block_literal_5 *src) {
+     _Block_object_dispose(src->objectPointer, BLOCK_FIELD_IS_OBJECT);
+}
+
+generated.
+
+
+2.3 Imported __block marked variables.
+
+2.3.1 Layout of __block marked variables
+
+The compiler must embed variables that are marked __block in a specialized structure of the form:
+
+struct _block_byref_xxxx {
+    void *isa;
+    struct Block_byref *forwarding;
+    int flags;   //refcount;
+    int size;
+    typeof(marked_variable) marked_variable;
+};
+
+Variables of certain types require helper functions for when Block_copy() and Block_release() are performed upon a referencing Block.  At the "C" level only variables that are of type Block or ones that have __attribute__((NSObject)) marked require helper functions.  In Objective-C objects require helper functions and in C++ stack based objects require helper functions. Variables that require helper functions use the form:
+
+struct _block_byref_xxxx {
+    void *isa;
+    struct _block_byref_xxxx *forwarding;
+    int flags;   //refcount;
+    int size;
+    // helper functions called via Block_copy() and Block_release()
+    void (*byref_keep)(void  *dst, void *src);
+    void (*byref_dispose)(void *);
+    typeof(marked_variable) marked_variable;
+};
+
+The structure is initialized such that
+ a) the forwarding pointer is set to the beginning of its enclosing structure,
+ b) the size field is initialized to the total size of the enclosing structure,
+ c) the flags field is set to either 0 if no helper functions are needed or (1<<25) if they are,
+ d) the helper functions are initialized (if present)
+ e) the variable itself is set to its initial value.
+ f) the isa field is set to NULL
+
+2.3.2 Access to __block variables from within its lexical scope.
+
+In order to "move" the variable to the heap upon a copy_helper operation the compiler must rewrite access to such a variable to be indirect through the structures forwarding pointer.  For example:
+
+  int __block i = 10;
+  i = 11;
+
+would be rewritten to be:
+
+  struct _block_byref_i {
+    void *isa;
+    struct _block_byref_i *forwarding;
+    int flags;   //refcount;
+    int size;
+    int captured_i;
+  } i = { NULL, &i, 0, sizeof(struct _block_byref_i), 11 };
+
+  i.forwarding->captured_i = 11;
+
+In the case of a Block reference variable being marked __block the helper code generated must use the _Block_object_assign and _Block_object_dispose routines supplied by the runtime to make the copies.  For example:
+
+   __block void (voidBlock)(void) = blockA;
+   voidBlock = blockB;
+
+would translate into
+
+struct _block_byref_voidBlock {
+    void *isa;
+    struct _block_byref_voidBlock *forwarding;
+    int flags;   //refcount;
+    int size;
+    void (*byref_keep)(struct _block_byref_voidBlock *dst, struct _block_byref_voidBlock *src);
+    void (*byref_dispose)(struct _block_byref_voidBlock *);
+    void (^captured_voidBlock)(void);
+};
+
+void _block_byref_keep_helper(struct _block_byref_voidBlock *dst, struct _block_byref_voidBlock *src) {
+    //_Block_copy_assign(&dst->captured_voidBlock, src->captured_voidBlock, 0);
+    _Block_object_assign(&dst->captured_voidBlock, src->captured_voidBlock, BLOCK_FIELD_IS_BLOCK | BLOCK_BYREF_CALLER);
+}
+
+void _block_byref_dispose_helper(struct _block_byref_voidBlock *param) {
+    //_Block_destroy(param->captured_voidBlock, 0);
+    _Block_object_dispose(param->captured_voidBlock, BLOCK_FIELD_IS_BLOCK | BLOCK_BYREF_CALLER)}
+
+and
+  struct _block_byref_voidBlock voidBlock = {( .forwarding=&voidBlock, .flags=(1<<25), .size=sizeof(struct _block_byref_voidBlock *),
+      .byref_keep=_block_byref_keep_helper, .byref_dispose=_block_byref_dispose_helper,
+      .captured_voidBlock=blockA };
+
+  voidBlock.forwarding->captured_voidBlock = blockB;
+  
+
+2.3.3 Importing __block variables into Blocks
+
+A Block that uses a __block variable in its compound statement body must import the variable and emit copy_helper and dispose_helper helper functions that, in turn, call back into the runtime to actually copy or release the byref data block using the functions _Block_object_assign and _Block_object_dispose.
+
+For example:
+
+   int __block i = 2;
+   functioncall(^{ i = 10; });
+
+would translate to
+
+struct _block_byref_i {
+    void *isa;  // set to NULL
+    struct _block_byref_voidBlock *forwarding;
+    int flags;   //refcount;
+    int size;
+    void (*byref_keep)(struct _block_byref_i *dst, struct _block_byref_i *src);
+    void (*byref_dispose)(struct _block_byref_i *);
+    int captured_i;
+};
+
+
+struct __block_literal_5 {
+    void *isa;
+    int flags;
+    int reserved; 
+    void (*invoke)(struct __block_literal_5 *);
+    struct __block_descriptor_5 *descriptor;
+    struct _block_byref_i *i_holder;
+};
+
+void __block_invoke_5(struct __block_literal_5 *_block) {
+   _block->forwarding->captured_i = 10;
+}
+
+void __block_copy_5(struct __block_literal_5 *dst, struct __block_literal_5 *src) {
+     //_Block_byref_assign_copy(&dst->captured_i, src->captured_i);
+     _Block_object_assign(&dst->captured_i, src->captured_i, BLOCK_FIELD_IS_BYREF | BLOCK_BYREF_CALLER);
+}
+
+void __block_dispose_5(struct __block_literal_5 *src) {
+     //_Block_byref_release(src->captured_i);
+     _Block_object_dispose(src->captured_i, BLOCK_FIELD_IS_BYREF | BLOCK_BYREF_CALLER);
+}
+
+static struct __block_descriptor_5 {
+    unsigned long int reserved;
+    unsigned long int Block_size;
+    void (*copy_helper)(struct __block_literal_5 *dst, struct __block_literal_5 *src);
+    void (*dispose_helper)(struct __block_literal_5 *);
+} __block_descriptor_5 = { 0, sizeof(struct __block_literal_5) __block_copy_5, __block_dispose_5 };
+
+and
+
+  struct _block_byref_i i = {( .forwarding=&i, .flags=0, .size=sizeof(struct _block_byref_i) )};
+  struct __block_literal_5 _block_literal = {
+	&_NSConcreteStackBlock,
+	(1<<25)|(1<<29), <uninitialized>,
+	__block_invoke_5,
+	&__block_descriptor_5,
+        2,
+   };
+
+2.3.4 Importing __attribute__((NSObject)) __block variables
+
+A __block variable that is also marked __attribute__((NSObject)) should have byref_keep and byref_dispose helper functions that use _Block_object_assign and _Block_object_dispose.
+
+2.3.5 __block escapes
+
+Because Blocks referencing __block variables may have Block_copy() performed upon them the underlying storage for the variables may move to the heap.  In Objective-C Garbage Collection Only compilation environments the heap used is the garbage collected one and no further action is required.  Otherwise the compiler must issue a call to potentially release any heap storage for __block variables at all escapes or terminations of their scope.
+
+
+2.3.6 Nesting
+
+Blocks may contain Block literal expressions.  Any variables used within inner blocks are imported into all enclosing Block scopes even if the variables are not used.  This includes const imports as well as __block variables.
+
+3. Objective C Extensions to Blocks
+
+3.1 Importing Objects
+
+Objects should be treated as __attribute__((NSObject)) variables; all copy_helper, dispose_helper, byref_keep, and byref_dispose helper functions should use _Block_object_assign and _Block_object_dispose.  There should be no code generated that uses -retain or -release methods.
+
+
+3.2 Blocks as Objects
+
+The compiler will treat Blocks as objects when synthesizing property setters and getters, will characterize them as objects when generating garbage collection strong and weak layout information in the same manner as objects, and will issue strong and weak write-barrier assignments in the same manner as objects.
+
+3.3 __weak __block Support
+
+Objective-C (and Objective-C++) support the __weak attribute on __block variables.  Under normal circumstances the compiler uses the Objective-C runtime helper support functions objc_assign_weak and objc_read_weak.  Both should continue to be used for all reads and writes of __weak __block variables:
+	objc_read_weak(&block->byref_i->forwarding->i)
+
+The __weak variable is stored in a _block_byref_xxxx structure and the Block has copy and dispose helpers for this structure that call:
+	_Block_object_assign(&dest->_block_byref_i, src-> _block_byref_i, BLOCK_FIELD_IS_WEAK | BLOCK_FIELD_IS_BYREF);
+and
+	_Block_object_dispose(src->_block_byref_i, BLOCK_FIELD_IS_WEAK | BLOCK_FIELD_IS_BYREF);
+
+
+In turn, the block_byref copy support helpers distinguish between whether the __block variable is a Block or not and should either call:
+	_Block_object_assign(&dest->_block_byref_i, src->_block_byref_i, BLOCK_FIELD_IS_WEAK | BLOCK_FIELD_IS_OBJECT | BLOCK_BYREF_CALLER);
+for something declared as an object or
+	_Block_object_assign(&dest->_block_byref_i, src->_block_byref_i, BLOCK_FIELD_IS_WEAK | BLOCK_FIELD_IS_BLOCK | BLOCK_BYREF_CALLER);
+for something declared as a Block.
+
+A full example follows:
+
+
+   __block __weak id obj = <initialization expression>;
+   functioncall(^{ [obj somemessage]; });
+
+would translate to
+
+struct _block_byref_obj {
+    void *isa;  // uninitialized
+    struct _block_byref_obj *forwarding;
+    int flags;   //refcount;
+    int size;
+    void (*byref_keep)(struct _block_byref_i *dst, struct _block_byref_i *src);
+    void (*byref_dispose)(struct _block_byref_i *);
+    int captured_obj;
+};
+
+void _block_byref_obj_keep(struct _block_byref_voidBlock *dst, struct _block_byref_voidBlock *src) {
+    //_Block_copy_assign(&dst->captured_obj, src->captured_obj, 0);
+    _Block_object_assign(&dst->captured_obj, src->captured_obj, BLOCK_FIELD_IS_OBJECT | BLOCK_FIELD_IS_WEAK | BLOCK_BYREF_CALLER);
+}
+
+void _block_byref_obj_dispose(struct _block_byref_voidBlock *param) {
+    //_Block_destroy(param->captured_obj, 0);
+    _Block_object_dispose(param->captured_obj, BLOCK_FIELD_IS_OBJECT | BLOCK_FIELD_IS_WEAK | BLOCK_BYREF_CALLER);
+};
+
+for the block byref part and
+
+struct __block_literal_5 {
+    void *isa;
+    int flags;
+    int reserved; 
+    void (*invoke)(struct __block_literal_5 *);
+    struct __block_descriptor_5 *descriptor;
+    struct _block_byref_obj *byref_obj;
+};
+
+void __block_invoke_5(struct __block_literal_5 *_block) {
+   [objc_read_weak(&_block->byref_obj->forwarding->captured_obj) somemessage];
+}
+
+void __block_copy_5(struct __block_literal_5 *dst, struct __block_literal_5 *src) {
+     //_Block_byref_assign_copy(&dst->byref_obj, src->byref_obj);
+     _Block_object_assign(&dst->byref_obj, src->byref_obj, BLOCK_FIELD_IS_BYREF | BLOCK_FIELD_IS_WEAK);
+}
+
+void __block_dispose_5(struct __block_literal_5 *src) {
+     //_Block_byref_release(src->byref_obj);
+     _Block_object_dispose(src->byref_obj, BLOCK_FIELD_IS_BYREF | BLOCK_FIELD_IS_WEAK);
+}
+
+static struct __block_descriptor_5 {
+    unsigned long int reserved;
+    unsigned long int Block_size;
+    void (*copy_helper)(struct __block_literal_5 *dst, struct __block_literal_5 *src);
+    void (*dispose_helper)(struct __block_literal_5 *);
+} __block_descriptor_5 = { 0, sizeof(struct __block_literal_5), __block_copy_5, __block_dispose_5 };
+
+and within the compound statement:
+
+  struct _block_byref_obj obj = {( .forwarding=&obj, .flags=(1<<25), .size=sizeof(struct _block_byref_obj),
+				.byref_keep=_block_byref_obj_keep, .byref_dispose=_block_byref_obj_dispose,
+				.captured_obj = <initialization expression> )};
+
+  struct __block_literal_5 _block_literal = {
+	&_NSConcreteStackBlock,
+	(1<<25)|(1<<29), <uninitialized>,
+	__block_invoke_5,
+	&__block_descriptor_5,
+        &obj,		// a reference to the on-stack structure containing "captured_obj"
+   };
+
+
+   functioncall(_block_literal->invoke(&_block_literal));
+
+
+4.0 C++ Support
+
+Within a block stack based C++ objects are copied as const copies using the const copy constructor.  It is an error if a stack based C++ object is used within a block if it does not have a const copy constructor.  In addition both copy and destroy helper routines must be synthesized for the block to support the Block_copy() operation, and the flags work marked with the (1<<26) bit in addition to the (1<<25) bit.  The copy helper should call the constructor using appropriate offsets of the variable within the supplied stack based block source and heap based destination for all const constructed copies, and similarly should call the destructor in the destroy routine.
+
+As an example, suppose a C++ class FOO existed with a const copy constructor.  Within a code block a stack version of a FOO object is declared and used within a Block literal expression:
+
+{
+    FOO foo;
+    void (^block)(void) = ^{ printf("%d\n", foo.value()); };
+}
+
+The compiler would synthesize
+
+struct __block_literal_10 {
+    void *isa;
+    int flags;
+    int reserved; 
+    void (*invoke)(struct __block_literal_10 *);
+    struct __block_descriptor_10 *descriptor;
+    const FOO foo;
+};
+
+void __block_invoke_10(struct __block_literal_10 *_block) {
+   printf("%d\n", _block->foo.value());
+}
+
+void __block_literal_10(struct __block_literal_10 *dst, struct __block_literal_10 *src) {
+     comp_ctor(&dst->foo, &src->foo);
+}
+
+void __block_dispose_10(struct __block_literal_10 *src) {
+     comp_dtor(&src->foo);
+}
+
+static struct __block_descriptor_10 {
+    unsigned long int reserved;
+    unsigned long int Block_size;
+    void (*copy_helper)(struct __block_literal_10 *dst, struct __block_literal_10 *src);
+    void (*dispose_helper)(struct __block_literal_10 *);
+} __block_descriptor_10 = { 0, sizeof(struct __block_literal_10), __block_copy_10, __block_dispose_10 };
+
+and the code would be:
+{
+  FOO foo;
+  comp_ctor(&foo); // default constructor
+  struct __block_literal_10 _block_literal = {
+	&_NSConcreteStackBlock,
+	(1<<25)|(1<<26)|(1<<29), <uninitialized>,
+	__block_invoke_10,
+	&__block_descriptor_10,
+   };
+   comp_ctor(&_block_literal->foo, &foo);  // const copy into stack version
+   struct __block_literal_10 &block = &_block_literal;  // assign literal to block variable
+   block->invoke(block);	// invoke block
+   comp_dtor(&_block_literal->foo); // destroy stack version of const block copy
+   comp_dtor(&foo); // destroy original version
+}
+
+
+C++ objects stored in __block storage start out on the stack in a block_byref data structure as do other variables.  Such objects (if not const objects) must support a regular copy constructor.  The block_byref data structure will have copy and destroy helper routines synthesized by the compiler.  The copy helper will have code created to perform the copy constructor based on the initial stack block_byref data structure, and will also set the (1<<26) bit in addition to the (1<<25) bit.  The destroy helper will have code to do the destructor on the object stored within the supplied block_byref heap data structure.
+
+To support member variable and function access the compiler will synthesize a const pointer to a block version of the this pointer.
+
+5.0 Runtime Helper Functions
+
+The runtime helper functions are described in /usr/local/include/Block_private.h.  To summarize their use, a block requires copy/dispose helpers if it imports any block variables, __block storage variables, __attribute__((NSObject)) variables, or C++ const copied objects with constructor/destructors.  The (1<<26) bit is set and functions are generated.
+
+The block copy helper function should, for each of the variables of the type mentioned above, call
+     _Block_object_assign(&dst->target, src->target, BLOCK_FIELD_<appropo>);
+in the copy helper and
+    _Block_object_dispose(->target, BLOCK_FIELD_<appropo>);
+in the dispose helper where
+      <appropo> is
+
+enum {
+    BLOCK_FIELD_IS_OBJECT   =  3,  // id, NSObject, __attribute__((NSObject)), block, ...
+    BLOCK_FIELD_IS_BLOCK    =  7,  // a block variable
+    BLOCK_FIELD_IS_BYREF    =  8,  // the on stack structure holding the __block variable
+
+    BLOCK_FIELD_IS_WEAK     = 16,  // declared __weak
+
+    BLOCK_BYREF_CALLER      = 128, // called from byref copy/dispose helpers
+};
+
+and of course the CTORs/DTORs for const copied C++ objects.
+
+The block_byref data structure similarly requires copy/dispose helpers for block variables, __attribute__((NSObject)) variables, or C++ const copied objects with constructor/destructors, and again the (1<<26) bit is set and functions are generated in the same manner.
+
+Under ObjC we allow __weak as an attribute on __block variables, and this causes the addition of BLOCK_FIELD_IS_WEAK orred onto the BLOCK_FIELD_IS_BYREF flag when copying the block_byref structure in the block copy helper, and onto the BLOCK_FIELD_<appropo> field within the block_byref copy/dispose helper calls.
+
+The prototypes, and summary, of the helper functions are
+
+/* Certain field types require runtime assistance when being copied to the heap.  The following function is used
+   to copy fields of types: blocks, pointers to byref structures, and objects (including __attribute__((NSObject)) pointers.
+   BLOCK_FIELD_IS_WEAK is orthogonal to the other choices which are mutually exclusive.
+   Only in a Block copy helper will one see BLOCK_FIELD_IS_BYREF.
+ */
+void _Block_object_assign(void *destAddr, const void *object, const int flags);
+
+/* Similarly a compiler generated dispose helper needs to call back for each field of the byref data structure.
+   (Currently the implementation only packs one field into the byref structure but in principle there could be more).
+   The same flags used in the copy helper should be used for each call generated to this function:
+ */
+void _Block_object_dispose(const void *object, const int flags);
+
+The following functions have been used and will continue to be supported until new compiler support is complete.
+
+// Obsolete functions.
+// Copy helper callback for copying a block imported into a Block
+// Called by copy_helper helper functions synthesized by the compiler.
+// The address in the destination block of an imported Block is provided as the first argument
+// and the value of the existing imported Block is the second.
+// Use: _Block_object_assign(dest, src, BLOCK_FIELD_IS_BLOCK {| BLOCK_FIELD_IS_WEAK});
+void _Block_copy_assign(struct Block_basic **dest, const struct Block_basic *src, const int flags);
+
+// Destroy helper callback for releasing Blocks imported into a Block
+// Called by dispose_helper helper functions synthesized by the compiler.
+// The value of the imported Block variable is passed back.
+// Use: _Block_object_dispose(src, BLOCK_FIELD_IS_BLOCK {| BLOCK_FIELD_IS_WEAK});
+void _Block_destroy(const struct Block_basic *src, const int flags);
+
+// Byref data block copy helper callback
+// Called by block copy helpers when copying __block structures
+// Use: _Block_object_assign(dest, src, BLOCK_FIELD_IS_BYREF {| BLOCK_FIELD_IS_WEAK});
+void _Block_byref_assign_copy(struct Block_byref **destp, struct Block_byref *src);
+
+// Byref data block release helper callback
+// Called by block release helpers when releasing a Block 
+// Called at escape points in scope where __block variables live (under non-GC-only conditions) 
+// Use: _Block_object_dispose(src, BLOCK_FIELD_IS_BYREF {| BLOCK_FIELD_IS_WEAK});
+void §(struct Block_byref *shared_struct);
+
+
diff --git a/docs/BlockLanguageSpec.txt b/docs/BlockLanguageSpec.txt
new file mode 100644
index 0000000..a612fd2
--- /dev/null
+++ b/docs/BlockLanguageSpec.txt
@@ -0,0 +1,165 @@
+Language Specification for Blocks
+
+2008/2/25 — created
+2008/7/28 — revised, __block syntax
+2008/8/13 — revised, Block globals
+2008/8/21 — revised, C++ elaboration
+2008/11/1 — revised, __weak support
+2009/1/12 — revised, explicit return types
+2009/2/10 — revised, __block objects need retain
+
+Copyright 2008-2009 Apple, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+The Block Type
+
+A new derived type is introduced to C and, by extension, Objective-C, C++, and Objective-C++. Like function types, the Block type is a pair consisting of a result value type and a list of parameter types very similar to a function type. Blocks are intended to be used much like functions with the key distinction being that in addition to executable code they also contain various variable bindings to automatic (stack) or managed (heap) memory.
+
+The abstract declarator int (^)(char, float) describes a reference to a Block that, when invoked, takes two parameters, the first of type char and the second of type float, and returns a value of type int.  The Block referenced is of opaque data that may reside in automatic (stack) memory, global memory, or heap memory.
+
+
+Block Variable Declarations
+
+A variable with Block type is declared using function pointer style notation substituting ^ for *. The following are valid Block variable declarations:
+    void (^blockReturningVoidWithVoidArgument)(void);
+    int (^blockReturningIntWithIntAndCharArguments)(int, char);
+    void (^arrayOfTenBlocksReturningVoidWithIntArgument[10])(int);
+
+Variadic ... arguments are supported. [variadic.c]  A Block that takes no arguments must specify void in the argument list [voidarg.c].  An empty parameter list does not represent, as K&R provide, an unspecified argument list.  Note: both gcc and clang support K&R style as a convenience.
+
+A Block reference may be cast to a pointer of arbitrary type and vice versa. [cast.c]  A Block reference may not be dereferenced via the pointer dereference operator *, and thus a Block's size may not be computed at compile time. [sizeof.c]
+
+
+Block Literal Expressions
+
+A Block literal expression produces a reference to a Block. It is introduced by the use of the ^ token as a unary operator.  
+    Block_literal_expression ::=   ^ block_decl compound_statement_body
+    block_decl ::= 
+    block_decl ::= parameter_list
+    block_decl ::= type_expression
+
+...where type expression is extended to allow ^ as a Block reference (pointer) where * is allowed as a function reference (pointer).
+
+The following Block literal:
+    ^ void (void) { printf("hello world\n"); }
+
+...produces a reference to a Block with no arguments with no return value.
+
+The return type is optional and is inferred from the return statements. If the return statements return a value, they all must return a value of the same type. If there is no value returned the inferred type of the Block is void; otherwise it is the type of the return statement value.
+
+If the return type is omitted and the argument list is ( void ), the ( void ) argument list may also be omitted.
+
+So:
+    ^ ( void ) { printf("hello world\n"); }
+
+...and:
+    ^ { printf("hello world\n"); }
+
+...are exactly equivalent constructs for the same expression.
+
+The type_expression extends C expression parsing to accommodate Block reference declarations as it accommodates function pointer declarations.
+
+Given:
+    typedef int (*pointerToFunctionThatReturnsIntWithCharArg)(char);
+    pointerToFunctionThatReturnsIntWithCharArg functionPointer;
+
+    ^ pointerToFunctionThatReturnsIntWithCharArg (float x) { return functionPointer; }
+
+...and:
+    ^ int ((*)(float x))(char) { return functionPointer; }
+
+...are equivalent expressions, as is:
+
+    ^(float x) { return functionPointer; }
+
+[returnfunctionptr.c]
+
+The compound statement body establishes a new lexical scope within that of its parent. Variables used within the scope of the compound statement are bound to the Block in the normal manner with the exception of those in automatic (stack) storage. Thus one may access functions and global variables as one would expect, as well as static local variables. [testme]
+
+Local automatic (stack) variables referenced within the compound statement of a Block are imported and captured by the Block as const copies. The capture (binding) is performed at the time of the Block literal expression evaluation.
+
+The lifetime of variables declared in a Block is that of a function; each activation frame contains a new copy of variables declared within the local scope of the Block. Such variable declarations should be allowed anywhere [testme] rather than only when C99 parsing is requested, including for statements. [testme]
+
+Block literal expressions may occur within Block literal expressions (nest) and all variables captured by any nested blocks are implicitly also captured in the scopes of their enclosing Blocks.
+
+A Block literal expression may be used as the initialization value for Block variables at global or local static scope.
+
+
+The Invoke Operator
+
+Blocks are invoked using function call syntax with a list of expression parameters of types corresponding to the declaration and returning a result type also according to the declaration. Given:
+    int (^x)(char);
+    void (^z)(void);
+    int (^(*y))(char) = &x;
+
+...the following are all legal Block invocations:
+    x('a');
+    (*y)('a');
+    (true ? x : *y)('a')
+
+
+The Copy and Release Operations
+
+The compiler and runtime provide copy and release operations for Block references that create and, in matched use, release allocated storage for referenced Blocks.
+
+The copy operation Block_copy() is styled as a function that takes an arbitrary Block reference and returns a Block reference of the same type. The release operation, Block_release(), is styled as a function that takes an arbitrary Block reference and, if dynamically matched to a Block copy operation, allows recovery of the referenced allocated memory.
+
+
+The __block Storage Qualifier
+
+In addition to the new Block type we also introduce a new storage qualifier, __block, for local variables. [testme: a __block declaration within a block literal]  The __block storage qualifier is mutually exclusive to the existing local storage qualifiers auto, register, and static.[testme]  Variables qualified by __block act as if they were in allocated storage and this storage is automatically recovered after last use of said variable.  An implementation may choose an optimization where the storage is initially automatic and only "moved" to allocated (heap) storage upon a Block_copy of a referencing Block.  Such variables may be mutated as normal variables are.
+
+In the case where a __block variable is a Block one must assume that the __block variable resides in allocated storage and as such is assumed to reference a Block that is also in allocated storage (that it is the result of a Block_copy operation).  Despite this there is no provision to do a Block_copy or a Block_release if an implementation provides initial automatic storage for Blocks.  This is due to the inherent race condition of potentially several threads trying to update the shared variable and the need for synchronization around disposing of older values and copying new ones.  Such synchronization is beyond the scope of this language specification.
+
+
+Control Flow
+
+The compound statement of a Block is treated much like a function body with respect to control flow in that goto, break, and continue do not escape the Block.  Exceptions are treated "normally" in that when thrown they pop stack frames until a catch clause is found.
+
+
+Objective-C Extensions
+
+Objective-C extends the definition of a Block reference type to be that also of id.  A variable or expression of Block type may be messaged or used as a parameter wherever an id may be. The converse is also true. Block references may thus appear as properties and are subject to the assign, retain, and copy attribute logic that is reserved for objects.
+
+All Blocks are constructed to be Objective-C objects regardless of whether the Objective-C runtime is operational in the program or not. Blocks using automatic (stack) memory are objects and may be messaged, although they may not be assigned into __weak locations if garbage collection is enabled.
+
+Within a Block literal expression within a method definition references to instance variables are also imported into the lexical scope of the compound statement. These variables are implicitly qualified as references from self, and so self is imported as a const copy. The net effect is that  instance variables can be mutated.
+
+The Block_copy operator retains all objects held in variables of automatic storage referenced within the Block expression (or form strong references if running under garbage collection).  Object variables of __block storage type are assumed to hold normal pointers with no provision for retain and release messages.
+
+Foundation defines (and supplies) -copy and -release methods for Blocks.
+
+In the Objective-C and Objective-C++ languages, we allow the __weak specifier for __block variables of object type.  If garbage collection is not enabled, this qualifier causes these variables to be kept without retain messages being sent. This knowingly leads to dangling pointers if the Block (or a copy) outlives the lifetime of this object.
+
+In garbage collected environments, the __weak variable is set to nil when the object it references is collected, as long as the __block variable resides in the heap (either by default or via Block_copy()).  The initial Apple implementation does in fact start __block variables on the stack and migrate them to the heap only as a result of a Block_copy() operation.
+
+It is a runtime error to attempt to assign a reference to a stack-based Block into any storage marked __weak, including __weak __block variables.
+
+
+C++ Extensions
+
+Block literal expressions within functions are extended to allow const use of C++ objects, pointers, or references held in automatic storage.
+
+For example, given class Foo with member function fighter(void):
+      Foo foo;
+      Foo &fooRef = foo;
+      Foo *fooPtr = &foo;
+
+...a Block that used foo would import the variables as const variations:
+       const Foo block_foo = foo;	// const copy constructor
+       const Foo &block_fooRef = fooRef;
+       const Foo *block_fooPtr = fooPtr;
+
+Stack-local objects are copied into a Block via a copy const constructor.  If no such constructor exists, it is considered an error to reference such objects from within the Block compound statements. A destructor is run as control leaves the compound statement that contains the Block literal expression.
+
+If a Block originates on the stack, a const copy constructor of the stack-based Block const copy is performed when a Block_copy operation is called; when the last Block_release (or subsequently GC) occurs, a destructor is run on the heap copy.
+
+Variables declared as residing in __block storage may be initially allocated in the heap or may first appear on the stack and be copied to the heap as a result of a Block_copy() operation. When copied from the stack, a normal copy constructor is used to initialize the heap-based version from the original stack version. The destructor for a const copied object is run at the normal end of scope. The destructor for any initial stack based version is also called at normal end of scope.
+
+Within a member function, access to member functions and variables is done via an implicit const copy of a this pointer.
+
+Member variables that are Blocks may not be overloaded by the types of their arguments.
+
diff --git a/docs/DriverArchitecture.png b/docs/DriverArchitecture.png
new file mode 100644
index 0000000..056a70a
--- /dev/null
+++ b/docs/DriverArchitecture.png
Binary files differ
diff --git a/docs/DriverInternals.html b/docs/DriverInternals.html
new file mode 100644
index 0000000..a7d2da3
--- /dev/null
+++ b/docs/DriverInternals.html
@@ -0,0 +1,517 @@
+<html>
+  <head>
+    <title>Clang Driver Manual</title>
+    <link type="text/css" rel="stylesheet" href="../menu.css" />
+    <link type="text/css" rel="stylesheet" href="../content.css" />
+    <style type="text/css">
+      td {
+      vertical-align: top;
+      }
+    </style>
+  </head>
+  <body>
+
+    <!--#include virtual="../menu.html.incl"-->
+
+    <div id="content">
+
+      <h1>Driver Design &amp; Internals</h1>
+
+      <ul>
+        <li><a href="#intro">Introduction</a></li>
+        <li><a href="#features">Features and Goals</a></li>
+        <ul>
+          <li><a href="#gcccompat">GCC Compatibility</a></li>
+          <li><a href="#components">Flexible</a></li>
+          <li><a href="#performance">Low Overhead</a></li>
+          <li><a href="#simple">Simple</a></li>
+        </ul>
+        <li><a href="#design">Design</a></li>
+        <ul>
+          <li><a href="#int_intro">Internals Introduction</a></li>
+          <li><a href="#int_overview">Design Overview</a></li>
+          <li><a href="#int_notes">Additional Notes</a></li>
+          <ul>
+            <li><a href="#int_compilation">The Compilation Object</a></li>
+            <li><a href="#int_unified_parsing">Unified Parsing &amp; Pipelining</a></li>
+            <li><a href="#int_toolchain_translation">ToolChain Argument Translation</a></li>
+            <li><a href="#int_unused_warnings">Unused Argument Warnings</a></li>
+          </ul>
+          <li><a href="#int_gcc_concepts">Relation to GCC Driver Concepts</a></li>
+        </ul>
+      </ul>
+
+
+      <!-- ======================================================================= -->
+      <h2 id="intro">Introduction</h2>
+      <!-- ======================================================================= -->
+
+      <p>This document describes the Clang driver. The purpose of this
+        document is to describe both the motivation and design goals
+        for the driver, as well as details of the internal
+        implementation.</p>
+
+      <!-- ======================================================================= -->
+      <h2 id="features">Features and Goals</h2>
+      <!-- ======================================================================= -->
+
+      <p>The Clang driver is intended to be a production quality
+        compiler driver providing access to the Clang compiler and
+        tools, with a command line interface which is compatible with
+        the gcc driver.</p>
+
+      <p>Although the driver is part of and driven by the Clang
+        project, it is logically a separate tool which shares many of
+        the same goals as Clang:</p>
+
+      <p><b>Features</b>:</p>
+      <ul>
+        <li><a href="#gcccompat">GCC Compatibility</a></li>
+        <li><a href="#components">Flexible</a></li>
+        <li><a href="#performance">Low Overhead</a></li>
+        <li><a href="#simple">Simple</a></li>
+      </ul>
+
+      <!--=======================================================================-->
+      <h3 id="gcccompat">GCC Compatibility</h3>
+      <!--=======================================================================-->
+
+      <p>The number one goal of the driver is to ease the adoption of
+        Clang by allowing users to drop Clang into a build system
+        which was designed to call GCC. Although this makes the driver
+        much more complicated than might otherwise be necessary, we
+        decided that being very compatible with the gcc command line
+        interface was worth it in order to allow users to quickly test
+        clang on their projects.</p>
+
+      <!--=======================================================================-->
+      <h3 id="components">Flexible</h3>
+      <!--=======================================================================-->
+
+      <p>The driver was designed to be flexible and easily accomodate
+        new uses as we grow the clang and LLVM infrastructure. As one
+        example, the driver can easily support the introduction of
+        tools which have an integrated assembler; something we hope to
+        add to LLVM in the future.</p>
+
+      <p>Similarly, most of the driver functionality is kept in a
+        library which can be used to build other tools which want to
+        implement or accept a gcc like interface. </p>
+
+      <!--=======================================================================-->
+      <h3 id="performance">Low Overhead</h3>
+      <!--=======================================================================-->
+
+      <p>The driver should have as little overhead as possible. In
+        practice, we found that the gcc driver by itself incurred a
+        small but meaningful overhead when compiling many small
+        files. The driver doesn't do much work compared to a
+        compilation, but we have tried to keep it as efficient as
+        possible by following a few simple principles:</p>
+      <ul>
+        <li>Avoid memory allocation and string copying when
+          possible.</li>
+
+        <li>Don't parse arguments more than once.</li>
+
+        <li>Provide a few simple interfaces for efficiently searching
+          arguments.</li>
+      </ul>
+
+      <!--=======================================================================-->
+      <h3 id="simple">Simple</h3>
+      <!--=======================================================================-->
+
+      <p>Finally, the driver was designed to be "as simple as
+        possible", given the other goals. Notably, trying to be
+        completely compatible with the gcc driver adds a significant
+        amount of complexity. However, the design of the driver
+        attempts to mitigate this complexity by dividing the process
+        into a number of independent stages instead of a single
+        monolithic task.</p>
+
+      <!-- ======================================================================= -->
+      <h2 id="design">Internal Design and Implementation</h2>
+      <!-- ======================================================================= -->
+
+      <ul>
+        <li><a href="#int_intro">Internals Introduction</a></li>
+        <li><a href="#int_overview">Design Overview</a></li>
+        <li><a href="#int_notes">Additional Notes</a></li>
+        <li><a href="#int_gcc_concepts">Relation to GCC Driver Concepts</a></li>
+      </ul>
+
+      <!--=======================================================================-->
+      <h3><a name="int_intro">Internals Introduction</a></h3>
+      <!--=======================================================================-->
+
+      <p>In order to satisfy the stated goals, the driver was designed
+        to completely subsume the functionality of the gcc executable;
+        that is, the driver should not need to delegate to gcc to
+        perform subtasks. On Darwin, this implies that the Clang
+        driver also subsumes the gcc driver-driver, which is used to
+        implement support for building universal images (binaries and
+        object files). This also implies that the driver should be
+        able to call the language specific compilers (e.g. cc1)
+        directly, which means that it must have enough information to
+        forward command line arguments to child processes
+        correctly.</p>
+
+      <!--=======================================================================-->
+      <h3><a name="int_overview">Design Overview</a></h3>
+      <!--=======================================================================-->
+
+      <p>The diagram below shows the significant components of the
+        driver architecture and how they relate to one another. The
+        orange components represent concrete data structures built by
+        the driver, the green components indicate conceptually
+        distinct stages which manipulate these data structures, and
+        the blue components are important helper classes. </p>
+
+      <center>
+        <a href="DriverArchitecture.png" alt="Driver Architecture Diagram">
+          <img width=400 src="DriverArchitecture.png">
+        </a>
+      </center>
+
+      <!--=======================================================================-->
+      <h3><a name="int_stages">Driver Stages</a></h3>
+      <!--=======================================================================-->
+
+      <p>The driver functionality is conceptually divided into five stages:</p>
+
+      <ol>
+        <li>
+          <b>Parse: Option Parsing</b>
+
+          <p>The command line argument strings are decomposed into
+            arguments (<tt>Arg</tt> instances). The driver expects to
+            understand all available options, although there is some
+            facility for just passing certain classes of options
+            through (like <tt>-Wl,</tt>).</p>
+
+          <p>Each argument corresponds to exactly one
+            abstract <tt>Option</tt> definition, which describes how
+            the option is parsed along with some additional
+            metadata. The Arg instances themselves are lightweight and
+            merely contain enough information for clients to determine
+            which option they correspond to and their values (if they
+            have additional parameters).</p>
+
+          <p>For example, a command line like "-Ifoo -I foo" would
+            parse to two Arg instances (a JoinedArg and a SeparateArg
+            instance), but each would refer to the same Option.</p>
+
+          <p>Options are lazily created in order to avoid populating
+            all Option classes when the driver is loaded. Most of the
+            driver code only needs to deal with options by their
+            unique ID (e.g., <tt>options::OPT_I</tt>),</p>
+
+          <p>Arg instances themselves do not generally store the
+            values of parameters. In many cases, this would
+            simply result in creating unnecessary string
+            copies. Instead, Arg instances are always embedded inside
+            an ArgList structure, which contains the original vector
+            of argument strings. Each Arg itself only needs to contain
+            an index into this vector instead of storing its values
+            directly.</p>
+
+          <p>The clang driver can dump the results of this
+            stage using the <tt>-ccc-print-options</tt> flag (which
+            must preceed any actual command line arguments). For
+            example:</p>
+          <pre>
+            $ <b>clang -ccc-print-options -Xarch_i386 -fomit-frame-pointer -Wa,-fast -Ifoo -I foo t.c</b>
+            Option 0 - Name: "-Xarch_", Values: {"i386", "-fomit-frame-pointer"}
+            Option 1 - Name: "-Wa,", Values: {"-fast"}
+            Option 2 - Name: "-I", Values: {"foo"}
+            Option 3 - Name: "-I", Values: {"foo"}
+            Option 4 - Name: "&lt;input&gt;", Values: {"t.c"}
+          </pre>
+
+          <p>After this stage is complete the command line should be
+            broken down into well defined option objects with their
+            appropriate parameters.  Subsequent stages should rarely,
+            if ever, need to do any string processing.</p>
+        </li>
+
+        <li>
+          <b>Pipeline: Compilation Job Construction</b>
+
+          <p>Once the arguments are parsed, the tree of subprocess
+            jobs needed for the desired compilation sequence are
+            constructed. This involves determining the input files and
+            their types, what work is to be done on them (preprocess,
+            compile, assemble, link, etc.), and constructing a list of
+            Action instances for each task. The result is a list of
+            one or more top-level actions, each of which generally
+            corresponds to a single output (for example, an object or
+            linked executable).</p>
+
+          <p>The majority of Actions correspond to actual tasks,
+            however there are two special Actions. The first is
+            InputAction, which simply serves to adapt an input
+            argument for use as an input to other Actions. The second
+            is BindArchAction, which conceptually alters the
+            architecture to be used for all of its input Actions.</p>
+
+          <p>The clang driver can dump the results of this
+            stage using the <tt>-ccc-print-phases</tt> flag. For
+            example:</p>
+          <pre>
+            $ <b>clang -ccc-print-phases -x c t.c -x assembler t.s</b>
+            0: input, "t.c", c
+            1: preprocessor, {0}, cpp-output
+            2: compiler, {1}, assembler
+            3: assembler, {2}, object
+            4: input, "t.s", assembler
+            5: assembler, {4}, object
+            6: linker, {3, 5}, image
+          </pre>
+          <p>Here the driver is constructing seven distinct actions,
+            four to compile the "t.c" input into an object file, two to
+            assemble the "t.s" input, and one to link them together.</p>
+
+          <p>A rather different compilation pipeline is shown here; in
+            this example there are two top level actions to compile
+            the input files into two separate object files, where each
+            object file is built using <tt>lipo</tt> to merge results
+            built for two separate architectures.</p>
+          <pre>
+            $ <b>clang -ccc-print-phases -c -arch i386 -arch x86_64 t0.c t1.c</b>
+            0: input, "t0.c", c
+            1: preprocessor, {0}, cpp-output
+            2: compiler, {1}, assembler
+            3: assembler, {2}, object
+            4: bind-arch, "i386", {3}, object
+            5: bind-arch, "x86_64", {3}, object
+            6: lipo, {4, 5}, object
+            7: input, "t1.c", c
+            8: preprocessor, {7}, cpp-output
+            9: compiler, {8}, assembler
+            10: assembler, {9}, object
+            11: bind-arch, "i386", {10}, object
+            12: bind-arch, "x86_64", {10}, object
+            13: lipo, {11, 12}, object
+          </pre>
+
+          <p>After this stage is complete the compilation process is
+            divided into a simple set of actions which need to be
+            performed to produce intermediate or final outputs (in
+            some cases, like <tt>-fsyntax-only</tt>, there is no
+            "real" final output). Phases are well known compilation
+            steps, such as "preprocess", "compile", "assemble",
+            "link", etc.</p>
+        </li>
+
+        <li>
+          <b>Bind: Tool &amp; Filename Selection</b>
+
+          <p>This stage (in conjunction with the Translate stage)
+            turns the tree of Actions into a list of actual subprocess
+            to run. Conceptually, the driver performs a top down
+            matching to assign Action(s) to Tools. The ToolChain is
+            responsible for selecting the tool to perform a particular
+            action; once selected the driver interacts with the tool
+            to see if it can match additional actions (for example, by
+            having an integrated preprocessor).
+
+          <p>Once Tools have been selected for all actions, the driver
+            determines how the tools should be connected (for example,
+            using an inprocess module, pipes, temporary files, or user
+            provided filenames). If an output file is required, the
+            driver also computes the appropriate file name (the suffix
+            and file location depend on the input types and options
+            such as <tt>-save-temps</tt>).
+
+          <p>The driver interacts with a ToolChain to perform the Tool
+            bindings. Each ToolChain contains information about all
+            the tools needed for compilation for a particular
+            architecture, platform, and operating system. A single
+            driver invocation may query multiple ToolChains during one
+            compilation in order to interact with tools for separate
+            architectures.</p>
+
+          <p>The results of this stage are not computed directly, but
+            the driver can print the results via
+            the <tt>-ccc-print-bindings</tt> option. For example:</p>
+          <pre>
+            $ <b>clang -ccc-print-bindings -arch i386 -arch ppc t0.c</b>
+            # "i386-apple-darwin9" - "clang", inputs: ["t0.c"], output: "/tmp/cc-Sn4RKF.s"
+            # "i386-apple-darwin9" - "darwin::Assemble", inputs: ["/tmp/cc-Sn4RKF.s"], output: "/tmp/cc-gvSnbS.o"
+            # "i386-apple-darwin9" - "darwin::Link", inputs: ["/tmp/cc-gvSnbS.o"], output: "/tmp/cc-jgHQxi.out"
+            # "ppc-apple-darwin9" - "gcc::Compile", inputs: ["t0.c"], output: "/tmp/cc-Q0bTox.s"
+            # "ppc-apple-darwin9" - "gcc::Assemble", inputs: ["/tmp/cc-Q0bTox.s"], output: "/tmp/cc-WCdicw.o"
+            # "ppc-apple-darwin9" - "gcc::Link", inputs: ["/tmp/cc-WCdicw.o"], output: "/tmp/cc-HHBEBh.out"
+            # "i386-apple-darwin9" - "darwin::Lipo", inputs: ["/tmp/cc-jgHQxi.out", "/tmp/cc-HHBEBh.out"], output: "a.out"
+          </pre>
+
+          <p>This shows the tool chain, tool, inputs and outputs which
+            have been bound for this compilation sequence. Here clang
+            is being used to compile t0.c on the i386 architecture and
+            darwin specific versions of the tools are being used to
+            assemble and link the result, but generic gcc versions of
+            the tools are being used on PowerPC.</p>
+        </li>
+
+        <li>
+          <b>Translate: Tool Specific Argument Translation</b>
+
+          <p>Once a Tool has been selected to perform a particular
+            Action, the Tool must construct concrete Jobs which will be
+            executed during compilation. The main work is in translating
+            from the gcc style command line options to whatever options
+            the subprocess expects.</p>
+
+          <p>Some tools, such as the assembler, only interact with a
+            handful of arguments and just determine the path of the
+            executable to call and pass on their input and output
+            arguments. Others, like the compiler or the linker, may
+            translate a large number of arguments in addition.</p>
+
+          <p>The ArgList class provides a number of simple helper
+            methods to assist with translating arguments; for example,
+            to pass on only the last of arguments corresponding to some
+            option, or all arguments for an option.</p>
+
+          <p>The result of this stage is a list of Jobs (executable
+            paths and argument strings) to execute.</p>
+        </li>
+
+        <li>
+          <b>Execute</b>
+          <p>Finally, the compilation pipeline is executed. This is
+            mostly straightforward, although there is some interaction
+            with options
+            like <tt>-pipe</tt>, <tt>-pass-exit-codes</tt>
+            and <tt>-time</tt>.</p>
+        </li>
+
+      </ol>
+
+      <!--=======================================================================-->
+      <h3><a name="int_notes">Additional Notes</a></h3>
+      <!--=======================================================================-->
+
+      <h4 id="int_compilation">The Compilation Object</h4>
+
+      <p>The driver constructs a Compilation object for each set of
+        command line arguments. The Driver itself is intended to be
+        invariant during construction of a Compilation; an IDE should be
+        able to construct a single long lived driver instance to use
+        for an entire build, for example.</p>
+
+      <p>The Compilation object holds information that is particular
+        to each compilation sequence. For example, the list of used
+        temporary files (which must be removed once compilation is
+        finished) and result files (which should be removed if
+        compilation files).</p>
+
+      <h4 id="int_unified_parsing">Unified Parsing &amp; Pipelining</h4>
+
+      <p>Parsing and pipelining both occur without reference to a
+        Compilation instance. This is by design; the driver expects that
+        both of these phases are platform neutral, with a few very well
+        defined exceptions such as whether the platform uses a driver
+        driver.</p>
+
+      <h4 id="int_toolchain_translation">ToolChain Argument Translation</h4>
+
+      <p>In order to match gcc very closely, the clang driver
+        currently allows tool chains to perform their own translation of
+        the argument list (into a new ArgList data structure). Although
+        this allows the clang driver to match gcc easily, it also makes
+        the driver operation much harder to understand (since the Tools
+        stop seeing some arguments the user provided, and see new ones
+        instead).</p>
+
+      <p>For example, on Darwin <tt>-gfull</tt> gets translated into two
+        separate arguments, <tt>-g</tt>
+        and <tt>-fno-eliminate-unused-debug-symbols</tt>. Trying to write Tool
+        logic to do something with <tt>-gfull</tt> will not work, because Tool
+        argument translation is done after the arguments have been
+        translated.</p>
+
+      <p>A long term goal is to remove this tool chain specific
+        translation, and instead force each tool to change its own logic
+        to do the right thing on the untranslated original arguments.</p>
+
+      <h4 id="int_unused_warnings">Unused Argument Warnings</h4>
+      <p>The driver operates by parsing all arguments but giving Tools
+        the opportunity to choose which arguments to pass on. One
+        downside of this infrastructure is that if the user misspells
+        some option, or is confused about which options to use, some
+        command line arguments the user really cared about may go
+        unused. This problem is particularly important when using
+        clang as a compiler, since the clang compiler does not support
+        anywhere near all the options that gcc does, and we want to make
+        sure users know which ones are being used.</p>
+
+      <p>To support this, the driver maintains a bit associated with
+        each argument of whether it has been used (at all) during the
+        compilation. This bit usually doesn't need to be set by hand,
+        as the key ArgList accessors will set it automatically.</p>
+
+      <p>When a compilation is successful (there are no errors), the
+        driver checks the bit and emits an "unused argument" warning for
+        any arguments which were never accessed. This is conservative
+        (the argument may not have been used to do what the user wanted)
+        but still catches the most obvious cases.</p>
+
+      <!--=======================================================================-->
+      <h3><a name="int_gcc_concepts">Relation to GCC Driver Concepts</a></h3>
+      <!--=======================================================================-->
+
+      <p>For those familiar with the gcc driver, this section provides
+        a brief overview of how things from the gcc driver map to the
+        clang driver.</p>
+
+      <ul>
+        <li>
+          <b>Driver Driver</b>
+          <p>The driver driver is fully integrated into the clang
+            driver. The driver simply constructs additional Actions to
+            bind the architecture during the <i>Pipeline</i>
+            phase. The tool chain specific argument translation is
+            responsible for handling <tt>-Xarch_</tt>.</p>
+
+          <p>The one caveat is that this approach
+            requires <tt>-Xarch_</tt> not be used to alter the
+            compilation itself (for example, one cannot
+            provide <tt>-S</tt> as an <tt>-Xarch_</tt> argument). The
+            driver attempts to reject such invocations, and overall
+            there isn't a good reason to abuse <tt>-Xarch_</tt> to
+            that end in practice.</p>
+
+          <p>The upside is that the clang driver is more efficient and
+            does little extra work to support universal builds. It also
+            provides better error reporting and UI consistency.</p>
+        </li>
+
+        <li>
+          <b>Specs</b>
+          <p>The clang driver has no direct correspondant for
+            "specs". The majority of the functionality that is
+            embedded in specs is in the Tool specific argument
+            translation routines. The parts of specs which control the
+            compilation pipeline are generally part of
+            the <ii>Pipeline</ii> stage.</p>
+        </li>
+
+        <li>
+          <b>Toolchains</b>
+          <p>The gcc driver has no direct understanding of tool
+            chains. Each gcc binary roughly corresponds to the
+            information which is embedded inside a single
+            ToolChain.</p>
+
+          <p>The clang driver is intended to be portable and support
+            complex compilation environments. All platform and tool
+            chain specific code should be protected behind either
+            abstract or well defined interfaces (such as whether the
+            platform supports use as a driver driver).</p>
+        </li>
+      </ul>
+    </div>
+  </body>
+</html>
diff --git a/docs/InternalsManual.html b/docs/InternalsManual.html
new file mode 100644
index 0000000..5d75eaa
--- /dev/null
+++ b/docs/InternalsManual.html
@@ -0,0 +1,1681 @@
+<html>
+<head>
+<title>"Clang" CFE Internals Manual</title>
+<link type="text/css" rel="stylesheet" href="../menu.css" />
+<link type="text/css" rel="stylesheet" href="../content.css" />
+<style type="text/css">
+td {
+	vertical-align: top;
+}
+</style>
+</head>
+<body>
+
+<!--#include virtual="../menu.html.incl"-->
+
+<div id="content">
+
+<h1>"Clang" CFE Internals Manual</h1>
+
+<ul>
+<li><a href="#intro">Introduction</a></li>
+<li><a href="#libsystem">LLVM System and Support Libraries</a></li>
+<li><a href="#libbasic">The Clang 'Basic' Library</a>
+  <ul>
+  <li><a href="#Diagnostics">The Diagnostics Subsystem</a></li>
+  <li><a href="#SourceLocation">The SourceLocation and SourceManager
+      classes</a></li>
+  </ul>
+</li>
+<li><a href="#libdriver">The Driver Library</a>
+  <ul>
+  </ul>
+</li>
+<li><a href="#pch">Precompiled Headers</a>
+<li><a href="#libfrontend">The Frontend Library</a>
+  <ul>
+  </ul>
+</li>
+<li><a href="#liblex">The Lexer and Preprocessor Library</a>
+  <ul>
+  <li><a href="#Token">The Token class</a></li>
+  <li><a href="#Lexer">The Lexer class</a></li>
+  <li><a href="#AnnotationToken">Annotation Tokens</a></li>
+  <li><a href="#TokenLexer">The TokenLexer class</a></li>
+  <li><a href="#MultipleIncludeOpt">The MultipleIncludeOpt class</a></li>
+  </ul>
+</li>
+<li><a href="#libparse">The Parser Library</a>
+  <ul>
+  </ul>
+</li>
+<li><a href="#libast">The AST Library</a>
+  <ul>
+  <li><a href="#Type">The Type class and its subclasses</a></li>
+  <li><a href="#QualType">The QualType class</a></li>
+  <li><a href="#DeclarationName">Declaration names</a></li>
+  <li><a href="#DeclContext">Declaration contexts</a>
+    <ul>
+      <li><a href="#Redeclarations">Redeclarations and Overloads</a></li>
+      <li><a href="#LexicalAndSemanticContexts">Lexical and Semantic
+      Contexts</a></li>
+      <li><a href="#TransparentContexts">Transparent Declaration Contexts</a></li>
+      <li><a href="#MultiDeclContext">Multiply-Defined Declaration Contexts</a></li>
+    </ul>
+  </li>
+  <li><a href="#CFG">The CFG class</a></li>
+  <li><a href="#Constants">Constant Folding in the Clang AST</a></li>
+  </ul>
+</li>
+<li><a href="libIndex.html">The Index Library</a></li>
+</ul>
+
+
+<!-- ======================================================================= -->
+<h2 id="intro">Introduction</h2>
+<!-- ======================================================================= -->
+
+<p>This document describes some of the more important APIs and internal design
+decisions made in the Clang C front-end.  The purpose of this document is to
+both capture some of this high level information and also describe some of the
+design decisions behind it.  This is meant for people interested in hacking on
+Clang, not for end-users.  The description below is categorized by
+libraries, and does not describe any of the clients of the libraries.</p>
+
+<!-- ======================================================================= -->
+<h2 id="libsystem">LLVM System and Support Libraries</h2>
+<!-- ======================================================================= -->
+
+<p>The LLVM libsystem library provides the basic Clang system abstraction layer,
+which is used for file system access.  The LLVM libsupport library provides many
+underlying libraries and <a 
+href="http://llvm.org/docs/ProgrammersManual.html">data-structures</a>,
+ including command line option
+processing and various containers.</p>
+
+<!-- ======================================================================= -->
+<h2 id="libbasic">The Clang 'Basic' Library</h2>
+<!-- ======================================================================= -->
+
+<p>This library certainly needs a better name.  The 'basic' library contains a
+number of low-level utilities for tracking and manipulating source buffers,
+locations within the source buffers, diagnostics, tokens, target abstraction,
+and information about the subset of the language being compiled for.</p>
+
+<p>Part of this infrastructure is specific to C (such as the TargetInfo class),
+other parts could be reused for other non-C-based languages (SourceLocation,
+SourceManager, Diagnostics, FileManager).  When and if there is future demand
+we can figure out if it makes sense to introduce a new library, move the general
+classes somewhere else, or introduce some other solution.</p>
+
+<p>We describe the roles of these classes in order of their dependencies.</p>
+
+
+<!-- ======================================================================= -->
+<h3 id="Diagnostics">The Diagnostics Subsystem</h3>
+<!-- ======================================================================= -->
+
+<p>The Clang Diagnostics subsystem is an important part of how the compiler
+communicates with the human.  Diagnostics are the warnings and errors produced
+when the code is incorrect or dubious.  In Clang, each diagnostic produced has
+(at the minimum) a unique ID, a <a href="#SourceLocation">SourceLocation</a> to
+"put the caret", an English translation associated with it, and a severity (e.g.
+<tt>WARNING</tt> or <tt>ERROR</tt>).  They can also optionally include a number
+of arguments to the dianostic (which fill in "%0"'s in the string) as well as a
+number of source ranges that related to the diagnostic.</p>
+
+<p>In this section, we'll be giving examples produced by the Clang command line
+driver, but diagnostics can be <a href="#DiagnosticClient">rendered in many
+different ways</a> depending on how the DiagnosticClient interface is
+implemented.  A representative example of a diagonstic is:</p>
+
+<pre>
+t.c:38:15: error: invalid operands to binary expression ('int *' and '_Complex float')
+   <font color="darkgreen">P = (P-42) + Gamma*4;</font>
+       <font color="blue">~~~~~~ ^ ~~~~~~~</font>
+</pre>
+
+<p>In this example, you can see the English translation, the severity (error),
+you can see the source location (the caret ("^") and file/line/column info),
+the source ranges "~~~~", arguments to the diagnostic ("int*" and "_Complex
+float").  You'll have to believe me that there is a unique ID backing the
+diagnostic :).</p>
+
+<p>Getting all of this to happen has several steps and involves many moving
+pieces, this section describes them and talks about best practices when adding
+a new diagnostic.</p>
+
+<!-- ============================ -->
+<h4>The DiagnosticKinds.def file</h4>
+<!-- ============================ -->
+
+<p>Diagnostics are created by adding an entry to the <tt><a
+href="http://llvm.org/svn/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticKinds.def"
+>DiagnosticKinds.def</a></tt> file.  This file encodes the unique ID of the 
+diagnostic (as an enum, the first argument), the severity of the diagnostic
+(second argument) and the English translation + format string.</p>
+
+<p>There is little sanity with the naming of the unique ID's right now.  Some
+start with err_, warn_, ext_ to encode the severity into the name.  Since the
+enum is referenced in the C++ code that produces the diagnostic, it is somewhat
+useful for it to be reasonably short.</p>
+
+<p>The severity of the diagnostic comes from the set {<tt>NOTE</tt>,
+<tt>WARNING</tt>, <tt>EXTENSION</tt>, <tt>EXTWARN</tt>, <tt>ERROR</tt>}.  The
+<tt>ERROR</tt> severity is used for diagnostics indicating the program is never
+acceptable under any circumstances.  When an error is emitted, the AST for the
+input code may not be fully built.  The <tt>EXTENSION</tt> and <tt>EXTWARN</tt>
+severities are used for extensions to the language that Clang accepts.  This
+means that Clang fully understands and can represent them in the AST, but we
+produce diagnostics to tell the user their code is non-portable.  The difference
+is that the former are ignored by default, and the later warn by default.  The
+<tt>WARNING</tt> severity is used for constructs that are valid in the currently
+selected source language but that are dubious in some way.  The <tt>NOTE</tt>
+level is used to staple more information onto previous diagnostics.</p>
+
+<p>These <em>severities</em> are mapped into a smaller set (the
+Diagnostic::Level enum, {<tt>Ignored</tt>, <tt>Note</tt>, <tt>Warning</tt>,
+<tt>Error</tt>, <tt>Fatal</tt> }) of output <em>levels</em> by the diagnostics
+subsystem based on various configuration options.  Clang internally supports a
+fully fine grained mapping mechanism that allows you to map almost any
+diagnostic to the output level that you want.  The only diagnostics that cannot
+be mapped are <tt>NOTE</tt>s, which always follow the severity of the previously
+emitted diagnostic and <tt>ERROR</tt>s, which can only be mapped to
+<tt>Fatal</tt> (it is not possible to turn an error into a warning,
+for example).</p>
+
+<p>Diagnostic mappings are used in many ways.  For example, if the user
+specifies <tt>-pedantic</tt>, <tt>EXTENSION</tt> maps to <tt>Warning</tt>, if
+they specify <tt>-pedantic-errors</tt>, it turns into <tt>Error</tt>.  This is
+used to implement options like <tt>-Wunused_macros</tt>, <tt>-Wundef</tt> etc.
+</p>
+
+<p>
+Mapping to <tt>Fatal</tt> should only be used for diagnostics that are
+considered so severe that error recovery won't be able to recover sensibly from
+them (thus spewing a ton of bogus errors).  One example of this class of error
+are failure to #include a file.
+</p>
+
+<!-- ================= -->
+<h4>The Format String</h4>
+<!-- ================= -->
+
+<p>The format string for the diagnostic is very simple, but it has some power.
+It takes the form of a string in English with markers that indicate where and
+how arguments to the diagnostic are inserted and formatted.  For example, here
+are some simple format strings:</p>
+
+<pre>
+  "binary integer literals are an extension"
+  "format string contains '\\0' within the string body"
+  "more '<b>%%</b>' conversions than data arguments"
+  "invalid operands to binary expression (<b>%0</b> and <b>%1</b>)"
+  "overloaded '<b>%0</b>' must be a <b>%select{unary|binary|unary or binary}2</b> operator"
+       " (has <b>%1</b> parameter<b>%s1</b>)"
+</pre>
+
+<p>These examples show some important points of format strings.  You can use any
+   plain ASCII character in the diagnostic string except "%" without a problem,
+   but these are C strings, so you have to use and be aware of all the C escape
+   sequences (as in the second example).  If you want to produce a "%" in the
+   output, use the "%%" escape sequence, like the third diagnostic.  Finally,
+   Clang uses the "%...[digit]" sequences to specify where and how arguments to
+   the diagnostic are formatted.</p>
+   
+<p>Arguments to the diagnostic are numbered according to how they are specified
+   by the C++ code that <a href="#producingdiag">produces them</a>, and are
+   referenced by <tt>%0</tt> .. <tt>%9</tt>.  If you have more than 10 arguments
+   to your diagnostic, you are doing something wrong :).  Unlike printf, there
+   is no requirement that arguments to the diagnostic end up in the output in
+   the same order as they are specified, you could have a format string with
+   <tt>"%1 %0"</tt> that swaps them, for example.  The text in between the
+   percent and digit are formatting instructions.  If there are no instructions,
+   the argument is just turned into a string and substituted in.</p>
+
+<p>Here are some "best practices" for writing the English format string:</p>
+
+<ul>
+<li>Keep the string short.  It should ideally fit in the 80 column limit of the
+    <tt>DiagnosticKinds.def</tt> file.  This avoids the diagnostic wrapping when
+    printed, and forces you to think about the important point you are conveying
+    with the diagnostic.</li>
+<li>Take advantage of location information.  The user will be able to see the
+    line and location of the caret, so you don't need to tell them that the
+    problem is with the 4th argument to the function: just point to it.</li>
+<li>Do not capitalize the diagnostic string, and do not end it with a
+    period.</li>
+<li>If you need to quote something in the diagnostic string, use single
+    quotes.</li>
+</ul>
+
+<p>Diagnostics should never take random English strings as arguments: you
+shouldn't use <tt>"you have a problem with %0"</tt> and pass in things like
+<tt>"your argument"</tt> or <tt>"your return value"</tt> as arguments. Doing
+this prevents <a href="translation">translating</a> the Clang diagnostics to
+other languages (because they'll get random English words in their otherwise
+localized diagnostic).  The exceptions to this are C/C++ language keywords
+(e.g. auto, const, mutable, etc) and C/C++ operators (<tt>/=</tt>).  Note
+that things like "pointer" and "reference" are not keywords.  On the other
+hand, you <em>can</em> include anything that comes from the user's source code,
+including variable names, types, labels, etc.  The 'select' format can be 
+used to achieve this sort of thing in a localizable way, see below.</p>
+
+<!-- ==================================== -->
+<h4>Formatting a Diagnostic Argument</a></h4>
+<!-- ==================================== -->
+
+<p>Arguments to diagnostics are fully typed internally, and come from a couple
+different classes: integers, types, names, and random strings.  Depending on
+the class of the argument, it can be optionally formatted in different ways.
+This gives the DiagnosticClient information about what the argument means
+without requiring it to use a specific presentation (consider this MVC for
+Clang :).</p>
+
+<p>Here are the different diagnostic argument formats currently supported by
+Clang:</p>
+
+<table>
+<tr><td colspan="2"><b>"s" format</b></td></tr>
+<tr><td>Example:</td><td><tt>"requires %1 parameter%s1"</tt></td></tr>
+<tr><td>Class:</td><td>Integers</td></tr>
+<tr><td>Description:</td><td>This is a simple formatter for integers that is
+    useful when producing English diagnostics.  When the integer is 1, it prints
+    as nothing.  When the integer is not 1, it prints as "s".  This allows some
+    simple grammatical forms to be to be handled correctly, and eliminates the
+    need to use gross things like <tt>"requires %1 parameter(s)"</tt>.</td></tr>
+
+<tr><td colspan="2"><b>"select" format</b></td></tr>
+<tr><td>Example:</td><td><tt>"must be a %select{unary|binary|unary or binary}2
+     operator"</tt></td></tr>
+<tr><td>Class:</td><td>Integers</td></tr>
+<tr><td>Description:</td><td><p>This format specifier is used to merge multiple
+    related diagnostics together into one common one, without requiring the
+    difference to be specified as an English string argument.  Instead of
+    specifying the string, the diagnostic gets an integer argument and the
+    format string selects the numbered option.  In this case, the "%2" value
+    must be an integer in the range [0..2].  If it is 0, it prints 'unary', if
+    it is 1 it prints 'binary' if it is 2, it prints 'unary or binary'.  This
+    allows other language translations to substitute reasonable words (or entire
+    phrases) based on the semantics of the diagnostic instead of having to do
+    things textually.</p>
+    <p>The selected string does undergo formatting.</p></td></tr>
+
+<tr><td colspan="2"><b>"plural" format</b></td></tr>
+<tr><td>Example:</td><td><tt>"you have %1 %plural{1:mouse|:mice}1 connected to
+    your computer"</tt></td></tr>
+<tr><td>Class:</td><td>Integers</td></tr>
+<tr><td>Description:</td><td><p>This is a formatter for complex plural forms.
+    It is designed to handle even the requirements of languages with very
+	complex plural forms, as many Baltic languages have. The argument consists
+	of a series of expression/form pairs, separated by ':', where the first form
+	whose expression evaluates to true is the result of the modifier.</p>
+	<p>An expression can be empty, in which case it is always true. See the
+	example at the top. Otherwise, it is a series of one or more numeric
+	conditions, separated by ','. If any condition matches, the expression
+	matches. Each numeric condition can take one of three forms.</p>
+	<ul>
+	    <li>number: A simple decimal number matches if the argument is the same
+		as the number. Example: <tt>"%plural{1:mouse|:mice}4"</tt></li>
+		<li>range: A range in square brackets matches if the argument is within
+		the range. Then range is inclusive on both ends. Example:
+		<tt>"%plural{0:none|1:one|[2,5]:some|:many}2"</tt></li>
+		<li>modulo: A modulo operator is followed by a number, and
+                equals sign and either a number or a range. The tests are the
+                same as for plain
+		numbers and ranges, but the argument is taken modulo the number first.
+		Example: <tt>"%plural{%100=0:even hundred|%100=[1,50]:lower half|:everything
+		else}1"</tt></li>
+	</ul>
+	<p>The parser is very unforgiving. A syntax error, even whitespace, will
+	abort, as will a failure to match the argument against any
+	expression.</p></td></tr>
+
+<tr><td colspan="2"><b>"ordinal" format</b></td></tr>
+<tr><td>Example:</td><td><tt>"ambiguity in %ordinal0 argument"</tt></td></tr>
+<tr><td>Class:</td><td>Integers</td></tr>
+<tr><td>Description:</td><td><p>This is a formatter which represents the
+    argument number as an ordinal:  the value <tt>1</tt> becomes <tt>1st</tt>,
+    <tt>3</tt> becomes <tt>3rd</tt>, and so on.  Values less than <tt>1</tt>
+    are not supported.</p>
+    <p>This formatter is currently hard-coded to use English ordinals.</p></td></tr>
+
+<tr><td colspan="2"><b>"objcclass" format</b></td></tr>
+<tr><td>Example:</td><td><tt>"method %objcclass0 not found"</tt></td></tr>
+<tr><td>Class:</td><td>DeclarationName</td></tr>
+<tr><td>Description:</td><td><p>This is a simple formatter that indicates the
+    DeclarationName corresponds to an Objective-C class method selector.  As
+    such, it prints the selector with a leading '+'.</p></td></tr>
+
+<tr><td colspan="2"><b>"objcinstance" format</b></td></tr>
+<tr><td>Example:</td><td><tt>"method %objcinstance0 not found"</tt></td></tr>
+<tr><td>Class:</td><td>DeclarationName</td></tr>
+<tr><td>Description:</td><td><p>This is a simple formatter that indicates the
+    DeclarationName corresponds to an Objective-C instance method selector.  As
+    such, it prints the selector with a leading '-'.</p></td></tr>
+
+<tr><td colspan="2"><b>"q" format</b></td></tr>
+<tr><td>Example:</td><td><tt>"candidate found by name lookup is %q0"</tt></td></tr>
+<tr><td>Class:</td><td>NamedDecl*</td></tr>
+<tr><td>Description</td><td><p>This formatter indicates that the fully-qualified name of the declaration should be printed, e.g., "std::vector" rather than "vector".</p></td></tr>
+    
+</table>
+
+<p>It is really easy to add format specifiers to the Clang diagnostics system,
+but they should be discussed before they are added.  If you are creating a lot
+of repetitive diagnostics and/or have an idea for a useful formatter, please
+bring it up on the cfe-dev mailing list.</p>
+
+<!-- ===================================================== -->
+<h4><a name="#producingdiag">Producing the Diagnostic</a></h4>
+<!-- ===================================================== -->
+
+<p>Now that you've created the diagnostic in the DiagnosticKinds.def file, you
+need to write the code that detects the condition in question and emits the
+new diagnostic.  Various components of Clang (e.g. the preprocessor, Sema,
+etc) provide a helper function named "Diag".  It creates a diagnostic and
+accepts the arguments, ranges, and other information that goes along with
+it.</p>
+
+<p>For example, the binary expression error comes from code like this:</p>
+
+<pre>
+  if (various things that are bad)
+    Diag(Loc, diag::err_typecheck_invalid_operands)
+      &lt;&lt; lex-&gt;getType() &lt;&lt; rex-&gt;getType()
+      &lt;&lt; lex-&gt;getSourceRange() &lt;&lt; rex-&gt;getSourceRange();
+</pre>
+
+<p>This shows that use of the Diag method: they take a location (a <a
+href="#SourceLocation">SourceLocation</a> object) and a diagnostic enum value
+(which matches the name from DiagnosticKinds.def).  If the diagnostic takes
+arguments, they are specified with the &lt;&lt; operator: the first argument
+becomes %0, the second becomes %1, etc.  The diagnostic interface allows you to
+specify arguments of many different types, including <tt>int</tt> and
+<tt>unsigned</tt> for integer arguments, <tt>const char*</tt> and
+<tt>std::string</tt> for string arguments, <tt>DeclarationName</tt> and
+<tt>const IdentifierInfo*</tt> for names, <tt>QualType</tt> for types, etc.
+SourceRanges are also specified with the &lt;&lt; operator, but do not have a
+specific ordering requirement.</p>
+
+<p>As you can see, adding and producing a diagnostic is pretty straightforward.
+The hard part is deciding exactly what you need to say to help the user, picking
+a suitable wording, and providing the information needed to format it correctly.
+The good news is that the call site that issues a diagnostic should be
+completely independent of how the diagnostic is formatted and in what language
+it is rendered.
+</p>
+
+<!-- ==================================================== -->
+<h4 id="code-modification-hints">Code Modification Hints</h4>
+<!-- ==================================================== -->
+
+<p>In some cases, the front end emits diagnostics when it is clear
+that some small change to the source code would fix the problem. For
+example, a missing semicolon at the end of a statement or a use of
+deprecated syntax that is easily rewritten into a more modern form. 
+Clang tries very hard to emit the diagnostic and recover gracefully
+in these and other cases.</p>
+
+<p>However, for these cases where the fix is obvious, the diagnostic 
+can be annotated with a code
+modification "hint" that describes how to change the code referenced
+by the diagnostic to fix the problem. For example, it might add the
+missing semicolon at the end of the statement or rewrite the use of a
+deprecated construct into something more palatable. Here is one such
+example C++ front end, where we warn about the right-shift operator
+changing meaning from C++98 to C++0x:</p>
+
+<pre>
+test.cpp:3:7: warning: use of right-shift operator ('&gt;&gt;') in template argument will require parentheses in C++0x
+A&lt;100 &gt;&gt; 2&gt; *a;
+      ^
+  (       )
+</pre>
+
+<p>Here, the code modification hint is suggesting that parentheses be
+added, and showing exactly where those parentheses would be inserted
+into the source code. The code modification hints themselves describe
+what changes to make to the source code in an abstract manner, which
+the text diagnostic printer renders as a line of "insertions" below
+the caret line. <a href="#DiagnosticClient">Other diagnostic
+clients</a> might choose to render the code differently (e.g., as
+markup inline) or even give the user the ability to automatically fix
+the problem.</p>
+
+<p>All code modification hints are described by the
+<code>CodeModificationHint</code> class, instances of which should be
+attached to the diagnostic using the &lt;&lt; operator in the same way
+that highlighted source ranges and arguments are passed to the
+diagnostic. Code modification hints can be created with one of three
+constructors:</p>
+
+<dl>
+  <dt><code>CodeModificationHint::CreateInsertion(Loc, Code)</code></dt>
+  <dd>Specifies that the given <code>Code</code> (a string) should be inserted
+  before the source location <code>Loc</code>.</dd>
+
+  <dt><code>CodeModificationHint::CreateRemoval(Range)</code></dt>
+  <dd>Specifies that the code in the given source <code>Range</code>
+  should be removed.</dd>
+
+  <dt><code>CodeModificationHint::CreateReplacement(Range, Code)</code></dt>
+  <dd>Specifies that the code in the given source <code>Range</code>
+  should be removed, and replaced with the given <code>Code</code> string.</dd>
+</dl>
+
+<!-- ============================================================= -->
+<h4><a name="DiagnosticClient">The DiagnosticClient Interface</a></h4>
+<!-- ============================================================= -->
+
+<p>Once code generates a diagnostic with all of the arguments and the rest of
+the relevant information, Clang needs to know what to do with it.  As previously
+mentioned, the diagnostic machinery goes through some filtering to map a
+severity onto a diagnostic level, then (assuming the diagnostic is not mapped to
+"<tt>Ignore</tt>") it invokes an object that implements the DiagnosticClient
+interface with the information.</p>
+
+<p>It is possible to implement this interface in many different ways.  For
+example, the normal Clang DiagnosticClient (named 'TextDiagnosticPrinter') turns
+the arguments into strings (according to the various formatting rules), prints
+out the file/line/column information and the string, then prints out the line of
+code, the source ranges, and the caret.  However, this behavior isn't required.
+</p>
+
+<p>Another implementation of the DiagnosticClient interface is the
+'TextDiagnosticBuffer' class, which is used when Clang is in -verify mode.
+Instead of formatting and printing out the diagnostics, this implementation just
+captures and remembers the diagnostics as they fly by.  Then -verify compares
+the list of produced diagnostics to the list of expected ones.  If they disagree,
+it prints out its own output.
+</p>
+
+<p>There are many other possible implementations of this interface, and this is
+why we prefer diagnostics to pass down rich structured information in arguments.
+For example, an HTML output might want declaration names be linkified to where
+they come from in the source.  Another example is that a GUI might let you click
+on typedefs to expand them.  This application would want to pass significantly
+more information about types through to the GUI than a simple flat string.  The
+interface allows this to happen.</p>
+
+<!-- ====================================================== -->
+<h4><a name="translation">Adding Translations to Clang</a></h4>
+<!-- ====================================================== -->
+
+<p>Not possible yet!  Diagnostic strings should be written in UTF-8, the client
+can translate to the relevant code page if needed.  Each translation completely
+replaces the format string for the diagnostic.</p>
+
+
+<!-- ======================================================================= -->
+<h3 id="SourceLocation">The SourceLocation and SourceManager classes</h3>
+<!-- ======================================================================= -->
+
+<p>Strangely enough, the SourceLocation class represents a location within the
+source code of the program.  Important design points include:</p>
+
+<ol>
+<li>sizeof(SourceLocation) must be extremely small, as these are embedded into
+    many AST nodes and are passed around often.  Currently it is 32 bits.</li>
+<li>SourceLocation must be a simple value object that can be efficiently
+    copied.</li>
+<li>We should be able to represent a source location for any byte of any input
+    file.  This includes in the middle of tokens, in whitespace, in trigraphs,
+    etc.</li>
+<li>A SourceLocation must encode the current #include stack that was active when
+    the location was processed.  For example, if the location corresponds to a
+    token, it should contain the set of #includes active when the token was
+    lexed.  This allows us to print the #include stack for a diagnostic.</li>
+<li>SourceLocation must be able to describe macro expansions, capturing both
+    the ultimate instantiation point and the source of the original character
+    data.</li>
+</ol>
+
+<p>In practice, the SourceLocation works together with the SourceManager class
+to encode two pieces of information about a location: it's spelling location
+and it's instantiation location.  For most tokens, these will be the same.  However,
+for a macro expansion (or tokens that came from a _Pragma directive) these will
+describe the location of the characters corresponding to the token and the
+location where the token was used (i.e. the macro instantiation point or the 
+location of the _Pragma itself).</p>
+
+<p>The Clang front-end inherently depends on the location of a token being
+tracked correctly.  If it is ever incorrect, the front-end may get confused and
+die.  The reason for this is that the notion of the 'spelling' of a Token in
+Clang depends on being able to find the original input characters for the token.
+This concept maps directly to the "spelling location" for the token.</p>
+
+<!-- ======================================================================= -->
+<h2 id="libdriver">The Driver Library</h2>
+<!-- ======================================================================= -->
+
+<p>The clang Driver and library are documented <a
+href="DriverInternals.html">here<a>.<p>
+
+<!-- ======================================================================= -->
+<h2 id="pch">Precompiled Headers</h2>
+<!-- ======================================================================= -->
+
+<p>Clang supports two implementations of precompiled headers. The
+   default implementation, precompiled headers (<a
+    href="PCHInternals.html">PCH</a>) uses a serialized representation
+   of Clang's internal data structures, encoded with the <a
+    href="http://llvm.org/docs/BitCodeFormat.html">LLVM bitstream
+   format</a>. Pretokenized headers (<a
+    href="PTHInternals.html">PTH</a>), on the other hand, contain a
+   serialized representation of the tokens encountered when
+   preprocessing a header (and anything that header includes).</p>
+
+
+<!-- ======================================================================= -->
+<h2 id="libfrontend">The Frontend Library</h2>
+<!-- ======================================================================= -->
+
+<p>The Frontend library contains functionality useful for building
+tools on top of the clang libraries, for example several methods for
+outputting diagnostics.</p>
+
+<!-- ======================================================================= -->
+<h2 id="liblex">The Lexer and Preprocessor Library</h2>
+<!-- ======================================================================= -->
+
+<p>The Lexer library contains several tightly-connected classes that are involved
+with the nasty process of lexing and preprocessing C source code.  The main
+interface to this library for outside clients is the large <a 
+href="#Preprocessor">Preprocessor</a> class.
+It contains the various pieces of state that are required to coherently read
+tokens out of a translation unit.</p>
+
+<p>The core interface to the Preprocessor object (once it is set up) is the
+Preprocessor::Lex method, which returns the next <a href="#Token">Token</a> from
+the preprocessor stream.  There are two types of token providers that the
+preprocessor is capable of reading from: a buffer lexer (provided by the <a 
+href="#Lexer">Lexer</a> class) and a buffered token stream (provided by the <a
+href="#TokenLexer">TokenLexer</a> class).  
+
+
+<!-- ======================================================================= -->
+<h3 id="Token">The Token class</h3>
+<!-- ======================================================================= -->
+
+<p>The Token class is used to represent a single lexed token.  Tokens are
+intended to be used by the lexer/preprocess and parser libraries, but are not
+intended to live beyond them (for example, they should not live in the ASTs).<p>
+
+<p>Tokens most often live on the stack (or some other location that is efficient
+to access) as the parser is running, but occasionally do get buffered up.  For
+example, macro definitions are stored as a series of tokens, and the C++
+front-end periodically needs to buffer tokens up for tentative parsing and
+various pieces of look-ahead.  As such, the size of a Token matter.  On a 32-bit
+system, sizeof(Token) is currently 16 bytes.</p>
+
+<p>Tokens occur in two forms: "<a href="#AnnotationToken">Annotation
+Tokens</a>" and normal tokens.  Normal tokens are those returned by the lexer,
+annotation tokens represent semantic information and are produced by the parser,
+replacing normal tokens in the token stream.  Normal tokens contain the
+following information:</p>
+
+<ul>
+<li><b>A SourceLocation</b> - This indicates the location of the start of the
+token.</li>
+
+<li><b>A length</b> - This stores the length of the token as stored in the
+SourceBuffer.  For tokens that include them, this length includes trigraphs and
+escaped newlines which are ignored by later phases of the compiler.  By pointing
+into the original source buffer, it is always possible to get the original
+spelling of a token completely accurately.</li>
+
+<li><b>IdentifierInfo</b> - If a token takes the form of an identifier, and if
+identifier lookup was enabled when the token was lexed (e.g. the lexer was not
+reading in 'raw' mode) this contains a pointer to the unique hash value for the
+identifier.  Because the lookup happens before keyword identification, this
+field is set even for language keywords like 'for'.</li>
+
+<li><b>TokenKind</b> - This indicates the kind of token as classified by the
+lexer.  This includes things like <tt>tok::starequal</tt> (for the "*="
+operator), <tt>tok::ampamp</tt> for the "&amp;&amp;" token, and keyword values
+(e.g. <tt>tok::kw_for</tt>) for identifiers that correspond to keywords.  Note 
+that some tokens can be spelled multiple ways.  For example, C++ supports
+"operator keywords", where things like "and" are treated exactly like the
+"&amp;&amp;" operator.  In these cases, the kind value is set to
+<tt>tok::ampamp</tt>, which is good for the parser, which doesn't have to 
+consider both forms.  For something that cares about which form is used (e.g.
+the preprocessor 'stringize' operator) the spelling indicates the original
+form.</li>
+
+<li><b>Flags</b> - There are currently four flags tracked by the
+lexer/preprocessor system on a per-token basis:
+
+  <ol>
+  <li><b>StartOfLine</b> - This was the first token that occurred on its input
+       source line.</li>
+  <li><b>LeadingSpace</b> - There was a space character either immediately
+       before the token or transitively before the token as it was expanded
+       through a macro.  The definition of this flag is very closely defined by
+       the stringizing requirements of the preprocessor.</li>
+  <li><b>DisableExpand</b> - This flag is used internally to the preprocessor to
+      represent identifier tokens which have macro expansion disabled.  This
+      prevents them from being considered as candidates for macro expansion ever
+      in the future.</li>
+  <li><b>NeedsCleaning</b> - This flag is set if the original spelling for the
+      token includes a trigraph or escaped newline.  Since this is uncommon,
+      many pieces of code can fast-path on tokens that did not need cleaning.
+      </p>
+   </ol>
+</li>
+</ul>
+
+<p>One interesting (and somewhat unusual) aspect of normal tokens is that they
+don't contain any semantic information about the lexed value.  For example, if
+the token was a pp-number token, we do not represent the value of the number
+that was lexed (this is left for later pieces of code to decide).  Additionally,
+the lexer library has no notion of typedef names vs variable names: both are
+returned as identifiers, and the parser is left to decide whether a specific
+identifier is a typedef or a variable (tracking this requires scope information 
+among other things).  The parser can do this translation by replacing tokens
+returned by the preprocessor with "Annotation Tokens".</p>
+
+<!-- ======================================================================= -->
+<h3 id="AnnotationToken">Annotation Tokens</h3>
+<!-- ======================================================================= -->
+
+<p>Annotation Tokens are tokens that are synthesized by the parser and injected
+into the preprocessor's token stream (replacing existing tokens) to record
+semantic information found by the parser.  For example, if "foo" is found to be
+a typedef, the "foo" <tt>tok::identifier</tt> token is replaced with an
+<tt>tok::annot_typename</tt>.  This is useful for a couple of reasons: 1) this
+makes it easy to handle qualified type names (e.g. "foo::bar::baz&lt;42&gt;::t")
+in C++ as a single "token" in the parser. 2) if the parser backtracks, the
+reparse does not need to redo semantic analysis to determine whether a token
+sequence is a variable, type, template, etc.</p>
+
+<p>Annotation Tokens are created by the parser and reinjected into the parser's
+token stream (when backtracking is enabled).  Because they can only exist in
+tokens that the preprocessor-proper is done with, it doesn't need to keep around
+flags like "start of line" that the preprocessor uses to do its job.
+Additionally, an annotation token may "cover" a sequence of preprocessor tokens
+(e.g. <tt>a::b::c</tt> is five preprocessor tokens).  As such, the valid fields
+of an annotation token are different than the fields for a normal token (but
+they are multiplexed into the normal Token fields):</p>
+
+<ul>
+<li><b>SourceLocation "Location"</b> - The SourceLocation for the annotation
+token indicates the first token replaced by the annotation token. In the example
+above, it would be the location of the "a" identifier.</li>
+
+<li><b>SourceLocation "AnnotationEndLoc"</b> - This holds the location of the
+last token replaced with the annotation token.  In the example above, it would
+be the location of the "c" identifier.</li>
+
+<li><b>void* "AnnotationValue"</b> - This contains an opaque object that the
+parser gets from Sema through an Actions module, it is passed around and Sema
+intepretes it, based on the type of annotation token.</li>
+
+<li><b>TokenKind "Kind"</b> - This indicates the kind of Annotation token this
+is.  See below for the different valid kinds.</li>
+</ul>
+
+<p>Annotation tokens currently come in three kinds:</p>
+
+<ol>
+<li><b>tok::annot_typename</b>: This annotation token represents a
+resolved typename token that is potentially qualified.  The AnnotationValue
+field contains a pointer returned by Action::getTypeName().  In the case of the
+Sema actions module, this is a <tt>Decl*</tt> for the type.</li>
+
+<li><b>tok::annot_cxxscope</b>: This annotation token represents a C++ scope
+specifier, such as "A::B::".  This corresponds to the grammar productions "::"
+and ":: [opt] nested-name-specifier".  The AnnotationValue pointer is returned
+by the Action::ActOnCXXGlobalScopeSpecifier and
+Action::ActOnCXXNestedNameSpecifier callbacks.  In the case of Sema, this is a
+<tt>DeclContext*</tt>.</li>
+
+<li><b>tok::annot_template_id</b>: This annotation token represents a
+C++ template-id such as "foo&lt;int, 4&gt;", where "foo" is the name
+of a template. The AnnotationValue pointer is a pointer to a malloc'd
+TemplateIdAnnotation object. Depending on the context, a parsed template-id that names a type might become a typename annotation token (if all we care about is the named type, e.g., because it occurs in a type specifier) or might remain a template-id token (if we want to retain more source location information or produce a new type, e.g., in a declaration of a class template specialization). template-id annotation tokens that refer to a type can be "upgraded" to typename annotation tokens by the parser.</li>
+
+</ol>
+
+<p>As mentioned above, annotation tokens are not returned by the preprocessor,
+they are formed on demand by the parser.  This means that the parser has to be
+aware of cases where an annotation could occur and form it where appropriate.
+This is somewhat similar to how the parser handles Translation Phase 6 of C99:
+String Concatenation (see C99 5.1.1.2).  In the case of string concatenation,
+the preprocessor just returns distinct tok::string_literal and
+tok::wide_string_literal tokens and the parser eats a sequence of them wherever
+the grammar indicates that a string literal can occur.</p>
+
+<p>In order to do this, whenever the parser expects a tok::identifier or
+tok::coloncolon, it should call the TryAnnotateTypeOrScopeToken or
+TryAnnotateCXXScopeToken methods to form the annotation token.  These methods
+will maximally form the specified annotation tokens and replace the current
+token with them, if applicable.  If the current tokens is not valid for an
+annotation token, it will remain an identifier or :: token.</p>
+
+
+
+<!-- ======================================================================= -->
+<h3 id="Lexer">The Lexer class</h3>
+<!-- ======================================================================= -->
+
+<p>The Lexer class provides the mechanics of lexing tokens out of a source
+buffer and deciding what they mean.  The Lexer is complicated by the fact that
+it operates on raw buffers that have not had spelling eliminated (this is a
+necessity to get decent performance), but this is countered with careful coding
+as well as standard performance techniques (for example, the comment handling
+code is vectorized on X86 and PowerPC hosts).</p>
+
+<p>The lexer has a couple of interesting modal features:</p>
+
+<ul>
+<li>The lexer can operate in 'raw' mode.  This mode has several features that
+    make it possible to quickly lex the file (e.g. it stops identifier lookup,
+    doesn't specially handle preprocessor tokens, handles EOF differently, etc).
+    This mode is used for lexing within an "<tt>#if 0</tt>" block, for
+    example.</li>
+<li>The lexer can capture and return comments as tokens.  This is required to
+    support the -C preprocessor mode, which passes comments through, and is
+    used by the diagnostic checker to identifier expect-error annotations.</li>
+<li>The lexer can be in ParsingFilename mode, which happens when preprocessing
+    after reading a #include directive.  This mode changes the parsing of '&lt;'
+    to return an "angled string" instead of a bunch of tokens for each thing
+    within the filename.</li>
+<li>When parsing a preprocessor directive (after "<tt>#</tt>") the
+    ParsingPreprocessorDirective mode is entered.  This changes the parser to
+    return EOM at a newline.</li>
+<li>The Lexer uses a LangOptions object to know whether trigraphs are enabled,
+    whether C++ or ObjC keywords are recognized, etc.</li>
+</ul>
+
+<p>In addition to these modes, the lexer keeps track of a couple of other
+   features that are local to a lexed buffer, which change as the buffer is
+   lexed:</p>
+
+<ul>
+<li>The Lexer uses BufferPtr to keep track of the current character being
+    lexed.</li>
+<li>The Lexer uses IsAtStartOfLine to keep track of whether the next lexed token
+    will start with its "start of line" bit set.</li>
+<li>The Lexer keeps track of the current #if directives that are active (which
+    can be nested).</li>
+<li>The Lexer keeps track of an <a href="#MultipleIncludeOpt">
+    MultipleIncludeOpt</a> object, which is used to
+    detect whether the buffer uses the standard "<tt>#ifndef XX</tt> /
+    <tt>#define XX</tt>" idiom to prevent multiple inclusion.  If a buffer does,
+    subsequent includes can be ignored if the XX macro is defined.</li>
+</ul>
+
+<!-- ======================================================================= -->
+<h3 id="TokenLexer">The TokenLexer class</h3>
+<!-- ======================================================================= -->
+
+<p>The TokenLexer class is a token provider that returns tokens from a list
+of tokens that came from somewhere else.  It typically used for two things: 1)
+returning tokens from a macro definition as it is being expanded 2) returning
+tokens from an arbitrary buffer of tokens.  The later use is used by _Pragma and
+will most likely be used to handle unbounded look-ahead for the C++ parser.</p>
+
+<!-- ======================================================================= -->
+<h3 id="MultipleIncludeOpt">The MultipleIncludeOpt class</h3>
+<!-- ======================================================================= -->
+
+<p>The MultipleIncludeOpt class implements a really simple little state machine
+that is used to detect the standard "<tt>#ifndef XX</tt> / <tt>#define XX</tt>"
+idiom that people typically use to prevent multiple inclusion of headers.  If a
+buffer uses this idiom and is subsequently #include'd, the preprocessor can
+simply check to see whether the guarding condition is defined or not.  If so,
+the preprocessor can completely ignore the include of the header.</p>
+
+
+
+<!-- ======================================================================= -->
+<h2 id="libparse">The Parser Library</h2>
+<!-- ======================================================================= -->
+
+<!-- ======================================================================= -->
+<h2 id="libast">The AST Library</h2>
+<!-- ======================================================================= -->
+
+<!-- ======================================================================= -->
+<h3 id="Type">The Type class and its subclasses</h3>
+<!-- ======================================================================= -->
+
+<p>The Type class (and its subclasses) are an important part of the AST.  Types
+are accessed through the ASTContext class, which implicitly creates and uniques
+them as they are needed.  Types have a couple of non-obvious features: 1) they
+do not capture type qualifiers like const or volatile (See
+<a href="#QualType">QualType</a>), and 2) they implicitly capture typedef
+information.  Once created, types are immutable (unlike decls).</p>
+
+<p>Typedefs in C make semantic analysis a bit more complex than it would
+be without them.  The issue is that we want to capture typedef information
+and represent it in the AST perfectly, but the semantics of operations need to
+"see through" typedefs.  For example, consider this code:</p>
+
+<code>
+void func() {<br>
+&nbsp;&nbsp;typedef int foo;<br>
+&nbsp;&nbsp;foo X, *Y;<br>
+&nbsp;&nbsp;typedef foo* bar;<br>
+&nbsp;&nbsp;bar Z;<br>
+&nbsp;&nbsp;*X;   <i>// error</i><br>
+&nbsp;&nbsp;**Y;  <i>// error</i><br>
+&nbsp;&nbsp;**Z;  <i>// error</i><br>
+}<br>
+</code>
+
+<p>The code above is illegal, and thus we expect there to be diagnostics emitted
+on the annotated lines.  In this example, we expect to get:</p>
+
+<pre>
+<b>test.c:6:1: error: indirection requires pointer operand ('foo' invalid)</b>
+*X; // error
+<font color="blue">^~</font>
+<b>test.c:7:1: error: indirection requires pointer operand ('foo' invalid)</b>
+**Y; // error
+<font color="blue">^~~</font>
+<b>test.c:8:1: error: indirection requires pointer operand ('foo' invalid)</b>
+**Z; // error
+<font color="blue">^~~</font>
+</pre>
+
+<p>While this example is somewhat silly, it illustrates the point: we want to
+retain typedef information where possible, so that we can emit errors about
+"<tt>std::string</tt>" instead of "<tt>std::basic_string&lt;char, std:...</tt>".
+Doing this requires properly keeping typedef information (for example, the type
+of "X" is "foo", not "int"), and requires properly propagating it through the
+various operators (for example, the type of *Y is "foo", not "int").  In order
+to retain this information, the type of these expressions is an instance of the
+TypedefType class, which indicates that the type of these expressions is a
+typedef for foo.
+</p>
+
+<p>Representing types like this is great for diagnostics, because the
+user-specified type is always immediately available.  There are two problems
+with this: first, various semantic checks need to make judgements about the
+<em>actual structure</em> of a type, ignoring typdefs.  Second, we need an
+efficient way to query whether two types are structurally identical to each
+other, ignoring typedefs.  The solution to both of these problems is the idea of
+canonical types.</p>
+
+<!-- =============== -->
+<h4>Canonical Types</h4>
+<!-- =============== -->
+
+<p>Every instance of the Type class contains a canonical type pointer.  For
+simple types with no typedefs involved (e.g. "<tt>int</tt>", "<tt>int*</tt>",
+"<tt>int**</tt>"), the type just points to itself.  For types that have a
+typedef somewhere in their structure (e.g. "<tt>foo</tt>", "<tt>foo*</tt>",
+"<tt>foo**</tt>", "<tt>bar</tt>"), the canonical type pointer points to their
+structurally equivalent type without any typedefs (e.g. "<tt>int</tt>",
+"<tt>int*</tt>", "<tt>int**</tt>", and "<tt>int*</tt>" respectively).</p>
+
+<p>This design provides a constant time operation (dereferencing the canonical
+type pointer) that gives us access to the structure of types.  For example,
+we can trivially tell that "bar" and "foo*" are the same type by dereferencing
+their canonical type pointers and doing a pointer comparison (they both point
+to the single "<tt>int*</tt>" type).</p>
+
+<p>Canonical types and typedef types bring up some complexities that must be
+carefully managed.  Specifically, the "isa/cast/dyncast" operators generally
+shouldn't be used in code that is inspecting the AST.  For example, when type
+checking the indirection operator (unary '*' on a pointer), the type checker
+must verify that the operand has a pointer type.  It would not be correct to
+check that with "<tt>isa&lt;PointerType&gt;(SubExpr-&gt;getType())</tt>",
+because this predicate would fail if the subexpression had a typedef type.</p>
+
+<p>The solution to this problem are a set of helper methods on Type, used to
+check their properties.  In this case, it would be correct to use
+"<tt>SubExpr-&gt;getType()-&gt;isPointerType()</tt>" to do the check.  This
+predicate will return true if the <em>canonical type is a pointer</em>, which is
+true any time the type is structurally a pointer type.  The only hard part here
+is remembering not to use the <tt>isa/cast/dyncast</tt> operations.</p>
+
+<p>The second problem we face is how to get access to the pointer type once we
+know it exists.  To continue the example, the result type of the indirection
+operator is the pointee type of the subexpression.  In order to determine the
+type, we need to get the instance of PointerType that best captures the typedef
+information in the program.  If the type of the expression is literally a
+PointerType, we can return that, otherwise we have to dig through the
+typedefs to find the pointer type.  For example, if the subexpression had type
+"<tt>foo*</tt>", we could return that type as the result.  If the subexpression
+had type "<tt>bar</tt>", we want to return "<tt>foo*</tt>" (note that we do
+<em>not</em> want "<tt>int*</tt>").  In order to provide all of this, Type has
+a getAsPointerType() method that checks whether the type is structurally a
+PointerType and, if so, returns the best one.  If not, it returns a null
+pointer.</p>
+
+<p>This structure is somewhat mystical, but after meditating on it, it will 
+make sense to you :).</p>
+
+<!-- ======================================================================= -->
+<h3 id="QualType">The QualType class</h3>
+<!-- ======================================================================= -->
+
+<p>The QualType class is designed as a trivial value class that is small,
+passed by-value and is efficient to query.  The idea of QualType is that it
+stores the type qualifiers (const, volatile, restrict) separately from the types
+themselves: QualType is conceptually a pair of "Type*" and bits for the type
+qualifiers.</p>
+
+<p>By storing the type qualifiers as bits in the conceptual pair, it is
+extremely efficient to get the set of qualifiers on a QualType (just return the
+field of the pair), add a type qualifier (which is a trivial constant-time
+operation that sets a bit), and remove one or more type qualifiers (just return
+a QualType with the bitfield set to empty).</p>
+
+<p>Further, because the bits are stored outside of the type itself, we do not
+need to create duplicates of types with different sets of qualifiers (i.e. there
+is only a single heap allocated "int" type: "const int" and "volatile const int"
+both point to the same heap allocated "int" type).  This reduces the heap size
+used to represent bits and also means we do not have to consider qualifiers when
+uniquing types (<a href="#Type">Type</a> does not even contain qualifiers).</p>
+
+<p>In practice, on hosts where it is safe, the 3 type qualifiers are stored in
+the low bit of the pointer to the Type object.  This means that QualType is
+exactly the same size as a pointer, and this works fine on any system where
+malloc'd objects are at least 8 byte aligned.</p>
+
+<!-- ======================================================================= -->
+<h3 id="DeclarationName">Declaration names</h3>
+<!-- ======================================================================= -->
+
+<p>The <tt>DeclarationName</tt> class represents the name of a
+  declaration in Clang. Declarations in the C family of languages can
+  take several different forms. Most declarations are named by 
+  simple identifiers, e.g., "<code>f</code>" and "<code>x</code>" in
+  the function declaration <code>f(int x)</code>. In C++, declaration
+  names can also name class constructors ("<code>Class</code>"
+  in <code>struct Class { Class(); }</code>), class destructors
+  ("<code>~Class</code>"), overloaded operator names ("operator+"),
+  and conversion functions ("<code>operator void const *</code>"). In
+  Objective-C, declaration names can refer to the names of Objective-C
+  methods, which involve the method name and the parameters,
+  collectively called a <i>selector</i>, e.g.,
+  "<code>setWidth:height:</code>". Since all of these kinds of
+  entities - variables, functions, Objective-C methods, C++
+  constructors, destructors, and operators - are represented as
+  subclasses of Clang's common <code>NamedDecl</code>
+  class, <code>DeclarationName</code> is designed to efficiently
+  represent any kind of name.</p>
+
+<p>Given
+  a <code>DeclarationName</code> <code>N</code>, <code>N.getNameKind()</code>
+  will produce a value that describes what kind of name <code>N</code>
+  stores. There are 8 options (all of the names are inside
+  the <code>DeclarationName</code> class)</p>
+<dl>
+  <dt>Identifier</dt>
+  <dd>The name is a simple
+  identifier. Use <code>N.getAsIdentifierInfo()</code> to retrieve the
+  corresponding <code>IdentifierInfo*</code> pointing to the actual
+  identifier. Note that C++ overloaded operators (e.g.,
+  "<code>operator+</code>") are represented as special kinds of
+  identifiers. Use <code>IdentifierInfo</code>'s <code>getOverloadedOperatorID</code>
+  function to determine whether an identifier is an overloaded
+  operator name.</dd>
+
+  <dt>ObjCZeroArgSelector, ObjCOneArgSelector,
+  ObjCMultiArgSelector</dt>
+  <dd>The name is an Objective-C selector, which can be retrieved as a
+    <code>Selector</code> instance
+    via <code>N.getObjCSelector()</code>. The three possible name
+    kinds for Objective-C reflect an optimization within
+    the <code>DeclarationName</code> class: both zero- and
+    one-argument selectors are stored as a
+    masked <code>IdentifierInfo</code> pointer, and therefore require
+    very little space, since zero- and one-argument selectors are far
+    more common than multi-argument selectors (which use a different
+    structure).</dd>
+
+  <dt>CXXConstructorName</dt>
+  <dd>The name is a C++ constructor
+    name. Use <code>N.getCXXNameType()</code> to retrieve
+    the <a href="#QualType">type</a> that this constructor is meant to
+    construct. The type is always the canonical type, since all
+    constructors for a given type have the same name.</dd>
+
+  <dt>CXXDestructorName</dt>
+  <dd>The name is a C++ destructor
+    name. Use <code>N.getCXXNameType()</code> to retrieve
+    the <a href="#QualType">type</a> whose destructor is being
+    named. This type is always a canonical type.</dd>
+
+  <dt>CXXConversionFunctionName</dt>
+  <dd>The name is a C++ conversion function. Conversion functions are
+  named according to the type they convert to, e.g., "<code>operator void
+      const *</code>". Use <code>N.getCXXNameType()</code> to retrieve
+  the type that this conversion function converts to. This type is
+    always a canonical type.</dd>
+
+  <dt>CXXOperatorName</dt>
+  <dd>The name is a C++ overloaded operator name. Overloaded operators
+  are named according to their spelling, e.g.,
+  "<code>operator+</code>" or "<code>operator new
+  []</code>". Use <code>N.getCXXOverloadedOperator()</code> to
+  retrieve the overloaded operator (a value of
+    type <code>OverloadedOperatorKind</code>).</dd>
+</dl>
+
+<p><code>DeclarationName</code>s are cheap to create, copy, and
+  compare. They require only a single pointer's worth of storage in
+  the common cases (identifiers, zero-
+  and one-argument Objective-C selectors) and use dense, uniqued
+  storage for the other kinds of
+  names. Two <code>DeclarationName</code>s can be compared for
+  equality (<code>==</code>, <code>!=</code>) using a simple bitwise
+  comparison, can be ordered
+  with <code>&lt;</code>, <code>&gt;</code>, <code>&lt;=</code>,
+  and <code>&gt;=</code> (which provide a lexicographical ordering for
+  normal identifiers but an unspecified ordering for other kinds of
+  names), and can be placed into LLVM <code>DenseMap</code>s
+  and <code>DenseSet</code>s.</p>
+
+<p><code>DeclarationName</code> instances can be created in different
+  ways depending on what kind of name the instance will store. Normal
+  identifiers (<code>IdentifierInfo</code> pointers) and Objective-C selectors
+  (<code>Selector</code>) can be implicitly converted
+  to <code>DeclarationName</code>s. Names for C++ constructors,
+  destructors, conversion functions, and overloaded operators can be retrieved from
+  the <code>DeclarationNameTable</code>, an instance of which is
+  available as <code>ASTContext::DeclarationNames</code>. The member
+  functions <code>getCXXConstructorName</code>, <code>getCXXDestructorName</code>,
+  <code>getCXXConversionFunctionName</code>, and <code>getCXXOperatorName</code>, respectively,
+  return <code>DeclarationName</code> instances for the four kinds of
+  C++ special function names.</p>
+
+<!-- ======================================================================= -->
+<h3 id="DeclContext">Declaration contexts</h3>
+<!-- ======================================================================= -->
+<p>Every declaration in a program exists within some <i>declaration
+    context</i>, such as a translation unit, namespace, class, or
+    function. Declaration contexts in Clang are represented by
+    the <code>DeclContext</code> class, from which the various
+  declaration-context AST nodes
+  (<code>TranslationUnitDecl</code>, <code>NamespaceDecl</code>, <code>RecordDecl</code>, <code>FunctionDecl</code>,
+  etc.) will derive. The <code>DeclContext</code> class provides
+  several facilities common to each declaration context:</p>
+<dl>
+  <dt>Source-centric vs. Semantics-centric View of Declarations</dt>
+  <dd><code>DeclContext</code> provides two views of the declarations
+  stored within a declaration context. The source-centric view
+  accurately represents the program source code as written, including
+  multiple declarations of entities where present (see the
+    section <a href="#Redeclarations">Redeclarations and
+  Overloads</a>), while the semantics-centric view represents the
+  program semantics. The two views are kept synchronized by semantic
+  analysis while the ASTs are being constructed.</dd>
+
+  <dt>Storage of declarations within that context</dt>
+  <dd>Every declaration context can contain some number of
+    declarations. For example, a C++ class (represented
+    by <code>RecordDecl</code>) contains various member functions,
+    fields, nested types, and so on. All of these declarations will be
+    stored within the <code>DeclContext</code>, and one can iterate
+    over the declarations via
+    [<code>DeclContext::decls_begin()</code>, 
+    <code>DeclContext::decls_end()</code>). This mechanism provides
+    the source-centric view of declarations in the context.</dd>
+
+  <dt>Lookup of declarations within that context</dt>
+  <dd>The <code>DeclContext</code> structure provides efficient name
+    lookup for names within that declaration context. For example,
+    if <code>N</code> is a namespace we can look for the
+    name <code>N::f</code>
+    using <code>DeclContext::lookup</code>. The lookup itself is
+    based on a lazily-constructed array (for declaration contexts
+    with a small number of declarations) or hash table (for
+    declaration contexts with more declarations). The lookup
+    operation provides the semantics-centric view of the declarations
+    in the context.</dd>
+
+  <dt>Ownership of declarations</dt>
+  <dd>The <code>DeclContext</code> owns all of the declarations that
+  were declared within its declaration context, and is responsible
+  for the management of their memory as well as their
+  (de-)serialization.</dd>
+</dl>
+
+<p>All declarations are stored within a declaration context, and one
+  can query
+  information about the context in which each declaration lives. One
+  can retrieve the <code>DeclContext</code> that contains a
+  particular <code>Decl</code>
+  using <code>Decl::getDeclContext</code>. However, see the
+  section <a href="#LexicalAndSemanticContexts">Lexical and Semantic
+  Contexts</a> for more information about how to interpret this
+  context information.</p>
+
+<h4 id="Redeclarations">Redeclarations and Overloads</h4>
+<p>Within a translation unit, it is common for an entity to be
+declared several times. For example, we might declare a function "f"
+  and then later re-declare it as part of an inlined definition:</p>
+
+<pre>
+void f(int x, int y, int z = 1);
+
+inline void f(int x, int y, int z) { /* ... */ }
+</pre>
+
+<p>The representation of "f" differs in the source-centric and
+  semantics-centric views of a declaration context. In the
+  source-centric view, all redeclarations will be present, in the
+  order they occurred in the source code, making 
+    this view suitable for clients that wish to see the structure of
+    the source code. In the semantics-centric view, only the most recent "f"
+  will be found by the lookup, since it effectively replaces the first
+  declaration of "f".</p>
+
+<p>In the semantics-centric view, overloading of functions is
+  represented explicitly. For example, given two declarations of a
+  function "g" that are overloaded, e.g.,</p>
+<pre>
+void g();
+void g(int);
+</pre>
+<p>the <code>DeclContext::lookup</code> operation will return
+  an <code>OverloadedFunctionDecl</code> that contains both
+  declarations of "g". Clients that perform semantic analysis on a
+  program that is not concerned with the actual source code will
+  primarily use this semantics-centric view.</p>
+
+<h4 id="LexicalAndSemanticContexts">Lexical and Semantic Contexts</h4>
+<p>Each declaration has two potentially different
+  declaration contexts: a <i>lexical</i> context, which corresponds to
+  the source-centric view of the declaration context, and
+  a <i>semantic</i> context, which corresponds to the
+  semantics-centric view. The lexical context is accessible
+  via <code>Decl::getLexicalDeclContext</code> while the
+  semantic context is accessible
+  via <code>Decl::getDeclContext</code>, both of which return
+  <code>DeclContext</code> pointers. For most declarations, the two
+  contexts are identical. For example:</p>
+
+<pre>
+class X {
+public:
+  void f(int x);
+};
+</pre>
+
+<p>Here, the semantic and lexical contexts of <code>X::f</code> are
+  the <code>DeclContext</code> associated with the
+  class <code>X</code> (itself stored as a <code>RecordDecl</code> AST
+  node). However, we can now define <code>X::f</code> out-of-line:</p>
+
+<pre>
+void X::f(int x = 17) { /* ... */ }
+</pre>
+
+<p>This definition of has different lexical and semantic
+  contexts. The lexical context corresponds to the declaration
+  context in which the actual declaration occurred in the source
+  code, e.g., the translation unit containing <code>X</code>. Thus,
+  this declaration of <code>X::f</code> can be found by traversing
+  the declarations provided by
+  [<code>decls_begin()</code>, <code>decls_end()</code>) in the
+  translation unit.</p>
+
+<p>The semantic context of <code>X::f</code> corresponds to the
+  class <code>X</code>, since this member function is (semantically) a
+  member of <code>X</code>. Lookup of the name <code>f</code> into
+  the <code>DeclContext</code> associated with <code>X</code> will
+  then return the definition of <code>X::f</code> (including
+  information about the default argument).</p>
+
+<h4 id="TransparentContexts">Transparent Declaration Contexts</h4>
+<p>In C and C++, there are several contexts in which names that are
+  logically declared inside another declaration will actually "leak"
+  out into the enclosing scope from the perspective of name
+  lookup. The most obvious instance of this behavior is in
+  enumeration types, e.g.,</p>
+<pre>
+enum Color {
+  Red, 
+  Green,
+  Blue
+};
+</pre>
+
+<p>Here, <code>Color</code> is an enumeration, which is a declaration
+  context that contains the
+  enumerators <code>Red</code>, <code>Green</code>,
+  and <code>Blue</code>. Thus, traversing the list of declarations
+  contained in the enumeration <code>Color</code> will
+  yield <code>Red</code>, <code>Green</code>,
+  and <code>Blue</code>. However, outside of the scope
+  of <code>Color</code> one can name the enumerator <code>Red</code>
+  without qualifying the name, e.g.,</p>
+
+<pre>
+Color c = Red;
+</pre>
+
+<p>There are other entities in C++ that provide similar behavior. For
+  example, linkage specifications that use curly braces:</p>
+
+<pre>
+extern "C" {
+  void f(int);
+  void g(int);
+}
+// f and g are visible here
+</pre>
+
+<p>For source-level accuracy, we treat the linkage specification and
+  enumeration type as a
+  declaration context in which its enclosed declarations ("Red",
+  "Green", and "Blue"; "f" and "g")
+  are declared. However, these declarations are visible outside of the
+  scope of the declaration context.</p>
+
+<p>These language features (and several others, described below) have
+  roughly the same set of 
+  requirements: declarations are declared within a particular lexical
+  context, but the declarations are also found via name lookup in
+  scopes enclosing the declaration itself. This feature is implemented
+  via <i>transparent</i> declaration contexts
+  (see <code>DeclContext::isTransparentContext()</code>), whose
+  declarations are visible in the nearest enclosing non-transparent
+  declaration context. This means that the lexical context of the
+  declaration (e.g., an enumerator) will be the
+  transparent <code>DeclContext</code> itself, as will the semantic
+  context, but the declaration will be visible in every outer context
+  up to and including the first non-transparent declaration context (since
+  transparent declaration contexts can be nested).</p>
+
+<p>The transparent <code>DeclContexts</code> are:</p>
+<ul>
+  <li>Enumerations (but not C++0x "scoped enumerations"):
+    <pre>
+enum Color { 
+  Red, 
+  Green, 
+  Blue 
+};
+// Red, Green, and Blue are in scope
+  </pre></li>
+  <li>C++ linkage specifications:
+  <pre>
+extern "C" {
+  void f(int);
+  void g(int);
+}
+// f and g are in scope
+  </pre></li>
+  <li>Anonymous unions and structs:
+    <pre>
+struct LookupTable {
+  bool IsVector;
+  union {
+    std::vector&lt;Item&gt; *Vector;
+    std::set&lt;Item&gt; *Set;
+  };
+};
+
+LookupTable LT;
+LT.Vector = 0; // Okay: finds Vector inside the unnamed union
+    </pre>
+  </li>
+  <li>C++0x inline namespaces:
+<pre>
+namespace mylib {
+  inline namespace debug {
+    class X;
+  }
+}
+mylib::X *xp; // okay: mylib::X refers to mylib::debug::X
+</pre>
+</li>
+</ul>
+
+
+<h4 id="MultiDeclContext">Multiply-Defined Declaration Contexts</h4>
+<p>C++ namespaces have the interesting--and, so far, unique--property that 
+the namespace can be defined multiple times, and the declarations
+provided by each namespace definition are effectively merged (from
+the semantic point of view). For example, the following two code
+snippets are semantically indistinguishable:</p>
+<pre>
+// Snippet #1:
+namespace N {
+  void f();
+}
+namespace N {
+  void f(int);
+}
+
+// Snippet #2:
+namespace N {
+  void f();
+  void f(int);
+}
+</pre>
+
+<p>In Clang's representation, the source-centric view of declaration
+  contexts will actually have two separate <code>NamespaceDecl</code>
+  nodes in Snippet #1, each of which is a declaration context that
+  contains a single declaration of "f". However, the semantics-centric
+  view provided by name lookup into the namespace <code>N</code> for
+  "f" will return an <code>OverloadedFunctionDecl</code> that contains
+  both declarations of "f".</p>
+
+<p><code>DeclContext</code> manages multiply-defined declaration
+  contexts internally. The
+  function <code>DeclContext::getPrimaryContext</code> retrieves the
+  "primary" context for a given <code>DeclContext</code> instance,
+  which is the <code>DeclContext</code> responsible for maintaining
+  the lookup table used for the semantics-centric view. Given the
+  primary context, one can follow the chain
+  of <code>DeclContext</code> nodes that define additional
+  declarations via <code>DeclContext::getNextContext</code>. Note that
+  these functions are used internally within the lookup and insertion
+  methods of the <code>DeclContext</code>, so the vast majority of
+  clients can ignore them.</p>
+
+<!-- ======================================================================= -->
+<h3 id="CFG">The <tt>CFG</tt> class</h3>
+<!-- ======================================================================= -->
+
+<p>The <tt>CFG</tt> class is designed to represent a source-level
+control-flow graph for a single statement (<tt>Stmt*</tt>).  Typically
+instances of <tt>CFG</tt> are constructed for function bodies (usually
+an instance of <tt>CompoundStmt</tt>), but can also be instantiated to
+represent the control-flow of any class that subclasses <tt>Stmt</tt>,
+which includes simple expressions.  Control-flow graphs are especially
+useful for performing
+<a href="http://en.wikipedia.org/wiki/Data_flow_analysis#Sensitivities">flow-
+or path-sensitive</a> program analyses on a given function.</p>
+
+<!-- ============ -->
+<h4>Basic Blocks</h4>
+<!-- ============ -->
+
+<p>Concretely, an instance of <tt>CFG</tt> is a collection of basic
+blocks.  Each basic block is an instance of <tt>CFGBlock</tt>, which
+simply contains an ordered sequence of <tt>Stmt*</tt> (each referring
+to statements in the AST).  The ordering of statements within a block
+indicates unconditional flow of control from one statement to the
+next.  <a href="#ConditionalControlFlow">Conditional control-flow</a>
+is represented using edges between basic blocks.  The statements
+within a given <tt>CFGBlock</tt> can be traversed using
+the <tt>CFGBlock::*iterator</tt> interface.</p>
+
+<p>
+A <tt>CFG</tt> object owns the instances of <tt>CFGBlock</tt> within
+the control-flow graph it represents.  Each <tt>CFGBlock</tt> within a
+CFG is also uniquely numbered (accessible
+via <tt>CFGBlock::getBlockID()</tt>).  Currently the number is
+based on the ordering the blocks were created, but no assumptions
+should be made on how <tt>CFGBlock</tt>s are numbered other than their
+numbers are unique and that they are numbered from 0..N-1 (where N is
+the number of basic blocks in the CFG).</p>
+
+<!-- ===================== -->
+<h4>Entry and Exit Blocks</h4>
+<!-- ===================== -->
+
+Each instance of <tt>CFG</tt> contains two special blocks:
+an <i>entry</i> block (accessible via <tt>CFG::getEntry()</tt>), which
+has no incoming edges, and an <i>exit</i> block (accessible
+via <tt>CFG::getExit()</tt>), which has no outgoing edges.  Neither
+block contains any statements, and they serve the role of providing a
+clear entrance and exit for a body of code such as a function body.
+The presence of these empty blocks greatly simplifies the
+implementation of many analyses built on top of CFGs.
+
+<!-- ===================================================== -->
+<h4 id ="ConditionalControlFlow">Conditional Control-Flow</h4>
+<!-- ===================================================== -->
+
+<p>Conditional control-flow (such as those induced by if-statements
+and loops) is represented as edges between <tt>CFGBlock</tt>s.
+Because different C language constructs can induce control-flow,
+each <tt>CFGBlock</tt> also records an extra <tt>Stmt*</tt> that
+represents the <i>terminator</i> of the block.  A terminator is simply
+the statement that caused the control-flow, and is used to identify
+the nature of the conditional control-flow between blocks.  For
+example, in the case of an if-statement, the terminator refers to
+the <tt>IfStmt</tt> object in the AST that represented the given
+branch.</p>
+
+<p>To illustrate, consider the following code example:</p>
+
+<code>
+int foo(int x) {<br>
+&nbsp;&nbsp;x = x + 1;<br>
+<br>
+&nbsp;&nbsp;if (x > 2) x++;<br>
+&nbsp;&nbsp;else {<br>
+&nbsp;&nbsp;&nbsp;&nbsp;x += 2;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;x *= 2;<br>
+&nbsp;&nbsp;}<br>
+<br>
+&nbsp;&nbsp;return x;<br>
+}
+</code>
+
+<p>After invoking the parser+semantic analyzer on this code fragment,
+the AST of the body of <tt>foo</tt> is referenced by a
+single <tt>Stmt*</tt>.  We can then construct an instance
+of <tt>CFG</tt> representing the control-flow graph of this function
+body by single call to a static class method:</p>
+
+<code>
+&nbsp;&nbsp;Stmt* FooBody = ...<br>
+&nbsp;&nbsp;CFG*  FooCFG = <b>CFG::buildCFG</b>(FooBody);
+</code>
+
+<p>It is the responsibility of the caller of <tt>CFG::buildCFG</tt>
+to <tt>delete</tt> the returned <tt>CFG*</tt> when the CFG is no
+longer needed.</p>
+
+<p>Along with providing an interface to iterate over
+its <tt>CFGBlock</tt>s, the <tt>CFG</tt> class also provides methods
+that are useful for debugging and visualizing CFGs.  For example, the
+method
+<tt>CFG::dump()</tt> dumps a pretty-printed version of the CFG to
+standard error.  This is especially useful when one is using a
+debugger such as gdb.  For example, here is the output
+of <tt>FooCFG->dump()</tt>:</p>
+
+<code>
+&nbsp;[ B5 (ENTRY) ]<br>
+&nbsp;&nbsp;&nbsp;&nbsp;Predecessors (0):<br>
+&nbsp;&nbsp;&nbsp;&nbsp;Successors (1): B4<br>
+<br>
+&nbsp;[ B4 ]<br>
+&nbsp;&nbsp;&nbsp;&nbsp;1: x = x + 1<br>
+&nbsp;&nbsp;&nbsp;&nbsp;2: (x > 2)<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<b>T: if [B4.2]</b><br>
+&nbsp;&nbsp;&nbsp;&nbsp;Predecessors (1): B5<br>
+&nbsp;&nbsp;&nbsp;&nbsp;Successors (2): B3 B2<br>
+<br>
+&nbsp;[ B3 ]<br>
+&nbsp;&nbsp;&nbsp;&nbsp;1: x++<br>
+&nbsp;&nbsp;&nbsp;&nbsp;Predecessors (1): B4<br>
+&nbsp;&nbsp;&nbsp;&nbsp;Successors (1): B1<br>
+<br>
+&nbsp;[ B2 ]<br>
+&nbsp;&nbsp;&nbsp;&nbsp;1: x += 2<br>
+&nbsp;&nbsp;&nbsp;&nbsp;2: x *= 2<br>
+&nbsp;&nbsp;&nbsp;&nbsp;Predecessors (1): B4<br>
+&nbsp;&nbsp;&nbsp;&nbsp;Successors (1): B1<br>
+<br>
+&nbsp;[ B1 ]<br>
+&nbsp;&nbsp;&nbsp;&nbsp;1: return x;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;Predecessors (2): B2 B3<br>
+&nbsp;&nbsp;&nbsp;&nbsp;Successors (1): B0<br>
+<br>
+&nbsp;[ B0 (EXIT) ]<br>
+&nbsp;&nbsp;&nbsp;&nbsp;Predecessors (1): B1<br>
+&nbsp;&nbsp;&nbsp;&nbsp;Successors (0):
+</code>
+
+<p>For each block, the pretty-printed output displays for each block
+the number of <i>predecessor</i> blocks (blocks that have outgoing
+control-flow to the given block) and <i>successor</i> blocks (blocks
+that have control-flow that have incoming control-flow from the given
+block).  We can also clearly see the special entry and exit blocks at
+the beginning and end of the pretty-printed output.  For the entry
+block (block B5), the number of predecessor blocks is 0, while for the
+exit block (block B0) the number of successor blocks is 0.</p>
+
+<p>The most interesting block here is B4, whose outgoing control-flow
+represents the branching caused by the sole if-statement
+in <tt>foo</tt>.  Of particular interest is the second statement in
+the block, <b><tt>(x > 2)</tt></b>, and the terminator, printed
+as <b><tt>if [B4.2]</tt></b>.  The second statement represents the
+evaluation of the condition of the if-statement, which occurs before
+the actual branching of control-flow.  Within the <tt>CFGBlock</tt>
+for B4, the <tt>Stmt*</tt> for the second statement refers to the
+actual expression in the AST for <b><tt>(x > 2)</tt></b>.  Thus
+pointers to subclasses of <tt>Expr</tt> can appear in the list of
+statements in a block, and not just subclasses of <tt>Stmt</tt> that
+refer to proper C statements.</p>
+
+<p>The terminator of block B4 is a pointer to the <tt>IfStmt</tt>
+object in the AST.  The pretty-printer outputs <b><tt>if
+[B4.2]</tt></b> because the condition expression of the if-statement
+has an actual place in the basic block, and thus the terminator is
+essentially
+<i>referring</i> to the expression that is the second statement of
+block B4 (i.e., B4.2).  In this manner, conditions for control-flow
+(which also includes conditions for loops and switch statements) are
+hoisted into the actual basic block.</p>
+
+<!-- ===================== -->
+<!-- <h4>Implicit Control-Flow</h4> -->
+<!-- ===================== -->
+
+<!--
+<p>A key design principle of the <tt>CFG</tt> class was to not require
+any transformations to the AST in order to represent control-flow.
+Thus the <tt>CFG</tt> does not perform any "lowering" of the
+statements in an AST: loops are not transformed into guarded gotos,
+short-circuit operations are not converted to a set of if-statements,
+and so on.</p>
+-->
+
+
+<!-- ======================================================================= -->
+<h3 id="Constants">Constant Folding in the Clang AST</h3>
+<!-- ======================================================================= -->
+
+<p>There are several places where constants and constant folding matter a lot to
+the Clang front-end.  First, in general, we prefer the AST to retain the source
+code as close to how the user wrote it as possible.  This means that if they
+wrote "5+4", we want to keep the addition and two constants in the AST, we don't
+want to fold to "9".  This means that constant folding in various ways turns
+into a tree walk that needs to handle the various cases.</p>
+
+<p>However, there are places in both C and C++ that require constants to be
+folded.  For example, the C standard defines what an "integer constant
+expression" (i-c-e) is with very precise and specific requirements.  The
+language then requires i-c-e's in a lot of places (for example, the size of a
+bitfield, the value for a case statement, etc).  For these, we have to be able
+to constant fold the constants, to do semantic checks (e.g. verify bitfield size
+is non-negative and that case statements aren't duplicated).  We aim for Clang
+to be very pedantic about this, diagnosing cases when the code does not use an
+i-c-e where one is required, but accepting the code unless running with
+<tt>-pedantic-errors</tt>.</p>
+
+<p>Things get a little bit more tricky when it comes to compatibility with
+real-world source code.  Specifically, GCC has historically accepted a huge
+superset of expressions as i-c-e's, and a lot of real world code depends on this
+unfortuate accident of history (including, e.g., the glibc system headers).  GCC
+accepts anything its "fold" optimizer is capable of reducing to an integer
+constant, which means that the definition of what it accepts changes as its
+optimizer does.  One example is that GCC accepts things like "case X-X:" even
+when X is a variable, because it can fold this to 0.</p>
+
+<p>Another issue are how constants interact with the extensions we support, such
+as __builtin_constant_p, __builtin_inf, __extension__ and many others.  C99
+obviously does not specify the semantics of any of these extensions, and the
+definition of i-c-e does not include them.  However, these extensions are often
+used in real code, and we have to have a way to reason about them.</p>
+
+<p>Finally, this is not just a problem for semantic analysis.  The code
+generator and other clients have to be able to fold constants (e.g. to
+initialize global variables) and has to handle a superset of what C99 allows.
+Further, these clients can benefit from extended information.  For example, we
+know that "foo()||1" always evaluates to true, but we can't replace the
+expression with true because it has side effects.</p>
+
+<!-- ======================= -->
+<h4>Implementation Approach</h4>
+<!-- ======================= -->
+
+<p>After trying several different approaches, we've finally converged on a
+design (Note, at the time of this writing, not all of this has been implemented,
+consider this a design goal!).  Our basic approach is to define a single
+recursive method evaluation method (<tt>Expr::Evaluate</tt>), which is
+implemented in <tt>AST/ExprConstant.cpp</tt>.  Given an expression with 'scalar'
+type (integer, fp, complex, or pointer) this method returns the following
+information:</p>
+
+<ul>
+<li>Whether the expression is an integer constant expression, a general
+    constant that was folded but has no side effects, a general constant that
+    was folded but that does have side effects, or an uncomputable/unfoldable
+    value.
+</li>
+<li>If the expression was computable in any way, this method returns the APValue
+    for the result of the expression.</li>
+<li>If the expression is not evaluatable at all, this method returns
+    information on one of the problems with the expression.  This includes a
+    SourceLocation for where the problem is, and a diagnostic ID that explains
+    the problem.  The diagnostic should be have ERROR type.</li>
+<li>If the expression is not an integer constant expression, this method returns
+    information on one of the problems with the expression.  This includes a
+    SourceLocation for where the problem is, and a diagnostic ID that explains
+    the problem.  The diagnostic should be have EXTENSION type.</li>
+</ul>
+
+<p>This information gives various clients the flexibility that they want, and we
+will eventually have some helper methods for various extensions.  For example,
+Sema should have a <tt>Sema::VerifyIntegerConstantExpression</tt> method, which
+calls Evaluate on the expression.  If the expression is not foldable, the error
+is emitted, and it would return true.  If the expression is not an i-c-e, the
+EXTENSION diagnostic is emitted.  Finally it would return false to indicate that
+the AST is ok.</p>
+
+<p>Other clients can use the information in other ways, for example, codegen can
+just use expressions that are foldable in any way.</p>
+
+<!-- ========== -->
+<h4>Extensions</h4>
+<!-- ========== -->
+
+<p>This section describes how some of the various extensions Clang supports 
+interacts with constant evaluation:</p>
+
+<ul>
+<li><b><tt>__extension__</tt></b>: The expression form of this extension causes
+    any evaluatable subexpression to be accepted as an integer constant
+    expression.</li>
+<li><b><tt>__builtin_constant_p</tt></b>: This returns true (as a integer
+    constant expression) if the operand is any evaluatable constant.  As a
+    special case, if <tt>__builtin_constant_p</tt> is the (potentially
+    parenthesized) condition of a conditional operator expression ("?:"), only
+    the true side of the conditional operator is considered, and it is evaluated
+    with full constant folding.</li>
+<li><b><tt>__builtin_choose_expr</tt></b>: The condition is required to be an
+    integer constant expression, but we accept any constant as an "extension of
+    an extension".  This only evaluates one operand depending on which way the
+    condition evaluates.</li>
+<li><b><tt>__builtin_classify_type</tt></b>: This always returns an integer
+    constant expression.</li>
+<li><b><tt>__builtin_inf,nan,..</tt></b>: These are treated just like a
+    floating-point literal.</li>
+<li><b><tt>__builtin_abs,copysign,..</tt></b>: These are constant folded as
+    general constant expressions.</li>
+</ul>
+
+
+
+
+</div>
+</body>
+</html>
diff --git a/docs/LanguageExtensions.html b/docs/LanguageExtensions.html
new file mode 100644
index 0000000..9779c3f
--- /dev/null
+++ b/docs/LanguageExtensions.html
@@ -0,0 +1,621 @@
+<html>
+<head>
+<title>Clang Language Extensions</title>
+<link type="text/css" rel="stylesheet" href="../menu.css" />
+<link type="text/css" rel="stylesheet" href="../content.css" />
+<style type="text/css">
+td {
+	vertical-align: top;
+}
+</style>
+</head>
+<body>
+
+<!--#include virtual="../menu.html.incl"-->
+
+<div id="content">
+
+<h1>Clang Language Extensions</h1>
+
+<ul>
+<li><a href="#intro">Introduction</a></li>
+<li><a href="#feature_check">Feature Checking Macros</a></li>
+<li><a href="#has_include">Include File Checking Macros</a></li>
+<li><a href="#builtinmacros">Builtin Macros</a></li>
+<li><a href="#vectors">Vectors and Extended Vectors</a></li>
+<li><a href="#checking_language_features">Checks for Standard Language Features</a></li>
+  <ul>
+  <li><a href="#cxx_exceptions">C++ exceptions</a></li>
+  <li><a href="#cxx_rtti">C++ RTTI</a></li>
+  </ul>
+<li><a href="#checking_upcoming_features">Checks for Upcoming Standard Language Features</a></li>
+  <ul>
+  <li><a href="#cxx_attributes">C++0x attributes</a></li>
+  <li><a href="#cxx_decltype">C++0x <tt>decltype()</tt></a></li>
+  <li><a href="#cxx_deleted_functions">C++0x deleted functions</a></li>
+  <li><a href="#cxx_concepts">C++ TR concepts</a></li>
+  <li><a href="#cxx_lambdas">C++0x lambdas</a></li>
+  <li><a href="#cxx_nullptr">C++0x nullptr</a></li>
+  <li><a href="#cxx_rvalue_references">C++0x rvalue references</a></li>
+  <li><a href="#cxx_static_assert">C++0x <tt>static_assert()</tt></a></li>
+  <li><a href="#cxx_auto_type">C++0x type inference</a></li>
+  <li><a href="#cxx_variadic_templates">C++0x variadic templates</a></li>
+  </ul>
+<li><a href="#blocks">Blocks</a></li>
+<li><a href="#overloading-in-c">Function Overloading in C</a></li>
+<li><a href="#builtins">Builtin Functions</a>
+  <ul>
+  <li><a href="#__builtin_shufflevector">__builtin_shufflevector</a></li>
+  <li><a href="#__builtin_unreachable">__builtin_unreachable</a></li>
+  </ul>
+</li>
+<li><a href="#targetspecific">Target-Specific Extensions</a>
+  <ul>
+  <li><a href="#x86-specific">X86/X86-64 Language Extensions</a></li>
+  </ul>
+</li>
+<li><a href="#analyzerspecific">Static Analysis-Specific Extensions</a>
+  <ul>
+    <li><a href="#analyzerattributes">Analyzer Attributes</a></li>
+  </ul>
+</li>
+</ul>
+
+<!-- ======================================================================= -->
+<h2 id="intro">Introduction</h2>
+<!-- ======================================================================= -->
+
+<p>This document describes the language extensions provided by Clang.  In
+addition to the language extensions listed here, Clang aims to support a broad
+range of GCC extensions.  Please see the <a 
+href="http://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html">GCC manual</a> for
+more information on these extensions.</p>
+
+<!-- ======================================================================= -->
+<h2 id="feature_check">Feature Checking Macros</h2>
+<!-- ======================================================================= -->
+
+<p>Language extensions can be very useful, but only if you know you can depend
+on them.  In order to allow fine-grain features checks, we support two builtin
+function-like macros.  This allows you to directly test for a feature in your
+code without having to resort to something like autoconf or fragile "compiler
+version checks".</p>
+
+<!-- ======================================================================= -->
+<h3 id="__has_builtin">__has_builtin</h3>
+<!-- ======================================================================= -->
+
+<p>This function-like macro takes a single identifier argument that is the name
+of a builtin function.  It evaluates to 1 if the builtin is supported or 0 if
+not.  It can be used like this:</p>
+
+<blockquote>
+<pre>
+#ifndef __has_builtin         // Optional of course.
+  #define __has_builtin(x) 0  // Compatibility with non-clang compilers.
+#endif
+
+...
+#if __has_builtin(__builtin_trap)
+  __builtin_trap();
+#else
+  abort();
+#endif
+...
+</pre>
+</blockquote>
+
+
+<!-- ======================================================================= -->
+<h3 id="__has_feature">__has_feature</h3>
+<!-- ======================================================================= -->
+
+<p>This function-like macro takes a single identifier argument that is the name
+of a feature.  It evaluates to 1 if the feature is supported or 0 if not.  It
+can be used like this:</p>
+
+<blockquote>
+<pre>
+#ifndef __has_feature         // Optional of course.
+  #define __has_feature(x) 0  // Compatibility with non-clang compilers.
+#endif
+
+...
+#if __has_feature(attribute_overloadable) || \
+    __has_feature(blocks)
+...
+#endif
+...
+</pre>
+</blockquote>
+
+<p>The feature tag is described along with the language feature below.</p>
+
+<!-- ======================================================================= -->
+<h2 id="has_include">Include File Checking Macros</h2>
+<!-- ======================================================================= -->
+
+<p>Not all developments systems have the same include files.
+The <a href="#__has_include">__has_include</a> and
+<a href="#__has_include_next">__has_include_next</a> macros allow you to
+check for the existence of an include file before doing
+a possibly failing #include directive.</p>
+
+<!-- ======================================================================= -->
+<h3 id="__has_include">__has_include</h3>
+<!-- ======================================================================= -->
+
+<p>This function-like macro takes a single file name string argument that
+is the name of an include file.  It evaluates to 1 if the file can
+be found using the include paths, or 0 otherwise:</p>
+
+<blockquote>
+<pre>
+// Note the two possible file name string formats.
+#if __has_include("myinclude.h") && __has_include(&lt;stdint.h&gt;)
+# include "myinclude.h"
+#endif
+
+// To avoid problem with non-clang compilers not having this macro.
+#if defined(__has_include) && __has_include("myinclude.h")
+# include "myinclude.h"
+#endif
+</pre>
+</blockquote>
+
+<p>To test for this feature, use #if defined(__has_include).</p>
+
+<!-- ======================================================================= -->
+<h3 id="__has_include_next">__has_include_next</h3>
+<!-- ======================================================================= -->
+
+<p>This function-like macro takes a single file name string argument that
+is the name of an include file.  It is like __has_include except that it
+looks for the second instance of the given file found in the include
+paths.  It evaluates to 1 if the second instance of the file can
+be found using the include paths, or 0 otherwise:</p>
+
+<blockquote>
+<pre>
+// Note the two possible file name string formats.
+#if __has_include_next("myinclude.h") && __has_include_next(&lt;stdint.h&gt;)
+# include_next "myinclude.h"
+#endif
+
+// To avoid problem with non-clang compilers not having this macro.
+#if defined(__has_include_next) && __has_include_next("myinclude.h")
+# include_next "myinclude.h"
+#endif
+</pre>
+</blockquote>
+
+<p>Note that __has_include_next, like the GNU extension
+#include_next directive, is intended for use in headers only,
+and will issue a warning if used in the top-level compilation
+file.  A warning will also be issued if an absolute path
+is used in the file argument.</p>
+
+<!-- ======================================================================= -->
+<h2 id="builtinmacros">Builtin Macros</h2>
+<!-- ======================================================================= -->
+
+<p>__BASE_FILE__, __INCLUDE_LEVEL__, __TIMESTAMP__, __COUNTER__</p>
+
+<!-- ======================================================================= -->
+<h2 id="vectors">Vectors and Extended Vectors</h2>
+<!-- ======================================================================= -->
+
+<p>Supports the GCC vector extensions, plus some stuff like V[1].</p>
+
+<p>Also supports <tt>ext_vector</tt>, which additionally support for V.xyzw
+syntax and other tidbits as seen in OpenCL. An example is:</p>
+
+<blockquote>
+<pre>
+typedef float float4 <b>__attribute__((ext_vector_type(4)))</b>;
+typedef float float2 <b>__attribute__((ext_vector_type(2)))</b>;
+
+float4 foo(float2 a, float2 b) {
+  float4 c;
+  c.xz = a;
+  c.yw = b;
+  return c;
+}
+</blockquote>
+
+<p>Query for this feature with __has_feature(attribute_ext_vector_type).</p>
+
+<p>See also <a href="#__builtin_shufflevector">__builtin_shufflevector</a>.</p>
+
+<!-- ======================================================================= -->
+<h2 id="checking_language_features">Checks for Standard Language Features</h2>
+<!-- ======================================================================= -->
+
+<p>The <tt>__has_feature</tt> macro can be used to query if certain standard language features are
+enabled.  Those features are listed here.</p>
+
+<h3 id="cxx_exceptions">C++ exceptions</h3>
+
+<p>Use <tt>__has_feature(cxx_exceptions)</tt> to determine if C++ exceptions have been enabled. For
+example, compiling code with <tt>-fexceptions</tt> enables C++ exceptions.</p>
+
+<h3 id="cxx_rtti">C++ RTTI</h3>
+
+<p>Use <tt>__has_feature(cxx_rtti)</tt> to determine if C++ RTTI has been enabled. For example,
+compiling code with <tt>-fno-rtti</tt> disables the use of RTTI.</p>
+
+<!-- ======================================================================= -->
+<h2 id="checking_upcoming_features">Checks for Upcoming Standard Language Features</h2>
+<!-- ======================================================================= -->
+
+<p>The <tt>__has_feature</tt> macro can be used to query if certain upcoming
+standard language features are enabled.  Those features are listed here.</p>
+
+<p>Currently, all features listed here are slated for inclusion in the upcoming
+C++0x standard. As a result, all the features that clang supports are enabled
+with the <tt>-std=c++0x</tt> option when compiling C++ code. Features that are
+not yet implemented will be noted.</p>
+
+<h3 id="cxx_decltype">C++0x <tt>decltype()</tt></h3>
+
+<p>Use <tt>__has_feature(cxx_decltype)</tt> to determine if support for the
+<tt>decltype()</tt> specifier is enabled.</p>
+
+<h3 id="cxx_attributes">C++0x attributes</h3>
+
+<p>Use <tt>__has_feature(cxx_attributes)</tt> to determine if support for
+attribute parsing with C++0x's square bracket notation is enabled.
+
+<h3 id="cxx_deleted_functions">C++0x deleted functions</tt></h3>
+
+<p>Use <tt>__has_feature(cxx_deleted_functions)</tt> to determine if support for
+deleted function definitions (with <tt>= delete</tt>) is enabled.
+
+<h3 id="cxx_concepts">C++ TR concepts</h3>
+
+<p>Use <tt>__has_feature(cxx_concepts)</tt> to determine if support for
+concepts is enabled. clang does not currently implement this feature.
+
+<h3 id="cxx_lambdas">C++0x lambdas</h3>
+
+<p>Use <tt>__has_feature(cxx_lambdas)</tt> to determine if support for
+lambdas is enabled. clang does not currently implement this feature.
+
+<h3 id="cxx_nullptr">C++0x <tt>nullptr</tt></h3>
+
+<p>Use <tt>__has_feature(cxx_nullptr)</tt> to determine if support for
+<tt>nullptr</tt> is enabled. clang does not yet fully implement this feature.
+
+<h3 id="cxx_rvalue_references">C++0x rvalue references</tt></h3>
+
+<p>Use <tt>__has_feature(cxx_rvalue_references)</tt> to determine if support for
+rvalue references is enabled. clang does not yet fully implement this feature.
+
+<h3 id="cxx_static_assert">C++0x <tt>static_assert()</tt></h3>
+
+<p>Use <tt>__has_feature(cxx_static_assert)</tt> to determine if support for
+compile-time assertions using <tt>static_assert</tt> is enabled.</p>
+
+<h3 id="cxx_auto_type">C++0x type inference</h3>
+
+<p>Use <tt>__has_feature(cxx_auto_type)</tt> to determine C++0x type inference
+is supported using the <tt>auto</tt> specifier. If this is disabled,
+<tt>auto</tt> will instead be a storage class specifier, as in C or C++98.</p>
+
+<h3 id="cxx_variadic_templates">C++0x variadic templates</tt></h3>
+
+<p>Use <tt>__has_feature(cxx_variadic_templates)</tt> to determine if support
+for templates taking any number of arguments with the ellipsis notation is
+enabled. clang does not yet fully implement this feature.</p>
+
+<!-- ======================================================================= -->
+<h2 id="blocks">Blocks</h2>
+<!-- ======================================================================= -->
+
+<p>The syntax and high level language feature description is in <a
+href="BlockLanguageSpec.txt">BlockLanguageSpec.txt</a>.  Implementation and ABI
+details for the clang implementation are in <a 
+href="Block-ABI-Apple.txt">Block-ABI-Apple.txt</a>.</p>
+
+
+<p>Query for this feature with __has_feature(blocks).</p>
+
+<!-- ======================================================================= -->
+<h2 id="overloading-in-c">Function Overloading in C</h2>
+<!-- ======================================================================= -->
+
+<p>Clang provides support for C++ function overloading in C. Function
+overloading in C is introduced using the <tt>overloadable</tt> attribute. For
+example, one might provide several overloaded versions of a <tt>tgsin</tt>
+function that invokes the appropriate standard function computing the sine of a
+value with <tt>float</tt>, <tt>double</tt>, or <tt>long double</tt>
+precision:</p>
+
+<blockquote>
+<pre>
+#include &lt;math.h&gt;
+float <b>__attribute__((overloadable))</b> tgsin(float x) { return sinf(x); }
+double <b>__attribute__((overloadable))</b> tgsin(double x) { return sin(x); }
+long double <b>__attribute__((overloadable))</b> tgsin(long double x) { return sinl(x); }
+</pre>
+</blockquote>
+
+<p>Given these declarations, one can call <tt>tgsin</tt> with a
+<tt>float</tt> value to receive a <tt>float</tt> result, with a
+<tt>double</tt> to receive a <tt>double</tt> result, etc. Function
+overloading in C follows the rules of C++ function overloading to pick
+the best overload given the call arguments, with a few C-specific
+semantics:</p>
+<ul>
+  <li>Conversion from <tt>float</tt> or <tt>double</tt> to <tt>long
+  double</tt> is ranked as a floating-point promotion (per C99) rather
+  than as a floating-point conversion (as in C++).</li>
+  
+  <li>A conversion from a pointer of type <tt>T*</tt> to a pointer of type
+  <tt>U*</tt> is considered a pointer conversion (with conversion
+  rank) if <tt>T</tt> and <tt>U</tt> are compatible types.</li>
+
+  <li>A conversion from type <tt>T</tt> to a value of type <tt>U</tt>
+  is permitted if <tt>T</tt> and <tt>U</tt> are compatible types. This
+  conversion is given "conversion" rank.</li>
+</ul>
+
+<p>The declaration of <tt>overloadable</tt> functions is restricted to
+function declarations and definitions. Most importantly, if any
+function with a given name is given the <tt>overloadable</tt>
+attribute, then all function declarations and definitions with that
+name (and in that scope) must have the <tt>overloadable</tt>
+attribute. This rule even applies to redeclarations of functions whose original
+declaration had the <tt>overloadable</tt> attribute, e.g.,</p>
+
+<blockquote>
+<pre>
+int f(int) __attribute__((overloadable));
+float f(float); <i>// error: declaration of "f" must have the "overloadable" attribute</i>
+
+int g(int) __attribute__((overloadable));
+int g(int) { } <i>// error: redeclaration of "g" must also have the "overloadable" attribute</i>
+</pre>
+</blockquote>
+
+<p>Functions marked <tt>overloadable</tt> must have
+prototypes. Therefore, the following code is ill-formed:</p>
+
+<blockquote>
+<pre>
+int h() __attribute__((overloadable)); <i>// error: h does not have a prototype</i>
+</pre>
+</blockquote>
+
+<p>However, <tt>overloadable</tt> functions are allowed to use a
+ellipsis even if there are no named parameters (as is permitted in C++). This feature is particularly useful when combined with the <tt>unavailable</tt> attribute:</p>
+
+<blockquote>
+<pre>
+void honeypot(...) __attribute__((overloadable, unavailable)); <i>// calling me is an error</i>
+</pre>
+</blockquote>
+
+<p>Functions declared with the <tt>overloadable</tt> attribute have
+their names mangled according to the same rules as C++ function
+names. For example, the three <tt>tgsin</tt> functions in our
+motivating example get the mangled names <tt>_Z5tgsinf</tt>,
+<tt>_Z5tgsind</tt>, and <tt>Z5tgsine</tt>, respectively. There are two
+caveats to this use of name mangling:</p>
+
+<ul>
+  
+  <li>Future versions of Clang may change the name mangling of
+  functions overloaded in C, so you should not depend on an specific
+  mangling. To be completely safe, we strongly urge the use of
+  <tt>static inline</tt> with <tt>overloadable</tt> functions.</li>
+
+  <li>The <tt>overloadable</tt> attribute has almost no meaning when
+  used in C++, because names will already be mangled and functions are
+  already overloadable. However, when an <tt>overloadable</tt>
+  function occurs within an <tt>extern "C"</tt> linkage specification,
+  it's name <i>will</i> be mangled in the same way as it would in
+  C.</li>
+</ul>
+
+<p>Query for this feature with __has_feature(attribute_overloadable).</p>
+
+
+<!-- ======================================================================= -->
+<h2 id="builtins">Builtin Functions</h2>
+<!-- ======================================================================= -->
+
+<p>Clang supports a number of builtin library functions with the same syntax as
+GCC, including things like <tt>__builtin_nan</tt>,
+<tt>__builtin_constant_p</tt>, <tt>__builtin_choose_expr</tt>, 
+<tt>__builtin_types_compatible_p</tt>, <tt>__sync_fetch_and_add</tt>, etc.  In
+addition to the GCC builtins, Clang supports a number of builtins that GCC does
+not, which are listed here.</p>
+
+<p>Please note that Clang does not and will not support all of the GCC builtins
+for vector operations.  Instead of using builtins, you should use the functions
+defined in target-specific header files like <tt>&lt;xmmintrin.h&gt;</tt>, which
+define portable wrappers for these.  Many of the Clang versions of these
+functions are implemented directly in terms of <a href="#vectors">extended
+vector support</a> instead of builtins, in order to reduce the number of
+builtins that we need to implement.</p>
+
+<!-- ======================================================================= -->
+<h3 id="__builtin_shufflevector">__builtin_shufflevector</h3>
+<!-- ======================================================================= -->
+
+<p><tt>__builtin_shufflevector</tt> is used to express generic vector
+permutation/shuffle/swizzle operations. This builtin is also very important for
+the implementation of various target-specific header files like
+<tt>&lt;xmmintrin.h&gt;</tt>.
+</p>
+
+<p><b>Syntax:</b></p>
+
+<pre>
+__builtin_shufflevector(vec1, vec2, index1, index2, ...)
+</pre>
+
+<p><b>Examples:</b></p>
+
+<pre>
+  // Identity operation - return 4-element vector V1.
+  __builtin_shufflevector(V1, V1, 0, 1, 2, 3)
+
+  // "Splat" element 0 of V1 into a 4-element result.
+  __builtin_shufflevector(V1, V1, 0, 0, 0, 0)
+
+  // Reverse 4-element vector V1.
+  __builtin_shufflevector(V1, V1, 3, 2, 1, 0)
+
+  // Concatenate every other element of 4-element vectors V1 and V2.
+  __builtin_shufflevector(V1, V2, 0, 2, 4, 6)
+
+  // Concatenate every other element of 8-element vectors V1 and V2.
+  __builtin_shufflevector(V1, V2, 0, 2, 4, 6, 8, 10, 12, 14)
+</pre>
+
+<p><b>Description:</b></p>
+
+<p>The first two arguments to __builtin_shufflevector are vectors that have the
+same element type.  The remaining arguments are a list of integers that specify
+the elements indices of the first two vectors that should be extracted and
+returned in a new vector.  These element indices are numbered sequentially
+starting with the first vector, continuing into the second vector.  Thus, if
+vec1 is a 4-element vector, index 5 would refer to the second element of vec2.
+</p>
+
+<p>The result of __builtin_shufflevector is a vector
+with the same element type as vec1/vec2 but that has an element count equal to
+the number of indices specified.
+</p>
+
+<p>Query for this feature with __has_builtin(__builtin_shufflevector).</p>
+
+<!-- ======================================================================= -->
+<h3 id="__builtin_unreachable">__builtin_unreachable</h3>
+<!-- ======================================================================= -->
+
+<p><tt>__builtin_unreachable</tt> is used to indicate that a specific point in
+the program cannot be reached, even if the compiler might otherwise think it
+can.  This is useful to improve optimization and eliminates certain warnings.
+For example, without the <tt>__builtin_unreachable</tt> in the example below,
+the compiler assumes that the inline asm can fall through and prints a "function
+declared 'noreturn' should not return" warning.
+</p>
+
+<p><b>Syntax:</b></p>
+
+<pre>
+__builtin_unreachable()
+</pre>
+
+<p><b>Example of Use:</b></p>
+
+<pre>
+void myabort(void) __attribute__((noreturn));
+void myabort(void) {
+    asm("int3");
+    __builtin_unreachable();
+}
+</pre>
+
+<p><b>Description:</b></p>
+
+<p>The __builtin_unreachable() builtin has completely undefined behavior.  Since
+it has undefined behavior, it is a statement that it is never reached and the
+optimizer can take advantage of this to produce better code.  This builtin takes
+no arguments and produces a void result.
+</p>
+
+<p>Query for this feature with __has_builtin(__builtin_unreachable).</p>
+
+
+<!-- ======================================================================= -->
+<h2 id="targetspecific">Target-Specific Extensions</h2>
+<!-- ======================================================================= -->
+
+<p>Clang supports some language features conditionally on some targets.</p>
+
+<!-- ======================================================================= -->
+<h3 id="x86-specific">X86/X86-64 Language Extensions</h3>
+<!-- ======================================================================= -->
+
+<p>The X86 backend has these language extensions:</p>
+
+<!-- ======================================================================= -->
+<h4 id="x86-gs-segment">Memory references off the GS segment</h4>
+<!-- ======================================================================= -->
+
+<p>Annotating a pointer with address space #256 causes it to  be code generated
+relative to the X86 GS segment register, and address space #257 causes it to be
+relative to the X86 FS segment.  Note that this is a very very low-level
+feature that should only be used if you know what you're doing (for example in
+an OS kernel).</p>
+
+<p>Here is an example:</p>
+
+<pre>
+#define GS_RELATIVE __attribute__((address_space(256)))
+int foo(int GS_RELATIVE *P) {
+  return *P;
+}
+</pre>
+
+<p>Which compiles to (on X86-32):</p>
+
+<pre>
+_foo:
+	movl	4(%esp), %eax
+	movl	%gs:(%eax), %eax
+	ret
+</pre>
+
+<!-- ======================================================================= -->
+<h2 id="analyzerspecific">Static Analysis-Specific Extensions</h2>
+<!-- ======================================================================= -->
+
+<p>Clang supports additional attributes that are useful for documenting program
+invariants and rules for static analysis tools. The extensions documented here
+are used by the <a
+href="http://clang.llvm.org/StaticAnalysis.html">path-sensitive static analyzer
+engine</a> that is part of Clang's Analysis library.</p>
+
+<!-- ======================================================================= -->
+<h3 id="analyzerattributes">Analyzer Attributes</h3>
+<!-- ======================================================================= -->
+
+<h4 id="attr_analyzer_noreturn"><tt>analyzer_noreturn</tt></h4>
+
+<p>Clang's static analysis engine understands the standard <tt>noreturn</tt>
+attribute. This attribute, which is typically affixed to a function prototype,
+indicates that a call to a given function never returns. Function prototypes for
+common functions like <tt>exit</tt> are typically annotated with this attribute,
+as well as a variety of common assertion handlers. Users can educate the static
+analyzer about their own custom assertion handles (thus cutting down on false
+positives due to false paths) by marking their own &quot;panic&quot; functions
+with this attribute.</p>
+
+<p>While useful, <tt>noreturn</tt> is not applicable in all cases. Sometimes
+there are special functions that for all intents and purposes should be
+considered panic functions (i.e., they are only called when an internal program
+error occurs) but may actually return so that the program can fail gracefully.
+The <tt>analyzer_noreturn</tt> attribute allows one to annotate such functions
+as being interpreted as &quot;no return&quot; functions by the analyzer (thus
+pruning bogus paths) but will not affect compilation (as in the case of
+<tt>noreturn</tt>).</p>
+
+<p><b>Usage</b>: The <tt>analyzer_noreturn</tt> attribute can be placed in the
+same places where the <tt>noreturn</tt> attribute can be placed. It is commonly
+placed at the end of function prototypes:</p>
+
+<pre>
+  void foo() <b>__attribute__((analyzer_noreturn))</b>;
+</pre>
+
+<p>Query for this feature with __has_feature(attribute_analyzer_noreturn).</p>
+
+
+</div>
+</body>
+</html>
diff --git a/docs/Makefile b/docs/Makefile
new file mode 100644
index 0000000..e9bbb28
--- /dev/null
+++ b/docs/Makefile
@@ -0,0 +1,97 @@
+##===- docs/Makefile ---------------------------------------*- Makefile -*-===##
+# 
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+# 
+##===----------------------------------------------------------------------===##
+
+LEVEL      := ../../..
+DIRS       := tools
+
+ifdef BUILD_FOR_WEBSITE
+PROJ_OBJ_DIR = .
+DOXYGEN = doxygen
+
+$(PROJ_OBJ_DIR)/doxygen.cfg: doxygen.cfg.in
+	cat $< | sed \
+	  -e 's/@abs_top_srcdir@/../g' \
+	  -e 's/@DOT@/dot/g' \
+	  -e 's/@PACKAGE_VERSION@/mainline/' \
+	  -e 's/@abs_top_builddir@/../g' > $@
+endif
+
+include $(LEVEL)/Makefile.common
+
+HTML       := $(wildcard $(PROJ_SRC_DIR)/*.html) \
+              $(wildcard $(PROJ_SRC_DIR)/*.css)
+#IMAGES     := $(wildcard $(PROJ_SRC_DIR)/img/*.*)
+DOXYFILES  := doxygen.cfg.in doxygen.css doxygen.footer doxygen.header \
+              doxygen.intro
+EXTRA_DIST := $(HTML) $(DOXYFILES) llvm.css CommandGuide img
+
+.PHONY: install-html install-doxygen doxygen generated
+
+install_targets :=
+ifndef ONLY_MAN_DOCS
+install_targets += install-html
+endif
+ifeq ($(ENABLE_DOXYGEN),1)
+install_targets += install-doxygen
+endif
+install-local:: $(install_targets)
+
+# Live documentation is generated for the web site using this target:
+# 'make generated BUILD_FOR_WEBSITE=1'
+generated:: doxygen
+
+install-html: $(PROJ_OBJ_DIR)/html.tar.gz
+	$(Echo) Installing HTML documentation
+	$(Verb) $(MKDIR) $(DESTDIR)$(PROJ_docsdir)/html
+	$(Verb) $(MKDIR) $(DESTDIR)$(PROJ_docsdir)/html/img
+	$(Verb) $(DataInstall) $(HTML) $(DESTDIR)$(PROJ_docsdir)/html
+#	$(Verb) $(DataInstall) $(IMAGES) $(DESTDIR)$(PROJ_docsdir)/html/img
+	$(Verb) $(DataInstall) $(PROJ_OBJ_DIR)/html.tar.gz $(DESTDIR)$(PROJ_docsdir)
+
+$(PROJ_OBJ_DIR)/html.tar.gz: $(HTML)
+	$(Echo) Packaging HTML documentation
+	$(Verb) $(RM) -rf $@ $(PROJ_OBJ_DIR)/html.tar
+	$(Verb) cd $(PROJ_SRC_DIR) && \
+	  $(TAR) cf $(PROJ_OBJ_DIR)/html.tar *.html
+	$(Verb) $(GZIP) $(PROJ_OBJ_DIR)/html.tar
+
+install-doxygen: doxygen
+	$(Echo) Installing doxygen documentation
+	$(Verb) $(MKDIR) $(DESTDIR)$(PROJ_docsdir)/html/doxygen
+	$(Verb) $(DataInstall) $(PROJ_OBJ_DIR)/doxygen.tar.gz $(DESTDIR)$(PROJ_docsdir)
+	$(Verb) cd $(PROJ_OBJ_DIR)/doxygen && \
+	  $(FIND) . -type f -exec \
+	    $(DataInstall) {} $(DESTDIR)$(PROJ_docsdir)/html/doxygen \;
+
+doxygen: regendoc $(PROJ_OBJ_DIR)/doxygen.tar.gz
+
+regendoc:
+	$(Echo) Building doxygen documentation
+	$(Verb) if test -e $(PROJ_OBJ_DIR)/doxygen ; then \
+	  $(RM) -rf $(PROJ_OBJ_DIR)/doxygen ; \
+	fi
+	$(Verb) $(DOXYGEN) $(PROJ_OBJ_DIR)/doxygen.cfg
+
+$(PROJ_OBJ_DIR)/doxygen.tar.gz: $(DOXYFILES) $(PROJ_OBJ_DIR)/doxygen.cfg
+	$(Echo) Packaging doxygen documentation
+	$(Verb) $(RM) -rf $@ $(PROJ_OBJ_DIR)/doxygen.tar
+	$(Verb) $(TAR) cf $(PROJ_OBJ_DIR)/doxygen.tar doxygen
+	$(Verb) $(GZIP) $(PROJ_OBJ_DIR)/doxygen.tar
+	$(Verb) $(CP) $(PROJ_OBJ_DIR)/doxygen.tar.gz $(PROJ_OBJ_DIR)/doxygen/html/
+
+userloc: $(LLVM_SRC_ROOT)/docs/userloc.html
+
+$(LLVM_SRC_ROOT)/docs/userloc.html:
+	$(Echo) Making User LOC Table
+	$(Verb) cd $(LLVM_SRC_ROOT) ; ./utils/userloc.pl -details -recurse \
+	  -html lib include tools runtime utils examples autoconf test > docs/userloc.html
+
+uninstall-local::
+	$(Echo) Uninstalling Documentation
+	$(Verb) $(RM) -rf $(DESTDIR)$(PROJ_docsdir)
diff --git a/docs/PCHInternals.html b/docs/PCHInternals.html
new file mode 100644
index 0000000..e21ec5e
--- /dev/null
+++ b/docs/PCHInternals.html
@@ -0,0 +1,500 @@
+<html>
+<head>
+  <title>Precompiled Headers (PCH)</title>
+  <link type="text/css" rel="stylesheet" href="../menu.css" />
+  <link type="text/css" rel="stylesheet" href="../content.css" />
+  <style type="text/css">
+    td {
+    vertical-align: top;
+    }
+  </style>
+</head>
+
+<body>
+
+<!--#include virtual="../menu.html.incl"-->
+
+<div id="content">
+
+<h1>Precompiled Headers</h1>
+
+  <p>This document describes the design and implementation of Clang's
+  precompiled headers (PCH). If you are interested in the end-user
+  view, please see the <a
+   href="UsersManual.html#precompiledheaders">User's Manual</a>.</p>
+
+  <p><b>Table of Contents</b></p>
+  <ul>
+    <li><a href="#usage">Using Precompiled Headers with
+    <tt>clang</tt></a></li>
+    <li><a href="#philosophy">Design Philosophy</a></li>
+    <li><a href="#contents">Precompiled Header Contents</a>
+      <ul>
+        <li><a href="#metadata">Metadata Block</a></li>
+        <li><a href="#sourcemgr">Source Manager Block</a></li>
+        <li><a href="#preprocessor">Preprocessor Block</a></li>
+        <li><a href="#types">Types Block</a></li>
+        <li><a href="#decls">Declarations Block</a></li>
+        <li><a href="#stmt">Statements and Expressions</a></li>
+        <li><a href="#idtable">Identifier Table Block</a></li>
+        <li><a href="#method-pool">Method Pool Block</a></li>
+      </ul>
+    </li>
+    <li><a href="#tendrils">Precompiled Header Integration
+    Points</a></li>
+</ul>
+    
+<h2 id="usage">Using Precompiled Headers with <tt>clang</tt></h2>
+
+<p>The Clang compiler frontend, <tt>clang -cc1</tt>, supports two command line
+options for generating and using PCH files.<p>
+
+<p>To generate PCH files using <tt>clang -cc1</tt>, use the option
+<b><tt>-emit-pch</tt></b>:
+
+<pre> $ clang -cc1 test.h -emit-pch -o test.h.pch </pre>
+
+<p>This option is transparently used by <tt>clang</tt> when generating
+PCH files. The resulting PCH file contains the serialized form of the
+compiler's internal representation after it has completed parsing and
+semantic analysis. The PCH file can then be used as a prefix header
+with the <b><tt>-include-pch</tt></b> option:</p>
+
+<pre>
+  $ clang -cc1 -include-pch test.h.pch test.c -o test.s
+</pre>
+
+<h2 id="philosophy">Design Philosophy</h2>
+  
+<p>Precompiled headers are meant to improve overall compile times for
+  projects, so the design of precompiled headers is entirely driven by
+  performance concerns. The use case for precompiled headers is
+  relatively simple: when there is a common set of headers that is
+  included in nearly every source file in the project, we
+  <i>precompile</i> that bundle of headers into a single precompiled
+  header (PCH file). Then, when compiling the source files in the
+  project, we load the PCH file first (as a prefix header), which acts
+  as a stand-in for that bundle of headers.</p>
+
+<p>A precompiled header implementation improves performance when:</p>
+<ul>
+  <li>Loading the PCH file is significantly faster than re-parsing the
+  bundle of headers stored within the PCH file. Thus, a precompiled
+  header design attempts to minimize the cost of reading the PCH
+  file. Ideally, this cost should not vary with the size of the
+  precompiled header file.</li>
+  
+  <li>The cost of generating the PCH file initially is not so large
+  that it counters the per-source-file performance improvement due to
+  eliminating the need to parse the bundled headers in the first
+  place. This is particularly important on multi-core systems, because
+  PCH file generation serializes the build when all compilations
+  require the PCH file to be up-to-date.</li>
+</ul>
+
+<p>Clang's precompiled headers are designed with a compact on-disk
+representation, which minimizes both PCH creation time and the time
+required to initially load the PCH file. The PCH file itself contains
+a serialized representation of Clang's abstract syntax trees and
+supporting data structures, stored using the same compressed bitstream
+as <a href="http://llvm.org/docs/BitCodeFormat.html">LLVM's bitcode
+file format</a>.</p>
+
+<p>Clang's precompiled headers are loaded "lazily" from disk. When a
+PCH file is initially loaded, Clang reads only a small amount of data
+from the PCH file to establish where certain important data structures
+are stored. The amount of data read in this initial load is
+independent of the size of the PCH file, such that a larger PCH file
+does not lead to longer PCH load times. The actual header data in the
+PCH file--macros, functions, variables, types, etc.--is loaded only
+when it is referenced from the user's code, at which point only that
+entity (and those entities it depends on) are deserialized from the
+PCH file. With this approach, the cost of using a precompiled header
+for a translation unit is proportional to the amount of code actually
+used from the header, rather than being proportional to the size of
+the header itself.</p> 
+
+<p>When given the <code>-print-stats</code> option, Clang produces
+statistics describing how much of the precompiled header was actually
+loaded from disk. For a simple "Hello, World!" program that includes
+the Apple <code>Cocoa.h</code> header (which is built as a precompiled
+header), this option illustrates how little of the actual precompiled
+header is required:</p>
+
+<pre>
+*** PCH Statistics:
+  933 stat cache hits
+  4 stat cache misses
+  895/39981 source location entries read (2.238563%)
+  19/15315 types read (0.124061%)
+  20/82685 declarations read (0.024188%)
+  154/58070 identifiers read (0.265197%)
+  0/7260 selectors read (0.000000%)
+  0/30842 statements read (0.000000%)
+  4/8400 macros read (0.047619%)
+  1/4995 lexical declcontexts read (0.020020%)
+  0/4413 visible declcontexts read (0.000000%)
+  0/7230 method pool entries read (0.000000%)
+  0 method pool misses
+</pre>
+
+<p>For this small program, only a tiny fraction of the source
+locations, types, declarations, identifiers, and macros were actually
+deserialized from the precompiled header. These statistics can be
+useful to determine whether the precompiled header implementation can
+be improved by making more of the implementation lazy.</p>
+
+<h2 id="contents">Precompiled Header Contents</h2>
+
+<img src="PCHLayout.png" align="right" alt="Precompiled header layout">
+
+<p>Clang's precompiled headers are organized into several different
+blocks, each of which contains the serialized representation of a part
+of Clang's internal representation. Each of the blocks corresponds to
+either a block or a record within <a
+ href="http://llvm.org/docs/BitCodeFormat.html">LLVM's bitstream
+format</a>. The contents of each of these logical blocks are described
+below.</p>
+
+<p>For a given precompiled header, the <a
+href="http://llvm.org/cmds/llvm-bcanalyzer.html"><code>llvm-bcanalyzer</code></a>
+utility can be used to examine the actual structure of the bitstream
+for the precompiled header. This information can be used both to help
+understand the structure of the precompiled header and to isolate
+areas where precompiled headers can still be optimized, e.g., through
+the introduction of abbreviations.</p>
+
+<h3 id="metadata">Metadata Block</h3>
+
+<p>The metadata block contains several records that provide
+information about how the precompiled header was built. This metadata
+is primarily used to validate the use of a precompiled header. For
+example, a precompiled header built for a 32-bit x86 target cannot be used
+when compiling for a 64-bit x86 target. The metadata block contains
+information about:</p>
+
+<dl>
+  <dt>Language options</dt>
+  <dd>Describes the particular language dialect used to compile the
+PCH file, including major options (e.g., Objective-C support) and more
+minor options (e.g., support for "//" comments). The contents of this
+record correspond to the <code>LangOptions</code> class.</dd>
+  
+  <dt>Target architecture</dt>
+  <dd>The target triple that describes the architecture, platform, and
+ABI for which the PCH file was generated, e.g.,
+<code>i386-apple-darwin9</code>.</dd>
+  
+  <dt>PCH version</dt>
+  <dd>The major and minor version numbers of the precompiled header
+format. Changes in the minor version number should not affect backward
+compatibility, while changes in the major version number imply that a
+newer compiler cannot read an older precompiled header (and
+vice-versa).</dd>
+
+  <dt>Original file name</dt>
+  <dd>The full path of the header that was used to generate the
+precompiled header.</dd>
+
+  <dt>Predefines buffer</dt>
+  <dd>Although not explicitly stored as part of the metadata, the
+predefines buffer is used in the validation of the precompiled header.
+The predefines buffer itself contains code generated by the compiler
+to initialize the preprocessor state according to the current target,
+platform, and command-line options. For example, the predefines buffer
+will contain "<code>#define __STDC__ 1</code>" when we are compiling C
+without Microsoft extensions. The predefines buffer itself is stored
+within the <a href="#sourcemgr">source manager block</a>, but its
+contents are verified along with the rest of the metadata.</dd>
+
+</dl>
+
+<h3 id="sourcemgr">Source Manager Block</h3>
+
+<p>The source manager block contains the serialized representation of
+Clang's <a
+ href="InternalsManual.html#SourceLocation">SourceManager</a> class,
+which handles the mapping from source locations (as represented in
+Clang's abstract syntax tree) into actual column/line positions within
+a source file or macro instantiation. The precompiled header's
+representation of the source manager also includes information about
+all of the headers that were (transitively) included when building the
+precompiled header.</p>
+
+<p>The bulk of the source manager block is dedicated to information
+about the various files, buffers, and macro instantiations into which
+a source location can refer. Each of these is referenced by a numeric
+"file ID", which is a unique number (allocated starting at 1) stored
+in the source location. Clang serializes the information for each kind
+of file ID, along with an index that maps file IDs to the position
+within the PCH file where the information about that file ID is
+stored. The data associated with a file ID is loaded only when
+required by the front end, e.g., to emit a diagnostic that includes a
+macro instantiation history inside the header itself.</p>
+
+<p>The source manager block also contains information about all of the
+headers that were included when building the precompiled header. This
+includes information about the controlling macro for the header (e.g.,
+when the preprocessor identified that the contents of the header
+dependent on a macro like <code>LLVM_CLANG_SOURCEMANAGER_H</code>)
+along with a cached version of the results of the <code>stat()</code>
+system calls performed when building the precompiled header. The
+latter is particularly useful in reducing system time when searching
+for include files.</p>
+
+<h3 id="preprocessor">Preprocessor Block</h3>
+
+<p>The preprocessor block contains the serialized representation of
+the preprocessor. Specifically, it contains all of the macros that
+have been defined by the end of the header used to build the
+precompiled header, along with the token sequences that comprise each
+macro. The macro definitions are only read from the PCH file when the
+name of the macro first occurs in the program. This lazy loading of
+macro definitions is triggered by lookups into the <a
+ href="#idtable">identifier table</a>.</p>
+
+<h3 id="types">Types Block</h3>
+
+<p>The types block contains the serialized representation of all of
+the types referenced in the translation unit. Each Clang type node
+(<code>PointerType</code>, <code>FunctionProtoType</code>, etc.) has a
+corresponding record type in the PCH file. When types are deserialized
+from the precompiled header, the data within the record is used to
+reconstruct the appropriate type node using the AST context.</p>
+
+<p>Each type has a unique type ID, which is an integer that uniquely
+identifies that type. Type ID 0 represents the NULL type, type IDs
+less than <code>NUM_PREDEF_TYPE_IDS</code> represent predefined types
+(<code>void</code>, <code>float</code>, etc.), while other
+"user-defined" type IDs are assigned consecutively from
+<code>NUM_PREDEF_TYPE_IDS</code> upward as the types are encountered.
+The PCH file has an associated mapping from the user-defined types
+block to the location within the types block where the serialized
+representation of that type resides, enabling lazy deserialization of
+types. When a type is referenced from within the PCH file, that
+reference is encoded using the type ID shifted left by 3 bits. The
+lower three bits are used to represent the <code>const</code>,
+<code>volatile</code>, and <code>restrict</code> qualifiers, as in
+Clang's <a
+ href="http://clang.llvm.org/docs/InternalsManual.html#Type">QualType</a>
+class.</p>
+
+<h3 id="decls">Declarations Block</h3>
+
+<p>The declarations block contains the serialized representation of
+all of the declarations referenced in the translation unit. Each Clang
+declaration node (<code>VarDecl</code>, <code>FunctionDecl</code>,
+etc.) has a corresponding record type in the PCH file. When
+declarations are deserialized from the precompiled header, the data
+within the record is used to build and populate a new instance of the
+corresponding <code>Decl</code> node. As with types, each declaration
+node has a numeric ID that is used to refer to that declaration within
+the PCH file. In addition, a lookup table provides a mapping from that
+numeric ID to the offset within the precompiled header where that
+declaration is described.</p>
+
+<p>Declarations in Clang's abstract syntax trees are stored
+hierarchically. At the top of the hierarchy is the translation unit
+(<code>TranslationUnitDecl</code>), which contains all of the
+declarations in the translation unit. These declarations (such as
+functions or struct types) may also contain other declarations inside
+them, and so on. Within Clang, each declaration is stored within a <a
+href="http://clang.llvm.org/docs/InternalsManual.html#DeclContext">declaration
+context</a>, as represented by the <code>DeclContext</code> class.
+Declaration contexts provide the mechanism to perform name lookup
+within a given declaration (e.g., find the member named <code>x</code>
+in a structure) and iterate over the declarations stored within a
+context (e.g., iterate over all of the fields of a structure for
+structure layout).</p>
+
+<p>In Clang's precompiled header format, deserializing a declaration
+that is a <code>DeclContext</code> is a separate operation from
+deserializing all of the declarations stored within that declaration
+context. Therefore, Clang will deserialize the translation unit
+declaration without deserializing the declarations within that
+translation unit. When required, the declarations stored within a
+declaration context will be deserialized. There are two representations
+of the declarations within a declaration context, which correspond to
+the name-lookup and iteration behavior described above:</p>
+
+<ul>
+  <li>When the front end performs name lookup to find a name
+  <code>x</code> within a given declaration context (for example,
+  during semantic analysis of the expression <code>p-&gt;x</code>,
+  where <code>p</code>'s type is defined in the precompiled header),
+  Clang deserializes a hash table mapping from the names within that
+  declaration context to the declaration IDs that represent each
+  visible declaration with that name. The entire hash table is
+  deserialized at this point (into the <code>llvm::DenseMap</code>
+  stored within each <code>DeclContext</code> object), but the actual
+  declarations are not yet deserialized. In a second step, those
+  declarations with the name <code>x</code> will be deserialized and
+  will be used as the result of name lookup.</li>
+
+  <li>When the front end performs iteration over all of the
+  declarations within a declaration context, all of those declarations
+  are immediately de-serialized. For large declaration contexts (e.g.,
+  the translation unit), this operation is expensive; however, large
+  declaration contexts are not traversed in normal compilation, since
+  such a traversal is unnecessary. However, it is common for the code
+  generator and semantic analysis to traverse declaration contexts for
+  structs, classes, unions, and enumerations, although those contexts
+  contain relatively few declarations in the common case.</li>
+</ul>
+
+<h3 id="stmt">Statements and Expressions</h3>
+
+<p>Statements and expressions are stored in the precompiled header in
+both the <a href="#types">types</a> and the <a
+ href="#decls">declarations</a> blocks, because every statement or
+expression will be associated with either a type or declaration. The
+actual statement and expression records are stored immediately
+following the declaration or type that owns the statement or
+expression. For example, the statement representing the body of a
+function will be stored directly following the declaration of the
+function.</p>
+
+<p>As with types and declarations, each statement and expression kind
+in Clang's abstract syntax tree (<code>ForStmt</code>,
+<code>CallExpr</code>, etc.) has a corresponding record type in the
+precompiled header, which contains the serialized representation of
+that statement or expression. Each substatement or subexpression
+within an expression is stored as a separate record (which keeps most
+records to a fixed size). Within the precompiled header, the
+subexpressions of an expression are stored prior to the expression
+that owns those expression, using a form of <a
+href="http://en.wikipedia.org/wiki/Reverse_Polish_notation">Reverse
+Polish Notation</a>. For example, an expression <code>3 - 4 + 5</code>
+would be represented as follows:</p>
+
+<table border="1">
+  <tr><td><code>IntegerLiteral(3)</code></td></tr>
+  <tr><td><code>IntegerLiteral(4)</code></td></tr>
+  <tr><td><code>BinaryOperator(-)</code></td></tr>
+  <tr><td><code>IntegerLiteral(5)</code></td></tr>
+  <tr><td><code>BinaryOperator(+)</code></td></tr>
+  <tr><td>STOP</td></tr>
+</table>
+
+<p>When reading this representation, Clang evaluates each expression
+record it encounters, builds the appropriate abstract synax tree node,
+and then pushes that expression on to a stack. When a record contains <i>N</i>
+subexpressions--<code>BinaryOperator</code> has two of them--those
+expressions are popped from the top of the stack. The special STOP
+code indicates that we have reached the end of a serialized expression
+or statement; other expression or statement records may follow, but
+they are part of a different expression.</p>
+
+<h3 id="idtable">Identifier Table Block</h3>
+
+<p>The identifier table block contains an on-disk hash table that maps
+each identifier mentioned within the precompiled header to the
+serialized representation of the identifier's information (e.g, the
+<code>IdentifierInfo</code> structure). The serialized representation
+contains:</p>
+
+<ul>
+  <li>The actual identifier string.</li>
+  <li>Flags that describe whether this identifier is the name of a
+  built-in, a poisoned identifier, an extension token, or a
+  macro.</li>
+  <li>If the identifier names a macro, the offset of the macro
+  definition within the <a href="#preprocessor">preprocessor
+  block</a>.</li>
+  <li>If the identifier names one or more declarations visible from
+  translation unit scope, the <a href="#decls">declaration IDs</a> of these
+  declarations.</li>
+</ul>
+
+<p>When a precompiled header is loaded, the precompiled header
+mechanism introduces itself into the identifier table as an external
+lookup source. Thus, when the user program refers to an identifier
+that has not yet been seen, Clang will perform a lookup into the
+identifier table. If an identifier is found, its contents (macro 
+definitions, flags, top-level declarations, etc.) will be deserialized, at which point the corresponding <code>IdentifierInfo</code> structure will have the same contents it would have after parsing the headers in the precompiled header.</p>
+
+<p>Within the PCH file, the identifiers used to name declarations are represented with an integral value. A separate table provides a mapping from this integral value (the identifier ID) to the location within the on-disk
+hash table where that identifier is stored. This mapping is used when
+deserializing the name of a declaration, the identifier of a token, or
+any other construct in the PCH file that refers to a name.</p>
+
+<h3 id="method-pool">Method Pool Block</h3>
+
+<p>The method pool block is represented as an on-disk hash table that
+serves two purposes: it provides a mapping from the names of
+Objective-C selectors to the set of Objective-C instance and class
+methods that have that particular selector (which is required for
+semantic analysis in Objective-C) and also stores all of the selectors
+used by entities within the precompiled header. The design of the
+method pool is similar to that of the <a href="#idtable">identifier
+table</a>: the first time a particular selector is formed during the
+compilation of the program, Clang will search in the on-disk hash
+table of selectors; if found, Clang will read the Objective-C methods
+associated with that selector into the appropriate front-end data
+structure (<code>Sema::InstanceMethodPool</code> and
+<code>Sema::FactoryMethodPool</code> for instance and class methods,
+respectively).</p>
+
+<p>As with identifiers, selectors are represented by numeric values
+within the PCH file. A separate index maps these numeric selector
+values to the offset of the selector within the on-disk hash table,
+and will be used when de-serializing an Objective-C method declaration
+(or other Objective-C construct) that refers to the selector.</p>
+
+<h2 id="tendrils">Precompiled Header Integration Points</h2>
+
+<p>The "lazy" deserialization behavior of precompiled headers requires
+their integration into several completely different submodules of
+Clang. For example, lazily deserializing the declarations during name
+lookup requires that the name-lookup routines be able to query the
+precompiled header to find entities within the PCH file.</p>
+
+<p>For each Clang data structure that requires direct interaction with
+the precompiled header logic, there is an abstract class that provides
+the interface between the two modules. The <code>PCHReader</code>
+class, which handles the loading of a precompiled header, inherits
+from all of these abstract classes to provide lazy deserialization of
+Clang's data structures. <code>PCHReader</code> implements the
+following abstract classes:</p>
+
+<dl>
+  <dt><code>StatSysCallCache</code></dt>
+  <dd>This abstract interface is associated with the
+    <code>FileManager</code> class, and is used whenever the file
+    manager is going to perform a <code>stat()</code> system call.</dd>
+    
+  <dt><code>ExternalSLocEntrySource</code></dt>
+  <dd>This abstract interface is associated with the
+    <code>SourceManager</code> class, and is used whenever the
+    <a href="#sourcemgr">source manager</a> needs to load the details
+    of a file, buffer, or macro instantiation.</dd>
+
+  <dt><code>IdentifierInfoLookup</code></dt>
+  <dd>This abstract interface is associated with the
+    <code>IdentifierTable</code> class, and is used whenever the
+    program source refers to an identifier that has not yet been seen.
+    In this case, the precompiled header implementation searches for
+    this identifier within its <a href="#idtable">identifier table</a>
+    to load any top-level declarations or macros associated with that
+    identifier.</dd>
+
+  <dt><code>ExternalASTSource</code></dt>
+  <dd>This abstract interface is associated with the
+    <code>ASTContext</code> class, and is used whenever the abstract
+    syntax tree nodes need to loaded from the precompiled header. It
+    provides the ability to de-serialize declarations and types
+    identified by their numeric values, read the bodies of functions
+    when required, and read the declarations stored within a
+    declaration context (either for iteration or for name lookup).</dd>
+    
+  <dt><code>ExternalSemaSource</code></dt>
+  <dd>This abstract interface is associated with the <code>Sema</code>
+    class, and is used whenever semantic analysis needs to read
+    information from the <a href="#methodpool">global method
+    pool</a>.</dd>
+</dl>
+
+</div>
+
+</body>
+</html>
diff --git a/docs/PCHLayout.graffle b/docs/PCHLayout.graffle
new file mode 100644
index 0000000..5c96bfb
--- /dev/null
+++ b/docs/PCHLayout.graffle
@@ -0,0 +1,1880 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>ActiveLayerIndex</key>
+	<integer>0</integer>
+	<key>ApplicationVersion</key>
+	<array>
+		<string>com.omnigroup.OmniGrafflePro</string>
+		<string>137.11.0.108132</string>
+	</array>
+	<key>AutoAdjust</key>
+	<true/>
+	<key>BackgroundGraphic</key>
+	<dict>
+		<key>Bounds</key>
+		<string>{{0, 0}, {576, 733}}</string>
+		<key>Class</key>
+		<string>SolidGraphic</string>
+		<key>ID</key>
+		<integer>2</integer>
+		<key>Style</key>
+		<dict>
+			<key>shadow</key>
+			<dict>
+				<key>Draws</key>
+				<string>NO</string>
+			</dict>
+			<key>stroke</key>
+			<dict>
+				<key>Draws</key>
+				<string>NO</string>
+			</dict>
+		</dict>
+	</dict>
+	<key>CanvasOrigin</key>
+	<string>{0, 0}</string>
+	<key>ColumnAlign</key>
+	<integer>1</integer>
+	<key>ColumnSpacing</key>
+	<real>36</real>
+	<key>CreationDate</key>
+	<string>2009-06-02 11:19:43 -0700</string>
+	<key>Creator</key>
+	<string>Douglas Gregor</string>
+	<key>DisplayScale</key>
+	<string>1 0/72 in = 1.0000 in</string>
+	<key>GraphDocumentVersion</key>
+	<integer>6</integer>
+	<key>GraphicsList</key>
+	<array>
+		<dict>
+			<key>Bounds</key>
+			<string>{{35, 301}, {104, 30}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>13</integer>
+			<key>Layer</key>
+			<integer>0</integer>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.175793</string>
+						<key>g</key>
+						<string>0.402929</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>CornerRadius</key>
+					<real>9</real>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf460
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf0 Method Pool}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{32, 58}, {110, 14}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>FitText</key>
+			<string>YES</string>
+			<key>Flow</key>
+			<string>Resize</string>
+			<key>ID</key>
+			<integer>12</integer>
+			<key>Layer</key>
+			<integer>0</integer>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+				<key>shadow</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Pad</key>
+				<integer>0</integer>
+				<key>Text</key>
+				<string>{\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf460
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf0 Precompiled Header}</string>
+				<key>VerticalPad</key>
+				<integer>0</integer>
+			</dict>
+			<key>Wrap</key>
+			<string>NO</string>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{35, 190}, {104, 30}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>11</integer>
+			<key>Layer</key>
+			<integer>0</integer>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>1</string>
+						<key>g</key>
+						<string>0.796208</string>
+						<key>r</key>
+						<string>0.324589</string>
+					</dict>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>CornerRadius</key>
+					<real>9</real>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf460
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf0 Types}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{35, 227}, {104, 30}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>10</integer>
+			<key>Layer</key>
+			<integer>0</integer>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>1</string>
+						<key>g</key>
+						<string>0.382716</string>
+						<key>r</key>
+						<string>0.524072</string>
+					</dict>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>CornerRadius</key>
+					<real>9</real>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf460
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf0 Declarations}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{35, 264}, {104, 30}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>8</integer>
+			<key>Layer</key>
+			<integer>0</integer>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.99938</string>
+						<key>g</key>
+						<string>0.457913</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>CornerRadius</key>
+					<real>9</real>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf460
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf0 Identifier Table}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{35, 153}, {104, 30}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>7</integer>
+			<key>Layer</key>
+			<integer>0</integer>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.669993</string>
+						<key>g</key>
+						<string>1</string>
+						<key>r</key>
+						<string>0.254644</string>
+					</dict>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>CornerRadius</key>
+					<real>9</real>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf460
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf0 Preprocessor}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{35, 116}, {104, 30}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>6</integer>
+			<key>Layer</key>
+			<integer>0</integer>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.258332</string>
+						<key>g</key>
+						<string>1</string>
+						<key>r</key>
+						<string>0.593784</string>
+					</dict>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>CornerRadius</key>
+					<real>9</real>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf460
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf0 Source Manager}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{35, 79}, {104, 30}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>5</integer>
+			<key>Layer</key>
+			<integer>0</integer>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.270873</string>
+						<key>g</key>
+						<string>1</string>
+						<key>r</key>
+						<string>0.979351</string>
+					</dict>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>CornerRadius</key>
+					<real>9</real>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf460
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf0 Metadata}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{21, 47}, {132, 293}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>4</integer>
+			<key>Layer</key>
+			<integer>1</integer>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>FillType</key>
+					<integer>2</integer>
+					<key>GradientAngle</key>
+					<real>90</real>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>CornerRadius</key>
+					<real>9</real>
+				</dict>
+			</dict>
+		</dict>
+	</array>
+	<key>GridInfo</key>
+	<dict/>
+	<key>GuidesLocked</key>
+	<string>NO</string>
+	<key>GuidesVisible</key>
+	<string>YES</string>
+	<key>HPages</key>
+	<integer>1</integer>
+	<key>ImageCounter</key>
+	<integer>1</integer>
+	<key>KeepToScale</key>
+	<false/>
+	<key>Layers</key>
+	<array>
+		<dict>
+			<key>Lock</key>
+			<string>NO</string>
+			<key>Name</key>
+			<string>Sub-blocks</string>
+			<key>Print</key>
+			<string>YES</string>
+			<key>View</key>
+			<string>YES</string>
+		</dict>
+		<dict>
+			<key>Lock</key>
+			<string>NO</string>
+			<key>Name</key>
+			<string>PCH Block</string>
+			<key>Print</key>
+			<string>YES</string>
+			<key>View</key>
+			<string>YES</string>
+		</dict>
+	</array>
+	<key>LayoutInfo</key>
+	<dict>
+		<key>Animate</key>
+		<string>NO</string>
+		<key>circoMinDist</key>
+		<real>18</real>
+		<key>circoSeparation</key>
+		<real>0.0</real>
+		<key>layoutEngine</key>
+		<string>dot</string>
+		<key>neatoSeparation</key>
+		<real>0.0</real>
+		<key>twopiSeparation</key>
+		<real>0.0</real>
+	</dict>
+	<key>LinksVisible</key>
+	<string>NO</string>
+	<key>MagnetsVisible</key>
+	<string>NO</string>
+	<key>MasterSheets</key>
+	<array/>
+	<key>ModificationDate</key>
+	<string>2009-06-03 08:22:05 -0700</string>
+	<key>Modifier</key>
+	<string>Douglas Gregor</string>
+	<key>NotesVisible</key>
+	<string>NO</string>
+	<key>Orientation</key>
+	<integer>2</integer>
+	<key>OriginVisible</key>
+	<string>NO</string>
+	<key>PageBreaks</key>
+	<string>YES</string>
+	<key>PrintInfo</key>
+	<dict>
+		<key>NSBottomMargin</key>
+		<array>
+			<string>float</string>
+			<string>41</string>
+		</array>
+		<key>NSLeftMargin</key>
+		<array>
+			<string>float</string>
+			<string>18</string>
+		</array>
+		<key>NSPaperSize</key>
+		<array>
+			<string>size</string>
+			<string>{612, 792}</string>
+		</array>
+		<key>NSRightMargin</key>
+		<array>
+			<string>float</string>
+			<string>18</string>
+		</array>
+		<key>NSTopMargin</key>
+		<array>
+			<string>float</string>
+			<string>18</string>
+		</array>
+	</dict>
+	<key>PrintOnePage</key>
+	<false/>
+	<key>QuickLookPreview</key>
+	<data>
+	JVBERi0xLjMKJcTl8uXrp/Og0MTGCjQgMCBvYmoKPDwgL0xlbmd0aCA1IDAgUiAvRmls
+	dGVyIC9GbGF0ZURlY29kZSA+PgpzdHJlYW0KeAGNWNtuGzcQfedX8LF5iMz77r7WadEU
+	CJDUBvqsyptagWQ5klOgP9tv6TnDy64syXYMhGeo5XAuZ4bc/a6/6O/a4C92SXfe6/2o
+	/9QP2iySkX96ra+uD1avDtrK32Gl35tFLL9OqChQUPBVX30e96vx8enHcqP3a2xhY5Bt
+	vI3aGu27Xq+2+urj1uoPOxhBM7zRqU96q20IRGoD1C+GziT5wUaP0eYJEbpOr6Da62Cc
+	xtNAfugWxg1hWuoHr6gRI57GJgQb7aI8l+ednRYCU91KF3A0KEybxcB/OmF76GliNa1o
+	prFJu6E+DWGl75uXimHG4oidHf63CD7tLgk4jaDE773VfaejH7CCAby5t/pwr3IAz+TR
+	6t+RtW+n+by+EX1G31wzPVW5IQkUNCNOoSu5AJilAhIDHa3Ez2WBvkn4va2J8FEyhdiX
+	HPpgJLUccyIA5omAyESUhRmDeRU4qzzUyyMyXSMf0zwPzbCWB1jc0gCcs6CAtvoGzDsN
+	tUsSj+i0AxPNULjqMlcRrqMHYucYMZDZX3jA52R93IbzDwRskzVEJeXwfIuQ4LBskS5o
+	GGpBdecf8H1XjOzzA1d/jJvl0/qf8Xq32e3X2/Fpv16xWGu5I7rd4COqFexYuM70HUiB
+	8g9BJZQz6pQVCwRy+FDqFKL1qI0A3rNwswD/MwLJ+TQecL3wR01LEQTRyGBgEzxC1aA6
+	6zmLCGRdqImhDkzKwEdF+Wg6RGrA79WcSRsMpVIM5EOBW/Suc9WAn7uheAwwcxgS3el9
+	rQYKyIXMWkOC83drcoAmdy1oRXc5irsEM3cpwvK6MGMpHE6ii0WVB5EkCthXvG3GNG9h
+	ZXah+CrOCPevD2h1ByWJNWj2M+/RaBJMB+9+vgXlS4tw+j0Ly6akg74FJ39FIwBFbr/q
+	nz6NT8u75dPynbr9pn+5RW2dO0fQ8wYcAOwGJFbsvXeFWDpZaTokFtAUZ0VReGPdjFim
+	RjoO7AF8IA65MUEonIxwhJHmKOwlmEWaIiLdFgpmQyvgeMh8w8YMNcwq5rRQ01CyCUMl
+	FuA5YjGyeNJaOfO8UUSTy/KDcAenRD7SSCRXa8n6HCDMhXooFpfRc1l5CDDGTC6Amcuc
+	h1ttITHUiW8ERSbH2jQ2FnbZak5zmXYXR4rL2acZwbRR6BxnCMaT9oRgISx87FGgzwl2
+	s/uBe4X+tHxY/j3uX6OZiyGFQrOUcGQjItK/QAVTqploirmiKCzq8ulVBB43Mh1z8YNm
+	MdSkVJpFLgXNMGaaAcxiznlSqS4UzNov4HjI0x1PU2QhVnNazGkoYs6hxJzwJZrhzJaW
+	rXhOTy7LsS00i/XmRJol3oBkussNHnNdOchrZSnbe3GZY6YZwMxlzsOttlAwG24BbVAW
+	u+RpbJxpVs1pLtNu0gxDpZn49AaaxSQn8LM+hotG6s25RvZ5Pz7ud6vxcNi9wjK2sBC7
+	gZmX+4jv0Zwzy0KqZwbRFHJFkbEFPadmFhJTKdOB3SWjfK5AKE8GJgd7cRSWEcxCThFh
+	DaEsFMwuWcDxkKexsbCsmdNCTkMRcg4l5IQvsMylcjFQRJPLmiI9cimf+1nomEqZ7tld
+	Mmo3h+yykts8XOYoLCOYuUwRbrm+LBTMLllAG5TDLnkaGwvLmjnNZRoKlzkUlwnLTTGf
+	lpeaWeBl4qSZeVSN7QacCs+72ce78eFp/d/Uxo4P3wvqFjGhFZ8oG/f6nb79puTYfYMi
+	i6PXG1yCTzTdUg+Ob7xVvEVPuqRn+ddmnFRduAm4YDqc/mbhe9dZMBHvM5LkiMtjvmIS
+	TUxSFEmUaNqpB5IivqV4GpNC387NWjx4yZXiwZiLB2DGpAARbGkLBRfKBOgt8tE0Npbi
+	aeY0JtFQtmgMtUUDvlQ8rlx+lAOaXNYUpTZ8u9ugkjz1ynTrFy6221EtnpgvPw5jLh6A
+	mcuchz9tITHU5SoBKDLOoGkaG+fiqeY0l2koiwdDLR7AtxXPIK84z1u0X/jQJzT+58Xz
+	YVxtlnu8weweDlMFnWeZdyH2A1nWDckZnvGVZaGcijoCTSFXFIVlLN/6IhM9m4JMO/ng
+	QBradmwWlkWbT0WOwjKCWcgpIqxtITHUScgJinw0jY0zy6o5LeQ0lCzDUFkG+ALLLAJR
+	LgJAk8uaP9A3O7SrDQW2fmGZlVd79nDbLkeVZShhFpbDmFkGMHOZ8/CnLRTMS1UBbVAO
+	u8g0NxaWNXOayzQULnMoLmef3nIRcOD2SYu2CS80BleQE5ZJLzzXU+NZRcPC+zTYM4r+
+	fRwPl/pzSueMwj0xDQGJPzEKt5PVbvu43ox3+rdxeffaTVjuKHiDcAiYWdgO1xXkqtxR
+	vMtswI0iU7qklCLTHlw3FUBw9cAOjQ3BIHr5jC4FwM9n0mblMxo+F+TPcy1/FJHxtpC4
+	pp2gyEfT2FgKoJkzaYOhYAPtLWwgfKEAvLGlAIhmBUCRLnuTvw1mAR9AcgH4VvPepRqT
+	Ei1+mKLLHKUACGYFQBH+tIWCS81Tb5HRZilJAXhsLAXQzGku01C4zKG4TPi2Nsv30pMC
+	8B434R7t/oRreKW/393pz7vdZuqyX/4HnD2NIAplbmRzdHJlYW0KZW5kb2JqCjUgMCBv
+	YmoKMTkzOQplbmRvYmoKMiAwIG9iago8PCAvVHlwZSAvUGFnZSAvUGFyZW50IDMgMCBS
+	IC9SZXNvdXJjZXMgNiAwIFIgL0NvbnRlbnRzIDQgMCBSIC9NZWRpYUJveCBbMCAwIDU3
+	NiA3MzNdCj4+CmVuZG9iago2IDAgb2JqCjw8IC9Qcm9jU2V0IFsgL1BERiAvVGV4dCAv
+	SW1hZ2VCIC9JbWFnZUMgL0ltYWdlSSBdIC9Db2xvclNwYWNlIDw8IC9DczIgMjUgMCBS
+	Ci9DczEgNyAwIFIgPj4gL0ZvbnQgPDwgL0YxLjAgMjYgMCBSID4+IC9YT2JqZWN0IDw8
+	IC9JbTEgOCAwIFIgL0ltMiAxMSAwIFIKL0ltMyAxMyAwIFIgL0ltNSAxNyAwIFIgL0lt
+	NyAyMSAwIFIgL0ltOCAyMyAwIFIgL0ltNCAxNSAwIFIgL0ltNiAxOSAwIFIgPj4KL1No
+	YWRpbmcgPDwgL1NoMSAxMCAwIFIgPj4gPj4KZW5kb2JqCjEwIDAgb2JqCjw8IC9Db2xv
+	clNwYWNlIDcgMCBSIC9TaGFkaW5nVHlwZSAyIC9Db29yZHMgWyA2Ni41IC0xNDcgNjYu
+	NDk5OTUgMTQ3IF0gL0RvbWFpbgpbIDAgMSBdIC9FeHRlbmQgWyBmYWxzZSBmYWxzZSBd
+	IC9GdW5jdGlvbiAyNyAwIFIgPj4KZW5kb2JqCjggMCBvYmoKPDwgL0xlbmd0aCA5IDAg
+	UiAvVHlwZSAvWE9iamVjdCAvU3VidHlwZSAvSW1hZ2UgL1dpZHRoIDMwOCAvSGVpZ2h0
+	IDYzMCAvQ29sb3JTcGFjZQoyOCAwIFIgL1NNYXNrIDI5IDAgUiAvQml0c1BlckNvbXBv
+	bmVudCA4IC9GaWx0ZXIgL0ZsYXRlRGVjb2RlID4+CnN0cmVhbQp4Ae3QMQEAAADCoPVP
+	bQlPiEBhwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBg
+	wIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYM
+	GDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIAB
+	AwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBg
+	wIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYM
+	GDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIAB
+	AwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBg
+	wIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYM
+	GDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIAB
+	AwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBg
+	wIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYM
+	GDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIAB
+	AwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBg
+	wIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYM
+	GDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIAB
+	AwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBg
+	wIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYM
+	GDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIAB
+	AwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBg
+	wIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYM
+	GDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIAB
+	AwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBg
+	wIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYM
+	GDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIAB
+	AwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBg
+	wIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYM
+	GDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIAB
+	AwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBg
+	wIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYM
+	GDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIAB
+	AwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBg
+	wIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYM
+	GDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIAB
+	AwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBg
+	wIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYM
+	GDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIAB
+	AwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBg
+	wIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYM
+	GDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIAB
+	AwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBg
+	wIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYM
+	GDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIAB
+	AwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBg
+	wIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYM
+	GDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIAB
+	AwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBg
+	wIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYM
+	GDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIAB
+	AwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBg
+	wIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGPgMDOJgAAEK
+	ZW5kc3RyZWFtCmVuZG9iago5IDAgb2JqCjI1NjIKZW5kb2JqCjExIDAgb2JqCjw8IC9M
+	ZW5ndGggMTIgMCBSIC9UeXBlIC9YT2JqZWN0IC9TdWJ0eXBlIC9JbWFnZSAvV2lkdGgg
+	MjUyIC9IZWlnaHQgMTA0IC9Db2xvclNwYWNlCjMxIDAgUiAvU01hc2sgMzIgMCBSIC9C
+	aXRzUGVyQ29tcG9uZW50IDggL0ZpbHRlciAvRmxhdGVEZWNvZGUgPj4Kc3RyZWFtCngB
+	7dABDQAAAMKg909tDjeIQGHAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY
+	MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED
+	BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA
+	gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY
+	MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED
+	BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA
+	gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY
+	+B4YMy8AAQplbmRzdHJlYW0KZW5kb2JqCjEyIDAgb2JqCjM2NgplbmRvYmoKMTMgMCBv
+	YmoKPDwgL0xlbmd0aCAxNCAwIFIgL1R5cGUgL1hPYmplY3QgL1N1YnR5cGUgL0ltYWdl
+	IC9XaWR0aCAyNTIgL0hlaWdodCAxMDQgL0NvbG9yU3BhY2UKMzEgMCBSIC9TTWFzayAz
+	NCAwIFIgL0JpdHNQZXJDb21wb25lbnQgOCAvRmlsdGVyIC9GbGF0ZURlY29kZSA+Pgpz
+	dHJlYW0KeAHt0AENAAAAwqD3T20ON4hAYcCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw
+	YMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMG
+	DBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCA
+	AQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw
+	YMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMG
+	DBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCA
+	AQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw
+	YMCAAQMGDBj4HhgzLwABCmVuZHN0cmVhbQplbmRvYmoKMTQgMCBvYmoKMzY2CmVuZG9i
+	agoxNyAwIG9iago8PCAvTGVuZ3RoIDE4IDAgUiAvVHlwZSAvWE9iamVjdCAvU3VidHlw
+	ZSAvSW1hZ2UgL1dpZHRoIDI1MiAvSGVpZ2h0IDEwNCAvQ29sb3JTcGFjZQozMSAwIFIg
+	L1NNYXNrIDM2IDAgUiAvQml0c1BlckNvbXBvbmVudCA4IC9GaWx0ZXIgL0ZsYXRlRGVj
+	b2RlID4+CnN0cmVhbQp4Ae3QAQ0AAADCoPdPbQ43iEBhwIABAwYMGDBgwIABAwYMGDBg
+	wIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYM
+	GDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIAB
+	AwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBg
+	wIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYM
+	GDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIAB
+	AwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBg
+	wIABAwYMGDBgwIABAwYMGPgeGDMvAAEKZW5kc3RyZWFtCmVuZG9iagoxOCAwIG9iagoz
+	NjYKZW5kb2JqCjIxIDAgb2JqCjw8IC9MZW5ndGggMjIgMCBSIC9UeXBlIC9YT2JqZWN0
+	IC9TdWJ0eXBlIC9JbWFnZSAvV2lkdGggMjUyIC9IZWlnaHQgMTA0IC9Db2xvclNwYWNl
+	CjMxIDAgUiAvU01hc2sgMzggMCBSIC9CaXRzUGVyQ29tcG9uZW50IDggL0ZpbHRlciAv
+	RmxhdGVEZWNvZGUgPj4Kc3RyZWFtCngB7dABDQAAAMKg909tDjeIQGHAgAEDBgwYMGDA
+	gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY
+	MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED
+	BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA
+	gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY
+	MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED
+	BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA
+	gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY+B4YMy8AAQplbmRzdHJlYW0KZW5kb2JqCjIy
+	IDAgb2JqCjM2NgplbmRvYmoKMjMgMCBvYmoKPDwgL0xlbmd0aCAyNCAwIFIgL1R5cGUg
+	L1hPYmplY3QgL1N1YnR5cGUgL0ltYWdlIC9XaWR0aCAyNTIgL0hlaWdodCAxMDQgL0Nv
+	bG9yU3BhY2UKMzEgMCBSIC9TTWFzayA0MCAwIFIgL0JpdHNQZXJDb21wb25lbnQgOCAv
+	RmlsdGVyIC9GbGF0ZURlY29kZSA+PgpzdHJlYW0KeAHt0AENAAAAwqD3T20ON4hAYcCA
+	AQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw
+	YMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMG
+	DBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCA
+	AQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw
+	YMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMG
+	DBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCA
+	AQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBj4HhgzLwABCmVuZHN0cmVhbQpl
+	bmRvYmoKMjQgMCBvYmoKMzY2CmVuZG9iagoxNSAwIG9iago8PCAvTGVuZ3RoIDE2IDAg
+	UiAvVHlwZSAvWE9iamVjdCAvU3VidHlwZSAvSW1hZ2UgL1dpZHRoIDI1MiAvSGVpZ2h0
+	IDEwNCAvQ29sb3JTcGFjZQozMSAwIFIgL1NNYXNrIDQyIDAgUiAvQml0c1BlckNvbXBv
+	bmVudCA4IC9GaWx0ZXIgL0ZsYXRlRGVjb2RlID4+CnN0cmVhbQp4Ae3QAQ0AAADCoPdP
+	bQ43iEBhwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBg
+	wIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYM
+	GDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIAB
+	AwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBg
+	wIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYM
+	GDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIAB
+	AwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGPgeGDMvAAEKZW5k
+	c3RyZWFtCmVuZG9iagoxNiAwIG9iagozNjYKZW5kb2JqCjE5IDAgb2JqCjw8IC9MZW5n
+	dGggMjAgMCBSIC9UeXBlIC9YT2JqZWN0IC9TdWJ0eXBlIC9JbWFnZSAvV2lkdGggMjUy
+	IC9IZWlnaHQgMTA0IC9Db2xvclNwYWNlCjMxIDAgUiAvU01hc2sgNDQgMCBSIC9CaXRz
+	UGVyQ29tcG9uZW50IDggL0ZpbHRlciAvRmxhdGVEZWNvZGUgPj4Kc3RyZWFtCngB7dAB
+	DQAAAMKg909tDjeIQGHAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA
+	gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY
+	MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED
+	BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA
+	gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY
+	MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED
+	BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY+B4Y
+	My8AAQplbmRzdHJlYW0KZW5kb2JqCjIwIDAgb2JqCjM2NgplbmRvYmoKMjkgMCBvYmoK
+	PDwgL0xlbmd0aCAzMCAwIFIgL1R5cGUgL1hPYmplY3QgL1N1YnR5cGUgL0ltYWdlIC9X
+	aWR0aCAzMDggL0hlaWdodCA2MzAgL0NvbG9yU3BhY2UKL0RldmljZUdyYXkgL0JpdHNQ
+	ZXJDb21wb25lbnQgOCAvRmlsdGVyIC9GbGF0ZURlY29kZSA+PgpzdHJlYW0KeAHt2ulX
+	leUaBvAUZdrMbkCGTWwhBkEGBVFcECJhIGgZqEWyQNKUBFoYYgtDMhLRAmWJohE4oCSz
+	KKBm6/xr53424HABeXc6X3q7ng+nLr3Oxud3nuHdr+eddzgoQAEKUIACFPi/C6yy/Pi/
+	kRmp1S+Hm0XHywmuNvP9O3gLWm5ua9asWfsvGDJNNzcX3//o5gITLmPl7uHhuTi8LDcW
+	Z+bp4eFuZjsP95fZ5sHM6nIXLS8vb5sMHxm+lhxmZmaG3l5enp4GThacrLe/xGZOMLPC
+	3MVLuHx8/fz8/QMCAi08AgL8/f38fIXOW9wMm0tNe7SZRSZissK8bDbhEqugdXZ7cHBI
+	SEioJYdMLDjYbl8XFBgYIHA2m5dZbUZNudTmxdZ6eHrbfPz8DZdIhYWHh0dEREZGOiw4
+	ZFoRETLBsNDQEAPn7+dj8/b0mF9rmlt0nsysMV+/gCB7cOj68AiH493oaKdzQ4xlxwan
+	Mzr6XYcjInx9aLA9KEAWm6y1+aX2tv1p9qVsSxHzMWIC5oiKdsbExsXFJyQmJm6cH0mW
+	GQsTkqklxMfFxcY4o6McwmbUfERNNujb9+cCmbfNJRYWGRUtXgkbk5NTUlPT0mVstuAw
+	80pLTU1JTt6YIG7RUZFhLjXZoPNof7rSFsl8/ALtIWGR7zpj4xKFK31LxtasrG3bs1+N
+	HRYYr2aTvX1bVtbWjC3pApcYF+t8NzIsxB7o56NAc5F5eNp8/QPtoRFRztiEpJS0LZlZ
+	2TtycvPydubvMqPAYsM1qfydeXm5OTuyszK3pKUkJcQ6oyJC7YH+vjZzqMn2XHGlCZmb
+	nGVCFhQc5oiOiU9KTc/ctiM3b9cHhR8WFe8pKSktLd1ruSGTKinZU1z0YeEHu/Jyd2zL
+	TE9Nio+JdoQFBxk097XmmWMltFULZAHrQsIdG+ISU9K3ZufsLNhdXLLvo/2flJcfOHjI
+	ouPggfLyT/Z/tK+keHfBzpzsrekpiXEbHOEh6wIW0FYyE7I17p7evv5CFhUTn5yWmZ2b
+	X1i89+Pyg59WVFZWVR05UmPGF5YarikdOVJVVVlZ8enB8o/3Fhfm52ZnpiXHx0QJmr+v
+	nGnydLsCmnnK8PDy8Q8yZAmbNmfl5Bfu2Vd2qKKyuubY8RO1J0/W1dXX1zdYbMiU6upO
+	nqw9cfxYTXVlxaGyfXsK83OyNm9KMGhB/j5eriNt2c1pdqac/36BwUKWmJKx/f2CIhE7
+	XH30+Ff1Xzeeamo63XzGoqP5dFPTqcav6786frT6sKgVFby/PSMlUdCCA/3MPbDCQlsl
+	y8yQ2cMcMQkpGdl5hSX7RexYbX1jU/O3Ld+1nmtr+96io63tXOt3Ld82NzXW1x4Ttf0l
+	hXnZGSkJMY4weeSwecrdudzmdC0zL58Ae2ikM36TkO0uLfus6mhtw6nmlta28+0XOjou
+	dl6y6Oi82NFxof18W2tL86mG2qNVn5WV7ha0TfHOyFB7gNmdyy60hWUmh1l0XPLm7Xm7
+	95ZXHDle13impe2HC52Xfu7q7r5y9WqPJcfVq1e6u7t+vtR54Ye2ljONdcePVJTv3Z23
+	fXNyXLQcaSsutNWr5QLwDbCHyWGWlvV+YWn55zUnGppazrV3XO660nOt9/qNPhk3LTjM
+	vG5c773Wc6Xrckf7uZamhhM1n5eXFr6flSZHWpg9wFcW2urVS24BszXlNAsyOzMlI6eg
+	pKyi5sTXzWfPd1zu7untu/lL/68DAwODg4O3LTdkUjK1X/t/udnX29N9ueP82eavT9RU
+	lJUU5GSkmN3pWmjLbE7Zmu7mNAuLik1Kz95ZtP+zaiFrbe/s6um92T9w+87de0ND92U8
+	sNwwsxoaunf3zu2B/pu9PV2d7a2CVv3Z/qKd2elJsWah+Xi5L3MLrJKt6e0XGBLhjE/d
+	mlu471DVlw1Cdqn7Wl//4N2hB8O/PRxxjVHLjfl5Pfxt+MHQ3cH+vmvdlwSt4cuqQ/sK
+	c7emxjsjQgL9vGVzLrk5XVvT377eEbsxPTt/T9nho3VN3wlZ762BO/eHR0bHxscnJicn
+	pyw5ZGIT4+NjoyPD9+8M3OoVtO+a6o4eLtuTn52+Mdax3u4vjxtuSw4019aUx9nouE2Z
+	ObLMqmsbW853CtngveGRsYmpqUfTjy09ph9NTU2MjQzfGxS0zvMtjbXVstByMjfJ1Rkc
+	6NqccAnIcWa2ZmjkhsS0bXnFZYePNTSf6+i6dmtwaHh0Ymr68ZOZ2fkxZ7mxMLGZJ4+n
+	pyZGh4cGb13r6jjX3HDscFlx3ra0xA2RoWZzLjnQzHFm81u3Pio2ecuOgr2yzE61tF/u
+	6Ru499vY5PST2dm5p88sPp7Ozc4+mZ4c++3eQF/P5faWU7LQ9hbs2JIcG7V+nZ9t6YEm
+	Zp42f7tszZTMnN0fVxytb27r6L7ef2d4dHJ6ZlbAnv8u44VFh5nb82fPns7OTE+ODt/p
+	v97d0dZcf7Ti4905mSmyOV0HGl4Cq+TpzCcwOMKZkJqVV1RWebyx5YfLPTcHh0Ympmfm
+	BGwR6w8LjsW5CdvczPTEyNDgzZ7LP7Q0Hq8sK8rLSk1wRsiBJpcAXJyr3dy9fOU4i0lM
+	z95VcrD6q6bWC129/XeHx6Yezz57Lp8KVv+xwIApySSfP5t9PDU2fLe/t+tCa9NX1QdL
+	dmWnJ8bIgebr5Y4Xp5h5y5cAR2ySHGf7Pq2pa267eKVvYOjh+PTMUyCzgNZrU3gNzqA9
+	nZkefzg00HflYltzXc2n++RAS4p1yFcB76Vm5tqUK+C95Iycwo8qjjV8e/5Sz83bD0Ym
+	ZZnJxnztk/947Qda4F9fn9mLF7/LQpsceXD7Zs+l8982HKv4qDAnI/k9cwmYi/PNhw15
+	1LD52cPk6Wxr7of7D3/Z2NL+07Vf7sjWfDInZosfbAGjZaewOD8xm3sim/POL9d+am9p
+	/PLw/g9zt8oTWphdLs6lZvPXZry5Aj6pPHHq7I8/m+Ns/NHMnGzNhc9c9udZ4hcXJiib
+	c27m0bg50H7+8eypE5WfmEsgfv7iXGImjxoB8qhhrs3isqrab1o7uq7/eu+hmMlxZnmy
+	//xnEU0OtEfjD+/9er2ro/Wb2ip5qpWLU8wC5NsT7k1jFhzulG8BO/eUV8m12dF9Q66A
+	ienZl2aWWFArTmIeTS6B2ekJuQRudHfIxVlVvmenfBNwhgevaBYh35y255ccqD55+txF
+	YyZPZ+YKcH3eij/NIr/hmqS5BMwTmphdPHf6ZPWBkvzt8u0pYgUzH3kRtMH1eHbgyMnm
+	tk7zqLFwbZqPs4jMn0zDzHLh4jQPG51tzSePHHA9oG2Q10HyULt0b4rZ4iOteTwTs8H7
+	r8z+5GdZ5rdemd0fdJnV1Sw+1P6Zmbw821V6qKbuzPeXrv67za5e+v5MXc2hUvkisDEm
+	UmFWTzNjVk+ztx0ib+xNmr2Ny/X7/18z1Y+0QGnx3pQ74K3rzLxydN2bC3cAnmcW4FBN
+	4S1mb7xAo9k8Kc1US+uN0l8yk1fb8prWEbNxs+v5zOxNeX12f9S8pZWvTm98sIWDfBEw
+	b2pH75sXaIvPGps3xjjkRS2+3Ja/DjCvth0xSZvN3zp90TBv9kDM5sTMwkowNTGbEzPX
+	S8fvzzR8Yf7maXOSy8wL/kKAZgt2NINFpIg0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYA
+	oog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBB
+	hWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0
+	UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYA
+	oog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBB
+	hWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0
+	UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYA
+	oog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBB
+	hWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0
+	UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYA
+	oog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBB
+	hWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0
+	UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYA
+	oog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBB
+	hWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0
+	UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYA
+	oog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBB
+	hWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0
+	UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYA
+	oog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBB
+	hWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0
+	UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYA
+	oog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBB
+	hWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0
+	UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYA
+	oog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBB
+	hWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0
+	UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYA
+	oog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBB
+	hWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0
+	UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYA
+	oog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBB
+	hWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0
+	UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYA
+	oog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBB
+	hWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0
+	UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYA
+	oog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBB
+	hWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0
+	UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYA
+	oog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBB
+	hWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0
+	UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYA
+	oog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBB
+	hWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0
+	UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBBhWYAoog0UyBB5a+Z
+	efoGhjpiNm7O3lV6qKb+zPeXem4O3h+dejz77MUff8AnWzb+IWazj6dG7w/e7Ln0/Zn6
+	mkOlu7I3b4xxhAb6eq51W/XOa2PV6rWePoEhkTEb01+aXe0bvD8yKWa/v/j3mL34Xcwm
+	R+4P9l19aZa+MSYyJNDHc+1qmi2zW/6g2TIqf/5Lf8XsHe5NF+ZbzF47zeRf32L277gF
+	/pAr4E/PM5ot2aY0W0Ly1l/4e2Z18nz2+rPGv3Rv1rmez149ayy/NxPl+azkYE1dc1vn
+	ldeez/6FZlc625rrag6W7MpOT1x8PlvOLGKDy+zAkZOnjdnA0OIzrazat67sf3xBJrl4
+	BwwN9InZ6ZNHDrjMNkTMP9MuMbMFBItZ2vb8kgPVJ0+fu9h9Q8wmpl3fA8zH/eNN3jIB
+	M0eX2fTEyNDAje6L506frD5Qkr89LXFDRHCATb4HLGcW7kxM27ZzT3nVV02tHcbsoZg9
+	fS5fOM14y8/8h//2/BxfPH86Oz3x0Jh1tDZ9VVW+Z+e2tERn+Ipm9vDohNSsvOKyqtpv
+	Wju6rv967+H4o5mXZpZGmyf7Q8xmHo0/vPfr9a6O1m9qq8qK87JSE6LD7cutszWeNn8x
+	ixezok8qT5w6++PPvf13h8Vs7vmLhYVmYbRFshfP58Rs+G5/788/nj11ovKTIjGLFzN/
+	m+ca3JtrPGx+9rDouE1bcz/cf/jLxpb2n679cmd4bOrJnHmxsTD+4ftvxT/+4vzka8Dc
+	k6mx4Tu/XPupvaXxy8P7P8zduikuOszuZ/NYxszbb936qPeSM3IKP6o41vDteXmBdvvB
+	wsX5Es18+Io/+R/5G4tc5p8vFr46Pbgtr8/Of9twrOKjwpyM5Pei1q/z815q5ubu7RcU
+	6ohN2rKjYN+n5gHtonnYeDg+bQ60l7vTfPI/kmbFP7SZ0cKQacpxNj0uV0DflYvm8ezT
+	fQU7tiTFOkKD/Lzd3XBvurl7yYvayJj5h9pquTgvdJkDbcy8qQU08yNW/DP8g35j0eo1
+	MvOWdswcZ10X5NqsXnyklde0XkvMVrmZF7XBEU5zcRaVVR5vbPnhsrzdNk9oM3PPnv8u
+	/xu4BvwcS8TFuf3+/NncjHk6kzfbl39oaTxeWWaugARnRLB5Tfvmq+133jEvt10XZ1xK
+	Zs7ujyuO1je3dXRf778zPDo5PTP79JmwyVj8dKv908zt+bNnT2dnpidHh+/0X+/uaGuu
+	P1rx8e6czJS4+WsTXm27zOTilEsgNlkOtL2HqmtPtbRf7ukbuPfb2OT0k9nZOWGz9ng6
+	Nzv7ZHpy7Ld7A309l9tbTtVWH9orx1lyrLkCbB7LmK3x8PaTA02+PW2Tp9rDxxqaz3V0
+	Xbs1ODQ8OjE1/fjJzOz8mLPcWJjYzJPH01MTo8NDg7eudXWca244dlieaOVbwIbI0EDX
+	tfnGX6HI96jVa9y95EALlye0zJzCfbLQGlvOd3b33hq8NzwyNjE19Wj6saXH9KOpqYmx
+	keF7g7d6uzvPtzTKMttXmJMpT2fhcpx5uePjmZjJJSAH2npHrPx1Xf6essNH65rOtl8S
+	tIE794dHRsfGxycmJyenLDlkYhPj42OjI8P37wwI2aX2s011Rw+X7cnPTt8Y61hvvgWs
+	xUeN+QNNNmdIhDM+dWuuLLSqLxuaWwXtWl//4N2hB8O/PRxxjVHLjfl5Pfxt+MHQ3cH+
+	vmtC1trc8GWVLLPcranxTnkRJFtzyXFmzMzmDLCHRcUmpWfvLNr/WfWJrwWts6un92b/
+	wO07d+8NDd2X8cByw8xqaOje3Tu3B/pv9vZ0dQrZ1yeqP9tftDM7PSk2Kswe4NqaeJyJ
+	mdmc8lUg0hmfkpFTUFJWUSNoZ893XO7u6e27+Uv/rwMDA4ODg7ctN2RSMrVf+3+52dfb
+	03254/xZIaupKCspyMlIiXdGypcA19ZcYvbO6tVrPbx8zUKLSUzLer+wtPzzmhMNTS3n
+	2jsud13pudZ7/UafjJsWHGZeN673Xuu50nW5o/1cS1PDiZrPy0sL389KS4wxy8zXS7Ym
+	fHMy7x9lc7oWWohcncmbt+ft3lteceR4XeOZlrYfLnRe+rmru/vK1as9lhxXr17p7u76
+	+VLnhR/aWs401h0/UlG+d3fe9s3JcmmGuJbZmjf/zxrzb2zN5vQwJ5rZnZsysvN2l5Z9
+	VnW0tuFUc0tr2/n2Cx0dFzsvWXR0XuzouNB+vq21pflUQ+3Rqs/KSnfnZWdsMjvTnGYe
+	cmsu3ZovF1qgPcwRk5AiaIUl+w8drj5WW9/Y1Pxty3et59ravrfoaGs71/pdy7fNTY31
+	tceqDx/aX1IoZCkJMY4we6A5zZZdZsZMFppcA/JgK0daSsb29wuK9pWJ2tHjX9V/3Xiq
+	qel08xmLjubTTU2nGr+u/+r4UREr21dU8P72jBQ5zORxVshWWmbyWCsnmuxO/6AQQUvY
+	tDkrJ79wj6hVVFbXHDt+ovbkybq6+vr6BosNmVJd3cmTtSeOH6uprqwQsT2F+TlZmzcl
+	CFlIkL/ZmWuWuwHmbwG3Ne6e3r7+6wxafHJaZnZufmHx3o/LD35aUVlZVXXkSI0ZX1hq
+	uKZ05EhVVWVlxacHyz/eW1yYn5udmZYcb8jW+ft6e7qvWf40W0Bb6+5p8w0QNMeGuMSU
+	9K3ZOTsLdheX7Pto/yfl5QcOHrLoOHigvPyT/R/tKyneXbAzJ3trekpi3AaHkAX42jzd
+	V7gAXHfnqtVypBk0/6DgMEd0THxSanrmth25ebs+KPywqHhPSUlpaeleyw2ZVEnJnuKi
+	Dws/2JWXu2NbZnpqUnxMtCMsOMh/gWzZS3PxecMcaQYt0B4aEeWMTUhKSduSmZW9Iyc3
+	L29n/i4zCiw2XJPK35mXl5uzIzsrc0taSlJCrDMqItQeaMhch9lyzxnzZObuFDQ503z8
+	Au0hYZHvOmPjEpNTUtO3ZGzNytq2PfvV2GGB8Wo22du3ZWVtzdiSnpqSnBgX63w3MixE
+	HjJ85Cwz5/+fkb1Cs/kFBNlDwyKjomNi4xI2Jgtcalq6jM0WHGZeaanClbwxIS42Jjoq
+	MizUHhTgZ1ORvbNqYaV52XxcauvDHVHRTnGLi09ITEzcOD+SLDMWJiRTS4iPEy9ndJQj
+	fL1LzMfmtbDK/nyZyR41F4E51LxsvkYtOHR9eITD8W50tNO5IcayY4PTGR39rsMRIWDB
+	Zo35ipgcZW5v25gvLwJBEzVvWWv+gUHr7CGhoWHh4eEREZGRkQ4LDplWRIRMMCw0NMS+
+	LijQ389HtqXHWjWZrLT5peZu1posNr+AQANnDw4OCRE9Kw6ZWHCw3XAFBvjJEjNrTA5/
+	s8jeui9fuz7NBpUb1NPL22bzETh//wCxs+4ICPD3Fy4fm83by1POMZfYWy7MRa6F/SlL
+	TdQMm4e4GTihk+FryWFmZmbo7SVessLWrjFr7C8ssgU9s0NXu5nVZuBEbmF4WW4szszT
+	w3CZFfY/gb222lxwZsVZf6yR5WW4/ocV9sY2XSXD9TGu/3Cz6Hg1QzPfNwD+TjAfZu3x
+	d3T436UABShAAQpQYAWB/wIyjvCaCmVuZHN0cmVhbQplbmRvYmoKMzAgMCBvYmoKNzcy
+	OAplbmRvYmoKMzIgMCBvYmoKPDwgL0xlbmd0aCAzMyAwIFIgL1R5cGUgL1hPYmplY3Qg
+	L1N1YnR5cGUgL0ltYWdlIC9XaWR0aCAyNTIgL0hlaWdodCAxMDQgL0NvbG9yU3BhY2UK
+	L0RldmljZUdyYXkgL0JpdHNQZXJDb21wb25lbnQgOCAvRmlsdGVyIC9GbGF0ZURlY29k
+	ZSA+PgpzdHJlYW0KeAHtnPlXUukfx01LRZBFQUPAQBgBRZRcUDwYLoOpqGW4lKNH5aup
+	iXZwlDqYMuaIy+TCUdMyyaXM3cilmub0r83nuUA2LmXf+uHa5f2LnTjn8n49n+V57uU+
+	j4+PV94R8I6AdwS8I+AdARiBc2dGPyxciNj3k/xwrk9GfZHv7xkEN7Wf3/nz5y+cIYFd
+	Pz9sGP5PfgwcsBGzf0BAoEck3MrjMDAgwB+5dg3AN+O7wFG0/YGaRAoigyigYFwLOURO
+	g0ikwEA0AJAAEP9vwkcVjiLuD9yATQmmUmk0Op1xBkSn02hUajAMQRDwI3yM/rSlj4IO
+	5BBxEpkM2MAcEspkslhhYWHhuBYYZLGYzNAQBoMOA0Amk1D0Ef0pQ+8ivxAQGESmUGkI
+	G4jZERERHA6Xy+XhWGCPwwGj7PDwMDQANCqFHBQY4Ir9abq+Cx3FPJhKD2Gywi9GcHi8
+	S3y+QBAlxL2iBAI+/xKPx4m4GM5ihtAh+BB7V+i/lvco3yHdgZyCyAGcF8kXCEXR0WKJ
+	VCqNcSkWd3IbA4sScXS0SCjgR/IAH9FTgB4S/+t570YPImPkbG4kH7glMTKZPD4+QQG6
+	jGMhfwnx8XKZLEYC/PxILhujh8R3wX8x8h50CpXBDGNzLwlE0VLAViQmpSiVqWmqA6Xj
+	SAeuVGmpSmVKUqICBkAaLRJc4rLDmAwq5RTwGHpAIDmYxmCGcyIFIkmsPCExWalKV2do
+	NJlZ2Ug5OBVmLitTo8lQp6uUyYkJ8liJSBDJCWcyaMFkVPSQ9idGHtD9oNYBPYTF5vGF
+	4th4RXJqeoYm+1ft1bz8Ap2usLCwCLcCczpdQX7eVe2v2ZqM9NRkRXysWMjnsVkhCN7/
+	AprrToI/50anh4ZF8KKipXJFikqdmZObryu+VnKjtLSsvALnKi8rLb1Rcq1Yl5+bk6lW
+	pSjk0ugoXkRYKN0NfxI7oJ/3DwwKpgF6pFAsS0hWZWRp84uul5bfrKyurqmpqzMg/Q+X
+	wqzV1dXUVFdX3iwvvV6Ur83KUCUnyMTCSICnBUPNwyrnBHg0uwWQKLQQhC6Ju6xUZ2kL
+	ivUVldW1hobGpuaWFqOxtbW1DacCa0ZjS0tzU2ODoba6skJfXKDNUisvx0kQfAiNQsJK
+	/tikRxkPfY7KYAG6VJ6UdiUnD8irausb77TeNbV3dHSa7+Fc5s6OjnbT3dY7jfW1VUCf
+	l3MlLUkuBXgWg4r63QmBPwdhR+hMNk8okSepNFpdCZA3NLeaOsz3LQ+6e6zWP3Auq7Wn
+	+4HlvrnD1NrcAPQlOq1GlSSXCHlsmOrIgdDrj0t6LOwkCp0ZzhWI4wA9t1B/q6a+ua3d
+	bOm29vb122wDg0M41+CAzdbf12vttpjb25rra27pC3MBPk4s4IYz6Sjrjw28O+xQ7Pxo
+	2eU0TW5RaWVdo9F0z2J92D849GhkdHRsfNyOa42Pj42OjjwaGux/aLXcMxkb6ypLi3I1
+	aZdl0Xwo+RMD7+sLjS6YzmRDsScor2gLS38zNLV1WHr6bMMjY/aJyanH06AZHAv5ezw1
+	OWEfGxm29fVYOtqaDL+VFmqvKBOg5NlMejAE3tf3SLdDKQ/VHoIyXp6kztHpKw1Nd81d
+	vbbhUfvk9MzT2Wdzc3MOh+M5bgXmwOKz2acz05P20WFbb5f5bpOhUq/LUSfJUdZjgT8m
+	6SHl/VG1syNFsQpVZl7JrVpA7+4bHLFPzszOPZ9fWFxaegF6iVshd0tLiwvzz+dmZybt
+	I4N93QBfe6skL1OliBWhwFNI/sd0u3OQ8kFURhhHII5PydAWV9TcbgP0odGJ6VnHwtLL
+	5Vcrq5jWcCuXv5VXyy+XFhyz0xOjQwDfdrumolibkRIvFnDCGNQgSPojnR5LeRrzIk8U
+	o1BlFeir6o0dDwB98snc/Ivl1bX1jY3Nra2tbVwLDG5ubKyvrS6/mJ97MgnwDzqM9VX6
+	giyVIkbEu8ikwTTnd6TgsZSHZQ0/Oi5ZDWGvbTZZegcB3bG4vLq+ub392vnmTMj5ent7
+	c311edEB8IO9FlNzLQRenRwHrZ7FwJL+ULODckcpH86NkiakavL1VQ1t5h7byMQTx9Ly
+	2ua2883O7p5L+7iV2+Duzhvn9uba8pLjycSIrcfc1lClz9ekJkijuOEo6Y8UPCp3MjX0
+	YqRIlpieUwRhb7f0Ddun5xZfrW85d/b29t++OyN6u7+3t+PcWn+1ODdtH+6ztEPgi3LS
+	E2WiyIuhVPLRggf2QDKNCSkvT1bnXq+sbzVbbaNTs/PLa1vO3T0Af/836APOhTy+f/fu
+	7d6uc2tteX52atRmNbfWV17PVSfLIemxgj/c7M7B7E5hsDgCSbxSk6evbjRZHg7bZxxL
+	q5vO3X0A90D/g2N5PAL+/q5zc3XJMWMffmgxNVbr8zTKeImAAwUPze5Qo/f18ycFQ7kL
+	pQpVtq689k5Hd//I5OzC8vr2m7137+Gqh5g/4kiHrIHZ9+/23myvLy/MTo70d3fcqS3X
+	ZasUUiEUfDDJ/3CjB/YgWNTxRLFQ7sU3DUazdWBsem5pZcO5+/YQOo6oP7Py2QAg+Le7
+	zo2VpbnpsQGr2Wi4WQwFHyviwdIu6Cg7avPQ6n6RJam11yob2u73Dtlnnr9c3YKwQ8J/
+	duV/PvtCHP3zc4cfPvwNgd9affl8xj7Ue7+tofKaVp0k+wU1O9To/zvJwRRHpjLZMLun
+	ZFwtqbptsvT9NfF0HlJ+Zx/YPRfGEeuxVjw+gX1/B5J+/unEX30W0+2qkqsZKTDDs5nQ
+	6I+yu9q8GLW6G9VN7V1/PkLlvvF6dx9S3n3NY78PV//pNgpJv7/7egMV/KM/u9qbqm+g
+	Zid2Nfoj7DDF0WGKQ20+X1/T/Hu3bWTq2eIKsEO5nxn0jx898FDwrzdWFp9Njdi6f2+u
+	gdUNNHpgp8Oq9nDOI3ZWhABWdZkFpTXQ5m2jj6HVbTr3PrHjKsAnmnHBQ7Pbc25Cs3s8
+	aoNGX1NakAkrO0EE60R2Dqxo07J0ZbUtnT0DiB1md9TqsOud+G04+wAzi5odmuGBfaCn
+	s6W2TJeVBqtazgnsFLiBjcKm97K6FrN1EE1x7jaPLoczwi/YQW7djR5NcoNWc0tdGTbB
+	R8FtLCxujuY8sHuWNmh6B3bHiwP2L3wX7j46YH/hwNiNBs/i5kvscPOeXVhhMN77Y2j8
+	52AfH/rjntFQUQgLuxgh9xTsrT8Xe6uX3Rv3E3udu94P5zzu2tlXDHn6PPQ6VO/flfNf
+	+Srcffwj2c/S9I6ta93z+4+Iu5cdd6l9gqH/rG2+ud4JubZxPa4j4pr24F6m82e6l+n8
+	6r0M3L8T9h6W2M8uiPrM6jyBn1US+hk1gX+bIPJvUgT+LZLIv0ET+t0DQr9zQtx3jXwI
+	/I6Zz3HvFnad/XcLu07zbiGR3ykl9rvExH2H3IfAewd8iLxnhMh7hTyBJ+IeMWAn7t5A
+	6HaE3ROKAk/YvcBY1qPt7wTcAw7sUPIE3fuP4KHkCXnmAxxS5zrhJYiAZ30cwBPwjBc4
+	ndAVeSKe7YNFHg7yIuKZTrCbAnV7OL+NiGd5AbyLnohnuLlCj8WeeGf3IXgIPdAT8cxG
+	tIfKhY8qn2BndSJ4Nz7En3BntLrwIfxYAmCnvaJhwLfcNuEP8u1G+P4/6GJnQ9/P6r2C
+	dwS8I+AdAe8I/BQj8C9ppK71CmVuZHN0cmVhbQplbmRvYmoKMzMgMCBvYmoKMjc2MApl
+	bmRvYmoKNDIgMCBvYmoKPDwgL0xlbmd0aCA0MyAwIFIgL1R5cGUgL1hPYmplY3QgL1N1
+	YnR5cGUgL0ltYWdlIC9XaWR0aCAyNTIgL0hlaWdodCAxMDQgL0NvbG9yU3BhY2UKL0Rl
+	dmljZUdyYXkgL0JpdHNQZXJDb21wb25lbnQgOCAvRmlsdGVyIC9GbGF0ZURlY29kZSA+
+	PgpzdHJlYW0KeAHtnPlXUukfx01LRZBFQUPAQBgBRZRcUDwYLoOpqGW4lKNH5aupiXZw
+	lDqYMuaIy+TCUdMyyaXM3cilmub0r83nuUA2LmXf+uHa5f2LnTjn8n49n+V57uU+j4+P
+	V94R8I6AdwS8I+AdARiBc2dGPyxciNj3k/xwrk9GfZHv7xkEN7Wf3/nz5y+cIYFdPz9s
+	GP5PfgwcsBGzf0BAoEck3MrjMDAgwB+5dg3AN+O7wFG0/YGaRAoigyigYFwLOUROg0ik
+	wEA0AJAAEP9vwkcVjiLuD9yATQmmUmk0Op1xBkSn02hUajAMQRDwI3yM/rSlj4IO5BBx
+	EpkM2MAcEspkslhhYWHhuBYYZLGYzNAQBoMOA0Amk1D0Ef0pQ+8ivxAQGESmUGkIG4jZ
+	ERERHA6Xy+XhWGCPwwGj7PDwMDQANCqFHBQY4Ir9abq+Cx3FPJhKD2Gywi9GcHi8S3y+
+	QBAlxL2iBAI+/xKPx4m4GM5ihtAh+BB7V+i/lvco3yHdgZyCyAGcF8kXCEXR0WKJVCqN
+	cSkWd3IbA4sScXS0SCjgR/IAH9FTgB4S/+t570YPImPkbG4kH7glMTKZPD4+QQG6jGMh
+	fwnx8XKZLEYC/PxILhujh8R3wX8x8h50CpXBDGNzLwlE0VLAViQmpSiVqWmqA6XjSAeu
+	VGmpSmVKUqICBkAaLRJc4rLDmAwq5RTwGHpAIDmYxmCGcyIFIkmsPCExWalKV2doNJlZ
+	2Ug5OBVmLitTo8lQp6uUyYkJ8liJSBDJCWcyaMFkVPSQ9idGHtD9oNYBPYTF5vGF4th4
+	RXJqeoYm+1ft1bz8Ap2usLCwCLcCczpdQX7eVe2v2ZqM9NRkRXysWMjnsVkhCN7/Aprr
+	ToI/50anh4ZF8KKipXJFikqdmZObryu+VnKjtLSsvALnKi8rLb1Rcq1Yl5+bk6lWpSjk
+	0ugoXkRYKN0NfxI7oJ/3DwwKpgF6pFAsS0hWZWRp84uul5bfrKyurqmpqzMg/Q+XwqzV
+	1dXUVFdX3iwvvV6Ur83KUCUnyMTCSICnBUPNwyrnBHg0uwWQKLQQhC6Ju6xUZ2kLivUV
+	ldW1hobGpuaWFqOxtbW1DacCa0ZjS0tzU2ODoba6skJfXKDNUisvx0kQfAiNQsJK/tik
+	RxkPfY7KYAG6VJ6UdiUnD8irausb77TeNbV3dHSa7+Fc5s6OjnbT3dY7jfW1VUCfl3Ml
+	LUkuBXgWg4r63QmBPwdhR+hMNk8okSepNFpdCZA3NLeaOsz3LQ+6e6zWP3Auq7Wn+4Hl
+	vrnD1NrcAPQlOq1GlSSXCHlsmOrIgdDrj0t6LOwkCp0ZzhWI4wA9t1B/q6a+ua3dbOm2
+	9vb122wDg0M41+CAzdbf12vttpjb25rra27pC3MBPk4s4IYz6Sjrjw28O+xQ7Pxo2eU0
+	TW5RaWVdo9F0z2J92D849GhkdHRsfNyOa42Pj42OjjwaGux/aLXcMxkb6ypLi3I1aZdl
+	0Xwo+RMD7+sLjS6YzmRDsScor2gLS38zNLV1WHr6bMMjY/aJyanH06AZHAv5ezw1OWEf
+	Gxm29fVYOtqaDL+VFmqvKBOg5NlMejAE3tf3SLdDKQ/VHoIyXp6kztHpKw1Nd81dvbbh
+	Ufvk9MzT2Wdzc3MOh+M5bgXmwOKz2acz05P20WFbb5f5bpOhUq/LUSfJUdZjgT8m6SHl
+	/VG1syNFsQpVZl7JrVpA7+4bHLFPzszOPZ9fWFxaegF6iVshd0tLiwvzz+dmZybtI4N9
+	3QBfe6skL1OliBWhwFNI/sd0u3OQ8kFURhhHII5PydAWV9TcbgP0odGJ6VnHwtLL5Vcr
+	q5jWcCuXv5VXyy+XFhyz0xOjQwDfdrumolibkRIvFnDCGNQgSPojnR5LeRrzIk8Uo1Bl
+	Feir6o0dDwB98snc/Ivl1bX1jY3Nra2tbVwLDG5ubKyvrS6/mJ97MgnwDzqM9VX6giyV
+	IkbEu8ikwTTnd6TgsZSHZQ0/Oi5ZDWGvbTZZegcB3bG4vLq+ub392vnmTMj5ent7c311
+	edEB8IO9FlNzLQRenRwHrZ7FwJL+ULODckcpH86NkiakavL1VQ1t5h7byMQTx9Ly2ua2
+	883O7p5L+7iV2+Duzhvn9uba8pLjycSIrcfc1lClz9ekJkijuOEo6Y8UPCp3MjX0YqRI
+	lpieUwRhb7f0Ddun5xZfrW85d/b29t++OyN6u7+3t+PcWn+1ODdtH+6ztEPgi3LSE2Wi
+	yIuhVPLRggf2QDKNCSkvT1bnXq+sbzVbbaNTs/PLa1vO3T0Af/836APOhTy+f/fu7d6u
+	c2tteX52atRmNbfWV17PVSfLIemxgj/c7M7B7E5hsDgCSbxSk6evbjRZHg7bZxxLq5vO
+	3X0A90D/g2N5PAL+/q5zc3XJMWMffmgxNVbr8zTKeImAAwUPze5Qo/f18ycFQ7kLpQpV
+	tq689k5Hd//I5OzC8vr2m7137+Gqh5g/4kiHrIHZ9+/23myvLy/MTo70d3fcqS3XZasU
+	UiEUfDDJ/3CjB/YgWNTxRLFQ7sU3DUazdWBsem5pZcO5+/YQOo6oP7Py2QAg+Le7zo2V
+	pbnpsQGr2Wi4WQwFHyviwdIu6Cg7avPQ6n6RJam11yob2u73Dtlnnr9c3YKwQ8J/duV/
+	PvtCHP3zc4cfPvwNgd9affl8xj7Ue7+tofKaVp0k+wU1O9To/zvJwRRHpjLZMLunZFwt
+	qbptsvT9NfF0HlJ+Zx/YPRfGEeuxVjw+gX1/B5J+/unEX30W0+2qkqsZKTDDs5nQ6I+y
+	u9q8GLW6G9VN7V1/PkLlvvF6dx9S3n3NY78PV//pNgpJv7/7egMV/KM/u9qbqm+gZid2
+	Nfoj7DDF0WGKQ20+X1/T/Hu3bWTq2eIKsEO5nxn0jx898FDwrzdWFp9Njdi6f2+ugdUN
+	NHpgp8Oq9nDOI3ZWhABWdZkFpTXQ5m2jj6HVbTr3PrHjKsAnmnHBQ7Pbc25Cs3s8aoNG
+	X1NakAkrO0EE60R2Dqxo07J0ZbUtnT0DiB1md9TqsOud+G04+wAzi5odmuGBfaCns6W2
+	TJeVBqtazgnsFLiBjcKm97K6FrN1EE1x7jaPLoczwi/YQW7djR5NcoNWc0tdGTbBR8Ft
+	LCxujuY8sHuWNmh6B3bHiwP2L3wX7j46YH/hwNiNBs/i5kvscPOeXVhhMN77Y2j852Af
+	H/rjntFQUQgLuxgh9xTsrT8Xe6uX3Rv3E3udu94P5zzu2tlXDHn6PPQ6VO/flfNf+Src
+	ffwj2c/S9I6ta93z+4+Iu5cdd6l9gqH/rG2+ud4JubZxPa4j4pr24F6m82e6l+n86r0M
+	3L8T9h6W2M8uiPrM6jyBn1US+hk1gX+bIPJvUgT+LZLIv0ET+t0DQr9zQtx3jXwI/I6Z
+	z3HvFnad/XcLu07zbiGR3ykl9rvExH2H3IfAewd8iLxnhMh7hTyBJ+IeMWAn7t5A6HaE
+	3ROKAk/YvcBY1qPt7wTcAw7sUPIE3fuP4KHkCXnmAxxS5zrhJYiAZ30cwBPwjBc4ndAV
+	eSKe7YNFHg7yIuKZTrCbAnV7OL+NiGd5AbyLnohnuLlCj8WeeGf3IXgIPdAT8cxGtIfK
+	hY8qn2BndSJ4Nz7En3BntLrwIfxYAmCnvaJhwLfcNuEP8u1G+P4/6GJnQ9/P6r2CdwS8
+	I+AdAe8I/BQj8C9ppK71CmVuZHN0cmVhbQplbmRvYmoKNDMgMCBvYmoKMjc2MAplbmRv
+	YmoKNDQgMCBvYmoKPDwgL0xlbmd0aCA0NSAwIFIgL1R5cGUgL1hPYmplY3QgL1N1YnR5
+	cGUgL0ltYWdlIC9XaWR0aCAyNTIgL0hlaWdodCAxMDQgL0NvbG9yU3BhY2UKL0Rldmlj
+	ZUdyYXkgL0JpdHNQZXJDb21wb25lbnQgOCAvRmlsdGVyIC9GbGF0ZURlY29kZSA+Pgpz
+	dHJlYW0KeAHtnPlXUukfx01LRZBFQUPAQBgBRZRcUDwYLoOpqGW4lKNH5aupiXZwlDqY
+	MuaIy+TCUdMyyaXM3cilmub0r83nuUA2LmXf+uHa5f2LnTjn8n49n+V57uU+j4+PV94R
+	8I6AdwS8I+AdARiBc2dGPyxciNj3k/xwrk9GfZHv7xkEN7Wf3/nz5y+cIYFdPz9sGP5P
+	fgwcsBGzf0BAoEck3MrjMDAgwB+5dg3AN+O7wFG0/YGaRAoigyigYFwLOUROg0ikwEA0
+	AJAAEP9vwkcVjiLuD9yATQmmUmk0Op1xBkSn02hUajAMQRDwI3yM/rSlj4IO5BBxEpkM
+	2MAcEspkslhhYWHhuBYYZLGYzNAQBoMOA0Amk1D0Ef0pQ+8ivxAQGESmUGkIG4jZERER
+	HA6Xy+XhWGCPwwGj7PDwMDQANCqFHBQY4Ir9abq+Cx3FPJhKD2Gywi9GcHi8S3y+QBAl
+	xL2iBAI+/xKPx4m4GM5ihtAh+BB7V+i/lvco3yHdgZyCyAGcF8kXCEXR0WKJVCqNcSkW
+	d3IbA4sScXS0SCjgR/IAH9FTgB4S/+t570YPImPkbG4kH7glMTKZPD4+QQG6jGMhfwnx
+	8XKZLEYC/PxILhujh8R3wX8x8h50CpXBDGNzLwlE0VLAViQmpSiVqWmqA6XjSAeuVGmp
+	SmVKUqICBkAaLRJc4rLDmAwq5RTwGHpAIDmYxmCGcyIFIkmsPCExWalKV2doNJlZ2Ug5
+	OBVmLitTo8lQp6uUyYkJ8liJSBDJCWcyaMFkVPSQ9idGHtD9oNYBPYTF5vGF4th4RXJq
+	eoYm+1ft1bz8Ap2usLCwCLcCczpdQX7eVe2v2ZqM9NRkRXysWMjnsVkhCN7/AprrToI/
+	50anh4ZF8KKipXJFikqdmZObryu+VnKjtLSsvALnKi8rLb1Rcq1Yl5+bk6lWpSjk0ugo
+	XkRYKN0NfxI7oJ/3DwwKpgF6pFAsS0hWZWRp84uul5bfrKyurqmpqzMg/Q+XwqzV1dXU
+	VFdX3iwvvV6Ur83KUCUnyMTCSICnBUPNwyrnBHg0uwWQKLQQhC6Ju6xUZ2kLivUVldW1
+	hobGpuaWFqOxtbW1DacCa0ZjS0tzU2ODoba6skJfXKDNUisvx0kQfAiNQsJK/tikRxkP
+	fY7KYAG6VJ6UdiUnD8irausb77TeNbV3dHSa7+Fc5s6OjnbT3dY7jfW1VUCfl3MlLUku
+	BXgWg4r63QmBPwdhR+hMNk8okSepNFpdCZA3NLeaOsz3LQ+6e6zWP3Auq7Wn+4HlvrnD
+	1NrcAPQlOq1GlSSXCHlsmOrIgdDrj0t6LOwkCp0ZzhWI4wA9t1B/q6a+ua3dbOm29vb1
+	22wDg0M41+CAzdbf12vttpjb25rra27pC3MBPk4s4IYz6Sjrjw28O+xQ7Pxo2eU0TW5R
+	aWVdo9F0z2J92D849GhkdHRsfNyOa42Pj42OjjwaGux/aLXcMxkb6ypLi3I1aZdl0Xwo
+	+RMD7+sLjS6YzmRDsScor2gLS38zNLV1WHr6bMMjY/aJyanH06AZHAv5ezw1OWEfGxm2
+	9fVYOtqaDL+VFmqvKBOg5NlMejAE3tf3SLdDKQ/VHoIyXp6kztHpKw1Nd81dvbbhUfvk
+	9MzT2Wdzc3MOh+M5bgXmwOKz2acz05P20WFbb5f5bpOhUq/LUSfJUdZjgT8m6SHl/VG1
+	syNFsQpVZl7JrVpA7+4bHLFPzszOPZ9fWFxaegF6iVshd0tLiwvzz+dmZybtI4N93QBf
+	e6skL1OliBWhwFNI/sd0u3OQ8kFURhhHII5PydAWV9TcbgP0odGJ6VnHwtLL5Vcrq5jW
+	cCuXv5VXyy+XFhyz0xOjQwDfdrumolibkRIvFnDCGNQgSPojnR5LeRrzIk8Uo1BlFeir
+	6o0dDwB98snc/Ivl1bX1jY3Nra2tbVwLDG5ubKyvrS6/mJ97MgnwDzqM9VX6giyVIkbE
+	u8ikwTTnd6TgsZSHZQ0/Oi5ZDWGvbTZZegcB3bG4vLq+ub392vnmTMj5ent7c311edEB
+	8IO9FlNzLQRenRwHrZ7FwJL+ULODckcpH86NkiakavL1VQ1t5h7byMQTx9Ly2ua2883O
+	7p5L+7iV2+Duzhvn9uba8pLjycSIrcfc1lClz9ekJkijuOEo6Y8UPCp3MjX0YqRIlpie
+	UwRhb7f0Ddun5xZfrW85d/b29t++OyN6u7+3t+PcWn+1ODdtH+6ztEPgi3LSE2WiyIuh
+	VPLRggf2QDKNCSkvT1bnXq+sbzVbbaNTs/PLa1vO3T0Af/836APOhTy+f/fu7d6uc2tt
+	eX52atRmNbfWV17PVSfLIemxgj/c7M7B7E5hsDgCSbxSk6evbjRZHg7bZxxLq5vO3X0A
+	90D/g2N5PAL+/q5zc3XJMWMffmgxNVbr8zTKeImAAwUPze5Qo/f18ycFQ7kLpQpVtq68
+	9k5Hd//I5OzC8vr2m7137+Gqh5g/4kiHrIHZ9+/23myvLy/MTo70d3fcqS3XZasUUiEU
+	fDDJ/3CjB/YgWNTxRLFQ7sU3DUazdWBsem5pZcO5+/YQOo6oP7Py2QAg+Le7zo2Vpbnp
+	sQGr2Wi4WQwFHyviwdIu6Cg7avPQ6n6RJam11yob2u73Dtlnnr9c3YKwQ8J/duV/PvtC
+	HP3zc4cfPvwNgd9affl8xj7Ue7+tofKaVp0k+wU1O9To/zvJwRRHpjLZMLunZFwtqbpt
+	svT9NfF0HlJ+Zx/YPRfGEeuxVjw+gX1/B5J+/unEX30W0+2qkqsZKTDDs5nQ6I+yu9q8
+	GLW6G9VN7V1/PkLlvvF6dx9S3n3NY78PV//pNgpJv7/7egMV/KM/u9qbqm+gZid2Nfoj
+	7DDF0WGKQ20+X1/T/Hu3bWTq2eIKsEO5nxn0jx898FDwrzdWFp9Njdi6f2+ugdUNNHpg
+	p8Oq9nDOI3ZWhABWdZkFpTXQ5m2jj6HVbTr3PrHjKsAnmnHBQ7Pbc25Cs3s8aoNGX1Na
+	kAkrO0EE60R2Dqxo07J0ZbUtnT0DiB1md9TqsOud+G04+wAzi5odmuGBfaCns6W2TJeV
+	BqtazgnsFLiBjcKm97K6FrN1EE1x7jaPLoczwi/YQW7djR5NcoNWc0tdGTbBR8FtLCxu
+	juY8sHuWNmh6B3bHiwP2L3wX7j46YH/hwNiNBs/i5kvscPOeXVhhMN77Y2j852AfH/rj
+	ntFQUQgLuxgh9xTsrT8Xe6uX3Rv3E3udu94P5zzu2tlXDHn6PPQ6VO/flfNf+Srcffwj
+	2c/S9I6ta93z+4+Iu5cdd6l9gqH/rG2+ud4JubZxPa4j4pr24F6m82e6l+n86r0M3L8T
+	9h6W2M8uiPrM6jyBn1US+hk1gX+bIPJvUgT+LZLIv0ET+t0DQr9zQtx3jXwI/I6Zz3Hv
+	Fnad/XcLu07zbiGR3ykl9rvExH2H3IfAewd8iLxnhMh7hTyBJ+IeMWAn7t5A6HaE3ROK
+	Ak/YvcBY1qPt7wTcAw7sUPIE3fuP4KHkCXnmAxxS5zrhJYiAZ30cwBPwjBc4ndAVeSKe
+	7YNFHg7yIuKZTrCbAnV7OL+NiGd5AbyLnohnuLlCj8WeeGf3IXgIPdAT8cxGtIfKhY8q
+	n2BndSJ4Nz7En3BntLrwIfxYAmCnvaJhwLfcNuEP8u1G+P4/6GJnQ9/P6r2CdwS8I+Ad
+	Ae8I/BQj8C9ppK71CmVuZHN0cmVhbQplbmRvYmoKNDUgMCBvYmoKMjc2MAplbmRvYmoK
+	NDAgMCBvYmoKPDwgL0xlbmd0aCA0MSAwIFIgL1R5cGUgL1hPYmplY3QgL1N1YnR5cGUg
+	L0ltYWdlIC9XaWR0aCAyNTIgL0hlaWdodCAxMDQgL0NvbG9yU3BhY2UKL0RldmljZUdy
+	YXkgL0JpdHNQZXJDb21wb25lbnQgOCAvRmlsdGVyIC9GbGF0ZURlY29kZSA+PgpzdHJl
+	YW0KeAHtnPlXUukfx01LRZBFQUPAQBgBRZRcUDwYLoOpqGW4lKNH5aupiXZwlDqYMuaI
+	y+TCUdMyyaXM3cilmub0r83nuUA2LmXf+uHa5f2LnTjn8n49n+V57uU+j4+PV94R8I6A
+	dwS8I+AdARiBc2dGPyxciNj3k/xwrk9GfZHv7xkEN7Wf3/nz5y+cIYFdPz9sGP5Pfgwc
+	sBGzf0BAoEck3MrjMDAgwB+5dg3AN+O7wFG0/YGaRAoigyigYFwLOUROg0ikwEA0AJAA
+	EP9vwkcVjiLuD9yATQmmUmk0Op1xBkSn02hUajAMQRDwI3yM/rSlj4IO5BBxEpkM2MAc
+	EspkslhhYWHhuBYYZLGYzNAQBoMOA0Amk1D0Ef0pQ+8ivxAQGESmUGkIG4jZERERHA6X
+	y+XhWGCPwwGj7PDwMDQANCqFHBQY4Ir9abq+Cx3FPJhKD2Gywi9GcHi8S3y+QBAlxL2i
+	BAI+/xKPx4m4GM5ihtAh+BB7V+i/lvco3yHdgZyCyAGcF8kXCEXR0WKJVCqNcSkWd3Ib
+	A4sScXS0SCjgR/IAH9FTgB4S/+t570YPImPkbG4kH7glMTKZPD4+QQG6jGMhfwnx8XKZ
+	LEYC/PxILhujh8R3wX8x8h50CpXBDGNzLwlE0VLAViQmpSiVqWmqA6XjSAeuVGmpSmVK
+	UqICBkAaLRJc4rLDmAwq5RTwGHpAIDmYxmCGcyIFIkmsPCExWalKV2doNJlZ2Ug5OBVm
+	LitTo8lQp6uUyYkJ8liJSBDJCWcyaMFkVPSQ9idGHtD9oNYBPYTF5vGF4th4RXJqeoYm
+	+1ft1bz8Ap2usLCwCLcCczpdQX7eVe2v2ZqM9NRkRXysWMjnsVkhCN7/AprrToI/50an
+	h4ZF8KKipXJFikqdmZObryu+VnKjtLSsvALnKi8rLb1Rcq1Yl5+bk6lWpSjk0ugoXkRY
+	KN0NfxI7oJ/3DwwKpgF6pFAsS0hWZWRp84uul5bfrKyurqmpqzMg/Q+XwqzV1dXUVFdX
+	3iwvvV6Ur83KUCUnyMTCSICnBUPNwyrnBHg0uwWQKLQQhC6Ju6xUZ2kLivUVldW1hobG
+	puaWFqOxtbW1DacCa0ZjS0tzU2ODoba6skJfXKDNUisvx0kQfAiNQsJK/tikRxkPfY7K
+	YAG6VJ6UdiUnD8irausb77TeNbV3dHSa7+Fc5s6OjnbT3dY7jfW1VUCfl3MlLUkuBXgW
+	g4r63QmBPwdhR+hMNk8okSepNFpdCZA3NLeaOsz3LQ+6e6zWP3Auq7Wn+4HlvrnD1Nrc
+	APQlOq1GlSSXCHlsmOrIgdDrj0t6LOwkCp0ZzhWI4wA9t1B/q6a+ua3dbOm29vb122wD
+	g0M41+CAzdbf12vttpjb25rra27pC3MBPk4s4IYz6Sjrjw28O+xQ7Pxo2eU0TW5RaWVd
+	o9F0z2J92D849GhkdHRsfNyOa42Pj42OjjwaGux/aLXcMxkb6ypLi3I1aZdl0Xwo+RMD
+	7+sLjS6YzmRDsScor2gLS38zNLV1WHr6bMMjY/aJyanH06AZHAv5ezw1OWEfGxm29fVY
+	OtqaDL+VFmqvKBOg5NlMejAE3tf3SLdDKQ/VHoIyXp6kztHpKw1Nd81dvbbhUfvk9MzT
+	2Wdzc3MOh+M5bgXmwOKz2acz05P20WFbb5f5bpOhUq/LUSfJUdZjgT8m6SHl/VG1syNF
+	sQpVZl7JrVpA7+4bHLFPzszOPZ9fWFxaegF6iVshd0tLiwvzz+dmZybtI4N93QBfe6sk
+	L1OliBWhwFNI/sd0u3OQ8kFURhhHII5PydAWV9TcbgP0odGJ6VnHwtLL5Vcrq5jWcCuX
+	v5VXyy+XFhyz0xOjQwDfdrumolibkRIvFnDCGNQgSPojnR5LeRrzIk8Uo1BlFeir6o0d
+	DwB98snc/Ivl1bX1jY3Nra2tbVwLDG5ubKyvrS6/mJ97MgnwDzqM9VX6giyVIkbEu8ik
+	wTTnd6TgsZSHZQ0/Oi5ZDWGvbTZZegcB3bG4vLq+ub392vnmTMj5ent7c311edEB8IO9
+	FlNzLQRenRwHrZ7FwJL+ULODckcpH86NkiakavL1VQ1t5h7byMQTx9Ly2ua2883O7p5L
+	+7iV2+Duzhvn9uba8pLjycSIrcfc1lClz9ekJkijuOEo6Y8UPCp3MjX0YqRIlpieUwRh
+	b7f0Ddun5xZfrW85d/b29t++OyN6u7+3t+PcWn+1ODdtH+6ztEPgi3LSE2WiyIuhVPLR
+	ggf2QDKNCSkvT1bnXq+sbzVbbaNTs/PLa1vO3T0Af/836APOhTy+f/fu7d6uc2tteX52
+	atRmNbfWV17PVSfLIemxgj/c7M7B7E5hsDgCSbxSk6evbjRZHg7bZxxLq5vO3X0A90D/
+	g2N5PAL+/q5zc3XJMWMffmgxNVbr8zTKeImAAwUPze5Qo/f18ycFQ7kLpQpVtq689k5H
+	d//I5OzC8vr2m7137+Gqh5g/4kiHrIHZ9+/23myvLy/MTo70d3fcqS3XZasUUiEUfDDJ
+	/3CjB/YgWNTxRLFQ7sU3DUazdWBsem5pZcO5+/YQOo6oP7Py2QAg+Le7zo2VpbnpsQGr
+	2Wi4WQwFHyviwdIu6Cg7avPQ6n6RJam11yob2u73Dtlnnr9c3YKwQ8J/duV/PvtCHP3z
+	c4cfPvwNgd9affl8xj7Ue7+tofKaVp0k+wU1O9To/zvJwRRHpjLZMLunZFwtqbptsvT9
+	NfF0HlJ+Zx/YPRfGEeuxVjw+gX1/B5J+/unEX30W0+2qkqsZKTDDs5nQ6I+yu9q8GLW6
+	G9VN7V1/PkLlvvF6dx9S3n3NY78PV//pNgpJv7/7egMV/KM/u9qbqm+gZid2Nfoj7DDF
+	0WGKQ20+X1/T/Hu3bWTq2eIKsEO5nxn0jx898FDwrzdWFp9Njdi6f2+ugdUNNHpgp8Oq
+	9nDOI3ZWhABWdZkFpTXQ5m2jj6HVbTr3PrHjKsAnmnHBQ7Pbc25Cs3s8aoNGX1NakAkr
+	O0EE60R2Dqxo07J0ZbUtnT0DiB1md9TqsOud+G04+wAzi5odmuGBfaCns6W2TJeVBqta
+	zgnsFLiBjcKm97K6FrN1EE1x7jaPLoczwi/YQW7djR5NcoNWc0tdGTbBR8FtLCxujuY8
+	sHuWNmh6B3bHiwP2L3wX7j46YH/hwNiNBs/i5kvscPOeXVhhMN77Y2j852AfH/rjntFQ
+	UQgLuxgh9xTsrT8Xe6uX3Rv3E3udu94P5zzu2tlXDHn6PPQ6VO/flfNf+Srcffwj2c/S
+	9I6ta93z+4+Iu5cdd6l9gqH/rG2+ud4JubZxPa4j4pr24F6m82e6l+n86r0M3L8T9h6W
+	2M8uiPrM6jyBn1US+hk1gX+bIPJvUgT+LZLIv0ET+t0DQr9zQtx3jXwI/I6Zz3HvFnad
+	/XcLu07zbiGR3ykl9rvExH2H3IfAewd8iLxnhMh7hTyBJ+IeMWAn7t5A6HaE3ROKAk/Y
+	vcBY1qPt7wTcAw7sUPIE3fuP4KHkCXnmAxxS5zrhJYiAZ30cwBPwjBc4ndAVeSKe7YNF
+	Hg7yIuKZTrCbAnV7OL+NiGd5AbyLnohnuLlCj8WeeGf3IXgIPdAT8cxGtIfKhY8qn2Bn
+	dSJ4Nz7En3BntLrwIfxYAmCnvaJhwLfcNuEP8u1G+P4/6GJnQ9/P6r2CdwS8I+AdAe8I
+	/BQj8C9ppK71CmVuZHN0cmVhbQplbmRvYmoKNDEgMCBvYmoKMjc2MAplbmRvYmoKMzQg
+	MCBvYmoKPDwgL0xlbmd0aCAzNSAwIFIgL1R5cGUgL1hPYmplY3QgL1N1YnR5cGUgL0lt
+	YWdlIC9XaWR0aCAyNTIgL0hlaWdodCAxMDQgL0NvbG9yU3BhY2UKL0RldmljZUdyYXkg
+	L0JpdHNQZXJDb21wb25lbnQgOCAvRmlsdGVyIC9GbGF0ZURlY29kZSA+PgpzdHJlYW0K
+	eAHtnPlXUukfx01LRZBFQUPAQBgBRZRcUDwYLoOpqGW4lKNH5aupiXZwlDqYMuaIy+TC
+	UdMyyaXM3cilmub0r83nuUA2LmXf+uHa5f2LnTjn8n49n+V57uU+j4+PV94R8I6AdwS8
+	I+AdARiBc2dGPyxciNj3k/xwrk9GfZHv7xkEN7Wf3/nz5y+cIYFdPz9sGP5PfgwcsBGz
+	f0BAoEck3MrjMDAgwB+5dg3AN+O7wFG0/YGaRAoigyigYFwLOUROg0ikwEA0AJAAEP9v
+	wkcVjiLuD9yATQmmUmk0Op1xBkSn02hUajAMQRDwI3yM/rSlj4IO5BBxEpkM2MAcEspk
+	slhhYWHhuBYYZLGYzNAQBoMOA0Amk1D0Ef0pQ+8ivxAQGESmUGkIG4jZERERHA6Xy+Xh
+	WGCPwwGj7PDwMDQANCqFHBQY4Ir9abq+Cx3FPJhKD2Gywi9GcHi8S3y+QBAlxL2iBAI+
+	/xKPx4m4GM5ihtAh+BB7V+i/lvco3yHdgZyCyAGcF8kXCEXR0WKJVCqNcSkWd3IbA4sS
+	cXS0SCjgR/IAH9FTgB4S/+t570YPImPkbG4kH7glMTKZPD4+QQG6jGMhfwnx8XKZLEYC
+	/PxILhujh8R3wX8x8h50CpXBDGNzLwlE0VLAViQmpSiVqWmqA6XjSAeuVGmpSmVKUqIC
+	BkAaLRJc4rLDmAwq5RTwGHpAIDmYxmCGcyIFIkmsPCExWalKV2doNJlZ2Ug5OBVmLitT
+	o8lQp6uUyYkJ8liJSBDJCWcyaMFkVPSQ9idGHtD9oNYBPYTF5vGF4th4RXJqeoYm+1ft
+	1bz8Ap2usLCwCLcCczpdQX7eVe2v2ZqM9NRkRXysWMjnsVkhCN7/AprrToI/50anh4ZF
+	8KKipXJFikqdmZObryu+VnKjtLSsvALnKi8rLb1Rcq1Yl5+bk6lWpSjk0ugoXkRYKN0N
+	fxI7oJ/3DwwKpgF6pFAsS0hWZWRp84uul5bfrKyurqmpqzMg/Q+XwqzV1dXUVFdX3iwv
+	vV6Ur83KUCUnyMTCSICnBUPNwyrnBHg0uwWQKLQQhC6Ju6xUZ2kLivUVldW1hobGpuaW
+	FqOxtbW1DacCa0ZjS0tzU2ODoba6skJfXKDNUisvx0kQfAiNQsJK/tikRxkPfY7KYAG6
+	VJ6UdiUnD8irausb77TeNbV3dHSa7+Fc5s6OjnbT3dY7jfW1VUCfl3MlLUkuBXgWg4r6
+	3QmBPwdhR+hMNk8okSepNFpdCZA3NLeaOsz3LQ+6e6zWP3Auq7Wn+4HlvrnD1NrcAPQl
+	Oq1GlSSXCHlsmOrIgdDrj0t6LOwkCp0ZzhWI4wA9t1B/q6a+ua3dbOm29vb122wDg0M4
+	1+CAzdbf12vttpjb25rra27pC3MBPk4s4IYz6Sjrjw28O+xQ7Pxo2eU0TW5RaWVdo9F0
+	z2J92D849GhkdHRsfNyOa42Pj42OjjwaGux/aLXcMxkb6ypLi3I1aZdl0Xwo+RMD7+sL
+	jS6YzmRDsScor2gLS38zNLV1WHr6bMMjY/aJyanH06AZHAv5ezw1OWEfGxm29fVYOtqa
+	DL+VFmqvKBOg5NlMejAE3tf3SLdDKQ/VHoIyXp6kztHpKw1Nd81dvbbhUfvk9MzT2Wdz
+	c3MOh+M5bgXmwOKz2acz05P20WFbb5f5bpOhUq/LUSfJUdZjgT8m6SHl/VG1syNFsQpV
+	Zl7JrVpA7+4bHLFPzszOPZ9fWFxaegF6iVshd0tLiwvzz+dmZybtI4N93QBfe6skL1Ol
+	iBWhwFNI/sd0u3OQ8kFURhhHII5PydAWV9TcbgP0odGJ6VnHwtLL5Vcrq5jWcCuXv5VX
+	yy+XFhyz0xOjQwDfdrumolibkRIvFnDCGNQgSPojnR5LeRrzIk8Uo1BlFeir6o0dDwB9
+	8snc/Ivl1bX1jY3Nra2tbVwLDG5ubKyvrS6/mJ97MgnwDzqM9VX6giyVIkbEu8ikwTTn
+	d6TgsZSHZQ0/Oi5ZDWGvbTZZegcB3bG4vLq+ub392vnmTMj5ent7c311edEB8IO9FlNz
+	LQRenRwHrZ7FwJL+ULODckcpH86NkiakavL1VQ1t5h7byMQTx9Ly2ua2883O7p5L+7iV
+	2+Duzhvn9uba8pLjycSIrcfc1lClz9ekJkijuOEo6Y8UPCp3MjX0YqRIlpieUwRhb7f0
+	Ddun5xZfrW85d/b29t++OyN6u7+3t+PcWn+1ODdtH+6ztEPgi3LSE2WiyIuhVPLRggf2
+	QDKNCSkvT1bnXq+sbzVbbaNTs/PLa1vO3T0Af/836APOhTy+f/fu7d6uc2tteX52atRm
+	NbfWV17PVSfLIemxgj/c7M7B7E5hsDgCSbxSk6evbjRZHg7bZxxLq5vO3X0A90D/g2N5
+	PAL+/q5zc3XJMWMffmgxNVbr8zTKeImAAwUPze5Qo/f18ycFQ7kLpQpVtq689k5Hd//I
+	5OzC8vr2m7137+Gqh5g/4kiHrIHZ9+/23myvLy/MTo70d3fcqS3XZasUUiEUfDDJ/3Cj
+	B/YgWNTxRLFQ7sU3DUazdWBsem5pZcO5+/YQOo6oP7Py2QAg+Le7zo2VpbnpsQGr2Wi4
+	WQwFHyviwdIu6Cg7avPQ6n6RJam11yob2u73Dtlnnr9c3YKwQ8J/duV/PvtCHP3zc4cf
+	PvwNgd9affl8xj7Ue7+tofKaVp0k+wU1O9To/zvJwRRHpjLZMLunZFwtqbptsvT9NfF0
+	HlJ+Zx/YPRfGEeuxVjw+gX1/B5J+/unEX30W0+2qkqsZKTDDs5nQ6I+yu9q8GLW6G9VN
+	7V1/PkLlvvF6dx9S3n3NY78PV//pNgpJv7/7egMV/KM/u9qbqm+gZid2Nfoj7DDF0WGK
+	Q20+X1/T/Hu3bWTq2eIKsEO5nxn0jx898FDwrzdWFp9Njdi6f2+ugdUNNHpgp8Oq9nDO
+	I3ZWhABWdZkFpTXQ5m2jj6HVbTr3PrHjKsAnmnHBQ7Pbc25Cs3s8aoNGX1NakAkrO0EE
+	60R2Dqxo07J0ZbUtnT0DiB1md9TqsOud+G04+wAzi5odmuGBfaCns6W2TJeVBqtazgns
+	FLiBjcKm97K6FrN1EE1x7jaPLoczwi/YQW7djR5NcoNWc0tdGTbBR8FtLCxujuY8sHuW
+	Nmh6B3bHiwP2L3wX7j46YH/hwNiNBs/i5kvscPOeXVhhMN77Y2j852AfH/rjntFQUQgL
+	uxgh9xTsrT8Xe6uX3Rv3E3udu94P5zzu2tlXDHn6PPQ6VO/flfNf+Srcffwj2c/S9I6t
+	a93z+4+Iu5cdd6l9gqH/rG2+ud4JubZxPa4j4pr24F6m82e6l+n86r0M3L8T9h6W2M8u
+	iPrM6jyBn1US+hk1gX+bIPJvUgT+LZLIv0ET+t0DQr9zQtx3jXwI/I6Zz3HvFnad/XcL
+	u07zbiGR3ykl9rvExH2H3IfAewd8iLxnhMh7hTyBJ+IeMWAn7t5A6HaE3ROKAk/YvcBY
+	1qPt7wTcAw7sUPIE3fuP4KHkCXnmAxxS5zrhJYiAZ30cwBPwjBc4ndAVeSKe7YNFHg7y
+	IuKZTrCbAnV7OL+NiGd5AbyLnohnuLlCj8WeeGf3IXgIPdAT8cxGtIfKhY8qn2BndSJ4
+	Nz7En3BntLrwIfxYAmCnvaJhwLfcNuEP8u1G+P4/6GJnQ9/P6r2CdwS8I+AdAe8I/BQj
+	8C9ppK71CmVuZHN0cmVhbQplbmRvYmoKMzUgMCBvYmoKMjc2MAplbmRvYmoKMzggMCBv
+	YmoKPDwgL0xlbmd0aCAzOSAwIFIgL1R5cGUgL1hPYmplY3QgL1N1YnR5cGUgL0ltYWdl
+	IC9XaWR0aCAyNTIgL0hlaWdodCAxMDQgL0NvbG9yU3BhY2UKL0RldmljZUdyYXkgL0Jp
+	dHNQZXJDb21wb25lbnQgOCAvRmlsdGVyIC9GbGF0ZURlY29kZSA+PgpzdHJlYW0KeAHt
+	nPlXUukfx01LRZBFQUPAQBgBRZRcUDwYLoOpqGW4lKNH5aupiXZwlDqYMuaIy+TCUdMy
+	yaXM3cilmub0r83nuUA2LmXf+uHa5f2LnTjn8n49n+V57uU+j4+PV94R8I6AdwS8I+Ad
+	ARiBc2dGPyxciNj3k/xwrk9GfZHv7xkEN7Wf3/nz5y+cIYFdPz9sGP5PfgwcsBGzf0BA
+	oEck3MrjMDAgwB+5dg3AN+O7wFG0/YGaRAoigyigYFwLOUROg0ikwEA0AJAAEP9vwkcV
+	jiLuD9yATQmmUmk0Op1xBkSn02hUajAMQRDwI3yM/rSlj4IO5BBxEpkM2MAcEspkslhh
+	YWHhuBYYZLGYzNAQBoMOA0Amk1D0Ef0pQ+8ivxAQGESmUGkIG4jZERERHA6Xy+XhWGCP
+	wwGj7PDwMDQANCqFHBQY4Ir9abq+Cx3FPJhKD2Gywi9GcHi8S3y+QBAlxL2iBAI+/xKP
+	x4m4GM5ihtAh+BB7V+i/lvco3yHdgZyCyAGcF8kXCEXR0WKJVCqNcSkWd3IbA4sScXS0
+	SCjgR/IAH9FTgB4S/+t570YPImPkbG4kH7glMTKZPD4+QQG6jGMhfwnx8XKZLEYC/PxI
+	Lhujh8R3wX8x8h50CpXBDGNzLwlE0VLAViQmpSiVqWmqA6XjSAeuVGmpSmVKUqICBkAa
+	LRJc4rLDmAwq5RTwGHpAIDmYxmCGcyIFIkmsPCExWalKV2doNJlZ2Ug5OBVmLitTo8lQ
+	p6uUyYkJ8liJSBDJCWcyaMFkVPSQ9idGHtD9oNYBPYTF5vGF4th4RXJqeoYm+1ft1bz8
+	Ap2usLCwCLcCczpdQX7eVe2v2ZqM9NRkRXysWMjnsVkhCN7/AprrToI/50anh4ZF8KKi
+	pXJFikqdmZObryu+VnKjtLSsvALnKi8rLb1Rcq1Yl5+bk6lWpSjk0ugoXkRYKN0NfxI7
+	oJ/3DwwKpgF6pFAsS0hWZWRp84uul5bfrKyurqmpqzMg/Q+XwqzV1dXUVFdX3iwvvV6U
+	r83KUCUnyMTCSICnBUPNwyrnBHg0uwWQKLQQhC6Ju6xUZ2kLivUVldW1hobGpuaWFqOx
+	tbW1DacCa0ZjS0tzU2ODoba6skJfXKDNUisvx0kQfAiNQsJK/tikRxkPfY7KYAG6VJ6U
+	diUnD8irausb77TeNbV3dHSa7+Fc5s6OjnbT3dY7jfW1VUCfl3MlLUkuBXgWg4r63QmB
+	PwdhR+hMNk8okSepNFpdCZA3NLeaOsz3LQ+6e6zWP3Auq7Wn+4HlvrnD1NrcAPQlOq1G
+	lSSXCHlsmOrIgdDrj0t6LOwkCp0ZzhWI4wA9t1B/q6a+ua3dbOm29vb122wDg0M41+CA
+	zdbf12vttpjb25rra27pC3MBPk4s4IYz6Sjrjw28O+xQ7Pxo2eU0TW5RaWVdo9F0z2J9
+	2D849GhkdHRsfNyOa42Pj42OjjwaGux/aLXcMxkb6ypLi3I1aZdl0Xwo+RMD7+sLjS6Y
+	zmRDsScor2gLS38zNLV1WHr6bMMjY/aJyanH06AZHAv5ezw1OWEfGxm29fVYOtqaDL+V
+	FmqvKBOg5NlMejAE3tf3SLdDKQ/VHoIyXp6kztHpKw1Nd81dvbbhUfvk9MzT2Wdzc3MO
+	h+M5bgXmwOKz2acz05P20WFbb5f5bpOhUq/LUSfJUdZjgT8m6SHl/VG1syNFsQpVZl7J
+	rVpA7+4bHLFPzszOPZ9fWFxaegF6iVshd0tLiwvzz+dmZybtI4N93QBfe6skL1OliBWh
+	wFNI/sd0u3OQ8kFURhhHII5PydAWV9TcbgP0odGJ6VnHwtLL5Vcrq5jWcCuXv5VXyy+X
+	Fhyz0xOjQwDfdrumolibkRIvFnDCGNQgSPojnR5LeRrzIk8Uo1BlFeir6o0dDwB98snc
+	/Ivl1bX1jY3Nra2tbVwLDG5ubKyvrS6/mJ97MgnwDzqM9VX6giyVIkbEu8ikwTTnd6Tg
+	sZSHZQ0/Oi5ZDWGvbTZZegcB3bG4vLq+ub392vnmTMj5ent7c311edEB8IO9FlNzLQRe
+	nRwHrZ7FwJL+ULODckcpH86NkiakavL1VQ1t5h7byMQTx9Ly2ua2883O7p5L+7iV2+Du
+	zhvn9uba8pLjycSIrcfc1lClz9ekJkijuOEo6Y8UPCp3MjX0YqRIlpieUwRhb7f0Ddun
+	5xZfrW85d/b29t++OyN6u7+3t+PcWn+1ODdtH+6ztEPgi3LSE2WiyIuhVPLRggf2QDKN
+	CSkvT1bnXq+sbzVbbaNTs/PLa1vO3T0Af/836APOhTy+f/fu7d6uc2tteX52atRmNbfW
+	V17PVSfLIemxgj/c7M7B7E5hsDgCSbxSk6evbjRZHg7bZxxLq5vO3X0A90D/g2N5PAL+
+	/q5zc3XJMWMffmgxNVbr8zTKeImAAwUPze5Qo/f18ycFQ7kLpQpVtq689k5Hd//I5OzC
+	8vr2m7137+Gqh5g/4kiHrIHZ9+/23myvLy/MTo70d3fcqS3XZasUUiEUfDDJ/3CjB/Yg
+	WNTxRLFQ7sU3DUazdWBsem5pZcO5+/YQOo6oP7Py2QAg+Le7zo2VpbnpsQGr2Wi4WQwF
+	HyviwdIu6Cg7avPQ6n6RJam11yob2u73Dtlnnr9c3YKwQ8J/duV/PvtCHP3zc4cfPvwN
+	gd9affl8xj7Ue7+tofKaVp0k+wU1O9To/zvJwRRHpjLZMLunZFwtqbptsvT9NfF0HlJ+
+	Zx/YPRfGEeuxVjw+gX1/B5J+/unEX30W0+2qkqsZKTDDs5nQ6I+yu9q8GLW6G9VN7V1/
+	PkLlvvF6dx9S3n3NY78PV//pNgpJv7/7egMV/KM/u9qbqm+gZid2Nfoj7DDF0WGKQ20+
+	X1/T/Hu3bWTq2eIKsEO5nxn0jx898FDwrzdWFp9Njdi6f2+ugdUNNHpgp8Oq9nDOI3ZW
+	hABWdZkFpTXQ5m2jj6HVbTr3PrHjKsAnmnHBQ7Pbc25Cs3s8aoNGX1NakAkrO0EE60R2
+	Dqxo07J0ZbUtnT0DiB1md9TqsOud+G04+wAzi5odmuGBfaCns6W2TJeVBqtazgnsFLiB
+	jcKm97K6FrN1EE1x7jaPLoczwi/YQW7djR5NcoNWc0tdGTbBR8FtLCxujuY8sHuWNmh6
+	B3bHiwP2L3wX7j46YH/hwNiNBs/i5kvscPOeXVhhMN77Y2j852AfH/rjntFQUQgLuxgh
+	9xTsrT8Xe6uX3Rv3E3udu94P5zzu2tlXDHn6PPQ6VO/flfNf+Srcffwj2c/S9I6ta93z
+	+4+Iu5cdd6l9gqH/rG2+ud4JubZxPa4j4pr24F6m82e6l+n86r0M3L8T9h6W2M8uiPrM
+	6jyBn1US+hk1gX+bIPJvUgT+LZLIv0ET+t0DQr9zQtx3jXwI/I6Zz3HvFnad/XcLu07z
+	biGR3ykl9rvExH2H3IfAewd8iLxnhMh7hTyBJ+IeMWAn7t5A6HaE3ROKAk/YvcBY1qPt
+	7wTcAw7sUPIE3fuP4KHkCXnmAxxS5zrhJYiAZ30cwBPwjBc4ndAVeSKe7YNFHg7yIuKZ
+	TrCbAnV7OL+NiGd5AbyLnohnuLlCj8WeeGf3IXgIPdAT8cxGtIfKhY8qn2BndSJ4Nz7E
+	n3BntLrwIfxYAmCnvaJhwLfcNuEP8u1G+P4/6GJnQ9/P6r2CdwS8I+AdAe8I/BQj8C9p
+	pK71CmVuZHN0cmVhbQplbmRvYmoKMzkgMCBvYmoKMjc2MAplbmRvYmoKMzYgMCBvYmoK
+	PDwgL0xlbmd0aCAzNyAwIFIgL1R5cGUgL1hPYmplY3QgL1N1YnR5cGUgL0ltYWdlIC9X
+	aWR0aCAyNTIgL0hlaWdodCAxMDQgL0NvbG9yU3BhY2UKL0RldmljZUdyYXkgL0JpdHNQ
+	ZXJDb21wb25lbnQgOCAvRmlsdGVyIC9GbGF0ZURlY29kZSA+PgpzdHJlYW0KeAHtnPlX
+	Uukfx01LRZBFQUPAQBgBRZRcUDwYLoOpqGW4lKNH5aupiXZwlDqYMuaIy+TCUdMyyaXM
+	3cilmub0r83nuUA2LmXf+uHa5f2LnTjn8n49n+V57uU+j4+PV94R8I6AdwS8I+AdARiB
+	c2dGPyxciNj3k/xwrk9GfZHv7xkEN7Wf3/nz5y+cIYFdPz9sGP5PfgwcsBGzf0BAoEck
+	3MrjMDAgwB+5dg3AN+O7wFG0/YGaRAoigyigYFwLOUROg0ikwEA0AJAAEP9vwkcVjiLu
+	D9yATQmmUmk0Op1xBkSn02hUajAMQRDwI3yM/rSlj4IO5BBxEpkM2MAcEspkslhhYWHh
+	uBYYZLGYzNAQBoMOA0Amk1D0Ef0pQ+8ivxAQGESmUGkIG4jZERERHA6Xy+XhWGCPwwGj
+	7PDwMDQANCqFHBQY4Ir9abq+Cx3FPJhKD2Gywi9GcHi8S3y+QBAlxL2iBAI+/xKPx4m4
+	GM5ihtAh+BB7V+i/lvco3yHdgZyCyAGcF8kXCEXR0WKJVCqNcSkWd3IbA4sScXS0SCjg
+	R/IAH9FTgB4S/+t570YPImPkbG4kH7glMTKZPD4+QQG6jGMhfwnx8XKZLEYC/PxILhuj
+	h8R3wX8x8h50CpXBDGNzLwlE0VLAViQmpSiVqWmqA6XjSAeuVGmpSmVKUqICBkAaLRJc
+	4rLDmAwq5RTwGHpAIDmYxmCGcyIFIkmsPCExWalKV2doNJlZ2Ug5OBVmLitTo8lQp6uU
+	yYkJ8liJSBDJCWcyaMFkVPSQ9idGHtD9oNYBPYTF5vGF4th4RXJqeoYm+1ft1bz8Ap2u
+	sLCwCLcCczpdQX7eVe2v2ZqM9NRkRXysWMjnsVkhCN7/AprrToI/50anh4ZF8KKipXJF
+	ikqdmZObryu+VnKjtLSsvALnKi8rLb1Rcq1Yl5+bk6lWpSjk0ugoXkRYKN0NfxI7oJ/3
+	DwwKpgF6pFAsS0hWZWRp84uul5bfrKyurqmpqzMg/Q+XwqzV1dXUVFdX3iwvvV6Ur83K
+	UCUnyMTCSICnBUPNwyrnBHg0uwWQKLQQhC6Ju6xUZ2kLivUVldW1hobGpuaWFqOxtbW1
+	DacCa0ZjS0tzU2ODoba6skJfXKDNUisvx0kQfAiNQsJK/tikRxkPfY7KYAG6VJ6UdiUn
+	D8irausb77TeNbV3dHSa7+Fc5s6OjnbT3dY7jfW1VUCfl3MlLUkuBXgWg4r63QmBPwdh
+	R+hMNk8okSepNFpdCZA3NLeaOsz3LQ+6e6zWP3Auq7Wn+4HlvrnD1NrcAPQlOq1GlSSX
+	CHlsmOrIgdDrj0t6LOwkCp0ZzhWI4wA9t1B/q6a+ua3dbOm29vb122wDg0M41+CAzdbf
+	12vttpjb25rra27pC3MBPk4s4IYz6Sjrjw28O+xQ7Pxo2eU0TW5RaWVdo9F0z2J92D84
+	9GhkdHRsfNyOa42Pj42OjjwaGux/aLXcMxkb6ypLi3I1aZdl0Xwo+RMD7+sLjS6YzmRD
+	sScor2gLS38zNLV1WHr6bMMjY/aJyanH06AZHAv5ezw1OWEfGxm29fVYOtqaDL+VFmqv
+	KBOg5NlMejAE3tf3SLdDKQ/VHoIyXp6kztHpKw1Nd81dvbbhUfvk9MzT2Wdzc3MOh+M5
+	bgXmwOKz2acz05P20WFbb5f5bpOhUq/LUSfJUdZjgT8m6SHl/VG1syNFsQpVZl7JrVpA
+	7+4bHLFPzszOPZ9fWFxaegF6iVshd0tLiwvzz+dmZybtI4N93QBfe6skL1OliBWhwFNI
+	/sd0u3OQ8kFURhhHII5PydAWV9TcbgP0odGJ6VnHwtLL5Vcrq5jWcCuXv5VXyy+XFhyz
+	0xOjQwDfdrumolibkRIvFnDCGNQgSPojnR5LeRrzIk8Uo1BlFeir6o0dDwB98snc/Ivl
+	1bX1jY3Nra2tbVwLDG5ubKyvrS6/mJ97MgnwDzqM9VX6giyVIkbEu8ikwTTnd6TgsZSH
+	ZQ0/Oi5ZDWGvbTZZegcB3bG4vLq+ub392vnmTMj5ent7c311edEB8IO9FlNzLQRenRwH
+	rZ7FwJL+ULODckcpH86NkiakavL1VQ1t5h7byMQTx9Ly2ua2883O7p5L+7iV2+Duzhvn
+	9uba8pLjycSIrcfc1lClz9ekJkijuOEo6Y8UPCp3MjX0YqRIlpieUwRhb7f0Ddun5xZf
+	rW85d/b29t++OyN6u7+3t+PcWn+1ODdtH+6ztEPgi3LSE2WiyIuhVPLRggf2QDKNCSkv
+	T1bnXq+sbzVbbaNTs/PLa1vO3T0Af/836APOhTy+f/fu7d6uc2tteX52atRmNbfWV17P
+	VSfLIemxgj/c7M7B7E5hsDgCSbxSk6evbjRZHg7bZxxLq5vO3X0A90D/g2N5PAL+/q5z
+	c3XJMWMffmgxNVbr8zTKeImAAwUPze5Qo/f18ycFQ7kLpQpVtq689k5Hd//I5OzC8vr2
+	m7137+Gqh5g/4kiHrIHZ9+/23myvLy/MTo70d3fcqS3XZasUUiEUfDDJ/3CjB/YgWNTx
+	RLFQ7sU3DUazdWBsem5pZcO5+/YQOo6oP7Py2QAg+Le7zo2VpbnpsQGr2Wi4WQwFHyvi
+	wdIu6Cg7avPQ6n6RJam11yob2u73Dtlnnr9c3YKwQ8J/duV/PvtCHP3zc4cfPvwNgd9a
+	ffl8xj7Ue7+tofKaVp0k+wU1O9To/zvJwRRHpjLZMLunZFwtqbptsvT9NfF0HlJ+Zx/Y
+	PRfGEeuxVjw+gX1/B5J+/unEX30W0+2qkqsZKTDDs5nQ6I+yu9q8GLW6G9VN7V1/PkLl
+	vvF6dx9S3n3NY78PV//pNgpJv7/7egMV/KM/u9qbqm+gZid2Nfoj7DDF0WGKQ20+X1/T
+	/Hu3bWTq2eIKsEO5nxn0jx898FDwrzdWFp9Njdi6f2+ugdUNNHpgp8Oq9nDOI3ZWhABW
+	dZkFpTXQ5m2jj6HVbTr3PrHjKsAnmnHBQ7Pbc25Cs3s8aoNGX1NakAkrO0EE60R2Dqxo
+	07J0ZbUtnT0DiB1md9TqsOud+G04+wAzi5odmuGBfaCns6W2TJeVBqtazgnsFLiBjcKm
+	97K6FrN1EE1x7jaPLoczwi/YQW7djR5NcoNWc0tdGTbBR8FtLCxujuY8sHuWNmh6B3bH
+	iwP2L3wX7j46YH/hwNiNBs/i5kvscPOeXVhhMN77Y2j852AfH/rjntFQUQgLuxgh9xTs
+	rT8Xe6uX3Rv3E3udu94P5zzu2tlXDHn6PPQ6VO/flfNf+Srcffwj2c/S9I6ta93z+4+I
+	u5cdd6l9gqH/rG2+ud4JubZxPa4j4pr24F6m82e6l+n86r0M3L8T9h6W2M8uiPrM6jyB
+	n1US+hk1gX+bIPJvUgT+LZLIv0ET+t0DQr9zQtx3jXwI/I6Zz3HvFnad/XcLu07zbiGR
+	3ykl9rvExH2H3IfAewd8iLxnhMh7hTyBJ+IeMWAn7t5A6HaE3ROKAk/YvcBY1qPt7wTc
+	Aw7sUPIE3fuP4KHkCXnmAxxS5zrhJYiAZ30cwBPwjBc4ndAVeSKe7YNFHg7yIuKZTrCb
+	AnV7OL+NiGd5AbyLnohnuLlCj8WeeGf3IXgIPdAT8cxGtIfKhY8qn2BndSJ4Nz7En3Bn
+	tLrwIfxYAmCnvaJhwLfcNuEP8u1G+P4/6GJnQ9/P6r2CdwS8I+AdAe8I/BQj8C9ppK71
+	CmVuZHN0cmVhbQplbmRvYmoKMzcgMCBvYmoKMjc2MAplbmRvYmoKNDYgMCBvYmoKPDwg
+	L0xlbmd0aCA0NyAwIFIgL04gMSAvQWx0ZXJuYXRlIC9EZXZpY2VHcmF5IC9GaWx0ZXIg
+	L0ZsYXRlRGVjb2RlID4+CnN0cmVhbQp4AYVST0gUURz+zTYShIhBhXiIdwoJlSmsrKDa
+	dnVZlW1bldKiGGffuqOzM9Ob2TXFkwRdojx1D6JjdOzQoZuXosCsS9cgqSAIPHXo+83s
+	6iiEb3k73/v9/X7fe0RtnabvOylBVHNDlSulp25OTYuDHylFHdROWKYV+OlicYyx67mS
+	v7vX1mfS2LLex7V2+/Y9tZVlYCHqLba3EPohkWYAH5mfKGWAs8Adlq/YPgE8WA6sGvAj
+	ogMPmrkw09GcdKWyLZFT5qIoKq9iO0mu+/m5xr6LtYmD/lyPZtaOvbPqqtFM1LT3RKG8
+	D65EGc9fVPZsNRSnDeOcSEMaKfKu1d8rTMcRkSsQSgZSNWS5n2pOnXXgdRi7XbqT4/j2
+	EKU+yWCoibXpspkdhX0AdirL7BDwBejxsmIP54F7Yf9bUcOTwCdhP2SHedatH/YXrlPg
+	e4Q9NeDOFK7F8dqKH14tAUP3VCNojHNNxNPXOXOkiO8x1BmY90Y5pgsxd5aqEzeAO2Ef
+	WapmCrFd+67qJe57AnfT4zvRmzkLXKAcSXKxFdkU0DwJWBR9i7BJDjw+zh5V4HeomMAc
+	uYnczSj3HtURG2ejUoFWeo1Xxk/jufHF+GVsGM+Afqx213t8/+njFXXXtj48+Y163Dmu
+	vZ0bVWFWcWUL3f/HMoSP2Sc5psHToVlYa9h25A+azEywDCjEfwU+l/qSE1Xc1e7tuEUS
+	zFA+LGwluktUbinU6j2DSqwcK9gAdnCSxCxaHLhTa7o5eHfYInpt+U1XsuuG/vr2evva
+	8h5tyqgpKBPNs0RmlLFbo+TdeNv9ZpERnzg6vue9ilrJ/klFED+FOVoq8hRV9FZQ1sRv
+	Zw5+G7Z+XD+l5/VB/TwJPa2f0a/ooxG+DHRJz8JzUR+jSfCwaSHiEqCKgzPUTlRjjQPi
+	KfHytFtkkf0PQBn9ZgplbmRzdHJlYW0KZW5kb2JqCjQ3IDAgb2JqCjcwNAplbmRvYmoK
+	MjUgMCBvYmoKWyAvSUNDQmFzZWQgNDYgMCBSIF0KZW5kb2JqCjQ4IDAgb2JqCjw8IC9M
+	ZW5ndGggNDkgMCBSIC9OIDMgL0FsdGVybmF0ZSAvRGV2aWNlUkdCIC9GaWx0ZXIgL0Zs
+	YXRlRGVjb2RlID4+CnN0cmVhbQp4Aa1YZ1QUy7auHgaGnBkyDFFyRhhyjkNOSlByZkhD
+	DgqCICBBlCQiCCiCIiDpYCCoiCiCgogKqIgKEiQISH49cDx33XfXXe/Pq7Wm66uvdqiu
+	Xd17dgPAgHELCQlEAACC8IQwa0MdzLHjjhjUO4AEVIAVqAION4/wEG1LSxws8l/a+iiA
+	iFPDkkRb50Jk7PQDR6ZD8cE5Ketrhv9F6Q9NGwY7BACSgAlmn0OsRcTuh9iWiKMIIQRY
+	xpeIPXzdPGEcD2OJMFtrXRjXwJjW5xC3E7H7Ie4j4kgPH6LuGABkjHhPPzwAqHkYa3h6
+	hXvA00S/np7hHkEwzgUAoRMUFAzbpx+BeRGPkDBYl34HxoLEfYF7uLnOAKDMDNuw/hcX
+	chSAJngb+Tj/xQm1AYBGAlDX/i9u1fpgryD0YLi3vNyBOYhaBwDSyf39VWF4bRcA2M3b
+	39++tr+/WwkAyTgAXYEeEWGRB7LwjUADAPxf48N7/luDBA4OMcB8IAzMQ8kIVRIhpDVp
+	HUqJfIPyNw0TnQKDN1MGSzFrJrsrJy9XDQ8drwemhZ9KwFfwmfCRI5kiS2JO4p2SolLn
+	pVdlbeXqFagVTx69owywhippqp1qmxrSmgFaVdqTuqx6OP00g07DdWMJk5OmebgesxUL
+	jKW5FcG6zGbIjtc+0uHpcXbHAKdW570TRiezXAfdGT1sPQu8Pvhw+7r51fqvBqoFpeNf
+	BC+Hkoahw4UIShHGkU5RgdHxMTmxV+Ma43sS3iTOnNpKoksWOqOSYp7qctY+DZvOlr5x
+	bizjXmZpVuJ512ydHP6c/dz3eS0X8vI9Lypforz0rqCmkFBkWaxbonZZsVT8CncZVdna
+	1fHyhxVXrkVVmlfxV61Wd17PvGFXw1UzdbO2NrYu4JbX7ZP1x+6YNWg1Sjdx3SW7u9A8
+	3NLaWtQW2W77l1wHbcfcvWf3qx+cfujUKd9F0fW5u7nn3COnx5JPwJPh3sqnhD79Z+hn
+	3/pbnqe9cBgQGdh5OTiYM2Q0tPOq8XXgsOjw95GaNwGjMqMbbx+OnX1n8R79fuJD1bj/
+	hNTE8mTjx+hP+p9ZP/+Yav2SPI37yvD11bec70bfd2fqZm1nt3+UzCnNvZ73nt9ayFgU
+	XBz8eXZJa2lzuXklZFVqdeFXw1rUuu4G08bM797N2q0L28k7MbsRexH7lvv7cPyVwSMI
+	jzhKwodUIk0hmycPp+ShektTSxfDgGNiZx5Fn2ETYq/nFOIK4W7gWcYo8CXyvxBkE/IT
+	7hBhFPUUa5WglHSWqpFeklWXi5e/r7B9VEbJSTkCm61SDZ+Ct+rzmpAWs7a4jraurZ6v
+	fqxBlmGZUaPxE5NR0++4LXMmCyPLs1YPrH/ZSti52mc7dB5bcGR30ncOdbl8ou/kqhvG
+	3dojybPRa9qH3lfAT9hfLEAiUDpIEa8SrBliEGoe5hDuTgiIiIk8F1UYfTPmYezruG/x
+	qwkriZ9PPTvdlFSanHkmIsU91fwsNo0/HZX+49yLjPrM9Cz388rZVNkfcmpzE/PCL3jm
+	213UvyRbwFEICqeKeorLSqIum5Xyla5c6SrLvnq8nL98rqL1WmpldBW+2vu68w3LGu2b
+	0rWcdci6+VvDt9vqL9+Ja3BpVG/ibtq7+7G5u6W8NaXNu93gL+EO0o7pe133Sx/EPLTv
+	lOui7ZrrftZz/VHKY48nur2CT1FP5/qePavuP/3c6QV2gG1g4+W7wfahy68SXrsO64wI
+	vEG+mR598rZyLOndiffYD+zjyPGliU+TTz82fCr4HDPl+EV1mmN6HT4Htd/PzDjNyv+g
+	/vF17sF84UL4ot1PrSXZZakVuVXlXwZrDuveG+G/YzdjtoK2bXbEd9Z2q/cM9t7t6+1X
+	HMRfEMRDCOgSwoQEg+QklSA7hiog/0yJpcqnXqTVpcuhf8VIzSTHrM+ihZZhxbAxslNw
+	IDm2OTe51rjXeFZ5lzHLfIv8MwIfBd8I9Qm3H7khkicaJeYgrizBKLEo2StVKh0ioy3L
+	IDshd10+WEFRYV2x/WiMElZpQ7kZG6oiowpUX6tVq0drmGnya25oDWhX6cTr2unJ6lPr
+	zxn0G9YZZRuHmtiaYnHcuB2zMfO7FjmW/lZG1oI2kM2k7X27Uvs4B6djWseFHCkdV5wm
+	nPtcmk6UnEx0dXCTdqd0n/Ho86z1yvYm+Dj76vmJ+dP7rweMB3YFXcOnBLuGqIWyhu6E
+	LYR/IYxG9EbejSqJjotxjJWNI417E1+R4J8okTh/qu60XxJ/0ofkS2csUqhTnqdmnsWl
+	UacNpOecs8pgzniXWZ7lf14xG8oezLmaG5qnf4HjwlJ+98WUS0cvzRaUFdoUURX1FqeU
+	GF6muTxaWnElrMzgKufV1fKXFTXwefKp0q/mrJ6/3nEjs8bzpmYtd+1e3dSt57db6svv
+	ZDVENbo1mdyVa2Zv3m2ZbL3XVt5+56/OjpF7U/dXHoJOyi7Gbs4ezCOBxwJP+Hp5nrL3
+	MT2j6Sft336+8mLppfJg/tDca+XhlJHRUem358d+vSeMk0/c+3jxc/6Xzm+as6zz3kuG
+	a/LbKcT4H+Y+Yk4gg3NVkRcAx1MBsGEDIPM9AEdKAGBxBcCSBgBbLED4rgGEeCqAnEXA
+	n/zBBuSACTgJCCAdlIJ60ANGwDewCVFBPJAcZAA5QsFQKlQKNUMD0AwCieBH6CA8EOcQ
+	jYiPJHQk2iQEkhqScSQD0hB5CtmGXCIVI/UkrSCdJOMicya7QvYRJYDyRzWiNsn1yfPJ
+	P1PIUqRSfKBUpMyjXKAyo6qjpqbGU7+mUaK5SktGG0z7ns6QroVemL6IgYYhmWGLkcD4
+	kymYaZE5hHmWxYnlJVoffZ9VkbWeTZytll2c/RaHLEcbpwbnUy4rrgluX/g8p/Ay8VZg
+	ZDDdfNZ8X/gjBNACvYIJQopCS8K1R7xFBEWmRa+L+YpLiq9I3JM8I4WTZpWelmmQTZAz
+	k+eV31D4prh0dEeZEsuiIqyqpGai7qoRr1mm9UR7TpdPz16/wOC9kZCxnYmHaSwu16ze
+	/LXFvpWMdaBNg+2uvZXDHTgHpjntuMSf2HINcCtzf+NJ42Xifd5nFH7rxQe8DcLiy0Oo
+	Qk+HrRFCIhai/KPnY8PithNyTvGd7kx2TAGp19PM03cybmedzGbJeZWXlm9wcb+go6iq
+	pKm0q+xB+b1rDVWV13NrEmsDbrnU2zTgmnDNtq2+7d4d1vdVH2K7lHqMHgf0lvR9fW42
+	MDgUPaw0yvkO/aF0YvWTxVTN9O53y9mCuZcLm0usKzy/2NcpN35sdm7n7h4/eH/Qwv8g
+	FIExcAbB4AwoBHWgEz4Bs2APYobEIV3ICYqAcqA6qA/6jkAhRBFmCALiCuIFYo9EnsSX
+	5CrJKJIWjn0y8gFyi1SJNIK0hXSDDEuWQNaDokTZoK6ifpCrkGeRT1LIU2RRzFDiKJuo
+	OKlSqZaoT1AP0mjTtNKK016j46IrpGehv8SAZihm5GasZJJgamPWZu5nMWDpQeugH7Ma
+	sj5ns2abYPdlX+NI5URz3uRS5xrh9udB8JTyHuUdxATwkfNV8+vA77EKQXchAaEZ4VtH
+	QkWURSHRfrGL4iclxCR+Sz6WypV2lZGS2Zbtl7ssj1fAKaofVVfSUNbGaqkYqJqq2aif
+	0AjWTNOq1O7Wmddj17cyyDEcNUabiJoa4bzNMsybLb5Z8Vi72FTZrtobOVQfp3GMdpp1
+	8Twx4Wrpdta922PHS9U7yee5H5d/eMDLICn8xeDt0MCwcYJVxNMojejWWIW4WwkSifWn
+	FZMenDFP+XQ2PJ3iXGWmWtbb7PBcxrzb+eYXvxckF4kWv72ccUWtbLa85JpR5U517Q3n
+	m3S1vbeS6jXv7DU+vpvV4twm1T7VUXTf8CFlZ1933iPPJ9inTH0b/Z9eDL3sHmp/fWuk
+	arRirPh91njApPrH3c+3vzh/JflWMaMzOzNXsGD5k3OZZJV+zWpjcZv6IP5oIAM//x4g
+	AY59IxgAsxAZJAjpQV5QOnQbegPtIyQQLoh8xCsSFhJnkmqSn0gV5DnkGPycJ5AOk4mT
+	pZJNoXRRN8hpyWPIv1McpxiiNKd8SWVHNUEdSL1PU0SrQDtGd5pemn6a4QqjMxMv0wzz
+	XRY8Whz9g7WODc+uwL7N8Zgzm+sYtxD3Mk8n73mMM580P8T/VqBFsEgoUdj7iLmIiqiI
+	GKs4SnxTYkFyUuqVdK9Mu2ydXLl8sUKx4s2jD5QGlSexiyq7atTq7Bpimhpa9tpBOhm6
+	dXpD+nuGUkaexikmJabNuGGzTQsRS3era9bLtsZ2tx3YjxU6cjvVuOieGHeNcaf1uO6l
+	5j3qG+pPG3AzSAc/FhIQuh+eG8ETeStaKaY37lSCzynDJNEziJSRs6XpLhlsmc/OR+UI
+	5D69EHKR6VJjoWMxV8lMaWOZbzlPxUBlXDXv9Z4ar1pU3Z3bx++gGjqawpsVWhFt3X8p
+	djTdF3pQ0ynUVdMj+6j7iUXvVF9CP9fzngG/Qdah/tfxI/Jvlt/efhf8vm+casJ48vzH
+	ic8yU0lfBr6ivzl/L5v58INiTnLeaMF68dhPsyW1Zd7lnZUXq8W/LNdQa/Xr5uuLG/G/
+	Ub/zN5k2z22Brait8W3sduH2rx3rnbKdr7uSu4Td+3vIvWN7Pfvi+5eI8T+sl4j5A1Dq
+	BgcGh2FwunoHw/+/S1BgBFyTHTRG+EqNdze3gHsingkhWNrCPRr+bYVH2ujDPT1cDtF7
+	+xkY/40xnm56pjDmgnmZWF9dcxhTwxjnHWZgDWNYFzrm72ZiCWNaGOO98HY2MIbtQ/Eh
+	gQc1LhFnhxB0iPJwboTKvcL1/8i0x/raOvyt2x8WYW0HY0FYZiwg2JQoT/S14+ml9/fa
+	EOT4QHMczMN+EWx+BGPi+uG6ESEFDIAbXI35AC8gCXBAF+j9fcXAPAYeB8OzXiAclps+
+	kPsjZX8w9vtfWpLA+8Be5IFOAJyVw0DQSb/kMNjWv1v3gC1HgEBYLgKEydTJzMrs/CND
+	9Bp44PmPlul/MIfWDld4KOsHPGGpPzzR/gFP9B7U5B1ZFByjYu+LFEbKIRWROkh1pAYS
+	CzBINJIDSCIVkMpIbaQmUhWew76cb5v/Zy2H++P+z32a/lkzvHL8P+x/eAV+8HeMg/od
+	3mlABp+P0tNE9Eholtj9WyN4RROIhG5wSEyYn48vAaMNf73wksAY4z2kJDByMjJY8D+q
+	bG8vCmVuZHN0cmVhbQplbmRvYmoKNDkgMCBvYmoKMzkxMAplbmRvYmoKMzEgMCBvYmoK
+	WyAvSUNDQmFzZWQgNDggMCBSIF0KZW5kb2JqCjUwIDAgb2JqCjw8IC9MZW5ndGggNTEg
+	MCBSIC9OIDMgL0FsdGVybmF0ZSAvRGV2aWNlUkdCIC9GaWx0ZXIgL0ZsYXRlRGVjb2Rl
+	ID4+CnN0cmVhbQp4Aa1YZ1QUy7auHgaGnBkyDFFyRhhyjkNOSlByZkhDDgqCICBBlCQi
+	CCiCIiDpYCCoiCiCgogKqIgKEiQISH49cDx33XfXXe/Pq7Wm66uvdqiuXd17dgPAgHEL
+	CQlEAACC8IQwa0MdzLHjjhjUO4AEVIAVqAION4/wEG1LSxws8l/a+iiAiFPDkkRb50Jk
+	7PQDR6ZD8cE5Ketrhv9F6Q9NGwY7BACSgAlmn0OsRcTuh9iWiKMIIQRYxpeIPXzdPGEc
+	D2OJMFtrXRjXwJjW5xC3E7H7Ie4j4kgPH6LuGABkjHhPPzwAqHkYa3h6hXvA00S/np7h
+	HkEwzgUAoRMUFAzbpx+BeRGPkDBYl34HxoLEfYF7uLnOAKDMDNuw/hcXchSAJngb+Tj/
+	xQm1AYBGAlDX/i9u1fpgryD0YLi3vNyBOYhaBwDSyf39VWF4bRcA2M3b39++tr+/WwkA
+	yTgAXYEeEWGRB7LwjUADAPxf48N7/luDBA4OMcB8IAzMQ8kIVRIhpDVpHUqJfIPyNw0T
+	nQKDN1MGSzFrJrsrJy9XDQ8drwemhZ9KwFfwmfCRI5kiS2JO4p2SolLnpVdlbeXqFagV
+	Tx69owywhippqp1qmxrSmgFaVdqTuqx6OP00g07DdWMJk5OmebgesxULjKW5FcG6zGbI
+	jtc+0uHpcXbHAKdW570TRiezXAfdGT1sPQu8Pvhw+7r51fqvBqoFpeNfBC+Hkoahw4UI
+	ShHGkU5RgdHxMTmxV+Ma43sS3iTOnNpKoksWOqOSYp7qctY+DZvOlr5xbizjXmZpVuJ5
+	12ydHP6c/dz3eS0X8vI9Lypforz0rqCmkFBkWaxbonZZsVT8CncZVdna1fHyhxVXrkVV
+	mlfxV61Wd17PvGFXw1UzdbO2NrYu4JbX7ZP1x+6YNWg1Sjdx3SW7u9A83NLaWtQW2W77
+	l1wHbcfcvWf3qx+cfujUKd9F0fW5u7nn3COnx5JPwJPh3sqnhD79Z+hn3/pbnqe9cBgQ
+	Gdh5OTiYM2Q0tPOq8XXgsOjw95GaNwGjMqMbbx+OnX1n8R79fuJD1bj/hNTE8mTjx+hP
+	+p9ZP/+Yav2SPI37yvD11bec70bfd2fqZm1nt3+UzCnNvZ73nt9ayFgUXBz8eXZJa2lz
+	uXklZFVqdeFXw1rUuu4G08bM797N2q0L28k7MbsRexH7lvv7cPyVwSMIjzhKwodUIk0h
+	mycPp+ShektTSxfDgGNiZx5Fn2ETYq/nFOIK4W7gWcYo8CXyvxBkE/IT7hBhFPUUa5Wg
+	lHSWqpFeklWXi5e/r7B9VEbJSTkCm61SDZ+Ct+rzmpAWs7a4jraurZ6vfqxBlmGZUaPx
+	E5NR0++4LXMmCyPLs1YPrH/ZSti52mc7dB5bcGR30ncOdbl8ou/kqhvG3dojybPRa9qH
+	3lfAT9hfLEAiUDpIEa8SrBliEGoe5hDuTgiIiIk8F1UYfTPmYezruG/xqwkriZ9PPTvd
+	lFSanHkmIsU91fwsNo0/HZX+49yLjPrM9Cz388rZVNkfcmpzE/PCL3jm213UvyRbwFEI
+	CqeKeorLSqIum5Xyla5c6SrLvnq8nL98rqL1WmpldBW+2vu68w3LGu2b0rWcdci6+VvD
+	t9vqL9+Ja3BpVG/ibtq7+7G5u6W8NaXNu93gL+EO0o7pe133Sx/EPLTvlOui7ZrrftZz
+	/VHKY48nur2CT1FP5/qePavuP/3c6QV2gG1g4+W7wfahy68SXrsO64wIvEG+mR598rZy
+	LOndiffYD+zjyPGliU+TTz82fCr4HDPl+EV1mmN6HT4Htd/PzDjNyv+g/vF17sF84UL4
+	ot1PrSXZZakVuVXlXwZrDuveG+G/YzdjtoK2bXbEd9Z2q/cM9t7t6+1XHMRfEMRDCOgS
+	woQEg+QklSA7hiog/0yJpcqnXqTVpcuhf8VIzSTHrM+ihZZhxbAxslNwIDm2OTe51rjX
+	eFZ5lzHLfIv8MwIfBd8I9Qm3H7khkicaJeYgrizBKLEo2StVKh0ioy3LIDshd10+WEFR
+	YV2x/WiMElZpQ7kZG6oiowpUX6tVq0drmGnya25oDWhX6cTr2unJ6lPrzxn0G9YZZRuH
+	mtiaYnHcuB2zMfO7FjmW/lZG1oI2kM2k7X27Uvs4B6djWseFHCkdV5wmnPtcmk6UnEx0
+	dXCTdqd0n/Ho86z1yvYm+Dj76vmJ+dP7rweMB3YFXcOnBLuGqIWyhu6ELYR/IYxG9Ebe
+	jSqJjotxjJWNI417E1+R4J8okTh/qu60XxJ/0ofkS2csUqhTnqdmnsWlUacNpOecs8pg
+	zniXWZ7lf14xG8oezLmaG5qnf4HjwlJ+98WUS0cvzRaUFdoUURX1FqeUGF6muTxaWnEl
+	rMzgKufV1fKXFTXwefKp0q/mrJ6/3nEjs8bzpmYtd+1e3dSt57db6svvZDVENbo1mdyV
+	a2Zv3m2ZbL3XVt5+56/OjpF7U/dXHoJOyi7Gbs4ezCOBxwJP+Hp5nrL3MT2j6Sft336+
+	8mLppfJg/tDca+XhlJHRUem358d+vSeMk0/c+3jxc/6Xzm+as6zz3kuGa/LbKcT4H+Y+
+	Yk4gg3NVkRcAx1MBsGEDIPM9AEdKAGBxBcCSBgBbLED4rgGEeCqAnEXAn/zBBuSACTgJ
+	CCAdlIJ60ANGwDewCVFBPJAcZAA5QsFQKlQKNUMD0AwCieBH6CA8EOcQjYiPJHQk2iQE
+	khqScSQD0hB5CtmGXCIVI/UkrSCdJOMicya7QvYRJYDyRzWiNsn1yfPJP1PIUqRSfKBU
+	pMyjXKAyo6qjpqbGU7+mUaK5SktGG0z7ns6QroVemL6IgYYhmWGLkcD4kymYaZE5hHmW
+	xYnlJVoffZ9VkbWeTZytll2c/RaHLEcbpwbnUy4rrgluX/g8p/Ay8VZgZDDdfNZ8X/gj
+	BNACvYIJQopCS8K1R7xFBEWmRa+L+YpLiq9I3JM8I4WTZpWelmmQTZAzk+eV31D4prh0
+	dEeZEsuiIqyqpGai7qoRr1mm9UR7TpdPz16/wOC9kZCxnYmHaSwu16ze/LXFvpWMdaBN
+	g+2uvZXDHTgHpjntuMSf2HINcCtzf+NJ42Xifd5nFH7rxQe8DcLiy0OoQk+HrRFCIhai
+	/KPnY8PithNyTvGd7kx2TAGp19PM03cybmedzGbJeZWXlm9wcb+go6iqpKm0q+xB+b1r
+	DVWV13NrEmsDbrnU2zTgmnDNtq2+7d4d1vdVH2K7lHqMHgf0lvR9fW42MDgUPaw0yvkO
+	/aF0YvWTxVTN9O53y9mCuZcLm0usKzy/2NcpN35sdm7n7h4/eH/Qwv8gFIExcAbB4Awo
+	BHWgEz4Bs2APYobEIV3ICYqAcqA6qA/6jkAhRBFmCALiCuIFYo9EnsSX5CrJKJIWjn0y
+	8gFyi1SJNIK0hXSDDEuWQNaDokTZoK6ifpCrkGeRT1LIU2RRzFDiKJuoOKlSqZaoT1AP
+	0mjTtNKK016j46IrpGehv8SAZihm5GasZJJgamPWZu5nMWDpQeugH7Masj5ns2abYPdl
+	X+NI5URz3uRS5xrh9udB8JTyHuUdxATwkfNV8+vA77EKQXchAaEZ4VtHQkWURSHRfrGL
+	4iclxCR+Sz6WypV2lZGS2Zbtl7ssj1fAKaofVVfSUNbGaqkYqJqq2aif0AjWTNOq1O7W
+	mddj17cyyDEcNUabiJoa4bzNMsybLb5Z8Vi72FTZrtobOVQfp3GMdpp18Twx4Wrpdta9
+	22PHS9U7yee5H5d/eMDLICn8xeDt0MCwcYJVxNMojejWWIW4WwkSifWnFZMenDFP+XQ2
+	PJ3iXGWmWtbb7PBcxrzb+eYXvxckF4kWv72ccUWtbLa85JpR5U517Q3nm3S1vbeS6jXv
+	7DU+vpvV4twm1T7VUXTf8CFlZ1933iPPJ9inTH0b/Z9eDL3sHmp/fWukarRirPh91njA
+	pPrH3c+3vzh/JflWMaMzOzNXsGD5k3OZZJV+zWpjcZv6IP5oIAM//x4gAY59IxgAsxAZ
+	JAjpQV5QOnQbegPtIyQQLoh8xCsSFhJnkmqSn0gV5DnkGPycJ5AOk4mTpZJNoXRRN8hp
+	yWPIv1McpxiiNKd8SWVHNUEdSL1PU0SrQDtGd5pemn6a4QqjMxMv0wzzXRY8Whz9g7WO
+	Dc+uwL7N8Zgzm+sYtxD3Mk8n73mMM580P8T/VqBFsEgoUdj7iLmIiqiIGKs4SnxTYkFy
+	UuqVdK9Mu2ydXLl8sUKx4s2jD5QGlSexiyq7atTq7Bpimhpa9tpBOhm6dXpD+nuGUkae
+	xikmJabNuGGzTQsRS3era9bLtsZ2tx3YjxU6cjvVuOieGHeNcaf1uO6l5j3qG+pPG3Az
+	SAc/FhIQuh+eG8ETeStaKaY37lSCzynDJNEziJSRs6XpLhlsmc/OR+UI5D69EHKR6VJj
+	oWMxV8lMaWOZbzlPxUBlXDXv9Z4ar1pU3Z3bx++gGjqawpsVWhFt3X8pdjTdF3pQ0ynU
+	VdMj+6j7iUXvVF9CP9fzngG/Qdah/tfxI/Jvlt/efhf8vm+casJ48vzHic8yU0lfBr6i
+	vzl/L5v58INiTnLeaMF68dhPsyW1Zd7lnZUXq8W/LNdQa/Xr5uuLG/G/Ub/zN5k2z22B
+	rait8W3sduH2rx3rnbKdr7uSu4Td+3vIvWN7Pfvi+5eI8T+sl4j5A1DqBgcGh2FwunoH
+	w/+/S1BgBFyTHTRG+EqNdze3gHsingkhWNrCPRr+bYVH2ujDPT1cDtF7+xkY/40xnm56
+	pjDmgnmZWF9dcxhTwxjnHWZgDWNYFzrm72ZiCWNaGOO98HY2MIbtQ/EhgQc1LhFnhxB0
+	iPJwboTKvcL1/8i0x/raOvyt2x8WYW0HY0FYZiwg2JQoT/S14+ml9/faEOT4QHMczMN+
+	EWx+BGPi+uG6ESEFDIAbXI35AC8gCXBAF+j9fcXAPAYeB8OzXiAclps+kPsjZX8w9vtf
+	WpLA+8Be5IFOAJyVw0DQSb/kMNjWv1v3gC1HgEBYLgKEydTJzMrs/CND9Bp44PmPlul/
+	MIfWDld4KOsHPGGpPzzR/gFP9B7U5B1ZFByjYu+LFEbKIRWROkh1pAYSCzBINJIDSCIV
+	kMpIbaQmUhWew76cb5v/Zy2H++P+z32a/lkzvHL8P+x/eAV+8HeMg/od3mlABp+P0tNE
+	9Eholtj9WyN4RROIhG5wSEyYn48vAaMNf73wksAY4z2kJDByMjJY8D+qbG8vCmVuZHN0
+	cmVhbQplbmRvYmoKNTEgMCBvYmoKMzkxMAplbmRvYmoKMjggMCBvYmoKWyAvSUNDQmFz
+	ZWQgNTAgMCBSIF0KZW5kb2JqCjUyIDAgb2JqCjw8IC9MZW5ndGggNTMgMCBSIC9OIDMg
+	L0FsdGVybmF0ZSAvRGV2aWNlUkdCIC9GaWx0ZXIgL0ZsYXRlRGVjb2RlID4+CnN0cmVh
+	bQp4AYWUTUgUYRjH/7ONBLEG0ZcIxdDBJFQmC1IC0/UrU7Zl1UwJYp19d50cZ6eZ3S1F
+	IoTomHWMLlZEh4hO4aFDpzpEBJl1iaCjRRAFXiK2/zuTu2NUvjAzv3me//t8vcMAVY9S
+	jmNFNGDKzrvJ3ph2enRM2/waVahGFFwpw3M6EokBn6mVz/Vr9S0UaVlqlLHW+zZ8q3aZ
+	EFA0KndkAz4seTzg45Iv5J08NWckGxOpNNkhN7hDyU7yLfLWbIjHQ5wWngFUtVOTMxyX
+	cSI7yC1FIytjPiDrdtq0ye+lPe0ZU9Sw38g3OQvauPL9QNseYNOLim3MAx7cA3bXVWz1
+	NcDOEWDxUMX2PenPR9n1ysscavbDKdEYa/pQKn2vAzbfAH5eL5V+3C6Vft5hDtbx1DIK
+	btHXsjDlJRDUG+xm/OQa/YuDnnxVC7DAOY5sAfqvADc/AvsfAtsfA4lqYKgVkctsN7jy
+	4iLnAnTmnGnXzE7ktWZdP6J18GiF1mcbTQ1ayrI03+VprvCEWxTpJkxZBc7ZX9t4jwp7
+	eJBP9he5JLzu36zMpVNdnCWa2NantOjqJjeQ72fMnj5yPa/3GbdnOGDlgJnvGwo4csq2
+	4jwXqYnU2OPxk2TGV1QnH5PzkDznFQdlTN9+LnUiQa6lPTmZ65eaXdzbPjMxxDOSrFgz
+	E53x3/zGLSRl3n3U3HUs/5tnbZFnGIUFARM27zY0JNGLGBrhwEUOGXpMKkxapV/QasLD
+	5F+VFhLlXRYVvVjhnhV/z3kUuFvGP4VYHHMN5Qia/k7/oi/rC/pd/fN8baG+4plzz5rG
+	q2tfGVdmltXIuEGNMr6sKYhvsNoOei1kaZ3iFfTklfWN4eoy9nxt2aPJHOJqfDXUpQhl
+	asQ448muZfdFssU34edby/av6VH7fPZJTSXXsrp4Zin6fDZcDWv/s6tg0rKr8OSNkC48
+	a6HuVQ+qfWqL2gpNPaa2q21qF9+OqgPlHcOclYkLrNtl9Sn2YGOa3spJV2aL4N/CL4b/
+	pV5hC9c0NPkPTbi5jGkJ3xHcNnCHlP/DX7MDDd4KZW5kc3RyZWFtCmVuZG9iago1MyAw
+	IG9iago3OTIKZW5kb2JqCjcgMCBvYmoKWyAvSUNDQmFzZWQgNTIgMCBSIF0KZW5kb2Jq
+	CjI3IDAgb2JqCjw8IC9MZW5ndGggNTQgMCBSIC9GdW5jdGlvblR5cGUgMCAvQml0c1Bl
+	clNhbXBsZSA4IC9TaXplIFsgMTM2NSBdIC9Eb21haW4KWyAwIDEgXSAvUmFuZ2UgWyAw
+	IDEgMCAxIDAgMSBdIC9GaWx0ZXIgL0ZsYXRlRGVjb2RlID4+CnN0cmVhbQp4AZXB10IB
+	AAAAwP//lYoQkTQUGVFpJxqUSjRUKBlf4OHuptO5JmiM/tEI/aFfNEQD1Ec/6Bt9oR76
+	RB/oHb2hLuqgV9R2L+gZPaEWekQPqIka6B7doVt0g+qohq5RFV2hS3SBztGZO0Un6BhV
+	0BE6RAeojEpoHxVRAeVRDu2hLMqgXbSD0mjbbaFNtIFSaB0l0RpKoDhaRTEURSsogsIo
+	hJZREAXQElp0C3PMAGm/R/cKZW5kc3RyZWFtCmVuZG9iago1NCAwIG9iagoxNzcKZW5k
+	b2JqCjMgMCBvYmoKPDwgL1R5cGUgL1BhZ2VzIC9NZWRpYUJveCBbMCAwIDU3NiA3MzNd
+	IC9Db3VudCAxIC9LaWRzIFsgMiAwIFIgXSA+PgplbmRvYmoKNTUgMCBvYmoKPDwgL1R5
+	cGUgL0NhdGFsb2cgL1BhZ2VzIDMgMCBSIC9WZXJzaW9uIC8xLjQgPj4KZW5kb2JqCjU2
+	IDAgb2JqCjw8IC9MZW5ndGggNTcgMCBSIC9MZW5ndGgxIDExMjE2IC9GaWx0ZXIgL0Zs
+	YXRlRGVjb2RlID4+CnN0cmVhbQp4Ab16e2CT1dn4c857zbVJmnuTJmmapOklvdHS0kJj
+	acu1FahCixTbQrkJWrFWQWFVUaQiE5GL4Jx44TptKBWCDH+MocDmp+gUlKlzn+jcPju3
+	/dA5IMn3vG9KB/v2+fOP/ZY3537ec57beZ7nnPcAAQA19AAD4TlL2jobJt+6GmveACCG
+	Od1d7kd/P+ZpzH8CwCye1zl/if6Tn/8CgJsMoFTPX7xsnuf8ub8BpDQBWGBBR9vcP3/9
+	bjuAH8tQugArlBnCCCw/huXMBUu67u4+r3wZywNY7lx825y2KccmhgECmVgetaTt7k6x
+	R4njBVqx7L61bUnHxGUr12O5B8sZnbfd0cVsZP6I5eexPLNzaUfnTx+4tRAgC4vMWxgR
+	fKSfGrO8nPvOKNn5O7sAxWaGxYgDwCEF8eruCqVKrQFtig5Ab0g1msBssdqwg/3qTv+/
+	8mnfY2DuKOi4I5DF9YCdzQcXQOIDDOekNH5j4nPuBOjiSxJ/ZipwsENSoPGqSjgKj8I2
+	6EOEd2E+C2bDFjhFFsEhMgsG4AxJhxD0AAtRmAxvkETibZgHz2P/LjgGG2Ef0j8LloAJ
+	W9cRX2I5lsOYb4dViWchE8rgITgC5TjqOhhM7E7sx9ZpcCPsgb34/i+Jl+5jUxMvJc6D
+	CFNxzFXY8nZicqIPDJAL1TAFa1fBq8THnEssACtUIHRPwY9hO/wMviT3k4HEgkR34nTi
+	t8g8KzigEZ8VZID8luljH0o8lfhDIo6UyIJsnLUVNsBzOH4fPkdRfGrJLaSLbCAbaZje
+	TwfYBzlLPIZ0CMI4fMbDbfAwUuAQHIe/wN/IV9TK6Jgu5rVESeL/ggomIZYSJh3Qjc9q
+	fNYhTocJTwrIWDKFrCBPkI3kVzSb3kib6F30bvo508DMYpYxv2LvYPu5tdwWXhX/OnE4
+	cSLxHi4pJ9wES2ElYncMTsMFuEgYHMtBfKSCVJPZ+PSQbfQQ2U4O0SnkKDlN95DfkE/J
+	V+QS5aiammgO7aIb6F56jL7JLMTV8yTzG+ZrdgxHue3cZ7xP+HW8Pb4m/maiIvHbxLeo
+	BUTwIGeqoQFuhjbEthNGwA8Qixfx6UOuHYfX4JT8fEocMAjfIhVQVxA7KSL1+DSQ68k8
+	spA8TV7B51UZlm8oMoIqqJ5aqIM20na6hPbQ92gPk8ZkMxOZmUwfPieZM8wl5hLLsams
+	iR3HToC17BJ2Kz472F1sP/sWV86N4Rq46VwPt4Zby8zh3ubO8Cv5dXw//xX/JyFLmCzc
+	JqxF7pxCmf3ZNYuDJZkIfRHcCnNIDWmHTciN7aQNelG65pKHkV6dkJVoYVYy42gBSsOr
+	cA9K61ZYAWuYWbA98T6zB86ipCzGUXtgJ1sNTm4zcud+KEApGnrCwexgVsDvy/RmeNyu
+	dKcjzW6zWswmY6pBr9OoVUqFKPAcy1ACubXeulZ3xN8aYf3e8ePzpLK3DSvarqpojbix
+	qu7aPhG39F4bNl3TM4w95/1Dz3CyZ3i4J9G5K6EyL9dd63VH/qPG646SmVObMP9ojbfZ
+	HRmU8/Vy/jE5r8G8x4MvuGutC2rcEdLqro3UdS/orW2tycslh8JIDmVerqQ4wqCSBo7A
+	2LYVC6yYSD1qI3ZvTW3E5sU8tjG+2ra5kSlTm2pr0jyeZqzDqmlNOEde7sIIwgmPqOd6
+	5z4SDUN7q5Rrm9UUYdqaI7RVGkufE7F4ayKW5Z9Z/168kqtde1VjhPrq2jp66yLh1keQ
+	uFKxVSq1rcXSpEY3DksfbG6KkAeHgJBgXISQSuB2eGsluFoXuSMKb7V3Qe+iViQuTGvq
+	t4fttd62muYITGnqt4VtciEv95B1ZYUHsT+Ud13edVJa4bGuTKa/eyBZ/85RKbWuPP4J
+	ppOmDROASDN5JyCcEfcceRIvAlsmRR1l0DunDOmEv2aCaC5EeMZGKMoM44twvgltkZ7G
+	K2AsqEkC17qopl9hs0s4tFY3Y//WXt0o5BT213ndvV8DstA7+OW1NW1DNbxP9zVIjRKj
+	h2UlQtqu5LtlwiDWC6zeBRJ/u2WeYtlrrb2qAssSaSSYI8ZI0aQpTZ6IuxkropCTOykK
+	iilN+whZ1xwliQejUOM8BApgbp6NzbmSqC2swfmxkJeLFdkezIVy3XWIdZ0kK+5ed++E
+	ub3uOvcCFCbWJ6fY0NHbnI8UbGxCOsENOGO4OW0429HcPArHyZfGwVewe28zjrBoaARM
+	5ar8GHYqyJ2EXPFPaZraFOmpSYuEa5qRCyi+R6c0RY6i5DY3Y6/CYUgR4hULrUMwFyHM
+	hdnYXpwcpRHHwCGae3ulMRubvJ7I0d7etF5pvSXLUQL/WBEeqoiC1AURr42Snin4LiZe
+	T5pU4fV4PQhWs0TTESjSVyQqCiXfTeHSYbjxzZEIbalM4bJ/EYXLvw+FR30vClcMQ3oN
+	hSsR5gqJwqP/fRQecw2Fq76bwuFhuBHI6xDasEzh6n8Rhcd+HwrXfC8K1w5Deg2F6xDm
+	WonC4/59FB5/DYUnfDeFJw7DjUBOQmgnyhSe/C+icP33oXDD96Lw9cOQXkPhKQjz9RKF
+	p/77KDztGgo3fjeFbxiGG4G8EaG9Qabw9H8RhWd8Hwo3fS8KNw9Deg2FZyLMzRKFb/r3
+	UXjWVRRGh7cagD2Ney8GBKiKQmNOFMR8NH4YRF0U4DQGqYx55sMosBgA88KH8Aq+ATA9
+	5xUchcO0oLBY79EHMFSz66KX/5M7cnFslK2/tB97UXgBt6ZzcB4N7nXmh12r9ZsMtEhU
+	padQSLeIYmGq3a7xaW02+xlP9xprTk7DhfpYg+6b+kGoilXFCgvGLgv7iVnvM/l5gRNY
+	gRGowPFKnVhEiBkjhUFVRAQjes85OSQnJzsn574WX9HIUukp0VGvR8943Baz3ijQIKGn
+	O67rmlhhT/ngz/Efn6SNJH/nxqZt8YdifXtMgduaH2kcR/QkdGkLl3r2WPztPxyJ9yMO
+	BHduwOUjDiqoCntERTpDKUuoUhBZwcdzdg1R+lRgU6s1z3i6OxEHXcOFyvpYJaIhJVBV
+	WVVZnl8ZqywsSJVIVaz3YuzdfopePnUqxp7ijsS205svjqV9sanyfKdw0sdl3ljQJ0FC
+	SycBoRzcz0osofkFhTiO99QpfPPiWGzcjHt/C/ZPhV+Gm2vIJIbyRMGYiY05S7hU4mCM
+	qjT1DNLEvEt+zbyr+rVaySpZTS19iLJT6WZKg8osTZmyTDOOzqDdVPDN1SgpY2AIVakN
+	DC+aLBY7y3JRsi2sUboYFR9TExrTuAxYcyAVbEYJ6QadhPN524Xycvxbz0vo13bUfA5V
+	FkTfYCmfNG3ZPo06SvYMUKSdCjP9lDKrufrQ8hi74vhqLpkWFkDL0tvJ0pbbUz0KgmTS
+	jygtIV5iMppNeu9m4iQ7yHPEfoSNt7wWn8m9yh255GfPXRzLzMk7fdelIHs2r/SjEZd/
+	JMteH8r4t0gXJRihLVyyUL3QsEy93MCONzYZFxiXG1lBTNfrdEqiTUknQJUi5Q1qVmE0
+	FrJ2c4rCBzaTOUpU+z0br0imxNP6mB7Rgaoq5KjOIDOWtBQWtKR6inA3xaPEeSHgx8RT
+	VFrSRzce/9OZj+NFJ5ieu6vviHeRtQ/t5I58dPInidgG9tAoV5xZisdPFFoT77HfcJ9B
+	Pu7Z4uHZwZSA1+8v1ZZ4xvnb/cu1d2UqbhGtWouPNmsXaPdkMErtqIzMDCXDOqwPGfPz
+	cxyjjAw7KkdRQJVaUZ+Z4coqKNBbfZYJoi/LXuTy6SeAL99WWPSMZ9EQMoMXBuWFdmEQ
+	kTDoy8ulgGgNVkkVukEJy1CsuOV2eRHWZ4X0LhCpn/rzfLzP7mdyIQfyQnLCZYs5xJnq
+	yoE0kzWH2Kwkj80BRUCVQ3wqEsK8EMQo3eDARjNGKNW4THS4ZHWVclaOce3edx+0ELPF
+	XIxLuGREwJ9P/AF/yYjM4iLW5MWsN4M3GS1ml9THZGS97oB/JCHpwog5Fztn9U+a/OyJ
+	n09dSwyXfkfGHk4pvOlcZOvMitNvbpy6Nv6j/4r/cds2htaTcysaHnePeebu4iJfXm7J
+	rIOvx3/zdXfVHU+0Ly5yF+RnVMw/fuGdtY/8kVVJa9+DMoTrDHXeiLCd8OkgUFZU4IqA
+	S5Txcewl3iaunS3Lf/0FlIgLDUmpr5KWfmEBMUki7ClhT8X1v4jruSN9F//CaVEw8dgO
+	piU+lE8SUvCMqBI+CpdlFxClDteqI1A8XrdQsUgnlIsGtYJJKxIyFU6d2lmRQ0PBioMV
+	tKIo22fQCZzoCGRYHFHSG/ZanC4h4AypqLNEVSlUVjqMQjB7V6Z9TFrQMTElUGYbPean
+	ZDMidIhsgqSmHRKB87HjyPEk66sGkfsS61v0hvLQYGiQYKq3lMtCkFU60pQBxOYjpSke
+	sKanecDsNnqIJwNGUg/YnRYPIoyRxN8h1iZZ2pIps3Q00ZIUwgu8iUj6eQTyU+AF7xhS
+	XIT81BuxE06hJd6MgD8gJcj70pGpRLu04ebmTZ4FRUvaCxvJwBiT+oHlj1Z4lLu4vz53
+	pPtOi0+drs/O9bdkmxUj37x345FXNve+NTN3wo71Jgev1Tjy55PFYq41b1bj5OzG17eN
+	H78lttmRwTAPqvlqb3j8opcf3vh8KjkvrcPuxMesjzsGekiHznBoh7DTcdbBZIgp6RSP
+	WC1OTtAr050qlTEg2t32kC5EgqC3udyrPUdaZKJKWvD8kAUblFaTvlyfpJ7VYOaVZt7o
+	JwYlRibB4iepinR/0nJJko9qXSKFQW+kMgVM3swkkWShL+7uq3i+9eTfvjm3/Iai8h10
+	3vr1j95zyD/uGHcs9l/1U+OD8QvxeKTCW79mxRev7v74wNubZ++T9SCenjGn2QY8902D
+	neH8nTayxbpL3GNlJor6bUaGMfJOu6BxopUQ0tIsuoCBMAGqtzuVAYvN4YwSYb9n6Yoh
+	iZGN2mB5uaQjrlIWsniMAJvoU5uUftCm6hBLfYpOsGGJA8ZDCGUZlVnjhxQDRgor7ycs
+	4T1os2VRkfSArlLWBpIKaMGzam8IBQBFJSkVxZI40BIdFAv0zKeWPt3SlT+ZWPDw450P
+	2PrS/3T4nYvE8K6DbYicnfPAriXPbP9wzV3vvUaKP8ejv1Ec8rUscY4ZRL6qwAl3hYtG
+	asdpZ2h3srvTOJ9opClOHYhOp5CqpE6LigulhnRBvcHuUgXstnTXas/S6qvRRwYDMvZq
+	3tqtDoUSCLGqEDcHRmCjflCmiX5EEP/yKjBI4i0LPW8Ci9kieQIlElpQMsJQ/M3j21ds
+	37H84d2kt7Fg9IvPVv3ktv3xi199TG7+4uypX/789C/oyBHpk6jz4piNc5pI3sU/kBmo
+	Q8YnzrF2PI104Mm1j6jDyzaLT9p3uhhOS1M4o0lrSDEZw+qwUQzaySTVAeYEeZ05kfa+
+	+IHijOt97xeWL7yqE/oTBjpL5DyZKVvNzsxyXhDMHqdDUDrNKp+w2bHTcRDXAOszp/gc
+	nE2pFvTaQIozwNkDmSEhYLP5A+96diSFH2VfFv13Y+WGclQjaFTK81uG5USymGhXksuh
+	Drwsx+BRL+FY3uXX6wy6VJ1Rx/JqX0Zaph/c4PSTdKfCIvhBZdL6iUbrtXuwisNItKJc
+	aXQYyaZE1jWy8GTnZN9Hbm+B21skEZKshCcdlxS6gyhAqGt4pLYehUiyK2hMBEIHzpSV
+	GnSXv+Ie2/zoDQXGfcL1hdOWXTftZPwPxPqfxKXKmvjivbs44mXH3XLj1MUTn33utZbS
+	cRXrQ1McOvRLeEJJddx/Z939+3vJh0m9PjpewXyBPHFBHn6JOBiuLzVOECcomsRmxcPq
+	3Wm7nLsDO3IOpanCImPOCGqPKzNQdbN80GlTGpzKlJAQCnEOJmQO5QU5e4FaG9CM8Qcc
+	tvyCqwTxwmC5ROnY+a+Rnld0d9WgTN4kfXO9WfZ0lT7Tp/N70/1+yLJjpFdpPZCiVWt8
+	zgw/CaQFcT2qDWjk/r4KMSdLqyShJcXoOPOeDH+geMgoy1o5U6IgyMpbXp2oygm9d3Zx
+	yY7KzvipF7/UHtQERj/wVtjPlG5Z8VL8EhFeITXP/+DVOt+Ge49dnxt/m60e4x27+nLR
+	G93ntr0wPlD5+PSPpk35Kzp3GhKKbz/af/PWl4/0zVlF85CgBL+mgLx2zdAYzkXpFC2C
+	RQywgdQ7hTtFMVVDU034hcvJCya1UhNU2q3EFASzzWKNEn6/pz25diV7PKSWK+WVW04k
+	QZSVLtqipAFCbzPpY+i9qwbCxTPu/31j3qH0wtWdBwZQyX441VP+XPPTsan0ue6RTVvP
+	xE5K/KYSfKQCfQRpL1UadgifsQg0zyglNwHlIygwqBgVe/4OyfFY5fFhP6GqflDeGHj1
+	xSbvqoP4Y7MvneGO4FdOHGYNRqPlsYNhxJJRcjgojgmMjeWuGhKRG3I8koOtGRiQdwdD
+	9ON97Djww4PhCkEUtHyKRbRoLSkBMYBLebxtumq+Su31Ke1Or01JWYvP47Q4NbwAfJrD
+	x6Qqs3BOfdAYJaTfHkSDQMKo60I+FB5bICtKNFcT+bzuwuCF2BAw6PujIzQo+5KSI3GF
+	4qYhiluuWH4kvLQc0cW/igP94RHNt/c05GZWPtvxfkP24VvqFz150B7snLdzgM3fcn3m
+	6KrMuumNT92wLjaSfnHLlHU7Yuvp4SVFk55+S+KMzBdmENehDS3f7HDhQf4ET1neyAeM
+	3XyXwBnV1GjVoUUH3qpS2gW7HdRBhd1BQtagDWxp6FZdIz5J1ZZcbYjXILrLQyJE0HKb
+	rkJFkiHUNVqC+JBVeyfvWXB+Su5BZ8HKcHBiWV7aANmJ8M+e9uMZz0qy1F45V2OuLrl9
+	YewtBBalqCLxAetBe63GPbMNHgsXbxE36Z40v8DuEnfodpuj4knxLPuZ9vdG9SiRd1oF
+	tdOgsgk2m4kGUuxpioDJZk+LEgVa7SGtnHT0h/WEbKxzwcL6VakK1KB66ieCBXOcBnNK
+	o9oPRIeRaEYjzWgxko20FOWgcc40SJ657Imbiw2oTakHLZhsmD95sGDyKy9s2vQcfoS9
+	HP/rR/HLxPA7vouk7Ng0+4nL/XvPM+fiX6KbEou/RHIuozMYlmxzd/xG1oeoayEDusK5
+	u8WdFpoluh16Le80CSm81ulQZWhpwGrPVKLH5QlmpNi8mf/U45LNsl6WMzw5cJjTgLP7
+	WT+kIWKcGSNi0/qBscg4yWhJfpfkZSV5Jm0uiklxUj7xw5hkL9AV1Xvp6zt9da8crvVh
+	HA/1lYZvuudA/GDX1mXTCioGlv3qnZ5Z+w7P3XrvjB3MvnUTsirjv0ccn910c0n6hNhH
+	Q+uYPo5rUA/Xh/0Bxq8ZyYxjWa2oo1qFXqEOiJIY6pWiPZVIvgfYDKlRUosLa+WwV9mg
+	w910VX3V8dhxybJK6ympv2TRM1tMkr8kLaE1e03P38JZnbo03cOP41I5VLqNMq8ytG9p
+	bIu0LqoTZ5kD7CS0TfkkFP5hmWILt8nwpHGLaUs2n5XpC5R66jzjMscFpmfOCMzLnO9f
+	pl6mWabt9nZldvm6/DvSd+WmMmiSuTw2lAp2U5rFYTXlGUNZKaqFot9X6qO+DI2SzUm1
+	vu5wpgqsM7Q1R5UvKLQ6KkC+J9/uspqtAcuYLL8QyLIXal0B3RgIhGwFhf3DfgSqkKR9
+	K9dhTkK3PB/joR0qblFllZLcmk4medRvwi2pR+vygMIveAjuSj3AZWPOacC6NKPVQ9wp
+	GR7wZGg1YkDpIX6fQom7VA/wQYzS9Q6PtDNN7lySjqjsjcoickXw0S1Nlc2gLC5DW1PZ
+	cgj/c2+KguMPkK9EX82uuVtGB+744Zrrun596C+3jKV7OP+YJ+ctrM1quOtY9cIPPv7q
+	hEAOkikzC2bMuKk2Ez2wjOwJ92356bqZC0YXjWsI12XbUp35ubVP/PD0B8/Qv6FNsCS+
+	ogpuJmqHaS9rQsqjWhIlVWEfay63MLxWqbejusYv8UEwaU0pjIuhzGUznrBd9swf8uJj
+	LeXHpQMpXVJN50tKOlY5qIudl40H2iG9tA6u7MX8JeinFu86sHev31SoSTe6xgZWzly/
+	npsZf29DrLYsVUXoOoV433z62gbZHvYkPmU+xvVsQQhnh0dFjSeNVJEqGm2pNmMWfxdz
+	Fk04cFol8Bolh7rLKlituDUIKYNqld1OghKw71yxlvWS8pI2Vcj+pJ+Dp2lDok9aSBJQ
+	dEAkZ3qk7N/hgYHeR8rsBQ/8tMY3sId6R8zf8FljHulj82Pl00a07pr5I6q99PbTo7Nv
+	eHLaGvo+XoehYIpPkH02SeP+Inxrr+lh604rI/AWvsww3tBkmC/cxdwlrDVugc3cFtNm
+	82bLLthl1o2HSaZxllMmtoZ7naOruR2wg+zkdlm4zCzOarKY0Q8wqVUpTlErKWhzGnKG
+	A9JnMVn71D80o55+1zNfWuE2PPc8b42Vl+PfJnPFmkS3PlZeZMu3VlVWVkprHk/RwgYT
+	3uQxLzFYLFaOkCUGAOvqUI5uxXE5ETEl0qHN7biJaiHFPEMFKgtjieQIl44cQ0aSYsIw
+	nhP+B9qrn+p5yh9Mz8/WFeXruDHaeNcbxEXY/Pnx9fEvX4rPG+DF5zW8xyo+kck2XN7C
+	3C/ZJwdGd3PvIH/T0MdtC5emfWYDwckrnQxJMZY7zRrepVd6ENe09KDVpdXogxaDYEjR
+	urRUe9loc3ve8cwf2lENi+IZlMchrwEPDCV5rBp8Fxc6KSwwSO7ZsH6TpBOfkuISX0mx
+	SUC2v+ytGtBnWhw21TR3/0D/xo00dQB/XPWIWZQ+T8mNL627PJd5at0u1xtvnLh0Rvar
+	MAL48tv8e25Oqfwa9Ml7U69Prn1WqpdTU7yC9+GJHOD3XyLV4g9TPhgP4hUu8m3H5UHV
+	+uGWZDuAgzNANS3HE+MT8AKG7Zg/xe9BqZkOfRha2U/Bw94B0zB0swAVmJZhGI9hNIZV
+	5IQc1uA7q6QyBqlPN90Da7C/NLYFyz2YN2FAXuAdmBGwCd6Ez8lScpI+QY8xa5lv2LvZ
+	89xL/HR+B/8u/42wVHhTrBOjYlzxsTKkfFiVrupJ4oMj3IY8vQV9Vwo6fFrwGtkXSjXe
+	n5KwJnirKYk9j23QMLN22vQpOeM7Fnd3dC2c04Y9KAb8JTrwXtE/+0kQMhDA08JcPNss
+	hlIYCTVQC3XyjaWJ8q2k6+VbU9PwJtSNMB1mQBPMwlsyeOAtfZeYgKEKQwmGnJzrrNBD
+	dsBjGJ7BwMBC8ggsw7AGw5MY2OHcbiwdIo/0s2L4FbIM7GRiWMW6bjDaXFalyvUOuncD
+	T7s+sH56mNjw+8Rvia1fA4rrlOQZ8mOYCy7yAu6ol+OtqiyydX9wsasVm3ZDJ4YeDIwc
+	E7K7P73I9SrJBR9L8B0/pLPkgOt3hXmuzwqjlPS7jgWiLCY/S8dSOMV11Pm06/8457te
+	xbA32bQniD0OuHY7F7s2pEfJ1n7X45KT3e9an0zudOKrB1xLgptccwvl9smbonRvv6sc
+	26eHVa7SMo+rxHnelR+IigTLec7JruzC/3Bl4ovYzY2D+sJ6l8O5wTUKm9KdtYFRGA6T
+	PWQbZJNt/b6Jrlcwi+junxAs2xQl9+wfn1Xoi5Ll4dLxWZuC4wO+4GSXL1gXCGB++klh
+	lXCTcJ1QJOTgxSY0uEKaYBQNok7UimpRKYqiECU/6a9y8YfJXqhCsuzdL/IifkJ4CSvZ
+	w+RFufLFgyIrUhFEYzTxCV66JIBbjL0DKGYEMHOAl3N8lLyI35KkqhfDLhR5AqzcoEPJ
+	w2N7FC8UUEpEChPxBsmjUR4eNHdXWasMY/TldTX/W9Qqt1yJZRP/zyMrcUY24R2GyB5n
+	M14XwUzC2XylK6ru/8ev607s0FGdk4Oqe39356J58vUXb21HK96CiTzSjdeRetrd7n2L
+	Oofu9vhb2+cskO5ftHVEOr0dNZFF3hr3vm75Pan6quZ5UnO3t2YfzKu9oWnfvHBHTX93
+	uLtWuga0v716acs1c60Znmtp9T+Zq1oabKk0V7v83j/M1SI1t0tztUhztUhztYfb5bkk
+	EtQubKy+owulE6/I4BWVrMbIhKkzm/AmWHNNlOyQ7s3cCf8Nq6YP6wplbmRzdHJlYW0K
+	ZW5kb2JqCjU3IDAgb2JqCjc1NjgKZW5kb2JqCjU4IDAgb2JqCjw8IC9UeXBlIC9Gb250
+	RGVzY3JpcHRvciAvQXNjZW50IDc3MCAvQ2FwSGVpZ2h0IDcyNyAvRGVzY2VudCAtMjMw
+	IC9GbGFncyAzMgovRm9udEJCb3ggWy05NTEgLTQ4MSAxNDQ1IDExMjJdIC9Gb250TmFt
+	ZSAvTlpFUlZQK0hlbHZldGljYSAvSXRhbGljQW5nbGUgMAovU3RlbVYgOTggL01heFdp
+	ZHRoIDE1MDAgL1N0ZW1IIDg1IC9YSGVpZ2h0IDUzMSAvRm9udEZpbGUyIDU2IDAgUiA+
+	PgplbmRvYmoKNTkgMCBvYmoKWyAyNzggMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAw
+	IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMAowIDcyMiAwIDAg
+	MCA3MjIgMjc4IDAgMCAwIDgzMyAwIDAgNjY3IDAgMCA2NjcgNjExIDAgMCAwIDAgMCAw
+	IDAgMCAwIDAgMCAwCjU1NiA1NTYgNTAwIDU1NiA1NTYgMCA1NTYgNTU2IDIyMiAwIDAg
+	MjIyIDgzMyA1NTYgNTU2IDU1NiAwIDMzMyA1MDAgMjc4IDU1NgowIDAgMCA1MDAgMCAw
+	IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAg
+	MCAwIDAgMCAwCjAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAw
+	IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAKMCAwIDAgMCAwIDAgMCAwIDAg
+	MCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCA1MDAgXQpl
+	bmRvYmoKMjYgMCBvYmoKPDwgL1R5cGUgL0ZvbnQgL1N1YnR5cGUgL1RydWVUeXBlIC9C
+	YXNlRm9udCAvTlpFUlZQK0hlbHZldGljYSAvRm9udERlc2NyaXB0b3IKNTggMCBSIC9X
+	aWR0aHMgNTkgMCBSIC9GaXJzdENoYXIgMzIgL0xhc3RDaGFyIDIyMiAvRW5jb2Rpbmcg
+	L01hY1JvbWFuRW5jb2RpbmcKPj4KZW5kb2JqCjEgMCBvYmoKPDwgL1RpdGxlIChVbnRp
+	dGxlZCkgL0F1dGhvciAoRG91Z2xhcyBHcmVnb3IpIC9DcmVhdG9yIChPbW5pR3JhZmZs
+	ZSBQcm9mZXNzaW9uYWwpCi9Qcm9kdWNlciAoTWFjIE9TIFggMTAuNS43IFF1YXJ0eiBQ
+	REZDb250ZXh0KSAvQ3JlYXRpb25EYXRlIChEOjIwMDkwNjAzMTUyMjEwWjAwJzAwJykK
+	L01vZERhdGUgKEQ6MjAwOTA2MDMxNTIyMTBaMDAnMDAnKSA+PgplbmRvYmoKeHJlZgow
+	IDYwCjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDA1Njk0NCAwMDAwMCBuIAowMDAwMDAy
+	MDU1IDAwMDAwIG4gCjAwMDAwNDgyNTAgMDAwMDAgbiAKMDAwMDAwMDAyMiAwMDAwMCBu
+	IAowMDAwMDAyMDM1IDAwMDAwIG4gCjAwMDAwMDIxNTkgMDAwMDAgbiAKMDAwMDA0Nzg1
+	NCAwMDAwMCBuIAowMDAwMDAyNTc4IDAwMDAwIG4gCjAwMDAwMDUzMjEgMDAwMDAgbiAK
+	MDAwMDAwMjQzMSAwMDAwMCBuIAowMDAwMDA1MzQxIDAwMDAwIG4gCjAwMDAwMDU4OTAg
+	MDAwMDAgbiAKMDAwMDAwNTkxMCAwMDAwMCBuIAowMDAwMDA2NDU5IDAwMDAwIG4gCjAw
+	MDAwMDgxODYgMDAwMDAgbiAKMDAwMDAwODczNSAwMDAwMCBuIAowMDAwMDA2NDc5IDAw
+	MDAwIG4gCjAwMDAwMDcwMjggMDAwMDAgbiAKMDAwMDAwODc1NSAwMDAwMCBuIAowMDAw
+	MDA5MzA0IDAwMDAwIG4gCjAwMDAwMDcwNDggMDAwMDAgbiAKMDAwMDAwNzU5NyAwMDAw
+	MCBuIAowMDAwMDA3NjE3IDAwMDAwIG4gCjAwMDAwMDgxNjYgMDAwMDAgbiAKMDAwMDAz
+	ODc2MCAwMDAwMCBuIAowMDAwMDU2NzY5IDAwMDAwIG4gCjAwMDAwNDc4OTAgMDAwMDAg
+	biAKMDAwMDA0NjkwMiAwMDAwMCBuIAowMDAwMDA5MzI0IDAwMDAwIG4gCjAwMDAwMTcy
+	MjYgMDAwMDAgbiAKMDAwMDA0MjgzMSAwMDAwMCBuIAowMDAwMDE3MjQ3IDAwMDAwIG4g
+	CjAwMDAwMjAxODEgMDAwMDAgbiAKMDAwMDAyOTA2NyAwMDAwMCBuIAowMDAwMDMyMDAx
+	IDAwMDAwIG4gCjAwMDAwMzQ5NzcgMDAwMDAgbiAKMDAwMDAzNzkxMSAwMDAwMCBuIAow
+	MDAwMDMyMDIyIDAwMDAwIG4gCjAwMDAwMzQ5NTYgMDAwMDAgbiAKMDAwMDAyNjExMiAw
+	MDAwMCBuIAowMDAwMDI5MDQ2IDAwMDAwIG4gCjAwMDAwMjAyMDIgMDAwMDAgbiAKMDAw
+	MDAyMzEzNiAwMDAwMCBuIAowMDAwMDIzMTU3IDAwMDAwIG4gCjAwMDAwMjYwOTEgMDAw
+	MDAgbiAKMDAwMDAzNzkzMiAwMDAwMCBuIAowMDAwMDM4NzQwIDAwMDAwIG4gCjAwMDAw
+	Mzg3OTcgMDAwMDAgbiAKMDAwMDA0MjgxMCAwMDAwMCBuIAowMDAwMDQyODY4IDAwMDAw
+	IG4gCjAwMDAwNDY4ODEgMDAwMDAgbiAKMDAwMDA0NjkzOSAwMDAwMCBuIAowMDAwMDQ3
+	ODM0IDAwMDAwIG4gCjAwMDAwNDgyMzAgMDAwMDAgbiAKMDAwMDA0ODMzMyAwMDAwMCBu
+	IAowMDAwMDQ4Mzk3IDAwMDAwIG4gCjAwMDAwNTYwNTYgMDAwMDAgbiAKMDAwMDA1NjA3
+	NyAwMDAwMCBuIAowMDAwMDU2MzEzIDAwMDAwIG4gCnRyYWlsZXIKPDwgL1NpemUgNjAg
+	L1Jvb3QgNTUgMCBSIC9JbmZvIDEgMCBSIC9JRCBbIDxiYzVlZmZkZTlhMWUyZTllZTdk
+	YTA4ZDUwYzhlZDc4YT4KPGJjNWVmZmRlOWExZTJlOWVlN2RhMDhkNTBjOGVkNzhhPiBd
+	ID4+CnN0YXJ0eHJlZgo1NzE2NQolJUVPRgoxIDAgb2JqCjw8L0F1dGhvciAoRG91Z2xh
+	cyBHcmVnb3IpL0NyZWF0aW9uRGF0ZSAoRDoyMDA5MDYwMjE4MTkwMFopL0NyZWF0b3Ig
+	KE9tbmlHcmFmZmxlIFByb2Zlc3Npb25hbCA1LjEuMSkvTW9kRGF0ZSAoRDoyMDA5MDYw
+	MzE1MjIwMFopL1Byb2R1Y2VyIChNYWMgT1MgWCAxMC41LjcgUXVhcnR6IFBERkNvbnRl
+	eHQpL1RpdGxlIChQQ0hMYXlvdXQuZ3JhZmZsZSk+PgplbmRvYmoKeHJlZgoxIDEKMDAw
+	MDA1ODUyMyAwMDAwMCBuIAp0cmFpbGVyCjw8L0lEIFs8YmM1ZWZmZGU5YTFlMmU5ZWU3
+	ZGEwOGQ1MGM4ZWQ3OGE+IDxiYzVlZmZkZTlhMWUyZTllZTdkYTA4ZDUwYzhlZDc4YT5d
+	IC9JbmZvIDEgMCBSIC9QcmV2IDU3MTY1IC9Sb290IDU1IDAgUiAvU2l6ZSA2MD4+CnN0
+	YXJ0eHJlZgo1ODc0MAolJUVPRgo=
+	</data>
+	<key>QuickLookThumbnail</key>
+	<data>
+	TU0AKgAACVSAP+BACCQWDQeEQmFQuGQ2FwJ/wV5xNuxUBxeEAGNRCNAGORuBwSOxCCx2
+	ESSFAqVCKWSgAL6YDmZAeaQ6Cx8AzadQtxT0Cz+XOChB0OhVyuV5BINBUESKNQ+BP18v
+	kAAgEAOBVOqAQCRAEVyOvt7veq1+nTmCNi1S5vW0Ogx7LRiuwLhF5tJqv4RiUJhMCvZ0
+	uxzOwFCAJvp6v9+gEEvRvuJ/xcVj8OOVpPsGApxvcEAxzOR8AwGgh4vEIi4bjkcCemgC
+	1NiXRVuhvaSUAvl3Op9gYC2h9v8CV8CPhxN15h8QBLfvp+vh+v4GBQI61+Ph4VN9vJ7v
+	wCAcFb0FhAIb20ABteeXNv1UQOy6RyGd/H3xGzy5uff0+raBt7PZ6m4cBEgGApuoI+iD
+	vo8qdQShJ6nmBAMgsNAOg4GyCtklxsw0/ZpGoT4RhUR4HAcAUEHoekEgYBkFIIfEUM6A
+	B8H4qoCRYhJomaF4WhQUSIG/H8Mw0DUhmubRJhaGZPIUfxakweRzgcAoDnQfYLBYv5/p
+	zGYAHQfgFA0AZ4H2AoricAyFmoaIQBQERXoKoRwJca05yGDS8EgGodlIhZ8Hefp7t6AB
+	7SzErfoJGoALIBIDH+e4BgECoIxsgs0hAEwQFaiBx02lxq09Opsm4WAPBIQQIgiAb41U
+	hZ/H8f5gl4GIchqTaCnJW6XGpXQM14fdfGiaZOgeCJzoIfyFLRBgAQOkUDWag0GH+6II
+	i1U4OIKc1spcaduV4DKIHAdRtnCehrn7c751W2yPPggoDH8BYahAH6rAQjtsnMlxo33b
+	xmm8YpYg0PQDA6fSTXVdR9HmfwSGeJ4uBOPCCnViiXGhi4MYyWRwE2aoWE2cJiAACQVA
+	EAwJQGAB/HkdQAAHVwDgmfx0mefoDg0AoEgUAB9UGAwFAFEp/2PLIFAGAwIAEBRqBAOo
+	MT2gh16li2LgvqxYm+TJrhkUBymWfR/HrlwFACBwbAOe2vnudJ+gkIgDnkYSqAyAR7na
+	AAIAef52Gzm1ln8CABgWHQFAwCwAgGZ4PDoC+oAAdvIJcZ/J6sC5XmuTJsCAUgBAHSeE
+	IQfh6H8AgGRKg4BmUEI6A4UKIHd2CXGb2fKnMdpwk2dA6nuDZyWXZnQJ0Ap+AYHZ4DEJ
+	ASiygp3+alxl+gC3pJ3dKDvn6vgnl7Xn+gCvvHgeZ5D8d5jm0BZ9gBSaBqem6I/ZVQFH
+	ifQ3gOyYNBOiSJpcZP+e8ConRvjIEMDgqgCymvNAAAUBwAAGKpeCTYGoyB3CoAsEkjqJ
+	0UHwGRBt6QFhIjjGOJIH7pyCC4GaAAA5TRuDlLKAACYESDALAOAAeY6AAAGgWPIqipwA
+	GBAAEAGoAGcEFBSM0doswIBJIKf1QZ8BjxPf8I8bwwxLBGNaQoejYhwDxAACQDSiWxAF
+	VSlsAhBB7voAIqkfaJQLRXIKCiIwswHhIIKWMe5Lhix5ApHsXA5BqBwBYOsAAFwHwPYQ
+	c8IAsxyiYBSE8gpWiXDDkk/4fklRVjbGWOKGCCUFPrc+gh9xOZPEGAcAEAwVAEgjAoAw
+	B5HR9SvkjJIvrMlWjSHUO8ag8mwEDeAQ5ZJ8QFD+H0EkD4FUVAMIhJUfksRhgSmcL8bg
+	4g4gIBaPwCoG30yfkMQke49QpDiGQIIFoGCCrnH6S4YU6VTgRE0NwdYlAQBCJsPYbh5m
+	xAcAkAAfcYx8AAdKABCJOwTjdGUKsE4CX2kQQOL+hkzgJCXGyOkTIJQjE6HoAAdixRpj
+	XAAP0BjUSCRfCID0nYJhuDKFUCaGZ9T4EwF9Q4Tg1hxiVBLEork22EAsGsMEUQKoFkEI
+	uVg+AvaiTrHQPAeIdxtDyHCBMD7v6cE2AYP4fYZwBjrCaCMDJBSuFdPgLysB4gIPXJBL
+	1dZOK0HwrIuxLNZV3AGUZV+sAD66DwHcPMZQsB/j7HgBFV1ZqokHH8AIeYJQfD2BWDQC
+	xECaAHJcLqyCIwHDMF6OofQ1AjxpAOP0fQ3Bzj2AABQBoHACkEHsWI74CR/ABjKPwd8+
+	wI2lWMPgf4Ao0gDKuQceQCBihEDJA4ABKgFEuFxcWugDxmC7HgP8bUSiCD5HqNMc49x4
+	jqHWNwBgDgPHfAIOkdY1wJgZA+Okd4+gQgWBGO0d45QEAGAIP0fY7gHAYCpEMgo8ACDJ
+	CKGdY5BAF3/JcLfAVxxji3HSAUb4USDj8H26QAsJLAkIHjfkIYZpzkCAbhklwtcOXHG0
+	NIdY4xeAzAiAoD2ESbD6H4PceQDxaBGC6BkjuGQGkuFpjeyUyhsjSHSPkeFH5RyjfaQY
+	p+QkDShd+d4AIIAWgFAUAsBJHaxY2xvMecw+BvT9hsq2/pDK1kurOQIjo9gAj2AWC+/4
+	DgFkFocS4WOb7JDpGiOkIAzggAXASBdg66h+HNH4AEq2ECEHbHuMABwwAEBNivLPN2b8
+	aD1GIPUJo5gmj8HyNwZI7RpjYHmP0GQFgUDxHsPAB6UiqKCHuOoCYFAhgVHuMscr6B3D
+	4HSYwDwBh8j0BMB0IQGkSjHH8McewV8yEaj2BQlwsNlTHHoMMegUB0hQo6PQbY8BtDrH
+	2PoDgEwWAJHzp0AIDXTDrqWO4DoFMSD+HeOceo3x1D9AEAgAoE2eDwA0BIFoEUSjGH6M
+	Ye4WI7kCg6S4VvBcaDtGKO0Kg5gqRitligmwuh+C6H+FWtoAWMgYJcKzjkxx7DzHsPkW
+	4+QSMMIjYDiA+gCD6HICscgEAUgQIKnXjfHL/gLJwQ49z7608XJPmJ95COaHwFX0Xm48
+	h1jpAiLsTIFx6jo5PxAhQ89ADkBiE4B4MggEFA510lwquwXCHoMUWYVxxi2I6PhGRujg
+	AGAHAsfo541ghyi7/d4/x5adAIAsAoHADolz6o4AaqCDDBAEBseYVQ9kFPYS4VHjwE+R
+	H0MYWIVRzC8eYO8ewqR3UAXPAxkzLlGAAHqPnbJ0wOPoAne8bo+R/RnAEC0C4CASUrII
+	MUf4Fh2BVD6QUEHvyXCn+F5EBI8hgiuC8OwYHUj4jFkGOsKfiyCAh+oS4U3116jzG6NU
+	HIxxNAmAXNrqQ9h+D+FUAoF4DglhjIKCP9xLhS/xXrlwdo3RrgLHoOoAKrXg5F5QnKM6
+	AKBIBgsaK0BTAOJcieGOU2HGsa+YdAI6q6B/AmzBAfAsyO//AuwiICAAAA4BAAADAAAA
+	AQAaAAABAQADAAAAAQA3AAABAgADAAAAAwAACgIBAwADAAAAAQAFAAABBgADAAAAAQAC
+	AAABEQAEAAAAAQAAAAgBEgADAAAAAQABAAABFQADAAAAAQADAAABFgADAAAAAQaQAAAB
+	FwAEAAAAAQAACUsBHAADAAAAAQABAAABPQADAAAAAQACAAABUwADAAAAAwAACgiHcwAH
+	AAARIAAACg4AAAAAAAgACAAIAAEAAQABAAARIGFwcGwCAAAAbW50clJHQiBYWVogB9kA
+	BAALABcAOwAaYWNzcEFQUEwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPbWAAEAAAAA
+	0y1hcHBsiXAwVUVs1ORxbm+PhPb1RwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+	AAAOclhZWgAAASwAAAAUZ1hZWgAAAUAAAAAUYlhZWgAAAVQAAAAUd3RwdAAAAWgAAAAU
+	Y2hhZAAAAXwAAAAsclRSQwAAAagAAAAOZ1RSQwAAAbgAAAAOYlRSQwAAAcgAAAAOdmNn
+	dAAAAdgAAAYSbmRpbgAAB+wAAAY+ZGVzYwAADiwAAABkZHNjbQAADpAAAAJCbW1vZAAA
+	ENQAAAAoY3BydAAAEPwAAAAkWFlaIAAAAAAAAGDoAAA4FAAABlJYWVogAAAAAAAAcDYA
+	ALICAAAhG1hZWiAAAAAAAAAltwAAFgQAAKu4WFlaIAAAAAAAAPNSAAEAAAABFs9zZjMy
+	AAAAAAABDEIAAAXe///zJgAAB5IAAP2R///7ov///aMAAAPcAADAbGN1cnYAAAAAAAAA
+	AQHNAABjdXJ2AAAAAAAAAAEBzQAAY3VydgAAAAAAAAABAc0AAHZjZ3QAAAAAAAAAAAAD
+	AQAAAgAAACEAcgDsAYICOwMlBFIFqwc3CPcK+A0TDzQRZhOKFZkXixlgGx8cqB4PH2Mg
+	tSILI2gkySYnJ4so8CpbK78tKS6NL/MxVDKuNAw1XzavOAA5RzqHO788+T4vP2tApEHe
+	QxdETEWHRr9H9kksSl9LkUzCTfJPIFBOUXRSnlPQVR9WdlfHWRlaa1u2XP5eSF+MYM9i
+	EmNUZJZl22cdaGFpqmrzbDxtiG7Mb/FxBXIWcyV0N3VJdlt3bHh8eY96n3uxfMJ91X7o
+	f/qBD4IlgzqEToVdhlaHOYgYiPeJ2Iq7i5yMfo1gjkKPIo//kNqRtZKRk2SUOJUKldmW
+	qJd0mFCZQ5o8mzWcK50dngue9Z/coL6hnaJ3o06kIqTzpb+mi6dVqByo4qmqqnqra6xl
+	rV+uWK9NsECxL7Icswaz7bTTtba2mLd2uFS5MroOuuu7ybylvYC+W78zwAnA4cG0wonD
+	W8QtxQDF08ajx3TIRckWyebKtcuHzFfNKM38zs/Pj9BI0PzRsdJs0ynT59So1WvWMNb3
+	177YhtlP2hba3duk3GrdLt3x3rHfeOBF4Rfh6uK244LkTOUR5dHmj+dI5/3oq+lU6fvq
+	mus369LsZuz67YruJO7P74bwQPD58bTycPMu8+30sPV39kP3E/fo+Mb5qvqS+4L8ef11
+	/nX/UP//AAAAOADDAW4CNgMhBDcFhAbsCHMKHgvXDaoPeRFMExkU1haDGCUZrhslHHAd
+	sB7xIDQhfiLMJBglaSa6KBIpZCq2LAotXC6oL/AxPTJ8M7w0+zYwN1s4dTmOOqU7vzzX
+	Pew/AUAUQStCQUNURGhFekaMR55IsUnFStZL50z6ThNPSFCGUb1S9FQsVWBWjle/WO1a
+	GVtFXHFdm17IX/NhIGJSY4FksWXkZxBoI2kmaiprLGwvbTVuOm8/cEZxTnJXc2J0a3V5
+	dol3l3ipeb560nvmfPN98n7hf8mAsoGcgouDdYRihU6GOYciiAeI6onMiq6LiIxijTiO
+	C47bj6qQfpFzkmSTVZRFlTGWGpcAl+KYwpmemnebTZwhnPKdwJ6On1mgIqDrobaihaN4
+	pG6lZqZcp1CoQakvqhurBKvsrNOtt66br3uwXbE9sh2y/rPftMG1oLaEt2a4RrkmugW6
+	5LvAvJy9eb5WvzLADsDrwcnCpsOExGPFQ8YkxwfH68jJyaXKgMtbzDnNGM33ztnPuNCb
+	0X3SYNNC1CPVBNXk1sXXo9iB2V7aOdsZ3ATc8N3g3sffsOCW4XniWuM75Brk9uXR5qrn
+	g+hb6TPqDOrl673sl+1z7lXvQPAx8S7yMvM49Eb1V/Zm93P4evl5+m37U/wr/PX9pf5G
+	/tn/RP+h//8AAAAkAHwBAgGVAkoDIAQbBSwGWAeWCOEKOQuTDO4OQw+PENESDBMyFEUV
+	QBYwFyAYEhkJGgQa+xv5HPUd9R7zH/Eg8SHuIugj3yTVJcgmuCenKJEpdypXKzgsEizu
+	LcYunC9wMEExETHdMqYzbzQ1NPY1uDZ5Nzk39zi0OXE6MDsAO9I8pT14Pk0/Ij/3QM1B
+	pEJ8Q1VEMUUMRetGykerSI5JcUpUSzlMHUz8TdhOs0+PUGpRSFIkUwFT3lS8VZxWe1db
+	WEBZJVoKWvJb3VzIXbJeml9+YFdhL2IKYuhjyGSqZY5mdGdcaERpKmoQavZr3GzAbaJu
+	hG9gcDxxF3H8cu1z43TWdcZ2s3eaeHt5WnoxewV71XyhfWp+LH7sf6uAaYEigduClYNP
+	hAyEy4WLhkyHDIfNiI+JUYoUitmLoIxqjTWOAY7Pj5+QcZFFkhqS8JPBlISVNpXplp6X
+	U5gLmMaZhJpHmw2b1pyhnXKeRp8bn/OgzqGoooWjZ6RFpRul7Ka6p4uoZKk/qh2q/qvi
+	rMutta6gr4ywd7FhskqzMrQZtP213ra7t6C4r7m/utS74rzyvgC/CsASwRvCIMMjxCPF
+	IcYexxnIE8kNygXK+8vyzPDOOM+T0OvSONOE1NbWL9eN2PTadNwI3bvflOGT47/mP+kX
+	7GbwR/Uz+4T//wAAbmRpbgAAAAAAAAY2AACYZQAAWYUAAFMYAACL2gAAJ5oAABVgAABQ
+	DQAAVDkAAmj1AAIrhQABXCgAAwEAAAIAAAAYADIASgBfAHQAiACcAK4AwgDUAOYA+QEL
+	AR4BMgFGAVoBbwGFAZwBtAHNAegCBAIiAkICYwKJArEC3wMPA0EDdAOoA9wEEQRHBH8E
+	twTwBSoFZAWhBd4GHAZcBp0G3wcjB2oHsQf5CEUIkwjhCTEJhQnbCjUKkQrtC00LqwwM
+	DG4M0g03DZ8OBg5vDtoPRw+1ECYQmBENEYIR+hJ0Eu8TbxPuFHAU6RVbFc4WRRa8FzUX
+	rhgrGKoZKxmsGjEatxs+G8ccURzdHWgd9R6EHxMfoSAwIMEhUiHjInUjFiPGJH0lNSXw
+	JqonZigkKOQppipoKy0r8iy7LYMuTC8XL+QwsDF9Mk0zHzP3NOY18Db8OAo5FTomOzc8
+	Sj1gPnw/nkDFQetDIURWRZZG2kglSVVKY0t6TJBNrk7ST/9RMFJsU7BU/VZRV69ZGVqH
+	W/xdfF76YGthnmLVZA1lSmaNZ9ZpJmp8a9dtOW6gcAtxgHL1dHB17XdqeOx6cnv7fY9/
+	IYC/glqEAIWmh06I/IqtjF+OFY/RkYeTRpT/lrqYpJqynMCevaC7orCko6aQqH6qa6xd
+	rlOwTLJMtFS2aLhmulK8O745wDfCSMRrxprI5ctNzc/QeNM31hvZFtuc3fPgT+Ko5P3n
+	UOmW687t+fAX8h70GfYK9+r5v/uQ/Vn//wAAAA4AIQA1AEkAXABvAIMAlwCrAL8A1ADp
+	AP4BFAErAUMBWwF1AY8BqwHIAecCBwIpAk0CdAKdAswC/gMzA2gDnwPWBA4ERwSCBL0E
+	+gU3BXUFtQX3BjkGfQbCBwoHUwefB+oIOgiMCN4JMwmMCegKTAqyCxsLhQvwDF4Mzw1B
+	DbYOKw6iDxwPlxAVEJURFhGZEh0SoxMsE7cUQRTKFUYVwhZCFsQXRxfLGFIY3RloGfUa
+	hRsWG6kcPRzUHWoeAh6cHzYfzyBrIQghpSJCIugjoSRiJSMl6CasJ3EoOCkBKcoqlCtf
+	LCos+C3ELpAvYDAuMPsxyjKbM240TDU9Nj03PjhBOUA6RjtLPFM9Xj5vP4dAo0HBQuxE
+	GUVRRo9H1kkWSilLSExmTYpOtE/mUR5SXVOkVPNWSFelWQ1aeFvpXWRe3WBQYYZiwWP8
+	ZTtmgWfLaRxqc2vObS5ulG/7cWxy3HRRdcd3Pni2ejR7rH0sfq6ANYG9g06E4IZziAmJ
+	o4s8jNeOc5ASka2TTpTnloKYKZnXm4qdPJ7poJqiSKP8paqnXKkPqsasga4/r/6xxLOM
+	tVy3Lrjiupi8R74Kv8jBkcNkxTnHE8j3yuDM0M7B0LjSrNSk1qHYmdqM3GvePd/94a3j
+	XOUD5qHoQuno65btUO8b8QPzEPVR9+77DP//AAAAFgAwAEoAYwB9AJcAsQDNAOkBBgEk
+	AUQBZQGIAa0B1QH/AiwCXQKTAtEDFQNcA6UD7wQ6BIkE2AUqBX0F0wYrBoUG4gdDB6cI
+	Dgh5COcJWQnQCk4KzgtVC90MbAz/DZgONA7YD4AQLxDkEZ0SXBMfE+gUsxVuFisW6her
+	GG4ZNBn7GsQbjhxYHSUd8R6/H40gXCEvIgEi1yO1JJglfiZmJ04oOikoKhcrByv5LO0t
+	3i7RL8YwuDGrMqAzmTSZNak2vTfPON457jr9PAw9GT4qPz5AVkFtQopDq0TQRf5HLkhk
+	SYRKmku0TNNN+U8oUGJRolLxVElVrVcZWJdaHVuoXUNe3GB5Yg5jpmU8ZtZocWoOa6lt
+	Qm7YcGtx/3OQdR52rHg3ecZ7f31nf0eBKYMChNSGnIhdihiLyY13jyOQx5JwlBOVsZda
+	mRya6JyxnmigHqHNo3ulH6bCqGWqB6uvrVmvB7C6snO0NLYCt8G5NbqyvCW9qL8lwKjC
+	McPBxU/G4sh9yhzLws1pzxfQytJ81DPV8det2W/ayNwL3Unejd/d4TDigePN5RbmXOee
+	6NvqCest7EjtUu5Y703wPPEf8fzyzPOZ9FD1B/Wu9k727vd8+Af4k/kT+Yn6APp3+tz7
+	OfuX+/T8Uvye/OX9Lf10/bz+BP5Y/sL/K/+V//8AAGRlc2MAAAAAAAAACkNvbG9yIExD
+	RAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+	AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABtbHVjAAAAAAAAABIAAAAMbmJOTwAA
+	ABIAAADocHRQVAAAABYAAAD6c3ZTRQAAABAAAAEQZmlGSQAAABAAAAEgZGFESwAAABwA
+	AAEwemhDTgAAAAwAAAFMZnJGUgAAABYAAAFYamFKUAAAAA4AAAFuZW5VUwAAABIAAAF8
+	cGxQTAAAABIAAAGOcHRCUgAAABgAAAGgZXNFUwAAABIAAAG4emhUVwAAAA4AAAHKcnVS
+	VQAAACQAAAHYa29LUgAAAAwAAAH8ZGVERQAAABAAAAIIbmxOTAAAABYAAAIYaXRJVAAA
+	ABQAAAIuAEYAYQByAGcAZQAtAEwAQwBEAEwAQwBEACAAYQAgAEMAbwByAGUAcwBGAOQA
+	cgBnAC0ATABDAEQAVgDkAHIAaQAtAEwAQwBEAEwAQwBEAC0AZgBhAHIAdgBlAHMAawDm
+	AHIAbV9pgnIAIABMAEMARABMAEMARAAgAGMAbwB1AGwAZQB1AHIwqzDpMPwAIABMAEMA
+	RABDAG8AbABvAHIAIABMAEMARABLAG8AbABvAHIAIABMAEMARABMAEMARAAgAEMAbwBs
+	AG8AcgBpAGQAbwBMAEMARAAgAGMAbwBsAG8Acl9pgnJtsmZ2mG95OlZoBCYEMgQ1BEIE
+	PQQ+BDkAIAQWBBoALQQ0BDgEQQQ/BDsENQQ5zuy37AAgAEwAQwBEAEYAYQByAGIALQBM
+	AEMARABLAGwAZQB1AHIAZQBuAC0ATABDAEQATABDAEQAIABjAG8AbABvAHIAaQAAbW1v
+	ZAAAAAAAAAYQAACcgAAAAADDJekAAAAAAAAAAAAAAAAAAAAAAHRleHQAAAAAQ29weXJp
+	Z2h0IEFwcGxlLCBJbmMuLCAyMDA5AA==
+	</data>
+	<key>ReadOnly</key>
+	<string>NO</string>
+	<key>RowAlign</key>
+	<integer>1</integer>
+	<key>RowSpacing</key>
+	<real>36</real>
+	<key>SheetTitle</key>
+	<string>Canvas 1</string>
+	<key>SmartAlignmentGuidesActive</key>
+	<string>YES</string>
+	<key>SmartDistanceGuidesActive</key>
+	<string>YES</string>
+	<key>UniqueID</key>
+	<integer>1</integer>
+	<key>UseEntirePage</key>
+	<false/>
+	<key>VPages</key>
+	<integer>1</integer>
+	<key>WindowInfo</key>
+	<dict>
+		<key>CurrentSheet</key>
+		<integer>0</integer>
+		<key>ExpandedCanvases</key>
+		<array>
+			<dict>
+				<key>name</key>
+				<string>Canvas 1</string>
+			</dict>
+		</array>
+		<key>Frame</key>
+		<string>{{388, 0}, {710, 878}}</string>
+		<key>ListView</key>
+		<true/>
+		<key>OutlineWidth</key>
+		<integer>142</integer>
+		<key>RightSidebar</key>
+		<false/>
+		<key>ShowRuler</key>
+		<true/>
+		<key>Sidebar</key>
+		<true/>
+		<key>SidebarWidth</key>
+		<integer>120</integer>
+		<key>VisibleRegion</key>
+		<string>{{0, 0}, {561, 709}}</string>
+		<key>Zoom</key>
+		<real>1</real>
+		<key>ZoomValues</key>
+		<array>
+			<array>
+				<string>Canvas 1</string>
+				<real>1</real>
+				<real>1</real>
+			</array>
+		</array>
+	</dict>
+	<key>saveQuickLookFiles</key>
+	<string>YES</string>
+</dict>
+</plist>
diff --git a/docs/PCHLayout.png b/docs/PCHLayout.png
new file mode 100644
index 0000000..c304e04
--- /dev/null
+++ b/docs/PCHLayout.png
Binary files differ
diff --git a/docs/PTHInternals.html b/docs/PTHInternals.html
new file mode 100644
index 0000000..279d479
--- /dev/null
+++ b/docs/PTHInternals.html
@@ -0,0 +1,177 @@
+<html>
+  <head>
+  <title>Pretokenized Headers (PTH)</title>
+  <link type="text/css" rel="stylesheet" href="../menu.css" />
+  <link type="text/css" rel="stylesheet" href="../content.css" />
+  <style type="text/css">
+    td {
+    vertical-align: top;
+    }
+  </style>
+</head>
+<body>
+
+<!--#include virtual="../menu.html.incl"-->
+
+<div id="content">
+
+<h1>Pretokenized Headers (PTH)</h1>
+
+<p>This document first describes the low-level
+interface for using PTH and then briefly elaborates on its design and
+implementation.  If you are interested in the end-user view, please see the
+<a href="UsersManual.html#precompiledheaders">User's Manual</a>.</p>
+
+
+<h2>Using Pretokenized Headers with <tt>clang</tt> (Low-level Interface)</h2>
+
+<p>The Clang compiler frontend, <tt>clang -cc1</tt>, supports three command line
+options for generating and using PTH files.<p>
+
+<p>To generate PTH files using <tt>clang -cc1</tt>, use the option
+<b><tt>-emit-pth</tt></b>:
+
+<pre> $ clang -cc1 test.h -emit-pth -o test.h.pth </pre>
+
+<p>This option is transparently used by <tt>clang</tt> when generating PTH
+files. Similarly, PTH files can be used as prefix headers using the
+<b><tt>-include-pth</tt></b> option:</p>
+
+<pre>
+  $ clang -cc1 -include-pth test.h.pth test.c -o test.s
+</pre>
+
+<p>Alternatively, Clang's PTH files can be used as a raw &quot;token-cache&quot;
+(or &quot;content&quot; cache) of the source included by the original header
+file. This means that the contents of the PTH file are searched as substitutes
+for <em>any</em> source files that are used by <tt>clang -cc1</tt> to process a
+source file. This is done by specifying the <b><tt>-token-cache</tt></b>
+option:</p>
+
+<pre>
+  $ cat test.h
+  #include &lt;stdio.h&gt;
+  $ clang -cc1 -emit-pth test.h -o test.h.pth
+  $ cat test.c
+  #include "test.h"
+  $ clang -cc1 test.c -o test -token-cache test.h.pth
+</pre>
+
+<p>In this example the contents of <tt>stdio.h</tt> (and the files it includes)
+will be retrieved from <tt>test.h.pth</tt>, as the PTH file is being used in
+this case as a raw cache of the contents of <tt>test.h</tt>. This is a low-level
+interface used to both implement the high-level PTH interface as well as to
+provide alternative means to use PTH-style caching.</p>
+
+<h2>PTH Design and Implementation</h2>
+
+<p>Unlike GCC's precompiled headers, which cache the full ASTs and preprocessor
+state of a header file, Clang's pretokenized header files mainly cache the raw
+lexer <em>tokens</em> that are needed to segment the stream of characters in a
+source file into keywords, identifiers, and operators. Consequently, PTH serves
+to mainly directly speed up the lexing and preprocessing of a source file, while
+parsing and type-checking must be completely redone every time a PTH file is
+used.</p>
+
+<h3>Basic Design Tradeoffs</h3>
+
+<p>In the long term there are plans to provide an alternate PCH implementation
+for Clang that also caches the work for parsing and type checking the contents
+of header files. The current implementation of PCH in Clang as pretokenized
+header files was motivated by the following factors:<p>
+
+<ul>
+
+<li><p><b>Language independence</b>: PTH files work with any language that
+Clang's lexer can handle, including C, Objective-C, and (in the early stages)
+C++. This means development on language features at the parsing level or above
+(which is basically almost all interesting pieces) does not require PTH to be
+modified.</p></li>
+
+<li><b>Simple design</b>: Relatively speaking, PTH has a simple design and
+implementation, making it easy to test. Further, because the machinery for PTH
+resides at the lower-levels of the Clang library stack it is fairly
+straightforward to profile and optimize.</li>
+</ul>
+
+<p>Further, compared to GCC's PCH implementation (which is the dominate
+precompiled header file implementation that Clang can be directly compared
+against) the PTH design in Clang yields several attractive features:</p>
+
+<ul>
+
+<li><p><b>Architecture independence</b>: In contrast to GCC's PCH files (and
+those of several other compilers), Clang's PTH files are architecture
+independent, requiring only a single PTH file when building an program for
+multiple architectures.</p>
+
+<p>For example, on Mac OS X one may wish to
+compile a &quot;universal binary&quot; that runs on PowerPC, 32-bit Intel
+(i386), and 64-bit Intel architectures. In contrast, GCC requires a PCH file for
+each architecture, as the definitions of types in the AST are
+architecture-specific. Since a Clang PTH file essentially represents a lexical
+cache of header files, a single PTH file can be safely used when compiling for
+multiple architectures. This can also reduce compile times because only a single
+PTH file needs to be generated during a build instead of several.</p></li>
+
+<li><p><b>Reduced memory pressure</b>: Similar to GCC,
+Clang reads PTH files via the use of memory mapping (i.e., <tt>mmap</tt>).
+Clang, however, memory maps PTH files as read-only, meaning that multiple
+invocations of <tt>clang -cc1</tt> can share the same pages in memory from a
+memory-mapped PTH file. In comparison, GCC also memory maps its PCH files but
+also modifies those pages in memory, incurring the copy-on-write costs. The
+read-only nature of PTH can greatly reduce memory pressure for builds involving
+multiple cores, thus improving overall scalability.</p></li>
+
+<li><p><b>Fast generation</b>: PTH files can be generated in a small fraction
+of the time needed to generate GCC's PCH files. Since PTH/PCH generation is a
+serial operation that typically blocks progress during a build, faster
+generation time leads to improved processor utilization with parallel builds on
+multicore machines.</p></li>
+
+</ul>
+
+<p>Despite these strengths, PTH's simple design suffers some algorithmic
+handicaps compared to other PCH strategies such as those used by GCC. While PTH
+can greatly speed up the processing time of a header file, the amount of work
+required to process a header file is still roughly linear in the size of the
+header file. In contrast, the amount of work done by GCC to process a
+precompiled header is (theoretically) constant (the ASTs for the header are
+literally memory mapped into the compiler). This means that only the pieces of
+the header file that are referenced by the source file including the header are
+the only ones the compiler needs to process during actual compilation. While
+GCC's particular implementation of PCH mitigates some of these algorithmic
+strengths via the use of copy-on-write pages, the approach itself can
+fundamentally dominate at an algorithmic level, especially when one considers
+header files of arbitrary size.</p>
+
+<p>There are plans to potentially implement an complementary PCH implementation
+for Clang based on the lazy deserialization of ASTs. This approach would
+theoretically have the same constant-time algorithmic advantages just mentioned
+but would also retain some of the strengths of PTH such as reduced memory
+pressure (ideal for multi-core builds).</p>
+
+<h3>Internal PTH Optimizations</h3>
+
+<p>While the main optimization employed by PTH is to reduce lexing time of
+header files by caching pre-lexed tokens, PTH also employs several other
+optimizations to speed up the processing of header files:</p>
+
+<ul>
+
+<li><p><em><tt>stat</tt> caching</em>: PTH files cache information obtained via
+calls to <tt>stat</tt> that <tt>clang -cc1</tt> uses to resolve which files are
+included by <tt>#include</tt> directives. This greatly reduces the overhead
+involved in context-switching to the kernel to resolve included files.</p></li>
+
+<li><p><em>Fasting skipping of <tt>#ifdef</tt>...<tt>#endif</tt> chains</em>:
+PTH files record the basic structure of nested preprocessor blocks. When the
+condition of the preprocessor block is false, all of its tokens are immediately
+skipped instead of requiring them to be handled by Clang's
+preprocessor.</p></li>
+
+</ul>
+
+</div>
+</body>
+</html>
diff --git a/docs/UsersManual.html b/docs/UsersManual.html
new file mode 100644
index 0000000..7d7f263
--- /dev/null
+++ b/docs/UsersManual.html
@@ -0,0 +1,876 @@
+<html>
+<head>
+<title>Clang Compiler User's Manual</title>
+<link type="text/css" rel="stylesheet" href="../menu.css" />
+<link type="text/css" rel="stylesheet" href="../content.css" />
+<style type="text/css">
+td {
+	vertical-align: top;
+}
+</style>
+</head>
+<body>
+
+<!--#include virtual="../menu.html.incl"-->
+
+<div id="content">
+
+<h1>Clang Compiler User's Manual</h1>
+
+<ul>
+<li><a href="#intro">Introduction</a>
+  <ul>
+  <li><a href="#terminology">Terminology</a></li>
+  <li><a href="#basicusage">Basic Usage</a></li>
+  </ul>
+</li>
+<li><a href="#commandline">Command Line Options</a>
+  <ul>
+  <li><a href="#cl_diagnostics">Options to Control Error and Warning
+      Messages</a></li>
+  </ul>
+</li>
+<li><a href="#general_features">Language and Target-Independent Features</a>
+ <ul>
+  <li><a href="#diagnostics">Controlling Errors and Warnings</a></li>
+   <ul>
+   <li><a href="#diagnostics_display">Controlling How Clang Displays Diagnostics</a></li>
+   <li><a href="#diagnostics_mappings">Diagnostic Mappings</a></li>
+   <li><a href="#diagnostics_commandline">Controlling Diagnostics via Command Line Flags</a></li>
+   <li><a href="#diagnostics_pragmas">Controlling Diagnostics via Pragmas</a></li>
+   </ul>
+  <li><a href="#precompiledheaders">Precompiled Headers</a></li>
+  <li><a href="#codegen">Controlling Code Generation</a></li>
+  </ul>
+</li>
+<li><a href="#c">C Language Features</a>
+  <ul>
+  <li><a href="#c_ext">Extensions supported by clang</a></li>
+  <li><a href="#c_modes">Differences between various standard modes</a></li>
+  <li><a href="#c_unimpl_gcc">GCC extensions not implemented yet</a></li>
+  <li><a href="#c_unsupp_gcc">Intentionally unsupported GCC extensions</a></li>
+  <li><a href="#c_ms">Microsoft extensions</a></li>
+  </ul>
+</li>
+<li><a href="#objc">Objective-C Language Features</a>
+  <ul>
+  <li><a href="#objc_incompatibilities">Intentional Incompatibilities with
+      GCC</a></li>
+  </ul>
+</li>
+<li><a href="#cxx">C++ Language Features</a>
+</li>
+<li><a href="#objcxx">Objective C++ Language Features</a>
+</li>
+<li><a href="#target_features">Target-Specific Features and Limitations</a>
+  <ul>
+  <li><a href="#target_arch">CPU Architectures Features and Limitations</a>
+    <ul>
+    <li><a href="#target_arch_x86">X86</a></li>
+    <li><a href="#target_arch_arm">ARM</a></li>
+    <li><a href="#target_arch_other">Other platforms</a></li>
+    </ul>
+  </li>
+  <li><a href="#target_os">Operating System Features and Limitations</a>
+    <ul>
+    <li><a href="#target_os_darwin">Darwin (Mac OS/X)</a></li>
+    <li>Linux, etc.</li>
+    </ul>
+  
+  </li>
+  </ul>
+</li>
+</ul>
+
+
+<!-- ======================================================================= -->
+<h2 id="intro">Introduction</h2>
+<!-- ======================================================================= -->
+
+<p>The Clang Compiler is an open-source compiler for the C family of programming
+languages, aiming to be the best in class implementation of these languages.
+Clang builds on the LLVM optimizer and code generator, allowing it to provide
+high-quality optimization and code generation support for many targets.  For
+more general information, please see the <a href="http://clang.llvm.org">Clang
+Web Site</a> or the <a href="http://llvm.org">LLVM Web Site</a>.</p>
+
+<p>This document describes important notes about using Clang as a compiler for
+an end-user, documenting the supported features, command line options, etc.  If
+you are interested in using Clang to build a tool that processes code, please
+see <a href="InternalsManual.html">the Clang Internals Manual</a>.  If you are
+interested in the <a href="http://clang.llvm.org/StaticAnalysis.html">Clang
+Static Analyzer</a>, please see its web page.</p>
+
+<p>Clang is designed to support the C family of programming languages, which
+includes <a href="#c">C</a>, <a href="#objc">Objective-C</a>, <a
+href="#cxx">C++</a>, and <a href="#objcxx">Objective-C++</a> as well as many
+dialects of those.  For language-specific information, please see the
+corresponding language specific section:</p>
+
+<ul>
+<li><a href="#c">C Language</a>: K&amp;R C, ANSI C89, ISO C90, ISO C94
+    (C89+AMD1), ISO C99 (+TC1, TC2, TC3). </li>
+<li><a href="#objc">Objective-C Language</a>: ObjC 1, ObjC 2, ObjC 2.1, plus
+    variants depending on base language.</li>
+<li><a href="#cxx">C++ Language Features</a></li>
+<li><a href="#objcxx">Objective C++ Language</a></li>
+</ul>
+
+<p>In addition to these base languages and their dialects, Clang supports a
+broad variety of language extensions, which are documented in the corresponding
+language section.  These extensions are provided to be compatible with the GCC,
+Microsoft, and other popular compilers as well as to improve functionality
+through Clang-specific features.  The Clang driver and language features are
+intentionally designed to be as compatible with the GNU GCC compiler as
+reasonably possible, easing migration from GCC to Clang.  In most cases, code
+"just works".</p>
+
+<p>In addition to language specific features, Clang has a variety of features
+that depend on what CPU architecture or operating system is being compiled for.
+Please see the <a href="#target_features">Target-Specific Features and
+Limitations</a> section for more details.</p>
+
+<p>The rest of the introduction introduces some basic <a
+href="#terminology">compiler terminology</a> that is used throughout this manual
+and contains a basic <a href="#basicusage">introduction to using Clang</a>
+as a command line compiler.</p>
+
+<!-- = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = -->
+<h3 id="terminology">Terminology</h3>
+<!-- = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = -->
+
+<p>Front end, parser, backend, preprocessor, undefined behavior, diagnostic,
+ optimizer</p>
+
+<!-- = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = -->
+<h3 id="basicusage">Basic Usage</h3>
+<!-- = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = -->
+
+<p>Intro to how to use a C compiler for newbies.</p>
+<p>
+compile + link
+
+compile then link
+
+debug info
+
+enabling optimizations
+
+picking a language to use, defaults to C99 by default.  Autosenses based on
+extension.
+
+using a makefile
+</p>
+
+
+<!-- ======================================================================= -->
+<h2 id="commandline">Command Line Options</h2>
+<!-- ======================================================================= -->
+
+<p>
+This section is generally an index into other sections.  It does not go into
+depth on the ones that are covered by other sections.  However, the first part
+introduces the language selection and other high level options like -c, -g, etc.
+</p>
+
+
+<!-- = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = -->
+<h3 id="cl_diagnostics">Options to Control Error and Warning Messages</h3>
+<!-- = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = -->
+
+<p><b>-Werror</b>: Turn warnings into errors.</p>
+<p><b>-Werror=foo</b>: Turn warning "foo" into an error.</p>
+<p><b>-Wno-error=foo</b>: Turn warning "foo" into an warning even if -Werror is
+   specified.</p>
+<p><b>-Wfoo</b>: Enable warning foo</p>
+<p><b>-Wno-foo</b>: Disable warning foo</p>
+<p><b>-w</b>: Disable all warnings.</p>
+<p><b>-pedantic</b>: Warn on language extensions.</p>
+<p><b>-pedantic-errors</b>: Error on language extensions.</p>
+<p><b>-Wsystem-headers</b>: Enable warnings from system headers.</p>
+
+<p><b>-ferror-limit=123</b>: Stop emitting diagnostics after 123 errors have
+   been produced.  The default is 20, and the error limit can be disabled with
+   -ferror-limit=0.</p>
+
+<p><b>-ftemplate-backtrace-limit=123</b>: Only emit up to 123 template instantiation notes within the template instantiation backtrace for a single warning or error. The default is 10, and the limit can be disabled with -ftemplate-backtrace-limit=0.</p>
+
+<!-- ================================================= -->
+<h4 id="cl_diag_formatting">Formatting of Diagnostics</h4>
+<!-- ================================================= -->
+
+<p>Clang aims to produce beautiful diagnostics by default, particularly for new
+users that first come to Clang.  However, different people have different
+preferences, and sometimes Clang is driven by another program that wants to
+parse simple and consistent output, not a person. For these cases, Clang
+provides a wide range of options to control the exact output format of the
+diagnostics that it generates.</p>
+
+<dl>
+
+<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+<dt id="opt_fshow-column"><b>-f[no-]show-column</b>: Print column number in
+diagnostic.</dt>
+<dd>This option, which defaults to on, controls whether or not Clang prints the
+column number of a diagnostic.  For example, when this is enabled, Clang will
+print something like:</p>
+
+<pre>
+  test.c:28:8: warning: extra tokens at end of #endif directive [-Wextra-tokens]
+  #endif bad
+         ^
+         //
+</pre>
+
+<p>When this is disabled, Clang will print "test.c:28: warning..." with no
+column number.</p>
+</dd>
+
+<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+<dt id="opt_fshow-source-location"><b>-f[no-]show-source-location</b>: Print
+source file/line/column information in diagnostic.</dt>
+<dd>This option, which defaults to on, controls whether or not Clang prints the
+filename, line number and column number of a diagnostic.  For example,
+when this is enabled, Clang will print something like:</p>
+
+<pre>
+  test.c:28:8: warning: extra tokens at end of #endif directive [-Wextra-tokens]
+  #endif bad
+         ^
+         //
+</pre>
+
+<p>When this is disabled, Clang will not print the "test.c:28:8: " part.</p>
+</dd>
+
+<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+<dt id="opt_fcaret-diagnostics"><b>-f[no-]caret-diagnostics</b>: Print source
+line and ranges from source code in diagnostic.</dt>
+<dd>This option, which defaults to on, controls whether or not Clang prints the
+source line, source ranges, and caret when emitting a diagnostic.  For example,
+when this is enabled, Clang will print something like:</p>
+
+<pre>
+  test.c:28:8: warning: extra tokens at end of #endif directive [-Wextra-tokens]
+  #endif bad
+         ^
+         //
+</pre>
+
+<p>When this is disabled, Clang will just print:</p>
+
+<pre>
+  test.c:28:8: warning: extra tokens at end of #endif directive [-Wextra-tokens]
+</pre>
+
+</dd>
+
+<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+<dt id="opt_fdiagnostics-show-option"><b>-f[no-]diagnostics-show-option</b>:
+Enable <tt>[-Woption]</tt> information in diagnostic line.</dt>
+<dd>This option, which defaults to on,
+controls whether or not Clang prints the associated <A
+href="#cl_diag_warning_groups">warning group</a> option name when outputting
+a warning diagnostic.  For example, in this output:</p>
+
+<pre>
+  test.c:28:8: warning: extra tokens at end of #endif directive [-Wextra-tokens]
+  #endif bad
+         ^
+         //
+</pre>
+
+<p>Passing <b>-fno-diagnostics-show-option</b> will prevent Clang from printing
+the [<a href="#opt_Wextra-tokens">-Wextra-tokens</a>] information in the
+diagnostic.  This information tells you the flag needed to enable or disable the
+diagnostic, either from the command line or through <a 
+href="#pragma_GCC_diagnostic">#pragma GCC diagnostic</a>.</dd>
+
+
+<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+<dt id="opt_fdiagnostics-fixit-info"><b>-f[no-]diagnostics-fixit-info</b>:
+Enable "FixIt" information in the diagnostics output.</dt>
+<dd>This option, which defaults to on, controls whether or not Clang prints the
+information on how to fix a specific diagnostic underneath it when it knows.
+For example, in this output:</p>
+
+<pre>
+  test.c:28:8: warning: extra tokens at end of #endif directive [-Wextra-tokens]
+  #endif bad
+         ^
+         //
+</pre>
+
+<p>Passing <b>-fno-diagnostics-fixit-info</b> will prevent Clang from printing
+the "//" line at the end of the message.  This information is useful for users
+who may not understand what is wrong, but can be confusing for machine
+parsing.</p>
+</dd>
+
+<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+<dt id="opt_fdiagnostics-print-source-range-info">
+<b>-f[no-]diagnostics-print-source-range-info</b>:
+Print machine parsable information about source ranges.</dt>
+<dd>This option, which defaults to off, controls whether or not Clang prints
+information about source ranges in a machine parsable format after the
+file/line/column number information.  The information is a simple sequence of
+brace enclosed ranges, where each range lists the start and end line/column
+locations.  For example, in this output:</p>
+
+<pre>
+exprs.c:47:15:{47:8-47:14}{47:17-47:24}: error: invalid operands to binary expression ('int *' and '_Complex float')
+   P = (P-42) + Gamma*4;
+       ~~~~~~ ^ ~~~~~~~
+</pre>
+
+<p>The {}'s are generated by -fdiagnostics-print-source-range-info.</p>
+</dd>
+
+
+</dl>
+
+ 
+
+
+<!-- ===================================================== -->
+<h4 id="cl_diag_warning_groups">Individual Warning Groups</h4>
+<!-- ===================================================== -->
+
+<p>TODO: Generate this from tblgen.  Define one anchor per warning group.</p>
+
+
+<dl>
+
+
+<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+<dt id="opt_Wextra-tokens"><b>-Wextra-tokens</b>: Warn about excess tokens at
+    the end of a preprocessor directive.</dt>
+<dd>This option, which defaults to on, enables warnings about extra tokens at
+the end of preprocessor directives.  For example:</p>
+
+<pre>
+  test.c:28:8: warning: extra tokens at end of #endif directive [-Wextra-tokens]
+  #endif bad
+         ^
+</pre>
+
+<p>These extra tokens are not strictly conforming, and are usually best handled
+by commenting them out.</p>
+
+<p>This option is also enabled by <a href="">-Wfoo</a>, <a href="">-Wbar</a>,
+ and <a href="">-Wbaz</a>.</p>
+</dd>
+
+</dl>
+
+<!-- ======================================================================= -->
+<h2 id="general_features">Language and Target-Independent Features</h2>
+<!-- ======================================================================= -->
+
+
+<!-- = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = -->
+<h3 id="diagnostics">Controlling Errors and Warnings</h3>
+<!-- = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = -->
+
+<p>Clang provides a number of ways to control which code constructs cause it to
+emit errors and warning messages, and how they are displayed to the console.</p>
+
+<h4 id="diagnostics_display">Controlling How Clang Displays Diagnostics</h4>
+
+<p>When Clang emits a diagnostic, it includes rich information in the output,
+and gives you fine-grain control over which information is printed.  Clang has
+the ability to print this information, and these are the options that control
+it:</p>
+
+<p>
+<ol>
+<li>A file/line/column indicator that shows exactly where the diagnostic occurs
+    in your code [<a href="#opt_fshow-column">-fshow-column</a>, <a
+    href="#opt_fshow-source-location">-fshow-source-location</a>].</li>
+<li>A categorization of the diagnostic as a note, warning, error, or fatal
+    error.</li>
+<li>A text string that describes what the problem is.</li>
+<li>An option that indicates how to control the diagnostic (for diagnostics that
+    support it) [<a 
+   href="#opt_fdiagnostics-show-option">-fdiagnostics-show-option</a>].</li>
+<li>The line of source code that the issue occurs on, along with a caret and
+    ranges that indicate the important locations [<a
+    href="opt_fcaret-diagnostics">-fcaret-diagnostics</a>].</li>
+<li>"FixIt" information, which is a concise explanation of how to fix the
+    problem (when Clang is certain it knows) [<a
+    href="opt_fdiagnostics-fixit-info">-fdiagnostics-fixit-info</a>].</li>
+<li>A machine-parsable representation of the ranges involved (off by
+    default) [<a
+      href="opt_fdiagnostics-print-source-range-info">-fdiagnostics-print-source-range-info</a>].</li>
+</ol></p>
+
+<p>For more information please see <a href="#cl_diag_formatting">Formatting of
+Diagnostics</a>.</p>
+
+<h4 id="diagnostics_mappings">Diagnostic Mappings</h4>
+
+<p>All diagnostics are mapped into one of these 5 classes:</p>
+
+<p>
+<ul>
+<li>Ignored</li>
+<li>Note</li>
+<li>Warning</li>
+<li>Error</li>
+<li>Fatal</li>
+</ul></p>
+
+<h4 id="diagnostics_commandline">Controlling Diagnostics via Command Line Flags</h4>
+
+<p>-W flags, -pedantic, etc</p>
+
+<h4 id="diagnostics_pragmas">Controlling Diagnostics via Pragmas</h4>
+
+<p>Clang can also control what diagnostics are enabled through the use of
+pragmas in the source code. This is useful for turning off specific warnings
+in a section of source code. Clang supports GCC's pragma for compatibility
+with existing source code, as well as several extensions. </p>
+
+<p>The pragma may control any warning that can be used from the command line.
+Warnings may be set to ignored, warning, error, or fatal. The following 
+example code will tell Clang or GCC to ignore the -Wall warnings:</p>
+
+<pre>
+#pragma GCC diagnostic ignored "-Wall"
+</pre>
+
+<p>In addition to all of the functionality of provided by GCC's pragma, Clang 
+also allows you to push and pop the current warning state.  This is particularly
+useful when writing a header file that will be compiled by other people, because 
+you don't know what warning flags they build with.</p>
+
+<p>In the below example
+-Wmultichar is ignored for only a single line of code, after which the
+diagnostics return to whatever state had previously existed.</p>
+
+<pre>
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wmultichar"
+
+char b = 'df'; // no warning.
+
+#pragma clang diagnostic pop
+</pre>
+
+<p>The push and pop pragmas will save and restore the full diagnostic state of
+the compiler, regardless of how it was set. That means that it is possible to
+use push and pop around GCC compatible diagnostics and Clang will push and pop
+them appropriately, while GCC will ignore the pushes and pops as unknown 
+pragmas. It should be noted that while Clang supports the GCC pragma, Clang and
+GCC do not support the exact same set of warnings, so even when using GCC
+compatible #pragmas there is no guarantee that they will have identical behaviour
+on both compilers. </p>
+
+<!-- = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = -->
+<h3 id="precompiledheaders">Precompiled Headers</h3>
+<!-- = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = -->
+
+<p><a href="http://en.wikipedia.org/wiki/Precompiled_header">Precompiled
+headers</a> are a general approach employed by many compilers to reduce
+compilation time. The underlying motivation of the approach is that it is
+common for the same (and often large) header files to be included by
+multiple source files. Consequently, compile times can often be greatly improved
+by caching some of the (redundant) work done by a compiler to process headers.
+Precompiled header files, which represent one of many ways to implement
+this optimization, are literally files that represent an on-disk cache that
+contains the vital information necessary to reduce some of the work
+needed to process a corresponding header file. While details of precompiled
+headers vary between compilers, precompiled headers have been shown to be a
+highly effective at speeding up program compilation on systems with very large
+system headers (e.g., Mac OS/X).</p>
+
+<h4>Generating a PCH File</h4>
+
+<p>To generate a PCH file using Clang, one invokes Clang with
+the <b><tt>-x <i>&lt;language&gt;</i>-header</tt></b> option. This mirrors the
+interface in GCC for generating PCH files:</p>
+
+<pre>
+  $ gcc -x c-header test.h -o test.h.gch
+  $ clang -x c-header test.h -o test.h.pch
+</pre>
+
+<h4>Using a PCH File</h4>
+
+<p>A PCH file can then be used as a prefix header when a
+<b><tt>-include</tt></b> option is passed to <tt>clang</tt>:</p>
+
+<pre>
+  $ clang -include test.h test.c -o test
+</pre>
+
+<p>The <tt>clang</tt> driver will first check if a PCH file for <tt>test.h</tt>
+is available; if so, the contents of <tt>test.h</tt> (and the files it includes)
+will be processed from the PCH file. Otherwise, Clang falls back to
+directly processing the content of <tt>test.h</tt>. This mirrors the behavior of
+GCC.</p>
+
+<p><b>NOTE:</b> Clang does <em>not</em> automatically use PCH files
+for headers that are directly included within a source file. For example:</p>
+
+<pre>
+  $ clang -x c-header test.h -o test.h.pch
+  $ cat test.c
+  #include "test.h"
+  $ clang test.c -o test
+</pre>
+
+<p>In this example, <tt>clang</tt> will not automatically use the PCH file for
+<tt>test.h</tt> since <tt>test.h</tt> was included directly in the source file
+and not specified on the command line using <tt>-include</tt>.</p>
+
+<h4>Relocatable PCH Files</h4>
+<p>It is sometimes necessary to build a precompiled header from headers that
+are not yet in their final, installed locations. For example, one might build a
+precompiled header within the build tree that is then meant to be installed
+alongside the headers. Clang permits the creation of "relocatable" precompiled
+headers, which are built with a given path (into the build directory) and can 
+later be used from an installed location.</p>
+
+<p>To build a relocatable precompiled header, place your headers into a
+subdirectory whose structure mimics the installed location. For example, if you
+want to build a precompiled header for the header <code>mylib.h</code> that
+will be installed into <code>/usr/include</code>, create a subdirectory 
+<code>build/usr/include</code> and place the header <code>mylib.h</code> into
+that subdirectory. If <code>mylib.h</code> depends on other headers, then 
+they can be stored within <code>build/usr/include</code> in a way that mimics
+the installed location.</p>
+
+<p>Building a relocatable precompiled header requires two additional arguments.
+First, pass the <code>--relocatable-pch</code> flag to indicate that the
+resulting PCH file should be relocatable. Second, pass 
+<code>-isysroot /path/to/build</code>, which makes all includes for your
+library relative to the build directory. For example:</p>
+
+<pre>
+  # clang -x c-header --relocatable-pch -isysroot /path/to/build /path/to/build/mylib.h mylib.h.pch
+</pre>
+
+<p>When loading the relocatable PCH file, the various headers used in the PCH
+file are found from the system header root. For example, <code>mylib.h</code>
+can be found in <code>/usr/include/mylib.h</code>. If the headers are installed
+in some other system root, the <code>-isysroot</code> option can be used provide
+a different system root from which the headers will be based. For example,
+<code>-isysroot /Developer/SDKs/MacOSX10.4u.sdk</code> will look for 
+<code>mylib.h</code> in 
+<code>/Developer/SDKs/MacOSX10.4u.sdk/usr/include/mylib.h</code>.</p>
+
+<p>Relocatable precompiled headers are intended to be used in a limited number
+of cases where the compilation environment is tightly controlled and the
+precompiled header cannot be generated after headers have been installed. 
+Relocatable precompiled headers also have some performance impact, because
+the difference in location between the header locations at PCH build time vs. 
+at the time of PCH use requires one of the PCH optimizations,
+<code>stat()</code> caching, to be disabled. However, this change is only 
+likely to affect PCH files that reference a large number of headers.</p>
+
+<!-- = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = -->
+<h3 id="codegen">Controlling Code Generation</h3>
+<!-- = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = -->
+
+<p>Clang provides a number of ways to control code generation.  The options are listed below.</p>
+
+<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+<dt id="opt_fcatch-undefined-behavior"><b>-fcatch-undefined-behavior</b>: Turn
+on runtime code generation to check for undefined behavior.</dt>
+
+<dd>This option, which defaults to off, controls whether or not Clang
+adds runtime checks for undefined runtime behavior.  If the check fails,
+<tt>__builtin_trap()</tt> is used to indicate failure.
+The checks are:
+<p>
+<li>Subscripting where the static type of one operand is variable
+    which is decayed from an array type and the other operand is
+    greater than the size of the array or less than zero.</li>
+<li>Shift operators where the amount shifted is greater or equal to the
+    promoted bit-width of the left-hand-side or less than zero.</li>
+<li>If control flow reaches __builtin_unreachable.
+<li>When llvm implements more __builtin_object_size support, reads and
+    writes for objects that __builtin_object_size indicates we aren't
+    accessing valid memory.  Bit-fields and vectors are not yet checked.
+</p>
+</dd>
+
+<dt id="opt_fno-assume-sane-operator-new"><b>-fno-assume-sane-operator-new</b>:
+Don't assume that the C++'s new operator is sane.</dt>
+<dd>This option tells the compiler to do not assume that C++'s global new
+operator will always return a pointer that do not
+alias any other pointer when the function returns.</dd>
+
+<!-- ======================================================================= -->
+<h2 id="c">C Language Features</h2>
+<!-- ======================================================================= -->
+
+<p>The support for standard C in clang is feature-complete except for the C99
+floating-point pragmas.</p>
+
+<!-- = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = -->
+<h3 id="c_ext">Extensions supported by clang</h3>
+<!-- = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = -->
+
+<p>See <a href="LanguageExtensions.html">clang language extensions</a>.</p>
+
+<!-- = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = -->
+<h3 id="c_modes">Differences between various standard modes</h3>
+<!-- = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = -->
+
+<p>clang supports the -std option, which changes what language mode clang uses.
+The supported modes for C are c89, gnu89, c94, c99, gnu99 and various aliases
+for those modes.  If no -std option is specified, clang defaults to gnu99 mode.
+</p>
+
+<p>Differences between all c* and gnu* modes:</p>
+<ul>
+<li>c* modes define "__STRICT_ANSI__".</li>
+<li>Target-specific defines not prefixed by underscores, like "linux", are
+defined in gnu* modes.</li>
+<li>Trigraphs default to being off in gnu* modes; they can be enabled by the
+-trigraphs option.</li>
+<li>The parser recognizes "asm" and "typeof" as keywords in gnu* modes; the
+variants "__asm__" and "__typeof__" are recognized in all modes.</li>
+<li>The Apple "blocks" extension is recognized by default in gnu* modes
+on some platforms; it can be enabled in any mode with the "-fblocks"
+option.</li>
+</ul>
+
+<p>Differences between *89 and *99 modes:</p>
+<ul>
+<li>The *99 modes default to implementing "inline" as specified in C99, while
+the *89 modes implement the GNU version.  This can be overridden for individual
+functions with the __gnu_inline__ attribute.</li>
+<li>Digraphs are not recognized in c89 mode.</li>
+<li>The scope of names defined inside a "for", "if", "switch", "while", or "do"
+statement is different. (example: "if ((struct x {int x;}*)0) {}".)</li>
+<li>__STDC_VERSION__ is not defined in *89 modes.</li>
+<li>"inline" is not recognized as a keyword in c89 mode.</li>
+<li>"restrict" is not recognized as a keyword in *89 modes.</li>
+<li>Commas are allowed in integer constant expressions in *99 modes.</li>
+<li>Arrays which are not lvalues are not implicitly promoted to pointers in
+*89 modes.</li>
+<li>Some warnings are different.</li>
+</ul>
+
+<p>c94 mode is identical to c89 mode except that digraphs are enabled in
+c94 mode (FIXME: And __STDC_VERSION__ should be defined!).</p>
+
+<!-- = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = -->
+<h3 id="c_unimpl_gcc">GCC extensions not implemented yet</h3>
+<!-- = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = -->
+
+<p>clang tries to be compatible with gcc as much as possible, but some gcc
+extensions are not implemented yet:</p>
+
+<ul>
+<li>clang does not support __label__
+(<a href="http://llvm.org/bugs/show_bug.cgi?id=3429">bug 3429</a>). This is
+a relatively small feature, so it is likely to be implemented relatively
+soon.</li>
+
+<li>clang does not support attributes on function pointers
+(<a href="http://llvm.org/bugs/show_bug.cgi?id=2461">bug 2461</a>). This is
+a relatively important feature, so it is likely to be implemented relatively
+soon.</li>
+
+<li>clang does not support #pragma weak
+(<a href="http://llvm.org/bugs/show_bug.cgi?id=3679">bug 3679</a>). Due to
+the uses described in the bug, this is likely to be implemented at some
+point, at least partially.</li>
+
+<li>clang does not support #pragma align
+(<a href="http://llvm.org/bugs/show_bug.cgi?id=3811">bug 3811</a>). This is a
+relatively small feature, so it is likely to be implemented relatively
+soon.</li>
+
+<li>clang does not support code generation for local variables pinned to
+registers (<a href="http://llvm.org/bugs/show_bug.cgi?id=3933">bug 3933</a>).
+This is a relatively small feature, so it is likely to be implemented
+relatively soon.</li>
+
+<li>clang does not support decimal floating point types (_Decimal32 and
+friends) or fixed-point types (_Fract and friends); nobody has expressed
+interest in these features yet, so it's hard to say when they will be
+implemented.</li>
+
+<li>clang does not support nested functions; this is a complex feature which
+is infrequently used, so it is unlikely to be implemented anytime soon.</li>
+
+<li>clang does not support global register variables, this is unlikely
+to be implemented soon because it requires additional LLVM backend support.
+</li>
+
+<li>clang does not support static initialization of flexible array
+members. This appears to be a rarely used extension, but could be
+implemented pending user demand.</li>
+
+<li>clang does not support __builtin_va_arg_pack/__builtin_va_arg_pack_len. 
+This is used rarely, but in some potentially interesting places, like the
+glibc headers, so it may be implemented pending user demand.  Note that
+because clang pretends to be like GCC 4.2, and this extension was introduced
+in 4.3, the glibc headers will not try to use this extension with clang at
+the moment.</li>
+
+<li>clang does not support the gcc extension for forward-declaring function
+parameters; this has not showed up in any real-world code yet, though, so it
+might never be implemented.</li>
+
+</ul>
+
+<p>This is not a complete list; if you find an unsupported extension
+missing from this list, please send an e-mail to cfe-dev.  This list
+currently excludes C++; see <a href="#cxx">C++ Language Features</a>.
+Also, this list does not include bugs in mostly-implemented features; please
+see the <a href="http://llvm.org/bugs/buglist.cgi?quicksearch=product%3Aclang+component%3A-New%2BBugs%2CAST%2CBasic%2CDriver%2CHeaders%2CLLVM%2BCodeGen%2Cparser%2Cpreprocessor%2CSemantic%2BAnalyzer">
+bug tracker</a> for known existing bugs (FIXME: Is there a section for
+bug-reporting guidelines somewhere?).</p>
+
+<!-- = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = -->
+<h3 id="c_unsupp_gcc">Intentionally unsupported GCC extensions</h3>
+<!-- = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = -->
+
+<ul>
+
+<li>clang does not support the gcc extension that allows variable-length arrays
+in structures.  This is for a few of reasons: one, it is tricky
+to implement, two, the extension is completely undocumented, and three, the
+extension appears to be rarely used.</li>
+
+<li>clang does not support duplicate definitions of a function where one is
+inline. This complicates clients of the AST which normally can expect there is
+at most one definition for each function. Source code using this feature should
+be changed to define the inline and out-of-line definitions in separate
+translation units.</li>
+
+<li>clang does not have an equivalent to gcc's "fold"; this means that
+clang doesn't accept some constructs gcc might accept in contexts where a
+constant expression is required, like "x-x" where x is a variable, or calls
+to C library functions like strlen.</li>
+
+<li>clang does not support multiple alternative constraints in inline asm; this
+is an extremely obscure feature which would be complicated to implement
+correctly.</li>
+
+<li>clang does not support __builtin_apply and friends; this extension is
+extremely obscure and difficult to implement reliably.</li>
+
+</ul>
+
+<!-- = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = -->
+<h3 id="c_ms">Microsoft extensions</h3>
+<!-- = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = -->
+
+<p>clang has some experimental support for extensions from
+Microsoft Visual C++; to enable it, use the -fms-extensions command-line
+option.  This is the default for Windows targets.  Note that the
+support is incomplete; enabling Microsoft extensions will silently drop
+certain constructs (including __declspec and Microsoft-style asm statements).
+</p>
+
+<li>clang does not support the Microsoft extension where anonymous
+record members can be declared using user defined typedefs.</li>
+
+<li>clang supports the Microsoft "#pragma pack" feature for
+controlling record layout. GCC also contains support for this feature,
+however where MSVC and GCC are incompatible clang follows the MSVC
+definition.</li>
+
+<!-- ======================================================================= -->
+<h2 id="objc">Objective-C Language Features</h2>
+<!-- ======================================================================= -->
+
+
+<!-- = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = -->
+<h3 id="objc_incompatibilities">Intentional Incompatibilities with GCC</h3>
+<!-- = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = -->
+
+<p>No cast of super, no lvalue casts.</p>
+
+
+
+<!-- ======================================================================= -->
+<h2 id="cxx">C++ Language Features</h2>
+<!-- ======================================================================= -->
+
+<p>At this point, Clang C++ is not production-quality and is not recommended for use beyond experimentation.  However, Clang C++ support
+is under active development and is progressing rapidly.  Please see the <a
+href="http://clang.llvm.org/cxx_status.html">C++ Status</a> page for details or
+ask on the mailing list about how you can help.</p>
+
+<p>Note that released Clang compilers will refuse to even try to use clang to compile C++ code unless you pass the <tt>-ccc-clang-cxx</tt> option to the driver. To turn on Clang's C++ support, please pass that flag. Clang compilers built from the Subversion trunk enable C++ support by default, and do not require the <tt>-ccc-clang-cxx</tt> flag.</p>
+ 
+<p>Clang strives to strictly conform to the C++ standard.  That means
+it will reject invalid C++ code that another compiler may accept.  If
+Clang reports errors in your code, please check
+the <a href="http://clang.llvm.org/cxx_compatibility.html">C++
+Compatibility</a> page to see whether they are C++-conformance bugs
+and how you can fix them.</p>
+
+<!-- ======================================================================= -->
+<h2 id="objcxx">Objective C++ Language Features</h2>
+<!-- ======================================================================= -->
+
+<p>At this point, Clang C++ support is not generally useful (and therefore,
+neither is Objective-C++).  Please see the <a href="#cxx">C++ section</a> for
+more information.</p>
+
+<!-- ======================================================================= -->
+<h2 id="target_features">Target-Specific Features and Limitations</h2>
+<!-- ======================================================================= -->
+
+
+<!-- = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = -->
+<h3 id="target_arch">CPU Architectures Features and Limitations</h3>
+<!-- = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = -->
+
+<!-- ======================== -->
+<h4 id="target_arch_x86">X86</h4>
+<!-- ======================== -->
+<p>The support for X86 (both 32-bit and 64-bit) is considered stable
+on Darwin (Mac OS/X), Linux, FreeBSD, and Dragonfly BSD: it has been tested to
+correctly compile large C and Objective-C codebases. (FIXME: Anything specific
+we want to say here? Possibly mention some LLVM x86 limitations?)
+
+<!-- ======================== -->
+<h4 id="target_arch_arm">ARM</h4>
+<!-- ======================== -->
+ARM support is mostly feature-complete, but still experimental; it hasn't
+undergone significant testing.
+
+<!-- ======================== -->
+<h4 id="target_arch_other">Other platforms</h4>
+<!-- ======================== -->
+clang currently contains some support for PPC and Sparc; however, significant
+pieces of code generation are still missing, and they haven't undergone
+significant testing.
+
+<p>clang contains some support for the embedded PIC16 processor
+(FIXME: I haven't been keeping track of this; what should this say?).
+
+<p>clang contains limited support for the MSP430 embedded processor, but both
+the clang support and the LLVM backend support are highly experimental.
+
+<p>Other platforms are completely unsupported at the moment.  Adding the
+minimal support needed for parsing and semantic analysis on a new platform
+is quite easy; see lib/Basic/Targets.cpp in the clang source tree. This level
+of support is also sufficient for conversion to LLVM IR for simple programs.
+Proper support for conversion to LLVM IR requires adding code to
+lib/CodeGen/CGCall.cpp at the moment; this is likely to change soon, though.
+Generating assembly requires a suitable LLVM backend. 
+
+<!-- = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = -->
+<h3 id="target_os">Operating System Features and Limitations</h3>
+<!-- = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = -->
+
+<!-- ======================================= -->
+<h4 id="target_os_darwin">Darwin (Mac OS/X)</h4>
+<!-- ======================================= -->
+
+<p>No __thread support, 64-bit ObjC support requires SL tools.</p>
+
+</div>
+</body>
+</html>
diff --git a/docs/doxygen.cfg b/docs/doxygen.cfg
new file mode 100644
index 0000000..40180b2
--- /dev/null
+++ b/docs/doxygen.cfg
@@ -0,0 +1,1230 @@
+# Doxyfile 1.4.4
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+#       TAG = value [value, ...]
+# For lists items can also be appended using:
+#       TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded 
+# by quotes) that should identify the project.
+
+PROJECT_NAME           = clang
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. 
+# This could be handy for archiving the generated documentation or 
+# if some version control system is used.
+
+PROJECT_NUMBER         = mainline
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
+# base path where the generated documentation will be put. 
+# If a relative path is entered, it will be relative to the location 
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = ../docs/doxygen
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 
+# 4096 sub-directories (in 2 levels) under the output directory of each output 
+# format and will distribute the generated files over these directories. 
+# Enabling this option can be useful when feeding doxygen a huge amount of 
+# source files, where putting all generated files in the same directory would 
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS         = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all 
+# documentation generated by doxygen is written. Doxygen will use this 
+# information to generate all constant output in the proper language. 
+# The default language is English, other supported languages are: 
+# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, 
+# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese, 
+# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian, 
+# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, 
+# Swedish, and Ukrainian.
+
+OUTPUT_LANGUAGE        = English
+
+# This tag can be used to specify the encoding used in the generated output. 
+# The encoding is not always determined by the language that is chosen, 
+# but also whether or not the output is meant for Windows or non-Windows users. 
+# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES 
+# forces the Windows encoding (this is the default for the Windows binary), 
+# whereas setting the tag to NO uses a Unix-style encoding (the default for 
+# all platforms other than Windows).
+
+USE_WINDOWS_ENCODING   = NO
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 
+# include brief member descriptions after the members that are listed in 
+# the file and class documentation (similar to JavaDoc). 
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 
+# the brief description of a member or function before the detailed description. 
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF           = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator 
+# that is used to form the text in various listings. Each string 
+# in this list, if found as the leading text of the brief description, will be 
+# stripped from the text and the result after processing the whole list, is 
+# used as the annotated text. Otherwise, the brief description is used as-is. 
+# If left blank, the following values are used ("$name" is automatically 
+# replaced with the name of the entity): "The $name class" "The $name widget" 
+# "The $name file" "is" "provides" "specifies" "contains" 
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF       = 
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 
+# Doxygen will generate a detailed section even if there is only a brief 
+# description.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all 
+# inherited members of a class in the documentation of that class as if those 
+# members were ordinary class members. Constructors, destructors and assignment 
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 
+# path before files name in the file list and in the header files. If set 
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES        = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 
+# can be used to strip a user-defined part of the path. Stripping is 
+# only done if one of the specified strings matches the left-hand part of 
+# the path. The tag can be used to show relative paths in the file list. 
+# If left blank the directory from which doxygen is run is used as the 
+# path to strip.
+
+STRIP_FROM_PATH        = ../..
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of 
+# the path mentioned in the documentation of a class, which tells 
+# the reader which header file to include in order to use a class. 
+# If left blank only the name of the header file containing the class 
+# definition is used. Otherwise one should specify the include paths that 
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH    = 
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter 
+# (but less readable) file names. This can be useful is your file systems 
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen 
+# will interpret the first line (until the first dot) of a JavaDoc-style 
+# comment as the brief description. If set to NO, the JavaDoc 
+# comments will behave just like the Qt-style comments (thus requiring an 
+# explicit @brief command for a brief description.
+
+JAVADOC_AUTOBRIEF      = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen 
+# treat a multi-line C++ special comment block (i.e. a block of //! or /// 
+# comments) as a brief description. This used to be the default behaviour. 
+# The new default is to treat a multi-line C++ comment block as a detailed 
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the DETAILS_AT_TOP tag is set to YES then Doxygen 
+# will output the detailed description near the top, like JavaDoc.
+# If set to NO, the detailed description appears after the member 
+# documentation.
+
+DETAILS_AT_TOP         = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 
+# member inherits the documentation from any documented member that it 
+# re-implements.
+
+INHERIT_DOCS           = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 
+# tag is set to YES, then doxygen will reuse the documentation of the first 
+# member in the group (if any) for the other members of the group. By default 
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce 
+# a new page for each member. If set to NO, the documentation of a member will 
+# be part of the file/class/namespace that contains it.
+
+#SEPARATE_MEMBER_PAGES  = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. 
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE               = 2
+
+# This tag can be used to specify a number of aliases that acts 
+# as commands in the documentation. An alias has the form "name=value". 
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to 
+# put the command \sideeffect (or @sideeffect) in the documentation, which 
+# will result in a user-defined paragraph with heading "Side Effects:". 
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES                = 
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C 
+# sources only. Doxygen will then generate output that is more tailored for C. 
+# For instance, some of the names that are used will be different. The list 
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C  = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources 
+# only. Doxygen will then generate output that is more tailored for Java. 
+# For instance, namespaces will be presented as packages, qualified scopes 
+# will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of 
+# the same type (for instance a group of public functions) to be put as a 
+# subgroup of that type (e.g. under the Public Functions section). Set it to 
+# NO to prevent subgrouping. Alternatively, this can be done per class using 
+# the \nosubgrouping command.
+
+SUBGROUPING            = YES
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 
+# documentation are documented, even if no documentation was available. 
+# Private class members and static file members will be hidden unless 
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL            = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class 
+# will be included in the documentation.
+
+EXTRACT_PRIVATE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file 
+# will be included in the documentation.
+
+EXTRACT_STATIC         = YES
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) 
+# defined locally in source files will be included in the documentation. 
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES  = YES
+
+# This flag is only useful for Objective-C code. When set to YES local 
+# methods, which are defined in the implementation section but not in 
+# the interface are included in the documentation. 
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS  = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 
+# undocumented members of documented classes, files or namespaces. 
+# If set to NO (the default) these members will be included in the 
+# various overviews, but no documentation section is generated. 
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS     = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all 
+# undocumented classes that are normally visible in the class hierarchy. 
+# If set to NO (the default) these classes will be included in the various 
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES     = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all 
+# friend (class|struct|union) declarations. 
+# If set to NO (the default) these declarations will be included in the 
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 
+# documentation blocks found inside the body of a function. 
+# If set to NO (the default) these blocks will be appended to the 
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation 
+# that is typed after a \internal command is included. If the tag is set 
+# to NO (the default) then the documentation will be excluded. 
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 
+# file names in lower-case letters. If set to YES upper-case letters are also 
+# allowed. This is useful if you have classes or files whose names only differ 
+# in case and if your file system supports case sensitive file names. Windows 
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES       = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
+# will show members with their full class and namespace scopes in the 
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
+# will put a list of the files that are included by a file in the documentation 
+# of that file.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
+# is inserted in the documentation for inline members.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
+# will sort the (detailed) documentation of file and class members 
+# alphabetically by member name. If set to NO the members will appear in 
+# declaration order.
+
+SORT_MEMBER_DOCS       = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the 
+# brief documentation of file, namespace and class members alphabetically 
+# by member name. If set to NO (the default) the members will appear in 
+# declaration order.
+
+SORT_BRIEF_DOCS        = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be 
+# sorted by fully-qualified names, including namespaces. If set to 
+# NO (the default), the class list will be sorted only by class name, 
+# not including the namespace part. 
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the 
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME     = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or 
+# disable (NO) the todo list. This list is created by putting \todo 
+# commands in the documentation.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or 
+# disable (NO) the test list. This list is created by putting \test 
+# commands in the documentation.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or 
+# disable (NO) the bug list. This list is created by putting \bug 
+# commands in the documentation.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 
+# disable (NO) the deprecated list. This list is created by putting 
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional 
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS       = 
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines 
+# the initial value of a variable or define consists of for it to appear in 
+# the documentation. If the initializer consists of more lines than specified 
+# here it will be hidden. Use a value of 0 to hide initializers completely. 
+# The appearance of the initializer of individual variables and defines in the 
+# documentation can be controlled using \showinitializer or \hideinitializer 
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated 
+# at the bottom of the documentation of classes and structs. If set to YES the 
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES        = YES
+
+# If the sources in your project are distributed over multiple directories 
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy 
+# in the documentation. The default is YES.
+
+SHOW_DIRECTORIES       = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that 
+# doxygen should invoke to get the current version for each file (typically from the 
+# version control system). Doxygen will invoke the program by executing (via 
+# popen()) the command <command> <input-file>, where <command> is the value of 
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file 
+# provided by doxygen. Whatever the progam writes to standard output 
+# is used as the file version. See the manual for examples.
+
+#FILE_VERSION_FILTER    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated 
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET                  = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are 
+# generated by doxygen. Possible values are YES and NO. If left blank 
+# NO is used.
+
+WARNINGS               = NO
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED   = NO
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for 
+# potential errors in the documentation, such as not documenting some 
+# parameters in a documented function, or documenting parameters that 
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR      = YES
+
+# This WARN_NO_PARAMDOC option can be abled to get warnings for 
+# functions that are documented, but have no documentation for their parameters 
+# or return value. If set to NO (the default) doxygen will only warn about 
+# wrong or incomplete parameter documentation, but not about the absence of 
+# documentation.
+
+#WARN_NO_PARAMDOC       = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that 
+# doxygen can produce. The string should contain the $file, $line, and $text 
+# tags, which will be replaced by the file and line number from which the 
+# warning originated and the warning text. Optionally the format may contain 
+# $version, which will be replaced by the version of the file (if it could 
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT            = 
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning 
+# and error messages should be written. If left blank the output is written 
+# to stderr.
+
+WARN_LOGFILE           = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain 
+# documented source files. You may enter file names like "myfile.cpp" or 
+# directories like "/usr/src/myproject". Separate the files or directories 
+# with spaces.
+
+INPUT                  = ../include \
+                         ../lib \
+                         ../docs/doxygen.intro
+
+# If the value of the INPUT tag contains directories, you can use the 
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank the following patterns are tested: 
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx 
+# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm
+
+FILE_PATTERNS          = 
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories 
+# should be searched for input files as well. Possible values are YES and NO. 
+# If left blank NO is used.
+
+RECURSIVE              = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should 
+# excluded from the INPUT source files. This way you can easily exclude a 
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE                = 
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or 
+# directories that are symbolic links (a Unix filesystem feature) are excluded 
+# from the input.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the 
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 
+# certain files from those directories. Note that the wildcards are matched 
+# against the file with absolute path, so to exclude all test directories 
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS       = 
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or 
+# directories that contain example code fragments that are included (see 
+# the \include command).
+
+EXAMPLE_PATH           = ../examples
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the 
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank all files are included.
+
+EXAMPLE_PATTERNS       = 
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be 
+# searched for input files to be used with the \include or \dontinclude 
+# commands irrespective of the value of the RECURSIVE tag. 
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE      = YES
+
+# The IMAGE_PATH tag can be used to specify one or more files or 
+# directories that contain image that are included in the documentation (see 
+# the \image command).
+
+IMAGE_PATH             = ../docs/img
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should 
+# invoke to filter for each input file. Doxygen will invoke the filter program 
+# by executing (via popen()) the command <filter> <input-file>, where <filter> 
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
+# input file. Doxygen will then use the output that the filter program writes 
+# to standard output.  If FILTER_PATTERNS is specified, this tag will be 
+# ignored.
+
+INPUT_FILTER           = 
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern 
+# basis.  Doxygen will compare the file name with each pattern and apply the 
+# filter if there is a match.  The filters are a list of the form: 
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further 
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER 
+# is applied to all files.
+
+FILTER_PATTERNS        = 
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 
+# INPUT_FILTER) will be used to filter the input files when producing source 
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES    = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will 
+# be generated. Documented entities will be cross-referenced with these sources. 
+# Note: To get rid of all source code in the generated output, make sure also 
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER         = YES
+
+# Setting the INLINE_SOURCES tag to YES will include the body 
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 
+# doxygen to hide any special comment blocks from generated source code 
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS    = NO
+
+# If the REFERENCED_BY_RELATION tag is set to YES (the default) 
+# then for each documented function all documented 
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES (the default) 
+# then for each documented function all documented entities 
+# called/used by that function will be listed.
+
+REFERENCES_RELATION    = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code 
+# will point to the HTML generated by the htags(1) tool instead of doxygen 
+# built-in source browser. The htags tool is part of GNU's global source 
+# tagging system (see http://www.gnu.org/software/global/global.html). You 
+# will need version 4.8.6 or higher.
+
+#USE_HTAGS              = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 
+# will generate a verbatim copy of the header file for each class for 
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS       = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 
+# of all compounds will be generated. Enable this if the project 
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX     = YES
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX    = 4
+
+# In case all classes in a project start with a common prefix, all 
+# classes will be put under the same header in the alphabetical index. 
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX          = llvm::
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
+# generate HTML output.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT            = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for 
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank 
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard header.
+
+HTML_HEADER            = ../docs/doxygen.header
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard footer.
+
+HTML_FOOTER            = ../docs/doxygen.footer
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading 
+# style sheet that is used by each HTML page. It can be used to 
+# fine-tune the look of the HTML output. If the tag is left blank doxygen 
+# will generate a default style sheet. Note that doxygen will try to copy 
+# the style sheet file to the HTML output directory, so don't put your own 
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET        = ../docs/doxygen.css
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
+# files or namespaces will be aligned in HTML using tables. If set to 
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS     = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
+# will be generated that can be used as input for tools like the 
+# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) 
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP      = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can 
+# be used to specify the file name of the resulting .chm file. You 
+# can add a path in front of the file if the result should not be 
+# written to the html output directory.
+
+CHM_FILE               = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can 
+# be used to specify the location (absolute path including file name) of 
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run 
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION           = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 
+# controls if a separate .chi index file is generated (YES) or that 
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI           = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 
+# controls whether a binary table of contents is generated (YES) or a 
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members 
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND             = NO
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at 
+# top of each HTML page. The value NO (the default) enables the index and 
+# the value YES disables it.
+
+DISABLE_INDEX          = NO
+
+# This tag can be used to set the number of enum values (range [1..20]) 
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
+# generated containing a tree-like index structure (just like the one that 
+# is generated for HTML Help). For this to work a browser that supports 
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, 
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are 
+# probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW      = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
+# used to set the initial width (in pixels) of the frame in which the tree 
+# is shown.
+
+TREEVIEW_WIDTH         = 250
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 
+# generate Latex output.
+
+GENERATE_LATEX         = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT           = 
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be 
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to 
+# generate index for LaTeX. If left blank `makeindex' will be used as the 
+# default command name.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 
+# LaTeX documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used 
+# by the printer. Possible values are: a4, a4wide, letter, legal and 
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE             = letter
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES         = 
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for 
+# the generated latex document. The header should contain everything until 
+# the first chapter. If it is left blank doxygen will generate a 
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER           = 
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will 
+# contain links (just like the HTML output) instead of page references 
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS         = NO
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 
+# plain latex in the generated Makefile. Set this option to YES to get a 
+# higher quality PDF documentation.
+
+USE_PDFLATEX           = NO
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 
+# command to the generated LaTeX files. This will instruct LaTeX to keep 
+# running if errors occur, instead of asking the user for help. 
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE        = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not 
+# include the index chapters (such as File Index, Compound Index, etc.) 
+# in the output.
+
+LATEX_HIDE_INDICES     = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 
+# The RTF output is optimized for Word 97 and may not look very pretty with 
+# other RTF readers or editors.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT             = 
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact 
+# RTF documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 
+# will contain hyperlink fields. The RTF file will 
+# contain links (just like the HTML output) instead of page references. 
+# This makes the output suitable for online browsing using WORD or other 
+# programs which support those fields. 
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS         = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's 
+# config file, i.e. a series of assignments. You only have to provide 
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE    = 
+
+# Set optional variables used in the generation of an rtf document. 
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
+# generate man pages
+
+GENERATE_MAN           = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT             = 
+
+# The MAN_EXTENSION tag determines the extension that is added to 
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION          = 
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output, 
+# then it will generate one additional man file for each entity 
+# documented in the real man page(s). These additional files 
+# only source the real man page, but without them the man command 
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS              = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will 
+# generate an XML file that captures the structure of 
+# the code including all documentation.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT             = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_SCHEMA             = 
+
+# The XML_DTD tag can be used to specify an XML DTD, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_DTD                = 
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will 
+# dump the program listings (including syntax highlighting 
+# and cross-referencing information) to the XML output. Note that 
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will 
+# generate an AutoGen Definitions (see autogen.sf.net) file 
+# that captures the structure of the code including all 
+# documentation. Note that this feature is still experimental 
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will 
+# generate a Perl module file that captures the structure of 
+# the code including all documentation. Note that this 
+# feature is still experimental and incomplete at the 
+# moment.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate 
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able 
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be 
+# nicely formatted so it can be parsed by a human reader.  This is useful 
+# if you want to understand what is going on.  On the other hand, if this 
+# tag is set to NO the size of the Perl module output will be much smaller 
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file 
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. 
+# This is useful so different doxyrules.make files included by the same 
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor   
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 
+# evaluate all C-preprocessor directives found in the sources and include 
+# files.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 
+# names in the source code. If set to NO (the default) only conditional 
+# compilation will be performed. Macro expansion can be done in a controlled 
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION        = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
+# then the macro expansion is limited to the macros specified with the 
+# PREDEFINED and EXPAND_AS_PREDEFINED tags.
+
+EXPAND_ONLY_PREDEF     = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that 
+# contain include files that are not input files but should be processed by 
+# the preprocessor.
+
+INCLUDE_PATH           = ../include
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
+# patterns (like *.h and *.hpp) to filter out the header-files in the 
+# directories. If left blank, the patterns specified with FILE_PATTERNS will 
+# be used.
+
+INCLUDE_FILE_PATTERNS  = 
+
+# The PREDEFINED tag can be used to specify one or more macro names that 
+# are defined before the preprocessor is started (similar to the -D option of 
+# gcc). The argument of the tag is a list of macros of the form: name 
+# or name=definition (no spaces). If the definition and the = are 
+# omitted =1 is assumed. To prevent a macro definition from being 
+# undefined via #undef or recursively expanded use the := operator 
+# instead of the = operator.
+
+PREDEFINED             = 
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 
+# this tag can be used to specify a list of macro names that should be expanded. 
+# The macro definition that is found in the sources will be used. 
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED      = 
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
+# doxygen's preprocessor will remove all function-like macros that are alone 
+# on a line, have an all uppercase name, and do not end with a semicolon. Such 
+# function macros are typically used for boiler-plate code, and will confuse 
+# the parser if not removed.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references   
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles. 
+# Optionally an initial location of the external documentation 
+# can be added for each tagfile. The format of a tag file without 
+# this location is as follows: 
+#   TAGFILES = file1 file2 ... 
+# Adding location for the tag files is done as follows: 
+#   TAGFILES = file1=loc1 "file2 = loc2" ... 
+# where "loc1" and "loc2" can be relative or absolute paths or 
+# URLs. If a location is present for each tag, the installdox tool 
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen 
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES               = 
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create 
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE       = 
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed 
+# in the class index. If set to NO only the inherited external classes 
+# will be listed.
+
+ALLEXTERNALS           = YES
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed 
+# in the modules index. If set to NO, only the current project's groups will 
+# be listed.
+
+EXTERNAL_GROUPS        = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script 
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH              = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base 
+# or super classes. Setting the tag to NO turns the diagrams off. Note that 
+# this option is superseded by the HAVE_DOT option below. This is only a 
+# fallback. It is recommended to install and use dot, since it yields more 
+# powerful graphs.
+
+CLASS_DIAGRAMS         = YES
+
+# If set to YES, the inheritance and collaboration graphs will hide 
+# inheritance and usage relations if the target is undocumented 
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS   = NO
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
+# available from the path. This tool is part of Graphviz, a graph visualization 
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section 
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT               = YES
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect inheritance relations. Setting this tag to YES will force the 
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect implementation dependencies (inheritance, containment, and 
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH    = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for groups, showing the direct groups dependencies
+
+#GROUP_GRAPHS           = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and 
+# collaboration diagrams in a style similar to the OMG's Unified Modeling 
+# Language.
+
+UML_LOOK               = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the 
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS     = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 
+# tags are set to YES then doxygen will generate a graph for each documented 
+# file showing the direct and indirect include dependencies of the file with 
+# other documented files.
+
+INCLUDE_GRAPH          = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each 
+# documented header file showing the documented files that directly or 
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will 
+# generate a call dependency graph for every global function or class method. 
+# Note that enabling this option will significantly increase the time of a run. 
+# So in most cases it will be better to enable call graphs for selected 
+# functions only using the \callgraph command.
+
+CALL_GRAPH             = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES 
+# then doxygen will show the dependencies a directory has on other directories 
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+#DIRECTORY_GRAPH        = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images 
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT       = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be 
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH               = dot
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that 
+# contain dot files that are included in the documentation (see the 
+# \dotfile command).
+
+DOTFILE_DIRS           = 
+
+# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width 
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than 
+# this value, doxygen will try to truncate the graph, so that it fits within 
+# the specified constraint. Beware that most browsers cannot cope with very 
+# large images.
+
+MAX_DOT_GRAPH_WIDTH    = 1024
+
+# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height 
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than 
+# this value, doxygen will try to truncate the graph, so that it fits within 
+# the specified constraint. Beware that most browsers cannot cope with very 
+# large images.
+
+MAX_DOT_GRAPH_HEIGHT   = 1024
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the 
+# graphs generated by dot. A depth value of 3 means that only nodes reachable 
+# from the root by following a path via at most 3 edges will be shown. Nodes 
+# that lay further from the root node will be omitted. Note that setting this 
+# option to 1 or 2 may greatly reduce the computation time needed for large 
+# code bases. Also note that a graph may be further truncated if the graph's 
+# image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH 
+# and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default), 
+# the graph is not depth-constrained.
+
+MAX_DOT_GRAPH_DEPTH    = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent 
+# background. This is disabled by default, which results in a white background. 
+# Warning: Depending on the platform used, enabling this option may lead to 
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to 
+# read).
+
+#DOT_TRANSPARENT        = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output 
+# files in one run (i.e. multiple -o and -T options on the command line). This 
+# makes dot run faster, but since only newer versions of dot (>1.8.10) 
+# support this, this feature is disabled by default.
+
+#DOT_MULTI_TARGETS      = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 
+# generate a legend page explaining the meaning of the various boxes and 
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 
+# remove the intermediate dot files that are used to generate 
+# the various graphs.
+
+DOT_CLEANUP            = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine   
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be 
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE           = NO
diff --git a/docs/doxygen.cfg.in b/docs/doxygen.cfg.in
new file mode 100644
index 0000000..c1130fb
--- /dev/null
+++ b/docs/doxygen.cfg.in
@@ -0,0 +1,1230 @@
+# Doxyfile 1.4.4
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+#       TAG = value [value, ...]
+# For lists items can also be appended using:
+#       TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded 
+# by quotes) that should identify the project.
+
+PROJECT_NAME           = clang
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. 
+# This could be handy for archiving the generated documentation or 
+# if some version control system is used.
+
+PROJECT_NUMBER         = @PACKAGE_VERSION@
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
+# base path where the generated documentation will be put. 
+# If a relative path is entered, it will be relative to the location 
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = @abs_top_builddir@/docs/doxygen
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 
+# 4096 sub-directories (in 2 levels) under the output directory of each output 
+# format and will distribute the generated files over these directories. 
+# Enabling this option can be useful when feeding doxygen a huge amount of 
+# source files, where putting all generated files in the same directory would 
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS         = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all 
+# documentation generated by doxygen is written. Doxygen will use this 
+# information to generate all constant output in the proper language. 
+# The default language is English, other supported languages are: 
+# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, 
+# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese, 
+# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian, 
+# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, 
+# Swedish, and Ukrainian.
+
+OUTPUT_LANGUAGE        = English
+
+# This tag can be used to specify the encoding used in the generated output. 
+# The encoding is not always determined by the language that is chosen, 
+# but also whether or not the output is meant for Windows or non-Windows users. 
+# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES 
+# forces the Windows encoding (this is the default for the Windows binary), 
+# whereas setting the tag to NO uses a Unix-style encoding (the default for 
+# all platforms other than Windows).
+
+USE_WINDOWS_ENCODING   = NO
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 
+# include brief member descriptions after the members that are listed in 
+# the file and class documentation (similar to JavaDoc). 
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 
+# the brief description of a member or function before the detailed description. 
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF           = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator 
+# that is used to form the text in various listings. Each string 
+# in this list, if found as the leading text of the brief description, will be 
+# stripped from the text and the result after processing the whole list, is 
+# used as the annotated text. Otherwise, the brief description is used as-is. 
+# If left blank, the following values are used ("$name" is automatically 
+# replaced with the name of the entity): "The $name class" "The $name widget" 
+# "The $name file" "is" "provides" "specifies" "contains" 
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF       = 
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 
+# Doxygen will generate a detailed section even if there is only a brief 
+# description.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all 
+# inherited members of a class in the documentation of that class as if those 
+# members were ordinary class members. Constructors, destructors and assignment 
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 
+# path before files name in the file list and in the header files. If set 
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES        = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 
+# can be used to strip a user-defined part of the path. Stripping is 
+# only done if one of the specified strings matches the left-hand part of 
+# the path. The tag can be used to show relative paths in the file list. 
+# If left blank the directory from which doxygen is run is used as the 
+# path to strip.
+
+STRIP_FROM_PATH        = ../..
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of 
+# the path mentioned in the documentation of a class, which tells 
+# the reader which header file to include in order to use a class. 
+# If left blank only the name of the header file containing the class 
+# definition is used. Otherwise one should specify the include paths that 
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH    = 
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter 
+# (but less readable) file names. This can be useful is your file systems 
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen 
+# will interpret the first line (until the first dot) of a JavaDoc-style 
+# comment as the brief description. If set to NO, the JavaDoc 
+# comments will behave just like the Qt-style comments (thus requiring an 
+# explicit @brief command for a brief description.
+
+JAVADOC_AUTOBRIEF      = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen 
+# treat a multi-line C++ special comment block (i.e. a block of //! or /// 
+# comments) as a brief description. This used to be the default behaviour. 
+# The new default is to treat a multi-line C++ comment block as a detailed 
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the DETAILS_AT_TOP tag is set to YES then Doxygen 
+# will output the detailed description near the top, like JavaDoc.
+# If set to NO, the detailed description appears after the member 
+# documentation.
+
+DETAILS_AT_TOP         = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 
+# member inherits the documentation from any documented member that it 
+# re-implements.
+
+INHERIT_DOCS           = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 
+# tag is set to YES, then doxygen will reuse the documentation of the first 
+# member in the group (if any) for the other members of the group. By default 
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce 
+# a new page for each member. If set to NO, the documentation of a member will 
+# be part of the file/class/namespace that contains it.
+
+#SEPARATE_MEMBER_PAGES  = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. 
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE               = 2
+
+# This tag can be used to specify a number of aliases that acts 
+# as commands in the documentation. An alias has the form "name=value". 
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to 
+# put the command \sideeffect (or @sideeffect) in the documentation, which 
+# will result in a user-defined paragraph with heading "Side Effects:". 
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES                = 
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C 
+# sources only. Doxygen will then generate output that is more tailored for C. 
+# For instance, some of the names that are used will be different. The list 
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C  = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources 
+# only. Doxygen will then generate output that is more tailored for Java. 
+# For instance, namespaces will be presented as packages, qualified scopes 
+# will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of 
+# the same type (for instance a group of public functions) to be put as a 
+# subgroup of that type (e.g. under the Public Functions section). Set it to 
+# NO to prevent subgrouping. Alternatively, this can be done per class using 
+# the \nosubgrouping command.
+
+SUBGROUPING            = YES
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 
+# documentation are documented, even if no documentation was available. 
+# Private class members and static file members will be hidden unless 
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL            = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class 
+# will be included in the documentation.
+
+EXTRACT_PRIVATE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file 
+# will be included in the documentation.
+
+EXTRACT_STATIC         = YES
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) 
+# defined locally in source files will be included in the documentation. 
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES  = YES
+
+# This flag is only useful for Objective-C code. When set to YES local 
+# methods, which are defined in the implementation section but not in 
+# the interface are included in the documentation. 
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS  = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 
+# undocumented members of documented classes, files or namespaces. 
+# If set to NO (the default) these members will be included in the 
+# various overviews, but no documentation section is generated. 
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS     = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all 
+# undocumented classes that are normally visible in the class hierarchy. 
+# If set to NO (the default) these classes will be included in the various 
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES     = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all 
+# friend (class|struct|union) declarations. 
+# If set to NO (the default) these declarations will be included in the 
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 
+# documentation blocks found inside the body of a function. 
+# If set to NO (the default) these blocks will be appended to the 
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation 
+# that is typed after a \internal command is included. If the tag is set 
+# to NO (the default) then the documentation will be excluded. 
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 
+# file names in lower-case letters. If set to YES upper-case letters are also 
+# allowed. This is useful if you have classes or files whose names only differ 
+# in case and if your file system supports case sensitive file names. Windows 
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES       = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
+# will show members with their full class and namespace scopes in the 
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
+# will put a list of the files that are included by a file in the documentation 
+# of that file.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
+# is inserted in the documentation for inline members.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
+# will sort the (detailed) documentation of file and class members 
+# alphabetically by member name. If set to NO the members will appear in 
+# declaration order.
+
+SORT_MEMBER_DOCS       = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the 
+# brief documentation of file, namespace and class members alphabetically 
+# by member name. If set to NO (the default) the members will appear in 
+# declaration order.
+
+SORT_BRIEF_DOCS        = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be 
+# sorted by fully-qualified names, including namespaces. If set to 
+# NO (the default), the class list will be sorted only by class name, 
+# not including the namespace part. 
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the 
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME     = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or 
+# disable (NO) the todo list. This list is created by putting \todo 
+# commands in the documentation.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or 
+# disable (NO) the test list. This list is created by putting \test 
+# commands in the documentation.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or 
+# disable (NO) the bug list. This list is created by putting \bug 
+# commands in the documentation.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 
+# disable (NO) the deprecated list. This list is created by putting 
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional 
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS       = 
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines 
+# the initial value of a variable or define consists of for it to appear in 
+# the documentation. If the initializer consists of more lines than specified 
+# here it will be hidden. Use a value of 0 to hide initializers completely. 
+# The appearance of the initializer of individual variables and defines in the 
+# documentation can be controlled using \showinitializer or \hideinitializer 
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated 
+# at the bottom of the documentation of classes and structs. If set to YES the 
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES        = YES
+
+# If the sources in your project are distributed over multiple directories 
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy 
+# in the documentation. The default is YES.
+
+SHOW_DIRECTORIES       = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that 
+# doxygen should invoke to get the current version for each file (typically from the 
+# version control system). Doxygen will invoke the program by executing (via 
+# popen()) the command <command> <input-file>, where <command> is the value of 
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file 
+# provided by doxygen. Whatever the progam writes to standard output 
+# is used as the file version. See the manual for examples.
+
+#FILE_VERSION_FILTER    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated 
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET                  = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are 
+# generated by doxygen. Possible values are YES and NO. If left blank 
+# NO is used.
+
+WARNINGS               = NO
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED   = NO
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for 
+# potential errors in the documentation, such as not documenting some 
+# parameters in a documented function, or documenting parameters that 
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR      = YES
+
+# This WARN_NO_PARAMDOC option can be abled to get warnings for 
+# functions that are documented, but have no documentation for their parameters 
+# or return value. If set to NO (the default) doxygen will only warn about 
+# wrong or incomplete parameter documentation, but not about the absence of 
+# documentation.
+
+#WARN_NO_PARAMDOC       = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that 
+# doxygen can produce. The string should contain the $file, $line, and $text 
+# tags, which will be replaced by the file and line number from which the 
+# warning originated and the warning text. Optionally the format may contain 
+# $version, which will be replaced by the version of the file (if it could 
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT            = 
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning 
+# and error messages should be written. If left blank the output is written 
+# to stderr.
+
+WARN_LOGFILE           = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain 
+# documented source files. You may enter file names like "myfile.cpp" or 
+# directories like "/usr/src/myproject". Separate the files or directories 
+# with spaces.
+
+INPUT                  = @abs_top_srcdir@/include \
+                         @abs_top_srcdir@/lib \
+                         @abs_top_srcdir@/docs/doxygen.intro
+
+# If the value of the INPUT tag contains directories, you can use the 
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank the following patterns are tested: 
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx 
+# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm
+
+FILE_PATTERNS          = 
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories 
+# should be searched for input files as well. Possible values are YES and NO. 
+# If left blank NO is used.
+
+RECURSIVE              = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should 
+# excluded from the INPUT source files. This way you can easily exclude a 
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE                = 
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or 
+# directories that are symbolic links (a Unix filesystem feature) are excluded 
+# from the input.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the 
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 
+# certain files from those directories. Note that the wildcards are matched 
+# against the file with absolute path, so to exclude all test directories 
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS       = 
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or 
+# directories that contain example code fragments that are included (see 
+# the \include command).
+
+EXAMPLE_PATH           = @abs_top_srcdir@/examples
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the 
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank all files are included.
+
+EXAMPLE_PATTERNS       = 
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be 
+# searched for input files to be used with the \include or \dontinclude 
+# commands irrespective of the value of the RECURSIVE tag. 
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE      = YES
+
+# The IMAGE_PATH tag can be used to specify one or more files or 
+# directories that contain image that are included in the documentation (see 
+# the \image command).
+
+IMAGE_PATH             = @abs_top_srcdir@/docs/img
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should 
+# invoke to filter for each input file. Doxygen will invoke the filter program 
+# by executing (via popen()) the command <filter> <input-file>, where <filter> 
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
+# input file. Doxygen will then use the output that the filter program writes 
+# to standard output.  If FILTER_PATTERNS is specified, this tag will be 
+# ignored.
+
+INPUT_FILTER           = 
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern 
+# basis.  Doxygen will compare the file name with each pattern and apply the 
+# filter if there is a match.  The filters are a list of the form: 
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further 
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER 
+# is applied to all files.
+
+FILTER_PATTERNS        = 
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 
+# INPUT_FILTER) will be used to filter the input files when producing source 
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES    = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will 
+# be generated. Documented entities will be cross-referenced with these sources. 
+# Note: To get rid of all source code in the generated output, make sure also 
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER         = YES
+
+# Setting the INLINE_SOURCES tag to YES will include the body 
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 
+# doxygen to hide any special comment blocks from generated source code 
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS    = NO
+
+# If the REFERENCED_BY_RELATION tag is set to YES (the default) 
+# then for each documented function all documented 
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES (the default) 
+# then for each documented function all documented entities 
+# called/used by that function will be listed.
+
+REFERENCES_RELATION    = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code 
+# will point to the HTML generated by the htags(1) tool instead of doxygen 
+# built-in source browser. The htags tool is part of GNU's global source 
+# tagging system (see http://www.gnu.org/software/global/global.html). You 
+# will need version 4.8.6 or higher.
+
+#USE_HTAGS              = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 
+# will generate a verbatim copy of the header file for each class for 
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS       = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 
+# of all compounds will be generated. Enable this if the project 
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX     = YES
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX    = 4
+
+# In case all classes in a project start with a common prefix, all 
+# classes will be put under the same header in the alphabetical index. 
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX          = clang::
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
+# generate HTML output.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT            = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for 
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank 
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard header.
+
+HTML_HEADER            = @abs_top_srcdir@/docs/doxygen.header
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard footer.
+
+HTML_FOOTER            = @abs_top_srcdir@/docs/doxygen.footer
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading 
+# style sheet that is used by each HTML page. It can be used to 
+# fine-tune the look of the HTML output. If the tag is left blank doxygen 
+# will generate a default style sheet. Note that doxygen will try to copy 
+# the style sheet file to the HTML output directory, so don't put your own 
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET        = @abs_top_srcdir@/docs/doxygen.css
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
+# files or namespaces will be aligned in HTML using tables. If set to 
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS     = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
+# will be generated that can be used as input for tools like the 
+# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) 
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP      = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can 
+# be used to specify the file name of the resulting .chm file. You 
+# can add a path in front of the file if the result should not be 
+# written to the html output directory.
+
+CHM_FILE               = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can 
+# be used to specify the location (absolute path including file name) of 
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run 
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION           = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 
+# controls if a separate .chi index file is generated (YES) or that 
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI           = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 
+# controls whether a binary table of contents is generated (YES) or a 
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members 
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND             = NO
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at 
+# top of each HTML page. The value NO (the default) enables the index and 
+# the value YES disables it.
+
+DISABLE_INDEX          = NO
+
+# This tag can be used to set the number of enum values (range [1..20]) 
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
+# generated containing a tree-like index structure (just like the one that 
+# is generated for HTML Help). For this to work a browser that supports 
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, 
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are 
+# probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW      = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
+# used to set the initial width (in pixels) of the frame in which the tree 
+# is shown.
+
+TREEVIEW_WIDTH         = 250
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 
+# generate Latex output.
+
+GENERATE_LATEX         = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT           = 
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be 
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to 
+# generate index for LaTeX. If left blank `makeindex' will be used as the 
+# default command name.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 
+# LaTeX documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used 
+# by the printer. Possible values are: a4, a4wide, letter, legal and 
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE             = letter
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES         = 
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for 
+# the generated latex document. The header should contain everything until 
+# the first chapter. If it is left blank doxygen will generate a 
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER           = 
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will 
+# contain links (just like the HTML output) instead of page references 
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS         = NO
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 
+# plain latex in the generated Makefile. Set this option to YES to get a 
+# higher quality PDF documentation.
+
+USE_PDFLATEX           = NO
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 
+# command to the generated LaTeX files. This will instruct LaTeX to keep 
+# running if errors occur, instead of asking the user for help. 
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE        = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not 
+# include the index chapters (such as File Index, Compound Index, etc.) 
+# in the output.
+
+LATEX_HIDE_INDICES     = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 
+# The RTF output is optimized for Word 97 and may not look very pretty with 
+# other RTF readers or editors.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT             = 
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact 
+# RTF documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 
+# will contain hyperlink fields. The RTF file will 
+# contain links (just like the HTML output) instead of page references. 
+# This makes the output suitable for online browsing using WORD or other 
+# programs which support those fields. 
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS         = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's 
+# config file, i.e. a series of assignments. You only have to provide 
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE    = 
+
+# Set optional variables used in the generation of an rtf document. 
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
+# generate man pages
+
+GENERATE_MAN           = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT             = 
+
+# The MAN_EXTENSION tag determines the extension that is added to 
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION          = 
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output, 
+# then it will generate one additional man file for each entity 
+# documented in the real man page(s). These additional files 
+# only source the real man page, but without them the man command 
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS              = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will 
+# generate an XML file that captures the structure of 
+# the code including all documentation.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT             = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_SCHEMA             = 
+
+# The XML_DTD tag can be used to specify an XML DTD, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_DTD                = 
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will 
+# dump the program listings (including syntax highlighting 
+# and cross-referencing information) to the XML output. Note that 
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will 
+# generate an AutoGen Definitions (see autogen.sf.net) file 
+# that captures the structure of the code including all 
+# documentation. Note that this feature is still experimental 
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will 
+# generate a Perl module file that captures the structure of 
+# the code including all documentation. Note that this 
+# feature is still experimental and incomplete at the 
+# moment.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate 
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able 
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be 
+# nicely formatted so it can be parsed by a human reader.  This is useful 
+# if you want to understand what is going on.  On the other hand, if this 
+# tag is set to NO the size of the Perl module output will be much smaller 
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file 
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. 
+# This is useful so different doxyrules.make files included by the same 
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor   
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 
+# evaluate all C-preprocessor directives found in the sources and include 
+# files.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 
+# names in the source code. If set to NO (the default) only conditional 
+# compilation will be performed. Macro expansion can be done in a controlled 
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION        = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
+# then the macro expansion is limited to the macros specified with the 
+# PREDEFINED and EXPAND_AS_PREDEFINED tags.
+
+EXPAND_ONLY_PREDEF     = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that 
+# contain include files that are not input files but should be processed by 
+# the preprocessor.
+
+INCLUDE_PATH           = ../include
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
+# patterns (like *.h and *.hpp) to filter out the header-files in the 
+# directories. If left blank, the patterns specified with FILE_PATTERNS will 
+# be used.
+
+INCLUDE_FILE_PATTERNS  = 
+
+# The PREDEFINED tag can be used to specify one or more macro names that 
+# are defined before the preprocessor is started (similar to the -D option of 
+# gcc). The argument of the tag is a list of macros of the form: name 
+# or name=definition (no spaces). If the definition and the = are 
+# omitted =1 is assumed. To prevent a macro definition from being 
+# undefined via #undef or recursively expanded use the := operator 
+# instead of the = operator.
+
+PREDEFINED             = 
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 
+# this tag can be used to specify a list of macro names that should be expanded. 
+# The macro definition that is found in the sources will be used. 
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED      = 
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
+# doxygen's preprocessor will remove all function-like macros that are alone 
+# on a line, have an all uppercase name, and do not end with a semicolon. Such 
+# function macros are typically used for boiler-plate code, and will confuse 
+# the parser if not removed.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references   
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles. 
+# Optionally an initial location of the external documentation 
+# can be added for each tagfile. The format of a tag file without 
+# this location is as follows: 
+#   TAGFILES = file1 file2 ... 
+# Adding location for the tag files is done as follows: 
+#   TAGFILES = file1=loc1 "file2 = loc2" ... 
+# where "loc1" and "loc2" can be relative or absolute paths or 
+# URLs. If a location is present for each tag, the installdox tool 
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen 
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES               = 
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create 
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE       = 
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed 
+# in the class index. If set to NO only the inherited external classes 
+# will be listed.
+
+ALLEXTERNALS           = YES
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed 
+# in the modules index. If set to NO, only the current project's groups will 
+# be listed.
+
+EXTERNAL_GROUPS        = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script 
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH              = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base 
+# or super classes. Setting the tag to NO turns the diagrams off. Note that 
+# this option is superseded by the HAVE_DOT option below. This is only a 
+# fallback. It is recommended to install and use dot, since it yields more 
+# powerful graphs.
+
+CLASS_DIAGRAMS         = YES
+
+# If set to YES, the inheritance and collaboration graphs will hide 
+# inheritance and usage relations if the target is undocumented 
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS   = NO
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
+# available from the path. This tool is part of Graphviz, a graph visualization 
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section 
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT               = YES
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect inheritance relations. Setting this tag to YES will force the 
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect implementation dependencies (inheritance, containment, and 
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH    = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for groups, showing the direct groups dependencies
+
+#GROUP_GRAPHS           = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and 
+# collaboration diagrams in a style similar to the OMG's Unified Modeling 
+# Language.
+
+UML_LOOK               = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the 
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS     = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 
+# tags are set to YES then doxygen will generate a graph for each documented 
+# file showing the direct and indirect include dependencies of the file with 
+# other documented files.
+
+INCLUDE_GRAPH          = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each 
+# documented header file showing the documented files that directly or 
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will 
+# generate a call dependency graph for every global function or class method. 
+# Note that enabling this option will significantly increase the time of a run. 
+# So in most cases it will be better to enable call graphs for selected 
+# functions only using the \callgraph command.
+
+CALL_GRAPH             = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES 
+# then doxygen will show the dependencies a directory has on other directories 
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+#DIRECTORY_GRAPH        = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images 
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT       = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be 
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH               = @DOT@
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that 
+# contain dot files that are included in the documentation (see the 
+# \dotfile command).
+
+DOTFILE_DIRS           = 
+
+# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width 
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than 
+# this value, doxygen will try to truncate the graph, so that it fits within 
+# the specified constraint. Beware that most browsers cannot cope with very 
+# large images.
+
+MAX_DOT_GRAPH_WIDTH    = 1024
+
+# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height 
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than 
+# this value, doxygen will try to truncate the graph, so that it fits within 
+# the specified constraint. Beware that most browsers cannot cope with very 
+# large images.
+
+MAX_DOT_GRAPH_HEIGHT   = 1024
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the 
+# graphs generated by dot. A depth value of 3 means that only nodes reachable 
+# from the root by following a path via at most 3 edges will be shown. Nodes 
+# that lay further from the root node will be omitted. Note that setting this 
+# option to 1 or 2 may greatly reduce the computation time needed for large 
+# code bases. Also note that a graph may be further truncated if the graph's 
+# image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH 
+# and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default), 
+# the graph is not depth-constrained.
+
+MAX_DOT_GRAPH_DEPTH    = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent 
+# background. This is disabled by default, which results in a white background. 
+# Warning: Depending on the platform used, enabling this option may lead to 
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to 
+# read).
+
+#DOT_TRANSPARENT        = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output 
+# files in one run (i.e. multiple -o and -T options on the command line). This 
+# makes dot run faster, but since only newer versions of dot (>1.8.10) 
+# support this, this feature is disabled by default.
+
+#DOT_MULTI_TARGETS      = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 
+# generate a legend page explaining the meaning of the various boxes and 
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 
+# remove the intermediate dot files that are used to generate 
+# the various graphs.
+
+DOT_CLEANUP            = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine   
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be 
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE           = NO
diff --git a/docs/doxygen.css b/docs/doxygen.css
new file mode 100644
index 0000000..f105e20
--- /dev/null
+++ b/docs/doxygen.css
@@ -0,0 +1,378 @@
+BODY,H1,H2,H3,H4,H5,H6,P,CENTER,TD,TH,UL,DL,DIV {
+	font-family: Verdana,Geneva,Arial,Helvetica,sans-serif;
+}
+BODY,TD {
+ font-size: 90%;
+}
+H1 {
+ text-align: center;
+ font-size: 140%;
+ font-weight: bold;
+}
+H2 {
+ font-size: 120%;
+ font-style: italic;
+}
+H3 {
+ font-size: 100%;
+}
+CAPTION { font-weight: bold }
+DIV.qindex {
+	width: 100%;
+	background-color: #eeeeff;
+	border: 1px solid #b0b0b0;
+	text-align: center;
+	margin: 2px;
+	padding: 2px;
+	line-height: 140%;
+}
+DIV.nav {
+	width: 100%;
+	background-color: #eeeeff;
+	border: 1px solid #b0b0b0;
+	text-align: center;
+	margin: 2px;
+	padding: 2px;
+	line-height: 140%;
+}
+DIV.navtab {
+       background-color: #eeeeff;
+       border: 1px solid #b0b0b0;
+       text-align: center;
+       margin: 2px;
+       margin-right: 15px;
+       padding: 2px;
+}
+TD.navtab {
+       font-size: 70%;
+}
+A.qindex {
+       text-decoration: none;
+       font-weight: bold;
+       color: #1A419D;
+}
+A.qindex:visited {
+       text-decoration: none;
+       font-weight: bold;
+       color: #1A419D
+}
+A.qindex:hover {
+	text-decoration: none;
+	background-color: #ddddff;
+}
+A.qindexHL {
+	text-decoration: none;
+	font-weight: bold;
+	background-color: #6666cc;
+	color: #ffffff;
+	border: 1px double #9295C2;
+}
+A.qindexHL:hover {
+	text-decoration: none;
+	background-color: #6666cc;
+	color: #ffffff;
+}
+A.qindexHL:visited { 
+ text-decoration: none; background-color: #6666cc; color: #ffffff }
+A.el { text-decoration: none; font-weight: bold }
+A.elRef { font-weight: bold }
+A.code:link { text-decoration: none; font-weight: normal; color: #0000FF}
+A.code:visited { text-decoration: none; font-weight: normal; color: #0000FF}
+A.codeRef:link { font-weight: normal; color: #0000FF}
+A.codeRef:visited { font-weight: normal; color: #0000FF}
+A:hover { text-decoration: none; background-color: #f2f2ff }
+DL.el { margin-left: -1cm }
+.fragment {
+       font-family: Fixed, monospace;
+       font-size: 95%;
+}
+PRE.fragment {
+	border: 1px solid #CCCCCC;
+	background-color: #f5f5f5;
+	margin-top: 4px;
+	margin-bottom: 4px;
+	margin-left: 2px;
+	margin-right: 8px;
+	padding-left: 6px;
+	padding-right: 6px;
+	padding-top: 4px;
+	padding-bottom: 4px;
+}
+DIV.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px }
+TD.md { background-color: #F4F4FB; font-weight: bold; }
+TD.mdPrefix {
+       background-color: #F4F4FB;
+       color: #606060;
+	font-size: 80%;
+}
+TD.mdname1 { background-color: #F4F4FB; font-weight: bold; color: #602020; }
+TD.mdname { background-color: #F4F4FB; font-weight: bold; color: #602020; width: 600px; }
+DIV.groupHeader {
+       margin-left: 16px;
+       margin-top: 12px;
+       margin-bottom: 6px;
+       font-weight: bold;
+}
+DIV.groupText { margin-left: 16px; font-style: italic; font-size: 90% }
+BODY {
+	background: white;
+	color: black;
+	margin-right: 20px;
+	margin-left: 20px;
+}
+TD.indexkey {
+	background-color: #eeeeff;
+	font-weight: bold;
+	padding-right  : 10px;
+	padding-top    : 2px;
+	padding-left   : 10px;
+	padding-bottom : 2px;
+	margin-left    : 0px;
+	margin-right   : 0px;
+	margin-top     : 2px;
+	margin-bottom  : 2px;
+	border: 1px solid #CCCCCC;
+}
+TD.indexvalue {
+	background-color: #eeeeff;
+	font-style: italic;
+	padding-right  : 10px;
+	padding-top    : 2px;
+	padding-left   : 10px;
+	padding-bottom : 2px;
+	margin-left    : 0px;
+	margin-right   : 0px;
+	margin-top     : 2px;
+	margin-bottom  : 2px;
+	border: 1px solid #CCCCCC;
+}
+TR.memlist {
+   background-color: #f0f0f0; 
+}
+P.formulaDsp { text-align: center; }
+IMG.formulaDsp { }
+IMG.formulaInl { vertical-align: middle; }
+SPAN.keyword       { color: #008000 }
+SPAN.keywordtype   { color: #604020 }
+SPAN.keywordflow   { color: #e08000 }
+SPAN.comment       { color: #800000 }
+SPAN.preprocessor  { color: #806020 }
+SPAN.stringliteral { color: #002080 }
+SPAN.charliteral   { color: #008080 }
+.mdTable {
+	border: 1px solid #868686;
+	background-color: #F4F4FB;
+}
+.mdRow {
+	padding: 8px 10px;
+}
+.mdescLeft {
+       padding: 0px 8px 4px 8px;
+	font-size: 80%;
+	font-style: italic;
+	background-color: #FAFAFA;
+	border-top: 1px none #E0E0E0;
+	border-right: 1px none #E0E0E0;
+	border-bottom: 1px none #E0E0E0;
+	border-left: 1px none #E0E0E0;
+	margin: 0px;
+}
+.mdescRight {
+       padding: 0px 8px 4px 8px;
+	font-size: 80%;
+	font-style: italic;
+	background-color: #FAFAFA;
+	border-top: 1px none #E0E0E0;
+	border-right: 1px none #E0E0E0;
+	border-bottom: 1px none #E0E0E0;
+	border-left: 1px none #E0E0E0;
+	margin: 0px;
+}
+.memItemLeft {
+	padding: 1px 0px 0px 8px;
+	margin: 4px;
+	border-top-width: 1px;
+	border-right-width: 1px;
+	border-bottom-width: 1px;
+	border-left-width: 1px;
+	border-top-color: #E0E0E0;
+	border-right-color: #E0E0E0;
+	border-bottom-color: #E0E0E0;
+	border-left-color: #E0E0E0;
+	border-top-style: solid;
+	border-right-style: none;
+	border-bottom-style: none;
+	border-left-style: none;
+	background-color: #FAFAFA;
+	font-size: 80%;
+}
+.memItemRight {
+	padding: 1px 8px 0px 8px;
+	margin: 4px;
+	border-top-width: 1px;
+	border-right-width: 1px;
+	border-bottom-width: 1px;
+	border-left-width: 1px;
+	border-top-color: #E0E0E0;
+	border-right-color: #E0E0E0;
+	border-bottom-color: #E0E0E0;
+	border-left-color: #E0E0E0;
+	border-top-style: solid;
+	border-right-style: none;
+	border-bottom-style: none;
+	border-left-style: none;
+	background-color: #FAFAFA;
+	font-size: 80%;
+}
+.memTemplItemLeft {
+	padding: 1px 0px 0px 8px;
+	margin: 4px;
+	border-top-width: 1px;
+	border-right-width: 1px;
+	border-bottom-width: 1px;
+	border-left-width: 1px;
+	border-top-color: #E0E0E0;
+	border-right-color: #E0E0E0;
+	border-bottom-color: #E0E0E0;
+	border-left-color: #E0E0E0;
+	border-top-style: none;
+	border-right-style: none;
+	border-bottom-style: none;
+	border-left-style: none;
+	background-color: #FAFAFA;
+	font-size: 80%;
+}
+.memTemplItemRight {
+	padding: 1px 8px 0px 8px;
+	margin: 4px;
+	border-top-width: 1px;
+	border-right-width: 1px;
+	border-bottom-width: 1px;
+	border-left-width: 1px;
+	border-top-color: #E0E0E0;
+	border-right-color: #E0E0E0;
+	border-bottom-color: #E0E0E0;
+	border-left-color: #E0E0E0;
+	border-top-style: none;
+	border-right-style: none;
+	border-bottom-style: none;
+	border-left-style: none;
+	background-color: #FAFAFA;
+	font-size: 80%;
+}
+.memTemplParams {
+	padding: 1px 0px 0px 8px;
+	margin: 4px;
+	border-top-width: 1px;
+	border-right-width: 1px;
+	border-bottom-width: 1px;
+	border-left-width: 1px;
+	border-top-color: #E0E0E0;
+	border-right-color: #E0E0E0;
+	border-bottom-color: #E0E0E0;
+	border-left-color: #E0E0E0;
+	border-top-style: solid;
+	border-right-style: none;
+	border-bottom-style: none;
+	border-left-style: none;
+       color: #606060;
+	background-color: #FAFAFA;
+	font-size: 80%;
+}
+.search     { color: #003399;
+              font-weight: bold;
+}
+FORM.search {
+              margin-bottom: 0px;
+              margin-top: 0px;
+}
+INPUT.search { font-size: 75%;
+               color: #000080;
+               font-weight: normal;
+               background-color: #eeeeff;
+}
+TD.tiny      { font-size: 75%;
+}
+a {
+	color: #252E78;
+}
+a:visited {
+	color: #3D2185;
+}
+.dirtab { padding: 4px;
+          border-collapse: collapse;
+          border: 1px solid #b0b0b0;
+}
+TH.dirtab { background: #eeeeff;
+            font-weight: bold;
+}
+HR { height: 1px;
+     border: none;
+     border-top: 1px solid black;
+}
+
+/* 
+ * LLVM Modifications.
+ * Note: Everything above here is generated with "doxygen -w htlm" command. See
+ * "doxygen --help" for details. What follows are CSS overrides for LLVM 
+ * specific formatting. We want to keep the above so it can be replaced with
+ * subsequent doxygen upgrades.
+ */
+
+.footer {
+        font-size: 80%;
+        font-weight: bold;
+        text-align: center;
+        vertical-align: middle;
+}
+.title {
+  font-size: 25pt; 
+  color: black; background: url("http://llvm.org/img/lines.gif");
+  font-weight: bold;
+  border-width: 1px;
+  border-style: solid none solid none;
+  text-align: center;
+  vertical-align: middle;
+  padding-left: 8pt;
+  padding-top: 1px;
+  padding-bottom: 2px
+}
+A:link {
+        cursor: pointer;
+        text-decoration: none;
+        font-weight: bolder;
+}
+A:visited {
+        cursor: pointer;
+        text-decoration: underline;
+        font-weight: bolder;
+}
+A:hover {
+        cursor: pointer;
+        text-decoration: underline;
+        font-weight: bolder;
+}
+A:active {
+        cursor: pointer;
+        text-decoration: underline;
+        font-weight: bolder;
+        font-style: italic;
+}
+H1 {
+ text-align: center;
+ font-size: 140%;
+ font-weight: bold;
+}
+H2 {
+ font-size: 120%;
+ font-style: italic;
+}
+H3 {
+ font-size: 100%;
+}
+A.qindex {}
+A.qindexRef {}
+A.el { text-decoration: none; font-weight: bold }
+A.elRef { font-weight: bold }
+A.code { text-decoration: none; font-weight: normal; color: #4444ee }
+A.codeRef { font-weight: normal; color: #4444ee }
diff --git a/docs/doxygen.footer b/docs/doxygen.footer
new file mode 100644
index 0000000..524e9a2
--- /dev/null
+++ b/docs/doxygen.footer
@@ -0,0 +1,10 @@
+<hr>
+<p class="footer">
+Generated on $datetime by <a href="http://www.doxygen.org">Doxygen 
+$doxygenversion</a>.</p>
+
+<p class="footer">
+See the <a href="http://clang.llvm.org">Main Clang Web Page</a> for more 
+information.</p>
+</body>
+</html>
diff --git a/docs/doxygen.header b/docs/doxygen.header
new file mode 100644
index 0000000..bea5137
--- /dev/null
+++ b/docs/doxygen.header
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html><head>
+<meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1"/>
+<meta name="keywords" content="clang,LLVM,Low Level Virtual Machine,C,C++,doxygen,API,frontend,documentation"/>
+<meta name="description" content="C++ source code API documentation for clang."/>
+<title>clang: $title</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head><body>
+<p class="title">clang API Documentation</p>
diff --git a/docs/doxygen.intro b/docs/doxygen.intro
new file mode 100644
index 0000000..accab72
--- /dev/null
+++ b/docs/doxygen.intro
@@ -0,0 +1,15 @@
+/// @mainpage clang
+///
+/// @section main_intro Introduction
+/// Welcome to the clang project.
+///
+/// This documentation describes the @b internal software that makes 
+/// up clang, not the @b external use of clang. There are no instructions
+/// here on how to use clang, only the APIs that make up the software. For 
+/// usage instructions, please see the programmer's guide or reference 
+/// manual.
+///
+/// @section main_caveat Caveat 
+/// This documentation is generated directly from the source code with doxygen. 
+/// Since clang is constantly under active development, what you're about to
+/// read is out of date!
diff --git a/docs/index.html b/docs/index.html
new file mode 100644
index 0000000..d741b68
--- /dev/null
+++ b/docs/index.html
@@ -0,0 +1,4 @@
+<title>'clang' C frontend documentation</title>
+
+None yet, sorry :(
+
diff --git a/docs/libIndex.html b/docs/libIndex.html
new file mode 100644
index 0000000..e722ee1
--- /dev/null
+++ b/docs/libIndex.html
@@ -0,0 +1,267 @@
+<html>
+<head>
+  <title>The Index Library</title>
+  <link type="text/css" rel="stylesheet" href="../menu.css" />
+  <link type="text/css" rel="stylesheet" href="../content.css" />
+  <style type="text/css">
+    td {
+    vertical-align: top;
+    }
+  </style>
+</head>
+
+<body>
+
+<!--#include virtual="../menu.html.incl"-->
+
+<div id="content">
+
+<h1>The Index Library</h1>
+
+  <p><b>Table of Contents</b></p>
+  <ul>
+    <li><a href="#philosophy">Design Philosophy</a></li>
+    <li><a href="#classes">Classes</a>
+      <ul>
+        <li><a href="#entity">Entity</a></li>
+        <li><a href="#astlocation">ASTLocation</a></li>
+        <li><a href="#declreferencemap">DeclReferenceMap</a></li>
+      </ul>
+    </li>
+    <li><a href="#functions">Functions</a>
+      <ul>
+        <li><a href="#resolveloc">ResolveLocationInAST</a></li>
+      </ul>
+    </li>
+    <li><a href="#astfiles">AST Files</a></li>
+    <li><a href="#indextest">index-test tool</a>
+      <ul>
+        <li><a href="#indextestusage">Usage</a></li>
+        <li><a href="#indextestexamples">Examples</a></li>
+      </ul>
+    </li>
+</ul>
+    
+<h2 id="philosophy">Design Philosophy</h2>
+  
+<p> The Index library is meant to provide the basic infrastructure for
+ cross-translation-unit analysis and is primarily focused on indexing
+  related functionality. It provides an API for clients that need to
+ accurately map the AST nodes of the ASTContext to the locations in the source files.
+It also allows them to analyze information across multiple translation units.</p>
+
+<p>As a "general rule", ASTContexts are considered the primary source of
+information that a client wants about a translation unit. There will be no such class as an
+ "indexing database" that stores, for example, source locations of identifiers separately from ASTContext.
+All the information that a client needs from a translation unit will be extracted from the ASTContext.</p>
+
+<h2 id="classes">Classes</h2>
+
+<h3 id="entity">Entity</h3>
+
+<p>To be able to reason about semantically the same Decls that are contained in multiple ASTContexts, the 'Entity' class was introduced.
+An Entity is an ASTContext-independent "token" that can be created from a Decl (and a typename in the future) with
+the purpose to "resolve" it into a Decl belonging to another ASTContext. Some examples to make the concept of Entities more clear:</p>
+
+<p>
+t1.c:
+<pre class="code_example">
+void foo(void);
+void bar(void);
+</pre>
+</p>
+
+<p>
+t2.c:
+<pre class="code_example">
+void foo(void) {
+}
+</pre>
+</p>
+
+<p>
+Translation unit <code>t1.c</code> contains 2 Entities <code>foo</code> and <code>bar</code>, while <code>t2.c</code> contains 1 Entity <code>foo</code>.
+Entities are uniqued in such a way that the Entity* pointer for <code>t1.c/foo</code> is the same as the Entity* pointer for <code>t2.c/foo</code>.
+An Entity doesn't convey any information about the declaration, it is more like an opaque pointer used only to get the
+associated Decl out of an ASTContext so that the actual information for the declaration can be accessed.
+Another important aspect of Entities is that they can only be created/associated for declarations that are visible outside the
+translation unit. This means that for:
+</p>
+<p>
+t3.c:
+<pre class="code_example">
+static void foo(void);
+</pre>
+</p>
+<p>
+there can be no Entity (if you ask for the Entity* of the static function <code>foo</code> you'll get a null pointer).
+This is for 2 reasons:
+<ul>
+<li>To preserve the invariant that the same Entity* pointers refer to the same semantic Decls.
+   In the above example <code>t1.c/foo</code> and <code>t2.c/foo</code> are the same, while <code>t3.c/foo</code> is different.</li>
+<li>The purpose of Entity is to get the same semantic Decl from multiple ASTContexts. For a Decl that is not visible
+   outside of its own translation unit, you don't need an Entity since it won't appear in another ASTContext.</li>
+</ul>   
+</p>
+   
+<h3 id="astlocation">ASTLocation</h3>
+
+Encapsulates a "point" in the AST tree of the ASTContext.
+It represents either a Decl*, or a Stmt* along with its immediate Decl* parent.
+An example for its usage is that libIndex will provide the references of <code>foo</code> in the form of ASTLocations,
+"pointing" at the expressions that reference <code>foo</code>.
+
+<h3 id="declreferencemap">DeclReferenceMap</h3>
+
+Accepts an ASTContext and creates a mapping from NamedDecls to the ASTLocations that reference them (in the same ASTContext).
+
+<h2 id="functions">Functions</h2>
+
+<h3 id="resolveloc">ResolveLocationInAST</h3>
+
+A function that accepts an ASTContext and a SourceLocation which it resolves into an ASTLocation.
+
+<h2 id="astfiles">AST Files</h2>
+
+The precompiled headers implementation of clang (<a href="http://clang.llvm.org/docs/PCHInternals.html">PCH</a>) is ideal for storing an ASTContext in a compact form that
+will be loaded later for AST analysis. An "AST file" refers to a translation unit that was "compiled" into a precompiled header file.
+
+<h2 id="indextest">index-test tool</h2>
+
+<h3 id="indextestusage">Usage</h3>
+
+A command-line tool that exercises the libIndex API, useful for testing its features.
+As input it accepts multiple AST files (representing multiple translation units) and a few options:
+
+<p>
+<pre class="code_example">
+   -point-at  [file:line:column]
+</pre>
+Resolves a [file:line:column] triplet into a ASTLocation from the first AST file. If no other option is specified, it prints the ASTLocation.
+It also prints a declaration's associated doxygen comment, if one is available.
+</p>
+
+<p>
+<pre class="code_example">
+   -print-refs
+</pre>
+Prints the ASTLocations that reference the declaration that was resolved out of the [file:line:column] triplet
+</p>
+
+<p>
+<pre class="code_example">
+   -print-defs
+</pre>
+Prints the ASTLocations that define the resolved declaration
+</p>
+
+<p>
+<pre class="code_example">
+   -print-decls
+</pre>
+Prints the ASTLocations that declare the resolved declaration
+</p>
+
+<h3 id="indextestexamples">Examples</h3>
+
+<p>
+Here's an example of using index-test:
+</p>
+
+<p>
+We have 3 files,
+</p>
+
+<p>
+foo.h:
+<pre class="code_example">
+extern int global_var;
+
+void foo_func(int param1);
+void bar_func(void);
+</pre>
+
+t1.c:
+<pre class="code_example">
+#include "foo.h"
+
+void foo_func(int param1) {
+  int local_var = global_var;
+  for (int for_var = 100; for_var < 500; ++for_var) {
+    local_var = param1 + for_var;
+  }
+  bar_func();
+}
+</pre>
+
+t2.c:
+<pre class="code_example">
+#include "foo.h"
+
+int global_var = 10;
+
+void bar_func(void) {
+  global_var += 100;
+  foo_func(global_var);
+}
+</pre>
+</p>
+
+<p>
+You first get AST files out of <code>t1.c</code> and <code>t2.c</code>:
+
+<pre class="code_example">
+$ clang -emit-ast t1.c -o t1.ast
+$ clang -emit-ast t2.c -o t2.ast
+</pre>
+</p>
+
+<p>
+Find the ASTLocation under this position of <code>t1.c</code>:
+<pre class="code_example">
+[...]
+void foo_func(int param1) {
+  int local_var = global_var;
+                      ^
+[...]
+</pre>
+
+<pre class="code_example">
+$ index-test t1.ast -point-at t1.c:4:23
+> [Decl: Var local_var | Stmt: DeclRefExpr global_var] &lt;t1.c:4:19, t1.c:4:19>
+</pre>
+</p>
+
+<p>
+Find the declaration:
+
+<pre class="code_example">
+$ index-test t1.ast -point-at t1.c:4:23 -print-decls
+> [Decl: Var global_var] &lt;foo.h:1:12, foo.h:1:12>
+</pre>
+</p>
+
+<p>
+Find the references:
+
+<pre class="code_example">
+$ index-test t1.ast t2.ast -point-at t1.c:4:23 -print-refs
+> [Decl: Var local_var | Stmt: DeclRefExpr global_var] &lt;t1.c:4:19, t1.c:4:19>
+> [Decl: Function bar_func | Stmt: DeclRefExpr global_var] &lt;t2.c:6:3, t2.c:6:3>
+> [Decl: Function bar_func | Stmt: DeclRefExpr global_var] &lt;t2.c:7:12, t2.c:7:12>
+</pre>
+</p>
+
+<p>
+Find definitions:
+
+<pre class="code_example">
+$ index-test t1.ast t2.ast -point-at t1.c:4:23 -print-defs
+> [Decl: Var global_var] &lt;t2.c:3:5, t2.c:3:18>
+</pre>
+</p>
+
+</div>
+
+</body>
+</html>
diff --git a/docs/tools/Makefile b/docs/tools/Makefile
new file mode 100644
index 0000000..91bc447
--- /dev/null
+++ b/docs/tools/Makefile
@@ -0,0 +1,115 @@
+##===- docs/tools/Makefile ---------------------------------*- Makefile -*-===##
+# 
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+# 
+##===----------------------------------------------------------------------===##
+
+ifdef BUILD_FOR_WEBSITE
+
+# FIXME: This was copied from the CommandGuide makefile. Figure out
+# how to get this stuff on the website.
+
+# This special case is for keeping the CommandGuide on the LLVM web site
+# up to date automatically as the documents are checked in. It must build
+# the POD files to HTML only and keep them in the src directories. It must also
+# build in an unconfigured tree, hence the ifdef. To use this, run
+# make -s BUILD_FOR_WEBSITE=1 inside the cvs commit script.
+SRC_DOC_DIR=
+DST_HTML_DIR=html/
+DST_MAN_DIR=man/man1/
+DST_PS_DIR=ps/
+CLANG_VERSION := trunk
+
+# If we are in BUILD_FOR_WEBSITE mode, default to the all target.
+all:: html man ps
+
+clean:
+	rm -f pod2htm*.*~~ $(HTML) $(MAN) $(PS)
+
+# To create other directories, as needed, and timestamp their creation
+%/.dir:
+	-mkdir $* > /dev/null
+	date > $@
+
+else
+
+# Otherwise, if not in BUILD_FOR_WEBSITE mode, use the project info.
+LEVEL := ../../../..
+include $(LEVEL)/Makefile.common
+
+CLANG_VERSION := $(shell cat $(PROJ_SRC_DIR)/../../VER)
+
+SRC_DOC_DIR=$(PROJ_SRC_DIR)/
+DST_HTML_DIR=$(PROJ_OBJ_DIR)/
+DST_MAN_DIR=$(PROJ_OBJ_DIR)/
+DST_PS_DIR=$(PROJ_OBJ_DIR)/
+
+endif
+
+
+POD  := $(wildcard $(SRC_DOC_DIR)*.pod)
+HTML := $(patsubst $(SRC_DOC_DIR)%.pod, $(DST_HTML_DIR)%.html, $(POD))
+MAN  := $(patsubst $(SRC_DOC_DIR)%.pod, $(DST_MAN_DIR)%.1, $(POD))
+PS   := $(patsubst $(SRC_DOC_DIR)%.pod, $(DST_PS_DIR)%.ps, $(POD))
+
+ifdef ONLY_MAN_DOCS
+INSTALL_TARGETS := install-man
+else
+INSTALL_TARGETS := install-html install-man install-ps
+endif
+
+.SUFFIXES:
+.SUFFIXES: .html .pod .1 .ps
+
+$(DST_HTML_DIR)%.html: %.pod $(DST_HTML_DIR)/.dir
+	pod2html --css=manpage.css --htmlroot=. \
+	  --podpath=. --infile=$< --outfile=$@ --title=$*
+
+$(DST_MAN_DIR)%.1: %.pod $(DST_MAN_DIR)/.dir
+	pod2man --release "clang $(CLANG_VERSION)" --center="Clang Tools Documentation" $< $@
+
+$(DST_PS_DIR)%.ps: $(DST_MAN_DIR)%.1 $(DST_PS_DIR)/.dir
+	groff -Tps -man $< > $@
+
+
+html: $(HTML)
+man: $(MAN)
+ps: $(PS)
+
+EXTRA_DIST := $(POD)
+
+clean-local::
+	$(Verb) $(RM) -f pod2htm*.*~~ $(HTML) $(MAN) $(PS)
+
+HTML_DIR := $(DESTDIR)$(PROJ_docsdir)/html/clang
+MAN_DIR  := $(DESTDIR)$(PROJ_mandir)/man1
+PS_DIR   := $(DESTDIR)$(PROJ_docsdir)/ps
+
+install-html:: $(HTML)
+	$(Echo) Installing HTML Clang Tools Documentation
+	$(Verb) $(MKDIR) $(HTML_DIR)
+	$(Verb) $(DataInstall) $(HTML) $(HTML_DIR)
+	$(Verb) $(DataInstall) $(PROJ_SRC_DIR)/manpage.css $(HTML_DIR)
+
+install-man:: $(MAN)
+	$(Echo) Installing MAN Clang Tools Documentation
+	$(Verb) $(MKDIR) $(MAN_DIR)
+	$(Verb) $(DataInstall) $(MAN) $(MAN_DIR)
+
+install-ps:: $(PS)
+	$(Echo) Installing PS Clang Tools Documentation
+	$(Verb) $(MKDIR) $(PS_DIR)
+	$(Verb) $(DataInstall) $(PS) $(PS_DIR)
+
+install-local:: $(INSTALL_TARGETS)
+
+uninstall-local::
+	$(Echo) Uninstalling Clang Tools Documentation
+	$(Verb) $(RM) -rf $(HTML_DIR) $(MAN_DIR) $(PS_DIR)
+
+printvars::
+	$(Echo) "POD            : " '$(POD)'
+	$(Echo) "HTML           : " '$(HTML)'
diff --git a/docs/tools/clang.pod b/docs/tools/clang.pod
new file mode 100644
index 0000000..42cf8fa
--- /dev/null
+++ b/docs/tools/clang.pod
@@ -0,0 +1,518 @@
+=pod
+
+=head1 NAME
+
+clang - the Clang C and Objective-C compiler
+
+=head1 SYNOPSIS
+
+B<clang> [B<-c>|B<-S>|B<-E>] B<-std=>I<standard> B<-g>
+  [B<-O0>|B<-O1>|B<-O2>|B<-Os>|B<-O3>|B<-O4>]
+  B<-W>I<warnings...> B<-pedantic>
+  B<-I>I<dir...> B<-L>I<dir...>
+  B<-D>I<macro[=defn]>
+  B<-f>I<feature-option...>
+  B<-m>I<machine-option...>
+  B<-o> I<output-file>
+  I<input-filenames>
+
+=head1 DESCRIPTION
+
+B<clang> is a C and Objective-C compiler which encompasses preprocessing,
+parsing, optimization, code generation, assembly, and linking.  Depending on
+which high-level mode setting is passed, Clang will stop before doing a full
+link.  While Clang is highly integrated, it is important to understand the
+stages of compilation, to understand how to invoke it.  These stages are:
+
+=over
+
+=item B<Driver>
+
+The B<clang> executable is actually a small driver which controls the overall
+execution of other tools such as the compiler, assembler and linker.  Typically
+you do not need to interact with the driver, but you transparently use it to run
+the other tools.
+
+=item B<Preprocessing>
+
+This stage handles tokenization of the input source file, macro expansion,
+#include expansion and handling of other preprocessor directives.  The output of
+this stage is typically called a ".i" (for C) or ".mi" (for Objective-C) file.
+
+=item B<Parsing and Semantic Analysis>
+
+This stage parses the input file, translating preprocessor tokens into a parse
+tree.  Once in the form of a parser tree, it applies semantic analysis to compute
+types for expressions as well and determine whether the code is well formed. This
+stage is responsible for generating most of the compiler warnings as well as
+parse errors.  The output of this stage is an "Abstract Syntax Tree" (AST).
+
+=item B<Code Generation and Optimization>
+
+This stage translates an AST into low-level intermediate code (known as "LLVM
+IR") and ultimately to machine code (depending on the optimization level).  This
+phase is responsible for optimizing the generated code and handling
+target-specfic code generation.  The output of this stage is typically called a
+".s" file or "assembly" file.
+
+=item B<Assembler>
+
+This stage runs the target assembler to translate the output of the compiler
+into a target object file.  The output of this stage is typically called a ".o"
+file or "object" file.
+
+=item B<Linker>
+
+This stage runs the target linker to merge multiple object files into an
+executable or dynamic library.  The output of this stage is typically called an
+"a.out", ".dylib" or ".so" file.
+
+=back
+
+The Clang compiler supports a large number of options to control each of these
+stages.  In addition to compilation of code, Clang also supports other tools:
+
+B<Clang Static Analyzer>
+
+The Clang Static Analyzer is a tool that scans source code to try to find bugs
+though code analysis.  This tool uses many parts of Clang and is built into the
+same driver.
+
+
+=head1 OPTIONS
+
+=head2 Stage Selection Options
+
+=over
+
+=item B<-E>
+
+Run the preprocessor stage.
+
+=item B<-fsyntax-only>
+
+Run the preprocessor, parser and type checking stages.
+
+=item B<-S>
+
+Run the previous stages as well as LLVM generation and optimization stages and
+target-specific code generation, producing an assembly file.
+
+=item B<-c>
+
+Run all of the above, plus the assembler, generating a target ".o" object file.
+
+=item B<no stage selection option>
+
+If no stage selection option is specified, all stages above are run, and the
+linker is run to combine the results into an executable or shared library.
+
+=item B<--analyze>
+
+Run the Clang Static Analyzer.
+
+=back
+
+
+
+=head2 Language Selection and Mode Options
+
+=over
+
+=item B<-x> I<language>
+
+Treat subsequent input files as having type I<language>.
+
+=item B<-std>=I<language>
+
+Specify the language standard to compile for.
+
+=item B<-ansi>
+
+Same as B<-std=c89>.
+
+=item B<-ObjC++>
+
+Treat source input files as Objective-C++ inputs.
+
+=item B<-ObjC>
+
+Treat source input files as Objective-C inputs.
+
+=item B<-trigraphs>
+
+Enable trigraphs.
+
+=item B<-ffreestanding>
+
+Indicate that the file should be compiled for a freestanding, not a hosted,
+environment.
+
+=item B<-fno-builtin>
+
+Disable special handling and optimizations of builtin functions like strlen and
+malloc.
+
+=item B<-fmath-errno>
+
+Indicate that math functions should be treated as updating errno.
+
+=item B<-fpascal-strings>
+
+Enable support for Pascal-style strings with "\pfoo".
+
+=item B<-fms-extensions>
+
+Enable support for Microsoft extensions.
+
+=item B<-fwritable-strings>
+
+Make all string literals default to writable.  This disables uniquing of
+strings and other optimizations.
+
+=item B<-flax-vector-conversions>
+
+Allow loose type checking rules for implicit vector conversions.
+
+=item B<-fblocks>
+
+Enable the "Blocks" language feature.
+
+
+=item B<-fobjc-gc-only>
+
+Indicate that Objective-C code should be compiled in GC-only mode, which only
+works when Objective-C Garbage Collection is enabled.
+
+=item B<-fobjc-gc>
+
+Indicate that Objective-C code should be compiled in hybrid-GC mode, which works
+with both GC and non-GC mode.
+
+=back
+
+
+
+=head2 Target Selection Options
+
+Clang fully supports cross compilation as an inherent part of its design.
+Depending on how your version of Clang is configured, it may have support for
+a number of cross compilers, or may only support a native target.
+
+=over
+
+=item B<-arch> I<architecture>
+
+Specify the architecture to build for.
+
+=item B<-mmacosx-version-min>=I<version>
+
+When building for Mac OS/X, specify the minimum version supported by your
+application.
+
+=item B<-miphoneos-version-min>
+
+When building for iPhone OS, specify the minimum version supported by your
+application.
+
+
+=item B<-march>=I<cpu>
+
+Specify that Clang should generate code for a specific processor family member
+and later.  For example, if you specify -march=i486, the compiler is allowed to
+generate instructions that are valid on i486 and later processors, but which
+may not exist on earlier ones.
+
+=back
+
+
+=head2 Code Generation Options
+
+=over
+
+=item B<-O0> B<-O1> B<-O2> B<-Os> B<-O3> B<-O4>
+
+Specify which optimization level to use.  B<-O0> means "no optimization": this
+level compiles the fastest and generates the most debuggable code.  B<-O2> is a
+moderate level of optimization which enables most optimizations.  B<-Os> is like
+B<-O2> with extra optimizations to reduce code size.  B<-O3> is like B<-O2>,
+except that it enables optimizations that take longer to perform or that may
+generate larger code (in an attempt to make the program run faster).  On
+supported platforms, B<-O4> enables link-time optimization; object files are
+stored in the LLVM bitcode file format and whole program optimization is done at
+link time. B<-O1> is somewhere between B<-O0> and B<-O2>.
+
+=item B<-g>
+
+Generate debug information.  Note that Clang debug information works best at
+B<-O0>.  At higher optimization levels, only line number information is
+currently available.
+
+=item B<-fexceptions>
+
+Enable generation of unwind information, this allows exceptions to be thrown
+through Clang compiled stack frames.  This is on by default in x86-64.
+
+=item B<-ftrapv>
+
+Generate code to catch integer overflow errors.  Signed integer overflow is
+undefined in C, with this flag, extra code is generated to detect this and abort
+when it happens.
+
+
+=item B<-fvisibility>
+
+This flag sets the default visibility level.
+
+=item B<-fcommon>
+
+This flag specifies that variables without initializers get common linkage.  It
+can be disabled with B<-fno-common>.
+
+=item B<-flto> B<-emit-llvm>
+
+Generate output files in LLVM formats, suitable for link time optimization. When
+used with B<-S> this generates LLVM intermediate language assembly files,
+otherwise this generates LLVM bitcode format object files (which may be passed
+to the linker depending on the stage selection options).
+
+=cut
+
+##=item B<-fnext-runtime> B<-fobjc-nonfragile-abi> B<-fgnu-runtime>
+##These options specify which Objective-C runtime the code generator should
+##target.  FIXME: we don't want people poking these generally.
+
+=pod
+
+=back
+
+
+=head2 Driver Options
+
+=over
+
+=item B<-###>
+
+Print the commands to run for this compilation.
+
+=item B<--help>
+
+Display available options.
+
+=item B<-Qunused-arguments>
+
+Don't emit warning for unused driver arguments.
+
+=item B<-Wa,>I<args>
+
+Pass the comma separated arguments in I<args> to the assembler.
+
+=item B<-Wl,>I<args>
+
+Pass the comma separated arguments in I<args> to the linker.
+
+=item B<-Wp,>I<args>
+
+Pass the comma separated arguments in I<args> to the preprocessor.
+
+=item B<-Xanalyzer> I<arg>
+
+Pass I<arg> to the static analyzer.
+
+=item B<-Xassembler> I<arg>
+
+Pass I<arg> to the assembler.
+
+=item B<-Xclang> I<arg>
+
+Pass I<arg> to the clang compiler.
+
+=item B<-Xlinker> I<arg>
+
+Pass I<arg> to the linker.
+
+=item B<-Xpreprocessor> I<arg>
+
+Pass I<arg> to the preprocessor.
+
+=item B<-o> I<file>               
+
+Write output to I<file>.
+
+=item B<-print-file-name>=I<file>
+
+Print the full library path of I<file>.
+
+=item B<-print-libgcc-file-name>
+
+Print the library path for "libgcc.a".
+
+=item B<-print-prog-name>=I<name>
+
+Print the full program path of I<name>.
+
+=item B<-print-search-dirs>
+
+Print the paths used for finding libraries and programs.
+
+=item B<-save-temps>
+
+Save intermediate compilation results.
+
+=item B<-time>
+
+Time individual commands.
+
+=item B<-ftime-report>
+
+Print timing summary of each stage of compilation.
+
+=item B<-v>
+
+Show commands to run and use verbose output.
+
+=back
+
+
+=head2 Diagnostics Options
+
+=over
+
+=item B<-fshow-column>
+B<-fshow-source-location>
+B<-fcaret-diagnostics>
+B<-fdiagnostics-fixit-info>
+B<-fdiagnostics-print-source-range-info>
+B<-fprint-source-range-info>
+B<-fdiagnostics-show-option>
+B<-fmessage-length>
+
+These options control how Clang prints out information about diagnostics (errors
+and warnings).  Please see the Clang User's Manual for more information.
+
+=back
+
+
+=head2 Preprocessor Options
+
+=over
+
+=item B<-D>I<macroname=value>
+
+Adds an implicit #define into the predefines buffer which is read before the
+source file is preprocessed.
+
+=item B<-U>I<macroname>
+
+Adds an implicit #undef into the predefines buffer which is read before the
+source file is preprocessed.
+
+=item B<-include> I<filename>
+
+Adds an implicit #include into the predefines buffer which is read before the
+source file is preprocessed.
+
+=item B<-I>I<directory>
+
+Add the specified directory to the search path for include files.
+
+=item B<-F>I<directory>
+
+Add the specified directory to the search path for framework include files.
+
+=item B<-nostdinc>
+
+Do not search the standard system directories for include files.
+
+=item B<-nobuiltininc>
+
+Do not search clang's builtin directory for include files.
+
+=cut
+
+## TODO, but do we really want people using this stuff?
+#=item B<-idirafter>I<directory>
+#=item B<-iquote>I<directory>
+#=item B<-isystem>I<directory>
+#=item B<-iprefix>I<directory>
+#=item B<-iwithprefix>I<directory>
+#=item B<-iwithprefixbefore>I<directory>
+#=item B<-isysroot>
+
+=pod
+
+
+=back
+
+
+
+=cut
+
+### TODO someday.
+#=head2 Warning Control Options
+#=over
+#=back
+#=head2 Code Generation and Optimization Options
+#=over
+#=back
+#=head2 Assembler Options
+#=over
+#=back
+#=head2 Linker Options
+#=over
+#=back
+#=head2 Static Analyzer Options
+#=over
+#=back
+
+=pod
+
+
+=head1 ENVIRONMENT
+
+=over
+
+=item B<TMPDIR>, B<TEMP>, B<TMP>
+
+These environment variables are checked, in order, for the location to
+write temporary files used during the compilation process.
+
+=item B<CPATH>
+
+If this environment variable is present, it is treated as a delimited
+list of paths to be added to the default system include path list. The
+delimiter is the platform dependent delimitor, as used in the I<PATH>
+environment variable.
+
+Empty components in the environment variable are ignored.
+
+=item B<C_INCLUDE_PATH>, B<OBJC_INCLUDE_PATH>, B<CPLUS_INCLUDE_PATH>,
+B<OBJCPLUS_INCLUDE_PATH>
+
+These environment variables specify additional paths, as for CPATH,
+which are only used when processing the appropriate language.
+
+=item B<MACOSX_DEPLOYMENT_TARGET>
+
+If -mmacosx-version-min is unspecified, the default deployment target
+is read from this environment variable.  This option only affects darwin
+targets.
+
+=back
+
+=head1 BUGS
+
+Clang currently does not have C++ support, and this manual page is incomplete.
+To report bugs, please visit L<http://llvm.org/bugs/>.  Most bug reports should
+include preprocessed source files (use the B<-E> option) and the full output of 
+the compiler, along with information to reproduce.
+
+=head1 SEE ALSO
+
+ as(1), ld(1)
+
+=head1 AUTHOR
+
+Maintained by the Clang / LLVM Team (L<http://clang.llvm.org>).
+
+=cut
diff --git a/docs/tools/manpage.css b/docs/tools/manpage.css
new file mode 100644
index 0000000..c922564
--- /dev/null
+++ b/docs/tools/manpage.css
@@ -0,0 +1,256 @@
+/* Based on http://www.perldoc.com/css/perldoc.css */
+
+@import url("../llvm.css");
+
+body { font-family: Arial,Helvetica; }
+
+blockquote { margin: 10pt;  }
+
+h1, a { color: #336699; }
+
+
+/*** Top menu style ****/
+.mmenuon { 
+ font-family: Arial,Helvetica; font-weight: bold; text-decoration: none;
+ color: #ff6600; font-size: 10pt;
+}
+.mmenuoff { 
+ font-family: Arial,Helvetica; font-weight: bold; text-decoration: none;
+ color: #ffffff; font-size: 10pt;
+}	  
+.cpyright {
+ font-family: Arial,Helvetica; font-weight: bold; text-decoration: none;
+ color: #ffffff; font-size: xx-small;
+}
+.cpyrightText {
+ font-family: Arial,Helvetica; font-weight: bold; text-decoration: none;
+ color: #ffffff; font-size: xx-small;
+}
+.sections { 
+ font-family: Arial,Helvetica; font-weight: bold; text-decoration: none;
+ color: #336699; font-size: 11pt;
+}	 
+.dsections { 
+ font-family: Arial,Helvetica; font-weight: bold; text-decoration: none;
+ color: #336699; font-size: 12pt;
+}	
+.slink { 
+ font-family: Arial,Helvetica; font-weight: normal; text-decoration: none;
+ color: #000000; font-size: 9pt;
+}	 
+
+.slink2 { font-family: Arial,Helvetica; text-decoration: none; color: #336699; }	 
+
+.maintitle { 
+ font-family: Arial,Helvetica; font-weight: bold; text-decoration: none;
+ color: #336699; font-size: 18pt;
+}	 
+.dblArrow {
+ font-family: Arial,Helvetica; font-weight: bold; text-decoration: none;
+ color: #336699; font-size: small;
+}
+.menuSec {
+ font-family: Arial,Helvetica; font-weight: bold; text-decoration: none;
+ color: #336699; font-size: small;
+}
+
+.newstext {
+ font-family: Arial,Helvetica; font-size: small;
+}
+
+.linkmenu {
+ font-family: Arial,Helvetica; color: #000000; font-weight: bold;
+ text-decoration: none;
+}
+
+P {
+ font-family: Arial,Helvetica;
+}
+
+PRE {
+    font-size: 10pt;
+}
+.quote { 
+ font-family: Times; text-decoration: none;
+ color: #000000; font-size: 9pt; font-style: italic;
+}	
+.smstd { font-family: Arial,Helvetica; color: #000000; font-size: x-small; } 
+.std { font-family: Arial,Helvetica; color: #000000; } 
+.meerkatTitle { 
+ font-family: sans-serif; font-size: x-small;  color: black;    }
+
+.meerkatDescription { font-family: sans-serif; font-size: 10pt; color: black }
+.meerkatCategory { 
+ font-family: sans-serif; font-size: 9pt; font-weight: bold; font-style: italic; 
+ color: brown; }
+.meerkatChannel { 
+ font-family: sans-serif; font-size: 9pt; font-style: italic; color: brown; }
+.meerkatDate { font-family: sans-serif; font-size: xx-small; color: #336699; }
+
+.tocTitle {
+ font-family: Arial,Helvetica; font-weight: bold; text-decoration: none;
+ color: #333333; font-size: 10pt;
+}
+
+.toc-item {
+ font-family: Arial,Helvetica; font-weight: bold; 
+ color: #336699; font-size: 10pt; text-decoration: underline;
+}
+
+.perlVersion {
+ font-family: Arial,Helvetica; font-weight: bold; 
+ color: #336699; font-size: 10pt; text-decoration: none;
+}
+
+.podTitle {
+ font-family: Arial,Helvetica; font-weight: bold; text-decoration: none;
+ color: #000000;
+}
+
+.docTitle {
+ font-family: Arial,Helvetica; font-weight: bold; text-decoration: none;
+ color: #000000; font-size: 10pt;
+}
+.dotDot {
+ font-family: Arial,Helvetica; font-weight: bold; 
+ color: #000000; font-size: 9pt;
+}
+
+.docSec {
+ font-family: Arial,Helvetica; font-weight: normal; 
+ color: #333333; font-size: 9pt;
+}
+.docVersion {
+ font-family: Arial,Helvetica; font-weight: bold; text-decoration: none;
+ color: #336699; font-size: 10pt;
+}
+
+.docSecs-on {
+ font-family: Arial,Helvetica; font-weight: normal; text-decoration: none;
+ color: #ff0000; font-size: 10pt;
+}
+.docSecs-off {
+ font-family: Arial,Helvetica; font-weight: normal; text-decoration: none;
+ color: #333333; font-size: 10pt;
+}
+
+h2 {
+ font-family: Arial,Helvetica; font-weight: bold; text-decoration: none;
+ color: #336699; font-size: medium;
+}
+h1 {
+ font-family: Verdana,Arial,Helvetica; font-weight: bold; text-decoration: none;
+ color: #336699; font-size: large;
+}
+
+DL {
+ font-family: Arial,Helvetica; font-weight: normal; text-decoration: none;
+ color: #333333; font-size: 10pt;
+}
+
+UL > LI > A {
+ font-family: Arial,Helvetica; font-weight: bold;
+ color: #336699; font-size: 10pt;
+}
+
+.moduleInfo {
+ font-family: Arial,Helvetica; font-weight: bold; text-decoration: none;
+ color: #333333; font-size: 11pt;
+}
+
+.moduleInfoSec {
+ font-family: Arial,Helvetica; font-weight: bold; text-decoration: none;
+ color: #336699; font-size: 10pt;
+}
+
+.moduleInfoVal {
+ font-family: Arial,Helvetica; font-weight: normal; text-decoration: underline;
+ color: #000000; font-size: 10pt;
+}
+
+.cpanNavTitle {
+ font-family: Arial,Helvetica; font-weight: bold; 
+ color: #ffffff; font-size: 10pt;
+}
+.cpanNavLetter {
+ font-family: Arial,Helvetica; font-weight: bold; text-decoration: none; 
+ color: #333333; font-size: 9pt;
+}
+.cpanCat {
+ font-family: Arial,Helvetica; font-weight: bold; text-decoration: none; 
+ color: #336699; font-size: 9pt;
+}
+
+.bttndrkblue-bkgd-top {
+	background-color: #225688;
+	background-image: url(/global/mvc_objects/images/bttndrkblue_bgtop.gif);
+}
+.bttndrkblue-bkgd-left {
+	background-color: #225688;
+	background-image: url(/global/mvc_objects/images/bttndrkblue_bgleft.gif);
+}
+.bttndrkblue-bkgd {
+	padding-top: 0px;
+	padding-bottom: 0px;
+	margin-bottom: 0px;
+	margin-top: 0px;
+	background-repeat: no-repeat;
+	background-color: #225688;
+	background-image: url(/global/mvc_objects/images/bttndrkblue_bgmiddle.gif);
+	vertical-align: top;
+}
+.bttndrkblue-bkgd-right {
+	background-color: #225688;
+	background-image: url(/global/mvc_objects/images/bttndrkblue_bgright.gif);
+}
+.bttndrkblue-bkgd-bottom {
+	background-color: #225688;
+	background-image: url(/global/mvc_objects/images/bttndrkblue_bgbottom.gif);
+}
+.bttndrkblue-text a {
+	color: #ffffff;
+	text-decoration: none;
+}
+a.bttndrkblue-text:hover {
+	color: #ffDD3C;
+	text-decoration: none;
+}
+.bg-ltblue {
+	background-color: #f0f5fa;
+} 
+
+.border-left-b {
+	background: #f0f5fa url(/i/corner-leftline.gif) repeat-y;
+} 
+
+.border-right-b {
+	background: #f0f5fa url(/i/corner-rightline.gif) repeat-y;
+} 
+
+.border-top-b {
+	background: #f0f5fa url(/i/corner-topline.gif) repeat-x;
+} 
+
+.border-bottom-b {
+	background: #f0f5fa url(/i/corner-botline.gif) repeat-x;
+} 
+
+.border-right-w {
+	background: #ffffff url(/i/corner-rightline.gif) repeat-y;
+} 
+
+.border-top-w {
+	background: #ffffff url(/i/corner-topline.gif) repeat-x;
+} 
+
+.border-bottom-w {
+	background: #ffffff url(/i/corner-botline.gif) repeat-x;
+} 
+
+.bg-white {
+	background-color: #ffffff;
+} 
+
+.border-left-w {
+	background: #ffffff url(/i/corner-leftline.gif) repeat-y;
+} 
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
new file mode 100644
index 0000000..d2738c6
--- /dev/null
+++ b/examples/CMakeLists.txt
@@ -0,0 +1,4 @@
+add_subdirectory(clang-interpreter)
+add_subdirectory(PrintFunctionNames)
+add_subdirectory(wpa)
+
diff --git a/examples/Makefile b/examples/Makefile
new file mode 100644
index 0000000..869197d
--- /dev/null
+++ b/examples/Makefile
@@ -0,0 +1,14 @@
+##===- examples/Makefile -----------------------------------*- Makefile -*-===##
+#
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../../..
+
+PARALLEL_DIRS := clang-interpreter PrintFunctionNames wpa
+
+include $(LEVEL)/Makefile.common
diff --git a/examples/PrintFunctionNames/CMakeLists.txt b/examples/PrintFunctionNames/CMakeLists.txt
new file mode 100644
index 0000000..49dd22a
--- /dev/null
+++ b/examples/PrintFunctionNames/CMakeLists.txt
@@ -0,0 +1,26 @@
+set(SHARED_LIBRARY TRUE)
+
+set(LLVM_NO_RTTI 1)
+
+set(LLVM_USED_LIBS
+  clangIndex
+  clangFrontend
+  clangDriver
+  clangSema
+  clangAnalysis
+  clangAST
+  clangParse
+  clangLex
+  clangBasic)
+
+set( LLVM_LINK_COMPONENTS
+  bitreader
+  mc
+  core
+  )
+
+add_clang_library(PrintFunctionNames PrintFunctionNames.cpp)
+
+set_target_properties(PrintFunctionNames
+  PROPERTIES
+  LINKER_LANGUAGE CXX)
diff --git a/examples/PrintFunctionNames/Makefile b/examples/PrintFunctionNames/Makefile
new file mode 100644
index 0000000..57d3ba9
--- /dev/null
+++ b/examples/PrintFunctionNames/Makefile
@@ -0,0 +1,27 @@
+##===- examples/PrintFunctionNames/Makefile ----------------*- Makefile -*-===##
+# 
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+# 
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../../../..
+LIBRARYNAME = PrintFunctionNames
+
+CPPFLAGS += -I$(PROJ_SRC_DIR)/../../include -I$(PROJ_OBJ_DIR)/../../include
+
+# Include this here so we can get the configuration of the targets that have
+# been configured for construction. We have to do this early so we can set up
+# LINK_COMPONENTS before including Makefile.rules
+include $(LEVEL)/Makefile.config
+
+LINK_LIBS_IN_SHARED = 1
+SHARED_LIBRARY = 1
+
+LINK_COMPONENTS := bitreader mc core
+USEDLIBS = clangIndex.a clangFrontend.a clangDriver.a clangSema.a \
+	   clangAnalysis.a clangAST.a clangParse.a clangLex.a clangBasic.a
+
+include $(LEVEL)/Makefile.common
diff --git a/examples/PrintFunctionNames/PrintFunctionNames.cpp b/examples/PrintFunctionNames/PrintFunctionNames.cpp
new file mode 100644
index 0000000..5b7b66a
--- /dev/null
+++ b/examples/PrintFunctionNames/PrintFunctionNames.cpp
@@ -0,0 +1,44 @@
+//===- PrintFunctionNames.cpp ---------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Example clang plugin which simply prints the names of all the top-level decls
+// in the input file.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/FrontendPluginRegistry.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/AST.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace clang;
+
+namespace {
+
+class PrintFunctionsConsumer : public ASTConsumer {
+public:
+  virtual void HandleTopLevelDecl(DeclGroupRef DG) {
+    for (DeclGroupRef::iterator i = DG.begin(), e = DG.end(); i != e; ++i) {
+      const Decl *D = *i;
+      if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
+        llvm::errs() << "top-level-decl: \"" << ND->getNameAsString() << "\"\n";
+    }
+  }
+}; 
+
+class PrintFunctionNamesAction : public ASTFrontendAction {
+protected:
+  ASTConsumer *CreateASTConsumer(CompilerInstance &CI, llvm::StringRef) {
+    return new PrintFunctionsConsumer();
+  }
+};
+
+}
+
+FrontendPluginRegistry::Add<PrintFunctionNamesAction>
+X("print-fns", "print function names");
diff --git a/examples/PrintFunctionNames/README.txt b/examples/PrintFunctionNames/README.txt
new file mode 100644
index 0000000..267865c
--- /dev/null
+++ b/examples/PrintFunctionNames/README.txt
@@ -0,0 +1,10 @@
+This is a simple example demonstrating how to use clang's facility for
+providing AST consumers using a plugin.
+
+You will probably need to build clang so that it exports all symbols (disable
+TOOL_NO_EXPORT in the tools/clang Makefile).
+
+Once the plugin is built, you can run it using:
+--
+$ clang -cc1 -load path/to/PrintFunctionNames.so -plugin print-fns some-input-file.c
+--
diff --git a/examples/clang-interpreter/CMakeLists.txt b/examples/clang-interpreter/CMakeLists.txt
new file mode 100644
index 0000000..0f63b5f
--- /dev/null
+++ b/examples/clang-interpreter/CMakeLists.txt
@@ -0,0 +1,30 @@
+set(LLVM_NO_RTTI 1)
+
+set(LLVM_USED_LIBS
+    clangFrontend
+    clangDriver
+    clangCodeGen
+    clangSema
+    clangChecker
+    clangAnalysis
+    clangRewrite
+    clangAST
+    clangParse
+    clangLex
+    clangBasic
+    )
+
+set(LLVM_LINK_COMPONENTS
+    jit
+    interpreter
+    nativecodegen
+    bitreader
+    bitwriter
+    ipo
+    selectiondag
+  )
+
+add_clang_executable(clang-interpreter
+  main.cpp
+  )
+add_dependencies(clang-interpreter clang-headers)
diff --git a/examples/clang-interpreter/Makefile b/examples/clang-interpreter/Makefile
new file mode 100644
index 0000000..fecc3f5
--- /dev/null
+++ b/examples/clang-interpreter/Makefile
@@ -0,0 +1,30 @@
+##===- examples/clang-interpreter/Makefile -----------------*- Makefile -*-===##
+#
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../../../..
+
+TOOLNAME = clang-interpreter
+CPPFLAGS += -I$(PROJ_SRC_DIR)/../../include -I$(PROJ_OBJ_DIR)/../../include
+NO_INSTALL = 1
+
+# No plugins, optimize startup time.
+TOOL_NO_EXPORTS = 1
+
+# Include this here so we can get the configuration of the targets that have
+# been configured for construction. We have to do this early so we can set up
+# LINK_COMPONENTS before including Makefile.rules
+include $(LEVEL)/Makefile.config
+
+LINK_COMPONENTS := jit interpreter nativecodegen bitreader bitwriter ipo \
+	selectiondag
+USEDLIBS = clangFrontend.a clangDriver.a clangCodeGen.a clangSema.a \
+           clangChecker.a clangAnalysis.a clangRewrite.a  clangAST.a \
+           clangParse.a clangLex.a clangBasic.a
+
+include $(LLVM_SRC_ROOT)/Makefile.rules
diff --git a/examples/clang-interpreter/README.txt b/examples/clang-interpreter/README.txt
new file mode 100644
index 0000000..7dd45fa
--- /dev/null
+++ b/examples/clang-interpreter/README.txt
@@ -0,0 +1,17 @@
+This is an example of Clang based interpreter, for executing standalone C
+programs.
+
+It demonstrates the following features:
+ 1. Parsing standard compiler command line arguments using the Driver library.
+
+ 2. Constructing a Clang compiler instance, using the appropriate arguments
+    derived in step #1.
+
+ 3. Invoking the Clang compiler to lex, parse, syntax check, and then generate
+    LLVM code.
+
+ 4. Use the LLVM JIT functionality to execute the final module.
+
+The implementation has many limitations and is not designed to be a full fledged
+C interpreter. It is designed to demonstrate a simple but functional use of the
+Clang compiler libraries.
diff --git a/examples/clang-interpreter/main.cpp b/examples/clang-interpreter/main.cpp
new file mode 100644
index 0000000..8623954
--- /dev/null
+++ b/examples/clang-interpreter/main.cpp
@@ -0,0 +1,155 @@
+//===-- examples/clang-interpreter/main.cpp - Clang C Interpreter Example -===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Driver/Compilation.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/Tool.h"
+#include "clang/Frontend/CodeGenAction.h"
+#include "clang/Frontend/CompilerInvocation.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Frontend/DiagnosticOptions.h"
+#include "clang/Frontend/FrontendDiagnostic.h"
+#include "clang/Frontend/TextDiagnosticPrinter.h"
+
+#include "llvm/LLVMContext.h"
+#include "llvm/Module.h"
+#include "llvm/Config/config.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/Config/config.h"
+#include "llvm/ExecutionEngine/ExecutionEngine.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/System/Host.h"
+#include "llvm/System/Path.h"
+#include "llvm/Target/TargetSelect.h"
+using namespace clang;
+using namespace clang::driver;
+
+llvm::sys::Path GetExecutablePath(const char *Argv0) {
+  // This just needs to be some symbol in the binary; C++ doesn't
+  // allow taking the address of ::main however.
+  void *MainAddr = (void*) (intptr_t) GetExecutablePath;
+  return llvm::sys::Path::GetMainExecutable(Argv0, MainAddr);
+}
+
+int Execute(llvm::Module *Mod, char * const *envp) {
+  llvm::InitializeNativeTarget();
+
+  std::string Error;
+  llvm::OwningPtr<llvm::ExecutionEngine> EE(
+    llvm::ExecutionEngine::createJIT(Mod, &Error));
+  if (!EE) {
+    llvm::errs() << "unable to make execution engine: " << Error << "\n";
+    return 255;
+  }
+
+  llvm::Function *EntryFn = Mod->getFunction("main");
+  if (!EntryFn) {
+    llvm::errs() << "'main' function not found in module.\n";
+    return 255;
+  }
+
+  // FIXME: Support passing arguments.
+  std::vector<std::string> Args;
+  Args.push_back(Mod->getModuleIdentifier());
+
+  return EE->runFunctionAsMain(EntryFn, Args, envp);
+}
+
+int main(int argc, const char **argv, char * const *envp) {
+  void *MainAddr = (void*) (intptr_t) GetExecutablePath;
+  llvm::sys::Path Path = GetExecutablePath(argv[0]);
+  TextDiagnosticPrinter DiagClient(llvm::errs(), DiagnosticOptions());
+
+  Diagnostic Diags(&DiagClient);
+  Driver TheDriver(Path.getBasename(), Path.getDirname(),
+                   llvm::sys::getHostTriple(),
+                   "a.out", /*IsProduction=*/false, /*CXXIsProduction=*/false,
+                   Diags);
+  TheDriver.setTitle("clang interpreter");
+
+  // FIXME: This is a hack to try to force the driver to do something we can
+  // recognize. We need to extend the driver library to support this use model
+  // (basically, exactly one input, and the operation mode is hard wired).
+  llvm::SmallVector<const char *, 16> Args(argv, argv + argc);
+  Args.push_back("-fsyntax-only");
+  llvm::OwningPtr<Compilation> C(TheDriver.BuildCompilation(Args.size(),
+                                                            Args.data()));
+  if (!C)
+    return 0;
+
+  // FIXME: This is copied from ASTUnit.cpp; simplify and eliminate.
+
+  // We expect to get back exactly one command job, if we didn't something
+  // failed. Extract that job from the compilation.
+  const driver::JobList &Jobs = C->getJobs();
+  if (Jobs.size() != 1 || !isa<driver::Command>(Jobs.begin())) {
+    llvm::SmallString<256> Msg;
+    llvm::raw_svector_ostream OS(Msg);
+    C->PrintJob(OS, C->getJobs(), "; ", true);
+    Diags.Report(diag::err_fe_expected_compiler_job) << OS.str();
+    return 1;
+  }
+
+  const driver::Command *Cmd = cast<driver::Command>(*Jobs.begin());
+  if (llvm::StringRef(Cmd->getCreator().getName()) != "clang") {
+    Diags.Report(diag::err_fe_expected_clang_command);
+    return 1;
+  }
+
+  // Initialize a compiler invocation object from the clang (-cc1) arguments.
+  const driver::ArgStringList &CCArgs = Cmd->getArguments();
+  llvm::OwningPtr<CompilerInvocation> CI(new CompilerInvocation);
+  CompilerInvocation::CreateFromArgs(*CI,
+                                     const_cast<const char **>(CCArgs.data()),
+                                     const_cast<const char **>(CCArgs.data()) +
+                                       CCArgs.size(),
+                                     Diags);
+
+  // Show the invocation, with -v.
+  if (CI->getHeaderSearchOpts().Verbose) {
+    llvm::errs() << "clang invocation:\n";
+    C->PrintJob(llvm::errs(), C->getJobs(), "\n", true);
+    llvm::errs() << "\n";
+  }
+
+  // FIXME: This is copied from cc1_main.cpp; simplify and eliminate.
+
+  // Create a compiler instance to handle the actual work.
+  CompilerInstance Clang;
+  Clang.setLLVMContext(new llvm::LLVMContext);
+  Clang.setInvocation(CI.take());
+
+  // Create the compilers actual diagnostics engine.
+  Clang.createDiagnostics(int(CCArgs.size()),const_cast<char**>(CCArgs.data()));
+  if (!Clang.hasDiagnostics())
+    return 1;
+
+  // Infer the builtin include path if unspecified.
+  if (Clang.getHeaderSearchOpts().UseBuiltinIncludes &&
+      Clang.getHeaderSearchOpts().ResourceDir.empty())
+    Clang.getHeaderSearchOpts().ResourceDir =
+      CompilerInvocation::GetResourcesPath(argv[0], MainAddr);
+
+  // Create and execute the frontend to generate an LLVM bitcode module.
+  llvm::OwningPtr<CodeGenAction> Act(new EmitLLVMOnlyAction());
+  if (!Clang.ExecuteAction(*Act))
+    return 1;
+
+  int Res = 255;
+  if (llvm::Module *Module = Act->takeModule())
+    Res = Execute(Module, envp);
+
+  // Shutdown.
+
+  llvm::llvm_shutdown();
+
+  return Res;
+}
diff --git a/examples/wpa/CMakeLists.txt b/examples/wpa/CMakeLists.txt
new file mode 100644
index 0000000..8d443d6
--- /dev/null
+++ b/examples/wpa/CMakeLists.txt
@@ -0,0 +1,23 @@
+set(LLVM_NO_RTTI 1)
+
+set(LLVM_USED_LIBS
+  clangIndex
+  clangFrontend
+  clangDriver
+  clangSema
+  clangAnalysis
+  clangAST
+  clangParse
+  clangLex
+  clangBasic)
+
+set( LLVM_LINK_COMPONENTS
+  bitreader
+  mc
+  core
+  )
+
+add_clang_executable(clang-wpa
+  clang-wpa.cpp
+  )
+add_dependencies(clang-wpa clang-headers)
diff --git a/examples/wpa/Makefile b/examples/wpa/Makefile
new file mode 100644
index 0000000..6b7f407
--- /dev/null
+++ b/examples/wpa/Makefile
@@ -0,0 +1,28 @@
+##===- examples/wpa/Makefile -------------------------------*- Makefile -*-===##
+#
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../../../..
+
+TOOLNAME = clang-wpa
+CPPFLAGS += -I$(PROJ_SRC_DIR)/../../include -I$(PROJ_OBJ_DIR)/../../include
+NO_INSTALL = 1
+
+# No plugins, optimize startup time.
+TOOL_NO_EXPORTS = 1
+
+# Include this here so we can get the configuration of the targets that have
+# been configured for construction. We have to do this early so we can set up
+# LINK_COMPONENTS before including Makefile.rules
+include $(LEVEL)/Makefile.config
+
+LINK_COMPONENTS := bitreader mc core
+USEDLIBS = clangIndex.a clangFrontend.a clangDriver.a clangSema.a \
+	   clangAnalysis.a clangAST.a clangParse.a clangLex.a clangBasic.a
+
+include $(LLVM_SRC_ROOT)/Makefile.rules
diff --git a/examples/wpa/clang-wpa.cpp b/examples/wpa/clang-wpa.cpp
new file mode 100644
index 0000000..b515e33
--- /dev/null
+++ b/examples/wpa/clang-wpa.cpp
@@ -0,0 +1,56 @@
+//===--- clang-wpa.cpp - clang whole program analyzer ---------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This tool reads a sequence of precompiled AST files, and do various
+// cross translation unit analyses.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Frontend/ASTUnit.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Index/CallGraph.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace clang;
+using namespace idx;
+
+static llvm::cl::list<std::string>
+InputFilenames(llvm::cl::Positional, llvm::cl::desc("<input AST files>"));
+
+int main(int argc, char **argv) {
+  llvm::cl::ParseCommandLineOptions(argc, argv, "clang-wpa");
+  FileManager FileMgr;
+  std::vector<ASTUnit*> ASTUnits;
+
+  if (InputFilenames.empty())
+    return 0;
+
+  DiagnosticOptions DiagOpts;
+  llvm::IntrusiveRefCntPtr<Diagnostic> Diags
+    = CompilerInstance::createDiagnostics(DiagOpts, argc, argv);
+  for (unsigned i = 0, e = InputFilenames.size(); i != e; ++i) {
+    const std::string &InFile = InputFilenames[i];
+    llvm::OwningPtr<ASTUnit> AST(ASTUnit::LoadFromPCHFile(InFile, Diags));
+    if (!AST)
+      return 1;
+
+    ASTUnits.push_back(AST.take());
+  }
+
+  llvm::OwningPtr<CallGraph> CG;
+  CG.reset(new CallGraph());
+
+  for (unsigned i = 0, e = ASTUnits.size(); i != e; ++i)
+    CG->addTU(ASTUnits[i]->getASTContext());
+
+  CG->ViewCallGraph();
+}
diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt
new file mode 100644
index 0000000..253a09b
--- /dev/null
+++ b/include/CMakeLists.txt
@@ -0,0 +1 @@
+add_subdirectory(clang)
diff --git a/include/Makefile b/include/Makefile
new file mode 100644
index 0000000..47daabc
--- /dev/null
+++ b/include/Makefile
@@ -0,0 +1,4 @@
+LEVEL = ../../..
+DIRS := clang
+
+include $(LEVEL)/Makefile.common
diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h
new file mode 100644
index 0000000..1bf5a46
--- /dev/null
+++ b/include/clang-c/Index.h
@@ -0,0 +1,1851 @@
+/*===-- clang-c/Index.h - Indexing Public C Interface -------------*- C -*-===*\
+|*                                                                            *|
+|*                     The LLVM Compiler Infrastructure                       *|
+|*                                                                            *|
+|* This file is distributed under the University of Illinois Open Source      *|
+|* License. See LICENSE.TXT for details.                                      *|
+|*                                                                            *|
+|*===----------------------------------------------------------------------===*|
+|*                                                                            *|
+|* This header provides a public inferface to a Clang library for extracting  *|
+|* high-level symbol information from source files without exposing the full  *|
+|* Clang C++ API.                                                             *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef CLANG_C_INDEX_H
+#define CLANG_C_INDEX_H
+
+#include <sys/stat.h>
+#include <time.h>
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* MSVC DLL import/export. */
+#ifdef _MSC_VER
+  #ifdef _CINDEX_LIB_
+    #define CINDEX_LINKAGE __declspec(dllexport)
+  #else
+    #define CINDEX_LINKAGE __declspec(dllimport)
+  #endif
+#else
+  #define CINDEX_LINKAGE
+#endif
+
+/** \defgroup CINDEX C Interface to Clang
+ *
+ * The C Interface to Clang provides a relatively small API that exposes
+ * facilities for parsing source code into an abstract syntax tree (AST),
+ * loading already-parsed ASTs, traversing the AST, associating
+ * physical source locations with elements within the AST, and other
+ * facilities that support Clang-based development tools.
+ *
+ * This C interface to Clang will never provide all of the information
+ * representation stored in Clang's C++ AST, nor should it: the intent is to
+ * maintain an API that is relatively stable from one release to the next,
+ * providing only the basic functionality needed to support development tools.
+ *
+ * To avoid namespace pollution, data types are prefixed with "CX" and
+ * functions are prefixed with "clang_".
+ *
+ * @{
+ */
+
+/**
+ * \brief An "index" that consists of a set of translation units that would
+ * typically be linked together into an executable or library.
+ */
+typedef void *CXIndex;
+
+/**
+ * \brief A single translation unit, which resides in an index.
+ */
+typedef void *CXTranslationUnit;  /* A translation unit instance. */
+
+/**
+ * \brief Opaque pointer representing client data that will be passed through
+ * to various callbacks and visitors.
+ */
+typedef void *CXClientData;
+
+/**
+ * \brief Provides the contents of a file that has not yet been saved to disk.
+ *
+ * Each CXUnsavedFile instance provides the name of a file on the
+ * system along with the current contents of that file that have not
+ * yet been saved to disk.
+ */
+struct CXUnsavedFile {
+  /**
+   * \brief The file whose contents have not yet been saved.
+   *
+   * This file must already exist in the file system.
+   */
+  const char *Filename;
+
+  /**
+   * \brief A buffer containing the unsaved contents of this file.
+   */
+  const char *Contents;
+
+  /**
+   * \brief The length of the unsaved contents of this buffer.
+   */
+  unsigned long Length;
+};
+
+/**
+ * \defgroup CINDEX_STRING String manipulation routines
+ *
+ * @{
+ */
+
+/**
+ * \brief A character string.
+ *
+ * The \c CXString type is used to return strings from the interface when
+ * the ownership of that string might different from one call to the next.
+ * Use \c clang_getCString() to retrieve the string data and, once finished
+ * with the string data, call \c clang_disposeString() to free the string.
+ */
+typedef struct {
+  const char *Spelling;
+  /* A 1 value indicates the clang_ indexing API needed to allocate the string
+     (and it must be freed by clang_disposeString()). */
+  int MustFreeString;
+} CXString;
+
+/**
+ * \brief Retrieve the character data associated with the given string.
+ */
+CINDEX_LINKAGE const char *clang_getCString(CXString string);
+
+/**
+ * \brief Free the given string,
+ */
+CINDEX_LINKAGE void clang_disposeString(CXString string);
+
+/**
+ * @}
+ */
+
+/**
+ * \brief clang_createIndex() provides a shared context for creating
+ * translation units. It provides two options:
+ *
+ * - excludeDeclarationsFromPCH: When non-zero, allows enumeration of "local"
+ * declarations (when loading any new translation units). A "local" declaration
+ * is one that belongs in the translation unit itself and not in a precompiled
+ * header that was used by the translation unit. If zero, all declarations
+ * will be enumerated.
+ *
+ * Here is an example:
+ *
+ *   // excludeDeclsFromPCH = 1, displayDiagnostics=1
+ *   Idx = clang_createIndex(1, 1);
+ *
+ *   // IndexTest.pch was produced with the following command:
+ *   // "clang -x c IndexTest.h -emit-ast -o IndexTest.pch"
+ *   TU = clang_createTranslationUnit(Idx, "IndexTest.pch");
+ *
+ *   // This will load all the symbols from 'IndexTest.pch'
+ *   clang_visitChildren(clang_getTranslationUnitCursor(TU),
+ *                       TranslationUnitVisitor, 0);
+ *   clang_disposeTranslationUnit(TU);
+ *
+ *   // This will load all the symbols from 'IndexTest.c', excluding symbols
+ *   // from 'IndexTest.pch'.
+ *   char *args[] = { "-Xclang", "-include-pch=IndexTest.pch" };
+ *   TU = clang_createTranslationUnitFromSourceFile(Idx, "IndexTest.c", 2, args,
+ *                                                  0, 0);
+ *   clang_visitChildren(clang_getTranslationUnitCursor(TU),
+ *                       TranslationUnitVisitor, 0);
+ *   clang_disposeTranslationUnit(TU);
+ *
+ * This process of creating the 'pch', loading it separately, and using it (via
+ * -include-pch) allows 'excludeDeclsFromPCH' to remove redundant callbacks
+ * (which gives the indexer the same performance benefit as the compiler).
+ */
+CINDEX_LINKAGE CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
+                                         int displayDiagnostics);
+
+/**
+ * \brief Destroy the given index.
+ *
+ * The index must not be destroyed until all of the translation units created
+ * within that index have been destroyed.
+ */
+CINDEX_LINKAGE void clang_disposeIndex(CXIndex index);
+
+/**
+ * \brief Request that AST's be generated externally for API calls which parse
+ * source code on the fly, e.g. \see createTranslationUnitFromSourceFile.
+ *
+ * Note: This is for debugging purposes only, and may be removed at a later
+ * date.
+ *
+ * \param index - The index to update.
+ * \param value - The new flag value.
+ */
+CINDEX_LINKAGE void clang_setUseExternalASTGeneration(CXIndex index,
+                                                      int value);
+/**
+ * \defgroup CINDEX_FILES File manipulation routines
+ *
+ * @{
+ */
+
+/**
+ * \brief A particular source file that is part of a translation unit.
+ */
+typedef void *CXFile;
+
+
+/**
+ * \brief Retrieve the complete file and path name of the given file.
+ */
+CINDEX_LINKAGE CXString clang_getFileName(CXFile SFile);
+
+/**
+ * \brief Retrieve the last modification time of the given file.
+ */
+CINDEX_LINKAGE time_t clang_getFileTime(CXFile SFile);
+
+/**
+ * \brief Retrieve a file handle within the given translation unit.
+ *
+ * \param tu the translation unit
+ *
+ * \param file_name the name of the file.
+ *
+ * \returns the file handle for the named file in the translation unit \p tu,
+ * or a NULL file handle if the file was not a part of this translation unit.
+ */
+CINDEX_LINKAGE CXFile clang_getFile(CXTranslationUnit tu,
+                                    const char *file_name);
+
+/**
+ * @}
+ */
+
+/**
+ * \defgroup CINDEX_LOCATIONS Physical source locations
+ *
+ * Clang represents physical source locations in its abstract syntax tree in
+ * great detail, with file, line, and column information for the majority of
+ * the tokens parsed in the source code. These data types and functions are
+ * used to represent source location information, either for a particular
+ * point in the program or for a range of points in the program, and extract
+ * specific location information from those data types.
+ *
+ * @{
+ */
+
+/**
+ * \brief Identifies a specific source location within a translation
+ * unit.
+ *
+ * Use clang_getInstantiationLocation() to map a source location to a
+ * particular file, line, and column.
+ */
+typedef struct {
+  void *ptr_data[2];
+  unsigned int_data;
+} CXSourceLocation;
+
+/**
+ * \brief Identifies a half-open character range in the source code.
+ *
+ * Use clang_getRangeStart() and clang_getRangeEnd() to retrieve the
+ * starting and end locations from a source range, respectively.
+ */
+typedef struct {
+  void *ptr_data[2];
+  unsigned begin_int_data;
+  unsigned end_int_data;
+} CXSourceRange;
+
+/**
+ * \brief Retrieve a NULL (invalid) source location.
+ */
+CINDEX_LINKAGE CXSourceLocation clang_getNullLocation();
+
+/**
+ * \determine Determine whether two source locations, which must refer into
+ * the same translation unit, refer to exactly the same point in the source
+ * code.
+ *
+ * \returns non-zero if the source locations refer to the same location, zero
+ * if they refer to different locations.
+ */
+CINDEX_LINKAGE unsigned clang_equalLocations(CXSourceLocation loc1,
+                                             CXSourceLocation loc2);
+
+/**
+ * \brief Retrieves the source location associated with a given file/line/column
+ * in a particular translation unit.
+ */
+CINDEX_LINKAGE CXSourceLocation clang_getLocation(CXTranslationUnit tu,
+                                                  CXFile file,
+                                                  unsigned line,
+                                                  unsigned column);
+
+/**
+ * \brief Retrieve a NULL (invalid) source range.
+ */
+CINDEX_LINKAGE CXSourceRange clang_getNullRange();
+
+/**
+ * \brief Retrieve a source range given the beginning and ending source
+ * locations.
+ */
+CINDEX_LINKAGE CXSourceRange clang_getRange(CXSourceLocation begin,
+                                            CXSourceLocation end);
+
+/**
+ * \brief Retrieve the file, line, column, and offset represented by
+ * the given source location.
+ *
+ * \param location the location within a source file that will be decomposed
+ * into its parts.
+ *
+ * \param file [out] if non-NULL, will be set to the file to which the given
+ * source location points.
+ *
+ * \param line [out] if non-NULL, will be set to the line to which the given
+ * source location points.
+ *
+ * \param column [out] if non-NULL, will be set to the column to which the given
+ * source location points.
+ *
+ * \param offset [out] if non-NULL, will be set to the offset into the
+ * buffer to which the given source location points.
+ */
+CINDEX_LINKAGE void clang_getInstantiationLocation(CXSourceLocation location,
+                                                   CXFile *file,
+                                                   unsigned *line,
+                                                   unsigned *column,
+                                                   unsigned *offset);
+
+/**
+ * \brief Retrieve a source location representing the first character within a
+ * source range.
+ */
+CINDEX_LINKAGE CXSourceLocation clang_getRangeStart(CXSourceRange range);
+
+/**
+ * \brief Retrieve a source location representing the last character within a
+ * source range.
+ */
+CINDEX_LINKAGE CXSourceLocation clang_getRangeEnd(CXSourceRange range);
+
+/**
+ * @}
+ */
+
+/**
+ * \defgroup CINDEX_DIAG Diagnostic reporting
+ *
+ * @{
+ */
+
+/**
+ * \brief Describes the severity of a particular diagnostic.
+ */
+enum CXDiagnosticSeverity {
+  /**
+   * \brief A diagnostic that has been suppressed, e.g., by a command-line
+   * option.
+   */
+  CXDiagnostic_Ignored = 0,
+
+  /**
+   * \brief This diagnostic is a note that should be attached to the
+   * previous (non-note) diagnostic.
+   */
+  CXDiagnostic_Note    = 1,
+
+  /**
+   * \brief This diagnostic indicates suspicious code that may not be
+   * wrong.
+   */
+  CXDiagnostic_Warning = 2,
+
+  /**
+   * \brief This diagnostic indicates that the code is ill-formed.
+   */
+  CXDiagnostic_Error   = 3,
+
+  /**
+   * \brief This diagnostic indicates that the code is ill-formed such
+   * that future parser recovery is unlikely to produce useful
+   * results.
+   */
+  CXDiagnostic_Fatal   = 4
+};
+
+/**
+ * \brief A single diagnostic, containing the diagnostic's severity,
+ * location, text, source ranges, and fix-it hints.
+ */
+typedef void *CXDiagnostic;
+
+/**
+ * \brief Determine the number of diagnostics produced for the given
+ * translation unit.
+ */
+CINDEX_LINKAGE unsigned clang_getNumDiagnostics(CXTranslationUnit Unit);
+
+/**
+ * \brief Retrieve a diagnostic associated with the given translation unit.
+ *
+ * \param Unit the translation unit to query.
+ * \param Index the zero-based diagnostic number to retrieve.
+ *
+ * \returns the requested diagnostic. This diagnostic must be freed
+ * via a call to \c clang_disposeDiagnostic().
+ */
+CINDEX_LINKAGE CXDiagnostic clang_getDiagnostic(CXTranslationUnit Unit,
+                                                unsigned Index);
+
+/**
+ * \brief Destroy a diagnostic.
+ */
+CINDEX_LINKAGE void clang_disposeDiagnostic(CXDiagnostic Diagnostic);
+
+/**
+ * \brief Options to control the display of diagnostics.
+ *
+ * The values in this enum are meant to be combined to customize the
+ * behavior of \c clang_displayDiagnostic().
+ */
+enum CXDiagnosticDisplayOptions {
+  /**
+   * \brief Display the source-location information where the
+   * diagnostic was located.
+   *
+   * When set, diagnostics will be prefixed by the file, line, and
+   * (optionally) column to which the diagnostic refers. For example,
+   *
+   * \code
+   * test.c:28: warning: extra tokens at end of #endif directive
+   * \endcode
+   *
+   * This option corresponds to the clang flag \c -fshow-source-location.
+   */
+  CXDiagnostic_DisplaySourceLocation = 0x01,
+
+  /**
+   * \brief If displaying the source-location information of the
+   * diagnostic, also include the column number.
+   *
+   * This option corresponds to the clang flag \c -fshow-column.
+   */
+  CXDiagnostic_DisplayColumn = 0x02,
+
+  /**
+   * \brief If displaying the source-location information of the
+   * diagnostic, also include information about source ranges in a
+   * machine-parsable format.
+   *
+   * This option corresponds to the clang flag
+   * \c -fdiagnostics-print-source-range-info.
+   */
+  CXDiagnostic_DisplaySourceRanges = 0x04
+};
+
+/**
+ * \brief Format the given diagnostic in a manner that is suitable for display.
+ *
+ * This routine will format the given diagnostic to a string, rendering
+ * the diagnostic according to the various options given. The
+ * \c clang_defaultDiagnosticDisplayOptions() function returns the set of
+ * options that most closely mimics the behavior of the clang compiler.
+ *
+ * \param Diagnostic The diagnostic to print.
+ *
+ * \param Options A set of options that control the diagnostic display,
+ * created by combining \c CXDiagnosticDisplayOptions values.
+ *
+ * \returns A new string containing for formatted diagnostic.
+ */
+CINDEX_LINKAGE CXString clang_formatDiagnostic(CXDiagnostic Diagnostic,
+                                               unsigned Options);
+
+/**
+ * \brief Retrieve the set of display options most similar to the
+ * default behavior of the clang compiler.
+ *
+ * \returns A set of display options suitable for use with \c
+ * clang_displayDiagnostic().
+ */
+CINDEX_LINKAGE unsigned clang_defaultDiagnosticDisplayOptions(void);
+
+/**
+ * \brief Print a diagnostic to the given file.
+ */
+
+/**
+ * \brief Determine the severity of the given diagnostic.
+ */
+CINDEX_LINKAGE enum CXDiagnosticSeverity
+clang_getDiagnosticSeverity(CXDiagnostic);
+
+/**
+ * \brief Retrieve the source location of the given diagnostic.
+ *
+ * This location is where Clang would print the caret ('^') when
+ * displaying the diagnostic on the command line.
+ */
+CINDEX_LINKAGE CXSourceLocation clang_getDiagnosticLocation(CXDiagnostic);
+
+/**
+ * \brief Retrieve the text of the given diagnostic.
+ */
+CINDEX_LINKAGE CXString clang_getDiagnosticSpelling(CXDiagnostic);
+
+/**
+ * \brief Determine the number of source ranges associated with the given
+ * diagnostic.
+ */
+CINDEX_LINKAGE unsigned clang_getDiagnosticNumRanges(CXDiagnostic);
+
+/**
+ * \brief Retrieve a source range associated with the diagnostic.
+ *
+ * A diagnostic's source ranges highlight important elements in the source
+ * code. On the command line, Clang displays source ranges by
+ * underlining them with '~' characters.
+ *
+ * \param Diagnostic the diagnostic whose range is being extracted.
+ *
+ * \param Range the zero-based index specifying which range to
+ *
+ * \returns the requested source range.
+ */
+CINDEX_LINKAGE CXSourceRange clang_getDiagnosticRange(CXDiagnostic Diagnostic,
+                                                      unsigned Range);
+
+/**
+ * \brief Determine the number of fix-it hints associated with the
+ * given diagnostic.
+ */
+CINDEX_LINKAGE unsigned clang_getDiagnosticNumFixIts(CXDiagnostic Diagnostic);
+
+/**
+ * \brief Retrieve the replacement information for a given fix-it.
+ *
+ * Fix-its are described in terms of a source range whose contents
+ * should be replaced by a string. This approach generalizes over
+ * three kinds of operations: removal of source code (the range covers
+ * the code to be removed and the replacement string is empty),
+ * replacement of source code (the range covers the code to be
+ * replaced and the replacement string provides the new code), and
+ * insertion (both the start and end of the range point at the
+ * insertion location, and the replacement string provides the text to
+ * insert).
+ *
+ * \param Diagnostic The diagnostic whose fix-its are being queried.
+ *
+ * \param FixIt The zero-based index of the fix-it.
+ *
+ * \param ReplacementRange The source range whose contents will be
+ * replaced with the returned replacement string. Note that source
+ * ranges are half-open ranges [a, b), so the source code should be
+ * replaced from a and up to (but not including) b.
+ *
+ * \returns A string containing text that should be replace the source
+ * code indicated by the \c ReplacementRange.
+ */
+CINDEX_LINKAGE CXString clang_getDiagnosticFixIt(CXDiagnostic Diagnostic,
+                                                 unsigned FixIt,
+                                               CXSourceRange *ReplacementRange);
+
+/**
+ * @}
+ */
+
+/**
+ * \defgroup CINDEX_TRANSLATION_UNIT Translation unit manipulation
+ *
+ * The routines in this group provide the ability to create and destroy
+ * translation units from files, either by parsing the contents of the files or
+ * by reading in a serialized representation of a translation unit.
+ *
+ * @{
+ */
+
+/**
+ * \brief Get the original translation unit source file name.
+ */
+CINDEX_LINKAGE CXString
+clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit);
+
+/**
+ * \brief Return the CXTranslationUnit for a given source file and the provided
+ * command line arguments one would pass to the compiler.
+ *
+ * Note: The 'source_filename' argument is optional.  If the caller provides a
+ * NULL pointer, the name of the source file is expected to reside in the
+ * specified command line arguments.
+ *
+ * Note: When encountered in 'clang_command_line_args', the following options
+ * are ignored:
+ *
+ *   '-c'
+ *   '-emit-ast'
+ *   '-fsyntax-only'
+ *   '-o <output file>'  (both '-o' and '<output file>' are ignored)
+ *
+ *
+ * \param source_filename - The name of the source file to load, or NULL if the
+ * source file is included in clang_command_line_args.
+ *
+ * \param num_unsaved_files the number of unsaved file entries in \p
+ * unsaved_files.
+ *
+ * \param unsaved_files the files that have not yet been saved to disk
+ * but may be required for code completion, including the contents of
+ * those files.  The contents and name of these files (as specified by
+ * CXUnsavedFile) are copied when necessary, so the client only needs to
+ * guarantee their validity until the call to this function returns.
+ *
+ * \param diag_callback callback function that will receive any diagnostics
+ * emitted while processing this source file. If NULL, diagnostics will be
+ * suppressed.
+ *
+ * \param diag_client_data client data that will be passed to the diagnostic
+ * callback function.
+ */
+CINDEX_LINKAGE CXTranslationUnit clang_createTranslationUnitFromSourceFile(
+                                         CXIndex CIdx,
+                                         const char *source_filename,
+                                         int num_clang_command_line_args,
+                                         const char **clang_command_line_args,
+                                         unsigned num_unsaved_files,
+                                         struct CXUnsavedFile *unsaved_files);
+
+/**
+ * \brief Create a translation unit from an AST file (-emit-ast).
+ */
+CINDEX_LINKAGE CXTranslationUnit clang_createTranslationUnit(CXIndex,
+                                             const char *ast_filename);
+
+/**
+ * \brief Destroy the specified CXTranslationUnit object.
+ */
+CINDEX_LINKAGE void clang_disposeTranslationUnit(CXTranslationUnit);
+
+/**
+ * @}
+ */
+
+/**
+ * \brief Describes the kind of entity that a cursor refers to.
+ */
+enum CXCursorKind {
+  /* Declarations */
+  CXCursor_FirstDecl                     = 1,
+  /**
+   * \brief A declaration whose specific kind is not exposed via this
+   * interface.
+   *
+   * Unexposed declarations have the same operations as any other kind
+   * of declaration; one can extract their location information,
+   * spelling, find their definitions, etc. However, the specific kind
+   * of the declaration is not reported.
+   */
+  CXCursor_UnexposedDecl                 = 1,
+  /** \brief A C or C++ struct. */
+  CXCursor_StructDecl                    = 2,
+  /** \brief A C or C++ union. */
+  CXCursor_UnionDecl                     = 3,
+  /** \brief A C++ class. */
+  CXCursor_ClassDecl                     = 4,
+  /** \brief An enumeration. */
+  CXCursor_EnumDecl                      = 5,
+  /**
+   * \brief A field (in C) or non-static data member (in C++) in a
+   * struct, union, or C++ class.
+   */
+  CXCursor_FieldDecl                     = 6,
+  /** \brief An enumerator constant. */
+  CXCursor_EnumConstantDecl              = 7,
+  /** \brief A function. */
+  CXCursor_FunctionDecl                  = 8,
+  /** \brief A variable. */
+  CXCursor_VarDecl                       = 9,
+  /** \brief A function or method parameter. */
+  CXCursor_ParmDecl                      = 10,
+  /** \brief An Objective-C @interface. */
+  CXCursor_ObjCInterfaceDecl             = 11,
+  /** \brief An Objective-C @interface for a category. */
+  CXCursor_ObjCCategoryDecl              = 12,
+  /** \brief An Objective-C @protocol declaration. */
+  CXCursor_ObjCProtocolDecl              = 13,
+  /** \brief An Objective-C @property declaration. */
+  CXCursor_ObjCPropertyDecl              = 14,
+  /** \brief An Objective-C instance variable. */
+  CXCursor_ObjCIvarDecl                  = 15,
+  /** \brief An Objective-C instance method. */
+  CXCursor_ObjCInstanceMethodDecl        = 16,
+  /** \brief An Objective-C class method. */
+  CXCursor_ObjCClassMethodDecl           = 17,
+  /** \brief An Objective-C @implementation. */
+  CXCursor_ObjCImplementationDecl        = 18,
+  /** \brief An Objective-C @implementation for a category. */
+  CXCursor_ObjCCategoryImplDecl          = 19,
+  /** \brief A typedef */
+  CXCursor_TypedefDecl                   = 20,
+
+  /** \brief A C++ class method. */
+  CXCursor_CXXMethod                     = 21,
+
+  CXCursor_LastDecl                      = 21,
+
+  /* References */
+  CXCursor_FirstRef                      = 40, /* Decl references */
+  CXCursor_ObjCSuperClassRef             = 40,
+  CXCursor_ObjCProtocolRef               = 41,
+  CXCursor_ObjCClassRef                  = 42,
+  /**
+   * \brief A reference to a type declaration.
+   *
+   * A type reference occurs anywhere where a type is named but not
+   * declared. For example, given:
+   *
+   * \code
+   * typedef unsigned size_type;
+   * size_type size;
+   * \endcode
+   *
+   * The typedef is a declaration of size_type (CXCursor_TypedefDecl),
+   * while the type of the variable "size" is referenced. The cursor
+   * referenced by the type of size is the typedef for size_type.
+   */
+  CXCursor_TypeRef                       = 43,
+  CXCursor_LastRef                       = 43,
+
+  /* Error conditions */
+  CXCursor_FirstInvalid                  = 70,
+  CXCursor_InvalidFile                   = 70,
+  CXCursor_NoDeclFound                   = 71,
+  CXCursor_NotImplemented                = 72,
+  CXCursor_InvalidCode                   = 73,
+  CXCursor_LastInvalid                   = CXCursor_InvalidCode,
+
+  /* Expressions */
+  CXCursor_FirstExpr                     = 100,
+
+  /**
+   * \brief An expression whose specific kind is not exposed via this
+   * interface.
+   *
+   * Unexposed expressions have the same operations as any other kind
+   * of expression; one can extract their location information,
+   * spelling, children, etc. However, the specific kind of the
+   * expression is not reported.
+   */
+  CXCursor_UnexposedExpr                 = 100,
+
+  /**
+   * \brief An expression that refers to some value declaration, such
+   * as a function, varible, or enumerator.
+   */
+  CXCursor_DeclRefExpr                   = 101,
+
+  /**
+   * \brief An expression that refers to a member of a struct, union,
+   * class, Objective-C class, etc.
+   */
+  CXCursor_MemberRefExpr                 = 102,
+
+  /** \brief An expression that calls a function. */
+  CXCursor_CallExpr                      = 103,
+
+  /** \brief An expression that sends a message to an Objective-C
+   object or class. */
+  CXCursor_ObjCMessageExpr               = 104,
+
+  /** \brief An expression that represents a block literal. */
+  CXCursor_BlockExpr                     = 105,
+
+  CXCursor_LastExpr                      = 105,
+
+  /* Statements */
+  CXCursor_FirstStmt                     = 200,
+  /**
+   * \brief A statement whose specific kind is not exposed via this
+   * interface.
+   *
+   * Unexposed statements have the same operations as any other kind of
+   * statement; one can extract their location information, spelling,
+   * children, etc. However, the specific kind of the statement is not
+   * reported.
+   */
+  CXCursor_UnexposedStmt                 = 200,
+  CXCursor_LastStmt                      = 200,
+
+  /**
+   * \brief Cursor that represents the translation unit itself.
+   *
+   * The translation unit cursor exists primarily to act as the root
+   * cursor for traversing the contents of a translation unit.
+   */
+  CXCursor_TranslationUnit               = 300,
+
+  /* Attributes */
+  CXCursor_FirstAttr                     = 400,
+  /**
+   * \brief An attribute whose specific kind is not exposed via this
+   * interface.
+   */
+  CXCursor_UnexposedAttr                 = 400,
+
+  CXCursor_IBActionAttr                  = 401,
+  CXCursor_IBOutletAttr                  = 402,
+  CXCursor_LastAttr                      = CXCursor_IBOutletAttr,
+     
+  /* Preprocessing */
+  CXCursor_PreprocessingDirective        = 500,
+  CXCursor_MacroDefinition               = 501,
+  CXCursor_MacroInstantiation            = 502,
+  CXCursor_FirstPreprocessing            = CXCursor_PreprocessingDirective,
+  CXCursor_LastPreprocessing             = CXCursor_MacroInstantiation
+};
+
+/**
+ * \brief A cursor representing some element in the abstract syntax tree for
+ * a translation unit.
+ *
+ * The cursor abstraction unifies the different kinds of entities in a
+ * program--declaration, statements, expressions, references to declarations,
+ * etc.--under a single "cursor" abstraction with a common set of operations.
+ * Common operation for a cursor include: getting the physical location in
+ * a source file where the cursor points, getting the name associated with a
+ * cursor, and retrieving cursors for any child nodes of a particular cursor.
+ *
+ * Cursors can be produced in two specific ways.
+ * clang_getTranslationUnitCursor() produces a cursor for a translation unit,
+ * from which one can use clang_visitChildren() to explore the rest of the
+ * translation unit. clang_getCursor() maps from a physical source location
+ * to the entity that resides at that location, allowing one to map from the
+ * source code into the AST.
+ */
+typedef struct {
+  enum CXCursorKind kind;
+  void *data[3];
+} CXCursor;
+
+/**
+ * \defgroup CINDEX_CURSOR_MANIP Cursor manipulations
+ *
+ * @{
+ */
+
+/**
+ * \brief Retrieve the NULL cursor, which represents no entity.
+ */
+CINDEX_LINKAGE CXCursor clang_getNullCursor(void);
+
+/**
+ * \brief Retrieve the cursor that represents the given translation unit.
+ *
+ * The translation unit cursor can be used to start traversing the
+ * various declarations within the given translation unit.
+ */
+CINDEX_LINKAGE CXCursor clang_getTranslationUnitCursor(CXTranslationUnit);
+
+/**
+ * \brief Determine whether two cursors are equivalent.
+ */
+CINDEX_LINKAGE unsigned clang_equalCursors(CXCursor, CXCursor);
+
+/**
+ * \brief Retrieve the kind of the given cursor.
+ */
+CINDEX_LINKAGE enum CXCursorKind clang_getCursorKind(CXCursor);
+
+/**
+ * \brief Determine whether the given cursor kind represents a declaration.
+ */
+CINDEX_LINKAGE unsigned clang_isDeclaration(enum CXCursorKind);
+
+/**
+ * \brief Determine whether the given cursor kind represents a simple
+ * reference.
+ *
+ * Note that other kinds of cursors (such as expressions) can also refer to
+ * other cursors. Use clang_getCursorReferenced() to determine whether a
+ * particular cursor refers to another entity.
+ */
+CINDEX_LINKAGE unsigned clang_isReference(enum CXCursorKind);
+
+/**
+ * \brief Determine whether the given cursor kind represents an expression.
+ */
+CINDEX_LINKAGE unsigned clang_isExpression(enum CXCursorKind);
+
+/**
+ * \brief Determine whether the given cursor kind represents a statement.
+ */
+CINDEX_LINKAGE unsigned clang_isStatement(enum CXCursorKind);
+
+/**
+ * \brief Determine whether the given cursor kind represents an invalid
+ * cursor.
+ */
+CINDEX_LINKAGE unsigned clang_isInvalid(enum CXCursorKind);
+
+/**
+ * \brief Determine whether the given cursor kind represents a translation
+ * unit.
+ */
+CINDEX_LINKAGE unsigned clang_isTranslationUnit(enum CXCursorKind);
+
+/***
+ * \brief Determine whether the given cursor represents a preprocessing
+ * element, such as a preprocessor directive or macro instantiation.
+ */
+CINDEX_LINKAGE unsigned clang_isPreprocessing(enum CXCursorKind);
+  
+/***
+ * \brief Determine whether the given cursor represents a currently
+ *  unexposed piece of the AST (e.g., CXCursor_UnexposedStmt).
+ */
+CINDEX_LINKAGE unsigned clang_isUnexposed(enum CXCursorKind);
+
+/**
+ * \brief Describe the linkage of the entity referred to by a cursor.
+ */
+enum CXLinkageKind {
+  /** \brief This value indicates that no linkage information is available
+   * for a provided CXCursor. */
+  CXLinkage_Invalid,
+  /**
+   * \brief This is the linkage for variables, parameters, and so on that
+   *  have automatic storage.  This covers normal (non-extern) local variables.
+   */
+  CXLinkage_NoLinkage,
+  /** \brief This is the linkage for static variables and static functions. */
+  CXLinkage_Internal,
+  /** \brief This is the linkage for entities with external linkage that live
+   * in C++ anonymous namespaces.*/
+  CXLinkage_UniqueExternal,
+  /** \brief This is the linkage for entities with true, external linkage. */
+  CXLinkage_External
+};
+
+/**
+ * \brief Determine the linkage of the entity referred to by a given cursor.
+ */
+CINDEX_LINKAGE enum CXLinkageKind clang_getCursorLinkage(CXCursor cursor);
+
+/**
+ * \brief Describe the "language" of the entity referred to by a cursor.
+ */
+CINDEX_LINKAGE enum CXLanguageKind {
+  CXLanguage_Invalid = 0,
+  CXLanguage_C,
+  CXLanguage_ObjC,
+  CXLanguage_CPlusPlus
+};
+
+/**
+ * \brief Determine the "language" of the entity referred to by a given cursor.
+ */
+CINDEX_LINKAGE enum CXLanguageKind clang_getCursorLanguage(CXCursor cursor);
+
+/**
+ * @}
+ */
+
+/**
+ * \defgroup CINDEX_CURSOR_SOURCE Mapping between cursors and source code
+ *
+ * Cursors represent a location within the Abstract Syntax Tree (AST). These
+ * routines help map between cursors and the physical locations where the
+ * described entities occur in the source code. The mapping is provided in
+ * both directions, so one can map from source code to the AST and back.
+ *
+ * @{
+ */
+
+/**
+ * \brief Map a source location to the cursor that describes the entity at that
+ * location in the source code.
+ *
+ * clang_getCursor() maps an arbitrary source location within a translation
+ * unit down to the most specific cursor that describes the entity at that
+ * location. For example, given an expression \c x + y, invoking
+ * clang_getCursor() with a source location pointing to "x" will return the
+ * cursor for "x"; similarly for "y". If the cursor points anywhere between
+ * "x" or "y" (e.g., on the + or the whitespace around it), clang_getCursor()
+ * will return a cursor referring to the "+" expression.
+ *
+ * \returns a cursor representing the entity at the given source location, or
+ * a NULL cursor if no such entity can be found.
+ */
+CINDEX_LINKAGE CXCursor clang_getCursor(CXTranslationUnit, CXSourceLocation);
+
+/**
+ * \brief Retrieve the physical location of the source constructor referenced
+ * by the given cursor.
+ *
+ * The location of a declaration is typically the location of the name of that
+ * declaration, where the name of that declaration would occur if it is
+ * unnamed, or some keyword that introduces that particular declaration.
+ * The location of a reference is where that reference occurs within the
+ * source code.
+ */
+CINDEX_LINKAGE CXSourceLocation clang_getCursorLocation(CXCursor);
+
+/**
+ * \brief Retrieve the physical extent of the source construct referenced by
+ * the given cursor.
+ *
+ * The extent of a cursor starts with the file/line/column pointing at the
+ * first character within the source construct that the cursor refers to and
+ * ends with the last character withinin that source construct. For a
+ * declaration, the extent covers the declaration itself. For a reference,
+ * the extent covers the location of the reference (e.g., where the referenced
+ * entity was actually used).
+ */
+CINDEX_LINKAGE CXSourceRange clang_getCursorExtent(CXCursor);
+
+/**
+ * @}
+ */
+
+/**
+ * \defgroup CINDEX_CURSOR_TRAVERSAL Traversing the AST with cursors
+ *
+ * These routines provide the ability to traverse the abstract syntax tree
+ * using cursors.
+ *
+ * @{
+ */
+
+/**
+ * \brief Describes how the traversal of the children of a particular
+ * cursor should proceed after visiting a particular child cursor.
+ *
+ * A value of this enumeration type should be returned by each
+ * \c CXCursorVisitor to indicate how clang_visitChildren() proceed.
+ */
+enum CXChildVisitResult {
+  /**
+   * \brief Terminates the cursor traversal.
+   */
+  CXChildVisit_Break,
+  /**
+   * \brief Continues the cursor traversal with the next sibling of
+   * the cursor just visited, without visiting its children.
+   */
+  CXChildVisit_Continue,
+  /**
+   * \brief Recursively traverse the children of this cursor, using
+   * the same visitor and client data.
+   */
+  CXChildVisit_Recurse
+};
+
+/**
+ * \brief Visitor invoked for each cursor found by a traversal.
+ *
+ * This visitor function will be invoked for each cursor found by
+ * clang_visitCursorChildren(). Its first argument is the cursor being
+ * visited, its second argument is the parent visitor for that cursor,
+ * and its third argument is the client data provided to
+ * clang_visitCursorChildren().
+ *
+ * The visitor should return one of the \c CXChildVisitResult values
+ * to direct clang_visitCursorChildren().
+ */
+typedef enum CXChildVisitResult (*CXCursorVisitor)(CXCursor cursor,
+                                                   CXCursor parent,
+                                                   CXClientData client_data);
+
+/**
+ * \brief Visit the children of a particular cursor.
+ *
+ * This function visits all the direct children of the given cursor,
+ * invoking the given \p visitor function with the cursors of each
+ * visited child. The traversal may be recursive, if the visitor returns
+ * \c CXChildVisit_Recurse. The traversal may also be ended prematurely, if
+ * the visitor returns \c CXChildVisit_Break.
+ *
+ * \param parent the cursor whose child may be visited. All kinds of
+ * cursors can be visited, including invalid cursors (which, by
+ * definition, have no children).
+ *
+ * \param visitor the visitor function that will be invoked for each
+ * child of \p parent.
+ *
+ * \param client_data pointer data supplied by the client, which will
+ * be passed to the visitor each time it is invoked.
+ *
+ * \returns a non-zero value if the traversal was terminated
+ * prematurely by the visitor returning \c CXChildVisit_Break.
+ */
+CINDEX_LINKAGE unsigned clang_visitChildren(CXCursor parent,
+                                            CXCursorVisitor visitor,
+                                            CXClientData client_data);
+
+/**
+ * @}
+ */
+
+/**
+ * \defgroup CINDEX_CURSOR_XREF Cross-referencing in the AST
+ *
+ * These routines provide the ability to determine references within and
+ * across translation units, by providing the names of the entities referenced
+ * by cursors, follow reference cursors to the declarations they reference,
+ * and associate declarations with their definitions.
+ *
+ * @{
+ */
+
+/**
+ * \brief Retrieve a Unified Symbol Resolution (USR) for the entity referenced
+ * by the given cursor.
+ *
+ * A Unified Symbol Resolution (USR) is a string that identifies a particular
+ * entity (function, class, variable, etc.) within a program. USRs can be
+ * compared across translation units to determine, e.g., when references in
+ * one translation refer to an entity defined in another translation unit.
+ */
+CINDEX_LINKAGE CXString clang_getCursorUSR(CXCursor);
+
+/**
+ * \brief Construct a USR for a specified Objective-C class.
+ */
+CINDEX_LINKAGE CXString clang_constructUSR_ObjCClass(const char *class_name);
+
+/**
+ * \brief Construct a USR for a specified Objective-C category.
+ */
+CINDEX_LINKAGE CXString
+  clang_constructUSR_ObjCCategory(const char *class_name,
+                                 const char *category_name);
+
+/**
+ * \brief Construct a USR for a specified Objective-C protocol.
+ */
+CINDEX_LINKAGE CXString
+  clang_constructUSR_ObjCProtocol(const char *protocol_name);
+
+
+/**
+ * \brief Construct a USR for a specified Objective-C instance variable and
+ *   the USR for its containing class.
+ */
+CINDEX_LINKAGE CXString clang_constructUSR_ObjCIvar(const char *name,
+                                                    CXString classUSR);
+
+/**
+ * \brief Construct a USR for a specified Objective-C method and
+ *   the USR for its containing class.
+ */
+CINDEX_LINKAGE CXString clang_constructUSR_ObjCMethod(const char *name,
+                                                      unsigned isInstanceMethod,
+                                                      CXString classUSR);
+
+/**
+ * \brief Construct a USR for a specified Objective-C property and the USR
+ *  for its containing class.
+ */
+CINDEX_LINKAGE CXString clang_constructUSR_ObjCProperty(const char *property,
+                                                        CXString classUSR);
+
+/**
+ * \brief Retrieve a name for the entity referenced by this cursor.
+ */
+CINDEX_LINKAGE CXString clang_getCursorSpelling(CXCursor);
+
+/** \brief For a cursor that is a reference, retrieve a cursor representing the
+ * entity that it references.
+ *
+ * Reference cursors refer to other entities in the AST. For example, an
+ * Objective-C superclass reference cursor refers to an Objective-C class.
+ * This function produces the cursor for the Objective-C class from the
+ * cursor for the superclass reference. If the input cursor is a declaration or
+ * definition, it returns that declaration or definition unchanged.
+ * Otherwise, returns the NULL cursor.
+ */
+CINDEX_LINKAGE CXCursor clang_getCursorReferenced(CXCursor);
+
+/**
+ *  \brief For a cursor that is either a reference to or a declaration
+ *  of some entity, retrieve a cursor that describes the definition of
+ *  that entity.
+ *
+ *  Some entities can be declared multiple times within a translation
+ *  unit, but only one of those declarations can also be a
+ *  definition. For example, given:
+ *
+ *  \code
+ *  int f(int, int);
+ *  int g(int x, int y) { return f(x, y); }
+ *  int f(int a, int b) { return a + b; }
+ *  int f(int, int);
+ *  \endcode
+ *
+ *  there are three declarations of the function "f", but only the
+ *  second one is a definition. The clang_getCursorDefinition()
+ *  function will take any cursor pointing to a declaration of "f"
+ *  (the first or fourth lines of the example) or a cursor referenced
+ *  that uses "f" (the call to "f' inside "g") and will return a
+ *  declaration cursor pointing to the definition (the second "f"
+ *  declaration).
+ *
+ *  If given a cursor for which there is no corresponding definition,
+ *  e.g., because there is no definition of that entity within this
+ *  translation unit, returns a NULL cursor.
+ */
+CINDEX_LINKAGE CXCursor clang_getCursorDefinition(CXCursor);
+
+/**
+ * \brief Determine whether the declaration pointed to by this cursor
+ * is also a definition of that entity.
+ */
+CINDEX_LINKAGE unsigned clang_isCursorDefinition(CXCursor);
+
+/**
+ * @}
+ */
+
+/**
+ * \defgroup CINDEX_LEX Token extraction and manipulation
+ *
+ * The routines in this group provide access to the tokens within a
+ * translation unit, along with a semantic mapping of those tokens to
+ * their corresponding cursors.
+ *
+ * @{
+ */
+
+/**
+ * \brief Describes a kind of token.
+ */
+typedef enum CXTokenKind {
+  /**
+   * \brief A token that contains some kind of punctuation.
+   */
+  CXToken_Punctuation,
+
+  /**
+   * \brief A language keyword.
+   */
+  CXToken_Keyword,
+
+  /**
+   * \brief An identifier (that is not a keyword).
+   */
+  CXToken_Identifier,
+
+  /**
+   * \brief A numeric, string, or character literal.
+   */
+  CXToken_Literal,
+
+  /**
+   * \brief A comment.
+   */
+  CXToken_Comment
+} CXTokenKind;
+
+/**
+ * \brief Describes a single preprocessing token.
+ */
+typedef struct {
+  unsigned int_data[4];
+  void *ptr_data;
+} CXToken;
+
+/**
+ * \brief Determine the kind of the given token.
+ */
+CINDEX_LINKAGE CXTokenKind clang_getTokenKind(CXToken);
+
+/**
+ * \brief Determine the spelling of the given token.
+ *
+ * The spelling of a token is the textual representation of that token, e.g.,
+ * the text of an identifier or keyword.
+ */
+CINDEX_LINKAGE CXString clang_getTokenSpelling(CXTranslationUnit, CXToken);
+
+/**
+ * \brief Retrieve the source location of the given token.
+ */
+CINDEX_LINKAGE CXSourceLocation clang_getTokenLocation(CXTranslationUnit,
+                                                       CXToken);
+
+/**
+ * \brief Retrieve a source range that covers the given token.
+ */
+CINDEX_LINKAGE CXSourceRange clang_getTokenExtent(CXTranslationUnit, CXToken);
+
+/**
+ * \brief Tokenize the source code described by the given range into raw
+ * lexical tokens.
+ *
+ * \param TU the translation unit whose text is being tokenized.
+ *
+ * \param Range the source range in which text should be tokenized. All of the
+ * tokens produced by tokenization will fall within this source range,
+ *
+ * \param Tokens this pointer will be set to point to the array of tokens
+ * that occur within the given source range. The returned pointer must be
+ * freed with clang_disposeTokens() before the translation unit is destroyed.
+ *
+ * \param NumTokens will be set to the number of tokens in the \c *Tokens
+ * array.
+ *
+ */
+CINDEX_LINKAGE void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
+                                   CXToken **Tokens, unsigned *NumTokens);
+
+/**
+ * \brief Annotate the given set of tokens by providing cursors for each token
+ * that can be mapped to a specific entity within the abstract syntax tree.
+ *
+ * This token-annotation routine is equivalent to invoking
+ * clang_getCursor() for the source locations of each of the
+ * tokens. The cursors provided are filtered, so that only those
+ * cursors that have a direct correspondence to the token are
+ * accepted. For example, given a function call \c f(x),
+ * clang_getCursor() would provide the following cursors:
+ *
+ *   * when the cursor is over the 'f', a DeclRefExpr cursor referring to 'f'.
+ *   * when the cursor is over the '(' or the ')', a CallExpr referring to 'f'.
+ *   * when the cursor is over the 'x', a DeclRefExpr cursor referring to 'x'.
+ *
+ * Only the first and last of these cursors will occur within the
+ * annotate, since the tokens "f" and "x' directly refer to a function
+ * and a variable, respectively, but the parentheses are just a small
+ * part of the full syntax of the function call expression, which is
+ * not provided as an annotation.
+ *
+ * \param TU the translation unit that owns the given tokens.
+ *
+ * \param Tokens the set of tokens to annotate.
+ *
+ * \param NumTokens the number of tokens in \p Tokens.
+ *
+ * \param Cursors an array of \p NumTokens cursors, whose contents will be
+ * replaced with the cursors corresponding to each token.
+ */
+CINDEX_LINKAGE void clang_annotateTokens(CXTranslationUnit TU,
+                                         CXToken *Tokens, unsigned NumTokens,
+                                         CXCursor *Cursors);
+
+/**
+ * \brief Free the given set of tokens.
+ */
+CINDEX_LINKAGE void clang_disposeTokens(CXTranslationUnit TU,
+                                        CXToken *Tokens, unsigned NumTokens);
+
+/**
+ * @}
+ */
+
+/**
+ * \defgroup CINDEX_DEBUG Debugging facilities
+ *
+ * These routines are used for testing and debugging, only, and should not
+ * be relied upon.
+ *
+ * @{
+ */
+
+/* for debug/testing */
+CINDEX_LINKAGE CXString clang_getCursorKindSpelling(enum CXCursorKind Kind);
+CINDEX_LINKAGE void clang_getDefinitionSpellingAndExtent(CXCursor,
+                                          const char **startBuf,
+                                          const char **endBuf,
+                                          unsigned *startLine,
+                                          unsigned *startColumn,
+                                          unsigned *endLine,
+                                          unsigned *endColumn);
+CINDEX_LINKAGE void clang_enableStackTraces(void);
+/**
+ * @}
+ */
+
+/**
+ * \defgroup CINDEX_CODE_COMPLET Code completion
+ *
+ * Code completion involves taking an (incomplete) source file, along with
+ * knowledge of where the user is actively editing that file, and suggesting
+ * syntactically- and semantically-valid constructs that the user might want to
+ * use at that particular point in the source code. These data structures and
+ * routines provide support for code completion.
+ *
+ * @{
+ */
+
+/**
+ * \brief A semantic string that describes a code-completion result.
+ *
+ * A semantic string that describes the formatting of a code-completion
+ * result as a single "template" of text that should be inserted into the
+ * source buffer when a particular code-completion result is selected.
+ * Each semantic string is made up of some number of "chunks", each of which
+ * contains some text along with a description of what that text means, e.g.,
+ * the name of the entity being referenced, whether the text chunk is part of
+ * the template, or whether it is a "placeholder" that the user should replace
+ * with actual code,of a specific kind. See \c CXCompletionChunkKind for a
+ * description of the different kinds of chunks.
+ */
+typedef void *CXCompletionString;
+
+/**
+ * \brief A single result of code completion.
+ */
+typedef struct {
+  /**
+   * \brief The kind of entity that this completion refers to.
+   *
+   * The cursor kind will be a macro, keyword, or a declaration (one of the
+   * *Decl cursor kinds), describing the entity that the completion is
+   * referring to.
+   *
+   * \todo In the future, we would like to provide a full cursor, to allow
+   * the client to extract additional information from declaration.
+   */
+  enum CXCursorKind CursorKind;
+
+  /**
+   * \brief The code-completion string that describes how to insert this
+   * code-completion result into the editing buffer.
+   */
+  CXCompletionString CompletionString;
+} CXCompletionResult;
+
+/**
+ * \brief Describes a single piece of text within a code-completion string.
+ *
+ * Each "chunk" within a code-completion string (\c CXCompletionString) is
+ * either a piece of text with a specific "kind" that describes how that text
+ * should be interpreted by the client or is another completion string.
+ */
+enum CXCompletionChunkKind {
+  /**
+   * \brief A code-completion string that describes "optional" text that
+   * could be a part of the template (but is not required).
+   *
+   * The Optional chunk is the only kind of chunk that has a code-completion
+   * string for its representation, which is accessible via
+   * \c clang_getCompletionChunkCompletionString(). The code-completion string
+   * describes an additional part of the template that is completely optional.
+   * For example, optional chunks can be used to describe the placeholders for
+   * arguments that match up with defaulted function parameters, e.g. given:
+   *
+   * \code
+   * void f(int x, float y = 3.14, double z = 2.71828);
+   * \endcode
+   *
+   * The code-completion string for this function would contain:
+   *   - a TypedText chunk for "f".
+   *   - a LeftParen chunk for "(".
+   *   - a Placeholder chunk for "int x"
+   *   - an Optional chunk containing the remaining defaulted arguments, e.g.,
+   *       - a Comma chunk for ","
+   *       - a Placeholder chunk for "float y"
+   *       - an Optional chunk containing the last defaulted argument:
+   *           - a Comma chunk for ","
+   *           - a Placeholder chunk for "double z"
+   *   - a RightParen chunk for ")"
+   *
+   * There are many ways to handle Optional chunks. Two simple approaches are:
+   *   - Completely ignore optional chunks, in which case the template for the
+   *     function "f" would only include the first parameter ("int x").
+   *   - Fully expand all optional chunks, in which case the template for the
+   *     function "f" would have all of the parameters.
+   */
+  CXCompletionChunk_Optional,
+  /**
+   * \brief Text that a user would be expected to type to get this
+   * code-completion result.
+   *
+   * There will be exactly one "typed text" chunk in a semantic string, which
+   * will typically provide the spelling of a keyword or the name of a
+   * declaration that could be used at the current code point. Clients are
+   * expected to filter the code-completion results based on the text in this
+   * chunk.
+   */
+  CXCompletionChunk_TypedText,
+  /**
+   * \brief Text that should be inserted as part of a code-completion result.
+   *
+   * A "text" chunk represents text that is part of the template to be
+   * inserted into user code should this particular code-completion result
+   * be selected.
+   */
+  CXCompletionChunk_Text,
+  /**
+   * \brief Placeholder text that should be replaced by the user.
+   *
+   * A "placeholder" chunk marks a place where the user should insert text
+   * into the code-completion template. For example, placeholders might mark
+   * the function parameters for a function declaration, to indicate that the
+   * user should provide arguments for each of those parameters. The actual
+   * text in a placeholder is a suggestion for the text to display before
+   * the user replaces the placeholder with real code.
+   */
+  CXCompletionChunk_Placeholder,
+  /**
+   * \brief Informative text that should be displayed but never inserted as
+   * part of the template.
+   *
+   * An "informative" chunk contains annotations that can be displayed to
+   * help the user decide whether a particular code-completion result is the
+   * right option, but which is not part of the actual template to be inserted
+   * by code completion.
+   */
+  CXCompletionChunk_Informative,
+  /**
+   * \brief Text that describes the current parameter when code-completion is
+   * referring to function call, message send, or template specialization.
+   *
+   * A "current parameter" chunk occurs when code-completion is providing
+   * information about a parameter corresponding to the argument at the
+   * code-completion point. For example, given a function
+   *
+   * \code
+   * int add(int x, int y);
+   * \endcode
+   *
+   * and the source code \c add(, where the code-completion point is after the
+   * "(", the code-completion string will contain a "current parameter" chunk
+   * for "int x", indicating that the current argument will initialize that
+   * parameter. After typing further, to \c add(17, (where the code-completion
+   * point is after the ","), the code-completion string will contain a
+   * "current paremeter" chunk to "int y".
+   */
+  CXCompletionChunk_CurrentParameter,
+  /**
+   * \brief A left parenthesis ('('), used to initiate a function call or
+   * signal the beginning of a function parameter list.
+   */
+  CXCompletionChunk_LeftParen,
+  /**
+   * \brief A right parenthesis (')'), used to finish a function call or
+   * signal the end of a function parameter list.
+   */
+  CXCompletionChunk_RightParen,
+  /**
+   * \brief A left bracket ('[').
+   */
+  CXCompletionChunk_LeftBracket,
+  /**
+   * \brief A right bracket (']').
+   */
+  CXCompletionChunk_RightBracket,
+  /**
+   * \brief A left brace ('{').
+   */
+  CXCompletionChunk_LeftBrace,
+  /**
+   * \brief A right brace ('}').
+   */
+  CXCompletionChunk_RightBrace,
+  /**
+   * \brief A left angle bracket ('<').
+   */
+  CXCompletionChunk_LeftAngle,
+  /**
+   * \brief A right angle bracket ('>').
+   */
+  CXCompletionChunk_RightAngle,
+  /**
+   * \brief A comma separator (',').
+   */
+  CXCompletionChunk_Comma,
+  /**
+   * \brief Text that specifies the result type of a given result.
+   *
+   * This special kind of informative chunk is not meant to be inserted into
+   * the text buffer. Rather, it is meant to illustrate the type that an
+   * expression using the given completion string would have.
+   */
+  CXCompletionChunk_ResultType,
+  /**
+   * \brief A colon (':').
+   */
+  CXCompletionChunk_Colon,
+  /**
+   * \brief A semicolon (';').
+   */
+  CXCompletionChunk_SemiColon,
+  /**
+   * \brief An '=' sign.
+   */
+  CXCompletionChunk_Equal,
+  /**
+   * Horizontal space (' ').
+   */
+  CXCompletionChunk_HorizontalSpace,
+  /**
+   * Vertical space ('\n'), after which it is generally a good idea to
+   * perform indentation.
+   */
+  CXCompletionChunk_VerticalSpace
+};
+
+/**
+ * \brief Determine the kind of a particular chunk within a completion string.
+ *
+ * \param completion_string the completion string to query.
+ *
+ * \param chunk_number the 0-based index of the chunk in the completion string.
+ *
+ * \returns the kind of the chunk at the index \c chunk_number.
+ */
+CINDEX_LINKAGE enum CXCompletionChunkKind
+clang_getCompletionChunkKind(CXCompletionString completion_string,
+                             unsigned chunk_number);
+
+/**
+ * \brief Retrieve the text associated with a particular chunk within a
+ * completion string.
+ *
+ * \param completion_string the completion string to query.
+ *
+ * \param chunk_number the 0-based index of the chunk in the completion string.
+ *
+ * \returns the text associated with the chunk at index \c chunk_number.
+ */
+CINDEX_LINKAGE CXString
+clang_getCompletionChunkText(CXCompletionString completion_string,
+                             unsigned chunk_number);
+
+/**
+ * \brief Retrieve the completion string associated with a particular chunk
+ * within a completion string.
+ *
+ * \param completion_string the completion string to query.
+ *
+ * \param chunk_number the 0-based index of the chunk in the completion string.
+ *
+ * \returns the completion string associated with the chunk at index
+ * \c chunk_number, or NULL if that chunk is not represented by a completion
+ * string.
+ */
+CINDEX_LINKAGE CXCompletionString
+clang_getCompletionChunkCompletionString(CXCompletionString completion_string,
+                                         unsigned chunk_number);
+
+/**
+ * \brief Retrieve the number of chunks in the given code-completion string.
+ */
+CINDEX_LINKAGE unsigned
+clang_getNumCompletionChunks(CXCompletionString completion_string);
+
+/**
+ * \brief Contains the results of code-completion.
+ *
+ * This data structure contains the results of code completion, as
+ * produced by \c clang_codeComplete. Its contents must be freed by
+ * \c clang_disposeCodeCompleteResults.
+ */
+typedef struct {
+  /**
+   * \brief The code-completion results.
+   */
+  CXCompletionResult *Results;
+
+  /**
+   * \brief The number of code-completion results stored in the
+   * \c Results array.
+   */
+  unsigned NumResults;
+} CXCodeCompleteResults;
+
+/**
+ * \brief Perform code completion at a given location in a source file.
+ *
+ * This function performs code completion at a particular file, line, and
+ * column within source code, providing results that suggest potential
+ * code snippets based on the context of the completion. The basic model
+ * for code completion is that Clang will parse a complete source file,
+ * performing syntax checking up to the location where code-completion has
+ * been requested. At that point, a special code-completion token is passed
+ * to the parser, which recognizes this token and determines, based on the
+ * current location in the C/Objective-C/C++ grammar and the state of
+ * semantic analysis, what completions to provide. These completions are
+ * returned via a new \c CXCodeCompleteResults structure.
+ *
+ * Code completion itself is meant to be triggered by the client when the
+ * user types punctuation characters or whitespace, at which point the
+ * code-completion location will coincide with the cursor. For example, if \c p
+ * is a pointer, code-completion might be triggered after the "-" and then
+ * after the ">" in \c p->. When the code-completion location is afer the ">",
+ * the completion results will provide, e.g., the members of the struct that
+ * "p" points to. The client is responsible for placing the cursor at the
+ * beginning of the token currently being typed, then filtering the results
+ * based on the contents of the token. For example, when code-completing for
+ * the expression \c p->get, the client should provide the location just after
+ * the ">" (e.g., pointing at the "g") to this code-completion hook. Then, the
+ * client can filter the results based on the current token text ("get"), only
+ * showing those results that start with "get". The intent of this interface
+ * is to separate the relatively high-latency acquisition of code-completion
+ * results from the filtering of results on a per-character basis, which must
+ * have a lower latency.
+ *
+ * \param CIdx the \c CXIndex instance that will be used to perform code
+ * completion.
+ *
+ * \param source_filename the name of the source file that should be parsed to
+ * perform code-completion. This source file must be the same as or include the
+ * filename described by \p complete_filename, or no code-completion results
+ * will be produced.  NOTE: One can also specify NULL for this argument if the
+ * source file is included in command_line_args.
+ *
+ * \param num_command_line_args the number of command-line arguments stored in
+ * \p command_line_args.
+ *
+ * \param command_line_args the command-line arguments to pass to the Clang
+ * compiler to build the given source file. This should include all of the
+ * necessary include paths, language-dialect switches, precompiled header
+ * includes, etc., but should not include any information specific to
+ * code completion.
+ *
+ * \param num_unsaved_files the number of unsaved file entries in \p
+ * unsaved_files.
+ *
+ * \param unsaved_files the files that have not yet been saved to disk
+ * but may be required for code completion, including the contents of
+ * those files.  The contents and name of these files (as specified by
+ * CXUnsavedFile) are copied when necessary, so the client only needs to
+ * guarantee their validity until the call to this function returns.
+ *
+ * \param complete_filename the name of the source file where code completion
+ * should be performed. In many cases, this name will be the same as the
+ * source filename. However, the completion filename may also be a file
+ * included by the source file, which is required when producing
+ * code-completion results for a header.
+ *
+ * \param complete_line the line at which code-completion should occur.
+ *
+ * \param complete_column the column at which code-completion should occur.
+ * Note that the column should point just after the syntactic construct that
+ * initiated code completion, and not in the middle of a lexical token.
+ *
+ * \param diag_callback callback function that will receive any diagnostics
+ * emitted while processing this source file. If NULL, diagnostics will be
+ * suppressed.
+ *
+ * \param diag_client_data client data that will be passed to the diagnostic
+ * callback function.
+ *
+ * \returns if successful, a new CXCodeCompleteResults structure
+ * containing code-completion results, which should eventually be
+ * freed with \c clang_disposeCodeCompleteResults(). If code
+ * completion fails, returns NULL.
+ */
+CINDEX_LINKAGE
+CXCodeCompleteResults *clang_codeComplete(CXIndex CIdx,
+                                          const char *source_filename,
+                                          int num_command_line_args,
+                                          const char **command_line_args,
+                                          unsigned num_unsaved_files,
+                                          struct CXUnsavedFile *unsaved_files,
+                                          const char *complete_filename,
+                                          unsigned complete_line,
+                                          unsigned complete_column);
+
+/**
+ * \brief Free the given set of code-completion results.
+ */
+CINDEX_LINKAGE
+void clang_disposeCodeCompleteResults(CXCodeCompleteResults *Results);
+
+/**
+ * \brief Determine the number of diagnostics produced prior to the
+ * location where code completion was performed.
+ */
+CINDEX_LINKAGE
+unsigned clang_codeCompleteGetNumDiagnostics(CXCodeCompleteResults *Results);
+
+/**
+ * \brief Retrieve a diagnostic associated with the given code completion.
+ *
+ * \param Result the code completion results to query.
+ * \param Index the zero-based diagnostic number to retrieve.
+ *
+ * \returns the requested diagnostic. This diagnostic must be freed
+ * via a call to \c clang_disposeDiagnostic().
+ */
+CINDEX_LINKAGE
+CXDiagnostic clang_codeCompleteGetDiagnostic(CXCodeCompleteResults *Results,
+                                             unsigned Index);
+
+/**
+ * @}
+ */
+
+
+/**
+ * \defgroup CINDEX_MISC Miscellaneous utility functions
+ *
+ * @{
+ */
+
+/**
+ * \brief Return a version string, suitable for showing to a user, but not
+ *        intended to be parsed (the format is not guaranteed to be stable).
+ */
+CINDEX_LINKAGE CXString clang_getClangVersion();
+
+/**
+ * \brief Return a version string, suitable for showing to a user, but not
+ *        intended to be parsed (the format is not guaranteed to be stable).
+ */
+
+
+ /**
+  * \brief Visitor invoked for each file in a translation unit
+  *        (used with clang_getInclusions()).
+  *
+  * This visitor function will be invoked by clang_getInclusions() for each
+  * file included (either at the top-level or by #include directives) within
+  * a translation unit.  The first argument is the file being included, and
+  * the second and third arguments provide the inclusion stack.  The
+  * array is sorted in order of immediate inclusion.  For example,
+  * the first element refers to the location that included 'included_file'.
+  */
+typedef void (*CXInclusionVisitor)(CXFile included_file,
+                                   CXSourceLocation* inclusion_stack,
+                                   unsigned include_len,
+                                   CXClientData client_data);
+
+/**
+ * \brief Visit the set of preprocessor inclusions in a translation unit.
+ *   The visitor function is called with the provided data for every included
+ *   file.  This does not include headers included by the PCH file (unless one
+ *   is inspecting the inclusions in the PCH file itself).
+ */
+CINDEX_LINKAGE void clang_getInclusions(CXTranslationUnit tu,
+                                        CXInclusionVisitor visitor,
+                                        CXClientData client_data);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
diff --git a/include/clang/AST/APValue.h b/include/clang/AST/APValue.h
new file mode 100644
index 0000000..5effa90
--- /dev/null
+++ b/include/clang/AST/APValue.h
@@ -0,0 +1,243 @@
+//===--- APValue.h - Union class for APFloat/APSInt/Complex -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the APValue class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_APVALUE_H
+#define LLVM_CLANG_AST_APVALUE_H
+
+#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/APFloat.h"
+
+namespace clang {
+  class CharUnits;
+  class Expr;
+
+/// APValue - This class implements a discriminated union of [uninitialized]
+/// [APSInt] [APFloat], [Complex APSInt] [Complex APFloat], [Expr + Offset].
+class APValue {
+  typedef llvm::APSInt APSInt;
+  typedef llvm::APFloat APFloat;
+public:
+  enum ValueKind {
+    Uninitialized,
+    Int,
+    Float,
+    ComplexInt,
+    ComplexFloat,
+    LValue,
+    Vector
+  };
+private:
+  ValueKind Kind;
+
+  struct ComplexAPSInt {
+    APSInt Real, Imag;
+    ComplexAPSInt() : Real(1), Imag(1) {}
+  };
+  struct ComplexAPFloat {
+    APFloat Real, Imag;
+    ComplexAPFloat() : Real(0.0), Imag(0.0) {}
+  };
+
+  struct Vec {
+    APValue *Elts;
+    unsigned NumElts;
+    Vec() : Elts(0), NumElts(0) {}
+    ~Vec() { delete[] Elts; }
+  };
+
+  enum {
+    MaxSize = (sizeof(ComplexAPSInt) > sizeof(ComplexAPFloat) ?
+               sizeof(ComplexAPSInt) : sizeof(ComplexAPFloat))
+  };
+
+  union {
+    void *Aligner;
+    char Data[MaxSize];
+  };
+
+public:
+  APValue() : Kind(Uninitialized) {}
+  explicit APValue(const APSInt &I) : Kind(Uninitialized) {
+    MakeInt(); setInt(I);
+  }
+  explicit APValue(const APFloat &F) : Kind(Uninitialized) {
+    MakeFloat(); setFloat(F);
+  }
+  explicit APValue(const APValue *E, unsigned N) : Kind(Uninitialized) {
+    MakeVector(); setVector(E, N);
+  }
+  APValue(const APSInt &R, const APSInt &I) : Kind(Uninitialized) {
+    MakeComplexInt(); setComplexInt(R, I);
+  }
+  APValue(const APFloat &R, const APFloat &I) : Kind(Uninitialized) {
+    MakeComplexFloat(); setComplexFloat(R, I);
+  }
+  APValue(const APValue &RHS) : Kind(Uninitialized) {
+    *this = RHS;
+  }
+  APValue(Expr* B, const CharUnits &O) : Kind(Uninitialized) {
+    MakeLValue(); setLValue(B, O);
+  }
+  APValue(Expr* B);
+
+  ~APValue() {
+    MakeUninit();
+  }
+
+  ValueKind getKind() const { return Kind; }
+  bool isUninit() const { return Kind == Uninitialized; }
+  bool isInt() const { return Kind == Int; }
+  bool isFloat() const { return Kind == Float; }
+  bool isComplexInt() const { return Kind == ComplexInt; }
+  bool isComplexFloat() const { return Kind == ComplexFloat; }
+  bool isLValue() const { return Kind == LValue; }
+  bool isVector() const { return Kind == Vector; }
+
+  void print(llvm::raw_ostream &OS) const;
+  void dump() const;
+
+  APSInt &getInt() {
+    assert(isInt() && "Invalid accessor");
+    return *(APSInt*)(char*)Data;
+  }
+  const APSInt &getInt() const {
+    return const_cast<APValue*>(this)->getInt();
+  }
+
+  APFloat &getFloat() {
+    assert(isFloat() && "Invalid accessor");
+    return *(APFloat*)(char*)Data;
+  }
+  const APFloat &getFloat() const {
+    return const_cast<APValue*>(this)->getFloat();
+  }
+
+  APValue &getVectorElt(unsigned i) {
+    assert(isVector() && "Invalid accessor");
+    return ((Vec*)(char*)Data)->Elts[i];
+  }
+  const APValue &getVectorElt(unsigned i) const {
+    assert(isVector() && "Invalid accessor");
+    return ((const Vec*)(const char*)Data)->Elts[i];
+  }
+  unsigned getVectorLength() const {
+    assert(isVector() && "Invalid accessor");
+    return ((const Vec*)(const void *)Data)->NumElts;
+  }
+
+  APSInt &getComplexIntReal() {
+    assert(isComplexInt() && "Invalid accessor");
+    return ((ComplexAPSInt*)(char*)Data)->Real;
+  }
+  const APSInt &getComplexIntReal() const {
+    return const_cast<APValue*>(this)->getComplexIntReal();
+  }
+
+  APSInt &getComplexIntImag() {
+    assert(isComplexInt() && "Invalid accessor");
+    return ((ComplexAPSInt*)(char*)Data)->Imag;
+  }
+  const APSInt &getComplexIntImag() const {
+    return const_cast<APValue*>(this)->getComplexIntImag();
+  }
+
+  APFloat &getComplexFloatReal() {
+    assert(isComplexFloat() && "Invalid accessor");
+    return ((ComplexAPFloat*)(char*)Data)->Real;
+  }
+  const APFloat &getComplexFloatReal() const {
+    return const_cast<APValue*>(this)->getComplexFloatReal();
+  }
+
+  APFloat &getComplexFloatImag() {
+    assert(isComplexFloat() && "Invalid accessor");
+    return ((ComplexAPFloat*)(char*)Data)->Imag;
+  }
+  const APFloat &getComplexFloatImag() const {
+    return const_cast<APValue*>(this)->getComplexFloatImag();
+  }
+
+  Expr* getLValueBase() const;
+  CharUnits getLValueOffset() const;
+
+  void setInt(const APSInt &I) {
+    assert(isInt() && "Invalid accessor");
+    *(APSInt*)(char*)Data = I;
+  }
+  void setFloat(const APFloat &F) {
+    assert(isFloat() && "Invalid accessor");
+    *(APFloat*)(char*)Data = F;
+  }
+  void setVector(const APValue *E, unsigned N) {
+    assert(isVector() && "Invalid accessor");
+    ((Vec*)(char*)Data)->Elts = new APValue[N];
+    ((Vec*)(char*)Data)->NumElts = N;
+    for (unsigned i = 0; i != N; ++i)
+      ((Vec*)(char*)Data)->Elts[i] = E[i];
+  }
+  void setComplexInt(const APSInt &R, const APSInt &I) {
+    assert(R.getBitWidth() == I.getBitWidth() &&
+           "Invalid complex int (type mismatch).");
+    assert(isComplexInt() && "Invalid accessor");
+    ((ComplexAPSInt*)(char*)Data)->Real = R;
+    ((ComplexAPSInt*)(char*)Data)->Imag = I;
+  }
+  void setComplexFloat(const APFloat &R, const APFloat &I) {
+    assert(&R.getSemantics() == &I.getSemantics() &&
+           "Invalid complex float (type mismatch).");
+    assert(isComplexFloat() && "Invalid accessor");
+    ((ComplexAPFloat*)(char*)Data)->Real = R;
+    ((ComplexAPFloat*)(char*)Data)->Imag = I;
+  }
+  void setLValue(Expr *B, const CharUnits &O);
+
+  const APValue &operator=(const APValue &RHS);
+
+private:
+  void MakeUninit();
+  void MakeInt() {
+    assert(isUninit() && "Bad state change");
+    new ((void*)Data) APSInt(1);
+    Kind = Int;
+  }
+  void MakeFloat() {
+    assert(isUninit() && "Bad state change");
+    new ((void*)(char*)Data) APFloat(0.0);
+    Kind = Float;
+  }
+  void MakeVector() {
+    assert(isUninit() && "Bad state change");
+    new ((void*)(char*)Data) Vec();
+    Kind = Vector;
+  }
+  void MakeComplexInt() {
+    assert(isUninit() && "Bad state change");
+    new ((void*)(char*)Data) ComplexAPSInt();
+    Kind = ComplexInt;
+  }
+  void MakeComplexFloat() {
+    assert(isUninit() && "Bad state change");
+    new ((void*)(char*)Data) ComplexAPFloat();
+    Kind = ComplexFloat;
+  }
+  void MakeLValue();
+};
+
+inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const APValue &V) {
+  V.print(OS);
+  return OS;
+}
+
+} // end namespace clang.
+
+#endif
diff --git a/include/clang/AST/AST.h b/include/clang/AST/AST.h
new file mode 100644
index 0000000..164c5fb
--- /dev/null
+++ b/include/clang/AST/AST.h
@@ -0,0 +1,28 @@
+//===--- AST.h - "Umbrella" header for AST library --------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the interface to the AST classes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_AST_H
+#define LLVM_CLANG_AST_AST_H
+
+// This header exports all AST interfaces.
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprObjC.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/StmtVisitor.h"
+
+#endif
diff --git a/include/clang/AST/ASTConsumer.h b/include/clang/AST/ASTConsumer.h
new file mode 100644
index 0000000..53bb785
--- /dev/null
+++ b/include/clang/AST/ASTConsumer.h
@@ -0,0 +1,80 @@
+//===--- ASTConsumer.h - Abstract interface for reading ASTs ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the ASTConsumer class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_ASTCONSUMER_H
+#define LLVM_CLANG_AST_ASTCONSUMER_H
+
+namespace clang {
+  class ASTContext;
+  class DeclGroupRef;
+  class TagDecl;
+  class HandleTagDeclDefinition;
+  class SemaConsumer; // layering violation required for safe SemaConsumer
+  class VarDecl;
+
+/// ASTConsumer - This is an abstract interface that should be implemented by
+/// clients that read ASTs.  This abstraction layer allows the client to be
+/// independent of the AST producer (e.g. parser vs AST dump file reader, etc).
+class ASTConsumer {
+  /// \brief Whether this AST consumer also requires information about
+  /// semantic analysis.
+  bool SemaConsumer;
+
+  friend class SemaConsumer;
+
+public:
+  ASTConsumer() : SemaConsumer(false) { }
+
+  virtual ~ASTConsumer() {}
+
+  /// Initialize - This is called to initialize the consumer, providing the
+  /// ASTContext.
+  virtual void Initialize(ASTContext &Context) {}
+
+  /// HandleTopLevelDecl - Handle the specified top-level declaration.  This is
+  /// called by the parser to process every top-level Decl*. Note that D can be
+  /// the head of a chain of Decls (e.g. for `int a, b` the chain will have two
+  /// elements). Use Decl::getNextDeclarator() to walk the chain.
+  virtual void HandleTopLevelDecl(DeclGroupRef D);
+
+  /// HandleTranslationUnit - This method is called when the ASTs for entire
+  /// translation unit have been parsed.
+  virtual void HandleTranslationUnit(ASTContext &Ctx) {}
+
+  /// HandleTagDeclDefinition - This callback is invoked each time a TagDecl
+  /// (e.g. struct, union, enum, class) is completed.  This allows the client to
+  /// hack on the type, which can occur at any point in the file (because these
+  /// can be defined in declspecs).
+  virtual void HandleTagDeclDefinition(TagDecl *D) {}
+
+  /// CompleteTentativeDefinition - Callback invoked at the end of a translation
+  /// unit to notify the consumer that the given tentative definition should be
+  /// completed.
+  ///
+  /// The variable declaration itself will be a tentative
+  /// definition. If it had an incomplete array type, its type will
+  /// have already been changed to an array of size 1. However, the
+  /// declaration remains a tentative definition and has not been
+  /// modified by the introduction of an implicit zero initializer.
+  virtual void CompleteTentativeDefinition(VarDecl *D) {}
+
+  /// PrintStats - If desired, print any statistics.
+  virtual void PrintStats() {}
+
+  // Support isa/cast/dyn_cast
+  static bool classof(const ASTConsumer *) { return true; }
+};
+
+} // end namespace clang.
+
+#endif
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
new file mode 100644
index 0000000..b4aa03d
--- /dev/null
+++ b/include/clang/AST/ASTContext.h
@@ -0,0 +1,1391 @@
+//===--- ASTContext.h - Context to hold long-lived AST nodes ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the ASTContext interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_ASTCONTEXT_H
+#define LLVM_CLANG_AST_ASTCONTEXT_H
+
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/OperatorKinds.h"
+#include "clang/Basic/PartialDiagnostic.h"
+#include "clang/AST/Attr.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/NestedNameSpecifier.h"
+#include "clang/AST/PrettyPrinter.h"
+#include "clang/AST/TemplateName.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/CanonicalType.h"
+#include "clang/AST/UsuallyTinyPtrVector.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/Support/Allocator.h"
+#include <vector>
+
+namespace llvm {
+  struct fltSemantics;
+  class raw_ostream;
+}
+
+namespace clang {
+  class FileManager;
+  class ASTRecordLayout;
+  class BlockExpr;
+  class CharUnits;
+  class Diagnostic;
+  class Expr;
+  class ExternalASTSource;
+  class IdentifierTable;
+  class SelectorTable;
+  class SourceManager;
+  class TargetInfo;
+  // Decls
+  class DeclContext;
+  class CXXMethodDecl;
+  class CXXRecordDecl;
+  class Decl;
+  class FieldDecl;
+  class ObjCIvarDecl;
+  class ObjCIvarRefExpr;
+  class ObjCPropertyDecl;
+  class RecordDecl;
+  class StoredDeclsMap;
+  class TagDecl;
+  class TemplateTypeParmDecl;
+  class TranslationUnitDecl;
+  class TypeDecl;
+  class TypedefDecl;
+  class UsingDecl;
+  class UsingShadowDecl;
+  class UnresolvedSetIterator;
+
+  namespace Builtin { class Context; }
+
+/// ASTContext - This class holds long-lived AST nodes (such as types and
+/// decls) that can be referred to throughout the semantic analysis of a file.
+class ASTContext {
+  std::vector<Type*> Types;
+  llvm::FoldingSet<ExtQuals> ExtQualNodes;
+  llvm::FoldingSet<ComplexType> ComplexTypes;
+  llvm::FoldingSet<PointerType> PointerTypes;
+  llvm::FoldingSet<BlockPointerType> BlockPointerTypes;
+  llvm::FoldingSet<LValueReferenceType> LValueReferenceTypes;
+  llvm::FoldingSet<RValueReferenceType> RValueReferenceTypes;
+  llvm::FoldingSet<MemberPointerType> MemberPointerTypes;
+  llvm::FoldingSet<ConstantArrayType> ConstantArrayTypes;
+  llvm::FoldingSet<IncompleteArrayType> IncompleteArrayTypes;
+  std::vector<VariableArrayType*> VariableArrayTypes;
+  llvm::FoldingSet<DependentSizedArrayType> DependentSizedArrayTypes;
+  llvm::FoldingSet<DependentSizedExtVectorType> DependentSizedExtVectorTypes;
+  llvm::FoldingSet<VectorType> VectorTypes;
+  llvm::FoldingSet<FunctionNoProtoType> FunctionNoProtoTypes;
+  llvm::FoldingSet<FunctionProtoType> FunctionProtoTypes;
+  llvm::FoldingSet<DependentTypeOfExprType> DependentTypeOfExprTypes;
+  llvm::FoldingSet<DependentDecltypeType> DependentDecltypeTypes;
+  llvm::FoldingSet<TemplateTypeParmType> TemplateTypeParmTypes;
+  llvm::FoldingSet<SubstTemplateTypeParmType> SubstTemplateTypeParmTypes;
+  llvm::FoldingSet<TemplateSpecializationType> TemplateSpecializationTypes;
+  llvm::FoldingSet<QualifiedNameType> QualifiedNameTypes;
+  llvm::FoldingSet<DependentNameType> DependentNameTypes;
+  llvm::FoldingSet<ObjCInterfaceType> ObjCInterfaceTypes;
+  llvm::FoldingSet<ObjCObjectPointerType> ObjCObjectPointerTypes;
+  llvm::FoldingSet<ElaboratedType> ElaboratedTypes;
+
+  llvm::FoldingSet<QualifiedTemplateName> QualifiedTemplateNames;
+  llvm::FoldingSet<DependentTemplateName> DependentTemplateNames;
+
+  /// \brief The set of nested name specifiers.
+  ///
+  /// This set is managed by the NestedNameSpecifier class.
+  llvm::FoldingSet<NestedNameSpecifier> NestedNameSpecifiers;
+  NestedNameSpecifier *GlobalNestedNameSpecifier;
+  friend class NestedNameSpecifier;
+
+  /// ASTRecordLayouts - A cache mapping from RecordDecls to ASTRecordLayouts.
+  ///  This is lazily created.  This is intentionally not serialized.
+  llvm::DenseMap<const RecordDecl*, const ASTRecordLayout*> ASTRecordLayouts;
+  llvm::DenseMap<const ObjCContainerDecl*, const ASTRecordLayout*> ObjCLayouts;
+
+  /// KeyFunctions - A cache mapping from CXXRecordDecls to key functions.
+  llvm::DenseMap<const CXXRecordDecl*, const CXXMethodDecl*> KeyFunctions;
+  
+  /// \brief Mapping from ObjCContainers to their ObjCImplementations.
+  llvm::DenseMap<ObjCContainerDecl*, ObjCImplDecl*> ObjCImpls;
+
+  /// BuiltinVaListType - built-in va list type.
+  /// This is initially null and set by Sema::LazilyCreateBuiltin when
+  /// a builtin that takes a valist is encountered.
+  QualType BuiltinVaListType;
+
+  /// ObjCIdType - a pseudo built-in typedef type (set by Sema).
+  QualType ObjCIdTypedefType;
+
+  /// ObjCSelType - another pseudo built-in typedef type (set by Sema).
+  QualType ObjCSelTypedefType;
+
+  /// ObjCProtoType - another pseudo built-in typedef type (set by Sema).
+  QualType ObjCProtoType;
+  const RecordType *ProtoStructType;
+
+  /// ObjCClassType - another pseudo built-in typedef type (set by Sema).
+  QualType ObjCClassTypedefType;
+
+  QualType ObjCConstantStringType;
+  RecordDecl *CFConstantStringTypeDecl;
+
+  RecordDecl *NSConstantStringTypeDecl;
+
+  RecordDecl *ObjCFastEnumerationStateTypeDecl;
+
+  /// \brief The type for the C FILE type.
+  TypeDecl *FILEDecl;
+
+  /// \brief The type for the C jmp_buf type.
+  TypeDecl *jmp_bufDecl;
+
+  /// \brief The type for the C sigjmp_buf type.
+  TypeDecl *sigjmp_bufDecl;
+
+  /// \brief Type for the Block descriptor for Blocks CodeGen.
+  RecordDecl *BlockDescriptorType;
+
+  /// \brief Type for the Block descriptor for Blocks CodeGen.
+  RecordDecl *BlockDescriptorExtendedType;
+
+  /// \brief Keeps track of all declaration attributes.
+  ///
+  /// Since so few decls have attrs, we keep them in a hash map instead of
+  /// wasting space in the Decl class.
+  llvm::DenseMap<const Decl*, Attr*> DeclAttrs;
+
+  /// \brief Keeps track of the static data member templates from which
+  /// static data members of class template specializations were instantiated.
+  ///
+  /// This data structure stores the mapping from instantiations of static
+  /// data members to the static data member representations within the
+  /// class template from which they were instantiated along with the kind
+  /// of instantiation or specialization (a TemplateSpecializationKind - 1).
+  ///
+  /// Given the following example:
+  ///
+  /// \code
+  /// template<typename T>
+  /// struct X {
+  ///   static T value;
+  /// };
+  ///
+  /// template<typename T>
+  ///   T X<T>::value = T(17);
+  ///
+  /// int *x = &X<int>::value;
+  /// \endcode
+  ///
+  /// This mapping will contain an entry that maps from the VarDecl for
+  /// X<int>::value to the corresponding VarDecl for X<T>::value (within the
+  /// class template X) and will be marked TSK_ImplicitInstantiation.
+  llvm::DenseMap<const VarDecl *, MemberSpecializationInfo *> 
+    InstantiatedFromStaticDataMember;
+
+  /// \brief Keeps track of the declaration from which a UsingDecl was
+  /// created during instantiation.  The source declaration is always
+  /// a UsingDecl, an UnresolvedUsingValueDecl, or an
+  /// UnresolvedUsingTypenameDecl.
+  ///
+  /// For example:
+  /// \code
+  /// template<typename T>
+  /// struct A {
+  ///   void f();
+  /// };
+  ///
+  /// template<typename T>
+  /// struct B : A<T> {
+  ///   using A<T>::f;
+  /// };
+  ///
+  /// template struct B<int>;
+  /// \endcode
+  ///
+  /// This mapping will contain an entry that maps from the UsingDecl in
+  /// B<int> to the UnresolvedUsingDecl in B<T>.
+  llvm::DenseMap<UsingDecl *, NamedDecl *> InstantiatedFromUsingDecl;
+
+  llvm::DenseMap<UsingShadowDecl*, UsingShadowDecl*>
+    InstantiatedFromUsingShadowDecl;
+
+  llvm::DenseMap<FieldDecl *, FieldDecl *> InstantiatedFromUnnamedFieldDecl;
+
+  /// \brief Mapping that stores the methods overridden by a given C++
+  /// member function.
+  ///
+  /// Since most C++ member functions aren't virtual and therefore
+  /// don't override anything, we store the overridden functions in
+  /// this map on the side rather than within the CXXMethodDecl structure.
+  typedef UsuallyTinyPtrVector<const CXXMethodDecl> CXXMethodVector;
+  llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector> OverriddenMethods;
+
+  TranslationUnitDecl *TUDecl;
+
+  /// SourceMgr - The associated SourceManager object.
+  SourceManager &SourceMgr;
+
+  /// LangOpts - The language options used to create the AST associated with
+  ///  this ASTContext object.
+  LangOptions LangOpts;
+
+  /// MallocAlloc/BumpAlloc - The allocator objects used to create AST objects.
+  bool FreeMemory;
+  llvm::MallocAllocator MallocAlloc;
+  llvm::BumpPtrAllocator BumpAlloc;
+
+  /// \brief Allocator for partial diagnostics.
+  PartialDiagnostic::StorageAllocator DiagAllocator;
+  
+public:
+  const TargetInfo &Target;
+  IdentifierTable &Idents;
+  SelectorTable &Selectors;
+  Builtin::Context &BuiltinInfo;
+  DeclarationNameTable DeclarationNames;
+  llvm::OwningPtr<ExternalASTSource> ExternalSource;
+  clang::PrintingPolicy PrintingPolicy;
+
+  // Typedefs which may be provided defining the structure of Objective-C
+  // pseudo-builtins
+  QualType ObjCIdRedefinitionType;
+  QualType ObjCClassRedefinitionType;
+  QualType ObjCSelRedefinitionType;
+
+  SourceManager& getSourceManager() { return SourceMgr; }
+  const SourceManager& getSourceManager() const { return SourceMgr; }
+  void *Allocate(unsigned Size, unsigned Align = 8) {
+    return FreeMemory ? MallocAlloc.Allocate(Size, Align) :
+                        BumpAlloc.Allocate(Size, Align);
+  }
+  void Deallocate(void *Ptr) {
+    if (FreeMemory)
+      MallocAlloc.Deallocate(Ptr);
+  }
+  
+  PartialDiagnostic::StorageAllocator &getDiagAllocator() {
+    return DiagAllocator;
+  }
+
+  const LangOptions& getLangOptions() const { return LangOpts; }
+
+  FullSourceLoc getFullLoc(SourceLocation Loc) const {
+    return FullSourceLoc(Loc,SourceMgr);
+  }
+
+  /// \brief Retrieve the attributes for the given declaration.
+  Attr*& getDeclAttrs(const Decl *D) { return DeclAttrs[D]; }
+
+  /// \brief Erase the attributes corresponding to the given declaration.
+  void eraseDeclAttrs(const Decl *D) { DeclAttrs.erase(D); }
+
+  /// \brief If this variable is an instantiated static data member of a
+  /// class template specialization, returns the templated static data member
+  /// from which it was instantiated.
+  MemberSpecializationInfo *getInstantiatedFromStaticDataMember(
+                                                           const VarDecl *Var);
+
+  /// \brief Note that the static data member \p Inst is an instantiation of
+  /// the static data member template \p Tmpl of a class template.
+  void setInstantiatedFromStaticDataMember(VarDecl *Inst, VarDecl *Tmpl,
+                                           TemplateSpecializationKind TSK);
+
+  /// \brief If the given using decl is an instantiation of a
+  /// (possibly unresolved) using decl from a template instantiation,
+  /// return it.
+  NamedDecl *getInstantiatedFromUsingDecl(UsingDecl *Inst);
+
+  /// \brief Remember that the using decl \p Inst is an instantiation
+  /// of the using decl \p Pattern of a class template.
+  void setInstantiatedFromUsingDecl(UsingDecl *Inst, NamedDecl *Pattern);
+
+  void setInstantiatedFromUsingShadowDecl(UsingShadowDecl *Inst,
+                                          UsingShadowDecl *Pattern);
+  UsingShadowDecl *getInstantiatedFromUsingShadowDecl(UsingShadowDecl *Inst);
+
+  FieldDecl *getInstantiatedFromUnnamedFieldDecl(FieldDecl *Field);
+
+  void setInstantiatedFromUnnamedFieldDecl(FieldDecl *Inst, FieldDecl *Tmpl);
+
+  // Access to the set of methods overridden by the given C++ method.
+  typedef CXXMethodVector::iterator overridden_cxx_method_iterator;
+  overridden_cxx_method_iterator
+  overridden_methods_begin(const CXXMethodDecl *Method) const;
+
+  overridden_cxx_method_iterator
+  overridden_methods_end(const CXXMethodDecl *Method) const;
+
+  /// \brief Note that the given C++ \p Method overrides the given \p
+  /// Overridden method.
+  void addOverriddenMethod(const CXXMethodDecl *Method, 
+                           const CXXMethodDecl *Overridden);
+  
+  TranslationUnitDecl *getTranslationUnitDecl() const { return TUDecl; }
+
+
+  // Builtin Types.
+  CanQualType VoidTy;
+  CanQualType BoolTy;
+  CanQualType CharTy;
+  CanQualType WCharTy;  // [C++ 3.9.1p5], integer type in C99.
+  CanQualType Char16Ty; // [C++0x 3.9.1p5], integer type in C99.
+  CanQualType Char32Ty; // [C++0x 3.9.1p5], integer type in C99.
+  CanQualType SignedCharTy, ShortTy, IntTy, LongTy, LongLongTy, Int128Ty;
+  CanQualType UnsignedCharTy, UnsignedShortTy, UnsignedIntTy, UnsignedLongTy;
+  CanQualType UnsignedLongLongTy, UnsignedInt128Ty;
+  CanQualType FloatTy, DoubleTy, LongDoubleTy;
+  CanQualType FloatComplexTy, DoubleComplexTy, LongDoubleComplexTy;
+  CanQualType VoidPtrTy, NullPtrTy;
+  CanQualType OverloadTy;
+  CanQualType DependentTy;
+  CanQualType UndeducedAutoTy;
+  CanQualType ObjCBuiltinIdTy, ObjCBuiltinClassTy, ObjCBuiltinSelTy;
+
+  ASTContext(const LangOptions& LOpts, SourceManager &SM, const TargetInfo &t,
+             IdentifierTable &idents, SelectorTable &sels,
+             Builtin::Context &builtins,
+             bool FreeMemory = true, unsigned size_reserve=0);
+
+  ~ASTContext();
+
+  /// \brief Attach an external AST source to the AST context.
+  ///
+  /// The external AST source provides the ability to load parts of
+  /// the abstract syntax tree as needed from some external storage,
+  /// e.g., a precompiled header.
+  void setExternalSource(llvm::OwningPtr<ExternalASTSource> &Source);
+
+  /// \brief Retrieve a pointer to the external AST source associated
+  /// with this AST context, if any.
+  ExternalASTSource *getExternalSource() const { return ExternalSource.get(); }
+
+  void PrintStats() const;
+  const std::vector<Type*>& getTypes() const { return Types; }
+
+  //===--------------------------------------------------------------------===//
+  //                           Type Constructors
+  //===--------------------------------------------------------------------===//
+
+private:
+  /// getExtQualType - Return a type with extended qualifiers.
+  QualType getExtQualType(const Type *Base, Qualifiers Quals);
+
+  QualType getTypeDeclTypeSlow(const TypeDecl *Decl);
+
+public:
+  /// getAddSpaceQualType - Return the uniqued reference to the type for an
+  /// address space qualified type with the specified type and address space.
+  /// The resulting type has a union of the qualifiers from T and the address
+  /// space. If T already has an address space specifier, it is silently
+  /// replaced.
+  QualType getAddrSpaceQualType(QualType T, unsigned AddressSpace);
+
+  /// getObjCGCQualType - Returns the uniqued reference to the type for an
+  /// objc gc qualified type. The retulting type has a union of the qualifiers
+  /// from T and the gc attribute.
+  QualType getObjCGCQualType(QualType T, Qualifiers::GC gcAttr);
+
+  /// getRestrictType - Returns the uniqued reference to the type for a
+  /// 'restrict' qualified type.  The resulting type has a union of the
+  /// qualifiers from T and 'restrict'.
+  QualType getRestrictType(QualType T) {
+    return T.withFastQualifiers(Qualifiers::Restrict);
+  }
+
+  /// getVolatileType - Returns the uniqued reference to the type for a
+  /// 'volatile' qualified type.  The resulting type has a union of the
+  /// qualifiers from T and 'volatile'.
+  QualType getVolatileType(QualType T);
+
+  /// getConstType - Returns the uniqued reference to the type for a
+  /// 'const' qualified type.  The resulting type has a union of the
+  /// qualifiers from T and 'const'.
+  ///
+  /// It can be reasonably expected that this will always be
+  /// equivalent to calling T.withConst().
+  QualType getConstType(QualType T) { return T.withConst(); }
+
+  /// getNoReturnType - Add or remove the noreturn attribute to the given type 
+  /// which must be a FunctionType or a pointer to an allowable type or a 
+  /// BlockPointer.
+  QualType getNoReturnType(QualType T, bool AddNoReturn = true);
+
+  /// getCallConvType - Adds the specified calling convention attribute to
+  /// the given type, which must be a FunctionType or a pointer to an
+  /// allowable type.
+  QualType getCallConvType(QualType T, CallingConv CallConv);
+
+  /// getRegParmType - Sets the specified regparm attribute to
+  /// the given type, which must be a FunctionType or a pointer to an
+  /// allowable type.
+  QualType getRegParmType(QualType T, unsigned RegParm);
+
+  /// getComplexType - Return the uniqued reference to the type for a complex
+  /// number with the specified element type.
+  QualType getComplexType(QualType T);
+  CanQualType getComplexType(CanQualType T) {
+    return CanQualType::CreateUnsafe(getComplexType((QualType) T));
+  }
+
+  /// getPointerType - Return the uniqued reference to the type for a pointer to
+  /// the specified type.
+  QualType getPointerType(QualType T);
+  CanQualType getPointerType(CanQualType T) {
+    return CanQualType::CreateUnsafe(getPointerType((QualType) T));
+  }
+
+  /// getBlockPointerType - Return the uniqued reference to the type for a block
+  /// of the specified type.
+  QualType getBlockPointerType(QualType T);
+
+  /// This gets the struct used to keep track of the descriptor for pointer to
+  /// blocks.
+  QualType getBlockDescriptorType();
+
+  // Set the type for a Block descriptor type.
+  void setBlockDescriptorType(QualType T);
+  /// Get the BlockDescriptorType type, or NULL if it hasn't yet been built.
+  QualType getRawBlockdescriptorType() {
+    if (BlockDescriptorType)
+      return getTagDeclType(BlockDescriptorType);
+    return QualType();
+  }
+
+  /// This gets the struct used to keep track of the extended descriptor for
+  /// pointer to blocks.
+  QualType getBlockDescriptorExtendedType();
+
+  // Set the type for a Block descriptor extended type.
+  void setBlockDescriptorExtendedType(QualType T);
+  /// Get the BlockDescriptorExtendedType type, or NULL if it hasn't yet been
+  /// built.
+  QualType getRawBlockdescriptorExtendedType() {
+    if (BlockDescriptorExtendedType)
+      return getTagDeclType(BlockDescriptorExtendedType);
+    return QualType();
+  }
+
+  /// This gets the struct used to keep track of pointer to blocks, complete
+  /// with captured variables.
+  QualType getBlockParmType(bool BlockHasCopyDispose,
+                            llvm::SmallVector<const Expr *, 8> &BDRDs);
+
+  /// This builds the struct used for __block variables.
+  QualType BuildByRefType(const char *DeclName, QualType Ty);
+
+  /// Returns true iff we need copy/dispose helpers for the given type.
+  bool BlockRequiresCopying(QualType Ty);
+
+  /// getLValueReferenceType - Return the uniqued reference to the type for an
+  /// lvalue reference to the specified type.
+  QualType getLValueReferenceType(QualType T, bool SpelledAsLValue = true);
+
+  /// getRValueReferenceType - Return the uniqued reference to the type for an
+  /// rvalue reference to the specified type.
+  QualType getRValueReferenceType(QualType T);
+
+  /// getMemberPointerType - Return the uniqued reference to the type for a
+  /// member pointer to the specified type in the specified class. The class
+  /// is a Type because it could be a dependent name.
+  QualType getMemberPointerType(QualType T, const Type *Cls);
+
+  /// getVariableArrayType - Returns a non-unique reference to the type for a
+  /// variable array of the specified element type.
+  QualType getVariableArrayType(QualType EltTy, Expr *NumElts,
+                                ArrayType::ArraySizeModifier ASM,
+                                unsigned EltTypeQuals,
+                                SourceRange Brackets);
+
+  /// getDependentSizedArrayType - Returns a non-unique reference to
+  /// the type for a dependently-sized array of the specified element
+  /// type. FIXME: We will need these to be uniqued, or at least
+  /// comparable, at some point.
+  QualType getDependentSizedArrayType(QualType EltTy, Expr *NumElts,
+                                      ArrayType::ArraySizeModifier ASM,
+                                      unsigned EltTypeQuals,
+                                      SourceRange Brackets);
+
+  /// getIncompleteArrayType - Returns a unique reference to the type for a
+  /// incomplete array of the specified element type.
+  QualType getIncompleteArrayType(QualType EltTy,
+                                  ArrayType::ArraySizeModifier ASM,
+                                  unsigned EltTypeQuals);
+
+  /// getConstantArrayType - Return the unique reference to the type for a
+  /// constant array of the specified element type.
+  QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize,
+                                ArrayType::ArraySizeModifier ASM,
+                                unsigned EltTypeQuals);
+
+  /// getVectorType - Return the unique reference to a vector type of
+  /// the specified element type and size. VectorType must be a built-in type.
+  QualType getVectorType(QualType VectorType, unsigned NumElts,
+                         bool AltiVec, bool IsPixel);
+
+  /// getExtVectorType - Return the unique reference to an extended vector type
+  /// of the specified element type and size.  VectorType must be a built-in
+  /// type.
+  QualType getExtVectorType(QualType VectorType, unsigned NumElts);
+
+  /// getDependentSizedExtVectorType - Returns a non-unique reference to
+  /// the type for a dependently-sized vector of the specified element
+  /// type. FIXME: We will need these to be uniqued, or at least
+  /// comparable, at some point.
+  QualType getDependentSizedExtVectorType(QualType VectorType,
+                                          Expr *SizeExpr,
+                                          SourceLocation AttrLoc);
+
+  /// getFunctionNoProtoType - Return a K&R style C function type like 'int()'.
+  ///
+  QualType getFunctionNoProtoType(QualType ResultTy,
+                                  const FunctionType::ExtInfo &Info);
+
+  QualType getFunctionNoProtoType(QualType ResultTy) {
+    return getFunctionNoProtoType(ResultTy, FunctionType::ExtInfo());
+  }
+
+  /// getFunctionType - Return a normal function type with a typed argument
+  /// list.  isVariadic indicates whether the argument list includes '...'.
+  QualType getFunctionType(QualType ResultTy, const QualType *ArgArray,
+                           unsigned NumArgs, bool isVariadic,
+                           unsigned TypeQuals, bool hasExceptionSpec,
+                           bool hasAnyExceptionSpec,
+                           unsigned NumExs, const QualType *ExArray,
+                           const FunctionType::ExtInfo &Info);
+
+  /// getTypeDeclType - Return the unique reference to the type for
+  /// the specified type declaration.
+  QualType getTypeDeclType(const TypeDecl *Decl,
+                           const TypeDecl *PrevDecl = 0) {
+    assert(Decl && "Passed null for Decl param");
+    if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0);
+
+    if (PrevDecl) {
+      assert(PrevDecl->TypeForDecl && "previous decl has no TypeForDecl");
+      Decl->TypeForDecl = PrevDecl->TypeForDecl;
+      return QualType(PrevDecl->TypeForDecl, 0);
+    }
+
+    return getTypeDeclTypeSlow(Decl);
+  }
+
+  /// getTypedefType - Return the unique reference to the type for the
+  /// specified typename decl.
+  QualType getTypedefType(const TypedefDecl *Decl);
+
+  QualType getInjectedClassNameType(CXXRecordDecl *Decl, QualType TST);
+
+  QualType getSubstTemplateTypeParmType(const TemplateTypeParmType *Replaced,
+                                        QualType Replacement);
+
+  QualType getTemplateTypeParmType(unsigned Depth, unsigned Index,
+                                   bool ParameterPack,
+                                   IdentifierInfo *Name = 0);
+
+  QualType getTemplateSpecializationType(TemplateName T,
+                                         const TemplateArgument *Args,
+                                         unsigned NumArgs,
+                                         QualType Canon = QualType(),
+                                         bool IsCurrentInstantiation = false);
+
+  QualType getTemplateSpecializationType(TemplateName T,
+                                         const TemplateArgumentListInfo &Args,
+                                         QualType Canon = QualType(),
+                                         bool IsCurrentInstantiation = false);
+
+  TypeSourceInfo *
+  getTemplateSpecializationTypeInfo(TemplateName T, SourceLocation TLoc,
+                                    const TemplateArgumentListInfo &Args,
+                                    QualType Canon = QualType());
+
+  QualType getQualifiedNameType(NestedNameSpecifier *NNS,
+                                QualType NamedType);
+  QualType getDependentNameType(ElaboratedTypeKeyword Keyword,
+                                NestedNameSpecifier *NNS,
+                                const IdentifierInfo *Name,
+                                QualType Canon = QualType());
+  QualType getDependentNameType(ElaboratedTypeKeyword Keyword,
+                                NestedNameSpecifier *NNS,
+                                const TemplateSpecializationType *TemplateId,
+                                QualType Canon = QualType());
+  QualType getElaboratedType(QualType UnderlyingType,
+                             ElaboratedType::TagKind Tag);
+
+  QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl,
+                                ObjCProtocolDecl **Protocols = 0,
+                                unsigned NumProtocols = 0);
+
+  /// getObjCObjectPointerType - Return a ObjCObjectPointerType type for the
+  /// given interface decl and the conforming protocol list.
+  QualType getObjCObjectPointerType(QualType OIT,
+                                    ObjCProtocolDecl **ProtocolList = 0,
+                                    unsigned NumProtocols = 0,
+                                    unsigned Quals = 0);
+
+  /// getTypeOfType - GCC extension.
+  QualType getTypeOfExprType(Expr *e);
+  QualType getTypeOfType(QualType t);
+
+  /// getDecltypeType - C++0x decltype.
+  QualType getDecltypeType(Expr *e);
+
+  /// getTagDeclType - Return the unique reference to the type for the
+  /// specified TagDecl (struct/union/class/enum) decl.
+  QualType getTagDeclType(const TagDecl *Decl);
+
+  /// getSizeType - Return the unique type for "size_t" (C99 7.17), defined
+  /// in <stddef.h>. The sizeof operator requires this (C99 6.5.3.4p4).
+  CanQualType getSizeType() const;
+
+  /// getWCharType - In C++, this returns the unique wchar_t type.  In C99, this
+  /// returns a type compatible with the type defined in <stddef.h> as defined
+  /// by the target.
+  QualType getWCharType() const { return WCharTy; }
+
+  /// getSignedWCharType - Return the type of "signed wchar_t".
+  /// Used when in C++, as a GCC extension.
+  QualType getSignedWCharType() const;
+
+  /// getUnsignedWCharType - Return the type of "unsigned wchar_t".
+  /// Used when in C++, as a GCC extension.
+  QualType getUnsignedWCharType() const;
+
+  /// getPointerDiffType - Return the unique type for "ptrdiff_t" (ref?)
+  /// defined in <stddef.h>. Pointer - pointer requires this (C99 6.5.6p9).
+  QualType getPointerDiffType() const;
+
+  // getCFConstantStringType - Return the C structure type used to represent
+  // constant CFStrings.
+  QualType getCFConstantStringType();
+
+  // getNSConstantStringType - Return the C structure type used to represent
+  // constant NSStrings.
+  QualType getNSConstantStringType();
+  /// Get the structure type used to representation NSStrings, or NULL
+  /// if it hasn't yet been built.
+  QualType getRawNSConstantStringType() {
+    if (NSConstantStringTypeDecl)
+      return getTagDeclType(NSConstantStringTypeDecl);
+    return QualType();
+  }
+  void setNSConstantStringType(QualType T);
+
+
+  /// Get the structure type used to representation CFStrings, or NULL
+  /// if it hasn't yet been built.
+  QualType getRawCFConstantStringType() {
+    if (CFConstantStringTypeDecl)
+      return getTagDeclType(CFConstantStringTypeDecl);
+    return QualType();
+  }
+  void setCFConstantStringType(QualType T);
+
+  // This setter/getter represents the ObjC type for an NSConstantString.
+  void setObjCConstantStringInterface(ObjCInterfaceDecl *Decl);
+  QualType getObjCConstantStringInterface() const {
+    return ObjCConstantStringType;
+  }
+
+  //// This gets the struct used to keep track of fast enumerations.
+  QualType getObjCFastEnumerationStateType();
+
+  /// Get the ObjCFastEnumerationState type, or NULL if it hasn't yet
+  /// been built.
+  QualType getRawObjCFastEnumerationStateType() {
+    if (ObjCFastEnumerationStateTypeDecl)
+      return getTagDeclType(ObjCFastEnumerationStateTypeDecl);
+    return QualType();
+  }
+
+  void setObjCFastEnumerationStateType(QualType T);
+
+  /// \brief Set the type for the C FILE type.
+  void setFILEDecl(TypeDecl *FILEDecl) { this->FILEDecl = FILEDecl; }
+
+  /// \brief Retrieve the C FILE type.
+  QualType getFILEType() {
+    if (FILEDecl)
+      return getTypeDeclType(FILEDecl);
+    return QualType();
+  }
+
+  /// \brief Set the type for the C jmp_buf type.
+  void setjmp_bufDecl(TypeDecl *jmp_bufDecl) {
+    this->jmp_bufDecl = jmp_bufDecl;
+  }
+
+  /// \brief Retrieve the C jmp_buf type.
+  QualType getjmp_bufType() {
+    if (jmp_bufDecl)
+      return getTypeDeclType(jmp_bufDecl);
+    return QualType();
+  }
+
+  /// \brief Set the type for the C sigjmp_buf type.
+  void setsigjmp_bufDecl(TypeDecl *sigjmp_bufDecl) {
+    this->sigjmp_bufDecl = sigjmp_bufDecl;
+  }
+
+  /// \brief Retrieve the C sigjmp_buf type.
+  QualType getsigjmp_bufType() {
+    if (sigjmp_bufDecl)
+      return getTypeDeclType(sigjmp_bufDecl);
+    return QualType();
+  }
+
+  /// getObjCEncodingForType - Emit the ObjC type encoding for the
+  /// given type into \arg S. If \arg NameFields is specified then
+  /// record field names are also encoded.
+  void getObjCEncodingForType(QualType t, std::string &S,
+                              const FieldDecl *Field=0);
+
+  void getLegacyIntegralTypeEncoding(QualType &t) const;
+
+  // Put the string version of type qualifiers into S.
+  void getObjCEncodingForTypeQualifier(Decl::ObjCDeclQualifier QT,
+                                       std::string &S) const;
+
+  /// getObjCEncodingForMethodDecl - Return the encoded type for this method
+  /// declaration.
+  void getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl, std::string &S);
+
+  /// getObjCEncodingForBlockDecl - Return the encoded type for this block
+  /// declaration.
+  void getObjCEncodingForBlock(const BlockExpr *Expr, std::string& S);
+  
+  /// getObjCEncodingForPropertyDecl - Return the encoded type for
+  /// this method declaration. If non-NULL, Container must be either
+  /// an ObjCCategoryImplDecl or ObjCImplementationDecl; it should
+  /// only be NULL when getting encodings for protocol properties.
+  void getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD,
+                                      const Decl *Container,
+                                      std::string &S);
+
+  bool ProtocolCompatibleWithProtocol(ObjCProtocolDecl *lProto,
+                                      ObjCProtocolDecl *rProto);
+
+  /// getObjCEncodingTypeSize returns size of type for objective-c encoding
+  /// purpose in characters.
+  CharUnits getObjCEncodingTypeSize(QualType t);
+
+  /// This setter/getter represents the ObjC 'id' type. It is setup lazily, by
+  /// Sema.  id is always a (typedef for a) pointer type, a pointer to a struct.
+  QualType getObjCIdType() const { return ObjCIdTypedefType; }
+  void setObjCIdType(QualType T);
+
+  void setObjCSelType(QualType T);
+  QualType getObjCSelType() const { return ObjCSelTypedefType; }
+
+  void setObjCProtoType(QualType QT);
+  QualType getObjCProtoType() const { return ObjCProtoType; }
+
+  /// This setter/getter repreents the ObjC 'Class' type. It is setup lazily, by
+  /// Sema.  'Class' is always a (typedef for a) pointer type, a pointer to a
+  /// struct.
+  QualType getObjCClassType() const { return ObjCClassTypedefType; }
+  void setObjCClassType(QualType T);
+
+  void setBuiltinVaListType(QualType T);
+  QualType getBuiltinVaListType() const { return BuiltinVaListType; }
+
+  /// getCVRQualifiedType - Returns a type with additional const,
+  /// volatile, or restrict qualifiers.
+  QualType getCVRQualifiedType(QualType T, unsigned CVR) {
+    return getQualifiedType(T, Qualifiers::fromCVRMask(CVR));
+  }
+
+  /// getQualifiedType - Returns a type with additional qualifiers.
+  QualType getQualifiedType(QualType T, Qualifiers Qs) {
+    if (!Qs.hasNonFastQualifiers())
+      return T.withFastQualifiers(Qs.getFastQualifiers());
+    QualifierCollector Qc(Qs);
+    const Type *Ptr = Qc.strip(T);
+    return getExtQualType(Ptr, Qc);
+  }
+
+  /// getQualifiedType - Returns a type with additional qualifiers.
+  QualType getQualifiedType(const Type *T, Qualifiers Qs) {
+    if (!Qs.hasNonFastQualifiers())
+      return QualType(T, Qs.getFastQualifiers());
+    return getExtQualType(T, Qs);
+  }
+
+  DeclarationName getNameForTemplate(TemplateName Name);
+
+  TemplateName getOverloadedTemplateName(UnresolvedSetIterator Begin,
+                                         UnresolvedSetIterator End);
+
+  TemplateName getQualifiedTemplateName(NestedNameSpecifier *NNS,
+                                        bool TemplateKeyword,
+                                        TemplateDecl *Template);
+
+  TemplateName getDependentTemplateName(NestedNameSpecifier *NNS,
+                                        const IdentifierInfo *Name);
+  TemplateName getDependentTemplateName(NestedNameSpecifier *NNS,
+                                        OverloadedOperatorKind Operator);
+
+  enum GetBuiltinTypeError {
+    GE_None,              //< No error
+    GE_Missing_stdio,     //< Missing a type from <stdio.h>
+    GE_Missing_setjmp     //< Missing a type from <setjmp.h>
+  };
+
+  /// GetBuiltinType - Return the type for the specified builtin.
+  QualType GetBuiltinType(unsigned ID, GetBuiltinTypeError &Error);
+
+private:
+  CanQualType getFromTargetType(unsigned Type) const;
+
+  //===--------------------------------------------------------------------===//
+  //                         Type Predicates.
+  //===--------------------------------------------------------------------===//
+
+public:
+  /// getObjCGCAttr - Returns one of GCNone, Weak or Strong objc's
+  /// garbage collection attribute.
+  ///
+  Qualifiers::GC getObjCGCAttrKind(const QualType &Ty) const;
+
+  /// isObjCNSObjectType - Return true if this is an NSObject object with
+  /// its NSObject attribute set.
+  bool isObjCNSObjectType(QualType Ty) const;
+
+  //===--------------------------------------------------------------------===//
+  //                         Type Sizing and Analysis
+  //===--------------------------------------------------------------------===//
+
+  /// getFloatTypeSemantics - Return the APFloat 'semantics' for the specified
+  /// scalar floating point type.
+  const llvm::fltSemantics &getFloatTypeSemantics(QualType T) const;
+
+  /// getTypeInfo - Get the size and alignment of the specified complete type in
+  /// bits.
+  std::pair<uint64_t, unsigned> getTypeInfo(const Type *T);
+  std::pair<uint64_t, unsigned> getTypeInfo(QualType T) {
+    return getTypeInfo(T.getTypePtr());
+  }
+
+  /// getTypeSize - Return the size of the specified type, in bits.  This method
+  /// does not work on incomplete types.
+  uint64_t getTypeSize(QualType T) {
+    return getTypeInfo(T).first;
+  }
+  uint64_t getTypeSize(const Type *T) {
+    return getTypeInfo(T).first;
+  }
+
+  /// getCharWidth - Return the size of the character type, in bits
+  uint64_t getCharWidth() {
+    return getTypeSize(CharTy);
+  }
+  
+  /// getTypeSizeInChars - Return the size of the specified type, in characters.
+  /// This method does not work on incomplete types.
+  CharUnits getTypeSizeInChars(QualType T);
+  CharUnits getTypeSizeInChars(const Type *T);
+
+  /// getTypeAlign - Return the ABI-specified alignment of a type, in bits.
+  /// This method does not work on incomplete types.
+  unsigned getTypeAlign(QualType T) {
+    return getTypeInfo(T).second;
+  }
+  unsigned getTypeAlign(const Type *T) {
+    return getTypeInfo(T).second;
+  }
+
+  /// getTypeAlignInChars - Return the ABI-specified alignment of a type, in 
+  /// characters. This method does not work on incomplete types.
+  CharUnits getTypeAlignInChars(QualType T);
+  CharUnits getTypeAlignInChars(const Type *T);
+
+  /// getPreferredTypeAlign - Return the "preferred" alignment of the specified
+  /// type for the current target in bits.  This can be different than the ABI
+  /// alignment in cases where it is beneficial for performance to overalign
+  /// a data type.
+  unsigned getPreferredTypeAlign(const Type *T);
+
+  /// getDeclAlign - Return a conservative estimate of the alignment of
+  /// the specified decl.  Note that bitfields do not have a valid alignment, so
+  /// this method will assert on them.
+  /// If @p RefAsPointee, references are treated like their underlying type
+  /// (for alignof), else they're treated like pointers (for CodeGen).
+  CharUnits getDeclAlign(const Decl *D, bool RefAsPointee = false);
+
+  /// getASTRecordLayout - Get or compute information about the layout of the
+  /// specified record (struct/union/class), which indicates its size and field
+  /// position information.
+  const ASTRecordLayout &getASTRecordLayout(const RecordDecl *D);
+
+  /// getASTObjCInterfaceLayout - Get or compute information about the
+  /// layout of the specified Objective-C interface.
+  const ASTRecordLayout &getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D);
+
+  void DumpRecordLayout(const RecordDecl *RD, llvm::raw_ostream &OS);
+
+  /// getASTObjCImplementationLayout - Get or compute information about
+  /// the layout of the specified Objective-C implementation. This may
+  /// differ from the interface if synthesized ivars are present.
+  const ASTRecordLayout &
+  getASTObjCImplementationLayout(const ObjCImplementationDecl *D);
+
+  /// getKeyFunction - Get the key function for the given record decl. 
+  /// The key function is, according to the Itanium C++ ABI section 5.2.3:
+  ///
+  /// ...the first non-pure virtual function that is not inline at the point
+  /// of class definition.
+  const CXXMethodDecl *getKeyFunction(const CXXRecordDecl *RD);
+
+  void CollectObjCIvars(const ObjCInterfaceDecl *OI,
+                        llvm::SmallVectorImpl<FieldDecl*> &Fields);
+
+  void ShallowCollectObjCIvars(const ObjCInterfaceDecl *OI,
+                               llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars);
+  void CollectNonClassIvars(const ObjCInterfaceDecl *OI,
+                               llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars);
+  void CollectIvarsToConstructOrDestruct(const ObjCInterfaceDecl *OI,
+                                    llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars,
+                                    bool construct=true);
+  unsigned CountNonClassIvars(const ObjCInterfaceDecl *OI);
+  void CollectInheritedProtocols(const Decl *CDecl,
+                          llvm::SmallPtrSet<ObjCProtocolDecl*, 8> &Protocols);
+
+  //===--------------------------------------------------------------------===//
+  //                            Type Operators
+  //===--------------------------------------------------------------------===//
+
+  /// getCanonicalType - Return the canonical (structural) type corresponding to
+  /// the specified potentially non-canonical type.  The non-canonical version
+  /// of a type may have many "decorated" versions of types.  Decorators can
+  /// include typedefs, 'typeof' operators, etc. The returned type is guaranteed
+  /// to be free of any of these, allowing two canonical types to be compared
+  /// for exact equality with a simple pointer comparison.
+  CanQualType getCanonicalType(QualType T);
+  const Type *getCanonicalType(const Type *T) {
+    return T->getCanonicalTypeInternal().getTypePtr();
+  }
+
+  /// getCanonicalParamType - Return the canonical parameter type
+  /// corresponding to the specific potentially non-canonical one.
+  /// Qualifiers are stripped off, functions are turned into function
+  /// pointers, and arrays decay one level into pointers.
+  CanQualType getCanonicalParamType(QualType T);
+
+  /// \brief Determine whether the given types are equivalent.
+  bool hasSameType(QualType T1, QualType T2) {
+    return getCanonicalType(T1) == getCanonicalType(T2);
+  }
+
+  /// \brief Returns this type as a completely-unqualified array type,
+  /// capturing the qualifiers in Quals. This will remove the minimal amount of
+  /// sugaring from the types, similar to the behavior of
+  /// QualType::getUnqualifiedType().
+  ///
+  /// \param T is the qualified type, which may be an ArrayType
+  ///
+  /// \param Quals will receive the full set of qualifiers that were
+  /// applied to the array.
+  ///
+  /// \returns if this is an array type, the completely unqualified array type
+  /// that corresponds to it. Otherwise, returns T.getUnqualifiedType().
+  QualType getUnqualifiedArrayType(QualType T, Qualifiers &Quals);
+
+  /// \brief Determine whether the given types are equivalent after
+  /// cvr-qualifiers have been removed.
+  bool hasSameUnqualifiedType(QualType T1, QualType T2) {
+    CanQualType CT1 = getCanonicalType(T1);
+    CanQualType CT2 = getCanonicalType(T2);
+
+    Qualifiers Quals;
+    QualType UnqualT1 = getUnqualifiedArrayType(CT1, Quals);
+    QualType UnqualT2 = getUnqualifiedArrayType(CT2, Quals);
+    return UnqualT1 == UnqualT2;
+  }
+
+  /// \brief Retrieves the "canonical" declaration of
+
+  /// \brief Retrieves the "canonical" nested name specifier for a
+  /// given nested name specifier.
+  ///
+  /// The canonical nested name specifier is a nested name specifier
+  /// that uniquely identifies a type or namespace within the type
+  /// system. For example, given:
+  ///
+  /// \code
+  /// namespace N {
+  ///   struct S {
+  ///     template<typename T> struct X { typename T* type; };
+  ///   };
+  /// }
+  ///
+  /// template<typename T> struct Y {
+  ///   typename N::S::X<T>::type member;
+  /// };
+  /// \endcode
+  ///
+  /// Here, the nested-name-specifier for N::S::X<T>:: will be
+  /// S::X<template-param-0-0>, since 'S' and 'X' are uniquely defined
+  /// by declarations in the type system and the canonical type for
+  /// the template type parameter 'T' is template-param-0-0.
+  NestedNameSpecifier *
+  getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS);
+
+  /// \brief Retrieves the canonical representation of the given
+  /// calling convention.
+  CallingConv getCanonicalCallConv(CallingConv CC) {
+    if (CC == CC_C)
+      return CC_Default;
+    return CC;
+  }
+
+  /// \brief Determines whether two calling conventions name the same
+  /// calling convention.
+  bool isSameCallConv(CallingConv lcc, CallingConv rcc) {
+    return (getCanonicalCallConv(lcc) == getCanonicalCallConv(rcc));
+  }
+
+  /// \brief Retrieves the "canonical" template name that refers to a
+  /// given template.
+  ///
+  /// The canonical template name is the simplest expression that can
+  /// be used to refer to a given template. For most templates, this
+  /// expression is just the template declaration itself. For example,
+  /// the template std::vector can be referred to via a variety of
+  /// names---std::vector, ::std::vector, vector (if vector is in
+  /// scope), etc.---but all of these names map down to the same
+  /// TemplateDecl, which is used to form the canonical template name.
+  ///
+  /// Dependent template names are more interesting. Here, the
+  /// template name could be something like T::template apply or
+  /// std::allocator<T>::template rebind, where the nested name
+  /// specifier itself is dependent. In this case, the canonical
+  /// template name uses the shortest form of the dependent
+  /// nested-name-specifier, which itself contains all canonical
+  /// types, values, and templates.
+  TemplateName getCanonicalTemplateName(TemplateName Name);
+
+  /// \brief Determine whether the given template names refer to the same
+  /// template.
+  bool hasSameTemplateName(TemplateName X, TemplateName Y);
+  
+  /// \brief Retrieve the "canonical" template argument.
+  ///
+  /// The canonical template argument is the simplest template argument
+  /// (which may be a type, value, expression, or declaration) that
+  /// expresses the value of the argument.
+  TemplateArgument getCanonicalTemplateArgument(const TemplateArgument &Arg);
+
+  /// Type Query functions.  If the type is an instance of the specified class,
+  /// return the Type pointer for the underlying maximally pretty type.  This
+  /// is a member of ASTContext because this may need to do some amount of
+  /// canonicalization, e.g. to move type qualifiers into the element type.
+  const ArrayType *getAsArrayType(QualType T);
+  const ConstantArrayType *getAsConstantArrayType(QualType T) {
+    return dyn_cast_or_null<ConstantArrayType>(getAsArrayType(T));
+  }
+  const VariableArrayType *getAsVariableArrayType(QualType T) {
+    return dyn_cast_or_null<VariableArrayType>(getAsArrayType(T));
+  }
+  const IncompleteArrayType *getAsIncompleteArrayType(QualType T) {
+    return dyn_cast_or_null<IncompleteArrayType>(getAsArrayType(T));
+  }
+  const DependentSizedArrayType *getAsDependentSizedArrayType(QualType T) {
+    return dyn_cast_or_null<DependentSizedArrayType>(getAsArrayType(T));
+  }
+  
+  /// getBaseElementType - Returns the innermost element type of an array type.
+  /// For example, will return "int" for int[m][n]
+  QualType getBaseElementType(const ArrayType *VAT);
+
+  /// getBaseElementType - Returns the innermost element type of a type
+  /// (which needn't actually be an array type).
+  QualType getBaseElementType(QualType QT);
+
+  /// getConstantArrayElementCount - Returns number of constant array elements.
+  uint64_t getConstantArrayElementCount(const ConstantArrayType *CA) const;
+
+  /// getArrayDecayedType - Return the properly qualified result of decaying the
+  /// specified array type to a pointer.  This operation is non-trivial when
+  /// handling typedefs etc.  The canonical type of "T" must be an array type,
+  /// this returns a pointer to a properly qualified element of the array.
+  ///
+  /// See C99 6.7.5.3p7 and C99 6.3.2.1p3.
+  QualType getArrayDecayedType(QualType T);
+
+  /// getPromotedIntegerType - Returns the type that Promotable will
+  /// promote to: C99 6.3.1.1p2, assuming that Promotable is a promotable
+  /// integer type.
+  QualType getPromotedIntegerType(QualType PromotableType);
+
+  /// \brief Whether this is a promotable bitfield reference according
+  /// to C99 6.3.1.1p2, bullet 2 (and GCC extensions).
+  ///
+  /// \returns the type this bit-field will promote to, or NULL if no
+  /// promotion occurs.
+  QualType isPromotableBitField(Expr *E);
+
+  /// getIntegerTypeOrder - Returns the highest ranked integer type:
+  /// C99 6.3.1.8p1.  If LHS > RHS, return 1.  If LHS == RHS, return 0. If
+  /// LHS < RHS, return -1.
+  int getIntegerTypeOrder(QualType LHS, QualType RHS);
+
+  /// getFloatingTypeOrder - Compare the rank of the two specified floating
+  /// point types, ignoring the domain of the type (i.e. 'double' ==
+  /// '_Complex double').  If LHS > RHS, return 1.  If LHS == RHS, return 0. If
+  /// LHS < RHS, return -1.
+  int getFloatingTypeOrder(QualType LHS, QualType RHS);
+
+  /// getFloatingTypeOfSizeWithinDomain - Returns a real floating
+  /// point or a complex type (based on typeDomain/typeSize).
+  /// 'typeDomain' is a real floating point or complex type.
+  /// 'typeSize' is a real floating point or complex type.
+  QualType getFloatingTypeOfSizeWithinDomain(QualType typeSize,
+                                             QualType typeDomain) const;
+
+private:
+  // Helper for integer ordering
+  unsigned getIntegerRank(Type* T);
+
+public:
+
+  //===--------------------------------------------------------------------===//
+  //                    Type Compatibility Predicates
+  //===--------------------------------------------------------------------===//
+
+  /// Compatibility predicates used to check assignment expressions.
+  bool typesAreCompatible(QualType, QualType); // C99 6.2.7p1
+
+  bool typesAreBlockPointerCompatible(QualType, QualType); 
+
+  bool isObjCIdType(QualType T) const {
+    return T == ObjCIdTypedefType;
+  }
+  bool isObjCClassType(QualType T) const {
+    return T == ObjCClassTypedefType;
+  }
+  bool isObjCSelType(QualType T) const {
+    return T == ObjCSelTypedefType;
+  }
+  bool QualifiedIdConformsQualifiedId(QualType LHS, QualType RHS);
+  bool ObjCQualifiedIdTypesAreCompatible(QualType LHS, QualType RHS,
+                                         bool ForCompare);
+
+  // Check the safety of assignment from LHS to RHS
+  bool canAssignObjCInterfaces(const ObjCObjectPointerType *LHSOPT,
+                               const ObjCObjectPointerType *RHSOPT);
+  bool canAssignObjCInterfaces(const ObjCInterfaceType *LHS,
+                               const ObjCInterfaceType *RHS);
+  bool canAssignObjCInterfacesInBlockPointer(
+                                          const ObjCObjectPointerType *LHSOPT,
+                                          const ObjCObjectPointerType *RHSOPT);
+  bool areComparableObjCPointerTypes(QualType LHS, QualType RHS);
+  QualType areCommonBaseCompatible(const ObjCObjectPointerType *LHSOPT,
+                                   const ObjCObjectPointerType *RHSOPT);
+  
+  // Functions for calculating composite types
+  QualType mergeTypes(QualType, QualType, bool OfBlockPointer=false);
+  QualType mergeFunctionTypes(QualType, QualType, bool OfBlockPointer=false);
+
+  /// UsualArithmeticConversionsType - handles the various conversions
+  /// that are common to binary operators (C99 6.3.1.8, C++ [expr]p9)
+  /// and returns the result type of that conversion.
+  QualType UsualArithmeticConversionsType(QualType lhs, QualType rhs);
+
+  //===--------------------------------------------------------------------===//
+  //                    Integer Predicates
+  //===--------------------------------------------------------------------===//
+
+  // The width of an integer, as defined in C99 6.2.6.2. This is the number
+  // of bits in an integer type excluding any padding bits.
+  unsigned getIntWidth(QualType T);
+
+  // Per C99 6.2.5p6, for every signed integer type, there is a corresponding
+  // unsigned integer type.  This method takes a signed type, and returns the
+  // corresponding unsigned integer type.
+  QualType getCorrespondingUnsignedType(QualType T);
+
+  //===--------------------------------------------------------------------===//
+  //                    Type Iterators.
+  //===--------------------------------------------------------------------===//
+
+  typedef std::vector<Type*>::iterator       type_iterator;
+  typedef std::vector<Type*>::const_iterator const_type_iterator;
+
+  type_iterator types_begin() { return Types.begin(); }
+  type_iterator types_end() { return Types.end(); }
+  const_type_iterator types_begin() const { return Types.begin(); }
+  const_type_iterator types_end() const { return Types.end(); }
+
+  //===--------------------------------------------------------------------===//
+  //                    Integer Values
+  //===--------------------------------------------------------------------===//
+
+  /// MakeIntValue - Make an APSInt of the appropriate width and
+  /// signedness for the given \arg Value and integer \arg Type.
+  llvm::APSInt MakeIntValue(uint64_t Value, QualType Type) {
+    llvm::APSInt Res(getIntWidth(Type), !Type->isSignedIntegerType());
+    Res = Value;
+    return Res;
+  }
+
+  /// \brief Get the implementation of ObjCInterfaceDecl,or NULL if none exists.
+  ObjCImplementationDecl *getObjCImplementation(ObjCInterfaceDecl *D);
+  /// \brief Get the implementation of ObjCCategoryDecl, or NULL if none exists.
+  ObjCCategoryImplDecl   *getObjCImplementation(ObjCCategoryDecl *D);
+
+  /// \brief Set the implementation of ObjCInterfaceDecl.
+  void setObjCImplementation(ObjCInterfaceDecl *IFaceD,
+                             ObjCImplementationDecl *ImplD);
+  /// \brief Set the implementation of ObjCCategoryDecl.
+  void setObjCImplementation(ObjCCategoryDecl *CatD,
+                             ObjCCategoryImplDecl *ImplD);
+
+  /// \brief Allocate an uninitialized TypeSourceInfo.
+  ///
+  /// The caller should initialize the memory held by TypeSourceInfo using
+  /// the TypeLoc wrappers.
+  ///
+  /// \param T the type that will be the basis for type source info. This type
+  /// should refer to how the declarator was written in source code, not to
+  /// what type semantic analysis resolved the declarator to.
+  ///
+  /// \param Size the size of the type info to create, or 0 if the size
+  /// should be calculated based on the type.
+  TypeSourceInfo *CreateTypeSourceInfo(QualType T, unsigned Size = 0);
+
+  /// \brief Allocate a TypeSourceInfo where all locations have been
+  /// initialized to a given location, which defaults to the empty
+  /// location.
+  TypeSourceInfo *
+  getTrivialTypeSourceInfo(QualType T, SourceLocation Loc = SourceLocation());
+
+private:
+  ASTContext(const ASTContext&); // DO NOT IMPLEMENT
+  void operator=(const ASTContext&); // DO NOT IMPLEMENT
+
+  void InitBuiltinTypes();
+  void InitBuiltinType(CanQualType &R, BuiltinType::Kind K);
+
+  // Return the ObjC type encoding for a given type.
+  void getObjCEncodingForTypeImpl(QualType t, std::string &S,
+                                  bool ExpandPointedToStructures,
+                                  bool ExpandStructures,
+                                  const FieldDecl *Field,
+                                  bool OutermostType = false,
+                                  bool EncodingProperty = false);
+
+  const ASTRecordLayout &getObjCLayout(const ObjCInterfaceDecl *D,
+                                       const ObjCImplementationDecl *Impl);
+  
+private:
+  // FIXME: This currently contains the set of StoredDeclMaps used
+  // by DeclContext objects.  This probably should not be in ASTContext,
+  // but we include it here so that ASTContext can quickly deallocate them.
+  llvm::PointerIntPair<StoredDeclsMap*,1> LastSDM;
+  friend class DeclContext;
+  void ReleaseDeclContextMaps();
+};
+  
+/// @brief Utility function for constructing a nullary selector.
+static inline Selector GetNullarySelector(const char* name, ASTContext& Ctx) {
+  IdentifierInfo* II = &Ctx.Idents.get(name);
+  return Ctx.Selectors.getSelector(0, &II);
+}
+
+/// @brief Utility function for constructing an unary selector.
+static inline Selector GetUnarySelector(const char* name, ASTContext& Ctx) {
+  IdentifierInfo* II = &Ctx.Idents.get(name);
+  return Ctx.Selectors.getSelector(1, &II);
+}
+
+}  // end namespace clang
+
+// operator new and delete aren't allowed inside namespaces.
+// The throw specifications are mandated by the standard.
+/// @brief Placement new for using the ASTContext's allocator.
+///
+/// This placement form of operator new uses the ASTContext's allocator for
+/// obtaining memory. It is a non-throwing new, which means that it returns
+/// null on error. (If that is what the allocator does. The current does, so if
+/// this ever changes, this operator will have to be changed, too.)
+/// Usage looks like this (assuming there's an ASTContext 'Context' in scope):
+/// @code
+/// // Default alignment (8)
+/// IntegerLiteral *Ex = new (Context) IntegerLiteral(arguments);
+/// // Specific alignment
+/// IntegerLiteral *Ex2 = new (Context, 4) IntegerLiteral(arguments);
+/// @endcode
+/// Please note that you cannot use delete on the pointer; it must be
+/// deallocated using an explicit destructor call followed by
+/// @c Context.Deallocate(Ptr).
+///
+/// @param Bytes The number of bytes to allocate. Calculated by the compiler.
+/// @param C The ASTContext that provides the allocator.
+/// @param Alignment The alignment of the allocated memory (if the underlying
+///                  allocator supports it).
+/// @return The allocated memory. Could be NULL.
+inline void *operator new(size_t Bytes, clang::ASTContext &C,
+                          size_t Alignment) throw () {
+  return C.Allocate(Bytes, Alignment);
+}
+/// @brief Placement delete companion to the new above.
+///
+/// This operator is just a companion to the new above. There is no way of
+/// invoking it directly; see the new operator for more details. This operator
+/// is called implicitly by the compiler if a placement new expression using
+/// the ASTContext throws in the object constructor.
+inline void operator delete(void *Ptr, clang::ASTContext &C, size_t)
+              throw () {
+  C.Deallocate(Ptr);
+}
+
+/// This placement form of operator new[] uses the ASTContext's allocator for
+/// obtaining memory. It is a non-throwing new[], which means that it returns
+/// null on error.
+/// Usage looks like this (assuming there's an ASTContext 'Context' in scope):
+/// @code
+/// // Default alignment (8)
+/// char *data = new (Context) char[10];
+/// // Specific alignment
+/// char *data = new (Context, 4) char[10];
+/// @endcode
+/// Please note that you cannot use delete on the pointer; it must be
+/// deallocated using an explicit destructor call followed by
+/// @c Context.Deallocate(Ptr).
+///
+/// @param Bytes The number of bytes to allocate. Calculated by the compiler.
+/// @param C The ASTContext that provides the allocator.
+/// @param Alignment The alignment of the allocated memory (if the underlying
+///                  allocator supports it).
+/// @return The allocated memory. Could be NULL.
+inline void *operator new[](size_t Bytes, clang::ASTContext& C,
+                            size_t Alignment = 8) throw () {
+  return C.Allocate(Bytes, Alignment);
+}
+
+/// @brief Placement delete[] companion to the new[] above.
+///
+/// This operator is just a companion to the new[] above. There is no way of
+/// invoking it directly; see the new[] operator for more details. This operator
+/// is called implicitly by the compiler if a placement new[] expression using
+/// the ASTContext throws in the object constructor.
+inline void operator delete[](void *Ptr, clang::ASTContext &C, size_t)
+              throw () {
+  C.Deallocate(Ptr);
+}
+
+#endif
diff --git a/include/clang/AST/ASTDiagnostic.h b/include/clang/AST/ASTDiagnostic.h
new file mode 100644
index 0000000..2d31491
--- /dev/null
+++ b/include/clang/AST/ASTDiagnostic.h
@@ -0,0 +1,47 @@
+//===--- ASTDiagnostic.h - Diagnostics for the AST library ------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_DIAGNOSTICAST_H
+#define LLVM_CLANG_DIAGNOSTICAST_H
+
+#include "clang/Basic/Diagnostic.h"
+
+namespace clang {
+  namespace diag {
+    enum {
+#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE) ENUM,
+#define ASTSTART
+#include "clang/Basic/DiagnosticASTKinds.inc"
+#undef DIAG
+      NUM_BUILTIN_AST_DIAGNOSTICS
+    };
+  }  // end namespace diag
+  
+  /// \brief Diagnostic argument formatting function for diagnostics that
+  /// involve AST nodes.
+  ///
+  /// This function formats diagnostic arguments for various AST nodes, 
+  /// including types, declaration names, nested name specifiers, and
+  /// declaration contexts, into strings that can be printed as part of
+  /// diagnostics. It is meant to be used as the argument to
+  /// \c Diagnostic::SetArgToStringFn(), where the cookie is an \c ASTContext
+  /// pointer.
+  void FormatASTNodeDiagnosticArgument(Diagnostic::ArgumentKind Kind, 
+                                       intptr_t Val,
+                                       const char *Modifier, 
+                                       unsigned ModLen,
+                                       const char *Argument, 
+                                       unsigned ArgLen,
+                                      const Diagnostic::ArgumentValue *PrevArgs,
+                                       unsigned NumPrevArgs,
+                                       llvm::SmallVectorImpl<char> &Output,
+                                       void *Cookie);
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/AST/ASTImporter.h b/include/clang/AST/ASTImporter.h
new file mode 100644
index 0000000..7975c43
--- /dev/null
+++ b/include/clang/AST/ASTImporter.h
@@ -0,0 +1,240 @@
+//===--- ASTImporter.h - Importing ASTs from other Contexts -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the ASTImporter class which imports AST nodes from one
+//  context into another context.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_AST_ASTIMPORTER_H
+#define LLVM_CLANG_AST_ASTIMPORTER_H
+
+#include "clang/AST/Type.h"
+#include "clang/AST/DeclarationName.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace clang {
+  class ASTContext;
+  class Decl;
+  class DeclContext;
+  class Diagnostic;
+  class Expr;
+  class FileManager;
+  class IdentifierInfo;
+  class NestedNameSpecifier;
+  class Stmt;
+  class TypeSourceInfo;
+  
+  /// \brief Imports selected nodes from one AST context into another context,
+  /// merging AST nodes where appropriate.
+  class ASTImporter {
+  public:
+    typedef llvm::DenseSet<std::pair<Decl *, Decl *> > NonEquivalentDeclSet;
+    
+  private:
+    /// \brief The contexts we're importing to and from.
+    ASTContext &ToContext, &FromContext;
+    
+    /// \brief The file managers we're importing to and from.
+    FileManager &ToFileManager, &FromFileManager;
+    
+    /// \brief The diagnostics object that we should use to emit diagnostics.
+    Diagnostic &Diags;
+    
+    /// \brief Mapping from the already-imported types in the "from" context
+    /// to the corresponding types in the "to" context.
+    llvm::DenseMap<Type *, Type *> ImportedTypes;
+    
+    /// \brief Mapping from the already-imported declarations in the "from"
+    /// context to the corresponding declarations in the "to" context.
+    llvm::DenseMap<Decl *, Decl *> ImportedDecls;
+
+    /// \brief Mapping from the already-imported statements in the "from"
+    /// context to the corresponding statements in the "to" context.
+    llvm::DenseMap<Stmt *, Stmt *> ImportedStmts;
+
+    /// \brief Mapping from the already-imported FileIDs in the "from" source
+    /// manager to the corresponding FileIDs in the "to" source manager.
+    llvm::DenseMap<unsigned, FileID> ImportedFileIDs;
+    
+    /// \brief Imported, anonymous tag declarations that are missing their 
+    /// corresponding typedefs.
+    llvm::SmallVector<TagDecl *, 4> AnonTagsWithPendingTypedefs;
+    
+    /// \brief Declaration (from, to) pairs that are known not to be equivalent
+    /// (which we have already complained about).
+    NonEquivalentDeclSet NonEquivalentDecls;
+    
+  public:
+    ASTImporter(Diagnostic &Diags,
+                ASTContext &ToContext, FileManager &ToFileManager,
+                ASTContext &FromContext, FileManager &FromFileManager);
+    
+    virtual ~ASTImporter();
+    
+    /// \brief Import the given type from the "from" context into the "to"
+    /// context.
+    ///
+    /// \returns the equivalent type in the "to" context, or a NULL type if
+    /// an error occurred.
+    QualType Import(QualType FromT);
+
+    /// \brief Import the given type source information from the
+    /// "from" context into the "to" context.
+    ///
+    /// \returns the equivalent type source information in the "to"
+    /// context, or NULL if an error occurred.
+    TypeSourceInfo *Import(TypeSourceInfo *FromTSI);
+
+    /// \brief Import the given declaration from the "from" context into the 
+    /// "to" context.
+    ///
+    /// \returns the equivalent declaration in the "to" context, or a NULL type 
+    /// if an error occurred.
+    Decl *Import(Decl *FromD);
+
+    /// \brief Import the given declaration context from the "from"
+    /// AST context into the "to" AST context.
+    ///
+    /// \returns the equivalent declaration context in the "to"
+    /// context, or a NULL type if an error occurred.
+    DeclContext *ImportContext(DeclContext *FromDC);
+    
+    /// \brief Import the given expression from the "from" context into the
+    /// "to" context.
+    ///
+    /// \returns the equivalent expression in the "to" context, or NULL if
+    /// an error occurred.
+    Expr *Import(Expr *FromE);
+
+    /// \brief Import the given statement from the "from" context into the
+    /// "to" context.
+    ///
+    /// \returns the equivalent statement in the "to" context, or NULL if
+    /// an error occurred.
+    Stmt *Import(Stmt *FromS);
+
+    /// \brief Import the given nested-name-specifier from the "from"
+    /// context into the "to" context.
+    ///
+    /// \returns the equivalent nested-name-specifier in the "to"
+    /// context, or NULL if an error occurred.
+    NestedNameSpecifier *Import(NestedNameSpecifier *FromNNS);
+    
+    /// \brief Import the given source location from the "from" context into
+    /// the "to" context.
+    ///
+    /// \returns the equivalent source location in the "to" context, or an
+    /// invalid source location if an error occurred.
+    SourceLocation Import(SourceLocation FromLoc);
+
+    /// \brief Import the given source range from the "from" context into
+    /// the "to" context.
+    ///
+    /// \returns the equivalent source range in the "to" context, or an
+    /// invalid source location if an error occurred.
+    SourceRange Import(SourceRange FromRange);
+
+    /// \brief Import the given declaration name from the "from"
+    /// context into the "to" context.
+    ///
+    /// \returns the equivalent declaration name in the "to" context,
+    /// or an empty declaration name if an error occurred.
+    DeclarationName Import(DeclarationName FromName);
+
+    /// \brief Import the given identifier from the "from" context
+    /// into the "to" context.
+    ///
+    /// \returns the equivalent identifier in the "to" context.
+    IdentifierInfo *Import(IdentifierInfo *FromId);
+
+    /// \brief Import the given Objective-C selector from the "from"
+    /// context into the "to" context.
+    ///
+    /// \returns the equivalent selector in the "to" context.
+    Selector Import(Selector FromSel);
+
+    /// \brief Import the given file ID from the "from" context into the 
+    /// "to" context.
+    ///
+    /// \returns the equivalent file ID in the source manager of the "to"
+    /// context.
+    FileID Import(FileID);
+    
+    /// \brief Cope with a name conflict when importing a declaration into the
+    /// given context.
+    ///
+    /// This routine is invoked whenever there is a name conflict while 
+    /// importing a declaration. The returned name will become the name of the
+    /// imported declaration. By default, the returned name is the same as the
+    /// original name, leaving the conflict unresolve such that name lookup
+    /// for this name is likely to find an ambiguity later.
+    ///
+    /// Subclasses may override this routine to resolve the conflict, e.g., by
+    /// renaming the declaration being imported.
+    ///
+    /// \param Name the name of the declaration being imported, which conflicts
+    /// with other declarations.
+    ///
+    /// \param DC the declaration context (in the "to" AST context) in which 
+    /// the name is being imported.
+    ///
+    /// \param IDNS the identifier namespace in which the name will be found.
+    ///
+    /// \param Decls the set of declarations with the same name as the
+    /// declaration being imported.
+    ///
+    /// \param NumDecls the number of conflicting declarations in \p Decls.
+    ///
+    /// \returns the name that the newly-imported declaration should have.
+    virtual DeclarationName HandleNameConflict(DeclarationName Name,
+                                               DeclContext *DC,
+                                               unsigned IDNS,
+                                               NamedDecl **Decls,
+                                               unsigned NumDecls);
+    
+    /// \brief Retrieve the context that AST nodes are being imported into.
+    ASTContext &getToContext() const { return ToContext; }
+    
+    /// \brief Retrieve the context that AST nodes are being imported from.
+    ASTContext &getFromContext() const { return FromContext; }
+    
+    /// \brief Retrieve the file manager that AST nodes are being imported into.
+    FileManager &getToFileManager() const { return ToFileManager; }
+
+    /// \brief Retrieve the file manager that AST nodes are being imported from.
+    FileManager &getFromFileManager() const { return FromFileManager; }
+
+    /// \brief Retrieve the diagnostic formatter.
+    Diagnostic &getDiags() const { return Diags; }
+    
+    /// \brief Report a diagnostic in the "to" context.
+    DiagnosticBuilder ToDiag(SourceLocation Loc, unsigned DiagID);
+    
+    /// \brief Report a diagnostic in the "from" context.
+    DiagnosticBuilder FromDiag(SourceLocation Loc, unsigned DiagID);
+    
+    /// \brief Return the set of declarations that we know are not equivalent.
+    NonEquivalentDeclSet &getNonEquivalentDecls() { return NonEquivalentDecls; }
+    
+    /// \brief Note that we have imported the "from" declaration by mapping it
+    /// to the (potentially-newly-created) "to" declaration.
+    ///
+    /// \returns \p To
+    Decl *Imported(Decl *From, Decl *To);
+    
+    /// \brief Determine whether the given types are structurally
+    /// equivalent.
+    bool IsStructurallyEquivalent(QualType From, QualType To);
+  };
+}
+
+#endif // LLVM_CLANG_AST_ASTIMPORTER_H
diff --git a/include/clang/AST/ASTVector.h b/include/clang/AST/ASTVector.h
new file mode 100644
index 0000000..217dfad
--- /dev/null
+++ b/include/clang/AST/ASTVector.h
@@ -0,0 +1,397 @@
+//===- ASTVector.h - Vector that uses ASTContext for allocation  --*- C++ -*-=//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file provides ASTVector, a vector  ADT whose contents are
+//  allocated using the allocator associated with an ASTContext..
+//
+//===----------------------------------------------------------------------===//
+
+// FIXME: Most of this is copy-and-paste from BumpVector.h and SmallVector.h.
+// We can refactor this core logic into something common.
+
+#ifndef LLVM_CLANG_AST_VECTOR
+#define LLVM_CLANG_AST_VECTOR
+
+#include "llvm/Support/type_traits.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include <algorithm>
+#include <memory>
+#include <cstring>
+
+#ifdef _MSC_VER
+namespace std {
+#if _MSC_VER <= 1310
+  // Work around flawed VC++ implementation of std::uninitialized_copy.  Define
+  // additional overloads so that elements with pointer types are recognized as
+  // scalars and not objects, causing bizarre type conversion errors.
+  template<class T1, class T2>
+  inline _Scalar_ptr_iterator_tag _Ptr_cat(T1 **, T2 **) {
+    _Scalar_ptr_iterator_tag _Cat;
+    return _Cat;
+  }
+
+  template<class T1, class T2>
+  inline _Scalar_ptr_iterator_tag _Ptr_cat(T1* const *, T2 **) {
+    _Scalar_ptr_iterator_tag _Cat;
+    return _Cat;
+  }
+#else
+  // FIXME: It is not clear if the problem is fixed in VS 2005.  What is clear
+  // is that the above hack won't work if it wasn't fixed.
+#endif
+}
+#endif
+
+namespace clang {
+
+template<typename T>
+class ASTVector {
+  T *Begin, *End, *Capacity;
+
+  void setEnd(T *P) { this->End = P; }
+
+public:
+  // Default ctor - Initialize to empty.
+  explicit ASTVector(ASTContext &C, unsigned N = 0)
+  : Begin(NULL), End(NULL), Capacity(NULL) {
+    reserve(C, N);
+  }
+
+  ~ASTVector() {
+    if (llvm::is_class<T>::value) {
+      // Destroy the constructed elements in the vector.
+      destroy_range(Begin, End);
+    }
+  }
+
+  typedef size_t size_type;
+  typedef ptrdiff_t difference_type;
+  typedef T value_type;
+  typedef T* iterator;
+  typedef const T* const_iterator;
+
+  typedef std::reverse_iterator<const_iterator>  const_reverse_iterator;
+  typedef std::reverse_iterator<iterator>  reverse_iterator;
+
+  typedef T& reference;
+  typedef const T& const_reference;
+  typedef T* pointer;
+  typedef const T* const_pointer;
+
+  // forward iterator creation methods.
+  iterator begin() { return Begin; }
+  const_iterator begin() const { return Begin; }
+  iterator end() { return End; }
+  const_iterator end() const { return End; }
+
+  // reverse iterator creation methods.
+  reverse_iterator rbegin()            { return reverse_iterator(end()); }
+  const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); }
+  reverse_iterator rend()              { return reverse_iterator(begin()); }
+  const_reverse_iterator rend() const { return const_reverse_iterator(begin());}
+
+  bool empty() const { return Begin == End; }
+  size_type size() const { return End-Begin; }
+
+  reference operator[](unsigned idx) {
+    assert(Begin + idx < End);
+    return Begin[idx];
+  }
+  const_reference operator[](unsigned idx) const {
+    assert(Begin + idx < End);
+    return Begin[idx];
+  }
+
+  reference front() {
+    return begin()[0];
+  }
+  const_reference front() const {
+    return begin()[0];
+  }
+
+  reference back() {
+    return end()[-1];
+  }
+  const_reference back() const {
+    return end()[-1];
+  }
+
+  void pop_back() {
+    --End;
+    End->~T();
+  }
+
+  T pop_back_val() {
+    T Result = back();
+    pop_back();
+    return Result;
+  }
+
+  void clear() {
+    if (llvm::is_class<T>::value) {
+      destroy_range(Begin, End);
+    }
+    End = Begin;
+  }
+
+  /// data - Return a pointer to the vector's buffer, even if empty().
+  pointer data() {
+    return pointer(Begin);
+  }
+
+  /// data - Return a pointer to the vector's buffer, even if empty().
+  const_pointer data() const {
+    return const_pointer(Begin);
+  }
+
+  void push_back(const_reference Elt, ASTContext &C) {
+    if (End < Capacity) {
+    Retry:
+      new (End) T(Elt);
+      ++End;
+      return;
+    }
+    grow(C);
+    goto Retry;
+  }
+
+  void reserve(ASTContext &C, unsigned N) {
+    if (unsigned(Capacity-Begin) < N)
+      grow(C, N);
+  }
+
+  /// capacity - Return the total number of elements in the currently allocated
+  /// buffer.
+  size_t capacity() const { return Capacity - Begin; }
+
+  /// append - Add the specified range to the end of the SmallVector.
+  ///
+  template<typename in_iter>
+  void append(ASTContext &C, in_iter in_start, in_iter in_end) {
+    size_type NumInputs = std::distance(in_start, in_end);
+
+    if (NumInputs == 0)
+      return;
+
+    // Grow allocated space if needed.
+    if (NumInputs > size_type(this->capacity_ptr()-this->end()))
+      this->grow(C, this->size()+NumInputs);
+
+    // Copy the new elements over.
+    // TODO: NEED To compile time dispatch on whether in_iter is a random access
+    // iterator to use the fast uninitialized_copy.
+    std::uninitialized_copy(in_start, in_end, this->end());
+    this->setEnd(this->end() + NumInputs);
+  }
+
+  /// append - Add the specified range to the end of the SmallVector.
+  ///
+  void append(ASTContext &C, size_type NumInputs, const T &Elt) {
+    // Grow allocated space if needed.
+    if (NumInputs > size_type(this->capacity_ptr()-this->end()))
+      this->grow(C, this->size()+NumInputs);
+
+    // Copy the new elements over.
+    std::uninitialized_fill_n(this->end(), NumInputs, Elt);
+    this->setEnd(this->end() + NumInputs);
+  }
+
+  /// uninitialized_copy - Copy the range [I, E) onto the uninitialized memory
+  /// starting with "Dest", constructing elements into it as needed.
+  template<typename It1, typename It2>
+  static void uninitialized_copy(It1 I, It1 E, It2 Dest) {
+    std::uninitialized_copy(I, E, Dest);
+  }
+
+  iterator insert(ASTContext &C, iterator I, const T &Elt) {
+    if (I == this->end()) {  // Important special case for empty vector.
+      push_back(Elt);
+      return this->end()-1;
+    }
+
+    if (this->EndX < this->CapacityX) {
+    Retry:
+      new (this->end()) T(this->back());
+      this->setEnd(this->end()+1);
+      // Push everything else over.
+      std::copy_backward(I, this->end()-1, this->end());
+      *I = Elt;
+      return I;
+    }
+    size_t EltNo = I-this->begin();
+    this->grow(C);
+    I = this->begin()+EltNo;
+    goto Retry;
+  }
+
+  iterator insert(ASTContext &C, iterator I, size_type NumToInsert,
+                  const T &Elt) {
+    if (I == this->end()) {  // Important special case for empty vector.
+      append(C, NumToInsert, Elt);
+      return this->end()-1;
+    }
+
+    // Convert iterator to elt# to avoid invalidating iterator when we reserve()
+    size_t InsertElt = I - this->begin();
+
+    // Ensure there is enough space.
+    reserve(C, static_cast<unsigned>(this->size() + NumToInsert));
+
+    // Uninvalidate the iterator.
+    I = this->begin()+InsertElt;
+
+    // If there are more elements between the insertion point and the end of the
+    // range than there are being inserted, we can use a simple approach to
+    // insertion.  Since we already reserved space, we know that this won't
+    // reallocate the vector.
+    if (size_t(this->end()-I) >= NumToInsert) {
+      T *OldEnd = this->end();
+      append(C, this->end()-NumToInsert, this->end());
+
+      // Copy the existing elements that get replaced.
+      std::copy_backward(I, OldEnd-NumToInsert, OldEnd);
+
+      std::fill_n(I, NumToInsert, Elt);
+      return I;
+    }
+
+    // Otherwise, we're inserting more elements than exist already, and we're
+    // not inserting at the end.
+
+    // Copy over the elements that we're about to overwrite.
+    T *OldEnd = this->end();
+    this->setEnd(this->end() + NumToInsert);
+    size_t NumOverwritten = OldEnd-I;
+    this->uninitialized_copy(I, OldEnd, this->end()-NumOverwritten);
+
+    // Replace the overwritten part.
+    std::fill_n(I, NumOverwritten, Elt);
+
+    // Insert the non-overwritten middle part.
+    std::uninitialized_fill_n(OldEnd, NumToInsert-NumOverwritten, Elt);
+    return I;
+  }
+
+  template<typename ItTy>
+  iterator insert(ASTContext &C, iterator I, ItTy From, ItTy To) {
+    if (I == this->end()) {  // Important special case for empty vector.
+      append(C, From, To);
+      return this->end()-1;
+    }
+
+    size_t NumToInsert = std::distance(From, To);
+    // Convert iterator to elt# to avoid invalidating iterator when we reserve()
+    size_t InsertElt = I - this->begin();
+
+    // Ensure there is enough space.
+    reserve(C, static_cast<unsigned>(this->size() + NumToInsert));
+
+    // Uninvalidate the iterator.
+    I = this->begin()+InsertElt;
+
+    // If there are more elements between the insertion point and the end of the
+    // range than there are being inserted, we can use a simple approach to
+    // insertion.  Since we already reserved space, we know that this won't
+    // reallocate the vector.
+    if (size_t(this->end()-I) >= NumToInsert) {
+      T *OldEnd = this->end();
+      append(C, this->end()-NumToInsert, this->end());
+
+      // Copy the existing elements that get replaced.
+      std::copy_backward(I, OldEnd-NumToInsert, OldEnd);
+
+      std::copy(From, To, I);
+      return I;
+    }
+
+    // Otherwise, we're inserting more elements than exist already, and we're
+    // not inserting at the end.
+
+    // Copy over the elements that we're about to overwrite.
+    T *OldEnd = this->end();
+    this->setEnd(this->end() + NumToInsert);
+    size_t NumOverwritten = OldEnd-I;
+    this->uninitialized_copy(I, OldEnd, this->end()-NumOverwritten);
+
+    // Replace the overwritten part.
+    for (; NumOverwritten > 0; --NumOverwritten) {
+      *I = *From;
+      ++I; ++From;
+    }
+
+    // Insert the non-overwritten middle part.
+    this->uninitialized_copy(From, To, OldEnd);
+    return I;
+  }
+
+  void resize(ASTContext &C, unsigned N, const T &NV) {
+    if (N < this->size()) {
+      this->destroy_range(this->begin()+N, this->end());
+      this->setEnd(this->begin()+N);
+    } else if (N > this->size()) {
+      if (this->capacity() < N)
+        this->grow(C, N);
+      construct_range(this->end(), this->begin()+N, NV);
+      this->setEnd(this->begin()+N);
+    }
+  }
+
+private:
+  /// grow - double the size of the allocated memory, guaranteeing space for at
+  /// least one more element or MinSize if specified.
+  void grow(ASTContext &C, size_type MinSize = 1);
+
+  void construct_range(T *S, T *E, const T &Elt) {
+    for (; S != E; ++S)
+      new (S) T(Elt);
+  }
+
+  void destroy_range(T *S, T *E) {
+    while (S != E) {
+      --E;
+      E->~T();
+    }
+  }
+
+protected:
+  iterator capacity_ptr() { return (iterator)this->Capacity; }
+};
+
+// Define this out-of-line to dissuade the C++ compiler from inlining it.
+template <typename T>
+void ASTVector<T>::grow(ASTContext &C, size_t MinSize) {
+  size_t CurCapacity = Capacity-Begin;
+  size_t CurSize = size();
+  size_t NewCapacity = 2*CurCapacity;
+  if (NewCapacity < MinSize)
+    NewCapacity = MinSize;
+
+  // Allocate the memory from the ASTContext.
+  T *NewElts = new (C) T[NewCapacity];
+
+  // Copy the elements over.
+  if (llvm::is_class<T>::value) {
+    std::uninitialized_copy(Begin, End, NewElts);
+    // Destroy the original elements.
+    destroy_range(Begin, End);
+  }
+  else {
+    // Use memcpy for PODs (std::uninitialized_copy optimizes to memmove).
+    memcpy(NewElts, Begin, CurSize * sizeof(T));
+  }
+
+  C.Deallocate(Begin);
+  Begin = NewElts;
+  End = NewElts+CurSize;
+  Capacity = Begin+NewCapacity;
+}
+
+} // end: clang namespace
+#endif
diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h
new file mode 100644
index 0000000..1974493
--- /dev/null
+++ b/include/clang/AST/Attr.h
@@ -0,0 +1,587 @@
+//===--- Attr.h - Classes for representing expressions ----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the Attr interface and subclasses.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_ATTR_H
+#define LLVM_CLANG_AST_ATTR_H
+
+#include "llvm/Support/Casting.h"
+#include "llvm/ADT/StringRef.h"
+#include <cassert>
+#include <cstring>
+#include <algorithm>
+using llvm::dyn_cast;
+
+namespace clang {
+  class ASTContext;
+}
+
+
+// Defined in ASTContext.h
+void *operator new(size_t Bytes, clang::ASTContext &C,
+                   size_t Alignment = 16) throw ();
+
+// It is good practice to pair new/delete operators.  Also, MSVC gives many
+// warnings if a matching delete overload is not declared, even though the
+// throw() spec guarantees it will not be implicitly called.
+void operator delete(void *Ptr, clang::ASTContext &C, size_t)
+              throw ();
+
+namespace clang {
+
+/// Attr - This represents one attribute.
+class Attr {
+public:
+  enum Kind {
+    Alias,
+    Aligned,
+    AlwaysInline,
+    AnalyzerNoReturn, // Clang-specific.
+    Annotate,
+    AsmLabel, // Represent GCC asm label extension.
+    BaseCheck,
+    Blocks,
+    CDecl,
+    Cleanup,
+    Const,
+    Constructor,
+    Deprecated,
+    Destructor,
+    FastCall,
+    Final,
+    Format,
+    FormatArg,
+    GNUInline,
+    Hiding,
+    IBOutletKind, // Clang-specific. Use "Kind" suffix to not conflict w/ macro.
+    IBActionKind, // Clang-specific. Use "Kind" suffix to not conflict w/ macro.
+    Malloc,
+    NoDebug,
+    NoInline,
+    NonNull,
+    NoReturn,
+    NoThrow,
+    ObjCException,
+    ObjCNSObject,
+    Override,
+    CFReturnsRetained,      // Clang/Checker-specific.
+    CFReturnsNotRetained,   // Clang/Checker-specific.
+    NSReturnsRetained,      // Clang/Checker-specific.
+    NSReturnsNotRetained,   // Clang/Checker-specific.
+    Overloadable, // Clang-specific
+    Packed,
+    PragmaPack,
+    Pure,
+    Regparm,
+    ReqdWorkGroupSize,   // OpenCL-specific
+    Section,
+    Sentinel,
+    StdCall,
+    TransparentUnion,
+    Unavailable,
+    Unused,
+    Used,
+    Visibility,
+    WarnUnusedResult,
+    Weak,
+    WeakImport,
+    WeakRef,
+
+    FIRST_TARGET_ATTRIBUTE,
+    DLLExport,
+    DLLImport,
+    MSP430Interrupt,
+    X86ForceAlignArgPointer
+  };
+
+private:
+  Attr *Next;
+  Kind AttrKind;
+  bool Inherited : 1;
+
+protected:
+  void* operator new(size_t bytes) throw() {
+    assert(0 && "Attrs cannot be allocated with regular 'new'.");
+    return 0;
+  }
+  void operator delete(void* data) throw() {
+    assert(0 && "Attrs cannot be released with regular 'delete'.");
+  }
+
+protected:
+  Attr(Kind AK) : Next(0), AttrKind(AK), Inherited(false) {}
+  virtual ~Attr() {
+    assert(Next == 0 && "Destroy didn't work");
+  }
+public:
+  virtual void Destroy(ASTContext &C);
+
+  /// \brief Whether this attribute should be merged to new
+  /// declarations.
+  virtual bool isMerged() const { return true; }
+
+  Kind getKind() const { return AttrKind; }
+
+  Attr *getNext() { return Next; }
+  const Attr *getNext() const { return Next; }
+  void setNext(Attr *next) { Next = next; }
+
+  template<typename T> const T *getNext() const {
+    for (const Attr *attr = getNext(); attr; attr = attr->getNext())
+      if (const T *V = dyn_cast<T>(attr))
+        return V;
+    return 0;
+  }
+
+  bool isInherited() const { return Inherited; }
+  void setInherited(bool value) { Inherited = value; }
+
+  void addAttr(Attr *attr) {
+    assert((attr != 0) && "addAttr(): attr is null");
+
+    // FIXME: This doesn't preserve the order in any way.
+    attr->Next = Next;
+    Next = attr;
+  }
+
+  // Clone this attribute.
+  virtual Attr* clone(ASTContext &C) const = 0;
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Attr *) { return true; }
+};
+  
+class AttrWithString : public Attr {
+private:
+  const char *Str;
+  unsigned StrLen;
+protected:
+  AttrWithString(Attr::Kind AK, ASTContext &C, llvm::StringRef s);
+  llvm::StringRef getString() const { return llvm::StringRef(Str, StrLen); }
+  void ReplaceString(ASTContext &C, llvm::StringRef newS);
+public:
+  virtual void Destroy(ASTContext &C);
+};
+
+#define DEF_SIMPLE_ATTR(ATTR)                                           \
+class ATTR##Attr : public Attr {                                        \
+public:                                                                 \
+  ATTR##Attr() : Attr(ATTR) {}                                          \
+  virtual Attr *clone(ASTContext &C) const;                             \
+  static bool classof(const Attr *A) { return A->getKind() == ATTR; }   \
+  static bool classof(const ATTR##Attr *A) { return true; }             \
+}
+
+DEF_SIMPLE_ATTR(Packed);
+
+class PragmaPackAttr : public Attr {
+  unsigned Alignment;
+
+public:
+  PragmaPackAttr(unsigned alignment) : Attr(PragmaPack), Alignment(alignment) {}
+
+  /// getAlignment - The specified alignment in bits.
+  unsigned getAlignment() const { return Alignment; }
+
+  virtual Attr* clone(ASTContext &C) const;
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Attr *A) {
+    return A->getKind() == PragmaPack;
+  }
+  static bool classof(const PragmaPackAttr *A) { return true; }
+};
+
+class AlignedAttr : public Attr {
+  unsigned Alignment;
+public:
+  AlignedAttr(unsigned alignment)
+    : Attr(Aligned), Alignment(alignment) {}
+
+  /// getAlignment - The specified alignment in bits.
+  unsigned getAlignment() const { return Alignment; }
+  
+  /// getMaxAlignment - Get the maximum alignment of attributes on this list.
+  unsigned getMaxAlignment() const {
+    const AlignedAttr *Next = getNext<AlignedAttr>();
+    if (Next)
+      return std::max(Next->getMaxAlignment(), Alignment);
+    else
+      return Alignment;
+  }
+
+  virtual Attr* clone(ASTContext &C) const;
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Attr *A) {
+    return A->getKind() == Aligned;
+  }
+  static bool classof(const AlignedAttr *A) { return true; }
+};
+
+class AnnotateAttr : public AttrWithString {
+public:
+  AnnotateAttr(ASTContext &C, llvm::StringRef ann)
+    : AttrWithString(Annotate, C, ann) {}
+
+  llvm::StringRef getAnnotation() const { return getString(); }
+
+  virtual Attr* clone(ASTContext &C) const;
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Attr *A) {
+    return A->getKind() == Annotate;
+  }
+  static bool classof(const AnnotateAttr *A) { return true; }
+};
+
+class AsmLabelAttr : public AttrWithString {
+public:
+  AsmLabelAttr(ASTContext &C, llvm::StringRef L)
+    : AttrWithString(AsmLabel, C, L) {}
+
+  llvm::StringRef getLabel() const { return getString(); }
+
+  virtual Attr* clone(ASTContext &C) const;
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Attr *A) {
+    return A->getKind() == AsmLabel;
+  }
+  static bool classof(const AsmLabelAttr *A) { return true; }
+};
+
+DEF_SIMPLE_ATTR(AlwaysInline);
+
+class AliasAttr : public AttrWithString {
+public:
+  AliasAttr(ASTContext &C, llvm::StringRef aliasee)
+    : AttrWithString(Alias, C, aliasee) {}
+
+  llvm::StringRef getAliasee() const { return getString(); }
+
+  virtual Attr *clone(ASTContext &C) const;
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Attr *A) { return A->getKind() == Alias; }
+  static bool classof(const AliasAttr *A) { return true; }
+};
+
+class ConstructorAttr : public Attr {
+  int priority;
+public:
+  ConstructorAttr(int p) : Attr(Constructor), priority(p) {}
+
+  int getPriority() const { return priority; }
+
+  virtual Attr *clone(ASTContext &C) const;
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Attr *A) { return A->getKind() == Constructor; }
+  static bool classof(const ConstructorAttr *A) { return true; }
+};
+
+class DestructorAttr : public Attr {
+  int priority;
+public:
+  DestructorAttr(int p) : Attr(Destructor), priority(p) {}
+
+  int getPriority() const { return priority; }
+
+  virtual Attr *clone(ASTContext &C) const;
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Attr *A) { return A->getKind() == Destructor; }
+  static bool classof(const DestructorAttr *A) { return true; }
+};
+
+class IBOutletAttr : public Attr {
+public:
+  IBOutletAttr() : Attr(IBOutletKind) {}
+
+  virtual Attr *clone(ASTContext &C) const;
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Attr *A) {
+    return A->getKind() == IBOutletKind;
+  }
+  static bool classof(const IBOutletAttr *A) { return true; }
+};
+
+class IBActionAttr : public Attr {
+public:
+  IBActionAttr() : Attr(IBActionKind) {}
+
+  virtual Attr *clone(ASTContext &C) const;
+
+    // Implement isa/cast/dyncast/etc.
+  static bool classof(const Attr *A) {
+    return A->getKind() == IBActionKind;
+  }
+  static bool classof(const IBActionAttr *A) { return true; }
+};
+
+DEF_SIMPLE_ATTR(AnalyzerNoReturn);
+DEF_SIMPLE_ATTR(Deprecated);
+DEF_SIMPLE_ATTR(Final);
+DEF_SIMPLE_ATTR(GNUInline);
+DEF_SIMPLE_ATTR(Malloc);
+DEF_SIMPLE_ATTR(NoReturn);
+
+class SectionAttr : public AttrWithString {
+public:
+  SectionAttr(ASTContext &C, llvm::StringRef N)
+    : AttrWithString(Section, C, N) {}
+
+  llvm::StringRef getName() const { return getString(); }
+
+  virtual Attr *clone(ASTContext &C) const;
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Attr *A) {
+    return A->getKind() == Section;
+  }
+  static bool classof(const SectionAttr *A) { return true; }
+};
+
+DEF_SIMPLE_ATTR(Unavailable);
+DEF_SIMPLE_ATTR(Unused);
+DEF_SIMPLE_ATTR(Used);
+DEF_SIMPLE_ATTR(Weak);
+DEF_SIMPLE_ATTR(WeakImport);
+DEF_SIMPLE_ATTR(WeakRef);
+DEF_SIMPLE_ATTR(NoThrow);
+DEF_SIMPLE_ATTR(Const);
+DEF_SIMPLE_ATTR(Pure);
+
+class NonNullAttr : public Attr {
+  unsigned* ArgNums;
+  unsigned Size;
+public:
+  NonNullAttr(ASTContext &C, unsigned* arg_nums = 0, unsigned size = 0);
+
+  virtual void Destroy(ASTContext &C);
+
+  typedef const unsigned *iterator;
+  iterator begin() const { return ArgNums; }
+  iterator end() const { return ArgNums + Size; }
+  unsigned size() const { return Size; }
+
+  bool isNonNull(unsigned arg) const {
+    return ArgNums ? std::binary_search(ArgNums, ArgNums+Size, arg) : true;
+  }
+
+  virtual Attr *clone(ASTContext &C) const;
+
+  static bool classof(const Attr *A) { return A->getKind() == NonNull; }
+  static bool classof(const NonNullAttr *A) { return true; }
+};
+
+class FormatAttr : public AttrWithString {
+  int formatIdx, firstArg;
+public:
+  FormatAttr(ASTContext &C, llvm::StringRef type, int idx, int first)
+    : AttrWithString(Format, C, type), formatIdx(idx), firstArg(first) {}
+
+  llvm::StringRef getType() const { return getString(); }
+  void setType(ASTContext &C, llvm::StringRef type);
+  int getFormatIdx() const { return formatIdx; }
+  int getFirstArg() const { return firstArg; }
+
+  virtual Attr *clone(ASTContext &C) const;
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Attr *A) { return A->getKind() == Format; }
+  static bool classof(const FormatAttr *A) { return true; }
+};
+
+class FormatArgAttr : public Attr {
+  int formatIdx;
+public:
+  FormatArgAttr(int idx) : Attr(FormatArg), formatIdx(idx) {}
+  int getFormatIdx() const { return formatIdx; }
+
+  virtual Attr *clone(ASTContext &C) const;
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Attr *A) { return A->getKind() == FormatArg; }
+  static bool classof(const FormatArgAttr *A) { return true; }
+};
+
+class SentinelAttr : public Attr {
+  int sentinel, NullPos;
+public:
+  SentinelAttr(int sentinel_val, int nullPos) : Attr(Sentinel),
+               sentinel(sentinel_val), NullPos(nullPos) {}
+  int getSentinel() const { return sentinel; }
+  int getNullPos() const { return NullPos; }
+
+  virtual Attr *clone(ASTContext &C) const;
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Attr *A) { return A->getKind() == Sentinel; }
+  static bool classof(const SentinelAttr *A) { return true; }
+};
+
+class VisibilityAttr : public Attr {
+public:
+  /// @brief An enumeration for the kinds of visibility of symbols.
+  enum VisibilityTypes {
+    DefaultVisibility = 0,
+    HiddenVisibility,
+    ProtectedVisibility
+  };
+private:
+  VisibilityTypes VisibilityType;
+public:
+  VisibilityAttr(VisibilityTypes v) : Attr(Visibility),
+                 VisibilityType(v) {}
+
+  VisibilityTypes getVisibility() const { return VisibilityType; }
+
+  virtual Attr *clone(ASTContext &C) const;
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Attr *A) { return A->getKind() == Visibility; }
+  static bool classof(const VisibilityAttr *A) { return true; }
+};
+
+DEF_SIMPLE_ATTR(FastCall);
+DEF_SIMPLE_ATTR(StdCall);
+DEF_SIMPLE_ATTR(CDecl);
+DEF_SIMPLE_ATTR(TransparentUnion);
+DEF_SIMPLE_ATTR(ObjCNSObject);
+DEF_SIMPLE_ATTR(ObjCException);
+
+class OverloadableAttr : public Attr {
+public:
+  OverloadableAttr() : Attr(Overloadable) { }
+
+  virtual bool isMerged() const { return false; }
+
+  virtual Attr *clone(ASTContext &C) const;
+
+  static bool classof(const Attr *A) { return A->getKind() == Overloadable; }
+  static bool classof(const OverloadableAttr *) { return true; }
+};
+
+class BlocksAttr : public Attr {
+public:
+  enum BlocksAttrTypes {
+    ByRef = 0
+  };
+private:
+  BlocksAttrTypes BlocksAttrType;
+public:
+  BlocksAttr(BlocksAttrTypes t) : Attr(Blocks), BlocksAttrType(t) {}
+
+  BlocksAttrTypes getType() const { return BlocksAttrType; }
+
+  virtual Attr *clone(ASTContext &C) const;
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Attr *A) { return A->getKind() == Blocks; }
+  static bool classof(const BlocksAttr *A) { return true; }
+};
+
+class FunctionDecl;
+
+class CleanupAttr : public Attr {
+  FunctionDecl *FD;
+
+public:
+  CleanupAttr(FunctionDecl *fd) : Attr(Cleanup), FD(fd) {}
+
+  const FunctionDecl *getFunctionDecl() const { return FD; }
+
+  virtual Attr *clone(ASTContext &C) const;
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Attr *A) { return A->getKind() == Cleanup; }
+  static bool classof(const CleanupAttr *A) { return true; }
+};
+
+DEF_SIMPLE_ATTR(NoDebug);
+DEF_SIMPLE_ATTR(WarnUnusedResult);
+DEF_SIMPLE_ATTR(NoInline);
+
+class RegparmAttr : public Attr {
+  unsigned NumParams;
+
+public:
+  RegparmAttr(unsigned np) : Attr(Regparm), NumParams(np) {}
+
+  unsigned getNumParams() const { return NumParams; }
+
+  virtual Attr *clone(ASTContext &C) const;
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Attr *A) { return A->getKind() == Regparm; }
+  static bool classof(const RegparmAttr *A) { return true; }
+};
+
+class ReqdWorkGroupSizeAttr : public Attr {
+  unsigned X, Y, Z;
+public:
+  ReqdWorkGroupSizeAttr(unsigned X, unsigned Y, unsigned Z)
+  : Attr(ReqdWorkGroupSize), X(X), Y(Y), Z(Z) {}
+
+  unsigned getXDim() const { return X; }
+  unsigned getYDim() const { return Y; }
+  unsigned getZDim() const { return Z; }
+
+  virtual Attr *clone(ASTContext &C) const;
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Attr *A) {
+    return A->getKind() == ReqdWorkGroupSize;
+  }
+  static bool classof(const ReqdWorkGroupSizeAttr *A) { return true; }
+};
+
+// Checker-specific attributes.
+DEF_SIMPLE_ATTR(CFReturnsNotRetained);
+DEF_SIMPLE_ATTR(CFReturnsRetained);
+DEF_SIMPLE_ATTR(NSReturnsNotRetained);
+DEF_SIMPLE_ATTR(NSReturnsRetained);
+
+// C++0x member checking attributes.
+DEF_SIMPLE_ATTR(BaseCheck);
+DEF_SIMPLE_ATTR(Hiding);
+DEF_SIMPLE_ATTR(Override);
+
+// Target-specific attributes
+DEF_SIMPLE_ATTR(DLLImport);
+DEF_SIMPLE_ATTR(DLLExport);
+
+class MSP430InterruptAttr : public Attr {
+  unsigned Number;
+
+public:
+  MSP430InterruptAttr(unsigned n) : Attr(MSP430Interrupt), Number(n) {}
+
+  unsigned getNumber() const { return Number; }
+
+  virtual Attr *clone(ASTContext &C) const;
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Attr *A) { return A->getKind() == MSP430Interrupt; }
+  static bool classof(const MSP430InterruptAttr *A) { return true; }
+};
+
+DEF_SIMPLE_ATTR(X86ForceAlignArgPointer);
+
+#undef DEF_SIMPLE_ATTR
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/AST/CXXInheritance.h b/include/clang/AST/CXXInheritance.h
new file mode 100644
index 0000000..edd633e
--- /dev/null
+++ b/include/clang/AST/CXXInheritance.h
@@ -0,0 +1,365 @@
+//===------ CXXInheritance.h - C++ Inheritance ------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides routines that help analyzing C++ inheritance hierarchies.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_CXXINHERITANCE_H
+#define LLVM_CLANG_AST_CXXINHERITANCE_H
+
+#include "clang/AST/DeclarationName.h"
+#include "clang/AST/DeclBase.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/TypeOrdering.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVector.h"
+#include <list>
+#include <map>
+#include <cassert>
+
+namespace clang {
+  
+class CXXBaseSpecifier;
+class CXXMethodDecl;
+class CXXRecordDecl;
+class NamedDecl;
+  
+/// \brief Represents an element in a path from a derived class to a
+/// base class. 
+/// 
+/// Each step in the path references the link from a
+/// derived class to one of its direct base classes, along with a
+/// base "number" that identifies which base subobject of the
+/// original derived class we are referencing.
+struct CXXBasePathElement {
+  /// \brief The base specifier that states the link from a derived
+  /// class to a base class, which will be followed by this base
+  /// path element.
+  const CXXBaseSpecifier *Base;
+  
+  /// \brief The record decl of the class that the base is a base of.
+  const CXXRecordDecl *Class;
+  
+  /// \brief Identifies which base class subobject (of type
+  /// \c Base->getType()) this base path element refers to. 
+  ///
+  /// This value is only valid if \c !Base->isVirtual(), because there
+  /// is no base numbering for the zero or one virtual bases of a
+  /// given type.
+  int SubobjectNumber;
+};
+
+/// \brief Represents a path from a specific derived class
+/// (which is not represented as part of the path) to a particular
+/// (direct or indirect) base class subobject.
+///
+/// Individual elements in the path are described by the \c CXXBasePathElement 
+/// structure, which captures both the link from a derived class to one of its
+/// direct bases and identification describing which base class
+/// subobject is being used.
+class CXXBasePath : public llvm::SmallVector<CXXBasePathElement, 4> {
+public:
+  CXXBasePath() : Access(AS_public) {}
+
+  /// \brief The access along this inheritance path.  This is only
+  /// calculated when recording paths.  AS_none is a special value
+  /// used to indicate a path which permits no legal access.
+  AccessSpecifier Access;
+
+  /// \brief The set of declarations found inside this base class
+  /// subobject.
+  DeclContext::lookup_result Decls;
+
+  void clear() {
+    llvm::SmallVectorImpl<CXXBasePathElement>::clear();
+    Access = AS_public;
+  }
+};
+
+/// BasePaths - Represents the set of paths from a derived class to
+/// one of its (direct or indirect) bases. For example, given the
+/// following class hierachy:
+///
+/// @code
+/// class A { };
+/// class B : public A { };
+/// class C : public A { };
+/// class D : public B, public C{ };
+/// @endcode
+///
+/// There are two potential BasePaths to represent paths from D to a
+/// base subobject of type A. One path is (D,0) -> (B,0) -> (A,0)
+/// and another is (D,0)->(C,0)->(A,1). These two paths actually
+/// refer to two different base class subobjects of the same type,
+/// so the BasePaths object refers to an ambiguous path. On the
+/// other hand, consider the following class hierarchy:
+///
+/// @code
+/// class A { };
+/// class B : public virtual A { };
+/// class C : public virtual A { };
+/// class D : public B, public C{ };
+/// @endcode
+///
+/// Here, there are two potential BasePaths again, (D, 0) -> (B, 0)
+/// -> (A,v) and (D, 0) -> (C, 0) -> (A, v), but since both of them
+/// refer to the same base class subobject of type A (the virtual
+/// one), there is no ambiguity.
+class CXXBasePaths {
+  /// \brief The type from which this search originated.
+  CXXRecordDecl *Origin;
+  
+  /// Paths - The actual set of paths that can be taken from the
+  /// derived class to the same base class.
+  std::list<CXXBasePath> Paths;
+  
+  /// ClassSubobjects - Records the class subobjects for each class
+  /// type that we've seen. The first element in the pair says
+  /// whether we found a path to a virtual base for that class type,
+  /// while the element contains the number of non-virtual base
+  /// class subobjects for that class type. The key of the map is
+  /// the cv-unqualified canonical type of the base class subobject.
+  std::map<QualType, std::pair<bool, unsigned>, QualTypeOrdering>
+    ClassSubobjects;
+  
+  /// FindAmbiguities - Whether Sema::IsDerivedFrom should try find
+  /// ambiguous paths while it is looking for a path from a derived
+  /// type to a base type.
+  bool FindAmbiguities;
+  
+  /// RecordPaths - Whether Sema::IsDerivedFrom should record paths
+  /// while it is determining whether there are paths from a derived
+  /// type to a base type.
+  bool RecordPaths;
+  
+  /// DetectVirtual - Whether Sema::IsDerivedFrom should abort the search
+  /// if it finds a path that goes across a virtual base. The virtual class
+  /// is also recorded.
+  bool DetectVirtual;
+  
+  /// ScratchPath - A BasePath that is used by Sema::lookupInBases
+  /// to help build the set of paths.
+  CXXBasePath ScratchPath;
+
+  /// DetectedVirtual - The base class that is virtual.
+  const RecordType *DetectedVirtual;
+  
+  /// \brief Array of the declarations that have been found. This
+  /// array is constructed only if needed, e.g., to iterate over the
+  /// results within LookupResult.
+  NamedDecl **DeclsFound;
+  unsigned NumDeclsFound;
+  
+  friend class CXXRecordDecl;
+  
+  void ComputeDeclsFound();
+
+  bool lookupInBases(ASTContext &Context, 
+                     const CXXRecordDecl *Record,
+                     CXXRecordDecl::BaseMatchesCallback *BaseMatches, 
+                     void *UserData);
+public:
+  typedef std::list<CXXBasePath>::iterator paths_iterator;
+  typedef std::list<CXXBasePath>::const_iterator const_paths_iterator;
+  typedef NamedDecl **decl_iterator;
+  
+  /// BasePaths - Construct a new BasePaths structure to record the
+  /// paths for a derived-to-base search.
+  explicit CXXBasePaths(bool FindAmbiguities = true,
+                        bool RecordPaths = true,
+                        bool DetectVirtual = true)
+    : FindAmbiguities(FindAmbiguities), RecordPaths(RecordPaths),
+      DetectVirtual(DetectVirtual), DetectedVirtual(0), DeclsFound(0),
+      NumDeclsFound(0) { }
+  
+  ~CXXBasePaths() { delete [] DeclsFound; }
+  
+  paths_iterator begin() { return Paths.begin(); }
+  paths_iterator end()   { return Paths.end(); }
+  const_paths_iterator begin() const { return Paths.begin(); }
+  const_paths_iterator end()   const { return Paths.end(); }
+  
+  CXXBasePath&       front()       { return Paths.front(); }
+  const CXXBasePath& front() const { return Paths.front(); }
+  
+  decl_iterator found_decls_begin();
+  decl_iterator found_decls_end();
+  
+  /// \brief Determine whether the path from the most-derived type to the
+  /// given base type is ambiguous (i.e., it refers to multiple subobjects of
+  /// the same base type).
+  bool isAmbiguous(QualType BaseType);
+  
+  /// \brief Whether we are finding multiple paths to detect ambiguities.
+  bool isFindingAmbiguities() const { return FindAmbiguities; }
+  
+  /// \brief Whether we are recording paths.
+  bool isRecordingPaths() const { return RecordPaths; }
+  
+  /// \brief Specify whether we should be recording paths or not.
+  void setRecordingPaths(bool RP) { RecordPaths = RP; }
+  
+  /// \brief Whether we are detecting virtual bases.
+  bool isDetectingVirtual() const { return DetectVirtual; }
+  
+  /// \brief The virtual base discovered on the path (if we are merely
+  /// detecting virtuals).
+  const RecordType* getDetectedVirtual() const {
+    return DetectedVirtual;
+  }
+
+  /// \brief Retrieve the type from which this base-paths search
+  /// began
+  CXXRecordDecl *getOrigin() const { return Origin; }
+  void setOrigin(CXXRecordDecl *Rec) { Origin = Rec; }
+  
+  /// \brief Clear the base-paths results.
+  void clear();
+  
+  /// \brief Swap this data structure's contents with another CXXBasePaths 
+  /// object.
+  void swap(CXXBasePaths &Other);
+};
+
+/// \brief Uniquely identifies a virtual method within a class
+/// hierarchy by the method itself and a class subobject number.
+struct UniqueVirtualMethod {
+  UniqueVirtualMethod() : Method(0), Subobject(0), InVirtualSubobject(0) { }
+
+  UniqueVirtualMethod(CXXMethodDecl *Method, unsigned Subobject,
+                      const CXXRecordDecl *InVirtualSubobject)
+    : Method(Method), Subobject(Subobject), 
+      InVirtualSubobject(InVirtualSubobject) { }
+
+  /// \brief The overriding virtual method.
+  CXXMethodDecl *Method;
+
+  /// \brief The subobject in which the overriding virtual method
+  /// resides.
+  unsigned Subobject;
+
+  /// \brief The virtual base class subobject of which this overridden
+  /// virtual method is a part. Note that this records the closest
+  /// derived virtual base class subobject.
+  const CXXRecordDecl *InVirtualSubobject;
+
+  friend bool operator==(const UniqueVirtualMethod &X,
+                         const UniqueVirtualMethod &Y) {
+    return X.Method == Y.Method && X.Subobject == Y.Subobject &&
+      X.InVirtualSubobject == Y.InVirtualSubobject;
+  }
+
+  friend bool operator!=(const UniqueVirtualMethod &X,
+                         const UniqueVirtualMethod &Y) {
+    return !(X == Y);
+  }
+};
+
+/// \brief The set of methods that override a given virtual method in
+/// each subobject where it occurs.
+///
+/// The first part of the pair is the subobject in which the
+/// overridden virtual function occurs, while the second part of the
+/// pair is the virtual method that overrides it (including the
+/// subobject in which that virtual function occurs).
+class OverridingMethods {
+  llvm::DenseMap<unsigned, llvm::SmallVector<UniqueVirtualMethod, 4> > 
+    Overrides;
+
+public:
+  // Iterate over the set of subobjects that have overriding methods.
+  typedef llvm::DenseMap<unsigned, llvm::SmallVector<UniqueVirtualMethod, 4> >
+            ::iterator iterator;
+  typedef llvm::DenseMap<unsigned, llvm::SmallVector<UniqueVirtualMethod, 4> >
+            ::const_iterator const_iterator;
+  iterator begin() { return Overrides.begin(); }
+  const_iterator begin() const { return Overrides.begin(); }
+  iterator end() { return Overrides.end(); }
+  const_iterator end() const { return Overrides.end(); }
+  unsigned size() const { return Overrides.size(); }
+
+  // Iterate over the set of overriding virtual methods in a given
+  // subobject.
+  typedef llvm::SmallVector<UniqueVirtualMethod, 4>::iterator 
+    overriding_iterator;
+  typedef llvm::SmallVector<UniqueVirtualMethod, 4>::const_iterator
+    overriding_const_iterator;
+
+  // Add a new overriding method for a particular subobject.
+  void add(unsigned OverriddenSubobject, UniqueVirtualMethod Overriding);
+
+  // Add all of the overriding methods from "other" into overrides for
+  // this method. Used when merging the overrides from multiple base
+  // class subobjects.
+  void add(const OverridingMethods &Other);
+
+  // Replace all overriding virtual methods in all subobjects with the
+  // given virtual method.
+  void replaceAll(UniqueVirtualMethod Overriding);
+};
+
+/// \brief A mapping from each virtual member function to its set of
+/// final overriders.
+///
+/// Within a class hierarchy for a given derived class, each virtual
+/// member function in that hierarchy has one or more "final
+/// overriders" (C++ [class.virtual]p2). A final overrider for a
+/// virtual function "f" is the virtual function that will actually be
+/// invoked when dispatching a call to "f" through the
+/// vtable. Well-formed classes have a single final overrider for each
+/// virtual function; in abstract classes, the final overrider for at
+/// least one virtual function is a pure virtual function. Due to
+/// multiple, virtual inheritance, it is possible for a class to have
+/// more than one final overrider. Athough this is an error (per C++
+/// [class.virtual]p2), it is not considered an error here: the final
+/// overrider map can represent multiple final overriders for a
+/// method, and it is up to the client to determine whether they are
+/// problem. For example, the following class \c D has two final
+/// overriders for the virtual function \c A::f(), one in \c C and one
+/// in \c D:
+///
+/// \code
+///   struct A { virtual void f(); };
+///   struct B : virtual A { virtual void f(); };
+///   struct C : virtual A { virtual void f(); };
+///   struct D : B, C { };
+/// \endcode
+///
+/// This data structure contaings a mapping from every virtual
+/// function *that does not override an existing virtual function* and
+/// in every subobject where that virtual function occurs to the set
+/// of virtual functions that override it. Thus, the same virtual
+/// function \c A::f can actually occur in multiple subobjects of type
+/// \c A due to multiple inheritance, and may be overriden by
+/// different virtual functions in each, as in the following example:
+///
+/// \code
+///   struct A { virtual void f(); };
+///   struct B : A { virtual void f(); };
+///   struct C : A { virtual void f(); };
+///   struct D : B, C { };
+/// \endcode
+///
+/// Unlike in the previous example, where the virtual functions \c
+/// B::f and \c C::f both overrode \c A::f in the same subobject of
+/// type \c A, in this example the two virtual functions both override
+/// \c A::f but in *different* subobjects of type A. This is
+/// represented by numbering the subobjects in which the overridden
+/// and the overriding virtual member functions are located. Subobject
+/// 0 represents the virtua base class subobject of that type, while
+/// subobject numbers greater than 0 refer to non-virtual base class
+/// subobjects of that type.
+class CXXFinalOverriderMap 
+  : public llvm::DenseMap<const CXXMethodDecl *, OverridingMethods> { };
+  
+} // end namespace clang
+
+#endif
diff --git a/include/clang/AST/CanonicalType.h b/include/clang/AST/CanonicalType.h
new file mode 100644
index 0000000..93dcad7
--- /dev/null
+++ b/include/clang/AST/CanonicalType.h
@@ -0,0 +1,724 @@
+//===-- CanonicalType.h - C Language Family Type Representation -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the CanQual class template, which provides access to
+//  canonical types.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_CANONICAL_TYPE_H
+#define LLVM_CLANG_AST_CANONICAL_TYPE_H
+
+#include "clang/AST/Type.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/type_traits.h"
+#include <iterator>
+
+namespace clang {
+
+template<typename T> class CanProxy;
+template<typename T> struct CanProxyAdaptor;
+
+//----------------------------------------------------------------------------//
+// Canonical, qualified type template
+//----------------------------------------------------------------------------//
+
+/// \brief Represents a canonical, potentially-qualified type.
+///
+/// The CanQual template is a lightweight smart pointer that provides access
+/// to the canonical representation of a type, where all typedefs and other
+/// syntactic sugar has been eliminated. A CanQualType may also have various
+/// qualifiers (const, volatile, restrict) attached to it.
+///
+/// The template type parameter @p T is one of the Type classes (PointerType,
+/// BuiltinType, etc.). The type stored within @c CanQual<T> will be of that
+/// type (or some subclass of that type). The typedef @c CanQualType is just
+/// a shorthand for @c CanQual<Type>.
+///
+/// An instance of @c CanQual<T> can be implicitly converted to a
+/// @c CanQual<U> when T is derived from U, which essentially provides an
+/// implicit upcast. For example, @c CanQual<LValueReferenceType> can be
+/// converted to @c CanQual<ReferenceType>. Note that any @c CanQual type can
+/// be implicitly converted to a QualType, but the reverse operation requires
+/// a call to ASTContext::getCanonicalType().
+///
+///
+template<typename T = Type>
+class CanQual {
+  /// \brief The actual, canonical type.
+  QualType Stored;
+
+public:
+  /// \brief Constructs a NULL canonical type.
+  CanQual() : Stored() { }
+
+  /// \brief Converting constructor that permits implicit upcasting of
+  /// canonical type pointers.
+  template<typename U>
+  CanQual(const CanQual<U>& Other,
+          typename llvm::enable_if<llvm::is_base_of<T, U>, int>::type = 0);
+
+  /// \brief Retrieve the underlying type pointer, which refers to a
+  /// canonical type.
+  T *getTypePtr() const { return cast_or_null<T>(Stored.getTypePtr()); }
+
+  /// \brief Implicit conversion to a qualified type.
+  operator QualType() const { return Stored; }
+
+  /// \brief Implicit conversion to bool.
+  operator bool() const { return !isNull(); }
+  
+  bool isNull() const {
+    return Stored.isNull();
+  }
+
+  /// \brief Retrieve a canonical type pointer with a different static type,
+  /// upcasting or downcasting as needed.
+  ///
+  /// The getAs() function is typically used to try to downcast to a
+  /// more specific (canonical) type in the type system. For example:
+  ///
+  /// @code
+  /// void f(CanQual<Type> T) {
+  ///   if (CanQual<PointerType> Ptr = T->getAs<PointerType>()) {
+  ///     // look at Ptr's pointee type
+  ///   }
+  /// }
+  /// @endcode
+  ///
+  /// \returns A proxy pointer to the same type, but with the specified
+  /// static type (@p U). If the dynamic type is not the specified static type
+  /// or a derived class thereof, a NULL canonical type.
+  template<typename U> CanProxy<U> getAs() const;
+
+  /// \brief Overloaded arrow operator that produces a canonical type
+  /// proxy.
+  CanProxy<T> operator->() const;
+
+  /// \brief Retrieve all qualifiers.
+  Qualifiers getQualifiers() const { return Stored.getLocalQualifiers(); }
+
+  /// \brief Retrieve the const/volatile/restrict qualifiers.
+  unsigned getCVRQualifiers() const { return Stored.getLocalCVRQualifiers(); }
+
+  /// \brief Determines whether this type has any qualifiers
+  bool hasQualifiers() const { return Stored.hasLocalQualifiers(); }
+
+  bool isConstQualified() const {
+    return Stored.isLocalConstQualified();
+  }
+  bool isVolatileQualified() const {
+    return Stored.isLocalVolatileQualified();
+  }
+  bool isRestrictQualified() const {
+    return Stored.isLocalRestrictQualified();
+  }
+
+  /// \brief Determines if this canonical type is furthermore
+  /// canonical as a parameter.  The parameter-canonicalization
+  /// process decays arrays to pointers and drops top-level qualifiers.
+  bool isCanonicalAsParam() const {
+    return Stored.isCanonicalAsParam();
+  }
+
+  /// \brief Retrieve the unqualified form of this type.
+  CanQual<T> getUnqualifiedType() const;
+
+  /// \brief Retrieves a version of this type with const applied.
+  /// Note that this does not always yield a canonical type.
+  QualType withConst() const {
+    return Stored.withConst();
+  }
+
+  /// \brief Determines whether this canonical type is more qualified than
+  /// the @p Other canonical type.
+  bool isMoreQualifiedThan(CanQual<T> Other) const {
+    return Stored.isMoreQualifiedThan(Other.Stored);
+  }
+
+  /// \brief Determines whether this canonical type is at least as qualified as
+  /// the @p Other canonical type.
+  bool isAtLeastAsQualifiedAs(CanQual<T> Other) const {
+    return Stored.isAtLeastAsQualifiedAs(Other.Stored);
+  }
+
+  /// \brief If the canonical type is a reference type, returns the type that
+  /// it refers to; otherwise, returns the type itself.
+  CanQual<Type> getNonReferenceType() const;
+
+  /// \brief Retrieve the internal representation of this canonical type.
+  void *getAsOpaquePtr() const { return Stored.getAsOpaquePtr(); }
+
+  /// \brief Construct a canonical type from its internal representation.
+  static CanQual<T> getFromOpaquePtr(void *Ptr);
+
+  /// \brief Builds a canonical type from a QualType.
+  ///
+  /// This routine is inherently unsafe, because it requires the user to
+  /// ensure that the given type is a canonical type with the correct
+  // (dynamic) type.
+  static CanQual<T> CreateUnsafe(QualType Other);
+
+  void dump() const { Stored.dump(); }
+
+  void Profile(llvm::FoldingSetNodeID &ID) const {
+    ID.AddPointer(getAsOpaquePtr());
+  }
+};
+
+template<typename T, typename U>
+inline bool operator==(CanQual<T> x, CanQual<U> y) {
+  return x.getAsOpaquePtr() == y.getAsOpaquePtr();
+}
+
+template<typename T, typename U>
+inline bool operator!=(CanQual<T> x, CanQual<U> y) {
+  return x.getAsOpaquePtr() != y.getAsOpaquePtr();
+}
+
+/// \brief Represents a canonical, potentially-qualified type.
+typedef CanQual<Type> CanQualType;
+
+inline CanQualType Type::getCanonicalTypeUnqualified() const {
+  return CanQualType::CreateUnsafe(getCanonicalTypeInternal());
+}
+
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+                                           CanQualType T) {
+  DB << static_cast<QualType>(T);
+  return DB;
+}
+
+//----------------------------------------------------------------------------//
+// Internal proxy classes used by canonical types
+//----------------------------------------------------------------------------//
+
+#define LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(Accessor)                    \
+CanQualType Accessor() const {                                           \
+return CanQualType::CreateUnsafe(this->getTypePtr()->Accessor());      \
+}
+
+#define LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Type, Accessor)             \
+Type Accessor() const { return this->getTypePtr()->Accessor(); }
+
+/// \brief Base class of all canonical proxy types, which is responsible for
+/// storing the underlying canonical type and providing basic conversions.
+template<typename T>
+class CanProxyBase {
+protected:
+  CanQual<T> Stored;
+
+public:
+  /// \brief Retrieve the pointer to the underlying Type
+  T* getTypePtr() const { return Stored.getTypePtr(); }
+
+  /// \brief Implicit conversion to the underlying pointer.
+  ///
+  /// Also provides the ability to use canonical type proxies in a Boolean
+  // context,e.g.,
+  /// @code
+  ///   if (CanQual<PointerType> Ptr = T->getAs<PointerType>()) { ... }
+  /// @endcode
+  operator const T*() const { return this->Stored.getTypePtr(); }
+
+  /// \brief Try to convert the given canonical type to a specific structural
+  /// type.
+  template<typename U> CanProxy<U> getAs() const {
+    return this->Stored.template getAs<U>();
+  }
+
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Type::TypeClass, getTypeClass)
+
+  // Type predicates
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjectType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIncompleteType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIncompleteOrObjectType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isPODType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariablyModifiedType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegerType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isEnumeralType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBooleanType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isCharType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isWideCharType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegralType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isRealFloatingType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isComplexType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAnyComplexType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isFloatingType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isRealType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isArithmeticType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVoidType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isDerivedType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isScalarType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAggregateType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAnyPointerType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVoidPointerType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isFunctionPointerType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isMemberFunctionPointerType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isClassType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isStructureType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isStructureOrClassType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnionType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isComplexIntegerType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isNullPtrType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isDependentType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isOverloadableType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasPointerRepresentation)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasObjCPointerRepresentation)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isPromotableIntegerType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSignedIntegerType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnsignedIntegerType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isConstantSizeType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSpecifierType)
+
+  /// \brief Retrieve the proxy-adaptor type.
+  ///
+  /// This arrow operator is used when CanProxyAdaptor has been specialized
+  /// for the given type T. In that case, we reference members of the
+  /// CanProxyAdaptor specialization. Otherwise, this operator will be hidden
+  /// by the arrow operator in the primary CanProxyAdaptor template.
+  const CanProxyAdaptor<T> *operator->() const {
+    return static_cast<const CanProxyAdaptor<T> *>(this);
+  }
+};
+
+/// \brief Replacable canonical proxy adaptor class that provides the link
+/// between a canonical type and the accessors of the type.
+///
+/// The CanProxyAdaptor is a replaceable class template that is instantiated
+/// as part of each canonical proxy type. The primary template merely provides
+/// redirection to the underlying type (T), e.g., @c PointerType. One can
+/// provide specializations of this class template for each underlying type
+/// that provide accessors returning canonical types (@c CanQualType) rather
+/// than the more typical @c QualType, to propagate the notion of "canonical"
+/// through the system.
+template<typename T>
+struct CanProxyAdaptor : CanProxyBase<T> { };
+
+/// \brief Canonical proxy type returned when retrieving the members of a
+/// canonical type or as the result of the @c CanQual<T>::getAs member
+/// function.
+///
+/// The CanProxy type mainly exists as a proxy through which operator-> will
+/// look to either map down to a raw T* (e.g., PointerType*) or to a proxy
+/// type that provides canonical-type access to the fields of the type.
+template<typename T>
+class CanProxy : public CanProxyAdaptor<T> {
+public:
+  /// \brief Build a NULL proxy.
+  CanProxy() { }
+
+  /// \brief Build a proxy to the given canonical type.
+  CanProxy(CanQual<T> Stored) { this->Stored = Stored; }
+
+  /// \brief Implicit conversion to the stored canonical type.
+  operator CanQual<T>() const { return this->Stored; }
+};
+
+} // end namespace clang
+
+namespace llvm {
+
+/// Implement simplify_type for CanQual<T>, so that we can dyn_cast from
+/// CanQual<T> to a specific Type class. We're prefer isa/dyn_cast/cast/etc.
+/// to return smart pointer (proxies?).
+template<typename T>
+struct simplify_type<const ::clang::CanQual<T> > {
+  typedef T* SimpleType;
+  static SimpleType getSimplifiedValue(const ::clang::CanQual<T> &Val) {
+    return Val.getTypePtr();
+  }
+};
+template<typename T>
+struct simplify_type< ::clang::CanQual<T> >
+: public simplify_type<const ::clang::CanQual<T> > {};
+
+// Teach SmallPtrSet that CanQual<T> is "basically a pointer".
+template<typename T>
+class PointerLikeTypeTraits<clang::CanQual<T> > {
+public:
+  static inline void *getAsVoidPointer(clang::CanQual<T> P) {
+    return P.getAsOpaquePtr();
+  }
+  static inline clang::CanQual<T> getFromVoidPointer(void *P) {
+    return clang::CanQual<T>::getFromOpaquePtr(P);
+  }
+  // qualifier information is encoded in the low bits.
+  enum { NumLowBitsAvailable = 0 };
+};
+
+} // end namespace llvm
+
+namespace clang {
+
+//----------------------------------------------------------------------------//
+// Canonical proxy adaptors for canonical type nodes.
+//----------------------------------------------------------------------------//
+
+/// \brief Iterator adaptor that turns an iterator over canonical QualTypes
+/// into an iterator over CanQualTypes.
+template<typename InputIterator>
+class CanTypeIterator {
+  InputIterator Iter;
+
+public:
+  typedef CanQualType    value_type;
+  typedef value_type     reference;
+  typedef CanProxy<Type> pointer;
+  typedef typename std::iterator_traits<InputIterator>::difference_type
+    difference_type;
+  typedef typename std::iterator_traits<InputIterator>::iterator_category
+    iterator_category;
+
+  CanTypeIterator() : Iter() { }
+  explicit CanTypeIterator(InputIterator Iter) : Iter(Iter) { }
+
+  // Input iterator
+  reference operator*() const {
+    return CanQualType::CreateUnsafe(*Iter);
+  }
+
+  pointer operator->() const;
+
+  CanTypeIterator &operator++() {
+    ++Iter;
+    return *this;
+  }
+
+  CanTypeIterator operator++(int) {
+    CanTypeIterator Tmp(*this);
+    ++Iter;
+    return Tmp;
+  }
+
+  friend bool operator==(const CanTypeIterator& X, const CanTypeIterator &Y) {
+    return X.Iter == Y.Iter;
+  }
+  friend bool operator!=(const CanTypeIterator& X, const CanTypeIterator &Y) {
+    return X.Iter != Y.Iter;
+  }
+
+  // Bidirectional iterator
+  CanTypeIterator &operator--() {
+    --Iter;
+    return *this;
+  }
+
+  CanTypeIterator operator--(int) {
+    CanTypeIterator Tmp(*this);
+    --Iter;
+    return Tmp;
+  }
+
+  // Random access iterator
+  reference operator[](difference_type n) const {
+    return CanQualType::CreateUnsafe(Iter[n]);
+  }
+
+  CanTypeIterator &operator+=(difference_type n) {
+    Iter += n;
+    return *this;
+  }
+
+  CanTypeIterator &operator-=(difference_type n) {
+    Iter -= n;
+    return *this;
+  }
+
+  friend CanTypeIterator operator+(CanTypeIterator X, difference_type n) {
+    X += n;
+    return X;
+  }
+
+  friend CanTypeIterator operator+(difference_type n, CanTypeIterator X) {
+    X += n;
+    return X;
+  }
+
+  friend CanTypeIterator operator-(CanTypeIterator X, difference_type n) {
+    X -= n;
+    return X;
+  }
+
+  friend difference_type operator-(const CanTypeIterator &X,
+                                   const CanTypeIterator &Y) {
+    return X - Y;
+  }
+};
+
+template<>
+struct CanProxyAdaptor<ComplexType> : public CanProxyBase<ComplexType> {
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
+};
+
+template<>
+struct CanProxyAdaptor<PointerType> : public CanProxyBase<PointerType> {
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
+};
+
+template<>
+struct CanProxyAdaptor<BlockPointerType>
+  : public CanProxyBase<BlockPointerType> {
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
+};
+
+template<>
+struct CanProxyAdaptor<ReferenceType> : public CanProxyBase<ReferenceType> {
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
+};
+
+template<>
+struct CanProxyAdaptor<LValueReferenceType>
+  : public CanProxyBase<LValueReferenceType> {
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
+};
+
+template<>
+struct CanProxyAdaptor<RValueReferenceType>
+  : public CanProxyBase<RValueReferenceType> {
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
+};
+
+template<>
+struct CanProxyAdaptor<MemberPointerType>
+  : public CanProxyBase<MemberPointerType> {
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const Type *, getClass)
+};
+
+template<>
+struct CanProxyAdaptor<ArrayType> : public CanProxyBase<ArrayType> {
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier,
+                                      getSizeModifier)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getIndexTypeQualifiers)
+};
+
+template<>
+struct CanProxyAdaptor<ConstantArrayType>
+  : public CanProxyBase<ConstantArrayType> {
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier,
+                                      getSizeModifier)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getIndexTypeQualifiers)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const llvm::APInt &, getSize)
+};
+
+template<>
+struct CanProxyAdaptor<IncompleteArrayType>
+  : public CanProxyBase<IncompleteArrayType> {
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier,
+                                      getSizeModifier)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getIndexTypeQualifiers)
+};
+
+template<>
+struct CanProxyAdaptor<VariableArrayType>
+  : public CanProxyBase<VariableArrayType> {
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier,
+                                      getSizeModifier)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getIndexTypeQualifiers)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Expr *, getSizeExpr)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceRange, getBracketsRange)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getLBracketLoc)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getRBracketLoc)
+};
+
+template<>
+struct CanProxyAdaptor<DependentSizedArrayType>
+  : public CanProxyBase<DependentSizedArrayType> {
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Expr *, getSizeExpr)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceRange, getBracketsRange)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getLBracketLoc)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getRBracketLoc)
+};
+
+template<>
+struct CanProxyAdaptor<DependentSizedExtVectorType>
+  : public CanProxyBase<DependentSizedExtVectorType> {
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const Expr *, getSizeExpr)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getAttributeLoc)
+};
+
+template<>
+struct CanProxyAdaptor<VectorType> : public CanProxyBase<VectorType> {
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumElements)
+};
+
+template<>
+struct CanProxyAdaptor<ExtVectorType> : public CanProxyBase<ExtVectorType> {
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumElements)
+};
+
+template<>
+struct CanProxyAdaptor<FunctionType> : public CanProxyBase<FunctionType> {
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getResultType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo)
+};
+
+template<>
+struct CanProxyAdaptor<FunctionNoProtoType>
+  : public CanProxyBase<FunctionNoProtoType> {
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getResultType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo)
+};
+
+template<>
+struct CanProxyAdaptor<FunctionProtoType>
+  : public CanProxyBase<FunctionProtoType> {
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getResultType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumArgs)
+  CanQualType getArgType(unsigned i) const {
+    return CanQualType::CreateUnsafe(this->getTypePtr()->getArgType(i));
+  }
+
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariadic)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getTypeQuals)
+
+  typedef CanTypeIterator<FunctionProtoType::arg_type_iterator>
+    arg_type_iterator;
+
+  arg_type_iterator arg_type_begin() const {
+    return arg_type_iterator(this->getTypePtr()->arg_type_begin());
+  }
+
+  arg_type_iterator arg_type_end() const {
+    return arg_type_iterator(this->getTypePtr()->arg_type_end());
+  }
+
+  // Note: canonical function types never have exception specifications
+};
+
+template<>
+struct CanProxyAdaptor<TypeOfType> : public CanProxyBase<TypeOfType> {
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getUnderlyingType)
+};
+
+template<>
+struct CanProxyAdaptor<DecltypeType> : public CanProxyBase<DecltypeType> {
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Expr *, getUnderlyingExpr)
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getUnderlyingType)
+};
+
+template<>
+struct CanProxyAdaptor<TagType> : public CanProxyBase<TagType> {
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(TagDecl *, getDecl)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined)
+};
+
+template<>
+struct CanProxyAdaptor<RecordType> : public CanProxyBase<RecordType> {
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(RecordDecl *, getDecl)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasConstFields)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getAddressSpace)
+};
+
+template<>
+struct CanProxyAdaptor<EnumType> : public CanProxyBase<EnumType> {
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(EnumDecl *, getDecl)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined)
+};
+
+template<>
+struct CanProxyAdaptor<TemplateTypeParmType>
+  : public CanProxyBase<TemplateTypeParmType> {
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getDepth)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getIndex)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isParameterPack)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(IdentifierInfo *, getName)
+};
+
+template<>
+struct CanProxyAdaptor<ObjCObjectPointerType>
+  : public CanProxyBase<ObjCObjectPointerType> {
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const ObjCInterfaceType *,
+                                      getInterfaceType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCIdType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCClassType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedIdType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedClassType)
+
+  typedef ObjCObjectPointerType::qual_iterator qual_iterator;
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_begin)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_end)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, qual_empty)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumProtocols)
+};
+
+//----------------------------------------------------------------------------//
+// Method and function definitions
+//----------------------------------------------------------------------------//
+template<typename T>
+inline CanQual<T> CanQual<T>::getUnqualifiedType() const {
+  return CanQual<T>::CreateUnsafe(Stored.getLocalUnqualifiedType());
+}
+
+template<typename T>
+inline CanQual<Type> CanQual<T>::getNonReferenceType() const {
+  if (CanQual<ReferenceType> RefType = getAs<ReferenceType>())
+    return RefType->getPointeeType();
+  else
+    return *this;
+}
+
+template<typename T>
+CanQual<T> CanQual<T>::getFromOpaquePtr(void *Ptr) {
+  CanQual<T> Result;
+  Result.Stored.setFromOpaqueValue(Ptr);
+  assert((!Result || Result.Stored.isCanonical())
+         && "Type is not canonical!");
+  return Result;
+}
+
+template<typename T>
+CanQual<T> CanQual<T>::CreateUnsafe(QualType Other) {
+  assert((Other.isNull() || Other.isCanonical()) && "Type is not canonical!");
+  assert((Other.isNull() || isa<T>(Other.getTypePtr())) &&
+         "Dynamic type does not meet the static type's requires");
+  CanQual<T> Result;
+  Result.Stored = Other;
+  return Result;
+}
+
+template<typename T>
+template<typename U>
+CanProxy<U> CanQual<T>::getAs() const {
+  if (Stored.isNull())
+    return CanProxy<U>();
+
+  if (isa<U>(Stored.getTypePtr()))
+    return CanQual<U>::CreateUnsafe(Stored);
+
+  return CanProxy<U>();
+}
+
+template<typename T>
+CanProxy<T> CanQual<T>::operator->() const {
+  return CanProxy<T>(*this);
+}
+
+template<typename InputIterator>
+typename CanTypeIterator<InputIterator>::pointer
+CanTypeIterator<InputIterator>::operator->() const {
+  return CanProxy<Type>(*this);
+}
+
+}
+
+
+#endif // LLVM_CLANG_AST_CANONICAL_TYPE_H
diff --git a/include/clang/AST/CharUnits.h b/include/clang/AST/CharUnits.h
new file mode 100644
index 0000000..0bb4b76
--- /dev/null
+++ b/include/clang/AST/CharUnits.h
@@ -0,0 +1,149 @@
+//===--- CharUnits.h - Character units for sizes and offsets ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the CharUnits class
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_CHARUNITS_H
+#define LLVM_CLANG_AST_CHARUNITS_H
+
+#include "llvm/System/DataTypes.h"
+
+namespace clang {
+  
+  /// CharUnits - This is an opaque type for sizes expressed in character units.
+  /// Instances of this type represent a quantity as a multiple of the size 
+  /// of the standard C type, char, on the target architecture. As an opaque
+  /// type, CharUnits protects you from accidentally combining operations on
+  /// quantities in bit units and character units. 
+  ///
+  /// It should be noted that characters and bytes are distinct concepts. Bytes
+  /// refer to addressable units of data storage on the target machine, and
+  /// characters are members of a set of elements used for the organization,
+  /// control, or representation of data. According to C99, bytes are allowed
+  /// to exceed characters in size, although currently, clang only supports
+  /// architectures where the two are the same size.
+  /// 
+  /// For portability, never assume that a target character is 8 bits wide. Use 
+  /// CharUnit values whereever you calculate sizes, offsets, or alignments
+  /// in character units.
+  class CharUnits {
+    public:
+      typedef int64_t QuantityType;
+
+    private:
+      QuantityType Quantity;
+
+      explicit CharUnits(QuantityType C) : Quantity(C) {}
+
+    public:
+
+      /// CharUnits - A default constructor.
+      CharUnits() : Quantity(0) {}
+
+      /// Zero - Construct a CharUnits quantity of zero.
+      static CharUnits Zero() {
+        return CharUnits(0);
+      }
+
+      /// One - Construct a CharUnits quantity of one.
+      static CharUnits One() {
+        return CharUnits(1);
+      }
+
+      /// fromQuantity - Construct a CharUnits quantity from a raw integer type.
+      static CharUnits fromQuantity(QuantityType Quantity) {
+        return CharUnits(Quantity); 
+      }
+
+      // Compound assignment.
+      CharUnits& operator+= (const CharUnits &Other) {
+        Quantity += Other.Quantity;
+        return *this;
+      }
+      CharUnits& operator-= (const CharUnits &Other) {
+        Quantity -= Other.Quantity;
+        return *this;
+      }
+       
+      // Comparison operators.
+      bool operator== (const CharUnits &Other) const {
+        return Quantity == Other.Quantity;
+      }
+      bool operator!= (const CharUnits &Other) const {
+        return Quantity != Other.Quantity;
+      }
+
+      // Relational operators.
+      bool operator<  (const CharUnits &Other) const { 
+        return Quantity <  Other.Quantity; 
+      }
+      bool operator<= (const CharUnits &Other) const { 
+        return Quantity <= Other.Quantity;
+      }
+      bool operator>  (const CharUnits &Other) const { 
+        return Quantity >  Other.Quantity; 
+      }
+      bool operator>= (const CharUnits &Other) const { 
+        return Quantity >= Other.Quantity; 
+      }
+
+      // Other predicates.
+      
+      /// isZero - Test whether the quantity equals zero.
+      bool isZero() const     { return Quantity == 0; }
+
+      /// isOne - Test whether the quantity equals one.
+      bool isOne() const      { return Quantity == 1; }
+
+      /// isPositive - Test whether the quantity is greater than zero.
+      bool isPositive() const { return Quantity  > 0; }
+
+      /// isNegative - Test whether the quantity is less than zero.
+      bool isNegative() const { return Quantity  < 0; }
+
+      // Arithmetic operators.
+      CharUnits operator* (QuantityType N) const {
+        return CharUnits(Quantity * N);
+      }
+      CharUnits operator/ (QuantityType N) const {
+        return CharUnits(Quantity / N);
+      }
+      QuantityType operator/ (const CharUnits &Other) const {
+        return Quantity / Other.Quantity;
+      }
+      CharUnits operator% (QuantityType N) const {
+        return CharUnits(Quantity % N);
+      }
+      QuantityType operator% (const CharUnits &Other) const {
+        return Quantity % Other.Quantity;
+      }
+      CharUnits operator+ (const CharUnits &Other) const {
+        return CharUnits(Quantity + Other.Quantity);
+      }
+      CharUnits operator- (const CharUnits &Other) const {
+        return CharUnits(Quantity - Other.Quantity);
+      }
+      
+      // Conversions.
+
+      /// getQuantity - Get the raw integer representation of this quantity.
+      QuantityType getQuantity() const { return Quantity; }
+
+
+  }; // class CharUnit
+} // namespace clang
+
+inline clang::CharUnits operator* (clang::CharUnits::QuantityType Scale, 
+                                   const clang::CharUnits &CU) {
+  return CU * Scale;
+}
+
+#endif // LLVM_CLANG_AST_CHARUNITS_H
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
new file mode 100644
index 0000000..626657d
--- /dev/null
+++ b/include/clang/AST/Decl.h
@@ -0,0 +1,2086 @@
+//===--- Decl.h - Classes for representing declarations ---------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the Decl subclasses.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_DECL_H
+#define LLVM_CLANG_AST_DECL_H
+
+#include "clang/AST/APValue.h"
+#include "clang/AST/DeclBase.h"
+#include "clang/AST/Redeclarable.h"
+#include "clang/AST/DeclarationName.h"
+#include "clang/AST/ExternalASTSource.h"
+#include "clang/Basic/Linkage.h"
+
+namespace clang {
+class CXXTemporary;
+class Expr;
+class FunctionTemplateDecl;
+class Stmt;
+class CompoundStmt;
+class StringLiteral;
+class TemplateArgumentList;
+class MemberSpecializationInfo;
+class FunctionTemplateSpecializationInfo;
+class DependentFunctionTemplateSpecializationInfo;
+class TypeLoc;
+class UnresolvedSetImpl;
+
+/// \brief A container of type source information.
+///
+/// A client can read the relevant info using TypeLoc wrappers, e.g:
+/// @code
+/// TypeLoc TL = TypeSourceInfo->getTypeLoc();
+/// if (PointerLoc *PL = dyn_cast<PointerLoc>(&TL))
+///   PL->getStarLoc().print(OS, SrcMgr);
+/// @endcode
+///
+class TypeSourceInfo {
+  QualType Ty;
+  // Contains a memory block after the class, used for type source information,
+  // allocated by ASTContext.
+  friend class ASTContext;
+  TypeSourceInfo(QualType ty) : Ty(ty) { }
+public:
+  /// \brief Return the type wrapped by this type source info.
+  QualType getType() const { return Ty; }
+
+  /// \brief Return the TypeLoc wrapper for the type source info.
+  TypeLoc getTypeLoc() const;
+};
+
+/// TranslationUnitDecl - The top declaration context.
+class TranslationUnitDecl : public Decl, public DeclContext {
+  ASTContext &Ctx;
+
+  /// The (most recently entered) anonymous namespace for this
+  /// translation unit, if one has been created.
+  NamespaceDecl *AnonymousNamespace;
+
+  explicit TranslationUnitDecl(ASTContext &ctx)
+    : Decl(TranslationUnit, 0, SourceLocation()),
+      DeclContext(TranslationUnit),
+      Ctx(ctx), AnonymousNamespace(0) {}
+public:
+  ASTContext &getASTContext() const { return Ctx; }
+
+  NamespaceDecl *getAnonymousNamespace() const { return AnonymousNamespace; }
+  void setAnonymousNamespace(NamespaceDecl *D) { AnonymousNamespace = D; }
+
+  static TranslationUnitDecl *Create(ASTContext &C);
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classof(const TranslationUnitDecl *D) { return true; }
+  static bool classofKind(Kind K) { return K == TranslationUnit; }
+  static DeclContext *castToDeclContext(const TranslationUnitDecl *D) {
+    return static_cast<DeclContext *>(const_cast<TranslationUnitDecl*>(D));
+  }
+  static TranslationUnitDecl *castFromDeclContext(const DeclContext *DC) {
+    return static_cast<TranslationUnitDecl *>(const_cast<DeclContext*>(DC));
+  }
+};
+
+/// NamedDecl - This represents a decl with a name.  Many decls have names such
+/// as ObjCMethodDecl, but not @class, etc.
+class NamedDecl : public Decl {
+  /// Name - The name of this declaration, which is typically a normal
+  /// identifier but may also be a special kind of name (C++
+  /// constructor, Objective-C selector, etc.)
+  DeclarationName Name;
+
+protected:
+  NamedDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName N)
+    : Decl(DK, DC, L), Name(N) { }
+
+public:
+  /// getIdentifier - Get the identifier that names this declaration,
+  /// if there is one. This will return NULL if this declaration has
+  /// no name (e.g., for an unnamed class) or if the name is a special
+  /// name (C++ constructor, Objective-C selector, etc.).
+  IdentifierInfo *getIdentifier() const { return Name.getAsIdentifierInfo(); }
+
+  /// getName - Get the name of identifier for this declaration as a StringRef.
+  /// This requires that the declaration have a name and that it be a simple
+  /// identifier.
+  llvm::StringRef getName() const {
+    assert(Name.isIdentifier() && "Name is not a simple identifier");
+    return getIdentifier() ? getIdentifier()->getName() : "";
+  }
+
+  /// getNameAsCString - Get the name of identifier for this declaration as a
+  /// C string (const char*).  This requires that the declaration have a name
+  /// and that it be a simple identifier.
+  //
+  // FIXME: Deprecated, move clients to getName().
+  const char *getNameAsCString() const {
+    assert(Name.isIdentifier() && "Name is not a simple identifier");
+    return getIdentifier() ? getIdentifier()->getNameStart() : "";
+  }
+
+  /// getNameAsString - Get a human-readable name for the declaration, even if
+  /// it is one of the special kinds of names (C++ constructor, Objective-C
+  /// selector, etc).  Creating this name requires expensive string
+  /// manipulation, so it should be called only when performance doesn't matter.
+  /// For simple declarations, getNameAsCString() should suffice.
+  //
+  // FIXME: This function should be renamed to indicate that it is not just an
+  // alternate form of getName(), and clients should move as appropriate.
+  //
+  // FIXME: Deprecated, move clients to getName().
+  std::string getNameAsString() const { return Name.getAsString(); }
+
+  /// getDeclName - Get the actual, stored name of the declaration,
+  /// which may be a special name.
+  DeclarationName getDeclName() const { return Name; }
+
+  /// \brief Set the name of this declaration.
+  void setDeclName(DeclarationName N) { Name = N; }
+
+  /// getQualifiedNameAsString - Returns human-readable qualified name for
+  /// declaration, like A::B::i, for i being member of namespace A::B.
+  /// If declaration is not member of context which can be named (record,
+  /// namespace), it will return same result as getNameAsString().
+  /// Creating this name is expensive, so it should be called only when
+  /// performance doesn't matter.
+  std::string getQualifiedNameAsString() const;
+  std::string getQualifiedNameAsString(const PrintingPolicy &Policy) const;
+
+  /// getNameForDiagnostic - Appends a human-readable name for this
+  /// declaration into the given string.
+  ///
+  /// This is the method invoked by Sema when displaying a NamedDecl
+  /// in a diagnostic.  It does not necessarily produce the same
+  /// result as getNameAsString(); for example, class template
+  /// specializations are printed with their template arguments.
+  ///
+  /// TODO: use an API that doesn't require so many temporary strings
+  virtual void getNameForDiagnostic(std::string &S,
+                                    const PrintingPolicy &Policy,
+                                    bool Qualified) const {
+    if (Qualified)
+      S += getQualifiedNameAsString(Policy);
+    else
+      S += getNameAsString();
+  }
+
+  /// declarationReplaces - Determine whether this declaration, if
+  /// known to be well-formed within its context, will replace the
+  /// declaration OldD if introduced into scope. A declaration will
+  /// replace another declaration if, for example, it is a
+  /// redeclaration of the same variable or function, but not if it is
+  /// a declaration of a different kind (function vs. class) or an
+  /// overloaded function.
+  bool declarationReplaces(NamedDecl *OldD) const;
+
+  /// \brief Determine whether this declaration has linkage.
+  bool hasLinkage() const;
+
+  /// \brief Determine whether this declaration is a C++ class member.
+  bool isCXXClassMember() const {
+    const DeclContext *DC = getDeclContext();
+
+    // C++0x [class.mem]p1:
+    //   The enumerators of an unscoped enumeration defined in
+    //   the class are members of the class.
+    // FIXME: support C++0x scoped enumerations.
+    if (isa<EnumDecl>(DC))
+      DC = DC->getParent();
+
+    return DC->isRecord();
+  }
+
+  /// \brief Given that this declaration is a C++ class member,
+  /// determine whether it's an instance member of its class.
+  bool isCXXInstanceMember() const;
+
+  /// \brief Determine what kind of linkage this entity has.
+  Linkage getLinkage() const;
+
+  /// \brief Looks through UsingDecls and ObjCCompatibleAliasDecls for
+  /// the underlying named decl.
+  NamedDecl *getUnderlyingDecl();
+  const NamedDecl *getUnderlyingDecl() const {
+    return const_cast<NamedDecl*>(this)->getUnderlyingDecl();
+  }
+
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classof(const NamedDecl *D) { return true; }
+  static bool classofKind(Kind K) { return K >= NamedFirst && K <= NamedLast; }
+};
+
+inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
+                                     const NamedDecl *ND) {
+  ND->getDeclName().printName(OS);
+  return OS;
+}
+
+/// NamespaceDecl - Represent a C++ namespace.
+class NamespaceDecl : public NamedDecl, public DeclContext {
+  SourceLocation LBracLoc, RBracLoc;
+
+  // For extended namespace definitions:
+  //
+  // namespace A { int x; }
+  // namespace A { int y; }
+  //
+  // there will be one NamespaceDecl for each declaration.
+  // NextNamespace points to the next extended declaration.
+  // OrigNamespace points to the original namespace declaration.
+  // OrigNamespace of the first namespace decl points to itself.
+  NamespaceDecl *NextNamespace;
+
+  /// \brief A pointer to either the original namespace definition for
+  /// this namespace (if the boolean value is false) or the anonymous
+  /// namespace that lives just inside this namespace (if the boolean
+  /// value is true).
+  ///
+  /// We can combine these two notions because the anonymous namespace
+  /// must only be stored in one of the namespace declarations (so all
+  /// of the namespace declarations can find it). We therefore choose
+  /// the original namespace declaration, since all of the namespace
+  /// declarations have a link directly to it; the original namespace
+  /// declaration itself only needs to know that it is the original
+  /// namespace declaration (which the boolean indicates).
+  llvm::PointerIntPair<NamespaceDecl *, 1, bool> OrigOrAnonNamespace;
+
+  NamespaceDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id)
+    : NamedDecl(Namespace, DC, L, Id), DeclContext(Namespace),
+      NextNamespace(0), OrigOrAnonNamespace(0, true) { }
+
+public:
+  static NamespaceDecl *Create(ASTContext &C, DeclContext *DC,
+                               SourceLocation L, IdentifierInfo *Id);
+
+  virtual void Destroy(ASTContext& C);
+
+  // \brief Returns true if this is an anonymous namespace declaration.
+  //
+  // For example:
+  //   namespace {
+  //     ...
+  //   };
+  // q.v. C++ [namespace.unnamed]
+  bool isAnonymousNamespace() const {
+    return !getIdentifier();
+  }
+
+  NamespaceDecl *getNextNamespace() { return NextNamespace; }
+  const NamespaceDecl *getNextNamespace() const { return NextNamespace; }
+  void setNextNamespace(NamespaceDecl *ND) { NextNamespace = ND; }
+
+  NamespaceDecl *getOriginalNamespace() const {
+    if (OrigOrAnonNamespace.getInt())
+      return const_cast<NamespaceDecl *>(this);
+
+    return OrigOrAnonNamespace.getPointer();
+  }
+
+  void setOriginalNamespace(NamespaceDecl *ND) { 
+    if (ND != this) {
+      OrigOrAnonNamespace.setPointer(ND);
+      OrigOrAnonNamespace.setInt(false);
+    }
+  }
+
+  NamespaceDecl *getAnonymousNamespace() const {
+    return getOriginalNamespace()->OrigOrAnonNamespace.getPointer();
+  }
+
+  void setAnonymousNamespace(NamespaceDecl *D) {
+    assert(!D || D->isAnonymousNamespace());
+    assert(!D || D->getParent() == this);
+    getOriginalNamespace()->OrigOrAnonNamespace.setPointer(D);
+  }
+
+  virtual NamespaceDecl *getCanonicalDecl() { return getOriginalNamespace(); }
+  const NamespaceDecl *getCanonicalDecl() const { 
+    return getOriginalNamespace(); 
+  }
+
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(getLocation(), RBracLoc);
+  }
+
+  SourceLocation getLBracLoc() const { return LBracLoc; }
+  SourceLocation getRBracLoc() const { return RBracLoc; }
+  void setLBracLoc(SourceLocation LBrace) { LBracLoc = LBrace; }
+  void setRBracLoc(SourceLocation RBrace) { RBracLoc = RBrace; }
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classof(const NamespaceDecl *D) { return true; }
+  static bool classofKind(Kind K) { return K == Namespace; }
+  static DeclContext *castToDeclContext(const NamespaceDecl *D) {
+    return static_cast<DeclContext *>(const_cast<NamespaceDecl*>(D));
+  }
+  static NamespaceDecl *castFromDeclContext(const DeclContext *DC) {
+    return static_cast<NamespaceDecl *>(const_cast<DeclContext*>(DC));
+  }
+};
+
+/// ValueDecl - Represent the declaration of a variable (in which case it is
+/// an lvalue) a function (in which case it is a function designator) or
+/// an enum constant.
+class ValueDecl : public NamedDecl {
+  QualType DeclType;
+
+protected:
+  ValueDecl(Kind DK, DeclContext *DC, SourceLocation L,
+            DeclarationName N, QualType T)
+    : NamedDecl(DK, DC, L, N), DeclType(T) {}
+public:
+  QualType getType() const { return DeclType; }
+  void setType(QualType newType) { DeclType = newType; }
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classof(const ValueDecl *D) { return true; }
+  static bool classofKind(Kind K) { return K >= ValueFirst && K <= ValueLast; }
+};
+
+/// \brief Represents a ValueDecl that came out of a declarator.
+/// Contains type source information through TypeSourceInfo.
+class DeclaratorDecl : public ValueDecl {
+  // A struct representing both a TInfo and a syntactic qualifier,
+  // to be used for the (uncommon) case of out-of-line declarations.
+  struct ExtInfo {
+    TypeSourceInfo *TInfo;
+    NestedNameSpecifier *NNS;
+    SourceRange NNSRange;
+  };
+
+  llvm::PointerUnion<TypeSourceInfo*, ExtInfo*> DeclInfo;
+
+  bool hasExtInfo() const { return DeclInfo.is<ExtInfo*>(); }
+  ExtInfo *getExtInfo() { return DeclInfo.get<ExtInfo*>(); }
+  const ExtInfo *getExtInfo() const { return DeclInfo.get<ExtInfo*>(); }
+
+protected:
+  DeclaratorDecl(Kind DK, DeclContext *DC, SourceLocation L,
+                 DeclarationName N, QualType T, TypeSourceInfo *TInfo)
+    : ValueDecl(DK, DC, L, N, T), DeclInfo(TInfo) {}
+
+public:
+  virtual ~DeclaratorDecl();
+  virtual void Destroy(ASTContext &C);
+
+  TypeSourceInfo *getTypeSourceInfo() const {
+    return hasExtInfo()
+      ? DeclInfo.get<ExtInfo*>()->TInfo
+      : DeclInfo.get<TypeSourceInfo*>();
+  }
+  void setTypeSourceInfo(TypeSourceInfo *TI) {
+    if (hasExtInfo())
+      DeclInfo.get<ExtInfo*>()->TInfo = TI;
+    else
+      DeclInfo = TI;
+  }
+
+  NestedNameSpecifier *getQualifier() const {
+    return hasExtInfo() ? DeclInfo.get<ExtInfo*>()->NNS : 0;
+  }
+  SourceRange getQualifierRange() const {
+    return hasExtInfo() ? DeclInfo.get<ExtInfo*>()->NNSRange : SourceRange();
+  }
+  void setQualifierInfo(NestedNameSpecifier *Qualifier,
+                        SourceRange QualifierRange);
+
+  SourceLocation getTypeSpecStartLoc() const;
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classof(const DeclaratorDecl *D) { return true; }
+  static bool classofKind(Kind K) {
+    return K >= DeclaratorFirst && K <= DeclaratorLast;
+  }
+};
+
+/// \brief Structure used to store a statement, the constant value to
+/// which it was evaluated (if any), and whether or not the statement
+/// is an integral constant expression (if known).
+struct EvaluatedStmt {
+  EvaluatedStmt() : WasEvaluated(false), IsEvaluating(false), CheckedICE(false),
+                    CheckingICE(false), IsICE(false) { }
+
+  /// \brief Whether this statement was already evaluated.
+  bool WasEvaluated : 1;
+
+  /// \brief Whether this statement is being evaluated.
+  bool IsEvaluating : 1;
+
+  /// \brief Whether we already checked whether this statement was an
+  /// integral constant expression.
+  bool CheckedICE : 1;
+
+  /// \brief Whether we are checking whether this statement is an
+  /// integral constant expression.
+  bool CheckingICE : 1;
+
+  /// \brief Whether this statement is an integral constant
+  /// expression. Only valid if CheckedICE is true.
+  bool IsICE : 1;
+
+  Stmt *Value;
+  APValue Evaluated;
+};
+
+// \brief Describes the kind of template specialization that a
+// particular template specialization declaration represents.
+enum TemplateSpecializationKind {
+  /// This template specialization was formed from a template-id but
+  /// has not yet been declared, defined, or instantiated.
+  TSK_Undeclared = 0,
+  /// This template specialization was implicitly instantiated from a
+  /// template. (C++ [temp.inst]).
+  TSK_ImplicitInstantiation,
+  /// This template specialization was declared or defined by an
+  /// explicit specialization (C++ [temp.expl.spec]) or partial
+  /// specialization (C++ [temp.class.spec]).
+  TSK_ExplicitSpecialization,
+  /// This template specialization was instantiated from a template
+  /// due to an explicit instantiation declaration request
+  /// (C++0x [temp.explicit]).
+  TSK_ExplicitInstantiationDeclaration,
+  /// This template specialization was instantiated from a template
+  /// due to an explicit instantiation definition request
+  /// (C++ [temp.explicit]).
+  TSK_ExplicitInstantiationDefinition
+};
+  
+/// VarDecl - An instance of this class is created to represent a variable
+/// declaration or definition.
+class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {
+public:
+  enum StorageClass {
+    None, Auto, Register, Extern, Static, PrivateExtern
+  };
+
+  /// getStorageClassSpecifierString - Return the string used to
+  /// specify the storage class \arg SC.
+  ///
+  /// It is illegal to call this function with SC == None.
+  static const char *getStorageClassSpecifierString(StorageClass SC);
+
+protected:
+  /// \brief Placeholder type used in Init to denote an unparsed C++ default
+  /// argument.
+  struct UnparsedDefaultArgument;
+
+  /// \brief Placeholder type used in Init to denote an uninstantiated C++
+  /// default argument.
+  struct UninstantiatedDefaultArgument;
+
+  typedef llvm::PointerUnion4<Stmt *, EvaluatedStmt *,
+                              UnparsedDefaultArgument *,
+                              UninstantiatedDefaultArgument *> InitType;
+
+  /// \brief The initializer for this variable or, for a ParmVarDecl, the
+  /// C++ default argument.
+  mutable InitType Init;
+
+private:
+  // FIXME: This can be packed into the bitfields in Decl.
+  unsigned SClass : 3;
+  unsigned SClassAsWritten : 3;
+  bool ThreadSpecified : 1;
+  bool HasCXXDirectInit : 1;
+
+  /// DeclaredInCondition - Whether this variable was declared in a
+  /// condition, e.g., if (int x = foo()) { ... }.
+  bool DeclaredInCondition : 1;
+
+  friend class StmtIteratorBase;
+protected:
+  VarDecl(Kind DK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
+          QualType T, TypeSourceInfo *TInfo, StorageClass SC,
+          StorageClass SCAsWritten)
+    : DeclaratorDecl(DK, DC, L, Id, T, TInfo), Init(),
+      ThreadSpecified(false), HasCXXDirectInit(false),
+      DeclaredInCondition(false) {
+    SClass = SC;
+    SClassAsWritten = SCAsWritten;
+  }
+
+  typedef Redeclarable<VarDecl> redeclarable_base;
+  virtual VarDecl *getNextRedeclaration() { return RedeclLink.getNext(); }
+
+public:
+  typedef redeclarable_base::redecl_iterator redecl_iterator;
+  redecl_iterator redecls_begin() const {
+    return redeclarable_base::redecls_begin();
+  }
+  redecl_iterator redecls_end() const {
+    return redeclarable_base::redecls_end();
+  }
+
+  static VarDecl *Create(ASTContext &C, DeclContext *DC,
+                         SourceLocation L, IdentifierInfo *Id,
+                         QualType T, TypeSourceInfo *TInfo, StorageClass S,
+                         StorageClass SCAsWritten);
+
+  virtual void Destroy(ASTContext& C);
+  virtual ~VarDecl();
+
+  virtual SourceRange getSourceRange() const;
+
+  StorageClass getStorageClass() const { return (StorageClass)SClass; }
+  StorageClass getStorageClassAsWritten() const {
+    return (StorageClass) SClassAsWritten;
+  }
+  void setStorageClass(StorageClass SC) { SClass = SC; }
+  void setStorageClassAsWritten(StorageClass SC) { SClassAsWritten = SC; }
+
+  void setThreadSpecified(bool T) { ThreadSpecified = T; }
+  bool isThreadSpecified() const {
+    return ThreadSpecified;
+  }
+
+  /// hasLocalStorage - Returns true if a variable with function scope
+  ///  is a non-static local variable.
+  bool hasLocalStorage() const {
+    if (getStorageClass() == None)
+      return !isFileVarDecl();
+
+    // Return true for:  Auto, Register.
+    // Return false for: Extern, Static, PrivateExtern.
+
+    return getStorageClass() <= Register;
+  }
+
+  /// isStaticLocal - Returns true if a variable with function scope is a 
+  /// static local variable.
+  bool isStaticLocal() const {
+    return getStorageClass() == Static && !isFileVarDecl();
+  }
+  
+  /// hasExternStorage - Returns true if a variable has extern or
+  /// __private_extern__ storage.
+  bool hasExternalStorage() const {
+    return getStorageClass() == Extern || getStorageClass() == PrivateExtern;
+  }
+
+  /// hasGlobalStorage - Returns true for all variables that do not
+  ///  have local storage.  This includs all global variables as well
+  ///  as static variables declared within a function.
+  bool hasGlobalStorage() const { return !hasLocalStorage(); }
+
+  /// \brief Determines whether this variable is a variable with
+  /// external, C linkage.
+  bool isExternC() const;
+
+  /// isBlockVarDecl - Returns true for local variable declarations.  Note that
+  /// this includes static variables inside of functions. It also includes
+  /// variables inside blocks.
+  ///
+  ///   void foo() { int x; static int y; extern int z; }
+  ///
+  bool isBlockVarDecl() const {
+    if (getKind() != Decl::Var)
+      return false;
+    if (const DeclContext *DC = getDeclContext())
+      return DC->getLookupContext()->isFunctionOrMethod();
+    return false;
+  }
+
+  /// isFunctionOrMethodVarDecl - Similar to isBlockVarDecl, but excludes
+  /// variables declared in blocks.
+  bool isFunctionOrMethodVarDecl() const {
+    if (getKind() != Decl::Var)
+      return false;
+    if (const DeclContext *DC = getDeclContext())
+      return DC->getLookupContext()->isFunctionOrMethod() &&
+             DC->getLookupContext()->getDeclKind() != Decl::Block;
+    return false;
+  }
+
+  /// \brief Determines whether this is a static data member.
+  ///
+  /// This will only be true in C++, and applies to, e.g., the
+  /// variable 'x' in:
+  /// \code
+  /// struct S {
+  ///   static int x;
+  /// };
+  /// \endcode
+  bool isStaticDataMember() const {
+    // If it wasn't static, it would be a FieldDecl.
+    return getDeclContext()->isRecord();
+  }
+
+  virtual VarDecl *getCanonicalDecl();
+  const VarDecl *getCanonicalDecl() const {
+    return const_cast<VarDecl*>(this)->getCanonicalDecl();
+  }
+
+  enum DefinitionKind {
+    DeclarationOnly,      ///< This declaration is only a declaration.
+    TentativeDefinition,  ///< This declaration is a tentative definition.
+    Definition            ///< This declaration is definitely a definition.
+  };
+
+  /// \brief Check whether this declaration is a definition. If this could be
+  /// a tentative definition (in C), don't check whether there's an overriding
+  /// definition.
+  DefinitionKind isThisDeclarationADefinition() const;
+
+  /// \brief Get the tentative definition that acts as the real definition in
+  /// a TU. Returns null if there is a proper definition available.
+  VarDecl *getActingDefinition();
+  const VarDecl *getActingDefinition() const {
+    return const_cast<VarDecl*>(this)->getActingDefinition();
+  }
+
+  /// \brief Determine whether this is a tentative definition of a
+  /// variable in C.
+  bool isTentativeDefinitionNow() const;
+
+  /// \brief Get the real (not just tentative) definition for this declaration.
+  VarDecl *getDefinition();
+  const VarDecl *getDefinition() const {
+    return const_cast<VarDecl*>(this)->getDefinition();
+  }
+
+  /// \brief Determine whether this is or was instantiated from an out-of-line 
+  /// definition of a static data member.
+  virtual bool isOutOfLine() const;
+
+  /// \brief If this is a static data member, find its out-of-line definition.
+  VarDecl *getOutOfLineDefinition();
+  
+  /// isFileVarDecl - Returns true for file scoped variable declaration.
+  bool isFileVarDecl() const {
+    if (getKind() != Decl::Var)
+      return false;
+    if (const DeclContext *Ctx = getDeclContext()) {
+      Ctx = Ctx->getLookupContext();
+      if (isa<TranslationUnitDecl>(Ctx) || isa<NamespaceDecl>(Ctx) )
+        return true;
+    }
+    if (isStaticDataMember())
+      return true;
+
+    return false;
+  }
+
+  /// getAnyInitializer - Get the initializer for this variable, no matter which
+  /// declaration it is attached to.
+  const Expr *getAnyInitializer() const {
+    const VarDecl *D;
+    return getAnyInitializer(D);
+  }
+
+  /// getAnyInitializer - Get the initializer for this variable, no matter which
+  /// declaration it is attached to. Also get that declaration.
+  const Expr *getAnyInitializer(const VarDecl *&D) const;
+
+  bool hasInit() const {
+    return !Init.isNull();
+  }
+  const Expr *getInit() const {
+    if (Init.isNull())
+      return 0;
+
+    const Stmt *S = Init.dyn_cast<Stmt *>();
+    if (!S) {
+      if (EvaluatedStmt *ES = Init.dyn_cast<EvaluatedStmt*>())
+        S = ES->Value;
+    }
+    return (const Expr*) S;
+  }
+  Expr *getInit() {
+    if (Init.isNull())
+      return 0;
+
+    Stmt *S = Init.dyn_cast<Stmt *>();
+    if (!S) {
+      if (EvaluatedStmt *ES = Init.dyn_cast<EvaluatedStmt*>())
+        S = ES->Value;
+    }
+
+    return (Expr*) S;
+  }
+
+  /// \brief Retrieve the address of the initializer expression.
+  Stmt **getInitAddress() {
+    if (EvaluatedStmt *ES = Init.dyn_cast<EvaluatedStmt*>())
+      return &ES->Value;
+
+    // This union hack tip-toes around strict-aliasing rules.
+    union {
+      InitType *InitPtr;
+      Stmt **StmtPtr;
+    };
+
+    InitPtr = &Init;
+    return StmtPtr;
+  }
+
+  void setInit(Expr *I);
+
+  EvaluatedStmt *EnsureEvaluatedStmt() const {
+    EvaluatedStmt *Eval = Init.dyn_cast<EvaluatedStmt *>();
+    if (!Eval) {
+      Stmt *S = Init.get<Stmt *>();
+      Eval = new (getASTContext()) EvaluatedStmt;
+      Eval->Value = S;
+      Init = Eval;
+    }
+    return Eval;
+  }
+
+  /// \brief Check whether we are in the process of checking whether the
+  /// initializer can be evaluated.
+  bool isEvaluatingValue() const {
+    if (EvaluatedStmt *Eval = Init.dyn_cast<EvaluatedStmt *>())
+      return Eval->IsEvaluating;
+
+    return false;
+  }
+
+  /// \brief Note that we now are checking whether the initializer can be
+  /// evaluated.
+  void setEvaluatingValue() const {
+    EvaluatedStmt *Eval = EnsureEvaluatedStmt();
+    Eval->IsEvaluating = true;
+  }
+
+  /// \brief Note that constant evaluation has computed the given
+  /// value for this variable's initializer.
+  void setEvaluatedValue(const APValue &Value) const {
+    EvaluatedStmt *Eval = EnsureEvaluatedStmt();
+    Eval->IsEvaluating = false;
+    Eval->WasEvaluated = true;
+    Eval->Evaluated = Value;
+  }
+
+  /// \brief Return the already-evaluated value of this variable's
+  /// initializer, or NULL if the value is not yet known. Returns pointer
+  /// to untyped APValue if the value could not be evaluated.
+  APValue *getEvaluatedValue() const {
+    if (EvaluatedStmt *Eval = Init.dyn_cast<EvaluatedStmt *>())
+      if (Eval->WasEvaluated)
+        return &Eval->Evaluated;
+
+    return 0;
+  }
+
+  /// \brief Determines whether it is already known whether the
+  /// initializer is an integral constant expression or not.
+  bool isInitKnownICE() const {
+    if (EvaluatedStmt *Eval = Init.dyn_cast<EvaluatedStmt *>())
+      return Eval->CheckedICE;
+
+    return false;
+  }
+
+  /// \brief Determines whether the initializer is an integral
+  /// constant expression.
+  ///
+  /// \pre isInitKnownICE()
+  bool isInitICE() const {
+    assert(isInitKnownICE() &&
+           "Check whether we already know that the initializer is an ICE");
+    return Init.get<EvaluatedStmt *>()->IsICE;
+  }
+
+  /// \brief Check whether we are in the process of checking the initializer
+  /// is an integral constant expression.
+  bool isCheckingICE() const {
+    if (EvaluatedStmt *Eval = Init.dyn_cast<EvaluatedStmt *>())
+      return Eval->CheckingICE;
+
+    return false;
+  }
+
+  /// \brief Note that we now are checking whether the initializer is an
+  /// integral constant expression.
+  void setCheckingICE() const {
+    EvaluatedStmt *Eval = EnsureEvaluatedStmt();
+    Eval->CheckingICE = true;
+  }
+
+  /// \brief Note that we now know whether the initializer is an
+  /// integral constant expression.
+  void setInitKnownICE(bool IsICE) const {
+    EvaluatedStmt *Eval = EnsureEvaluatedStmt();
+    Eval->CheckingICE = false;
+    Eval->CheckedICE = true;
+    Eval->IsICE = IsICE;
+  }
+
+  void setCXXDirectInitializer(bool T) { HasCXXDirectInit = T; }
+
+  /// hasCXXDirectInitializer - If true, the initializer was a direct
+  /// initializer, e.g: "int x(1);". The Init expression will be the expression
+  /// inside the parens or a "ClassType(a,b,c)" class constructor expression for
+  /// class types. Clients can distinguish between "int x(1);" and "int x=1;"
+  /// by checking hasCXXDirectInitializer.
+  ///
+  bool hasCXXDirectInitializer() const {
+    return HasCXXDirectInit;
+  }
+
+  /// isDeclaredInCondition - Whether this variable was declared as
+  /// part of a condition in an if/switch/while statement, e.g.,
+  /// @code
+  /// if (int x = foo()) { ... }
+  /// @endcode
+  bool isDeclaredInCondition() const {
+    return DeclaredInCondition;
+  }
+  void setDeclaredInCondition(bool InCondition) {
+    DeclaredInCondition = InCondition;
+  }
+  
+  /// \brief If this variable is an instantiated static data member of a
+  /// class template specialization, returns the templated static data member
+  /// from which it was instantiated.
+  VarDecl *getInstantiatedFromStaticDataMember() const;
+
+  /// \brief If this variable is a static data member, determine what kind of 
+  /// template specialization or instantiation this is.
+  TemplateSpecializationKind getTemplateSpecializationKind() const;
+  
+  /// \brief If this variable is an instantiation of a static data member of a
+  /// class template specialization, retrieves the member specialization
+  /// information.
+  MemberSpecializationInfo *getMemberSpecializationInfo() const;
+  
+  /// \brief For a static data member that was instantiated from a static
+  /// data member of a class template, set the template specialiation kind.
+  void setTemplateSpecializationKind(TemplateSpecializationKind TSK,
+                        SourceLocation PointOfInstantiation = SourceLocation());
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classof(const VarDecl *D) { return true; }
+  static bool classofKind(Kind K) { return K >= VarFirst && K <= VarLast; }
+};
+
+class ImplicitParamDecl : public VarDecl {
+protected:
+  ImplicitParamDecl(Kind DK, DeclContext *DC, SourceLocation L,
+                    IdentifierInfo *Id, QualType Tw)
+    : VarDecl(DK, DC, L, Id, Tw, /*TInfo=*/0, VarDecl::None, VarDecl::None) {}
+public:
+  static ImplicitParamDecl *Create(ASTContext &C, DeclContext *DC,
+                                   SourceLocation L, IdentifierInfo *Id,
+                                   QualType T);
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const ImplicitParamDecl *D) { return true; }
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) { return K == ImplicitParam; }
+};
+
+/// ParmVarDecl - Represent a parameter to a function.
+class ParmVarDecl : public VarDecl {
+  // NOTE: VC++ treats enums as signed, avoid using the ObjCDeclQualifier enum
+  /// FIXME: Also can be paced into the bitfields in Decl.
+  /// in, inout, etc.
+  unsigned objcDeclQualifier : 6;
+  bool HasInheritedDefaultArg : 1;
+
+protected:
+  ParmVarDecl(Kind DK, DeclContext *DC, SourceLocation L,
+              IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
+              StorageClass S, StorageClass SCAsWritten, Expr *DefArg)
+    : VarDecl(DK, DC, L, Id, T, TInfo, S, SCAsWritten),
+      objcDeclQualifier(OBJC_TQ_None), HasInheritedDefaultArg(false) {
+    setDefaultArg(DefArg);
+  }
+
+public:
+  static ParmVarDecl *Create(ASTContext &C, DeclContext *DC,
+                             SourceLocation L,IdentifierInfo *Id,
+                             QualType T, TypeSourceInfo *TInfo,
+                             StorageClass S, StorageClass SCAsWritten,
+                             Expr *DefArg);
+
+  ObjCDeclQualifier getObjCDeclQualifier() const {
+    return ObjCDeclQualifier(objcDeclQualifier);
+  }
+  void setObjCDeclQualifier(ObjCDeclQualifier QTVal) {
+    objcDeclQualifier = QTVal;
+  }
+
+  Expr *getDefaultArg();
+  const Expr *getDefaultArg() const {
+    return const_cast<ParmVarDecl *>(this)->getDefaultArg();
+  }
+  
+  void setDefaultArg(Expr *defarg) {
+    Init = reinterpret_cast<Stmt *>(defarg);
+  }
+
+  unsigned getNumDefaultArgTemporaries() const;
+  CXXTemporary *getDefaultArgTemporary(unsigned i);
+  const CXXTemporary *getDefaultArgTemporary(unsigned i) const {
+    return const_cast<ParmVarDecl *>(this)->getDefaultArgTemporary(i);
+  }
+  
+  /// \brief Retrieve the source range that covers the entire default
+  /// argument.
+  SourceRange getDefaultArgRange() const;  
+  void setUninstantiatedDefaultArg(Expr *arg) {
+    Init = reinterpret_cast<UninstantiatedDefaultArgument *>(arg);
+  }
+  Expr *getUninstantiatedDefaultArg() {
+    return (Expr *)Init.get<UninstantiatedDefaultArgument *>();
+  }
+  const Expr *getUninstantiatedDefaultArg() const {
+    return (const Expr *)Init.get<UninstantiatedDefaultArgument *>();
+  }
+
+  /// hasDefaultArg - Determines whether this parameter has a default argument,
+  /// either parsed or not.
+  bool hasDefaultArg() const {
+    return getInit() || hasUnparsedDefaultArg() ||
+      hasUninstantiatedDefaultArg();
+  }
+
+  /// hasUnparsedDefaultArg - Determines whether this parameter has a
+  /// default argument that has not yet been parsed. This will occur
+  /// during the processing of a C++ class whose member functions have
+  /// default arguments, e.g.,
+  /// @code
+  ///   class X {
+  ///   public:
+  ///     void f(int x = 17); // x has an unparsed default argument now
+  ///   }; // x has a regular default argument now
+  /// @endcode
+  bool hasUnparsedDefaultArg() const {
+    return Init.is<UnparsedDefaultArgument*>();
+  }
+
+  bool hasUninstantiatedDefaultArg() const {
+    return Init.is<UninstantiatedDefaultArgument*>();
+  }
+
+  /// setUnparsedDefaultArg - Specify that this parameter has an
+  /// unparsed default argument. The argument will be replaced with a
+  /// real default argument via setDefaultArg when the class
+  /// definition enclosing the function declaration that owns this
+  /// default argument is completed.
+  void setUnparsedDefaultArg() {
+    Init = (UnparsedDefaultArgument *)0;
+  }
+
+  bool hasInheritedDefaultArg() const {
+    return HasInheritedDefaultArg;
+  }
+
+  void setHasInheritedDefaultArg(bool I = true) {
+    HasInheritedDefaultArg = I;
+  }
+
+  QualType getOriginalType() const {
+    if (getTypeSourceInfo())
+      return getTypeSourceInfo()->getType();
+    return getType();
+  }
+
+  /// setOwningFunction - Sets the function declaration that owns this
+  /// ParmVarDecl. Since ParmVarDecls are often created before the
+  /// FunctionDecls that own them, this routine is required to update
+  /// the DeclContext appropriately.
+  void setOwningFunction(DeclContext *FD) { setDeclContext(FD); }
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classof(const ParmVarDecl *D) { return true; }
+  static bool classofKind(Kind K) { return K == ParmVar; }
+};
+
+/// FunctionDecl - An instance of this class is created to represent a
+/// function declaration or definition.
+///
+/// Since a given function can be declared several times in a program,
+/// there may be several FunctionDecls that correspond to that
+/// function. Only one of those FunctionDecls will be found when
+/// traversing the list of declarations in the context of the
+/// FunctionDecl (e.g., the translation unit); this FunctionDecl
+/// contains all of the information known about the function. Other,
+/// previous declarations of the function are available via the
+/// getPreviousDeclaration() chain.
+class FunctionDecl : public DeclaratorDecl, public DeclContext,
+                     public Redeclarable<FunctionDecl> {
+public:
+  enum StorageClass {
+    None, Extern, Static, PrivateExtern
+  };
+
+private:
+  /// ParamInfo - new[]'d array of pointers to VarDecls for the formal
+  /// parameters of this function.  This is null if a prototype or if there are
+  /// no formals.
+  ParmVarDecl **ParamInfo;
+
+  LazyDeclStmtPtr Body;
+
+  // FIXME: This can be packed into the bitfields in Decl.
+  // NOTE: VC++ treats enums as signed, avoid using the StorageClass enum
+  unsigned SClass : 2;
+  unsigned SClassAsWritten : 2;
+  bool IsInline : 1;
+  bool IsVirtualAsWritten : 1;
+  bool IsPure : 1;
+  bool HasInheritedPrototype : 1;
+  bool HasWrittenPrototype : 1;
+  bool IsDeleted : 1;
+  bool IsTrivial : 1; // sunk from CXXMethodDecl
+  bool IsCopyAssignment : 1;  // sunk from CXXMethodDecl
+  bool HasImplicitReturnZero : 1;
+
+  /// \brief End part of this FunctionDecl's source range.
+  ///
+  /// We could compute the full range in getSourceRange(). However, when we're
+  /// dealing with a function definition deserialized from a PCH/AST file,
+  /// we can only compute the full range once the function body has been
+  /// de-serialized, so it's far better to have the (sometimes-redundant)
+  /// EndRangeLoc.
+  SourceLocation EndRangeLoc;
+
+  /// \brief The template or declaration that this declaration
+  /// describes or was instantiated from, respectively.
+  ///
+  /// For non-templates, this value will be NULL. For function
+  /// declarations that describe a function template, this will be a
+  /// pointer to a FunctionTemplateDecl. For member functions
+  /// of class template specializations, this will be a MemberSpecializationInfo
+  /// pointer containing information about the specialization.
+  /// For function template specializations, this will be a
+  /// FunctionTemplateSpecializationInfo, which contains information about
+  /// the template being specialized and the template arguments involved in
+  /// that specialization.
+  llvm::PointerUnion4<FunctionTemplateDecl *, 
+                      MemberSpecializationInfo *,
+                      FunctionTemplateSpecializationInfo *,
+                      DependentFunctionTemplateSpecializationInfo *>
+    TemplateOrSpecialization;
+
+protected:
+  FunctionDecl(Kind DK, DeclContext *DC, SourceLocation L,
+               DeclarationName N, QualType T, TypeSourceInfo *TInfo,
+               StorageClass S, StorageClass SCAsWritten, bool isInline)
+    : DeclaratorDecl(DK, DC, L, N, T, TInfo),
+      DeclContext(DK),
+      ParamInfo(0), Body(),
+      SClass(S), SClassAsWritten(SCAsWritten), IsInline(isInline),
+      IsVirtualAsWritten(false), IsPure(false), HasInheritedPrototype(false),
+      HasWrittenPrototype(true), IsDeleted(false), IsTrivial(false),
+      IsCopyAssignment(false),
+      HasImplicitReturnZero(false),
+      EndRangeLoc(L), TemplateOrSpecialization() {}
+
+  virtual ~FunctionDecl() {}
+  virtual void Destroy(ASTContext& C);
+
+  typedef Redeclarable<FunctionDecl> redeclarable_base;
+  virtual FunctionDecl *getNextRedeclaration() { return RedeclLink.getNext(); }
+
+public:
+  typedef redeclarable_base::redecl_iterator redecl_iterator;
+  redecl_iterator redecls_begin() const {
+    return redeclarable_base::redecls_begin();
+  }
+  redecl_iterator redecls_end() const {
+    return redeclarable_base::redecls_end();
+  }
+
+  static FunctionDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L,
+                              DeclarationName N, QualType T,
+                              TypeSourceInfo *TInfo,
+                              StorageClass S = None,
+                              StorageClass SCAsWritten = None,
+                              bool isInline = false,
+                              bool hasWrittenPrototype = true);
+
+  virtual void getNameForDiagnostic(std::string &S,
+                                    const PrintingPolicy &Policy,
+                                    bool Qualified) const;
+
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(getLocation(), EndRangeLoc);
+  }
+  void setLocEnd(SourceLocation E) {
+    EndRangeLoc = E;
+  }
+
+  /// getBody - Retrieve the body (definition) of the function. The
+  /// function body might be in any of the (re-)declarations of this
+  /// function. The variant that accepts a FunctionDecl pointer will
+  /// set that function declaration to the actual declaration
+  /// containing the body (if there is one).
+  Stmt *getBody(const FunctionDecl *&Definition) const;
+
+  virtual Stmt *getBody() const {
+    const FunctionDecl* Definition;
+    return getBody(Definition);
+  }
+
+  /// isThisDeclarationADefinition - Returns whether this specific
+  /// declaration of the function is also a definition. This does not
+  /// determine whether the function has been defined (e.g., in a
+  /// previous definition); for that information, use getBody.
+  /// FIXME: Should return true if function is deleted or defaulted. However,
+  /// CodeGenModule.cpp uses it, and I don't know if this would break it.
+  bool isThisDeclarationADefinition() const { return Body; }
+
+  void setBody(Stmt *B);
+  void setLazyBody(uint64_t Offset) { Body = Offset; }
+
+  /// Whether this function is marked as virtual explicitly.
+  bool isVirtualAsWritten() const { return IsVirtualAsWritten; }
+  void setVirtualAsWritten(bool V) { IsVirtualAsWritten = V; }
+
+  /// Whether this virtual function is pure, i.e. makes the containing class
+  /// abstract.
+  bool isPure() const { return IsPure; }
+  void setPure(bool P = true) { IsPure = P; }
+
+  /// Whether this function is "trivial" in some specialized C++ senses.
+  /// Can only be true for default constructors, copy constructors,
+  /// copy assignment operators, and destructors.  Not meaningful until
+  /// the class has been fully built by Sema.
+  bool isTrivial() const { return IsTrivial; }
+  void setTrivial(bool IT) { IsTrivial = IT; }
+
+  bool isCopyAssignment() const { return IsCopyAssignment; }
+  void setCopyAssignment(bool CA) { IsCopyAssignment = CA; }
+
+  /// Whether falling off this function implicitly returns null/zero.
+  /// If a more specific implicit return value is required, front-ends
+  /// should synthesize the appropriate return statements.
+  bool hasImplicitReturnZero() const { return HasImplicitReturnZero; }
+  void setHasImplicitReturnZero(bool IRZ) { HasImplicitReturnZero = IRZ; }
+
+  /// \brief Whether this function has a prototype, either because one
+  /// was explicitly written or because it was "inherited" by merging
+  /// a declaration without a prototype with a declaration that has a
+  /// prototype.
+  bool hasPrototype() const {
+    return HasWrittenPrototype || HasInheritedPrototype;
+  }
+
+  bool hasWrittenPrototype() const { return HasWrittenPrototype; }
+  void setHasWrittenPrototype(bool P) { HasWrittenPrototype = P; }
+
+  /// \brief Whether this function inherited its prototype from a
+  /// previous declaration.
+  bool hasInheritedPrototype() const { return HasInheritedPrototype; }
+  void setHasInheritedPrototype(bool P = true) { HasInheritedPrototype = P; }
+
+  /// \brief Whether this function has been deleted.
+  ///
+  /// A function that is "deleted" (via the C++0x "= delete" syntax)
+  /// acts like a normal function, except that it cannot actually be
+  /// called or have its address taken. Deleted functions are
+  /// typically used in C++ overload resolution to attract arguments
+  /// whose type or lvalue/rvalue-ness would permit the use of a
+  /// different overload that would behave incorrectly. For example,
+  /// one might use deleted functions to ban implicit conversion from
+  /// a floating-point number to an Integer type:
+  ///
+  /// @code
+  /// struct Integer {
+  ///   Integer(long); // construct from a long
+  ///   Integer(double) = delete; // no construction from float or double
+  ///   Integer(long double) = delete; // no construction from long double
+  /// };
+  /// @endcode
+  bool isDeleted() const { return IsDeleted; }
+  void setDeleted(bool D = true) { IsDeleted = D; }
+
+  /// \brief Determines whether this is a function "main", which is
+  /// the entry point into an executable program.
+  bool isMain() const;
+
+  /// \brief Determines whether this function is a function with
+  /// external, C linkage.
+  bool isExternC() const;
+
+  /// \brief Determines whether this is a global function.
+  bool isGlobal() const;
+
+  void setPreviousDeclaration(FunctionDecl * PrevDecl);
+
+  virtual const FunctionDecl *getCanonicalDecl() const;
+  virtual FunctionDecl *getCanonicalDecl();
+
+  unsigned getBuiltinID() const;
+
+  // Iterator access to formal parameters.
+  unsigned param_size() const { return getNumParams(); }
+  typedef ParmVarDecl **param_iterator;
+  typedef ParmVarDecl * const *param_const_iterator;
+
+  param_iterator param_begin() { return ParamInfo; }
+  param_iterator param_end()   { return ParamInfo+param_size(); }
+
+  param_const_iterator param_begin() const { return ParamInfo; }
+  param_const_iterator param_end() const   { return ParamInfo+param_size(); }
+
+  /// getNumParams - Return the number of parameters this function must have
+  /// based on its FunctionType.  This is the length of the ParamInfo array
+  /// after it has been created.
+  unsigned getNumParams() const;
+
+  const ParmVarDecl *getParamDecl(unsigned i) const {
+    assert(i < getNumParams() && "Illegal param #");
+    return ParamInfo[i];
+  }
+  ParmVarDecl *getParamDecl(unsigned i) {
+    assert(i < getNumParams() && "Illegal param #");
+    return ParamInfo[i];
+  }
+  void setParams(ParmVarDecl **NewParamInfo, unsigned NumParams);
+
+  /// getMinRequiredArguments - Returns the minimum number of arguments
+  /// needed to call this function. This may be fewer than the number of
+  /// function parameters, if some of the parameters have default
+  /// arguments (in C++).
+  unsigned getMinRequiredArguments() const;
+
+  QualType getResultType() const {
+    return getType()->getAs<FunctionType>()->getResultType();
+  }
+  StorageClass getStorageClass() const { return StorageClass(SClass); }
+  void setStorageClass(StorageClass SC) { SClass = SC; }
+
+  StorageClass getStorageClassAsWritten() const {
+    return StorageClass(SClassAsWritten);
+  }
+  void setStorageClassAsWritten(StorageClass SC) { SClassAsWritten = SC; }
+
+  /// \brief Determine whether the "inline" keyword was specified for this
+  /// function.
+  bool isInlineSpecified() const { return IsInline; }
+                       
+  /// Set whether the "inline" keyword was specified for this function.
+  void setInlineSpecified(bool I) { IsInline = I; }
+
+  /// \brief Determine whether this function should be inlined, because it is
+  /// either marked "inline" or is a member function of a C++ class that
+  /// was defined in the class body.
+  bool isInlined() const;
+                       
+  bool isInlineDefinitionExternallyVisible() const;
+                       
+  /// isOverloadedOperator - Whether this function declaration
+  /// represents an C++ overloaded operator, e.g., "operator+".
+  bool isOverloadedOperator() const {
+    return getOverloadedOperator() != OO_None;
+  }
+
+  OverloadedOperatorKind getOverloadedOperator() const;
+
+  const IdentifierInfo *getLiteralIdentifier() const;
+
+  /// \brief If this function is an instantiation of a member function
+  /// of a class template specialization, retrieves the function from
+  /// which it was instantiated.
+  ///
+  /// This routine will return non-NULL for (non-templated) member
+  /// functions of class templates and for instantiations of function
+  /// templates. For example, given:
+  ///
+  /// \code
+  /// template<typename T>
+  /// struct X {
+  ///   void f(T);
+  /// };
+  /// \endcode
+  ///
+  /// The declaration for X<int>::f is a (non-templated) FunctionDecl
+  /// whose parent is the class template specialization X<int>. For
+  /// this declaration, getInstantiatedFromFunction() will return
+  /// the FunctionDecl X<T>::A. When a complete definition of
+  /// X<int>::A is required, it will be instantiated from the
+  /// declaration returned by getInstantiatedFromMemberFunction().
+  FunctionDecl *getInstantiatedFromMemberFunction() const;
+
+  /// \brief If this function is an instantiation of a member function of a
+  /// class template specialization, retrieves the member specialization
+  /// information.
+  MemberSpecializationInfo *getMemberSpecializationInfo() const;
+                       
+  /// \brief Specify that this record is an instantiation of the
+  /// member function FD.
+  void setInstantiationOfMemberFunction(FunctionDecl *FD,
+                                        TemplateSpecializationKind TSK);
+
+  /// \brief Retrieves the function template that is described by this
+  /// function declaration.
+  ///
+  /// Every function template is represented as a FunctionTemplateDecl
+  /// and a FunctionDecl (or something derived from FunctionDecl). The
+  /// former contains template properties (such as the template
+  /// parameter lists) while the latter contains the actual
+  /// description of the template's
+  /// contents. FunctionTemplateDecl::getTemplatedDecl() retrieves the
+  /// FunctionDecl that describes the function template,
+  /// getDescribedFunctionTemplate() retrieves the
+  /// FunctionTemplateDecl from a FunctionDecl.
+  FunctionTemplateDecl *getDescribedFunctionTemplate() const {
+    return TemplateOrSpecialization.dyn_cast<FunctionTemplateDecl*>();
+  }
+
+  void setDescribedFunctionTemplate(FunctionTemplateDecl *Template) {
+    TemplateOrSpecialization = Template;
+  }
+
+  /// \brief Determine whether this function is a function template 
+  /// specialization.
+  bool isFunctionTemplateSpecialization() const {
+    return getPrimaryTemplate() != 0;
+  }
+       
+  /// \brief If this function is actually a function template specialization,
+  /// retrieve information about this function template specialization. 
+  /// Otherwise, returns NULL.
+  FunctionTemplateSpecializationInfo *getTemplateSpecializationInfo() const {
+    return TemplateOrSpecialization.
+             dyn_cast<FunctionTemplateSpecializationInfo*>();
+  }
+
+  /// \brief Determines whether this function is a function template
+  /// specialization or a member of a class template specialization that can
+  /// be implicitly instantiated.
+  bool isImplicitlyInstantiable() const;
+              
+  /// \brief Retrieve the function declaration from which this function could
+  /// be instantiated, if it is an instantiation (rather than a non-template
+  /// or a specialization, for example).
+  FunctionDecl *getTemplateInstantiationPattern() const;
+
+  /// \brief Retrieve the primary template that this function template
+  /// specialization either specializes or was instantiated from.
+  ///
+  /// If this function declaration is not a function template specialization,
+  /// returns NULL.
+  FunctionTemplateDecl *getPrimaryTemplate() const;
+
+  /// \brief Retrieve the template arguments used to produce this function
+  /// template specialization from the primary template.
+  ///
+  /// If this function declaration is not a function template specialization,
+  /// returns NULL.
+  const TemplateArgumentList *getTemplateSpecializationArgs() const;
+
+  /// \brief Specify that this function declaration is actually a function
+  /// template specialization.
+  ///
+  /// \param Context the AST context in which this function resides.
+  ///
+  /// \param Template the function template that this function template
+  /// specialization specializes.
+  ///
+  /// \param TemplateArgs the template arguments that produced this
+  /// function template specialization from the template.
+  ///
+  /// \param InsertPos If non-NULL, the position in the function template
+  /// specialization set where the function template specialization data will
+  /// be inserted.
+  ///
+  /// \param TSK the kind of template specialization this is.
+  void setFunctionTemplateSpecialization(FunctionTemplateDecl *Template,
+                                      const TemplateArgumentList *TemplateArgs,
+                                         void *InsertPos,
+                    TemplateSpecializationKind TSK = TSK_ImplicitInstantiation);
+
+  /// \brief Specifies that this function declaration is actually a
+  /// dependent function template specialization.
+  void setDependentTemplateSpecialization(ASTContext &Context,
+                             const UnresolvedSetImpl &Templates,
+                      const TemplateArgumentListInfo &TemplateArgs);
+
+  DependentFunctionTemplateSpecializationInfo *
+  getDependentSpecializationInfo() const {
+    return TemplateOrSpecialization.
+             dyn_cast<DependentFunctionTemplateSpecializationInfo*>();
+  }
+
+  /// \brief Determine what kind of template instantiation this function
+  /// represents.
+  TemplateSpecializationKind getTemplateSpecializationKind() const;
+
+  /// \brief Determine what kind of template instantiation this function
+  /// represents.
+  void setTemplateSpecializationKind(TemplateSpecializationKind TSK,
+                        SourceLocation PointOfInstantiation = SourceLocation());
+
+  /// \brief Retrieve the (first) point of instantiation of a function template
+  /// specialization or a member of a class template specialization.
+  ///
+  /// \returns the first point of instantiation, if this function was 
+  /// instantiated from a template; otherwie, returns an invalid source 
+  /// location.
+  SourceLocation getPointOfInstantiation() const;
+                       
+  /// \brief Determine whether this is or was instantiated from an out-of-line 
+  /// definition of a member function.
+  virtual bool isOutOfLine() const;
+                       
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classof(const FunctionDecl *D) { return true; }
+  static bool classofKind(Kind K) {
+    return K >= FunctionFirst && K <= FunctionLast;
+  }
+  static DeclContext *castToDeclContext(const FunctionDecl *D) {
+    return static_cast<DeclContext *>(const_cast<FunctionDecl*>(D));
+  }
+  static FunctionDecl *castFromDeclContext(const DeclContext *DC) {
+    return static_cast<FunctionDecl *>(const_cast<DeclContext*>(DC));
+  }
+};
+
+
+/// FieldDecl - An instance of this class is created by Sema::ActOnField to
+/// represent a member of a struct/union/class.
+class FieldDecl : public DeclaratorDecl {
+  // FIXME: This can be packed into the bitfields in Decl.
+  bool Mutable : 1;
+  Expr *BitWidth;
+protected:
+  FieldDecl(Kind DK, DeclContext *DC, SourceLocation L,
+            IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
+            Expr *BW, bool Mutable)
+    : DeclaratorDecl(DK, DC, L, Id, T, TInfo), Mutable(Mutable), BitWidth(BW) {
+  }
+
+public:
+  static FieldDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L,
+                           IdentifierInfo *Id, QualType T,
+                           TypeSourceInfo *TInfo, Expr *BW, bool Mutable);
+
+  /// isMutable - Determines whether this field is mutable (C++ only).
+  bool isMutable() const { return Mutable; }
+
+  /// \brief Set whether this field is mutable (C++ only).
+  void setMutable(bool M) { Mutable = M; }
+
+  /// isBitfield - Determines whether this field is a bitfield.
+  bool isBitField() const { return BitWidth != NULL; }
+
+  /// @brief Determines whether this is an unnamed bitfield.
+  bool isUnnamedBitfield() const { return BitWidth != NULL && !getDeclName(); }
+
+  /// isAnonymousStructOrUnion - Determines whether this field is a
+  /// representative for an anonymous struct or union. Such fields are
+  /// unnamed and are implicitly generated by the implementation to
+  /// store the data for the anonymous union or struct.
+  bool isAnonymousStructOrUnion() const;
+
+  Expr *getBitWidth() const { return BitWidth; }
+  void setBitWidth(Expr *BW) { BitWidth = BW; }
+
+  /// getParent - Returns the parent of this field declaration, which
+  /// is the struct in which this method is defined.
+  const RecordDecl *getParent() const {
+    return cast<RecordDecl>(getDeclContext());
+  }
+
+  RecordDecl *getParent() {
+    return cast<RecordDecl>(getDeclContext());
+  }
+  
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classof(const FieldDecl *D) { return true; }
+  static bool classofKind(Kind K) { return K >= FieldFirst && K <= FieldLast; }
+};
+
+/// EnumConstantDecl - An instance of this object exists for each enum constant
+/// that is defined.  For example, in "enum X {a,b}", each of a/b are
+/// EnumConstantDecl's, X is an instance of EnumDecl, and the type of a/b is a
+/// TagType for the X EnumDecl.
+class EnumConstantDecl : public ValueDecl {
+  Stmt *Init; // an integer constant expression
+  llvm::APSInt Val; // The value.
+protected:
+  EnumConstantDecl(DeclContext *DC, SourceLocation L,
+                   IdentifierInfo *Id, QualType T, Expr *E,
+                   const llvm::APSInt &V)
+    : ValueDecl(EnumConstant, DC, L, Id, T), Init((Stmt*)E), Val(V) {}
+
+  virtual ~EnumConstantDecl() {}
+public:
+
+  static EnumConstantDecl *Create(ASTContext &C, EnumDecl *DC,
+                                  SourceLocation L, IdentifierInfo *Id,
+                                  QualType T, Expr *E,
+                                  const llvm::APSInt &V);
+
+  virtual void Destroy(ASTContext& C);
+
+  const Expr *getInitExpr() const { return (const Expr*) Init; }
+  Expr *getInitExpr() { return (Expr*) Init; }
+  const llvm::APSInt &getInitVal() const { return Val; }
+
+  void setInitExpr(Expr *E) { Init = (Stmt*) E; }
+  void setInitVal(const llvm::APSInt &V) { Val = V; }
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classof(const EnumConstantDecl *D) { return true; }
+  static bool classofKind(Kind K) { return K == EnumConstant; }
+
+  friend class StmtIteratorBase;
+};
+
+
+/// TypeDecl - Represents a declaration of a type.
+///
+class TypeDecl : public NamedDecl {
+  /// TypeForDecl - This indicates the Type object that represents
+  /// this TypeDecl.  It is a cache maintained by
+  /// ASTContext::getTypedefType, ASTContext::getTagDeclType, and
+  /// ASTContext::getTemplateTypeParmType, and TemplateTypeParmDecl.
+  mutable Type *TypeForDecl;
+  friend class ASTContext;
+  friend class DeclContext;
+  friend class TagDecl;
+  friend class TemplateTypeParmDecl;
+  friend class TagType;
+
+protected:
+  TypeDecl(Kind DK, DeclContext *DC, SourceLocation L,
+           IdentifierInfo *Id)
+    : NamedDecl(DK, DC, L, Id), TypeForDecl(0) {}
+
+public:
+  // Low-level accessor
+  Type *getTypeForDecl() const { return TypeForDecl; }
+  void setTypeForDecl(Type *TD) { TypeForDecl = TD; }
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classof(const TypeDecl *D) { return true; }
+  static bool classofKind(Kind K) { return K >= TypeFirst && K <= TypeLast; }
+};
+
+
+class TypedefDecl : public TypeDecl, public Redeclarable<TypedefDecl> {
+  /// UnderlyingType - This is the type the typedef is set to.
+  TypeSourceInfo *TInfo;
+
+  TypedefDecl(DeclContext *DC, SourceLocation L,
+              IdentifierInfo *Id, TypeSourceInfo *TInfo)
+    : TypeDecl(Typedef, DC, L, Id), TInfo(TInfo) {}
+
+  virtual ~TypedefDecl();
+public:
+
+  static TypedefDecl *Create(ASTContext &C, DeclContext *DC,
+                             SourceLocation L, IdentifierInfo *Id,
+                             TypeSourceInfo *TInfo);
+
+  TypeSourceInfo *getTypeSourceInfo() const {
+    return TInfo;
+  }
+
+  /// Retrieves the canonical declaration of this typedef.
+  TypedefDecl *getCanonicalDecl() {
+    return getFirstDeclaration();
+  }
+  const TypedefDecl *getCanonicalDecl() const {
+    return getFirstDeclaration();
+  }
+
+  QualType getUnderlyingType() const {
+    return TInfo->getType();
+  }
+  void setTypeSourceInfo(TypeSourceInfo *newType) {
+    TInfo = newType;
+  }
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classof(const TypedefDecl *D) { return true; }
+  static bool classofKind(Kind K) { return K == Typedef; }
+};
+
+class TypedefDecl;
+
+/// TagDecl - Represents the declaration of a struct/union/class/enum.
+class TagDecl
+  : public TypeDecl, public DeclContext, public Redeclarable<TagDecl> {
+public:
+  // This is really ugly.
+  typedef ElaboratedType::TagKind TagKind;
+  static const TagKind TK_struct = ElaboratedType::TK_struct;
+  static const TagKind TK_union = ElaboratedType::TK_union;
+  static const TagKind TK_class = ElaboratedType::TK_class;
+  static const TagKind TK_enum = ElaboratedType::TK_enum;
+
+private:
+  // FIXME: This can be packed into the bitfields in Decl.
+  /// TagDeclKind - The TagKind enum.
+  unsigned TagDeclKind : 2;
+
+  /// IsDefinition - True if this is a definition ("struct foo {};"), false if
+  /// it is a declaration ("struct foo;").
+  bool IsDefinition : 1;
+
+  /// IsEmbeddedInDeclarator - True if this tag declaration is
+  /// "embedded" (i.e., defined or declared for the very first time)
+  /// in the syntax of a declarator.
+  bool IsEmbeddedInDeclarator : 1;
+
+  SourceLocation TagKeywordLoc;
+  SourceLocation RBraceLoc;
+
+  // A struct representing syntactic qualifier info,
+  // to be used for the (uncommon) case of out-of-line declarations.
+  struct ExtInfo {
+    NestedNameSpecifier *NNS;
+    SourceRange NNSRange;
+  };
+
+  /// TypedefDeclOrQualifier - If the (out-of-line) tag declaration name
+  /// is qualified, it points to the qualifier info (nns and range);
+  /// otherwise, if the tag declaration is anonymous and it is part of
+  /// a typedef, it points to the TypedefDecl (used for mangling);
+  /// otherwise, it is a null (TypedefDecl) pointer.
+  llvm::PointerUnion<TypedefDecl*, ExtInfo*> TypedefDeclOrQualifier;
+
+  bool hasExtInfo() const { return TypedefDeclOrQualifier.is<ExtInfo*>(); }
+  ExtInfo *getExtInfo() { return TypedefDeclOrQualifier.get<ExtInfo*>(); }
+  const ExtInfo *getExtInfo() const {
+    return TypedefDeclOrQualifier.get<ExtInfo*>();
+  }
+
+protected:
+  TagDecl(Kind DK, TagKind TK, DeclContext *DC,
+          SourceLocation L, IdentifierInfo *Id,
+          TagDecl *PrevDecl, SourceLocation TKL = SourceLocation())
+    : TypeDecl(DK, DC, L, Id), DeclContext(DK), TagKeywordLoc(TKL),
+      TypedefDeclOrQualifier((TypedefDecl*) 0) {
+    assert((DK != Enum || TK == TK_enum) &&"EnumDecl not matched with TK_enum");
+    TagDeclKind = TK;
+    IsDefinition = false;
+    IsEmbeddedInDeclarator = false;
+    setPreviousDeclaration(PrevDecl);
+  }
+
+  typedef Redeclarable<TagDecl> redeclarable_base;
+  virtual TagDecl *getNextRedeclaration() { return RedeclLink.getNext(); }
+
+public:
+  void Destroy(ASTContext &C);
+
+  typedef redeclarable_base::redecl_iterator redecl_iterator;
+  redecl_iterator redecls_begin() const {
+    return redeclarable_base::redecls_begin();
+  }
+  redecl_iterator redecls_end() const {
+    return redeclarable_base::redecls_end();
+  }
+
+  SourceLocation getRBraceLoc() const { return RBraceLoc; }
+  void setRBraceLoc(SourceLocation L) { RBraceLoc = L; }
+
+  SourceLocation getTagKeywordLoc() const { return TagKeywordLoc; }
+  void setTagKeywordLoc(SourceLocation TKL) { TagKeywordLoc = TKL; }
+
+  virtual SourceRange getSourceRange() const;
+
+  virtual TagDecl* getCanonicalDecl();
+  const TagDecl* getCanonicalDecl() const {
+    return const_cast<TagDecl*>(this)->getCanonicalDecl();
+  }
+
+  /// isDefinition - Return true if this decl has its body specified.
+  bool isDefinition() const {
+    return IsDefinition;
+  }
+
+  bool isEmbeddedInDeclarator() const {
+    return IsEmbeddedInDeclarator;
+  }
+  void setEmbeddedInDeclarator(bool isInDeclarator) {
+    IsEmbeddedInDeclarator = isInDeclarator;
+  }
+
+  /// \brief Whether this declaration declares a type that is
+  /// dependent, i.e., a type that somehow depends on template
+  /// parameters.
+  bool isDependentType() const { return isDependentContext(); }
+
+  /// @brief Starts the definition of this tag declaration.
+  ///
+  /// This method should be invoked at the beginning of the definition
+  /// of this tag declaration. It will set the tag type into a state
+  /// where it is in the process of being defined.
+  void startDefinition();
+
+  /// @brief Completes the definition of this tag declaration.
+  void completeDefinition();
+
+  /// getDefinition - Returns the TagDecl that actually defines this
+  ///  struct/union/class/enum.  When determining whether or not a
+  ///  struct/union/class/enum is completely defined, one should use this method
+  ///  as opposed to 'isDefinition'.  'isDefinition' indicates whether or not a
+  ///  specific TagDecl is defining declaration, not whether or not the
+  ///  struct/union/class/enum type is defined.  This method returns NULL if
+  ///  there is no TagDecl that defines the struct/union/class/enum.
+  TagDecl* getDefinition() const;
+
+  void setDefinition(bool V) { IsDefinition = V; }
+
+  const char *getKindName() const {
+    return ElaboratedType::getNameForTagKind(getTagKind());
+  }
+
+  /// getTagKindForTypeSpec - Converts a type specifier (DeclSpec::TST)
+  /// into a tag kind.  It is an error to provide a type specifier
+  /// which *isn't* a tag kind here.
+  static TagKind getTagKindForTypeSpec(unsigned TypeSpec);
+
+  TagKind getTagKind() const {
+    return TagKind(TagDeclKind);
+  }
+
+  void setTagKind(TagKind TK) { TagDeclKind = TK; }
+
+  bool isStruct() const { return getTagKind() == TK_struct; }
+  bool isClass()  const { return getTagKind() == TK_class; }
+  bool isUnion()  const { return getTagKind() == TK_union; }
+  bool isEnum()   const { return getTagKind() == TK_enum; }
+
+  TypedefDecl *getTypedefForAnonDecl() const {
+    return hasExtInfo() ? 0 : TypedefDeclOrQualifier.get<TypedefDecl*>();
+  }
+  void setTypedefForAnonDecl(TypedefDecl *TDD) { TypedefDeclOrQualifier = TDD; }
+
+  NestedNameSpecifier *getQualifier() const {
+    return hasExtInfo() ? TypedefDeclOrQualifier.get<ExtInfo*>()->NNS : 0;
+  }
+  SourceRange getQualifierRange() const {
+    return hasExtInfo()
+      ? TypedefDeclOrQualifier.get<ExtInfo*>()->NNSRange
+      : SourceRange();
+  }
+  void setQualifierInfo(NestedNameSpecifier *Qualifier,
+                        SourceRange QualifierRange);
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classof(const TagDecl *D) { return true; }
+  static bool classofKind(Kind K) { return K >= TagFirst && K <= TagLast; }
+
+  static DeclContext *castToDeclContext(const TagDecl *D) {
+    return static_cast<DeclContext *>(const_cast<TagDecl*>(D));
+  }
+  static TagDecl *castFromDeclContext(const DeclContext *DC) {
+    return static_cast<TagDecl *>(const_cast<DeclContext*>(DC));
+  }
+};
+
+/// EnumDecl - Represents an enum.  As an extension, we allow forward-declared
+/// enums.
+class EnumDecl : public TagDecl {
+  /// IntegerType - This represent the integer type that the enum corresponds
+  /// to for code generation purposes.  Note that the enumerator constants may
+  /// have a different type than this does.
+  QualType IntegerType;
+
+  /// PromotionType - The integer type that values of this type should
+  /// promote to.  In C, enumerators are generally of an integer type
+  /// directly, but gcc-style large enumerators (and all enumerators
+  /// in C++) are of the enum type instead.
+  QualType PromotionType;
+
+  /// \brief If the enumeration was instantiated from an enumeration
+  /// within a class or function template, this pointer refers to the
+  /// enumeration declared within the template.
+  EnumDecl *InstantiatedFrom;
+
+  EnumDecl(DeclContext *DC, SourceLocation L,
+           IdentifierInfo *Id, EnumDecl *PrevDecl, SourceLocation TKL)
+    : TagDecl(Enum, TK_enum, DC, L, Id, PrevDecl, TKL), InstantiatedFrom(0) {
+      IntegerType = QualType();
+    }
+public:
+  EnumDecl *getCanonicalDecl() {
+    return cast<EnumDecl>(TagDecl::getCanonicalDecl());
+  }
+  const EnumDecl *getCanonicalDecl() const {
+    return cast<EnumDecl>(TagDecl::getCanonicalDecl());
+  }
+
+  static EnumDecl *Create(ASTContext &C, DeclContext *DC,
+                          SourceLocation L, IdentifierInfo *Id,
+                          SourceLocation TKL, EnumDecl *PrevDecl);
+
+  virtual void Destroy(ASTContext& C);
+
+  /// completeDefinition - When created, the EnumDecl corresponds to a
+  /// forward-declared enum. This method is used to mark the
+  /// declaration as being defined; it's enumerators have already been
+  /// added (via DeclContext::addDecl). NewType is the new underlying
+  /// type of the enumeration type.
+  void completeDefinition(QualType NewType,
+                          QualType PromotionType);
+
+  // enumerator_iterator - Iterates through the enumerators of this
+  // enumeration.
+  typedef specific_decl_iterator<EnumConstantDecl> enumerator_iterator;
+
+  enumerator_iterator enumerator_begin() const {
+    return enumerator_iterator(this->decls_begin());
+  }
+
+  enumerator_iterator enumerator_end() const {
+    return enumerator_iterator(this->decls_end());
+  }
+
+  /// getPromotionType - Return the integer type that enumerators
+  /// should promote to.
+  QualType getPromotionType() const { return PromotionType; }
+
+  /// \brief Set the promotion type.
+  void setPromotionType(QualType T) { PromotionType = T; }
+
+  /// getIntegerType - Return the integer type this enum decl corresponds to.
+  /// This returns a null qualtype for an enum forward definition.
+  QualType getIntegerType() const { return IntegerType; }
+
+  /// \brief Set the underlying integer type.
+  void setIntegerType(QualType T) { IntegerType = T; }
+
+  /// \brief Returns the enumeration (declared within the template)
+  /// from which this enumeration type was instantiated, or NULL if
+  /// this enumeration was not instantiated from any template.
+  EnumDecl *getInstantiatedFromMemberEnum() const {
+    return InstantiatedFrom;
+  }
+
+  void setInstantiationOfMemberEnum(EnumDecl *IF) { InstantiatedFrom = IF; }
+
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classof(const EnumDecl *D) { return true; }
+  static bool classofKind(Kind K) { return K == Enum; }
+};
+
+
+/// RecordDecl - Represents a struct/union/class.  For example:
+///   struct X;                  // Forward declaration, no "body".
+///   union Y { int A, B; };     // Has body with members A and B (FieldDecls).
+/// This decl will be marked invalid if *any* members are invalid.
+///
+class RecordDecl : public TagDecl {
+  // FIXME: This can be packed into the bitfields in Decl.
+  /// HasFlexibleArrayMember - This is true if this struct ends with a flexible
+  /// array member (e.g. int X[]) or if this union contains a struct that does.
+  /// If so, this cannot be contained in arrays or other structs as a member.
+  bool HasFlexibleArrayMember : 1;
+
+  /// AnonymousStructOrUnion - Whether this is the type of an anonymous struct
+  /// or union.
+  bool AnonymousStructOrUnion : 1;
+
+  /// HasObjectMember - This is true if this struct has at least one member
+  /// containing an object.
+  bool HasObjectMember : 1;
+
+protected:
+  RecordDecl(Kind DK, TagKind TK, DeclContext *DC,
+             SourceLocation L, IdentifierInfo *Id,
+             RecordDecl *PrevDecl, SourceLocation TKL);
+  virtual ~RecordDecl();
+
+public:
+  static RecordDecl *Create(ASTContext &C, TagKind TK, DeclContext *DC,
+                            SourceLocation L, IdentifierInfo *Id,
+                            SourceLocation TKL = SourceLocation(),
+                            RecordDecl* PrevDecl = 0);
+
+  virtual void Destroy(ASTContext& C);
+
+  bool hasFlexibleArrayMember() const { return HasFlexibleArrayMember; }
+  void setHasFlexibleArrayMember(bool V) { HasFlexibleArrayMember = V; }
+
+  /// isAnonymousStructOrUnion - Whether this is an anonymous struct
+  /// or union. To be an anonymous struct or union, it must have been
+  /// declared without a name and there must be no objects of this
+  /// type declared, e.g.,
+  /// @code
+  ///   union { int i; float f; };
+  /// @endcode
+  /// is an anonymous union but neither of the following are:
+  /// @code
+  ///  union X { int i; float f; };
+  ///  union { int i; float f; } obj;
+  /// @endcode
+  bool isAnonymousStructOrUnion() const { return AnonymousStructOrUnion; }
+  void setAnonymousStructOrUnion(bool Anon) {
+    AnonymousStructOrUnion = Anon;
+  }
+
+  bool hasObjectMember() const { return HasObjectMember; }
+  void setHasObjectMember (bool val) { HasObjectMember = val; }
+
+  /// \brief Determines whether this declaration represents the
+  /// injected class name.
+  ///
+  /// The injected class name in C++ is the name of the class that
+  /// appears inside the class itself. For example:
+  ///
+  /// \code
+  /// struct C {
+  ///   // C is implicitly declared here as a synonym for the class name.
+  /// };
+  ///
+  /// C::C c; // same as "C c;"
+  /// \endcode
+  bool isInjectedClassName() const;
+
+  /// getDefinition - Returns the RecordDecl that actually defines this
+  ///  struct/union/class.  When determining whether or not a struct/union/class
+  ///  is completely defined, one should use this method as opposed to
+  ///  'isDefinition'.  'isDefinition' indicates whether or not a specific
+  ///  RecordDecl is defining declaration, not whether or not the record
+  ///  type is defined.  This method returns NULL if there is no RecordDecl
+  ///  that defines the struct/union/tag.
+  RecordDecl* getDefinition() const {
+    return cast_or_null<RecordDecl>(TagDecl::getDefinition());
+  }
+
+  // Iterator access to field members. The field iterator only visits
+  // the non-static data members of this class, ignoring any static
+  // data members, functions, constructors, destructors, etc.
+  typedef specific_decl_iterator<FieldDecl> field_iterator;
+
+  field_iterator field_begin() const {
+    return field_iterator(decls_begin());
+  }
+  field_iterator field_end() const {
+    return field_iterator(decls_end());
+  }
+
+  // field_empty - Whether there are any fields (non-static data
+  // members) in this record.
+  bool field_empty() const {
+    return field_begin() == field_end();
+  }
+
+  /// completeDefinition - Notes that the definition of this type is
+  /// now complete.
+  void completeDefinition();
+
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classof(const RecordDecl *D) { return true; }
+  static bool classofKind(Kind K) {
+    return K >= RecordFirst && K <= RecordLast;
+  }
+};
+
+class FileScopeAsmDecl : public Decl {
+  StringLiteral *AsmString;
+  FileScopeAsmDecl(DeclContext *DC, SourceLocation L, StringLiteral *asmstring)
+    : Decl(FileScopeAsm, DC, L), AsmString(asmstring) {}
+public:
+  static FileScopeAsmDecl *Create(ASTContext &C, DeclContext *DC,
+                                  SourceLocation L, StringLiteral *Str);
+
+  const StringLiteral *getAsmString() const { return AsmString; }
+  StringLiteral *getAsmString() { return AsmString; }
+  void setAsmString(StringLiteral *Asm) { AsmString = Asm; }
+
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classof(const FileScopeAsmDecl *D) { return true; }
+  static bool classofKind(Kind K) { return K == FileScopeAsm; }
+};
+
+/// BlockDecl - This represents a block literal declaration, which is like an
+/// unnamed FunctionDecl.  For example:
+/// ^{ statement-body }   or   ^(int arg1, float arg2){ statement-body }
+///
+class BlockDecl : public Decl, public DeclContext {
+  // FIXME: This can be packed into the bitfields in Decl.
+  bool isVariadic : 1;
+  /// ParamInfo - new[]'d array of pointers to ParmVarDecls for the formal
+  /// parameters of this function.  This is null if a prototype or if there are
+  /// no formals.
+  ParmVarDecl **ParamInfo;
+  unsigned NumParams;
+
+  Stmt *Body;
+
+protected:
+  BlockDecl(DeclContext *DC, SourceLocation CaretLoc)
+    : Decl(Block, DC, CaretLoc), DeclContext(Block),
+      isVariadic(false), ParamInfo(0), NumParams(0), Body(0) {}
+
+  virtual ~BlockDecl();
+  virtual void Destroy(ASTContext& C);
+
+public:
+  static BlockDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L);
+
+  SourceLocation getCaretLocation() const { return getLocation(); }
+
+  bool IsVariadic() const { return isVariadic; }
+  void setIsVariadic(bool value) { isVariadic = value; }
+
+  CompoundStmt *getCompoundBody() const { return (CompoundStmt*) Body; }
+  Stmt *getBody() const { return (Stmt*) Body; }
+  void setBody(CompoundStmt *B) { Body = (Stmt*) B; }
+
+  // Iterator access to formal parameters.
+  unsigned param_size() const { return getNumParams(); }
+  typedef ParmVarDecl **param_iterator;
+  typedef ParmVarDecl * const *param_const_iterator;
+
+  bool param_empty() const { return NumParams == 0; }
+  param_iterator param_begin()  { return ParamInfo; }
+  param_iterator param_end()   { return ParamInfo+param_size(); }
+
+  param_const_iterator param_begin() const { return ParamInfo; }
+  param_const_iterator param_end() const   { return ParamInfo+param_size(); }
+
+  unsigned getNumParams() const;
+  const ParmVarDecl *getParamDecl(unsigned i) const {
+    assert(i < getNumParams() && "Illegal param #");
+    return ParamInfo[i];
+  }
+  ParmVarDecl *getParamDecl(unsigned i) {
+    assert(i < getNumParams() && "Illegal param #");
+    return ParamInfo[i];
+  }
+  void setParams(ParmVarDecl **NewParamInfo, unsigned NumParams);
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classof(const BlockDecl *D) { return true; }
+  static bool classofKind(Kind K) { return K == Block; }
+  static DeclContext *castToDeclContext(const BlockDecl *D) {
+    return static_cast<DeclContext *>(const_cast<BlockDecl*>(D));
+  }
+  static BlockDecl *castFromDeclContext(const DeclContext *DC) {
+    return static_cast<BlockDecl *>(const_cast<DeclContext*>(DC));
+  }
+};
+
+/// Insertion operator for diagnostics.  This allows sending NamedDecl's
+/// into a diagnostic with <<.
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+                                           NamedDecl* ND) {
+  DB.AddTaggedVal(reinterpret_cast<intptr_t>(ND), Diagnostic::ak_nameddecl);
+  return DB;
+}
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/AST/DeclAccessPair.h b/include/clang/AST/DeclAccessPair.h
new file mode 100644
index 0000000..7ecd8f8
--- /dev/null
+++ b/include/clang/AST/DeclAccessPair.h
@@ -0,0 +1,72 @@
+//===--- DeclAccessPair.h - A decl bundled with its path access -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the DeclAccessPair class, which provides an
+//  efficient representation of a pair of a NamedDecl* and an
+//  AccessSpecifier.  Generally the access specifier gives the
+//  natural access of a declaration when named in a class, as
+//  defined in C++ [class.access.base]p1.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_DECLACCESSPAIR_H
+#define LLVM_CLANG_AST_DECLACCESSPAIR_H
+
+#include "clang/Basic/Specifiers.h"
+
+namespace clang {
+
+class NamedDecl;
+
+/// A POD class for pairing a NamedDecl* with an access specifier.
+/// Can be put into unions.
+class DeclAccessPair {
+  NamedDecl *Ptr; // we'd use llvm::PointerUnion, but it isn't trivial
+
+  enum { Mask = 0x3 };
+
+public:
+  static DeclAccessPair make(NamedDecl *D, AccessSpecifier AS) {
+    DeclAccessPair p;
+    p.set(D, AS);
+    return p;
+  }
+
+  NamedDecl *getDecl() const {
+    return (NamedDecl*) (~Mask & (uintptr_t) Ptr);
+  }
+  AccessSpecifier getAccess() const {
+    return AccessSpecifier(Mask & (uintptr_t) Ptr);
+  }
+
+  void setDecl(NamedDecl *D) {
+    set(D, getAccess());
+  }
+  void setAccess(AccessSpecifier AS) {
+    set(getDecl(), AS);
+  }
+  void set(NamedDecl *D, AccessSpecifier AS) {
+    Ptr = reinterpret_cast<NamedDecl*>(uintptr_t(AS) |
+                                       reinterpret_cast<uintptr_t>(D));
+  }
+
+  operator NamedDecl*() const { return getDecl(); }
+  NamedDecl *operator->() const { return getDecl(); }
+};
+}
+
+// Take a moment to tell SmallVector that DeclAccessPair is POD.
+namespace llvm {
+template<typename> struct isPodLike;
+template<> struct isPodLike<clang::DeclAccessPair> {
+   static const bool value = true;
+};
+}
+
+#endif
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
new file mode 100644
index 0000000..a9b948e
--- /dev/null
+++ b/include/clang/AST/DeclBase.h
@@ -0,0 +1,1206 @@
+//===-- DeclBase.h - Base Classes for representing declarations -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the Decl and DeclContext interfaces.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_DECLBASE_H
+#define LLVM_CLANG_AST_DECLBASE_H
+
+#include "clang/AST/Attr.h"
+#include "clang/AST/Type.h"
+#include "clang/Basic/Specifiers.h"
+#include "llvm/Support/PrettyStackTrace.h"
+#include "llvm/ADT/PointerUnion.h"
+
+namespace clang {
+class DeclContext;
+class TranslationUnitDecl;
+class NamespaceDecl;
+class UsingDirectiveDecl;
+class NamedDecl;
+class FunctionDecl;
+class CXXRecordDecl;
+class EnumDecl;
+class ObjCMethodDecl;
+class ObjCContainerDecl;
+class ObjCInterfaceDecl;
+class ObjCCategoryDecl;
+class ObjCProtocolDecl;
+class ObjCImplementationDecl;
+class ObjCCategoryImplDecl;
+class ObjCImplDecl;
+class LinkageSpecDecl;
+class BlockDecl;
+class DeclarationName;
+class CompoundStmt;
+class StoredDeclsMap;
+class DependentDiagnostic;
+}
+
+namespace llvm {
+// DeclContext* is only 4-byte aligned on 32-bit systems.
+template<>
+  class PointerLikeTypeTraits<clang::DeclContext*> {
+  typedef clang::DeclContext* PT;
+public:
+  static inline void *getAsVoidPointer(PT P) { return P; }
+  static inline PT getFromVoidPointer(void *P) {
+    return static_cast<PT>(P);
+  }
+  enum { NumLowBitsAvailable = 2 };
+};
+}
+
+namespace clang {
+
+/// Decl - This represents one declaration (or definition), e.g. a variable,
+/// typedef, function, struct, etc.
+///
+class Decl {
+public:
+  /// \brief Lists the kind of concrete classes of Decl.
+  enum Kind {
+#define DECL(Derived, Base) Derived,
+#define DECL_RANGE(CommonBase, Start, End) \
+    CommonBase##First = Start, CommonBase##Last = End,
+#define LAST_DECL_RANGE(CommonBase, Start, End) \
+    CommonBase##First = Start, CommonBase##Last = End
+#include "clang/AST/DeclNodes.def"
+  };
+
+  /// IdentifierNamespace - The different namespaces in which
+  /// declarations may appear.  According to C99 6.2.3, there are
+  /// four namespaces, labels, tags, members and ordinary
+  /// identifiers.  C++ describes lookup completely differently:
+  /// certain lookups merely "ignore" certain kinds of declarations,
+  /// usually based on whether the declaration is of a type, etc.
+  /// 
+  /// These are meant as bitmasks, so that searches in
+  /// C++ can look into the "tag" namespace during ordinary lookup.
+  ///
+  /// Decl currently provides 16 bits of IDNS bits.
+  enum IdentifierNamespace {
+    /// Labels, declared with 'x:' and referenced with 'goto x'.
+    IDNS_Label               = 0x0001,
+
+    /// Tags, declared with 'struct foo;' and referenced with
+    /// 'struct foo'.  All tags are also types.  This is what
+    /// elaborated-type-specifiers look for in C.
+    IDNS_Tag                 = 0x0002,
+
+    /// Types, declared with 'struct foo', typedefs, etc.
+    /// This is what elaborated-type-specifiers look for in C++,
+    /// but note that it's ill-formed to find a non-tag.
+    IDNS_Type                = 0x0004,
+
+    /// Members, declared with object declarations within tag
+    /// definitions.  In C, these can only be found by "qualified"
+    /// lookup in member expressions.  In C++, they're found by
+    /// normal lookup.
+    IDNS_Member              = 0x0008,
+
+    /// Namespaces, declared with 'namespace foo {}'.
+    /// Lookup for nested-name-specifiers find these.
+    IDNS_Namespace           = 0x0010,
+
+    /// Ordinary names.  In C, everything that's not a label, tag,
+    /// or member ends up here.
+    IDNS_Ordinary            = 0x0020,
+
+    /// Objective C @protocol.
+    IDNS_ObjCProtocol        = 0x0040,
+
+    /// This declaration is a friend function.  A friend function
+    /// declaration is always in this namespace but may also be in
+    /// IDNS_Ordinary if it was previously declared.
+    IDNS_OrdinaryFriend      = 0x0080,
+
+    /// This declaration is a friend class.  A friend class
+    /// declaration is always in this namespace but may also be in
+    /// IDNS_Tag|IDNS_Type if it was previously declared.
+    IDNS_TagFriend           = 0x0100,
+
+    /// This declaration is a using declaration.  A using declaration
+    /// *introduces* a number of other declarations into the current
+    /// scope, and those declarations use the IDNS of their targets,
+    /// but the actual using declarations go in this namespace.
+    IDNS_Using               = 0x0200,
+
+    /// This declaration is a C++ operator declared in a non-class
+    /// context.  All such operators are also in IDNS_Ordinary.
+    /// C++ lexical operator lookup looks for these.
+    IDNS_NonMemberOperator   = 0x0400
+  };
+
+  /// ObjCDeclQualifier - Qualifier used on types in method declarations
+  /// for remote messaging. They are meant for the arguments though and
+  /// applied to the Decls (ObjCMethodDecl and ParmVarDecl).
+  enum ObjCDeclQualifier {
+    OBJC_TQ_None = 0x0,
+    OBJC_TQ_In = 0x1,
+    OBJC_TQ_Inout = 0x2,
+    OBJC_TQ_Out = 0x4,
+    OBJC_TQ_Bycopy = 0x8,
+    OBJC_TQ_Byref = 0x10,
+    OBJC_TQ_Oneway = 0x20
+  };
+
+private:
+  /// NextDeclInContext - The next declaration within the same lexical
+  /// DeclContext. These pointers form the linked list that is
+  /// traversed via DeclContext's decls_begin()/decls_end().
+  Decl *NextDeclInContext;
+
+  friend class DeclContext;
+
+  struct MultipleDC {
+    DeclContext *SemanticDC;
+    DeclContext *LexicalDC;
+  };
+
+
+  /// DeclCtx - Holds either a DeclContext* or a MultipleDC*.
+  /// For declarations that don't contain C++ scope specifiers, it contains
+  /// the DeclContext where the Decl was declared.
+  /// For declarations with C++ scope specifiers, it contains a MultipleDC*
+  /// with the context where it semantically belongs (SemanticDC) and the
+  /// context where it was lexically declared (LexicalDC).
+  /// e.g.:
+  ///
+  ///   namespace A {
+  ///      void f(); // SemanticDC == LexicalDC == 'namespace A'
+  ///   }
+  ///   void A::f(); // SemanticDC == namespace 'A'
+  ///                // LexicalDC == global namespace
+  llvm::PointerUnion<DeclContext*, MultipleDC*> DeclCtx;
+
+  inline bool isInSemaDC() const    { return DeclCtx.is<DeclContext*>(); }
+  inline bool isOutOfSemaDC() const { return DeclCtx.is<MultipleDC*>(); }
+  inline MultipleDC *getMultipleDC() const {
+    return DeclCtx.get<MultipleDC*>();
+  }
+  inline DeclContext *getSemanticDC() const {
+    return DeclCtx.get<DeclContext*>();
+  }
+
+  /// Loc - The location that this decl.
+  SourceLocation Loc;
+
+  /// DeclKind - This indicates which class this is.
+  Kind DeclKind   :  8;
+
+  /// InvalidDecl - This indicates a semantic error occurred.
+  unsigned int InvalidDecl :  1;
+
+  /// HasAttrs - This indicates whether the decl has attributes or not.
+  unsigned int HasAttrs : 1;
+
+  /// Implicit - Whether this declaration was implicitly generated by
+  /// the implementation rather than explicitly written by the user.
+  bool Implicit : 1;
+
+  /// \brief Whether this declaration was "used", meaning that a definition is
+  /// required.
+  bool Used : 1;
+
+protected:
+  /// Access - Used by C++ decls for the access specifier.
+  // NOTE: VC++ treats enums as signed, avoid using the AccessSpecifier enum
+  unsigned Access : 2;
+  friend class CXXClassMemberWrapper;
+  
+  // PCHLevel - the "level" of precompiled header/AST file from which this
+  // declaration was built.
+  unsigned PCHLevel : 2;
+  
+  /// IdentifierNamespace - This specifies what IDNS_* namespace this lives in.
+  unsigned IdentifierNamespace : 16;
+
+private:
+#ifndef NDEBUG
+  void CheckAccessDeclContext() const;
+#else
+  void CheckAccessDeclContext() const { }
+#endif
+
+protected:
+
+  Decl(Kind DK, DeclContext *DC, SourceLocation L)
+    : NextDeclInContext(0), DeclCtx(DC),
+      Loc(L), DeclKind(DK), InvalidDecl(0),
+      HasAttrs(false), Implicit(false), Used(false),
+      Access(AS_none), PCHLevel(0),
+      IdentifierNamespace(getIdentifierNamespaceForKind(DK)) {
+    if (Decl::CollectingStats()) addDeclKind(DK);
+  }
+
+  virtual ~Decl();
+
+public:
+
+  /// \brief Source range that this declaration covers.
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(getLocation(), getLocation());
+  }
+  SourceLocation getLocStart() const { return getSourceRange().getBegin(); }
+  SourceLocation getLocEnd() const { return getSourceRange().getEnd(); }
+
+  SourceLocation getLocation() const { return Loc; }
+  void setLocation(SourceLocation L) { Loc = L; }
+
+  Kind getKind() const { return DeclKind; }
+  const char *getDeclKindName() const;
+
+  Decl *getNextDeclInContext() { return NextDeclInContext; }
+  const Decl *getNextDeclInContext() const { return NextDeclInContext; }
+
+  DeclContext *getDeclContext() {
+    if (isInSemaDC())
+      return getSemanticDC();
+    return getMultipleDC()->SemanticDC;
+  }
+  const DeclContext *getDeclContext() const {
+    return const_cast<Decl*>(this)->getDeclContext();
+  }
+
+  TranslationUnitDecl *getTranslationUnitDecl();
+  const TranslationUnitDecl *getTranslationUnitDecl() const {
+    return const_cast<Decl*>(this)->getTranslationUnitDecl();
+  }
+
+  bool isInAnonymousNamespace() const;
+
+  ASTContext &getASTContext() const;
+
+  void setAccess(AccessSpecifier AS) {
+    Access = AS;
+    CheckAccessDeclContext();
+  }
+
+  AccessSpecifier getAccess() const {
+    CheckAccessDeclContext();
+    return AccessSpecifier(Access);
+  }
+
+  bool hasAttrs() const { return HasAttrs; }
+  void addAttr(Attr *attr);
+  const Attr *getAttrs() const {
+    if (!HasAttrs) return 0;  // common case, no attributes.
+    return getAttrsImpl();    // Uncommon case, out of line hash lookup.
+  }
+  void swapAttrs(Decl *D);
+  void invalidateAttrs();
+
+  template<typename T> const T *getAttr() const {
+    for (const Attr *attr = getAttrs(); attr; attr = attr->getNext())
+      if (const T *V = dyn_cast<T>(attr))
+        return V;
+    return 0;
+  }
+
+  template<typename T> bool hasAttr() const {
+    return getAttr<T>() != 0;
+  }
+
+  /// setInvalidDecl - Indicates the Decl had a semantic error. This
+  /// allows for graceful error recovery.
+  void setInvalidDecl(bool Invalid = true);
+  bool isInvalidDecl() const { return (bool) InvalidDecl; }
+
+  /// isImplicit - Indicates whether the declaration was implicitly
+  /// generated by the implementation. If false, this declaration
+  /// was written explicitly in the source code.
+  bool isImplicit() const { return Implicit; }
+  void setImplicit(bool I = true) { Implicit = I; }
+
+  /// \brief Whether this declaration was used, meaning that a definition
+  /// is required.
+  bool isUsed() const;
+  
+  void setUsed(bool U = true) { Used = U; }
+
+  /// \brief Retrieve the level of precompiled header from which this
+  /// declaration was generated.
+  ///
+  /// The PCH level of a declaration describes where the declaration originated
+  /// from. A PCH level of 0 indicates that the declaration was not from a 
+  /// precompiled header. A PCH level of 1 indicates that the declaration was
+  /// from a top-level precompiled header; 2 indicates that the declaration 
+  /// comes from a precompiled header on which the top-level precompiled header
+  /// depends, and so on. 
+  unsigned getPCHLevel() const { return PCHLevel; }
+
+  /// \brief The maximum PCH level that any declaration may have.
+  static const unsigned MaxPCHLevel = 3;
+  
+  /// \brief Set the PCH level of this declaration.
+  void setPCHLevel(unsigned Level) { 
+    assert(Level < MaxPCHLevel && "PCH level exceeds the maximum");
+    PCHLevel = Level;
+  }
+  
+  unsigned getIdentifierNamespace() const {
+    return IdentifierNamespace;
+  }
+  bool isInIdentifierNamespace(unsigned NS) const {
+    return getIdentifierNamespace() & NS;
+  }
+  static unsigned getIdentifierNamespaceForKind(Kind DK);
+
+  bool hasTagIdentifierNamespace() const {
+    return isTagIdentifierNamespace(getIdentifierNamespace());
+  }
+  static bool isTagIdentifierNamespace(unsigned NS) {
+    // TagDecls have Tag and Type set and may also have TagFriend.
+    return (NS & ~IDNS_TagFriend) == (IDNS_Tag | IDNS_Type);
+  }
+
+  /// getLexicalDeclContext - The declaration context where this Decl was
+  /// lexically declared (LexicalDC). May be different from
+  /// getDeclContext() (SemanticDC).
+  /// e.g.:
+  ///
+  ///   namespace A {
+  ///      void f(); // SemanticDC == LexicalDC == 'namespace A'
+  ///   }
+  ///   void A::f(); // SemanticDC == namespace 'A'
+  ///                // LexicalDC == global namespace
+  DeclContext *getLexicalDeclContext() {
+    if (isInSemaDC())
+      return getSemanticDC();
+    return getMultipleDC()->LexicalDC;
+  }
+  const DeclContext *getLexicalDeclContext() const {
+    return const_cast<Decl*>(this)->getLexicalDeclContext();
+  }
+
+  virtual bool isOutOfLine() const {
+    return getLexicalDeclContext() != getDeclContext();
+  }
+
+  /// setDeclContext - Set both the semantic and lexical DeclContext
+  /// to DC.
+  void setDeclContext(DeclContext *DC);
+
+  void setLexicalDeclContext(DeclContext *DC);
+
+  // isDefinedOutsideFunctionOrMethod - This predicate returns true if this
+  // scoped decl is defined outside the current function or method.  This is
+  // roughly global variables and functions, but also handles enums (which could
+  // be defined inside or outside a function etc).
+  bool isDefinedOutsideFunctionOrMethod() const;
+
+  /// \brief Retrieves the "canonical" declaration of the given declaration.
+  virtual Decl *getCanonicalDecl() { return this; }
+  const Decl *getCanonicalDecl() const {
+    return const_cast<Decl*>(this)->getCanonicalDecl();
+  }
+
+  /// \brief Whether this particular Decl is a canonical one.
+  bool isCanonicalDecl() const { return getCanonicalDecl() == this; }
+
+protected:
+  /// \brief Returns the next redeclaration or itself if this is the only decl.
+  ///
+  /// Decl subclasses that can be redeclared should override this method so that
+  /// Decl::redecl_iterator can iterate over them.
+  virtual Decl *getNextRedeclaration() { return this; }
+
+public:
+  /// \brief Iterates through all the redeclarations of the same decl.
+  class redecl_iterator {
+    /// Current - The current declaration.
+    Decl *Current;
+    Decl *Starter;
+
+  public:
+    typedef Decl*                     value_type;
+    typedef Decl*                     reference;
+    typedef Decl*                     pointer;
+    typedef std::forward_iterator_tag iterator_category;
+    typedef std::ptrdiff_t            difference_type;
+
+    redecl_iterator() : Current(0) { }
+    explicit redecl_iterator(Decl *C) : Current(C), Starter(C) { }
+
+    reference operator*() const { return Current; }
+    pointer operator->() const { return Current; }
+
+    redecl_iterator& operator++() {
+      assert(Current && "Advancing while iterator has reached end");
+      // Get either previous decl or latest decl.
+      Decl *Next = Current->getNextRedeclaration();
+      assert(Next && "Should return next redeclaration or itself, never null!");
+      Current = (Next != Starter ? Next : 0);
+      return *this;
+    }
+
+    redecl_iterator operator++(int) {
+      redecl_iterator tmp(*this);
+      ++(*this);
+      return tmp;
+    }
+
+    friend bool operator==(redecl_iterator x, redecl_iterator y) {
+      return x.Current == y.Current;
+    }
+    friend bool operator!=(redecl_iterator x, redecl_iterator y) {
+      return x.Current != y.Current;
+    }
+  };
+
+  /// \brief Returns iterator for all the redeclarations of the same decl.
+  /// It will iterate at least once (when this decl is the only one).
+  redecl_iterator redecls_begin() const {
+    return redecl_iterator(const_cast<Decl*>(this));
+  }
+  redecl_iterator redecls_end() const { return redecl_iterator(); }
+
+  /// getBody - If this Decl represents a declaration for a body of code,
+  ///  such as a function or method definition, this method returns the
+  ///  top-level Stmt* of that body.  Otherwise this method returns null.
+  virtual Stmt* getBody() const { return 0; }
+
+  /// getCompoundBody - Returns getBody(), dyn_casted to a CompoundStmt.
+  CompoundStmt* getCompoundBody() const;
+
+  /// getBodyRBrace - Gets the right brace of the body, if a body exists.
+  /// This works whether the body is a CompoundStmt or a CXXTryStmt.
+  SourceLocation getBodyRBrace() const;
+
+  // global temp stats (until we have a per-module visitor)
+  static void addDeclKind(Kind k);
+  static bool CollectingStats(bool Enable = false);
+  static void PrintStats();
+
+  /// isTemplateParameter - Determines whether this declaration is a
+  /// template parameter.
+  bool isTemplateParameter() const;
+
+  /// isTemplateParameter - Determines whether this declaration is a
+  /// template parameter pack.
+  bool isTemplateParameterPack() const;
+
+  /// \brief Whether this declaration is a function or function template.
+  bool isFunctionOrFunctionTemplate() const;
+
+  /// \brief Changes the namespace of this declaration to reflect that it's
+  /// the object of a friend declaration.
+  ///
+  /// These declarations appear in the lexical context of the friending
+  /// class, but in the semantic context of the actual entity.  This property
+  /// applies only to a specific decl object;  other redeclarations of the
+  /// same entity may not (and probably don't) share this property.
+  void setObjectOfFriendDecl(bool PreviouslyDeclared) {
+    unsigned OldNS = IdentifierNamespace;
+    assert((OldNS & (IDNS_Tag | IDNS_Ordinary |
+                     IDNS_TagFriend | IDNS_OrdinaryFriend)) &&
+           "namespace includes neither ordinary nor tag");
+    assert(!(OldNS & ~(IDNS_Tag | IDNS_Ordinary | IDNS_Type |
+                       IDNS_TagFriend | IDNS_OrdinaryFriend)) &&
+           "namespace includes other than ordinary or tag");
+
+    IdentifierNamespace = 0;
+    if (OldNS & (IDNS_Tag | IDNS_TagFriend)) {
+      IdentifierNamespace |= IDNS_TagFriend;
+      if (PreviouslyDeclared) IdentifierNamespace |= IDNS_Tag | IDNS_Type;
+    }
+
+    if (OldNS & (IDNS_Ordinary | IDNS_OrdinaryFriend)) {
+      IdentifierNamespace |= IDNS_OrdinaryFriend;
+      if (PreviouslyDeclared) IdentifierNamespace |= IDNS_Ordinary;
+    }
+  }
+
+  enum FriendObjectKind {
+    FOK_None, // not a friend object
+    FOK_Declared, // a friend of a previously-declared entity
+    FOK_Undeclared // a friend of a previously-undeclared entity
+  };
+
+  /// \brief Determines whether this declaration is the object of a
+  /// friend declaration and, if so, what kind.
+  ///
+  /// There is currently no direct way to find the associated FriendDecl.
+  FriendObjectKind getFriendObjectKind() const {
+    unsigned mask
+      = (IdentifierNamespace & (IDNS_TagFriend | IDNS_OrdinaryFriend));
+    if (!mask) return FOK_None;
+    return (IdentifierNamespace & (IDNS_Tag | IDNS_Ordinary) ? 
+              FOK_Declared : FOK_Undeclared);
+  }
+
+  /// Specifies that this declaration is a C++ overloaded non-member.
+  void setNonMemberOperator() {
+    assert(getKind() == Function || getKind() == FunctionTemplate);
+    assert((IdentifierNamespace & IDNS_Ordinary) &&
+           "visible non-member operators should be in ordinary namespace");
+    IdentifierNamespace |= IDNS_NonMemberOperator;
+  }
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *) { return true; }
+  static bool classofKind(Kind K) { return true; }
+  static DeclContext *castToDeclContext(const Decl *);
+  static Decl *castFromDeclContext(const DeclContext *);
+
+  /// Destroy - Call destructors and release memory.
+  virtual void Destroy(ASTContext& C);
+
+  void print(llvm::raw_ostream &Out, unsigned Indentation = 0) const;
+  void print(llvm::raw_ostream &Out, const PrintingPolicy &Policy,
+             unsigned Indentation = 0) const;
+  static void printGroup(Decl** Begin, unsigned NumDecls,
+                         llvm::raw_ostream &Out, const PrintingPolicy &Policy,
+                         unsigned Indentation = 0);
+  void dump() const;
+
+private:
+  const Attr *getAttrsImpl() const;
+
+};
+
+/// PrettyStackTraceDecl - If a crash occurs, indicate that it happened when
+/// doing something to a specific decl.
+class PrettyStackTraceDecl : public llvm::PrettyStackTraceEntry {
+  const Decl *TheDecl;
+  SourceLocation Loc;
+  SourceManager &SM;
+  const char *Message;
+public:
+  PrettyStackTraceDecl(const Decl *theDecl, SourceLocation L,
+                       SourceManager &sm, const char *Msg)
+  : TheDecl(theDecl), Loc(L), SM(sm), Message(Msg) {}
+
+  virtual void print(llvm::raw_ostream &OS) const;
+};
+
+
+/// DeclContext - This is used only as base class of specific decl types that
+/// can act as declaration contexts. These decls are (only the top classes
+/// that directly derive from DeclContext are mentioned, not their subclasses):
+///
+///   TranslationUnitDecl
+///   NamespaceDecl
+///   FunctionDecl
+///   TagDecl
+///   ObjCMethodDecl
+///   ObjCContainerDecl
+///   LinkageSpecDecl
+///   BlockDecl
+///
+class DeclContext {
+  /// DeclKind - This indicates which class this is.
+  Decl::Kind DeclKind   :  8;
+
+  /// \brief Whether this declaration context also has some external
+  /// storage that contains additional declarations that are lexically
+  /// part of this context.
+  mutable bool ExternalLexicalStorage : 1;
+
+  /// \brief Whether this declaration context also has some external
+  /// storage that contains additional declarations that are visible
+  /// in this context.
+  mutable bool ExternalVisibleStorage : 1;
+
+  /// \brief Pointer to the data structure used to lookup declarations
+  /// within this context (or a DependentStoredDeclsMap if this is a
+  /// dependent context).
+  mutable StoredDeclsMap *LookupPtr;
+
+  /// FirstDecl - The first declaration stored within this declaration
+  /// context.
+  mutable Decl *FirstDecl;
+
+  /// LastDecl - The last declaration stored within this declaration
+  /// context. FIXME: We could probably cache this value somewhere
+  /// outside of the DeclContext, to reduce the size of DeclContext by
+  /// another pointer.
+  mutable Decl *LastDecl;
+
+protected:
+   DeclContext(Decl::Kind K)
+     : DeclKind(K), ExternalLexicalStorage(false),
+       ExternalVisibleStorage(false), LookupPtr(0), FirstDecl(0),
+       LastDecl(0) { }
+
+  void DestroyDecls(ASTContext &C);
+
+public:
+  ~DeclContext();
+
+  Decl::Kind getDeclKind() const {
+    return DeclKind;
+  }
+  const char *getDeclKindName() const;
+
+  /// getParent - Returns the containing DeclContext.
+  DeclContext *getParent() {
+    return cast<Decl>(this)->getDeclContext();
+  }
+  const DeclContext *getParent() const {
+    return const_cast<DeclContext*>(this)->getParent();
+  }
+
+  /// getLexicalParent - Returns the containing lexical DeclContext. May be
+  /// different from getParent, e.g.:
+  ///
+  ///   namespace A {
+  ///      struct S;
+  ///   }
+  ///   struct A::S {}; // getParent() == namespace 'A'
+  ///                   // getLexicalParent() == translation unit
+  ///
+  DeclContext *getLexicalParent() {
+    return cast<Decl>(this)->getLexicalDeclContext();
+  }
+  const DeclContext *getLexicalParent() const {
+    return const_cast<DeclContext*>(this)->getLexicalParent();
+  }
+
+  DeclContext *getLookupParent();
+  
+  const DeclContext *getLookupParent() const {
+    return const_cast<DeclContext*>(this)->getLookupParent();
+  }
+  
+  ASTContext &getParentASTContext() const {
+    return cast<Decl>(this)->getASTContext();
+  }
+
+  bool isFunctionOrMethod() const {
+    switch (DeclKind) {
+    case Decl::Block:
+    case Decl::ObjCMethod:
+      return true;
+    default:
+      return DeclKind >= Decl::FunctionFirst && DeclKind <= Decl::FunctionLast;
+    }
+  }
+
+  bool isFileContext() const {
+    return DeclKind == Decl::TranslationUnit || DeclKind == Decl::Namespace;
+  }
+
+  bool isTranslationUnit() const {
+    return DeclKind == Decl::TranslationUnit;
+  }
+
+  bool isRecord() const {
+    return DeclKind >= Decl::RecordFirst && DeclKind <= Decl::RecordLast;
+  }
+
+  bool isNamespace() const {
+    return DeclKind == Decl::Namespace;
+  }
+
+  /// \brief Determines whether this context is dependent on a
+  /// template parameter.
+  bool isDependentContext() const;
+
+  /// isTransparentContext - Determines whether this context is a
+  /// "transparent" context, meaning that the members declared in this
+  /// context are semantically declared in the nearest enclosing
+  /// non-transparent (opaque) context but are lexically declared in
+  /// this context. For example, consider the enumerators of an
+  /// enumeration type:
+  /// @code
+  /// enum E {
+  ///   Val1
+  /// };
+  /// @endcode
+  /// Here, E is a transparent context, so its enumerator (Val1) will
+  /// appear (semantically) that it is in the same context of E.
+  /// Examples of transparent contexts include: enumerations (except for
+  /// C++0x scoped enums), C++ linkage specifications, and C++0x
+  /// inline namespaces.
+  bool isTransparentContext() const;
+
+  /// \brief Determine whether this declaration context is equivalent
+  /// to the declaration context DC.
+  bool Equals(DeclContext *DC) {
+    return DC && this->getPrimaryContext() == DC->getPrimaryContext();
+  }
+
+  /// \brief Determine whether this declaration context encloses the
+  /// declaration context DC.
+  bool Encloses(DeclContext *DC);
+
+  /// getPrimaryContext - There may be many different
+  /// declarations of the same entity (including forward declarations
+  /// of classes, multiple definitions of namespaces, etc.), each with
+  /// a different set of declarations. This routine returns the
+  /// "primary" DeclContext structure, which will contain the
+  /// information needed to perform name lookup into this context.
+  DeclContext *getPrimaryContext();
+  const DeclContext *getPrimaryContext() const {
+    return const_cast<DeclContext*>(this)->getPrimaryContext();
+  }
+
+  /// getLookupContext - Retrieve the innermost non-transparent
+  /// context of this context, which corresponds to the innermost
+  /// location from which name lookup can find the entities in this
+  /// context.
+  DeclContext *getLookupContext();
+  const DeclContext *getLookupContext() const {
+    return const_cast<DeclContext *>(this)->getLookupContext();
+  }
+
+  /// \brief Retrieve the nearest enclosing namespace context.
+  DeclContext *getEnclosingNamespaceContext();
+  const DeclContext *getEnclosingNamespaceContext() const {
+    return const_cast<DeclContext *>(this)->getEnclosingNamespaceContext();
+  }
+
+  /// getNextContext - If this is a DeclContext that may have other
+  /// DeclContexts that are semantically connected but syntactically
+  /// different, such as C++ namespaces, this routine retrieves the
+  /// next DeclContext in the link. Iteration through the chain of
+  /// DeclContexts should begin at the primary DeclContext and
+  /// continue until this function returns NULL. For example, given:
+  /// @code
+  /// namespace N {
+  ///   int x;
+  /// }
+  /// namespace N {
+  ///   int y;
+  /// }
+  /// @endcode
+  /// The first occurrence of namespace N will be the primary
+  /// DeclContext. Its getNextContext will return the second
+  /// occurrence of namespace N.
+  DeclContext *getNextContext();
+
+  /// decl_iterator - Iterates through the declarations stored
+  /// within this context.
+  class decl_iterator {
+    /// Current - The current declaration.
+    Decl *Current;
+
+  public:
+    typedef Decl*                     value_type;
+    typedef Decl*                     reference;
+    typedef Decl*                     pointer;
+    typedef std::forward_iterator_tag iterator_category;
+    typedef std::ptrdiff_t            difference_type;
+
+    decl_iterator() : Current(0) { }
+    explicit decl_iterator(Decl *C) : Current(C) { }
+
+    reference operator*() const { return Current; }
+    pointer operator->() const { return Current; }
+
+    decl_iterator& operator++() {
+      Current = Current->getNextDeclInContext();
+      return *this;
+    }
+
+    decl_iterator operator++(int) {
+      decl_iterator tmp(*this);
+      ++(*this);
+      return tmp;
+    }
+
+    friend bool operator==(decl_iterator x, decl_iterator y) {
+      return x.Current == y.Current;
+    }
+    friend bool operator!=(decl_iterator x, decl_iterator y) {
+      return x.Current != y.Current;
+    }
+  };
+
+  /// decls_begin/decls_end - Iterate over the declarations stored in
+  /// this context.
+  decl_iterator decls_begin() const;
+  decl_iterator decls_end() const;
+  bool decls_empty() const;
+
+  /// specific_decl_iterator - Iterates over a subrange of
+  /// declarations stored in a DeclContext, providing only those that
+  /// are of type SpecificDecl (or a class derived from it). This
+  /// iterator is used, for example, to provide iteration over just
+  /// the fields within a RecordDecl (with SpecificDecl = FieldDecl).
+  template<typename SpecificDecl>
+  class specific_decl_iterator {
+    /// Current - The current, underlying declaration iterator, which
+    /// will either be NULL or will point to a declaration of
+    /// type SpecificDecl.
+    DeclContext::decl_iterator Current;
+
+    /// SkipToNextDecl - Advances the current position up to the next
+    /// declaration of type SpecificDecl that also meets the criteria
+    /// required by Acceptable.
+    void SkipToNextDecl() {
+      while (*Current && !isa<SpecificDecl>(*Current))
+        ++Current;
+    }
+
+  public:
+    typedef SpecificDecl* value_type;
+    typedef SpecificDecl* reference;
+    typedef SpecificDecl* pointer;
+    typedef std::iterator_traits<DeclContext::decl_iterator>::difference_type
+      difference_type;
+    typedef std::forward_iterator_tag iterator_category;
+
+    specific_decl_iterator() : Current() { }
+
+    /// specific_decl_iterator - Construct a new iterator over a
+    /// subset of the declarations the range [C,
+    /// end-of-declarations). If A is non-NULL, it is a pointer to a
+    /// member function of SpecificDecl that should return true for
+    /// all of the SpecificDecl instances that will be in the subset
+    /// of iterators. For example, if you want Objective-C instance
+    /// methods, SpecificDecl will be ObjCMethodDecl and A will be
+    /// &ObjCMethodDecl::isInstanceMethod.
+    explicit specific_decl_iterator(DeclContext::decl_iterator C) : Current(C) {
+      SkipToNextDecl();
+    }
+
+    reference operator*() const { return cast<SpecificDecl>(*Current); }
+    pointer operator->() const { return cast<SpecificDecl>(*Current); }
+
+    specific_decl_iterator& operator++() {
+      ++Current;
+      SkipToNextDecl();
+      return *this;
+    }
+
+    specific_decl_iterator operator++(int) {
+      specific_decl_iterator tmp(*this);
+      ++(*this);
+      return tmp;
+    }
+
+    friend bool
+    operator==(const specific_decl_iterator& x, const specific_decl_iterator& y) {
+      return x.Current == y.Current;
+    }
+
+    friend bool
+    operator!=(const specific_decl_iterator& x, const specific_decl_iterator& y) {
+      return x.Current != y.Current;
+    }
+  };
+
+  /// \brief Iterates over a filtered subrange of declarations stored
+  /// in a DeclContext.
+  ///
+  /// This iterator visits only those declarations that are of type
+  /// SpecificDecl (or a class derived from it) and that meet some
+  /// additional run-time criteria. This iterator is used, for
+  /// example, to provide access to the instance methods within an
+  /// Objective-C interface (with SpecificDecl = ObjCMethodDecl and
+  /// Acceptable = ObjCMethodDecl::isInstanceMethod).
+  template<typename SpecificDecl, bool (SpecificDecl::*Acceptable)() const>
+  class filtered_decl_iterator {
+    /// Current - The current, underlying declaration iterator, which
+    /// will either be NULL or will point to a declaration of
+    /// type SpecificDecl.
+    DeclContext::decl_iterator Current;
+
+    /// SkipToNextDecl - Advances the current position up to the next
+    /// declaration of type SpecificDecl that also meets the criteria
+    /// required by Acceptable.
+    void SkipToNextDecl() {
+      while (*Current &&
+             (!isa<SpecificDecl>(*Current) ||
+              (Acceptable && !(cast<SpecificDecl>(*Current)->*Acceptable)())))
+        ++Current;
+    }
+
+  public:
+    typedef SpecificDecl* value_type;
+    typedef SpecificDecl* reference;
+    typedef SpecificDecl* pointer;
+    typedef std::iterator_traits<DeclContext::decl_iterator>::difference_type
+      difference_type;
+    typedef std::forward_iterator_tag iterator_category;
+
+    filtered_decl_iterator() : Current() { }
+
+    /// specific_decl_iterator - Construct a new iterator over a
+    /// subset of the declarations the range [C,
+    /// end-of-declarations). If A is non-NULL, it is a pointer to a
+    /// member function of SpecificDecl that should return true for
+    /// all of the SpecificDecl instances that will be in the subset
+    /// of iterators. For example, if you want Objective-C instance
+    /// methods, SpecificDecl will be ObjCMethodDecl and A will be
+    /// &ObjCMethodDecl::isInstanceMethod.
+    explicit filtered_decl_iterator(DeclContext::decl_iterator C) : Current(C) {
+      SkipToNextDecl();
+    }
+
+    reference operator*() const { return cast<SpecificDecl>(*Current); }
+    pointer operator->() const { return cast<SpecificDecl>(*Current); }
+
+    filtered_decl_iterator& operator++() {
+      ++Current;
+      SkipToNextDecl();
+      return *this;
+    }
+
+    filtered_decl_iterator operator++(int) {
+      filtered_decl_iterator tmp(*this);
+      ++(*this);
+      return tmp;
+    }
+
+    friend bool
+    operator==(const filtered_decl_iterator& x, const filtered_decl_iterator& y) {
+      return x.Current == y.Current;
+    }
+
+    friend bool
+    operator!=(const filtered_decl_iterator& x, const filtered_decl_iterator& y) {
+      return x.Current != y.Current;
+    }
+  };
+
+  /// @brief Add the declaration D into this context.
+  ///
+  /// This routine should be invoked when the declaration D has first
+  /// been declared, to place D into the context where it was
+  /// (lexically) defined. Every declaration must be added to one
+  /// (and only one!) context, where it can be visited via
+  /// [decls_begin(), decls_end()). Once a declaration has been added
+  /// to its lexical context, the corresponding DeclContext owns the
+  /// declaration.
+  ///
+  /// If D is also a NamedDecl, it will be made visible within its
+  /// semantic context via makeDeclVisibleInContext.
+  void addDecl(Decl *D);
+
+  /// @brief Add the declaration D to this context without modifying
+  /// any lookup tables.
+  ///
+  /// This is useful for some operations in dependent contexts where
+  /// the semantic context might not be dependent;  this basically
+  /// only happens with friends.
+  void addHiddenDecl(Decl *D);
+
+  /// @brief Removes a declaration from this context.
+  void removeDecl(Decl *D);
+
+  /// lookup_iterator - An iterator that provides access to the results
+  /// of looking up a name within this context.
+  typedef NamedDecl **lookup_iterator;
+
+  /// lookup_const_iterator - An iterator that provides non-mutable
+  /// access to the results of lookup up a name within this context.
+  typedef NamedDecl * const * lookup_const_iterator;
+
+  typedef std::pair<lookup_iterator, lookup_iterator> lookup_result;
+  typedef std::pair<lookup_const_iterator, lookup_const_iterator>
+    lookup_const_result;
+
+  /// lookup - Find the declarations (if any) with the given Name in
+  /// this context. Returns a range of iterators that contains all of
+  /// the declarations with this name, with object, function, member,
+  /// and enumerator names preceding any tag name. Note that this
+  /// routine will not look into parent contexts.
+  lookup_result lookup(DeclarationName Name);
+  lookup_const_result lookup(DeclarationName Name) const;
+
+  /// @brief Makes a declaration visible within this context.
+  ///
+  /// This routine makes the declaration D visible to name lookup
+  /// within this context and, if this is a transparent context,
+  /// within its parent contexts up to the first enclosing
+  /// non-transparent context. Making a declaration visible within a
+  /// context does not transfer ownership of a declaration, and a
+  /// declaration can be visible in many contexts that aren't its
+  /// lexical context.
+  ///
+  /// If D is a redeclaration of an existing declaration that is
+  /// visible from this context, as determined by
+  /// NamedDecl::declarationReplaces, the previous declaration will be
+  /// replaced with D.
+  ///
+  /// @param Recoverable true if it's okay to not add this decl to
+  /// the lookup tables because it can be easily recovered by walking
+  /// the declaration chains.
+  void makeDeclVisibleInContext(NamedDecl *D, bool Recoverable = true);
+
+  /// udir_iterator - Iterates through the using-directives stored
+  /// within this context.
+  typedef UsingDirectiveDecl * const * udir_iterator;
+
+  typedef std::pair<udir_iterator, udir_iterator> udir_iterator_range;
+
+  udir_iterator_range getUsingDirectives() const;
+
+  udir_iterator using_directives_begin() const {
+    return getUsingDirectives().first;
+  }
+
+  udir_iterator using_directives_end() const {
+    return getUsingDirectives().second;
+  }
+
+  // These are all defined in DependentDiagnostic.h.
+  class ddiag_iterator;
+  inline ddiag_iterator ddiag_begin() const;
+  inline ddiag_iterator ddiag_end() const;
+
+  // Low-level accessors
+
+  /// \brief Retrieve the internal representation of the lookup structure.
+  StoredDeclsMap* getLookupPtr() const { return LookupPtr; }
+
+  /// \brief Whether this DeclContext has external storage containing
+  /// additional declarations that are lexically in this context.
+  bool hasExternalLexicalStorage() const { return ExternalLexicalStorage; }
+
+  /// \brief State whether this DeclContext has external storage for
+  /// declarations lexically in this context.
+  void setHasExternalLexicalStorage(bool ES = true) {
+    ExternalLexicalStorage = ES;
+  }
+
+  /// \brief Whether this DeclContext has external storage containing
+  /// additional declarations that are visible in this context.
+  bool hasExternalVisibleStorage() const { return ExternalVisibleStorage; }
+
+  /// \brief State whether this DeclContext has external storage for
+  /// declarations visible in this context.
+  void setHasExternalVisibleStorage(bool ES = true) {
+    ExternalVisibleStorage = ES;
+  }
+
+  static bool classof(const Decl *D);
+  static bool classof(const DeclContext *D) { return true; }
+#define DECL_CONTEXT(Name) \
+  static bool classof(const Name##Decl *D) { return true; }
+#include "clang/AST/DeclNodes.def"
+
+  void dumpDeclContext() const;
+
+private:
+  void LoadLexicalDeclsFromExternalStorage() const;
+  void LoadVisibleDeclsFromExternalStorage() const;
+
+  friend class DependentDiagnostic;
+  StoredDeclsMap *CreateStoredDeclsMap(ASTContext &C) const;
+
+  void buildLookup(DeclContext *DCtx);
+  void makeDeclVisibleInContextImpl(NamedDecl *D);
+};
+
+inline bool Decl::isTemplateParameter() const {
+  return getKind() == TemplateTypeParm || getKind() == NonTypeTemplateParm ||
+         getKind() == TemplateTemplateParm;
+}
+
+
+// Specialization selected when ToTy is not a known subclass of DeclContext.
+template <class ToTy,
+          bool IsKnownSubtype = ::llvm::is_base_of< DeclContext, ToTy>::value>
+struct cast_convert_decl_context {
+  static const ToTy *doit(const DeclContext *Val) {
+    return static_cast<const ToTy*>(Decl::castFromDeclContext(Val));
+  }
+
+  static ToTy *doit(DeclContext *Val) {
+    return static_cast<ToTy*>(Decl::castFromDeclContext(Val));
+  }
+};
+
+// Specialization selected when ToTy is a known subclass of DeclContext.
+template <class ToTy>
+struct cast_convert_decl_context<ToTy, true> {
+  static const ToTy *doit(const DeclContext *Val) {
+    return static_cast<const ToTy*>(Val);
+  }
+
+  static ToTy *doit(DeclContext *Val) {
+    return static_cast<ToTy*>(Val);
+  }
+};
+
+
+} // end clang.
+
+namespace llvm {
+
+/// isa<T>(DeclContext*)
+template<class ToTy>
+struct isa_impl_wrap<ToTy,
+                     const ::clang::DeclContext,const ::clang::DeclContext> {
+  static bool doit(const ::clang::DeclContext &Val) {
+    return ToTy::classofKind(Val.getDeclKind());
+  }
+};
+template<class ToTy>
+struct isa_impl_wrap<ToTy, ::clang::DeclContext, ::clang::DeclContext>
+  : public isa_impl_wrap<ToTy,
+                      const ::clang::DeclContext,const ::clang::DeclContext> {};
+
+/// cast<T>(DeclContext*)
+template<class ToTy>
+struct cast_convert_val<ToTy,
+                        const ::clang::DeclContext,const ::clang::DeclContext> {
+  static const ToTy &doit(const ::clang::DeclContext &Val) {
+    return *::clang::cast_convert_decl_context<ToTy>::doit(&Val);
+  }
+};
+template<class ToTy>
+struct cast_convert_val<ToTy, ::clang::DeclContext, ::clang::DeclContext> {
+  static ToTy &doit(::clang::DeclContext &Val) {
+    return *::clang::cast_convert_decl_context<ToTy>::doit(&Val);
+  }
+};
+template<class ToTy>
+struct cast_convert_val<ToTy,
+                     const ::clang::DeclContext*, const ::clang::DeclContext*> {
+  static const ToTy *doit(const ::clang::DeclContext *Val) {
+    return ::clang::cast_convert_decl_context<ToTy>::doit(Val);
+  }
+};
+template<class ToTy>
+struct cast_convert_val<ToTy, ::clang::DeclContext*, ::clang::DeclContext*> {
+  static ToTy *doit(::clang::DeclContext *Val) {
+    return ::clang::cast_convert_decl_context<ToTy>::doit(Val);
+  }
+};
+
+/// Implement cast_convert_val for Decl -> DeclContext conversions.
+template<class FromTy>
+struct cast_convert_val< ::clang::DeclContext, FromTy, FromTy> {
+  static ::clang::DeclContext &doit(const FromTy &Val) {
+    return *FromTy::castToDeclContext(&Val);
+  }
+};
+
+template<class FromTy>
+struct cast_convert_val< ::clang::DeclContext, FromTy*, FromTy*> {
+  static ::clang::DeclContext *doit(const FromTy *Val) {
+    return FromTy::castToDeclContext(Val);
+  }
+};
+
+template<class FromTy>
+struct cast_convert_val< const ::clang::DeclContext, FromTy, FromTy> {
+  static const ::clang::DeclContext &doit(const FromTy &Val) {
+    return *FromTy::castToDeclContext(&Val);
+  }
+};
+
+template<class FromTy>
+struct cast_convert_val< const ::clang::DeclContext, FromTy*, FromTy*> {
+  static const ::clang::DeclContext *doit(const FromTy *Val) {
+    return FromTy::castToDeclContext(Val);
+  }
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
new file mode 100644
index 0000000..5e791c3
--- /dev/null
+++ b/include/clang/AST/DeclCXX.h
@@ -0,0 +1,1917 @@
+//===-- DeclCXX.h - Classes for representing C++ declarations -*- C++ -*-=====//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the C++ Decl subclasses, other than those for
+//  templates (in DeclTemplate.h) and friends (in DeclFriend.h).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_DECLCXX_H
+#define LLVM_CLANG_AST_DECLCXX_H
+
+#include "clang/AST/Expr.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/UnresolvedSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallPtrSet.h"
+
+namespace clang {
+
+class ClassTemplateDecl;
+class ClassTemplateSpecializationDecl;
+class CXXBasePath;
+class CXXBasePaths;
+class CXXConstructorDecl;
+class CXXConversionDecl;
+class CXXDestructorDecl;
+class CXXMethodDecl;
+class CXXRecordDecl;
+class CXXMemberLookupCriteria;
+class CXXFinalOverriderMap;
+class FriendDecl;
+  
+/// \brief Represents any kind of function declaration, whether it is a
+/// concrete function or a function template.
+class AnyFunctionDecl {
+  NamedDecl *Function;
+
+  AnyFunctionDecl(NamedDecl *ND) : Function(ND) { }
+
+public:
+  AnyFunctionDecl(FunctionDecl *FD) : Function(FD) { }
+  AnyFunctionDecl(FunctionTemplateDecl *FTD);
+
+  /// \brief Implicily converts any function or function template into a
+  /// named declaration.
+  operator NamedDecl *() const { return Function; }
+
+  /// \brief Retrieve the underlying function or function template.
+  NamedDecl *get() const { return Function; }
+
+  static AnyFunctionDecl getFromNamedDecl(NamedDecl *ND) {
+    return AnyFunctionDecl(ND);
+  }
+};
+
+} // end namespace clang
+
+namespace llvm {
+  /// Implement simplify_type for AnyFunctionDecl, so that we can dyn_cast from
+  /// AnyFunctionDecl to any function or function template declaration.
+  template<> struct simplify_type<const ::clang::AnyFunctionDecl> {
+    typedef ::clang::NamedDecl* SimpleType;
+    static SimpleType getSimplifiedValue(const ::clang::AnyFunctionDecl &Val) {
+      return Val;
+    }
+  };
+  template<> struct simplify_type< ::clang::AnyFunctionDecl>
+  : public simplify_type<const ::clang::AnyFunctionDecl> {};
+
+  // Provide PointerLikeTypeTraits for non-cvr pointers.
+  template<>
+  class PointerLikeTypeTraits< ::clang::AnyFunctionDecl> {
+  public:
+    static inline void *getAsVoidPointer(::clang::AnyFunctionDecl F) {
+      return F.get();
+    }
+    static inline ::clang::AnyFunctionDecl getFromVoidPointer(void *P) {
+      return ::clang::AnyFunctionDecl::getFromNamedDecl(
+                                      static_cast< ::clang::NamedDecl*>(P));
+    }
+
+    enum { NumLowBitsAvailable = 2 };
+  };
+
+} // end namespace llvm
+
+namespace clang {
+
+/// CXXBaseSpecifier - A base class of a C++ class.
+///
+/// Each CXXBaseSpecifier represents a single, direct base class (or
+/// struct) of a C++ class (or struct). It specifies the type of that
+/// base class, whether it is a virtual or non-virtual base, and what
+/// level of access (public, protected, private) is used for the
+/// derivation. For example:
+///
+/// @code
+///   class A { };
+///   class B { };
+///   class C : public virtual A, protected B { };
+/// @endcode
+///
+/// In this code, C will have two CXXBaseSpecifiers, one for "public
+/// virtual A" and the other for "protected B".
+class CXXBaseSpecifier {
+  /// Range - The source code range that covers the full base
+  /// specifier, including the "virtual" (if present) and access
+  /// specifier (if present).
+  // FIXME: Move over to a TypeLoc!
+  SourceRange Range;
+
+  /// Virtual - Whether this is a virtual base class or not.
+  bool Virtual : 1;
+
+  /// BaseOfClass - Whether this is the base of a class (true) or of a
+  /// struct (false). This determines the mapping from the access
+  /// specifier as written in the source code to the access specifier
+  /// used for semantic analysis.
+  bool BaseOfClass : 1;
+
+  /// Access - Access specifier as written in the source code (which
+  /// may be AS_none). The actual type of data stored here is an
+  /// AccessSpecifier, but we use "unsigned" here to work around a
+  /// VC++ bug.
+  unsigned Access : 2;
+
+  /// BaseType - The type of the base class. This will be a class or
+  /// struct (or a typedef of such).
+  QualType BaseType;
+
+public:
+  CXXBaseSpecifier() { }
+
+  CXXBaseSpecifier(SourceRange R, bool V, bool BC, AccessSpecifier A, QualType T)
+    : Range(R), Virtual(V), BaseOfClass(BC), Access(A), BaseType(T) { }
+
+  /// getSourceRange - Retrieves the source range that contains the
+  /// entire base specifier.
+  SourceRange getSourceRange() const { return Range; }
+
+  /// isVirtual - Determines whether the base class is a virtual base
+  /// class (or not).
+  bool isVirtual() const { return Virtual; }
+
+  /// \brief Determine whether this base class if a base of a class declared
+  /// with the 'class' keyword (vs. one declared with the 'struct' keyword).
+  bool isBaseOfClass() const { return BaseOfClass; }
+  
+  /// getAccessSpecifier - Returns the access specifier for this base
+  /// specifier. This is the actual base specifier as used for
+  /// semantic analysis, so the result can never be AS_none. To
+  /// retrieve the access specifier as written in the source code, use
+  /// getAccessSpecifierAsWritten().
+  AccessSpecifier getAccessSpecifier() const {
+    if ((AccessSpecifier)Access == AS_none)
+      return BaseOfClass? AS_private : AS_public;
+    else
+      return (AccessSpecifier)Access;
+  }
+
+  /// getAccessSpecifierAsWritten - Retrieves the access specifier as
+  /// written in the source code (which may mean that no access
+  /// specifier was explicitly written). Use getAccessSpecifier() to
+  /// retrieve the access specifier for use in semantic analysis.
+  AccessSpecifier getAccessSpecifierAsWritten() const {
+    return (AccessSpecifier)Access;
+  }
+
+  /// getType - Retrieves the type of the base class. This type will
+  /// always be an unqualified class type.
+  QualType getType() const { return BaseType; }
+};
+
+/// CXXRecordDecl - Represents a C++ struct/union/class.
+/// FIXME: This class will disappear once we've properly taught RecordDecl
+/// to deal with C++-specific things.
+class CXXRecordDecl : public RecordDecl {
+
+  friend void TagDecl::startDefinition();
+
+  struct DefinitionData {
+    DefinitionData(CXXRecordDecl *D);
+
+    /// UserDeclaredConstructor - True when this class has a
+    /// user-declared constructor.
+    bool UserDeclaredConstructor : 1;
+
+    /// UserDeclaredCopyConstructor - True when this class has a
+    /// user-declared copy constructor.
+    bool UserDeclaredCopyConstructor : 1;
+
+    /// UserDeclaredCopyAssignment - True when this class has a
+    /// user-declared copy assignment operator.
+    bool UserDeclaredCopyAssignment : 1;
+
+    /// UserDeclaredDestructor - True when this class has a
+    /// user-declared destructor.
+    bool UserDeclaredDestructor : 1;
+
+    /// Aggregate - True when this class is an aggregate.
+    bool Aggregate : 1;
+
+    /// PlainOldData - True when this class is a POD-type.
+    bool PlainOldData : 1;
+
+    /// Empty - true when this class is empty for traits purposes,
+    /// i.e. has no data members other than 0-width bit-fields, has no
+    /// virtual function/base, and doesn't inherit from a non-empty
+    /// class. Doesn't take union-ness into account.
+    bool Empty : 1;
+
+    /// Polymorphic - True when this class is polymorphic, i.e. has at
+    /// least one virtual member or derives from a polymorphic class.
+    bool Polymorphic : 1;
+
+    /// Abstract - True when this class is abstract, i.e. has at least
+    /// one pure virtual function, (that can come from a base class).
+    bool Abstract : 1;
+
+    /// HasTrivialConstructor - True when this class has a trivial constructor.
+    ///
+    /// C++ [class.ctor]p5.  A constructor is trivial if it is an
+    /// implicitly-declared default constructor and if:
+    /// * its class has no virtual functions and no virtual base classes, and
+    /// * all the direct base classes of its class have trivial constructors, and
+    /// * for all the nonstatic data members of its class that are of class type
+    ///   (or array thereof), each such class has a trivial constructor.
+    bool HasTrivialConstructor : 1;
+
+    /// HasTrivialCopyConstructor - True when this class has a trivial copy
+    /// constructor.
+    ///
+    /// C++ [class.copy]p6.  A copy constructor for class X is trivial
+    /// if it is implicitly declared and if
+    /// * class X has no virtual functions and no virtual base classes, and
+    /// * each direct base class of X has a trivial copy constructor, and
+    /// * for all the nonstatic data members of X that are of class type (or
+    ///   array thereof), each such class type has a trivial copy constructor;
+    /// otherwise the copy constructor is non-trivial.
+    bool HasTrivialCopyConstructor : 1;
+
+    /// HasTrivialCopyAssignment - True when this class has a trivial copy
+    /// assignment operator.
+    ///
+    /// C++ [class.copy]p11.  A copy assignment operator for class X is
+    /// trivial if it is implicitly declared and if
+    /// * class X has no virtual functions and no virtual base classes, and
+    /// * each direct base class of X has a trivial copy assignment operator, and
+    /// * for all the nonstatic data members of X that are of class type (or
+    ///   array thereof), each such class type has a trivial copy assignment
+    ///   operator;
+    /// otherwise the copy assignment operator is non-trivial.
+    bool HasTrivialCopyAssignment : 1;
+
+    /// HasTrivialDestructor - True when this class has a trivial destructor.
+    ///
+    /// C++ [class.dtor]p3.  A destructor is trivial if it is an
+    /// implicitly-declared destructor and if:
+    /// * all of the direct base classes of its class have trivial destructors
+    ///   and
+    /// * for all of the non-static data members of its class that are of class
+    ///   type (or array thereof), each such class has a trivial destructor.
+    bool HasTrivialDestructor : 1;
+
+    /// ComputedVisibleConversions - True when visible conversion functions are
+    /// already computed and are available.
+    bool ComputedVisibleConversions : 1;
+  
+    /// Bases - Base classes of this class.
+    /// FIXME: This is wasted space for a union.
+    CXXBaseSpecifier *Bases;
+
+    /// NumBases - The number of base class specifiers in Bases.
+    unsigned NumBases;
+
+    /// VBases - direct and indirect virtual base classes of this class.
+    CXXBaseSpecifier *VBases;
+
+    /// NumVBases - The number of virtual base class specifiers in VBases.
+    unsigned NumVBases;
+
+    /// Conversions - Overload set containing the conversion functions
+    /// of this C++ class (but not its inherited conversion
+    /// functions). Each of the entries in this overload set is a
+    /// CXXConversionDecl.
+    UnresolvedSet<4> Conversions;
+
+    /// VisibleConversions - Overload set containing the conversion
+    /// functions of this C++ class and all those inherited conversion
+    /// functions that are visible in this class. Each of the entries
+    /// in this overload set is a CXXConversionDecl or a
+    /// FunctionTemplateDecl.
+    UnresolvedSet<4> VisibleConversions;
+
+    /// Definition - The declaration which defines this record.
+    CXXRecordDecl *Definition;
+
+    /// FirstFriend - The first friend declaration in this class, or
+    /// null if there aren't any.  This is actually currently stored
+    /// in reverse order.
+    FriendDecl *FirstFriend;
+
+  } *DefinitionData;
+
+  struct DefinitionData &data() {
+    assert(DefinitionData && "queried property of class with no definition");
+    return *DefinitionData;
+  }
+
+  const struct DefinitionData &data() const {
+    assert(DefinitionData && "queried property of class with no definition");
+    return *DefinitionData;
+  }
+  
+  /// \brief The template or declaration that this declaration
+  /// describes or was instantiated from, respectively.
+  ///
+  /// For non-templates, this value will be NULL. For record
+  /// declarations that describe a class template, this will be a
+  /// pointer to a ClassTemplateDecl. For member
+  /// classes of class template specializations, this will be the
+  /// MemberSpecializationInfo referring to the member class that was 
+  /// instantiated or specialized.
+  llvm::PointerUnion<ClassTemplateDecl*, MemberSpecializationInfo*>
+    TemplateOrInstantiation;
+
+#ifndef NDEBUG
+  void CheckConversionFunction(NamedDecl *D);
+#endif
+  
+protected:
+  CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC,
+                SourceLocation L, IdentifierInfo *Id,
+                CXXRecordDecl *PrevDecl,
+                SourceLocation TKL = SourceLocation());
+
+  ~CXXRecordDecl();
+
+public:
+  /// base_class_iterator - Iterator that traverses the base classes
+  /// of a class.
+  typedef CXXBaseSpecifier*       base_class_iterator;
+
+  /// base_class_const_iterator - Iterator that traverses the base
+  /// classes of a class.
+  typedef const CXXBaseSpecifier* base_class_const_iterator;
+
+  /// reverse_base_class_iterator = Iterator that traverses the base classes
+  /// of a class in reverse order.
+  typedef std::reverse_iterator<base_class_iterator>
+    reverse_base_class_iterator;
+
+  /// reverse_base_class_iterator = Iterator that traverses the base classes
+  /// of a class in reverse order.
+  typedef std::reverse_iterator<base_class_const_iterator>
+    reverse_base_class_const_iterator;
+
+  virtual CXXRecordDecl *getCanonicalDecl() {
+    return cast<CXXRecordDecl>(RecordDecl::getCanonicalDecl());
+  }
+  virtual const CXXRecordDecl *getCanonicalDecl() const {
+    return cast<CXXRecordDecl>(RecordDecl::getCanonicalDecl());
+  }
+
+  CXXRecordDecl *getDefinition() const {
+    if (!DefinitionData) return 0;
+    return data().Definition;
+  }
+
+  bool hasDefinition() const { return DefinitionData != 0; }
+
+  static CXXRecordDecl *Create(ASTContext &C, TagKind TK, DeclContext *DC,
+                               SourceLocation L, IdentifierInfo *Id,
+                               SourceLocation TKL = SourceLocation(),
+                               CXXRecordDecl* PrevDecl=0,
+                               bool DelayTypeCreation = false);
+
+  virtual void Destroy(ASTContext& C);
+
+  bool isDynamicClass() const {
+    return data().Polymorphic || data().NumVBases != 0;
+  }
+
+  /// setBases - Sets the base classes of this struct or class.
+  void setBases(CXXBaseSpecifier const * const *Bases, unsigned NumBases);
+
+  /// getNumBases - Retrieves the number of base classes of this
+  /// class.
+  unsigned getNumBases() const { return data().NumBases; }
+
+  base_class_iterator bases_begin() { return data().Bases; }
+  base_class_const_iterator bases_begin() const { return data().Bases; }
+  base_class_iterator bases_end() { return bases_begin() + data().NumBases; }
+  base_class_const_iterator bases_end() const {
+    return bases_begin() + data().NumBases;
+  }
+  reverse_base_class_iterator       bases_rbegin() {
+    return reverse_base_class_iterator(bases_end());
+  }
+  reverse_base_class_const_iterator bases_rbegin() const {
+    return reverse_base_class_const_iterator(bases_end());
+  }
+  reverse_base_class_iterator bases_rend() {
+    return reverse_base_class_iterator(bases_begin());
+  }
+  reverse_base_class_const_iterator bases_rend() const {
+    return reverse_base_class_const_iterator(bases_begin());
+  }
+
+  /// getNumVBases - Retrieves the number of virtual base classes of this
+  /// class.
+  unsigned getNumVBases() const { return data().NumVBases; }
+
+  base_class_iterator vbases_begin() { return data().VBases; }
+  base_class_const_iterator vbases_begin() const { return data().VBases; }
+  base_class_iterator vbases_end() { return vbases_begin() + data().NumVBases; }
+  base_class_const_iterator vbases_end() const {
+    return vbases_begin() + data().NumVBases;
+  }
+  reverse_base_class_iterator vbases_rbegin() {
+    return reverse_base_class_iterator(vbases_end());
+  }
+  reverse_base_class_const_iterator vbases_rbegin() const {
+    return reverse_base_class_const_iterator(vbases_end());
+  }
+  reverse_base_class_iterator vbases_rend() {
+    return reverse_base_class_iterator(vbases_begin());
+  }
+  reverse_base_class_const_iterator vbases_rend() const {
+    return reverse_base_class_const_iterator(vbases_begin());
+ }
+
+  /// \brief Determine whether this class has any dependent base classes.
+  bool hasAnyDependentBases() const;
+
+  /// Iterator access to method members.  The method iterator visits
+  /// all method members of the class, including non-instance methods,
+  /// special methods, etc.
+  typedef specific_decl_iterator<CXXMethodDecl> method_iterator;
+
+  /// method_begin - Method begin iterator.  Iterates in the order the methods
+  /// were declared.
+  method_iterator method_begin() const {
+    return method_iterator(decls_begin());
+  }
+  /// method_end - Method end iterator.
+  method_iterator method_end() const {
+    return method_iterator(decls_end());
+  }
+
+  /// Iterator access to constructor members.
+  typedef specific_decl_iterator<CXXConstructorDecl> ctor_iterator;
+
+  ctor_iterator ctor_begin() const {
+    return ctor_iterator(decls_begin());
+  }
+  ctor_iterator ctor_end() const {
+    return ctor_iterator(decls_end());
+  }
+
+  /// An iterator over friend declarations.  All of these are defined
+  /// in DeclFriend.h.
+  class friend_iterator;
+  friend_iterator friend_begin() const;
+  friend_iterator friend_end() const;
+  void pushFriendDecl(FriendDecl *FD);
+
+  /// Determines whether this record has any friends.
+  bool hasFriends() const {
+    return data().FirstFriend != 0;
+  }
+
+  /// hasConstCopyConstructor - Determines whether this class has a
+  /// copy constructor that accepts a const-qualified argument.
+  bool hasConstCopyConstructor(ASTContext &Context) const;
+
+  /// getCopyConstructor - Returns the copy constructor for this class
+  CXXConstructorDecl *getCopyConstructor(ASTContext &Context,
+                                         unsigned TypeQuals) const;
+
+  /// hasConstCopyAssignment - Determines whether this class has a
+  /// copy assignment operator that accepts a const-qualified argument.
+  /// It returns its decl in MD if found.
+  bool hasConstCopyAssignment(ASTContext &Context,
+                              const CXXMethodDecl *&MD) const;
+
+  /// addedConstructor - Notify the class that another constructor has
+  /// been added. This routine helps maintain information about the
+  /// class based on which constructors have been added.
+  void addedConstructor(ASTContext &Context, CXXConstructorDecl *ConDecl);
+
+  /// hasUserDeclaredConstructor - Whether this class has any
+  /// user-declared constructors. When true, a default constructor
+  /// will not be implicitly declared.
+  bool hasUserDeclaredConstructor() const {
+    return data().UserDeclaredConstructor;
+  }
+
+  /// hasUserDeclaredCopyConstructor - Whether this class has a
+  /// user-declared copy constructor. When false, a copy constructor
+  /// will be implicitly declared.
+  bool hasUserDeclaredCopyConstructor() const {
+    return data().UserDeclaredCopyConstructor;
+  }
+
+  /// addedAssignmentOperator - Notify the class that another assignment
+  /// operator has been added. This routine helps maintain information about the
+   /// class based on which operators have been added.
+  void addedAssignmentOperator(ASTContext &Context, CXXMethodDecl *OpDecl);
+
+  /// hasUserDeclaredCopyAssignment - Whether this class has a
+  /// user-declared copy assignment operator. When false, a copy
+  /// assigment operator will be implicitly declared.
+  bool hasUserDeclaredCopyAssignment() const {
+    return data().UserDeclaredCopyAssignment;
+  }
+
+  /// hasUserDeclaredDestructor - Whether this class has a
+  /// user-declared destructor. When false, a destructor will be
+  /// implicitly declared.
+  bool hasUserDeclaredDestructor() const {
+    return data().UserDeclaredDestructor;
+  }
+
+  /// setUserDeclaredDestructor - Set whether this class has a
+  /// user-declared destructor. If not set by the time the class is
+  /// fully defined, a destructor will be implicitly declared.
+  void setUserDeclaredDestructor(bool UCD) {
+    data().UserDeclaredDestructor = UCD;
+  }
+
+  /// getConversions - Retrieve the overload set containing all of the
+  /// conversion functions in this class.
+  UnresolvedSetImpl *getConversionFunctions() {
+    return &data().Conversions;
+  }
+  const UnresolvedSetImpl *getConversionFunctions() const {
+    return &data().Conversions;
+  }
+
+  typedef UnresolvedSetImpl::iterator conversion_iterator;
+  conversion_iterator conversion_begin() const {
+    return getConversionFunctions()->begin();
+  }
+  conversion_iterator conversion_end() const {
+    return getConversionFunctions()->end();
+  }
+
+  /// Replaces a conversion function with a new declaration.
+  ///
+  /// Returns true if the old conversion was found.
+  bool replaceConversion(const NamedDecl* Old, NamedDecl *New) {
+    return getConversionFunctions()->replace(Old, New);
+  }
+
+  /// Removes a conversion function from this class.  The conversion
+  /// function must currently be a member of this class.  Furthermore,
+  /// this class must currently be in the process of being defined.
+  void removeConversion(const NamedDecl *Old);
+
+  /// getVisibleConversionFunctions - get all conversion functions visible
+  /// in current class; including conversion function templates.
+  const UnresolvedSetImpl *getVisibleConversionFunctions();
+
+  /// addConversionFunction - Registers a conversion function which
+  /// this class declares directly.
+  void addConversionFunction(NamedDecl *Decl) {
+#ifndef NDEBUG
+    CheckConversionFunction(Decl);
+#endif
+
+    // We intentionally don't use the decl's access here because it
+    // hasn't been set yet.  That's really just a misdesign in Sema.
+    data().Conversions.addDecl(Decl);
+  }
+
+  /// isAggregate - Whether this class is an aggregate (C++
+  /// [dcl.init.aggr]), which is a class with no user-declared
+  /// constructors, no private or protected non-static data members,
+  /// no base classes, and no virtual functions (C++ [dcl.init.aggr]p1).
+  bool isAggregate() const { return data().Aggregate; }
+
+  /// setAggregate - Set whether this class is an aggregate (C++
+  /// [dcl.init.aggr]).
+  void setAggregate(bool Agg) { data().Aggregate = Agg; }
+
+  /// setMethodAsVirtual - Make input method virtual and set the necesssary 
+  /// special function bits and other bits accordingly.
+  void setMethodAsVirtual(FunctionDecl *Method);
+
+  /// isPOD - Whether this class is a POD-type (C++ [class]p4), which is a class
+  /// that is an aggregate that has no non-static non-POD data members, no
+  /// reference data members, no user-defined copy assignment operator and no
+  /// user-defined destructor.
+  bool isPOD() const { return data().PlainOldData; }
+
+  /// setPOD - Set whether this class is a POD-type (C++ [class]p4).
+  void setPOD(bool POD) { data().PlainOldData = POD; }
+
+  /// isEmpty - Whether this class is empty (C++0x [meta.unary.prop]), which
+  /// means it has a virtual function, virtual base, data member (other than
+  /// 0-width bit-field) or inherits from a non-empty class. Does NOT include
+  /// a check for union-ness.
+  bool isEmpty() const { return data().Empty; }
+
+  /// Set whether this class is empty (C++0x [meta.unary.prop])
+  void setEmpty(bool Emp) { data().Empty = Emp; }
+
+  /// isPolymorphic - Whether this class is polymorphic (C++ [class.virtual]),
+  /// which means that the class contains or inherits a virtual function.
+  bool isPolymorphic() const { return data().Polymorphic; }
+
+  /// setPolymorphic - Set whether this class is polymorphic (C++
+  /// [class.virtual]).
+  void setPolymorphic(bool Poly) { data().Polymorphic = Poly; }
+
+  /// isAbstract - Whether this class is abstract (C++ [class.abstract]),
+  /// which means that the class contains or inherits a pure virtual function.
+  bool isAbstract() const { return data().Abstract; }
+
+  /// setAbstract - Set whether this class is abstract (C++ [class.abstract])
+  void setAbstract(bool Abs) { data().Abstract = Abs; }
+
+  // hasTrivialConstructor - Whether this class has a trivial constructor
+  // (C++ [class.ctor]p5)
+  bool hasTrivialConstructor() const { return data().HasTrivialConstructor; }
+
+  // setHasTrivialConstructor - Set whether this class has a trivial constructor
+  // (C++ [class.ctor]p5)
+  void setHasTrivialConstructor(bool TC) { data().HasTrivialConstructor = TC; }
+
+  // hasTrivialCopyConstructor - Whether this class has a trivial copy
+  // constructor (C++ [class.copy]p6)
+  bool hasTrivialCopyConstructor() const {
+    return data().HasTrivialCopyConstructor;
+  }
+
+  // setHasTrivialCopyConstructor - Set whether this class has a trivial
+  // copy constructor (C++ [class.copy]p6)
+  void setHasTrivialCopyConstructor(bool TC) {
+    data().HasTrivialCopyConstructor = TC;
+  }
+
+  // hasTrivialCopyAssignment - Whether this class has a trivial copy
+  // assignment operator (C++ [class.copy]p11)
+  bool hasTrivialCopyAssignment() const {
+    return data().HasTrivialCopyAssignment;
+  }
+
+  // setHasTrivialCopyAssignment - Set whether this class has a
+  // trivial copy assignment operator (C++ [class.copy]p11)
+  void setHasTrivialCopyAssignment(bool TC) {
+    data().HasTrivialCopyAssignment = TC;
+  }
+
+  // hasTrivialDestructor - Whether this class has a trivial destructor
+  // (C++ [class.dtor]p3)
+  bool hasTrivialDestructor() const { return data().HasTrivialDestructor; }
+
+  // setHasTrivialDestructor - Set whether this class has a trivial destructor
+  // (C++ [class.dtor]p3)
+  void setHasTrivialDestructor(bool TC) { data().HasTrivialDestructor = TC; }
+
+  /// \brief If this record is an instantiation of a member class,
+  /// retrieves the member class from which it was instantiated.
+  ///
+  /// This routine will return non-NULL for (non-templated) member
+  /// classes of class templates. For example, given:
+  ///
+  /// \code
+  /// template<typename T>
+  /// struct X {
+  ///   struct A { };
+  /// };
+  /// \endcode
+  ///
+  /// The declaration for X<int>::A is a (non-templated) CXXRecordDecl
+  /// whose parent is the class template specialization X<int>. For
+  /// this declaration, getInstantiatedFromMemberClass() will return
+  /// the CXXRecordDecl X<T>::A. When a complete definition of
+  /// X<int>::A is required, it will be instantiated from the
+  /// declaration returned by getInstantiatedFromMemberClass().
+  CXXRecordDecl *getInstantiatedFromMemberClass() const;
+  
+  /// \brief If this class is an instantiation of a member class of a
+  /// class template specialization, retrieves the member specialization
+  /// information.
+  MemberSpecializationInfo *getMemberSpecializationInfo() const;
+  
+  /// \brief Specify that this record is an instantiation of the
+  /// member class RD.
+  void setInstantiationOfMemberClass(CXXRecordDecl *RD,
+                                     TemplateSpecializationKind TSK);
+
+  /// \brief Retrieves the class template that is described by this
+  /// class declaration.
+  ///
+  /// Every class template is represented as a ClassTemplateDecl and a
+  /// CXXRecordDecl. The former contains template properties (such as
+  /// the template parameter lists) while the latter contains the
+  /// actual description of the template's
+  /// contents. ClassTemplateDecl::getTemplatedDecl() retrieves the
+  /// CXXRecordDecl that from a ClassTemplateDecl, while
+  /// getDescribedClassTemplate() retrieves the ClassTemplateDecl from
+  /// a CXXRecordDecl.
+  ClassTemplateDecl *getDescribedClassTemplate() const {
+    return TemplateOrInstantiation.dyn_cast<ClassTemplateDecl*>();
+  }
+
+  void setDescribedClassTemplate(ClassTemplateDecl *Template) {
+    TemplateOrInstantiation = Template;
+  }
+
+  /// \brief Determine whether this particular class is a specialization or
+  /// instantiation of a class template or member class of a class template,
+  /// and how it was instantiated or specialized.
+  TemplateSpecializationKind getTemplateSpecializationKind() const;
+  
+  /// \brief Set the kind of specialization or template instantiation this is.
+  void setTemplateSpecializationKind(TemplateSpecializationKind TSK);
+  
+  /// getDefaultConstructor - Returns the default constructor for this class
+  CXXConstructorDecl *getDefaultConstructor(ASTContext &Context);
+
+  /// getDestructor - Returns the destructor decl for this class.
+  CXXDestructorDecl *getDestructor(ASTContext &Context) const;
+
+  /// isLocalClass - If the class is a local class [class.local], returns
+  /// the enclosing function declaration.
+  const FunctionDecl *isLocalClass() const {
+    if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(getDeclContext()))
+      return RD->isLocalClass();
+
+    return dyn_cast<FunctionDecl>(getDeclContext());
+  }
+
+  /// \brief Determine whether this class is derived from the class \p Base.
+  ///
+  /// This routine only determines whether this class is derived from \p Base,
+  /// but does not account for factors that may make a Derived -> Base class
+  /// ill-formed, such as private/protected inheritance or multiple, ambiguous
+  /// base class subobjects.
+  ///
+  /// \param Base the base class we are searching for.
+  ///
+  /// \returns true if this class is derived from Base, false otherwise.
+  bool isDerivedFrom(CXXRecordDecl *Base) const;
+  
+  /// \brief Determine whether this class is derived from the type \p Base.
+  ///
+  /// This routine only determines whether this class is derived from \p Base,
+  /// but does not account for factors that may make a Derived -> Base class
+  /// ill-formed, such as private/protected inheritance or multiple, ambiguous
+  /// base class subobjects.
+  ///
+  /// \param Base the base class we are searching for.
+  ///
+  /// \param Paths will contain the paths taken from the current class to the
+  /// given \p Base class.
+  ///
+  /// \returns true if this class is derived from Base, false otherwise.
+  ///
+  /// \todo add a separate paramaeter to configure IsDerivedFrom, rather than 
+  /// tangling input and output in \p Paths  
+  bool isDerivedFrom(CXXRecordDecl *Base, CXXBasePaths &Paths) const;
+
+  /// \brief Determine whether this class is virtually derived from
+  /// the class \p Base.
+  ///
+  /// This routine only determines whether this class is virtually
+  /// derived from \p Base, but does not account for factors that may
+  /// make a Derived -> Base class ill-formed, such as
+  /// private/protected inheritance or multiple, ambiguous base class
+  /// subobjects.
+  ///
+  /// \param Base the base class we are searching for.
+  ///
+  /// \returns true if this class is virtually derived from Base,
+  /// false otherwise.
+  bool isVirtuallyDerivedFrom(CXXRecordDecl *Base) const;
+
+  /// \brief Determine whether this class is provably not derived from
+  /// the type \p Base.
+  bool isProvablyNotDerivedFrom(const CXXRecordDecl *Base) const;
+
+  /// \brief Function type used by forallBases() as a callback.
+  ///
+  /// \param Base the definition of the base class
+  ///
+  /// \returns true if this base matched the search criteria
+  typedef bool ForallBasesCallback(const CXXRecordDecl *BaseDefinition,
+                                   void *UserData);
+
+  /// \brief Determines if the given callback holds for all the direct
+  /// or indirect base classes of this type.
+  ///
+  /// The class itself does not count as a base class.  This routine
+  /// returns false if the class has non-computable base classes.
+  /// 
+  /// \param AllowShortCircuit if false, forces the callback to be called
+  /// for every base class, even if a dependent or non-matching base was
+  /// found.
+  bool forallBases(ForallBasesCallback *BaseMatches, void *UserData,
+                   bool AllowShortCircuit = true) const;
+  
+  /// \brief Function type used by lookupInBases() to determine whether a 
+  /// specific base class subobject matches the lookup criteria.
+  ///
+  /// \param Specifier the base-class specifier that describes the inheritance 
+  /// from the base class we are trying to match.
+  ///
+  /// \param Path the current path, from the most-derived class down to the 
+  /// base named by the \p Specifier.
+  ///
+  /// \param UserData a single pointer to user-specified data, provided to
+  /// lookupInBases().
+  ///
+  /// \returns true if this base matched the search criteria, false otherwise.
+  typedef bool BaseMatchesCallback(const CXXBaseSpecifier *Specifier,
+                                   CXXBasePath &Path,
+                                   void *UserData);
+  
+  /// \brief Look for entities within the base classes of this C++ class,
+  /// transitively searching all base class subobjects.
+  ///
+  /// This routine uses the callback function \p BaseMatches to find base 
+  /// classes meeting some search criteria, walking all base class subobjects
+  /// and populating the given \p Paths structure with the paths through the 
+  /// inheritance hierarchy that resulted in a match. On a successful search,
+  /// the \p Paths structure can be queried to retrieve the matching paths and
+  /// to determine if there were any ambiguities.
+  ///
+  /// \param BaseMatches callback function used to determine whether a given
+  /// base matches the user-defined search criteria.
+  ///
+  /// \param UserData user data pointer that will be provided to \p BaseMatches.
+  ///
+  /// \param Paths used to record the paths from this class to its base class
+  /// subobjects that match the search criteria.
+  ///
+  /// \returns true if there exists any path from this class to a base class
+  /// subobject that matches the search criteria.
+  bool lookupInBases(BaseMatchesCallback *BaseMatches, void *UserData,
+                     CXXBasePaths &Paths) const;
+  
+  /// \brief Base-class lookup callback that determines whether the given
+  /// base class specifier refers to a specific class declaration.
+  ///
+  /// This callback can be used with \c lookupInBases() to determine whether
+  /// a given derived class has is a base class subobject of a particular type.
+  /// The user data pointer should refer to the canonical CXXRecordDecl of the
+  /// base class that we are searching for.
+  static bool FindBaseClass(const CXXBaseSpecifier *Specifier,
+                            CXXBasePath &Path, void *BaseRecord);
+
+  /// \brief Base-class lookup callback that determines whether the
+  /// given base class specifier refers to a specific class
+  /// declaration and describes virtual derivation.
+  ///
+  /// This callback can be used with \c lookupInBases() to determine
+  /// whether a given derived class has is a virtual base class
+  /// subobject of a particular type.  The user data pointer should
+  /// refer to the canonical CXXRecordDecl of the base class that we
+  /// are searching for.
+  static bool FindVirtualBaseClass(const CXXBaseSpecifier *Specifier,
+                                   CXXBasePath &Path, void *BaseRecord);
+  
+  /// \brief Base-class lookup callback that determines whether there exists
+  /// a tag with the given name.
+  ///
+  /// This callback can be used with \c lookupInBases() to find tag members
+  /// of the given name within a C++ class hierarchy. The user data pointer
+  /// is an opaque \c DeclarationName pointer.
+  static bool FindTagMember(const CXXBaseSpecifier *Specifier,
+                            CXXBasePath &Path, void *Name);
+
+  /// \brief Base-class lookup callback that determines whether there exists
+  /// a member with the given name.
+  ///
+  /// This callback can be used with \c lookupInBases() to find members
+  /// of the given name within a C++ class hierarchy. The user data pointer
+  /// is an opaque \c DeclarationName pointer.
+  static bool FindOrdinaryMember(const CXXBaseSpecifier *Specifier,
+                                 CXXBasePath &Path, void *Name);
+  
+  /// \brief Base-class lookup callback that determines whether there exists
+  /// a member with the given name that can be used in a nested-name-specifier.
+  ///
+  /// This callback can be used with \c lookupInBases() to find membes of
+  /// the given name within a C++ class hierarchy that can occur within
+  /// nested-name-specifiers.
+  static bool FindNestedNameSpecifierMember(const CXXBaseSpecifier *Specifier,
+                                            CXXBasePath &Path,
+                                            void *UserData);
+
+  /// \brief Retrieve the final overriders for each virtual member
+  /// function in the class hierarchy where this class is the
+  /// most-derived class in the class hierarchy.
+  void getFinalOverriders(CXXFinalOverriderMap &FinaOverriders) const;
+
+  /// viewInheritance - Renders and displays an inheritance diagram
+  /// for this C++ class and all of its base classes (transitively) using
+  /// GraphViz.
+  void viewInheritance(ASTContext& Context) const;
+
+  /// MergeAccess - Calculates the access of a decl that is reached
+  /// along a path.
+  static AccessSpecifier MergeAccess(AccessSpecifier PathAccess,
+                                     AccessSpecifier DeclAccess) {
+    assert(DeclAccess != AS_none);
+    if (DeclAccess == AS_private) return AS_none;
+    return (PathAccess > DeclAccess ? PathAccess : DeclAccess);
+  }
+
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) {
+    return K == CXXRecord ||
+           K == ClassTemplateSpecialization ||
+           K == ClassTemplatePartialSpecialization;
+  }
+  static bool classof(const CXXRecordDecl *D) { return true; }
+  static bool classof(const ClassTemplateSpecializationDecl *D) {
+    return true;
+  }
+};
+
+/// CXXMethodDecl - Represents a static or instance method of a
+/// struct/union/class.
+class CXXMethodDecl : public FunctionDecl {
+protected:
+  CXXMethodDecl(Kind DK, CXXRecordDecl *RD, SourceLocation L,
+                DeclarationName N, QualType T, TypeSourceInfo *TInfo,
+                bool isStatic, StorageClass SCAsWritten, bool isInline)
+    : FunctionDecl(DK, RD, L, N, T, TInfo, (isStatic ? Static : None),
+                   SCAsWritten, isInline) {}
+
+public:
+  static CXXMethodDecl *Create(ASTContext &C, CXXRecordDecl *RD,
+                              SourceLocation L, DeclarationName N,
+                              QualType T, TypeSourceInfo *TInfo,
+                              bool isStatic = false,
+                              StorageClass SCAsWritten = FunctionDecl::None,
+                              bool isInline = false);
+
+  bool isStatic() const { return getStorageClass() == Static; }
+  bool isInstance() const { return !isStatic(); }
+
+  bool isVirtual() const {
+    CXXMethodDecl *CD = 
+      cast<CXXMethodDecl>(const_cast<CXXMethodDecl*>(this)->getCanonicalDecl());
+
+    if (CD->isVirtualAsWritten())
+      return true;
+    
+    return (CD->begin_overridden_methods() != CD->end_overridden_methods());
+  }
+
+  /// \brief Determine whether this is a usual deallocation function
+  /// (C++ [basic.stc.dynamic.deallocation]p2), which is an overloaded
+  /// delete or delete[] operator with a particular signature.
+  bool isUsualDeallocationFunction() const;
+  
+  const CXXMethodDecl *getCanonicalDecl() const {
+    return cast<CXXMethodDecl>(FunctionDecl::getCanonicalDecl());
+  }
+  CXXMethodDecl *getCanonicalDecl() {
+    return cast<CXXMethodDecl>(FunctionDecl::getCanonicalDecl());
+  }
+  
+  ///
+  void addOverriddenMethod(const CXXMethodDecl *MD);
+
+  typedef const CXXMethodDecl ** method_iterator;
+
+  method_iterator begin_overridden_methods() const;
+  method_iterator end_overridden_methods() const;
+
+  /// getParent - Returns the parent of this method declaration, which
+  /// is the class in which this method is defined.
+  const CXXRecordDecl *getParent() const {
+    return cast<CXXRecordDecl>(FunctionDecl::getParent());
+  }
+
+  /// getParent - Returns the parent of this method declaration, which
+  /// is the class in which this method is defined.
+  CXXRecordDecl *getParent() {
+    return const_cast<CXXRecordDecl *>(
+             cast<CXXRecordDecl>(FunctionDecl::getParent()));
+  }
+
+  /// getThisType - Returns the type of 'this' pointer.
+  /// Should only be called for instance methods.
+  QualType getThisType(ASTContext &C) const;
+
+  unsigned getTypeQualifiers() const {
+    return getType()->getAs<FunctionProtoType>()->getTypeQuals();
+  }
+
+  bool hasInlineBody() const;
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classof(const CXXMethodDecl *D) { return true; }
+  static bool classofKind(Kind K) {
+    return K >= CXXMethod && K <= CXXConversion;
+  }
+};
+
+/// CXXBaseOrMemberInitializer - Represents a C++ base or member
+/// initializer, which is part of a constructor initializer that
+/// initializes one non-static member variable or one base class. For
+/// example, in the following, both 'A(a)' and 'f(3.14159)' are member
+/// initializers:
+///
+/// @code
+/// class A { };
+/// class B : public A {
+///   float f;
+/// public:
+///   B(A& a) : A(a), f(3.14159) { }
+/// };
+/// @endcode
+class CXXBaseOrMemberInitializer {
+  /// \brief Either the base class name (stored as a TypeSourceInfo*) or the
+  /// field being initialized.
+  llvm::PointerUnion<TypeSourceInfo *, FieldDecl *> BaseOrMember;
+  
+  /// \brief The source location for the field name.
+  SourceLocation MemberLocation;
+  
+  /// \brief The argument used to initialize the base or member, which may
+  /// end up constructing an object (when multiple arguments are involved).
+  Stmt *Init;
+
+  /// \brief Stores either the constructor to call to initialize this base or
+  /// member (a CXXConstructorDecl pointer), or stores the anonymous union of
+  /// which the initialized value is a member.
+  ///
+  /// When the value is a FieldDecl pointer, 'BaseOrMember' is class's
+  /// anonymous union data member, this field holds the FieldDecl for the
+  /// member of the anonymous union being initialized.
+  /// @code
+  /// struct X {
+  ///   X() : au_i1(123) {}
+  ///   union {
+  ///     int au_i1;
+  ///     float au_f1;
+  ///   };
+  /// };
+  /// @endcode
+  /// In above example, BaseOrMember holds the field decl. for anonymous union
+  /// and AnonUnionMember holds field decl for au_i1.
+  FieldDecl *AnonUnionMember;
+
+  /// IsVirtual - If the initializer is a base initializer, this keeps track
+  /// of whether the base is virtual or not.
+  bool IsVirtual;
+  
+  /// LParenLoc - Location of the left paren of the ctor-initializer.
+  SourceLocation LParenLoc;
+
+  /// RParenLoc - Location of the right paren of the ctor-initializer.
+  SourceLocation RParenLoc;
+
+public:
+  /// CXXBaseOrMemberInitializer - Creates a new base-class initializer.
+  explicit
+  CXXBaseOrMemberInitializer(ASTContext &Context,
+                             TypeSourceInfo *TInfo, bool IsVirtual,
+                             SourceLocation L, 
+                             Expr *Init,
+                             SourceLocation R);
+
+  /// CXXBaseOrMemberInitializer - Creates a new member initializer.
+  explicit
+  CXXBaseOrMemberInitializer(ASTContext &Context,
+                             FieldDecl *Member, SourceLocation MemberLoc,
+                             SourceLocation L,
+                             Expr *Init,
+                             SourceLocation R);
+
+  /// \brief Destroy the base or member initializer.
+  void Destroy(ASTContext &Context);
+
+  /// isBaseInitializer - Returns true when this initializer is
+  /// initializing a base class.
+  bool isBaseInitializer() const { return BaseOrMember.is<TypeSourceInfo*>(); }
+
+  /// isMemberInitializer - Returns true when this initializer is
+  /// initializing a non-static data member.
+  bool isMemberInitializer() const { return BaseOrMember.is<FieldDecl*>(); }
+
+  /// If this is a base class initializer, returns the type of the 
+  /// base class with location information. Otherwise, returns an NULL
+  /// type location.
+  TypeLoc getBaseClassLoc() const;
+
+  /// If this is a base class initializer, returns the type of the base class.
+  /// Otherwise, returns NULL.
+  const Type *getBaseClass() const;
+  Type *getBaseClass();
+
+  /// Returns whether the base is virtual or not.
+  bool isBaseVirtual() const {
+    assert(isBaseInitializer() && "Must call this on base initializer!");
+    
+    return IsVirtual;
+  }
+
+  /// \brief Returns the declarator information for a base class initializer.
+  TypeSourceInfo *getBaseClassInfo() const {
+    return BaseOrMember.dyn_cast<TypeSourceInfo *>();
+  }
+  
+  /// getMember - If this is a member initializer, returns the
+  /// declaration of the non-static data member being
+  /// initialized. Otherwise, returns NULL.
+  FieldDecl *getMember() {
+    if (isMemberInitializer())
+      return BaseOrMember.get<FieldDecl*>();
+    else
+      return 0;
+  }
+
+  SourceLocation getMemberLocation() const { 
+    return MemberLocation;
+  }
+
+  void setMember(FieldDecl *Member) {
+    assert(isMemberInitializer());
+    BaseOrMember = Member;
+  }
+  
+  /// \brief Determine the source location of the initializer.
+  SourceLocation getSourceLocation() const;
+  
+  /// \brief Determine the source range covering the entire initializer.
+  SourceRange getSourceRange() const;
+  
+  FieldDecl *getAnonUnionMember() const {
+    return AnonUnionMember;
+  }
+  void setAnonUnionMember(FieldDecl *anonMember) {
+    AnonUnionMember = anonMember;
+  }
+
+  SourceLocation getLParenLoc() const { return LParenLoc; }
+  SourceLocation getRParenLoc() const { return RParenLoc; }
+
+  Expr *getInit() { return static_cast<Expr *>(Init); }
+};
+
+/// CXXConstructorDecl - Represents a C++ constructor within a
+/// class. For example:
+///
+/// @code
+/// class X {
+/// public:
+///   explicit X(int); // represented by a CXXConstructorDecl.
+/// };
+/// @endcode
+class CXXConstructorDecl : public CXXMethodDecl {
+  /// IsExplicitSpecified - Whether this constructor declaration has the
+  /// 'explicit' keyword specified.
+  bool IsExplicitSpecified : 1;
+
+  /// ImplicitlyDefined - Whether this constructor was implicitly
+  /// defined by the compiler. When false, the constructor was defined
+  /// by the user. In C++03, this flag will have the same value as
+  /// Implicit. In C++0x, however, a constructor that is
+  /// explicitly defaulted (i.e., defined with " = default") will have
+  /// @c !Implicit && ImplicitlyDefined.
+  bool ImplicitlyDefined : 1;
+
+  /// Support for base and member initializers.
+  /// BaseOrMemberInitializers - The arguments used to initialize the base
+  /// or member.
+  CXXBaseOrMemberInitializer **BaseOrMemberInitializers;
+  unsigned NumBaseOrMemberInitializers;
+
+  CXXConstructorDecl(CXXRecordDecl *RD, SourceLocation L,
+                     DeclarationName N, QualType T, TypeSourceInfo *TInfo,
+                     bool isExplicitSpecified, bool isInline, 
+                     bool isImplicitlyDeclared)
+    : CXXMethodDecl(CXXConstructor, RD, L, N, T, TInfo, false,
+                    FunctionDecl::None, isInline),
+      IsExplicitSpecified(isExplicitSpecified), ImplicitlyDefined(false),
+      BaseOrMemberInitializers(0), NumBaseOrMemberInitializers(0) {
+    setImplicit(isImplicitlyDeclared);
+  }
+  virtual void Destroy(ASTContext& C);
+
+public:
+  static CXXConstructorDecl *Create(ASTContext &C, CXXRecordDecl *RD,
+                                    SourceLocation L, DeclarationName N,
+                                    QualType T, TypeSourceInfo *TInfo,
+                                    bool isExplicit,
+                                    bool isInline, bool isImplicitlyDeclared);
+
+  /// isExplicitSpecified - Whether this constructor declaration has the
+  /// 'explicit' keyword specified.
+  bool isExplicitSpecified() const { return IsExplicitSpecified; }
+  
+  /// isExplicit - Whether this constructor was marked "explicit" or not.
+  bool isExplicit() const {
+    return cast<CXXConstructorDecl>(getFirstDeclaration())
+      ->isExplicitSpecified();
+  }
+
+  /// isImplicitlyDefined - Whether this constructor was implicitly
+  /// defined. If false, then this constructor was defined by the
+  /// user. This operation can only be invoked if the constructor has
+  /// already been defined.
+  bool isImplicitlyDefined() const {
+    assert(isThisDeclarationADefinition() &&
+           "Can only get the implicit-definition flag once the "
+           "constructor has been defined");
+    return ImplicitlyDefined;
+  }
+
+  /// setImplicitlyDefined - Set whether this constructor was
+  /// implicitly defined or not.
+  void setImplicitlyDefined(bool ID) {
+    assert(isThisDeclarationADefinition() &&
+           "Can only set the implicit-definition flag once the constructor "
+           "has been defined");
+    ImplicitlyDefined = ID;
+  }
+
+  /// init_iterator - Iterates through the member/base initializer list.
+  typedef CXXBaseOrMemberInitializer **init_iterator;
+
+  /// init_const_iterator - Iterates through the memberbase initializer list.
+  typedef CXXBaseOrMemberInitializer * const * init_const_iterator;
+
+  /// init_begin() - Retrieve an iterator to the first initializer.
+  init_iterator       init_begin()       { return BaseOrMemberInitializers; }
+  /// begin() - Retrieve an iterator to the first initializer.
+  init_const_iterator init_begin() const { return BaseOrMemberInitializers; }
+
+  /// init_end() - Retrieve an iterator past the last initializer.
+  init_iterator       init_end()       {
+    return BaseOrMemberInitializers + NumBaseOrMemberInitializers;
+  }
+  /// end() - Retrieve an iterator past the last initializer.
+  init_const_iterator init_end() const {
+    return BaseOrMemberInitializers + NumBaseOrMemberInitializers;
+  }
+
+  /// getNumArgs - Determine the number of arguments used to
+  /// initialize the member or base.
+  unsigned getNumBaseOrMemberInitializers() const {
+      return NumBaseOrMemberInitializers;
+  }
+
+  void setNumBaseOrMemberInitializers(unsigned numBaseOrMemberInitializers) {
+    NumBaseOrMemberInitializers = numBaseOrMemberInitializers;
+  }
+
+  void setBaseOrMemberInitializers(CXXBaseOrMemberInitializer ** initializers) {
+    BaseOrMemberInitializers = initializers;
+  }
+  /// isDefaultConstructor - Whether this constructor is a default
+  /// constructor (C++ [class.ctor]p5), which can be used to
+  /// default-initialize a class of this type.
+  bool isDefaultConstructor() const;
+
+  /// isCopyConstructor - Whether this constructor is a copy
+  /// constructor (C++ [class.copy]p2, which can be used to copy the
+  /// class. @p TypeQuals will be set to the qualifiers on the
+  /// argument type. For example, @p TypeQuals would be set to @c
+  /// QualType::Const for the following copy constructor:
+  ///
+  /// @code
+  /// class X {
+  /// public:
+  ///   X(const X&);
+  /// };
+  /// @endcode
+  bool isCopyConstructor(unsigned &TypeQuals) const;
+
+  /// isCopyConstructor - Whether this constructor is a copy
+  /// constructor (C++ [class.copy]p2, which can be used to copy the
+  /// class.
+  bool isCopyConstructor() const {
+    unsigned TypeQuals = 0;
+    return isCopyConstructor(TypeQuals);
+  }
+
+  /// isConvertingConstructor - Whether this constructor is a
+  /// converting constructor (C++ [class.conv.ctor]), which can be
+  /// used for user-defined conversions.
+  bool isConvertingConstructor(bool AllowExplicit) const;
+
+  /// \brief Determine whether this is a member template specialization that
+  /// looks like a copy constructor. Such constructors are never used to copy
+  /// an object.
+  bool isCopyConstructorLikeSpecialization() const;
+  
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classof(const CXXConstructorDecl *D) { return true; }
+  static bool classofKind(Kind K) { return K == CXXConstructor; }
+};
+
+/// CXXDestructorDecl - Represents a C++ destructor within a
+/// class. For example:
+///
+/// @code
+/// class X {
+/// public:
+///   ~X(); // represented by a CXXDestructorDecl.
+/// };
+/// @endcode
+class CXXDestructorDecl : public CXXMethodDecl {
+  /// ImplicitlyDefined - Whether this destructor was implicitly
+  /// defined by the compiler. When false, the destructor was defined
+  /// by the user. In C++03, this flag will have the same value as
+  /// Implicit. In C++0x, however, a destructor that is
+  /// explicitly defaulted (i.e., defined with " = default") will have
+  /// @c !Implicit && ImplicitlyDefined.
+  bool ImplicitlyDefined : 1;
+
+  FunctionDecl *OperatorDelete;
+  
+  CXXDestructorDecl(CXXRecordDecl *RD, SourceLocation L,
+                    DeclarationName N, QualType T,
+                    bool isInline, bool isImplicitlyDeclared)
+    : CXXMethodDecl(CXXDestructor, RD, L, N, T, /*TInfo=*/0, false,
+                    FunctionDecl::None, isInline),
+      ImplicitlyDefined(false), OperatorDelete(0) {
+    setImplicit(isImplicitlyDeclared);
+  }
+
+public:
+  static CXXDestructorDecl *Create(ASTContext &C, CXXRecordDecl *RD,
+                                   SourceLocation L, DeclarationName N,
+                                   QualType T, bool isInline,
+                                   bool isImplicitlyDeclared);
+
+  /// isImplicitlyDefined - Whether this destructor was implicitly
+  /// defined. If false, then this destructor was defined by the
+  /// user. This operation can only be invoked if the destructor has
+  /// already been defined.
+  bool isImplicitlyDefined() const {
+    assert(isThisDeclarationADefinition() &&
+           "Can only get the implicit-definition flag once the destructor has been defined");
+    return ImplicitlyDefined;
+  }
+
+  /// setImplicitlyDefined - Set whether this destructor was
+  /// implicitly defined or not.
+  void setImplicitlyDefined(bool ID) {
+    assert(isThisDeclarationADefinition() &&
+           "Can only set the implicit-definition flag once the destructor has been defined");
+    ImplicitlyDefined = ID;
+  }
+
+  void setOperatorDelete(FunctionDecl *OD) { OperatorDelete = OD; }
+  const FunctionDecl *getOperatorDelete() const { return OperatorDelete; }
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classof(const CXXDestructorDecl *D) { return true; }
+  static bool classofKind(Kind K) { return K == CXXDestructor; }
+};
+
+/// CXXConversionDecl - Represents a C++ conversion function within a
+/// class. For example:
+///
+/// @code
+/// class X {
+/// public:
+///   operator bool();
+/// };
+/// @endcode
+class CXXConversionDecl : public CXXMethodDecl {
+  /// IsExplicitSpecified - Whether this conversion function declaration is 
+  /// marked "explicit", meaning that it can only be applied when the user
+  /// explicitly wrote a cast. This is a C++0x feature.
+  bool IsExplicitSpecified : 1;
+
+  CXXConversionDecl(CXXRecordDecl *RD, SourceLocation L,
+                    DeclarationName N, QualType T, TypeSourceInfo *TInfo,
+                    bool isInline, bool isExplicitSpecified)
+    : CXXMethodDecl(CXXConversion, RD, L, N, T, TInfo, false,
+                    FunctionDecl::None, isInline),
+      IsExplicitSpecified(isExplicitSpecified) { }
+
+public:
+  static CXXConversionDecl *Create(ASTContext &C, CXXRecordDecl *RD,
+                                   SourceLocation L, DeclarationName N,
+                                   QualType T, TypeSourceInfo *TInfo,
+                                   bool isInline, bool isExplicit);
+
+  /// IsExplicitSpecified - Whether this conversion function declaration is 
+  /// marked "explicit", meaning that it can only be applied when the user
+  /// explicitly wrote a cast. This is a C++0x feature.
+  bool isExplicitSpecified() const { return IsExplicitSpecified; }
+
+  /// isExplicit - Whether this is an explicit conversion operator
+  /// (C++0x only). Explicit conversion operators are only considered
+  /// when the user has explicitly written a cast.
+  bool isExplicit() const {
+    return cast<CXXConversionDecl>(getFirstDeclaration())
+      ->isExplicitSpecified();
+  }
+
+  /// getConversionType - Returns the type that this conversion
+  /// function is converting to.
+  QualType getConversionType() const {
+    return getType()->getAs<FunctionType>()->getResultType();
+  }
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classof(const CXXConversionDecl *D) { return true; }
+  static bool classofKind(Kind K) { return K == CXXConversion; }
+};
+
+/// LinkageSpecDecl - This represents a linkage specification.  For example:
+///   extern "C" void foo();
+///
+class LinkageSpecDecl : public Decl, public DeclContext {
+public:
+  /// LanguageIDs - Used to represent the language in a linkage
+  /// specification.  The values are part of the serialization abi for
+  /// ASTs and cannot be changed without altering that abi.  To help
+  /// ensure a stable abi for this, we choose the DW_LANG_ encodings
+  /// from the dwarf standard.
+  enum LanguageIDs { lang_c = /* DW_LANG_C */ 0x0002,
+  lang_cxx = /* DW_LANG_C_plus_plus */ 0x0004 };
+private:
+  /// Language - The language for this linkage specification.
+  LanguageIDs Language;
+
+  /// HadBraces - Whether this linkage specification had curly braces or not.
+  bool HadBraces : 1;
+
+  LinkageSpecDecl(DeclContext *DC, SourceLocation L, LanguageIDs lang,
+                  bool Braces)
+    : Decl(LinkageSpec, DC, L),
+      DeclContext(LinkageSpec), Language(lang), HadBraces(Braces) { }
+
+public:
+  static LinkageSpecDecl *Create(ASTContext &C, DeclContext *DC,
+                                 SourceLocation L, LanguageIDs Lang,
+                                 bool Braces);
+
+  LanguageIDs getLanguage() const { return Language; }
+
+  /// hasBraces - Determines whether this linkage specification had
+  /// braces in its syntactic form.
+  bool hasBraces() const { return HadBraces; }
+
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classof(const LinkageSpecDecl *D) { return true; }
+  static bool classofKind(Kind K) { return K == LinkageSpec; }
+  static DeclContext *castToDeclContext(const LinkageSpecDecl *D) {
+    return static_cast<DeclContext *>(const_cast<LinkageSpecDecl*>(D));
+  }
+  static LinkageSpecDecl *castFromDeclContext(const DeclContext *DC) {
+    return static_cast<LinkageSpecDecl *>(const_cast<DeclContext*>(DC));
+  }
+};
+
+/// UsingDirectiveDecl - Represents C++ using-directive. For example:
+///
+///    using namespace std;
+///
+// NB: UsingDirectiveDecl should be Decl not NamedDecl, but we provide
+// artificial name, for all using-directives in order to store
+// them in DeclContext effectively.
+class UsingDirectiveDecl : public NamedDecl {
+
+  /// SourceLocation - Location of 'namespace' token.
+  SourceLocation NamespaceLoc;
+
+  /// \brief The source range that covers the nested-name-specifier
+  /// preceding the namespace name.
+  SourceRange QualifierRange;
+
+  /// \brief The nested-name-specifier that precedes the namespace
+  /// name, if any.
+  NestedNameSpecifier *Qualifier;
+
+  /// IdentLoc - Location of nominated namespace-name identifier.
+  // FIXME: We don't store location of scope specifier.
+  SourceLocation IdentLoc;
+
+  /// NominatedNamespace - Namespace nominated by using-directive.
+  NamedDecl *NominatedNamespace;
+
+  /// Enclosing context containing both using-directive and nominated
+  /// namespace.
+  DeclContext *CommonAncestor;
+
+  /// getUsingDirectiveName - Returns special DeclarationName used by
+  /// using-directives. This is only used by DeclContext for storing
+  /// UsingDirectiveDecls in its lookup structure.
+  static DeclarationName getName() {
+    return DeclarationName::getUsingDirectiveName();
+  }
+
+  UsingDirectiveDecl(DeclContext *DC, SourceLocation L,
+                     SourceLocation NamespcLoc,
+                     SourceRange QualifierRange,
+                     NestedNameSpecifier *Qualifier,
+                     SourceLocation IdentLoc,
+                     NamedDecl *Nominated,
+                     DeclContext *CommonAncestor)
+    : NamedDecl(Decl::UsingDirective, DC, L, getName()),
+      NamespaceLoc(NamespcLoc), QualifierRange(QualifierRange),
+      Qualifier(Qualifier), IdentLoc(IdentLoc),
+      NominatedNamespace(Nominated),
+      CommonAncestor(CommonAncestor) {
+  }
+
+public:
+  /// \brief Retrieve the source range of the nested-name-specifier
+  /// that qualifiers the namespace name.
+  SourceRange getQualifierRange() const { return QualifierRange; }
+
+  /// \brief Retrieve the nested-name-specifier that qualifies the
+  /// name of the namespace.
+  NestedNameSpecifier *getQualifier() const { return Qualifier; }
+
+  NamedDecl *getNominatedNamespaceAsWritten() { return NominatedNamespace; }
+  const NamedDecl *getNominatedNamespaceAsWritten() const {
+    return NominatedNamespace;
+  }
+
+  /// getNominatedNamespace - Returns namespace nominated by using-directive.
+  NamespaceDecl *getNominatedNamespace();
+
+  const NamespaceDecl *getNominatedNamespace() const {
+    return const_cast<UsingDirectiveDecl*>(this)->getNominatedNamespace();
+  }
+
+  /// getCommonAncestor - returns common ancestor context of using-directive,
+  /// and nominated by it namespace.
+  DeclContext *getCommonAncestor() { return CommonAncestor; }
+  const DeclContext *getCommonAncestor() const { return CommonAncestor; }
+
+  /// getNamespaceKeyLocation - Returns location of namespace keyword.
+  SourceLocation getNamespaceKeyLocation() const { return NamespaceLoc; }
+
+  /// getIdentLocation - Returns location of identifier.
+  SourceLocation getIdentLocation() const { return IdentLoc; }
+
+  static UsingDirectiveDecl *Create(ASTContext &C, DeclContext *DC,
+                                    SourceLocation L,
+                                    SourceLocation NamespaceLoc,
+                                    SourceRange QualifierRange,
+                                    NestedNameSpecifier *Qualifier,
+                                    SourceLocation IdentLoc,
+                                    NamedDecl *Nominated,
+                                    DeclContext *CommonAncestor);
+
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classof(const UsingDirectiveDecl *D) { return true; }
+  static bool classofKind(Kind K) { return K == Decl::UsingDirective; }
+
+  // Friend for getUsingDirectiveName.
+  friend class DeclContext;
+};
+
+/// NamespaceAliasDecl - Represents a C++ namespace alias. For example:
+///
+/// @code
+/// namespace Foo = Bar;
+/// @endcode
+class NamespaceAliasDecl : public NamedDecl {
+  SourceLocation AliasLoc;
+
+  /// \brief The source range that covers the nested-name-specifier
+  /// preceding the namespace name.
+  SourceRange QualifierRange;
+
+  /// \brief The nested-name-specifier that precedes the namespace
+  /// name, if any.
+  NestedNameSpecifier *Qualifier;
+
+  /// IdentLoc - Location of namespace identifier.
+  SourceLocation IdentLoc;
+
+  /// Namespace - The Decl that this alias points to. Can either be a
+  /// NamespaceDecl or a NamespaceAliasDecl.
+  NamedDecl *Namespace;
+
+  NamespaceAliasDecl(DeclContext *DC, SourceLocation L,
+                     SourceLocation AliasLoc, IdentifierInfo *Alias,
+                     SourceRange QualifierRange,
+                     NestedNameSpecifier *Qualifier,
+                     SourceLocation IdentLoc, NamedDecl *Namespace)
+    : NamedDecl(Decl::NamespaceAlias, DC, L, Alias), AliasLoc(AliasLoc),
+      QualifierRange(QualifierRange), Qualifier(Qualifier),
+      IdentLoc(IdentLoc), Namespace(Namespace) { }
+
+public:
+  /// \brief Retrieve the source range of the nested-name-specifier
+  /// that qualifiers the namespace name.
+  SourceRange getQualifierRange() const { return QualifierRange; }
+
+  /// \brief Retrieve the nested-name-specifier that qualifies the
+  /// name of the namespace.
+  NestedNameSpecifier *getQualifier() const { return Qualifier; }
+
+  NamespaceDecl *getNamespace() {
+    if (NamespaceAliasDecl *AD = dyn_cast<NamespaceAliasDecl>(Namespace))
+      return AD->getNamespace();
+
+    return cast<NamespaceDecl>(Namespace);
+  }
+
+  const NamespaceDecl *getNamespace() const {
+    return const_cast<NamespaceAliasDecl*>(this)->getNamespace();
+  }
+
+  /// Returns the location of the alias name, i.e. 'foo' in
+  /// "namespace foo = ns::bar;".
+  SourceLocation getAliasLoc() const { return AliasLoc; }
+
+  /// Returns the location of the 'namespace' keyword.
+  SourceLocation getNamespaceLoc() const { return getLocation(); }
+
+  /// Returns the location of the identifier in the named namespace.
+  SourceLocation getTargetNameLoc() const { return IdentLoc; }
+
+  /// \brief Retrieve the namespace that this alias refers to, which
+  /// may either be a NamespaceDecl or a NamespaceAliasDecl.
+  NamedDecl *getAliasedNamespace() const { return Namespace; }
+
+  static NamespaceAliasDecl *Create(ASTContext &C, DeclContext *DC,
+                                    SourceLocation L, SourceLocation AliasLoc,
+                                    IdentifierInfo *Alias,
+                                    SourceRange QualifierRange,
+                                    NestedNameSpecifier *Qualifier,
+                                    SourceLocation IdentLoc,
+                                    NamedDecl *Namespace);
+
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classof(const NamespaceAliasDecl *D) { return true; }
+  static bool classofKind(Kind K) { return K == Decl::NamespaceAlias; }
+};
+
+/// UsingShadowDecl - Represents a shadow declaration introduced into
+/// a scope by a (resolved) using declaration.  For example,
+///
+/// namespace A {
+///   void foo();
+/// }
+/// namespace B {
+///   using A::foo(); // <- a UsingDecl
+///                   // Also creates a UsingShadowDecl for A::foo in B
+/// }
+///
+class UsingShadowDecl : public NamedDecl {
+  /// The referenced declaration.
+  NamedDecl *Underlying;
+
+  /// The using declaration which introduced this decl.
+  UsingDecl *Using;
+
+  UsingShadowDecl(DeclContext *DC, SourceLocation Loc, UsingDecl *Using,
+                  NamedDecl *Target)
+    : NamedDecl(UsingShadow, DC, Loc, Target->getDeclName()),
+      Underlying(Target), Using(Using) {
+    IdentifierNamespace = Target->getIdentifierNamespace();
+    setImplicit();
+  }
+
+public:
+  static UsingShadowDecl *Create(ASTContext &C, DeclContext *DC,
+                                 SourceLocation Loc, UsingDecl *Using,
+                                 NamedDecl *Target) {
+    return new (C) UsingShadowDecl(DC, Loc, Using, Target);
+  }
+
+  /// Gets the underlying declaration which has been brought into the
+  /// local scope.
+  NamedDecl *getTargetDecl() const {
+    return Underlying;
+  }
+
+  /// Gets the using declaration to which this declaration is tied.
+  UsingDecl *getUsingDecl() const {
+    return Using;
+  }
+
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classof(const UsingShadowDecl *D) { return true; }
+  static bool classofKind(Kind K) { return K == Decl::UsingShadow; }
+};
+
+/// UsingDecl - Represents a C++ using-declaration. For example:
+///    using someNameSpace::someIdentifier;
+class UsingDecl : public NamedDecl {
+  /// \brief The source range that covers the nested-name-specifier
+  /// preceding the declaration name.
+  SourceRange NestedNameRange;
+
+  /// \brief The source location of the "using" location itself.
+  SourceLocation UsingLocation;
+
+  /// \brief Target nested name specifier.
+  NestedNameSpecifier* TargetNestedName;
+
+  /// \brief The collection of shadow declarations associated with
+  /// this using declaration.  This set can change as a class is
+  /// processed.
+  llvm::SmallPtrSet<UsingShadowDecl*, 8> Shadows;
+
+  // \brief Has 'typename' keyword.
+  bool IsTypeName;
+
+  UsingDecl(DeclContext *DC, SourceLocation L, SourceRange NNR,
+            SourceLocation UL, NestedNameSpecifier* TargetNNS,
+            DeclarationName Name, bool IsTypeNameArg)
+    : NamedDecl(Decl::Using, DC, L, Name),
+      NestedNameRange(NNR), UsingLocation(UL), TargetNestedName(TargetNNS),
+      IsTypeName(IsTypeNameArg) {
+  }
+
+public:
+  /// \brief Returns the source range that covers the nested-name-specifier
+  /// preceding the namespace name.
+  SourceRange getNestedNameRange() { return NestedNameRange; }
+
+  /// \brief Returns the source location of the "using" location itself.
+  SourceLocation getUsingLocation() { return UsingLocation; }
+
+  /// \brief Get target nested name declaration.
+  NestedNameSpecifier* getTargetNestedNameDecl() {
+    return TargetNestedName;
+  }
+
+  /// isTypeName - Return true if using decl has 'typename'.
+  bool isTypeName() const { return IsTypeName; }
+
+  typedef llvm::SmallPtrSet<UsingShadowDecl*,8>::const_iterator shadow_iterator;
+  shadow_iterator shadow_begin() const { return Shadows.begin(); }
+  shadow_iterator shadow_end() const { return Shadows.end(); }
+
+  void addShadowDecl(UsingShadowDecl *S) {
+    assert(S->getUsingDecl() == this);
+    if (!Shadows.insert(S)) {
+      assert(false && "declaration already in set");
+    }
+  }
+  void removeShadowDecl(UsingShadowDecl *S) {
+    assert(S->getUsingDecl() == this);
+    if (!Shadows.erase(S)) {
+      assert(false && "declaration not in set");
+    }
+  }
+
+  static UsingDecl *Create(ASTContext &C, DeclContext *DC,
+      SourceLocation IdentL, SourceRange NNR, SourceLocation UsingL,
+      NestedNameSpecifier* TargetNNS, DeclarationName Name, bool IsTypeNameArg);
+
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classof(const UsingDecl *D) { return true; }
+  static bool classofKind(Kind K) { return K == Decl::Using; }
+};
+
+/// UnresolvedUsingValueDecl - Represents a dependent using
+/// declaration which was not marked with 'typename'.  Unlike
+/// non-dependent using declarations, these *only* bring through
+/// non-types; otherwise they would break two-phase lookup.
+///
+/// template <class T> class A : public Base<T> {
+///   using Base<T>::foo;
+/// };
+class UnresolvedUsingValueDecl : public ValueDecl {
+  /// \brief The source range that covers the nested-name-specifier
+  /// preceding the declaration name.
+  SourceRange TargetNestedNameRange;
+
+  /// \brief The source location of the 'using' keyword
+  SourceLocation UsingLocation;
+
+  NestedNameSpecifier *TargetNestedNameSpecifier;
+
+  UnresolvedUsingValueDecl(DeclContext *DC, QualType Ty,
+                           SourceLocation UsingLoc, SourceRange TargetNNR,
+                           NestedNameSpecifier *TargetNNS,
+                           SourceLocation TargetNameLoc,
+                           DeclarationName TargetName)
+    : ValueDecl(Decl::UnresolvedUsingValue, DC, TargetNameLoc, TargetName, Ty),
+    TargetNestedNameRange(TargetNNR), UsingLocation(UsingLoc),
+    TargetNestedNameSpecifier(TargetNNS)
+  { }
+
+public:
+  /// \brief Returns the source range that covers the nested-name-specifier
+  /// preceding the namespace name.
+  SourceRange getTargetNestedNameRange() const { return TargetNestedNameRange; }
+
+  /// \brief Get target nested name declaration.
+  NestedNameSpecifier* getTargetNestedNameSpecifier() {
+    return TargetNestedNameSpecifier;
+  }
+
+  /// \brief Returns the source location of the 'using' keyword.
+  SourceLocation getUsingLoc() const { return UsingLocation; }
+
+  static UnresolvedUsingValueDecl *
+    Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc,
+           SourceRange TargetNNR, NestedNameSpecifier *TargetNNS,
+           SourceLocation TargetNameLoc, DeclarationName TargetName);
+
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classof(const UnresolvedUsingValueDecl *D) { return true; }
+  static bool classofKind(Kind K) { return K == Decl::UnresolvedUsingValue; }
+};
+
+/// UnresolvedUsingTypenameDecl - Represents a dependent using
+/// declaration which was marked with 'typename'.
+///
+/// template <class T> class A : public Base<T> {
+///   using typename Base<T>::foo;
+/// };
+///
+/// The type associated with a unresolved using typename decl is
+/// currently always a typename type.
+class UnresolvedUsingTypenameDecl : public TypeDecl {
+  /// \brief The source range that covers the nested-name-specifier
+  /// preceding the declaration name.
+  SourceRange TargetNestedNameRange;
+
+  /// \brief The source location of the 'using' keyword
+  SourceLocation UsingLocation;
+
+  /// \brief The source location of the 'typename' keyword
+  SourceLocation TypenameLocation;
+
+  NestedNameSpecifier *TargetNestedNameSpecifier;
+
+  UnresolvedUsingTypenameDecl(DeclContext *DC, SourceLocation UsingLoc,
+                    SourceLocation TypenameLoc,
+                    SourceRange TargetNNR, NestedNameSpecifier *TargetNNS,
+                    SourceLocation TargetNameLoc, IdentifierInfo *TargetName)
+  : TypeDecl(Decl::UnresolvedUsingTypename, DC, TargetNameLoc, TargetName),
+    TargetNestedNameRange(TargetNNR), UsingLocation(UsingLoc),
+    TypenameLocation(TypenameLoc), TargetNestedNameSpecifier(TargetNNS)
+  { }
+
+public:
+  /// \brief Returns the source range that covers the nested-name-specifier
+  /// preceding the namespace name.
+  SourceRange getTargetNestedNameRange() const { return TargetNestedNameRange; }
+
+  /// \brief Get target nested name declaration.
+  NestedNameSpecifier* getTargetNestedNameSpecifier() {
+    return TargetNestedNameSpecifier;
+  }
+
+  /// \brief Returns the source location of the 'using' keyword.
+  SourceLocation getUsingLoc() const { return UsingLocation; }
+
+  /// \brief Returns the source location of the 'typename' keyword.
+  SourceLocation getTypenameLoc() const { return TypenameLocation; }
+
+  static UnresolvedUsingTypenameDecl *
+    Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc,
+           SourceLocation TypenameLoc,
+           SourceRange TargetNNR, NestedNameSpecifier *TargetNNS,
+           SourceLocation TargetNameLoc, DeclarationName TargetName);
+
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classof(const UnresolvedUsingTypenameDecl *D) { return true; }
+  static bool classofKind(Kind K) { return K == Decl::UnresolvedUsingTypename; }
+};
+
+/// StaticAssertDecl - Represents a C++0x static_assert declaration.
+class StaticAssertDecl : public Decl {
+  Expr *AssertExpr;
+  StringLiteral *Message;
+
+  StaticAssertDecl(DeclContext *DC, SourceLocation L,
+                   Expr *assertexpr, StringLiteral *message)
+  : Decl(StaticAssert, DC, L), AssertExpr(assertexpr), Message(message) { }
+
+public:
+  static StaticAssertDecl *Create(ASTContext &C, DeclContext *DC,
+                                  SourceLocation L, Expr *AssertExpr,
+                                  StringLiteral *Message);
+
+  Expr *getAssertExpr() { return AssertExpr; }
+  const Expr *getAssertExpr() const { return AssertExpr; }
+
+  StringLiteral *getMessage() { return Message; }
+  const StringLiteral *getMessage() const { return Message; }
+
+  virtual ~StaticAssertDecl();
+  virtual void Destroy(ASTContext& C);
+
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classof(StaticAssertDecl *D) { return true; }
+  static bool classofKind(Kind K) { return K == Decl::StaticAssert; }
+};
+
+/// Insertion operator for diagnostics.  This allows sending AccessSpecifier's
+/// into a diagnostic with <<.
+const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+                                    AccessSpecifier AS);
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/AST/DeclContextInternals.h b/include/clang/AST/DeclContextInternals.h
new file mode 100644
index 0000000..2a4b12a
--- /dev/null
+++ b/include/clang/AST/DeclContextInternals.h
@@ -0,0 +1,288 @@
+//===-- DeclContextInternals.h - DeclContext Representation -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the data structures used in the implementation
+//  of DeclContext.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_AST_DECLCONTEXTINTERNALS_H
+#define LLVM_CLANG_AST_DECLCONTEXTINTERNALS_H
+
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclarationName.h"
+#include "clang/AST/DeclCXX.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/SmallVector.h"
+#include <algorithm>
+
+namespace clang {
+
+class DependentDiagnostic;
+
+/// StoredDeclsList - This is an array of decls optimized a common case of only
+/// containing one entry.
+struct StoredDeclsList {
+  /// The kind of data encoded in this list.
+  enum DataKind {
+    /// \brief The data is a NamedDecl*.
+    DK_Decl = 0,
+    /// \brief The data is a declaration ID (an unsigned value),
+    /// shifted left by 2 bits.
+    DK_DeclID = 1,
+    /// \brief The data is a pointer to a vector (of type VectorTy)
+    /// that contains declarations.
+    DK_Decl_Vector = 2,
+    /// \brief The data is a pointer to a vector (of type VectorTy)
+    /// that contains declaration ID.
+    DK_ID_Vector = 3
+  };
+
+  /// VectorTy - When in vector form, this is what the Data pointer points to.
+  typedef llvm::SmallVector<uintptr_t, 4> VectorTy;
+
+  /// \brief The stored data, which will be either a declaration ID, a
+  /// pointer to a NamedDecl, or a pointer to a vector.
+  uintptr_t Data;
+
+public:
+  StoredDeclsList() : Data(0) {}
+
+  StoredDeclsList(const StoredDeclsList &RHS) : Data(RHS.Data) {
+    if (VectorTy *RHSVec = RHS.getAsVector()) {
+      VectorTy *New = new VectorTy(*RHSVec);
+      Data = reinterpret_cast<uintptr_t>(New) | (Data & 0x03);
+    }
+  }
+
+  ~StoredDeclsList() {
+    // If this is a vector-form, free the vector.
+    if (VectorTy *Vector = getAsVector())
+      delete Vector;
+  }
+
+  StoredDeclsList &operator=(const StoredDeclsList &RHS) {
+    if (VectorTy *Vector = getAsVector())
+      delete Vector;
+    Data = RHS.Data;
+    if (VectorTy *RHSVec = RHS.getAsVector()) {
+      VectorTy *New = new VectorTy(*RHSVec);
+      Data = reinterpret_cast<uintptr_t>(New) | (Data & 0x03);
+    }
+    return *this;
+  }
+
+  bool isNull() const { return (Data & ~0x03) == 0; }
+
+  NamedDecl *getAsDecl() const {
+    if ((Data & 0x03) != DK_Decl)
+      return 0;
+
+    return reinterpret_cast<NamedDecl *>(Data & ~0x03);
+  }
+
+  VectorTy *getAsVector() const {
+    if ((Data & 0x03) != DK_ID_Vector && (Data & 0x03) != DK_Decl_Vector)
+      return 0;
+
+    return reinterpret_cast<VectorTy *>(Data & ~0x03);
+  }
+
+  void setOnlyValue(NamedDecl *ND) {
+    assert(!getAsVector() && "Not inline");
+    Data = reinterpret_cast<uintptr_t>(ND);
+  }
+
+  void setFromDeclIDs(const llvm::SmallVectorImpl<unsigned> &Vec) {
+    if (Vec.size() > 1) {
+      VectorTy *Vector = getAsVector();
+      if (!Vector) {
+        Vector = new VectorTy;
+        Data = reinterpret_cast<uintptr_t>(Vector) | DK_ID_Vector;
+      }
+
+      Vector->resize(Vec.size());
+      std::copy(Vec.begin(), Vec.end(), Vector->begin());
+      return;
+    }
+
+    if (VectorTy *Vector = getAsVector())
+      delete Vector;
+
+    if (Vec.empty())
+      Data = 0;
+    else
+      Data = (Vec[0] << 2) | DK_DeclID;
+  }
+
+  /// \brief Force the stored declarations list to contain actual
+  /// declarations.
+  ///
+  /// This routine will resolve any declaration IDs for declarations
+  /// that may not yet have been loaded from external storage.
+  void materializeDecls(ASTContext &Context);
+
+  bool hasDeclarationIDs() const {
+    DataKind DK = (DataKind)(Data & 0x03);
+    return DK == DK_DeclID || DK == DK_ID_Vector;
+  }
+
+  void remove(NamedDecl *D) {
+    assert(!isNull() && "removing from empty list");
+    if (NamedDecl *Singleton = getAsDecl()) {
+      assert(Singleton == D && "list is different singleton");
+      (void)Singleton;
+      Data = 0;
+      return;
+    }
+
+    VectorTy &Vec = *getAsVector();
+    VectorTy::iterator I = std::find(Vec.begin(), Vec.end(),
+                                     reinterpret_cast<uintptr_t>(D));
+    assert(I != Vec.end() && "list does not contain decl");
+    Vec.erase(I);
+
+    assert(std::find(Vec.begin(), Vec.end(), reinterpret_cast<uintptr_t>(D))
+             == Vec.end() && "list still contains decl");
+  }
+
+  /// getLookupResult - Return an array of all the decls that this list
+  /// represents.
+  DeclContext::lookup_result getLookupResult(ASTContext &Context) {
+    if (isNull())
+      return DeclContext::lookup_result(0, 0);
+
+    if (hasDeclarationIDs())
+      materializeDecls(Context);
+
+    // If we have a single NamedDecl, return it.
+    if (getAsDecl()) {
+      assert(!isNull() && "Empty list isn't allowed");
+
+      // Data is a raw pointer to a NamedDecl*, return it.
+      void *Ptr = &Data;
+      return DeclContext::lookup_result((NamedDecl**)Ptr, (NamedDecl**)Ptr+1);
+    }
+
+    assert(getAsVector() && "Must have a vector at this point");
+    VectorTy &Vector = *getAsVector();
+
+    // Otherwise, we have a range result.
+    return DeclContext::lookup_result((NamedDecl **)&Vector[0],
+                                      (NamedDecl **)&Vector[0]+Vector.size());
+  }
+
+  /// HandleRedeclaration - If this is a redeclaration of an existing decl,
+  /// replace the old one with D and return true.  Otherwise return false.
+  bool HandleRedeclaration(ASTContext &Context, NamedDecl *D) {
+    if (hasDeclarationIDs())
+      materializeDecls(Context);
+
+    // Most decls only have one entry in their list, special case it.
+    if (NamedDecl *OldD = getAsDecl()) {
+      if (!D->declarationReplaces(OldD))
+        return false;
+      setOnlyValue(D);
+      return true;
+    }
+
+    // Determine if this declaration is actually a redeclaration.
+    VectorTy &Vec = *getAsVector();
+    for (VectorTy::iterator OD = Vec.begin(), ODEnd = Vec.end();
+         OD != ODEnd; ++OD) {
+      NamedDecl *OldD = reinterpret_cast<NamedDecl *>(*OD);
+      if (D->declarationReplaces(OldD)) {
+        *OD = reinterpret_cast<uintptr_t>(D);
+        return true;
+      }
+    }
+
+    return false;
+  }
+
+  /// AddSubsequentDecl - This is called on the second and later decl when it is
+  /// not a redeclaration to merge it into the appropriate place in our list.
+  ///
+  void AddSubsequentDecl(NamedDecl *D) {
+    assert(!hasDeclarationIDs() && "Must materialize before adding decls");
+
+    // If this is the second decl added to the list, convert this to vector
+    // form.
+    if (NamedDecl *OldD = getAsDecl()) {
+      VectorTy *VT = new VectorTy();
+      VT->push_back(reinterpret_cast<uintptr_t>(OldD));
+      Data = reinterpret_cast<uintptr_t>(VT) | DK_Decl_Vector;
+    }
+
+    VectorTy &Vec = *getAsVector();
+
+    // Using directives end up in a special entry which contains only
+    // other using directives, so all this logic is wasted for them.
+    // But avoiding the logic wastes time in the far-more-common case
+    // that we're *not* adding a new using directive.
+
+    // Tag declarations always go at the end of the list so that an
+    // iterator which points at the first tag will start a span of
+    // decls that only contains tags.
+    if (D->hasTagIdentifierNamespace())
+      Vec.push_back(reinterpret_cast<uintptr_t>(D));
+
+    // Resolved using declarations go at the front of the list so that
+    // they won't show up in other lookup results.  Unresolved using
+    // declarations (which are always in IDNS_Using | IDNS_Ordinary)
+    // follow that so that the using declarations will be contiguous.
+    else if (D->getIdentifierNamespace() & Decl::IDNS_Using) {
+      VectorTy::iterator I = Vec.begin();
+      if (D->getIdentifierNamespace() != Decl::IDNS_Using) {
+        while (I != Vec.end() &&
+               reinterpret_cast<NamedDecl *>(*I)
+                 ->getIdentifierNamespace() == Decl::IDNS_Using)
+          ++I;
+      }
+      Vec.insert(I, reinterpret_cast<uintptr_t>(D));
+
+    // All other declarations go at the end of the list, but before any
+    // tag declarations.  But we can be clever about tag declarations
+    // because there can only ever be one in a scope.
+    } else if (reinterpret_cast<NamedDecl *>(Vec.back())
+                 ->hasTagIdentifierNamespace()) {
+      uintptr_t TagD = Vec.back();
+      Vec.back() = reinterpret_cast<uintptr_t>(D);
+      Vec.push_back(TagD);
+    } else
+      Vec.push_back(reinterpret_cast<uintptr_t>(D));
+  }
+};
+
+class StoredDeclsMap
+  : public llvm::DenseMap<DeclarationName, StoredDeclsList> {
+
+public:
+  static void DestroyAll(StoredDeclsMap *Map, bool Dependent);
+
+private:
+  friend class ASTContext; // walks the chain deleting these
+  friend class DeclContext;
+  llvm::PointerIntPair<StoredDeclsMap*, 1> Previous;
+};
+
+class DependentStoredDeclsMap : public StoredDeclsMap {
+public:
+  DependentStoredDeclsMap() : FirstDiagnostic(0) {}
+
+private:
+  friend class DependentDiagnostic;
+  friend class DeclContext; // iterates over diagnostics
+
+  DependentDiagnostic *FirstDiagnostic;
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/AST/DeclFriend.h b/include/clang/AST/DeclFriend.h
new file mode 100644
index 0000000..a20625d
--- /dev/null
+++ b/include/clang/AST/DeclFriend.h
@@ -0,0 +1,159 @@
+//===-- DeclFriend.h - Classes for C++ friend declarations -*- C++ -*------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the section of the AST representing C++ friend
+// declarations.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_DECLFRIEND_H
+#define LLVM_CLANG_AST_DECLFRIEND_H
+
+#include "clang/AST/DeclCXX.h"
+
+namespace clang {
+
+/// FriendDecl - Represents the declaration of a friend entity,
+/// which can be a function, a type, or a templated function or type.
+//  For example:
+///
+/// @code
+/// template <typename T> class A {
+///   friend int foo(T);
+///   friend class B;
+///   friend T; // only in C++0x
+///   template <typename U> friend class C;
+///   template <typename U> friend A& operator+=(A&, const U&) { ... }
+/// };
+/// @endcode
+///
+/// The semantic context of a friend decl is its declaring class.
+class FriendDecl : public Decl {
+public:
+  typedef llvm::PointerUnion<NamedDecl*,TypeSourceInfo*> FriendUnion;
+
+private:
+  // The declaration that's a friend of this class.
+  FriendUnion Friend;
+
+  // A pointer to the next friend in the sequence.
+  FriendDecl *NextFriend;
+
+  // Location of the 'friend' specifier.
+  SourceLocation FriendLoc;
+
+  friend class CXXRecordDecl::friend_iterator;
+  friend class CXXRecordDecl;
+
+  FriendDecl(DeclContext *DC, SourceLocation L, FriendUnion Friend,
+             SourceLocation FriendL)
+    : Decl(Decl::Friend, DC, L),
+      Friend(Friend),
+      NextFriend(0),
+      FriendLoc(FriendL) {
+  }
+
+public:
+  static FriendDecl *Create(ASTContext &C, DeclContext *DC,
+                            SourceLocation L, FriendUnion Friend_,
+                            SourceLocation FriendL);
+
+  /// If this friend declaration names an (untemplated but
+  /// possibly dependent) type, return the type;  otherwise
+  /// return null.  This is used only for C++0x's unelaborated
+  /// friend type declarations.
+  TypeSourceInfo *getFriendType() const {
+    return Friend.dyn_cast<TypeSourceInfo*>();
+  }
+
+  /// If this friend declaration doesn't name an unelaborated
+  /// type, return the inner declaration.
+  NamedDecl *getFriendDecl() const {
+    return Friend.dyn_cast<NamedDecl*>();
+  }
+
+  /// Retrieves the location of the 'friend' keyword.
+  SourceLocation getFriendLoc() const {
+    return FriendLoc;
+  }
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classof(const FriendDecl *D) { return true; }
+  static bool classofKind(Kind K) { return K == Decl::Friend; }
+};
+
+/// An iterator over the friend declarations of a class.
+class CXXRecordDecl::friend_iterator {
+  FriendDecl *Ptr;
+
+  friend class CXXRecordDecl;
+  explicit friend_iterator(FriendDecl *Ptr) : Ptr(Ptr) {}
+public:
+  friend_iterator() {}
+
+  typedef FriendDecl *value_type;
+  typedef FriendDecl *reference;
+  typedef FriendDecl *pointer;
+  typedef int difference_type;
+  typedef std::forward_iterator_tag iterator_category;
+
+  reference operator*() const { return Ptr; }
+
+  friend_iterator &operator++() {
+    assert(Ptr && "attempt to increment past end of friend list");
+    Ptr = Ptr->NextFriend;
+    return *this;
+  }
+
+  friend_iterator operator++(int) {
+    friend_iterator tmp = *this;
+    ++*this;
+    return tmp;
+  }
+
+  bool operator==(const friend_iterator &Other) const {
+    return Ptr == Other.Ptr;
+  }
+
+  bool operator!=(const friend_iterator &Other) const {
+    return Ptr != Other.Ptr;
+  }
+
+  friend_iterator &operator+=(difference_type N) {
+    assert(N >= 0 && "cannot rewind a CXXRecordDecl::friend_iterator");
+    while (N--)
+      ++*this;
+    return *this;
+  }
+
+  friend_iterator operator+(difference_type N) const {
+    friend_iterator tmp = *this;
+    tmp += N;
+    return tmp;
+  }
+};
+
+inline CXXRecordDecl::friend_iterator CXXRecordDecl::friend_begin() const {
+  return friend_iterator(data().FirstFriend);
+}
+
+inline CXXRecordDecl::friend_iterator CXXRecordDecl::friend_end() const {
+  return friend_iterator(0);
+}
+
+inline void CXXRecordDecl::pushFriendDecl(FriendDecl *FD) {
+  assert(FD->NextFriend == 0 && "friend already has next friend?");
+  FD->NextFriend = data().FirstFriend;
+  data().FirstFriend = FD;
+}
+  
+}
+
+#endif
diff --git a/include/clang/AST/DeclGroup.h b/include/clang/AST/DeclGroup.h
new file mode 100644
index 0000000..e1fae8f
--- /dev/null
+++ b/include/clang/AST/DeclGroup.h
@@ -0,0 +1,152 @@
+//===--- DeclGroup.h - Classes for representing groups of Decls -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the DeclGroup, DeclGroupRef, and OwningDeclGroup classes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_DECLGROUP_H
+#define LLVM_CLANG_AST_DECLGROUP_H
+
+#include "llvm/System/DataTypes.h"
+#include <cassert>
+
+namespace clang {
+
+class ASTContext;
+class Decl;
+class DeclGroup;
+class DeclGroupIterator;
+
+class DeclGroup {
+  // FIXME: Include a TypeSpecifier object.
+  unsigned NumDecls;
+
+private:
+  DeclGroup() : NumDecls(0) {}
+  DeclGroup(unsigned numdecls, Decl** decls);
+
+public:
+  static DeclGroup *Create(ASTContext &C, Decl **Decls, unsigned NumDecls);
+  void Destroy(ASTContext& C);
+
+  unsigned size() const { return NumDecls; }
+
+  Decl*& operator[](unsigned i) {
+    assert (i < NumDecls && "Out-of-bounds access.");
+    return *((Decl**) (this+1));
+  }
+
+  Decl* const& operator[](unsigned i) const {
+    assert (i < NumDecls && "Out-of-bounds access.");
+    return *((Decl* const*) (this+1));
+  }
+};
+
+class DeclGroupRef {
+  // Note this is not a PointerIntPair because we need the address of the
+  // non-group case to be valid as a Decl** for iteration.
+  enum Kind { SingleDeclKind=0x0, DeclGroupKind=0x1, Mask=0x1 };
+  Decl* D;
+
+  Kind getKind() const {
+    return (Kind) (reinterpret_cast<uintptr_t>(D) & Mask);
+  }
+
+public:
+  DeclGroupRef() : D(0) {}
+
+  explicit DeclGroupRef(Decl* d) : D(d) {}
+  explicit DeclGroupRef(DeclGroup* dg)
+    : D((Decl*) (reinterpret_cast<uintptr_t>(dg) | DeclGroupKind)) {}
+
+  static DeclGroupRef Create(ASTContext &C, Decl **Decls, unsigned NumDecls) {
+    if (NumDecls == 0)
+      return DeclGroupRef();
+    if (NumDecls == 1)
+      return DeclGroupRef(Decls[0]);
+    return DeclGroupRef(DeclGroup::Create(C, Decls, NumDecls));
+  }
+
+  typedef Decl** iterator;
+  typedef Decl* const * const_iterator;
+
+  bool isNull() const { return D == 0; }
+  bool isSingleDecl() const { return getKind() == SingleDeclKind; }
+  bool isDeclGroup() const { return getKind() == DeclGroupKind; }
+
+  Decl *getSingleDecl() {
+    assert(isSingleDecl() && "Isn't a declgroup");
+    return D;
+  }
+  const Decl *getSingleDecl() const {
+    return const_cast<DeclGroupRef*>(this)->getSingleDecl();
+  }
+
+  DeclGroup &getDeclGroup() {
+    assert(isDeclGroup() && "Isn't a declgroup");
+    return *((DeclGroup*)(reinterpret_cast<uintptr_t>(D) & ~Mask));
+  }
+  const DeclGroup &getDeclGroup() const {
+    return const_cast<DeclGroupRef*>(this)->getDeclGroup();
+  }
+
+  iterator begin() {
+    if (isSingleDecl())
+      return D ? &D : 0;
+    return &getDeclGroup()[0];
+  }
+
+  iterator end() {
+    if (isSingleDecl())
+      return D ? &D+1 : 0;
+    DeclGroup &G = getDeclGroup();
+    return &G[0] + G.size();
+  }
+
+  const_iterator begin() const {
+    if (isSingleDecl())
+      return D ? &D : 0;
+    return &getDeclGroup()[0];
+  }
+
+  const_iterator end() const {
+    if (isSingleDecl())
+      return D ? &D+1 : 0;
+    const DeclGroup &G = getDeclGroup();
+    return &G[0] + G.size();
+  }
+
+  void *getAsOpaquePtr() const { return D; }
+  static DeclGroupRef getFromOpaquePtr(void *Ptr) {
+    DeclGroupRef X;
+    X.D = static_cast<Decl*>(Ptr);
+    return X;
+  }
+};
+
+} // end clang namespace
+
+namespace llvm {
+  // DeclGroupRef is "like a pointer", implement PointerLikeTypeTraits.
+  template <typename T>
+  class PointerLikeTypeTraits;
+  template <>
+  class PointerLikeTypeTraits<clang::DeclGroupRef> {
+  public:
+    static inline void *getAsVoidPointer(clang::DeclGroupRef P) {
+      return P.getAsOpaquePtr();
+    }
+    static inline clang::DeclGroupRef getFromVoidPointer(void *P) {
+      return clang::DeclGroupRef::getFromOpaquePtr(P);
+    }
+    enum { NumLowBitsAvailable = 0 };
+  };
+}
+#endif
diff --git a/include/clang/AST/DeclNodes.def b/include/clang/AST/DeclNodes.def
new file mode 100644
index 0000000..5b03ff8
--- /dev/null
+++ b/include/clang/AST/DeclNodes.def
@@ -0,0 +1,165 @@
+//===-- DeclNodes.def - Metadata about Decl AST nodes -----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the declaration nodes within the AST. The
+//  description of the declaration nodes uses six macros: 
+//
+//  DECL(Derived, Base) describes a normal declaration type Derived
+//  and specifies its base class. Note that Derived should not have
+//  the Decl suffix on it, while Base should.
+//
+//  LAST_DECL(Derived, Base) is like DECL, but is used for the last
+//  declaration in the list.
+//
+//  ABSTRACT_DECL(Derived, Base) describes an abstract class that is
+//  used to specify a classification of declarations. For example,
+//  TagDecl is an abstract class used to describe the various kinds of
+//  "tag" declarations (unions, structs, classes, enums).
+//
+//  DECL_CONTEXT(Decl) specifies that Decl is a kind of declaration
+//  that is also a DeclContext.
+//  
+//  LAST_DECL_CONTEXT(Decl) is like DECL_CONTEXT, but is used for the
+//  last declaration context.
+//
+//  DECL_RANGE(CommonBase, Start, End) specifies a range of
+//  declaration values that have a common (potentially indirect) base
+//  class.
+//
+//  LAST_DECL_RANGE(CommonBase, Start, End) is like DECL_RANGE, but is
+//  used for the last declaration range.
+//
+//  Note that, due to the use of ranges, the order of the these
+//  declarations is significant. A declaration should be listed under
+//  its base class.
+//  ===----------------------------------------------------------------------===//
+
+#ifndef DECL
+#  define DECL(Derived, Base)
+#endif
+
+#ifndef LAST_DECL
+#  define LAST_DECL(Derived, Base) DECL(Derived, Base)
+#endif
+
+#ifndef ABSTRACT_DECL
+#  define ABSTRACT_DECL(Derived, Base)
+#endif
+
+#ifndef DECL_CONTEXT
+#  define DECL_CONTEXT(Decl)
+#endif
+
+#ifndef DECL_CONTEXT_BASE
+#  define DECL_CONTEXT_BASE(Decl) DECL_CONTEXT(Decl)
+#endif
+
+#ifndef LAST_DECL_CONTEXT
+#  define LAST_DECL_CONTEXT(Decl) DECL_CONTEXT(Decl)
+#endif
+
+#ifndef DECL_RANGE
+#  define DECL_RANGE(CommonBase, Start, End)
+#endif
+
+#ifndef LAST_DECL_RANGE
+#  define LAST_DECL_RANGE(CommonBase, Start, End) \
+  DECL_RANGE(CommonBase, Start, End)
+#endif
+
+DECL(TranslationUnit, Decl)
+ABSTRACT_DECL(Named,  Decl)
+  DECL(Namespace, NamedDecl)
+  DECL(UsingDirective, NamedDecl)
+  DECL(NamespaceAlias, NamedDecl)
+  ABSTRACT_DECL(Type, NamedDecl)
+    DECL(Typedef, TypeDecl)
+    DECL(UnresolvedUsingTypename, TypeDecl)
+    ABSTRACT_DECL(Tag, TypeDecl)
+      DECL(Enum, TagDecl)
+      DECL(Record, TagDecl)
+        DECL(CXXRecord, RecordDecl)
+          DECL(ClassTemplateSpecialization, CXXRecordDecl)
+            DECL(ClassTemplatePartialSpecialization, 
+                 ClassTemplateSpecializationDecl)
+    DECL(TemplateTypeParm, TypeDecl)
+  ABSTRACT_DECL(Value, NamedDecl)
+    DECL(EnumConstant, ValueDecl)
+    DECL(UnresolvedUsingValue, ValueDecl)
+    ABSTRACT_DECL(Declarator, ValueDecl)
+      DECL(Function, DeclaratorDecl)
+        DECL(CXXMethod, FunctionDecl)
+          DECL(CXXConstructor, CXXMethodDecl)
+          DECL(CXXDestructor, CXXMethodDecl)
+          DECL(CXXConversion, CXXMethodDecl)
+      DECL(Field, DeclaratorDecl)
+        DECL(ObjCIvar, FieldDecl)
+        DECL(ObjCAtDefsField, FieldDecl)
+      DECL(Var, DeclaratorDecl)
+        DECL(ImplicitParam, VarDecl)
+        DECL(ParmVar, VarDecl)
+        DECL(NonTypeTemplateParm, VarDecl)
+  ABSTRACT_DECL(Template, NamedDecl)
+    DECL(FunctionTemplate, TemplateDecl)
+    DECL(ClassTemplate, TemplateDecl)
+    DECL(TemplateTemplateParm, TemplateDecl)
+  DECL(Using, NamedDecl)
+  DECL(UsingShadow, NamedDecl)
+  DECL(ObjCMethod, NamedDecl)
+  ABSTRACT_DECL(ObjCContainer, NamedDecl)
+    DECL(ObjCCategory, ObjCContainerDecl)
+    DECL(ObjCProtocol, ObjCContainerDecl)
+    DECL(ObjCInterface, ObjCContainerDecl)
+    ABSTRACT_DECL(ObjCImpl, ObjCContainerDecl)
+      DECL(ObjCCategoryImpl, ObjCImplDecl)
+      DECL(ObjCImplementation, ObjCImplDecl)
+  DECL(ObjCProperty, NamedDecl)
+  DECL(ObjCCompatibleAlias, NamedDecl)
+DECL(LinkageSpec, Decl)
+DECL(ObjCPropertyImpl, Decl)
+DECL(ObjCForwardProtocol, Decl)
+DECL(ObjCClass, Decl)
+DECL(FileScopeAsm, Decl)
+DECL(Friend, Decl)
+DECL(FriendTemplate, Decl)
+DECL(StaticAssert, Decl)
+LAST_DECL(Block, Decl)
+
+// Declaration contexts. DECL_CONTEXT_BASE indicates that it has subclasses.
+DECL_CONTEXT(TranslationUnit)
+DECL_CONTEXT(Namespace)
+DECL_CONTEXT(LinkageSpec)
+DECL_CONTEXT(ObjCMethod)
+DECL_CONTEXT_BASE(Tag)
+DECL_CONTEXT_BASE(Function)
+DECL_CONTEXT_BASE(ObjCContainer)
+LAST_DECL_CONTEXT(Block)
+
+// Declaration ranges
+DECL_RANGE(Named, Namespace, ObjCCompatibleAlias)
+DECL_RANGE(ObjCContainer, ObjCCategory, ObjCImplementation)
+DECL_RANGE(Field, Field, ObjCAtDefsField)
+DECL_RANGE(Type, Typedef, TemplateTypeParm)
+DECL_RANGE(Tag, Enum, ClassTemplatePartialSpecialization)
+DECL_RANGE(Record, Record, ClassTemplatePartialSpecialization)
+DECL_RANGE(Value, EnumConstant, NonTypeTemplateParm)
+DECL_RANGE(Declarator, Function, NonTypeTemplateParm)
+DECL_RANGE(Function, Function, CXXConversion)
+DECL_RANGE(Template, FunctionTemplate, TemplateTemplateParm)
+DECL_RANGE(ObjCImpl, ObjCCategoryImpl, ObjCImplementation)
+LAST_DECL_RANGE(Var, Var, NonTypeTemplateParm)
+
+#undef LAST_DECL_RANGE
+#undef DECL_RANGE
+#undef LAST_DECL_CONTEXT
+#undef DECL_CONTEXT_BASE
+#undef DECL_CONTEXT
+#undef ABSTRACT_DECL
+#undef LAST_DECL
+#undef DECL
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h
new file mode 100644
index 0000000..18bb607
--- /dev/null
+++ b/include/clang/AST/DeclObjC.h
@@ -0,0 +1,1430 @@
+//===--- DeclObjC.h - Classes for representing declarations -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the DeclObjC interface and subclasses.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_DECLOBJC_H
+#define LLVM_CLANG_AST_DECLOBJC_H
+
+#include "clang/AST/Decl.h"
+#include "llvm/ADT/STLExtras.h"
+
+namespace clang {
+class Expr;
+class Stmt;
+class FunctionDecl;
+class AttributeList;
+class RecordDecl;
+class ObjCIvarDecl;
+class ObjCMethodDecl;
+class ObjCProtocolDecl;
+class ObjCCategoryDecl;
+class ObjCPropertyDecl;
+class ObjCPropertyImplDecl;
+
+class ObjCListBase {
+  void operator=(const ObjCListBase &);     // DO NOT IMPLEMENT
+  ObjCListBase(const ObjCListBase&);        // DO NOT IMPLEMENT
+protected:
+  /// List is an array of pointers to objects that are not owned by this object.
+  void **List;
+  unsigned NumElts;
+
+public:
+  ObjCListBase() : List(0), NumElts(0) {}
+  ~ObjCListBase() {
+    assert(List == 0 && "Destroy should have been called before dtor");
+  }
+
+  void Destroy(ASTContext &Ctx);
+
+  unsigned size() const { return NumElts; }
+  bool empty() const { return NumElts == 0; }
+
+protected:
+  void set(void *const* InList, unsigned Elts, ASTContext &Ctx);
+};
+
+
+/// ObjCList - This is a simple template class used to hold various lists of
+/// decls etc, which is heavily used by the ObjC front-end.  This only use case
+/// this supports is setting the list all at once and then reading elements out
+/// of it.
+template <typename T>
+class ObjCList : public ObjCListBase {
+public:
+  void set(T* const* InList, unsigned Elts, ASTContext &Ctx) {
+    ObjCListBase::set(reinterpret_cast<void*const*>(InList), Elts, Ctx);
+  }
+
+  typedef T* const * iterator;
+  iterator begin() const { return (iterator)List; }
+  iterator end() const { return (iterator)List+NumElts; }
+
+  T* operator[](unsigned Idx) const {
+    assert(Idx < NumElts && "Invalid access");
+    return (T*)List[Idx];
+  }
+};
+
+/// \brief A list of Objective-C protocols, along with the source
+/// locations at which they were referenced.
+class ObjCProtocolList : public ObjCList<ObjCProtocolDecl> {
+  SourceLocation *Locations;
+
+  using ObjCList<ObjCProtocolDecl>::set;
+
+public:
+  ObjCProtocolList() : ObjCList<ObjCProtocolDecl>(), Locations(0) { }
+
+  typedef const SourceLocation *loc_iterator;
+  loc_iterator loc_begin() const { return Locations; }
+  loc_iterator loc_end() const { return Locations + size(); }
+
+  void set(ObjCProtocolDecl* const* InList, unsigned Elts, 
+           const SourceLocation *Locs, ASTContext &Ctx);
+  void Destroy(ASTContext &Ctx);
+};
+
+
+/// ObjCMethodDecl - Represents an instance or class method declaration.
+/// ObjC methods can be declared within 4 contexts: class interfaces,
+/// categories, protocols, and class implementations. While C++ member
+/// functions leverage C syntax, Objective-C method syntax is modeled after
+/// Smalltalk (using colons to specify argument types/expressions).
+/// Here are some brief examples:
+///
+/// Setter/getter instance methods:
+/// - (void)setMenu:(NSMenu *)menu;
+/// - (NSMenu *)menu;
+///
+/// Instance method that takes 2 NSView arguments:
+/// - (void)replaceSubview:(NSView *)oldView with:(NSView *)newView;
+///
+/// Getter class method:
+/// + (NSMenu *)defaultMenu;
+///
+/// A selector represents a unique name for a method. The selector names for
+/// the above methods are setMenu:, menu, replaceSubview:with:, and defaultMenu.
+///
+class ObjCMethodDecl : public NamedDecl, public DeclContext {
+public:
+  enum ImplementationControl { None, Required, Optional };
+private:
+  /// Bitfields must be first fields in this class so they pack with those
+  /// declared in class Decl.
+  /// instance (true) or class (false) method.
+  bool IsInstance : 1;
+  bool IsVariadic : 1;
+
+  // Synthesized declaration method for a property setter/getter
+  bool IsSynthesized : 1;
+
+  // NOTE: VC++ treats enums as signed, avoid using ImplementationControl enum
+  /// @required/@optional
+  unsigned DeclImplementation : 2;
+
+  // NOTE: VC++ treats enums as signed, avoid using the ObjCDeclQualifier enum
+  /// in, inout, etc.
+  unsigned objcDeclQualifier : 6;
+
+  // Number of args separated by ':' in a method declaration.
+  unsigned NumSelectorArgs;
+
+  // Result type of this method.
+  QualType MethodDeclType;
+  
+  // Type source information for the result type.
+  TypeSourceInfo *ResultTInfo;
+
+  /// ParamInfo - List of pointers to VarDecls for the formal parameters of this
+  /// Method.
+  ObjCList<ParmVarDecl> ParamInfo;
+
+  /// List of attributes for this method declaration.
+  SourceLocation EndLoc; // the location of the ';' or '}'.
+
+  // The following are only used for method definitions, null otherwise.
+  // FIXME: space savings opportunity, consider a sub-class.
+  Stmt *Body;
+
+  /// SelfDecl - Decl for the implicit self parameter. This is lazily
+  /// constructed by createImplicitParams.
+  ImplicitParamDecl *SelfDecl;
+  /// CmdDecl - Decl for the implicit _cmd parameter. This is lazily
+  /// constructed by createImplicitParams.
+  ImplicitParamDecl *CmdDecl;
+
+  ObjCMethodDecl(SourceLocation beginLoc, SourceLocation endLoc,
+                 Selector SelInfo, QualType T,
+                 TypeSourceInfo *ResultTInfo,
+                 DeclContext *contextDecl,
+                 bool isInstance = true,
+                 bool isVariadic = false,
+                 bool isSynthesized = false,
+                 ImplementationControl impControl = None,
+                 unsigned numSelectorArgs = 0)
+  : NamedDecl(ObjCMethod, contextDecl, beginLoc, SelInfo),
+    DeclContext(ObjCMethod),
+    IsInstance(isInstance), IsVariadic(isVariadic),
+    IsSynthesized(isSynthesized),
+    DeclImplementation(impControl), objcDeclQualifier(OBJC_TQ_None),
+    NumSelectorArgs(numSelectorArgs), MethodDeclType(T), 
+    ResultTInfo(ResultTInfo),
+    EndLoc(endLoc), Body(0), SelfDecl(0), CmdDecl(0) {}
+
+  virtual ~ObjCMethodDecl() {}
+
+  /// \brief A definition will return its interface declaration.
+  /// An interface declaration will return its definition.
+  /// Otherwise it will return itself.
+  virtual ObjCMethodDecl *getNextRedeclaration();
+
+public:
+
+  /// Destroy - Call destructors and release memory.
+  virtual void Destroy(ASTContext& C);
+
+  static ObjCMethodDecl *Create(ASTContext &C,
+                                SourceLocation beginLoc,
+                                SourceLocation endLoc, Selector SelInfo,
+                                QualType T, 
+                                TypeSourceInfo *ResultTInfo,
+                                DeclContext *contextDecl,
+                                bool isInstance = true,
+                                bool isVariadic = false,
+                                bool isSynthesized = false,
+                                ImplementationControl impControl = None,
+                                unsigned numSelectorArgs = 0);
+
+  virtual ObjCMethodDecl *getCanonicalDecl();
+  const ObjCMethodDecl *getCanonicalDecl() const {
+    return const_cast<ObjCMethodDecl*>(this)->getCanonicalDecl();
+  }
+
+  ObjCDeclQualifier getObjCDeclQualifier() const {
+    return ObjCDeclQualifier(objcDeclQualifier);
+  }
+  void setObjCDeclQualifier(ObjCDeclQualifier QV) { objcDeclQualifier = QV; }
+
+  unsigned getNumSelectorArgs() const { return NumSelectorArgs; }
+  void setNumSelectorArgs(unsigned numSelectorArgs) { 
+    NumSelectorArgs = numSelectorArgs; 
+  }
+  
+  // Location information, modeled after the Stmt API.
+  SourceLocation getLocStart() const { return getLocation(); }
+  SourceLocation getLocEnd() const { return EndLoc; }
+  void setEndLoc(SourceLocation Loc) { EndLoc = Loc; }
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(getLocation(), EndLoc);
+  }
+
+  ObjCInterfaceDecl *getClassInterface();
+  const ObjCInterfaceDecl *getClassInterface() const {
+    return const_cast<ObjCMethodDecl*>(this)->getClassInterface();
+  }
+
+  Selector getSelector() const { return getDeclName().getObjCSelector(); }
+
+  QualType getResultType() const { return MethodDeclType; }
+  void setResultType(QualType T) { MethodDeclType = T; }
+
+  TypeSourceInfo *getResultTypeSourceInfo() const { return ResultTInfo; }
+  void setResultTypeSourceInfo(TypeSourceInfo *TInfo) { ResultTInfo = TInfo; }
+
+  // Iterator access to formal parameters.
+  unsigned param_size() const { return ParamInfo.size(); }
+  typedef ObjCList<ParmVarDecl>::iterator param_iterator;
+  param_iterator param_begin() const { return ParamInfo.begin(); }
+  param_iterator param_end() const { return ParamInfo.end(); }
+  // This method returns and of the parameters which are part of the selector
+  // name mangling requirements.
+  param_iterator sel_param_end() const { 
+    return ParamInfo.begin() + NumSelectorArgs; 
+  }
+
+  void setMethodParams(ASTContext &C, ParmVarDecl *const *List, unsigned Num,
+                       unsigned numSelectorArgs) {
+    ParamInfo.set(List, Num, C);
+    NumSelectorArgs = numSelectorArgs; 
+  }
+
+  // Iterator access to parameter types.
+  typedef std::const_mem_fun_t<QualType, ParmVarDecl> deref_fun;
+  typedef llvm::mapped_iterator<param_iterator, deref_fun> arg_type_iterator;
+
+  arg_type_iterator arg_type_begin() const {
+    return llvm::map_iterator(param_begin(), deref_fun(&ParmVarDecl::getType));
+  }
+  arg_type_iterator arg_type_end() const {
+    return llvm::map_iterator(param_end(), deref_fun(&ParmVarDecl::getType));
+  }
+
+  /// createImplicitParams - Used to lazily create the self and cmd
+  /// implict parameters. This must be called prior to using getSelfDecl()
+  /// or getCmdDecl(). The call is ignored if the implicit paramters
+  /// have already been created.
+  void createImplicitParams(ASTContext &Context, const ObjCInterfaceDecl *ID);
+
+  ImplicitParamDecl * getSelfDecl() const { return SelfDecl; }
+  void setSelfDecl(ImplicitParamDecl *SD) { SelfDecl = SD; }
+  ImplicitParamDecl * getCmdDecl() const { return CmdDecl; }
+  void setCmdDecl(ImplicitParamDecl *CD) { CmdDecl = CD; }
+
+  bool isInstanceMethod() const { return IsInstance; }
+  void setInstanceMethod(bool isInst) { IsInstance = isInst; }
+  bool isVariadic() const { return IsVariadic; }
+  void setVariadic(bool isVar) { IsVariadic = isVar; }
+
+  bool isClassMethod() const { return !IsInstance; }
+
+  bool isSynthesized() const { return IsSynthesized; }
+  void setSynthesized(bool isSynth) { IsSynthesized = isSynth; }
+
+  // Related to protocols declared in  @protocol
+  void setDeclImplementation(ImplementationControl ic) {
+    DeclImplementation = ic;
+  }
+  ImplementationControl getImplementationControl() const {
+    return ImplementationControl(DeclImplementation);
+  }
+
+  virtual Stmt *getBody() const {
+    return (Stmt*) Body;
+  }
+  CompoundStmt *getCompoundBody() { return (CompoundStmt*)Body; }
+  void setBody(Stmt *B) { Body = B; }
+
+  /// \brief Returns whether this specific method is a definition.
+  bool isThisDeclarationADefinition() const { return Body; }
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classof(const ObjCMethodDecl *D) { return true; }
+  static bool classofKind(Kind K) { return K == ObjCMethod; }
+  static DeclContext *castToDeclContext(const ObjCMethodDecl *D) {
+    return static_cast<DeclContext *>(const_cast<ObjCMethodDecl*>(D));
+  }
+  static ObjCMethodDecl *castFromDeclContext(const DeclContext *DC) {
+    return static_cast<ObjCMethodDecl *>(const_cast<DeclContext*>(DC));
+  }
+};
+
+/// ObjCMethodList - a linked list of methods with different signatures.
+struct ObjCMethodList {
+  ObjCMethodDecl *Method;
+  ObjCMethodList *Next;
+
+  ObjCMethodList() {
+    Method = 0;
+    Next = 0;
+  }
+  ObjCMethodList(ObjCMethodDecl *M, ObjCMethodList *C) {
+    Method = M;
+    Next = C;
+  }
+};
+
+/// ObjCContainerDecl - Represents a container for method declarations.
+/// Current sub-classes are ObjCInterfaceDecl, ObjCCategoryDecl,
+/// ObjCProtocolDecl, and ObjCImplDecl.
+///
+class ObjCContainerDecl : public NamedDecl, public DeclContext {
+  // These two locations in the range mark the end of the method container.
+  // The first points to the '@' token, and the second to the 'end' token.
+  SourceRange AtEnd;
+public:
+
+  ObjCContainerDecl(Kind DK, DeclContext *DC, SourceLocation L,
+                    IdentifierInfo *Id)
+    : NamedDecl(DK, DC, L, Id), DeclContext(DK) {}
+
+  virtual ~ObjCContainerDecl() {}
+
+  // Iterator access to properties.
+  typedef specific_decl_iterator<ObjCPropertyDecl> prop_iterator;
+  prop_iterator prop_begin() const {
+    return prop_iterator(decls_begin());
+  }
+  prop_iterator prop_end() const {
+    return prop_iterator(decls_end());
+  }
+
+  // Iterator access to instance/class methods.
+  typedef specific_decl_iterator<ObjCMethodDecl> method_iterator;
+  method_iterator meth_begin() const {
+    return method_iterator(decls_begin());
+  }
+  method_iterator meth_end() const {
+    return method_iterator(decls_end());
+  }
+
+  typedef filtered_decl_iterator<ObjCMethodDecl,
+                                 &ObjCMethodDecl::isInstanceMethod>
+    instmeth_iterator;
+  instmeth_iterator instmeth_begin() const {
+    return instmeth_iterator(decls_begin());
+  }
+  instmeth_iterator instmeth_end() const {
+    return instmeth_iterator(decls_end());
+  }
+
+  typedef filtered_decl_iterator<ObjCMethodDecl,
+                                 &ObjCMethodDecl::isClassMethod>
+    classmeth_iterator;
+  classmeth_iterator classmeth_begin() const {
+    return classmeth_iterator(decls_begin());
+  }
+  classmeth_iterator classmeth_end() const {
+    return classmeth_iterator(decls_end());
+  }
+
+  // Get the local instance/class method declared in this interface.
+  ObjCMethodDecl *getMethod(Selector Sel, bool isInstance) const;
+  ObjCMethodDecl *getInstanceMethod(Selector Sel) const {
+    return getMethod(Sel, true/*isInstance*/);
+  }
+  ObjCMethodDecl *getClassMethod(Selector Sel) const {
+    return getMethod(Sel, false/*isInstance*/);
+  }
+  ObjCIvarDecl *getIvarDecl(IdentifierInfo *Id) const;
+
+  ObjCPropertyDecl *FindPropertyDeclaration(IdentifierInfo *PropertyId) const;
+
+  // Marks the end of the container.
+  SourceRange getAtEndRange() const {
+    return AtEnd;
+  }
+  void setAtEndRange(SourceRange atEnd) {
+    AtEnd = atEnd;
+  }
+
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(getLocation(), getAtEndRange().getEnd());
+  }
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classof(const ObjCContainerDecl *D) { return true; }
+  static bool classofKind(Kind K) {
+    return K >= ObjCContainerFirst &&
+           K <= ObjCContainerLast;
+  }
+
+  static DeclContext *castToDeclContext(const ObjCContainerDecl *D) {
+    return static_cast<DeclContext *>(const_cast<ObjCContainerDecl*>(D));
+  }
+  static ObjCContainerDecl *castFromDeclContext(const DeclContext *DC) {
+    return static_cast<ObjCContainerDecl *>(const_cast<DeclContext*>(DC));
+  }
+};
+
+/// ObjCInterfaceDecl - Represents an ObjC class declaration. For example:
+///
+///   // MostPrimitive declares no super class (not particularly useful).
+///   @interface MostPrimitive
+///     // no instance variables or methods.
+///   @end
+///
+///   // NSResponder inherits from NSObject & implements NSCoding (a protocol).
+///   @interface NSResponder : NSObject <NSCoding>
+///   { // instance variables are represented by ObjCIvarDecl.
+///     id nextResponder; // nextResponder instance variable.
+///   }
+///   - (NSResponder *)nextResponder; // return a pointer to NSResponder.
+///   - (void)mouseMoved:(NSEvent *)theEvent; // return void, takes a pointer
+///   @end                                    // to an NSEvent.
+///
+///   Unlike C/C++, forward class declarations are accomplished with @class.
+///   Unlike C/C++, @class allows for a list of classes to be forward declared.
+///   Unlike C++, ObjC is a single-rooted class model. In Cocoa, classes
+///   typically inherit from NSObject (an exception is NSProxy).
+///
+class ObjCInterfaceDecl : public ObjCContainerDecl {
+  /// TypeForDecl - This indicates the Type object that represents this
+  /// TypeDecl.  It is a cache maintained by ASTContext::getObjCInterfaceType
+  mutable Type *TypeForDecl;
+  friend class ASTContext;
+
+  /// Class's super class.
+  ObjCInterfaceDecl *SuperClass;
+
+  /// Protocols referenced in interface header declaration
+  ObjCProtocolList ReferencedProtocols;
+
+  /// List of categories defined for this class.
+  /// FIXME: Why is this a linked list??
+  ObjCCategoryDecl *CategoryList;
+
+  bool ForwardDecl:1; // declared with @class.
+  bool InternalInterface:1; // true - no @interface for @implementation
+
+  SourceLocation ClassLoc; // location of the class identifier.
+  SourceLocation SuperClassLoc; // location of the super class identifier.
+  SourceLocation EndLoc; // marks the '>', '}', or identifier.
+
+  ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id,
+                    SourceLocation CLoc, bool FD, bool isInternal);
+
+  virtual ~ObjCInterfaceDecl() {}
+
+public:
+
+  /// Destroy - Call destructors and release memory.
+  virtual void Destroy(ASTContext& C);
+
+  static ObjCInterfaceDecl *Create(ASTContext &C, DeclContext *DC,
+                                   SourceLocation atLoc,
+                                   IdentifierInfo *Id,
+                                   SourceLocation ClassLoc = SourceLocation(),
+                                   bool ForwardDecl = false,
+                                   bool isInternal = false);
+  const ObjCProtocolList &getReferencedProtocols() const {
+    return ReferencedProtocols;
+  }
+
+  ObjCImplementationDecl *getImplementation() const;
+  void setImplementation(ObjCImplementationDecl *ImplD);
+
+  ObjCCategoryDecl *FindCategoryDeclaration(IdentifierInfo *CategoryId) const;
+
+  // Get the local instance/class method declared in a category.
+  ObjCMethodDecl *getCategoryInstanceMethod(Selector Sel) const;
+  ObjCMethodDecl *getCategoryClassMethod(Selector Sel) const;
+  ObjCMethodDecl *getCategoryMethod(Selector Sel, bool isInstance) const {
+    return isInstance ? getInstanceMethod(Sel)
+                      : getClassMethod(Sel);
+  }
+
+  typedef ObjCProtocolList::iterator protocol_iterator;
+  protocol_iterator protocol_begin() const {return ReferencedProtocols.begin();}
+  protocol_iterator protocol_end() const { return ReferencedProtocols.end(); }
+  typedef ObjCProtocolList::loc_iterator protocol_loc_iterator;
+  protocol_loc_iterator protocol_loc_begin() const { 
+    return ReferencedProtocols.loc_begin(); 
+  }
+  protocol_loc_iterator protocol_loc_end() const { 
+    return ReferencedProtocols.loc_end(); 
+  }
+  unsigned protocol_size() const { return ReferencedProtocols.size(); }
+
+  typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
+  ivar_iterator ivar_begin() const { return  ivar_iterator(decls_begin()); }
+  ivar_iterator ivar_end() const { return ivar_iterator(decls_end()); }
+  unsigned ivar_size() const {
+    return std::distance(ivar_begin(), ivar_end());
+  }
+  bool ivar_empty() const { return ivar_begin() == ivar_end(); }
+
+  /// setProtocolList - Set the list of protocols that this interface
+  /// implements.
+  void setProtocolList(ObjCProtocolDecl *const* List, unsigned Num,
+                       const SourceLocation *Locs, ASTContext &C) {
+    ReferencedProtocols.set(List, Num, Locs, C);
+  }
+
+  /// mergeClassExtensionProtocolList - Merge class extension's protocol list
+  /// into the protocol list for this class.
+  void mergeClassExtensionProtocolList(ObjCProtocolDecl *const* List, 
+                                       unsigned Num,
+                                       const SourceLocation *Locs,
+                                       ASTContext &C);
+
+  bool isForwardDecl() const { return ForwardDecl; }
+  void setForwardDecl(bool val) { ForwardDecl = val; }
+
+  ObjCInterfaceDecl *getSuperClass() const { return SuperClass; }
+  void setSuperClass(ObjCInterfaceDecl * superCls) { SuperClass = superCls; }
+
+  ObjCCategoryDecl* getCategoryList() const { return CategoryList; }
+  void setCategoryList(ObjCCategoryDecl *category) {
+    CategoryList = category;
+  }
+
+  ObjCCategoryDecl* getClassExtension() const;
+
+  ObjCPropertyDecl
+    *FindPropertyVisibleInPrimaryClass(IdentifierInfo *PropertyId) const;
+
+  /// isSuperClassOf - Return true if this class is the specified class or is a
+  /// super class of the specified interface class.
+  bool isSuperClassOf(const ObjCInterfaceDecl *I) const {
+    // If RHS is derived from LHS it is OK; else it is not OK.
+    while (I != NULL) {
+      if (this == I)
+        return true;
+      I = I->getSuperClass();
+    }
+    return false;
+  }
+
+  ObjCIvarDecl *lookupInstanceVariable(IdentifierInfo *IVarName,
+                                       ObjCInterfaceDecl *&ClassDeclared);
+  ObjCIvarDecl *lookupInstanceVariable(IdentifierInfo *IVarName) {
+    ObjCInterfaceDecl *ClassDeclared;
+    return lookupInstanceVariable(IVarName, ClassDeclared);
+  }
+
+  // Lookup a method. First, we search locally. If a method isn't
+  // found, we search referenced protocols and class categories.
+  ObjCMethodDecl *lookupMethod(Selector Sel, bool isInstance) const;
+  ObjCMethodDecl *lookupInstanceMethod(Selector Sel) const {
+    return lookupMethod(Sel, true/*isInstance*/);
+  }
+  ObjCMethodDecl *lookupClassMethod(Selector Sel) const {
+    return lookupMethod(Sel, false/*isInstance*/);
+  }
+  ObjCInterfaceDecl *lookupInheritedClass(const IdentifierInfo *ICName);
+  
+  // Lookup a method in the classes implementation hierarchy.
+  ObjCMethodDecl *lookupPrivateInstanceMethod(const Selector &Sel);
+
+  // Location information, modeled after the Stmt API.
+  SourceLocation getLocStart() const { return getLocation(); } // '@'interface
+  SourceLocation getLocEnd() const { return EndLoc; }
+  void setLocEnd(SourceLocation LE) { EndLoc = LE; }
+
+  void setClassLoc(SourceLocation Loc) { ClassLoc = Loc; }
+  SourceLocation getClassLoc() const { return ClassLoc; }
+  void setSuperClassLoc(SourceLocation Loc) { SuperClassLoc = Loc; }
+  SourceLocation getSuperClassLoc() const { return SuperClassLoc; }
+
+  /// isImplicitInterfaceDecl - check that this is an implicitly declared
+  /// ObjCInterfaceDecl node. This is for legacy objective-c @implementation
+  /// declaration without an @interface declaration.
+  bool isImplicitInterfaceDecl() const { return InternalInterface; }
+  void setImplicitInterfaceDecl(bool val) { InternalInterface = val; }
+
+  /// ClassImplementsProtocol - Checks that 'lProto' protocol
+  /// has been implemented in IDecl class, its super class or categories (if
+  /// lookupCategory is true).
+  bool ClassImplementsProtocol(ObjCProtocolDecl *lProto,
+                               bool lookupCategory,
+                               bool RHSIsQualifiedID = false);
+
+  // Low-level accessor
+  Type *getTypeForDecl() const { return TypeForDecl; }
+  void setTypeForDecl(Type *TD) const { TypeForDecl = TD; }
+
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classof(const ObjCInterfaceDecl *D) { return true; }
+  static bool classofKind(Kind K) { return K == ObjCInterface; }
+};
+
+/// ObjCIvarDecl - Represents an ObjC instance variable. In general, ObjC
+/// instance variables are identical to C. The only exception is Objective-C
+/// supports C++ style access control. For example:
+///
+///   @interface IvarExample : NSObject
+///   {
+///     id defaultToProtected;
+///   @public:
+///     id canBePublic; // same as C++.
+///   @protected:
+///     id canBeProtected; // same as C++.
+///   @package:
+///     id canBePackage; // framework visibility (not available in C++).
+///   }
+///
+class ObjCIvarDecl : public FieldDecl {
+public:
+  enum AccessControl {
+    None, Private, Protected, Public, Package
+  };
+
+private:
+  ObjCIvarDecl(ObjCContainerDecl *DC, SourceLocation L, IdentifierInfo *Id,
+               QualType T, TypeSourceInfo *TInfo, AccessControl ac, Expr *BW)
+    : FieldDecl(ObjCIvar, DC, L, Id, T, TInfo, BW, /*Mutable=*/false),
+      DeclAccess(ac) {}
+
+public:
+  static ObjCIvarDecl *Create(ASTContext &C, ObjCContainerDecl *DC,
+                              SourceLocation L, IdentifierInfo *Id, QualType T,
+                              TypeSourceInfo *TInfo,
+                              AccessControl ac, Expr *BW = NULL);
+
+  /// \brief Return the class interface that this ivar is logically contained
+  /// in; this is either the interface where the ivar was declared, or the
+  /// interface the ivar is conceptually a part of in the case of synthesized
+  /// ivars.
+  const ObjCInterfaceDecl *getContainingInterface() const;
+
+  void setAccessControl(AccessControl ac) { DeclAccess = ac; }
+
+  AccessControl getAccessControl() const { return AccessControl(DeclAccess); }
+
+  AccessControl getCanonicalAccessControl() const {
+    return DeclAccess == None ? Protected : AccessControl(DeclAccess);
+  }
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classof(const ObjCIvarDecl *D) { return true; }
+  static bool classofKind(Kind K) { return K == ObjCIvar; }
+private:
+  // NOTE: VC++ treats enums as signed, avoid using the AccessControl enum
+  unsigned DeclAccess : 3;
+};
+
+
+/// ObjCAtDefsFieldDecl - Represents a field declaration created by an
+///  @defs(...).
+class ObjCAtDefsFieldDecl : public FieldDecl {
+private:
+  ObjCAtDefsFieldDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
+                      QualType T, Expr *BW)
+    : FieldDecl(ObjCAtDefsField, DC, L, Id, T,
+                /*TInfo=*/0, // FIXME: Do ObjCAtDefs have declarators ?
+                BW, /*Mutable=*/false) {}
+
+public:
+  static ObjCAtDefsFieldDecl *Create(ASTContext &C, DeclContext *DC,
+                                     SourceLocation L,
+                                     IdentifierInfo *Id, QualType T,
+                                     Expr *BW);
+
+  virtual void Destroy(ASTContext& C);
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classof(const ObjCAtDefsFieldDecl *D) { return true; }
+  static bool classofKind(Kind K) { return K == ObjCAtDefsField; }
+};
+
+/// ObjCProtocolDecl - Represents a protocol declaration. ObjC protocols
+/// declare a pure abstract type (i.e no instance variables are permitted).
+/// Protocols orginally drew inspiration from C++ pure virtual functions (a C++
+/// feature with nice semantics and lousy syntax:-). Here is an example:
+///
+/// @protocol NSDraggingInfo <refproto1, refproto2>
+/// - (NSWindow *)draggingDestinationWindow;
+/// - (NSImage *)draggedImage;
+/// @end
+///
+/// This says that NSDraggingInfo requires two methods and requires everything
+/// that the two "referenced protocols" 'refproto1' and 'refproto2' require as
+/// well.
+///
+/// @interface ImplementsNSDraggingInfo : NSObject <NSDraggingInfo>
+/// @end
+///
+/// ObjC protocols inspired Java interfaces. Unlike Java, ObjC classes and
+/// protocols are in distinct namespaces. For example, Cocoa defines both
+/// an NSObject protocol and class (which isn't allowed in Java). As a result,
+/// protocols are referenced using angle brackets as follows:
+///
+/// id <NSDraggingInfo> anyObjectThatImplementsNSDraggingInfo;
+///
+class ObjCProtocolDecl : public ObjCContainerDecl {
+  /// Referenced protocols
+  ObjCProtocolList ReferencedProtocols;
+
+  bool isForwardProtoDecl; // declared with @protocol.
+
+  SourceLocation EndLoc; // marks the '>' or identifier.
+
+  ObjCProtocolDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id)
+    : ObjCContainerDecl(ObjCProtocol, DC, L, Id),
+      isForwardProtoDecl(true) {
+  }
+
+  virtual ~ObjCProtocolDecl() {}
+
+public:
+  static ObjCProtocolDecl *Create(ASTContext &C, DeclContext *DC,
+                                  SourceLocation L, IdentifierInfo *Id);
+
+  /// Destroy - Call destructors and release memory.
+  virtual void Destroy(ASTContext& C);
+
+  const ObjCProtocolList &getReferencedProtocols() const {
+    return ReferencedProtocols;
+  }
+  typedef ObjCProtocolList::iterator protocol_iterator;
+  protocol_iterator protocol_begin() const {return ReferencedProtocols.begin();}
+  protocol_iterator protocol_end() const { return ReferencedProtocols.end(); }
+  typedef ObjCProtocolList::loc_iterator protocol_loc_iterator;
+  protocol_loc_iterator protocol_loc_begin() const { 
+    return ReferencedProtocols.loc_begin(); 
+  }
+  protocol_loc_iterator protocol_loc_end() const { 
+    return ReferencedProtocols.loc_end(); 
+  }
+  unsigned protocol_size() const { return ReferencedProtocols.size(); }
+
+  /// setProtocolList - Set the list of protocols that this interface
+  /// implements.
+  void setProtocolList(ObjCProtocolDecl *const*List, unsigned Num,
+                       const SourceLocation *Locs, ASTContext &C) {
+    ReferencedProtocols.set(List, Num, Locs, C);
+  }
+
+  ObjCProtocolDecl *lookupProtocolNamed(IdentifierInfo *PName);
+
+  // Lookup a method. First, we search locally. If a method isn't
+  // found, we search referenced protocols and class categories.
+  ObjCMethodDecl *lookupMethod(Selector Sel, bool isInstance) const;
+  ObjCMethodDecl *lookupInstanceMethod(Selector Sel) const {
+    return lookupMethod(Sel, true/*isInstance*/);
+  }
+  ObjCMethodDecl *lookupClassMethod(Selector Sel) const {
+    return lookupMethod(Sel, false/*isInstance*/);
+  }
+  
+  bool isForwardDecl() const { return isForwardProtoDecl; }
+  void setForwardDecl(bool val) { isForwardProtoDecl = val; }
+
+  // Location information, modeled after the Stmt API.
+  SourceLocation getLocStart() const { return getLocation(); } // '@'protocol
+  SourceLocation getLocEnd() const { return EndLoc; }
+  void setLocEnd(SourceLocation LE) { EndLoc = LE; }
+
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classof(const ObjCProtocolDecl *D) { return true; }
+  static bool classofKind(Kind K) { return K == ObjCProtocol; }
+};
+
+/// ObjCClassDecl - Specifies a list of forward class declarations. For example:
+///
+/// @class NSCursor, NSImage, NSPasteboard, NSWindow;
+///
+class ObjCClassDecl : public Decl {
+public:
+  class ObjCClassRef {
+    ObjCInterfaceDecl *ID;
+    SourceLocation L;
+  public:
+    ObjCClassRef(ObjCInterfaceDecl *d, SourceLocation l) : ID(d), L(l) {}
+    SourceLocation getLocation() const { return L; }
+    ObjCInterfaceDecl *getInterface() const { return ID; }
+  };
+private:
+  ObjCClassRef *ForwardDecls;
+  unsigned NumDecls;
+
+  ObjCClassDecl(DeclContext *DC, SourceLocation L,
+                ObjCInterfaceDecl *const *Elts, const SourceLocation *Locs,                
+                unsigned nElts, ASTContext &C);
+  virtual ~ObjCClassDecl() {}
+public:
+
+  /// Destroy - Call destructors and release memory.
+  virtual void Destroy(ASTContext& C);
+
+  static ObjCClassDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L,
+                               ObjCInterfaceDecl *const *Elts = 0,
+                               const SourceLocation *Locs = 0,
+                               unsigned nElts = 0);
+  
+  virtual SourceRange getSourceRange() const;
+
+  typedef const ObjCClassRef* iterator;
+  iterator begin() const { return ForwardDecls; }
+  iterator end() const { return ForwardDecls + NumDecls; }
+  unsigned size() const { return NumDecls; }
+
+  /// setClassList - Set the list of forward classes.
+  void setClassList(ASTContext &C, ObjCInterfaceDecl*const*List,
+                    const SourceLocation *Locs, unsigned Num);
+
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classof(const ObjCClassDecl *D) { return true; }
+  static bool classofKind(Kind K) { return K == ObjCClass; }
+};
+
+/// ObjCForwardProtocolDecl - Specifies a list of forward protocol declarations.
+/// For example:
+///
+/// @protocol NSTextInput, NSChangeSpelling, NSDraggingInfo;
+///
+class ObjCForwardProtocolDecl : public Decl {
+  ObjCProtocolList ReferencedProtocols;
+
+  ObjCForwardProtocolDecl(DeclContext *DC, SourceLocation L,
+                          ObjCProtocolDecl *const *Elts, unsigned nElts,
+                          const SourceLocation *Locs, ASTContext &C);
+  virtual ~ObjCForwardProtocolDecl() {}
+
+public:
+  static ObjCForwardProtocolDecl *Create(ASTContext &C, DeclContext *DC,
+                                         SourceLocation L,
+                                         ObjCProtocolDecl *const *Elts,
+                                         unsigned Num,
+                                         const SourceLocation *Locs);
+
+  static ObjCForwardProtocolDecl *Create(ASTContext &C, DeclContext *DC,
+                                         SourceLocation L) {
+    return Create(C, DC, L, 0, 0, 0);
+  }
+
+  /// Destroy - Call destructors and release memory.
+  virtual void Destroy(ASTContext& C);
+
+  typedef ObjCProtocolList::iterator protocol_iterator;
+  protocol_iterator protocol_begin() const {return ReferencedProtocols.begin();}
+  protocol_iterator protocol_end() const { return ReferencedProtocols.end(); }
+  typedef ObjCProtocolList::loc_iterator protocol_loc_iterator;
+  protocol_loc_iterator protocol_loc_begin() const { 
+    return ReferencedProtocols.loc_begin(); 
+  }
+  protocol_loc_iterator protocol_loc_end() const { 
+    return ReferencedProtocols.loc_end(); 
+  }
+
+  unsigned protocol_size() const { return ReferencedProtocols.size(); }
+
+  /// setProtocolList - Set the list of forward protocols.
+  void setProtocolList(ObjCProtocolDecl *const*List, unsigned Num,
+                       const SourceLocation *Locs, ASTContext &C) {
+    ReferencedProtocols.set(List, Num, Locs, C);
+  }
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classof(const ObjCForwardProtocolDecl *D) { return true; }
+  static bool classofKind(Kind K) { return K == ObjCForwardProtocol; }
+};
+
+/// ObjCCategoryDecl - Represents a category declaration. A category allows
+/// you to add methods to an existing class (without subclassing or modifying
+/// the original class interface or implementation:-). Categories don't allow
+/// you to add instance data. The following example adds "myMethod" to all
+/// NSView's within a process:
+///
+/// @interface NSView (MyViewMethods)
+/// - myMethod;
+/// @end
+///
+/// Categories also allow you to split the implementation of a class across
+/// several files (a feature more naturally supported in C++).
+///
+/// Categories were originally inspired by dynamic languages such as Common
+/// Lisp and Smalltalk.  More traditional class-based languages (C++, Java)
+/// don't support this level of dynamism, which is both powerful and dangerous.
+///
+class ObjCCategoryDecl : public ObjCContainerDecl {
+  /// Interface belonging to this category
+  ObjCInterfaceDecl *ClassInterface;
+
+  /// referenced protocols in this category.
+  ObjCProtocolList ReferencedProtocols;
+
+  /// Next category belonging to this class.
+  /// FIXME: this should not be a singly-linked list.  Move storage elsewhere.
+  ObjCCategoryDecl *NextClassCategory;
+
+  /// \brief The location of the '@' in '@interface'
+  SourceLocation AtLoc;
+
+  /// \brief The location of the category name in this declaration.
+  SourceLocation CategoryNameLoc;
+
+  ObjCCategoryDecl(DeclContext *DC, SourceLocation AtLoc, 
+                   SourceLocation ClassNameLoc, SourceLocation CategoryNameLoc,
+                   IdentifierInfo *Id)
+    : ObjCContainerDecl(ObjCCategory, DC, ClassNameLoc, Id),
+      ClassInterface(0), NextClassCategory(0), AtLoc(AtLoc), 
+      CategoryNameLoc(CategoryNameLoc) {
+  }
+public:
+
+  static ObjCCategoryDecl *Create(ASTContext &C, DeclContext *DC,
+                                  SourceLocation AtLoc, 
+                                  SourceLocation ClassNameLoc,
+                                  SourceLocation CategoryNameLoc,
+                                  IdentifierInfo *Id);
+
+  ObjCInterfaceDecl *getClassInterface() { return ClassInterface; }
+  const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; }
+  void setClassInterface(ObjCInterfaceDecl *IDecl) { ClassInterface = IDecl; }
+
+  ObjCCategoryImplDecl *getImplementation() const;
+  void setImplementation(ObjCCategoryImplDecl *ImplD);
+
+  /// setProtocolList - Set the list of protocols that this interface
+  /// implements.
+  void setProtocolList(ObjCProtocolDecl *const*List, unsigned Num,
+                       const SourceLocation *Locs, ASTContext &C) {
+    ReferencedProtocols.set(List, Num, Locs, C);
+  }
+
+  const ObjCProtocolList &getReferencedProtocols() const {
+    return ReferencedProtocols;
+  }
+
+  typedef ObjCProtocolList::iterator protocol_iterator;
+  protocol_iterator protocol_begin() const {return ReferencedProtocols.begin();}
+  protocol_iterator protocol_end() const { return ReferencedProtocols.end(); }
+  unsigned protocol_size() const { return ReferencedProtocols.size(); }
+  typedef ObjCProtocolList::loc_iterator protocol_loc_iterator;
+  protocol_loc_iterator protocol_loc_begin() const { 
+    return ReferencedProtocols.loc_begin(); 
+  }
+  protocol_loc_iterator protocol_loc_end() const { 
+    return ReferencedProtocols.loc_end(); 
+  }
+
+  ObjCCategoryDecl *getNextClassCategory() const { return NextClassCategory; }
+  void setNextClassCategory(ObjCCategoryDecl *Cat) {
+    NextClassCategory = Cat;
+  }
+  void insertNextClassCategory() {
+    NextClassCategory = ClassInterface->getCategoryList();
+    ClassInterface->setCategoryList(this);
+  }
+
+  bool IsClassExtension() const { return getIdentifier() == 0; }
+  
+  typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
+  ivar_iterator ivar_begin() const {
+    return ivar_iterator(decls_begin());
+  }
+  ivar_iterator ivar_end() const {
+    return ivar_iterator(decls_end());
+  }
+  unsigned ivar_size() const {
+    return std::distance(ivar_begin(), ivar_end());
+  }
+  bool ivar_empty() const {
+    return ivar_begin() == ivar_end();
+  }
+  
+  SourceLocation getAtLoc() const { return AtLoc; }
+  void setAtLoc(SourceLocation At) { AtLoc = At; }
+
+  SourceLocation getCategoryNameLoc() const { return CategoryNameLoc; }
+  void setCategoryNameLoc(SourceLocation Loc) { CategoryNameLoc = Loc; }
+
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(AtLoc, getAtEndRange().getEnd());
+  }
+
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classof(const ObjCCategoryDecl *D) { return true; }
+  static bool classofKind(Kind K) { return K == ObjCCategory; }
+};
+
+class ObjCImplDecl : public ObjCContainerDecl {
+  /// Class interface for this class/category implementation
+  ObjCInterfaceDecl *ClassInterface;
+
+protected:
+  ObjCImplDecl(Kind DK, DeclContext *DC, SourceLocation L,
+               ObjCInterfaceDecl *classInterface)
+    : ObjCContainerDecl(DK, DC, L,
+                        classInterface? classInterface->getIdentifier() : 0),
+      ClassInterface(classInterface) {}
+
+public:
+  virtual ~ObjCImplDecl() {}
+
+  const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; }
+  ObjCInterfaceDecl *getClassInterface() { return ClassInterface; }
+  void setClassInterface(ObjCInterfaceDecl *IFace);
+
+  void addInstanceMethod(ObjCMethodDecl *method) {
+    // FIXME: Context should be set correctly before we get here.
+    method->setLexicalDeclContext(this);
+    addDecl(method);
+  }
+  void addClassMethod(ObjCMethodDecl *method) {
+    // FIXME: Context should be set correctly before we get here.
+    method->setLexicalDeclContext(this);
+    addDecl(method);
+  }
+
+  void addPropertyImplementation(ObjCPropertyImplDecl *property);
+
+  ObjCPropertyImplDecl *FindPropertyImplDecl(IdentifierInfo *propertyId) const;
+  ObjCPropertyImplDecl *FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const;
+
+  // Iterator access to properties.
+  typedef specific_decl_iterator<ObjCPropertyImplDecl> propimpl_iterator;
+  propimpl_iterator propimpl_begin() const {
+    return propimpl_iterator(decls_begin());
+  }
+  propimpl_iterator propimpl_end() const {
+    return propimpl_iterator(decls_end());
+  }
+
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classof(const ObjCImplDecl *D) { return true; }
+  static bool classofKind(Kind K) {
+    return K >= ObjCImplFirst && K <= ObjCImplLast;
+  }
+};
+
+/// ObjCCategoryImplDecl - An object of this class encapsulates a category
+/// @implementation declaration. If a category class has declaration of a
+/// property, its implementation must be specified in the category's
+/// @implementation declaration. Example:
+/// @interface I @end
+/// @interface I(CATEGORY)
+///    @property int p1, d1;
+/// @end
+/// @implementation I(CATEGORY)
+///  @dynamic p1,d1;
+/// @end
+///
+/// ObjCCategoryImplDecl
+class ObjCCategoryImplDecl : public ObjCImplDecl {
+  // Category name
+  IdentifierInfo *Id;
+
+  ObjCCategoryImplDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
+                       ObjCInterfaceDecl *classInterface)
+    : ObjCImplDecl(ObjCCategoryImpl, DC, L, classInterface), Id(Id) {}
+public:
+  static ObjCCategoryImplDecl *Create(ASTContext &C, DeclContext *DC,
+                                      SourceLocation L, IdentifierInfo *Id,
+                                      ObjCInterfaceDecl *classInterface);
+
+  /// getIdentifier - Get the identifier that names the category
+  /// interface associated with this implementation.
+  /// FIXME: This is a bad API, we are overriding the NamedDecl::getIdentifier()
+  /// to mean something different. For example:
+  /// ((NamedDecl *)SomeCategoryImplDecl)->getIdentifier() 
+  /// returns the class interface name, whereas 
+  /// ((ObjCCategoryImplDecl *)SomeCategoryImplDecl)->getIdentifier() 
+  /// returns the category name.
+  IdentifierInfo *getIdentifier() const {
+    return Id;
+  }
+  void setIdentifier(IdentifierInfo *II) { Id = II; }
+
+  ObjCCategoryDecl *getCategoryDecl() const;
+
+  /// getName - Get the name of identifier for the class interface associated
+  /// with this implementation as a StringRef.
+  //
+  // FIXME: This is a bad API, we are overriding the NamedDecl::getName, to mean
+  // something different.
+  llvm::StringRef getName() const {
+    return Id ? Id->getNameStart() : "";
+  }
+
+  /// getNameAsCString - Get the name of identifier for the class
+  /// interface associated with this implementation as a C string
+  /// (const char*).
+  //
+  // FIXME: Deprecated, move clients to getName().
+  const char *getNameAsCString() const {
+    return Id ? Id->getNameStart() : "";
+  }
+
+  /// @brief Get the name of the class associated with this interface.
+  //
+  // FIXME: Deprecated, move clients to getName().
+  std::string getNameAsString() const {
+    return getName();
+  }
+
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classof(const ObjCCategoryImplDecl *D) { return true; }
+  static bool classofKind(Kind K) { return K == ObjCCategoryImpl;}
+};
+
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
+                              const ObjCCategoryImplDecl *CID);
+
+/// ObjCImplementationDecl - Represents a class definition - this is where
+/// method definitions are specified. For example:
+///
+/// @code
+/// @implementation MyClass
+/// - (void)myMethod { /* do something */ }
+/// @end
+/// @endcode
+///
+/// Typically, instance variables are specified in the class interface,
+/// *not* in the implementation. Nevertheless (for legacy reasons), we
+/// allow instance variables to be specified in the implementation.  When
+/// specified, they need to be *identical* to the interface.
+///
+class ObjCImplementationDecl : public ObjCImplDecl {
+  /// Implementation Class's super class.
+  ObjCInterfaceDecl *SuperClass;
+
+  ObjCImplementationDecl(DeclContext *DC, SourceLocation L,
+                         ObjCInterfaceDecl *classInterface,
+                         ObjCInterfaceDecl *superDecl)
+    : ObjCImplDecl(ObjCImplementation, DC, L, classInterface),
+       SuperClass(superDecl){}
+public:
+  static ObjCImplementationDecl *Create(ASTContext &C, DeclContext *DC,
+                                        SourceLocation L,
+                                        ObjCInterfaceDecl *classInterface,
+                                        ObjCInterfaceDecl *superDecl);
+
+  /// getIdentifier - Get the identifier that names the class
+  /// interface associated with this implementation.
+  IdentifierInfo *getIdentifier() const {
+    return getClassInterface()->getIdentifier();
+  }
+
+  /// getName - Get the name of identifier for the class interface associated
+  /// with this implementation as a StringRef.
+  //
+  // FIXME: This is a bad API, we are overriding the NamedDecl::getName, to mean
+  // something different.
+  llvm::StringRef getName() const {
+    assert(getIdentifier() && "Name is not a simple identifier");
+    return getIdentifier()->getName();
+  }
+
+  /// getNameAsCString - Get the name of identifier for the class
+  /// interface associated with this implementation as a C string
+  /// (const char*).
+  //
+  // FIXME: Move to StringRef API.
+  const char *getNameAsCString() const {
+    return getName().data();
+  }
+
+  /// @brief Get the name of the class associated with this interface.
+  //
+  // FIXME: Move to StringRef API.
+  std::string getNameAsString() const {
+    return getName();
+  }
+
+  const ObjCInterfaceDecl *getSuperClass() const { return SuperClass; }
+  ObjCInterfaceDecl *getSuperClass() { return SuperClass; }
+
+  void setSuperClass(ObjCInterfaceDecl * superCls) { SuperClass = superCls; }
+
+  typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
+  ivar_iterator ivar_begin() const {
+    return ivar_iterator(decls_begin());
+  }
+  ivar_iterator ivar_end() const {
+    return ivar_iterator(decls_end());
+  }
+  unsigned ivar_size() const {
+    return std::distance(ivar_begin(), ivar_end());
+  }
+  bool ivar_empty() const {
+    return ivar_begin() == ivar_end();
+  }
+
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classof(const ObjCImplementationDecl *D) { return true; }
+  static bool classofKind(Kind K) { return K == ObjCImplementation; }
+};
+
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
+                              const ObjCImplementationDecl *ID);
+
+/// ObjCCompatibleAliasDecl - Represents alias of a class. This alias is
+/// declared as @compatibility_alias alias class.
+class ObjCCompatibleAliasDecl : public NamedDecl {
+  /// Class that this is an alias of.
+  ObjCInterfaceDecl *AliasedClass;
+
+  ObjCCompatibleAliasDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
+                          ObjCInterfaceDecl* aliasedClass)
+    : NamedDecl(ObjCCompatibleAlias, DC, L, Id), AliasedClass(aliasedClass) {}
+public:
+  static ObjCCompatibleAliasDecl *Create(ASTContext &C, DeclContext *DC,
+                                         SourceLocation L, IdentifierInfo *Id,
+                                         ObjCInterfaceDecl* aliasedClass);
+
+  const ObjCInterfaceDecl *getClassInterface() const { return AliasedClass; }
+  ObjCInterfaceDecl *getClassInterface() { return AliasedClass; }
+  void setClassInterface(ObjCInterfaceDecl *D) { AliasedClass = D; }
+
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classof(const ObjCCompatibleAliasDecl *D) { return true; }
+  static bool classofKind(Kind K) { return K == ObjCCompatibleAlias; }
+
+};
+
+/// ObjCPropertyDecl - Represents one property declaration in an interface.
+/// For example:
+/// @property (assign, readwrite) int MyProperty;
+///
+class ObjCPropertyDecl : public NamedDecl {
+public:
+  enum PropertyAttributeKind {
+    OBJC_PR_noattr    = 0x00,
+    OBJC_PR_readonly  = 0x01,
+    OBJC_PR_getter    = 0x02,
+    OBJC_PR_assign    = 0x04,
+    OBJC_PR_readwrite = 0x08,
+    OBJC_PR_retain    = 0x10,
+    OBJC_PR_copy      = 0x20,
+    OBJC_PR_nonatomic = 0x40,
+    OBJC_PR_setter    = 0x80
+  };
+
+  enum SetterKind { Assign, Retain, Copy };
+  enum PropertyControl { None, Required, Optional };
+private:
+  SourceLocation AtLoc;   // location of @property
+  QualType DeclType;
+  unsigned PropertyAttributes : 8;
+
+  // @required/@optional
+  unsigned PropertyImplementation : 2;
+
+  Selector GetterName;    // getter name of NULL if no getter
+  Selector SetterName;    // setter name of NULL if no setter
+
+  ObjCMethodDecl *GetterMethodDecl; // Declaration of getter instance method
+  ObjCMethodDecl *SetterMethodDecl; // Declaration of setter instance method
+  ObjCIvarDecl *PropertyIvarDecl;   // Synthesize ivar for this property
+
+  ObjCPropertyDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
+                   SourceLocation AtLocation, QualType T)
+    : NamedDecl(ObjCProperty, DC, L, Id), AtLoc(AtLocation), DeclType(T),
+      PropertyAttributes(OBJC_PR_noattr), PropertyImplementation(None),
+      GetterName(Selector()),
+      SetterName(Selector()),
+      GetterMethodDecl(0), SetterMethodDecl(0) , PropertyIvarDecl(0) {}
+public:
+  static ObjCPropertyDecl *Create(ASTContext &C, DeclContext *DC,
+                                  SourceLocation L,
+                                  IdentifierInfo *Id, SourceLocation AtLocation,
+                                  QualType T,
+                                  PropertyControl propControl = None);
+  SourceLocation getAtLoc() const { return AtLoc; }
+  void setAtLoc(SourceLocation L) { AtLoc = L; }
+  
+  QualType getType() const { return DeclType; }
+  void setType(QualType T) { DeclType = T; }
+
+  PropertyAttributeKind getPropertyAttributes() const {
+    return PropertyAttributeKind(PropertyAttributes);
+  }
+  void setPropertyAttributes(PropertyAttributeKind PRVal) {
+    PropertyAttributes |= PRVal;
+  }
+
+ void makeitReadWriteAttribute(void) {
+    PropertyAttributes &= ~OBJC_PR_readonly;
+    PropertyAttributes |= OBJC_PR_readwrite;
+ }
+
+  // Helper methods for accessing attributes.
+
+  /// isReadOnly - Return true iff the property has a setter.
+  bool isReadOnly() const {
+    return (PropertyAttributes & OBJC_PR_readonly);
+  }
+
+  /// getSetterKind - Return the method used for doing assignment in
+  /// the property setter. This is only valid if the property has been
+  /// defined to have a setter.
+  SetterKind getSetterKind() const {
+    if (PropertyAttributes & OBJC_PR_retain)
+      return Retain;
+    if (PropertyAttributes & OBJC_PR_copy)
+      return Copy;
+    return Assign;
+  }
+
+  Selector getGetterName() const { return GetterName; }
+  void setGetterName(Selector Sel) { GetterName = Sel; }
+
+  Selector getSetterName() const { return SetterName; }
+  void setSetterName(Selector Sel) { SetterName = Sel; }
+
+  ObjCMethodDecl *getGetterMethodDecl() const { return GetterMethodDecl; }
+  void setGetterMethodDecl(ObjCMethodDecl *gDecl) { GetterMethodDecl = gDecl; }
+
+  ObjCMethodDecl *getSetterMethodDecl() const { return SetterMethodDecl; }
+  void setSetterMethodDecl(ObjCMethodDecl *gDecl) { SetterMethodDecl = gDecl; }
+
+  // Related to @optional/@required declared in @protocol
+  void setPropertyImplementation(PropertyControl pc) {
+    PropertyImplementation = pc;
+  }
+  PropertyControl getPropertyImplementation() const {
+    return PropertyControl(PropertyImplementation);
+  }
+
+  void setPropertyIvarDecl(ObjCIvarDecl *Ivar) {
+    PropertyIvarDecl = Ivar;
+  }
+  ObjCIvarDecl *getPropertyIvarDecl() const {
+    return PropertyIvarDecl;
+  }
+
+  /// Lookup a property by name in the specified DeclContext.
+  static ObjCPropertyDecl *findPropertyDecl(const DeclContext *DC,
+                                            IdentifierInfo *propertyID);
+
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classof(const ObjCPropertyDecl *D) { return true; }
+  static bool classofKind(Kind K) { return K == ObjCProperty; }
+};
+
+/// ObjCPropertyImplDecl - Represents implementation declaration of a property
+/// in a class or category implementation block. For example:
+/// @synthesize prop1 = ivar1;
+///
+class ObjCPropertyImplDecl : public Decl {
+public:
+  enum Kind {
+    Synthesize,
+    Dynamic
+  };
+private:
+  SourceLocation AtLoc;   // location of @synthesize or @dynamic
+  /// Property declaration being implemented
+  ObjCPropertyDecl *PropertyDecl;
+
+  /// Null for @dynamic. Required for @synthesize.
+  ObjCIvarDecl *PropertyIvarDecl;
+
+  ObjCPropertyImplDecl(DeclContext *DC, SourceLocation atLoc, SourceLocation L,
+                       ObjCPropertyDecl *property,
+                       Kind PK,
+                       ObjCIvarDecl *ivarDecl)
+    : Decl(ObjCPropertyImpl, DC, L), AtLoc(atLoc),
+      PropertyDecl(property), PropertyIvarDecl(ivarDecl) {
+    assert (PK == Dynamic || PropertyIvarDecl);
+  }
+
+public:
+  static ObjCPropertyImplDecl *Create(ASTContext &C, DeclContext *DC,
+                                      SourceLocation atLoc, SourceLocation L,
+                                      ObjCPropertyDecl *property,
+                                      Kind PK,
+                                      ObjCIvarDecl *ivarDecl);
+
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(AtLoc, getLocation());
+  }
+  SourceLocation getLocStart() const { return AtLoc; }
+  void setAtLoc(SourceLocation Loc) { AtLoc = Loc; }
+
+  ObjCPropertyDecl *getPropertyDecl() const {
+    return PropertyDecl;
+  }
+  void setPropertyDecl(ObjCPropertyDecl *Prop) { PropertyDecl = Prop; }
+
+  Kind getPropertyImplementation() const {
+    return PropertyIvarDecl ? Synthesize : Dynamic;
+  }
+
+  ObjCIvarDecl *getPropertyIvarDecl() const {
+    return PropertyIvarDecl;
+  }
+  void setPropertyIvarDecl(ObjCIvarDecl *Ivar) { PropertyIvarDecl = Ivar; }
+
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classof(const ObjCPropertyImplDecl *D) { return true; }
+  static bool classofKind(Decl::Kind K) { return K == ObjCPropertyImpl; }
+};
+
+}  // end namespace clang
+#endif
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h
new file mode 100644
index 0000000..2bb971d
--- /dev/null
+++ b/include/clang/AST/DeclTemplate.h
@@ -0,0 +1,1402 @@
+//===-- DeclTemplate.h - Classes for representing C++ templates -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the C++ template declaration subclasses.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_DECLTEMPLATE_H
+#define LLVM_CLANG_AST_DECLTEMPLATE_H
+
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/TemplateBase.h"
+#include "llvm/ADT/PointerUnion.h"
+#include <limits>
+
+namespace clang {
+
+class TemplateParameterList;
+class TemplateDecl;
+class FunctionTemplateDecl;
+class ClassTemplateDecl;
+class ClassTemplatePartialSpecializationDecl;
+class TemplateTypeParmDecl;
+class NonTypeTemplateParmDecl;
+class TemplateTemplateParmDecl;
+
+/// \brief Stores a template parameter of any kind.
+typedef llvm::PointerUnion3<TemplateTypeParmDecl*, NonTypeTemplateParmDecl*,
+                            TemplateTemplateParmDecl*> TemplateParameter;
+
+/// TemplateParameterList - Stores a list of template parameters for a
+/// TemplateDecl and its derived classes.
+class TemplateParameterList {
+  /// The location of the 'template' keyword.
+  SourceLocation TemplateLoc;
+
+  /// The locations of the '<' and '>' angle brackets.
+  SourceLocation LAngleLoc, RAngleLoc;
+
+  /// The number of template parameters in this template
+  /// parameter list.
+  unsigned NumParams;
+
+  TemplateParameterList(SourceLocation TemplateLoc, SourceLocation LAngleLoc,
+                        NamedDecl **Params, unsigned NumParams,
+                        SourceLocation RAngleLoc);
+
+public:
+  static TemplateParameterList *Create(ASTContext &C,
+                                       SourceLocation TemplateLoc,
+                                       SourceLocation LAngleLoc,
+                                       NamedDecl **Params,
+                                       unsigned NumParams,
+                                       SourceLocation RAngleLoc);
+
+  /// iterator - Iterates through the template parameters in this list.
+  typedef NamedDecl** iterator;
+
+  /// const_iterator - Iterates through the template parameters in this list.
+  typedef NamedDecl* const* const_iterator;
+
+  iterator begin() { return reinterpret_cast<NamedDecl **>(this + 1); }
+  const_iterator begin() const {
+    return reinterpret_cast<NamedDecl * const *>(this + 1);
+  }
+  iterator end() { return begin() + NumParams; }
+  const_iterator end() const { return begin() + NumParams; }
+
+  unsigned size() const { return NumParams; }
+
+  NamedDecl* getParam(unsigned Idx) {
+    assert(Idx < size() && "Template parameter index out-of-range");
+    return begin()[Idx];
+  }
+
+  const NamedDecl* getParam(unsigned Idx) const {
+    assert(Idx < size() && "Template parameter index out-of-range");
+    return begin()[Idx];
+  }
+
+  /// \btief Returns the minimum number of arguments needed to form a
+  /// template specialization. This may be fewer than the number of
+  /// template parameters, if some of the parameters have default
+  /// arguments or if there is a parameter pack.
+  unsigned getMinRequiredArguments() const;
+
+  /// \brief Get the depth of this template parameter list in the set of
+  /// template parameter lists.
+  ///
+  /// The first template parameter list in a declaration will have depth 0,
+  /// the second template parameter list will have depth 1, etc.
+  unsigned getDepth() const;
+  
+  SourceLocation getTemplateLoc() const { return TemplateLoc; }
+  SourceLocation getLAngleLoc() const { return LAngleLoc; }
+  SourceLocation getRAngleLoc() const { return RAngleLoc; }
+
+  SourceRange getSourceRange() const {
+    return SourceRange(TemplateLoc, RAngleLoc);
+  }
+};
+
+/// \brief A helper class for making template argument lists.
+class TemplateArgumentListBuilder {
+  TemplateArgument *StructuredArgs;
+  unsigned MaxStructuredArgs;
+  unsigned NumStructuredArgs;
+
+  TemplateArgument *FlatArgs;
+  unsigned MaxFlatArgs;
+  unsigned NumFlatArgs;
+
+  bool AddingToPack;
+  unsigned PackBeginIndex;
+
+public:
+  TemplateArgumentListBuilder(const TemplateParameterList *Parameters,
+                              unsigned NumTemplateArgs)
+  : StructuredArgs(0), MaxStructuredArgs(Parameters->size()),
+  NumStructuredArgs(0), FlatArgs(0),
+  MaxFlatArgs(std::max(MaxStructuredArgs, NumTemplateArgs)), NumFlatArgs(0),
+  AddingToPack(false), PackBeginIndex(0) { }
+
+  void Append(const TemplateArgument& Arg);
+  void BeginPack();
+  void EndPack();
+
+  void ReleaseArgs();
+
+  unsigned flatSize() const {
+    return NumFlatArgs;
+  }
+  const TemplateArgument *getFlatArguments() const {
+    return FlatArgs;
+  }
+
+  unsigned structuredSize() const {
+    // If we don't have any structured args, just reuse the flat size.
+    if (!StructuredArgs)
+      return flatSize();
+
+    return NumStructuredArgs;
+  }
+  const TemplateArgument *getStructuredArguments() const {
+    // If we don't have any structured args, just reuse the flat args.
+    if (!StructuredArgs)
+      return getFlatArguments();
+
+    return StructuredArgs;
+  }
+};
+
+/// \brief A template argument list.
+///
+/// FIXME: In the future, this class will be extended to support
+/// variadic templates and member templates, which will make some of
+/// the function names below make more sense.
+class TemplateArgumentList {
+  /// \brief The template argument list.
+  ///
+  /// The integer value will be non-zero to indicate that this
+  /// template argument list does not own the pointer.
+  llvm::PointerIntPair<const TemplateArgument *, 1> FlatArguments;
+
+  /// \brief The number of template arguments in this template
+  /// argument list.
+  unsigned NumFlatArguments;
+
+  llvm::PointerIntPair<const TemplateArgument *, 1> StructuredArguments;
+  unsigned NumStructuredArguments;
+
+public:
+  TemplateArgumentList(ASTContext &Context,
+                       TemplateArgumentListBuilder &Builder,
+                       bool TakeArgs);
+
+  /// \brief Produces a shallow copy of the given template argument list
+  TemplateArgumentList(const TemplateArgumentList &Other);
+  
+  ~TemplateArgumentList();
+
+  /// \brief Retrieve the template argument at a given index.
+  const TemplateArgument &get(unsigned Idx) const {
+    assert(Idx < NumFlatArguments && "Invalid template argument index");
+    return getFlatArgumentList()[Idx];
+  }
+
+  /// \brief Retrieve the template argument at a given index.
+  const TemplateArgument &operator[](unsigned Idx) const { return get(Idx); }
+
+  /// \brief Retrieve the number of template arguments in this
+  /// template argument list.
+  unsigned size() const { return NumFlatArguments; }
+
+  /// \brief Retrieve the number of template arguments in the
+  /// flattened template argument list.
+  unsigned flat_size() const { return NumFlatArguments; }
+
+  /// \brief Retrieve the flattened template argument list.
+  const TemplateArgument *getFlatArgumentList() const {
+    return FlatArguments.getPointer();
+  }
+};
+
+//===----------------------------------------------------------------------===//
+// Kinds of Templates
+//===----------------------------------------------------------------------===//
+
+/// TemplateDecl - The base class of all kinds of template declarations (e.g.,
+/// class, function, etc.). The TemplateDecl class stores the list of template
+/// parameters and a reference to the templated scoped declaration: the
+/// underlying AST node.
+class TemplateDecl : public NamedDecl {
+protected:
+  // This is probably never used.
+  TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
+               DeclarationName Name)
+    : NamedDecl(DK, DC, L, Name), TemplatedDecl(0), TemplateParams(0) { }
+
+  // Construct a template decl with the given name and parameters.
+  // Used when there is not templated element (tt-params, alias?).
+  TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
+               DeclarationName Name, TemplateParameterList *Params)
+    : NamedDecl(DK, DC, L, Name), TemplatedDecl(0), TemplateParams(Params) { }
+
+  // Construct a template decl with name, parameters, and templated element.
+  TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
+               DeclarationName Name, TemplateParameterList *Params,
+               NamedDecl *Decl)
+    : NamedDecl(DK, DC, L, Name), TemplatedDecl(Decl),
+      TemplateParams(Params) { }
+public:
+  ~TemplateDecl();
+
+  /// Get the list of template parameters
+  TemplateParameterList *getTemplateParameters() const {
+    return TemplateParams;
+  }
+
+  /// Get the underlying, templated declaration.
+  NamedDecl *getTemplatedDecl() const { return TemplatedDecl; }
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classof(const TemplateDecl *D) { return true; }
+  static bool classof(const FunctionTemplateDecl *D) { return true; }
+  static bool classof(const ClassTemplateDecl *D) { return true; }
+  static bool classof(const TemplateTemplateParmDecl *D) { return true; }
+  static bool classofKind(Kind K) {
+    return K >= TemplateFirst && K <= TemplateLast;
+  }
+
+protected:
+  NamedDecl *TemplatedDecl;
+  TemplateParameterList* TemplateParams;
+};
+
+/// \brief Provides information about a function template specialization,
+/// which is a FunctionDecl that has been explicitly specialization or
+/// instantiated from a function template.
+class FunctionTemplateSpecializationInfo : public llvm::FoldingSetNode {
+public:
+  /// \brief The function template specialization that this structure
+  /// describes.
+  FunctionDecl *Function;
+
+  /// \brief The function template from which this function template
+  /// specialization was generated.
+  ///
+  /// The two bits are contain the top 4 values of TemplateSpecializationKind.
+  llvm::PointerIntPair<FunctionTemplateDecl *, 2> Template;
+
+  /// \brief The template arguments used to produce the function template
+  /// specialization from the function template.
+  const TemplateArgumentList *TemplateArguments;
+
+  /// \brief The point at which this function template specialization was
+  /// first instantiated. 
+  SourceLocation PointOfInstantiation;
+  
+  /// \brief Retrieve the template from which this function was specialized.
+  FunctionTemplateDecl *getTemplate() const { return Template.getPointer(); }
+
+  /// \brief Determine what kind of template specialization this is.
+  TemplateSpecializationKind getTemplateSpecializationKind() const {
+    return (TemplateSpecializationKind)(Template.getInt() + 1);
+  }
+
+  /// \brief Set the template specialization kind.
+  void setTemplateSpecializationKind(TemplateSpecializationKind TSK) {
+    assert(TSK != TSK_Undeclared &&
+         "Cannot encode TSK_Undeclared for a function template specialization");
+    Template.setInt(TSK - 1);
+  }
+
+  /// \brief Retrieve the first point of instantiation of this function
+  /// template specialization.
+  ///
+  /// The point of instantiation may be an invalid source location if this
+  /// function has yet to be instantiated.
+  SourceLocation getPointOfInstantiation() const { 
+    return PointOfInstantiation; 
+  }
+  
+  /// \brief Set the (first) point of instantiation of this function template
+  /// specialization.
+  void setPointOfInstantiation(SourceLocation POI) {
+    PointOfInstantiation = POI;
+  }
+  
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    Profile(ID, TemplateArguments->getFlatArgumentList(),
+            TemplateArguments->flat_size(),
+            Function->getASTContext());
+  }
+
+  static void
+  Profile(llvm::FoldingSetNodeID &ID, const TemplateArgument *TemplateArgs,
+          unsigned NumTemplateArgs, ASTContext &Context) {
+    ID.AddInteger(NumTemplateArgs);
+    for (unsigned Arg = 0; Arg != NumTemplateArgs; ++Arg)
+      TemplateArgs[Arg].Profile(ID, Context);
+  }
+};
+
+/// \brief Provides information a specialization of a member of a class 
+/// template, which may be a member function, static data member, or
+/// member class.
+class MemberSpecializationInfo {
+  // The member declaration from which this member was instantiated, and the
+  // manner in which the instantiation occurred (in the lower two bits).
+  llvm::PointerIntPair<NamedDecl *, 2> MemberAndTSK;
+  
+  // The point at which this member was first instantiated.
+  SourceLocation PointOfInstantiation;
+  
+public:
+  explicit 
+  MemberSpecializationInfo(NamedDecl *IF, TemplateSpecializationKind TSK)
+    : MemberAndTSK(IF, TSK - 1), PointOfInstantiation() {
+    assert(TSK != TSK_Undeclared && 
+           "Cannot encode undeclared template specializations for members");
+  }
+  
+  /// \brief Retrieve the member declaration from which this member was
+  /// instantiated.
+  NamedDecl *getInstantiatedFrom() const { return MemberAndTSK.getPointer(); }
+  
+  /// \brief Determine what kind of template specialization this is.
+  TemplateSpecializationKind getTemplateSpecializationKind() const {
+    return (TemplateSpecializationKind)(MemberAndTSK.getInt() + 1);
+  }
+  
+  /// \brief Set the template specialization kind.
+  void setTemplateSpecializationKind(TemplateSpecializationKind TSK) {
+    assert(TSK != TSK_Undeclared && 
+           "Cannot encode undeclared template specializations for members");
+    MemberAndTSK.setInt(TSK - 1);
+  }
+  
+  /// \brief Retrieve the first point of instantiation of this member. 
+  /// If the point of instantiation is an invalid location, then this member
+  /// has not yet been instantiated.
+  SourceLocation getPointOfInstantiation() const { 
+    return PointOfInstantiation; 
+  }
+  
+  /// \brief Set the first point of instantiation.
+  void setPointOfInstantiation(SourceLocation POI) {
+    PointOfInstantiation = POI;
+  }
+};
+
+/// \brief Provides information about a dependent function-template
+/// specialization declaration.  Since explicit function template
+/// specialization and instantiation declarations can only appear in
+/// namespace scope, and you can only specialize a member of a
+/// fully-specialized class, the only way to get one of these is in
+/// a friend declaration like the following:
+///
+///   template <class T> void foo(T);
+///   template <class T> class A {
+///     friend void foo<>(T);
+///   };
+class DependentFunctionTemplateSpecializationInfo {
+  union {
+    // Force sizeof to be a multiple of sizeof(void*) so that the
+    // trailing data is aligned.
+    void *Aligner; 
+
+    struct {
+      /// The number of potential template candidates.
+      unsigned NumTemplates;
+
+      /// The number of template arguments.
+      unsigned NumArgs;      
+    } d;
+  };
+
+  /// The locations of the left and right angle brackets.
+  SourceRange AngleLocs;
+
+  FunctionTemplateDecl * const *getTemplates() const {
+    return reinterpret_cast<FunctionTemplateDecl*const*>(this+1);
+  }
+
+  const TemplateArgumentLoc *getTemplateArgs() const {
+    return reinterpret_cast<const TemplateArgumentLoc*>(
+             &getTemplates()[getNumTemplates()]);
+  }
+
+public:
+  DependentFunctionTemplateSpecializationInfo(
+                                 const UnresolvedSetImpl &Templates,
+                                 const TemplateArgumentListInfo &TemplateArgs);
+
+  /// \brief Returns the number of function templates that this might
+  /// be a specialization of.
+  unsigned getNumTemplates() const {
+    return d.NumTemplates;
+  }
+
+  /// \brief Returns the i'th template candidate.
+  FunctionTemplateDecl *getTemplate(unsigned I) const {
+    assert(I < getNumTemplates() && "template index out of range");
+    return getTemplates()[I];
+  }
+
+  /// \brief Returns the number of explicit template arguments that were given.
+  unsigned getNumTemplateArgs() const {
+    return d.NumArgs;
+  }
+
+  /// \brief Returns the nth template argument.
+  const TemplateArgumentLoc &getTemplateArg(unsigned I) const {
+    assert(I < getNumTemplateArgs() && "template arg index out of range");
+    return getTemplateArgs()[I];
+  }
+
+  SourceLocation getLAngleLoc() const {
+    return AngleLocs.getBegin();
+  }
+
+  SourceLocation getRAngleLoc() const {
+    return AngleLocs.getEnd();
+  }
+};
+  
+/// Declaration of a template function.
+class FunctionTemplateDecl : public TemplateDecl {
+protected:
+  /// \brief Data that is common to all of the declarations of a given
+  /// function template.
+  struct Common {
+    Common() : InstantiatedFromMember(0, false) { }
+
+    /// \brief The function template specializations for this function
+    /// template, including explicit specializations and instantiations.
+    llvm::FoldingSet<FunctionTemplateSpecializationInfo> Specializations;
+
+    /// \brief The member function template from which this was most
+    /// directly instantiated (or null).
+    ///
+    /// The boolean value indicates whether this member function template
+    /// was explicitly specialized.
+    llvm::PointerIntPair<FunctionTemplateDecl*, 1, bool> InstantiatedFromMember;
+  };
+
+  /// \brief A pointer to the previous declaration (if this is a redeclaration)
+  /// or to the data that is common to all declarations of this function
+  /// template.
+  llvm::PointerUnion<Common*, FunctionTemplateDecl*> CommonOrPrev;
+
+  /// \brief Retrieves the "common" pointer shared by all
+  /// (re-)declarations of the same function template. Calling this routine
+  /// may implicitly allocate memory for the common pointer.
+  Common *getCommonPtr();
+
+  FunctionTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
+                       TemplateParameterList *Params, NamedDecl *Decl)
+    : TemplateDecl(FunctionTemplate, DC, L, Name, Params, Decl),
+      CommonOrPrev((Common*)0) { }
+
+public:
+  void Destroy(ASTContext &C);
+
+  /// Get the underlying function declaration of the template.
+  FunctionDecl *getTemplatedDecl() const {
+    return static_cast<FunctionDecl*>(TemplatedDecl);
+  }
+
+  /// \brief Retrieve the set of function template specializations of this
+  /// function template.
+  llvm::FoldingSet<FunctionTemplateSpecializationInfo> &getSpecializations() {
+    return getCommonPtr()->Specializations;
+  }
+
+  /// \brief Retrieve the previous declaration of this function template, or
+  /// NULL if no such declaration exists.
+  const FunctionTemplateDecl *getPreviousDeclaration() const {
+    return CommonOrPrev.dyn_cast<FunctionTemplateDecl*>();
+  }
+
+  /// \brief Retrieve the previous declaration of this function template, or
+  /// NULL if no such declaration exists.
+  FunctionTemplateDecl *getPreviousDeclaration() {
+    return CommonOrPrev.dyn_cast<FunctionTemplateDecl*>();
+  }
+
+  /// \brief Set the previous declaration of this function template.
+  void setPreviousDeclaration(FunctionTemplateDecl *Prev) {
+    if (Prev)
+      CommonOrPrev = Prev;
+  }
+
+  virtual FunctionTemplateDecl *getCanonicalDecl();
+
+  /// \brief Retrieve the member function template that this function template
+  /// was instantiated from.
+  ///
+  /// This routine will return non-NULL for member function templates of
+  /// class templates.  For example, given:
+  ///
+  /// \code
+  /// template <typename T>
+  /// struct X {
+  ///   template <typename U> void f();
+  /// };
+  /// \endcode
+  ///
+  /// X<int>::A<float> is a CXXMethodDecl (whose parent is X<int>, a
+  /// ClassTemplateSpecializationDecl) for which getPrimaryTemplate() will
+  /// return X<int>::f, a FunctionTemplateDecl (whose parent is again
+  /// X<int>) for which getInstantiatedFromMemberTemplate() will return
+  /// X<T>::f, a FunctionTemplateDecl (whose parent is X<T>, a
+  /// ClassTemplateDecl).
+  ///
+  /// \returns NULL if this is not an instantiation of a member function
+  /// template.
+  FunctionTemplateDecl *getInstantiatedFromMemberTemplate() {
+    return getCommonPtr()->InstantiatedFromMember.getPointer();
+  }
+
+  void setInstantiatedFromMemberTemplate(FunctionTemplateDecl *FTD) {
+    assert(!getCommonPtr()->InstantiatedFromMember.getPointer());
+    getCommonPtr()->InstantiatedFromMember.setPointer(FTD);
+  }
+
+  /// \brief Determines whether this template was a specialization of a 
+  /// member template.
+  ///
+  /// In the following example, the function template \c X<int>::f is a 
+  /// member specialization.
+  ///
+  /// \code
+  /// template<typename T>
+  /// struct X {
+  ///   template<typename U> void f(T, U);
+  /// };
+  ///
+  /// template<> template<typename T>
+  /// void X<int>::f(int, T);
+  /// \endcode
+  bool isMemberSpecialization() {
+    return getCommonPtr()->InstantiatedFromMember.getInt();
+  }
+  
+  /// \brief Note that this member template is a specialization.
+  void setMemberSpecialization() {
+    assert(getCommonPtr()->InstantiatedFromMember.getPointer() &&
+           "Only member templates can be member template specializations");
+    getCommonPtr()->InstantiatedFromMember.setInt(true);
+  }
+  
+  /// Create a template function node.
+  static FunctionTemplateDecl *Create(ASTContext &C, DeclContext *DC,
+                                      SourceLocation L,
+                                      DeclarationName Name,
+                                      TemplateParameterList *Params,
+                                      NamedDecl *Decl);
+
+  // Implement isa/cast/dyncast support
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classof(const FunctionTemplateDecl *D) { return true; }
+  static bool classofKind(Kind K) { return K == FunctionTemplate; }
+};
+
+//===----------------------------------------------------------------------===//
+// Kinds of Template Parameters
+//===----------------------------------------------------------------------===//
+
+/// The TemplateParmPosition class defines the position of a template parameter
+/// within a template parameter list. Because template parameter can be listed
+/// sequentially for out-of-line template members, each template parameter is
+/// given a Depth - the nesting of template parameter scopes - and a Position -
+/// the occurrence within the parameter list.
+/// This class is inheritedly privately by different kinds of template
+/// parameters and is not part of the Decl hierarchy. Just a facility.
+class TemplateParmPosition {
+protected:
+  // FIXME: This should probably never be called, but it's here as
+  TemplateParmPosition()
+    : Depth(0), Position(0)
+  { /* assert(0 && "Cannot create positionless template parameter"); */ }
+
+  TemplateParmPosition(unsigned D, unsigned P)
+    : Depth(D), Position(P)
+  { }
+
+  // FIXME: These probably don't need to be ints. int:5 for depth, int:8 for
+  // position? Maybe?
+  unsigned Depth;
+  unsigned Position;
+
+public:
+  /// Get the nesting depth of the template parameter.
+  unsigned getDepth() const { return Depth; }
+
+  /// Get the position of the template parameter within its parameter list.
+  unsigned getPosition() const { return Position; }
+
+  /// Get the index of the template parameter within its parameter list.
+  unsigned getIndex() const { return Position; }
+};
+
+/// TemplateTypeParmDecl - Declaration of a template type parameter,
+/// e.g., "T" in
+/// @code
+/// template<typename T> class vector;
+/// @endcode
+class TemplateTypeParmDecl : public TypeDecl {
+  /// \brief Whether this template type parameter was declaration with
+  /// the 'typename' keyword. If false, it was declared with the
+  /// 'class' keyword.
+  bool Typename : 1;
+
+  /// \brief Whether this template type parameter inherited its
+  /// default argument.
+  bool InheritedDefault : 1;
+
+  /// \brief Whether this is a parameter pack.
+  bool ParameterPack : 1;
+
+  /// \brief The default template argument, if any.
+  TypeSourceInfo *DefaultArgument;
+
+  TemplateTypeParmDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
+                       bool Typename, QualType Type, bool ParameterPack)
+    : TypeDecl(TemplateTypeParm, DC, L, Id), Typename(Typename),
+      InheritedDefault(false), ParameterPack(ParameterPack), DefaultArgument() {
+    TypeForDecl = Type.getTypePtr();
+  }
+
+public:
+  static TemplateTypeParmDecl *Create(ASTContext &C, DeclContext *DC,
+                                      SourceLocation L, unsigned D, unsigned P,
+                                      IdentifierInfo *Id, bool Typename,
+                                      bool ParameterPack);
+
+  /// \brief Whether this template type parameter was declared with
+  /// the 'typename' keyword. If not, it was declared with the 'class'
+  /// keyword.
+  bool wasDeclaredWithTypename() const { return Typename; }
+
+  /// \brief Determine whether this template parameter has a default
+  /// argument.
+  bool hasDefaultArgument() const { return DefaultArgument != 0; }
+
+  /// \brief Retrieve the default argument, if any.
+  QualType getDefaultArgument() const { return DefaultArgument->getType(); }
+
+  /// \brief Retrieves the default argument's source information, if any.
+  TypeSourceInfo *getDefaultArgumentInfo() const { return DefaultArgument; }
+
+  /// \brief Retrieves the location of the default argument declaration.
+  SourceLocation getDefaultArgumentLoc() const;
+
+  /// \brief Determines whether the default argument was inherited
+  /// from a previous declaration of this template.
+  bool defaultArgumentWasInherited() const { return InheritedDefault; }
+
+  /// \brief Set the default argument for this template parameter, and
+  /// whether that default argument was inherited from another
+  /// declaration.
+  void setDefaultArgument(TypeSourceInfo *DefArg, bool Inherited) {
+    DefaultArgument = DefArg;
+    InheritedDefault = Inherited;
+  }
+
+  /// \brief Removes the default argument of this template parameter.
+  void removeDefaultArgument() {
+    DefaultArgument = 0;
+    InheritedDefault = false;
+  }
+
+  /// \brief Retrieve the depth of the template parameter.
+  unsigned getDepth() const;
+  
+  /// \brief Retrieve the index of the template parameter.
+  unsigned getIndex() const;
+
+  /// \brief Returns whether this is a parameter pack.
+  bool isParameterPack() const { return ParameterPack; }
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classof(const TemplateTypeParmDecl *D) { return true; }
+  static bool classofKind(Kind K) { return K == TemplateTypeParm; }
+};
+
+/// NonTypeTemplateParmDecl - Declares a non-type template parameter,
+/// e.g., "Size" in
+/// @code
+/// template<int Size> class array { };
+/// @endcode
+class NonTypeTemplateParmDecl
+  : public VarDecl, protected TemplateParmPosition {
+  /// \brief The default template argument, if any.
+  Expr *DefaultArgument;
+
+  NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation L, unsigned D,
+                          unsigned P, IdentifierInfo *Id, QualType T,
+                          TypeSourceInfo *TInfo)
+    : VarDecl(NonTypeTemplateParm, DC, L, Id, T, TInfo, VarDecl::None,
+              VarDecl::None),
+      TemplateParmPosition(D, P), DefaultArgument(0)
+  { }
+
+public:
+  static NonTypeTemplateParmDecl *
+  Create(ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D,
+         unsigned P, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo);
+
+  using TemplateParmPosition::getDepth;
+  using TemplateParmPosition::getPosition;
+  using TemplateParmPosition::getIndex;
+
+  /// \brief Determine whether this template parameter has a default
+  /// argument.
+  bool hasDefaultArgument() const { return DefaultArgument; }
+
+  /// \brief Retrieve the default argument, if any.
+  Expr *getDefaultArgument() const { return DefaultArgument; }
+
+  /// \brief Retrieve the location of the default argument, if any.
+  SourceLocation getDefaultArgumentLoc() const;
+
+  /// \brief Set the default argument for this template parameter.
+  void setDefaultArgument(Expr *DefArg) {
+    DefaultArgument = DefArg;
+  }
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classof(const NonTypeTemplateParmDecl *D) { return true; }
+  static bool classofKind(Kind K) { return K == NonTypeTemplateParm; }
+};
+
+/// TemplateTemplateParmDecl - Declares a template template parameter,
+/// e.g., "T" in
+/// @code
+/// template <template <typename> class T> class container { };
+/// @endcode
+/// A template template parameter is a TemplateDecl because it defines the
+/// name of a template and the template parameters allowable for substitution.
+class TemplateTemplateParmDecl
+  : public TemplateDecl, protected TemplateParmPosition {
+
+  /// \brief The default template argument, if any.
+  TemplateArgumentLoc DefaultArgument;
+
+  TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L,
+                           unsigned D, unsigned P,
+                           IdentifierInfo *Id, TemplateParameterList *Params)
+    : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
+      TemplateParmPosition(D, P), DefaultArgument()
+    { }
+
+public:
+  static TemplateTemplateParmDecl *Create(ASTContext &C, DeclContext *DC,
+                                          SourceLocation L, unsigned D,
+                                          unsigned P, IdentifierInfo *Id,
+                                          TemplateParameterList *Params);
+
+  using TemplateParmPosition::getDepth;
+  using TemplateParmPosition::getPosition;
+  using TemplateParmPosition::getIndex;
+
+  /// \brief Determine whether this template parameter has a default
+  /// argument.
+  bool hasDefaultArgument() const { 
+    return !DefaultArgument.getArgument().isNull(); 
+  }
+
+  /// \brief Retrieve the default argument, if any.
+  const TemplateArgumentLoc &getDefaultArgument() const { 
+    return DefaultArgument; 
+  }
+
+  /// \brief Set the default argument for this template parameter.
+  void setDefaultArgument(const TemplateArgumentLoc &DefArg) {
+    DefaultArgument = DefArg;
+  }
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classof(const TemplateTemplateParmDecl *D) { return true; }
+  static bool classofKind(Kind K) { return K == TemplateTemplateParm; }
+};
+
+/// \brief Represents a class template specialization, which refers to
+/// a class template with a given set of template arguments.
+///
+/// Class template specializations represent both explicit
+/// specialization of class templates, as in the example below, and
+/// implicit instantiations of class templates.
+///
+/// \code
+/// template<typename T> class array;
+///
+/// template<>
+/// class array<bool> { }; // class template specialization array<bool>
+/// \endcode
+class ClassTemplateSpecializationDecl
+  : public CXXRecordDecl, public llvm::FoldingSetNode {
+
+  /// \brief Structure that stores information about a class template
+  /// specialization that was instantiated from a class template partial
+  /// specialization.
+  struct SpecializedPartialSpecialization {
+    /// \brief The class template partial specialization from which this
+    /// class template specialization was instantiated.
+    ClassTemplatePartialSpecializationDecl *PartialSpecialization;
+
+    /// \brief The template argument list deduced for the class template
+    /// partial specialization itself.
+    TemplateArgumentList *TemplateArgs;
+  };
+
+  /// \brief The template that this specialization specializes
+  llvm::PointerUnion<ClassTemplateDecl *, SpecializedPartialSpecialization *>
+    SpecializedTemplate;
+
+  /// \brief The type-as-written of an explicit template specialization.
+  /// Does not apply to implicit specializations.
+  TypeSourceInfo *TypeAsWritten;
+
+  /// \brief The template arguments used to describe this specialization.
+  TemplateArgumentList TemplateArgs;
+
+  /// \brief The point where this template was instantiated (if any)
+  SourceLocation PointOfInstantiation;
+
+  /// \brief The kind of specialization this declaration refers to.
+  /// Really a value of type TemplateSpecializationKind.
+  unsigned SpecializationKind : 3;
+
+protected:
+  ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK,
+                                  DeclContext *DC, SourceLocation L,
+                                  ClassTemplateDecl *SpecializedTemplate,
+                                  TemplateArgumentListBuilder &Builder,
+                                  ClassTemplateSpecializationDecl *PrevDecl);
+
+public:
+  static ClassTemplateSpecializationDecl *
+  Create(ASTContext &Context, DeclContext *DC, SourceLocation L,
+         ClassTemplateDecl *SpecializedTemplate,
+         TemplateArgumentListBuilder &Builder,
+         ClassTemplateSpecializationDecl *PrevDecl);
+
+  virtual void Destroy(ASTContext& C);
+
+  virtual void getNameForDiagnostic(std::string &S,
+                                    const PrintingPolicy &Policy,
+                                    bool Qualified) const;
+
+  /// \brief Retrieve the template that this specialization specializes.
+  ClassTemplateDecl *getSpecializedTemplate() const;
+
+  /// \brief Retrieve the template arguments of the class template
+  /// specialization.
+  const TemplateArgumentList &getTemplateArgs() const {
+    return TemplateArgs;
+  }
+
+  /// \brief Determine the kind of specialization that this
+  /// declaration represents.
+  TemplateSpecializationKind getSpecializationKind() const {
+    return static_cast<TemplateSpecializationKind>(SpecializationKind);
+  }
+
+  void setSpecializationKind(TemplateSpecializationKind TSK) {
+    SpecializationKind = TSK;
+  }
+
+  /// \brief Get the point of instantiation (if any), or null if none.
+  SourceLocation getPointOfInstantiation() const {
+    return PointOfInstantiation;
+  }
+
+  void setPointOfInstantiation(SourceLocation Loc) {
+    assert(Loc.isValid() && "point of instantiation must be valid!");
+    PointOfInstantiation = Loc;
+  }
+
+  /// \brief If this class template specialization is an instantiation of
+  /// a template (rather than an explicit specialization), return the
+  /// class template or class template partial specialization from which it
+  /// was instantiated.
+  llvm::PointerUnion<ClassTemplateDecl *,
+                     ClassTemplatePartialSpecializationDecl *>
+  getInstantiatedFrom() const {
+    if (getSpecializationKind() != TSK_ImplicitInstantiation &&
+        getSpecializationKind() != TSK_ExplicitInstantiationDefinition &&
+        getSpecializationKind() != TSK_ExplicitInstantiationDeclaration)
+      return (ClassTemplateDecl*)0;
+
+    if (SpecializedPartialSpecialization *PartialSpec
+          = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
+      return PartialSpec->PartialSpecialization;
+
+    return const_cast<ClassTemplateDecl*>(
+                             SpecializedTemplate.get<ClassTemplateDecl*>());
+  }
+
+  /// \brief Retrieve the set of template arguments that should be used
+  /// to instantiate members of the class template or class template partial
+  /// specialization from which this class template specialization was
+  /// instantiated.
+  ///
+  /// \returns For a class template specialization instantiated from the primary
+  /// template, this function will return the same template arguments as
+  /// getTemplateArgs(). For a class template specialization instantiated from
+  /// a class template partial specialization, this function will return the
+  /// deduced template arguments for the class template partial specialization
+  /// itself.
+  const TemplateArgumentList &getTemplateInstantiationArgs() const {
+    if (SpecializedPartialSpecialization *PartialSpec
+        = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
+      return *PartialSpec->TemplateArgs;
+
+    return getTemplateArgs();
+  }
+
+  /// \brief Note that this class template specialization is actually an
+  /// instantiation of the given class template partial specialization whose
+  /// template arguments have been deduced.
+  void setInstantiationOf(ClassTemplatePartialSpecializationDecl *PartialSpec,
+                          TemplateArgumentList *TemplateArgs) {
+    SpecializedPartialSpecialization *PS
+      = new (getASTContext()) SpecializedPartialSpecialization();
+    PS->PartialSpecialization = PartialSpec;
+    PS->TemplateArgs = TemplateArgs;
+    SpecializedTemplate = PS;
+  }
+
+  /// \brief Sets the type of this specialization as it was written by
+  /// the user. This will be a class template specialization type.
+  void setTypeAsWritten(TypeSourceInfo *T) {
+    TypeAsWritten = T;
+  }
+
+  /// \brief Gets the type of this specialization as it was written by
+  /// the user, if it was so written.
+  TypeSourceInfo *getTypeAsWritten() const {
+    return TypeAsWritten;
+  }
+
+  void Profile(llvm::FoldingSetNodeID &ID) const {
+    Profile(ID, TemplateArgs.getFlatArgumentList(), TemplateArgs.flat_size(),
+            getASTContext());
+  }
+
+  static void
+  Profile(llvm::FoldingSetNodeID &ID, const TemplateArgument *TemplateArgs,
+          unsigned NumTemplateArgs, ASTContext &Context) {
+    ID.AddInteger(NumTemplateArgs);
+    for (unsigned Arg = 0; Arg != NumTemplateArgs; ++Arg)
+      TemplateArgs[Arg].Profile(ID, Context);
+  }
+
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) {
+    return K == ClassTemplateSpecialization ||
+           K == ClassTemplatePartialSpecialization;
+  }
+
+  static bool classof(const ClassTemplateSpecializationDecl *) {
+    return true;
+  }
+
+  static bool classof(const ClassTemplatePartialSpecializationDecl *) {
+    return true;
+  }
+};
+
+class ClassTemplatePartialSpecializationDecl
+  : public ClassTemplateSpecializationDecl {
+  /// \brief The list of template parameters
+  TemplateParameterList* TemplateParams;
+
+  /// \brief The source info for the template arguments as written.
+  /// FIXME: redundant with TypeAsWritten?
+  TemplateArgumentLoc *ArgsAsWritten;
+  unsigned NumArgsAsWritten;
+
+  /// \brief The class template partial specialization from which this 
+  /// class template partial specialization was instantiated.
+  ///
+  /// The boolean value will be true to indicate that this class template
+  /// partial specialization was specialized at this level.
+  llvm::PointerIntPair<ClassTemplatePartialSpecializationDecl *, 1, bool>
+      InstantiatedFromMember;
+    
+  ClassTemplatePartialSpecializationDecl(ASTContext &Context,
+                                         DeclContext *DC, SourceLocation L,
+                                         TemplateParameterList *Params,
+                                         ClassTemplateDecl *SpecializedTemplate,
+                                         TemplateArgumentListBuilder &Builder,
+                                         TemplateArgumentLoc *ArgInfos,
+                                         unsigned NumArgInfos,
+                               ClassTemplatePartialSpecializationDecl *PrevDecl)
+    : ClassTemplateSpecializationDecl(Context,
+                                      ClassTemplatePartialSpecialization,
+                                      DC, L, SpecializedTemplate, Builder,
+                                      PrevDecl),
+      TemplateParams(Params), ArgsAsWritten(ArgInfos),
+      NumArgsAsWritten(NumArgInfos), InstantiatedFromMember(0, false) { }
+
+public:
+  static ClassTemplatePartialSpecializationDecl *
+  Create(ASTContext &Context, DeclContext *DC, SourceLocation L,
+         TemplateParameterList *Params,
+         ClassTemplateDecl *SpecializedTemplate,
+         TemplateArgumentListBuilder &Builder,
+         const TemplateArgumentListInfo &ArgInfos,
+         QualType CanonInjectedType,
+         ClassTemplatePartialSpecializationDecl *PrevDecl);
+
+  /// Get the list of template parameters
+  TemplateParameterList *getTemplateParameters() const {
+    return TemplateParams;
+  }
+
+  /// Get the template arguments as written.
+  TemplateArgumentLoc *getTemplateArgsAsWritten() const {
+    return ArgsAsWritten;
+  }
+
+  /// Get the number of template arguments as written.
+  unsigned getNumTemplateArgsAsWritten() const {
+    return NumArgsAsWritten;
+  }
+
+  /// \brief Retrieve the member class template partial specialization from
+  /// which this particular class template partial specialization was
+  /// instantiated.
+  ///
+  /// \code
+  /// template<typename T>
+  /// struct Outer {
+  ///   template<typename U> struct Inner;
+  ///   template<typename U> struct Inner<U*> { }; // #1
+  /// };
+  ///
+  /// Outer<float>::Inner<int*> ii;
+  /// \endcode
+  ///
+  /// In this example, the instantiation of \c Outer<float>::Inner<int*> will
+  /// end up instantiating the partial specialization 
+  /// \c Outer<float>::Inner<U*>, which itself was instantiated from the class 
+  /// template partial specialization \c Outer<T>::Inner<U*>. Given 
+  /// \c Outer<float>::Inner<U*>, this function would return
+  /// \c Outer<T>::Inner<U*>.
+  ClassTemplatePartialSpecializationDecl *getInstantiatedFromMember() {
+    ClassTemplatePartialSpecializationDecl *First
+      = cast<ClassTemplatePartialSpecializationDecl>(getFirstDeclaration());
+    return First->InstantiatedFromMember.getPointer();
+  }
+  
+  void setInstantiatedFromMember(
+                          ClassTemplatePartialSpecializationDecl *PartialSpec) {
+    ClassTemplatePartialSpecializationDecl *First
+      = cast<ClassTemplatePartialSpecializationDecl>(getFirstDeclaration());
+    First->InstantiatedFromMember.setPointer(PartialSpec);
+  }
+    
+  /// \brief Determines whether this class template partial specialization 
+  /// template was a specialization of a member partial specialization.
+  ///
+  /// In the following example, the member template partial specialization
+  /// \c X<int>::Inner<T*> is a member specialization.
+  ///
+  /// \code
+  /// template<typename T>
+  /// struct X {
+  ///   template<typename U> struct Inner;
+  ///   template<typename U> struct Inner<U*>;
+  /// };
+  ///
+  /// template<> template<typename T>
+  /// struct X<int>::Inner<T*> { /* ... */ };
+  /// \endcode
+  bool isMemberSpecialization() {
+    ClassTemplatePartialSpecializationDecl *First
+      = cast<ClassTemplatePartialSpecializationDecl>(getFirstDeclaration());
+    return First->InstantiatedFromMember.getInt();
+  }
+  
+  /// \brief Note that this member template is a specialization.
+  void setMemberSpecialization() {
+    ClassTemplatePartialSpecializationDecl *First
+      = cast<ClassTemplatePartialSpecializationDecl>(getFirstDeclaration());
+    assert(First->InstantiatedFromMember.getPointer() &&
+           "Only member templates can be member template specializations");
+    return First->InstantiatedFromMember.setInt(true);
+  }
+
+  /// Retrieves the injected specialization type for this partial
+  /// specialization.  This is not the same as the type-decl-type for
+  /// this partial specialization, which is an InjectedClassNameType.
+  QualType getInjectedSpecializationType() const {
+    assert(getTypeForDecl() && "partial specialization has no type set!");
+    return cast<InjectedClassNameType>(getTypeForDecl())
+             ->getInjectedSpecializationType();
+  }
+    
+  // FIXME: Add Profile support!
+
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) {
+    return K == ClassTemplatePartialSpecialization;
+  }
+
+  static bool classof(const ClassTemplatePartialSpecializationDecl *) {
+    return true;
+  }
+};
+
+/// Declaration of a class template.
+class ClassTemplateDecl : public TemplateDecl {
+protected:
+  /// \brief Data that is common to all of the declarations of a given
+  /// class template.
+  struct Common {
+    Common() : InstantiatedFromMember(0, 0) {}
+
+    /// \brief The class template specializations for this class
+    /// template, including explicit specializations and instantiations.
+    llvm::FoldingSet<ClassTemplateSpecializationDecl> Specializations;
+
+    /// \brief The class template partial specializations for this class
+    /// template.
+    llvm::FoldingSet<ClassTemplatePartialSpecializationDecl>
+      PartialSpecializations;
+
+    /// \brief The injected-class-name type for this class template.
+    QualType InjectedClassNameType;
+
+    /// \brief The templated member class from which this was most
+    /// directly instantiated (or null).
+    ///
+    /// The boolean value indicates whether this member class template
+    /// was explicitly specialized.
+    llvm::PointerIntPair<ClassTemplateDecl *, 1, bool> InstantiatedFromMember;
+  };
+
+  // FIXME: Combine PreviousDeclaration with CommonPtr, as in 
+  // FunctionTemplateDecl.
+  
+  /// \brief Previous declaration of this class template.
+  ClassTemplateDecl *PreviousDeclaration;
+
+  /// \brief Pointer to the data that is common to all of the
+  /// declarations of this class template.
+  ///
+  /// The first declaration of a class template (e.g., the declaration
+  /// with no "previous declaration") owns this pointer.
+  Common *CommonPtr;
+
+  ClassTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
+                    TemplateParameterList *Params, NamedDecl *Decl,
+                    ClassTemplateDecl *PrevDecl, Common *CommonPtr)
+    : TemplateDecl(ClassTemplate, DC, L, Name, Params, Decl),
+      PreviousDeclaration(PrevDecl), CommonPtr(CommonPtr) { }
+
+  ~ClassTemplateDecl();
+
+public:
+  /// Get the underlying class declarations of the template.
+  CXXRecordDecl *getTemplatedDecl() const {
+    return static_cast<CXXRecordDecl *>(TemplatedDecl);
+  }
+
+  /// \brief Retrieve the previous declaration of this template.
+  ClassTemplateDecl *getPreviousDeclaration() const {
+    return PreviousDeclaration;
+  }
+
+  virtual ClassTemplateDecl *getCanonicalDecl();
+
+  /// Create a class template node.
+  static ClassTemplateDecl *Create(ASTContext &C, DeclContext *DC,
+                                   SourceLocation L,
+                                   DeclarationName Name,
+                                   TemplateParameterList *Params,
+                                   NamedDecl *Decl,
+                                   ClassTemplateDecl *PrevDecl);
+
+  /// \brief Retrieve the set of specializations of this class template.
+  llvm::FoldingSet<ClassTemplateSpecializationDecl> &getSpecializations() {
+    return CommonPtr->Specializations;
+  }
+
+  /// \brief Retrieve the set of partial specializations of this class
+  /// template.
+  llvm::FoldingSet<ClassTemplatePartialSpecializationDecl> &
+  getPartialSpecializations() {
+    return CommonPtr->PartialSpecializations;
+  }
+
+  /// \brief Find a class template partial specialization with the given
+  /// type T.
+  ///
+  /// \brief A dependent type that names a specialization of this class
+  /// template.
+  ///
+  /// \returns the class template partial specialization that exactly matches
+  /// the type \p T, or NULL if no such partial specialization exists.
+  ClassTemplatePartialSpecializationDecl *findPartialSpecialization(QualType T);
+
+  /// \brief Retrieve the template specialization type of the
+  /// injected-class-name for this class template.
+  ///
+  /// The injected-class-name for a class template \c X is \c
+  /// X<template-args>, where \c template-args is formed from the
+  /// template arguments that correspond to the template parameters of
+  /// \c X. For example:
+  ///
+  /// \code
+  /// template<typename T, int N>
+  /// struct array {
+  ///   typedef array this_type; // "array" is equivalent to "array<T, N>"
+  /// };
+  /// \endcode
+  QualType getInjectedClassNameSpecialization(ASTContext &Context);
+
+  /// \brief Retrieve the member class template that this class template was
+  /// derived from.
+  ///
+  /// This routine will return non-NULL for templated member classes of
+  /// class templates.  For example, given:
+  ///
+  /// \code
+  /// template <typename T>
+  /// struct X {
+  ///   template <typename U> struct A {};
+  /// };
+  /// \endcode
+  ///
+  /// X<int>::A<float> is a ClassTemplateSpecializationDecl (whose parent
+  /// is X<int>, also a CTSD) for which getSpecializedTemplate() will
+  /// return X<int>::A<U>, a TemplateClassDecl (whose parent is again
+  /// X<int>) for which getInstantiatedFromMemberTemplate() will return
+  /// X<T>::A<U>, a TemplateClassDecl (whose parent is X<T>, also a TCD).
+  ///
+  /// \returns null if this is not an instantiation of a member class template.
+  ClassTemplateDecl *getInstantiatedFromMemberTemplate() const {
+    return CommonPtr->InstantiatedFromMember.getPointer();
+  }
+
+  void setInstantiatedFromMemberTemplate(ClassTemplateDecl *CTD) {
+    assert(!CommonPtr->InstantiatedFromMember.getPointer());
+    CommonPtr->InstantiatedFromMember.setPointer(CTD);
+  }
+
+  /// \brief Determines whether this template was a specialization of a 
+  /// member template.
+  ///
+  /// In the following example, the member template \c X<int>::Inner is a 
+  /// member specialization.
+  ///
+  /// \code
+  /// template<typename T>
+  /// struct X {
+  ///   template<typename U> struct Inner;
+  /// };
+  ///
+  /// template<> template<typename T>
+  /// struct X<int>::Inner { /* ... */ };
+  /// \endcode
+  bool isMemberSpecialization() {
+    return CommonPtr->InstantiatedFromMember.getInt();
+  }
+  
+  /// \brief Note that this member template is a specialization.
+  void setMemberSpecialization() {
+    assert(CommonPtr->InstantiatedFromMember.getPointer() &&
+           "Only member templates can be member template specializations");
+    CommonPtr->InstantiatedFromMember.setInt(true);
+  }
+  
+  // Implement isa/cast/dyncast support
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classof(const ClassTemplateDecl *D) { return true; }
+  static bool classofKind(Kind K) { return K == ClassTemplate; }
+
+  virtual void Destroy(ASTContext& C);
+};
+
+/// Declaration of a friend template.  For example:
+///
+/// template <typename T> class A {
+///   friend class MyVector<T>; // not a friend template
+///   template <typename U> friend class B; // friend template
+///   template <typename U> friend class Foo<T>::Nested; // friend template
+class FriendTemplateDecl : public Decl {
+public:
+  typedef llvm::PointerUnion<NamedDecl*,TypeSourceInfo*> FriendUnion;
+
+private:
+  // The number of template parameters;  always non-zero.
+  unsigned NumParams;
+
+  // The parameter list.
+  TemplateParameterList **Params;
+
+  // The declaration that's a friend of this class.
+  FriendUnion Friend;
+
+  // Location of the 'friend' specifier.
+  SourceLocation FriendLoc;
+
+
+  FriendTemplateDecl(DeclContext *DC, SourceLocation Loc,
+                     unsigned NParams, 
+                     TemplateParameterList **Params,
+                     FriendUnion Friend,
+                     SourceLocation FriendLoc)
+    : Decl(Decl::FriendTemplate, DC, Loc),
+      NumParams(NParams),
+      Params(Params),
+      Friend(Friend),
+      FriendLoc(FriendLoc)
+  {}
+
+public:
+  static FriendTemplateDecl *Create(ASTContext &Context,
+                                    DeclContext *DC, SourceLocation Loc,
+                                    unsigned NParams, 
+                                    TemplateParameterList **Params,
+                                    FriendUnion Friend,
+                                    SourceLocation FriendLoc);
+
+  /// If this friend declaration names a templated type (or
+  /// a dependent member type of a templated type), return that
+  /// type;  otherwise return null.
+  TypeSourceInfo *getFriendType() const {
+    return Friend.dyn_cast<TypeSourceInfo*>();
+  }
+
+  /// If this friend declaration names a templated function (or
+  /// a member function of a templated type), return that type;
+  /// otherwise return null.
+  NamedDecl *getFriendDecl() const {
+    return Friend.dyn_cast<NamedDecl*>();
+  }
+
+  /// Retrieves the location of the 'friend' keyword.
+  SourceLocation getFriendLoc() const {
+    return FriendLoc;
+  }
+
+  TemplateParameterList *getTemplateParameterList(unsigned i) const {
+    assert(i <= NumParams);
+    return Params[i];
+  }
+
+  unsigned getNumTemplateParameters() const {
+    return NumParams;
+  }
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) { return K == Decl::FriendTemplate; }
+  static bool classof(const FriendTemplateDecl *D) { return true; }
+};
+
+/// Implementation of inline functions that require the template declarations
+inline AnyFunctionDecl::AnyFunctionDecl(FunctionTemplateDecl *FTD)
+  : Function(FTD) { }
+
+} /* end of namespace clang */
+
+#endif
diff --git a/include/clang/AST/DeclVisitor.h b/include/clang/AST/DeclVisitor.h
new file mode 100644
index 0000000..140e5c0
--- /dev/null
+++ b/include/clang/AST/DeclVisitor.h
@@ -0,0 +1,55 @@
+//===--- DeclVisitor.h - Visitor for Decl subclasses ------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the DeclVisitor interface.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_AST_DECLVISITOR_H
+#define LLVM_CLANG_AST_DECLVISITOR_H
+
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclFriend.h"
+#include "clang/AST/DeclTemplate.h"
+
+namespace clang {
+
+#define DISPATCH(NAME, CLASS) \
+  return static_cast<ImplClass*>(this)-> Visit##NAME(static_cast<CLASS*>(D))
+
+/// \brief A simple visitor class that helps create declaration visitors.
+template<typename ImplClass, typename RetTy=void>
+class DeclVisitor {
+public:
+  RetTy Visit(Decl *D) {
+    switch (D->getKind()) {
+      default: assert(false && "Decl that isn't part of DeclNodes.def!");
+#define DECL(Derived, Base) \
+      case Decl::Derived: DISPATCH(Derived##Decl, Derived##Decl);
+#define ABSTRACT_DECL(Derived, Base)
+#include "clang/AST/DeclNodes.def"
+    }
+  }
+
+  // If the implementation chooses not to implement a certain visit
+  // method, fall back to the parent.
+#define DECL(Derived, Base)                                             \
+  RetTy Visit##Derived##Decl(Derived##Decl *D) { DISPATCH(Base, Base); }
+#define ABSTRACT_DECL(Derived, Base) DECL(Derived, Base)
+#include "clang/AST/DeclNodes.def"
+
+  RetTy VisitDecl(Decl *D) { return RetTy(); }
+};
+
+#undef DISPATCH
+
+}  // end namespace clang
+
+#endif // LLVM_CLANG_AST_DECLVISITOR_H
diff --git a/include/clang/AST/DeclarationName.h b/include/clang/AST/DeclarationName.h
new file mode 100644
index 0000000..9401786
--- /dev/null
+++ b/include/clang/AST/DeclarationName.h
@@ -0,0 +1,415 @@
+//===-- DeclarationName.h - Representation of declaration names -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the DeclarationName and DeclarationNameTable classes.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_AST_DECLARATIONNAME_H
+#define LLVM_CLANG_AST_DECLARATIONNAME_H
+
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/CanonicalType.h"
+#include "clang/Basic/PartialDiagnostic.h"
+
+namespace llvm {
+  template <typename T> struct DenseMapInfo;
+}
+
+namespace clang {
+  class CXXSpecialName;
+  class CXXOperatorIdName;
+  class CXXLiteralOperatorIdName;
+  class DeclarationNameExtra;
+  class IdentifierInfo;
+  class MultiKeywordSelector;
+  class UsingDirectiveDecl;
+
+/// DeclarationName - The name of a declaration. In the common case,
+/// this just stores an IdentifierInfo pointer to a normal
+/// name. However, it also provides encodings for Objective-C
+/// selectors (optimizing zero- and one-argument selectors, which make
+/// up 78% percent of all selectors in Cocoa.h) and special C++ names
+/// for constructors, destructors, and conversion functions.
+class DeclarationName {
+public:
+  /// NameKind - The kind of name this object contains.
+  enum NameKind {
+    Identifier,
+    ObjCZeroArgSelector,
+    ObjCOneArgSelector,
+    ObjCMultiArgSelector,
+    CXXConstructorName,
+    CXXDestructorName,
+    CXXConversionFunctionName,
+    CXXOperatorName,
+    CXXLiteralOperatorName,
+    CXXUsingDirective
+  };
+
+private:
+  /// StoredNameKind - The kind of name that is actually stored in the
+  /// upper bits of the Ptr field. This is only used internally.
+  enum StoredNameKind {
+    StoredIdentifier = 0,
+    StoredObjCZeroArgSelector,
+    StoredObjCOneArgSelector,
+    StoredDeclarationNameExtra,
+    PtrMask = 0x03
+  };
+
+  /// Ptr - The lowest two bits are used to express what kind of name
+  /// we're actually storing, using the values of NameKind. Depending
+  /// on the kind of name this is, the upper bits of Ptr may have one
+  /// of several different meanings:
+  ///
+  ///   StoredIdentifier - The name is a normal identifier, and Ptr is
+  ///   a normal IdentifierInfo pointer.
+  ///
+  ///   StoredObjCZeroArgSelector - The name is an Objective-C
+  ///   selector with zero arguments, and Ptr is an IdentifierInfo
+  ///   pointer pointing to the selector name.
+  ///
+  ///   StoredObjCOneArgSelector - The name is an Objective-C selector
+  ///   with one argument, and Ptr is an IdentifierInfo pointer
+  ///   pointing to the selector name.
+  ///
+  ///   StoredDeclarationNameExtra - Ptr is actually a pointer to a
+  ///   DeclarationNameExtra structure, whose first value will tell us
+  ///   whether this is an Objective-C selector, C++ operator-id name,
+  ///   or special C++ name.
+  uintptr_t Ptr;
+
+  /// getStoredNameKind - Return the kind of object that is stored in
+  /// Ptr.
+  StoredNameKind getStoredNameKind() const {
+    return static_cast<StoredNameKind>(Ptr & PtrMask);
+  }
+
+  /// getExtra - Get the "extra" information associated with this
+  /// multi-argument selector or C++ special name.
+  DeclarationNameExtra *getExtra() const {
+    assert(getStoredNameKind() == StoredDeclarationNameExtra &&
+           "Declaration name does not store an Extra structure");
+    return reinterpret_cast<DeclarationNameExtra *>(Ptr & ~PtrMask);
+  }
+
+  /// getAsCXXSpecialName - If the stored pointer is actually a
+  /// CXXSpecialName, returns a pointer to it. Otherwise, returns
+  /// a NULL pointer.
+  CXXSpecialName *getAsCXXSpecialName() const {
+    if (getNameKind() >= CXXConstructorName &&
+        getNameKind() <= CXXConversionFunctionName)
+      return reinterpret_cast<CXXSpecialName *>(Ptr & ~PtrMask);
+    return 0;
+  }
+
+  /// getAsCXXOperatorIdName
+  CXXOperatorIdName *getAsCXXOperatorIdName() const {
+    if (getNameKind() == CXXOperatorName)
+      return reinterpret_cast<CXXOperatorIdName *>(Ptr & ~PtrMask);
+    return 0;
+  }
+
+  CXXLiteralOperatorIdName *getAsCXXLiteralOperatorIdName() const {
+    if (getNameKind() == CXXLiteralOperatorName)
+      return reinterpret_cast<CXXLiteralOperatorIdName *>(Ptr & ~PtrMask);
+    return 0;
+  }
+
+  // Construct a declaration name from the name of a C++ constructor,
+  // destructor, or conversion function.
+  DeclarationName(CXXSpecialName *Name)
+    : Ptr(reinterpret_cast<uintptr_t>(Name)) {
+    assert((Ptr & PtrMask) == 0 && "Improperly aligned CXXSpecialName");
+    Ptr |= StoredDeclarationNameExtra;
+  }
+
+  // Construct a declaration name from the name of a C++ overloaded
+  // operator.
+  DeclarationName(CXXOperatorIdName *Name)
+    : Ptr(reinterpret_cast<uintptr_t>(Name)) {
+    assert((Ptr & PtrMask) == 0 && "Improperly aligned CXXOperatorId");
+    Ptr |= StoredDeclarationNameExtra;
+  }
+
+  DeclarationName(CXXLiteralOperatorIdName *Name)
+    : Ptr(reinterpret_cast<uintptr_t>(Name)) {
+    assert((Ptr & PtrMask) == 0 && "Improperly aligned CXXLiteralOperatorId");
+    Ptr |= StoredDeclarationNameExtra;
+  }
+
+  /// Construct a declaration name from a raw pointer.
+  DeclarationName(uintptr_t Ptr) : Ptr(Ptr) { }
+
+  friend class DeclarationNameTable;
+  friend class NamedDecl;
+
+  /// getFETokenInfoAsVoid - Retrieves the front end-specified pointer
+  /// for this name as a void pointer.
+  void *getFETokenInfoAsVoid() const;
+
+public:
+  /// DeclarationName - Used to create an empty selector.
+  DeclarationName() : Ptr(0) { }
+
+  // Construct a declaration name from an IdentifierInfo *.
+  DeclarationName(const IdentifierInfo *II)
+    : Ptr(reinterpret_cast<uintptr_t>(II)) {
+    assert((Ptr & PtrMask) == 0 && "Improperly aligned IdentifierInfo");
+  }
+
+  // Construct a declaration name from an Objective-C selector.
+  DeclarationName(Selector Sel);
+
+  /// getUsingDirectiveName - Return name for all using-directives.
+  static DeclarationName getUsingDirectiveName();
+
+  // operator bool() - Evaluates true when this declaration name is
+  // non-empty.
+  operator bool() const {
+    return ((Ptr & PtrMask) != 0) ||
+           (reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask));
+  }
+
+  /// Predicate functions for querying what type of name this is.
+  bool isIdentifier() const { return getStoredNameKind() == StoredIdentifier; }
+  bool isObjCZeroArgSelector() const {
+    return getStoredNameKind() == StoredObjCZeroArgSelector;
+  }
+  bool isObjCOneArgSelector() const {
+    return getStoredNameKind() == StoredObjCOneArgSelector;
+  }
+
+  /// getNameKind - Determine what kind of name this is.
+  NameKind getNameKind() const;
+
+  /// \brief Determines whether the name itself is dependent, e.g., because it 
+  /// involves a C++ type that is itself dependent.
+  ///
+  /// Note that this does not capture all of the notions of "dependent name",
+  /// because an identifier can be a dependent name if it is used as the 
+  /// callee in a call expression with dependent arguments.
+  bool isDependentName() const;
+  
+  /// getNameAsString - Retrieve the human-readable string for this name.
+  std::string getAsString() const;
+
+  /// printName - Print the human-readable name to a stream.
+  void printName(llvm::raw_ostream &OS) const;
+
+  /// getAsIdentifierInfo - Retrieve the IdentifierInfo * stored in
+  /// this declaration name, or NULL if this declaration name isn't a
+  /// simple identifier.
+  IdentifierInfo *getAsIdentifierInfo() const {
+    if (isIdentifier())
+      return reinterpret_cast<IdentifierInfo *>(Ptr);
+    return 0;
+  }
+
+  /// getAsOpaqueInteger - Get the representation of this declaration
+  /// name as an opaque integer.
+  uintptr_t getAsOpaqueInteger() const { return Ptr; }
+
+  /// getAsOpaquePtr - Get the representation of this declaration name as
+  /// an opaque pointer.
+  void *getAsOpaquePtr() const { return reinterpret_cast<void*>(Ptr); }
+
+  static DeclarationName getFromOpaquePtr(void *P) {
+    DeclarationName N;
+    N.Ptr = reinterpret_cast<uintptr_t> (P);
+    return N;
+  }
+
+  static DeclarationName getFromOpaqueInteger(uintptr_t P) {
+    DeclarationName N;
+    N.Ptr = P;
+    return N;
+  }
+
+  /// getCXXNameType - If this name is one of the C++ names (of a
+  /// constructor, destructor, or conversion function), return the
+  /// type associated with that name.
+  QualType getCXXNameType() const;
+
+  /// getCXXOverloadedOperator - If this name is the name of an
+  /// overloadable operator in C++ (e.g., @c operator+), retrieve the
+  /// kind of overloaded operator.
+  OverloadedOperatorKind getCXXOverloadedOperator() const;
+
+  /// getCXXLiteralIdentifier - If this name is the name of a literal
+  /// operator, retrieve the identifier associated with it.
+  IdentifierInfo *getCXXLiteralIdentifier() const;
+
+  /// getObjCSelector - Get the Objective-C selector stored in this
+  /// declaration name.
+  Selector getObjCSelector() const;
+
+  /// getFETokenInfo/setFETokenInfo - The language front-end is
+  /// allowed to associate arbitrary metadata with some kinds of
+  /// declaration names, including normal identifiers and C++
+  /// constructors, destructors, and conversion functions.
+  template<typename T>
+  T *getFETokenInfo() const { return static_cast<T*>(getFETokenInfoAsVoid()); }
+
+  void setFETokenInfo(void *T);
+
+  /// operator== - Determine whether the specified names are identical..
+  friend bool operator==(DeclarationName LHS, DeclarationName RHS) {
+    return LHS.Ptr == RHS.Ptr;
+  }
+
+  /// operator!= - Determine whether the specified names are different.
+  friend bool operator!=(DeclarationName LHS, DeclarationName RHS) {
+    return LHS.Ptr != RHS.Ptr;
+  }
+
+  static DeclarationName getEmptyMarker() {
+    return DeclarationName(uintptr_t(-1));
+  }
+
+  static DeclarationName getTombstoneMarker() {
+    return DeclarationName(uintptr_t(-2));
+  }
+
+  static int compare(DeclarationName LHS, DeclarationName RHS);
+  
+  void dump() const;
+};
+
+/// Ordering on two declaration names. If both names are identifiers,
+/// this provides a lexicographical ordering.
+inline bool operator<(DeclarationName LHS, DeclarationName RHS) {
+  return DeclarationName::compare(LHS, RHS) < 0;
+}
+
+/// Ordering on two declaration names. If both names are identifiers,
+/// this provides a lexicographical ordering.
+inline bool operator>(DeclarationName LHS, DeclarationName RHS) {
+  return DeclarationName::compare(LHS, RHS) > 0;
+}
+
+/// Ordering on two declaration names. If both names are identifiers,
+/// this provides a lexicographical ordering.
+inline bool operator<=(DeclarationName LHS, DeclarationName RHS) {
+  return DeclarationName::compare(LHS, RHS) <= 0;
+}
+
+/// Ordering on two declaration names. If both names are identifiers,
+/// this provides a lexicographical ordering.
+inline bool operator>=(DeclarationName LHS, DeclarationName RHS) {
+  return DeclarationName::compare(LHS, RHS) >= 0;
+}
+
+/// DeclarationNameTable - Used to store and retrieve DeclarationName
+/// instances for the various kinds of declaration names, e.g., normal
+/// identifiers, C++ constructor names, etc. This class contains
+/// uniqued versions of each of the C++ special names, which can be
+/// retrieved using its member functions (e.g.,
+/// getCXXConstructorName).
+class DeclarationNameTable {
+  void *CXXSpecialNamesImpl; // Actually a FoldingSet<CXXSpecialName> *
+  CXXOperatorIdName *CXXOperatorNames; // Operator names
+  void *CXXLiteralOperatorNames; // Actually a FoldingSet<...> *
+
+  DeclarationNameTable(const DeclarationNameTable&);            // NONCOPYABLE
+  DeclarationNameTable& operator=(const DeclarationNameTable&); // NONCOPYABLE
+
+public:
+  DeclarationNameTable();
+  ~DeclarationNameTable();
+
+  /// getIdentifier - Create a declaration name that is a simple
+  /// identifier.
+  DeclarationName getIdentifier(const IdentifierInfo *ID) {
+    return DeclarationName(ID);
+  }
+
+  /// getCXXConstructorName - Returns the name of a C++ constructor
+  /// for the given Type.
+  DeclarationName getCXXConstructorName(CanQualType Ty) {
+    return getCXXSpecialName(DeclarationName::CXXConstructorName, 
+                             Ty.getUnqualifiedType());
+  }
+
+  /// getCXXDestructorName - Returns the name of a C++ destructor
+  /// for the given Type.
+  DeclarationName getCXXDestructorName(CanQualType Ty) {
+    return getCXXSpecialName(DeclarationName::CXXDestructorName, 
+                             Ty.getUnqualifiedType());
+  }
+
+  /// getCXXConversionFunctionName - Returns the name of a C++
+  /// conversion function for the given Type.
+  DeclarationName getCXXConversionFunctionName(CanQualType Ty) {
+    return getCXXSpecialName(DeclarationName::CXXConversionFunctionName, Ty);
+  }
+
+  /// getCXXSpecialName - Returns a declaration name for special kind
+  /// of C++ name, e.g., for a constructor, destructor, or conversion
+  /// function.
+  DeclarationName getCXXSpecialName(DeclarationName::NameKind Kind,
+                                    CanQualType Ty);
+
+  /// getCXXOperatorName - Get the name of the overloadable C++
+  /// operator corresponding to Op.
+  DeclarationName getCXXOperatorName(OverloadedOperatorKind Op);
+
+  /// getCXXLiteralOperatorName - Get the name of the literal operator function
+  /// with II as the identifier.
+  DeclarationName getCXXLiteralOperatorName(IdentifierInfo *II);
+};
+
+/// Insertion operator for diagnostics.  This allows sending DeclarationName's
+/// into a diagnostic with <<.
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+                                           DeclarationName N) {
+  DB.AddTaggedVal(N.getAsOpaqueInteger(),
+                  Diagnostic::ak_declarationname);
+  return DB;
+}
+
+/// Insertion operator for partial diagnostics.  This allows binding
+/// DeclarationName's into a partial diagnostic with <<.
+inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
+                                           DeclarationName N) {
+  PD.AddTaggedVal(N.getAsOpaqueInteger(),
+                  Diagnostic::ak_declarationname);
+  return PD;
+}
+
+}  // end namespace clang
+
+namespace llvm {
+/// Define DenseMapInfo so that DeclarationNames can be used as keys
+/// in DenseMap and DenseSets.
+template<>
+struct DenseMapInfo<clang::DeclarationName> {
+  static inline clang::DeclarationName getEmptyKey() {
+    return clang::DeclarationName::getEmptyMarker();
+  }
+
+  static inline clang::DeclarationName getTombstoneKey() {
+    return clang::DeclarationName::getTombstoneMarker();
+  }
+
+  static unsigned getHashValue(clang::DeclarationName);
+
+  static inline bool
+  isEqual(clang::DeclarationName LHS, clang::DeclarationName RHS) {
+    return LHS == RHS;
+  }
+};
+
+template <>
+struct isPodLike<clang::DeclarationName> { static const bool value = true; };
+
+}  // end namespace llvm
+
+#endif
diff --git a/include/clang/AST/DependentDiagnostic.h b/include/clang/AST/DependentDiagnostic.h
new file mode 100644
index 0000000..2bbe502
--- /dev/null
+++ b/include/clang/AST/DependentDiagnostic.h
@@ -0,0 +1,192 @@
+//===-- DependentDiagnostic.h - Dependently-generated diagnostics -*- C++ -*-=//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines interfaces for diagnostics which may or may
+//  fire based on how a template is instantiated.
+//
+//  At the moment, the only consumer of this interface is access
+//  control.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_DEPENDENT_DIAGNOSTIC_H
+#define LLVM_CLANG_AST_DEPENDENT_DIAGNOSTIC_H
+
+#include "clang/Basic/PartialDiagnostic.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/AST/DeclBase.h"
+#include "clang/AST/DeclContextInternals.h"
+#include "clang/AST/Type.h"
+
+namespace clang {
+
+class ASTContext;
+class CXXRecordDecl;
+class NamedDecl;
+
+/// A dependently-generated diagnostic.
+class DependentDiagnostic {
+public:
+  enum AccessNonce { Access = 0 };
+
+  static DependentDiagnostic *Create(ASTContext &Context,
+                                     DeclContext *Parent,
+                                     AccessNonce _,
+                                     SourceLocation Loc,
+                                     bool IsMemberAccess,
+                                     AccessSpecifier AS,
+                                     NamedDecl *TargetDecl,
+                                     CXXRecordDecl *NamingClass,
+                                     QualType BaseObjectType,
+                                     const PartialDiagnostic &PDiag) {
+    DependentDiagnostic *DD = Create(Context, Parent, PDiag);
+    DD->AccessData.Loc = Loc.getRawEncoding();
+    DD->AccessData.IsMember = IsMemberAccess;
+    DD->AccessData.Access = AS;
+    DD->AccessData.TargetDecl = TargetDecl;
+    DD->AccessData.NamingClass = NamingClass;
+    DD->AccessData.BaseObjectType = BaseObjectType.getAsOpaquePtr();
+    return DD;
+  }
+
+  unsigned getKind() const {
+    return Access;
+  }
+
+  bool isAccessToMember() const {
+    assert(getKind() == Access);
+    return AccessData.IsMember;
+  }
+
+  AccessSpecifier getAccess() const {
+    assert(getKind() == Access);
+    return AccessSpecifier(AccessData.Access);
+  }
+
+  SourceLocation getAccessLoc() const {
+    assert(getKind() == Access);
+    return SourceLocation::getFromRawEncoding(AccessData.Loc);
+  }
+
+  NamedDecl *getAccessTarget() const {
+    assert(getKind() == Access);
+    return AccessData.TargetDecl;
+  }
+
+  NamedDecl *getAccessNamingClass() const {
+    assert(getKind() == Access);
+    return AccessData.NamingClass;
+  }
+
+  QualType getAccessBaseObjectType() const {
+    assert(getKind() == Access);
+    return QualType::getFromOpaquePtr(AccessData.BaseObjectType);
+  }
+
+  const PartialDiagnostic &getDiagnostic() const {
+    return Diag;
+  }
+
+private:
+  DependentDiagnostic(const PartialDiagnostic &PDiag,
+                      PartialDiagnostic::Storage *Storage) 
+    : Diag(PDiag, Storage) {}
+  
+  static DependentDiagnostic *Create(ASTContext &Context,
+                                     DeclContext *Parent,
+                                     const PartialDiagnostic &PDiag);
+
+  friend class DependentStoredDeclsMap;
+  friend class DeclContext::ddiag_iterator;
+  DependentDiagnostic *NextDiagnostic;
+
+  PartialDiagnostic Diag;
+
+  union {
+    struct {
+      unsigned Loc;
+      unsigned Access : 2;
+      unsigned IsMember : 1;
+      NamedDecl *TargetDecl;
+      CXXRecordDecl *NamingClass;
+      void *BaseObjectType;
+    } AccessData;
+  };
+};
+
+/// 
+
+/// An iterator over the dependent diagnostics in a dependent context.
+class DeclContext::ddiag_iterator {
+public:
+  ddiag_iterator() : Ptr(0) {}
+  explicit ddiag_iterator(DependentDiagnostic *Ptr) : Ptr(Ptr) {}
+
+  typedef DependentDiagnostic *value_type;
+  typedef DependentDiagnostic *reference;
+  typedef DependentDiagnostic *pointer;
+  typedef int difference_type;
+  typedef std::forward_iterator_tag iterator_category;
+
+  reference operator*() const { return Ptr; }
+
+  ddiag_iterator &operator++() {
+    assert(Ptr && "attempt to increment past end of diag list");
+    Ptr = Ptr->NextDiagnostic;
+    return *this;
+  }
+
+  ddiag_iterator operator++(int) {
+    ddiag_iterator tmp = *this;
+    ++*this;
+    return tmp;
+  }
+
+  bool operator==(ddiag_iterator Other) const {
+    return Ptr == Other.Ptr;
+  }
+
+  bool operator!=(ddiag_iterator Other) const {
+    return Ptr != Other.Ptr;
+  }
+
+  ddiag_iterator &operator+=(difference_type N) {
+    assert(N >= 0 && "cannot rewind a DeclContext::ddiag_iterator");
+    while (N--)
+      ++*this;
+    return *this;
+  }
+
+  ddiag_iterator operator+(difference_type N) const {
+    ddiag_iterator tmp = *this;
+    tmp += N;
+    return tmp;
+  }
+
+private:
+  DependentDiagnostic *Ptr;
+};
+
+inline DeclContext::ddiag_iterator DeclContext::ddiag_begin() const {
+  assert(isDependentContext()
+         && "cannot iterate dependent diagnostics of non-dependent context");
+  const DependentStoredDeclsMap *Map
+    = static_cast<DependentStoredDeclsMap*>(getPrimaryContext()->LookupPtr);
+
+  if (!Map) return ddiag_iterator();
+  return ddiag_iterator(Map->FirstDiagnostic);
+}
+
+inline DeclContext::ddiag_iterator DeclContext::ddiag_end() const {
+  return ddiag_iterator();
+}
+
+}
+
+#endif
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
new file mode 100644
index 0000000..d824a56
--- /dev/null
+++ b/include/clang/AST/Expr.h
@@ -0,0 +1,3153 @@
+//===--- Expr.h - Classes for representing expressions ----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the Expr interface and subclasses.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_EXPR_H
+#define LLVM_CLANG_AST_EXPR_H
+
+#include "clang/AST/APValue.h"
+#include "clang/AST/Stmt.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/DeclAccessPair.h"
+#include "clang/AST/ASTVector.h"
+#include "clang/AST/UsuallyTinyPtrVector.h"
+#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/APFloat.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include <vector>
+
+namespace clang {
+  class ASTContext;
+  class APValue;
+  class Decl;
+  class IdentifierInfo;
+  class ParmVarDecl;
+  class NamedDecl;
+  class ValueDecl;
+  class BlockDecl;
+  class CXXBaseSpecifier;
+  class CXXOperatorCallExpr;
+  class CXXMemberCallExpr;
+  class TemplateArgumentLoc;
+  class TemplateArgumentListInfo;
+
+/// \brief A simple array of base specifiers.
+typedef UsuallyTinyPtrVector<const CXXBaseSpecifier> CXXBaseSpecifierArray;
+
+/// Expr - This represents one expression.  Note that Expr's are subclasses of
+/// Stmt.  This allows an expression to be transparently used any place a Stmt
+/// is required.
+///
+class Expr : public Stmt {
+  QualType TR;
+
+protected:
+  /// TypeDependent - Whether this expression is type-dependent
+  /// (C++ [temp.dep.expr]).
+  bool TypeDependent : 1;
+
+  /// ValueDependent - Whether this expression is value-dependent
+  /// (C++ [temp.dep.constexpr]).
+  bool ValueDependent : 1;
+
+  Expr(StmtClass SC, QualType T, bool TD, bool VD)
+    : Stmt(SC), TypeDependent(TD), ValueDependent(VD) {
+    setType(T);
+  }
+
+  /// \brief Construct an empty expression.
+  explicit Expr(StmtClass SC, EmptyShell) : Stmt(SC) { }
+
+public:
+  /// \brief Increases the reference count for this expression.
+  ///
+  /// Invoke the Retain() operation when this expression
+  /// is being shared by another owner.
+  Expr *Retain() {
+    Stmt::Retain();
+    return this;
+  }
+
+  QualType getType() const { return TR; }
+  void setType(QualType t) {
+    // In C++, the type of an expression is always adjusted so that it
+    // will not have reference type an expression will never have
+    // reference type (C++ [expr]p6). Use
+    // QualType::getNonReferenceType() to retrieve the non-reference
+    // type. Additionally, inspect Expr::isLvalue to determine whether
+    // an expression that is adjusted in this manner should be
+    // considered an lvalue.
+    assert((t.isNull() || !t->isReferenceType()) &&
+           "Expressions can't have reference type");
+
+    TR = t;
+  }
+
+  /// isValueDependent - Determines whether this expression is
+  /// value-dependent (C++ [temp.dep.constexpr]). For example, the
+  /// array bound of "Chars" in the following example is
+  /// value-dependent.
+  /// @code
+  /// template<int Size, char (&Chars)[Size]> struct meta_string;
+  /// @endcode
+  bool isValueDependent() const { return ValueDependent; }
+
+  /// \brief Set whether this expression is value-dependent or not.
+  void setValueDependent(bool VD) { ValueDependent = VD; }
+
+  /// isTypeDependent - Determines whether this expression is
+  /// type-dependent (C++ [temp.dep.expr]), which means that its type
+  /// could change from one template instantiation to the next. For
+  /// example, the expressions "x" and "x + y" are type-dependent in
+  /// the following code, but "y" is not type-dependent:
+  /// @code
+  /// template<typename T>
+  /// void add(T x, int y) {
+  ///   x + y;
+  /// }
+  /// @endcode
+  bool isTypeDependent() const { return TypeDependent; }
+
+  /// \brief Set whether this expression is type-dependent or not.
+  void setTypeDependent(bool TD) { TypeDependent = TD; }
+
+  /// SourceLocation tokens are not useful in isolation - they are low level
+  /// value objects created/interpreted by SourceManager. We assume AST
+  /// clients will have a pointer to the respective SourceManager.
+  virtual SourceRange getSourceRange() const = 0;
+
+  /// getExprLoc - Return the preferred location for the arrow when diagnosing
+  /// a problem with a generic expression.
+  virtual SourceLocation getExprLoc() const { return getLocStart(); }
+
+  /// isUnusedResultAWarning - Return true if this immediate expression should
+  /// be warned about if the result is unused.  If so, fill in Loc and Ranges
+  /// with location to warn on and the source range[s] to report with the
+  /// warning.
+  bool isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1,
+                              SourceRange &R2, ASTContext &Ctx) const;
+
+  /// isLvalue - C99 6.3.2.1: an lvalue is an expression with an object type or
+  /// incomplete type other than void. Nonarray expressions that can be lvalues:
+  ///  - name, where name must be a variable
+  ///  - e[i]
+  ///  - (e), where e must be an lvalue
+  ///  - e.name, where e must be an lvalue
+  ///  - e->name
+  ///  - *e, the type of e cannot be a function type
+  ///  - string-constant
+  ///  - reference type [C++ [expr]]
+  ///  - b ? x : y, where x and y are lvalues of suitable types [C++]
+  ///
+  enum isLvalueResult {
+    LV_Valid,
+    LV_NotObjectType,
+    LV_IncompleteVoidType,
+    LV_DuplicateVectorComponents,
+    LV_InvalidExpression,
+    LV_MemberFunction,
+    LV_SubObjCPropertySetting,
+    LV_ClassTemporary
+  };
+  isLvalueResult isLvalue(ASTContext &Ctx) const;
+
+  // Same as above, but excluding checks for non-object and void types in C
+  isLvalueResult isLvalueInternal(ASTContext &Ctx) const;
+
+  /// isModifiableLvalue - C99 6.3.2.1: an lvalue that does not have array type,
+  /// does not have an incomplete type, does not have a const-qualified type,
+  /// and if it is a structure or union, does not have any member (including,
+  /// recursively, any member or element of all contained aggregates or unions)
+  /// with a const-qualified type.
+  ///
+  /// \param Loc [in] [out] - A source location which *may* be filled
+  /// in with the location of the expression making this a
+  /// non-modifiable lvalue, if specified.
+  enum isModifiableLvalueResult {
+    MLV_Valid,
+    MLV_NotObjectType,
+    MLV_IncompleteVoidType,
+    MLV_DuplicateVectorComponents,
+    MLV_InvalidExpression,
+    MLV_LValueCast,           // Specialized form of MLV_InvalidExpression.
+    MLV_IncompleteType,
+    MLV_ConstQualified,
+    MLV_ArrayType,
+    MLV_NotBlockQualified,
+    MLV_ReadonlyProperty,
+    MLV_NoSetterProperty,
+    MLV_MemberFunction,
+    MLV_SubObjCPropertySetting,
+    MLV_ClassTemporary
+  };
+  isModifiableLvalueResult isModifiableLvalue(ASTContext &Ctx,
+                                              SourceLocation *Loc = 0) const;
+
+  /// \brief If this expression refers to a bit-field, retrieve the
+  /// declaration of that bit-field.
+  FieldDecl *getBitField();
+
+  const FieldDecl *getBitField() const {
+    return const_cast<Expr*>(this)->getBitField();
+  }
+
+  /// \brief Returns whether this expression refers to a vector element.
+  bool refersToVectorElement() const;
+  
+  /// isKnownToHaveBooleanValue - Return true if this is an integer expression
+  /// that is known to return 0 or 1.  This happens for _Bool/bool expressions
+  /// but also int expressions which are produced by things like comparisons in
+  /// C.
+  bool isKnownToHaveBooleanValue() const;
+  
+  /// isIntegerConstantExpr - Return true if this expression is a valid integer
+  /// constant expression, and, if so, return its value in Result.  If not a
+  /// valid i-c-e, return false and fill in Loc (if specified) with the location
+  /// of the invalid expression.
+  bool isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx,
+                             SourceLocation *Loc = 0,
+                             bool isEvaluated = true) const;
+  bool isIntegerConstantExpr(ASTContext &Ctx, SourceLocation *Loc = 0) const {
+    llvm::APSInt X;
+    return isIntegerConstantExpr(X, Ctx, Loc);
+  }
+  /// isConstantInitializer - Returns true if this expression is a constant
+  /// initializer, which can be emitted at compile-time.
+  bool isConstantInitializer(ASTContext &Ctx) const;
+
+  /// EvalResult is a struct with detailed info about an evaluated expression.
+  struct EvalResult {
+    /// Val - This is the value the expression can be folded to.
+    APValue Val;
+
+    /// HasSideEffects - Whether the evaluated expression has side effects.
+    /// For example, (f() && 0) can be folded, but it still has side effects.
+    bool HasSideEffects;
+
+    /// Diag - If the expression is unfoldable, then Diag contains a note
+    /// diagnostic indicating why it's not foldable. DiagLoc indicates a caret
+    /// position for the error, and DiagExpr is the expression that caused
+    /// the error.
+    /// If the expression is foldable, but not an integer constant expression,
+    /// Diag contains a note diagnostic that describes why it isn't an integer
+    /// constant expression. If the expression *is* an integer constant
+    /// expression, then Diag will be zero.
+    unsigned Diag;
+    const Expr *DiagExpr;
+    SourceLocation DiagLoc;
+
+    EvalResult() : HasSideEffects(false), Diag(0), DiagExpr(0) {}
+  };
+
+  /// Evaluate - Return true if this is a constant which we can fold using
+  /// any crazy technique (that has nothing to do with language standards) that
+  /// we want to.  If this function returns true, it returns the folded constant
+  /// in Result.
+  bool Evaluate(EvalResult &Result, ASTContext &Ctx) const;
+
+  /// EvaluateAsAny - The same as Evaluate, except that it also succeeds on
+  /// stack based objects.
+  bool EvaluateAsAny(EvalResult &Result, ASTContext &Ctx) const;
+
+  /// EvaluateAsBooleanCondition - Return true if this is a constant
+  /// which we we can fold and convert to a boolean condition using
+  /// any crazy technique that we want to.
+  bool EvaluateAsBooleanCondition(bool &Result, ASTContext &Ctx) const;
+
+  /// isEvaluatable - Call Evaluate to see if this expression can be constant
+  /// folded, but discard the result.
+  bool isEvaluatable(ASTContext &Ctx) const;
+
+  /// HasSideEffects - This routine returns true for all those expressions
+  /// which must be evaluated each time and must not be optimization away 
+  /// or evaluated at compile time. Example is a function call, volatile
+  /// variable read.
+  bool HasSideEffects(ASTContext &Ctx) const;
+  
+  /// EvaluateAsInt - Call Evaluate and return the folded integer. This
+  /// must be called on an expression that constant folds to an integer.
+  llvm::APSInt EvaluateAsInt(ASTContext &Ctx) const;
+
+  /// EvaluateAsLValue - Evaluate an expression to see if it's a lvalue
+  /// with link time known address.
+  bool EvaluateAsLValue(EvalResult &Result, ASTContext &Ctx) const;
+
+  /// EvaluateAsAnyLValue - The same as EvaluateAsLValue, except that it
+  /// also succeeds on stack based, immutable address lvalues.
+  bool EvaluateAsAnyLValue(EvalResult &Result, ASTContext &Ctx) const;
+
+  /// \brief Enumeration used to describe how \c isNullPointerConstant()
+  /// should cope with value-dependent expressions.
+  enum NullPointerConstantValueDependence {
+    /// \brief Specifies that the expression should never be value-dependent.
+    NPC_NeverValueDependent = 0,
+    
+    /// \brief Specifies that a value-dependent expression of integral or
+    /// dependent type should be considered a null pointer constant.
+    NPC_ValueDependentIsNull,
+    
+    /// \brief Specifies that a value-dependent expression should be considered
+    /// to never be a null pointer constant.
+    NPC_ValueDependentIsNotNull
+  };
+  
+  /// isNullPointerConstant - C99 6.3.2.3p3 -  Return true if this is either an
+  /// integer constant expression with the value zero, or if this is one that is
+  /// cast to void*.
+  bool isNullPointerConstant(ASTContext &Ctx,
+                             NullPointerConstantValueDependence NPC) const;
+
+  /// isOBJCGCCandidate - Return true if this expression may be used in a read/
+  /// write barrier.
+  bool isOBJCGCCandidate(ASTContext &Ctx) const;
+
+  /// IgnoreParens - Ignore parentheses.  If this Expr is a ParenExpr, return
+  ///  its subexpression.  If that subexpression is also a ParenExpr,
+  ///  then this method recursively returns its subexpression, and so forth.
+  ///  Otherwise, the method returns the current Expr.
+  Expr *IgnoreParens();
+
+  /// IgnoreParenCasts - Ignore parentheses and casts.  Strip off any ParenExpr
+  /// or CastExprs, returning their operand.
+  Expr *IgnoreParenCasts();
+
+  /// IgnoreParenNoopCasts - Ignore parentheses and casts that do not change the
+  /// value (including ptr->int casts of the same size).  Strip off any
+  /// ParenExpr or CastExprs, returning their operand.
+  Expr *IgnoreParenNoopCasts(ASTContext &Ctx);
+
+  /// \brief Determine whether this expression is a default function argument.
+  ///
+  /// Default arguments are implicitly generated in the abstract syntax tree
+  /// by semantic analysis for function calls, object constructions, etc. in 
+  /// C++. Default arguments are represented by \c CXXDefaultArgExpr nodes;
+  /// this routine also looks through any implicit casts to determine whether
+  /// the expression is a default argument.
+  bool isDefaultArgument() const;
+  
+  /// \brief Determine whether this expression directly creates a
+  /// temporary object (of class type).
+  bool isTemporaryObject() const { return getTemporaryObject() != 0; }
+
+  /// \brief If this expression directly creates a temporary object of
+  /// class type, return the expression that actually constructs that
+  /// temporary object.
+  const Expr *getTemporaryObject() const;
+
+  const Expr *IgnoreParens() const {
+    return const_cast<Expr*>(this)->IgnoreParens();
+  }
+  const Expr *IgnoreParenCasts() const {
+    return const_cast<Expr*>(this)->IgnoreParenCasts();
+  }
+  const Expr *IgnoreParenNoopCasts(ASTContext &Ctx) const {
+    return const_cast<Expr*>(this)->IgnoreParenNoopCasts(Ctx);
+  }
+
+  static bool hasAnyTypeDependentArguments(Expr** Exprs, unsigned NumExprs);
+  static bool hasAnyValueDependentArguments(Expr** Exprs, unsigned NumExprs);
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() >= firstExprConstant &&
+           T->getStmtClass() <= lastExprConstant;
+  }
+  static bool classof(const Expr *) { return true; }
+};
+
+
+//===----------------------------------------------------------------------===//
+// Primary Expressions.
+//===----------------------------------------------------------------------===//
+
+/// \brief Represents the qualifier that may precede a C++ name, e.g., the
+/// "std::" in "std::sort".
+struct NameQualifier {
+  /// \brief The nested name specifier.
+  NestedNameSpecifier *NNS;
+  
+  /// \brief The source range covered by the nested name specifier.
+  SourceRange Range;
+};
+
+/// \brief Represents an explicit template argument list in C++, e.g.,
+/// the "<int>" in "sort<int>".
+struct ExplicitTemplateArgumentList {
+  /// \brief The source location of the left angle bracket ('<');
+  SourceLocation LAngleLoc;
+  
+  /// \brief The source location of the right angle bracket ('>');
+  SourceLocation RAngleLoc;
+  
+  /// \brief The number of template arguments in TemplateArgs.
+  /// The actual template arguments (if any) are stored after the
+  /// ExplicitTemplateArgumentList structure.
+  unsigned NumTemplateArgs;
+  
+  /// \brief Retrieve the template arguments
+  TemplateArgumentLoc *getTemplateArgs() {
+    return reinterpret_cast<TemplateArgumentLoc *> (this + 1);
+  }
+  
+  /// \brief Retrieve the template arguments
+  const TemplateArgumentLoc *getTemplateArgs() const {
+    return reinterpret_cast<const TemplateArgumentLoc *> (this + 1);
+  }
+
+  void initializeFrom(const TemplateArgumentListInfo &List);
+  void copyInto(TemplateArgumentListInfo &List) const;
+  static std::size_t sizeFor(const TemplateArgumentListInfo &List);
+};
+  
+/// DeclRefExpr - [C99 6.5.1p2] - A reference to a declared variable, function,
+/// enum, etc.
+class DeclRefExpr : public Expr {
+  enum {
+    // Flag on DecoratedD that specifies when this declaration reference 
+    // expression has a C++ nested-name-specifier.
+    HasQualifierFlag = 0x01,
+    // Flag on DecoratedD that specifies when this declaration reference 
+    // expression has an explicit C++ template argument list.
+    HasExplicitTemplateArgumentListFlag = 0x02
+  };
+  
+  // DecoratedD - The declaration that we are referencing, plus two bits to 
+  // indicate whether (1) the declaration's name was explicitly qualified and
+  // (2) the declaration's name was followed by an explicit template 
+  // argument list.
+  llvm::PointerIntPair<ValueDecl *, 2> DecoratedD;
+  
+  // Loc - The location of the declaration name itself.
+  SourceLocation Loc;
+
+  /// \brief Retrieve the qualifier that preceded the declaration name, if any.
+  NameQualifier *getNameQualifier() {
+    if ((DecoratedD.getInt() & HasQualifierFlag) == 0)
+      return 0;
+    
+    return reinterpret_cast<NameQualifier *> (this + 1);
+  }
+  
+  /// \brief Retrieve the qualifier that preceded the member name, if any.
+  const NameQualifier *getNameQualifier() const {
+    return const_cast<DeclRefExpr *>(this)->getNameQualifier();
+  }
+  
+  /// \brief Retrieve the explicit template argument list that followed the
+  /// member template name, if any.
+  ExplicitTemplateArgumentList *getExplicitTemplateArgumentList() {
+    if ((DecoratedD.getInt() & HasExplicitTemplateArgumentListFlag) == 0)
+      return 0;
+    
+    if ((DecoratedD.getInt() & HasQualifierFlag) == 0)
+      return reinterpret_cast<ExplicitTemplateArgumentList *>(this + 1);
+    
+    return reinterpret_cast<ExplicitTemplateArgumentList *>(
+                                                      getNameQualifier() + 1);
+  }
+  
+  /// \brief Retrieve the explicit template argument list that followed the
+  /// member template name, if any.
+  const ExplicitTemplateArgumentList *getExplicitTemplateArgumentList() const {
+    return const_cast<DeclRefExpr *>(this)->getExplicitTemplateArgumentList();
+  }
+  
+  DeclRefExpr(NestedNameSpecifier *Qualifier, SourceRange QualifierRange,
+              ValueDecl *D, SourceLocation NameLoc,
+              const TemplateArgumentListInfo *TemplateArgs,
+              QualType T);
+  
+protected:
+  /// \brief Computes the type- and value-dependence flags for this
+  /// declaration reference expression.
+  void computeDependence();
+
+  DeclRefExpr(StmtClass SC, ValueDecl *d, QualType t, SourceLocation l) :
+    Expr(SC, t, false, false), DecoratedD(d, 0), Loc(l) {
+    computeDependence();
+  }
+
+public:
+  DeclRefExpr(ValueDecl *d, QualType t, SourceLocation l) :
+    Expr(DeclRefExprClass, t, false, false), DecoratedD(d, 0), Loc(l) {
+    computeDependence();
+  }
+
+  /// \brief Construct an empty declaration reference expression.
+  explicit DeclRefExpr(EmptyShell Empty)
+    : Expr(DeclRefExprClass, Empty) { }
+
+  static DeclRefExpr *Create(ASTContext &Context,
+                             NestedNameSpecifier *Qualifier,
+                             SourceRange QualifierRange,
+                             ValueDecl *D,
+                             SourceLocation NameLoc,
+                             QualType T,
+                             const TemplateArgumentListInfo *TemplateArgs = 0);
+  
+  ValueDecl *getDecl() { return DecoratedD.getPointer(); }
+  const ValueDecl *getDecl() const { return DecoratedD.getPointer(); }
+  void setDecl(ValueDecl *NewD) { DecoratedD.setPointer(NewD); }
+
+  SourceLocation getLocation() const { return Loc; }
+  void setLocation(SourceLocation L) { Loc = L; }
+  virtual SourceRange getSourceRange() const;
+
+  /// \brief Determine whether this declaration reference was preceded by a
+  /// C++ nested-name-specifier, e.g., \c N::foo.
+  bool hasQualifier() const { return DecoratedD.getInt() & HasQualifierFlag; }
+  
+  /// \brief If the name was qualified, retrieves the source range of
+  /// the nested-name-specifier that precedes the name. Otherwise,
+  /// returns an empty source range.
+  SourceRange getQualifierRange() const {
+    if (!hasQualifier())
+      return SourceRange();
+    
+    return getNameQualifier()->Range;
+  }
+  
+  /// \brief If the name was qualified, retrieves the nested-name-specifier 
+  /// that precedes the name. Otherwise, returns NULL.
+  NestedNameSpecifier *getQualifier() const {
+    if (!hasQualifier())
+      return 0;
+    
+    return getNameQualifier()->NNS;
+  }
+  
+  /// \brief Determines whether this member expression actually had a C++
+  /// template argument list explicitly specified, e.g., x.f<int>.
+  bool hasExplicitTemplateArgumentList() const {
+    return DecoratedD.getInt() & HasExplicitTemplateArgumentListFlag;
+  }
+
+  /// \brief Copies the template arguments (if present) into the given
+  /// structure.
+  void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
+    if (hasExplicitTemplateArgumentList())
+      getExplicitTemplateArgumentList()->copyInto(List);
+  }
+  
+  /// \brief Retrieve the location of the left angle bracket following the
+  /// member name ('<'), if any.
+  SourceLocation getLAngleLoc() const {
+    if (!hasExplicitTemplateArgumentList())
+      return SourceLocation();
+    
+    return getExplicitTemplateArgumentList()->LAngleLoc;
+  }
+  
+  /// \brief Retrieve the template arguments provided as part of this
+  /// template-id.
+  const TemplateArgumentLoc *getTemplateArgs() const {
+    if (!hasExplicitTemplateArgumentList())
+      return 0;
+    
+    return getExplicitTemplateArgumentList()->getTemplateArgs();
+  }
+  
+  /// \brief Retrieve the number of template arguments provided as part of this
+  /// template-id.
+  unsigned getNumTemplateArgs() const {
+    if (!hasExplicitTemplateArgumentList())
+      return 0;
+    
+    return getExplicitTemplateArgumentList()->NumTemplateArgs;
+  }
+  
+  /// \brief Retrieve the location of the right angle bracket following the
+  /// template arguments ('>').
+  SourceLocation getRAngleLoc() const {
+    if (!hasExplicitTemplateArgumentList())
+      return SourceLocation();
+    
+    return getExplicitTemplateArgumentList()->RAngleLoc;
+  }
+  
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == DeclRefExprClass;
+  }
+  static bool classof(const DeclRefExpr *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+/// PredefinedExpr - [C99 6.4.2.2] - A predefined identifier such as __func__.
+class PredefinedExpr : public Expr {
+public:
+  enum IdentType {
+    Func,
+    Function,
+    PrettyFunction,
+    /// PrettyFunctionNoVirtual - The same as PrettyFunction, except that the
+    /// 'virtual' keyword is omitted for virtual member functions.
+    PrettyFunctionNoVirtual
+  };
+
+private:
+  SourceLocation Loc;
+  IdentType Type;
+public:
+  PredefinedExpr(SourceLocation l, QualType type, IdentType IT)
+    : Expr(PredefinedExprClass, type, type->isDependentType(), 
+           type->isDependentType()), Loc(l), Type(IT) {}
+
+  /// \brief Construct an empty predefined expression.
+  explicit PredefinedExpr(EmptyShell Empty)
+    : Expr(PredefinedExprClass, Empty) { }
+
+  IdentType getIdentType() const { return Type; }
+  void setIdentType(IdentType IT) { Type = IT; }
+
+  SourceLocation getLocation() const { return Loc; }
+  void setLocation(SourceLocation L) { Loc = L; }
+
+  static std::string ComputeName(IdentType IT, const Decl *CurrentDecl);
+
+  virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == PredefinedExprClass;
+  }
+  static bool classof(const PredefinedExpr *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+class IntegerLiteral : public Expr {
+  llvm::APInt Value;
+  SourceLocation Loc;
+public:
+  // type should be IntTy, LongTy, LongLongTy, UnsignedIntTy, UnsignedLongTy,
+  // or UnsignedLongLongTy
+  IntegerLiteral(const llvm::APInt &V, QualType type, SourceLocation l)
+    : Expr(IntegerLiteralClass, type, false, false), Value(V), Loc(l) {
+    assert(type->isIntegerType() && "Illegal type in IntegerLiteral");
+  }
+
+  /// \brief Construct an empty integer literal.
+  explicit IntegerLiteral(EmptyShell Empty)
+    : Expr(IntegerLiteralClass, Empty) { }
+
+  const llvm::APInt &getValue() const { return Value; }
+  virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
+
+  /// \brief Retrieve the location of the literal.
+  SourceLocation getLocation() const { return Loc; }
+
+  void setValue(const llvm::APInt &Val) { Value = Val; }
+  void setLocation(SourceLocation Location) { Loc = Location; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == IntegerLiteralClass;
+  }
+  static bool classof(const IntegerLiteral *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+class CharacterLiteral : public Expr {
+  unsigned Value;
+  SourceLocation Loc;
+  bool IsWide;
+public:
+  // type should be IntTy
+  CharacterLiteral(unsigned value, bool iswide, QualType type, SourceLocation l)
+    : Expr(CharacterLiteralClass, type, false, false), Value(value), Loc(l),
+      IsWide(iswide) {
+  }
+
+  /// \brief Construct an empty character literal.
+  CharacterLiteral(EmptyShell Empty) : Expr(CharacterLiteralClass, Empty) { }
+
+  SourceLocation getLocation() const { return Loc; }
+  bool isWide() const { return IsWide; }
+
+  virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
+
+  unsigned getValue() const { return Value; }
+
+  void setLocation(SourceLocation Location) { Loc = Location; }
+  void setWide(bool W) { IsWide = W; }
+  void setValue(unsigned Val) { Value = Val; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CharacterLiteralClass;
+  }
+  static bool classof(const CharacterLiteral *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+class FloatingLiteral : public Expr {
+  llvm::APFloat Value;
+  bool IsExact : 1;
+  SourceLocation Loc;
+public:
+  FloatingLiteral(const llvm::APFloat &V, bool isexact,
+                  QualType Type, SourceLocation L)
+    : Expr(FloatingLiteralClass, Type, false, false), Value(V),
+      IsExact(isexact), Loc(L) {}
+
+  /// \brief Construct an empty floating-point literal.
+  explicit FloatingLiteral(EmptyShell Empty)
+    : Expr(FloatingLiteralClass, Empty), Value(0.0) { }
+
+  const llvm::APFloat &getValue() const { return Value; }
+  void setValue(const llvm::APFloat &Val) { Value = Val; }
+
+  bool isExact() const { return IsExact; }
+  void setExact(bool E) { IsExact = E; }
+
+  /// getValueAsApproximateDouble - This returns the value as an inaccurate
+  /// double.  Note that this may cause loss of precision, but is useful for
+  /// debugging dumps, etc.
+  double getValueAsApproximateDouble() const;
+
+  SourceLocation getLocation() const { return Loc; }
+  void setLocation(SourceLocation L) { Loc = L; }
+
+  virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == FloatingLiteralClass;
+  }
+  static bool classof(const FloatingLiteral *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+/// ImaginaryLiteral - We support imaginary integer and floating point literals,
+/// like "1.0i".  We represent these as a wrapper around FloatingLiteral and
+/// IntegerLiteral classes.  Instances of this class always have a Complex type
+/// whose element type matches the subexpression.
+///
+class ImaginaryLiteral : public Expr {
+  Stmt *Val;
+public:
+  ImaginaryLiteral(Expr *val, QualType Ty)
+    : Expr(ImaginaryLiteralClass, Ty, false, false), Val(val) {}
+
+  /// \brief Build an empty imaginary literal.
+  explicit ImaginaryLiteral(EmptyShell Empty)
+    : Expr(ImaginaryLiteralClass, Empty) { }
+
+  const Expr *getSubExpr() const { return cast<Expr>(Val); }
+  Expr *getSubExpr() { return cast<Expr>(Val); }
+  void setSubExpr(Expr *E) { Val = E; }
+
+  virtual SourceRange getSourceRange() const { return Val->getSourceRange(); }
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ImaginaryLiteralClass;
+  }
+  static bool classof(const ImaginaryLiteral *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+/// StringLiteral - This represents a string literal expression, e.g. "foo"
+/// or L"bar" (wide strings).  The actual string is returned by getStrData()
+/// is NOT null-terminated, and the length of the string is determined by
+/// calling getByteLength().  The C type for a string is always a
+/// ConstantArrayType.  In C++, the char type is const qualified, in C it is
+/// not.
+///
+/// Note that strings in C can be formed by concatenation of multiple string
+/// literal pptokens in translation phase #6.  This keeps track of the locations
+/// of each of these pieces.
+///
+/// Strings in C can also be truncated and extended by assigning into arrays,
+/// e.g. with constructs like:
+///   char X[2] = "foobar";
+/// In this case, getByteLength() will return 6, but the string literal will
+/// have type "char[2]".
+class StringLiteral : public Expr {
+  const char *StrData;
+  unsigned ByteLength;
+  bool IsWide;
+  unsigned NumConcatenated;
+  SourceLocation TokLocs[1];
+
+  StringLiteral(QualType Ty) : Expr(StringLiteralClass, Ty, false, false) {}
+
+protected:
+  virtual void DoDestroy(ASTContext &C);
+
+public:
+  /// This is the "fully general" constructor that allows representation of
+  /// strings formed from multiple concatenated tokens.
+  static StringLiteral *Create(ASTContext &C, const char *StrData,
+                               unsigned ByteLength, bool Wide, QualType Ty,
+                               const SourceLocation *Loc, unsigned NumStrs);
+
+  /// Simple constructor for string literals made from one token.
+  static StringLiteral *Create(ASTContext &C, const char *StrData,
+                               unsigned ByteLength,
+                               bool Wide, QualType Ty, SourceLocation Loc) {
+    return Create(C, StrData, ByteLength, Wide, Ty, &Loc, 1);
+  }
+
+  /// \brief Construct an empty string literal.
+  static StringLiteral *CreateEmpty(ASTContext &C, unsigned NumStrs);
+
+  llvm::StringRef getString() const {
+    return llvm::StringRef(StrData, ByteLength);
+  }
+  // FIXME: These are deprecated, replace with StringRef.
+  const char *getStrData() const { return StrData; }
+  unsigned getByteLength() const { return ByteLength; }
+
+  /// \brief Sets the string data to the given string data.
+  void setString(ASTContext &C, llvm::StringRef Str);
+
+  bool isWide() const { return IsWide; }
+  void setWide(bool W) { IsWide = W; }
+
+  bool containsNonAsciiOrNull() const {
+    llvm::StringRef Str = getString();
+    for (unsigned i = 0, e = Str.size(); i != e; ++i)
+      if (!isascii(Str[i]) || !Str[i])
+        return true;
+    return false;
+  }
+  /// getNumConcatenated - Get the number of string literal tokens that were
+  /// concatenated in translation phase #6 to form this string literal.
+  unsigned getNumConcatenated() const { return NumConcatenated; }
+
+  SourceLocation getStrTokenLoc(unsigned TokNum) const {
+    assert(TokNum < NumConcatenated && "Invalid tok number");
+    return TokLocs[TokNum];
+  }
+  void setStrTokenLoc(unsigned TokNum, SourceLocation L) {
+    assert(TokNum < NumConcatenated && "Invalid tok number");
+    TokLocs[TokNum] = L;
+  }
+
+  typedef const SourceLocation *tokloc_iterator;
+  tokloc_iterator tokloc_begin() const { return TokLocs; }
+  tokloc_iterator tokloc_end() const { return TokLocs+NumConcatenated; }
+
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(TokLocs[0], TokLocs[NumConcatenated-1]);
+  }
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == StringLiteralClass;
+  }
+  static bool classof(const StringLiteral *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+/// ParenExpr - This represents a parethesized expression, e.g. "(1)".  This
+/// AST node is only formed if full location information is requested.
+class ParenExpr : public Expr {
+  SourceLocation L, R;
+  Stmt *Val;
+public:
+  ParenExpr(SourceLocation l, SourceLocation r, Expr *val)
+    : Expr(ParenExprClass, val->getType(),
+           val->isTypeDependent(), val->isValueDependent()),
+      L(l), R(r), Val(val) {}
+
+  /// \brief Construct an empty parenthesized expression.
+  explicit ParenExpr(EmptyShell Empty)
+    : Expr(ParenExprClass, Empty) { }
+
+  const Expr *getSubExpr() const { return cast<Expr>(Val); }
+  Expr *getSubExpr() { return cast<Expr>(Val); }
+  void setSubExpr(Expr *E) { Val = E; }
+
+  virtual SourceRange getSourceRange() const { return SourceRange(L, R); }
+
+  /// \brief Get the location of the left parentheses '('.
+  SourceLocation getLParen() const { return L; }
+  void setLParen(SourceLocation Loc) { L = Loc; }
+
+  /// \brief Get the location of the right parentheses ')'.
+  SourceLocation getRParen() const { return R; }
+  void setRParen(SourceLocation Loc) { R = Loc; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ParenExprClass;
+  }
+  static bool classof(const ParenExpr *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+
+/// UnaryOperator - This represents the unary-expression's (except sizeof and
+/// alignof), the postinc/postdec operators from postfix-expression, and various
+/// extensions.
+///
+/// Notes on various nodes:
+///
+/// Real/Imag - These return the real/imag part of a complex operand.  If
+///   applied to a non-complex value, the former returns its operand and the
+///   later returns zero in the type of the operand.
+///
+/// __builtin_offsetof(type, a.b[10]) is represented as a unary operator whose
+///   subexpression is a compound literal with the various MemberExpr and
+///   ArraySubscriptExpr's applied to it.
+///
+class UnaryOperator : public Expr {
+public:
+  // Note that additions to this should also update the StmtVisitor class.
+  enum Opcode {
+    PostInc, PostDec, // [C99 6.5.2.4] Postfix increment and decrement operators
+    PreInc, PreDec,   // [C99 6.5.3.1] Prefix increment and decrement operators.
+    AddrOf, Deref,    // [C99 6.5.3.2] Address and indirection operators.
+    Plus, Minus,      // [C99 6.5.3.3] Unary arithmetic operators.
+    Not, LNot,        // [C99 6.5.3.3] Unary arithmetic operators.
+    Real, Imag,       // "__real expr"/"__imag expr" Extension.
+    Extension,        // __extension__ marker.
+    OffsetOf          // __builtin_offsetof
+  };
+private:
+  Stmt *Val;
+  Opcode Opc;
+  SourceLocation Loc;
+public:
+
+  UnaryOperator(Expr *input, Opcode opc, QualType type, SourceLocation l)
+    : Expr(UnaryOperatorClass, type,
+           input->isTypeDependent() && opc != OffsetOf,
+           input->isValueDependent()),
+      Val(input), Opc(opc), Loc(l) {}
+
+  /// \brief Build an empty unary operator.
+  explicit UnaryOperator(EmptyShell Empty)
+    : Expr(UnaryOperatorClass, Empty), Opc(AddrOf) { }
+
+  Opcode getOpcode() const { return Opc; }
+  void setOpcode(Opcode O) { Opc = O; }
+
+  Expr *getSubExpr() const { return cast<Expr>(Val); }
+  void setSubExpr(Expr *E) { Val = E; }
+
+  /// getOperatorLoc - Return the location of the operator.
+  SourceLocation getOperatorLoc() const { return Loc; }
+  void setOperatorLoc(SourceLocation L) { Loc = L; }
+
+  /// isPostfix - Return true if this is a postfix operation, like x++.
+  static bool isPostfix(Opcode Op) {
+    return Op == PostInc || Op == PostDec;
+  }
+
+  /// isPostfix - Return true if this is a prefix operation, like --x.
+  static bool isPrefix(Opcode Op) {
+    return Op == PreInc || Op == PreDec;
+  }
+
+  bool isPrefix() const { return isPrefix(Opc); }
+  bool isPostfix() const { return isPostfix(Opc); }
+  bool isIncrementOp() const {return Opc==PreInc || Opc==PostInc; }
+  bool isIncrementDecrementOp() const { return Opc>=PostInc && Opc<=PreDec; }
+  bool isOffsetOfOp() const { return Opc == OffsetOf; }
+  static bool isArithmeticOp(Opcode Op) { return Op >= Plus && Op <= LNot; }
+  bool isArithmeticOp() const { return isArithmeticOp(Opc); }
+
+  /// getOpcodeStr - Turn an Opcode enum value into the punctuation char it
+  /// corresponds to, e.g. "sizeof" or "[pre]++"
+  static const char *getOpcodeStr(Opcode Op);
+
+  /// \brief Retrieve the unary opcode that corresponds to the given
+  /// overloaded operator.
+  static Opcode getOverloadedOpcode(OverloadedOperatorKind OO, bool Postfix);
+
+  /// \brief Retrieve the overloaded operator kind that corresponds to
+  /// the given unary opcode.
+  static OverloadedOperatorKind getOverloadedOperator(Opcode Opc);
+
+  virtual SourceRange getSourceRange() const {
+    if (isPostfix())
+      return SourceRange(Val->getLocStart(), Loc);
+    else
+      return SourceRange(Loc, Val->getLocEnd());
+  }
+  virtual SourceLocation getExprLoc() const { return Loc; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == UnaryOperatorClass;
+  }
+  static bool classof(const UnaryOperator *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+/// SizeOfAlignOfExpr - [C99 6.5.3.4] - This is for sizeof/alignof, both of
+/// types and expressions.
+class SizeOfAlignOfExpr : public Expr {
+  bool isSizeof : 1;  // true if sizeof, false if alignof.
+  bool isType : 1;    // true if operand is a type, false if an expression
+  union {
+    TypeSourceInfo *Ty;
+    Stmt *Ex;
+  } Argument;
+  SourceLocation OpLoc, RParenLoc;
+
+protected:
+  virtual void DoDestroy(ASTContext& C);
+
+public:
+  SizeOfAlignOfExpr(bool issizeof, TypeSourceInfo *TInfo,
+                    QualType resultType, SourceLocation op,
+                    SourceLocation rp) :
+      Expr(SizeOfAlignOfExprClass, resultType,
+           false, // Never type-dependent (C++ [temp.dep.expr]p3).
+           // Value-dependent if the argument is type-dependent.
+           TInfo->getType()->isDependentType()),
+      isSizeof(issizeof), isType(true), OpLoc(op), RParenLoc(rp) {
+    Argument.Ty = TInfo;
+  }
+
+  SizeOfAlignOfExpr(bool issizeof, Expr *E,
+                    QualType resultType, SourceLocation op,
+                    SourceLocation rp) :
+      Expr(SizeOfAlignOfExprClass, resultType,
+           false, // Never type-dependent (C++ [temp.dep.expr]p3).
+           // Value-dependent if the argument is type-dependent.
+           E->isTypeDependent()),
+      isSizeof(issizeof), isType(false), OpLoc(op), RParenLoc(rp) {
+    Argument.Ex = E;
+  }
+
+  /// \brief Construct an empty sizeof/alignof expression.
+  explicit SizeOfAlignOfExpr(EmptyShell Empty)
+    : Expr(SizeOfAlignOfExprClass, Empty) { }
+
+  bool isSizeOf() const { return isSizeof; }
+  void setSizeof(bool S) { isSizeof = S; }
+
+  bool isArgumentType() const { return isType; }
+  QualType getArgumentType() const {
+    return getArgumentTypeInfo()->getType();
+  }
+  TypeSourceInfo *getArgumentTypeInfo() const {
+    assert(isArgumentType() && "calling getArgumentType() when arg is expr");
+    return Argument.Ty;
+  }
+  Expr *getArgumentExpr() {
+    assert(!isArgumentType() && "calling getArgumentExpr() when arg is type");
+    return static_cast<Expr*>(Argument.Ex);
+  }
+  const Expr *getArgumentExpr() const {
+    return const_cast<SizeOfAlignOfExpr*>(this)->getArgumentExpr();
+  }
+
+  void setArgument(Expr *E) { Argument.Ex = E; isType = false; }
+  void setArgument(TypeSourceInfo *TInfo) {
+    Argument.Ty = TInfo;
+    isType = true;
+  }
+
+  /// Gets the argument type, or the type of the argument expression, whichever
+  /// is appropriate.
+  QualType getTypeOfArgument() const {
+    return isArgumentType() ? getArgumentType() : getArgumentExpr()->getType();
+  }
+
+  SourceLocation getOperatorLoc() const { return OpLoc; }
+  void setOperatorLoc(SourceLocation L) { OpLoc = L; }
+
+  SourceLocation getRParenLoc() const { return RParenLoc; }
+  void setRParenLoc(SourceLocation L) { RParenLoc = L; }
+
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(OpLoc, RParenLoc);
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == SizeOfAlignOfExprClass;
+  }
+  static bool classof(const SizeOfAlignOfExpr *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+//===----------------------------------------------------------------------===//
+// Postfix Operators.
+//===----------------------------------------------------------------------===//
+
+/// ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
+class ArraySubscriptExpr : public Expr {
+  enum { LHS, RHS, END_EXPR=2 };
+  Stmt* SubExprs[END_EXPR];
+  SourceLocation RBracketLoc;
+public:
+  ArraySubscriptExpr(Expr *lhs, Expr *rhs, QualType t,
+                     SourceLocation rbracketloc)
+  : Expr(ArraySubscriptExprClass, t,
+         lhs->isTypeDependent() || rhs->isTypeDependent(),
+         lhs->isValueDependent() || rhs->isValueDependent()),
+    RBracketLoc(rbracketloc) {
+    SubExprs[LHS] = lhs;
+    SubExprs[RHS] = rhs;
+  }
+
+  /// \brief Create an empty array subscript expression.
+  explicit ArraySubscriptExpr(EmptyShell Shell)
+    : Expr(ArraySubscriptExprClass, Shell) { }
+
+  /// An array access can be written A[4] or 4[A] (both are equivalent).
+  /// - getBase() and getIdx() always present the normalized view: A[4].
+  ///    In this case getBase() returns "A" and getIdx() returns "4".
+  /// - getLHS() and getRHS() present the syntactic view. e.g. for
+  ///    4[A] getLHS() returns "4".
+  /// Note: Because vector element access is also written A[4] we must
+  /// predicate the format conversion in getBase and getIdx only on the
+  /// the type of the RHS, as it is possible for the LHS to be a vector of
+  /// integer type
+  Expr *getLHS() { return cast<Expr>(SubExprs[LHS]); }
+  const Expr *getLHS() const { return cast<Expr>(SubExprs[LHS]); }
+  void setLHS(Expr *E) { SubExprs[LHS] = E; }
+
+  Expr *getRHS() { return cast<Expr>(SubExprs[RHS]); }
+  const Expr *getRHS() const { return cast<Expr>(SubExprs[RHS]); }
+  void setRHS(Expr *E) { SubExprs[RHS] = E; }
+
+  Expr *getBase() {
+    return cast<Expr>(getRHS()->getType()->isIntegerType() ? getLHS():getRHS());
+  }
+
+  const Expr *getBase() const {
+    return cast<Expr>(getRHS()->getType()->isIntegerType() ? getLHS():getRHS());
+  }
+
+  Expr *getIdx() {
+    return cast<Expr>(getRHS()->getType()->isIntegerType() ? getRHS():getLHS());
+  }
+
+  const Expr *getIdx() const {
+    return cast<Expr>(getRHS()->getType()->isIntegerType() ? getRHS():getLHS());
+  }
+
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(getLHS()->getLocStart(), RBracketLoc);
+  }
+
+  SourceLocation getRBracketLoc() const { return RBracketLoc; }
+  void setRBracketLoc(SourceLocation L) { RBracketLoc = L; }
+
+  virtual SourceLocation getExprLoc() const { return getBase()->getExprLoc(); }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ArraySubscriptExprClass;
+  }
+  static bool classof(const ArraySubscriptExpr *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+
+/// CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
+/// CallExpr itself represents a normal function call, e.g., "f(x, 2)",
+/// while its subclasses may represent alternative syntax that (semantically)
+/// results in a function call. For example, CXXOperatorCallExpr is
+/// a subclass for overloaded operator calls that use operator syntax, e.g.,
+/// "str1 + str2" to resolve to a function call.
+class CallExpr : public Expr {
+  enum { FN=0, ARGS_START=1 };
+  Stmt **SubExprs;
+  unsigned NumArgs;
+  SourceLocation RParenLoc;
+
+protected:
+  // This version of the constructor is for derived classes.
+  CallExpr(ASTContext& C, StmtClass SC, Expr *fn, Expr **args, unsigned numargs,
+           QualType t, SourceLocation rparenloc);
+
+  virtual void DoDestroy(ASTContext& C);
+
+public:
+  CallExpr(ASTContext& C, Expr *fn, Expr **args, unsigned numargs, QualType t,
+           SourceLocation rparenloc);
+
+  /// \brief Build an empty call expression.
+  CallExpr(ASTContext &C, StmtClass SC, EmptyShell Empty);
+
+  ~CallExpr() {}
+
+  const Expr *getCallee() const { return cast<Expr>(SubExprs[FN]); }
+  Expr *getCallee() { return cast<Expr>(SubExprs[FN]); }
+  void setCallee(Expr *F) { SubExprs[FN] = F; }
+
+  Decl *getCalleeDecl();
+  const Decl *getCalleeDecl() const {
+    return const_cast<CallExpr*>(this)->getCalleeDecl();
+  }
+
+  /// \brief If the callee is a FunctionDecl, return it. Otherwise return 0.
+  FunctionDecl *getDirectCallee();
+  const FunctionDecl *getDirectCallee() const {
+    return const_cast<CallExpr*>(this)->getDirectCallee();
+  }
+
+  /// getNumArgs - Return the number of actual arguments to this call.
+  ///
+  unsigned getNumArgs() const { return NumArgs; }
+
+  /// getArg - Return the specified argument.
+  Expr *getArg(unsigned Arg) {
+    assert(Arg < NumArgs && "Arg access out of range!");
+    return cast<Expr>(SubExprs[Arg+ARGS_START]);
+  }
+  const Expr *getArg(unsigned Arg) const {
+    assert(Arg < NumArgs && "Arg access out of range!");
+    return cast<Expr>(SubExprs[Arg+ARGS_START]);
+  }
+
+  /// setArg - Set the specified argument.
+  void setArg(unsigned Arg, Expr *ArgExpr) {
+    assert(Arg < NumArgs && "Arg access out of range!");
+    SubExprs[Arg+ARGS_START] = ArgExpr;
+  }
+
+  /// setNumArgs - This changes the number of arguments present in this call.
+  /// Any orphaned expressions are deleted by this, and any new operands are set
+  /// to null.
+  void setNumArgs(ASTContext& C, unsigned NumArgs);
+
+  typedef ExprIterator arg_iterator;
+  typedef ConstExprIterator const_arg_iterator;
+
+  arg_iterator arg_begin() { return SubExprs+ARGS_START; }
+  arg_iterator arg_end() { return SubExprs+ARGS_START+getNumArgs(); }
+  const_arg_iterator arg_begin() const { return SubExprs+ARGS_START; }
+  const_arg_iterator arg_end() const { return SubExprs+ARGS_START+getNumArgs();}
+
+  /// getNumCommas - Return the number of commas that must have been present in
+  /// this function call.
+  unsigned getNumCommas() const { return NumArgs ? NumArgs - 1 : 0; }
+
+  /// isBuiltinCall - If this is a call to a builtin, return the builtin ID.  If
+  /// not, return 0.
+  unsigned isBuiltinCall(ASTContext &Context) const;
+
+  /// getCallReturnType - Get the return type of the call expr. This is not
+  /// always the type of the expr itself, if the return type is a reference
+  /// type.
+  QualType getCallReturnType() const;
+
+  SourceLocation getRParenLoc() const { return RParenLoc; }
+  void setRParenLoc(SourceLocation L) { RParenLoc = L; }
+
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(getCallee()->getLocStart(), RParenLoc);
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CallExprClass ||
+           T->getStmtClass() == CXXOperatorCallExprClass ||
+           T->getStmtClass() == CXXMemberCallExprClass;
+  }
+  static bool classof(const CallExpr *) { return true; }
+  static bool classof(const CXXOperatorCallExpr *) { return true; }
+  static bool classof(const CXXMemberCallExpr *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+/// MemberExpr - [C99 6.5.2.3] Structure and Union Members.  X->F and X.F.
+///
+class MemberExpr : public Expr {
+  /// Extra data stored in some member expressions.
+  struct MemberNameQualifier : public NameQualifier {
+    DeclAccessPair FoundDecl;
+  };
+
+  /// Base - the expression for the base pointer or structure references.  In
+  /// X.F, this is "X".
+  Stmt *Base;
+
+  /// MemberDecl - This is the decl being referenced by the field/member name.
+  /// In X.F, this is the decl referenced by F.
+  ValueDecl *MemberDecl;
+
+  /// MemberLoc - This is the location of the member name.
+  SourceLocation MemberLoc;
+
+  /// IsArrow - True if this is "X->F", false if this is "X.F".
+  bool IsArrow : 1;
+
+  /// \brief True if this member expression used a nested-name-specifier to
+  /// refer to the member, e.g., "x->Base::f", or found its member via a using
+  /// declaration.  When true, a MemberNameQualifier
+  /// structure is allocated immediately after the MemberExpr.
+  bool HasQualifierOrFoundDecl : 1;
+
+  /// \brief True if this member expression specified a template argument list
+  /// explicitly, e.g., x->f<int>. When true, an ExplicitTemplateArgumentList
+  /// structure (and its TemplateArguments) are allocated immediately after
+  /// the MemberExpr or, if the member expression also has a qualifier, after
+  /// the MemberNameQualifier structure.
+  bool HasExplicitTemplateArgumentList : 1;
+
+  /// \brief Retrieve the qualifier that preceded the member name, if any.
+  MemberNameQualifier *getMemberQualifier() {
+    assert(HasQualifierOrFoundDecl);
+    return reinterpret_cast<MemberNameQualifier *> (this + 1);
+  }
+
+  /// \brief Retrieve the qualifier that preceded the member name, if any.
+  const MemberNameQualifier *getMemberQualifier() const {
+    return const_cast<MemberExpr *>(this)->getMemberQualifier();
+  }
+
+  /// \brief Retrieve the explicit template argument list that followed the
+  /// member template name, if any.
+  ExplicitTemplateArgumentList *getExplicitTemplateArgumentList() {
+    if (!HasExplicitTemplateArgumentList)
+      return 0;
+
+    if (!HasQualifierOrFoundDecl)
+      return reinterpret_cast<ExplicitTemplateArgumentList *>(this + 1);
+
+    return reinterpret_cast<ExplicitTemplateArgumentList *>(
+                                                      getMemberQualifier() + 1);
+  }
+
+  /// \brief Retrieve the explicit template argument list that followed the
+  /// member template name, if any.
+  const ExplicitTemplateArgumentList *getExplicitTemplateArgumentList() const {
+    return const_cast<MemberExpr *>(this)->getExplicitTemplateArgumentList();
+  }
+
+public:
+  MemberExpr(Expr *base, bool isarrow, ValueDecl *memberdecl,
+             SourceLocation l, QualType ty)
+    : Expr(MemberExprClass, ty,
+           base->isTypeDependent(), base->isValueDependent()),
+      Base(base), MemberDecl(memberdecl), MemberLoc(l), IsArrow(isarrow),
+      HasQualifierOrFoundDecl(false), HasExplicitTemplateArgumentList(false) {}
+
+  /// \brief Build an empty member reference expression.
+  explicit MemberExpr(EmptyShell Empty)
+    : Expr(MemberExprClass, Empty), HasQualifierOrFoundDecl(false),
+      HasExplicitTemplateArgumentList(false) { }
+
+  static MemberExpr *Create(ASTContext &C, Expr *base, bool isarrow,
+                            NestedNameSpecifier *qual, SourceRange qualrange,
+                            ValueDecl *memberdecl, DeclAccessPair founddecl,
+                            SourceLocation l,
+                            const TemplateArgumentListInfo *targs,
+                            QualType ty);
+
+  void setBase(Expr *E) { Base = E; }
+  Expr *getBase() const { return cast<Expr>(Base); }
+
+  /// \brief Retrieve the member declaration to which this expression refers.
+  ///
+  /// The returned declaration will either be a FieldDecl or (in C++)
+  /// a CXXMethodDecl.
+  ValueDecl *getMemberDecl() const { return MemberDecl; }
+  void setMemberDecl(ValueDecl *D) { MemberDecl = D; }
+
+  /// \brief Retrieves the declaration found by lookup.
+  DeclAccessPair getFoundDecl() const {
+    if (!HasQualifierOrFoundDecl)
+      return DeclAccessPair::make(getMemberDecl(),
+                                  getMemberDecl()->getAccess());
+    return getMemberQualifier()->FoundDecl;
+  }
+
+  /// \brief Determines whether this member expression actually had
+  /// a C++ nested-name-specifier prior to the name of the member, e.g.,
+  /// x->Base::foo.
+  bool hasQualifier() const { return getQualifier() != 0; }
+
+  /// \brief If the member name was qualified, retrieves the source range of
+  /// the nested-name-specifier that precedes the member name. Otherwise,
+  /// returns an empty source range.
+  SourceRange getQualifierRange() const {
+    if (!HasQualifierOrFoundDecl)
+      return SourceRange();
+
+    return getMemberQualifier()->Range;
+  }
+
+  /// \brief If the member name was qualified, retrieves the
+  /// nested-name-specifier that precedes the member name. Otherwise, returns
+  /// NULL.
+  NestedNameSpecifier *getQualifier() const {
+    if (!HasQualifierOrFoundDecl)
+      return 0;
+
+    return getMemberQualifier()->NNS;
+  }
+
+  /// \brief Determines whether this member expression actually had a C++
+  /// template argument list explicitly specified, e.g., x.f<int>.
+  bool hasExplicitTemplateArgumentList() const {
+    return HasExplicitTemplateArgumentList;
+  }
+
+  /// \brief Copies the template arguments (if present) into the given
+  /// structure.
+  void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
+    if (hasExplicitTemplateArgumentList())
+      getExplicitTemplateArgumentList()->copyInto(List);
+  }
+  
+  /// \brief Retrieve the location of the left angle bracket following the
+  /// member name ('<'), if any.
+  SourceLocation getLAngleLoc() const {
+    if (!HasExplicitTemplateArgumentList)
+      return SourceLocation();
+
+    return getExplicitTemplateArgumentList()->LAngleLoc;
+  }
+
+  /// \brief Retrieve the template arguments provided as part of this
+  /// template-id.
+  const TemplateArgumentLoc *getTemplateArgs() const {
+    if (!HasExplicitTemplateArgumentList)
+      return 0;
+
+    return getExplicitTemplateArgumentList()->getTemplateArgs();
+  }
+
+  /// \brief Retrieve the number of template arguments provided as part of this
+  /// template-id.
+  unsigned getNumTemplateArgs() const {
+    if (!HasExplicitTemplateArgumentList)
+      return 0;
+
+    return getExplicitTemplateArgumentList()->NumTemplateArgs;
+  }
+
+  /// \brief Retrieve the location of the right angle bracket following the
+  /// template arguments ('>').
+  SourceLocation getRAngleLoc() const {
+    if (!HasExplicitTemplateArgumentList)
+      return SourceLocation();
+
+    return getExplicitTemplateArgumentList()->RAngleLoc;
+  }
+
+  bool isArrow() const { return IsArrow; }
+  void setArrow(bool A) { IsArrow = A; }
+
+  /// getMemberLoc - Return the location of the "member", in X->F, it is the
+  /// location of 'F'.
+  SourceLocation getMemberLoc() const { return MemberLoc; }
+  void setMemberLoc(SourceLocation L) { MemberLoc = L; }
+
+  virtual SourceRange getSourceRange() const {
+    // If we have an implicit base (like a C++ implicit this),
+    // make sure not to return its location
+    SourceLocation EndLoc = MemberLoc;
+    if (HasExplicitTemplateArgumentList)
+      EndLoc = getRAngleLoc();
+
+    SourceLocation BaseLoc = getBase()->getLocStart();
+    if (BaseLoc.isInvalid())
+      return SourceRange(MemberLoc, EndLoc);
+    return SourceRange(BaseLoc, EndLoc);
+  }
+
+  virtual SourceLocation getExprLoc() const { return MemberLoc; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == MemberExprClass;
+  }
+  static bool classof(const MemberExpr *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+/// CompoundLiteralExpr - [C99 6.5.2.5]
+///
+class CompoundLiteralExpr : public Expr {
+  /// LParenLoc - If non-null, this is the location of the left paren in a
+  /// compound literal like "(int){4}".  This can be null if this is a
+  /// synthesized compound expression.
+  SourceLocation LParenLoc;
+
+  /// The type as written.  This can be an incomplete array type, in
+  /// which case the actual expression type will be different.
+  TypeSourceInfo *TInfo;
+  Stmt *Init;
+  bool FileScope;
+public:
+  // FIXME: Can compound literals be value-dependent?
+  CompoundLiteralExpr(SourceLocation lparenloc, TypeSourceInfo *tinfo,
+                      QualType T, Expr *init, bool fileScope)
+    : Expr(CompoundLiteralExprClass, T,
+           tinfo->getType()->isDependentType(), false),
+      LParenLoc(lparenloc), TInfo(tinfo), Init(init), FileScope(fileScope) {}
+
+  /// \brief Construct an empty compound literal.
+  explicit CompoundLiteralExpr(EmptyShell Empty)
+    : Expr(CompoundLiteralExprClass, Empty) { }
+
+  const Expr *getInitializer() const { return cast<Expr>(Init); }
+  Expr *getInitializer() { return cast<Expr>(Init); }
+  void setInitializer(Expr *E) { Init = E; }
+
+  bool isFileScope() const { return FileScope; }
+  void setFileScope(bool FS) { FileScope = FS; }
+
+  SourceLocation getLParenLoc() const { return LParenLoc; }
+  void setLParenLoc(SourceLocation L) { LParenLoc = L; }
+
+  TypeSourceInfo *getTypeSourceInfo() const { return TInfo; }
+  void setTypeSourceInfo(TypeSourceInfo* tinfo) { TInfo = tinfo; }
+
+  virtual SourceRange getSourceRange() const {
+    // FIXME: Init should never be null.
+    if (!Init)
+      return SourceRange();
+    if (LParenLoc.isInvalid())
+      return Init->getSourceRange();
+    return SourceRange(LParenLoc, Init->getLocEnd());
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CompoundLiteralExprClass;
+  }
+  static bool classof(const CompoundLiteralExpr *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+/// CastExpr - Base class for type casts, including both implicit
+/// casts (ImplicitCastExpr) and explicit casts that have some
+/// representation in the source code (ExplicitCastExpr's derived
+/// classes).
+class CastExpr : public Expr {
+public:
+  /// CastKind - the kind of cast this represents.
+  enum CastKind {
+    /// CK_Unknown - Unknown cast kind.
+    /// FIXME: The goal is to get rid of this and make all casts have a
+    /// kind so that the AST client doesn't have to try to figure out what's
+    /// going on.
+    CK_Unknown,
+
+    /// CK_BitCast - Used for reinterpret_cast.
+    CK_BitCast,
+
+    /// CK_NoOp - Used for const_cast.
+    CK_NoOp,
+
+    /// CK_BaseToDerived - Base to derived class casts.
+    CK_BaseToDerived,
+
+    /// CK_DerivedToBase - Derived to base class casts.
+    CK_DerivedToBase,
+
+    /// CK_UncheckedDerivedToBase - Derived to base class casts that
+    /// assume that the derived pointer is not null.
+    CK_UncheckedDerivedToBase,
+
+    /// CK_Dynamic - Dynamic cast.
+    CK_Dynamic,
+
+    /// CK_ToUnion - Cast to union (GCC extension).
+    CK_ToUnion,
+
+    /// CK_ArrayToPointerDecay - Array to pointer decay.
+    CK_ArrayToPointerDecay,
+
+    // CK_FunctionToPointerDecay - Function to pointer decay.
+    CK_FunctionToPointerDecay,
+
+    /// CK_NullToMemberPointer - Null pointer to member pointer.
+    CK_NullToMemberPointer,
+
+    /// CK_BaseToDerivedMemberPointer - Member pointer in base class to
+    /// member pointer in derived class.
+    CK_BaseToDerivedMemberPointer,
+
+    /// CK_DerivedToBaseMemberPointer - Member pointer in derived class to
+    /// member pointer in base class.
+    CK_DerivedToBaseMemberPointer,
+    
+    /// CK_UserDefinedConversion - Conversion using a user defined type
+    /// conversion function.
+    CK_UserDefinedConversion,
+
+    /// CK_ConstructorConversion - Conversion by constructor
+    CK_ConstructorConversion,
+    
+    /// CK_IntegralToPointer - Integral to pointer
+    CK_IntegralToPointer,
+    
+    /// CK_PointerToIntegral - Pointer to integral
+    CK_PointerToIntegral,
+    
+    /// CK_ToVoid - Cast to void.
+    CK_ToVoid,
+    
+    /// CK_VectorSplat - Casting from an integer/floating type to an extended
+    /// vector type with the same element type as the src type. Splats the 
+    /// src expression into the destination expression.
+    CK_VectorSplat,
+    
+    /// CK_IntegralCast - Casting between integral types of different size.
+    CK_IntegralCast,
+
+    /// CK_IntegralToFloating - Integral to floating point.
+    CK_IntegralToFloating,
+    
+    /// CK_FloatingToIntegral - Floating point to integral.
+    CK_FloatingToIntegral,
+    
+    /// CK_FloatingCast - Casting between floating types of different size.
+    CK_FloatingCast,
+    
+    /// CK_MemberPointerToBoolean - Member pointer to boolean
+    CK_MemberPointerToBoolean,
+
+    /// CK_AnyPointerToObjCPointerCast - Casting any pointer to objective-c 
+    /// pointer
+    CK_AnyPointerToObjCPointerCast,
+    /// CK_AnyPointerToBlockPointerCast - Casting any pointer to block 
+    /// pointer
+    CK_AnyPointerToBlockPointerCast
+
+  };
+
+private:
+  CastKind Kind;
+  Stmt *Op;
+
+  /// BasePath - For derived-to-base and base-to-derived casts, the base array
+  /// contains the inheritance path.
+  CXXBaseSpecifierArray BasePath;
+
+  void CheckBasePath() const {
+#ifndef NDEBUG
+    switch (getCastKind()) {
+    case CK_DerivedToBase:
+    case CK_UncheckedDerivedToBase:
+    case CK_DerivedToBaseMemberPointer:
+    case CK_BaseToDerived:
+    case CK_BaseToDerivedMemberPointer:
+      assert(!BasePath.empty() && "Cast kind should have a base path!");
+      break;
+
+    // These should not have an inheritance path.
+    case CK_Unknown:
+    case CK_BitCast:
+    case CK_NoOp:
+    case CK_Dynamic:
+    case CK_ToUnion:
+    case CK_ArrayToPointerDecay:
+    case CK_FunctionToPointerDecay:
+    case CK_NullToMemberPointer:
+    case CK_UserDefinedConversion:
+    case CK_ConstructorConversion:
+    case CK_IntegralToPointer:
+    case CK_PointerToIntegral:
+    case CK_ToVoid:
+    case CK_VectorSplat:
+    case CK_IntegralCast:
+    case CK_IntegralToFloating:
+    case CK_FloatingToIntegral:
+    case CK_FloatingCast:
+    case CK_MemberPointerToBoolean:
+    case CK_AnyPointerToObjCPointerCast:
+    case CK_AnyPointerToBlockPointerCast:
+      assert(BasePath.empty() && "Cast kind should not have a base path!");
+      break;
+    }
+#endif
+  }
+
+protected:
+  CastExpr(StmtClass SC, QualType ty, const CastKind kind, Expr *op,
+           CXXBaseSpecifierArray BasePath) :
+    Expr(SC, ty,
+         // Cast expressions are type-dependent if the type is
+         // dependent (C++ [temp.dep.expr]p3).
+         ty->isDependentType(),
+         // Cast expressions are value-dependent if the type is
+         // dependent or if the subexpression is value-dependent.
+         ty->isDependentType() || (op && op->isValueDependent())),
+    Kind(kind), Op(op), BasePath(BasePath) {
+      CheckBasePath();
+    }
+
+  /// \brief Construct an empty cast.
+  CastExpr(StmtClass SC, EmptyShell Empty)
+    : Expr(SC, Empty) { }
+
+  virtual void DoDestroy(ASTContext &C);
+
+public:
+  CastKind getCastKind() const { return Kind; }
+  void setCastKind(CastKind K) { Kind = K; }
+  const char *getCastKindName() const;
+
+  Expr *getSubExpr() { return cast<Expr>(Op); }
+  const Expr *getSubExpr() const { return cast<Expr>(Op); }
+  void setSubExpr(Expr *E) { Op = E; }
+
+  /// \brief Retrieve the cast subexpression as it was written in the source
+  /// code, looking through any implicit casts or other intermediate nodes
+  /// introduced by semantic analysis.
+  Expr *getSubExprAsWritten();
+  const Expr *getSubExprAsWritten() const {
+    return const_cast<CastExpr *>(this)->getSubExprAsWritten();
+  }
+
+  const CXXBaseSpecifierArray& getBasePath() const { return BasePath; }
+
+  static bool classof(const Stmt *T) {
+    StmtClass SC = T->getStmtClass();
+    if (SC >= CXXStaticCastExprClass && SC <= CXXFunctionalCastExprClass)
+      return true;
+
+    if (SC >= ImplicitCastExprClass && SC <= CStyleCastExprClass)
+      return true;
+
+    return false;
+  }
+  static bool classof(const CastExpr *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+/// ImplicitCastExpr - Allows us to explicitly represent implicit type
+/// conversions, which have no direct representation in the original
+/// source code. For example: converting T[]->T*, void f()->void
+/// (*f)(), float->double, short->int, etc.
+///
+/// In C, implicit casts always produce rvalues. However, in C++, an
+/// implicit cast whose result is being bound to a reference will be
+/// an lvalue. For example:
+///
+/// @code
+/// class Base { };
+/// class Derived : public Base { };
+/// void f(Derived d) {
+///   Base& b = d; // initializer is an ImplicitCastExpr to an lvalue of type Base
+/// }
+/// @endcode
+class ImplicitCastExpr : public CastExpr {
+  /// LvalueCast - Whether this cast produces an lvalue.
+  bool LvalueCast;
+
+public:
+  ImplicitCastExpr(QualType ty, CastKind kind, Expr *op, 
+                   CXXBaseSpecifierArray BasePath, bool Lvalue)
+    : CastExpr(ImplicitCastExprClass, ty, kind, op, BasePath), 
+    LvalueCast(Lvalue) { }
+
+  /// \brief Construct an empty implicit cast.
+  explicit ImplicitCastExpr(EmptyShell Shell)
+    : CastExpr(ImplicitCastExprClass, Shell) { }
+
+  virtual SourceRange getSourceRange() const {
+    return getSubExpr()->getSourceRange();
+  }
+
+  /// isLvalueCast - Whether this cast produces an lvalue.
+  bool isLvalueCast() const { return LvalueCast; }
+
+  /// setLvalueCast - Set whether this cast produces an lvalue.
+  void setLvalueCast(bool Lvalue) { LvalueCast = Lvalue; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ImplicitCastExprClass;
+  }
+  static bool classof(const ImplicitCastExpr *) { return true; }
+};
+
+/// ExplicitCastExpr - An explicit cast written in the source
+/// code.
+///
+/// This class is effectively an abstract class, because it provides
+/// the basic representation of an explicitly-written cast without
+/// specifying which kind of cast (C cast, functional cast, static
+/// cast, etc.) was written; specific derived classes represent the
+/// particular style of cast and its location information.
+///
+/// Unlike implicit casts, explicit cast nodes have two different
+/// types: the type that was written into the source code, and the
+/// actual type of the expression as determined by semantic
+/// analysis. These types may differ slightly. For example, in C++ one
+/// can cast to a reference type, which indicates that the resulting
+/// expression will be an lvalue. The reference type, however, will
+/// not be used as the type of the expression.
+class ExplicitCastExpr : public CastExpr {
+  /// TInfo - Source type info for the (written) type
+  /// this expression is casting to.
+  TypeSourceInfo *TInfo;
+
+protected:
+  ExplicitCastExpr(StmtClass SC, QualType exprTy, CastKind kind,
+                   Expr *op, CXXBaseSpecifierArray BasePath,
+                   TypeSourceInfo *writtenTy)
+    : CastExpr(SC, exprTy, kind, op, BasePath), TInfo(writtenTy) {}
+
+  /// \brief Construct an empty explicit cast.
+  ExplicitCastExpr(StmtClass SC, EmptyShell Shell)
+    : CastExpr(SC, Shell) { }
+
+public:
+  /// getTypeInfoAsWritten - Returns the type source info for the type
+  /// that this expression is casting to.
+  TypeSourceInfo *getTypeInfoAsWritten() const { return TInfo; }
+  void setTypeInfoAsWritten(TypeSourceInfo *writtenTy) { TInfo = writtenTy; }
+
+  /// getTypeAsWritten - Returns the type that this expression is
+  /// casting to, as written in the source code.
+  QualType getTypeAsWritten() const { return TInfo->getType(); }
+
+  static bool classof(const Stmt *T) {
+    StmtClass SC = T->getStmtClass();
+    if (SC >= CStyleCastExprClass && SC <= CStyleCastExprClass)
+      return true;
+    if (SC >= CXXStaticCastExprClass && SC <= CXXFunctionalCastExprClass)
+      return true;
+
+    return false;
+  }
+  static bool classof(const ExplicitCastExpr *) { return true; }
+};
+
+/// CStyleCastExpr - An explicit cast in C (C99 6.5.4) or a C-style
+/// cast in C++ (C++ [expr.cast]), which uses the syntax
+/// (Type)expr. For example: @c (int)f.
+class CStyleCastExpr : public ExplicitCastExpr {
+  SourceLocation LPLoc; // the location of the left paren
+  SourceLocation RPLoc; // the location of the right paren
+public:
+  CStyleCastExpr(QualType exprTy, CastKind kind, Expr *op,
+                 CXXBaseSpecifierArray BasePath, TypeSourceInfo *writtenTy,
+                 SourceLocation l, SourceLocation r)
+    : ExplicitCastExpr(CStyleCastExprClass, exprTy, kind, op, BasePath,
+                       writtenTy), LPLoc(l), RPLoc(r) {}
+
+  /// \brief Construct an empty C-style explicit cast.
+  explicit CStyleCastExpr(EmptyShell Shell)
+    : ExplicitCastExpr(CStyleCastExprClass, Shell) { }
+
+  SourceLocation getLParenLoc() const { return LPLoc; }
+  void setLParenLoc(SourceLocation L) { LPLoc = L; }
+
+  SourceLocation getRParenLoc() const { return RPLoc; }
+  void setRParenLoc(SourceLocation L) { RPLoc = L; }
+
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(LPLoc, getSubExpr()->getSourceRange().getEnd());
+  }
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CStyleCastExprClass;
+  }
+  static bool classof(const CStyleCastExpr *) { return true; }
+};
+
+/// \brief A builtin binary operation expression such as "x + y" or "x <= y".
+///
+/// This expression node kind describes a builtin binary operation,
+/// such as "x + y" for integer values "x" and "y". The operands will
+/// already have been converted to appropriate types (e.g., by
+/// performing promotions or conversions).
+///
+/// In C++, where operators may be overloaded, a different kind of
+/// expression node (CXXOperatorCallExpr) is used to express the
+/// invocation of an overloaded operator with operator syntax. Within
+/// a C++ template, whether BinaryOperator or CXXOperatorCallExpr is
+/// used to store an expression "x + y" depends on the subexpressions
+/// for x and y. If neither x or y is type-dependent, and the "+"
+/// operator resolves to a built-in operation, BinaryOperator will be
+/// used to express the computation (x and y may still be
+/// value-dependent). If either x or y is type-dependent, or if the
+/// "+" resolves to an overloaded operator, CXXOperatorCallExpr will
+/// be used to express the computation.
+class BinaryOperator : public Expr {
+public:
+  enum Opcode {
+    // Operators listed in order of precedence.
+    // Note that additions to this should also update the StmtVisitor class.
+    PtrMemD, PtrMemI, // [C++ 5.5] Pointer-to-member operators.
+    Mul, Div, Rem,    // [C99 6.5.5] Multiplicative operators.
+    Add, Sub,         // [C99 6.5.6] Additive operators.
+    Shl, Shr,         // [C99 6.5.7] Bitwise shift operators.
+    LT, GT, LE, GE,   // [C99 6.5.8] Relational operators.
+    EQ, NE,           // [C99 6.5.9] Equality operators.
+    And,              // [C99 6.5.10] Bitwise AND operator.
+    Xor,              // [C99 6.5.11] Bitwise XOR operator.
+    Or,               // [C99 6.5.12] Bitwise OR operator.
+    LAnd,             // [C99 6.5.13] Logical AND operator.
+    LOr,              // [C99 6.5.14] Logical OR operator.
+    Assign, MulAssign,// [C99 6.5.16] Assignment operators.
+    DivAssign, RemAssign,
+    AddAssign, SubAssign,
+    ShlAssign, ShrAssign,
+    AndAssign, XorAssign,
+    OrAssign,
+    Comma             // [C99 6.5.17] Comma operator.
+  };
+private:
+  enum { LHS, RHS, END_EXPR };
+  Stmt* SubExprs[END_EXPR];
+  Opcode Opc;
+  SourceLocation OpLoc;
+public:
+
+  BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy,
+                 SourceLocation opLoc)
+    : Expr(BinaryOperatorClass, ResTy,
+           lhs->isTypeDependent() || rhs->isTypeDependent(),
+           lhs->isValueDependent() || rhs->isValueDependent()),
+      Opc(opc), OpLoc(opLoc) {
+    SubExprs[LHS] = lhs;
+    SubExprs[RHS] = rhs;
+    assert(!isCompoundAssignmentOp() &&
+           "Use ArithAssignBinaryOperator for compound assignments");
+  }
+
+  /// \brief Construct an empty binary operator.
+  explicit BinaryOperator(EmptyShell Empty)
+    : Expr(BinaryOperatorClass, Empty), Opc(Comma) { }
+
+  SourceLocation getOperatorLoc() const { return OpLoc; }
+  void setOperatorLoc(SourceLocation L) { OpLoc = L; }
+
+  Opcode getOpcode() const { return Opc; }
+  void setOpcode(Opcode O) { Opc = O; }
+
+  Expr *getLHS() const { return cast<Expr>(SubExprs[LHS]); }
+  void setLHS(Expr *E) { SubExprs[LHS] = E; }
+  Expr *getRHS() const { return cast<Expr>(SubExprs[RHS]); }
+  void setRHS(Expr *E) { SubExprs[RHS] = E; }
+
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(getLHS()->getLocStart(), getRHS()->getLocEnd());
+  }
+
+  /// getOpcodeStr - Turn an Opcode enum value into the punctuation char it
+  /// corresponds to, e.g. "<<=".
+  static const char *getOpcodeStr(Opcode Op);
+
+  /// \brief Retrieve the binary opcode that corresponds to the given
+  /// overloaded operator.
+  static Opcode getOverloadedOpcode(OverloadedOperatorKind OO);
+
+  /// \brief Retrieve the overloaded operator kind that corresponds to
+  /// the given binary opcode.
+  static OverloadedOperatorKind getOverloadedOperator(Opcode Opc);
+
+  /// predicates to categorize the respective opcodes.
+  bool isMultiplicativeOp() const { return Opc >= Mul && Opc <= Rem; }
+  bool isAdditiveOp() const { return Opc == Add || Opc == Sub; }
+  static bool isShiftOp(Opcode Opc) { return Opc == Shl || Opc == Shr; }
+  bool isShiftOp() const { return isShiftOp(Opc); }
+
+  static bool isBitwiseOp(Opcode Opc) { return Opc >= And && Opc <= Or; }
+  bool isBitwiseOp() const { return isBitwiseOp(Opc); }
+
+  static bool isRelationalOp(Opcode Opc) { return Opc >= LT && Opc <= GE; }
+  bool isRelationalOp() const { return isRelationalOp(Opc); }
+
+  static bool isEqualityOp(Opcode Opc) { return Opc == EQ || Opc == NE; }
+  bool isEqualityOp() const { return isEqualityOp(Opc); }
+
+  static bool isComparisonOp(Opcode Opc) { return Opc >= LT && Opc <= NE; }
+  bool isComparisonOp() const { return isComparisonOp(Opc); }
+
+  static bool isLogicalOp(Opcode Opc) { return Opc == LAnd || Opc == LOr; }
+  bool isLogicalOp() const { return isLogicalOp(Opc); }
+
+  bool isAssignmentOp() const { return Opc >= Assign && Opc <= OrAssign; }
+  bool isCompoundAssignmentOp() const { return Opc > Assign && Opc <= OrAssign;}
+  bool isShiftAssignOp() const { return Opc == ShlAssign || Opc == ShrAssign; }
+
+  static bool classof(const Stmt *S) {
+    return S->getStmtClass() == BinaryOperatorClass ||
+           S->getStmtClass() == CompoundAssignOperatorClass;
+  }
+  static bool classof(const BinaryOperator *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+
+protected:
+  BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy,
+                 SourceLocation opLoc, bool dead)
+    : Expr(CompoundAssignOperatorClass, ResTy,
+           lhs->isTypeDependent() || rhs->isTypeDependent(),
+           lhs->isValueDependent() || rhs->isValueDependent()),
+      Opc(opc), OpLoc(opLoc) {
+    SubExprs[LHS] = lhs;
+    SubExprs[RHS] = rhs;
+  }
+
+  BinaryOperator(StmtClass SC, EmptyShell Empty)
+    : Expr(SC, Empty), Opc(MulAssign) { }
+};
+
+/// CompoundAssignOperator - For compound assignments (e.g. +=), we keep
+/// track of the type the operation is performed in.  Due to the semantics of
+/// these operators, the operands are promoted, the aritmetic performed, an
+/// implicit conversion back to the result type done, then the assignment takes
+/// place.  This captures the intermediate type which the computation is done
+/// in.
+class CompoundAssignOperator : public BinaryOperator {
+  QualType ComputationLHSType;
+  QualType ComputationResultType;
+public:
+  CompoundAssignOperator(Expr *lhs, Expr *rhs, Opcode opc,
+                         QualType ResType, QualType CompLHSType,
+                         QualType CompResultType,
+                         SourceLocation OpLoc)
+    : BinaryOperator(lhs, rhs, opc, ResType, OpLoc, true),
+      ComputationLHSType(CompLHSType),
+      ComputationResultType(CompResultType) {
+    assert(isCompoundAssignmentOp() &&
+           "Only should be used for compound assignments");
+  }
+
+  /// \brief Build an empty compound assignment operator expression.
+  explicit CompoundAssignOperator(EmptyShell Empty)
+    : BinaryOperator(CompoundAssignOperatorClass, Empty) { }
+
+  // The two computation types are the type the LHS is converted
+  // to for the computation and the type of the result; the two are
+  // distinct in a few cases (specifically, int+=ptr and ptr-=ptr).
+  QualType getComputationLHSType() const { return ComputationLHSType; }
+  void setComputationLHSType(QualType T) { ComputationLHSType = T; }
+
+  QualType getComputationResultType() const { return ComputationResultType; }
+  void setComputationResultType(QualType T) { ComputationResultType = T; }
+
+  static bool classof(const CompoundAssignOperator *) { return true; }
+  static bool classof(const Stmt *S) {
+    return S->getStmtClass() == CompoundAssignOperatorClass;
+  }
+};
+
+/// ConditionalOperator - The ?: operator.  Note that LHS may be null when the
+/// GNU "missing LHS" extension is in use.
+///
+class ConditionalOperator : public Expr {
+  enum { COND, LHS, RHS, END_EXPR };
+  Stmt* SubExprs[END_EXPR]; // Left/Middle/Right hand sides.
+  SourceLocation QuestionLoc, ColonLoc;
+public:
+  ConditionalOperator(Expr *cond, SourceLocation QLoc, Expr *lhs,
+                      SourceLocation CLoc, Expr *rhs, QualType t)
+    : Expr(ConditionalOperatorClass, t,
+           // FIXME: the type of the conditional operator doesn't
+           // depend on the type of the conditional, but the standard
+           // seems to imply that it could. File a bug!
+           ((lhs && lhs->isTypeDependent()) || (rhs && rhs->isTypeDependent())),
+           (cond->isValueDependent() ||
+            (lhs && lhs->isValueDependent()) ||
+            (rhs && rhs->isValueDependent()))),
+      QuestionLoc(QLoc),
+      ColonLoc(CLoc) {
+    SubExprs[COND] = cond;
+    SubExprs[LHS] = lhs;
+    SubExprs[RHS] = rhs;
+  }
+
+  /// \brief Build an empty conditional operator.
+  explicit ConditionalOperator(EmptyShell Empty)
+    : Expr(ConditionalOperatorClass, Empty) { }
+
+  // getCond - Return the expression representing the condition for
+  //  the ?: operator.
+  Expr *getCond() const { return cast<Expr>(SubExprs[COND]); }
+  void setCond(Expr *E) { SubExprs[COND] = E; }
+
+  // getTrueExpr - Return the subexpression representing the value of the ?:
+  //  expression if the condition evaluates to true.  In most cases this value
+  //  will be the same as getLHS() except a GCC extension allows the left
+  //  subexpression to be omitted, and instead of the condition be returned.
+  //  e.g: x ?: y is shorthand for x ? x : y, except that the expression "x"
+  //  is only evaluated once.
+  Expr *getTrueExpr() const {
+    return cast<Expr>(SubExprs[LHS] ? SubExprs[LHS] : SubExprs[COND]);
+  }
+
+  // getTrueExpr - Return the subexpression representing the value of the ?:
+  // expression if the condition evaluates to false. This is the same as getRHS.
+  Expr *getFalseExpr() const { return cast<Expr>(SubExprs[RHS]); }
+
+  Expr *getLHS() const { return cast_or_null<Expr>(SubExprs[LHS]); }
+  void setLHS(Expr *E) { SubExprs[LHS] = E; }
+
+  Expr *getRHS() const { return cast<Expr>(SubExprs[RHS]); }
+  void setRHS(Expr *E) { SubExprs[RHS] = E; }
+
+  SourceLocation getQuestionLoc() const { return QuestionLoc; }
+  void setQuestionLoc(SourceLocation L) { QuestionLoc = L; }
+
+  SourceLocation getColonLoc() const { return ColonLoc; }
+  void setColonLoc(SourceLocation L) { ColonLoc = L; }
+
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(getCond()->getLocStart(), getRHS()->getLocEnd());
+  }
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ConditionalOperatorClass;
+  }
+  static bool classof(const ConditionalOperator *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+/// AddrLabelExpr - The GNU address of label extension, representing &&label.
+class AddrLabelExpr : public Expr {
+  SourceLocation AmpAmpLoc, LabelLoc;
+  LabelStmt *Label;
+public:
+  AddrLabelExpr(SourceLocation AALoc, SourceLocation LLoc, LabelStmt *L,
+                QualType t)
+    : Expr(AddrLabelExprClass, t, false, false),
+      AmpAmpLoc(AALoc), LabelLoc(LLoc), Label(L) {}
+
+  /// \brief Build an empty address of a label expression.
+  explicit AddrLabelExpr(EmptyShell Empty)
+    : Expr(AddrLabelExprClass, Empty) { }
+
+  SourceLocation getAmpAmpLoc() const { return AmpAmpLoc; }
+  void setAmpAmpLoc(SourceLocation L) { AmpAmpLoc = L; }
+  SourceLocation getLabelLoc() const { return LabelLoc; }
+  void setLabelLoc(SourceLocation L) { LabelLoc = L; }
+
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(AmpAmpLoc, LabelLoc);
+  }
+
+  LabelStmt *getLabel() const { return Label; }
+  void setLabel(LabelStmt *S) { Label = S; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == AddrLabelExprClass;
+  }
+  static bool classof(const AddrLabelExpr *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+/// StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).
+/// The StmtExpr contains a single CompoundStmt node, which it evaluates and
+/// takes the value of the last subexpression.
+class StmtExpr : public Expr {
+  Stmt *SubStmt;
+  SourceLocation LParenLoc, RParenLoc;
+public:
+  // FIXME: Does type-dependence need to be computed differently?
+  StmtExpr(CompoundStmt *substmt, QualType T,
+           SourceLocation lp, SourceLocation rp) :
+    Expr(StmtExprClass, T, T->isDependentType(), false),
+    SubStmt(substmt), LParenLoc(lp), RParenLoc(rp) { }
+
+  /// \brief Build an empty statement expression.
+  explicit StmtExpr(EmptyShell Empty) : Expr(StmtExprClass, Empty) { }
+
+  CompoundStmt *getSubStmt() { return cast<CompoundStmt>(SubStmt); }
+  const CompoundStmt *getSubStmt() const { return cast<CompoundStmt>(SubStmt); }
+  void setSubStmt(CompoundStmt *S) { SubStmt = S; }
+
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(LParenLoc, RParenLoc);
+  }
+
+  SourceLocation getLParenLoc() const { return LParenLoc; }
+  void setLParenLoc(SourceLocation L) { LParenLoc = L; }
+  SourceLocation getRParenLoc() const { return RParenLoc; }
+  void setRParenLoc(SourceLocation L) { RParenLoc = L; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == StmtExprClass;
+  }
+  static bool classof(const StmtExpr *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+/// TypesCompatibleExpr - GNU builtin-in function __builtin_types_compatible_p.
+/// This AST node represents a function that returns 1 if two *types* (not
+/// expressions) are compatible. The result of this built-in function can be
+/// used in integer constant expressions.
+class TypesCompatibleExpr : public Expr {
+  QualType Type1;
+  QualType Type2;
+  SourceLocation BuiltinLoc, RParenLoc;
+public:
+  TypesCompatibleExpr(QualType ReturnType, SourceLocation BLoc,
+                      QualType t1, QualType t2, SourceLocation RP) :
+    Expr(TypesCompatibleExprClass, ReturnType, false, false),
+    Type1(t1), Type2(t2), BuiltinLoc(BLoc), RParenLoc(RP) {}
+
+  /// \brief Build an empty __builtin_type_compatible_p expression.
+  explicit TypesCompatibleExpr(EmptyShell Empty)
+    : Expr(TypesCompatibleExprClass, Empty) { }
+
+  QualType getArgType1() const { return Type1; }
+  void setArgType1(QualType T) { Type1 = T; }
+  QualType getArgType2() const { return Type2; }
+  void setArgType2(QualType T) { Type2 = T; }
+
+  SourceLocation getBuiltinLoc() const { return BuiltinLoc; }
+  void setBuiltinLoc(SourceLocation L) { BuiltinLoc = L; }
+
+  SourceLocation getRParenLoc() const { return RParenLoc; }
+  void setRParenLoc(SourceLocation L) { RParenLoc = L; }
+
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(BuiltinLoc, RParenLoc);
+  }
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == TypesCompatibleExprClass;
+  }
+  static bool classof(const TypesCompatibleExpr *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+/// ShuffleVectorExpr - clang-specific builtin-in function
+/// __builtin_shufflevector.
+/// This AST node represents a operator that does a constant
+/// shuffle, similar to LLVM's shufflevector instruction. It takes
+/// two vectors and a variable number of constant indices,
+/// and returns the appropriately shuffled vector.
+class ShuffleVectorExpr : public Expr {
+  SourceLocation BuiltinLoc, RParenLoc;
+
+  // SubExprs - the list of values passed to the __builtin_shufflevector
+  // function. The first two are vectors, and the rest are constant
+  // indices.  The number of values in this list is always
+  // 2+the number of indices in the vector type.
+  Stmt **SubExprs;
+  unsigned NumExprs;
+
+protected:
+  virtual void DoDestroy(ASTContext &C);
+
+public:
+  // FIXME: Can a shufflevector be value-dependent?  Does type-dependence need
+  // to be computed differently?
+  ShuffleVectorExpr(ASTContext &C, Expr **args, unsigned nexpr,
+                    QualType Type, SourceLocation BLoc,
+                    SourceLocation RP) :
+    Expr(ShuffleVectorExprClass, Type, Type->isDependentType(), false),
+    BuiltinLoc(BLoc), RParenLoc(RP), NumExprs(nexpr) {
+
+    SubExprs = new (C) Stmt*[nexpr];
+    for (unsigned i = 0; i < nexpr; i++)
+      SubExprs[i] = args[i];
+  }
+
+  /// \brief Build an empty vector-shuffle expression.
+  explicit ShuffleVectorExpr(EmptyShell Empty)
+    : Expr(ShuffleVectorExprClass, Empty), SubExprs(0) { }
+
+  SourceLocation getBuiltinLoc() const { return BuiltinLoc; }
+  void setBuiltinLoc(SourceLocation L) { BuiltinLoc = L; }
+
+  SourceLocation getRParenLoc() const { return RParenLoc; }
+  void setRParenLoc(SourceLocation L) { RParenLoc = L; }
+
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(BuiltinLoc, RParenLoc);
+  }
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ShuffleVectorExprClass;
+  }
+  static bool classof(const ShuffleVectorExpr *) { return true; }
+
+  ~ShuffleVectorExpr() {}
+
+  /// getNumSubExprs - Return the size of the SubExprs array.  This includes the
+  /// constant expression, the actual arguments passed in, and the function
+  /// pointers.
+  unsigned getNumSubExprs() const { return NumExprs; }
+
+  /// getExpr - Return the Expr at the specified index.
+  Expr *getExpr(unsigned Index) {
+    assert((Index < NumExprs) && "Arg access out of range!");
+    return cast<Expr>(SubExprs[Index]);
+  }
+  const Expr *getExpr(unsigned Index) const {
+    assert((Index < NumExprs) && "Arg access out of range!");
+    return cast<Expr>(SubExprs[Index]);
+  }
+
+  void setExprs(ASTContext &C, Expr ** Exprs, unsigned NumExprs);
+
+  unsigned getShuffleMaskIdx(ASTContext &Ctx, unsigned N) {
+    assert((N < NumExprs - 2) && "Shuffle idx out of range!");
+    return getExpr(N+2)->EvaluateAsInt(Ctx).getZExtValue();
+  }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+/// ChooseExpr - GNU builtin-in function __builtin_choose_expr.
+/// This AST node is similar to the conditional operator (?:) in C, with
+/// the following exceptions:
+/// - the test expression must be a integer constant expression.
+/// - the expression returned acts like the chosen subexpression in every
+///   visible way: the type is the same as that of the chosen subexpression,
+///   and all predicates (whether it's an l-value, whether it's an integer
+///   constant expression, etc.) return the same result as for the chosen
+///   sub-expression.
+class ChooseExpr : public Expr {
+  enum { COND, LHS, RHS, END_EXPR };
+  Stmt* SubExprs[END_EXPR]; // Left/Middle/Right hand sides.
+  SourceLocation BuiltinLoc, RParenLoc;
+public:
+  ChooseExpr(SourceLocation BLoc, Expr *cond, Expr *lhs, Expr *rhs, QualType t,
+             SourceLocation RP, bool TypeDependent, bool ValueDependent)
+    : Expr(ChooseExprClass, t, TypeDependent, ValueDependent),
+      BuiltinLoc(BLoc), RParenLoc(RP) {
+      SubExprs[COND] = cond;
+      SubExprs[LHS] = lhs;
+      SubExprs[RHS] = rhs;
+    }
+
+  /// \brief Build an empty __builtin_choose_expr.
+  explicit ChooseExpr(EmptyShell Empty) : Expr(ChooseExprClass, Empty) { }
+
+  /// isConditionTrue - Return whether the condition is true (i.e. not
+  /// equal to zero).
+  bool isConditionTrue(ASTContext &C) const;
+
+  /// getChosenSubExpr - Return the subexpression chosen according to the
+  /// condition.
+  Expr *getChosenSubExpr(ASTContext &C) const {
+    return isConditionTrue(C) ? getLHS() : getRHS();
+  }
+
+  Expr *getCond() const { return cast<Expr>(SubExprs[COND]); }
+  void setCond(Expr *E) { SubExprs[COND] = E; }
+  Expr *getLHS() const { return cast<Expr>(SubExprs[LHS]); }
+  void setLHS(Expr *E) { SubExprs[LHS] = E; }
+  Expr *getRHS() const { return cast<Expr>(SubExprs[RHS]); }
+  void setRHS(Expr *E) { SubExprs[RHS] = E; }
+
+  SourceLocation getBuiltinLoc() const { return BuiltinLoc; }
+  void setBuiltinLoc(SourceLocation L) { BuiltinLoc = L; }
+
+  SourceLocation getRParenLoc() const { return RParenLoc; }
+  void setRParenLoc(SourceLocation L) { RParenLoc = L; }
+
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(BuiltinLoc, RParenLoc);
+  }
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ChooseExprClass;
+  }
+  static bool classof(const ChooseExpr *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+/// GNUNullExpr - Implements the GNU __null extension, which is a name
+/// for a null pointer constant that has integral type (e.g., int or
+/// long) and is the same size and alignment as a pointer. The __null
+/// extension is typically only used by system headers, which define
+/// NULL as __null in C++ rather than using 0 (which is an integer
+/// that may not match the size of a pointer).
+class GNUNullExpr : public Expr {
+  /// TokenLoc - The location of the __null keyword.
+  SourceLocation TokenLoc;
+
+public:
+  GNUNullExpr(QualType Ty, SourceLocation Loc)
+    : Expr(GNUNullExprClass, Ty, false, false), TokenLoc(Loc) { }
+
+  /// \brief Build an empty GNU __null expression.
+  explicit GNUNullExpr(EmptyShell Empty) : Expr(GNUNullExprClass, Empty) { }
+
+  /// getTokenLocation - The location of the __null token.
+  SourceLocation getTokenLocation() const { return TokenLoc; }
+  void setTokenLocation(SourceLocation L) { TokenLoc = L; }
+
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(TokenLoc);
+  }
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == GNUNullExprClass;
+  }
+  static bool classof(const GNUNullExpr *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+/// VAArgExpr, used for the builtin function __builtin_va_arg.
+class VAArgExpr : public Expr {
+  Stmt *Val;
+  SourceLocation BuiltinLoc, RParenLoc;
+public:
+  VAArgExpr(SourceLocation BLoc, Expr* e, QualType t, SourceLocation RPLoc)
+    : Expr(VAArgExprClass, t, t->isDependentType(), false),
+      Val(e),
+      BuiltinLoc(BLoc),
+      RParenLoc(RPLoc) { }
+
+  /// \brief Create an empty __builtin_va_arg expression.
+  explicit VAArgExpr(EmptyShell Empty) : Expr(VAArgExprClass, Empty) { }
+
+  const Expr *getSubExpr() const { return cast<Expr>(Val); }
+  Expr *getSubExpr() { return cast<Expr>(Val); }
+  void setSubExpr(Expr *E) { Val = E; }
+
+  SourceLocation getBuiltinLoc() const { return BuiltinLoc; }
+  void setBuiltinLoc(SourceLocation L) { BuiltinLoc = L; }
+
+  SourceLocation getRParenLoc() const { return RParenLoc; }
+  void setRParenLoc(SourceLocation L) { RParenLoc = L; }
+
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(BuiltinLoc, RParenLoc);
+  }
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == VAArgExprClass;
+  }
+  static bool classof(const VAArgExpr *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+/// @brief Describes an C or C++ initializer list.
+///
+/// InitListExpr describes an initializer list, which can be used to
+/// initialize objects of different types, including
+/// struct/class/union types, arrays, and vectors. For example:
+///
+/// @code
+/// struct foo x = { 1, { 2, 3 } };
+/// @endcode
+///
+/// Prior to semantic analysis, an initializer list will represent the
+/// initializer list as written by the user, but will have the
+/// placeholder type "void". This initializer list is called the
+/// syntactic form of the initializer, and may contain C99 designated
+/// initializers (represented as DesignatedInitExprs), initializations
+/// of subobject members without explicit braces, and so on. Clients
+/// interested in the original syntax of the initializer list should
+/// use the syntactic form of the initializer list.
+///
+/// After semantic analysis, the initializer list will represent the
+/// semantic form of the initializer, where the initializations of all
+/// subobjects are made explicit with nested InitListExpr nodes and
+/// C99 designators have been eliminated by placing the designated
+/// initializations into the subobject they initialize. Additionally,
+/// any "holes" in the initialization, where no initializer has been
+/// specified for a particular subobject, will be replaced with
+/// implicitly-generated ImplicitValueInitExpr expressions that
+/// value-initialize the subobjects. Note, however, that the
+/// initializer lists may still have fewer initializers than there are
+/// elements to initialize within the object.
+///
+/// Given the semantic form of the initializer list, one can retrieve
+/// the original syntactic form of that initializer list (if it
+/// exists) using getSyntacticForm(). Since many initializer lists
+/// have the same syntactic and semantic forms, getSyntacticForm() may
+/// return NULL, indicating that the current initializer list also
+/// serves as its syntactic form.
+class InitListExpr : public Expr {
+  // FIXME: Eliminate this vector in favor of ASTContext allocation
+  typedef ASTVector<Stmt *> InitExprsTy;
+  InitExprsTy InitExprs;
+  SourceLocation LBraceLoc, RBraceLoc;
+
+  /// Contains the initializer list that describes the syntactic form
+  /// written in the source code.
+  InitListExpr *SyntacticForm;
+
+  /// If this initializer list initializes a union, specifies which
+  /// field within the union will be initialized.
+  FieldDecl *UnionFieldInit;
+
+  /// Whether this initializer list originally had a GNU array-range
+  /// designator in it. This is a temporary marker used by CodeGen.
+  bool HadArrayRangeDesignator;
+
+public:
+  InitListExpr(ASTContext &C, SourceLocation lbraceloc,
+               Expr **initexprs, unsigned numinits,
+               SourceLocation rbraceloc);
+
+  /// \brief Build an empty initializer list.
+  explicit InitListExpr(ASTContext &C, EmptyShell Empty)
+    : Expr(InitListExprClass, Empty), InitExprs(C) { }
+
+  unsigned getNumInits() const { return InitExprs.size(); }
+
+  const Expr* getInit(unsigned Init) const {
+    assert(Init < getNumInits() && "Initializer access out of range!");
+    return cast_or_null<Expr>(InitExprs[Init]);
+  }
+
+  Expr* getInit(unsigned Init) {
+    assert(Init < getNumInits() && "Initializer access out of range!");
+    return cast_or_null<Expr>(InitExprs[Init]);
+  }
+
+  void setInit(unsigned Init, Expr *expr) {
+    assert(Init < getNumInits() && "Initializer access out of range!");
+    InitExprs[Init] = expr;
+  }
+
+  /// \brief Reserve space for some number of initializers.
+  void reserveInits(ASTContext &C, unsigned NumInits);
+
+  /// @brief Specify the number of initializers
+  ///
+  /// If there are more than @p NumInits initializers, the remaining
+  /// initializers will be destroyed. If there are fewer than @p
+  /// NumInits initializers, NULL expressions will be added for the
+  /// unknown initializers.
+  void resizeInits(ASTContext &Context, unsigned NumInits);
+
+  /// @brief Updates the initializer at index @p Init with the new
+  /// expression @p expr, and returns the old expression at that
+  /// location.
+  ///
+  /// When @p Init is out of range for this initializer list, the
+  /// initializer list will be extended with NULL expressions to
+  /// accomodate the new entry.
+  Expr *updateInit(ASTContext &C, unsigned Init, Expr *expr);
+
+  /// \brief If this initializes a union, specifies which field in the
+  /// union to initialize.
+  ///
+  /// Typically, this field is the first named field within the
+  /// union. However, a designated initializer can specify the
+  /// initialization of a different field within the union.
+  FieldDecl *getInitializedFieldInUnion() { return UnionFieldInit; }
+  void setInitializedFieldInUnion(FieldDecl *FD) { UnionFieldInit = FD; }
+
+  // Explicit InitListExpr's originate from source code (and have valid source
+  // locations). Implicit InitListExpr's are created by the semantic analyzer.
+  bool isExplicit() {
+    return LBraceLoc.isValid() && RBraceLoc.isValid();
+  }
+
+  SourceLocation getLBraceLoc() const { return LBraceLoc; }
+  void setLBraceLoc(SourceLocation Loc) { LBraceLoc = Loc; }
+  SourceLocation getRBraceLoc() const { return RBraceLoc; }
+  void setRBraceLoc(SourceLocation Loc) { RBraceLoc = Loc; }
+
+  /// @brief Retrieve the initializer list that describes the
+  /// syntactic form of the initializer.
+  ///
+  ///
+  InitListExpr *getSyntacticForm() const { return SyntacticForm; }
+  void setSyntacticForm(InitListExpr *Init) { SyntacticForm = Init; }
+
+  bool hadArrayRangeDesignator() const { return HadArrayRangeDesignator; }
+  void sawArrayRangeDesignator(bool ARD = true) {
+    HadArrayRangeDesignator = ARD;
+  }
+
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(LBraceLoc, RBraceLoc);
+  }
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == InitListExprClass;
+  }
+  static bool classof(const InitListExpr *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+
+  typedef InitExprsTy::iterator iterator;
+  typedef InitExprsTy::reverse_iterator reverse_iterator;
+
+  iterator begin() { return InitExprs.begin(); }
+  iterator end() { return InitExprs.end(); }
+  reverse_iterator rbegin() { return InitExprs.rbegin(); }
+  reverse_iterator rend() { return InitExprs.rend(); }
+};
+
+/// @brief Represents a C99 designated initializer expression.
+///
+/// A designated initializer expression (C99 6.7.8) contains one or
+/// more designators (which can be field designators, array
+/// designators, or GNU array-range designators) followed by an
+/// expression that initializes the field or element(s) that the
+/// designators refer to. For example, given:
+///
+/// @code
+/// struct point {
+///   double x;
+///   double y;
+/// };
+/// struct point ptarray[10] = { [2].y = 1.0, [2].x = 2.0, [0].x = 1.0 };
+/// @endcode
+///
+/// The InitListExpr contains three DesignatedInitExprs, the first of
+/// which covers @c [2].y=1.0. This DesignatedInitExpr will have two
+/// designators, one array designator for @c [2] followed by one field
+/// designator for @c .y. The initalization expression will be 1.0.
+class DesignatedInitExpr : public Expr {
+public:
+  /// \brief Forward declaration of the Designator class.
+  class Designator;
+
+private:
+  /// The location of the '=' or ':' prior to the actual initializer
+  /// expression.
+  SourceLocation EqualOrColonLoc;
+
+  /// Whether this designated initializer used the GNU deprecated
+  /// syntax rather than the C99 '=' syntax.
+  bool GNUSyntax : 1;
+
+  /// The number of designators in this initializer expression.
+  unsigned NumDesignators : 15;
+
+  /// \brief The designators in this designated initialization
+  /// expression.
+  Designator *Designators;
+
+  /// The number of subexpressions of this initializer expression,
+  /// which contains both the initializer and any additional
+  /// expressions used by array and array-range designators.
+  unsigned NumSubExprs : 16;
+
+
+  DesignatedInitExpr(ASTContext &C, QualType Ty, unsigned NumDesignators,
+                     const Designator *Designators,
+                     SourceLocation EqualOrColonLoc, bool GNUSyntax,
+                     Expr **IndexExprs, unsigned NumIndexExprs,
+                     Expr *Init);
+
+  explicit DesignatedInitExpr(unsigned NumSubExprs)
+    : Expr(DesignatedInitExprClass, EmptyShell()),
+      NumDesignators(0), Designators(0), NumSubExprs(NumSubExprs) { }
+
+protected:
+  virtual void DoDestroy(ASTContext &C);
+
+  void DestroyDesignators(ASTContext &C);
+  
+public:
+  /// A field designator, e.g., ".x".
+  struct FieldDesignator {
+    /// Refers to the field that is being initialized. The low bit
+    /// of this field determines whether this is actually a pointer
+    /// to an IdentifierInfo (if 1) or a FieldDecl (if 0). When
+    /// initially constructed, a field designator will store an
+    /// IdentifierInfo*. After semantic analysis has resolved that
+    /// name, the field designator will instead store a FieldDecl*.
+    uintptr_t NameOrField;
+
+    /// The location of the '.' in the designated initializer.
+    unsigned DotLoc;
+
+    /// The location of the field name in the designated initializer.
+    unsigned FieldLoc;
+  };
+
+  /// An array or GNU array-range designator, e.g., "[9]" or "[10..15]".
+  struct ArrayOrRangeDesignator {
+    /// Location of the first index expression within the designated
+    /// initializer expression's list of subexpressions.
+    unsigned Index;
+    /// The location of the '[' starting the array range designator.
+    unsigned LBracketLoc;
+    /// The location of the ellipsis separating the start and end
+    /// indices. Only valid for GNU array-range designators.
+    unsigned EllipsisLoc;
+    /// The location of the ']' terminating the array range designator.
+    unsigned RBracketLoc;
+  };
+
+  /// @brief Represents a single C99 designator.
+  ///
+  /// @todo This class is infuriatingly similar to clang::Designator,
+  /// but minor differences (storing indices vs. storing pointers)
+  /// keep us from reusing it. Try harder, later, to rectify these
+  /// differences.
+  class Designator {
+    /// @brief The kind of designator this describes.
+    enum {
+      FieldDesignator,
+      ArrayDesignator,
+      ArrayRangeDesignator
+    } Kind;
+
+    union {
+      /// A field designator, e.g., ".x".
+      struct FieldDesignator Field;
+      /// An array or GNU array-range designator, e.g., "[9]" or "[10..15]".
+      struct ArrayOrRangeDesignator ArrayOrRange;
+    };
+    friend class DesignatedInitExpr;
+
+  public:
+    Designator() {}
+
+    /// @brief Initializes a field designator.
+    Designator(const IdentifierInfo *FieldName, SourceLocation DotLoc,
+               SourceLocation FieldLoc)
+      : Kind(FieldDesignator) {
+      Field.NameOrField = reinterpret_cast<uintptr_t>(FieldName) | 0x01;
+      Field.DotLoc = DotLoc.getRawEncoding();
+      Field.FieldLoc = FieldLoc.getRawEncoding();
+    }
+
+    /// @brief Initializes an array designator.
+    Designator(unsigned Index, SourceLocation LBracketLoc,
+               SourceLocation RBracketLoc)
+      : Kind(ArrayDesignator) {
+      ArrayOrRange.Index = Index;
+      ArrayOrRange.LBracketLoc = LBracketLoc.getRawEncoding();
+      ArrayOrRange.EllipsisLoc = SourceLocation().getRawEncoding();
+      ArrayOrRange.RBracketLoc = RBracketLoc.getRawEncoding();
+    }
+
+    /// @brief Initializes a GNU array-range designator.
+    Designator(unsigned Index, SourceLocation LBracketLoc,
+               SourceLocation EllipsisLoc, SourceLocation RBracketLoc)
+      : Kind(ArrayRangeDesignator) {
+      ArrayOrRange.Index = Index;
+      ArrayOrRange.LBracketLoc = LBracketLoc.getRawEncoding();
+      ArrayOrRange.EllipsisLoc = EllipsisLoc.getRawEncoding();
+      ArrayOrRange.RBracketLoc = RBracketLoc.getRawEncoding();
+    }
+
+    bool isFieldDesignator() const { return Kind == FieldDesignator; }
+    bool isArrayDesignator() const { return Kind == ArrayDesignator; }
+    bool isArrayRangeDesignator() const { return Kind == ArrayRangeDesignator; }
+
+    IdentifierInfo * getFieldName();
+
+    FieldDecl *getField() {
+      assert(Kind == FieldDesignator && "Only valid on a field designator");
+      if (Field.NameOrField & 0x01)
+        return 0;
+      else
+        return reinterpret_cast<FieldDecl *>(Field.NameOrField);
+    }
+
+    void setField(FieldDecl *FD) {
+      assert(Kind == FieldDesignator && "Only valid on a field designator");
+      Field.NameOrField = reinterpret_cast<uintptr_t>(FD);
+    }
+
+    SourceLocation getDotLoc() const {
+      assert(Kind == FieldDesignator && "Only valid on a field designator");
+      return SourceLocation::getFromRawEncoding(Field.DotLoc);
+    }
+
+    SourceLocation getFieldLoc() const {
+      assert(Kind == FieldDesignator && "Only valid on a field designator");
+      return SourceLocation::getFromRawEncoding(Field.FieldLoc);
+    }
+
+    SourceLocation getLBracketLoc() const {
+      assert((Kind == ArrayDesignator || Kind == ArrayRangeDesignator) &&
+             "Only valid on an array or array-range designator");
+      return SourceLocation::getFromRawEncoding(ArrayOrRange.LBracketLoc);
+    }
+
+    SourceLocation getRBracketLoc() const {
+      assert((Kind == ArrayDesignator || Kind == ArrayRangeDesignator) &&
+             "Only valid on an array or array-range designator");
+      return SourceLocation::getFromRawEncoding(ArrayOrRange.RBracketLoc);
+    }
+
+    SourceLocation getEllipsisLoc() const {
+      assert(Kind == ArrayRangeDesignator &&
+             "Only valid on an array-range designator");
+      return SourceLocation::getFromRawEncoding(ArrayOrRange.EllipsisLoc);
+    }
+
+    unsigned getFirstExprIndex() const {
+      assert((Kind == ArrayDesignator || Kind == ArrayRangeDesignator) &&
+             "Only valid on an array or array-range designator");
+      return ArrayOrRange.Index;
+    }
+
+    SourceLocation getStartLocation() const {
+      if (Kind == FieldDesignator)
+        return getDotLoc().isInvalid()? getFieldLoc() : getDotLoc();
+      else
+        return getLBracketLoc();
+    }
+  };
+
+  static DesignatedInitExpr *Create(ASTContext &C, Designator *Designators,
+                                    unsigned NumDesignators,
+                                    Expr **IndexExprs, unsigned NumIndexExprs,
+                                    SourceLocation EqualOrColonLoc,
+                                    bool GNUSyntax, Expr *Init);
+
+  static DesignatedInitExpr *CreateEmpty(ASTContext &C, unsigned NumIndexExprs);
+
+  /// @brief Returns the number of designators in this initializer.
+  unsigned size() const { return NumDesignators; }
+
+  // Iterator access to the designators.
+  typedef Designator* designators_iterator;
+  designators_iterator designators_begin() { return Designators; }
+  designators_iterator designators_end() {
+    return Designators + NumDesignators;
+  }
+
+  Designator *getDesignator(unsigned Idx) { return &designators_begin()[Idx]; }
+
+  void setDesignators(ASTContext &C, const Designator *Desigs, 
+                      unsigned NumDesigs);
+
+  Expr *getArrayIndex(const Designator& D);
+  Expr *getArrayRangeStart(const Designator& D);
+  Expr *getArrayRangeEnd(const Designator& D);
+
+  /// @brief Retrieve the location of the '=' that precedes the
+  /// initializer value itself, if present.
+  SourceLocation getEqualOrColonLoc() const { return EqualOrColonLoc; }
+  void setEqualOrColonLoc(SourceLocation L) { EqualOrColonLoc = L; }
+
+  /// @brief Determines whether this designated initializer used the
+  /// deprecated GNU syntax for designated initializers.
+  bool usesGNUSyntax() const { return GNUSyntax; }
+  void setGNUSyntax(bool GNU) { GNUSyntax = GNU; }
+
+  /// @brief Retrieve the initializer value.
+  Expr *getInit() const {
+    return cast<Expr>(*const_cast<DesignatedInitExpr*>(this)->child_begin());
+  }
+
+  void setInit(Expr *init) {
+    *child_begin() = init;
+  }
+
+  /// \brief Retrieve the total number of subexpressions in this
+  /// designated initializer expression, including the actual
+  /// initialized value and any expressions that occur within array
+  /// and array-range designators.
+  unsigned getNumSubExprs() const { return NumSubExprs; }
+
+  Expr *getSubExpr(unsigned Idx) {
+    assert(Idx < NumSubExprs && "Subscript out of range");
+    char* Ptr = static_cast<char*>(static_cast<void *>(this));
+    Ptr += sizeof(DesignatedInitExpr);
+    return reinterpret_cast<Expr**>(reinterpret_cast<void**>(Ptr))[Idx];
+  }
+
+  void setSubExpr(unsigned Idx, Expr *E) {
+    assert(Idx < NumSubExprs && "Subscript out of range");
+    char* Ptr = static_cast<char*>(static_cast<void *>(this));
+    Ptr += sizeof(DesignatedInitExpr);
+    reinterpret_cast<Expr**>(reinterpret_cast<void**>(Ptr))[Idx] = E;
+  }
+
+  /// \brief Replaces the designator at index @p Idx with the series
+  /// of designators in [First, Last).
+  void ExpandDesignator(ASTContext &C, unsigned Idx, const Designator *First,
+                        const Designator *Last);
+
+  virtual SourceRange getSourceRange() const;
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == DesignatedInitExprClass;
+  }
+  static bool classof(const DesignatedInitExpr *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+/// \brief Represents an implicitly-generated value initialization of
+/// an object of a given type.
+///
+/// Implicit value initializations occur within semantic initializer
+/// list expressions (InitListExpr) as placeholders for subobject
+/// initializations not explicitly specified by the user.
+///
+/// \see InitListExpr
+class ImplicitValueInitExpr : public Expr {
+public:
+  explicit ImplicitValueInitExpr(QualType ty)
+    : Expr(ImplicitValueInitExprClass, ty, false, false) { }
+
+  /// \brief Construct an empty implicit value initialization.
+  explicit ImplicitValueInitExpr(EmptyShell Empty)
+    : Expr(ImplicitValueInitExprClass, Empty) { }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ImplicitValueInitExprClass;
+  }
+  static bool classof(const ImplicitValueInitExpr *) { return true; }
+
+  virtual SourceRange getSourceRange() const {
+    return SourceRange();
+  }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+
+class ParenListExpr : public Expr {
+  Stmt **Exprs;
+  unsigned NumExprs;
+  SourceLocation LParenLoc, RParenLoc;
+
+protected:
+  virtual void DoDestroy(ASTContext& C);
+
+public:
+  ParenListExpr(ASTContext& C, SourceLocation lparenloc, Expr **exprs,
+                unsigned numexprs, SourceLocation rparenloc);
+
+  ~ParenListExpr() {}
+
+  /// \brief Build an empty paren list.
+  //explicit ParenListExpr(EmptyShell Empty) : Expr(ParenListExprClass, Empty) { }
+
+  unsigned getNumExprs() const { return NumExprs; }
+
+  const Expr* getExpr(unsigned Init) const {
+    assert(Init < getNumExprs() && "Initializer access out of range!");
+    return cast_or_null<Expr>(Exprs[Init]);
+  }
+
+  Expr* getExpr(unsigned Init) {
+    assert(Init < getNumExprs() && "Initializer access out of range!");
+    return cast_or_null<Expr>(Exprs[Init]);
+  }
+
+  Expr **getExprs() { return reinterpret_cast<Expr **>(Exprs); }
+
+  SourceLocation getLParenLoc() const { return LParenLoc; }
+  SourceLocation getRParenLoc() const { return RParenLoc; }
+
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(LParenLoc, RParenLoc);
+  }
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ParenListExprClass;
+  }
+  static bool classof(const ParenListExpr *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+
+//===----------------------------------------------------------------------===//
+// Clang Extensions
+//===----------------------------------------------------------------------===//
+
+
+/// ExtVectorElementExpr - This represents access to specific elements of a
+/// vector, and may occur on the left hand side or right hand side.  For example
+/// the following is legal:  "V.xy = V.zw" if V is a 4 element extended vector.
+///
+/// Note that the base may have either vector or pointer to vector type, just
+/// like a struct field reference.
+///
+class ExtVectorElementExpr : public Expr {
+  Stmt *Base;
+  IdentifierInfo *Accessor;
+  SourceLocation AccessorLoc;
+public:
+  ExtVectorElementExpr(QualType ty, Expr *base, IdentifierInfo &accessor,
+                       SourceLocation loc)
+    : Expr(ExtVectorElementExprClass, ty, base->isTypeDependent(),
+           base->isValueDependent()),
+      Base(base), Accessor(&accessor), AccessorLoc(loc) {}
+
+  /// \brief Build an empty vector element expression.
+  explicit ExtVectorElementExpr(EmptyShell Empty)
+    : Expr(ExtVectorElementExprClass, Empty) { }
+
+  const Expr *getBase() const { return cast<Expr>(Base); }
+  Expr *getBase() { return cast<Expr>(Base); }
+  void setBase(Expr *E) { Base = E; }
+
+  IdentifierInfo &getAccessor() const { return *Accessor; }
+  void setAccessor(IdentifierInfo *II) { Accessor = II; }
+
+  SourceLocation getAccessorLoc() const { return AccessorLoc; }
+  void setAccessorLoc(SourceLocation L) { AccessorLoc = L; }
+
+  /// getNumElements - Get the number of components being selected.
+  unsigned getNumElements() const;
+
+  /// containsDuplicateElements - Return true if any element access is
+  /// repeated.
+  bool containsDuplicateElements() const;
+
+  /// getEncodedElementAccess - Encode the elements accessed into an llvm
+  /// aggregate Constant of ConstantInt(s).
+  void getEncodedElementAccess(llvm::SmallVectorImpl<unsigned> &Elts) const;
+
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(getBase()->getLocStart(), AccessorLoc);
+  }
+
+  /// isArrow - Return true if the base expression is a pointer to vector,
+  /// return false if the base expression is a vector.
+  bool isArrow() const;
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ExtVectorElementExprClass;
+  }
+  static bool classof(const ExtVectorElementExpr *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+
+/// BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
+/// ^{ statement-body }   or   ^(int arg1, float arg2){ statement-body }
+class BlockExpr : public Expr {
+protected:
+  BlockDecl *TheBlock;
+  bool HasBlockDeclRefExprs;
+public:
+  BlockExpr(BlockDecl *BD, QualType ty, bool hasBlockDeclRefExprs)
+    : Expr(BlockExprClass, ty, ty->isDependentType(), false),
+      TheBlock(BD), HasBlockDeclRefExprs(hasBlockDeclRefExprs) {}
+
+  /// \brief Build an empty block expression.
+  explicit BlockExpr(EmptyShell Empty) : Expr(BlockExprClass, Empty) { }
+
+  const BlockDecl *getBlockDecl() const { return TheBlock; }
+  BlockDecl *getBlockDecl() { return TheBlock; }
+  void setBlockDecl(BlockDecl *BD) { TheBlock = BD; }
+
+  // Convenience functions for probing the underlying BlockDecl.
+  SourceLocation getCaretLocation() const;
+  const Stmt *getBody() const;
+  Stmt *getBody();
+
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(getCaretLocation(), getBody()->getLocEnd());
+  }
+
+  /// getFunctionType - Return the underlying function type for this block.
+  const FunctionType *getFunctionType() const;
+
+  /// hasBlockDeclRefExprs - Return true iff the block has BlockDeclRefExpr
+  /// inside of the block that reference values outside the block.
+  bool hasBlockDeclRefExprs() const { return HasBlockDeclRefExprs; }
+  void setHasBlockDeclRefExprs(bool BDRE) { HasBlockDeclRefExprs = BDRE; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == BlockExprClass;
+  }
+  static bool classof(const BlockExpr *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+/// BlockDeclRefExpr - A reference to a declared variable, function,
+/// enum, etc.
+class BlockDeclRefExpr : public Expr {
+  ValueDecl *D;
+  SourceLocation Loc;
+  bool IsByRef : 1;
+  bool ConstQualAdded : 1;
+public:
+  // FIXME: Fix type/value dependence!
+  BlockDeclRefExpr(ValueDecl *d, QualType t, SourceLocation l, bool ByRef,
+                   bool constAdded = false)
+  : Expr(BlockDeclRefExprClass, t, false, false), D(d), Loc(l), IsByRef(ByRef),
+    ConstQualAdded(constAdded) {}
+
+  // \brief Build an empty reference to a declared variable in a
+  // block.
+  explicit BlockDeclRefExpr(EmptyShell Empty)
+    : Expr(BlockDeclRefExprClass, Empty) { }
+
+  ValueDecl *getDecl() { return D; }
+  const ValueDecl *getDecl() const { return D; }
+  void setDecl(ValueDecl *VD) { D = VD; }
+
+  SourceLocation getLocation() const { return Loc; }
+  void setLocation(SourceLocation L) { Loc = L; }
+
+  virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
+
+  bool isByRef() const { return IsByRef; }
+  void setByRef(bool BR) { IsByRef = BR; }
+
+  bool isConstQualAdded() const { return ConstQualAdded; }
+  void setConstQualAdded(bool C) { ConstQualAdded = C; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == BlockDeclRefExprClass;
+  }
+  static bool classof(const BlockDeclRefExpr *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
new file mode 100644
index 0000000..d66642c
--- /dev/null
+++ b/include/clang/AST/ExprCXX.h
@@ -0,0 +1,2150 @@
+//===--- ExprCXX.h - Classes for representing expressions -------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the Expr interface and subclasses for C++ expressions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_EXPRCXX_H
+#define LLVM_CLANG_AST_EXPRCXX_H
+
+#include "clang/Basic/TypeTraits.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/UnresolvedSet.h"
+#include "clang/AST/TemplateBase.h"
+
+namespace clang {
+
+  class CXXConstructorDecl;
+  class CXXDestructorDecl;
+  class CXXMethodDecl;
+  class CXXTemporary;
+  class TemplateArgumentListInfo;
+
+//===--------------------------------------------------------------------===//
+// C++ Expressions.
+//===--------------------------------------------------------------------===//
+
+/// \brief A call to an overloaded operator written using operator
+/// syntax.
+///
+/// Represents a call to an overloaded operator written using operator
+/// syntax, e.g., "x + y" or "*p". While semantically equivalent to a
+/// normal call, this AST node provides better information about the
+/// syntactic representation of the call.
+///
+/// In a C++ template, this expression node kind will be used whenever
+/// any of the arguments are type-dependent. In this case, the
+/// function itself will be a (possibly empty) set of functions and
+/// function templates that were found by name lookup at template
+/// definition time.
+class CXXOperatorCallExpr : public CallExpr {
+  /// \brief The overloaded operator.
+  OverloadedOperatorKind Operator;
+
+public:
+  CXXOperatorCallExpr(ASTContext& C, OverloadedOperatorKind Op, Expr *fn,
+                      Expr **args, unsigned numargs, QualType t,
+                      SourceLocation operatorloc)
+    : CallExpr(C, CXXOperatorCallExprClass, fn, args, numargs, t, operatorloc),
+      Operator(Op) {}
+  explicit CXXOperatorCallExpr(ASTContext& C, EmptyShell Empty) :
+    CallExpr(C, CXXOperatorCallExprClass, Empty) { }
+
+
+  /// getOperator - Returns the kind of overloaded operator that this
+  /// expression refers to.
+  OverloadedOperatorKind getOperator() const { return Operator; }
+  void setOperator(OverloadedOperatorKind Kind) { Operator = Kind; }
+
+  /// getOperatorLoc - Returns the location of the operator symbol in
+  /// the expression. When @c getOperator()==OO_Call, this is the
+  /// location of the right parentheses; when @c
+  /// getOperator()==OO_Subscript, this is the location of the right
+  /// bracket.
+  SourceLocation getOperatorLoc() const { return getRParenLoc(); }
+
+  virtual SourceRange getSourceRange() const;
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CXXOperatorCallExprClass;
+  }
+  static bool classof(const CXXOperatorCallExpr *) { return true; }
+};
+
+/// CXXMemberCallExpr - Represents a call to a member function that
+/// may be written either with member call syntax (e.g., "obj.func()"
+/// or "objptr->func()") or with normal function-call syntax
+/// ("func()") within a member function that ends up calling a member
+/// function. The callee in either case is a MemberExpr that contains
+/// both the object argument and the member function, while the
+/// arguments are the arguments within the parentheses (not including
+/// the object argument).
+class CXXMemberCallExpr : public CallExpr {
+public:
+  CXXMemberCallExpr(ASTContext& C, Expr *fn, Expr **args, unsigned numargs,
+                    QualType t, SourceLocation rparenloc)
+    : CallExpr(C, CXXMemberCallExprClass, fn, args, numargs, t, rparenloc) {}
+
+  /// getImplicitObjectArgument - Retrieves the implicit object
+  /// argument for the member call. For example, in "x.f(5)", this
+  /// operation would return "x".
+  Expr *getImplicitObjectArgument();
+
+  virtual SourceRange getSourceRange() const;
+  
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CXXMemberCallExprClass;
+  }
+  static bool classof(const CXXMemberCallExpr *) { return true; }
+};
+
+/// CXXNamedCastExpr - Abstract class common to all of the C++ "named"
+/// casts, @c static_cast, @c dynamic_cast, @c reinterpret_cast, or @c
+/// const_cast.
+///
+/// This abstract class is inherited by all of the classes
+/// representing "named" casts, e.g., CXXStaticCastExpr,
+/// CXXDynamicCastExpr, CXXReinterpretCastExpr, and CXXConstCastExpr.
+class CXXNamedCastExpr : public ExplicitCastExpr {
+private:
+  SourceLocation Loc; // the location of the casting op
+
+protected:
+  CXXNamedCastExpr(StmtClass SC, QualType ty, CastKind kind, Expr *op,
+                   CXXBaseSpecifierArray BasePath, TypeSourceInfo *writtenTy,
+                   SourceLocation l)
+    : ExplicitCastExpr(SC, ty, kind, op, BasePath, writtenTy), Loc(l) {}
+
+  explicit CXXNamedCastExpr(StmtClass SC, EmptyShell Shell)
+    : ExplicitCastExpr(SC, Shell) { }
+
+public:
+  const char *getCastName() const;
+
+  /// \brief Retrieve the location of the cast operator keyword, e.g.,
+  /// "static_cast".
+  SourceLocation getOperatorLoc() const { return Loc; }
+  void setOperatorLoc(SourceLocation L) { Loc = L; }
+
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(Loc, getSubExpr()->getSourceRange().getEnd());
+  }
+  static bool classof(const Stmt *T) {
+    switch (T->getStmtClass()) {
+    case CXXStaticCastExprClass:
+    case CXXDynamicCastExprClass:
+    case CXXReinterpretCastExprClass:
+    case CXXConstCastExprClass:
+      return true;
+    default:
+      return false;
+    }
+  }
+  static bool classof(const CXXNamedCastExpr *) { return true; }
+};
+
+/// CXXStaticCastExpr - A C++ @c static_cast expression (C++ [expr.static.cast]).
+///
+/// This expression node represents a C++ static cast, e.g.,
+/// @c static_cast<int>(1.0).
+class CXXStaticCastExpr : public CXXNamedCastExpr {
+public:
+  CXXStaticCastExpr(QualType ty, CastKind kind, Expr *op, 
+                    CXXBaseSpecifierArray BasePath, TypeSourceInfo *writtenTy,
+                    SourceLocation l)
+    : CXXNamedCastExpr(CXXStaticCastExprClass, ty, kind, op, BasePath, writtenTy, l) {}
+
+  explicit CXXStaticCastExpr(EmptyShell Empty)
+    : CXXNamedCastExpr(CXXStaticCastExprClass, Empty) { }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CXXStaticCastExprClass;
+  }
+  static bool classof(const CXXStaticCastExpr *) { return true; }
+};
+
+/// CXXDynamicCastExpr - A C++ @c dynamic_cast expression
+/// (C++ [expr.dynamic.cast]), which may perform a run-time check to
+/// determine how to perform the type cast.
+///
+/// This expression node represents a dynamic cast, e.g.,
+/// @c dynamic_cast<Derived*>(BasePtr).
+class CXXDynamicCastExpr : public CXXNamedCastExpr {
+public:
+  CXXDynamicCastExpr(QualType ty, CastKind kind, Expr *op, 
+                     CXXBaseSpecifierArray BasePath, TypeSourceInfo *writtenTy,
+                     SourceLocation l)
+    : CXXNamedCastExpr(CXXDynamicCastExprClass, ty, kind, op, BasePath,
+                       writtenTy, l) {}
+
+  explicit CXXDynamicCastExpr(EmptyShell Empty)
+    : CXXNamedCastExpr(CXXDynamicCastExprClass, Empty) { }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CXXDynamicCastExprClass;
+  }
+  static bool classof(const CXXDynamicCastExpr *) { return true; }
+};
+
+/// CXXReinterpretCastExpr - A C++ @c reinterpret_cast expression (C++
+/// [expr.reinterpret.cast]), which provides a differently-typed view
+/// of a value but performs no actual work at run time.
+///
+/// This expression node represents a reinterpret cast, e.g.,
+/// @c reinterpret_cast<int>(VoidPtr).
+class CXXReinterpretCastExpr : public CXXNamedCastExpr {
+public:
+  CXXReinterpretCastExpr(QualType ty, CastKind kind, Expr *op, 
+                         CXXBaseSpecifierArray BasePath,
+                         TypeSourceInfo *writtenTy, SourceLocation l)
+    : CXXNamedCastExpr(CXXReinterpretCastExprClass, ty, kind, op, BasePath,
+                       writtenTy, l) {}
+
+  explicit CXXReinterpretCastExpr(EmptyShell Empty)
+    : CXXNamedCastExpr(CXXReinterpretCastExprClass, Empty) { }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CXXReinterpretCastExprClass;
+  }
+  static bool classof(const CXXReinterpretCastExpr *) { return true; }
+};
+
+/// CXXConstCastExpr - A C++ @c const_cast expression (C++ [expr.const.cast]),
+/// which can remove type qualifiers but does not change the underlying value.
+///
+/// This expression node represents a const cast, e.g.,
+/// @c const_cast<char*>(PtrToConstChar).
+class CXXConstCastExpr : public CXXNamedCastExpr {
+public:
+  CXXConstCastExpr(QualType ty, Expr *op, TypeSourceInfo *writtenTy,
+                   SourceLocation l)
+    : CXXNamedCastExpr(CXXConstCastExprClass, ty, CK_NoOp, op, 
+                       CXXBaseSpecifierArray(), writtenTy, l) {}
+
+  explicit CXXConstCastExpr(EmptyShell Empty)
+    : CXXNamedCastExpr(CXXConstCastExprClass, Empty) { }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CXXConstCastExprClass;
+  }
+  static bool classof(const CXXConstCastExpr *) { return true; }
+};
+
+/// CXXBoolLiteralExpr - [C++ 2.13.5] C++ Boolean Literal.
+///
+class CXXBoolLiteralExpr : public Expr {
+  bool Value;
+  SourceLocation Loc;
+public:
+  CXXBoolLiteralExpr(bool val, QualType Ty, SourceLocation l) :
+    Expr(CXXBoolLiteralExprClass, Ty, false, false), Value(val), Loc(l) {}
+
+  explicit CXXBoolLiteralExpr(EmptyShell Empty)
+    : Expr(CXXBoolLiteralExprClass, Empty) { }
+
+  bool getValue() const { return Value; }
+  void setValue(bool V) { Value = V; }
+
+  virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
+
+  SourceLocation getLocation() const { return Loc; }
+  void setLocation(SourceLocation L) { Loc = L; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CXXBoolLiteralExprClass;
+  }
+  static bool classof(const CXXBoolLiteralExpr *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+/// CXXNullPtrLiteralExpr - [C++0x 2.14.7] C++ Pointer Literal
+class CXXNullPtrLiteralExpr : public Expr {
+  SourceLocation Loc;
+public:
+  CXXNullPtrLiteralExpr(QualType Ty, SourceLocation l) :
+    Expr(CXXNullPtrLiteralExprClass, Ty, false, false), Loc(l) {}
+
+  explicit CXXNullPtrLiteralExpr(EmptyShell Empty)
+    : Expr(CXXNullPtrLiteralExprClass, Empty) { }
+
+  virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
+
+  SourceLocation getLocation() const { return Loc; }
+  void setLocation(SourceLocation L) { Loc = L; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CXXNullPtrLiteralExprClass;
+  }
+  static bool classof(const CXXNullPtrLiteralExpr *) { return true; }
+
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+/// CXXTypeidExpr - A C++ @c typeid expression (C++ [expr.typeid]), which gets
+/// the type_info that corresponds to the supplied type, or the (possibly
+/// dynamic) type of the supplied expression.
+///
+/// This represents code like @c typeid(int) or @c typeid(*objPtr)
+class CXXTypeidExpr : public Expr {
+private:
+  llvm::PointerUnion<Stmt *, TypeSourceInfo *> Operand;
+  SourceRange Range;
+
+public:
+  CXXTypeidExpr(QualType Ty, TypeSourceInfo *Operand, SourceRange R)
+    : Expr(CXXTypeidExprClass, Ty, 
+           // typeid is never type-dependent (C++ [temp.dep.expr]p4)
+           false,
+           // typeid is value-dependent if the type or expression are dependent
+           Operand->getType()->isDependentType()),
+      Operand(Operand), Range(R) { }
+  
+  CXXTypeidExpr(QualType Ty, Expr *Operand, SourceRange R)
+    : Expr(CXXTypeidExprClass, Ty,
+        // typeid is never type-dependent (C++ [temp.dep.expr]p4)
+        false,
+        // typeid is value-dependent if the type or expression are dependent
+        Operand->isTypeDependent() || Operand->isValueDependent()),
+      Operand(Operand), Range(R) { }
+
+  bool isTypeOperand() const { return Operand.is<TypeSourceInfo *>(); }
+  
+  /// \brief Retrieves the type operand of this typeid() expression after
+  /// various required adjustments (removing reference types, cv-qualifiers).
+  QualType getTypeOperand() const;
+
+  /// \brief Retrieve source information for the type operand.
+  TypeSourceInfo *getTypeOperandSourceInfo() const {
+    assert(isTypeOperand() && "Cannot call getTypeOperand for typeid(expr)");
+    return Operand.get<TypeSourceInfo *>();
+  }
+  
+  Expr* getExprOperand() const {
+    assert(!isTypeOperand() && "Cannot call getExprOperand for typeid(type)");
+    return static_cast<Expr*>(Operand.get<Stmt *>());
+  }
+
+  virtual SourceRange getSourceRange() const {
+    return Range;
+  }
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CXXTypeidExprClass;
+  }
+  static bool classof(const CXXTypeidExpr *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+/// CXXThisExpr - Represents the "this" expression in C++, which is a
+/// pointer to the object on which the current member function is
+/// executing (C++ [expr.prim]p3). Example:
+///
+/// @code
+/// class Foo {
+/// public:
+///   void bar();
+///   void test() { this->bar(); }
+/// };
+/// @endcode
+class CXXThisExpr : public Expr {
+  SourceLocation Loc;
+  bool Implicit : 1;
+  
+public:
+  CXXThisExpr(SourceLocation L, QualType Type, bool isImplicit)
+    : Expr(CXXThisExprClass, Type,
+           // 'this' is type-dependent if the class type of the enclosing
+           // member function is dependent (C++ [temp.dep.expr]p2)
+           Type->isDependentType(), Type->isDependentType()),
+      Loc(L), Implicit(isImplicit) { }
+
+  virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
+
+  bool isImplicit() const { return Implicit; }
+  void setImplicit(bool I) { Implicit = I; }
+  
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CXXThisExprClass;
+  }
+  static bool classof(const CXXThisExpr *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+///  CXXThrowExpr - [C++ 15] C++ Throw Expression.  This handles
+///  'throw' and 'throw' assignment-expression.  When
+///  assignment-expression isn't present, Op will be null.
+///
+class CXXThrowExpr : public Expr {
+  Stmt *Op;
+  SourceLocation ThrowLoc;
+public:
+  // Ty is the void type which is used as the result type of the
+  // exepression.  The l is the location of the throw keyword.  expr
+  // can by null, if the optional expression to throw isn't present.
+  CXXThrowExpr(Expr *expr, QualType Ty, SourceLocation l) :
+    Expr(CXXThrowExprClass, Ty, false, false), Op(expr), ThrowLoc(l) {}
+  const Expr *getSubExpr() const { return cast_or_null<Expr>(Op); }
+  Expr *getSubExpr() { return cast_or_null<Expr>(Op); }
+  void setSubExpr(Expr *E) { Op = E; }
+
+  SourceLocation getThrowLoc() const { return ThrowLoc; }
+  void setThrowLoc(SourceLocation L) { ThrowLoc = L; }
+
+  virtual SourceRange getSourceRange() const {
+    if (getSubExpr() == 0)
+      return SourceRange(ThrowLoc, ThrowLoc);
+    return SourceRange(ThrowLoc, getSubExpr()->getSourceRange().getEnd());
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CXXThrowExprClass;
+  }
+  static bool classof(const CXXThrowExpr *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+/// CXXDefaultArgExpr - C++ [dcl.fct.default]. This wraps up a
+/// function call argument that was created from the corresponding
+/// parameter's default argument, when the call did not explicitly
+/// supply arguments for all of the parameters.
+class CXXDefaultArgExpr : public Expr {
+  /// \brief The parameter whose default is being used.
+  ///
+  /// When the bit is set, the subexpression is stored after the 
+  /// CXXDefaultArgExpr itself. When the bit is clear, the parameter's
+  /// actual default expression is the subexpression.
+  llvm::PointerIntPair<ParmVarDecl *, 1, bool> Param;
+
+  /// \brief The location where the default argument expression was used.
+  SourceLocation Loc;
+  
+protected:
+  CXXDefaultArgExpr(StmtClass SC, SourceLocation Loc, ParmVarDecl *param)
+    : Expr(SC, 
+           param->hasUnparsedDefaultArg()
+             ? param->getType().getNonReferenceType()
+             : param->getDefaultArg()->getType(),
+           false, false),
+      Param(param, false), Loc(Loc) { }
+
+  CXXDefaultArgExpr(StmtClass SC, SourceLocation Loc, ParmVarDecl *param, 
+                    Expr *SubExpr)
+    : Expr(SC, SubExpr->getType(), false, false), Param(param, true), Loc(Loc)
+  {
+    *reinterpret_cast<Expr **>(this + 1) = SubExpr;
+  }
+  
+protected:
+  virtual void DoDestroy(ASTContext &C);
+  
+public:
+  // Param is the parameter whose default argument is used by this
+  // expression.
+  static CXXDefaultArgExpr *Create(ASTContext &C, SourceLocation Loc,
+                                   ParmVarDecl *Param) {
+    return new (C) CXXDefaultArgExpr(CXXDefaultArgExprClass, Loc, Param);
+  }
+
+  // Param is the parameter whose default argument is used by this
+  // expression, and SubExpr is the expression that will actually be used.
+  static CXXDefaultArgExpr *Create(ASTContext &C, 
+                                   SourceLocation Loc,
+                                   ParmVarDecl *Param, 
+                                   Expr *SubExpr);
+  
+  // Retrieve the parameter that the argument was created from.
+  const ParmVarDecl *getParam() const { return Param.getPointer(); }
+  ParmVarDecl *getParam() { return Param.getPointer(); }
+
+  // Retrieve the actual argument to the function call.
+  const Expr *getExpr() const { 
+    if (Param.getInt())
+      return *reinterpret_cast<Expr const * const*> (this + 1);
+    return getParam()->getDefaultArg(); 
+  }
+  Expr *getExpr() { 
+    if (Param.getInt())
+      return *reinterpret_cast<Expr **> (this + 1);
+    return getParam()->getDefaultArg(); 
+  }
+
+  /// \brief Retrieve the location where this default argument was actually 
+  /// used.
+  SourceLocation getUsedLocation() const { return Loc; }
+  
+  virtual SourceRange getSourceRange() const {
+    // Default argument expressions have no representation in the
+    // source, so they have an empty source range.
+    return SourceRange();
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CXXDefaultArgExprClass;
+  }
+  static bool classof(const CXXDefaultArgExpr *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+/// CXXTemporary - Represents a C++ temporary.
+class CXXTemporary {
+  /// Destructor - The destructor that needs to be called.
+  const CXXDestructorDecl *Destructor;
+
+  CXXTemporary(const CXXDestructorDecl *destructor)
+    : Destructor(destructor) { }
+  ~CXXTemporary() { }
+
+public:
+  static CXXTemporary *Create(ASTContext &C,
+                              const CXXDestructorDecl *Destructor);
+
+  void Destroy(ASTContext &Ctx);
+
+  const CXXDestructorDecl *getDestructor() const { return Destructor; }
+};
+
+/// CXXBindTemporaryExpr - Represents binding an expression to a temporary,
+/// so its destructor can be called later.
+class CXXBindTemporaryExpr : public Expr {
+  CXXTemporary *Temp;
+
+  Stmt *SubExpr;
+
+  CXXBindTemporaryExpr(CXXTemporary *temp, Expr* subexpr)
+   : Expr(CXXBindTemporaryExprClass, subexpr->getType(), false, false),
+     Temp(temp), SubExpr(subexpr) { }
+  ~CXXBindTemporaryExpr() { }
+
+protected:
+  virtual void DoDestroy(ASTContext &C);
+
+public:
+  static CXXBindTemporaryExpr *Create(ASTContext &C, CXXTemporary *Temp,
+                                      Expr* SubExpr);
+
+  CXXTemporary *getTemporary() { return Temp; }
+  const CXXTemporary *getTemporary() const { return Temp; }
+
+  const Expr *getSubExpr() const { return cast<Expr>(SubExpr); }
+  Expr *getSubExpr() { return cast<Expr>(SubExpr); }
+  void setSubExpr(Expr *E) { SubExpr = E; }
+
+  virtual SourceRange getSourceRange() const { 
+    return SubExpr->getSourceRange();
+  }
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CXXBindTemporaryExprClass;
+  }
+  static bool classof(const CXXBindTemporaryExpr *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+/// CXXBindReferenceExpr - Represents binding an expression to a reference.
+/// In the example:
+///
+/// const int &i = 10;
+///
+/// a bind reference expression is inserted to indicate that 10 is bound to
+/// a reference. (Ans also that a temporary needs to be created to hold the
+/// value).
+class CXXBindReferenceExpr : public Expr {
+  // SubExpr - The expression being bound.
+  Stmt *SubExpr;
+  
+  // ExtendsLifetime - Whether binding this reference extends the lifetime of
+  // the expression being bound. FIXME: Add C++ reference.
+  bool ExtendsLifetime;
+
+  /// RequiresTemporaryCopy - Whether binding the subexpression requires a
+  /// temporary copy.
+  bool RequiresTemporaryCopy;
+  
+  CXXBindReferenceExpr(Expr *subexpr, bool ExtendsLifetime, 
+                       bool RequiresTemporaryCopy)
+  : Expr(CXXBindReferenceExprClass, subexpr->getType(), false, false),
+    SubExpr(subexpr), ExtendsLifetime(ExtendsLifetime), 
+    RequiresTemporaryCopy(RequiresTemporaryCopy) { }
+  ~CXXBindReferenceExpr() { }
+
+protected:
+  virtual void DoDestroy(ASTContext &C);
+
+public:
+  static CXXBindReferenceExpr *Create(ASTContext &C, Expr *SubExpr,
+                                      bool ExtendsLifetime, 
+                                      bool RequiresTemporaryCopy);
+
+  const Expr *getSubExpr() const { return cast<Expr>(SubExpr); }
+  Expr *getSubExpr() { return cast<Expr>(SubExpr); }
+  void setSubExpr(Expr *E) { SubExpr = E; }
+
+  virtual SourceRange getSourceRange() const { 
+    return SubExpr->getSourceRange();
+  }
+
+  /// requiresTemporaryCopy - Whether binding the subexpression requires a
+  /// temporary copy.
+  bool requiresTemporaryCopy() const { return RequiresTemporaryCopy; }
+
+  // extendsLifetime - Whether binding this reference extends the lifetime of
+  // the expression being bound. FIXME: Add C++ reference.
+  bool extendsLifetime() { return ExtendsLifetime; }
+    
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CXXBindReferenceExprClass;
+  }
+  static bool classof(const CXXBindReferenceExpr *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+/// CXXConstructExpr - Represents a call to a C++ constructor.
+class CXXConstructExpr : public Expr {
+  CXXConstructorDecl *Constructor;
+
+  SourceLocation Loc;
+  bool Elidable : 1;
+  bool ZeroInitialization : 1;
+  bool BaseInitialization : 1;
+  Stmt **Args;
+  unsigned NumArgs;
+
+protected:
+  CXXConstructExpr(ASTContext &C, StmtClass SC, QualType T,
+                   SourceLocation Loc,
+                   CXXConstructorDecl *d, bool elidable,
+                   Expr **args, unsigned numargs,
+                   bool ZeroInitialization = false,
+                   bool BaseInitialization = false);
+  ~CXXConstructExpr() { }
+
+  virtual void DoDestroy(ASTContext &C);
+
+public:
+  /// \brief Construct an empty C++ construction expression that will store
+  /// \p numargs arguments.
+  CXXConstructExpr(EmptyShell Empty, ASTContext &C, unsigned numargs);
+  
+  static CXXConstructExpr *Create(ASTContext &C, QualType T,
+                                  SourceLocation Loc,
+                                  CXXConstructorDecl *D, bool Elidable,
+                                  Expr **Args, unsigned NumArgs,
+                                  bool ZeroInitialization = false,
+                                  bool BaseInitialization = false);
+
+
+  CXXConstructorDecl* getConstructor() const { return Constructor; }
+  void setConstructor(CXXConstructorDecl *C) { Constructor = C; }
+  
+  SourceLocation getLocation() const { return Loc; }
+  void setLocation(SourceLocation Loc) { this->Loc = Loc; }
+  
+  /// \brief Whether this construction is elidable.
+  bool isElidable() const { return Elidable; }
+  void setElidable(bool E) { Elidable = E; }
+  
+  /// \brief Whether this construction first requires
+  /// zero-initialization before the initializer is called.
+  bool requiresZeroInitialization() const { return ZeroInitialization; }
+  void setRequiresZeroInitialization(bool ZeroInit) {
+    ZeroInitialization = ZeroInit;
+  }
+  
+  /// \brief Determines whether this constructor is actually constructing
+  /// a base class (rather than a complete object).
+  bool isBaseInitialization() const { return BaseInitialization; }
+  void setBaseInitialization(bool BI) { BaseInitialization = BI; }
+  
+  typedef ExprIterator arg_iterator;
+  typedef ConstExprIterator const_arg_iterator;
+
+  arg_iterator arg_begin() { return Args; }
+  arg_iterator arg_end() { return Args + NumArgs; }
+  const_arg_iterator arg_begin() const { return Args; }
+  const_arg_iterator arg_end() const { return Args + NumArgs; }
+
+  Expr **getArgs() const { return reinterpret_cast<Expr **>(Args); }
+  unsigned getNumArgs() const { return NumArgs; }
+
+  /// getArg - Return the specified argument.
+  Expr *getArg(unsigned Arg) {
+    assert(Arg < NumArgs && "Arg access out of range!");
+    return cast<Expr>(Args[Arg]);
+  }
+  const Expr *getArg(unsigned Arg) const {
+    assert(Arg < NumArgs && "Arg access out of range!");
+    return cast<Expr>(Args[Arg]);
+  }
+
+  /// setArg - Set the specified argument.
+  void setArg(unsigned Arg, Expr *ArgExpr) {
+    assert(Arg < NumArgs && "Arg access out of range!");
+    Args[Arg] = ArgExpr;
+  }
+
+  virtual SourceRange getSourceRange() const;
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CXXConstructExprClass ||
+      T->getStmtClass() == CXXTemporaryObjectExprClass;
+  }
+  static bool classof(const CXXConstructExpr *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+/// CXXFunctionalCastExpr - Represents an explicit C++ type conversion
+/// that uses "functional" notion (C++ [expr.type.conv]). Example: @c
+/// x = int(0.5);
+class CXXFunctionalCastExpr : public ExplicitCastExpr {
+  SourceLocation TyBeginLoc;
+  SourceLocation RParenLoc;
+public:
+  CXXFunctionalCastExpr(QualType ty, TypeSourceInfo *writtenTy,
+                        SourceLocation tyBeginLoc, CastKind kind,
+                        Expr *castExpr, CXXBaseSpecifierArray BasePath,
+                        SourceLocation rParenLoc) 
+    : ExplicitCastExpr(CXXFunctionalCastExprClass, ty, kind, castExpr, 
+                       BasePath, writtenTy),
+      TyBeginLoc(tyBeginLoc), RParenLoc(rParenLoc) {}
+
+  explicit CXXFunctionalCastExpr(EmptyShell Shell)
+    : ExplicitCastExpr(CXXFunctionalCastExprClass, Shell) { }
+
+  SourceLocation getTypeBeginLoc() const { return TyBeginLoc; }
+  void setTypeBeginLoc(SourceLocation L) { TyBeginLoc = L; }
+  SourceLocation getRParenLoc() const { return RParenLoc; }
+  void setRParenLoc(SourceLocation L) { RParenLoc = L; }
+
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(TyBeginLoc, RParenLoc);
+  }
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CXXFunctionalCastExprClass;
+  }
+  static bool classof(const CXXFunctionalCastExpr *) { return true; }
+};
+
+/// @brief Represents a C++ functional cast expression that builds a
+/// temporary object.
+///
+/// This expression type represents a C++ "functional" cast
+/// (C++[expr.type.conv]) with N != 1 arguments that invokes a
+/// constructor to build a temporary object. If N == 0 but no
+/// constructor will be called (because the functional cast is
+/// performing a value-initialized an object whose class type has no
+/// user-declared constructors), CXXZeroInitValueExpr will represent
+/// the functional cast. Finally, with N == 1 arguments the functional
+/// cast expression will be represented by CXXFunctionalCastExpr.
+/// Example:
+/// @code
+/// struct X { X(int, float); }
+///
+/// X create_X() {
+///   return X(1, 3.14f); // creates a CXXTemporaryObjectExpr
+/// };
+/// @endcode
+class CXXTemporaryObjectExpr : public CXXConstructExpr {
+  SourceLocation TyBeginLoc;
+  SourceLocation RParenLoc;
+
+public:
+  CXXTemporaryObjectExpr(ASTContext &C, CXXConstructorDecl *Cons,
+                         QualType writtenTy, SourceLocation tyBeginLoc,
+                         Expr **Args,unsigned NumArgs,
+                         SourceLocation rParenLoc);
+
+  ~CXXTemporaryObjectExpr() { }
+
+  SourceLocation getTypeBeginLoc() const { return TyBeginLoc; }
+  SourceLocation getRParenLoc() const { return RParenLoc; }
+
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(TyBeginLoc, RParenLoc);
+  }
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CXXTemporaryObjectExprClass;
+  }
+  static bool classof(const CXXTemporaryObjectExpr *) { return true; }
+};
+
+/// CXXZeroInitValueExpr - [C++ 5.2.3p2]
+/// Expression "T()" which creates a value-initialized rvalue of type
+/// T, which is either a non-class type or a class type without any
+/// user-defined constructors.
+///
+class CXXZeroInitValueExpr : public Expr {
+  SourceLocation TyBeginLoc;
+  SourceLocation RParenLoc;
+
+public:
+  CXXZeroInitValueExpr(QualType ty, SourceLocation tyBeginLoc,
+                       SourceLocation rParenLoc ) :
+    Expr(CXXZeroInitValueExprClass, ty, false, false),
+    TyBeginLoc(tyBeginLoc), RParenLoc(rParenLoc) {}
+
+  SourceLocation getTypeBeginLoc() const { return TyBeginLoc; }
+  SourceLocation getRParenLoc() const { return RParenLoc; }
+
+  /// @brief Whether this initialization expression was
+  /// implicitly-generated.
+  bool isImplicit() const {
+    return TyBeginLoc.isInvalid() && RParenLoc.isInvalid();
+  }
+
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(TyBeginLoc, RParenLoc);
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CXXZeroInitValueExprClass;
+  }
+  static bool classof(const CXXZeroInitValueExpr *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+/// CXXNewExpr - A new expression for memory allocation and constructor calls,
+/// e.g: "new CXXNewExpr(foo)".
+class CXXNewExpr : public Expr {
+  // Was the usage ::new, i.e. is the global new to be used?
+  bool GlobalNew : 1;
+  // Was the form (type-id) used? Otherwise, it was new-type-id.
+  bool ParenTypeId : 1;
+  // Is there an initializer? If not, built-ins are uninitialized, else they're
+  // value-initialized.
+  bool Initializer : 1;
+  // Do we allocate an array? If so, the first SubExpr is the size expression.
+  bool Array : 1;
+  // The number of placement new arguments.
+  unsigned NumPlacementArgs : 14;
+  // The number of constructor arguments. This may be 1 even for non-class
+  // types; use the pseudo copy constructor.
+  unsigned NumConstructorArgs : 14;
+  // Contains an optional array size expression, any number of optional
+  // placement arguments, and any number of optional constructor arguments,
+  // in that order.
+  Stmt **SubExprs;
+  // Points to the allocation function used.
+  FunctionDecl *OperatorNew;
+  // Points to the deallocation function used in case of error. May be null.
+  FunctionDecl *OperatorDelete;
+  // Points to the constructor used. Cannot be null if AllocType is a record;
+  // it would still point at the default constructor (even an implicit one).
+  // Must be null for all other types.
+  CXXConstructorDecl *Constructor;
+
+  SourceLocation StartLoc;
+  SourceLocation EndLoc;
+
+public:
+  CXXNewExpr(ASTContext &C, bool globalNew, FunctionDecl *operatorNew,
+             Expr **placementArgs, unsigned numPlaceArgs, bool ParenTypeId,
+             Expr *arraySize, CXXConstructorDecl *constructor, bool initializer,
+             Expr **constructorArgs, unsigned numConsArgs,
+             FunctionDecl *operatorDelete, QualType ty,
+             SourceLocation startLoc, SourceLocation endLoc);
+  
+  virtual void DoDestroy(ASTContext &C);
+
+  QualType getAllocatedType() const {
+    assert(getType()->isPointerType());
+    return getType()->getAs<PointerType>()->getPointeeType();
+  }
+
+  FunctionDecl *getOperatorNew() const { return OperatorNew; }
+  FunctionDecl *getOperatorDelete() const { return OperatorDelete; }
+  CXXConstructorDecl *getConstructor() const { return Constructor; }
+
+  bool isArray() const { return Array; }
+  Expr *getArraySize() {
+    return Array ? cast<Expr>(SubExprs[0]) : 0;
+  }
+  const Expr *getArraySize() const {
+    return Array ? cast<Expr>(SubExprs[0]) : 0;
+  }
+
+  unsigned getNumPlacementArgs() const { return NumPlacementArgs; }
+  Expr *getPlacementArg(unsigned i) {
+    assert(i < NumPlacementArgs && "Index out of range");
+    return cast<Expr>(SubExprs[Array + i]);
+  }
+  const Expr *getPlacementArg(unsigned i) const {
+    assert(i < NumPlacementArgs && "Index out of range");
+    return cast<Expr>(SubExprs[Array + i]);
+  }
+
+  bool isGlobalNew() const { return GlobalNew; }
+  bool isParenTypeId() const { return ParenTypeId; }
+  bool hasInitializer() const { return Initializer; }
+
+  unsigned getNumConstructorArgs() const { return NumConstructorArgs; }
+  Expr *getConstructorArg(unsigned i) {
+    assert(i < NumConstructorArgs && "Index out of range");
+    return cast<Expr>(SubExprs[Array + NumPlacementArgs + i]);
+  }
+  const Expr *getConstructorArg(unsigned i) const {
+    assert(i < NumConstructorArgs && "Index out of range");
+    return cast<Expr>(SubExprs[Array + NumPlacementArgs + i]);
+  }
+
+  typedef ExprIterator arg_iterator;
+  typedef ConstExprIterator const_arg_iterator;
+
+  arg_iterator placement_arg_begin() {
+    return SubExprs + Array;
+  }
+  arg_iterator placement_arg_end() {
+    return SubExprs + Array + getNumPlacementArgs();
+  }
+  const_arg_iterator placement_arg_begin() const {
+    return SubExprs + Array;
+  }
+  const_arg_iterator placement_arg_end() const {
+    return SubExprs + Array + getNumPlacementArgs();
+  }
+
+  arg_iterator constructor_arg_begin() {
+    return SubExprs + Array + getNumPlacementArgs();
+  }
+  arg_iterator constructor_arg_end() {
+    return SubExprs + Array + getNumPlacementArgs() + getNumConstructorArgs();
+  }
+  const_arg_iterator constructor_arg_begin() const {
+    return SubExprs + Array + getNumPlacementArgs();
+  }
+  const_arg_iterator constructor_arg_end() const {
+    return SubExprs + Array + getNumPlacementArgs() + getNumConstructorArgs();
+  }
+
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(StartLoc, EndLoc);
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CXXNewExprClass;
+  }
+  static bool classof(const CXXNewExpr *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+/// CXXDeleteExpr - A delete expression for memory deallocation and destructor
+/// calls, e.g. "delete[] pArray".
+class CXXDeleteExpr : public Expr {
+  // Is this a forced global delete, i.e. "::delete"?
+  bool GlobalDelete : 1;
+  // Is this the array form of delete, i.e. "delete[]"?
+  bool ArrayForm : 1;
+  // Points to the operator delete overload that is used. Could be a member.
+  FunctionDecl *OperatorDelete;
+  // The pointer expression to be deleted.
+  Stmt *Argument;
+  // Location of the expression.
+  SourceLocation Loc;
+public:
+  CXXDeleteExpr(QualType ty, bool globalDelete, bool arrayForm,
+                FunctionDecl *operatorDelete, Expr *arg, SourceLocation loc)
+    : Expr(CXXDeleteExprClass, ty, false, false), GlobalDelete(globalDelete),
+      ArrayForm(arrayForm), OperatorDelete(operatorDelete), Argument(arg),
+      Loc(loc) { }
+
+  bool isGlobalDelete() const { return GlobalDelete; }
+  bool isArrayForm() const { return ArrayForm; }
+
+  FunctionDecl *getOperatorDelete() const { return OperatorDelete; }
+
+  Expr *getArgument() { return cast<Expr>(Argument); }
+  const Expr *getArgument() const { return cast<Expr>(Argument); }
+
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(Loc, Argument->getLocEnd());
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CXXDeleteExprClass;
+  }
+  static bool classof(const CXXDeleteExpr *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+/// \brief Structure used to store the type being destroyed by a 
+/// pseudo-destructor expression.
+class PseudoDestructorTypeStorage {
+  /// \brief Either the type source information or the name of the type, if 
+  /// it couldn't be resolved due to type-dependence.
+  llvm::PointerUnion<TypeSourceInfo *, IdentifierInfo *> Type;
+  
+  /// \brief The starting source location of the pseudo-destructor type.
+  SourceLocation Location;
+  
+public:
+  PseudoDestructorTypeStorage() { }
+  
+  PseudoDestructorTypeStorage(IdentifierInfo *II, SourceLocation Loc)
+    : Type(II), Location(Loc) { }
+  
+  PseudoDestructorTypeStorage(TypeSourceInfo *Info);
+  
+  TypeSourceInfo *getTypeSourceInfo() const { 
+    return Type.dyn_cast<TypeSourceInfo *>(); 
+  }
+  
+  IdentifierInfo *getIdentifier() const {
+    return Type.dyn_cast<IdentifierInfo *>();
+  }
+  
+  SourceLocation getLocation() const { return Location; }
+};
+  
+/// \brief Represents a C++ pseudo-destructor (C++ [expr.pseudo]).
+///
+/// A pseudo-destructor is an expression that looks like a member access to a
+/// destructor of a scalar type, except that scalar types don't have 
+/// destructors. For example:
+///
+/// \code
+/// typedef int T;
+/// void f(int *p) {
+///   p->T::~T();
+/// }
+/// \endcode
+///
+/// Pseudo-destructors typically occur when instantiating templates such as:
+/// 
+/// \code
+/// template<typename T>
+/// void destroy(T* ptr) {
+///   ptr->T::~T();
+/// }
+/// \endcode
+///
+/// for scalar types. A pseudo-destructor expression has no run-time semantics
+/// beyond evaluating the base expression.
+class CXXPseudoDestructorExpr : public Expr {
+  /// \brief The base expression (that is being destroyed).
+  Stmt *Base;
+
+  /// \brief Whether the operator was an arrow ('->'); otherwise, it was a
+  /// period ('.').
+  bool IsArrow : 1;
+
+  /// \brief The location of the '.' or '->' operator.
+  SourceLocation OperatorLoc;
+
+  /// \brief The nested-name-specifier that follows the operator, if present.
+  NestedNameSpecifier *Qualifier;
+
+  /// \brief The source range that covers the nested-name-specifier, if
+  /// present.
+  SourceRange QualifierRange;
+
+  /// \brief The type that precedes the '::' in a qualified pseudo-destructor
+  /// expression.
+  TypeSourceInfo *ScopeType;
+  
+  /// \brief The location of the '::' in a qualified pseudo-destructor 
+  /// expression.
+  SourceLocation ColonColonLoc;
+  
+  /// \brief The location of the '~'.
+  SourceLocation TildeLoc;
+  
+  /// \brief The type being destroyed, or its name if we were unable to 
+  /// resolve the name.
+  PseudoDestructorTypeStorage DestroyedType;
+
+public:
+  CXXPseudoDestructorExpr(ASTContext &Context,
+                          Expr *Base, bool isArrow, SourceLocation OperatorLoc,
+                          NestedNameSpecifier *Qualifier,
+                          SourceRange QualifierRange,
+                          TypeSourceInfo *ScopeType,
+                          SourceLocation ColonColonLoc,
+                          SourceLocation TildeLoc,
+                          PseudoDestructorTypeStorage DestroyedType)
+    : Expr(CXXPseudoDestructorExprClass,
+           Context.getPointerType(Context.getFunctionType(Context.VoidTy, 0, 0,
+                                                          false, 0, false, 
+                                                          false, 0, 0,
+                                                      FunctionType::ExtInfo())),
+           /*isTypeDependent=*/(Base->isTypeDependent() ||
+            (DestroyedType.getTypeSourceInfo() &&
+              DestroyedType.getTypeSourceInfo()->getType()->isDependentType())),
+           /*isValueDependent=*/Base->isValueDependent()),
+      Base(static_cast<Stmt *>(Base)), IsArrow(isArrow),
+      OperatorLoc(OperatorLoc), Qualifier(Qualifier),
+      QualifierRange(QualifierRange), 
+      ScopeType(ScopeType), ColonColonLoc(ColonColonLoc), TildeLoc(TildeLoc),
+      DestroyedType(DestroyedType) { }
+
+  void setBase(Expr *E) { Base = E; }
+  Expr *getBase() const { return cast<Expr>(Base); }
+
+  /// \brief Determines whether this member expression actually had
+  /// a C++ nested-name-specifier prior to the name of the member, e.g.,
+  /// x->Base::foo.
+  bool hasQualifier() const { return Qualifier != 0; }
+
+  /// \brief If the member name was qualified, retrieves the source range of
+  /// the nested-name-specifier that precedes the member name. Otherwise,
+  /// returns an empty source range.
+  SourceRange getQualifierRange() const { return QualifierRange; }
+
+  /// \brief If the member name was qualified, retrieves the
+  /// nested-name-specifier that precedes the member name. Otherwise, returns
+  /// NULL.
+  NestedNameSpecifier *getQualifier() const { return Qualifier; }
+
+  /// \brief Determine whether this pseudo-destructor expression was written
+  /// using an '->' (otherwise, it used a '.').
+  bool isArrow() const { return IsArrow; }
+  void setArrow(bool A) { IsArrow = A; }
+
+  /// \brief Retrieve the location of the '.' or '->' operator.
+  SourceLocation getOperatorLoc() const { return OperatorLoc; }
+
+  /// \brief Retrieve the scope type in a qualified pseudo-destructor 
+  /// expression.
+  ///
+  /// Pseudo-destructor expressions can have extra qualification within them
+  /// that is not part of the nested-name-specifier, e.g., \c p->T::~T().
+  /// Here, if the object type of the expression is (or may be) a scalar type,
+  /// \p T may also be a scalar type and, therefore, cannot be part of a 
+  /// nested-name-specifier. It is stored as the "scope type" of the pseudo-
+  /// destructor expression.
+  TypeSourceInfo *getScopeTypeInfo() const { return ScopeType; }
+  
+  /// \brief Retrieve the location of the '::' in a qualified pseudo-destructor
+  /// expression.
+  SourceLocation getColonColonLoc() const { return ColonColonLoc; }
+  
+  /// \brief Retrieve the location of the '~'.
+  SourceLocation getTildeLoc() const { return TildeLoc; }
+  
+  /// \brief Retrieve the source location information for the type
+  /// being destroyed.
+  ///
+  /// This type-source information is available for non-dependent 
+  /// pseudo-destructor expressions and some dependent pseudo-destructor
+  /// expressions. Returns NULL if we only have the identifier for a
+  /// dependent pseudo-destructor expression.
+  TypeSourceInfo *getDestroyedTypeInfo() const { 
+    return DestroyedType.getTypeSourceInfo(); 
+  }
+  
+  /// \brief In a dependent pseudo-destructor expression for which we do not
+  /// have full type information on the destroyed type, provides the name
+  /// of the destroyed type.
+  IdentifierInfo *getDestroyedTypeIdentifier() const {
+    return DestroyedType.getIdentifier();
+  }
+  
+  /// \brief Retrieve the type being destroyed.
+  QualType getDestroyedType() const;
+  
+  /// \brief Retrieve the starting location of the type being destroyed.
+  SourceLocation getDestroyedTypeLoc() const { 
+    return DestroyedType.getLocation(); 
+  }
+
+  virtual SourceRange getSourceRange() const;
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CXXPseudoDestructorExprClass;
+  }
+  static bool classof(const CXXPseudoDestructorExpr *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+/// UnaryTypeTraitExpr - A GCC or MS unary type trait, as used in the
+/// implementation of TR1/C++0x type trait templates.
+/// Example:
+/// __is_pod(int) == true
+/// __is_enum(std::string) == false
+class UnaryTypeTraitExpr : public Expr {
+  /// UTT - The trait.
+  UnaryTypeTrait UTT;
+
+  /// Loc - The location of the type trait keyword.
+  SourceLocation Loc;
+
+  /// RParen - The location of the closing paren.
+  SourceLocation RParen;
+
+  /// QueriedType - The type we're testing.
+  QualType QueriedType;
+
+public:
+  UnaryTypeTraitExpr(SourceLocation loc, UnaryTypeTrait utt, QualType queried,
+                     SourceLocation rparen, QualType ty)
+    : Expr(UnaryTypeTraitExprClass, ty, false, queried->isDependentType()),
+      UTT(utt), Loc(loc), RParen(rparen), QueriedType(queried) { }
+
+  virtual SourceRange getSourceRange() const { return SourceRange(Loc, RParen);}
+
+  UnaryTypeTrait getTrait() const { return UTT; }
+
+  QualType getQueriedType() const { return QueriedType; }
+
+  bool EvaluateTrait(ASTContext&) const;
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == UnaryTypeTraitExprClass;
+  }
+  static bool classof(const UnaryTypeTraitExpr *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+/// \brief A reference to an overloaded function set, either an
+/// \t UnresolvedLookupExpr or an \t UnresolvedMemberExpr.
+class OverloadExpr : public Expr {
+  /// The results.  These are undesugared, which is to say, they may
+  /// include UsingShadowDecls.  Access is relative to the naming
+  /// class.
+  UnresolvedSet<4> Results;
+
+  /// The common name of these declarations.
+  DeclarationName Name;
+
+  /// The scope specifier, if any.
+  NestedNameSpecifier *Qualifier;
+  
+  /// The source range of the scope specifier.
+  SourceRange QualifierRange;
+
+  /// The location of the name.
+  SourceLocation NameLoc;
+
+  /// True if the name was a template-id.
+  bool HasExplicitTemplateArgs;
+
+protected:
+  OverloadExpr(StmtClass K, QualType T, bool Dependent,
+               NestedNameSpecifier *Qualifier, SourceRange QRange,
+               DeclarationName Name, SourceLocation NameLoc,
+               bool HasTemplateArgs)
+    : Expr(K, T, Dependent, Dependent),
+      Name(Name), Qualifier(Qualifier), QualifierRange(QRange),
+      NameLoc(NameLoc), HasExplicitTemplateArgs(HasTemplateArgs)
+  {}
+
+public:
+  /// Computes whether an unresolved lookup on the given declarations
+  /// and optional template arguments is type- and value-dependent.
+  static bool ComputeDependence(UnresolvedSetIterator Begin,
+                                UnresolvedSetIterator End,
+                                const TemplateArgumentListInfo *Args);
+
+  /// Finds the overloaded expression in the given expression of
+  /// OverloadTy.
+  ///
+  /// \return the expression (which must be there) and true if it is
+  /// within an address-of operator.
+  static llvm::PointerIntPair<OverloadExpr*,1> find(Expr *E) {
+    assert(E->getType()->isSpecificBuiltinType(BuiltinType::Overload));
+
+    bool op = false;
+    E = E->IgnoreParens();
+    if (isa<UnaryOperator>(E))
+      op = true, E = cast<UnaryOperator>(E)->getSubExpr()->IgnoreParens();
+    return llvm::PointerIntPair<OverloadExpr*,1>(cast<OverloadExpr>(E), op);
+  }
+
+  void addDecls(UnresolvedSetIterator Begin, UnresolvedSetIterator End) {
+    Results.append(Begin, End);
+  }
+
+  /// Gets the naming class of this lookup, if any.
+  CXXRecordDecl *getNamingClass() const;
+
+  typedef UnresolvedSetImpl::iterator decls_iterator;
+  decls_iterator decls_begin() const { return Results.begin(); }
+  decls_iterator decls_end() const { return Results.end(); }
+
+  /// Gets the decls as an unresolved set.
+  const UnresolvedSetImpl &getDecls() { return Results; }
+
+  /// Gets the number of declarations in the unresolved set.
+  unsigned getNumDecls() const { return Results.size(); }
+
+  /// Gets the name looked up.
+  DeclarationName getName() const { return Name; }
+  void setName(DeclarationName N) { Name = N; }
+
+  /// Gets the location of the name.
+  SourceLocation getNameLoc() const { return NameLoc; }
+  void setNameLoc(SourceLocation Loc) { NameLoc = Loc; }
+
+  /// Fetches the nested-name qualifier, if one was given.
+  NestedNameSpecifier *getQualifier() const { return Qualifier; }
+
+  /// Fetches the range of the nested-name qualifier.
+  SourceRange getQualifierRange() const { return QualifierRange; }
+
+  /// \brief Determines whether this expression had an explicit
+  /// template argument list, e.g. f<int>.
+  bool hasExplicitTemplateArgs() const { return HasExplicitTemplateArgs; }
+
+  ExplicitTemplateArgumentList &getExplicitTemplateArgs(); // defined far below
+
+  const ExplicitTemplateArgumentList &getExplicitTemplateArgs() const {
+    return const_cast<OverloadExpr*>(this)->getExplicitTemplateArgs();
+  }
+
+  ExplicitTemplateArgumentList *getOptionalExplicitTemplateArgs() {
+    if (hasExplicitTemplateArgs())
+      return &getExplicitTemplateArgs();
+    return 0;
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == UnresolvedLookupExprClass ||
+           T->getStmtClass() == UnresolvedMemberExprClass;
+  }
+  static bool classof(const OverloadExpr *) { return true; }
+};
+
+/// \brief A reference to a name which we were able to look up during
+/// parsing but could not resolve to a specific declaration.  This
+/// arises in several ways:
+///   * we might be waiting for argument-dependent lookup
+///   * the name might resolve to an overloaded function
+/// and eventually:
+///   * the lookup might have included a function template
+/// These never include UnresolvedUsingValueDecls, which are always
+/// class members and therefore appear only in
+/// UnresolvedMemberLookupExprs.
+class UnresolvedLookupExpr : public OverloadExpr {
+  /// True if these lookup results should be extended by
+  /// argument-dependent lookup if this is the operand of a function
+  /// call.
+  bool RequiresADL;
+
+  /// True if these lookup results are overloaded.  This is pretty
+  /// trivially rederivable if we urgently need to kill this field.
+  bool Overloaded;
+
+  /// The naming class (C++ [class.access.base]p5) of the lookup, if
+  /// any.  This can generally be recalculated from the context chain,
+  /// but that can be fairly expensive for unqualified lookups.  If we
+  /// want to improve memory use here, this could go in a union
+  /// against the qualified-lookup bits.
+  CXXRecordDecl *NamingClass;
+
+  UnresolvedLookupExpr(QualType T, bool Dependent, CXXRecordDecl *NamingClass,
+                       NestedNameSpecifier *Qualifier, SourceRange QRange,
+                       DeclarationName Name, SourceLocation NameLoc,
+                       bool RequiresADL, bool Overloaded, bool HasTemplateArgs)
+    : OverloadExpr(UnresolvedLookupExprClass, T, Dependent, Qualifier, QRange,
+                   Name, NameLoc, HasTemplateArgs),
+      RequiresADL(RequiresADL), Overloaded(Overloaded), NamingClass(NamingClass)
+  {}
+
+public:
+  static UnresolvedLookupExpr *Create(ASTContext &C,
+                                      bool Dependent,
+                                      CXXRecordDecl *NamingClass,
+                                      NestedNameSpecifier *Qualifier,
+                                      SourceRange QualifierRange,
+                                      DeclarationName Name,
+                                      SourceLocation NameLoc,
+                                      bool ADL, bool Overloaded) {
+    return new(C) UnresolvedLookupExpr(Dependent ? C.DependentTy : C.OverloadTy,
+                                       Dependent, NamingClass,
+                                       Qualifier, QualifierRange,
+                                       Name, NameLoc, ADL, Overloaded, false);
+  }
+
+  static UnresolvedLookupExpr *Create(ASTContext &C,
+                                      bool Dependent,
+                                      CXXRecordDecl *NamingClass,
+                                      NestedNameSpecifier *Qualifier,
+                                      SourceRange QualifierRange,
+                                      DeclarationName Name,
+                                      SourceLocation NameLoc,
+                                      bool ADL,
+                                      const TemplateArgumentListInfo &Args);
+
+  /// True if this declaration should be extended by
+  /// argument-dependent lookup.
+  bool requiresADL() const { return RequiresADL; }
+
+  /// True if this lookup is overloaded.
+  bool isOverloaded() const { return Overloaded; }
+
+  /// Gets the 'naming class' (in the sense of C++0x
+  /// [class.access.base]p5) of the lookup.  This is the scope
+  /// that was looked in to find these results.
+  CXXRecordDecl *getNamingClass() const { return NamingClass; }
+
+  // Note that, inconsistently with the explicit-template-argument AST
+  // nodes, users are *forbidden* from calling these methods on objects
+  // without explicit template arguments.
+
+  ExplicitTemplateArgumentList &getExplicitTemplateArgs() {
+    assert(hasExplicitTemplateArgs());
+    return *reinterpret_cast<ExplicitTemplateArgumentList*>(this + 1);
+  }
+
+  /// Gets a reference to the explicit template argument list.
+  const ExplicitTemplateArgumentList &getExplicitTemplateArgs() const {
+    assert(hasExplicitTemplateArgs());
+    return *reinterpret_cast<const ExplicitTemplateArgumentList*>(this + 1);
+  }
+
+  /// \brief Copies the template arguments (if present) into the given
+  /// structure.
+  void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
+    getExplicitTemplateArgs().copyInto(List);
+  }
+  
+  SourceLocation getLAngleLoc() const {
+    return getExplicitTemplateArgs().LAngleLoc;
+  }
+
+  SourceLocation getRAngleLoc() const {
+    return getExplicitTemplateArgs().RAngleLoc;
+  }
+
+  TemplateArgumentLoc const *getTemplateArgs() const {
+    return getExplicitTemplateArgs().getTemplateArgs();
+  }
+
+  unsigned getNumTemplateArgs() const {
+    return getExplicitTemplateArgs().NumTemplateArgs;
+  }
+
+  virtual SourceRange getSourceRange() const {
+    SourceRange Range(getNameLoc());
+    if (getQualifier()) Range.setBegin(getQualifierRange().getBegin());
+    if (hasExplicitTemplateArgs()) Range.setEnd(getRAngleLoc());
+    return Range;
+  }
+
+  virtual StmtIterator child_begin();
+  virtual StmtIterator child_end();
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == UnresolvedLookupExprClass;
+  }
+  static bool classof(const UnresolvedLookupExpr *) { return true; }
+};
+
+/// \brief A qualified reference to a name whose declaration cannot
+/// yet be resolved.
+///
+/// DependentScopeDeclRefExpr is similar to DeclRefExpr in that
+/// it expresses a reference to a declaration such as
+/// X<T>::value. The difference, however, is that an
+/// DependentScopeDeclRefExpr node is used only within C++ templates when
+/// the qualification (e.g., X<T>::) refers to a dependent type. In
+/// this case, X<T>::value cannot resolve to a declaration because the
+/// declaration will differ from on instantiation of X<T> to the
+/// next. Therefore, DependentScopeDeclRefExpr keeps track of the
+/// qualifier (X<T>::) and the name of the entity being referenced
+/// ("value"). Such expressions will instantiate to a DeclRefExpr once the
+/// declaration can be found.
+class DependentScopeDeclRefExpr : public Expr {
+  /// The name of the entity we will be referencing.
+  DeclarationName Name;
+
+  /// Location of the name of the declaration we're referencing.
+  SourceLocation Loc;
+
+  /// QualifierRange - The source range that covers the
+  /// nested-name-specifier.
+  SourceRange QualifierRange;
+
+  /// \brief The nested-name-specifier that qualifies this unresolved
+  /// declaration name.
+  NestedNameSpecifier *Qualifier;
+
+  /// \brief Whether the name includes explicit template arguments.
+  bool HasExplicitTemplateArgs;
+
+  DependentScopeDeclRefExpr(QualType T,
+                            NestedNameSpecifier *Qualifier,
+                            SourceRange QualifierRange,
+                            DeclarationName Name,
+                            SourceLocation NameLoc,
+                            bool HasExplicitTemplateArgs)
+    : Expr(DependentScopeDeclRefExprClass, T, true, true),
+      Name(Name), Loc(NameLoc),
+      QualifierRange(QualifierRange), Qualifier(Qualifier),
+      HasExplicitTemplateArgs(HasExplicitTemplateArgs)
+  {}
+
+public:
+  static DependentScopeDeclRefExpr *Create(ASTContext &C,
+                                           NestedNameSpecifier *Qualifier,
+                                           SourceRange QualifierRange,
+                                           DeclarationName Name,
+                                           SourceLocation NameLoc,
+                              const TemplateArgumentListInfo *TemplateArgs = 0);
+
+  /// \brief Retrieve the name that this expression refers to.
+  DeclarationName getDeclName() const { return Name; }
+
+  /// \brief Retrieve the location of the name within the expression.
+  SourceLocation getLocation() const { return Loc; }
+
+  /// \brief Retrieve the source range of the nested-name-specifier.
+  SourceRange getQualifierRange() const { return QualifierRange; }
+
+  /// \brief Retrieve the nested-name-specifier that qualifies this
+  /// declaration.
+  NestedNameSpecifier *getQualifier() const { return Qualifier; }
+
+  /// Determines whether this lookup had explicit template arguments.
+  bool hasExplicitTemplateArgs() const { return HasExplicitTemplateArgs; }
+
+  // Note that, inconsistently with the explicit-template-argument AST
+  // nodes, users are *forbidden* from calling these methods on objects
+  // without explicit template arguments.
+
+  /// Gets a reference to the explicit template argument list.
+  const ExplicitTemplateArgumentList &getExplicitTemplateArgs() const {
+    assert(hasExplicitTemplateArgs());
+    return *reinterpret_cast<const ExplicitTemplateArgumentList*>(this + 1);
+  }
+
+  /// \brief Copies the template arguments (if present) into the given
+  /// structure.
+  void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
+    getExplicitTemplateArgs().copyInto(List);
+  }
+  
+  SourceLocation getLAngleLoc() const {
+    return getExplicitTemplateArgs().LAngleLoc;
+  }
+
+  SourceLocation getRAngleLoc() const {
+    return getExplicitTemplateArgs().RAngleLoc;
+  }
+
+  TemplateArgumentLoc const *getTemplateArgs() const {
+    return getExplicitTemplateArgs().getTemplateArgs();
+  }
+
+  unsigned getNumTemplateArgs() const {
+    return getExplicitTemplateArgs().NumTemplateArgs;
+  }
+
+  virtual SourceRange getSourceRange() const {
+    SourceRange Range(QualifierRange.getBegin(), getLocation());
+    if (hasExplicitTemplateArgs())
+      Range.setEnd(getRAngleLoc());
+    return Range;
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == DependentScopeDeclRefExprClass;
+  }
+  static bool classof(const DependentScopeDeclRefExpr *) { return true; }
+
+  virtual StmtIterator child_begin();
+  virtual StmtIterator child_end();
+};
+
+class CXXExprWithTemporaries : public Expr {
+  Stmt *SubExpr;
+
+  CXXTemporary **Temps;
+  unsigned NumTemps;
+
+  CXXExprWithTemporaries(Expr *SubExpr, CXXTemporary **Temps,
+                         unsigned NumTemps);
+  ~CXXExprWithTemporaries();
+
+protected:
+  virtual void DoDestroy(ASTContext &C);
+
+public:
+  static CXXExprWithTemporaries *Create(ASTContext &C, Expr *SubExpr,
+                                        CXXTemporary **Temps, 
+                                        unsigned NumTemps);
+
+  unsigned getNumTemporaries() const { return NumTemps; }
+  CXXTemporary *getTemporary(unsigned i) {
+    assert(i < NumTemps && "Index out of range");
+    return Temps[i];
+  }
+  const CXXTemporary *getTemporary(unsigned i) const {
+    return const_cast<CXXExprWithTemporaries*>(this)->getTemporary(i);
+  }
+
+  Expr *getSubExpr() { return cast<Expr>(SubExpr); }
+  const Expr *getSubExpr() const { return cast<Expr>(SubExpr); }
+  void setSubExpr(Expr *E) { SubExpr = E; }
+
+  virtual SourceRange getSourceRange() const { 
+    return SubExpr->getSourceRange();
+  }
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CXXExprWithTemporariesClass;
+  }
+  static bool classof(const CXXExprWithTemporaries *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+/// \brief Describes an explicit type conversion that uses functional
+/// notion but could not be resolved because one or more arguments are
+/// type-dependent.
+///
+/// The explicit type conversions expressed by
+/// CXXUnresolvedConstructExpr have the form \c T(a1, a2, ..., aN),
+/// where \c T is some type and \c a1, a2, ..., aN are values, and
+/// either \C T is a dependent type or one or more of the \c a's is
+/// type-dependent. For example, this would occur in a template such
+/// as:
+///
+/// \code
+///   template<typename T, typename A1>
+///   inline T make_a(const A1& a1) {
+///     return T(a1);
+///   }
+/// \endcode
+///
+/// When the returned expression is instantiated, it may resolve to a
+/// constructor call, conversion function call, or some kind of type
+/// conversion.
+class CXXUnresolvedConstructExpr : public Expr {
+  /// \brief The starting location of the type
+  SourceLocation TyBeginLoc;
+
+  /// \brief The type being constructed.
+  QualType Type;
+
+  /// \brief The location of the left parentheses ('(').
+  SourceLocation LParenLoc;
+
+  /// \brief The location of the right parentheses (')').
+  SourceLocation RParenLoc;
+
+  /// \brief The number of arguments used to construct the type.
+  unsigned NumArgs;
+
+  CXXUnresolvedConstructExpr(SourceLocation TyBegin,
+                             QualType T,
+                             SourceLocation LParenLoc,
+                             Expr **Args,
+                             unsigned NumArgs,
+                             SourceLocation RParenLoc);
+
+public:
+  static CXXUnresolvedConstructExpr *Create(ASTContext &C,
+                                            SourceLocation TyBegin,
+                                            QualType T,
+                                            SourceLocation LParenLoc,
+                                            Expr **Args,
+                                            unsigned NumArgs,
+                                            SourceLocation RParenLoc);
+
+  /// \brief Retrieve the source location where the type begins.
+  SourceLocation getTypeBeginLoc() const { return TyBeginLoc; }
+  void setTypeBeginLoc(SourceLocation L) { TyBeginLoc = L; }
+
+  /// \brief Retrieve the type that is being constructed, as specified
+  /// in the source code.
+  QualType getTypeAsWritten() const { return Type; }
+  void setTypeAsWritten(QualType T) { Type = T; }
+
+  /// \brief Retrieve the location of the left parentheses ('(') that
+  /// precedes the argument list.
+  SourceLocation getLParenLoc() const { return LParenLoc; }
+  void setLParenLoc(SourceLocation L) { LParenLoc = L; }
+
+  /// \brief Retrieve the location of the right parentheses (')') that
+  /// follows the argument list.
+  SourceLocation getRParenLoc() const { return RParenLoc; }
+  void setRParenLoc(SourceLocation L) { RParenLoc = L; }
+
+  /// \brief Retrieve the number of arguments.
+  unsigned arg_size() const { return NumArgs; }
+
+  typedef Expr** arg_iterator;
+  arg_iterator arg_begin() { return reinterpret_cast<Expr**>(this + 1); }
+  arg_iterator arg_end() { return arg_begin() + NumArgs; }
+
+  typedef const Expr* const * const_arg_iterator;
+  const_arg_iterator arg_begin() const {
+    return reinterpret_cast<const Expr* const *>(this + 1);
+  }
+  const_arg_iterator arg_end() const {
+    return arg_begin() + NumArgs;
+  }
+
+  Expr *getArg(unsigned I) {
+    assert(I < NumArgs && "Argument index out-of-range");
+    return *(arg_begin() + I);
+  }
+
+  const Expr *getArg(unsigned I) const {
+    assert(I < NumArgs && "Argument index out-of-range");
+    return *(arg_begin() + I);
+  }
+
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(TyBeginLoc, RParenLoc);
+  }
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CXXUnresolvedConstructExprClass;
+  }
+  static bool classof(const CXXUnresolvedConstructExpr *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+/// \brief Represents a C++ member access expression where the actual
+/// member referenced could not be resolved because the base
+/// expression or the member name was dependent.
+///
+/// Like UnresolvedMemberExprs, these can be either implicit or
+/// explicit accesses.  It is only possible to get one of these with
+/// an implicit access if a qualifier is provided.
+class CXXDependentScopeMemberExpr : public Expr {
+  /// \brief The expression for the base pointer or class reference,
+  /// e.g., the \c x in x.f.  Can be null in implicit accesses.
+  Stmt *Base;
+
+  /// \brief The type of the base expression.  Never null, even for
+  /// implicit accesses.
+  QualType BaseType;
+
+  /// \brief Whether this member expression used the '->' operator or
+  /// the '.' operator.
+  bool IsArrow : 1;
+
+  /// \brief Whether this member expression has explicitly-specified template
+  /// arguments.
+  bool HasExplicitTemplateArgs : 1;
+
+  /// \brief The location of the '->' or '.' operator.
+  SourceLocation OperatorLoc;
+
+  /// \brief The nested-name-specifier that precedes the member name, if any.
+  NestedNameSpecifier *Qualifier;
+
+  /// \brief The source range covering the nested name specifier.
+  SourceRange QualifierRange;
+
+  /// \brief In a qualified member access expression such as t->Base::f, this
+  /// member stores the resolves of name lookup in the context of the member
+  /// access expression, to be used at instantiation time.
+  ///
+  /// FIXME: This member, along with the Qualifier and QualifierRange, could
+  /// be stuck into a structure that is optionally allocated at the end of
+  /// the CXXDependentScopeMemberExpr, to save space in the common case.
+  NamedDecl *FirstQualifierFoundInScope;
+
+  /// \brief The member to which this member expression refers, which
+  /// can be name, overloaded operator, or destructor.
+  /// FIXME: could also be a template-id
+  DeclarationName Member;
+
+  /// \brief The location of the member name.
+  SourceLocation MemberLoc;
+
+  /// \brief Retrieve the explicit template argument list that followed the
+  /// member template name, if any.
+  ExplicitTemplateArgumentList *getExplicitTemplateArgumentList() {
+    assert(HasExplicitTemplateArgs);
+    return reinterpret_cast<ExplicitTemplateArgumentList *>(this + 1);
+  }
+
+  /// \brief Retrieve the explicit template argument list that followed the
+  /// member template name, if any.
+  const ExplicitTemplateArgumentList *getExplicitTemplateArgumentList() const {
+    return const_cast<CXXDependentScopeMemberExpr *>(this)
+             ->getExplicitTemplateArgumentList();
+  }
+
+  CXXDependentScopeMemberExpr(ASTContext &C,
+                          Expr *Base, QualType BaseType, bool IsArrow,
+                          SourceLocation OperatorLoc,
+                          NestedNameSpecifier *Qualifier,
+                          SourceRange QualifierRange,
+                          NamedDecl *FirstQualifierFoundInScope,
+                          DeclarationName Member,
+                          SourceLocation MemberLoc,
+                          const TemplateArgumentListInfo *TemplateArgs);
+
+public:
+  CXXDependentScopeMemberExpr(ASTContext &C,
+                          Expr *Base, QualType BaseType,
+                          bool IsArrow,
+                          SourceLocation OperatorLoc,
+                          NestedNameSpecifier *Qualifier,
+                          SourceRange QualifierRange,
+                          NamedDecl *FirstQualifierFoundInScope,
+                          DeclarationName Member,
+                          SourceLocation MemberLoc)
+  : Expr(CXXDependentScopeMemberExprClass, C.DependentTy, true, true),
+    Base(Base), BaseType(BaseType), IsArrow(IsArrow),
+    HasExplicitTemplateArgs(false), OperatorLoc(OperatorLoc),
+    Qualifier(Qualifier), QualifierRange(QualifierRange),
+    FirstQualifierFoundInScope(FirstQualifierFoundInScope),
+    Member(Member), MemberLoc(MemberLoc) { }
+
+  static CXXDependentScopeMemberExpr *
+  Create(ASTContext &C,
+         Expr *Base, QualType BaseType, bool IsArrow,
+         SourceLocation OperatorLoc,
+         NestedNameSpecifier *Qualifier,
+         SourceRange QualifierRange,
+         NamedDecl *FirstQualifierFoundInScope,
+         DeclarationName Member,
+         SourceLocation MemberLoc,
+         const TemplateArgumentListInfo *TemplateArgs);
+
+  /// \brief True if this is an implicit access, i.e. one in which the
+  /// member being accessed was not written in the source.  The source
+  /// location of the operator is invalid in this case.
+  bool isImplicitAccess() const { return Base == 0; }
+
+  /// \brief Retrieve the base object of this member expressions,
+  /// e.g., the \c x in \c x.m.
+  Expr *getBase() const {
+    assert(!isImplicitAccess());
+    return cast<Expr>(Base);
+  }
+  void setBase(Expr *E) { Base = E; }
+
+  QualType getBaseType() const { return BaseType; }
+
+  /// \brief Determine whether this member expression used the '->'
+  /// operator; otherwise, it used the '.' operator.
+  bool isArrow() const { return IsArrow; }
+  void setArrow(bool A) { IsArrow = A; }
+
+  /// \brief Retrieve the location of the '->' or '.' operator.
+  SourceLocation getOperatorLoc() const { return OperatorLoc; }
+  void setOperatorLoc(SourceLocation L) { OperatorLoc = L; }
+
+  /// \brief Retrieve the nested-name-specifier that qualifies the member
+  /// name.
+  NestedNameSpecifier *getQualifier() const { return Qualifier; }
+
+  /// \brief Retrieve the source range covering the nested-name-specifier
+  /// that qualifies the member name.
+  SourceRange getQualifierRange() const { return QualifierRange; }
+
+  /// \brief Retrieve the first part of the nested-name-specifier that was
+  /// found in the scope of the member access expression when the member access
+  /// was initially parsed.
+  ///
+  /// This function only returns a useful result when member access expression
+  /// uses a qualified member name, e.g., "x.Base::f". Here, the declaration
+  /// returned by this function describes what was found by unqualified name
+  /// lookup for the identifier "Base" within the scope of the member access
+  /// expression itself. At template instantiation time, this information is
+  /// combined with the results of name lookup into the type of the object
+  /// expression itself (the class type of x).
+  NamedDecl *getFirstQualifierFoundInScope() const {
+    return FirstQualifierFoundInScope;
+  }
+
+  /// \brief Retrieve the name of the member that this expression
+  /// refers to.
+  DeclarationName getMember() const { return Member; }
+  void setMember(DeclarationName N) { Member = N; }
+
+  // \brief Retrieve the location of the name of the member that this
+  // expression refers to.
+  SourceLocation getMemberLoc() const { return MemberLoc; }
+  void setMemberLoc(SourceLocation L) { MemberLoc = L; }
+
+  /// \brief Determines whether this member expression actually had a C++
+  /// template argument list explicitly specified, e.g., x.f<int>.
+  bool hasExplicitTemplateArgs() const {
+    return HasExplicitTemplateArgs;
+  }
+
+  /// \brief Copies the template arguments (if present) into the given
+  /// structure.
+  void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
+    assert(HasExplicitTemplateArgs);
+    getExplicitTemplateArgumentList()->copyInto(List);
+  }
+
+  /// \brief Retrieve the location of the left angle bracket following the
+  /// member name ('<'), if any.
+  SourceLocation getLAngleLoc() const {
+    assert(HasExplicitTemplateArgs);
+    return getExplicitTemplateArgumentList()->LAngleLoc;
+  }
+
+  /// \brief Retrieve the template arguments provided as part of this
+  /// template-id.
+  const TemplateArgumentLoc *getTemplateArgs() const {
+    assert(HasExplicitTemplateArgs);
+    return getExplicitTemplateArgumentList()->getTemplateArgs();
+  }
+
+  /// \brief Retrieve the number of template arguments provided as part of this
+  /// template-id.
+  unsigned getNumTemplateArgs() const {
+    assert(HasExplicitTemplateArgs);
+    return getExplicitTemplateArgumentList()->NumTemplateArgs;
+  }
+
+  /// \brief Retrieve the location of the right angle bracket following the
+  /// template arguments ('>').
+  SourceLocation getRAngleLoc() const {
+    assert(HasExplicitTemplateArgs);
+    return getExplicitTemplateArgumentList()->RAngleLoc;
+  }
+
+  virtual SourceRange getSourceRange() const {
+    SourceRange Range;
+    if (!isImplicitAccess())
+      Range.setBegin(Base->getSourceRange().getBegin());
+    else if (getQualifier())
+      Range.setBegin(getQualifierRange().getBegin());
+    else
+      Range.setBegin(MemberLoc);
+
+    if (hasExplicitTemplateArgs())
+      Range.setEnd(getRAngleLoc());
+    else
+      Range.setEnd(MemberLoc);
+    return Range;
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CXXDependentScopeMemberExprClass;
+  }
+  static bool classof(const CXXDependentScopeMemberExpr *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+/// \brief Represents a C++ member access expression for which lookup
+/// produced a set of overloaded functions.
+///
+/// The member access may be explicit or implicit:
+///    struct A {
+///      int a, b;
+///      int explicitAccess() { return this->a + this->A::b; }
+///      int implicitAccess() { return a + A::b; }
+///    };
+///
+/// In the final AST, an explicit access always becomes a MemberExpr.
+/// An implicit access may become either a MemberExpr or a
+/// DeclRefExpr, depending on whether the member is static.
+class UnresolvedMemberExpr : public OverloadExpr {
+  /// \brief Whether this member expression used the '->' operator or
+  /// the '.' operator.
+  bool IsArrow : 1;
+
+  /// \brief Whether the lookup results contain an unresolved using
+  /// declaration.
+  bool HasUnresolvedUsing : 1;
+
+  /// \brief The expression for the base pointer or class reference,
+  /// e.g., the \c x in x.f.  This can be null if this is an 'unbased'
+  /// member expression
+  Stmt *Base;
+
+  /// \brief The type of the base expression;  never null.
+  QualType BaseType;
+
+  /// \brief The location of the '->' or '.' operator.
+  SourceLocation OperatorLoc;
+
+  UnresolvedMemberExpr(QualType T, bool Dependent,
+                       bool HasUnresolvedUsing,
+                       Expr *Base, QualType BaseType, bool IsArrow,
+                       SourceLocation OperatorLoc,
+                       NestedNameSpecifier *Qualifier,
+                       SourceRange QualifierRange,
+                       DeclarationName Member,
+                       SourceLocation MemberLoc,
+                       const TemplateArgumentListInfo *TemplateArgs);
+
+public:
+  static UnresolvedMemberExpr *
+  Create(ASTContext &C, bool Dependent, bool HasUnresolvedUsing,
+         Expr *Base, QualType BaseType, bool IsArrow,
+         SourceLocation OperatorLoc,
+         NestedNameSpecifier *Qualifier,
+         SourceRange QualifierRange,
+         DeclarationName Member,
+         SourceLocation MemberLoc,
+         const TemplateArgumentListInfo *TemplateArgs);
+
+  /// \brief True if this is an implicit access, i.e. one in which the
+  /// member being accessed was not written in the source.  The source
+  /// location of the operator is invalid in this case.
+  bool isImplicitAccess() const { return Base == 0; }
+
+  /// \brief Retrieve the base object of this member expressions,
+  /// e.g., the \c x in \c x.m.
+  Expr *getBase() {
+    assert(!isImplicitAccess());
+    return cast<Expr>(Base);
+  }
+  const Expr *getBase() const {
+    assert(!isImplicitAccess());
+    return cast<Expr>(Base);
+  }
+  void setBase(Expr *E) { Base = E; }
+
+  QualType getBaseType() const { return BaseType; }
+
+  /// \brief Determine whether this member expression used the '->'
+  /// operator; otherwise, it used the '.' operator.
+  bool isArrow() const { return IsArrow; }
+  void setArrow(bool A) { IsArrow = A; }
+
+  /// \brief Retrieve the location of the '->' or '.' operator.
+  SourceLocation getOperatorLoc() const { return OperatorLoc; }
+  void setOperatorLoc(SourceLocation L) { OperatorLoc = L; }
+
+  /// \brief Retrieves the naming class of this lookup.
+  CXXRecordDecl *getNamingClass() const;
+
+  /// \brief Retrieve the name of the member that this expression
+  /// refers to.
+  DeclarationName getMemberName() const { return getName(); }
+  void setMemberName(DeclarationName N) { setName(N); }
+
+  // \brief Retrieve the location of the name of the member that this
+  // expression refers to.
+  SourceLocation getMemberLoc() const { return getNameLoc(); }
+  void setMemberLoc(SourceLocation L) { setNameLoc(L); }
+
+  /// \brief Retrieve the explicit template argument list that followed the
+  /// member template name.
+  ExplicitTemplateArgumentList &getExplicitTemplateArgs() {
+    assert(hasExplicitTemplateArgs());
+    return *reinterpret_cast<ExplicitTemplateArgumentList *>(this + 1);
+  }
+
+  /// \brief Retrieve the explicit template argument list that followed the
+  /// member template name, if any.
+  const ExplicitTemplateArgumentList &getExplicitTemplateArgs() const {
+    assert(hasExplicitTemplateArgs());
+    return *reinterpret_cast<const ExplicitTemplateArgumentList *>(this + 1);
+  }
+
+  /// \brief Copies the template arguments into the given structure.
+  void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
+    getExplicitTemplateArgs().copyInto(List);
+  }
+
+  /// \brief Retrieve the location of the left angle bracket following
+  /// the member name ('<').
+  SourceLocation getLAngleLoc() const {
+    return getExplicitTemplateArgs().LAngleLoc;
+  }
+
+  /// \brief Retrieve the template arguments provided as part of this
+  /// template-id.
+  const TemplateArgumentLoc *getTemplateArgs() const {
+    return getExplicitTemplateArgs().getTemplateArgs();
+  }
+
+  /// \brief Retrieve the number of template arguments provided as
+  /// part of this template-id.
+  unsigned getNumTemplateArgs() const {
+    return getExplicitTemplateArgs().NumTemplateArgs;
+  }
+
+  /// \brief Retrieve the location of the right angle bracket
+  /// following the template arguments ('>').
+  SourceLocation getRAngleLoc() const {
+    return getExplicitTemplateArgs().RAngleLoc;
+  }
+
+  virtual SourceRange getSourceRange() const {
+    SourceRange Range;
+    if (!isImplicitAccess())
+      Range.setBegin(Base->getSourceRange().getBegin());
+    else if (getQualifier())
+      Range.setBegin(getQualifierRange().getBegin());
+    else
+      Range.setBegin(getMemberLoc());
+
+    if (hasExplicitTemplateArgs())
+      Range.setEnd(getRAngleLoc());
+    else
+      Range.setEnd(getMemberLoc());
+    return Range;
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == UnresolvedMemberExprClass;
+  }
+  static bool classof(const UnresolvedMemberExpr *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+inline ExplicitTemplateArgumentList &OverloadExpr::getExplicitTemplateArgs() {
+  if (isa<UnresolvedLookupExpr>(this))
+    return cast<UnresolvedLookupExpr>(this)->getExplicitTemplateArgs();
+  else
+    return cast<UnresolvedMemberExpr>(this)->getExplicitTemplateArgs();
+}
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/AST/ExprObjC.h b/include/clang/AST/ExprObjC.h
new file mode 100644
index 0000000..8a09f4e
--- /dev/null
+++ b/include/clang/AST/ExprObjC.h
@@ -0,0 +1,815 @@
+//===--- ExprObjC.h - Classes for representing ObjC expressions -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the ExprObjC interface and subclasses.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_EXPROBJC_H
+#define LLVM_CLANG_AST_EXPROBJC_H
+
+#include "clang/AST/Expr.h"
+#include "clang/Basic/IdentifierTable.h"
+
+namespace clang {
+  class IdentifierInfo;
+  class ASTContext;
+  class ObjCMethodDecl;
+  class ObjCPropertyDecl;
+
+/// ObjCStringLiteral, used for Objective-C string literals
+/// i.e. @"foo".
+class ObjCStringLiteral : public Expr {
+  Stmt *String;
+  SourceLocation AtLoc;
+public:
+  ObjCStringLiteral(StringLiteral *SL, QualType T, SourceLocation L)
+    : Expr(ObjCStringLiteralClass, T, false, false), String(SL), AtLoc(L) {}
+  explicit ObjCStringLiteral(EmptyShell Empty)
+    : Expr(ObjCStringLiteralClass, Empty) {}
+
+  StringLiteral *getString() { return cast<StringLiteral>(String); }
+  const StringLiteral *getString() const { return cast<StringLiteral>(String); }
+  void setString(StringLiteral *S) { String = S; }
+
+  SourceLocation getAtLoc() const { return AtLoc; }
+  void setAtLoc(SourceLocation L) { AtLoc = L; }
+
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(AtLoc, String->getLocEnd());
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ObjCStringLiteralClass;
+  }
+  static bool classof(const ObjCStringLiteral *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+/// ObjCEncodeExpr, used for @encode in Objective-C.  @encode has the same type
+/// and behavior as StringLiteral except that the string initializer is obtained
+/// from ASTContext with the encoding type as an argument.
+class ObjCEncodeExpr : public Expr {
+  TypeSourceInfo *EncodedType;
+  SourceLocation AtLoc, RParenLoc;
+public:
+  ObjCEncodeExpr(QualType T, TypeSourceInfo *EncodedType,
+                 SourceLocation at, SourceLocation rp)
+    : Expr(ObjCEncodeExprClass, T, EncodedType->getType()->isDependentType(),
+           EncodedType->getType()->isDependentType()), 
+      EncodedType(EncodedType), AtLoc(at), RParenLoc(rp) {}
+
+  explicit ObjCEncodeExpr(EmptyShell Empty) : Expr(ObjCEncodeExprClass, Empty){}
+
+
+  SourceLocation getAtLoc() const { return AtLoc; }
+  void setAtLoc(SourceLocation L) { AtLoc = L; }
+  SourceLocation getRParenLoc() const { return RParenLoc; }
+  void setRParenLoc(SourceLocation L) { RParenLoc = L; }
+
+  QualType getEncodedType() const { return EncodedType->getType(); }
+
+  TypeSourceInfo *getEncodedTypeSourceInfo() const { return EncodedType; }
+  void setEncodedTypeSourceInfo(TypeSourceInfo *EncType) { 
+    EncodedType = EncType; 
+  }
+
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(AtLoc, RParenLoc);
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ObjCEncodeExprClass;
+  }
+  static bool classof(const ObjCEncodeExpr *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+/// ObjCSelectorExpr used for @selector in Objective-C.
+class ObjCSelectorExpr : public Expr {
+  Selector SelName;
+  SourceLocation AtLoc, RParenLoc;
+public:
+  ObjCSelectorExpr(QualType T, Selector selInfo,
+                   SourceLocation at, SourceLocation rp)
+  : Expr(ObjCSelectorExprClass, T, false, false), SelName(selInfo), AtLoc(at),
+    RParenLoc(rp){}
+  explicit ObjCSelectorExpr(EmptyShell Empty)
+   : Expr(ObjCSelectorExprClass, Empty) {}
+
+  Selector getSelector() const { return SelName; }
+  void setSelector(Selector S) { SelName = S; }
+
+  SourceLocation getAtLoc() const { return AtLoc; }
+  SourceLocation getRParenLoc() const { return RParenLoc; }
+  void setAtLoc(SourceLocation L) { AtLoc = L; }
+  void setRParenLoc(SourceLocation L) { RParenLoc = L; }
+
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(AtLoc, RParenLoc);
+  }
+
+  /// getNumArgs - Return the number of actual arguments to this call.
+  unsigned getNumArgs() const { return SelName.getNumArgs(); }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ObjCSelectorExprClass;
+  }
+  static bool classof(const ObjCSelectorExpr *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+/// ObjCProtocolExpr used for protocol expression in Objective-C.  This is used
+/// as: @protocol(foo), as in:
+///   obj conformsToProtocol:@protocol(foo)]
+/// The return type is "Protocol*".
+class ObjCProtocolExpr : public Expr {
+  ObjCProtocolDecl *TheProtocol;
+  SourceLocation AtLoc, RParenLoc;
+public:
+  ObjCProtocolExpr(QualType T, ObjCProtocolDecl *protocol,
+                   SourceLocation at, SourceLocation rp)
+  : Expr(ObjCProtocolExprClass, T, false, false), TheProtocol(protocol),
+    AtLoc(at), RParenLoc(rp) {}
+  explicit ObjCProtocolExpr(EmptyShell Empty)
+    : Expr(ObjCProtocolExprClass, Empty) {}
+
+  ObjCProtocolDecl *getProtocol() const { return TheProtocol; }
+  void setProtocol(ObjCProtocolDecl *P) { TheProtocol = P; }
+
+  SourceLocation getAtLoc() const { return AtLoc; }
+  SourceLocation getRParenLoc() const { return RParenLoc; }
+  void setAtLoc(SourceLocation L) { AtLoc = L; }
+  void setRParenLoc(SourceLocation L) { RParenLoc = L; }
+
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(AtLoc, RParenLoc);
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ObjCProtocolExprClass;
+  }
+  static bool classof(const ObjCProtocolExpr *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+/// ObjCIvarRefExpr - A reference to an ObjC instance variable.
+class ObjCIvarRefExpr : public Expr {
+  class ObjCIvarDecl *D;
+  SourceLocation Loc;
+  Stmt *Base;
+  bool IsArrow:1;      // True if this is "X->F", false if this is "X.F".
+  bool IsFreeIvar:1;   // True if ivar reference has no base (self assumed).
+
+public:
+  ObjCIvarRefExpr(ObjCIvarDecl *d,
+                  QualType t, SourceLocation l, Expr *base,
+                  bool arrow = false, bool freeIvar = false) :
+    Expr(ObjCIvarRefExprClass, t, /*TypeDependent=*/false,
+         base->isValueDependent()), D(d),
+         Loc(l), Base(base), IsArrow(arrow),
+         IsFreeIvar(freeIvar) {}
+
+  explicit ObjCIvarRefExpr(EmptyShell Empty)
+    : Expr(ObjCIvarRefExprClass, Empty) {}
+
+  ObjCIvarDecl *getDecl() { return D; }
+  const ObjCIvarDecl *getDecl() const { return D; }
+  void setDecl(ObjCIvarDecl *d) { D = d; }
+
+  const Expr *getBase() const { return cast<Expr>(Base); }
+  Expr *getBase() { return cast<Expr>(Base); }
+  void setBase(Expr * base) { Base = base; }
+
+  bool isArrow() const { return IsArrow; }
+  bool isFreeIvar() const { return IsFreeIvar; }
+  void setIsArrow(bool A) { IsArrow = A; }
+  void setIsFreeIvar(bool A) { IsFreeIvar = A; }
+
+  SourceLocation getLocation() const { return Loc; }
+  void setLocation(SourceLocation L) { Loc = L; }
+
+  virtual SourceRange getSourceRange() const {
+    return isFreeIvar() ? SourceRange(Loc)
+    : SourceRange(getBase()->getLocStart(), Loc);
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ObjCIvarRefExprClass;
+  }
+  static bool classof(const ObjCIvarRefExpr *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+/// ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC
+/// property.
+///
+class ObjCPropertyRefExpr : public Expr {
+private:
+  ObjCPropertyDecl *AsProperty;
+  SourceLocation IdLoc;
+  Stmt *Base;
+public:
+  ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t,
+                      SourceLocation l, Expr *base)
+    : Expr(ObjCPropertyRefExprClass, t, /*TypeDependent=*/false, 
+           base->isValueDependent()), 
+      AsProperty(PD), IdLoc(l), Base(base) {
+  }
+
+  explicit ObjCPropertyRefExpr(EmptyShell Empty)
+    : Expr(ObjCPropertyRefExprClass, Empty) {}
+
+  ObjCPropertyDecl *getProperty() const { return AsProperty; }
+  void setProperty(ObjCPropertyDecl *D) { AsProperty = D; }
+
+  const Expr *getBase() const { return cast<Expr>(Base); }
+  Expr *getBase() { return cast<Expr>(Base); }
+  void setBase(Expr *base) { Base = base; }
+
+  SourceLocation getLocation() const { return IdLoc; }
+  void setLocation(SourceLocation L) { IdLoc = L; }
+
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(getBase()->getLocStart(), IdLoc);
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ObjCPropertyRefExprClass;
+  }
+  static bool classof(const ObjCPropertyRefExpr *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+/// ObjCImplicitSetterGetterRefExpr - A dot-syntax expression to access two
+/// methods; one to set a value to an 'ivar' (Setter) and the other to access
+/// an 'ivar' (Setter).
+/// An example for use of this AST is:
+/// @code
+///  @interface Test { }
+///  - (Test *)crash;
+///  - (void)setCrash: (Test*)value;
+/// @end
+/// void  foo(Test *p1, Test *p2)
+/// {
+///    p2.crash  = p1.crash; // Uses ObjCImplicitSetterGetterRefExpr AST
+/// }
+/// @endcode
+class ObjCImplicitSetterGetterRefExpr : public Expr {
+  /// Setter - Setter method user declared for setting its 'ivar' to a value
+  ObjCMethodDecl *Setter;
+  /// Getter - Getter method user declared for accessing 'ivar' it controls.
+  ObjCMethodDecl *Getter;
+  /// Location of the member in the dot syntax notation. This is location
+  /// of the getter method.
+  SourceLocation MemberLoc;
+  // FIXME: Swizzle these into a single pointer.
+  Stmt *Base;
+  ObjCInterfaceDecl *InterfaceDecl;
+  /// Location of the receiver class in the dot syntax notation
+  /// used to call a class method setter/getter.
+  SourceLocation ClassLoc;
+
+public:
+  ObjCImplicitSetterGetterRefExpr(ObjCMethodDecl *getter,
+                 QualType t,
+                 ObjCMethodDecl *setter,
+                 SourceLocation l, Expr *base)
+    : Expr(ObjCImplicitSetterGetterRefExprClass, t, /*TypeDependent=*/false, 
+           base->isValueDependent()),
+      Setter(setter), Getter(getter), MemberLoc(l), Base(base),
+      InterfaceDecl(0), ClassLoc(SourceLocation()) {
+    }
+  ObjCImplicitSetterGetterRefExpr(ObjCMethodDecl *getter,
+                 QualType t,
+                 ObjCMethodDecl *setter,
+                 SourceLocation l, ObjCInterfaceDecl *C, SourceLocation CL)
+    : Expr(ObjCImplicitSetterGetterRefExprClass, t, false, false),
+      Setter(setter), Getter(getter), MemberLoc(l), Base(0), InterfaceDecl(C),
+      ClassLoc(CL) {
+    }
+  explicit ObjCImplicitSetterGetterRefExpr(EmptyShell Empty)
+           : Expr(ObjCImplicitSetterGetterRefExprClass, Empty){}
+
+  ObjCMethodDecl *getGetterMethod() const { return Getter; }
+  ObjCMethodDecl *getSetterMethod() const { return Setter; }
+  ObjCInterfaceDecl *getInterfaceDecl() const { return InterfaceDecl; }
+  void setGetterMethod(ObjCMethodDecl *D) { Getter = D; }
+  void setSetterMethod(ObjCMethodDecl *D) { Setter = D; }
+  void setInterfaceDecl(ObjCInterfaceDecl *D) { InterfaceDecl = D; }
+
+  virtual SourceRange getSourceRange() const {
+    if (Base)
+      return SourceRange(getBase()->getLocStart(), MemberLoc);
+    return SourceRange(ClassLoc, MemberLoc);
+  }
+  const Expr *getBase() const { return cast_or_null<Expr>(Base); }
+  Expr *getBase() { return cast_or_null<Expr>(Base); }
+  void setBase(Expr *base) { Base = base; }
+
+  SourceLocation getLocation() const { return MemberLoc; }
+  void setLocation(SourceLocation L) { MemberLoc = L; }
+  SourceLocation getClassLoc() const { return ClassLoc; }
+  void setClassLoc(SourceLocation L) { ClassLoc = L; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ObjCImplicitSetterGetterRefExprClass;
+  }
+  static bool classof(const ObjCImplicitSetterGetterRefExpr *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+/// \brief An expression that sends a message to the given Objective-C
+/// object or class.
+///
+/// The following contains two message send expressions:
+///
+/// \code
+///   [[NSString alloc] initWithString:@"Hello"]
+/// \endcode
+///
+/// The innermost message send invokes the "alloc" class method on the
+/// NSString class, while the outermost message send invokes the
+/// "initWithString" instance method on the object returned from
+/// NSString's "alloc". In all, an Objective-C message send can take
+/// on four different (although related) forms:
+///
+///   1. Send to an object instance.
+///   2. Send to a class.
+///   3. Send to the superclass instance of the current class.
+///   4. Send to the superclass of the current class.
+///
+/// All four kinds of message sends are modeled by the ObjCMessageExpr
+/// class, and can be distinguished via \c getReceiverKind(). Example:
+///
+class ObjCMessageExpr : public Expr {
+  /// \brief The number of arguments in the message send, not
+  /// including the receiver.
+  unsigned NumArgs : 16;
+
+  /// \brief The kind of message send this is, which is one of the
+  /// ReceiverKind values.
+  ///
+  /// We pad this out to a byte to avoid excessive masking and shifting.
+  unsigned Kind : 8;
+
+  /// \brief Whether we have an actual method prototype in \c
+  /// SelectorOrMethod.
+  ///
+  /// When non-zero, we have a method declaration; otherwise, we just
+  /// have a selector.
+  unsigned HasMethod : 8;
+
+  /// \brief When the message expression is a send to 'super', this is
+  /// the location of the 'super' keyword.
+  SourceLocation SuperLoc;
+
+  /// \brief Stores either the selector that this message is sending
+  /// to (when \c HasMethod is zero) or an \c ObjCMethodDecl pointer
+  /// referring to the method that we type-checked against.
+  uintptr_t SelectorOrMethod;
+
+  /// \brief The source locations of the open and close square
+  /// brackets ('[' and ']', respectively).
+  SourceLocation LBracLoc, RBracLoc;
+
+  ObjCMessageExpr(EmptyShell Empty, unsigned NumArgs)
+    : Expr(ObjCMessageExprClass, Empty), NumArgs(NumArgs), Kind(0), 
+      HasMethod(0), SelectorOrMethod(0) { }
+
+  ObjCMessageExpr(QualType T,
+                  SourceLocation LBracLoc,
+                  SourceLocation SuperLoc,
+                  bool IsInstanceSuper,
+                  QualType SuperType,
+                  Selector Sel, 
+                  ObjCMethodDecl *Method,
+                  Expr **Args, unsigned NumArgs,
+                  SourceLocation RBracLoc);
+  ObjCMessageExpr(QualType T,
+                  SourceLocation LBracLoc,
+                  TypeSourceInfo *Receiver,
+                  Selector Sel, 
+                  ObjCMethodDecl *Method,
+                  Expr **Args, unsigned NumArgs,
+                  SourceLocation RBracLoc);
+  ObjCMessageExpr(QualType T,
+                  SourceLocation LBracLoc,
+                  Expr *Receiver,
+                  Selector Sel, 
+                  ObjCMethodDecl *Method,
+                  Expr **Args, unsigned NumArgs,
+                  SourceLocation RBracLoc);
+
+  /// \brief Retrieve the pointer value of the message receiver.
+  void *getReceiverPointer() const {
+    return *const_cast<void **>(
+                             reinterpret_cast<const void * const*>(this + 1));
+  }
+
+  /// \brief Set the pointer value of the message receiver.
+  void setReceiverPointer(void *Value) {
+    *reinterpret_cast<void **>(this + 1) = Value;
+  }
+
+public:
+  /// \brief The kind of receiver this message is sending to.
+  enum ReceiverKind {
+    /// \brief The receiver is a class.
+    Class = 0,
+    /// \brief The receiver is an object instance.
+    Instance,
+    /// \brief The receiver is a superclass.
+    SuperClass,
+    /// \brief The receiver is the instance of the superclass object.
+    SuperInstance
+  };
+
+  /// \brief Create a message send to super.
+  ///
+  /// \param Context The ASTContext in which this expression will be created.
+  ///
+  /// \param T The result type of this message.
+  ///
+  /// \param LBrac The location of the open square bracket '['.
+  ///
+  /// \param SuperLoc The location of the "super" keyword.
+  ///
+  /// \param IsInstanceSuper Whether this is an instance "super"
+  /// message (otherwise, it's a class "super" message).
+  ///
+  /// \param Sel The selector used to determine which method gets called.
+  ///
+  /// \param Method The Objective-C method against which this message
+  /// send was type-checked. May be NULL.
+  ///
+  /// \param Args The message send arguments.
+  ///
+  /// \param NumArgs The number of arguments.
+  ///
+  /// \param RBracLoc The location of the closing square bracket ']'.
+  static ObjCMessageExpr *Create(ASTContext &Context, QualType T,
+                                 SourceLocation LBracLoc,
+                                 SourceLocation SuperLoc,
+                                 bool IsInstanceSuper,
+                                 QualType SuperType,
+                                 Selector Sel, 
+                                 ObjCMethodDecl *Method,
+                                 Expr **Args, unsigned NumArgs,
+                                 SourceLocation RBracLoc);
+
+  /// \brief Create a class message send.
+  ///
+  /// \param Context The ASTContext in which this expression will be created.
+  ///
+  /// \param T The result type of this message.
+  ///
+  /// \param LBrac The location of the open square bracket '['.
+  ///
+  /// \param Receiver The type of the receiver, including
+  /// source-location information.
+  ///
+  /// \param Sel The selector used to determine which method gets called.
+  ///
+  /// \param Method The Objective-C method against which this message
+  /// send was type-checked. May be NULL.
+  ///
+  /// \param Args The message send arguments.
+  ///
+  /// \param NumArgs The number of arguments.
+  ///
+  /// \param RBracLoc The location of the closing square bracket ']'.
+  static ObjCMessageExpr *Create(ASTContext &Context, QualType T,
+                                 SourceLocation LBracLoc,
+                                 TypeSourceInfo *Receiver,
+                                 Selector Sel, 
+                                 ObjCMethodDecl *Method,
+                                 Expr **Args, unsigned NumArgs,
+                                 SourceLocation RBracLoc);
+
+  /// \brief Create an instance message send.
+  ///
+  /// \param Context The ASTContext in which this expression will be created.
+  ///
+  /// \param T The result type of this message.
+  ///
+  /// \param LBrac The location of the open square bracket '['.
+  ///
+  /// \param Receiver The expression used to produce the object that
+  /// will receive this message.
+  ///
+  /// \param Sel The selector used to determine which method gets called.
+  ///
+  /// \param Method The Objective-C method against which this message
+  /// send was type-checked. May be NULL.
+  ///
+  /// \param Args The message send arguments.
+  ///
+  /// \param NumArgs The number of arguments.
+  ///
+  /// \param RBracLoc The location of the closing square bracket ']'.
+  static ObjCMessageExpr *Create(ASTContext &Context, QualType T,
+                                 SourceLocation LBracLoc,
+                                 Expr *Receiver,
+                                 Selector Sel, 
+                                 ObjCMethodDecl *Method,
+                                 Expr **Args, unsigned NumArgs,
+                                 SourceLocation RBracLoc);
+
+  /// \brief Create an empty Objective-C message expression, to be
+  /// filled in by subsequent calls.
+  ///
+  /// \param Context The context in which the message send will be created.
+  ///
+  /// \param NumArgs The number of message arguments, not including
+  /// the receiver.
+  static ObjCMessageExpr *CreateEmpty(ASTContext &Context, unsigned NumArgs);
+
+  /// \brief Determine the kind of receiver that this message is being
+  /// sent to.
+  ReceiverKind getReceiverKind() const { return (ReceiverKind)Kind; }
+
+  /// \brief Determine whether this is an instance message to either a
+  /// computed object or to super.
+  bool isInstanceMessage() const {
+    return getReceiverKind() == Instance || getReceiverKind() == SuperInstance;
+  }
+
+  /// \brief Determine whether this is an class message to either a
+  /// specified class or to super.
+  bool isClassMessage() const {
+    return getReceiverKind() == Class || getReceiverKind() == SuperClass;
+  }
+
+  /// \brief Returns the receiver of an instance message.
+  ///
+  /// \brief Returns the object expression for an instance message, or
+  /// NULL for a message that is not an instance message.
+  Expr *getInstanceReceiver() {
+    if (getReceiverKind() == Instance)
+      return static_cast<Expr *>(getReceiverPointer());
+
+    return 0;
+  }
+  const Expr *getInstanceReceiver() const {
+    return const_cast<ObjCMessageExpr*>(this)->getInstanceReceiver();
+  }
+
+  /// \brief Turn this message send into an instance message that
+  /// computes the receiver object with the given expression.
+  void setInstanceReceiver(Expr *rec) { 
+    Kind = Instance;
+    setReceiverPointer(rec);
+  }
+  
+  /// \brief Returns the type of a class message send, or NULL if the
+  /// message is not a class message.
+  QualType getClassReceiver() const { 
+    if (TypeSourceInfo *TSInfo = getClassReceiverTypeInfo())
+      return TSInfo->getType();
+
+    return QualType();
+  }
+
+  /// \brief Returns a type-source information of a class message
+  /// send, or NULL if the message is not a class message.
+  TypeSourceInfo *getClassReceiverTypeInfo() const {
+    if (getReceiverKind() == Class)
+      return reinterpret_cast<TypeSourceInfo *>(getReceiverPointer());
+    return 0;
+  }
+
+  void setClassReceiver(TypeSourceInfo *TSInfo) {
+    Kind = Class;
+    setReceiverPointer(TSInfo);
+  }
+
+  /// \brief Retrieve the location of the 'super' keyword for a class
+  /// or instance message to 'super', otherwise an invalid source location.
+  SourceLocation getSuperLoc() const { 
+    if (getReceiverKind() == SuperInstance || getReceiverKind() == SuperClass)
+      return SuperLoc;
+
+    return SourceLocation();
+  }
+
+  /// \brief Retrieve the Objective-C interface to which this message
+  /// is being directed, if known.
+  ///
+  /// This routine cross-cuts all of the different kinds of message
+  /// sends to determine what the underlying (statically known) type
+  /// of the receiver will be; use \c getReceiverKind() to determine
+  /// whether the message is a class or an instance method, whether it
+  /// is a send to super or not, etc.
+  ///
+  /// \returns The Objective-C interface if known, otherwise NULL.
+  ObjCInterfaceDecl *getReceiverInterface() const;
+
+  /// \brief Retrieve the type referred to by 'super'. 
+  ///
+  /// The returned type will either be an ObjCInterfaceType (for an
+  /// class message to super) or an ObjCObjectPointerType that refers
+  /// to a class (for an instance message to super);
+  QualType getSuperType() const {
+    if (getReceiverKind() == SuperInstance || getReceiverKind() == SuperClass)
+      return QualType::getFromOpaquePtr(getReceiverPointer());
+
+    return QualType();
+  }
+
+  void setSuper(SourceLocation Loc, QualType T, bool IsInstanceSuper) {
+    Kind = IsInstanceSuper? SuperInstance : SuperClass;
+    SuperLoc = Loc;
+    setReceiverPointer(T.getAsOpaquePtr());
+  }
+
+  Selector getSelector() const;
+
+  void setSelector(Selector S) { 
+    HasMethod = false;
+    SelectorOrMethod = reinterpret_cast<uintptr_t>(S.getAsOpaquePtr());
+  }
+
+  const ObjCMethodDecl *getMethodDecl() const { 
+    if (HasMethod)
+      return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod);
+
+    return 0;
+  }
+
+  ObjCMethodDecl *getMethodDecl() { 
+    if (HasMethod)
+      return reinterpret_cast<ObjCMethodDecl *>(SelectorOrMethod);
+
+    return 0;
+  }
+
+  void setMethodDecl(ObjCMethodDecl *MD) { 
+    HasMethod = true;
+    SelectorOrMethod = reinterpret_cast<uintptr_t>(MD);
+  }
+
+  /// \brief Return the number of actual arguments in this message,
+  /// not counting the receiver.
+  unsigned getNumArgs() const { return NumArgs; }
+
+  /// \brief Retrieve the arguments to this message, not including the
+  /// receiver.
+  Stmt **getArgs() {
+    return reinterpret_cast<Stmt **>(this + 1) + 1;
+  }
+  const Stmt * const *getArgs() const {
+    return reinterpret_cast<const Stmt * const *>(this + 1) + 1;
+  }
+
+  /// getArg - Return the specified argument.
+  Expr *getArg(unsigned Arg) {
+    assert(Arg < NumArgs && "Arg access out of range!");
+    return cast<Expr>(getArgs()[Arg]);
+  }
+  const Expr *getArg(unsigned Arg) const {
+    assert(Arg < NumArgs && "Arg access out of range!");
+    return cast<Expr>(getArgs()[Arg]);
+  }
+  /// setArg - Set the specified argument.
+  void setArg(unsigned Arg, Expr *ArgExpr) {
+    assert(Arg < NumArgs && "Arg access out of range!");
+    getArgs()[Arg] = ArgExpr;
+  }
+
+  SourceLocation getLeftLoc() const { return LBracLoc; }
+  SourceLocation getRightLoc() const { return RBracLoc; }
+
+  void setLeftLoc(SourceLocation L) { LBracLoc = L; }
+  void setRightLoc(SourceLocation L) { RBracLoc = L; }
+
+  void setSourceRange(SourceRange R) {
+    LBracLoc = R.getBegin();
+    RBracLoc = R.getEnd();
+  }
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(LBracLoc, RBracLoc);
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ObjCMessageExprClass;
+  }
+  static bool classof(const ObjCMessageExpr *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+
+  typedef ExprIterator arg_iterator;
+  typedef ConstExprIterator const_arg_iterator;
+
+  arg_iterator arg_begin() { return getArgs(); }
+  arg_iterator arg_end()   { return getArgs() + NumArgs; }
+  const_arg_iterator arg_begin() const { return getArgs(); }
+  const_arg_iterator arg_end() const { return getArgs() + NumArgs; }
+};
+
+/// ObjCSuperExpr - Represents the "super" expression in Objective-C,
+/// which refers to the object on which the current method is executing.
+///
+/// FIXME: This class is intended for removal, once its remaining
+/// clients have been altered to represent "super" internally.
+class ObjCSuperExpr : public Expr {
+  SourceLocation Loc;
+public:
+  ObjCSuperExpr(SourceLocation L, QualType Type)
+    : Expr(ObjCSuperExprClass, Type, false, false), Loc(L) { }
+  explicit ObjCSuperExpr(EmptyShell Empty) : Expr(ObjCSuperExprClass, Empty) {}
+
+  SourceLocation getLoc() const { return Loc; }
+  void setLoc(SourceLocation L) { Loc = L; }
+
+  virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ObjCSuperExprClass;
+  }
+  static bool classof(const ObjCSuperExpr *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+/// ObjCIsaExpr - Represent X->isa and X.isa when X is an ObjC 'id' type.
+/// (similiar in spirit to MemberExpr).
+class ObjCIsaExpr : public Expr {
+  /// Base - the expression for the base object pointer.
+  Stmt *Base;
+
+  /// IsaMemberLoc - This is the location of the 'isa'.
+  SourceLocation IsaMemberLoc;
+
+  /// IsArrow - True if this is "X->F", false if this is "X.F".
+  bool IsArrow;
+public:
+  ObjCIsaExpr(Expr *base, bool isarrow, SourceLocation l, QualType ty)
+    : Expr(ObjCIsaExprClass, ty, /*TypeDependent=*/false, 
+           base->isValueDependent()),
+      Base(base), IsaMemberLoc(l), IsArrow(isarrow) {}
+
+  /// \brief Build an empty expression.
+  explicit ObjCIsaExpr(EmptyShell Empty) : Expr(ObjCIsaExprClass, Empty) { }
+
+  void setBase(Expr *E) { Base = E; }
+  Expr *getBase() const { return cast<Expr>(Base); }
+
+  bool isArrow() const { return IsArrow; }
+  void setArrow(bool A) { IsArrow = A; }
+
+  /// getMemberLoc - Return the location of the "member", in X->F, it is the
+  /// location of 'F'.
+  SourceLocation getIsaMemberLoc() const { return IsaMemberLoc; }
+  void setIsaMemberLoc(SourceLocation L) { IsaMemberLoc = L; }
+
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(getBase()->getLocStart(), IsaMemberLoc);
+  }
+
+  virtual SourceLocation getExprLoc() const { return IsaMemberLoc; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ObjCIsaExprClass;
+  }
+  static bool classof(const ObjCIsaExpr *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/AST/ExternalASTSource.h b/include/clang/AST/ExternalASTSource.h
new file mode 100644
index 0000000..79e4451
--- /dev/null
+++ b/include/clang/AST/ExternalASTSource.h
@@ -0,0 +1,192 @@
+//===--- ExternalASTSource.h - Abstract External AST Interface --*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the ExternalASTSource interface, which enables
+//  construction of AST nodes from some external source.x
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_AST_EXTERNAL_AST_SOURCE_H
+#define LLVM_CLANG_AST_EXTERNAL_AST_SOURCE_H
+
+#include "clang/AST/DeclarationName.h"
+#include "clang/AST/Type.h"
+#include "llvm/ADT/SmallVector.h"
+#include <cassert>
+#include <vector>
+namespace clang {
+
+class ASTConsumer;
+class Decl;
+class DeclContext;
+class ExternalSemaSource; // layering violation required for downcasting
+class Stmt;
+
+/// \brief The deserialized representation of a set of declarations
+/// with the same name that are visible in a given context.
+struct VisibleDeclaration {
+  /// \brief The name of the declarations.
+  DeclarationName Name;
+
+  /// \brief The ID numbers of all of the declarations with this name.
+  ///
+  /// These declarations have not necessarily been de-serialized.
+  llvm::SmallVector<unsigned, 4> Declarations;
+};
+
+/// \brief Abstract interface for external sources of AST nodes.
+///
+/// External AST sources provide AST nodes constructed from some
+/// external source, such as a precompiled header. External AST
+/// sources can resolve types and declarations from abstract IDs into
+/// actual type and declaration nodes, and read parts of declaration
+/// contexts.
+class ExternalASTSource {
+  /// \brief Whether this AST source also provides information for
+  /// semantic analysis.
+  bool SemaSource;
+
+  friend class ExternalSemaSource;
+
+public:
+  ExternalASTSource() : SemaSource(false) { }
+
+  virtual ~ExternalASTSource();
+
+  /// \brief Resolve a type ID into a type, potentially building a new
+  /// type.
+  virtual QualType GetType(uint32_t ID) = 0;
+
+  /// \brief Resolve a declaration ID into a declaration, potentially
+  /// building a new declaration.
+  virtual Decl *GetDecl(uint32_t ID) = 0;
+
+  /// \brief Resolve a selector ID into a selector.
+  virtual Selector GetSelector(uint32_t ID) = 0;
+
+  /// \brief Returns the number of selectors known to the external AST
+  /// source.
+  virtual uint32_t GetNumKnownSelectors() = 0;
+
+  /// \brief Resolve the offset of a statement in the decl stream into a
+  /// statement.
+  ///
+  /// This operation will read a new statement from the external
+  /// source each time it is called, and is meant to be used via a
+  /// LazyOffsetPtr.
+  virtual Stmt *GetDeclStmt(uint64_t Offset) = 0;
+
+  /// \brief Read all of the declarations lexically stored in a
+  /// declaration context.
+  ///
+  /// \param DC The declaration context whose declarations will be
+  /// read.
+  ///
+  /// \param Decls Vector that will contain the declarations loaded
+  /// from the external source. The caller is responsible for merging
+  /// these declarations with any declarations already stored in the
+  /// declaration context.
+  ///
+  /// \returns true if there was an error while reading the
+  /// declarations for this declaration context.
+  virtual bool ReadDeclsLexicallyInContext(DeclContext *DC,
+                                  llvm::SmallVectorImpl<uint32_t> &Decls) = 0;
+
+  /// \brief Read all of the declarations visible from a declaration
+  /// context.
+  ///
+  /// \param DC The declaration context whose visible declarations
+  /// will be read.
+  ///
+  /// \param Decls A vector of visible declaration structures,
+  /// providing the mapping from each name visible in the declaration
+  /// context to the declaration IDs of declarations with that name.
+  ///
+  /// \returns true if there was an error while reading the
+  /// declarations for this declaration context.
+  virtual bool ReadDeclsVisibleInContext(DeclContext *DC,
+                       llvm::SmallVectorImpl<VisibleDeclaration> & Decls) = 0;
+
+  /// \brief Function that will be invoked when we begin parsing a new
+  /// translation unit involving this external AST source.
+  virtual void StartTranslationUnit(ASTConsumer *Consumer) { }
+
+  /// \brief Print any statistics that have been gathered regarding
+  /// the external AST source.
+  virtual void PrintStats();
+};
+
+/// \brief A lazy pointer to an AST node (of base type T) that resides
+/// within an external AST source.
+///
+/// The AST node is identified within the external AST source by a
+/// 63-bit offset, and can be retrieved via an operation on the
+/// external AST source itself.
+template<typename T, T* (ExternalASTSource::*Get)(uint64_t Offset)>
+struct LazyOffsetPtr {
+  /// \brief Either a pointer to an AST node or the offset within the
+  /// external AST source where the AST node can be found.
+  ///
+  /// If the low bit is clear, a pointer to the AST node. If the low
+  /// bit is set, the upper 63 bits are the offset.
+  mutable uint64_t Ptr;
+
+public:
+  LazyOffsetPtr() : Ptr(0) { }
+
+  explicit LazyOffsetPtr(T *Ptr) : Ptr(reinterpret_cast<uint64_t>(Ptr)) { }
+  explicit LazyOffsetPtr(uint64_t Offset) : Ptr((Offset << 1) | 0x01) {
+    assert((Offset << 1 >> 1) == Offset && "Offsets must require < 63 bits");
+    if (Offset == 0)
+      Ptr = 0;
+  }
+
+  LazyOffsetPtr &operator=(T *Ptr) {
+    this->Ptr = reinterpret_cast<uint64_t>(Ptr);
+    return *this;
+  }
+
+  LazyOffsetPtr &operator=(uint64_t Offset) {
+    assert((Offset << 1 >> 1) == Offset && "Offsets must require < 63 bits");
+    if (Offset == 0)
+      Ptr = 0;
+    else
+      Ptr = (Offset << 1) | 0x01;
+
+    return *this;
+  }
+
+  /// \brief Whether this pointer is non-NULL.
+  ///
+  /// This operation does not require the AST node to be deserialized.
+  operator bool() const { return Ptr != 0; }
+
+  /// \brief Whether this pointer is currently stored as an offset.
+  bool isOffset() const { return Ptr & 0x01; }
+
+  /// \brief Retrieve the pointer to the AST node that this lazy pointer
+  ///
+  /// \param Source the external AST source.
+  ///
+  /// \returns a pointer to the AST node.
+  T* get(ExternalASTSource *Source) const {
+    if (isOffset()) {
+      assert(Source &&
+             "Cannot deserialize a lazy pointer without an AST source");
+      Ptr = reinterpret_cast<uint64_t>((Source->*Get)(Ptr >> 1));
+    }
+    return reinterpret_cast<T*>(Ptr);
+  }
+};
+
+/// \brief A lazy pointer to a statement.
+typedef LazyOffsetPtr<Stmt, &ExternalASTSource::GetDeclStmt> LazyDeclStmtPtr;
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_AST_EXTERNAL_AST_SOURCE_H
diff --git a/include/clang/AST/FullExpr.h b/include/clang/AST/FullExpr.h
new file mode 100644
index 0000000..bb81bf0
--- /dev/null
+++ b/include/clang/AST/FullExpr.h
@@ -0,0 +1,89 @@
+//===--- FullExpr.h - C++ full expression class -----------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the FullExpr interface, to be used for type safe handling
+//  of full expressions.
+//
+//  Full expressions are described in C++ [intro.execution]p12.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_AST_FULLEXPR_H
+#define LLVM_CLANG_AST_FULLEXPR_H
+
+#include "llvm/ADT/PointerUnion.h"
+
+namespace clang {
+  class ASTContext;
+  class CXXTemporary;
+  class Expr;
+
+class FullExpr {
+  struct ExprAndTemporaries {
+    Expr *SubExpr;
+    
+    unsigned NumTemps;
+    
+    typedef CXXTemporary** temps_iterator;
+    
+    temps_iterator temps_begin() { 
+      return reinterpret_cast<CXXTemporary **>(this + 1); 
+    }
+    temps_iterator temps_end() { 
+      return temps_begin() + NumTemps;
+    }
+  };
+
+  typedef llvm::PointerUnion<Expr *, ExprAndTemporaries *> SubExprTy;
+  SubExprTy SubExpr;
+  
+  FullExpr() { }
+
+public:
+  static FullExpr Create(ASTContext &Context, Expr *SubExpr, 
+                         CXXTemporary **Temps, unsigned NumTemps);
+  void Destroy(ASTContext &Context);
+  
+  Expr *getExpr() {
+    if (Expr *E = SubExpr.dyn_cast<Expr *>())
+      return E;
+    
+    return SubExpr.get<ExprAndTemporaries *>()->SubExpr;
+  }
+  
+  const Expr *getExpr() const { 
+    return const_cast<FullExpr*>(this)->getExpr();
+  }
+  
+  typedef CXXTemporary** temps_iterator;
+
+  temps_iterator temps_begin() {
+    if (ExprAndTemporaries *ET = SubExpr.dyn_cast<ExprAndTemporaries *>())
+      return ET->temps_begin();
+    
+    return 0;
+  }
+  temps_iterator temps_end() {
+    if (ExprAndTemporaries *ET = SubExpr.dyn_cast<ExprAndTemporaries *>())
+      return ET->temps_end();
+    
+    return 0;
+  }
+    
+  void *getAsOpaquePtr() const { return SubExpr.getOpaqueValue(); }
+
+  static FullExpr getFromOpaquePtr(void *Ptr) {
+    FullExpr E;
+    E.SubExpr = SubExprTy::getFromOpaqueValue(Ptr);
+    return E;
+  }
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/AST/NestedNameSpecifier.h b/include/clang/AST/NestedNameSpecifier.h
new file mode 100644
index 0000000..1594b09
--- /dev/null
+++ b/include/clang/AST/NestedNameSpecifier.h
@@ -0,0 +1,202 @@
+//===--- NestedNameSpecifier.h - C++ nested name specifiers -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the NestedNameSpecifier class, which represents
+//  a C++ nested-name-specifier.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H
+#define LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H
+
+#include "clang/Basic/Diagnostic.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/PointerIntPair.h"
+
+namespace llvm {
+  class raw_ostream;
+}
+
+namespace clang {
+
+class ASTContext;
+class NamespaceDecl;
+class IdentifierInfo;
+struct PrintingPolicy;
+class Type;
+class LangOptions;
+
+/// \brief Represents a C++ nested name specifier, such as
+/// "::std::vector<int>::".
+///
+/// C++ nested name specifiers are the prefixes to qualified
+/// namespaces. For example, "foo::" in "foo::x" is a nested name
+/// specifier. Nested name specifiers are made up of a sequence of
+/// specifiers, each of which can be a namespace, type, identifier
+/// (for dependent names), or the global specifier ('::', must be the
+/// first specifier).
+class NestedNameSpecifier : public llvm::FoldingSetNode {
+  /// \brief The nested name specifier that precedes this nested name
+  /// specifier.
+  ///
+  /// The pointer is the nested-name-specifier that precedes this
+  /// one. The integer stores one of the first four values of type
+  /// SpecifierKind.
+  llvm::PointerIntPair<NestedNameSpecifier *, 2> Prefix;
+
+  /// \brief The last component in the nested name specifier, which
+  /// can be an identifier, a declaration, or a type.
+  ///
+  /// When the pointer is NULL, this specifier represents the global
+  /// specifier '::'. Otherwise, the pointer is one of
+  /// IdentifierInfo*, Namespace*, or Type*, depending on the kind of
+  /// specifier as encoded within the prefix.
+  void* Specifier;
+
+public:
+  /// \brief The kind of specifier that completes this nested name
+  /// specifier.
+  enum SpecifierKind {
+    /// \brief An identifier, stored as an IdentifierInfo*.
+    Identifier = 0,
+    /// \brief A namespace, stored as a Namespace*.
+    Namespace = 1,
+    /// \brief A type, stored as a Type*.
+    TypeSpec = 2,
+    /// \brief A type that was preceded by the 'template' keyword,
+    /// stored as a Type*.
+    TypeSpecWithTemplate = 3,
+    /// \brief The global specifier '::'. There is no stored value.
+    Global = 4
+  };
+
+private:
+  /// \brief Builds the global specifier.
+  NestedNameSpecifier() : Prefix(0, 0), Specifier(0) { }
+
+  /// \brief Copy constructor used internally to clone nested name
+  /// specifiers.
+  NestedNameSpecifier(const NestedNameSpecifier &Other)
+    : llvm::FoldingSetNode(Other), Prefix(Other.Prefix),
+      Specifier(Other.Specifier) {
+  }
+
+  NestedNameSpecifier &operator=(const NestedNameSpecifier &); // do not implement
+
+  /// \brief Either find or insert the given nested name specifier
+  /// mockup in the given context.
+  static NestedNameSpecifier *FindOrInsert(ASTContext &Context,
+                                           const NestedNameSpecifier &Mockup);
+
+public:
+  /// \brief Builds a specifier combining a prefix and an identifier.
+  ///
+  /// The prefix must be dependent, since nested name specifiers
+  /// referencing an identifier are only permitted when the identifier
+  /// cannot be resolved.
+  static NestedNameSpecifier *Create(ASTContext &Context,
+                                     NestedNameSpecifier *Prefix,
+                                     IdentifierInfo *II);
+
+  /// \brief Builds a nested name specifier that names a namespace.
+  static NestedNameSpecifier *Create(ASTContext &Context,
+                                     NestedNameSpecifier *Prefix,
+                                     NamespaceDecl *NS);
+
+  /// \brief Builds a nested name specifier that names a type.
+  static NestedNameSpecifier *Create(ASTContext &Context,
+                                     NestedNameSpecifier *Prefix,
+                                     bool Template, Type *T);
+
+  /// \brief Builds a specifier that consists of just an identifier.
+  ///
+  /// The nested-name-specifier is assumed to be dependent, but has no
+  /// prefix because the prefix is implied by something outside of the
+  /// nested name specifier, e.g., in "x->Base::f", the "x" has a dependent
+  /// type.
+  static NestedNameSpecifier *Create(ASTContext &Context, IdentifierInfo *II);
+
+  /// \brief Returns the nested name specifier representing the global
+  /// scope.
+  static NestedNameSpecifier *GlobalSpecifier(ASTContext &Context);
+
+  /// \brief Return the prefix of this nested name specifier.
+  ///
+  /// The prefix contains all of the parts of the nested name
+  /// specifier that preced this current specifier. For example, for a
+  /// nested name specifier that represents "foo::bar::", the current
+  /// specifier will contain "bar::" and the prefix will contain
+  /// "foo::".
+  NestedNameSpecifier *getPrefix() const { return Prefix.getPointer(); }
+
+  /// \brief Determine what kind of nested name specifier is stored.
+  SpecifierKind getKind() const {
+    if (Specifier == 0)
+      return Global;
+    return (SpecifierKind)Prefix.getInt();
+  }
+
+  /// \brief Retrieve the identifier stored in this nested name
+  /// specifier.
+  IdentifierInfo *getAsIdentifier() const {
+    if (Prefix.getInt() == Identifier)
+      return (IdentifierInfo *)Specifier;
+
+    return 0;
+  }
+
+  /// \brief Retrieve the namespace stored in this nested name
+  /// specifier.
+  NamespaceDecl *getAsNamespace() const {
+    if (Prefix.getInt() == Namespace)
+      return (NamespaceDecl *)Specifier;
+
+    return 0;
+  }
+
+  /// \brief Retrieve the type stored in this nested name specifier.
+  Type *getAsType() const {
+    if (Prefix.getInt() == TypeSpec ||
+        Prefix.getInt() == TypeSpecWithTemplate)
+      return (Type *)Specifier;
+
+    return 0;
+  }
+
+  /// \brief Whether this nested name specifier refers to a dependent
+  /// type or not.
+  bool isDependent() const;
+
+  /// \brief Print this nested name specifier to the given output
+  /// stream.
+  void print(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const;
+
+  void Profile(llvm::FoldingSetNodeID &ID) const {
+    ID.AddPointer(Prefix.getOpaqueValue());
+    ID.AddPointer(Specifier);
+  }
+
+  void Destroy(ASTContext &Context);
+
+  /// \brief Dump the nested name specifier to standard output to aid
+  /// in debugging.
+  void dump(const LangOptions &LO);
+};
+
+/// Insertion operator for diagnostics.  This allows sending NestedNameSpecifiers
+/// into a diagnostic with <<.
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+                                           NestedNameSpecifier *NNS) {
+  DB.AddTaggedVal(reinterpret_cast<intptr_t>(NNS),
+                  Diagnostic::ak_nestednamespec);
+  return DB;
+}
+
+}
+
+#endif
diff --git a/include/clang/AST/ParentMap.h b/include/clang/AST/ParentMap.h
new file mode 100644
index 0000000..f826e11
--- /dev/null
+++ b/include/clang/AST/ParentMap.h
@@ -0,0 +1,50 @@
+//===--- ParentMap.h - Mappings from Stmts to their Parents -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the ParentMap class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_PARENTMAP_H
+#define LLVM_CLANG_PARENTMAP_H
+
+namespace clang {
+class Stmt;
+class Expr;
+
+class ParentMap {
+  void* Impl;
+public:
+  ParentMap(Stmt* ASTRoot);
+  ~ParentMap();
+
+  Stmt *getParent(Stmt*) const;
+  Stmt *getParentIgnoreParens(Stmt *) const;
+
+  const Stmt *getParent(const Stmt* S) const {
+    return getParent(const_cast<Stmt*>(S));
+  }
+
+  const Stmt *getParentIgnoreParens(const Stmt *S) const {
+    return getParentIgnoreParens(const_cast<Stmt*>(S));
+  }
+
+  bool hasParent(Stmt* S) const {
+    return getParent(S) != 0;
+  }
+
+  bool isConsumedExpr(Expr *E) const;
+
+  bool isConsumedExpr(const Expr *E) const {
+    return isConsumedExpr(const_cast<Expr*>(E));
+  }
+};
+
+} // end clang namespace
+#endif
diff --git a/include/clang/AST/PrettyPrinter.h b/include/clang/AST/PrettyPrinter.h
new file mode 100644
index 0000000..70d65d3
--- /dev/null
+++ b/include/clang/AST/PrettyPrinter.h
@@ -0,0 +1,110 @@
+//===--- PrettyPrinter.h - Classes for aiding with AST printing -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the PrinterHelper interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_PRETTY_PRINTER_H
+#define LLVM_CLANG_AST_PRETTY_PRINTER_H
+
+namespace llvm {
+  class raw_ostream;
+}
+
+namespace clang {
+
+class Stmt;
+class TagDecl;
+class LangOptions;
+
+class PrinterHelper {
+public:
+  virtual ~PrinterHelper();
+  virtual bool handledStmt(Stmt* E, llvm::raw_ostream& OS) = 0;
+};
+
+/// \brief Describes how types, statements, expressions, and
+/// declarations should be printed.
+struct PrintingPolicy {
+  /// \brief Create a default printing policy for C.
+  PrintingPolicy(const LangOptions &LO)
+    : Indentation(2), LangOpts(LO), SuppressSpecifiers(false),
+      SuppressTag(false), SuppressScope(false),
+      Dump(false), ConstantArraySizeAsWritten(false),
+      AnonymousTagLocations(true) { }
+
+  /// \brief The number of spaces to use to indent each line.
+  unsigned Indentation : 8;
+
+  /// \brief What language we're printing.
+  const LangOptions &LangOpts;
+
+  /// \brief Whether we should suppress printing of the actual specifiers for
+  /// the given type or declaration.
+  ///
+  /// This flag is only used when we are printing declarators beyond
+  /// the first declarator within a declaration group. For example, given:
+  ///
+  /// \code
+  /// const int *x, *y;
+  /// \endcode
+  ///
+  /// SuppressSpecifiers will be false when printing the
+  /// declaration for "x", so that we will print "int *x"; it will be
+  /// \c true when we print "y", so that we suppress printing the
+  /// "const int" type specifier and instead only print the "*y".
+  bool SuppressSpecifiers : 1;
+
+  /// \brief Whether type printing should skip printing the actual tag type.
+  ///
+  /// This is used when the caller needs to print a tag definition in front
+  /// of the type, as in constructs like the following:
+  ///
+  /// \code
+  /// typedef struct { int x, y; } Point;
+  /// \endcode
+  bool SuppressTag : 1;
+
+  /// \brief Suppresses printing of scope specifiers.
+  bool SuppressScope : 1;
+
+  /// \brief True when we are "dumping" rather than "pretty-printing",
+  /// where dumping involves printing the internal details of the AST
+  /// and pretty-printing involves printing something similar to
+  /// source code.
+  bool Dump : 1;
+
+  /// \brief Whether we should print the sizes of constant array expressions
+  /// as written in the sources.
+  ///
+  /// This flag is determines whether arrays types declared as
+  ///
+  /// \code
+  /// int a[4+10*10];
+  /// char a[] = "A string";
+  /// \endcode
+  ///
+  /// will be printed as written or as follows:
+  ///
+  /// \code
+  /// int a[104];
+  /// char a[9] = "A string";
+  /// \endcode
+  bool ConstantArraySizeAsWritten : 1;
+  
+  /// \brief When printing an anonymous tag name, also print the location of
+  /// that entity (e.g., "enum <anonymous at t.h:10:5>"). Otherwise, just 
+  /// prints "<anonymous>" for the name.
+  bool AnonymousTagLocations : 1;
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/AST/RecordLayout.h b/include/clang/AST/RecordLayout.h
new file mode 100644
index 0000000..e78476e
--- /dev/null
+++ b/include/clang/AST/RecordLayout.h
@@ -0,0 +1,240 @@
+//===--- RecordLayout.h - Layout information for a struct/union -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the RecordLayout interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_LAYOUTINFO_H
+#define LLVM_CLANG_AST_LAYOUTINFO_H
+
+#include "llvm/System/DataTypes.h"
+#include "llvm/ADT/DenseMap.h"
+#include "clang/AST/DeclCXX.h"
+
+namespace clang {
+  class ASTContext;
+  class FieldDecl;
+  class RecordDecl;
+  class CXXRecordDecl;
+
+/// ASTRecordLayout -
+/// This class contains layout information for one RecordDecl,
+/// which is a struct/union/class.  The decl represented must be a definition,
+/// not a forward declaration.
+/// This class is also used to contain layout information for one
+/// ObjCInterfaceDecl. FIXME - Find appropriate name.
+/// These objects are managed by ASTContext.
+class ASTRecordLayout {
+  /// Size - Size of record in bits.
+  uint64_t Size;
+
+  /// DataSize - Size of record in bits without tail padding.
+  uint64_t DataSize;
+
+  /// FieldOffsets - Array of field offsets in bits.
+  uint64_t *FieldOffsets;
+
+  // Alignment - Alignment of record in bits.
+  unsigned Alignment;
+
+  // FieldCount - Number of fields.
+  unsigned FieldCount;
+
+public:
+  /// PrimaryBaseInfo - Contains info about a primary base.
+  struct PrimaryBaseInfo {
+    PrimaryBaseInfo() {}
+
+    PrimaryBaseInfo(const CXXRecordDecl *Base, bool IsVirtual)
+      : Value(Base, Base && IsVirtual) {}
+
+    /// Value - Points to the primary base. The single-bit value
+    /// will be non-zero when the primary base is virtual.
+    llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> Value;
+    
+    /// getBase - Returns the primary base.
+    const CXXRecordDecl *getBase() const { return Value.getPointer(); }
+  
+    /// isVirtual - Returns whether the primary base is virtual or not.
+    bool isVirtual() const { return Value.getInt(); }
+
+    friend bool operator==(const PrimaryBaseInfo &X, const PrimaryBaseInfo &Y) {
+      return X.Value == Y.Value;
+    }
+  }; 
+  
+  /// primary_base_info_iterator - An iterator for iterating the primary base
+  /// class chain.
+  class primary_base_info_iterator {
+    /// Current - The current base class info.
+    PrimaryBaseInfo Current;
+    
+  public:
+    primary_base_info_iterator() {}
+    primary_base_info_iterator(PrimaryBaseInfo Info) : Current(Info) {}
+
+    const PrimaryBaseInfo &operator*() const { return Current; }
+
+    primary_base_info_iterator& operator++() {
+      const CXXRecordDecl *RD = Current.getBase();
+      Current = RD->getASTContext().getASTRecordLayout(RD).getPrimaryBaseInfo();
+      return *this;
+    }
+
+    friend bool operator==(const primary_base_info_iterator &X,
+                           const primary_base_info_iterator &Y) {
+      return X.Current == Y.Current;
+    }
+    friend bool operator!=(const primary_base_info_iterator &X,
+                           const primary_base_info_iterator &Y) {
+      return !(X == Y);
+    }
+  };
+    
+private:
+  /// CXXRecordLayoutInfo - Contains C++ specific layout information.
+  struct CXXRecordLayoutInfo {
+    /// NonVirtualSize - The non-virtual size (in bits) of an object, which is
+    /// the size of the object without virtual bases.
+    uint64_t NonVirtualSize;
+
+    /// NonVirtualAlign - The non-virtual alignment (in bits) of an object,
+    /// which is the alignment of the object without virtual bases.
+    uint64_t NonVirtualAlign;
+
+    /// PrimaryBase - The primary base info for this record.
+    PrimaryBaseInfo PrimaryBase;
+    
+    /// FIXME: This should really use a SmallPtrMap, once we have one in LLVM :)
+    typedef llvm::DenseMap<const CXXRecordDecl *, uint64_t> BaseOffsetsMapTy;
+    
+    /// BaseOffsets - Contains a map from base classes to their offset.
+    BaseOffsetsMapTy BaseOffsets;
+
+    /// VBaseOffsets - Contains a map from vbase classes to their offset.
+    BaseOffsetsMapTy VBaseOffsets;
+  };
+
+  /// CXXInfo - If the record layout is for a C++ record, this will have
+  /// C++ specific information about the record.
+  CXXRecordLayoutInfo *CXXInfo;
+
+  friend class ASTContext;
+  friend class ASTRecordLayoutBuilder;
+
+  ASTRecordLayout(ASTContext &Ctx, uint64_t size, unsigned alignment,
+                  unsigned datasize, const uint64_t *fieldoffsets,
+                  unsigned fieldcount);
+
+  // Constructor for C++ records.
+  typedef CXXRecordLayoutInfo::BaseOffsetsMapTy BaseOffsetsMapTy;
+  ASTRecordLayout(ASTContext &Ctx,
+                  uint64_t size, unsigned alignment, uint64_t datasize,
+                  const uint64_t *fieldoffsets, unsigned fieldcount,
+                  uint64_t nonvirtualsize, unsigned nonvirtualalign,
+                  const PrimaryBaseInfo &PrimaryBase,
+                  const BaseOffsetsMapTy& BaseOffsets,
+                  const BaseOffsetsMapTy& VBaseOffsets);
+
+  ~ASTRecordLayout() {}
+
+  void Destroy(ASTContext &Ctx);
+
+  ASTRecordLayout(const ASTRecordLayout&);   // DO NOT IMPLEMENT
+  void operator=(const ASTRecordLayout&); // DO NOT IMPLEMENT
+public:
+
+  /// getAlignment - Get the record alignment in bits.
+  unsigned getAlignment() const { return Alignment; }
+
+  /// getSize - Get the record size in bits.
+  uint64_t getSize() const { return Size; }
+
+  /// getFieldCount - Get the number of fields in the layout.
+  unsigned getFieldCount() const { return FieldCount; }
+
+  /// getFieldOffset - Get the offset of the given field index, in
+  /// bits.
+  uint64_t getFieldOffset(unsigned FieldNo) const {
+    assert (FieldNo < FieldCount && "Invalid Field No");
+    return FieldOffsets[FieldNo];
+  }
+
+  /// getDataSize() - Get the record data size, which is the record size
+  /// without tail padding, in bits.
+  uint64_t getDataSize() const {
+    return DataSize;
+  }
+
+  /// getNonVirtualSize - Get the non-virtual size (in bits) of an object,
+  /// which is the size of the object without virtual bases.
+  uint64_t getNonVirtualSize() const {
+    assert(CXXInfo && "Record layout does not have C++ specific info!");
+
+    return CXXInfo->NonVirtualSize;
+  }
+
+  /// getNonVirtualSize - Get the non-virtual alignment (in bits) of an object,
+  /// which is the alignment of the object without virtual bases.
+  unsigned getNonVirtualAlign() const {
+    assert(CXXInfo && "Record layout does not have C++ specific info!");
+
+    return CXXInfo->NonVirtualAlign;
+  }
+
+  /// getPrimaryBaseInfo - Get the primary base info.
+  const PrimaryBaseInfo &getPrimaryBaseInfo() const {
+    assert(CXXInfo && "Record layout does not have C++ specific info!");
+
+    return CXXInfo->PrimaryBase;
+  }
+
+  // FIXME: Migrate off of this function and use getPrimaryBaseInfo directly.
+  const CXXRecordDecl *getPrimaryBase() const {
+    return getPrimaryBaseInfo().getBase();
+  }
+
+  // FIXME: Migrate off of this function and use getPrimaryBaseInfo directly.
+  bool getPrimaryBaseWasVirtual() const {
+    return getPrimaryBaseInfo().isVirtual();
+  }
+
+  /// getBaseClassOffset - Get the offset, in bits, for the given base class.
+  uint64_t getBaseClassOffset(const CXXRecordDecl *Base) const {
+    assert(CXXInfo && "Record layout does not have C++ specific info!");
+    assert(CXXInfo->BaseOffsets.count(Base) && "Did not find base!");
+
+    return CXXInfo->BaseOffsets[Base];
+  }
+
+  /// getVBaseClassOffset - Get the offset, in bits, for the given base class.
+  uint64_t getVBaseClassOffset(const CXXRecordDecl *VBase) const {
+    assert(CXXInfo && "Record layout does not have C++ specific info!");
+    assert(CXXInfo->VBaseOffsets.count(VBase) && "Did not find base!");
+
+    return CXXInfo->VBaseOffsets[VBase];
+  }
+  
+  primary_base_info_iterator primary_base_begin() const {
+    assert(CXXInfo && "Record layout does not have C++ specific info!");
+  
+    return primary_base_info_iterator(getPrimaryBaseInfo());
+  }
+
+  primary_base_info_iterator primary_base_end() const {
+    assert(CXXInfo && "Record layout does not have C++ specific info!");
+    
+    return primary_base_info_iterator();
+  }
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/AST/Redeclarable.h b/include/clang/AST/Redeclarable.h
new file mode 100644
index 0000000..01f4b29
--- /dev/null
+++ b/include/clang/AST/Redeclarable.h
@@ -0,0 +1,179 @@
+//===-- Redeclarable.h - Base for Decls that can be redeclared -*- C++ -*-====//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the Redeclarable interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_REDECLARABLE_H
+#define LLVM_CLANG_AST_REDECLARABLE_H
+
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/Support/Casting.h"
+#include <iterator>
+
+namespace clang {
+
+/// \brief Provides common interface for the Decls that can be redeclared.
+template<typename decl_type>
+class Redeclarable {
+
+protected:
+  // FIXME: PointerIntPair is a value class that should not be inherited from.
+  // This should change to using containment.
+  struct DeclLink : public llvm::PointerIntPair<decl_type *, 1, bool> {
+    DeclLink(decl_type *D, bool isLatest)
+      : llvm::PointerIntPair<decl_type *, 1, bool>(D, isLatest) { }
+
+    typedef llvm::PointerIntPair<decl_type *, 1, bool> base_type;
+
+    bool NextIsPrevious() const { return base_type::getInt() == false; }
+    bool NextIsLatest() const { return base_type::getInt() == true; }
+    decl_type *getNext() const { return base_type::getPointer(); }
+  };
+
+  struct PreviousDeclLink : public DeclLink {
+    PreviousDeclLink(decl_type *D) : DeclLink(D, false) { }
+  };
+
+  struct LatestDeclLink : public DeclLink {
+    LatestDeclLink(decl_type *D) : DeclLink(D, true) { }
+  };
+
+  /// \brief Points to the next redeclaration in the chain.
+  ///
+  /// If NextIsPrevious() is true, this is a link to the previous declaration
+  /// of this same Decl. If NextIsLatest() is true, this is the first
+  /// declaration and Link points to the latest declaration. For example:
+  ///
+  ///  #1 int f(int x, int y = 1); // <pointer to #3, true>
+  ///  #2 int f(int x = 0, int y); // <pointer to #1, false>
+  ///  #3 int f(int x, int y) { return x + y; } // <pointer to #2, false>
+  ///
+  /// If there is only one declaration, it is <pointer to self, true>
+  DeclLink RedeclLink;
+
+public:
+  Redeclarable() : RedeclLink(LatestDeclLink(static_cast<decl_type*>(this))) { }
+
+  /// \brief Return the previous declaration of this declaration or NULL if this
+  /// is the first declaration.
+  decl_type *getPreviousDeclaration() {
+    if (RedeclLink.NextIsPrevious())
+      return RedeclLink.getNext();
+    return 0;
+  }
+  const decl_type *getPreviousDeclaration() const {
+    return const_cast<decl_type *>(
+                 static_cast<const decl_type*>(this))->getPreviousDeclaration();
+  }
+
+  /// \brief Return the first declaration of this declaration or itself if this
+  /// is the only declaration.
+  decl_type *getFirstDeclaration() {
+    decl_type *D = static_cast<decl_type*>(this);
+    while (D->getPreviousDeclaration())
+      D = D->getPreviousDeclaration();
+    return D;
+  }
+
+  /// \brief Return the first declaration of this declaration or itself if this
+  /// is the only declaration.
+  const decl_type *getFirstDeclaration() const {
+    const decl_type *D = static_cast<const decl_type*>(this);
+    while (D->getPreviousDeclaration())
+      D = D->getPreviousDeclaration();
+    return D;
+  }
+
+  /// \brief Returns the most recent (re)declaration of this declaration.
+  decl_type *getMostRecentDeclaration() {
+    return getFirstDeclaration()->RedeclLink.getNext();
+  }
+
+  /// \brief Returns the most recent (re)declaration of this declaration.
+  const decl_type *getMostRecentDeclaration() const {
+    return getFirstDeclaration()->RedeclLink.getNext();
+  }
+  
+  /// \brief Set the previous declaration. If PrevDecl is NULL, set this as the
+  /// first and only declaration.
+  void setPreviousDeclaration(decl_type *PrevDecl) {
+    decl_type *First;
+
+    if (PrevDecl) {
+      // Point to previous. Make sure that this is actually the most recent
+      // redeclaration, or we can build invalid chains. If the most recent
+      // redeclaration is invalid, it won't be PrevDecl, but we want it anyway.
+      RedeclLink = PreviousDeclLink(llvm::cast<decl_type>(
+                                      PrevDecl->getMostRecentDeclaration()));
+      First = PrevDecl->getFirstDeclaration();
+      assert(First->RedeclLink.NextIsLatest() && "Expected first");
+    } else {
+      // Make this first.
+      First = static_cast<decl_type*>(this);
+    }
+
+    // First one will point to this one as latest.
+    First->RedeclLink = LatestDeclLink(static_cast<decl_type*>(this));
+  }
+
+  /// \brief Iterates through all the redeclarations of the same decl.
+  class redecl_iterator {
+    /// Current - The current declaration.
+    decl_type *Current;
+    decl_type *Starter;
+
+  public:
+    typedef decl_type*                value_type;
+    typedef decl_type*                reference;
+    typedef decl_type*                pointer;
+    typedef std::forward_iterator_tag iterator_category;
+    typedef std::ptrdiff_t            difference_type;
+
+    redecl_iterator() : Current(0) { }
+    explicit redecl_iterator(decl_type *C) : Current(C), Starter(C) { }
+
+    reference operator*() const { return Current; }
+    pointer operator->() const { return Current; }
+
+    redecl_iterator& operator++() {
+      assert(Current && "Advancing while iterator has reached end");
+      // Get either previous decl or latest decl.
+      decl_type *Next = Current->RedeclLink.getNext();
+      Current = (Next != Starter ? Next : 0);
+      return *this;
+    }
+
+    redecl_iterator operator++(int) {
+      redecl_iterator tmp(*this);
+      ++(*this);
+      return tmp;
+    }
+
+    friend bool operator==(redecl_iterator x, redecl_iterator y) {
+      return x.Current == y.Current;
+    }
+    friend bool operator!=(redecl_iterator x, redecl_iterator y) {
+      return x.Current != y.Current;
+    }
+  };
+
+  /// \brief Returns iterator for all the redeclarations of the same decl.
+  /// It will iterate at least once (when this decl is the only one).
+  redecl_iterator redecls_begin() const {
+    return redecl_iterator(const_cast<decl_type*>(
+                                          static_cast<const decl_type*>(this)));
+  }
+  redecl_iterator redecls_end() const { return redecl_iterator(); }
+};
+
+}
+
+#endif
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
new file mode 100644
index 0000000..0b68a40
--- /dev/null
+++ b/include/clang/AST/Stmt.h
@@ -0,0 +1,1365 @@
+//===--- Stmt.h - Classes for representing statements -----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the Stmt interface and subclasses.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_STMT_H
+#define LLVM_CLANG_AST_STMT_H
+
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/raw_ostream.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/AST/PrettyPrinter.h"
+#include "clang/AST/StmtIterator.h"
+#include "clang/AST/DeclGroup.h"
+#include "clang/AST/FullExpr.h"
+#include "llvm/ADT/SmallVector.h"
+#include "clang/AST/ASTContext.h"
+#include <string>
+using llvm::dyn_cast_or_null;
+
+namespace llvm {
+  class FoldingSetNodeID;
+}
+
+namespace clang {
+  class ASTContext;
+  class Expr;
+  class Decl;
+  class ParmVarDecl;
+  class QualType;
+  class IdentifierInfo;
+  class SourceManager;
+  class StringLiteral;
+  class SwitchStmt;
+
+  //===----------------------------------------------------------------------===//
+  // ExprIterator - Iterators for iterating over Stmt* arrays that contain
+  //  only Expr*.  This is needed because AST nodes use Stmt* arrays to store
+  //  references to children (to be compatible with StmtIterator).
+  //===----------------------------------------------------------------------===//
+
+  class Stmt;
+  class Expr;
+
+  class ExprIterator {
+    Stmt** I;
+  public:
+    ExprIterator(Stmt** i) : I(i) {}
+    ExprIterator() : I(0) {}
+    ExprIterator& operator++() { ++I; return *this; }
+    ExprIterator operator-(size_t i) { return I-i; }
+    ExprIterator operator+(size_t i) { return I+i; }
+    Expr* operator[](size_t idx);
+    // FIXME: Verify that this will correctly return a signed distance.
+    signed operator-(const ExprIterator& R) const { return I - R.I; }
+    Expr* operator*() const;
+    Expr* operator->() const;
+    bool operator==(const ExprIterator& R) const { return I == R.I; }
+    bool operator!=(const ExprIterator& R) const { return I != R.I; }
+    bool operator>(const ExprIterator& R) const { return I > R.I; }
+    bool operator>=(const ExprIterator& R) const { return I >= R.I; }
+  };
+
+  class ConstExprIterator {
+    const Stmt * const *I;
+  public:
+    ConstExprIterator(const Stmt * const *i) : I(i) {}
+    ConstExprIterator() : I(0) {}
+    ConstExprIterator& operator++() { ++I; return *this; }
+    ConstExprIterator operator+(size_t i) const { return I+i; }
+    ConstExprIterator operator-(size_t i) const { return I-i; }
+    const Expr * operator[](size_t idx) const;
+    signed operator-(const ConstExprIterator& R) const { return I - R.I; }
+    const Expr * operator*() const;
+    const Expr * operator->() const;
+    bool operator==(const ConstExprIterator& R) const { return I == R.I; }
+    bool operator!=(const ConstExprIterator& R) const { return I != R.I; }
+    bool operator>(const ConstExprIterator& R) const { return I > R.I; }
+    bool operator>=(const ConstExprIterator& R) const { return I >= R.I; }
+  };
+
+//===----------------------------------------------------------------------===//
+// AST classes for statements.
+//===----------------------------------------------------------------------===//
+
+/// Stmt - This represents one statement.
+///
+class Stmt {
+public:
+  enum StmtClass {
+    NoStmtClass = 0,
+#define STMT(CLASS, PARENT) CLASS##Class,
+#define FIRST_STMT(CLASS) firstStmtConstant = CLASS##Class,
+#define LAST_STMT(CLASS) lastStmtConstant = CLASS##Class,
+#define FIRST_EXPR(CLASS) firstExprConstant = CLASS##Class,
+#define LAST_EXPR(CLASS) lastExprConstant = CLASS##Class
+#define ABSTRACT_EXPR(CLASS, PARENT)
+#include "clang/AST/StmtNodes.def"
+};
+private:
+  /// \brief The statement class.
+  const unsigned sClass : 8;
+
+  /// \brief The reference count for this statement.
+  unsigned RefCount : 24;
+
+  // Make vanilla 'new' and 'delete' illegal for Stmts.
+protected:
+  void* operator new(size_t bytes) throw() {
+    assert(0 && "Stmts cannot be allocated with regular 'new'.");
+    return 0;
+  }
+  void operator delete(void* data) throw() {
+    assert(0 && "Stmts cannot be released with regular 'delete'.");
+  }
+
+public:
+  // Only allow allocation of Stmts using the allocator in ASTContext
+  // or by doing a placement new.
+  void* operator new(size_t bytes, ASTContext& C,
+                     unsigned alignment = 8) throw() {
+    return ::operator new(bytes, C, alignment);
+  }
+
+  void* operator new(size_t bytes, ASTContext* C,
+                     unsigned alignment = 8) throw() {
+    return ::operator new(bytes, *C, alignment);
+  }
+
+  void* operator new(size_t bytes, void* mem) throw() {
+    return mem;
+  }
+
+  void operator delete(void*, ASTContext&, unsigned) throw() { }
+  void operator delete(void*, ASTContext*, unsigned) throw() { }
+  void operator delete(void*, std::size_t) throw() { }
+  void operator delete(void*, void*) throw() { }
+
+public:
+  /// \brief A placeholder type used to construct an empty shell of a
+  /// type, that will be filled in later (e.g., by some
+  /// de-serialization).
+  struct EmptyShell { };
+
+protected:
+  /// DestroyChildren - Invoked by destructors of subclasses of Stmt to
+  ///  recursively release child AST nodes.
+  void DestroyChildren(ASTContext& Ctx);
+
+  /// \brief Construct an empty statement.
+  explicit Stmt(StmtClass SC, EmptyShell) : sClass(SC), RefCount(1) {
+    if (Stmt::CollectingStats()) Stmt::addStmtClass(SC);
+  }
+
+  /// \brief Virtual method that performs the actual destruction of
+  /// this statement.
+  ///
+  /// Subclasses should override this method (not Destroy()) to
+  /// provide class-specific destruction.
+  virtual void DoDestroy(ASTContext &Ctx);
+
+public:
+  Stmt(StmtClass SC) : sClass(SC), RefCount(1) {
+    if (Stmt::CollectingStats()) Stmt::addStmtClass(SC);
+  }
+  virtual ~Stmt() {}
+
+#ifndef NDEBUG
+  /// \brief True if this statement's refcount is in a valid state.
+  /// Should be used only in assertions.
+  bool isRetained() const {
+    return (RefCount >= 1);
+  }
+#endif
+
+  /// \brief Destroy the current statement and its children.
+  void Destroy(ASTContext &Ctx) {
+    assert(RefCount >= 1);
+    if (--RefCount == 0)
+      DoDestroy(Ctx);
+  }
+
+  /// \brief Increases the reference count for this statement.
+  ///
+  /// Invoke the Retain() operation when this statement or expression
+  /// is being shared by another owner.
+  Stmt *Retain() {
+    assert(RefCount >= 1);
+    ++RefCount;
+    return this;
+  }
+
+  StmtClass getStmtClass() const { 
+    assert(RefCount >= 1 && "Referencing already-destroyed statement!");
+    return (StmtClass)sClass; 
+  }
+  const char *getStmtClassName() const;
+
+  /// SourceLocation tokens are not useful in isolation - they are low level
+  /// value objects created/interpreted by SourceManager. We assume AST
+  /// clients will have a pointer to the respective SourceManager.
+  virtual SourceRange getSourceRange() const = 0;
+  SourceLocation getLocStart() const { return getSourceRange().getBegin(); }
+  SourceLocation getLocEnd() const { return getSourceRange().getEnd(); }
+
+  // global temp stats (until we have a per-module visitor)
+  static void addStmtClass(const StmtClass s);
+  static bool CollectingStats(bool Enable = false);
+  static void PrintStats();
+
+  /// dump - This does a local dump of the specified AST fragment.  It dumps the
+  /// specified node and a few nodes underneath it, but not the whole subtree.
+  /// This is useful in a debugger.
+  void dump() const;
+  void dump(SourceManager &SM) const;
+
+  /// dumpAll - This does a dump of the specified AST fragment and all subtrees.
+  void dumpAll() const;
+  void dumpAll(SourceManager &SM) const;
+
+  /// dumpPretty/printPretty - These two methods do a "pretty print" of the AST
+  /// back to its original source language syntax.
+  void dumpPretty(ASTContext& Context) const;
+  void printPretty(llvm::raw_ostream &OS, PrinterHelper *Helper,
+                   const PrintingPolicy &Policy,
+                   unsigned Indentation = 0) const {
+    printPretty(OS, *(ASTContext*)0, Helper, Policy, Indentation);
+  }
+  void printPretty(llvm::raw_ostream &OS, ASTContext &Context,
+                   PrinterHelper *Helper,
+                   const PrintingPolicy &Policy,
+                   unsigned Indentation = 0) const;
+
+  /// viewAST - Visualize an AST rooted at this Stmt* using GraphViz.  Only
+  ///   works on systems with GraphViz (Mac OS X) or dot+gv installed.
+  void viewAST() const;
+
+  // Implement isa<T> support.
+  static bool classof(const Stmt *) { return true; }
+
+  /// hasImplicitControlFlow - Some statements (e.g. short circuited operations)
+  ///  contain implicit control-flow in the order their subexpressions
+  ///  are evaluated.  This predicate returns true if this statement has
+  ///  such implicit control-flow.  Such statements are also specially handled
+  ///  within CFGs.
+  bool hasImplicitControlFlow() const;
+
+  /// Child Iterators: All subclasses must implement child_begin and child_end
+  ///  to permit easy iteration over the substatements/subexpessions of an
+  ///  AST node.  This permits easy iteration over all nodes in the AST.
+  typedef StmtIterator       child_iterator;
+  typedef ConstStmtIterator  const_child_iterator;
+
+  virtual child_iterator child_begin() = 0;
+  virtual child_iterator child_end()   = 0;
+
+  const_child_iterator child_begin() const {
+    return const_child_iterator(const_cast<Stmt*>(this)->child_begin());
+  }
+
+  const_child_iterator child_end() const {
+    return const_child_iterator(const_cast<Stmt*>(this)->child_end());
+  }
+
+  /// \brief Produce a unique representation of the given statement.
+  ///
+  /// \brief ID once the profiling operation is complete, will contain
+  /// the unique representation of the given statement.
+  ///
+  /// \brief Context the AST context in which the statement resides
+  ///
+  /// \brief Canonical whether the profile should be based on the canonical
+  /// representation of this statement (e.g., where non-type template
+  /// parameters are identified by index/level rather than their
+  /// declaration pointers) or the exact representation of the statement as
+  /// written in the source.
+  void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context,
+               bool Canonical);
+};
+
+/// DeclStmt - Adaptor class for mixing declarations with statements and
+/// expressions. For example, CompoundStmt mixes statements, expressions
+/// and declarations (variables, types). Another example is ForStmt, where
+/// the first statement can be an expression or a declaration.
+///
+class DeclStmt : public Stmt {
+  DeclGroupRef DG;
+  SourceLocation StartLoc, EndLoc;
+
+protected:
+  virtual void DoDestroy(ASTContext &Ctx);
+
+public:
+  DeclStmt(DeclGroupRef dg, SourceLocation startLoc,
+           SourceLocation endLoc) : Stmt(DeclStmtClass), DG(dg),
+                                    StartLoc(startLoc), EndLoc(endLoc) {}
+
+  /// \brief Build an empty declaration statement.
+  explicit DeclStmt(EmptyShell Empty) : Stmt(DeclStmtClass, Empty) { }
+
+  /// isSingleDecl - This method returns true if this DeclStmt refers
+  /// to a single Decl.
+  bool isSingleDecl() const {
+    return DG.isSingleDecl();
+  }
+
+  const Decl *getSingleDecl() const { return DG.getSingleDecl(); }
+  Decl *getSingleDecl() { return DG.getSingleDecl(); }
+
+  const DeclGroupRef getDeclGroup() const { return DG; }
+  DeclGroupRef getDeclGroup() { return DG; }
+  void setDeclGroup(DeclGroupRef DGR) { DG = DGR; }
+
+  SourceLocation getStartLoc() const { return StartLoc; }
+  void setStartLoc(SourceLocation L) { StartLoc = L; }
+  SourceLocation getEndLoc() const { return EndLoc; }
+  void setEndLoc(SourceLocation L) { EndLoc = L; }
+
+  SourceRange getSourceRange() const {
+    return SourceRange(StartLoc, EndLoc);
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == DeclStmtClass;
+  }
+  static bool classof(const DeclStmt *) { return true; }
+
+  // Iterators over subexpressions.
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+
+  typedef DeclGroupRef::iterator decl_iterator;
+  typedef DeclGroupRef::const_iterator const_decl_iterator;
+
+  decl_iterator decl_begin() { return DG.begin(); }
+  decl_iterator decl_end() { return DG.end(); }
+  const_decl_iterator decl_begin() const { return DG.begin(); }
+  const_decl_iterator decl_end() const { return DG.end(); }
+};
+
+/// NullStmt - This is the null statement ";": C99 6.8.3p3.
+///
+class NullStmt : public Stmt {
+  SourceLocation SemiLoc;
+public:
+  NullStmt(SourceLocation L) : Stmt(NullStmtClass), SemiLoc(L) {}
+
+  /// \brief Build an empty null statement.
+  explicit NullStmt(EmptyShell Empty) : Stmt(NullStmtClass, Empty) { }
+
+  SourceLocation getSemiLoc() const { return SemiLoc; }
+  void setSemiLoc(SourceLocation L) { SemiLoc = L; }
+
+  virtual SourceRange getSourceRange() const { return SourceRange(SemiLoc); }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == NullStmtClass;
+  }
+  static bool classof(const NullStmt *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+/// CompoundStmt - This represents a group of statements like { stmt stmt }.
+///
+class CompoundStmt : public Stmt {
+  Stmt** Body;
+  unsigned NumStmts;
+  SourceLocation LBracLoc, RBracLoc;
+public:
+  CompoundStmt(ASTContext& C, Stmt **StmtStart, unsigned numStmts,
+                             SourceLocation LB, SourceLocation RB)
+  : Stmt(CompoundStmtClass), NumStmts(numStmts), LBracLoc(LB), RBracLoc(RB) {
+    if (NumStmts == 0) {
+      Body = 0;
+      return;
+    }
+
+    Body = new (C) Stmt*[NumStmts];
+    memcpy(Body, StmtStart, numStmts * sizeof(*Body));
+  }
+
+  // \brief Build an empty compound statement.
+  explicit CompoundStmt(EmptyShell Empty)
+    : Stmt(CompoundStmtClass, Empty), Body(0), NumStmts(0) { }
+
+  void setStmts(ASTContext &C, Stmt **Stmts, unsigned NumStmts);
+
+  bool body_empty() const { return NumStmts == 0; }
+  unsigned size() const { return NumStmts; }
+
+  typedef Stmt** body_iterator;
+  body_iterator body_begin() { return Body; }
+  body_iterator body_end() { return Body + NumStmts; }
+  Stmt *body_back() { return NumStmts ? Body[NumStmts-1] : 0; }
+
+  typedef Stmt* const * const_body_iterator;
+  const_body_iterator body_begin() const { return Body; }
+  const_body_iterator body_end() const { return Body + NumStmts; }
+  const Stmt *body_back() const { return NumStmts ? Body[NumStmts-1] : 0; }
+
+  typedef std::reverse_iterator<body_iterator> reverse_body_iterator;
+  reverse_body_iterator body_rbegin() {
+    return reverse_body_iterator(body_end());
+  }
+  reverse_body_iterator body_rend() {
+    return reverse_body_iterator(body_begin());
+  }
+
+  typedef std::reverse_iterator<const_body_iterator>
+          const_reverse_body_iterator;
+
+  const_reverse_body_iterator body_rbegin() const {
+    return const_reverse_body_iterator(body_end());
+  }
+
+  const_reverse_body_iterator body_rend() const {
+    return const_reverse_body_iterator(body_begin());
+  }
+
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(LBracLoc, RBracLoc);
+  }
+
+  SourceLocation getLBracLoc() const { return LBracLoc; }
+  void setLBracLoc(SourceLocation L) { LBracLoc = L; }
+  SourceLocation getRBracLoc() const { return RBracLoc; }
+  void setRBracLoc(SourceLocation L) { RBracLoc = L; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CompoundStmtClass;
+  }
+  static bool classof(const CompoundStmt *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+// SwitchCase is the base class for CaseStmt and DefaultStmt,
+class SwitchCase : public Stmt {
+protected:
+  // A pointer to the following CaseStmt or DefaultStmt class,
+  // used by SwitchStmt.
+  SwitchCase *NextSwitchCase;
+
+  SwitchCase(StmtClass SC) : Stmt(SC), NextSwitchCase(0) {}
+
+public:
+  const SwitchCase *getNextSwitchCase() const { return NextSwitchCase; }
+
+  SwitchCase *getNextSwitchCase() { return NextSwitchCase; }
+
+  void setNextSwitchCase(SwitchCase *SC) { NextSwitchCase = SC; }
+
+  Stmt *getSubStmt() { return v_getSubStmt(); }
+
+  virtual SourceRange getSourceRange() const { return SourceRange(); }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CaseStmtClass ||
+    T->getStmtClass() == DefaultStmtClass;
+  }
+  static bool classof(const SwitchCase *) { return true; }
+protected:
+  virtual Stmt* v_getSubStmt() = 0;
+};
+
+class CaseStmt : public SwitchCase {
+  enum { SUBSTMT, LHS, RHS, END_EXPR };
+  Stmt* SubExprs[END_EXPR];  // The expression for the RHS is Non-null for
+                             // GNU "case 1 ... 4" extension
+  SourceLocation CaseLoc;
+  SourceLocation EllipsisLoc;
+  SourceLocation ColonLoc;
+
+  virtual Stmt* v_getSubStmt() { return getSubStmt(); }
+public:
+  CaseStmt(Expr *lhs, Expr *rhs, SourceLocation caseLoc,
+           SourceLocation ellipsisLoc, SourceLocation colonLoc)
+    : SwitchCase(CaseStmtClass) {
+    SubExprs[SUBSTMT] = 0;
+    SubExprs[LHS] = reinterpret_cast<Stmt*>(lhs);
+    SubExprs[RHS] = reinterpret_cast<Stmt*>(rhs);
+    CaseLoc = caseLoc;
+    EllipsisLoc = ellipsisLoc;
+    ColonLoc = colonLoc;
+  }
+
+  /// \brief Build an empty switch case statement.
+  explicit CaseStmt(EmptyShell Empty) : SwitchCase(CaseStmtClass) { }
+
+  SourceLocation getCaseLoc() const { return CaseLoc; }
+  void setCaseLoc(SourceLocation L) { CaseLoc = L; }
+  SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
+  void setEllipsisLoc(SourceLocation L) { EllipsisLoc = L; }
+  SourceLocation getColonLoc() const { return ColonLoc; }
+  void setColonLoc(SourceLocation L) { ColonLoc = L; }
+
+  Expr *getLHS() { return reinterpret_cast<Expr*>(SubExprs[LHS]); }
+  Expr *getRHS() { return reinterpret_cast<Expr*>(SubExprs[RHS]); }
+  Stmt *getSubStmt() { return SubExprs[SUBSTMT]; }
+
+  const Expr *getLHS() const {
+    return reinterpret_cast<const Expr*>(SubExprs[LHS]);
+  }
+  const Expr *getRHS() const {
+    return reinterpret_cast<const Expr*>(SubExprs[RHS]);
+  }
+  const Stmt *getSubStmt() const { return SubExprs[SUBSTMT]; }
+
+  void setSubStmt(Stmt *S) { SubExprs[SUBSTMT] = S; }
+  void setLHS(Expr *Val) { SubExprs[LHS] = reinterpret_cast<Stmt*>(Val); }
+  void setRHS(Expr *Val) { SubExprs[RHS] = reinterpret_cast<Stmt*>(Val); }
+
+
+  virtual SourceRange getSourceRange() const {
+    // Handle deeply nested case statements with iteration instead of recursion.
+    const CaseStmt *CS = this;
+    while (const CaseStmt *CS2 = dyn_cast<CaseStmt>(CS->getSubStmt()))
+      CS = CS2;
+
+    return SourceRange(CaseLoc, CS->getSubStmt()->getLocEnd());
+  }
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CaseStmtClass;
+  }
+  static bool classof(const CaseStmt *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+class DefaultStmt : public SwitchCase {
+  Stmt* SubStmt;
+  SourceLocation DefaultLoc;
+  SourceLocation ColonLoc;
+  virtual Stmt* v_getSubStmt() { return getSubStmt(); }
+public:
+  DefaultStmt(SourceLocation DL, SourceLocation CL, Stmt *substmt) :
+    SwitchCase(DefaultStmtClass), SubStmt(substmt), DefaultLoc(DL),
+    ColonLoc(CL) {}
+
+  /// \brief Build an empty default statement.
+  explicit DefaultStmt(EmptyShell) : SwitchCase(DefaultStmtClass) { }
+
+  Stmt *getSubStmt() { return SubStmt; }
+  const Stmt *getSubStmt() const { return SubStmt; }
+  void setSubStmt(Stmt *S) { SubStmt = S; }
+
+  SourceLocation getDefaultLoc() const { return DefaultLoc; }
+  void setDefaultLoc(SourceLocation L) { DefaultLoc = L; }
+  SourceLocation getColonLoc() const { return ColonLoc; }
+  void setColonLoc(SourceLocation L) { ColonLoc = L; }
+
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(DefaultLoc, SubStmt->getLocEnd());
+  }
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == DefaultStmtClass;
+  }
+  static bool classof(const DefaultStmt *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+class LabelStmt : public Stmt {
+  IdentifierInfo *Label;
+  Stmt *SubStmt;
+  SourceLocation IdentLoc;
+public:
+  LabelStmt(SourceLocation IL, IdentifierInfo *label, Stmt *substmt)
+    : Stmt(LabelStmtClass), Label(label),
+      SubStmt(substmt), IdentLoc(IL) {}
+
+  // \brief Build an empty label statement.
+  explicit LabelStmt(EmptyShell Empty) : Stmt(LabelStmtClass, Empty) { }
+
+  SourceLocation getIdentLoc() const { return IdentLoc; }
+  IdentifierInfo *getID() const { return Label; }
+  void setID(IdentifierInfo *II) { Label = II; }
+  const char *getName() const;
+  Stmt *getSubStmt() { return SubStmt; }
+  const Stmt *getSubStmt() const { return SubStmt; }
+  void setIdentLoc(SourceLocation L) { IdentLoc = L; }
+  void setSubStmt(Stmt *SS) { SubStmt = SS; }
+
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(IdentLoc, SubStmt->getLocEnd());
+  }
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == LabelStmtClass;
+  }
+  static bool classof(const LabelStmt *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+
+/// IfStmt - This represents an if/then/else.
+///
+class IfStmt : public Stmt {
+  enum { COND, THEN, ELSE, END_EXPR };
+  Stmt* SubExprs[END_EXPR];
+
+  /// \brief If non-NULL, the declaration in the "if" statement.
+  VarDecl *Var;
+  
+  SourceLocation IfLoc;
+  SourceLocation ElseLoc;
+  
+public:
+  IfStmt(SourceLocation IL, VarDecl *var, Expr *cond, Stmt *then,
+         SourceLocation EL = SourceLocation(), Stmt *elsev = 0)
+    : Stmt(IfStmtClass), Var(var), IfLoc(IL), ElseLoc(EL)  {
+    SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
+    SubExprs[THEN] = then;
+    SubExprs[ELSE] = elsev;
+  }
+
+  /// \brief Build an empty if/then/else statement
+  explicit IfStmt(EmptyShell Empty) : Stmt(IfStmtClass, Empty) { }
+
+  /// \brief Retrieve the variable declared in this "if" statement, if any.
+  ///
+  /// In the following example, "x" is the condition variable.
+  /// \code
+  /// if (int x = foo()) {
+  ///   printf("x is %d", x);
+  /// }
+  /// \endcode
+  VarDecl *getConditionVariable() const { return Var; }
+  void setConditionVariable(VarDecl *V) { Var = V; }
+  
+  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
+  void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt *>(E); }
+  const Stmt *getThen() const { return SubExprs[THEN]; }
+  void setThen(Stmt *S) { SubExprs[THEN] = S; }
+  const Stmt *getElse() const { return SubExprs[ELSE]; }
+  void setElse(Stmt *S) { SubExprs[ELSE] = S; }
+
+  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
+  Stmt *getThen() { return SubExprs[THEN]; }
+  Stmt *getElse() { return SubExprs[ELSE]; }
+
+  SourceLocation getIfLoc() const { return IfLoc; }
+  void setIfLoc(SourceLocation L) { IfLoc = L; }
+  SourceLocation getElseLoc() const { return ElseLoc; }
+  void setElseLoc(SourceLocation L) { ElseLoc = L; }
+
+  virtual SourceRange getSourceRange() const {
+    if (SubExprs[ELSE])
+      return SourceRange(IfLoc, SubExprs[ELSE]->getLocEnd());
+    else
+      return SourceRange(IfLoc, SubExprs[THEN]->getLocEnd());
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == IfStmtClass;
+  }
+  static bool classof(const IfStmt *) { return true; }
+
+  // Iterators over subexpressions.  The iterators will include iterating
+  // over the initialization expression referenced by the condition variable.
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+
+protected:
+  virtual void DoDestroy(ASTContext &Ctx);
+};
+
+/// SwitchStmt - This represents a 'switch' stmt.
+///
+class SwitchStmt : public Stmt {
+  enum { COND, BODY, END_EXPR };
+  Stmt* SubExprs[END_EXPR];
+  VarDecl *Var;
+  // This points to a linked list of case and default statements.
+  SwitchCase *FirstCase;
+  SourceLocation SwitchLoc;
+
+protected:
+  virtual void DoDestroy(ASTContext &Ctx);
+
+public:
+  SwitchStmt(VarDecl *Var, Expr *cond) 
+    : Stmt(SwitchStmtClass), Var(Var), FirstCase(0) 
+  {
+    SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
+    SubExprs[BODY] = NULL;
+  }
+
+  /// \brief Build a empty switch statement.
+  explicit SwitchStmt(EmptyShell Empty) : Stmt(SwitchStmtClass, Empty) { }
+
+  /// \brief Retrieve the variable declared in this "switch" statement, if any.
+  ///
+  /// In the following example, "x" is the condition variable.
+  /// \code
+  /// switch (int x = foo()) {
+  ///   case 0: break;
+  ///   // ...
+  /// }
+  /// \endcode
+  VarDecl *getConditionVariable() const { return Var; }
+  void setConditionVariable(VarDecl *V) { Var = V; }
+
+  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
+  const Stmt *getBody() const { return SubExprs[BODY]; }
+  const SwitchCase *getSwitchCaseList() const { return FirstCase; }
+
+  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]);}
+  void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt *>(E); }
+  Stmt *getBody() { return SubExprs[BODY]; }
+  void setBody(Stmt *S) { SubExprs[BODY] = S; }
+  SwitchCase *getSwitchCaseList() { return FirstCase; }
+
+  /// \brief Set the case list for this switch statement.
+  ///
+  /// The caller is responsible for incrementing the retain counts on
+  /// all of the SwitchCase statements in this list.
+  void setSwitchCaseList(SwitchCase *SC) { FirstCase = SC; }
+
+  SourceLocation getSwitchLoc() const { return SwitchLoc; }
+  void setSwitchLoc(SourceLocation L) { SwitchLoc = L; }
+
+  void setBody(Stmt *S, SourceLocation SL) {
+    SubExprs[BODY] = S;
+    SwitchLoc = SL;
+  }
+  void addSwitchCase(SwitchCase *SC) {
+    assert(!SC->getNextSwitchCase() && "case/default already added to a switch");
+    SC->Retain();
+    SC->setNextSwitchCase(FirstCase);
+    FirstCase = SC;
+  }
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(SwitchLoc, SubExprs[BODY]->getLocEnd());
+  }
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == SwitchStmtClass;
+  }
+  static bool classof(const SwitchStmt *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+
+/// WhileStmt - This represents a 'while' stmt.
+///
+class WhileStmt : public Stmt {
+  enum { COND, BODY, END_EXPR };
+  VarDecl *Var;
+  Stmt* SubExprs[END_EXPR];
+  SourceLocation WhileLoc;
+public:
+  WhileStmt(VarDecl *Var, Expr *cond, Stmt *body, SourceLocation WL)
+    : Stmt(WhileStmtClass), Var(Var) 
+  {
+    SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
+    SubExprs[BODY] = body;
+    WhileLoc = WL;
+  }
+
+  /// \brief Build an empty while statement.
+  explicit WhileStmt(EmptyShell Empty) : Stmt(WhileStmtClass, Empty) { }
+
+  /// \brief Retrieve the variable declared in this "while" statement, if any.
+  ///
+  /// In the following example, "x" is the condition variable.
+  /// \code
+  /// while (int x = random()) {
+  ///   // ...
+  /// }
+  /// \endcode
+  VarDecl *getConditionVariable() const { return Var; }
+  void setConditionVariable(VarDecl *V) { Var = V; }
+
+  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
+  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
+  void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); }
+  Stmt *getBody() { return SubExprs[BODY]; }
+  const Stmt *getBody() const { return SubExprs[BODY]; }
+  void setBody(Stmt *S) { SubExprs[BODY] = S; }
+
+  SourceLocation getWhileLoc() const { return WhileLoc; }
+  void setWhileLoc(SourceLocation L) { WhileLoc = L; }
+
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(WhileLoc, SubExprs[BODY]->getLocEnd());
+  }
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == WhileStmtClass;
+  }
+  static bool classof(const WhileStmt *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+  
+protected:
+  virtual void DoDestroy(ASTContext &Ctx);
+};
+
+/// DoStmt - This represents a 'do/while' stmt.
+///
+class DoStmt : public Stmt {
+  enum { COND, BODY, END_EXPR };
+  Stmt* SubExprs[END_EXPR];
+  SourceLocation DoLoc;
+  SourceLocation WhileLoc;
+  SourceLocation RParenLoc;  // Location of final ')' in do stmt condition.
+
+public:
+  DoStmt(Stmt *body, Expr *cond, SourceLocation DL, SourceLocation WL,
+         SourceLocation RP)
+    : Stmt(DoStmtClass), DoLoc(DL), WhileLoc(WL), RParenLoc(RP) {
+    SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
+    SubExprs[BODY] = body;
+  }
+
+  /// \brief Build an empty do-while statement.
+  explicit DoStmt(EmptyShell Empty) : Stmt(DoStmtClass, Empty) { }
+
+  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
+  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
+  void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); }
+  Stmt *getBody() { return SubExprs[BODY]; }
+  const Stmt *getBody() const { return SubExprs[BODY]; }
+  void setBody(Stmt *S) { SubExprs[BODY] = S; }
+
+  SourceLocation getDoLoc() const { return DoLoc; }
+  void setDoLoc(SourceLocation L) { DoLoc = L; }
+  SourceLocation getWhileLoc() const { return WhileLoc; }
+  void setWhileLoc(SourceLocation L) { WhileLoc = L; }
+
+  SourceLocation getRParenLoc() const { return RParenLoc; }
+  void setRParenLoc(SourceLocation L) { RParenLoc = L; }
+
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(DoLoc, RParenLoc);
+  }
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == DoStmtClass;
+  }
+  static bool classof(const DoStmt *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+
+/// ForStmt - This represents a 'for (init;cond;inc)' stmt.  Note that any of
+/// the init/cond/inc parts of the ForStmt will be null if they were not
+/// specified in the source.
+///
+class ForStmt : public Stmt {
+  enum { INIT, COND, INC, BODY, END_EXPR };
+  Stmt* SubExprs[END_EXPR]; // SubExprs[INIT] is an expression or declstmt.
+  VarDecl *CondVar;
+  SourceLocation ForLoc;
+  SourceLocation LParenLoc, RParenLoc;
+
+public:
+  ForStmt(Stmt *Init, Expr *Cond, VarDecl *condVar, Expr *Inc, Stmt *Body, 
+          SourceLocation FL, SourceLocation LP, SourceLocation RP)
+    : Stmt(ForStmtClass), CondVar(condVar), ForLoc(FL), LParenLoc(LP), 
+      RParenLoc(RP) 
+  {
+    SubExprs[INIT] = Init;
+    SubExprs[COND] = reinterpret_cast<Stmt*>(Cond);
+    SubExprs[INC] = reinterpret_cast<Stmt*>(Inc);
+    SubExprs[BODY] = Body;
+  }
+
+  /// \brief Build an empty for statement.
+  explicit ForStmt(EmptyShell Empty) : Stmt(ForStmtClass, Empty) { }
+
+  Stmt *getInit() { return SubExprs[INIT]; }
+  
+  /// \brief Retrieve the variable declared in this "for" statement, if any.
+  ///
+  /// In the following example, "y" is the condition variable.
+  /// \code
+  /// for (int x = random(); int y = mangle(x); ++x) {
+  ///   // ...
+  /// }
+  /// \endcode
+  VarDecl *getConditionVariable() const { return CondVar; }
+  void setConditionVariable(VarDecl *V) { CondVar = V; }
+  
+  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
+  Expr *getInc()  { return reinterpret_cast<Expr*>(SubExprs[INC]); }
+  Stmt *getBody() { return SubExprs[BODY]; }
+
+  const Stmt *getInit() const { return SubExprs[INIT]; }
+  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
+  const Expr *getInc()  const { return reinterpret_cast<Expr*>(SubExprs[INC]); }
+  const Stmt *getBody() const { return SubExprs[BODY]; }
+
+  void setInit(Stmt *S) { SubExprs[INIT] = S; }
+  void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); }
+  void setInc(Expr *E) { SubExprs[INC] = reinterpret_cast<Stmt*>(E); }
+  void setBody(Stmt *S) { SubExprs[BODY] = S; }
+
+  SourceLocation getForLoc() const { return ForLoc; }
+  void setForLoc(SourceLocation L) { ForLoc = L; }
+  SourceLocation getLParenLoc() const { return LParenLoc; }
+  void setLParenLoc(SourceLocation L) { LParenLoc = L; }
+  SourceLocation getRParenLoc() const { return RParenLoc; }
+  void setRParenLoc(SourceLocation L) { RParenLoc = L; }
+
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd());
+  }
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ForStmtClass;
+  }
+  static bool classof(const ForStmt *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+  
+protected:
+  virtual void DoDestroy(ASTContext &Ctx);
+};
+
+/// GotoStmt - This represents a direct goto.
+///
+class GotoStmt : public Stmt {
+  LabelStmt *Label;
+  SourceLocation GotoLoc;
+  SourceLocation LabelLoc;
+public:
+  GotoStmt(LabelStmt *label, SourceLocation GL, SourceLocation LL)
+    : Stmt(GotoStmtClass), Label(label), GotoLoc(GL), LabelLoc(LL) {}
+
+  /// \brief Build an empty goto statement.
+  explicit GotoStmt(EmptyShell Empty) : Stmt(GotoStmtClass, Empty) { }
+
+  LabelStmt *getLabel() const { return Label; }
+  void setLabel(LabelStmt *S) { Label = S; }
+
+  SourceLocation getGotoLoc() const { return GotoLoc; }
+  void setGotoLoc(SourceLocation L) { GotoLoc = L; }
+  SourceLocation getLabelLoc() const { return LabelLoc; }
+  void setLabelLoc(SourceLocation L) { LabelLoc = L; }
+
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(GotoLoc, LabelLoc);
+  }
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == GotoStmtClass;
+  }
+  static bool classof(const GotoStmt *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+/// IndirectGotoStmt - This represents an indirect goto.
+///
+class IndirectGotoStmt : public Stmt {
+  SourceLocation GotoLoc;
+  SourceLocation StarLoc;
+  Stmt *Target;
+public:
+  IndirectGotoStmt(SourceLocation gotoLoc, SourceLocation starLoc,
+                   Expr *target)
+    : Stmt(IndirectGotoStmtClass), GotoLoc(gotoLoc), StarLoc(starLoc),
+      Target((Stmt*)target) {}
+
+  /// \brief Build an empty indirect goto statement.
+  explicit IndirectGotoStmt(EmptyShell Empty)
+    : Stmt(IndirectGotoStmtClass, Empty) { }
+
+  void setGotoLoc(SourceLocation L) { GotoLoc = L; }
+  SourceLocation getGotoLoc() const { return GotoLoc; }
+  void setStarLoc(SourceLocation L) { StarLoc = L; }
+  SourceLocation getStarLoc() const { return StarLoc; }
+
+  Expr *getTarget();
+  const Expr *getTarget() const;
+  void setTarget(Expr *E) { Target = reinterpret_cast<Stmt*>(E); }
+
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(GotoLoc, Target->getLocEnd());
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == IndirectGotoStmtClass;
+  }
+  static bool classof(const IndirectGotoStmt *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+
+/// ContinueStmt - This represents a continue.
+///
+class ContinueStmt : public Stmt {
+  SourceLocation ContinueLoc;
+public:
+  ContinueStmt(SourceLocation CL) : Stmt(ContinueStmtClass), ContinueLoc(CL) {}
+
+  /// \brief Build an empty continue statement.
+  explicit ContinueStmt(EmptyShell Empty) : Stmt(ContinueStmtClass, Empty) { }
+
+  SourceLocation getContinueLoc() const { return ContinueLoc; }
+  void setContinueLoc(SourceLocation L) { ContinueLoc = L; }
+
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(ContinueLoc);
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ContinueStmtClass;
+  }
+  static bool classof(const ContinueStmt *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+/// BreakStmt - This represents a break.
+///
+class BreakStmt : public Stmt {
+  SourceLocation BreakLoc;
+public:
+  BreakStmt(SourceLocation BL) : Stmt(BreakStmtClass), BreakLoc(BL) {}
+
+  /// \brief Build an empty break statement.
+  explicit BreakStmt(EmptyShell Empty) : Stmt(BreakStmtClass, Empty) { }
+
+  SourceLocation getBreakLoc() const { return BreakLoc; }
+  void setBreakLoc(SourceLocation L) { BreakLoc = L; }
+
+  virtual SourceRange getSourceRange() const { return SourceRange(BreakLoc); }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == BreakStmtClass;
+  }
+  static bool classof(const BreakStmt *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+
+/// ReturnStmt - This represents a return, optionally of an expression:
+///   return;
+///   return 4;
+///
+/// Note that GCC allows return with no argument in a function declared to
+/// return a value, and it allows returning a value in functions declared to
+/// return void.  We explicitly model this in the AST, which means you can't
+/// depend on the return type of the function and the presence of an argument.
+///
+class ReturnStmt : public Stmt {
+  Stmt *RetExpr;
+  SourceLocation RetLoc;
+public:
+  ReturnStmt(SourceLocation RL, Expr *E = 0) : Stmt(ReturnStmtClass),
+    RetExpr((Stmt*) E), RetLoc(RL) {}
+
+  /// \brief Build an empty return expression.
+  explicit ReturnStmt(EmptyShell Empty) : Stmt(ReturnStmtClass, Empty) { }
+
+  const Expr *getRetValue() const;
+  Expr *getRetValue();
+  void setRetValue(Expr *E) { RetExpr = reinterpret_cast<Stmt*>(E); }
+
+  SourceLocation getReturnLoc() const { return RetLoc; }
+  void setReturnLoc(SourceLocation L) { RetLoc = L; }
+
+  virtual SourceRange getSourceRange() const;
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ReturnStmtClass;
+  }
+  static bool classof(const ReturnStmt *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+/// AsmStmt - This represents a GNU inline-assembly statement extension.
+///
+class AsmStmt : public Stmt {
+  SourceLocation AsmLoc, RParenLoc;
+  StringLiteral *AsmStr;
+
+  bool IsSimple;
+  bool IsVolatile;
+  bool MSAsm;
+
+  unsigned NumOutputs;
+  unsigned NumInputs;
+  unsigned NumClobbers;
+
+  // FIXME: If we wanted to, we could allocate all of these in one big array.
+  IdentifierInfo **Names;
+  StringLiteral **Constraints;
+  Stmt **Exprs;
+  StringLiteral **Clobbers;
+
+protected:
+  virtual void DoDestroy(ASTContext &Ctx);
+  
+public:
+  AsmStmt(ASTContext &C, SourceLocation asmloc, bool issimple, bool isvolatile, 
+          bool msasm, unsigned numoutputs, unsigned numinputs,
+          IdentifierInfo **names, StringLiteral **constraints,
+          Expr **exprs, StringLiteral *asmstr, unsigned numclobbers,
+          StringLiteral **clobbers, SourceLocation rparenloc);
+
+  /// \brief Build an empty inline-assembly statement.
+  explicit AsmStmt(EmptyShell Empty) : Stmt(AsmStmtClass, Empty), 
+    Names(0), Constraints(0), Exprs(0), Clobbers(0) { }
+
+  SourceLocation getAsmLoc() const { return AsmLoc; }
+  void setAsmLoc(SourceLocation L) { AsmLoc = L; }
+  SourceLocation getRParenLoc() const { return RParenLoc; }
+  void setRParenLoc(SourceLocation L) { RParenLoc = L; }
+
+  bool isVolatile() const { return IsVolatile; }
+  void setVolatile(bool V) { IsVolatile = V; }
+  bool isSimple() const { return IsSimple; }
+  void setSimple(bool V) { IsSimple = V; }
+  bool isMSAsm() const { return MSAsm; }
+  void setMSAsm(bool V) { MSAsm = V; }
+
+  //===--- Asm String Analysis ---===//
+
+  const StringLiteral *getAsmString() const { return AsmStr; }
+  StringLiteral *getAsmString() { return AsmStr; }
+  void setAsmString(StringLiteral *E) { AsmStr = E; }
+
+  /// AsmStringPiece - this is part of a decomposed asm string specification
+  /// (for use with the AnalyzeAsmString function below).  An asm string is
+  /// considered to be a concatenation of these parts.
+  class AsmStringPiece {
+  public:
+    enum Kind {
+      String,  // String in .ll asm string form, "$" -> "$$" and "%%" -> "%".
+      Operand  // Operand reference, with optional modifier %c4.
+    };
+  private:
+    Kind MyKind;
+    std::string Str;
+    unsigned OperandNo;
+  public:
+    AsmStringPiece(const std::string &S) : MyKind(String), Str(S) {}
+    AsmStringPiece(unsigned OpNo, char Modifier)
+      : MyKind(Operand), Str(), OperandNo(OpNo) {
+      Str += Modifier;
+    }
+
+    bool isString() const { return MyKind == String; }
+    bool isOperand() const { return MyKind == Operand; }
+
+    const std::string &getString() const {
+      assert(isString());
+      return Str;
+    }
+
+    unsigned getOperandNo() const {
+      assert(isOperand());
+      return OperandNo;
+    }
+
+    /// getModifier - Get the modifier for this operand, if present.  This
+    /// returns '\0' if there was no modifier.
+    char getModifier() const {
+      assert(isOperand());
+      return Str[0];
+    }
+  };
+
+  /// AnalyzeAsmString - Analyze the asm string of the current asm, decomposing
+  /// it into pieces.  If the asm string is erroneous, emit errors and return
+  /// true, otherwise return false.  This handles canonicalization and
+  /// translation of strings from GCC syntax to LLVM IR syntax, and handles
+  //// flattening of named references like %[foo] to Operand AsmStringPiece's.
+  unsigned AnalyzeAsmString(llvm::SmallVectorImpl<AsmStringPiece> &Pieces,
+                            ASTContext &C, unsigned &DiagOffs) const;
+
+
+  //===--- Output operands ---===//
+
+  unsigned getNumOutputs() const { return NumOutputs; }
+
+  IdentifierInfo *getOutputIdentifier(unsigned i) const {
+    return Names[i];
+  }
+
+  llvm::StringRef getOutputName(unsigned i) const {
+    if (IdentifierInfo *II = getOutputIdentifier(i))
+      return II->getName();
+    
+    return llvm::StringRef();
+  }
+
+  /// getOutputConstraint - Return the constraint string for the specified
+  /// output operand.  All output constraints are known to be non-empty (either
+  /// '=' or '+').
+  llvm::StringRef getOutputConstraint(unsigned i) const;
+
+  const StringLiteral *getOutputConstraintLiteral(unsigned i) const {
+    return Constraints[i];
+  }
+  StringLiteral *getOutputConstraintLiteral(unsigned i) {
+    return Constraints[i];
+  }
+
+  Expr *getOutputExpr(unsigned i);
+
+  const Expr *getOutputExpr(unsigned i) const {
+    return const_cast<AsmStmt*>(this)->getOutputExpr(i);
+  }
+
+  /// isOutputPlusConstraint - Return true if the specified output constraint
+  /// is a "+" constraint (which is both an input and an output) or false if it
+  /// is an "=" constraint (just an output).
+  bool isOutputPlusConstraint(unsigned i) const {
+    return getOutputConstraint(i)[0] == '+';
+  }
+
+  /// getNumPlusOperands - Return the number of output operands that have a "+"
+  /// constraint.
+  unsigned getNumPlusOperands() const;
+
+  //===--- Input operands ---===//
+
+  unsigned getNumInputs() const { return NumInputs; }
+
+  IdentifierInfo *getInputIdentifier(unsigned i) const {
+    return Names[i + NumOutputs];
+  }
+
+  llvm::StringRef getInputName(unsigned i) const {
+    if (IdentifierInfo *II = getInputIdentifier(i))
+      return II->getName();
+
+    return llvm::StringRef();
+  }
+
+  /// getInputConstraint - Return the specified input constraint.  Unlike output
+  /// constraints, these can be empty.
+  llvm::StringRef getInputConstraint(unsigned i) const;
+
+  const StringLiteral *getInputConstraintLiteral(unsigned i) const {
+    return Constraints[i + NumOutputs];
+  }
+  StringLiteral *getInputConstraintLiteral(unsigned i) {
+    return Constraints[i + NumOutputs];
+  }
+
+  Expr *getInputExpr(unsigned i);
+
+  const Expr *getInputExpr(unsigned i) const {
+    return const_cast<AsmStmt*>(this)->getInputExpr(i);
+  }
+
+  void setOutputsAndInputsAndClobbers(ASTContext &C,
+                                      IdentifierInfo **Names,
+                                      StringLiteral **Constraints,
+                                      Stmt **Exprs,
+                                      unsigned NumOutputs,
+                                      unsigned NumInputs,                                      
+                                      StringLiteral **Clobbers,
+                                      unsigned NumClobbers);
+
+  //===--- Other ---===//
+
+  /// getNamedOperand - Given a symbolic operand reference like %[foo],
+  /// translate this into a numeric value needed to reference the same operand.
+  /// This returns -1 if the operand name is invalid.
+  int getNamedOperand(llvm::StringRef SymbolicName) const;
+
+  unsigned getNumClobbers() const { return NumClobbers; }
+  StringLiteral *getClobber(unsigned i) { return Clobbers[i]; }
+  const StringLiteral *getClobber(unsigned i) const { return Clobbers[i]; }
+
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(AsmLoc, RParenLoc);
+  }
+
+  static bool classof(const Stmt *T) {return T->getStmtClass() == AsmStmtClass;}
+  static bool classof(const AsmStmt *) { return true; }
+
+  // Input expr iterators.
+
+  typedef ExprIterator inputs_iterator;
+  typedef ConstExprIterator const_inputs_iterator;
+
+  inputs_iterator begin_inputs() {
+    return &Exprs[0] + NumOutputs;
+  }
+
+  inputs_iterator end_inputs() {
+    return &Exprs[0] + NumOutputs + NumInputs;
+  }
+
+  const_inputs_iterator begin_inputs() const {
+    return &Exprs[0] + NumOutputs;
+  }
+
+  const_inputs_iterator end_inputs() const {
+    return &Exprs[0] + NumOutputs + NumInputs;
+  }
+
+  // Output expr iterators.
+
+  typedef ExprIterator outputs_iterator;
+  typedef ConstExprIterator const_outputs_iterator;
+
+  outputs_iterator begin_outputs() {
+    return &Exprs[0];
+  }
+  outputs_iterator end_outputs() {
+    return &Exprs[0] + NumOutputs;
+  }
+
+  const_outputs_iterator begin_outputs() const {
+    return &Exprs[0];
+  }
+  const_outputs_iterator end_outputs() const {
+    return &Exprs[0] + NumOutputs;
+  }
+
+  // Child iterators
+
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/AST/StmtCXX.h b/include/clang/AST/StmtCXX.h
new file mode 100644
index 0000000..4e87c27
--- /dev/null
+++ b/include/clang/AST/StmtCXX.h
@@ -0,0 +1,113 @@
+//===--- StmtCXX.h - Classes for representing C++ statements ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the C++ statement AST node classes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_STMTCXX_H
+#define LLVM_CLANG_AST_STMTCXX_H
+
+#include "clang/AST/Stmt.h"
+
+namespace clang {
+
+class VarDecl;
+
+/// CXXCatchStmt - This represents a C++ catch block.
+///
+class CXXCatchStmt : public Stmt {
+  SourceLocation CatchLoc;
+  /// The exception-declaration of the type.
+  VarDecl *ExceptionDecl;
+  /// The handler block.
+  Stmt *HandlerBlock;
+
+protected:
+  virtual void DoDestroy(ASTContext& Ctx);
+
+public:
+  CXXCatchStmt(SourceLocation catchLoc, VarDecl *exDecl, Stmt *handlerBlock)
+  : Stmt(CXXCatchStmtClass), CatchLoc(catchLoc), ExceptionDecl(exDecl),
+    HandlerBlock(handlerBlock) {}
+
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(CatchLoc, HandlerBlock->getLocEnd());
+  }
+
+  SourceLocation getCatchLoc() const { return CatchLoc; }
+  VarDecl *getExceptionDecl() const { return ExceptionDecl; }
+  QualType getCaughtType() const;
+  Stmt *getHandlerBlock() const { return HandlerBlock; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CXXCatchStmtClass;
+  }
+  static bool classof(const CXXCatchStmt *) { return true; }
+
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+/// CXXTryStmt - A C++ try block, including all handlers.
+///
+class CXXTryStmt : public Stmt {
+  SourceLocation TryLoc;
+  unsigned NumHandlers;
+
+  CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock, Stmt **handlers,
+             unsigned numHandlers);
+
+public:
+  static CXXTryStmt *Create(ASTContext &C, SourceLocation tryLoc,
+                            Stmt *tryBlock, Stmt **handlers,
+                            unsigned numHandlers);
+
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(getTryLoc(), getEndLoc());
+  }
+
+  SourceLocation getTryLoc() const { return TryLoc; }
+  SourceLocation getEndLoc() const {
+    Stmt const * const*Stmts = reinterpret_cast<Stmt const * const*>(this + 1);
+    return Stmts[NumHandlers]->getLocEnd();
+  }
+
+  CompoundStmt *getTryBlock() {
+    Stmt **Stmts = reinterpret_cast<Stmt **>(this + 1);
+    return llvm::cast<CompoundStmt>(Stmts[0]);
+  }
+  const CompoundStmt *getTryBlock() const {
+    Stmt const * const*Stmts = reinterpret_cast<Stmt const * const*>(this + 1);
+    return llvm::cast<CompoundStmt>(Stmts[0]);
+  }
+
+  unsigned getNumHandlers() const { return NumHandlers; }
+  CXXCatchStmt *getHandler(unsigned i) {
+    Stmt **Stmts = reinterpret_cast<Stmt **>(this + 1);
+    return llvm::cast<CXXCatchStmt>(Stmts[i + 1]);
+  }
+  const CXXCatchStmt *getHandler(unsigned i) const {
+    Stmt const * const*Stmts = reinterpret_cast<Stmt const * const*>(this + 1);
+    return llvm::cast<CXXCatchStmt>(Stmts[i + 1]);
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CXXTryStmtClass;
+  }
+  static bool classof(const CXXTryStmt *) { return true; }
+
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/AST/StmtGraphTraits.h b/include/clang/AST/StmtGraphTraits.h
new file mode 100644
index 0000000..25d0152
--- /dev/null
+++ b/include/clang/AST/StmtGraphTraits.h
@@ -0,0 +1,83 @@
+//===--- StmtGraphTraits.h - Graph Traits for the class Stmt ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines a template specialization of llvm::GraphTraits to
+//  treat ASTs (Stmt*) as graphs
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_STMT_GRAPHTRAITS_H
+#define LLVM_CLANG_AST_STMT_GRAPHTRAITS_H
+
+#include "clang/AST/Stmt.h"
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/DepthFirstIterator.h"
+
+namespace llvm {
+
+//template <typename T> struct GraphTraits;
+
+
+template <> struct GraphTraits<clang::Stmt*> {
+  typedef clang::Stmt                       NodeType;
+  typedef clang::Stmt::child_iterator       ChildIteratorType;
+  typedef llvm::df_iterator<clang::Stmt*>   nodes_iterator;
+
+  static NodeType* getEntryNode(clang::Stmt* S) { return S; }
+
+  static inline ChildIteratorType child_begin(NodeType* N) {
+    if (N) return N->child_begin();
+    else return ChildIteratorType();
+  }
+
+  static inline ChildIteratorType child_end(NodeType* N) {
+    if (N) return N->child_end();
+    else return ChildIteratorType();
+  }
+
+  static nodes_iterator nodes_begin(clang::Stmt* S) {
+    return df_begin(S);
+  }
+
+  static nodes_iterator nodes_end(clang::Stmt* S) {
+    return df_end(S);
+  }
+};
+
+
+template <> struct GraphTraits<const clang::Stmt*> {
+  typedef const clang::Stmt                       NodeType;
+  typedef clang::Stmt::const_child_iterator       ChildIteratorType;
+  typedef llvm::df_iterator<const clang::Stmt*>   nodes_iterator;
+
+  static NodeType* getEntryNode(const clang::Stmt* S) { return S; }
+
+  static inline ChildIteratorType child_begin(NodeType* N) {
+    if (N) return N->child_begin();
+    else return ChildIteratorType();
+  }
+
+  static inline ChildIteratorType child_end(NodeType* N) {
+    if (N) return N->child_end();
+    else return ChildIteratorType();
+  }
+
+  static nodes_iterator nodes_begin(const clang::Stmt* S) {
+    return df_begin(S);
+  }
+
+  static nodes_iterator nodes_end(const clang::Stmt* S) {
+    return df_end(S);
+  }
+};
+
+
+} // end namespace llvm
+
+#endif
diff --git a/include/clang/AST/StmtIterator.h b/include/clang/AST/StmtIterator.h
new file mode 100644
index 0000000..a48f4e6
--- /dev/null
+++ b/include/clang/AST/StmtIterator.h
@@ -0,0 +1,150 @@
+//===--- StmtIterator.h - Iterators for Statements ------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the StmtIterator and ConstStmtIterator classes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_STMT_ITR_H
+#define LLVM_CLANG_AST_STMT_ITR_H
+
+#include "llvm/System/DataTypes.h"
+#include <cassert>
+#include <iterator>
+
+namespace clang {
+
+class Stmt;
+class Decl;
+class VariableArrayType;
+
+class StmtIteratorBase {
+protected:
+  enum { DeclMode = 0x1, SizeOfTypeVAMode = 0x2, DeclGroupMode = 0x3,
+         Flags = 0x3 };
+  
+  Stmt **stmt;
+  union { Decl *decl; Decl **DGI; };
+  uintptr_t RawVAPtr;
+  Decl **DGE;
+  
+  bool inDecl() const {
+    return (RawVAPtr & Flags) == DeclMode;
+  }
+
+  bool inDeclGroup() const {
+    return (RawVAPtr & Flags) == DeclGroupMode;
+  }
+
+  bool inSizeOfTypeVA() const {
+    return (RawVAPtr & Flags) == SizeOfTypeVAMode;
+  }
+
+  bool inStmt() const {
+    return (RawVAPtr & Flags) == 0;
+  }
+
+  VariableArrayType* getVAPtr() const {
+    return reinterpret_cast<VariableArrayType*>(RawVAPtr & ~Flags);
+  }
+
+  void setVAPtr(VariableArrayType* P) {
+    assert (inDecl() || inDeclGroup() || inSizeOfTypeVA());
+    RawVAPtr = reinterpret_cast<uintptr_t>(P) | (RawVAPtr & Flags);
+  }
+
+  void NextDecl(bool ImmediateAdvance = true);
+  bool HandleDecl(Decl* D);
+  void NextVA();
+
+  Stmt*& GetDeclExpr() const;
+
+  StmtIteratorBase(Stmt **s) : stmt(s), decl(0), RawVAPtr(0) {}
+  StmtIteratorBase(Decl *d, Stmt **s);
+  StmtIteratorBase(VariableArrayType *t);
+  StmtIteratorBase(Decl **dgi, Decl **dge);
+  StmtIteratorBase() : stmt(0), decl(0), RawVAPtr(0) {}
+};
+
+
+template <typename DERIVED, typename REFERENCE>
+class StmtIteratorImpl : public StmtIteratorBase,
+                         public std::iterator<std::forward_iterator_tag,
+                                              REFERENCE, ptrdiff_t,
+                                              REFERENCE, REFERENCE> {
+protected:
+  StmtIteratorImpl(const StmtIteratorBase& RHS) : StmtIteratorBase(RHS) {}
+public:
+  StmtIteratorImpl() {}
+  StmtIteratorImpl(Stmt **s) : StmtIteratorBase(s) {}
+  StmtIteratorImpl(Decl **dgi, Decl **dge) : StmtIteratorBase(dgi, dge) {}
+  StmtIteratorImpl(Decl *d, Stmt **s) : StmtIteratorBase(d, s) {}
+  StmtIteratorImpl(VariableArrayType* t) : StmtIteratorBase(t) {}
+
+  DERIVED& operator++() {
+    if (inDecl() || inDeclGroup()) {
+      if (getVAPtr()) NextVA();
+      else NextDecl();
+    }
+    else if (inSizeOfTypeVA())
+      NextVA();
+    else
+      ++stmt;
+
+    return static_cast<DERIVED&>(*this);
+  }
+
+  DERIVED operator++(int) {
+    DERIVED tmp = static_cast<DERIVED&>(*this);
+    operator++();
+    return tmp;
+  }
+
+  bool operator==(const DERIVED& RHS) const {
+    return stmt == RHS.stmt && decl == RHS.decl && RawVAPtr == RHS.RawVAPtr;
+  }
+
+  bool operator!=(const DERIVED& RHS) const {
+    return stmt != RHS.stmt || decl != RHS.decl || RawVAPtr != RHS.RawVAPtr;
+  }
+
+  REFERENCE operator*() const {
+    return (REFERENCE) (inStmt() ? *stmt : GetDeclExpr());
+  }
+
+  REFERENCE operator->() const { return operator*(); }
+};
+
+struct StmtIterator : public StmtIteratorImpl<StmtIterator,Stmt*&> {
+  explicit StmtIterator() : StmtIteratorImpl<StmtIterator,Stmt*&>() {}
+
+  StmtIterator(Stmt** S) : StmtIteratorImpl<StmtIterator,Stmt*&>(S) {}
+
+  StmtIterator(Decl** dgi, Decl** dge)
+   : StmtIteratorImpl<StmtIterator,Stmt*&>(dgi, dge) {}
+
+  StmtIterator(VariableArrayType* t)
+    : StmtIteratorImpl<StmtIterator,Stmt*&>(t) {}
+
+  StmtIterator(Decl* D, Stmt **s = 0)
+    : StmtIteratorImpl<StmtIterator,Stmt*&>(D, s) {}
+};
+
+struct ConstStmtIterator : public StmtIteratorImpl<ConstStmtIterator,
+                                                   const Stmt*> {
+  explicit ConstStmtIterator() :
+    StmtIteratorImpl<ConstStmtIterator,const Stmt*>() {}
+
+  ConstStmtIterator(const StmtIterator& RHS) :
+    StmtIteratorImpl<ConstStmtIterator,const Stmt*>(RHS) {}
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/AST/StmtNodes.def b/include/clang/AST/StmtNodes.def
new file mode 100644
index 0000000..4e80ecb
--- /dev/null
+++ b/include/clang/AST/StmtNodes.def
@@ -0,0 +1,164 @@
+//===-- StmtNodes.def - Metadata about Stmt AST nodes -----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the AST Node info database.
+//
+//===---------------------------------------------------------------------===//
+
+#ifndef FIRST_STMT
+#define FIRST_STMT(CLASS)
+#define LAST_STMT(CLASS)
+#endif
+
+#ifndef FIRST_EXPR
+#define FIRST_EXPR(CLASS)
+#define LAST_EXPR(CLASS)
+#endif
+
+#ifndef EXPR
+#  define EXPR(Type, Base) STMT(Type, Base)
+#endif
+
+#ifndef ABSTRACT_EXPR
+#  define ABSTRACT_EXPR(Type, Base) EXPR(Type, Base)
+#endif
+
+// Normal Statements.
+STMT(NullStmt        , Stmt)
+FIRST_STMT(NullStmt)
+STMT(CompoundStmt    , Stmt)
+STMT(CaseStmt        , SwitchCase)
+STMT(DefaultStmt     , SwitchCase)
+STMT(LabelStmt       , Stmt)
+STMT(IfStmt          , Stmt)
+STMT(SwitchStmt      , Stmt)
+STMT(WhileStmt       , Stmt)
+STMT(DoStmt          , Stmt)
+STMT(ForStmt         , Stmt)
+STMT(GotoStmt        , Stmt)
+STMT(IndirectGotoStmt, Stmt)
+STMT(ContinueStmt    , Stmt)
+STMT(BreakStmt       , Stmt)
+STMT(ReturnStmt      , Stmt)
+STMT(DeclStmt        , Stmt)
+STMT(SwitchCase      , Stmt)
+
+// GNU Stmt Extensions
+STMT(AsmStmt         , Stmt)
+
+// Obj-C statements
+STMT(ObjCAtTryStmt        , Stmt)
+STMT(ObjCAtCatchStmt      , Stmt)
+STMT(ObjCAtFinallyStmt    , Stmt)
+STMT(ObjCAtThrowStmt      , Stmt)
+STMT(ObjCAtSynchronizedStmt , Stmt)
+// Obj-C2 statements
+STMT(ObjCForCollectionStmt, Stmt)
+
+// C++ statements
+STMT(CXXCatchStmt, Stmt)
+STMT(CXXTryStmt  , Stmt)
+
+LAST_STMT(CXXTryStmt)
+
+// Expressions.
+ABSTRACT_EXPR(Expr         , Stmt)
+EXPR(PredefinedExpr        , Expr)
+EXPR(DeclRefExpr           , Expr)
+EXPR(IntegerLiteral        , Expr)
+EXPR(FloatingLiteral       , Expr)
+EXPR(ImaginaryLiteral      , Expr)
+EXPR(StringLiteral         , Expr)
+EXPR(CharacterLiteral      , Expr)
+EXPR(ParenExpr             , Expr)
+EXPR(UnaryOperator         , Expr)
+EXPR(SizeOfAlignOfExpr     , Expr)
+EXPR(ArraySubscriptExpr    , Expr)
+EXPR(CallExpr              , Expr)
+EXPR(MemberExpr            , Expr)
+ABSTRACT_EXPR(CastExpr     , Expr)
+EXPR(BinaryOperator        , Expr)
+EXPR(CompoundAssignOperator, BinaryOperator)
+EXPR(ConditionalOperator   , Expr)
+EXPR(ImplicitCastExpr      , CastExpr)
+ABSTRACT_EXPR(ExplicitCastExpr, CastExpr)
+EXPR(CStyleCastExpr        , ExplicitCastExpr)
+EXPR(CompoundLiteralExpr   , Expr)
+EXPR(ExtVectorElementExpr  , Expr)
+EXPR(InitListExpr          , Expr)
+EXPR(DesignatedInitExpr    , Expr)
+EXPR(ImplicitValueInitExpr , Expr)
+EXPR(ParenListExpr         , Expr)
+EXPR(VAArgExpr             , Expr)
+
+// GNU Extensions.
+EXPR(AddrLabelExpr        , Expr)
+EXPR(StmtExpr             , Expr)
+EXPR(TypesCompatibleExpr  , Expr)
+EXPR(ChooseExpr           , Expr)
+EXPR(GNUNullExpr          , Expr)
+
+// C++ Expressions.
+EXPR(CXXOperatorCallExpr    , CallExpr)
+EXPR(CXXMemberCallExpr      , CallExpr)
+ABSTRACT_EXPR(CXXNamedCastExpr       , ExplicitCastExpr)
+EXPR(CXXStaticCastExpr      , CXXNamedCastExpr)
+EXPR(CXXDynamicCastExpr     , CXXNamedCastExpr)
+EXPR(CXXReinterpretCastExpr , CXXNamedCastExpr)
+EXPR(CXXConstCastExpr       , CXXNamedCastExpr)
+EXPR(CXXFunctionalCastExpr  , ExplicitCastExpr)
+EXPR(CXXTypeidExpr          , Expr)
+EXPR(CXXBoolLiteralExpr     , Expr)
+EXPR(CXXNullPtrLiteralExpr  , Expr)
+EXPR(CXXThisExpr            , Expr)
+EXPR(CXXThrowExpr           , Expr)
+EXPR(CXXDefaultArgExpr      , Expr)
+EXPR(CXXZeroInitValueExpr   , Expr)
+EXPR(CXXNewExpr             , Expr)
+EXPR(CXXDeleteExpr          , Expr)
+EXPR(CXXPseudoDestructorExpr, Expr)
+EXPR(UnresolvedLookupExpr   , Expr)
+EXPR(UnaryTypeTraitExpr     , Expr)
+EXPR(DependentScopeDeclRefExpr  , Expr)
+EXPR(CXXConstructExpr       , Expr)
+EXPR(CXXBindTemporaryExpr   , Expr)
+EXPR(CXXBindReferenceExpr   , Expr)
+EXPR(CXXExprWithTemporaries , Expr)
+EXPR(CXXTemporaryObjectExpr , CXXConstructExpr)
+EXPR(CXXUnresolvedConstructExpr, Expr)
+EXPR(CXXDependentScopeMemberExpr, Expr)
+EXPR(UnresolvedMemberExpr   , Expr)
+
+// Obj-C Expressions.
+EXPR(ObjCStringLiteral    , Expr)
+EXPR(ObjCEncodeExpr       , Expr)
+EXPR(ObjCMessageExpr      , Expr)
+EXPR(ObjCSelectorExpr     , Expr)
+EXPR(ObjCProtocolExpr     , Expr)
+EXPR(ObjCIvarRefExpr      , Expr)
+EXPR(ObjCPropertyRefExpr  , Expr)
+EXPR(ObjCImplicitSetterGetterRefExpr , Expr)
+EXPR(ObjCSuperExpr        , Expr)
+EXPR(ObjCIsaExpr          , Expr)
+
+// Clang Extensions.
+EXPR(ShuffleVectorExpr    , Expr)
+EXPR(BlockExpr            , Expr)
+EXPR(BlockDeclRefExpr     , Expr)
+
+FIRST_EXPR(PredefinedExpr)
+LAST_EXPR(BlockDeclRefExpr)
+
+#undef ABSTRACT_EXPR
+#undef EXPR
+#undef STMT
+#undef FIRST_STMT
+#undef LAST_STMT
+#undef FIRST_EXPR
+#undef LAST_EXPR
diff --git a/include/clang/AST/StmtObjC.h b/include/clang/AST/StmtObjC.h
new file mode 100644
index 0000000..269aa4c
--- /dev/null
+++ b/include/clang/AST/StmtObjC.h
@@ -0,0 +1,344 @@
+//===--- StmtObjC.h - Classes for representing ObjC statements --*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the Objective-C statement AST node classes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_STMTOBJC_H
+#define LLVM_CLANG_AST_STMTOBJC_H
+
+#include "clang/AST/Stmt.h"
+
+namespace clang {
+
+/// ObjCForCollectionStmt - This represents Objective-c's collection statement;
+/// represented as 'for (element 'in' collection-expression)' stmt.
+///
+class ObjCForCollectionStmt : public Stmt {
+  enum { ELEM, COLLECTION, BODY, END_EXPR };
+  Stmt* SubExprs[END_EXPR]; // SubExprs[ELEM] is an expression or declstmt.
+  SourceLocation ForLoc;
+  SourceLocation RParenLoc;
+public:
+  ObjCForCollectionStmt(Stmt *Elem, Expr *Collect, Stmt *Body,
+                        SourceLocation FCL, SourceLocation RPL);
+  explicit ObjCForCollectionStmt(EmptyShell Empty) :
+    Stmt(ObjCForCollectionStmtClass, Empty) { }
+
+  Stmt *getElement() { return SubExprs[ELEM]; }
+  Expr *getCollection() {
+    return reinterpret_cast<Expr*>(SubExprs[COLLECTION]);
+  }
+  Stmt *getBody() { return SubExprs[BODY]; }
+
+  const Stmt *getElement() const { return SubExprs[ELEM]; }
+  const Expr *getCollection() const {
+    return reinterpret_cast<Expr*>(SubExprs[COLLECTION]);
+  }
+  const Stmt *getBody() const { return SubExprs[BODY]; }
+
+  void setElement(Stmt *S) { SubExprs[ELEM] = S; }
+  void setCollection(Expr *E) {
+    SubExprs[COLLECTION] = reinterpret_cast<Stmt*>(E);
+  }
+  void setBody(Stmt *S) { SubExprs[BODY] = S; }
+
+  SourceLocation getForLoc() const { return ForLoc; }
+  void setForLoc(SourceLocation Loc) { ForLoc = Loc; }
+  SourceLocation getRParenLoc() const { return RParenLoc; }
+  void setRParenLoc(SourceLocation Loc) { RParenLoc = Loc; }
+
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd());
+  }
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ObjCForCollectionStmtClass;
+  }
+  static bool classof(const ObjCForCollectionStmt *) { return true; }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+/// ObjCAtCatchStmt - This represents objective-c's @catch statement.
+class ObjCAtCatchStmt : public Stmt {
+private:
+  VarDecl *ExceptionDecl;
+  Stmt *Body;
+  SourceLocation AtCatchLoc, RParenLoc;
+
+public:
+  ObjCAtCatchStmt(SourceLocation atCatchLoc, SourceLocation rparenloc,
+                  VarDecl *catchVarDecl,
+                  Stmt *atCatchStmt)
+    : Stmt(ObjCAtCatchStmtClass), ExceptionDecl(catchVarDecl), 
+    Body(atCatchStmt), AtCatchLoc(atCatchLoc), RParenLoc(rparenloc) { }
+
+  explicit ObjCAtCatchStmt(EmptyShell Empty) :
+    Stmt(ObjCAtCatchStmtClass, Empty) { }
+
+  const Stmt *getCatchBody() const { return Body; }
+  Stmt *getCatchBody() { return Body; }
+  void setCatchBody(Stmt *S) { Body = S; }
+
+  const VarDecl *getCatchParamDecl() const {
+    return ExceptionDecl;
+  }
+  VarDecl *getCatchParamDecl() {
+    return ExceptionDecl;
+  }
+  void setCatchParamDecl(VarDecl *D) { ExceptionDecl = D; }
+
+  SourceLocation getAtCatchLoc() const { return AtCatchLoc; }
+  void setAtCatchLoc(SourceLocation Loc) { AtCatchLoc = Loc; }
+  SourceLocation getRParenLoc() const { return RParenLoc; }
+  void setRParenLoc(SourceLocation Loc) { RParenLoc = Loc; }
+
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(AtCatchLoc, Body->getLocEnd());
+  }
+
+  bool hasEllipsis() const { return getCatchParamDecl() == 0; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ObjCAtCatchStmtClass;
+  }
+  static bool classof(const ObjCAtCatchStmt *) { return true; }
+
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+/// ObjCAtFinallyStmt - This represent objective-c's @finally Statement
+class ObjCAtFinallyStmt : public Stmt {
+  Stmt *AtFinallyStmt;
+  SourceLocation AtFinallyLoc;
+public:
+  ObjCAtFinallyStmt(SourceLocation atFinallyLoc, Stmt *atFinallyStmt)
+  : Stmt(ObjCAtFinallyStmtClass),
+    AtFinallyStmt(atFinallyStmt), AtFinallyLoc(atFinallyLoc) {}
+
+  explicit ObjCAtFinallyStmt(EmptyShell Empty) :
+    Stmt(ObjCAtFinallyStmtClass, Empty) { }
+
+  const Stmt *getFinallyBody() const { return AtFinallyStmt; }
+  Stmt *getFinallyBody() { return AtFinallyStmt; }
+  void setFinallyBody(Stmt *S) { AtFinallyStmt = S; }
+
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(AtFinallyLoc, AtFinallyStmt->getLocEnd());
+  }
+
+  SourceLocation getAtFinallyLoc() const { return AtFinallyLoc; }
+  void setAtFinallyLoc(SourceLocation Loc) { AtFinallyLoc = Loc; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ObjCAtFinallyStmtClass;
+  }
+  static bool classof(const ObjCAtFinallyStmt *) { return true; }
+
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+/// ObjCAtTryStmt - This represent objective-c's over-all
+/// @try ... @catch ... @finally statement.
+class ObjCAtTryStmt : public Stmt {
+private:
+  // The location of the 
+  SourceLocation AtTryLoc;
+  
+  // The number of catch blocks in this statement.
+  unsigned NumCatchStmts : 16;
+  
+  // Whether this statement has a @finally statement.
+  bool HasFinally : 1;
+  
+  /// \brief Retrieve the statements that are stored after this @try statement.
+  ///
+  /// The order of the statements in memory follows the order in the source,
+  /// with the @try body first, followed by the @catch statements (if any) and,
+  /// finally, the @finally (if it exists).
+  Stmt **getStmts() { return reinterpret_cast<Stmt **> (this + 1); }
+  const Stmt* const *getStmts() const { 
+    return reinterpret_cast<const Stmt * const*> (this + 1); 
+  }
+  
+  ObjCAtTryStmt(SourceLocation atTryLoc, Stmt *atTryStmt,
+                Stmt **CatchStmts, unsigned NumCatchStmts,
+                Stmt *atFinallyStmt);
+  
+  explicit ObjCAtTryStmt(EmptyShell Empty, unsigned NumCatchStmts,
+                         bool HasFinally)
+    : Stmt(ObjCAtTryStmtClass, Empty), NumCatchStmts(NumCatchStmts),
+      HasFinally(HasFinally) { }
+
+public:
+  static ObjCAtTryStmt *Create(ASTContext &Context, SourceLocation atTryLoc, 
+                               Stmt *atTryStmt,
+                               Stmt **CatchStmts, unsigned NumCatchStmts,
+                               Stmt *atFinallyStmt);
+  static ObjCAtTryStmt *CreateEmpty(ASTContext &Context, 
+                                    unsigned NumCatchStmts,
+                                    bool HasFinally);
+  
+  /// \brief Retrieve the location of the @ in the @try.
+  SourceLocation getAtTryLoc() const { return AtTryLoc; }
+  void setAtTryLoc(SourceLocation Loc) { AtTryLoc = Loc; }
+
+  /// \brief Retrieve the @try body.
+  const Stmt *getTryBody() const { return getStmts()[0]; }
+  Stmt *getTryBody() { return getStmts()[0]; }
+  void setTryBody(Stmt *S) { getStmts()[0] = S; }
+
+  /// \brief Retrieve the number of @catch statements in this try-catch-finally
+  /// block.
+  unsigned getNumCatchStmts() const { return NumCatchStmts; }
+  
+  /// \brief Retrieve a @catch statement.
+  const ObjCAtCatchStmt *getCatchStmt(unsigned I) const {
+    assert(I < NumCatchStmts && "Out-of-bounds @catch index");
+    return cast_or_null<ObjCAtCatchStmt>(getStmts()[I + 1]);
+  }
+  
+  /// \brief Retrieve a @catch statement.
+  ObjCAtCatchStmt *getCatchStmt(unsigned I) {
+    assert(I < NumCatchStmts && "Out-of-bounds @catch index");
+    return cast_or_null<ObjCAtCatchStmt>(getStmts()[I + 1]);
+  }
+  
+  /// \brief Set a particular catch statement.
+  void setCatchStmt(unsigned I, ObjCAtCatchStmt *S) {
+    assert(I < NumCatchStmts && "Out-of-bounds @catch index");
+    getStmts()[I + 1] = S;
+  }
+  
+  /// Retrieve the @finally statement, if any.
+  const ObjCAtFinallyStmt *getFinallyStmt() const {
+    if (!HasFinally)
+      return 0;
+    
+    return cast_or_null<ObjCAtFinallyStmt>(getStmts()[1 + NumCatchStmts]);
+  }
+  ObjCAtFinallyStmt *getFinallyStmt() {
+    if (!HasFinally)
+      return 0;
+    
+    return cast_or_null<ObjCAtFinallyStmt>(getStmts()[1 + NumCatchStmts]);
+  }
+  void setFinallyStmt(Stmt *S) { 
+    assert(HasFinally && "@try does not have a @finally slot!");
+    getStmts()[1 + NumCatchStmts] = S; 
+  }
+
+  virtual SourceRange getSourceRange() const;
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ObjCAtTryStmtClass;
+  }
+  static bool classof(const ObjCAtTryStmt *) { return true; }
+
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+/// ObjCAtSynchronizedStmt - This is for objective-c's @synchronized statement.
+/// Example: @synchronized (sem) {
+///             do-something;
+///          }
+///
+class ObjCAtSynchronizedStmt : public Stmt {
+private:
+  enum { SYNC_EXPR, SYNC_BODY, END_EXPR };
+  Stmt* SubStmts[END_EXPR];
+  SourceLocation AtSynchronizedLoc;
+
+public:
+  ObjCAtSynchronizedStmt(SourceLocation atSynchronizedLoc, Stmt *synchExpr,
+                         Stmt *synchBody)
+  : Stmt(ObjCAtSynchronizedStmtClass) {
+    SubStmts[SYNC_EXPR] = synchExpr;
+    SubStmts[SYNC_BODY] = synchBody;
+    AtSynchronizedLoc = atSynchronizedLoc;
+  }
+  explicit ObjCAtSynchronizedStmt(EmptyShell Empty) :
+    Stmt(ObjCAtSynchronizedStmtClass, Empty) { }
+
+  SourceLocation getAtSynchronizedLoc() const { return AtSynchronizedLoc; }
+  void setAtSynchronizedLoc(SourceLocation Loc) { AtSynchronizedLoc = Loc; }
+
+  const CompoundStmt *getSynchBody() const {
+    return reinterpret_cast<CompoundStmt*>(SubStmts[SYNC_BODY]);
+  }
+  CompoundStmt *getSynchBody() {
+    return reinterpret_cast<CompoundStmt*>(SubStmts[SYNC_BODY]);
+  }
+  void setSynchBody(Stmt *S) { SubStmts[SYNC_BODY] = S; }
+
+  const Expr *getSynchExpr() const {
+    return reinterpret_cast<Expr*>(SubStmts[SYNC_EXPR]);
+  }
+  Expr *getSynchExpr() {
+    return reinterpret_cast<Expr*>(SubStmts[SYNC_EXPR]);
+  }
+  void setSynchExpr(Stmt *S) { SubStmts[SYNC_EXPR] = S; }
+
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(AtSynchronizedLoc, getSynchBody()->getLocEnd());
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ObjCAtSynchronizedStmtClass;
+  }
+  static bool classof(const ObjCAtSynchronizedStmt *) { return true; }
+
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+/// ObjCAtThrowStmt - This represents objective-c's @throw statement.
+class ObjCAtThrowStmt : public Stmt {
+  Stmt *Throw;
+  SourceLocation AtThrowLoc;
+public:
+  ObjCAtThrowStmt(SourceLocation atThrowLoc, Stmt *throwExpr)
+  : Stmt(ObjCAtThrowStmtClass), Throw(throwExpr) {
+    AtThrowLoc = atThrowLoc;
+  }
+  explicit ObjCAtThrowStmt(EmptyShell Empty) :
+    Stmt(ObjCAtThrowStmtClass, Empty) { }
+
+  const Expr *getThrowExpr() const { return reinterpret_cast<Expr*>(Throw); }
+  Expr *getThrowExpr() { return reinterpret_cast<Expr*>(Throw); }
+  void setThrowExpr(Stmt *S) { Throw = S; }
+
+  SourceLocation getThrowLoc() { return AtThrowLoc; }
+  void setThrowLoc(SourceLocation Loc) { AtThrowLoc = Loc; }
+
+  virtual SourceRange getSourceRange() const {
+    if (Throw)
+      return SourceRange(AtThrowLoc, Throw->getLocEnd());
+    else
+      return SourceRange(AtThrowLoc);
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ObjCAtThrowStmtClass;
+  }
+  static bool classof(const ObjCAtThrowStmt *) { return true; }
+
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/AST/StmtVisitor.h b/include/clang/AST/StmtVisitor.h
new file mode 100644
index 0000000..4986f08
--- /dev/null
+++ b/include/clang/AST/StmtVisitor.h
@@ -0,0 +1,177 @@
+//===--- StmtVisitor.h - Visitor for Stmt subclasses ------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the StmtVisitor interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_STMTVISITOR_H
+#define LLVM_CLANG_AST_STMTVISITOR_H
+
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/ExprObjC.h"
+#include "clang/AST/StmtCXX.h"
+#include "clang/AST/StmtObjC.h"
+
+namespace clang {
+
+#define DISPATCH(NAME, CLASS) \
+  return static_cast<ImplClass*>(this)->Visit ## NAME(static_cast<CLASS*>(S))
+
+/// StmtVisitor - This class implements a simple visitor for Stmt subclasses.
+/// Since Expr derives from Stmt, this also includes support for visiting Exprs.
+template<typename ImplClass, typename RetTy=void>
+class StmtVisitor {
+public:
+  RetTy Visit(Stmt *S) {
+
+    // If we have a binary expr, dispatch to the subcode of the binop.  A smart
+    // optimizer (e.g. LLVM) will fold this comparison into the switch stmt
+    // below.
+    if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(S)) {
+      switch (BinOp->getOpcode()) {
+      default: assert(0 && "Unknown binary operator!");
+      case BinaryOperator::PtrMemD:   DISPATCH(BinPtrMemD,   BinaryOperator);
+      case BinaryOperator::PtrMemI:   DISPATCH(BinPtrMemI,   BinaryOperator);
+      case BinaryOperator::Mul:       DISPATCH(BinMul,       BinaryOperator);
+      case BinaryOperator::Div:       DISPATCH(BinDiv,       BinaryOperator);
+      case BinaryOperator::Rem:       DISPATCH(BinRem,       BinaryOperator);
+      case BinaryOperator::Add:       DISPATCH(BinAdd,       BinaryOperator);
+      case BinaryOperator::Sub:       DISPATCH(BinSub,       BinaryOperator);
+      case BinaryOperator::Shl:       DISPATCH(BinShl,       BinaryOperator);
+      case BinaryOperator::Shr:       DISPATCH(BinShr,       BinaryOperator);
+
+      case BinaryOperator::LT:        DISPATCH(BinLT,        BinaryOperator);
+      case BinaryOperator::GT:        DISPATCH(BinGT,        BinaryOperator);
+      case BinaryOperator::LE:        DISPATCH(BinLE,        BinaryOperator);
+      case BinaryOperator::GE:        DISPATCH(BinGE,        BinaryOperator);
+      case BinaryOperator::EQ:        DISPATCH(BinEQ,        BinaryOperator);
+      case BinaryOperator::NE:        DISPATCH(BinNE,        BinaryOperator);
+
+      case BinaryOperator::And:       DISPATCH(BinAnd,       BinaryOperator);
+      case BinaryOperator::Xor:       DISPATCH(BinXor,       BinaryOperator);
+      case BinaryOperator::Or :       DISPATCH(BinOr,        BinaryOperator);
+      case BinaryOperator::LAnd:      DISPATCH(BinLAnd,      BinaryOperator);
+      case BinaryOperator::LOr :      DISPATCH(BinLOr,       BinaryOperator);
+      case BinaryOperator::Assign:    DISPATCH(BinAssign,    BinaryOperator);
+      case BinaryOperator::MulAssign:
+        DISPATCH(BinMulAssign, CompoundAssignOperator);
+      case BinaryOperator::DivAssign:
+        DISPATCH(BinDivAssign, CompoundAssignOperator);
+      case BinaryOperator::RemAssign:
+        DISPATCH(BinRemAssign, CompoundAssignOperator);
+      case BinaryOperator::AddAssign:
+        DISPATCH(BinAddAssign, CompoundAssignOperator);
+      case BinaryOperator::SubAssign:
+        DISPATCH(BinSubAssign, CompoundAssignOperator);
+      case BinaryOperator::ShlAssign:
+        DISPATCH(BinShlAssign, CompoundAssignOperator);
+      case BinaryOperator::ShrAssign:
+        DISPATCH(BinShrAssign, CompoundAssignOperator);
+      case BinaryOperator::AndAssign:
+        DISPATCH(BinAndAssign, CompoundAssignOperator);
+      case BinaryOperator::OrAssign:
+        DISPATCH(BinOrAssign,  CompoundAssignOperator);
+      case BinaryOperator::XorAssign:
+        DISPATCH(BinXorAssign, CompoundAssignOperator);
+      case BinaryOperator::Comma:     DISPATCH(BinComma,     BinaryOperator);
+      }
+    } else if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(S)) {
+      switch (UnOp->getOpcode()) {
+      default: assert(0 && "Unknown unary operator!");
+      case UnaryOperator::PostInc:      DISPATCH(UnaryPostInc,   UnaryOperator);
+      case UnaryOperator::PostDec:      DISPATCH(UnaryPostDec,   UnaryOperator);
+      case UnaryOperator::PreInc:       DISPATCH(UnaryPreInc,    UnaryOperator);
+      case UnaryOperator::PreDec:       DISPATCH(UnaryPreDec,    UnaryOperator);
+      case UnaryOperator::AddrOf:       DISPATCH(UnaryAddrOf,    UnaryOperator);
+      case UnaryOperator::Deref:        DISPATCH(UnaryDeref,     UnaryOperator);
+      case UnaryOperator::Plus:         DISPATCH(UnaryPlus,      UnaryOperator);
+      case UnaryOperator::Minus:        DISPATCH(UnaryMinus,     UnaryOperator);
+      case UnaryOperator::Not:          DISPATCH(UnaryNot,       UnaryOperator);
+      case UnaryOperator::LNot:         DISPATCH(UnaryLNot,      UnaryOperator);
+      case UnaryOperator::Real:         DISPATCH(UnaryReal,      UnaryOperator);
+      case UnaryOperator::Imag:         DISPATCH(UnaryImag,      UnaryOperator);
+      case UnaryOperator::Extension:    DISPATCH(UnaryExtension, UnaryOperator);
+      case UnaryOperator::OffsetOf:     DISPATCH(UnaryOffsetOf,  UnaryOperator);
+      }
+    }
+
+    // Top switch stmt: dispatch to VisitFooStmt for each FooStmt.
+    switch (S->getStmtClass()) {
+    default: assert(0 && "Unknown stmt kind!");
+#define ABSTRACT_EXPR(CLASS, PARENT)
+#define STMT(CLASS, PARENT)                              \
+    case Stmt::CLASS ## Class: DISPATCH(CLASS, CLASS);
+#include "clang/AST/StmtNodes.def"
+    }
+  }
+
+  // If the implementation chooses not to implement a certain visit method, fall
+  // back on VisitExpr or whatever else is the superclass.
+#define STMT(CLASS, PARENT)                                   \
+  RetTy Visit ## CLASS(CLASS *S) { DISPATCH(PARENT, PARENT); }
+#include "clang/AST/StmtNodes.def"
+
+  // If the implementation doesn't implement binary operator methods, fall back
+  // on VisitBinaryOperator.
+#define BINOP_FALLBACK(NAME) \
+  RetTy VisitBin ## NAME(BinaryOperator *S) { \
+    DISPATCH(BinaryOperator, BinaryOperator); \
+  }
+  BINOP_FALLBACK(PtrMemD)                    BINOP_FALLBACK(PtrMemI)
+  BINOP_FALLBACK(Mul)   BINOP_FALLBACK(Div)  BINOP_FALLBACK(Rem)
+  BINOP_FALLBACK(Add)   BINOP_FALLBACK(Sub)  BINOP_FALLBACK(Shl)
+  BINOP_FALLBACK(Shr)
+
+  BINOP_FALLBACK(LT)    BINOP_FALLBACK(GT)   BINOP_FALLBACK(LE)
+  BINOP_FALLBACK(GE)    BINOP_FALLBACK(EQ)   BINOP_FALLBACK(NE)
+  BINOP_FALLBACK(And)   BINOP_FALLBACK(Xor)  BINOP_FALLBACK(Or)
+  BINOP_FALLBACK(LAnd)  BINOP_FALLBACK(LOr)
+
+  BINOP_FALLBACK(Assign)
+  BINOP_FALLBACK(Comma)
+#undef BINOP_FALLBACK
+
+  // If the implementation doesn't implement compound assignment operator
+  // methods, fall back on VisitCompoundAssignOperator.
+#define CAO_FALLBACK(NAME) \
+  RetTy VisitBin ## NAME(CompoundAssignOperator *S) { \
+    DISPATCH(CompoundAssignOperator, CompoundAssignOperator); \
+  }
+  CAO_FALLBACK(MulAssign) CAO_FALLBACK(DivAssign) CAO_FALLBACK(RemAssign)
+  CAO_FALLBACK(AddAssign) CAO_FALLBACK(SubAssign) CAO_FALLBACK(ShlAssign)
+  CAO_FALLBACK(ShrAssign) CAO_FALLBACK(AndAssign) CAO_FALLBACK(OrAssign)
+  CAO_FALLBACK(XorAssign)
+#undef CAO_FALLBACK
+
+  // If the implementation doesn't implement unary operator methods, fall back
+  // on VisitUnaryOperator.
+#define UNARYOP_FALLBACK(NAME) \
+  RetTy VisitUnary ## NAME(UnaryOperator *S) { \
+    DISPATCH(UnaryOperator, UnaryOperator);    \
+  }
+  UNARYOP_FALLBACK(PostInc)   UNARYOP_FALLBACK(PostDec)
+  UNARYOP_FALLBACK(PreInc)    UNARYOP_FALLBACK(PreDec)
+  UNARYOP_FALLBACK(AddrOf)    UNARYOP_FALLBACK(Deref)
+
+  UNARYOP_FALLBACK(Plus)      UNARYOP_FALLBACK(Minus)
+  UNARYOP_FALLBACK(Not)       UNARYOP_FALLBACK(LNot)
+  UNARYOP_FALLBACK(Real)      UNARYOP_FALLBACK(Imag)
+  UNARYOP_FALLBACK(Extension) UNARYOP_FALLBACK(OffsetOf)
+#undef UNARYOP_FALLBACK
+
+  // Base case, ignore it. :)
+  RetTy VisitStmt(Stmt *Node) { return RetTy(); }
+};
+
+#undef DISPATCH
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/AST/TemplateBase.h b/include/clang/AST/TemplateBase.h
new file mode 100644
index 0000000..50a100c
--- /dev/null
+++ b/include/clang/AST/TemplateBase.h
@@ -0,0 +1,478 @@
+//===-- TemplateBase.h - Core classes for C++ templates ---------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file provides definitions which are common for all kinds of
+//  template representation.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_TEMPLATEBASE_H
+#define LLVM_CLANG_AST_TEMPLATEBASE_H
+
+#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/TemplateName.h"
+
+namespace llvm {
+  class FoldingSetNodeID;
+}
+
+namespace clang {
+
+class Decl;
+class Expr;
+class TypeSourceInfo;
+
+/// \brief Represents a template argument within a class template
+/// specialization.
+class TemplateArgument {
+  union {
+    uintptr_t TypeOrValue;
+    struct {
+      char Value[sizeof(llvm::APSInt)];
+      void *Type;
+    } Integer;
+    struct {
+      TemplateArgument *Args;
+      unsigned NumArgs;
+      bool CopyArgs;
+    } Args;
+  };
+
+public:
+  /// \brief The type of template argument we're storing.
+  enum ArgKind {
+    /// \brief Represents an empty template argument, e.g., one that has not
+    /// been deduced.
+    Null = 0,
+    /// The template argument is a type. Its value is stored in the
+    /// TypeOrValue field.
+    Type,
+    /// The template argument is a declaration that was provided for a pointer
+    /// or reference non-type template parameter.
+    Declaration,
+    /// The template argument is an integral value stored in an llvm::APSInt
+    /// that was provided for an integral non-type template parameter. 
+    Integral,
+    /// The template argument is a template name that was provided for a 
+    /// template template parameter.
+    Template,
+    /// The template argument is a value- or type-dependent expression
+    /// stored in an Expr*.
+    Expression,
+    /// The template argument is actually a parameter pack. Arguments are stored
+    /// in the Args struct.
+    Pack
+  } Kind;
+
+  /// \brief Construct an empty, invalid template argument.
+  TemplateArgument() : TypeOrValue(0), Kind(Null) { }
+
+  /// \brief Construct a template type argument.
+  TemplateArgument(QualType T) : Kind(Type) {
+    TypeOrValue = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
+  }
+
+  /// \brief Construct a template argument that refers to a
+  /// declaration, which is either an external declaration or a
+  /// template declaration.
+  TemplateArgument(Decl *D) : Kind(Declaration) {
+    // FIXME: Need to be sure we have the "canonical" declaration!
+    TypeOrValue = reinterpret_cast<uintptr_t>(D);
+  }
+
+  /// \brief Construct an integral constant template argument.
+  TemplateArgument(const llvm::APSInt &Value, QualType Type) : Kind(Integral) {
+    new (Integer.Value) llvm::APSInt(Value);
+    Integer.Type = Type.getAsOpaquePtr();
+  }
+
+  /// \brief Construct a template argument that is a template.
+  ///
+  /// This form of template argument is generally used for template template
+  /// parameters. However, the template name could be a dependent template
+  /// name that ends up being instantiated to a function template whose address
+  /// is taken.
+  TemplateArgument(TemplateName Name) : Kind(Template) {
+    TypeOrValue = reinterpret_cast<uintptr_t>(Name.getAsVoidPointer());
+  }
+  
+  /// \brief Construct a template argument that is an expression.
+  ///
+  /// This form of template argument only occurs in template argument
+  /// lists used for dependent types and for expression; it will not
+  /// occur in a non-dependent, canonical template argument list.
+  TemplateArgument(Expr *E) : Kind(Expression) {
+    TypeOrValue = reinterpret_cast<uintptr_t>(E);
+  }
+
+  /// \brief Copy constructor for a template argument.
+  TemplateArgument(const TemplateArgument &Other) : Kind(Other.Kind) {
+    if (Kind == Integral) {
+      new (Integer.Value) llvm::APSInt(*Other.getAsIntegral());
+      Integer.Type = Other.Integer.Type;
+    } else if (Kind == Pack) {
+      Args.NumArgs = Other.Args.NumArgs;
+      Args.Args = new TemplateArgument[Args.NumArgs];
+      for (unsigned I = 0; I != Args.NumArgs; ++I)
+        Args.Args[I] = Other.Args.Args[I];
+    }
+    else
+      TypeOrValue = Other.TypeOrValue;
+  }
+
+  TemplateArgument& operator=(const TemplateArgument& Other) {
+    // FIXME: Does not provide the strong guarantee for exception
+    // safety.
+    using llvm::APSInt;
+
+    // FIXME: Handle Packs
+    assert(Kind != Pack && "FIXME: Handle packs");
+    assert(Other.Kind != Pack && "FIXME: Handle packs");
+
+    if (Kind == Other.Kind && Kind == Integral) {
+      // Copy integral values.
+      *this->getAsIntegral() = *Other.getAsIntegral();
+      Integer.Type = Other.Integer.Type;
+    } else {
+      // Destroy the current integral value, if that's what we're holding.
+      if (Kind == Integral)
+        getAsIntegral()->~APSInt();
+
+      Kind = Other.Kind;
+
+      if (Other.Kind == Integral) {
+        new (Integer.Value) llvm::APSInt(*Other.getAsIntegral());
+        Integer.Type = Other.Integer.Type;
+      } else
+        TypeOrValue = Other.TypeOrValue;
+    }
+
+    return *this;
+  }
+
+  ~TemplateArgument() {
+    using llvm::APSInt;
+
+    if (Kind == Integral)
+      getAsIntegral()->~APSInt();
+    else if (Kind == Pack && Args.CopyArgs)
+      delete[] Args.Args;
+  }
+
+  /// \brief Return the kind of stored template argument.
+  ArgKind getKind() const { return Kind; }
+
+  /// \brief Determine whether this template argument has no value.
+  bool isNull() const { return Kind == Null; }
+
+  /// \brief Retrieve the template argument as a type.
+  QualType getAsType() const {
+    if (Kind != Type)
+      return QualType();
+
+    return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue));
+  }
+
+  /// \brief Retrieve the template argument as a declaration.
+  Decl *getAsDecl() const {
+    if (Kind != Declaration)
+      return 0;
+    return reinterpret_cast<Decl *>(TypeOrValue);
+  }
+
+  /// \brief Retrieve the template argument as a template name.
+  TemplateName getAsTemplate() const {
+    if (Kind != Template)
+      return TemplateName();
+    
+    return TemplateName::getFromVoidPointer(
+                                        reinterpret_cast<void *> (TypeOrValue));
+  }
+  
+  /// \brief Retrieve the template argument as an integral value.
+  llvm::APSInt *getAsIntegral() {
+    if (Kind != Integral)
+      return 0;
+    return reinterpret_cast<llvm::APSInt*>(&Integer.Value[0]);
+  }
+
+  const llvm::APSInt *getAsIntegral() const {
+    return const_cast<TemplateArgument*>(this)->getAsIntegral();
+  }
+
+  /// \brief Retrieve the type of the integral value.
+  QualType getIntegralType() const {
+    if (Kind != Integral)
+      return QualType();
+
+    return QualType::getFromOpaquePtr(Integer.Type);
+  }
+
+  void setIntegralType(QualType T) {
+    assert(Kind == Integral &&
+           "Cannot set the integral type of a non-integral template argument");
+    Integer.Type = T.getAsOpaquePtr();
+  }
+
+  /// \brief Retrieve the template argument as an expression.
+  Expr *getAsExpr() const {
+    if (Kind != Expression)
+      return 0;
+
+    return reinterpret_cast<Expr *>(TypeOrValue);
+  }
+
+  /// \brief Iterator that traverses the elements of a template argument pack.
+  typedef const TemplateArgument * pack_iterator;
+
+  /// \brief Iterator referencing the first argument of a template argument
+  /// pack.
+  pack_iterator pack_begin() const {
+    assert(Kind == Pack);
+    return Args.Args;
+  }
+
+  /// \brief Iterator referencing one past the last argument of a template
+  /// argument pack.
+  pack_iterator pack_end() const {
+    assert(Kind == Pack);
+    return Args.Args + Args.NumArgs;
+  }
+
+  /// \brief The number of template arguments in the given template argument
+  /// pack.
+  unsigned pack_size() const {
+    assert(Kind == Pack);
+    return Args.NumArgs;
+  }
+
+  /// \brief Construct a template argument pack.
+  void setArgumentPack(TemplateArgument *Args, unsigned NumArgs, bool CopyArgs);
+
+  /// \brief Used to insert TemplateArguments into FoldingSets.
+  void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context) const;
+};
+
+/// Location information for a TemplateArgument.
+struct TemplateArgumentLocInfo {
+private:
+  union {
+    Expr *Expression;
+    TypeSourceInfo *Declarator;
+    struct {
+      unsigned QualifierRange[2];
+      unsigned TemplateNameLoc;
+    } Template;
+  };
+
+#ifndef NDEBUG
+  enum Kind {
+    K_None,
+    K_TypeSourceInfo,
+    K_Expression,
+    K_Template
+  } Kind;
+#endif
+
+public:
+  TemplateArgumentLocInfo()
+    : Expression(0)
+#ifndef NDEBUG
+      , Kind(K_None) 
+#endif
+    {}
+  
+  TemplateArgumentLocInfo(TypeSourceInfo *TInfo)
+    : Declarator(TInfo)
+#ifndef NDEBUG
+      , Kind(K_TypeSourceInfo) 
+#endif
+    {}
+  
+  TemplateArgumentLocInfo(Expr *E)
+    : Expression(E)
+#ifndef NDEBUG
+      , Kind(K_Expression) 
+#endif
+    {}
+  
+  TemplateArgumentLocInfo(SourceRange QualifierRange, 
+                          SourceLocation TemplateNameLoc)
+#ifndef NDEBUG
+    : Kind(K_Template)
+#endif
+  {
+    Template.QualifierRange[0] = QualifierRange.getBegin().getRawEncoding();
+    Template.QualifierRange[1] = QualifierRange.getEnd().getRawEncoding();
+    Template.TemplateNameLoc = TemplateNameLoc.getRawEncoding();
+  }
+
+  TypeSourceInfo *getAsTypeSourceInfo() const {
+    assert(Kind == K_TypeSourceInfo);
+    return Declarator;
+  }
+
+  Expr *getAsExpr() const {
+    assert(Kind == K_Expression);
+    return Expression;
+  }
+
+  SourceRange getTemplateQualifierRange() const {
+    assert(Kind == K_Template);
+    return SourceRange(
+                SourceLocation::getFromRawEncoding(Template.QualifierRange[0]),
+                SourceLocation::getFromRawEncoding(Template.QualifierRange[1]));
+  }
+  
+  SourceLocation getTemplateNameLoc() const {
+    assert(Kind == K_Template);
+    return SourceLocation::getFromRawEncoding(Template.TemplateNameLoc);
+  }
+  
+#ifndef NDEBUG
+  void validateForArgument(const TemplateArgument &Arg) {
+    switch (Arg.getKind()) {
+    case TemplateArgument::Type:
+      assert(Kind == K_TypeSourceInfo);
+      break;
+    case TemplateArgument::Expression:
+    case TemplateArgument::Declaration:
+      assert(Kind == K_Expression);
+      break;
+    case TemplateArgument::Template:
+      assert(Kind == K_Template);
+      break;
+    case TemplateArgument::Integral:
+    case TemplateArgument::Pack:
+      assert(Kind == K_None);
+      break;
+    case TemplateArgument::Null:
+      llvm_unreachable("source info for null template argument?");
+    }
+  }
+#endif
+};
+
+/// Location wrapper for a TemplateArgument.  TemplateArgument is to
+/// TemplateArgumentLoc as Type is to TypeLoc.
+class TemplateArgumentLoc {
+  TemplateArgument Argument;
+  TemplateArgumentLocInfo LocInfo;
+
+public:
+  TemplateArgumentLoc() {}
+
+  TemplateArgumentLoc(const TemplateArgument &Argument,
+                      TemplateArgumentLocInfo Opaque)
+    : Argument(Argument), LocInfo(Opaque) {
+  }
+
+  TemplateArgumentLoc(const TemplateArgument &Argument, TypeSourceInfo *TInfo)
+    : Argument(Argument), LocInfo(TInfo) {
+    assert(Argument.getKind() == TemplateArgument::Type);
+  }
+
+  TemplateArgumentLoc(const TemplateArgument &Argument, Expr *E)
+    : Argument(Argument), LocInfo(E) {
+    assert(Argument.getKind() == TemplateArgument::Expression);
+  }
+
+  TemplateArgumentLoc(const TemplateArgument &Argument, 
+                      SourceRange QualifierRange,
+                      SourceLocation TemplateNameLoc)
+    : Argument(Argument), LocInfo(QualifierRange, TemplateNameLoc) {
+    assert(Argument.getKind() == TemplateArgument::Template);
+  }
+  
+  /// \brief - Fetches the primary location of the argument.
+  SourceLocation getLocation() const {
+    if (Argument.getKind() == TemplateArgument::Template)
+      return getTemplateNameLoc();
+    
+    return getSourceRange().getBegin();
+  }
+
+  /// \brief - Fetches the full source range of the argument.
+  SourceRange getSourceRange() const;
+
+  const TemplateArgument &getArgument() const {
+    return Argument;
+  }
+
+  TemplateArgumentLocInfo getLocInfo() const {
+    return LocInfo;
+  }
+
+  TypeSourceInfo *getTypeSourceInfo() const {
+    assert(Argument.getKind() == TemplateArgument::Type);
+    return LocInfo.getAsTypeSourceInfo();
+  }
+
+  Expr *getSourceExpression() const {
+    assert(Argument.getKind() == TemplateArgument::Expression);
+    return LocInfo.getAsExpr();
+  }
+
+  Expr *getSourceDeclExpression() const {
+    assert(Argument.getKind() == TemplateArgument::Declaration);
+    return LocInfo.getAsExpr();
+  }
+  
+  SourceRange getTemplateQualifierRange() const {
+    assert(Argument.getKind() == TemplateArgument::Template);
+    return LocInfo.getTemplateQualifierRange();
+  }
+  
+  SourceLocation getTemplateNameLoc() const {
+    assert(Argument.getKind() == TemplateArgument::Template);
+    return LocInfo.getTemplateNameLoc();
+  }  
+};
+
+/// A convenient class for passing around template argument
+/// information.  Designed to be passed by reference.
+class TemplateArgumentListInfo {
+  llvm::SmallVector<TemplateArgumentLoc, 8> Arguments;
+  SourceLocation LAngleLoc;
+  SourceLocation RAngleLoc;
+
+public:
+  TemplateArgumentListInfo() {}
+
+  TemplateArgumentListInfo(SourceLocation LAngleLoc,
+                           SourceLocation RAngleLoc)
+    : LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc) {}
+
+  SourceLocation getLAngleLoc() const { return LAngleLoc; }
+  SourceLocation getRAngleLoc() const { return RAngleLoc; }
+
+  void setLAngleLoc(SourceLocation Loc) { LAngleLoc = Loc; }
+  void setRAngleLoc(SourceLocation Loc) { RAngleLoc = Loc; }
+
+  unsigned size() const { return Arguments.size(); }
+
+  const TemplateArgumentLoc *getArgumentArray() const {
+    return Arguments.data();
+  }
+
+  const TemplateArgumentLoc &operator[](unsigned I) const {
+    return Arguments[I];
+  }
+
+  void addArgument(const TemplateArgumentLoc &Loc) {
+    Arguments.push_back(Loc);
+  }
+};
+
+}
+
+#endif
diff --git a/include/clang/AST/TemplateName.h b/include/clang/AST/TemplateName.h
new file mode 100644
index 0000000..f3de9fa
--- /dev/null
+++ b/include/clang/AST/TemplateName.h
@@ -0,0 +1,372 @@
+//===--- TemplateName.h - C++ Template Name Representation-------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the TemplateName interface and subclasses.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_TEMPLATENAME_H
+#define LLVM_CLANG_AST_TEMPLATENAME_H
+
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/PointerUnion.h"
+#include "clang/Basic/OperatorKinds.h"
+
+namespace llvm {
+  class raw_ostream;
+}
+
+namespace clang {
+
+class DependentTemplateName;
+class DiagnosticBuilder;
+class IdentifierInfo;
+class NestedNameSpecifier;
+struct PrintingPolicy;
+class QualifiedTemplateName;
+class NamedDecl;
+class TemplateDecl;
+
+/// \brief A structure for storing the information associated with an
+/// overloaded template name.
+class OverloadedTemplateStorage {
+  union {
+    unsigned Size;
+    NamedDecl *Storage[1];
+  };
+
+  friend class ASTContext;
+
+  OverloadedTemplateStorage(unsigned Size) : Size(Size) {}
+
+  NamedDecl **getStorage() {
+    return &Storage[1];
+  }
+  NamedDecl * const *getStorage() const {
+    return &Storage[1];
+  }
+
+public:
+  typedef NamedDecl *const *iterator;
+
+  unsigned size() const { return Size; }
+
+  iterator begin() const { return getStorage(); }
+  iterator end() const { return getStorage() + size(); }
+};
+
+/// \brief Represents a C++ template name within the type system.
+///
+/// A C++ template name refers to a template within the C++ type
+/// system. In most cases, a template name is simply a reference to a
+/// class template, e.g.
+///
+/// \code
+/// template<typename T> class X { };
+///
+/// X<int> xi;
+/// \endcode
+///
+/// Here, the 'X' in \c X<int> is a template name that refers to the
+/// declaration of the class template X, above. Template names can
+/// also refer to function templates, C++0x template aliases, etc.
+///
+/// Some template names are dependent. For example, consider:
+///
+/// \code
+/// template<typename MetaFun, typename T1, typename T2> struct apply2 {
+///   typedef typename MetaFun::template apply<T1, T2>::type type;
+/// };
+/// \endcode
+///
+/// Here, "apply" is treated as a template name within the typename
+/// specifier in the typedef. "apply" is a nested template, and can
+/// only be understood in the context of
+class TemplateName {
+  typedef llvm::PointerUnion4<TemplateDecl *,
+                              OverloadedTemplateStorage *,
+                              QualifiedTemplateName *,
+                              DependentTemplateName *> StorageType;
+
+  StorageType Storage;
+
+  explicit TemplateName(void *Ptr) {
+    Storage = StorageType::getFromOpaqueValue(Ptr);
+  }
+
+public:
+  TemplateName() : Storage() { }
+  explicit TemplateName(TemplateDecl *Template) : Storage(Template) { }
+  explicit TemplateName(OverloadedTemplateStorage *Storage)
+    : Storage(Storage) { }
+  explicit TemplateName(QualifiedTemplateName *Qual) : Storage(Qual) { }
+  explicit TemplateName(DependentTemplateName *Dep) : Storage(Dep) { }
+
+  /// \brief Determine whether this template name is NULL.
+  bool isNull() const { return Storage.isNull(); }
+
+  /// \brief Retrieve the the underlying template declaration that
+  /// this template name refers to, if known.
+  ///
+  /// \returns The template declaration that this template name refers
+  /// to, if any. If the template name does not refer to a specific
+  /// declaration because it is a dependent name, or if it refers to a
+  /// set of function templates, returns NULL.
+  TemplateDecl *getAsTemplateDecl() const;
+
+  /// \brief Retrieve the the underlying, overloaded function template
+  // declarations that this template name refers to, if known.
+  ///
+  /// \returns The set of overloaded function templates that this template
+  /// name refers to, if known. If the template name does not refer to a
+  /// specific set of function templates because it is a dependent name or
+  /// refers to a single template, returns NULL.
+  OverloadedTemplateStorage *getAsOverloadedTemplate() const {
+    return Storage.dyn_cast<OverloadedTemplateStorage *>();
+  }
+
+  /// \brief Retrieve the underlying qualified template name
+  /// structure, if any.
+  QualifiedTemplateName *getAsQualifiedTemplateName() const {
+    return Storage.dyn_cast<QualifiedTemplateName *>();
+  }
+
+  /// \brief Retrieve the underlying dependent template name
+  /// structure, if any.
+  DependentTemplateName *getAsDependentTemplateName() const {
+    return Storage.dyn_cast<DependentTemplateName *>();
+  }
+
+  /// \brief Determines whether this is a dependent template name.
+  bool isDependent() const;
+
+  /// \brief Print the template name.
+  ///
+  /// \param OS the output stream to which the template name will be
+  /// printed.
+  ///
+  /// \param SuppressNNS if true, don't print the
+  /// nested-name-specifier that precedes the template name (if it has
+  /// one).
+  void print(llvm::raw_ostream &OS, const PrintingPolicy &Policy,
+             bool SuppressNNS = false) const;
+
+  /// \brief Debugging aid that dumps the template name to standard
+  /// error.
+  void dump() const;
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    ID.AddPointer(Storage.getOpaqueValue());
+  }
+
+  /// \brief Retrieve the template name as a void pointer.
+  void *getAsVoidPointer() const { return Storage.getOpaqueValue(); }
+
+  /// \brief Build a template name from a void pointer.
+  static TemplateName getFromVoidPointer(void *Ptr) {
+    return TemplateName(Ptr);
+  }
+};
+
+/// Insertion operator for diagnostics.  This allows sending TemplateName's
+/// into a diagnostic with <<.
+const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+                                    TemplateName N);
+
+/// \brief Represents a template name that was expressed as a
+/// qualified name.
+///
+/// This kind of template name refers to a template name that was
+/// preceded by a nested name specifier, e.g., \c std::vector. Here,
+/// the nested name specifier is "std::" and the template name is the
+/// declaration for "vector". The QualifiedTemplateName class is only
+/// used to provide "sugar" for template names that were expressed
+/// with a qualified name, and has no semantic meaning. In this
+/// manner, it is to TemplateName what QualifiedNameType is to Type,
+/// providing extra syntactic sugar for downstream clients.
+class QualifiedTemplateName : public llvm::FoldingSetNode {
+  /// \brief The nested name specifier that qualifies the template name.
+  ///
+  /// The bit is used to indicate whether the "template" keyword was
+  /// present before the template name itself. Note that the
+  /// "template" keyword is always redundant in this case (otherwise,
+  /// the template name would be a dependent name and we would express
+  /// this name with DependentTemplateName).
+  llvm::PointerIntPair<NestedNameSpecifier *, 1> Qualifier;
+
+  /// \brief The template declaration or set of overloaded function templates
+  /// that this qualified name refers to.
+  TemplateDecl *Template;
+
+  friend class ASTContext;
+
+  QualifiedTemplateName(NestedNameSpecifier *NNS, bool TemplateKeyword,
+                        TemplateDecl *Template)
+    : Qualifier(NNS, TemplateKeyword? 1 : 0),
+      Template(Template) { }
+
+public:
+  /// \brief Return the nested name specifier that qualifies this name.
+  NestedNameSpecifier *getQualifier() const { return Qualifier.getPointer(); }
+
+  /// \brief Whether the template name was prefixed by the "template"
+  /// keyword.
+  bool hasTemplateKeyword() const { return Qualifier.getInt(); }
+
+  /// \brief The template declaration that this qualified name refers
+  /// to.
+  TemplateDecl *getDecl() const { return Template; }
+
+  /// \brief The template declaration to which this qualified name
+  /// refers.
+  TemplateDecl *getTemplateDecl() const { return Template; }
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    Profile(ID, getQualifier(), hasTemplateKeyword(), getTemplateDecl());
+  }
+
+  static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS,
+                      bool TemplateKeyword, TemplateDecl *Template) {
+    ID.AddPointer(NNS);
+    ID.AddBoolean(TemplateKeyword);
+    ID.AddPointer(Template);
+  }
+};
+
+/// \brief Represents a dependent template name that cannot be
+/// resolved prior to template instantiation.
+///
+/// This kind of template name refers to a dependent template name,
+/// including its nested name specifier (if any). For example,
+/// DependentTemplateName can refer to "MetaFun::template apply",
+/// where "MetaFun::" is the nested name specifier and "apply" is the
+/// template name referenced. The "template" keyword is implied.
+class DependentTemplateName : public llvm::FoldingSetNode {
+  /// \brief The nested name specifier that qualifies the template
+  /// name.
+  ///
+  /// The bit stored in this qualifier describes whether the \c Name field
+  /// is interpreted as an IdentifierInfo pointer (when clear) or as an
+  /// overloaded operator kind (when set).
+  llvm::PointerIntPair<NestedNameSpecifier *, 1, bool> Qualifier;
+
+  /// \brief The dependent template name.
+  union {
+    /// \brief The identifier template name.
+    ///
+    /// Only valid when the bit on \c Qualifier is clear.
+    const IdentifierInfo *Identifier;
+    
+    /// \brief The overloaded operator name.
+    ///
+    /// Only valid when the bit on \c Qualifier is set.
+    OverloadedOperatorKind Operator;
+  };
+
+  /// \brief The canonical template name to which this dependent
+  /// template name refers.
+  ///
+  /// The canonical template name for a dependent template name is
+  /// another dependent template name whose nested name specifier is
+  /// canonical.
+  TemplateName CanonicalTemplateName;
+
+  friend class ASTContext;
+
+  DependentTemplateName(NestedNameSpecifier *Qualifier,
+                        const IdentifierInfo *Identifier)
+    : Qualifier(Qualifier, false), Identifier(Identifier), 
+      CanonicalTemplateName(this) { }
+
+  DependentTemplateName(NestedNameSpecifier *Qualifier,
+                        const IdentifierInfo *Identifier,
+                        TemplateName Canon)
+    : Qualifier(Qualifier, false), Identifier(Identifier), 
+      CanonicalTemplateName(Canon) { }
+
+  DependentTemplateName(NestedNameSpecifier *Qualifier,
+                        OverloadedOperatorKind Operator)
+  : Qualifier(Qualifier, true), Operator(Operator), 
+    CanonicalTemplateName(this) { }
+  
+  DependentTemplateName(NestedNameSpecifier *Qualifier,
+                        OverloadedOperatorKind Operator,
+                        TemplateName Canon)
+  : Qualifier(Qualifier, true), Operator(Operator), 
+    CanonicalTemplateName(Canon) { }
+  
+public:
+  /// \brief Return the nested name specifier that qualifies this name.
+  NestedNameSpecifier *getQualifier() const { return Qualifier.getPointer(); }
+
+  /// \brief Determine whether this template name refers to an identifier.
+  bool isIdentifier() const { return !Qualifier.getInt(); }
+
+  /// \brief Returns the identifier to which this template name refers.
+  const IdentifierInfo *getIdentifier() const { 
+    assert(isIdentifier() && "Template name isn't an identifier?");
+    return Identifier;
+  }
+  
+  /// \brief Determine whether this template name refers to an overloaded
+  /// operator.
+  bool isOverloadedOperator() const { return Qualifier.getInt(); }
+  
+  /// \brief Return the overloaded operator to which this template name refers.
+  OverloadedOperatorKind getOperator() const { 
+    assert(isOverloadedOperator() &&
+           "Template name isn't an overloaded operator?");
+    return Operator; 
+  }
+  
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    if (isIdentifier())
+      Profile(ID, getQualifier(), getIdentifier());
+    else
+      Profile(ID, getQualifier(), getOperator());
+  }
+
+  static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS,
+                      const IdentifierInfo *Identifier) {
+    ID.AddPointer(NNS);
+    ID.AddBoolean(false);
+    ID.AddPointer(Identifier);
+  }
+
+  static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS,
+                      OverloadedOperatorKind Operator) {
+    ID.AddPointer(NNS);
+    ID.AddBoolean(true);
+    ID.AddInteger(Operator);
+  }
+};
+
+} // end namespace clang.
+
+namespace llvm {
+
+/// \brief The clang::TemplateName class is effectively a pointer.
+template<>
+class PointerLikeTypeTraits<clang::TemplateName> {
+public:
+  static inline void *getAsVoidPointer(clang::TemplateName TN) {
+    return TN.getAsVoidPointer();
+  }
+
+  static inline clang::TemplateName getFromVoidPointer(void *Ptr) {
+    return clang::TemplateName::getFromVoidPointer(Ptr);
+  }
+
+  // No bits are available!
+  enum { NumLowBitsAvailable = 0 };
+};
+
+} // end namespace llvm.
+
+#endif
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
new file mode 100644
index 0000000..5f53774
--- /dev/null
+++ b/include/clang/AST/Type.h
@@ -0,0 +1,3304 @@
+//===--- Type.h - C Language Family Type Representation ---------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the Type interface and subclasses.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_TYPE_H
+#define LLVM_CLANG_AST_TYPE_H
+
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/Linkage.h"
+#include "clang/Basic/PartialDiagnostic.h"
+#include "clang/AST/NestedNameSpecifier.h"
+#include "clang/AST/TemplateName.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/type_traits.h"
+#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/PointerUnion.h"
+
+using llvm::isa;
+using llvm::cast;
+using llvm::cast_or_null;
+using llvm::dyn_cast;
+using llvm::dyn_cast_or_null;
+namespace clang {
+  enum {
+    TypeAlignmentInBits = 3,
+    TypeAlignment = 1 << TypeAlignmentInBits
+  };
+  class Type;
+  class ExtQuals;
+  class QualType;
+}
+
+namespace llvm {
+  template <typename T>
+  class PointerLikeTypeTraits;
+  template<>
+  class PointerLikeTypeTraits< ::clang::Type*> {
+  public:
+    static inline void *getAsVoidPointer(::clang::Type *P) { return P; }
+    static inline ::clang::Type *getFromVoidPointer(void *P) {
+      return static_cast< ::clang::Type*>(P);
+    }
+    enum { NumLowBitsAvailable = clang::TypeAlignmentInBits };
+  };
+  template<>
+  class PointerLikeTypeTraits< ::clang::ExtQuals*> {
+  public:
+    static inline void *getAsVoidPointer(::clang::ExtQuals *P) { return P; }
+    static inline ::clang::ExtQuals *getFromVoidPointer(void *P) {
+      return static_cast< ::clang::ExtQuals*>(P);
+    }
+    enum { NumLowBitsAvailable = clang::TypeAlignmentInBits };
+  };
+
+  template <>
+  struct isPodLike<clang::QualType> { static const bool value = true; };
+}
+
+namespace clang {
+  class ASTContext;
+  class TypedefDecl;
+  class TemplateDecl;
+  class TemplateTypeParmDecl;
+  class NonTypeTemplateParmDecl;
+  class TemplateTemplateParmDecl;
+  class TagDecl;
+  class RecordDecl;
+  class CXXRecordDecl;
+  class EnumDecl;
+  class FieldDecl;
+  class ObjCInterfaceDecl;
+  class ObjCProtocolDecl;
+  class ObjCMethodDecl;
+  class UnresolvedUsingTypenameDecl;
+  class Expr;
+  class Stmt;
+  class SourceLocation;
+  class StmtIteratorBase;
+  class TemplateArgument;
+  class TemplateArgumentLoc;
+  class TemplateArgumentListInfo;
+  class Type;
+  class QualifiedNameType;
+  struct PrintingPolicy;
+
+  template <typename> class CanQual;  
+  typedef CanQual<Type> CanQualType;
+
+  // Provide forward declarations for all of the *Type classes
+#define TYPE(Class, Base) class Class##Type;
+#include "clang/AST/TypeNodes.def"
+
+/// Qualifiers - The collection of all-type qualifiers we support.
+/// Clang supports five independent qualifiers:
+/// * C99: const, volatile, and restrict
+/// * Embedded C (TR18037): address spaces
+/// * Objective C: the GC attributes (none, weak, or strong)
+class Qualifiers {
+public:
+  enum TQ { // NOTE: These flags must be kept in sync with DeclSpec::TQ.
+    Const    = 0x1,
+    Restrict = 0x2,
+    Volatile = 0x4,
+    CVRMask = Const | Volatile | Restrict
+  };
+
+  enum GC {
+    GCNone = 0,
+    Weak,
+    Strong
+  };
+
+  enum {
+    /// The maximum supported address space number.
+    /// 24 bits should be enough for anyone.
+    MaxAddressSpace = 0xffffffu,
+
+    /// The width of the "fast" qualifier mask.
+    FastWidth = 2,
+
+    /// The fast qualifier mask.
+    FastMask = (1 << FastWidth) - 1
+  };
+
+  Qualifiers() : Mask(0) {}
+
+  static Qualifiers fromFastMask(unsigned Mask) {
+    Qualifiers Qs;
+    Qs.addFastQualifiers(Mask);
+    return Qs;
+  }
+
+  static Qualifiers fromCVRMask(unsigned CVR) {
+    Qualifiers Qs;
+    Qs.addCVRQualifiers(CVR);
+    return Qs;
+  }
+
+  // Deserialize qualifiers from an opaque representation.
+  static Qualifiers fromOpaqueValue(unsigned opaque) {
+    Qualifiers Qs;
+    Qs.Mask = opaque;
+    return Qs;
+  }
+
+  // Serialize these qualifiers into an opaque representation.
+  unsigned getAsOpaqueValue() const {
+    return Mask;
+  }
+
+  bool hasConst() const { return Mask & Const; }
+  void setConst(bool flag) {
+    Mask = (Mask & ~Const) | (flag ? Const : 0);
+  }
+  void removeConst() { Mask &= ~Const; }
+  void addConst() { Mask |= Const; }
+
+  bool hasVolatile() const { return Mask & Volatile; }
+  void setVolatile(bool flag) {
+    Mask = (Mask & ~Volatile) | (flag ? Volatile : 0);
+  }
+  void removeVolatile() { Mask &= ~Volatile; }
+  void addVolatile() { Mask |= Volatile; }
+
+  bool hasRestrict() const { return Mask & Restrict; }
+  void setRestrict(bool flag) {
+    Mask = (Mask & ~Restrict) | (flag ? Restrict : 0);
+  }
+  void removeRestrict() { Mask &= ~Restrict; }
+  void addRestrict() { Mask |= Restrict; }
+
+  bool hasCVRQualifiers() const { return getCVRQualifiers(); }
+  unsigned getCVRQualifiers() const { return Mask & CVRMask; }
+  void setCVRQualifiers(unsigned mask) {
+    assert(!(mask & ~CVRMask) && "bitmask contains non-CVR bits");
+    Mask = (Mask & ~CVRMask) | mask;
+  }
+  void removeCVRQualifiers(unsigned mask) {
+    assert(!(mask & ~CVRMask) && "bitmask contains non-CVR bits");
+    Mask &= ~mask;
+  }
+  void removeCVRQualifiers() {
+    removeCVRQualifiers(CVRMask);
+  }
+  void addCVRQualifiers(unsigned mask) {
+    assert(!(mask & ~CVRMask) && "bitmask contains non-CVR bits");
+    Mask |= mask;
+  }
+
+  bool hasObjCGCAttr() const { return Mask & GCAttrMask; }
+  GC getObjCGCAttr() const { return GC((Mask & GCAttrMask) >> GCAttrShift); }
+  void setObjCGCAttr(GC type) {
+    Mask = (Mask & ~GCAttrMask) | (type << GCAttrShift);
+  }
+  void removeObjCGCAttr() { setObjCGCAttr(GCNone); }
+  void addObjCGCAttr(GC type) {
+    assert(type);
+    setObjCGCAttr(type);
+  }
+
+  bool hasAddressSpace() const { return Mask & AddressSpaceMask; }
+  unsigned getAddressSpace() const { return Mask >> AddressSpaceShift; }
+  void setAddressSpace(unsigned space) {
+    assert(space <= MaxAddressSpace);
+    Mask = (Mask & ~AddressSpaceMask)
+         | (((uint32_t) space) << AddressSpaceShift);
+  }
+  void removeAddressSpace() { setAddressSpace(0); }
+  void addAddressSpace(unsigned space) {
+    assert(space);
+    setAddressSpace(space);
+  }
+
+  // Fast qualifiers are those that can be allocated directly
+  // on a QualType object.
+  bool hasFastQualifiers() const { return getFastQualifiers(); }
+  unsigned getFastQualifiers() const { return Mask & FastMask; }
+  void setFastQualifiers(unsigned mask) {
+    assert(!(mask & ~FastMask) && "bitmask contains non-fast qualifier bits");
+    Mask = (Mask & ~FastMask) | mask;
+  }
+  void removeFastQualifiers(unsigned mask) {
+    assert(!(mask & ~FastMask) && "bitmask contains non-fast qualifier bits");
+    Mask &= ~mask;
+  }
+  void removeFastQualifiers() {
+    removeFastQualifiers(FastMask);
+  }
+  void addFastQualifiers(unsigned mask) {
+    assert(!(mask & ~FastMask) && "bitmask contains non-fast qualifier bits");
+    Mask |= mask;
+  }
+
+  /// hasNonFastQualifiers - Return true if the set contains any
+  /// qualifiers which require an ExtQuals node to be allocated.
+  bool hasNonFastQualifiers() const { return Mask & ~FastMask; }
+  Qualifiers getNonFastQualifiers() const {
+    Qualifiers Quals = *this;
+    Quals.setFastQualifiers(0);
+    return Quals;
+  }
+
+  /// hasQualifiers - Return true if the set contains any qualifiers.
+  bool hasQualifiers() const { return Mask; }
+  bool empty() const { return !Mask; }
+
+  /// \brief Add the qualifiers from the given set to this set.
+  void addQualifiers(Qualifiers Q) {
+    // If the other set doesn't have any non-boolean qualifiers, just
+    // bit-or it in.
+    if (!(Q.Mask & ~CVRMask))
+      Mask |= Q.Mask;
+    else {
+      Mask |= (Q.Mask & CVRMask);
+      if (Q.hasAddressSpace())
+        addAddressSpace(Q.getAddressSpace());
+      if (Q.hasObjCGCAttr())
+        addObjCGCAttr(Q.getObjCGCAttr());
+    }
+  }
+
+  bool operator==(Qualifiers Other) const { return Mask == Other.Mask; }
+  bool operator!=(Qualifiers Other) const { return Mask != Other.Mask; }
+
+  operator bool() const { return hasQualifiers(); }
+
+  Qualifiers &operator+=(Qualifiers R) {
+    addQualifiers(R);
+    return *this;
+  }
+
+  // Union two qualifier sets.  If an enumerated qualifier appears
+  // in both sets, use the one from the right.
+  friend Qualifiers operator+(Qualifiers L, Qualifiers R) {
+    L += R;
+    return L;
+  }
+
+  std::string getAsString() const;
+  std::string getAsString(const PrintingPolicy &Policy) const {
+    std::string Buffer;
+    getAsStringInternal(Buffer, Policy);
+    return Buffer;
+  }
+  void getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const;
+
+  void Profile(llvm::FoldingSetNodeID &ID) const {
+    ID.AddInteger(Mask);
+  }
+
+private:
+
+  // bits:     |0 1 2|3 .. 4|5  ..  31|
+  //           |C R V|GCAttr|AddrSpace|
+  uint32_t Mask;
+
+  static const uint32_t GCAttrMask = 0x18;
+  static const uint32_t GCAttrShift = 3;
+  static const uint32_t AddressSpaceMask = ~(CVRMask | GCAttrMask);
+  static const uint32_t AddressSpaceShift = 5;
+};
+
+
+/// ExtQuals - We can encode up to three bits in the low bits of a
+/// type pointer, but there are many more type qualifiers that we want
+/// to be able to apply to an arbitrary type.  Therefore we have this
+/// struct, intended to be heap-allocated and used by QualType to
+/// store qualifiers.
+///
+/// The current design tags the 'const' and 'restrict' qualifiers in
+/// two low bits on the QualType pointer; a third bit records whether
+/// the pointer is an ExtQuals node.  'const' was chosen because it is
+/// orders of magnitude more common than the other two qualifiers, in
+/// both library and user code.  It's relatively rare to see
+/// 'restrict' in user code, but many standard C headers are saturated
+/// with 'restrict' declarations, so that representing them efficiently
+/// is a critical goal of this representation.
+class ExtQuals : public llvm::FoldingSetNode {
+  // NOTE: changing the fast qualifiers should be straightforward as
+  // long as you don't make 'const' non-fast.
+  // 1. Qualifiers:
+  //    a) Modify the bitmasks (Qualifiers::TQ and DeclSpec::TQ).
+  //       Fast qualifiers must occupy the low-order bits.
+  //    b) Update Qualifiers::FastWidth and FastMask.
+  // 2. QualType:
+  //    a) Update is{Volatile,Restrict}Qualified(), defined inline.
+  //    b) Update remove{Volatile,Restrict}, defined near the end of
+  //       this header.
+  // 3. ASTContext:
+  //    a) Update get{Volatile,Restrict}Type.
+
+  /// Context - the context to which this set belongs.  We save this
+  /// here so that QualifierCollector can use it to reapply extended
+  /// qualifiers to an arbitrary type without requiring a context to
+  /// be pushed through every single API dealing with qualifiers.
+  ASTContext& Context;
+
+  /// BaseType - the underlying type that this qualifies
+  const Type *BaseType;
+
+  /// Quals - the immutable set of qualifiers applied by this
+  /// node;  always contains extended qualifiers.
+  Qualifiers Quals;
+
+public:
+  ExtQuals(ASTContext& Context, const Type *Base, Qualifiers Quals)
+    : Context(Context), BaseType(Base), Quals(Quals)
+  {
+    assert(Quals.hasNonFastQualifiers()
+           && "ExtQuals created with no fast qualifiers");
+    assert(!Quals.hasFastQualifiers()
+           && "ExtQuals created with fast qualifiers");
+  }
+
+  Qualifiers getQualifiers() const { return Quals; }
+
+  bool hasVolatile() const { return Quals.hasVolatile(); }
+
+  bool hasObjCGCAttr() const { return Quals.hasObjCGCAttr(); }
+  Qualifiers::GC getObjCGCAttr() const { return Quals.getObjCGCAttr(); }
+
+  bool hasAddressSpace() const { return Quals.hasAddressSpace(); }
+  unsigned getAddressSpace() const { return Quals.getAddressSpace(); }
+
+  const Type *getBaseType() const { return BaseType; }
+
+  ASTContext &getContext() const { return Context; }
+
+public:
+  void Profile(llvm::FoldingSetNodeID &ID) const {
+    Profile(ID, getBaseType(), Quals);
+  }
+  static void Profile(llvm::FoldingSetNodeID &ID,
+                      const Type *BaseType,
+                      Qualifiers Quals) {
+    assert(!Quals.hasFastQualifiers() && "fast qualifiers in ExtQuals hash!");
+    ID.AddPointer(BaseType);
+    Quals.Profile(ID);
+  }
+};
+
+/// CallingConv - Specifies the calling convention that a function uses.
+enum CallingConv {
+  CC_Default,
+  CC_C,           // __attribute__((cdecl))
+  CC_X86StdCall,  // __attribute__((stdcall))
+  CC_X86FastCall  // __attribute__((fastcall))
+};
+
+
+/// QualType - For efficiency, we don't store CV-qualified types as nodes on
+/// their own: instead each reference to a type stores the qualifiers.  This
+/// greatly reduces the number of nodes we need to allocate for types (for
+/// example we only need one for 'int', 'const int', 'volatile int',
+/// 'const volatile int', etc).
+///
+/// As an added efficiency bonus, instead of making this a pair, we
+/// just store the two bits we care about in the low bits of the
+/// pointer.  To handle the packing/unpacking, we make QualType be a
+/// simple wrapper class that acts like a smart pointer.  A third bit
+/// indicates whether there are extended qualifiers present, in which
+/// case the pointer points to a special structure.
+class QualType {
+  // Thankfully, these are efficiently composable.
+  llvm::PointerIntPair<llvm::PointerUnion<const Type*,const ExtQuals*>,
+                       Qualifiers::FastWidth> Value;
+
+  const ExtQuals *getExtQualsUnsafe() const {
+    return Value.getPointer().get<const ExtQuals*>();
+  }
+
+  const Type *getTypePtrUnsafe() const {
+    return Value.getPointer().get<const Type*>();
+  }
+
+  QualType getUnqualifiedTypeSlow() const;
+  
+  friend class QualifierCollector;
+public:
+  QualType() {}
+
+  QualType(const Type *Ptr, unsigned Quals)
+    : Value(Ptr, Quals) {}
+  QualType(const ExtQuals *Ptr, unsigned Quals)
+    : Value(Ptr, Quals) {}
+
+  unsigned getLocalFastQualifiers() const { return Value.getInt(); }
+  void setLocalFastQualifiers(unsigned Quals) { Value.setInt(Quals); }
+
+  /// Retrieves a pointer to the underlying (unqualified) type.
+  /// This should really return a const Type, but it's not worth
+  /// changing all the users right now.
+  Type *getTypePtr() const {
+    if (hasLocalNonFastQualifiers())
+      return const_cast<Type*>(getExtQualsUnsafe()->getBaseType());
+    return const_cast<Type*>(getTypePtrUnsafe());
+  }
+
+  void *getAsOpaquePtr() const { return Value.getOpaqueValue(); }
+  static QualType getFromOpaquePtr(void *Ptr) {
+    QualType T;
+    T.Value.setFromOpaqueValue(Ptr);
+    return T;
+  }
+
+  Type &operator*() const {
+    return *getTypePtr();
+  }
+
+  Type *operator->() const {
+    return getTypePtr();
+  }
+
+  bool isCanonical() const;
+  bool isCanonicalAsParam() const;
+
+  /// isNull - Return true if this QualType doesn't point to a type yet.
+  bool isNull() const {
+    return Value.getPointer().isNull();
+  }
+
+  /// \brief Determine whether this particular QualType instance has the 
+  /// "const" qualifier set, without looking through typedefs that may have
+  /// added "const" at a different level.
+  bool isLocalConstQualified() const {
+    return (getLocalFastQualifiers() & Qualifiers::Const);
+  }
+  
+  /// \brief Determine whether this type is const-qualified.
+  bool isConstQualified() const;
+  
+  /// \brief Determine whether this particular QualType instance has the 
+  /// "restrict" qualifier set, without looking through typedefs that may have
+  /// added "restrict" at a different level.
+  bool isLocalRestrictQualified() const {
+    return (getLocalFastQualifiers() & Qualifiers::Restrict);
+  }
+  
+  /// \brief Determine whether this type is restrict-qualified.
+  bool isRestrictQualified() const;
+  
+  /// \brief Determine whether this particular QualType instance has the 
+  /// "volatile" qualifier set, without looking through typedefs that may have
+  /// added "volatile" at a different level.
+  bool isLocalVolatileQualified() const {
+    return (hasLocalNonFastQualifiers() && getExtQualsUnsafe()->hasVolatile());
+  }
+
+  /// \brief Determine whether this type is volatile-qualified.
+  bool isVolatileQualified() const;
+  
+  /// \brief Determine whether this particular QualType instance has any
+  /// qualifiers, without looking through any typedefs that might add 
+  /// qualifiers at a different level.
+  bool hasLocalQualifiers() const {
+    return getLocalFastQualifiers() || hasLocalNonFastQualifiers();
+  }
+
+  /// \brief Determine whether this type has any qualifiers.
+  bool hasQualifiers() const;
+  
+  /// \brief Determine whether this particular QualType instance has any
+  /// "non-fast" qualifiers, e.g., those that are stored in an ExtQualType
+  /// instance.
+  bool hasLocalNonFastQualifiers() const {
+    return Value.getPointer().is<const ExtQuals*>();
+  }
+
+  /// \brief Retrieve the set of qualifiers local to this particular QualType
+  /// instance, not including any qualifiers acquired through typedefs or
+  /// other sugar.
+  Qualifiers getLocalQualifiers() const {
+    Qualifiers Quals;
+    if (hasLocalNonFastQualifiers())
+      Quals = getExtQualsUnsafe()->getQualifiers();
+    Quals.addFastQualifiers(getLocalFastQualifiers());
+    return Quals;
+  }
+
+  /// \brief Retrieve the set of qualifiers applied to this type.
+  Qualifiers getQualifiers() const;
+  
+  /// \brief Retrieve the set of CVR (const-volatile-restrict) qualifiers 
+  /// local to this particular QualType instance, not including any qualifiers
+  /// acquired through typedefs or other sugar.
+  unsigned getLocalCVRQualifiers() const {
+    unsigned CVR = getLocalFastQualifiers();
+    if (isLocalVolatileQualified())
+      CVR |= Qualifiers::Volatile;
+    return CVR;
+  }
+
+  /// \brief Retrieve the set of CVR (const-volatile-restrict) qualifiers 
+  /// applied to this type.
+  unsigned getCVRQualifiers() const;
+
+  /// \brief Retrieve the set of CVR (const-volatile-restrict) qualifiers
+  /// applied to this type, looking through any number of unqualified array
+  /// types to their element types' qualifiers.
+  unsigned getCVRQualifiersThroughArrayTypes() const;
+
+  bool isConstant(ASTContext& Ctx) const {
+    return QualType::isConstant(*this, Ctx);
+  }
+
+  // Don't promise in the API that anything besides 'const' can be
+  // easily added.
+
+  /// addConst - add the specified type qualifier to this QualType.  
+  void addConst() {
+    addFastQualifiers(Qualifiers::Const);
+  }
+  QualType withConst() const {
+    return withFastQualifiers(Qualifiers::Const);
+  }
+
+  void addFastQualifiers(unsigned TQs) {
+    assert(!(TQs & ~Qualifiers::FastMask)
+           && "non-fast qualifier bits set in mask!");
+    Value.setInt(Value.getInt() | TQs);
+  }
+
+  // FIXME: The remove* functions are semantically broken, because they might
+  // not remove a qualifier stored on a typedef. Most of the with* functions
+  // have the same problem.
+  void removeConst();
+  void removeVolatile();
+  void removeRestrict();
+  void removeCVRQualifiers(unsigned Mask);
+
+  void removeFastQualifiers() { Value.setInt(0); }
+  void removeFastQualifiers(unsigned Mask) {
+    assert(!(Mask & ~Qualifiers::FastMask) && "mask has non-fast qualifiers");
+    Value.setInt(Value.getInt() & ~Mask);
+  }
+
+  // Creates a type with the given qualifiers in addition to any
+  // qualifiers already on this type.
+  QualType withFastQualifiers(unsigned TQs) const {
+    QualType T = *this;
+    T.addFastQualifiers(TQs);
+    return T;
+  }
+
+  // Creates a type with exactly the given fast qualifiers, removing
+  // any existing fast qualifiers.
+  QualType withExactFastQualifiers(unsigned TQs) const {
+    return withoutFastQualifiers().withFastQualifiers(TQs);
+  }
+
+  // Removes fast qualifiers, but leaves any extended qualifiers in place.
+  QualType withoutFastQualifiers() const {
+    QualType T = *this;
+    T.removeFastQualifiers();
+    return T;
+  }
+
+  /// \brief Return this type with all of the instance-specific qualifiers
+  /// removed, but without removing any qualifiers that may have been applied
+  /// through typedefs.
+  QualType getLocalUnqualifiedType() const { return QualType(getTypePtr(), 0); }
+
+  /// \brief Return the unqualified form of the given type, which might be
+  /// desugared to eliminate qualifiers introduced via typedefs.
+  QualType getUnqualifiedType() const {
+    QualType T = getLocalUnqualifiedType();
+    if (!T.hasQualifiers())
+      return T;
+    
+    return getUnqualifiedTypeSlow();
+  }
+  
+  bool isMoreQualifiedThan(QualType Other) const;
+  bool isAtLeastAsQualifiedAs(QualType Other) const;
+  QualType getNonReferenceType() const;
+
+  /// getDesugaredType - Return the specified type with any "sugar" removed from
+  /// the type.  This takes off typedefs, typeof's etc.  If the outer level of
+  /// the type is already concrete, it returns it unmodified.  This is similar
+  /// to getting the canonical type, but it doesn't remove *all* typedefs.  For
+  /// example, it returns "T*" as "T*", (not as "int*"), because the pointer is
+  /// concrete.
+  ///
+  /// Qualifiers are left in place.
+  QualType getDesugaredType() const {
+    return QualType::getDesugaredType(*this);
+  }
+
+  /// operator==/!= - Indicate whether the specified types and qualifiers are
+  /// identical.
+  friend bool operator==(const QualType &LHS, const QualType &RHS) {
+    return LHS.Value == RHS.Value;
+  }
+  friend bool operator!=(const QualType &LHS, const QualType &RHS) {
+    return LHS.Value != RHS.Value;
+  }
+  std::string getAsString() const;
+
+  std::string getAsString(const PrintingPolicy &Policy) const {
+    std::string S;
+    getAsStringInternal(S, Policy);
+    return S;
+  }
+  void getAsStringInternal(std::string &Str,
+                           const PrintingPolicy &Policy) const;
+
+  void dump(const char *s) const;
+  void dump() const;
+
+  void Profile(llvm::FoldingSetNodeID &ID) const {
+    ID.AddPointer(getAsOpaquePtr());
+  }
+
+  /// getAddressSpace - Return the address space of this type.
+  inline unsigned getAddressSpace() const;
+
+  /// GCAttrTypesAttr - Returns gc attribute of this type.
+  inline Qualifiers::GC getObjCGCAttr() const;
+
+  /// isObjCGCWeak true when Type is objc's weak.
+  bool isObjCGCWeak() const {
+    return getObjCGCAttr() == Qualifiers::Weak;
+  }
+
+  /// isObjCGCStrong true when Type is objc's strong.
+  bool isObjCGCStrong() const {
+    return getObjCGCAttr() == Qualifiers::Strong;
+  }
+
+private:
+  // These methods are implemented in a separate translation unit;
+  // "static"-ize them to avoid creating temporary QualTypes in the
+  // caller.
+  static bool isConstant(QualType T, ASTContext& Ctx);
+  static QualType getDesugaredType(QualType T);
+};
+
+} // end clang.
+
+namespace llvm {
+/// Implement simplify_type for QualType, so that we can dyn_cast from QualType
+/// to a specific Type class.
+template<> struct simplify_type<const ::clang::QualType> {
+  typedef ::clang::Type* SimpleType;
+  static SimpleType getSimplifiedValue(const ::clang::QualType &Val) {
+    return Val.getTypePtr();
+  }
+};
+template<> struct simplify_type< ::clang::QualType>
+  : public simplify_type<const ::clang::QualType> {};
+
+// Teach SmallPtrSet that QualType is "basically a pointer".
+template<>
+class PointerLikeTypeTraits<clang::QualType> {
+public:
+  static inline void *getAsVoidPointer(clang::QualType P) {
+    return P.getAsOpaquePtr();
+  }
+  static inline clang::QualType getFromVoidPointer(void *P) {
+    return clang::QualType::getFromOpaquePtr(P);
+  }
+  // Various qualifiers go in low bits.
+  enum { NumLowBitsAvailable = 0 };
+};
+
+} // end namespace llvm
+
+namespace clang {
+
+/// Type - This is the base class of the type hierarchy.  A central concept
+/// with types is that each type always has a canonical type.  A canonical type
+/// is the type with any typedef names stripped out of it or the types it
+/// references.  For example, consider:
+///
+///  typedef int  foo;
+///  typedef foo* bar;
+///    'int *'    'foo *'    'bar'
+///
+/// There will be a Type object created for 'int'.  Since int is canonical, its
+/// canonicaltype pointer points to itself.  There is also a Type for 'foo' (a
+/// TypedefType).  Its CanonicalType pointer points to the 'int' Type.  Next
+/// there is a PointerType that represents 'int*', which, like 'int', is
+/// canonical.  Finally, there is a PointerType type for 'foo*' whose canonical
+/// type is 'int*', and there is a TypedefType for 'bar', whose canonical type
+/// is also 'int*'.
+///
+/// Non-canonical types are useful for emitting diagnostics, without losing
+/// information about typedefs being used.  Canonical types are useful for type
+/// comparisons (they allow by-pointer equality tests) and useful for reasoning
+/// about whether something has a particular form (e.g. is a function type),
+/// because they implicitly, recursively, strip all typedefs out of a type.
+///
+/// Types, once created, are immutable.
+///
+class Type {
+public:
+  enum TypeClass {
+#define TYPE(Class, Base) Class,
+#define LAST_TYPE(Class) TypeLast = Class,
+#define ABSTRACT_TYPE(Class, Base)
+#include "clang/AST/TypeNodes.def"
+    TagFirst = Record, TagLast = Enum
+  };
+
+private:
+  QualType CanonicalType;
+
+  /// TypeClass bitfield - Enum that specifies what subclass this belongs to.
+  unsigned TC : 8;
+
+  /// Dependent - Whether this type is a dependent type (C++ [temp.dep.type]).
+  /// Note that this should stay at the end of the ivars for Type so that
+  /// subclasses can pack their bitfields into the same word.
+  bool Dependent : 1;
+
+  Type(const Type&);           // DO NOT IMPLEMENT.
+  void operator=(const Type&); // DO NOT IMPLEMENT.
+protected:
+  // silence VC++ warning C4355: 'this' : used in base member initializer list
+  Type *this_() { return this; }
+  Type(TypeClass tc, QualType Canonical, bool dependent)
+    : CanonicalType(Canonical.isNull() ? QualType(this_(), 0) : Canonical),
+      TC(tc), Dependent(dependent) {}
+  virtual ~Type() {}
+  virtual void Destroy(ASTContext& C);
+  friend class ASTContext;
+
+public:
+  TypeClass getTypeClass() const { return static_cast<TypeClass>(TC); }
+
+  bool isCanonicalUnqualified() const {
+    return CanonicalType.getTypePtr() == this;
+  }
+
+  /// Types are partitioned into 3 broad categories (C99 6.2.5p1):
+  /// object types, function types, and incomplete types.
+
+  /// \brief Determines whether the type describes an object in memory.
+  ///
+  /// Note that this definition of object type corresponds to the C++
+  /// definition of object type, which includes incomplete types, as
+  /// opposed to the C definition (which does not include incomplete
+  /// types).
+  bool isObjectType() const;
+
+  /// isIncompleteType - Return true if this is an incomplete type.
+  /// A type that can describe objects, but which lacks information needed to
+  /// determine its size (e.g. void, or a fwd declared struct). Clients of this
+  /// routine will need to determine if the size is actually required.
+  bool isIncompleteType() const;
+
+  /// isIncompleteOrObjectType - Return true if this is an incomplete or object
+  /// type, in other words, not a function type.
+  bool isIncompleteOrObjectType() const {
+    return !isFunctionType();
+  }
+
+  /// isPODType - Return true if this is a plain-old-data type (C++ 3.9p10).
+  bool isPODType() const;
+
+  /// isLiteralType - Return true if this is a literal type
+  /// (C++0x [basic.types]p10)
+  bool isLiteralType() const;
+
+  /// isVariablyModifiedType (C99 6.7.5.2p2) - Return true for variable array
+  /// types that have a non-constant expression. This does not include "[]".
+  bool isVariablyModifiedType() const;
+
+  /// Helper methods to distinguish type categories. All type predicates
+  /// operate on the canonical type, ignoring typedefs and qualifiers.
+
+  /// isSpecificBuiltinType - Test for a particular builtin type.
+  bool isSpecificBuiltinType(unsigned K) const;
+
+  /// isIntegerType() does *not* include complex integers (a GCC extension).
+  /// isComplexIntegerType() can be used to test for complex integers.
+  bool isIntegerType() const;     // C99 6.2.5p17 (int, char, bool, enum)
+  bool isEnumeralType() const;
+  bool isBooleanType() const;
+  bool isCharType() const;
+  bool isWideCharType() const;
+  bool isAnyCharacterType() const;
+  bool isIntegralType() const;
+  
+  /// Floating point categories.
+  bool isRealFloatingType() const; // C99 6.2.5p10 (float, double, long double)
+  /// isComplexType() does *not* include complex integers (a GCC extension).
+  /// isComplexIntegerType() can be used to test for complex integers.
+  bool isComplexType() const;      // C99 6.2.5p11 (complex)
+  bool isAnyComplexType() const;   // C99 6.2.5p11 (complex) + Complex Int.
+  bool isFloatingType() const;     // C99 6.2.5p11 (real floating + complex)
+  bool isRealType() const;         // C99 6.2.5p17 (real floating + integer)
+  bool isArithmeticType() const;   // C99 6.2.5p18 (integer + floating)
+  bool isVoidType() const;         // C99 6.2.5p19
+  bool isDerivedType() const;      // C99 6.2.5p20
+  bool isScalarType() const;       // C99 6.2.5p21 (arithmetic + pointers)
+  bool isAggregateType() const;
+
+  // Type Predicates: Check to see if this type is structurally the specified
+  // type, ignoring typedefs and qualifiers.
+  bool isFunctionType() const;
+  bool isFunctionNoProtoType() const { return getAs<FunctionNoProtoType>(); }
+  bool isFunctionProtoType() const { return getAs<FunctionProtoType>(); }
+  bool isPointerType() const;
+  bool isAnyPointerType() const;   // Any C pointer or ObjC object pointer
+  bool isBlockPointerType() const;
+  bool isVoidPointerType() const;
+  bool isReferenceType() const;
+  bool isLValueReferenceType() const;
+  bool isRValueReferenceType() const;
+  bool isFunctionPointerType() const;
+  bool isMemberPointerType() const;
+  bool isMemberFunctionPointerType() const;
+  bool isArrayType() const;
+  bool isConstantArrayType() const;
+  bool isIncompleteArrayType() const;
+  bool isVariableArrayType() const;
+  bool isDependentSizedArrayType() const;
+  bool isRecordType() const;
+  bool isClassType() const;
+  bool isStructureType() const;
+  bool isStructureOrClassType() const;
+  bool isUnionType() const;
+  bool isComplexIntegerType() const;            // GCC _Complex integer type.
+  bool isVectorType() const;                    // GCC vector type.
+  bool isExtVectorType() const;                 // Extended vector type.
+  bool isObjCObjectPointerType() const;         // Pointer to *any* ObjC object.
+  // FIXME: change this to 'raw' interface type, so we can used 'interface' type
+  // for the common case.
+  bool isObjCInterfaceType() const;             // NSString or NSString<foo>
+  bool isObjCQualifiedInterfaceType() const;    // NSString<foo>
+  bool isObjCQualifiedIdType() const;           // id<foo>
+  bool isObjCQualifiedClassType() const;        // Class<foo>
+  bool isObjCIdType() const;                    // id
+  bool isObjCClassType() const;                 // Class
+  bool isObjCSelType() const;                 // Class
+  bool isObjCBuiltinType() const;               // 'id' or 'Class'
+  bool isTemplateTypeParmType() const;          // C++ template type parameter
+  bool isNullPtrType() const;                   // C++0x nullptr_t
+
+  /// isDependentType - Whether this type is a dependent type, meaning
+  /// that its definition somehow depends on a template parameter
+  /// (C++ [temp.dep.type]).
+  bool isDependentType() const { return Dependent; }
+  bool isOverloadableType() const;
+
+  /// \brief Determine wither this type is a C++ elaborated-type-specifier.
+  bool isElaboratedTypeSpecifier() const;
+  
+  /// hasPointerRepresentation - Whether this type is represented
+  /// natively as a pointer; this includes pointers, references, block
+  /// pointers, and Objective-C interface, qualified id, and qualified
+  /// interface types, as well as nullptr_t.
+  bool hasPointerRepresentation() const;
+
+  /// hasObjCPointerRepresentation - Whether this type can represent
+  /// an objective pointer type for the purpose of GC'ability
+  bool hasObjCPointerRepresentation() const;
+
+  // Type Checking Functions: Check to see if this type is structurally the
+  // specified type, ignoring typedefs and qualifiers, and return a pointer to
+  // the best type we can.
+  const RecordType *getAsStructureType() const;
+  /// NOTE: getAs*ArrayType are methods on ASTContext.
+  const RecordType *getAsUnionType() const;
+  const ComplexType *getAsComplexIntegerType() const; // GCC complex int type.
+  // The following is a convenience method that returns an ObjCObjectPointerType
+  // for object declared using an interface.
+  const ObjCObjectPointerType *getAsObjCInterfacePointerType() const;
+  const ObjCObjectPointerType *getAsObjCQualifiedIdType() const;
+  const ObjCInterfaceType *getAsObjCQualifiedInterfaceType() const;
+  const CXXRecordDecl *getCXXRecordDeclForPointerType() const;
+
+  // Member-template getAs<specific type>'.  This scheme will eventually
+  // replace the specific getAsXXXX methods above.
+  //
+  // There are some specializations of this member template listed
+  // immediately following this class.
+  template <typename T> const T *getAs() const;
+
+  /// getAsPointerToObjCInterfaceType - If this is a pointer to an ObjC
+  /// interface, return the interface type, otherwise return null.
+  const ObjCInterfaceType *getAsPointerToObjCInterfaceType() const;
+
+  /// getArrayElementTypeNoTypeQual - If this is an array type, return the
+  /// element type of the array, potentially with type qualifiers missing.
+  /// This method should never be used when type qualifiers are meaningful.
+  const Type *getArrayElementTypeNoTypeQual() const;
+
+  /// getPointeeType - If this is a pointer, ObjC object pointer, or block
+  /// pointer, this returns the respective pointee.
+  QualType getPointeeType() const;
+
+  /// getUnqualifiedDesugaredType() - Return the specified type with
+  /// any "sugar" removed from the type, removing any typedefs,
+  /// typeofs, etc., as well as any qualifiers.
+  const Type *getUnqualifiedDesugaredType() const;
+
+  /// More type predicates useful for type checking/promotion
+  bool isPromotableIntegerType() const; // C99 6.3.1.1p2
+
+  /// isSignedIntegerType - Return true if this is an integer type that is
+  /// signed, according to C99 6.2.5p4 [char, signed char, short, int, long..],
+  /// an enum decl which has a signed representation, or a vector of signed
+  /// integer element type.
+  bool isSignedIntegerType() const;
+
+  /// isUnsignedIntegerType - Return true if this is an integer type that is
+  /// unsigned, according to C99 6.2.5p6 [which returns true for _Bool], an enum
+  /// decl which has an unsigned representation, or a vector of unsigned integer
+  /// element type.
+  bool isUnsignedIntegerType() const;
+
+  /// isConstantSizeType - Return true if this is not a variable sized type,
+  /// according to the rules of C99 6.7.5p3.  It is not legal to call this on
+  /// incomplete types.
+  bool isConstantSizeType() const;
+
+  /// isSpecifierType - Returns true if this type can be represented by some
+  /// set of type specifiers.
+  bool isSpecifierType() const;
+
+  const char *getTypeClassName() const;
+
+  /// \brief Determine the linkage of this type.
+  virtual Linkage getLinkage() const;
+
+  QualType getCanonicalTypeInternal() const {
+    return CanonicalType;
+  }
+  CanQualType getCanonicalTypeUnqualified() const; // in CanonicalType.h
+  void dump() const;
+  static bool classof(const Type *) { return true; }
+};
+
+template <> inline const TypedefType *Type::getAs() const {
+  return dyn_cast<TypedefType>(this);
+}
+
+// We can do canonical leaf types faster, because we don't have to
+// worry about preserving child type decoration.
+#define TYPE(Class, Base)
+#define LEAF_TYPE(Class) \
+template <> inline const Class##Type *Type::getAs() const { \
+  return dyn_cast<Class##Type>(CanonicalType); \
+}
+#include "clang/AST/TypeNodes.def"
+
+
+/// BuiltinType - This class is used for builtin types like 'int'.  Builtin
+/// types are always canonical and have a literal name field.
+class BuiltinType : public Type {
+public:
+  enum Kind {
+    Void,
+
+    Bool,     // This is bool and/or _Bool.
+    Char_U,   // This is 'char' for targets where char is unsigned.
+    UChar,    // This is explicitly qualified unsigned char.
+    Char16,   // This is 'char16_t' for C++.
+    Char32,   // This is 'char32_t' for C++.
+    UShort,
+    UInt,
+    ULong,
+    ULongLong,
+    UInt128,  // __uint128_t
+
+    Char_S,   // This is 'char' for targets where char is signed.
+    SChar,    // This is explicitly qualified signed char.
+    WChar,    // This is 'wchar_t' for C++.
+    Short,
+    Int,
+    Long,
+    LongLong,
+    Int128,   // __int128_t
+
+    Float, Double, LongDouble,
+
+    NullPtr,  // This is the type of C++0x 'nullptr'.
+
+    Overload,  // This represents the type of an overloaded function declaration.
+    Dependent, // This represents the type of a type-dependent expression.
+
+    UndeducedAuto, // In C++0x, this represents the type of an auto variable
+                   // that has not been deduced yet.
+    ObjCId,    // This represents the ObjC 'id' type.
+    ObjCClass, // This represents the ObjC 'Class' type.
+    ObjCSel    // This represents the ObjC 'SEL' type.
+  };
+private:
+  Kind TypeKind;
+public:
+  BuiltinType(Kind K)
+    : Type(Builtin, QualType(), /*Dependent=*/(K == Dependent)),
+      TypeKind(K) {}
+
+  Kind getKind() const { return TypeKind; }
+  const char *getName(const LangOptions &LO) const;
+
+  bool isSugared() const { return false; }
+  QualType desugar() const { return QualType(this, 0); }
+
+  bool isInteger() const {
+    return TypeKind >= Bool && TypeKind <= Int128;
+  }
+
+  bool isSignedInteger() const {
+    return TypeKind >= Char_S && TypeKind <= Int128;
+  }
+
+  bool isUnsignedInteger() const {
+    return TypeKind >= Bool && TypeKind <= UInt128;
+  }
+
+  bool isFloatingPoint() const {
+    return TypeKind >= Float && TypeKind <= LongDouble;
+  }
+
+  virtual Linkage getLinkage() const;
+
+  static bool classof(const Type *T) { return T->getTypeClass() == Builtin; }
+  static bool classof(const BuiltinType *) { return true; }
+};
+
+/// ComplexType - C99 6.2.5p11 - Complex values.  This supports the C99 complex
+/// types (_Complex float etc) as well as the GCC integer complex extensions.
+///
+class ComplexType : public Type, public llvm::FoldingSetNode {
+  QualType ElementType;
+  ComplexType(QualType Element, QualType CanonicalPtr) :
+    Type(Complex, CanonicalPtr, Element->isDependentType()),
+    ElementType(Element) {
+  }
+  friend class ASTContext;  // ASTContext creates these.
+public:
+  QualType getElementType() const { return ElementType; }
+
+  bool isSugared() const { return false; }
+  QualType desugar() const { return QualType(this, 0); }
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    Profile(ID, getElementType());
+  }
+  static void Profile(llvm::FoldingSetNodeID &ID, QualType Element) {
+    ID.AddPointer(Element.getAsOpaquePtr());
+  }
+
+  virtual Linkage getLinkage() const;
+
+  static bool classof(const Type *T) { return T->getTypeClass() == Complex; }
+  static bool classof(const ComplexType *) { return true; }
+};
+
+/// PointerType - C99 6.7.5.1 - Pointer Declarators.
+///
+class PointerType : public Type, public llvm::FoldingSetNode {
+  QualType PointeeType;
+
+  PointerType(QualType Pointee, QualType CanonicalPtr) :
+    Type(Pointer, CanonicalPtr, Pointee->isDependentType()), PointeeType(Pointee) {
+  }
+  friend class ASTContext;  // ASTContext creates these.
+public:
+
+  QualType getPointeeType() const { return PointeeType; }
+
+  bool isSugared() const { return false; }
+  QualType desugar() const { return QualType(this, 0); }
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    Profile(ID, getPointeeType());
+  }
+  static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee) {
+    ID.AddPointer(Pointee.getAsOpaquePtr());
+  }
+
+  virtual Linkage getLinkage() const;
+
+  static bool classof(const Type *T) { return T->getTypeClass() == Pointer; }
+  static bool classof(const PointerType *) { return true; }
+};
+
+/// BlockPointerType - pointer to a block type.
+/// This type is to represent types syntactically represented as
+/// "void (^)(int)", etc. Pointee is required to always be a function type.
+///
+class BlockPointerType : public Type, public llvm::FoldingSetNode {
+  QualType PointeeType;  // Block is some kind of pointer type
+  BlockPointerType(QualType Pointee, QualType CanonicalCls) :
+    Type(BlockPointer, CanonicalCls, Pointee->isDependentType()),
+    PointeeType(Pointee) {
+  }
+  friend class ASTContext;  // ASTContext creates these.
+public:
+
+  // Get the pointee type. Pointee is required to always be a function type.
+  QualType getPointeeType() const { return PointeeType; }
+
+  bool isSugared() const { return false; }
+  QualType desugar() const { return QualType(this, 0); }
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+      Profile(ID, getPointeeType());
+  }
+  static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee) {
+      ID.AddPointer(Pointee.getAsOpaquePtr());
+  }
+
+  virtual Linkage getLinkage() const;
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == BlockPointer;
+  }
+  static bool classof(const BlockPointerType *) { return true; }
+};
+
+/// ReferenceType - Base for LValueReferenceType and RValueReferenceType
+///
+class ReferenceType : public Type, public llvm::FoldingSetNode {
+  QualType PointeeType;
+
+  /// True if the type was originally spelled with an lvalue sigil.
+  /// This is never true of rvalue references but can also be false
+  /// on lvalue references because of C++0x [dcl.typedef]p9,
+  /// as follows:
+  ///
+  ///   typedef int &ref;    // lvalue, spelled lvalue
+  ///   typedef int &&rvref; // rvalue
+  ///   ref &a;              // lvalue, inner ref, spelled lvalue
+  ///   ref &&a;             // lvalue, inner ref
+  ///   rvref &a;            // lvalue, inner ref, spelled lvalue
+  ///   rvref &&a;           // rvalue, inner ref
+  bool SpelledAsLValue;
+
+  /// True if the inner type is a reference type.  This only happens
+  /// in non-canonical forms.
+  bool InnerRef;
+
+protected:
+  ReferenceType(TypeClass tc, QualType Referencee, QualType CanonicalRef,
+                bool SpelledAsLValue) :
+    Type(tc, CanonicalRef, Referencee->isDependentType()),
+    PointeeType(Referencee), SpelledAsLValue(SpelledAsLValue),
+    InnerRef(Referencee->isReferenceType()) {
+  }
+public:
+  bool isSpelledAsLValue() const { return SpelledAsLValue; }
+  bool isInnerRef() const { return InnerRef; }
+  
+  QualType getPointeeTypeAsWritten() const { return PointeeType; }
+  QualType getPointeeType() const {
+    // FIXME: this might strip inner qualifiers; okay?
+    const ReferenceType *T = this;
+    while (T->InnerRef)
+      T = T->PointeeType->getAs<ReferenceType>();
+    return T->PointeeType;
+  }
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    Profile(ID, PointeeType, SpelledAsLValue);
+  }
+  static void Profile(llvm::FoldingSetNodeID &ID,
+                      QualType Referencee,
+                      bool SpelledAsLValue) {
+    ID.AddPointer(Referencee.getAsOpaquePtr());
+    ID.AddBoolean(SpelledAsLValue);
+  }
+
+  virtual Linkage getLinkage() const;
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == LValueReference ||
+           T->getTypeClass() == RValueReference;
+  }
+  static bool classof(const ReferenceType *) { return true; }
+};
+
+/// LValueReferenceType - C++ [dcl.ref] - Lvalue reference
+///
+class LValueReferenceType : public ReferenceType {
+  LValueReferenceType(QualType Referencee, QualType CanonicalRef,
+                      bool SpelledAsLValue) :
+    ReferenceType(LValueReference, Referencee, CanonicalRef, SpelledAsLValue)
+  {}
+  friend class ASTContext; // ASTContext creates these
+public:
+  bool isSugared() const { return false; }
+  QualType desugar() const { return QualType(this, 0); }
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == LValueReference;
+  }
+  static bool classof(const LValueReferenceType *) { return true; }
+};
+
+/// RValueReferenceType - C++0x [dcl.ref] - Rvalue reference
+///
+class RValueReferenceType : public ReferenceType {
+  RValueReferenceType(QualType Referencee, QualType CanonicalRef) :
+    ReferenceType(RValueReference, Referencee, CanonicalRef, false) {
+  }
+  friend class ASTContext; // ASTContext creates these
+public:
+  bool isSugared() const { return false; }
+  QualType desugar() const { return QualType(this, 0); }
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == RValueReference;
+  }
+  static bool classof(const RValueReferenceType *) { return true; }
+};
+
+/// MemberPointerType - C++ 8.3.3 - Pointers to members
+///
+class MemberPointerType : public Type, public llvm::FoldingSetNode {
+  QualType PointeeType;
+  /// The class of which the pointee is a member. Must ultimately be a
+  /// RecordType, but could be a typedef or a template parameter too.
+  const Type *Class;
+
+  MemberPointerType(QualType Pointee, const Type *Cls, QualType CanonicalPtr) :
+    Type(MemberPointer, CanonicalPtr,
+         Cls->isDependentType() || Pointee->isDependentType()),
+    PointeeType(Pointee), Class(Cls) {
+  }
+  friend class ASTContext; // ASTContext creates these.
+public:
+
+  QualType getPointeeType() const { return PointeeType; }
+
+  const Type *getClass() const { return Class; }
+
+  bool isSugared() const { return false; }
+  QualType desugar() const { return QualType(this, 0); }
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    Profile(ID, getPointeeType(), getClass());
+  }
+  static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee,
+                      const Type *Class) {
+    ID.AddPointer(Pointee.getAsOpaquePtr());
+    ID.AddPointer(Class);
+  }
+
+  virtual Linkage getLinkage() const;
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == MemberPointer;
+  }
+  static bool classof(const MemberPointerType *) { return true; }
+};
+
+/// ArrayType - C99 6.7.5.2 - Array Declarators.
+///
+class ArrayType : public Type, public llvm::FoldingSetNode {
+public:
+  /// ArraySizeModifier - Capture whether this is a normal array (e.g. int X[4])
+  /// an array with a static size (e.g. int X[static 4]), or an array
+  /// with a star size (e.g. int X[*]).
+  /// 'static' is only allowed on function parameters.
+  enum ArraySizeModifier {
+    Normal, Static, Star
+  };
+private:
+  /// ElementType - The element type of the array.
+  QualType ElementType;
+
+  // NOTE: VC++ treats enums as signed, avoid using the ArraySizeModifier enum
+  /// NOTE: These fields are packed into the bitfields space in the Type class.
+  unsigned SizeModifier : 2;
+
+  /// IndexTypeQuals - Capture qualifiers in declarations like:
+  /// 'int X[static restrict 4]'. For function parameters only.
+  unsigned IndexTypeQuals : 3;
+
+protected:
+  // C++ [temp.dep.type]p1:
+  //   A type is dependent if it is...
+  //     - an array type constructed from any dependent type or whose
+  //       size is specified by a constant expression that is
+  //       value-dependent,
+  ArrayType(TypeClass tc, QualType et, QualType can,
+            ArraySizeModifier sm, unsigned tq)
+    : Type(tc, can, et->isDependentType() || tc == DependentSizedArray),
+      ElementType(et), SizeModifier(sm), IndexTypeQuals(tq) {}
+
+  friend class ASTContext;  // ASTContext creates these.
+public:
+  QualType getElementType() const { return ElementType; }
+  ArraySizeModifier getSizeModifier() const {
+    return ArraySizeModifier(SizeModifier);
+  }
+  Qualifiers getIndexTypeQualifiers() const {
+    return Qualifiers::fromCVRMask(IndexTypeQuals);
+  }
+  unsigned getIndexTypeCVRQualifiers() const { return IndexTypeQuals; }
+
+  virtual Linkage getLinkage() const;
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == ConstantArray ||
+           T->getTypeClass() == VariableArray ||
+           T->getTypeClass() == IncompleteArray ||
+           T->getTypeClass() == DependentSizedArray;
+  }
+  static bool classof(const ArrayType *) { return true; }
+};
+
+/// ConstantArrayType - This class represents the canonical version of
+/// C arrays with a specified constant size.  For example, the canonical
+/// type for 'int A[4 + 4*100]' is a ConstantArrayType where the element
+/// type is 'int' and the size is 404.
+class ConstantArrayType : public ArrayType {
+  llvm::APInt Size; // Allows us to unique the type.
+
+  ConstantArrayType(QualType et, QualType can, const llvm::APInt &size,
+                    ArraySizeModifier sm, unsigned tq)
+    : ArrayType(ConstantArray, et, can, sm, tq),
+      Size(size) {}
+protected:
+  ConstantArrayType(TypeClass tc, QualType et, QualType can,
+                    const llvm::APInt &size, ArraySizeModifier sm, unsigned tq)
+    : ArrayType(tc, et, can, sm, tq), Size(size) {}
+  friend class ASTContext;  // ASTContext creates these.
+public:
+  const llvm::APInt &getSize() const { return Size; }
+  bool isSugared() const { return false; }
+  QualType desugar() const { return QualType(this, 0); }
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    Profile(ID, getElementType(), getSize(),
+            getSizeModifier(), getIndexTypeCVRQualifiers());
+  }
+  static void Profile(llvm::FoldingSetNodeID &ID, QualType ET,
+                      const llvm::APInt &ArraySize, ArraySizeModifier SizeMod,
+                      unsigned TypeQuals) {
+    ID.AddPointer(ET.getAsOpaquePtr());
+    ID.AddInteger(ArraySize.getZExtValue());
+    ID.AddInteger(SizeMod);
+    ID.AddInteger(TypeQuals);
+  }
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == ConstantArray;
+  }
+  static bool classof(const ConstantArrayType *) { return true; }
+};
+
+/// IncompleteArrayType - This class represents C arrays with an unspecified
+/// size.  For example 'int A[]' has an IncompleteArrayType where the element
+/// type is 'int' and the size is unspecified.
+class IncompleteArrayType : public ArrayType {
+
+  IncompleteArrayType(QualType et, QualType can,
+                      ArraySizeModifier sm, unsigned tq)
+    : ArrayType(IncompleteArray, et, can, sm, tq) {}
+  friend class ASTContext;  // ASTContext creates these.
+public:
+  bool isSugared() const { return false; }
+  QualType desugar() const { return QualType(this, 0); }
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == IncompleteArray;
+  }
+  static bool classof(const IncompleteArrayType *) { return true; }
+
+  friend class StmtIteratorBase;
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    Profile(ID, getElementType(), getSizeModifier(),
+            getIndexTypeCVRQualifiers());
+  }
+
+  static void Profile(llvm::FoldingSetNodeID &ID, QualType ET,
+                      ArraySizeModifier SizeMod, unsigned TypeQuals) {
+    ID.AddPointer(ET.getAsOpaquePtr());
+    ID.AddInteger(SizeMod);
+    ID.AddInteger(TypeQuals);
+  }
+};
+
+/// VariableArrayType - This class represents C arrays with a specified size
+/// which is not an integer-constant-expression.  For example, 'int s[x+foo()]'.
+/// Since the size expression is an arbitrary expression, we store it as such.
+///
+/// Note: VariableArrayType's aren't uniqued (since the expressions aren't) and
+/// should not be: two lexically equivalent variable array types could mean
+/// different things, for example, these variables do not have the same type
+/// dynamically:
+///
+/// void foo(int x) {
+///   int Y[x];
+///   ++x;
+///   int Z[x];
+/// }
+///
+class VariableArrayType : public ArrayType {
+  /// SizeExpr - An assignment expression. VLA's are only permitted within
+  /// a function block.
+  Stmt *SizeExpr;
+  /// Brackets - The left and right array brackets.
+  SourceRange Brackets;
+
+  VariableArrayType(QualType et, QualType can, Expr *e,
+                    ArraySizeModifier sm, unsigned tq,
+                    SourceRange brackets)
+    : ArrayType(VariableArray, et, can, sm, tq),
+      SizeExpr((Stmt*) e), Brackets(brackets) {}
+  friend class ASTContext;  // ASTContext creates these.
+  virtual void Destroy(ASTContext& C);
+
+public:
+  Expr *getSizeExpr() const {
+    // We use C-style casts instead of cast<> here because we do not wish
+    // to have a dependency of Type.h on Stmt.h/Expr.h.
+    return (Expr*) SizeExpr;
+  }
+  SourceRange getBracketsRange() const { return Brackets; }
+  SourceLocation getLBracketLoc() const { return Brackets.getBegin(); }
+  SourceLocation getRBracketLoc() const { return Brackets.getEnd(); }
+
+  bool isSugared() const { return false; }
+  QualType desugar() const { return QualType(this, 0); }
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == VariableArray;
+  }
+  static bool classof(const VariableArrayType *) { return true; }
+
+  friend class StmtIteratorBase;
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    assert(0 && "Cannnot unique VariableArrayTypes.");
+  }
+};
+
+/// DependentSizedArrayType - This type represents an array type in
+/// C++ whose size is a value-dependent expression. For example:
+///
+/// \code
+/// template<typename T, int Size>
+/// class array {
+///   T data[Size];
+/// };
+/// \endcode
+///
+/// For these types, we won't actually know what the array bound is
+/// until template instantiation occurs, at which point this will
+/// become either a ConstantArrayType or a VariableArrayType.
+class DependentSizedArrayType : public ArrayType {
+  ASTContext &Context;
+
+  /// \brief An assignment expression that will instantiate to the
+  /// size of the array.
+  ///
+  /// The expression itself might be NULL, in which case the array
+  /// type will have its size deduced from an initializer.
+  Stmt *SizeExpr;
+
+  /// Brackets - The left and right array brackets.
+  SourceRange Brackets;
+
+  DependentSizedArrayType(ASTContext &Context, QualType et, QualType can,
+                          Expr *e, ArraySizeModifier sm, unsigned tq,
+                          SourceRange brackets)
+    : ArrayType(DependentSizedArray, et, can, sm, tq),
+      Context(Context), SizeExpr((Stmt*) e), Brackets(brackets) {}
+  friend class ASTContext;  // ASTContext creates these.
+  virtual void Destroy(ASTContext& C);
+
+public:
+  Expr *getSizeExpr() const {
+    // We use C-style casts instead of cast<> here because we do not wish
+    // to have a dependency of Type.h on Stmt.h/Expr.h.
+    return (Expr*) SizeExpr;
+  }
+  SourceRange getBracketsRange() const { return Brackets; }
+  SourceLocation getLBracketLoc() const { return Brackets.getBegin(); }
+  SourceLocation getRBracketLoc() const { return Brackets.getEnd(); }
+
+  bool isSugared() const { return false; }
+  QualType desugar() const { return QualType(this, 0); }
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == DependentSizedArray;
+  }
+  static bool classof(const DependentSizedArrayType *) { return true; }
+
+  friend class StmtIteratorBase;
+
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    Profile(ID, Context, getElementType(),
+            getSizeModifier(), getIndexTypeCVRQualifiers(), getSizeExpr());
+  }
+
+  static void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context,
+                      QualType ET, ArraySizeModifier SizeMod,
+                      unsigned TypeQuals, Expr *E);
+};
+
+/// DependentSizedExtVectorType - This type represent an extended vector type
+/// where either the type or size is dependent. For example:
+/// @code
+/// template<typename T, int Size>
+/// class vector {
+///   typedef T __attribute__((ext_vector_type(Size))) type;
+/// }
+/// @endcode
+class DependentSizedExtVectorType : public Type, public llvm::FoldingSetNode {
+  ASTContext &Context;
+  Expr *SizeExpr;
+  /// ElementType - The element type of the array.
+  QualType ElementType;
+  SourceLocation loc;
+
+  DependentSizedExtVectorType(ASTContext &Context, QualType ElementType,
+                              QualType can, Expr *SizeExpr, SourceLocation loc)
+    : Type (DependentSizedExtVector, can, true),
+      Context(Context), SizeExpr(SizeExpr), ElementType(ElementType),
+      loc(loc) {}
+  friend class ASTContext;
+  virtual void Destroy(ASTContext& C);
+
+public:
+  Expr *getSizeExpr() const { return SizeExpr; }
+  QualType getElementType() const { return ElementType; }
+  SourceLocation getAttributeLoc() const { return loc; }
+
+  bool isSugared() const { return false; }
+  QualType desugar() const { return QualType(this, 0); }
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == DependentSizedExtVector;
+  }
+  static bool classof(const DependentSizedExtVectorType *) { return true; }
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    Profile(ID, Context, getElementType(), getSizeExpr());
+  }
+
+  static void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context,
+                      QualType ElementType, Expr *SizeExpr);
+};
+
+
+/// VectorType - GCC generic vector type. This type is created using
+/// __attribute__((vector_size(n)), where "n" specifies the vector size in
+/// bytes; or from an Altivec __vector or vector declaration.
+/// Since the constructor takes the number of vector elements, the
+/// client is responsible for converting the size into the number of elements.
+class VectorType : public Type, public llvm::FoldingSetNode {
+protected:
+  /// ElementType - The element type of the vector.
+  QualType ElementType;
+
+  /// NumElements - The number of elements in the vector.
+  unsigned NumElements;
+
+  /// AltiVec - True if this is for an Altivec vector.
+  bool AltiVec;
+
+  /// Pixel - True if this is for an Altivec vector pixel.
+  bool Pixel;
+
+  VectorType(QualType vecType, unsigned nElements, QualType canonType,
+      bool isAltiVec, bool isPixel) :
+    Type(Vector, canonType, vecType->isDependentType()),
+    ElementType(vecType), NumElements(nElements),
+    AltiVec(isAltiVec), Pixel(isPixel) {}
+  VectorType(TypeClass tc, QualType vecType, unsigned nElements,
+             QualType canonType, bool isAltiVec, bool isPixel)
+    : Type(tc, canonType, vecType->isDependentType()), ElementType(vecType),
+      NumElements(nElements), AltiVec(isAltiVec), Pixel(isPixel) {}
+  friend class ASTContext;  // ASTContext creates these.
+public:
+
+  QualType getElementType() const { return ElementType; }
+  unsigned getNumElements() const { return NumElements; }
+
+  bool isSugared() const { return false; }
+  QualType desugar() const { return QualType(this, 0); }
+
+  bool isAltiVec() const { return AltiVec; }
+  
+  bool isPixel() const { return Pixel; }
+  
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    Profile(ID, getElementType(), getNumElements(), getTypeClass(),
+      AltiVec, Pixel);
+  }
+  static void Profile(llvm::FoldingSetNodeID &ID, QualType ElementType,
+                      unsigned NumElements, TypeClass TypeClass,
+                      bool isAltiVec, bool isPixel) {
+    ID.AddPointer(ElementType.getAsOpaquePtr());
+    ID.AddInteger(NumElements);
+    ID.AddInteger(TypeClass);
+    ID.AddBoolean(isAltiVec);
+    ID.AddBoolean(isPixel);
+  }
+
+  virtual Linkage getLinkage() const;
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == Vector || T->getTypeClass() == ExtVector;
+  }
+  static bool classof(const VectorType *) { return true; }
+};
+
+/// ExtVectorType - Extended vector type. This type is created using
+/// __attribute__((ext_vector_type(n)), where "n" is the number of elements.
+/// Unlike vector_size, ext_vector_type is only allowed on typedef's. This
+/// class enables syntactic extensions, like Vector Components for accessing
+/// points, colors, and textures (modeled after OpenGL Shading Language).
+class ExtVectorType : public VectorType {
+  ExtVectorType(QualType vecType, unsigned nElements, QualType canonType) :
+    VectorType(ExtVector, vecType, nElements, canonType, false, false) {}
+  friend class ASTContext;  // ASTContext creates these.
+public:
+  static int getPointAccessorIdx(char c) {
+    switch (c) {
+    default: return -1;
+    case 'x': return 0;
+    case 'y': return 1;
+    case 'z': return 2;
+    case 'w': return 3;
+    }
+  }
+  static int getNumericAccessorIdx(char c) {
+    switch (c) {
+      default: return -1;
+      case '0': return 0;
+      case '1': return 1;
+      case '2': return 2;
+      case '3': return 3;
+      case '4': return 4;
+      case '5': return 5;
+      case '6': return 6;
+      case '7': return 7;
+      case '8': return 8;
+      case '9': return 9;
+      case 'A':
+      case 'a': return 10;
+      case 'B':
+      case 'b': return 11;
+      case 'C':
+      case 'c': return 12;
+      case 'D':
+      case 'd': return 13;
+      case 'E':
+      case 'e': return 14;
+      case 'F':
+      case 'f': return 15;
+    }
+  }
+
+  static int getAccessorIdx(char c) {
+    if (int idx = getPointAccessorIdx(c)+1) return idx-1;
+    return getNumericAccessorIdx(c);
+  }
+
+  bool isAccessorWithinNumElements(char c) const {
+    if (int idx = getAccessorIdx(c)+1)
+      return unsigned(idx-1) < NumElements;
+    return false;
+  }
+  bool isSugared() const { return false; }
+  QualType desugar() const { return QualType(this, 0); }
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == ExtVector;
+  }
+  static bool classof(const ExtVectorType *) { return true; }
+};
+
+/// FunctionType - C99 6.7.5.3 - Function Declarators.  This is the common base
+/// class of FunctionNoProtoType and FunctionProtoType.
+///
+class FunctionType : public Type {
+  /// SubClassData - This field is owned by the subclass, put here to pack
+  /// tightly with the ivars in Type.
+  bool SubClassData : 1;
+
+  /// TypeQuals - Used only by FunctionProtoType, put here to pack with the
+  /// other bitfields.
+  /// The qualifiers are part of FunctionProtoType because...
+  ///
+  /// C++ 8.3.5p4: The return type, the parameter type list and the
+  /// cv-qualifier-seq, [...], are part of the function type.
+  ///
+  unsigned TypeQuals : 3;
+
+  /// NoReturn - Indicates if the function type is attribute noreturn.
+  unsigned NoReturn : 1;
+
+  /// RegParm - How many arguments to pass inreg.
+  unsigned RegParm : 3;
+
+  /// CallConv - The calling convention used by the function.
+  unsigned CallConv : 2;
+
+  // The type returned by the function.
+  QualType ResultType;
+
+ public:
+  // This class is used for passing arround the information needed to
+  // construct a call. It is not actually used for storage, just for
+  // factoring together common arguments.
+  // If you add a field (say Foo), other than the obvious places (both, constructors,
+  // compile failures), what you need to update is
+  // * Operetor==
+  // * getFoo
+  // * withFoo
+  // * functionType. Add Foo, getFoo.
+  // * ASTContext::getFooType
+  // * ASTContext::mergeFunctionTypes
+  // * FunctionNoProtoType::Profile
+  // * FunctionProtoType::Profile
+  // * TypePrinter::PrintFunctionProto
+  // * PCH read and write
+  // * Codegen
+
+  class ExtInfo {
+   public:
+    // Constructor with no defaults. Use this when you know that you
+    // have all the elements (when reading a PCH file for example).
+    ExtInfo(bool noReturn, unsigned regParm, CallingConv cc) :
+        NoReturn(noReturn), RegParm(regParm), CC(cc) {}
+
+    // Constructor with all defaults. Use when for example creating a
+    // function know to use defaults.
+    ExtInfo() : NoReturn(false), RegParm(0), CC(CC_Default) {}
+
+    bool getNoReturn() const { return NoReturn; }
+    unsigned getRegParm() const { return RegParm; }
+    CallingConv getCC() const { return CC; }
+
+    bool operator==(const ExtInfo &Other) const {
+      return getNoReturn() == Other.getNoReturn() &&
+          getRegParm() == Other.getRegParm() &&
+          getCC() == Other.getCC();
+    }
+    bool operator!=(const ExtInfo &Other) const {
+      return !(*this == Other);
+    }
+
+    // Note that we don't have setters. That is by design, use
+    // the following with methods instead of mutating these objects.
+
+    ExtInfo withNoReturn(bool noReturn) const {
+      return ExtInfo(noReturn, getRegParm(), getCC());
+    }
+
+    ExtInfo withRegParm(unsigned RegParm) const {
+      return ExtInfo(getNoReturn(), RegParm, getCC());
+    }
+
+    ExtInfo withCallingConv(CallingConv cc) const {
+      return ExtInfo(getNoReturn(), getRegParm(), cc);
+    }
+
+   private:
+    // True if we have __attribute__((noreturn))
+    bool NoReturn;
+    // The value passed to __attribute__((regparm(x)))
+    unsigned RegParm;
+    // The calling convention as specified via
+    // __attribute__((cdecl|stdcall||fastcall))
+    CallingConv CC;
+  };
+
+protected:
+  FunctionType(TypeClass tc, QualType res, bool SubclassInfo,
+               unsigned typeQuals, QualType Canonical, bool Dependent,
+               const ExtInfo &Info)
+    : Type(tc, Canonical, Dependent),
+      SubClassData(SubclassInfo), TypeQuals(typeQuals),
+      NoReturn(Info.getNoReturn()),
+      RegParm(Info.getRegParm()), CallConv(Info.getCC()), ResultType(res) {}
+  bool getSubClassData() const { return SubClassData; }
+  unsigned getTypeQuals() const { return TypeQuals; }
+public:
+
+  QualType getResultType() const { return ResultType; }
+  unsigned getRegParmType() const { return RegParm; }
+  bool getNoReturnAttr() const { return NoReturn; }
+  CallingConv getCallConv() const { return (CallingConv)CallConv; }
+  ExtInfo getExtInfo() const {
+    return ExtInfo(NoReturn, RegParm, (CallingConv)CallConv);
+  }
+
+  static llvm::StringRef getNameForCallConv(CallingConv CC);
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == FunctionNoProto ||
+           T->getTypeClass() == FunctionProto;
+  }
+  static bool classof(const FunctionType *) { return true; }
+};
+
+/// FunctionNoProtoType - Represents a K&R-style 'int foo()' function, which has
+/// no information available about its arguments.
+class FunctionNoProtoType : public FunctionType, public llvm::FoldingSetNode {
+  FunctionNoProtoType(QualType Result, QualType Canonical,
+                      const ExtInfo &Info)
+    : FunctionType(FunctionNoProto, Result, false, 0, Canonical,
+                   /*Dependent=*/false, Info) {}
+  friend class ASTContext;  // ASTContext creates these.
+public:
+  // No additional state past what FunctionType provides.
+
+  bool isSugared() const { return false; }
+  QualType desugar() const { return QualType(this, 0); }
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    Profile(ID, getResultType(), getExtInfo());
+  }
+  static void Profile(llvm::FoldingSetNodeID &ID, QualType ResultType,
+                      const ExtInfo &Info) {
+    ID.AddInteger(Info.getCC());
+    ID.AddInteger(Info.getRegParm());
+    ID.AddInteger(Info.getNoReturn());
+    ID.AddPointer(ResultType.getAsOpaquePtr());
+  }
+
+  virtual Linkage getLinkage() const;
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == FunctionNoProto;
+  }
+  static bool classof(const FunctionNoProtoType *) { return true; }
+};
+
+/// FunctionProtoType - Represents a prototype with argument type info, e.g.
+/// 'int foo(int)' or 'int foo(void)'.  'void' is represented as having no
+/// arguments, not as having a single void argument. Such a type can have an
+/// exception specification, but this specification is not part of the canonical
+/// type.
+class FunctionProtoType : public FunctionType, public llvm::FoldingSetNode {
+  /// hasAnyDependentType - Determine whether there are any dependent
+  /// types within the arguments passed in.
+  static bool hasAnyDependentType(const QualType *ArgArray, unsigned numArgs) {
+    for (unsigned Idx = 0; Idx < numArgs; ++Idx)
+      if (ArgArray[Idx]->isDependentType())
+    return true;
+
+    return false;
+  }
+
+  FunctionProtoType(QualType Result, const QualType *ArgArray, unsigned numArgs,
+                    bool isVariadic, unsigned typeQuals, bool hasExs,
+                    bool hasAnyExs, const QualType *ExArray,
+                    unsigned numExs, QualType Canonical,
+                    const ExtInfo &Info)
+    : FunctionType(FunctionProto, Result, isVariadic, typeQuals, Canonical,
+                   (Result->isDependentType() ||
+                    hasAnyDependentType(ArgArray, numArgs)),
+                   Info),
+      NumArgs(numArgs), NumExceptions(numExs), HasExceptionSpec(hasExs),
+      AnyExceptionSpec(hasAnyExs) {
+    // Fill in the trailing argument array.
+    QualType *ArgInfo = reinterpret_cast<QualType*>(this+1);
+    for (unsigned i = 0; i != numArgs; ++i)
+      ArgInfo[i] = ArgArray[i];
+    // Fill in the exception array.
+    QualType *Ex = ArgInfo + numArgs;
+    for (unsigned i = 0; i != numExs; ++i)
+      Ex[i] = ExArray[i];
+  }
+
+  /// NumArgs - The number of arguments this function has, not counting '...'.
+  unsigned NumArgs : 20;
+
+  /// NumExceptions - The number of types in the exception spec, if any.
+  unsigned NumExceptions : 10;
+
+  /// HasExceptionSpec - Whether this function has an exception spec at all.
+  bool HasExceptionSpec : 1;
+
+  /// AnyExceptionSpec - Whether this function has a throw(...) spec.
+  bool AnyExceptionSpec : 1;
+
+  /// ArgInfo - There is an variable size array after the class in memory that
+  /// holds the argument types.
+
+  /// Exceptions - There is another variable size array after ArgInfo that
+  /// holds the exception types.
+
+  friend class ASTContext;  // ASTContext creates these.
+
+public:
+  unsigned getNumArgs() const { return NumArgs; }
+  QualType getArgType(unsigned i) const {
+    assert(i < NumArgs && "Invalid argument number!");
+    return arg_type_begin()[i];
+  }
+
+  bool hasExceptionSpec() const { return HasExceptionSpec; }
+  bool hasAnyExceptionSpec() const { return AnyExceptionSpec; }
+  unsigned getNumExceptions() const { return NumExceptions; }
+  QualType getExceptionType(unsigned i) const {
+    assert(i < NumExceptions && "Invalid exception number!");
+    return exception_begin()[i];
+  }
+  bool hasEmptyExceptionSpec() const {
+    return hasExceptionSpec() && !hasAnyExceptionSpec() &&
+      getNumExceptions() == 0;
+  }
+
+  bool isVariadic() const { return getSubClassData(); }
+  unsigned getTypeQuals() const { return FunctionType::getTypeQuals(); }
+
+  typedef const QualType *arg_type_iterator;
+  arg_type_iterator arg_type_begin() const {
+    return reinterpret_cast<const QualType *>(this+1);
+  }
+  arg_type_iterator arg_type_end() const { return arg_type_begin()+NumArgs; }
+
+  typedef const QualType *exception_iterator;
+  exception_iterator exception_begin() const {
+    // exceptions begin where arguments end
+    return arg_type_end();
+  }
+  exception_iterator exception_end() const {
+    return exception_begin() + NumExceptions;
+  }
+
+  bool isSugared() const { return false; }
+  QualType desugar() const { return QualType(this, 0); }
+
+  virtual Linkage getLinkage() const;
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == FunctionProto;
+  }
+  static bool classof(const FunctionProtoType *) { return true; }
+
+  void Profile(llvm::FoldingSetNodeID &ID);
+  static void Profile(llvm::FoldingSetNodeID &ID, QualType Result,
+                      arg_type_iterator ArgTys, unsigned NumArgs,
+                      bool isVariadic, unsigned TypeQuals,
+                      bool hasExceptionSpec, bool anyExceptionSpec,
+                      unsigned NumExceptions, exception_iterator Exs,
+                      const ExtInfo &ExtInfo);
+};
+
+
+/// \brief Represents the dependent type named by a dependently-scoped
+/// typename using declaration, e.g.
+///   using typename Base<T>::foo;
+/// Template instantiation turns these into the underlying type.
+class UnresolvedUsingType : public Type {
+  UnresolvedUsingTypenameDecl *Decl;
+
+  UnresolvedUsingType(const UnresolvedUsingTypenameDecl *D)
+    : Type(UnresolvedUsing, QualType(), true),
+      Decl(const_cast<UnresolvedUsingTypenameDecl*>(D)) {}
+  friend class ASTContext; // ASTContext creates these.
+public:
+
+  UnresolvedUsingTypenameDecl *getDecl() const { return Decl; }
+
+  bool isSugared() const { return false; }
+  QualType desugar() const { return QualType(this, 0); }
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == UnresolvedUsing;
+  }
+  static bool classof(const UnresolvedUsingType *) { return true; }
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    return Profile(ID, Decl);
+  }
+  static void Profile(llvm::FoldingSetNodeID &ID,
+                      UnresolvedUsingTypenameDecl *D) {
+    ID.AddPointer(D);
+  }
+};
+
+
+class TypedefType : public Type {
+  TypedefDecl *Decl;
+protected:
+  TypedefType(TypeClass tc, const TypedefDecl *D, QualType can)
+    : Type(tc, can, can->isDependentType()),
+      Decl(const_cast<TypedefDecl*>(D)) {
+    assert(!isa<TypedefType>(can) && "Invalid canonical type");
+  }
+  friend class ASTContext;  // ASTContext creates these.
+public:
+
+  TypedefDecl *getDecl() const { return Decl; }
+
+  /// LookThroughTypedefs - Return the ultimate type this typedef corresponds to
+  /// potentially looking through *all* consecutive typedefs.  This returns the
+  /// sum of the type qualifiers, so if you have:
+  ///   typedef const int A;
+  ///   typedef volatile A B;
+  /// looking through the typedefs for B will give you "const volatile A".
+  QualType LookThroughTypedefs() const;
+
+  bool isSugared() const { return true; }
+  QualType desugar() const;
+
+  static bool classof(const Type *T) { return T->getTypeClass() == Typedef; }
+  static bool classof(const TypedefType *) { return true; }
+};
+
+/// TypeOfExprType (GCC extension).
+class TypeOfExprType : public Type {
+  Expr *TOExpr;
+
+protected:
+  TypeOfExprType(Expr *E, QualType can = QualType());
+  friend class ASTContext;  // ASTContext creates these.
+public:
+  Expr *getUnderlyingExpr() const { return TOExpr; }
+
+  /// \brief Remove a single level of sugar.
+  QualType desugar() const;
+
+  /// \brief Returns whether this type directly provides sugar.
+  bool isSugared() const { return true; }
+
+  static bool classof(const Type *T) { return T->getTypeClass() == TypeOfExpr; }
+  static bool classof(const TypeOfExprType *) { return true; }
+};
+
+/// \brief Internal representation of canonical, dependent
+/// typeof(expr) types.
+///
+/// This class is used internally by the ASTContext to manage
+/// canonical, dependent types, only. Clients will only see instances
+/// of this class via TypeOfExprType nodes.
+class DependentTypeOfExprType
+  : public TypeOfExprType, public llvm::FoldingSetNode {
+  ASTContext &Context;
+
+public:
+  DependentTypeOfExprType(ASTContext &Context, Expr *E)
+    : TypeOfExprType(E), Context(Context) { }
+
+  bool isSugared() const { return false; }
+  QualType desugar() const { return QualType(this, 0); }
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    Profile(ID, Context, getUnderlyingExpr());
+  }
+
+  static void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context,
+                      Expr *E);
+};
+
+/// TypeOfType (GCC extension).
+class TypeOfType : public Type {
+  QualType TOType;
+  TypeOfType(QualType T, QualType can)
+    : Type(TypeOf, can, T->isDependentType()), TOType(T) {
+    assert(!isa<TypedefType>(can) && "Invalid canonical type");
+  }
+  friend class ASTContext;  // ASTContext creates these.
+public:
+  QualType getUnderlyingType() const { return TOType; }
+
+  /// \brief Remove a single level of sugar.
+  QualType desugar() const { return getUnderlyingType(); }
+
+  /// \brief Returns whether this type directly provides sugar.
+  bool isSugared() const { return true; }
+
+  static bool classof(const Type *T) { return T->getTypeClass() == TypeOf; }
+  static bool classof(const TypeOfType *) { return true; }
+};
+
+/// DecltypeType (C++0x)
+class DecltypeType : public Type {
+  Expr *E;
+
+  // FIXME: We could get rid of UnderlyingType if we wanted to: We would have to
+  // Move getDesugaredType to ASTContext so that it can call getDecltypeForExpr
+  // from it.
+  QualType UnderlyingType;
+
+protected:
+  DecltypeType(Expr *E, QualType underlyingType, QualType can = QualType());
+  friend class ASTContext;  // ASTContext creates these.
+public:
+  Expr *getUnderlyingExpr() const { return E; }
+  QualType getUnderlyingType() const { return UnderlyingType; }
+
+  /// \brief Remove a single level of sugar.
+  QualType desugar() const { return getUnderlyingType(); }
+
+  /// \brief Returns whether this type directly provides sugar.
+  bool isSugared() const { return !isDependentType(); }
+
+  static bool classof(const Type *T) { return T->getTypeClass() == Decltype; }
+  static bool classof(const DecltypeType *) { return true; }
+};
+
+/// \brief Internal representation of canonical, dependent
+/// decltype(expr) types.
+///
+/// This class is used internally by the ASTContext to manage
+/// canonical, dependent types, only. Clients will only see instances
+/// of this class via DecltypeType nodes.
+class DependentDecltypeType : public DecltypeType, public llvm::FoldingSetNode {
+  ASTContext &Context;
+
+public:
+  DependentDecltypeType(ASTContext &Context, Expr *E);
+
+  bool isSugared() const { return false; }
+  QualType desugar() const { return QualType(this, 0); }
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    Profile(ID, Context, getUnderlyingExpr());
+  }
+
+  static void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context,
+                      Expr *E);
+};
+
+class TagType : public Type {
+  /// Stores the TagDecl associated with this type. The decl will
+  /// point to the TagDecl that actually defines the entity (or is a
+  /// definition in progress), if there is such a definition. The
+  /// single-bit value will be non-zero when this tag is in the
+  /// process of being defined.
+  mutable llvm::PointerIntPair<TagDecl *, 1> decl;
+  friend class ASTContext;
+  friend class TagDecl;
+
+protected:
+  TagType(TypeClass TC, const TagDecl *D, QualType can);
+
+public:
+  TagDecl *getDecl() const { return decl.getPointer(); }
+
+  /// @brief Determines whether this type is in the process of being
+  /// defined.
+  bool isBeingDefined() const { return decl.getInt(); }
+  void setBeingDefined(bool Def) const { decl.setInt(Def? 1 : 0); }
+
+  virtual Linkage getLinkage() const;
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() >= TagFirst && T->getTypeClass() <= TagLast;
+  }
+  static bool classof(const TagType *) { return true; }
+  static bool classof(const RecordType *) { return true; }
+  static bool classof(const EnumType *) { return true; }
+};
+
+/// RecordType - This is a helper class that allows the use of isa/cast/dyncast
+/// to detect TagType objects of structs/unions/classes.
+class RecordType : public TagType {
+protected:
+  explicit RecordType(const RecordDecl *D)
+    : TagType(Record, reinterpret_cast<const TagDecl*>(D), QualType()) { }
+  explicit RecordType(TypeClass TC, RecordDecl *D)
+    : TagType(TC, reinterpret_cast<const TagDecl*>(D), QualType()) { }
+  friend class ASTContext;   // ASTContext creates these.
+public:
+
+  RecordDecl *getDecl() const {
+    return reinterpret_cast<RecordDecl*>(TagType::getDecl());
+  }
+
+  // FIXME: This predicate is a helper to QualType/Type. It needs to
+  // recursively check all fields for const-ness. If any field is declared
+  // const, it needs to return false.
+  bool hasConstFields() const { return false; }
+
+  // FIXME: RecordType needs to check when it is created that all fields are in
+  // the same address space, and return that.
+  unsigned getAddressSpace() const { return 0; }
+
+  bool isSugared() const { return false; }
+  QualType desugar() const { return QualType(this, 0); }
+
+  static bool classof(const TagType *T);
+  static bool classof(const Type *T) {
+    return isa<TagType>(T) && classof(cast<TagType>(T));
+  }
+  static bool classof(const RecordType *) { return true; }
+};
+
+/// EnumType - This is a helper class that allows the use of isa/cast/dyncast
+/// to detect TagType objects of enums.
+class EnumType : public TagType {
+  explicit EnumType(const EnumDecl *D)
+    : TagType(Enum, reinterpret_cast<const TagDecl*>(D), QualType()) { }
+  friend class ASTContext;   // ASTContext creates these.
+public:
+
+  EnumDecl *getDecl() const {
+    return reinterpret_cast<EnumDecl*>(TagType::getDecl());
+  }
+
+  bool isSugared() const { return false; }
+  QualType desugar() const { return QualType(this, 0); }
+
+  static bool classof(const TagType *T);
+  static bool classof(const Type *T) {
+    return isa<TagType>(T) && classof(cast<TagType>(T));
+  }
+  static bool classof(const EnumType *) { return true; }
+};
+
+/// ElaboratedType - A non-canonical type used to represents uses of
+/// elaborated type specifiers in C++.  For example:
+///
+///   void foo(union MyUnion);
+///            ^^^^^^^^^^^^^
+///
+/// At the moment, for efficiency we do not create elaborated types in
+/// C, since outside of typedefs all references to structs would
+/// necessarily be elaborated.
+class ElaboratedType : public Type, public llvm::FoldingSetNode {
+public:
+  enum TagKind {
+    TK_struct,
+    TK_union,
+    TK_class,
+    TK_enum
+  };
+
+private:
+  /// The tag that was used in this elaborated type specifier.
+  TagKind Tag;
+
+  /// The underlying type.
+  QualType UnderlyingType;
+
+  explicit ElaboratedType(QualType Ty, TagKind Tag, QualType Canon)
+    : Type(Elaborated, Canon, Canon->isDependentType()),
+      Tag(Tag), UnderlyingType(Ty) { }
+  friend class ASTContext;   // ASTContext creates these.
+
+public:
+  TagKind getTagKind() const { return Tag; }
+  QualType getUnderlyingType() const { return UnderlyingType; }
+
+  /// \brief Remove a single level of sugar.
+  QualType desugar() const { return getUnderlyingType(); }
+
+  /// \brief Returns whether this type directly provides sugar.
+  bool isSugared() const { return true; }
+
+  static const char *getNameForTagKind(TagKind Kind) {
+    switch (Kind) {
+    default: assert(0 && "Unknown TagKind!");
+    case TK_struct: return "struct";
+    case TK_union:  return "union";
+    case TK_class:  return "class";
+    case TK_enum:   return "enum";
+    }
+  }
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    Profile(ID, getUnderlyingType(), getTagKind());
+  }
+  static void Profile(llvm::FoldingSetNodeID &ID, QualType T, TagKind Tag) {
+    ID.AddPointer(T.getAsOpaquePtr());
+    ID.AddInteger(Tag);
+  }
+
+  static bool classof(const ElaboratedType*) { return true; }
+  static bool classof(const Type *T) { return T->getTypeClass() == Elaborated; }
+};
+
+class TemplateTypeParmType : public Type, public llvm::FoldingSetNode {
+  unsigned Depth : 15;
+  unsigned Index : 16;
+  unsigned ParameterPack : 1;
+  IdentifierInfo *Name;
+
+  TemplateTypeParmType(unsigned D, unsigned I, bool PP, IdentifierInfo *N,
+                       QualType Canon)
+    : Type(TemplateTypeParm, Canon, /*Dependent=*/true),
+      Depth(D), Index(I), ParameterPack(PP), Name(N) { }
+
+  TemplateTypeParmType(unsigned D, unsigned I, bool PP)
+    : Type(TemplateTypeParm, QualType(this, 0), /*Dependent=*/true),
+      Depth(D), Index(I), ParameterPack(PP), Name(0) { }
+
+  friend class ASTContext;  // ASTContext creates these
+
+public:
+  unsigned getDepth() const { return Depth; }
+  unsigned getIndex() const { return Index; }
+  bool isParameterPack() const { return ParameterPack; }
+  IdentifierInfo *getName() const { return Name; }
+
+  bool isSugared() const { return false; }
+  QualType desugar() const { return QualType(this, 0); }
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    Profile(ID, Depth, Index, ParameterPack, Name);
+  }
+
+  static void Profile(llvm::FoldingSetNodeID &ID, unsigned Depth,
+                      unsigned Index, bool ParameterPack,
+                      IdentifierInfo *Name) {
+    ID.AddInteger(Depth);
+    ID.AddInteger(Index);
+    ID.AddBoolean(ParameterPack);
+    ID.AddPointer(Name);
+  }
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == TemplateTypeParm;
+  }
+  static bool classof(const TemplateTypeParmType *T) { return true; }
+};
+
+/// \brief Represents the result of substituting a type for a template
+/// type parameter.
+///
+/// Within an instantiated template, all template type parameters have
+/// been replaced with these.  They are used solely to record that a
+/// type was originally written as a template type parameter;
+/// therefore they are never canonical.
+class SubstTemplateTypeParmType : public Type, public llvm::FoldingSetNode {
+  // The original type parameter.
+  const TemplateTypeParmType *Replaced;
+
+  SubstTemplateTypeParmType(const TemplateTypeParmType *Param, QualType Canon)
+    : Type(SubstTemplateTypeParm, Canon, Canon->isDependentType()),
+      Replaced(Param) { }
+
+  friend class ASTContext;
+
+public:
+  IdentifierInfo *getName() const { return Replaced->getName(); }
+
+  /// Gets the template parameter that was substituted for.
+  const TemplateTypeParmType *getReplacedParameter() const {
+    return Replaced;
+  }
+
+  /// Gets the type that was substituted for the template
+  /// parameter.
+  QualType getReplacementType() const {
+    return getCanonicalTypeInternal();
+  }
+
+  bool isSugared() const { return true; }
+  QualType desugar() const { return getReplacementType(); }
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    Profile(ID, getReplacedParameter(), getReplacementType());
+  }
+  static void Profile(llvm::FoldingSetNodeID &ID,
+                      const TemplateTypeParmType *Replaced,
+                      QualType Replacement) {
+    ID.AddPointer(Replaced);
+    ID.AddPointer(Replacement.getAsOpaquePtr());
+  }
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == SubstTemplateTypeParm;
+  }
+  static bool classof(const SubstTemplateTypeParmType *T) { return true; }
+};
+
+/// \brief Represents the type of a template specialization as written
+/// in the source code.
+///
+/// Template specialization types represent the syntactic form of a
+/// template-id that refers to a type, e.g., @c vector<int>. Some
+/// template specialization types are syntactic sugar, whose canonical
+/// type will point to some other type node that represents the
+/// instantiation or class template specialization. For example, a
+/// class template specialization type of @c vector<int> will refer to
+/// a tag type for the instantiation
+/// @c std::vector<int, std::allocator<int>>.
+///
+/// Other template specialization types, for which the template name
+/// is dependent, may be canonical types. These types are always
+/// dependent.
+class TemplateSpecializationType
+  : public Type, public llvm::FoldingSetNode {
+
+  // The ASTContext is currently needed in order to profile expressions.
+  // FIXME: avoid this.
+  //
+  // The bool is whether this is a current instantiation.
+  llvm::PointerIntPair<ASTContext*, 1, bool> ContextAndCurrentInstantiation;
+
+    /// \brief The name of the template being specialized.
+  TemplateName Template;
+
+  /// \brief - The number of template arguments named in this class
+  /// template specialization.
+  unsigned NumArgs;
+
+  TemplateSpecializationType(ASTContext &Context,
+                             TemplateName T,
+                             bool IsCurrentInstantiation,
+                             const TemplateArgument *Args,
+                             unsigned NumArgs, QualType Canon);
+
+  virtual void Destroy(ASTContext& C);
+
+  friend class ASTContext;  // ASTContext creates these
+
+public:
+  /// \brief Determine whether any of the given template arguments are
+  /// dependent.
+  static bool anyDependentTemplateArguments(const TemplateArgument *Args,
+                                            unsigned NumArgs);
+
+  static bool anyDependentTemplateArguments(const TemplateArgumentLoc *Args,
+                                            unsigned NumArgs);
+
+  static bool anyDependentTemplateArguments(const TemplateArgumentListInfo &);
+
+  /// \brief Print a template argument list, including the '<' and '>'
+  /// enclosing the template arguments.
+  static std::string PrintTemplateArgumentList(const TemplateArgument *Args,
+                                               unsigned NumArgs,
+                                               const PrintingPolicy &Policy);
+
+  static std::string PrintTemplateArgumentList(const TemplateArgumentLoc *Args,
+                                               unsigned NumArgs,
+                                               const PrintingPolicy &Policy);
+
+  static std::string PrintTemplateArgumentList(const TemplateArgumentListInfo &,
+                                               const PrintingPolicy &Policy);
+
+  /// True if this template specialization type matches a current
+  /// instantiation in the context in which it is found.
+  bool isCurrentInstantiation() const {
+    return ContextAndCurrentInstantiation.getInt();
+  }
+
+  typedef const TemplateArgument * iterator;
+
+  iterator begin() const { return getArgs(); }
+  iterator end() const;
+
+  /// \brief Retrieve the name of the template that we are specializing.
+  TemplateName getTemplateName() const { return Template; }
+
+  /// \brief Retrieve the template arguments.
+  const TemplateArgument *getArgs() const {
+    return reinterpret_cast<const TemplateArgument *>(this + 1);
+  }
+
+  /// \brief Retrieve the number of template arguments.
+  unsigned getNumArgs() const { return NumArgs; }
+
+  /// \brief Retrieve a specific template argument as a type.
+  /// \precondition @c isArgType(Arg)
+  const TemplateArgument &getArg(unsigned Idx) const;
+
+  bool isSugared() const {
+    return !isDependentType() || isCurrentInstantiation();
+  }
+  QualType desugar() const { return getCanonicalTypeInternal(); }
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    Profile(ID, Template, isCurrentInstantiation(), getArgs(), NumArgs,
+            *ContextAndCurrentInstantiation.getPointer());
+  }
+
+  static void Profile(llvm::FoldingSetNodeID &ID, TemplateName T,
+                      bool IsCurrentInstantiation,
+                      const TemplateArgument *Args,
+                      unsigned NumArgs,
+                      ASTContext &Context);
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == TemplateSpecialization;
+  }
+  static bool classof(const TemplateSpecializationType *T) { return true; }
+};
+
+/// \brief The injected class name of a C++ class template or class
+/// template partial specialization.  Used to record that a type was
+/// spelled with a bare identifier rather than as a template-id; the
+/// equivalent for non-templated classes is just RecordType.
+///
+/// Injected class name types are always dependent.  Template
+/// instantiation turns these into RecordTypes.
+///
+/// Injected class name types are always canonical.  This works
+/// because it is impossible to compare an injected class name type
+/// with the corresponding non-injected template type, for the same
+/// reason that it is impossible to directly compare template
+/// parameters from different dependent contexts: injected class name
+/// types can only occur within the scope of a particular templated
+/// declaration, and within that scope every template specialization
+/// will canonicalize to the injected class name (when appropriate
+/// according to the rules of the language).
+class InjectedClassNameType : public Type {
+  CXXRecordDecl *Decl;
+
+  /// The template specialization which this type represents.
+  /// For example, in
+  ///   template <class T> class A { ... };
+  /// this is A<T>, whereas in
+  ///   template <class X, class Y> class A<B<X,Y> > { ... };
+  /// this is A<B<X,Y> >.
+  ///
+  /// It is always unqualified, always a template specialization type,
+  /// and always dependent.
+  QualType InjectedType;
+
+  friend class ASTContext; // ASTContext creates these.
+  InjectedClassNameType(CXXRecordDecl *D, QualType TST)
+    : Type(InjectedClassName, QualType(), true),
+      Decl(D), InjectedType(TST) {
+    assert(isa<TemplateSpecializationType>(TST));
+    assert(!TST.hasQualifiers());
+    assert(TST->isDependentType());
+  }
+
+public:
+  QualType getInjectedSpecializationType() const { return InjectedType; }
+  const TemplateSpecializationType *getInjectedTST() const {
+    return cast<TemplateSpecializationType>(InjectedType.getTypePtr());
+  }
+
+  CXXRecordDecl *getDecl() const { return Decl; }
+
+  bool isSugared() const { return false; }
+  QualType desugar() const { return QualType(this, 0); }
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == InjectedClassName;
+  }
+  static bool classof(const InjectedClassNameType *T) { return true; }
+};
+
+/// \brief The elaboration keyword that precedes a qualified type name or
+/// introduces an elaborated-type-specifier.
+enum ElaboratedTypeKeyword {
+  /// \brief No keyword precedes the qualified type name.
+  ETK_None,
+  /// \brief The "typename" keyword precedes the qualified type name, e.g.,
+  /// \c typename T::type.
+  ETK_Typename,
+  /// \brief The "class" keyword introduces the elaborated-type-specifier.
+  ETK_Class,
+  /// \brief The "struct" keyword introduces the elaborated-type-specifier.
+  ETK_Struct,
+  /// \brief The "union" keyword introduces the elaborated-type-specifier.
+  ETK_Union,
+  /// \brief The "enum" keyword introduces the elaborated-type-specifier.
+  ETK_Enum
+};
+  
+/// \brief Represents a type that was referred to via a qualified
+/// name, e.g., N::M::type.
+///
+/// This type is used to keep track of a type name as written in the
+/// source code, including any nested-name-specifiers. The type itself
+/// is always "sugar", used to express what was written in the source
+/// code but containing no additional semantic information.
+class QualifiedNameType : public Type, public llvm::FoldingSetNode {
+  /// \brief The nested name specifier containing the qualifier.
+  NestedNameSpecifier *NNS;
+
+  /// \brief The type that this qualified name refers to.
+  QualType NamedType;
+
+  QualifiedNameType(NestedNameSpecifier *NNS, QualType NamedType,
+                    QualType CanonType)
+    : Type(QualifiedName, CanonType, NamedType->isDependentType()),
+      NNS(NNS), NamedType(NamedType) { }
+
+  friend class ASTContext;  // ASTContext creates these
+
+public:
+  /// \brief Retrieve the qualification on this type.
+  NestedNameSpecifier *getQualifier() const { return NNS; }
+
+  /// \brief Retrieve the type named by the qualified-id.
+  QualType getNamedType() const { return NamedType; }
+
+  /// \brief Remove a single level of sugar.
+  QualType desugar() const { return getNamedType(); }
+
+  /// \brief Returns whether this type directly provides sugar.
+  bool isSugared() const { return true; }
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    Profile(ID, NNS, NamedType);
+  }
+
+  static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS,
+                      QualType NamedType) {
+    ID.AddPointer(NNS);
+    NamedType.Profile(ID);
+  }
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == QualifiedName;
+  }
+  static bool classof(const QualifiedNameType *T) { return true; }
+};
+
+/// \brief Represents a qualified type name for which the type name is
+/// dependent. 
+///
+/// DependentNameType represents a class of dependent types that involve a 
+/// dependent nested-name-specifier (e.g., "T::") followed by a (dependent) 
+/// name of a type. The DependentNameType may start with a "typename" (for a
+/// typename-specifier), "class", "struct", "union", or "enum" (for a 
+/// dependent elaborated-type-specifier), or nothing (in contexts where we
+/// know that we must be referring to a type, e.g., in a base class specifier).
+class DependentNameType : public Type, public llvm::FoldingSetNode {
+  /// \brief The keyword used to elaborate this type.
+  ElaboratedTypeKeyword Keyword;
+  
+  /// \brief The nested name specifier containing the qualifier.
+  NestedNameSpecifier *NNS;
+
+  typedef llvm::PointerUnion<const IdentifierInfo *,
+                             const TemplateSpecializationType *> NameType;
+
+  /// \brief The type that this typename specifier refers to.
+  NameType Name;
+
+  DependentNameType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, 
+                    const IdentifierInfo *Name, QualType CanonType)
+    : Type(DependentName, CanonType, true), 
+      Keyword(Keyword), NNS(NNS), Name(Name) {
+    assert(NNS->isDependent() &&
+           "DependentNameType requires a dependent nested-name-specifier");
+  }
+
+  DependentNameType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
+                    const TemplateSpecializationType *Ty, QualType CanonType)
+    : Type(DependentName, CanonType, true), 
+      Keyword(Keyword), NNS(NNS), Name(Ty) {
+    assert(NNS->isDependent() &&
+           "DependentNameType requires a dependent nested-name-specifier");
+  }
+
+  friend class ASTContext;  // ASTContext creates these
+
+public:
+  /// \brief Retrieve the keyword used to elaborate this type.
+  ElaboratedTypeKeyword getKeyword() const { return Keyword; }
+  
+  /// \brief Retrieve the qualification on this type.
+  NestedNameSpecifier *getQualifier() const { return NNS; }
+
+  /// \brief Retrieve the type named by the typename specifier as an
+  /// identifier.
+  ///
+  /// This routine will return a non-NULL identifier pointer when the
+  /// form of the original typename was terminated by an identifier,
+  /// e.g., "typename T::type".
+  const IdentifierInfo *getIdentifier() const {
+    return Name.dyn_cast<const IdentifierInfo *>();
+  }
+
+  /// \brief Retrieve the type named by the typename specifier as a
+  /// type specialization.
+  const TemplateSpecializationType *getTemplateId() const {
+    return Name.dyn_cast<const TemplateSpecializationType *>();
+  }
+
+  bool isSugared() const { return false; }
+  QualType desugar() const { return QualType(this, 0); }
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    Profile(ID, Keyword, NNS, Name);
+  }
+
+  static void Profile(llvm::FoldingSetNodeID &ID, ElaboratedTypeKeyword Keyword,
+                      NestedNameSpecifier *NNS, NameType Name) {
+    ID.AddInteger(Keyword);
+    ID.AddPointer(NNS);
+    ID.AddPointer(Name.getOpaqueValue());
+  }
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == DependentName;
+  }
+  static bool classof(const DependentNameType *T) { return true; }
+};
+
+/// ObjCInterfaceType - Interfaces are the core concept in Objective-C for
+/// object oriented design.  They basically correspond to C++ classes.  There
+/// are two kinds of interface types, normal interfaces like "NSString" and
+/// qualified interfaces, which are qualified with a protocol list like
+/// "NSString<NSCopyable, NSAmazing>".
+class ObjCInterfaceType : public Type, public llvm::FoldingSetNode {
+  ObjCInterfaceDecl *Decl;
+
+  /// \brief The number of protocols stored after the ObjCInterfaceType node.
+  /// The list of protocols is sorted on protocol name. No protocol is enterred 
+  /// more than once.
+  unsigned NumProtocols;
+
+  ObjCInterfaceType(QualType Canonical, ObjCInterfaceDecl *D,
+                    ObjCProtocolDecl **Protos, unsigned NumP);
+  friend class ASTContext;  // ASTContext creates these.
+public:
+  void Destroy(ASTContext& C);
+
+  ObjCInterfaceDecl *getDecl() const { return Decl; }
+
+  /// getNumProtocols - Return the number of qualifying protocols in this
+  /// interface type, or 0 if there are none.
+  unsigned getNumProtocols() const { return NumProtocols; }
+
+  /// \brief Retrieve the Ith protocol.
+  ObjCProtocolDecl *getProtocol(unsigned I) const {
+    assert(I < getNumProtocols() && "Out-of-range protocol access");
+    return qual_begin()[I];
+  }
+  
+  /// qual_iterator and friends: this provides access to the (potentially empty)
+  /// list of protocols qualifying this interface.
+  typedef ObjCProtocolDecl*  const * qual_iterator;
+  qual_iterator qual_begin() const {
+    return reinterpret_cast<qual_iterator>(this + 1);
+  }
+  qual_iterator qual_end() const   {
+    return qual_begin() + NumProtocols;
+  }
+  bool qual_empty() const { return NumProtocols == 0; }
+
+  bool isSugared() const { return false; }
+  QualType desugar() const { return QualType(this, 0); }
+
+  void Profile(llvm::FoldingSetNodeID &ID);
+  static void Profile(llvm::FoldingSetNodeID &ID,
+                      const ObjCInterfaceDecl *Decl,
+                      ObjCProtocolDecl * const *protocols, 
+                      unsigned NumProtocols);
+
+  virtual Linkage getLinkage() const;
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == ObjCInterface;
+  }
+  static bool classof(const ObjCInterfaceType *) { return true; }
+};
+
+/// ObjCObjectPointerType - Used to represent 'id', 'Interface *', 'id <p>',
+/// and 'Interface <p> *'.
+///
+/// Duplicate protocols are removed and protocol list is canonicalized to be in
+/// alphabetical order.
+class ObjCObjectPointerType : public Type, public llvm::FoldingSetNode {
+  QualType PointeeType; // A builtin or interface type.
+
+  /// \brief The number of protocols stored after the ObjCObjectPointerType 
+  /// node.
+  ///
+  /// The list of protocols is sorted on protocol name. No protocol is enterred 
+  /// more than once.
+  unsigned NumProtocols;
+
+  ObjCObjectPointerType(QualType Canonical, QualType T,
+                        ObjCProtocolDecl **Protos, unsigned NumP);
+  friend class ASTContext;  // ASTContext creates these.
+
+public:
+  void Destroy(ASTContext& C);
+
+  // Get the pointee type. Pointee will either be:
+  // - a built-in type (for 'id' and 'Class').
+  // - an interface type (for user-defined types).
+  // - a TypedefType whose canonical type is an interface (as in 'T' below).
+  //   For example: typedef NSObject T; T *var;
+  QualType getPointeeType() const { return PointeeType; }
+
+  const ObjCInterfaceType *getInterfaceType() const {
+    return PointeeType->getAs<ObjCInterfaceType>();
+  }
+  /// getInterfaceDecl - returns an interface decl for user-defined types.
+  ObjCInterfaceDecl *getInterfaceDecl() const {
+    return getInterfaceType() ? getInterfaceType()->getDecl() : 0;
+  }
+  /// isObjCIdType - true for "id".
+  bool isObjCIdType() const {
+    return getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCId) &&
+           !NumProtocols;
+  }
+  /// isObjCClassType - true for "Class".
+  bool isObjCClassType() const {
+    return getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCClass) &&
+           !NumProtocols;
+  }
+  
+  /// isObjCQualifiedIdType - true for "id <p>".
+  bool isObjCQualifiedIdType() const {
+    return getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCId) &&
+           NumProtocols;
+  }
+  /// isObjCQualifiedClassType - true for "Class <p>".
+  bool isObjCQualifiedClassType() const {
+    return getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCClass) &&
+           NumProtocols;
+  }
+  /// qual_iterator and friends: this provides access to the (potentially empty)
+  /// list of protocols qualifying this interface.
+  typedef ObjCProtocolDecl*  const * qual_iterator;
+
+  qual_iterator qual_begin() const {
+    return reinterpret_cast<qual_iterator> (this + 1);
+  }
+  qual_iterator qual_end() const   {
+    return qual_begin() + NumProtocols;
+  }
+  bool qual_empty() const { return NumProtocols == 0; }
+
+  /// getNumProtocols - Return the number of qualifying protocols in this
+  /// interface type, or 0 if there are none.
+  unsigned getNumProtocols() const { return NumProtocols; }
+
+  /// \brief Retrieve the Ith protocol.
+  ObjCProtocolDecl *getProtocol(unsigned I) const {
+    assert(I < getNumProtocols() && "Out-of-range protocol access");
+    return qual_begin()[I];
+  }
+  
+  bool isSugared() const { return false; }
+  QualType desugar() const { return QualType(this, 0); }
+
+  virtual Linkage getLinkage() const;
+
+  void Profile(llvm::FoldingSetNodeID &ID);
+  static void Profile(llvm::FoldingSetNodeID &ID, QualType T,
+                      ObjCProtocolDecl *const *protocols, 
+                      unsigned NumProtocols);
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == ObjCObjectPointer;
+  }
+  static bool classof(const ObjCObjectPointerType *) { return true; }
+};
+
+/// A qualifier set is used to build a set of qualifiers.
+class QualifierCollector : public Qualifiers {
+  ASTContext *Context;
+
+public:
+  QualifierCollector(Qualifiers Qs = Qualifiers())
+    : Qualifiers(Qs), Context(0) {}
+  QualifierCollector(ASTContext &Context, Qualifiers Qs = Qualifiers())
+    : Qualifiers(Qs), Context(&Context) {}
+
+  void setContext(ASTContext &C) { Context = &C; }
+
+  /// Collect any qualifiers on the given type and return an
+  /// unqualified type.
+  const Type *strip(QualType QT) {
+    addFastQualifiers(QT.getLocalFastQualifiers());
+    if (QT.hasLocalNonFastQualifiers()) {
+      const ExtQuals *EQ = QT.getExtQualsUnsafe();
+      Context = &EQ->getContext();
+      addQualifiers(EQ->getQualifiers());
+      return EQ->getBaseType();
+    }
+    return QT.getTypePtrUnsafe();
+  }
+
+  /// Apply the collected qualifiers to the given type.
+  QualType apply(QualType QT) const;
+
+  /// Apply the collected qualifiers to the given type.
+  QualType apply(const Type* T) const;
+
+};
+
+
+// Inline function definitions.
+
+inline bool QualType::isCanonical() const {
+  const Type *T = getTypePtr();
+  if (hasLocalQualifiers())
+    return T->isCanonicalUnqualified() && !isa<ArrayType>(T);
+  return T->isCanonicalUnqualified();
+}
+
+inline bool QualType::isCanonicalAsParam() const {
+  if (hasLocalQualifiers()) return false;
+  const Type *T = getTypePtr();
+  return T->isCanonicalUnqualified() &&
+           !isa<FunctionType>(T) && !isa<ArrayType>(T);
+}
+
+inline bool QualType::isConstQualified() const {
+  return isLocalConstQualified() || 
+              getTypePtr()->getCanonicalTypeInternal().isLocalConstQualified();
+}
+
+inline bool QualType::isRestrictQualified() const {
+  return isLocalRestrictQualified() || 
+            getTypePtr()->getCanonicalTypeInternal().isLocalRestrictQualified();
+}
+
+
+inline bool QualType::isVolatileQualified() const {
+  return isLocalVolatileQualified() || 
+  getTypePtr()->getCanonicalTypeInternal().isLocalVolatileQualified();
+}
+  
+inline bool QualType::hasQualifiers() const {
+  return hasLocalQualifiers() ||
+                  getTypePtr()->getCanonicalTypeInternal().hasLocalQualifiers();
+}
+  
+inline Qualifiers QualType::getQualifiers() const {
+  Qualifiers Quals = getLocalQualifiers();
+  Quals.addQualifiers(
+                 getTypePtr()->getCanonicalTypeInternal().getLocalQualifiers());
+  return Quals;
+}
+  
+inline unsigned QualType::getCVRQualifiers() const {
+  return getLocalCVRQualifiers() | 
+              getTypePtr()->getCanonicalTypeInternal().getLocalCVRQualifiers();
+}
+
+/// getCVRQualifiersThroughArrayTypes - If there are CVR qualifiers for this
+/// type, returns them. Otherwise, if this is an array type, recurses
+/// on the element type until some qualifiers have been found or a non-array
+/// type reached.
+inline unsigned QualType::getCVRQualifiersThroughArrayTypes() const {
+  if (unsigned Quals = getCVRQualifiers())
+    return Quals;
+  QualType CT = getTypePtr()->getCanonicalTypeInternal();
+  if (const ArrayType *AT = dyn_cast<ArrayType>(CT))
+    return AT->getElementType().getCVRQualifiersThroughArrayTypes();
+  return 0;
+}
+
+inline void QualType::removeConst() {
+  removeFastQualifiers(Qualifiers::Const);
+}
+
+inline void QualType::removeRestrict() {
+  removeFastQualifiers(Qualifiers::Restrict);
+}
+
+inline void QualType::removeVolatile() {
+  QualifierCollector Qc;
+  const Type *Ty = Qc.strip(*this);
+  if (Qc.hasVolatile()) {
+    Qc.removeVolatile();
+    *this = Qc.apply(Ty);
+  }
+}
+
+inline void QualType::removeCVRQualifiers(unsigned Mask) {
+  assert(!(Mask & ~Qualifiers::CVRMask) && "mask has non-CVR bits");
+
+  // Fast path: we don't need to touch the slow qualifiers.
+  if (!(Mask & ~Qualifiers::FastMask)) {
+    removeFastQualifiers(Mask);
+    return;
+  }
+
+  QualifierCollector Qc;
+  const Type *Ty = Qc.strip(*this);
+  Qc.removeCVRQualifiers(Mask);
+  *this = Qc.apply(Ty);
+}
+
+/// getAddressSpace - Return the address space of this type.
+inline unsigned QualType::getAddressSpace() const {
+  if (hasLocalNonFastQualifiers()) {
+    const ExtQuals *EQ = getExtQualsUnsafe();
+    if (EQ->hasAddressSpace())
+      return EQ->getAddressSpace();
+  }
+
+  QualType CT = getTypePtr()->getCanonicalTypeInternal();
+  if (CT.hasLocalNonFastQualifiers()) {
+    const ExtQuals *EQ = CT.getExtQualsUnsafe();
+    if (EQ->hasAddressSpace())
+      return EQ->getAddressSpace();
+  }
+
+  if (const ArrayType *AT = dyn_cast<ArrayType>(CT))
+    return AT->getElementType().getAddressSpace();
+  if (const RecordType *RT = dyn_cast<RecordType>(CT))
+    return RT->getAddressSpace();
+  return 0;
+}
+
+/// getObjCGCAttr - Return the gc attribute of this type.
+inline Qualifiers::GC QualType::getObjCGCAttr() const {
+  if (hasLocalNonFastQualifiers()) {
+    const ExtQuals *EQ = getExtQualsUnsafe();
+    if (EQ->hasObjCGCAttr())
+      return EQ->getObjCGCAttr();
+  }
+
+  QualType CT = getTypePtr()->getCanonicalTypeInternal();
+  if (CT.hasLocalNonFastQualifiers()) {
+    const ExtQuals *EQ = CT.getExtQualsUnsafe();
+    if (EQ->hasObjCGCAttr())
+      return EQ->getObjCGCAttr();
+  }
+
+  if (const ArrayType *AT = dyn_cast<ArrayType>(CT))
+      return AT->getElementType().getObjCGCAttr();
+  if (const ObjCObjectPointerType *PT = CT->getAs<ObjCObjectPointerType>())
+    return PT->getPointeeType().getObjCGCAttr();
+  // We most look at all pointer types, not just pointer to interface types.
+  if (const PointerType *PT = CT->getAs<PointerType>())
+    return PT->getPointeeType().getObjCGCAttr();
+  return Qualifiers::GCNone;
+}
+
+inline FunctionType::ExtInfo getFunctionExtInfo(const Type &t) {
+  if (const PointerType *PT = t.getAs<PointerType>()) {
+    if (const FunctionType *FT = PT->getPointeeType()->getAs<FunctionType>())
+      return FT->getExtInfo();
+  } else if (const FunctionType *FT = t.getAs<FunctionType>())
+    return FT->getExtInfo();
+
+  return FunctionType::ExtInfo();
+}
+
+inline FunctionType::ExtInfo getFunctionExtInfo(QualType t) {
+  return getFunctionExtInfo(*t);
+}
+
+/// isMoreQualifiedThan - Determine whether this type is more
+/// qualified than the Other type. For example, "const volatile int"
+/// is more qualified than "const int", "volatile int", and
+/// "int". However, it is not more qualified than "const volatile
+/// int".
+inline bool QualType::isMoreQualifiedThan(QualType Other) const {
+  // FIXME: work on arbitrary qualifiers
+  unsigned MyQuals = this->getCVRQualifiersThroughArrayTypes();
+  unsigned OtherQuals = Other.getCVRQualifiersThroughArrayTypes();
+  if (getAddressSpace() != Other.getAddressSpace())
+    return false;
+  return MyQuals != OtherQuals && (MyQuals | OtherQuals) == MyQuals;
+}
+
+/// isAtLeastAsQualifiedAs - Determine whether this type is at last
+/// as qualified as the Other type. For example, "const volatile
+/// int" is at least as qualified as "const int", "volatile int",
+/// "int", and "const volatile int".
+inline bool QualType::isAtLeastAsQualifiedAs(QualType Other) const {
+  // FIXME: work on arbitrary qualifiers
+  unsigned MyQuals = this->getCVRQualifiersThroughArrayTypes();
+  unsigned OtherQuals = Other.getCVRQualifiersThroughArrayTypes();
+  if (getAddressSpace() != Other.getAddressSpace())
+    return false;
+  return (MyQuals | OtherQuals) == MyQuals;
+}
+
+/// getNonReferenceType - If Type is a reference type (e.g., const
+/// int&), returns the type that the reference refers to ("const
+/// int"). Otherwise, returns the type itself. This routine is used
+/// throughout Sema to implement C++ 5p6:
+///
+///   If an expression initially has the type "reference to T" (8.3.2,
+///   8.5.3), the type is adjusted to "T" prior to any further
+///   analysis, the expression designates the object or function
+///   denoted by the reference, and the expression is an lvalue.
+inline QualType QualType::getNonReferenceType() const {
+  if (const ReferenceType *RefType = (*this)->getAs<ReferenceType>())
+    return RefType->getPointeeType();
+  else
+    return *this;
+}
+
+inline const ObjCInterfaceType *Type::getAsPointerToObjCInterfaceType() const {
+  if (const PointerType *PT = getAs<PointerType>())
+    return PT->getPointeeType()->getAs<ObjCInterfaceType>();
+  return 0;
+}
+
+inline bool Type::isFunctionType() const {
+  return isa<FunctionType>(CanonicalType);
+}
+inline bool Type::isPointerType() const {
+  return isa<PointerType>(CanonicalType);
+}
+inline bool Type::isAnyPointerType() const {
+  return isPointerType() || isObjCObjectPointerType();
+}
+inline bool Type::isBlockPointerType() const {
+  return isa<BlockPointerType>(CanonicalType);
+}
+inline bool Type::isReferenceType() const {
+  return isa<ReferenceType>(CanonicalType);
+}
+inline bool Type::isLValueReferenceType() const {
+  return isa<LValueReferenceType>(CanonicalType);
+}
+inline bool Type::isRValueReferenceType() const {
+  return isa<RValueReferenceType>(CanonicalType);
+}
+inline bool Type::isFunctionPointerType() const {
+  if (const PointerType* T = getAs<PointerType>())
+    return T->getPointeeType()->isFunctionType();
+  else
+    return false;
+}
+inline bool Type::isMemberPointerType() const {
+  return isa<MemberPointerType>(CanonicalType);
+}
+inline bool Type::isMemberFunctionPointerType() const {
+  if (const MemberPointerType* T = getAs<MemberPointerType>())
+    return T->getPointeeType()->isFunctionType();
+  else
+    return false;
+}
+inline bool Type::isArrayType() const {
+  return isa<ArrayType>(CanonicalType);
+}
+inline bool Type::isConstantArrayType() const {
+  return isa<ConstantArrayType>(CanonicalType);
+}
+inline bool Type::isIncompleteArrayType() const {
+  return isa<IncompleteArrayType>(CanonicalType);
+}
+inline bool Type::isVariableArrayType() const {
+  return isa<VariableArrayType>(CanonicalType);
+}
+inline bool Type::isDependentSizedArrayType() const {
+  return isa<DependentSizedArrayType>(CanonicalType);
+}
+inline bool Type::isRecordType() const {
+  return isa<RecordType>(CanonicalType);
+}
+inline bool Type::isAnyComplexType() const {
+  return isa<ComplexType>(CanonicalType);
+}
+inline bool Type::isVectorType() const {
+  return isa<VectorType>(CanonicalType);
+}
+inline bool Type::isExtVectorType() const {
+  return isa<ExtVectorType>(CanonicalType);
+}
+inline bool Type::isObjCObjectPointerType() const {
+  return isa<ObjCObjectPointerType>(CanonicalType);
+}
+inline bool Type::isObjCInterfaceType() const {
+  return isa<ObjCInterfaceType>(CanonicalType);
+}
+inline bool Type::isObjCQualifiedIdType() const {
+  if (const ObjCObjectPointerType *OPT = getAs<ObjCObjectPointerType>())
+    return OPT->isObjCQualifiedIdType();
+  return false;
+}
+inline bool Type::isObjCQualifiedClassType() const {
+  if (const ObjCObjectPointerType *OPT = getAs<ObjCObjectPointerType>())
+    return OPT->isObjCQualifiedClassType();
+  return false;
+}
+inline bool Type::isObjCIdType() const {
+  if (const ObjCObjectPointerType *OPT = getAs<ObjCObjectPointerType>())
+    return OPT->isObjCIdType();
+  return false;
+}
+inline bool Type::isObjCClassType() const {
+  if (const ObjCObjectPointerType *OPT = getAs<ObjCObjectPointerType>())
+    return OPT->isObjCClassType();
+  return false;
+}
+inline bool Type::isObjCSelType() const {
+  if (const PointerType *OPT = getAs<PointerType>())
+    return OPT->getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCSel);
+  return false;
+}
+inline bool Type::isObjCBuiltinType() const {
+  return isObjCIdType() || isObjCClassType() || isObjCSelType();
+}
+inline bool Type::isTemplateTypeParmType() const {
+  return isa<TemplateTypeParmType>(CanonicalType);
+}
+
+inline bool Type::isSpecificBuiltinType(unsigned K) const {
+  if (const BuiltinType *BT = getAs<BuiltinType>())
+    if (BT->getKind() == (BuiltinType::Kind) K)
+      return true;
+  return false;
+}
+
+/// \brief Determines whether this is a type for which one can define
+/// an overloaded operator.
+inline bool Type::isOverloadableType() const {
+  return isDependentType() || isRecordType() || isEnumeralType();
+}
+
+inline bool Type::hasPointerRepresentation() const {
+  return (isPointerType() || isReferenceType() || isBlockPointerType() ||
+          isObjCInterfaceType() || isObjCObjectPointerType() ||
+          isObjCQualifiedInterfaceType() || isNullPtrType());
+}
+
+inline bool Type::hasObjCPointerRepresentation() const {
+  return (isObjCInterfaceType() || isObjCObjectPointerType() ||
+          isObjCQualifiedInterfaceType());
+}
+
+/// Insertion operator for diagnostics.  This allows sending QualType's into a
+/// diagnostic with <<.
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+                                           QualType T) {
+  DB.AddTaggedVal(reinterpret_cast<intptr_t>(T.getAsOpaquePtr()),
+                  Diagnostic::ak_qualtype);
+  return DB;
+}
+
+/// Insertion operator for partial diagnostics.  This allows sending QualType's
+/// into a diagnostic with <<.
+inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
+                                           QualType T) {
+  PD.AddTaggedVal(reinterpret_cast<intptr_t>(T.getAsOpaquePtr()),
+                  Diagnostic::ak_qualtype);
+  return PD;
+}
+
+// Helper class template that is used by Type::getAs to ensure that one does
+// not try to look through a qualified type to get to an array type.
+template<typename T,
+         bool isArrayType = (llvm::is_same<T, ArrayType>::value ||
+                             llvm::is_base_of<ArrayType, T>::value)>
+struct ArrayType_cannot_be_used_with_getAs { };
+  
+template<typename T>
+struct ArrayType_cannot_be_used_with_getAs<T, true>;
+  
+/// Member-template getAs<specific type>'.
+template <typename T> const T *Type::getAs() const {
+  ArrayType_cannot_be_used_with_getAs<T> at;
+  (void)at;
+  
+  // If this is directly a T type, return it.
+  if (const T *Ty = dyn_cast<T>(this))
+    return Ty;
+
+  // If the canonical form of this type isn't the right kind, reject it.
+  if (!isa<T>(CanonicalType))
+    return 0;
+
+  // If this is a typedef for the type, strip the typedef off without
+  // losing all typedef information.
+  return cast<T>(getUnqualifiedDesugaredType());
+}
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h
new file mode 100644
index 0000000..a51da74
--- /dev/null
+++ b/include/clang/AST/TypeLoc.h
@@ -0,0 +1,1252 @@
+//===--- TypeLoc.h - Type Source Info Wrapper -------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the TypeLoc interface and subclasses.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_TYPELOC_H
+#define LLVM_CLANG_AST_TYPELOC_H
+
+#include "clang/AST/Type.h"
+#include "clang/AST/TemplateBase.h"
+#include "clang/Basic/Specifiers.h"
+
+namespace clang {
+  class ParmVarDecl;
+  class TypeSourceInfo;
+  class UnqualTypeLoc;
+
+// Predeclare all the type nodes.
+#define ABSTRACT_TYPELOC(Class, Base)
+#define TYPELOC(Class, Base) \
+  class Class##TypeLoc;
+#include "clang/AST/TypeLocNodes.def"
+
+/// \brief Base wrapper for a particular "section" of type source info.
+///
+/// A client should use the TypeLoc subclasses through cast/dyn_cast in order to
+/// get at the actual information.
+class TypeLoc {
+protected:
+  // The correctness of this relies on the property that, for Type *Ty,
+  //   QualType(Ty, 0).getAsOpaquePtr() == (void*) Ty
+  void *Ty;
+  void *Data;
+
+public:
+  /// The kinds of TypeLocs.  Equivalent to the Type::TypeClass enum,
+  /// except it also defines a Qualified enum that corresponds to the
+  /// QualifiedLoc class.
+  enum TypeLocClass {
+#define ABSTRACT_TYPE(Class, Base)
+#define TYPE(Class, Base) \
+    Class = Type::Class,
+#include "clang/AST/TypeNodes.def"
+    Qualified
+  };
+
+  TypeLoc() : Ty(0), Data(0) { }
+  TypeLoc(QualType ty, void *opaqueData)
+    : Ty(ty.getAsOpaquePtr()), Data(opaqueData) { }
+  TypeLoc(Type *ty, void *opaqueData)
+    : Ty(ty), Data(opaqueData) { }
+
+  TypeLocClass getTypeLocClass() const {
+    if (getType().hasLocalQualifiers()) return Qualified;
+    return (TypeLocClass) getType()->getTypeClass();
+  }
+
+  bool isNull() const { return !Ty; }
+  operator bool() const { return Ty; }
+
+  /// \brief Returns the size of type source info data block for the given type.
+  static unsigned getFullDataSizeForType(QualType Ty);
+
+  /// \brief Get the type for which this source info wrapper provides
+  /// information.
+  QualType getType() const {
+    return QualType::getFromOpaquePtr(Ty);
+  }
+
+  Type *getTypePtr() const {
+    return QualType::getFromOpaquePtr(Ty).getTypePtr();
+  }
+
+  /// \brief Get the pointer where source information is stored.
+  void *getOpaqueData() const {
+    return Data;
+  }
+
+  /// \brief Get the full source range.
+  SourceRange getFullSourceRange() const {
+    SourceLocation End = getSourceRange().getEnd();
+    TypeLoc Cur = *this;
+    while (true) {
+      TypeLoc Next = Cur.getNextTypeLoc();
+      if (Next.isNull()) break;
+      Cur = Next;
+    }
+    return SourceRange(Cur.getSourceRange().getBegin(), End);
+  }
+
+  /// \brief Get the local source range.
+  SourceRange getSourceRange() const {
+    return getSourceRangeImpl(*this);
+  }
+
+  /// \brief Returns the size of the type source info data block.
+  unsigned getFullDataSize() const {
+    return getFullDataSizeForType(getType());
+  }
+
+  /// \brief Get the next TypeLoc pointed by this TypeLoc, e.g for "int*" the
+  /// TypeLoc is a PointerLoc and next TypeLoc is for "int".
+  TypeLoc getNextTypeLoc() const {
+    return getNextTypeLocImpl(*this);
+  }
+
+  /// \brief Skips past any qualifiers, if this is qualified.
+  UnqualTypeLoc getUnqualifiedLoc() const; // implemented in this header
+
+  /// \brief Initializes this to state that every location in this
+  /// type is the given location.
+  ///
+  /// This method exists to provide a simple transition for code that
+  /// relies on location-less types.
+  void initialize(SourceLocation Loc) const {
+    initializeImpl(*this, Loc);
+  }
+
+  friend bool operator==(const TypeLoc &LHS, const TypeLoc &RHS) {
+    return LHS.Ty == RHS.Ty && LHS.Data == RHS.Data;
+  }
+
+  friend bool operator!=(const TypeLoc &LHS, const TypeLoc &RHS) {
+    return !(LHS == RHS);
+  }
+
+  static bool classof(const TypeLoc *TL) { return true; }
+
+private:
+  static void initializeImpl(TypeLoc TL, SourceLocation Loc);
+  static TypeLoc getNextTypeLocImpl(TypeLoc TL);
+  static SourceRange getSourceRangeImpl(TypeLoc TL);
+};
+
+/// \brief Wrapper of type source information for a type with
+/// no direct quqlaifiers.
+class UnqualTypeLoc : public TypeLoc {
+public:
+  UnqualTypeLoc() {}
+  UnqualTypeLoc(Type *Ty, void *Data) : TypeLoc(Ty, Data) {}
+
+  Type *getTypePtr() const {
+    return reinterpret_cast<Type*>(Ty);
+  }
+
+  TypeLocClass getTypeLocClass() const {
+    return (TypeLocClass) getTypePtr()->getTypeClass();
+  }
+
+  static bool classof(const TypeLoc *TL) {
+    return !TL->getType().hasLocalQualifiers();
+  }
+  static bool classof(const UnqualTypeLoc *TL) { return true; }
+};
+
+/// \brief Wrapper of type source information for a type with
+/// non-trivial direct qualifiers.
+///
+/// Currently, we intentionally do not provide source location for
+/// type qualifiers.
+class QualifiedTypeLoc : public TypeLoc {
+public:
+  SourceRange getSourceRange() const {
+    return SourceRange();
+  }
+
+  UnqualTypeLoc getUnqualifiedLoc() const {
+    return UnqualTypeLoc(getTypePtr(), Data);
+  }
+
+  /// Initializes the local data of this type source info block to
+  /// provide no information.
+  void initializeLocal(SourceLocation Loc) {
+    // do nothing
+  }
+
+  TypeLoc getNextTypeLoc() const {
+    return getUnqualifiedLoc();
+  }
+
+  /// \brief Returns the size of the type source info data block that is
+  /// specific to this type.
+  unsigned getLocalDataSize() const {
+    // In fact, we don't currently preserve any location information
+    // for qualifiers.
+    return 0;
+  }
+
+  /// \brief Returns the size of the type source info data block.
+  unsigned getFullDataSize() const {
+    return getLocalDataSize() + 
+      getFullDataSizeForType(getType().getLocalUnqualifiedType());
+  }
+
+  static bool classof(const TypeLoc *TL) {
+    return TL->getType().hasLocalQualifiers();
+  }
+  static bool classof(const QualifiedTypeLoc *TL) { return true; }
+};
+
+inline UnqualTypeLoc TypeLoc::getUnqualifiedLoc() const {
+  if (isa<QualifiedTypeLoc>(this))
+    return cast<QualifiedTypeLoc>(this)->getUnqualifiedLoc();
+  return cast<UnqualTypeLoc>(*this);
+}
+
+/// A metaprogramming base class for TypeLoc classes which correspond
+/// to a particular Type subclass.  It is accepted for a single
+/// TypeLoc class to correspond to multiple Type classes.
+///
+/// \param Base a class from which to derive
+/// \param Derived the class deriving from this one
+/// \param TypeClass the concrete Type subclass associated with this
+///   location type
+/// \param LocalData the structure type of local location data for
+///   this type
+///
+/// sizeof(LocalData) needs to be a multiple of sizeof(void*) or
+/// else the world will end.
+///
+/// TypeLocs with non-constant amounts of local data should override
+/// getExtraLocalDataSize(); getExtraLocalData() will then point to
+/// this extra memory.
+///
+/// TypeLocs with an inner type should define
+///   QualType getInnerType() const
+/// and getInnerTypeLoc() will then point to this inner type's
+/// location data.
+///
+/// A word about hierarchies: this template is not designed to be
+/// derived from multiple times in a hierarchy.  It is also not
+/// designed to be used for classes where subtypes might provide
+/// different amounts of source information.  It should be subclassed
+/// only at the deepest portion of the hierarchy where all children
+/// have identical source information; if that's an abstract type,
+/// then further descendents should inherit from
+/// InheritingConcreteTypeLoc instead.
+template <class Base, class Derived, class TypeClass, class LocalData>
+class ConcreteTypeLoc : public Base {
+
+  const Derived *asDerived() const {
+    return static_cast<const Derived*>(this);
+  }
+
+public:
+  unsigned getLocalDataSize() const {
+    return sizeof(LocalData) + asDerived()->getExtraLocalDataSize();
+  }
+  // Give a default implementation that's useful for leaf types.
+  unsigned getFullDataSize() const {
+    return asDerived()->getLocalDataSize() + getInnerTypeSize();
+  }
+
+  static bool classofType(const Type *Ty) {
+    return TypeClass::classof(Ty);
+  }
+
+  TypeLoc getNextTypeLoc() const {
+    return getNextTypeLoc(asDerived()->getInnerType());
+  }
+
+  TypeClass *getTypePtr() const {
+    return cast<TypeClass>(Base::getTypePtr());
+  }
+
+protected:
+  unsigned getExtraLocalDataSize() const {
+    return 0;
+  }
+
+  LocalData *getLocalData() const {
+    return static_cast<LocalData*>(Base::Data);
+  }
+
+  /// Gets a pointer past the Info structure; useful for classes with
+  /// local data that can't be captured in the Info (e.g. because it's
+  /// of variable size).
+  void *getExtraLocalData() const {
+    return getLocalData() + 1;
+  }
+  
+  void *getNonLocalData() const {
+    return static_cast<char*>(Base::Data) + asDerived()->getLocalDataSize();
+  }
+
+  struct HasNoInnerType {};
+  HasNoInnerType getInnerType() const { return HasNoInnerType(); }
+
+  TypeLoc getInnerTypeLoc() const {
+    return TypeLoc(asDerived()->getInnerType(), getNonLocalData());
+  }
+
+private:
+  unsigned getInnerTypeSize() const {
+    return getInnerTypeSize(asDerived()->getInnerType());
+  }
+
+  unsigned getInnerTypeSize(HasNoInnerType _) const {
+    return 0;
+  }
+
+  unsigned getInnerTypeSize(QualType _) const {
+    return getInnerTypeLoc().getFullDataSize();
+  }
+
+  TypeLoc getNextTypeLoc(HasNoInnerType _) const {
+    return TypeLoc();
+  }
+
+  TypeLoc getNextTypeLoc(QualType T) const {
+    return TypeLoc(T, getNonLocalData());
+  }
+};
+
+/// A metaprogramming class designed for concrete subtypes of abstract
+/// types where all subtypes share equivalently-structured source
+/// information.  See the note on ConcreteTypeLoc.
+template <class Base, class Derived, class TypeClass>
+class InheritingConcreteTypeLoc : public Base {
+public:
+  static bool classof(const TypeLoc *TL) {
+    return Derived::classofType(TL->getTypePtr());
+  }
+  static bool classof(const UnqualTypeLoc *TL) {
+    return Derived::classofType(TL->getTypePtr());
+  }
+  static bool classof(const Derived *TL) {
+    return true;
+  }
+
+  TypeClass *getTypePtr() const {
+    return cast<TypeClass>(Base::getTypePtr());
+  }
+};
+
+
+struct TypeSpecLocInfo {
+  SourceLocation NameLoc;
+};
+
+/// \brief A reasonable base class for TypeLocs that correspond to
+/// types that are written as a type-specifier.
+class TypeSpecTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 
+                                               TypeSpecTypeLoc,
+                                               Type,
+                                               TypeSpecLocInfo> {
+public:
+  enum { LocalDataSize = sizeof(TypeSpecLocInfo) };
+
+  SourceLocation getNameLoc() const {
+    return this->getLocalData()->NameLoc;
+  }
+  void setNameLoc(SourceLocation Loc) {
+    this->getLocalData()->NameLoc = Loc;
+  }
+  SourceRange getSourceRange() const {
+    return SourceRange(getNameLoc(), getNameLoc());
+  }
+  void initializeLocal(SourceLocation Loc) {
+    setNameLoc(Loc);
+  }
+
+  static bool classof(const TypeLoc *TL);
+  static bool classof(const TypeSpecTypeLoc *TL) { return true; }
+};
+
+
+struct BuiltinLocInfo {
+  SourceLocation BuiltinLoc;
+};
+
+/// \brief Wrapper for source info for builtin types.
+class BuiltinTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
+                                              BuiltinTypeLoc,
+                                              BuiltinType,
+                                              BuiltinLocInfo> {
+public:
+  enum { LocalDataSize = sizeof(BuiltinLocInfo) };
+
+  SourceLocation getBuiltinLoc() const {
+    return getLocalData()->BuiltinLoc;
+  }
+  void setBuiltinLoc(SourceLocation Loc) {
+    getLocalData()->BuiltinLoc = Loc;
+  }
+
+  SourceLocation getNameLoc() const { return getBuiltinLoc(); }
+
+  WrittenBuiltinSpecs& getWrittenBuiltinSpecs() {
+    return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData()));
+  }
+  const WrittenBuiltinSpecs& getWrittenBuiltinSpecs() const {
+    return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData()));
+  }
+
+  bool needsExtraLocalData() const {
+    BuiltinType::Kind bk = getTypePtr()->getKind();
+    return (bk >= BuiltinType::UShort && bk <= BuiltinType::UInt128)
+      || (bk >= BuiltinType::Short && bk <= BuiltinType::LongDouble)
+      || bk == BuiltinType::UChar
+      || bk == BuiltinType::SChar;
+  }
+
+  unsigned getExtraLocalDataSize() const {
+    return needsExtraLocalData() ? sizeof(WrittenBuiltinSpecs) : 0;
+  }
+
+  SourceRange getSourceRange() const {
+    return SourceRange(getBuiltinLoc(), getBuiltinLoc());
+  }
+
+  TypeSpecifierSign getWrittenSignSpec() const {
+    if (needsExtraLocalData())
+      return static_cast<TypeSpecifierSign>(getWrittenBuiltinSpecs().Sign);
+    else
+      return TSS_unspecified;
+  }
+  bool hasWrittenSignSpec() const {
+    return getWrittenSignSpec() != TSS_unspecified;
+  }
+  void setWrittenSignSpec(TypeSpecifierSign written) {
+    if (needsExtraLocalData())
+      getWrittenBuiltinSpecs().Sign = written;
+  }
+
+  TypeSpecifierWidth getWrittenWidthSpec() const {
+    if (needsExtraLocalData())
+      return static_cast<TypeSpecifierWidth>(getWrittenBuiltinSpecs().Width);
+    else
+      return TSW_unspecified;
+  }
+  bool hasWrittenWidthSpec() const {
+    return getWrittenWidthSpec() != TSW_unspecified;
+  }
+  void setWrittenWidthSpec(TypeSpecifierWidth written) {
+    if (needsExtraLocalData())
+      getWrittenBuiltinSpecs().Width = written;
+  }
+
+  TypeSpecifierType getWrittenTypeSpec() const;
+  bool hasWrittenTypeSpec() const {
+    return getWrittenTypeSpec() != TST_unspecified;
+  }
+  void setWrittenTypeSpec(TypeSpecifierType written) {
+    if (needsExtraLocalData())
+      getWrittenBuiltinSpecs().Type = written;
+  }
+
+  bool hasModeAttr() const {
+    if (needsExtraLocalData())
+      return getWrittenBuiltinSpecs().ModeAttr;
+    else
+      return false;
+  }
+  void setModeAttr(bool written) {
+    if (needsExtraLocalData())
+      getWrittenBuiltinSpecs().ModeAttr = written;
+  }
+
+  void initializeLocal(SourceLocation Loc) {
+    setBuiltinLoc(Loc);
+    if (needsExtraLocalData()) {
+      WrittenBuiltinSpecs &wbs = getWrittenBuiltinSpecs();
+      wbs.Sign = TSS_unspecified;
+      wbs.Width = TSW_unspecified;
+      wbs.Type = TST_unspecified;
+      wbs.ModeAttr = false;
+    }
+  }
+};
+
+
+/// \brief Wrapper for source info for typedefs.
+class TypedefTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
+                                                        TypedefTypeLoc,
+                                                        TypedefType> {
+public:
+  TypedefDecl *getTypedefDecl() const {
+    return getTypePtr()->getDecl();
+  }
+};
+
+/// \brief Wrapper for source info for injected class names of class
+/// templates.
+class InjectedClassNameTypeLoc :
+    public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
+                                     InjectedClassNameTypeLoc,
+                                     InjectedClassNameType> {
+};
+
+/// \brief Wrapper for source info for unresolved typename using decls.
+class UnresolvedUsingTypeLoc :
+    public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
+                                     UnresolvedUsingTypeLoc,
+                                     UnresolvedUsingType> {
+public:
+  UnresolvedUsingTypenameDecl *getDecl() const {
+    return getTypePtr()->getDecl();
+  }
+};
+
+/// \brief Wrapper for source info for tag types.  Note that this only
+/// records source info for the name itself; a type written 'struct foo'
+/// should be represented as an ElaboratedTypeLoc.  We currently
+/// only do that when C++ is enabled because of the expense of
+/// creating an ElaboratedType node for so many type references in C.
+class TagTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
+                                                    TagTypeLoc,
+                                                    TagType> {
+public:
+  TagDecl *getDecl() const { return getTypePtr()->getDecl(); }
+};
+
+/// \brief Wrapper for source info for record types.
+class RecordTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
+                                                       RecordTypeLoc,
+                                                       RecordType> {
+public:
+  RecordDecl *getDecl() const { return getTypePtr()->getDecl(); }
+};
+
+/// \brief Wrapper for source info for enum types.
+class EnumTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
+                                                     EnumTypeLoc,
+                                                     EnumType> {
+public:
+  EnumDecl *getDecl() const { return getTypePtr()->getDecl(); }
+};
+
+/// \brief Wrapper for template type parameters.
+class TemplateTypeParmTypeLoc :
+    public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
+                                     TemplateTypeParmTypeLoc,
+                                     TemplateTypeParmType> {
+};
+
+/// \brief Wrapper for substituted template type parameters.
+class SubstTemplateTypeParmTypeLoc :
+    public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
+                                     SubstTemplateTypeParmTypeLoc,
+                                     SubstTemplateTypeParmType> {
+};
+
+
+struct ObjCProtocolListLocInfo {
+  SourceLocation LAngleLoc;
+  SourceLocation RAngleLoc;
+};
+
+// A helper class for defining ObjC TypeLocs that can qualified with
+// protocols.
+//
+// TypeClass basically has to be either ObjCInterfaceType or
+// ObjCObjectPointerType.
+template <class Derived, class TypeClass, class LocalData>
+class ObjCProtocolListTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
+                                                       Derived,
+                                                       TypeClass,
+                                                       LocalData> {
+  // SourceLocations are stored after Info, one for each Protocol.
+  SourceLocation *getProtocolLocArray() const {
+    return (SourceLocation*) this->getExtraLocalData();
+  }
+
+protected:
+  void initializeLocalBase(SourceLocation Loc) {
+    setLAngleLoc(Loc);
+    setRAngleLoc(Loc);
+    for (unsigned i = 0, e = getNumProtocols(); i != e; ++i)
+      setProtocolLoc(i, Loc);
+  }
+
+public:
+  SourceLocation getLAngleLoc() const {
+    return this->getLocalData()->LAngleLoc;
+  }
+  void setLAngleLoc(SourceLocation Loc) {
+    this->getLocalData()->LAngleLoc = Loc;
+  }
+
+  SourceLocation getRAngleLoc() const {
+    return this->getLocalData()->RAngleLoc;
+  }
+  void setRAngleLoc(SourceLocation Loc) {
+    this->getLocalData()->RAngleLoc = Loc;
+  }
+
+  unsigned getNumProtocols() const {
+    return this->getTypePtr()->getNumProtocols();
+  }
+
+  SourceLocation getProtocolLoc(unsigned i) const {
+    assert(i < getNumProtocols() && "Index is out of bounds!");
+    return getProtocolLocArray()[i];
+  }
+  void setProtocolLoc(unsigned i, SourceLocation Loc) {
+    assert(i < getNumProtocols() && "Index is out of bounds!");
+    getProtocolLocArray()[i] = Loc;
+  }
+
+  ObjCProtocolDecl *getProtocol(unsigned i) const {
+    assert(i < getNumProtocols() && "Index is out of bounds!");
+    return *(this->getTypePtr()->qual_begin() + i);
+  }
+  
+  SourceRange getSourceRange() const {
+    return SourceRange(getLAngleLoc(), getRAngleLoc());
+  }
+
+  void initializeLocal(SourceLocation Loc) {
+    initializeLocalBase(Loc);
+  }
+
+  unsigned getExtraLocalDataSize() const {
+    return this->getNumProtocols() * sizeof(SourceLocation);
+  }
+};
+
+
+struct ObjCInterfaceLocInfo : ObjCProtocolListLocInfo {
+  SourceLocation NameLoc;
+};
+
+/// \brief Wrapper for source info for ObjC interfaces.
+class ObjCInterfaceTypeLoc :
+    public ObjCProtocolListTypeLoc<ObjCInterfaceTypeLoc,
+                                   ObjCInterfaceType,
+                                   ObjCInterfaceLocInfo> {
+public:
+  ObjCInterfaceDecl *getIFaceDecl() const {
+    return getTypePtr()->getDecl();
+  }
+
+  SourceLocation getNameLoc() const {
+    return getLocalData()->NameLoc;
+  }
+
+  void setNameLoc(SourceLocation Loc) {
+    getLocalData()->NameLoc = Loc;
+  }
+
+  SourceRange getSourceRange() const {
+    if (getNumProtocols()) 
+      return SourceRange(getNameLoc(), getRAngleLoc());
+    else
+      return SourceRange(getNameLoc(), getNameLoc());
+  }
+
+  void initializeLocal(SourceLocation Loc) {
+    initializeLocalBase(Loc);
+    setNameLoc(Loc);
+  }
+};
+
+
+struct ObjCObjectPointerLocInfo : ObjCProtocolListLocInfo {
+  SourceLocation StarLoc;
+  bool HasProtocols;
+  bool HasBaseType;
+};
+
+/// Wraps an ObjCPointerType with source location information.  Note
+/// that not all ObjCPointerTypes actually have a star location; nor
+/// are protocol locations necessarily written in the source just
+/// because they're present on the type.
+class ObjCObjectPointerTypeLoc :
+    public ObjCProtocolListTypeLoc<ObjCObjectPointerTypeLoc,
+                                   ObjCObjectPointerType,
+                                   ObjCObjectPointerLocInfo> {
+public:
+  bool hasProtocolsAsWritten() const {
+    return getLocalData()->HasProtocols;
+  }
+
+  void setHasProtocolsAsWritten(bool HasProtocols) {
+    getLocalData()->HasProtocols = HasProtocols;
+  }
+
+  bool hasBaseTypeAsWritten() const {
+    return getLocalData()->HasBaseType;
+  }
+
+  void setHasBaseTypeAsWritten(bool HasBaseType) {
+    getLocalData()->HasBaseType = HasBaseType;
+  }
+
+  SourceLocation getStarLoc() const {
+    return getLocalData()->StarLoc;
+  }
+
+  void setStarLoc(SourceLocation Loc) {
+    getLocalData()->StarLoc = Loc;
+  }
+
+  SourceRange getSourceRange() const {
+    // Being written with protocols is incompatible with being written
+    // with a star.
+    if (hasProtocolsAsWritten())
+      return SourceRange(getLAngleLoc(), getRAngleLoc());
+    else
+      return SourceRange(getStarLoc(), getStarLoc());
+  }
+
+  void initializeLocal(SourceLocation Loc) {
+    initializeLocalBase(Loc);
+    setHasProtocolsAsWritten(false);
+    setHasBaseTypeAsWritten(false);
+    setStarLoc(Loc);
+  }
+
+  TypeLoc getBaseTypeLoc() const {
+    return getInnerTypeLoc();
+  }
+
+  QualType getInnerType() const {
+    return getTypePtr()->getPointeeType();
+  }
+};
+
+
+struct PointerLikeLocInfo {
+  SourceLocation StarLoc;
+};
+
+/// A base class for 
+template <class Derived, class TypeClass, class LocalData = PointerLikeLocInfo>
+class PointerLikeTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, Derived,
+                                                  TypeClass, LocalData> {
+public:  
+  SourceLocation getSigilLoc() const {
+    return this->getLocalData()->StarLoc;
+  }
+  void setSigilLoc(SourceLocation Loc) {
+    this->getLocalData()->StarLoc = Loc;
+  }
+
+  TypeLoc getPointeeLoc() const {
+    return this->getInnerTypeLoc();
+  }
+
+  SourceRange getSourceRange() const {
+    return SourceRange(getSigilLoc(), getSigilLoc());
+  }
+
+  void initializeLocal(SourceLocation Loc) {
+    setSigilLoc(Loc);
+  }
+
+  QualType getInnerType() const {
+    return this->getTypePtr()->getPointeeType();
+  }
+};
+
+
+/// \brief Wrapper for source info for pointers.
+class PointerTypeLoc : public PointerLikeTypeLoc<PointerTypeLoc,
+                                                 PointerType> {
+public:
+  SourceLocation getStarLoc() const {
+    return getSigilLoc();
+  }
+  void setStarLoc(SourceLocation Loc) {
+    setSigilLoc(Loc);
+  }
+};
+
+
+/// \brief Wrapper for source info for block pointers.
+class BlockPointerTypeLoc : public PointerLikeTypeLoc<BlockPointerTypeLoc,
+                                                      BlockPointerType> {
+public:
+  SourceLocation getCaretLoc() const {
+    return getSigilLoc();
+  }
+  void setCaretLoc(SourceLocation Loc) {
+    setSigilLoc(Loc);
+  }
+};
+
+
+/// \brief Wrapper for source info for member pointers.
+class MemberPointerTypeLoc : public PointerLikeTypeLoc<MemberPointerTypeLoc,
+                                                       MemberPointerType> {
+public:
+  SourceLocation getStarLoc() const {
+    return getSigilLoc();
+  }
+  void setStarLoc(SourceLocation Loc) {
+    setSigilLoc(Loc);
+  }
+};
+
+
+class ReferenceTypeLoc : public PointerLikeTypeLoc<ReferenceTypeLoc,
+                                                   ReferenceType> {
+public:
+  QualType getInnerType() const {
+    return getTypePtr()->getPointeeTypeAsWritten();
+  }
+};
+
+class LValueReferenceTypeLoc :
+    public InheritingConcreteTypeLoc<ReferenceTypeLoc,
+                                     LValueReferenceTypeLoc,
+                                     LValueReferenceType> {
+public:
+  SourceLocation getAmpLoc() const {
+    return getSigilLoc();
+  }
+  void setAmpLoc(SourceLocation Loc) {
+    setSigilLoc(Loc);
+  }
+};
+
+class RValueReferenceTypeLoc :
+    public InheritingConcreteTypeLoc<ReferenceTypeLoc,
+                                     RValueReferenceTypeLoc,
+                                     RValueReferenceType> {
+public:
+  SourceLocation getAmpAmpLoc() const {
+    return getSigilLoc();
+  }
+  void setAmpAmpLoc(SourceLocation Loc) {
+    setSigilLoc(Loc);
+  }
+};
+
+
+struct FunctionLocInfo {
+  SourceLocation LParenLoc, RParenLoc;
+};
+
+/// \brief Wrapper for source info for functions.
+class FunctionTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
+                                               FunctionTypeLoc,
+                                               FunctionType,
+                                               FunctionLocInfo> {
+  // ParmVarDecls* are stored after Info, one for each argument.
+  ParmVarDecl **getParmArray() const {
+    return (ParmVarDecl**) getExtraLocalData();
+  }
+
+public:
+  SourceLocation getLParenLoc() const {
+    return getLocalData()->LParenLoc;
+  }
+  void setLParenLoc(SourceLocation Loc) {
+    getLocalData()->LParenLoc = Loc;
+  }
+
+  SourceLocation getRParenLoc() const {
+    return getLocalData()->RParenLoc;
+  }
+  void setRParenLoc(SourceLocation Loc) {
+    getLocalData()->RParenLoc = Loc;
+  }
+
+  unsigned getNumArgs() const {
+    if (isa<FunctionNoProtoType>(getTypePtr()))
+      return 0;
+    return cast<FunctionProtoType>(getTypePtr())->getNumArgs();
+  }
+  ParmVarDecl *getArg(unsigned i) const { return getParmArray()[i]; }
+  void setArg(unsigned i, ParmVarDecl *VD) { getParmArray()[i] = VD; }
+
+  TypeLoc getArgLoc(unsigned i) const;
+
+  TypeLoc getResultLoc() const {
+    return getInnerTypeLoc();
+  }
+
+  SourceRange getSourceRange() const {
+    return SourceRange(getLParenLoc(), getRParenLoc());
+  }
+
+  void initializeLocal(SourceLocation Loc) {
+    setLParenLoc(Loc);
+    setRParenLoc(Loc);
+    for (unsigned i = 0, e = getNumArgs(); i != e; ++i)
+      setArg(i, NULL);
+  }
+
+  /// \brief Returns the size of the type source info data block that is
+  /// specific to this type.
+  unsigned getExtraLocalDataSize() const {
+    return getNumArgs() * sizeof(ParmVarDecl*);
+  }
+
+  QualType getInnerType() const { return getTypePtr()->getResultType(); }
+};
+
+class FunctionProtoTypeLoc :
+    public InheritingConcreteTypeLoc<FunctionTypeLoc,
+                                     FunctionProtoTypeLoc,
+                                     FunctionProtoType> {
+};
+
+class FunctionNoProtoTypeLoc :
+    public InheritingConcreteTypeLoc<FunctionTypeLoc,
+                                     FunctionNoProtoTypeLoc,
+                                     FunctionNoProtoType> {
+};
+
+
+struct ArrayLocInfo {
+  SourceLocation LBracketLoc, RBracketLoc;
+  Expr *Size;
+};
+
+/// \brief Wrapper for source info for arrays.
+class ArrayTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
+                                            ArrayTypeLoc,
+                                            ArrayType,
+                                            ArrayLocInfo> {
+public:
+  SourceLocation getLBracketLoc() const {
+    return getLocalData()->LBracketLoc;
+  }
+  void setLBracketLoc(SourceLocation Loc) {
+    getLocalData()->LBracketLoc = Loc;
+  }
+
+  SourceLocation getRBracketLoc() const {
+    return getLocalData()->RBracketLoc;
+  }
+  void setRBracketLoc(SourceLocation Loc) {
+    getLocalData()->RBracketLoc = Loc;
+  }
+
+  SourceRange getBracketsRange() const {
+    return SourceRange(getLBracketLoc(), getRBracketLoc());
+  }
+
+  Expr *getSizeExpr() const {
+    return getLocalData()->Size;
+  }
+  void setSizeExpr(Expr *Size) {
+    getLocalData()->Size = Size;
+  }
+
+  TypeLoc getElementLoc() const {
+    return getInnerTypeLoc();
+  }
+
+  SourceRange getSourceRange() const {
+    return SourceRange(getLBracketLoc(), getRBracketLoc());
+  }
+
+  void initializeLocal(SourceLocation Loc) {
+    setLBracketLoc(Loc);
+    setRBracketLoc(Loc);
+    setSizeExpr(NULL);
+  }
+
+  QualType getInnerType() const { return getTypePtr()->getElementType(); }
+};
+
+class ConstantArrayTypeLoc :
+    public InheritingConcreteTypeLoc<ArrayTypeLoc,
+                                     ConstantArrayTypeLoc,
+                                     ConstantArrayType> {
+};
+
+class IncompleteArrayTypeLoc :
+    public InheritingConcreteTypeLoc<ArrayTypeLoc,
+                                     IncompleteArrayTypeLoc,
+                                     IncompleteArrayType> {
+};
+
+class DependentSizedArrayTypeLoc :
+    public InheritingConcreteTypeLoc<ArrayTypeLoc,
+                                     DependentSizedArrayTypeLoc,
+                                     DependentSizedArrayType> {
+
+};
+
+class VariableArrayTypeLoc :
+    public InheritingConcreteTypeLoc<ArrayTypeLoc,
+                                     VariableArrayTypeLoc,
+                                     VariableArrayType> {
+};
+
+
+// Location information for a TemplateName.  Rudimentary for now.
+struct TemplateNameLocInfo {
+  SourceLocation NameLoc;
+};
+
+struct TemplateSpecializationLocInfo : TemplateNameLocInfo {
+  SourceLocation LAngleLoc;
+  SourceLocation RAngleLoc;
+};
+
+class TemplateSpecializationTypeLoc :
+    public ConcreteTypeLoc<UnqualTypeLoc,
+                           TemplateSpecializationTypeLoc,
+                           TemplateSpecializationType,
+                           TemplateSpecializationLocInfo> {
+public:
+  SourceLocation getLAngleLoc() const {
+    return getLocalData()->LAngleLoc;
+  }
+  void setLAngleLoc(SourceLocation Loc) {
+    getLocalData()->LAngleLoc = Loc;
+  }
+
+  SourceLocation getRAngleLoc() const {
+    return getLocalData()->RAngleLoc;
+  }
+  void setRAngleLoc(SourceLocation Loc) {
+    getLocalData()->RAngleLoc = Loc;
+  }
+
+  unsigned getNumArgs() const {
+    return getTypePtr()->getNumArgs();
+  }
+  void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
+#ifndef NDEBUG
+    AI.validateForArgument(getTypePtr()->getArg(i));
+#endif
+    getArgInfos()[i] = AI;
+  }
+  TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
+    return getArgInfos()[i];
+  }
+
+  TemplateArgumentLoc getArgLoc(unsigned i) const {
+    return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
+  }
+
+  SourceLocation getTemplateNameLoc() const {
+    return getLocalData()->NameLoc;
+  }
+  void setTemplateNameLoc(SourceLocation Loc) {
+    getLocalData()->NameLoc = Loc;
+  }
+
+  /// \brief - Copy the location information from the given info.
+  void copy(TemplateSpecializationTypeLoc Loc) {
+    unsigned size = getFullDataSize();
+    assert(size == Loc.getFullDataSize());
+
+    // We're potentially copying Expr references here.  We don't
+    // bother retaining them because TypeSourceInfos live forever, so
+    // as long as the Expr was retained when originally written into
+    // the TypeLoc, we're okay.
+    memcpy(Data, Loc.Data, size);
+  }
+
+  SourceRange getSourceRange() const {
+    return SourceRange(getTemplateNameLoc(), getRAngleLoc());
+  }
+
+  void initializeLocal(SourceLocation Loc) {
+    setLAngleLoc(Loc);
+    setRAngleLoc(Loc);
+    setTemplateNameLoc(Loc);
+
+    for (unsigned i = 0, e = getNumArgs(); i != e; ++i) {
+      TemplateArgumentLocInfo Info;
+#ifndef NDEBUG
+      // If asserts are enabled, be sure to initialize the argument
+      // loc with the right kind of pointer.
+      switch (getTypePtr()->getArg(i).getKind()) {
+      case TemplateArgument::Expression:
+      case TemplateArgument::Declaration:
+        Info = TemplateArgumentLocInfo((Expr*) 0);
+        break;
+
+      case TemplateArgument::Type:
+        Info = TemplateArgumentLocInfo((TypeSourceInfo*) 0);
+        break;
+
+      case TemplateArgument::Template:
+        Info = TemplateArgumentLocInfo(SourceRange(), SourceLocation());
+        break;
+          
+      case TemplateArgument::Integral:
+      case TemplateArgument::Pack:
+      case TemplateArgument::Null:
+        // K_None is fine.
+        break;
+      }
+#endif
+      getArgInfos()[i] = Info;
+    }
+  }
+
+  unsigned getExtraLocalDataSize() const {
+    return getNumArgs() * sizeof(TemplateArgumentLocInfo);
+  }
+
+private:
+  TemplateArgumentLocInfo *getArgInfos() const {
+    return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
+  }
+};
+
+//===----------------------------------------------------------------------===//
+//
+//  All of these need proper implementations.
+//
+//===----------------------------------------------------------------------===//
+
+// FIXME: size expression and attribute locations (or keyword if we
+// ever fully support altivec syntax).
+class VectorTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
+                                                       VectorTypeLoc,
+                                                       VectorType> {
+};
+
+// FIXME: size expression and attribute locations.
+class ExtVectorTypeLoc : public InheritingConcreteTypeLoc<VectorTypeLoc,
+                                                          ExtVectorTypeLoc,
+                                                          ExtVectorType> {
+};
+
+// FIXME: attribute locations.
+// For some reason, this isn't a subtype of VectorType.
+class DependentSizedExtVectorTypeLoc :
+    public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
+                                     DependentSizedExtVectorTypeLoc,
+                                     DependentSizedExtVectorType> {
+};
+
+// FIXME: location of the '_Complex' keyword.
+class ComplexTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
+                                                        ComplexTypeLoc,
+                                                        ComplexType> {
+};
+
+struct TypeofLocInfo {
+  SourceLocation TypeofLoc;
+  SourceLocation LParenLoc;
+  SourceLocation RParenLoc;
+};
+
+struct TypeOfExprTypeLocInfo : public TypeofLocInfo {
+};
+
+struct TypeOfTypeLocInfo : public TypeofLocInfo {
+  TypeSourceInfo* UnderlyingTInfo;
+};
+
+template <class Derived, class TypeClass, class LocalData = TypeofLocInfo>
+class TypeofLikeTypeLoc
+  : public ConcreteTypeLoc<UnqualTypeLoc, Derived, TypeClass, LocalData> {
+public:
+  SourceLocation getTypeofLoc() const {
+    return this->getLocalData()->TypeofLoc;
+  }
+  void setTypeofLoc(SourceLocation Loc) {
+    this->getLocalData()->TypeofLoc = Loc;
+  }
+
+  SourceLocation getLParenLoc() const {
+    return this->getLocalData()->LParenLoc;
+  }
+  void setLParenLoc(SourceLocation Loc) {
+    this->getLocalData()->LParenLoc = Loc;
+  }
+
+  SourceLocation getRParenLoc() const {
+    return this->getLocalData()->RParenLoc;
+  }
+  void setRParenLoc(SourceLocation Loc) {
+    this->getLocalData()->RParenLoc = Loc;
+  }
+
+  SourceRange getParensRange() const {
+    return SourceRange(getLParenLoc(), getRParenLoc());
+  }
+  void setParensRange(SourceRange range) {
+      setLParenLoc(range.getBegin());
+      setRParenLoc(range.getEnd());
+  }
+
+  SourceRange getSourceRange() const {
+    return SourceRange(getTypeofLoc(), getRParenLoc());
+  }
+
+  void initializeLocal(SourceLocation Loc) {
+    setTypeofLoc(Loc);
+    setLParenLoc(Loc);
+    setRParenLoc(Loc);
+  }
+};
+
+class TypeOfExprTypeLoc : public TypeofLikeTypeLoc<TypeOfExprTypeLoc,
+                                                   TypeOfExprType,
+                                                   TypeOfExprTypeLocInfo> {
+public:
+  Expr* getUnderlyingExpr() const {
+    return getTypePtr()->getUnderlyingExpr();
+  }
+  // Reimplemented to account for GNU/C++ extension
+  //     typeof unary-expression
+  // where there are no parentheses.
+  SourceRange getSourceRange() const;
+};
+
+class TypeOfTypeLoc
+  : public TypeofLikeTypeLoc<TypeOfTypeLoc, TypeOfType, TypeOfTypeLocInfo> {
+public:
+  QualType getUnderlyingType() const {
+    return this->getTypePtr()->getUnderlyingType();
+  }
+  TypeSourceInfo* getUnderlyingTInfo() const {
+    return this->getLocalData()->UnderlyingTInfo;
+  }
+  void setUnderlyingTInfo(TypeSourceInfo* TI) const {
+    this->getLocalData()->UnderlyingTInfo = TI;
+  }
+};
+
+// FIXME: location of the 'decltype' and parens.
+class DecltypeTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
+                                                         DecltypeTypeLoc,
+                                                         DecltypeType> {
+};
+
+// FIXME: location of the tag keyword.
+class ElaboratedTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
+                                                           ElaboratedTypeLoc,
+                                                           ElaboratedType> {
+};
+
+// FIXME: locations for the nested name specifier;  at the very least,
+// a SourceRange.
+class QualifiedNameTypeLoc :
+    public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
+                                     QualifiedNameTypeLoc,
+                                     QualifiedNameType> {
+};
+
+// FIXME: locations for the typename keyword and nested name specifier.
+class DependentNameTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
+                                                         DependentNameTypeLoc,
+                                                         DependentNameType> {
+};
+
+}
+
+#endif
diff --git a/include/clang/AST/TypeLocBuilder.h b/include/clang/AST/TypeLocBuilder.h
new file mode 100644
index 0000000..c3b1c68
--- /dev/null
+++ b/include/clang/AST/TypeLocBuilder.h
@@ -0,0 +1,134 @@
+//===--- TypeLocBuilder.h - Type Source Info collector ----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This files defines TypeLocBuilder, a class for building TypeLocs
+//  bottom-up.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_TYPELOCBUILDER_H
+#define LLVM_CLANG_AST_TYPELOCBUILDER_H
+
+#include "clang/AST/TypeLoc.h"
+#include "llvm/ADT/SmallVector.h"
+#include "clang/AST/ASTContext.h"
+
+namespace clang {
+
+class TypeLocBuilder {
+  enum { InlineCapacity = 8 * sizeof(SourceLocation) };
+
+  /// The underlying location-data buffer.  Data grows from the end
+  /// of the buffer backwards.
+  char *Buffer;
+
+  /// The capacity of the current buffer.
+  size_t Capacity;
+
+  /// The index of the first occupied byte in the buffer.
+  size_t Index;
+
+#ifndef NDEBUG
+  /// The last type pushed on this builder.
+  QualType LastTy;
+#endif
+    
+  /// The inline buffer.
+  char InlineBuffer[InlineCapacity];
+
+ public:
+  TypeLocBuilder()
+    : Buffer(InlineBuffer), Capacity(InlineCapacity), Index(InlineCapacity)
+  {}
+
+  ~TypeLocBuilder() {
+    if (Buffer != InlineBuffer)
+      delete[] Buffer;
+  }
+
+  /// Ensures that this buffer has at least as much capacity as described.
+  void reserve(size_t Requested) {
+    if (Requested > Capacity)
+      // For now, match the request exactly.
+      grow(Requested);
+  }
+
+  /// Pushes space for a typespec TypeLoc.  Invalidates any TypeLocs
+  /// previously retrieved from this builder.
+  TypeSpecTypeLoc pushTypeSpec(QualType T) {
+    size_t LocalSize = TypeSpecTypeLoc::LocalDataSize;
+    return cast<TypeSpecTypeLoc>(pushImpl(T, LocalSize));
+  }
+  
+
+  /// Pushes space for a new TypeLoc of the given type.  Invalidates
+  /// any TypeLocs previously retrieved from this builder.
+  template <class TyLocType> TyLocType push(QualType T) {
+    size_t LocalSize = cast<TyLocType>(TypeLoc(T, 0)).getLocalDataSize();
+    return cast<TyLocType>(pushImpl(T, LocalSize));
+  }
+
+  /// Creates a TypeSourceInfo for the given type.
+  TypeSourceInfo *getTypeSourceInfo(ASTContext& Context, QualType T) {
+#ifndef NDEBUG
+    assert(T == LastTy && "type doesn't match last type pushed!");
+#endif
+
+    size_t FullDataSize = Capacity - Index;
+    TypeSourceInfo *DI = Context.CreateTypeSourceInfo(T, FullDataSize);
+    memcpy(DI->getTypeLoc().getOpaqueData(), &Buffer[Index], FullDataSize);
+    return DI;
+  }
+
+private:
+  TypeLoc pushImpl(QualType T, size_t LocalSize) {
+#ifndef NDEBUG
+    QualType TLast = TypeLoc(T, 0).getNextTypeLoc().getType();
+    assert(TLast == LastTy &&
+           "mismatch between last type and new type's inner type");
+    LastTy = T;
+#endif
+
+    // If we need to grow, grow by a factor of 2.
+    if (LocalSize > Index) {
+      size_t RequiredCapacity = Capacity + (LocalSize - Index);
+      size_t NewCapacity = Capacity * 2;
+      while (RequiredCapacity > NewCapacity)
+        NewCapacity *= 2;
+      grow(NewCapacity);
+    }
+
+    Index -= LocalSize;
+
+    return TypeLoc(T, &Buffer[Index]);
+  }
+
+  /// Grow to the given capacity.
+  void grow(size_t NewCapacity) {
+    assert(NewCapacity > Capacity);
+
+    // Allocate the new buffer and copy the old data into it.
+    char *NewBuffer = new char[NewCapacity];
+    unsigned NewIndex = Index + NewCapacity - Capacity;
+    memcpy(&NewBuffer[NewIndex],
+           &Buffer[Index],
+           Capacity - Index);
+
+    if (Buffer != InlineBuffer)
+      delete[] Buffer;
+
+    Buffer = NewBuffer;
+    Capacity = NewCapacity;
+    Index = NewIndex;
+  }
+};
+
+}
+
+#endif
diff --git a/include/clang/AST/TypeLocNodes.def b/include/clang/AST/TypeLocNodes.def
new file mode 100644
index 0000000..4590e48
--- /dev/null
+++ b/include/clang/AST/TypeLocNodes.def
@@ -0,0 +1,41 @@
+//===-- TypeLocNodes.def - Metadata about TypeLoc wrappers ------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the TypeLoc info database.  Each node is
+//  enumerated by providing its core name (e.g., "Pointer" for "PointerTypeLoc")
+//  and base class (e.g., "DeclaratorLoc").  All nodes except QualifiedTypeLoc
+//  are associated
+//
+//    TYPELOC(Class, Base) - A TypeLoc subclass.  If UNQUAL_TYPELOC is
+//      provided, there will be exactly one of these, Qualified.
+//
+//    UNQUAL_TYPELOC(Class, Base, Type) - An UnqualTypeLoc subclass.
+//
+//    ABSTRACT_TYPELOC(Class) - Refers to TypeSpecLoc and DeclaratorLoc.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef UNQUAL_TYPELOC
+#  define UNQUAL_TYPELOC(Class, Base) TYPELOC(Class, Base)
+#endif
+
+#ifndef ABSTRACT_TYPELOC
+#  define ABSTRACT_TYPELOC(Class, Base) UNQUAL_TYPELOC(Class, Base)
+#endif
+
+TYPELOC(Qualified, TypeLoc)
+#define TYPE(Class, Base) UNQUAL_TYPELOC(Class, Base##Loc)
+#define ABSTRACT_TYPE(Class, Base) ABSTRACT_TYPELOC(Class, Base##Loc)
+#include "clang/AST/TypeNodes.def"
+
+#undef DECLARATOR_TYPELOC
+#undef TYPESPEC_TYPELOC
+#undef ABSTRACT_TYPELOC
+#undef UNQUAL_TYPELOC
+#undef TYPELOC
diff --git a/include/clang/AST/TypeLocVisitor.h b/include/clang/AST/TypeLocVisitor.h
new file mode 100644
index 0000000..50fc439
--- /dev/null
+++ b/include/clang/AST/TypeLocVisitor.h
@@ -0,0 +1,62 @@
+//===--- TypeLocVisitor.h - Visitor for TypeLoc subclasses ------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the TypeLocVisitor interface.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_AST_TYPELOCVISITOR_H
+#define LLVM_CLANG_AST_TYPELOCVISITOR_H
+
+#include "clang/AST/TypeLoc.h"
+#include "clang/AST/TypeVisitor.h"
+#include "llvm/Support/ErrorHandling.h"
+
+namespace clang {
+
+#define DISPATCH(CLASSNAME) \
+  return static_cast<ImplClass*>(this)-> \
+    Visit##CLASSNAME(cast<CLASSNAME>(TyLoc))
+
+template<typename ImplClass, typename RetTy=void>
+class TypeLocVisitor {
+public:
+  RetTy Visit(TypeLoc TyLoc) {
+    switch (TyLoc.getTypeLocClass()) {
+#define ABSTRACT_TYPELOC(CLASS, PARENT)
+#define TYPELOC(CLASS, PARENT) \
+    case TypeLoc::CLASS: DISPATCH(CLASS##TypeLoc);
+#include "clang/AST/TypeLocNodes.def"
+    }
+    llvm_unreachable("unexpected type loc class!");
+  }
+
+  RetTy Visit(UnqualTypeLoc TyLoc) {
+    switch (TyLoc.getTypeLocClass()) {
+#define ABSTRACT_TYPELOC(CLASS, PARENT)
+#define TYPELOC(CLASS, PARENT) \
+    case TypeLoc::CLASS: DISPATCH(CLASS##TypeLoc);
+#include "clang/AST/TypeLocNodes.def"
+    }
+    llvm_unreachable("unexpected type loc class!");
+  }
+
+#define TYPELOC(CLASS, PARENT)      \
+  RetTy Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
+    DISPATCH(PARENT);               \
+  }
+#include "clang/AST/TypeLocNodes.def"
+
+  RetTy VisitTypeLoc(TypeLoc TyLoc) { return RetTy(); }
+};
+
+#undef DISPATCH
+
+}  // end namespace clang
+
+#endif // LLVM_CLANG_AST_TYPELOCVISITOR_H
diff --git a/include/clang/AST/TypeNodes.def b/include/clang/AST/TypeNodes.def
new file mode 100644
index 0000000..c665073
--- /dev/null
+++ b/include/clang/AST/TypeNodes.def
@@ -0,0 +1,119 @@
+//===-- TypeNodes.def - Metadata about Type AST nodes -----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the AST type info database. Each type node is
+//  enumerated by providing its name (e.g., "Builtin" or "Enum") and
+//  base class (e.g., "Type" or "TagType"). Depending on where in the
+//  abstract syntax tree the type will show up, the enumeration uses
+//  one of four different macros:
+//
+//    TYPE(Class, Base) - A type that can show up anywhere in the AST,
+//    and might be dependent, canonical, or non-canonical. All clients
+//    will need to understand these types.
+//
+//    ABSTRACT_TYPE(Class, Base) - An abstract class that shows up in
+//    the type hierarchy but has no concrete instances.
+//
+//    NON_CANONICAL_TYPE(Class, Base) - A type that can show up
+//    anywhere in the AST but will never be a part of a canonical
+//    type. Clients that only need to deal with canonical types
+//    (ignoring, e.g., typedefs and other type alises used for
+//    pretty-printing) can ignore these types.
+//
+//    DEPENDENT_TYPE(Class, Base) - A type that will only show up
+//    within a C++ template that has not been instantiated, e.g., a
+//    type that is always dependent. Clients that do not need to deal
+//    with uninstantiated C++ templates can ignore these types.
+//
+//    NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) - A type that
+//    is non-canonical unless it is dependent.  Defaults to TYPE because
+//    it is neither reliably dependent nor reliably non-canonical.
+//
+//  There is a sixth macro, independent of the others.  Most clients
+//  will not need to use it.
+//
+//    LEAF_TYPE(Class) - A type that never has inner types.  Clients
+//    which can operate on such types more efficiently may wish to do so.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef ABSTRACT_TYPE
+#  define ABSTRACT_TYPE(Class, Base) TYPE(Class, Base)
+#endif
+
+#ifndef NON_CANONICAL_TYPE
+#  define NON_CANONICAL_TYPE(Class, Base) TYPE(Class, Base)
+#endif
+
+#ifndef DEPENDENT_TYPE
+#  define DEPENDENT_TYPE(Class, Base) TYPE(Class, Base)
+#endif
+
+#ifndef NON_CANONICAL_UNLESS_DEPENDENT_TYPE
+#  define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) TYPE(Class, Base)
+#endif
+
+TYPE(Builtin, Type)
+TYPE(Complex, Type)
+TYPE(Pointer, Type)
+TYPE(BlockPointer, Type)
+ABSTRACT_TYPE(Reference, Type)
+TYPE(LValueReference, ReferenceType)
+TYPE(RValueReference, ReferenceType)
+TYPE(MemberPointer, Type)
+ABSTRACT_TYPE(Array, Type)
+TYPE(ConstantArray, ArrayType)
+TYPE(IncompleteArray, ArrayType)
+TYPE(VariableArray, ArrayType)
+DEPENDENT_TYPE(DependentSizedArray, ArrayType)
+DEPENDENT_TYPE(DependentSizedExtVector, Type)
+TYPE(Vector, Type)
+TYPE(ExtVector, VectorType)
+ABSTRACT_TYPE(Function, Type)
+TYPE(FunctionProto, FunctionType)
+TYPE(FunctionNoProto, FunctionType)
+DEPENDENT_TYPE(UnresolvedUsing, Type)
+NON_CANONICAL_TYPE(Typedef, Type)
+NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TypeOfExpr, Type)
+NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TypeOf, Type)
+NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Decltype, Type)
+ABSTRACT_TYPE(Tag, Type)
+TYPE(Record, TagType)
+TYPE(Enum, TagType)
+NON_CANONICAL_TYPE(Elaborated, Type)
+DEPENDENT_TYPE(TemplateTypeParm, Type)
+NON_CANONICAL_TYPE(SubstTemplateTypeParm, Type)
+NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TemplateSpecialization, Type)
+NON_CANONICAL_TYPE(QualifiedName, Type)
+DEPENDENT_TYPE(InjectedClassName, Type)
+DEPENDENT_TYPE(DependentName, Type)
+TYPE(ObjCInterface, Type)
+TYPE(ObjCObjectPointer, Type)
+
+#ifdef LAST_TYPE
+LAST_TYPE(ObjCObjectPointer)
+#undef LAST_TYPE
+#endif
+
+// These types are always leaves in the type hierarchy.
+#ifdef LEAF_TYPE
+LEAF_TYPE(Enum)
+LEAF_TYPE(Builtin)
+LEAF_TYPE(Record)
+LEAF_TYPE(InjectedClassName)
+LEAF_TYPE(ObjCInterface)
+LEAF_TYPE(TemplateTypeParm)
+#undef LEAF_TYPE
+#endif
+
+#undef NON_CANONICAL_UNLESS_DEPENDENT_TYPE
+#undef DEPENDENT_TYPE
+#undef NON_CANONICAL_TYPE
+#undef ABSTRACT_TYPE
+#undef TYPE
diff --git a/include/clang/AST/TypeOrdering.h b/include/clang/AST/TypeOrdering.h
new file mode 100644
index 0000000..1a050d2
--- /dev/null
+++ b/include/clang/AST/TypeOrdering.h
@@ -0,0 +1,56 @@
+//===-------------- TypeOrdering.h - Total ordering for types -------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file provides a function objects and specializations that
+//  allow QualType values to be sorted, used in std::maps, std::sets,
+//  llvm::DenseMaps, and llvm::DenseSets.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TYPE_ORDERING_H
+#define LLVM_CLANG_TYPE_ORDERING_H
+
+#include "clang/AST/Type.h"
+#include <functional>
+
+namespace clang {
+
+/// QualTypeOrdering - Function object that provides a total ordering
+/// on QualType values.
+struct QualTypeOrdering : std::binary_function<QualType, QualType, bool> {
+  bool operator()(QualType T1, QualType T2) const {
+    return std::less<void*>()(T1.getAsOpaquePtr(), T2.getAsOpaquePtr());
+  }
+};
+
+}
+
+namespace llvm {
+  template<class> struct DenseMapInfo;
+
+  template<> struct DenseMapInfo<clang::QualType> {
+    static inline clang::QualType getEmptyKey() { return clang::QualType(); }
+
+    static inline clang::QualType getTombstoneKey() {
+      using clang::QualType;
+      return QualType::getFromOpaquePtr(reinterpret_cast<clang::Type *>(-1));
+    }
+
+    static unsigned getHashValue(clang::QualType Val) {
+      return (unsigned)((uintptr_t)Val.getAsOpaquePtr()) ^
+            ((unsigned)((uintptr_t)Val.getAsOpaquePtr() >> 9));
+    }
+
+    static bool isEqual(clang::QualType LHS, clang::QualType RHS) {
+      return LHS == RHS;
+    }
+  };
+}
+
+#endif
diff --git a/include/clang/AST/TypeVisitor.h b/include/clang/AST/TypeVisitor.h
new file mode 100644
index 0000000..19f7f42
--- /dev/null
+++ b/include/clang/AST/TypeVisitor.h
@@ -0,0 +1,52 @@
+//===--- TypeVisitor.h - Visitor for Stmt subclasses ------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the TypeVisitor interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_TYPEVISITOR_H
+#define LLVM_CLANG_AST_TYPEVISITOR_H
+
+#include "clang/AST/Type.h"
+
+namespace clang {
+
+#define DISPATCH(CLASS) \
+  return static_cast<ImplClass*>(this)->Visit ## CLASS(static_cast<CLASS*>(T))
+
+template<typename ImplClass, typename RetTy=void>
+class TypeVisitor {
+public:
+  RetTy Visit(Type *T) {
+    // Top switch stmt: dispatch to VisitFooStmt for each FooStmt.
+    switch (T->getTypeClass()) {
+    default: assert(0 && "Unknown type class!");
+#define ABSTRACT_TYPE(CLASS, PARENT)
+#define TYPE(CLASS, PARENT) case Type::CLASS: DISPATCH(CLASS##Type);
+#include "clang/AST/TypeNodes.def"
+    }
+  }
+
+  // If the implementation chooses not to implement a certain visit method, fall
+  // back on superclass.
+#define TYPE(CLASS, PARENT) RetTy Visit##CLASS##Type(CLASS##Type *T) {       \
+  DISPATCH(PARENT);                                                          \
+}
+#include "clang/AST/TypeNodes.def"
+
+  // Base case, ignore it. :)
+  RetTy VisitType(Type*) { return RetTy(); }
+};
+
+#undef DISPATCH
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/AST/UnresolvedSet.h b/include/clang/AST/UnresolvedSet.h
new file mode 100644
index 0000000..cad7e61
--- /dev/null
+++ b/include/clang/AST/UnresolvedSet.h
@@ -0,0 +1,183 @@
+//===-- UnresolvedSet.h - Unresolved sets of declarations  ------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the UnresolvedSet class, which is used to store
+//  collections of declarations in the AST.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_UNRESOLVEDSET_H
+#define LLVM_CLANG_AST_UNRESOLVEDSET_H
+
+#include <iterator>
+#include "llvm/ADT/SmallVector.h"
+#include "clang/AST/DeclAccessPair.h"
+
+namespace clang {
+
+/// The iterator over UnresolvedSets.  Serves as both the const and
+/// non-const iterator.
+class UnresolvedSetIterator {
+private:
+  typedef llvm::SmallVectorImpl<DeclAccessPair> DeclsTy;
+  typedef DeclsTy::iterator IteratorTy;
+
+  IteratorTy ir;
+
+  friend class UnresolvedSetImpl;
+  explicit UnresolvedSetIterator(DeclsTy::iterator ir) : ir(ir) {}
+  explicit UnresolvedSetIterator(DeclsTy::const_iterator ir) :
+    ir(const_cast<DeclsTy::iterator>(ir)) {}
+public:
+  UnresolvedSetIterator() {}
+
+  typedef std::iterator_traits<IteratorTy>::difference_type difference_type;
+  typedef NamedDecl *value_type;
+  typedef NamedDecl **pointer;
+  typedef NamedDecl *reference;
+  typedef std::iterator_traits<IteratorTy>::iterator_category iterator_category;
+
+  NamedDecl *getDecl() const { return ir->getDecl(); }
+  AccessSpecifier getAccess() const { return ir->getAccess(); }
+  DeclAccessPair getPair() const { return *ir; }
+
+  NamedDecl *operator*() const { return getDecl(); }
+  
+  UnresolvedSetIterator &operator++() { ++ir; return *this; }
+  UnresolvedSetIterator operator++(int) { return UnresolvedSetIterator(ir++); }
+  UnresolvedSetIterator &operator--() { --ir; return *this; }
+  UnresolvedSetIterator operator--(int) { return UnresolvedSetIterator(ir--); }
+
+  UnresolvedSetIterator &operator+=(difference_type d) {
+    ir += d; return *this;
+  }
+  UnresolvedSetIterator operator+(difference_type d) const {
+    return UnresolvedSetIterator(ir + d);
+  }
+  UnresolvedSetIterator &operator-=(difference_type d) {
+    ir -= d; return *this;
+  }
+  UnresolvedSetIterator operator-(difference_type d) const {
+    return UnresolvedSetIterator(ir - d);
+  }
+  value_type operator[](difference_type d) const { return *(*this + d); }
+
+  difference_type operator-(const UnresolvedSetIterator &o) const {
+    return ir - o.ir;
+  }
+
+  bool operator==(const UnresolvedSetIterator &o) const { return ir == o.ir; }
+  bool operator!=(const UnresolvedSetIterator &o) const { return ir != o.ir; }
+  bool operator<(const UnresolvedSetIterator &o) const { return ir < o.ir; }
+  bool operator<=(const UnresolvedSetIterator &o) const { return ir <= o.ir; }
+  bool operator>=(const UnresolvedSetIterator &o) const { return ir >= o.ir; }
+  bool operator>(const UnresolvedSetIterator &o) const { return ir > o.ir; }
+};
+
+/// UnresolvedSet - A set of unresolved declarations.  This is needed
+/// in a lot of places, but isn't really worth breaking into its own
+/// header right now.
+class UnresolvedSetImpl {
+  typedef UnresolvedSetIterator::DeclsTy DeclsTy;
+
+  // Don't allow direct construction, and only permit subclassing by
+  // UnresolvedSet.
+private:
+  template <unsigned N> friend class UnresolvedSet;
+  UnresolvedSetImpl() {}
+  UnresolvedSetImpl(const UnresolvedSetImpl &) {}
+
+public:
+  // We don't currently support assignment through this iterator, so we might
+  // as well use the same implementation twice.
+  typedef UnresolvedSetIterator iterator;
+  typedef UnresolvedSetIterator const_iterator;
+
+  iterator begin() { return iterator(decls().begin()); }
+  iterator end() { return iterator(decls().end()); }
+
+  const_iterator begin() const { return const_iterator(decls().begin()); }
+  const_iterator end() const { return const_iterator(decls().end()); }
+
+  void addDecl(NamedDecl *D) {
+    addDecl(D, AS_none);
+  }
+
+  void addDecl(NamedDecl *D, AccessSpecifier AS) {
+    decls().push_back(DeclAccessPair::make(D, AS));
+  }
+
+  /// Replaces the given declaration with the new one, once.
+  ///
+  /// \return true if the set changed
+  bool replace(const NamedDecl* Old, NamedDecl *New) {
+    for (DeclsTy::iterator I = decls().begin(), E = decls().end(); I != E; ++I)
+      if (I->getDecl() == Old)
+        return (I->setDecl(New), true);
+    return false;
+  }
+
+  /// Replaces the declaration at the given iterator with the new one,
+  /// preserving the original access bits.
+  void replace(iterator I, NamedDecl *New) {
+    I.ir->setDecl(New);
+  }
+
+  void replace(iterator I, NamedDecl *New, AccessSpecifier AS) {
+    I.ir->set(New, AS);
+  }
+
+  void erase(unsigned I) {
+    decls()[I] = decls().back();
+    decls().pop_back();
+  }
+
+  void erase(iterator I) {
+    *I.ir = decls().back();
+    decls().pop_back();
+  }
+
+  void setAccess(iterator I, AccessSpecifier AS) {
+    I.ir->setAccess(AS);
+  }
+
+  void clear() { decls().clear(); }
+  void set_size(unsigned N) { decls().set_size(N); }
+
+  bool empty() const { return decls().empty(); }
+  unsigned size() const { return decls().size(); }
+
+  void append(iterator I, iterator E) {
+    decls().append(I.ir, E.ir);
+  }
+
+  DeclAccessPair &operator[](unsigned I) { return decls()[I]; }
+  const DeclAccessPair &operator[](unsigned I) const { return decls()[I]; }
+
+private:
+  // These work because the only permitted subclass is UnresolvedSetImpl
+
+  DeclsTy &decls() {
+    return *reinterpret_cast<DeclsTy*>(this);
+  }
+  const DeclsTy &decls() const {
+    return *reinterpret_cast<const DeclsTy*>(this);
+  }
+};
+
+/// A set of unresolved declarations 
+template <unsigned InlineCapacity> class UnresolvedSet :
+    public UnresolvedSetImpl {
+  llvm::SmallVector<DeclAccessPair, InlineCapacity> Decls;
+};
+
+  
+} // namespace clang
+
+#endif
diff --git a/include/clang/AST/UsuallyTinyPtrVector.h b/include/clang/AST/UsuallyTinyPtrVector.h
new file mode 100644
index 0000000..5ee40e0
--- /dev/null
+++ b/include/clang/AST/UsuallyTinyPtrVector.h
@@ -0,0 +1,105 @@
+//===-- UsuallyTinyPtrVector.h - Pointer vector class -----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the UsuallyTinyPtrVector class, which is a vector that
+//  optimizes the case where there is only one element.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_USUALLY_TINY_PTR_VECTOR_H
+#define LLVM_CLANG_AST_USUALLY_TINY_PTR_VECTOR_H
+
+#include <vector>
+
+namespace clang {
+
+/// \brief A vector class template that is optimized for storing a single 
+/// pointer element.
+template<typename T>
+class UsuallyTinyPtrVector {
+  /// \brief Storage for the vector.
+  ///
+  /// When the low bit is zero, this is a T *. When the
+  /// low bit is one, this is a std::vector<T *> *.
+  mutable uintptr_t Storage;
+
+  typedef std::vector<T*> vector_type;
+
+public:
+  UsuallyTinyPtrVector() : Storage(0) { }
+  explicit UsuallyTinyPtrVector(T *Element) 
+    : Storage(reinterpret_cast<uintptr_t>(Element)) { }
+  
+  bool empty() const { return !Storage; }
+
+  typedef const T **iterator;
+  iterator begin() const;
+  iterator end() const;
+
+  void push_back(T *Method);
+  void Destroy();
+};
+
+template<typename T>
+typename UsuallyTinyPtrVector<T>::iterator 
+UsuallyTinyPtrVector<T>::begin() const {
+  if ((Storage & 0x01) == 0)
+    return reinterpret_cast<iterator>(&Storage);
+
+  vector_type *Vec = reinterpret_cast<vector_type *>(Storage & ~0x01);
+  return &Vec->front();
+}
+
+
+template<typename T>
+typename UsuallyTinyPtrVector<T>::iterator 
+UsuallyTinyPtrVector<T>::end() const {
+  if ((Storage & 0x01) == 0) {
+    if (Storage == 0)
+      return reinterpret_cast<iterator>(&Storage);
+
+    return reinterpret_cast<iterator>(&Storage) + 1;
+  }
+
+  vector_type *Vec = reinterpret_cast<vector_type *>(Storage & ~0x01);
+  return &Vec->front() + Vec->size();
+}
+
+template<typename T>
+void UsuallyTinyPtrVector<T>::push_back(T *Element) {
+  if (Storage == 0) {
+    // 0 -> 1 element.
+    Storage = reinterpret_cast<uintptr_t>(Element);
+    return;
+  }
+
+  vector_type *Vec;
+  if ((Storage & 0x01) == 0) {
+    // 1 -> 2 elements. Allocate a new vector and push the element into that
+    // vector.
+    Vec = new vector_type;
+    Vec->push_back(reinterpret_cast<T *>(Storage));
+    Storage = reinterpret_cast<uintptr_t>(Vec) | 0x01;
+  } else
+    Vec = reinterpret_cast<vector_type *>(Storage & ~0x01);
+
+  // Add the new element to the vector.
+  Vec->push_back(Element);
+}
+
+template<typename T>
+void UsuallyTinyPtrVector<T>::Destroy() {
+  if (Storage & 0x01)
+    delete reinterpret_cast<vector_type *>(Storage & ~0x01);
+  
+  Storage = 0;
+}
+
+}
+#endif 
diff --git a/include/clang/Analysis/Analyses/LiveVariables.h b/include/clang/Analysis/Analyses/LiveVariables.h
new file mode 100644
index 0000000..44ab080
--- /dev/null
+++ b/include/clang/Analysis/Analyses/LiveVariables.h
@@ -0,0 +1,121 @@
+//===- LiveVariables.h - Live Variable Analysis for Source CFGs -*- C++ --*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements Live Variables analysis for source-level CFGs.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIVEVARIABLES_H
+#define LLVM_CLANG_LIVEVARIABLES_H
+
+#include "clang/AST/Decl.h"
+#include "clang/Analysis/Support/BlkExprDeclBitVector.h"
+#include "clang/Analysis/FlowSensitive/DataflowValues.h"
+
+namespace clang {
+
+class Stmt;
+class DeclRefExpr;
+class SourceManager;
+class AnalysisContext;
+
+struct LiveVariables_ValueTypes {
+
+  struct ObserverTy;
+
+  // We keep dataflow state for declarations and block-level expressions;
+  typedef StmtDeclBitVector_Types::ValTy ValTy;
+
+  // We need to keep track of both declarations and CFGBlock-level expressions,
+  // (so that we don't explore such expressions twice).  We also want
+  // to compute liveness information for block-level expressions, since these
+  // act as "temporary" values.
+
+  struct AnalysisDataTy : public StmtDeclBitVector_Types::AnalysisDataTy {
+    ObserverTy* Observer;
+    ValTy AlwaysLive;
+    AnalysisContext *AC;
+
+    AnalysisDataTy() : Observer(NULL), AC(NULL) {}
+  };
+
+  //===-----------------------------------------------------===//
+  // ObserverTy - Observer for uninitialized values queries.
+  //===-----------------------------------------------------===//
+
+  struct ObserverTy {
+    virtual ~ObserverTy() {}
+
+    /// ObserveStmt - A callback invoked right before invoking the
+    ///  liveness transfer function on the given statement.
+    virtual void ObserveStmt(Stmt* S, const AnalysisDataTy& AD,
+                             const ValTy& V) {}
+
+    virtual void ObserverKill(DeclRefExpr* DR) {}
+  };
+};
+
+class LiveVariables : public DataflowValues<LiveVariables_ValueTypes,
+                                            dataflow::backward_analysis_tag> {
+
+
+public:
+  typedef LiveVariables_ValueTypes::ObserverTy ObserverTy;
+
+  LiveVariables(AnalysisContext &AC);
+
+  /// IsLive - Return true if a variable is live at the end of a
+  /// specified block.
+  bool isLive(const CFGBlock* B, const VarDecl* D) const;
+
+  /// IsLive - Returns true if a variable is live at the beginning of the
+  ///  the statement.  This query only works if liveness information
+  ///  has been recorded at the statement level (see runOnAllBlocks), and
+  ///  only returns liveness information for block-level expressions.
+  bool isLive(const Stmt* S, const VarDecl* D) const;
+
+  /// IsLive - Returns true the block-level expression "value" is live
+  ///  before the given block-level expression (see runOnAllBlocks).
+  bool isLive(const Stmt* Loc, const Stmt* StmtVal) const;
+
+  /// IsLive - Return true if a variable is live according to the
+  ///  provided livness bitvector.
+  bool isLive(const ValTy& V, const VarDecl* D) const;
+
+  /// dumpLiveness - Print to stderr the liveness information encoded
+  ///  by a specified bitvector.
+  void dumpLiveness(const ValTy& V, const SourceManager& M) const;
+
+  /// dumpBlockLiveness - Print to stderr the liveness information
+  ///  associated with each basic block.
+  void dumpBlockLiveness(const SourceManager& M) const;
+
+  /// getNumDecls - Return the number of variables (declarations) that
+  ///  whose liveness status is being tracked by the dataflow
+  ///  analysis.
+  unsigned getNumDecls() const { return getAnalysisData().getNumDecls(); }
+
+  /// IntializeValues - This routine can perform extra initialization, but
+  ///  for LiveVariables this does nothing since all that logic is in
+  ///  the constructor.
+  void InitializeValues(const CFG& cfg) {}
+
+  void runOnCFG(CFG& cfg);
+
+  /// runOnAllBlocks - Propagate the dataflow values once for each block,
+  ///  starting from the current dataflow values.  'recordStmtValues' indicates
+  ///  whether the method should store dataflow values per each individual
+  ///  block-level expression.
+  void runOnAllBlocks(const CFG& cfg, ObserverTy* Obs,
+                      bool recordStmtValues=false);
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Analysis/Analyses/PrintfFormatString.h b/include/clang/Analysis/Analyses/PrintfFormatString.h
new file mode 100644
index 0000000..e4f7c57
--- /dev/null
+++ b/include/clang/Analysis/Analyses/PrintfFormatString.h
@@ -0,0 +1,313 @@
+//==- PrintfFormatStrings.h - Analysis of printf format strings --*- C++ -*-==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Handling of format string in printf and friends.  The structure of format
+// strings for fprintf() are described in C99 7.19.6.1.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FPRINTF_FORMAT_H
+#define LLVM_CLANG_FPRINTF_FORMAT_H
+
+#include "clang/AST/CanonicalType.h"
+
+namespace clang {
+
+class ASTContext;
+
+namespace analyze_printf {
+
+class ArgTypeResult {
+public:
+  enum Kind { UnknownTy, InvalidTy, SpecificTy, ObjCPointerTy, CStrTy,
+              WCStrTy };
+private:
+  const Kind K;
+  QualType T;
+  ArgTypeResult(bool) : K(InvalidTy) {}
+public:
+  ArgTypeResult(Kind k = UnknownTy) : K(k) {}
+  ArgTypeResult(QualType t) : K(SpecificTy), T(t) {}
+  ArgTypeResult(CanQualType t) : K(SpecificTy), T(t) {}
+
+  static ArgTypeResult Invalid() { return ArgTypeResult(true); }
+
+  bool isValid() const { return K != InvalidTy; }
+
+  const QualType *getSpecificType() const {
+    return K == SpecificTy ? &T : 0;
+  }
+
+  bool matchesType(ASTContext &C, QualType argTy) const;
+
+  bool matchesAnyObjCObjectRef() const { return K == ObjCPointerTy; }
+
+  QualType getRepresentativeType(ASTContext &C) const;
+};
+
+class ConversionSpecifier {
+public:
+  enum Kind {
+   InvalidSpecifier = 0,
+    // C99 conversion specifiers.
+   dArg, // 'd'
+   iArg, // 'i',
+   oArg, // 'o',
+   uArg, // 'u',
+   xArg, // 'x',
+   XArg, // 'X',
+   fArg, // 'f',
+   FArg, // 'F',
+   eArg, // 'e',
+   EArg, // 'E',
+   gArg, // 'g',
+   GArg, // 'G',
+   aArg, // 'a',
+   AArg, // 'A',
+   IntAsCharArg,  // 'c'
+   CStrArg,       // 's'
+   VoidPtrArg,    // 'p'
+   OutIntPtrArg,  // 'n'
+   PercentArg,    // '%'
+   // MacOS X unicode extensions.
+   CArg, // 'C'
+   UnicodeStrArg, // 'S'
+   // Objective-C specific specifiers.
+   ObjCObjArg,    // '@'
+   // GlibC specific specifiers.
+   PrintErrno,    // 'm'
+   // Specifier ranges.
+   IntArgBeg = dArg,
+   IntArgEnd = iArg,
+   UIntArgBeg = oArg,
+   UIntArgEnd = XArg,
+   DoubleArgBeg = fArg,
+   DoubleArgEnd = AArg,
+   C99Beg = IntArgBeg,
+   C99End = DoubleArgEnd,
+   ObjCBeg = ObjCObjArg,
+   ObjCEnd = ObjCObjArg
+  };
+
+  ConversionSpecifier()
+    : Position(0), kind(InvalidSpecifier) {}
+
+  ConversionSpecifier(const char *pos, Kind k)
+    : Position(pos), kind(k) {}
+
+  const char *getStart() const {
+    return Position;
+  }
+
+  llvm::StringRef getCharacters() const {
+    return llvm::StringRef(getStart(), getLength());
+  }
+
+  bool consumesDataArgument() const {
+    switch (kind) {
+  	  case PercentArg:
+	  case PrintErrno:
+		return false;
+	  default:
+		return true;
+	}
+  }
+
+  bool isObjCArg() const { return kind >= ObjCBeg && kind <= ObjCEnd; }
+  bool isIntArg() const { return kind >= dArg && kind <= iArg; }
+  bool isUIntArg() const { return kind >= oArg && kind <= XArg; }
+  bool isDoubleArg() const { return kind >= fArg && kind <= AArg; }
+  Kind getKind() const { return kind; }
+  unsigned getLength() const {
+    // Conversion specifiers currently only are represented by
+    // single characters, but we be flexible.
+    return 1;
+  }
+
+private:
+  const char *Position;
+  Kind kind;
+};
+
+enum LengthModifier {
+ None,
+ AsChar,      // 'hh'
+ AsShort,     // 'h'
+ AsLong,      // 'l'
+ AsLongLong,  // 'll', 'q' (BSD, deprecated)
+ AsIntMax,    // 'j'
+ AsSizeT,     // 'z'
+ AsPtrDiff,   // 't'
+ AsLongDouble, // 'L'
+ AsWideChar = AsLong // for '%ls'
+};
+
+class OptionalAmount {
+public:
+  enum HowSpecified { NotSpecified, Constant, Arg, Invalid };
+
+  OptionalAmount(HowSpecified h, unsigned i, const char *st)
+    : start(st), hs(h), amt(i) {}
+
+  OptionalAmount(bool b = true)
+    : start(0), hs(b ? NotSpecified : Invalid), amt(0) {}
+
+  bool isInvalid() const {
+    return hs == Invalid;
+  }
+
+  HowSpecified getHowSpecified() const { return hs; }
+
+  bool hasDataArgument() const { return hs == Arg; }
+
+  unsigned getArgIndex() const {
+    assert(hasDataArgument());
+    return amt;
+  }
+
+  unsigned getConstantAmount() const {
+    assert(hs == Constant);
+    return amt;
+  }
+
+  const char *getStart() const {
+    return start;
+  }
+
+  ArgTypeResult getArgType(ASTContext &Ctx) const;
+
+private:
+  const char *start;
+  HowSpecified hs;
+  unsigned amt;
+};
+
+class FormatSpecifier {
+  LengthModifier LM;
+  unsigned IsLeftJustified : 1;
+  unsigned HasPlusPrefix : 1;
+  unsigned HasSpacePrefix : 1;
+  unsigned HasAlternativeForm : 1;
+  unsigned HasLeadingZeroes : 1;
+  /// Positional arguments, an IEEE extension:
+  ///  IEEE Std 1003.1, 2004 Edition
+  ///  http://www.opengroup.org/onlinepubs/009695399/functions/printf.html
+  unsigned UsesPositionalArg : 1;
+  unsigned argIndex;
+  ConversionSpecifier CS;
+  OptionalAmount FieldWidth;
+  OptionalAmount Precision;
+public:
+  FormatSpecifier() : LM(None),
+    IsLeftJustified(0), HasPlusPrefix(0), HasSpacePrefix(0),
+    HasAlternativeForm(0), HasLeadingZeroes(0), UsesPositionalArg(0),
+    argIndex(0) {}
+
+  static FormatSpecifier Parse(const char *beg, const char *end);
+
+  // Methods for incrementally constructing the FormatSpecifier.
+  void setConversionSpecifier(const ConversionSpecifier &cs) {
+    CS = cs;
+  }
+  void setLengthModifier(LengthModifier lm) {
+    LM = lm;
+  }
+  void setIsLeftJustified() { IsLeftJustified = 1; }
+  void setHasPlusPrefix() { HasPlusPrefix = 1; }
+  void setHasSpacePrefix() { HasSpacePrefix = 1; }
+  void setHasAlternativeForm() { HasAlternativeForm = 1; }
+  void setHasLeadingZeros() { HasLeadingZeroes = 1; }
+  void setUsesPositionalArg() { UsesPositionalArg = 1; }
+
+  void setArgIndex(unsigned i) {
+    assert(CS.consumesDataArgument());
+    argIndex = i;
+  }
+
+  unsigned getArgIndex() const {
+    assert(CS.consumesDataArgument());
+    return argIndex;
+  }
+
+  // Methods for querying the format specifier.
+
+  const ConversionSpecifier &getConversionSpecifier() const {
+    return CS;
+  }
+
+  LengthModifier getLengthModifier() const {
+    return LM;
+  }
+
+  const OptionalAmount &getFieldWidth() const {
+    return FieldWidth;
+  }
+
+  void setFieldWidth(const OptionalAmount &Amt) {
+    FieldWidth = Amt;
+  }
+
+  void setPrecision(const OptionalAmount &Amt) {
+    Precision = Amt;
+  }
+
+  const OptionalAmount &getPrecision() const {
+    return Precision;
+  }
+
+  /// \brief Returns the builtin type that a data argument
+  /// paired with this format specifier should have.  This method
+  /// will return null if the format specifier does not have
+  /// a matching data argument or the matching argument matches
+  /// more than one type.
+  ArgTypeResult getArgType(ASTContext &Ctx) const;
+
+  bool isLeftJustified() const { return (bool) IsLeftJustified; }
+  bool hasPlusPrefix() const { return (bool) HasPlusPrefix; }
+  bool hasAlternativeForm() const { return (bool) HasAlternativeForm; }
+  bool hasLeadingZeros() const { return (bool) HasLeadingZeroes; }
+  bool hasSpacePrefix() const { return (bool) HasSpacePrefix; }
+  bool usesPositionalArg() const { return (bool) UsesPositionalArg; }
+};
+
+enum PositionContext { FieldWidthPos = 0, PrecisionPos = 1 };
+
+class FormatStringHandler {
+public:
+  FormatStringHandler() {}
+  virtual ~FormatStringHandler();
+
+  virtual void HandleIncompleteFormatSpecifier(const char *startSpecifier,
+                                               unsigned specifierLen) {}
+
+  virtual void HandleNullChar(const char *nullCharacter) {}
+
+  virtual void HandleInvalidPosition(const char *startPos, unsigned posLen,
+                                     PositionContext p) {}
+
+  virtual void HandleZeroPosition(const char *startPos, unsigned posLen) {}
+
+  virtual bool
+    HandleInvalidConversionSpecifier(const analyze_printf::FormatSpecifier &FS,
+                                     const char *startSpecifier,
+                                     unsigned specifierLen) { return true; }
+
+  virtual bool HandleFormatSpecifier(const analyze_printf::FormatSpecifier &FS,
+                                     const char *startSpecifier,
+                                     unsigned specifierLen) {
+    return true;
+  }
+};
+
+bool ParseFormatString(FormatStringHandler &H,
+                       const char *beg, const char *end);
+
+} // end printf namespace
+} // end clang namespace
+#endif
diff --git a/include/clang/Analysis/Analyses/ReachableCode.h b/include/clang/Analysis/Analyses/ReachableCode.h
new file mode 100644
index 0000000..e0c84f9
--- /dev/null
+++ b/include/clang/Analysis/Analyses/ReachableCode.h
@@ -0,0 +1,55 @@
+//===- ReachableCode.h -----------------------------------------*- C++ --*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// A flow-sensitive, path-insensitive analysis of unreachable code.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_REACHABLECODE_H
+#define LLVM_CLANG_REACHABLECODE_H
+
+#include "clang/Basic/SourceLocation.h"
+
+//===----------------------------------------------------------------------===//
+// Forward declarations.
+//===----------------------------------------------------------------------===//
+
+namespace llvm {
+  class BitVector;
+}
+
+namespace clang {
+  class AnalysisContext;
+  class CFGBlock;
+}
+
+//===----------------------------------------------------------------------===//
+// API.
+//===----------------------------------------------------------------------===//
+
+namespace clang {
+namespace reachable_code {
+
+class Callback {
+public:
+  virtual ~Callback() {}
+  virtual void HandleUnreachable(SourceLocation L, SourceRange R1,
+                                 SourceRange R2) = 0;
+};
+
+/// ScanReachableFromBlock - Mark all blocks reachable from Start.
+/// Returns the total number of blocks that were marked reachable.  
+unsigned ScanReachableFromBlock(const CFGBlock &Start,
+                                llvm::BitVector &Reachable);
+
+void FindUnreachableCode(AnalysisContext &AC, Callback &CB);
+
+}} // end namespace clang::reachable_code
+
+#endif
diff --git a/include/clang/Analysis/Analyses/UninitializedValues.h b/include/clang/Analysis/Analyses/UninitializedValues.h
new file mode 100644
index 0000000..cd771ac
--- /dev/null
+++ b/include/clang/Analysis/Analyses/UninitializedValues.h
@@ -0,0 +1,77 @@
+//===- UninitializedValues.h - unintialized values analysis ----*- C++ --*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides the interface for the Unintialized Values analysis,
+// a flow-sensitive analysis that detects when variable values are unintialized.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_UNITVALS_H
+#define LLVM_CLANG_UNITVALS_H
+
+#include "clang/Analysis/Support/BlkExprDeclBitVector.h"
+#include "clang/Analysis/FlowSensitive/DataflowValues.h"
+
+namespace clang {
+
+  class BlockVarDecl;
+  class Expr;
+  class DeclRefExpr;
+  class VarDecl;
+
+/// UninitializedValues_ValueTypes - Utility class to wrap type declarations
+///   for dataflow values and dataflow analysis state for the
+///   Unitialized Values analysis.
+class UninitializedValues_ValueTypes {
+public:
+
+  struct ObserverTy;
+
+  struct AnalysisDataTy : public StmtDeclBitVector_Types::AnalysisDataTy {
+    AnalysisDataTy() : Observer(NULL), FullUninitTaint(true) {}
+    virtual ~AnalysisDataTy() {}
+
+    ObserverTy* Observer;
+    bool FullUninitTaint;
+  };
+
+  typedef StmtDeclBitVector_Types::ValTy ValTy;
+
+  //===--------------------------------------------------------------------===//
+  // ObserverTy - Observer for querying DeclRefExprs that use an uninitalized
+  //   value.
+  //===--------------------------------------------------------------------===//
+
+  struct ObserverTy {
+    virtual ~ObserverTy();
+    virtual void ObserveDeclRefExpr(ValTy& Val, AnalysisDataTy& AD,
+                                    DeclRefExpr* DR, VarDecl* VD) = 0;
+  };
+};
+
+/// UninitializedValues - Objects of this class encapsulate dataflow analysis
+///  information regarding what variable declarations in a function are
+///  potentially unintialized.
+class UninitializedValues :
+  public DataflowValues<UninitializedValues_ValueTypes> {
+public:
+  typedef UninitializedValues_ValueTypes::ObserverTy ObserverTy;
+
+  UninitializedValues(CFG &cfg) { getAnalysisData().setCFG(cfg); }
+
+  /// IntializeValues - Create initial dataflow values and meta data for
+  ///  a given CFG.  This is intended to be called by the dataflow solver.
+  void InitializeValues(const CFG& cfg);
+};
+
+
+void CheckUninitializedValues(CFG& cfg, ASTContext& Ctx, Diagnostic& Diags,
+                              bool FullUninitTaint=false);
+} // end namespace clang
+#endif
diff --git a/include/clang/Analysis/AnalysisContext.h b/include/clang/Analysis/AnalysisContext.h
new file mode 100644
index 0000000..9ebd93b
--- /dev/null
+++ b/include/clang/Analysis/AnalysisContext.h
@@ -0,0 +1,263 @@
+//=== AnalysisContext.h - Analysis context for Path Sens analysis --*- C++ -*-//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines AnalysisContext, a class that manages the analysis context
+// data for path sensitive analysis.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_ANALYSISCONTEXT_H
+#define LLVM_CLANG_ANALYSIS_ANALYSISCONTEXT_H
+
+#include "clang/AST/Decl.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/Support/Allocator.h"
+
+namespace clang {
+
+class Decl;
+class Stmt;
+class CFG;
+class CFGBlock;
+class LiveVariables;
+class ParentMap;
+class ImplicitParamDecl;
+class LocationContextManager;
+class StackFrameContext;
+
+/// AnalysisContext contains the context data for the function or method under
+/// analysis.
+class AnalysisContext {
+  const Decl *D;
+
+  // AnalysisContext owns the following data.
+  CFG *cfg;
+  bool builtCFG;
+  LiveVariables *liveness;
+  ParentMap *PM;
+  llvm::DenseMap<const BlockDecl*,void*> *ReferencedBlockVars;
+  llvm::BumpPtrAllocator A;
+  bool AddEHEdges;
+public:
+  AnalysisContext(const Decl *d, bool addehedges = false)
+    : D(d), cfg(0), builtCFG(false), liveness(0), PM(0),
+      ReferencedBlockVars(0), AddEHEdges(addehedges) {}
+
+  ~AnalysisContext();
+
+  ASTContext &getASTContext() { return D->getASTContext(); }
+  const Decl *getDecl() { return D; }
+  /// getAddEHEdges - Return true iff we are adding exceptional edges from
+  /// callExprs.  If this is false, then try/catch statements and blocks
+  /// reachable from them can appear to be dead in the CFG, analysis passes must
+  /// cope with that.
+  bool getAddEHEdges() const { return AddEHEdges; }
+  Stmt *getBody();
+  CFG *getCFG();
+  ParentMap &getParentMap();
+  LiveVariables *getLiveVariables();
+
+  typedef const VarDecl * const * referenced_decls_iterator;
+
+  std::pair<referenced_decls_iterator, referenced_decls_iterator>
+    getReferencedBlockVars(const BlockDecl *BD);
+
+  /// Return the ImplicitParamDecl* associated with 'self' if this
+  /// AnalysisContext wraps an ObjCMethodDecl.  Returns NULL otherwise.
+  const ImplicitParamDecl *getSelfDecl() const;
+};
+
+class AnalysisContextManager {
+  typedef llvm::DenseMap<const Decl*, AnalysisContext*> ContextMap;
+  ContextMap Contexts;
+public:
+  ~AnalysisContextManager();
+
+  AnalysisContext *getContext(const Decl *D);
+
+  // Discard all previously created AnalysisContexts.
+  void clear();
+};
+
+class LocationContext : public llvm::FoldingSetNode {
+public:
+  enum ContextKind { StackFrame, Scope, Block };
+
+private:
+  ContextKind Kind;
+  AnalysisContext *Ctx;
+  const LocationContext *Parent;
+
+protected:
+  LocationContext(ContextKind k, AnalysisContext *ctx,
+                  const LocationContext *parent)
+    : Kind(k), Ctx(ctx), Parent(parent) {}
+
+public:
+  virtual ~LocationContext();
+
+  ContextKind getKind() const { return Kind; }
+
+  AnalysisContext *getAnalysisContext() const { return Ctx; }
+
+  const LocationContext *getParent() const { return Parent; }
+
+  bool isParentOf(const LocationContext *LC) const;
+
+  const Decl *getDecl() const { return getAnalysisContext()->getDecl(); }
+
+  CFG *getCFG() const { return getAnalysisContext()->getCFG(); }
+
+  LiveVariables *getLiveVariables() const {
+    return getAnalysisContext()->getLiveVariables();
+  }
+
+  ParentMap &getParentMap() const {
+    return getAnalysisContext()->getParentMap();
+  }
+
+  const ImplicitParamDecl *getSelfDecl() const {
+    return Ctx->getSelfDecl();
+  }
+
+  const StackFrameContext *getCurrentStackFrame() const;
+  const StackFrameContext *
+    getStackFrameForDeclContext(const DeclContext *DC) const;
+
+  virtual void Profile(llvm::FoldingSetNodeID &ID) = 0;
+
+  static bool classof(const LocationContext*) { return true; }
+
+public:
+  static void ProfileCommon(llvm::FoldingSetNodeID &ID,
+                            ContextKind ck,
+                            AnalysisContext *ctx,
+                            const LocationContext *parent,
+                            const void* data);
+};
+
+class StackFrameContext : public LocationContext {
+  // The callsite where this stack frame is established.
+  const Stmt *CallSite;
+
+  // The parent block of the callsite.
+  const CFGBlock *Block;
+
+  // The index of the callsite in the CFGBlock.
+  unsigned Index;
+
+  friend class LocationContextManager;
+  StackFrameContext(AnalysisContext *ctx, const LocationContext *parent,
+                    const Stmt *s, const CFGBlock *blk, unsigned idx)
+    : LocationContext(StackFrame, ctx, parent), CallSite(s), Block(blk),
+      Index(idx) {}
+
+public:
+  ~StackFrameContext() {}
+
+  const Stmt *getCallSite() const { return CallSite; }
+
+  const CFGBlock *getCallSiteBlock() const { return Block; }
+
+  unsigned getIndex() const { return Index; }
+
+  void Profile(llvm::FoldingSetNodeID &ID);
+
+  static void Profile(llvm::FoldingSetNodeID &ID, AnalysisContext *ctx,
+                      const LocationContext *parent, const Stmt *s,
+                      const CFGBlock *blk, unsigned idx) {
+    ProfileCommon(ID, StackFrame, ctx, parent, s);
+    ID.AddPointer(blk);
+    ID.AddInteger(idx);
+  }
+
+  static bool classof(const LocationContext* Ctx) {
+    return Ctx->getKind() == StackFrame;
+  }
+};
+
+class ScopeContext : public LocationContext {
+  const Stmt *Enter;
+
+  friend class LocationContextManager;
+  ScopeContext(AnalysisContext *ctx, const LocationContext *parent,
+               const Stmt *s)
+    : LocationContext(Scope, ctx, parent), Enter(s) {}
+
+public:
+  ~ScopeContext() {}
+
+  void Profile(llvm::FoldingSetNodeID &ID);
+
+  static void Profile(llvm::FoldingSetNodeID &ID, AnalysisContext *ctx,
+                      const LocationContext *parent, const Stmt *s) {
+    ProfileCommon(ID, Scope, ctx, parent, s);
+  }
+
+  static bool classof(const LocationContext* Ctx) {
+    return Ctx->getKind() == Scope;
+  }
+};
+
+class BlockInvocationContext : public LocationContext {
+  // FIXME: Add back context-sensivity (we don't want libAnalysis to know
+  //  about MemRegion).
+  const BlockDecl *BD;
+
+  friend class LocationContextManager;
+
+  BlockInvocationContext(AnalysisContext *ctx, const LocationContext *parent,
+                         const BlockDecl *bd)
+    : LocationContext(Block, ctx, parent), BD(bd) {}
+
+public:
+  ~BlockInvocationContext() {}
+
+  const BlockDecl *getBlockDecl() const { return BD; }
+
+  void Profile(llvm::FoldingSetNodeID &ID);
+
+  static void Profile(llvm::FoldingSetNodeID &ID, AnalysisContext *ctx,
+                      const LocationContext *parent, const BlockDecl *bd) {
+    ProfileCommon(ID, Block, ctx, parent, bd);
+  }
+
+  static bool classof(const LocationContext* Ctx) {
+    return Ctx->getKind() == Block;
+  }
+};
+
+class LocationContextManager {
+  llvm::FoldingSet<LocationContext> Contexts;
+public:
+  ~LocationContextManager();
+
+  const StackFrameContext *getStackFrame(AnalysisContext *ctx,
+                                         const LocationContext *parent,
+                                         const Stmt *s, const CFGBlock *blk,
+                                         unsigned idx);
+
+  const ScopeContext *getScope(AnalysisContext *ctx,
+                               const LocationContext *parent,
+                               const Stmt *s);
+
+  /// Discard all previously created LocationContext objects.
+  void clear();
+private:
+  template <typename LOC, typename DATA>
+  const LOC *getLocationContext(AnalysisContext *ctx,
+                                const LocationContext *parent,
+                                const DATA *d);
+};
+
+} // end clang namespace
+#endif
diff --git a/include/clang/Analysis/AnalysisDiagnostic.h b/include/clang/Analysis/AnalysisDiagnostic.h
new file mode 100644
index 0000000..114ae74
--- /dev/null
+++ b/include/clang/Analysis/AnalysisDiagnostic.h
@@ -0,0 +1,27 @@
+//===--- DiagnosticAnalysis.h - Diagnostics for libanalysis -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_DIAGNOSTICANALYSIS_H
+#define LLVM_CLANG_DIAGNOSTICANALYSIS_H
+
+#include "clang/Basic/Diagnostic.h"
+
+namespace clang {
+  namespace diag {
+    enum {
+#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE) ENUM,
+#define ANALYSISSTART
+#include "clang/Basic/DiagnosticAnalysisKinds.inc"
+#undef DIAG
+      NUM_BUILTIN_ANALYSIS_DIAGNOSTICS
+    };
+  }  // end namespace diag
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Analysis/CFG.h b/include/clang/Analysis/CFG.h
new file mode 100644
index 0000000..b7256c9
--- /dev/null
+++ b/include/clang/Analysis/CFG.h
@@ -0,0 +1,512 @@
+//===--- CFG.h - Classes for representing and building CFGs------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the CFG and CFGBuilder classes for representing and
+//  building Control-Flow Graphs (CFGs) from ASTs.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_CFG_H
+#define LLVM_CLANG_CFG_H
+
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Casting.h"
+#include "clang/Analysis/Support/BumpVector.h"
+#include "clang/Basic/SourceLocation.h"
+#include <cassert>
+
+namespace llvm {
+  class raw_ostream;
+}
+namespace clang {
+  class Decl;
+  class Stmt;
+  class Expr;
+  class CFG;
+  class PrinterHelper;
+  class LangOptions;
+  class ASTContext;
+
+namespace {
+// An element of the CFG for implicit descructor calls implied by the language
+// rules.
+class Dtor {
+  // Statement that introduces the variable.
+  Stmt *S;
+  // A token which ends the scope, return, goto, throw, }.
+  SourceLocation Loc;
+public:
+  Dtor(Stmt *s, SourceLocation l) : S(s), Loc(l) {
+  }
+  SourceLocation getLoc() { return Loc; }
+  Stmt *getStmt() { return S; }
+};
+}
+
+/// CFGElement - Represents a top-level expression in a basic block.
+class CFGElement {
+  llvm::PointerIntPair<Stmt *, 2> Data;
+public:
+  enum Type { StartScope, EndScope };
+  explicit CFGElement() {}
+  CFGElement(Stmt *S, bool lvalue) : Data(S, lvalue ? 1 : 0) {}
+  CFGElement(Stmt *S, Type t) : Data(S, t == StartScope ? 2 : 3) {}
+  // CFGElement(Dtor *S, Type t) : Data(reinterpret_cast<Stmt*>(S), 4) {}
+  Stmt *getStmt() const { return Data.getPointer(); }
+  bool asLValue() const { return Data.getInt() == 1; }
+  bool asStartScope() const { return Data.getInt() == 2; }
+  bool asEndScope() const { return Data.getInt() == 3; }
+  bool asDtor() const { return Data.getInt() == 4; }
+  operator Stmt*() const { return getStmt(); }
+  operator bool() const { return getStmt() != 0; }
+  operator Dtor*() const { return reinterpret_cast<Dtor*>(getStmt()); }
+};
+
+/// CFGBlock - Represents a single basic block in a source-level CFG.
+///  It consists of:
+///
+///  (1) A set of statements/expressions (which may contain subexpressions).
+///  (2) A "terminator" statement (not in the set of statements).
+///  (3) A list of successors and predecessors.
+///
+/// Terminator: The terminator represents the type of control-flow that occurs
+/// at the end of the basic block.  The terminator is a Stmt* referring to an
+/// AST node that has control-flow: if-statements, breaks, loops, etc.
+/// If the control-flow is conditional, the condition expression will appear
+/// within the set of statements in the block (usually the last statement).
+///
+/// Predecessors: the order in the set of predecessors is arbitrary.
+///
+/// Successors: the order in the set of successors is NOT arbitrary.  We
+///  currently have the following orderings based on the terminator:
+///
+///     Terminator       Successor Ordering
+///  -----------------------------------------------------
+///       if            Then Block;  Else Block
+///     ? operator      LHS expression;  RHS expression
+///     &&, ||          expression that uses result of && or ||, RHS
+///
+class CFGBlock {
+  class StatementList {
+    typedef BumpVector<CFGElement> ImplTy;
+    ImplTy Impl;
+  public:
+    StatementList(BumpVectorContext &C) : Impl(C, 4) {}
+    
+    typedef std::reverse_iterator<ImplTy::iterator>       iterator;
+    typedef std::reverse_iterator<ImplTy::const_iterator> const_iterator;
+    typedef ImplTy::iterator                              reverse_iterator;
+    typedef ImplTy::const_iterator                        const_reverse_iterator;
+  
+    void push_back(CFGElement e, BumpVectorContext &C) { Impl.push_back(e, C); }
+    CFGElement front() const { return Impl.back(); }
+    CFGElement back() const { return Impl.front(); }
+    
+    iterator begin() { return Impl.rbegin(); }
+    iterator end() { return Impl.rend(); }
+    const_iterator begin() const { return Impl.rbegin(); }
+    const_iterator end() const { return Impl.rend(); }
+    reverse_iterator rbegin() { return Impl.begin(); }
+    reverse_iterator rend() { return Impl.end(); }
+    const_reverse_iterator rbegin() const { return Impl.begin(); }
+    const_reverse_iterator rend() const { return Impl.end(); }
+
+   CFGElement operator[](size_t i) const  {
+     assert(i < Impl.size());
+     return Impl[Impl.size() - 1 - i];
+   }
+    
+    size_t size() const { return Impl.size(); }
+    bool empty() const { return Impl.empty(); }
+  };
+
+  /// Stmts - The set of statements in the basic block.
+  StatementList Stmts;
+
+  /// Label - An (optional) label that prefixes the executable
+  ///  statements in the block.  When this variable is non-NULL, it is
+  ///  either an instance of LabelStmt, SwitchCase or CXXCatchStmt.
+  Stmt *Label;
+
+  /// Terminator - The terminator for a basic block that
+  ///  indicates the type of control-flow that occurs between a block
+  ///  and its successors.
+  Stmt *Terminator;
+
+  /// LoopTarget - Some blocks are used to represent the "loop edge" to
+  ///  the start of a loop from within the loop body.  This Stmt* will be
+  ///  refer to the loop statement for such blocks (and be null otherwise).
+  const Stmt *LoopTarget;
+
+  /// BlockID - A numerical ID assigned to a CFGBlock during construction
+  ///   of the CFG.
+  unsigned BlockID;
+
+  /// Predecessors/Successors - Keep track of the predecessor / successor
+  /// CFG blocks.
+  typedef BumpVector<CFGBlock*> AdjacentBlocks;
+  AdjacentBlocks Preds;
+  AdjacentBlocks Succs;
+
+public:
+  explicit CFGBlock(unsigned blockid, BumpVectorContext &C)
+    : Stmts(C), Label(NULL), Terminator(NULL), LoopTarget(NULL),
+      BlockID(blockid), Preds(C, 1), Succs(C, 1) {}
+  ~CFGBlock() {}
+
+  // Statement iterators
+  typedef StatementList::iterator                      iterator;
+  typedef StatementList::const_iterator                const_iterator;
+  typedef StatementList::reverse_iterator              reverse_iterator;
+  typedef StatementList::const_reverse_iterator        const_reverse_iterator;
+
+  CFGElement                   front()       const { return Stmts.front();   }
+  CFGElement                   back()        const { return Stmts.back();    }
+
+  iterator                     begin()             { return Stmts.begin();   }
+  iterator                     end()               { return Stmts.end();     }
+  const_iterator               begin()       const { return Stmts.begin();   }
+  const_iterator               end()         const { return Stmts.end();     }
+
+  reverse_iterator             rbegin()            { return Stmts.rbegin();  }
+  reverse_iterator             rend()              { return Stmts.rend();    }
+  const_reverse_iterator       rbegin()      const { return Stmts.rbegin();  }
+  const_reverse_iterator       rend()        const { return Stmts.rend();    }
+
+  unsigned                     size()        const { return Stmts.size();    }
+  bool                         empty()       const { return Stmts.empty();   }
+
+  CFGElement operator[](size_t i) const  { return Stmts[i]; }
+
+  // CFG iterators
+  typedef AdjacentBlocks::iterator                              pred_iterator;
+  typedef AdjacentBlocks::const_iterator                  const_pred_iterator;
+  typedef AdjacentBlocks::reverse_iterator              pred_reverse_iterator;
+  typedef AdjacentBlocks::const_reverse_iterator  const_pred_reverse_iterator;
+
+  typedef AdjacentBlocks::iterator                              succ_iterator;
+  typedef AdjacentBlocks::const_iterator                  const_succ_iterator;
+  typedef AdjacentBlocks::reverse_iterator              succ_reverse_iterator;
+  typedef AdjacentBlocks::const_reverse_iterator  const_succ_reverse_iterator;
+
+  pred_iterator                pred_begin()        { return Preds.begin();   }
+  pred_iterator                pred_end()          { return Preds.end();     }
+  const_pred_iterator          pred_begin()  const { return Preds.begin();   }
+  const_pred_iterator          pred_end()    const { return Preds.end();     }
+
+  pred_reverse_iterator        pred_rbegin()       { return Preds.rbegin();  }
+  pred_reverse_iterator        pred_rend()         { return Preds.rend();    }
+  const_pred_reverse_iterator  pred_rbegin() const { return Preds.rbegin();  }
+  const_pred_reverse_iterator  pred_rend()   const { return Preds.rend();    }
+
+  succ_iterator                succ_begin()        { return Succs.begin();   }
+  succ_iterator                succ_end()          { return Succs.end();     }
+  const_succ_iterator          succ_begin()  const { return Succs.begin();   }
+  const_succ_iterator          succ_end()    const { return Succs.end();     }
+
+  succ_reverse_iterator        succ_rbegin()       { return Succs.rbegin();  }
+  succ_reverse_iterator        succ_rend()         { return Succs.rend();    }
+  const_succ_reverse_iterator  succ_rbegin() const { return Succs.rbegin();  }
+  const_succ_reverse_iterator  succ_rend()   const { return Succs.rend();    }
+
+  unsigned                     succ_size()   const { return Succs.size();    }
+  bool                         succ_empty()  const { return Succs.empty();   }
+
+  unsigned                     pred_size()   const { return Preds.size();    }
+  bool                         pred_empty()  const { return Preds.empty();   }
+
+  // Manipulation of block contents
+
+  void setTerminator(Stmt* Statement) { Terminator = Statement; }
+  void setLabel(Stmt* Statement) { Label = Statement; }
+  void setLoopTarget(const Stmt *loopTarget) { LoopTarget = loopTarget; }
+
+  Stmt* getTerminator() { return Terminator; }
+  const Stmt* getTerminator() const { return Terminator; }
+
+  Stmt* getTerminatorCondition();
+
+  const Stmt* getTerminatorCondition() const {
+    return const_cast<CFGBlock*>(this)->getTerminatorCondition();
+  }
+
+  const Stmt *getLoopTarget() const { return LoopTarget; }
+
+  bool hasBinaryBranchTerminator() const;
+
+  Stmt* getLabel() { return Label; }
+  const Stmt* getLabel() const { return Label; }
+
+  unsigned getBlockID() const { return BlockID; }
+
+  void dump(const CFG *cfg, const LangOptions &LO) const;
+  void print(llvm::raw_ostream &OS, const CFG* cfg, const LangOptions &LO) const;
+  void printTerminator(llvm::raw_ostream &OS, const LangOptions &LO) const;
+  
+  void addSuccessor(CFGBlock* Block, BumpVectorContext &C) {
+    if (Block)
+      Block->Preds.push_back(this, C);
+    Succs.push_back(Block, C);
+  }
+  
+  void appendStmt(Stmt* Statement, BumpVectorContext &C, bool asLValue) {
+      Stmts.push_back(CFGElement(Statement, asLValue), C);
+  }  
+  void StartScope(Stmt* S, BumpVectorContext &C) {
+    Stmts.push_back(CFGElement(S, CFGElement::StartScope), C);
+  }
+  void EndScope(Stmt* S, BumpVectorContext &C) {
+    Stmts.push_back(CFGElement(S, CFGElement::EndScope), C);
+  }
+};
+
+
+/// CFG - Represents a source-level, intra-procedural CFG that represents the
+///  control-flow of a Stmt.  The Stmt can represent an entire function body,
+///  or a single expression.  A CFG will always contain one empty block that
+///  represents the Exit point of the CFG.  A CFG will also contain a designated
+///  Entry block.  The CFG solely represents control-flow; it consists of
+///  CFGBlocks which are simply containers of Stmt*'s in the AST the CFG
+///  was constructed from.
+class CFG {
+public:
+  //===--------------------------------------------------------------------===//
+  // CFG Construction & Manipulation.
+  //===--------------------------------------------------------------------===//
+
+  /// buildCFG - Builds a CFG from an AST.  The responsibility to free the
+  ///   constructed CFG belongs to the caller.
+  static CFG* buildCFG(const Decl *D, Stmt* AST, ASTContext *C,
+                       bool AddEHEdges = false,
+                       bool AddScopes = false /* NOT FULLY IMPLEMENTED.
+                                                 NOT READY FOR GENERAL USE. */);
+
+  /// createBlock - Create a new block in the CFG.  The CFG owns the block;
+  ///  the caller should not directly free it.
+  CFGBlock* createBlock();
+
+  /// setEntry - Set the entry block of the CFG.  This is typically used
+  ///  only during CFG construction.  Most CFG clients expect that the
+  ///  entry block has no predecessors and contains no statements.
+  void setEntry(CFGBlock *B) { Entry = B; }
+
+  /// setIndirectGotoBlock - Set the block used for indirect goto jumps.
+  ///  This is typically used only during CFG construction.
+  void setIndirectGotoBlock(CFGBlock* B) { IndirectGotoBlock = B; }
+
+  //===--------------------------------------------------------------------===//
+  // Block Iterators
+  //===--------------------------------------------------------------------===//
+
+  typedef BumpVector<CFGBlock*>                    CFGBlockListTy;    
+  typedef CFGBlockListTy::iterator                 iterator;
+  typedef CFGBlockListTy::const_iterator           const_iterator;
+  typedef std::reverse_iterator<iterator>          reverse_iterator;
+  typedef std::reverse_iterator<const_iterator>    const_reverse_iterator;
+
+  CFGBlock&                 front()                { return *Blocks.front(); }
+  CFGBlock&                 back()                 { return *Blocks.back(); }
+
+  iterator                  begin()                { return Blocks.begin(); }
+  iterator                  end()                  { return Blocks.end(); }
+  const_iterator            begin()       const    { return Blocks.begin(); }
+  const_iterator            end()         const    { return Blocks.end(); }
+
+  reverse_iterator          rbegin()               { return Blocks.rbegin(); }
+  reverse_iterator          rend()                 { return Blocks.rend(); }
+  const_reverse_iterator    rbegin()      const    { return Blocks.rbegin(); }
+  const_reverse_iterator    rend()        const    { return Blocks.rend(); }
+
+  CFGBlock&                 getEntry()             { return *Entry; }
+  const CFGBlock&           getEntry()    const    { return *Entry; }
+  CFGBlock&                 getExit()              { return *Exit; }
+  const CFGBlock&           getExit()     const    { return *Exit; }
+
+  CFGBlock*        getIndirectGotoBlock() { return IndirectGotoBlock; }
+  const CFGBlock*  getIndirectGotoBlock() const { return IndirectGotoBlock; }
+
+  //===--------------------------------------------------------------------===//
+  // Member templates useful for various batch operations over CFGs.
+  //===--------------------------------------------------------------------===//
+
+  template <typename CALLBACK>
+  void VisitBlockStmts(CALLBACK& O) const {
+    for (const_iterator I=begin(), E=end(); I != E; ++I)
+      for (CFGBlock::const_iterator BI=(*I)->begin(), BE=(*I)->end();
+           BI != BE; ++BI)
+        O(*BI);
+  }
+
+  //===--------------------------------------------------------------------===//
+  // CFG Introspection.
+  //===--------------------------------------------------------------------===//
+
+  struct   BlkExprNumTy {
+    const signed Idx;
+    explicit BlkExprNumTy(signed idx) : Idx(idx) {}
+    explicit BlkExprNumTy() : Idx(-1) {}
+    operator bool() const { return Idx >= 0; }
+    operator unsigned() const { assert(Idx >=0); return (unsigned) Idx; }
+  };
+
+  bool          isBlkExpr(const Stmt* S) { return getBlkExprNum(S); }
+  BlkExprNumTy  getBlkExprNum(const Stmt* S);
+  unsigned      getNumBlkExprs();
+
+  /// getNumBlockIDs - Returns the total number of BlockIDs allocated (which
+  /// start at 0).
+  unsigned getNumBlockIDs() const { return NumBlockIDs; }
+
+  //===--------------------------------------------------------------------===//
+  // CFG Debugging: Pretty-Printing and Visualization.
+  //===--------------------------------------------------------------------===//
+
+  void viewCFG(const LangOptions &LO) const;
+  void print(llvm::raw_ostream& OS, const LangOptions &LO) const;
+  void dump(const LangOptions &LO) const;
+
+  //===--------------------------------------------------------------------===//
+  // Internal: constructors and data.
+  //===--------------------------------------------------------------------===//
+
+  CFG() : Entry(NULL), Exit(NULL), IndirectGotoBlock(NULL), NumBlockIDs(0),
+          BlkExprMap(NULL), Blocks(BlkBVC, 10) {}
+
+  ~CFG();
+
+  llvm::BumpPtrAllocator& getAllocator() {
+    return BlkBVC.getAllocator();
+  }
+  
+  BumpVectorContext &getBumpVectorContext() {
+    return BlkBVC;
+  }
+
+private:
+  CFGBlock* Entry;
+  CFGBlock* Exit;
+  CFGBlock* IndirectGotoBlock;  // Special block to contain collective dispatch
+                                // for indirect gotos
+  unsigned  NumBlockIDs;
+
+  // BlkExprMap - An opaque pointer to prevent inclusion of DenseMap.h.
+  //  It represents a map from Expr* to integers to record the set of
+  //  block-level expressions and their "statement number" in the CFG.
+  void*     BlkExprMap;
+  
+  BumpVectorContext BlkBVC;
+  
+  CFGBlockListTy Blocks;
+
+};
+} // end namespace clang
+
+//===----------------------------------------------------------------------===//
+// GraphTraits specializations for CFG basic block graphs (source-level CFGs)
+//===----------------------------------------------------------------------===//
+
+namespace llvm {
+
+/// Implement simplify_type for CFGElement, so that we can dyn_cast from
+/// CFGElement to a specific Stmt class.
+template <> struct simplify_type<const ::clang::CFGElement> {
+  typedef ::clang::Stmt* SimpleType;
+  static SimpleType getSimplifiedValue(const ::clang::CFGElement &Val) {
+    return Val.getStmt();
+  }
+};
+  
+template <> struct simplify_type< ::clang::CFGElement> 
+  : public simplify_type<const ::clang::CFGElement> {};
+  
+// Traits for: CFGBlock
+
+template <> struct GraphTraits< ::clang::CFGBlock* > {
+  typedef ::clang::CFGBlock NodeType;
+  typedef ::clang::CFGBlock::succ_iterator ChildIteratorType;
+
+  static NodeType* getEntryNode(::clang::CFGBlock* BB)
+  { return BB; }
+
+  static inline ChildIteratorType child_begin(NodeType* N)
+  { return N->succ_begin(); }
+
+  static inline ChildIteratorType child_end(NodeType* N)
+  { return N->succ_end(); }
+};
+
+template <> struct GraphTraits< const ::clang::CFGBlock* > {
+  typedef const ::clang::CFGBlock NodeType;
+  typedef ::clang::CFGBlock::const_succ_iterator ChildIteratorType;
+
+  static NodeType* getEntryNode(const clang::CFGBlock* BB)
+  { return BB; }
+
+  static inline ChildIteratorType child_begin(NodeType* N)
+  { return N->succ_begin(); }
+
+  static inline ChildIteratorType child_end(NodeType* N)
+  { return N->succ_end(); }
+};
+
+template <> struct GraphTraits<Inverse<const ::clang::CFGBlock*> > {
+  typedef const ::clang::CFGBlock NodeType;
+  typedef ::clang::CFGBlock::const_pred_iterator ChildIteratorType;
+
+  static NodeType *getEntryNode(Inverse<const ::clang::CFGBlock*> G)
+  { return G.Graph; }
+
+  static inline ChildIteratorType child_begin(NodeType* N)
+  { return N->pred_begin(); }
+
+  static inline ChildIteratorType child_end(NodeType* N)
+  { return N->pred_end(); }
+};
+
+// Traits for: CFG
+
+template <> struct GraphTraits< ::clang::CFG* >
+    : public GraphTraits< ::clang::CFGBlock* >  {
+
+  typedef ::clang::CFG::iterator nodes_iterator;
+
+  static NodeType *getEntryNode(::clang::CFG* F) { return &F->getEntry(); }
+  static nodes_iterator nodes_begin(::clang::CFG* F) { return F->begin(); }
+  static nodes_iterator nodes_end(::clang::CFG* F) { return F->end(); }
+};
+
+template <> struct GraphTraits<const ::clang::CFG* >
+    : public GraphTraits<const ::clang::CFGBlock* >  {
+
+  typedef ::clang::CFG::const_iterator nodes_iterator;
+
+  static NodeType *getEntryNode( const ::clang::CFG* F) {
+    return &F->getEntry();
+  }
+  static nodes_iterator nodes_begin( const ::clang::CFG* F) {
+    return F->begin();
+  }
+  static nodes_iterator nodes_end( const ::clang::CFG* F) {
+    return F->end();
+  }
+};
+
+template <> struct GraphTraits<Inverse<const ::clang::CFG*> >
+  : public GraphTraits<Inverse<const ::clang::CFGBlock*> > {
+
+  typedef ::clang::CFG::const_iterator nodes_iterator;
+
+  static NodeType *getEntryNode(const ::clang::CFG* F) { return &F->getExit(); }
+  static nodes_iterator nodes_begin(const ::clang::CFG* F) { return F->begin();}
+  static nodes_iterator nodes_end(const ::clang::CFG* F) { return F->end(); }
+};
+} // end llvm namespace
+#endif
diff --git a/include/clang/Analysis/FlowSensitive/DataflowSolver.h b/include/clang/Analysis/FlowSensitive/DataflowSolver.h
new file mode 100644
index 0000000..3c76201
--- /dev/null
+++ b/include/clang/Analysis/FlowSensitive/DataflowSolver.h
@@ -0,0 +1,320 @@
+//===--- DataflowSolver.h - Skeleton Dataflow Analysis Code -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines skeleton code for implementing dataflow analyses.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSES_DATAFLOW_SOLVER
+#define LLVM_CLANG_ANALYSES_DATAFLOW_SOLVER
+
+#include "clang/Analysis/CFG.h"
+#include "clang/Analysis/ProgramPoint.h"
+#include "clang/Analysis/FlowSensitive/DataflowValues.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVector.h"
+#include "functional" // STL
+
+namespace clang {
+
+//===----------------------------------------------------------------------===//
+/// DataflowWorkListTy - Data structure representing the worklist used for
+///  dataflow algorithms.
+//===----------------------------------------------------------------------===//
+
+class DataflowWorkListTy {
+  llvm::DenseMap<const CFGBlock*, unsigned char> BlockSet;
+  llvm::SmallVector<const CFGBlock *, 10> BlockQueue;
+public:
+  /// enqueue - Add a block to the worklist.  Blocks already on the
+  ///  worklist are not added a second time.
+  void enqueue(const CFGBlock* B) {
+    unsigned char &x = BlockSet[B];
+    if (x == 1)
+      return;
+    x = 1;
+    BlockQueue.push_back(B);
+  }
+
+  /// dequeue - Remove a block from the worklist.
+  const CFGBlock* dequeue() {
+    assert(!BlockQueue.empty());
+    const CFGBlock *B = BlockQueue.back();
+    BlockQueue.pop_back();
+    BlockSet[B] = 0;
+    return B;
+  }
+
+  /// isEmpty - Return true if the worklist is empty.
+  bool isEmpty() const { return BlockQueue.empty(); }
+};
+
+//===----------------------------------------------------------------------===//
+// BlockItrTraits - Traits classes that allow transparent iteration
+//  over successors/predecessors of a block depending on the direction
+//  of our dataflow analysis.
+//===----------------------------------------------------------------------===//
+
+namespace dataflow {
+template<typename Tag> struct ItrTraits {};
+
+template <> struct ItrTraits<forward_analysis_tag> {
+  typedef CFGBlock::const_pred_iterator PrevBItr;
+  typedef CFGBlock::const_succ_iterator NextBItr;
+  typedef CFGBlock::const_iterator      StmtItr;
+
+  static PrevBItr PrevBegin(const CFGBlock* B) { return B->pred_begin(); }
+  static PrevBItr PrevEnd(const CFGBlock* B) { return B->pred_end(); }
+
+  static NextBItr NextBegin(const CFGBlock* B) { return B->succ_begin(); }
+  static NextBItr NextEnd(const CFGBlock* B) { return B->succ_end(); }
+
+  static StmtItr StmtBegin(const CFGBlock* B) { return B->begin(); }
+  static StmtItr StmtEnd(const CFGBlock* B) { return B->end(); }
+
+  static BlockEdge PrevEdge(const CFGBlock* B, const CFGBlock* Prev) {
+    return BlockEdge(Prev, B, 0);
+  }
+
+  static BlockEdge NextEdge(const CFGBlock* B, const CFGBlock* Next) {
+    return BlockEdge(B, Next, 0);
+  }
+};
+
+template <> struct ItrTraits<backward_analysis_tag> {
+  typedef CFGBlock::const_succ_iterator    PrevBItr;
+  typedef CFGBlock::const_pred_iterator    NextBItr;
+  typedef CFGBlock::const_reverse_iterator StmtItr;
+
+  static PrevBItr PrevBegin(const CFGBlock* B) { return B->succ_begin(); }
+  static PrevBItr PrevEnd(const CFGBlock* B) { return B->succ_end(); }
+
+  static NextBItr NextBegin(const CFGBlock* B) { return B->pred_begin(); }
+  static NextBItr NextEnd(const CFGBlock* B) { return B->pred_end(); }
+
+  static StmtItr StmtBegin(const CFGBlock* B) { return B->rbegin(); }
+  static StmtItr StmtEnd(const CFGBlock* B) { return B->rend(); }
+
+  static BlockEdge PrevEdge(const CFGBlock* B, const CFGBlock* Prev) {
+    return BlockEdge(B, Prev, 0);
+  }
+
+  static BlockEdge NextEdge(const CFGBlock* B, const CFGBlock* Next) {
+    return BlockEdge(Next, B, 0);
+  }
+};
+} // end namespace dataflow
+
+//===----------------------------------------------------------------------===//
+/// DataflowSolverTy - Generic dataflow solver.
+//===----------------------------------------------------------------------===//
+
+template <typename _DFValuesTy,      // Usually a subclass of DataflowValues
+          typename _TransferFuncsTy,
+          typename _MergeOperatorTy,
+          typename _Equal = std::equal_to<typename _DFValuesTy::ValTy> >
+class DataflowSolver {
+
+  //===----------------------------------------------------===//
+  // Type declarations.
+  //===----------------------------------------------------===//
+
+public:
+  typedef _DFValuesTy                              DFValuesTy;
+  typedef _TransferFuncsTy                         TransferFuncsTy;
+  typedef _MergeOperatorTy                         MergeOperatorTy;
+
+  typedef typename _DFValuesTy::AnalysisDirTag     AnalysisDirTag;
+  typedef typename _DFValuesTy::ValTy              ValTy;
+  typedef typename _DFValuesTy::EdgeDataMapTy      EdgeDataMapTy;
+  typedef typename _DFValuesTy::BlockDataMapTy     BlockDataMapTy;
+
+  typedef dataflow::ItrTraits<AnalysisDirTag>      ItrTraits;
+  typedef typename ItrTraits::NextBItr             NextBItr;
+  typedef typename ItrTraits::PrevBItr             PrevBItr;
+  typedef typename ItrTraits::StmtItr              StmtItr;
+
+  //===----------------------------------------------------===//
+  // External interface: constructing and running the solver.
+  //===----------------------------------------------------===//
+
+public:
+  DataflowSolver(DFValuesTy& d) : D(d), TF(d.getAnalysisData()) {}
+  ~DataflowSolver() {}
+
+  /// runOnCFG - Computes dataflow values for all blocks in a CFG.
+  void runOnCFG(CFG& cfg, bool recordStmtValues = false) {
+    // Set initial dataflow values and boundary conditions.
+    D.InitializeValues(cfg);
+    // Solve the dataflow equations.  This will populate D.EdgeDataMap
+    // with dataflow values.
+    SolveDataflowEquations(cfg, recordStmtValues);
+  }
+
+  /// runOnBlock - Computes dataflow values for a given block.  This
+  ///  should usually be invoked only after previously computing
+  ///  dataflow values using runOnCFG, as runOnBlock is intended to
+  ///  only be used for querying the dataflow values within a block
+  ///  with and Observer object.
+  void runOnBlock(const CFGBlock* B, bool recordStmtValues) {
+    BlockDataMapTy& M = D.getBlockDataMap();
+    typename BlockDataMapTy::iterator I = M.find(B);
+
+    if (I != M.end()) {
+      TF.getVal().copyValues(I->second);
+      ProcessBlock(B, recordStmtValues, AnalysisDirTag());
+    }
+  }
+
+  void runOnBlock(const CFGBlock& B, bool recordStmtValues) {
+    runOnBlock(&B, recordStmtValues);
+  }
+  void runOnBlock(CFG::iterator& I, bool recordStmtValues) {
+    runOnBlock(*I, recordStmtValues);
+  }
+  void runOnBlock(CFG::const_iterator& I, bool recordStmtValues) {
+    runOnBlock(*I, recordStmtValues);
+  }
+
+  void runOnAllBlocks(const CFG& cfg, bool recordStmtValues = false) {
+    for (CFG::const_iterator I=cfg.begin(), E=cfg.end(); I!=E; ++I)
+      runOnBlock(I, recordStmtValues);
+  }
+
+  //===----------------------------------------------------===//
+  // Internal solver logic.
+  //===----------------------------------------------------===//
+
+private:
+
+  /// SolveDataflowEquations - Perform the actual worklist algorithm
+  ///  to compute dataflow values.
+  void SolveDataflowEquations(CFG& cfg, bool recordStmtValues) {
+    EnqueueBlocksOnWorklist(cfg, AnalysisDirTag());
+
+    while (!WorkList.isEmpty()) {
+      const CFGBlock* B = WorkList.dequeue();
+      ProcessMerge(cfg, B);
+      ProcessBlock(B, recordStmtValues, AnalysisDirTag());
+      UpdateEdges(cfg, B, TF.getVal());
+    }
+  }
+
+  void EnqueueBlocksOnWorklist(CFG &cfg, dataflow::forward_analysis_tag) {
+    // Enqueue all blocks to ensure the dataflow values are computed
+    // for every block.  Not all blocks are guaranteed to reach the exit block.
+    for (CFG::iterator I=cfg.begin(), E=cfg.end(); I!=E; ++I)
+      WorkList.enqueue(&**I);
+  }
+
+  void EnqueueBlocksOnWorklist(CFG &cfg, dataflow::backward_analysis_tag) {
+    // Enqueue all blocks to ensure the dataflow values are computed
+    // for every block.  Not all blocks are guaranteed to reach the exit block.
+    // Enqueue in reverse order since that will more likely match with
+    // the order they should ideally processed by the dataflow algorithm.
+    for (CFG::reverse_iterator I=cfg.rbegin(), E=cfg.rend(); I!=E; ++I)
+      WorkList.enqueue(&**I);
+  }
+
+  void ProcessMerge(CFG& cfg, const CFGBlock* B) {
+    ValTy& V = TF.getVal();
+    TF.SetTopValue(V);
+
+    // Merge dataflow values from all predecessors of this block.
+    MergeOperatorTy Merge;
+
+    EdgeDataMapTy& M = D.getEdgeDataMap();
+    bool firstMerge = true;
+
+    for (PrevBItr I=ItrTraits::PrevBegin(B),E=ItrTraits::PrevEnd(B); I!=E; ++I){
+
+      CFGBlock *PrevBlk = *I;
+
+      if (!PrevBlk)
+        continue;
+
+      typename EdgeDataMapTy::iterator EI =
+        M.find(ItrTraits::PrevEdge(B, PrevBlk));
+
+      if (EI != M.end()) {
+        if (firstMerge) {
+          firstMerge = false;
+          V.copyValues(EI->second);
+        }
+        else
+          Merge(V, EI->second);
+      }
+    }
+
+    // Set the data for the block.
+    D.getBlockDataMap()[B].copyValues(V);
+  }
+
+  /// ProcessBlock - Process the transfer functions for a given block.
+  void ProcessBlock(const CFGBlock* B, bool recordStmtValues,
+                    dataflow::forward_analysis_tag) {
+
+    for (StmtItr I=ItrTraits::StmtBegin(B), E=ItrTraits::StmtEnd(B); I!=E;++I)
+      ProcessStmt(*I, recordStmtValues, AnalysisDirTag());
+
+    TF.VisitTerminator(const_cast<CFGBlock*>(B));
+  }
+
+  void ProcessBlock(const CFGBlock* B, bool recordStmtValues,
+                    dataflow::backward_analysis_tag) {
+
+    TF.VisitTerminator(const_cast<CFGBlock*>(B));
+
+    for (StmtItr I=ItrTraits::StmtBegin(B), E=ItrTraits::StmtEnd(B); I!=E;++I)
+      ProcessStmt(*I, recordStmtValues, AnalysisDirTag());
+  }
+
+  void ProcessStmt(const Stmt* S, bool record, dataflow::forward_analysis_tag) {
+    if (record) D.getStmtDataMap()[S] = TF.getVal();
+    TF.BlockStmt_Visit(const_cast<Stmt*>(S));
+  }
+
+  void ProcessStmt(const Stmt* S, bool record, dataflow::backward_analysis_tag){
+    TF.BlockStmt_Visit(const_cast<Stmt*>(S));
+    if (record) D.getStmtDataMap()[S] = TF.getVal();
+  }
+
+  /// UpdateEdges - After processing the transfer functions for a
+  ///   block, update the dataflow value associated with the block's
+  ///   outgoing/incoming edges (depending on whether we do a
+  //    forward/backward analysis respectively)
+  void UpdateEdges(CFG& cfg, const CFGBlock* B, ValTy& V) {
+    for (NextBItr I=ItrTraits::NextBegin(B), E=ItrTraits::NextEnd(B); I!=E; ++I)
+      if (CFGBlock *NextBlk = *I)
+        UpdateEdgeValue(ItrTraits::NextEdge(B, NextBlk),V, NextBlk);
+  }
+
+  /// UpdateEdgeValue - Update the value associated with a given edge.
+  void UpdateEdgeValue(BlockEdge E, ValTy& V, const CFGBlock* TargetBlock) {
+    EdgeDataMapTy& M = D.getEdgeDataMap();
+    typename EdgeDataMapTy::iterator I = M.find(E);
+
+    if (I == M.end()) {  // First computed value for this edge?
+      M[E].copyValues(V);
+      WorkList.enqueue(TargetBlock);
+    }
+    else if (!_Equal()(V,I->second)) {
+      I->second.copyValues(V);
+      WorkList.enqueue(TargetBlock);
+    }
+  }
+
+private:
+  DFValuesTy& D;
+  DataflowWorkListTy WorkList;
+  TransferFuncsTy TF;
+};
+
+} // end namespace clang
+#endif
diff --git a/include/clang/Analysis/FlowSensitive/DataflowValues.h b/include/clang/Analysis/FlowSensitive/DataflowValues.h
new file mode 100644
index 0000000..7aa15c5
--- /dev/null
+++ b/include/clang/Analysis/FlowSensitive/DataflowValues.h
@@ -0,0 +1,172 @@
+//===--- DataflowValues.h - Data structure for dataflow values --*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a skeleton data structure for encapsulating the dataflow
+// values for a CFG.  Typically this is subclassed to provide methods for
+// computing these values from a CFG.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSES_DATAFLOW_VALUES
+#define LLVM_CLANG_ANALYSES_DATAFLOW_VALUES
+
+#include "clang/Analysis/CFG.h"
+#include "clang/Analysis/ProgramPoint.h"
+#include "llvm/ADT/DenseMap.h"
+
+//===----------------------------------------------------------------------===//
+/// Dataflow Directional Tag Classes.  These are used for tag dispatching
+///  within the dataflow solver/transfer functions to determine what direction
+///  a dataflow analysis flows.
+//===----------------------------------------------------------------------===//
+
+namespace clang {
+namespace dataflow {
+  struct forward_analysis_tag {};
+  struct backward_analysis_tag {};
+} // end namespace dataflow
+
+//===----------------------------------------------------------------------===//
+/// DataflowValues.  Container class to store dataflow values for a CFG.
+//===----------------------------------------------------------------------===//
+
+template <typename ValueTypes,
+          typename _AnalysisDirTag = dataflow::forward_analysis_tag >
+class DataflowValues {
+
+  //===--------------------------------------------------------------------===//
+  // Type declarations.
+  //===--------------------------------------------------------------------===//
+
+public:
+  typedef typename ValueTypes::ValTy               ValTy;
+  typedef typename ValueTypes::AnalysisDataTy      AnalysisDataTy;
+  typedef _AnalysisDirTag                          AnalysisDirTag;
+  typedef llvm::DenseMap<ProgramPoint, ValTy>      EdgeDataMapTy;
+  typedef llvm::DenseMap<const CFGBlock*, ValTy>   BlockDataMapTy;
+  typedef llvm::DenseMap<const Stmt*, ValTy>       StmtDataMapTy;
+
+  //===--------------------------------------------------------------------===//
+  // Predicates.
+  //===--------------------------------------------------------------------===//
+
+public:
+  /// isForwardAnalysis - Returns true if the dataflow values are computed
+  ///  from a forward analysis.
+  bool isForwardAnalysis() { return isForwardAnalysis(AnalysisDirTag()); }
+
+  /// isBackwardAnalysis - Returns true if the dataflow values are computed
+  ///  from a backward analysis.
+  bool isBackwardAnalysis() { return !isForwardAnalysis(); }
+
+private:
+  bool isForwardAnalysis(dataflow::forward_analysis_tag)  { return true; }
+  bool isForwardAnalysis(dataflow::backward_analysis_tag) { return false; }
+
+  //===--------------------------------------------------------------------===//
+  // Initialization and accessors methods.
+  //===--------------------------------------------------------------------===//
+
+public:
+  DataflowValues() : StmtDataMap(NULL) {}
+  ~DataflowValues() { delete StmtDataMap; }
+
+  /// InitializeValues - Invoked by the solver to initialize state needed for
+  ///  dataflow analysis.  This method is usually specialized by subclasses.
+  void InitializeValues(const CFG& cfg) {}
+
+
+  /// getEdgeData - Retrieves the dataflow values associated with a
+  ///  CFG edge.
+  ValTy& getEdgeData(const BlockEdge& E) {
+    typename EdgeDataMapTy::iterator I = EdgeDataMap.find(E);
+    assert (I != EdgeDataMap.end() && "No data associated with Edge.");
+    return I->second;
+  }
+
+  const ValTy& getEdgeData(const BlockEdge& E) const {
+    return reinterpret_cast<DataflowValues*>(this)->getEdgeData(E);
+  }
+
+  /// getBlockData - Retrieves the dataflow values associated with a
+  ///  specified CFGBlock.  If the dataflow analysis is a forward analysis,
+  ///  this data is associated with the END of the block.  If the analysis
+  ///  is a backwards analysis, it is associated with the ENTRY of the block.
+  ValTy& getBlockData(const CFGBlock* B) {
+    typename BlockDataMapTy::iterator I = BlockDataMap.find(B);
+    assert (I != BlockDataMap.end() && "No data associated with block.");
+    return I->second;
+  }
+
+  const ValTy& getBlockData(const CFGBlock* B) const {
+    return const_cast<DataflowValues*>(this)->getBlockData(B);
+  }
+
+  /// getStmtData - Retrieves the dataflow values associated with a
+  ///  specified Stmt.  If the dataflow analysis is a forward analysis,
+  ///  this data corresponds to the point immediately before a Stmt.
+  ///  If the analysis is a backwards analysis, it is associated with
+  ///  the point after a Stmt.  This data is only computed for block-level
+  ///  expressions, and only when requested when the analysis is executed.
+  ValTy& getStmtData(const Stmt* S) {
+    assert (StmtDataMap && "Dataflow values were not computed for statements.");
+    typename StmtDataMapTy::iterator I = StmtDataMap->find(S);
+    assert (I != StmtDataMap->end() && "No data associated with statement.");
+    return I->second;
+  }
+
+  const ValTy& getStmtData(const Stmt* S) const {
+    return const_cast<DataflowValues*>(this)->getStmtData(S);
+  }
+
+  /// getEdgeDataMap - Retrieves the internal map between CFG edges and
+  ///  dataflow values.  Usually used by a dataflow solver to compute
+  ///  values for blocks.
+  EdgeDataMapTy& getEdgeDataMap() { return EdgeDataMap; }
+  const EdgeDataMapTy& getEdgeDataMap() const { return EdgeDataMap; }
+
+  /// getBlockDataMap - Retrieves the internal map between CFGBlocks and
+  /// dataflow values.  If the dataflow analysis operates in the forward
+  /// direction, the values correspond to the dataflow values at the start
+  /// of the block.  Otherwise, for a backward analysis, the values correpsond
+  /// to the dataflow values at the end of the block.
+  BlockDataMapTy& getBlockDataMap() { return BlockDataMap; }
+  const BlockDataMapTy& getBlockDataMap() const { return BlockDataMap; }
+
+  /// getStmtDataMap - Retrieves the internal map between Stmts and
+  /// dataflow values.
+  StmtDataMapTy& getStmtDataMap() {
+    if (!StmtDataMap) StmtDataMap = new StmtDataMapTy();
+    return *StmtDataMap;
+  }
+
+  const StmtDataMapTy& getStmtDataMap() const {
+    return const_cast<DataflowValues*>(this)->getStmtDataMap();
+  }
+
+  /// getAnalysisData - Retrieves the meta data associated with a
+  ///  dataflow analysis for analyzing a particular CFG.
+  ///  This is typically consumed by transfer function code (via the solver).
+  ///  This can also be used by subclasses to interpret the dataflow values.
+  AnalysisDataTy& getAnalysisData() { return AnalysisData; }
+  const AnalysisDataTy& getAnalysisData() const { return AnalysisData; }
+
+  //===--------------------------------------------------------------------===//
+  // Internal data.
+  //===--------------------------------------------------------------------===//
+
+protected:
+  EdgeDataMapTy      EdgeDataMap;
+  BlockDataMapTy     BlockDataMap;
+  StmtDataMapTy*     StmtDataMap;
+  AnalysisDataTy     AnalysisData;
+};
+
+} // end namespace clang
+#endif
diff --git a/include/clang/Analysis/ProgramPoint.h b/include/clang/Analysis/ProgramPoint.h
new file mode 100644
index 0000000..fb8d4d5
--- /dev/null
+++ b/include/clang/Analysis/ProgramPoint.h
@@ -0,0 +1,380 @@
+//==- ProgramPoint.h - Program Points for Path-Sensitive Analysis --*- C++ -*-//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the interface ProgramPoint, which identifies a
+//  distinct location in a function.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_PROGRAM_POINT
+#define LLVM_CLANG_ANALYSIS_PROGRAM_POINT
+
+#include "clang/Analysis/CFG.h"
+#include "llvm/System/DataTypes.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/Support/Casting.h"
+#include <cassert>
+#include <utility>
+
+namespace clang {
+
+class LocationContext;
+class FunctionDecl;
+
+class ProgramPoint {
+public:
+  enum Kind { BlockEdgeKind,
+              BlockEntranceKind,
+              BlockExitKind,
+              PreStmtKind,
+              PostStmtKind,
+              PreLoadKind,
+              PostLoadKind,
+              PreStoreKind,
+              PostStoreKind,
+              PostPurgeDeadSymbolsKind,
+              PostStmtCustomKind,
+              PostLValueKind,
+              CallEnterKind,
+              CallExitKind,
+              MinPostStmtKind = PostStmtKind,
+              MaxPostStmtKind = PostLValueKind };
+
+private:
+  std::pair<const void *, const void *> Data;
+  Kind K;
+
+  // The LocationContext could be NULL to allow ProgramPoint to be used in
+  // context insensitive analysis.
+  const LocationContext *L;
+  const void *Tag;
+
+protected:
+  ProgramPoint(const void* P, Kind k, const LocationContext *l,
+               const void *tag = 0)
+    : Data(P, NULL), K(k), L(l), Tag(tag) {}
+
+  ProgramPoint(const void* P1, const void* P2, Kind k, const LocationContext *l,
+               const void *tag = 0)
+    : Data(P1, P2), K(k), L(l), Tag(tag) {}
+
+protected:
+  const void* getData1() const { return Data.first; }
+  const void* getData2() const { return Data.second; }
+  const void *getTag() const { return Tag; }
+
+public:
+  Kind getKind() const { return K; }
+
+  const LocationContext *getLocationContext() const { return L; }
+
+  // For use with DenseMap.  This hash is probably slow.
+  unsigned getHashValue() const {
+    llvm::FoldingSetNodeID ID;
+    Profile(ID);
+    return ID.ComputeHash();
+  }
+
+  static bool classof(const ProgramPoint*) { return true; }
+
+  bool operator==(const ProgramPoint & RHS) const {
+    return K == RHS.K && Data == RHS.Data && L == RHS.L && Tag == RHS.Tag;
+  }
+
+  bool operator!=(const ProgramPoint& RHS) const {
+    return K != RHS.K || Data != RHS.Data || L != RHS.L || Tag != RHS.Tag;
+  }
+
+  void Profile(llvm::FoldingSetNodeID& ID) const {
+    ID.AddInteger((unsigned) K);
+    ID.AddPointer(Data.first);
+    ID.AddPointer(Data.second);
+    ID.AddPointer(L);
+    ID.AddPointer(Tag);
+  }
+};
+
+class BlockEntrance : public ProgramPoint {
+public:
+  BlockEntrance(const CFGBlock* B, const LocationContext *L,
+                const void *tag = 0)
+    : ProgramPoint(B, BlockEntranceKind, L, tag) {}
+
+  CFGBlock* getBlock() const {
+    return const_cast<CFGBlock*>(reinterpret_cast<const CFGBlock*>(getData1()));
+  }
+
+  CFGElement getFirstElement() const {
+    const CFGBlock* B = getBlock();
+    return B->empty() ? CFGElement() : B->front();
+  }
+  
+  Stmt *getFirstStmt() const {
+    return getFirstElement().getStmt();
+  }
+
+  static bool classof(const ProgramPoint* Location) {
+    return Location->getKind() == BlockEntranceKind;
+  }
+};
+
+class BlockExit : public ProgramPoint {
+public:
+  BlockExit(const CFGBlock* B, const LocationContext *L)
+    : ProgramPoint(B, BlockExitKind, L) {}
+
+  CFGBlock* getBlock() const {
+    return const_cast<CFGBlock*>(reinterpret_cast<const CFGBlock*>(getData1()));
+  }
+
+  Stmt* getLastStmt() const {
+    const CFGBlock* B = getBlock();
+    return B->empty() ? CFGElement() : B->back();
+  }
+
+  Stmt* getTerminator() const {
+    return getBlock()->getTerminator();
+  }
+
+  static bool classof(const ProgramPoint* Location) {
+    return Location->getKind() == BlockExitKind;
+  }
+};
+
+class StmtPoint : public ProgramPoint {
+public:
+  StmtPoint(const Stmt *S, const void *p2, Kind k, const LocationContext *L,
+            const void *tag)
+    : ProgramPoint(S, p2, k, L, tag) {}
+
+  const Stmt *getStmt() const { return (const Stmt*) getData1(); }
+
+  template <typename T>
+  const T* getStmtAs() const { return llvm::dyn_cast<T>(getStmt()); }
+
+  static bool classof(const ProgramPoint* Location) {
+    unsigned k = Location->getKind();
+    return k >= PreStmtKind && k <= MaxPostStmtKind;
+  }
+};
+
+
+class PreStmt : public StmtPoint {
+public:
+  PreStmt(const Stmt *S, const LocationContext *L, const void *tag,
+          const Stmt *SubStmt = 0)
+    : StmtPoint(S, SubStmt, PreStmtKind, L, tag) {}
+
+  const Stmt *getSubStmt() const { return (const Stmt*) getData2(); }
+
+  static bool classof(const ProgramPoint* Location) {
+    return Location->getKind() == PreStmtKind;
+  }
+};
+
+class PostStmt : public StmtPoint {
+protected:
+  PostStmt(const Stmt* S, Kind k, const LocationContext *L, const void *tag = 0)
+    : StmtPoint(S, NULL, k, L, tag) {}
+
+  PostStmt(const Stmt* S, const void* data, Kind k, const LocationContext *L,
+           const void *tag =0)
+    : StmtPoint(S, data, k, L, tag) {}
+
+public:
+  explicit PostStmt(const Stmt* S, const LocationContext *L,const void *tag = 0)
+    : StmtPoint(S, NULL, PostStmtKind, L, tag) {}
+
+  static bool classof(const ProgramPoint* Location) {
+    unsigned k = Location->getKind();
+    return k >= MinPostStmtKind && k <= MaxPostStmtKind;
+  }
+};
+
+class PostStmtCustom : public PostStmt {
+public:
+  PostStmtCustom(const Stmt* S,
+                 const std::pair<const void*, const void*>* TaggedData,\
+                 const LocationContext *L)
+    : PostStmt(S, TaggedData, PostStmtCustomKind, L) {}
+
+  const std::pair<const void*, const void*>& getTaggedPair() const {
+    return
+      *reinterpret_cast<const std::pair<const void*, const void*>*>(getData2());
+  }
+
+  const void* getTag() const { return getTaggedPair().first; }
+
+  const void* getTaggedData() const { return getTaggedPair().second; }
+
+  static bool classof(const ProgramPoint* Location) {
+    return Location->getKind() == PostStmtCustomKind;
+  }
+};
+
+  
+class LocationCheck : public StmtPoint {
+protected:
+  LocationCheck(const Stmt *S, const LocationContext *L,
+                ProgramPoint::Kind K, const void *tag)
+    : StmtPoint(S, NULL, K, L, tag) {}
+    
+  static bool classof(const ProgramPoint *location) {
+    unsigned k = location->getKind();
+    return k == PreLoadKind || k == PreStoreKind;
+  }
+};
+  
+class PreLoad : public LocationCheck {
+public:
+  PreLoad(const Stmt *S, const LocationContext *L, const void *tag = 0)
+    : LocationCheck(S, L, PreLoadKind, tag) {}
+  
+  static bool classof(const ProgramPoint *location) {
+    return location->getKind() == PreLoadKind;
+  }
+};
+
+class PreStore : public LocationCheck {
+public:
+  PreStore(const Stmt *S, const LocationContext *L, const void *tag = 0)
+  : LocationCheck(S, L, PreStoreKind, tag) {}
+  
+  static bool classof(const ProgramPoint *location) {
+    return location->getKind() == PreStoreKind;
+  }
+};
+
+class PostLoad : public PostStmt {
+public:
+  PostLoad(const Stmt* S, const LocationContext *L, const void *tag = 0)
+    : PostStmt(S, PostLoadKind, L, tag) {}
+
+  static bool classof(const ProgramPoint* Location) {
+    return Location->getKind() == PostLoadKind;
+  }
+};
+
+class PostStore : public PostStmt {
+public:
+  PostStore(const Stmt* S, const LocationContext *L, const void *tag = 0)
+    : PostStmt(S, PostStoreKind, L, tag) {}
+
+  static bool classof(const ProgramPoint* Location) {
+    return Location->getKind() == PostStoreKind;
+  }
+};
+
+class PostLValue : public PostStmt {
+public:
+  PostLValue(const Stmt* S, const LocationContext *L, const void *tag = 0)
+    : PostStmt(S, PostLValueKind, L, tag) {}
+
+  static bool classof(const ProgramPoint* Location) {
+    return Location->getKind() == PostLValueKind;
+  }
+};
+
+class PostPurgeDeadSymbols : public PostStmt {
+public:
+  PostPurgeDeadSymbols(const Stmt* S, const LocationContext *L,
+                       const void *tag = 0)
+    : PostStmt(S, PostPurgeDeadSymbolsKind, L, tag) {}
+
+  static bool classof(const ProgramPoint* Location) {
+    return Location->getKind() == PostPurgeDeadSymbolsKind;
+  }
+};
+
+class BlockEdge : public ProgramPoint {
+public:
+  BlockEdge(const CFGBlock* B1, const CFGBlock* B2, const LocationContext *L)
+    : ProgramPoint(B1, B2, BlockEdgeKind, L) {}
+
+  CFGBlock* getSrc() const {
+    return const_cast<CFGBlock*>(static_cast<const CFGBlock*>(getData1()));
+  }
+
+  CFGBlock* getDst() const {
+    return const_cast<CFGBlock*>(static_cast<const CFGBlock*>(getData2()));
+  }
+
+  static bool classof(const ProgramPoint* Location) {
+    return Location->getKind() == BlockEdgeKind;
+  }
+};
+
+class CallEnter : public StmtPoint {
+public:
+  // CallEnter uses the caller's location context.
+  CallEnter(const Stmt *S, const FunctionDecl *fd, const LocationContext *L)
+    : StmtPoint(S, fd, CallEnterKind, L, 0) {}
+
+  const Stmt *getCallExpr() const {
+    return static_cast<const Stmt *>(getData1());
+  }
+
+  const FunctionDecl *getCallee() const {
+    return static_cast<const FunctionDecl *>(getData2());
+  }
+
+  static bool classof(const ProgramPoint *Location) {
+    return Location->getKind() == CallEnterKind;
+  }
+};
+
+class CallExit : public StmtPoint {
+public:
+  // CallExit uses the callee's location context.
+  CallExit(const Stmt *S, const LocationContext *L)
+    : StmtPoint(S, 0, CallExitKind, L, 0) {}
+
+  static bool classof(const ProgramPoint *Location) {
+    return Location->getKind() == CallExitKind;
+  }
+};
+
+
+} // end namespace clang
+
+
+namespace llvm { // Traits specialization for DenseMap
+
+template <> struct DenseMapInfo<clang::ProgramPoint> {
+
+static inline clang::ProgramPoint getEmptyKey() {
+  uintptr_t x =
+   reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getEmptyKey()) & ~0x7;
+  return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x), 0);
+}
+
+static inline clang::ProgramPoint getTombstoneKey() {
+  uintptr_t x =
+   reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getTombstoneKey()) & ~0x7;
+  return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x), 0);
+}
+
+static unsigned getHashValue(const clang::ProgramPoint& Loc) {
+  return Loc.getHashValue();
+}
+
+static bool isEqual(const clang::ProgramPoint& L,
+                    const clang::ProgramPoint& R) {
+  return L == R;
+}
+
+};
+  
+template <>
+struct isPodLike<clang::ProgramPoint> { static const bool value = true; };
+
+} // end namespace llvm
+
+#endif
diff --git a/include/clang/Analysis/Support/BlkExprDeclBitVector.h b/include/clang/Analysis/Support/BlkExprDeclBitVector.h
new file mode 100644
index 0000000..27ecc66
--- /dev/null
+++ b/include/clang/Analysis/Support/BlkExprDeclBitVector.h
@@ -0,0 +1,307 @@
+// BlkExprDeclBitVector.h - Dataflow types for Bitvector Analysis --*- C++ --*--
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides definition of dataflow types used by analyses such
+// as LiveVariables and UninitializedValues.  The underlying dataflow values
+// are implemented as bitvectors, but the definitions in this file include
+// the necessary boilerplate to use with our dataflow framework.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_STMTDECLBVDVAL_H
+#define LLVM_CLANG_STMTDECLBVDVAL_H
+
+#include "clang/Analysis/CFG.h"
+#include "clang/AST/Decl.h" // for Decl* -> NamedDecl* conversion
+#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/DenseMap.h"
+
+namespace clang {
+
+  class Stmt;
+  class ASTContext;
+
+struct DeclBitVector_Types {
+
+  class Idx {
+    unsigned I;
+  public:
+    explicit Idx(unsigned i) : I(i) {}
+    Idx() : I(~0U) {}
+
+    bool isValid() const {
+      return I != ~0U;
+    }
+    operator unsigned() const {
+      assert (isValid());
+      return I;
+    }
+  };
+
+  //===--------------------------------------------------------------------===//
+  // AnalysisDataTy - Whole-function meta data.
+  //===--------------------------------------------------------------------===//
+
+  class AnalysisDataTy {
+  public:
+    typedef llvm::DenseMap<const NamedDecl*, unsigned > DMapTy;
+    typedef DMapTy::const_iterator decl_iterator;
+
+  protected:
+    DMapTy DMap;
+    unsigned NDecls;
+
+  public:
+
+    AnalysisDataTy() : NDecls(0) {}
+    virtual ~AnalysisDataTy() {}
+
+    bool isTracked(const NamedDecl* SD) { return DMap.find(SD) != DMap.end(); }
+
+    Idx getIdx(const NamedDecl* SD) const {
+      DMapTy::const_iterator I = DMap.find(SD);
+      return I == DMap.end() ? Idx() : Idx(I->second);
+    }
+
+    unsigned getNumDecls() const { return NDecls; }
+
+    void Register(const NamedDecl* SD) {
+      if (!isTracked(SD)) DMap[SD] = NDecls++;
+    }
+
+    decl_iterator begin_decl() const { return DMap.begin(); }
+    decl_iterator end_decl() const { return DMap.end(); }
+  };
+
+  //===--------------------------------------------------------------------===//
+  // ValTy - Dataflow value.
+  //===--------------------------------------------------------------------===//
+
+  class ValTy {
+    llvm::BitVector DeclBV;
+  public:
+
+    void resetDeclValues(AnalysisDataTy& AD) {
+      DeclBV.resize(AD.getNumDecls());
+      DeclBV.reset();
+    }
+
+    void setDeclValues(AnalysisDataTy& AD) {
+      DeclBV.resize(AD.getNumDecls());
+      DeclBV.set();
+    }
+
+    void resetValues(AnalysisDataTy& AD) {
+      resetDeclValues(AD);
+    }
+
+    bool operator==(const ValTy& RHS) const {
+      assert (sizesEqual(RHS));
+      return DeclBV == RHS.DeclBV;
+    }
+
+    void copyValues(const ValTy& RHS) { DeclBV = RHS.DeclBV; }
+
+    llvm::BitVector::reference getBit(unsigned i) {
+      return DeclBV[i];
+    }
+
+    bool getBit(unsigned i) const {
+      return DeclBV[i];
+    }
+
+    llvm::BitVector::reference
+    operator()(const NamedDecl* ND, const AnalysisDataTy& AD) {
+      return getBit(AD.getIdx(ND));
+    }
+
+    bool operator()(const NamedDecl* ND, const AnalysisDataTy& AD) const {
+      return getBit(AD.getIdx(ND));
+    }
+
+    llvm::BitVector::reference getDeclBit(unsigned i) { return DeclBV[i]; }
+    const llvm::BitVector::reference getDeclBit(unsigned i) const {
+      return const_cast<llvm::BitVector&>(DeclBV)[i];
+    }
+
+    ValTy& operator|=(const ValTy& RHS) {
+      assert (sizesEqual(RHS));
+      DeclBV |= RHS.DeclBV;
+      return *this;
+    }
+
+    ValTy& operator&=(const ValTy& RHS) {
+      assert (sizesEqual(RHS));
+      DeclBV &= RHS.DeclBV;
+      return *this;
+    }
+
+    ValTy& OrDeclBits(const ValTy& RHS) {
+      return operator|=(RHS);
+    }
+
+    ValTy& AndDeclBits(const ValTy& RHS) {
+      return operator&=(RHS);
+    }
+
+    bool sizesEqual(const ValTy& RHS) const {
+      return DeclBV.size() == RHS.DeclBV.size();
+    }
+  };
+
+  //===--------------------------------------------------------------------===//
+  // Some useful merge operations.
+  //===--------------------------------------------------------------------===//
+
+  struct Union { void operator()(ValTy& Dst, ValTy& Src) { Dst |= Src; } };
+  struct Intersect { void operator()(ValTy& Dst, ValTy& Src) { Dst &= Src; } };
+};
+
+
+struct StmtDeclBitVector_Types {
+
+  //===--------------------------------------------------------------------===//
+  // AnalysisDataTy - Whole-function meta data.
+  //===--------------------------------------------------------------------===//
+
+  class AnalysisDataTy : public DeclBitVector_Types::AnalysisDataTy {
+    ASTContext* ctx;
+    CFG* cfg;
+  public:
+    AnalysisDataTy() : ctx(0), cfg(0) {}
+    virtual ~AnalysisDataTy() {}
+
+    void setContext(ASTContext& c) { ctx = &c; }
+    ASTContext& getContext() {
+      assert(ctx && "ASTContext should not be NULL.");
+      return *ctx;
+    }
+
+    void setCFG(CFG& c) { cfg = &c; }
+    CFG& getCFG() { assert(cfg && "CFG should not be NULL."); return *cfg; }
+
+    bool isTracked(const Stmt* S) { return cfg->isBlkExpr(S); }
+    using DeclBitVector_Types::AnalysisDataTy::isTracked;
+
+    unsigned getIdx(const Stmt* S) const {
+      CFG::BlkExprNumTy I = cfg->getBlkExprNum(S);
+      assert(I && "Stmtession not tracked for bitvector.");
+      return I;
+    }
+    using DeclBitVector_Types::AnalysisDataTy::getIdx;
+
+    unsigned getNumBlkExprs() const { return cfg->getNumBlkExprs(); }
+  };
+
+  //===--------------------------------------------------------------------===//
+  // ValTy - Dataflow value.
+  //===--------------------------------------------------------------------===//
+
+  class ValTy : public DeclBitVector_Types::ValTy {
+    llvm::BitVector BlkExprBV;
+    typedef DeclBitVector_Types::ValTy ParentTy;
+
+    static inline ParentTy& ParentRef(ValTy& X) {
+      return static_cast<ParentTy&>(X);
+    }
+
+    static inline const ParentTy& ParentRef(const ValTy& X) {
+      return static_cast<const ParentTy&>(X);
+    }
+
+  public:
+
+    void resetBlkExprValues(AnalysisDataTy& AD) {
+      BlkExprBV.resize(AD.getNumBlkExprs());
+      BlkExprBV.reset();
+    }
+
+    void setBlkExprValues(AnalysisDataTy& AD) {
+      BlkExprBV.resize(AD.getNumBlkExprs());
+      BlkExprBV.set();
+    }
+
+    void resetValues(AnalysisDataTy& AD) {
+      resetDeclValues(AD);
+      resetBlkExprValues(AD);
+    }
+
+    void setValues(AnalysisDataTy& AD) {
+      setDeclValues(AD);
+      setBlkExprValues(AD);
+    }
+
+    bool operator==(const ValTy& RHS) const {
+      return ParentRef(*this) == ParentRef(RHS)
+          && BlkExprBV == RHS.BlkExprBV;
+    }
+
+    void copyValues(const ValTy& RHS) {
+      ParentRef(*this).copyValues(ParentRef(RHS));
+      BlkExprBV = RHS.BlkExprBV;
+    }
+
+    llvm::BitVector::reference
+    operator()(const Stmt* S, const AnalysisDataTy& AD) {
+      return BlkExprBV[AD.getIdx(S)];
+    }
+    const llvm::BitVector::reference
+    operator()(const Stmt* S, const AnalysisDataTy& AD) const {
+      return const_cast<ValTy&>(*this)(S,AD);
+    }
+
+    using DeclBitVector_Types::ValTy::operator();
+
+
+    llvm::BitVector::reference getStmtBit(unsigned i) { return BlkExprBV[i]; }
+    const llvm::BitVector::reference getStmtBit(unsigned i) const {
+      return const_cast<llvm::BitVector&>(BlkExprBV)[i];
+    }
+
+    ValTy& OrBlkExprBits(const ValTy& RHS) {
+      BlkExprBV |= RHS.BlkExprBV;
+      return *this;
+    }
+
+    ValTy& AndBlkExprBits(const ValTy& RHS) {
+      BlkExprBV &= RHS.BlkExprBV;
+      return *this;
+    }
+
+    ValTy& operator|=(const ValTy& RHS) {
+      assert (sizesEqual(RHS));
+      ParentRef(*this) |= ParentRef(RHS);
+      BlkExprBV |= RHS.BlkExprBV;
+      return *this;
+    }
+
+    ValTy& operator&=(const ValTy& RHS) {
+      assert (sizesEqual(RHS));
+      ParentRef(*this) &= ParentRef(RHS);
+      BlkExprBV &= RHS.BlkExprBV;
+      return *this;
+    }
+
+    bool sizesEqual(const ValTy& RHS) const {
+      return ParentRef(*this).sizesEqual(ParentRef(RHS))
+          && BlkExprBV.size() == RHS.BlkExprBV.size();
+    }
+  };
+
+  //===--------------------------------------------------------------------===//
+  // Some useful merge operations.
+  //===--------------------------------------------------------------------===//
+
+  struct Union { void operator()(ValTy& Dst, ValTy& Src) { Dst |= Src; } };
+  struct Intersect { void operator()(ValTy& Dst, ValTy& Src) { Dst &= Src; } };
+
+};
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Analysis/Support/BumpVector.h b/include/clang/Analysis/Support/BumpVector.h
new file mode 100644
index 0000000..c6c9eed
--- /dev/null
+++ b/include/clang/Analysis/Support/BumpVector.h
@@ -0,0 +1,216 @@
+//===-- BumpVector.h - Vector-like ADT that uses bump allocation --*- C++ -*-=//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file provides BumpVector, a vector-like ADT whose contents are
+//  allocated from a BumpPtrAllocator.
+//
+//===----------------------------------------------------------------------===//
+
+// FIXME: Most of this is copy-and-paste from SmallVector.h.  We can
+// refactor this core logic into something common that is shared between
+// the two.  The main thing that is different is the allocation strategy.
+
+#ifndef LLVM_CLANG_BUMP_VECTOR
+#define LLVM_CLANG_BUMP_VECTOR
+
+#include "llvm/Support/type_traits.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include <algorithm>
+#include <cstring>
+
+namespace clang {
+  
+class BumpVectorContext {
+  llvm::PointerIntPair<llvm::BumpPtrAllocator*, 1> Alloc;
+public:
+  /// Construct a new BumpVectorContext that creates a new BumpPtrAllocator
+  /// and destroys it when the BumpVectorContext object is destroyed.
+  BumpVectorContext() : Alloc(new llvm::BumpPtrAllocator(), 1) {}
+  
+  /// Construct a new BumpVectorContext that reuses an existing
+  /// BumpPtrAllocator.  This BumpPtrAllocator is not destroyed when the
+  /// BumpVectorContext object is destroyed.
+  BumpVectorContext(llvm::BumpPtrAllocator &A) : Alloc(&A, 0) {}
+  
+  ~BumpVectorContext() {
+    if (Alloc.getInt())
+      delete Alloc.getPointer();
+  }
+  
+  llvm::BumpPtrAllocator &getAllocator() { return *Alloc.getPointer(); }
+};
+  
+template<typename T>
+class BumpVector {
+  T *Begin, *End, *Capacity;
+public:
+  // Default ctor - Initialize to empty.
+  explicit BumpVector(BumpVectorContext &C, unsigned N)
+  : Begin(NULL), End(NULL), Capacity(NULL) {
+    reserve(C, N);
+  }
+  
+  ~BumpVector() {
+    if (llvm::is_class<T>::value) {
+      // Destroy the constructed elements in the vector.
+      destroy_range(Begin, End);
+    }
+  }
+  
+  typedef size_t size_type;
+  typedef ptrdiff_t difference_type;
+  typedef T value_type;
+  typedef T* iterator;
+  typedef const T* const_iterator;
+  
+  typedef std::reverse_iterator<const_iterator>  const_reverse_iterator;
+  typedef std::reverse_iterator<iterator>  reverse_iterator;
+  
+  typedef T& reference;
+  typedef const T& const_reference;
+  typedef T* pointer;
+  typedef const T* const_pointer;
+  
+  // forward iterator creation methods.
+  iterator begin() { return Begin; }
+  const_iterator begin() const { return Begin; }
+  iterator end() { return End; }
+  const_iterator end() const { return End; }
+  
+  // reverse iterator creation methods.
+  reverse_iterator rbegin()            { return reverse_iterator(end()); }
+  const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); }
+  reverse_iterator rend()              { return reverse_iterator(begin()); }
+  const_reverse_iterator rend() const { return const_reverse_iterator(begin());}
+    
+  bool empty() const { return Begin == End; }
+  size_type size() const { return End-Begin; }
+
+  reference operator[](unsigned idx) {
+    assert(Begin + idx < End);
+    return Begin[idx];
+  }
+  const_reference operator[](unsigned idx) const {
+    assert(Begin + idx < End);
+    return Begin[idx];
+  }
+  
+  reference front() {
+    return begin()[0];
+  }
+  const_reference front() const {
+    return begin()[0];
+  }
+  
+  reference back() {
+    return end()[-1];
+  }
+  const_reference back() const {
+    return end()[-1];
+  }
+  
+  void pop_back() {
+    --End;
+    End->~T();
+  }
+  
+  T pop_back_val() {
+    T Result = back();
+    pop_back();
+    return Result;
+  }
+  
+  void clear() {
+    if (llvm::is_class<T>::value) {
+      destroy_range(Begin, End);
+    }
+    End = Begin;
+  }
+  
+  /// data - Return a pointer to the vector's buffer, even if empty().
+  pointer data() {
+    return pointer(Begin);
+  }
+  
+  /// data - Return a pointer to the vector's buffer, even if empty().
+  const_pointer data() const {
+    return const_pointer(Begin);
+  }
+  
+  void push_back(const_reference Elt, BumpVectorContext &C) {
+    if (End < Capacity) {
+    Retry:
+      new (End) T(Elt);
+      ++End;
+      return;
+    }
+    grow(C);
+    goto Retry;    
+  }
+  
+  void reserve(BumpVectorContext &C, unsigned N) {
+    if (unsigned(Capacity-Begin) < N)
+      grow(C, N);
+  }
+
+  /// capacity - Return the total number of elements in the currently allocated
+  /// buffer.
+  size_t capacity() const { return Capacity - Begin; }  
+    
+private:
+  /// grow - double the size of the allocated memory, guaranteeing space for at
+  /// least one more element or MinSize if specified.
+  void grow(BumpVectorContext &C, size_type MinSize = 1);
+  
+  void construct_range(T *S, T *E, const T &Elt) {
+    for (; S != E; ++S)
+      new (S) T(Elt);
+  }
+  
+  void destroy_range(T *S, T *E) {
+    while (S != E) {
+      --E;
+      E->~T();
+    }
+  }
+};
+  
+// Define this out-of-line to dissuade the C++ compiler from inlining it.
+template <typename T>
+void BumpVector<T>::grow(BumpVectorContext &C, size_t MinSize) {
+  size_t CurCapacity = Capacity-Begin;
+  size_t CurSize = size();
+  size_t NewCapacity = 2*CurCapacity;
+  if (NewCapacity < MinSize)
+    NewCapacity = MinSize;
+
+  // Allocate the memory from the BumpPtrAllocator.
+  T *NewElts = C.getAllocator().template Allocate<T>(NewCapacity);
+  
+  // Copy the elements over.
+  if (llvm::is_class<T>::value) {
+    std::uninitialized_copy(Begin, End, NewElts);
+    // Destroy the original elements.
+    destroy_range(Begin, End);
+  }
+  else {
+    // Use memcpy for PODs (std::uninitialized_copy optimizes to memmove).
+    memcpy(NewElts, Begin, CurSize * sizeof(T));
+  }
+
+  // For now, leak 'Begin'.  We can add it back to a freelist in
+  // BumpVectorContext.
+  Begin = NewElts;
+  End = NewElts+CurSize;
+  Capacity = Begin+NewCapacity;
+}
+
+} // end: clang namespace
+#endif // end: LLVM_CLANG_BUMP_VECTOR
diff --git a/include/clang/Analysis/Support/SaveAndRestore.h b/include/clang/Analysis/Support/SaveAndRestore.h
new file mode 100644
index 0000000..f720639
--- /dev/null
+++ b/include/clang/Analysis/Support/SaveAndRestore.h
@@ -0,0 +1,47 @@
+//===-- SaveAndRestore.h - Utility  -------------------------------*- C++ -*-=//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file provides utility classes that uses RAII to save and restore
+//  values.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_SAVERESTORE
+#define LLVM_CLANG_ANALYSIS_SAVERESTORE
+
+namespace clang {
+
+// SaveAndRestore - A utility class that uses RAII to save and restore
+//  the value of a variable.
+template<typename T>
+struct SaveAndRestore {
+  SaveAndRestore(T& x) : X(x), old_value(x) {}
+  SaveAndRestore(T& x, const T &new_value) : X(x), old_value(x) {
+    X = new_value;
+  }
+  ~SaveAndRestore() { X = old_value; }
+  T get() { return old_value; }
+private:
+  T& X;
+  T old_value;
+};
+
+// SaveOr - Similar to SaveAndRestore.  Operates only on bools; the old
+//  value of a variable is saved, and during the dstor the old value is
+//  or'ed with the new value.
+struct SaveOr {
+  SaveOr(bool& x) : X(x), old_value(x) { x = false; }
+  ~SaveOr() { X |= old_value; }
+private:
+  bool& X;
+  const bool old_value;
+};
+
+}
+#endif
diff --git a/include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h b/include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h
new file mode 100644
index 0000000..d627b88
--- /dev/null
+++ b/include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h
@@ -0,0 +1,92 @@
+//= CFGRecStmtDeclVisitor - Recursive visitor of CFG stmts/decls -*- C++ --*-=//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the template class CFGRecStmtDeclVisitor, which extends
+// CFGRecStmtVisitor by implementing (typed) visitation of decls.
+//
+// FIXME: This may not be fully complete.  We currently explore only subtypes
+//        of ScopedDecl.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_CFG_REC_STMT_DECL_VISITOR_H
+#define LLVM_CLANG_ANALYSIS_CFG_REC_STMT_DECL_VISITOR_H
+
+#include "clang/Analysis/Visitors/CFGRecStmtVisitor.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclCXX.h"
+
+#define DISPATCH_CASE(CASE,CLASS) \
+case Decl::CASE: \
+static_cast<ImplClass*>(this)->Visit##CLASS(static_cast<CLASS*>(D));\
+break;
+
+#define DEFAULT_DISPATCH(CLASS) void Visit##CLASS(CLASS* D) {}
+#define DEFAULT_DISPATCH_VARDECL(CLASS) void Visit##CLASS(CLASS* D)\
+  { static_cast<ImplClass*>(this)->VisitVarDecl(D); }
+
+
+namespace clang {
+template <typename ImplClass>
+class CFGRecStmtDeclVisitor : public CFGRecStmtVisitor<ImplClass> {
+public:
+
+  void VisitDeclRefExpr(DeclRefExpr* DR) {
+    static_cast<ImplClass*>(this)->VisitDecl(DR->getDecl());
+  }
+
+  void VisitDeclStmt(DeclStmt* DS) {
+    for (DeclStmt::decl_iterator DI = DS->decl_begin(), DE = DS->decl_end();
+        DI != DE; ++DI) {
+      Decl* D = *DI;
+      static_cast<ImplClass*>(this)->VisitDecl(D);
+      // Visit the initializer.
+      if (VarDecl* VD = dyn_cast<VarDecl>(D))
+        if (Expr* I = VD->getInit())
+          static_cast<ImplClass*>(this)->Visit(I);
+    }
+  }
+
+  void VisitDecl(Decl* D) {
+    switch (D->getKind()) {
+        DISPATCH_CASE(Function,FunctionDecl)
+        DISPATCH_CASE(CXXMethod,CXXMethodDecl)
+        DISPATCH_CASE(Var,VarDecl)
+        DISPATCH_CASE(ParmVar,ParmVarDecl)       // FIXME: (same)
+        DISPATCH_CASE(ImplicitParam,ImplicitParamDecl)
+        DISPATCH_CASE(EnumConstant,EnumConstantDecl)
+        DISPATCH_CASE(Typedef,TypedefDecl)
+        DISPATCH_CASE(Record,RecordDecl)    // FIXME: Refine.  VisitStructDecl?
+        DISPATCH_CASE(Enum,EnumDecl)
+      default:
+        assert(false && "Subtype of ScopedDecl not handled.");
+    }
+  }
+
+  DEFAULT_DISPATCH(VarDecl)
+  DEFAULT_DISPATCH(FunctionDecl)
+  DEFAULT_DISPATCH(CXXMethodDecl)
+  DEFAULT_DISPATCH_VARDECL(ParmVarDecl)
+  DEFAULT_DISPATCH(ImplicitParamDecl)
+  DEFAULT_DISPATCH(EnumConstantDecl)
+  DEFAULT_DISPATCH(TypedefDecl)
+  DEFAULT_DISPATCH(RecordDecl)
+  DEFAULT_DISPATCH(EnumDecl)
+  DEFAULT_DISPATCH(ObjCInterfaceDecl)
+  DEFAULT_DISPATCH(ObjCClassDecl)
+  DEFAULT_DISPATCH(ObjCMethodDecl)
+  DEFAULT_DISPATCH(ObjCProtocolDecl)
+  DEFAULT_DISPATCH(ObjCCategoryDecl)
+};
+
+} // end namespace clang
+
+#undef DISPATCH_CASE
+#undef DEFAULT_DISPATCH
+#endif
diff --git a/include/clang/Analysis/Visitors/CFGRecStmtVisitor.h b/include/clang/Analysis/Visitors/CFGRecStmtVisitor.h
new file mode 100644
index 0000000..75a4ac6
--- /dev/null
+++ b/include/clang/Analysis/Visitors/CFGRecStmtVisitor.h
@@ -0,0 +1,54 @@
+//==- CFGRecStmtVisitor - Recursive visitor of CFG statements ---*- C++ --*-==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the template class CFGRecStmtVisitor, which extends
+// CFGStmtVisitor by implementing a default recursive visit of all statements.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_CFG_REC_STMT_VISITOR_H
+#define LLVM_CLANG_ANALYSIS_CFG_REC_STMT_VISITOR_H
+
+#include "clang/Analysis/Visitors/CFGStmtVisitor.h"
+
+namespace clang {
+template <typename ImplClass>
+class CFGRecStmtVisitor : public CFGStmtVisitor<ImplClass,void> {
+public:
+
+  void VisitStmt(Stmt* S) {
+    static_cast< ImplClass* >(this)->VisitChildren(S);
+  }
+  
+  void VisitConditionVariableInit(Stmt *S) {
+    assert(S == this->getCurrentBlkStmt());
+    VarDecl *CondVar = 0;
+    switch (S->getStmtClass()) {
+#define CONDVAR_CASE(CLASS) \
+case Stmt::CLASS ## Class:\
+CondVar = cast<CLASS>(S)->getConditionVariable();\
+break;
+        CONDVAR_CASE(IfStmt)
+        CONDVAR_CASE(ForStmt)
+        CONDVAR_CASE(SwitchStmt)
+        CONDVAR_CASE(WhileStmt)
+#undef CONDVAR_CASE
+      default:
+        assert(false && "Infeasible");
+    }    
+    static_cast<ImplClass*>(this)->Visit(CondVar->getInit());
+  }
+
+  // Defining operator() allows the visitor to be used as a C++ style functor.
+  void operator()(Stmt* S) { static_cast<ImplClass*>(this)->BlockStmt_Visit(S);}
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Analysis/Visitors/CFGStmtVisitor.h b/include/clang/Analysis/Visitors/CFGStmtVisitor.h
new file mode 100644
index 0000000..8a85ec1
--- /dev/null
+++ b/include/clang/Analysis/Visitors/CFGStmtVisitor.h
@@ -0,0 +1,168 @@
+//===--- CFGStmtVisitor.h - Visitor for Stmts in a CFG ----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the CFGStmtVisitor interface, which extends
+//  StmtVisitor.  This interface is useful for visiting statements in a CFG
+//  where some statements have implicit control-flow and thus should
+//  be treated specially.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_CFGSTMTVISITOR_H
+#define LLVM_CLANG_ANALYSIS_CFGSTMTVISITOR_H
+
+#include "clang/AST/StmtVisitor.h"
+#include "clang/Analysis/CFG.h"
+
+namespace clang {
+
+#define DISPATCH_CASE(CLASS) \
+case Stmt::CLASS ## Class: return \
+static_cast<ImplClass*>(this)->BlockStmt_Visit ## CLASS(static_cast<CLASS*>(S));
+
+#define DEFAULT_BLOCKSTMT_VISIT(CLASS) RetTy BlockStmt_Visit ## CLASS(CLASS *S)\
+{ return\
+  static_cast<ImplClass*>(this)->BlockStmt_VisitImplicitControlFlowExpr(\
+  cast<Expr>(S)); }
+
+template <typename ImplClass, typename RetTy=void>
+class CFGStmtVisitor : public StmtVisitor<ImplClass,RetTy> {
+  Stmt* CurrentBlkStmt;
+
+  struct NullifyStmt {
+    Stmt*& S;
+
+    NullifyStmt(Stmt*& s) : S(s) {}
+    ~NullifyStmt() { S = NULL; }
+  };
+
+public:
+  CFGStmtVisitor() : CurrentBlkStmt(NULL) {}
+
+  Stmt* getCurrentBlkStmt() const { return CurrentBlkStmt; }
+
+  RetTy Visit(Stmt* S) {
+    if (S == CurrentBlkStmt ||
+        !static_cast<ImplClass*>(this)->getCFG().isBlkExpr(S))
+      return StmtVisitor<ImplClass,RetTy>::Visit(S);
+    else
+      return RetTy();
+  }
+  
+  /// VisitConditionVariableInit - Handle the initialization of condition
+  ///  variables at branches.  Valid statements include IfStmt, ForStmt,
+  ///  WhileStmt, and SwitchStmt.
+  RetTy VisitConditionVariableInit(Stmt *S) {
+    return RetTy();
+  }
+
+  /// BlockVisit_XXX - Visitor methods for visiting the "root" statements in
+  /// CFGBlocks.  Root statements are the statements that appear explicitly in
+  /// the list of statements in a CFGBlock.  For substatements, or when there
+  /// is no implementation provided for a BlockStmt_XXX method, we default
+  /// to using StmtVisitor's Visit method.
+  RetTy BlockStmt_Visit(Stmt* S) {
+    CurrentBlkStmt = S;
+    NullifyStmt cleanup(CurrentBlkStmt);
+
+    switch (S->getStmtClass()) {
+      case Stmt::IfStmtClass:
+      case Stmt::ForStmtClass:
+      case Stmt::WhileStmtClass:
+      case Stmt::SwitchStmtClass:
+        return static_cast<ImplClass*>(this)->VisitConditionVariableInit(S);
+
+      DISPATCH_CASE(StmtExpr)
+      DISPATCH_CASE(ConditionalOperator)
+      DISPATCH_CASE(ObjCForCollectionStmt)
+
+      case Stmt::BinaryOperatorClass: {
+        BinaryOperator* B = cast<BinaryOperator>(S);
+        if (B->isLogicalOp())
+          return static_cast<ImplClass*>(this)->BlockStmt_VisitLogicalOp(B);
+        else if (B->getOpcode() == BinaryOperator::Comma)
+          return static_cast<ImplClass*>(this)->BlockStmt_VisitComma(B);
+        // Fall through.
+      }
+
+      default:
+        if (isa<Expr>(S))
+          return
+            static_cast<ImplClass*>(this)->BlockStmt_VisitExpr(cast<Expr>(S));
+        else
+          return static_cast<ImplClass*>(this)->BlockStmt_VisitStmt(S);
+    }
+  }
+
+  DEFAULT_BLOCKSTMT_VISIT(StmtExpr)
+  DEFAULT_BLOCKSTMT_VISIT(ConditionalOperator)
+
+  RetTy BlockStmt_VisitObjCForCollectionStmt(ObjCForCollectionStmt* S) {
+    return static_cast<ImplClass*>(this)->BlockStmt_VisitStmt(S);
+  }
+
+  RetTy BlockStmt_VisitImplicitControlFlowExpr(Expr* E) {
+    return static_cast<ImplClass*>(this)->BlockStmt_VisitExpr(E);
+  }
+
+  RetTy BlockStmt_VisitExpr(Expr* E) {
+    return static_cast<ImplClass*>(this)->BlockStmt_VisitStmt(E);
+  }
+
+  RetTy BlockStmt_VisitStmt(Stmt* S) {
+    return static_cast<ImplClass*>(this)->Visit(S);
+  }
+
+  RetTy BlockStmt_VisitLogicalOp(BinaryOperator* B) {
+    return
+     static_cast<ImplClass*>(this)->BlockStmt_VisitImplicitControlFlowExpr(B);
+  }
+
+  RetTy BlockStmt_VisitComma(BinaryOperator* B) {
+    return
+     static_cast<ImplClass*>(this)->BlockStmt_VisitImplicitControlFlowExpr(B);
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Utility methods.  Not called by default (but subclasses may use them).
+  //===--------------------------------------------------------------------===//
+
+  /// VisitChildren: Call "Visit" on each child of S.
+  void VisitChildren(Stmt* S) {
+
+    switch (S->getStmtClass()) {
+      default:
+        break;
+
+      case Stmt::StmtExprClass: {
+        CompoundStmt* CS = cast<StmtExpr>(S)->getSubStmt();
+        if (CS->body_empty()) return;
+        static_cast<ImplClass*>(this)->Visit(CS->body_back());
+        return;
+      }
+
+      case Stmt::BinaryOperatorClass: {
+        BinaryOperator* B = cast<BinaryOperator>(S);
+        if (B->getOpcode() != BinaryOperator::Comma) break;
+        static_cast<ImplClass*>(this)->Visit(B->getRHS());
+        return;
+      }
+    }
+
+    for (Stmt::child_iterator I=S->child_begin(), E=S->child_end(); I != E;++I)
+      if (*I) static_cast<ImplClass*>(this)->Visit(*I);
+  }
+};
+
+#undef DEFAULT_BLOCKSTMT_VISIT
+#undef DISPATCH_CASE
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Basic/Builtins.def b/include/clang/Basic/Builtins.def
new file mode 100644
index 0000000..b306954
--- /dev/null
+++ b/include/clang/Basic/Builtins.def
@@ -0,0 +1,562 @@
+//===--- Builtins.def - Builtin function info database ----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the standard builtin function database.  Users of this file
+// must define the BUILTIN macro to make use of this information.
+//
+//===----------------------------------------------------------------------===//
+
+// FIXME: This should really be a .td file, but that requires modifying tblgen.
+// Perhaps tblgen should have plugins.
+
+// The first value provided to the macro specifies the function name of the
+// builtin, and results in a clang::builtin::BIXX enum value for XX.
+
+// The second value provided to the macro specifies the type of the function
+// (result value, then each argument) as follows:
+//  v -> void
+//  b -> boolean
+//  c -> char
+//  s -> short
+//  i -> int
+//  f -> float
+//  d -> double
+//  z -> size_t
+//  F -> constant CFString
+//  a -> __builtin_va_list
+//  A -> "reference" to __builtin_va_list
+//  V -> Vector, following num elements and a base type.
+//  X -> _Complex, followed by the base type.
+//  P -> FILE
+//  J -> jmp_buf
+//  SJ -> sigjmp_buf
+//  . -> "...".  This may only occur at the end of the function list.
+//
+// Types maybe prefixed with the following modifiers:
+//  L   -> long (e.g. Li for 'long int')
+//  LL  -> long long
+//  LLL -> __int128_t (e.g. LLLi)
+//  S   -> signed
+//  U   -> unsigned
+//
+// Types may be postfixed with the following modifiers:
+// * -> pointer (optionally followed by an address space number)
+// & -> reference (optionally followed by an address space number)
+// C -> const
+// D -> volatile
+
+// The third value provided to the macro specifies information about attributes
+// of the function.  These must be kept in sync with the predicates in the
+// Builtin::Context class.  Currently we have:
+//  n -> nothrow
+//  r -> noreturn
+//  c -> const
+//  F -> this is a libc/libm function with a '__builtin_' prefix added.
+//  f -> this is a libc/libm function without the '__builtin_' prefix. It can
+//       be followed by ':headername:' to state which header this function
+//       comes from.
+//  p:N: -> this is a printf-like function whose Nth argument is the format
+//          string.
+//  P:N: -> similar to the p:N: attribute, but the function is like vprintf
+//          in that it accepts its arguments as a va_list rather than
+//          through an ellipsis
+//  e -> const, but only when -fmath-errno=0
+//  FIXME: gcc has nonnull
+
+#if defined(BUILTIN) && !defined(LIBBUILTIN)
+#  define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) BUILTIN(ID, TYPE, ATTRS)
+#endif
+
+// Standard libc/libm functions:
+BUILTIN(__builtin_atan2 , "ddd"  , "Fnc")
+BUILTIN(__builtin_atan2f, "fff"  , "Fnc")
+BUILTIN(__builtin_atan2l, "LdLdLd", "Fnc")
+BUILTIN(__builtin_abs  , "ii"  , "ncF")
+BUILTIN(__builtin_copysign, "ddd", "ncF")
+BUILTIN(__builtin_copysignf, "fff", "ncF")
+BUILTIN(__builtin_copysignl, "LdLdLd", "ncF")
+BUILTIN(__builtin_fabs , "dd"  , "ncF")
+BUILTIN(__builtin_fabsf, "ff"  , "ncF")
+BUILTIN(__builtin_fabsl, "LdLd", "ncF")
+BUILTIN(__builtin_fmod , "ddd"  , "Fnc")
+BUILTIN(__builtin_fmodf, "fff"  , "Fnc")
+BUILTIN(__builtin_fmodl, "LdLdLd", "Fnc")
+BUILTIN(__builtin_frexp , "ddi*"  , "Fnc")
+BUILTIN(__builtin_frexpf, "ffi*"  , "Fnc")
+BUILTIN(__builtin_frexpl, "LdLdi*", "Fnc")
+BUILTIN(__builtin_huge_val, "d", "nc")
+BUILTIN(__builtin_huge_valf, "f", "nc")
+BUILTIN(__builtin_huge_vall, "Ld", "nc")
+BUILTIN(__builtin_inf  , "d"   , "nc")
+BUILTIN(__builtin_inff , "f"   , "nc")
+BUILTIN(__builtin_infl , "Ld"  , "nc")
+BUILTIN(__builtin_ldexp , "ddi"  , "Fnc")
+BUILTIN(__builtin_ldexpf, "ffi"  , "Fnc")
+BUILTIN(__builtin_ldexpl, "LdLdi", "Fnc")
+BUILTIN(__builtin_modf , "ddd*"  , "Fnc")
+BUILTIN(__builtin_modff, "fff*"  , "Fnc")
+BUILTIN(__builtin_modfl, "LdLdLd*", "Fnc")
+BUILTIN(__builtin_nan,  "dcC*" , "ncF")
+BUILTIN(__builtin_nanf, "fcC*" , "ncF")
+BUILTIN(__builtin_nanl, "LdcC*", "ncF")
+BUILTIN(__builtin_nans,  "dcC*" , "ncF")
+BUILTIN(__builtin_nansf, "fcC*" , "ncF")
+BUILTIN(__builtin_nansl, "LdcC*", "ncF")
+BUILTIN(__builtin_powi , "ddi"  , "Fnc")
+BUILTIN(__builtin_powif, "ffi"  , "Fnc")
+BUILTIN(__builtin_powil, "LdLdi", "Fnc")
+BUILTIN(__builtin_pow , "ddd"  , "Fnc")
+BUILTIN(__builtin_powf, "fff"  , "Fnc")
+BUILTIN(__builtin_powl, "LdLdLd", "Fnc")
+
+// Standard unary libc/libm functions with double/float/long double variants:
+BUILTIN(__builtin_acos , "dd"  , "Fnc")
+BUILTIN(__builtin_acosf, "ff"  , "Fnc")
+BUILTIN(__builtin_acosl, "LdLd", "Fnc")
+BUILTIN(__builtin_asin , "dd"  , "Fnc")
+BUILTIN(__builtin_asinf, "ff"  , "Fnc")
+BUILTIN(__builtin_asinl, "LdLd", "Fnc")
+BUILTIN(__builtin_atan , "dd"  , "Fnc")
+BUILTIN(__builtin_atanf, "ff"  , "Fnc")
+BUILTIN(__builtin_atanl, "LdLd", "Fnc")
+BUILTIN(__builtin_ceil , "dd"  , "Fnc")
+BUILTIN(__builtin_ceilf, "ff"  , "Fnc")
+BUILTIN(__builtin_ceill, "LdLd", "Fnc")
+BUILTIN(__builtin_cos , "dd"  , "Fnc")
+BUILTIN(__builtin_cosf, "ff"  , "Fnc")
+BUILTIN(__builtin_cosh , "dd"  , "Fnc")
+BUILTIN(__builtin_coshf, "ff"  , "Fnc")
+BUILTIN(__builtin_coshl, "LdLd", "Fnc")
+BUILTIN(__builtin_cosl, "LdLd", "Fnc")
+BUILTIN(__builtin_exp , "dd"  , "Fnc")
+BUILTIN(__builtin_expf, "ff"  , "Fnc")
+BUILTIN(__builtin_expl, "LdLd", "Fnc")
+BUILTIN(__builtin_floor , "dd"  , "Fnc")
+BUILTIN(__builtin_floorf, "ff"  , "Fnc")
+BUILTIN(__builtin_floorl, "LdLd", "Fnc")
+BUILTIN(__builtin_hypot , "ddd"  , "Fnc")
+BUILTIN(__builtin_hypotf, "fff"  , "Fnc")
+BUILTIN(__builtin_hypotl, "LdLdLd", "Fnc")
+BUILTIN(__builtin_log , "dd"  , "Fnc")
+BUILTIN(__builtin_log10 , "dd"  , "Fnc")
+BUILTIN(__builtin_log10f, "ff"  , "Fnc")
+BUILTIN(__builtin_log10l, "LdLd", "Fnc")
+BUILTIN(__builtin_logf, "ff"  , "Fnc")
+BUILTIN(__builtin_logl, "LdLd", "Fnc")
+BUILTIN(__builtin_sin , "dd"  , "Fnc")
+BUILTIN(__builtin_sinf, "ff"  , "Fnc")
+BUILTIN(__builtin_sinh , "dd"  , "Fnc")
+BUILTIN(__builtin_sinhf, "ff"  , "Fnc")
+BUILTIN(__builtin_sinhl, "LdLd", "Fnc")
+BUILTIN(__builtin_sinl, "LdLd", "Fnc")
+BUILTIN(__builtin_sqrt , "dd"  , "Fnc")
+BUILTIN(__builtin_sqrtf, "ff"  , "Fnc")
+BUILTIN(__builtin_sqrtl, "LdLd", "Fnc")
+BUILTIN(__builtin_tan , "dd"  , "Fnc")
+BUILTIN(__builtin_tanf, "ff"  , "Fnc")
+BUILTIN(__builtin_tanh , "dd"  , "Fnc")
+BUILTIN(__builtin_tanhf, "ff"  , "Fnc")
+BUILTIN(__builtin_tanhl, "LdLd", "Fnc")
+BUILTIN(__builtin_tanl, "LdLd", "Fnc")
+
+// C99 complex builtins
+BUILTIN(__builtin_cabs, "dXd", "Fnc")
+BUILTIN(__builtin_cabsf, "fXf", "Fnc")
+BUILTIN(__builtin_cabsl, "LdXLd", "Fnc")
+BUILTIN(__builtin_cacos, "XdXd", "Fnc")
+BUILTIN(__builtin_cacosf, "XfXf", "Fnc")
+BUILTIN(__builtin_cacosl, "XLdXLd", "Fnc")
+BUILTIN(__builtin_carg, "dXd", "Fnc")
+BUILTIN(__builtin_cargf, "fXf", "Fnc")
+BUILTIN(__builtin_cargl, "LdXLd", "Fnc")
+BUILTIN(__builtin_casin, "XdXd", "Fnc")
+BUILTIN(__builtin_casinf, "XfXf", "Fnc")
+BUILTIN(__builtin_casinl, "XLdXLd", "Fnc")
+BUILTIN(__builtin_catan, "XdXd", "Fnc")
+BUILTIN(__builtin_catanf, "XfXf", "Fnc")
+BUILTIN(__builtin_catanl, "XLdXLd", "Fnc")
+BUILTIN(__builtin_ccos, "XdXd", "Fnc")
+BUILTIN(__builtin_ccosf, "XfXf", "Fnc")
+BUILTIN(__builtin_ccosl, "XLdXLd", "Fnc")
+BUILTIN(__builtin_ccosh, "XdXd", "Fnc")
+BUILTIN(__builtin_ccoshf, "XfXf", "Fnc")
+BUILTIN(__builtin_ccoshl, "XLdXLd", "Fnc")
+BUILTIN(__builtin_cexp, "XdXd", "Fnc")
+BUILTIN(__builtin_cexpf, "XfXf", "Fnc")
+BUILTIN(__builtin_cexpl, "XLdXLd", "Fnc")
+BUILTIN(__builtin_cimag, "dXd", "Fnc")
+BUILTIN(__builtin_cimagf, "fXf", "Fnc")
+BUILTIN(__builtin_cimagl, "LdXLd", "Fnc")
+BUILTIN(__builtin_conj, "dXd", "Fnc")
+BUILTIN(__builtin_conjf, "fXf", "Fnc")
+BUILTIN(__builtin_conjl, "LdXLd", "Fnc")
+BUILTIN(__builtin_clog, "XdXd", "Fnc")
+BUILTIN(__builtin_clogf, "XfXf", "Fnc")
+BUILTIN(__builtin_clogl, "XLdXLd", "Fnc")
+BUILTIN(__builtin_cproj, "XdXd", "Fnc")
+BUILTIN(__builtin_cprojf, "XfXf", "Fnc")
+BUILTIN(__builtin_cprojl, "XLdXLd", "Fnc")
+BUILTIN(__builtin_cpow, "XdXdXd", "Fnc")
+BUILTIN(__builtin_cpowf, "XfXfXf", "Fnc")
+BUILTIN(__builtin_cpowl, "XLdXLdXLd", "Fnc")
+BUILTIN(__builtin_creal, "dXd", "Fnc")
+BUILTIN(__builtin_crealf, "fXf", "Fnc")
+BUILTIN(__builtin_creall, "LdXLd", "Fnc")
+BUILTIN(__builtin_csin, "XdXd", "Fnc")
+BUILTIN(__builtin_csinf, "XfXf", "Fnc")
+BUILTIN(__builtin_csinl, "XLdXLd", "Fnc")
+BUILTIN(__builtin_csinh, "XdXd", "Fnc")
+BUILTIN(__builtin_csinhf, "XfXf", "Fnc")
+BUILTIN(__builtin_csinhl, "XLdXLd", "Fnc")
+BUILTIN(__builtin_csqrt, "XdXd", "Fnc")
+BUILTIN(__builtin_csqrtf, "XfXf", "Fnc")
+BUILTIN(__builtin_csqrtl, "XLdXLd", "Fnc")
+BUILTIN(__builtin_ctan, "XdXd", "Fnc")
+BUILTIN(__builtin_ctanf, "XfXf", "Fnc")
+BUILTIN(__builtin_ctanl, "XLdXLd", "Fnc")
+BUILTIN(__builtin_ctanh, "XdXd", "Fnc")
+BUILTIN(__builtin_ctanhf, "XfXf", "Fnc")
+BUILTIN(__builtin_ctanhl, "XLdXLd", "Fnc")
+
+// FP Comparisons.
+BUILTIN(__builtin_isgreater     , "i.", "nc")
+BUILTIN(__builtin_isgreaterequal, "i.", "nc")
+BUILTIN(__builtin_isless        , "i.", "nc")
+BUILTIN(__builtin_islessequal   , "i.", "nc")
+BUILTIN(__builtin_islessgreater , "i.", "nc")
+BUILTIN(__builtin_isunordered   , "i.", "nc")
+
+// Unary FP classification
+BUILTIN(__builtin_fpclassify, "iiiii.", "nc")
+BUILTIN(__builtin_isfinite,   "i.", "nc")
+BUILTIN(__builtin_isinf,      "i.", "nc")
+BUILTIN(__builtin_isinf_sign, "i.", "nc")
+BUILTIN(__builtin_isnan,      "i.", "nc")
+BUILTIN(__builtin_isnormal,   "i.", "nc")
+
+// FP signbit builtins
+BUILTIN(__builtin_signbit, "id", "nc")
+BUILTIN(__builtin_signbitf, "if", "nc")
+BUILTIN(__builtin_signbitl, "iLd", "nc")
+
+// Builtins for arithmetic.
+BUILTIN(__builtin_clz  , "iUi"  , "nc")
+BUILTIN(__builtin_clzl , "iULi" , "nc")
+BUILTIN(__builtin_clzll, "iULLi", "nc")
+// TODO: int clzimax(uintmax_t)
+BUILTIN(__builtin_ctz  , "iUi"  , "nc")
+BUILTIN(__builtin_ctzl , "iULi" , "nc")
+BUILTIN(__builtin_ctzll, "iULLi", "nc")
+// TODO: int ctzimax(uintmax_t)
+BUILTIN(__builtin_ffs  , "iUi"  , "nc")
+BUILTIN(__builtin_ffsl , "iULi" , "nc")
+BUILTIN(__builtin_ffsll, "iULLi", "nc")
+BUILTIN(__builtin_parity  , "iUi"  , "nc")
+BUILTIN(__builtin_parityl , "iULi" , "nc")
+BUILTIN(__builtin_parityll, "iULLi", "nc")
+BUILTIN(__builtin_popcount  , "iUi"  , "nc")
+BUILTIN(__builtin_popcountl , "iULi" , "nc")
+BUILTIN(__builtin_popcountll, "iULLi", "nc")
+
+// FIXME: These type signatures are not correct for targets with int != 32-bits
+// or with ULL != 64-bits.
+BUILTIN(__builtin_bswap32, "UiUi", "nc")
+BUILTIN(__builtin_bswap64, "ULLiULLi", "nc")
+
+// Random GCC builtins
+BUILTIN(__builtin_constant_p, "Us.", "nc")
+BUILTIN(__builtin_classify_type, "i.", "nc")
+BUILTIN(__builtin___CFStringMakeConstantString, "FC*cC*", "nc")
+BUILTIN(__builtin___NSStringMakeConstantString, "FC*cC*", "nc")
+BUILTIN(__builtin_va_start, "vA.", "n")
+BUILTIN(__builtin_va_end, "vA", "n")
+BUILTIN(__builtin_va_copy, "vAA", "n")
+BUILTIN(__builtin_stdarg_start, "vA.", "n")
+BUILTIN(__builtin_bcmp, "iv*v*z", "n")
+BUILTIN(__builtin_bcopy, "vv*v*z", "n")
+BUILTIN(__builtin_bzero, "vv*z", "nF")
+BUILTIN(__builtin_memchr, "v*vC*iz", "nF")
+BUILTIN(__builtin_memcmp, "ivC*vC*z", "nF")
+BUILTIN(__builtin_memcpy, "v*v*vC*z", "nF")
+BUILTIN(__builtin_memmove, "v*v*vC*z", "nF")
+BUILTIN(__builtin_mempcpy, "v*v*vC*z", "nF")
+BUILTIN(__builtin_memset, "v*v*iz", "nF")
+BUILTIN(__builtin_stpcpy, "c*c*cC*", "nF")
+BUILTIN(__builtin_stpncpy, "c*c*cC*z", "nF")
+BUILTIN(__builtin_strcasecmp, "icC*cC*", "nF")
+BUILTIN(__builtin_strcat, "c*c*cC*", "nF")
+BUILTIN(__builtin_strchr, "c*cC*i", "nF")
+BUILTIN(__builtin_strcmp, "icC*cC*", "nF")
+BUILTIN(__builtin_strcpy, "c*c*cC*", "nF")
+BUILTIN(__builtin_strcspn, "zcC*cC*", "nF")
+BUILTIN(__builtin_strdup, "c*cC*", "nF")
+BUILTIN(__builtin_strlen, "zcC*", "nF")
+BUILTIN(__builtin_strncasecmp, "icC*cC*z", "nF")
+BUILTIN(__builtin_strncat, "c*c*cC*z", "nF")
+BUILTIN(__builtin_strncmp, "icC*cC*z", "nF")
+BUILTIN(__builtin_strncpy, "c*c*cC*z", "nF")
+BUILTIN(__builtin_strndup, "c*cC*z", "nF")
+BUILTIN(__builtin_strpbrk, "c*cC*cC*", "nF")
+BUILTIN(__builtin_strrchr, "c*cC*i", "nF")
+BUILTIN(__builtin_strspn, "zcC*cC*", "nF")
+BUILTIN(__builtin_strstr, "c*cC*cC*", "nF")
+BUILTIN(__builtin_return_address, "v*Ui", "n")
+BUILTIN(__builtin_extract_return_addr, "v*v*", "n")
+BUILTIN(__builtin_frame_address, "v*Ui", "n")
+BUILTIN(__builtin_flt_rounds, "i", "nc")
+BUILTIN(__builtin_setjmp, "iv**", "")
+BUILTIN(__builtin_longjmp, "vv**i", "r")
+BUILTIN(__builtin_unwind_init, "v", "")
+BUILTIN(__builtin_eh_return_data_regno, "ii", "nc")
+BUILTIN(__builtin_vsprintf, "ic*cC*a", "nFP:1:")
+BUILTIN(__builtin_vsnprintf, "ic*zcC*a", "nFP:2:")
+
+// GCC exception builtins
+BUILTIN(__builtin_eh_return, "vzv*", "") // FIXME: Takes intptr_t, not size_t!
+BUILTIN(__builtin_frob_return_addr, "v*v*", "n")
+BUILTIN(__builtin_dwarf_cfa, "v*", "n")
+BUILTIN(__builtin_init_dwarf_reg_size_table, "vv*", "n")
+BUILTIN(__builtin_dwarf_sp_column, "Ui", "n")
+BUILTIN(__builtin_extend_pointer, "ULLiv*", "n") // _Unwind_Word == uint64_t
+
+// GCC Object size checking builtins
+BUILTIN(__builtin_object_size, "zv*i", "n")
+BUILTIN(__builtin___memcpy_chk, "v*v*vC*zz", "nF")
+BUILTIN(__builtin___memmove_chk, "v*v*vC*zz", "nF")
+BUILTIN(__builtin___mempcpy_chk, "v*v*vC*zz", "nF")
+BUILTIN(__builtin___memset_chk, "v*v*izz", "nF")
+BUILTIN(__builtin___stpcpy_chk, "c*c*cC*z", "nF")
+BUILTIN(__builtin___strcat_chk, "c*c*cC*z", "nF")
+BUILTIN(__builtin___strcpy_chk, "c*c*cC*z", "nF")
+BUILTIN(__builtin___strncat_chk, "c*c*cC*zz", "nF")
+BUILTIN(__builtin___strncpy_chk, "c*c*cC*zz", "nF")
+BUILTIN(__builtin___stpncpy_chk, "c*c*cC*zz", "nF")
+BUILTIN(__builtin___snprintf_chk, "ic*zizcC*.", "Fp:4:")
+BUILTIN(__builtin___sprintf_chk, "ic*izcC*.", "Fp:3:")
+BUILTIN(__builtin___vsnprintf_chk, "ic*zizcC*a", "FP:4:")
+BUILTIN(__builtin___vsprintf_chk, "ic*izcC*a", "FP:3:")
+BUILTIN(__builtin___fprintf_chk, "iP*icC*.", "Fp:2:")
+BUILTIN(__builtin___printf_chk, "iicC*.", "Fp:1:")
+BUILTIN(__builtin___vfprintf_chk, "iP*icC*a", "FP:2:")
+BUILTIN(__builtin___vprintf_chk, "iicC*a", "FP:1:")
+
+BUILTIN(__builtin_expect, "LiLiLi"   , "nc")
+BUILTIN(__builtin_prefetch, "vvC*.", "nc")
+BUILTIN(__builtin_trap, "v", "nr")
+BUILTIN(__builtin_unreachable, "v", "nr")
+BUILTIN(__builtin_shufflevector, "v."   , "nc")
+BUILTIN(__builtin_alloca, "v*z"   , "n")
+
+// "Overloaded" Atomic operator builtins.  These are overloaded to support data
+// types of i8, i16, i32, i64, and i128.  The front-end sees calls to the
+// non-suffixed version of these (which has a bogus type) and transforms them to
+// the right overloaded version in Sema (plus casts).
+
+// FIXME: These assume that char -> i8, short -> i16, int -> i32,
+// long long -> i64.
+
+BUILTIN(__sync_fetch_and_add, "v.", "")
+BUILTIN(__sync_fetch_and_add_1, "cc*c.", "n")
+BUILTIN(__sync_fetch_and_add_2, "ss*s.", "n")
+BUILTIN(__sync_fetch_and_add_4, "ii*i.", "n")
+BUILTIN(__sync_fetch_and_add_8, "LLiLLi*LLi.", "n")
+BUILTIN(__sync_fetch_and_add_16, "LLLiLLLi*LLLi.", "n")
+
+BUILTIN(__sync_fetch_and_sub, "v.", "")
+BUILTIN(__sync_fetch_and_sub_1, "cc*c.", "n")
+BUILTIN(__sync_fetch_and_sub_2, "ss*s.", "n")
+BUILTIN(__sync_fetch_and_sub_4, "ii*i.", "n")
+BUILTIN(__sync_fetch_and_sub_8, "LLiLLi*LLi.", "n")
+BUILTIN(__sync_fetch_and_sub_16, "LLLiLLLi*LLLi.", "n")
+
+BUILTIN(__sync_fetch_and_or, "v.", "")
+BUILTIN(__sync_fetch_and_or_1, "cc*c.", "n")
+BUILTIN(__sync_fetch_and_or_2, "ss*s.", "n")
+BUILTIN(__sync_fetch_and_or_4, "ii*i.", "n")
+BUILTIN(__sync_fetch_and_or_8, "LLiLLi*LLi.", "n")
+BUILTIN(__sync_fetch_and_or_16, "LLLiLLLi*LLLi.", "n")
+
+BUILTIN(__sync_fetch_and_and, "v.", "")
+BUILTIN(__sync_fetch_and_and_1, "cc*c.", "n")
+BUILTIN(__sync_fetch_and_and_2, "ss*s.", "n")
+BUILTIN(__sync_fetch_and_and_4, "ii*i.", "n")
+BUILTIN(__sync_fetch_and_and_8, "LLiLLi*LLi.", "n")
+BUILTIN(__sync_fetch_and_and_16, "LLLiLLLi*LLLi.", "n")
+
+BUILTIN(__sync_fetch_and_xor, "v.", "")
+BUILTIN(__sync_fetch_and_xor_1, "cc*c.", "n")
+BUILTIN(__sync_fetch_and_xor_2, "ss*s.", "n")
+BUILTIN(__sync_fetch_and_xor_4, "ii*i.", "n")
+BUILTIN(__sync_fetch_and_xor_8, "LLiLLi*LLi.", "n")
+BUILTIN(__sync_fetch_and_xor_16, "LLLiLLLi*LLLi.", "n")
+
+
+BUILTIN(__sync_add_and_fetch, "v.", "")
+BUILTIN(__sync_add_and_fetch_1, "cc*c.", "n")
+BUILTIN(__sync_add_and_fetch_2, "ss*s.", "n")
+BUILTIN(__sync_add_and_fetch_4, "ii*i.", "n")
+BUILTIN(__sync_add_and_fetch_8, "LLiLLi*LLi.", "n")
+BUILTIN(__sync_add_and_fetch_16, "LLLiLLLi*LLLi.", "n")
+
+BUILTIN(__sync_sub_and_fetch, "v.", "")
+BUILTIN(__sync_sub_and_fetch_1, "cc*c.", "n")
+BUILTIN(__sync_sub_and_fetch_2, "ss*s.", "n")
+BUILTIN(__sync_sub_and_fetch_4, "ii*i.", "n")
+BUILTIN(__sync_sub_and_fetch_8, "LLiLLi*LLi.", "n")
+BUILTIN(__sync_sub_and_fetch_16, "LLLiLLLi*LLLi.", "n")
+
+BUILTIN(__sync_or_and_fetch, "v.", "")
+BUILTIN(__sync_or_and_fetch_1, "cc*c.", "n")
+BUILTIN(__sync_or_and_fetch_2, "ss*s.", "n")
+BUILTIN(__sync_or_and_fetch_4, "ii*i.", "n")
+BUILTIN(__sync_or_and_fetch_8, "LLiLLi*LLi.", "n")
+BUILTIN(__sync_or_and_fetch_16, "LLLiLLLi*LLLi.", "n")
+
+BUILTIN(__sync_and_and_fetch, "v.", "")
+BUILTIN(__sync_and_and_fetch_1, "cc*c.", "n")
+BUILTIN(__sync_and_and_fetch_2, "ss*s.", "n")
+BUILTIN(__sync_and_and_fetch_4, "ii*i.", "n")
+BUILTIN(__sync_and_and_fetch_8, "LLiLLi*LLi.", "n")
+BUILTIN(__sync_and_and_fetch_16, "LLLiLLLi*LLLi.", "n")
+
+BUILTIN(__sync_xor_and_fetch, "v.", "")
+BUILTIN(__sync_xor_and_fetch_1, "cc*c.", "n")
+BUILTIN(__sync_xor_and_fetch_2, "ss*s.", "n")
+BUILTIN(__sync_xor_and_fetch_4, "ii*i.", "n")
+BUILTIN(__sync_xor_and_fetch_8, "LLiLLi*LLi.", "n")
+BUILTIN(__sync_xor_and_fetch_16, "LLLiLLLi*LLLi.", "n")
+
+BUILTIN(__sync_bool_compare_and_swap, "v.", "")
+BUILTIN(__sync_bool_compare_and_swap_1, "bcD*cc.", "n")
+BUILTIN(__sync_bool_compare_and_swap_2, "bsD*ss.", "n")
+BUILTIN(__sync_bool_compare_and_swap_4, "biD*ii.", "n")
+BUILTIN(__sync_bool_compare_and_swap_8, "bLLiD*LLiLLi.", "n")
+BUILTIN(__sync_bool_compare_and_swap_16, "bLLLiD*LLLiLLLi.", "n")
+
+BUILTIN(__sync_val_compare_and_swap, "v.", "")
+BUILTIN(__sync_val_compare_and_swap_1, "ccD*cc.", "n")
+BUILTIN(__sync_val_compare_and_swap_2, "ssD*ss.", "n")
+BUILTIN(__sync_val_compare_and_swap_4, "iiD*ii.", "n")
+BUILTIN(__sync_val_compare_and_swap_8, "LLiLLiD*LLiLLi.", "n")
+BUILTIN(__sync_val_compare_and_swap_16, "LLLiLLLiD*LLLiLLLi.", "n")
+
+BUILTIN(__sync_lock_test_and_set, "v.", "")
+BUILTIN(__sync_lock_test_and_set_1, "cc*c.", "n")
+BUILTIN(__sync_lock_test_and_set_2, "ss*s.", "n")
+BUILTIN(__sync_lock_test_and_set_4, "ii*i.", "n")
+BUILTIN(__sync_lock_test_and_set_8, "LLiLLi*LLi.", "n")
+BUILTIN(__sync_lock_test_and_set_16, "LLLiLLLi*LLLi.", "n")
+
+BUILTIN(__sync_lock_release, "v.", "")
+BUILTIN(__sync_lock_release_1, "vc*.", "n")
+BUILTIN(__sync_lock_release_2, "vs*.", "n")
+BUILTIN(__sync_lock_release_4, "vi*.", "n")
+BUILTIN(__sync_lock_release_8, "vLLi*.", "n")
+BUILTIN(__sync_lock_release_16, "vLLLi*.", "n")
+
+
+
+// Non-overloaded atomic builtins.
+BUILTIN(__sync_synchronize, "v.", "n")
+// LLVM instruction builtin [Clang extension].
+BUILTIN(__builtin_llvm_memory_barrier,"vbbbbb", "n")
+// GCC does not support these, they are a Clang extension.
+BUILTIN(__sync_fetch_and_min, "ii*i", "n")
+BUILTIN(__sync_fetch_and_max, "ii*i", "n")
+BUILTIN(__sync_fetch_and_umin, "UiUi*Ui", "n")
+BUILTIN(__sync_fetch_and_umax, "UiUi*Ui", "n")
+
+// Random libc builtins.
+BUILTIN(__builtin_abort, "v", "Fnr")
+BUILTIN(__builtin_index, "c*cC*i", "Fn")
+BUILTIN(__builtin_rindex, "c*cC*i", "Fn")
+
+
+
+// C99 library functions
+// C99 stdlib.h
+LIBBUILTIN(abort, "v",            "fr",    "stdlib.h")
+LIBBUILTIN(calloc, "v*zz",        "f",     "stdlib.h")
+LIBBUILTIN(exit, "vi",            "fr",    "stdlib.h")
+LIBBUILTIN(_Exit, "vi",           "fr",    "stdlib.h")
+LIBBUILTIN(malloc, "v*z",         "f",     "stdlib.h")
+LIBBUILTIN(realloc, "v*v*z",      "f",     "stdlib.h")
+// C99 string.h
+LIBBUILTIN(memcpy, "v*v*vC*z",    "f",     "string.h")
+LIBBUILTIN(memmove, "v*v*vC*z",   "f",     "string.h")
+LIBBUILTIN(strcpy, "c*c*cC*",     "f",     "string.h")
+LIBBUILTIN(strncpy, "c*c*cC*z",   "f",     "string.h")
+LIBBUILTIN(strcat, "c*c*cC*",     "f",     "string.h")
+LIBBUILTIN(strncat, "c*c*cC*z",   "f",     "string.h")
+LIBBUILTIN(strxfrm, "zc*cC*z",    "f",     "string.h")
+LIBBUILTIN(memchr, "v*vC*iz",     "f",     "string.h")
+LIBBUILTIN(strchr, "c*cC*i",      "f",     "string.h")
+LIBBUILTIN(strcspn, "zcC*cC*",    "f",     "string.h")
+LIBBUILTIN(strpbrk, "c*cC*cC*",   "f",     "string.h")
+LIBBUILTIN(strrchr, "c*cC*i",     "f",     "string.h")
+LIBBUILTIN(strspn, "zcC*cC*",     "f",     "string.h")
+LIBBUILTIN(strstr, "c*cC*cC*",    "f",     "string.h")
+LIBBUILTIN(strtok, "c*c*cC*",     "f",     "string.h")
+LIBBUILTIN(memset, "v*v*iz",      "f",     "string.h")
+LIBBUILTIN(strerror, "c*i",       "f",     "string.h")
+LIBBUILTIN(strlen, "zcC*",        "f",     "string.h")
+// C99 stdio.h
+LIBBUILTIN(printf, "icC*.",       "fp:0:", "stdio.h")
+LIBBUILTIN(fprintf, "iP*cC*.",    "fp:1:", "stdio.h")
+LIBBUILTIN(snprintf, "ic*zcC*.",  "fp:2:", "stdio.h")
+LIBBUILTIN(sprintf, "ic*cC*.",    "fp:1:", "stdio.h")
+LIBBUILTIN(vprintf, "icC*a",      "fP:0:", "stdio.h")
+LIBBUILTIN(vfprintf, "i.",        "fP:1:", "stdio.h")
+LIBBUILTIN(vsnprintf, "ic*zcC*a", "fP:2:", "stdio.h")
+LIBBUILTIN(vsprintf, "ic*cC*a",   "fP:1:", "stdio.h")
+// C99
+LIBBUILTIN(longjmp, "vJi",        "fr",    "setjmp.h")
+
+// Non-C library functions
+// FIXME: Non-C-standard stuff shouldn't be builtins in non-GNU mode!
+LIBBUILTIN(alloca, "v*z",         "f",     "stdlib.h")
+// POSIX string.h
+LIBBUILTIN(stpcpy, "c*c*cC*",     "f",     "string.h")
+LIBBUILTIN(stpncpy, "c*c*cC*z",   "f",     "string.h")
+LIBBUILTIN(strdup, "c*cC*",       "f",     "string.h")
+LIBBUILTIN(strndup, "c*cC*z",     "f",     "string.h")
+// POSIX strings.h
+LIBBUILTIN(index, "c*cC*i",       "f",     "strings.h")
+LIBBUILTIN(rindex, "c*cC*i",      "f",     "strings.h")
+LIBBUILTIN(bzero, "vv*z",         "f",     "strings.h")
+// POSIX unistd.h
+LIBBUILTIN(_exit, "vi",           "fr",    "unistd.h")
+// POSIX setjmp.h
+LIBBUILTIN(_longjmp, "vJi",       "fr",    "setjmp.h")
+LIBBUILTIN(siglongjmp, "vSJi",    "fr",    "setjmp.h")
+
+// FIXME: This type isn't very correct, it should be
+//   id objc_msgSend(id, SEL)
+// but we need new type letters for that.
+LIBBUILTIN(objc_msgSend, "v*.",   "f",     "objc/message.h")
+
+// Builtin math library functions
+LIBBUILTIN(pow, "ddd", "fe", "math.h")
+LIBBUILTIN(powl, "LdLdLd", "fe", "math.h")
+LIBBUILTIN(powf, "fff", "fe", "math.h")
+
+LIBBUILTIN(sqrt, "dd", "fe", "math.h")
+LIBBUILTIN(sqrtl, "LdLd", "fe", "math.h")
+LIBBUILTIN(sqrtf, "ff", "fe", "math.h")
+
+LIBBUILTIN(sin, "dd", "fe", "math.h")
+LIBBUILTIN(sinl, "LdLd", "fe", "math.h")
+LIBBUILTIN(sinf, "ff", "fe", "math.h")
+
+LIBBUILTIN(cos, "dd", "fe", "math.h")
+LIBBUILTIN(cosl, "LdLd", "fe", "math.h")
+LIBBUILTIN(cosf, "ff", "fe", "math.h")
+
+#undef BUILTIN
+#undef LIBBUILTIN
diff --git a/include/clang/Basic/Builtins.h b/include/clang/Basic/Builtins.h
new file mode 100644
index 0000000..07f091a
--- /dev/null
+++ b/include/clang/Basic/Builtins.h
@@ -0,0 +1,142 @@
+//===--- Builtins.h - Builtin function header -------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines enum values for all the target-independent builtin
+// functions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_BUILTINS_H
+#define LLVM_CLANG_BASIC_BUILTINS_H
+
+#include <cstring>
+
+// VC++ defines 'alloca' as an object-like macro, which interferes with our
+// builtins.
+#undef alloca
+
+namespace llvm {
+  template <typename T> class SmallVectorImpl;
+}
+
+namespace clang {
+  class TargetInfo;
+  class IdentifierTable;
+  class ASTContext;
+  class QualType;
+
+namespace Builtin {
+enum ID {
+  NotBuiltin  = 0,      // This is not a builtin function.
+#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
+#include "clang/Basic/Builtins.def"
+  FirstTSBuiltin
+};
+
+struct Info {
+  const char *Name, *Type, *Attributes, *HeaderName;
+  bool Suppressed;
+
+  bool operator==(const Info &RHS) const {
+    return !strcmp(Name, RHS.Name) &&
+           !strcmp(Type, RHS.Type) &&
+           !strcmp(Attributes, RHS.Attributes);
+  }
+  bool operator!=(const Info &RHS) const { return !(*this == RHS); }
+};
+
+/// Builtin::Context - This holds information about target-independent and
+/// target-specific builtins, allowing easy queries by clients.
+class Context {
+  const Info *TSRecords;
+  unsigned NumTSRecords;
+public:
+  Context(const TargetInfo &Target);
+
+  /// InitializeBuiltins - Mark the identifiers for all the builtins with their
+  /// appropriate builtin ID # and mark any non-portable builtin identifiers as
+  /// such.
+  void InitializeBuiltins(IdentifierTable &Table, bool NoBuiltins = false);
+
+  /// \brief Popular the vector with the names of all of the builtins.
+  void GetBuiltinNames(llvm::SmallVectorImpl<const char *> &Names,
+                       bool NoBuiltins);
+
+  /// Builtin::GetName - Return the identifier name for the specified builtin,
+  /// e.g. "__builtin_abs".
+  const char *GetName(unsigned ID) const {
+    return GetRecord(ID).Name;
+  }
+
+  /// GetTypeString - Get the type descriptor string for the specified builtin.
+  const char *GetTypeString(unsigned ID) const {
+    return GetRecord(ID).Type;
+  }
+
+  /// isConst - Return true if this function has no side effects and doesn't
+  /// read memory.
+  bool isConst(unsigned ID) const {
+    return strchr(GetRecord(ID).Attributes, 'c') != 0;
+  }
+
+  /// isNoThrow - Return true if we know this builtin never throws an exception.
+  bool isNoThrow(unsigned ID) const {
+    return strchr(GetRecord(ID).Attributes, 'n') != 0;
+  }
+
+  /// isNoReturn - Return true if we know this builtin never returns.
+  bool isNoReturn(unsigned ID) const {
+    return strchr(GetRecord(ID).Attributes, 'r') != 0;
+  }
+
+  /// isLibFunction - Return true if this is a builtin for a libc/libm function,
+  /// with a "__builtin_" prefix (e.g. __builtin_abs).
+  bool isLibFunction(unsigned ID) const {
+    return strchr(GetRecord(ID).Attributes, 'F') != 0;
+  }
+
+  /// \brief Determines whether this builtin is a predefined libc/libm
+  /// function, such as "malloc", where we know the signature a
+  /// priori.
+  bool isPredefinedLibFunction(unsigned ID) const {
+    return strchr(GetRecord(ID).Attributes, 'f') != 0;
+  }
+
+  /// \brief If this is a library function that comes from a specific
+  /// header, retrieve that header name.
+  const char *getHeaderName(unsigned ID) const {
+    return GetRecord(ID).HeaderName;
+  }
+
+  /// \brief Determine whether this builtin is like printf in its
+  /// formatting rules and, if so, set the index to the format string
+  /// argument and whether this function as a va_list argument.
+  bool isPrintfLike(unsigned ID, unsigned &FormatIdx, bool &HasVAListArg);
+
+  /// hasVAListUse - Return true of the specified builtin uses __builtin_va_list
+  /// as an operand or return type.
+  bool hasVAListUse(unsigned ID) const {
+    return strpbrk(GetRecord(ID).Type, "Aa") != 0;
+  }
+
+  /// isConstWithoutErrno - Return true if this function has no side
+  /// effects and doesn't read memory, except for possibly errno. Such
+  /// functions can be const when the MathErrno lang option is
+  /// disabled.
+  bool isConstWithoutErrno(unsigned ID) const {
+    return strchr(GetRecord(ID).Attributes, 'e') != 0;
+  }
+
+private:
+  const Info &GetRecord(unsigned ID) const;
+};
+
+}
+} // end namespace clang
+#endif
diff --git a/include/clang/Basic/BuiltinsARM.def b/include/clang/Basic/BuiltinsARM.def
new file mode 100644
index 0000000..4973076
--- /dev/null
+++ b/include/clang/Basic/BuiltinsARM.def
@@ -0,0 +1,20 @@
+//===--- BuiltinsARM.def - ARM Builtin function database ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the ARM-specific builtin function database.  Users of
+// this file must define the BUILTIN macro to make use of this information.
+//
+//===----------------------------------------------------------------------===//
+
+// The format of this database matches clang/Basic/Builtins.def.
+
+// FIXME: This is just a placeholder. NEON intrinsics should be listed here.
+BUILTIN(__builtin_thread_pointer, "v*", "")
+
+#undef BUILTIN
diff --git a/include/clang/Basic/BuiltinsPPC.def b/include/clang/Basic/BuiltinsPPC.def
new file mode 100644
index 0000000..287bba9
--- /dev/null
+++ b/include/clang/Basic/BuiltinsPPC.def
@@ -0,0 +1,114 @@
+//===--- BuiltinsPPC.def - PowerPC Builtin function database ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the PowerPC-specific builtin function database.  Users of
+// this file must define the BUILTIN macro to make use of this information.
+//
+//===----------------------------------------------------------------------===//
+
+// FIXME: this needs to be the full list supported by GCC.  Right now, I'm just
+// adding stuff on demand.
+
+// The format of this database matches clang/Basic/Builtins.def.
+
+// This is just a placeholder, the types and attributes are wrong.
+BUILTIN(__builtin_altivec_abs_v16qi, "V16UcV16Sc", "")
+BUILTIN(__builtin_altivec_abs_v8hi, "V8UsV8Ss", "")
+BUILTIN(__builtin_altivec_abs_v4si, "V4UiV4Si", "")
+
+BUILTIN(__builtin_altivec_abss_v16qi, "V16UcV16Sc", "")
+BUILTIN(__builtin_altivec_abss_v8hi, "V8UsV8Ss", "")
+BUILTIN(__builtin_altivec_abss_v4si, "V4UiV4Si", "")
+
+BUILTIN(__builtin_altivec_vaddcuw, "V4UiV4UiV4Ui", "")
+
+BUILTIN(__builtin_altivec_vaddsbs, "V16ScV16ScV16Sc", "")
+BUILTIN(__builtin_altivec_vaddubs, "V16UcV16UcV16Uc", "")
+BUILTIN(__builtin_altivec_vaddshs, "V8SsV8SsV8Ss", "")
+BUILTIN(__builtin_altivec_vadduhs, "V8UsV8UsV8Us", "")
+BUILTIN(__builtin_altivec_vaddsws, "V4SiV4SiV4Si", "")
+BUILTIN(__builtin_altivec_vadduws, "V4UiV4UiV4Ui", "")
+
+BUILTIN(__builtin_altivec_vsubsbs, "V16ScV16ScV16Sc", "")
+BUILTIN(__builtin_altivec_vsububs, "V16UcV16UcV16Uc", "")
+BUILTIN(__builtin_altivec_vsubshs, "V8SsV8SsV8Ss", "")
+BUILTIN(__builtin_altivec_vsubuhs, "V8UsV8UsV8Us", "")
+BUILTIN(__builtin_altivec_vsubsws, "V4SiV4SiV4Si", "")
+BUILTIN(__builtin_altivec_vsubuws, "V4UiV4UiV4Ui", "")
+
+BUILTIN(__builtin_altivec_vavgsb, "V16ScV16ScV16Sc", "")
+BUILTIN(__builtin_altivec_vavgub, "V16UcV16UcV16Uc", "")
+BUILTIN(__builtin_altivec_vavgsh, "V8SsV8SsV8Ss", "")
+BUILTIN(__builtin_altivec_vavguh, "V8UsV8UsV8Us", "")
+BUILTIN(__builtin_altivec_vavgsw, "V4SiV4SiV4Si", "")
+BUILTIN(__builtin_altivec_vavguw, "V4UiV4UiV4Ui", "")
+
+BUILTIN(__builtin_altivec_stvx, "vV4iiv*", "")
+BUILTIN(__builtin_altivec_stvxl, "vV4iiv*", "")
+BUILTIN(__builtin_altivec_stvebx, "vV16civ*", "")
+BUILTIN(__builtin_altivec_stvehx, "vV8siv*", "")
+BUILTIN(__builtin_altivec_stvewx, "vV4iiv*", "")
+
+BUILTIN(__builtin_altivec_vcmpbfp, "V4iV4fV4f", "")
+
+BUILTIN(__builtin_altivec_vcmpgefp, "V4iV4fV4f", "")
+
+BUILTIN(__builtin_altivec_vcmpequb, "V16cV16cV16c", "")
+BUILTIN(__builtin_altivec_vcmpequh, "V8sV8sV8s", "")
+BUILTIN(__builtin_altivec_vcmpequw, "V4iV4iV4i", "")
+BUILTIN(__builtin_altivec_vcmpeqfp, "V4iV4fV4f", "")
+
+BUILTIN(__builtin_altivec_vcmpgtsb, "V16cV16ScV16Sc", "")
+BUILTIN(__builtin_altivec_vcmpgtub, "V16cV16UcV16Uc", "")
+BUILTIN(__builtin_altivec_vcmpgtsh, "V8sV8SsV8Ss", "")
+BUILTIN(__builtin_altivec_vcmpgtuh, "V8sV8UsV8Us", "")
+BUILTIN(__builtin_altivec_vcmpgtsw, "V4iV4SiV4Si", "")
+BUILTIN(__builtin_altivec_vcmpgtuw, "V4iV4UiV4Ui", "")
+BUILTIN(__builtin_altivec_vcmpgtfp, "V4iV4fV4f", "")
+
+BUILTIN(__builtin_altivec_vmaxsb, "V16ScV16ScV16Sc", "")
+BUILTIN(__builtin_altivec_vmaxub, "V16UcV16UcV16Uc", "")
+BUILTIN(__builtin_altivec_vmaxsh, "V8SsV8SsV8Ss", "")
+BUILTIN(__builtin_altivec_vmaxuh, "V8UsV8UsV8Us", "")
+BUILTIN(__builtin_altivec_vmaxsw, "V4SiV4SiV4Si", "")
+BUILTIN(__builtin_altivec_vmaxuw, "V4UiV4UiV4Ui", "")
+BUILTIN(__builtin_altivec_vmaxfp, "V4fV4fV4f", "")
+
+BUILTIN(__builtin_altivec_mfvscr, "V8Us", "")
+
+BUILTIN(__builtin_altivec_vminsb, "V16ScV16ScV16Sc", "")
+BUILTIN(__builtin_altivec_vminub, "V16UcV16UcV16Uc", "")
+BUILTIN(__builtin_altivec_vminsh, "V8SsV8SsV8Ss", "")
+BUILTIN(__builtin_altivec_vminuh, "V8UsV8UsV8Us", "")
+BUILTIN(__builtin_altivec_vminsw, "V4SiV4SiV4Si", "")
+BUILTIN(__builtin_altivec_vminuw, "V4UiV4UiV4Ui", "")
+BUILTIN(__builtin_altivec_vminfp, "V4fV4fV4f", "")
+
+BUILTIN(__builtin_altivec_mtvscr, "vV4i", "")
+
+BUILTIN(__builtin_altivec_vcmpbfp_p, "iiV4fV4f", "")
+
+BUILTIN(__builtin_altivec_vcmpgefp_p, "iiV4fV4f", "")
+
+BUILTIN(__builtin_altivec_vcmpequb_p, "iiV16cV16c", "")
+BUILTIN(__builtin_altivec_vcmpequh_p, "iiV8sV8s", "")
+BUILTIN(__builtin_altivec_vcmpequw_p, "iiV4iV4i", "")
+BUILTIN(__builtin_altivec_vcmpeqfp_p, "iiV4fV4f", "")
+
+BUILTIN(__builtin_altivec_vcmpgtsb_p, "iiV16ScV16Sc", "")
+BUILTIN(__builtin_altivec_vcmpgtub_p, "iiV16UcV16Uc", "")
+BUILTIN(__builtin_altivec_vcmpgtsh_p, "iiV8SsV8Ss", "")
+BUILTIN(__builtin_altivec_vcmpgtuh_p, "iiV8UsV8Us", "")
+BUILTIN(__builtin_altivec_vcmpgtsw_p, "iiV4SiV4Si", "")
+BUILTIN(__builtin_altivec_vcmpgtuw_p, "iiV4UiV4Ui", "")
+BUILTIN(__builtin_altivec_vcmpgtfp_p, "iiV4fV4f", "")
+
+// FIXME: Obviously incomplete.
+
+#undef BUILTIN
diff --git a/include/clang/Basic/BuiltinsX86.def b/include/clang/Basic/BuiltinsX86.def
new file mode 100644
index 0000000..a878dd1
--- /dev/null
+++ b/include/clang/Basic/BuiltinsX86.def
@@ -0,0 +1,328 @@
+//===--- BuiltinsX86.def - X86 Builtin function database --------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the X86-specific builtin function database.  Users of
+// this file must define the BUILTIN macro to make use of this information.
+//
+//===----------------------------------------------------------------------===//
+
+// The format of this database matches clang/Basic/Builtins.def.
+
+// FIXME: In GCC, these builtins are defined depending on whether support for
+// MMX/SSE/etc is turned on. We should do this too.
+
+// FIXME: Ideally we would be able to pull this information from what
+// LLVM already knows about X86 builtins. We need to match the LLVM
+// definition anyway, since code generation will lower to the
+// intrinsic if one exists.
+
+BUILTIN(__builtin_ia32_emms  , "v", "")
+
+// FIXME: Are these nothrow/const?
+
+// SSE intrinsics.
+BUILTIN(__builtin_ia32_comieq, "iV4fV4f", "")
+BUILTIN(__builtin_ia32_comilt, "iV4fV4f", "")
+BUILTIN(__builtin_ia32_comile, "iV4fV4f", "")
+BUILTIN(__builtin_ia32_comigt, "iV4fV4f", "")
+BUILTIN(__builtin_ia32_comige, "iV4fV4f", "")
+BUILTIN(__builtin_ia32_comineq, "iV4fV4f", "")
+BUILTIN(__builtin_ia32_ucomieq, "iV4fV4f", "")
+BUILTIN(__builtin_ia32_ucomilt, "iV4fV4f", "")
+BUILTIN(__builtin_ia32_ucomile, "iV4fV4f", "")
+BUILTIN(__builtin_ia32_ucomigt, "iV4fV4f", "")
+BUILTIN(__builtin_ia32_ucomige, "iV4fV4f", "")
+BUILTIN(__builtin_ia32_ucomineq, "iV4fV4f", "")
+BUILTIN(__builtin_ia32_comisdeq, "iV2dV2d", "")
+BUILTIN(__builtin_ia32_comisdlt, "iV2dV2d", "")
+BUILTIN(__builtin_ia32_comisdle, "iV2dV2d", "")
+BUILTIN(__builtin_ia32_comisdgt, "iV2dV2d", "")
+BUILTIN(__builtin_ia32_comisdge, "iV2dV2d", "")
+BUILTIN(__builtin_ia32_comisdneq, "iV2dV2d", "")
+BUILTIN(__builtin_ia32_ucomisdeq, "iV2dV2d", "")
+BUILTIN(__builtin_ia32_ucomisdlt, "iV2dV2d", "")
+BUILTIN(__builtin_ia32_ucomisdle, "iV2dV2d", "")
+BUILTIN(__builtin_ia32_ucomisdgt, "iV2dV2d", "")
+BUILTIN(__builtin_ia32_ucomisdge, "iV2dV2d", "")
+BUILTIN(__builtin_ia32_ucomisdneq, "iV2dV2d", "")
+BUILTIN(__builtin_ia32_cmpps, "V4fV4fV4fc", "")
+BUILTIN(__builtin_ia32_cmpss, "V4fV4fV4fc", "")
+BUILTIN(__builtin_ia32_minps, "V4fV4fV4f", "")
+BUILTIN(__builtin_ia32_maxps, "V4fV4fV4f", "")
+BUILTIN(__builtin_ia32_minss, "V4fV4fV4f", "")
+BUILTIN(__builtin_ia32_maxss, "V4fV4fV4f", "")
+BUILTIN(__builtin_ia32_paddsb, "V8cV8cV8c", "")
+BUILTIN(__builtin_ia32_paddsw, "V4sV4sV4s", "")
+BUILTIN(__builtin_ia32_psubsb, "V8cV8cV8c", "")
+BUILTIN(__builtin_ia32_psubsw, "V4sV4sV4s", "")
+BUILTIN(__builtin_ia32_paddusb, "V8cV8cV8c", "")
+BUILTIN(__builtin_ia32_paddusw, "V4sV4sV4s", "")
+BUILTIN(__builtin_ia32_psubusb, "V8cV8cV8c", "")
+BUILTIN(__builtin_ia32_psubusw, "V4sV4sV4s", "")
+BUILTIN(__builtin_ia32_pmulhw, "V4sV4sV4s", "")
+BUILTIN(__builtin_ia32_pmulhuw, "V4sV4sV4s", "")
+BUILTIN(__builtin_ia32_pavgb, "V8cV8cV8c", "")
+BUILTIN(__builtin_ia32_pavgw, "V4sV4sV4s", "")
+BUILTIN(__builtin_ia32_pcmpeqb, "V8cV8cV8c", "")
+BUILTIN(__builtin_ia32_pcmpeqw, "V4sV4sV4s", "")
+BUILTIN(__builtin_ia32_pcmpeqd, "V2iV2iV2i", "")
+BUILTIN(__builtin_ia32_pcmpgtb, "V8cV8cV8c", "")
+BUILTIN(__builtin_ia32_pcmpgtw, "V4sV4sV4s", "")
+BUILTIN(__builtin_ia32_pcmpgtd, "V2iV2iV2i", "")
+BUILTIN(__builtin_ia32_pmaxub, "V8cV8cV8c", "")
+BUILTIN(__builtin_ia32_pmaxsw, "V4sV4sV4s", "")
+BUILTIN(__builtin_ia32_pminub, "V8cV8cV8c", "")
+BUILTIN(__builtin_ia32_pminsw, "V4sV4sV4s", "")
+BUILTIN(__builtin_ia32_punpcklwd, "V4sV4sV4s", "")
+BUILTIN(__builtin_ia32_cmppd, "V2dV2dV2dc", "")
+BUILTIN(__builtin_ia32_cmpsd, "V2dV2dV2dc", "")
+BUILTIN(__builtin_ia32_minpd, "V2dV2dV2d", "")
+BUILTIN(__builtin_ia32_maxpd, "V2dV2dV2d", "")
+BUILTIN(__builtin_ia32_minsd, "V2dV2dV2d", "")
+BUILTIN(__builtin_ia32_maxsd, "V2dV2dV2d", "")
+BUILTIN(__builtin_ia32_paddsb128, "V16cV16cV16c", "")
+BUILTIN(__builtin_ia32_paddsw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_psubsb128, "V16cV16cV16c", "")
+BUILTIN(__builtin_ia32_psubsw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_paddusb128, "V16cV16cV16c", "")
+BUILTIN(__builtin_ia32_paddusw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_psubusb128, "V16cV16cV16c", "")
+BUILTIN(__builtin_ia32_psubusw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_pmulhw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_pavgb128, "V16cV16cV16c", "")
+BUILTIN(__builtin_ia32_pavgw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_pcmpeqb128, "V16cV16cV16c", "")
+BUILTIN(__builtin_ia32_pcmpeqw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_pcmpeqd128, "V4iV4iV4i", "")
+BUILTIN(__builtin_ia32_pcmpgtb128, "V16cV16cV16c", "")
+BUILTIN(__builtin_ia32_pcmpgtw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_pcmpgtd128, "V4iV4iV4i", "")
+BUILTIN(__builtin_ia32_pmaxub128, "V16cV16cV16c", "")
+BUILTIN(__builtin_ia32_pmaxsw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_pminub128, "V16cV16cV16c", "")
+BUILTIN(__builtin_ia32_pminsw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_packsswb128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_packssdw128, "V4iV4iV4i", "")
+BUILTIN(__builtin_ia32_packuswb128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_pmulhuw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_addsubps, "V4fV4fV4f", "")
+BUILTIN(__builtin_ia32_addsubpd, "V2dV2dV2d", "")
+BUILTIN(__builtin_ia32_haddps, "V4fV4fV4f", "")
+BUILTIN(__builtin_ia32_haddpd, "V2dV2dV2d", "")
+BUILTIN(__builtin_ia32_hsubps, "V4fV4fV4f", "")
+BUILTIN(__builtin_ia32_hsubpd, "V2dV2dV2d", "")
+BUILTIN(__builtin_ia32_phaddw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_phaddw, "V4sV4sV4s", "")
+BUILTIN(__builtin_ia32_phaddd128, "V4iV4iV4i", "")
+BUILTIN(__builtin_ia32_phaddd, "V2iV2iV2i", "")
+BUILTIN(__builtin_ia32_phaddsw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_phaddsw, "V4sV4sV4s", "")
+BUILTIN(__builtin_ia32_phsubw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_phsubw, "V4sV4sV4s", "")
+BUILTIN(__builtin_ia32_phsubd128, "V4iV4iV4i", "")
+BUILTIN(__builtin_ia32_phsubd, "V2iV2iV2i", "")
+BUILTIN(__builtin_ia32_phsubsw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_phsubsw, "V4sV4sV4s", "")
+BUILTIN(__builtin_ia32_pmaddubsw128, "V16cV16cV16c", "")
+BUILTIN(__builtin_ia32_pmaddubsw, "V8cV8cV8c", "")
+BUILTIN(__builtin_ia32_pmulhrsw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_pmulhrsw, "V4sV4sV4s", "")
+BUILTIN(__builtin_ia32_pshufb128, "V16cV16cV16c", "")
+BUILTIN(__builtin_ia32_pshufb, "V8cV8cV8c", "")
+BUILTIN(__builtin_ia32_psignb128, "V16cV16cV16c", "")
+BUILTIN(__builtin_ia32_psignb, "V8cV8cV8c", "")
+BUILTIN(__builtin_ia32_psignw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_psignw, "V4sV4sV4s", "")
+BUILTIN(__builtin_ia32_psignd128, "V4iV4iV4i", "")
+BUILTIN(__builtin_ia32_psignd, "V2iV2iV2i", "")
+BUILTIN(__builtin_ia32_pabsb128, "V16cV16c", "")
+BUILTIN(__builtin_ia32_pabsb, "V8cV8c", "")
+BUILTIN(__builtin_ia32_pabsw128, "V8sV8s", "")
+BUILTIN(__builtin_ia32_pabsw, "V4sV4s", "")
+BUILTIN(__builtin_ia32_pabsd128, "V4iV4i", "")
+BUILTIN(__builtin_ia32_pabsd, "V2iV2i", "")
+BUILTIN(__builtin_ia32_psllw, "V4sV4sV1LLi", "")
+BUILTIN(__builtin_ia32_pslld, "V2iV2iV1LLi", "")
+BUILTIN(__builtin_ia32_psllq, "V1LLiV1LLiV1LLi", "")
+BUILTIN(__builtin_ia32_psrlw, "V4sV4sV1LLi", "")
+BUILTIN(__builtin_ia32_psrld, "V2iV2iV1LLi", "")
+BUILTIN(__builtin_ia32_psrlq, "V1LLiV1LLiV1LLi", "")
+BUILTIN(__builtin_ia32_psraw, "V4sV4sV1LLi", "")
+BUILTIN(__builtin_ia32_psrad, "V2iV2iV1LLi", "")
+BUILTIN(__builtin_ia32_pmaddwd, "V2iV4sV4s", "")
+BUILTIN(__builtin_ia32_packsswb, "V8cV4sV4s", "")
+BUILTIN(__builtin_ia32_packssdw, "V4sV2iV2i", "")
+BUILTIN(__builtin_ia32_packuswb, "V8cV4sV4s", "")
+BUILTIN(__builtin_ia32_ldmxcsr, "vUi", "")
+BUILTIN(__builtin_ia32_stmxcsr, "Ui", "")
+BUILTIN(__builtin_ia32_cvtpi2ps, "V4fV4fV2i", "")
+BUILTIN(__builtin_ia32_cvtps2pi, "V2iV4f", "")
+BUILTIN(__builtin_ia32_cvtss2si, "iV4f", "")
+BUILTIN(__builtin_ia32_cvtss2si64, "LLiV4f", "")
+BUILTIN(__builtin_ia32_cvttps2pi, "V2iV4f", "")
+BUILTIN(__builtin_ia32_maskmovq, "vV8cV8cc*", "")
+BUILTIN(__builtin_ia32_loadups, "V4ffC*", "")
+BUILTIN(__builtin_ia32_storeups, "vf*V4f", "")
+BUILTIN(__builtin_ia32_storehps, "vV2i*V4f", "")
+BUILTIN(__builtin_ia32_storelps, "vV2i*V4f", "")
+BUILTIN(__builtin_ia32_movmskps, "iV4f", "")
+BUILTIN(__builtin_ia32_pmovmskb, "iV8c", "")
+BUILTIN(__builtin_ia32_movntps, "vf*V4f", "")
+BUILTIN(__builtin_ia32_movntq, "vV1LLi*V1LLi", "")
+BUILTIN(__builtin_ia32_sfence, "v", "")
+BUILTIN(__builtin_ia32_psadbw, "V4sV8cV8c", "")
+BUILTIN(__builtin_ia32_rcpps, "V4fV4f", "")
+BUILTIN(__builtin_ia32_rcpss, "V4fV4f", "")
+BUILTIN(__builtin_ia32_rsqrtps, "V4fV4f", "")
+BUILTIN(__builtin_ia32_rsqrtss, "V4fV4f", "")
+BUILTIN(__builtin_ia32_sqrtps, "V4fV4f", "")
+BUILTIN(__builtin_ia32_sqrtss, "V4fV4f", "")
+BUILTIN(__builtin_ia32_maskmovdqu, "vV16cV16cc*", "")
+BUILTIN(__builtin_ia32_loadupd, "V2ddC*", "")
+BUILTIN(__builtin_ia32_storeupd, "vd*V2d", "")
+BUILTIN(__builtin_ia32_movmskpd, "iV2d", "")
+BUILTIN(__builtin_ia32_pmovmskb128, "iV16c", "")
+BUILTIN(__builtin_ia32_movnti, "vi*i", "")
+BUILTIN(__builtin_ia32_movntpd, "vd*V2d", "")
+BUILTIN(__builtin_ia32_movntdq, "vV2LLi*V2LLi", "")
+BUILTIN(__builtin_ia32_psadbw128, "V2LLiV16cV16c", "")
+BUILTIN(__builtin_ia32_sqrtpd, "V2dV2d", "")
+BUILTIN(__builtin_ia32_sqrtsd, "V2dV2d", "")
+BUILTIN(__builtin_ia32_cvtdq2pd, "V2dV4i", "")
+BUILTIN(__builtin_ia32_cvtdq2ps, "V4fV4i", "")
+BUILTIN(__builtin_ia32_cvtpd2dq, "V2LLiV2d", "")
+BUILTIN(__builtin_ia32_cvtpd2pi, "V2iV2d", "")
+BUILTIN(__builtin_ia32_cvtpd2ps, "V4fV2d", "")
+BUILTIN(__builtin_ia32_cvttpd2dq, "V4iV2d", "")
+BUILTIN(__builtin_ia32_cvttpd2pi, "V2iV2d", "")
+BUILTIN(__builtin_ia32_cvtpi2pd, "V2dV2i", "")
+BUILTIN(__builtin_ia32_cvtsd2si, "iV2d", "")
+BUILTIN(__builtin_ia32_cvtsd2si64, "LLiV2d", "")
+BUILTIN(__builtin_ia32_cvtps2dq, "V4iV4f", "")
+BUILTIN(__builtin_ia32_cvtps2pd, "V2dV4f", "")
+BUILTIN(__builtin_ia32_cvttps2dq, "V4iV4f", "")
+BUILTIN(__builtin_ia32_clflush, "vvC*", "")
+BUILTIN(__builtin_ia32_lfence, "v", "")
+BUILTIN(__builtin_ia32_mfence, "v", "")
+BUILTIN(__builtin_ia32_loaddqu, "V16ccC*", "")
+BUILTIN(__builtin_ia32_storedqu, "vc*V16c", "")
+BUILTIN(__builtin_ia32_psllwi, "V4sV4si", "")
+BUILTIN(__builtin_ia32_pslldi, "V2iV2ii", "")
+BUILTIN(__builtin_ia32_psllqi, "V1LLiV1LLii", "")
+BUILTIN(__builtin_ia32_psrawi, "V4sV4si", "")
+BUILTIN(__builtin_ia32_psradi, "V2iV2ii", "")
+BUILTIN(__builtin_ia32_psrlwi, "V4sV4si", "")
+BUILTIN(__builtin_ia32_psrldi, "V2iV2ii", "")
+BUILTIN(__builtin_ia32_psrlqi, "V1LLiV1LLii", "")
+BUILTIN(__builtin_ia32_pmuludq, "V1LLiV2iV2i", "")
+BUILTIN(__builtin_ia32_pmuludq128, "V2LLiV4iV4i", "")
+BUILTIN(__builtin_ia32_psraw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_psrad128, "V4iV4iV4i", "")
+BUILTIN(__builtin_ia32_psrlw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_psrld128, "V4iV4iV4i", "")
+BUILTIN(__builtin_ia32_pslldqi128, "V2LLiV2LLii", "")
+BUILTIN(__builtin_ia32_psrldqi128, "V2LLiV2LLii", "")
+BUILTIN(__builtin_ia32_psrlq128, "V2LLiV2LLiV2LLi", "")
+BUILTIN(__builtin_ia32_psllw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_pslld128, "V4iV4iV4i", "")
+BUILTIN(__builtin_ia32_psllq128, "V2LLiV2LLiV2LLi", "")
+BUILTIN(__builtin_ia32_psllwi128, "V8sV8si", "")
+BUILTIN(__builtin_ia32_pslldi128, "V4iV4ii", "")
+BUILTIN(__builtin_ia32_psllqi128, "V2LLiV2LLii", "")
+BUILTIN(__builtin_ia32_psrlwi128, "V8sV8si", "")
+BUILTIN(__builtin_ia32_psrldi128, "V4iV4ii", "")
+BUILTIN(__builtin_ia32_psrlqi128, "V2LLiV2LLii", "")
+BUILTIN(__builtin_ia32_psrawi128, "V8sV8si", "")
+BUILTIN(__builtin_ia32_psradi128, "V4iV4ii", "")
+BUILTIN(__builtin_ia32_pmaddwd128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_monitor, "vv*UiUi", "")
+BUILTIN(__builtin_ia32_mwait, "vUiUi", "")
+BUILTIN(__builtin_ia32_lddqu, "V16ccC*", "")
+BUILTIN(__builtin_ia32_palignr128, "V16cV16cV16cc", "")
+BUILTIN(__builtin_ia32_palignr, "V8cV8cV8cc", "")
+BUILTIN(__builtin_ia32_insertps128, "V4fV4fV4fi", "")
+
+BUILTIN(__builtin_ia32_storelv4si, "vV2i*V2LLi", "")
+
+BUILTIN(__builtin_ia32_pblendvb128, "V16cV16cV16cV16c", "")
+BUILTIN(__builtin_ia32_pblendw128, "V8sV8sV8si", "")
+BUILTIN(__builtin_ia32_blendpd, "V2dV2dV2di", "")
+BUILTIN(__builtin_ia32_blendps, "V4fV4fV4fi", "")
+BUILTIN(__builtin_ia32_blendvpd, "V2dV2dV2dV2d", "")
+BUILTIN(__builtin_ia32_blendvps, "V4fV4fV4fV4f", "")
+
+BUILTIN(__builtin_ia32_packusdw128, "V8sV4iV4i", "")
+BUILTIN(__builtin_ia32_pmaxsb128, "V16cV16cV16c", "")
+BUILTIN(__builtin_ia32_pmaxsd128, "V4iV4iV4i", "")
+BUILTIN(__builtin_ia32_pmaxud128, "V4iV4iV4i", "")
+BUILTIN(__builtin_ia32_pmaxuw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_pminsb128, "V16cV16cV16c", "")
+BUILTIN(__builtin_ia32_pminsd128, "V4iV4iV4i", "")
+BUILTIN(__builtin_ia32_pminud128, "V4iV4iV4i", "")
+BUILTIN(__builtin_ia32_pminuw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_pmovsxbd128, "V4iV16c", "")
+BUILTIN(__builtin_ia32_pmovsxbq128, "V2LLiV16c", "")
+BUILTIN(__builtin_ia32_pmovsxbw128, "V8sV16c", "")
+BUILTIN(__builtin_ia32_pmovsxdq128, "V2LLiV4i", "")
+BUILTIN(__builtin_ia32_pmovsxwd128, "V4iV8s", "")
+BUILTIN(__builtin_ia32_pmovsxwq128, "V2LLiV8s", "")
+BUILTIN(__builtin_ia32_pmovzxbd128, "V4iV16c", "")
+BUILTIN(__builtin_ia32_pmovzxbq128, "V2LLiV16c", "")
+BUILTIN(__builtin_ia32_pmovzxbw128, "V8sV16c", "")
+BUILTIN(__builtin_ia32_pmovzxdq128, "V2LLiV4i", "")
+BUILTIN(__builtin_ia32_pmovzxwd128, "V4iV8s", "")
+BUILTIN(__builtin_ia32_pmovzxwq128, "V2LLiV8s", "")
+BUILTIN(__builtin_ia32_pmuldq128, "V2LLiV4iV4i", "")
+BUILTIN(__builtin_ia32_pmulld128, "V4iV4iV4i", "")
+BUILTIN(__builtin_ia32_roundps, "V4fV4fi", "")
+BUILTIN(__builtin_ia32_roundss, "V4fV4fV4fi", "")
+BUILTIN(__builtin_ia32_roundsd, "V2dV2dV2di", "")
+BUILTIN(__builtin_ia32_roundpd, "V2dV2di", "")
+BUILTIN(__builtin_ia32_dpps, "V4fV4fV4fi", "")
+BUILTIN(__builtin_ia32_dppd, "V2dV2dV2di", "")
+BUILTIN(__builtin_ia32_movntdqa, "V2LLiV2LLi*", "")
+BUILTIN(__builtin_ia32_ptestz128, "iV2LLiV2LLi", "")
+BUILTIN(__builtin_ia32_ptestc128, "iV2LLiV2LLi", "")
+BUILTIN(__builtin_ia32_ptestnzc128, "iV2LLiV2LLi", "")
+BUILTIN(__builtin_ia32_pcmpeqq, "V2LLiV2LLiV2LLi", "")
+BUILTIN(__builtin_ia32_mpsadbw128, "V16cV16cV16ci", "")
+
+// SSE 4.2
+BUILTIN(__builtin_ia32_pcmpistrm128, "V16cV16cV16cc", "")
+BUILTIN(__builtin_ia32_pcmpistri128, "iV16cV16cc", "")
+BUILTIN(__builtin_ia32_pcmpestrm128, "V16cV16ciV16cic", "")
+BUILTIN(__builtin_ia32_pcmpestri128, "iV16ciV16cic","")
+
+BUILTIN(__builtin_ia32_pcmpistria128, "iV16ciV16cic","")
+BUILTIN(__builtin_ia32_pcmpistric128, "iV16ciV16cic","")
+BUILTIN(__builtin_ia32_pcmpistrio128, "iV16ciV16cic","")
+BUILTIN(__builtin_ia32_pcmpistris128, "iV16ciV16cic","")
+BUILTIN(__builtin_ia32_pcmpistriz128, "iV16ciV16cic","")
+
+BUILTIN(__builtin_ia32_pcmpestria128, "iV16ciV16cic","")
+BUILTIN(__builtin_ia32_pcmpestric128, "iV16ciV16cic","")
+BUILTIN(__builtin_ia32_pcmpestrio128, "iV16ciV16cic","")
+BUILTIN(__builtin_ia32_pcmpestris128, "iV16ciV16cic","")
+BUILTIN(__builtin_ia32_pcmpestriz128, "iV16ciV16cic","")
+
+BUILTIN(__builtin_ia32_pcmpgtq, "V2LLiV2LLiV2LLi", "")
+
+BUILTIN(__builtin_ia32_crc32qi, "iic", "")
+BUILTIN(__builtin_ia32_crc32hi, "iis", "")
+BUILTIN(__builtin_ia32_crc32si, "iii", "")
+BUILTIN(__builtin_ia32_crc32di, "LLiLLiLLi", "")
+
+// AES
+BUILTIN(__builtin_ia32_aesenc128, "V2LLiV2LLiV2LLi", "")
+BUILTIN(__builtin_ia32_aesenclast128, "V2LLiV2LLiV2LLi", "")
+BUILTIN(__builtin_ia32_aesdec128, "V2LLiV2LLiV2LLi", "")
+BUILTIN(__builtin_ia32_aesdeclast128, "V2LLiV2LLiV2LLi", "")
+BUILTIN(__builtin_ia32_aesimc128, "V2LLiV2LLi", "")
+BUILTIN(__builtin_ia32_aeskeygenassist128, "V2LLiV2LLii", "")
+#undef BUILTIN
diff --git a/include/clang/Basic/CMakeLists.txt b/include/clang/Basic/CMakeLists.txt
new file mode 100644
index 0000000..c2a4e13
--- /dev/null
+++ b/include/clang/Basic/CMakeLists.txt
@@ -0,0 +1,20 @@
+macro(clang_diag_gen component)
+  tablegen(Diagnostic${component}Kinds.inc
+        -gen-clang-diags-defs -clang-component=${component})
+  add_custom_target(ClangDiagnostic${component}
+    DEPENDS Diagnostic${component}Kinds.inc)
+endmacro(clang_diag_gen)
+
+set(LLVM_TARGET_DEFINITIONS Diagnostic.td)
+clang_diag_gen(Analysis)
+clang_diag_gen(AST)
+clang_diag_gen(Common)
+clang_diag_gen(Driver)
+clang_diag_gen(Frontend)
+clang_diag_gen(Lex)
+clang_diag_gen(Parse)
+clang_diag_gen(Sema)
+tablegen(DiagnosticGroups.inc
+         -gen-clang-diag-groups)
+add_custom_target(ClangDiagnosticGroups
+  DEPENDS DiagnosticGroups.inc)
diff --git a/include/clang/Basic/ConvertUTF.h b/include/clang/Basic/ConvertUTF.h
new file mode 100644
index 0000000..4da2ad7
--- /dev/null
+++ b/include/clang/Basic/ConvertUTF.h
@@ -0,0 +1,159 @@
+/*===--- ConvertUTF.h - Universal Character Names conversions ---------------===
+ *
+ *                     The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ *==------------------------------------------------------------------------==*/
+/*
+ * Copyright 2001-2004 Unicode, Inc.
+ *
+ * Disclaimer
+ *
+ * This source code is provided as is by Unicode, Inc. No claims are
+ * made as to fitness for any particular purpose. No warranties of any
+ * kind are expressed or implied. The recipient agrees to determine
+ * applicability of information provided. If this file has been
+ * purchased on magnetic or optical media from Unicode, Inc., the
+ * sole remedy for any claim will be exchange of defective media
+ * within 90 days of receipt.
+ *
+ * Limitations on Rights to Redistribute This Code
+ *
+ * Unicode, Inc. hereby grants the right to freely use the information
+ * supplied in this file in the creation of products supporting the
+ * Unicode Standard, and to make copies of this file in any form
+ * for internal or external distribution as long as this notice
+ * remains attached.
+ */
+
+/* ---------------------------------------------------------------------
+
+    Conversions between UTF32, UTF-16, and UTF-8.  Header file.
+
+    Several funtions are included here, forming a complete set of
+    conversions between the three formats.  UTF-7 is not included
+    here, but is handled in a separate source file.
+
+    Each of these routines takes pointers to input buffers and output
+    buffers.  The input buffers are const.
+
+    Each routine converts the text between *sourceStart and sourceEnd,
+    putting the result into the buffer between *targetStart and
+    targetEnd. Note: the end pointers are *after* the last item: e.g.
+    *(sourceEnd - 1) is the last item.
+
+    The return result indicates whether the conversion was successful,
+    and if not, whether the problem was in the source or target buffers.
+    (Only the first encountered problem is indicated.)
+
+    After the conversion, *sourceStart and *targetStart are both
+    updated to point to the end of last text successfully converted in
+    the respective buffers.
+
+    Input parameters:
+        sourceStart - pointer to a pointer to the source buffer.
+                The contents of this are modified on return so that
+                it points at the next thing to be converted.
+        targetStart - similarly, pointer to pointer to the target buffer.
+        sourceEnd, targetEnd - respectively pointers to the ends of the
+                two buffers, for overflow checking only.
+
+    These conversion functions take a ConversionFlags argument. When this
+    flag is set to strict, both irregular sequences and isolated surrogates
+    will cause an error.  When the flag is set to lenient, both irregular
+    sequences and isolated surrogates are converted.
+
+    Whether the flag is strict or lenient, all illegal sequences will cause
+    an error return. This includes sequences such as: <F4 90 80 80>, <C0 80>,
+    or <A0> in UTF-8, and values above 0x10FFFF in UTF-32. Conformant code
+    must check for illegal sequences.
+
+    When the flag is set to lenient, characters over 0x10FFFF are converted
+    to the replacement character; otherwise (when the flag is set to strict)
+    they constitute an error.
+
+    Output parameters:
+        The value "sourceIllegal" is returned from some routines if the input
+        sequence is malformed.  When "sourceIllegal" is returned, the source
+        value will point to the illegal value that caused the problem. E.g.,
+        in UTF-8 when a sequence is malformed, it points to the start of the
+        malformed sequence.
+
+    Author: Mark E. Davis, 1994.
+    Rev History: Rick McGowan, fixes & updates May 2001.
+         Fixes & updates, Sept 2001.
+
+------------------------------------------------------------------------ */
+
+/* ---------------------------------------------------------------------
+    The following 4 definitions are compiler-specific.
+    The C standard does not guarantee that wchar_t has at least
+    16 bits, so wchar_t is no less portable than unsigned short!
+    All should be unsigned values to avoid sign extension during
+    bit mask & shift operations.
+------------------------------------------------------------------------ */
+
+typedef unsigned long   UTF32;  /* at least 32 bits */
+typedef unsigned short  UTF16;  /* at least 16 bits */
+typedef unsigned char   UTF8;   /* typically 8 bits */
+typedef unsigned char   Boolean; /* 0 or 1 */
+
+/* Some fundamental constants */
+#define UNI_REPLACEMENT_CHAR (UTF32)0x0000FFFD
+#define UNI_MAX_BMP (UTF32)0x0000FFFF
+#define UNI_MAX_UTF16 (UTF32)0x0010FFFF
+#define UNI_MAX_UTF32 (UTF32)0x7FFFFFFF
+#define UNI_MAX_LEGAL_UTF32 (UTF32)0x0010FFFF
+
+typedef enum {
+  conversionOK,           /* conversion successful */
+  sourceExhausted,        /* partial character in source, but hit end */
+  targetExhausted,        /* insuff. room in target for conversion */
+  sourceIllegal           /* source sequence is illegal/malformed */
+} ConversionResult;
+
+typedef enum {
+  strictConversion = 0,
+  lenientConversion
+} ConversionFlags;
+
+/* This is for C++ and does no harm in C */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ConversionResult ConvertUTF8toUTF16 (
+  const UTF8** sourceStart, const UTF8* sourceEnd,
+  UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags);
+
+#ifdef CLANG_NEEDS_THESE_ONE_DAY
+ConversionResult ConvertUTF16toUTF8 (
+  const UTF16** sourceStart, const UTF16* sourceEnd,
+  UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags);
+
+ConversionResult ConvertUTF8toUTF32 (
+  const UTF8** sourceStart, const UTF8* sourceEnd,
+  UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags);
+
+ConversionResult ConvertUTF32toUTF8 (
+  const UTF32** sourceStart, const UTF32* sourceEnd,
+  UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags);
+
+ConversionResult ConvertUTF16toUTF32 (
+  const UTF16** sourceStart, const UTF16* sourceEnd,
+  UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags);
+
+ConversionResult ConvertUTF32toUTF16 (
+  const UTF32** sourceStart, const UTF32* sourceEnd,
+  UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags);
+#endif
+
+Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd);
+
+#ifdef __cplusplus
+}
+#endif
+
+/* --------------------------------------------------------------------- */
diff --git a/include/clang/Basic/Diagnostic.h b/include/clang/Basic/Diagnostic.h
new file mode 100644
index 0000000..bf94af6
--- /dev/null
+++ b/include/clang/Basic/Diagnostic.h
@@ -0,0 +1,960 @@
+//===--- Diagnostic.h - C Language Family Diagnostic Handling ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the Diagnostic-related interfaces.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_DIAGNOSTIC_H
+#define LLVM_CLANG_DIAGNOSTIC_H
+
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/type_traits.h"
+#include <string>
+#include <vector>
+#include <cassert>
+
+namespace llvm {
+  template <typename T> class SmallVectorImpl;
+  class raw_ostream;
+}
+
+namespace clang {
+  class DeclContext;
+  class DiagnosticBuilder;
+  class DiagnosticClient;
+  class FileManager;
+  class IdentifierInfo;
+  class LangOptions;
+  class PartialDiagnostic;
+  class Preprocessor;
+  class SourceManager;
+  class SourceRange;
+
+  // Import the diagnostic enums themselves.
+  namespace diag {
+    // Start position for diagnostics.
+    enum {
+      DIAG_START_DRIVER   =                        300,
+      DIAG_START_FRONTEND = DIAG_START_DRIVER   +  100,
+      DIAG_START_LEX      = DIAG_START_FRONTEND +  100,
+      DIAG_START_PARSE    = DIAG_START_LEX      +  300,
+      DIAG_START_AST      = DIAG_START_PARSE    +  300,
+      DIAG_START_SEMA     = DIAG_START_AST      +  100,
+      DIAG_START_ANALYSIS = DIAG_START_SEMA     + 1500,
+      DIAG_UPPER_LIMIT    = DIAG_START_ANALYSIS +  100
+    };
+
+    class CustomDiagInfo;
+
+    /// diag::kind - All of the diagnostics that can be emitted by the frontend.
+    typedef unsigned kind;
+
+    // Get typedefs for common diagnostics.
+    enum {
+#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE) ENUM,
+#include "clang/Basic/DiagnosticCommonKinds.inc"
+      NUM_BUILTIN_COMMON_DIAGNOSTICS
+#undef DIAG
+    };
+
+    /// Enum values that allow the client to map NOTEs, WARNINGs, and EXTENSIONs
+    /// to either MAP_IGNORE (nothing), MAP_WARNING (emit a warning), MAP_ERROR
+    /// (emit as an error).  It allows clients to map errors to
+    /// MAP_ERROR/MAP_DEFAULT or MAP_FATAL (stop emitting diagnostics after this
+    /// one).
+    enum Mapping {
+      // NOTE: 0 means "uncomputed".
+      MAP_IGNORE  = 1,     //< Map this diagnostic to nothing, ignore it.
+      MAP_WARNING = 2,     //< Map this diagnostic to a warning.
+      MAP_ERROR   = 3,     //< Map this diagnostic to an error.
+      MAP_FATAL   = 4,     //< Map this diagnostic to a fatal error.
+
+      /// Map this diagnostic to "warning", but make it immune to -Werror.  This
+      /// happens when you specify -Wno-error=foo.
+      MAP_WARNING_NO_WERROR = 5,
+      /// Map this diagnostic to "error", but make it immune to -Wfatal-errors.
+      /// This happens for -Wno-fatal-errors=foo.
+      MAP_ERROR_NO_WFATAL = 6
+    };
+  }
+
+/// \brief Annotates a diagnostic with some code that should be
+/// inserted, removed, or replaced to fix the problem.
+///
+/// This kind of hint should be used when we are certain that the
+/// introduction, removal, or modification of a particular (small!)
+/// amount of code will correct a compilation error. The compiler
+/// should also provide full recovery from such errors, such that
+/// suppressing the diagnostic output can still result in successful
+/// compilation.
+class FixItHint {
+public:
+  /// \brief Tokens that should be removed to correct the error.
+  SourceRange RemoveRange;
+
+  /// \brief The location at which we should insert code to correct
+  /// the error.
+  SourceLocation InsertionLoc;
+
+  /// \brief The actual code to insert at the insertion location, as a
+  /// string.
+  std::string CodeToInsert;
+
+  /// \brief Empty code modification hint, indicating that no code
+  /// modification is known.
+  FixItHint() : RemoveRange(), InsertionLoc() { }
+
+  bool isNull() const {
+    return !RemoveRange.isValid() && !InsertionLoc.isValid();
+  }
+  
+  /// \brief Create a code modification hint that inserts the given
+  /// code string at a specific location.
+  static FixItHint CreateInsertion(SourceLocation InsertionLoc,
+                                   llvm::StringRef Code) {
+    FixItHint Hint;
+    Hint.InsertionLoc = InsertionLoc;
+    Hint.CodeToInsert = Code;
+    return Hint;
+  }
+
+  /// \brief Create a code modification hint that removes the given
+  /// source range.
+  static FixItHint CreateRemoval(SourceRange RemoveRange) {
+    FixItHint Hint;
+    Hint.RemoveRange = RemoveRange;
+    return Hint;
+  }
+
+  /// \brief Create a code modification hint that replaces the given
+  /// source range with the given code string.
+  static FixItHint CreateReplacement(SourceRange RemoveRange,
+                                     llvm::StringRef Code) {
+    FixItHint Hint;
+    Hint.RemoveRange = RemoveRange;
+    Hint.InsertionLoc = RemoveRange.getBegin();
+    Hint.CodeToInsert = Code;
+    return Hint;
+  }
+};
+
+/// Diagnostic - This concrete class is used by the front-end to report
+/// problems and issues.  It massages the diagnostics (e.g. handling things like
+/// "report warnings as errors" and passes them off to the DiagnosticClient for
+/// reporting to the user.
+class Diagnostic : public llvm::RefCountedBase<Diagnostic> {
+public:
+  /// Level - The level of the diagnostic, after it has been through mapping.
+  enum Level {
+    Ignored, Note, Warning, Error, Fatal
+  };
+
+  /// ExtensionHandling - How do we handle otherwise-unmapped extension?  This
+  /// is controlled by -pedantic and -pedantic-errors.
+  enum ExtensionHandling {
+    Ext_Ignore, Ext_Warn, Ext_Error
+  };
+
+  enum ArgumentKind {
+    ak_std_string,      // std::string
+    ak_c_string,        // const char *
+    ak_sint,            // int
+    ak_uint,            // unsigned
+    ak_identifierinfo,  // IdentifierInfo
+    ak_qualtype,        // QualType
+    ak_declarationname, // DeclarationName
+    ak_nameddecl,       // NamedDecl *
+    ak_nestednamespec,  // NestedNameSpecifier *
+    ak_declcontext      // DeclContext *
+  };
+  
+  /// ArgumentValue - This typedef represents on argument value, which is a
+  /// union discriminated by ArgumentKind, with a value.
+  typedef std::pair<ArgumentKind, intptr_t> ArgumentValue;
+
+private:
+  unsigned char AllExtensionsSilenced; // Used by __extension__
+  bool IgnoreAllWarnings;        // Ignore all warnings: -w
+  bool WarningsAsErrors;         // Treat warnings like errors:
+  bool ErrorsAsFatal;            // Treat errors like fatal errors.
+  bool SuppressSystemWarnings;   // Suppress warnings in system headers.
+  bool SuppressAllDiagnostics;   // Suppress all diagnostics.
+  unsigned ErrorLimit;           // Cap of # errors emitted, 0 -> no limit.
+  unsigned TemplateBacktraceLimit; // Cap on depth of template backtrace stack,
+                                   // 0 -> no limit.
+  ExtensionHandling ExtBehavior; // Map extensions onto warnings or errors?
+  DiagnosticClient *Client;
+
+  /// DiagMappings - Mapping information for diagnostics.  Mapping info is
+  /// packed into four bits per diagnostic.  The low three bits are the mapping
+  /// (an instance of diag::Mapping), or zero if unset.  The high bit is set
+  /// when the mapping was established as a user mapping.  If the high bit is
+  /// clear, then the low bits are set to the default value, and should be
+  /// mapped with -pedantic, -Werror, etc.
+
+  typedef std::vector<unsigned char> DiagMappings;
+  mutable std::vector<DiagMappings> DiagMappingsStack;
+
+  /// ErrorOccurred / FatalErrorOccurred - This is set to true when an error or
+  /// fatal error is emitted, and is sticky.
+  bool ErrorOccurred;
+  bool FatalErrorOccurred;
+
+  /// LastDiagLevel - This is the level of the last diagnostic emitted.  This is
+  /// used to emit continuation diagnostics with the same level as the
+  /// diagnostic that they follow.
+  Diagnostic::Level LastDiagLevel;
+
+  unsigned NumWarnings;       // Number of warnings reported
+  unsigned NumErrors;         // Number of errors reported
+  unsigned NumErrorsSuppressed; // Number of errors suppressed
+  
+  /// CustomDiagInfo - Information for uniquing and looking up custom diags.
+  diag::CustomDiagInfo *CustomDiagInfo;
+
+  /// ArgToStringFn - A function pointer that converts an opaque diagnostic
+  /// argument to a strings.  This takes the modifiers and argument that was
+  /// present in the diagnostic.
+  ///
+  /// The PrevArgs array (whose length is NumPrevArgs) indicates the previous
+  /// arguments formatted for this diagnostic.  Implementations of this function
+  /// can use this information to avoid redundancy across arguments.
+  ///
+  /// This is a hack to avoid a layering violation between libbasic and libsema.
+  typedef void (*ArgToStringFnTy)(ArgumentKind Kind, intptr_t Val,
+                                  const char *Modifier, unsigned ModifierLen,
+                                  const char *Argument, unsigned ArgumentLen,
+                                  const ArgumentValue *PrevArgs,
+                                  unsigned NumPrevArgs,
+                                  llvm::SmallVectorImpl<char> &Output,
+                                  void *Cookie);
+  void *ArgToStringCookie;
+  ArgToStringFnTy ArgToStringFn;
+
+  /// \brief ID of the "delayed" diagnostic, which is a (typically
+  /// fatal) diagnostic that had to be delayed because it was found
+  /// while emitting another diagnostic.
+  unsigned DelayedDiagID;
+
+  /// \brief First string argument for the delayed diagnostic.
+  std::string DelayedDiagArg1;
+
+  /// \brief Second string argument for the delayed diagnostic.
+  std::string DelayedDiagArg2;
+
+public:
+  explicit Diagnostic(DiagnosticClient *client = 0);
+  ~Diagnostic();
+
+  //===--------------------------------------------------------------------===//
+  //  Diagnostic characterization methods, used by a client to customize how
+  //
+
+  DiagnosticClient *getClient() { return Client; }
+  const DiagnosticClient *getClient() const { return Client; }
+
+  /// pushMappings - Copies the current DiagMappings and pushes the new copy
+  /// onto the top of the stack.
+  void pushMappings();
+
+  /// popMappings - Pops the current DiagMappings off the top of the stack
+  /// causing the new top of the stack to be the active mappings. Returns
+  /// true if the pop happens, false if there is only one DiagMapping on the
+  /// stack.
+  bool popMappings();
+
+  void setClient(DiagnosticClient* client) { Client = client; }
+
+  /// setErrorLimit - Specify a limit for the number of errors we should
+  /// emit before giving up.  Zero disables the limit.
+  void setErrorLimit(unsigned Limit) { ErrorLimit = Limit; }
+  
+  /// \brief Specify the maximum number of template instantiation
+  /// notes to emit along with a given diagnostic.
+  void setTemplateBacktraceLimit(unsigned Limit) {
+    TemplateBacktraceLimit = Limit;
+  }
+
+  /// \brief Retrieve the maximum number of template instantiation
+  /// nodes to emit along with a given diagnostic.
+  unsigned getTemplateBacktraceLimit() const {
+    return TemplateBacktraceLimit;
+  }
+
+  /// setIgnoreAllWarnings - When set to true, any unmapped warnings are
+  /// ignored.  If this and WarningsAsErrors are both set, then this one wins.
+  void setIgnoreAllWarnings(bool Val) { IgnoreAllWarnings = Val; }
+  bool getIgnoreAllWarnings() const { return IgnoreAllWarnings; }
+
+  /// setWarningsAsErrors - When set to true, any warnings reported are issued
+  /// as errors.
+  void setWarningsAsErrors(bool Val) { WarningsAsErrors = Val; }
+  bool getWarningsAsErrors() const { return WarningsAsErrors; }
+
+  /// setErrorsAsFatal - When set to true, any error reported is made a
+  /// fatal error.
+  void setErrorsAsFatal(bool Val) { ErrorsAsFatal = Val; }
+  bool getErrorsAsFatal() const { return ErrorsAsFatal; }
+
+  /// setSuppressSystemWarnings - When set to true mask warnings that
+  /// come from system headers.
+  void setSuppressSystemWarnings(bool Val) { SuppressSystemWarnings = Val; }
+  bool getSuppressSystemWarnings() const { return SuppressSystemWarnings; }
+
+  /// \brief Suppress all diagnostics, to silence the front end when we 
+  /// know that we don't want any more diagnostics to be passed along to the
+  /// client
+  void setSuppressAllDiagnostics(bool Val = true) { 
+    SuppressAllDiagnostics = Val; 
+  }
+  bool getSuppressAllDiagnostics() const { return SuppressAllDiagnostics; }
+  
+  /// \brief Pretend that the last diagnostic issued was ignored. This can
+  /// be used by clients who suppress diagnostics themselves.
+  void setLastDiagnosticIgnored() {
+    LastDiagLevel = Ignored;
+  }
+  
+  /// setExtensionHandlingBehavior - This controls whether otherwise-unmapped
+  /// extension diagnostics are mapped onto ignore/warning/error.  This
+  /// corresponds to the GCC -pedantic and -pedantic-errors option.
+  void setExtensionHandlingBehavior(ExtensionHandling H) {
+    ExtBehavior = H;
+  }
+
+  /// AllExtensionsSilenced - This is a counter bumped when an __extension__
+  /// block is encountered.  When non-zero, all extension diagnostics are
+  /// entirely silenced, no matter how they are mapped.
+  void IncrementAllExtensionsSilenced() { ++AllExtensionsSilenced; }
+  void DecrementAllExtensionsSilenced() { --AllExtensionsSilenced; }
+  bool hasAllExtensionsSilenced() { return AllExtensionsSilenced != 0; }
+
+  /// setDiagnosticMapping - This allows the client to specify that certain
+  /// warnings are ignored.  Notes can never be mapped, errors can only be
+  /// mapped to fatal, and WARNINGs and EXTENSIONs can be mapped arbitrarily.
+  void setDiagnosticMapping(diag::kind Diag, diag::Mapping Map) {
+    assert(Diag < diag::DIAG_UPPER_LIMIT &&
+           "Can only map builtin diagnostics");
+    assert((isBuiltinWarningOrExtension(Diag) ||
+            (Map == diag::MAP_FATAL || Map == diag::MAP_ERROR)) &&
+           "Cannot map errors into warnings!");
+    setDiagnosticMappingInternal(Diag, Map, true);
+  }
+
+  /// setDiagnosticGroupMapping - Change an entire diagnostic group (e.g.
+  /// "unknown-pragmas" to have the specified mapping.  This returns true and
+  /// ignores the request if "Group" was unknown, false otherwise.
+  bool setDiagnosticGroupMapping(const char *Group, diag::Mapping Map);
+
+  bool hasErrorOccurred() const { return ErrorOccurred; }
+  bool hasFatalErrorOccurred() const { return FatalErrorOccurred; }
+
+  unsigned getNumErrors() const { return NumErrors; }
+  unsigned getNumErrorsSuppressed() const { return NumErrorsSuppressed; }
+  unsigned getNumWarnings() const { return NumWarnings; }
+
+  /// getCustomDiagID - Return an ID for a diagnostic with the specified message
+  /// and level.  If this is the first request for this diagnosic, it is
+  /// registered and created, otherwise the existing ID is returned.
+  unsigned getCustomDiagID(Level L, llvm::StringRef Message);
+
+
+  /// ConvertArgToString - This method converts a diagnostic argument (as an
+  /// intptr_t) into the string that represents it.
+  void ConvertArgToString(ArgumentKind Kind, intptr_t Val,
+                          const char *Modifier, unsigned ModLen,
+                          const char *Argument, unsigned ArgLen,
+                          const ArgumentValue *PrevArgs, unsigned NumPrevArgs,
+                          llvm::SmallVectorImpl<char> &Output) const {
+    ArgToStringFn(Kind, Val, Modifier, ModLen, Argument, ArgLen,
+                  PrevArgs, NumPrevArgs, Output, ArgToStringCookie);
+  }
+
+  void SetArgToStringFn(ArgToStringFnTy Fn, void *Cookie) {
+    ArgToStringFn = Fn;
+    ArgToStringCookie = Cookie;
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Diagnostic classification and reporting interfaces.
+  //
+
+  /// getDescription - Given a diagnostic ID, return a description of the
+  /// issue.
+  const char *getDescription(unsigned DiagID) const;
+
+  /// isNoteWarningOrExtension - Return true if the unmapped diagnostic
+  /// level of the specified diagnostic ID is a Warning or Extension.
+  /// This only works on builtin diagnostics, not custom ones, and is not legal to
+  /// call on NOTEs.
+  static bool isBuiltinWarningOrExtension(unsigned DiagID);
+
+  /// \brief Determine whether the given built-in diagnostic ID is a
+  /// Note.
+  static bool isBuiltinNote(unsigned DiagID);
+
+  /// isBuiltinExtensionDiag - Determine whether the given built-in diagnostic
+  /// ID is for an extension of some sort.
+  ///
+  static bool isBuiltinExtensionDiag(unsigned DiagID) {
+    bool ignored;
+    return isBuiltinExtensionDiag(DiagID, ignored);
+  }
+  
+  /// isBuiltinExtensionDiag - Determine whether the given built-in diagnostic
+  /// ID is for an extension of some sort.  This also returns EnabledByDefault,
+  /// which is set to indicate whether the diagnostic is ignored by default (in
+  /// which case -pedantic enables it) or treated as a warning/error by default.
+  ///
+  static bool isBuiltinExtensionDiag(unsigned DiagID, bool &EnabledByDefault);
+  
+
+  /// getWarningOptionForDiag - Return the lowest-level warning option that
+  /// enables the specified diagnostic.  If there is no -Wfoo flag that controls
+  /// the diagnostic, this returns null.
+  static const char *getWarningOptionForDiag(unsigned DiagID);
+
+  /// \brief Enumeration describing how the the emission of a diagnostic should
+  /// be treated when it occurs during C++ template argument deduction.
+  enum SFINAEResponse {
+    /// \brief The diagnostic should not be reported, but it should cause
+    /// template argument deduction to fail.
+    ///
+    /// The vast majority of errors that occur during template argument 
+    /// deduction fall into this category.
+    SFINAE_SubstitutionFailure,
+    
+    /// \brief The diagnostic should be suppressed entirely.
+    ///
+    /// Warnings generally fall into this category.
+    SFINAE_Suppress,
+    
+    /// \brief The diagnostic should be reported.
+    ///
+    /// The diagnostic should be reported. Various fatal errors (e.g., 
+    /// template instantiation depth exceeded) fall into this category.
+    SFINAE_Report
+  };
+  
+  /// \brief Determines whether the given built-in diagnostic ID is
+  /// for an error that is suppressed if it occurs during C++ template
+  /// argument deduction.
+  ///
+  /// When an error is suppressed due to SFINAE, the template argument
+  /// deduction fails but no diagnostic is emitted. Certain classes of
+  /// errors, such as those errors that involve C++ access control,
+  /// are not SFINAE errors.
+  static SFINAEResponse getDiagnosticSFINAEResponse(unsigned DiagID);
+
+  /// getDiagnosticLevel - Based on the way the client configured the Diagnostic
+  /// object, classify the specified diagnostic ID into a Level, consumable by
+  /// the DiagnosticClient.
+  Level getDiagnosticLevel(unsigned DiagID) const;
+
+  /// Report - Issue the message to the client.  @c DiagID is a member of the
+  /// @c diag::kind enum.  This actually returns aninstance of DiagnosticBuilder
+  /// which emits the diagnostics (through @c ProcessDiag) when it is destroyed.
+  /// @c Pos represents the source location associated with the diagnostic,
+  /// which can be an invalid location if no position information is available.
+  inline DiagnosticBuilder Report(FullSourceLoc Pos, unsigned DiagID);
+  inline DiagnosticBuilder Report(unsigned DiagID);
+
+  /// \brief Determine whethere there is already a diagnostic in flight.
+  bool isDiagnosticInFlight() const { return CurDiagID != ~0U; }
+
+  /// \brief Set the "delayed" diagnostic that will be emitted once
+  /// the current diagnostic completes.
+  ///
+  ///  If a diagnostic is already in-flight but the front end must
+  ///  report a problem (e.g., with an inconsistent file system
+  ///  state), this routine sets a "delayed" diagnostic that will be
+  ///  emitted after the current diagnostic completes. This should
+  ///  only be used for fatal errors detected at inconvenient
+  ///  times. If emitting a delayed diagnostic causes a second delayed
+  ///  diagnostic to be introduced, that second delayed diagnostic
+  ///  will be ignored.
+  ///
+  /// \param DiagID The ID of the diagnostic being delayed.
+  ///
+  /// \param Arg1 A string argument that will be provided to the
+  /// diagnostic. A copy of this string will be stored in the
+  /// Diagnostic object itself.
+  ///
+  /// \param Arg2 A string argument that will be provided to the
+  /// diagnostic. A copy of this string will be stored in the
+  /// Diagnostic object itself.
+  void SetDelayedDiagnostic(unsigned DiagID, llvm::StringRef Arg1 = "",
+                            llvm::StringRef Arg2 = "");
+  
+  /// \brief Clear out the current diagnostic.
+  void Clear() { CurDiagID = ~0U; }
+
+private:
+  /// \brief Report the delayed diagnostic.
+  void ReportDelayed();
+
+
+  /// getDiagnosticMappingInfo - Return the mapping info currently set for the
+  /// specified builtin diagnostic.  This returns the high bit encoding, or zero
+  /// if the field is completely uninitialized.
+  diag::Mapping getDiagnosticMappingInfo(diag::kind Diag) const {
+    const DiagMappings &currentMappings = DiagMappingsStack.back();
+    return (diag::Mapping)((currentMappings[Diag/2] >> (Diag & 1)*4) & 15);
+  }
+
+  void setDiagnosticMappingInternal(unsigned DiagId, unsigned Map,
+                                    bool isUser) const {
+    if (isUser) Map |= 8;  // Set the high bit for user mappings.
+    unsigned char &Slot = DiagMappingsStack.back()[DiagId/2];
+    unsigned Shift = (DiagId & 1)*4;
+    Slot &= ~(15 << Shift);
+    Slot |= Map << Shift;
+  }
+
+  /// getDiagnosticLevel - This is an internal implementation helper used when
+  /// DiagClass is already known.
+  Level getDiagnosticLevel(unsigned DiagID, unsigned DiagClass) const;
+
+  // This is private state used by DiagnosticBuilder.  We put it here instead of
+  // in DiagnosticBuilder in order to keep DiagnosticBuilder a small lightweight
+  // object.  This implementation choice means that we can only have one
+  // diagnostic "in flight" at a time, but this seems to be a reasonable
+  // tradeoff to keep these objects small.  Assertions verify that only one
+  // diagnostic is in flight at a time.
+  friend class DiagnosticBuilder;
+  friend class DiagnosticInfo;
+
+  /// CurDiagLoc - This is the location of the current diagnostic that is in
+  /// flight.
+  FullSourceLoc CurDiagLoc;
+
+  /// CurDiagID - This is the ID of the current diagnostic that is in flight.
+  /// This is set to ~0U when there is no diagnostic in flight.
+  unsigned CurDiagID;
+
+  enum {
+    /// MaxArguments - The maximum number of arguments we can hold. We currently
+    /// only support up to 10 arguments (%0-%9).  A single diagnostic with more
+    /// than that almost certainly has to be simplified anyway.
+    MaxArguments = 10
+  };
+
+  /// NumDiagArgs - This contains the number of entries in Arguments.
+  signed char NumDiagArgs;
+  /// NumRanges - This is the number of ranges in the DiagRanges array.
+  unsigned char NumDiagRanges;
+  /// \brief The number of code modifications hints in the
+  /// FixItHints array.
+  unsigned char NumFixItHints;
+
+  /// DiagArgumentsKind - This is an array of ArgumentKind::ArgumentKind enum
+  /// values, with one for each argument.  This specifies whether the argument
+  /// is in DiagArgumentsStr or in DiagArguments.
+  unsigned char DiagArgumentsKind[MaxArguments];
+
+  /// DiagArgumentsStr - This holds the values of each string argument for the
+  /// current diagnostic.  This value is only used when the corresponding
+  /// ArgumentKind is ak_std_string.
+  std::string DiagArgumentsStr[MaxArguments];
+
+  /// DiagArgumentsVal - The values for the various substitution positions. This
+  /// is used when the argument is not an std::string.  The specific value is
+  /// mangled into an intptr_t and the intepretation depends on exactly what
+  /// sort of argument kind it is.
+  intptr_t DiagArgumentsVal[MaxArguments];
+
+  /// DiagRanges - The list of ranges added to this diagnostic.  It currently
+  /// only support 10 ranges, could easily be extended if needed.
+  SourceRange DiagRanges[10];
+
+  enum { MaxFixItHints = 3 };
+
+  /// FixItHints - If valid, provides a hint with some code
+  /// to insert, remove, or modify at a particular position.
+  FixItHint FixItHints[MaxFixItHints];
+
+  /// ProcessDiag - This is the method used to report a diagnostic that is
+  /// finally fully formed.
+  ///
+  /// \returns true if the diagnostic was emitted, false if it was
+  /// suppressed.
+  bool ProcessDiag();
+};
+
+//===----------------------------------------------------------------------===//
+// DiagnosticBuilder
+//===----------------------------------------------------------------------===//
+
+/// DiagnosticBuilder - This is a little helper class used to produce
+/// diagnostics.  This is constructed by the Diagnostic::Report method, and
+/// allows insertion of extra information (arguments and source ranges) into the
+/// currently "in flight" diagnostic.  When the temporary for the builder is
+/// destroyed, the diagnostic is issued.
+///
+/// Note that many of these will be created as temporary objects (many call
+/// sites), so we want them to be small and we never want their address taken.
+/// This ensures that compilers with somewhat reasonable optimizers will promote
+/// the common fields to registers, eliminating increments of the NumArgs field,
+/// for example.
+class DiagnosticBuilder {
+  mutable Diagnostic *DiagObj;
+  mutable unsigned NumArgs, NumRanges, NumFixItHints;
+
+  void operator=(const DiagnosticBuilder&); // DO NOT IMPLEMENT
+  friend class Diagnostic;
+  explicit DiagnosticBuilder(Diagnostic *diagObj)
+    : DiagObj(diagObj), NumArgs(0), NumRanges(0), NumFixItHints(0) {}
+
+public:
+  /// Copy constructor.  When copied, this "takes" the diagnostic info from the
+  /// input and neuters it.
+  DiagnosticBuilder(const DiagnosticBuilder &D) {
+    DiagObj = D.DiagObj;
+    D.DiagObj = 0;
+    NumArgs = D.NumArgs;
+    NumRanges = D.NumRanges;
+    NumFixItHints = D.NumFixItHints;
+  }
+
+  /// \brief Simple enumeration value used to give a name to the
+  /// suppress-diagnostic constructor.
+  enum SuppressKind { Suppress };
+
+  /// \brief Create an empty DiagnosticBuilder object that represents
+  /// no actual diagnostic.
+  explicit DiagnosticBuilder(SuppressKind)
+    : DiagObj(0), NumArgs(0), NumRanges(0), NumFixItHints(0) { }
+
+  /// \brief Force the diagnostic builder to emit the diagnostic now.
+  ///
+  /// Once this function has been called, the DiagnosticBuilder object
+  /// should not be used again before it is destroyed.
+  ///
+  /// \returns true if a diagnostic was emitted, false if the
+  /// diagnostic was suppressed.
+  bool Emit();
+
+  /// Destructor - The dtor emits the diagnostic if it hasn't already
+  /// been emitted.
+  ~DiagnosticBuilder() { Emit(); }
+
+  /// isActive - Determine whether this diagnostic is still active.
+  bool isActive() const { return DiagObj != 0; }
+
+  /// Operator bool: conversion of DiagnosticBuilder to bool always returns
+  /// true.  This allows is to be used in boolean error contexts like:
+  /// return Diag(...);
+  operator bool() const { return true; }
+
+  void AddString(llvm::StringRef S) const {
+    assert(NumArgs < Diagnostic::MaxArguments &&
+           "Too many arguments to diagnostic!");
+    if (DiagObj) {
+      DiagObj->DiagArgumentsKind[NumArgs] = Diagnostic::ak_std_string;
+      DiagObj->DiagArgumentsStr[NumArgs++] = S;
+    }
+  }
+
+  void AddTaggedVal(intptr_t V, Diagnostic::ArgumentKind Kind) const {
+    assert(NumArgs < Diagnostic::MaxArguments &&
+           "Too many arguments to diagnostic!");
+    if (DiagObj) {
+      DiagObj->DiagArgumentsKind[NumArgs] = Kind;
+      DiagObj->DiagArgumentsVal[NumArgs++] = V;
+    }
+  }
+
+  void AddSourceRange(const SourceRange &R) const {
+    assert(NumRanges <
+           sizeof(DiagObj->DiagRanges)/sizeof(DiagObj->DiagRanges[0]) &&
+           "Too many arguments to diagnostic!");
+    if (DiagObj)
+      DiagObj->DiagRanges[NumRanges++] = R;
+  }
+
+  void AddFixItHint(const FixItHint &Hint) const {
+    if (Hint.isNull())
+      return;
+    
+    assert(NumFixItHints < Diagnostic::MaxFixItHints &&
+           "Too many fix-it hints!");
+    if (DiagObj)
+      DiagObj->FixItHints[NumFixItHints++] = Hint;
+  }
+};
+
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+                                           llvm::StringRef S) {
+  DB.AddString(S);
+  return DB;
+}
+
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+                                           const char *Str) {
+  DB.AddTaggedVal(reinterpret_cast<intptr_t>(Str),
+                  Diagnostic::ak_c_string);
+  return DB;
+}
+
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, int I) {
+  DB.AddTaggedVal(I, Diagnostic::ak_sint);
+  return DB;
+}
+
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,bool I) {
+  DB.AddTaggedVal(I, Diagnostic::ak_sint);
+  return DB;
+}
+
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+                                           unsigned I) {
+  DB.AddTaggedVal(I, Diagnostic::ak_uint);
+  return DB;
+}
+
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+                                           const IdentifierInfo *II) {
+  DB.AddTaggedVal(reinterpret_cast<intptr_t>(II),
+                  Diagnostic::ak_identifierinfo);
+  return DB;
+}
+
+// Adds a DeclContext to the diagnostic. The enable_if template magic is here
+// so that we only match those arguments that are (statically) DeclContexts;
+// other arguments that derive from DeclContext (e.g., RecordDecls) will not
+// match.
+template<typename T>
+inline
+typename llvm::enable_if<llvm::is_same<T, DeclContext>, 
+                         const DiagnosticBuilder &>::type
+operator<<(const DiagnosticBuilder &DB, T *DC) {
+  DB.AddTaggedVal(reinterpret_cast<intptr_t>(DC),
+                  Diagnostic::ak_declcontext);
+  return DB;
+}
+  
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+                                           const SourceRange &R) {
+  DB.AddSourceRange(R);
+  return DB;
+}
+
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+                                           const FixItHint &Hint) {
+  DB.AddFixItHint(Hint);
+  return DB;
+}
+
+/// Report - Issue the message to the client.  DiagID is a member of the
+/// diag::kind enum.  This actually returns a new instance of DiagnosticBuilder
+/// which emits the diagnostics (through ProcessDiag) when it is destroyed.
+inline DiagnosticBuilder Diagnostic::Report(FullSourceLoc Loc, unsigned DiagID){
+  assert(CurDiagID == ~0U && "Multiple diagnostics in flight at once!");
+  CurDiagLoc = Loc;
+  CurDiagID = DiagID;
+  return DiagnosticBuilder(this);
+}
+inline DiagnosticBuilder Diagnostic::Report(unsigned DiagID) {
+  return Report(FullSourceLoc(), DiagID);
+}
+
+//===----------------------------------------------------------------------===//
+// DiagnosticInfo
+//===----------------------------------------------------------------------===//
+
+/// DiagnosticInfo - This is a little helper class (which is basically a smart
+/// pointer that forward info from Diagnostic) that allows clients to enquire
+/// about the currently in-flight diagnostic.
+class DiagnosticInfo {
+  const Diagnostic *DiagObj;
+public:
+  explicit DiagnosticInfo(const Diagnostic *DO) : DiagObj(DO) {}
+
+  const Diagnostic *getDiags() const { return DiagObj; }
+  unsigned getID() const { return DiagObj->CurDiagID; }
+  const FullSourceLoc &getLocation() const { return DiagObj->CurDiagLoc; }
+
+  unsigned getNumArgs() const { return DiagObj->NumDiagArgs; }
+
+  /// getArgKind - Return the kind of the specified index.  Based on the kind
+  /// of argument, the accessors below can be used to get the value.
+  Diagnostic::ArgumentKind getArgKind(unsigned Idx) const {
+    assert(Idx < getNumArgs() && "Argument index out of range!");
+    return (Diagnostic::ArgumentKind)DiagObj->DiagArgumentsKind[Idx];
+  }
+
+  /// getArgStdStr - Return the provided argument string specified by Idx.
+  const std::string &getArgStdStr(unsigned Idx) const {
+    assert(getArgKind(Idx) == Diagnostic::ak_std_string &&
+           "invalid argument accessor!");
+    return DiagObj->DiagArgumentsStr[Idx];
+  }
+
+  /// getArgCStr - Return the specified C string argument.
+  const char *getArgCStr(unsigned Idx) const {
+    assert(getArgKind(Idx) == Diagnostic::ak_c_string &&
+           "invalid argument accessor!");
+    return reinterpret_cast<const char*>(DiagObj->DiagArgumentsVal[Idx]);
+  }
+
+  /// getArgSInt - Return the specified signed integer argument.
+  int getArgSInt(unsigned Idx) const {
+    assert(getArgKind(Idx) == Diagnostic::ak_sint &&
+           "invalid argument accessor!");
+    return (int)DiagObj->DiagArgumentsVal[Idx];
+  }
+
+  /// getArgUInt - Return the specified unsigned integer argument.
+  unsigned getArgUInt(unsigned Idx) const {
+    assert(getArgKind(Idx) == Diagnostic::ak_uint &&
+           "invalid argument accessor!");
+    return (unsigned)DiagObj->DiagArgumentsVal[Idx];
+  }
+
+  /// getArgIdentifier - Return the specified IdentifierInfo argument.
+  const IdentifierInfo *getArgIdentifier(unsigned Idx) const {
+    assert(getArgKind(Idx) == Diagnostic::ak_identifierinfo &&
+           "invalid argument accessor!");
+    return reinterpret_cast<IdentifierInfo*>(DiagObj->DiagArgumentsVal[Idx]);
+  }
+
+  /// getRawArg - Return the specified non-string argument in an opaque form.
+  intptr_t getRawArg(unsigned Idx) const {
+    assert(getArgKind(Idx) != Diagnostic::ak_std_string &&
+           "invalid argument accessor!");
+    return DiagObj->DiagArgumentsVal[Idx];
+  }
+
+
+  /// getNumRanges - Return the number of source ranges associated with this
+  /// diagnostic.
+  unsigned getNumRanges() const {
+    return DiagObj->NumDiagRanges;
+  }
+
+  SourceRange getRange(unsigned Idx) const {
+    assert(Idx < DiagObj->NumDiagRanges && "Invalid diagnostic range index!");
+    return DiagObj->DiagRanges[Idx];
+  }
+
+  unsigned getNumFixItHints() const {
+    return DiagObj->NumFixItHints;
+  }
+
+  const FixItHint &getFixItHint(unsigned Idx) const {
+    return DiagObj->FixItHints[Idx];
+  }
+
+  const FixItHint *getFixItHints() const {
+    return DiagObj->NumFixItHints?
+             &DiagObj->FixItHints[0] : 0;
+  }
+
+  /// FormatDiagnostic - Format this diagnostic into a string, substituting the
+  /// formal arguments into the %0 slots.  The result is appended onto the Str
+  /// array.
+  void FormatDiagnostic(llvm::SmallVectorImpl<char> &OutStr) const;
+
+  /// FormatDiagnostic - Format the given format-string into the
+  /// output buffer using the arguments stored in this diagnostic.
+  void FormatDiagnostic(const char *DiagStr, const char *DiagEnd,
+                        llvm::SmallVectorImpl<char> &OutStr) const;
+};
+
+/**
+ * \brief Represents a diagnostic in a form that can be serialized and
+ * deserialized.
+ */
+class StoredDiagnostic {
+  Diagnostic::Level Level;
+  FullSourceLoc Loc;
+  std::string Message;
+  std::vector<SourceRange> Ranges;
+  std::vector<FixItHint> FixIts;
+
+public:
+  StoredDiagnostic();
+  StoredDiagnostic(Diagnostic::Level Level, const DiagnosticInfo &Info);
+  StoredDiagnostic(Diagnostic::Level Level, llvm::StringRef Message);
+  ~StoredDiagnostic();
+
+  /// \brief Evaluates true when this object stores a diagnostic.
+  operator bool() const { return Message.size() > 0; }
+
+  Diagnostic::Level getLevel() const { return Level; }
+  const FullSourceLoc &getLocation() const { return Loc; }
+  llvm::StringRef getMessage() const { return Message; }
+  
+  typedef std::vector<SourceRange>::const_iterator range_iterator;
+  range_iterator range_begin() const { return Ranges.begin(); }
+  range_iterator range_end() const { return Ranges.end(); }
+  unsigned range_size() const { return Ranges.size(); }
+
+  typedef std::vector<FixItHint>::const_iterator fixit_iterator;
+  fixit_iterator fixit_begin() const { return FixIts.begin(); }
+  fixit_iterator fixit_end() const { return FixIts.end(); }
+  unsigned fixit_size() const { return FixIts.size(); }
+
+  /// Serialize - Serialize the given diagnostic (with its diagnostic
+  /// level) to the given stream. Serialization is a lossy operation,
+  /// since the specific diagnostic ID and any macro-instantiation
+  /// information is lost.
+  void Serialize(llvm::raw_ostream &OS) const;
+
+  /// Deserialize - Deserialize the first diagnostic within the memory
+  /// [Memory, MemoryEnd), producing a new diagnostic builder describing the
+  /// deserialized diagnostic. If the memory does not contain a
+  /// diagnostic, returns a diagnostic builder with no diagnostic ID.
+  static StoredDiagnostic Deserialize(FileManager &FM, SourceManager &SM, 
+                                   const char *&Memory, const char *MemoryEnd);
+};
+
+/// DiagnosticClient - This is an abstract interface implemented by clients of
+/// the front-end, which formats and prints fully processed diagnostics.
+class DiagnosticClient {
+public:
+  virtual ~DiagnosticClient();
+
+  /// BeginSourceFile - Callback to inform the diagnostic client that processing
+  /// of a source file is beginning.
+  ///
+  /// Note that diagnostics may be emitted outside the processing of a source
+  /// file, for example during the parsing of command line options. However,
+  /// diagnostics with source range information are required to only be emitted
+  /// in between BeginSourceFile() and EndSourceFile().
+  ///
+  /// \arg LO - The language options for the source file being processed.
+  /// \arg PP - The preprocessor object being used for the source; this optional
+  /// and may not be present, for example when processing AST source files.
+  virtual void BeginSourceFile(const LangOptions &LangOpts,
+                               const Preprocessor *PP = 0) {}
+
+  /// EndSourceFile - Callback to inform the diagnostic client that processing
+  /// of a source file has ended. The diagnostic client should assume that any
+  /// objects made available via \see BeginSourceFile() are inaccessible.
+  virtual void EndSourceFile() {}
+
+  /// IncludeInDiagnosticCounts - This method (whose default implementation
+  /// returns true) indicates whether the diagnostics handled by this
+  /// DiagnosticClient should be included in the number of diagnostics reported
+  /// by Diagnostic.
+  virtual bool IncludeInDiagnosticCounts() const;
+
+  /// HandleDiagnostic - Handle this diagnostic, reporting it to the user or
+  /// capturing it to a log as needed.
+  virtual void HandleDiagnostic(Diagnostic::Level DiagLevel,
+                                const DiagnosticInfo &Info) = 0;
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Basic/Diagnostic.td b/include/clang/Basic/Diagnostic.td
new file mode 100644
index 0000000..6aa3b43
--- /dev/null
+++ b/include/clang/Basic/Diagnostic.td
@@ -0,0 +1,76 @@
+//===--- Diagnostic.td - C Language Family Diagnostic Handling ------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the TableGen core definitions for the diagnostics
+//  and diagnostic control.
+//
+//===----------------------------------------------------------------------===//
+
+// Define the diagnostic mappings.
+class DiagMapping;
+def MAP_IGNORE  : DiagMapping;
+def MAP_WARNING : DiagMapping;
+def MAP_ERROR   : DiagMapping;
+def MAP_FATAL   : DiagMapping;
+
+// Define the diagnostic classes.
+class DiagClass;
+def CLASS_NOTE      : DiagClass;
+def CLASS_WARNING   : DiagClass;
+def CLASS_EXTENSION : DiagClass;
+def CLASS_ERROR     : DiagClass;
+
+// Diagnostic Groups.
+class DiagGroup<string Name, list<DiagGroup> subgroups = []> {
+  string GroupName = Name;
+  list<DiagGroup> SubGroups = subgroups;
+}
+class InGroup<DiagGroup G> { DiagGroup Group = G; }
+//class IsGroup<string Name> { DiagGroup Group = DiagGroup<Name>; }
+
+
+// This defines the diagnostic groups that have references to them.
+include "DiagnosticGroups.td"
+
+
+// All diagnostics emitted by the compiler are an indirect subclass of this.
+class Diagnostic<string text, DiagClass DC, DiagMapping defaultmapping> {
+  /// Component is specified by the file with a big let directive.
+  string      Component = ?;
+  string      Text = text;
+  DiagClass   Class = DC;
+  bit         SFINAE = 1;
+  DiagMapping DefaultMapping = defaultmapping;
+  DiagGroup   Group;
+}
+
+class Error<string str>     : Diagnostic<str, CLASS_ERROR, MAP_ERROR>;
+class Warning<string str>   : Diagnostic<str, CLASS_WARNING, MAP_WARNING>;
+class Extension<string str> : Diagnostic<str, CLASS_EXTENSION, MAP_IGNORE>;
+class ExtWarn<string str>   : Diagnostic<str, CLASS_EXTENSION, MAP_WARNING>;
+class Note<string str>      : Diagnostic<str, CLASS_NOTE, MAP_FATAL/*ignored*/>;
+
+
+class DefaultIgnore { DiagMapping DefaultMapping = MAP_IGNORE; }
+class DefaultWarn   { DiagMapping DefaultMapping = MAP_WARNING; }
+class DefaultError  { DiagMapping DefaultMapping = MAP_ERROR; }
+class DefaultFatal  { DiagMapping DefaultMapping = MAP_FATAL; }
+
+class NoSFINAE { bit SFINAE = 0; }
+
+// Definitions for Diagnostics.
+include "DiagnosticASTKinds.td"
+include "DiagnosticAnalysisKinds.td"
+include "DiagnosticCommonKinds.td"
+include "DiagnosticDriverKinds.td"
+include "DiagnosticFrontendKinds.td"
+include "DiagnosticLexKinds.td"
+include "DiagnosticParseKinds.td"
+include "DiagnosticSemaKinds.td"
+
diff --git a/include/clang/Basic/DiagnosticASTKinds.td b/include/clang/Basic/DiagnosticASTKinds.td
new file mode 100644
index 0000000..cc89c7c
--- /dev/null
+++ b/include/clang/Basic/DiagnosticASTKinds.td
@@ -0,0 +1,81 @@
+//==--- DiagnosticASTKinds.td - libast diagnostics ------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+let Component = "AST" in {
+
+//def note_comma_in_ice : Note<
+//  "C does not permit evaluated commas in an integer constant expression">;
+def note_expr_divide_by_zero : Note<"division by zero">;
+
+// inline asm related.
+def err_asm_invalid_escape : Error<
+  "invalid %% escape in inline assembly string">;
+def err_asm_unknown_symbolic_operand_name : Error<
+  "unknown symbolic operand name in inline assembly string">;
+
+def err_asm_unterminated_symbolic_operand_name : Error<
+  "unterminated symbolic operand name in inline assembly string">;
+def err_asm_empty_symbolic_operand_name : Error<
+  "empty symbolic operand name in inline assembly string">;
+def err_asm_invalid_operand_number : Error<
+  "invalid operand number in inline asm string">;
+
+// Importing ASTs
+def err_odr_variable_type_inconsistent : Error<
+  "external variable %0 declared with incompatible types in different "
+  "translation units (%1 vs. %2)">;
+def err_odr_variable_multiple_def : Error<
+  "external variable %0 defined in multiple translation units">;
+def note_odr_value_here : Note<"declared here with type %0">;
+def note_odr_defined_here : Note<"also defined here">;
+def err_odr_function_type_inconsistent : Error<
+  "external function %0 declared with incompatible types in different "
+  "translation units (%1 vs. %2)">;
+def warn_odr_tag_type_inconsistent : Warning<
+  "type %0 has incompatible definitions in different translation units">;
+def note_odr_tag_kind_here: Note<
+  "%0 is a %select{struct|union|class|enum}1 here">;
+def note_odr_field : Note<"field %0 has type %1 here">;
+def note_odr_missing_field : Note<"no corresponding field here">;
+def note_odr_bit_field : Note<"bit-field %0 with type %1 and length %2 here">;
+def note_odr_not_bit_field : Note<"field %0 is not a bit-field">;
+def note_odr_base : Note<"class has base type %0">;
+def note_odr_virtual_base : Note<
+  "%select{non-virtual|virtual}0 derivation here">;
+def note_odr_missing_base : Note<"no corresponding base class here">;
+def note_odr_number_of_bases : Note<
+  "class has %0 base %plural{1:class|:classes}0">;
+def note_odr_enumerator : Note<"enumerator %0 with value %1 here">;
+def note_odr_missing_enumerator : Note<"no corresponding enumerator here">;
+def err_odr_ivar_type_inconsistent : Error<
+  "instance variable %0 declared with incompatible types in different "
+  "translation units (%1 vs. %2)">;
+def err_odr_objc_superclass_inconsistent : Error<
+  "class %0 has incompatible superclasses">;
+def note_odr_objc_superclass : Note<"inherits from superclass %0 here">;
+def note_odr_objc_missing_superclass : Note<"no corresponding superclass here">;
+def err_odr_objc_method_result_type_inconsistent : Error<
+  "%select{class|instance}0 method %1 has incompatible result types in "
+  "different translation units (%2 vs. %3)">;
+def err_odr_objc_method_num_params_inconsistent : Error<
+  "%select{class|instance}0 method %1 has a different number of parameters in "
+  "different translation units (%2 vs. %3)">;
+def err_odr_objc_method_param_type_inconsistent : Error<
+  "%select{class|instance}0 method %1 has a parameter with a different types "
+  "in different translation units (%2 vs. %3)">;
+def err_odr_objc_method_variadic_inconsistent : Error<
+  "%select{class|instance}0 method %1 is variadic in one translation unit "
+  "and not variadic in another">;
+def note_odr_objc_method_here : Note<
+  "%select{class|instance}0 method %1 also declared here">;
+def err_odr_objc_property_type_inconsistent : Error<
+  "property %0 declared with incompatible types in different "
+  "translation units (%1 vs. %2)">;
+def err_unsupported_ast_node: Error<"cannot import unsupported AST node %0">;
+}
diff --git a/include/clang/Basic/DiagnosticAnalysisKinds.td b/include/clang/Basic/DiagnosticAnalysisKinds.td
new file mode 100644
index 0000000..46dc0e6
--- /dev/null
+++ b/include/clang/Basic/DiagnosticAnalysisKinds.td
@@ -0,0 +1,15 @@
+//==--- DiagnosticAnalysisKinds.td - libanalysis diagnostics --------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+let Component = "Analysis" in {
+
+// CHECK: use of uninitialized values
+def warn_uninit_val : Warning<"use of uninitialized variable">;
+
+}
diff --git a/include/clang/Basic/DiagnosticCommonKinds.td b/include/clang/Basic/DiagnosticCommonKinds.td
new file mode 100644
index 0000000..88e7dc1
--- /dev/null
+++ b/include/clang/Basic/DiagnosticCommonKinds.td
@@ -0,0 +1,77 @@
+//==--- DiagnosticCommonKinds.td - common diagnostics ---------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Common Helpers
+//===----------------------------------------------------------------------===//
+
+let Component = "Common" in {
+
+// Basic.
+
+def fatal_too_many_errors
+  : Error<"too many errors emitted, stopping now">, DefaultFatal; 
+
+def note_previous_definition : Note<"previous definition is here">;
+def note_previous_declaration : Note<"previous declaration is here">;
+def note_previous_implicit_declaration : Note<
+  "previous implicit declaration is here">;
+def note_previous_use : Note<"previous use is here">;
+def note_duplicate_case_prev : Note<"previous case defined here">;
+def note_forward_declaration : Note<"forward declaration of %0">;
+def note_type_being_defined : Note<
+  "definition of %0 is not complete until the closing '}'">;
+/// note_matching - this is used as a continuation of a previous diagnostic,
+/// e.g. to specify the '(' when we expected a ')'.
+def note_matching : Note<"to match this '%0'">;
+
+def note_using : Note<"using">;
+def note_also_found : Note<"also found">;
+
+// Parse && Lex
+def err_expected_colon : Error<"expected ':'">;
+def err_expected_colon_after_setter_name : Error<
+  "method name referenced in property setter attribute "
+  "must end with ':'">;
+
+// Parse && Sema
+def ext_no_declarators : ExtWarn<"declaration does not declare anything">;
+def err_param_redefinition : Error<"redefinition of parameter %0">;
+def err_invalid_storage_class_in_func_decl : Error<
+  "invalid storage class specifier in function declarator">;
+def err_expected_namespace_name : Error<"expected namespace name">;
+
+// Sema && Lex
+def ext_longlong : Extension<
+  "'long long' is an extension when C99 mode is not enabled">,
+  InGroup<LongLong>;
+def warn_integer_too_large : Warning<
+  "integer constant is too large for its type">;
+def warn_integer_too_large_for_signed : Warning<
+  "integer constant is so large that it is unsigned">;
+
+// Sema && AST
+def note_invalid_subexpr_in_ice : Note<
+  "subexpression not valid in an integer constant expression">;
+
+// Targets
+
+def err_target_unknown_triple : Error<
+  "unknown target triple '%0', please use -triple or -arch">;
+def err_target_unknown_cpu : Error<"unknown target CPU '%0'">;
+def err_target_unknown_abi : Error<"unknown target ABI '%0'">;
+def err_target_invalid_feature : Error<"invalid target feature '%0'">;
+
+// Source manager
+def err_cannot_open_file : Error<"cannot open file '%0': %1">, DefaultFatal;
+def err_file_modified : Error<
+  "file '%0' modified since it was first processed">, DefaultFatal;
+def err_unsupported_bom : Error<"%0 byte order mark detected in '%1', but "
+  "encoding is not supported">, DefaultFatal;
+}
diff --git a/include/clang/Basic/DiagnosticDriverKinds.td b/include/clang/Basic/DiagnosticDriverKinds.td
new file mode 100644
index 0000000..3b7272e5
--- /dev/null
+++ b/include/clang/Basic/DiagnosticDriverKinds.td
@@ -0,0 +1,100 @@
+//==--- DiagnosticDriverKinds.td - libdriver diagnostics ------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+let Component = "Driver" in {
+
+def err_drv_no_such_file : Error<"no such file or directory: '%0'">;
+def err_drv_unsupported_opt : Error<"unsupported option '%0'">;
+def err_drv_unknown_stdin_type : Error<
+  "-E or -x required when input is from standard input">;
+def err_drv_unknown_language : Error<"language not recognized: '%0'">;
+def err_drv_invalid_arch_name : Error<
+  "invalid arch name '%0'">;
+def err_drv_invalid_opt_with_multiple_archs : Error<
+  "option '%0' cannot be used with multiple -arch options">;
+def err_drv_invalid_output_with_multiple_archs : Error<
+  "cannot use '%0' output with multiple -arch options">;
+def err_drv_no_input_files : Error<"no input files">;
+def err_drv_use_of_Z_option : Error<
+  "unsupported use of internal gcc -Z option '%0'">;
+def err_drv_output_argument_with_multiple_files : Error<
+  "cannot specify -o when generating multiple output files">;
+def err_drv_unable_to_make_temp : Error<
+  "unable to make temporary file: %0">;
+def err_drv_unable_to_remove_file : Error<
+  "unable to remove file: %0">;
+def err_drv_command_failure : Error<
+  "unable to execute command: %0">;
+def err_drv_invalid_darwin_version : Error<
+  "invalid Darwin version number: %0">;
+def err_drv_missing_argument : Error<
+  "argument to '%0' is missing (expected %1 %plural{1:value|:values}1)">;
+def err_drv_invalid_Xarch_argument : Error<
+  "invalid Xarch argument: '%0'">;
+def err_drv_argument_only_allowed_with : Error<
+  "invalid argument '%0' only allowed with '%1'">;
+def err_drv_argument_not_allowed_with : Error<
+  "invalid argument '%0' not allowed with '%1'">;
+def err_drv_invalid_version_number : Error<
+  "invalid version number in '%0'">;
+def err_drv_no_linker_llvm_support : Error<
+  "'%0': unable to pass LLVM bit-code files to linker">;
+def err_drv_no_ast_support : Error<
+  "'%0': unable to use AST files with this tool">;
+def err_drv_clang_unsupported : Error<
+  "the clang compiler does not support '%0'">;
+def err_drv_command_failed : Error<
+  "%0 command failed with exit code %1 (use -v to see invocation)">;
+def err_drv_command_signalled : Error<
+  "%0 command failed due to signal %1 (use -v to see invocation)">;
+def err_drv_invalid_mfloat_abi : Error<
+  "invalid float ABI '%0'">;
+def err_drv_I_dash_not_supported : Error<
+  "'%0' not supported, please use -iquote instead">;
+def err_drv_unknown_argument : Error<"unknown argument: '%0'">;
+def err_drv_invalid_value : Error<"invalid value '%1' in '%0'">;
+def err_drv_invalid_int_value : Error<"invalid integral value '%1' in '%0'">;
+def err_drv_invalid_remap_file : Error<
+    "invalid option '%0' not of the form <from-file>;<to-file>">;
+def err_drv_invalid_gcc_output_type : Error<
+    "invalid output type '%0' for use with gcc tool">;
+def err_drv_cc_print_options_failure : Error<
+    "unable to open CC_PRINT_OPTIONS file: %0">;
+
+def warn_drv_input_file_unused : Warning<
+  "%0: '%1' input unused when '%2' is present">;
+def warn_drv_preprocessed_input_file_unused : Warning<
+  "%0: previously preprocessed input unused when '%1' is present">;
+def warn_drv_unused_argument : Warning<
+  "argument unused during compilation: '%0'">;
+def warn_drv_pipe_ignored_with_save_temps : Warning<
+  "-pipe ignored because -save-temps specified">;
+def warn_drv_not_using_clang_cpp : Warning<
+  "not using the clang preprocessor due to user override">;
+def warn_drv_not_using_clang_cxx : Warning<
+  "not using the clang compiler for C++ inputs">;
+def warn_drv_not_using_clang_arch : Warning<
+  "not using the clang compiler for the '%0' architecture">;
+def warn_drv_clang_unsupported : Warning<
+  "the clang compiler does not support '%0'">;
+def warn_drv_assuming_mfloat_abi_is : Warning<
+  "unknown platform, assuming -mfloat-abi=%0">;
+def warn_ignoring_ftabstop_value : Warning<
+  "ignoring invalid -ftabstop value '%0', using default value %1">;
+def warn_drv_missing_resource_library : Warning<
+  "missing resource library '%0', link may fail">;
+def warn_drv_conflicting_deployment_targets : Warning<
+  "conflicting deployment targets, both MACOSX_DEPLOYMENT_TARGET '%0' and IPHONEOS_DEPLOYMENT_TARGET '%1' are present in environment">;
+def warn_drv_treating_input_as_cxx : Warning<
+  "treating '%0' input as '%1' when in C++ mode, this behavior is deprecated">,
+  InGroup<Deprecated>;
+def warn_drv_objc_gc_unsupported : Warning<
+  "Objective-C garbage collection is not supported on this platform, ignoring '%0'">;
+
+}
diff --git a/include/clang/Basic/DiagnosticFrontendKinds.td b/include/clang/Basic/DiagnosticFrontendKinds.td
new file mode 100644
index 0000000..5289a84
--- /dev/null
+++ b/include/clang/Basic/DiagnosticFrontendKinds.td
@@ -0,0 +1,252 @@
+//==--- DiagnosticFrontendKinds.td - frontend diagnostics -----------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+let Component = "Frontend" in {
+
+def err_fe_error_opening : Error<"error opening '%0': %1">;
+def err_fe_error_reading : Error<"error reading '%0'">;
+def err_fe_error_reading_stdin : Error<"error reading stdin">;
+def err_fe_error_backend : Error<"error in backend: %0">, DefaultFatal;
+def err_fe_invalid_ast_file : Error<"invalid AST file: '%0'">, DefaultFatal;
+def err_fe_invalid_ast_action : Error<"invalid action for AST input">,
+                                      DefaultFatal;
+def err_fe_inline_asm : Error<"%0">;  // Error generated by the backend.
+def note_fe_inline_asm_here : Note<"generated from here">;
+def err_fe_invalid_code_complete_file : Error<
+    "cannot locate code-completion file %0">, DefaultFatal;
+def err_fe_stdout_binary : Error<"unable to change standard output to binary">,
+  DefaultFatal;
+def err_fe_stderr_binary : Error<"unable to change standard error to binary">,
+  DefaultFatal;
+def err_fe_dependency_file_requires_MT : Error<
+    "-dependency-file requires at least one -MT or -MQ option">;
+def err_fe_incompatible_options : Error<
+    "'%0' cannot be used with '%1'">, DefaultFatal;
+def err_fe_no_fixit_and_codegen : Error<
+    "FIX-ITs cannot be applied when generating code">;
+def err_fe_unable_to_find_fixit_file : Error<
+    "FIX-IT could not find file '%0'">;
+def err_fe_invalid_plugin_name : Error<
+    "unable to find plugin '%0'">;
+def err_fe_expected_compiler_job : Error<
+    "unable to handle compilation, expected exactly one compiler job in '%0'">;
+def err_fe_expected_clang_command : Error<
+    "expected a clang compiler command">;
+def err_fe_remap_missing_to_file : Error<
+    "could not remap file '%0' to the contents of file '%1'">, DefaultFatal;
+def err_fe_remap_missing_from_file : Error<
+    "could not remap from missing file '%0'">, DefaultFatal;
+def err_fe_unable_to_load_pch : Error<
+    "unable to load PCH file">;
+def err_fe_unable_to_load_plugin : Error<
+    "unable to load plugin '%0': '%1'">;
+def err_fe_unable_to_create_target : Error<
+    "unable to create target: '%0'">;
+def err_fe_unable_to_interface_with_target : Error<
+    "unable to interface with target machine">;
+def err_fe_unable_to_read_pch_file : Error<
+    "unable to read PCH file: '%0'">;
+def err_fe_not_a_pch_file : Error<
+    "input is not a PCH file: '%0'">;
+def err_fe_pch_malformed : Error<
+    "malformed or corrupted PCH file: '%0'">, DefaultFatal;
+def err_fe_pch_malformed_block : Error<
+    "malformed block record in PCH file: '%0'">, DefaultFatal;
+def err_fe_pch_error_at_end_block : Error<
+    "error at end of module block in PCH file: '%0'">, DefaultFatal;
+def err_fe_pch_file_modified : Error<
+    "file '%0' has been modified since the precompiled header was built">,
+    DefaultFatal;
+def err_fe_unable_to_open_output : Error<
+    "unable to open output file '%0': '%1'">;
+def err_fe_unable_to_open_logfile : Error<
+    "unable to open logfile file '%0': '%1'">;
+def err_fe_pth_file_has_no_source_header : Error<
+    "PTH file '%0' does not designate an original source header file for -include-pth">;
+def warn_fe_macro_contains_embedded_newline : Warning<
+    "macro '%0' contains embedded newline, text after the newline is ignored.">;
+
+def err_verify_bogus_characters : Error<
+    "bogus characters before '{{' in expected string">;
+def err_verify_missing_start : Error<
+    "cannot find start ('{{') of expected string">;
+def err_verify_missing_end : Error<
+    "cannot find end ('}}') of expected string">;
+def err_verify_inconsistent_diags : Error<
+    "'%0' diagnostics %select{expected|seen}1 but not %select{seen|expected}1: %2">;
+
+def note_fixit_applied : Note<"FIX-IT applied suggested code changes">;
+def note_fixit_in_macro : Note<
+    "FIX-IT unable to apply suggested code changes in a macro">;
+def note_fixit_failed : Note<
+    "FIX-IT unable to apply suggested code changes">;
+def note_fixit_unfixed_error : Note<"FIX-IT detected an error it cannot fix">;
+def note_fixit_main_file_unchanged : Note<
+    "main file unchanged">;
+def warn_fixit_no_changes : Note<
+    "FIX-IT detected errors it could not fix; no output will be generated">;
+
+def err_fe_invoking : Error<"error invoking%0: %1">, DefaultFatal;
+
+// PCH reader
+def err_relocatable_without_without_isysroot : Error<
+    "must specify system root with -isysroot when building a relocatable "
+    "PCH file">;
+def warn_pch_target_triple : Error<
+    "PCH file was compiled for the target '%0' but the current translation "
+    "unit is being compiled for target '%1'">;
+def warn_pch_c99 : Error<
+    "C99 support was %select{disabled|enabled}0 in PCH file but is "
+    "currently %select{disabled|enabled}1">;
+def warn_pch_cplusplus : Error<
+    "C++ support was %select{disabled|enabled}0 in PCH file but is "
+    "currently %select{disabled|enabled}1">;
+def warn_pch_cplusplus0x : Error<
+    "C++0x support was %select{disabled|enabled}0 in PCH file but is "
+    "currently %select{disabled|enabled}1">;
+def warn_pch_objective_c : Error<
+    "Objective-C support was %select{disabled|enabled}0 in PCH file but is "
+    "currently %select{disabled|enabled}1">;
+def warn_pch_objective_c2 : Error<
+    "Objective-C 2.0 support was %select{disabled|enabled}0 in PCH file but "
+    "is currently %select{disabled|enabled}1">;
+def warn_pch_nonfragile_abi : Error<
+    "PCH file was compiled with the %select{32-bit|non-fragile}0 Objective-C "
+    "ABI but the %select{32-bit|non-fragile}1 Objective-C ABI is selected">;
+def warn_pch_nonfragile_abi2 : Error<
+    "PCH file was compiled with the %select{32-bit|enhanced non-fragile}0 "
+    "Objective-C ABI but the %select{32-bit|enhanced non-fragile}1 "
+    "Objective-C ABI is selected">;
+def warn_pch_no_constant_cfstrings : Error<
+    "Objctive-C NSstring generation support was %select{disabled|enabled}0 "
+    "in PCH file but currently %select{disabled|enabled}1">; 
+def warn_pch_extensions : Error<
+    "extensions were %select{enabled|disabled}0 in PCH file but are "
+    "currently %select{enabled|disabled}1">;
+def warn_pch_gnu_extensions : Error<
+    "GNU extensions were %select{disabled|enabled}0 in PCH file but are "
+    "currently %select{disabled|enabled}1">;
+def warn_pch_gnu_keywords : Error<
+    "GNU keywords were %select{disabled|enabled}0 in PCH file but are "
+    "currently %select{disabled|enabled}1">;
+def warn_pch_microsoft_extensions : Error<
+    "Microsoft extensions were %select{disabled|enabled}0 in PCH file but are "
+    "currently %select{disabled|enabled}1">;
+def warn_pch_heinous_extensions : Error<
+    "heinous extensions were %select{disabled|enabled}0 in PCH file but are "
+    "currently %select{disabled|enabled}1">;
+def warn_pch_lax_vector_conversions : Error<
+    "lax vector conversions were %select{disabled|enabled}0 in PCH file but "
+    "are currently %select{disabled|enabled}1">;
+def warn_pch_altivec : Error<
+    "AltiVec initializers were %select{disabled|enabled}0 in PCH file but "
+    "are currently %select{disabled|enabled}1">;
+def warn_pch_opencl : Error<
+    "OpenCL language extensions were %select{disabled|enabled}0 in PCH file "
+    "but are currently %select{disabled|enabled}1">;
+def warn_pch_elide_constructors : Error<
+    "Elidable copy constructors were %select{disabled|enabled}0 in PCH file "
+    "but are currently %select{disabled|enabled}1">;
+def warn_pch_exceptions : Error<
+    "exceptions were %select{disabled|enabled}0 in PCH file but "
+    "are currently %select{disabled|enabled}1">;
+def warn_pch_sjlj_exceptions : Error<
+    "sjlj-exceptions were %select{disabled|enabled}0 in PCH file but "
+    "are currently %select{disabled|enabled}1">;
+def warn_pch_objc_runtime : Error<
+    "PCH file was compiled with the %select{NeXT|GNU}0 runtime but the "
+    "%select{NeXT|GNU}1 runtime is selected">;
+def warn_pch_freestanding : Error<
+    "PCH file was compiled with a %select{hosted|freestanding}0  "
+    "implementation but a %select{hosted|freestanding}1 implementation "
+    "is selected">;
+def warn_pch_builtins : Error<
+    "PCH file was compiled with builtins %select{enabled|disabled}0 but "
+    "builtins are currently %select{enabled|disabled}1">;
+def warn_pch_thread_safe_statics : Error<
+    "PCH file was compiled %select{without|with}0 thread-safe statics but "
+    "thread-safe statics are currently %select{disabled|enabled}1">;
+def warn_pch_posix_threads : Error<
+    "PCH file was compiled %select{without|with}0 POSIX thread support but "
+    "POSIX threads are currently %select{disabled|enabled}1">;
+def warn_pch_stack_protector : Error<
+    "stack protector was %select{off|on|required}0 in PCH file but "
+    "is currently %select{off|on|required}1">;
+def warn_pch_blocks : Error<
+    "blocks were %select{disabled|enabled}0 in PCH file but "
+    "are currently %select{disabled|enabled}1">;
+def warn_pch_math_errno : Error<
+    "math functions %select{do not respect|respect}0 'errno' in PCH "
+    "file but they are currently set to %select{not respect|respect}1 "
+    "'errno'">;
+def warn_pch_overflow_checking : Error<
+    "signed integer overflow checking was %select{disabled|enabled}0 in PCH "
+    "file but is currently %select{disabled|enabled}1">;
+def warn_pch_optimize : Error<
+    "the macro '__OPTIMIZE__' was %select{not defined|defined}0 in "
+    "the PCH file but is currently %select{undefined|defined}1">;
+def warn_pch_optimize_size : Error<
+    "the macro '__OPTIMIZE_SIZE__' was %select{not defined|defined}0 in "
+    "the PCH file but is currently %select{undefined|defined}1">;
+def warn_pch_static : Error<
+    "the PCH file was compiled %select{dynamic|static}0 but the "
+    "current translation unit is being compiled as %select{dynamic|static}1">;
+def warn_pch_pic_level : Error<
+    "PCH file was compiled with PIC level %0, but the current translation "
+    "unit will be compiled with PIC level %1">;
+def warn_pch_gnu_inline : Error<
+    "PCH file was compiled with %select{C99|GNU|}0 inline semantics but "
+    "%select{C99|GNU}1 inline semantics are currently selected">;
+def warn_pch_no_inline : Error<
+    "the macro '__NO_INLINE__' was %select{not defined|defined}0 in "
+    "the PCH file but is currently %select{undefined|defined}1">;
+def warn_pch_gc_mode : Error<
+    "the PCH file was built with %select{no||hybrid}0 garbage collection but "
+    "the current translation unit will compiled with %select{no||hybrid}1 "
+    "garbage collection">;
+def warn_pch_version_too_old : Error<
+    "PCH file uses an older PCH format that is no longer supported">;
+def warn_pch_version_too_new : Error<
+    "PCH file uses a newer PCH format that cannot be read">;
+def warn_pch_different_branch : Error<
+    "PCH file built from a different branch (%0) than the compiler (%1)">;
+def warn_cmdline_conflicting_macro_def : Error<
+    "definition of the macro '%0' conflicts with the definition used to "
+    "build the precompiled header">;
+def note_pch_macro_defined_as : Note<
+    "definition of macro '%0' in the precompiled header">;
+def warn_cmdline_missing_macro_defs : Warning<
+    "macro definitions used to build the precompiled header are missing">;
+def note_using_macro_def_from_pch : Note<
+    "using this macro definition from precompiled header">;
+def warn_macro_name_used_in_pch : Error<
+    "definition of macro %0 conflicts with an identifier used in the "
+    "precompiled header">;
+def warn_pch_compiler_options_mismatch : Error<
+    "compiler options used when building the precompiled header differ from "
+    "the options used when using the precompiled header">;
+def warn_pch_access_control : Error<
+    "C++ access control was %select{disabled|enabled}0 in the PCH file but "
+    "is currently %select{disabled|enabled}1">;
+def warn_pch_char_signed : Error<
+    "char was %select{unsigned|signed}0 in the PCH file but "
+    "is currently %select{unsigned|signed}1">;
+def warn_pch_short_wchar : Error<
+    "-fshort-wchar was %select{disabled|enabled}0 in the PCH file but "
+    "is currently %select{disabled|enabled}1">;
+
+def err_not_a_pch_file : Error<
+    "'%0' does not appear to be a precompiled header file">, DefaultFatal;
+def warn_unknown_warning_option : Warning<
+    "unknown warning option '%0'">,
+    InGroup<DiagGroup<"unknown-warning-option"> >;
+def warn_unknown_warning_specifier : Warning<
+    "unknown %0 warning specifier: '%1'">,
+    InGroup<DiagGroup<"unknown-warning-option"> >;
+}
diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td
new file mode 100644
index 0000000..1b2abfe
--- /dev/null
+++ b/include/clang/Basic/DiagnosticGroups.td
@@ -0,0 +1,192 @@
+//==--- DiagnosticGroups.td - Diagnostic Group Definitions ----------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+def ImplicitFunctionDeclare : DiagGroup<"implicit-function-declaration">;
+def ImplicitInt : DiagGroup<"implicit-int">;
+
+// Aggregation warning settings.
+def Implicit : DiagGroup<"implicit", [
+    ImplicitFunctionDeclare,
+    ImplicitInt
+]>;
+    
+
+
+// Empty DiagGroups are recognized by clang but ignored.
+def : DiagGroup<"address">;
+def AddressOfTemporary : DiagGroup<"address-of-temporary">;
+def : DiagGroup<"aggregate-return">;
+def : DiagGroup<"attributes">;
+def : DiagGroup<"bad-function-cast">;
+def : DiagGroup<"c++-compat">;
+def : DiagGroup<"cast-align">;
+def : DiagGroup<"cast-qual">;
+def : DiagGroup<"char-align">;
+def Comment : DiagGroup<"comment">;
+def : DiagGroup<"ctor-dtor-privacy">;
+def : DiagGroup<"declaration-after-statement">;
+def GNUDesignator : DiagGroup<"gnu-designator">;
+def Deprecated : DiagGroup<"deprecated">;
+def : DiagGroup<"disabled-optimization">;
+def : DiagGroup<"discard-qual">;
+def : DiagGroup<"div-by-zero">;
+def EmptyBody : DiagGroup<"empty-body">;
+def ExtraTokens : DiagGroup<"extra-tokens">;
+
+def FormatExtraArgs : DiagGroup<"format-extra-args">;
+def FormatZeroLength : DiagGroup<"format-zero-length">;
+
+def FourByteMultiChar : DiagGroup<"four-char-constants">;
+def : DiagGroup<"idiomatic-parentheses">;
+def : DiagGroup<"import">;
+def : DiagGroup<"init-self">;
+def : DiagGroup<"inline">;
+def : DiagGroup<"int-to-pointer-cast">;
+def : DiagGroup<"invalid-pch">;
+def LiteralRange : DiagGroup<"literal-range">;
+def MissingBraces : DiagGroup<"missing-braces">;
+def : DiagGroup<"missing-declarations">;
+def : DiagGroup<"missing-format-attribute">;
+def : DiagGroup<"missing-include-dirs">;
+def : DiagGroup<"missing-noreturn">;
+def MultiChar : DiagGroup<"multichar">;
+def : DiagGroup<"nested-externs">;
+def : DiagGroup<"newline-eof">;
+def LongLong : DiagGroup<"long-long">;
+def MismatchedTags : DiagGroup<"mismatched-tags">;
+def MissingFieldInitializers : DiagGroup<"missing-field-initializers">;
+def NonNull : DiagGroup<"nonnull">;
+def : DiagGroup<"nonportable-cfstrings">;
+def : DiagGroup<"non-virtual-dtor">;
+def : DiagGroup<"old-style-definition">;
+def : DiagGroup<"overflow">;
+def : DiagGroup<"overloaded-virtual">;
+def : DiagGroup<"packed">;
+def PointerArith : DiagGroup<"pointer-arith">;
+def : DiagGroup<"pointer-to-int-cast">;
+def : DiagGroup<"redundant-decls">;
+def ReturnType : DiagGroup<"return-type">;
+def SemiBeforeMethodBody : DiagGroup<"semicolon-before-method-body">;
+def : DiagGroup<"sequence-point">;
+def Shadow : DiagGroup<"shadow">;
+def : DiagGroup<"shorten-64-to-32">;
+def SignCompare : DiagGroup<"sign-compare">;
+def : DiagGroup<"synth">;
+
+// Preprocessor warnings.
+def : DiagGroup<"builtin-macro-redefined">;
+
+// Just silence warnings about -Wstrict-aliasing for now.
+def : DiagGroup<"strict-aliasing=0">;
+def : DiagGroup<"strict-aliasing=1">;
+def : DiagGroup<"strict-aliasing=2">;
+def : DiagGroup<"strict-aliasing">;
+
+// Just silence warnings about -Wstrict-overflow for now.
+def : DiagGroup<"strict-overflow=0">;
+def : DiagGroup<"strict-overflow=1">;
+def : DiagGroup<"strict-overflow=2">;
+def : DiagGroup<"strict-overflow=3">;
+def : DiagGroup<"strict-overflow=4">;
+def : DiagGroup<"strict-overflow=5">;
+def : DiagGroup<"strict-overflow">;
+
+def InvalidOffsetof : DiagGroup<"invalid-offsetof">;
+def : DiagGroup<"strict-prototypes">;
+def : DiagGroup<"strict-selector-match">;
+def SwitchEnum     : DiagGroup<"switch-enum">;
+def Switch         : DiagGroup<"switch", [SwitchEnum]>;
+def Trigraphs : DiagGroup<"trigraphs">;
+
+def : DiagGroup<"type-limits">;
+def Uninitialized  : DiagGroup<"uninitialized">;
+def UnknownPragmas : DiagGroup<"unknown-pragmas">;
+def UnusedArgument : DiagGroup<"unused-argument">;
+def UnusedFunction : DiagGroup<"unused-function">;
+def UnusedLabel : DiagGroup<"unused-label">;
+def UnusedParameter : DiagGroup<"unused-parameter">;
+def UnusedValue    : DiagGroup<"unused-value">;
+def UnusedVariable : DiagGroup<"unused-variable">;
+def ReadOnlySetterAttrs : DiagGroup<"readonly-setter-attrs">;
+def Reorder : DiagGroup<"reorder">;
+def UndeclaredSelector : DiagGroup<"undeclared-selector">;
+def Protocol : DiagGroup<"protocol">;
+def SuperSubClassMismatch : DiagGroup<"super-class-method-mismatch">;
+def : DiagGroup<"variadic-macros">;
+def VariadicMacros : DiagGroup<"variadic-macros">;
+def VectorConversions : DiagGroup<"vector-conversions">;      // clang specific
+def VolatileRegisterVar : DiagGroup<"volatile-register-var">;
+def : DiagGroup<"write-strings">;
+def CharSubscript : DiagGroup<"char-subscripts">;
+
+// Aggregation warning settings.
+
+// -Widiomatic-parentheses contains warnings about 'idiomatic'
+// missing parentheses;  it is off by default.
+def Parentheses : DiagGroup<"parentheses", [DiagGroup<"idiomatic-parentheses">]>;
+
+// -Wconversion has its own warnings, but we split this one out for
+// legacy reasons.
+def Conversion : DiagGroup<"conversion",
+                           [DiagGroup<"shorten-64-to-32">]>;
+
+def Unused : DiagGroup<"unused",
+                       [UnusedArgument, UnusedFunction, UnusedLabel,
+                        // UnusedParameter, (matches GCC's behavior)
+                        UnusedValue, UnusedVariable]>;
+
+// Format settings.
+def Format : DiagGroup<"format", [FormatExtraArgs, FormatZeroLength, NonNull]>;
+def FormatSecurity : DiagGroup<"format-security", [Format]>;
+def FormatNonLiteral : DiagGroup<"format-nonliteral", [FormatSecurity]>;
+def FormatY2K : DiagGroup<"format-y2k", [Format]>;
+def Format2 : DiagGroup<"format=2",
+                        [FormatNonLiteral, FormatSecurity, FormatY2K]>;
+
+def Extra : DiagGroup<"extra", [
+    MissingFieldInitializers,
+    SemiBeforeMethodBody,
+    SignCompare,
+    UnusedParameter
+  ]>;
+
+def Most : DiagGroup<"most", [
+    CharSubscript,
+    Comment,
+    Format,
+    Implicit,
+    MismatchedTags,
+    MissingBraces,
+    MultiChar,
+    Reorder,
+    ReturnType,
+    Switch,
+    Trigraphs,
+    Uninitialized,
+    UnknownPragmas,
+    Unused,
+    VectorConversions,
+    VolatileRegisterVar
+ ]>;
+
+// -Wall is -Wmost -Wparentheses
+def : DiagGroup<"all", [Most, Parentheses]>;
+
+// Aliases.
+def : DiagGroup<"", [Extra]>;                   // -W = -Wextra
+def : DiagGroup<"endif-labels", [ExtraTokens]>; // -Wendif-labels=-Wendif-tokens
+def : DiagGroup<"comments", [Comment]>;         // -Wcomments = -Wcomment
+
+// A warning group for warnings that we want to have on by default in clang,
+// but which aren't on by default in GCC.
+def NonGCC : DiagGroup<"non-gcc",
+    [SignCompare, Conversion, LiteralRange]>;
+
+// A warning group for warnings about GCC extensions.
+def GNU : DiagGroup<"gnu", [GNUDesignator]>;
diff --git a/include/clang/Basic/DiagnosticLexKinds.td b/include/clang/Basic/DiagnosticLexKinds.td
new file mode 100644
index 0000000..3f765bd
--- /dev/null
+++ b/include/clang/Basic/DiagnosticLexKinds.td
@@ -0,0 +1,300 @@
+//==--- DiagnosticLexKinds.td - liblex diagnostics ------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Lexer Diagnostics
+//===----------------------------------------------------------------------===//
+
+let Component = "Lex" in {
+
+def null_in_string : Warning<"null character(s) preserved in string literal">;
+def null_in_char : Warning<"null character(s) preserved in character literal">;
+def null_in_file : Warning<"null character ignored">;
+def warn_nested_block_comment : Warning<"'/*' within block comment">,
+  InGroup<Comment>;
+def escaped_newline_block_comment_end : Warning<
+  "escaped newline between */ characters at block comment end">,
+  InGroup<Comment>;
+def backslash_newline_space : Warning<
+  "backslash and newline separated by space">;
+
+// Trigraphs.
+def trigraph_ignored : Warning<"trigraph ignored">, InGroup<Trigraphs>;
+def trigraph_ignored_block_comment : Warning<
+  "ignored trigraph would end block comment">, InGroup<Trigraphs>;
+def trigraph_ends_block_comment : Warning<"trigraph ends block comment">,
+    InGroup<Trigraphs>;
+def trigraph_converted : Warning<"trigraph converted to '%0' character">,
+    InGroup<Trigraphs>;
+
+def ext_multi_line_bcpl_comment : Extension<"multi-line // comment">,
+    InGroup<Comment>;
+def ext_bcpl_comment : Extension<
+  "// comments are not allowed in this language">,
+  InGroup<Comment>;
+def ext_no_newline_eof : Extension<"no newline at end of file">;
+def ext_backslash_newline_eof : Extension<"backslash-newline at end of file">;
+def ext_dollar_in_identifier : Extension<"'$' in identifier">;
+def charize_microsoft_ext : Extension<"@# is a microsoft extension">;
+
+def ext_token_used : Extension<"extension used">;
+
+def err_unterminated_string : Error<"missing terminating '\"' character">;
+def err_unterminated_char : Error<"missing terminating ' character">;
+def err_empty_character : Error<"empty character constant">;
+def err_unterminated_block_comment : Error<"unterminated /* comment">;
+def err_invalid_character_to_charify : Error<
+  "invalid argument to convert to character">;
+
+def err_conflict_marker : Error<"version control conflict marker in file">;
+
+def ext_multichar_character_literal : ExtWarn<
+  "multi-character character constant">, InGroup<MultiChar>;
+def ext_four_char_character_literal : Extension<
+  "multi-character character constant">, InGroup<FourByteMultiChar>;
+  
+
+// Literal
+def ext_nonstandard_escape : Extension<
+  "use of non-standard escape character '\\%0'">;
+def ext_unknown_escape : ExtWarn<"unknown escape sequence '\\%0'">;
+def err_hex_escape_no_digits : Error<"\\x used with no following hex digits">;
+def err_ucn_escape_no_digits : Error<"\\u used with no following hex digits">;
+def err_ucn_escape_invalid : Error<"invalid universal character">;
+def err_ucn_escape_incomplete : Error<"incomplete universal character name">;
+def err_ucn_escape_too_big : Error<"universal character name is too long">;
+def err_invalid_decimal_digit : Error<"invalid digit '%0' in decimal constant">;
+def err_invalid_binary_digit : Error<"invalid digit '%0' in binary constant">;
+def err_invalid_octal_digit : Error<"invalid digit '%0' in octal constant">;
+def err_invalid_suffix_integer_constant : Error<
+  "invalid suffix '%0' on integer constant">;
+def err_invalid_suffix_float_constant : Error<
+  "invalid suffix '%0' on floating constant">;
+def warn_extraneous_wide_char_constant : Warning<
+  "extraneous characters in wide character constant ignored">;
+def warn_char_constant_too_large : Warning<
+  "character constant too long for its type">;
+def err_exponent_has_no_digits : Error<"exponent has no digits">;
+def ext_imaginary_constant : Extension<"imaginary constants are an extension">;
+def err_hexconstant_requires_exponent : Error<
+  "hexadecimal floating constants require an exponent">;
+def ext_hexconstant_cplusplus : ExtWarn<
+  "hexadecimal floating constants are a C99 feature that is incompatible with "
+  "C++0x">;
+def ext_hexconstant_invalid : Extension<
+  "hexadecimal floating constants are a C99 feature">;
+def ext_binary_literal : Extension<
+  "binary integer literals are an extension">;
+def err_pascal_string_too_long : Error<"Pascal string is too long">;
+def warn_octal_escape_too_large : ExtWarn<"octal escape sequence out of range">;
+def warn_hex_escape_too_large : ExtWarn<"hex escape sequence out of range">;
+
+//===----------------------------------------------------------------------===//
+// PTH Diagnostics
+//===----------------------------------------------------------------------===//
+def err_pth_cannot_read : Error<
+    "PTH file '%0' could not be read">;
+def err_invalid_pth_file : Error<
+    "invalid or corrupt PTH file '%0'">;
+
+//===----------------------------------------------------------------------===//
+// Preprocessor Diagnostics
+//===----------------------------------------------------------------------===//
+def pp_hash_warning : Warning<"#warning%0">, InGroup<DiagGroup<"#warnings">>;
+def pp_include_next_in_primary : Warning<
+  "#include_next in primary source file">;
+def pp_include_macros_out_of_predefines : Error<
+  "the #__include_macros directive is only for internal use by -imacros">;
+def pp_include_next_absolute_path : Warning<"#include_next with absolute path">;
+def ext_c99_whitespace_required_after_macro_name : ExtWarn<
+  "ISO C99 requires whitespace after the macro name">;
+def ext_missing_whitespace_after_macro_name : ExtWarn<
+  "whitespace required after macro name">;
+def warn_missing_whitespace_after_macro_name : Warning<
+  "whitespace recommended after macro name">;
+  
+def pp_pragma_once_in_main_file : Warning<"#pragma once in main file">;
+def pp_pragma_sysheader_in_main_file : Warning<
+  "#pragma system_header ignored in main file">;
+def pp_poisoning_existing_macro : Warning<"poisoning existing macro">;
+def pp_out_of_date_dependency : Warning<
+  "current file is older than dependency %0">;
+def pp_undef_builtin_macro : Warning<"undefining builtin macro">;
+def pp_redef_builtin_macro : Warning<"redefining builtin macro">,
+  InGroup<DiagGroup<"builtin-macro-redefined">>;
+def pp_macro_not_used : Warning<"macro is not used">, DefaultIgnore,
+  InGroup<DiagGroup<"unused-macros">>;
+def warn_pp_undef_identifier : Warning<
+  "%0 is not defined, evaluates to 0">,
+  InGroup<DiagGroup<"undef">>, DefaultIgnore;
+
+def pp_invalid_string_literal : Warning<
+  "invalid string literal, ignoring final '\\'">;
+def warn_pp_expr_overflow : Warning<
+  "integer overflow in preprocessor expression">;
+def warn_pp_convert_lhs_to_positive : Warning<
+  "left side of operator converted from negative value to unsigned: %0">;
+def warn_pp_convert_rhs_to_positive : Warning<
+  "right side of operator converted from negative value to unsigned: %0">;
+
+def ext_pp_import_directive : Extension<"#import is a language extension">;
+def ext_pp_ident_directive : Extension<"#ident is a language extension">;
+def ext_pp_include_next_directive : Extension<
+  "#include_next is a language extension">;
+def ext_pp_warning_directive : Extension<"#warning is a language extension">;
+
+def ext_pp_extra_tokens_at_eol : ExtWarn<
+  "extra tokens at end of #%0 directive">, InGroup<ExtraTokens>;
+  
+def ext_pp_comma_expr : Extension<"comma operator in operand of #if">;
+def ext_pp_bad_vaargs_use : Extension<
+  "__VA_ARGS__ can only appear in the expansion of a C99 variadic macro">;
+def ext_pp_macro_redef : ExtWarn<"%0 macro redefined">;
+def ext_variadic_macro : Extension<"variadic macros were introduced in C99">,
+  InGroup<VariadicMacros>;
+def ext_named_variadic_macro : Extension<
+  "named variadic macros are a GNU extension">, InGroup<VariadicMacros>;
+def ext_embedded_directive : Extension<
+  "embedding a directive within macro arguments is not portable">;
+def ext_missing_varargs_arg : Extension<
+  "varargs argument missing, but tolerated as an extension">;
+def ext_empty_fnmacro_arg : Extension<
+  "empty macro arguments were standardized in C99">;
+
+def err_pp_invalid_directive : Error<"invalid preprocessing directive">;
+def err_pp_hash_error : Error<"#error%0">;
+def err_pp_file_not_found : Error<"'%0' file not found">, DefaultFatal;
+def err_pp_error_opening_file : Error<
+  "error opening file '%0': %1">, DefaultFatal;
+def err_pp_empty_filename : Error<"empty filename">;
+def err_pp_include_too_deep : Error<"#include nested too deeply">;
+def err_pp_expects_filename : Error<"expected \"FILENAME\" or <FILENAME>">;
+def err_pp_macro_not_identifier : Error<"macro names must be identifiers">;
+def err_pp_missing_macro_name : Error<"macro name missing">;
+def err_pp_missing_rparen_in_macro_def : Error<
+  "missing ')' in macro parameter list">;
+def err_pp_invalid_tok_in_arg_list : Error<
+  "invalid token in macro parameter list">;
+def err_pp_expected_ident_in_arg_list : Error<
+  "expected identifier in macro parameter list">;
+def err_pp_expected_comma_in_arg_list : Error<
+  "expected comma in macro parameter list">;
+def err_pp_duplicate_name_in_arg_list : Error<
+  "duplicate macro parameter name %0">;
+def err_pp_stringize_not_parameter : Error<
+  "'#' is not followed by a macro parameter">;
+def err_pp_malformed_ident : Error<"invalid #ident directive">;
+def err_pp_unterminated_conditional : Error<
+  "unterminated conditional directive">;
+def pp_err_else_after_else : Error<"#else after #else">;
+def pp_err_elif_after_else : Error<"#elif after #else">;
+def pp_err_else_without_if : Error<"#else without #if">;
+def pp_err_elif_without_if : Error<"#elif without #if">;
+def err_pp_endif_without_if : Error<"#endif without #if">;
+def err_pp_expected_value_in_expr : Error<"expected value in expression">;
+def err_pp_missing_val_before_operator : Error<"missing value before operator">;
+def err_pp_expected_rparen : Error<"expected ')' in preprocessor expression">;
+def err_pp_expected_eol : Error<
+  "expected end of line in preprocessor expression">;
+def err_pp_defined_requires_identifier : Error<
+  "operator 'defined' requires an identifier">;
+def err_pp_missing_lparen : Error<"missing '(' after '%0'">;
+def err_pp_missing_rparen : Error<"missing ')' after '%0'">;
+def err_pp_colon_without_question : Error<"':' without preceding '?'">;
+def err_pp_division_by_zero : Error<
+  "division by zero in preprocessor expression">;
+def err_pp_remainder_by_zero : Error<
+  "remainder by zero in preprocessor expression">;
+def err_pp_expr_bad_token_binop : Error<
+  "token is not a valid binary operator in a preprocessor subexpression">;
+def err_pp_expr_bad_token_start_expr : Error<
+  "invalid token at start of a preprocessor expression">;
+def err_pp_invalid_poison : Error<"can only poison identifier tokens">;
+def err_pp_used_poisoned_id : Error<"attempt to use a poisoned identifier">;
+
+def err_feature_check_malformed : Error<
+  "builtin feature check macro requires a parenthesized identifier">;
+
+def err__Pragma_malformed : Error<
+  "_Pragma takes a parenthesized string literal">;
+def err_pragma_comment_malformed : Error<
+  "pragma comment requires parenthesized identifier and optional string">;
+def warn_pragma_ignored : Warning<"unknown pragma ignored">,
+   InGroup<UnknownPragmas>, DefaultIgnore;
+def ext_stdc_pragma_ignored : ExtWarn<"unknown pragma in STDC namespace">,
+   InGroup<UnknownPragmas>;
+def ext_stdc_pragma_syntax :
+   ExtWarn<"expected 'ON' or 'OFF' or 'DEFAULT' in pragma">,
+   InGroup<UnknownPragmas>;
+def ext_stdc_pragma_syntax_eom :
+   ExtWarn<"expected end of macro in STDC pragma">,
+   InGroup<UnknownPragmas>;
+def warn_stdc_fenv_access_not_supported :
+   Warning<"pragma STDC FENV_ACCESS ON is not supported, ignoring pragma">,
+   InGroup<UnknownPragmas>;
+def warn_pragma_diagnostic_gcc_invalid :
+   ExtWarn<"pragma diagnostic expected 'error', 'warning', 'ignored', or"
+            " 'fatal'">,
+   InGroup<UnknownPragmas>;
+def warn_pragma_diagnostic_clang_invalid :
+   ExtWarn<"pragma diagnostic expected 'error', 'warning', 'ignored', 'fatal'"
+            " 'push', or 'pop'">,
+   InGroup<UnknownPragmas>;
+def warn_pragma_diagnostic_clang_cannot_ppp :
+   ExtWarn<"pragma diagnostic pop could not pop, no matching push">,
+   InGroup<UnknownPragmas>;
+def warn_pragma_diagnostic_invalid_option :
+   ExtWarn<"pragma diagnostic expected option name (e.g. \"-Wundef\")">,
+   InGroup<UnknownPragmas>;
+def warn_pragma_diagnostic_invalid_token :
+   ExtWarn<"unexpected token in pragma diagnostic">,
+   InGroup<UnknownPragmas>;
+def warn_pragma_diagnostic_unknown_warning :
+   ExtWarn<"unknown warning group '%0', ignored">,
+   InGroup<UnknownPragmas>;
+
+def err_pragma_comment_unknown_kind : Error<"unknown kind of pragma comment">;
+def err_defined_macro_name : Error<"'defined' cannot be used as a macro name">;
+def err_paste_at_start : Error<
+  "'##' cannot appear at start of macro expansion">;
+def err_paste_at_end : Error<"'##' cannot appear at end of macro expansion">;
+def ext_paste_comma : Extension<
+  "Use of comma pasting extension is non-portable">;
+def err_unterm_macro_invoc : Error<
+  "unterminated function-like macro invocation">;
+def err_too_many_args_in_macro_invoc : Error<
+  "too many arguments provided to function-like macro invocation">;
+def err_too_few_args_in_macro_invoc : Error<
+  "too few arguments provided to function-like macro invocation">;
+def err_pp_bad_paste : Error<
+  "pasting formed '%0', an invalid preprocessing token">;
+def err_pp_operator_used_as_macro_name : Error<
+  "C++ operator '%0' cannot be used as a macro name">;
+def err_pp_illegal_floating_literal : Error<
+  "floating point literal in preprocessor expression">;
+def err_pp_line_requires_integer : Error<
+  "#line directive requires a positive integer argument">;
+def err_pp_line_invalid_filename : Error<
+  "invalid filename for #line directive">;
+def warn_pp_line_decimal : Warning<
+  "#line directive interprets number as decimal, not octal">;
+def err_pp_line_digit_sequence : Error<
+  "#line directive requires a simple digit sequence">;
+def err_pp_linemarker_requires_integer : Error<
+  "line marker directive requires a positive integer argument">;
+def err_pp_linemarker_invalid_filename : Error<
+  "invalid filename for line marker directive">;
+def err_pp_linemarker_invalid_flag : Error<
+  "invalid flag line marker directive">;
+def err_pp_linemarker_invalid_pop : Error<
+  "invalid line marker flag '2': cannot pop empty include stack">;
+def ext_pp_line_too_big : Extension<
+  "C requires #line number to be less than %0, allowed as extension">;
+
+}
diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td
new file mode 100644
index 0000000..2795851
--- /dev/null
+++ b/include/clang/Basic/DiagnosticParseKinds.td
@@ -0,0 +1,371 @@
+//==--- DiagnosticParseKinds.td - libparse diagnostics --------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Parser Diagnostics
+//===----------------------------------------------------------------------===//
+
+let Component = "Parse" in {
+
+def w_asm_qualifier_ignored : Warning<"ignored %0 qualifier on asm">;
+def warn_file_asm_volatile : Warning<
+  "meaningless 'volatile' on asm outside function">;
+
+def ext_empty_source_file : Extension<"ISO C forbids an empty source file">;
+def ext_top_level_semi : Extension<
+  "extra ';' outside of a function">;
+def ext_extra_struct_semi : Extension<
+  "extra ';' inside a struct or union">;
+
+def ext_duplicate_declspec : Extension<"duplicate '%0' declaration specifier">;
+def ext_plain_complex : ExtWarn<
+  "plain '_Complex' requires a type specifier; assuming '_Complex double'">;
+def ext_integer_complex : Extension<
+  "complex integer types are an extension">;
+def ext_thread_before : Extension<"'__thread' before 'static'">;
+
+def ext_empty_struct_union_enum : Extension<"use of empty %0 extension">;
+
+def err_invalid_sign_spec : Error<"'%0' cannot be signed or unsigned">;
+def err_invalid_short_spec : Error<"'short %0' is invalid">;
+def err_invalid_long_spec : Error<"'long %0' is invalid">;
+def err_invalid_longlong_spec : Error<"'long long %0' is invalid">;
+def err_invalid_complex_spec : Error<"'_Complex %0' is invalid">;
+def err_friend_storage_spec : Error<"'%0' is invalid in friend declarations">;
+
+def ext_ident_list_in_param : Extension<
+  "type-less parameter names in function declaration">;
+def ext_c99_variable_decl_in_for_loop : Extension<
+  "variable declaration in for loop is a C99-specific feature">;
+def ext_c99_compound_literal : Extension<
+  "compound literals are a C99-specific feature">;
+def ext_enumerator_list_comma : Extension<
+  "commas at the end of enumerator lists are a %select{C99|C++0x}0-specific "
+  "feature">;
+
+def ext_gnu_indirect_goto : Extension<
+  "use of GNU indirect-goto extension">, InGroup<GNU>;
+def ext_gnu_address_of_label : Extension<
+  "use of GNU address-of-label extension">, InGroup<GNU>;
+def ext_gnu_statement_expr : Extension<
+  "use of GNU statement expression extension">, InGroup<GNU>;
+def ext_gnu_conditional_expr : Extension<
+  "use of GNU ?: expression extension, eliding middle term">, InGroup<GNU>;
+def ext_gnu_empty_initializer : Extension<
+  "use of GNU empty initializer extension">, InGroup<GNU>;
+def ext_gnu_array_range : Extension<"use of GNU array range extension">, 
+  InGroup<GNUDesignator>;
+def ext_gnu_missing_equal_designator : ExtWarn<
+  "use of GNU 'missing =' extension in designator">, 
+  InGroup<GNUDesignator>;
+def err_expected_equal_designator : Error<"expected '=' or another designator">;
+def ext_gnu_old_style_field_designator : ExtWarn<
+  "use of GNU old-style field designator extension">, 
+  InGroup<GNUDesignator>;
+def ext_gnu_case_range : Extension<"use of GNU case range extension">,
+  InGroup<GNU>;
+
+// Generic errors.
+def err_parse_error : Error<"parse error">;
+def err_expected_expression : Error<"expected expression">;
+def err_expected_type : Error<"expected a type">;
+def err_expected_external_declaration : Error<"expected external declaration">;
+def err_expected_ident : Error<"expected identifier">;
+def err_expected_ident_lparen : Error<"expected identifier or '('">;
+def err_expected_ident_lbrace : Error<"expected identifier or '{'">;
+def err_expected_lbrace : Error<"expected '{'">;
+def err_expected_lparen : Error<"expected '('">;
+def err_expected_rparen : Error<"expected ')'">;
+def err_expected_lsquare : Error<"expected '['">;
+def err_expected_rsquare : Error<"expected ']'">;
+def err_expected_rbrace : Error<"expected '}'">;
+def err_expected_greater : Error<"expected '>'">;
+def err_expected_semi_declaration : Error<
+  "expected ';' at end of declaration">;
+def err_expected_semi_decl_list : Error<
+  "expected ';' at end of declaration list">;
+def ext_expected_semi_decl_list : Extension<
+  "expected ';' at end of declaration list">;
+def err_expected_member_name_or_semi : Error<
+  "expected member name or ';' after declaration specifiers">;
+def err_function_declared_typedef : Error<
+  "function definition declared 'typedef'">;
+def err_expected_fn_body : Error<
+  "expected function body after function declarator">;
+def err_expected_method_body : Error<"expected method body">;
+def err_invalid_token_after_toplevel_declarator : Error<
+  "invalid token after top level declarator">;
+def err_expected_statement : Error<"expected statement">;
+def err_expected_lparen_after : Error<"expected '(' after '%0'">;
+def err_expected_lparen_after_id : Error<"expected '(' after %0">;
+def err_expected_less_after : Error<"expected '<' after '%0'">;
+def err_expected_comma : Error<"expected ','">;
+def err_expected_lbrace_in_compound_literal : Error<
+  "expected '{' in compound literal">;
+def err_expected_while : Error<"expected 'while' in do/while loop">;
+
+def err_expected_semi_after : Error<"expected ';' after %0">;
+def err_expected_semi_after_stmt : Error<"expected ';' after %0 statement">;
+def err_expected_semi_after_expr : Error<"expected ';' after expression">;
+def err_expected_semi_after_method_proto : Error<
+  "expected ';' after method prototype">;
+def err_expected_semi_after_namespace_name : Error<
+  "expected ';' after namespace name">;
+def err_unexpected_namespace_attributes_alias : Error<
+  "attributes can not be specified on namespace alias">;
+def err_expected_semi_after_attribute_list : Error<
+  "expected ';' after attribute list">;
+def err_expected_semi_after_static_assert : Error<
+  "expected ';' after static_assert">;
+def err_expected_semi_for : Error<"expected ';' in 'for' statement specifier">;
+def err_expected_colon_after : Error<"expected ':' after %0">;
+def err_label_end_of_compound_statement : Error<
+  "label at end of compound statement: expected statement">;
+def err_expected_string_literal : Error<"expected string literal">;
+def err_expected_asm_operand : Error<
+  "expected string literal or '[' for asm operand">;
+def err_expected_selector_for_method : Error<
+  "expected selector for Objective-C method">;
+def err_expected_property_name : Error<"expected property name">;
+
+def err_unexpected_at : Error<"unexpected '@' in program">;
+
+def err_invalid_reference_qualifier_application : Error<
+  "'%0' qualifier may not be applied to a reference">;
+def err_illegal_decl_reference_to_reference : Error<
+  "%0 declared as a reference to a reference">;
+def err_rvalue_reference : Error<
+  "rvalue references are only allowed in C++0x">;
+def err_argument_required_after_attribute : Error<
+  "argument required after attribute">;
+def err_missing_param : Error<"expected parameter declarator">;
+def err_missing_comma_before_ellipsis : Error<
+  "C requires a comma prior to the ellipsis in a variadic function type">;
+def err_unexpected_typedef_ident : Error<
+  "unexpected type name %0: expected identifier">;
+def err_expected_class_name : Error<"expected class name">;
+def err_unspecified_vla_size_with_static : Error<
+  "'static' may not be used with an unspecified variable length array size">;
+
+// Declarations.
+def err_typename_requires_specqual : Error<
+  "type name requires a specifier or qualifier">;
+def err_typename_invalid_storageclass : Error<
+  "type name does not allow storage class to be specified">;
+def err_typename_invalid_functionspec : Error<
+  "type name does not allow function specifier to be specified">;
+def err_invalid_decl_spec_combination : Error<
+  "cannot combine with previous '%0' declaration specifier">;
+def err_invalid_vector_decl_spec_combination : Error<
+  "cannot combine with previous '%0' declaration specifier. '__vector' must be first">;
+def err_invalid_pixel_decl_spec_combination : Error<
+  "'__pixel' must be preceded by '__vector'.  '%0' declaration specifier not allowed here">;
+def err_invalid_vector_double_decl_spec_combination : Error<
+  "cannot use 'double' with '__vector'">;
+def warn_vector_long_decl_spec_combination : Warning<
+  "Use of 'long' with '__vector' is deprecated">, InGroup<Deprecated>;
+def err_friend_invalid_in_context : Error<
+  "'friend' used outside of class">;
+def err_unknown_typename : Error<
+  "unknown type name %0">;
+def err_use_of_tag_name_without_tag : Error<
+  "must use '%1' tag to refer to type %0%select{| in this scope}2">;
+def err_expected_ident_in_using : Error<
+  "expected an identifier in using directive">;
+def err_unexected_colon_in_nested_name_spec : Error<
+  "unexpected ':' in nested name specifier">;
+
+/// Objective-C parser diagnostics
+def err_expected_minus_or_plus : Error<
+  "method type specifier must start with '-' or '+'">;
+def err_objc_no_attributes_on_category : Error<
+  "attributes may not be specified on a category">;
+def err_objc_missing_end : Error<"missing @end">;
+def warn_objc_protocol_qualifier_missing_id : Warning<
+  "protocol qualifiers without 'id' is archaic">;
+def err_objc_unknown_at : Error<"expected an Objective-C directive after '@'">;
+def err_illegal_super_cast : Error<
+  "cannot cast 'super' (it isn't an expression)">;
+  
+def err_objc_illegal_visibility_spec : Error<
+  "illegal visibility specification">;
+def err_objc_illegal_interface_qual : Error<"illegal interface qualifier">;
+def err_objc_expected_equal : Error<
+  "setter/getter expects '=' followed by name">;
+def err_objc_property_requires_field_name : Error<
+  "property requires fields to be named">;
+def err_objc_property_bitfield : Error<"property name cannot be a bitfield">;
+def err_objc_expected_property_attr : Error<"unknown property attribute %0">;
+def err_objc_propertoes_require_objc2 : Error<
+  "properties are an Objective-C 2 feature">;
+def err_objc_unexpected_attr : Error<
+  "prefix attribute must be followed by an interface or protocol">;
+def err_objc_directive_only_in_protocol : Error<
+  "directive may only be specified in protocols only">;
+def err_missing_catch_finally : Error<
+  "@try statement without a @catch and @finally clause">;
+def err_objc_concat_string : Error<"unexpected token after Objective-C string">;
+def err_missing_sel_definition : Error<"cannot find definition of 'SEL'">;
+def err_missing_id_definition : Error<"cannot find definition of 'id'">;
+def err_missing_proto_definition : Error<
+  "cannot find definition of 'Protocol'">;
+def err_missing_class_definition : Error<"cannot find definition of 'Class'">;
+def warn_expected_implementation : Warning<
+  "@end must appear in an @implementation context">;
+def error_property_ivar_decl : Error<
+  "property synthesize requires specification of an ivar">;
+def err_synthesized_property_name : Error<
+  "expected a property name in @synthesize">;
+def warn_semicolon_before_method_body : Warning<
+  "semicolon before method body is ignored">,
+  InGroup<DiagGroup<"semicolon-before-method-body">>, DefaultIgnore;
+
+def err_expected_field_designator : Error<
+  "expected a field designator, such as '.field = 4'">;
+
+def err_declaration_does_not_declare_param : Error<
+  "declaration does not declare a parameter">;
+def err_no_matching_param : Error<"parameter named %0 is missing">;
+
+/// C++ parser diagnostics
+def err_expected_unqualified_id : Error<
+  "expected %select{identifier|unqualified-id}0">;
+def err_func_def_no_params : Error<
+  "function definition does not declare parameters">;
+def err_expected_lparen_after_type : Error<
+  "expected '(' for function-style cast or type construction">;
+def err_expected_equal_after_declarator : Error<
+  "expected '=' after declarator">;
+def warn_parens_disambiguated_as_function_decl : Warning<
+  "parentheses were disambiguated as a function declarator">;
+def err_expected_member_or_base_name : Error<
+  "expected class member or base class name">;
+def err_expected_lbrace_after_base_specifiers : Error<
+  "expected '{' after base class list">;
+def ext_ellipsis_exception_spec : Extension<
+  "exception specification of '...' is a Microsoft extension">;
+def err_expected_catch : Error<"expected catch">;
+def err_expected_lbrace_or_comma : Error<"expected '{' or ','">;
+def err_using_namespace_in_class : Error<
+  "'using namespace' is not allowed in classes">;
+def err_destructor_tilde_identifier : Error<
+  "expected a class name after '~' to name a destructor">;
+def err_destructor_template_id : Error<
+  "destructor name %0 does not refer to a template">;
+
+// C++ derived classes
+def err_dup_virtual : Error<"duplicate 'virtual' in base specifier">;
+
+// C++ operator overloading
+def err_operator_missing_type_specifier : Error<
+  "missing type specifier after 'operator'">;
+def err_operator_string_not_empty : Error<
+  "string literal after 'operator' must be '\"\"'">;
+
+// Classes.
+def err_anon_type_definition : Error<
+  "declaration of anonymous %0 must be a definition">;
+
+def err_cxx0x_attribute_forbids_arguments : Error<
+  "C++0x attribute '%0' cannot have an argument list">;
+def err_cxx0x_attribute_requires_arguments : Error<
+  "C++0x attribute '%0' must have an argument list">;
+def err_attributes_not_allowed : Error<"an attribute list cannot appear here">;
+
+/// C++ Templates
+def err_expected_template : Error<"expected template">;
+def err_unknown_template_name : Error<
+  "unknown template name %0">;
+def err_expected_comma_greater : Error<
+  "expected ',' or '>' in template-parameter-list">;
+def err_expected_type_id_after : Error<"expected type-id after '%0'">;
+def err_expected_class_before : Error<"expected 'class' before '%0'">;
+def err_template_spec_syntax_non_template : Error<
+  "identifier followed by '<' indicates a class template specialization but "
+  "%0 %select{does not refer to a template|refers to a function "
+  "template|<unused>|refers to a template template parameter}1">;
+def err_id_after_template_in_nested_name_spec : Error<
+  "expected template name after 'template' keyword in nested name specifier">;
+def err_id_after_template_in_typename_spec : Error<
+  "expected template name after 'template' keyword in typename specifier">;
+def err_less_after_template_name_in_nested_name_spec : Error<
+  "expected '<' after 'template %0' in nested name specifier">;
+def err_two_right_angle_brackets_need_space : Error<
+  "a space is required between consecutive right angle brackets (use '> >')">;
+def warn_cxx0x_right_shift_in_template_arg : Warning<
+  "use of right-shift operator ('>>') in template argument will require "
+  "parentheses in C++0x">;
+def err_multiple_template_declarators : Error<
+    "%select{|a template declaration|an explicit template specialization|"
+    "an explicit template instantiation}0 can "
+    "only %select{|declare|declare|instantiate}0 a single entity">;
+def err_explicit_instantiation_with_definition : Error<
+    "explicit template instantiation cannot have a definition; if this "
+    "definition is meant to be an explicit specialization, add '<>' after the "
+    "'template' keyword">;
+def err_enum_template : Error<"enumeration cannot be a template">;
+
+// Constructor template diagnostics.
+def err_out_of_line_constructor_template_id : Error<
+  "out-of-line constructor for %0 cannot have template arguments">;
+def err_out_of_line_template_id_names_constructor : Error<
+  "qualified reference to %0 is a constructor name rather than a "
+  "template name wherever a constructor can be declared">;
+def err_out_of_line_type_names_constructor : Error<
+  "qualified reference to %0 is a constructor name rather than a "
+  "type wherever a constructor can be declared">;
+
+def err_expected_qualified_after_typename : Error<
+  "expected a qualified name after 'typename'">;
+def err_expected_semi_after_tagdecl : Error<
+  "expected ';' after %0">;
+
+def err_typename_refers_to_non_type_template : Error<
+  "typename specifier refers to a non-template">;
+def err_expected_type_name_after_typename : Error<
+  "expected an identifier or template-id after '::'">;
+def err_explicit_spec_non_template : Error<
+  "explicit %select{specialization|instantiation}0 of non-template "
+  "%select{class|struct|union}1 %2">;
+
+def err_variadic_templates : Error<
+  "variadic templates are only allowed in C++0x">;
+  
+def err_default_template_template_parameter_not_template : Error<
+  "default template argument for a template template parameter must be a class "
+  "template">;
+  
+// C++ declarations
+def err_friend_decl_defines_class : Error<
+  "cannot define a type in a friend declaration">;
+  
+// Language specific pragmas
+// - Generic warnings
+def warn_pragma_expected_lparen : Warning<
+  "missing '(' after '#pragma %0' - ignoring">;
+def warn_pragma_expected_rparen : Warning<
+  "missing ')' after '#pragma %0' - ignoring">;
+def warn_pragma_expected_identifier : Warning<
+  "expected identifier in '#pragma %0' - ignored">;  
+def warn_pragma_extra_tokens_at_eol : Warning<
+  "extra tokens at end of '#pragma %0' - ignored">; 
+// - #pragma pack
+def warn_pragma_pack_invalid_action : Warning<
+  "unknown action for '#pragma pack' - ignored">;
+def warn_pragma_pack_invalid_constant : Warning<
+  "invalid constant for '#pragma pack', expected %0 - ignored">;
+def warn_pragma_pack_malformed : Warning<
+  "expected integer or identifier in '#pragma pack' - ignored">;
+// - #pragma unused
+def warn_pragma_unused_expected_var : Warning<
+  "expected '#pragma unused' argument to be a variable name">;
+def warn_pragma_unused_expected_punc : Warning<
+  "expected ')' or ',' in '#pragma unused'">;
+
+} // end of Parser diagnostics
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
new file mode 100644
index 0000000..94f1df1
--- /dev/null
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -0,0 +1,3007 @@
+//==--- DiagnosticSemaKinds.td - libsema diagnostics ----------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Semantic Analysis
+//===----------------------------------------------------------------------===//
+
+let Component = "Sema" in {
+
+// Constant expressions
+def err_expr_not_ice : Error<
+  "expression is not an integer constant expression">;
+def ext_expr_not_ice : Extension<
+  "expression is not integer constant expression "
+  "(but is allowed as an extension)">;
+
+def ext_null_pointer_expr_not_ice : Extension<
+  "null pointer expression is not an integer constant expression "
+  "(but is allowed as an extension)">;
+
+
+
+// Semantic analysis of constant literals.
+def ext_predef_outside_function : Warning<
+  "predefined identifier is only valid inside function">;
+def warn_float_overflow : Warning<
+  "magnitude of floating-point constant too large for type %0; maximum is %1">,
+   InGroup<LiteralRange>;
+def warn_float_underflow : Warning<
+  "magnitude of floating-point constant too small for type %0; minimum is %1">,
+  InGroup<LiteralRange>;
+
+// C99 Designated Initializers
+def err_array_designator_negative : Error<
+  "array designator value '%0' is negative">;
+def err_array_designator_empty_range : Error<
+  "array designator range [%0, %1] is empty">;
+def err_array_designator_non_array : Error<
+  "array designator cannot initialize non-array type %0">;
+def err_array_designator_too_large : Error<
+  "array designator index (%0) exceeds array bounds (%1)">;
+def err_field_designator_non_aggr : Error<
+  "field designator cannot initialize a "
+  "%select{non-struct, non-union|non-class}0 type %1">;
+def err_field_designator_unknown : Error<
+  "field designator %0 does not refer to any field in type %1">;
+def err_field_designator_nonfield : Error<
+  "field designator %0 does not refer to a non-static data member">;
+def note_field_designator_found : Note<"field designator refers here">;
+def err_designator_for_scalar_init : Error<
+  "designator in initializer for scalar type %0">;
+def warn_subobject_initializer_overrides : Warning<
+  "subobject initialization overrides initialization of other fields "
+  "within its enclosing subobject">;
+def warn_initializer_overrides : Warning<
+  "initializer overrides prior initialization of this subobject">;
+def note_previous_initializer : Note<
+  "previous initialization %select{|with side effects }0is here"
+  "%select{| (side effects may not occur at run time)}0">;
+def err_designator_into_flexible_array_member : Error<
+  "designator into flexible array member subobject">;
+def note_flexible_array_member : Note<
+  "initialized flexible array member %0 is here">;
+def ext_flexible_array_init : Extension<
+  "flexible array initialization is a GNU extension">, InGroup<GNU>;
+
+// Declarations.
+def ext_vla : Extension<
+  "variable length arrays are a C99 feature, accepted as an extension">;
+def err_vla_cxx : Error<
+  "variable length arrays are not permitted in C++">;
+  
+def ext_anon_param_requires_type_specifier : Extension<
+  "type specifier required for unnamed parameter, defaults to int">;
+def err_bad_variable_name : Error<
+  "'%0' cannot be the name of a variable or data member">;
+def err_parameter_name_omitted : Error<"parameter name omitted">;
+def warn_unused_parameter : Warning<"unused parameter %0">,
+  InGroup<UnusedParameter>, DefaultIgnore;
+def warn_unused_variable : Warning<"unused variable %0">,
+  InGroup<UnusedVariable>, DefaultIgnore;
+def warn_decl_in_param_list : Warning<
+  "declaration of %0 will not be visible outside of this function">;
+def err_array_star_in_function_definition : Error<
+  "variable length array must be bound in function definition">;
+def warn_unused_function : Warning<"unused function %0">,
+  InGroup<UnusedFunction>, DefaultIgnore;
+  
+def warn_implicit_function_decl : Warning<
+  "implicit declaration of function %0">,
+  InGroup<ImplicitFunctionDeclare>, DefaultIgnore;
+def ext_implicit_function_decl : ExtWarn<
+  "implicit declaration of function %0 is invalid in C99">,
+  InGroup<ImplicitFunctionDeclare>;
+
+def err_ellipsis_first_arg : Error<
+  "ISO C requires a named argument before '...'">;
+def err_declarator_need_ident : Error<"declarator requires an identifier">;
+def err_bad_language : Error<"unknown linkage language">;
+def warn_use_out_of_scope_declaration : Warning<
+  "use of out-of-scope declaration of %0">;
+def err_inline_non_function : Error<
+  "'inline' can only appear on functions">;
+
+def warn_decl_shadow :
+  Warning<"declaration shadows a %select{"
+          "local variable|"
+          "variable in %2|"
+          "static data member of %2|"
+          "field of %2}1">,
+  InGroup<Shadow>, DefaultIgnore;
+
+// C++ using declarations
+def err_using_requires_qualname : Error<
+  "using declaration requires a qualified name">;
+def err_using_typename_non_type : Error<
+  "'typename' keyword used on a non-type">;
+def err_using_dependent_value_is_type : Error<
+  "dependent using declaration resolved to type without 'typename'">;
+def err_using_decl_nested_name_specifier_is_not_class : Error<
+  "using declaration in class refers into '%0', which is not a class">;
+def err_using_decl_nested_name_specifier_is_current_class : Error<
+  "using declaration refers to its own class">;
+def err_using_decl_nested_name_specifier_is_not_base_class : Error<
+  "using declaration refers into '%0', which is not a base class of %1">;
+def err_using_decl_can_not_refer_to_class_member : Error<
+  "using declaration can not refer to class member">;
+def err_using_decl_can_not_refer_to_namespace : Error<
+  "using declaration can not refer to namespace">;
+def err_using_decl_constructor : Error<
+  "using declaration can not refer to a constructor">;
+def err_using_decl_destructor : Error<
+  "using declaration can not refer to a destructor">;
+def err_using_decl_template_id : Error<
+  "using declaration can not refer to a template specialization">;
+def note_using_decl_target : Note<"target of using declaration">;
+def note_using_decl_conflict : Note<"conflicting declaration">;
+def err_using_decl_redeclaration : Error<"redeclaration of using decl">;
+def err_using_decl_conflict : Error<
+  "target of using declaration conflicts with declaration already in scope">;
+def err_using_decl_conflict_reverse : Error<
+  "declaration conflicts with target of using declaration already in scope">;
+def note_using_decl : Note<"%select{|previous }0using declaration">;
+
+def warn_access_decl_deprecated : Warning<
+  "access declarations are deprecated; use using declarations instead">,
+  InGroup<Deprecated>;
+
+def err_invalid_thread : Error<
+  "'__thread' is only allowed on variable declarations">;
+def err_thread_non_global : Error<
+  "'__thread' variables must have global storage">;
+def err_thread_unsupported : Error<
+  "thread-local storage is unsupported for the current target">;
+
+def warn_maybe_falloff_nonvoid_function : Warning<
+  "control may reach end of non-void function">,
+  InGroup<ReturnType>;
+def warn_falloff_nonvoid_function : Warning<
+  "control reaches end of non-void function">,
+  InGroup<ReturnType>;
+def err_maybe_falloff_nonvoid_block : Error<
+  "control may reach end of non-void block">;
+def err_falloff_nonvoid_block : Error<
+  "control reaches end of non-void block">;
+def warn_suggest_noreturn_function : Warning<
+  "function could be attribute 'noreturn'">,
+  InGroup<DiagGroup<"missing-noreturn">>, DefaultIgnore;
+def warn_suggest_noreturn_block : Warning<
+  "block could be attribute 'noreturn'">,
+  InGroup<DiagGroup<"missing-noreturn">>, DefaultIgnore;
+def warn_unreachable : Warning<"will never be executed">,
+  InGroup<DiagGroup<"unreachable-code">>, DefaultIgnore;
+
+/// Built-in functions.
+def ext_implicit_lib_function_decl : ExtWarn<
+  "implicitly declaring C library function '%0' with type %1">;
+def note_please_include_header : Note<
+  "please include the header <%0> or explicitly provide a "
+  "declaration for '%1'">;
+def note_previous_builtin_declaration : Note<"%0 is a builtin with type %1">;
+def err_implicit_decl_requires_stdio : Error<
+  "implicit declaration of '%0' requires inclusion of the header <stdio.h>">;
+def err_implicit_decl_requires_setjmp : Error<
+  "implicit declaration of '%0' requires inclusion of the header <setjmp.h>">;
+def warn_redecl_library_builtin : Warning<
+  "incompatible redeclaration of library function %0">;
+def err_builtin_definition : Error<"definition of builtin function %0">;
+def err_types_compatible_p_in_cplusplus : Error<
+  "__builtin_types_compatible_p is not valid in C++">;
+def warn_builtin_unknown : Warning<"use of unknown builtin %0">, DefaultError;
+
+/// main()
+// static/inline main() are not errors in C, just in C++.
+def warn_unusual_main_decl : Warning<"'main' should not be declared "
+    "%select{static|inline|static or inline}0">;
+def err_unusual_main_decl : Error<"'main' is not allowed to be declared "
+    "%select{static|inline|static or inline}0">;
+def err_main_returns_nonint : Error<"'main' must return 'int'">;
+def err_main_surplus_args : Error<"too many parameters (%0) for 'main': "
+    "must be 0, 2, or 3">;
+def warn_main_one_arg : Warning<"only one parameter on 'main' declaration">;
+def err_main_arg_wrong : Error<"%select{first|second|third|fourth}0 "
+    "parameter of 'main' (%select{argument count|argument array|environment|"
+    "platform-specific data}0) must be of type %1">;
+
+/// parser diagnostics
+def ext_typedef_without_a_name : ExtWarn<"typedef requires a name">;
+def err_statically_allocated_object : Error<
+  "interface type cannot be statically allocated">;
+def err_object_cannot_be_passed_returned_by_value : Error<
+  "interface type %1 cannot be %select{returned|passed}0 by value"
+  "; did you forget * in %1">;
+def warn_enum_value_overflow : Warning<"overflow in enumeration value">;
+def warn_pragma_pack_invalid_alignment : Warning<
+  "expected #pragma pack parameter to be '1', '2', '4', '8', or '16'">;
+// Follow the MSVC implementation.
+def warn_pragma_pack_show : Warning<"value of #pragma pack(show) == %0">;
+def warn_pragma_pack_pop_identifer_and_alignment : Warning<
+  "specifying both a name and alignment to 'pop' is undefined">;
+def warn_pragma_pack_pop_failed : Warning<"#pragma pack(pop, ...) failed: %0">;
+
+def warn_pragma_unused_undeclared_var : Warning<
+  "undeclared variable %0 used as an argument for '#pragma unused'">;
+def warn_pragma_unused_expected_localvar : Warning<
+  "only local variables can be arguments to '#pragma unused'">;
+def err_unsupported_pragma_weak : Error<
+  "using '#pragma weak' to refer to an undeclared identifier is not yet supported">;
+
+/// Objective-C parser diagnostics
+def err_duplicate_class_def : Error<
+  "duplicate interface definition for class %0">;
+def err_undef_superclass : Error<
+  "cannot find interface declaration for %0, superclass of %1">;
+def err_no_nsconstant_string_class : Error<
+  "cannot find interface declaration for %0">;
+def err_recursive_superclass : Error<
+  "trying to recursively use %0 as superclass of %1">;
+def warn_previous_alias_decl : Warning<"previously declared alias is ignored">;
+def err_conflicting_aliasing_type : Error<"conflicting types for alias %0">;
+def warn_undef_interface : Warning<"cannot find interface declaration for %0">;
+def warn_duplicate_protocol_def : Warning<"duplicate protocol definition of %0 is ignored">;
+def err_protocol_has_circular_dependency : Error<
+  "protocol has circular dependency">;
+def err_undeclared_protocol : Error<"cannot find protocol declaration for %0">;
+def warn_undef_protocolref : Warning<"cannot find protocol definition for %0">;
+def warn_readonly_property : Warning<
+  "attribute 'readonly' of property %0 restricts attribute "
+  "'readwrite' of property inherited from %1">;
+
+def warn_property_attribute : Warning<
+  "property %0 '%1' attribute does not match the property inherited from %2">;
+def warn_property_types_are_incompatible : Warning<
+  "property type %0 is incompatible with type %1 inherited from %2">;
+def err_undef_interface : Error<"cannot find interface declaration for %0">;
+def err_class_extension_after_impl : Error<
+  "cannot declare class extension for %0 after class implementation">;
+def note_implementation_declared : Note<
+  "class implementation is declared here">;
+def warn_dup_category_def : Warning<
+  "duplicate definition of category %1 on interface %0">;
+def err_conflicting_super_class : Error<"conflicting super class name %0">;
+def err_dup_implementation_class : Error<"reimplementation of class %0">;
+def err_dup_implementation_category : Error<
+  "reimplementation of category %1 for class %0">;
+def err_conflicting_ivar_type : Error<
+  "instance variable %0 has conflicting type: %1 vs %2">;
+def err_duplicate_ivar_declaration : Error<
+  "instance variable is already declared">;
+def warn_on_superclass_use : Warning<
+  "class implementation may not have super class">;
+def err_conflicting_ivar_bitwidth : Error<
+  "instance variable %0 has conflicting bit-field width">;
+def err_conflicting_ivar_name : Error<
+  "conflicting instance variable names: %0 vs %1">;
+def err_inconsistant_ivar_count : Error<
+  "inconsistent number of instance variables specified">;
+def warn_incomplete_impl : Warning<"incomplete implementation">;
+def note_undef_method_impl : Note<"method definition for %0 not found">;
+def note_required_for_protocol_at : 
+  Note<"required for direct or indirect protocol %0">;
+
+def warn_conflicting_ret_types : Warning<
+  "conflicting return type in implementation of %0: %1 vs %2">;
+
+def warn_conflicting_param_types : Warning<
+  "conflicting parameter types in implementation of %0: %1 vs %2">;
+
+def warn_implements_nscopying : Warning<
+"default assign attribute on property %0 which implements "
+"NSCopying protocol is not appropriate with -fobjc-gc[-only]">;
+
+def warn_multiple_method_decl : Warning<"multiple methods named %0 found">;
+def warn_accessor_property_type_mismatch : Warning<
+  "type of property %0 does not match type of accessor %1">;
+def note_declared_at : Note<"declared here">;
+def err_setter_type_void : Error<"type of setter must be void">;
+def err_duplicate_method_decl : Error<"duplicate declaration of method %0">;
+def warn_missing_atend : Warning<"'@end' is missing in implementation context">;
+def err_objc_var_decl_inclass : 
+    Error<"cannot declare variable inside @interface or @protocol">;
+def error_missing_method_context : Error<
+  "missing context for method declaration">;
+def err_objc_property_attr_mutually_exclusive : Error<
+  "property attributes '%0' and '%1' are mutually exclusive">;
+def err_objc_property_requires_object : Error<
+  "property with '%0' attribute must be of object type">;
+def warn_objc_property_no_assignment_attribute : Warning<
+  "no 'assign', 'retain', or 'copy' attribute is specified - "
+  "'assign' is assumed">;
+def warn_objc_property_default_assign_on_object : Warning<
+  "default property attribute 'assign' not appropriate for non-gc object">;
+def warn_property_attr_mismatch : Warning<
+  "property attribute in continuation class does not match the primary class">;
+def warn_objc_property_copy_missing_on_block : Warning<
+    "'copy' attribute must be specified for the block property "
+    "when -fobjc-gc-only is specified">;
+def warn_atomic_property_rule : Warning<
+  "writable atomic property %0 cannot pair a synthesized setter/getter "
+  "with a user defined setter/getter">;
+def err_use_continuation_class : Error<
+  "illegal declaration of property in continuation class %0"
+  ": attribute must be readwrite, while its primary must be readonly">;
+def err_continuation_class : Error<"continuation class has no primary class">;
+def err_property_type : Error<"property cannot have array or function type %0">;
+def error_missing_property_context : Error<
+  "missing context for property implementation declaration">;
+def error_bad_property_decl : Error<
+  "property implementation must have its declaration in interface %0">;
+def error_category_property : Error<
+  "property declared in category %0 cannot be implemented in "
+  "class implementation">;
+def note_property_declare : Note<
+  "property declared here">;
+def error_synthesize_category_decl : Error<
+  "@synthesize not allowed in a category's implementation">;
+def error_reference_property : Error<
+  "property of reference type is not supported">;
+def error_missing_property_interface : Error<
+  "property implementation in a category with no category declaration">;
+def error_bad_category_property_decl : Error<
+  "property implementation must have its declaration in the category %0">;
+def error_bad_property_context : Error<
+  "property implementation must be in a class or category implementation">;
+def error_missing_property_ivar_decl : Error<
+  "synthesized property %0 must either be named the same as a compatible"
+  " ivar or must explicitly name an ivar">;
+
+def error_synthesized_ivar_yet_not_supported : Error<
+  "instance variable synthesis not yet supported"
+  " (need to declare %0 explicitly)">;
+
+def error_property_ivar_type : Error<
+  "type of property %0 (%1) does not match type of ivar %2 (%3)">;
+def error_ivar_in_superclass_use : Error<
+  "property %0 attempting to use ivar %1 declared in super class %2">;
+def error_weak_property : Error<
+  "existing ivar %1 for __weak property %0 must be __weak">;
+def error_strong_property : Error<
+  "existing ivar %1 for a __strong property %0 must be garbage collectable">;
+def error_dynamic_property_ivar_decl : Error<
+  "dynamic property can not have ivar specification">;
+def error_duplicate_ivar_use : Error<
+  "synthesized properties %0 and %1 both claim ivar %2">;
+def error_property_implemented : Error<"property %0 is already implemented">;
+def warn_objc_property_attr_mutually_exclusive : Warning<
+  "property attributes '%0' and '%1' are mutually exclusive">,
+  InGroup<ReadOnlySetterAttrs>, DefaultIgnore;
+def warn_undeclared_selector : Warning<
+  "undeclared selector %0">, InGroup<UndeclaredSelector>, DefaultIgnore;
+def warn_unimplemented_protocol_method : Warning<
+  "method in protocol not implemented">, InGroup<Protocol>;
+
+// C++ declarations
+def err_static_assert_expression_is_not_constant : Error<
+  "static_assert expression is not an integral constant expression">;
+def err_static_assert_failed : Error<"static_assert failed \"%0\"">;
+
+def err_unexpected_friend : Error<
+  "friends can only be classes or functions">;
+def ext_enum_friend : ExtWarn<
+  "enumeration type %0 cannot be a friend">;
+def ext_nonclass_type_friend : ExtWarn<
+  "non-class type %0 cannot be a friend">;
+def err_friend_is_member : Error<
+  "friends cannot be members of the declaring class">;
+def ext_unelaborated_friend_type : ExtWarn<
+  "must specify '%select{struct|union|class|enum}0' to befriend %1">;
+def err_qualified_friend_not_found : Error<
+  "no function named %0 with type %1 was found in the specified scope">;
+def err_introducing_special_friend : Error<
+  "must use a qualified name when declaring a %select{constructor|"
+  "destructor|conversion operator}0 as a friend">;
+def err_tagless_friend_type_template : Error<
+  "friend type templates must use an elaborated type">;
+
+def err_abstract_type_in_decl : Error<
+  "%select{return|parameter|variable|field}0 type %1 is an abstract class">;
+def err_allocation_of_abstract_type : Error<
+  "allocation of an object of abstract type %0">;
+def err_throw_abstract_type : Error<
+  "cannot throw an object of abstract type %0">;
+
+def err_multiple_final_overriders : Error<
+  "virtual function %q0 has more than one final overrider in %1">; 
+def note_final_overrider : Note<"final overrider of %q0 in %1">;
+
+def err_type_defined_in_type_specifier : Error<
+  "%0 can not be defined in a type specifier">;
+def err_type_defined_in_result_type : Error<
+  "%0 can not be defined in the result type of a function">;
+def err_type_defined_in_param_type : Error<
+  "%0 can not be defined in a parameter type">;
+
+def note_pure_virtual_function : Note<
+  "pure virtual function %0">;
+
+def err_deleted_non_function : Error<
+  "only functions can have deleted definitions">;
+def err_deleted_decl_not_first : Error<
+  "deleted definition must be first declaration">;
+
+def warn_weak_vtable : Warning<
+  "%0 has no out-of-line virtual method definitions; its vtable will be "
+  "emitted in every translation unit">,
+  InGroup<DiagGroup<"weak-vtables">>, DefaultIgnore;
+
+// C++ exception specifications
+def err_exception_spec_in_typedef : Error<
+  "exception specifications are not allowed in typedefs">;
+def err_distant_exception_spec : Error<
+  "exception specifications are not allowed beyond a single level "
+  "of indirection">;
+def err_incomplete_in_exception_spec : Error<
+  "%select{|pointer to |reference to }0incomplete type %1 is not allowed "
+  "in exception specification">;
+def err_mismatched_exception_spec : Error<
+  "exception specification in declaration does not match previous declaration">;
+def err_override_exception_spec : Error<
+  "exception specification of overriding function is more lax than "
+  "base version">;
+def err_incompatible_exception_specs : Error<
+  "target exception specification is not superset of source">;
+def err_deep_exception_specs_differ : Error<
+  "exception specifications of %select{return|argument}0 types differ">;
+def warn_missing_exception_specification : Warning<
+  "%0 is missing exception specification '%1'">;
+
+// C++ access checking
+def err_class_redeclared_with_different_access : Error<
+  "%0 redeclared with '%1' access">;
+def err_access : Error<
+  "%1 is a %select{private|protected}0 member of %3">, NoSFINAE;
+def err_access_ctor : Error<
+  "calling a %select{private|protected}0 constructor of class %2">, NoSFINAE;
+def err_access_base : Error<
+  "%select{base class|inherited virtual base class}0 %1 has %select{private|"
+  "protected}3 %select{constructor|copy constructor|copy assignment operator|"
+  "destructor}2">, NoSFINAE;
+def err_access_field: Error<
+  "field of type %0 has %select{private|protected}2 %select{constructor|copy "
+  "constructor|copy assignment operator|destructor}1">, NoSFINAE;
+
+def err_access_ctor_field :
+    Error<"field of type %1 has %select{private|protected}2 constructor">,
+    NoSFINAE;
+def err_access_dtor_base :
+    Error<"base class %0 has %select{private|protected}1 destructor">,
+    NoSFINAE;
+def err_access_dtor_vbase :
+    Error<"inherited virtual base class %0 has "
+    "%select{private|protected}1 destructor">,
+    NoSFINAE;
+def err_access_dtor_temp :
+    Error<"temporary of type %0 has %select{private|protected}1 destructor">,
+    NoSFINAE;
+def err_access_dtor_field :
+    Error<"field of type %1 has %select{private|protected}2 destructor">,
+    NoSFINAE;
+def err_access_dtor_var :
+    Error<"variable of type %1 has %select{private|protected}2 destructor">,
+    NoSFINAE;
+def err_access_assign_field :
+    Error<"field of type %1 has %select{private|protected}2 copy assignment"
+          " operator">,
+    NoSFINAE;
+def err_access_assign_base :
+    Error<"base class %0 has %select{private|protected}1 copy assignment"
+          " operator">,
+    NoSFINAE;
+def err_access_copy_field :
+    Error<"field of type %1 has %select{private|protected}2 copy constructor">,
+    NoSFINAE;
+def err_access_copy_base :
+    Error<"base class %0 has %select{private|protected}1 copy constructor">,
+    NoSFINAE;
+def note_previous_access_declaration : Note<
+  "previously declared '%1' here">;
+def err_access_outside_class : Error<
+  "access to %select{private|protected}0 member outside any class context">;
+def note_access_natural : Note<
+  "%select{|implicitly }1declared %select{private|protected}0 here">;
+def note_access_constrained_by_path : Note<
+  "constrained by %select{|implicitly }1%select{private|protected}0"
+  " inheritance here">;
+  
+// C++ name lookup
+def err_incomplete_nested_name_spec : Error<
+  "incomplete type %0 named in nested name specifier">;
+def err_dependent_nested_name_spec : Error<
+  "nested name specifier for a declaration cannot depend on a template "
+  "parameter">;
+def err_nested_name_member_ref_lookup_ambiguous : Error<
+  "lookup of %0 in member access expression is ambiguous">;
+def note_ambig_member_ref_object_type : Note<
+  "lookup in the object type %0 refers here">;
+def note_ambig_member_ref_scope : Note<
+  "lookup from the current scope refers here">;
+def err_qualified_member_nonclass : Error<
+  "qualified member access refers to a member in %0">;
+def err_incomplete_member_access : Error<
+  "member access into incomplete type %0">;
+def err_incomplete_type : Error<
+  "incomplete type %0 where a complete type is required">;
+  
+// C++ class members
+def err_storageclass_invalid_for_member : Error<
+  "storage class specified for a member declaration">;
+def err_mutable_function : Error<"'mutable' cannot be applied to functions">;
+def err_mutable_reference : Error<"'mutable' cannot be applied to references">;
+def err_mutable_const : Error<"'mutable' and 'const' cannot be mixed">;
+def err_mutable_nonmember : Error<
+  "'mutable' can only be applied to member variables">;
+def err_virtual_non_function : Error<
+  "'virtual' can only appear on non-static member functions">;
+def err_virtual_out_of_class : Error<
+  "'virtual' can only be specified inside the class definition">;
+def err_explicit_non_function : Error<
+  "'explicit' can only appear on non-static member functions">;
+def err_explicit_out_of_class : Error<
+  "'explicit' can only be specified inside the class definition">;
+def err_explicit_non_ctor_or_conv_function : Error<
+  "'explicit' can only be applied to a constructor or conversion function">;
+def err_static_not_bitfield : Error<"static member %0 cannot be a bit-field">;
+def err_static_out_of_line : Error<
+  "'static' can only be specified inside the class definition">;
+def err_typedef_not_bitfield : Error<"typedef member %0 cannot be a bit-field">;
+def err_not_integral_type_bitfield : Error<
+  "bit-field %0 has non-integral type %1">;
+def err_not_integral_type_anon_bitfield : Error<
+  "anonymous bit-field has non-integral type %0">;
+def err_member_initialization : Error<
+  "%0 can only be initialized if it is a static const integral data member">;
+def err_member_function_initialization : Error<
+  "initializer on function does not look like a pure-specifier">;
+def err_non_virtual_pure : Error<
+  "%0 is not virtual and cannot be declared pure">;
+def err_implicit_object_parameter_init : Error<
+  "cannot initialize object parameter of type %0 with an expression "
+  "of type %1">;
+def err_qualified_member_of_unrelated : Error<
+  "%q0 is not a member of class %1">;
+
+def note_field_decl : Note<"member is declared here">;
+def note_ivar_decl : Note<"ivar is declared here">;
+def note_bitfield_decl : Note<"bit-field is declared here">;
+def note_previous_decl : Note<"%0 declared here">;
+def note_member_synthesized_at : Note<
+  "implicit default %select{constructor|copy constructor|"
+  "copy assignment operator|destructor}0 for %1 first required here">;
+def err_missing_default_ctor : Error<
+  "%select{|implicit default }0constructor for %1 must explicitly initialize "
+  "the %select{base class|member}2 %3 which does not have a default "
+  "constructor">;
+def err_illegal_union_member : Error<
+  "union member %0 has a non-trivial %select{constructor|"
+  "copy constructor|copy assignment operator|destructor}1">;
+def note_nontrivial_has_virtual : Note<
+  "because type %0 has a virtual %select{member function|base class}1">;
+def note_nontrivial_has_nontrivial : Note<
+  "because type %0 has a %select{member|base class}1 with a non-trivial "
+  "%select{constructor|copy constructor|copy assignment operator|destructor}2">;
+def note_nontrivial_user_defined : Note<
+  "because type %0 has a user-declared %select{constructor|copy constructor|"
+  "copy assignment operator|destructor}1">;
+
+def err_different_return_type_for_overriding_virtual_function : Error<
+  "virtual function %0 has a different return type (%1) than the "
+  "function it overrides (which has return type %2)">;
+def note_overridden_virtual_function : Note<
+  "overridden virtual function is here">;
+
+def err_covariant_return_inaccessible_base : Error<
+  "invalid covariant return for virtual function: %1 is a "
+  "%select{private|protected}2 base class of %0">, NoSFINAE;
+def err_covariant_return_ambiguous_derived_to_base_conv : Error<
+  "return type of virtual function %3 is not covariant with the return type of "
+  "the function it overrides (ambiguous conversion from derived class "
+  "%0 to base class %1:%2)">;
+def err_covariant_return_not_derived : Error<
+  "return type of virtual function %0 is not covariant with the return type of "
+  "the function it overrides (%1 is not derived from %2)">;
+def err_covariant_return_incomplete : Error<
+  "return type of virtual function %0 is not covariant with the return type of "
+  "the function it overrides (%1 is incomplete)">;
+def err_covariant_return_type_different_qualifications : Error<
+  "return type of virtual function %0 is not covariant with the return type of "
+  "the function it overrides (%1 has different qualifiers than %2)">;
+def err_covariant_return_type_class_type_more_qualified : Error<
+  "return type of virtual function %0 is not covariant with the return type of "
+  "the function it overrides (class type %1 is more qualified than class "
+  "type %2">;
+  
+// C++ constructors
+def err_constructor_cannot_be : Error<"constructor cannot be declared '%0'">;
+def err_invalid_qualified_constructor : Error<
+  "'%0' qualifier is not allowed on a constructor">;
+def err_constructor_return_type : Error<
+  "constructor cannot have a return type">;
+def err_constructor_redeclared : Error<"constructor cannot be redeclared">;
+def err_constructor_byvalue_arg : Error<
+  "copy constructor must pass its first argument by reference">;
+def warn_no_constructor_for_refconst : Warning<
+  "%select{struct|union|class|enum}0 %1 does not declare any constructor to "
+  "initialize its non-modifiable members">;
+def note_refconst_member_not_initialized : Note<
+  "%select{const|reference}0 member %1 will never be initialized">;
+
+// C++ destructors
+def err_destructor_not_member : Error<
+  "destructor must be a non-static member function">;
+def err_destructor_cannot_be : Error<"destructor cannot be declared '%0'">;
+def err_invalid_qualified_destructor : Error<
+  "'%0' qualifier is not allowed on a destructor">;
+def err_destructor_return_type : Error<"destructor cannot have a return type">;
+def err_destructor_redeclared : Error<"destructor cannot be redeclared">;
+def err_destructor_with_params : Error<"destructor cannot have any parameters">;
+def err_destructor_variadic : Error<"destructor cannot be variadic">;
+def err_destructor_typedef_name : Error<
+  "destructor cannot be declared using a typedef %0 of the class name">;
+def err_destructor_name : Error<
+  "expected the class name after '~' to name the enclosing class">;
+def err_destructor_class_name : Error<
+  "expected the class name after '~' to name a destructor">;
+def err_ident_in_pseudo_dtor_not_a_type : Error<
+  "identifier %0 in pseudo-destructor expression does not name a type">;
+
+// C++ initialization
+def err_init_conversion_failed : Error<
+  "cannot initialize %select{a variable|a parameter|return object|an "
+  "exception object|a member subobject|an array element|a new value|a value|a "
+  "base class|a vector element}0 of type %1 with an %select{rvalue|lvalue}2 of "
+  "type %3">;
+
+def err_lvalue_to_rvalue_ref : Error<"rvalue reference cannot bind to lvalue">;
+def err_invalid_initialization : Error<
+"invalid initialization of reference of type %0 from expression of type %1">;
+def err_lvalue_to_rvalue_ambig_ref : Error<"rvalue reference cannot bind to lvalue "
+                                           "due to multiple conversion functions">;
+def err_not_reference_to_const_init : Error<
+  "%select{non-const|volatile}0 lvalue reference to type %1 cannot be "
+  "initialized with a %select{value|temporary}2 of type %3">;
+def err_lvalue_reference_bind_to_temporary : Error<
+  "%select{non-const|volatile}0 lvalue reference to type %1 cannot bind to a "
+  "temporary of type %2">;
+def err_lvalue_reference_bind_to_unrelated : Error<
+  "%select{non-const|volatile}0 lvalue reference to type %1 cannot bind to a "
+  "value of unrelated type %2">;
+def err_reference_bind_drops_quals : Error<
+  "binding of reference to type %0 to a value of type %1 drops qualifiers">;
+def err_reference_bind_failed : Error<
+  "reference to type %0 could not bind to an %select{rvalue|lvalue}1 of type "
+  "%2">;
+def err_reference_bind_init_list : Error<
+  "reference to type %0 cannot bind to an initializer list">;
+def err_init_list_bad_dest_type : Error<
+  "%select{|non-aggregate }0type %1 cannot be initialized with an initializer "
+  "list">;
+
+def err_reference_init_drops_quals : Error<
+  "initialization of reference to type %0 with a %select{value|temporary}1 of type %2 drops "
+  "qualifiers">;
+def err_reference_bind_to_bitfield : Error<
+  "%select{non-const|volatile}0 reference cannot bind to bit-field %1">;
+def err_reference_bind_to_vector_element : Error<
+  "%select{non-const|volatile}0 reference cannot bind to vector element">;
+def err_reference_var_requires_init : Error<
+  "declaration of reference variable %0 requires an initializer">;
+def err_const_var_requires_init : Error<
+  "declaration of const variable '%0' requires an initializer">;
+def err_reference_without_init : Error<
+  "reference to type %0 requires an initializer">;
+def err_reference_has_multiple_inits : Error<
+  "reference cannot be initialized with multiple values">;
+def err_init_non_aggr_init_list : Error<
+  "initialization of non-aggregate type %0 with an initializer list">;
+def err_init_reference_member_uninitialized : Error<
+  "reference member of type %0 uninitialized">;
+def note_uninit_reference_member : Note<
+  "uninitialized reference member is here">;
+def warn_field_is_uninit : Warning<"field is uninitialized when used here">,
+  InGroup<DiagGroup<"uninitialized">>;
+
+def err_temp_copy_no_viable : Error<
+  "no viable constructor %select{copying variable|copying parameter|"
+  "returning object|throwing object|copying member subobject|copying array "
+  "element|allocating object|copying temporary|initializing base subobject|"
+  "initializing vector element}0 of type %1">;
+def err_temp_copy_ambiguous : Error<
+  "ambiguous constructor call when %select{copying variable|copying "
+  "parameter|returning object|throwing object|copying member subobject|copying "
+  "array element|allocating object|copying temporary|initializing base subobject|"
+  "initializing vector element}0 of type %1">;
+def err_temp_copy_deleted : Error<
+  "%select{copying variable|copying parameter|returning object|throwing "
+  "object|copying member subobject|copying array element|allocating object|"
+  "copying temporary|initializing base subobject|initializing vector element}0 "
+  "of type %1 invokes deleted constructor">;
+def err_temp_copy_incomplete : Error<
+  "copying a temporary object of incomplete type %0">;
+
+// C++0x decltype
+def err_cannot_determine_declared_type_of_overloaded_function : Error<
+    "cannot determine the %select{type|declared type}0 of an overloaded "
+    "function">;
+    
+// C++0x auto
+def err_auto_variable_cannot_appear_in_own_initializer : Error<
+  "variable %0 declared with 'auto' type cannot appear in its own initializer">;
+def err_illegal_decl_array_of_auto : Error<
+  "'%0' declared as array of 'auto'">;
+def err_auto_not_allowed : Error<
+  "'auto' not allowed in %select{function prototype|struct member|union member"
+  "|class member|exception declaration|template parameter|block literal}0">;
+def err_auto_var_requires_init : Error<
+  "declaration of variable %0 with type %1 requires an initializer">;
+  
+// C++0x attributes
+def err_repeat_attribute : Error<"'%0' attribute cannot be repeated">;
+
+// C++0x [[final]]
+def err_final_function_overridden : Error<
+  "declaration of %0 overrides a 'final' function">;
+def err_final_base : Error<
+  "derivation from 'final' %0">;
+  
+// Objective-C++
+def err_objc_decls_may_only_appear_in_global_scope : Error<
+  "Objective-C declarations may only appear in global scope">;
+def err_nsobject_attribute : Error<
+  "__attribute ((NSObject)) is for pointer types only">;
+
+// Attributes
+def err_attribute_can_be_applied_only_to_symbol_declaration : Error<
+  "%0 attribute can be applied only to symbol declaration">;
+def err_attributes_are_not_compatible : Error<
+  "%0 and %1 attributes are not compatible">;
+def err_attribute_wrong_number_arguments : Error<
+  "attribute requires %0 argument(s)">;
+def err_attribute_missing_parameter_name : Error<
+  "attribute requires unquoted parameter">;
+def err_attribute_invalid_vector_type : Error<"invalid vector type %0">;
+def err_attribute_argument_not_int : Error<
+  "'%0' attribute requires integer constant">;
+def err_attribute_argument_n_not_int : Error<
+  "'%0' attribute requires parameter %1 to be an integer constant">;
+def err_attribute_argument_n_not_string : Error<
+  "'%0' attribute requires parameter %1 to be a string">;
+def err_attribute_argument_out_of_bounds : Error<
+  "'%0' attribute parameter %1 is out of bounds">;
+def err_attribute_requires_objc_interface : Error<
+  "attribute may only be applied to an Objective-C interface">;
+def err_nonnull_pointers_only : Error<
+  "nonnull attribute only applies to pointer arguments">;
+def err_format_strftime_third_parameter : Error<
+  "strftime format attribute requires 3rd parameter to be 0">;
+def err_format_attribute_requires_variadic : Error<
+  "format attribute requires variadic function">;
+def err_format_attribute_not : Error<"format argument not %0">;
+def err_format_attribute_result_not : Error<"function does not return %0">;
+def err_attribute_invalid_size : Error<
+  "vector size not an integral multiple of component size">;
+def err_attribute_zero_size : Error<"zero vector size">;
+def err_typecheck_vector_not_convertable : Error<
+  "can't convert between vector values of different size (%0 and %1)">;
+def err_typecheck_ext_vector_not_typedef : Error<
+  "ext_vector_type only applies to types, not variables">;
+def err_unsupported_vector_size : Error<
+  "unsupported type %0 for vector_size attribute, please use on typedef">;
+def err_ext_vector_component_exceeds_length : Error<
+  "vector component access exceeds type %0">;
+def err_ext_vector_component_name_illegal : Error<
+  "illegal vector component name '%0'">;
+def err_attribute_address_space_not_int : Error<
+  "address space attribute requires an integer constant">;
+def err_attribute_address_space_negative : Error<
+  "address space is negative">;
+def err_attribute_address_space_too_high : Error<
+  "address space is larger than the maximum supported (%0)">;
+def err_attribute_address_multiple_qualifiers : Error<
+  "multiple address spaces specified for type">;
+def err_implicit_pointer_address_space_cast : Error<
+  "illegal implicit cast between two pointers with different address spaces">;
+def err_as_qualified_auto_decl : Error<
+  "automatic variable qualified with an address space">;
+def err_arg_with_address_space : Error<
+  "parameter may not be qualified with an address space">;
+def err_attribute_not_string : Error<
+  "argument to %0 attribute was not a string literal">;
+def err_attribute_section_invalid_for_target : Error<
+  "argument to 'section' attribute is not valid for this target: %0">;
+def err_attribute_section_local_variable : Error<
+  "'section' attribute is not valid on local variables">;
+def err_attribute_aligned_not_power_of_two : Error<
+  "requested alignment is not a power of 2">;
+def warn_redeclaration_without_attribute_prev_attribute_ignored : Warning<
+  "'%0' redeclared without %1 attribute: previous %1 ignored">;
+def warn_attribute_ignored : Warning<"%0 attribute ignored">;
+def warn_attribute_precede_definition : Warning<
+  "attribute declaration must precede definition">;
+def warn_attribute_void_function_method : Warning<
+  "attribute %0 cannot be applied to "
+  "%select{functions|Objective-C method}1 without return value">;
+def warn_attribute_weak_on_field : Warning<
+  "__weak attribute cannot be specified on a field declaration">;
+def warn_attribute_weak_on_local : Warning<
+  "__weak attribute cannot be specified on an automatic variable">;
+def warn_weak_identifier_undeclared : Warning<
+  "weak identifier %0 never declared">;
+def err_attribute_weak_static : Error<
+  "weak declaration of '%0' must be public">;
+def warn_attribute_weak_import_invalid_on_definition : Warning<
+  "'weak_import' attribute cannot be specified on a definition">;
+def err_attribute_weakref_not_static : Error<
+  "weakref declaration of '%0' must be static">;
+def err_attribute_weakref_not_global_context : Error<
+  "weakref declaration of '%0' must be in a global context">;
+def err_attribute_weakref_without_alias : Error<
+  "weakref declaration of '%0' must also have an alias attribute">;
+def warn_attribute_wrong_decl_type : Warning<
+  "%0 attribute only applies to %select{function|union|"
+  "variable and function|function or method|parameter|"
+  "parameter or Objective-C method |function, method or block|"
+  "virtual method or class|function, method, or parameter|class|virtual method"
+  "|member}1 types">;
+def err_attribute_wrong_decl_type : Error<
+  "%0 attribute only applies to %select{function|union|"
+  "variable and function|function or method|parameter|"
+  "parameter or Objective-C method |function, method or block|"
+  "virtual method or class|function, method, or parameter|class|virtual method"
+  "|member}1 types">;
+def warn_function_attribute_wrong_type : Warning<
+  "%0 only applies to function types; type here is %1">;
+def warn_gnu_inline_attribute_requires_inline : Warning<
+  "'gnu_inline' attribute requires function to be marked 'inline',"
+  " attribute ignored">;
+def err_cconv_change : Error<
+  "function declared '%0' here was previously declared "
+  "%select{'%2'|without calling convention}1">;
+def err_cconv_knr : Error<
+  "function with no prototype cannot use %0 calling convention">;
+def err_cconv_varargs : Error<
+  "variadic function cannot use %0 calling convention">;
+
+def warn_impcast_vector_scalar : Warning<
+  "implicit cast turns vector to scalar: %0 to %1">,
+  InGroup<DiagGroup<"conversion">>, DefaultIgnore;
+def warn_impcast_complex_scalar : Warning<
+  "implicit cast discards imaginary component: %0 to %1">,
+  InGroup<DiagGroup<"conversion">>, DefaultIgnore;
+def warn_impcast_float_precision : Warning<
+  "implicit cast loses floating-point precision: %0 to %1">,
+  InGroup<DiagGroup<"conversion">>, DefaultIgnore;
+def warn_impcast_float_integer : Warning<
+  "implicit cast turns floating-point number into integer: %0 to %1">,
+  InGroup<DiagGroup<"conversion">>, DefaultIgnore;
+def warn_impcast_integer_precision : Warning<
+  "implicit cast loses integer precision: %0 to %1">,
+  InGroup<DiagGroup<"conversion">>, DefaultIgnore;
+def warn_impcast_integer_64_32 : Warning<
+  "implicit cast loses integer precision: %0 to %1">,
+  InGroup<DiagGroup<"shorten-64-to-32">>, DefaultIgnore;
+
+def warn_attribute_ignored_for_field_of_type : Warning<
+  "%0 attribute ignored for field of type %1">;
+def warn_transparent_union_attribute_field_size_align : Warning<
+  "%select{alignment|size}0 of field %1 (%2 bits) does not match the "
+  "%select{alignment|size}0 of the first field in transparent union; "
+  "transparent_union attribute ignored">;
+def note_transparent_union_first_field_size_align : Note<
+  "%select{alignment|size}0 of first field is %1 bits">;
+def warn_transparent_union_attribute_not_definition : Warning<
+  "transparent_union attribute can only be applied to a union definition; "
+  "attribute ignored">;
+def warn_transparent_union_attribute_floating : Warning<
+  "first field of a transparent union cannot have floating point or vector "
+  "type; transparent_union attribute ignored">;
+def warn_transparent_union_attribute_zero_fields : Warning<
+  "transparent union definition must contain at least one field; "
+  "transparent_union attribute ignored">;
+def warn_attribute_type_not_supported : Warning<
+  "'%0' attribute argument not supported: %1">;
+def warn_attribute_unknown_visibility : Warning<"unknown visibility '%1'">;
+def err_unknown_machine_mode : Error<"unknown machine mode %0">;
+def err_unsupported_machine_mode : Error<"unsupported machine mode %0">;
+def err_mode_not_primitive : Error<
+  "mode attribute only supported for integer and floating-point types">;
+def err_mode_wrong_type : Error<
+  "type of machine mode does not match type of base type">;
+def err_attr_wrong_decl : Error<
+  "'%0' attribute invalid on this declaration, requires typedef or value">;
+def warn_attribute_nonnull_no_pointers : Warning<
+  "'nonnull' attribute applied to function with no pointer arguments">;
+def warn_attribute_malloc_pointer_only : Warning<
+  "'malloc' attribute only applies to functions returning a pointer type">;
+def warn_transparent_union_nonpointer : Warning<
+  "'transparent_union' attribute support incomplete; only supported for "
+  "pointer unions">;
+
+def warn_attribute_sentinel_named_arguments : Warning<
+  "'sentinel' attribute requires named arguments">;
+def warn_attribute_sentinel_not_variadic : Warning<
+  "'sentinel' attribute only supported for variadic %select{functions|blocks}0">;
+def err_attribute_sentinel_less_than_zero : Error<
+  "'sentinel' parameter 1 less than zero">;
+def err_attribute_sentinel_not_zero_or_one : Error<
+  "'sentinel' parameter 2 not 0 or 1">;
+def err_attribute_cleanup_arg_not_found : Error<
+  "'cleanup' argument %0 not found">;
+def err_attribute_cleanup_arg_not_function : Error<
+  "'cleanup' argument %0 is not a function">;
+def err_attribute_cleanup_func_must_take_one_arg : Error<
+  "'cleanup' function %0 must take 1 parameter">;
+def err_attribute_cleanup_func_arg_incompatible_type : Error<
+  "'cleanup' function %0 parameter has type %1 which is incompatible with "
+  "type %2">;
+def err_attribute_regparm_wrong_platform : Error<
+  "'regparm' is not valid on this platform">;
+def err_attribute_regparm_invalid_number : Error<
+  "'regparm' parameter must be between 0 and %0 inclusive">;
+
+
+// Clang-Specific Attributes
+def err_attribute_iboutlet : Error<
+  "iboutlet attribute can only be applied to instance variables or "
+  "properties">;
+def err_attribute_ibaction: Error<
+  "ibaction attribute can only be applied to Objective-C instance methods">;
+def err_attribute_overloadable_not_function : Error<
+  "'overloadable' attribute can only be applied to a function">;
+def err_attribute_overloadable_missing : Error<
+  "%select{overloaded function|redeclaration of}0 %1 must have the "
+  "'overloadable' attribute">;
+def note_attribute_overloadable_prev_overload : Note<
+  "previous overload of function is here">;
+def err_attribute_overloadable_no_prototype : Error<
+  "'overloadable' function %0 must have a prototype">;
+def warn_ns_attribute_wrong_return_type : Warning<
+    "%0 attribute only applies to functions or methods that "
+    "return a pointer or Objective-C object">;
+
+// Function Parameter Semantic Analysis.
+def err_param_with_void_type : Error<"argument may not have 'void' type">;
+def err_void_only_param : Error<
+  "'void' must be the first and only parameter if specified">;
+def err_void_param_qualified : Error<
+  "'void' as parameter must not have type qualifiers">;
+def err_ident_list_in_fn_declaration : Error<
+  "a parameter list without types is only allowed in a function definition">;
+def ext_param_not_declared : Extension<
+  "parameter %0 was not declared, defaulting to type 'int'">;
+def err_param_typedef_of_void : Error<
+  "empty parameter list defined with a typedef of 'void' not allowed in C++">;
+def err_param_default_argument : Error<
+  "C does not support default arguments">;
+def err_param_default_argument_redefinition : Error<
+  "redefinition of default argument">;
+def err_param_default_argument_missing : Error<
+  "missing default argument on parameter">;
+def err_param_default_argument_missing_name : Error<
+  "missing default argument on parameter %0">;
+def err_param_default_argument_references_param : Error<
+  "default argument references parameter %0">;
+def err_param_default_argument_references_local : Error<
+  "default argument references local variable %0 of enclosing function">;
+def err_param_default_argument_references_this : Error<
+  "default argument references 'this'">;
+def err_param_default_argument_nonfunc : Error<
+  "default arguments can only be specified for parameters in a function "
+  "declaration">;
+def err_param_default_argument_template_redecl : Error<
+  "default arguments cannot be added to a function template that has already "
+  "been declared">;
+def err_param_default_argument_member_template_redecl : Error<
+  "default arguments cannot be added to an out-of-line definition of a member "
+  "of a %select{class template|class template partial specialization|nested "
+  "class in a template}0">;
+def err_uninitialized_member_for_assign : Error<
+  "cannot define the implicit default assignment operator for %0, because "
+  "non-static %select{reference|const}1 member %2 can't use default "
+  "assignment operator">;
+def note_first_required_here : Note<
+  "synthesized method is first required here">;
+def err_uninitialized_member_in_ctor : Error<
+  "%select{|implicit default }0constructor for %1 must explicitly initialize "
+  "the %select{reference|const}2 member %3">;
+
+def err_use_of_default_argument_to_function_declared_later : Error<
+  "use of default argument to function %0 that is declared later in class %1">;
+def note_default_argument_declared_here : Note<
+  "default argument declared here">;
+
+def ext_param_promoted_not_compatible_with_prototype : ExtWarn<
+  "promoted type %0 of K&R function parameter is not compatible with the "
+  "parameter type %1 declared in a previous prototype">;
+
+
+// C++ Overloading Semantic Analysis.
+def err_ovl_diff_return_type : Error<
+  "functions that differ only in their return type cannot be overloaded">;
+def err_ovl_static_nonstatic_member : Error<
+  "static and non-static member functions with the same parameter types "
+  "cannot be overloaded">;
+
+def err_ovl_no_viable_function_in_call : Error<
+  "no matching function for call to %0">;
+def err_ovl_no_viable_member_function_in_call : Error<
+  "no matching member function for call to %0">;
+def err_ovl_ambiguous_call : Error<
+  "call to %0 is ambiguous">;
+def err_ovl_deleted_call : Error<
+  "call to %select{unavailable|deleted}0 function %1">;
+def err_ovl_ambiguous_member_call : Error<
+  "call to member function %0 is ambiguous">;
+def err_ovl_deleted_member_call : Error<
+  "call to %select{unavailable|deleted}0 member function %1">;
+def note_ovl_candidate : Note<"candidate "
+    "%select{function|function|constructor|"
+    "function |function |constructor |"
+    "is the implicit default constructor|"
+    "is the implicit copy constructor|"
+    "is the implicit copy assignment operator}0%1">;
+
+def note_ovl_candidate_bad_deduction : Note<
+    "candidate template ignored: failed template argument deduction">;
+def note_ovl_candidate_incomplete_deduction : Note<"candidate template ignored: "
+    "couldn't infer template argument %0">;
+
+// Note that we don't treat templates differently for this diagnostic.
+def note_ovl_candidate_arity : Note<"candidate "
+    "%select{function|function|constructor|function|function|constructor|"
+    "constructor (the implicit default constructor)|"
+    "constructor (the implicit copy constructor)|"
+    "function (the implicit copy assignment operator)}0 not viable: requires"
+    "%select{ at least| at most|}2 %3 argument%s3, but %4 %plural{1:was|:were}4 "
+    "provided">;
+
+def note_ovl_candidate_deleted : Note<
+  "candidate %select{function|function|constructor|"
+  "function |function |constructor |||}0%1 "
+  "has been explicitly %select{made unavailable|deleted}2">;
+
+// Giving the index of the bad argument really clutters this message, and
+// it's relatively unimportant because 1) it's generally obvious which
+// argument(s) are of the given object type and 2) the fix is usually
+// to complete the type, which doesn't involve changes to the call line
+// anyway.  If people complain, we can change it.
+def note_ovl_candidate_bad_conv_incomplete : Note<"candidate "
+    "%select{function|function|constructor|"
+    "function |function |constructor |"
+    "constructor (the implicit default constructor)|"
+    "constructor (the implicit copy constructor)|"
+    "function (the implicit copy assignment operator)}0%1 "
+    "not viable: cannot convert argument of incomplete type %2 to %3">;
+def note_ovl_candidate_bad_overload : Note<"candidate "
+    "%select{function|function|constructor|"
+    "function |function |constructor |"
+    "constructor (the implicit default constructor)|"
+    "constructor (the implicit copy constructor)|"
+    "function (the implicit copy assignment operator)}0%1"
+    " not viable: no overload of %3 matching %2 for %ordinal4 argument">;
+def note_ovl_candidate_bad_conv : Note<"candidate "
+    "%select{function|function|constructor|"
+    "function |function |constructor |"
+    "constructor (the implicit default constructor)|"
+    "constructor (the implicit copy constructor)|"
+    "function (the implicit copy assignment operator)}0%1"
+    " not viable: no known conversion from %2 to %3 for "
+    "%select{%ordinal5 argument|object argument}4">;
+def note_ovl_candidate_bad_addrspace : Note<"candidate "
+    "%select{function|function|constructor|"
+    "function |function |constructor |"
+    "constructor (the implicit default constructor)|"
+    "constructor (the implicit copy constructor)|"
+    "function (the implicit copy assignment operator)}0%1 not viable: "
+    "%select{%ordinal6|'this'}5 argument (%2) is in "
+    "address space %3, but parameter must be in address space %4">;
+def note_ovl_candidate_bad_cvr_this : Note<"candidate "
+    "%select{|function|||function||||"
+    "function (the implicit copy assignment operator)}0 not viable: "
+    "'this' argument has type %2, but method is not marked "
+    "%select{const|volatile|const or volatile|restrict|const or restrict|"
+    "volatile or restrict|const, volatile, or restrict}3">;
+def note_ovl_candidate_bad_cvr : Note<"candidate "
+    "%select{function|function|constructor|"
+    "function |function |constructor |"
+    "constructor (the implicit default constructor)|"
+    "constructor (the implicit copy constructor)|"
+    "function (the implicit copy assignment operator)}0%1 not viable: "
+    "%ordinal4 argument (%2) would lose "
+    "%select{const|volatile|const and volatile|restrict|const and restrict|"
+    "volatile and restrict|const, volatile, and restrict}3 qualifier"
+    "%select{||s||s|s|s}3">;
+def note_ambiguous_type_conversion: Note<
+    "because of ambiguity in conversion of %0 to %1">;
+def note_ovl_builtin_binary_candidate : Note<
+    "built-in candidate %0">;
+def note_ovl_builtin_unary_candidate : Note<
+    "built-in candidate %0">;
+def err_ovl_no_viable_function_in_init : Error<
+  "no matching constructor for initialization of %0">;
+def err_ovl_ambiguous_init : Error<"call to constructor of %0 is ambiguous">;
+def err_ref_init_ambiguous : Error<
+  "reference initialization of type %0 with initializer of type %1 is ambiguous">;
+def err_ovl_deleted_init : Error<
+  "call to %select{unavailable|deleted}0 constructor of %1">;
+def err_ovl_ambiguous_oper : Error<
+  "use of overloaded operator '%0' is ambiguous">;
+def err_ovl_no_viable_oper : Error<"no viable overloaded '%0'">;
+def err_ovl_deleted_oper : Error<
+  "overload resolution selected %select{unavailable|deleted}0 operator '%1'">;
+def err_ovl_no_viable_subscript :
+    Error<"no viable overloaded operator[] for type %0">;
+def err_ovl_no_oper :
+    Error<"type %0 does not provide a %select{subscript|call}1 operator">;
+
+def err_ovl_no_viable_object_call : Error<
+  "no matching function for call to object of type %0">;
+def err_ovl_ambiguous_object_call : Error<
+  "call to object of type %0 is ambiguous">;
+def err_ovl_deleted_object_call : Error<
+  "call to %select{unavailable|deleted}0 function call operator in type %1">;
+def note_ovl_surrogate_cand : Note<"conversion candidate of type %0">;
+def err_member_call_without_object : Error<
+  "call to non-static member function without an object argument">;
+
+// C++ Address of Overloaded Function
+def err_addr_ovl_no_viable : Error<
+  "address of overloaded function %0 does not match required type %1">;
+def err_addr_ovl_ambiguous : Error<
+  "address of overloaded function %0 is ambiguous">;
+def err_addr_ovl_not_func_ptrref : Error<
+  "address of overloaded function %0 cannot be converted to type %1">;
+  
+// C++ Template Declarations
+def err_template_param_shadow : Error<
+  "declaration of %0 shadows template parameter">;
+def note_template_param_here : Note<"template parameter is declared here">;
+def warn_template_export_unsupported : Warning<
+  "exported templates are unsupported">;
+def err_template_outside_namespace_or_class_scope : Error<
+  "templates can only be declared in namespace or class scope">;
+def err_template_linkage : Error<"templates must have C++ linkage">;
+def err_template_typedef : Error<"a typedef cannot be a template">;
+def err_template_unnamed_class : Error<
+  "cannot declare a class template with no name">;
+def err_template_param_list_different_arity : Error<
+  "%select{too few|too many}0 template parameters in template "
+  "%select{|template parameter }1redeclaration">;
+def note_template_param_list_different_arity : Note<
+  "%select{too few|too many}0 template parameters in template template "
+  "argument">;
+def note_template_prev_declaration : Note<
+  "previous template %select{declaration|template parameter}0 is here">;
+def err_template_param_different_kind : Error<
+  "template parameter has a different kind in template "
+  "%select{|template parameter }0redeclaration">;
+def note_template_param_different_kind : Note<
+  "template parameter has a different kind in template argument">;
+def err_template_nontype_parm_different_type : Error<
+  "template non-type parameter has a different type %0 in template "
+  "%select{|template parameter }1redeclaration">;
+
+def note_template_nontype_parm_different_type : Note<
+  "template non-type parameter has a different type %0 in template argument">;
+def note_template_nontype_parm_prev_declaration : Note<
+  "previous non-type template parameter with type %0 is here">;
+def err_template_nontype_parm_bad_type : Error<
+  "a non-type template parameter cannot have type %0">;
+def err_template_param_default_arg_redefinition : Error<
+  "template parameter redefines default argument">;
+def note_template_param_prev_default_arg : Note<
+  "previous default template argument defined here">;
+def err_template_param_default_arg_missing : Error<
+  "template parameter missing a default argument">;
+def err_template_parameter_default_in_function_template : Error<
+  "a template parameter of a function template cannot have a default argument "
+  "in C++98">;
+def err_template_parameter_default_template_member : Error<
+  "cannot add a default template argument to the definition of a member of a "
+  "class template">;
+def err_template_parameter_default_friend_template : Error<
+  "default template argument not permitted on a friend template">;
+
+def err_template_variable : Error<"variable %0 declared as a template">;
+def err_template_variable_noparams : Error<
+  "extraneous 'template<>' in declaration of variable %0">;
+def err_template_tag_noparams : Error<
+  "extraneous 'template<>' in declaration of %0 %1">;
+def err_template_decl_ref : Error<
+  "cannot refer to class template %0 without a template argument list">;
+
+// C++ Template Argument Lists
+def err_template_missing_args : Error<
+  "use of class template %0 requires template arguments">;
+def err_template_arg_list_different_arity : Error<
+  "%select{too few|too many}0 template arguments for "
+  "%select{class template|function template|template template parameter"
+  "|template}1 %2">;
+def note_template_decl_here : Note<"template is declared here">;
+def note_member_of_template_here : Note<"member is declared here">;
+def err_template_arg_must_be_type : Error<
+  "template argument for template type parameter must be a type">;
+def err_template_arg_must_be_expr : Error<
+  "template argument for non-type template parameter must be an expression">;
+def err_template_arg_nontype_ambig : Error<
+  "template argument for non-type template parameter is treated as type %0">;
+def err_template_arg_must_be_template : Error<
+  "template argument for template template parameter must be a class template">;
+def err_template_arg_local_type : Error<"template argument uses local type %0">;
+def err_template_arg_unnamed_type : Error<
+  "template argument uses unnamed type">;
+def note_template_unnamed_type_here : Note<
+  "unnamed type used in template argument was declared here">;
+def err_template_arg_overload_type : Error<
+  "template argument is the type of an unresolved overloaded function">;
+def err_template_arg_not_class_template : Error<
+  "template argument does not refer to a class template or template "
+  "template parameter">;
+def note_template_arg_refers_here_func : Note<
+  "template argument refers to function template %0, here">;
+def err_template_arg_template_params_mismatch : Error<
+  "template template argument has different template parameters than its "
+  "corresponding template template parameter">;
+def err_template_arg_not_integral_or_enumeral : Error<
+  "non-type template argument of type %0 must have an integral or enumeration"
+  " type">;
+def err_template_arg_not_ice : Error<
+  "non-type template argument of type %0 is not an integral constant "
+  "expression">;
+def err_deduced_non_type_template_arg_type_mismatch : Error<
+  "deduced non-type template argument does not have the same type as the "
+  "its corresponding template parameter (%0 vs %1)">;
+def err_template_arg_not_convertible : Error<
+  "non-type template argument of type %0 cannot be converted to a value "
+  "of type %1">;
+def warn_template_arg_negative : Warning<
+  "non-type template argument with value '%0' converted to '%1' for unsigned "
+  "template parameter of type %2">;
+def warn_template_arg_too_large : Warning<
+  "non-type template argument value '%0' truncated to '%1' for "
+  "template parameter of type %2">;
+def err_template_arg_no_ref_bind : Error<
+  "non-type template parameter of reference type %0 cannot bind to template "
+  "argument of type %1">;
+def err_template_arg_ref_bind_ignores_quals : Error<
+  "reference binding of non-type template parameter of type %0 to template "
+  "argument of type %1 ignores qualifiers">;
+def err_template_arg_not_decl_ref : Error<
+  "non-type template argument does not refer to any declaration">;
+def err_template_arg_not_object_or_func_form : Error<
+  "non-type template argument does not directly refer to an object or "
+  "function">;
+def err_template_arg_not_address_of : Error<
+  "non-type template argument for template parameter of pointer type %0 must "
+  "have its address taken">;
+def err_template_arg_address_of_non_pointer : Error<
+  "address taken in non-type template argument for template parameter of "
+  "reference type %0">;
+def err_template_arg_reference_var : Error<
+  "non-type template argument of reference type %0 is not an object">;
+def err_template_arg_field : Error<
+  "non-type template argument refers to non-static data member %0">;
+def err_template_arg_method : Error<
+  "non-type template argument refers to non-static member function %0">;
+def err_template_arg_function_not_extern : Error<
+  "non-template argument refers to function %0 with internal linkage">;
+def err_template_arg_object_not_extern : Error<
+  "non-template argument refers to object %0 that does not have external "
+  "linkage">;
+def note_template_arg_internal_object : Note<
+  "non-template argument refers to %select{function|object}0 here">;
+def note_template_arg_refers_here : Note<"non-template argument refers here">;
+def err_template_arg_not_object_or_func : Error<
+  "non-type template argument does not refer to an object or function">;
+def err_template_arg_not_pointer_to_member_form : Error<
+  "non-type template argument is not a pointer to member constant">;
+def err_template_arg_extra_parens : Error<
+  "non-type template argument cannot be surrounded by parentheses">;
+def err_pointer_to_member_type : Error<
+  "invalid use of pointer to member type after %select{.*|->*}0">;
+
+// C++ template specialization
+def err_template_spec_unknown_kind : Error<
+  "can only provide an explicit specialization for a class template, function "
+  "template, or a member function, static data member, or member class of a "
+  "class template">;
+def note_specialized_entity : Note<
+  "explicitly specialized declaration is here">;
+def err_template_spec_decl_function_scope : Error<
+  "explicit specialization of %0 in function scope">;
+def err_template_spec_decl_class_scope : Error<
+  "explicit specialization of %0 in class scope">;
+def err_template_spec_decl_friend : Error<
+  "cannot declare an explicit specialization in a friend">;
+def err_template_spec_decl_out_of_scope_global : Error<
+  "%select{class template|class template partial|function template|member "
+  "function|static data member|member class}0 specialization of %1 must "
+  "originally be declared in the global scope">;
+def err_template_spec_decl_out_of_scope : Error<
+  "%select{class template|class template partial|function template|member "
+  "function|static data member|member class}0 specialization of %1 must "
+  "originally be declared in namespace %2">;
+def err_template_spec_redecl_out_of_scope : Error<
+  "%select{class template|class template partial|function template|member "
+  "function|static data member|member class}0 specialization of %1 not in a "
+  "namespace enclosing %2">;
+def err_template_spec_redecl_global_scope : Error<
+  "%select{class template|class template partial|function template|member "
+  "function|static data member|member class}0 specialization of %1 must occur "
+  "at global scope">;
+def err_spec_member_not_instantiated : Error<
+  "specialization of member %q0 does not specialize an instantiated member">;
+def note_specialized_decl : Note<"attempt to specialize declaration here">;
+def err_specialization_after_instantiation : Error<
+  "explicit specialization of %0 after instantiation">;
+def note_instantiation_required_here : Note<
+  "%select{implicit|explicit}0 instantiation first required here">;
+def err_template_spec_friend : Error<
+  "template specialization declaration cannot be a friend">;
+def err_template_spec_default_arg : Error<
+  "default argument not permitted on an explicit "
+  "%select{instantiation|specialization}0 of function %1">;
+def err_not_class_template_specialization : Error<
+  "cannot specialize a %select{dependent template|template template "
+  "parameter}0">;
+
+// C++ class template specializations and out-of-line definitions
+def err_template_spec_needs_header : Error<
+  "template specialization requires 'template<>'">;
+def err_template_spec_needs_template_parameters : Error<
+  "template specialization or definition requires a template parameter list "
+  "corresponding to the nested type %0">;
+def err_template_param_list_matches_nontemplate : Error<
+  "template parameter list matching the non-templated nested type %0 should "
+  "be empty ('template<>')">;
+def err_template_spec_extra_headers : Error<
+  "extraneous template parameter list in template specialization or "
+  "out-of-line template definition">;
+def warn_template_spec_extra_headers : Warning<
+  "extraneous template parameter list in template specialization">;
+def note_explicit_template_spec_does_not_need_header : Note<
+  "'template<>' header not required for explicitly-specialized class %0 "
+  "declared here">;
+def err_template_qualified_declarator_no_match : Error<
+  "nested name specifier '%0' for declaration does not refer into a class, "
+  "class template or class template partial specialization">;
+
+// C++ Class Template Partial Specialization
+def err_default_arg_in_partial_spec : Error<
+    "default template argument in a class template partial specialization">;
+def err_dependent_non_type_arg_in_partial_spec : Error<
+    "non-type template argument depends on a template parameter of the "
+    "partial specialization">;
+def err_dependent_typed_non_type_arg_in_partial_spec : Error<
+    "non-type template argument specializes a template parameter with "
+    "dependent type %0">;
+def err_partial_spec_args_match_primary_template : Error<
+    "class template partial specialization does not specialize any template "
+    "argument; to %select{declare|define}0 the primary template, remove the "
+    "template argument list">; 
+def warn_partial_specs_not_deducible : Warning<
+    "class template partial specialization contains "
+    "%select{a template parameter|template parameters}0 that can not be "
+    "deduced; this partial specialization will never be used">;
+def note_partial_spec_unused_parameter : Note<
+    "non-deducible template parameter %0">;
+def err_partial_spec_ordering_ambiguous : Error<
+    "ambiguous partial specializations of %0">;
+def note_partial_spec_match : Note<"partial specialization matches %0">;
+def err_partial_spec_redeclared : Error<
+  "class template partial specialization %0 cannot be redeclared">;
+def note_prev_partial_spec_here : Note<
+  "previous declaration of class template partial specialization %0 is here">;
+def err_partial_spec_fully_specialized : Error<
+  "partial specialization of %0 does not use any of its template parameters">;
+  
+// C++ Function template specializations
+def err_function_template_spec_no_match : Error<
+    "no function template matches function template specialization %0">;
+def err_function_template_spec_ambiguous : Error<
+    "function template specialization %0 ambiguously refers to more than one "
+    "function template; explicitly specify%select{|additional }1 template "
+    "arguments to identify a particular function template">;
+def note_function_template_spec_matched : Note<
+    "function template matches specialization %0">;
+
+// C++ Template Instantiation
+def err_template_recursion_depth_exceeded : Error<
+  "recursive template instantiation exceeded maximum depth of %0">,
+  DefaultFatal, NoSFINAE;
+def note_template_recursion_depth : Note<
+  "use -ftemplate-depth-N to increase recursive template instantiation depth">;
+
+def err_template_instantiate_undefined : Error<
+  "%select{implicit|explicit}0 instantiation of undefined template %1">;
+def err_implicit_instantiate_member_undefined : Error<
+  "implicit instantiation of undefined member %0">;
+def note_template_class_instantiation_here : Note<
+  "in instantiation of template class %0 requested here">;
+def note_template_member_class_here : Note<
+  "in instantiation of member class %0 requested here">;
+def note_template_member_function_here : Note<
+  "in instantiation of member function %q0 requested here">;
+def note_function_template_spec_here : Note<
+  "in instantiation of function template specialization %q0 requested here">;
+def note_template_static_data_member_def_here : Note<
+  "in instantiation of static data member %q0 requested here">;
+  
+def note_default_arg_instantiation_here : Note<
+  "in instantiation of default argument for '%0' required here">;
+def note_default_function_arg_instantiation_here : Note<
+  "in instantiation of default function argument expression "
+  "for '%0' required here">;
+def note_explicit_template_arg_substitution_here : Note<
+  "while substituting explicitly-specified template arguments into function "
+  "template %0 %1">;
+def note_function_template_deduction_instantiation_here : Note<
+  "while substituting deduced template arguments into function template %0 "
+  "%1">;
+def note_partial_spec_deduct_instantiation_here : Note<
+  "during template argument deduction for class template partial "
+  "specialization %0 %1">;
+def note_prior_template_arg_substitution : Note<
+  "while substituting prior template arguments into %select{non-type|template}0"
+  " template parameter%1 %2">;
+def note_template_default_arg_checking : Note<
+  "while checking a default template argument used here">;
+def note_instantiation_contexts_suppressed : Note<
+  "(skipping %0 context%s0 in backtrace; use -ftemplate-backtrace-limit=0 to "
+  "see  all)">;
+
+def err_field_instantiates_to_function : Error<
+  "data member instantiated with function type %0">;
+def err_nested_name_spec_non_tag : Error<
+  "type %0 cannot be used prior to '::' because it has no members">;
+
+// C++ Explicit Instantiation
+def err_explicit_instantiation_duplicate : Error<
+    "duplicate explicit instantiation of %0">;
+def note_previous_explicit_instantiation : Note<
+    "previous explicit instantiation is here">;
+def ext_explicit_instantiation_after_specialization : Extension<
+    "explicit instantiation of %0 that occurs after an explicit "
+    "specialization will be ignored (C++0x extension)">;
+def note_previous_template_specialization : Note<
+    "previous template specialization is here">;
+def err_explicit_instantiation_enum : Error<
+    "explicit instantiation of enumeration type %0">;
+def err_explicit_instantiation_nontemplate_type : Error<
+    "explicit instantiation of non-templated type %0">;
+def note_nontemplate_decl_here : Note<
+    "non-templated declaration is here">;
+def err_explicit_instantiation_out_of_scope : Error<
+  "explicit instantiation of %0 not in a namespace enclosing %1">;
+def err_explicit_instantiation_must_be_global : Error<
+  "explicit instantiation of %0 must occur at global scope">;
+  
+def err_explicit_instantiation_requires_name : Error<
+  "explicit instantiation declaration requires a name">;
+def err_explicit_instantiation_of_typedef : Error<
+  "explicit instantiation of typedef %0">;
+def err_explicit_instantiation_not_known : Error<
+  "explicit instantiation of %0 does not refer to a function template, member "
+  "function, member class, or static data member">;
+def note_explicit_instantiation_here : Note<
+  "explicit instantiation refers here">;
+def err_explicit_instantiation_data_member_not_instantiated : Error<
+  "explicit instantiation refers to static data member %q0 that is not an "
+  "instantiation">;
+def err_explicit_instantiation_member_function_not_instantiated : Error<
+  "explicit instantiation refers to member function %q0 that is not an "
+  "instantiation">;
+def err_explicit_instantiation_ambiguous : Error<
+  "partial ordering for explicit instantiation of %0 is ambiguous">;
+def note_explicit_instantiation_candidate : Note<
+  "explicit instantiation candidate function template here %0">;
+def err_explicit_instantiation_inline : Error<
+  "explicit instantiation cannot be 'inline'">;
+def err_explicit_instantiation_without_qualified_id : Error<
+  "qualifier in explicit instantiation of %q0 requires a template-id">;
+def err_explicit_instantiation_without_qualified_id_quals : Error<
+  "qualifier in explicit instantiation of '%0%1' requires a template-id">;
+def err_explicit_instantiation_unqualified_wrong_namespace : Error<
+  "explicit instantiation of %q0 must occur in %1">;
+def err_explicit_instantiation_undefined_member : Error<
+  "explicit instantiation of undefined %select{member class|member function|"
+  "static data member}0 %1 of class template %2">;
+def err_explicit_instantiation_undefined_func_template : Error<
+  "explicit instantiation of undefined function template %0">;
+def err_explicit_instantiation_declaration_after_definition : Error<
+  "explicit instantiation declaration (with 'extern') follows explicit "
+  "instantiation definition (without 'extern')">;
+def note_explicit_instantiation_definition_here : Note<
+  "explicit instantiation definition is here">;
+  
+// C++ typename-specifiers
+def err_typename_nested_not_found : Error<"no type named %0 in %1">;
+def err_typename_nested_not_type : Error<
+    "typename specifier refers to non-type member %0 in %1">;
+def note_typename_refers_here : Note<
+    "referenced member %0 is declared here">;
+def err_typename_missing : Error<
+  "missing 'typename' prior to dependent type name '%0%1'">;
+
+def err_template_kw_refers_to_non_template : Error<
+    "%0 following the 'template' keyword does not refer to a template">;
+def err_template_kw_refers_to_function_template : Error<
+    "%0 following the 'template' keyword refers to a function template">;
+def err_template_kw_refers_to_class_template : Error<
+    "'%0%1' instantiated to a class template, not a function template">;
+def note_referenced_class_template : Error<
+    "class template declared here">;
+def err_template_kw_missing : Error<
+  "missing 'template' keyword prior to dependent template name '%0%1'">;
+
+// C++0x Variadic Templates
+def err_template_param_pack_default_arg : Error<
+  "template parameter pack cannot have a default argument">;
+def err_template_param_pack_must_be_last_template_parameter : Error<
+  "template parameter pack must be the last template parameter">;
+
+def err_unexpected_typedef : Error<
+  "unexpected type name %0: expected expression">;
+def err_unexpected_namespace : Error<
+  "unexpected namespace name %0: expected expression">;
+def err_undeclared_var_use : Error<"use of undeclared identifier %0">;
+def note_dependent_var_use : Note<"must qualify identifier to find this "
+    "declaration in dependent base class">;
+def err_undeclared_use : Error<"use of undeclared %0">;
+def warn_deprecated : Warning<"%0 is deprecated">,
+    InGroup<DiagGroup<"deprecated-declarations">>;
+def warn_unavailable : Warning<"%0 is unavailable">,
+    InGroup<DiagGroup<"unavailable-declarations">>;
+def note_unavailable_here : Note<
+  "function has been explicitly marked %select{unavailable|deleted}0 here">;
+def warn_not_enough_argument : Warning<
+  "not enough variable arguments in %0 declaration to fit a sentinel">;
+def warn_missing_sentinel : Warning <
+  "missing sentinel in %select{function call|method dispatch|block call}0">;
+def note_sentinel_here : Note<
+  "%select{function|method|block}0 has been explicitly marked sentinel here">;
+def warn_missing_prototype : Warning<
+  "no previous prototype for function %0">,
+  InGroup<DiagGroup<"missing-prototypes">>, DefaultIgnore;
+def err_redefinition : Error<"redefinition of %0">;
+def err_definition_of_implicitly_declared_member : Error<
+  "definition of implicitly declared %select{constructor|copy constructor|"
+  "copy assignment operator|destructor}1">;
+  
+def warn_redefinition_of_typedef : Warning<
+  "redefinition of typedef %0 is invalid in C">,
+  InGroup<DiagGroup<"typedef-redefinition"> >, DefaultError;
+
+def err_static_non_static : Error<
+  "static declaration of %0 follows non-static declaration">;
+def err_non_static_static : Error<
+  "non-static declaration of %0 follows static declaration">;
+def err_non_thread_thread : Error<
+  "non-thread-local declaration of %0 follows thread-local declaration">;
+def err_thread_non_thread : Error<
+  "thread-local declaration of %0 follows non-thread-local declaration">;
+def err_redefinition_different_type : Error<
+  "redefinition of %0 with a different type">;
+def err_redefinition_different_kind : Error<
+  "redefinition of %0 as different kind of symbol">;
+def err_redefinition_different_typedef : Error<
+  "typedef redefinition with different types (%0 vs %1)">;
+def err_tag_reference_non_tag : Error<
+  "elaborated type refers to %select{a non-tag type|a typedef|a template}0">;
+def err_tag_reference_conflict : Error<
+  "implicit declaration introduced by elaborated type conflicts with "
+  "%select{a declaration|a typedef|a template}0 of the same name">;
+def err_dependent_tag_decl : Error<
+  "%select{declaration|definition}0 of %select{struct|union|class|enum}1 "
+  "in a dependent scope">;
+def err_tag_definition_of_typedef : Error<
+  "definition of type %0 conflicts with typedef of the same name">;
+def err_conflicting_types : Error<"conflicting types for %0">;
+def err_nested_redefinition : Error<"nested redefinition of %0">;
+def err_use_with_wrong_tag : Error<
+  "use of %0 with tag type that does not match previous declaration">;
+def warn_struct_class_tag_mismatch : Warning<
+    "%select{struct|class}0 %select{|template}1 %2 was previously declared "
+    "as a %select{class|struct}0 %select{|template}1">,
+    InGroup<MismatchedTags>, DefaultIgnore;
+def ext_forward_ref_enum : Extension<
+  "ISO C forbids forward references to 'enum' types">;
+def err_forward_ref_enum : Error<
+  "ISO C++ forbids forward references to 'enum' types">;
+def err_redefinition_of_enumerator : Error<"redefinition of enumerator %0">;
+def err_duplicate_member : Error<"duplicate member %0">;
+def err_misplaced_ivar : Error<
+  "ivars may not be placed in %select{categories|class extension}0">;
+def ext_enum_value_not_int : Extension<
+  "ISO C restricts enumerator values to range of 'int' (%0 is too "
+  "%select{small|large}1)">;
+def warn_enum_too_large : Warning<
+  "enumeration values exceed range of largest integer">;
+def warn_enumerator_too_large : Warning<
+  "enumerator value %0 is not representable in the largest integer type">;
+  
+def warn_illegal_constant_array_size : Extension<
+  "size of static array must be an integer constant expression">;
+def err_vla_decl_in_file_scope : Error<
+  "variable length array declaration not allowed at file scope">;
+def err_vla_decl_has_static_storage : Error<
+  "variable length array declaration can not have 'static' storage duration">;
+def err_vla_decl_has_extern_linkage : Error<
+  "variable length array declaration can not have 'extern' linkage">;
+def err_vm_decl_in_file_scope : Error<
+  "variably modified type declaration not allowed at file scope">;
+def err_vm_decl_has_extern_linkage : Error<
+  "variably modified type declaration can not have 'extern' linkage">;
+def err_typecheck_field_variable_size : Error<
+  "fields must have a constant size: 'variable length array in structure' "
+  "extension will never be supported">;
+def err_vm_func_decl : Error<
+  "function declaration cannot have variably modified type">;
+
+def err_typecheck_negative_array_size : Error<"array size is negative">;
+def warn_typecheck_function_qualifiers : Warning<
+  "qualifier on function type %0 has unspecified behavior">;
+def err_typecheck_invalid_restrict_not_pointer : Error<
+  "restrict requires a pointer or reference (%0 is invalid)">;
+def err_typecheck_invalid_restrict_not_pointer_noarg : Error<
+  "restrict requires a pointer or reference">;
+def err_typecheck_invalid_restrict_invalid_pointee : Error<
+  "pointer to function type %0 may not be 'restrict' qualified">;
+def ext_typecheck_zero_array_size : Extension<
+  "zero size arrays are an extension">;
+def err_typecheck_zero_array_size : Error<
+  "zero-length arrays are not permitted in C++">;
+def err_at_least_one_initializer_needed_to_size_array : Error<
+  "at least one initializer value required to size array">;
+def err_array_size_non_int : Error<"size of array has non-integer type %0">;
+def err_init_element_not_constant : Error<
+  "initializer element is not a compile-time constant">;
+def err_block_extern_cant_init : Error<
+  "'extern' variable cannot have an initializer">;
+def warn_extern_init : Warning<"'extern' variable has an initializer">;
+def err_variable_object_no_init : Error<
+  "variable-sized object may not be initialized">;
+def err_array_init_list_required : Error<
+  "initialization with '{...}' expected for array">;
+def err_excess_initializers : Error<
+  "excess elements in %select{array|vector|scalar|union|struct}0 initializer">;
+def warn_excess_initializers : ExtWarn<
+  "excess elements in %select{array|vector|scalar|union|struct}0 initializer">;
+def err_excess_initializers_in_char_array_initializer : Error<
+  "excess elements in char array initializer">;
+def warn_excess_initializers_in_char_array_initializer : ExtWarn<
+  "excess elements in char array initializer">;
+def warn_initializer_string_for_char_array_too_long : ExtWarn<
+  "initializer-string for char array is too long">;
+def warn_missing_field_initializers : Warning<
+  "missing field '%0' initializer">,
+  InGroup<MissingFieldInitializers>, DefaultIgnore;
+def warn_braces_around_scalar_init : Warning<
+  "braces around scalar initializer">;
+def err_many_braces_around_scalar_init : Error<
+  "too many braces around scalar initializer">;
+def err_empty_scalar_initializer : Error<"scalar initializer cannot be empty">;
+def err_illegal_initializer : Error<
+  "illegal initializer (only variables can be initialized)">;
+def err_illegal_initializer_type : Error<"illegal initializer type %0">;
+def err_implicit_empty_initializer : Error<
+  "initializer for aggregate with no elements requires explicit braces">;
+def err_bitfield_has_negative_width : Error<
+  "bit-field %0 has negative width (%1)">;
+def err_anon_bitfield_has_negative_width : Error<
+  "anonymous bit-field has negative width (%0)">;
+def err_bitfield_has_zero_width : Error<"named bit-field %0 has zero width">;
+def err_bitfield_width_exceeds_type_size : Error<
+  "size of bit-field %0 (%1 bits) exceeds size of its type (%2 bits)">;
+def err_anon_bitfield_width_exceeds_type_size : Error<
+  "size of anonymous bit-field (%0 bits) exceeds size of its type (%1 bits)">;
+  
+// Used by C++ which allows bit-fields that are wider than the type.
+def warn_bitfield_width_exceeds_type_size: Warning<
+  "size of bit-field %0 (%1 bits) exceeds the size of its type; value will be "
+  "truncated to %2 bits">;
+def warn_anon_bitfield_width_exceeds_type_size : Warning<
+  "size of anonymous bit-field (%0 bits) exceeds size of its type; value will "
+  "be truncated to %1 bits">;
+
+def warn_missing_braces : Warning<
+  "suggest braces around initialization of subobject">,
+  InGroup<DiagGroup<"missing-braces">>, DefaultIgnore;
+
+def err_redefinition_of_label : Error<"redefinition of label '%0'">;
+def err_undeclared_label_use : Error<"use of undeclared label '%0'">;
+
+def err_goto_into_protected_scope : Error<"illegal goto into protected scope">;
+def err_switch_into_protected_scope : Error<
+  "illegal switch case into protected scope">;
+def err_indirect_goto_in_protected_scope : Warning<
+  "illegal indirect goto in protected scope, unknown effect on scopes">,
+    InGroup<DiagGroup<"label-address-scope">>;
+def err_addr_of_label_in_protected_scope : Warning<
+  "address taken of label in protected scope, jump to it would have "
+  "unknown effect on scope">, InGroup<DiagGroup<"label-address-scope">>;
+def note_protected_by_variable_init : Note<
+  "jump bypasses variable initialization">;
+def note_protected_by_vla_typedef : Note<
+  "jump bypasses initialization of VLA typedef">;
+def note_protected_by_vla : Note<
+  "jump bypasses initialization of variable length array">;
+def note_protected_by_cleanup : Note<
+  "jump bypasses initialization of declaration with __attribute__((cleanup))">;
+def note_protected_by_objc_try : Note<
+  "jump bypasses initialization of @try block">;
+def note_protected_by_objc_catch : Note<
+  "jump bypasses initialization of @catch block">;
+def note_protected_by_objc_finally : Note<
+  "jump bypasses initialization of @finally block">;
+def note_protected_by_objc_synchronized : Note<
+  "jump bypasses initialization of @synchronized block">;
+def note_protected_by_cxx_try : Note<
+  "jump bypasses initialization of try block">;
+def note_protected_by_cxx_catch : Note<
+  "jump bypasses initialization of catch block">;
+def note_protected_by___block : Note<
+  "jump bypasses setup of __block variable">;
+
+def err_func_returning_array_function : Error<
+  "function cannot return %select{array|function}0 type %1">;
+def err_field_declared_as_function : Error<"field %0 declared as a function">;
+def err_field_incomplete : Error<"field has incomplete type %0">;
+def ext_variable_sized_type_in_struct : ExtWarn<
+  "field %0 with variable sized type %1 not at the end of a struct or class is"
+  " a GNU extension">, InGroup<GNU>;
+
+def err_flexible_array_empty_struct : Error<
+  "flexible array %0 not allowed in otherwise empty struct">;
+def ext_flexible_array_in_struct : Extension<
+  "%0 may not be nested in a struct due to flexible array member">;
+def ext_flexible_array_in_array : Extension<
+  "%0 may not be used as an array element due to flexible array member">;
+def err_flexible_array_init_nonempty : Error<
+  "non-empty initialization of flexible array member inside subobject">;
+def err_flexible_array_init_needs_braces : Error<
+  "flexible array requires brace-enclosed initializer">;
+def err_illegal_decl_array_of_functions : Error<
+  "'%0' declared as array of functions of type %1">;
+def err_illegal_decl_array_incomplete_type : Error<
+  "array has incomplete element type %0">;
+def err_illegal_decl_array_of_references : Error<
+  "'%0' declared as array of references of type %1">;
+def err_array_star_outside_prototype : Error<
+  "star modifier used outside of function prototype">;
+def err_illegal_decl_pointer_to_reference : Error<
+  "'%0' declared as a pointer to a reference of type %1">;
+def err_illegal_decl_mempointer_to_reference : Error<
+  "'%0' declared as a member pointer to a reference of type %1">;
+def err_illegal_decl_mempointer_to_void : Error<
+  "'%0' declared as a member pointer to void">;
+def err_illegal_decl_mempointer_in_nonclass : Error<
+  "'%0' does not point into a class">;
+def err_mempointer_in_nonclass_type : Error<
+  "member pointer refers into non-class type %0">;
+def err_reference_to_void : Error<"cannot form a reference to 'void'">;
+def err_qualified_block_pointer_type : Error<
+  "qualifier specification on block pointer type not allowed">;
+def err_nonfunction_block_type : Error<
+  "block pointer to non-function type is invalid">;
+def err_return_block_has_expr : Error<"void block should not return a value">;
+def err_block_return_missing_expr : Error<
+  "non-void block should return a value">;
+def err_block_with_return_type_requires_args : Error<
+  "block with explicit return type requires argument list">;
+def err_func_def_incomplete_result : Error<
+  "incomplete result type %0 in function definition">;
+
+// Expressions.
+def ext_sizeof_function_type : Extension<
+  "invalid application of 'sizeof' to a function type">, InGroup<PointerArith>;
+def ext_sizeof_void_type : Extension<
+  "invalid application of '%0' to a void type">, InGroup<PointerArith>;
+def err_sizeof_alignof_incomplete_type : Error<
+  "invalid application of '%select{sizeof|__alignof}0' to an incomplete type %1">;
+def err_sizeof_alignof_bitfield : Error<
+  "invalid application of '%select{sizeof|__alignof}0' to bit-field">;
+def err_offsetof_incomplete_type : Error<
+  "offsetof of incomplete type %0">;
+def err_offsetof_record_type : Error<
+  "offsetof requires struct, union, or class type, %0 invalid">;
+def err_offsetof_array_type : Error<"offsetof requires array type, %0 invalid">;
+def ext_offsetof_extended_field_designator : Extension<
+  "using extended field designator is an extension">;
+def warn_offsetof_non_pod_type : ExtWarn<"offset of on non-POD type %0">,
+  InGroup<InvalidOffsetof>;
+
+def warn_floatingpoint_eq : Warning<
+  "comparing floating point with == or != is unsafe">,
+  InGroup<DiagGroup<"float-equal">>, DefaultIgnore;
+
+def warn_division_by_zero : Warning<"division by zero is undefined">;
+def warn_remainder_by_zero : Warning<"remainder by zero is undefined">;
+def warn_shift_negative : Warning<"shift count is negative">;
+def warn_shift_gt_typewidth : Warning<"shift count >= width of type">;
+
+def warn_precedence_bitwise_rel : Warning<
+  "%0 has lower precedence than %1; %1 will be evaluated first">,
+  InGroup<Parentheses>;
+def note_precedence_bitwise_first : Note<
+  "place parentheses around the %0 expression to evaluate it first">;
+def note_precedence_bitwise_silence : Note<
+  "place parentheses around the %0 expression to silence this warning">;
+  
+def err_sizeof_nonfragile_interface : Error<
+  "invalid application of '%select{alignof|sizeof}1' to interface %0 in "
+  "non-fragile ABI">;
+def err_atdef_nonfragile_interface : Error<
+  "invalid application of @defs in non-fragile ABI">;
+def err_subscript_nonfragile_interface : Error<
+  "subscript requires size of interface %0, which is not constant in "
+  "non-fragile ABI">;
+
+def err_arithmetic_nonfragile_interface : Error<
+  "arithmetic on pointer to interface %0, which is not a constant size in "
+  "non-fragile ABI">;
+
+
+def ext_subscript_non_lvalue : Extension<
+  "ISO C90 does not allow subscripting non-lvalue array">;
+def err_typecheck_subscript_value : Error<
+  "subscripted value is not an array, pointer, or vector">;
+def err_typecheck_subscript_not_integer : Error<
+  "array subscript is not an integer">;
+def err_subscript_function_type : Error<
+  "subscript of pointer to function type %0">;
+def err_subscript_incomplete_type : Error<
+  "subscript of pointer to incomplete type %0">;
+def err_typecheck_member_reference_struct_union : Error<
+  "member reference base type %0 is not a structure or union">;
+def err_typecheck_member_reference_ivar : Error<
+  "%0 does not have a member named %1">;
+def err_typecheck_member_reference_arrow : Error<
+  "member reference type %0 is not a pointer">;
+def err_typecheck_member_reference_suggestion : Error<
+  "member reference type %0 is %select{a|not a}1 pointer; maybe you meant to use '%select{->|.}1'?">;
+def err_typecheck_member_reference_type : Error<
+  "cannot refer to type member %0 in %1 with '%select{.|->}2'">;
+def err_typecheck_member_reference_unknown : Error<
+  "cannot refer to member %0 in %1 with '%select{.|->}2'">;
+def err_member_reference_needs_call : Error<
+  "base of member reference has function type %0; perhaps you meant to call "
+  "this function with '()'?">;
+def warn_subscript_is_char : Warning<"array subscript is of type 'char'">,
+  InGroup<CharSubscript>, DefaultIgnore;
+
+def err_typecheck_incomplete_tag : Error<"incomplete definition of type %0">;
+def err_no_member : Error<"no member named %0 in %1">;
+
+def err_member_redeclared : Error<"class member cannot be redeclared">;
+def err_member_def_undefined_record : Error<
+  "out-of-line definition of %0 from class %1 without definition">;
+def err_member_def_does_not_match : Error<
+  "out-of-line definition of %0 does not match any declaration in %1">;
+def err_nonstatic_member_out_of_line : Error<
+  "non-static data member defined out-of-line">;
+def err_qualified_typedef_declarator : Error<
+  "typedef declarator cannot be qualified">;
+def err_qualified_param_declarator : Error<
+  "parameter declarator cannot be qualified">;
+def err_out_of_line_declaration : Error<
+  "out-of-line declaration of a member must be a definition">;
+def note_member_def_close_match : Note<"member declaration nearly matches">;
+def err_typecheck_ivar_variable_size : Error<
+  "instance variables must have a constant size">;
+def err_ivar_reference_type : Error<
+  "instance variables cannot be of reference type">;
+def err_typecheck_illegal_increment_decrement : Error<
+  "cannot %select{decrement|increment}1 value of type %0">;
+def err_typecheck_arithmetic_incomplete_type : Error<
+  "arithmetic on pointer to incomplete type %0">;
+def err_typecheck_pointer_arith_function_type : Error<
+  "arithmetic on pointer to function type %0">;
+def err_typecheck_pointer_arith_void_type : Error<
+  "arithmetic on pointer to void type">;
+def err_typecheck_decl_incomplete_type : Error<
+  "variable has incomplete type %0">;
+def ext_typecheck_decl_incomplete_type : ExtWarn<
+  "tentative definition of variable with internal linkage has incomplete non-array type %0">;
+def err_tentative_def_incomplete_type : Error<
+  "tentative definition has type %0 that is never completed">;
+def err_tentative_def_incomplete_type_arr : Error<
+  "tentative definition has array of type %0 that is never completed">;
+def warn_tentative_incomplete_array : Warning<
+  "tentative array definition assumed to have one element">;
+def err_typecheck_incomplete_array_needs_initializer : Error<
+  "definition of variable with array type needs an explicit size "
+  "or an initializer">;
+def err_array_init_not_init_list : Error<
+  "array initializer must be an initializer "
+  "list%select{| or string literal}0">;
+def warn_deprecated_string_literal_conversion : Warning<
+  "conversion from string literal to %0 is deprecated">, InGroup<Deprecated>;
+def err_realimag_invalid_type : Error<"invalid type %0 to %1 operator">;
+def err_typecheck_sclass_fscope : Error<
+  "illegal storage class on file-scoped variable">;
+def err_unsupported_global_register : Error<
+  "global register variables are not supported">;
+def err_typecheck_sclass_func : Error<"illegal storage class on function">;
+def err_static_block_func : Error<
+  "function declared in block scope cannot have 'static' storage class">;
+def err_typecheck_address_of : Error<"address of %0 requested">;
+def ext_typecheck_addrof_void : Extension<
+  "ISO C forbids taking the address of an expression of type 'void'">;
+def err_unqualified_pointer_member_function : Error<
+  "must explicitly qualify member function %0 when taking its address">;
+def err_typecheck_invalid_lvalue_addrof : Error<
+  "address expression must be an lvalue or a function designator">;
+def ext_typecheck_addrof_class_temporary : ExtWarn<
+  "taking the address of a temporary object of type %0">, 
+  InGroup<DiagGroup<"address-of-temporary">>, DefaultError;
+def err_typecheck_addrof_class_temporary : Error<
+  "taking the address of a temporary object of type %0">;
+def err_typecheck_unary_expr : Error<
+  "invalid argument type %0 to unary expression">;
+def err_typecheck_indirection_requires_pointer : Error<
+  "indirection requires pointer operand (%0 invalid)">;
+def err_indirection_requires_nonfragile_object : Error<
+  "indirection cannot be to an interface in non-fragile ABI (%0 invalid)">;
+def err_direct_interface_unsupported : Error<
+  "indirection to an interface is not supported (%0 invalid)">;
+def err_typecheck_invalid_operands : Error<
+  "invalid operands to binary expression (%0 and %1)">;
+def err_typecheck_sub_ptr_object : Error<
+  "subtraction of pointer %0 requires pointee to be a complete object type">;
+def err_typecheck_sub_ptr_compatible : Error<
+  "%0 and %1 are not pointers to compatible types">;
+def ext_typecheck_ordered_comparison_of_pointer_integer : ExtWarn<
+  "ordered comparison between pointer and integer (%0 and %1)">;
+def ext_typecheck_ordered_comparison_of_pointer_and_zero : Extension<
+  "ordered comparison between pointer and zero (%0 and %1) is an extension">;
+def ext_typecheck_ordered_comparison_of_function_pointers : ExtWarn<
+  "ordered comparison of function pointers (%0 and %1)">;
+def ext_typecheck_comparison_of_fptr_to_void : Extension<
+  "equality comparison between function pointer and void pointer (%0 and %1)">;
+def ext_typecheck_comparison_of_pointer_integer : ExtWarn<
+  "comparison between pointer and integer (%0 and %1)">;
+def ext_typecheck_comparison_of_distinct_pointers : ExtWarn<
+  "comparison of distinct pointer types (%0 and %1)">;
+def ext_typecheck_cond_incompatible_operands : ExtWarn<
+  "incompatible operand types (%0 and %1)">;
+def err_typecheck_comparison_of_distinct_pointers : Error<
+  "comparison of distinct pointer types (%0 and %1)">;
+def ext_typecheck_comparison_of_distinct_pointers_nonstandard : ExtWarn<
+  "comparison of distinct pointer types (%0 and %1) uses non-standard "
+  "composite pointer type %2">;
+def err_typecheck_vector_comparison : Error<
+  "comparison of vector types (%0 and %1) not supported yet">;
+def err_typecheck_assign_const : Error<"read-only variable is not assignable">;
+def err_stmtexpr_file_scope : Error<
+  "statement expression not allowed at file scope">;
+def warn_mixed_sign_comparison : Warning<
+  "comparison of integers of different signs: %0 and %1">,
+  InGroup<SignCompare>, DefaultIgnore;
+def warn_mixed_sign_conditional : Warning<
+  "operands of ? are integers of different signs: %0 and %1">,
+  InGroup<SignCompare>, DefaultIgnore;
+def warn_lunsigned_always_true_comparison : Warning<
+  "comparison of unsigned expression %0 is always %1">,
+  InGroup<SignCompare>, DefaultIgnore;
+def warn_runsigned_always_true_comparison : Warning<
+  "comparison of %0 unsigned expression is always %1">,
+  InGroup<SignCompare>, DefaultIgnore;
+
+def err_invalid_this_use : Error<
+  "invalid use of 'this' outside of a nonstatic member function">;
+def err_invalid_member_use_in_static_method : Error<
+  "invalid use of member %0 in static member function">;
+def err_invalid_qualified_function_type : Error<
+  "type qualifier is not allowed on this function">;
+def err_invalid_qualified_typedef_function_type_use : Error<
+  "a qualified function type cannot be used to declare a nonmember function "
+  "or a static member function">;
+
+def err_invalid_non_static_member_use : Error<
+  "invalid use of nonstatic data member %0">;
+def err_invalid_incomplete_type_use : Error<
+  "invalid use of incomplete type %0">;
+def err_builtin_func_cast_more_than_one_arg : Error<
+  "function-style cast to a builtin type can only take one argument">;
+def err_builtin_direct_init_more_than_one_arg : Error<
+  "initializer of a builtin type can only take one argument">;
+def err_value_init_for_array_type : Error<
+  "array types cannot be value-initialized">;
+def warn_printf_nonliteral_noargs : Warning<
+  "format string is not a string literal (potentially insecure)">,
+  InGroup<FormatSecurity>;
+def warn_printf_nonliteral : Warning<
+  "format string is not a string literal">,
+  InGroup<FormatNonLiteral>, DefaultIgnore;
+
+def err_unexpected_interface : Error<
+  "unexpected interface name %0: expected expression">;
+def err_ref_non_value : Error<"%0 does not refer to a value">;
+def err_ref_vm_type : Error<
+  "cannot refer to declaration with a variably modified type inside block">;
+def err_ref_array_type : Error<
+  "cannot refer to declaration with an array type inside block">;
+def err_property_not_found : Error<
+  "property %0 not found on object of type %1">;
+def err_duplicate_property : Error<
+  "property has a previous declaration">;
+def ext_gnu_void_ptr : Extension<
+  "use of GNU void* extension">, InGroup<PointerArith>;
+def ext_gnu_ptr_func_arith : Extension<
+  "arithmetic on pointer to function type %0 is a GNU extension">,
+  InGroup<PointerArith>;
+def error_readonly_property_assignment : Error<
+  "assigning to property with 'readonly' attribute not allowed">;
+def ext_integer_increment_complex : Extension<
+  "ISO C does not support '++'/'--' on complex integer type %0">;
+def ext_integer_complement_complex : Extension<
+  "ISO C does not support '~' for complex conjugation of %0">;
+def error_nosetter_property_assignment : Error<
+  "setter method is needed to assign to object using property" " assignment syntax">;
+def error_no_subobject_property_setting : Error<
+  "expression is not assignable using property assignment syntax">;
+
+def ext_freestanding_complex : Extension<
+  "complex numbers are an extension in a freestanding C99 implementation">;
+
+
+// Obj-c expressions
+def warn_root_inst_method_not_found : Warning<
+  "instance method %0 is being used on 'Class' which is not in the root class">;
+def warn_class_method_not_found : Warning<
+  "method %objcclass0 not found (return type defaults to 'id')">;
+def warn_inst_method_not_found : Warning<
+  "method %objcinstance0 not found (return type defaults to 'id')">;
+def error_no_super_class_message : Error<
+  "no @interface declaration found in class messaging of %0">;
+def error_no_super_class : Error<
+  "no super class declared in @interface for %0">;
+def err_invalid_receiver_to_message : Error<
+  "invalid receiver to message expression">;
+def err_invalid_receiver_to_message_super : Error<
+  "'super' is only valid in a method body">;
+def err_invalid_receiver_class_message : Error<
+  "receiver type %0 is not an Objective-C class">;
+def warn_bad_receiver_type : Warning<
+  "receiver type %0 is not 'id' or interface pointer, consider "
+  "casting it to 'id'">;
+def err_bad_receiver_type : Error<"bad receiver type %0">;
+def err_unknown_receiver_suggest : Error<
+  "unknown receiver %0; did you mean %1?">;
+def error_objc_throw_expects_object : Error<
+  "@throw requires an Objective-C object type (%0 invalid)">;
+def error_objc_synchronized_expects_object : Error<
+  "@synchronized requires an Objective-C object type (%0 invalid)">;
+def error_rethrow_used_outside_catch : Error<
+  "@throw (rethrow) used outside of a @catch block">;
+def err_attribute_multiple_objc_gc : Error<
+  "multiple garbage collection attributes specified for type">;
+def err_catch_param_not_objc_type : Error<
+  "@catch parameter is not a pointer to an interface type">;
+def err_illegal_qualifiers_on_catch_parm : Error<
+  "illegal qualifiers on @catch parameter">;
+def err_storage_spec_on_catch_parm : Error<
+  "@catch parameter cannot have storage specifier %select{|'typedef'|'extern'|"
+  "'static'|'auto'|'register'|'__private_extern__'|'mutable'}0">;
+def warn_register_objc_catch_parm : Warning<
+  "'register' storage specifier on @catch parameter will be ignored">;
+def err_qualified_objc_catch_parm : Error<
+  "@catch parameter declarator cannot be qualified">;
+
+
+def warn_setter_getter_impl_required : Warning<
+  "property %0 requires method %1 to be defined - "
+  "use @synthesize, @dynamic or provide a method implementation">;
+def warn_setter_getter_impl_required_in_category : Warning<
+  "property %0 requires method %1 to be defined - "
+  "use @dynamic or provide a method implementation in category">;
+def note_property_impl_required : Note<
+  "implementation is here">;
+def note_parameter_named_here : Note<
+  "passing argument to parameter %0 here">;
+def note_parameter_here : Note<
+  "passing argument to parameter here">;
+
+// C++ casts
+// These messages adhere to the TryCast pattern: %0 is an int specifying the
+// cast type, %1 is the source type, %2 is the destination type.
+def err_bad_cxx_cast_generic : Error<
+  "%select{const_cast|static_cast|reinterpret_cast|dynamic_cast|C-style cast|"
+  "functional-style cast}0 from %1 to %2 is not allowed">;
+def err_bad_cxx_cast_rvalue : Error<
+  "%select{const_cast|static_cast|reinterpret_cast|dynamic_cast|C-style cast|"
+  "functional-style cast}0 from rvalue to reference type %2">;
+def err_bad_cxx_cast_const_away : Error<
+  "%select{const_cast|static_cast|reinterpret_cast|dynamic_cast|C-style cast|"
+  "functional-style cast}0 from %1 to %2 casts away constness">;
+def err_bad_const_cast_dest : Error<
+  "%select{const_cast||||C-style cast|functional-style cast}0 to %2, "
+  "which is not a reference, pointer-to-object, or pointer-to-data-member">;
+def ext_cast_fn_obj : Extension<
+  "cast between pointer-to-function and pointer-to-object is an extension">;
+def err_bad_reinterpret_cast_small_int : Error<
+  "cast from pointer to smaller type %2 loses information">;
+def err_bad_cxx_cast_vector_to_scalar_different_size : Error<
+  "%select{||reinterpret_cast||C-style cast|}0 from vector %1 " 
+  "to scalar %2 of different size">;
+def err_bad_cxx_cast_scalar_to_vector_different_size : Error<
+  "%select{||reinterpret_cast||C-style cast|}0 from scalar %1 " 
+  "to vector %2 of different size">;
+def err_bad_cxx_cast_vector_to_vector_different_size : Error<
+  "%select{||reinterpret_cast||C-style cast|}0 from vector %1 " 
+  "to vector %2 of different size">;
+def err_bad_lvalue_to_rvalue_cast : Error<
+  "cannot cast from lvalue of type %1 to rvalue reference type %2; types are "
+  "not compatible">;
+def err_bad_static_cast_pointer_nonpointer : Error<
+  "cannot cast from type %1 to pointer type %2">;
+def err_bad_static_cast_member_pointer_nonmp : Error<
+  "cannot cast from type %1 to member pointer type %2">;
+def err_bad_static_cast_incomplete : Error<"%0 is an incomplete type">;
+
+// These messages don't adhere to the pattern.
+// FIXME: Display the path somehow better.
+def err_ambiguous_base_to_derived_cast : Error<
+  "ambiguous cast from base %0 to derived %1:%2">;
+def err_static_downcast_via_virtual : Error<
+  "cannot cast %0 to %1 via virtual base %2">;
+def err_downcast_from_inaccessible_base : Error<
+  "cannot cast %select{private|protected}2 base class %1 to %0">;
+def err_upcast_to_inaccessible_base : Error<
+  "cannot cast %0 to its %select{private|protected}2 base class %1">;
+def err_bad_dynamic_cast_not_ref_or_ptr : Error<
+  "%0 is not a reference or pointer">;
+def err_bad_dynamic_cast_not_class : Error<"%0 is not a class">;
+def err_bad_dynamic_cast_incomplete : Error<"%0 is an incomplete type">;
+def err_bad_dynamic_cast_not_ptr : Error<"%0 is not a pointer">;
+def err_bad_dynamic_cast_not_polymorphic : Error<"%0 is not polymorphic">;
+
+// Other C++ expressions
+def err_need_header_before_typeid : Error<
+  "you need to include <typeinfo> before using the 'typeid' operator">;
+def err_incomplete_typeid : Error<"'typeid' of incomplete type %0">;
+def err_static_illegal_in_new : Error<
+  "the 'static' modifier for the array size is not legal in new expressions">;
+def err_array_new_needs_size : Error<
+  "array size must be specified in new expressions">;
+def err_bad_new_type : Error<
+  "cannot allocate %select{function|reference}1 type %0 with new">;
+def err_new_incomplete_type : Error<
+  "allocation of incomplete type %0">;
+def err_new_array_nonconst : Error<
+  "only the first dimension of an allocated array may have dynamic size">;
+def err_new_paren_array_nonconst : Error<
+  "when type is in parentheses, array cannot have dynamic size">;
+def err_placement_new_non_placement_delete : Error<
+  "'new' expression with placement arguments refers to non-placement "
+  "'operator delete'">;
+def err_array_size_not_integral : Error<
+  "array size expression must have integral or enumerated type, not %0">;
+def err_default_init_const : Error<
+  "default initialization of an object of const type %0"
+  "%select{| requires a user-provided default constructor}1">;
+def err_delete_operand : Error<"cannot delete expression of type %0">;
+def err_ambiguous_delete_operand : Error<"ambiguous conversion of delete "
+                                         "expression of type %0 to a pointer">;
+def warn_delete_incomplete : Warning<
+  "deleting pointer to incomplete type %0 may cause undefined behaviour">;
+def err_no_suitable_delete_member_function_found : Error<
+  "no suitable member %0 in %1">;
+def note_member_declared_here : Note<
+  "member %0 declared here">;
+def err_decrement_bool : Error<"cannot decrement expression of type bool">;
+def warn_increment_bool : Warning<
+  "incrementing expression of type bool is deprecated">, InGroup<Deprecated>;
+def ext_catch_incomplete_ptr : ExtWarn<
+  "ISO C++ forbids catching a pointer to incomplete type %0">;
+def ext_catch_incomplete_ref : ExtWarn<
+  "ISO C++ forbids catching a reference to incomplete type %0">;
+def err_catch_incomplete : Error<"cannot catch incomplete type %0">;
+def err_catch_rvalue_ref : Error<"cannot catch exceptions by rvalue reference">;
+def err_qualified_catch_declarator : Error<
+  "exception declarator cannot be qualified">;
+def err_early_catch_all : Error<"catch-all handler must come last">;
+def err_bad_memptr_rhs : Error<
+  "right hand operand to %0 has non pointer-to-member type %1">;
+def err_memptr_rhs_to_incomplete : Error<
+  "cannot dereference pointer into incomplete class type %0">;
+def err_bad_memptr_lhs : Error<
+  "left hand operand to %0 must be a %select{|pointer to }1class "
+  "compatible with the right hand operand, but is %2">;
+def warn_exception_caught_by_earlier_handler : Warning<
+  "exception of type %0 will be caught by earlier handler">;
+def note_previous_exception_handler : Note<"for type %0">;
+
+def err_conditional_void_nonvoid : Error<
+  "%select{left|right}1 operand to ? is void, but %select{right|left}1 operand "
+  "is of type %0">;
+def err_conditional_ambiguous : Error<
+  "conditional expression is ambiguous; %0 can be converted to %1 "
+  "and vice versa">;
+def err_conditional_ambiguous_ovl : Error<
+  "conditional expression is ambiguous; %0 and %1 can be converted to several "
+  "common types">;
+
+def err_throw_incomplete : Error<
+  "cannot throw object of incomplete type %0">;
+def err_throw_incomplete_ptr : Error<
+  "cannot throw pointer to object of incomplete type %0">;
+def err_return_in_constructor_handler : Error<
+  "return in the catch of a function try block of a constructor is illegal">;
+
+def err_operator_arrow_circular : Error<
+  "circular pointer delegation detected">;
+def err_pseudo_dtor_base_not_scalar : Error<
+  "object expression of non-scalar type %0 cannot be used in a "
+  "pseudo-destructor expression">;
+def err_pseudo_dtor_type_mismatch : Error<
+  "the type of object expression (%0) does not match the type being destroyed "
+  "(%1) in pseudo-destructor expression">;
+def err_pseudo_dtor_call_with_args : Error<
+  "call to pseudo-destructor cannot have any arguments">;
+def err_dtor_expr_without_call : Error<
+  "%select{destructor reference|pseudo-destructor expression}0 must be "
+  "called immediately with '()'">;
+def err_pseudo_dtor_destructor_non_type : Error<
+  "%0 does not refer to a type name in pseudo-destructor expression; expected "
+  "the name of type %1">;
+def err_pseudo_dtor_template : Error<
+  "specialization of template %0 does not refer to a scalar type in pseudo-"
+  "destructor expression">;
+def err_invalid_use_of_function_type : Error<
+  "a function type is not allowed here">;
+def err_invalid_use_of_array_type : Error<"an array type is not allowed here">;
+def err_type_defined_in_condition : Error<
+  "types may not be defined in conditions">;
+def err_typecheck_bool_condition : Error<
+  "value of type %0 is not contextually convertible to 'bool'">;
+def err_typecheck_ambiguous_condition : Error<
+  "conversion from %0 to %1 is ambiguous">;
+def err_typecheck_nonviable_condition : Error<
+  "no viable conversion from %0 to %1">;
+def err_typecheck_deleted_function : Error<
+  "conversion function from %0 to %1 invokes a deleted function">;
+  
+def err_expected_class_or_namespace : Error<"expected a class or namespace">;
+def err_missing_qualified_for_redecl : Error<
+  "must qualify the name %0 to declare %q1 in this scope">;
+def err_invalid_declarator_scope : Error<
+  "definition or redeclaration of %0 not in a namespace enclosing %1">;
+def err_invalid_declarator_global_scope : Error<
+  "definition or redeclaration of %0 cannot name the global scope">;
+def err_invalid_declarator_in_function : Error<
+  "definition or redeclaration of %0 not allowed inside a function">;
+def err_not_tag_in_scope : Error<
+  "no %select{struct|union|class|enum}0 named %1 in %2">;
+
+def err_cannot_form_pointer_to_member_of_reference_type : Error<
+  "cannot form a pointer-to-member to member %0 of reference type %1">;
+def err_incomplete_object_call : Error<
+  "incomplete type in call to object of type %0">;
+  
+def warn_condition_is_assignment : Warning<"using the result of an "
+  "assignment as a condition without parentheses">,
+  InGroup<Parentheses>;
+// Completely identical except off by default.
+def warn_condition_is_idiomatic_assignment : Warning<"using the result "
+  "of an assignment as a condition without parentheses">,
+  InGroup<DiagGroup<"idiomatic-parentheses">>, DefaultIgnore;
+def note_condition_assign_to_comparison : Note<
+  "use '==' to turn this assignment into an equality comparison">;
+def note_condition_assign_silence : Note<
+  "place parentheses around the assignment to silence this warning">;
+
+def warn_value_always_zero : Warning<
+  "%0 is always %select{zero|false|NULL}1 in this context">;
+
+// assignment related diagnostics (also for argument passing, returning, etc).
+// In most of these diagnostics the %2 is a value from the
+// Sema::AssignmentAction enumeration
+def err_typecheck_convert_incompatible : Error<
+  "%select{assigning to|passing|returning|converting|initializing|sending|casting}2"
+  " %0 "
+  "%select{from incompatible type|to parameter of incompatible type|"
+  "from a function with incompatible result type|to incompatible type|"
+  "with an expression of incompatible type|to parameter of incompatible type|"
+  "to incompatible type}2 %1">;
+def warn_incompatible_qualified_id : Warning<
+  "%select{assigning to|passing|returning|converting|initializing|sending|casting}2"
+  " %0 "
+  "%select{from incompatible type|to parameter of incompatible type|"
+  "from a function with incompatible result type|to incompatible type|"
+  "with an expression of incompatible type|to parameter of incompatible type|"
+  "to incompatible type}2 %1">;
+def ext_typecheck_convert_pointer_int : ExtWarn<
+  "incompatible pointer to integer conversion "
+  "%select{assigning to|passing|returning|converting|initializing|sending|casting}2"
+  " %0 "
+  "%select{from|to parameter of type|from a function with result type|to type|"
+  "with an expression of type|to parameter of type|to type}2 %1">;
+def ext_typecheck_convert_int_pointer : ExtWarn<
+  "incompatible integer to pointer conversion "
+  "%select{assigning to|passing|returning|converting|initializing|sending|casting}2"
+  " %0 "
+  "%select{from|to parameter of type|from a function with result type|to type|"
+  "with an expression of type|to parameter of type|to type}2 %1">;
+def ext_typecheck_convert_pointer_void_func : Extension<
+  "%select{assigning to|passing|returning|converting|initializing|sending|casting}2"
+  " %0 "
+  "%select{from|to parameter of type|from a function with result type|to type|"
+  "with an expression of type|to parameter of type|to type}2 %1 "
+  "converts between void pointer and function pointer">;
+def ext_typecheck_convert_incompatible_pointer_sign : ExtWarn<
+  "%select{assigning to|passing|returning|converting|initializing|sending|casting}2"
+  " %0 "
+  "%select{from|to parameter of type|from a function with result type|to type|"
+  "with an expression of type|to parameter of type|to type}2 %1 "
+  "converts between pointers to integer types with different sign">,
+  InGroup<DiagGroup<"pointer-sign">>;
+def ext_typecheck_convert_incompatible_pointer : ExtWarn<
+  "incompatible pointer types "
+  "%select{assigning to|passing|returning|converting|initializing|sending|casting}2"
+  " %0 "
+  "%select{from|to parameter of type|from a function with result type|to type|"
+  "with an expression of type|to parameter of type|to type}2 %1">;
+def ext_typecheck_convert_discards_qualifiers : ExtWarn<
+  "%select{assigning to|passing|returning|converting|initializing|sending|casting}2"
+  " %0 "
+  "%select{from|to parameter of type|from a function with result type|to type|"
+  "with an expression of type|to parameter of type|to type}2 %1 discards "
+  "qualifiers">;
+def ext_nested_pointer_qualifier_mismatch : ExtWarn<
+  "%select{assigning to|passing|returning|converting|initializing|sending|casting}2"
+  " %0 "
+  "%select{from|to parameter of type|from a function with result type|to type|"
+  "with an expression of type|to parameter of type|to type}2 %1 discards "
+  "qualifiers in nested pointer types">;
+def warn_incompatible_vectors : Warning<
+  "incompatible vector types "
+  "%select{assigning to|passing|returning|converting|initializing|sending|casting}2"
+  " %0 "
+  "%select{from|to parameter of type|from a function with result type|to type|"
+  "with an expression of type|to parameter of type|to type}2 %1">,
+  InGroup<VectorConversions>, DefaultIgnore;
+def err_int_to_block_pointer : Error<
+  "invalid block pointer conversion "
+  "%select{assigning to|passing|returning|converting|initializing|sending|casting}2"
+  " %0 "
+  "%select{from|to parameter of type|from a function with result type|to type|"
+  "with an expression of type|to parameter of type|to type}2 %1">;
+def err_typecheck_convert_incompatible_block_pointer : Error<
+  "incompatible block pointer types "
+  "%select{assigning to|passing|returning|converting|initializing|sending|casting}2"
+  " %0 "
+  "%select{from|to parameter of type|from a function with result type|to type|"
+  "with an expression of type|to parameter of type|to type}2 %1">;
+  
+def err_typecheck_convert_ambiguous : Error<
+  "ambiguity in initializing value of type %0 with initializer of type %1">;
+def err_cannot_initialize_decl_noname : Error<
+  "cannot initialize a value of type %0 with an %select{rvalue|lvalue}1 "
+  "of type %2">;
+def err_cannot_initialize_decl : Error<
+  "cannot initialize %0 with an %select{rvalue|lvalue}1 of type %2">;
+def err_typecheck_comparison_of_distinct_blocks : Error<
+  "comparison of distinct block types (%0 and %1)">;
+
+def err_typecheck_array_not_modifiable_lvalue : Error<
+  "array type %0 is not assignable">;
+def err_typecheck_non_object_not_modifiable_lvalue : Error<
+  "non-object type %0 is not assignable">;
+def err_typecheck_expression_not_modifiable_lvalue : Error<
+  "expression is not assignable">;
+def err_typecheck_incomplete_type_not_modifiable_lvalue : Error<
+  "incomplete type %0 is not assignable">;
+def err_typecheck_lvalue_casts_not_supported : Error<
+  "assignment to cast is illegal, lvalue casts are not supported">;
+
+def err_typecheck_duplicate_vector_components_not_mlvalue : Error<
+  "vector is not assignable (contains duplicate components)">;
+def err_block_decl_ref_not_modifiable_lvalue : Error<
+  "variable is not assignable (missing __block type specifier)">;
+def err_typecheck_call_not_function : Error<
+  "called object type %0 is not a function or function pointer">;
+def err_call_incomplete_return : Error<
+  "calling function with incomplete return type %0">;
+def err_call_function_incomplete_return : Error<
+  "calling %0 with incomplete return type %1">;
+def note_function_with_incomplete_return_type_declared_here : Note<
+  "%0 declared here">;
+def err_call_incomplete_argument : Error<
+  "argument type %0 is incomplete">;
+def err_typecheck_call_too_few_args : Error<
+  "too few arguments to %select{function|block|method}0 call, "
+  "expected %1, have %2">;
+def err_typecheck_call_too_few_args_at_least : Error<
+  "too few arguments to %select{function|block|method}0 call, "
+  "expected at least %1, have %2">;
+def err_typecheck_call_too_many_args : Error<
+  "too many arguments to %select{function|block|method}0 call, "
+  "expected %1, have %2">;
+def err_typecheck_call_too_many_args_at_most : Error<
+  "too many arguments to %select{function|block|method}0 call, "
+  "expected at most %1, have %2">;
+def warn_call_wrong_number_of_arguments : Warning<
+  "too %select{few|many}0 arguments in call to %1">;
+def err_atomic_builtin_must_be_pointer : Error<
+  "first argument to atomic builtin must be a pointer (%0 invalid)">;
+def err_atomic_builtin_must_be_pointer_intptr : Error<
+  "first argument to atomic builtin must be a pointer to integer or pointer"
+  " (%0 invalid)">;
+def err_atomic_builtin_pointer_size : Error<
+  "first argument to atomic builtin must be a pointer to 1,2,4,8 or 16 byte "
+  "type (%0 invalid)">;
+
+  
+def err_deleted_function_use : Error<"attempt to use a deleted function">;
+
+def err_cannot_pass_objc_interface_to_vararg : Error<
+  "cannot pass object with interface type %0 by-value through variadic "
+  "%select{function|block|method}1">;
+
+def warn_cannot_pass_non_pod_arg_to_vararg : Warning<
+  "cannot pass object of non-POD type %0 through variadic "
+  "%select{function|block|method|constructor}1; call will abort at runtime">,
+  InGroup<DiagGroup<"non-pod-varargs">>, DefaultError;
+
+def err_typecheck_call_invalid_ordered_compare : Error<
+  "ordered compare requires two args of floating point type (%0 and %1)">;
+def err_typecheck_call_invalid_unary_fp : Error<
+  "floating point classification requires argument of floating point type "
+  "(passed in %0)">;
+def err_typecheck_cond_expect_scalar : Error<
+  "used type %0 where arithmetic or pointer type is required">;
+def ext_typecheck_cond_one_void : Extension<
+  "C99 forbids conditional expressions with only one void side">;
+def ext_typecheck_cast_nonscalar : Extension<
+  "C99 forbids casting nonscalar type %0 to the same type">;
+def ext_typecheck_cast_to_union : Extension<"C99 forbids casts to union type">;
+def err_typecheck_cast_to_union_no_type : Error<
+  "cast to union type from type %0 not present in union">;
+def err_cast_pointer_from_non_pointer_int : Error<
+  "operand of type %0 cannot be cast to a pointer type">;
+def err_cast_pointer_to_non_pointer_int : Error<
+  "pointer cannot be cast to type %0">;
+def err_typecheck_expect_scalar_operand : Error<
+  "operand of type %0 where arithmetic or pointer type is required">;
+def err_typecheck_cond_incompatible_operands : Error<
+  "incompatible operand types (%0 and %1)">;
+def ext_typecheck_cond_incompatible_operands_nonstandard : ExtWarn<
+  "incompatible operand types (%0 and %1) use non-standard composite pointer "
+  "type %2">;
+def err_cast_selector_expr : Error<
+  "cannot type cast @selector expression">;
+def warn_typecheck_cond_incompatible_pointers : ExtWarn<
+  "pointer type mismatch (%0 and %1)">;
+def warn_typecheck_cond_pointer_integer_mismatch : ExtWarn<
+  "pointer/integer type mismatch in conditional expression (%0 and %1)">;
+def err_typecheck_choose_expr_requires_constant : Error<
+  "'__builtin_choose_expr' requires a constant expression">;
+def ext_typecheck_expression_not_constant_but_accepted : Extension<
+  "expression is not a constant, but is accepted as one by GNU extensions">, 
+  InGroup<GNU>;
+def warn_unused_expr : Warning<"expression result unused">,
+  InGroup<UnusedValue>;
+def warn_unused_voidptr : Warning<
+  "expression result unused; should this cast be to 'void'?">,
+  InGroup<UnusedValue>;
+def warn_unused_property_expr : Warning<
+ "property access result unused - getters should not be used for side effects">,
+  InGroup<UnusedValue>;
+def warn_unused_call : Warning<
+  "ignoring return value of function declared with %0 attribute">,
+  InGroup<UnusedValue>;
+
+def err_incomplete_type_used_in_type_trait_expr : Error<
+  "incomplete type %0 used in type trait expression">;
+def err_expected_ident_or_lparen : Error<"expected identifier or '('">;
+  
+// inline asm.
+def err_asm_wide_character : Error<"wide string is invalid in 'asm'">;
+def err_asm_invalid_lvalue_in_output : Error<"invalid lvalue in asm output">;
+def err_asm_invalid_output_constraint : Error<
+  "invalid output constraint '%0' in asm">;
+def err_asm_invalid_lvalue_in_input : Error<
+  "invalid lvalue in asm input for constraint '%0'">;
+def err_asm_invalid_input_constraint : Error<
+  "invalid input constraint '%0' in asm">;
+def err_asm_invalid_type_in_input : Error<
+  "invalid type %0 in asm input for constraint '%1'">;
+def err_asm_tying_incompatible_types : Error<
+  "unsupported inline asm: input with type %0 matching output with type %1">;
+def err_asm_unknown_register_name : Error<"unknown register name '%0' in asm">;
+def err_invalid_asm_cast_lvalue : Error<
+  "invalid use of a cast in a inline asm context requiring an l-value: "
+  "remove the cast or build with -fheinous-gnu-extensions">;
+
+def warn_invalid_asm_cast_lvalue : Warning<
+  "invalid use of a cast in a inline asm context requiring an l-value: "
+  "accepted due to -fheinous-gnu-extensions, but clang may remove support "
+  "for this in the future">;
+
+
+
+def err_invalid_conversion_between_vectors : Error<
+  "invalid conversion between vector type %0 and %1 of different size">;
+def err_invalid_conversion_between_vector_and_integer : Error<
+  "invalid conversion between vector type %0 and integer type %1 "
+  "of different size">;
+
+def err_invalid_conversion_between_vector_and_scalar : Error<
+  "invalid conversion between vector type %0 and scalar type %1">;
+def err_overload_expr_requires_non_zero_constant : Error<
+  "overload requires a non-zero constant expression as first argument">;
+def err_overload_incorrect_fntype : Error<
+  "argument is not a function, or has wrong number of parameters">;
+
+// C++ member initializers.
+def err_only_constructors_take_base_inits : Error<
+  "only constructors take base initializers">;
+
+def err_multiple_mem_initialization : Error <
+  "multiple initializations given for non-static member %0">;
+def err_multiple_mem_union_initialization : Error <
+  "initializing multiple members of anonymous union">;
+def err_multiple_base_initialization : Error <
+  "multiple initializations given for base %0">;
+
+def err_mem_init_not_member_or_class : Error<
+  "member initializer %0 does not name a non-static data member or base "
+  "class">;
+
+def warn_initializer_out_of_order : Warning<
+  "%select{field|base class}0 %1 will be initialized after "
+  "%select{field|base}2 %3">,
+  InGroup<Reorder>, DefaultIgnore;
+
+def err_base_init_does_not_name_class : Error<
+  "constructor initializer %0 does not name a class">;
+def err_base_init_direct_and_virtual : Error<
+  "base class initializer %0 names both a direct base class and an "
+  "inherited virtual base class">;
+def err_not_direct_base_or_virtual : Error<
+  "type %0 is not a direct or virtual base of %1">;
+
+def err_in_class_initializer_non_integral_type : Error<
+  "in-class initializer has non-integral, non-enumeration type %0">;
+def err_in_class_initializer_non_constant : Error<
+  "in-class initializer is not an integral constant expression">;
+
+// C++ anonymous unions and GNU anonymous structs/unions
+def ext_anonymous_union : Extension<
+  "anonymous unions are a GNU extension in C">, InGroup<GNU>;
+def ext_anonymous_struct : Extension<
+  "anonymous structs are a GNU extension">, InGroup<GNU>;
+def err_anonymous_union_not_static : Error<
+  "anonymous unions at namespace or global scope must be declared 'static'">;
+def err_anonymous_union_with_storage_spec : Error<
+  "anonymous union at class scope must not have a storage specifier">;
+def err_anonymous_struct_not_member : Error<
+  "anonymous %select{structs|structs and classes}0 must be "
+  "%select{struct or union|class}0 members">;
+def err_anonymous_union_member_redecl : Error<
+  "member of anonymous union redeclares %0">;
+def err_anonymous_struct_member_redecl : Error<
+  "member of anonymous struct redeclares %0">;
+def err_anonymous_record_with_type : Error<
+  "types cannot be declared in an anonymous %select{struct|union}0">;
+def err_anonymous_record_with_function : Error<
+  "functions cannot be declared in an anonymous %select{struct|union}0">;
+def err_anonymous_record_with_static : Error<
+  "static members cannot be declared in an anonymous %select{struct|union}0">;
+def err_anonymous_record_bad_member : Error<
+  "anonymous %select{struct|union}0 can only contain non-static data members">;
+def err_anonymous_record_nonpublic_member : Error<
+  "anonymous %select{struct|union}0 cannot contain a "
+  "%select{private|protected}1 data member">;
+
+// C++ local classes
+def err_reference_to_local_var_in_enclosing_function : Error<
+  "reference to local variable %0 declared in enclosed function %1">;
+def note_local_variable_declared_here : Note<
+  "%0 declared here">;
+def err_static_data_member_not_allowed_in_local_class : Error<
+  "static data member %0 not allowed in local class %1">; 
+  
+// C++ derived classes
+def err_base_clause_on_union : Error<"unions cannot have base classes">;
+def err_base_must_be_class : Error<"base specifier must name a class">;
+def err_union_as_base_class : Error<"unions cannot be base classes">;
+def err_incomplete_base_class : Error<"base class has incomplete type">;
+def err_duplicate_base_class : Error<
+  "base class %0 specified more than once as a direct base class">;
+// FIXME: better way to display derivation?  Pass entire thing into diagclient?
+def err_ambiguous_derived_to_base_conv : Error<
+  "ambiguous conversion from derived class %0 to base class %1:%2">;
+def err_ambiguous_memptr_conv : Error<
+  "ambiguous conversion from pointer to member of %select{base|derived}0 "
+  "class %1 to pointer to member of %select{derived|base}0 class %2:%3">;
+
+def err_memptr_conv_via_virtual : Error<
+  "conversion from pointer to member of class %0 to pointer to member "
+  "of class %1 via virtual base %2 is not allowed">;
+
+// C++ access control
+def err_conv_to_inaccessible_base : Error<
+  "conversion from %0 to inaccessible base class %1">, NoSFINAE;
+def note_inheritance_specifier_here : Note<
+  "'%0' inheritance specifier here">;
+def note_inheritance_implicitly_private_here : Note<
+  "inheritance is implicitly 'private'">;
+
+// C++ member name lookup
+def err_ambiguous_member_multiple_subobjects : Error<
+  "non-static member %0 found in multiple base-class subobjects of type %1:%2">;
+def err_ambiguous_member_multiple_subobject_types : Error<
+  "member %0 found in multiple base classes of different types">;
+def note_ambiguous_member_found : Note<"member found by ambiguous name lookup">;
+def err_ambiguous_reference : Error<"reference to %0 is ambiguous">;
+def note_ambiguous_candidate : Note<"candidate found by name lookup is %q0">;
+def err_ambiguous_tag_hiding : Error<"a type named %0 is hidden by a "
+  "declaration in a different namespace">;
+def note_hidden_tag : Note<"type declaration hidden">;
+def note_hiding_object : Note<"declaration hides type">;
+
+// C++ operator overloading
+def err_operator_overload_needs_class_or_enum : Error<
+  "overloaded %0 must have at least one parameter of class "
+  "or enumeration type">;
+
+def err_operator_overload_variadic : Error<"overloaded %0 cannot be variadic">;
+def err_operator_overload_static : Error<
+  "overloaded %0 cannot be a static member function">;
+def err_operator_overload_default_arg : Error<
+  "parameter of overloaded %0 cannot have a default argument">;
+def err_operator_overload_must_be : Error<
+  "overloaded %0 must be a %select{unary|binary|unary or binary}2 operator "
+  "(has %1 parameter%s1)">;
+
+def err_operator_overload_must_be_member : Error<
+  "overloaded %0 must be a non-static member function">;
+def err_operator_overload_post_incdec_must_be_int : Error<
+  "parameter of overloaded post-%select{increment|decrement}1 operator must "
+  "have type 'int' (not %0)">;
+
+// C++ allocation and deallocation functions.
+def err_operator_new_delete_declared_in_namespace : Error<
+  "%0 cannot be declared inside a namespace">;
+def err_operator_new_delete_declared_static : Error<
+  "%0 cannot be declared static in global scope">;
+def err_operator_new_delete_invalid_result_type : Error<
+  "%0 must return type %1">;
+def err_operator_new_delete_dependent_result_type : Error<
+  "%0 cannot have a dependent return type; use %1 instead">;
+def err_operator_new_delete_too_few_parameters : Error<
+  "%0 must have at least one parameter.">;
+def err_operator_new_delete_template_too_few_parameters : Error<
+  "%0 template must have at least two parameters.">;
+
+def err_operator_new_dependent_param_type : Error<
+  "%0 cannot take a dependent type as first parameter; "
+  "use size_t (%1) instead">;
+def err_operator_new_param_type : Error<
+  "%0 takes type size_t (%1) as first parameter">;
+def err_operator_new_default_arg: Error<
+  "parameter of %0 cannot have a default argument">;
+def err_operator_delete_dependent_param_type : Error<
+  "%0 cannot take a dependent type as first parameter; use %1 instead">;
+def err_operator_delete_param_type : Error<
+  "%0 takes type %1 as first parameter">;
+
+// C++ literal operators
+def err_literal_operator_outside_namespace : Error<
+  "literal operator %0 must be in a namespace or global scope">;
+// FIXME: This diagnostic sucks
+def err_literal_operator_params : Error<
+  "parameter declaration for literal operator %0 is not valid">;
+
+// C++ conversion functions
+def err_conv_function_not_member : Error<
+  "conversion function must be a non-static member function">;
+def err_conv_function_return_type : Error<
+  "conversion function cannot have a return type">;
+def err_conv_function_with_params : Error<
+  "conversion function cannot have any parameters">;
+def err_conv_function_variadic : Error<
+  "conversion function cannot be variadic">;
+def err_conv_function_to_array : Error<
+  "conversion function cannot convert to an array type">;
+def err_conv_function_to_function : Error<
+  "conversion function cannot convert to a function type">;
+def err_conv_function_with_complex_decl : Error<
+  "must use a typedef to declare a conversion to %0">;
+def err_conv_function_redeclared : Error<
+  "conversion function cannot be redeclared">;
+def warn_conv_to_self_not_used : Warning<
+  "conversion function converting %0 to itself will never be used">;
+def warn_conv_to_base_not_used : Warning<
+  "conversion function converting %0 to its base class %1 will never be used">;
+def warn_conv_to_void_not_used : Warning<
+  "conversion function converting %0 to %1 will never be used">;
+
+def warn_not_compound_assign : Warning<
+  "use of unary operator that may be intended as compound assignment (%0=)">;
+
+// C++0x explicit conversion operators
+def warn_explicit_conversion_functions : Warning<
+  "explicit conversion functions are a C++0x extension">;
+
+def warn_printf_write_back : Warning<
+  "use of '%%n' in format string discouraged (potentially insecure)">,
+  InGroup<FormatSecurity>;
+def warn_printf_insufficient_data_args : Warning<
+  "more '%%' conversions than data arguments">, InGroup<Format>;
+def warn_printf_data_arg_not_used : Warning<
+  "data argument not used by format string">, InGroup<FormatExtraArgs>;
+def warn_printf_invalid_conversion : Warning<
+  "invalid conversion specifier '%0'">, InGroup<Format>;
+def warn_printf_incomplete_specifier : Warning<
+  "incomplete format specifier">, InGroup<Format>;
+def warn_printf_missing_format_string : Warning<
+  "format string missing">, InGroup<Format>;
+def warn_printf_conversion_argument_type_mismatch : Warning<
+  "conversion specifies type %0 but the argument has type %1">,
+  InGroup<Format>;
+def warn_printf_positional_arg_exceeds_data_args : Warning <
+  "data argument position '%0' exceeds the number of data arguments (%1)">,
+  InGroup<Format>;
+def warn_printf_zero_positional_specifier : Warning<
+  "position arguments in format strings start counting at 1 (not 0)">,
+  InGroup<Format>;
+def warn_printf_invalid_positional_specifier : Warning<
+  "invalid position specified for %select{field width|field precision}0">,
+  InGroup<Format>;
+def warn_printf_mix_positional_nonpositional_args : Warning<
+  "cannot mix positional and non-positional arguments in format string">,
+  InGroup<Format>;
+def warn_null_arg : Warning<
+  "null passed to a callee which requires a non-null argument">,
+  InGroup<NonNull>;
+def warn_printf_empty_format_string : Warning<
+  "format string is empty">, InGroup<FormatZeroLength>;
+def warn_printf_format_string_is_wide_literal : Warning<
+  "format string should not be a wide string">, InGroup<Format>;
+def warn_printf_format_string_contains_null_char : Warning<
+  "format string contains '\\0' within the string body">, InGroup<Format>;
+def warn_printf_asterisk_missing_arg : Warning<
+  "'%select{*|.*}0' specified field %select{width|precision}0 is missing a matching 'int' argument">;
+def warn_printf_asterisk_wrong_type : Warning<
+  "field %select{width|precision}0 should have type %1, but argument has type %2">,
+  InGroup<Format>;
+def warn_printf_nonsensical_precision: Warning<
+  "precision used in '%0' conversion specifier (where it has no meaning)">,
+  InGroup<Format>;
+def warn_printf_nonsensical_flag: Warning<
+  "flag '%0' results in undefined behavior in '%1' conversion specifier">,
+  InGroup<Format>;
+  
+// CHECK: returning address/reference of stack memory
+def warn_ret_stack_addr : Warning<
+  "address of stack memory associated with local variable %0 returned">;
+def warn_ret_stack_ref : Warning<
+  "reference to stack memory associated with local variable %0 returned">;
+def warn_ret_addr_label : Warning<
+  "returning address of label, which is local">;
+def err_ret_local_block : Error<
+  "returning block that lives on the local stack">;
+
+
+// For non-floating point, expressions of the form x == x or x != x
+// should result in a warning, since these always evaluate to a constant.
+def warn_selfcomparison : Warning<
+  "self-comparison always results in a constant value">;
+def warn_stringcompare : Warning<
+  "result of comparison against %select{a string literal|@encode}0 is "
+  "unspecified (use strncmp instead)">;
+
+
+
+// Blocks
+def err_blocks_disable : Error<"blocks support disabled - compile with -fblocks"
+  " or pick a deployment target that supports them">;
+def err_expected_block_lbrace : Error<"expected '{' in block literal">;
+def err_return_in_block_expression : Error<
+  "return not allowed in block expression literal">;
+def err_block_returns_array : Error<
+  "block declared as returning an array">;
+
+
+// CFString checking
+def err_cfstring_literal_not_string_constant : Error<
+  "CFString literal is not a string constant">;
+def warn_cfstring_literal_contains_nul_character : Warning<
+  "CFString literal contains NUL character">;
+
+// Statements.
+def err_continue_not_in_loop : Error<
+  "'continue' statement not in loop statement">;
+def err_break_not_in_loop_or_switch : Error<
+  "'break' statement not in loop or switch statement">;
+def err_default_not_in_switch : Error<
+  "'default' statement not in switch statement">;
+def err_case_not_in_switch : Error<"'case' statement not in switch statement">;
+def warn_bool_switch_condition : Warning<
+  "switch condition has boolean value">;
+def warn_case_value_overflow : Warning<
+  "overflow converting case value to switch condition type (%0 to %1)">,
+  InGroup<DiagGroup<"switch">>;
+def err_duplicate_case : Error<"duplicate case value '%0'">;
+def warn_case_empty_range : Warning<"empty case range specified">;
+def warn_missing_cases : Warning<"enumeration value %0 not handled in switch">,
+  InGroup<DiagGroup<"switch-enum"> >;
+def not_in_enum : Warning<"case value not in enumerated type %0">,
+  InGroup<DiagGroup<"switch-enum"> >; 
+def err_typecheck_statement_requires_scalar : Error<
+  "statement requires expression of scalar type (%0 invalid)">;
+def err_typecheck_statement_requires_integer : Error<
+  "statement requires expression of integer type (%0 invalid)">;
+def err_multiple_default_labels_defined : Error<
+  "multiple default labels in one switch">;
+def err_switch_multiple_conversions : Error<
+  "multiple conversions from switch condition type %0 to an integral or "
+  "enumeration type">;
+def note_switch_conversion : Note<
+  "conversion to %select{integral|enumeration}0 type %1">;
+def err_switch_explicit_conversion : Error<
+  "switch condition type %0 requires explicit conversion to %1">;
+def err_switch_incomplete_class_type : Error<
+  "switch condition has incomplete class type %0">;
+def warn_empty_if_body : Warning<
+  "if statement has empty body">, InGroup<EmptyBody>;
+def err_va_start_used_in_non_variadic_function : Error<
+  "'va_start' used in function with fixed args">;
+def warn_second_parameter_of_va_start_not_last_named_argument : Warning<
+  "second parameter of 'va_start' not last named argument">;
+def err_first_argument_to_va_arg_not_of_type_va_list : Error<
+  "first argument to 'va_arg' is of type %0 and not 'va_list'">;
+
+def warn_return_missing_expr : Warning<
+  "non-void %select{function|method}1 %0 should return a value">,
+  InGroup<ReturnType>;
+def ext_return_missing_expr : ExtWarn<
+  "non-void %select{function|method}1 %0 should return a value">,
+  InGroup<ReturnType>;
+def ext_return_has_expr : ExtWarn<
+  "void %select{function|method}1 %0 should not return a value">,
+  InGroup<ReturnType>;
+def ext_return_has_void_expr : Extension<
+  "void %select{function|method}1 %0 should not return void expression">;
+def warn_noreturn_function_has_return_expr : Warning<
+  "function %0 declared 'noreturn' should not return">,
+  InGroup<DiagGroup<"invalid-noreturn">>;
+def warn_falloff_noreturn_function : Warning<
+  "function declared 'noreturn' should not return">,
+  InGroup<DiagGroup<"invalid-noreturn">>;
+def err_noreturn_block_has_return_expr : Error<
+  "block declared 'noreturn' should not return">;
+def err_block_on_nonlocal : Error<
+  "__block attribute not allowed, only allowed on local variables">;
+def err_block_on_vm : Error<
+  "__block attribute not allowed on declaration with a variably modified type">;
+
+def err_shufflevector_non_vector : Error<
+  "first two arguments to __builtin_shufflevector must be vectors">;
+def err_shufflevector_incompatible_vector : Error<
+  "first two arguments to __builtin_shufflevector must have the same type">;
+def err_shufflevector_nonconstant_argument : Error<
+  "index for __builtin_shufflevector must be a constant integer">;
+def err_shufflevector_argument_too_large : Error<
+  "index for __builtin_shufflevector must be less than the total number "
+  "of vector elements">;
+
+def err_vector_incorrect_num_initializers : Error<
+  "%select{too many|too few}0 elements in vector initialization (expected %1 elements, have %2)">;
+def err_altivec_empty_initializer : Error<"expected initializer">;
+
+def err_argument_invalid_range : Error<
+  "argument should be a value from %0 to %1">;
+
+def err_builtin_longjmp_invalid_val : Error<
+  "argument to __builtin_longjmp must be a constant 1">;
+
+def err_constant_integer_arg_type : Error<
+  "argument to %0 must be a constant integer">;
+
+def ext_mixed_decls_code : Extension<
+  "ISO C90 forbids mixing declarations and code">;
+def err_non_variable_decl_in_for : Error<
+  "declaration of non-local variable in 'for' loop">;
+def err_toomany_element_decls : Error<
+  "only one element declaration is allowed">;
+def err_selector_element_not_lvalue : Error<
+  "selector element is not a valid lvalue">;
+def err_selector_element_type : Error<
+  "selector element type %0 is not a valid object">;
+def err_collection_expr_type : Error<
+  "collection expression type %0 is not a valid object">;
+
+def err_invalid_conversion_between_ext_vectors : Error<
+  "invalid conversion between ext-vector type %0 and %1">;
+
+// Type
+def ext_invalid_sign_spec : Extension<"'%0' cannot be signed or unsigned">;
+def warn_receiver_forward_class : Warning<
+    "receiver %0 is a forward class and corresponding @interface may not exist">;
+def note_method_sent_forward_class : Note<"method %0 is used for the forward class">;
+def ext_missing_declspec : ExtWarn<
+  "declaration specifier missing, defaulting to 'int'">;
+def ext_missing_type_specifier : ExtWarn<
+  "type specifier missing, defaults to 'int'">,
+  InGroup<ImplicitInt>;
+def err_decimal_unsupported : Error<
+  "GNU decimal type extension not supported">;
+def err_missing_type_specifier : Error<
+  "C++ requires a type specifier for all declarations">;
+def err_missing_param_declspec : Error<
+  "parameter requires a declaration specifier">;
+def err_objc_array_of_interfaces : Error<
+  "array of interface %0 is invalid (probably should be an array of pointers)">;
+def ext_c99_array_usage : Extension<
+  "use of C99-specific array features, accepted as an extension">;
+def err_c99_array_usage_cxx : Error<
+  "C99-specific array features are not permitted in C++">;
+  
+def note_getter_unavailable : Note<
+  "or because setter is declared here, but no getter method %0 is found">;
+def err_invalid_protocol_qualifiers : Error<
+  "invalid protocol qualifiers on non-ObjC type">;
+def warn_ivar_use_hidden : Warning<
+  "local declaration of %0 hides instance variable">;
+def error_ivar_use_in_class_method : Error<
+  "instance variable %0 accessed in class method">;
+def error_private_ivar_access : Error<"instance variable %0 is private">,
+  NoSFINAE;
+def error_protected_ivar_access : Error<"instance variable %0 is protected">,
+  NoSFINAE;
+def warn_maynot_respond : Warning<"%0 may not respond to %1">;
+def warn_attribute_method_def : Warning<
+  "method attribute can only be specified on method declarations">;
+def ext_typecheck_base_super : Warning<
+  "method parameter type %0 does not match "
+  "super class method parameter type %1">, InGroup<SuperSubClassMismatch>, DefaultIgnore;
+
+// Spell-checking diagnostics
+def err_unknown_typename_suggest : Error<
+  "unknown type name %0; did you mean %1?">;
+def err_unknown_nested_typename_suggest : Error<
+  "no type named %0 in %1; did you mean %2?">;
+def err_no_member_suggest : Error<"no member named %0 in %1; did you mean %2?">;
+def err_undeclared_use_suggest : Error<
+  "use of undeclared %0; did you mean %1?">;
+def err_undeclared_var_use_suggest : Error<
+  "use of undeclared identifier %0; did you mean %1?">;
+def err_no_template_suggest : Error<"no template named %0; did you mean %1?">;
+def err_no_member_template_suggest : Error<
+  "no template named %0 in %1; did you mean %2?">;
+def err_mem_init_not_member_or_class_suggest : Error<
+  "initializer %0 does not name a non-static data member or base "
+  "class; did you mean the %select{base class|member}1 %2?">;
+def err_field_designator_unknown_suggest : Error<
+  "field designator %0 does not refer to any field in type %1; did you mean "
+  "%2?">;
+def err_typecheck_member_reference_ivar_suggest : Error<
+  "%0 does not have a member named %1; did you mean %2?">;
+def err_property_not_found_suggest : Error<
+  "property %0 not found on object of type %1; did you mean %2?">;
+def err_undef_interface_suggest : Error<
+  "cannot find interface declaration for %0; did you mean %1?">;
+def warn_undef_interface_suggest : Warning<
+  "cannot find interface declaration for %0; did you mean %1?">;
+def err_undef_superclass_suggest : Error<
+  "cannot find interface declaration for %0, superclass of %1; did you mean "
+  "%2?">;
+def err_undeclared_protocol_suggest : Error<
+  "cannot find protocol declaration for %0; did you mean %1?">;
+def note_base_class_specified_here : Note<
+  "base class %0 specified here">;
+
+}
+
+
diff --git a/include/clang/Basic/FileManager.h b/include/clang/Basic/FileManager.h
new file mode 100644
index 0000000..d0e0118
--- /dev/null
+++ b/include/clang/Basic/FileManager.h
@@ -0,0 +1,216 @@
+//===--- FileManager.h - File System Probing and Caching --------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the FileManager interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FILEMANAGER_H
+#define LLVM_CLANG_FILEMANAGER_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Config/config.h" // for mode_t
+// FIXME: Enhance libsystem to support inode and other fields in stat.
+#include <sys/types.h>
+#include <sys/stat.h>
+
+namespace clang {
+class FileManager;
+
+/// DirectoryEntry - Cached information about one directory on the disk.
+///
+class DirectoryEntry {
+  const char *Name;   // Name of the directory.
+  friend class FileManager;
+public:
+  DirectoryEntry() : Name(0) {}
+  const char *getName() const { return Name; }
+};
+
+/// FileEntry - Cached information about one file on the disk.
+///
+class FileEntry {
+  const char *Name;           // Name of the file.
+  off_t Size;                 // File size in bytes.
+  time_t ModTime;             // Modification time of file.
+  const DirectoryEntry *Dir;  // Directory file lives in.
+  unsigned UID;               // A unique (small) ID for the file.
+  dev_t Device;               // ID for the device containing the file.
+  ino_t Inode;                // Inode number for the file.
+  mode_t FileMode;            // The file mode as returned by 'stat'.
+  friend class FileManager;
+public:
+  FileEntry(dev_t device, ino_t inode, mode_t m)
+    : Name(0), Device(device), Inode(inode), FileMode(m) {}
+  // Add a default constructor for use with llvm::StringMap
+  FileEntry() : Name(0), Device(0), Inode(0), FileMode(0) {}
+
+  const char *getName() const { return Name; }
+  off_t getSize() const { return Size; }
+  unsigned getUID() const { return UID; }
+  ino_t getInode() const { return Inode; }
+  dev_t getDevice() const { return Device; }
+  time_t getModificationTime() const { return ModTime; }
+  mode_t getFileMode() const { return FileMode; }
+
+  /// getDir - Return the directory the file lives in.
+  ///
+  const DirectoryEntry *getDir() const { return Dir; }
+
+  bool operator<(const FileEntry& RHS) const {
+    return Device < RHS.Device || (Device == RHS.Device && Inode < RHS.Inode);
+  }
+};
+
+/// \brief Abstract interface for introducing a FileManager cache for 'stat'
+/// system calls, which is used by precompiled and pretokenized headers to
+/// improve performance.
+class StatSysCallCache {
+protected:
+  llvm::OwningPtr<StatSysCallCache> NextStatCache;
+  
+public:
+  virtual ~StatSysCallCache() {}
+  virtual int stat(const char *path, struct stat *buf) {
+    if (getNextStatCache())
+      return getNextStatCache()->stat(path, buf);
+    
+    return ::stat(path, buf);
+  }
+  
+  /// \brief Sets the next stat call cache in the chain of stat caches.
+  /// Takes ownership of the given stat cache.
+  void setNextStatCache(StatSysCallCache *Cache) {
+    NextStatCache.reset(Cache);
+  }
+  
+  /// \brief Retrieve the next stat call cache in the chain.
+  StatSysCallCache *getNextStatCache() { return NextStatCache.get(); }
+
+  /// \brief Retrieve the next stat call cache in the chain, transferring
+  /// ownership of this cache (and, transitively, all of the remaining caches)
+  /// to the caller.
+  StatSysCallCache *takeNextStatCache() { return NextStatCache.take(); }
+};
+
+/// \brief A stat "cache" that can be used by FileManager to keep
+/// track of the results of stat() calls that occur throughout the
+/// execution of the front end.
+class MemorizeStatCalls : public StatSysCallCache {
+public:
+  /// \brief The result of a stat() call.
+  ///
+  /// The first member is the result of calling stat(). If stat()
+  /// found something, the second member is a copy of the stat
+  /// structure.
+  typedef std::pair<int, struct stat> StatResult;
+
+  /// \brief The set of stat() calls that have been
+  llvm::StringMap<StatResult, llvm::BumpPtrAllocator> StatCalls;
+
+  typedef llvm::StringMap<StatResult, llvm::BumpPtrAllocator>::const_iterator
+    iterator;
+
+  iterator begin() const { return StatCalls.begin(); }
+  iterator end() const { return StatCalls.end(); }
+
+  virtual int stat(const char *path, struct stat *buf);
+};
+
+/// FileManager - Implements support for file system lookup, file system
+/// caching, and directory search management.  This also handles more advanced
+/// properties, such as uniquing files based on "inode", so that a file with two
+/// names (e.g. symlinked) will be treated as a single file.
+///
+class FileManager {
+
+  class UniqueDirContainer;
+  class UniqueFileContainer;
+
+  /// UniqueDirs/UniqueFiles - Cache for existing directories/files.
+  ///
+  UniqueDirContainer &UniqueDirs;
+  UniqueFileContainer &UniqueFiles;
+
+  /// DirEntries/FileEntries - This is a cache of directory/file entries we have
+  /// looked up.  The actual Entry is owned by UniqueFiles/UniqueDirs above.
+  ///
+  llvm::StringMap<DirectoryEntry*, llvm::BumpPtrAllocator> DirEntries;
+  llvm::StringMap<FileEntry*, llvm::BumpPtrAllocator> FileEntries;
+
+  /// NextFileUID - Each FileEntry we create is assigned a unique ID #.
+  ///
+  unsigned NextFileUID;
+
+  /// \brief The virtual files that we have allocated.
+  llvm::SmallVector<FileEntry *, 4> VirtualFileEntries;
+
+  // Statistics.
+  unsigned NumDirLookups, NumFileLookups;
+  unsigned NumDirCacheMisses, NumFileCacheMisses;
+
+  // Caching.
+  llvm::OwningPtr<StatSysCallCache> StatCache;
+
+  int stat_cached(const char* path, struct stat* buf) {
+    return StatCache.get() ? StatCache->stat(path, buf) : stat(path, buf);
+  }
+
+public:
+  FileManager();
+  ~FileManager();
+
+  /// \brief Installs the provided StatSysCallCache object within
+  /// the FileManager. 
+  ///
+  /// Ownership of this object is transferred to the FileManager.
+  ///
+  /// \param statCache the new stat cache to install. Ownership of this
+  /// object is transferred to the FileManager.
+  ///
+  /// \param AtBeginning whether this new stat cache must be installed at the
+  /// beginning of the chain of stat caches. Otherwise, it will be added to
+  /// the end of the chain.
+  void addStatCache(StatSysCallCache *statCache, bool AtBeginning = false);
+
+  /// \brief Removes the provided StatSysCallCache object from the file manager.
+  void removeStatCache(StatSysCallCache *statCache);
+  
+  /// getDirectory - Lookup, cache, and verify the specified directory.  This
+  /// returns null if the directory doesn't exist.
+  ///
+  const DirectoryEntry *getDirectory(const llvm::StringRef &Filename) {
+    return getDirectory(Filename.begin(), Filename.end());
+  }
+  const DirectoryEntry *getDirectory(const char *FileStart,const char *FileEnd);
+
+  /// getFile - Lookup, cache, and verify the specified file.  This returns null
+  /// if the file doesn't exist.
+  ///
+  const FileEntry *getFile(const llvm::StringRef &Filename) {
+    return getFile(Filename.begin(), Filename.end());
+  }
+  const FileEntry *getFile(const char *FilenameStart,
+                           const char *FilenameEnd);
+
+  /// \brief Retrieve a file entry for a "virtual" file that acts as
+  /// if there were a file with the given name on disk. The file
+  /// itself is not accessed.
+  const FileEntry *getVirtualFile(const llvm::StringRef &Filename,
+                                  off_t Size, time_t ModificationTime);
+  void PrintStats() const;
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Basic/IdentifierTable.h b/include/clang/Basic/IdentifierTable.h
new file mode 100644
index 0000000..582d59c
--- /dev/null
+++ b/include/clang/Basic/IdentifierTable.h
@@ -0,0 +1,569 @@
+//===--- IdentifierTable.h - Hash table for identifier lookup ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the IdentifierInfo, IdentifierTable, and Selector
+// interfaces.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_IDENTIFIERTABLE_H
+#define LLVM_CLANG_BASIC_IDENTIFIERTABLE_H
+
+#include "clang/Basic/OperatorKinds.h"
+#include "clang/Basic/TokenKinds.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/Support/PointerLikeTypeTraits.h"
+#include <string>
+#include <cassert>
+
+namespace llvm {
+  template <typename T> struct DenseMapInfo;
+}
+
+namespace clang {
+  class LangOptions;
+  class IdentifierInfo;
+  class IdentifierTable;
+  class SourceLocation;
+  class MultiKeywordSelector; // private class used by Selector
+  class DeclarationName;      // AST class that stores declaration names
+
+  /// IdentifierLocPair - A simple pair of identifier info and location.
+  typedef std::pair<IdentifierInfo*, SourceLocation> IdentifierLocPair;
+
+
+/// IdentifierInfo - One of these records is kept for each identifier that
+/// is lexed.  This contains information about whether the token was #define'd,
+/// is a language keyword, or if it is a front-end token of some sort (e.g. a
+/// variable or function name).  The preprocessor keeps this information in a
+/// set, and all tok::identifier tokens have a pointer to one of these.
+class IdentifierInfo {
+  // Note: DON'T make TokenID a 'tok::TokenKind'; MSVC will treat it as a
+  //       signed char and TokenKinds > 127 won't be handled correctly.
+  unsigned TokenID            : 8; // Front-end token ID or tok::identifier.
+  // Objective-C keyword ('protocol' in '@protocol') or builtin (__builtin_inf).
+  // First NUM_OBJC_KEYWORDS values are for Objective-C, the remaining values
+  // are for builtins.
+  unsigned ObjCOrBuiltinID    :10;
+  bool HasMacro               : 1; // True if there is a #define for this.
+  bool IsExtension            : 1; // True if identifier is a lang extension.
+  bool IsPoisoned             : 1; // True if identifier is poisoned.
+  bool IsCPPOperatorKeyword   : 1; // True if ident is a C++ operator keyword.
+  bool NeedsHandleIdentifier  : 1; // See "RecomputeNeedsHandleIdentifier".
+  // 9 bits left in 32-bit word.
+  void *FETokenInfo;               // Managed by the language front-end.
+  llvm::StringMapEntry<IdentifierInfo*> *Entry;
+
+  IdentifierInfo(const IdentifierInfo&);  // NONCOPYABLE.
+  void operator=(const IdentifierInfo&);  // NONASSIGNABLE.
+
+  friend class IdentifierTable;
+
+public:
+  IdentifierInfo();
+
+
+  /// isStr - Return true if this is the identifier for the specified string.
+  /// This is intended to be used for string literals only: II->isStr("foo").
+  template <std::size_t StrLen>
+  bool isStr(const char (&Str)[StrLen]) const {
+    return getLength() == StrLen-1 && !memcmp(getNameStart(), Str, StrLen-1);
+  }
+
+  /// getNameStart - Return the beginning of the actual string for this
+  /// identifier.  The returned string is properly null terminated.
+  ///
+  const char *getNameStart() const {
+    if (Entry) return Entry->getKeyData();
+    // FIXME: This is gross. It would be best not to embed specific details
+    // of the PTH file format here.
+    // The 'this' pointer really points to a
+    // std::pair<IdentifierInfo, const char*>, where internal pointer
+    // points to the external string data.
+    return ((std::pair<IdentifierInfo, const char*>*) this)->second;
+  }
+
+  /// getLength - Efficiently return the length of this identifier info.
+  ///
+  unsigned getLength() const {
+    if (Entry) return Entry->getKeyLength();
+    // FIXME: This is gross. It would be best not to embed specific details
+    // of the PTH file format here.
+    // The 'this' pointer really points to a
+    // std::pair<IdentifierInfo, const char*>, where internal pointer
+    // points to the external string data.
+    const char* p = ((std::pair<IdentifierInfo, const char*>*) this)->second-2;
+    return (((unsigned) p[0]) | (((unsigned) p[1]) << 8)) - 1;
+  }
+
+  /// getName - Return the actual identifier string.
+  llvm::StringRef getName() const {
+    return llvm::StringRef(getNameStart(), getLength());
+  }
+
+  /// hasMacroDefinition - Return true if this identifier is #defined to some
+  /// other value.
+  bool hasMacroDefinition() const {
+    return HasMacro;
+  }
+  void setHasMacroDefinition(bool Val) {
+    if (HasMacro == Val) return;
+
+    HasMacro = Val;
+    if (Val)
+      NeedsHandleIdentifier = 1;
+    else
+      RecomputeNeedsHandleIdentifier();
+  }
+
+  /// get/setTokenID - If this is a source-language token (e.g. 'for'), this API
+  /// can be used to cause the lexer to map identifiers to source-language
+  /// tokens.
+  tok::TokenKind getTokenID() const { return (tok::TokenKind)TokenID; }
+  void setTokenID(tok::TokenKind ID) { TokenID = ID; }
+
+  /// getPPKeywordID - Return the preprocessor keyword ID for this identifier.
+  /// For example, "define" will return tok::pp_define.
+  tok::PPKeywordKind getPPKeywordID() const;
+
+  /// getObjCKeywordID - Return the Objective-C keyword ID for the this
+  /// identifier.  For example, 'class' will return tok::objc_class if ObjC is
+  /// enabled.
+  tok::ObjCKeywordKind getObjCKeywordID() const {
+    if (ObjCOrBuiltinID < tok::NUM_OBJC_KEYWORDS)
+      return tok::ObjCKeywordKind(ObjCOrBuiltinID);
+    else
+      return tok::objc_not_keyword;
+  }
+  void setObjCKeywordID(tok::ObjCKeywordKind ID) { ObjCOrBuiltinID = ID; }
+
+  /// getBuiltinID - Return a value indicating whether this is a builtin
+  /// function.  0 is not-built-in.  1 is builtin-for-some-nonprimary-target.
+  /// 2+ are specific builtin functions.
+  unsigned getBuiltinID() const {
+    if (ObjCOrBuiltinID >= tok::NUM_OBJC_KEYWORDS)
+      return ObjCOrBuiltinID - tok::NUM_OBJC_KEYWORDS;
+    else
+      return 0;
+  }
+  void setBuiltinID(unsigned ID) {
+    ObjCOrBuiltinID = ID + tok::NUM_OBJC_KEYWORDS;
+    assert(ObjCOrBuiltinID - unsigned(tok::NUM_OBJC_KEYWORDS) == ID
+           && "ID too large for field!");
+  }
+
+  unsigned getObjCOrBuiltinID() const { return ObjCOrBuiltinID; }
+  void setObjCOrBuiltinID(unsigned ID) { ObjCOrBuiltinID = ID; }
+
+  /// get/setExtension - Initialize information about whether or not this
+  /// language token is an extension.  This controls extension warnings, and is
+  /// only valid if a custom token ID is set.
+  bool isExtensionToken() const { return IsExtension; }
+  void setIsExtensionToken(bool Val) {
+    IsExtension = Val;
+    if (Val)
+      NeedsHandleIdentifier = 1;
+    else
+      RecomputeNeedsHandleIdentifier();
+  }
+
+  /// setIsPoisoned - Mark this identifier as poisoned.  After poisoning, the
+  /// Preprocessor will emit an error every time this token is used.
+  void setIsPoisoned(bool Value = true) {
+    IsPoisoned = Value;
+    if (Value)
+      NeedsHandleIdentifier = 1;
+    else
+      RecomputeNeedsHandleIdentifier();
+  }
+
+  /// isPoisoned - Return true if this token has been poisoned.
+  bool isPoisoned() const { return IsPoisoned; }
+
+  /// isCPlusPlusOperatorKeyword/setIsCPlusPlusOperatorKeyword controls whether
+  /// this identifier is a C++ alternate representation of an operator.
+  void setIsCPlusPlusOperatorKeyword(bool Val = true) {
+    IsCPPOperatorKeyword = Val;
+    if (Val)
+      NeedsHandleIdentifier = 1;
+    else
+      RecomputeNeedsHandleIdentifier();
+  }
+  bool isCPlusPlusOperatorKeyword() const { return IsCPPOperatorKeyword; }
+
+  /// getFETokenInfo/setFETokenInfo - The language front-end is allowed to
+  /// associate arbitrary metadata with this token.
+  template<typename T>
+  T *getFETokenInfo() const { return static_cast<T*>(FETokenInfo); }
+  void setFETokenInfo(void *T) { FETokenInfo = T; }
+
+  /// isHandleIdentifierCase - Return true if the Preprocessor::HandleIdentifier
+  /// must be called on a token of this identifier.  If this returns false, we
+  /// know that HandleIdentifier will not affect the token.
+  bool isHandleIdentifierCase() const { return NeedsHandleIdentifier; }
+
+private:
+  /// RecomputeNeedsHandleIdentifier - The Preprocessor::HandleIdentifier does
+  /// several special (but rare) things to identifiers of various sorts.  For
+  /// example, it changes the "for" keyword token from tok::identifier to
+  /// tok::for.
+  ///
+  /// This method is very tied to the definition of HandleIdentifier.  Any
+  /// change to it should be reflected here.
+  void RecomputeNeedsHandleIdentifier() {
+    NeedsHandleIdentifier =
+      (isPoisoned() | hasMacroDefinition() | isCPlusPlusOperatorKeyword() |
+       isExtensionToken());
+  }
+};
+
+/// IdentifierInfoLookup - An abstract class used by IdentifierTable that
+///  provides an interface for performing lookups from strings
+/// (const char *) to IdentiferInfo objects.
+class IdentifierInfoLookup {
+public:
+  virtual ~IdentifierInfoLookup();
+
+  /// get - Return the identifier token info for the specified named identifier.
+  ///  Unlike the version in IdentifierTable, this returns a pointer instead
+  ///  of a reference.  If the pointer is NULL then the IdentifierInfo cannot
+  ///  be found.
+  virtual IdentifierInfo* get(llvm::StringRef Name) = 0;
+};
+
+/// \brief An abstract class used to resolve numerical identifier
+/// references (meaningful only to some external source) into
+/// IdentifierInfo pointers.
+class ExternalIdentifierLookup {
+public:
+  virtual ~ExternalIdentifierLookup();
+
+  /// \brief Return the identifier associated with the given ID number.
+  ///
+  /// The ID 0 is associated with the NULL identifier.
+  virtual IdentifierInfo *GetIdentifier(unsigned ID) = 0;
+};
+
+/// IdentifierTable - This table implements an efficient mapping from strings to
+/// IdentifierInfo nodes.  It has no other purpose, but this is an
+/// extremely performance-critical piece of the code, as each occurrance of
+/// every identifier goes through here when lexed.
+class IdentifierTable {
+  // Shark shows that using MallocAllocator is *much* slower than using this
+  // BumpPtrAllocator!
+  typedef llvm::StringMap<IdentifierInfo*, llvm::BumpPtrAllocator> HashTableTy;
+  HashTableTy HashTable;
+
+  IdentifierInfoLookup* ExternalLookup;
+
+public:
+  /// IdentifierTable ctor - Create the identifier table, populating it with
+  /// info about the language keywords for the language specified by LangOpts.
+  IdentifierTable(const LangOptions &LangOpts,
+                  IdentifierInfoLookup* externalLookup = 0);
+
+  /// \brief Set the external identifier lookup mechanism.
+  void setExternalIdentifierLookup(IdentifierInfoLookup *IILookup) {
+    ExternalLookup = IILookup;
+  }
+
+  llvm::BumpPtrAllocator& getAllocator() {
+    return HashTable.getAllocator();
+  }
+
+  /// get - Return the identifier token info for the specified named identifier.
+  ///
+  IdentifierInfo &get(llvm::StringRef Name) {
+    llvm::StringMapEntry<IdentifierInfo*> &Entry =
+      HashTable.GetOrCreateValue(Name);
+
+    IdentifierInfo *II = Entry.getValue();
+    if (II) return *II;
+
+    // No entry; if we have an external lookup, look there first.
+    if (ExternalLookup) {
+      II = ExternalLookup->get(Name);
+      if (II) {
+        // Cache in the StringMap for subsequent lookups.
+        Entry.setValue(II);
+        return *II;
+      }
+    }
+
+    // Lookups failed, make a new IdentifierInfo.
+    void *Mem = getAllocator().Allocate<IdentifierInfo>();
+    II = new (Mem) IdentifierInfo();
+    Entry.setValue(II);
+
+    // Make sure getName() knows how to find the IdentifierInfo
+    // contents.
+    II->Entry = &Entry;
+
+    return *II;
+  }
+
+  IdentifierInfo &get(const char *NameStart, const char *NameEnd) {
+    return get(llvm::StringRef(NameStart, NameEnd-NameStart));
+  }
+
+  IdentifierInfo &get(const char *Name, size_t NameLen) {
+    return get(llvm::StringRef(Name, NameLen));
+  }
+
+  /// \brief Creates a new IdentifierInfo from the given string.
+  ///
+  /// This is a lower-level version of get() that requires that this
+  /// identifier not be known previously and that does not consult an
+  /// external source for identifiers. In particular, external
+  /// identifier sources can use this routine to build IdentifierInfo
+  /// nodes and then introduce additional information about those
+  /// identifiers.
+  IdentifierInfo &CreateIdentifierInfo(const char *NameStart,
+                                       const char *NameEnd) {
+    llvm::StringMapEntry<IdentifierInfo*> &Entry =
+      HashTable.GetOrCreateValue(NameStart, NameEnd);
+
+    IdentifierInfo *II = Entry.getValue();
+    assert(!II && "IdentifierInfo already exists");
+
+    // Lookups failed, make a new IdentifierInfo.
+    void *Mem = getAllocator().Allocate<IdentifierInfo>();
+    II = new (Mem) IdentifierInfo();
+    Entry.setValue(II);
+
+    // Make sure getName() knows how to find the IdentifierInfo
+    // contents.
+    II->Entry = &Entry;
+
+    return *II;
+  }
+  IdentifierInfo &CreateIdentifierInfo(llvm::StringRef Name) {
+    return CreateIdentifierInfo(Name.begin(), Name.end());
+  }
+
+  typedef HashTableTy::const_iterator iterator;
+  typedef HashTableTy::const_iterator const_iterator;
+
+  iterator begin() const { return HashTable.begin(); }
+  iterator end() const   { return HashTable.end(); }
+  unsigned size() const { return HashTable.size(); }
+
+  /// PrintStats - Print some statistics to stderr that indicate how well the
+  /// hashing is doing.
+  void PrintStats() const;
+
+  void AddKeywords(const LangOptions &LangOpts);
+};
+
+/// Selector - This smart pointer class efficiently represents Objective-C
+/// method names. This class will either point to an IdentifierInfo or a
+/// MultiKeywordSelector (which is private). This enables us to optimize
+/// selectors that take no arguments and selectors that take 1 argument, which
+/// accounts for 78% of all selectors in Cocoa.h.
+class Selector {
+  friend class DiagnosticInfo;
+
+  enum IdentifierInfoFlag {
+    // MultiKeywordSelector = 0.
+    ZeroArg  = 0x1,
+    OneArg   = 0x2,
+    ArgFlags = ZeroArg|OneArg
+  };
+  uintptr_t InfoPtr; // a pointer to the MultiKeywordSelector or IdentifierInfo.
+
+  Selector(IdentifierInfo *II, unsigned nArgs) {
+    InfoPtr = reinterpret_cast<uintptr_t>(II);
+    assert((InfoPtr & ArgFlags) == 0 &&"Insufficiently aligned IdentifierInfo");
+    assert(nArgs < 2 && "nArgs not equal to 0/1");
+    InfoPtr |= nArgs+1;
+  }
+  Selector(MultiKeywordSelector *SI) {
+    InfoPtr = reinterpret_cast<uintptr_t>(SI);
+    assert((InfoPtr & ArgFlags) == 0 &&"Insufficiently aligned IdentifierInfo");
+  }
+
+  IdentifierInfo *getAsIdentifierInfo() const {
+    if (getIdentifierInfoFlag())
+      return reinterpret_cast<IdentifierInfo *>(InfoPtr & ~ArgFlags);
+    return 0;
+  }
+  unsigned getIdentifierInfoFlag() const {
+    return InfoPtr & ArgFlags;
+  }
+
+public:
+  friend class SelectorTable; // only the SelectorTable can create these
+  friend class DeclarationName; // and the AST's DeclarationName.
+
+  /// The default ctor should only be used when creating data structures that
+  ///  will contain selectors.
+  Selector() : InfoPtr(0) {}
+  Selector(uintptr_t V) : InfoPtr(V) {}
+
+  /// operator==/!= - Indicate whether the specified selectors are identical.
+  bool operator==(Selector RHS) const {
+    return InfoPtr == RHS.InfoPtr;
+  }
+  bool operator!=(Selector RHS) const {
+    return InfoPtr != RHS.InfoPtr;
+  }
+  void *getAsOpaquePtr() const {
+    return reinterpret_cast<void*>(InfoPtr);
+  }
+
+  /// \brief Determine whether this is the empty selector.
+  bool isNull() const { return InfoPtr == 0; }
+
+  // Predicates to identify the selector type.
+  bool isKeywordSelector() const {
+    return getIdentifierInfoFlag() != ZeroArg;
+  }
+  bool isUnarySelector() const {
+    return getIdentifierInfoFlag() == ZeroArg;
+  }
+  unsigned getNumArgs() const;
+  IdentifierInfo *getIdentifierInfoForSlot(unsigned argIndex) const;
+
+  /// getAsString - Derive the full selector name (e.g. "foo:bar:") and return
+  /// it as an std::string.
+  std::string getAsString() const;
+
+  static Selector getEmptyMarker() {
+    return Selector(uintptr_t(-1));
+  }
+  static Selector getTombstoneMarker() {
+    return Selector(uintptr_t(-2));
+  }
+};
+
+/// SelectorTable - This table allows us to fully hide how we implement
+/// multi-keyword caching.
+class SelectorTable {
+  void *Impl;  // Actually a SelectorTableImpl
+  SelectorTable(const SelectorTable&); // DISABLED: DO NOT IMPLEMENT
+  void operator=(const SelectorTable&); // DISABLED: DO NOT IMPLEMENT
+public:
+  SelectorTable();
+  ~SelectorTable();
+
+  /// getSelector - This can create any sort of selector.  NumArgs indicates
+  /// whether this is a no argument selector "foo", a single argument selector
+  /// "foo:" or multi-argument "foo:bar:".
+  Selector getSelector(unsigned NumArgs, IdentifierInfo **IIV);
+
+  Selector getUnarySelector(IdentifierInfo *ID) {
+    return Selector(ID, 1);
+  }
+  Selector getNullarySelector(IdentifierInfo *ID) {
+    return Selector(ID, 0);
+  }
+
+  /// constructSetterName - Return the setter name for the given
+  /// identifier, i.e. "set" + Name where the initial character of Name
+  /// has been capitalized.
+  static Selector constructSetterName(IdentifierTable &Idents,
+                                      SelectorTable &SelTable,
+                                      const IdentifierInfo *Name) {
+    llvm::SmallString<100> SelectorName;
+    SelectorName = "set";
+    SelectorName += Name->getName();
+    SelectorName[3] = toupper(SelectorName[3]);
+    IdentifierInfo *SetterName = &Idents.get(SelectorName);
+    return SelTable.getUnarySelector(SetterName);
+  }
+};
+
+/// DeclarationNameExtra - Common base of the MultiKeywordSelector,
+/// CXXSpecialName, and CXXOperatorIdName classes, all of which are
+/// private classes that describe different kinds of names.
+class DeclarationNameExtra {
+public:
+  /// ExtraKind - The kind of "extra" information stored in the
+  /// DeclarationName. See @c ExtraKindOrNumArgs for an explanation of
+  /// how these enumerator values are used.
+  enum ExtraKind {
+    CXXConstructor = 0,
+    CXXDestructor,
+    CXXConversionFunction,
+#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
+    CXXOperator##Name,
+#include "clang/Basic/OperatorKinds.def"
+    CXXLiteralOperator,
+    CXXUsingDirective,
+    NUM_EXTRA_KINDS
+  };
+
+  /// ExtraKindOrNumArgs - Either the kind of C++ special name or
+  /// operator-id (if the value is one of the CXX* enumerators of
+  /// ExtraKind), in which case the DeclarationNameExtra is also a
+  /// CXXSpecialName, (for CXXConstructor, CXXDestructor, or
+  /// CXXConversionFunction) CXXOperatorIdName, or CXXLiteralOperatorName,
+  /// it may be also name common to C++ using-directives (CXXUsingDirective),
+  /// otherwise it is NUM_EXTRA_KINDS+NumArgs, where NumArgs is the number of
+  /// arguments in the Objective-C selector, in which case the
+  /// DeclarationNameExtra is also a MultiKeywordSelector.
+  unsigned ExtraKindOrNumArgs;
+};
+
+}  // end namespace clang
+
+namespace llvm {
+/// Define DenseMapInfo so that Selectors can be used as keys in DenseMap and
+/// DenseSets.
+template <>
+struct DenseMapInfo<clang::Selector> {
+  static inline clang::Selector getEmptyKey() {
+    return clang::Selector::getEmptyMarker();
+  }
+  static inline clang::Selector getTombstoneKey() {
+    return clang::Selector::getTombstoneMarker();
+  }
+
+  static unsigned getHashValue(clang::Selector S);
+
+  static bool isEqual(clang::Selector LHS, clang::Selector RHS) {
+    return LHS == RHS;
+  }
+};
+
+template <>
+struct isPodLike<clang::Selector> { static const bool value = true; };
+
+
+// Provide PointerLikeTypeTraits for IdentifierInfo pointers, which
+// are not guaranteed to be 8-byte aligned.
+template<>
+class PointerLikeTypeTraits<clang::IdentifierInfo*> {
+public:
+  static inline void *getAsVoidPointer(clang::IdentifierInfo* P) {
+    return P;
+  }
+  static inline clang::IdentifierInfo *getFromVoidPointer(void *P) {
+    return static_cast<clang::IdentifierInfo*>(P);
+  }
+  enum { NumLowBitsAvailable = 1 };
+};
+
+template<>
+class PointerLikeTypeTraits<const clang::IdentifierInfo*> {
+public:
+  static inline const void *getAsVoidPointer(const clang::IdentifierInfo* P) {
+    return P;
+  }
+  static inline const clang::IdentifierInfo *getFromVoidPointer(const void *P) {
+    return static_cast<const clang::IdentifierInfo*>(P);
+  }
+  enum { NumLowBitsAvailable = 1 };
+};
+
+}  // end namespace llvm
+#endif
diff --git a/include/clang/Basic/LangOptions.h b/include/clang/Basic/LangOptions.h
new file mode 100644
index 0000000..f88b0ef
--- /dev/null
+++ b/include/clang/Basic/LangOptions.h
@@ -0,0 +1,202 @@
+//===--- LangOptions.h - C Language Family Language Options -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the LangOptions interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LANGOPTIONS_H
+#define LLVM_CLANG_LANGOPTIONS_H
+
+#include <string>
+
+namespace clang {
+
+/// LangOptions - This class keeps track of the various options that can be
+/// enabled, which controls the dialect of C that is accepted.
+class LangOptions {
+public:
+  unsigned Trigraphs         : 1;  // Trigraphs in source files.
+  unsigned BCPLComment       : 1;  // BCPL-style '//' comments.
+  unsigned Bool              : 1;  // 'bool', 'true', 'false' keywords.
+  unsigned DollarIdents      : 1;  // '$' allowed in identifiers.
+  unsigned AsmPreprocessor   : 1;  // Preprocessor in asm mode.
+  unsigned GNUMode           : 1;  // True in gnu99 mode false in c99 mode (etc)
+  unsigned GNUKeywords       : 1;  // True if GNU-only keywords are allowed
+  unsigned ImplicitInt       : 1;  // C89 implicit 'int'.
+  unsigned Digraphs          : 1;  // C94, C99 and C++
+  unsigned HexFloats         : 1;  // C99 Hexadecimal float constants.
+  unsigned C99               : 1;  // C99 Support
+  unsigned Microsoft         : 1;  // Microsoft extensions.
+  unsigned CPlusPlus         : 1;  // C++ Support
+  unsigned CPlusPlus0x       : 1;  // C++0x Support
+  unsigned CXXOperatorNames  : 1;  // Treat C++ operator names as keywords.
+
+  unsigned ObjC1             : 1;  // Objective-C 1 support enabled.
+  unsigned ObjC2             : 1;  // Objective-C 2 support enabled.
+  unsigned ObjCNonFragileABI : 1;  // Objective-C modern abi enabled
+  unsigned ObjCNonFragileABI2 : 1;  // Objective-C enhanced modern abi enabled
+
+  unsigned PascalStrings     : 1;  // Allow Pascal strings
+  unsigned WritableStrings   : 1;  // Allow writable strings
+  unsigned ConstStrings      : 1;  // Add const qualifier to strings (-Wwrite-strings)
+  unsigned LaxVectorConversions : 1;
+  unsigned AltiVec           : 1;  // Support AltiVec-style vector initializers.
+  unsigned Exceptions        : 1;  // Support exception handling.
+  unsigned SjLjExceptions    : 1;  // Use setjmp-longjump exception handling.
+  unsigned RTTI              : 1;  // Support RTTI information.
+
+  unsigned NeXTRuntime       : 1; // Use NeXT runtime.
+  unsigned Freestanding      : 1; // Freestanding implementation
+  unsigned NoBuiltin         : 1; // Do not use builtin functions (-fno-builtin)
+
+  unsigned ThreadsafeStatics : 1; // Whether static initializers are protected
+                                  // by locks.
+  unsigned POSIXThreads      : 1; // Compiling with POSIX thread support
+                                  // (-pthread)
+  unsigned Blocks            : 1; // block extension to C
+  unsigned EmitAllDecls      : 1; // Emit all declarations, even if
+                                  // they are unused.
+  unsigned MathErrno         : 1; // Math functions must respect errno
+                                  // (modulo the platform support).
+
+  unsigned OverflowChecking  : 1; // Extension to call a handler function when
+                                  // signed integer arithmetic overflows.
+
+  unsigned HeinousExtensions : 1; // Extensions that we really don't like and
+                                  // may be ripped out at any time.
+
+  unsigned Optimize          : 1; // Whether __OPTIMIZE__ should be defined.
+  unsigned OptimizeSize      : 1; // Whether __OPTIMIZE_SIZE__ should be
+                                  // defined.
+  unsigned Static            : 1; // Should __STATIC__ be defined (as
+                                  // opposed to __DYNAMIC__).
+  unsigned PICLevel          : 2; // The value for __PIC__, if non-zero.
+
+  unsigned GNUInline         : 1; // Should GNU inline semantics be
+                                  // used (instead of C99 semantics).
+  unsigned NoInline          : 1; // Should __NO_INLINE__ be defined.
+
+  unsigned ObjCGCBitmapPrint : 1; // Enable printing of gc's bitmap layout
+                                  // for __weak/__strong ivars.
+
+  unsigned AccessControl     : 1; // Whether C++ access control should
+                                  // be enabled.
+  unsigned CharIsSigned      : 1; // Whether char is a signed or unsigned type
+  unsigned ShortWChar        : 1; // Force wchar_t to be unsigned short int.
+
+  unsigned OpenCL            : 1; // OpenCL C99 language extensions.
+  
+  unsigned AssumeSaneOperatorNew : 1; // Whether to add __attribute__((malloc))
+                                      // to the declaration of C++'s new
+                                      // operators
+  unsigned ElideConstructors : 1; // Whether C++ copy constructors should be
+                                  // elided if possible.
+  unsigned CatchUndefined    : 1; // Generate code to check for undefined ops.
+  unsigned DumpRecordLayouts : 1; /// Dump the layout of IRgen'd records.
+  unsigned DumpVTableLayouts : 1; /// Dump the layouts of emitted vtables.
+  unsigned NoConstantCFStrings : 1;  // Do not do CF strings
+
+  // FIXME: This is just a temporary option, for testing purposes.
+  unsigned NoBitFieldTypeAlign : 1;
+
+private:
+  unsigned GC : 2;                // Objective-C Garbage Collection modes.  We
+                                  // declare this enum as unsigned because MSVC
+                                  // insists on making enums signed.  Set/Query
+                                  // this value using accessors.
+  unsigned SymbolVisibility  : 3; // Symbol's visibility.
+  unsigned StackProtector    : 2; // Whether stack protectors are on. We declare
+                                  // this enum as unsigned because MSVC insists
+                                  // on making enums signed.  Set/Query this
+                                  // value using accessors.
+
+public:
+  unsigned InstantiationDepth;    // Maximum template instantiation depth.
+
+  std::string ObjCConstantStringClass;
+
+  enum GCMode { NonGC, GCOnly, HybridGC };
+  enum StackProtectorMode { SSPOff, SSPOn, SSPReq };
+  enum VisibilityMode {
+    Default,
+    Protected,
+    Hidden
+  };
+
+  LangOptions() {
+    Trigraphs = BCPLComment = Bool = DollarIdents = AsmPreprocessor = 0;
+    GNUMode = GNUKeywords = ImplicitInt = Digraphs = 0;
+    HexFloats = 0;
+    GC = ObjC1 = ObjC2 = ObjCNonFragileABI = ObjCNonFragileABI2 = 0;
+    NoConstantCFStrings = 0;
+    C99 = Microsoft = CPlusPlus = CPlusPlus0x = 0;
+    CXXOperatorNames = PascalStrings = WritableStrings = ConstStrings = 0;
+    Exceptions = SjLjExceptions = Freestanding = NoBuiltin = 0;
+    NeXTRuntime = 1;
+    RTTI = 1;
+    LaxVectorConversions = 1;
+    HeinousExtensions = 0;
+    AltiVec = OpenCL = StackProtector = 0;
+
+    SymbolVisibility = (unsigned) Default;
+
+    ThreadsafeStatics = 1;
+    POSIXThreads = 0;
+    Blocks = 0;
+    EmitAllDecls = 0;
+    MathErrno = 1;
+
+    AssumeSaneOperatorNew = 1;
+
+    // FIXME: The default should be 1.
+    AccessControl = 0;
+    ElideConstructors = 1;
+
+    OverflowChecking = 0;
+    ObjCGCBitmapPrint = 0;
+
+    InstantiationDepth = 500;
+
+    Optimize = 0;
+    OptimizeSize = 0;
+
+    Static = 0;
+    PICLevel = 0;
+
+    GNUInline = 0;
+    NoInline = 0;
+
+    CharIsSigned = 1;
+    ShortWChar = 0;
+    CatchUndefined = 0;
+    DumpRecordLayouts = 0;
+    DumpVTableLayouts = 0;
+    NoBitFieldTypeAlign = 0;
+  }
+
+  GCMode getGCMode() const { return (GCMode) GC; }
+  void setGCMode(GCMode m) { GC = (unsigned) m; }
+
+  StackProtectorMode getStackProtectorMode() const {
+    return static_cast<StackProtectorMode>(StackProtector);
+  }
+  void setStackProtectorMode(StackProtectorMode m) {
+    StackProtector = static_cast<unsigned>(m);
+  }
+
+  VisibilityMode getVisibilityMode() const {
+    return (VisibilityMode) SymbolVisibility;
+  }
+  void setVisibilityMode(VisibilityMode v) { SymbolVisibility = (unsigned) v; }
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Basic/Linkage.h b/include/clang/Basic/Linkage.h
new file mode 100644
index 0000000..de0de34
--- /dev/null
+++ b/include/clang/Basic/Linkage.h
@@ -0,0 +1,57 @@
+//===--- Linkage.h - Linkage enumeration and utilities ----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the Linkage enumeration and various utility
+// functions.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_BASIC_LINKAGE_H
+#define LLVM_CLANG_BASIC_LINKAGE_H
+
+namespace clang {
+
+/// \brief Describes the different kinds of linkage 
+/// (C++ [basic.link], C99 6.2.2) that an entity may have.
+enum Linkage {
+  /// \brief No linkage, which means that the entity is unique and
+  /// can only be referred to from within its scope.
+  NoLinkage = 0,
+
+  /// \brief Internal linkage, which indicates that the entity can
+  /// be referred to from within the translation unit (but not other
+  /// translation units).
+  InternalLinkage,
+
+  /// \brief External linkage within a unique namespace. From the
+  /// langauge perspective, these entities have external
+  /// linkage. However, since they reside in an anonymous namespace,
+  /// their names are unique to this translation unit, which is
+  /// equivalent to having internal linkage from the code-generation
+  /// point of view.
+  UniqueExternalLinkage,
+
+  /// \brief External linkage, which indicates that the entity can
+  /// be referred to from other translation units.
+  ExternalLinkage
+};
+
+/// \brief Determine whether the given linkage is semantically
+/// external.
+inline bool isExternalLinkage(Linkage L) {
+  return L == UniqueExternalLinkage || L == ExternalLinkage;
+}
+
+/// \brief Compute the minimum linkage given two linages.
+static inline Linkage minLinkage(Linkage L1, Linkage L2) {
+  return L1 < L2? L1 : L2;
+}
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_BASIC_LINKAGE_H
diff --git a/include/clang/Basic/MacroBuilder.h b/include/clang/Basic/MacroBuilder.h
new file mode 100644
index 0000000..3287b30
--- /dev/null
+++ b/include/clang/Basic/MacroBuilder.h
@@ -0,0 +1,46 @@
+//===--- MacroBuilder.h - CPP Macro building utility ------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the MacroBuilder utility class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_MACROBUILDER_H
+#define LLVM_CLANG_BASIC_MACROBUILDER_H
+
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace clang {
+
+class MacroBuilder {
+  llvm::raw_ostream &Out;
+public:
+  MacroBuilder(llvm::raw_ostream &Output) : Out(Output) {}
+
+  /// Append a #define line for macro of the form "#define Name Value\n".
+  void defineMacro(const llvm::Twine &Name, const llvm::Twine &Value = "1") {
+    Out << "#define " << Name << ' ' << Value << '\n';
+  }
+
+  /// Append a #undef line for Name.  Name should be of the form XXX
+  /// and we emit "#undef XXX".
+  void undefineMacro(const llvm::Twine &Name) {
+    Out << "#undef " << Name << '\n';
+  }
+
+  /// Directly append Str and a newline to the underlying buffer.
+  void append(const llvm::Twine &Str) {
+    Out << Str << '\n';
+  }
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Basic/Makefile b/include/clang/Basic/Makefile
new file mode 100644
index 0000000..48f7f9d
--- /dev/null
+++ b/include/clang/Basic/Makefile
@@ -0,0 +1,22 @@
+LEVEL = ../../../../..
+BUILT_SOURCES = DiagnosticAnalysisKinds.inc DiagnosticASTKinds.inc \
+	DiagnosticCommonKinds.inc DiagnosticDriverKinds.inc \
+	DiagnosticFrontendKinds.inc DiagnosticLexKinds.inc \
+	DiagnosticParseKinds.inc DiagnosticSemaKinds.inc \
+        DiagnosticGroups.inc
+
+TABLEGEN_INC_FILES_COMMON = 1
+
+include $(LEVEL)/Makefile.common
+
+INPUT_TDS = $(wildcard $(PROJ_SRC_DIR)/Diagnostic*.td)
+
+$(ObjDir)/Diagnostic%Kinds.inc.tmp : Diagnostic.td Diagnostic%Kinds.td $(TBLGEN) $(ObjDir)/.dir
+	$(Echo) "Building Clang $(patsubst Diagnostic%Kinds.inc.tmp,%,$(@F)) diagnostic tables with tblgen"
+	$(Verb) $(TableGen) -gen-clang-diags-defs -clang-component=$(patsubst Diagnostic%Kinds.inc.tmp,%,$(@F)) -o $(call SYSPATH, $@) $<
+
+$(ObjDir)/DiagnosticGroups.inc.tmp : Diagnostic.td DiagnosticGroups.td $(INPUT_TDS) $(TBLGEN) $(ObjDir)/.dir
+	$(Echo) "Building Clang diagnostic groups with tblgen"
+	$(Verb) $(TableGen) -gen-clang-diag-groups -o $(call SYSPATH, $@) $<
+
+
diff --git a/include/clang/Basic/OnDiskHashTable.h b/include/clang/Basic/OnDiskHashTable.h
new file mode 100644
index 0000000..2019e27
--- /dev/null
+++ b/include/clang/Basic/OnDiskHashTable.h
@@ -0,0 +1,347 @@
+//===--- OnDiskHashTable.h - On-Disk Hash Table Implementation --*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines facilities for reading and writing on-disk hash
+//  tables.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_BASIC_ON_DISK_HASH_TABLE_H
+#define LLVM_CLANG_BASIC_ON_DISK_HASH_TABLE_H
+
+#include "llvm/Support/Allocator.h"
+#include "llvm/System/DataTypes.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/System/Host.h"
+#include <cassert>
+#include <cstdlib>
+
+namespace clang {
+
+namespace io {
+
+typedef uint32_t Offset;
+
+inline void Emit8(llvm::raw_ostream& Out, uint32_t V) {
+  Out << (unsigned char)(V);
+}
+
+inline void Emit16(llvm::raw_ostream& Out, uint32_t V) {
+  Out << (unsigned char)(V);
+  Out << (unsigned char)(V >>  8);
+  assert((V >> 16) == 0);
+}
+
+inline void Emit24(llvm::raw_ostream& Out, uint32_t V) {
+  Out << (unsigned char)(V);
+  Out << (unsigned char)(V >>  8);
+  Out << (unsigned char)(V >> 16);
+  assert((V >> 24) == 0);
+}
+
+inline void Emit32(llvm::raw_ostream& Out, uint32_t V) {
+  Out << (unsigned char)(V);
+  Out << (unsigned char)(V >>  8);
+  Out << (unsigned char)(V >> 16);
+  Out << (unsigned char)(V >> 24);
+}
+
+inline void Emit64(llvm::raw_ostream& Out, uint64_t V) {
+  Out << (unsigned char)(V);
+  Out << (unsigned char)(V >>  8);
+  Out << (unsigned char)(V >> 16);
+  Out << (unsigned char)(V >> 24);
+  Out << (unsigned char)(V >> 32);
+  Out << (unsigned char)(V >> 40);
+  Out << (unsigned char)(V >> 48);
+  Out << (unsigned char)(V >> 56);
+}
+
+inline void Pad(llvm::raw_ostream& Out, unsigned A) {
+  Offset off = (Offset) Out.tell();
+  uint32_t n = ((uintptr_t)(off+A-1) & ~(uintptr_t)(A-1)) - off;
+  for (; n ; --n)
+    Emit8(Out, 0);
+}
+
+inline uint16_t ReadUnalignedLE16(const unsigned char *&Data) {
+  uint16_t V = ((uint16_t)Data[0]) |
+               ((uint16_t)Data[1] <<  8);
+  Data += 2;
+  return V;
+}
+
+inline uint32_t ReadUnalignedLE32(const unsigned char *&Data) {
+  uint32_t V = ((uint32_t)Data[0])  |
+               ((uint32_t)Data[1] << 8)  |
+               ((uint32_t)Data[2] << 16) |
+               ((uint32_t)Data[3] << 24);
+  Data += 4;
+  return V;
+}
+
+inline uint64_t ReadUnalignedLE64(const unsigned char *&Data) {
+  uint64_t V = ((uint64_t)Data[0])  |
+    ((uint64_t)Data[1] << 8)  |
+    ((uint64_t)Data[2] << 16) |
+    ((uint64_t)Data[3] << 24) |
+    ((uint64_t)Data[4] << 32) |
+    ((uint64_t)Data[5] << 40) |
+    ((uint64_t)Data[6] << 48) |
+    ((uint64_t)Data[7] << 56);
+  Data += 8;
+  return V;
+}
+
+inline uint32_t ReadLE32(const unsigned char *&Data) {
+  // Hosts that directly support little-endian 32-bit loads can just
+  // use them.  Big-endian hosts need a bswap.
+  uint32_t V = *((uint32_t*)Data);
+  if (llvm::sys::isBigEndianHost())
+    V = llvm::ByteSwap_32(V);
+  Data += 4;
+  return V;
+}
+
+} // end namespace io
+
+template<typename Info>
+class OnDiskChainedHashTableGenerator {
+  unsigned NumBuckets;
+  unsigned NumEntries;
+  llvm::BumpPtrAllocator BA;
+
+  class Item {
+  public:
+    typename Info::key_type key;
+    typename Info::data_type data;
+    Item *next;
+    const uint32_t hash;
+
+    Item(typename Info::key_type_ref k, typename Info::data_type_ref d)
+    : key(k), data(d), next(0), hash(Info::ComputeHash(k)) {}
+  };
+
+  class Bucket {
+  public:
+    io::Offset off;
+    Item*  head;
+    unsigned length;
+
+    Bucket() {}
+  };
+
+  Bucket* Buckets;
+
+private:
+  void insert(Bucket* b, size_t size, Item* E) {
+    unsigned idx = E->hash & (size - 1);
+    Bucket& B = b[idx];
+    E->next = B.head;
+    ++B.length;
+    B.head = E;
+  }
+
+  void resize(size_t newsize) {
+    Bucket* newBuckets = (Bucket*) std::calloc(newsize, sizeof(Bucket));
+    // Populate newBuckets with the old entries.
+    for (unsigned i = 0; i < NumBuckets; ++i)
+      for (Item* E = Buckets[i].head; E ; ) {
+        Item* N = E->next;
+        E->next = 0;
+        insert(newBuckets, newsize, E);
+        E = N;
+      }
+
+    free(Buckets);
+    NumBuckets = newsize;
+    Buckets = newBuckets;
+  }
+
+public:
+
+  void insert(typename Info::key_type_ref key,
+              typename Info::data_type_ref data) {
+
+    ++NumEntries;
+    if (4*NumEntries >= 3*NumBuckets) resize(NumBuckets*2);
+    insert(Buckets, NumBuckets, new (BA.Allocate<Item>()) Item(key, data));
+  }
+
+  io::Offset Emit(llvm::raw_ostream &out) {
+    Info InfoObj;
+    return Emit(out, InfoObj);
+  }
+
+  io::Offset Emit(llvm::raw_ostream &out, Info &InfoObj) {
+    using namespace clang::io;
+
+    // Emit the payload of the table.
+    for (unsigned i = 0; i < NumBuckets; ++i) {
+      Bucket& B = Buckets[i];
+      if (!B.head) continue;
+
+      // Store the offset for the data of this bucket.
+      B.off = out.tell();
+      assert(B.off && "Cannot write a bucket at offset 0. Please add padding.");
+
+      // Write out the number of items in the bucket.
+      Emit16(out, B.length);
+
+      // Write out the entries in the bucket.
+      for (Item *I = B.head; I ; I = I->next) {
+        Emit32(out, I->hash);
+        const std::pair<unsigned, unsigned>& Len =
+          InfoObj.EmitKeyDataLength(out, I->key, I->data);
+        InfoObj.EmitKey(out, I->key, Len.first);
+        InfoObj.EmitData(out, I->key, I->data, Len.second);
+      }
+    }
+
+    // Emit the hashtable itself.
+    Pad(out, 4);
+    io::Offset TableOff = out.tell();
+    Emit32(out, NumBuckets);
+    Emit32(out, NumEntries);
+    for (unsigned i = 0; i < NumBuckets; ++i) Emit32(out, Buckets[i].off);
+
+    return TableOff;
+  }
+
+  OnDiskChainedHashTableGenerator() {
+    NumEntries = 0;
+    NumBuckets = 64;
+    // Note that we do not need to run the constructors of the individual
+    // Bucket objects since 'calloc' returns bytes that are all 0.
+    Buckets = (Bucket*) std::calloc(NumBuckets, sizeof(Bucket));
+  }
+
+  ~OnDiskChainedHashTableGenerator() {
+    std::free(Buckets);
+  }
+};
+
+template<typename Info>
+class OnDiskChainedHashTable {
+  const unsigned NumBuckets;
+  const unsigned NumEntries;
+  const unsigned char* const Buckets;
+  const unsigned char* const Base;
+  Info InfoObj;
+
+public:
+  typedef typename Info::internal_key_type internal_key_type;
+  typedef typename Info::external_key_type external_key_type;
+  typedef typename Info::data_type         data_type;
+
+  OnDiskChainedHashTable(unsigned numBuckets, unsigned numEntries,
+                         const unsigned char* buckets,
+                         const unsigned char* base,
+                         const Info &InfoObj = Info())
+    : NumBuckets(numBuckets), NumEntries(numEntries),
+      Buckets(buckets), Base(base), InfoObj(InfoObj) {
+        assert((reinterpret_cast<uintptr_t>(buckets) & 0x3) == 0 &&
+               "'buckets' must have a 4-byte alignment");
+      }
+
+  unsigned getNumBuckets() const { return NumBuckets; }
+  unsigned getNumEntries() const { return NumEntries; }
+  const unsigned char* getBase() const { return Base; }
+  const unsigned char* getBuckets() const { return Buckets; }
+
+  bool isEmpty() const { return NumEntries == 0; }
+
+  class iterator {
+    internal_key_type key;
+    const unsigned char* const data;
+    const unsigned len;
+    Info *InfoObj;
+  public:
+    iterator() : data(0), len(0) {}
+    iterator(const internal_key_type k, const unsigned char* d, unsigned l,
+             Info *InfoObj)
+      : key(k), data(d), len(l), InfoObj(InfoObj) {}
+
+    data_type operator*() const { return InfoObj->ReadData(key, data, len); }
+    bool operator==(const iterator& X) const { return X.data == data; }
+    bool operator!=(const iterator& X) const { return X.data != data; }
+  };
+
+  iterator find(const external_key_type& eKey, Info *InfoPtr = 0) {
+    if (!InfoPtr)
+      InfoPtr = &InfoObj;
+
+    using namespace io;
+    const internal_key_type& iKey = Info::GetInternalKey(eKey);
+    unsigned key_hash = Info::ComputeHash(iKey);
+
+    // Each bucket is just a 32-bit offset into the hash table file.
+    unsigned idx = key_hash & (NumBuckets - 1);
+    const unsigned char* Bucket = Buckets + sizeof(uint32_t)*idx;
+
+    unsigned offset = ReadLE32(Bucket);
+    if (offset == 0) return iterator(); // Empty bucket.
+    const unsigned char* Items = Base + offset;
+
+    // 'Items' starts with a 16-bit unsigned integer representing the
+    // number of items in this bucket.
+    unsigned len = ReadUnalignedLE16(Items);
+
+    for (unsigned i = 0; i < len; ++i) {
+      // Read the hash.
+      uint32_t item_hash = ReadUnalignedLE32(Items);
+
+      // Determine the length of the key and the data.
+      const std::pair<unsigned, unsigned>& L = Info::ReadKeyDataLength(Items);
+      unsigned item_len = L.first + L.second;
+
+      // Compare the hashes.  If they are not the same, skip the entry entirely.
+      if (item_hash != key_hash) {
+        Items += item_len;
+        continue;
+      }
+
+      // Read the key.
+      const internal_key_type& X =
+        InfoPtr->ReadKey((const unsigned char* const) Items, L.first);
+
+      // If the key doesn't match just skip reading the value.
+      if (!Info::EqualKey(X, iKey)) {
+        Items += item_len;
+        continue;
+      }
+
+      // The key matches!
+      return iterator(X, Items + L.first, L.second, InfoPtr);
+    }
+
+    return iterator();
+  }
+
+  iterator end() const { return iterator(); }
+
+
+  static OnDiskChainedHashTable* Create(const unsigned char* buckets,
+                                        const unsigned char* const base,
+                                        const Info &InfoObj = Info()) {
+    using namespace io;
+    assert(buckets > base);
+    assert((reinterpret_cast<uintptr_t>(buckets) & 0x3) == 0 &&
+           "buckets should be 4-byte aligned.");
+
+    unsigned numBuckets = ReadLE32(buckets);
+    unsigned numEntries = ReadLE32(buckets);
+    return new OnDiskChainedHashTable<Info>(numBuckets, numEntries, buckets,
+                                            base, InfoObj);
+  }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Basic/OperatorKinds.def b/include/clang/Basic/OperatorKinds.def
new file mode 100644
index 0000000..d011e9d
--- /dev/null
+++ b/include/clang/Basic/OperatorKinds.def
@@ -0,0 +1,106 @@
+//===--- OperatorKinds.def - C++ Overloaded Operator Database ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the OverloadedOperator database, which includes
+// all of the overloadable C++ operators.
+//
+//===----------------------------------------------------------------------===//
+//
+/// @file OperatorKinds.def
+///
+/// In this file, each of the overloadable C++ operators is enumerated
+/// with either the OVERLOADED_OPERATOR or OVERLOADED_OPERATOR_MULTI
+/// macro, each of which can be specified by the code including this
+/// file. OVERLOADED_OPERATOR is used for single-token operators
+/// (e.g., "+"), and has six arguments:
+///
+/// Name: The name of the token. OO_Name will be the name of the
+/// corresponding enumerator in OverloadedOperatorKind in
+/// OperatorKinds.h.
+///
+/// Spelling: A string that provides a canonical spelling for the
+/// operator, e.g., "operator+".
+///
+/// Token: The name of the token that specifies the operator, e.g.,
+/// "plus" for operator+ or "greatergreaterequal" for
+/// "operator>>=". With a "kw_" prefix, the token name can be used as
+/// an enumerator into the TokenKind enumeration.
+///
+/// Unary: True if the operator can be declared as a unary operator.
+///
+/// Binary: True if the operator can be declared as a binary
+/// operator. Note that some operators (e.g., "operator+" and
+/// "operator*") can be both unary and binary.
+///
+/// MemberOnly: True if this operator can only be declared as a
+/// non-static member function. False if the operator can be both a
+/// non-member function and a non-static member function.
+///
+/// OVERLOADED_OPERATOR_MULTI is used to enumerate the multi-token
+/// overloaded operator names, e.g., "operator delete []". The macro
+/// has all of the parameters of OVERLOADED_OPERATOR except Token,
+/// which is omitted.
+
+#ifndef OVERLOADED_OPERATOR
+#  define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly)
+#endif
+
+#ifndef OVERLOADED_OPERATOR_MULTI
+#  define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly) \
+    OVERLOADED_OPERATOR(Name,Spelling,unknown,Unary,Binary,MemberOnly)
+#endif
+
+OVERLOADED_OPERATOR_MULTI(New            , "new"                      , true , true , false)
+OVERLOADED_OPERATOR_MULTI(Delete         , "delete"                   , true , true , false)
+OVERLOADED_OPERATOR_MULTI(Array_New      , "new[]"                    , true , true , false)
+OVERLOADED_OPERATOR_MULTI(Array_Delete   , "delete[]"                 , true , true , false)
+OVERLOADED_OPERATOR(Plus                 , "+"   , plus               , true , true , false)
+OVERLOADED_OPERATOR(Minus                , "-"   , minus              , true , true , false)
+OVERLOADED_OPERATOR(Star                 , "*"   , star               , true , true , false)
+OVERLOADED_OPERATOR(Slash                , "/"   , slash              , false, true , false)
+OVERLOADED_OPERATOR(Percent              , "%"   , percent            , false, true , false)
+OVERLOADED_OPERATOR(Caret                , "^"   , caret              , false, true , false)
+OVERLOADED_OPERATOR(Amp                  , "&"   , amp                , true , true , false)
+OVERLOADED_OPERATOR(Pipe                 , "|"   , pipe               , false, true , false)
+OVERLOADED_OPERATOR(Tilde                , "~"   , tilde              , true , false, false)
+OVERLOADED_OPERATOR(Exclaim              , "!"   , exclaim            , true , false, false)
+OVERLOADED_OPERATOR(Equal                , "="   , equal              , false, true , true)
+OVERLOADED_OPERATOR(Less                 , "<"   , less               , false, true , false)
+OVERLOADED_OPERATOR(Greater              , ">"   , greater            , false, true , false)
+OVERLOADED_OPERATOR(PlusEqual            , "+="  , plusequal          , false, true , false)
+OVERLOADED_OPERATOR(MinusEqual           , "-="  , minusequal         , false, true , false)
+OVERLOADED_OPERATOR(StarEqual            , "*="  , starequal          , false, true , false)
+OVERLOADED_OPERATOR(SlashEqual           , "/="  , slashequal         , false, true , false)
+OVERLOADED_OPERATOR(PercentEqual         , "%="  , percentequal       , false, true , false)
+OVERLOADED_OPERATOR(CaretEqual           , "^="  , caretequal         , false, true , false)
+OVERLOADED_OPERATOR(AmpEqual             , "&="  , ampequal           , false, true , false)
+OVERLOADED_OPERATOR(PipeEqual            , "|="  , pipeequal          , false, true , false)
+OVERLOADED_OPERATOR(LessLess             , "<<"  , lessless           , false, true , false)
+OVERLOADED_OPERATOR(GreaterGreater       , ">>"  , greatergreater     , false, true , false)
+OVERLOADED_OPERATOR(LessLessEqual        , "<<=" , lesslessequal      , false, true , false)
+OVERLOADED_OPERATOR(GreaterGreaterEqual  , ">>=" , greatergreaterequal, false, true , false)
+OVERLOADED_OPERATOR(EqualEqual           , "=="  , equalequal         , false, true , false)
+OVERLOADED_OPERATOR(ExclaimEqual         , "!="  , exclaimequal       , false, true , false)
+OVERLOADED_OPERATOR(LessEqual            , "<="  , lessequal          , false, true , false)
+OVERLOADED_OPERATOR(GreaterEqual         , ">="  , greaterequal       , false, true , false)
+OVERLOADED_OPERATOR(AmpAmp               , "&&"  , ampamp             , false, true , false)
+OVERLOADED_OPERATOR(PipePipe             , "||"  , pipepipe           , false, true , false)
+OVERLOADED_OPERATOR(PlusPlus             , "++"  , plusplus           , true , true , false)
+OVERLOADED_OPERATOR(MinusMinus           , "--"  , minusminus         , true , true , false)
+OVERLOADED_OPERATOR(Comma                , ","   , comma              , false, true , false)
+OVERLOADED_OPERATOR(ArrowStar            , "->*" , arrowstar          , false, true , false)
+OVERLOADED_OPERATOR(Arrow                , "->"  , arrow              , true , false, true)
+OVERLOADED_OPERATOR_MULTI(Call           , "()"                       , true , true , true)
+OVERLOADED_OPERATOR_MULTI(Subscript      , "[]"                       , false, true , true)
+// ?: can *not* be overloaded, but we need the overload
+// resolution machinery for it.
+OVERLOADED_OPERATOR_MULTI(Conditional    , "?"                        , false, true , false)
+
+#undef OVERLOADED_OPERATOR_MULTI
+#undef OVERLOADED_OPERATOR
diff --git a/include/clang/Basic/OperatorKinds.h b/include/clang/Basic/OperatorKinds.h
new file mode 100644
index 0000000..c0a9505
--- /dev/null
+++ b/include/clang/Basic/OperatorKinds.h
@@ -0,0 +1,35 @@
+//===--- OperatorKinds.h - C++ Overloaded Operators -------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines C++ overloaded operators.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_OPERATOR_KINDS_H
+#define LLVM_CLANG_BASIC_OPERATOR_KINDS_H
+
+namespace clang {
+
+/// OverloadedOperatorKind - Enumeration specifying the different kinds of
+/// C++ overloaded operators.
+enum OverloadedOperatorKind {
+  OO_None,                //< Not an overloaded operator
+#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
+  OO_##Name,
+#include "clang/Basic/OperatorKinds.def"
+  NUM_OVERLOADED_OPERATORS
+};
+
+/// \brief Retrieve the spelling of the given overloaded operator, without 
+/// the preceding "operator" keyword.
+const char *getOperatorSpelling(OverloadedOperatorKind Operator);
+  
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Basic/PartialDiagnostic.h b/include/clang/Basic/PartialDiagnostic.h
new file mode 100644
index 0000000..89fae87
--- /dev/null
+++ b/include/clang/Basic/PartialDiagnostic.h
@@ -0,0 +1,287 @@
+//===--- PartialDiagnostic.h - Diagnostic "closures" ------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements a partial diagnostic that can be emitted anwyhere
+//  in a DiagnosticBuilder stream.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_PARTIALDIAGNOSTIC_H
+#define LLVM_CLANG_PARTIALDIAGNOSTIC_H
+
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/System/DataTypes.h"
+#include <cassert>
+
+namespace clang {
+
+class PartialDiagnostic {
+public:
+  struct Storage {
+    Storage() : NumDiagArgs(0), NumDiagRanges(0), NumFixItHints(0) { }
+
+    enum {
+        /// MaxArguments - The maximum number of arguments we can hold. We 
+        /// currently only support up to 10 arguments (%0-%9).
+        /// A single diagnostic with more than that almost certainly has to
+        /// be simplified anyway.
+        MaxArguments = 10
+    };
+  
+    /// NumDiagArgs - This contains the number of entries in Arguments.
+    unsigned char NumDiagArgs;
+  
+    /// NumDiagRanges - This is the number of ranges in the DiagRanges array.
+    unsigned char NumDiagRanges;
+
+    /// \brief The number of code modifications hints in the
+    /// FixItHints array.
+    unsigned char NumFixItHints;
+    
+    /// DiagArgumentsKind - This is an array of ArgumentKind::ArgumentKind enum
+    /// values, with one for each argument.  This specifies whether the argument
+    /// is in DiagArgumentsStr or in DiagArguments.
+    unsigned char DiagArgumentsKind[MaxArguments];
+  
+    /// DiagArgumentsVal - The values for the various substitution positions. 
+    /// This is used when the argument is not an std::string. The specific value 
+    /// is mangled into an intptr_t and the intepretation depends on exactly
+    /// what sort of argument kind it is.
+    intptr_t DiagArgumentsVal[MaxArguments];
+  
+    /// DiagRanges - The list of ranges added to this diagnostic.  It currently
+    /// only support 10 ranges, could easily be extended if needed.
+    SourceRange DiagRanges[10];
+    
+    enum { MaxFixItHints = 3 };
+    
+    /// FixItHints - If valid, provides a hint with some code
+    /// to insert, remove, or modify at a particular position.
+    FixItHint FixItHints[MaxFixItHints];    
+  };
+
+  /// \brief An allocator for Storage objects, which uses a small cache to 
+  /// objects, used to reduce malloc()/free() traffic for partial diagnostics.
+  class StorageAllocator {
+    static const unsigned NumCached = 4;
+    Storage Cached[NumCached];
+    Storage *FreeList[NumCached];
+    unsigned NumFreeListEntries;
+    
+  public:
+    StorageAllocator();
+    ~StorageAllocator();
+    
+    /// \brief Allocate new storage.
+    Storage *Allocate() {
+      if (NumFreeListEntries == 0)
+        return new Storage;
+      
+      Storage *Result = FreeList[--NumFreeListEntries];
+      Result->NumDiagArgs = 0;
+      Result->NumDiagRanges = 0;
+      Result->NumFixItHints = 0;
+      return Result;
+    }
+    
+    /// \brief Free the given storage object.
+    void Deallocate(Storage *S) {
+      if (S >= Cached && S <= Cached + NumCached) {
+        FreeList[NumFreeListEntries++] = S;
+        return;
+      }
+      
+      delete S;
+    }
+  };
+  
+private:
+  // NOTE: Sema assumes that PartialDiagnostic is location-invariant
+  // in the sense that its bits can be safely memcpy'ed and destructed
+  // in the new location.
+
+  /// DiagID - The diagnostic ID.
+  mutable unsigned DiagID;
+  
+  /// DiagStorage - Storage for args and ranges.
+  mutable Storage *DiagStorage;
+
+  /// \brief Allocator used to allocate storage for this diagnostic.
+  StorageAllocator *Allocator;
+  
+  /// \brief Retrieve storage for this particular diagnostic.
+  Storage *getStorage() const {
+    if (DiagStorage)
+      return DiagStorage;
+    
+    if (Allocator)
+      DiagStorage = Allocator->Allocate();
+    else {
+      assert(Allocator != reinterpret_cast<StorageAllocator *>(~uintptr_t(0)));
+      DiagStorage = new Storage;
+    }
+    return DiagStorage;
+  }
+  
+  void freeStorage() { 
+    if (!DiagStorage)
+      return;
+    
+    if (Allocator)
+      Allocator->Deallocate(DiagStorage);
+    else if (Allocator != reinterpret_cast<StorageAllocator *>(~uintptr_t(0)))
+      delete DiagStorage;
+    DiagStorage = 0;
+  }
+  
+  void AddSourceRange(const SourceRange &R) const {
+    if (!DiagStorage)
+      DiagStorage = getStorage();
+
+    assert(DiagStorage->NumDiagRanges < 
+           llvm::array_lengthof(DiagStorage->DiagRanges) &&
+           "Too many arguments to diagnostic!");
+    DiagStorage->DiagRanges[DiagStorage->NumDiagRanges++] = R;
+  }  
+
+  void AddFixItHint(const FixItHint &Hint) const {
+    if (Hint.isNull())
+      return;
+    
+    if (!DiagStorage)
+      DiagStorage = getStorage();
+
+    assert(DiagStorage->NumFixItHints < Storage::MaxFixItHints &&
+           "Too many code modification hints!");
+    DiagStorage->FixItHints[DiagStorage->NumFixItHints++]
+      = Hint;
+  }
+  
+public:
+  PartialDiagnostic(unsigned DiagID, StorageAllocator &Allocator)
+    : DiagID(DiagID), DiagStorage(0), Allocator(&Allocator) { }
+  
+  PartialDiagnostic(const PartialDiagnostic &Other) 
+    : DiagID(Other.DiagID), DiagStorage(0), Allocator(Other.Allocator)
+  {
+    if (Other.DiagStorage) {
+      DiagStorage = getStorage();
+      *DiagStorage = *Other.DiagStorage;
+    }
+  }
+
+  PartialDiagnostic(const PartialDiagnostic &Other, Storage *DiagStorage) 
+    : DiagID(Other.DiagID), DiagStorage(DiagStorage), 
+      Allocator(reinterpret_cast<StorageAllocator *>(~uintptr_t(0)))
+  {
+    if (Other.DiagStorage)
+      *this->DiagStorage = *Other.DiagStorage;
+  }
+  
+  PartialDiagnostic &operator=(const PartialDiagnostic &Other) {
+    DiagID = Other.DiagID;
+    if (Other.DiagStorage) {
+      if (!DiagStorage)
+        DiagStorage = getStorage();
+      
+      *DiagStorage = *Other.DiagStorage;
+    } else {
+      freeStorage();
+    }
+
+    return *this;
+  }
+
+  ~PartialDiagnostic() {
+    freeStorage();
+  }
+
+  unsigned getDiagID() const { return DiagID; }
+
+  void AddTaggedVal(intptr_t V, Diagnostic::ArgumentKind Kind) const {
+    if (!DiagStorage)
+      DiagStorage = getStorage();
+
+    assert(DiagStorage->NumDiagArgs < Storage::MaxArguments &&
+           "Too many arguments to diagnostic!");
+    DiagStorage->DiagArgumentsKind[DiagStorage->NumDiagArgs] = Kind;
+    DiagStorage->DiagArgumentsVal[DiagStorage->NumDiagArgs++] = V;
+  }
+
+  void Emit(const DiagnosticBuilder &DB) const {
+    if (!DiagStorage)
+      return;
+    
+    // Add all arguments.
+    for (unsigned i = 0, e = DiagStorage->NumDiagArgs; i != e; ++i) {
+      DB.AddTaggedVal(DiagStorage->DiagArgumentsVal[i],
+                   (Diagnostic::ArgumentKind)DiagStorage->DiagArgumentsKind[i]);
+    }
+    
+    // Add all ranges.
+    for (unsigned i = 0, e = DiagStorage->NumDiagRanges; i != e; ++i)
+      DB.AddSourceRange(DiagStorage->DiagRanges[i]);
+    
+    // Add all code modification hints
+    for (unsigned i = 0, e = DiagStorage->NumFixItHints; i != e; ++i)
+      DB.AddFixItHint(DiagStorage->FixItHints[i]);
+  }
+  
+  /// \brief Clear out this partial diagnostic, giving it a new diagnostic ID
+  /// and removing all of its arguments, ranges, and fix-it hints.
+  void Reset(unsigned DiagID = 0) {
+    this->DiagID = DiagID;
+    freeStorage();
+  }
+  
+  bool hasStorage() const { return DiagStorage != 0; }
+  
+  friend const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
+                                             unsigned I) {
+    PD.AddTaggedVal(I, Diagnostic::ak_uint);
+    return PD;
+  }
+
+  friend const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
+                                             int I) {
+    PD.AddTaggedVal(I, Diagnostic::ak_sint);
+    return PD;
+  }
+
+  friend inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
+                                                    const char *S) {
+    PD.AddTaggedVal(reinterpret_cast<intptr_t>(S), Diagnostic::ak_c_string);
+    return PD;
+  }
+
+  friend inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
+                                                    const SourceRange &R) {
+    PD.AddSourceRange(R);
+    return PD;
+  }
+
+  friend const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
+                                             const FixItHint &Hint) {
+    PD.AddFixItHint(Hint);
+    return PD;
+  }
+  
+};
+
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+                                           const PartialDiagnostic &PD) {
+  PD.Emit(DB);
+  return DB;
+}
+  
+
+}  // end namespace clang
+#endif
diff --git a/include/clang/Basic/PrettyStackTrace.h b/include/clang/Basic/PrettyStackTrace.h
new file mode 100644
index 0000000..5a5d551
--- /dev/null
+++ b/include/clang/Basic/PrettyStackTrace.h
@@ -0,0 +1,37 @@
+//===- clang/Basic/PrettyStackTrace.h - Pretty Crash Handling --*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the PrettyStackTraceEntry class, which is used to make
+// crashes give more contextual information about what the program was doing
+// when it crashed.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_BASIC_PRETTYSTACKTRACE_H
+#define CLANG_BASIC_PRETTYSTACKTRACE_H
+
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/Support/PrettyStackTrace.h"
+
+namespace clang {
+
+  /// PrettyStackTraceLoc - If a crash happens while one of these objects are
+  /// live, the message is printed out along with the specified source location.
+  class PrettyStackTraceLoc : public llvm::PrettyStackTraceEntry {
+    SourceManager &SM;
+    SourceLocation Loc;
+    const char *Message;
+  public:
+    PrettyStackTraceLoc(SourceManager &sm, SourceLocation L, const char *Msg)
+      : SM(sm), Loc(L), Message(Msg) {}
+    virtual void print(llvm::raw_ostream &OS) const;
+  };
+}
+
+#endif
diff --git a/include/clang/Basic/SourceLocation.h b/include/clang/Basic/SourceLocation.h
new file mode 100644
index 0000000..0bbeffe
--- /dev/null
+++ b/include/clang/Basic/SourceLocation.h
@@ -0,0 +1,305 @@
+//===--- SourceLocation.h - Compact identifier for Source Files -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the SourceLocation class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SOURCELOCATION_H
+#define LLVM_CLANG_SOURCELOCATION_H
+
+#include <utility>
+#include <cassert>
+
+namespace llvm {
+  class MemoryBuffer;
+  class raw_ostream;
+  class StringRef;
+  template <typename T> struct DenseMapInfo;
+  template <typename T> struct isPodLike;
+}
+
+namespace clang {
+
+class SourceManager;
+
+/// FileID - This is an opaque identifier used by SourceManager which refers to
+/// a source file (MemoryBuffer) along with its #include path and #line data.
+///
+class FileID {
+  /// ID - Opaque identifier, 0 is "invalid".
+  unsigned ID;
+public:
+  FileID() : ID(0) {}
+
+  bool isInvalid() const { return ID == 0; }
+
+  bool operator==(const FileID &RHS) const { return ID == RHS.ID; }
+  bool operator<(const FileID &RHS) const { return ID < RHS.ID; }
+  bool operator<=(const FileID &RHS) const { return ID <= RHS.ID; }
+  bool operator!=(const FileID &RHS) const { return !(*this == RHS); }
+  bool operator>(const FileID &RHS) const { return RHS < *this; }
+  bool operator>=(const FileID &RHS) const { return RHS <= *this; }
+
+  static FileID getSentinel() { return get(~0U); }
+  unsigned getHashValue() const { return ID; }
+
+private:
+  friend class SourceManager;
+  static FileID get(unsigned V) {
+    FileID F;
+    F.ID = V;
+    return F;
+  }
+  unsigned getOpaqueValue() const { return ID; }
+};
+
+
+/// SourceLocation - This is a carefully crafted 32-bit identifier that encodes
+/// a full include stack, line and column number information for a position in
+/// an input translation unit.
+class SourceLocation {
+  unsigned ID;
+  friend class SourceManager;
+  enum {
+    MacroIDBit = 1U << 31
+  };
+public:
+
+  SourceLocation() : ID(0) {}  // 0 is an invalid FileID.
+
+  bool isFileID() const  { return (ID & MacroIDBit) == 0; }
+  bool isMacroID() const { return (ID & MacroIDBit) != 0; }
+
+  /// isValid - Return true if this is a valid SourceLocation object.  Invalid
+  /// SourceLocations are often used when events have no corresponding location
+  /// in the source (e.g. a diagnostic is required for a command line option).
+  ///
+  bool isValid() const { return ID != 0; }
+  bool isInvalid() const { return ID == 0; }
+
+private:
+  /// getOffset - Return the index for SourceManager's SLocEntryTable table,
+  /// note that this is not an index *into* it though.
+  unsigned getOffset() const {
+    return ID & ~MacroIDBit;
+  }
+
+  static SourceLocation getFileLoc(unsigned ID) {
+    assert((ID & MacroIDBit) == 0 && "Ran out of source locations!");
+    SourceLocation L;
+    L.ID = ID;
+    return L;
+  }
+
+  static SourceLocation getMacroLoc(unsigned ID) {
+    assert((ID & MacroIDBit) == 0 && "Ran out of source locations!");
+    SourceLocation L;
+    L.ID = MacroIDBit | ID;
+    return L;
+  }
+public:
+
+  /// getFileLocWithOffset - Return a source location with the specified offset
+  /// from this file SourceLocation.
+  SourceLocation getFileLocWithOffset(int Offset) const {
+    assert(((getOffset()+Offset) & MacroIDBit) == 0 && "invalid location");
+    SourceLocation L;
+    L.ID = ID+Offset;
+    return L;
+  }
+
+  /// getRawEncoding - When a SourceLocation itself cannot be used, this returns
+  /// an (opaque) 32-bit integer encoding for it.  This should only be passed
+  /// to SourceLocation::getFromRawEncoding, it should not be inspected
+  /// directly.
+  unsigned getRawEncoding() const { return ID; }
+
+
+  /// getFromRawEncoding - Turn a raw encoding of a SourceLocation object into
+  /// a real SourceLocation.
+  static SourceLocation getFromRawEncoding(unsigned Encoding) {
+    SourceLocation X;
+    X.ID = Encoding;
+    return X;
+  }
+
+  void print(llvm::raw_ostream &OS, const SourceManager &SM) const;
+  void dump(const SourceManager &SM) const;
+};
+
+inline bool operator==(const SourceLocation &LHS, const SourceLocation &RHS) {
+  return LHS.getRawEncoding() == RHS.getRawEncoding();
+}
+
+inline bool operator!=(const SourceLocation &LHS, const SourceLocation &RHS) {
+  return !(LHS == RHS);
+}
+
+inline bool operator<(const SourceLocation &LHS, const SourceLocation &RHS) {
+  return LHS.getRawEncoding() < RHS.getRawEncoding();
+}
+
+/// SourceRange - a trival tuple used to represent a source range.
+class SourceRange {
+  SourceLocation B;
+  SourceLocation E;
+public:
+  SourceRange(): B(SourceLocation()), E(SourceLocation()) {}
+  SourceRange(SourceLocation loc) : B(loc), E(loc) {}
+  SourceRange(SourceLocation begin, SourceLocation end) : B(begin), E(end) {}
+
+  SourceLocation getBegin() const { return B; }
+  SourceLocation getEnd() const { return E; }
+
+  void setBegin(SourceLocation b) { B = b; }
+  void setEnd(SourceLocation e) { E = e; }
+
+  bool isValid() const { return B.isValid() && E.isValid(); }
+  bool isInvalid() const { return !isValid(); }
+
+  bool operator==(const SourceRange &X) const {
+    return B == X.B && E == X.E;
+  }
+
+  bool operator!=(const SourceRange &X) const {
+    return B != X.B || E != X.E;
+  }
+};
+
+/// FullSourceLoc - A SourceLocation and its associated SourceManager.  Useful
+/// for argument passing to functions that expect both objects.
+class FullSourceLoc : public SourceLocation {
+  const SourceManager *SrcMgr;
+public:
+  /// Creates a FullSourceLoc where isValid() returns false.
+  explicit FullSourceLoc() : SrcMgr(0) {}
+
+  explicit FullSourceLoc(SourceLocation Loc, const SourceManager &SM)
+    : SourceLocation(Loc), SrcMgr(&SM) {}
+
+  const SourceManager &getManager() const {
+    assert(SrcMgr && "SourceManager is NULL.");
+    return *SrcMgr;
+  }
+
+  FileID getFileID() const;
+
+  FullSourceLoc getInstantiationLoc() const;
+  FullSourceLoc getSpellingLoc() const;
+
+  unsigned getInstantiationLineNumber(bool *Invalid = 0) const;
+  unsigned getInstantiationColumnNumber(bool *Invalid = 0) const;
+
+  unsigned getSpellingLineNumber(bool *Invalid = 0) const;
+  unsigned getSpellingColumnNumber(bool *Invalid = 0) const;
+
+  const char *getCharacterData(bool *Invalid = 0) const;
+
+  const llvm::MemoryBuffer* getBuffer(bool *Invalid = 0) const;
+
+  /// getBufferData - Return a StringRef to the source buffer data for the
+  /// specified FileID.
+  llvm::StringRef getBufferData(bool *Invalid = 0) const;
+
+  /// getDecomposedLoc - Decompose the specified location into a raw FileID +
+  /// Offset pair.  The first element is the FileID, the second is the
+  /// offset from the start of the buffer of the location.
+  std::pair<FileID, unsigned> getDecomposedLoc() const;
+
+  bool isInSystemHeader() const;
+
+  /// Prints information about this FullSourceLoc to stderr. Useful for
+  ///  debugging.
+  void dump() const { SourceLocation::dump(*SrcMgr); }
+
+  friend inline bool
+  operator==(const FullSourceLoc &LHS, const FullSourceLoc &RHS) {
+    return LHS.getRawEncoding() == RHS.getRawEncoding() &&
+          LHS.SrcMgr == RHS.SrcMgr;
+  }
+
+  friend inline bool
+  operator!=(const FullSourceLoc &LHS, const FullSourceLoc &RHS) {
+    return !(LHS == RHS);
+  }
+
+};
+
+/// PresumedLoc - This class represents an unpacked "presumed" location which
+/// can be presented to the user.  A 'presumed' location can be modified by
+/// #line and GNU line marker directives and is always the instantiation point
+/// of a normal location.
+///
+/// You can get a PresumedLoc from a SourceLocation with SourceManager.
+class PresumedLoc {
+  const char *Filename;
+  unsigned Line, Col;
+  SourceLocation IncludeLoc;
+public:
+  PresumedLoc() : Filename(0) {}
+  PresumedLoc(const char *FN, unsigned Ln, unsigned Co, SourceLocation IL)
+    : Filename(FN), Line(Ln), Col(Co), IncludeLoc(IL) {
+  }
+
+  /// isInvalid - Return true if this object is invalid or uninitialized. This
+  /// occurs when created with invalid source locations or when walking off
+  /// the top of a #include stack.
+  bool isInvalid() const { return Filename == 0; }
+  bool isValid() const { return Filename != 0; }
+
+  /// getFilename - Return the presumed filename of this location.  This can be
+  /// affected by #line etc.
+  const char *getFilename() const { return Filename; }
+
+  /// getLine - Return the presumed line number of this location.  This can be
+  /// affected by #line etc.
+  unsigned getLine() const { return Line; }
+
+  /// getColumn - Return the presumed column number of this location.  This can
+  /// not be affected by #line, but is packaged here for convenience.
+  unsigned getColumn() const { return Col; }
+
+  /// getIncludeLoc - Return the presumed include location of this location.
+  /// This can be affected by GNU linemarker directives.
+  SourceLocation getIncludeLoc() const { return IncludeLoc; }
+};
+
+
+}  // end namespace clang
+
+namespace llvm {
+  /// Define DenseMapInfo so that FileID's can be used as keys in DenseMap and
+  /// DenseSets.
+  template <>
+  struct DenseMapInfo<clang::FileID> {
+    static inline clang::FileID getEmptyKey() {
+      return clang::FileID();
+    }
+    static inline clang::FileID getTombstoneKey() {
+      return clang::FileID::getSentinel();
+    }
+
+    static unsigned getHashValue(clang::FileID S) {
+      return S.getHashValue();
+    }
+
+    static bool isEqual(clang::FileID LHS, clang::FileID RHS) {
+      return LHS == RHS;
+    }
+  };
+  
+  template <>
+  struct isPodLike<clang::SourceLocation> { static const bool value = true; };
+  template <>
+  struct isPodLike<clang::FileID> { static const bool value = true; };
+
+}  // end namespace llvm
+
+#endif
diff --git a/include/clang/Basic/SourceManager.h b/include/clang/Basic/SourceManager.h
new file mode 100644
index 0000000..930fb52
--- /dev/null
+++ b/include/clang/Basic/SourceManager.h
@@ -0,0 +1,799 @@
+//===--- SourceManager.h - Track and cache source files ---------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the SourceManager interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SOURCEMANAGER_H
+#define LLVM_CLANG_SOURCEMANAGER_H
+
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/System/DataTypes.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/DenseMap.h"
+#include <vector>
+#include <cassert>
+
+namespace llvm {
+class MemoryBuffer;
+class StringRef;
+}
+
+namespace clang {
+
+class Diagnostic;
+class SourceManager;
+class FileManager;
+class FileEntry;
+class LineTableInfo;
+  
+/// SrcMgr - Public enums and private classes that are part of the
+/// SourceManager implementation.
+///
+namespace SrcMgr {
+  /// CharacteristicKind - This is used to represent whether a file or directory
+  /// holds normal user code, system code, or system code which is implicitly
+  /// 'extern "C"' in C++ mode.  Entire directories can be tagged with this
+  /// (this is maintained by DirectoryLookup and friends) as can specific
+  /// FileIDInfos when a #pragma system_header is seen or various other cases.
+  ///
+  enum CharacteristicKind {
+    C_User, C_System, C_ExternCSystem
+  };
+
+  /// ContentCache - Once instance of this struct is kept for every file
+  /// loaded or used.  This object owns the MemoryBuffer object.
+  class ContentCache {
+    /// Buffer - The actual buffer containing the characters from the input
+    /// file.  This is owned by the ContentCache object.
+    /// The bit indicates whether the buffer is invalid.
+    mutable llvm::PointerIntPair<const llvm::MemoryBuffer *, 1, bool> Buffer;
+
+  public:
+    /// Reference to the file entry.  This reference does not own
+    /// the FileEntry object.  It is possible for this to be NULL if
+    /// the ContentCache encapsulates an imaginary text buffer.
+    const FileEntry *Entry;
+
+    /// SourceLineCache - A bump pointer allocated array of offsets for each
+    /// source line.  This is lazily computed.  This is owned by the
+    /// SourceManager BumpPointerAllocator object.
+    unsigned *SourceLineCache;
+
+    /// NumLines - The number of lines in this ContentCache.  This is only valid
+    /// if SourceLineCache is non-null.
+    unsigned NumLines;
+
+    /// getBuffer - Returns the memory buffer for the associated content.
+    ///
+    /// \param Diag Object through which diagnostics will be emitted it the
+    /// buffer cannot be retrieved.
+    /// 
+    /// \param Loc If specified, is the location that invalid file diagnostics
+    ///     will be emitted at.
+    ///
+    /// \param Invalid If non-NULL, will be set \c true if an error occurred.
+    const llvm::MemoryBuffer *getBuffer(Diagnostic &Diag,
+                                        const SourceManager &SM,
+                                        SourceLocation Loc = SourceLocation(),
+                                        bool *Invalid = 0) const;
+
+    /// getSize - Returns the size of the content encapsulated by this
+    ///  ContentCache. This can be the size of the source file or the size of an
+    ///  arbitrary scratch buffer.  If the ContentCache encapsulates a source
+    ///  file this size is retrieved from the file's FileEntry.
+    unsigned getSize() const;
+
+    /// getSizeBytesMapped - Returns the number of bytes actually mapped for
+    ///  this ContentCache.  This can be 0 if the MemBuffer was not actually
+    ///  instantiated.
+    unsigned getSizeBytesMapped() const;
+
+    void setBuffer(const llvm::MemoryBuffer *B) {
+      assert(!Buffer.getPointer() && "MemoryBuffer already set.");
+      Buffer.setPointer(B);
+      Buffer.setInt(false);
+    }
+
+    /// \brief Replace the existing buffer (which will be deleted)
+    /// with the given buffer.
+    void replaceBuffer(const llvm::MemoryBuffer *B);
+
+    ContentCache(const FileEntry *Ent = 0)
+      : Buffer(0, false), Entry(Ent), SourceLineCache(0), NumLines(0) {}
+
+    ~ContentCache();
+
+    /// The copy ctor does not allow copies where source object has either
+    ///  a non-NULL Buffer or SourceLineCache.  Ownership of allocated memory
+    ///  is not transfered, so this is a logical error.
+    ContentCache(const ContentCache &RHS) 
+      : Buffer(0, false), SourceLineCache(0) 
+    {
+      Entry = RHS.Entry;
+
+      assert (RHS.Buffer.getPointer() == 0 && RHS.SourceLineCache == 0
+              && "Passed ContentCache object cannot own a buffer.");
+
+      NumLines = RHS.NumLines;
+    }
+
+  private:
+    // Disable assignments.
+    ContentCache &operator=(const ContentCache& RHS);
+  };
+
+  /// FileInfo - Information about a FileID, basically just the logical file
+  /// that it represents and include stack information.
+  ///
+  /// Each FileInfo has include stack information, indicating where it came
+  /// from.  This information encodes the #include chain that a token was
+  /// instantiated from.  The main include file has an invalid IncludeLoc.
+  ///
+  /// FileInfos contain a "ContentCache *", with the contents of the file.
+  ///
+  class FileInfo {
+    /// IncludeLoc - The location of the #include that brought in this file.
+    /// This is an invalid SLOC for the main file (top of the #include chain).
+    unsigned IncludeLoc;  // Really a SourceLocation
+
+    /// Data - This contains the ContentCache* and the bits indicating the
+    /// characteristic of the file and whether it has #line info, all bitmangled
+    /// together.
+    uintptr_t Data;
+  public:
+    /// get - Return a FileInfo object.
+    static FileInfo get(SourceLocation IL, const ContentCache *Con,
+                        CharacteristicKind FileCharacter) {
+      FileInfo X;
+      X.IncludeLoc = IL.getRawEncoding();
+      X.Data = (uintptr_t)Con;
+      assert((X.Data & 7) == 0 &&"ContentCache pointer insufficiently aligned");
+      assert((unsigned)FileCharacter < 4 && "invalid file character");
+      X.Data |= (unsigned)FileCharacter;
+      return X;
+    }
+
+    SourceLocation getIncludeLoc() const {
+      return SourceLocation::getFromRawEncoding(IncludeLoc);
+    }
+    const ContentCache* getContentCache() const {
+      return reinterpret_cast<const ContentCache*>(Data & ~7UL);
+    }
+
+    /// getCharacteristic - Return whether this is a system header or not.
+    CharacteristicKind getFileCharacteristic() const {
+      return (CharacteristicKind)(Data & 3);
+    }
+
+    /// hasLineDirectives - Return true if this FileID has #line directives in
+    /// it.
+    bool hasLineDirectives() const { return (Data & 4) != 0; }
+
+    /// setHasLineDirectives - Set the flag that indicates that this FileID has
+    /// line table entries associated with it.
+    void setHasLineDirectives() {
+      Data |= 4;
+    }
+  };
+
+  /// InstantiationInfo - Each InstantiationInfo encodes the Instantiation
+  /// location - where the token was ultimately instantiated, and the
+  /// SpellingLoc - where the actual character data for the token came from.
+  class InstantiationInfo {
+     // Really these are all SourceLocations.
+
+    /// SpellingLoc - Where the spelling for the token can be found.
+    unsigned SpellingLoc;
+
+    /// InstantiationLocStart/InstantiationLocEnd - In a macro expansion, these
+    /// indicate the start and end of the instantiation.  In object-like macros,
+    /// these will be the same.  In a function-like macro instantiation, the
+    /// start will be the identifier and the end will be the ')'.
+    unsigned InstantiationLocStart, InstantiationLocEnd;
+  public:
+    SourceLocation getSpellingLoc() const {
+      return SourceLocation::getFromRawEncoding(SpellingLoc);
+    }
+    SourceLocation getInstantiationLocStart() const {
+      return SourceLocation::getFromRawEncoding(InstantiationLocStart);
+    }
+    SourceLocation getInstantiationLocEnd() const {
+      return SourceLocation::getFromRawEncoding(InstantiationLocEnd);
+    }
+
+    std::pair<SourceLocation,SourceLocation> getInstantiationLocRange() const {
+      return std::make_pair(getInstantiationLocStart(),
+                            getInstantiationLocEnd());
+    }
+
+    /// get - Return a InstantiationInfo for an expansion.  IL specifies
+    /// the instantiation location (where the macro is expanded), and SL
+    /// specifies the spelling location (where the characters from the token
+    /// come from).  IL and PL can both refer to normal File SLocs or
+    /// instantiation locations.
+    static InstantiationInfo get(SourceLocation ILStart, SourceLocation ILEnd,
+                                 SourceLocation SL) {
+      InstantiationInfo X;
+      X.SpellingLoc = SL.getRawEncoding();
+      X.InstantiationLocStart = ILStart.getRawEncoding();
+      X.InstantiationLocEnd = ILEnd.getRawEncoding();
+      return X;
+    }
+  };
+
+  /// SLocEntry - This is a discriminated union of FileInfo and
+  /// InstantiationInfo.  SourceManager keeps an array of these objects, and
+  /// they are uniquely identified by the FileID datatype.
+  class SLocEntry {
+    unsigned Offset;   // low bit is set for instantiation info.
+    union {
+      FileInfo File;
+      InstantiationInfo Instantiation;
+    };
+  public:
+    unsigned getOffset() const { return Offset >> 1; }
+
+    bool isInstantiation() const { return Offset & 1; }
+    bool isFile() const { return !isInstantiation(); }
+
+    const FileInfo &getFile() const {
+      assert(isFile() && "Not a file SLocEntry!");
+      return File;
+    }
+
+    const InstantiationInfo &getInstantiation() const {
+      assert(isInstantiation() && "Not an instantiation SLocEntry!");
+      return Instantiation;
+    }
+
+    static SLocEntry get(unsigned Offset, const FileInfo &FI) {
+      SLocEntry E;
+      E.Offset = Offset << 1;
+      E.File = FI;
+      return E;
+    }
+
+    static SLocEntry get(unsigned Offset, const InstantiationInfo &II) {
+      SLocEntry E;
+      E.Offset = (Offset << 1) | 1;
+      E.Instantiation = II;
+      return E;
+    }
+  };
+}  // end SrcMgr namespace.
+
+/// \brief External source of source location entries.
+class ExternalSLocEntrySource {
+public:
+  virtual ~ExternalSLocEntrySource();
+
+  /// \brief Read the source location entry with index ID.
+  virtual void ReadSLocEntry(unsigned ID) = 0;
+};
+
+/// SourceManager - This file handles loading and caching of source files into
+/// memory.  This object owns the MemoryBuffer objects for all of the loaded
+/// files and assigns unique FileID's for each unique #include chain.
+///
+/// The SourceManager can be queried for information about SourceLocation
+/// objects, turning them into either spelling or instantiation locations.
+/// Spelling locations represent where the bytes corresponding to a token came
+/// from and instantiation locations represent where the location is in the
+/// user's view.  In the case of a macro expansion, for example, the spelling
+/// location indicates where the expanded token came from and the instantiation
+/// location specifies where it was expanded.
+class SourceManager {
+  /// \brief Diagnostic object.
+  Diagnostic &Diag;
+  
+  mutable llvm::BumpPtrAllocator ContentCacheAlloc;
+
+  /// FileInfos - Memoized information about all of the files tracked by this
+  /// SourceManager.  This set allows us to merge ContentCache entries based
+  /// on their FileEntry*.  All ContentCache objects will thus have unique,
+  /// non-null, FileEntry pointers.
+  llvm::DenseMap<const FileEntry*, SrcMgr::ContentCache*> FileInfos;
+
+  /// MemBufferInfos - Information about various memory buffers that we have
+  /// read in.  All FileEntry* within the stored ContentCache objects are NULL,
+  /// as they do not refer to a file.
+  std::vector<SrcMgr::ContentCache*> MemBufferInfos;
+
+  /// SLocEntryTable - This is an array of SLocEntry's that we have created.
+  /// FileID is an index into this vector.  This array is sorted by the offset.
+  std::vector<SrcMgr::SLocEntry> SLocEntryTable;
+  /// NextOffset - This is the next available offset that a new SLocEntry can
+  /// start at.  It is SLocEntryTable.back().getOffset()+size of back() entry.
+  unsigned NextOffset;
+
+  /// \brief If source location entries are being lazily loaded from
+  /// an external source, this vector indicates whether the Ith source
+  /// location entry has already been loaded from the external storage.
+  std::vector<bool> SLocEntryLoaded;
+
+  /// \brief An external source for source location entries.
+  ExternalSLocEntrySource *ExternalSLocEntries;
+
+  /// LastFileIDLookup - This is a one-entry cache to speed up getFileID.
+  /// LastFileIDLookup records the last FileID looked up or created, because it
+  /// is very common to look up many tokens from the same file.
+  mutable FileID LastFileIDLookup;
+
+  /// LineTable - This holds information for #line directives.  It is referenced
+  /// by indices from SLocEntryTable.
+  LineTableInfo *LineTable;
+
+  /// LastLineNo - These ivars serve as a cache used in the getLineNumber
+  /// method which is used to speedup getLineNumber calls to nearby locations.
+  mutable FileID LastLineNoFileIDQuery;
+  mutable SrcMgr::ContentCache *LastLineNoContentCache;
+  mutable unsigned LastLineNoFilePos;
+  mutable unsigned LastLineNoResult;
+
+  /// MainFileID - The file ID for the main source file of the translation unit.
+  FileID MainFileID;
+
+  // Statistics for -print-stats.
+  mutable unsigned NumLinearScans, NumBinaryProbes;
+
+  // Cache results for the isBeforeInTranslationUnit method.
+  mutable FileID LastLFIDForBeforeTUCheck;
+  mutable FileID LastRFIDForBeforeTUCheck;
+  mutable bool   LastResForBeforeTUCheck;
+
+  // SourceManager doesn't support copy construction.
+  explicit SourceManager(const SourceManager&);
+  void operator=(const SourceManager&);
+public:
+  SourceManager(Diagnostic &Diag)
+    : Diag(Diag), ExternalSLocEntries(0), LineTable(0), NumLinearScans(0),
+      NumBinaryProbes(0) {
+    clearIDTables();
+  }
+  ~SourceManager();
+
+  void clearIDTables();
+
+  //===--------------------------------------------------------------------===//
+  // MainFileID creation and querying methods.
+  //===--------------------------------------------------------------------===//
+
+  /// getMainFileID - Returns the FileID of the main source file.
+  FileID getMainFileID() const { return MainFileID; }
+
+  /// createMainFileID - Create the FileID for the main source file.
+  FileID createMainFileID(const FileEntry *SourceFile,
+                          SourceLocation IncludePos) {
+    assert(MainFileID.isInvalid() && "MainFileID already set!");
+    MainFileID = createFileID(SourceFile, IncludePos, SrcMgr::C_User);
+    return MainFileID;
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Methods to create new FileID's and instantiations.
+  //===--------------------------------------------------------------------===//
+
+  /// createFileID - Create a new FileID that represents the specified file
+  /// being #included from the specified IncludePosition.  This returns 0 on
+  /// error and translates NULL into standard input.
+  /// PreallocateID should be non-zero to specify which a pre-allocated,
+  /// lazily computed source location is being filled in by this operation.
+  FileID createFileID(const FileEntry *SourceFile, SourceLocation IncludePos,
+                      SrcMgr::CharacteristicKind FileCharacter,
+                      unsigned PreallocatedID = 0,
+                      unsigned Offset = 0) {
+    const SrcMgr::ContentCache *IR = getOrCreateContentCache(SourceFile);
+    if (IR == 0) return FileID();    // Error opening file?
+    return createFileID(IR, IncludePos, FileCharacter, PreallocatedID, Offset);
+  }
+
+  /// createFileIDForMemBuffer - Create a new FileID that represents the
+  /// specified memory buffer.  This does no caching of the buffer and takes
+  /// ownership of the MemoryBuffer, so only pass a MemoryBuffer to this once.
+  FileID createFileIDForMemBuffer(const llvm::MemoryBuffer *Buffer,
+                                  unsigned PreallocatedID = 0,
+                                  unsigned Offset = 0) {
+    return createFileID(createMemBufferContentCache(Buffer), SourceLocation(),
+                        SrcMgr::C_User, PreallocatedID, Offset);
+  }
+
+  /// createMainFileIDForMembuffer - Create the FileID for a memory buffer
+  ///  that will represent the FileID for the main source.  One example
+  ///  of when this would be used is when the main source is read from STDIN.
+  FileID createMainFileIDForMemBuffer(const llvm::MemoryBuffer *Buffer) {
+    assert(MainFileID.isInvalid() && "MainFileID already set!");
+    MainFileID = createFileIDForMemBuffer(Buffer);
+    return MainFileID;
+  }
+
+  /// createInstantiationLoc - Return a new SourceLocation that encodes the fact
+  /// that a token at Loc should actually be referenced from InstantiationLoc.
+  /// TokLength is the length of the token being instantiated.
+  SourceLocation createInstantiationLoc(SourceLocation Loc,
+                                        SourceLocation InstantiationLocStart,
+                                        SourceLocation InstantiationLocEnd,
+                                        unsigned TokLength,
+                                        unsigned PreallocatedID = 0,
+                                        unsigned Offset = 0);
+
+  /// \brief Retrieve the memory buffer associated with the given file.
+  ///
+  /// \param Invalid If non-NULL, will be set \c true if an error
+  /// occurs while retrieving the memory buffer.
+  const llvm::MemoryBuffer *getMemoryBufferForFile(const FileEntry *File,
+                                                   bool *Invalid = 0);
+
+  /// \brief Override the contents of the given source file by providing an
+  /// already-allocated buffer.
+  ///
+  /// \param SourceFile the source file whose contents will be override.
+  ///
+  /// \param Buffer the memory buffer whose contents will be used as the
+  /// data in the given source file.
+  ///
+  /// \returns true if an error occurred, false otherwise.
+  bool overrideFileContents(const FileEntry *SourceFile,
+                            const llvm::MemoryBuffer *Buffer);
+
+  //===--------------------------------------------------------------------===//
+  // FileID manipulation methods.
+  //===--------------------------------------------------------------------===//
+
+  /// getBuffer - Return the buffer for the specified FileID. If there is an
+  /// error opening this buffer the first time, this manufactures a temporary
+  /// buffer and returns a non-empty error string.
+  const llvm::MemoryBuffer *getBuffer(FileID FID, SourceLocation Loc,
+                                      bool *Invalid = 0) const {
+    return getSLocEntry(FID).getFile().getContentCache()
+       ->getBuffer(Diag, *this, Loc, Invalid);
+  }
+
+  const llvm::MemoryBuffer *getBuffer(FileID FID, bool *Invalid = 0) const {
+    return getSLocEntry(FID).getFile().getContentCache()
+       ->getBuffer(Diag, *this, SourceLocation(), Invalid);
+  }
+  
+  /// getFileEntryForID - Returns the FileEntry record for the provided FileID.
+  const FileEntry *getFileEntryForID(FileID FID) const {
+    return getSLocEntry(FID).getFile().getContentCache()->Entry;
+  }
+
+  /// getBufferData - Return a StringRef to the source buffer data for the
+  /// specified FileID.
+  ///
+  /// \param FID The file ID whose contents will be returned.
+  /// \param Invalid If non-NULL, will be set true if an error occurred.
+  llvm::StringRef getBufferData(FileID FID, bool *Invalid = 0) const;
+
+
+  //===--------------------------------------------------------------------===//
+  // SourceLocation manipulation methods.
+  //===--------------------------------------------------------------------===//
+
+  /// getFileID - Return the FileID for a SourceLocation.  This is a very
+  /// hot method that is used for all SourceManager queries that start with a
+  /// SourceLocation object.  It is responsible for finding the entry in
+  /// SLocEntryTable which contains the specified location.
+  ///
+  FileID getFileID(SourceLocation SpellingLoc) const {
+    unsigned SLocOffset = SpellingLoc.getOffset();
+
+    // If our one-entry cache covers this offset, just return it.
+    if (isOffsetInFileID(LastFileIDLookup, SLocOffset))
+      return LastFileIDLookup;
+
+    return getFileIDSlow(SLocOffset);
+  }
+
+  /// getLocForStartOfFile - Return the source location corresponding to the
+  /// first byte of the specified file.
+  SourceLocation getLocForStartOfFile(FileID FID) const {
+    assert(FID.ID < SLocEntryTable.size() && "FileID out of range");
+    assert(getSLocEntry(FID).isFile() && "FileID is not a file");
+    unsigned FileOffset = getSLocEntry(FID).getOffset();
+    return SourceLocation::getFileLoc(FileOffset);
+  }
+
+  /// getInstantiationLoc - Given a SourceLocation object, return the
+  /// instantiation location referenced by the ID.
+  SourceLocation getInstantiationLoc(SourceLocation Loc) const {
+    // Handle the non-mapped case inline, defer to out of line code to handle
+    // instantiations.
+    if (Loc.isFileID()) return Loc;
+    return getInstantiationLocSlowCase(Loc);
+  }
+
+  /// getImmediateInstantiationRange - Loc is required to be an instantiation
+  /// location.  Return the start/end of the instantiation information.
+  std::pair<SourceLocation,SourceLocation>
+  getImmediateInstantiationRange(SourceLocation Loc) const;
+
+  /// getInstantiationRange - Given a SourceLocation object, return the
+  /// range of tokens covered by the instantiation in the ultimate file.
+  std::pair<SourceLocation,SourceLocation>
+  getInstantiationRange(SourceLocation Loc) const;
+
+
+  /// getSpellingLoc - Given a SourceLocation object, return the spelling
+  /// location referenced by the ID.  This is the place where the characters
+  /// that make up the lexed token can be found.
+  SourceLocation getSpellingLoc(SourceLocation Loc) const {
+    // Handle the non-mapped case inline, defer to out of line code to handle
+    // instantiations.
+    if (Loc.isFileID()) return Loc;
+    return getSpellingLocSlowCase(Loc);
+  }
+
+  /// getImmediateSpellingLoc - Given a SourceLocation object, return the
+  /// spelling location referenced by the ID.  This is the first level down
+  /// towards the place where the characters that make up the lexed token can be
+  /// found.  This should not generally be used by clients.
+  SourceLocation getImmediateSpellingLoc(SourceLocation Loc) const;
+
+  /// getDecomposedLoc - Decompose the specified location into a raw FileID +
+  /// Offset pair.  The first element is the FileID, the second is the
+  /// offset from the start of the buffer of the location.
+  std::pair<FileID, unsigned> getDecomposedLoc(SourceLocation Loc) const {
+    FileID FID = getFileID(Loc);
+    return std::make_pair(FID, Loc.getOffset()-getSLocEntry(FID).getOffset());
+  }
+
+  /// getDecomposedInstantiationLoc - Decompose the specified location into a
+  /// raw FileID + Offset pair.  If the location is an instantiation record,
+  /// walk through it until we find the final location instantiated.
+  std::pair<FileID, unsigned>
+  getDecomposedInstantiationLoc(SourceLocation Loc) const {
+    FileID FID = getFileID(Loc);
+    const SrcMgr::SLocEntry *E = &getSLocEntry(FID);
+
+    unsigned Offset = Loc.getOffset()-E->getOffset();
+    if (Loc.isFileID())
+      return std::make_pair(FID, Offset);
+
+    return getDecomposedInstantiationLocSlowCase(E, Offset);
+  }
+
+  /// getDecomposedSpellingLoc - Decompose the specified location into a raw
+  /// FileID + Offset pair.  If the location is an instantiation record, walk
+  /// through it until we find its spelling record.
+  std::pair<FileID, unsigned>
+  getDecomposedSpellingLoc(SourceLocation Loc) const {
+    FileID FID = getFileID(Loc);
+    const SrcMgr::SLocEntry *E = &getSLocEntry(FID);
+
+    unsigned Offset = Loc.getOffset()-E->getOffset();
+    if (Loc.isFileID())
+      return std::make_pair(FID, Offset);
+    return getDecomposedSpellingLocSlowCase(E, Offset);
+  }
+
+  /// getFileOffset - This method returns the offset from the start
+  /// of the file that the specified SourceLocation represents. This is not very
+  /// meaningful for a macro ID.
+  unsigned getFileOffset(SourceLocation SpellingLoc) const {
+    return getDecomposedLoc(SpellingLoc).second;
+  }
+
+
+  //===--------------------------------------------------------------------===//
+  // Queries about the code at a SourceLocation.
+  //===--------------------------------------------------------------------===//
+
+  /// getCharacterData - Return a pointer to the start of the specified location
+  /// in the appropriate spelling MemoryBuffer.
+  ///
+  /// \param Invalid If non-NULL, will be set \c true if an error occurs.
+  const char *getCharacterData(SourceLocation SL, bool *Invalid = 0) const;
+
+  /// getColumnNumber - Return the column # for the specified file position.
+  /// This is significantly cheaper to compute than the line number.  This
+  /// returns zero if the column number isn't known.  This may only be called on
+  /// a file sloc, so you must choose a spelling or instantiation location
+  /// before calling this method.
+  unsigned getColumnNumber(FileID FID, unsigned FilePos, 
+                           bool *Invalid = 0) const;
+  unsigned getSpellingColumnNumber(SourceLocation Loc,
+                                   bool *Invalid = 0) const;
+  unsigned getInstantiationColumnNumber(SourceLocation Loc,
+                                        bool *Invalid = 0) const;
+
+
+  /// getLineNumber - Given a SourceLocation, return the spelling line number
+  /// for the position indicated.  This requires building and caching a table of
+  /// line offsets for the MemoryBuffer, so this is not cheap: use only when
+  /// about to emit a diagnostic.
+  unsigned getLineNumber(FileID FID, unsigned FilePos, bool *Invalid = 0) const;
+
+  unsigned getInstantiationLineNumber(SourceLocation Loc, 
+                                      bool *Invalid = 0) const;
+  unsigned getSpellingLineNumber(SourceLocation Loc, bool *Invalid = 0) const;
+
+  /// Return the filename or buffer identifier of the buffer the location is in.
+  /// Note that this name does not respect #line directives.  Use getPresumedLoc
+  /// for normal clients.
+  const char *getBufferName(SourceLocation Loc, bool *Invalid = 0) const;
+
+  /// getFileCharacteristic - return the file characteristic of the specified
+  /// source location, indicating whether this is a normal file, a system
+  /// header, or an "implicit extern C" system header.
+  ///
+  /// This state can be modified with flags on GNU linemarker directives like:
+  ///   # 4 "foo.h" 3
+  /// which changes all source locations in the current file after that to be
+  /// considered to be from a system header.
+  SrcMgr::CharacteristicKind getFileCharacteristic(SourceLocation Loc) const;
+
+  /// getPresumedLoc - This method returns the "presumed" location of a
+  /// SourceLocation specifies.  A "presumed location" can be modified by #line
+  /// or GNU line marker directives.  This provides a view on the data that a
+  /// user should see in diagnostics, for example.
+  ///
+  /// Note that a presumed location is always given as the instantiation point
+  /// of an instantiation location, not at the spelling location.
+  PresumedLoc getPresumedLoc(SourceLocation Loc) const;
+
+  /// isFromSameFile - Returns true if both SourceLocations correspond to
+  ///  the same file.
+  bool isFromSameFile(SourceLocation Loc1, SourceLocation Loc2) const {
+    return getFileID(Loc1) == getFileID(Loc2);
+  }
+
+  /// isFromMainFile - Returns true if the file of provided SourceLocation is
+  ///   the main file.
+  bool isFromMainFile(SourceLocation Loc) const {
+    return getFileID(Loc) == getMainFileID();
+  }
+
+  /// isInSystemHeader - Returns if a SourceLocation is in a system header.
+  bool isInSystemHeader(SourceLocation Loc) const {
+    return getFileCharacteristic(Loc) != SrcMgr::C_User;
+  }
+
+  /// isInExternCSystemHeader - Returns if a SourceLocation is in an "extern C"
+  /// system header.
+  bool isInExternCSystemHeader(SourceLocation Loc) const {
+    return getFileCharacteristic(Loc) == SrcMgr::C_ExternCSystem;
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Line Table Manipulation Routines
+  //===--------------------------------------------------------------------===//
+
+  /// getLineTableFilenameID - Return the uniqued ID for the specified filename.
+  ///
+  unsigned getLineTableFilenameID(const char *Ptr, unsigned Len);
+
+  /// AddLineNote - Add a line note to the line table for the FileID and offset
+  /// specified by Loc.  If FilenameID is -1, it is considered to be
+  /// unspecified.
+  void AddLineNote(SourceLocation Loc, unsigned LineNo, int FilenameID);
+  void AddLineNote(SourceLocation Loc, unsigned LineNo, int FilenameID,
+                   bool IsFileEntry, bool IsFileExit,
+                   bool IsSystemHeader, bool IsExternCHeader);
+
+  /// \brief Determine if the source manager has a line table.
+  bool hasLineTable() const { return LineTable != 0; }
+
+  /// \brief Retrieve the stored line table.
+  LineTableInfo &getLineTable();
+
+  //===--------------------------------------------------------------------===//
+  // Other miscellaneous methods.
+  //===--------------------------------------------------------------------===//
+
+  /// \brief Get the source location for the given file:line:col triplet.
+  ///
+  /// If the source file is included multiple times, the source location will
+  /// be based upon the first inclusion.
+  SourceLocation getLocation(const FileEntry *SourceFile,
+                             unsigned Line, unsigned Col) const;
+
+  /// \brief Determines the order of 2 source locations in the translation unit.
+  ///
+  /// \returns true if LHS source location comes before RHS, false otherwise.
+  bool isBeforeInTranslationUnit(SourceLocation LHS, SourceLocation RHS) const;
+
+  // Iterators over FileInfos.
+  typedef llvm::DenseMap<const FileEntry*, SrcMgr::ContentCache*>
+      ::const_iterator fileinfo_iterator;
+  fileinfo_iterator fileinfo_begin() const { return FileInfos.begin(); }
+  fileinfo_iterator fileinfo_end() const { return FileInfos.end(); }
+  bool hasFileInfo(const FileEntry *File) const {
+    return FileInfos.find(File) != FileInfos.end();
+  }
+
+  /// PrintStats - Print statistics to stderr.
+  ///
+  void PrintStats() const;
+
+  unsigned sloc_entry_size() const { return SLocEntryTable.size(); }
+
+  // FIXME: Exposing this is a little gross; what we want is a good way
+  //  to iterate the entries that were not defined in a PCH file (or
+  //  any other external source).
+  unsigned sloc_loaded_entry_size() const { return SLocEntryLoaded.size(); }
+
+  const SrcMgr::SLocEntry &getSLocEntry(unsigned ID) const {
+    assert(ID < SLocEntryTable.size() && "Invalid id");
+    if (ExternalSLocEntries &&
+        ID < SLocEntryLoaded.size() &&
+        !SLocEntryLoaded[ID])
+      ExternalSLocEntries->ReadSLocEntry(ID);
+    return SLocEntryTable[ID];
+  }
+
+  const SrcMgr::SLocEntry &getSLocEntry(FileID FID) const {
+    return getSLocEntry(FID.ID);
+  }
+
+  unsigned getNextOffset() const { return NextOffset; }
+
+  /// \brief Preallocate some number of source location entries, which
+  /// will be loaded as needed from the given external source.
+  void PreallocateSLocEntries(ExternalSLocEntrySource *Source,
+                              unsigned NumSLocEntries,
+                              unsigned NextOffset);
+
+  /// \brief Clear out any preallocated source location entries that
+  /// haven't already been loaded.
+  void ClearPreallocatedSLocEntries();
+
+private:
+  /// isOffsetInFileID - Return true if the specified FileID contains the
+  /// specified SourceLocation offset.  This is a very hot method.
+  inline bool isOffsetInFileID(FileID FID, unsigned SLocOffset) const {
+    const SrcMgr::SLocEntry &Entry = getSLocEntry(FID);
+    // If the entry is after the offset, it can't contain it.
+    if (SLocOffset < Entry.getOffset()) return false;
+
+    // If this is the last entry than it does.  Otherwise, the entry after it
+    // has to not include it.
+    if (FID.ID+1 == SLocEntryTable.size()) return true;
+
+    return SLocOffset < getSLocEntry(FileID::get(FID.ID+1)).getOffset();
+  }
+
+  /// createFileID - Create a new fileID for the specified ContentCache and
+  ///  include position.  This works regardless of whether the ContentCache
+  ///  corresponds to a file or some other input source.
+  FileID createFileID(const SrcMgr::ContentCache* File,
+                      SourceLocation IncludePos,
+                      SrcMgr::CharacteristicKind DirCharacter,
+                      unsigned PreallocatedID = 0,
+                      unsigned Offset = 0);
+
+  const SrcMgr::ContentCache *
+    getOrCreateContentCache(const FileEntry *SourceFile);
+
+  /// createMemBufferContentCache - Create a new ContentCache for the specified
+  ///  memory buffer.
+  const SrcMgr::ContentCache*
+  createMemBufferContentCache(const llvm::MemoryBuffer *Buf);
+
+  FileID getFileIDSlow(unsigned SLocOffset) const;
+
+  SourceLocation getInstantiationLocSlowCase(SourceLocation Loc) const;
+  SourceLocation getSpellingLocSlowCase(SourceLocation Loc) const;
+
+  std::pair<FileID, unsigned>
+  getDecomposedInstantiationLocSlowCase(const SrcMgr::SLocEntry *E,
+                                        unsigned Offset) const;
+  std::pair<FileID, unsigned>
+  getDecomposedSpellingLocSlowCase(const SrcMgr::SLocEntry *E,
+                                   unsigned Offset) const;
+};
+
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Basic/SourceManagerInternals.h b/include/clang/Basic/SourceManagerInternals.h
new file mode 100644
index 0000000..258989c
--- /dev/null
+++ b/include/clang/Basic/SourceManagerInternals.h
@@ -0,0 +1,130 @@
+//===--- SourceManagerInternals.h - SourceManager Internals -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the implementation details of the SourceManager
+//  class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SOURCEMANAGER_INTERNALS_H
+#define LLVM_CLANG_SOURCEMANAGER_INTERNALS_H
+
+#include "clang/Basic/SourceManager.h"
+#include "llvm/ADT/StringMap.h"
+#include <map>
+
+namespace clang {
+
+//===----------------------------------------------------------------------===//
+// Line Table Implementation
+//===----------------------------------------------------------------------===//
+
+struct LineEntry {
+  /// FileOffset - The offset in this file that the line entry occurs at.
+  unsigned FileOffset;
+
+  /// LineNo - The presumed line number of this line entry: #line 4.
+  unsigned LineNo;
+
+  /// FilenameID - The ID of the filename identified by this line entry:
+  /// #line 4 "foo.c".  This is -1 if not specified.
+  int FilenameID;
+
+  /// Flags - Set the 0 if no flags, 1 if a system header,
+  SrcMgr::CharacteristicKind FileKind;
+
+  /// IncludeOffset - This is the offset of the virtual include stack location,
+  /// which is manipulated by GNU linemarker directives.  If this is 0 then
+  /// there is no virtual #includer.
+  unsigned IncludeOffset;
+
+  static LineEntry get(unsigned Offs, unsigned Line, int Filename,
+                       SrcMgr::CharacteristicKind FileKind,
+                       unsigned IncludeOffset) {
+    LineEntry E;
+    E.FileOffset = Offs;
+    E.LineNo = Line;
+    E.FilenameID = Filename;
+    E.FileKind = FileKind;
+    E.IncludeOffset = IncludeOffset;
+    return E;
+  }
+};
+
+// needed for FindNearestLineEntry (upper_bound of LineEntry)
+inline bool operator<(const LineEntry &lhs, const LineEntry &rhs) {
+  // FIXME: should check the other field?
+  return lhs.FileOffset < rhs.FileOffset;
+}
+
+inline bool operator<(const LineEntry &E, unsigned Offset) {
+  return E.FileOffset < Offset;
+}
+
+inline bool operator<(unsigned Offset, const LineEntry &E) {
+  return Offset < E.FileOffset;
+}
+
+/// LineTableInfo - This class is used to hold and unique data used to
+/// represent #line information.
+class LineTableInfo {
+  /// FilenameIDs - This map is used to assign unique IDs to filenames in
+  /// #line directives.  This allows us to unique the filenames that
+  /// frequently reoccur and reference them with indices.  FilenameIDs holds
+  /// the mapping from string -> ID, and FilenamesByID holds the mapping of ID
+  /// to string.
+  llvm::StringMap<unsigned, llvm::BumpPtrAllocator> FilenameIDs;
+  std::vector<llvm::StringMapEntry<unsigned>*> FilenamesByID;
+
+  /// LineEntries - This is a map from FileIDs to a list of line entries (sorted
+  /// by the offset they occur in the file.
+  std::map<unsigned, std::vector<LineEntry> > LineEntries;
+public:
+  LineTableInfo() {
+  }
+
+  void clear() {
+    FilenameIDs.clear();
+    FilenamesByID.clear();
+    LineEntries.clear();
+  }
+
+  ~LineTableInfo() {}
+
+  unsigned getLineTableFilenameID(const char *Ptr, unsigned Len);
+  const char *getFilename(unsigned ID) const {
+    assert(ID < FilenamesByID.size() && "Invalid FilenameID");
+    return FilenamesByID[ID]->getKeyData();
+  }
+  unsigned getNumFilenames() const { return FilenamesByID.size(); }
+
+  void AddLineNote(unsigned FID, unsigned Offset,
+                   unsigned LineNo, int FilenameID);
+  void AddLineNote(unsigned FID, unsigned Offset,
+                   unsigned LineNo, int FilenameID,
+                   unsigned EntryExit, SrcMgr::CharacteristicKind FileKind);
+
+
+  /// FindNearestLineEntry - Find the line entry nearest to FID that is before
+  /// it.  If there is no line entry before Offset in FID, return null.
+  const LineEntry *FindNearestLineEntry(unsigned FID, unsigned Offset);
+
+  // Low-level access
+  typedef std::map<unsigned, std::vector<LineEntry> >::iterator iterator;
+  iterator begin() { return LineEntries.begin(); }
+  iterator end() { return LineEntries.end(); }
+
+  /// \brief Add a new line entry that has already been encoded into
+  /// the internal representation of the line table.
+  void AddEntry(unsigned FID, const std::vector<LineEntry> &Entries);
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Basic/Specifiers.h b/include/clang/Basic/Specifiers.h
new file mode 100644
index 0000000..9e54762
--- /dev/null
+++ b/include/clang/Basic/Specifiers.h
@@ -0,0 +1,83 @@
+//===--- Specifiers.h - Declaration and Type Specifiers ---------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines various enumerations that describe declaration and
+// type specifiers.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_SPECIFIERS_H
+#define LLVM_CLANG_BASIC_SPECIFIERS_H
+
+namespace clang {
+  /// \brief Specifies the width of a type, e.g., short, long, or long long.
+  enum TypeSpecifierWidth {
+    TSW_unspecified,
+    TSW_short,
+    TSW_long,
+    TSW_longlong
+  };
+  
+  /// \brief Specifies the signedness of a type, e.g., signed or unsigned.
+  enum TypeSpecifierSign {
+    TSS_unspecified,
+    TSS_signed,
+    TSS_unsigned
+  };
+  
+  /// \brief Specifies the kind of type.
+  enum TypeSpecifierType {
+    TST_unspecified,
+    TST_void,
+    TST_char,
+    TST_wchar,        // C++ wchar_t
+    TST_char16,       // C++0x char16_t
+    TST_char32,       // C++0x char32_t
+    TST_int,
+    TST_float,
+    TST_double,
+    TST_bool,         // _Bool
+    TST_decimal32,    // _Decimal32
+    TST_decimal64,    // _Decimal64
+    TST_decimal128,   // _Decimal128
+    TST_enum,
+    TST_union,
+    TST_struct,
+    TST_class,        // C++ class type
+    TST_typename,     // Typedef, C++ class-name or enum name, etc.
+    TST_typeofType,
+    TST_typeofExpr,
+    TST_decltype,     // C++0x decltype
+    TST_auto,         // C++0x auto
+    TST_error         // erroneous type
+  };
+  
+  /// WrittenBuiltinSpecs - Structure that packs information about the 
+  /// type specifiers that were written in a particular type specifier
+  /// sequence.
+  struct WrittenBuiltinSpecs {
+    /*DeclSpec::TST*/ unsigned Type  : 5;
+    /*DeclSpec::TSS*/ unsigned Sign  : 2;
+    /*DeclSpec::TSW*/ unsigned Width : 2;
+    bool ModeAttr : 1;
+  };  
+
+  /// AccessSpecifier - A C++ access specifier (public, private,
+  /// protected), plus the special value "none" which means
+  /// different things in different contexts.
+  enum AccessSpecifier {
+    AS_public,
+    AS_protected,
+    AS_private,
+    AS_none
+  };
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_BASIC_SPECIFIERS_H
diff --git a/include/clang/Basic/TargetBuiltins.h b/include/clang/Basic/TargetBuiltins.h
new file mode 100644
index 0000000..f1edd1d
--- /dev/null
+++ b/include/clang/Basic/TargetBuiltins.h
@@ -0,0 +1,50 @@
+//===--- TargetBuiltins.h - Target specific builtin IDs -------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_TARGET_BUILTINS_H
+#define LLVM_CLANG_BASIC_TARGET_BUILTINS_H
+
+#include "clang/Basic/Builtins.h"
+#undef PPC
+
+namespace clang {
+
+  /// ARM builtins
+  namespace ARM {
+    enum {
+        LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
+#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
+#include "clang/Basic/BuiltinsARM.def"
+        LastTSBuiltin
+    };
+  }
+
+  /// PPC builtins
+  namespace PPC {
+    enum {
+        LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
+#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
+#include "clang/Basic/BuiltinsPPC.def"
+        LastTSBuiltin
+    };
+  }
+
+  /// X86 builtins
+  namespace X86 {
+    enum {
+        LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
+#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
+#include "clang/Basic/BuiltinsX86.def"
+        LastTSBuiltin
+    };
+  }
+
+} // end namespace clang.
+
+#endif
diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h
new file mode 100644
index 0000000..1998750
--- /dev/null
+++ b/include/clang/Basic/TargetInfo.h
@@ -0,0 +1,466 @@
+//===--- TargetInfo.h - Expose information about the target -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the TargetInfo interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_TARGETINFO_H
+#define LLVM_CLANG_BASIC_TARGETINFO_H
+
+// FIXME: Daniel isn't smart enough to use a prototype for this.
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/System/DataTypes.h"
+#include <cassert>
+#include <vector>
+#include <string>
+
+namespace llvm {
+struct fltSemantics;
+class StringRef;
+}
+
+namespace clang {
+class Diagnostic;
+class LangOptions;
+class MacroBuilder;
+class SourceLocation;
+class SourceManager;
+class TargetOptions;
+
+namespace Builtin { struct Info; }
+
+/// TargetInfo - This class exposes information about the current target.
+///
+class TargetInfo {
+  llvm::Triple Triple;
+protected:
+  // Target values set by the ctor of the actual target implementation.  Default
+  // values are specified by the TargetInfo constructor.
+  bool TLSSupported;
+  bool NoAsmVariants;  // True if {|} are normal characters.
+  unsigned char PointerWidth, PointerAlign;
+  unsigned char IntWidth, IntAlign;
+  unsigned char FloatWidth, FloatAlign;
+  unsigned char DoubleWidth, DoubleAlign;
+  unsigned char LongDoubleWidth, LongDoubleAlign;
+  unsigned char LongWidth, LongAlign;
+  unsigned char LongLongWidth, LongLongAlign;
+  const char *DescriptionString;
+  const char *UserLabelPrefix;
+  const llvm::fltSemantics *FloatFormat, *DoubleFormat, *LongDoubleFormat;
+  unsigned char RegParmMax, SSERegParmMax;
+
+  // TargetInfo Constructor.  Default initializes all fields.
+  TargetInfo(const std::string &T);
+
+public:
+  /// CreateTargetInfo - Construct a target for the given options.
+  ///
+  /// \param Opts - The options to use to initialize the target. The target may
+  /// modify the options to canonicalize the target feature information to match
+  /// what the backend expects.
+  static TargetInfo* CreateTargetInfo(Diagnostic &Diags, TargetOptions &Opts);
+
+  virtual ~TargetInfo();
+
+  ///===---- Target Data Type Query Methods -------------------------------===//
+  enum IntType {
+    NoInt = 0,
+    SignedShort,
+    UnsignedShort,
+    SignedInt,
+    UnsignedInt,
+    SignedLong,
+    UnsignedLong,
+    SignedLongLong,
+    UnsignedLongLong
+  };
+protected:
+  IntType SizeType, IntMaxType, UIntMaxType, PtrDiffType, IntPtrType, WCharType,
+          WIntType, Char16Type, Char32Type, Int64Type, SigAtomicType;
+
+  /// Control whether the alignment of bit-field types is respected when laying
+  /// out structures. If true, then the alignment of the bit-field type will be
+  /// used to (a) impact the alignment of the containing structure, and (b)
+  /// ensure that the individual bit-field will not straddle an alignment
+  /// boundary.
+  unsigned UseBitFieldTypeAlignment : 1;
+
+public:
+  IntType getSizeType() const { return SizeType; }
+  IntType getIntMaxType() const { return IntMaxType; }
+  IntType getUIntMaxType() const { return UIntMaxType; }
+  IntType getPtrDiffType(unsigned AddrSpace) const {
+    return AddrSpace == 0 ? PtrDiffType : getPtrDiffTypeV(AddrSpace);
+  }
+  IntType getIntPtrType() const { return IntPtrType; }
+  IntType getWCharType() const { return WCharType; }
+  IntType getWIntType() const { return WIntType; }
+  IntType getChar16Type() const { return Char16Type; }
+  IntType getChar32Type() const { return Char32Type; }
+  IntType getInt64Type() const { return Int64Type; }
+  IntType getSigAtomicType() const { return SigAtomicType; }
+
+
+  /// getTypeWidth - Return the width (in bits) of the specified integer type 
+  /// enum. For example, SignedInt -> getIntWidth().
+  unsigned getTypeWidth(IntType T) const;
+
+  /// getTypeAlign - Return the alignment (in bits) of the specified integer
+  /// type enum. For example, SignedInt -> getIntAlign().
+  unsigned getTypeAlign(IntType T) const;
+
+  /// isTypeSigned - Return whether an integer types is signed. Returns true if
+  /// the type is signed; false otherwise.
+  bool isTypeSigned(IntType T) const;
+
+  /// getPointerWidth - Return the width of pointers on this target, for the
+  /// specified address space.
+  uint64_t getPointerWidth(unsigned AddrSpace) const {
+    return AddrSpace == 0 ? PointerWidth : getPointerWidthV(AddrSpace);
+  }
+  uint64_t getPointerAlign(unsigned AddrSpace) const {
+    return AddrSpace == 0 ? PointerAlign : getPointerAlignV(AddrSpace);
+  }
+
+  /// getBoolWidth/Align - Return the size of '_Bool' and C++ 'bool' for this
+  /// target, in bits.
+  unsigned getBoolWidth(bool isWide = false) const { return 8; }  // FIXME
+  unsigned getBoolAlign(bool isWide = false) const { return 8; }  // FIXME
+
+  unsigned getCharWidth() const { return 8; } // FIXME
+  unsigned getCharAlign() const { return 8; } // FIXME
+
+  /// getShortWidth/Align - Return the size of 'signed short' and
+  /// 'unsigned short' for this target, in bits.
+  unsigned getShortWidth() const { return 16; } // FIXME
+  unsigned getShortAlign() const { return 16; } // FIXME
+
+  /// getIntWidth/Align - Return the size of 'signed int' and 'unsigned int' for
+  /// this target, in bits.
+  unsigned getIntWidth() const { return IntWidth; }
+  unsigned getIntAlign() const { return IntAlign; }
+
+  /// getLongWidth/Align - Return the size of 'signed long' and 'unsigned long'
+  /// for this target, in bits.
+  unsigned getLongWidth() const { return LongWidth; }
+  unsigned getLongAlign() const { return LongAlign; }
+
+  /// getLongLongWidth/Align - Return the size of 'signed long long' and
+  /// 'unsigned long long' for this target, in bits.
+  unsigned getLongLongWidth() const { return LongLongWidth; }
+  unsigned getLongLongAlign() const { return LongLongAlign; }
+
+  /// getWCharWidth/Align - Return the size of 'wchar_t' for this target, in
+  /// bits.
+  unsigned getWCharWidth() const { return getTypeWidth(WCharType); }
+  unsigned getWCharAlign() const { return getTypeAlign(WCharType); }
+
+  /// getChar16Width/Align - Return the size of 'char16_t' for this target, in
+  /// bits.
+  unsigned getChar16Width() const { return getTypeWidth(Char16Type); }
+  unsigned getChar16Align() const { return getTypeAlign(Char16Type); }
+
+  /// getChar32Width/Align - Return the size of 'char32_t' for this target, in
+  /// bits.
+  unsigned getChar32Width() const { return getTypeWidth(Char32Type); }
+  unsigned getChar32Align() const { return getTypeAlign(Char32Type); }
+
+  /// getFloatWidth/Align/Format - Return the size/align/format of 'float'.
+  unsigned getFloatWidth() const { return FloatWidth; }
+  unsigned getFloatAlign() const { return FloatAlign; }
+  const llvm::fltSemantics &getFloatFormat() const { return *FloatFormat; }
+
+  /// getDoubleWidth/Align/Format - Return the size/align/format of 'double'.
+  unsigned getDoubleWidth() const { return DoubleWidth; }
+  unsigned getDoubleAlign() const { return DoubleAlign; }
+  const llvm::fltSemantics &getDoubleFormat() const { return *DoubleFormat; }
+
+  /// getLongDoubleWidth/Align/Format - Return the size/align/format of 'long
+  /// double'.
+  unsigned getLongDoubleWidth() const { return LongDoubleWidth; }
+  unsigned getLongDoubleAlign() const { return LongDoubleAlign; }
+  const llvm::fltSemantics &getLongDoubleFormat() const {
+    return *LongDoubleFormat;
+  }
+
+  /// getIntMaxTWidth - Return the size of intmax_t and uintmax_t for this
+  /// target, in bits.
+  unsigned getIntMaxTWidth() const {
+    return getTypeWidth(IntMaxType);
+  }
+
+  /// getUserLabelPrefix - This returns the default value of the
+  /// __USER_LABEL_PREFIX__ macro, which is the prefix given to user symbols by
+  /// default.  On most platforms this is "_", but it is "" on some, and "." on
+  /// others.
+  const char *getUserLabelPrefix() const {
+    return UserLabelPrefix;
+  }
+
+  bool useBitFieldTypeAlignment() const {
+    return UseBitFieldTypeAlignment;
+  }
+
+  /// getTypeName - Return the user string for the specified integer type enum.
+  /// For example, SignedShort -> "short".
+  static const char *getTypeName(IntType T);
+
+  /// getTypeConstantSuffix - Return the constant suffix for the specified
+  /// integer type enum. For example, SignedLong -> "L".
+  static const char *getTypeConstantSuffix(IntType T);
+
+  ///===---- Other target property query methods --------------------------===//
+
+  /// getTargetDefines - Appends the target-specific #define values for this
+  /// target set to the specified buffer.
+  virtual void getTargetDefines(const LangOptions &Opts,
+                                MacroBuilder &Builder) const = 0;
+
+
+  /// getTargetBuiltins - Return information about target-specific builtins for
+  /// the current primary target, and info about which builtins are non-portable
+  /// across the current set of primary and secondary targets.
+  virtual void getTargetBuiltins(const Builtin::Info *&Records,
+                                 unsigned &NumRecords) const = 0;
+
+  /// getVAListDeclaration - Return the declaration to use for
+  /// __builtin_va_list, which is target-specific.
+  virtual const char *getVAListDeclaration() const = 0;
+
+  /// isValidGCCRegisterName - Returns whether the passed in string
+  /// is a valid register name according to GCC. This is used by Sema for
+  /// inline asm statements.
+  bool isValidGCCRegisterName(llvm::StringRef Name) const;
+
+  // getNormalizedGCCRegisterName - Returns the "normalized" GCC register name.
+  // For example, on x86 it will return "ax" when "eax" is passed in.
+  llvm::StringRef getNormalizedGCCRegisterName(llvm::StringRef Name) const;
+
+  struct ConstraintInfo {
+    enum {
+      CI_None = 0x00,
+      CI_AllowsMemory = 0x01,
+      CI_AllowsRegister = 0x02,
+      CI_ReadWrite = 0x04,       // "+r" output constraint (read and write).
+      CI_HasMatchingInput = 0x08 // This output operand has a matching input.
+    };
+    unsigned Flags;
+    int TiedOperand;
+
+    std::string ConstraintStr;  // constraint: "=rm"
+    std::string Name;           // Operand name: [foo] with no []'s.
+  public:
+    ConstraintInfo(llvm::StringRef ConstraintStr, llvm::StringRef Name)
+      : Flags(0), TiedOperand(-1), ConstraintStr(ConstraintStr.str()), 
+      Name(Name.str()) {}
+
+    const std::string &getConstraintStr() const { return ConstraintStr; }
+    const std::string &getName() const { return Name; }
+    bool isReadWrite() const { return (Flags & CI_ReadWrite) != 0; }
+    bool allowsRegister() const { return (Flags & CI_AllowsRegister) != 0; }
+    bool allowsMemory() const { return (Flags & CI_AllowsMemory) != 0; }
+
+    /// hasMatchingInput - Return true if this output operand has a matching
+    /// (tied) input operand.
+    bool hasMatchingInput() const { return (Flags & CI_HasMatchingInput) != 0; }
+
+    /// hasTiedOperand() - Return true if this input operand is a matching
+    /// constraint that ties it to an output operand.  If this returns true,
+    /// then getTiedOperand will indicate which output operand this is tied to.
+    bool hasTiedOperand() const { return TiedOperand != -1; }
+    unsigned getTiedOperand() const {
+      assert(hasTiedOperand() && "Has no tied operand!");
+      return (unsigned)TiedOperand;
+    }
+
+    void setIsReadWrite() { Flags |= CI_ReadWrite; }
+    void setAllowsMemory() { Flags |= CI_AllowsMemory; }
+    void setAllowsRegister() { Flags |= CI_AllowsRegister; }
+    void setHasMatchingInput() { Flags |= CI_HasMatchingInput; }
+
+    /// setTiedOperand - Indicate that this is an input operand that is tied to
+    /// the specified output operand.  Copy over the various constraint
+    /// information from the output.
+    void setTiedOperand(unsigned N, ConstraintInfo &Output) {
+      Output.setHasMatchingInput();
+      Flags = Output.Flags;
+      TiedOperand = N;
+      // Don't copy Name or constraint string.
+    }
+  };
+
+  // validateOutputConstraint, validateInputConstraint - Checks that
+  // a constraint is valid and provides information about it.
+  // FIXME: These should return a real error instead of just true/false.
+  bool validateOutputConstraint(ConstraintInfo &Info) const;
+  bool validateInputConstraint(ConstraintInfo *OutputConstraints,
+                               unsigned NumOutputs,
+                               ConstraintInfo &info) const;
+  bool resolveSymbolicName(const char *&Name,
+                           ConstraintInfo *OutputConstraints,
+                           unsigned NumOutputs, unsigned &Index) const;
+
+  virtual std::string convertConstraint(const char Constraint) const {
+    return std::string(1, Constraint);
+  }
+
+  // Returns a string of target-specific clobbers, in LLVM format.
+  virtual const char *getClobbers() const = 0;
+
+
+  /// getTriple - Return the target triple of the primary target.
+  const llvm::Triple &getTriple() const {
+    return Triple;
+  }
+
+  const char *getTargetDescription() const {
+    return DescriptionString;
+  }
+
+  struct GCCRegAlias {
+    const char * const Aliases[5];
+    const char * const Register;
+  };
+
+  virtual bool useGlobalsForAutomaticVariables() const { return false; }
+
+  /// getCFStringSection - Return the section to use for CFString
+  /// literals, or 0 if no special section is used.
+  virtual const char *getCFStringSection() const {
+    return "__DATA,__cfstring";
+  }
+
+  /// getNSStringSection - Return the section to use for NSString
+  /// literals, or 0 if no special section is used.
+  virtual const char *getNSStringSection() const {
+    return "__OBJC,__cstring_object,regular,no_dead_strip";
+  }
+
+  /// getNSStringNonFragileABISection - Return the section to use for 
+  /// NSString literals, or 0 if no special section is used (NonFragile ABI).
+  virtual const char *getNSStringNonFragileABISection() const {
+    return "__DATA, __objc_stringobj, regular, no_dead_strip";
+  }
+
+  /// isValidSectionSpecifier - This is an optional hook that targets can
+  /// implement to perform semantic checking on attribute((section("foo")))
+  /// specifiers.  In this case, "foo" is passed in to be checked.  If the
+  /// section specifier is invalid, the backend should return a non-empty string
+  /// that indicates the problem.
+  ///
+  /// This hook is a simple quality of implementation feature to catch errors
+  /// and give good diagnostics in cases when the assembler or code generator
+  /// would otherwise reject the section specifier.
+  ///
+  virtual std::string isValidSectionSpecifier(llvm::StringRef SR) const {
+    return "";
+  }
+
+  /// setForcedLangOptions - Set forced language options.
+  /// Apply changes to the target information with respect to certain
+  /// language options which change the target configuration.
+  virtual void setForcedLangOptions(LangOptions &Opts);
+
+  /// getDefaultFeatures - Get the default set of target features for
+  /// the \args CPU; this should include all legal feature strings on
+  /// the target.
+  virtual void getDefaultFeatures(const std::string &CPU,
+                                  llvm::StringMap<bool> &Features) const {
+  }
+
+  /// getABI - Get the ABI in use.
+  virtual const char *getABI() const {
+    return "";
+  }
+
+  /// setCPU - Target the specific CPU.
+  ///
+  /// \return - False on error (invalid CPU name).
+  //
+  // FIXME: Remove this.
+  virtual bool setCPU(const std::string &Name) {
+    return true;
+  }
+
+  /// setABI - Use the specific ABI.
+  ///
+  /// \return - False on error (invalid ABI name).
+  virtual bool setABI(const std::string &Name) {
+    return false;
+  }
+
+  /// setFeatureEnabled - Enable or disable a specific target feature,
+  /// the feature name must be valid.
+  ///
+  /// \return - False on error (invalid feature name).
+  virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
+                                 const std::string &Name,
+                                 bool Enabled) const {
+    return false;
+  }
+
+  /// HandleTargetOptions - Perform initialization based on the user configured
+  /// set of features (e.g., +sse4). The list is guaranteed to have at most one
+  /// entry per feature.
+  ///
+  /// The target may modify the features list, to change which options are
+  /// passed onwards to the backend.
+  virtual void HandleTargetFeatures(std::vector<std::string> &Features) {
+  }
+
+  // getRegParmMax - Returns maximal number of args passed in registers.
+  unsigned getRegParmMax() const {
+    return RegParmMax;
+  }
+
+  /// isTLSSupported - Whether the target supports thread-local storage.
+  bool isTLSSupported() const {
+    return TLSSupported;
+  }
+  
+  /// hasNoAsmVariants - Return true if {|} are normal characters in the
+  /// asm string.  If this returns false (the default), then {abc|xyz} is syntax
+  /// that says that when compiling for asm variant #0, "abc" should be
+  /// generated, but when compiling for asm variant #1, "xyz" should be
+  /// generated.
+  bool hasNoAsmVariants() const {
+    return NoAsmVariants;
+  }
+  
+  /// getEHDataRegisterNumber - Return the register number that
+  /// __builtin_eh_return_regno would return with the specified argument.
+  virtual int getEHDataRegisterNumber(unsigned RegNo) const {
+    return -1; 
+  }
+  
+
+protected:
+  virtual uint64_t getPointerWidthV(unsigned AddrSpace) const {
+    return PointerWidth;
+  }
+  virtual uint64_t getPointerAlignV(unsigned AddrSpace) const {
+    return PointerAlign;
+  }
+  virtual enum IntType getPtrDiffTypeV(unsigned AddrSpace) const {
+    return PtrDiffType;
+  }
+  virtual void getGCCRegNames(const char * const *&Names,
+                              unsigned &NumNames) const = 0;
+  virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
+                                unsigned &NumAliases) const = 0;
+  virtual bool validateAsmConstraint(const char *&Name,
+                                     TargetInfo::ConstraintInfo &info) const= 0;
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Basic/TargetOptions.h b/include/clang/Basic/TargetOptions.h
new file mode 100644
index 0000000..eeaab15
--- /dev/null
+++ b/include/clang/Basic/TargetOptions.h
@@ -0,0 +1,39 @@
+//===--- TargetOptions.h ----------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_TARGETOPTIONS_H
+#define LLVM_CLANG_FRONTEND_TARGETOPTIONS_H
+
+#include <string>
+#include <vector>
+
+namespace clang {
+
+/// TargetOptions - Options for controlling the target.
+class TargetOptions {
+public:
+
+  /// If given, the name of the target triple to compile for. If not given the
+  /// target will be selected to match the host.
+  std::string Triple;
+
+  /// If given, the name of the target CPU to generate code for.
+  std::string CPU;
+
+  /// If given, the name of the target ABI to use.
+  std::string ABI;
+
+  /// The list of target specific features to enable or disable -- this should
+  /// be a list of strings starting with by '+' or '-'.
+  std::vector<std::string> Features;
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Basic/TemplateKinds.h b/include/clang/Basic/TemplateKinds.h
new file mode 100644
index 0000000..c6ea05b
--- /dev/null
+++ b/include/clang/Basic/TemplateKinds.h
@@ -0,0 +1,39 @@
+//===--- TemplateKinds.h - Enum values for C++ Template Kinds ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the TemplateNameKind enum.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_TEMPLATEKINDS_H
+#define LLVM_CLANG_TEMPLATEKINDS_H
+
+namespace clang {
+
+/// \brief Specifies the kind of template name that an identifier refers to.
+enum TemplateNameKind {
+  /// The name does not refer to a template.
+  TNK_Non_template = 0,
+  /// The name refers to a function template or a set of overloaded
+  /// functions that includes at least one function template.
+  TNK_Function_template,
+  /// The name refers to a template whose specialization produces a
+  /// type. The template itself could be a class template, template
+  /// template parameter, or C++0x template alias.
+  TNK_Type_template,
+  /// The name refers to a dependent template name. Whether the
+  /// template name is assumed to refer to a type template or a
+  /// function template depends on the context in which the template
+  /// name occurs.
+  TNK_Dependent_template_name
+};
+
+}
+#endif
+
+
diff --git a/include/clang/Basic/TokenKinds.def b/include/clang/Basic/TokenKinds.def
new file mode 100644
index 0000000..52e83f4
--- /dev/null
+++ b/include/clang/Basic/TokenKinds.def
@@ -0,0 +1,427 @@
+//===--- TokenKinds.def - C Family Token Kind Database ----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the TokenKind database.  This includes normal tokens like
+// tok::ampamp (corresponding to the && token) as well as keywords for various
+// languages.  Users of this file must optionally #define the TOK, KEYWORD,
+// ALIAS, or PPKEYWORD macros to make use of this file.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef TOK
+#define TOK(X)
+#endif
+#ifndef PUNCTUATOR
+#define PUNCTUATOR(X,Y) TOK(X)
+#endif
+#ifndef KEYWORD
+#define KEYWORD(X,Y) TOK(kw_ ## X)
+#endif
+#ifndef ALIAS
+#define ALIAS(X,Y,Z)
+#endif
+#ifndef PPKEYWORD
+#define PPKEYWORD(X)
+#endif
+#ifndef CXX_KEYWORD_OPERATOR
+#define CXX_KEYWORD_OPERATOR(X,Y)
+#endif
+#ifndef OBJC1_AT_KEYWORD
+#define OBJC1_AT_KEYWORD(X)
+#endif
+#ifndef OBJC2_AT_KEYWORD
+#define OBJC2_AT_KEYWORD(X)
+#endif
+#ifndef ANNOTATION
+#define ANNOTATION(X) TOK(annot_ ## X)
+#endif
+
+//===----------------------------------------------------------------------===//
+// Preprocessor keywords.
+//===----------------------------------------------------------------------===//
+
+// These have meaning after a '#' at the start of a line. These define enums in
+// the tok::pp_* namespace.  Note that IdentifierInfo::getPPKeywordID must be
+// manually updated if something is added here.
+PPKEYWORD(not_keyword)
+
+// C99 6.10.1 - Conditional Inclusion.
+PPKEYWORD(if)
+PPKEYWORD(ifdef)
+PPKEYWORD(ifndef)
+PPKEYWORD(elif)
+PPKEYWORD(else)
+PPKEYWORD(endif)
+PPKEYWORD(defined)
+
+// C99 6.10.2 - Source File Inclusion.
+PPKEYWORD(include)
+PPKEYWORD(__include_macros)
+
+// C99 6.10.3 - Macro Replacement.
+PPKEYWORD(define)
+PPKEYWORD(undef)
+
+// C99 6.10.4 - Line Control.
+PPKEYWORD(line)
+
+// C99 6.10.5 - Error Directive.
+PPKEYWORD(error)
+
+// C99 6.10.6 - Pragma Directive.
+PPKEYWORD(pragma)
+
+// GNU Extensions.
+PPKEYWORD(import)
+PPKEYWORD(include_next)
+PPKEYWORD(warning)
+PPKEYWORD(ident)
+PPKEYWORD(sccs)
+PPKEYWORD(assert)
+PPKEYWORD(unassert)
+
+//===----------------------------------------------------------------------===//
+// Language keywords.
+//===----------------------------------------------------------------------===//
+
+// These define members of the tok::* namespace.
+
+TOK(unknown)             // Not a token.
+TOK(eof)                 // End of file.
+TOK(eom)                 // End of macro (end of line inside a macro).
+TOK(code_completion)     // Code completion marker
+
+// C99 6.4.9: Comments.
+TOK(comment)             // Comment (only in -E -C[C] mode)
+
+// C99 6.4.2: Identifiers.
+TOK(identifier)          // abcde123
+
+// C99 6.4.4.1: Integer Constants
+// C99 6.4.4.2: Floating Constants
+TOK(numeric_constant)    // 0x123
+
+// C99 6.4.4: Character Constants
+TOK(char_constant)       // 'a'   L'b'
+
+// C99 6.4.5: String Literals.
+TOK(string_literal)      // "foo"
+TOK(wide_string_literal) // L"foo"
+TOK(angle_string_literal)// <foo>
+
+// C99 6.4.6: Punctuators.
+PUNCTUATOR(l_square,            "[")
+PUNCTUATOR(r_square,            "]")
+PUNCTUATOR(l_paren,             "(")
+PUNCTUATOR(r_paren,             ")")
+PUNCTUATOR(l_brace,             "{")
+PUNCTUATOR(r_brace,             "}")
+PUNCTUATOR(period,              ".")
+PUNCTUATOR(ellipsis,            "...")
+PUNCTUATOR(amp,                 "&")
+PUNCTUATOR(ampamp,              "&&")
+PUNCTUATOR(ampequal,            "&=")
+PUNCTUATOR(star,                "*")
+PUNCTUATOR(starequal,           "*=")
+PUNCTUATOR(plus,                "+")
+PUNCTUATOR(plusplus,            "++")
+PUNCTUATOR(plusequal,           "+=")
+PUNCTUATOR(minus,               "-")
+PUNCTUATOR(arrow,               "->")
+PUNCTUATOR(minusminus,          "--")
+PUNCTUATOR(minusequal,          "-=")
+PUNCTUATOR(tilde,               "~")
+PUNCTUATOR(exclaim,             "!")
+PUNCTUATOR(exclaimequal,        "!=")
+PUNCTUATOR(slash,               "/")
+PUNCTUATOR(slashequal,          "/=")
+PUNCTUATOR(percent,             "%")
+PUNCTUATOR(percentequal,        "%=")
+PUNCTUATOR(less,                "<")
+PUNCTUATOR(lessless,            "<<")
+PUNCTUATOR(lessequal,           "<=")
+PUNCTUATOR(lesslessequal,       "<<=")
+PUNCTUATOR(greater,             ">")
+PUNCTUATOR(greatergreater,      ">>")
+PUNCTUATOR(greaterequal,        ">=")
+PUNCTUATOR(greatergreaterequal, ">>=")
+PUNCTUATOR(caret,               "^")
+PUNCTUATOR(caretequal,          "^=")
+PUNCTUATOR(pipe,                "|")
+PUNCTUATOR(pipepipe,            "||")
+PUNCTUATOR(pipeequal,           "|=")
+PUNCTUATOR(question,            "?")
+PUNCTUATOR(colon,               ":")
+PUNCTUATOR(semi,                ";")
+PUNCTUATOR(equal,               "=")
+PUNCTUATOR(equalequal,          "==")
+PUNCTUATOR(comma,               ",")
+PUNCTUATOR(hash,                "#")
+PUNCTUATOR(hashhash,            "##")
+PUNCTUATOR(hashat,              "#@")
+
+// C++ Support
+PUNCTUATOR(periodstar,          ".*")
+PUNCTUATOR(arrowstar,           "->*")
+PUNCTUATOR(coloncolon,          "::")
+
+// Objective C support.
+PUNCTUATOR(at,                  "@")
+
+// C99 6.4.1: Keywords.  These turn into kw_* tokens.
+// Flags allowed:
+//   KEYALL   - This is a keyword in all variants of C and C++, or it
+//              is a keyword in the implementation namespace that should
+//              always be treated as a keyword
+//   KEYC99   - This is a keyword introduced to C in C99
+//   KEYCXX   - This is a C++ keyword, or a C++-specific keyword in the
+//              implementation namespace
+//   KEYCXX0X - This is a C++ keyword introduced to C++ in C++0x
+//   KEYGNU   - This is a keyword if GNU extensions are enabled
+//   KEYMS    - This is a keyword if Microsoft extensions are enabled
+//
+KEYWORD(auto                        , KEYALL)
+KEYWORD(break                       , KEYALL)
+KEYWORD(case                        , KEYALL)
+KEYWORD(char                        , KEYALL)
+KEYWORD(const                       , KEYALL)
+KEYWORD(continue                    , KEYALL)
+KEYWORD(default                     , KEYALL)
+KEYWORD(do                          , KEYALL)
+KEYWORD(double                      , KEYALL)
+KEYWORD(else                        , KEYALL)
+KEYWORD(enum                        , KEYALL)
+KEYWORD(extern                      , KEYALL)
+KEYWORD(float                       , KEYALL)
+KEYWORD(for                         , KEYALL)
+KEYWORD(goto                        , KEYALL)
+KEYWORD(if                          , KEYALL)
+KEYWORD(inline                      , KEYC99|KEYCXX|KEYGNU)
+KEYWORD(int                         , KEYALL)
+KEYWORD(long                        , KEYALL)
+KEYWORD(register                    , KEYALL)
+KEYWORD(restrict                    , KEYC99)
+KEYWORD(return                      , KEYALL)
+KEYWORD(short                       , KEYALL)
+KEYWORD(signed                      , KEYALL)
+KEYWORD(sizeof                      , KEYALL)
+KEYWORD(static                      , KEYALL)
+KEYWORD(struct                      , KEYALL)
+KEYWORD(switch                      , KEYALL)
+KEYWORD(typedef                     , KEYALL)
+KEYWORD(union                       , KEYALL)
+KEYWORD(unsigned                    , KEYALL)
+KEYWORD(void                        , KEYALL)
+KEYWORD(volatile                    , KEYALL)
+KEYWORD(while                       , KEYALL)
+KEYWORD(_Bool                       , KEYALL)
+KEYWORD(_Complex                    , KEYALL)
+KEYWORD(_Imaginary                  , KEYALL)
+KEYWORD(__func__                    , KEYALL)
+
+// C++ 2.11p1: Keywords.
+KEYWORD(asm                         , KEYCXX|KEYGNU)
+KEYWORD(bool                        , BOOLSUPPORT|KEYALTIVEC)
+KEYWORD(catch                       , KEYCXX)
+KEYWORD(class                       , KEYCXX)
+KEYWORD(const_cast                  , KEYCXX)
+KEYWORD(delete                      , KEYCXX)
+KEYWORD(dynamic_cast                , KEYCXX)
+KEYWORD(explicit                    , KEYCXX)
+KEYWORD(export                      , KEYCXX)
+KEYWORD(false                       , BOOLSUPPORT|KEYALTIVEC)
+KEYWORD(friend                      , KEYCXX)
+KEYWORD(mutable                     , KEYCXX)
+KEYWORD(namespace                   , KEYCXX)
+KEYWORD(new                         , KEYCXX)
+KEYWORD(operator                    , KEYCXX)
+KEYWORD(private                     , KEYCXX)
+KEYWORD(protected                   , KEYCXX)
+KEYWORD(public                      , KEYCXX)
+KEYWORD(reinterpret_cast            , KEYCXX)
+KEYWORD(static_cast                 , KEYCXX)
+KEYWORD(template                    , KEYCXX)
+KEYWORD(this                        , KEYCXX)
+KEYWORD(throw                       , KEYCXX)
+KEYWORD(true                        , BOOLSUPPORT|KEYALTIVEC)
+KEYWORD(try                         , KEYCXX)
+KEYWORD(typename                    , KEYCXX)
+KEYWORD(typeid                      , KEYCXX)
+KEYWORD(using                       , KEYCXX)
+KEYWORD(virtual                     , KEYCXX)
+KEYWORD(wchar_t                     , KEYCXX)
+
+// C++ 2.5p2: Alternative Representations.
+CXX_KEYWORD_OPERATOR(and     , ampamp)
+CXX_KEYWORD_OPERATOR(and_eq  , ampequal)
+CXX_KEYWORD_OPERATOR(bitand  , amp)
+CXX_KEYWORD_OPERATOR(bitor   , pipe)
+CXX_KEYWORD_OPERATOR(compl   , tilde)
+CXX_KEYWORD_OPERATOR(not     , exclaim)
+CXX_KEYWORD_OPERATOR(not_eq  , exclaimequal)
+CXX_KEYWORD_OPERATOR(or      , pipepipe)
+CXX_KEYWORD_OPERATOR(or_eq   , pipeequal)
+CXX_KEYWORD_OPERATOR(xor     , caret)
+CXX_KEYWORD_OPERATOR(xor_eq  , caretequal)
+
+// C++0x keywords
+KEYWORD(alignof                     , KEYCXX0X)
+KEYWORD(axiom                       , KEYCXX0X)
+KEYWORD(char16_t                    , KEYCXX0X)
+KEYWORD(char32_t                    , KEYCXX0X)
+KEYWORD(concept                     , KEYCXX0X)
+KEYWORD(concept_map                 , KEYCXX0X)
+KEYWORD(constexpr                   , KEYCXX0X)
+KEYWORD(decltype                    , KEYCXX0X)
+KEYWORD(late_check                  , KEYCXX0X)
+KEYWORD(nullptr                     , KEYCXX0X)
+KEYWORD(requires                    , KEYCXX0X)
+KEYWORD(static_assert               , KEYCXX0X)
+KEYWORD(thread_local                , KEYCXX0X)
+
+// GNU Extensions (in impl-reserved namespace)
+KEYWORD(_Decimal32                  , KEYALL)
+KEYWORD(_Decimal64                  , KEYALL)
+KEYWORD(_Decimal128                 , KEYALL)
+KEYWORD(__null                      , KEYCXX)
+KEYWORD(__alignof                   , KEYALL)
+KEYWORD(__attribute                 , KEYALL)
+KEYWORD(__builtin_choose_expr       , KEYALL)
+KEYWORD(__builtin_offsetof          , KEYALL)
+KEYWORD(__builtin_types_compatible_p, KEYALL)
+KEYWORD(__builtin_va_arg            , KEYALL)
+KEYWORD(__extension__               , KEYALL)
+KEYWORD(__imag                      , KEYALL)
+KEYWORD(__label__                   , KEYALL)
+KEYWORD(__real                      , KEYALL)
+KEYWORD(__thread                    , KEYALL)
+KEYWORD(__FUNCTION__                , KEYALL)
+KEYWORD(__PRETTY_FUNCTION__         , KEYALL)
+
+// GNU Extensions (outside impl-reserved namespace)
+KEYWORD(typeof                      , KEYGNU)
+
+// GNU and MS Type Traits
+KEYWORD(__has_nothrow_assign        , KEYCXX)
+KEYWORD(__has_nothrow_copy          , KEYCXX)
+KEYWORD(__has_nothrow_constructor   , KEYCXX)
+KEYWORD(__has_trivial_assign        , KEYCXX)
+KEYWORD(__has_trivial_copy          , KEYCXX)
+KEYWORD(__has_trivial_constructor   , KEYCXX)
+KEYWORD(__has_trivial_destructor    , KEYCXX)
+KEYWORD(__has_virtual_destructor    , KEYCXX)
+KEYWORD(__is_abstract               , KEYCXX)
+KEYWORD(__is_base_of                , KEYCXX)
+KEYWORD(__is_class                  , KEYCXX)
+KEYWORD(__is_empty                  , KEYCXX)
+KEYWORD(__is_enum                   , KEYCXX)
+KEYWORD(__is_pod                    , KEYCXX)
+KEYWORD(__is_polymorphic            , KEYCXX)
+KEYWORD(__is_union                  , KEYCXX)
+// Tentative name - there's no implementation of std::is_literal_type yet.
+KEYWORD(__is_literal                , KEYCXX)
+// FIXME: Add MS's traits, too.
+
+// Apple Extension.
+KEYWORD(__private_extern__          , KEYALL)
+
+// Microsoft Extension.
+KEYWORD(__declspec                  , KEYALL)
+KEYWORD(__cdecl                     , KEYALL)
+KEYWORD(__stdcall                   , KEYALL)
+KEYWORD(__fastcall                  , KEYALL)
+KEYWORD(__forceinline               , KEYALL)
+
+// Altivec Extension.
+KEYWORD(__vector                    , KEYALTIVEC)
+KEYWORD(__pixel                     , KEYALTIVEC)
+
+// Alternate spelling for various tokens.  There are GCC extensions in all
+// languages, but should not be disabled in strict conformance mode.
+ALIAS("__attribute__", __attribute, KEYALL)
+ALIAS("__const"      , const      , KEYALL)
+ALIAS("__const__"    , const      , KEYALL)
+ALIAS("__alignof__"  , __alignof  , KEYALL)
+ALIAS("__asm"        , asm        , KEYALL)
+ALIAS("__asm__"      , asm        , KEYALL)
+ALIAS("__complex"    , _Complex   , KEYALL)
+ALIAS("__complex__"  , _Complex   , KEYALL)
+ALIAS("__imag__"     , __imag     , KEYALL)
+ALIAS("__inline"     , inline     , KEYALL)
+ALIAS("__inline__"   , inline     , KEYALL)
+ALIAS("__real__"     , __real     , KEYALL)
+ALIAS("__restrict"   , restrict   , KEYALL)
+ALIAS("__restrict__" , restrict   , KEYALL)
+ALIAS("__signed"     , signed     , KEYALL)
+ALIAS("__signed__"   , signed     , KEYALL)
+ALIAS("__typeof"     , typeof     , KEYALL)
+ALIAS("__typeof__"   , typeof     , KEYALL)
+ALIAS("__volatile"   , volatile   , KEYALL)
+ALIAS("__volatile__" , volatile   , KEYALL)
+
+// Microsoft extensions which should be disabled in strict conformance mode
+KEYWORD(__ptr64                   , KEYMS)
+KEYWORD(__w64                     , KEYMS)
+ALIAS("_asm"         , asm        , KEYMS)
+ALIAS("_cdecl"       , __cdecl    , KEYMS)
+ALIAS("_fastcall"    , __fastcall , KEYMS)
+ALIAS("_stdcall"     , __stdcall  , KEYMS)
+
+//===----------------------------------------------------------------------===//
+// Objective-C @-preceeded keywords.
+//===----------------------------------------------------------------------===//
+
+// These have meaning after an '@' in Objective-C mode. These define enums in
+// the tok::objc_* namespace.
+
+OBJC1_AT_KEYWORD(not_keyword)
+OBJC1_AT_KEYWORD(class)
+OBJC1_AT_KEYWORD(compatibility_alias)
+OBJC1_AT_KEYWORD(defs)
+OBJC1_AT_KEYWORD(encode)
+OBJC1_AT_KEYWORD(end)
+OBJC1_AT_KEYWORD(implementation)
+OBJC1_AT_KEYWORD(interface)
+OBJC1_AT_KEYWORD(private)
+OBJC1_AT_KEYWORD(protected)
+OBJC1_AT_KEYWORD(protocol)
+OBJC1_AT_KEYWORD(public)
+OBJC1_AT_KEYWORD(selector)
+OBJC1_AT_KEYWORD(throw)
+OBJC1_AT_KEYWORD(try)
+OBJC1_AT_KEYWORD(catch)
+OBJC1_AT_KEYWORD(finally)
+OBJC1_AT_KEYWORD(synchronized)
+
+OBJC2_AT_KEYWORD(property)
+OBJC2_AT_KEYWORD(package)
+OBJC2_AT_KEYWORD(required)
+OBJC2_AT_KEYWORD(optional)
+OBJC2_AT_KEYWORD(synthesize)
+OBJC2_AT_KEYWORD(dynamic)
+
+// TODO: What to do about context-sensitive keywords like:
+//       bycopy/byref/in/inout/oneway/out?
+
+ANNOTATION(cxxscope)     // annotation for a C++ scope spec, e.g. "::foo::bar::"
+ANNOTATION(typename)     // annotation for a C typedef name, a C++ (possibly
+                         // qualified) typename, e.g. "foo::MyClass", or
+                         // template-id that names a type ("std::vector<int>")
+ANNOTATION(template_id)  // annotation for a C++ template-id that names a
+                         // function template specialization (not a type),
+                         // e.g., "std::swap<int>"
+#undef ANNOTATION
+#undef OBJC2_AT_KEYWORD
+#undef OBJC1_AT_KEYWORD
+#undef CXX_KEYWORD_OPERATOR
+#undef PPKEYWORD
+#undef ALIAS
+#undef KEYWORD
+#undef PUNCTUATOR
+#undef TOK
diff --git a/include/clang/Basic/TokenKinds.h b/include/clang/Basic/TokenKinds.h
new file mode 100644
index 0000000..85dc067
--- /dev/null
+++ b/include/clang/Basic/TokenKinds.h
@@ -0,0 +1,64 @@
+//===--- TokenKinds.h - Enum values for C Token Kinds -----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the TokenKind enum and support functions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOKENKINDS_H
+#define LLVM_CLANG_TOKENKINDS_H
+
+namespace clang {
+
+namespace tok {
+
+/// TokenKind - This provides a simple uniform namespace for tokens from all C
+/// languages.
+enum TokenKind {
+#define TOK(X) X,
+#include "clang/Basic/TokenKinds.def"
+  NUM_TOKENS
+};
+
+/// PPKeywordKind - This provides a namespace for preprocessor keywords which
+/// start with a '#' at the beginning of the line.
+enum PPKeywordKind {
+#define PPKEYWORD(X) pp_##X,
+#include "clang/Basic/TokenKinds.def"
+  NUM_PP_KEYWORDS
+};
+
+/// ObjCKeywordKind - This provides a namespace for Objective-C keywords which
+/// start with an '@'.
+enum ObjCKeywordKind {
+#define OBJC1_AT_KEYWORD(X) objc_##X,
+#define OBJC2_AT_KEYWORD(X) objc_##X,
+#include "clang/Basic/TokenKinds.def"
+  NUM_OBJC_KEYWORDS
+};
+
+/// \brief Determines the name of a token as used within the front end.
+///
+/// The name of a token will be an internal name (such as "l_square")
+/// and should not be used as part of diagnostic messages.
+const char *getTokenName(enum TokenKind Kind);
+
+/// \brief Determines the spelling of simple punctuation tokens like
+/// '!' or '%', and returns NULL for literal and annotation tokens.
+///
+/// This routine only retrieves the "simple" spelling of the token,
+/// and will not produce any alternative spellings (e.g., a
+/// digraph). For the actual spelling of a given Token, use
+/// Preprocessor::getSpelling().
+const char *getTokenSimpleSpelling(enum TokenKind Kind);
+
+}  // end namespace tok
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Basic/TypeTraits.h b/include/clang/Basic/TypeTraits.h
new file mode 100644
index 0000000..36b8300
--- /dev/null
+++ b/include/clang/Basic/TypeTraits.h
@@ -0,0 +1,41 @@
+//===--- TypeTraits.h - C++ Type Traits Support Enumerations ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines enumerations for the type traits support.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TYPETRAITS_H
+#define LLVM_CLANG_TYPETRAITS_H
+
+namespace clang {
+
+  /// UnaryTypeTrait - Names for the unary type traits.
+  enum UnaryTypeTrait {
+    UTT_HasNothrowAssign,
+    UTT_HasNothrowCopy,
+    UTT_HasNothrowConstructor,
+    UTT_HasTrivialAssign,
+    UTT_HasTrivialCopy,
+    UTT_HasTrivialConstructor,
+    UTT_HasTrivialDestructor,
+    UTT_HasVirtualDestructor,
+    UTT_IsAbstract,
+    UTT_IsClass,
+    UTT_IsEmpty,
+    UTT_IsEnum,
+    UTT_IsPOD,
+    UTT_IsPolymorphic,
+    UTT_IsUnion,
+    UTT_IsLiteral
+  };
+
+}
+
+#endif
diff --git a/include/clang/Basic/Version.h b/include/clang/Basic/Version.h
new file mode 100644
index 0000000..2e0993a
--- /dev/null
+++ b/include/clang/Basic/Version.h
@@ -0,0 +1,71 @@
+//===- Version.h - Clang Version Number -------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header defines version macros and version-related utility functions 
+// for Clang.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_VERSION_H
+#define LLVM_CLANG_BASIC_VERSION_H
+
+#include "llvm/ADT/StringRef.h"
+
+/// \brief Clang major version
+#define CLANG_VERSION_MAJOR 1
+
+// FIXME: Updates to this file must also update CMakeLists.txt and VER.
+/// \brief Clang minor version
+#define CLANG_VERSION_MINOR 5
+
+/// \brief Clang patchlevel version
+// #define CLANG_VERSION_PATCHLEVEL 1
+
+/// \brief Helper macro for CLANG_VERSION_STRING.
+#define CLANG_MAKE_VERSION_STRING2(X) #X
+
+#ifdef CLANG_VERSION_PATCHLEVEL
+/// \brief Helper macro for CLANG_VERSION_STRING.
+#define CLANG_MAKE_VERSION_STRING(X,Y,Z) CLANG_MAKE_VERSION_STRING2(X.Y.Z)
+
+/// \brief A string that describes the Clang version number, e.g.,
+/// "1.0".
+#define CLANG_VERSION_STRING \
+  CLANG_MAKE_VERSION_STRING(CLANG_VERSION_MAJOR,CLANG_VERSION_MINOR,CLANG_VERSION_PATCHLEVEL)
+#else
+/// \brief Helper macro for CLANG_VERSION_STRING.
+#define CLANG_MAKE_VERSION_STRING(X,Y) CLANG_MAKE_VERSION_STRING2(X.Y)
+
+/// \brief A string that describes the Clang version number, e.g.,
+/// "1.0".
+#define CLANG_VERSION_STRING \
+  CLANG_MAKE_VERSION_STRING(CLANG_VERSION_MAJOR,CLANG_VERSION_MINOR)
+#endif
+
+namespace clang {
+  /// \brief Retrieves the repository path (e.g., Subversion path) that 
+  /// identifies the particular Clang branch, tag, or trunk from which this
+  /// Clang was built.
+  llvm::StringRef getClangRepositoryPath();
+  
+  /// \brief Retrieves the repository revision number (or identifer) from which
+  ///  this Clang was built.
+  std::string getClangRevision();
+  
+  /// \brief Retrieves the full repository version that is an amalgamation of
+  ///  the information in getClangRepositoryPath() and getClangRevision().
+  std::string getClangFullRepositoryVersion();
+  
+  /// \brief Retrieves a string representing the complete clang version,
+  ///   which includes the clang version number, the repository version, 
+  ///   and the vendor tag.
+  std::string getClangFullVersion();
+}
+
+#endif // LLVM_CLANG_BASIC_VERSION_H
diff --git a/include/clang/CMakeLists.txt b/include/clang/CMakeLists.txt
new file mode 100644
index 0000000..61d2bf6
--- /dev/null
+++ b/include/clang/CMakeLists.txt
@@ -0,0 +1,2 @@
+add_subdirectory(Basic)
+add_subdirectory(Driver)
diff --git a/include/clang/Checker/BugReporter/BugReporter.h b/include/clang/Checker/BugReporter/BugReporter.h
new file mode 100644
index 0000000..5b65d52
--- /dev/null
+++ b/include/clang/Checker/BugReporter/BugReporter.h
@@ -0,0 +1,479 @@
+//===---  BugReporter.h - Generate PathDiagnostics --------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines BugReporter, a utility class for generating
+//  PathDiagnostics for analyses based on GRState.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_BUGREPORTER
+#define LLVM_CLANG_ANALYSIS_BUGREPORTER
+
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Checker/PathSensitive/GRState.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/ImmutableList.h"
+#include "llvm/ADT/ImmutableSet.h"
+#include "llvm/ADT/SmallSet.h"
+#include <list>
+
+namespace clang {
+
+class PathDiagnostic;
+class PathDiagnosticPiece;
+class PathDiagnosticClient;
+class ASTContext;
+class Diagnostic;
+class ExplodedNode;
+class ExplodedGraph;
+class BugReporter;
+class BugReporterContext;
+class GRExprEngine;
+class GRState;
+class Stmt;
+class BugType;
+class ParentMap;
+
+//===----------------------------------------------------------------------===//
+// Interface for individual bug reports.
+//===----------------------------------------------------------------------===//
+
+class BugReporterVisitor : public llvm::FoldingSetNode {
+public:
+  virtual ~BugReporterVisitor();
+  virtual PathDiagnosticPiece* VisitNode(const ExplodedNode* N,
+                                         const ExplodedNode* PrevN,
+                                         BugReporterContext& BRC) = 0;
+
+  virtual bool isOwnedByReporterContext() { return true; }
+  virtual void Profile(llvm::FoldingSetNodeID &ID) const = 0;
+};
+
+// FIXME: Combine this with RangedBugReport and remove RangedBugReport.
+class BugReport : public BugReporterVisitor {
+protected:
+  BugType& BT;
+  std::string ShortDescription;
+  std::string Description;
+  const ExplodedNode *EndNode;
+  SourceRange R;
+
+protected:
+  friend class BugReporter;
+  friend class BugReportEquivClass;
+
+  virtual void Profile(llvm::FoldingSetNodeID& hash) const {
+    hash.AddInteger(getLocation().getRawEncoding());
+  }
+
+public:
+  class NodeResolver {
+  public:
+    virtual ~NodeResolver() {}
+    virtual const ExplodedNode*
+            getOriginalNode(const ExplodedNode* N) = 0;
+  };
+
+  BugReport(BugType& bt, llvm::StringRef desc, const ExplodedNode *n)
+    : BT(bt), Description(desc), EndNode(n) {}
+
+  BugReport(BugType& bt, llvm::StringRef shortDesc, llvm::StringRef desc,
+            const ExplodedNode *n)
+  : BT(bt), ShortDescription(shortDesc), Description(desc), EndNode(n) {}
+
+  virtual ~BugReport();
+
+  virtual bool isOwnedByReporterContext() { return false; }
+
+  const BugType& getBugType() const { return BT; }
+  BugType& getBugType() { return BT; }
+
+  // FIXME: Perhaps this should be moved into a subclass?
+  const ExplodedNode* getEndNode() const { return EndNode; }
+
+  // FIXME: Do we need this?  Maybe getLocation() should return a ProgramPoint
+  // object.
+  // FIXME: If we do need it, we can probably just make it private to
+  // BugReporter.
+  const Stmt* getStmt() const;
+
+  const llvm::StringRef getDescription() const { return Description; }
+
+  const llvm::StringRef getShortDescription() const {
+    return ShortDescription.empty() ? Description : ShortDescription;
+  }
+
+  // FIXME: Is this needed?
+  virtual std::pair<const char**,const char**> getExtraDescriptiveText() {
+    return std::make_pair((const char**)0,(const char**)0);
+  }
+
+  // FIXME: Perhaps move this into a subclass.
+  virtual PathDiagnosticPiece* getEndPath(BugReporterContext& BRC,
+                                          const ExplodedNode* N);
+
+  /// getLocation - Return the "definitive" location of the reported bug.
+  ///  While a bug can span an entire path, usually there is a specific
+  ///  location that can be used to identify where the key issue occured.
+  ///  This location is used by clients rendering diagnostics.
+  virtual SourceLocation getLocation() const;
+
+  /// getRanges - Returns the source ranges associated with this bug.
+  virtual void getRanges(const SourceRange*& beg, const SourceRange*& end);
+
+  virtual PathDiagnosticPiece* VisitNode(const ExplodedNode* N,
+                                         const ExplodedNode* PrevN,
+                                         BugReporterContext& BR);
+
+  virtual void registerInitialVisitors(BugReporterContext& BRC,
+                                       const ExplodedNode* N) {}
+};
+
+//===----------------------------------------------------------------------===//
+// BugTypes (collections of related reports).
+//===----------------------------------------------------------------------===//
+
+class BugReportEquivClass : public llvm::FoldingSetNode {
+  // List of *owned* BugReport objects.
+  std::list<BugReport*> Reports;
+
+  friend class BugReporter;
+  void AddReport(BugReport* R) { Reports.push_back(R); }
+public:
+  BugReportEquivClass(BugReport* R) { Reports.push_back(R); }
+  ~BugReportEquivClass();
+
+  void Profile(llvm::FoldingSetNodeID& ID) const {
+    assert(!Reports.empty());
+    (*Reports.begin())->Profile(ID);
+  }
+
+  class iterator {
+    std::list<BugReport*>::iterator impl;
+  public:
+    iterator(std::list<BugReport*>::iterator i) : impl(i) {}
+    iterator& operator++() { ++impl; return *this; }
+    bool operator==(const iterator& I) const { return I.impl == impl; }
+    bool operator!=(const iterator& I) const { return I.impl != impl; }
+    BugReport* operator*() const { return *impl; }
+    BugReport* operator->() const { return *impl; }
+  };
+
+  class const_iterator {
+    std::list<BugReport*>::const_iterator impl;
+  public:
+    const_iterator(std::list<BugReport*>::const_iterator i) : impl(i) {}
+    const_iterator& operator++() { ++impl; return *this; }
+    bool operator==(const const_iterator& I) const { return I.impl == impl; }
+    bool operator!=(const const_iterator& I) const { return I.impl != impl; }
+    const BugReport* operator*() const { return *impl; }
+    const BugReport* operator->() const { return *impl; }
+  };
+
+  iterator begin() { return iterator(Reports.begin()); }
+  iterator end() { return iterator(Reports.end()); }
+
+  const_iterator begin() const { return const_iterator(Reports.begin()); }
+  const_iterator end() const { return const_iterator(Reports.end()); }
+};
+
+
+//===----------------------------------------------------------------------===//
+// Specialized subclasses of BugReport.
+//===----------------------------------------------------------------------===//
+
+// FIXME: Collapse this with the default BugReport class.
+class RangedBugReport : public BugReport {
+  std::vector<SourceRange> Ranges;
+public:
+  RangedBugReport(BugType& D, llvm::StringRef description, ExplodedNode *n)
+    : BugReport(D, description, n) {}
+
+  RangedBugReport(BugType& D, llvm::StringRef shortDescription,
+                  llvm::StringRef description, ExplodedNode *n)
+  : BugReport(D, shortDescription, description, n) {}
+
+  ~RangedBugReport();
+
+  // FIXME: Move this out of line.
+  void addRange(SourceRange R) {
+    assert(R.isValid());
+    Ranges.push_back(R);
+  }
+
+  // FIXME: Move this out of line.
+  void getRanges(const SourceRange*& beg, const SourceRange*& end) {
+
+    if (Ranges.empty()) {
+      beg = NULL;
+      end = NULL;
+    }
+    else {
+      beg = &Ranges[0];
+      end = beg + Ranges.size();
+    }
+  }
+};
+
+class EnhancedBugReport : public RangedBugReport {
+public:
+  typedef void (*VisitorCreator)(BugReporterContext &BRcC, const void *data,
+                                 const ExplodedNode *N);
+
+private:
+  typedef std::vector<std::pair<VisitorCreator, const void*> > Creators;
+  Creators creators;
+
+public:
+  EnhancedBugReport(BugType& D, llvm::StringRef description, ExplodedNode *n)
+   : RangedBugReport(D, description, n) {}
+
+  EnhancedBugReport(BugType& D, llvm::StringRef shortDescription,
+                   llvm::StringRef description, ExplodedNode *n)
+    : RangedBugReport(D, shortDescription, description, n) {}
+
+  ~EnhancedBugReport() {}
+
+  void registerInitialVisitors(BugReporterContext& BRC, const ExplodedNode* N) {
+    for (Creators::iterator I = creators.begin(), E = creators.end(); I!=E; ++I)
+      I->first(BRC, I->second, N);
+  }
+
+  void addVisitorCreator(VisitorCreator creator, const void *data) {
+    creators.push_back(std::make_pair(creator, data));
+  }
+};
+
+//===----------------------------------------------------------------------===//
+// BugReporter and friends.
+//===----------------------------------------------------------------------===//
+
+class BugReporterData {
+public:
+  virtual ~BugReporterData();
+  virtual Diagnostic& getDiagnostic() = 0;
+  virtual PathDiagnosticClient* getPathDiagnosticClient() = 0;
+  virtual ASTContext& getASTContext() = 0;
+  virtual SourceManager& getSourceManager() = 0;
+};
+
+class BugReporter {
+public:
+  enum Kind { BaseBRKind, GRBugReporterKind };
+
+private:
+  typedef llvm::ImmutableSet<BugType*> BugTypesTy;
+  BugTypesTy::Factory F;
+  BugTypesTy BugTypes;
+
+  const Kind kind;
+  BugReporterData& D;
+
+  void FlushReport(BugReportEquivClass& EQ);
+
+protected:
+  BugReporter(BugReporterData& d, Kind k) : BugTypes(F.GetEmptySet()), kind(k), D(d) {}
+
+public:
+  BugReporter(BugReporterData& d) : BugTypes(F.GetEmptySet()), kind(BaseBRKind), D(d) {}
+  virtual ~BugReporter();
+
+  void FlushReports();
+
+  Kind getKind() const { return kind; }
+
+  Diagnostic& getDiagnostic() {
+    return D.getDiagnostic();
+  }
+
+  PathDiagnosticClient* getPathDiagnosticClient() {
+    return D.getPathDiagnosticClient();
+  }
+
+  typedef BugTypesTy::iterator iterator;
+  iterator begin() { return BugTypes.begin(); }
+  iterator end() { return BugTypes.end(); }
+
+  ASTContext& getContext() { return D.getASTContext(); }
+
+  SourceManager& getSourceManager() { return D.getSourceManager(); }
+
+  virtual void GeneratePathDiagnostic(PathDiagnostic& PD,
+                                      BugReportEquivClass& EQ) {}
+
+  void Register(BugType *BT);
+
+  void EmitReport(BugReport *R);
+
+  void EmitBasicReport(llvm::StringRef BugName, llvm::StringRef BugStr,
+                       SourceLocation Loc,
+                       SourceRange* RangeBeg, unsigned NumRanges);
+
+  void EmitBasicReport(llvm::StringRef BugName, llvm::StringRef BugCategory,
+                       llvm::StringRef BugStr, SourceLocation Loc,
+                       SourceRange* RangeBeg, unsigned NumRanges);
+
+
+  void EmitBasicReport(llvm::StringRef BugName, llvm::StringRef BugStr,
+                       SourceLocation Loc) {
+    EmitBasicReport(BugName, BugStr, Loc, 0, 0);
+  }
+
+  void EmitBasicReport(llvm::StringRef BugName, llvm::StringRef BugCategory,
+                       llvm::StringRef BugStr, SourceLocation Loc) {
+    EmitBasicReport(BugName, BugCategory, BugStr, Loc, 0, 0);
+  }
+
+  void EmitBasicReport(llvm::StringRef BugName, llvm::StringRef BugStr,
+                       SourceLocation Loc, SourceRange R) {
+    EmitBasicReport(BugName, BugStr, Loc, &R, 1);
+  }
+
+  void EmitBasicReport(llvm::StringRef BugName, llvm::StringRef Category,
+                       llvm::StringRef BugStr, SourceLocation Loc,
+                       SourceRange R) {
+    EmitBasicReport(BugName, Category, BugStr, Loc, &R, 1);
+  }
+
+  static bool classof(const BugReporter* R) { return true; }
+};
+
+// FIXME: Get rid of GRBugReporter.  It's the wrong abstraction.
+class GRBugReporter : public BugReporter {
+  GRExprEngine& Eng;
+  llvm::SmallSet<SymbolRef, 10> NotableSymbols;
+public:
+  GRBugReporter(BugReporterData& d, GRExprEngine& eng)
+    : BugReporter(d, GRBugReporterKind), Eng(eng) {}
+
+  virtual ~GRBugReporter();
+
+  /// getEngine - Return the analysis engine used to analyze a given
+  ///  function or method.
+  GRExprEngine &getEngine() { return Eng; }
+
+  /// getGraph - Get the exploded graph created by the analysis engine
+  ///  for the analyzed method or function.
+  ExplodedGraph &getGraph();
+
+  /// getStateManager - Return the state manager used by the analysis
+  ///  engine.
+  GRStateManager &getStateManager();
+
+  virtual void GeneratePathDiagnostic(PathDiagnostic& PD,
+                                      BugReportEquivClass& R);
+
+  void addNotableSymbol(SymbolRef Sym) {
+    NotableSymbols.insert(Sym);
+  }
+
+  bool isNotable(SymbolRef Sym) const {
+    return (bool) NotableSymbols.count(Sym);
+  }
+
+  /// classof - Used by isa<>, cast<>, and dyn_cast<>.
+  static bool classof(const BugReporter* R) {
+    return R->getKind() == GRBugReporterKind;
+  }
+};
+
+class BugReporterContext {
+  GRBugReporter &BR;
+  // Not the most efficient data structure, but we use an ImmutableList for the
+  // Callbacks because it is safe to make additions to list during iteration.
+  llvm::ImmutableList<BugReporterVisitor*>::Factory F;
+  llvm::ImmutableList<BugReporterVisitor*> Callbacks;
+  llvm::FoldingSet<BugReporterVisitor> CallbacksSet;
+public:
+  BugReporterContext(GRBugReporter& br) : BR(br), Callbacks(F.GetEmptyList()) {}
+  virtual ~BugReporterContext();
+
+  void addVisitor(BugReporterVisitor* visitor);
+
+  typedef llvm::ImmutableList<BugReporterVisitor*>::iterator visitor_iterator;
+  visitor_iterator visitor_begin() { return Callbacks.begin(); }
+  visitor_iterator visitor_end() { return Callbacks.end(); }
+
+  GRBugReporter& getBugReporter() { return BR; }
+
+  ExplodedGraph &getGraph() { return BR.getGraph(); }
+
+  void addNotableSymbol(SymbolRef Sym) {
+    // FIXME: For now forward to GRBugReporter.
+    BR.addNotableSymbol(Sym);
+  }
+
+  bool isNotable(SymbolRef Sym) const {
+    // FIXME: For now forward to GRBugReporter.
+    return BR.isNotable(Sym);
+  }
+
+  GRStateManager& getStateManager() {
+    return BR.getStateManager();
+  }
+
+  ValueManager& getValueManager() {
+    return getStateManager().getValueManager();
+  }
+
+  ASTContext& getASTContext() {
+    return BR.getContext();
+  }
+
+  SourceManager& getSourceManager() {
+    return BR.getSourceManager();
+  }
+
+  virtual BugReport::NodeResolver& getNodeResolver() = 0;
+};
+
+class DiagBugReport : public RangedBugReport {
+  std::list<std::string> Strs;
+  FullSourceLoc L;
+public:
+  DiagBugReport(BugType& D, llvm::StringRef desc, FullSourceLoc l) :
+  RangedBugReport(D, desc, 0), L(l) {}
+
+  virtual ~DiagBugReport() {}
+
+  // FIXME: Move out-of-line (virtual function).
+  SourceLocation getLocation() const { return L; }
+
+  void addString(llvm::StringRef s) { Strs.push_back(s); }
+
+  typedef std::list<std::string>::const_iterator str_iterator;
+  str_iterator str_begin() const { return Strs.begin(); }
+  str_iterator str_end() const { return Strs.end(); }
+};
+
+//===----------------------------------------------------------------------===//
+//===----------------------------------------------------------------------===//
+
+namespace bugreporter {
+
+const Stmt *GetDerefExpr(const ExplodedNode *N);
+const Stmt *GetDenomExpr(const ExplodedNode *N);
+const Stmt *GetCalleeExpr(const ExplodedNode *N);
+const Stmt *GetRetValExpr(const ExplodedNode *N);
+
+void registerTrackNullOrUndefValue(BugReporterContext& BRC, const void *stmt,
+                                   const ExplodedNode* N);
+
+void registerFindLastStore(BugReporterContext& BRC, const void *memregion,
+                           const ExplodedNode *N);
+
+void registerNilReceiverVisitor(BugReporterContext &BRC);
+
+} // end namespace clang::bugreporter
+
+//===----------------------------------------------------------------------===//
+
+} // end clang namespace
+
+#endif
diff --git a/include/clang/Checker/BugReporter/BugType.h b/include/clang/Checker/BugReporter/BugType.h
new file mode 100644
index 0000000..afc07c8
--- /dev/null
+++ b/include/clang/Checker/BugReporter/BugType.h
@@ -0,0 +1,72 @@
+//===---  BugType.h - Bug Information Desciption ----------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines BugType, a class representing a bug type.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_BUGTYPE
+#define LLVM_CLANG_ANALYSIS_BUGTYPE
+
+#include "clang/Checker/BugReporter/BugReporter.h"
+#include "llvm/ADT/FoldingSet.h"
+#include <string>
+
+namespace clang {
+
+class ExplodedNode;
+class GRExprEngine;
+
+class BugType {
+private:
+  const std::string Name;
+  const std::string Category;
+  llvm::FoldingSet<BugReportEquivClass> EQClasses;
+  friend class BugReporter;
+  bool SuppressonSink;
+public:
+  BugType(llvm::StringRef name, llvm::StringRef cat)
+    : Name(name), Category(cat), SuppressonSink(false) {}
+  virtual ~BugType();
+
+  // FIXME: Should these be made strings as well?
+  llvm::StringRef getName() const { return Name; }
+  llvm::StringRef getCategory() const { return Category; }
+  
+  /// isSuppressOnSink - Returns true if bug reports associated with this bug
+  ///  type should be suppressed if the end node of the report is post-dominated
+  ///  by a sink node.
+  bool isSuppressOnSink() const { return SuppressonSink; }
+  void setSuppressOnSink(bool x) { SuppressonSink = x; }
+
+  virtual void FlushReports(BugReporter& BR);
+
+  typedef llvm::FoldingSet<BugReportEquivClass>::iterator iterator;
+  iterator begin() { return EQClasses.begin(); }
+  iterator end() { return EQClasses.end(); }
+
+  typedef llvm::FoldingSet<BugReportEquivClass>::const_iterator const_iterator;
+  const_iterator begin() const { return EQClasses.begin(); }
+  const_iterator end() const { return EQClasses.end(); }
+};
+
+class BuiltinBug : public BugType {
+  const std::string desc;
+public:
+  BuiltinBug(const char *name, const char *description)
+    : BugType(name, "Logic error"), desc(description) {}
+  
+  BuiltinBug(const char *name)
+    : BugType(name, "Logic error"), desc(name) {}
+  
+  llvm::StringRef getDescription() const { return desc; }
+};
+
+} // end clang namespace
+#endif
diff --git a/include/clang/Checker/BugReporter/PathDiagnostic.h b/include/clang/Checker/BugReporter/PathDiagnostic.h
new file mode 100644
index 0000000..24c75ce
--- /dev/null
+++ b/include/clang/Checker/BugReporter/PathDiagnostic.h
@@ -0,0 +1,494 @@
+//===--- PathDiagnostic.h - Path-Specific Diagnostic Handling ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the PathDiagnostic-related interfaces.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_PATH_DIAGNOSTIC_H
+#define LLVM_CLANG_PATH_DIAGNOSTIC_H
+
+#include "clang/Basic/Diagnostic.h"
+#include "llvm/ADT/FoldingSet.h"
+#include <deque>
+#include <iterator>
+#include <string>
+#include <vector>
+
+namespace clang {
+
+class Decl;
+class SourceManager;
+class Stmt;
+
+//===----------------------------------------------------------------------===//
+// High-level interface for handlers of path-sensitive diagnostics.
+//===----------------------------------------------------------------------===//
+
+class PathDiagnostic;
+
+class PathDiagnosticClient : public DiagnosticClient  {
+public:
+  PathDiagnosticClient() {}
+
+  virtual ~PathDiagnosticClient() {}
+  
+  virtual void
+  FlushDiagnostics(llvm::SmallVectorImpl<std::string> *FilesMade = 0) = 0;
+  
+  void FlushDiagnostics(llvm::SmallVectorImpl<std::string> &FilesMade) {
+    FlushDiagnostics(&FilesMade);
+  }
+  
+  virtual llvm::StringRef getName() const = 0;
+  
+  virtual void HandleDiagnostic(Diagnostic::Level DiagLevel,
+                                const DiagnosticInfo &Info);
+  virtual void HandlePathDiagnostic(const PathDiagnostic* D) = 0;
+
+  enum PathGenerationScheme { Minimal, Extensive };
+  virtual PathGenerationScheme getGenerationScheme() const { return Minimal; }
+  virtual bool supportsLogicalOpControlFlow() const { return false; }
+  virtual bool supportsAllBlockEdges() const { return false; }
+  virtual bool useVerboseDescription() const { return true; }
+};
+
+//===----------------------------------------------------------------------===//
+// Path-sensitive diagnostics.
+//===----------------------------------------------------------------------===//
+
+class PathDiagnosticRange : public SourceRange {
+public:
+  const bool isPoint;
+
+  PathDiagnosticRange(const SourceRange &R, bool isP = false)
+    : SourceRange(R), isPoint(isP) {}
+};
+
+class PathDiagnosticLocation {
+private:
+  enum Kind { RangeK, SingleLocK, StmtK, DeclK } K;
+  SourceRange R;
+  const Stmt *S;
+  const Decl *D;
+  const SourceManager *SM;
+public:
+  PathDiagnosticLocation()
+    : K(SingleLocK), S(0), D(0), SM(0) {}
+
+  PathDiagnosticLocation(FullSourceLoc L)
+    : K(SingleLocK), R(L, L), S(0), D(0), SM(&L.getManager()) {}
+
+  PathDiagnosticLocation(const Stmt *s, const SourceManager &sm)
+    : K(StmtK), S(s), D(0), SM(&sm) {}
+
+  PathDiagnosticLocation(SourceRange r, const SourceManager &sm)
+    : K(RangeK), R(r), S(0), D(0), SM(&sm) {}
+
+  PathDiagnosticLocation(const Decl *d, const SourceManager &sm)
+    : K(DeclK), S(0), D(d), SM(&sm) {}
+
+  bool operator==(const PathDiagnosticLocation &X) const {
+    return K == X.K && R == X.R && S == X.S && D == X.D;
+  }
+
+  bool operator!=(const PathDiagnosticLocation &X) const {
+    return K != X.K || R != X.R || S != X.S || D != X.D;;
+  }
+
+  PathDiagnosticLocation& operator=(const PathDiagnosticLocation &X) {
+    K = X.K;
+    R = X.R;
+    S = X.S;
+    D = X.D;
+    SM = X.SM;
+    return *this;
+  }
+
+  bool isValid() const {
+    return SM != 0;
+  }
+
+  const SourceManager& getSourceManager() const { assert(isValid());return *SM;}
+
+  FullSourceLoc asLocation() const;
+  PathDiagnosticRange asRange() const;
+  const Stmt *asStmt() const { assert(isValid()); return S; }
+  const Decl *asDecl() const { assert(isValid()); return D; }
+
+  bool hasRange() const { return K == StmtK || K == RangeK || K == DeclK; }
+
+  void invalidate() {
+    *this = PathDiagnosticLocation();
+  }
+
+  void flatten();
+
+  const SourceManager& getManager() const { assert(isValid()); return *SM; }
+  
+  void Profile(llvm::FoldingSetNodeID &ID) const;
+};
+
+class PathDiagnosticLocationPair {
+private:
+  PathDiagnosticLocation Start, End;
+public:
+  PathDiagnosticLocationPair(const PathDiagnosticLocation &start,
+                             const PathDiagnosticLocation &end)
+    : Start(start), End(end) {}
+
+  const PathDiagnosticLocation &getStart() const { return Start; }
+  const PathDiagnosticLocation &getEnd() const { return End; }
+
+  void flatten() {
+    Start.flatten();
+    End.flatten();
+  }
+  
+  void Profile(llvm::FoldingSetNodeID &ID) const {
+    Start.Profile(ID);
+    End.Profile(ID);
+  }
+};
+
+//===----------------------------------------------------------------------===//
+// Path "pieces" for path-sensitive diagnostics.
+//===----------------------------------------------------------------------===//
+
+class PathDiagnosticPiece {
+public:
+  enum Kind { ControlFlow, Event, Macro };
+  enum DisplayHint { Above, Below };
+
+private:
+  const std::string str;
+  std::vector<FixItHint> FixItHints;
+  const Kind kind;
+  const DisplayHint Hint;
+  std::vector<SourceRange> ranges;
+
+  // Do not implement:
+  PathDiagnosticPiece();
+  PathDiagnosticPiece(const PathDiagnosticPiece &P);
+  PathDiagnosticPiece& operator=(const PathDiagnosticPiece &P);
+
+protected:
+  PathDiagnosticPiece(llvm::StringRef s, Kind k, DisplayHint hint = Below);
+
+  PathDiagnosticPiece(Kind k, DisplayHint hint = Below);
+
+public:
+  virtual ~PathDiagnosticPiece();
+
+  const std::string& getString() const { return str; }
+
+  /// getDisplayHint - Return a hint indicating where the diagnostic should
+  ///  be displayed by the PathDiagnosticClient.
+  DisplayHint getDisplayHint() const { return Hint; }
+
+  virtual PathDiagnosticLocation getLocation() const = 0;
+  virtual void flattenLocations() = 0;
+
+  Kind getKind() const { return kind; }
+
+  void addRange(SourceRange R) { ranges.push_back(R); }
+
+  void addRange(SourceLocation B, SourceLocation E) {
+    ranges.push_back(SourceRange(B,E));
+  }
+
+  void addFixItHint(const FixItHint& Hint) {
+    FixItHints.push_back(Hint);
+  }
+
+  typedef const SourceRange* range_iterator;
+
+  range_iterator ranges_begin() const {
+    return ranges.empty() ? NULL : &ranges[0];
+  }
+
+  range_iterator ranges_end() const {
+    return ranges_begin() + ranges.size();
+  }
+
+  typedef const FixItHint *fixit_iterator;
+
+  fixit_iterator fixit_begin() const {
+    return FixItHints.empty()? 0 : &FixItHints[0];
+  }
+
+  fixit_iterator fixit_end() const {
+    return FixItHints.empty()? 0
+                   : &FixItHints[0] + FixItHints.size();
+  }
+
+  static inline bool classof(const PathDiagnosticPiece* P) {
+    return true;
+  }
+  
+  virtual void Profile(llvm::FoldingSetNodeID &ID) const;
+};
+
+class PathDiagnosticSpotPiece : public PathDiagnosticPiece {
+private:
+  PathDiagnosticLocation Pos;
+public:
+  PathDiagnosticSpotPiece(const PathDiagnosticLocation &pos,
+                          llvm::StringRef s,
+                          PathDiagnosticPiece::Kind k,
+                          bool addPosRange = true)
+  : PathDiagnosticPiece(s, k), Pos(pos) {
+    assert(Pos.asLocation().isValid() &&
+           "PathDiagnosticSpotPiece's must have a valid location.");
+    if (addPosRange && Pos.hasRange()) addRange(Pos.asRange());
+  }
+
+  PathDiagnosticLocation getLocation() const { return Pos; }
+  virtual void flattenLocations() { Pos.flatten(); }
+  
+  virtual void Profile(llvm::FoldingSetNodeID &ID) const;
+};
+
+class PathDiagnosticEventPiece : public PathDiagnosticSpotPiece {
+
+public:
+  PathDiagnosticEventPiece(const PathDiagnosticLocation &pos,
+                           llvm::StringRef s, bool addPosRange = true)
+    : PathDiagnosticSpotPiece(pos, s, Event, addPosRange) {}
+
+  ~PathDiagnosticEventPiece();
+
+  static inline bool classof(const PathDiagnosticPiece* P) {
+    return P->getKind() == Event;
+  }
+};
+
+class PathDiagnosticControlFlowPiece : public PathDiagnosticPiece {
+  std::vector<PathDiagnosticLocationPair> LPairs;
+public:
+  PathDiagnosticControlFlowPiece(const PathDiagnosticLocation &startPos,
+                                 const PathDiagnosticLocation &endPos,
+                                 llvm::StringRef s)
+    : PathDiagnosticPiece(s, ControlFlow) {
+      LPairs.push_back(PathDiagnosticLocationPair(startPos, endPos));
+    }
+
+  PathDiagnosticControlFlowPiece(const PathDiagnosticLocation &startPos,
+                                 const PathDiagnosticLocation &endPos)
+    : PathDiagnosticPiece(ControlFlow) {
+      LPairs.push_back(PathDiagnosticLocationPair(startPos, endPos));
+    }
+
+  ~PathDiagnosticControlFlowPiece();
+
+  PathDiagnosticLocation getStartLocation() const {
+    assert(!LPairs.empty() &&
+           "PathDiagnosticControlFlowPiece needs at least one location.");
+    return LPairs[0].getStart();
+  }
+
+  PathDiagnosticLocation getEndLocation() const {
+    assert(!LPairs.empty() &&
+           "PathDiagnosticControlFlowPiece needs at least one location.");
+    return LPairs[0].getEnd();
+  }
+
+  void push_back(const PathDiagnosticLocationPair &X) { LPairs.push_back(X); }
+
+  virtual PathDiagnosticLocation getLocation() const {
+    return getStartLocation();
+  }
+
+  typedef std::vector<PathDiagnosticLocationPair>::iterator iterator;
+  iterator begin() { return LPairs.begin(); }
+  iterator end()   { return LPairs.end(); }
+
+  virtual void flattenLocations() {
+    for (iterator I=begin(), E=end(); I!=E; ++I) I->flatten();
+  }
+
+  typedef std::vector<PathDiagnosticLocationPair>::const_iterator
+          const_iterator;
+  const_iterator begin() const { return LPairs.begin(); }
+  const_iterator end() const   { return LPairs.end(); }
+
+  static inline bool classof(const PathDiagnosticPiece* P) {
+    return P->getKind() == ControlFlow;
+  }
+  
+  virtual void Profile(llvm::FoldingSetNodeID &ID) const;
+};
+
+class PathDiagnosticMacroPiece : public PathDiagnosticSpotPiece {
+  std::vector<PathDiagnosticPiece*> SubPieces;
+public:
+  PathDiagnosticMacroPiece(const PathDiagnosticLocation &pos)
+    : PathDiagnosticSpotPiece(pos, "", Macro) {}
+
+  ~PathDiagnosticMacroPiece();
+
+  bool containsEvent() const;
+
+  void push_back(PathDiagnosticPiece* P) { SubPieces.push_back(P); }
+
+  typedef std::vector<PathDiagnosticPiece*>::iterator iterator;
+  iterator begin() { return SubPieces.begin(); }
+  iterator end() { return SubPieces.end(); }
+
+  virtual void flattenLocations() {
+    PathDiagnosticSpotPiece::flattenLocations();
+    for (iterator I=begin(), E=end(); I!=E; ++I) (*I)->flattenLocations();
+  }
+
+  typedef std::vector<PathDiagnosticPiece*>::const_iterator const_iterator;
+  const_iterator begin() const { return SubPieces.begin(); }
+  const_iterator end() const { return SubPieces.end(); }
+
+  static inline bool classof(const PathDiagnosticPiece* P) {
+    return P->getKind() == Macro;
+  }
+  
+  virtual void Profile(llvm::FoldingSetNodeID &ID) const;
+};
+
+/// PathDiagnostic - PathDiagnostic objects represent a single path-sensitive
+///  diagnostic.  It represents an ordered-collection of PathDiagnosticPieces,
+///  each which represent the pieces of the path.
+class PathDiagnostic : public llvm::FoldingSetNode {
+  std::deque<PathDiagnosticPiece*> path;
+  unsigned Size;
+  std::string BugType;
+  std::string Desc;
+  std::string Category;
+  std::deque<std::string> OtherDesc;
+
+public:
+  PathDiagnostic();
+
+  PathDiagnostic(llvm::StringRef bugtype, llvm::StringRef desc,
+                 llvm::StringRef category);
+
+  ~PathDiagnostic();
+
+  llvm::StringRef getDescription() const { return Desc; }
+  llvm::StringRef getBugType() const { return BugType; }
+  llvm::StringRef getCategory() const { return Category; }
+
+  typedef std::deque<std::string>::const_iterator meta_iterator;
+  meta_iterator meta_begin() const { return OtherDesc.begin(); }
+  meta_iterator meta_end() const { return OtherDesc.end(); }
+  void addMeta(llvm::StringRef s) { OtherDesc.push_back(s); }
+
+  PathDiagnosticLocation getLocation() const {
+    assert(Size > 0 && "getLocation() requires a non-empty PathDiagnostic.");
+    return rbegin()->getLocation();
+  }
+
+  void push_front(PathDiagnosticPiece* piece) {
+    assert(piece);
+    path.push_front(piece);
+    ++Size;
+  }
+
+  void push_back(PathDiagnosticPiece* piece) {
+    assert(piece);
+    path.push_back(piece);
+    ++Size;
+  }
+
+  PathDiagnosticPiece* back() {
+    return path.back();
+  }
+
+  const PathDiagnosticPiece* back() const {
+    return path.back();
+  }
+
+  unsigned size() const { return Size; }
+  bool empty() const { return Size == 0; }
+
+  void resetPath(bool deletePieces = true);
+
+  class iterator {
+  public:
+    typedef std::deque<PathDiagnosticPiece*>::iterator ImplTy;
+
+    typedef PathDiagnosticPiece              value_type;
+    typedef value_type&                      reference;
+    typedef value_type*                      pointer;
+    typedef ptrdiff_t                        difference_type;
+    typedef std::bidirectional_iterator_tag  iterator_category;
+
+  private:
+    ImplTy I;
+
+  public:
+    iterator(const ImplTy& i) : I(i) {}
+
+    bool operator==(const iterator& X) const { return I == X.I; }
+    bool operator!=(const iterator& X) const { return I != X.I; }
+
+    PathDiagnosticPiece& operator*() const { return **I; }
+    PathDiagnosticPiece* operator->() const { return *I; }
+
+    iterator& operator++() { ++I; return *this; }
+    iterator& operator--() { --I; return *this; }
+  };
+
+  class const_iterator {
+  public:
+    typedef std::deque<PathDiagnosticPiece*>::const_iterator ImplTy;
+
+    typedef const PathDiagnosticPiece        value_type;
+    typedef value_type&                      reference;
+    typedef value_type*                      pointer;
+    typedef ptrdiff_t                        difference_type;
+    typedef std::bidirectional_iterator_tag  iterator_category;
+
+  private:
+    ImplTy I;
+
+  public:
+    const_iterator(const ImplTy& i) : I(i) {}
+
+    bool operator==(const const_iterator& X) const { return I == X.I; }
+    bool operator!=(const const_iterator& X) const { return I != X.I; }
+
+    reference operator*() const { return **I; }
+    pointer operator->() const { return *I; }
+
+    const_iterator& operator++() { ++I; return *this; }
+    const_iterator& operator--() { --I; return *this; }
+  };
+
+  typedef std::reverse_iterator<iterator>       reverse_iterator;
+  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+
+  // forward iterator creation methods.
+
+  iterator begin() { return path.begin(); }
+  iterator end() { return path.end(); }
+
+  const_iterator begin() const { return path.begin(); }
+  const_iterator end() const { return path.end(); }
+
+  // reverse iterator creation methods.
+  reverse_iterator rbegin()            { return reverse_iterator(end()); }
+  const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); }
+  reverse_iterator rend()              { return reverse_iterator(begin()); }
+  const_reverse_iterator rend() const { return const_reverse_iterator(begin());}
+
+  void flattenLocations() {
+    for (iterator I = begin(), E = end(); I != E; ++I) I->flattenLocations();
+  }
+  
+  void Profile(llvm::FoldingSetNodeID &ID) const;
+};  
+} //end clang namespace
+#endif
diff --git a/include/clang/Checker/Checkers/DereferenceChecker.h b/include/clang/Checker/Checkers/DereferenceChecker.h
new file mode 100644
index 0000000..a84183e
--- /dev/null
+++ b/include/clang/Checker/Checkers/DereferenceChecker.h
@@ -0,0 +1,31 @@
+//== NullDerefChecker.h - Null dereference checker --------------*- C++ -*--==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This defines NullDerefChecker and UndefDerefChecker, two builtin checks
+// in GRExprEngine that check for null and undefined pointers at loads
+// and stores.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_DEREFCHECKER
+#define LLVM_CLANG_DEREFCHECKER
+
+#include <utility>
+
+namespace clang {
+
+class GRExprEngine;
+class ExplodedNode;
+
+std::pair<ExplodedNode * const *, ExplodedNode * const *>
+GetImplicitNullDereferences(GRExprEngine &Eng);
+
+} // end clang namespace
+
+#endif
diff --git a/include/clang/Checker/Checkers/LocalCheckers.h b/include/clang/Checker/Checkers/LocalCheckers.h
new file mode 100644
index 0000000..4a9e381
--- /dev/null
+++ b/include/clang/Checker/Checkers/LocalCheckers.h
@@ -0,0 +1,61 @@
+//==- LocalCheckers.h - Intra-Procedural+Flow-Sensitive Checkers -*- C++ -*-==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the interface to call a set of intra-procedural (local)
+//  checkers that use flow/path-sensitive analyses to find bugs.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_LOCALCHECKERS_H
+#define LLVM_CLANG_ANALYSIS_LOCALCHECKERS_H
+
+namespace clang {
+
+class CFG;
+class Decl;
+class Diagnostic;
+class ASTContext;
+class PathDiagnosticClient;
+class GRTransferFuncs;
+class BugType;
+class LangOptions;
+class ParentMap;
+class LiveVariables;
+class BugReporter;
+class ObjCImplementationDecl;
+class LangOptions;
+class GRExprEngine;
+class TranslationUnitDecl;
+
+void CheckDeadStores(CFG &cfg, LiveVariables &L, ParentMap &map, 
+                     BugReporter& BR);
+
+GRTransferFuncs* MakeCFRefCountTF(ASTContext& Ctx, bool GCEnabled,
+                                  const LangOptions& lopts);
+
+void CheckObjCDealloc(const ObjCImplementationDecl* D, const LangOptions& L,
+                      BugReporter& BR);
+
+void CheckObjCInstMethSignature(const ObjCImplementationDecl *ID,
+                                BugReporter& BR);
+
+void CheckObjCUnusedIvar(const ObjCImplementationDecl *D, BugReporter& BR);
+
+void RegisterAppleChecks(GRExprEngine& Eng, const Decl &D);
+void RegisterExperimentalChecks(GRExprEngine &Eng);
+void RegisterExperimentalInternalChecks(GRExprEngine &Eng);
+
+void CheckLLVMConventions(TranslationUnitDecl &TU, BugReporter &BR);
+void CheckSecuritySyntaxOnly(const Decl *D, BugReporter &BR);
+void CheckSizeofPointer(const Decl *D, BugReporter &BR);
+
+void RegisterCallInliner(GRExprEngine &Eng);
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Checker/DomainSpecific/CocoaConventions.h b/include/clang/Checker/DomainSpecific/CocoaConventions.h
new file mode 100644
index 0000000..4bbdab0
--- /dev/null
+++ b/include/clang/Checker/DomainSpecific/CocoaConventions.h
@@ -0,0 +1,39 @@
+//===- CocoaConventions.h - Special handling of Cocoa conventions -*- C++ -*--//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines 
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_CHECKER_DS_COCOA
+#define LLVM_CLANG_CHECKER_DS_COCOA
+
+#include "clang/AST/Type.h"
+
+namespace clang {
+namespace cocoa {
+ 
+  enum NamingConvention { NoConvention, CreateRule, InitRule };
+
+  NamingConvention deriveNamingConvention(Selector S);
+
+  static inline bool followsFundamentalRule(Selector S) {
+    return deriveNamingConvention(S) == CreateRule;
+  }
+  
+  bool isRefType(QualType RetTy, llvm::StringRef Prefix,
+                 llvm::StringRef Name = llvm::StringRef());
+  
+  bool isCFObjectRef(QualType T);
+  
+  bool isCocoaObjectRef(QualType T);
+
+}}
+
+#endif
diff --git a/include/clang/Checker/ManagerRegistry.h b/include/clang/Checker/ManagerRegistry.h
new file mode 100644
index 0000000..ebfd28e
--- /dev/null
+++ b/include/clang/Checker/ManagerRegistry.h
@@ -0,0 +1,53 @@
+//===-- ManagerRegistry.h - Pluggable analyzer module registry --*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the ManagerRegistry and Register* classes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_MANAGER_REGISTRY_H
+#define LLVM_CLANG_ANALYSIS_MANAGER_REGISTRY_H
+
+#include "clang/Checker/PathSensitive/GRState.h"
+
+namespace clang {
+
+/// ManagerRegistry - This class records manager creators registered at
+/// runtime. The information is communicated to AnalysisManager through static
+/// members. Better design is expected.
+
+class ManagerRegistry {
+public:
+  static StoreManagerCreator StoreMgrCreator;
+  static ConstraintManagerCreator ConstraintMgrCreator;
+};
+
+/// RegisterConstraintManager - This class is used to setup the constraint
+/// manager of the static analyzer. The constructor takes a creator function
+/// pointer for creating the constraint manager.
+///
+/// It is used like this:
+///
+/// class MyConstraintManager {};
+/// ConstraintManager* CreateMyConstraintManager(GRStateManager& statemgr) {
+///  return new MyConstraintManager(statemgr);
+/// }
+/// RegisterConstraintManager X(CreateMyConstraintManager);
+
+class RegisterConstraintManager {
+public:
+  RegisterConstraintManager(ConstraintManagerCreator CMC) {
+    assert(ManagerRegistry::ConstraintMgrCreator == 0
+           && "ConstraintMgrCreator already set!");
+    ManagerRegistry::ConstraintMgrCreator = CMC;
+  }
+};
+
+}
+#endif
diff --git a/include/clang/Checker/PathSensitive/AnalysisManager.h b/include/clang/Checker/PathSensitive/AnalysisManager.h
new file mode 100644
index 0000000..0c59d7b
--- /dev/null
+++ b/include/clang/Checker/PathSensitive/AnalysisManager.h
@@ -0,0 +1,153 @@
+//== AnalysisManager.h - Path sensitive analysis data manager ------*- C++ -*-//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the AnalysisManager class that manages the data and policy
+// for path sensitive analysis.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_ANALYSISMANAGER_H
+#define LLVM_CLANG_ANALYSIS_ANALYSISMANAGER_H
+
+#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Checker/BugReporter/BugReporter.h"
+#include "clang/Checker/BugReporter/PathDiagnostic.h"
+
+namespace clang {
+
+class AnalysisManager : public BugReporterData {
+  AnalysisContextManager AnaCtxMgr;
+  LocationContextManager LocCtxMgr;
+
+  ASTContext &Ctx;
+  Diagnostic &Diags;
+  const LangOptions &LangInfo;
+
+  llvm::OwningPtr<PathDiagnosticClient> PD;
+
+  // Configurable components creators.
+  StoreManagerCreator CreateStoreMgr;
+  ConstraintManagerCreator CreateConstraintMgr;
+
+  enum AnalysisScope { ScopeTU, ScopeDecl } AScope;
+
+  unsigned MaxNodes;
+
+  bool VisualizeEGDot;
+  bool VisualizeEGUbi;
+  bool PurgeDead;
+
+  /// EargerlyAssume - A flag indicating how the engine should handle
+  //   expressions such as: 'x = (y != 0)'.  When this flag is true then
+  //   the subexpression 'y != 0' will be eagerly assumed to be true or false,
+  //   thus evaluating it to the integers 0 or 1 respectively.  The upside
+  //   is that this can increase analysis precision until we have a better way
+  //   to lazily evaluate such logic.  The downside is that it eagerly
+  //   bifurcates paths.
+  bool EagerlyAssume;
+  bool TrimGraph;
+
+public:
+  AnalysisManager(ASTContext &ctx, Diagnostic &diags, 
+                  const LangOptions &lang, PathDiagnosticClient *pd,
+                  StoreManagerCreator storemgr,
+                  ConstraintManagerCreator constraintmgr, unsigned maxnodes,
+                  bool vizdot, bool vizubi, bool purge, bool eager, bool trim)
+
+    : Ctx(ctx), Diags(diags), LangInfo(lang), PD(pd),
+      CreateStoreMgr(storemgr), CreateConstraintMgr(constraintmgr),
+      AScope(ScopeDecl), MaxNodes(maxnodes),
+      VisualizeEGDot(vizdot), VisualizeEGUbi(vizubi), PurgeDead(purge),
+      EagerlyAssume(eager), TrimGraph(trim) {}
+  
+  ~AnalysisManager() { FlushDiagnostics(); }
+  
+  void ClearContexts() {
+    LocCtxMgr.clear();
+    AnaCtxMgr.clear();
+  }
+
+  StoreManagerCreator getStoreManagerCreator() {
+    return CreateStoreMgr;
+  }
+
+  ConstraintManagerCreator getConstraintManagerCreator() {
+    return CreateConstraintMgr;
+  }
+
+  virtual ASTContext &getASTContext() {
+    return Ctx;
+  }
+
+  virtual SourceManager &getSourceManager() {
+    return getASTContext().getSourceManager();
+  }
+
+  virtual Diagnostic &getDiagnostic() {
+    return Diags;
+  }
+
+  const LangOptions &getLangOptions() const {
+    return LangInfo;
+  }
+
+  virtual PathDiagnosticClient *getPathDiagnosticClient() {
+    return PD.get();
+  }
+  
+  void FlushDiagnostics() {
+    if (PD.get())
+      PD->FlushDiagnostics();
+  }
+
+  unsigned getMaxNodes() const { return MaxNodes; }
+
+  bool shouldVisualizeGraphviz() const { return VisualizeEGDot; }
+
+  bool shouldVisualizeUbigraph() const { return VisualizeEGUbi; }
+
+  bool shouldVisualize() const {
+    return VisualizeEGDot || VisualizeEGUbi;
+  }
+
+  bool shouldTrimGraph() const { return TrimGraph; }
+
+  bool shouldPurgeDead() const { return PurgeDead; }
+
+  bool shouldEagerlyAssume() const { return EagerlyAssume; }
+
+  CFG *getCFG(Decl const *D) {
+    return AnaCtxMgr.getContext(D)->getCFG();
+  }
+
+  LiveVariables *getLiveVariables(Decl const *D) {
+    return AnaCtxMgr.getContext(D)->getLiveVariables();
+  }
+
+  ParentMap &getParentMap(Decl const *D) {
+    return AnaCtxMgr.getContext(D)->getParentMap();
+  }
+
+  // Get the top level stack frame.
+  const StackFrameContext *getStackFrame(Decl const *D) {
+    return LocCtxMgr.getStackFrame(AnaCtxMgr.getContext(D), 0, 0, 0, 0);
+  }
+
+  // Get a stack frame with parent.
+  StackFrameContext const *getStackFrame(Decl const *D, 
+                                         LocationContext const *Parent,
+                                         Stmt const *S, const CFGBlock *Blk,
+                                         unsigned Idx) {
+    return LocCtxMgr.getStackFrame(AnaCtxMgr.getContext(D), Parent, S, Blk,Idx);
+  }
+};
+
+}
+
+#endif
diff --git a/include/clang/Checker/PathSensitive/BasicValueFactory.h b/include/clang/Checker/PathSensitive/BasicValueFactory.h
new file mode 100644
index 0000000..59dd919
--- /dev/null
+++ b/include/clang/Checker/PathSensitive/BasicValueFactory.h
@@ -0,0 +1,197 @@
+//=== BasicValueFactory.h - Basic values for Path Sens analysis --*- C++ -*---//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines BasicValueFactory, a class that manages the lifetime
+//  of APSInt objects and symbolic constraints used by GRExprEngine
+//  and related classes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_BASICVALUEFACTORY_H
+#define LLVM_CLANG_ANALYSIS_BASICVALUEFACTORY_H
+
+#include "clang/Checker/PathSensitive/SVals.h"
+#include "clang/AST/ASTContext.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/ImmutableList.h"
+
+namespace clang {
+
+  class GRState;
+
+class CompoundValData : public llvm::FoldingSetNode {
+  QualType T;
+  llvm::ImmutableList<SVal> L;
+
+public:
+  CompoundValData(QualType t, llvm::ImmutableList<SVal> l)
+    : T(t), L(l) {}
+
+  typedef llvm::ImmutableList<SVal>::iterator iterator;
+  iterator begin() const { return L.begin(); }
+  iterator end() const { return L.end(); }
+
+  static void Profile(llvm::FoldingSetNodeID& ID, QualType T,
+                      llvm::ImmutableList<SVal> L);
+
+  void Profile(llvm::FoldingSetNodeID& ID) { Profile(ID, T, L); }
+};
+
+class LazyCompoundValData : public llvm::FoldingSetNode {
+  const void *store;
+  const TypedRegion *region;
+public:
+  LazyCompoundValData(const void *st, const TypedRegion *r)
+    : store(st), region(r) {}
+
+  const void *getStore() const { return store; }
+  const TypedRegion *getRegion() const { return region; }
+
+  static void Profile(llvm::FoldingSetNodeID& ID, const void *store,
+                      const TypedRegion *region);
+
+  void Profile(llvm::FoldingSetNodeID& ID) { Profile(ID, store, region); }
+};
+
+class BasicValueFactory {
+  typedef llvm::FoldingSet<llvm::FoldingSetNodeWrapper<llvm::APSInt> >
+          APSIntSetTy;
+
+  ASTContext& Ctx;
+  llvm::BumpPtrAllocator& BPAlloc;
+
+  APSIntSetTy   APSIntSet;
+  void*         PersistentSVals;
+  void*         PersistentSValPairs;
+
+  llvm::ImmutableList<SVal>::Factory SValListFactory;
+  llvm::FoldingSet<CompoundValData>  CompoundValDataSet;
+  llvm::FoldingSet<LazyCompoundValData> LazyCompoundValDataSet;
+
+public:
+  BasicValueFactory(ASTContext& ctx, llvm::BumpPtrAllocator& Alloc)
+  : Ctx(ctx), BPAlloc(Alloc), PersistentSVals(0), PersistentSValPairs(0),
+    SValListFactory(Alloc) {}
+
+  ~BasicValueFactory();
+
+  ASTContext& getContext() const { return Ctx; }
+
+  const llvm::APSInt& getValue(const llvm::APSInt& X);
+  const llvm::APSInt& getValue(const llvm::APInt& X, bool isUnsigned);
+  const llvm::APSInt& getValue(uint64_t X, unsigned BitWidth, bool isUnsigned);
+  const llvm::APSInt& getValue(uint64_t X, QualType T);
+
+  /// Convert - Create a new persistent APSInt with the same value as 'From'
+  ///  but with the bitwidth and signedness of 'To'.
+  const llvm::APSInt &Convert(const llvm::APSInt& To,
+                              const llvm::APSInt& From) {
+
+    if (To.isUnsigned() == From.isUnsigned() &&
+        To.getBitWidth() == From.getBitWidth())
+      return From;
+
+    return getValue(From.getSExtValue(), To.getBitWidth(), To.isUnsigned());
+  }
+  
+  const llvm::APSInt &Convert(QualType T, const llvm::APSInt &From) {
+    assert(T->isIntegerType() || Loc::IsLocType(T));
+    unsigned bitwidth = Ctx.getTypeSize(T);
+    bool isUnsigned = T->isUnsignedIntegerType() || Loc::IsLocType(T);
+    
+    if (isUnsigned == From.isUnsigned() && bitwidth == From.getBitWidth())
+      return From;
+    
+    return getValue(From.getSExtValue(), bitwidth, isUnsigned);
+  }
+
+  const llvm::APSInt& getIntValue(uint64_t X, bool isUnsigned) {
+    QualType T = isUnsigned ? Ctx.UnsignedIntTy : Ctx.IntTy;
+    return getValue(X, T);
+  }
+
+  inline const llvm::APSInt& getMaxValue(const llvm::APSInt &v) {
+    return getValue(llvm::APSInt::getMaxValue(v.getBitWidth(), v.isUnsigned()));
+  }
+
+  inline const llvm::APSInt& getMinValue(const llvm::APSInt &v) {
+    return getValue(llvm::APSInt::getMinValue(v.getBitWidth(), v.isUnsigned()));
+  }
+
+  inline const llvm::APSInt& getMaxValue(QualType T) {
+    assert(T->isIntegerType() || Loc::IsLocType(T));
+    bool isUnsigned = T->isUnsignedIntegerType() || Loc::IsLocType(T);
+    return getValue(llvm::APSInt::getMaxValue(Ctx.getTypeSize(T), isUnsigned));
+  }
+
+  inline const llvm::APSInt& getMinValue(QualType T) {
+    assert(T->isIntegerType() || Loc::IsLocType(T));
+    bool isUnsigned = T->isUnsignedIntegerType() || Loc::IsLocType(T);
+    return getValue(llvm::APSInt::getMinValue(Ctx.getTypeSize(T), isUnsigned));
+  }
+
+  inline const llvm::APSInt& Add1(const llvm::APSInt& V) {
+    llvm::APSInt X = V;
+    ++X;
+    return getValue(X);
+  }
+
+  inline const llvm::APSInt& Sub1(const llvm::APSInt& V) {
+    llvm::APSInt X = V;
+    --X;
+    return getValue(X);
+  }
+
+  inline const llvm::APSInt& getZeroWithPtrWidth(bool isUnsigned = true) {
+    return getValue(0, Ctx.getTypeSize(Ctx.VoidPtrTy), isUnsigned);
+  }
+
+  inline const llvm::APSInt &getIntWithPtrWidth(uint64_t X, bool isUnsigned) {
+    return getValue(X, Ctx.getTypeSize(Ctx.VoidPtrTy), isUnsigned);
+  }
+
+  inline const llvm::APSInt& getTruthValue(bool b, QualType T) {
+    return getValue(b ? 1 : 0, Ctx.getTypeSize(T), false);
+  }
+
+  inline const llvm::APSInt& getTruthValue(bool b) {
+    return getTruthValue(b, Ctx.IntTy);
+  }
+
+  const CompoundValData *getCompoundValData(QualType T,
+                                            llvm::ImmutableList<SVal> Vals);
+
+  const LazyCompoundValData *getLazyCompoundValData(const void *store,
+                                                    const TypedRegion *region);
+
+  llvm::ImmutableList<SVal> getEmptySValList() {
+    return SValListFactory.GetEmptyList();
+  }
+
+  llvm::ImmutableList<SVal> consVals(SVal X, llvm::ImmutableList<SVal> L) {
+    return SValListFactory.Add(X, L);
+  }
+
+  const llvm::APSInt* EvaluateAPSInt(BinaryOperator::Opcode Op,
+                                     const llvm::APSInt& V1,
+                                     const llvm::APSInt& V2);
+
+  const std::pair<SVal, uintptr_t>&
+  getPersistentSValWithData(const SVal& V, uintptr_t Data);
+
+  const std::pair<SVal, SVal>&
+  getPersistentSValPair(const SVal& V1, const SVal& V2);
+
+  const SVal* getPersistentSVal(SVal X);
+};
+
+} // end clang namespace
+
+#endif
diff --git a/include/clang/Checker/PathSensitive/Checker.h b/include/clang/Checker/PathSensitive/Checker.h
new file mode 100644
index 0000000..8cb9cc8
--- /dev/null
+++ b/include/clang/Checker/PathSensitive/Checker.h
@@ -0,0 +1,285 @@
+//== Checker.h - Abstract interface for checkers -----------------*- C++ -*--=//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines Checker and CheckerVisitor, classes used for creating
+//  domain-specific checks.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_CHECKER
+#define LLVM_CLANG_ANALYSIS_CHECKER
+
+#include "clang/Analysis/Support/SaveAndRestore.h"
+#include "clang/Checker/PathSensitive/GRExprEngine.h"
+
+//===----------------------------------------------------------------------===//
+// Checker interface.
+//===----------------------------------------------------------------------===//
+
+namespace clang {
+
+class CheckerContext {
+  ExplodedNodeSet &Dst;
+  GRStmtNodeBuilder &B;
+  GRExprEngine &Eng;
+  ExplodedNode *Pred;
+  SaveAndRestore<bool> OldSink;
+  SaveAndRestore<const void*> OldTag;
+  SaveAndRestore<ProgramPoint::Kind> OldPointKind;
+  SaveOr OldHasGen;
+  const GRState *ST;
+  const Stmt *statement;
+  const unsigned size;
+  bool DoneEvaluating; // FIXME: This is not a permanent API change.
+public:
+  CheckerContext(ExplodedNodeSet &dst, GRStmtNodeBuilder &builder,
+                 GRExprEngine &eng, ExplodedNode *pred,
+                 const void *tag, ProgramPoint::Kind K,
+                 const Stmt *stmt = 0, const GRState *st = 0)
+    : Dst(dst), B(builder), Eng(eng), Pred(pred),
+      OldSink(B.BuildSinks),
+      OldTag(B.Tag, tag),
+      OldPointKind(B.PointKind, K),
+      OldHasGen(B.HasGeneratedNode),
+      ST(st), statement(stmt), size(Dst.size()) {}
+
+  ~CheckerContext();
+
+  GRExprEngine &getEngine() {
+    return Eng;
+  }
+
+  AnalysisManager &getAnalysisManager() {
+    return Eng.getAnalysisManager();
+  }
+
+  ConstraintManager &getConstraintManager() {
+    return Eng.getConstraintManager();
+  }
+
+  StoreManager &getStoreManager() {
+    return Eng.getStoreManager();
+  }
+
+  ExplodedNodeSet &getNodeSet() { return Dst; }
+  GRStmtNodeBuilder &getNodeBuilder() { return B; }
+  ExplodedNode *&getPredecessor() { return Pred; }
+  const GRState *getState() { return ST ? ST : B.GetState(Pred); }
+
+  ASTContext &getASTContext() {
+    return Eng.getContext();
+  }
+  
+  BugReporter &getBugReporter() {
+    return Eng.getBugReporter();
+  }
+  
+  SourceManager &getSourceManager() {
+    return getBugReporter().getSourceManager();
+  }
+
+  ValueManager &getValueManager() {
+    return Eng.getValueManager();
+  }
+
+  SValuator &getSValuator() {
+    return Eng.getSValuator();
+  }
+
+  ExplodedNode *GenerateNode(bool autoTransition = true) {
+    assert(statement && "Only transitions with statements currently supported");
+    ExplodedNode *N = GenerateNodeImpl(statement, getState(), false);
+    if (N && autoTransition)
+      Dst.Add(N);
+    return N;
+  }
+  
+  ExplodedNode *GenerateNode(const Stmt *stmt, const GRState *state,
+                             bool autoTransition = true) {
+    assert(state);
+    ExplodedNode *N = GenerateNodeImpl(stmt, state, false);
+    if (N && autoTransition)
+      addTransition(N);
+    return N;
+  }
+
+  ExplodedNode *GenerateNode(const GRState *state, ExplodedNode *pred,
+                             bool autoTransition = true) {
+   assert(statement && "Only transitions with statements currently supported");
+    ExplodedNode *N = GenerateNodeImpl(statement, state, pred, false);
+    if (N && autoTransition)
+      addTransition(N);
+    return N;
+  }
+
+  ExplodedNode *GenerateNode(const GRState *state, bool autoTransition = true) {
+    assert(statement && "Only transitions with statements currently supported");
+    ExplodedNode *N = GenerateNodeImpl(statement, state, false);
+    if (N && autoTransition)
+      addTransition(N);
+    return N;
+  }
+
+  ExplodedNode *GenerateSink(const Stmt *stmt, const GRState *state = 0) {
+    return GenerateNodeImpl(stmt, state ? state : getState(), true);
+  }
+  
+  ExplodedNode *GenerateSink(const GRState *state = 0) {
+    assert(statement && "Only transitions with statements currently supported");
+    return GenerateNodeImpl(statement, state ? state : getState(), true);
+  }
+
+  void addTransition(ExplodedNode *node) {
+    Dst.Add(node);
+  }
+  
+  void addTransition(const GRState *state) {
+    assert(state);
+    // If the 'state' is not new, we need to check if the cached state 'ST'
+    // is new.
+    if (state != getState() || (ST && ST != B.GetState(Pred)))
+      GenerateNode(state, true);
+    else
+      Dst.Add(Pred);
+  }
+
+  // Generate a node with a new program point different from the one that will
+  // be created by the GRStmtNodeBuilder.
+  void addTransition(const GRState *state, ProgramPoint Loc) {
+    ExplodedNode *N = B.generateNode(Loc, state, Pred);
+    if (N)
+      addTransition(N);
+  }
+
+  void EmitReport(BugReport *R) {
+    Eng.getBugReporter().EmitReport(R);
+  }
+
+private:
+  ExplodedNode *GenerateNodeImpl(const Stmt* stmt, const GRState *state,
+                             bool markAsSink) {
+    ExplodedNode *node = B.generateNode(stmt, state, Pred);
+    if (markAsSink && node)
+      node->markAsSink();
+    return node;
+  }
+
+  ExplodedNode *GenerateNodeImpl(const Stmt* stmt, const GRState *state,
+                                 ExplodedNode *pred, bool markAsSink) {
+   ExplodedNode *node = B.generateNode(stmt, state, pred);
+    if (markAsSink && node)
+      node->markAsSink();
+    return node;
+  }
+};
+
+class Checker {
+private:
+  friend class GRExprEngine;
+
+  // FIXME: Remove the 'tag' option.
+  void GR_Visit(ExplodedNodeSet &Dst,
+                GRStmtNodeBuilder &Builder,
+                GRExprEngine &Eng,
+                const Stmt *S,
+                ExplodedNode *Pred, void *tag, bool isPrevisit) {
+    CheckerContext C(Dst, Builder, Eng, Pred, tag,
+                     isPrevisit ? ProgramPoint::PreStmtKind :
+                     ProgramPoint::PostStmtKind, S);
+    if (isPrevisit)
+      _PreVisit(C, S);
+    else
+      _PostVisit(C, S);
+  }
+
+  bool GR_EvalNilReceiver(ExplodedNodeSet &Dst, GRStmtNodeBuilder &Builder,
+                          GRExprEngine &Eng, const ObjCMessageExpr *ME,
+                          ExplodedNode *Pred, const GRState *state, void *tag) {
+    CheckerContext C(Dst, Builder, Eng, Pred, tag, ProgramPoint::PostStmtKind,
+                     ME, state);
+    return EvalNilReceiver(C, ME);
+  }
+
+  bool GR_EvalCallExpr(ExplodedNodeSet &Dst, GRStmtNodeBuilder &Builder,
+                       GRExprEngine &Eng, const CallExpr *CE,
+                       ExplodedNode *Pred, void *tag) {
+    CheckerContext C(Dst, Builder, Eng, Pred, tag, ProgramPoint::PostStmtKind,
+                     CE);
+    return EvalCallExpr(C, CE);
+  }
+
+  // FIXME: Remove the 'tag' option.
+  void GR_VisitBind(ExplodedNodeSet &Dst,
+                    GRStmtNodeBuilder &Builder, GRExprEngine &Eng,
+                    const Stmt *AssignE,
+                    const Stmt *StoreE, ExplodedNode *Pred, void *tag, 
+                    SVal location, SVal val,
+                    bool isPrevisit) {
+    CheckerContext C(Dst, Builder, Eng, Pred, tag,
+                     isPrevisit ? ProgramPoint::PreStmtKind :
+                     ProgramPoint::PostStmtKind, StoreE);
+    assert(isPrevisit && "Only previsit supported for now.");
+    PreVisitBind(C, AssignE, StoreE, location, val);
+  }
+  
+  // FIXME: Remove the 'tag' option.
+  void GR_VisitLocation(ExplodedNodeSet &Dst,
+                        GRStmtNodeBuilder &Builder,
+                        GRExprEngine &Eng,
+                        const Stmt *S,
+                        ExplodedNode *Pred, const GRState *state,
+                        SVal location,
+                        void *tag, bool isLoad) {
+    CheckerContext C(Dst, Builder, Eng, Pred, tag,
+                     isLoad ? ProgramPoint::PreLoadKind :
+                     ProgramPoint::PreStoreKind, S, state);
+    VisitLocation(C, S, location);
+  }
+
+  void GR_EvalDeadSymbols(ExplodedNodeSet &Dst, GRStmtNodeBuilder &Builder,
+                          GRExprEngine &Eng, const Stmt *S, ExplodedNode *Pred,
+                          SymbolReaper &SymReaper, void *tag) {
+    CheckerContext C(Dst, Builder, Eng, Pred, tag, 
+                     ProgramPoint::PostPurgeDeadSymbolsKind, S);
+    EvalDeadSymbols(C, S, SymReaper);
+  }
+
+public:
+  virtual ~Checker();
+  virtual void _PreVisit(CheckerContext &C, const Stmt *S) {}
+  virtual void _PostVisit(CheckerContext &C, const Stmt *S) {}
+  virtual void VisitLocation(CheckerContext &C, const Stmt *S, SVal location) {}
+  virtual void PreVisitBind(CheckerContext &C, const Stmt *AssignE,
+                            const Stmt *StoreE, SVal location, SVal val) {}
+  virtual void EvalDeadSymbols(CheckerContext &C, const Stmt *S,
+                               SymbolReaper &SymReaper) {}
+  virtual void EvalEndPath(GREndPathNodeBuilder &B, void *tag,
+                           GRExprEngine &Eng) {}
+
+  virtual void VisitBranchCondition(GRBranchNodeBuilder &Builder,
+                                    GRExprEngine &Eng,
+                                    Stmt *Condition, void *tag) {}
+
+  virtual bool EvalNilReceiver(CheckerContext &C, const ObjCMessageExpr *ME) {
+    return false;
+  }
+
+  virtual bool EvalCallExpr(CheckerContext &C, const CallExpr *CE) {
+    return false;
+  }
+
+  virtual const GRState *EvalAssume(const GRState *state, SVal Cond, 
+                                    bool Assumption) {
+    return state;
+  }
+};
+} // end clang namespace
+
+#endif
+
diff --git a/include/clang/Checker/PathSensitive/CheckerVisitor.def b/include/clang/Checker/PathSensitive/CheckerVisitor.def
new file mode 100644
index 0000000..2edc4a3
--- /dev/null
+++ b/include/clang/Checker/PathSensitive/CheckerVisitor.def
@@ -0,0 +1,37 @@
+//===-- CheckerVisitor.def - Metadata for CheckerVisitor ----------------*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the AST nodes accepted by the CheckerVisitor class.
+//
+//===---------------------------------------------------------------------===//
+
+#ifndef PREVISIT
+#define PREVISIT(NODE, FALLBACK)
+#endif
+
+#ifndef POSTVISIT
+#define POSTVISIT(NODE, FALLBACK)
+#endif
+
+PREVISIT(ArraySubscriptExpr, Stmt)
+PREVISIT(BinaryOperator, Stmt)
+PREVISIT(CallExpr, Stmt)
+PREVISIT(CXXOperatorCallExpr, CallExpr)
+PREVISIT(DeclStmt, Stmt)
+PREVISIT(ObjCMessageExpr, Stmt)
+PREVISIT(ReturnStmt, Stmt)
+
+POSTVISIT(BlockExpr, Stmt)
+POSTVISIT(BinaryOperator, Stmt)
+POSTVISIT(CallExpr, Stmt)
+POSTVISIT(CXXOperatorCallExpr, CallExpr)
+POSTVISIT(ObjCMessageExpr, Stmt)
+
+#undef PREVISIT
+#undef POSTVISIT
diff --git a/include/clang/Checker/PathSensitive/CheckerVisitor.h b/include/clang/Checker/PathSensitive/CheckerVisitor.h
new file mode 100644
index 0000000..72f0ae1
--- /dev/null
+++ b/include/clang/Checker/PathSensitive/CheckerVisitor.h
@@ -0,0 +1,102 @@
+//== CheckerVisitor.h - Abstract visitor for checkers ------------*- C++ -*--=//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines CheckerVisitor.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_CHECKERVISITOR
+#define LLVM_CLANG_ANALYSIS_CHECKERVISITOR
+#include "clang/Checker/PathSensitive/Checker.h"
+
+namespace clang {
+
+//===----------------------------------------------------------------------===//
+// Checker visitor interface.  Used by subclasses of Checker to specify their
+// own checker visitor logic.
+//===----------------------------------------------------------------------===//
+
+/// CheckerVisitor - This class implements a simple visitor for Stmt subclasses.
+/// Since Expr derives from Stmt, this also includes support for visiting Exprs.
+template<typename ImplClass>
+class CheckerVisitor : public Checker {
+public:
+  virtual void _PreVisit(CheckerContext &C, const Stmt *S) {
+    PreVisit(C, S);
+  }
+  
+  virtual void _PostVisit(CheckerContext &C, const Stmt *S) {
+    PostVisit(C, S);
+  }
+
+  void PreVisit(CheckerContext &C, const Stmt *S) {
+    switch (S->getStmtClass()) {
+      default:
+        assert(false && "Unsupport statement.");
+        return;
+
+      case Stmt::ImplicitCastExprClass:
+      case Stmt::CStyleCastExprClass:
+        static_cast<ImplClass*>(this)->PreVisitCastExpr(C,
+                                               static_cast<const CastExpr*>(S));
+        break;
+
+      case Stmt::CompoundAssignOperatorClass:
+        static_cast<ImplClass*>(this)->PreVisitBinaryOperator(C,
+                                         static_cast<const BinaryOperator*>(S));
+        break;
+
+#define PREVISIT(NAME, FALLBACK) \
+case Stmt::NAME ## Class:\
+static_cast<ImplClass*>(this)->PreVisit ## NAME(C,static_cast<const NAME*>(S));\
+break;
+#include "clang/Checker/PathSensitive/CheckerVisitor.def"
+    }
+  }
+  
+  void PostVisit(CheckerContext &C, const Stmt *S) {
+    switch (S->getStmtClass()) {
+      default:
+        assert(false && "Unsupport statement.");
+        return;
+      case Stmt::CompoundAssignOperatorClass:
+        static_cast<ImplClass*>(this)->PostVisitBinaryOperator(C,
+                                         static_cast<const BinaryOperator*>(S));
+        break;
+
+#define POSTVISIT(NAME, FALLBACK) \
+case Stmt::NAME ## Class:\
+static_cast<ImplClass*>(this)->\
+PostVisit ## NAME(C,static_cast<const NAME*>(S));\
+break;
+#include "clang/Checker/PathSensitive/CheckerVisitor.def"
+    }
+  }
+
+  void PreVisitStmt(CheckerContext &C, const Stmt *S) {}
+  void PostVisitStmt(CheckerContext &C, const Stmt *S) {}
+
+  void PreVisitCastExpr(CheckerContext &C, const CastExpr *E) {
+    static_cast<ImplClass*>(this)->PreVisitStmt(C, E);
+  }
+  
+#define PREVISIT(NAME, FALLBACK) \
+void PreVisit ## NAME(CheckerContext &C, const NAME* S) {\
+  static_cast<ImplClass*>(this)->PreVisit ## FALLBACK(C, S);\
+}
+#define POSTVISIT(NAME, FALLBACK) \
+void PostVisit ## NAME(CheckerContext &C, const NAME* S) {\
+  static_cast<ImplClass*>(this)->PostVisit ## FALLBACK(C, S);\
+}
+#include "clang/Checker/PathSensitive/CheckerVisitor.def"
+};
+
+} // end clang namespace
+
+#endif
diff --git a/include/clang/Checker/PathSensitive/ConstraintManager.h b/include/clang/Checker/PathSensitive/ConstraintManager.h
new file mode 100644
index 0000000..ce7d1b3
--- /dev/null
+++ b/include/clang/Checker/PathSensitive/ConstraintManager.h
@@ -0,0 +1,75 @@
+//== ConstraintManager.h - Constraints on symbolic values.-------*- C++ -*--==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defined the interface to manage constraints on symbolic values.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_CONSTRAINT_MANAGER_H
+#define LLVM_CLANG_ANALYSIS_CONSTRAINT_MANAGER_H
+
+// FIXME: Typedef LiveSymbolsTy/DeadSymbolsTy at a more appropriate place.
+#include "clang/Checker/PathSensitive/Store.h"
+
+namespace llvm {
+class APSInt;
+}
+
+namespace clang {
+
+class GRState;
+class GRStateManager;
+class GRSubEngine;
+class SVal;
+
+class ConstraintManager {
+public:
+  virtual ~ConstraintManager();
+  virtual const GRState *Assume(const GRState *state, DefinedSVal Cond,
+                                bool Assumption) = 0;
+
+  virtual const GRState *AssumeInBound(const GRState *state, DefinedSVal Idx,
+                                       DefinedSVal UpperBound, bool Assumption) = 0;
+
+  std::pair<const GRState*, const GRState*> AssumeDual(const GRState *state,
+                                                       DefinedSVal Cond) {
+    return std::make_pair(Assume(state, Cond, true),
+                          Assume(state, Cond, false));
+  }
+
+  virtual const llvm::APSInt* getSymVal(const GRState *state,
+                                        SymbolRef sym) const = 0;
+
+  virtual bool isEqual(const GRState *state, SymbolRef sym,
+                       const llvm::APSInt& V) const = 0;
+
+  virtual const GRState *RemoveDeadBindings(const GRState *state,
+                                            SymbolReaper& SymReaper) = 0;
+
+  virtual void print(const GRState *state, llvm::raw_ostream& Out,
+                     const char* nl, const char *sep) = 0;
+
+  virtual void EndPath(const GRState *state) {}
+
+  /// canReasonAbout - Not all ConstraintManagers can accurately reason about
+  ///  all SVal values.  This method returns true if the ConstraintManager can
+  ///  reasonably handle a given SVal value.  This is typically queried by
+  ///  GRExprEngine to determine if the value should be replaced with a
+  ///  conjured symbolic value in order to recover some precision.
+  virtual bool canReasonAbout(SVal X) const = 0;
+};
+
+ConstraintManager* CreateBasicConstraintManager(GRStateManager& statemgr,
+                                                GRSubEngine &subengine);
+ConstraintManager* CreateRangeConstraintManager(GRStateManager& statemgr,
+                                                GRSubEngine &subengine);
+
+} // end clang namespace
+
+#endif
diff --git a/include/clang/Checker/PathSensitive/Environment.h b/include/clang/Checker/PathSensitive/Environment.h
new file mode 100644
index 0000000..b9bbebc
--- /dev/null
+++ b/include/clang/Checker/PathSensitive/Environment.h
@@ -0,0 +1,96 @@
+//== Environment.h - Map from Stmt* to Locations/Values ---------*- C++ -*--==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defined the Environment and EnvironmentManager classes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_ENVIRONMENT_H
+#define LLVM_CLANG_ANALYSIS_ENVIRONMENT_H
+
+// For using typedefs in StoreManager. Should find a better place for these
+// typedefs.
+#include "clang/Checker/PathSensitive/Store.h"
+
+#include "clang/Checker/PathSensitive/SVals.h"
+#include "llvm/ADT/ImmutableMap.h"
+
+namespace clang {
+
+class EnvironmentManager;
+class ValueManager;
+class LiveVariables;
+
+
+class Environment {
+private:
+  friend class EnvironmentManager;
+
+  // Type definitions.
+  typedef llvm::ImmutableMap<const Stmt*,SVal> BindingsTy;
+
+  // Data.
+  BindingsTy ExprBindings;
+
+  Environment(BindingsTy eb)
+    : ExprBindings(eb) {}
+
+public:
+  typedef BindingsTy::iterator iterator;
+  iterator begin() const { return ExprBindings.begin(); }
+  iterator end() const { return ExprBindings.end(); }
+
+  SVal LookupExpr(const Stmt* E) const {
+    const SVal* X = ExprBindings.lookup(E);
+    return X ? *X : UnknownVal();
+  }
+
+  SVal GetSVal(const Stmt* Ex, ValueManager& ValMgr) const;
+
+  /// Profile - Profile the contents of an Environment object for use
+  ///  in a FoldingSet.
+  static void Profile(llvm::FoldingSetNodeID& ID, const Environment* E) {
+    E->ExprBindings.Profile(ID);
+  }
+
+  /// Profile - Used to profile the contents of this object for inclusion
+  ///  in a FoldingSet.
+  void Profile(llvm::FoldingSetNodeID& ID) const {
+    Profile(ID, this);
+  }
+
+  bool operator==(const Environment& RHS) const {
+    return ExprBindings == RHS.ExprBindings;
+  }
+};
+
+class EnvironmentManager {
+private:
+  typedef Environment::BindingsTy::Factory FactoryTy;
+  FactoryTy F;
+
+public:
+  EnvironmentManager(llvm::BumpPtrAllocator& Allocator) : F(Allocator) {}
+  ~EnvironmentManager() {}
+
+  Environment getInitialEnvironment() {
+    return Environment(F.GetEmptyMap());
+  }
+
+  Environment BindExpr(Environment Env, const Stmt *S, SVal V,
+                       bool Invalidate);
+
+  Environment RemoveDeadBindings(Environment Env, const Stmt *S,
+                                 SymbolReaper &SymReaper, const GRState *ST,
+                          llvm::SmallVectorImpl<const MemRegion*>& RegionRoots);
+};
+
+} // end clang namespace
+
+#endif
diff --git a/include/clang/Checker/PathSensitive/ExplodedGraph.h b/include/clang/Checker/PathSensitive/ExplodedGraph.h
new file mode 100644
index 0000000..c09c893
--- /dev/null
+++ b/include/clang/Checker/PathSensitive/ExplodedGraph.h
@@ -0,0 +1,436 @@
+//=-- ExplodedGraph.h - Local, Path-Sens. "Exploded Graph" -*- C++ -*-------==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the template classes ExplodedNode and ExplodedGraph,
+//  which represent a path-sensitive, intra-procedural "exploded graph."
+//  See "Precise interprocedural dataflow analysis via graph reachability"
+//  by Reps, Horwitz, and Sagiv
+//  (http://portal.acm.org/citation.cfm?id=199462) for the definition of an
+//  exploded graph.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_EXPLODEDGRAPH
+#define LLVM_CLANG_ANALYSIS_EXPLODEDGRAPH
+
+#include "clang/Analysis/ProgramPoint.h"
+#include "clang/Analysis/AnalysisContext.h"
+#include "clang/AST/Decl.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/DepthFirstIterator.h"
+#include "llvm/Support/Casting.h"
+#include "clang/Analysis/Support/BumpVector.h"
+
+namespace clang {
+
+class GRState;
+class CFG;
+class ASTContext;
+class ExplodedGraph;
+
+//===----------------------------------------------------------------------===//
+// ExplodedGraph "implementation" classes.  These classes are not typed to
+// contain a specific kind of state.  Typed-specialized versions are defined
+// on top of these classes.
+//===----------------------------------------------------------------------===//
+
+class ExplodedNode : public llvm::FoldingSetNode {
+  friend class ExplodedGraph;
+  friend class GRCoreEngine;
+  friend class GRStmtNodeBuilder;
+  friend class GRBranchNodeBuilder;
+  friend class GRIndirectGotoNodeBuilder;
+  friend class GRSwitchNodeBuilder;
+  friend class GREndPathNodeBuilder;
+
+  class NodeGroup {
+    enum { Size1 = 0x0, SizeOther = 0x1, AuxFlag = 0x2, Mask = 0x3 };
+    uintptr_t P;
+
+    unsigned getKind() const {
+      return P & 0x1;
+    }
+
+    void* getPtr() const {
+      assert (!getFlag());
+      return reinterpret_cast<void*>(P & ~Mask);
+    }
+
+    ExplodedNode *getNode() const {
+      return reinterpret_cast<ExplodedNode*>(getPtr());
+    }
+
+  public:
+    NodeGroup() : P(0) {}
+
+    ExplodedNode **begin() const;
+
+    ExplodedNode **end() const;
+
+    unsigned size() const;
+
+    bool empty() const { return (P & ~Mask) == 0; }
+
+    void addNode(ExplodedNode* N, ExplodedGraph &G);
+
+    void setFlag() {
+      assert(P == 0);
+      P = AuxFlag;
+    }
+
+    bool getFlag() const {
+      return P & AuxFlag ? true : false;
+    }
+  };
+
+  /// Location - The program location (within a function body) associated
+  ///  with this node.
+  const ProgramPoint Location;
+
+  /// State - The state associated with this node.
+  const GRState* State;
+
+  /// Preds - The predecessors of this node.
+  NodeGroup Preds;
+
+  /// Succs - The successors of this node.
+  NodeGroup Succs;
+
+public:
+
+  explicit ExplodedNode(const ProgramPoint& loc, const GRState* state)
+    : Location(loc), State(state) {}
+
+  /// getLocation - Returns the edge associated with the given node.
+  ProgramPoint getLocation() const { return Location; }
+
+  const LocationContext *getLocationContext() const {
+    return getLocation().getLocationContext();
+  }
+
+  const Decl &getCodeDecl() const { return *getLocationContext()->getDecl(); }
+
+  CFG &getCFG() const { return *getLocationContext()->getCFG(); }
+
+  ParentMap &getParentMap() const {return getLocationContext()->getParentMap();}
+
+  LiveVariables &getLiveVariables() const { 
+    return *getLocationContext()->getLiveVariables(); 
+  }
+
+  const GRState* getState() const { return State; }
+
+  template <typename T>
+  const T* getLocationAs() const { return llvm::dyn_cast<T>(&Location); }
+
+  static void Profile(llvm::FoldingSetNodeID &ID,
+                      const ProgramPoint& Loc, const GRState* state) {
+    ID.Add(Loc);
+    ID.AddPointer(state);
+  }
+
+  void Profile(llvm::FoldingSetNodeID& ID) const {
+    Profile(ID, getLocation(), getState());
+  }
+
+  /// addPredeccessor - Adds a predecessor to the current node, and
+  ///  in tandem add this node as a successor of the other node.
+  void addPredecessor(ExplodedNode* V, ExplodedGraph &G);
+
+  unsigned succ_size() const { return Succs.size(); }
+  unsigned pred_size() const { return Preds.size(); }
+  bool succ_empty() const { return Succs.empty(); }
+  bool pred_empty() const { return Preds.empty(); }
+
+  bool isSink() const { return Succs.getFlag(); }
+  void markAsSink() { Succs.setFlag(); }
+
+  ExplodedNode* getFirstPred() {
+    return pred_empty() ? NULL : *(pred_begin());
+  }
+
+  const ExplodedNode* getFirstPred() const {
+    return const_cast<ExplodedNode*>(this)->getFirstPred();
+  }
+
+  // Iterators over successor and predecessor vertices.
+  typedef ExplodedNode**       succ_iterator;
+  typedef const ExplodedNode* const * const_succ_iterator;
+  typedef ExplodedNode**       pred_iterator;
+  typedef const ExplodedNode* const * const_pred_iterator;
+
+  pred_iterator pred_begin() { return Preds.begin(); }
+  pred_iterator pred_end() { return Preds.end(); }
+
+  const_pred_iterator pred_begin() const {
+    return const_cast<ExplodedNode*>(this)->pred_begin();
+  }
+  const_pred_iterator pred_end() const {
+    return const_cast<ExplodedNode*>(this)->pred_end();
+  }
+
+  succ_iterator succ_begin() { return Succs.begin(); }
+  succ_iterator succ_end() { return Succs.end(); }
+
+  const_succ_iterator succ_begin() const {
+    return const_cast<ExplodedNode*>(this)->succ_begin();
+  }
+  const_succ_iterator succ_end() const {
+    return const_cast<ExplodedNode*>(this)->succ_end();
+  }
+
+  // For debugging.
+
+public:
+
+  class Auditor {
+  public:
+    virtual ~Auditor();
+    virtual void AddEdge(ExplodedNode* Src, ExplodedNode* Dst) = 0;
+  };
+
+  static void SetAuditor(Auditor* A);
+};
+
+// FIXME: Is this class necessary?
+class InterExplodedGraphMap {
+  llvm::DenseMap<const ExplodedNode*, ExplodedNode*> M;
+  friend class ExplodedGraph;
+
+public:
+  ExplodedNode* getMappedNode(const ExplodedNode* N) const;
+
+  InterExplodedGraphMap() {}
+  virtual ~InterExplodedGraphMap() {}
+};
+
+class ExplodedGraph {
+protected:
+  friend class GRCoreEngine;
+
+  // Type definitions.
+  typedef llvm::SmallVector<ExplodedNode*,2>    RootsTy;
+  typedef llvm::SmallVector<ExplodedNode*,10>   EndNodesTy;
+
+  /// Roots - The roots of the simulation graph. Usually there will be only
+  /// one, but clients are free to establish multiple subgraphs within a single
+  /// SimulGraph. Moreover, these subgraphs can often merge when paths from
+  /// different roots reach the same state at the same program location.
+  RootsTy Roots;
+
+  /// EndNodes - The nodes in the simulation graph which have been
+  ///  specially marked as the endpoint of an abstract simulation path.
+  EndNodesTy EndNodes;
+
+  /// Nodes - The nodes in the graph.
+  llvm::FoldingSet<ExplodedNode> Nodes;
+
+  /// BVC - Allocator and context for allocating nodes and their predecessor
+  /// and successor groups.
+  BumpVectorContext BVC;
+
+  /// Ctx - The ASTContext used to "interpret" CodeDecl.
+  ASTContext& Ctx;
+
+  /// NumNodes - The number of nodes in the graph.
+  unsigned NumNodes;
+
+public:
+  /// getNode - Retrieve the node associated with a (Location,State) pair,
+  ///  where the 'Location' is a ProgramPoint in the CFG.  If no node for
+  ///  this pair exists, it is created.  IsNew is set to true if
+  ///  the node was freshly created.
+
+  ExplodedNode* getNode(const ProgramPoint& L, const GRState *State,
+                        bool* IsNew = 0);
+
+  ExplodedGraph* MakeEmptyGraph() const {
+    return new ExplodedGraph(Ctx);
+  }
+
+  /// addRoot - Add an untyped node to the set of roots.
+  ExplodedNode* addRoot(ExplodedNode* V) {
+    Roots.push_back(V);
+    return V;
+  }
+
+  /// addEndOfPath - Add an untyped node to the set of EOP nodes.
+  ExplodedNode* addEndOfPath(ExplodedNode* V) {
+    EndNodes.push_back(V);
+    return V;
+  }
+
+  ExplodedGraph(ASTContext& ctx) : Ctx(ctx), NumNodes(0) {}
+
+  ~ExplodedGraph() {}
+
+  unsigned num_roots() const { return Roots.size(); }
+  unsigned num_eops() const { return EndNodes.size(); }
+
+  bool empty() const { return NumNodes == 0; }
+  unsigned size() const { return NumNodes; }
+
+  // Iterators.
+  typedef ExplodedNode                        NodeTy;
+  typedef llvm::FoldingSet<ExplodedNode>      AllNodesTy;
+  typedef NodeTy**                            roots_iterator;
+  typedef NodeTy* const *                     const_roots_iterator;
+  typedef NodeTy**                            eop_iterator;
+  typedef NodeTy* const *                     const_eop_iterator;
+  typedef AllNodesTy::iterator                node_iterator;
+  typedef AllNodesTy::const_iterator          const_node_iterator;
+
+  node_iterator nodes_begin() { return Nodes.begin(); }
+
+  node_iterator nodes_end() { return Nodes.end(); }
+
+  const_node_iterator nodes_begin() const { return Nodes.begin(); }
+
+  const_node_iterator nodes_end() const { return Nodes.end(); }
+
+  roots_iterator roots_begin() { return Roots.begin(); }
+
+  roots_iterator roots_end() { return Roots.end(); }
+
+  const_roots_iterator roots_begin() const { return Roots.begin(); }
+
+  const_roots_iterator roots_end() const { return Roots.end(); }
+
+  eop_iterator eop_begin() { return EndNodes.begin(); }
+
+  eop_iterator eop_end() { return EndNodes.end(); }
+
+  const_eop_iterator eop_begin() const { return EndNodes.begin(); }
+
+  const_eop_iterator eop_end() const { return EndNodes.end(); }
+
+  llvm::BumpPtrAllocator & getAllocator() { return BVC.getAllocator(); }
+  BumpVectorContext &getNodeAllocator() { return BVC; }
+
+  ASTContext& getContext() { return Ctx; }
+
+  typedef llvm::DenseMap<const ExplodedNode*, ExplodedNode*> NodeMap;
+
+  std::pair<ExplodedGraph*, InterExplodedGraphMap*>
+  Trim(const NodeTy* const* NBeg, const NodeTy* const* NEnd,
+       llvm::DenseMap<const void*, const void*> *InverseMap = 0) const;
+
+  ExplodedGraph* TrimInternal(const ExplodedNode* const * NBeg,
+                              const ExplodedNode* const * NEnd,
+                              InterExplodedGraphMap *M,
+                    llvm::DenseMap<const void*, const void*> *InverseMap) const;
+};
+
+class ExplodedNodeSet {
+  typedef llvm::SmallPtrSet<ExplodedNode*,5> ImplTy;
+  ImplTy Impl;
+
+public:
+  ExplodedNodeSet(ExplodedNode* N) {
+    assert (N && !static_cast<ExplodedNode*>(N)->isSink());
+    Impl.insert(N);
+  }
+
+  ExplodedNodeSet() {}
+
+  inline void Add(ExplodedNode* N) {
+    if (N && !static_cast<ExplodedNode*>(N)->isSink()) Impl.insert(N);
+  }
+
+  ExplodedNodeSet& operator=(const ExplodedNodeSet &X) {
+    Impl = X.Impl;
+    return *this;
+  }
+
+  typedef ImplTy::iterator       iterator;
+  typedef ImplTy::const_iterator const_iterator;
+
+  unsigned size() const { return Impl.size();  }
+  bool empty()    const { return Impl.empty(); }
+
+  void clear() { Impl.clear(); }
+  void insert(const ExplodedNodeSet &S) {
+    if (empty())
+      Impl = S.Impl;
+    else
+      Impl.insert(S.begin(), S.end());
+  }
+
+  inline iterator begin() { return Impl.begin(); }
+  inline iterator end()   { return Impl.end();   }
+
+  inline const_iterator begin() const { return Impl.begin(); }
+  inline const_iterator end()   const { return Impl.end();   }
+};
+
+} // end clang namespace
+
+// GraphTraits
+
+namespace llvm {
+  template<> struct GraphTraits<clang::ExplodedNode*> {
+    typedef clang::ExplodedNode NodeType;
+    typedef NodeType::succ_iterator  ChildIteratorType;
+    typedef llvm::df_iterator<NodeType*>      nodes_iterator;
+
+    static inline NodeType* getEntryNode(NodeType* N) {
+      return N;
+    }
+
+    static inline ChildIteratorType child_begin(NodeType* N) {
+      return N->succ_begin();
+    }
+
+    static inline ChildIteratorType child_end(NodeType* N) {
+      return N->succ_end();
+    }
+
+    static inline nodes_iterator nodes_begin(NodeType* N) {
+      return df_begin(N);
+    }
+
+    static inline nodes_iterator nodes_end(NodeType* N) {
+      return df_end(N);
+    }
+  };
+
+  template<> struct GraphTraits<const clang::ExplodedNode*> {
+    typedef const clang::ExplodedNode NodeType;
+    typedef NodeType::const_succ_iterator   ChildIteratorType;
+    typedef llvm::df_iterator<NodeType*>       nodes_iterator;
+
+    static inline NodeType* getEntryNode(NodeType* N) {
+      return N;
+    }
+
+    static inline ChildIteratorType child_begin(NodeType* N) {
+      return N->succ_begin();
+    }
+
+    static inline ChildIteratorType child_end(NodeType* N) {
+      return N->succ_end();
+    }
+
+    static inline nodes_iterator nodes_begin(NodeType* N) {
+      return df_begin(N);
+    }
+
+    static inline nodes_iterator nodes_end(NodeType* N) {
+      return df_end(N);
+    }
+  };
+
+} // end llvm namespace
+
+#endif
diff --git a/include/clang/Checker/PathSensitive/GRAuditor.h b/include/clang/Checker/PathSensitive/GRAuditor.h
new file mode 100644
index 0000000..015c82e
--- /dev/null
+++ b/include/clang/Checker/PathSensitive/GRAuditor.h
@@ -0,0 +1,35 @@
+//==- GRAuditor.h - Observers of the creation of ExplodedNodes------*- C++ -*-//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines GRAuditor and its primary subclasses, an interface
+//  to audit the creation of ExplodedNodes.  This interface can be used
+//  to implement simple checkers that do not mutate analysis state but
+//  instead operate by perfoming simple logical checks at key monitoring
+//  locations (e.g., function calls).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_GRAUDITOR
+#define LLVM_CLANG_ANALYSIS_GRAUDITOR
+
+namespace clang {
+
+class ExplodedNode;
+class GRStateManager;
+
+class GRAuditor {
+public:
+  virtual ~GRAuditor() {}
+  virtual bool Audit(ExplodedNode* N, GRStateManager& M) = 0;
+};
+
+
+} // end clang namespace
+
+#endif
diff --git a/include/clang/Checker/PathSensitive/GRBlockCounter.h b/include/clang/Checker/PathSensitive/GRBlockCounter.h
new file mode 100644
index 0000000..b7d0e8a
--- /dev/null
+++ b/include/clang/Checker/PathSensitive/GRBlockCounter.h
@@ -0,0 +1,55 @@
+//==- GRBlockCounter.h - ADT for counting block visits -------------*- C++ -*-//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines GRBlockCounter, an abstract data type used to count
+//  the number of times a given block has been visited along a path
+//  analyzed by GRCoreEngine.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_GRBLOCKCOUNTER
+#define LLVM_CLANG_ANALYSIS_GRBLOCKCOUNTER
+
+namespace llvm {
+  class BumpPtrAllocator;
+}
+
+namespace clang {
+
+class StackFrameContext;
+
+class GRBlockCounter {
+  void* Data;
+
+  GRBlockCounter(void* D) : Data(D) {}
+
+public:
+  GRBlockCounter() : Data(0) {}
+
+  unsigned getNumVisited(const StackFrameContext *CallSite, 
+                         unsigned BlockID) const;
+
+  class Factory {
+    void* F;
+  public:
+    Factory(llvm::BumpPtrAllocator& Alloc);
+    ~Factory();
+
+    GRBlockCounter GetEmptyCounter();
+    GRBlockCounter IncrementCount(GRBlockCounter BC, 
+                                  const StackFrameContext *CallSite,
+                                  unsigned BlockID);
+  };
+
+  friend class Factory;
+};
+
+} // end clang namespace
+
+#endif
diff --git a/include/clang/Checker/PathSensitive/GRCoreEngine.h b/include/clang/Checker/PathSensitive/GRCoreEngine.h
new file mode 100644
index 0000000..2d8afee
--- /dev/null
+++ b/include/clang/Checker/PathSensitive/GRCoreEngine.h
@@ -0,0 +1,487 @@
+//==- GRCoreEngine.h - Path-Sensitive Dataflow Engine --------------*- C++ -*-//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines a generic engine for intraprocedural, path-sensitive,
+//  dataflow analysis via graph reachability.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_GRENGINE
+#define LLVM_CLANG_ANALYSIS_GRENGINE
+
+#include "clang/AST/Expr.h"
+#include "clang/Checker/PathSensitive/ExplodedGraph.h"
+#include "clang/Checker/PathSensitive/GRWorkList.h"
+#include "clang/Checker/PathSensitive/GRBlockCounter.h"
+#include "clang/Checker/PathSensitive/GRAuditor.h"
+#include "clang/Checker/PathSensitive/GRSubEngine.h"
+#include "llvm/ADT/OwningPtr.h"
+
+namespace clang {
+
+//===----------------------------------------------------------------------===//
+/// GRCoreEngine - Implements the core logic of the graph-reachability
+///   analysis. It traverses the CFG and generates the ExplodedGraph.
+///   Program "states" are treated as opaque void pointers.
+///   The template class GRCoreEngine (which subclasses GRCoreEngine)
+///   provides the matching component to the engine that knows the actual types
+///   for states.  Note that this engine only dispatches to transfer functions
+///   at the statement and block-level.  The analyses themselves must implement
+///   any transfer function logic and the sub-expression level (if any).
+class GRCoreEngine {
+  friend class GRStmtNodeBuilder;
+  friend class GRBranchNodeBuilder;
+  friend class GRIndirectGotoNodeBuilder;
+  friend class GRSwitchNodeBuilder;
+  friend class GREndPathNodeBuilder;
+  friend class GRCallEnterNodeBuilder;
+  friend class GRCallExitNodeBuilder;
+
+  GRSubEngine& SubEngine;
+
+  /// G - The simulation graph.  Each node is a (location,state) pair.
+  llvm::OwningPtr<ExplodedGraph> G;
+
+  /// WList - A set of queued nodes that need to be processed by the
+  ///  worklist algorithm.  It is up to the implementation of WList to decide
+  ///  the order that nodes are processed.
+  GRWorkList* WList;
+
+  /// BCounterFactory - A factory object for created GRBlockCounter objects.
+  ///   These are used to record for key nodes in the ExplodedGraph the
+  ///   number of times different CFGBlocks have been visited along a path.
+  GRBlockCounter::Factory BCounterFactory;
+
+  void GenerateNode(const ProgramPoint& Loc, const GRState* State,
+                    ExplodedNode* Pred);
+
+  void HandleBlockEdge(const BlockEdge& E, ExplodedNode* Pred);
+  void HandleBlockEntrance(const BlockEntrance& E, ExplodedNode* Pred);
+  void HandleBlockExit(CFGBlock* B, ExplodedNode* Pred);
+  void HandlePostStmt(const PostStmt& S, CFGBlock* B,
+                      unsigned StmtIdx, ExplodedNode *Pred);
+
+  void HandleBranch(Stmt* Cond, Stmt* Term, CFGBlock* B,
+                    ExplodedNode* Pred);
+  void HandleCallEnter(const CallEnter &L, const CFGBlock *Block,
+                       unsigned Index, ExplodedNode *Pred);
+  void HandleCallExit(const CallExit &L, ExplodedNode *Pred);
+
+  /// Get the initial state from the subengine.
+  const GRState* getInitialState(const LocationContext *InitLoc) {
+    return SubEngine.getInitialState(InitLoc);
+  }
+
+  void ProcessEndPath(GREndPathNodeBuilder& Builder);
+
+  void ProcessStmt(CFGElement E, GRStmtNodeBuilder& Builder);
+
+  bool ProcessBlockEntrance(CFGBlock* Blk, const ExplodedNode *Pred,
+                            GRBlockCounter BC);
+
+
+  void ProcessBranch(Stmt* Condition, Stmt* Terminator,
+                     GRBranchNodeBuilder& Builder);
+
+
+  void ProcessIndirectGoto(GRIndirectGotoNodeBuilder& Builder);
+
+
+  void ProcessSwitch(GRSwitchNodeBuilder& Builder);
+
+  void ProcessCallEnter(GRCallEnterNodeBuilder &Builder);
+  void ProcessCallExit(GRCallExitNodeBuilder &Builder);
+
+private:
+  GRCoreEngine(const GRCoreEngine&); // Do not implement.
+  GRCoreEngine& operator=(const GRCoreEngine&);
+
+public:
+  /// Construct a GRCoreEngine object to analyze the provided CFG using
+  ///  a DFS exploration of the exploded graph.
+  GRCoreEngine(ASTContext& ctx, GRSubEngine& subengine)
+    : SubEngine(subengine), G(new ExplodedGraph(ctx)),
+      WList(GRWorkList::MakeBFS()),
+      BCounterFactory(G->getAllocator()) {}
+
+  /// Construct a GRCoreEngine object to analyze the provided CFG and to
+  ///  use the provided worklist object to execute the worklist algorithm.
+  ///  The GRCoreEngine object assumes ownership of 'wlist'.
+  GRCoreEngine(ASTContext& ctx, GRWorkList* wlist, GRSubEngine& subengine)
+    : SubEngine(subengine), G(new ExplodedGraph(ctx)), WList(wlist),
+      BCounterFactory(G->getAllocator()) {}
+
+  ~GRCoreEngine() {
+    delete WList;
+  }
+
+  /// getGraph - Returns the exploded graph.
+  ExplodedGraph& getGraph() { return *G.get(); }
+
+  /// takeGraph - Returns the exploded graph.  Ownership of the graph is
+  ///  transfered to the caller.
+  ExplodedGraph* takeGraph() { return G.take(); }
+
+  /// ExecuteWorkList - Run the worklist algorithm for a maximum number of
+  ///  steps.  Returns true if there is still simulation state on the worklist.
+  bool ExecuteWorkList(const LocationContext *L, unsigned Steps);
+};
+
+class GRStmtNodeBuilder {
+  GRCoreEngine& Eng;
+  CFGBlock& B;
+  const unsigned Idx;
+  ExplodedNode* Pred;
+  GRStateManager& Mgr;
+  GRAuditor* Auditor;
+
+public:
+  bool PurgingDeadSymbols;
+  bool BuildSinks;
+  bool HasGeneratedNode;
+  ProgramPoint::Kind PointKind;
+  const void *Tag;
+
+  const GRState* CleanedState;
+
+
+  typedef llvm::SmallPtrSet<ExplodedNode*,5> DeferredTy;
+  DeferredTy Deferred;
+
+  void GenerateAutoTransition(ExplodedNode* N);
+
+public:
+  GRStmtNodeBuilder(CFGBlock* b, unsigned idx, ExplodedNode* N,
+                    GRCoreEngine* e, GRStateManager &mgr);
+
+  ~GRStmtNodeBuilder();
+
+  ExplodedNode* getBasePredecessor() const { return Pred; }
+
+  // FIXME: This should not be exposed.
+  GRWorkList *getWorkList() { return Eng.WList; }
+
+  void SetCleanedState(const GRState* St) {
+    CleanedState = St;
+  }
+
+  GRBlockCounter getBlockCounter() const { return Eng.WList->getBlockCounter();}
+
+  unsigned getCurrentBlockCount() const {
+    return getBlockCounter().getNumVisited(
+                            Pred->getLocationContext()->getCurrentStackFrame(),
+                                           B.getBlockID());
+  }
+
+  ExplodedNode* generateNode(PostStmt PP,const GRState* St,ExplodedNode* Pred) {
+    HasGeneratedNode = true;
+    return generateNodeInternal(PP, St, Pred);
+  }
+
+  ExplodedNode* generateNode(const Stmt *S, const GRState *St,
+                             ExplodedNode *Pred, ProgramPoint::Kind K) {
+    HasGeneratedNode = true;
+
+    if (PurgingDeadSymbols)
+      K = ProgramPoint::PostPurgeDeadSymbolsKind;
+
+    return generateNodeInternal(S, St, Pred, K, Tag);
+  }
+
+  ExplodedNode* generateNode(const Stmt *S, const GRState *St,
+                             ExplodedNode *Pred) {
+    return generateNode(S, St, Pred, PointKind);
+  }
+
+  ExplodedNode *generateNode(const ProgramPoint &PP, const GRState* State,
+                             ExplodedNode* Pred) {
+    HasGeneratedNode = true;
+    return generateNodeInternal(PP, State, Pred);
+  }
+
+  ExplodedNode*
+  generateNodeInternal(const ProgramPoint &PP, const GRState* State,
+                       ExplodedNode* Pred);
+
+  ExplodedNode*
+  generateNodeInternal(const Stmt* S, const GRState* State, ExplodedNode* Pred,
+                   ProgramPoint::Kind K = ProgramPoint::PostStmtKind,
+                   const void *tag = 0);
+
+  /// getStmt - Return the current block-level expression associated with
+  ///  this builder.
+  Stmt* getStmt() const { return B[Idx]; }
+
+  /// getBlock - Return the CFGBlock associated with the block-level expression
+  ///  of this builder.
+  CFGBlock* getBlock() const { return &B; }
+
+  unsigned getIndex() const { return Idx; }
+
+  void setAuditor(GRAuditor* A) { Auditor = A; }
+
+  const GRState* GetState(ExplodedNode* Pred) const {
+    if (Pred == getBasePredecessor())
+      return CleanedState;
+    else
+      return Pred->getState();
+  }
+
+  ExplodedNode* MakeNode(ExplodedNodeSet& Dst, Stmt* S, ExplodedNode* Pred,
+                   const GRState* St) {
+    return MakeNode(Dst, S, Pred, St, PointKind);
+  }
+
+  ExplodedNode* MakeNode(ExplodedNodeSet& Dst, Stmt* S, ExplodedNode* Pred,
+                         const GRState* St, ProgramPoint::Kind K);
+
+  ExplodedNode* MakeSinkNode(ExplodedNodeSet& Dst, Stmt* S,
+                       ExplodedNode* Pred, const GRState* St) {
+    bool Tmp = BuildSinks;
+    BuildSinks = true;
+    ExplodedNode* N = MakeNode(Dst, S, Pred, St);
+    BuildSinks = Tmp;
+    return N;
+  }
+};
+
+class GRBranchNodeBuilder {
+  GRCoreEngine& Eng;
+  CFGBlock* Src;
+  CFGBlock* DstT;
+  CFGBlock* DstF;
+  ExplodedNode* Pred;
+
+  typedef llvm::SmallVector<ExplodedNode*,3> DeferredTy;
+  DeferredTy Deferred;
+
+  bool GeneratedTrue;
+  bool GeneratedFalse;
+  bool InFeasibleTrue;
+  bool InFeasibleFalse;
+
+public:
+  GRBranchNodeBuilder(CFGBlock* src, CFGBlock* dstT, CFGBlock* dstF,
+                          ExplodedNode* pred, GRCoreEngine* e)
+  : Eng(*e), Src(src), DstT(dstT), DstF(dstF), Pred(pred),
+    GeneratedTrue(false), GeneratedFalse(false),
+    InFeasibleTrue(!DstT), InFeasibleFalse(!DstF) {}
+
+  ~GRBranchNodeBuilder();
+
+  ExplodedNode* getPredecessor() const { return Pred; }
+
+  const ExplodedGraph& getGraph() const { return *Eng.G; }
+
+  GRBlockCounter getBlockCounter() const { return Eng.WList->getBlockCounter();}
+
+  ExplodedNode* generateNode(const GRState* State, bool branch);
+
+  CFGBlock* getTargetBlock(bool branch) const {
+    return branch ? DstT : DstF;
+  }
+
+  void markInfeasible(bool branch) {
+    if (branch)
+      InFeasibleTrue = GeneratedTrue = true;
+    else
+      InFeasibleFalse = GeneratedFalse = true;
+  }
+
+  bool isFeasible(bool branch) {
+    return branch ? !InFeasibleTrue : !InFeasibleFalse;
+  }
+
+  const GRState* getState() const {
+    return getPredecessor()->getState();
+  }
+};
+
+class GRIndirectGotoNodeBuilder {
+  GRCoreEngine& Eng;
+  CFGBlock* Src;
+  CFGBlock& DispatchBlock;
+  Expr* E;
+  ExplodedNode* Pred;
+
+public:
+  GRIndirectGotoNodeBuilder(ExplodedNode* pred, CFGBlock* src, Expr* e,
+                            CFGBlock* dispatch, GRCoreEngine* eng)
+  : Eng(*eng), Src(src), DispatchBlock(*dispatch), E(e), Pred(pred) {}
+
+  class iterator {
+    CFGBlock::succ_iterator I;
+
+    friend class GRIndirectGotoNodeBuilder;
+    iterator(CFGBlock::succ_iterator i) : I(i) {}
+  public:
+
+    iterator& operator++() { ++I; return *this; }
+    bool operator!=(const iterator& X) const { return I != X.I; }
+
+    LabelStmt* getLabel() const {
+      return llvm::cast<LabelStmt>((*I)->getLabel());
+    }
+
+    CFGBlock*  getBlock() const {
+      return *I;
+    }
+  };
+
+  iterator begin() { return iterator(DispatchBlock.succ_begin()); }
+  iterator end() { return iterator(DispatchBlock.succ_end()); }
+
+  ExplodedNode* generateNode(const iterator& I, const GRState* State,
+                             bool isSink = false);
+
+  Expr* getTarget() const { return E; }
+
+  const GRState* getState() const { return Pred->State; }
+};
+
+class GRSwitchNodeBuilder {
+  GRCoreEngine& Eng;
+  CFGBlock* Src;
+  Expr* Condition;
+  ExplodedNode* Pred;
+
+public:
+  GRSwitchNodeBuilder(ExplodedNode* pred, CFGBlock* src,
+                      Expr* condition, GRCoreEngine* eng)
+  : Eng(*eng), Src(src), Condition(condition), Pred(pred) {}
+
+  class iterator {
+    CFGBlock::succ_reverse_iterator I;
+
+    friend class GRSwitchNodeBuilder;
+    iterator(CFGBlock::succ_reverse_iterator i) : I(i) {}
+
+  public:
+    iterator& operator++() { ++I; return *this; }
+    bool operator!=(const iterator& X) const { return I != X.I; }
+
+    CaseStmt* getCase() const {
+      return llvm::cast<CaseStmt>((*I)->getLabel());
+    }
+
+    CFGBlock* getBlock() const {
+      return *I;
+    }
+  };
+
+  iterator begin() { return iterator(Src->succ_rbegin()+1); }
+  iterator end() { return iterator(Src->succ_rend()); }
+
+  ExplodedNode* generateCaseStmtNode(const iterator& I, const GRState* State);
+
+  ExplodedNode* generateDefaultCaseNode(const GRState* State,
+                                        bool isSink = false);
+
+  Expr* getCondition() const { return Condition; }
+
+  const GRState* getState() const { return Pred->State; }
+};
+
+class GREndPathNodeBuilder {
+  GRCoreEngine &Eng;
+  CFGBlock& B;
+  ExplodedNode* Pred;
+
+public:
+  bool HasGeneratedNode;
+
+public:
+  GREndPathNodeBuilder(CFGBlock* b, ExplodedNode* N, GRCoreEngine* e)
+    : Eng(*e), B(*b), Pred(N), HasGeneratedNode(false) {}
+
+  ~GREndPathNodeBuilder();
+
+  GRWorkList &getWorkList() { return *Eng.WList; }
+
+  ExplodedNode* getPredecessor() const { return Pred; }
+
+  GRBlockCounter getBlockCounter() const {
+    return Eng.WList->getBlockCounter();
+  }
+
+  unsigned getCurrentBlockCount() const {
+    return getBlockCounter().getNumVisited(
+                            Pred->getLocationContext()->getCurrentStackFrame(),
+                                           B.getBlockID());
+  }
+
+  ExplodedNode* generateNode(const GRState* State, const void *tag = 0,
+                             ExplodedNode *P = 0);
+
+  void GenerateCallExitNode(const GRState *state);
+
+  CFGBlock* getBlock() const { return &B; }
+
+  const GRState* getState() const {
+    return getPredecessor()->getState();
+  }
+};
+
+class GRCallEnterNodeBuilder {
+  GRCoreEngine &Eng;
+
+  const ExplodedNode *Pred;
+
+  // The call site.
+  const Stmt *CE;
+
+  // The definition of callee.
+  const FunctionDecl *FD;
+
+  // The parent block of the CallExpr.
+  const CFGBlock *Block;
+
+  // The CFGBlock index of the CallExpr.
+  unsigned Index;
+
+public:
+  GRCallEnterNodeBuilder(GRCoreEngine &eng, const ExplodedNode *pred, 
+                         const Stmt *s, const FunctionDecl *fd, 
+                         const CFGBlock *blk, unsigned idx)
+    : Eng(eng), Pred(pred), CE(s), FD(fd), Block(blk), Index(idx) {}
+
+  const GRState *getState() const { return Pred->getState(); }
+
+  const LocationContext *getLocationContext() const { 
+    return Pred->getLocationContext();
+  }
+
+  const Stmt *getCallExpr() const { return CE; }
+
+  const FunctionDecl *getCallee() const { return FD; }
+
+  const CFGBlock *getBlock() const { return Block; }
+
+  unsigned getIndex() const { return Index; }
+
+  void GenerateNode(const GRState *state, const LocationContext *LocCtx);
+};
+
+class GRCallExitNodeBuilder {
+  GRCoreEngine &Eng;
+  const ExplodedNode *Pred;
+
+public:
+  GRCallExitNodeBuilder(GRCoreEngine &eng, const ExplodedNode *pred)
+    : Eng(eng), Pred(pred) {}
+
+  const ExplodedNode *getPredecessor() const { return Pred; }
+
+  const GRState *getState() const { return Pred->getState(); }
+
+  void GenerateNode(const GRState *state);
+}; 
+} // end clang namespace
+
+#endif
diff --git a/include/clang/Checker/PathSensitive/GRExprEngine.h b/include/clang/Checker/PathSensitive/GRExprEngine.h
new file mode 100644
index 0000000..85c2a69
--- /dev/null
+++ b/include/clang/Checker/PathSensitive/GRExprEngine.h
@@ -0,0 +1,459 @@
+//===-- GRExprEngine.h - Path-Sensitive Expression-Level Dataflow ---*- C++ -*-=
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines a meta-engine for path-sensitive dataflow analysis that
+//  is built on GRCoreEngine, but provides the boilerplate to execute transfer
+//  functions and build the ExplodedGraph at the expression level.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_GREXPRENGINE
+#define LLVM_CLANG_ANALYSIS_GREXPRENGINE
+
+#include "clang/Checker/PathSensitive/GRSubEngine.h"
+#include "clang/Checker/PathSensitive/GRCoreEngine.h"
+#include "clang/Checker/PathSensitive/GRState.h"
+#include "clang/Checker/PathSensitive/GRSimpleAPICheck.h"
+#include "clang/Checker/PathSensitive/GRTransferFuncs.h"
+#include "clang/Checker/BugReporter/BugReporter.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/ExprObjC.h"
+#include "clang/AST/ExprCXX.h"
+
+namespace clang {
+class AnalysisManager;
+class Checker;
+class ObjCForCollectionStmt;
+
+class GRExprEngine : public GRSubEngine {
+  AnalysisManager &AMgr;
+
+  GRCoreEngine CoreEngine;
+
+  /// G - the simulation graph.
+  ExplodedGraph& G;
+
+  /// Builder - The current GRStmtNodeBuilder which is used when building the
+  ///  nodes for a given statement.
+  GRStmtNodeBuilder* Builder;
+
+  /// StateMgr - Object that manages the data for all created states.
+  GRStateManager StateMgr;
+
+  /// SymMgr - Object that manages the symbol information.
+  SymbolManager& SymMgr;
+
+  /// ValMgr - Object that manages/creates SVals.
+  ValueManager &ValMgr;
+
+  /// SVator - SValuator object that creates SVals from expressions.
+  SValuator &SVator;
+
+  /// EntryNode - The immediate predecessor node.
+  ExplodedNode* EntryNode;
+
+  /// CleanedState - The state for EntryNode "cleaned" of all dead
+  ///  variables and symbols (as determined by a liveness analysis).
+  const GRState* CleanedState;
+
+  /// CurrentStmt - The current block-level statement.
+  Stmt* CurrentStmt;
+
+  // Obj-C Class Identifiers.
+  IdentifierInfo* NSExceptionII;
+
+  // Obj-C Selectors.
+  Selector* NSExceptionInstanceRaiseSelectors;
+  Selector RaiseSel;
+
+  llvm::OwningPtr<GRSimpleAPICheck> BatchAuditor;
+
+  typedef llvm::DenseMap<void *, unsigned> CheckerMap;
+  CheckerMap CheckerM;
+  
+  typedef std::vector<std::pair<void *, Checker*> > CheckersOrdered;
+  CheckersOrdered Checkers;
+
+  /// BR - The BugReporter associated with this engine.  It is important that
+  //   this object be placed at the very end of member variables so that its
+  //   destructor is called before the rest of the GRExprEngine is destroyed.
+  GRBugReporter BR;
+  
+  llvm::OwningPtr<GRTransferFuncs> TF;
+
+  class CallExprWLItem {
+  public:
+    CallExpr::arg_iterator I;
+    ExplodedNode *N;
+
+    CallExprWLItem(const CallExpr::arg_iterator &i, ExplodedNode *n)
+      : I(i), N(n) {}
+  };
+
+public:
+  GRExprEngine(AnalysisManager &mgr, GRTransferFuncs *tf);
+
+  ~GRExprEngine();
+
+  void ExecuteWorkList(const LocationContext *L, unsigned Steps = 150000) {
+    CoreEngine.ExecuteWorkList(L, Steps);
+  }
+
+  /// getContext - Return the ASTContext associated with this analysis.
+  ASTContext& getContext() const { return G.getContext(); }
+
+  AnalysisManager &getAnalysisManager() const { return AMgr; }
+
+  SValuator &getSValuator() { return SVator; }
+
+  GRTransferFuncs& getTF() { return *TF; }
+
+  BugReporter& getBugReporter() { return BR; }
+
+  GRStmtNodeBuilder &getBuilder() { assert(Builder); return *Builder; }
+
+  // FIXME: Remove once GRTransferFuncs is no longer referenced.
+  void setTransferFunction(GRTransferFuncs* tf);
+
+  /// ViewGraph - Visualize the ExplodedGraph created by executing the
+  ///  simulation.
+  void ViewGraph(bool trim = false);
+
+  void ViewGraph(ExplodedNode** Beg, ExplodedNode** End);
+
+  /// getInitialState - Return the initial state used for the root vertex
+  ///  in the ExplodedGraph.
+  const GRState* getInitialState(const LocationContext *InitLoc);
+
+  ExplodedGraph& getGraph() { return G; }
+  const ExplodedGraph& getGraph() const { return G; }
+
+  template <typename CHECKER>
+  void registerCheck(CHECKER *check) {
+    unsigned entry = Checkers.size();
+    void *tag = CHECKER::getTag();
+    Checkers.push_back(std::make_pair(tag, check));
+    CheckerM[tag] = entry;
+  }
+  
+  Checker *lookupChecker(void *tag) const;
+
+  template <typename CHECKER>
+  CHECKER *getChecker() const {
+     return static_cast<CHECKER*>(lookupChecker(CHECKER::getTag()));
+  }
+
+  void AddCheck(GRSimpleAPICheck* A, Stmt::StmtClass C);
+  void AddCheck(GRSimpleAPICheck* A);
+
+  /// ProcessStmt - Called by GRCoreEngine. Used to generate new successor
+  ///  nodes by processing the 'effects' of a block-level statement.
+  void ProcessStmt(CFGElement E, GRStmtNodeBuilder& builder);
+
+  /// ProcessBlockEntrance - Called by GRCoreEngine when start processing
+  ///  a CFGBlock.  This method returns true if the analysis should continue
+  ///  exploring the given path, and false otherwise.
+  bool ProcessBlockEntrance(CFGBlock* B, const ExplodedNode *Pred,
+                            GRBlockCounter BC);
+
+  /// ProcessBranch - Called by GRCoreEngine.  Used to generate successor
+  ///  nodes by processing the 'effects' of a branch condition.
+  void ProcessBranch(Stmt* Condition, Stmt* Term, GRBranchNodeBuilder& builder);
+
+  /// ProcessIndirectGoto - Called by GRCoreEngine.  Used to generate successor
+  ///  nodes by processing the 'effects' of a computed goto jump.
+  void ProcessIndirectGoto(GRIndirectGotoNodeBuilder& builder);
+
+  /// ProcessSwitch - Called by GRCoreEngine.  Used to generate successor
+  ///  nodes by processing the 'effects' of a switch statement.
+  void ProcessSwitch(GRSwitchNodeBuilder& builder);
+
+  /// ProcessEndPath - Called by GRCoreEngine.  Used to generate end-of-path
+  ///  nodes when the control reaches the end of a function.
+  void ProcessEndPath(GREndPathNodeBuilder& builder);
+
+  // Generate the entry node of the callee.
+  void ProcessCallEnter(GRCallEnterNodeBuilder &builder);
+
+  // Generate the first post callsite node.
+  void ProcessCallExit(GRCallExitNodeBuilder &builder);
+
+  /// EvalAssume - Callback function invoked by the ConstraintManager when
+  ///  making assumptions about state values.
+  const GRState *ProcessAssume(const GRState *state, SVal cond, bool assumption);
+
+  GRStateManager& getStateManager() { return StateMgr; }
+  const GRStateManager& getStateManager() const { return StateMgr; }
+
+  StoreManager& getStoreManager() { return StateMgr.getStoreManager(); }
+
+  ConstraintManager& getConstraintManager() {
+    return StateMgr.getConstraintManager();
+  }
+
+  // FIXME: Remove when we migrate over to just using ValueManager.
+  BasicValueFactory& getBasicVals() {
+    return StateMgr.getBasicVals();
+  }
+  const BasicValueFactory& getBasicVals() const {
+    return StateMgr.getBasicVals();
+  }
+
+  ValueManager &getValueManager() { return ValMgr; }
+  const ValueManager &getValueManager() const { return ValMgr; }
+
+  // FIXME: Remove when we migrate over to just using ValueManager.
+  SymbolManager& getSymbolManager() { return SymMgr; }
+  const SymbolManager& getSymbolManager() const { return SymMgr; }
+
+protected:
+  const GRState* GetState(ExplodedNode* N) {
+    return N == EntryNode ? CleanedState : N->getState();
+  }
+
+public:
+  ExplodedNode* MakeNode(ExplodedNodeSet& Dst, Stmt* S, ExplodedNode* Pred, 
+                         const GRState* St,
+                         ProgramPoint::Kind K = ProgramPoint::PostStmtKind,
+                         const void *tag = 0);
+
+  /// CheckerVisit - Dispatcher for performing checker-specific logic
+  ///  at specific statements.
+  void CheckerVisit(Stmt *S, ExplodedNodeSet &Dst, ExplodedNodeSet &Src, 
+                    bool isPrevisit);
+
+  bool CheckerEvalCall(const CallExpr *CE, 
+                       ExplodedNodeSet &Dst, 
+                       ExplodedNode *Pred);
+
+  void CheckerEvalNilReceiver(const ObjCMessageExpr *ME, 
+                              ExplodedNodeSet &Dst,
+                              const GRState *state,
+                              ExplodedNode *Pred);
+  
+  void CheckerVisitBind(const Stmt *AssignE, const Stmt *StoreE,
+                        ExplodedNodeSet &Dst, ExplodedNodeSet &Src, 
+                        SVal location, SVal val, bool isPrevisit);
+
+
+  /// Visit - Transfer function logic for all statements.  Dispatches to
+  ///  other functions that handle specific kinds of statements.
+  void Visit(Stmt* S, ExplodedNode* Pred, ExplodedNodeSet& Dst);
+
+  /// VisitLValue - Evaluate the lvalue of the expression. For example, if Ex is
+  /// a DeclRefExpr, it evaluates to the MemRegionVal which represents its
+  /// storage location. Note that not all kinds of expressions has lvalue.
+  void VisitLValue(Expr* Ex, ExplodedNode* Pred, ExplodedNodeSet& Dst);
+
+  /// VisitArraySubscriptExpr - Transfer function for array accesses.
+  void VisitArraySubscriptExpr(ArraySubscriptExpr* Ex, ExplodedNode* Pred,
+                               ExplodedNodeSet& Dst, bool asLValue);
+
+  /// VisitAsmStmt - Transfer function logic for inline asm.
+  void VisitAsmStmt(AsmStmt* A, ExplodedNode* Pred, ExplodedNodeSet& Dst);
+
+  void VisitAsmStmtHelperOutputs(AsmStmt* A,
+                                 AsmStmt::outputs_iterator I,
+                                 AsmStmt::outputs_iterator E,
+                                 ExplodedNode* Pred, ExplodedNodeSet& Dst);
+
+  void VisitAsmStmtHelperInputs(AsmStmt* A,
+                                AsmStmt::inputs_iterator I,
+                                AsmStmt::inputs_iterator E,
+                                ExplodedNode* Pred, ExplodedNodeSet& Dst);
+  
+  /// VisitBlockExpr - Transfer function logic for BlockExprs.
+  void VisitBlockExpr(BlockExpr *BE, ExplodedNode *Pred, ExplodedNodeSet &Dst);
+
+  /// VisitBinaryOperator - Transfer function logic for binary operators.
+  void VisitBinaryOperator(BinaryOperator* B, ExplodedNode* Pred, 
+                           ExplodedNodeSet& Dst, bool asLValue);
+
+
+  /// VisitCall - Transfer function for function calls.
+  void VisitCall(CallExpr* CE, ExplodedNode* Pred,
+                 CallExpr::arg_iterator AI, CallExpr::arg_iterator AE,
+                 ExplodedNodeSet& Dst, bool asLValue);
+
+  /// VisitCast - Transfer function logic for all casts (implicit and explicit).
+  void VisitCast(CastExpr *CastE, Expr *Ex, ExplodedNode *Pred,
+                 ExplodedNodeSet &Dst, bool asLValue);
+
+  /// VisitCompoundLiteralExpr - Transfer function logic for compound literals.
+  void VisitCompoundLiteralExpr(CompoundLiteralExpr* CL, ExplodedNode* Pred,
+                                ExplodedNodeSet& Dst, bool asLValue);
+
+  /// VisitDeclRefExpr - Transfer function logic for DeclRefExprs.
+  void VisitDeclRefExpr(DeclRefExpr* DR, ExplodedNode* Pred,
+                        ExplodedNodeSet& Dst, bool asLValue);
+
+  /// VisitBlockDeclRefExpr - Transfer function logic for BlockDeclRefExprs.
+  void VisitBlockDeclRefExpr(BlockDeclRefExpr* DR, ExplodedNode* Pred,
+                             ExplodedNodeSet& Dst, bool asLValue);
+  
+  void VisitCommonDeclRefExpr(Expr* DR, const NamedDecl *D,ExplodedNode* Pred,
+                             ExplodedNodeSet& Dst, bool asLValue);  
+  
+  /// VisitDeclStmt - Transfer function logic for DeclStmts.
+  void VisitDeclStmt(DeclStmt* DS, ExplodedNode* Pred, ExplodedNodeSet& Dst);
+
+  /// VisitGuardedExpr - Transfer function logic for ?, __builtin_choose
+  void VisitGuardedExpr(Expr* Ex, Expr* L, Expr* R, ExplodedNode* Pred,
+                        ExplodedNodeSet& Dst);
+
+  /// VisitCondInit - Transfer function for handling the initialization
+  ///  of a condition variable in an IfStmt, SwitchStmt, etc.
+  void VisitCondInit(VarDecl *VD, Stmt *S, ExplodedNode *Pred,
+                     ExplodedNodeSet& Dst);
+  
+  void VisitInitListExpr(InitListExpr* E, ExplodedNode* Pred,
+                         ExplodedNodeSet& Dst);
+
+  /// VisitLogicalExpr - Transfer function logic for '&&', '||'
+  void VisitLogicalExpr(BinaryOperator* B, ExplodedNode* Pred,
+                        ExplodedNodeSet& Dst);
+
+  /// VisitMemberExpr - Transfer function for member expressions.
+  void VisitMemberExpr(MemberExpr* M, ExplodedNode* Pred, ExplodedNodeSet& Dst,
+                       bool asLValue);
+
+  /// VisitObjCIvarRefExpr - Transfer function logic for ObjCIvarRefExprs.
+  void VisitObjCIvarRefExpr(ObjCIvarRefExpr* DR, ExplodedNode* Pred,
+                            ExplodedNodeSet& Dst, bool asLValue);
+
+  /// VisitObjCForCollectionStmt - Transfer function logic for
+  ///  ObjCForCollectionStmt.
+  void VisitObjCForCollectionStmt(ObjCForCollectionStmt* S, ExplodedNode* Pred,
+                                  ExplodedNodeSet& Dst);
+
+  void VisitObjCForCollectionStmtAux(ObjCForCollectionStmt* S, 
+                                     ExplodedNode* Pred,
+                                     ExplodedNodeSet& Dst, SVal ElementV);
+
+  /// VisitObjCMessageExpr - Transfer function for ObjC message expressions.
+  void VisitObjCMessageExpr(ObjCMessageExpr* ME, ExplodedNode* Pred, 
+                            ExplodedNodeSet& Dst, bool asLValue);
+
+  /// VisitReturnStmt - Transfer function logic for return statements.
+  void VisitReturnStmt(ReturnStmt* R, ExplodedNode* Pred, ExplodedNodeSet& Dst);
+
+  /// VisitSizeOfAlignOfExpr - Transfer function for sizeof.
+  void VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr* Ex, ExplodedNode* Pred,
+                              ExplodedNodeSet& Dst);
+
+  /// VisitUnaryOperator - Transfer function logic for unary operators.
+  void VisitUnaryOperator(UnaryOperator* B, ExplodedNode* Pred, 
+                          ExplodedNodeSet& Dst, bool asLValue);
+
+  void VisitCXXThisExpr(CXXThisExpr *TE, ExplodedNode *Pred, 
+                        ExplodedNodeSet & Dst);
+  
+  void VisitCXXConstructExpr(const CXXConstructExpr *E, SVal Dest,
+                             ExplodedNode *Pred,
+                             ExplodedNodeSet &Dst);
+
+  void VisitCXXMemberCallExpr(const CXXMemberCallExpr *MCE, ExplodedNode *Pred,
+                              ExplodedNodeSet &Dst);
+
+  void VisitCXXNewExpr(CXXNewExpr *CNE, ExplodedNode *Pred,
+                       ExplodedNodeSet &Dst);
+
+  void VisitCXXDeleteExpr(CXXDeleteExpr *CDE, ExplodedNode *Pred,
+                          ExplodedNodeSet &Dst);
+
+  void VisitAggExpr(const Expr *E, SVal Dest, ExplodedNode *Pred,
+                    ExplodedNodeSet &Dst);
+
+  /// Create a C++ temporary object for an rvalue.
+  void CreateCXXTemporaryObject(Expr *Ex, ExplodedNode *Pred, 
+                                ExplodedNodeSet &Dst);
+
+  /// Synthesize CXXThisRegion.
+  const CXXThisRegion *getCXXThisRegion(const CXXMethodDecl *MD,
+                                        const StackFrameContext *SFC);
+
+  /// Evaluate arguments with a work list algorithm.
+  void EvalArguments(ExprIterator AI, ExprIterator AE,
+                     const FunctionProtoType *FnType, 
+                     ExplodedNode *Pred, ExplodedNodeSet &Dst);
+
+  /// EvalEagerlyAssume - Given the nodes in 'Src', eagerly assume symbolic
+  ///  expressions of the form 'x != 0' and generate new nodes (stored in Dst)
+  ///  with those assumptions.
+  void EvalEagerlyAssume(ExplodedNodeSet& Dst, ExplodedNodeSet& Src, Expr *Ex);
+
+  SVal EvalMinus(SVal X) {
+    return X.isValid() ? SVator.EvalMinus(cast<NonLoc>(X)) : X;
+  }
+
+  SVal EvalComplement(SVal X) {
+    return X.isValid() ? SVator.EvalComplement(cast<NonLoc>(X)) : X;
+  }
+
+public:
+
+  SVal EvalBinOp(const GRState *state, BinaryOperator::Opcode op,
+                 NonLoc L, NonLoc R, QualType T) {
+    return SVator.EvalBinOpNN(state, op, L, R, T);
+  }
+
+  SVal EvalBinOp(const GRState *state, BinaryOperator::Opcode op,
+                 NonLoc L, SVal R, QualType T) {
+    return R.isValid() ? SVator.EvalBinOpNN(state,op,L, cast<NonLoc>(R), T) : R;
+  }
+
+  SVal EvalBinOp(const GRState *ST, BinaryOperator::Opcode Op,
+                 SVal LHS, SVal RHS, QualType T) {
+    return SVator.EvalBinOp(ST, Op, LHS, RHS, T);
+  }
+  
+protected:
+  void EvalObjCMessageExpr(ExplodedNodeSet& Dst, ObjCMessageExpr* ME, 
+                           ExplodedNode* Pred, const GRState *state) {
+    assert (Builder && "GRStmtNodeBuilder must be defined.");
+    getTF().EvalObjCMessageExpr(Dst, *this, *Builder, ME, Pred, state);
+  }
+
+  const GRState* MarkBranch(const GRState* St, Stmt* Terminator,
+                            bool branchTaken);
+
+  /// EvalBind - Handle the semantics of binding a value to a specific location.
+  ///  This method is used by EvalStore, VisitDeclStmt, and others.
+  void EvalBind(ExplodedNodeSet& Dst, Stmt *AssignE,
+                Stmt* StoreE, ExplodedNode* Pred,
+                const GRState* St, SVal location, SVal Val,
+                bool atDeclInit = false);
+
+public:
+  // FIXME: 'tag' should be removed, and a LocationContext should be used
+  // instead.
+  void EvalLoad(ExplodedNodeSet& Dst, Expr* Ex, ExplodedNode* Pred,
+                const GRState* St, SVal location, const void *tag = 0,
+                QualType LoadTy = QualType());
+
+  // FIXME: 'tag' should be removed, and a LocationContext should be used
+  // instead.
+  void EvalStore(ExplodedNodeSet& Dst, Expr* AssignE, Expr* StoreE,
+                 ExplodedNode* Pred, const GRState* St, SVal TargetLV, SVal Val,
+                 const void *tag = 0);
+private:  
+  void EvalLoadCommon(ExplodedNodeSet& Dst, Expr* Ex, ExplodedNode* Pred,
+                      const GRState* St, SVal location, const void *tag,
+                      QualType LoadTy);
+
+  // FIXME: 'tag' should be removed, and a LocationContext should be used
+  // instead.
+  void EvalLocation(ExplodedNodeSet &Dst, Stmt *S, ExplodedNode* Pred,
+                    const GRState* St, SVal location,
+                    const void *tag, bool isLoad);
+};
+
+} // end clang namespace
+
+#endif
diff --git a/include/clang/Checker/PathSensitive/GRExprEngineBuilders.h b/include/clang/Checker/PathSensitive/GRExprEngineBuilders.h
new file mode 100644
index 0000000..5503412
--- /dev/null
+++ b/include/clang/Checker/PathSensitive/GRExprEngineBuilders.h
@@ -0,0 +1,76 @@
+//===-- GRExprEngineBuilders.h - "Builder" classes for GRExprEngine -*- C++ -*-=
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines smart builder "references" which are used to marshal
+//  builders between GRExprEngine objects and their related components.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_GREXPRENGINE_BUILDERS
+#define LLVM_CLANG_ANALYSIS_GREXPRENGINE_BUILDERS
+#include "clang/Checker/PathSensitive/GRExprEngine.h"
+#include "clang/Analysis/Support/SaveAndRestore.h"
+
+namespace clang {
+
+class GRStmtNodeBuilderRef {
+  ExplodedNodeSet &Dst;
+  GRStmtNodeBuilder &B;
+  GRExprEngine& Eng;
+  ExplodedNode* Pred;
+  const GRState* state;
+  const Stmt* stmt;
+  const unsigned OldSize;
+  const bool AutoCreateNode;
+  SaveAndRestore<bool> OldSink;
+  SaveAndRestore<const void*> OldTag;
+  SaveOr OldHasGen;
+
+private:
+  friend class GRExprEngine;
+
+  GRStmtNodeBuilderRef(); // do not implement
+  void operator=(const GRStmtNodeBuilderRef&); // do not implement
+
+  GRStmtNodeBuilderRef(ExplodedNodeSet &dst,
+                       GRStmtNodeBuilder &builder,
+                       GRExprEngine& eng,
+                       ExplodedNode* pred,
+                       const GRState *st,
+                       const Stmt* s, bool auto_create_node)
+  : Dst(dst), B(builder), Eng(eng), Pred(pred),
+    state(st), stmt(s), OldSize(Dst.size()), AutoCreateNode(auto_create_node),
+    OldSink(B.BuildSinks), OldTag(B.Tag), OldHasGen(B.HasGeneratedNode) {}
+
+public:
+
+  ~GRStmtNodeBuilderRef() {
+    // Handle the case where no nodes where generated.  Auto-generate that
+    // contains the updated state if we aren't generating sinks.
+    if (!B.BuildSinks && Dst.size() == OldSize && !B.HasGeneratedNode) {
+      if (AutoCreateNode)
+        B.MakeNode(Dst, const_cast<Stmt*>(stmt), Pred, state);
+      else
+        Dst.Add(Pred);
+    }
+  }
+
+  const GRState *getState() { return state; }
+
+  GRStateManager& getStateManager() {
+    return Eng.getStateManager();
+  }
+
+  ExplodedNode* MakeNode(const GRState* state) {
+    return B.MakeNode(Dst, const_cast<Stmt*>(stmt), Pred, state);
+  }
+};
+
+} // end clang namespace
+#endif
diff --git a/include/clang/Checker/PathSensitive/GRSimpleAPICheck.h b/include/clang/Checker/PathSensitive/GRSimpleAPICheck.h
new file mode 100644
index 0000000..6d85e5f
--- /dev/null
+++ b/include/clang/Checker/PathSensitive/GRSimpleAPICheck.h
@@ -0,0 +1,31 @@
+// GRCheckAPI.h - Simple API checks based on GRAuditor ------------*- C++ -*--//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the interface for building simple, path-sensitive checks
+//  that are stateless and only emit warnings at errors that occur at
+//  CallExpr or ObjCMessageExpr.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_GRAPICHECKS
+#define LLVM_CLANG_ANALYSIS_GRAPICHECKS
+
+#include "clang/Checker/PathSensitive/GRAuditor.h"
+
+namespace clang {
+
+class GRSimpleAPICheck : public GRAuditor {
+public:
+  GRSimpleAPICheck() {}
+  virtual ~GRSimpleAPICheck() {}
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Checker/PathSensitive/GRState.h b/include/clang/Checker/PathSensitive/GRState.h
new file mode 100644
index 0000000..25ba1f8
--- /dev/null
+++ b/include/clang/Checker/PathSensitive/GRState.h
@@ -0,0 +1,750 @@
+//== GRState*h - Path-Sens. "State" for tracking valuues -----*- C++ -*--==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines SymbolRef, ExprBindKey, and GRState*
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_VALUESTATE_H
+#define LLVM_CLANG_ANALYSIS_VALUESTATE_H
+
+#include "clang/Checker/PathSensitive/ConstraintManager.h"
+#include "clang/Checker/PathSensitive/Environment.h"
+#include "clang/Checker/PathSensitive/Store.h"
+#include "clang/Checker/PathSensitive/ValueManager.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/ImmutableMap.h"
+#include "llvm/Support/Casting.h"
+
+namespace llvm {
+class APSInt;
+class BumpPtrAllocator;
+class raw_ostream;
+}
+
+namespace clang {
+class ASTContext;
+class GRStateManager;
+class Checker;
+
+typedef ConstraintManager* (*ConstraintManagerCreator)(GRStateManager&,
+                                                       GRSubEngine&);
+typedef StoreManager* (*StoreManagerCreator)(GRStateManager&);
+
+//===----------------------------------------------------------------------===//
+// GRStateTrait - Traits used by the Generic Data Map of a GRState.
+//===----------------------------------------------------------------------===//
+
+template <typename T> struct GRStatePartialTrait;
+
+template <typename T> struct GRStateTrait {
+  typedef typename T::data_type data_type;
+  static inline void* GDMIndex() { return &T::TagInt; }
+  static inline void* MakeVoidPtr(data_type D) { return (void*) D; }
+  static inline data_type MakeData(void* const* P) {
+    return P ? (data_type) *P : (data_type) 0;
+  }
+};
+
+//===----------------------------------------------------------------------===//
+// GRState- An ImmutableMap type Stmt*/Decl*/Symbols to SVals.
+//===----------------------------------------------------------------------===//
+
+class GRStateManager;
+
+/// GRState - This class encapsulates the actual data values for
+///  for a "state" in our symbolic value tracking.  It is intended to be
+///  used as a functional object; that is once it is created and made
+///  "persistent" in a FoldingSet its values will never change.
+class GRState : public llvm::FoldingSetNode {
+public:
+  typedef llvm::ImmutableSet<llvm::APSInt*>                IntSetTy;
+  typedef llvm::ImmutableMap<void*, void*>                 GenericDataMap;
+
+private:
+  void operator=(const GRState& R) const; // Do not implement.
+
+  friend class GRStateManager;
+
+  GRStateManager *StateMgr;
+  Environment Env;
+  Store St;
+  GenericDataMap   GDM;
+
+public:
+
+  /// This ctor is used when creating the first GRState object.
+  GRState(GRStateManager *mgr, const Environment& env,
+          Store st, GenericDataMap gdm)
+    : StateMgr(mgr),
+      Env(env),
+      St(st),
+      GDM(gdm) {}
+
+  /// Copy ctor - We must explicitly define this or else the "Next" ptr
+  ///  in FoldingSetNode will also get copied.
+  GRState(const GRState& RHS)
+    : llvm::FoldingSetNode(),
+      StateMgr(RHS.StateMgr),
+      Env(RHS.Env),
+      St(RHS.St),
+      GDM(RHS.GDM) {}
+
+  /// getStateManager - Return the GRStateManager associated with this state.
+  GRStateManager &getStateManager() const {
+    return *StateMgr;
+  }
+
+  /// getEnvironment - Return the environment associated with this state.
+  ///  The environment is the mapping from expressions to values.
+  const Environment& getEnvironment() const { return Env; }
+
+  /// getStore - Return the store associated with this state.  The store
+  ///  is a mapping from locations to values.
+  Store getStore() const { return St; }
+
+  void setStore(Store s) { St = s; }
+
+  /// getGDM - Return the generic data map associated with this state.
+  GenericDataMap getGDM() const { return GDM; }
+
+  void setGDM(GenericDataMap gdm) { GDM = gdm; }
+
+  /// Profile - Profile the contents of a GRState object for use
+  ///  in a FoldingSet.
+  static void Profile(llvm::FoldingSetNodeID& ID, const GRState* V) {
+    V->Env.Profile(ID);
+    ID.AddPointer(V->St);
+    V->GDM.Profile(ID);
+  }
+
+  /// Profile - Used to profile the contents of this object for inclusion
+  ///  in a FoldingSet.
+  void Profile(llvm::FoldingSetNodeID& ID) const {
+    Profile(ID, this);
+  }
+
+  SVal LookupExpr(Expr* E) const {
+    return Env.LookupExpr(E);
+  }
+
+  /// makeWithStore - Return a GRState with the same values as the current
+  /// state with the exception of using the specified Store.
+  const GRState *makeWithStore(Store store) const;
+
+  BasicValueFactory &getBasicVals() const;
+  SymbolManager &getSymbolManager() const;
+
+  //==---------------------------------------------------------------------==//
+  // Constraints on values.
+  //==---------------------------------------------------------------------==//
+  //
+  // Each GRState records constraints on symbolic values.  These constraints
+  // are managed using the ConstraintManager associated with a GRStateManager.
+  // As constraints gradually accrue on symbolic values, added constraints
+  // may conflict and indicate that a state is infeasible (as no real values
+  // could satisfy all the constraints).  This is the principal mechanism
+  // for modeling path-sensitivity in GRExprEngine/GRState.
+  //
+  // Various "Assume" methods form the interface for adding constraints to
+  // symbolic values.  A call to "Assume" indicates an assumption being placed
+  // on one or symbolic values.  Assume methods take the following inputs:
+  //
+  //  (1) A GRState object representing the current state.
+  //
+  //  (2) The assumed constraint (which is specific to a given "Assume" method).
+  //
+  //  (3) A binary value "Assumption" that indicates whether the constraint is
+  //      assumed to be true or false.
+  //
+  // The output of "Assume" are two values:
+  //
+  //  (a) "isFeasible" is set to true or false to indicate whether or not
+  //      the assumption is feasible.
+  //
+  //  (b) A new GRState object with the added constraints.
+  //
+  // FIXME: (a) should probably disappear since it is redundant with (b).
+  //  (i.e., (b) could just be set to NULL).
+  //
+
+  const GRState *Assume(DefinedOrUnknownSVal cond, bool assumption) const;
+  
+  std::pair<const GRState*, const GRState*>
+  Assume(DefinedOrUnknownSVal cond) const;
+
+  const GRState *AssumeInBound(DefinedOrUnknownSVal idx,
+                               DefinedOrUnknownSVal upperBound,
+                               bool assumption) const;
+
+  //==---------------------------------------------------------------------==//
+  // Utility methods for getting regions.
+  //==---------------------------------------------------------------------==//
+
+  const VarRegion* getRegion(const VarDecl *D, const LocationContext *LC) const;
+
+  //==---------------------------------------------------------------------==//
+  // Binding and retrieving values to/from the environment and symbolic store.
+  //==---------------------------------------------------------------------==//
+
+  /// BindCompoundLiteral - Return the state that has the bindings currently
+  ///  in 'state' plus the bindings for the CompoundLiteral.  'R' is the region
+  ///  for the compound literal and 'BegInit' and 'EndInit' represent an
+  ///  array of initializer values.
+  const GRState *bindCompoundLiteral(const CompoundLiteralExpr* CL,
+                                     const LocationContext *LC,
+                                     SVal V) const;
+
+  const GRState *BindExpr(const Stmt *S, SVal V, bool Invalidate = true) const;
+
+  const GRState *bindDecl(const VarRegion *VR, SVal V) const;
+
+  const GRState *bindDeclWithNoInit(const VarRegion *VR) const;
+
+  const GRState *bindLoc(Loc location, SVal V) const;
+
+  const GRState *bindLoc(SVal location, SVal V) const;
+
+  const GRState *unbindLoc(Loc LV) const;
+
+  /// Get the lvalue for a variable reference.
+  SVal getLValue(const VarDecl *D, const LocationContext *LC) const;
+
+  /// Get the lvalue for a StringLiteral.
+  SVal getLValue(const StringLiteral *literal) const;
+
+  SVal getLValue(const CompoundLiteralExpr *literal,
+                 const LocationContext *LC) const;
+
+  /// Get the lvalue for an ivar reference.
+  SVal getLValue(const ObjCIvarDecl *decl, SVal base) const;
+
+  /// Get the lvalue for a field reference.
+  SVal getLValue(const FieldDecl *decl, SVal Base) const;
+
+  /// Get the lvalue for an array index.
+  SVal getLValue(QualType ElementType, SVal Idx, SVal Base) const;
+
+  const llvm::APSInt *getSymVal(SymbolRef sym) const;
+
+  SVal getSVal(const Stmt* Ex) const;
+
+  SVal getSValAsScalarOrLoc(const Stmt *Ex) const;
+
+  SVal getSVal(Loc LV, QualType T = QualType()) const;
+
+  SVal getSVal(const MemRegion* R) const;
+
+  SVal getSValAsScalarOrLoc(const MemRegion *R) const;
+  
+  const llvm::APSInt *getSymVal(SymbolRef sym);
+
+  bool scanReachableSymbols(SVal val, SymbolVisitor& visitor) const;
+  
+  bool scanReachableSymbols(const SVal *I, const SVal *E,
+                            SymbolVisitor &visitor) const;
+  
+  bool scanReachableSymbols(const MemRegion * const *I, 
+                            const MemRegion * const *E,
+                            SymbolVisitor &visitor) const;
+
+  template <typename CB> CB scanReachableSymbols(SVal val) const;
+  template <typename CB> CB scanReachableSymbols(const SVal *beg,
+                                                 const SVal *end) const;
+  
+  template <typename CB> CB
+  scanReachableSymbols(const MemRegion * const *beg,
+                       const MemRegion * const *end) const;
+
+  //==---------------------------------------------------------------------==//
+  // Accessing the Generic Data Map (GDM).
+  //==---------------------------------------------------------------------==//
+
+  void* const* FindGDM(void* K) const;
+
+  template<typename T>
+  const GRState *add(typename GRStateTrait<T>::key_type K) const;
+
+  template <typename T>
+  typename GRStateTrait<T>::data_type
+  get() const {
+    return GRStateTrait<T>::MakeData(FindGDM(GRStateTrait<T>::GDMIndex()));
+  }
+
+  template<typename T>
+  typename GRStateTrait<T>::lookup_type
+  get(typename GRStateTrait<T>::key_type key) const {
+    void* const* d = FindGDM(GRStateTrait<T>::GDMIndex());
+    return GRStateTrait<T>::Lookup(GRStateTrait<T>::MakeData(d), key);
+  }
+
+  template <typename T>
+  typename GRStateTrait<T>::context_type get_context() const;
+
+
+  template<typename T>
+  const GRState *remove(typename GRStateTrait<T>::key_type K) const;
+
+  template<typename T>
+  const GRState *remove(typename GRStateTrait<T>::key_type K,
+                        typename GRStateTrait<T>::context_type C) const;
+  template <typename T>
+  const GRState *remove() const;
+
+  template<typename T>
+  const GRState *set(typename GRStateTrait<T>::data_type D) const;
+
+  template<typename T>
+  const GRState *set(typename GRStateTrait<T>::key_type K,
+                     typename GRStateTrait<T>::value_type E) const;
+
+  template<typename T>
+  const GRState *set(typename GRStateTrait<T>::key_type K,
+                     typename GRStateTrait<T>::value_type E,
+                     typename GRStateTrait<T>::context_type C) const;
+
+  template<typename T>
+  bool contains(typename GRStateTrait<T>::key_type key) const {
+    void* const* d = FindGDM(GRStateTrait<T>::GDMIndex());
+    return GRStateTrait<T>::Contains(GRStateTrait<T>::MakeData(d), key);
+  }
+
+  // State pretty-printing.
+  class Printer {
+  public:
+    virtual ~Printer() {}
+    virtual void Print(llvm::raw_ostream& Out, const GRState* state,
+                       const char* nl, const char* sep) = 0;
+  };
+
+  // Pretty-printing.
+  void print(llvm::raw_ostream& Out, CFG &C, const char *nl = "\n",
+             const char *sep = "") const;
+
+  void printStdErr(CFG &C) const;
+
+  void printDOT(llvm::raw_ostream& Out, CFG &C) const;
+};
+
+class GRStateSet {
+  typedef llvm::SmallPtrSet<const GRState*,5> ImplTy;
+  ImplTy Impl;
+public:
+  GRStateSet() {}
+
+  inline void Add(const GRState* St) {
+    Impl.insert(St);
+  }
+
+  typedef ImplTy::const_iterator iterator;
+
+  inline unsigned size() const { return Impl.size();  }
+  inline bool empty()    const { return Impl.empty(); }
+
+  inline iterator begin() const { return Impl.begin(); }
+  inline iterator end() const { return Impl.end();   }
+
+  class AutoPopulate {
+    GRStateSet& S;
+    unsigned StartSize;
+    const GRState* St;
+  public:
+    AutoPopulate(GRStateSet& s, const GRState* st)
+      : S(s), StartSize(S.size()), St(st) {}
+
+    ~AutoPopulate() {
+      if (StartSize == S.size())
+        S.Add(St);
+    }
+  };
+};
+
+//===----------------------------------------------------------------------===//
+// GRStateManager - Factory object for GRStates.
+//===----------------------------------------------------------------------===//
+
+class GRStateManager {
+  friend class GRState;
+  friend class GRExprEngine; // FIXME: Remove.
+private:
+  EnvironmentManager                   EnvMgr;
+  llvm::OwningPtr<StoreManager>        StoreMgr;
+  llvm::OwningPtr<ConstraintManager>   ConstraintMgr;
+
+  GRState::GenericDataMap::Factory     GDMFactory;
+
+  typedef llvm::DenseMap<void*,std::pair<void*,void (*)(void*)> > GDMContextsTy;
+  GDMContextsTy GDMContexts;
+
+  /// Printers - A set of printer objects used for pretty-printing a GRState.
+  ///  GRStateManager owns these objects.
+  std::vector<GRState::Printer*> Printers;
+
+  /// StateSet - FoldingSet containing all the states created for analyzing
+  ///  a particular function.  This is used to unique states.
+  llvm::FoldingSet<GRState> StateSet;
+
+  /// ValueMgr - Object that manages the data for all created SVals.
+  ValueManager ValueMgr;
+
+  /// Alloc - A BumpPtrAllocator to allocate states.
+  llvm::BumpPtrAllocator &Alloc;
+
+public:
+  GRStateManager(ASTContext& Ctx,
+                 StoreManagerCreator CreateStoreManager,
+                 ConstraintManagerCreator CreateConstraintManager,
+                 llvm::BumpPtrAllocator& alloc,
+                 GRSubEngine &subeng)
+    : EnvMgr(alloc),
+      GDMFactory(alloc),
+      ValueMgr(alloc, Ctx, *this),
+      Alloc(alloc) {
+    StoreMgr.reset((*CreateStoreManager)(*this));
+    ConstraintMgr.reset((*CreateConstraintManager)(*this, subeng));
+  }
+
+  ~GRStateManager();
+
+  const GRState *getInitialState(const LocationContext *InitLoc);
+
+  ASTContext &getContext() { return ValueMgr.getContext(); }
+  const ASTContext &getContext() const { return ValueMgr.getContext(); }
+
+  BasicValueFactory &getBasicVals() {
+    return ValueMgr.getBasicValueFactory();
+  }
+  const BasicValueFactory& getBasicVals() const {
+    return ValueMgr.getBasicValueFactory();
+  }
+
+  SymbolManager &getSymbolManager() {
+    return ValueMgr.getSymbolManager();
+  }
+  const SymbolManager &getSymbolManager() const {
+    return ValueMgr.getSymbolManager();
+  }
+
+  ValueManager &getValueManager() { return ValueMgr; }
+  const ValueManager &getValueManager() const { return ValueMgr; }
+
+  llvm::BumpPtrAllocator& getAllocator() { return Alloc; }
+
+  MemRegionManager& getRegionManager() {
+    return ValueMgr.getRegionManager();
+  }
+  const MemRegionManager& getRegionManager() const {
+    return ValueMgr.getRegionManager();
+  }
+
+  StoreManager& getStoreManager() { return *StoreMgr; }
+  ConstraintManager& getConstraintManager() { return *ConstraintMgr; }
+
+  const GRState* RemoveDeadBindings(const GRState* St, Stmt* Loc,
+                                    const StackFrameContext *LCtx,
+                                    SymbolReaper& SymReaper);
+
+public:
+
+  SVal ArrayToPointer(Loc Array) {
+    return StoreMgr->ArrayToPointer(Array);
+  }
+
+  // Methods that manipulate the GDM.
+  const GRState* addGDM(const GRState* St, void* Key, void* Data);
+  const GRState *removeGDM(const GRState *state, void *Key);
+
+  // Methods that query & manipulate the Store.
+
+  void iterBindings(const GRState* state, StoreManager::BindingsHandler& F) {
+    StoreMgr->iterBindings(state->getStore(), F);
+  }
+
+  const GRState* getPersistentState(GRState& Impl);
+
+  bool isEqual(const GRState* state, const Expr* Ex, const llvm::APSInt& V);
+  bool isEqual(const GRState* state, const Expr* Ex, uint64_t);
+
+  //==---------------------------------------------------------------------==//
+  // Generic Data Map methods.
+  //==---------------------------------------------------------------------==//
+  //
+  // GRStateManager and GRState support a "generic data map" that allows
+  // different clients of GRState objects to embed arbitrary data within a
+  // GRState object.  The generic data map is essentially an immutable map
+  // from a "tag" (that acts as the "key" for a client) and opaque values.
+  // Tags/keys and values are simply void* values.  The typical way that clients
+  // generate unique tags are by taking the address of a static variable.
+  // Clients are responsible for ensuring that data values referred to by a
+  // the data pointer are immutable (and thus are essentially purely functional
+  // data).
+  //
+  // The templated methods below use the GRStateTrait<T> class
+  // to resolve keys into the GDM and to return data values to clients.
+  //
+
+  // Trait based GDM dispatch.
+  template <typename T>
+  const GRState* set(const GRState* st, typename GRStateTrait<T>::data_type D) {
+    return addGDM(st, GRStateTrait<T>::GDMIndex(),
+                  GRStateTrait<T>::MakeVoidPtr(D));
+  }
+
+  template<typename T>
+  const GRState* set(const GRState* st,
+                     typename GRStateTrait<T>::key_type K,
+                     typename GRStateTrait<T>::value_type V,
+                     typename GRStateTrait<T>::context_type C) {
+
+    return addGDM(st, GRStateTrait<T>::GDMIndex(),
+     GRStateTrait<T>::MakeVoidPtr(GRStateTrait<T>::Set(st->get<T>(), K, V, C)));
+  }
+
+  template <typename T>
+  const GRState* add(const GRState* st,
+                     typename GRStateTrait<T>::key_type K,
+                     typename GRStateTrait<T>::context_type C) {
+    return addGDM(st, GRStateTrait<T>::GDMIndex(),
+        GRStateTrait<T>::MakeVoidPtr(GRStateTrait<T>::Add(st->get<T>(), K, C)));
+  }
+
+  template <typename T>
+  const GRState* remove(const GRState* st,
+                        typename GRStateTrait<T>::key_type K,
+                        typename GRStateTrait<T>::context_type C) {
+
+    return addGDM(st, GRStateTrait<T>::GDMIndex(),
+     GRStateTrait<T>::MakeVoidPtr(GRStateTrait<T>::Remove(st->get<T>(), K, C)));
+  }
+
+  template <typename T>
+  const GRState *remove(const GRState *st) {
+    return removeGDM(st, GRStateTrait<T>::GDMIndex());
+  }
+
+  void* FindGDMContext(void* index,
+                       void* (*CreateContext)(llvm::BumpPtrAllocator&),
+                       void  (*DeleteContext)(void*));
+
+  template <typename T>
+  typename GRStateTrait<T>::context_type get_context() {
+    void* p = FindGDMContext(GRStateTrait<T>::GDMIndex(),
+                             GRStateTrait<T>::CreateContext,
+                             GRStateTrait<T>::DeleteContext);
+
+    return GRStateTrait<T>::MakeContext(p);
+  }
+
+  const llvm::APSInt* getSymVal(const GRState* St, SymbolRef sym) {
+    return ConstraintMgr->getSymVal(St, sym);
+  }
+
+  void EndPath(const GRState* St) {
+    ConstraintMgr->EndPath(St);
+  }
+};
+
+
+//===----------------------------------------------------------------------===//
+// Out-of-line method definitions for GRState.
+//===----------------------------------------------------------------------===//
+
+inline const llvm::APSInt *GRState::getSymVal(SymbolRef sym) {
+  return getStateManager().getSymVal(this, sym);
+}
+  
+inline const VarRegion* GRState::getRegion(const VarDecl *D,
+                                           const LocationContext *LC) const {
+  return getStateManager().getRegionManager().getVarRegion(D, LC);
+}
+
+inline const GRState *GRState::Assume(DefinedOrUnknownSVal Cond,
+                                      bool Assumption) const {
+  if (Cond.isUnknown())
+    return this;
+  
+  return getStateManager().ConstraintMgr->Assume(this, cast<DefinedSVal>(Cond),
+                                                 Assumption);
+}
+  
+inline std::pair<const GRState*, const GRState*>
+GRState::Assume(DefinedOrUnknownSVal Cond) const {
+  if (Cond.isUnknown())
+    return std::make_pair(this, this);
+  
+  return getStateManager().ConstraintMgr->AssumeDual(this,
+                                                     cast<DefinedSVal>(Cond));
+}
+
+inline const GRState *GRState::AssumeInBound(DefinedOrUnknownSVal Idx,
+                                             DefinedOrUnknownSVal UpperBound,
+                                             bool Assumption) const {
+  if (Idx.isUnknown() || UpperBound.isUnknown())
+    return this;
+
+  ConstraintManager &CM = *getStateManager().ConstraintMgr;
+  return CM.AssumeInBound(this, cast<DefinedSVal>(Idx),
+                           cast<DefinedSVal>(UpperBound), Assumption);
+}
+
+inline const GRState *
+GRState::bindCompoundLiteral(const CompoundLiteralExpr* CL,
+                             const LocationContext *LC, SVal V) const {
+  Store new_store = 
+    getStateManager().StoreMgr->BindCompoundLiteral(St, CL, LC, V);
+  return makeWithStore(new_store);
+}
+
+inline const GRState *GRState::bindDecl(const VarRegion* VR, SVal IVal) const {
+  Store new_store = getStateManager().StoreMgr->BindDecl(St, VR, IVal);
+  return makeWithStore(new_store);
+}
+
+inline const GRState *GRState::bindDeclWithNoInit(const VarRegion* VR) const {
+  Store new_store = getStateManager().StoreMgr->BindDeclWithNoInit(St, VR);
+  return makeWithStore(new_store);
+}
+
+inline const GRState *GRState::bindLoc(Loc LV, SVal V) const {
+  Store new_store = getStateManager().StoreMgr->Bind(St, LV, V);
+  return makeWithStore(new_store);
+}
+
+inline const GRState *GRState::bindLoc(SVal LV, SVal V) const {
+  return !isa<Loc>(LV) ? this : bindLoc(cast<Loc>(LV), V);
+}
+
+inline SVal GRState::getLValue(const VarDecl* VD,
+                               const LocationContext *LC) const {
+  return getStateManager().StoreMgr->getLValueVar(VD, LC);
+}
+
+inline SVal GRState::getLValue(const StringLiteral *literal) const {
+  return getStateManager().StoreMgr->getLValueString(literal);
+}
+
+inline SVal GRState::getLValue(const CompoundLiteralExpr *literal,
+                               const LocationContext *LC) const {
+  return getStateManager().StoreMgr->getLValueCompoundLiteral(literal, LC);
+}
+
+inline SVal GRState::getLValue(const ObjCIvarDecl *D, SVal Base) const {
+  return getStateManager().StoreMgr->getLValueIvar(D, Base);
+}
+
+inline SVal GRState::getLValue(const FieldDecl* D, SVal Base) const {
+  return getStateManager().StoreMgr->getLValueField(D, Base);
+}
+
+inline SVal GRState::getLValue(QualType ElementType, SVal Idx, SVal Base) const{
+  return getStateManager().StoreMgr->getLValueElement(ElementType, Idx, Base);
+}
+
+inline const llvm::APSInt *GRState::getSymVal(SymbolRef sym) const {
+  return getStateManager().getSymVal(this, sym);
+}
+
+inline SVal GRState::getSVal(const Stmt* Ex) const {
+  return Env.GetSVal(Ex, getStateManager().ValueMgr);
+}
+
+inline SVal GRState::getSValAsScalarOrLoc(const Stmt *S) const {
+  if (const Expr *Ex = dyn_cast<Expr>(S)) {
+    QualType T = Ex->getType();
+    if (Loc::IsLocType(T) || T->isIntegerType())
+      return getSVal(S);
+  }
+
+  return UnknownVal();
+}
+
+inline SVal GRState::getSVal(Loc LV, QualType T) const {
+  return getStateManager().StoreMgr->Retrieve(St, LV, T);
+}
+
+inline SVal GRState::getSVal(const MemRegion* R) const {
+  return getStateManager().StoreMgr->Retrieve(St, loc::MemRegionVal(R));
+}
+
+inline BasicValueFactory &GRState::getBasicVals() const {
+  return getStateManager().getBasicVals();
+}
+
+inline SymbolManager &GRState::getSymbolManager() const {
+  return getStateManager().getSymbolManager();
+}
+
+template<typename T>
+const GRState *GRState::add(typename GRStateTrait<T>::key_type K) const {
+  return getStateManager().add<T>(this, K, get_context<T>());
+}
+
+template <typename T>
+typename GRStateTrait<T>::context_type GRState::get_context() const {
+  return getStateManager().get_context<T>();
+}
+
+template<typename T>
+const GRState *GRState::remove(typename GRStateTrait<T>::key_type K) const {
+  return getStateManager().remove<T>(this, K, get_context<T>());
+}
+
+template<typename T>
+const GRState *GRState::remove(typename GRStateTrait<T>::key_type K,
+                               typename GRStateTrait<T>::context_type C) const {
+  return getStateManager().remove<T>(this, K, C);
+}
+
+template <typename T>
+const GRState *GRState::remove() const {
+  return getStateManager().remove<T>(this);
+}
+
+template<typename T>
+const GRState *GRState::set(typename GRStateTrait<T>::data_type D) const {
+  return getStateManager().set<T>(this, D);
+}
+
+template<typename T>
+const GRState *GRState::set(typename GRStateTrait<T>::key_type K,
+                            typename GRStateTrait<T>::value_type E) const {
+  return getStateManager().set<T>(this, K, E, get_context<T>());
+}
+
+template<typename T>
+const GRState *GRState::set(typename GRStateTrait<T>::key_type K,
+                            typename GRStateTrait<T>::value_type E,
+                            typename GRStateTrait<T>::context_type C) const {
+  return getStateManager().set<T>(this, K, E, C);
+}
+
+template <typename CB>
+CB GRState::scanReachableSymbols(SVal val) const {
+  CB cb(this);
+  scanReachableSymbols(val, cb);
+  return cb;
+}
+  
+template <typename CB>
+CB GRState::scanReachableSymbols(const SVal *beg, const SVal *end) const {
+  CB cb(this);
+  scanReachableSymbols(beg, end, cb);
+  return cb;
+}
+
+template <typename CB>
+CB GRState::scanReachableSymbols(const MemRegion * const *beg,
+                                 const MemRegion * const *end) const {
+  CB cb(this);
+  scanReachableSymbols(beg, end, cb);
+  return cb;
+}
+} // end clang namespace
+
+#endif
diff --git a/include/clang/Checker/PathSensitive/GRStateTrait.h b/include/clang/Checker/PathSensitive/GRStateTrait.h
new file mode 100644
index 0000000..5189a1f
--- /dev/null
+++ b/include/clang/Checker/PathSensitive/GRStateTrait.h
@@ -0,0 +1,148 @@
+//==- GRStateTrait.h - Partial implementations of GRStateTrait -----*- C++ -*-//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines partial implementations of template specializations of
+//  the class GRStateTrait<>.  GRStateTrait<> is used by GRState to implement
+//  set/get methods for mapulating a GRState's generic data map.
+//
+//===----------------------------------------------------------------------===//
+
+
+#ifndef LLVM_CLANG_ANALYSIS_GRSTATETRAIT_H
+#define LLVM_CLANG_ANALYSIS_GRSTATETRAIT_H
+
+namespace llvm {
+  class BumpPtrAllocator;
+  template <typename K, typename D, typename I> class ImmutableMap;
+  template <typename K, typename I> class ImmutableSet;
+  template <typename T> class ImmutableList;
+  template <typename T> class ImmutableListImpl;
+}
+
+namespace clang {
+  template <typename T> struct GRStatePartialTrait;
+
+  // Partial-specialization for ImmutableMap.
+
+  template <typename Key, typename Data, typename Info>
+  struct GRStatePartialTrait< llvm::ImmutableMap<Key,Data,Info> > {
+    typedef llvm::ImmutableMap<Key,Data,Info> data_type;
+    typedef typename data_type::Factory&      context_type;
+    typedef Key                               key_type;
+    typedef Data                              value_type;
+    typedef const value_type*                 lookup_type;
+
+    static inline data_type MakeData(void* const* p) {
+      return p ? data_type((typename data_type::TreeTy*) *p) : data_type(0);
+    }
+    static inline void* MakeVoidPtr(data_type B) {
+      return B.getRoot();
+    }
+    static lookup_type Lookup(data_type B, key_type K) {
+      return B.lookup(K);
+    }
+    static data_type Set(data_type B, key_type K, value_type E,context_type F){
+      return F.Add(B, K, E);
+    }
+
+    static data_type Remove(data_type B, key_type K, context_type F) {
+      return F.Remove(B, K);
+    }
+
+    static inline context_type MakeContext(void* p) {
+      return *((typename data_type::Factory*) p);
+    }
+
+    static void* CreateContext(llvm::BumpPtrAllocator& Alloc) {
+      return new typename data_type::Factory(Alloc);
+    }
+
+    static void DeleteContext(void* Ctx) {
+      delete (typename data_type::Factory*) Ctx;
+    }
+  };
+
+
+  // Partial-specialization for ImmutableSet.
+
+  template <typename Key, typename Info>
+  struct GRStatePartialTrait< llvm::ImmutableSet<Key,Info> > {
+    typedef llvm::ImmutableSet<Key,Info>      data_type;
+    typedef typename data_type::Factory&      context_type;
+    typedef Key                               key_type;
+
+    static inline data_type MakeData(void* const* p) {
+      return p ? data_type((typename data_type::TreeTy*) *p) : data_type(0);
+    }
+
+    static inline void* MakeVoidPtr(data_type B) {
+      return B.getRoot();
+    }
+
+    static data_type Add(data_type B, key_type K, context_type F) {
+      return F.Add(B, K);
+    }
+
+    static data_type Remove(data_type B, key_type K, context_type F) {
+      return F.Remove(B, K);
+    }
+
+    static bool Contains(data_type B, key_type K) {
+      return B.contains(K);
+    }
+
+    static inline context_type MakeContext(void* p) {
+      return *((typename data_type::Factory*) p);
+    }
+
+    static void* CreateContext(llvm::BumpPtrAllocator& Alloc) {
+      return new typename data_type::Factory(Alloc);
+    }
+
+    static void DeleteContext(void* Ctx) {
+      delete (typename data_type::Factory*) Ctx;
+    }
+  };
+
+  // Partial-specialization for ImmutableList.
+
+  template <typename T>
+  struct GRStatePartialTrait< llvm::ImmutableList<T> > {
+    typedef llvm::ImmutableList<T>            data_type;
+    typedef T                                 key_type;
+    typedef typename data_type::Factory&      context_type;
+
+    static data_type Add(data_type L, key_type K, context_type F) {
+      return F.Add(K, L);
+    }
+
+    static inline data_type MakeData(void* const* p) {
+      return p ? data_type((const llvm::ImmutableListImpl<T>*) *p)
+               : data_type(0);
+    }
+
+    static inline void* MakeVoidPtr(data_type D) {
+      return  (void*) D.getInternalPointer();
+    }
+
+    static inline context_type MakeContext(void* p) {
+      return *((typename data_type::Factory*) p);
+    }
+
+    static void* CreateContext(llvm::BumpPtrAllocator& Alloc) {
+      return new typename data_type::Factory(Alloc);
+    }
+
+    static void DeleteContext(void* Ctx) {
+      delete (typename data_type::Factory*) Ctx;
+    }
+  };
+} // end clang namespace
+
+#endif
diff --git a/include/clang/Checker/PathSensitive/GRSubEngine.h b/include/clang/Checker/PathSensitive/GRSubEngine.h
new file mode 100644
index 0000000..d2e7457
--- /dev/null
+++ b/include/clang/Checker/PathSensitive/GRSubEngine.h
@@ -0,0 +1,84 @@
+//== GRSubEngine.h - Interface of the subengine of GRCoreEngine ----*- C++ -*-//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the interface of a subengine of the GRCoreEngine.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_ANALYSIS_GRSUBENGINE_H
+#define LLVM_CLANG_ANALYSIS_GRSUBENGINE_H
+
+#include "clang/Checker/PathSensitive/SVals.h"
+
+namespace clang {
+
+class Stmt;
+class CFGBlock;
+class CFGElement;
+class ExplodedNode;
+class GRState;
+class GRStateManager;
+class GRBlockCounter;
+class GRStmtNodeBuilder;
+class GRBranchNodeBuilder;
+class GRIndirectGotoNodeBuilder;
+class GRSwitchNodeBuilder;
+class GREndPathNodeBuilder;
+class GRCallEnterNodeBuilder;
+class GRCallExitNodeBuilder;
+class LocationContext;
+
+class GRSubEngine {
+public:
+  virtual ~GRSubEngine() {}
+
+  virtual const GRState* getInitialState(const LocationContext *InitLoc) = 0;
+
+  virtual GRStateManager& getStateManager() = 0;
+
+  /// ProcessStmt - Called by GRCoreEngine. Used to generate new successor
+  ///  nodes by processing the 'effects' of a block-level statement.
+  virtual void ProcessStmt(CFGElement E, GRStmtNodeBuilder& builder) = 0;
+
+  /// ProcessBlockEntrance - Called by GRCoreEngine when start processing
+  ///  a CFGBlock.  This method returns true if the analysis should continue
+  ///  exploring the given path, and false otherwise.
+  virtual bool ProcessBlockEntrance(CFGBlock* B, const ExplodedNode *Pred,
+                                    GRBlockCounter BC) = 0;
+
+  /// ProcessBranch - Called by GRCoreEngine.  Used to generate successor
+  ///  nodes by processing the 'effects' of a branch condition.
+  virtual void ProcessBranch(Stmt* Condition, Stmt* Term,
+                             GRBranchNodeBuilder& builder) = 0;
+
+  /// ProcessIndirectGoto - Called by GRCoreEngine.  Used to generate successor
+  ///  nodes by processing the 'effects' of a computed goto jump.
+  virtual void ProcessIndirectGoto(GRIndirectGotoNodeBuilder& builder) = 0;
+
+  /// ProcessSwitch - Called by GRCoreEngine.  Used to generate successor
+  ///  nodes by processing the 'effects' of a switch statement.
+  virtual void ProcessSwitch(GRSwitchNodeBuilder& builder) = 0;
+
+  /// ProcessEndPath - Called by GRCoreEngine.  Used to generate end-of-path
+  ///  nodes when the control reaches the end of a function.
+  virtual void ProcessEndPath(GREndPathNodeBuilder& builder) = 0;
+
+  // Generate the entry node of the callee.
+  virtual void ProcessCallEnter(GRCallEnterNodeBuilder &builder) = 0;
+
+  // Generate the first post callsite node.
+  virtual void ProcessCallExit(GRCallExitNodeBuilder &builder) = 0;
+  
+  /// EvalAssume - Called by ConstraintManager. Used to call checker-specific
+  ///  logic for handling assumptions on symbolic values.
+  virtual const GRState* ProcessAssume(const GRState *state,
+                                       SVal cond, bool assumption) = 0;
+};
+}
+
+#endif
diff --git a/include/clang/Checker/PathSensitive/GRTransferFuncs.h b/include/clang/Checker/PathSensitive/GRTransferFuncs.h
new file mode 100644
index 0000000..13325ed
--- /dev/null
+++ b/include/clang/Checker/PathSensitive/GRTransferFuncs.h
@@ -0,0 +1,87 @@
+//== GRTransferFuncs.h - Path-Sens. Transfer Functions Interface -*- C++ -*--=//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines GRTransferFuncs, which provides a base-class that
+//  defines an interface for transfer functions used by GRExprEngine.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_GRTF
+#define LLVM_CLANG_ANALYSIS_GRTF
+
+#include "clang/Checker/PathSensitive/GRState.h"
+#include "clang/Checker/PathSensitive/SVals.h"
+#include <vector>
+
+namespace clang {
+class ExplodedNode;
+class ExplodedNodeSet;
+class GREndPathNodeBuilder;
+class GRExprEngine;
+class GRStmtNodeBuilder;
+class GRStmtNodeBuilderRef;
+class ObjCMessageExpr;
+
+class GRTransferFuncs {
+public:
+  GRTransferFuncs() {}
+  virtual ~GRTransferFuncs() {}
+
+  virtual void RegisterPrinters(std::vector<GRState::Printer*>& Printers) {}
+  virtual void RegisterChecks(GRExprEngine& Eng) {}
+
+
+  // Calls.
+
+  virtual void EvalCall(ExplodedNodeSet& Dst,
+                        GRExprEngine& Engine,
+                        GRStmtNodeBuilder& Builder,
+                        CallExpr* CE, SVal L,
+                        ExplodedNode* Pred) {}
+
+  virtual void EvalObjCMessageExpr(ExplodedNodeSet& Dst,
+                                   GRExprEngine& Engine,
+                                   GRStmtNodeBuilder& Builder,
+                                   ObjCMessageExpr* ME,
+                                   ExplodedNode* Pred,
+                                   const GRState *state) {}
+
+  // Stores.
+
+  virtual void EvalBind(GRStmtNodeBuilderRef& B, SVal location, SVal val) {}
+
+  // End-of-path and dead symbol notification.
+
+  virtual void EvalEndPath(GRExprEngine& Engine,
+                           GREndPathNodeBuilder& Builder) {}
+
+
+  virtual void EvalDeadSymbols(ExplodedNodeSet& Dst,
+                               GRExprEngine& Engine,
+                               GRStmtNodeBuilder& Builder,
+                               ExplodedNode* Pred,
+                               Stmt* S, const GRState* state,
+                               SymbolReaper& SymReaper) {}
+
+  // Return statements.
+  virtual void EvalReturn(ExplodedNodeSet& Dst,
+                          GRExprEngine& Engine,
+                          GRStmtNodeBuilder& Builder,
+                          ReturnStmt* S,
+                          ExplodedNode* Pred) {}
+
+  // Assumptions.
+  virtual const GRState* EvalAssume(const GRState *state,
+                                    SVal Cond, bool Assumption) {
+    return state;
+  }  
+};
+} // end clang namespace
+
+#endif
diff --git a/include/clang/Checker/PathSensitive/GRWorkList.h b/include/clang/Checker/PathSensitive/GRWorkList.h
new file mode 100644
index 0000000..b8f90fa
--- /dev/null
+++ b/include/clang/Checker/PathSensitive/GRWorkList.h
@@ -0,0 +1,79 @@
+//==- GRWorkList.h - Worklist class used by GRCoreEngine -----------*- C++ -*-//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines GRWorkList, a pure virtual class that represents an opaque
+//  worklist used by GRCoreEngine to explore the reachability state space.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_GRWORKLIST
+#define LLVM_CLANG_ANALYSIS_GRWORKLIST
+
+#include "clang/Checker/PathSensitive/GRBlockCounter.h"
+#include <cstddef>
+
+namespace clang {
+  
+class CFGBlock;
+class ExplodedNode;
+class ExplodedNodeImpl;
+
+class GRWorkListUnit {
+  ExplodedNode* Node;
+  GRBlockCounter Counter;
+  CFGBlock* Block;
+  unsigned BlockIdx; // This is the index of the next statement.
+
+public:
+  GRWorkListUnit(ExplodedNode* N, GRBlockCounter C,
+                 CFGBlock* B, unsigned idx)
+  : Node(N),
+    Counter(C),
+    Block(B),
+    BlockIdx(idx) {}
+
+  explicit GRWorkListUnit(ExplodedNode* N, GRBlockCounter C)
+  : Node(N),
+    Counter(C),
+    Block(NULL),
+    BlockIdx(0) {}
+
+  ExplodedNode* getNode()         const { return Node; }
+  GRBlockCounter    getBlockCounter() const { return Counter; }
+  CFGBlock*         getBlock()        const { return Block; }
+  unsigned          getIndex()        const { return BlockIdx; }
+};
+
+class GRWorkList {
+  GRBlockCounter CurrentCounter;
+public:
+  virtual ~GRWorkList();
+  virtual bool hasWork() const = 0;
+
+  virtual void Enqueue(const GRWorkListUnit& U) = 0;
+
+  void Enqueue(ExplodedNode* N, CFGBlock& B, unsigned idx) {
+    Enqueue(GRWorkListUnit(N, CurrentCounter, &B, idx));
+  }
+
+  void Enqueue(ExplodedNode* N) {
+    Enqueue(GRWorkListUnit(N, CurrentCounter));
+  }
+
+  virtual GRWorkListUnit Dequeue() = 0;
+
+  void setBlockCounter(GRBlockCounter C) { CurrentCounter = C; }
+  GRBlockCounter getBlockCounter() const { return CurrentCounter; }
+
+  static GRWorkList *MakeDFS();
+  static GRWorkList *MakeBFS();
+  static GRWorkList *MakeBFSBlockDFSContents();
+};
+} // end clang namespace
+#endif
diff --git a/include/clang/Checker/PathSensitive/MemRegion.h b/include/clang/Checker/PathSensitive/MemRegion.h
new file mode 100644
index 0000000..2ab3b42
--- /dev/null
+++ b/include/clang/Checker/PathSensitive/MemRegion.h
@@ -0,0 +1,967 @@
+//== MemRegion.h - Abstract memory regions for static analysis --*- C++ -*--==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines MemRegion and its subclasses.  MemRegion defines a
+//  partially-typed abstraction of memory useful for path-sensitive dataflow
+//  analyses.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_MEMREGION_H
+#define LLVM_CLANG_ANALYSIS_MEMREGION_H
+
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/Checker/PathSensitive/SVals.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/ADT/FoldingSet.h"
+#include <string>
+
+namespace llvm {
+class BumpPtrAllocator;
+class raw_ostream;
+}
+
+namespace clang {
+
+class MemRegionManager;
+class MemSpaceRegion;
+class LocationContext;
+class StackFrameContext;
+class VarRegion;
+
+//===----------------------------------------------------------------------===//
+// Base region classes.
+//===----------------------------------------------------------------------===//
+
+/// MemRegion - The root abstract class for all memory regions.
+class MemRegion : public llvm::FoldingSetNode {
+  friend class MemRegionManager;
+public:
+  enum Kind {
+    // Memory spaces.
+    BEG_MEMSPACES,
+    GenericMemSpaceRegionKind = BEG_MEMSPACES,
+    StackLocalsSpaceRegionKind,
+    StackArgumentsSpaceRegionKind,
+    HeapSpaceRegionKind,
+    UnknownSpaceRegionKind,
+    GlobalsSpaceRegionKind,
+    END_MEMSPACES = GlobalsSpaceRegionKind,
+    // Untyped regions.
+    SymbolicRegionKind,
+    AllocaRegionKind,
+    // Typed regions.
+    BEG_TYPED_REGIONS,
+    FunctionTextRegionKind = BEG_TYPED_REGIONS,
+    BlockTextRegionKind,
+    BlockDataRegionKind,
+    CompoundLiteralRegionKind,
+    CXXThisRegionKind,
+    StringRegionKind,
+    ElementRegionKind,
+    // Decl Regions.
+    BEG_DECL_REGIONS,
+    VarRegionKind = BEG_DECL_REGIONS,
+    FieldRegionKind,
+    ObjCIvarRegionKind,
+    CXXObjectRegionKind,
+    END_DECL_REGIONS = CXXObjectRegionKind,
+    END_TYPED_REGIONS = END_DECL_REGIONS
+  };
+    
+private:
+  const Kind kind;
+
+protected:
+  MemRegion(Kind k) : kind(k) {}
+  virtual ~MemRegion();
+
+public:
+  ASTContext &getContext() const;
+
+  virtual void Profile(llvm::FoldingSetNodeID& ID) const = 0;
+
+  virtual MemRegionManager* getMemRegionManager() const = 0;
+
+  std::string getString() const;
+
+  const MemSpaceRegion *getMemorySpace() const;
+
+  const MemRegion *getBaseRegion() const;
+
+  const MemRegion *StripCasts() const;
+
+  bool hasGlobalsOrParametersStorage() const;
+
+  bool hasStackStorage() const;
+  
+  bool hasStackNonParametersStorage() const;
+  
+  bool hasStackParametersStorage() const;
+
+  virtual void dumpToStream(llvm::raw_ostream& os) const;
+
+  void dump() const;
+
+  Kind getKind() const { return kind; }
+
+  template<typename RegionTy> const RegionTy* getAs() const;
+
+  virtual bool isBoundable() const { return false; }
+
+  static bool classof(const MemRegion*) { return true; }
+};
+
+/// MemSpaceRegion - A memory region that represents and "memory space";
+///  for example, the set of global variables, the stack frame, etc.
+class MemSpaceRegion : public MemRegion {
+protected:
+  friend class MemRegionManager;
+  
+  MemRegionManager *Mgr;
+
+  MemSpaceRegion(MemRegionManager *mgr, Kind k = GenericMemSpaceRegionKind)
+    : MemRegion(k), Mgr(mgr) {
+    assert(classof(this));
+  }
+
+  MemRegionManager* getMemRegionManager() const { return Mgr; }
+
+public:
+  bool isBoundable() const { return false; }
+  
+  void Profile(llvm::FoldingSetNodeID &ID) const;
+
+  static bool classof(const MemRegion *R) {
+    Kind k = R->getKind();
+    return k >= BEG_MEMSPACES && k <= END_MEMSPACES;
+  }
+};
+  
+class GlobalsSpaceRegion : public MemSpaceRegion {
+  friend class MemRegionManager;
+
+  GlobalsSpaceRegion(MemRegionManager *mgr)
+    : MemSpaceRegion(mgr, GlobalsSpaceRegionKind) {}
+public:
+  static bool classof(const MemRegion *R) {
+    return R->getKind() == GlobalsSpaceRegionKind;
+  }
+};
+  
+class HeapSpaceRegion : public MemSpaceRegion {
+  friend class MemRegionManager;
+  
+  HeapSpaceRegion(MemRegionManager *mgr)
+    : MemSpaceRegion(mgr, HeapSpaceRegionKind) {}
+public:
+  static bool classof(const MemRegion *R) {
+    return R->getKind() == HeapSpaceRegionKind;
+  }
+};
+  
+class UnknownSpaceRegion : public MemSpaceRegion {
+  friend class MemRegionManager;
+  UnknownSpaceRegion(MemRegionManager *mgr)
+    : MemSpaceRegion(mgr, UnknownSpaceRegionKind) {}
+public:
+  static bool classof(const MemRegion *R) {
+    return R->getKind() == UnknownSpaceRegionKind;
+  }
+};
+  
+class StackSpaceRegion : public MemSpaceRegion {
+private:
+  const StackFrameContext *SFC;
+
+protected:
+  StackSpaceRegion(MemRegionManager *mgr, Kind k, const StackFrameContext *sfc)
+    : MemSpaceRegion(mgr, k), SFC(sfc) {
+    assert(classof(this));
+  }
+
+public:  
+  const StackFrameContext *getStackFrame() const { return SFC; }
+  
+  void Profile(llvm::FoldingSetNodeID &ID) const;
+
+  static bool classof(const MemRegion *R) {
+    Kind k = R->getKind();
+    return k >= StackLocalsSpaceRegionKind &&
+           k <= StackArgumentsSpaceRegionKind;
+  }  
+};
+  
+class StackLocalsSpaceRegion : public StackSpaceRegion {
+private:
+  friend class MemRegionManager;
+  StackLocalsSpaceRegion(MemRegionManager *mgr, const StackFrameContext *sfc)
+    : StackSpaceRegion(mgr, StackLocalsSpaceRegionKind, sfc) {}
+public:
+  static bool classof(const MemRegion *R) {
+    return R->getKind() == StackLocalsSpaceRegionKind;
+  }
+};
+
+class StackArgumentsSpaceRegion : public StackSpaceRegion {
+private:
+  friend class MemRegionManager;
+  StackArgumentsSpaceRegion(MemRegionManager *mgr, const StackFrameContext *sfc)
+    : StackSpaceRegion(mgr, StackArgumentsSpaceRegionKind, sfc) {}
+public:
+  static bool classof(const MemRegion *R) {
+    return R->getKind() == StackArgumentsSpaceRegionKind;
+  }
+};
+
+/// SubRegion - A region that subsets another larger region.  Most regions
+///  are subclasses of SubRegion.
+class SubRegion : public MemRegion {
+protected:
+  const MemRegion* superRegion;
+  SubRegion(const MemRegion* sReg, Kind k) : MemRegion(k), superRegion(sReg) {}
+public:
+  const MemRegion* getSuperRegion() const {
+    return superRegion;
+  }
+
+  MemRegionManager* getMemRegionManager() const;
+
+  bool isSubRegionOf(const MemRegion* R) const;
+
+  static bool classof(const MemRegion* R) {
+    return R->getKind() > END_MEMSPACES;
+  }
+};
+
+//===----------------------------------------------------------------------===//
+// Auxillary data classes for use with MemRegions.
+//===----------------------------------------------------------------------===//
+
+class ElementRegion;
+
+class RegionRawOffset {
+private:
+  friend class ElementRegion;
+
+  const MemRegion *Region;
+  int64_t Offset;
+
+  RegionRawOffset(const MemRegion* reg, int64_t offset = 0)
+    : Region(reg), Offset(offset) {}
+
+public:
+  // FIXME: Eventually support symbolic offsets.
+  int64_t getByteOffset() const { return Offset; }
+  const MemRegion *getRegion() const { return Region; }
+
+  void dumpToStream(llvm::raw_ostream& os) const;
+  void dump() const;
+};
+
+//===----------------------------------------------------------------------===//
+// MemRegion subclasses.
+//===----------------------------------------------------------------------===//
+
+/// AllocaRegion - A region that represents an untyped blob of bytes created
+///  by a call to 'alloca'.
+class AllocaRegion : public SubRegion {
+  friend class MemRegionManager;
+protected:
+  unsigned Cnt; // Block counter.  Used to distinguish different pieces of
+                // memory allocated by alloca at the same call site.
+  const Expr* Ex;
+
+  AllocaRegion(const Expr* ex, unsigned cnt, const MemRegion *superRegion)
+    : SubRegion(superRegion, AllocaRegionKind), Cnt(cnt), Ex(ex) {}
+
+public:
+
+  const Expr* getExpr() const { return Ex; }
+
+  bool isBoundable() const { return true; }
+
+  void Profile(llvm::FoldingSetNodeID& ID) const;
+
+  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Expr* Ex,
+                            unsigned Cnt, const MemRegion *superRegion);
+
+  void dumpToStream(llvm::raw_ostream& os) const;
+
+  static bool classof(const MemRegion* R) {
+    return R->getKind() == AllocaRegionKind;
+  }
+};
+
+/// TypedRegion - An abstract class representing regions that are typed.
+class TypedRegion : public SubRegion {
+protected:
+  TypedRegion(const MemRegion* sReg, Kind k) : SubRegion(sReg, k) {}
+
+public:
+  virtual QualType getValueType(ASTContext &C) const = 0;
+
+  virtual QualType getLocationType(ASTContext& C) const {
+    // FIXME: We can possibly optimize this later to cache this value.
+    return C.getPointerType(getValueType(C));
+  }
+
+  QualType getDesugaredValueType(ASTContext& C) const {
+    QualType T = getValueType(C);
+    return T.getTypePtr() ? T.getDesugaredType() : T;
+  }
+
+  QualType getDesugaredLocationType(ASTContext& C) const {
+    return getLocationType(C).getDesugaredType();
+  }
+
+  bool isBoundable() const {
+    return !getValueType(getContext()).isNull();
+  }
+
+  static bool classof(const MemRegion* R) {
+    unsigned k = R->getKind();
+    return k >= BEG_TYPED_REGIONS && k <= END_TYPED_REGIONS;
+  }
+};
+
+
+class CodeTextRegion : public TypedRegion {
+protected:
+  CodeTextRegion(const MemRegion *sreg, Kind k) : TypedRegion(sreg, k) {}
+public:
+  QualType getValueType(ASTContext &C) const {
+    // Do not get the object type of a CodeTextRegion.
+    assert(0);
+    return QualType();
+  }
+  
+  bool isBoundable() const { return false; }
+    
+  static bool classof(const MemRegion* R) {
+    Kind k = R->getKind();
+    return k >= FunctionTextRegionKind && k <= BlockTextRegionKind;
+  }
+};
+
+/// FunctionTextRegion - A region that represents code texts of function.
+class FunctionTextRegion : public CodeTextRegion {
+  const FunctionDecl *FD;
+public:
+  FunctionTextRegion(const FunctionDecl* fd, const MemRegion* sreg)
+    : CodeTextRegion(sreg, FunctionTextRegionKind), FD(fd) {}
+  
+  QualType getLocationType(ASTContext &C) const {
+    return C.getPointerType(FD->getType());
+  }
+  
+  const FunctionDecl *getDecl() const {
+    return FD;
+  }
+    
+  virtual void dumpToStream(llvm::raw_ostream& os) const;
+  
+  void Profile(llvm::FoldingSetNodeID& ID) const;
+  
+  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const FunctionDecl *FD,
+                            const MemRegion*);
+  
+  static bool classof(const MemRegion* R) {
+    return R->getKind() == FunctionTextRegionKind;
+  }
+};
+  
+  
+/// BlockTextRegion - A region that represents code texts of blocks (closures).
+///  Blocks are represented with two kinds of regions.  BlockTextRegions
+///  represent the "code", while BlockDataRegions represent instances of blocks,
+///  which correspond to "code+data".  The distinction is important, because
+///  like a closure a block captures the values of externally referenced
+///  variables.
+class BlockTextRegion : public CodeTextRegion {
+  friend class MemRegionManager;
+
+  const BlockDecl *BD;
+  AnalysisContext *AC;
+  CanQualType locTy;
+
+  BlockTextRegion(const BlockDecl *bd, CanQualType lTy,
+                  AnalysisContext *ac, const MemRegion* sreg)
+    : CodeTextRegion(sreg, BlockTextRegionKind), BD(bd), AC(ac), locTy(lTy) {}
+
+public:
+  QualType getLocationType(ASTContext &C) const {
+    return locTy;
+  }
+  
+  const BlockDecl *getDecl() const {
+    return BD;
+  }
+
+  AnalysisContext *getAnalysisContext() const { return AC; }
+    
+  virtual void dumpToStream(llvm::raw_ostream& os) const;
+  
+  void Profile(llvm::FoldingSetNodeID& ID) const;
+  
+  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const BlockDecl *BD,
+                            CanQualType, const AnalysisContext*,
+                            const MemRegion*);
+  
+  static bool classof(const MemRegion* R) {
+    return R->getKind() == BlockTextRegionKind;
+  }
+};
+  
+/// BlockDataRegion - A region that represents a block instance.
+///  Blocks are represented with two kinds of regions.  BlockTextRegions
+///  represent the "code", while BlockDataRegions represent instances of blocks,
+///  which correspond to "code+data".  The distinction is important, because
+///  like a closure a block captures the values of externally referenced
+///  variables.
+class BlockDataRegion : public SubRegion {
+  friend class MemRegionManager;
+  const BlockTextRegion *BC;
+  const LocationContext *LC; // Can be null */
+  void *ReferencedVars;
+
+  BlockDataRegion(const BlockTextRegion *bc, const LocationContext *lc,
+                  const MemRegion *sreg)
+  : SubRegion(sreg, BlockDataRegionKind), BC(bc), LC(lc), ReferencedVars(0) {}
+
+public:  
+  const BlockTextRegion *getCodeRegion() const { return BC; }
+  
+  const BlockDecl *getDecl() const { return BC->getDecl(); }
+  
+  class referenced_vars_iterator {
+    const MemRegion * const *R;
+  public:
+    explicit referenced_vars_iterator(const MemRegion * const *r) : R(r) {}
+    
+    operator const MemRegion * const *() const {
+      return R;
+    }
+    
+    const VarRegion* operator*() const {
+      return cast<VarRegion>(*R);
+    }
+    
+    bool operator==(const referenced_vars_iterator &I) const {
+      return I.R == R;
+    }
+    bool operator!=(const referenced_vars_iterator &I) const {
+      return I.R != R;
+    }
+    referenced_vars_iterator& operator++() {
+      ++R;
+      return *this;
+    }
+  };
+      
+  referenced_vars_iterator referenced_vars_begin() const;
+  referenced_vars_iterator referenced_vars_end() const;  
+    
+  virtual void dumpToStream(llvm::raw_ostream& os) const;
+    
+  void Profile(llvm::FoldingSetNodeID& ID) const;
+    
+  static void ProfileRegion(llvm::FoldingSetNodeID&, const BlockTextRegion *,
+                            const LocationContext *, const MemRegion *);
+    
+  static bool classof(const MemRegion* R) {
+    return R->getKind() == BlockDataRegionKind;
+  }
+private:
+  void LazyInitializeReferencedVars();
+};
+
+/// SymbolicRegion - A special, "non-concrete" region. Unlike other region
+///  clases, SymbolicRegion represents a region that serves as an alias for
+///  either a real region, a NULL pointer, etc.  It essentially is used to
+///  map the concept of symbolic values into the domain of regions.  Symbolic
+///  regions do not need to be typed.
+class SymbolicRegion : public SubRegion {
+protected:
+  const SymbolRef sym;
+
+public:
+  SymbolicRegion(const SymbolRef s, const MemRegion* sreg)
+    : SubRegion(sreg, SymbolicRegionKind), sym(s) {}
+
+  SymbolRef getSymbol() const {
+    return sym;
+  }
+
+  bool isBoundable() const { return true; }
+
+  void Profile(llvm::FoldingSetNodeID& ID) const;
+
+  static void ProfileRegion(llvm::FoldingSetNodeID& ID,
+                            SymbolRef sym,
+                            const MemRegion* superRegion);
+
+  void dumpToStream(llvm::raw_ostream& os) const;
+
+  static bool classof(const MemRegion* R) {
+    return R->getKind() == SymbolicRegionKind;
+  }
+};
+
+/// StringRegion - Region associated with a StringLiteral.
+class StringRegion : public TypedRegion {
+  friend class MemRegionManager;
+  const StringLiteral* Str;
+protected:
+
+  StringRegion(const StringLiteral* str, const MemRegion* sreg)
+    : TypedRegion(sreg, StringRegionKind), Str(str) {}
+
+  static void ProfileRegion(llvm::FoldingSetNodeID& ID,
+                            const StringLiteral* Str,
+                            const MemRegion* superRegion);
+
+public:
+
+  const StringLiteral* getStringLiteral() const { return Str; }
+
+  QualType getValueType(ASTContext& C) const {
+    return Str->getType();
+  }
+
+  bool isBoundable() const { return false; }
+
+  void Profile(llvm::FoldingSetNodeID& ID) const {
+    ProfileRegion(ID, Str, superRegion);
+  }
+
+  void dumpToStream(llvm::raw_ostream& os) const;
+
+  static bool classof(const MemRegion* R) {
+    return R->getKind() == StringRegionKind;
+  }
+};
+
+/// CompoundLiteralRegion - A memory region representing a compound literal.
+///   Compound literals are essentially temporaries that are stack allocated
+///   or in the global constant pool.
+class CompoundLiteralRegion : public TypedRegion {
+private:
+  friend class MemRegionManager;
+  const CompoundLiteralExpr* CL;
+
+  CompoundLiteralRegion(const CompoundLiteralExpr* cl, const MemRegion* sReg)
+    : TypedRegion(sReg, CompoundLiteralRegionKind), CL(cl) {}
+
+  static void ProfileRegion(llvm::FoldingSetNodeID& ID,
+                            const CompoundLiteralExpr* CL,
+                            const MemRegion* superRegion);
+public:
+  QualType getValueType(ASTContext& C) const {
+    return C.getCanonicalType(CL->getType());
+  }
+
+  bool isBoundable() const { return !CL->isFileScope(); }
+
+  void Profile(llvm::FoldingSetNodeID& ID) const;
+
+  void dumpToStream(llvm::raw_ostream& os) const;
+
+  const CompoundLiteralExpr* getLiteralExpr() const { return CL; }
+
+  static bool classof(const MemRegion* R) {
+    return R->getKind() == CompoundLiteralRegionKind;
+  }
+};
+
+class DeclRegion : public TypedRegion {
+protected:
+  const Decl* D;
+
+  DeclRegion(const Decl* d, const MemRegion* sReg, Kind k)
+    : TypedRegion(sReg, k), D(d) {}
+
+  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl* D,
+                      const MemRegion* superRegion, Kind k);
+
+public:
+  const Decl* getDecl() const { return D; }
+  void Profile(llvm::FoldingSetNodeID& ID) const;
+
+  static bool classof(const MemRegion* R) {
+    unsigned k = R->getKind();
+    return k >= BEG_DECL_REGIONS && k <= END_DECL_REGIONS;
+  }
+};
+
+class VarRegion : public DeclRegion {
+  friend class MemRegionManager;
+
+  // Constructors and private methods.
+  VarRegion(const VarDecl* vd, const MemRegion* sReg)
+    : DeclRegion(vd, sReg, VarRegionKind) {}
+
+  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const VarDecl* VD,
+                            const MemRegion *superRegion) {
+    DeclRegion::ProfileRegion(ID, VD, superRegion, VarRegionKind);
+  }
+
+  void Profile(llvm::FoldingSetNodeID& ID) const;
+
+public:
+  const VarDecl *getDecl() const { return cast<VarDecl>(D); }
+
+  const StackFrameContext *getStackFrame() const;
+  
+  QualType getValueType(ASTContext& C) const {
+    // FIXME: We can cache this if needed.
+    return C.getCanonicalType(getDecl()->getType());
+  }
+
+  void dumpToStream(llvm::raw_ostream& os) const;
+
+  static bool classof(const MemRegion* R) {
+    return R->getKind() == VarRegionKind;
+  }
+};
+  
+/// CXXThisRegion - Represents the region for the implicit 'this' parameter
+///  in a call to a C++ method.  This region doesn't represent the object
+///  referred to by 'this', but rather 'this' itself.
+class CXXThisRegion : public TypedRegion {
+  friend class MemRegionManager;
+  CXXThisRegion(const PointerType *thisPointerTy,
+                const MemRegion *sReg)
+    : TypedRegion(sReg, CXXThisRegionKind), ThisPointerTy(thisPointerTy) {}
+
+  static void ProfileRegion(llvm::FoldingSetNodeID &ID,
+                            const PointerType *PT,
+                            const MemRegion *sReg);
+
+  void Profile(llvm::FoldingSetNodeID &ID) const;
+
+public:  
+  QualType getValueType(ASTContext &C) const {
+    return QualType(ThisPointerTy, 0);
+  }
+  
+  void dumpToStream(llvm::raw_ostream& os) const;
+  
+  static bool classof(const MemRegion* R) {
+    return R->getKind() == CXXThisRegionKind;
+  }
+
+private:
+  const PointerType *ThisPointerTy;
+};
+
+class FieldRegion : public DeclRegion {
+  friend class MemRegionManager;
+
+  FieldRegion(const FieldDecl* fd, const MemRegion* sReg)
+    : DeclRegion(fd, sReg, FieldRegionKind) {}
+
+public:
+
+  void dumpToStream(llvm::raw_ostream& os) const;
+
+  const FieldDecl* getDecl() const { return cast<FieldDecl>(D); }
+
+  QualType getValueType(ASTContext& C) const {
+    // FIXME: We can cache this if needed.
+    return C.getCanonicalType(getDecl()->getType());
+  }
+
+  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const FieldDecl* FD,
+                            const MemRegion* superRegion) {
+    DeclRegion::ProfileRegion(ID, FD, superRegion, FieldRegionKind);
+  }
+
+  static bool classof(const MemRegion* R) {
+    return R->getKind() == FieldRegionKind;
+  }
+};
+
+class ObjCIvarRegion : public DeclRegion {
+
+  friend class MemRegionManager;
+
+  ObjCIvarRegion(const ObjCIvarDecl* ivd, const MemRegion* sReg)
+    : DeclRegion(ivd, sReg, ObjCIvarRegionKind) {}
+
+  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const ObjCIvarDecl* ivd,
+                            const MemRegion* superRegion) {
+    DeclRegion::ProfileRegion(ID, ivd, superRegion, ObjCIvarRegionKind);
+  }
+
+public:
+  const ObjCIvarDecl* getDecl() const { return cast<ObjCIvarDecl>(D); }
+  QualType getValueType(ASTContext&) const { return getDecl()->getType(); }
+
+  void dumpToStream(llvm::raw_ostream& os) const;
+
+  static bool classof(const MemRegion* R) {
+    return R->getKind() == ObjCIvarRegionKind;
+  }
+};
+
+class ElementRegion : public TypedRegion {
+  friend class MemRegionManager;
+
+  QualType ElementType;
+  SVal Index;
+
+  ElementRegion(QualType elementType, SVal Idx, const MemRegion* sReg)
+    : TypedRegion(sReg, ElementRegionKind),
+      ElementType(elementType), Index(Idx) {
+    assert((!isa<nonloc::ConcreteInt>(&Idx) ||
+           cast<nonloc::ConcreteInt>(&Idx)->getValue().isSigned()) &&
+           "The index must be signed");
+  }
+
+  static void ProfileRegion(llvm::FoldingSetNodeID& ID, QualType elementType,
+                            SVal Idx, const MemRegion* superRegion);
+
+public:
+
+  SVal getIndex() const { return Index; }
+
+  QualType getValueType(ASTContext&) const {
+    return ElementType;
+  }
+
+  QualType getElementType() const {
+    return ElementType;
+  }
+
+  RegionRawOffset getAsRawOffset() const;
+
+  void dumpToStream(llvm::raw_ostream& os) const;
+
+  void Profile(llvm::FoldingSetNodeID& ID) const;
+
+  static bool classof(const MemRegion* R) {
+    return R->getKind() == ElementRegionKind;
+  }
+};
+
+// C++ temporary object associated with an expression.
+class CXXObjectRegion : public TypedRegion {
+  friend class MemRegionManager;
+
+  Expr const *Ex;
+
+  CXXObjectRegion(Expr const *E, MemRegion const *sReg) 
+    : TypedRegion(sReg, CXXObjectRegionKind), Ex(E) {}
+
+  static void ProfileRegion(llvm::FoldingSetNodeID &ID,
+                            Expr const *E, const MemRegion *sReg);
+  
+public:
+  QualType getValueType(ASTContext& C) const {
+    return Ex->getType();
+  }
+
+  void Profile(llvm::FoldingSetNodeID &ID) const;
+
+  static bool classof(const MemRegion* R) {
+    return R->getKind() == CXXObjectRegionKind;
+  }
+};
+
+template<typename RegionTy>
+const RegionTy* MemRegion::getAs() const {
+  if (const RegionTy* RT = dyn_cast<RegionTy>(this))
+    return RT;
+
+  return NULL;
+}
+
+//===----------------------------------------------------------------------===//
+// MemRegionManager - Factory object for creating regions.
+//===----------------------------------------------------------------------===//
+
+class MemRegionManager {
+  ASTContext &C;
+  llvm::BumpPtrAllocator& A;
+  llvm::FoldingSet<MemRegion> Regions;
+
+  GlobalsSpaceRegion *globals;
+  
+  llvm::DenseMap<const StackFrameContext *, StackLocalsSpaceRegion *> 
+    StackLocalsSpaceRegions;
+  llvm::DenseMap<const StackFrameContext *, StackArgumentsSpaceRegion *>
+    StackArgumentsSpaceRegions;
+
+  HeapSpaceRegion *heap;
+  UnknownSpaceRegion *unknown;
+  MemSpaceRegion *code;
+
+public:
+  MemRegionManager(ASTContext &c, llvm::BumpPtrAllocator& a)
+    : C(c), A(a), globals(0), heap(0), unknown(0), code(0) {}
+
+  ~MemRegionManager();
+
+  ASTContext &getContext() { return C; }
+  
+  llvm::BumpPtrAllocator &getAllocator() { return A; }
+
+  /// getStackLocalsRegion - Retrieve the memory region associated with the
+  ///  specified stack frame.
+  const StackLocalsSpaceRegion *
+  getStackLocalsRegion(const StackFrameContext *STC);
+
+  /// getStackArgumentsRegion - Retrieve the memory region associated with
+  ///  function/method arguments of the specified stack frame.
+  const StackArgumentsSpaceRegion *
+  getStackArgumentsRegion(const StackFrameContext *STC);
+
+  /// getGlobalsRegion - Retrieve the memory region associated with
+  ///  all global variables.
+  const GlobalsSpaceRegion *getGlobalsRegion();
+
+  /// getHeapRegion - Retrieve the memory region associated with the
+  ///  generic "heap".
+  const HeapSpaceRegion *getHeapRegion();
+
+  /// getUnknownRegion - Retrieve the memory region associated with unknown
+  /// memory space.
+  const MemSpaceRegion *getUnknownRegion();
+
+  const MemSpaceRegion *getCodeRegion();
+
+  /// getAllocaRegion - Retrieve a region associated with a call to alloca().
+  const AllocaRegion *getAllocaRegion(const Expr* Ex, unsigned Cnt,
+                                      const LocationContext *LC);
+
+  /// getCompoundLiteralRegion - Retrieve the region associated with a
+  ///  given CompoundLiteral.
+  const CompoundLiteralRegion*
+  getCompoundLiteralRegion(const CompoundLiteralExpr* CL,
+                           const LocationContext *LC);
+  
+  /// getCXXThisRegion - Retrieve the [artifical] region associated with the
+  ///  parameter 'this'.
+  const CXXThisRegion *getCXXThisRegion(QualType thisPointerTy,
+                                        const LocationContext *LC);
+
+  /// getSymbolicRegion - Retrieve or create a "symbolic" memory region.
+  const SymbolicRegion* getSymbolicRegion(SymbolRef sym);
+
+  const StringRegion* getStringRegion(const StringLiteral* Str);
+
+  /// getVarRegion - Retrieve or create the memory region associated with
+  ///  a specified VarDecl and LocationContext.
+  const VarRegion* getVarRegion(const VarDecl *D, const LocationContext *LC);
+
+  /// getVarRegion - Retrieve or create the memory region associated with
+  ///  a specified VarDecl and super region.
+  const VarRegion* getVarRegion(const VarDecl *D, const MemRegion *superR);
+  
+  /// getElementRegion - Retrieve the memory region associated with the
+  ///  associated element type, index, and super region.
+  const ElementRegion *getElementRegion(QualType elementType, SVal Idx,
+                                        const MemRegion *superRegion,
+                                        ASTContext &Ctx);
+
+  const ElementRegion *getElementRegionWithSuper(const ElementRegion *ER,
+                                                 const MemRegion *superRegion) {
+    return getElementRegion(ER->getElementType(), ER->getIndex(),
+                            superRegion, ER->getContext());
+  }
+
+  /// getFieldRegion - Retrieve or create the memory region associated with
+  ///  a specified FieldDecl.  'superRegion' corresponds to the containing
+  ///  memory region (which typically represents the memory representing
+  ///  a structure or class).
+  const FieldRegion *getFieldRegion(const FieldDecl* fd,
+                                    const MemRegion* superRegion);
+
+  const FieldRegion *getFieldRegionWithSuper(const FieldRegion *FR,
+                                             const MemRegion *superRegion) {
+    return getFieldRegion(FR->getDecl(), superRegion);
+  }
+
+  /// getObjCIvarRegion - Retrieve or create the memory region associated with
+  ///   a specified Objective-c instance variable.  'superRegion' corresponds
+  ///   to the containing region (which typically represents the Objective-C
+  ///   object).
+  const ObjCIvarRegion *getObjCIvarRegion(const ObjCIvarDecl* ivd,
+                                          const MemRegion* superRegion);
+
+  const CXXObjectRegion *getCXXObjectRegion(Expr const *Ex,
+                                            LocationContext const *LC);
+
+  const FunctionTextRegion *getFunctionTextRegion(const FunctionDecl *FD);
+  const BlockTextRegion *getBlockTextRegion(const BlockDecl *BD,
+                                            CanQualType locTy,
+                                            AnalysisContext *AC);
+  
+  /// getBlockDataRegion - Get the memory region associated with an instance
+  ///  of a block.  Unlike many other MemRegions, the LocationContext*
+  ///  argument is allowed to be NULL for cases where we have no known
+  ///  context.
+  const BlockDataRegion *getBlockDataRegion(const BlockTextRegion *bc,
+                                            const LocationContext *lc = NULL);
+
+  bool isGlobalsRegion(const MemRegion* R) {
+    assert(R);
+    return R == globals;
+  }
+  
+private:
+  template <typename RegionTy, typename A1>
+  RegionTy* getRegion(const A1 a1);
+
+  template <typename RegionTy, typename A1>
+  RegionTy* getSubRegion(const A1 a1, const MemRegion* superRegion);
+
+  template <typename RegionTy, typename A1, typename A2>
+  RegionTy* getRegion(const A1 a1, const A2 a2);
+
+  template <typename RegionTy, typename A1, typename A2>
+  RegionTy* getSubRegion(const A1 a1, const A2 a2,
+                         const MemRegion* superRegion);
+
+  template <typename RegionTy, typename A1, typename A2, typename A3>
+  RegionTy* getSubRegion(const A1 a1, const A2 a2, const A3 a3,
+                         const MemRegion* superRegion);
+  
+  template <typename REG>
+  const REG* LazyAllocate(REG*& region);
+  
+  template <typename REG, typename ARG>
+  const REG* LazyAllocate(REG*& region, ARG a);
+};
+
+//===----------------------------------------------------------------------===//
+// Out-of-line member definitions.
+//===----------------------------------------------------------------------===//
+
+inline ASTContext& MemRegion::getContext() const {
+  return getMemRegionManager()->getContext();
+}
+  
+} // end clang namespace
+
+//===----------------------------------------------------------------------===//
+// Pretty-printing regions.
+//===----------------------------------------------------------------------===//
+
+namespace llvm {
+static inline raw_ostream& operator<<(raw_ostream& os,
+                                      const clang::MemRegion* R) {
+  R->dumpToStream(os);
+  return os;
+}
+} // end llvm namespace
+
+#endif
diff --git a/include/clang/Checker/PathSensitive/SVals.h b/include/clang/Checker/PathSensitive/SVals.h
new file mode 100644
index 0000000..040db83
--- /dev/null
+++ b/include/clang/Checker/PathSensitive/SVals.h
@@ -0,0 +1,502 @@
+//== SVals.h - Abstract Values for Static Analysis ---------*- C++ -*--==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines SVal, Loc, and NonLoc, classes that represent
+//  abstract r-values for use with path-sensitive value tracking.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_RVALUE_H
+#define LLVM_CLANG_ANALYSIS_RVALUE_H
+
+#include "clang/Checker/PathSensitive/SymbolManager.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/ADT/ImmutableList.h"
+
+namespace llvm {
+  class raw_ostream;
+}
+
+//==------------------------------------------------------------------------==//
+//  Base SVal types.
+//==------------------------------------------------------------------------==//
+
+namespace clang {
+
+class CompoundValData;
+class LazyCompoundValData;
+class GRState;
+class BasicValueFactory;
+class MemRegion;
+class TypedRegion;
+class MemRegionManager;
+class GRStateManager;
+class ValueManager;
+
+class SVal {
+public:
+  enum BaseKind { UndefinedKind, UnknownKind, LocKind, NonLocKind };
+  enum { BaseBits = 2, BaseMask = 0x3 };
+
+protected:
+  void* Data;
+  unsigned Kind;
+
+protected:
+  SVal(const void* d, bool isLoc, unsigned ValKind)
+  : Data(const_cast<void*>(d)),
+    Kind((isLoc ? LocKind : NonLocKind) | (ValKind << BaseBits)) {}
+
+  explicit SVal(BaseKind k, void* D = NULL)
+    : Data(D), Kind(k) {}
+
+public:
+  SVal() : Data(0), Kind(0) {}
+  ~SVal() {}
+
+  /// BufferTy - A temporary buffer to hold a set of SVals.
+  typedef llvm::SmallVector<SVal,5> BufferTy;
+
+  inline unsigned getRawKind() const { return Kind; }
+  inline BaseKind getBaseKind() const { return (BaseKind) (Kind & BaseMask); }
+  inline unsigned getSubKind() const { return (Kind & ~BaseMask) >> BaseBits; }
+
+  inline void Profile(llvm::FoldingSetNodeID& ID) const {
+    ID.AddInteger((unsigned) getRawKind());
+    ID.AddPointer(reinterpret_cast<void*>(Data));
+  }
+
+  inline bool operator==(const SVal& R) const {
+    return getRawKind() == R.getRawKind() && Data == R.Data;
+  }
+
+  inline bool operator!=(const SVal& R) const {
+    return !(*this == R);
+  }
+
+  inline bool isUnknown() const {
+    return getRawKind() == UnknownKind;
+  }
+
+  inline bool isUndef() const {
+    return getRawKind() == UndefinedKind;
+  }
+
+  inline bool isUnknownOrUndef() const {
+    return getRawKind() <= UnknownKind;
+  }
+
+  inline bool isValid() const {
+    return getRawKind() > UnknownKind;
+  }
+
+  bool isConstant() const;
+
+  bool isZeroConstant() const;
+
+  /// hasConjuredSymbol - If this SVal wraps a conjured symbol, return true;
+  bool hasConjuredSymbol() const;
+
+  /// getAsFunctionDecl - If this SVal is a MemRegionVal and wraps a
+  /// CodeTextRegion wrapping a FunctionDecl, return that FunctionDecl.
+  /// Otherwise return 0.
+  const FunctionDecl* getAsFunctionDecl() const;
+
+  /// getAsLocSymbol - If this SVal is a location (subclasses Loc) and
+  ///  wraps a symbol, return that SymbolRef.  Otherwise return a SymbolData*
+  SymbolRef getAsLocSymbol() const;
+
+  /// Get the symbol in the SVal or its base region.
+  SymbolRef getLocSymbolInBase() const;
+
+  /// getAsSymbol - If this Sval wraps a symbol return that SymbolRef.
+  ///  Otherwise return a SymbolRef where 'isValid()' returns false.
+  SymbolRef getAsSymbol() const;
+
+  /// getAsSymbolicExpression - If this Sval wraps a symbolic expression then
+  ///  return that expression.  Otherwise return NULL.
+  const SymExpr *getAsSymbolicExpression() const;
+
+  const MemRegion *getAsRegion() const;
+
+  void dumpToStream(llvm::raw_ostream& OS) const;
+  void dump() const;
+
+  // Iterators.
+  class symbol_iterator {
+    llvm::SmallVector<const SymExpr*, 5> itr;
+    void expand();
+  public:
+    symbol_iterator() {}
+    symbol_iterator(const SymExpr* SE);
+
+    symbol_iterator& operator++();
+    SymbolRef operator*();
+
+    bool operator==(const symbol_iterator& X) const;
+    bool operator!=(const symbol_iterator& X) const;
+  };
+
+  symbol_iterator symbol_begin() const {
+    const SymExpr *SE = getAsSymbolicExpression();
+    if (SE)
+      return symbol_iterator(SE);
+    else
+      return symbol_iterator();
+  }
+
+  symbol_iterator symbol_end() const { return symbol_iterator(); }
+
+  // Implement isa<T> support.
+  static inline bool classof(const SVal*) { return true; }
+};
+
+
+class UndefinedVal : public SVal {
+public:
+  UndefinedVal() : SVal(UndefinedKind) {}
+  UndefinedVal(void* D) : SVal(UndefinedKind, D) {}
+
+  static inline bool classof(const SVal* V) {
+    return V->getBaseKind() == UndefinedKind;
+  }
+
+  void* getData() const { return Data; }
+};
+
+class DefinedOrUnknownSVal : public SVal {
+private:
+  // Do not implement.  We want calling these methods to be a compiler
+  // error since they are tautologically false.
+  bool isUndef() const;
+  bool isValid() const;
+  
+protected:
+  explicit DefinedOrUnknownSVal(const void* d, bool isLoc, unsigned ValKind)
+    : SVal(d, isLoc, ValKind) {}
+  
+  explicit DefinedOrUnknownSVal(BaseKind k, void *D = NULL)
+    : SVal(k, D) {}
+  
+public:
+    // Implement isa<T> support.
+  static inline bool classof(const SVal *V) {
+    return !V->isUndef();
+  }
+};
+  
+class UnknownVal : public DefinedOrUnknownSVal {
+public:
+  UnknownVal() : DefinedOrUnknownSVal(UnknownKind) {}
+  
+  static inline bool classof(const SVal *V) {
+    return V->getBaseKind() == UnknownKind;
+  }
+};
+  
+class DefinedSVal : public DefinedOrUnknownSVal {
+private:
+  // Do not implement.  We want calling these methods to be a compiler
+  // error since they are tautologically true/false.
+  bool isUnknown() const;
+  bool isUnknownOrUndef() const;
+  bool isValid() const;  
+protected:
+  DefinedSVal(const void* d, bool isLoc, unsigned ValKind)
+    : DefinedOrUnknownSVal(d, isLoc, ValKind) {}
+public:
+  // Implement isa<T> support.
+  static inline bool classof(const SVal *V) {
+    return !V->isUnknownOrUndef();
+  }
+};
+
+class NonLoc : public DefinedSVal {
+protected:
+  NonLoc(unsigned SubKind, const void* d) : DefinedSVal(d, false, SubKind) {}
+
+public:
+  void dumpToStream(llvm::raw_ostream& Out) const;
+
+  // Implement isa<T> support.
+  static inline bool classof(const SVal* V) {
+    return V->getBaseKind() == NonLocKind;
+  }
+};
+
+class Loc : public DefinedSVal {
+protected:
+  Loc(unsigned SubKind, const void* D)
+  : DefinedSVal(const_cast<void*>(D), true, SubKind) {}
+
+public:
+  void dumpToStream(llvm::raw_ostream& Out) const;
+
+  Loc(const Loc& X) : DefinedSVal(X.Data, true, X.getSubKind()) {}
+  Loc& operator=(const Loc& X) { memcpy(this, &X, sizeof(Loc)); return *this; }
+
+  // Implement isa<T> support.
+  static inline bool classof(const SVal* V) {
+    return V->getBaseKind() == LocKind;
+  }
+
+  static inline bool IsLocType(QualType T) {
+    return T->isAnyPointerType() || T->isBlockPointerType() || 
+           T->isReferenceType();
+  }
+};
+
+//==------------------------------------------------------------------------==//
+//  Subclasses of NonLoc.
+//==------------------------------------------------------------------------==//
+
+namespace nonloc {
+
+enum Kind { ConcreteIntKind, SymbolValKind, SymExprValKind,
+            LocAsIntegerKind, CompoundValKind, LazyCompoundValKind };
+
+class SymbolVal : public NonLoc {
+public:
+  SymbolVal(SymbolRef sym) : NonLoc(SymbolValKind, sym) {}
+
+  SymbolRef getSymbol() const {
+    return (const SymbolData*) Data;
+  }
+
+  static inline bool classof(const SVal* V) {
+    return V->getBaseKind() == NonLocKind &&
+           V->getSubKind() == SymbolValKind;
+  }
+
+  static inline bool classof(const NonLoc* V) {
+    return V->getSubKind() == SymbolValKind;
+  }
+};
+
+class SymExprVal : public NonLoc {
+public:
+  SymExprVal(const SymExpr *SE)
+    : NonLoc(SymExprValKind, reinterpret_cast<const void*>(SE)) {}
+
+  const SymExpr *getSymbolicExpression() const {
+    return reinterpret_cast<SymExpr*>(Data);
+  }
+
+  static inline bool classof(const SVal* V) {
+    return V->getBaseKind() == NonLocKind &&
+           V->getSubKind() == SymExprValKind;
+  }
+
+  static inline bool classof(const NonLoc* V) {
+    return V->getSubKind() == SymExprValKind;
+  }
+};
+
+class ConcreteInt : public NonLoc {
+public:
+  ConcreteInt(const llvm::APSInt& V) : NonLoc(ConcreteIntKind, &V) {}
+
+  const llvm::APSInt& getValue() const {
+    return *static_cast<llvm::APSInt*>(Data);
+  }
+
+  // Transfer functions for binary/unary operations on ConcreteInts.
+  SVal evalBinOp(ValueManager &ValMgr, BinaryOperator::Opcode Op,
+                 const ConcreteInt& R) const;
+
+  ConcreteInt evalComplement(ValueManager &ValMgr) const;
+
+  ConcreteInt evalMinus(ValueManager &ValMgr) const;
+
+  // Implement isa<T> support.
+  static inline bool classof(const SVal* V) {
+    return V->getBaseKind() == NonLocKind &&
+           V->getSubKind() == ConcreteIntKind;
+  }
+
+  static inline bool classof(const NonLoc* V) {
+    return V->getSubKind() == ConcreteIntKind;
+  }
+};
+
+class LocAsInteger : public NonLoc {
+  friend class clang::ValueManager;
+
+  LocAsInteger(const std::pair<SVal, uintptr_t>& data) :
+    NonLoc(LocAsIntegerKind, &data) {
+      assert (isa<Loc>(data.first));
+    }
+
+public:
+
+  Loc getLoc() const {
+    return cast<Loc>(((std::pair<SVal, uintptr_t>*) Data)->first);
+  }
+
+  const Loc& getPersistentLoc() const {
+    const SVal& V = ((std::pair<SVal, uintptr_t>*) Data)->first;
+    return cast<Loc>(V);
+  }
+
+  unsigned getNumBits() const {
+    return ((std::pair<SVal, unsigned>*) Data)->second;
+  }
+
+  // Implement isa<T> support.
+  static inline bool classof(const SVal* V) {
+    return V->getBaseKind() == NonLocKind &&
+           V->getSubKind() == LocAsIntegerKind;
+  }
+
+  static inline bool classof(const NonLoc* V) {
+    return V->getSubKind() == LocAsIntegerKind;
+  }
+};
+
+class CompoundVal : public NonLoc {
+  friend class clang::ValueManager;
+
+  CompoundVal(const CompoundValData* D) : NonLoc(CompoundValKind, D) {}
+
+public:
+  const CompoundValData* getValue() const {
+    return static_cast<CompoundValData*>(Data);
+  }
+
+  typedef llvm::ImmutableList<SVal>::iterator iterator;
+  iterator begin() const;
+  iterator end() const;
+
+  static bool classof(const SVal* V) {
+    return V->getBaseKind() == NonLocKind && V->getSubKind() == CompoundValKind;
+  }
+
+  static bool classof(const NonLoc* V) {
+    return V->getSubKind() == CompoundValKind;
+  }
+};
+
+class LazyCompoundVal : public NonLoc {
+  friend class clang::ValueManager;
+
+  LazyCompoundVal(const LazyCompoundValData *D)
+    : NonLoc(LazyCompoundValKind, D) {}
+public:
+  const LazyCompoundValData *getCVData() const {
+    return static_cast<const LazyCompoundValData*>(Data);
+  }
+  const void *getStore() const;
+  const TypedRegion *getRegion() const;
+
+  static bool classof(const SVal *V) {
+    return V->getBaseKind() == NonLocKind &&
+           V->getSubKind() == LazyCompoundValKind;
+  }
+  static bool classof(const NonLoc *V) {
+    return V->getSubKind() == LazyCompoundValKind;
+  }
+};
+
+} // end namespace clang::nonloc
+
+//==------------------------------------------------------------------------==//
+//  Subclasses of Loc.
+//==------------------------------------------------------------------------==//
+
+namespace loc {
+
+enum Kind { GotoLabelKind, MemRegionKind, ConcreteIntKind };
+
+class GotoLabel : public Loc {
+public:
+  GotoLabel(LabelStmt* Label) : Loc(GotoLabelKind, Label) {}
+
+  LabelStmt* getLabel() const {
+    return static_cast<LabelStmt*>(Data);
+  }
+
+  static inline bool classof(const SVal* V) {
+    return V->getBaseKind() == LocKind &&
+           V->getSubKind() == GotoLabelKind;
+  }
+
+  static inline bool classof(const Loc* V) {
+    return V->getSubKind() == GotoLabelKind;
+  }
+};
+
+
+class MemRegionVal : public Loc {
+public:
+  MemRegionVal(const MemRegion* r) : Loc(MemRegionKind, r) {}
+
+  const MemRegion* getRegion() const {
+    return static_cast<MemRegion*>(Data);
+  }
+
+  const MemRegion* StripCasts() const;
+
+  template <typename REGION>
+  const REGION* getRegionAs() const {
+    return llvm::dyn_cast<REGION>(getRegion());
+  }
+
+  inline bool operator==(const MemRegionVal& R) const {
+    return getRegion() == R.getRegion();
+  }
+
+  inline bool operator!=(const MemRegionVal& R) const {
+    return getRegion() != R.getRegion();
+  }
+
+  // Implement isa<T> support.
+  static inline bool classof(const SVal* V) {
+    return V->getBaseKind() == LocKind &&
+           V->getSubKind() == MemRegionKind;
+  }
+
+  static inline bool classof(const Loc* V) {
+    return V->getSubKind() == MemRegionKind;
+  }
+};
+
+class ConcreteInt : public Loc {
+public:
+  ConcreteInt(const llvm::APSInt& V) : Loc(ConcreteIntKind, &V) {}
+
+  const llvm::APSInt& getValue() const {
+    return *static_cast<llvm::APSInt*>(Data);
+  }
+
+  // Transfer functions for binary/unary operations on ConcreteInts.
+  SVal EvalBinOp(BasicValueFactory& BasicVals, BinaryOperator::Opcode Op,
+                 const ConcreteInt& R) const;
+
+  // Implement isa<T> support.
+  static inline bool classof(const SVal* V) {
+    return V->getBaseKind() == LocKind &&
+           V->getSubKind() == ConcreteIntKind;
+  }
+
+  static inline bool classof(const Loc* V) {
+    return V->getSubKind() == ConcreteIntKind;
+  }
+};
+
+} // end clang::loc namespace
+} // end clang namespace
+
+namespace llvm {
+static inline llvm::raw_ostream& operator<<(llvm::raw_ostream& os,
+                                            clang::SVal V) {
+  V.dumpToStream(os);
+  return os;
+}
+} // end llvm namespace
+#endif
diff --git a/include/clang/Checker/PathSensitive/SValuator.h b/include/clang/Checker/PathSensitive/SValuator.h
new file mode 100644
index 0000000..9beb8cb
--- /dev/null
+++ b/include/clang/Checker/PathSensitive/SValuator.h
@@ -0,0 +1,66 @@
+// SValuator.h - Construction of SVals from evaluating expressions -*- C++ -*---
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines SValuator, a class that defines the interface for
+//  "symbolical evaluators" which construct an SVal from an expression.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_SVALUATOR
+#define LLVM_CLANG_ANALYSIS_SVALUATOR
+
+#include "clang/AST/Expr.h"
+#include "clang/Checker/PathSensitive/SVals.h"
+
+namespace clang {
+
+class GRState;
+class ValueManager;
+
+class SValuator {
+  friend class ValueManager;
+protected:
+  ValueManager &ValMgr;
+
+public:
+  // FIXME: Make these protected again one RegionStoreManager correctly
+  // handles loads from differening bound value types.
+  virtual SVal EvalCastNL(NonLoc val, QualType castTy) = 0;
+  virtual SVal EvalCastL(Loc val, QualType castTy) = 0;
+
+public:
+  SValuator(ValueManager &valMgr) : ValMgr(valMgr) {}
+  virtual ~SValuator() {}
+
+  SVal EvalCast(SVal V, QualType castTy, QualType originalType);
+  
+  virtual SVal EvalMinus(NonLoc val) = 0;
+
+  virtual SVal EvalComplement(NonLoc val) = 0;
+
+  virtual SVal EvalBinOpNN(const GRState *state, BinaryOperator::Opcode Op,
+                           NonLoc lhs, NonLoc rhs, QualType resultTy) = 0;
+
+  virtual SVal EvalBinOpLL(BinaryOperator::Opcode Op, Loc lhs, Loc rhs,
+                           QualType resultTy) = 0;
+
+  virtual SVal EvalBinOpLN(const GRState *state, BinaryOperator::Opcode Op,
+                           Loc lhs, NonLoc rhs, QualType resultTy) = 0;
+  
+  SVal EvalBinOp(const GRState *ST, BinaryOperator::Opcode Op,
+                 SVal L, SVal R, QualType T);
+  
+  DefinedOrUnknownSVal EvalEQ(const GRState *ST, DefinedOrUnknownSVal L,
+                              DefinedOrUnknownSVal R);
+};
+
+SValuator* CreateSimpleSValuator(ValueManager &valMgr);
+
+} // end clang namespace
+#endif
diff --git a/include/clang/Checker/PathSensitive/Store.h b/include/clang/Checker/PathSensitive/Store.h
new file mode 100644
index 0000000..41d7c2b
--- /dev/null
+++ b/include/clang/Checker/PathSensitive/Store.h
@@ -0,0 +1,231 @@
+//== Store.h - Interface for maps from Locations to Values ------*- C++ -*--==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defined the types Store and StoreManager.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_STORE_H
+#define LLVM_CLANG_ANALYSIS_STORE_H
+
+#include "clang/Checker/PathSensitive/MemRegion.h"
+#include "clang/Checker/PathSensitive/SVals.h"
+#include "clang/Checker/PathSensitive/ValueManager.h"
+#include "llvm/ADT/DenseSet.h"
+
+namespace clang {
+
+typedef const void* Store;
+
+class GRState;
+class GRStateManager;
+class Stmt;
+class Expr;
+class ObjCIvarDecl;
+class SubRegionMap;
+class StackFrameContext;
+
+class StoreManager {
+protected:
+  ValueManager &ValMgr;
+  GRStateManager &StateMgr;
+
+  /// MRMgr - Manages region objects associated with this StoreManager.
+  MemRegionManager &MRMgr;
+  ASTContext &Ctx;
+
+  StoreManager(GRStateManager &stateMgr);
+
+public:
+  virtual ~StoreManager() {}
+
+  /// Return the value bound to specified location in a given state.
+  /// \param[in] state The analysis state.
+  /// \param[in] loc The symbolic memory location.
+  /// \param[in] T An optional type that provides a hint indicating the
+  ///   expected type of the returned value.  This is used if the value is
+  ///   lazily computed.
+  /// \return The value bound to the location \c loc.
+  virtual SVal Retrieve(Store store, Loc loc, QualType T = QualType()) = 0;
+
+  /// Return a state with the specified value bound to the given location.
+  /// \param[in] state The analysis state.
+  /// \param[in] loc The symbolic memory location.
+  /// \param[in] val The value to bind to location \c loc.
+  /// \return A pointer to a GRState object that contains the same bindings as
+  ///   \c state with the addition of having the value specified by \c val bound
+  ///   to the location given for \c loc.
+  virtual Store Bind(Store store, Loc loc, SVal val) = 0;
+
+  virtual Store Remove(Store St, Loc L) = 0;
+
+  /// BindCompoundLiteral - Return the store that has the bindings currently
+  ///  in 'store' plus the bindings for the CompoundLiteral.  'R' is the region
+  ///  for the compound literal and 'BegInit' and 'EndInit' represent an
+  ///  array of initializer values.
+  virtual Store BindCompoundLiteral(Store store,
+                                    const CompoundLiteralExpr* cl,
+                                    const LocationContext *LC, SVal v) = 0;
+
+  /// getInitialStore - Returns the initial "empty" store representing the
+  ///  value bindings upon entry to an analyzed function.
+  virtual Store getInitialStore(const LocationContext *InitLoc) = 0;
+
+  /// getRegionManager - Returns the internal RegionManager object that is
+  ///  used to query and manipulate MemRegion objects.
+  MemRegionManager& getRegionManager() { return MRMgr; }
+
+  /// getSubRegionMap - Returns an opaque map object that clients can query
+  ///  to get the subregions of a given MemRegion object.  It is the
+  //   caller's responsibility to 'delete' the returned map.
+  virtual SubRegionMap *getSubRegionMap(Store store) = 0;
+
+  virtual SVal getLValueVar(const VarDecl *VD, const LocationContext *LC) {
+    return ValMgr.makeLoc(MRMgr.getVarRegion(VD, LC));
+  }
+
+  virtual SVal getLValueString(const StringLiteral* S) {
+    return ValMgr.makeLoc(MRMgr.getStringRegion(S));
+  }
+
+  SVal getLValueCompoundLiteral(const CompoundLiteralExpr* CL,
+                                const LocationContext *LC) {
+    return loc::MemRegionVal(MRMgr.getCompoundLiteralRegion(CL, LC));
+  }
+
+  virtual SVal getLValueIvar(const ObjCIvarDecl* decl, SVal base) {
+    return getLValueFieldOrIvar(decl, base);
+  }
+
+  virtual SVal getLValueField(const FieldDecl* D, SVal Base) {
+    return getLValueFieldOrIvar(D, Base);
+  }
+
+  virtual SVal getLValueElement(QualType elementType, SVal offset, SVal Base);
+
+  // FIXME: Make out-of-line.
+  virtual DefinedOrUnknownSVal getSizeInElements(const GRState *state, 
+                                                 const MemRegion *region,
+                                                 QualType EleTy) {
+    return UnknownVal();
+  }
+
+  /// ArrayToPointer - Used by GRExprEngine::VistCast to handle implicit
+  ///  conversions between arrays and pointers.
+  virtual SVal ArrayToPointer(Loc Array) = 0;
+
+  class CastResult {
+    const GRState *state;
+    const MemRegion *region;
+  public:
+    const GRState *getState() const { return state; }
+    const MemRegion* getRegion() const { return region; }
+    CastResult(const GRState *s, const MemRegion* r = 0) : state(s), region(r){}
+  };
+
+  const ElementRegion *GetElementZeroRegion(const MemRegion *R, QualType T);
+
+  /// CastRegion - Used by GRExprEngine::VisitCast to handle casts from
+  ///  a MemRegion* to a specific location type.  'R' is the region being
+  ///  casted and 'CastToTy' the result type of the cast.
+  const MemRegion *CastRegion(const MemRegion *region, QualType CastToTy);
+
+
+  /// EvalBinOp - Perform pointer arithmetic.
+  virtual SVal EvalBinOp(BinaryOperator::Opcode Op,
+                         Loc lhs, NonLoc rhs, QualType resultTy) {
+    return UnknownVal();
+  }
+
+  virtual Store RemoveDeadBindings(Store store, Stmt* Loc,
+                                   const StackFrameContext *LCtx,
+                                   SymbolReaper& SymReaper,
+                      llvm::SmallVectorImpl<const MemRegion*>& RegionRoots) = 0;
+
+  virtual Store BindDecl(Store store, const VarRegion *VR, SVal initVal) = 0;
+
+  virtual Store BindDeclWithNoInit(Store store, const VarRegion *VR) = 0;
+
+  typedef llvm::DenseSet<SymbolRef> InvalidatedSymbols;
+  
+  virtual Store InvalidateRegion(Store store,
+                                 const MemRegion *R,
+                                 const Expr *E, unsigned Count,
+                                 InvalidatedSymbols *IS) = 0;
+  
+  virtual Store InvalidateRegions(Store store,
+                                  const MemRegion * const *Begin,
+                                  const MemRegion * const *End,
+                                  const Expr *E, unsigned Count,
+                                  InvalidatedSymbols *IS);  
+
+  // FIXME: Make out-of-line.
+  virtual const GRState *setExtent(const GRState *state,
+                                    const MemRegion *region, SVal extent) {
+    return state;
+  }
+
+  /// EnterStackFrame - Let the StoreManager to do something when execution
+  /// engine is about to execute into a callee.
+  virtual const GRState *EnterStackFrame(const GRState *state,
+                                         const StackFrameContext *frame) {
+    return state;
+  }
+
+  virtual void print(Store store, llvm::raw_ostream& Out,
+                     const char* nl, const char *sep) = 0;
+
+  class BindingsHandler {
+  public:
+    virtual ~BindingsHandler();
+    virtual bool HandleBinding(StoreManager& SMgr, Store store,
+                               const MemRegion *region, SVal val) = 0;
+  };
+
+  /// iterBindings - Iterate over the bindings in the Store.
+  virtual void iterBindings(Store store, BindingsHandler& f) = 0;
+
+protected:
+  const MemRegion *MakeElementRegion(const MemRegion *Base,
+                                     QualType pointeeTy, uint64_t index = 0);
+
+  /// CastRetrievedVal - Used by subclasses of StoreManager to implement
+  ///  implicit casts that arise from loads from regions that are reinterpreted
+  ///  as another region.
+  SVal CastRetrievedVal(SVal val, const TypedRegion *R, QualType castTy,
+                        bool performTestOnly = true);
+
+private:
+  SVal getLValueFieldOrIvar(const Decl* D, SVal Base);
+};
+
+// FIXME: Do we still need this?
+/// SubRegionMap - An abstract interface that represents a queryable map
+///  between MemRegion objects and their subregions.
+class SubRegionMap {
+public:
+  virtual ~SubRegionMap() {}
+
+  class Visitor {
+  public:
+    virtual ~Visitor() {}
+    virtual bool Visit(const MemRegion* Parent, const MemRegion* SubRegion) = 0;
+  };
+
+  virtual bool iterSubRegions(const MemRegion *region, Visitor& V) const = 0;
+};
+
+// FIXME: Do we need to pass GRStateManager anymore?
+StoreManager *CreateBasicStoreManager(GRStateManager& StMgr);
+StoreManager *CreateRegionStoreManager(GRStateManager& StMgr);
+StoreManager *CreateFieldsOnlyRegionStoreManager(GRStateManager& StMgr);
+StoreManager *CreateFlatStoreManager(GRStateManager &StMgr);
+} // end clang namespace
+
+#endif
diff --git a/include/clang/Checker/PathSensitive/SummaryManager.h b/include/clang/Checker/PathSensitive/SummaryManager.h
new file mode 100644
index 0000000..fd23189
--- /dev/null
+++ b/include/clang/Checker/PathSensitive/SummaryManager.h
@@ -0,0 +1,57 @@
+//== SummaryManager.h - Generic handling of function summaries --*- C++ -*--==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines SummaryManager and related classes, which provides
+//  a generic mechanism for managing function summaries.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_CHECKER_SUMMARY
+#define LLVM_CLANG_CHECKER_SUMMARY
+
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/Support/Allocator.h"
+
+namespace clang {
+
+namespace summMgr {
+
+  
+/* Key kinds:
+ 
+ - C functions
+ - C++ functions (name + parameter types)
+ - ObjC methods:
+   - Class, selector (class method)
+   - Class, selector (instance method)
+   - Category, selector (instance method)
+   - Protocol, selector (instance method)
+ - C++ methods
+  - Class, function name + parameter types + const
+ */
+  
+class SummaryKey {
+  
+};
+
+} // end namespace clang::summMgr
+  
+class SummaryManagerImpl {
+  
+};
+
+  
+template <typename T>
+class SummaryManager : SummaryManagerImpl {
+  
+};
+
+} // end clang namespace
+
+#endif
diff --git a/include/clang/Checker/PathSensitive/SymbolManager.h b/include/clang/Checker/PathSensitive/SymbolManager.h
new file mode 100644
index 0000000..dea877c
--- /dev/null
+++ b/include/clang/Checker/PathSensitive/SymbolManager.h
@@ -0,0 +1,379 @@
+//== SymbolManager.h - Management of Symbolic Values ------------*- C++ -*--==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines SymbolManager, a class that manages symbolic values
+//  created for use by GRExprEngine and related classes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_SYMMGR_H
+#define LLVM_CLANG_ANALYSIS_SYMMGR_H
+
+#include "clang/AST/Decl.h"
+#include "clang/AST/Expr.h"
+#include "clang/Analysis/AnalysisContext.h"
+#include "llvm/System/DataTypes.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/DenseSet.h"
+
+namespace llvm {
+class BumpPtrAllocator;
+class raw_ostream;
+}
+
+namespace clang {
+  class ASTContext;
+  class BasicValueFactory;
+  class MemRegion;
+  class TypedRegion;
+  class VarRegion;
+  class StackFrameContext;
+
+class SymExpr : public llvm::FoldingSetNode {
+public:
+  enum Kind { BEGIN_SYMBOLS,
+              RegionValueKind, ConjuredKind, DerivedKind,
+              END_SYMBOLS,
+              SymIntKind, SymSymKind };
+private:
+  Kind K;
+
+protected:
+  SymExpr(Kind k) : K(k) {}
+
+public:
+  virtual ~SymExpr() {}
+
+  Kind getKind() const { return K; }
+
+  void dump() const;
+
+  virtual void dumpToStream(llvm::raw_ostream &os) const = 0;
+
+  virtual QualType getType(ASTContext&) const = 0;
+  virtual void Profile(llvm::FoldingSetNodeID& profile) = 0;
+
+  // Implement isa<T> support.
+  static inline bool classof(const SymExpr*) { return true; }
+};
+
+typedef unsigned SymbolID;
+
+class SymbolData : public SymExpr {
+private:
+  const SymbolID Sym;
+
+protected:
+  SymbolData(Kind k, SymbolID sym) : SymExpr(k), Sym(sym) {}
+
+public:
+  virtual ~SymbolData() {}
+
+  SymbolID getSymbolID() const { return Sym; }
+
+  // Implement isa<T> support.
+  static inline bool classof(const SymExpr* SE) {
+    Kind k = SE->getKind();
+    return k > BEGIN_SYMBOLS && k < END_SYMBOLS;
+  }
+};
+
+typedef const SymbolData* SymbolRef;
+
+// A symbol representing the value of a MemRegion.
+class SymbolRegionValue : public SymbolData {
+  const TypedRegion *R;
+
+public:
+  SymbolRegionValue(SymbolID sym, const TypedRegion *r)
+    : SymbolData(RegionValueKind, sym), R(r) {}
+
+  const TypedRegion* getRegion() const { return R; }
+
+  static void Profile(llvm::FoldingSetNodeID& profile, const TypedRegion* R) {
+    profile.AddInteger((unsigned) RegionValueKind);
+    profile.AddPointer(R);
+  }
+
+  virtual void Profile(llvm::FoldingSetNodeID& profile) {
+    Profile(profile, R);
+  }
+
+  void dumpToStream(llvm::raw_ostream &os) const;
+
+  QualType getType(ASTContext&) const;
+
+  // Implement isa<T> support.
+  static inline bool classof(const SymExpr* SE) {
+    return SE->getKind() == RegionValueKind;
+  }
+};
+
+// A symbol representing the result of an expression.
+class SymbolConjured : public SymbolData {
+  const Stmt* S;
+  QualType T;
+  unsigned Count;
+  const void* SymbolTag;
+
+public:
+  SymbolConjured(SymbolID sym, const Stmt* s, QualType t, unsigned count,
+                 const void* symbolTag)
+    : SymbolData(ConjuredKind, sym), S(s), T(t), Count(count),
+      SymbolTag(symbolTag) {}
+
+  const Stmt* getStmt() const { return S; }
+  unsigned getCount() const { return Count; }
+  const void* getTag() const { return SymbolTag; }
+
+  QualType getType(ASTContext&) const;
+
+  void dumpToStream(llvm::raw_ostream &os) const;
+
+  static void Profile(llvm::FoldingSetNodeID& profile, const Stmt* S,
+                      QualType T, unsigned Count, const void* SymbolTag) {
+    profile.AddInteger((unsigned) ConjuredKind);
+    profile.AddPointer(S);
+    profile.Add(T);
+    profile.AddInteger(Count);
+    profile.AddPointer(SymbolTag);
+  }
+
+  virtual void Profile(llvm::FoldingSetNodeID& profile) {
+    Profile(profile, S, T, Count, SymbolTag);
+  }
+
+  // Implement isa<T> support.
+  static inline bool classof(const SymExpr* SE) {
+    return SE->getKind() == ConjuredKind;
+  }
+};
+
+// A symbol representing the value of a MemRegion whose parent region has 
+// symbolic value.
+class SymbolDerived : public SymbolData {
+  SymbolRef parentSymbol;
+  const TypedRegion *R;
+
+public:
+  SymbolDerived(SymbolID sym, SymbolRef parent, const TypedRegion *r)
+    : SymbolData(DerivedKind, sym), parentSymbol(parent), R(r) {}
+
+  SymbolRef getParentSymbol() const { return parentSymbol; }
+  const TypedRegion *getRegion() const { return R; }
+
+  QualType getType(ASTContext&) const;
+
+  void dumpToStream(llvm::raw_ostream &os) const;
+
+  static void Profile(llvm::FoldingSetNodeID& profile, SymbolRef parent,
+                      const TypedRegion *r) {
+    profile.AddInteger((unsigned) DerivedKind);
+    profile.AddPointer(r);
+    profile.AddPointer(parent);
+  }
+
+  virtual void Profile(llvm::FoldingSetNodeID& profile) {
+    Profile(profile, parentSymbol, R);
+  }
+
+  // Implement isa<T> support.
+  static inline bool classof(const SymExpr* SE) {
+    return SE->getKind() == DerivedKind;
+  }
+};
+
+// SymIntExpr - Represents symbolic expression like 'x' + 3.
+class SymIntExpr : public SymExpr {
+  const SymExpr *LHS;
+  BinaryOperator::Opcode Op;
+  const llvm::APSInt& RHS;
+  QualType T;
+
+public:
+  SymIntExpr(const SymExpr *lhs, BinaryOperator::Opcode op,
+             const llvm::APSInt& rhs, QualType t)
+    : SymExpr(SymIntKind), LHS(lhs), Op(op), RHS(rhs), T(t) {}
+
+  // FIXME: We probably need to make this out-of-line to avoid redundant
+  // generation of virtual functions.
+  QualType getType(ASTContext& C) const { return T; }
+
+  BinaryOperator::Opcode getOpcode() const { return Op; }
+
+  void dumpToStream(llvm::raw_ostream &os) const;
+
+  const SymExpr *getLHS() const { return LHS; }
+  const llvm::APSInt &getRHS() const { return RHS; }
+
+  static void Profile(llvm::FoldingSetNodeID& ID, const SymExpr *lhs,
+                      BinaryOperator::Opcode op, const llvm::APSInt& rhs,
+                      QualType t) {
+    ID.AddInteger((unsigned) SymIntKind);
+    ID.AddPointer(lhs);
+    ID.AddInteger(op);
+    ID.AddPointer(&rhs);
+    ID.Add(t);
+  }
+
+  void Profile(llvm::FoldingSetNodeID& ID) {
+    Profile(ID, LHS, Op, RHS, T);
+  }
+
+  // Implement isa<T> support.
+  static inline bool classof(const SymExpr* SE) {
+    return SE->getKind() == SymIntKind;
+  }
+};
+
+// SymSymExpr - Represents symbolic expression like 'x' + 'y'.
+class SymSymExpr : public SymExpr {
+  const SymExpr *LHS;
+  BinaryOperator::Opcode Op;
+  const SymExpr *RHS;
+  QualType T;
+
+public:
+  SymSymExpr(const SymExpr *lhs, BinaryOperator::Opcode op, const SymExpr *rhs,
+             QualType t)
+    : SymExpr(SymSymKind), LHS(lhs), Op(op), RHS(rhs), T(t) {}
+
+  BinaryOperator::Opcode getOpcode() const { return Op; }
+  const SymExpr *getLHS() const { return LHS; }
+  const SymExpr *getRHS() const { return RHS; }
+
+  // FIXME: We probably need to make this out-of-line to avoid redundant
+  // generation of virtual functions.
+  QualType getType(ASTContext& C) const { return T; }
+
+  void dumpToStream(llvm::raw_ostream &os) const;
+
+  static void Profile(llvm::FoldingSetNodeID& ID, const SymExpr *lhs,
+                    BinaryOperator::Opcode op, const SymExpr *rhs, QualType t) {
+    ID.AddInteger((unsigned) SymSymKind);
+    ID.AddPointer(lhs);
+    ID.AddInteger(op);
+    ID.AddPointer(rhs);
+    ID.Add(t);
+  }
+
+  void Profile(llvm::FoldingSetNodeID& ID) {
+    Profile(ID, LHS, Op, RHS, T);
+  }
+
+  // Implement isa<T> support.
+  static inline bool classof(const SymExpr* SE) {
+    return SE->getKind() == SymSymKind;
+  }
+};
+
+class SymbolManager {
+  typedef llvm::FoldingSet<SymExpr> DataSetTy;
+  DataSetTy DataSet;
+  unsigned SymbolCounter;
+  llvm::BumpPtrAllocator& BPAlloc;
+  BasicValueFactory &BV;
+  ASTContext& Ctx;
+
+public:
+  SymbolManager(ASTContext& ctx, BasicValueFactory &bv,
+                llvm::BumpPtrAllocator& bpalloc)
+    : SymbolCounter(0), BPAlloc(bpalloc), BV(bv), Ctx(ctx) {}
+
+  ~SymbolManager();
+
+  static bool canSymbolicate(QualType T);
+
+  /// Make a unique symbol for MemRegion R according to its kind.
+  const SymbolRegionValue* getRegionValueSymbol(const TypedRegion* R);
+
+  const SymbolConjured* getConjuredSymbol(const Stmt* E, QualType T,
+                                          unsigned VisitCount,
+                                          const void* SymbolTag = 0);
+
+  const SymbolConjured* getConjuredSymbol(const Expr* E, unsigned VisitCount,
+                                          const void* SymbolTag = 0) {
+    return getConjuredSymbol(E, E->getType(), VisitCount, SymbolTag);
+  }
+
+  const SymbolDerived *getDerivedSymbol(SymbolRef parentSymbol,
+                                        const TypedRegion *R);
+
+  const SymIntExpr *getSymIntExpr(const SymExpr *lhs, BinaryOperator::Opcode op,
+                                  const llvm::APSInt& rhs, QualType t);
+
+  const SymIntExpr *getSymIntExpr(const SymExpr &lhs, BinaryOperator::Opcode op,
+                                  const llvm::APSInt& rhs, QualType t) {
+    return getSymIntExpr(&lhs, op, rhs, t);
+  }
+
+  const SymSymExpr *getSymSymExpr(const SymExpr *lhs, BinaryOperator::Opcode op,
+                                  const SymExpr *rhs, QualType t);
+
+  QualType getType(const SymExpr *SE) const {
+    return SE->getType(Ctx);
+  }
+
+  ASTContext &getContext() { return Ctx; }
+  BasicValueFactory &getBasicVals() { return BV; }
+};
+
+class SymbolReaper {
+  typedef llvm::DenseSet<SymbolRef> SetTy;
+
+  SetTy TheLiving;
+  SetTy TheDead;
+  const LocationContext *LCtx;
+  SymbolManager& SymMgr;
+
+public:
+  SymbolReaper(const LocationContext *ctx, SymbolManager& symmgr)
+    : LCtx(ctx), SymMgr(symmgr) {}
+
+  ~SymbolReaper() {}
+
+  const LocationContext *getLocationContext() const { return LCtx; }
+
+  bool isLive(SymbolRef sym);
+
+  bool isLive(const Stmt* Loc, const Stmt* ExprVal) const;
+
+  bool isLive(const Stmt* Loc, const VarRegion *VR) const;
+  
+  void markLive(SymbolRef sym);
+  bool maybeDead(SymbolRef sym);
+
+  typedef SetTy::const_iterator dead_iterator;
+  dead_iterator dead_begin() const { return TheDead.begin(); }
+  dead_iterator dead_end() const { return TheDead.end(); }
+
+  bool hasDeadSymbols() const {
+    return !TheDead.empty();
+  }
+};
+
+class SymbolVisitor {
+public:
+  // VisitSymbol - A visitor method invoked by
+  //  GRStateManager::scanReachableSymbols.  The method returns \c true if
+  //  symbols should continue be scanned and \c false otherwise.
+  virtual bool VisitSymbol(SymbolRef sym) = 0;
+  virtual ~SymbolVisitor();
+};
+
+} // end clang namespace
+
+namespace llvm {
+static inline llvm::raw_ostream& operator<<(llvm::raw_ostream& os,
+                                            const clang::SymExpr *SE) {
+  SE->dumpToStream(os);
+  return os;
+}
+} // end llvm namespace
+#endif
diff --git a/include/clang/Checker/PathSensitive/ValueManager.h b/include/clang/Checker/PathSensitive/ValueManager.h
new file mode 100644
index 0000000..5a9d54d
--- /dev/null
+++ b/include/clang/Checker/PathSensitive/ValueManager.h
@@ -0,0 +1,213 @@
+//== ValueManager.h - Aggregate manager of symbols and SVals ----*- C++ -*--==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines ValueManager, a class that manages symbolic values
+//  and SVals created for use by GRExprEngine and related classes.  It
+//  wraps and owns SymbolManager, MemRegionManager, and BasicValueFactory.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_AGGREGATE_VALUE_MANAGER_H
+#define LLVM_CLANG_ANALYSIS_AGGREGATE_VALUE_MANAGER_H
+
+#include "llvm/ADT/OwningPtr.h"
+#include "clang/Checker/PathSensitive/MemRegion.h"
+#include "clang/Checker/PathSensitive/SVals.h"
+#include "clang/Checker/PathSensitive/BasicValueFactory.h"
+#include "clang/Checker/PathSensitive/SymbolManager.h"
+#include "clang/Checker/PathSensitive/SValuator.h"
+#include "clang/AST/ExprCXX.h"
+
+namespace llvm { class BumpPtrAllocator; }
+
+namespace clang {
+
+class GRStateManager;
+
+class ValueManager {
+
+  ASTContext &Context;
+  BasicValueFactory BasicVals;
+
+  /// SymMgr - Object that manages the symbol information.
+  SymbolManager SymMgr;
+
+  /// SVator - SValuator object that creates SVals from expressions.
+  llvm::OwningPtr<SValuator> SVator;
+
+  MemRegionManager MemMgr;
+
+  GRStateManager &StateMgr;
+
+  const QualType ArrayIndexTy;
+  const unsigned ArrayIndexWidth;
+
+public:
+  ValueManager(llvm::BumpPtrAllocator &alloc, ASTContext &context,
+               GRStateManager &stateMgr)
+               : Context(context), BasicVals(context, alloc),
+                 SymMgr(context, BasicVals, alloc),
+                 MemMgr(context, alloc), StateMgr(stateMgr),
+                 ArrayIndexTy(context.IntTy),
+                 ArrayIndexWidth(context.getTypeSize(ArrayIndexTy)) {
+    // FIXME: Generalize later.
+    SVator.reset(clang::CreateSimpleSValuator(*this));
+  }
+
+  // Accessors to submanagers.
+
+  ASTContext &getContext() { return Context; }
+  const ASTContext &getContext() const { return Context; }
+
+  GRStateManager &getStateManager() { return StateMgr; }
+
+  BasicValueFactory &getBasicValueFactory() { return BasicVals; }
+  const BasicValueFactory &getBasicValueFactory() const { return BasicVals; }
+
+  SymbolManager &getSymbolManager() { return SymMgr; }
+  const SymbolManager &getSymbolManager() const { return SymMgr; }
+
+  SValuator &getSValuator() { return *SVator.get(); }
+
+  MemRegionManager &getRegionManager() { return MemMgr; }
+  const MemRegionManager &getRegionManager() const { return MemMgr; }
+
+  // Forwarding methods to SymbolManager.
+
+  const SymbolConjured* getConjuredSymbol(const Stmt* E, QualType T,
+                                          unsigned VisitCount,
+                                          const void* SymbolTag = 0) {
+    return SymMgr.getConjuredSymbol(E, T, VisitCount, SymbolTag);
+  }
+
+  const SymbolConjured* getConjuredSymbol(const Expr* E, unsigned VisitCount,
+                                          const void* SymbolTag = 0) {
+    return SymMgr.getConjuredSymbol(E, VisitCount, SymbolTag);
+  }
+
+  /// makeZeroVal - Construct an SVal representing '0' for the specified type.
+  DefinedOrUnknownSVal makeZeroVal(QualType T);
+
+  /// getRegionValueSymbolVal - make a unique symbol for value of R.
+  DefinedOrUnknownSVal getRegionValueSymbolVal(const TypedRegion *R);
+
+  DefinedOrUnknownSVal getConjuredSymbolVal(const void *SymbolTag,
+                                            const Expr *E, unsigned Count);
+  DefinedOrUnknownSVal getConjuredSymbolVal(const void *SymbolTag,
+                                            const Expr *E, QualType T,
+                                            unsigned Count);
+
+  DefinedOrUnknownSVal getDerivedRegionValueSymbolVal(SymbolRef parentSymbol,
+                                                      const TypedRegion *R);
+
+  DefinedSVal getFunctionPointer(const FunctionDecl *FD);
+  
+  DefinedSVal getBlockPointer(const BlockDecl *BD, CanQualType locTy,
+                              const LocationContext *LC);
+
+  NonLoc makeCompoundVal(QualType T, llvm::ImmutableList<SVal> Vals) {
+    return nonloc::CompoundVal(BasicVals.getCompoundValData(T, Vals));
+  }
+
+  NonLoc makeLazyCompoundVal(const void *store, const TypedRegion *R) {
+    return nonloc::LazyCompoundVal(BasicVals.getLazyCompoundValData(store, R));
+  }
+
+  NonLoc makeZeroArrayIndex() {
+    return nonloc::ConcreteInt(BasicVals.getValue(0, ArrayIndexTy));
+  }
+
+  NonLoc makeArrayIndex(uint64_t idx) {
+    return nonloc::ConcreteInt(BasicVals.getValue(idx, ArrayIndexTy));
+  }
+
+  SVal convertToArrayIndex(SVal V);
+
+  nonloc::ConcreteInt makeIntVal(const IntegerLiteral* I) {
+    return nonloc::ConcreteInt(BasicVals.getValue(I->getValue(),
+                                        I->getType()->isUnsignedIntegerType()));
+  }
+
+  nonloc::ConcreteInt makeIntVal(const CXXBoolLiteralExpr *E) {
+    return E->getValue() ? nonloc::ConcreteInt(BasicVals.getValue(1, 1, true))
+                         : nonloc::ConcreteInt(BasicVals.getValue(0, 1, true));
+  }
+
+  nonloc::ConcreteInt makeIntVal(const llvm::APSInt& V) {
+    return nonloc::ConcreteInt(BasicVals.getValue(V));
+  }
+
+  loc::ConcreteInt makeIntLocVal(const llvm::APSInt &v) {
+    return loc::ConcreteInt(BasicVals.getValue(v));
+  }
+
+  NonLoc makeIntVal(const llvm::APInt& V, bool isUnsigned) {
+    return nonloc::ConcreteInt(BasicVals.getValue(V, isUnsigned));
+  }
+
+  DefinedSVal makeIntVal(uint64_t X, QualType T) {
+    if (Loc::IsLocType(T))
+      return loc::ConcreteInt(BasicVals.getValue(X, T));
+
+    return nonloc::ConcreteInt(BasicVals.getValue(X, T));
+  }
+
+  NonLoc makeIntVal(uint64_t X, bool isUnsigned) {
+    return nonloc::ConcreteInt(BasicVals.getIntValue(X, isUnsigned));
+  }
+
+  NonLoc makeIntValWithPtrWidth(uint64_t X, bool isUnsigned) {
+    return nonloc::ConcreteInt(BasicVals.getIntWithPtrWidth(X, isUnsigned));
+  }
+
+  NonLoc makeIntVal(uint64_t X, unsigned BitWidth, bool isUnsigned) {
+    return nonloc::ConcreteInt(BasicVals.getValue(X, BitWidth, isUnsigned));
+  }
+
+  NonLoc makeLocAsInteger(Loc V, unsigned Bits) {
+    return nonloc::LocAsInteger(BasicVals.getPersistentSValWithData(V, Bits));
+  }
+
+  NonLoc makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op,
+                    const llvm::APSInt& rhs, QualType T);
+
+  NonLoc makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op,
+                    const SymExpr *rhs, QualType T);
+
+  NonLoc makeTruthVal(bool b, QualType T) {
+    return nonloc::ConcreteInt(BasicVals.getTruthValue(b, T));
+  }
+
+  NonLoc makeTruthVal(bool b) {
+    return nonloc::ConcreteInt(BasicVals.getTruthValue(b));
+  }
+
+  Loc makeNull() {
+    return loc::ConcreteInt(BasicVals.getZeroWithPtrWidth());
+  }
+
+  Loc makeLoc(SymbolRef Sym) {
+    return loc::MemRegionVal(MemMgr.getSymbolicRegion(Sym));
+  }
+
+  Loc makeLoc(const MemRegion* R) {
+    return loc::MemRegionVal(R);
+  }
+
+  Loc makeLoc(const AddrLabelExpr* E) {
+    return loc::GotoLabel(E->getLabel());
+  }
+
+  Loc makeLoc(const llvm::APSInt& V) {
+    return loc::ConcreteInt(BasicVals.getValue(V));
+  }
+};
+} // end clang namespace
+#endif
+
diff --git a/include/clang/CodeGen/CodeGenOptions.h b/include/clang/CodeGen/CodeGenOptions.h
new file mode 100644
index 0000000..54d3ba0
--- /dev/null
+++ b/include/clang/CodeGen/CodeGenOptions.h
@@ -0,0 +1,129 @@
+//===--- CodeGenOptions.h ---------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the CodeGenOptions interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_CODEGEN_CODEGENOPTIONS_H
+#define LLVM_CLANG_CODEGEN_CODEGENOPTIONS_H
+
+#include <string>
+
+namespace clang {
+
+/// CodeGenOptions - Track various options which control how the code
+/// is optimized and passed to the backend.
+class CodeGenOptions {
+public:
+  enum InliningMethod {
+    NoInlining,         // Perform no inlining whatsoever.
+    NormalInlining,     // Use the standard function inlining pass.
+    OnlyAlwaysInlining  // Only run the always inlining pass.
+  };
+
+  enum ObjCDispatchMethodKind {
+    Legacy = 0,
+    NonLegacy = 1,
+    Mixed = 2
+  };
+
+  unsigned AsmVerbose        : 1; /// -dA, -fverbose-asm.
+  unsigned CXAAtExit         : 1; /// Use __cxa_atexit for calling destructors.
+  unsigned CXXCtorDtorAliases: 1; /// Emit complete ctors/dtors as linker
+                                  /// aliases to base ctors when possible.
+  unsigned DataSections      : 1; /// Set when -fdata-sections is enabled
+  unsigned DebugInfo         : 1; /// Should generate deubg info (-g).
+  unsigned DisableFPElim     : 1; /// Set when -fomit-frame-pointer is enabled.
+  unsigned DisableLLVMOpts   : 1; /// Don't run any optimizations, for use in
+                                  /// getting .bc files that correspond to the
+                                  /// internal state before optimizations are
+                                  /// done.
+  unsigned DisableRedZone    : 1; /// Set when -mno-red-zone is enabled.
+  unsigned FunctionSections  : 1; /// Set when -ffunction-sections is enabled
+  unsigned MergeAllConstants : 1; /// Merge identical constants.
+  unsigned NoCommon          : 1; /// Set when -fno-common or C++ is enabled.
+  unsigned NoImplicitFloat   : 1; /// Set when -mno-implicit-float is enabled.
+  unsigned NoZeroInitializedInBSS : 1; /// -fno-zero-initialized-in-bss
+  unsigned ObjCDispatchMethod : 2; /// Method of Objective-C dispatch to use.
+  unsigned OptimizationLevel : 3; /// The -O[0-4] option specified.
+  unsigned OptimizeSize      : 1; /// If -Os is specified.
+  unsigned SoftFloat         : 1; /// -soft-float.
+  unsigned TimePasses        : 1; /// Set when -ftime-report is enabled.
+  unsigned UnitAtATime       : 1; /// Unused. For mirroring GCC optimization
+                                  /// selection.
+  unsigned UnrollLoops       : 1; /// Control whether loops are unrolled.
+  unsigned UnwindTables      : 1; /// Emit unwind tables.
+  unsigned VerifyModule      : 1; /// Control whether the module should be run
+                                  /// through the LLVM Verifier.
+
+  /// The code model to use (-mcmodel).
+  std::string CodeModel;
+
+  /// Enable additional debugging information.
+  std::string DebugPass;
+
+  /// The string to embed in the debug information for the compile unit, if
+  /// non-empty.
+  std::string DwarfDebugFlags;
+
+  /// The ABI to use for passing floating point arguments.
+  std::string FloatABI;
+
+  /// The float precision limit to use, if non-empty.
+  std::string LimitFloatPrecision;
+
+  /// The kind of inlining to perform.
+  InliningMethod Inlining;
+
+  /// The user provided name for the "main file", if non-empty. This is useful
+  /// in situations where the input file name does not match the original input
+  /// file, for example with -save-temps.
+  std::string MainFileName;
+
+  /// The name of the relocation model to use.
+  std::string RelocationModel;
+
+public:
+  CodeGenOptions() {
+    AsmVerbose = 0;
+    CXAAtExit = 1;
+    CXXCtorDtorAliases = 0;
+    DataSections = 0;
+    DebugInfo = 0;
+    DisableFPElim = 0;
+    DisableLLVMOpts = 0;
+    DisableRedZone = 0;
+    FunctionSections = 0;
+    MergeAllConstants = 1;
+    NoCommon = 0;
+    NoImplicitFloat = 0;
+    NoZeroInitializedInBSS = 0;
+    ObjCDispatchMethod = Legacy;
+    OptimizationLevel = 0;
+    OptimizeSize = 0;
+    SoftFloat = 0;
+    TimePasses = 0;
+    UnitAtATime = 1;
+    UnrollLoops = 0;
+    UnwindTables = 0;
+    VerifyModule = 1;
+
+    Inlining = NoInlining;
+    RelocationModel = "pic";
+  }
+
+  ObjCDispatchMethodKind getObjCDispatchMethod() const {
+    return ObjCDispatchMethodKind(ObjCDispatchMethod);
+  }
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/CodeGen/ModuleBuilder.h b/include/clang/CodeGen/ModuleBuilder.h
new file mode 100644
index 0000000..2a3aa6a
--- /dev/null
+++ b/include/clang/CodeGen/ModuleBuilder.h
@@ -0,0 +1,42 @@
+//===--- CodeGen/ModuleBuilder.h - Build LLVM from ASTs ---------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the ModuleBuilder interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_CODEGEN_MODULEBUILDER_H
+#define LLVM_CLANG_CODEGEN_MODULEBUILDER_H
+
+#include "clang/AST/ASTConsumer.h"
+#include <string>
+
+namespace llvm {
+  class LLVMContext;
+  class Module;
+}
+
+namespace clang {
+  class Diagnostic;
+  class LangOptions;
+  class CodeGenOptions;
+
+  class CodeGenerator : public ASTConsumer {
+  public:
+    virtual llvm::Module* GetModule() = 0;
+    virtual llvm::Module* ReleaseModule() = 0;
+  };
+
+  CodeGenerator *CreateLLVMCodeGen(Diagnostic &Diags,
+                                   const std::string &ModuleName,
+                                   const CodeGenOptions &CGO,
+                                   llvm::LLVMContext& C);
+}
+
+#endif
diff --git a/include/clang/Driver/Action.h b/include/clang/Driver/Action.h
new file mode 100644
index 0000000..ab3162a
--- /dev/null
+++ b/include/clang/Driver/Action.h
@@ -0,0 +1,217 @@
+//===--- Action.h - Abstract compilation steps ------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_DRIVER_ACTION_H_
+#define CLANG_DRIVER_ACTION_H_
+
+#include "llvm/ADT/SmallVector.h"
+
+#include "clang/Driver/Types.h"
+#include "clang/Driver/Util.h"
+
+#include "llvm/Support/Casting.h"
+using llvm::isa;
+using llvm::cast;
+using llvm::cast_or_null;
+using llvm::dyn_cast;
+using llvm::dyn_cast_or_null;
+
+namespace clang {
+namespace driver {
+  class Arg;
+
+/// Action - Represent an abstract compilation step to perform.
+///
+/// An action represents an edge in the compilation graph; typically
+/// it is a job to transform an input using some tool.
+///
+/// The current driver is hard wired to expect actions which produce a
+/// single primary output, at least in terms of controlling the
+/// compilation. Actions can produce auxiliary files, but can only
+/// produce a single output to feed into subsequent actions.
+class Action {
+public:
+  typedef ActionList::size_type size_type;
+  typedef ActionList::iterator iterator;
+  typedef ActionList::const_iterator const_iterator;
+
+  enum ActionClass {
+    InputClass = 0,
+    BindArchClass,
+    PreprocessJobClass,
+    PrecompileJobClass,
+    AnalyzeJobClass,
+    CompileJobClass,
+    AssembleJobClass,
+    LinkJobClass,
+    LipoJobClass,
+
+    JobClassFirst=PreprocessJobClass,
+    JobClassLast=LipoJobClass
+  };
+
+  static const char *getClassName(ActionClass AC);
+
+private:
+  ActionClass Kind;
+
+  /// The output type of this action.
+  types::ID Type;
+
+  ActionList Inputs;
+
+  unsigned OwnsInputs : 1;
+
+protected:
+  Action(ActionClass _Kind, types::ID _Type)
+    : Kind(_Kind), Type(_Type), OwnsInputs(true)  {}
+  Action(ActionClass _Kind, Action *Input, types::ID _Type)
+    : Kind(_Kind), Type(_Type), Inputs(&Input, &Input + 1), OwnsInputs(true) {}
+  Action(ActionClass _Kind, const ActionList &_Inputs, types::ID _Type)
+    : Kind(_Kind), Type(_Type), Inputs(_Inputs), OwnsInputs(true) {}
+public:
+  virtual ~Action();
+
+  const char *getClassName() const { return Action::getClassName(getKind()); }
+
+  bool getOwnsInputs() { return OwnsInputs; }
+  void setOwnsInputs(bool Value) { OwnsInputs = Value; }
+
+  ActionClass getKind() const { return Kind; }
+  types::ID getType() const { return Type; }
+
+  ActionList &getInputs() { return Inputs; }
+  const ActionList &getInputs() const { return Inputs; }
+
+  size_type size() const { return Inputs.size(); }
+
+  iterator begin() { return Inputs.begin(); }
+  iterator end() { return Inputs.end(); }
+  const_iterator begin() const { return Inputs.begin(); }
+  const_iterator end() const { return Inputs.end(); }
+
+  static bool classof(const Action *) { return true; }
+};
+
+class InputAction : public Action {
+  const Arg &Input;
+public:
+  InputAction(const Arg &_Input, types::ID _Type);
+
+  const Arg &getInputArg() const { return Input; }
+
+  static bool classof(const Action *A) {
+    return A->getKind() == InputClass;
+  }
+  static bool classof(const InputAction *) { return true; }
+};
+
+class BindArchAction : public Action {
+  /// The architecture to bind, or 0 if the default architecture
+  /// should be bound.
+  const char *ArchName;
+
+public:
+  BindArchAction(Action *Input, const char *_ArchName);
+
+  const char *getArchName() const { return ArchName; }
+
+  static bool classof(const Action *A) {
+    return A->getKind() == BindArchClass;
+  }
+  static bool classof(const BindArchAction *) { return true; }
+};
+
+class JobAction : public Action {
+protected:
+  JobAction(ActionClass Kind, Action *Input, types::ID Type);
+  JobAction(ActionClass Kind, const ActionList &Inputs, types::ID Type);
+
+public:
+  static bool classof(const Action *A) {
+    return (A->getKind() >= JobClassFirst &&
+            A->getKind() <= JobClassLast);
+  }
+  static bool classof(const JobAction *) { return true; }
+};
+
+class PreprocessJobAction : public JobAction {
+public:
+  PreprocessJobAction(Action *Input, types::ID OutputType);
+
+  static bool classof(const Action *A) {
+    return A->getKind() == PreprocessJobClass;
+  }
+  static bool classof(const PreprocessJobAction *) { return true; }
+};
+
+class PrecompileJobAction : public JobAction {
+public:
+  PrecompileJobAction(Action *Input, types::ID OutputType);
+
+  static bool classof(const Action *A) {
+    return A->getKind() == PrecompileJobClass;
+  }
+  static bool classof(const PrecompileJobAction *) { return true; }
+};
+
+class AnalyzeJobAction : public JobAction {
+public:
+  AnalyzeJobAction(Action *Input, types::ID OutputType);
+
+  static bool classof(const Action *A) {
+    return A->getKind() == AnalyzeJobClass;
+  }
+  static bool classof(const AnalyzeJobAction *) { return true; }
+};
+
+class CompileJobAction : public JobAction {
+public:
+  CompileJobAction(Action *Input, types::ID OutputType);
+
+  static bool classof(const Action *A) {
+    return A->getKind() == CompileJobClass;
+  }
+  static bool classof(const CompileJobAction *) { return true; }
+};
+
+class AssembleJobAction : public JobAction {
+public:
+  AssembleJobAction(Action *Input, types::ID OutputType);
+
+  static bool classof(const Action *A) {
+    return A->getKind() == AssembleJobClass;
+  }
+  static bool classof(const AssembleJobAction *) { return true; }
+};
+
+class LinkJobAction : public JobAction {
+public:
+  LinkJobAction(ActionList &Inputs, types::ID Type);
+
+  static bool classof(const Action *A) {
+    return A->getKind() == LinkJobClass;
+  }
+  static bool classof(const LinkJobAction *) { return true; }
+};
+
+class LipoJobAction : public JobAction {
+public:
+  LipoJobAction(ActionList &Inputs, types::ID Type);
+
+  static bool classof(const Action *A) {
+    return A->getKind() == LipoJobClass;
+  }
+  static bool classof(const LipoJobAction *) { return true; }
+};
+
+} // end namespace driver
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Driver/Arg.h b/include/clang/Driver/Arg.h
new file mode 100644
index 0000000..ebf40d4
--- /dev/null
+++ b/include/clang/Driver/Arg.h
@@ -0,0 +1,230 @@
+//===--- Arg.h - Parsed Argument Classes ------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_DRIVER_ARG_H_
+#define CLANG_DRIVER_ARG_H_
+
+#include "llvm/Support/Casting.h"
+using llvm::isa;
+using llvm::cast;
+using llvm::cast_or_null;
+using llvm::dyn_cast;
+using llvm::dyn_cast_or_null;
+
+#include "Util.h"
+#include <vector>
+#include <string>
+
+namespace clang {
+namespace driver {
+  class ArgList;
+  class Option;
+
+  /// Arg - A concrete instance of a particular driver option.
+  ///
+  /// The Arg class encodes just enough information to be able to
+  /// derive the argument values efficiently. In addition, Arg
+  /// instances have an intrusive double linked list which is used by
+  /// ArgList to provide efficient iteration over all instances of a
+  /// particular option.
+  class Arg {
+  public:
+    enum ArgClass {
+      FlagClass = 0,
+      PositionalClass,
+      JoinedClass,
+      SeparateClass,
+      CommaJoinedClass,
+      JoinedAndSeparateClass
+    };
+
+  private:
+    ArgClass Kind;
+
+    /// The option this argument is an instance of.
+    const Option *Opt;
+
+    /// The argument this argument was derived from (during tool chain
+    /// argument translation), if any.
+    const Arg *BaseArg;
+
+    /// The index at which this argument appears in the containing
+    /// ArgList.
+    unsigned Index;
+
+    /// Flag indicating whether this argument was used to effect
+    /// compilation; used for generating "argument unused"
+    /// diagnostics.
+    mutable bool Claimed;
+
+  protected:
+    Arg(ArgClass Kind, const Option *Opt, unsigned Index,
+        const Arg *BaseArg = 0);
+
+  public:
+    Arg(const Arg &);
+    virtual ~Arg();
+
+    ArgClass getKind() const { return Kind; }
+    const Option &getOption() const { return *Opt; }
+    unsigned getIndex() const { return Index; }
+
+    /// getBaseArg - Return the base argument which generated this
+    /// arg; this is either the argument itself or the argument it was
+    /// derived from during tool chain specific argument translation.
+    const Arg &getBaseArg() const {
+      return BaseArg ? *BaseArg : *this;
+    }
+    void setBaseArg(const Arg *_BaseArg) {
+      BaseArg = _BaseArg;
+    }
+
+    bool isClaimed() const { return getBaseArg().Claimed; }
+
+    /// claim - Set the Arg claimed bit.
+
+    // FIXME: We need to deal with derived arguments and set the bit
+    // in the original argument; not the derived one.
+    void claim() const { getBaseArg().Claimed = true; }
+
+    virtual unsigned getNumValues() const = 0;
+    virtual const char *getValue(const ArgList &Args, unsigned N=0) const = 0;
+
+    /// render - Append the argument onto the given array as strings.
+    virtual void render(const ArgList &Args, ArgStringList &Output) const = 0;
+
+    /// renderAsInput - Append the argument, render as an input, onto
+    /// the given array as strings. The distinction is that some
+    /// options only render their values when rendered as a input
+    /// (e.g., Xlinker).
+    void renderAsInput(const ArgList &Args, ArgStringList &Output) const;
+
+    static bool classof(const Arg *) { return true; }
+
+    void dump() const;
+
+    /// getAsString - Return a formatted version of the argument and
+    /// its values, for debugging and diagnostics.
+    std::string getAsString(const ArgList &Args) const;
+  };
+
+  /// FlagArg - An argument with no value.
+  class FlagArg : public Arg {
+  public:
+    FlagArg(const Option *Opt, unsigned Index, const Arg *BaseArg = 0);
+
+    virtual void render(const ArgList &Args, ArgStringList &Output) const;
+
+    virtual unsigned getNumValues() const { return 0; }
+    virtual const char *getValue(const ArgList &Args, unsigned N=0) const;
+
+    static bool classof(const Arg *A) {
+      return A->getKind() == Arg::FlagClass;
+    }
+    static bool classof(const FlagArg *) { return true; }
+  };
+
+  /// PositionalArg - A simple positional argument.
+  class PositionalArg : public Arg {
+  public:
+    PositionalArg(const Option *Opt, unsigned Index, const Arg *BaseArg = 0);
+
+    virtual void render(const ArgList &Args, ArgStringList &Output) const;
+
+    virtual unsigned getNumValues() const { return 1; }
+    virtual const char *getValue(const ArgList &Args, unsigned N=0) const;
+
+    static bool classof(const Arg *A) {
+      return A->getKind() == Arg::PositionalClass;
+    }
+    static bool classof(const PositionalArg *) { return true; }
+  };
+
+  /// JoinedArg - A single value argument where the value is joined
+  /// (suffixed) to the option.
+  class JoinedArg : public Arg {
+  public:
+    JoinedArg(const Option *Opt, unsigned Index, const Arg *BaseArg = 0);
+
+    virtual void render(const ArgList &Args, ArgStringList &Output) const;
+
+    virtual unsigned getNumValues() const { return 1; }
+    virtual const char *getValue(const ArgList &Args, unsigned N=0) const;
+
+    static bool classof(const Arg *A) {
+      return A->getKind() == Arg::JoinedClass;
+    }
+    static bool classof(const JoinedArg *) { return true; }
+  };
+
+  /// SeparateArg - An argument where one or more values follow the
+  /// option specifier immediately in the argument vector.
+  class SeparateArg : public Arg {
+    unsigned NumValues;
+
+  public:
+    SeparateArg(const Option *Opt, unsigned Index, unsigned NumValues,
+                const Arg *BaseArg = 0);
+
+    virtual void render(const ArgList &Args, ArgStringList &Output) const;
+
+    virtual unsigned getNumValues() const { return NumValues; }
+    virtual const char *getValue(const ArgList &Args, unsigned N=0) const;
+
+    static bool classof(const Arg *A) {
+      return A->getKind() == Arg::SeparateClass;
+    }
+    static bool classof(const SeparateArg *) { return true; }
+  };
+
+  /// CommaJoinedArg - An argument with multiple values joined by
+  /// commas and joined (suffixed) to the option specifier.
+  ///
+  /// The key point of this arg is that it renders its values into
+  /// separate arguments, which allows it to be used as a generic
+  /// mechanism for passing arguments through to tools.
+  class CommaJoinedArg : public Arg {
+    std::vector<std::string> Values;
+
+  public:
+    CommaJoinedArg(const Option *Opt, unsigned Index, const char *Str,
+                   const Arg *BaseArg = 0);
+
+    virtual void render(const ArgList &Args, ArgStringList &Output) const;
+
+    virtual unsigned getNumValues() const { return Values.size(); }
+    virtual const char *getValue(const ArgList &Args, unsigned N=0) const;
+
+    static bool classof(const Arg *A) {
+      return A->getKind() == Arg::CommaJoinedClass;
+    }
+    static bool classof(const CommaJoinedArg *) { return true; }
+  };
+
+  /// JoinedAndSeparateArg - An argument with both joined and separate
+  /// values.
+  class JoinedAndSeparateArg : public Arg {
+  public:
+    JoinedAndSeparateArg(const Option *Opt, unsigned Index,
+                         const Arg *BaseArg = 0);
+
+    virtual void render(const ArgList &Args, ArgStringList &Output) const;
+
+    virtual unsigned getNumValues() const { return 2; }
+    virtual const char *getValue(const ArgList &Args, unsigned N=0) const;
+
+    static bool classof(const Arg *A) {
+      return A->getKind() == Arg::JoinedAndSeparateClass;
+    }
+    static bool classof(const JoinedAndSeparateArg *) { return true; }
+  };
+} // end namespace driver
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Driver/ArgList.h b/include/clang/Driver/ArgList.h
new file mode 100644
index 0000000..0a8eaea
--- /dev/null
+++ b/include/clang/Driver/ArgList.h
@@ -0,0 +1,337 @@
+//===--- ArgList.h - Argument List Management ----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_DRIVER_ARGLIST_H_
+#define CLANG_DRIVER_ARGLIST_H_
+
+#include "clang/Driver/OptSpecifier.h"
+#include "clang/Driver/Util.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+
+#include <list>
+#include <string>
+
+namespace llvm {
+  class Twine;
+}
+
+namespace clang {
+namespace driver {
+  class Arg;
+  class ArgList;
+  class Option;
+
+  /// arg_iterator - Iterates through arguments stored inside an ArgList.
+  class arg_iterator {
+    /// The current argument.
+    llvm::SmallVectorImpl<Arg*>::const_iterator Current;
+
+    /// The argument list we are iterating over.
+    const ArgList &Args;
+
+    /// Optional filters on the arguments which will be match. Most clients
+    /// should never want to iterate over arguments without filters, so we won't
+    /// bother to factor this into two separate iterator implementations.
+    //
+    // FIXME: Make efficient; the idea is to provide efficient iteration over
+    // all arguments which match a particular id and then just provide an
+    // iterator combinator which takes multiple iterators which can be
+    // efficiently compared and returns them in order.
+    OptSpecifier Id0, Id1, Id2;
+
+    void SkipToNextArg();
+
+  public:
+    typedef const Arg*                  value_type;
+    typedef const Arg*                  reference;
+    typedef const Arg*                  pointer;
+    typedef std::forward_iterator_tag   iterator_category;
+    typedef std::ptrdiff_t              difference_type;
+
+    arg_iterator(llvm::SmallVectorImpl<Arg*>::const_iterator it,
+                 const ArgList &_Args, OptSpecifier _Id0 = 0U,
+                 OptSpecifier _Id1 = 0U, OptSpecifier _Id2 = 0U)
+      : Current(it), Args(_Args), Id0(_Id0), Id1(_Id1), Id2(_Id2) {
+      SkipToNextArg();
+    }
+
+    operator const Arg*() { return *Current; }
+    reference operator*() const { return *Current; }
+    pointer operator->() const { return *Current; }
+
+    arg_iterator &operator++() {
+      ++Current;
+      SkipToNextArg();
+      return *this;
+    }
+
+    arg_iterator operator++(int) {
+      arg_iterator tmp(*this);
+      ++(*this);
+      return tmp;
+    }
+
+    friend bool operator==(arg_iterator LHS, arg_iterator RHS) {
+      return LHS.Current == RHS.Current;
+    }
+    friend bool operator!=(arg_iterator LHS, arg_iterator RHS) {
+      return !(LHS == RHS);
+    }
+  };
+
+  /// ArgList - Ordered collection of driver arguments.
+  ///
+  /// The ArgList class manages a list of Arg instances as well as
+  /// auxiliary data and convenience methods to allow Tools to quickly
+  /// check for the presence of Arg instances for a particular Option
+  /// and to iterate over groups of arguments.
+  class ArgList {
+  public:
+    typedef llvm::SmallVector<Arg*, 16> arglist_type;
+    typedef arglist_type::iterator iterator;
+    typedef arglist_type::const_iterator const_iterator;
+    typedef arglist_type::reverse_iterator reverse_iterator;
+    typedef arglist_type::const_reverse_iterator const_reverse_iterator;
+
+  private:
+    /// The full list of arguments.
+    arglist_type &Args;
+
+  protected:
+    ArgList(arglist_type &Args);
+
+  public:
+    virtual ~ArgList();
+
+    /// @name Arg Access
+    /// @{
+
+    /// append - Append \arg A to the arg list.
+    void append(Arg *A);
+
+    arglist_type &getArgs() { return Args; }
+    const arglist_type &getArgs() const { return Args; }
+
+    unsigned size() const { return Args.size(); }
+
+    /// @}
+    /// @name Arg Iteration
+    /// @{
+
+    iterator begin() { return Args.begin(); }
+    iterator end() { return Args.end(); }
+
+    reverse_iterator rbegin() { return Args.rbegin(); }
+    reverse_iterator rend() { return Args.rend(); }
+
+    const_iterator begin() const { return Args.begin(); }
+    const_iterator end() const { return Args.end(); }
+
+    const_reverse_iterator rbegin() const { return Args.rbegin(); }
+    const_reverse_iterator rend() const { return Args.rend(); }
+
+    arg_iterator filtered_begin(OptSpecifier Id0 = 0U, OptSpecifier Id1 = 0U,
+                                OptSpecifier Id2 = 0U) const {
+      return arg_iterator(Args.begin(), *this, Id0, Id1, Id2);
+    }
+    arg_iterator filtered_end() const {
+      return arg_iterator(Args.end(), *this);
+    }
+
+    /// @}
+    /// @name Arg Access
+    /// @{
+
+    /// hasArg - Does the arg list contain any option matching \arg Id.
+    ///
+    /// \arg Claim Whether the argument should be claimed, if it exists.
+    bool hasArgNoClaim(OptSpecifier Id) const {
+      return getLastArgNoClaim(Id) != 0;
+    }
+    bool hasArg(OptSpecifier Id) const {
+      return getLastArg(Id) != 0;
+    }
+    bool hasArg(OptSpecifier Id0, OptSpecifier Id1) const {
+      return getLastArg(Id0, Id1) != 0;
+    }
+    bool hasArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2) const {
+      return getLastArg(Id0, Id1, Id2) != 0;
+    }
+
+    /// getLastArg - Return the last argument matching \arg Id, or null.
+    ///
+    /// \arg Claim Whether the argument should be claimed, if it exists.
+    Arg *getLastArgNoClaim(OptSpecifier Id) const;
+    Arg *getLastArg(OptSpecifier Id) const;
+    Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1) const;
+    Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2) const;
+
+    /// getArgString - Return the input argument string at \arg Index.
+    virtual const char *getArgString(unsigned Index) const = 0;
+    /// @name Translation Utilities
+    /// @{
+
+    /// hasFlag - Given an option \arg Pos and its negative form \arg
+    /// Neg, return true if the option is present, false if the
+    /// negation is present, and \arg Default if neither option is
+    /// given. If both the option and its negation are present, the
+    /// last one wins.
+    bool hasFlag(OptSpecifier Pos, OptSpecifier Neg, bool Default=true) const;
+
+    /// AddLastArg - Render only the last argument match \arg Id0, if
+    /// present.
+    void AddLastArg(ArgStringList &Output, OptSpecifier Id0) const;
+
+    /// AddAllArgs - Render all arguments matching the given ids.
+    void AddAllArgs(ArgStringList &Output, OptSpecifier Id0,
+                    OptSpecifier Id1 = 0U, OptSpecifier Id2 = 0U) const;
+
+    /// AddAllArgValues - Render the argument values of all arguments
+    /// matching the given ids.
+    void AddAllArgValues(ArgStringList &Output, OptSpecifier Id0,
+                         OptSpecifier Id1 = 0U, OptSpecifier Id2 = 0U) const;
+
+    /// AddAllArgsTranslated - Render all the arguments matching the
+    /// given ids, but forced to separate args and using the provided
+    /// name instead of the first option value.
+    ///
+    /// \param Joined - If true, render the argument as joined with
+    /// the option specifier.
+    void AddAllArgsTranslated(ArgStringList &Output, OptSpecifier Id0,
+                              const char *Translation,
+                              bool Joined = false) const;
+
+    /// ClaimAllArgs - Claim all arguments which match the given
+    /// option id.
+    void ClaimAllArgs(OptSpecifier Id0) const;
+
+    /// @}
+    /// @name Arg Synthesis
+    /// @{
+
+    /// MakeArgString - Construct a constant string pointer whose
+    /// lifetime will match that of the ArgList.
+    virtual const char *MakeArgString(llvm::StringRef Str) const = 0;
+    const char *MakeArgString(const char *Str) const {
+      return MakeArgString(llvm::StringRef(Str));
+    }
+    const char *MakeArgString(std::string Str) const {
+      return MakeArgString(llvm::StringRef(Str));
+    }
+    const char *MakeArgString(const llvm::Twine &Str) const;
+
+    /// @}
+  };
+
+  class InputArgList : public ArgList  {
+  private:
+    /// The internal list of arguments.
+    arglist_type ActualArgs;
+
+    /// List of argument strings used by the contained Args.
+    ///
+    /// This is mutable since we treat the ArgList as being the list
+    /// of Args, and allow routines to add new strings (to have a
+    /// convenient place to store the memory) via MakeIndex.
+    mutable ArgStringList ArgStrings;
+
+    /// Strings for synthesized arguments.
+    ///
+    /// This is mutable since we treat the ArgList as being the list
+    /// of Args, and allow routines to add new strings (to have a
+    /// convenient place to store the memory) via MakeIndex.
+    mutable std::list<std::string> SynthesizedStrings;
+
+    /// The number of original input argument strings.
+    unsigned NumInputArgStrings;
+
+  public:
+    InputArgList(const char **ArgBegin, const char **ArgEnd);
+    InputArgList(const ArgList &);
+    ~InputArgList();
+
+    virtual const char *getArgString(unsigned Index) const {
+      return ArgStrings[Index];
+    }
+
+    /// getNumInputArgStrings - Return the number of original input
+    /// argument strings.
+    unsigned getNumInputArgStrings() const { return NumInputArgStrings; }
+
+    /// @name Arg Synthesis
+    /// @{
+
+  public:
+    /// MakeIndex - Get an index for the given string(s).
+    unsigned MakeIndex(llvm::StringRef String0) const;
+    unsigned MakeIndex(llvm::StringRef String0, llvm::StringRef String1) const;
+
+    virtual const char *MakeArgString(llvm::StringRef Str) const;
+
+    /// @}
+  };
+
+  /// DerivedArgList - An ordered collection of driver arguments,
+  /// whose storage may be in another argument list.
+  class DerivedArgList : public ArgList {
+    InputArgList &BaseArgs;
+
+    /// The internal list of arguments.
+    arglist_type ActualArgs;
+
+    /// The list of arguments we synthesized.
+    mutable arglist_type SynthesizedArgs;
+
+    /// Is this only a proxy for the base ArgList?
+    bool OnlyProxy;
+
+  public:
+    /// Construct a new derived arg list from \arg BaseArgs.
+    ///
+    /// \param OnlyProxy - If true, this is only a proxy for the base
+    /// list (to adapt the type), and it's Args list is unused.
+    DerivedArgList(InputArgList &BaseArgs, bool OnlyProxy);
+    ~DerivedArgList();
+
+    virtual const char *getArgString(unsigned Index) const {
+      return BaseArgs.getArgString(Index);
+    }
+
+    /// @name Arg Synthesis
+    /// @{
+
+    virtual const char *MakeArgString(llvm::StringRef Str) const;
+
+    /// MakeFlagArg - Construct a new FlagArg for the given option
+    /// \arg Id.
+    Arg *MakeFlagArg(const Arg *BaseArg, const Option *Opt) const;
+
+    /// MakePositionalArg - Construct a new Positional arg for the
+    /// given option \arg Id, with the provided \arg Value.
+    Arg *MakePositionalArg(const Arg *BaseArg, const Option *Opt,
+                           llvm::StringRef Value) const;
+
+    /// MakeSeparateArg - Construct a new Positional arg for the
+    /// given option \arg Id, with the provided \arg Value.
+    Arg *MakeSeparateArg(const Arg *BaseArg, const Option *Opt,
+                         llvm::StringRef Value) const;
+
+    /// MakeJoinedArg - Construct a new Positional arg for the
+    /// given option \arg Id, with the provided \arg Value.
+    Arg *MakeJoinedArg(const Arg *BaseArg, const Option *Opt,
+                       llvm::StringRef Value) const;
+
+    /// @}
+  };
+
+} // end namespace driver
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Driver/CC1Options.h b/include/clang/Driver/CC1Options.h
new file mode 100644
index 0000000..4a8bbe5
--- /dev/null
+++ b/include/clang/Driver/CC1Options.h
@@ -0,0 +1,32 @@
+//===--- CC1Options.h - Clang CC1 Options Table -----------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_DRIVER_CC1OPTIONS_H
+#define CLANG_DRIVER_CC1OPTIONS_H
+
+namespace clang {
+namespace driver {
+  class OptTable;
+
+namespace cc1options {
+  enum ID {
+    OPT_INVALID = 0, // This is not an option ID.
+#define OPTION(NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \
+               HELPTEXT, METAVAR) OPT_##ID,
+#include "clang/Driver/CC1Options.inc"
+    LastOption
+#undef OPTION
+  };
+}
+
+  OptTable *createCC1OptTable();
+}
+}
+
+#endif
diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td
new file mode 100644
index 0000000..18b54ef
--- /dev/null
+++ b/include/clang/Driver/CC1Options.td
@@ -0,0 +1,496 @@
+//===--- CC1Options.td - Options for clang -cc1 ---------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the options accepted by clang -cc1.
+//
+//===----------------------------------------------------------------------===//
+
+// Include the common option parsing interfaces.
+include "OptParser.td"
+
+//===----------------------------------------------------------------------===//
+// Target Options
+//===----------------------------------------------------------------------===//
+
+def target_abi : Separate<"-target-abi">,
+  HelpText<"Target a particular ABI type">;
+def target_cpu : Separate<"-target-cpu">,
+  HelpText<"Target a specific cpu type">;
+def target_feature : Separate<"-target-feature">,
+  HelpText<"Target specific attributes">;
+def triple : Separate<"-triple">,
+  HelpText<"Specify target triple (e.g. i686-apple-darwin9)">;
+def triple_EQ : Joined<"-triple=">, Alias<triple>;
+
+//===----------------------------------------------------------------------===//
+// Analyzer Options
+//===----------------------------------------------------------------------===//
+
+def analysis_CFGDump : Flag<"-cfg-dump">,
+  HelpText<"Display Control-Flow Graphs">;
+def analysis_CFGView : Flag<"-cfg-view">,
+  HelpText<"View Control-Flow Graphs using GraphViz">;
+def analysis_DisplayLiveVariables : Flag<"-dump-live-variables">,
+  HelpText<"Print results of live variable analysis">;
+def analysis_LLVMConventionChecker : Flag<"-analyzer-check-llvm-conventions">,
+  HelpText<"Check code for LLVM codebase conventions (domain-specific)">;
+def analysis_SecuritySyntacticChecks : Flag<"-analyzer-check-security-syntactic">,
+  HelpText<"Perform quick security checks that require no data flow">;
+def analysis_WarnDeadStores : Flag<"-analyzer-check-dead-stores">,
+  HelpText<"Warn about stores to dead variables">;
+def analysis_WarnUninitVals : Flag<"-warn-uninit-values">,
+  HelpText<"Warn about uses of uninitialized variables">;
+def analysis_WarnObjCMethSigs : Flag<"-analyzer-check-objc-methodsigs">,
+  HelpText<"Warn about Objective-C method signatures with type incompatibilities">;
+def analysis_WarnObjCDealloc : Flag<"-analyzer-check-objc-missing-dealloc">,
+  HelpText<"Warn about Objective-C classes that lack a correct implementation of -dealloc">;
+def analysis_WarnObjCUnusedIvars : Flag<"-analyzer-check-objc-unused-ivars">,
+  HelpText<"Warn about private ivars that are never used">;
+def analysis_ObjCMemChecker : Flag<"-analyzer-check-objc-mem">,
+  HelpText<"Run the [Core] Foundation reference count checker">;
+def analysis_WarnSizeofPointer : Flag<"-warn-sizeof-pointer">,
+  HelpText<"Warn about unintended use of sizeof() on pointer expressions">;
+def analysis_InlineCall : Flag<"-inline-call">,
+  HelpText<"Experimental transfer function inlining callees when its definition is available.">;
+
+def analyzer_store : Separate<"-analyzer-store">,
+  HelpText<"Source Code Analysis - Abstract Memory Store Models">;
+def analyzer_store_EQ : Joined<"-analyzer-store=">, Alias<analyzer_store>;
+
+def analyzer_constraints : Separate<"-analyzer-constraints">,
+  HelpText<"Source Code Analysis - Symbolic Constraint Engines">;
+def analyzer_constraints_EQ : Joined<"-analyzer-constraints=">,
+  Alias<analyzer_constraints>;
+
+def analyzer_output : Separate<"-analyzer-output">,
+  HelpText<"Source Code Analysis - Output Options">;
+def analyzer_output_EQ : Joined<"-analyzer-output=">,
+  Alias<analyzer_output>;
+
+def analyzer_opt_analyze_headers : Flag<"-analyzer-opt-analyze-headers">,
+  HelpText<"Force the static analyzer to analyze functions defined in header files">;
+def analyzer_opt_analyze_nested_blocks : Flag<"-analyzer-opt-analyze-nested-blocks">,
+  HelpText<"Analyze the definitions of blocks in addition to functions">;  
+def analyzer_display_progress : Flag<"-analyzer-display-progress">,
+  HelpText<"Emit verbose output about the analyzer's progress">;
+def analyzer_experimental_checks : Flag<"-analyzer-experimental-checks">,
+  HelpText<"Use experimental path-sensitive checks">;
+def analyzer_experimental_internal_checks :
+  Flag<"-analyzer-experimental-internal-checks">,
+  HelpText<"Use new default path-sensitive checks currently in testing">;
+def analyze_function : Separate<"-analyze-function">,
+  HelpText<"Run analysis on specific function">;
+def analyze_function_EQ : Joined<"-analyze-function=">, Alias<analyze_function>;
+def analyzer_eagerly_assume : Flag<"-analyzer-eagerly-assume">,
+  HelpText<"Eagerly assume the truth/falseness of some symbolic constraints">;
+def analyzer_no_purge_dead : Flag<"-analyzer-no-purge-dead">,
+  HelpText<"Don't remove dead symbols, bindings, and constraints before processing a statement">;
+def trim_egraph : Flag<"-trim-egraph">,
+  HelpText<"Only show error-related paths in the analysis graph">;
+def analyzer_viz_egraph_graphviz : Flag<"-analyzer-viz-egraph-graphviz">,
+  HelpText<"Display exploded graph using GraphViz">;
+def analyzer_viz_egraph_ubigraph : Flag<"-analyzer-viz-egraph-ubigraph">,
+  HelpText<"Display exploded graph using Ubigraph">;
+def analyzer_max_nodes : Separate<"-analyzer-max-nodes">,
+  HelpText<"The maximum number of nodes the analyzer can generate">;
+
+//===----------------------------------------------------------------------===//
+// CodeGen Options
+//===----------------------------------------------------------------------===//
+
+def disable_llvm_optzns : Flag<"-disable-llvm-optzns">,
+  HelpText<"Don't run LLVM optimization passes">;
+def disable_llvm_verifier : Flag<"-disable-llvm-verifier">,
+  HelpText<"Don't run the LLVM IR verifier pass">;
+def disable_red_zone : Flag<"-disable-red-zone">,
+  HelpText<"Do not emit code that uses the red zone.">;
+def dwarf_debug_flags : Separate<"-dwarf-debug-flags">,
+  HelpText<"The string to embed in the Dwarf debug flags record.">;
+def g : Flag<"-g">, HelpText<"Generate source level debug information">;
+def fcatch_undefined_behavior : Flag<"-fcatch-undefined-behavior">,
+    HelpText<"Generate runtime checks for undefined behavior.">;
+def fno_common : Flag<"-fno-common">,
+  HelpText<"Compile common globals like normal definitions">;
+def no_implicit_float : Flag<"-no-implicit-float">,
+  HelpText<"Don't generate implicit floating point instructions (x86-only)">;
+def fno_merge_all_constants : Flag<"-fno-merge-all-constants">,
+  HelpText<"Disallow merging of constants.">;
+def fno_threadsafe_statics : Flag<"-fno-threadsafe-statics">,
+  HelpText<"Do not emit code to make initialization of local statics thread safe">;
+def fdump_vtable_layouts : Flag<"-fdump-vtable-layouts">,
+  HelpText<"Dump the layouts of all vtables that will be emitted in a translation unit">;
+def ffunction_sections : Flag<"-ffunction-sections">,
+  HelpText<"Place each function in its own section (ELF Only)">;
+def fdata_sections : Flag<"-fdata-sections">,
+  HelpText<"Place each data in its own section (ELF Only)">;
+def masm_verbose : Flag<"-masm-verbose">,
+  HelpText<"Generate verbose assembly output">;
+def mcode_model : Separate<"-mcode-model">,
+  HelpText<"The code model to use">;
+def mdebug_pass : Separate<"-mdebug-pass">,
+  HelpText<"Enable additional debug output">;
+def mdisable_fp_elim : Flag<"-mdisable-fp-elim">,
+  HelpText<"Disable frame pointer elimination optimization">;
+def mfloat_abi : Separate<"-mfloat-abi">,
+  HelpText<"The float ABI to use">;
+def mlimit_float_precision : Separate<"-mlimit-float-precision">,
+  HelpText<"Limit float precision to the given value">;
+def mno_zero_initialized_in_bss : Flag<"-mno-zero-initialized-in-bss">,
+  HelpText<"Do not put zero initialized data in the BSS">;
+def msoft_float : Flag<"-msoft-float">,
+  HelpText<"Use software floating point">;
+def mrelocation_model : Separate<"-mrelocation-model">,
+  HelpText<"The relocation model to use">;
+def munwind_tables : Flag<"-munwind-tables">,
+  HelpText<"Generate unwinding tables for all functions">;
+def mconstructor_aliases : Flag<"-mconstructor-aliases">,
+  HelpText<"Emit complete constructors and destructors as aliases when possible">;
+def O : Joined<"-O">, HelpText<"Optimization level">;
+def Os : Flag<"-Os">, HelpText<"Optimize for size">;
+
+//===----------------------------------------------------------------------===//
+// Dependency Output Options
+//===----------------------------------------------------------------------===//
+
+def dependency_file : Separate<"-dependency-file">,
+  HelpText<"Filename (or -) to write dependency output to">;
+def sys_header_deps : Flag<"-sys-header-deps">,
+  HelpText<"Include system headers in dependency output">;
+def MQ : Separate<"-MQ">, HelpText<"Specify target to quote for dependency">;
+def MT : Separate<"-MT">, HelpText<"Specify target for dependency">;
+def MP : Flag<"-MP">,
+  HelpText<"Create phony target for each dependency (other than main file)">;
+
+//===----------------------------------------------------------------------===//
+// Diagnostic Options
+//===----------------------------------------------------------------------===//
+
+def dump_build_information : Separate<"-dump-build-information">,
+  MetaVarName<"<filename>">,
+  HelpText<"output a dump of some build information to a file">;
+def fno_show_column : Flag<"-fno-show-column">,
+  HelpText<"Do not include column number on diagnostics">;
+def fno_show_source_location : Flag<"-fno-show-source-location">,
+  HelpText<"Do not include source location information with diagnostics">;
+def fno_caret_diagnostics : Flag<"-fno-caret-diagnostics">,
+  HelpText<"Do not include source line and caret with diagnostics">;
+def fno_diagnostics_fixit_info : Flag<"-fno-diagnostics-fixit-info">,
+  HelpText<"Do not include fixit information in diagnostics">;
+def fdiagnostics_binary : Flag<"-fdiagnostics-binary">;
+def w : Flag<"-w">, HelpText<"Suppress all warnings">;
+def pedantic : Flag<"-pedantic">;
+def pedantic_errors : Flag<"-pedantic-errors">;
+
+// This gets all -W options, including -Werror, -W[no-]system-headers, etc.  The
+// driver has stripped off -Wa,foo etc.  The driver has also translated -W to
+// -Wextra, so we don't need to worry about it.
+def W : Joined<"-W">;
+
+def fdiagnostics_print_source_range_info : Flag<"-fdiagnostics-print-source-range-info">,
+  HelpText<"Print source range spans in numeric form">;
+def fdiagnostics_show_option : Flag<"-fdiagnostics-show-option">,
+  HelpText<"Print diagnostic name with mappable diagnostics">;
+def ftabstop : Separate<"-ftabstop">, MetaVarName<"<N>">,
+  HelpText<"Set the tab stop distance.">;
+def ferror_limit : Separate<"-ferror-limit">, MetaVarName<"<N>">,
+  HelpText<"Set the maximum number of errors to emit before stopping (0 = no limit).">;
+def ftemplate_backtrace_limit : Separate<"-ftemplate-backtrace-limit">, MetaVarName<"<N>">,
+  HelpText<"Set the maximum number of entries to print in a template instantiation backtrace (0 = no limit).">;
+def fmessage_length : Separate<"-fmessage-length">, MetaVarName<"<N>">,
+  HelpText<"Format message diagnostics so that they fit within N columns or fewer, when possible.">;
+def fcolor_diagnostics : Flag<"-fcolor-diagnostics">,
+  HelpText<"Use colors in diagnostics">;
+def Wno_rewrite_macros : Flag<"-Wno-rewrite-macros">,
+  HelpText<"Silence ObjC rewriting warnings">;
+def Wwrite_strings : Flag<"-Wwrite-strings">,
+  HelpText<"Add const qualifier to string literals">;
+def verify : Flag<"-verify">,
+  HelpText<"Verify emitted diagnostics and warnings">;
+
+//===----------------------------------------------------------------------===//
+// Frontend Options
+//===----------------------------------------------------------------------===//
+
+// This isn't normally used, it is just here so we can parse a
+// CompilerInvocation out of a driver-derived argument vector.
+def cc1 : Flag<"-cc1">;
+
+def ast_merge : Separate<"-ast-merge">,
+  MetaVarName<"<ast file>">,
+  HelpText<"Merge the given AST file into the translation unit being compiled.">;
+def code_completion_at : Separate<"-code-completion-at">,
+  MetaVarName<"<file>:<line>:<column>">,
+  HelpText<"Dump code-completion information at a location">;
+def remap_file : Separate<"-remap-file">,
+  MetaVarName<"<from>;<to>">,
+  HelpText<"Replace the contents of the <from> file with the contents of the <to> file">;
+def code_completion_at_EQ : Joined<"-code-completion-at=">,
+  Alias<code_completion_at>;
+def no_code_completion_debug_printer : Flag<"-no-code-completion-debug-printer">,
+  HelpText<"Don't use the \"debug\" code-completion print">;
+def code_completion_macros : Flag<"-code-completion-macros">,
+  HelpText<"Include macros in code-completion results">;
+def disable_free : Flag<"-disable-free">,
+  HelpText<"Disable freeing of memory on exit">;
+def help : Flag<"-help">,
+  HelpText<"Print this help text">;
+def _help : Flag<"--help">, Alias<help>;
+def x : Separate<"-x">, HelpText<"Input language type">;
+def cxx_inheritance_view : Separate<"-cxx-inheritance-view">,
+  MetaVarName<"<class name>">,
+  HelpText<"View C++ inheritance for a specified class">;
+def o : Separate<"-o">, MetaVarName<"<path>">, HelpText<"Specify output file">;
+def load : Separate<"-load">, MetaVarName<"<dsopath>">,
+  HelpText<"Load the named plugin (dynamic shared object)">;
+def plugin : Separate<"-plugin">,
+  HelpText<"Use the named plugin action (use \"help\" to list available options)">;
+def resource_dir : Separate<"-resource-dir">,
+  HelpText<"The directory which holds the compiler resource files">;
+def version : Flag<"-version">,
+  HelpText<"Print the compiler version">;
+def _version : Flag<"--version">, Alias<version>;
+
+def Action_Group : OptionGroup<"<action group>">;
+let Group = Action_Group in {
+
+def Eonly : Flag<"-Eonly">,
+  HelpText<"Just run preprocessor, no output (for timings)">;
+def E : Flag<"-E">,
+  HelpText<"Run preprocessor, emit preprocessed file">;
+def dump_raw_tokens : Flag<"-dump-raw-tokens">,
+  HelpText<"Lex file in raw mode and dump raw tokens">;
+def analyze : Flag<"-analyze">,
+  HelpText<"Run static analysis engine">;
+def dump_tokens : Flag<"-dump-tokens">,
+  HelpText<"Run preprocessor, dump internal rep of tokens">;
+def init_only : Flag<"-init-only">,
+  HelpText<"Only execute frontend initialization">;
+def parse_noop : Flag<"-parse-noop">,
+  HelpText<"Run parser with noop callbacks (for timings)">;
+def fsyntax_only : Flag<"-fsyntax-only">,
+  HelpText<"Run parser and perform semantic analysis">;
+def fixit : Flag<"-fixit">,
+  HelpText<"Apply fix-it advice to the input source">;
+def fixit_EQ : Joined<"-fixit=">,
+  HelpText<"Apply fix-it advice creating a file with the given suffix">;
+def parse_print_callbacks : Flag<"-parse-print-callbacks">,
+  HelpText<"Run parser and print each callback invoked">;
+def emit_html : Flag<"-emit-html">,
+  HelpText<"Output input source as HTML">;
+def ast_print : Flag<"-ast-print">,
+  HelpText<"Build ASTs and then pretty-print them">;
+def ast_print_xml : Flag<"-ast-print-xml">,
+  HelpText<"Build ASTs and then print them in XML format">;
+def ast_dump : Flag<"-ast-dump">,
+  HelpText<"Build ASTs and then debug dump them">;
+def ast_view : Flag<"-ast-view">,
+  HelpText<"Build ASTs and view them with GraphViz">;
+def print_decl_contexts : Flag<"-print-decl-contexts">,
+  HelpText<"Print DeclContexts and their Decls">;
+def emit_pth : Flag<"-emit-pth">,
+  HelpText<"Generate pre-tokenized header file">;
+def emit_pch : Flag<"-emit-pch">,
+  HelpText<"Generate pre-compiled header file">;
+def S : Flag<"-S">,
+  HelpText<"Emit native assembly code">;
+def emit_llvm : Flag<"-emit-llvm">,
+  HelpText<"Build ASTs then convert to LLVM, emit .ll file">;
+def emit_llvm_bc : Flag<"-emit-llvm-bc">,
+  HelpText<"Build ASTs then convert to LLVM, emit .bc file">;
+def emit_llvm_only : Flag<"-emit-llvm-only">,
+  HelpText<"Build ASTs and convert to LLVM, discarding output">;
+def emit_obj : Flag<"-emit-obj">,
+  HelpText<"Emit native object files">;
+def rewrite_test : Flag<"-rewrite-test">,
+  HelpText<"Rewriter playground">;
+def rewrite_objc : Flag<"-rewrite-objc">,
+  HelpText<"Rewrite ObjC into C (code rewriter example)">;
+def rewrite_macros : Flag<"-rewrite-macros">,
+  HelpText<"Expand macros without full preprocessing">;
+
+}
+
+def relocatable_pch : Flag<"-relocatable-pch">,
+  HelpText<"Whether to build a relocatable precompiled header">;
+def print_stats : Flag<"-print-stats">,
+  HelpText<"Print performance metrics and statistics">;
+def ftime_report : Flag<"-ftime-report">,
+  HelpText<"Print the amount of time each phase of compilation takes">;
+
+def fdump_record_layouts : Flag<"-fdump-record-layouts">,
+  HelpText<"Dump record layout information">;
+
+// Generic forwarding to LLVM options. This should only be used for debugging
+// and experimental features.
+def mllvm : Separate<"-mllvm">,
+  HelpText<"Additional arguments to forward to LLVM's option processing">;
+
+//===----------------------------------------------------------------------===//
+// Language Options
+//===----------------------------------------------------------------------===//
+
+def fno_builtin : Flag<"-fno-builtin">,
+  HelpText<"Disable implicit builtin knowledge of functions">;
+def faltivec : Flag<"-faltivec">,
+  HelpText<"Enable AltiVec vector initializer syntax">;
+def fno_access_control : Flag<"-fno-access-control">,
+  HelpText<"Disable C++ access control">;
+def fno_assume_sane_operator_new : Flag<"-fno-assume-sane-operator-new">,
+  HelpText<"Don't assume that C++'s global operator new can't alias any pointer">;
+def fgnu_keywords : Flag<"-fgnu-keywords">,
+  HelpText<"Allow GNU-extension keywords regardless of language standard">;
+def fno_gnu_keywords : Flag<"-fno-gnu-keywords">,
+  HelpText<"Disallow GNU-extension keywords regardless of language standard">;
+def fdollars_in_identifiers : Flag<"-fdollars-in-identifiers">,
+  HelpText<"Allow '$' in identifiers">;
+def fno_dollars_in_identifiers : Flag<"-fno-dollars-in-identifiers">,
+  HelpText<"Disallow '$' in identifiers">;
+def femit_all_decls : Flag<"-femit-all-decls">,
+  HelpText<"Emit all declarations, even if unused">;
+def fblocks : Flag<"-fblocks">,
+  HelpText<"enable the 'blocks' language feature">;
+def fheinous_gnu_extensions : Flag<"-fheinous-gnu-extensions">;  
+def fexceptions : Flag<"-fexceptions">,
+  HelpText<"Enable support for exception handling">;
+def fsjlj_exceptions : Flag<"-fsjlj-exceptions">,
+  HelpText<"Use SjLj style exceptions">;
+def ffreestanding : Flag<"-ffreestanding">,
+  HelpText<"Assert that the compilation takes place in a freestanding environment">;
+def fgnu_runtime : Flag<"-fgnu-runtime">,
+  HelpText<"Generate output compatible with the standard GNU Objective-C runtime">;
+def std_EQ : Joined<"-std=">,
+  HelpText<"Language standard to compile for">;
+def fmath_errno : Flag<"-fmath-errno">,
+  HelpText<"Require math functions to indicate errors by setting errno">;
+def fms_extensions : Flag<"-fms-extensions">,
+  HelpText<"Accept some non-standard constructs used in Microsoft header files ">;
+def main_file_name : Separate<"-main-file-name">,
+  HelpText<"Main file name to use for debug info">;
+def fno_elide_constructors : Flag<"-fno-elide-constructors">,
+  HelpText<"Disable C++ copy constructor elision">;
+def fno_lax_vector_conversions : Flag<"-fno-lax-vector-conversions">,
+  HelpText<"Disallow implicit conversions between vectors with a different number of elements or different element types">;
+def fno_operator_names : Flag<"-fno-operator-names">,
+  HelpText<"Do not treat C++ operator name keywords as synonyms for operators">;
+def fno_signed_char : Flag<"-fno-signed-char">,
+  HelpText<"Char is unsigned">;
+def fno_use_cxa_atexit : Flag<"-fno-use-cxa-atexit">,
+  HelpText<"Don't use __cxa_atexit for calling destructors">;
+def fconstant_string_class : Separate<"-fconstant-string-class">,
+  MetaVarName<"<class name>">,
+  HelpText<"Specify the class to use for constant Objective-C string objects.">;
+def fno_constant_cfstrings : Flag<"-fno-constant-cfstrings">,
+  HelpText<"Enable creation of CodeFoundation-type constant strings">;
+def fobjc_gc : Flag<"-fobjc-gc">,
+  HelpText<"Enable Objective-C garbage collection">;
+def fobjc_gc_only : Flag<"-fobjc-gc-only">,
+  HelpText<"Use GC exclusively for Objective-C related memory management">;
+def fobjc_dispatch_method_EQ : Joined<"-fobjc-dispatch-method=">,
+  HelpText<"Objective-C dispatch method to use">;
+def print_ivar_layout : Flag<"-print-ivar-layout">,
+  HelpText<"Enable Objective-C Ivar layout bitmap print trace">;
+def fobjc_nonfragile_abi : Flag<"-fobjc-nonfragile-abi">,
+  HelpText<"enable objective-c's nonfragile abi">;
+def fobjc_nonfragile_abi2 : Flag<"-fobjc-nonfragile-abi2">,
+  HelpText<"enable objective-c's enhanced nonfragile abi">;
+def ftrapv : Flag<"-ftrapv">,
+  HelpText<"Trap on integer overflow">;
+def pic_level : Separate<"-pic-level">,
+  HelpText<"Value for __PIC__">;
+def pthread : Flag<"-pthread">,
+  HelpText<"Support POSIX threads in generated code">;
+def fpascal_strings : Flag<"-fpascal-strings">,
+  HelpText<"Recognize and construct Pascal-style string literals">;
+def fno_rtti : Flag<"-fno-rtti">,
+  HelpText<"Disable generation of rtti information">;
+def fshort_wchar : Flag<"-fshort-wchar">,
+  HelpText<"Force wchar_t to be a short unsigned int">;
+def static_define : Flag<"-static-define">,
+  HelpText<"Should __STATIC__ be defined">;
+def stack_protector : Separate<"-stack-protector">,
+  HelpText<"Enable stack protectors">;
+def fvisibility : Separate<"-fvisibility">,
+  HelpText<"Default symbol visibility">;
+def ftemplate_depth : Separate<"-ftemplate-depth">,
+  HelpText<"Maximum depth of recursive template instantiation">;
+def trigraphs : Flag<"-trigraphs">,
+  HelpText<"Process trigraph sequences">;
+def fwritable_strings : Flag<"-fwritable-strings">,
+  HelpText<"Store string literals as writable data">;
+def fno_bitfield_type_align : Flag<"-fno-bitfield-type-align">,
+  HelpText<"Ignore bit-field types when aligning structures">;
+
+//===----------------------------------------------------------------------===//
+// Header Search Options
+//===----------------------------------------------------------------------===//
+
+def nostdinc : Flag<"-nostdinc">,
+  HelpText<"Disable standard #include directories">;
+def nostdincxx : Flag<"-nostdinc++">,
+  HelpText<"Disable standard #include directories for the C++ standard library">;
+def nobuiltininc : Flag<"-nobuiltininc">,
+  HelpText<"Disable builtin #include directories">;
+def F : JoinedOrSeparate<"-F">, MetaVarName<"<directory>">,
+  HelpText<"Add directory to framework include search path">;
+def I : JoinedOrSeparate<"-I">, MetaVarName<"<directory>">,
+  HelpText<"Add directory to include search path">;
+def idirafter : JoinedOrSeparate<"-idirafter">, MetaVarName<"<directory>">,
+  HelpText<"Add directory to AFTER include search path">;
+def iquote : JoinedOrSeparate<"-iquote">, MetaVarName<"<directory>">,
+  HelpText<"Add directory to QUOTE include search path">;
+def isystem : JoinedOrSeparate<"-isystem">, MetaVarName<"<directory>">,
+  HelpText<"Add directory to SYSTEM include search path">;
+def iprefix : JoinedOrSeparate<"-iprefix">, MetaVarName<"<prefix>">,
+  HelpText<"Set the -iwithprefix/-iwithprefixbefore prefix">;
+def iwithprefix : JoinedOrSeparate<"-iwithprefix">, MetaVarName<"<dir>">,
+  HelpText<"Set directory to SYSTEM include search path with prefix">;
+def iwithprefixbefore : JoinedOrSeparate<"-iwithprefixbefore">,
+  MetaVarName<"<dir>">,
+  HelpText<"Set directory to include search path with prefix">;
+def isysroot : JoinedOrSeparate<"-isysroot">, MetaVarName<"<dir>">,
+  HelpText<"Set the system root directory (usually /)">;
+def v : Flag<"-v">, HelpText<"Enable verbose output">;
+
+//===----------------------------------------------------------------------===//
+// Preprocessor Options
+//===----------------------------------------------------------------------===//
+
+def D : JoinedOrSeparate<"-D">, MetaVarName<"<macro>">,
+  HelpText<"Predefine the specified macro">;
+def include_ : JoinedOrSeparate<"-include">, MetaVarName<"<file>">, EnumName<"include">,
+  HelpText<"Include file before parsing">;
+def imacros : JoinedOrSeparate<"-imacros">, MetaVarName<"<file>">,
+  HelpText<"Include macros from file before parsing">;
+def include_pch : Separate<"-include-pch">, MetaVarName<"<file>">,
+  HelpText<"Include precompiled header file">;
+def include_pth : Separate<"-include-pth">, MetaVarName<"<file>">,
+  HelpText<"Include file before parsing">;
+def token_cache : Separate<"-token-cache">, MetaVarName<"<path>">,
+  HelpText<"Use specified token cache file">;
+def U : JoinedOrSeparate<"-U">, MetaVarName<"<macro>">,
+  HelpText<"Undefine the specified macro">;
+def undef : Flag<"-undef">, MetaVarName<"<macro>">,
+  HelpText<"undef all system defines">;
+def detailed_preprocessing_record : Flag<"-detailed-preprocessing-record">,
+  HelpText<"include a detailed record of preprocessing actions">;
+  
+//===----------------------------------------------------------------------===//
+// Preprocessed Output Options
+//===----------------------------------------------------------------------===//
+
+def P : Flag<"-P">,
+  HelpText<"Disable linemarker output in -E mode">;
+def C : Flag<"-C">,
+  HelpText<"Enable comment output in -E mode">;
+def CC : Flag<"-CC">,
+  HelpText<"Enable comment output in -E mode, even from macro expansions">;
+def dM : Flag<"-dM">,
+  HelpText<"Print macro definitions in -E mode instead of normal output">;
+def dD : Flag<"-dD">,
+  HelpText<"Print macro definitions in -E mode in addition to normal output">;
diff --git a/include/clang/Driver/CMakeLists.txt b/include/clang/Driver/CMakeLists.txt
new file mode 100644
index 0000000..ed9825b
--- /dev/null
+++ b/include/clang/Driver/CMakeLists.txt
@@ -0,0 +1,11 @@
+set(LLVM_TARGET_DEFINITIONS Options.td)
+tablegen(Options.inc
+         -gen-opt-parser-defs)
+add_custom_target(ClangDriverOptions
+  DEPENDS Options.inc)
+
+set(LLVM_TARGET_DEFINITIONS CC1Options.td)
+tablegen(CC1Options.inc
+         -gen-opt-parser-defs)
+add_custom_target(ClangCC1Options
+  DEPENDS CC1Options.inc)
diff --git a/include/clang/Driver/Compilation.h b/include/clang/Driver/Compilation.h
new file mode 100644
index 0000000..56786a7
--- /dev/null
+++ b/include/clang/Driver/Compilation.h
@@ -0,0 +1,136 @@
+//===--- Compilation.h - Compilation Task Data Structure --------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_DRIVER_COMPILATION_H_
+#define CLANG_DRIVER_COMPILATION_H_
+
+#include "clang/Driver/Job.h"
+#include "clang/Driver/Util.h"
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace llvm {
+  class raw_ostream;
+}
+
+namespace clang {
+namespace driver {
+  class DerivedArgList;
+  class Driver;
+  class InputArgList;
+  class JobList;
+  class ToolChain;
+
+/// Compilation - A set of tasks to perform for a single driver
+/// invocation.
+class Compilation {
+  /// The driver we were created by.
+  const Driver &TheDriver;
+
+  /// The default tool chain.
+  const ToolChain &DefaultToolChain;
+
+  /// The original (untranslated) input argument list.
+  InputArgList *Args;
+
+  /// The list of actions.
+  ActionList Actions;
+
+  /// The root list of jobs.
+  JobList Jobs;
+
+  /// Cache of translated arguments for a particular tool chain.
+  llvm::DenseMap<std::pair<const ToolChain*, const char*>,
+                 DerivedArgList*> TCArgs;
+
+  /// Temporary files which should be removed on exit.
+  ArgStringList TempFiles;
+
+  /// Result files which should be removed on failure.
+  ArgStringList ResultFiles;
+
+public:
+  Compilation(const Driver &D, const ToolChain &DefaultToolChain,
+              InputArgList *Args);
+  ~Compilation();
+
+  const Driver &getDriver() const { return TheDriver; }
+
+  const ToolChain &getDefaultToolChain() const { return DefaultToolChain; }
+
+  const InputArgList &getArgs() const { return *Args; }
+
+  ActionList &getActions() { return Actions; }
+  const ActionList &getActions() const { return Actions; }
+
+  JobList &getJobs() { return Jobs; }
+  const JobList &getJobs() const { return Jobs; }
+
+  const ArgStringList &getTempFiles() const { return TempFiles; }
+
+  const ArgStringList &getResultFiles() const { return ResultFiles; }
+
+  /// getArgsForToolChain - Return the derived argument list for the
+  /// tool chain \arg TC (or the default tool chain, if TC is not
+  /// specified).
+  ///
+  /// \param BoundArch - The bound architecture name, or 0.
+  const DerivedArgList &getArgsForToolChain(const ToolChain *TC,
+                                            const char *BoundArch);
+
+  /// addTempFile - Add a file to remove on exit, and returns its
+  /// argument.
+  const char *addTempFile(const char *Name) {
+    TempFiles.push_back(Name);
+    return Name;
+  }
+
+  /// addResultFile - Add a file to remove on failure, and returns its
+  /// argument.
+  const char *addResultFile(const char *Name) {
+    ResultFiles.push_back(Name);
+    return Name;
+  }
+
+  /// CleanupFileList - Remove the files in the given list.
+  ///
+  /// \param IssueErrors - Report failures as errors.
+  /// \return Whether all files were removed successfully.
+  bool CleanupFileList(const ArgStringList &Files,
+                       bool IssueErrors=false) const;
+
+  /// PrintJob - Print one job in -### format.
+  ///
+  /// \param OS - The stream to print on.
+  /// \param J - The job to print.
+  /// \param Terminator - A string to print at the end of the line.
+  /// \param Quote - Should separate arguments be quoted.
+  void PrintJob(llvm::raw_ostream &OS, const Job &J,
+                const char *Terminator, bool Quote) const;
+
+  /// ExecuteCommand - Execute an actual command.
+  ///
+  /// \param FailingCommand - For non-zero results, this will be set to the
+  /// Command which failed, if any.
+  /// \return The result code of the subprocess.
+  int ExecuteCommand(const Command &C, const Command *&FailingCommand) const;
+
+  /// ExecuteJob - Execute a single job.
+  ///
+  /// \param FailingCommand - For non-zero results, this will be set to the
+  /// Command which failed.
+  /// \return The accumulated result code of the job.
+  int ExecuteJob(const Job &J, const Command *&FailingCommand) const;
+};
+
+} // end namespace driver
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Driver/Driver.h b/include/clang/Driver/Driver.h
new file mode 100644
index 0000000..90c3a0d
--- /dev/null
+++ b/include/clang/Driver/Driver.h
@@ -0,0 +1,318 @@
+//===--- Driver.h - Clang GCC Compatible Driver -----------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_DRIVER_DRIVER_H_
+#define CLANG_DRIVER_DRIVER_H_
+
+#include "clang/Basic/Diagnostic.h"
+
+#include "clang/Driver/Phases.h"
+#include "clang/Driver/Util.h"
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/System/Path.h" // FIXME: Kill when CompilationInfo
+                              // lands.
+#include <list>
+#include <set>
+#include <string>
+
+namespace llvm {
+  class raw_ostream;
+}
+namespace clang {
+namespace driver {
+  class Action;
+  class ArgList;
+  class Compilation;
+  class HostInfo;
+  class InputArgList;
+  class InputInfo;
+  class JobAction;
+  class OptTable;
+  class PipedJob;
+  class ToolChain;
+
+/// Driver - Encapsulate logic for constructing compilation processes
+/// from a set of gcc-driver-like command line arguments.
+class Driver {
+  OptTable *Opts;
+
+  Diagnostic &Diags;
+
+public:
+  // Diag - Forwarding function for diagnostics.
+  DiagnosticBuilder Diag(unsigned DiagID) const {
+    return Diags.Report(DiagID);
+  }
+
+  // FIXME: Privatize once interface is stable.
+public:
+  /// The name the driver was invoked as.
+  std::string Name;
+
+  /// The path the driver executable was in, as invoked from the
+  /// command line.
+  std::string Dir;
+
+  /// The path to the compiler resource directory.
+  std::string ResourceDir;
+
+  /// A prefix directory used to emulated a limited subset of GCC's '-Bprefix'
+  /// functionality.
+  /// FIXME: This type of customization should be removed in favor of the
+  /// universal driver when it is ready.
+  std::string PrefixDir;
+
+  /// Default host triple.
+  std::string DefaultHostTriple;
+
+  /// Default name for linked images (e.g., "a.out").
+  std::string DefaultImageName;
+
+  /// Driver title to use with help.
+  std::string DriverTitle;
+
+  /// Host information for the platform the driver is running as. This
+  /// will generally be the actual host platform, but not always.
+  const HostInfo *Host;
+
+  /// Information about the host which can be overriden by the user.
+  std::string HostBits, HostMachine, HostSystem, HostRelease;
+
+  /// Name to use when calling the generic gcc.
+  std::string CCCGenericGCCName;
+
+  /// The file to log CC_PRINT_OPTIONS output to, if enabled.
+  const char *CCPrintOptionsFilename;
+
+  /// Whether the driver should follow g++ like behavior.
+  unsigned CCCIsCXX : 1;
+
+  /// Echo commands while executing (in -v style).
+  unsigned CCCEcho : 1;
+
+  /// Only print tool bindings, don't build any jobs.
+  unsigned CCCPrintBindings : 1;
+
+  /// Set CC_PRINT_OPTIONS mode, which is like -v but logs the commands to
+  /// CCPrintOptionsFilename or to stderr.
+  unsigned CCPrintOptions : 1;
+
+private:
+  /// Whether to check that input files exist when constructing compilation
+  /// jobs.
+  unsigned CheckInputsExist : 1;
+
+  /// Use the clang compiler where possible.
+  unsigned CCCUseClang : 1;
+
+  /// Use clang for handling C++ and Objective-C++ inputs.
+  unsigned CCCUseClangCXX : 1;
+
+  /// Use clang as a preprocessor (clang's preprocessor will still be
+  /// used where an integrated CPP would).
+  unsigned CCCUseClangCPP : 1;
+
+public:
+  /// Use lazy precompiled headers for PCH support.
+  unsigned CCCUsePCH : 1;
+
+private:
+  /// Only use clang for the given architectures (only used when
+  /// non-empty).
+  std::set<llvm::Triple::ArchType> CCCClangArchs;
+
+  /// Certain options suppress the 'no input files' warning.
+  bool SuppressMissingInputWarning : 1;
+
+  std::list<std::string> TempFiles;
+  std::list<std::string> ResultFiles;
+
+public:
+  Driver(llvm::StringRef _Name, llvm::StringRef _Dir,
+         llvm::StringRef _DefaultHostTriple,
+         llvm::StringRef _DefaultImageName,
+         bool IsProduction, bool CXXIsProduction,
+         Diagnostic &_Diags);
+  ~Driver();
+
+  /// @name Accessors
+  /// @{
+
+  const OptTable &getOpts() const { return *Opts; }
+
+  const Diagnostic &getDiags() const { return Diags; }
+
+  bool getCheckInputsExist() const { return CheckInputsExist; }
+
+  void setCheckInputsExist(bool Value) { CheckInputsExist = Value; }
+
+  const std::string &getTitle() { return DriverTitle; }
+  void setTitle(std::string Value) { DriverTitle = Value; }
+
+  /// @}
+  /// @name Primary Functionality
+  /// @{
+
+  /// BuildCompilation - Construct a compilation object for a command
+  /// line argument vector.
+  ///
+  /// \return A compilation, or 0 if none was built for the given
+  /// argument vector. A null return value does not necessarily
+  /// indicate an error condition, the diagnostics should be queried
+  /// to determine if an error occurred.
+  Compilation *BuildCompilation(int argc, const char **argv);
+
+  /// @name Driver Steps
+  /// @{
+
+  /// ParseArgStrings - Parse the given list of strings into an
+  /// ArgList.
+  InputArgList *ParseArgStrings(const char **ArgBegin, const char **ArgEnd);
+
+  /// BuildActions - Construct the list of actions to perform for the
+  /// given arguments, which are only done for a single architecture.
+  ///
+  /// \param Args - The input arguments.
+  /// \param Actions - The list to store the resulting actions onto.
+  void BuildActions(const ArgList &Args, ActionList &Actions) const;
+
+  /// BuildUniversalActions - Construct the list of actions to perform
+  /// for the given arguments, which may require a universal build.
+  ///
+  /// \param Args - The input arguments.
+  /// \param Actions - The list to store the resulting actions onto.
+  void BuildUniversalActions(const ArgList &Args, ActionList &Actions) const;
+
+  /// BuildJobs - Bind actions to concrete tools and translate
+  /// arguments to form the list of jobs to run.
+  ///
+  /// \arg C - The compilation that is being built.
+  void BuildJobs(Compilation &C) const;
+
+  /// ExecuteCompilation - Execute the compilation according to the command line
+  /// arguments and return an appropriate exit code.
+  ///
+  /// This routine handles additional processing that must be done in addition
+  /// to just running the subprocesses, for example reporting errors, removing
+  /// temporary files, etc.
+  int ExecuteCompilation(const Compilation &C) const;
+
+  /// @}
+  /// @name Helper Methods
+  /// @{
+
+  /// PrintActions - Print the list of actions.
+  void PrintActions(const Compilation &C) const;
+
+  /// PrintHelp - Print the help text.
+  ///
+  /// \param ShowHidden - Show hidden options.
+  void PrintHelp(bool ShowHidden) const;
+
+  /// PrintOptions - Print the list of arguments.
+  void PrintOptions(const ArgList &Args) const;
+
+  /// PrintVersion - Print the driver version.
+  void PrintVersion(const Compilation &C, llvm::raw_ostream &OS) const;
+
+  /// GetFilePath - Lookup \arg Name in the list of file search paths.
+  ///
+  /// \arg TC - The tool chain for additional information on
+  /// directories to search.
+  //
+  // FIXME: This should be in CompilationInfo.
+  std::string GetFilePath(const char *Name, const ToolChain &TC) const;
+
+  /// GetProgramPath - Lookup \arg Name in the list of program search
+  /// paths.
+  ///
+  /// \arg TC - The provided tool chain for additional information on
+  /// directories to search.
+  ///
+  /// \arg WantFile - False when searching for an executable file, otherwise
+  /// true.  Defaults to false.
+  //
+  // FIXME: This should be in CompilationInfo.
+  std::string GetProgramPath(const char *Name, const ToolChain &TC,
+                              bool WantFile = false) const;
+
+  /// HandleImmediateArgs - Handle any arguments which should be
+  /// treated before building actions or binding tools.
+  ///
+  /// \return Whether any compilation should be built for this
+  /// invocation.
+  bool HandleImmediateArgs(const Compilation &C);
+
+  /// ConstructAction - Construct the appropriate action to do for
+  /// \arg Phase on the \arg Input, taking in to account arguments
+  /// like -fsyntax-only or --analyze.
+  Action *ConstructPhaseAction(const ArgList &Args, phases::ID Phase,
+                               Action *Input) const;
+
+
+  /// BuildJobsForAction - Construct the jobs to perform for the
+  /// action \arg A.
+  void BuildJobsForAction(Compilation &C,
+                          const Action *A,
+                          const ToolChain *TC,
+                          const char *BoundArch,
+                          bool CanAcceptPipe,
+                          bool AtTopLevel,
+                          const char *LinkingOutput,
+                          InputInfo &Result) const;
+
+  /// GetNamedOutputPath - Return the name to use for the output of
+  /// the action \arg JA. The result is appended to the compilation's
+  /// list of temporary or result files, as appropriate.
+  ///
+  /// \param C - The compilation.
+  /// \param JA - The action of interest.
+  /// \param BaseInput - The original input file that this action was
+  /// triggered by.
+  /// \param AtTopLevel - Whether this is a "top-level" action.
+  const char *GetNamedOutputPath(Compilation &C,
+                                 const JobAction &JA,
+                                 const char *BaseInput,
+                                 bool AtTopLevel) const;
+
+  /// GetTemporaryPath - Return the pathname of a temporary file to
+  /// use as part of compilation; the file will have the given suffix.
+  ///
+  /// GCC goes to extra lengths here to be a bit more robust.
+  std::string GetTemporaryPath(const char *Suffix) const;
+
+  /// GetHostInfo - Construct a new host info object for the given
+  /// host triple.
+  const HostInfo *GetHostInfo(const char *HostTriple) const;
+
+  /// ShouldUseClangCompilar - Should the clang compiler be used to
+  /// handle this action.
+  bool ShouldUseClangCompiler(const Compilation &C, const JobAction &JA,
+                              const llvm::Triple &ArchName) const;
+
+  /// @}
+
+  /// GetReleaseVersion - Parse (([0-9]+)(.([0-9]+)(.([0-9]+)?))?)? and
+  /// return the grouped values as integers. Numbers which are not
+  /// provided are set to 0.
+  ///
+  /// \return True if the entire string was parsed (9.2), or all
+  /// groups were parsed (10.3.5extrastuff). HadExtra is true if all
+  /// groups were parsed but extra characters remain at the end.
+  static bool GetReleaseVersion(const char *Str, unsigned &Major,
+                                unsigned &Minor, unsigned &Micro,
+                                bool &HadExtra);
+};
+
+} // end namespace driver
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Driver/DriverDiagnostic.h b/include/clang/Driver/DriverDiagnostic.h
new file mode 100644
index 0000000..d4a9da7
--- /dev/null
+++ b/include/clang/Driver/DriverDiagnostic.h
@@ -0,0 +1,27 @@
+//===--- DiagnosticDriver.h - Diagnostics for libdriver ---------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_DRIVERDIAGNOSTIC_H
+#define LLVM_CLANG_DRIVERDIAGNOSTIC_H
+
+#include "clang/Basic/Diagnostic.h"
+
+namespace clang {
+  namespace diag {
+    enum {
+#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE) ENUM,
+#define DRIVERSTART
+#include "clang/Basic/DiagnosticDriverKinds.inc"
+#undef DIAG
+      NUM_BUILTIN_DRIVER_DIAGNOSTICS
+    };
+  }  // end namespace diag
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Driver/HostInfo.h b/include/clang/Driver/HostInfo.h
new file mode 100644
index 0000000..ca1ee9a
--- /dev/null
+++ b/include/clang/Driver/HostInfo.h
@@ -0,0 +1,91 @@
+//===--- HostInfo.h - Host specific information -----------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_DRIVER_HOSTINFO_H_
+#define CLANG_DRIVER_HOSTINFO_H_
+
+#include "clang/Driver/Types.h"
+#include "llvm/ADT/Triple.h"
+#include <string>
+
+namespace clang {
+namespace driver {
+  class ArgList;
+  class Driver;
+  class ToolChain;
+
+/// HostInfo - Config information about a particular host which may interact
+/// with driver behavior.
+///
+/// The host information is used for controlling the parts of the driver which
+/// interact with the platform the driver is ostensibly being run from. For
+/// testing purposes, the HostInfo used by the driver may differ from the actual
+/// host.
+class HostInfo {
+protected:
+  const Driver &TheDriver;
+  const llvm::Triple Triple;
+
+  HostInfo(const Driver &D, const llvm::Triple &_Triple);
+
+public:
+  virtual ~HostInfo();
+
+  const Driver &getDriver() const { return TheDriver; }
+
+  const llvm::Triple& getTriple() const { return Triple; }
+  std::string getArchName() const { return Triple.getArchName(); }
+  std::string getPlatformName() const { return Triple.getVendorName(); }
+  std::string getOSName() const { return Triple.getOSName(); }
+
+  /// useDriverDriver - Whether the driver should act as a driver driver for
+  /// this host and support -arch, -Xarch, etc.
+  virtual bool useDriverDriver() const = 0;
+
+  /// lookupTypeForExtension - Return the default language type to use for the
+  /// given extension.
+  virtual types::ID lookupTypeForExtension(const char *Ext) const = 0;
+
+  /// CreateToolChain - Construct the toolchain to use for this host (which the
+  /// host retains ownership of).
+  ///
+  /// \param Args - The argument list, which may be used to alter the default
+  /// toolchain, for example in the presence of -m32 or -m64.
+  ///
+  /// \param ArchName - The architecture to return a toolchain for, or 0 if
+  /// unspecified. This will only ever be non-zero for hosts which support a
+  /// driver driver.
+
+  // FIXME: Pin down exactly what the HostInfo is allowed to use Args
+  // for here. Currently this is for -m32 / -m64 defaulting.
+  virtual ToolChain *CreateToolChain(const ArgList &Args,
+                                     const char *ArchName=0) const = 0;
+};
+
+const HostInfo *createAuroraUXHostInfo(const Driver &D,
+                                       const llvm::Triple& Triple);
+const HostInfo *createDarwinHostInfo(const Driver &D,
+                                     const llvm::Triple& Triple);
+const HostInfo *createOpenBSDHostInfo(const Driver &D,
+                                      const llvm::Triple& Triple);
+const HostInfo *createFreeBSDHostInfo(const Driver &D,
+                                      const llvm::Triple& Triple);
+const HostInfo *createDragonFlyHostInfo(const Driver &D,
+                                        const llvm::Triple& Triple);
+const HostInfo *createLinuxHostInfo(const Driver &D,
+                                    const llvm::Triple& Triple);
+const HostInfo *createTCEHostInfo(const Driver &D, 
+                                  const llvm::Triple& Triple);
+const HostInfo *createUnknownHostInfo(const Driver &D,
+                                      const llvm::Triple& Triple);
+
+} // end namespace driver
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Driver/Job.h b/include/clang/Driver/Job.h
new file mode 100644
index 0000000..5a789fb
--- /dev/null
+++ b/include/clang/Driver/Job.h
@@ -0,0 +1,157 @@
+//===--- Job.h - Commands to Execute ----------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_DRIVER_JOB_H_
+#define CLANG_DRIVER_JOB_H_
+
+#include "clang/Driver/Util.h"
+#include "llvm/ADT/SmallVector.h"
+
+#include "llvm/Support/Casting.h"
+using llvm::isa;
+using llvm::cast;
+using llvm::cast_or_null;
+using llvm::dyn_cast;
+using llvm::dyn_cast_or_null;
+
+namespace clang {
+namespace driver {
+class Command;
+class Tool;
+
+class Job {
+public:
+  enum JobClass {
+    CommandClass,
+    PipedJobClass,
+    JobListClass
+  };
+
+private:
+  JobClass Kind;
+
+protected:
+  Job(JobClass _Kind) : Kind(_Kind) {}
+public:
+  virtual ~Job();
+
+  JobClass getKind() const { return Kind; }
+
+  /// addCommand - Append a command to the current job, which must be
+  /// either a piped job or a job list.
+  void addCommand(Command *C);
+
+  static bool classof(const Job *) { return true; }
+};
+
+  /// Command - An executable path/name and argument vector to
+  /// execute.
+class Command : public Job {
+  /// Source - The action which caused the creation of this job.
+  const Action &Source;
+
+  /// Tool - The tool which caused the creation of this job.
+  const Tool &Creator;
+
+  /// The executable to run.
+  const char *Executable;
+
+  /// The list of program arguments (not including the implicit first
+  /// argument, which will be the executable).
+  ArgStringList Arguments;
+
+public:
+  Command(const Action &_Source, const Tool &_Creator, const char *_Executable,
+          const ArgStringList &_Arguments);
+
+  /// getSource - Return the Action which caused the creation of this job.
+  const Action &getSource() const { return Source; }
+
+  /// getCreator - Return the Tool which caused the creation of this job.
+  const Tool &getCreator() const { return Creator; }
+
+  const char *getExecutable() const { return Executable; }
+
+  const ArgStringList &getArguments() const { return Arguments; }
+
+  static bool classof(const Job *J) {
+    return J->getKind() == CommandClass;
+  }
+  static bool classof(const Command *) { return true; }
+};
+
+  /// PipedJob - A list of Commands which should be executed together
+  /// with their standard inputs and outputs connected.
+class PipedJob : public Job {
+public:
+  typedef llvm::SmallVector<Command*, 4> list_type;
+  typedef list_type::size_type size_type;
+  typedef list_type::iterator iterator;
+  typedef list_type::const_iterator const_iterator;
+
+private:
+  list_type Commands;
+
+public:
+  PipedJob();
+  virtual ~PipedJob();
+
+  /// Add a command to the piped job (taking ownership).
+  void addCommand(Command *C) { Commands.push_back(C); }
+
+  const list_type &getCommands() const { return Commands; }
+
+  size_type size() const { return Commands.size(); }
+  iterator begin() { return Commands.begin(); }
+  const_iterator begin() const { return Commands.begin(); }
+  iterator end() { return Commands.end(); }
+  const_iterator end() const { return Commands.end(); }
+
+  static bool classof(const Job *J) {
+    return J->getKind() == PipedJobClass;
+  }
+  static bool classof(const PipedJob *) { return true; }
+};
+
+  /// JobList - A sequence of jobs to perform.
+class JobList : public Job {
+public:
+  typedef llvm::SmallVector<Job*, 4> list_type;
+  typedef list_type::size_type size_type;
+  typedef list_type::iterator iterator;
+  typedef list_type::const_iterator const_iterator;
+
+private:
+  list_type Jobs;
+
+public:
+  JobList();
+  virtual ~JobList();
+
+  /// Add a job to the list (taking ownership).
+  void addJob(Job *J) { Jobs.push_back(J); }
+
+  const list_type &getJobs() const { return Jobs; }
+
+  size_type size() const { return Jobs.size(); }
+  iterator begin() { return Jobs.begin(); }
+  const_iterator begin() const { return Jobs.begin(); }
+  iterator end() { return Jobs.end(); }
+  const_iterator end() const { return Jobs.end(); }
+
+  static bool classof(const Job *J) {
+    return J->getKind() == JobListClass;
+  }
+  static bool classof(const JobList *) { return true; }
+};
+
+} // end namespace driver
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Driver/Makefile b/include/clang/Driver/Makefile
new file mode 100644
index 0000000..18f3e58
--- /dev/null
+++ b/include/clang/Driver/Makefile
@@ -0,0 +1,16 @@
+LEVEL = ../../../../..
+BUILT_SOURCES = Options.inc CC1Options.inc
+
+TABLEGEN_INC_FILES_COMMON = 1
+
+include $(LEVEL)/Makefile.common
+
+$(ObjDir)/Options.inc.tmp : Options.td OptParser.td $(TBLGEN) $(ObjDir)/.dir
+	$(Echo) "Building Clang Driver Option tables with tblgen"
+	$(Verb) $(TableGen) -gen-opt-parser-defs -o $(call SYSPATH, $@) $<
+
+$(ObjDir)/CC1Options.inc.tmp : CC1Options.td OptParser.td $(TBLGEN) $(ObjDir)/.dir
+	$(Echo) "Building Clang CC1 Option tables with tblgen"
+	$(Verb) $(TableGen) -gen-opt-parser-defs -o $(call SYSPATH, $@) $<
+
+
diff --git a/include/clang/Driver/OptParser.td b/include/clang/Driver/OptParser.td
new file mode 100644
index 0000000..a9f4289
--- /dev/null
+++ b/include/clang/Driver/OptParser.td
@@ -0,0 +1,135 @@
+//===--- OptParser.td - Common Option Parsing Interfaces ------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the common interfaces used by the option parsing TableGen
+//  backend.
+//
+//===----------------------------------------------------------------------===//
+
+// Define the kinds of options.
+
+class OptionKind<string name, int predecence = 0, bit sentinel = 0> {
+  string Name = name;
+  // The kind precedence, kinds with lower precedence are matched first.
+  int Precedence = predecence;
+  // Indicate a sentinel option.
+  bit Sentinel = sentinel;
+}
+
+// An option group.
+def KIND_GROUP : OptionKind<"Group">;
+// The input option kind.
+def KIND_INPUT : OptionKind<"Input", 1, 1>;
+// The unknown option kind.
+def KIND_UNKNOWN : OptionKind<"Unknown", 2, 1>;
+// A flag with no values.
+def KIND_FLAG : OptionKind<"Flag">;
+// An option which prefixes its (single) value.
+def KIND_JOINED : OptionKind<"Joined", 1>;
+// An option which is followed by its value.
+def KIND_SEPARATE : OptionKind<"Separate">;
+// An option followed by its values, which are separated by commas.
+def KIND_COMMAJOINED : OptionKind<"CommaJoined">;
+// An option which is which takes multiple (separate) arguments.
+def KIND_MULTIARG : OptionKind<"MultiArg">;
+// An option which is either joined to its (non-empty) value, or followed by its
+// value.
+def KIND_JOINED_OR_SEPARATE : OptionKind<"JoinedOrSeparate">;
+// An option which is both joined to its (first) value, and followed by its
+// (second) value.
+def KIND_JOINED_AND_SEPARATE : OptionKind<"JoinedAndSeparate">;
+
+// Define the option flags.
+
+class OptionFlag {}
+
+// DriverOption - The option is a "driver" option, and should not be forwarded
+// to gcc.
+def DriverOption : OptionFlag;
+
+// LinkerInput - The option is a linker input.
+def LinkerInput : OptionFlag;
+
+// NoArgumentUnused - Don't report argument unused warnings for this option; this
+// is useful for options like -static or -dynamic which a user may always end up
+// passing, even if the platform defaults to (or only supports) that option.
+def NoArgumentUnused : OptionFlag;
+
+// RenderAsInput - The option should not render the name when rendered as an
+// input (i.e., the option is rendered as values).
+def RenderAsInput : OptionFlag;
+
+// RenderJoined - The option should be rendered joined, even if separate (only
+// sensible on single value separate options).
+def RenderJoined : OptionFlag;
+
+// RenderSeparate - The option should be rendered separately, even if joined
+// (only sensible on joined options).
+def RenderSeparate : OptionFlag;
+
+// Unsupported - The option is unsupported, and the driver will reject command
+// lines that use it.
+def Unsupported : OptionFlag;
+
+// HelpHidden - The option should not be displayed in --help, even if it has
+// help text. Clients *can* use this in conjuction with the OptTable::PrintHelp
+// arguments to implement hidden help groups.
+def HelpHidden : OptionFlag;
+
+// Define the option group class.
+
+class OptionGroup<string name> {
+  string EnumName = ?; // Uses the def name if undefined.
+  string Name = name;
+  string HelpText = ?;
+  OptionGroup Group = ?;
+}
+
+// Define the option class.
+
+class Option<string name, OptionKind kind> {
+  string EnumName = ?; // Uses the def name if undefined.
+  string Name = name;
+  OptionKind Kind = kind;
+  // Used by MultiArg option kind.
+  int NumArgs = 0;
+  string HelpText = ?;
+  string MetaVarName = ?;
+  list<OptionFlag> Flags = [];
+  OptionGroup Group = ?;
+  Option Alias = ?;
+}
+
+// Helpers for defining options.
+
+class Flag<string name> : Option<name, KIND_FLAG>;
+class Joined<string name> : Option<name, KIND_JOINED>;
+class Separate<string name> : Option<name, KIND_SEPARATE>;
+class CommaJoined<string name> : Option<name, KIND_COMMAJOINED>;
+class MultiArg<string name, int numargs> : Option<name, KIND_MULTIARG> {
+  int NumArgs = numargs;
+}
+class JoinedOrSeparate<string name> : Option<name, KIND_JOINED_OR_SEPARATE>;
+class JoinedAndSeparate<string name> : Option<name, KIND_JOINED_AND_SEPARATE>;
+
+// Mix-ins for adding optional attributes.
+
+class Alias<Option alias> { Option Alias = alias; }
+class EnumName<string name> { string EnumName = name; }
+class Flags<list<OptionFlag> flags> { list<OptionFlag> Flags = flags; }
+class Group<OptionGroup group> { OptionGroup Group = group; }
+class HelpText<string text> { string HelpText = text; }
+class MetaVarName<string name> { string MetaVarName = name; }
+
+// Predefined options.
+
+// FIXME: Have generator validate that these appear in correct position (and
+// aren't duplicated).
+def INPUT : Option<"<input>", KIND_INPUT>, Flags<[DriverOption]>;
+def UNKNOWN : Option<"<unknown>", KIND_UNKNOWN>;
diff --git a/include/clang/Driver/OptSpecifier.h b/include/clang/Driver/OptSpecifier.h
new file mode 100644
index 0000000..bb1cd17
--- /dev/null
+++ b/include/clang/Driver/OptSpecifier.h
@@ -0,0 +1,39 @@
+//===--- OptSpecifier.h - Option Specifiers ---------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_DRIVER_OPTSPECIFIER_H
+#define CLANG_DRIVER_OPTSPECIFIER_H
+
+namespace clang {
+namespace driver {
+  class Option;
+
+  /// OptSpecifier - Wrapper class for abstracting references to option IDs.
+  class OptSpecifier {
+    unsigned ID;
+
+  private:
+    explicit OptSpecifier(bool); // DO NOT IMPLEMENT
+
+  public:
+    OptSpecifier() : ID(0) {}
+    /*implicit*/ OptSpecifier(unsigned _ID) : ID(_ID) {}
+    /*implicit*/ OptSpecifier(const Option *Opt);
+
+    bool isValid() const { return ID != 0; }
+
+    unsigned getID() const { return ID; }
+
+    bool operator==(OptSpecifier Opt) const { return ID == Opt.getID(); }
+    bool operator!=(OptSpecifier Opt) const { return !(*this == Opt); }
+  };
+}
+}
+
+#endif
diff --git a/include/clang/Driver/OptTable.h b/include/clang/Driver/OptTable.h
new file mode 100644
index 0000000..edae75c
--- /dev/null
+++ b/include/clang/Driver/OptTable.h
@@ -0,0 +1,188 @@
+//===--- OptTable.h - Option Table ------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_DRIVER_OPTTABLE_H
+#define CLANG_DRIVER_OPTTABLE_H
+
+#include "clang/Driver/OptSpecifier.h"
+#include <cassert>
+
+namespace llvm {
+  class raw_ostream;
+}
+
+namespace clang {
+namespace driver {
+namespace options {
+  enum DriverFlag {
+    DriverOption     = (1 << 0),
+    HelpHidden       = (1 << 1),
+    LinkerInput      = (1 << 2),
+    NoArgumentUnused = (1 << 3),
+    RenderAsInput    = (1 << 4),
+    RenderJoined     = (1 << 5),
+    RenderSeparate   = (1 << 6),
+    Unsupported      = (1 << 7)
+  };
+}
+
+  class Arg;
+  class InputArgList;
+  class Option;
+
+  /// OptTable - Provide access to the Option info table.
+  ///
+  /// The OptTable class provides a layer of indirection which allows Option
+  /// instance to be created lazily. In the common case, only a few options will
+  /// be needed at runtime; the OptTable class maintains enough information to
+  /// parse command lines without instantiating Options, while letting other
+  /// parts of the driver still use Option instances where convenient.
+  class OptTable {
+  public:
+    /// Info - Entry for a single option instance in the option data table.
+    struct Info {
+      const char *Name;
+      const char *HelpText;
+      const char *MetaVar;
+      unsigned char Kind;
+      unsigned char Flags;
+      unsigned char Param;
+      unsigned short GroupID;
+      unsigned short AliasID;
+    };
+
+  private:
+    /// The static option information table.
+    const Info *OptionInfos;
+    unsigned NumOptionInfos;
+
+    /// The lazily constructed options table, indexed by option::ID - 1.
+    mutable Option **Options;
+
+    /// Prebound input option instance.
+    const Option *TheInputOption;
+
+    /// Prebound unknown option instance.
+    const Option *TheUnknownOption;
+
+    /// The index of the first option which can be parsed (i.e., is not a
+    /// special option like 'input' or 'unknown', and is not an option group).
+    unsigned FirstSearchableIndex;
+
+  private:
+    const Info &getInfo(OptSpecifier Opt) const {
+      unsigned id = Opt.getID();
+      assert(id > 0 && id - 1 < getNumOptions() && "Invalid Option ID.");
+      return OptionInfos[id - 1];
+    }
+
+    Option *CreateOption(unsigned id) const;
+
+  protected:
+    OptTable(const Info *_OptionInfos, unsigned _NumOptionInfos);
+  public:
+    ~OptTable();
+
+    /// getNumOptions - Return the total number of option classes.
+    unsigned getNumOptions() const { return NumOptionInfos; }
+
+    /// getOption - Get the given \arg id's Option instance, lazily creating it
+    /// if necessary.
+    ///
+    /// \return The option, or null for the INVALID option id.
+    const Option *getOption(OptSpecifier Opt) const {
+      unsigned id = Opt.getID();
+      if (id == 0)
+        return 0;
+
+      assert((unsigned) (id - 1) < getNumOptions() && "Invalid ID.");
+      Option *&Entry = Options[id - 1];
+      if (!Entry)
+        Entry = CreateOption(id);
+      return Entry;
+    }
+
+    /// getOptionName - Lookup the name of the given option.
+    const char *getOptionName(OptSpecifier id) const {
+      return getInfo(id).Name;
+    }
+
+    /// getOptionKind - Get the kind of the given option.
+    unsigned getOptionKind(OptSpecifier id) const {
+      return getInfo(id).Kind;
+    }
+
+    /// getOptionGroupID - Get the group id for the given option.
+    unsigned getOptionGroupID(OptSpecifier id) const {
+      return getInfo(id).GroupID;
+    }
+
+    /// isOptionHelpHidden - Should the help for the given option be hidden by
+    /// default.
+    bool isOptionHelpHidden(OptSpecifier id) const {
+      return getInfo(id).Flags & options::HelpHidden;
+    }
+
+    /// getOptionHelpText - Get the help text to use to describe this option.
+    const char *getOptionHelpText(OptSpecifier id) const {
+      return getInfo(id).HelpText;
+    }
+
+    /// getOptionMetaVar - Get the meta-variable name to use when describing
+    /// this options values in the help text.
+    const char *getOptionMetaVar(OptSpecifier id) const {
+      return getInfo(id).MetaVar;
+    }
+
+    /// ParseOneArg - Parse a single argument; returning the new argument and
+    /// updating Index.
+    ///
+    /// \param [in] [out] Index - The current parsing position in the argument
+    /// string list; on return this will be the index of the next argument
+    /// string to parse.
+    ///
+    /// \return - The parsed argument, or 0 if the argument is missing values
+    /// (in which case Index still points at the conceptual next argument string
+    /// to parse).
+    Arg *ParseOneArg(const InputArgList &Args, unsigned &Index) const;
+
+    /// ParseArgs - Parse an list of arguments into an InputArgList.
+    ///
+    /// The resulting InputArgList will reference the strings in [ArgBegin,
+    /// ArgEnd), and their lifetime should extend past that of the returned
+    /// InputArgList.
+    ///
+    /// The only error that can occur in this routine is if an argument is
+    /// missing values; in this case \arg MissingArgCount will be non-zero.
+    ///
+    /// \param ArgBegin - The beginning of the argument vector.
+    /// \param ArgEnd - The end of the argument vector.
+    /// \param MissingArgIndex - On error, the index of the option which could
+    /// not be parsed.
+    /// \param MissingArgCount - On error, the number of missing options.
+    /// \return - An InputArgList; on error this will contain all the options
+    /// which could be parsed.
+    InputArgList *ParseArgs(const char **ArgBegin,
+                            const char **ArgEnd,
+                            unsigned &MissingArgIndex,
+                            unsigned &MissingArgCount) const;
+
+    /// PrintHelp - Render the help text for an option table.
+    ///
+    /// \param OS - The stream to write the help text to.
+    /// \param Name - The name to use in the usage line.
+    /// \param Title - The title to use in the usage line.
+    /// \param ShowHidden - Whether help-hidden arguments should be shown.
+    void PrintHelp(llvm::raw_ostream &OS, const char *Name,
+                   const char *Title, bool ShowHidden = false) const;
+  };
+}
+}
+
+#endif
diff --git a/include/clang/Driver/Option.h b/include/clang/Driver/Option.h
new file mode 100644
index 0000000..08b94b1
--- /dev/null
+++ b/include/clang/Driver/Option.h
@@ -0,0 +1,311 @@
+//===--- Option.h - Abstract Driver Options ---------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_DRIVER_OPTION_H_
+#define CLANG_DRIVER_OPTION_H_
+
+#include "clang/Driver/OptSpecifier.h"
+#include "llvm/Support/Casting.h"
+using llvm::isa;
+using llvm::cast;
+using llvm::cast_or_null;
+using llvm::dyn_cast;
+using llvm::dyn_cast_or_null;
+
+namespace clang {
+namespace driver {
+  class Arg;
+  class InputArgList;
+  class OptionGroup;
+
+  /// Option - Abstract representation for a single form of driver
+  /// argument.
+  ///
+  /// An Option class represents a form of option that the driver
+  /// takes, for example how many arguments the option has and how
+  /// they can be provided. Individual option instances store
+  /// additional information about what group the option is a member
+  /// of (if any), if the option is an alias, and a number of
+  /// flags. At runtime the driver parses the command line into
+  /// concrete Arg instances, each of which corresponds to a
+  /// particular Option instance.
+  class Option {
+  public:
+    enum OptionClass {
+      GroupClass = 0,
+      InputClass,
+      UnknownClass,
+      FlagClass,
+      JoinedClass,
+      SeparateClass,
+      CommaJoinedClass,
+      MultiArgClass,
+      JoinedOrSeparateClass,
+      JoinedAndSeparateClass
+    };
+
+  private:
+    OptionClass Kind;
+
+    /// The option ID.
+    OptSpecifier ID;
+
+    /// The option name.
+    const char *Name;
+
+    /// Group this option is a member of, if any.
+    const OptionGroup *Group;
+
+    /// Option that this is an alias for, if any.
+    const Option *Alias;
+
+    /// Unsupported options will not be rejected.
+    bool Unsupported : 1;
+
+    /// Treat this option like a linker input?
+    bool LinkerInput : 1;
+
+    /// When rendering as an input, don't render the option.
+
+    // FIXME: We should ditch the render/renderAsInput distinction.
+    bool NoOptAsInput : 1;
+
+    /// Always render this option as separate form its value.
+    bool ForceSeparateRender : 1;
+
+    /// Always render this option joined with its value.
+    bool ForceJoinedRender : 1;
+
+    /// This option is only consumed by the driver.
+    bool DriverOption : 1;
+
+    /// This option should not report argument unused errors.
+    bool NoArgumentUnused : 1;
+
+  protected:
+    Option(OptionClass Kind, OptSpecifier ID, const char *Name,
+           const OptionGroup *Group, const Option *Alias);
+  public:
+    virtual ~Option();
+
+    unsigned getID() const { return ID.getID(); }
+    OptionClass getKind() const { return Kind; }
+    const char *getName() const { return Name; }
+    const OptionGroup *getGroup() const { return Group; }
+    const Option *getAlias() const { return Alias; }
+
+    bool isUnsupported() const { return Unsupported; }
+    void setUnsupported(bool Value) { Unsupported = Value; }
+
+    bool isLinkerInput() const { return LinkerInput; }
+    void setLinkerInput(bool Value) { LinkerInput = Value; }
+
+    bool hasNoOptAsInput() const { return NoOptAsInput; }
+    void setNoOptAsInput(bool Value) { NoOptAsInput = Value; }
+
+    bool hasForceSeparateRender() const { return ForceSeparateRender; }
+    void setForceSeparateRender(bool Value) { ForceSeparateRender = Value; }
+
+    bool hasForceJoinedRender() const { return ForceJoinedRender; }
+    void setForceJoinedRender(bool Value) { ForceJoinedRender = Value; }
+
+    bool isDriverOption() const { return DriverOption; }
+    void setDriverOption(bool Value) { DriverOption = Value; }
+
+    bool hasNoArgumentUnused() const { return NoArgumentUnused; }
+    void setNoArgumentUnused(bool Value) { NoArgumentUnused = Value; }
+
+    bool hasForwardToGCC() const { return !DriverOption && !LinkerInput; }
+
+    /// getUnaliasedOption - Return the final option this option
+    /// aliases (itself, if the option has no alias).
+    const Option *getUnaliasedOption() const {
+      if (Alias) return Alias->getUnaliasedOption();
+      return this;
+    }
+
+    /// getRenderName - Return the name to use when rendering this
+    /// option.
+    const char *getRenderName() const {
+      return getUnaliasedOption()->getName();
+    }
+
+    /// matches - Predicate for whether this option is part of the
+    /// given option (which may be a group).
+    ///
+    /// Note that matches against options which are an alias should never be
+    /// done -- aliases do not participate in matching and so such a query will
+    /// always be false.
+    bool matches(OptSpecifier ID) const;
+
+    /// accept - Potentially accept the current argument, returning a
+    /// new Arg instance, or 0 if the option does not accept this
+    /// argument (or the argument is missing values).
+    ///
+    /// If the option accepts the current argument, accept() sets
+    /// Index to the position where argument parsing should resume
+    /// (even if the argument is missing values).
+    virtual Arg *accept(const InputArgList &Args, unsigned &Index) const = 0;
+
+    void dump() const;
+
+    static bool classof(const Option *) { return true; }
+  };
+
+  /// OptionGroup - A set of options which are can be handled uniformly
+  /// by the driver.
+  class OptionGroup : public Option {
+  public:
+    OptionGroup(OptSpecifier ID, const char *Name, const OptionGroup *Group);
+
+    virtual Arg *accept(const InputArgList &Args, unsigned &Index) const;
+
+    static bool classof(const Option *O) {
+      return O->getKind() == Option::GroupClass;
+    }
+    static bool classof(const OptionGroup *) { return true; }
+  };
+
+  // Dummy option classes.
+
+  /// InputOption - Dummy option class for representing driver inputs.
+  class InputOption : public Option {
+  public:
+    InputOption(OptSpecifier ID);
+
+    virtual Arg *accept(const InputArgList &Args, unsigned &Index) const;
+
+    static bool classof(const Option *O) {
+      return O->getKind() == Option::InputClass;
+    }
+    static bool classof(const InputOption *) { return true; }
+  };
+
+  /// UnknownOption - Dummy option class for represent unknown arguments.
+  class UnknownOption : public Option {
+  public:
+    UnknownOption(OptSpecifier ID);
+
+    virtual Arg *accept(const InputArgList &Args, unsigned &Index) const;
+
+    static bool classof(const Option *O) {
+      return O->getKind() == Option::UnknownClass;
+    }
+    static bool classof(const UnknownOption *) { return true; }
+  };
+
+  // Normal options.
+
+  class FlagOption : public Option {
+  public:
+    FlagOption(OptSpecifier ID, const char *Name, const OptionGroup *Group,
+               const Option *Alias);
+
+    virtual Arg *accept(const InputArgList &Args, unsigned &Index) const;
+
+    static bool classof(const Option *O) {
+      return O->getKind() == Option::FlagClass;
+    }
+    static bool classof(const FlagOption *) { return true; }
+  };
+
+  class JoinedOption : public Option {
+  public:
+    JoinedOption(OptSpecifier ID, const char *Name, const OptionGroup *Group,
+                 const Option *Alias);
+
+    virtual Arg *accept(const InputArgList &Args, unsigned &Index) const;
+
+    static bool classof(const Option *O) {
+      return O->getKind() == Option::JoinedClass;
+    }
+    static bool classof(const JoinedOption *) { return true; }
+  };
+
+  class SeparateOption : public Option {
+  public:
+    SeparateOption(OptSpecifier ID, const char *Name,
+                   const OptionGroup *Group, const Option *Alias);
+
+    virtual Arg *accept(const InputArgList &Args, unsigned &Index) const;
+
+    static bool classof(const Option *O) {
+      return O->getKind() == Option::SeparateClass;
+    }
+    static bool classof(const SeparateOption *) { return true; }
+  };
+
+  class CommaJoinedOption : public Option {
+  public:
+    CommaJoinedOption(OptSpecifier ID, const char *Name,
+                      const OptionGroup *Group, const Option *Alias);
+
+    virtual Arg *accept(const InputArgList &Args, unsigned &Index) const;
+
+    static bool classof(const Option *O) {
+      return O->getKind() == Option::CommaJoinedClass;
+    }
+    static bool classof(const CommaJoinedOption *) { return true; }
+  };
+
+  // FIXME: Fold MultiArgOption into SeparateOption?
+
+  /// MultiArgOption - An option which takes multiple arguments (these
+  /// are always separate arguments).
+  class MultiArgOption : public Option {
+    unsigned NumArgs;
+
+  public:
+    MultiArgOption(OptSpecifier ID, const char *Name, const OptionGroup *Group,
+                   const Option *Alias, unsigned NumArgs);
+
+    unsigned getNumArgs() const { return NumArgs; }
+
+    virtual Arg *accept(const InputArgList &Args, unsigned &Index) const;
+
+    static bool classof(const Option *O) {
+      return O->getKind() == Option::MultiArgClass;
+    }
+    static bool classof(const MultiArgOption *) { return true; }
+  };
+
+  /// JoinedOrSeparateOption - An option which either literally
+  /// prefixes its (non-empty) value, or is follwed by a value.
+  class JoinedOrSeparateOption : public Option {
+  public:
+    JoinedOrSeparateOption(OptSpecifier ID, const char *Name,
+                           const OptionGroup *Group, const Option *Alias);
+
+    virtual Arg *accept(const InputArgList &Args, unsigned &Index) const;
+
+    static bool classof(const Option *O) {
+      return O->getKind() == Option::JoinedOrSeparateClass;
+    }
+    static bool classof(const JoinedOrSeparateOption *) { return true; }
+  };
+
+  /// JoinedAndSeparateOption - An option which literally prefixes its
+  /// value and is followed by another value.
+  class JoinedAndSeparateOption : public Option {
+  public:
+    JoinedAndSeparateOption(OptSpecifier ID, const char *Name,
+                            const OptionGroup *Group, const Option *Alias);
+
+    virtual Arg *accept(const InputArgList &Args, unsigned &Index) const;
+
+    static bool classof(const Option *O) {
+      return O->getKind() == Option::JoinedAndSeparateClass;
+    }
+    static bool classof(const JoinedAndSeparateOption *) { return true; }
+  };
+
+} // end namespace driver
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Driver/Options.h b/include/clang/Driver/Options.h
new file mode 100644
index 0000000..ac312cd
--- /dev/null
+++ b/include/clang/Driver/Options.h
@@ -0,0 +1,32 @@
+//===--- Options.h - Option info & table ------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_DRIVER_OPTIONS_H
+#define CLANG_DRIVER_OPTIONS_H
+
+namespace clang {
+namespace driver {
+  class OptTable;
+
+namespace options {
+  enum ID {
+    OPT_INVALID = 0, // This is not an option ID.
+#define OPTION(NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \
+               HELPTEXT, METAVAR) OPT_##ID,
+#include "clang/Driver/Options.inc"
+    LastOption
+#undef OPTION
+  };
+}
+
+  OptTable *createDriverOptTable();
+}
+}
+
+#endif
diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td
new file mode 100644
index 0000000..1487121
--- /dev/null
+++ b/include/clang/Driver/Options.td
@@ -0,0 +1,708 @@
+//===--- DriverOptions.td - Options for clang -----------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the options accepted by clang.
+//
+//===----------------------------------------------------------------------===//
+
+// Include the common option parsing interfaces.
+include "OptParser.td"
+
+/////////
+// Groups
+
+// Meta-group which defines
+def CompileOnly_Group     : OptionGroup<"<CompileOnly group>">;
+
+def I_Group               : OptionGroup<"<I group>">, Group<CompileOnly_Group>;
+def M_Group               : OptionGroup<"<M group>">, Group<CompileOnly_Group>;
+def T_Group               : OptionGroup<"<T group>">;
+def O_Group               : OptionGroup<"<O group>">, Group<CompileOnly_Group>;
+def W_Group               : OptionGroup<"<W group>">, Group<CompileOnly_Group>;
+def X_Group               : OptionGroup<"<X group>">;
+def a_Group               : OptionGroup<"<a group>">;
+def d_Group               : OptionGroup<"<d group>">;
+def f_Group               : OptionGroup<"<f group>">, Group<CompileOnly_Group>;
+def g_Group               : OptionGroup<"<g group>">;
+def i_Group               : OptionGroup<"<i group>">, Group<CompileOnly_Group>;
+def clang_i_Group         : OptionGroup<"<clang i group>">, Group<i_Group>;
+def m_Group               : OptionGroup<"<m group>">, Group<CompileOnly_Group>;
+def m_x86_Features_Group  : OptionGroup<"<m x86 features group>">, Group<m_Group>;
+def u_Group               : OptionGroup<"<u group>">;
+
+def pedantic_Group        : OptionGroup<"<pedantic group>">,
+  Group<CompileOnly_Group>;
+
+// Temporary groups for clang options which we know we don't support,
+// but don't want to verbosely warn the user about.
+def clang_ignored_f_Group : OptionGroup<"<clang ignored f group>">,
+  Group<f_Group>;
+def clang_ignored_m_Group : OptionGroup<"<clang ignored m group>">,
+  Group<m_Group>;
+
+/////////
+// Options
+
+// The internal option ID must be a valid C++ identifier and results in a
+// clang::driver::options::OPT_XX enum constant for XX.
+//
+// We want to unambiguously be able to refer to options from the driver source
+// code, for this reason the option name is mangled into an ID. This mangling
+// isn't guaranteed to have an inverse, but for practical purposes it does.
+//
+// The mangling scheme is to ignore the leading '-', and perform the following
+// substitutions:
+//   _ => __
+//   - => _
+//   # => _HASH
+//   , => _COMMA
+//   = => _EQ
+//   C++ => CXX
+//   . => _
+
+// Developer Driver Options
+
+def ccc_Group : OptionGroup<"<clang internal options>">;
+def ccc_driver_Group : OptionGroup<"<clang driver internal options>">,
+  Group<ccc_Group>, HelpText<"DRIVER OPTIONS">;
+def ccc_debug_Group : OptionGroup<"<clang debug/development internal options>">,
+  Group<ccc_Group>, HelpText<"DEBUG/DEVELOPMENT OPTIONS">;
+
+class CCCDriverOpt : Group<ccc_driver_Group>, Flags<[DriverOption, HelpHidden]>;
+def ccc_cxx : Flag<"-ccc-cxx">, CCCDriverOpt,
+  HelpText<"Act as a C++ driver">;
+def ccc_echo : Flag<"-ccc-echo">, CCCDriverOpt,
+  HelpText<"Echo commands before running them">;
+def ccc_gcc_name : Separate<"-ccc-gcc-name">, CCCDriverOpt,
+  HelpText<"Name for native GCC compiler">,
+  MetaVarName<"<gcc-path>">;
+def ccc_clang_cxx : Flag<"-ccc-clang-cxx">, CCCDriverOpt,
+  HelpText<"Enable the clang compiler for C++">;
+def ccc_no_clang_cxx : Flag<"-ccc-no-clang-cxx">, CCCDriverOpt,
+  HelpText<"Disable the clang compiler for C++">;
+def ccc_no_clang : Flag<"-ccc-no-clang">, CCCDriverOpt,
+  HelpText<"Disable the clang compiler">;
+def ccc_no_clang_cpp : Flag<"-ccc-no-clang-cpp">, CCCDriverOpt,
+  HelpText<"Disable the clang preprocessor">;
+def ccc_clang_archs : Separate<"-ccc-clang-archs">, CCCDriverOpt,
+  HelpText<"Comma separate list of architectures to use the clang compiler for">,
+  MetaVarName<"<arch-list>">;
+def ccc_pch_is_pch : Flag<"-ccc-pch-is-pch">, CCCDriverOpt,
+  HelpText<"Use lazy PCH for precompiled headers">;
+def ccc_pch_is_pth : Flag<"-ccc-pch-is-pth">, CCCDriverOpt,
+  HelpText<"Use pretokenized headers for precompiled headers">;
+
+class CCCDebugOpt : Group<ccc_debug_Group>, Flags<[DriverOption, HelpHidden]>;
+def ccc_host_triple : Separate<"-ccc-host-triple">, CCCDebugOpt,
+  HelpText<"Simulate running on the given target">;
+def ccc_install_dir : Separate<"-ccc-install-dir">, CCCDebugOpt,
+  HelpText<"Simulate installation in the given directory">;
+def ccc_print_options : Flag<"-ccc-print-options">, CCCDebugOpt,
+  HelpText<"Dump parsed command line arguments">;
+def ccc_print_phases : Flag<"-ccc-print-phases">, CCCDebugOpt,
+  HelpText<"Dump list of actions to perform">;
+def ccc_print_bindings : Flag<"-ccc-print-bindings">, CCCDebugOpt,
+  HelpText<"Show bindings of tools to actions">;
+
+// Make sure all other -ccc- options are rejected.
+def ccc_ : Joined<"-ccc-">, Group<ccc_Group>, Flags<[Unsupported]>;
+
+// Standard Options
+
+def _HASH_HASH_HASH : Flag<"-###">, Flags<[DriverOption]>,
+    HelpText<"Print the commands to run for this compilation">;
+def A : JoinedOrSeparate<"-A">;
+def B : JoinedOrSeparate<"-B">;
+def CC : Flag<"-CC">;
+def C : Flag<"-C">;
+def D : JoinedOrSeparate<"-D">, Group<CompileOnly_Group>;
+def E : Flag<"-E">, Flags<[DriverOption]>,
+  HelpText<"Only run the preprocessor">;
+def F : JoinedOrSeparate<"-F">;
+def H : Flag<"-H">;
+def I_ : Flag<"-I-">, Group<I_Group>;
+def I : JoinedOrSeparate<"-I">, Group<I_Group>;
+def L : JoinedOrSeparate<"-L">;
+def MD : Flag<"-MD">, Group<M_Group>;
+def MF : JoinedOrSeparate<"-MF">, Group<M_Group>;
+def MG : Flag<"-MG">, Group<M_Group>;
+def MMD : Flag<"-MMD">, Group<M_Group>;
+def MM : Flag<"-MM">, Group<M_Group>;
+def MP : Flag<"-MP">, Group<M_Group>;
+def MQ : JoinedOrSeparate<"-MQ">, Group<M_Group>;
+def MT : JoinedOrSeparate<"-MT">, Group<M_Group>;
+def Mach : Flag<"-Mach">;
+def M : Flag<"-M">, Group<M_Group>;
+def O4 : Joined<"-O4">, Group<O_Group>;
+def ObjCXX : Flag<"-ObjC++">, Flags<[DriverOption]>,
+  HelpText<"Treat source input files as Objective-C++ inputs">;
+def ObjC : Flag<"-ObjC">, Flags<[DriverOption]>,
+  HelpText<"Treat source input files as Objective-C inputs">;
+def O : Joined<"-O">, Group<O_Group>;
+def P : Flag<"-P">;
+def Qn : Flag<"-Qn">;
+def Qunused_arguments : Flag<"-Qunused-arguments">, Flags<[DriverOption]>,
+  HelpText<"Don't emit warning for unused driver arguments">;
+def Q : Flag<"-Q">;
+def R : Flag<"-R">;
+def S : Flag<"-S">, Flags<[DriverOption]>,
+  HelpText<"Only run preprocess and compilation steps">;
+def Tbss : JoinedOrSeparate<"-Tbss">, Group<T_Group>;
+def Tdata : JoinedOrSeparate<"-Tdata">, Group<T_Group>;
+def Ttext : JoinedOrSeparate<"-Ttext">, Group<T_Group>;
+def T : JoinedOrSeparate<"-T">, Group<T_Group>;
+def U : JoinedOrSeparate<"-U">, Group<CompileOnly_Group>;
+def V : JoinedOrSeparate<"-V">, Flags<[DriverOption, Unsupported]>;
+def Wa_COMMA : CommaJoined<"-Wa,">,
+  HelpText<"Pass the comma separated arguments in <arg> to the assembler">,
+  MetaVarName<"<arg>">;
+def Wall : Flag<"-Wall">, Group<W_Group>;
+def Wextra : Flag<"-Wextra">, Group<W_Group>;
+def Wl_COMMA : CommaJoined<"-Wl,">, Flags<[LinkerInput, RenderAsInput]>,
+  HelpText<"Pass the comma separated arguments in <arg> to the linker">,
+  MetaVarName<"<arg>">;
+def Wno_nonportable_cfstrings : Joined<"-Wno-nonportable-cfstrings">, Group<W_Group>;
+def Wnonportable_cfstrings : Joined<"-Wnonportable-cfstrings">, Group<W_Group>;
+def Wp_COMMA : CommaJoined<"-Wp,">,
+  HelpText<"Pass the comma separated arguments in <arg> to the preprocessor">,
+  MetaVarName<"<arg>">;
+def W_Joined : Joined<"-W">, Group<W_Group>;
+def Xanalyzer : Separate<"-Xanalyzer">,
+  HelpText<"Pass <arg> to the static analyzer">, MetaVarName<"<arg>">;
+def Xarch__ : JoinedAndSeparate<"-Xarch_">, Flags<[DriverOption]>;
+def Xassembler : Separate<"-Xassembler">,
+  HelpText<"Pass <arg> to the assembler">, MetaVarName<"<arg>">;
+def Xclang : Separate<"-Xclang">,
+  HelpText<"Pass <arg> to the clang compiler">, MetaVarName<"<arg>">;
+def Xlinker : Separate<"-Xlinker">, Flags<[LinkerInput, RenderAsInput]>,
+  HelpText<"Pass <arg> to the linker">, MetaVarName<"<arg>">;
+def Xpreprocessor : Separate<"-Xpreprocessor">,
+  HelpText<"Pass <arg> to the preprocessor">, MetaVarName<"<arg>">;
+def X_Flag : Flag<"-X">;
+def X_Joined : Joined<"-X">;
+def Z_Flag : Flag<"-Z">;
+def Z_Joined : Joined<"-Z">;
+def all__load : Flag<"-all_load">;
+def allowable__client : Separate<"-allowable_client">;
+def ansi : Flag<"-ansi">, Group<a_Group>;
+def arch__errors__fatal : Flag<"-arch_errors_fatal">;
+def arch : Separate<"-arch">, Flags<[DriverOption]>;
+def a : Joined<"-a">, Group<a_Group>;
+def bind__at__load : Flag<"-bind_at_load">;
+def bundle__loader : Separate<"-bundle_loader">;
+def bundle : Flag<"-bundle">;
+def b : JoinedOrSeparate<"-b">, Flags<[Unsupported]>;
+def client__name : JoinedOrSeparate<"-client_name">;
+def combine : Flag<"-combine">, Flags<[DriverOption, Unsupported]>;
+def compatibility__version : JoinedOrSeparate<"-compatibility_version">;
+def coverage : Flag<"-coverage">;
+def cpp_precomp : Flag<"-cpp-precomp">;
+def current__version : JoinedOrSeparate<"-current_version">;
+def c : Flag<"-c">, Flags<[DriverOption]>,
+  HelpText<"Only run preprocess, compile, and assemble steps">;
+def dA : Flag<"-dA">, Group<d_Group>;
+def dD : Flag<"-dD">, Group<d_Group>;
+def dM : Flag<"-dM">, Group<d_Group>;
+def dead__strip : Flag<"-dead_strip">;
+def dependency_file : Separate<"-dependency-file">;
+def dumpmachine : Flag<"-dumpmachine">, Flags<[Unsupported]>;
+def dumpspecs : Flag<"-dumpspecs">, Flags<[Unsupported]>;
+def dumpversion : Flag<"-dumpversion">;
+def dylib__file : Separate<"-dylib_file">;
+def dylinker__install__name : JoinedOrSeparate<"-dylinker_install_name">;
+def dylinker : Flag<"-dylinker">;
+def dynamiclib : Flag<"-dynamiclib">;
+def dynamic : Flag<"-dynamic">, Flags<[NoArgumentUnused]>;
+def d_Flag : Flag<"-d">, Group<d_Group>;
+def d_Joined : Joined<"-d">, Group<d_Group>;
+def emit_ast : Flag<"-emit-ast">,
+  HelpText<"Emit Clang AST files for source inputs">;
+def emit_llvm : Flag<"-emit-llvm">,
+  HelpText<"Use the LLVM representation for assembler and object files">;
+def exported__symbols__list : Separate<"-exported_symbols_list">;
+def e : JoinedOrSeparate<"-e">;
+def fPIC : Flag<"-fPIC">, Group<f_Group>;
+def fPIE : Flag<"-fPIE">, Group<f_Group>;
+def faccess_control : Flag<"-faccess-control">, Group<f_Group>;
+def fapple_kext : Flag<"-fapple-kext">, Group<f_Group>;
+def fasm_blocks : Flag<"-fasm-blocks">, Group<clang_ignored_f_Group>;
+def fassume_sane_operator_new : Flag<"-fassume-sane-operator-new">, Group<f_Group>;
+def fastcp : Flag<"-fastcp">, Group<f_Group>;
+def fastf : Flag<"-fastf">, Group<f_Group>;
+def fast : Flag<"-fast">, Group<f_Group>;
+def fasynchronous_unwind_tables : Flag<"-fasynchronous-unwind-tables">, Group<f_Group>;
+def fblocks : Flag<"-fblocks">, Group<f_Group>;
+def fbootclasspath_EQ : Joined<"-fbootclasspath=">, Group<f_Group>;
+def fbuiltin_strcat : Flag<"-fbuiltin-strcat">, Group<f_Group>;
+def fbuiltin_strcpy : Flag<"-fbuiltin-strcpy">, Group<f_Group>;
+def fbuiltin : Flag<"-fbuiltin">, Group<f_Group>;
+def fcatch_undefined_behavior : Flag<"-fcatch-undefined-behavior">,
+    Group<f_Group>, HelpText<"Generate runtime checks for undefined behavior.">;
+def fclasspath_EQ : Joined<"-fclasspath=">, Group<f_Group>;
+def fcolor_diagnostics : Flag<"-fcolor-diagnostics">, Group<f_Group>;
+def fcommon : Flag<"-fcommon">, Group<f_Group>;
+def fcompile_resource_EQ : Joined<"-fcompile-resource=">, Group<f_Group>;
+def fconstant_cfstrings : Flag<"-fconstant-cfstrings">, Group<clang_ignored_f_Group>;
+def fconstant_string_class_EQ : Joined<"-fconstant-string-class=">, Group<f_Group>;
+def fcreate_profile : Flag<"-fcreate-profile">, Group<f_Group>;
+def fdebug_pass_arguments : Flag<"-fdebug-pass-arguments">, Group<f_Group>;
+def fdebug_pass_structure : Flag<"-fdebug-pass-structure">, Group<f_Group>;
+def fdiagnostics_binary : Flag<"-fdiagnostics-binary">, Group<f_Group>, Flags<[HelpHidden]>;
+def fdiagnostics_fixit_info : Flag<"-fdiagnostics-fixit-info">, Group<f_Group>;
+def fdiagnostics_print_source_range_info : Flag<"-fdiagnostics-print-source-range-info">, Group<f_Group>;
+def fdiagnostics_show_option : Flag<"-fdiagnostics-show-option">, Group<f_Group>;
+def fdollars_in_identifiers : Flag<"-fdollars-in-identifiers">, Group<f_Group>;
+def feliminate_unused_debug_symbols : Flag<"-feliminate-unused-debug-symbols">, Group<f_Group>;
+def femit_all_decls : Flag<"-femit-all-decls">, Group<f_Group>;
+def fencoding_EQ : Joined<"-fencoding=">, Group<f_Group>;
+def fexceptions : Flag<"-fexceptions">, Group<f_Group>;
+def fextdirs_EQ : Joined<"-fextdirs=">, Group<f_Group>;
+def fhosted : Flag<"-fhosted">, Group<f_Group>;
+def ffreestanding : Flag<"-ffreestanding">, Group<f_Group>;
+
+def fgnu_keywords : Flag<"-fgnu-keywords">, Group<f_Group>;
+def fasm : Flag<"-fasm">, Alias<fgnu_keywords>;
+
+def fgnu_runtime : Flag<"-fgnu-runtime">, Group<f_Group>;
+def fheinous_gnu_extensions : Flag<"-fheinous-gnu-extensions">;
+def filelist : Separate<"-filelist">, Flags<[LinkerInput]>;
+def findirect_virtual_calls : Flag<"-findirect-virtual-calls">, Group<f_Group>;
+def finline_functions : Flag<"-finline-functions">, Group<clang_ignored_f_Group>;
+def finline : Flag<"-finline">, Group<clang_ignored_f_Group>;
+def fkeep_inline_functions : Flag<"-fkeep-inline-functions">, Group<clang_ignored_f_Group>;
+def flat__namespace : Flag<"-flat_namespace">;
+def flax_vector_conversions : Flag<"-flax-vector-conversions">, Group<f_Group>;
+def flimited_precision_EQ : Joined<"-flimited-precision=">, Group<f_Group>;
+def flto : Flag<"-flto">, Group<f_Group>;
+def fmath_errno : Flag<"-fmath-errno">, Group<f_Group>;
+def fmerge_all_constants : Flag<"-fmerge-all-constants">, Group<f_Group>;
+def fmessage_length_EQ : Joined<"-fmessage-length=">, Group<f_Group>;
+def fms_extensions : Flag<"-fms-extensions">, Group<f_Group>;
+def fmudflapth : Flag<"-fmudflapth">, Group<f_Group>;
+def fmudflap : Flag<"-fmudflap">, Group<f_Group>;
+def fnested_functions : Flag<"-fnested-functions">, Group<f_Group>;
+def fnext_runtime : Flag<"-fnext-runtime">, Group<f_Group>;
+def fno_access_control : Flag<"-fno-access-control">, Group<f_Group>;
+def fno_asynchronous_unwind_tables : Flag<"-fno-asynchronous-unwind-tables">, Group<f_Group>;
+def fno_assume_sane_operator_new : Flag<"-fno-assume-sane-operator-new">, Group<f_Group>;
+def fno_blocks : Flag<"-fno-blocks">, Group<f_Group>;
+def fno_builtin_strcat : Flag<"-fno-builtin-strcat">, Group<f_Group>;
+def fno_builtin_strcpy : Flag<"-fno-builtin-strcpy">, Group<f_Group>;
+def fno_builtin : Flag<"-fno-builtin">, Group<f_Group>;
+def fno_caret_diagnostics : Flag<"-fno-caret-diagnostics">, Group<f_Group>;
+def fno_color_diagnostics : Flag<"-fno-color-diagnostics">, Group<f_Group>;
+def fno_common : Flag<"-fno-common">, Group<f_Group>;
+def fno_constant_cfstrings : Flag<"-fno-constant-cfstrings">, Group<f_Group>;
+def fno_diagnostics_fixit_info : Flag<"-fno-diagnostics-fixit-info">, Group<f_Group>;
+def fno_diagnostics_show_option : Flag<"-fno-diagnostics-show-option">, Group<f_Group>;
+def fno_dollars_in_identifiers : Flag<"-fno-dollars-in-identifiers">, Group<f_Group>;
+def fno_eliminate_unused_debug_symbols : Flag<"-fno-eliminate-unused-debug-symbols">, Group<f_Group>;
+def fno_exceptions : Flag<"-fno-exceptions">, Group<f_Group>;
+
+def fno_gnu_keywords : Flag<"-fno-gnu-keywords">, Group<f_Group>;
+def fno_asm : Flag<"-fno-asm">, Alias<fno_gnu_keywords>;
+
+def fno_inline_functions : Flag<"-fno-inline-functions">, Group<clang_ignored_f_Group>;
+def fno_inline : Flag<"-fno-inline">, Group<clang_ignored_f_Group>;
+def fno_keep_inline_functions : Flag<"-fno-keep-inline-functions">, Group<clang_ignored_f_Group>;
+def fno_lax_vector_conversions : Flag<"-fno-lax-vector-conversions">, Group<f_Group>;
+def fno_math_errno : Flag<"-fno-math-errno">, Group<f_Group>;
+def fno_merge_all_constants : Flag<"-fno-merge-all-constants">, Group<f_Group>;
+def fno_ms_extensions : Flag<"-fno-ms-extensions">, Group<f_Group>;
+def fno_objc_legacy_dispatch : Flag<"-fno-objc-legacy-dispatch">, Group<f_Group>;
+def fno_omit_frame_pointer : Flag<"-fno-omit-frame-pointer">, Group<f_Group>;
+def fno_pascal_strings : Flag<"-fno-pascal-strings">, Group<f_Group>;
+def fno_rtti : Flag<"-fno-rtti">, Group<f_Group>;
+def fno_show_column : Flag<"-fno-show-column">, Group<f_Group>;
+def fno_show_source_location : Flag<"-fno-show-source-location">, Group<f_Group>;
+def fno_stack_protector : Flag<"-fno-stack-protector">, Group<f_Group>;
+def fno_strict_aliasing : Flag<"-fno-strict-aliasing">, Group<clang_ignored_f_Group>;
+def fno_threadsafe_statics : Flag<"-fno-threadsafe-statics">, Group<f_Group>;
+def fno_use_cxa_atexit : Flag<"-fno-use-cxa-atexit">, Group<f_Group>;
+def fno_unit_at_a_time : Flag<"-fno-unit-at-a-time">, Group<f_Group>;
+def fno_unwind_tables : Flag<"-fno-unwind-tables">, Group<f_Group>;
+def fno_working_directory : Flag<"-fno-working-directory">, Group<f_Group>;
+def fno_zero_initialized_in_bss : Flag<"-fno-zero-initialized-in-bss">, Group<f_Group>;
+def fobjc_atdefs : Flag<"-fobjc-atdefs">, Group<clang_ignored_f_Group>;
+def fobjc_call_cxx_cdtors : Flag<"-fobjc-call-cxx-cdtors">, Group<clang_ignored_f_Group>;
+def fobjc_gc_only : Flag<"-fobjc-gc-only">, Group<f_Group>;
+def fobjc_gc : Flag<"-fobjc-gc">, Group<f_Group>;
+def fobjc_legacy_dispatch : Flag<"-fobjc-legacy-dispatch">, Group<f_Group>;
+def fobjc_new_property : Flag<"-fobjc-new-property">, Group<clang_ignored_f_Group>;
+def fobjc_nonfragile_abi : Flag<"-fobjc-nonfragile-abi">, Group<f_Group>;
+def fobjc_nonfragile_abi2 : Flag<"-fobjc-nonfragile-abi2">, Group<f_Group>;
+def fobjc_sender_dependent_dispatch : Flag<"-fobjc-sender-dependent-dispatch">, Group<f_Group>;
+def fobjc : Flag<"-fobjc">, Group<f_Group>;
+def fomit_frame_pointer : Flag<"-fomit-frame-pointer">, Group<f_Group>;
+def fopenmp : Flag<"-fopenmp">, Group<f_Group>;
+def force__cpusubtype__ALL : Flag<"-force_cpusubtype_ALL">;
+def force__flat__namespace : Flag<"-force_flat_namespace">;
+def foutput_class_dir_EQ : Joined<"-foutput-class-dir=">, Group<f_Group>;
+def fpascal_strings : Flag<"-fpascal-strings">, Group<f_Group>;
+def fpch_preprocess : Flag<"-fpch-preprocess">, Group<f_Group>;
+def fpic : Flag<"-fpic">, Group<f_Group>;
+def fpie : Flag<"-fpie">, Group<f_Group>;
+def fprofile_arcs : Flag<"-fprofile-arcs">, Group<f_Group>;
+def fprofile_generate : Flag<"-fprofile-generate">, Group<f_Group>;
+def framework : Separate<"-framework">, Flags<[LinkerInput]>;
+def frtti : Flag<"-frtti">, Group<f_Group>;
+def fsched_interblock : Flag<"-fsched-interblock">, Group<clang_ignored_f_Group>;
+def fshort_enums : Flag<"-fshort-enums">, Group<clang_ignored_f_Group>;
+def freorder_blocks : Flag<"-freorder-blocks">, Group<clang_ignored_f_Group>;
+def fshort_wchar : Flag<"-fshort-wchar">, Group<f_Group>;
+def fshow_source_location : Flag<"-fshow-source-location">, Group<f_Group>;
+def fsigned_bitfields : Flag<"-fsigned-bitfields">, Group<f_Group>;
+def fsigned_char : Flag<"-fsigned-char">, Group<f_Group>;
+def fstack_protector_all : Flag<"-fstack-protector-all">, Group<f_Group>;
+def fstack_protector : Flag<"-fstack-protector">, Group<f_Group>;
+def fstrict_aliasing : Flag<"-fstrict-aliasing">, Group<clang_ignored_f_Group>;
+def fsyntax_only : Flag<"-fsyntax-only">, Flags<[DriverOption]>;
+def ftabstop_EQ : Joined<"-ftabstop=">, Group<f_Group>;
+def ferror_limit_EQ : Joined<"-ferror-limit=">, Group<f_Group>;
+def ftemplate_depth_ : Joined<"-ftemplate-depth-">, Group<f_Group>;
+def ftemplate_backtrace_limit_EQ : Joined<"-ftemplate-backtrace-limit=">, 
+                                   Group<f_Group>;
+def fterminated_vtables : Flag<"-fterminated-vtables">, Group<f_Group>;
+def fthreadsafe_statics : Flag<"-fthreadsafe-statics">, Group<f_Group>;
+def ftime_report : Flag<"-ftime-report">, Group<f_Group>;
+def ftrapv : Flag<"-ftrapv">, Group<f_Group>;
+def funit_at_a_time : Flag<"-funit-at-a-time">, Group<f_Group>;
+def funsigned_bitfields : Flag<"-funsigned-bitfields">, Group<f_Group>;
+def funsigned_char : Flag<"-funsigned-char">, Group<f_Group>;
+def funwind_tables : Flag<"-funwind-tables">, Group<f_Group>;
+def fuse_cxa_atexit : Flag<"-fuse-cxa-atexit">, Group<f_Group>;
+def fverbose_asm : Flag<"-fverbose-asm">, Group<f_Group>;
+def fvisibility_EQ : Joined<"-fvisibility=">, Group<f_Group>;
+def fwritable_strings : Flag<"-fwritable-strings">, Group<f_Group>;
+def fzero_initialized_in_bss : Flag<"-fzero-initialized-in-bss">, Group<f_Group>;
+def f : Joined<"-f">, Group<f_Group>;
+def g0 : Joined<"-g0">, Group<g_Group>;
+def g3 : Joined<"-g3">, Group<g_Group>;
+def gfull : Joined<"-gfull">, Group<g_Group>;
+def gstabs : Joined<"-gstabs">, Group<g_Group>;
+def gused : Joined<"-gused">, Group<g_Group>;
+def g_Flag : Flag<"-g">, Group<g_Group>;
+def g_Joined : Joined<"-g">, Group<g_Group>;
+def headerpad__max__install__names : Joined<"-headerpad_max_install_names">;
+def idirafter : JoinedOrSeparate<"-idirafter">, Group<clang_i_Group>;
+def iframework : JoinedOrSeparate<"-iframework">, Group<clang_i_Group>;
+def imacros : JoinedOrSeparate<"-imacros">, Group<clang_i_Group>;
+def image__base : Separate<"-image_base">;
+def include_ : JoinedOrSeparate<"-include">, Group<clang_i_Group>, EnumName<"include">;
+def init : Separate<"-init">;
+def install__name : Separate<"-install_name">;
+def integrated_as : Flag<"-integrated-as">, Flags<[DriverOption]>;
+def iprefix : JoinedOrSeparate<"-iprefix">, Group<clang_i_Group>;
+def iquote : JoinedOrSeparate<"-iquote">, Group<clang_i_Group>;
+def isysroot : JoinedOrSeparate<"-isysroot">, Group<clang_i_Group>;
+def isystem : JoinedOrSeparate<"-isystem">, Group<clang_i_Group>;
+def iwithprefixbefore : JoinedOrSeparate<"-iwithprefixbefore">, Group<clang_i_Group>;
+def iwithprefix : JoinedOrSeparate<"-iwithprefix">, Group<clang_i_Group>;
+def iwithsysroot : JoinedOrSeparate<"-iwithsysroot">, Group<i_Group>;
+def i : Joined<"-i">, Group<i_Group>;
+def keep__private__externs : Flag<"-keep_private_externs">;
+def l : JoinedOrSeparate<"-l">, Flags<[LinkerInput, RenderJoined]>;
+def m32 : Flag<"-m32">, Group<m_Group>, Flags<[DriverOption]>;
+def m3dnowa : Flag<"-m3dnowa">, Group<m_x86_Features_Group>;
+def m3dnow : Flag<"-m3dnow">, Group<m_x86_Features_Group>;
+def m64 : Flag<"-m64">, Group<m_Group>, Flags<[DriverOption]>;
+def mabi_EQ : Joined<"-mabi=">, Group<m_Group>, Flags<[DriverOption]>;
+def march_EQ : Joined<"-march=">, Group<m_Group>, Flags<[DriverOption]>;
+def mcmodel_EQ : Joined<"-mcmodel=">, Group<m_Group>, Flags<[DriverOption]>;
+def mconstant_cfstrings : Flag<"-mconstant-cfstrings">, Group<clang_ignored_m_Group>;
+def mcpu_EQ : Joined<"-mcpu=">, Group<m_Group>, Flags<[DriverOption]>;
+def mdynamic_no_pic : Joined<"-mdynamic-no-pic">, Group<m_Group>, Flags<[NoArgumentUnused]>;
+def mfix_and_continue : Flag<"-mfix-and-continue">, Group<clang_ignored_m_Group>;
+def mfloat_abi_EQ : Joined<"-mfloat-abi=">, Group<m_Group>;
+def mfpu_EQ : Joined<"-mfpu=">, Group<m_Group>;
+def mhard_float : Flag<"-mhard-float">, Group<m_Group>;
+def miphoneos_version_min_EQ : Joined<"-miphoneos-version-min=">, Group<m_Group>, Flags<[DriverOption]>;
+def mkernel : Flag<"-mkernel">, Group<m_Group>;
+def mllvm : Separate<"-mllvm">;
+def mmacosx_version_min_EQ : Joined<"-mmacosx-version-min=">, Group<m_Group>, Flags<[DriverOption]>;
+def mmmx : Flag<"-mmmx">, Group<m_x86_Features_Group>;
+def mno_3dnowa : Flag<"-mno-3dnowa">, Group<m_x86_Features_Group>;
+def mno_3dnow : Flag<"-mno-3dnow">, Group<m_x86_Features_Group>;
+def mno_constant_cfstrings : Flag<"-mno-constant-cfstrings">, Group<m_Group>;
+def mno_mmx : Flag<"-mno-mmx">, Group<m_x86_Features_Group>;
+def mno_pascal_strings : Flag<"-mno-pascal-strings">, Group<m_Group>;
+def mno_red_zone : Flag<"-mno-red-zone">, Group<m_Group>;
+def mno_soft_float : Flag<"-mno-soft-float">, Group<m_Group>;
+def mno_sse2 : Flag<"-mno-sse2">, Group<m_x86_Features_Group>;
+def mno_sse3 : Flag<"-mno-sse3">, Group<m_x86_Features_Group>;
+def mno_sse4a : Flag<"-mno-sse4a">, Group<m_x86_Features_Group>;
+def mno_sse4 : Flag<"-mno-sse4">, Group<m_x86_Features_Group>;
+def mno_sse4_1 : Flag<"-mno-sse4.1">, Group<m_x86_Features_Group>;
+def mno_sse4_2 : Flag<"-mno-sse4.2">, Group<m_x86_Features_Group>;
+def mno_sse : Flag<"-mno-sse">, Group<m_x86_Features_Group>;
+def mno_ssse3 : Flag<"-mno-ssse3">, Group<m_x86_Features_Group>;
+def mno_aes : Flag<"-mno-aes">, Group<m_x86_Features_Group>;
+
+def mno_thumb : Flag<"-mno-thumb">, Group<m_Group>;
+def marm : Flag<"-marm">, Alias<mno_thumb>;
+
+def mno_warn_nonportable_cfstrings : Flag<"-mno-warn-nonportable-cfstrings">, Group<m_Group>;
+def mpascal_strings : Flag<"-mpascal-strings">, Group<m_Group>;
+def mred_zone : Flag<"-mred-zone">, Group<m_Group>;
+def msoft_float : Flag<"-msoft-float">, Group<m_Group>;
+def msse2 : Flag<"-msse2">, Group<m_x86_Features_Group>;
+def msse3 : Flag<"-msse3">, Group<m_x86_Features_Group>;
+def msse4a : Flag<"-msse4a">, Group<m_x86_Features_Group>;
+def msse4 : Flag<"-msse4">, Group<m_x86_Features_Group>;
+def msse4_1 : Flag<"-msse4.1">, Group<m_x86_Features_Group>;
+def msse4_2 : Flag<"-msse4.2">, Group<m_x86_Features_Group>;
+def msse : Flag<"-msse">, Group<m_x86_Features_Group>;
+def mssse3 : Flag<"-mssse3">, Group<m_x86_Features_Group>;
+def maes : Flag<"-maes">, Group<m_x86_Features_Group>;
+def mthumb : Flag<"-mthumb">, Group<m_Group>;
+def mtune_EQ : Joined<"-mtune=">, Group<m_Group>;
+def multi__module : Flag<"-multi_module">;
+def multiply__defined__unused : Separate<"-multiply_defined_unused">;
+def multiply__defined : Separate<"-multiply_defined">;
+def mwarn_nonportable_cfstrings : Flag<"-mwarn-nonportable-cfstrings">, Group<m_Group>;
+def m_Separate : Separate<"-m">, Group<m_Group>;
+def m_Joined : Joined<"-m">, Group<m_Group>;
+def no_canonical_prefixes : Flag<"-no-canonical-prefixes">, Flags<[HelpHidden]>,
+  HelpText<"Use relative instead of canonical paths">;
+def no_cpp_precomp : Flag<"-no-cpp-precomp">;
+def no_integrated_as : Flag<"-no-integrated-as">, Flags<[DriverOption]>;
+def no_integrated_cpp : Flag<"-no-integrated-cpp">, Flags<[DriverOption]>;
+def no__dead__strip__inits__and__terms : Flag<"-no_dead_strip_inits_and_terms">;
+def nobuiltininc : Flag<"-nobuiltininc">;
+def nodefaultlibs : Flag<"-nodefaultlibs">;
+def nofixprebinding : Flag<"-nofixprebinding">;
+def nolibc : Flag<"-nolibc">;
+def nomultidefs : Flag<"-nomultidefs">;
+def noprebind : Flag<"-noprebind">;
+def noseglinkedit : Flag<"-noseglinkedit">;
+def nostartfiles : Flag<"-nostartfiles">;
+def nostdinc : Flag<"-nostdinc">;
+def nostdincxx : Flag<"-nostdinc++">;
+def nostdlib : Flag<"-nostdlib">;
+def object : Flag<"-object">;
+def o : JoinedOrSeparate<"-o">, Flags<[DriverOption, RenderAsInput]>,
+  HelpText<"Write output to <file>">, MetaVarName<"<file>">;
+def pagezero__size : JoinedOrSeparate<"-pagezero_size">;
+def pass_exit_codes : Flag<"-pass-exit-codes">, Flags<[Unsupported]>;
+def pedantic_errors : Flag<"-pedantic-errors">, Group<pedantic_Group>;
+def pedantic : Flag<"-pedantic">, Group<pedantic_Group>;
+def pg : Flag<"-pg">;
+def pipe : Flag<"-pipe">,
+  HelpText<"Use pipes between commands, when possible">;
+def prebind__all__twolevel__modules : Flag<"-prebind_all_twolevel_modules">;
+def prebind : Flag<"-prebind">;
+def preload : Flag<"-preload">;
+def print_file_name_EQ : Joined<"-print-file-name=">,
+  HelpText<"Print the full library path of <file>">, MetaVarName<"<file>">;
+def print_ivar_layout : Flag<"-print-ivar-layout">;
+def print_libgcc_file_name : Flag<"-print-libgcc-file-name">,
+  HelpText<"Print the library path for \"libgcc.a\"">;
+def print_multi_directory : Flag<"-print-multi-directory">;
+def print_multi_lib : Flag<"-print-multi-lib">;
+def print_multi_os_directory : Flag<"-print-multi-os-directory">;
+def print_prog_name_EQ : Joined<"-print-prog-name=">,
+  HelpText<"Print the full program path of <name>">, MetaVarName<"<name>">;
+def print_search_dirs : Flag<"-print-search-dirs">,
+  HelpText<"Print the paths used for finding libraries and programs">;
+def private__bundle : Flag<"-private_bundle">;
+def pthreads : Flag<"-pthreads">;
+def pthread : Flag<"-pthread">;
+def p : Flag<"-p">;
+def read__only__relocs : Separate<"-read_only_relocs">;
+def remap : Flag<"-remap">;
+def rewrite_objc : Flag<"-rewrite-objc">, Flags<[DriverOption]>,
+  HelpText<"Rewrite Objective-C source to C++">;
+def rpath : Separate<"-rpath">, Flags<[LinkerInput]>;
+def r : Flag<"-r">;
+def save_temps : Flag<"-save-temps">, Flags<[DriverOption]>,
+  HelpText<"Save intermediate compilation results">;
+def sectalign : MultiArg<"-sectalign", 3>;
+def sectcreate : MultiArg<"-sectcreate", 3>;
+def sectobjectsymbols : MultiArg<"-sectobjectsymbols", 2>;
+def sectorder : MultiArg<"-sectorder", 3>;
+def seg1addr : JoinedOrSeparate<"-seg1addr">;
+def seg__addr__table__filename : Separate<"-seg_addr_table_filename">;
+def seg__addr__table : Separate<"-seg_addr_table">;
+def segaddr : MultiArg<"-segaddr", 2>;
+def segcreate : MultiArg<"-segcreate", 3>;
+def seglinkedit : Flag<"-seglinkedit">;
+def segprot : MultiArg<"-segprot", 3>;
+def segs__read__only__addr : Separate<"-segs_read_only_addr">;
+def segs__read__write__addr : Separate<"-segs_read_write_addr">;
+def segs__read__ : Joined<"-segs_read_">;
+def shared_libgcc : Flag<"-shared-libgcc">;
+def shared : Flag<"-shared">;
+def single__module : Flag<"-single_module">;
+def specs_EQ : Joined<"-specs=">;
+def specs : Separate<"-specs">, Flags<[Unsupported]>;
+def static_libgcc : Flag<"-static-libgcc">;
+def static : Flag<"-static">, Flags<[NoArgumentUnused]>;
+def std_default_EQ : Joined<"-std-default=">;
+def std_EQ : Joined<"-std=">;
+def sub__library : JoinedOrSeparate<"-sub_library">;
+def sub__umbrella : JoinedOrSeparate<"-sub_umbrella">;
+def s : Flag<"-s">;
+def time : Flag<"-time">,
+  HelpText<"Time individual commands">;
+def traditional_cpp : Flag<"-traditional-cpp">;
+def traditional : Flag<"-traditional">;
+def trigraphs : Flag<"-trigraphs">;
+def twolevel__namespace__hints : Flag<"-twolevel_namespace_hints">;
+def twolevel__namespace : Flag<"-twolevel_namespace">;
+def t : Flag<"-t">;
+def umbrella : Separate<"-umbrella">;
+def undefined : JoinedOrSeparate<"-undefined">, Group<u_Group>;
+def undef : Flag<"-undef">, Group<u_Group>;
+def unexported__symbols__list : Separate<"-unexported_symbols_list">;
+def u : JoinedOrSeparate<"-u">, Group<u_Group>;
+def v : Flag<"-v">,
+  HelpText<"Show commands to run and use verbose output">;
+def weak_l : Joined<"-weak-l">, Flags<[LinkerInput]>;
+def weak__framework : Separate<"-weak_framework">, Flags<[LinkerInput]>;
+def weak__library : Separate<"-weak_library">, Flags<[LinkerInput]>;
+def weak__reference__mismatches : Separate<"-weak_reference_mismatches">;
+def whatsloaded : Flag<"-whatsloaded">;
+def whyload : Flag<"-whyload">;
+def w : Flag<"-w">;
+def x : JoinedOrSeparate<"-x">, Flags<[DriverOption]>,
+  HelpText<"Treat subsequent input files as having type <language>">,
+  MetaVarName<"<language>">;
+def y : Joined<"-y">;
+
+// Double dash options, which are usually an alias for one of the previous
+// options.
+
+def _CLASSPATH_EQ : Joined<"--CLASSPATH=">, Alias<fclasspath_EQ>;
+def _CLASSPATH : Separate<"--CLASSPATH">, Alias<fclasspath_EQ>, Flags<[RenderJoined]>;
+def _all_warnings : Flag<"--all-warnings">, Alias<Wall>;
+def _analyze_auto : Flag<"--analyze-auto">, Flags<[DriverOption]>;
+def _analyzer_no_default_checks : Flag<"--analyzer-no-default-checks">, Flags<[DriverOption]>;
+def _analyzer_output : JoinedOrSeparate<"--analyzer-output">, Flags<[DriverOption]>;
+def _analyze : Flag<"--analyze">, Flags<[DriverOption]>,
+  HelpText<"Run the static analyzer">;
+def _ansi : Flag<"--ansi">, Alias<ansi>;
+def _assemble : Flag<"--assemble">, Alias<S>;
+def _assert_EQ : Joined<"--assert=">, Alias<A>, Flags<[RenderSeparate]>;
+def _assert : Separate<"--assert">, Alias<A>;
+def _bootclasspath_EQ : Joined<"--bootclasspath=">, Alias<fbootclasspath_EQ>;
+def _bootclasspath : Separate<"--bootclasspath">, Alias<fbootclasspath_EQ>, Flags<[RenderJoined]>;
+def _classpath_EQ : Joined<"--classpath=">, Alias<fclasspath_EQ>;
+def _classpath : Separate<"--classpath">, Alias<fclasspath_EQ>, Flags<[RenderJoined]>;
+def _combine : Flag<"--combine">, Alias<combine>, Flags<[Unsupported]>;
+def _comments_in_macros : Flag<"--comments-in-macros">, Alias<CC>;
+def _comments : Flag<"--comments">, Alias<C>;
+def _compile : Flag<"--compile">, Alias<c>;
+def _constant_cfstrings : Flag<"--constant-cfstrings">;
+def _coverage : Flag<"--coverage">, Alias<coverage>;
+def _debug_EQ : Joined<"--debug=">, Alias<g_Flag>, Flags<[Unsupported]>;
+def _debug : Flag<"--debug">, Alias<g_Flag>, Flags<[Unsupported]>;
+def _define_macro_EQ : Joined<"--define-macro=">, Alias<D>;
+def _define_macro : Separate<"--define-macro">, Alias<D>, Flags<[RenderJoined]>;
+def _dependencies : Flag<"--dependencies">, Alias<M>;
+def _encoding_EQ : Joined<"--encoding=">, Alias<fencoding_EQ>;
+def _encoding : Separate<"--encoding">, Alias<fencoding_EQ>, Flags<[RenderJoined]>;
+def _entry : Flag<"--entry">, Alias<e>;
+def _extdirs_EQ : Joined<"--extdirs=">, Alias<fextdirs_EQ>;
+def _extdirs : Separate<"--extdirs">, Alias<fextdirs_EQ>, Flags<[RenderJoined]>;
+def _extra_warnings : Flag<"--extra-warnings">, Alias<W_Joined>;
+def _for_linker_EQ : Joined<"--for-linker=">, Alias<Xlinker>, Flags<[LinkerInput, RenderAsInput, RenderSeparate]>;
+def _for_linker : Separate<"--for-linker">, Alias<Xlinker>, Flags<[LinkerInput, RenderAsInput]>;
+def _force_link_EQ : Joined<"--force-link=">, Alias<u>, Flags<[RenderSeparate]>;
+def _force_link : Separate<"--force-link">, Alias<u>;
+def _help_hidden : Flag<"--help-hidden">;
+def _help : Flag<"--help">,
+  HelpText<"Display available options">;
+def _imacros_EQ : Joined<"--imacros=">, Alias<imacros>, Flags<[RenderSeparate]>;
+def _imacros : Separate<"--imacros">, Alias<imacros>;
+def _include_barrier : Flag<"--include-barrier">, Alias<I_>;
+def _include_directory_after_EQ : Joined<"--include-directory-after=">, Alias<idirafter>, Flags<[RenderSeparate]>;
+def _include_directory_after : Separate<"--include-directory-after">, Alias<idirafter>;
+def _include_directory_EQ : Joined<"--include-directory=">, Alias<I>;
+def _include_directory : Separate<"--include-directory">, Alias<I>, Flags<[RenderJoined]>;
+def _include_prefix_EQ : Joined<"--include-prefix=">, Alias<iprefix>, Flags<[RenderSeparate]>;
+def _include_prefix : Separate<"--include-prefix">, Alias<iprefix>;
+def _include_with_prefix_after_EQ : Joined<"--include-with-prefix-after=">, Alias<iwithprefix>, Flags<[RenderSeparate]>;
+def _include_with_prefix_after : Separate<"--include-with-prefix-after">, Alias<iwithprefix>;
+def _include_with_prefix_before_EQ : Joined<"--include-with-prefix-before=">, Alias<iwithprefixbefore>, Flags<[RenderSeparate]>;
+def _include_with_prefix_before : Separate<"--include-with-prefix-before">, Alias<iwithprefixbefore>;
+def _include_with_prefix_EQ : Joined<"--include-with-prefix=">, Alias<iwithprefix>, Flags<[RenderSeparate]>;
+def _include_with_prefix : Separate<"--include-with-prefix">, Alias<iwithprefix>;
+def _include_EQ : Joined<"--include=">, Alias<include_>, Flags<[RenderSeparate]>;
+def _include : Separate<"--include">, Alias<include_>;
+def _language_EQ : Joined<"--language=">, Alias<x>, Flags<[RenderSeparate]>;
+def _language : Separate<"--language">, Alias<x>;
+def _library_directory_EQ : Joined<"--library-directory=">, Alias<L>, Flags<[RenderSeparate]>;
+def _library_directory : Separate<"--library-directory">, Alias<L>;
+def _machine__EQ : Joined<"--machine-=">, Alias<m_Joined>, Flags<[Unsupported]>;
+def _machine_ : Joined<"--machine-">, Alias<m_Joined>, Flags<[Unsupported]>;
+def _machine_EQ : Joined<"--machine=">, Alias<m_Joined>;
+def _machine : Separate<"--machine">, Alias<m_Joined>, Flags<[RenderJoined]>;
+def _no_integrated_cpp : Flag<"--no-integrated-cpp">, Alias<no_integrated_cpp>;
+def _no_line_commands : Flag<"--no-line-commands">, Alias<P>;
+def _no_standard_includes : Flag<"--no-standard-includes">, Alias<nostdinc>;
+def _no_standard_libraries : Flag<"--no-standard-libraries">, Alias<nostdlib>;
+def _no_undefined : Flag<"--no-undefined">, Flags<[LinkerInput]>;
+def _no_warnings : Flag<"--no-warnings">, Alias<w>;
+def _optimize_EQ : Joined<"--optimize=">, Alias<O>, Flags<[Unsupported]>;
+def _optimize : Flag<"--optimize">, Alias<O>, Flags<[Unsupported]>;
+def _output_class_directory_EQ : Joined<"--output-class-directory=">, Alias<foutput_class_dir_EQ>;
+def _output_class_directory : Separate<"--output-class-directory">, Alias<foutput_class_dir_EQ>, Flags<[RenderJoined]>;
+def _output_EQ : Joined<"--output=">, Alias<o>, Flags<[RenderSeparate]>;
+def _output : Separate<"--output">, Alias<o>;
+def _param : Separate<"--param">;
+def _param_EQ : Joined<"--param=">, Alias<_param>, Flags<[RenderSeparate]>;
+def _pass_exit_codes : Flag<"--pass-exit-codes">, Alias<pass_exit_codes>;
+def _pedantic_errors : Flag<"--pedantic-errors">, Alias<pedantic_errors>;
+def _pedantic : Flag<"--pedantic">, Alias<pedantic>;
+def _pipe : Flag<"--pipe">, Alias<pipe>, Flags<[DriverOption]>;
+def _prefix_EQ : Joined<"--prefix=">, Alias<B>, Flags<[RenderSeparate]>;
+def _prefix : Separate<"--prefix">, Alias<B>;
+def _preprocess : Flag<"--preprocess">, Alias<E>;
+def _print_file_name_EQ : Joined<"--print-file-name=">, Alias<print_file_name_EQ>;
+def _print_file_name : Separate<"--print-file-name">, Alias<print_file_name_EQ>;
+def _print_libgcc_file_name : Flag<"--print-libgcc-file-name">, Alias<print_libgcc_file_name>;
+def _print_missing_file_dependencies : Flag<"--print-missing-file-dependencies">, Alias<MG>;
+def _print_multi_directory : Flag<"--print-multi-directory">, Alias<print_multi_directory>;
+def _print_multi_lib : Flag<"--print-multi-lib">, Alias<print_multi_lib>;
+def _print_multi_os_directory : Flag<"--print-multi-os-directory">, Alias<print_multi_os_directory>;
+def _print_prog_name_EQ : Joined<"--print-prog-name=">, Alias<print_prog_name_EQ>;
+def _print_prog_name : Separate<"--print-prog-name">, Alias<print_prog_name_EQ>;
+def _print_search_dirs : Flag<"--print-search-dirs">, Alias<print_search_dirs>;
+def _profile_blocks : Flag<"--profile-blocks">, Alias<a>;
+def _profile : Flag<"--profile">, Alias<p>;
+def _relocatable_pch : Flag<"--relocatable-pch">,
+  HelpText<"Build a relocatable precompiled header">;
+def _resource_EQ : Joined<"--resource=">, Alias<fcompile_resource_EQ>;
+def _resource : Separate<"--resource">, Alias<fcompile_resource_EQ>, Flags<[RenderJoined]>;
+def _save_temps : Flag<"--save-temps">, Alias<save_temps>;
+def _shared : Flag<"--shared">, Alias<shared>;
+def _signed_char : Flag<"--signed-char">, Alias<fsigned_char>;
+def _specs_EQ : Joined<"--specs=">, Alias<specs_EQ>, Flags<[Unsupported]>;
+def _specs : Separate<"--specs">, Alias<specs_EQ>, Flags<[RenderJoined, Unsupported]>;
+def _static : Flag<"--static">, Alias<static>;
+def _std_EQ : Joined<"--std=">, Alias<std_EQ>;
+def _std : Separate<"--std">, Alias<std_EQ>, Flags<[RenderJoined]>;
+def _sysroot_EQ : Joined<"--sysroot=">;
+def _sysroot : Separate<"--sysroot">, Alias<_sysroot_EQ>, Flags<[RenderJoined]>;
+def _target_help : Flag<"--target-help">;
+def _trace_includes : Flag<"--trace-includes">, Alias<H>;
+def _traditional_cpp : Flag<"--traditional-cpp">, Alias<traditional_cpp>;
+def _traditional : Flag<"--traditional">, Alias<traditional>;
+def _trigraphs : Flag<"--trigraphs">, Alias<trigraphs>;
+def _undefine_macro_EQ : Joined<"--undefine-macro=">, Alias<U>;
+def _undefine_macro : Separate<"--undefine-macro">, Alias<U>, Flags<[RenderJoined]>;
+def _unsigned_char : Flag<"--unsigned-char">, Alias<funsigned_char>;
+def _user_dependencies : Flag<"--user-dependencies">, Alias<MM>;
+def _verbose : Flag<"--verbose">, Alias<v>;
+def _version : Flag<"--version">;
+def _warn__EQ : Joined<"--warn-=">, Alias<W_Joined>, Flags<[Unsupported]>;
+def _warn_ : Joined<"--warn-">, Alias<W_Joined>, Flags<[Unsupported]>;
+def _write_dependencies : Flag<"--write-dependencies">, Alias<MD>;
+def _write_user_dependencies : Flag<"--write-user-dependencies">, Alias<MMD>;
+def _ : Joined<"--">, Alias<f>, Flags<[Unsupported]>;
diff --git a/include/clang/Driver/Phases.h b/include/clang/Driver/Phases.h
new file mode 100644
index 0000000..a0c42ea
--- /dev/null
+++ b/include/clang/Driver/Phases.h
@@ -0,0 +1,32 @@
+//===--- Phases.h - Transformations on Driver Types -------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_DRIVER_PHASES_H_
+#define CLANG_DRIVER_PHASES_H_
+
+namespace clang {
+namespace driver {
+namespace phases {
+  /// ID - Ordered values for successive stages in the
+  /// compilation process which interact with user options.
+  enum ID {
+    Preprocess,
+    Precompile,
+    Compile,
+    Assemble,
+    Link
+  };
+
+  const char *getPhaseName(ID Id);
+
+} // end namespace phases
+} // end namespace driver
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Driver/Tool.h b/include/clang/Driver/Tool.h
new file mode 100644
index 0000000..ef77206
--- /dev/null
+++ b/include/clang/Driver/Tool.h
@@ -0,0 +1,74 @@
+//===--- Tool.h - Compilation Tools -----------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_DRIVER_TOOL_H_
+#define CLANG_DRIVER_TOOL_H_
+
+namespace llvm {
+  template<typename T, unsigned N> class SmallVector;
+}
+
+namespace clang {
+namespace driver {
+  class ArgList;
+  class Compilation;
+  class InputInfo;
+  class Job;
+  class JobAction;
+  class ToolChain;
+
+  typedef llvm::SmallVector<InputInfo, 4> InputInfoList;
+
+/// Tool - Information on a specific compilation tool.
+class Tool {
+  /// The tool name (for debugging).
+  const char *Name;
+
+  /// The tool chain this tool is a part of.
+  const ToolChain &TheToolChain;
+
+public:
+  Tool(const char *Name, const ToolChain &TC);
+
+public:
+  virtual ~Tool();
+
+  const char *getName() const { return Name; }
+
+  const ToolChain &getToolChain() const { return TheToolChain; }
+
+  virtual bool acceptsPipedInput() const = 0;
+  virtual bool canPipeOutput() const = 0;
+  virtual bool hasIntegratedAssembler() const { return false; }
+  virtual bool hasIntegratedCPP() const = 0;
+
+  /// \brief Does this tool have "good" standardized diagnostics, or should the
+  /// driver add an additional "command failed" diagnostic on failures.
+  virtual bool hasGoodDiagnostics() const { return false; }
+
+  /// ConstructJob - Construct jobs to perform the action \arg JA,
+  /// writing to \arg Output and with \arg Inputs.
+  ///
+  /// \param Dest - Where to put the resulting commands.
+  /// \param TCArgs - The argument list for this toolchain, with any
+  /// tool chain specific translations applied.
+  /// \param LinkingOutput - If this output will eventually feed the
+  /// linker, then this is the final output name of the linked image.
+  virtual void ConstructJob(Compilation &C, const JobAction &JA,
+                            Job &Dest,
+                            const InputInfo &Output,
+                            const InputInfoList &Inputs,
+                            const ArgList &TCArgs,
+                            const char *LinkingOutput) const = 0;
+};
+
+} // end namespace driver
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Driver/ToolChain.h b/include/clang/Driver/ToolChain.h
new file mode 100644
index 0000000..1a8ae77
--- /dev/null
+++ b/include/clang/Driver/ToolChain.h
@@ -0,0 +1,141 @@
+//===--- ToolChain.h - Collections of tools for one platform ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_DRIVER_TOOLCHAIN_H_
+#define CLANG_DRIVER_TOOLCHAIN_H_
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/System/Path.h"
+#include <string>
+
+namespace clang {
+namespace driver {
+  class Compilation;
+  class DerivedArgList;
+  class Driver;
+  class HostInfo;
+  class InputArgList;
+  class JobAction;
+  class Tool;
+
+/// ToolChain - Access to tools for a single platform.
+class ToolChain {
+public:
+  typedef llvm::SmallVector<std::string, 4> path_list;
+
+private:
+  const HostInfo &Host;
+  const llvm::Triple Triple;
+
+  /// The list of toolchain specific path prefixes to search for
+  /// files.
+  path_list FilePaths;
+
+  /// The list of toolchain specific path prefixes to search for
+  /// programs.
+  path_list ProgramPaths;
+
+protected:
+  ToolChain(const HostInfo &Host, const llvm::Triple &_Triple);
+
+public:
+  virtual ~ToolChain();
+
+  // Accessors
+
+  const Driver &getDriver() const;
+  const llvm::Triple &getTriple() const { return Triple; }
+
+  llvm::StringRef getArchName() const { return Triple.getArchName(); }
+  llvm::StringRef getPlatform() const { return Triple.getVendorName(); }
+  llvm::StringRef getOS() const { return Triple.getOSName(); }
+
+  std::string getTripleString() const {
+    return Triple.getTriple();
+  }
+
+  path_list &getFilePaths() { return FilePaths; }
+  const path_list &getFilePaths() const { return FilePaths; }
+
+  path_list &getProgramPaths() { return ProgramPaths; }
+  const path_list &getProgramPaths() const { return ProgramPaths; }
+
+  // Tool access.
+
+  /// TranslateArgs - Create a new derived argument list for any argument
+  /// translations this ToolChain may wish to perform.
+  ///
+  /// \param BoundArch - The bound architecture name, or 0.
+  virtual DerivedArgList *TranslateArgs(InputArgList &Args,
+                                        const char *BoundArch) const = 0;
+
+  /// SelectTool - Choose a tool to use to handle the action \arg JA.
+  virtual Tool &SelectTool(const Compilation &C, const JobAction &JA) const = 0;
+
+  // Helper methods
+
+  std::string GetFilePath(const Compilation &C, const char *Name) const;
+  std::string GetProgramPath(const Compilation &C, const char *Name,
+                             bool WantFile = false) const;
+
+  // Platform defaults information
+
+  /// IsBlocksDefault - Does this tool chain enable -fblocks by default.
+  virtual bool IsBlocksDefault() const { return false; }
+
+  /// IsIntegratedAssemblerDefault - Does this tool chain enable -integrated-as
+  /// by default.
+  virtual bool IsIntegratedAssemblerDefault() const { return false; }
+
+  /// IsObjCNonFragileABIDefault - Does this tool chain set
+  /// -fobjc-nonfragile-abi by default.
+  virtual bool IsObjCNonFragileABIDefault() const { return false; }
+
+  /// IsObjCLegacyDispatchDefault - Does this tool chain set
+  /// -fobjc-legacy-dispatch by default (this is only used with the non-fragile
+  /// ABI).
+  virtual bool IsObjCLegacyDispatchDefault() const { return false; }
+
+  /// UseObjCMixedDispatchDefault - When using non-legacy dispatch, should the
+  /// mixed dispatch method be used?
+  virtual bool UseObjCMixedDispatch() const { return false; }
+
+  /// GetDefaultStackProtectorLevel - Get the default stack protector level for
+  /// this tool chain (0=off, 1=on, 2=all).
+  virtual unsigned GetDefaultStackProtectorLevel() const { return 0; }
+
+  /// IsUnwindTablesDefault - Does this tool chain use -funwind-tables
+  /// by default.
+  virtual bool IsUnwindTablesDefault() const = 0;
+
+  /// GetDefaultRelocationModel - Return the LLVM name of the default
+  /// relocation model for this tool chain.
+  virtual const char *GetDefaultRelocationModel() const = 0;
+
+  /// GetForcedPicModel - Return the LLVM name of the forced PIC model
+  /// for this tool chain, or 0 if this tool chain does not force a
+  /// particular PIC mode.
+  virtual const char *GetForcedPicModel() const = 0;
+
+  /// Does this tool chain support Objective-C garbage collection.
+  virtual bool SupportsObjCGC() const { return false; }
+
+  /// UseDwarfDebugFlags - Embed the compile options to clang into the Dwarf
+  /// compile unit information.
+  virtual bool UseDwarfDebugFlags() const { return false; }
+
+  /// UseSjLjExceptions - Does this tool chain use SjLj exceptions.
+  virtual bool UseSjLjExceptions() const { return false; }
+};
+
+} // end namespace driver
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Driver/Types.def b/include/clang/Driver/Types.def
new file mode 100644
index 0000000..61a5043
--- /dev/null
+++ b/include/clang/Driver/Types.def
@@ -0,0 +1,81 @@
+//===--- Types.def - Driver Type info ---------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the driver type information. Users of this file
+// must define the TYPE macro to make use of this information.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef TYPE
+#error "Define TYPE prior to including this file!"
+#endif
+
+// TYPE(NAME, ID, PP_TYPE, TEMP_SUFFIX, FLAGS)
+
+// The first value is the type name as a string; for types which can
+// be user specified this should be the equivalent -x option.
+
+// The second value is the type id, which will result in a
+// clang::driver::types::TY_XX enum constant.
+
+// The third value is that id of the type for preprocessed inputs of
+// this type, or INVALID if this type is not preprocessed.
+
+// The fourth value is the suffix to use when creating temporary files
+// of this type, or null if unspecified.
+
+// The fifth value is a string containt option flags. Valid values:
+//  a - The type should only be assembled.
+//  p - The type should only be precompiled.
+//  u - The type can be user specified (with -x).
+//  A - The type's temporary suffix should be appended when generating
+//      outputs of this type.
+
+
+// C family source language (with and without preprocessing).
+TYPE("cpp-output",               PP_C,         INVALID,         "i",     "u")
+TYPE("c",                        C,            PP_C,            0,       "u")
+TYPE("cl",                       CL,           PP_C,            0,       "u")
+TYPE("objective-c-cpp-output",   PP_ObjC,      INVALID,         "mi",    "u")
+TYPE("objective-c",              ObjC,         PP_ObjC,         0,       "u")
+TYPE("c++-cpp-output",           PP_CXX,       INVALID,         "ii",    "u")
+TYPE("c++",                      CXX,          PP_CXX,          0,       "u")
+TYPE("objective-c++-cpp-output", PP_ObjCXX,    INVALID,         "mii",   "u")
+TYPE("objective-c++",            ObjCXX,       PP_ObjCXX,       0,       "u")
+
+// C family input files to precompile.
+TYPE("c-header-cpp-output",      PP_CHeader,   INVALID,         "i",     "p")
+TYPE("c-header",                 CHeader,      PP_CHeader,      0,       "pu")
+TYPE("objective-c-header-cpp-output", PP_ObjCHeader, INVALID,   "mi",    "p")
+TYPE("objective-c-header",       ObjCHeader,   PP_ObjCHeader,   0,       "pu")
+TYPE("c++-header-cpp-output",    PP_CXXHeader, INVALID,         "ii",    "p")
+TYPE("c++-header",               CXXHeader,    PP_CXXHeader,    0,       "pu")
+TYPE("objective-c++-header-cpp-output", PP_ObjCXXHeader, INVALID, "mii", "p")
+TYPE("objective-c++-header",     ObjCXXHeader, PP_ObjCXXHeader, 0,       "pu")
+
+// Other languages.
+TYPE("ada",                      Ada,          INVALID,         0,       "u")
+TYPE("assembler",                PP_Asm,       INVALID,         "s",     "au")
+TYPE("assembler-with-cpp",       Asm,          PP_Asm,          0,       "au")
+TYPE("f95",                      PP_Fortran,   INVALID,         0,       "u")
+TYPE("f95-cpp-input",            Fortran,      PP_Fortran,      0,       "u")
+TYPE("java",                     Java,         INVALID,         0,       "u")
+
+// Misc.
+TYPE("ast",                      AST,          INVALID,         "ast",   "u")
+TYPE("llvm-asm",                 LLVMAsm,      INVALID,         "s",     "")
+TYPE("llvm-bc",                  LLVMBC,       INVALID,         "o",     "")
+TYPE("plist",                    Plist,        INVALID,         "plist", "")
+TYPE("rewritten-objc",           RewrittenObjC,INVALID,         "cpp",   "")
+TYPE("precompiled-header",       PCH,          INVALID,         "gch",   "A")
+TYPE("object",                   Object,       INVALID,         "o",     "")
+TYPE("treelang",                 Treelang,     INVALID,         0,       "u")
+TYPE("image",                    Image,        INVALID,         "out",   "")
+TYPE("dependencies",             Dependencies, INVALID,         "d",     "")
+TYPE("none",                     Nothing,      INVALID,         0,       "u")
diff --git a/include/clang/Driver/Types.h b/include/clang/Driver/Types.h
new file mode 100644
index 0000000..d933230
--- /dev/null
+++ b/include/clang/Driver/Types.h
@@ -0,0 +1,92 @@
+//===--- Types.h - Input & Temporary Driver Types ---------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_DRIVER_TYPES_H_
+#define CLANG_DRIVER_TYPES_H_
+
+#include "clang/Driver/Phases.h"
+
+namespace clang {
+namespace driver {
+namespace types {
+  enum ID {
+    TY_INVALID,
+#define TYPE(NAME, ID, PP_TYPE, TEMP_SUFFIX, FLAGS) TY_##ID,
+#include "clang/Driver/Types.def"
+#undef TYPE
+    TY_LAST
+  };
+
+  /// getTypeName - Return the name of the type for \arg Id.
+  const char *getTypeName(ID Id);
+
+  /// getPreprocessedType - Get the ID of the type for this input when
+  /// it has been preprocessed, or INVALID if this input is not
+  /// preprocessed.
+  ID getPreprocessedType(ID Id);
+
+  /// getTypeTempSuffix - Return the suffix to use when creating a
+  /// temp file of this type, or null if unspecified.
+  const char *getTypeTempSuffix(ID Id);
+
+  /// onlyAssembleType - Should this type only be assembled.
+  bool onlyAssembleType(ID Id);
+
+  /// onlyPrecompileType - Should this type only be precompiled.
+  bool onlyPrecompileType(ID Id);
+
+  /// canTypeBeUserSpecified - Can this type be specified on the
+  /// command line (by the type name); this is used when forwarding
+  /// commands to gcc.
+  bool canTypeBeUserSpecified(ID Id);
+
+  /// appendSuffixForType - When generating outputs of this type,
+  /// should the suffix be appended (instead of replacing the existing
+  /// suffix).
+  bool appendSuffixForType(ID Id);
+
+  /// canLipoType - Is this type acceptable as the output of a
+  /// universal build (currently, just the Nothing, Image, and Object
+  /// types).
+  bool canLipoType(ID Id);
+
+  /// isAcceptedByClang - Can clang handle this input type.
+  bool isAcceptedByClang(ID Id);
+
+  /// isCXX - Is this a "C++" input (C++ and Obj-C++ sources and headers).
+  bool isCXX(ID Id);
+
+  /// isObjC - Is this an "ObjC" input (Obj-C and Obj-C++ sources and headers).
+  bool isObjC(ID Id);
+
+  /// lookupTypeForExtension - Lookup the type to use for the file
+  /// extension \arg Ext.
+  ID lookupTypeForExtension(const char *Ext);
+
+  /// lookupTypeForTypSpecifier - Lookup the type to use for a user
+  /// specified type name.
+  ID lookupTypeForTypeSpecifier(const char *Name);
+
+  /// getNumCompilationPhases - Return the complete number of phases
+  /// to be done for this type.
+  unsigned getNumCompilationPhases(ID Id);
+
+  /// getCompilationPhase - Return the \args N th compilation phase to
+  /// be done for this type.
+  phases::ID getCompilationPhase(ID Id, unsigned N);
+  
+  /// lookupCXXTypeForCType - Lookup CXX input type that corresponds to given
+  /// C type (used for clang++ emulation of g++ behaviour)
+  ID lookupCXXTypeForCType(ID Id);
+
+} // end namespace types
+} // end namespace driver
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Driver/Util.h b/include/clang/Driver/Util.h
new file mode 100644
index 0000000..52f268d
--- /dev/null
+++ b/include/clang/Driver/Util.h
@@ -0,0 +1,30 @@
+//===--- Util.h - Common Driver Utilities -----------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_DRIVER_UTIL_H_
+#define CLANG_DRIVER_UTIL_H_
+
+namespace llvm {
+  template<typename T, unsigned N> class SmallVector;
+}
+
+namespace clang {
+namespace driver {
+  class Action;
+
+  /// ArgStringList - Type used for constructing argv lists for subprocesses.
+  typedef llvm::SmallVector<const char*, 16> ArgStringList;
+
+  /// ActionList - Type used for lists of actions.
+  typedef llvm::SmallVector<Action*, 3> ActionList;
+
+} // end namespace driver
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Frontend/ASTConsumers.h b/include/clang/Frontend/ASTConsumers.h
new file mode 100644
index 0000000..9163a20
--- /dev/null
+++ b/include/clang/Frontend/ASTConsumers.h
@@ -0,0 +1,87 @@
+//===--- ASTConsumers.h - ASTConsumer implementations -----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// AST Consumers.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef DRIVER_ASTCONSUMERS_H
+#define DRIVER_ASTCONSUMERS_H
+
+#include <string>
+
+namespace llvm {
+  class raw_ostream;
+  class Module;
+  class LLVMContext;
+  namespace sys { class Path; }
+}
+namespace clang {
+
+class ASTConsumer;
+class CodeGenOptions;
+class Diagnostic;
+class FileManager;
+class LangOptions;
+class Preprocessor;
+class TargetOptions;
+
+// AST pretty-printer: prints out the AST in a format that is close to the
+// original C code.  The output is intended to be in a format such that
+// clang could re-parse the output back into the same AST, but the
+// implementation is still incomplete.
+ASTConsumer *CreateASTPrinter(llvm::raw_ostream *OS);
+
+// AST XML-printer: prints out the AST in a XML format
+// The output is intended to be in a format such that
+// clang or any other tool could re-parse the output back into the same AST,
+// but the implementation is still incomplete.
+ASTConsumer *CreateASTPrinterXML(llvm::raw_ostream *OS);
+
+// AST dumper: dumps the raw AST in human-readable form to stderr; this is
+// intended for debugging.
+ASTConsumer *CreateASTDumper();
+
+// Graphical AST viewer: for each function definition, creates a graph of
+// the AST and displays it with the graph viewer "dotty".  Also outputs
+// function declarations to stderr.
+ASTConsumer *CreateASTViewer();
+
+// DeclContext printer: prints out the DeclContext tree in human-readable form
+// to stderr; this is intended for debugging.
+ASTConsumer *CreateDeclContextPrinter();
+
+// ObjC rewriter: attempts tp rewrite ObjC constructs into pure C code.
+// This is considered experimental, and only works with Apple's ObjC runtime.
+ASTConsumer *CreateObjCRewriter(const std::string &InFile,
+                                llvm::raw_ostream *OS,
+                                Diagnostic &Diags,
+                                const LangOptions &LOpts,
+                                bool SilenceRewriteMacroWarning);
+
+/// CreateHTMLPrinter - Create an AST consumer which rewrites source code to
+/// HTML with syntax highlighting suitable for viewing in a web-browser.
+ASTConsumer *CreateHTMLPrinter(llvm::raw_ostream *OS, Preprocessor &PP,
+                               bool SyntaxHighlight = true,
+                               bool HighlightMacros = true);
+
+// PCH generator: generates a precompiled header file; this file can be used
+// later with the PCHReader (clang -cc1 option -include-pch) to speed up compile
+// times.
+ASTConsumer *CreatePCHGenerator(const Preprocessor &PP,
+                                llvm::raw_ostream *OS,
+                                const char *isysroot = 0);
+
+// Inheritance viewer: for C++ code, creates a graph of the inheritance
+// tree for the given class and displays it with "dotty".
+ASTConsumer *CreateInheritanceViewer(const std::string& clsname);
+
+} // end clang namespace
+
+#endif
diff --git a/include/clang/Frontend/ASTUnit.h b/include/clang/Frontend/ASTUnit.h
new file mode 100644
index 0000000..9252358
--- /dev/null
+++ b/include/clang/Frontend/ASTUnit.h
@@ -0,0 +1,266 @@
+//===--- ASTUnit.h - ASTUnit utility ----------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// ASTUnit utility class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_ASTUNIT_H
+#define LLVM_CLANG_FRONTEND_ASTUNIT_H
+
+#include "clang/Lex/PreprocessingRecord.h"
+#include "clang/Basic/SourceManager.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Index/ASTLocation.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/System/Path.h"
+#include <map>
+#include <string>
+#include <vector>
+#include <cassert>
+#include <utility>
+
+namespace llvm {
+  class MemoryBuffer;
+}
+
+namespace clang {
+class ASTContext;
+class CompilerInvocation;
+class Decl;
+class Diagnostic;
+class FileEntry;
+class FileManager;
+class HeaderSearch;
+class Preprocessor;
+class SourceManager;
+class TargetInfo;
+
+using namespace idx;
+
+/// \brief Utility class for loading a ASTContext from a PCH file.
+///
+class ASTUnit {
+public:
+  typedef std::map<FileID, std::vector<PreprocessedEntity *> > 
+    PreprocessedEntitiesByFileMap;
+private:
+  llvm::IntrusiveRefCntPtr<Diagnostic> Diagnostics;
+  llvm::OwningPtr<FileManager>      FileMgr;
+  llvm::OwningPtr<SourceManager>    SourceMgr;
+  llvm::OwningPtr<HeaderSearch>     HeaderInfo;
+  llvm::OwningPtr<TargetInfo>       Target;
+  llvm::OwningPtr<Preprocessor>     PP;
+  llvm::OwningPtr<ASTContext>       Ctx;
+  
+  /// Optional owned invocation, just used to make the invocation used in
+  /// LoadFromCommandLine available.
+  llvm::OwningPtr<CompilerInvocation> Invocation;
+
+  // OnlyLocalDecls - when true, walking this AST should only visit declarations
+  // that come from the AST itself, not from included precompiled headers.
+  // FIXME: This is temporary; eventually, CIndex will always do this.
+  bool                              OnlyLocalDecls;
+
+  /// Track whether the main file was loaded from an AST or not.
+  bool MainFileIsAST;
+
+  /// Track the top-level decls which appeared in an ASTUnit which was loaded
+  /// from a source file.
+  //
+  // FIXME: This is just an optimization hack to avoid deserializing large parts
+  // of a PCH file when using the Index library on an ASTUnit loaded from
+  // source. In the long term we should make the Index library use efficient and
+  // more scalable search mechanisms.
+  std::vector<Decl*> TopLevelDecls;
+
+  /// The name of the original source file used to generate this ASTUnit.
+  std::string OriginalSourceFile;
+
+  // Critical optimization when using clang_getCursor().
+  ASTLocation LastLoc;
+
+  /// \brief The set of diagnostics produced when creating this
+  /// translation unit.
+  llvm::SmallVector<StoredDiagnostic, 4> StoredDiagnostics;
+
+  /// \brief Temporary files that should be removed when the ASTUnit is 
+  /// destroyed.
+  llvm::SmallVector<llvm::sys::Path, 4> TemporaryFiles;
+
+  /// \brief A mapping from file IDs to the set of preprocessed entities
+  /// stored in that file. 
+  ///
+  /// FIXME: This is just an optimization hack to avoid searching through
+  /// many preprocessed entities during cursor traversal in the CIndex library.
+  /// Ideally, we would just be able to perform a binary search within the
+  /// list of preprocessed entities.
+  PreprocessedEntitiesByFileMap PreprocessedEntitiesByFile;
+  
+  /// \brief Simple hack to allow us to assert that ASTUnit is not being
+  /// used concurrently, which is not supported.
+  ///
+  /// Clients should create instances of the ConcurrencyCheck class whenever
+  /// using the ASTUnit in a way that isn't intended to be concurrent, which is
+  /// just about any usage.
+  unsigned int ConcurrencyCheckValue;
+  static const unsigned int CheckLocked = 28573289;
+  static const unsigned int CheckUnlocked = 9803453;
+  
+  ASTUnit(const ASTUnit&); // DO NOT IMPLEMENT
+  ASTUnit &operator=(const ASTUnit &); // DO NOT IMPLEMENT
+  
+  explicit ASTUnit(bool MainFileIsAST);
+
+public:
+  class ConcurrencyCheck {
+    volatile ASTUnit &Self;
+    
+  public:
+    explicit ConcurrencyCheck(ASTUnit &Self)
+      : Self(Self) 
+    { 
+      assert(Self.ConcurrencyCheckValue == CheckUnlocked && 
+             "Concurrent access to ASTUnit!");
+      Self.ConcurrencyCheckValue = CheckLocked;
+    }
+    
+    ~ConcurrencyCheck() {
+      Self.ConcurrencyCheckValue = CheckUnlocked;
+    }
+  };
+  friend class ConcurrencyCheck;
+  
+  ~ASTUnit();
+
+  bool isMainFileAST() const { return MainFileIsAST; }
+
+  const Diagnostic &getDiagnostics() const { return *Diagnostics; }
+  Diagnostic &getDiagnostics()             { return *Diagnostics; }
+  
+  const SourceManager &getSourceManager() const { return *SourceMgr; }
+        SourceManager &getSourceManager()       { return *SourceMgr; }
+
+  const Preprocessor &getPreprocessor() const { return *PP.get(); }
+        Preprocessor &getPreprocessor()       { return *PP.get(); }
+
+  const ASTContext &getASTContext() const { return *Ctx.get(); }
+        ASTContext &getASTContext()       { return *Ctx.get(); }
+
+  const FileManager &getFileManager() const { return *FileMgr; }
+        FileManager &getFileManager()       { return *FileMgr; }
+
+  const std::string &getOriginalSourceFileName();
+  const std::string &getPCHFileName();
+
+  /// \brief Add a temporary file that the ASTUnit depends on.
+  ///
+  /// This file will be erased when the ASTUnit is destroyed.
+  void addTemporaryFile(const llvm::sys::Path &TempFile) {
+    TemporaryFiles.push_back(TempFile);
+  }
+                        
+  bool getOnlyLocalDecls() const { return OnlyLocalDecls; }
+
+  void setLastASTLocation(ASTLocation ALoc) { LastLoc = ALoc; }
+  ASTLocation getLastASTLocation() const { return LastLoc; }
+
+  std::vector<Decl*> &getTopLevelDecls() {
+    assert(!isMainFileAST() && "Invalid call for AST based ASTUnit!");
+    return TopLevelDecls;
+  }
+  const std::vector<Decl*> &getTopLevelDecls() const {
+    assert(!isMainFileAST() && "Invalid call for AST based ASTUnit!");
+    return TopLevelDecls;
+  }
+
+  /// \brief Retrieve the mapping from File IDs to the preprocessed entities
+  /// within that file.
+  PreprocessedEntitiesByFileMap &getPreprocessedEntitiesByFile() {
+    return PreprocessedEntitiesByFile;
+  }
+  
+  // Retrieve the diagnostics associated with this AST
+  typedef const StoredDiagnostic *stored_diag_iterator;
+  stored_diag_iterator stored_diag_begin() const { 
+    return StoredDiagnostics.begin(); 
+  }
+  stored_diag_iterator stored_diag_end() const { 
+    return StoredDiagnostics.end(); 
+  }
+  unsigned stored_diag_size() const { return StoredDiagnostics.size(); }
+  
+  llvm::SmallVector<StoredDiagnostic, 4> &getStoredDiagnostics() { 
+    return StoredDiagnostics; 
+  }
+
+  /// \brief A mapping from a file name to the memory buffer that stores the
+  /// remapped contents of that file.
+  typedef std::pair<std::string, const llvm::MemoryBuffer *> RemappedFile;
+  
+  /// \brief Create a ASTUnit from a PCH file.
+  ///
+  /// \param Filename - The PCH file to load.
+  ///
+  /// \param Diags - The diagnostics engine to use for reporting errors; its
+  /// lifetime is expected to extend past that of the returned ASTUnit.
+  ///
+  /// \returns - The initialized ASTUnit or null if the PCH failed to load.
+  static ASTUnit *LoadFromPCHFile(const std::string &Filename,
+                                  llvm::IntrusiveRefCntPtr<Diagnostic> Diags,
+                                  bool OnlyLocalDecls = false,
+                                  RemappedFile *RemappedFiles = 0,
+                                  unsigned NumRemappedFiles = 0,
+                                  bool CaptureDiagnostics = false);
+
+  /// LoadFromCompilerInvocation - Create an ASTUnit from a source file, via a
+  /// CompilerInvocation object.
+  ///
+  /// \param CI - The compiler invocation to use; it must have exactly one input
+  /// source file. The ASTUnit takes ownership of the CompilerInvocation object.
+  ///
+  /// \param Diags - The diagnostics engine to use for reporting errors; its
+  /// lifetime is expected to extend past that of the returned ASTUnit.
+  //
+  // FIXME: Move OnlyLocalDecls, UseBumpAllocator to setters on the ASTUnit, we
+  // shouldn't need to specify them at construction time.
+  static ASTUnit *LoadFromCompilerInvocation(CompilerInvocation *CI,
+                                     llvm::IntrusiveRefCntPtr<Diagnostic> Diags,
+                                             bool OnlyLocalDecls = false,
+                                             bool CaptureDiagnostics = false);
+
+  /// LoadFromCommandLine - Create an ASTUnit from a vector of command line
+  /// arguments, which must specify exactly one source file.
+  ///
+  /// \param ArgBegin - The beginning of the argument vector.
+  ///
+  /// \param ArgEnd - The end of the argument vector.
+  ///
+  /// \param Diags - The diagnostics engine to use for reporting errors; its
+  /// lifetime is expected to extend past that of the returned ASTUnit.
+  ///
+  /// \param ResourceFilesPath - The path to the compiler resource files.
+  //
+  // FIXME: Move OnlyLocalDecls, UseBumpAllocator to setters on the ASTUnit, we
+  // shouldn't need to specify them at construction time.
+  static ASTUnit *LoadFromCommandLine(const char **ArgBegin,
+                                      const char **ArgEnd,
+                                    llvm::IntrusiveRefCntPtr<Diagnostic> Diags,
+                                      llvm::StringRef ResourceFilesPath,
+                                      bool OnlyLocalDecls = false,
+                                      RemappedFile *RemappedFiles = 0,
+                                      unsigned NumRemappedFiles = 0,
+                                      bool CaptureDiagnostics = false);
+};
+
+} // namespace clang
+
+#endif
diff --git a/include/clang/Frontend/Analyses.def b/include/clang/Frontend/Analyses.def
new file mode 100644
index 0000000..287c67e
--- /dev/null
+++ b/include/clang/Frontend/Analyses.def
@@ -0,0 +1,90 @@
+//===-- Analyses.def - Metadata about Static Analyses -----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the set of static analyses used by AnalysisConsumer.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef ANALYSIS
+#define ANALYSIS(NAME, CMDFLAG, DESC, SCOPE)
+#endif
+
+ANALYSIS(CFGDump, "cfg-dump",
+         "Display Control-Flow Graphs", Code)
+
+ANALYSIS(CFGView, "cfg-view",
+         "View Control-Flow Graphs using GraphViz", Code)
+
+ANALYSIS(DisplayLiveVariables, "dump-live-variables",
+         "Print results of live variable analysis", Code)
+
+ANALYSIS(SecuritySyntacticChecks, "analyzer-check-security-syntactic",
+         "Perform quick security checks that require no data flow",
+         Code)
+
+ANALYSIS(LLVMConventionChecker, "analyzer-check-llvm-conventions",
+  "Check code for LLVM codebase conventions (domain-specific)",
+  TranslationUnit)
+
+ANALYSIS(WarnDeadStores, "analyzer-check-dead-stores",
+         "Warn about stores to dead variables", Code)
+
+ANALYSIS(WarnUninitVals, "warn-uninit-values",
+         "Warn about uses of uninitialized variables", Code)
+
+ANALYSIS(WarnObjCMethSigs, "analyzer-check-objc-methodsigs",
+ "Warn about Objective-C method signatures with type incompatibilities",
+ ObjCImplementation)
+
+ANALYSIS(WarnObjCDealloc, "analyzer-check-objc-missing-dealloc",
+ "Warn about Objective-C classes that lack a correct implementation of -dealloc",
+ ObjCImplementation)
+ 
+ANALYSIS(WarnObjCUnusedIvars, "analyzer-check-objc-unused-ivars",
+  "Warn about private ivars that are never used", ObjCImplementation)
+
+ANALYSIS(ObjCMemChecker, "analyzer-check-objc-mem",
+         "Run the [Core] Foundation reference count checker", Code)
+
+ANALYSIS(WarnSizeofPointer, "warn-sizeof-pointer",
+         "Warn about unintended use of sizeof() on pointer expressions", Code)
+
+ANALYSIS(InlineCall, "inline-call",
+         "Experimental transfer function inling callees when its definition"
+         " is available.", TranslationUnit)
+
+#ifndef ANALYSIS_STORE
+#define ANALYSIS_STORE(NAME, CMDFLAG, DESC, CREATFN)
+#endif
+
+ANALYSIS_STORE(BasicStore, "basic", "Use basic analyzer store", CreateBasicStoreManager)
+ANALYSIS_STORE(RegionStore, "region", "Use region-based analyzer store", CreateRegionStoreManager)
+ANALYSIS_STORE(FlatStore, "flat", "Use flat analyzer store", CreateFlatStoreManager)
+
+#ifndef ANALYSIS_CONSTRAINTS
+#define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATFN)
+#endif
+
+ANALYSIS_CONSTRAINTS(BasicConstraints, "basic", "Use basic constraint tracking", CreateBasicConstraintManager)
+ANALYSIS_CONSTRAINTS(RangeConstraints, "range", "Use constraint tracking of concrete value ranges", CreateRangeConstraintManager)
+
+#ifndef ANALYSIS_DIAGNOSTICS
+#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN, AUTOCREATE)
+#endif
+
+ANALYSIS_DIAGNOSTICS(HTML,  "html",  "Output analysis results using HTML",   CreateHTMLDiagnosticClient, false)
+ANALYSIS_DIAGNOSTICS(PLIST, "plist", "Output analysis results using Plists", CreatePlistDiagnosticClient, true)
+ANALYSIS_DIAGNOSTICS(PLIST_HTML, "plist-html", "Output analysis results using HTML wrapped with Plists", CreatePlistHTMLDiagnosticClient, true)
+
+#undef ANALYSIS
+#undef ANALYSIS_STORE
+#undef ANALYSIS_CONSTRAINTS
+#undef ANALYSIS_DIAGNOSTICS
+#undef ANALYSIS_STORE
+
diff --git a/include/clang/Frontend/AnalysisConsumer.h b/include/clang/Frontend/AnalysisConsumer.h
new file mode 100644
index 0000000..3341bb0
--- /dev/null
+++ b/include/clang/Frontend/AnalysisConsumer.h
@@ -0,0 +1,101 @@
+//===--- AnalysisConsumer.h - Front-end Analysis Engine Hooks ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header contains the functions necessary for a front-end to run various
+// analyses.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_ANALYSISCONSUMER_H
+#define LLVM_CLANG_FRONTEND_ANALYSISCONSUMER_H
+
+#include <string>
+#include <vector>
+
+namespace clang {
+class ASTConsumer;
+class Diagnostic;
+class Preprocessor;
+class LangOptions;
+
+/// Analysis - Set of available source code analyses.
+enum Analyses {
+#define ANALYSIS(NAME, CMDFLAG, DESC, SCOPE) NAME,
+#include "clang/Frontend/Analyses.def"
+NumAnalyses
+};
+
+/// AnalysisStores - Set of available analysis store models.
+enum AnalysisStores {
+#define ANALYSIS_STORE(NAME, CMDFLAG, DESC, CREATFN) NAME##Model,
+#include "clang/Frontend/Analyses.def"
+NumStores
+};
+
+/// AnalysisConstraints - Set of available constraint models.
+enum AnalysisConstraints {
+#define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATFN) NAME##Model,
+#include "clang/Frontend/Analyses.def"
+NumConstraints
+};
+
+/// AnalysisDiagClients - Set of available diagnostic clients for rendering
+///  analysis results.
+enum AnalysisDiagClients {
+#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN, AUTOCREAT) PD_##NAME,
+#include "clang/Frontend/Analyses.def"
+NUM_ANALYSIS_DIAG_CLIENTS
+};
+
+class AnalyzerOptions {
+public:
+  std::vector<Analyses> AnalysisList;
+  AnalysisStores AnalysisStoreOpt;
+  AnalysisConstraints AnalysisConstraintsOpt;
+  AnalysisDiagClients AnalysisDiagOpt;
+  std::string AnalyzeSpecificFunction;
+  unsigned MaxNodes;
+  unsigned AnalyzeAll : 1;
+  unsigned AnalyzerDisplayProgress : 1;
+  unsigned AnalyzeNestedBlocks : 1;
+  unsigned EagerlyAssume : 1;
+  unsigned PurgeDead : 1;
+  unsigned TrimGraph : 1;
+  unsigned VisualizeEGDot : 1;
+  unsigned VisualizeEGUbi : 1;
+  unsigned EnableExperimentalChecks : 1;
+  unsigned EnableExperimentalInternalChecks : 1;
+public:
+  AnalyzerOptions() {
+    AnalysisStoreOpt = BasicStoreModel;
+    AnalysisConstraintsOpt = RangeConstraintsModel;
+    AnalysisDiagOpt = PD_HTML;
+    AnalyzeAll = 0;
+    AnalyzerDisplayProgress = 0;
+    AnalyzeNestedBlocks = 0;
+    EagerlyAssume = 0;
+    PurgeDead = 1;
+    TrimGraph = 0;
+    VisualizeEGDot = 0;
+    VisualizeEGUbi = 0;
+    EnableExperimentalChecks = 0;
+    EnableExperimentalInternalChecks = 0;
+  }
+};
+
+/// CreateAnalysisConsumer - Creates an ASTConsumer to run various code
+/// analysis passes.  (The set of analyses run is controlled by command-line
+/// options.)
+ASTConsumer* CreateAnalysisConsumer(const Preprocessor &pp,
+                                    const std::string &output,
+                                    const AnalyzerOptions& Opts);
+
+}
+
+#endif
diff --git a/include/clang/Frontend/ChainedDiagnosticClient.h b/include/clang/Frontend/ChainedDiagnosticClient.h
new file mode 100644
index 0000000..2d5e128
--- /dev/null
+++ b/include/clang/Frontend/ChainedDiagnosticClient.h
@@ -0,0 +1,58 @@
+//===--- ChainedDiagnosticClient.h - Chain Diagnostic Clients ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_CHAINEDDIAGNOSTICCLIENT_H
+#define LLVM_CLANG_FRONTEND_CHAINEDDIAGNOSTICCLIENT_H
+
+#include "clang/Basic/Diagnostic.h"
+#include "llvm/ADT/OwningPtr.h"
+
+namespace clang {
+class LangOptions;
+
+/// ChainedDiagnosticClient - Chain two diagnostic clients so that diagnostics
+/// go to the first client and then the second. The first diagnostic client
+/// should be the "primary" client, and will be used for computing whether the
+/// diagnostics should be included in counts.
+class ChainedDiagnosticClient : public DiagnosticClient {
+  llvm::OwningPtr<DiagnosticClient> Primary;
+  llvm::OwningPtr<DiagnosticClient> Secondary;
+
+public:
+  ChainedDiagnosticClient(DiagnosticClient *_Primary,
+                          DiagnosticClient *_Secondary) {
+    Primary.reset(_Primary);
+    Secondary.reset(_Secondary);
+  }
+
+  virtual void BeginSourceFile(const LangOptions &LO,
+                               const Preprocessor *PP) {
+    Primary->BeginSourceFile(LO, PP);
+    Secondary->BeginSourceFile(LO, PP);
+  }
+
+  virtual void EndSourceFile() {
+    Secondary->EndSourceFile();
+    Primary->EndSourceFile();
+  }
+
+  virtual bool IncludeInDiagnosticCounts() const {
+    return Primary->IncludeInDiagnosticCounts();
+  }
+
+  virtual void HandleDiagnostic(Diagnostic::Level DiagLevel,
+                                const DiagnosticInfo &Info) {
+    Primary->HandleDiagnostic(DiagLevel, Info);
+    Secondary->HandleDiagnostic(DiagLevel, Info);
+  }
+};
+
+} // end namspace clang
+
+#endif
diff --git a/include/clang/Frontend/CodeGenAction.h b/include/clang/Frontend/CodeGenAction.h
new file mode 100644
index 0000000..a1e3c42
--- /dev/null
+++ b/include/clang/Frontend/CodeGenAction.h
@@ -0,0 +1,65 @@
+//===--- CodeGenAction.h - LLVM Code Generation Frontend Action -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/FrontendAction.h"
+#include "llvm/ADT/OwningPtr.h"
+
+namespace llvm {
+  class Module;
+}
+
+namespace clang {
+
+class CodeGenAction : public ASTFrontendAction {
+private:
+  unsigned Act;
+  llvm::OwningPtr<llvm::Module> TheModule;
+
+protected:
+  CodeGenAction(unsigned _Act);
+
+  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                         llvm::StringRef InFile);
+
+  virtual void EndSourceFileAction();
+
+public:
+  ~CodeGenAction();
+
+  /// takeModule - Take the generated LLVM module, for use after the action has
+  /// been run. The result may be null on failure.
+  llvm::Module *takeModule();
+};
+
+class EmitAssemblyAction : public CodeGenAction {
+public:
+  EmitAssemblyAction();
+};
+
+class EmitBCAction : public CodeGenAction {
+public:
+  EmitBCAction();
+};
+
+class EmitLLVMAction : public CodeGenAction {
+public:
+  EmitLLVMAction();
+};
+
+class EmitLLVMOnlyAction : public CodeGenAction {
+public:
+  EmitLLVMOnlyAction();
+};
+
+class EmitObjAction : public CodeGenAction {
+public:
+  EmitObjAction();
+};
+
+}
diff --git a/include/clang/Frontend/CommandLineSourceLoc.h b/include/clang/Frontend/CommandLineSourceLoc.h
new file mode 100644
index 0000000..bea468b
--- /dev/null
+++ b/include/clang/Frontend/CommandLineSourceLoc.h
@@ -0,0 +1,80 @@
+
+//===--- CommandLineSourceLoc.h - Parsing for source locations-*- C++ -*---===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Command line parsing for source locations.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_COMMANDLINESOURCELOC_H
+#define LLVM_CLANG_FRONTEND_COMMANDLINESOURCELOC_H
+
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace clang {
+
+/// \brief A source location that has been parsed on the command line.
+struct ParsedSourceLocation {
+  std::string FileName;
+  unsigned Line;
+  unsigned Column;
+
+public:
+  /// Construct a parsed source location from a string; the Filename is empty on
+  /// error.
+  static ParsedSourceLocation FromString(llvm::StringRef Str) {
+    ParsedSourceLocation PSL;
+    std::pair<llvm::StringRef, llvm::StringRef> ColSplit = Str.rsplit(':');
+    std::pair<llvm::StringRef, llvm::StringRef> LineSplit =
+      ColSplit.first.rsplit(':');
+
+    // If both tail splits were valid integers, return success.
+    if (!ColSplit.second.getAsInteger(10, PSL.Column) &&
+        !LineSplit.second.getAsInteger(10, PSL.Line))
+      PSL.FileName = LineSplit.first;
+
+    return PSL;
+  }
+};
+
+}
+
+namespace llvm {
+  namespace cl {
+    /// \brief Command-line option parser that parses source locations.
+    ///
+    /// Source locations are of the form filename:line:column.
+    template<>
+    class parser<clang::ParsedSourceLocation>
+      : public basic_parser<clang::ParsedSourceLocation> {
+    public:
+      inline bool parse(Option &O, StringRef ArgName, StringRef ArgValue,
+                 clang::ParsedSourceLocation &Val);
+    };
+
+    bool
+    parser<clang::ParsedSourceLocation>::
+    parse(Option &O, StringRef ArgName, StringRef ArgValue,
+          clang::ParsedSourceLocation &Val) {
+      using namespace clang;
+
+      Val = ParsedSourceLocation::FromString(ArgValue);
+      if (Val.FileName.empty()) {
+        errs() << "error: "
+               << "source location must be of the form filename:line:column\n";
+        return true;
+      }
+
+      return false;
+    }
+  }
+}
+
+#endif
diff --git a/include/clang/Frontend/CompilerInstance.h b/include/clang/Frontend/CompilerInstance.h
new file mode 100644
index 0000000..36720c9
--- /dev/null
+++ b/include/clang/Frontend/CompilerInstance.h
@@ -0,0 +1,589 @@
+//===-- CompilerInstance.h - Clang Compiler Instance ------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_COMPILERINSTANCE_H_
+#define LLVM_CLANG_FRONTEND_COMPILERINSTANCE_H_
+
+#include "clang/Frontend/CompilerInvocation.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/OwningPtr.h"
+#include <cassert>
+#include <list>
+#include <string>
+
+namespace llvm {
+class LLVMContext;
+class raw_ostream;
+class raw_fd_ostream;
+class Timer;
+}
+
+namespace clang {
+class ASTContext;
+class ASTConsumer;
+class CodeCompleteConsumer;
+class Diagnostic;
+class DiagnosticClient;
+class ExternalASTSource;
+class FileManager;
+class FrontendAction;
+class Preprocessor;
+class SourceManager;
+class TargetInfo;
+
+/// CompilerInstance - Helper class for managing a single instance of the Clang
+/// compiler.
+///
+/// The CompilerInstance serves two purposes:
+///  (1) It manages the various objects which are necessary to run the compiler,
+///      for example the preprocessor, the target information, and the AST
+///      context.
+///  (2) It provides utility routines for constructing and manipulating the
+///      common Clang objects.
+///
+/// The compiler instance generally owns the instance of all the objects that it
+/// manages. However, clients can still share objects by manually setting the
+/// object and retaking ownership prior to destroying the CompilerInstance.
+///
+/// The compiler instance is intended to simplify clients, but not to lock them
+/// in to the compiler instance for everything. When possible, utility functions
+/// come in two forms; a short form that reuses the CompilerInstance objects,
+/// and a long form that takes explicit instances of any required objects.
+class CompilerInstance {
+  /// The LLVM context used for this instance.
+  llvm::OwningPtr<llvm::LLVMContext> LLVMContext;
+
+  /// The options used in this compiler instance.
+  llvm::OwningPtr<CompilerInvocation> Invocation;
+
+  /// The diagnostics engine instance.
+  llvm::IntrusiveRefCntPtr<Diagnostic> Diagnostics;
+
+  /// The diagnostics client instance.
+  llvm::OwningPtr<DiagnosticClient> DiagClient;
+
+  /// The target being compiled for.
+  llvm::OwningPtr<TargetInfo> Target;
+
+  /// The file manager.
+  llvm::OwningPtr<FileManager> FileMgr;
+
+  /// The source manager.
+  llvm::OwningPtr<SourceManager> SourceMgr;
+
+  /// The preprocessor.
+  llvm::OwningPtr<Preprocessor> PP;
+
+  /// The AST context.
+  llvm::OwningPtr<ASTContext> Context;
+
+  /// The AST consumer.
+  llvm::OwningPtr<ASTConsumer> Consumer;
+
+  /// The code completion consumer.
+  llvm::OwningPtr<CodeCompleteConsumer> CompletionConsumer;
+
+  /// The frontend timer
+  llvm::OwningPtr<llvm::Timer> FrontendTimer;
+
+  /// The list of active output files.
+  std::list< std::pair<std::string, llvm::raw_ostream*> > OutputFiles;
+
+  void operator=(const CompilerInstance &);  // DO NOT IMPLEMENT
+  CompilerInstance(const CompilerInstance&); // DO NOT IMPLEMENT
+public:
+  CompilerInstance();
+  ~CompilerInstance();
+
+  /// @name High-Level Operations
+  /// {
+
+  /// ExecuteAction - Execute the provided action against the compiler's
+  /// CompilerInvocation object.
+  ///
+  /// This function makes the following assumptions:
+  ///
+  ///  - The invocation options should be initialized. This function does not
+  ///    handle the '-help' or '-version' options, clients should handle those
+  ///    directly.
+  ///
+  ///  - The diagnostics engine should have already been created by the client.
+  ///
+  ///  - No other CompilerInstance state should have been initialized (this is
+  ///    an unchecked error).
+  ///
+  ///  - Clients should have initialized any LLVM target features that may be
+  ///    required.
+  ///
+  ///  - Clients should eventually call llvm_shutdown() upon the completion of
+  ///    this routine to ensure that any managed objects are properly destroyed.
+  ///
+  /// Note that this routine may write output to 'stderr'.
+  ///
+  /// \param Act - The action to execute.
+  /// \return - True on success.
+  //
+  // FIXME: This function should take the stream to write any debugging /
+  // verbose output to as an argument.
+  //
+  // FIXME: Eliminate the llvm_shutdown requirement, that should either be part
+  // of the context or else not CompilerInstance specific.
+  bool ExecuteAction(FrontendAction &Act);
+
+  /// }
+  /// @name LLVM Context
+  /// {
+
+  bool hasLLVMContext() const { return LLVMContext != 0; }
+
+  llvm::LLVMContext &getLLVMContext() const {
+    assert(LLVMContext && "Compiler instance has no LLVM context!");
+    return *LLVMContext;
+  }
+
+  llvm::LLVMContext *takeLLVMContext() { return LLVMContext.take(); }
+
+  /// setLLVMContext - Replace the current LLVM context and take ownership of
+  /// \arg Value.
+  void setLLVMContext(llvm::LLVMContext *Value);
+
+  /// }
+  /// @name Compiler Invocation and Options
+  /// {
+
+  bool hasInvocation() const { return Invocation != 0; }
+
+  CompilerInvocation &getInvocation() {
+    assert(Invocation && "Compiler instance has no invocation!");
+    return *Invocation;
+  }
+
+  CompilerInvocation *takeInvocation() { return Invocation.take(); }
+
+  /// setInvocation - Replace the current invocation; the compiler instance
+  /// takes ownership of \arg Value.
+  void setInvocation(CompilerInvocation *Value);
+
+  /// }
+  /// @name Forwarding Methods
+  /// {
+
+  AnalyzerOptions &getAnalyzerOpts() {
+    return Invocation->getAnalyzerOpts();
+  }
+  const AnalyzerOptions &getAnalyzerOpts() const {
+    return Invocation->getAnalyzerOpts();
+  }
+
+  CodeGenOptions &getCodeGenOpts() {
+    return Invocation->getCodeGenOpts();
+  }
+  const CodeGenOptions &getCodeGenOpts() const {
+    return Invocation->getCodeGenOpts();
+  }
+
+  DependencyOutputOptions &getDependencyOutputOpts() {
+    return Invocation->getDependencyOutputOpts();
+  }
+  const DependencyOutputOptions &getDependencyOutputOpts() const {
+    return Invocation->getDependencyOutputOpts();
+  }
+
+  DiagnosticOptions &getDiagnosticOpts() {
+    return Invocation->getDiagnosticOpts();
+  }
+  const DiagnosticOptions &getDiagnosticOpts() const {
+    return Invocation->getDiagnosticOpts();
+  }
+
+  FrontendOptions &getFrontendOpts() {
+    return Invocation->getFrontendOpts();
+  }
+  const FrontendOptions &getFrontendOpts() const {
+    return Invocation->getFrontendOpts();
+  }
+
+  HeaderSearchOptions &getHeaderSearchOpts() {
+    return Invocation->getHeaderSearchOpts();
+  }
+  const HeaderSearchOptions &getHeaderSearchOpts() const {
+    return Invocation->getHeaderSearchOpts();
+  }
+
+  LangOptions &getLangOpts() {
+    return Invocation->getLangOpts();
+  }
+  const LangOptions &getLangOpts() const {
+    return Invocation->getLangOpts();
+  }
+
+  PreprocessorOptions &getPreprocessorOpts() {
+    return Invocation->getPreprocessorOpts();
+  }
+  const PreprocessorOptions &getPreprocessorOpts() const {
+    return Invocation->getPreprocessorOpts();
+  }
+
+  PreprocessorOutputOptions &getPreprocessorOutputOpts() {
+    return Invocation->getPreprocessorOutputOpts();
+  }
+  const PreprocessorOutputOptions &getPreprocessorOutputOpts() const {
+    return Invocation->getPreprocessorOutputOpts();
+  }
+
+  TargetOptions &getTargetOpts() {
+    return Invocation->getTargetOpts();
+  }
+  const TargetOptions &getTargetOpts() const {
+    return Invocation->getTargetOpts();
+  }
+
+  /// }
+  /// @name Diagnostics Engine
+  /// {
+
+  bool hasDiagnostics() const { return Diagnostics != 0; }
+
+  Diagnostic &getDiagnostics() const {
+    assert(Diagnostics && "Compiler instance has no diagnostics!");
+    return *Diagnostics;
+  }
+
+  /// setDiagnostics - Replace the current diagnostics engine; the compiler
+  /// instance takes ownership of \arg Value.
+  void setDiagnostics(Diagnostic *Value);
+
+  DiagnosticClient &getDiagnosticClient() const {
+    assert(DiagClient && "Compiler instance has no diagnostic client!");
+    return *DiagClient;
+  }
+
+  /// takeDiagnosticClient - Remove the current diagnostics client and give
+  /// ownership to the caller.
+  DiagnosticClient *takeDiagnosticClient() { return DiagClient.take(); }
+
+  /// setDiagnosticClient - Replace the current diagnostics client; the compiler
+  /// instance takes ownership of \arg Value.
+  void setDiagnosticClient(DiagnosticClient *Value);
+
+  /// }
+  /// @name Target Info
+  /// {
+
+  bool hasTarget() const { return Target != 0; }
+
+  TargetInfo &getTarget() const {
+    assert(Target && "Compiler instance has no target!");
+    return *Target;
+  }
+
+  /// takeTarget - Remove the current diagnostics engine and give ownership
+  /// to the caller.
+  TargetInfo *takeTarget() { return Target.take(); }
+
+  /// setTarget - Replace the current diagnostics engine; the compiler
+  /// instance takes ownership of \arg Value.
+  void setTarget(TargetInfo *Value);
+
+  /// }
+  /// @name File Manager
+  /// {
+
+  bool hasFileManager() const { return FileMgr != 0; }
+
+  FileManager &getFileManager() const {
+    assert(FileMgr && "Compiler instance has no file manager!");
+    return *FileMgr;
+  }
+
+  /// takeFileManager - Remove the current file manager and give ownership to
+  /// the caller.
+  FileManager *takeFileManager() { return FileMgr.take(); }
+
+  /// setFileManager - Replace the current file manager; the compiler instance
+  /// takes ownership of \arg Value.
+  void setFileManager(FileManager *Value);
+
+  /// }
+  /// @name Source Manager
+  /// {
+
+  bool hasSourceManager() const { return SourceMgr != 0; }
+
+  SourceManager &getSourceManager() const {
+    assert(SourceMgr && "Compiler instance has no source manager!");
+    return *SourceMgr;
+  }
+
+  /// takeSourceManager - Remove the current source manager and give ownership
+  /// to the caller.
+  SourceManager *takeSourceManager() { return SourceMgr.take(); }
+
+  /// setSourceManager - Replace the current source manager; the compiler
+  /// instance takes ownership of \arg Value.
+  void setSourceManager(SourceManager *Value);
+
+  /// }
+  /// @name Preprocessor
+  /// {
+
+  bool hasPreprocessor() const { return PP != 0; }
+
+  Preprocessor &getPreprocessor() const {
+    assert(PP && "Compiler instance has no preprocessor!");
+    return *PP;
+  }
+
+  /// takePreprocessor - Remove the current preprocessor and give ownership to
+  /// the caller.
+  Preprocessor *takePreprocessor() { return PP.take(); }
+
+  /// setPreprocessor - Replace the current preprocessor; the compiler instance
+  /// takes ownership of \arg Value.
+  void setPreprocessor(Preprocessor *Value);
+
+  /// }
+  /// @name ASTContext
+  /// {
+
+  bool hasASTContext() const { return Context != 0; }
+
+  ASTContext &getASTContext() const {
+    assert(Context && "Compiler instance has no AST context!");
+    return *Context;
+  }
+
+  /// takeASTContext - Remove the current AST context and give ownership to the
+  /// caller.
+  ASTContext *takeASTContext() { return Context.take(); }
+
+  /// setASTContext - Replace the current AST context; the compiler instance
+  /// takes ownership of \arg Value.
+  void setASTContext(ASTContext *Value);
+
+  /// }
+  /// @name ASTConsumer
+  /// {
+
+  bool hasASTConsumer() const { return Consumer != 0; }
+
+  ASTConsumer &getASTConsumer() const {
+    assert(Consumer && "Compiler instance has no AST consumer!");
+    return *Consumer;
+  }
+
+  /// takeASTConsumer - Remove the current AST consumer and give ownership to
+  /// the caller.
+  ASTConsumer *takeASTConsumer() { return Consumer.take(); }
+
+  /// setASTConsumer - Replace the current AST consumer; the compiler instance
+  /// takes ownership of \arg Value.
+  void setASTConsumer(ASTConsumer *Value);
+
+  /// }
+  /// @name Code Completion
+  /// {
+
+  bool hasCodeCompletionConsumer() const { return CompletionConsumer != 0; }
+
+  CodeCompleteConsumer &getCodeCompletionConsumer() const {
+    assert(CompletionConsumer &&
+           "Compiler instance has no code completion consumer!");
+    return *CompletionConsumer;
+  }
+
+  /// takeCodeCompletionConsumer - Remove the current code completion consumer
+  /// and give ownership to the caller.
+  CodeCompleteConsumer *takeCodeCompletionConsumer() {
+    return CompletionConsumer.take();
+  }
+
+  /// setCodeCompletionConsumer - Replace the current code completion consumer;
+  /// the compiler instance takes ownership of \arg Value.
+  void setCodeCompletionConsumer(CodeCompleteConsumer *Value);
+
+  /// }
+  /// @name Frontend timer
+  /// {
+
+  bool hasFrontendTimer() const { return FrontendTimer != 0; }
+
+  llvm::Timer &getFrontendTimer() const {
+    assert(FrontendTimer && "Compiler instance has no frontend timer!");
+    return *FrontendTimer;
+  }
+
+  /// }
+  /// @name Output Files
+  /// {
+
+  /// getOutputFileList - Get the list of (path, output stream) pairs of output
+  /// files; the path may be empty but the stream will always be non-null.
+  const std::list< std::pair<std::string,
+                             llvm::raw_ostream*> > &getOutputFileList() const;
+
+  /// addOutputFile - Add an output file onto the list of tracked output files.
+  ///
+  /// \param Path - The path to the output file, or empty.
+  /// \param OS - The output stream, which should be non-null.
+  void addOutputFile(llvm::StringRef Path, llvm::raw_ostream *OS);
+
+  /// clearOutputFiles - Clear the output file list, destroying the contained
+  /// output streams.
+  ///
+  /// \param EraseFiles - If true, attempt to erase the files from disk.
+  void clearOutputFiles(bool EraseFiles);
+
+  /// }
+  /// @name Construction Utility Methods
+  /// {
+
+  /// Create the diagnostics engine using the invocation's diagnostic options
+  /// and replace any existing one with it.
+  ///
+  /// Note that this routine also replaces the diagnostic client.
+  void createDiagnostics(int Argc, char **Argv);
+
+  /// Create a Diagnostic object with a the TextDiagnosticPrinter.
+  ///
+  /// The \arg Argc and \arg Argv arguments are used only for logging purposes,
+  /// when the diagnostic options indicate that the compiler should output
+  /// logging information.
+  ///
+  /// Note that this creates an unowned DiagnosticClient, if using directly the
+  /// caller is responsible for releasing the returned Diagnostic's client
+  /// eventually.
+  ///
+  /// \param Opts - The diagnostic options; note that the created text
+  /// diagnostic object contains a reference to these options and its lifetime
+  /// must extend past that of the diagnostic engine.
+  ///
+  /// \return The new object on success, or null on failure.
+  static llvm::IntrusiveRefCntPtr<Diagnostic> 
+  createDiagnostics(const DiagnosticOptions &Opts, int Argc, char **Argv);
+
+  /// Create the file manager and replace any existing one with it.
+  void createFileManager();
+
+  /// Create the source manager and replace any existing one with it.
+  void createSourceManager();
+
+  /// Create the preprocessor, using the invocation, file, and source managers,
+  /// and replace any existing one with it.
+  void createPreprocessor();
+
+  /// Create a Preprocessor object.
+  ///
+  /// Note that this also creates a new HeaderSearch object which will be owned
+  /// by the resulting Preprocessor.
+  ///
+  /// \return The new object on success, or null on failure.
+  static Preprocessor *createPreprocessor(Diagnostic &, const LangOptions &,
+                                          const PreprocessorOptions &,
+                                          const HeaderSearchOptions &,
+                                          const DependencyOutputOptions &,
+                                          const TargetInfo &,
+                                          const FrontendOptions &,
+                                          SourceManager &, FileManager &);
+
+  /// Create the AST context.
+  void createASTContext();
+
+  /// Create an external AST source to read a PCH file and attach it to the AST
+  /// context.
+  void createPCHExternalASTSource(llvm::StringRef Path);
+
+  /// Create an external AST source to read a PCH file.
+  ///
+  /// \return - The new object on success, or null on failure.
+  static ExternalASTSource *
+  createPCHExternalASTSource(llvm::StringRef Path, const std::string &Sysroot,
+                             Preprocessor &PP, ASTContext &Context);
+
+  /// Create a code completion consumer using the invocation; note that this
+  /// will cause the source manager to truncate the input source file at the
+  /// completion point.
+  void createCodeCompletionConsumer();
+
+  /// Create a code completion consumer to print code completion results, at
+  /// \arg Filename, \arg Line, and \arg Column, to the given output stream \arg
+  /// OS.
+  static CodeCompleteConsumer *
+  createCodeCompletionConsumer(Preprocessor &PP, const std::string &Filename,
+                               unsigned Line, unsigned Column,
+                               bool UseDebugPrinter, bool ShowMacros,
+                               llvm::raw_ostream &OS);
+
+  /// Create the frontend timer and replace any existing one with it.
+  void createFrontendTimer();
+
+  /// Create the default output file (from the invocation's options) and add it
+  /// to the list of tracked output files.
+  ///
+  /// \return - Null on error.
+  llvm::raw_fd_ostream *
+  createDefaultOutputFile(bool Binary = true, llvm::StringRef BaseInput = "",
+                          llvm::StringRef Extension = "");
+
+  /// Create a new output file and add it to the list of tracked output files,
+  /// optionally deriving the output path name.
+  ///
+  /// \return - Null on error.
+  llvm::raw_fd_ostream *
+  createOutputFile(llvm::StringRef OutputPath, bool Binary = true,
+                   llvm::StringRef BaseInput = "",
+                   llvm::StringRef Extension = "");
+
+  /// Create a new output file, optionally deriving the output path name.
+  ///
+  /// If \arg OutputPath is empty, then createOutputFile will derive an output
+  /// path location as \arg BaseInput, with any suffix removed, and \arg
+  /// Extension appended.
+  ///
+  /// \param OutputPath - If given, the path to the output file.
+  /// \param Error [out] - On failure, the error message.
+  /// \param BaseInput - If \arg OutputPath is empty, the input path name to use
+  /// for deriving the output path.
+  /// \param Extension - The extension to use for derived output names.
+  /// \param Binary - The mode to open the file in.
+  /// \param ResultPathName [out] - If given, the result path name will be
+  /// stored here on success.
+  static llvm::raw_fd_ostream *
+  createOutputFile(llvm::StringRef OutputPath, std::string &Error,
+                   bool Binary = true, llvm::StringRef BaseInput = "",
+                   llvm::StringRef Extension = "",
+                   std::string *ResultPathName = 0);
+
+  /// }
+  /// @name Initialization Utility Methods
+  /// {
+
+  /// InitializeSourceManager - Initialize the source manager to set InputFile
+  /// as the main file.
+  ///
+  /// \return True on success.
+  bool InitializeSourceManager(llvm::StringRef InputFile);
+
+  /// InitializeSourceManager - Initialize the source manager to set InputFile
+  /// as the main file.
+  ///
+  /// \return True on success.
+  static bool InitializeSourceManager(llvm::StringRef InputFile,
+                                      Diagnostic &Diags,
+                                      FileManager &FileMgr,
+                                      SourceManager &SourceMgr,
+                                      const FrontendOptions &Opts);
+
+  /// }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Frontend/CompilerInvocation.h b/include/clang/Frontend/CompilerInvocation.h
new file mode 100644
index 0000000..f5a9053
--- /dev/null
+++ b/include/clang/Frontend/CompilerInvocation.h
@@ -0,0 +1,162 @@
+//===-- CompilerInvocation.h - Compiler Invocation Helper Data --*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_COMPILERINVOCATION_H_
+#define LLVM_CLANG_FRONTEND_COMPILERINVOCATION_H_
+
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/TargetOptions.h"
+#include "clang/CodeGen/CodeGenOptions.h"
+#include "clang/Frontend/AnalysisConsumer.h"
+#include "clang/Frontend/DependencyOutputOptions.h"
+#include "clang/Frontend/DiagnosticOptions.h"
+#include "clang/Frontend/FrontendOptions.h"
+#include "clang/Frontend/HeaderSearchOptions.h"
+#include "clang/Frontend/PreprocessorOptions.h"
+#include "clang/Frontend/PreprocessorOutputOptions.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringMap.h"
+#include <string>
+#include <vector>
+
+namespace llvm {
+  template<typename T> class SmallVectorImpl;
+}
+
+namespace clang {
+
+class Diagnostic;
+
+/// CompilerInvocation - Helper class for holding the data necessary to invoke
+/// the compiler.
+///
+/// This class is designed to represent an abstract "invocation" of the
+/// compiler, including data such as the include paths, the code generation
+/// options, the warning flags, and so on.
+class CompilerInvocation {
+  /// Options controlling the static analyzer.
+  AnalyzerOptions AnalyzerOpts;
+
+  /// Options controlling IRgen and the backend.
+  CodeGenOptions CodeGenOpts;
+
+  /// Options controlling dependency output.
+  DependencyOutputOptions DependencyOutputOpts;
+
+  /// Options controlling the diagnostic engine.
+  DiagnosticOptions DiagnosticOpts;
+
+  /// Options controlling the frontend itself.
+  FrontendOptions FrontendOpts;
+
+  /// Options controlling the #include directive.
+  HeaderSearchOptions HeaderSearchOpts;
+
+  /// Options controlling the language variant.
+  LangOptions LangOpts;
+
+  /// Options controlling the preprocessor (aside from #include handling).
+  PreprocessorOptions PreprocessorOpts;
+
+  /// Options controlling preprocessed output.
+  PreprocessorOutputOptions PreprocessorOutputOpts;
+
+  /// Options controlling the target.
+  TargetOptions TargetOpts;
+
+public:
+  CompilerInvocation() {}
+
+  /// @name Utility Methods
+  /// @{
+
+  /// CreateFromArgs - Create a compiler invocation from a list of input
+  /// options.
+  ///
+  /// \param Res [out] - The resulting invocation.
+  /// \param ArgBegin - The first element in the argument vector.
+  /// \param ArgEnd - The last element in the argument vector.
+  /// \param Diags - The diagnostic engine to use for errors.
+  static void CreateFromArgs(CompilerInvocation &Res, const char **ArgBegin,
+                             const char **ArgEnd, Diagnostic &Diags);
+
+  /// GetBuiltinIncludePath - Get the directory where the compiler headers
+  /// reside, relative to the compiler binary (found by the passed in
+  /// arguments).
+  ///
+  /// \param Argv0 - The program path (from argv[0]), for finding the builtin
+  /// compiler path.
+  /// \param MainAddr - The address of main (or some other function in the main
+  /// executable), for finding the builtin compiler path.
+  static std::string GetResourcesPath(const char *Argv0, void *MainAddr);
+
+  /// toArgs - Convert the CompilerInvocation to a list of strings suitable for
+  /// passing to CreateFromArgs.
+  void toArgs(std::vector<std::string> &Res);
+
+  /// @}
+  /// @name Option Subgroups
+  /// @{
+
+  AnalyzerOptions &getAnalyzerOpts() { return AnalyzerOpts; }
+  const AnalyzerOptions &getAnalyzerOpts() const {
+    return AnalyzerOpts;
+  }
+
+  CodeGenOptions &getCodeGenOpts() { return CodeGenOpts; }
+  const CodeGenOptions &getCodeGenOpts() const {
+    return CodeGenOpts;
+  }
+
+  DependencyOutputOptions &getDependencyOutputOpts() {
+    return DependencyOutputOpts;
+  }
+  const DependencyOutputOptions &getDependencyOutputOpts() const {
+    return DependencyOutputOpts;
+  }
+
+  DiagnosticOptions &getDiagnosticOpts() { return DiagnosticOpts; }
+  const DiagnosticOptions &getDiagnosticOpts() const { return DiagnosticOpts; }
+
+  HeaderSearchOptions &getHeaderSearchOpts() { return HeaderSearchOpts; }
+  const HeaderSearchOptions &getHeaderSearchOpts() const {
+    return HeaderSearchOpts;
+  }
+
+  FrontendOptions &getFrontendOpts() { return FrontendOpts; }
+  const FrontendOptions &getFrontendOpts() const {
+    return FrontendOpts;
+  }
+
+  LangOptions &getLangOpts() { return LangOpts; }
+  const LangOptions &getLangOpts() const { return LangOpts; }
+
+  PreprocessorOptions &getPreprocessorOpts() { return PreprocessorOpts; }
+  const PreprocessorOptions &getPreprocessorOpts() const {
+    return PreprocessorOpts;
+  }
+
+  PreprocessorOutputOptions &getPreprocessorOutputOpts() {
+    return PreprocessorOutputOpts;
+  }
+  const PreprocessorOutputOptions &getPreprocessorOutputOpts() const {
+    return PreprocessorOutputOpts;
+  }
+
+  TargetOptions &getTargetOpts() { return TargetOpts; }
+  const TargetOptions &getTargetOpts() const {
+    return TargetOpts;
+  }
+
+  /// @}
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Frontend/DeclContextXML.def b/include/clang/Frontend/DeclContextXML.def
new file mode 100644
index 0000000..39ed5f9
--- /dev/null
+++ b/include/clang/Frontend/DeclContextXML.def
@@ -0,0 +1,113 @@
+//===-- DeclContextXML.def - Metadata about Context XML nodes ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the XML context info database as written in the   
+//  <ReferenceSection>/<Contexts> sub-nodes of the XML document. Type nodes 
+//  are referred by "context" reference attributes throughout the document.
+//  A context node never contains sub-nodes. 
+//  The semantics of the attributes and enums are mostly self-documenting
+//  by looking at the appropriate internally used functions and values.
+//  The following macros are used:
+//
+//  NODE_XML( CLASS, NAME ) - A node of name NAME denotes a concrete 
+//  context of class CLASS where CLASS is a class name used internally by clang. 
+//  After a NODE_XML the definition of all (optional) attributes of that context 
+//  node and possible sub-nodes follows.
+//
+//  END_NODE_XML - Closes the attribute definition of the current node.
+//
+//  ID_ATTRIBUTE_XML - Context nodes have an "id" attribute containing a 
+//  string, which value uniquely identify that statement. Other nodes may refer 
+//  by "context" attributes to this value.
+//
+//  TYPE_ATTRIBUTE_XML( FN ) - Context nodes may refer to the ids of type 
+//  nodes by a "type" attribute, if they create a type during declaration. 
+//  For instance 'struct S;' creates both a context 'S::' and a type 'S'. 
+//  Contexts and types always have different ids, however declarations and 
+//  contexts may share the same ids. FN is internally used by clang.
+// 
+//  ATTRIBUTE_XML( FN, NAME ) - An attribute named NAME. FN is internally 
+//  used by clang. A boolean attribute have the values "0" or "1".
+//
+//  ATTRIBUTE_ENUM[_OPT]_XML( FN, NAME ) - An attribute named NAME. The value
+//  is an enumeration defined with ENUM_XML macros immediately following after 
+//  that macro. An optional attribute is ommited, if the particular enum is the 
+//  empty string. FN is internally used by clang.
+//  
+//  ENUM_XML( VALUE, NAME ) - An enumeration element named NAME. VALUE is 
+//  internally used by clang.
+//
+//  END_ENUM_XML - Closes the enumeration definition of the current attribute.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef TYPE_ATTRIBUTE_XML
+#  define TYPE_ATTRIBUTE_XML( FN )     ATTRIBUTE_XML(FN, "type")
+#endif
+
+#ifndef CONTEXT_ATTRIBUTE_XML
+#  define CONTEXT_ATTRIBUTE_XML( FN )  ATTRIBUTE_XML(FN, "context")
+#endif
+
+NODE_XML(TranslationUnitDecl, "TranslationUnit")
+  ID_ATTRIBUTE_XML
+END_NODE_XML
+
+NODE_XML(FunctionDecl, "Function")
+  ID_ATTRIBUTE_XML
+  ATTRIBUTE_XML(getDeclContext(), "context")
+  ATTRIBUTE_XML(getNameAsString(), "name")
+  TYPE_ATTRIBUTE_XML(getType()->getAsFunctionType())
+END_NODE_XML
+
+NODE_XML(NamespaceDecl, "Namespace")
+  ID_ATTRIBUTE_XML
+  ATTRIBUTE_XML(getDeclContext(), "context")
+  ATTRIBUTE_XML(getNameAsString(), "name")
+END_NODE_XML
+
+NODE_XML(RecordDecl, "Record")
+  ID_ATTRIBUTE_XML
+  ATTRIBUTE_XML(getDeclContext(), "context")
+  ATTRIBUTE_XML(getNameAsString(), "name")
+  TYPE_ATTRIBUTE_XML(getTypeForDecl()) 
+END_NODE_XML
+
+NODE_XML(EnumDecl, "Enum")
+  ID_ATTRIBUTE_XML
+  ATTRIBUTE_XML(getDeclContext(), "context")
+  ATTRIBUTE_XML(getNameAsString(), "name")
+  TYPE_ATTRIBUTE_XML(getTypeForDecl()) 
+END_NODE_XML
+
+NODE_XML(LinkageSpecDecl, "LinkageSpec")
+  ID_ATTRIBUTE_XML
+  ATTRIBUTE_XML(getDeclContext(), "context")
+  ATTRIBUTE_ENUM_OPT_XML(getLanguage(), "lang")
+	  ENUM_XML(LinkageSpecDecl::lang_c, "C")
+	  ENUM_XML(LinkageSpecDecl::lang_cxx, "CXX")
+  END_ENUM_XML
+END_NODE_XML
+
+//===----------------------------------------------------------------------===//
+#undef NODE_XML
+#undef ID_ATTRIBUTE_XML                
+#undef TYPE_ATTRIBUTE_XML
+#undef ATTRIBUTE_XML
+#undef ATTRIBUTE_SPECIAL_XML
+#undef ATTRIBUTE_OPT_XML
+#undef ATTRIBUTE_ENUM_XML
+#undef ATTRIBUTE_ENUM_OPT_XML
+#undef ATTRIBUTE_FILE_LOCATION_XML
+#undef ENUM_XML
+#undef END_ENUM_XML                    
+#undef END_NODE_XML                    
+#undef SUB_NODE_XML
+#undef SUB_NODE_SEQUENCE_XML
+#undef SUB_NODE_OPT_XML
diff --git a/include/clang/Frontend/DeclXML.def b/include/clang/Frontend/DeclXML.def
new file mode 100644
index 0000000..e839a8c
--- /dev/null
+++ b/include/clang/Frontend/DeclXML.def
@@ -0,0 +1,257 @@
+//===-- DeclXML.def - Metadata about Decl XML nodes ------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the XML statement database structure as written in
+//  <TranslationUnit> sub-nodes of the XML document.
+//  The semantics of the attributes and enums are mostly self-documenting
+//  by looking at the appropriate internally used functions and values.
+//  The following macros are used:
+//
+//  NODE_XML( CLASS, NAME ) - A node of name NAME denotes a concrete
+//  statement of class CLASS where CLASS is a class name used internally by clang.
+//  After a NODE_XML the definition of all (optional) attributes of that statement
+//  node and possible sub-nodes follows.
+//
+//  END_NODE_XML - Closes the attribute definition of the current node.
+//
+//  ID_ATTRIBUTE_XML - Some statement nodes have an "id" attribute containing a
+//  string, which value uniquely identify that statement. Other nodes may refer
+//  by reference attributes to this value (currently used only for Label).
+//
+//  TYPE_ATTRIBUTE_XML( FN ) - Type nodes refer to the result type id of an
+//  expression by a "type" attribute. FN is internally used by clang.
+//
+//  ATTRIBUTE_XML( FN, NAME ) - An attribute named NAME. FN is internally
+//  used by clang. A boolean attribute have the values "0" or "1".
+//
+//  ATTRIBUTE_SPECIAL_XML( FN, NAME ) - An attribute named NAME which deserves
+//  a special handling. See the appropriate documentations.
+//
+//  ATTRIBUTE_FILE_LOCATION_XML - A bunch of attributes denoting the location of
+//  a statement in the source file(s).
+//
+//  ATTRIBUTE_OPT_XML( FN, NAME ) - An optional attribute named NAME.
+//  Optional attributes are omitted for boolean types, if the value is false,
+//  for integral types, if the value is null and for strings,
+//  if the value is the empty string. FN is internally used by clang.
+//
+//  ATTRIBUTE_ENUM[_OPT]_XML( FN, NAME ) - An attribute named NAME. The value
+//  is an enumeration defined with ENUM_XML macros immediately following after
+//  that macro. An optional attribute is ommited, if the particular enum is the
+//  empty string. FN is internally used by clang.
+//
+//  ENUM_XML( VALUE, NAME ) - An enumeration element named NAME. VALUE is
+//  internally used by clang.
+//
+//  END_ENUM_XML - Closes the enumeration definition of the current attribute.
+//
+//  SUB_NODE_XML( CLASS ) - A mandatory sub-node of class CLASS or its sub-classes.
+//
+//  SUB_NODE_OPT_XML( CLASS ) - An optional sub-node of class CLASS or its sub-classes.
+//
+//  SUB_NODE_SEQUENCE_XML( CLASS ) - Zero or more sub-nodes of class CLASS or
+//  its sub-classes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef ATTRIBUTE_FILE_LOCATION_XML
+#  define ATTRIBUTE_FILE_LOCATION_XML             \
+     ATTRIBUTE_XML(getFilename(), "file")         \
+     ATTRIBUTE_XML(getLine(), "line")             \
+     ATTRIBUTE_XML(getColumn(), "col")            \
+     ATTRIBUTE_OPT_XML(getFilename(), "endfile")  \
+     ATTRIBUTE_OPT_XML(getLine(), "endline")      \
+     ATTRIBUTE_OPT_XML(getColumn(), "endcol")
+#endif
+
+#ifndef TYPE_ATTRIBUTE_XML
+#  define TYPE_ATTRIBUTE_XML( FN )    ATTRIBUTE_XML(FN, "type")
+#endif
+
+#ifndef CONTEXT_ATTRIBUTE_XML
+#  define CONTEXT_ATTRIBUTE_XML( FN ) ATTRIBUTE_XML(FN, "context")
+#endif
+
+//NODE_XML(TranslationUnitDecl, "TranslationUnit")
+//  SUB_NODE_SEQUENCE_XML(Decl)
+//END_NODE_XML
+
+NODE_XML(Decl, "FIXME_Decl")
+  ATTRIBUTE_FILE_LOCATION_XML
+END_NODE_XML
+
+NODE_XML(FunctionDecl, "Function")
+  ID_ATTRIBUTE_XML
+  ATTRIBUTE_FILE_LOCATION_XML
+  ATTRIBUTE_XML(getDeclContext(), "context")
+  ATTRIBUTE_XML(getNameAsString(), "name")
+  TYPE_ATTRIBUTE_XML(getType()->getAs<FunctionType>()->getResultType())
+  ATTRIBUTE_XML(getType()->getAs<FunctionType>(), "function_type")
+  ATTRIBUTE_ENUM_OPT_XML(getStorageClass(), "storage_class")
+	  ENUM_XML(FunctionDecl::None, "")
+	  ENUM_XML(FunctionDecl::Extern, "extern")
+	  ENUM_XML(FunctionDecl::Static, "static")
+	  ENUM_XML(FunctionDecl::PrivateExtern, "__private_extern__")
+  END_ENUM_XML
+  ATTRIBUTE_OPT_XML(isInlineSpecified(), "inline")
+  //ATTRIBUTE_OPT_XML(isVariadic(), "variadic")       // in the type reference
+  ATTRIBUTE_XML(getNumParams(), "num_args")
+  SUB_NODE_SEQUENCE_XML(ParmVarDecl)
+  SUB_NODE_FN_BODY_XML
+END_NODE_XML
+
+NODE_XML(CXXMethodDecl, "CXXMethodDecl")
+  ID_ATTRIBUTE_XML
+  ATTRIBUTE_FILE_LOCATION_XML
+  ATTRIBUTE_XML(getDeclContext(), "context")
+  ATTRIBUTE_XML(getNameAsString(), "name")
+  TYPE_ATTRIBUTE_XML(getType()->getAs<FunctionType>()->getResultType())
+  ATTRIBUTE_XML(getType()->getAs<FunctionType>(), "function_type")
+  ATTRIBUTE_OPT_XML(isInlineSpecified(), "inline")
+  ATTRIBUTE_OPT_XML(isStatic(), "static")
+  ATTRIBUTE_OPT_XML(isVirtual(), "virtual")
+  ATTRIBUTE_XML(getNumParams(), "num_args")
+  SUB_NODE_SEQUENCE_XML(ParmVarDecl)
+  SUB_NODE_FN_BODY_XML
+END_NODE_XML
+
+NODE_XML(NamespaceDecl, "Namespace")
+  ID_ATTRIBUTE_XML
+  ATTRIBUTE_FILE_LOCATION_XML
+  ATTRIBUTE_XML(getDeclContext(), "context")
+  ATTRIBUTE_XML(getNameAsString(), "name")
+END_NODE_XML
+
+NODE_XML(UsingDirectiveDecl, "UsingDirective")
+  ATTRIBUTE_FILE_LOCATION_XML
+  ATTRIBUTE_XML(getDeclContext(), "context")
+  ATTRIBUTE_XML(getNameAsString(), "name")
+  ATTRIBUTE_XML(getNominatedNamespace(), "ref")
+END_NODE_XML
+
+NODE_XML(NamespaceAliasDecl, "NamespaceAlias")
+  ATTRIBUTE_FILE_LOCATION_XML
+  ATTRIBUTE_XML(getDeclContext(), "context")
+  ATTRIBUTE_XML(getNameAsString(), "name")
+  ATTRIBUTE_XML(getNamespace(), "ref")
+END_NODE_XML
+
+NODE_XML(RecordDecl, "Record")
+  ID_ATTRIBUTE_XML
+  ATTRIBUTE_FILE_LOCATION_XML
+  ATTRIBUTE_XML(getDeclContext(), "context")
+  ATTRIBUTE_XML(getNameAsString(), "name")
+  ATTRIBUTE_OPT_XML(isDefinition() == false, "forward")
+  ATTRIBUTE_XML(getTypeForDecl(), "type")             // refers to the type this decl creates
+  SUB_NODE_SEQUENCE_XML(FieldDecl)
+END_NODE_XML
+
+NODE_XML(CXXRecordDecl, "CXXRecord")
+  ID_ATTRIBUTE_XML
+  ATTRIBUTE_FILE_LOCATION_XML
+  ATTRIBUTE_XML(getDeclContext(), "context")
+  ATTRIBUTE_XML(getNameAsString(), "name")
+  ATTRIBUTE_OPT_XML(isDefinition() == false, "forward")
+  ATTRIBUTE_XML(getTypeForDecl(), "type")             // refers to the type this decl creates
+  SUB_NODE_SEQUENCE_XML(FieldDecl)
+END_NODE_XML
+
+NODE_XML(EnumDecl, "Enum")
+  ID_ATTRIBUTE_XML
+  ATTRIBUTE_FILE_LOCATION_XML
+  ATTRIBUTE_XML(getDeclContext(), "context")
+  ATTRIBUTE_XML(getNameAsString(), "name")
+  ATTRIBUTE_OPT_XML(isDefinition() == false, "forward")
+  ATTRIBUTE_SPECIAL_XML(getIntegerType(), "type")     // is NULL in pure declarations thus deserves special handling
+  SUB_NODE_SEQUENCE_XML(EnumConstantDecl)             // only present in definition
+END_NODE_XML
+
+NODE_XML(EnumConstantDecl, "EnumConstant")
+  ID_ATTRIBUTE_XML
+  ATTRIBUTE_FILE_LOCATION_XML
+  ATTRIBUTE_XML(getDeclContext(), "context")
+  ATTRIBUTE_XML(getNameAsString(), "name")
+  TYPE_ATTRIBUTE_XML(getType())
+  ATTRIBUTE_XML(getInitVal().toString(10, true), "value")     // integer
+  SUB_NODE_OPT_XML(Expr)                                      // init expr of this constant
+END_NODE_XML
+
+NODE_XML(FieldDecl, "Field")
+  ID_ATTRIBUTE_XML
+  ATTRIBUTE_FILE_LOCATION_XML
+  ATTRIBUTE_XML(getDeclContext(), "context")
+  ATTRIBUTE_XML(getNameAsString(), "name")
+  TYPE_ATTRIBUTE_XML(getType())
+  ATTRIBUTE_OPT_XML(isMutable(), "mutable")
+  ATTRIBUTE_OPT_XML(isBitField(), "bitfield")
+  SUB_NODE_OPT_XML(Expr)                                      // init expr of a bit field
+END_NODE_XML
+
+NODE_XML(TypedefDecl, "Typedef")
+  ID_ATTRIBUTE_XML
+  ATTRIBUTE_FILE_LOCATION_XML
+  ATTRIBUTE_XML(getDeclContext(), "context")
+  ATTRIBUTE_XML(getNameAsString(), "name")
+  TYPE_ATTRIBUTE_XML(getUnderlyingType())
+END_NODE_XML
+
+NODE_XML(VarDecl, "Var")
+  ID_ATTRIBUTE_XML
+  ATTRIBUTE_FILE_LOCATION_XML
+  ATTRIBUTE_XML(getDeclContext(), "context")
+  ATTRIBUTE_XML(getNameAsString(), "name")
+  TYPE_ATTRIBUTE_XML(getType())
+  ATTRIBUTE_ENUM_OPT_XML(getStorageClass(), "storage_class")
+	  ENUM_XML(VarDecl::None, "")
+	  ENUM_XML(VarDecl::Auto, "auto")
+	  ENUM_XML(VarDecl::Register, "register")
+	  ENUM_XML(VarDecl::Extern, "extern")
+	  ENUM_XML(VarDecl::Static, "static")
+	  ENUM_XML(VarDecl::PrivateExtern, "__private_extern__")
+  END_ENUM_XML
+  SUB_NODE_OPT_XML(Expr)                                      // init expr
+END_NODE_XML
+
+NODE_XML(ParmVarDecl, "ParmVar")
+  ID_ATTRIBUTE_XML
+  ATTRIBUTE_FILE_LOCATION_XML
+  ATTRIBUTE_XML(getDeclContext(), "context")
+  ATTRIBUTE_XML(getNameAsString(), "name")
+  TYPE_ATTRIBUTE_XML(getType())
+  SUB_NODE_OPT_XML(Expr)                                      // default argument expression
+END_NODE_XML
+
+NODE_XML(LinkageSpecDecl, "LinkageSpec")
+  ID_ATTRIBUTE_XML
+  ATTRIBUTE_FILE_LOCATION_XML
+  ATTRIBUTE_XML(getDeclContext(), "context")
+  ATTRIBUTE_ENUM_OPT_XML(getLanguage(), "lang")
+	  ENUM_XML(LinkageSpecDecl::lang_c, "C")
+	  ENUM_XML(LinkageSpecDecl::lang_cxx, "CXX")
+  END_ENUM_XML
+END_NODE_XML
+
+
+//===----------------------------------------------------------------------===//
+#undef NODE_XML
+#undef ID_ATTRIBUTE_XML
+#undef TYPE_ATTRIBUTE_XML
+#undef ATTRIBUTE_XML
+#undef ATTRIBUTE_SPECIAL_XML
+#undef ATTRIBUTE_OPT_XML
+#undef ATTRIBUTE_ENUM_XML
+#undef ATTRIBUTE_ENUM_OPT_XML
+#undef ATTRIBUTE_FILE_LOCATION_XML
+#undef ENUM_XML
+#undef END_ENUM_XML
+#undef END_NODE_XML
+#undef SUB_NODE_XML
+#undef SUB_NODE_SEQUENCE_XML
+#undef SUB_NODE_OPT_XML
+#undef SUB_NODE_FN_BODY_XML
diff --git a/include/clang/Frontend/DependencyOutputOptions.h b/include/clang/Frontend/DependencyOutputOptions.h
new file mode 100644
index 0000000..ab8e49d
--- /dev/null
+++ b/include/clang/Frontend/DependencyOutputOptions.h
@@ -0,0 +1,43 @@
+//===--- DependencyOutputOptions.h ------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_DEPENDENCYOUTPUTOPTIONS_H
+#define LLVM_CLANG_FRONTEND_DEPENDENCYOUTPUTOPTIONS_H
+
+#include <string>
+#include <vector>
+
+namespace clang {
+
+/// DependencyOutputOptions - Options for controlling the compiler dependency
+/// file generation.
+class DependencyOutputOptions {
+public:
+  unsigned IncludeSystemHeaders : 1; ///< Include system header dependencies.
+  unsigned UsePhonyTargets : 1;      ///< Include phony targets for each
+                                     /// dependency, which can avoid some 'make'
+                                     /// problems.
+
+  /// The file to write depencency output to.
+  std::string OutputFile;
+
+  /// A list of names to use as the targets in the dependency file; this list
+  /// must contain at least one entry.
+  std::vector<std::string> Targets;
+
+public:
+  DependencyOutputOptions() {
+    IncludeSystemHeaders = 0;
+    UsePhonyTargets = 0;
+  }
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Frontend/DiagnosticOptions.h b/include/clang/Frontend/DiagnosticOptions.h
new file mode 100644
index 0000000..797cb34
--- /dev/null
+++ b/include/clang/Frontend/DiagnosticOptions.h
@@ -0,0 +1,83 @@
+//===--- DiagnosticOptions.h ------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_DIAGNOSTICOPTIONS_H
+#define LLVM_CLANG_FRONTEND_DIAGNOSTICOPTIONS_H
+
+#include <string>
+#include <vector>
+
+namespace clang {
+
+/// DiagnosticOptions - Options for controlling the compiler diagnostics
+/// engine.
+class DiagnosticOptions {
+public:
+  unsigned IgnoreWarnings : 1;   /// -w
+  unsigned NoRewriteMacros : 1;  /// -Wno-rewrite-macros
+  unsigned Pedantic : 1;         /// -pedantic
+  unsigned PedanticErrors : 1;   /// -pedantic-errors
+  unsigned ShowColumn : 1;       /// Show column number on diagnostics.
+  unsigned ShowLocation : 1;     /// Show source location information.
+  unsigned ShowCarets : 1;       /// Show carets in diagnostics.
+  unsigned ShowFixits : 1;       /// Show fixit information.
+  unsigned ShowSourceRanges : 1; /// Show source ranges in numeric form.
+  unsigned ShowOptionNames : 1;  /// Show the diagnostic name for mappable
+                                 /// diagnostics.
+  unsigned ShowColors : 1;       /// Show diagnostics with ANSI color sequences.
+  unsigned VerifyDiagnostics: 1; /// Check that diagnostics match the expected
+                                 /// diagnostics, indicated by markers in the
+                                 /// input source file.
+  unsigned BinaryOutput : 1;     /// Emit diagnostics via the diagnostic 
+                                 /// binary serialization mechanism, to be
+                                 /// deserialized by, e.g., the CIndex library.
+
+  unsigned ErrorLimit;           /// Limit # errors emitted.
+  unsigned TemplateBacktraceLimit; /// Limit depth of instantiation backtrace.
+
+  /// The distance between tab stops.
+  unsigned TabStop;
+  enum { DefaultTabStop = 8, MaxTabStop = 100 };
+
+  /// Column limit for formatting message diagnostics, or 0 if unused.
+  unsigned MessageLength;
+
+  /// If non-empty, a file to log extended build information to, for development
+  /// testing and analysis.
+  std::string DumpBuildInformation;
+
+  /// The list of -W... options used to alter the diagnostic mappings, with the
+  /// prefixes removed.
+  std::vector<std::string> Warnings;
+
+public:
+  DiagnosticOptions() {
+    IgnoreWarnings = 0;
+    TabStop = DefaultTabStop;
+    MessageLength = 0;
+    NoRewriteMacros = 0;
+    Pedantic = 0;
+    PedanticErrors = 0;
+    ShowCarets = 1;
+    ShowColors = 0;
+    ShowColumn = 1;
+    ShowFixits = 1;
+    ShowLocation = 1;
+    ShowOptionNames = 0;
+    ShowSourceRanges = 0;
+    VerifyDiagnostics = 0;
+    BinaryOutput = 0;
+    ErrorLimit = 0;
+    TemplateBacktraceLimit = 0;
+  }
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Frontend/DocumentXML.def b/include/clang/Frontend/DocumentXML.def
new file mode 100644
index 0000000..4c52bd8
--- /dev/null
+++ b/include/clang/Frontend/DocumentXML.def
@@ -0,0 +1,75 @@
+//===-- DocumentXML.def - Metadata about Document XML nodes -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the XML root database structure as written in 
+//  an AST XML document. 
+//  The following macros are used:
+//
+//  NODE_XML( CLASS, NAME ) - A node of name NAME denotes a concrete 
+//  statement of class CLASS where CLASS is a class name used internally by clang. 
+//  After a NODE_XML the definition of all (optional) attributes of that statement 
+//  node and possible sub-nodes follows.
+//
+//  END_NODE_XML - Closes the attribute definition of the current node.
+//
+//  ID_ATTRIBUTE_XML - Some nodes have an "id" attribute containing a 
+//  string, which value uniquely identify the entity represented by that node. 
+//  Other nodes may refer by reference attributes to this value.
+//
+//  ATTRIBUTE_SPECIAL_XML( FN, NAME ) - An attribute named NAME which deserves 
+//  a special handling. See the appropriate documentations. 
+//
+//  SUB_NODE_XML( CLASS ) - A mandatory sub-node of class CLASS or its sub-classes.
+//
+//  SUB_NODE_SEQUENCE_XML( CLASS ) - Zero or more sub-nodes of class CLASS or 
+//  its sub-classes.
+//
+//===----------------------------------------------------------------------===//
+
+ROOT_NODE_XML("CLANG_XML")
+  ATTRIBUTE_SPECIAL_XML(ignore, "version")     // special retrieving needed
+  SUB_NODE_XML("TranslationUnit")
+  SUB_NODE_XML("ReferenceSection")
+END_NODE_XML
+
+NODE_XML("TranslationUnit")
+  SUB_NODE_SEQUENCE_XML(Decl)
+END_NODE_XML
+
+NODE_XML("ReferenceSection")
+  SUB_NODE_XML("Types")
+  SUB_NODE_XML("Contexts")
+  SUB_NODE_XML("Files")
+END_NODE_XML
+
+NODE_XML("Types")
+  SUB_NODE_SEQUENCE_XML(Type)
+END_NODE_XML
+
+NODE_XML("Contexts")
+  SUB_NODE_SEQUENCE_XML(DeclContext)
+END_NODE_XML
+
+NODE_XML("Files")
+  SUB_NODE_SEQUENCE_XML("File")
+END_NODE_XML
+
+NODE_XML("File")
+  ID_ATTRIBUTE_XML
+  ATTRIBUTE_SPECIAL_XML(ignore, "name")         // special retrieving needed, denotes the source file name
+END_NODE_XML
+
+
+//===----------------------------------------------------------------------===//
+#undef NODE_XML
+#undef ID_ATTRIBUTE_XML                
+#undef ATTRIBUTE_SPECIAL_XML
+#undef END_NODE_XML                    
+#undef SUB_NODE_XML
+#undef SUB_NODE_SEQUENCE_XML
diff --git a/include/clang/Frontend/DocumentXML.h b/include/clang/Frontend/DocumentXML.h
new file mode 100644
index 0000000..6693ddb
--- /dev/null
+++ b/include/clang/Frontend/DocumentXML.h
@@ -0,0 +1,174 @@
+//===--- DocumentXML.h - XML document for ASTs ------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the XML document class, which provides the means to
+// dump out the AST in a XML form that exposes type details and other fields.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_DOCUMENTXML_H
+#define LLVM_CLANG_FRONTEND_DOCUMENTXML_H
+
+#include <string>
+#include <map>
+#include <stack>
+#include "clang/AST/Type.h"
+#include "clang/AST/TypeOrdering.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/ADT/DenseMap.h"
+
+namespace clang {
+
+//--------------------------------------------------------- forwards
+class DeclContext;
+class Decl;
+class NamedDecl;
+class FunctionDecl;
+class ASTContext;
+class LabelStmt;
+
+//---------------------------------------------------------
+namespace XML {
+  // id maps:
+  template<class T>
+  struct IdMap : llvm::DenseMap<T, unsigned> {};
+
+  template<>
+  struct IdMap<QualType> : std::map<QualType, unsigned, QualTypeOrdering> {};
+
+  template<>
+  struct IdMap<std::string> : std::map<std::string, unsigned> {};
+}
+
+//---------------------------------------------------------
+class DocumentXML {
+public:
+  DocumentXML(const std::string& rootName, llvm::raw_ostream& out);
+
+  void initialize(ASTContext &Context);
+  void PrintDecl(Decl *D);
+  void PrintStmt(const Stmt *S);    // defined in StmtXML.cpp
+  void finalize();
+
+
+  DocumentXML& addSubNode(const std::string& name);   // also enters the sub node, returns *this
+  DocumentXML& toParent();                            // returns *this
+
+  void addAttribute(const char* pName, const QualType& pType);
+  void addAttribute(const char* pName, bool value);
+
+  template<class T>
+  void addAttribute(const char* pName, const T* value)   {
+    addPtrAttribute(pName, value);
+  }
+
+  template<class T>
+  void addAttribute(const char* pName, T* value) {
+    addPtrAttribute(pName, value);
+  }
+
+  template<class T>
+  void addAttribute(const char* pName, const T& value);
+
+  template<class T>
+  void addAttributeOptional(const char* pName, const T& value);
+
+  void addSourceFileAttribute(const std::string& fileName);
+
+  PresumedLoc addLocation(const SourceLocation& Loc);
+  void addLocationRange(const SourceRange& R);
+
+  static std::string escapeString(const char* pStr, std::string::size_type len);
+
+private:
+  DocumentXML(const DocumentXML&);              // not defined
+  DocumentXML& operator=(const DocumentXML&);   // not defined
+
+  std::stack<std::string> NodeStack;
+  llvm::raw_ostream& Out;
+  ASTContext *Ctx;
+  bool      HasCurrentNodeSubNodes;
+
+
+  XML::IdMap<QualType>                 Types;
+  XML::IdMap<const DeclContext*>       Contexts;
+  XML::IdMap<const Type*>              BasicTypes;
+  XML::IdMap<std::string>              SourceFiles;
+  XML::IdMap<const NamedDecl*>         Decls;
+  XML::IdMap<const LabelStmt*>         Labels;
+
+  void addContextsRecursively(const DeclContext *DC);
+  void addTypeRecursively(const Type* pType);
+  void addTypeRecursively(const QualType& pType);
+
+  void Indent();
+
+  // forced pointer dispatch:
+  void addPtrAttribute(const char* pName, const Type* pType);
+  void addPtrAttribute(const char* pName, const NamedDecl* D);
+  void addPtrAttribute(const char* pName, const DeclContext* D);
+  void addPtrAttribute(const char* pName, const NamespaceDecl* D);    // disambiguation
+  void addPtrAttribute(const char* pName, const LabelStmt* L);
+  void addPtrAttribute(const char* pName, const char* text);
+
+  // defined in TypeXML.cpp:
+  void addParentTypes(const Type* pType);
+  void writeTypeToXML(const Type* pType);
+  void writeTypeToXML(const QualType& pType);
+  class TypeAdder;
+  friend class TypeAdder;
+
+  // defined in DeclXML.cpp:
+  void writeDeclToXML(Decl *D);
+  class DeclPrinter;
+  friend class DeclPrinter;
+
+  // for addAttributeOptional:
+  static bool isDefault(unsigned value)           { return value == 0; }
+  static bool isDefault(bool value)               { return !value; }
+  static bool isDefault(Qualifiers::GC value)     { return value == Qualifiers::GCNone; }
+  static bool isDefault(const std::string& value) { return value.empty(); }
+};
+
+//--------------------------------------------------------- inlines
+
+inline void DocumentXML::initialize(ASTContext &Context) {
+  Ctx = &Context;
+}
+
+//---------------------------------------------------------
+template<class T>
+inline void DocumentXML::addAttribute(const char* pName, const T& value) {
+  Out << ' ' << pName << "=\"" << value << "\"";
+}
+
+//---------------------------------------------------------
+inline void DocumentXML::addPtrAttribute(const char* pName, const char* text) {
+  Out << ' ' << pName << "=\"" << text << "\"";
+}
+
+//---------------------------------------------------------
+inline void DocumentXML::addAttribute(const char* pName, bool value) {
+  addPtrAttribute(pName, value ? "1" : "0");
+}
+
+//---------------------------------------------------------
+template<class T>
+inline void DocumentXML::addAttributeOptional(const char* pName,
+                                              const T& value) {
+  if (!isDefault(value)) {
+    addAttribute(pName, value);
+  }
+}
+
+//---------------------------------------------------------
+
+} //namespace clang
+
+#endif //LLVM_CLANG_DOCUMENTXML_H
diff --git a/include/clang/Frontend/FixItRewriter.h b/include/clang/Frontend/FixItRewriter.h
new file mode 100644
index 0000000..b432d74
--- /dev/null
+++ b/include/clang/Frontend/FixItRewriter.h
@@ -0,0 +1,104 @@
+//===--- FixItRewriter.h - Fix-It Rewriter Diagnostic Client ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This is a diagnostic client adaptor that performs rewrites as
+// suggested by code modification hints attached to diagnostics. It
+// then forwards any diagnostics to the adapted diagnostic client.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_FRONTEND_FIX_IT_REWRITER_H
+#define LLVM_CLANG_FRONTEND_FIX_IT_REWRITER_H
+
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Rewrite/Rewriter.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace llvm { class raw_ostream; }
+
+namespace clang {
+
+class SourceManager;
+class FileEntry;
+
+class FixItPathRewriter {
+public:
+  virtual ~FixItPathRewriter();
+
+  /// \brief This file is about to be rewritten. Return the name of the file
+  /// that is okay to write to.
+  virtual std::string RewriteFilename(const std::string &Filename) = 0;
+};
+
+class FixItRewriter : public DiagnosticClient {
+  /// \brief The diagnostics machinery.
+  Diagnostic &Diags;
+
+  /// \brief The rewriter used to perform the various code
+  /// modifications.
+  Rewriter Rewrite;
+
+  /// \brief The diagnostic client that performs the actual formatting
+  /// of error messages.
+  DiagnosticClient *Client;
+
+  /// \brief Turn an input path into an output path. NULL implies overwriting
+  /// the original.
+  FixItPathRewriter *PathRewriter;
+
+  /// \brief The number of rewriter failures.
+  unsigned NumFailures;
+
+public:
+  typedef Rewriter::buffer_iterator iterator;
+
+  /// \brief Initialize a new fix-it rewriter.
+  FixItRewriter(Diagnostic &Diags, SourceManager &SourceMgr,
+                const LangOptions &LangOpts, FixItPathRewriter *PathRewriter);
+
+  /// \brief Destroy the fix-it rewriter.
+  ~FixItRewriter();
+
+  /// \brief Check whether there are modifications for a given file.
+  bool IsModified(FileID ID) const {
+    return Rewrite.getRewriteBufferFor(ID) != NULL;
+  }
+
+  // Iteration over files with changes.
+  iterator buffer_begin() { return Rewrite.buffer_begin(); }
+  iterator buffer_end() { return Rewrite.buffer_end(); }
+
+  /// \brief Write a single modified source file.
+  ///
+  /// \returns true if there was an error, false otherwise.
+  bool WriteFixedFile(FileID ID, llvm::raw_ostream &OS);
+
+  /// \brief Write the modified source files.
+  ///
+  /// \returns true if there was an error, false otherwise.
+  bool WriteFixedFiles();
+
+  /// IncludeInDiagnosticCounts - This method (whose default implementation
+  /// returns true) indicates whether the diagnostics handled by this
+  /// DiagnosticClient should be included in the number of diagnostics
+  /// reported by Diagnostic.
+  virtual bool IncludeInDiagnosticCounts() const;
+
+  /// HandleDiagnostic - Handle this diagnostic, reporting it to the user or
+  /// capturing it to a log as needed.
+  virtual void HandleDiagnostic(Diagnostic::Level DiagLevel,
+                                const DiagnosticInfo &Info);
+
+  /// \brief Emit a diagnostic via the adapted diagnostic client.
+  void Diag(FullSourceLoc Loc, unsigned DiagID);
+};
+
+}
+
+#endif // LLVM_CLANG_FRONTEND_FIX_IT_REWRITER_H
diff --git a/include/clang/Frontend/FrontendAction.h b/include/clang/Frontend/FrontendAction.h
new file mode 100644
index 0000000..7b7db37
--- /dev/null
+++ b/include/clang/Frontend/FrontendAction.h
@@ -0,0 +1,204 @@
+//===-- FrontendAction.h - Generic Frontend Action Interface ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_FRONTENDACTION_H
+#define LLVM_CLANG_FRONTEND_FRONTENDACTION_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/OwningPtr.h"
+#include <string>
+
+namespace clang {
+class ASTUnit;
+class ASTConsumer;
+class CompilerInstance;
+class ASTMergeAction;
+
+/// FrontendAction - Abstract base class for actions which can be performed by
+/// the frontend.
+class FrontendAction {
+  std::string CurrentFile;
+  llvm::OwningPtr<ASTUnit> CurrentASTUnit;
+  CompilerInstance *Instance;
+  friend class ASTMergeAction;
+
+protected:
+  /// @name Implementation Action Interface
+  /// @{
+
+  /// CreateASTConsumer - Create the AST consumer object for this action, if
+  /// supported.
+  ///
+  /// This routine is called as part of \see BeginSourceAction(), which will
+  /// fail if the AST consumer cannot be created. This will not be called if the
+  /// action has indicated that it only uses the preprocessor.
+  ///
+  /// \param CI - The current compiler instance, provided as a convenience, \see
+  /// getCompilerInstance().
+  ///
+  /// \param InFile - The current input file, provided as a convenience, \see
+  /// getCurrentFile().
+  ///
+  /// \return The new AST consumer, or 0 on failure.
+  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                         llvm::StringRef InFile) = 0;
+
+  /// BeginSourceFileAction - Callback at the start of processing a single
+  /// input.
+  ///
+  /// \return True on success; on failure \see ExecutionAction() and
+  /// EndSourceFileAction() will not be called.
+  virtual bool BeginSourceFileAction(CompilerInstance &CI,
+                                     llvm::StringRef Filename) {
+    return true;
+  }
+
+  /// ExecuteAction - Callback to run the program action, using the initialized
+  /// compiler instance.
+  ///
+  /// This routine is guaranteed to only be called between \see
+  /// BeginSourceFileAction() and \see EndSourceFileAction().
+  virtual void ExecuteAction() = 0;
+
+  /// EndSourceFileAction - Callback at the end of processing a single input;
+  /// this is guaranteed to only be called following a successful call to
+  /// BeginSourceFileAction (and BeingSourceFile).
+  virtual void EndSourceFileAction() {}
+
+  /// @}
+
+public:
+  FrontendAction();
+  virtual ~FrontendAction();
+
+  /// @name Compiler Instance Access
+  /// @{
+
+  CompilerInstance &getCompilerInstance() const {
+    assert(Instance && "Compiler instance not registered!");
+    return *Instance;
+  }
+
+  void setCompilerInstance(CompilerInstance *Value) { Instance = Value; }
+
+  /// @}
+  /// @name Current File Information
+  /// @{
+
+  bool isCurrentFileAST() const {
+    assert(!CurrentFile.empty() && "No current file!");
+    return CurrentASTUnit != 0;
+  }
+
+  const std::string &getCurrentFile() const {
+    assert(!CurrentFile.empty() && "No current file!");
+    return CurrentFile;
+  }
+
+  ASTUnit &getCurrentASTUnit() const {
+    assert(!CurrentASTUnit && "No current AST unit!");
+    return *CurrentASTUnit;
+  }
+
+  ASTUnit *takeCurrentASTUnit() {
+    return CurrentASTUnit.take();
+  }
+
+  void setCurrentFile(llvm::StringRef Value, ASTUnit *AST = 0);
+
+  /// @}
+  /// @name Supported Modes
+  /// @{
+
+  /// usesPreprocessorOnly - Does this action only use the preprocessor? If so
+  /// no AST context will be created and this action will be invalid with PCH
+  /// inputs.
+  virtual bool usesPreprocessorOnly() const = 0;
+
+  /// usesCompleteTranslationUnit - For AST based actions, should the
+  /// translation unit be completed?
+  virtual bool usesCompleteTranslationUnit() { return true; }
+
+  /// hasPCHSupport - Does this action support use with PCH?
+  virtual bool hasPCHSupport() const { return !usesPreprocessorOnly(); }
+
+  /// hasASTSupport - Does this action support use with AST files?
+  virtual bool hasASTSupport() const { return !usesPreprocessorOnly(); }
+
+  /// hasCodeCompletionSupport - Does this action support use with code
+  /// completion?
+  virtual bool hasCodeCompletionSupport() const { return false; }
+
+  /// @}
+  /// @name Public Action Interface
+  /// @{
+
+  /// BeginSourceFile - Prepare the action for processing the input file \arg
+  /// Filename; this is run after the options and frontend have been
+  /// initialized, but prior to executing any per-file processing.
+  ///
+  /// \param CI - The compiler instance this action is being run from. The
+  /// action may store and use this object up until the matching EndSourceFile
+  /// action.
+  ///
+  /// \param Filename - The input filename, which will be made available to
+  /// clients via \see getCurrentFile().
+  ///
+  /// \param IsAST - Indicates whether this is an AST input. AST inputs require
+  /// special handling, since the AST file itself contains several objects which
+  /// would normally be owned by the CompilerInstance. When processing AST input
+  /// files, these objects should generally not be initialized in the
+  /// CompilerInstance -- they will automatically be shared with the AST file in
+  /// between \see BeginSourceFile() and \see EndSourceFile().
+  ///
+  /// \return True on success; the compilation of this file should be aborted
+  /// and neither Execute nor EndSourceFile should be called.
+  bool BeginSourceFile(CompilerInstance &CI, llvm::StringRef Filename,
+                       bool IsAST = false);
+
+  /// Execute - Set the source managers main input file, and run the action.
+  void Execute();
+
+  /// EndSourceFile - Perform any per-file post processing, deallocate per-file
+  /// objects, and run statistics and output file cleanup code.
+  void EndSourceFile();
+
+  /// @}
+};
+
+/// ASTFrontendAction - Abstract base class to use for AST consumer based
+/// frontend actions.
+class ASTFrontendAction : public FrontendAction {
+  /// ExecuteAction - Implement the ExecuteAction interface by running Sema on
+  /// the already initialized AST consumer.
+  ///
+  /// This will also take care of instantiating a code completion consumer if
+  /// the user requested it and the action supports it.
+  virtual void ExecuteAction();
+
+public:
+  virtual bool usesPreprocessorOnly() const { return false; }
+};
+
+/// PreprocessorFrontendAction - Abstract base class to use for preprocessor
+/// based frontend actions.
+class PreprocessorFrontendAction : public FrontendAction {
+protected:
+  /// CreateASTConsumer - Provide a default implementation which returns aborts,
+  /// this method should never be called by FrontendAction clients.
+  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                         llvm::StringRef InFile);
+
+public:
+  virtual bool usesPreprocessorOnly() const { return true; }
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Frontend/FrontendActions.h b/include/clang/Frontend/FrontendActions.h
new file mode 100644
index 0000000..3ddd77d
--- /dev/null
+++ b/include/clang/Frontend/FrontendActions.h
@@ -0,0 +1,226 @@
+//===-- FrontendActions.h - Useful Frontend Actions -------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_FRONTENDACTIONS_H
+#define LLVM_CLANG_FRONTEND_FRONTENDACTIONS_H
+
+#include "clang/Frontend/FrontendAction.h"
+#include <string>
+#include <vector>
+
+namespace clang {
+class FixItRewriter;
+class FixItPathRewriter;
+
+//===----------------------------------------------------------------------===//
+// Custom Consumer Actions
+//===----------------------------------------------------------------------===//
+
+class InitOnlyAction : public FrontendAction {
+  virtual void ExecuteAction();
+
+  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                         llvm::StringRef InFile);
+
+public:
+  // Don't claim to only use the preprocessor, we want to follow the AST path,
+  // but do nothing.
+  virtual bool usesPreprocessorOnly() const { return false; }
+};
+
+//===----------------------------------------------------------------------===//
+// AST Consumer Actions
+//===----------------------------------------------------------------------===//
+
+class AnalysisAction : public ASTFrontendAction {
+protected:
+  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                         llvm::StringRef InFile);
+};
+
+class ASTPrintAction : public ASTFrontendAction {
+protected:
+  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                         llvm::StringRef InFile);
+};
+
+class ASTPrintXMLAction : public ASTFrontendAction {
+protected:
+  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                         llvm::StringRef InFile);
+};
+
+class ASTDumpAction : public ASTFrontendAction {
+protected:
+  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                         llvm::StringRef InFile);
+};
+
+class ASTViewAction : public ASTFrontendAction {
+protected:
+  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                         llvm::StringRef InFile);
+};
+
+class DeclContextPrintAction : public ASTFrontendAction {
+protected:
+  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                         llvm::StringRef InFile);
+};
+
+class FixItAction : public ASTFrontendAction {
+private:
+  llvm::OwningPtr<FixItRewriter> Rewriter;
+  llvm::OwningPtr<FixItPathRewriter> PathRewriter;
+
+protected:
+
+  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                         llvm::StringRef InFile);
+
+  virtual bool BeginSourceFileAction(CompilerInstance &CI,
+                                     llvm::StringRef Filename);
+
+  virtual void EndSourceFileAction();
+
+  virtual bool hasASTSupport() const { return false; }
+
+public:
+  FixItAction();
+  ~FixItAction();
+};
+
+class GeneratePCHAction : public ASTFrontendAction {
+protected:
+  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                         llvm::StringRef InFile);
+
+  virtual bool usesCompleteTranslationUnit() { return false; }
+
+  virtual bool hasASTSupport() const { return false; }
+};
+
+class HTMLPrintAction : public ASTFrontendAction {
+protected:
+  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                         llvm::StringRef InFile);
+};
+
+class InheritanceViewAction : public ASTFrontendAction {
+protected:
+  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                         llvm::StringRef InFile);
+};
+
+class RewriteObjCAction : public ASTFrontendAction {
+protected:
+  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                         llvm::StringRef InFile);
+};
+
+class SyntaxOnlyAction : public ASTFrontendAction {
+protected:
+  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                         llvm::StringRef InFile);
+
+public:
+  virtual bool hasCodeCompletionSupport() const { return true; }
+};
+
+/**
+ * \brief Frontend action adaptor that merges ASTs together.
+ *
+ * This action takes an existing AST file and "merges" it into the AST
+ * context, producing a merged context. This action is an action
+ * adaptor, which forwards most of its calls to another action that
+ * will consume the merged context.
+ */
+class ASTMergeAction : public FrontendAction {
+  /// \brief The action that the merge action adapts.
+  FrontendAction *AdaptedAction;
+  
+  /// \brief The set of AST files to merge.
+  std::vector<std::string> ASTFiles;
+
+protected:
+  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                         llvm::StringRef InFile);
+
+  virtual bool BeginSourceFileAction(CompilerInstance &CI,
+                                     llvm::StringRef Filename);
+
+  virtual void ExecuteAction();
+  virtual void EndSourceFileAction();
+
+public:
+  ASTMergeAction(FrontendAction *AdaptedAction,
+                 std::string *ASTFiles, unsigned NumASTFiles);
+  virtual ~ASTMergeAction();
+
+  virtual bool usesPreprocessorOnly() const;
+  virtual bool usesCompleteTranslationUnit();
+  virtual bool hasPCHSupport() const;
+  virtual bool hasASTSupport() const;
+  virtual bool hasCodeCompletionSupport() const;
+};
+
+//===----------------------------------------------------------------------===//
+// Preprocessor Actions
+//===----------------------------------------------------------------------===//
+
+class DumpRawTokensAction : public PreprocessorFrontendAction {
+protected:
+  void ExecuteAction();
+};
+
+class DumpTokensAction : public PreprocessorFrontendAction {
+protected:
+  void ExecuteAction();
+};
+
+class GeneratePTHAction : public PreprocessorFrontendAction {
+protected:
+  void ExecuteAction();
+};
+
+class ParseOnlyAction : public PreprocessorFrontendAction {
+protected:
+  void ExecuteAction();
+};
+
+class PreprocessOnlyAction : public PreprocessorFrontendAction {
+protected:
+  void ExecuteAction();
+};
+
+class PrintParseAction : public PreprocessorFrontendAction {
+protected:
+  void ExecuteAction();
+};
+
+class PrintPreprocessedAction : public PreprocessorFrontendAction {
+protected:
+  void ExecuteAction();
+
+  virtual bool hasPCHSupport() const { return true; }
+};
+
+class RewriteMacrosAction : public PreprocessorFrontendAction {
+protected:
+  void ExecuteAction();
+};
+
+class RewriteTestAction : public PreprocessorFrontendAction {
+protected:
+  void ExecuteAction();
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Frontend/FrontendDiagnostic.h b/include/clang/Frontend/FrontendDiagnostic.h
new file mode 100644
index 0000000..a044586
--- /dev/null
+++ b/include/clang/Frontend/FrontendDiagnostic.h
@@ -0,0 +1,27 @@
+//===--- DiagnosticFrontend.h - Diagnostics for frontend --------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTENDDIAGNOSTIC_H
+#define LLVM_CLANG_FRONTENDDIAGNOSTIC_H
+
+#include "clang/Basic/Diagnostic.h"
+
+namespace clang {
+  namespace diag {
+    enum {
+#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE) ENUM,
+#define FRONTENDSTART
+#include "clang/Basic/DiagnosticFrontendKinds.inc"
+#undef DIAG
+      NUM_BUILTIN_FRONTEND_DIAGNOSTICS
+    };
+  }  // end namespace diag
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Frontend/FrontendOptions.h b/include/clang/Frontend/FrontendOptions.h
new file mode 100644
index 0000000..60512ed
--- /dev/null
+++ b/include/clang/Frontend/FrontendOptions.h
@@ -0,0 +1,141 @@
+//===--- FrontendOptions.h --------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_FRONTENDOPTIONS_H
+#define LLVM_CLANG_FRONTEND_FRONTENDOPTIONS_H
+
+#include "clang/Frontend/CommandLineSourceLoc.h"
+#include "llvm/ADT/StringRef.h"
+#include <string>
+#include <vector>
+
+namespace clang {
+
+namespace frontend {
+  enum ActionKind {
+    ASTDump,                ///< Parse ASTs and dump them.
+    ASTPrint,               ///< Parse ASTs and print them.
+    ASTPrintXML,            ///< Parse ASTs and print them in XML.
+    ASTView,                ///< Parse ASTs and view them in Graphviz.
+    DumpRawTokens,          ///< Dump out raw tokens.
+    DumpTokens,             ///< Dump out preprocessed tokens.
+    EmitAssembly,           ///< Emit a .s file.
+    EmitBC,                 ///< Emit a .bc file.
+    EmitHTML,               ///< Translate input source into HTML.
+    EmitLLVM,               ///< Emit a .ll file.
+    EmitLLVMOnly,           ///< Generate LLVM IR, but do not
+    EmitObj,                ///< Emit a .o file.
+    FixIt,                  ///< Parse and apply any fixits to the source.
+    GeneratePCH,            ///< Generate pre-compiled header.
+    GeneratePTH,            ///< Generate pre-tokenized header.
+    InheritanceView,        ///< View C++ inheritance for a specified class.
+    InitOnly,               ///< Only execute frontend initialization.
+    ParseNoop,              ///< Parse with noop callbacks.
+    ParsePrintCallbacks,    ///< Parse and print each callback.
+    ParseSyntaxOnly,        ///< Parse and perform semantic analysis.
+    PluginAction,           ///< Run a plugin action, \see ActionName.
+    PrintDeclContext,       ///< Print DeclContext and their Decls.
+    PrintPreprocessedInput, ///< -E mode.
+    RewriteMacros,          ///< Expand macros but not #includes.
+    RewriteObjC,            ///< ObjC->C Rewriter.
+    RewriteTest,            ///< Rewriter playground
+    RunAnalysis,            ///< Run one or more source code analyses.
+    RunPreprocessorOnly     ///< Just lex, no output.
+  };
+}
+
+/// FrontendOptions - Options for controlling the behavior of the frontend.
+class FrontendOptions {
+public:
+  enum InputKind {
+    IK_None,
+    IK_Asm,
+    IK_C,
+    IK_CXX,
+    IK_ObjC,
+    IK_ObjCXX,
+    IK_PreprocessedC,
+    IK_PreprocessedCXX,
+    IK_PreprocessedObjC,
+    IK_PreprocessedObjCXX,
+    IK_OpenCL,
+    IK_AST
+  };
+
+  unsigned DebugCodeCompletionPrinter : 1; ///< Use the debug printer for code
+                                           /// completion results.
+  unsigned DisableFree : 1;                ///< Disable memory freeing on exit.
+  unsigned RelocatablePCH : 1;             ///< When generating PCH files,
+                                           /// instruct the PCH writer to create
+                                           /// relocatable PCH files.
+  unsigned ShowHelp : 1;                   ///< Show the -help text.
+  unsigned ShowMacrosInCodeCompletion : 1; ///< Show macros in code completion
+                                           /// results.
+  unsigned ShowStats : 1;                  ///< Show frontend performance
+                                           /// metrics and statistics.
+  unsigned ShowTimers : 1;                 ///< Show timers for individual
+                                           /// actions.
+  unsigned ShowVersion : 1;                ///< Show the -version text.
+
+  /// The input files and their types.
+  std::vector<std::pair<InputKind, std::string> > Inputs;
+
+  /// The output file, if any.
+  std::string OutputFile;
+
+  /// If given, the name for a C++ class to view the inheritance of.
+  std::string ViewClassInheritance;
+
+  /// If given, the new suffix for fix-it rewritten files.
+  std::string FixItSuffix;
+
+  /// If given, enable code completion at the provided location.
+  ParsedSourceLocation CodeCompletionAt;
+
+  /// The frontend action to perform.
+  frontend::ActionKind ProgramAction;
+
+  /// The name of the action to run when using a plugin action.
+  std::string ActionName;
+
+  /// The list of plugins to load.
+  std::vector<std::string> Plugins;
+
+  /// \brief The list of AST files to merge.
+  std::vector<std::string> ASTMergeFiles;
+
+  /// \brief A list of arguments to forward to LLVM's option processing; this
+  /// should only be used for debugging and experimental features.
+  std::vector<std::string> LLVMArgs;
+
+public:
+  FrontendOptions() {
+    DebugCodeCompletionPrinter = 1;
+    DisableFree = 0;
+    ProgramAction = frontend::ParseSyntaxOnly;
+    ActionName = "";
+    RelocatablePCH = 0;
+    ShowHelp = 0;
+    ShowMacrosInCodeCompletion = 0;
+    ShowStats = 0;
+    ShowTimers = 0;
+    ShowVersion = 0;
+  }
+
+  /// getInputKindForExtension - Return the appropriate input kind for a file
+  /// extension. For example, "c" would return IK_C.
+  ///
+  /// \return The input kind for the extension, or IK_None if the extension is
+  /// not recognized.
+  static InputKind getInputKindForExtension(llvm::StringRef Extension);
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Frontend/FrontendPluginRegistry.h b/include/clang/Frontend/FrontendPluginRegistry.h
new file mode 100644
index 0000000..8341492
--- /dev/null
+++ b/include/clang/Frontend/FrontendPluginRegistry.h
@@ -0,0 +1,23 @@
+//===-- FrontendAction.h - Pluggable Frontend Action Interface --*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_PLUGINFRONTENDACTION_H
+#define LLVM_CLANG_FRONTEND_PLUGINFRONTENDACTION_H
+
+#include "clang/Frontend/FrontendAction.h"
+#include "llvm/Support/Registry.h"
+
+namespace clang {
+
+/// The frontend plugin registry.
+typedef llvm::Registry<FrontendAction> FrontendPluginRegistry;
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Frontend/HeaderSearchOptions.h b/include/clang/Frontend/HeaderSearchOptions.h
new file mode 100644
index 0000000..c668245
--- /dev/null
+++ b/include/clang/Frontend/HeaderSearchOptions.h
@@ -0,0 +1,95 @@
+//===--- HeaderSearchOptions.h ----------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_HEADERSEARCHOPTIONS_H
+#define LLVM_CLANG_FRONTEND_HEADERSEARCHOPTIONS_H
+
+#include "llvm/ADT/StringRef.h"
+#include <vector>
+
+namespace clang {
+
+namespace frontend {
+  /// IncludeDirGroup - Identifiers the group a include entry belongs to, which
+  /// represents its relative positive in the search list.
+  enum IncludeDirGroup {
+    Quoted = 0,     ///< `#include ""` paths. Thing `gcc -iquote`.
+    Angled,         ///< Paths for both `#include ""` and `#include <>`. (`-I`)
+    System,         ///< Like Angled, but marks system directories.
+    After           ///< Like System, but searched after the system directories.
+  };
+}
+
+/// HeaderSearchOptions - Helper class for storing options related to the
+/// initialization of the HeaderSearch object.
+class HeaderSearchOptions {
+public:
+  struct Entry {
+    std::string Path;
+    frontend::IncludeDirGroup Group;
+    unsigned IsUserSupplied : 1;
+    unsigned IsFramework : 1;
+
+    Entry(llvm::StringRef _Path, frontend::IncludeDirGroup _Group,
+          bool _IsUserSupplied, bool _IsFramework)
+      : Path(_Path), Group(_Group), IsUserSupplied(_IsUserSupplied),
+        IsFramework(_IsFramework) {}
+  };
+
+  /// If non-empty, the directory to use as a "virtual system root" for include
+  /// paths.
+  std::string Sysroot;
+
+  /// User specified include entries.
+  std::vector<Entry> UserEntries;
+
+  /// A (system-path) delimited list of include paths to be added from the
+  /// environment following the user specified includes (but prior to builtin
+  /// and standard includes). This is parsed in the same manner as the CPATH
+  /// environment variable for gcc.
+  std::string EnvIncPath;
+
+  /// Per-language environmental include paths, see \see EnvIncPath.
+  std::string CEnvIncPath;
+  std::string ObjCEnvIncPath;
+  std::string CXXEnvIncPath;
+  std::string ObjCXXEnvIncPath;
+
+  /// The directory which holds the compiler resource files (builtin includes,
+  /// etc.).
+  std::string ResourceDir;
+
+  /// Include the compiler builtin includes.
+  unsigned UseBuiltinIncludes : 1;
+
+  /// Include the system standard include search directories.
+  unsigned UseStandardIncludes : 1;
+
+  /// Include the system standard C++ library include search directories.
+  unsigned UseStandardCXXIncludes : 1;
+
+  /// Whether header search information should be output as for -v.
+  unsigned Verbose : 1;
+
+public:
+  HeaderSearchOptions(llvm::StringRef _Sysroot = "/")
+    : Sysroot(_Sysroot), UseBuiltinIncludes(true),
+      UseStandardIncludes(true), UseStandardCXXIncludes(true),
+      Verbose(false) {}
+
+  /// AddPath - Add the \arg Path path to the specified \arg Group list.
+  void AddPath(llvm::StringRef Path, frontend::IncludeDirGroup Group,
+               bool IsUserSupplied, bool IsFramework) {
+    UserEntries.push_back(Entry(Path, Group, IsUserSupplied, IsFramework));
+  }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Frontend/LangStandard.h b/include/clang/Frontend/LangStandard.h
new file mode 100644
index 0000000..441d34f
--- /dev/null
+++ b/include/clang/Frontend/LangStandard.h
@@ -0,0 +1,83 @@
+//===--- LangStandard.h -----------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_LANGSTANDARD_H
+#define LLVM_CLANG_FRONTEND_LANGSTANDARD_H
+
+#include "llvm/ADT/StringRef.h"
+
+namespace clang {
+
+namespace frontend {
+
+enum LangFeatures {
+  BCPLComment = (1 << 0),
+  C99 = (1 << 1),
+  CPlusPlus = (1 << 2),
+  CPlusPlus0x = (1 << 3),
+  Digraphs = (1 << 4),
+  GNUMode = (1 << 5),
+  HexFloat = (1 << 6),
+  ImplicitInt = (1 << 7)
+};
+
+}
+
+/// LangStandard - Information about the properties of a particular language
+/// standard.
+struct LangStandard {
+  enum Kind {
+#define LANGSTANDARD(id, name, desc, features) \
+    lang_##id,
+#include "clang/Frontend/LangStandards.def"
+    lang_unspecified
+  };
+
+  const char *ShortName;
+  const char *Description;
+  unsigned Flags;
+
+public:
+  /// getName - Get the name of this standard.
+  const char *getName() const { return ShortName; }
+
+  /// getDescription - Get the description of this standard.
+  const char *getDescription() const { return Description; }
+
+  /// hasBCPLComments - Language supports '//' comments.
+  bool hasBCPLComments() const { return Flags & frontend::BCPLComment; }
+
+  /// isC99 - Language is a superset of C99.
+  bool isC99() const { return Flags & frontend::C99; }
+
+  /// isCPlusPlus - Language is a C++ variant.
+  bool isCPlusPlus() const { return Flags & frontend::CPlusPlus; }
+
+  /// isCPlusPlus0x - Language is a C++0x variant.
+  bool isCPlusPlus0x() const { return Flags & frontend::CPlusPlus0x; }
+
+  /// hasDigraphs - Language supports digraphs.
+  bool hasDigraphs() const { return Flags & frontend::Digraphs; }
+
+  /// isGNUMode - Language includes GNU extensions.
+  bool isGNUMode() const { return Flags & frontend::GNUMode; }
+
+  /// hasHexFloats - Language supports hexadecimal float constants.
+  bool hasHexFloats() const { return Flags & frontend::HexFloat; }
+
+  /// hasImplicitInt - Language allows variables to be typed as int implicitly.
+  bool hasImplicitInt() const { return Flags & frontend::ImplicitInt; }
+
+  static const LangStandard &getLangStandardForKind(Kind K);
+  static const LangStandard *getLangStandardForName(llvm::StringRef Name);
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Frontend/LangStandards.def b/include/clang/Frontend/LangStandards.def
new file mode 100644
index 0000000..52aa463
--- /dev/null
+++ b/include/clang/Frontend/LangStandards.def
@@ -0,0 +1,83 @@
+//===-- LangStandards.def - Language Standard Data --------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LANGSTANDARD
+#error "LANGSTANDARD must be defined before including this file"
+#endif
+
+/// LANGSTANDARD(IDENT, NAME, DESC, FEATURES)
+///
+/// \param IDENT - The name of the standard as a C++ identifier.
+/// \param NAME - The name of the standard.
+/// \param DESC - A short description of the standard.
+/// \param FEATURES - The standard features as flags, these are enums from the
+/// clang::frontend namespace, which is assumed to be be available.
+
+// C89-ish modes.
+LANGSTANDARD(c89, "c89",
+             "ISO C 1990",
+             ImplicitInt)
+LANGSTANDARD(c90, "c90",
+             "ISO C 1990",
+             ImplicitInt)
+LANGSTANDARD(iso9899_1990, "iso9899:1990",
+             "ISO C 1990",
+             ImplicitInt)
+
+LANGSTANDARD(c94, "iso9899:199409",
+             "ISO C 1990 with amendment 1",
+             Digraphs | ImplicitInt)
+
+LANGSTANDARD(gnu89, "gnu89",
+             "ISO C 1990 with GNU extensions",
+             BCPLComment | Digraphs | GNUMode | ImplicitInt)
+
+// C99-ish modes
+LANGSTANDARD(c99, "c99",
+             "ISO C 1999",
+             BCPLComment | C99 | Digraphs | HexFloat)
+LANGSTANDARD(c9x, "c9x",
+             "ISO C 1999",
+             BCPLComment | C99 | Digraphs | HexFloat)
+LANGSTANDARD(iso9899_1999,
+             "iso9899:1999", "ISO C 1999",
+             BCPLComment | C99 | Digraphs | HexFloat)
+LANGSTANDARD(iso9899_199x,
+             "iso9899:199x", "ISO C 1999",
+             BCPLComment | C99 | Digraphs | HexFloat)
+
+LANGSTANDARD(gnu99, "gnu99",
+             "ISO C 1999 with GNU extensions",
+             BCPLComment | C99 | Digraphs | GNUMode | HexFloat | Digraphs)
+LANGSTANDARD(gnu9x, "gnu9x",
+             "ISO C 1999 with GNU extensions",
+             BCPLComment | C99 | Digraphs | GNUMode | HexFloat)
+
+// C++ modes
+LANGSTANDARD(cxx98, "c++98",
+             "ISO C++ 1998 with amendments",
+             BCPLComment | CPlusPlus | Digraphs)
+LANGSTANDARD(gnucxx98, "gnu++98",
+             "ISO C++ 1998 with " "amendments and GNU extensions",
+             BCPLComment | CPlusPlus | Digraphs | GNUMode)
+
+LANGSTANDARD(cxx0x, "c++0x",
+             "Upcoming ISO C++ 200x with amendments",
+             BCPLComment | CPlusPlus | CPlusPlus0x | Digraphs)
+LANGSTANDARD(gnucxx0x, "gnu++0x",
+             "Upcoming ISO C++ 200x with amendments and GNU extensions",
+             BCPLComment | CPlusPlus | CPlusPlus0x | Digraphs | GNUMode)
+
+// OpenCL
+
+LANGSTANDARD(opencl, "cl",
+             "OpenCL 1.0",
+             BCPLComment | C99 | Digraphs | HexFloat)
+
+#undef LANGSTANDARD
diff --git a/include/clang/Frontend/PCHBitCodes.h b/include/clang/Frontend/PCHBitCodes.h
new file mode 100644
index 0000000..457e633
--- /dev/null
+++ b/include/clang/Frontend/PCHBitCodes.h
@@ -0,0 +1,729 @@
+//===- PCHBitCodes.h - Enum values for the PCH bitcode format ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header defines Bitcode enum values for Clang precompiled header files.
+//
+// The enum values defined in this file should be considered permanent.  If
+// new features are added, they should have values added at the end of the
+// respective lists.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_FRONTEND_PCHBITCODES_H
+#define LLVM_CLANG_FRONTEND_PCHBITCODES_H
+
+#include "llvm/Bitcode/BitCodes.h"
+#include "llvm/System/DataTypes.h"
+
+namespace clang {
+  namespace pch {
+    /// \brief PCH major version number supported by this version of
+    /// Clang.
+    ///
+    /// Whenever the PCH format changes in a way that makes it
+    /// incompatible with previous versions (such that a reader
+    /// designed for the previous version could not support reading
+    /// the new version), this number should be increased.
+    ///
+    /// Version 3 of PCH files also requires that the version control branch and
+    /// revision match exactly, since there is no backward compatibility of
+    /// PCH files at this time.
+    const unsigned VERSION_MAJOR = 3;
+
+    /// \brief PCH minor version number supported by this version of
+    /// Clang.
+    ///
+    /// Whenever the PCH format changes in a way that is still
+    /// compatible with previous versions (such that a reader designed
+    /// for the previous version could still support reading the new
+    /// version by ignoring new kinds of subblocks), this number
+    /// should be increased.
+    const unsigned VERSION_MINOR = 0;
+
+    /// \brief An ID number that refers to a declaration in a PCH file.
+    ///
+    /// The ID numbers of types are consecutive (in order of
+    /// discovery) and start at 2. 0 is reserved for NULL, and 1 is
+    /// reserved for the translation unit declaration.
+    typedef uint32_t DeclID;
+
+    /// \brief An ID number that refers to a type in a PCH file.
+    ///
+    /// The ID of a type is partitioned into two parts: the lower
+    /// three bits are used to store the const/volatile/restrict
+    /// qualifiers (as with QualType) and the upper bits provide a
+    /// type index. The type index values are partitioned into two
+    /// sets. The values below NUM_PREDEF_TYPE_IDs are predefined type
+    /// IDs (based on the PREDEF_TYPE_*_ID constants), with 0 as a
+    /// placeholder for "no type". Values from NUM_PREDEF_TYPE_IDs are
+    /// other types that have serialized representations.
+    typedef uint32_t TypeID;
+
+    /// \brief An ID number that refers to an identifier in a PCH
+    /// file.
+    typedef uint32_t IdentID;
+
+    typedef uint32_t SelectorID;
+
+    /// \brief Describes the various kinds of blocks that occur within
+    /// a PCH file.
+    enum BlockIDs {
+      /// \brief The PCH block, which acts as a container around the
+      /// full PCH block.
+      PCH_BLOCK_ID = llvm::bitc::FIRST_APPLICATION_BLOCKID,
+
+      /// \brief The block containing information about the source
+      /// manager.
+      SOURCE_MANAGER_BLOCK_ID,
+
+      /// \brief The block containing information about the
+      /// preprocessor.
+      PREPROCESSOR_BLOCK_ID,
+
+      /// \brief The block containing the definitions of all of the
+      /// types and decls used within the PCH file.
+      DECLTYPES_BLOCK_ID
+    };
+
+    /// \brief Record types that occur within the PCH block itself.
+    enum PCHRecordTypes {
+      /// \brief Record code for the offsets of each type.
+      ///
+      /// The TYPE_OFFSET constant describes the record that occurs
+      /// within the PCH block. The record itself is an array of offsets that
+      /// point into the declarations and types block (identified by 
+      /// DECLTYPES_BLOCK_ID). The index into the array is based on the ID
+      /// of a type. For a given type ID @c T, the lower three bits of
+      /// @c T are its qualifiers (const, volatile, restrict), as in
+      /// the QualType class. The upper bits, after being shifted and
+      /// subtracting NUM_PREDEF_TYPE_IDS, are used to index into the
+      /// TYPE_OFFSET block to determine the offset of that type's
+      /// corresponding record within the DECLTYPES_BLOCK_ID block.
+      TYPE_OFFSET = 1,
+
+      /// \brief Record code for the offsets of each decl.
+      ///
+      /// The DECL_OFFSET constant describes the record that occurs
+      /// within the block identified by DECL_OFFSETS_BLOCK_ID within
+      /// the PCH block. The record itself is an array of offsets that
+      /// point into the declarations and types block (identified by
+      /// DECLTYPES_BLOCK_ID). The declaration ID is an index into this
+      /// record, after subtracting one to account for the use of
+      /// declaration ID 0 for a NULL declaration pointer. Index 0 is
+      /// reserved for the translation unit declaration.
+      DECL_OFFSET = 2,
+
+      /// \brief Record code for the language options table.
+      ///
+      /// The record with this code contains the contents of the
+      /// LangOptions structure. We serialize the entire contents of
+      /// the structure, and let the reader decide which options are
+      /// actually important to check.
+      LANGUAGE_OPTIONS = 3,
+
+      /// \brief PCH metadata, including the PCH file version number
+      /// and the target triple used to build the PCH file.
+      METADATA = 4,
+
+      /// \brief Record code for the table of offsets of each
+      /// identifier ID.
+      ///
+      /// The offset table contains offsets into the blob stored in
+      /// the IDENTIFIER_TABLE record. Each offset points to the
+      /// NULL-terminated string that corresponds to that identifier.
+      IDENTIFIER_OFFSET = 5,
+
+      /// \brief Record code for the identifier table.
+      ///
+      /// The identifier table is a simple blob that contains
+      /// NULL-terminated strings for all of the identifiers
+      /// referenced by the PCH file. The IDENTIFIER_OFFSET table
+      /// contains the mapping from identifier IDs to the characters
+      /// in this blob. Note that the starting offsets of all of the
+      /// identifiers are odd, so that, when the identifier offset
+      /// table is loaded in, we can use the low bit to distinguish
+      /// between offsets (for unresolved identifier IDs) and
+      /// IdentifierInfo pointers (for already-resolved identifier
+      /// IDs).
+      IDENTIFIER_TABLE = 6,
+
+      /// \brief Record code for the array of external definitions.
+      ///
+      /// The PCH file contains a list of all of the unnamed external
+      /// definitions present within the parsed headers, stored as an
+      /// array of declaration IDs. These external definitions will be
+      /// reported to the AST consumer after the PCH file has been
+      /// read, since their presence can affect the semantics of the
+      /// program (e.g., for code generation).
+      EXTERNAL_DEFINITIONS = 7,
+
+      /// \brief Record code for the set of non-builtin, special
+      /// types.
+      ///
+      /// This record contains the type IDs for the various type nodes
+      /// that are constructed during semantic analysis (e.g.,
+      /// __builtin_va_list). The SPECIAL_TYPE_* constants provide
+      /// offsets into this record.
+      SPECIAL_TYPES = 8,
+
+      /// \brief Record code for the extra statistics we gather while
+      /// generating a PCH file.
+      STATISTICS = 9,
+
+      /// \brief Record code for the array of tentative definitions.
+      TENTATIVE_DEFINITIONS = 10,
+
+      /// \brief Record code for the array of locally-scoped external
+      /// declarations.
+      LOCALLY_SCOPED_EXTERNAL_DECLS = 11,
+
+      /// \brief Record code for the table of offsets into the
+      /// Objective-C method pool.
+      SELECTOR_OFFSETS = 12,
+
+      /// \brief Record code for the Objective-C method pool,
+      METHOD_POOL = 13,
+
+      /// \brief The value of the next __COUNTER__ to dispense.
+      /// [PP_COUNTER_VALUE, Val]
+      PP_COUNTER_VALUE = 14,
+
+      /// \brief Record code for the table of offsets into the block
+      /// of source-location information.
+      SOURCE_LOCATION_OFFSETS = 15,
+
+      /// \brief Record code for the set of source location entries
+      /// that need to be preloaded by the PCH reader.
+      ///
+      /// This set contains the source location entry for the
+      /// predefines buffer and for any file entries that need to be
+      /// preloaded.
+      SOURCE_LOCATION_PRELOADS = 16,
+
+      /// \brief Record code for the stat() cache.
+      STAT_CACHE = 17,
+
+      /// \brief Record code for the set of ext_vector type names.
+      EXT_VECTOR_DECLS = 18,
+
+      /// \brief Record code for the original file that was used to
+      /// generate the precompiled header.
+      ORIGINAL_FILE_NAME = 19,
+
+      /// Record #20 intentionally left blank.
+      
+      /// \brief Record code for the version control branch and revision
+      /// information of the compiler used to build this PCH file.
+      VERSION_CONTROL_BRANCH_REVISION = 21,
+      
+      /// \brief Record code for the array of unused static functions.
+      UNUSED_STATIC_FUNCS = 22,
+      
+      /// \brief Record code for the table of offsets to macro definition
+      /// entries in the preprocessing record.
+      MACRO_DEFINITION_OFFSETS = 23
+    };
+
+    /// \brief Record types used within a source manager block.
+    enum SourceManagerRecordTypes {
+      /// \brief Describes a source location entry (SLocEntry) for a
+      /// file.
+      SM_SLOC_FILE_ENTRY = 1,
+      /// \brief Describes a source location entry (SLocEntry) for a
+      /// buffer.
+      SM_SLOC_BUFFER_ENTRY = 2,
+      /// \brief Describes a blob that contains the data for a buffer
+      /// entry. This kind of record always directly follows a
+      /// SM_SLOC_BUFFER_ENTRY record.
+      SM_SLOC_BUFFER_BLOB = 3,
+      /// \brief Describes a source location entry (SLocEntry) for a
+      /// macro instantiation.
+      SM_SLOC_INSTANTIATION_ENTRY = 4,
+      /// \brief Describes the SourceManager's line table, with
+      /// information about #line directives.
+      SM_LINE_TABLE = 5
+    };
+
+    /// \brief Record types used within a preprocessor block.
+    enum PreprocessorRecordTypes {
+      // The macros in the PP section are a PP_MACRO_* instance followed by a
+      // list of PP_TOKEN instances for each token in the definition.
+
+      /// \brief An object-like macro definition.
+      /// [PP_MACRO_OBJECT_LIKE, IdentInfoID, SLoc, IsUsed]
+      PP_MACRO_OBJECT_LIKE = 1,
+
+      /// \brief A function-like macro definition.
+      /// [PP_MACRO_FUNCTION_LIKE, <ObjectLikeStuff>, IsC99Varargs, IsGNUVarars,
+      ///  NumArgs, ArgIdentInfoID* ]
+      PP_MACRO_FUNCTION_LIKE = 2,
+
+      /// \brief Describes one token.
+      /// [PP_TOKEN, SLoc, Length, IdentInfoID, Kind, Flags]
+      PP_TOKEN = 3,
+
+      /// \brief Describes a macro instantiation within the preprocessing 
+      /// record.
+      PP_MACRO_INSTANTIATION = 4,
+      
+      /// \brief Describes a macro definition within the preprocessing record.
+      PP_MACRO_DEFINITION = 5
+    };
+
+    /// \defgroup PCHAST Precompiled header AST constants
+    ///
+    /// The constants in this group describe various components of the
+    /// abstract syntax tree within a precompiled header.
+    ///
+    /// @{
+
+    /// \brief Predefined type IDs.
+    ///
+    /// These type IDs correspond to predefined types in the AST
+    /// context, such as built-in types (int) and special place-holder
+    /// types (the <overload> and <dependent> type markers). Such
+    /// types are never actually serialized, since they will be built
+    /// by the AST context when it is created.
+    enum PredefinedTypeIDs {
+      /// \brief The NULL type.
+      PREDEF_TYPE_NULL_ID       = 0,
+      /// \brief The void type.
+      PREDEF_TYPE_VOID_ID       = 1,
+      /// \brief The 'bool' or '_Bool' type.
+      PREDEF_TYPE_BOOL_ID       = 2,
+      /// \brief The 'char' type, when it is unsigned.
+      PREDEF_TYPE_CHAR_U_ID     = 3,
+      /// \brief The 'unsigned char' type.
+      PREDEF_TYPE_UCHAR_ID      = 4,
+      /// \brief The 'unsigned short' type.
+      PREDEF_TYPE_USHORT_ID     = 5,
+      /// \brief The 'unsigned int' type.
+      PREDEF_TYPE_UINT_ID       = 6,
+      /// \brief The 'unsigned long' type.
+      PREDEF_TYPE_ULONG_ID      = 7,
+      /// \brief The 'unsigned long long' type.
+      PREDEF_TYPE_ULONGLONG_ID  = 8,
+      /// \brief The 'char' type, when it is signed.
+      PREDEF_TYPE_CHAR_S_ID     = 9,
+      /// \brief The 'signed char' type.
+      PREDEF_TYPE_SCHAR_ID      = 10,
+      /// \brief The C++ 'wchar_t' type.
+      PREDEF_TYPE_WCHAR_ID      = 11,
+      /// \brief The (signed) 'short' type.
+      PREDEF_TYPE_SHORT_ID      = 12,
+      /// \brief The (signed) 'int' type.
+      PREDEF_TYPE_INT_ID        = 13,
+      /// \brief The (signed) 'long' type.
+      PREDEF_TYPE_LONG_ID       = 14,
+      /// \brief The (signed) 'long long' type.
+      PREDEF_TYPE_LONGLONG_ID   = 15,
+      /// \brief The 'float' type.
+      PREDEF_TYPE_FLOAT_ID      = 16,
+      /// \brief The 'double' type.
+      PREDEF_TYPE_DOUBLE_ID     = 17,
+      /// \brief The 'long double' type.
+      PREDEF_TYPE_LONGDOUBLE_ID = 18,
+      /// \brief The placeholder type for overloaded function sets.
+      PREDEF_TYPE_OVERLOAD_ID   = 19,
+      /// \brief The placeholder type for dependent types.
+      PREDEF_TYPE_DEPENDENT_ID  = 20,
+      /// \brief The '__uint128_t' type.
+      PREDEF_TYPE_UINT128_ID    = 21,
+      /// \brief The '__int128_t' type.
+      PREDEF_TYPE_INT128_ID     = 22,
+      /// \brief The type of 'nullptr'.
+      PREDEF_TYPE_NULLPTR_ID    = 23,
+      /// \brief The C++ 'char16_t' type.
+      PREDEF_TYPE_CHAR16_ID     = 24,
+      /// \brief The C++ 'char32_t' type.
+      PREDEF_TYPE_CHAR32_ID     = 25,
+      /// \brief The ObjC 'id' type.
+      PREDEF_TYPE_OBJC_ID       = 26,
+      /// \brief The ObjC 'Class' type.
+      PREDEF_TYPE_OBJC_CLASS    = 27,
+      /// \brief The ObjC 'SEL' type.
+      PREDEF_TYPE_OBJC_SEL    = 28
+    };
+
+    /// \brief The number of predefined type IDs that are reserved for
+    /// the PREDEF_TYPE_* constants.
+    ///
+    /// Type IDs for non-predefined types will start at
+    /// NUM_PREDEF_TYPE_IDs.
+    const unsigned NUM_PREDEF_TYPE_IDS = 100;
+
+    /// \brief Record codes for each kind of type.
+    ///
+    /// These constants describe the type records that can occur within a
+    /// block identified by DECLTYPES_BLOCK_ID in the PCH file. Each
+    /// constant describes a record for a specific type class in the
+    /// AST.
+    enum TypeCode {
+      /// \brief An ExtQualType record.
+      TYPE_EXT_QUAL                 = 1,
+      /// \brief A ComplexType record.
+      TYPE_COMPLEX                  = 3,
+      /// \brief A PointerType record.
+      TYPE_POINTER                  = 4,
+      /// \brief A BlockPointerType record.
+      TYPE_BLOCK_POINTER            = 5,
+      /// \brief An LValueReferenceType record.
+      TYPE_LVALUE_REFERENCE         = 6,
+      /// \brief An RValueReferenceType record.
+      TYPE_RVALUE_REFERENCE         = 7,
+      /// \brief A MemberPointerType record.
+      TYPE_MEMBER_POINTER           = 8,
+      /// \brief A ConstantArrayType record.
+      TYPE_CONSTANT_ARRAY           = 9,
+      /// \brief An IncompleteArrayType record.
+      TYPE_INCOMPLETE_ARRAY         = 10,
+      /// \brief A VariableArrayType record.
+      TYPE_VARIABLE_ARRAY           = 11,
+      /// \brief A VectorType record.
+      TYPE_VECTOR                   = 12,
+      /// \brief An ExtVectorType record.
+      TYPE_EXT_VECTOR               = 13,
+      /// \brief A FunctionNoProtoType record.
+      TYPE_FUNCTION_NO_PROTO        = 14,
+      /// \brief A FunctionProtoType record.
+      TYPE_FUNCTION_PROTO           = 15,
+      /// \brief A TypedefType record.
+      TYPE_TYPEDEF                  = 16,
+      /// \brief A TypeOfExprType record.
+      TYPE_TYPEOF_EXPR              = 17,
+      /// \brief A TypeOfType record.
+      TYPE_TYPEOF                   = 18,
+      /// \brief A RecordType record.
+      TYPE_RECORD                   = 19,
+      /// \brief An EnumType record.
+      TYPE_ENUM                     = 20,
+      /// \brief An ObjCInterfaceType record.
+      TYPE_OBJC_INTERFACE           = 21,
+      /// \brief An ObjCObjectPointerType record.
+      TYPE_OBJC_OBJECT_POINTER      = 22,
+      /// \brief a DecltypeType record.
+      TYPE_DECLTYPE                 = 23,
+      /// \brief An ElaboratedType record.
+      TYPE_ELABORATED               = 24,
+      /// \brief A SubstTemplateTypeParmType record.
+      TYPE_SUBST_TEMPLATE_TYPE_PARM = 25,
+      /// \brief An UnresolvedUsingType record.
+      TYPE_UNRESOLVED_USING         = 26,
+      /// \brief An InjectedClassNameType record.
+      TYPE_INJECTED_CLASS_NAME      = 27
+    };
+
+    /// \brief The type IDs for special types constructed by semantic
+    /// analysis.
+    ///
+    /// The constants in this enumeration are indices into the
+    /// SPECIAL_TYPES record.
+    enum SpecialTypeIDs {
+      /// \brief __builtin_va_list
+      SPECIAL_TYPE_BUILTIN_VA_LIST             = 0,
+      /// \brief Objective-C "id" type
+      SPECIAL_TYPE_OBJC_ID                     = 1,
+      /// \brief Objective-C selector type
+      SPECIAL_TYPE_OBJC_SELECTOR               = 2,
+      /// \brief Objective-C Protocol type
+      SPECIAL_TYPE_OBJC_PROTOCOL               = 3,
+      /// \brief Objective-C Class type
+      SPECIAL_TYPE_OBJC_CLASS                  = 4,
+      /// \brief CFConstantString type
+      SPECIAL_TYPE_CF_CONSTANT_STRING          = 5,
+      /// \brief Objective-C fast enumeration state type
+      SPECIAL_TYPE_OBJC_FAST_ENUMERATION_STATE = 6,
+      /// \brief C FILE typedef type
+      SPECIAL_TYPE_FILE                        = 7,
+      /// \brief C jmp_buf typedef type
+      SPECIAL_TYPE_jmp_buf                     = 8,
+      /// \brief C sigjmp_buf typedef type
+      SPECIAL_TYPE_sigjmp_buf                  = 9,
+      /// \brief Objective-C "id" redefinition type
+      SPECIAL_TYPE_OBJC_ID_REDEFINITION        = 10,
+      /// \brief Objective-C "Class" redefinition type
+      SPECIAL_TYPE_OBJC_CLASS_REDEFINITION     = 11,
+      /// \brief Block descriptor type for Blocks CodeGen
+      SPECIAL_TYPE_BLOCK_DESCRIPTOR            = 12,
+      /// \brief Block extedned descriptor type for Blocks CodeGen
+      SPECIAL_TYPE_BLOCK_EXTENDED_DESCRIPTOR   = 13,
+      /// \brief Objective-C "SEL" redefinition type
+      SPECIAL_TYPE_OBJC_SEL_REDEFINITION       = 14,
+      /// \brief NSConstantString type
+      SPECIAL_TYPE_NS_CONSTANT_STRING          = 15
+    };
+
+    /// \brief Record codes for each kind of declaration.
+    ///
+    /// These constants describe the declaration records that can occur within
+    /// a declarations block (identified by DECLS_BLOCK_ID). Each
+    /// constant describes a record for a specific declaration class
+    /// in the AST.
+    enum DeclCode {
+      /// \brief Attributes attached to a declaration.
+      DECL_ATTR = 50,
+      /// \brief A TranslationUnitDecl record.
+      DECL_TRANSLATION_UNIT,
+      /// \brief A TypedefDecl record.
+      DECL_TYPEDEF,
+      /// \brief An EnumDecl record.
+      DECL_ENUM,
+      /// \brief A RecordDecl record.
+      DECL_RECORD,
+      /// \brief An EnumConstantDecl record.
+      DECL_ENUM_CONSTANT,
+      /// \brief A FunctionDecl record.
+      DECL_FUNCTION,
+      /// \brief A ObjCMethodDecl record.
+      DECL_OBJC_METHOD,
+      /// \brief A ObjCInterfaceDecl record.
+      DECL_OBJC_INTERFACE,
+      /// \brief A ObjCProtocolDecl record.
+      DECL_OBJC_PROTOCOL,
+      /// \brief A ObjCIvarDecl record.
+      DECL_OBJC_IVAR,
+      /// \brief A ObjCAtDefsFieldDecl record.
+      DECL_OBJC_AT_DEFS_FIELD,
+      /// \brief A ObjCClassDecl record.
+      DECL_OBJC_CLASS,
+      /// \brief A ObjCForwardProtocolDecl record.
+      DECL_OBJC_FORWARD_PROTOCOL,
+      /// \brief A ObjCCategoryDecl record.
+      DECL_OBJC_CATEGORY,
+      /// \brief A ObjCCategoryImplDecl record.
+      DECL_OBJC_CATEGORY_IMPL,
+      /// \brief A ObjCImplementationDecl record.
+      DECL_OBJC_IMPLEMENTATION,
+      /// \brief A ObjCCompatibleAliasDecl record.
+      DECL_OBJC_COMPATIBLE_ALIAS,
+      /// \brief A ObjCPropertyDecl record.
+      DECL_OBJC_PROPERTY,
+      /// \brief A ObjCPropertyImplDecl record.
+      DECL_OBJC_PROPERTY_IMPL,
+      /// \brief A FieldDecl record.
+      DECL_FIELD,
+      /// \brief A VarDecl record.
+      DECL_VAR,
+      /// \brief An ImplicitParamDecl record.
+      DECL_IMPLICIT_PARAM,
+      /// \brief A ParmVarDecl record.
+      DECL_PARM_VAR,
+      /// \brief A FileScopeAsmDecl record.
+      DECL_FILE_SCOPE_ASM,
+      /// \brief A BlockDecl record.
+      DECL_BLOCK,
+      /// \brief A record that stores the set of declarations that are
+      /// lexically stored within a given DeclContext.
+      ///
+      /// The record itself is an array of declaration IDs, in the
+      /// order in which those declarations were added to the
+      /// declaration context. This data is used when iterating over
+      /// the contents of a DeclContext, e.g., via
+      /// DeclContext::decls_begin()/DeclContext::decls_end().
+      DECL_CONTEXT_LEXICAL,
+      /// \brief A record that stores the set of declarations that are
+      /// visible from a given DeclContext.
+      ///
+      /// The record itself stores a set of mappings, each of which
+      /// associates a declaration name with one or more declaration
+      /// IDs. This data is used when performing qualified name lookup
+      /// into a DeclContext via DeclContext::lookup.
+      DECL_CONTEXT_VISIBLE,
+      /// \brief A NamespaceDecl record.
+      DECL_NAMESPACE
+    };
+
+    /// \brief Record codes for each kind of statement or expression.
+    ///
+    /// These constants describe the records that describe statements
+    /// or expressions. These records  occur within type and declarations
+    /// block, so they begin with record values of 100.  Each constant 
+    /// describes a record for a specific statement or expression class in the
+    /// AST.
+    enum StmtCode {
+      /// \brief A marker record that indicates that we are at the end
+      /// of an expression.
+      STMT_STOP = 100,
+      /// \brief A NULL expression.
+      STMT_NULL_PTR,
+      /// \brief A NullStmt record.
+      STMT_NULL,
+      /// \brief A CompoundStmt record.
+      STMT_COMPOUND,
+      /// \brief A CaseStmt record.
+      STMT_CASE,
+      /// \brief A DefaultStmt record.
+      STMT_DEFAULT,
+      /// \brief A LabelStmt record.
+      STMT_LABEL,
+      /// \brief An IfStmt record.
+      STMT_IF,
+      /// \brief A SwitchStmt record.
+      STMT_SWITCH,
+      /// \brief A WhileStmt record.
+      STMT_WHILE,
+      /// \brief A DoStmt record.
+      STMT_DO,
+      /// \brief A ForStmt record.
+      STMT_FOR,
+      /// \brief A GotoStmt record.
+      STMT_GOTO,
+      /// \brief An IndirectGotoStmt record.
+      STMT_INDIRECT_GOTO,
+      /// \brief A ContinueStmt record.
+      STMT_CONTINUE,
+      /// \brief A BreakStmt record.
+      STMT_BREAK,
+      /// \brief A ReturnStmt record.
+      STMT_RETURN,
+      /// \brief A DeclStmt record.
+      STMT_DECL,
+      /// \brief An AsmStmt record.
+      STMT_ASM,
+      /// \brief A PredefinedExpr record.
+      EXPR_PREDEFINED,
+      /// \brief A DeclRefExpr record.
+      EXPR_DECL_REF,
+      /// \brief An IntegerLiteral record.
+      EXPR_INTEGER_LITERAL,
+      /// \brief A FloatingLiteral record.
+      EXPR_FLOATING_LITERAL,
+      /// \brief An ImaginaryLiteral record.
+      EXPR_IMAGINARY_LITERAL,
+      /// \brief A StringLiteral record.
+      EXPR_STRING_LITERAL,
+      /// \brief A CharacterLiteral record.
+      EXPR_CHARACTER_LITERAL,
+      /// \brief A ParenExpr record.
+      EXPR_PAREN,
+      /// \brief A UnaryOperator record.
+      EXPR_UNARY_OPERATOR,
+      /// \brief A SizefAlignOfExpr record.
+      EXPR_SIZEOF_ALIGN_OF,
+      /// \brief An ArraySubscriptExpr record.
+      EXPR_ARRAY_SUBSCRIPT,
+      /// \brief A CallExpr record.
+      EXPR_CALL,
+      /// \brief A MemberExpr record.
+      EXPR_MEMBER,
+      /// \brief A BinaryOperator record.
+      EXPR_BINARY_OPERATOR,
+      /// \brief A CompoundAssignOperator record.
+      EXPR_COMPOUND_ASSIGN_OPERATOR,
+      /// \brief A ConditionOperator record.
+      EXPR_CONDITIONAL_OPERATOR,
+      /// \brief An ImplicitCastExpr record.
+      EXPR_IMPLICIT_CAST,
+      /// \brief A CStyleCastExpr record.
+      EXPR_CSTYLE_CAST,
+      /// \brief A CompoundLiteralExpr record.
+      EXPR_COMPOUND_LITERAL,
+      /// \brief An ExtVectorElementExpr record.
+      EXPR_EXT_VECTOR_ELEMENT,
+      /// \brief An InitListExpr record.
+      EXPR_INIT_LIST,
+      /// \brief A DesignatedInitExpr record.
+      EXPR_DESIGNATED_INIT,
+      /// \brief An ImplicitValueInitExpr record.
+      EXPR_IMPLICIT_VALUE_INIT,
+      /// \brief A VAArgExpr record.
+      EXPR_VA_ARG,
+      /// \brief An AddrLabelExpr record.
+      EXPR_ADDR_LABEL,
+      /// \brief A StmtExpr record.
+      EXPR_STMT,
+      /// \brief A TypesCompatibleExpr record.
+      EXPR_TYPES_COMPATIBLE,
+      /// \brief A ChooseExpr record.
+      EXPR_CHOOSE,
+      /// \brief A GNUNullExpr record.
+      EXPR_GNU_NULL,
+      /// \brief A ShuffleVectorExpr record.
+      EXPR_SHUFFLE_VECTOR,
+      /// \brief BlockExpr
+      EXPR_BLOCK,
+      /// \brief A BlockDeclRef record.
+      EXPR_BLOCK_DECL_REF,
+      
+      // Objective-C
+
+      /// \brief An ObjCStringLiteral record.
+      EXPR_OBJC_STRING_LITERAL,
+      /// \brief An ObjCEncodeExpr record.
+      EXPR_OBJC_ENCODE,
+      /// \brief An ObjCSelectorExpr record.
+      EXPR_OBJC_SELECTOR_EXPR,
+      /// \brief An ObjCProtocolExpr record.
+      EXPR_OBJC_PROTOCOL_EXPR,
+      /// \brief An ObjCIvarRefExpr record.
+      EXPR_OBJC_IVAR_REF_EXPR,
+      /// \brief An ObjCPropertyRefExpr record.
+      EXPR_OBJC_PROPERTY_REF_EXPR,
+      /// \brief An ObjCImplicitSetterGetterRefExpr record.
+      EXPR_OBJC_KVC_REF_EXPR,
+      /// \brief An ObjCMessageExpr record.
+      EXPR_OBJC_MESSAGE_EXPR,
+      /// \brief An ObjCSuperExpr record.
+      EXPR_OBJC_SUPER_EXPR,
+      /// \brief An ObjCIsa Expr record.
+      EXPR_OBJC_ISA,
+
+      /// \brief An ObjCForCollectionStmt record.
+      STMT_OBJC_FOR_COLLECTION,
+      /// \brief An ObjCAtCatchStmt record.
+      STMT_OBJC_CATCH,
+      /// \brief An ObjCAtFinallyStmt record.
+      STMT_OBJC_FINALLY,
+      /// \brief An ObjCAtTryStmt record.
+      STMT_OBJC_AT_TRY,
+      /// \brief An ObjCAtSynchronizedStmt record.
+      STMT_OBJC_AT_SYNCHRONIZED,
+      /// \brief An ObjCAtThrowStmt record.
+      STMT_OBJC_AT_THROW,
+
+      // C++
+
+      /// \brief A CXXOperatorCallExpr record.
+      EXPR_CXX_OPERATOR_CALL,
+      /// \brief A CXXConstructExpr record.
+      EXPR_CXX_CONSTRUCT,
+      // \brief A CXXStaticCastExpr record.
+      EXPR_CXX_STATIC_CAST,
+      // \brief A CXXDynamicCastExpr record.
+      EXPR_CXX_DYNAMIC_CAST,
+      // \brief A CXXReinterpretCastExpr record.
+      EXPR_CXX_REINTERPRET_CAST,
+      // \brief A CXXConstCastExpr record.
+      EXPR_CXX_CONST_CAST,
+      // \brief A CXXFunctionalCastExpr record.
+      EXPR_CXX_FUNCTIONAL_CAST,
+      // \brief A CXXBoolLiteralExpr record.
+      EXPR_CXX_BOOL_LITERAL,
+      // \brief A CXXNullPtrLiteralExpr record.
+      EXPR_CXX_NULL_PTR_LITERAL
+    };
+
+    /// \brief The kinds of designators that can occur in a
+    /// DesignatedInitExpr.
+    enum DesignatorTypes {
+      /// \brief Field designator where only the field name is known.
+      DESIG_FIELD_NAME  = 0,
+      /// \brief Field designator where the field has been resolved to
+      /// a declaration.
+      DESIG_FIELD_DECL  = 1,
+      /// \brief Array designator.
+      DESIG_ARRAY       = 2,
+      /// \brief GNU array range designator.
+      DESIG_ARRAY_RANGE = 3
+    };
+
+    /// @}
+  }
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Frontend/PCHReader.h b/include/clang/Frontend/PCHReader.h
new file mode 100644
index 0000000..c235230
--- /dev/null
+++ b/include/clang/Frontend/PCHReader.h
@@ -0,0 +1,809 @@
+//===--- PCHReader.h - Precompiled Headers Reader ---------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the PCHReader class, which reads a precompiled header.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_PCH_READER_H
+#define LLVM_CLANG_FRONTEND_PCH_READER_H
+
+#include "clang/Frontend/PCHBitCodes.h"
+#include "clang/AST/DeclarationName.h"
+#include "clang/Sema/ExternalSemaSource.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/TemplateBase.h"
+#include "clang/Lex/ExternalPreprocessorSource.h"
+#include "clang/Lex/PreprocessingRecord.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/SourceManager.h"
+#include "llvm/ADT/APFloat.h"
+#include "llvm/ADT/APInt.h"
+#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Bitcode/BitstreamReader.h"
+#include "llvm/System/DataTypes.h"
+#include <deque>
+#include <map>
+#include <string>
+#include <utility>
+#include <vector>
+
+namespace llvm {
+  class MemoryBuffer;
+}
+
+namespace clang {
+
+class AddrLabelExpr;
+class ASTConsumer;
+class ASTContext;
+class Attr;
+class Decl;
+class DeclContext;
+class GotoStmt;
+class LabelStmt;
+class MacroDefinition;
+class NamedDecl;
+class Preprocessor;
+class Sema;
+class SwitchCase;
+class PCHReader;
+struct HeaderFileInfo;
+
+/// \brief Abstract interface for callback invocations by the PCHReader.
+///
+/// While reading a PCH file, the PCHReader will call the methods of the
+/// listener to pass on specific information. Some of the listener methods can
+/// return true to indicate to the PCHReader that the information (and
+/// consequently the PCH file) is invalid.
+class PCHReaderListener {
+public:
+  virtual ~PCHReaderListener();
+
+  /// \brief Receives the language options.
+  ///
+  /// \returns true to indicate the options are invalid or false otherwise.
+  virtual bool ReadLanguageOptions(const LangOptions &LangOpts) {
+    return false;
+  }
+
+  /// \brief Receives the target triple.
+  ///
+  /// \returns true to indicate the target triple is invalid or false otherwise.
+  virtual bool ReadTargetTriple(llvm::StringRef Triple) {
+    return false;
+  }
+
+  /// \brief Receives the contents of the predefines buffer.
+  ///
+  /// \param PCHPredef The start of the predefines buffer in the PCH
+  /// file.
+  ///
+  /// \param PCHBufferID The FileID for the PCH predefines buffer.
+  ///
+  /// \param OriginalFileName The original file name for the PCH, which will
+  /// appear as an entry in the predefines buffer.
+  ///
+  /// \param SuggestedPredefines If necessary, additional definitions are added
+  /// here.
+  ///
+  /// \returns true to indicate the predefines are invalid or false otherwise.
+  virtual bool ReadPredefinesBuffer(llvm::StringRef PCHPredef,
+                                    FileID PCHBufferID,
+                                    llvm::StringRef OriginalFileName,
+                                    std::string &SuggestedPredefines) {
+    return false;
+  }
+
+  /// \brief Receives a HeaderFileInfo entry.
+  virtual void ReadHeaderFileInfo(const HeaderFileInfo &HFI, unsigned ID) {}
+
+  /// \brief Receives __COUNTER__ value.
+  virtual void ReadCounter(unsigned Value) {}
+};
+
+/// \brief PCHReaderListener implementation to validate the information of
+/// the PCH file against an initialized Preprocessor.
+class PCHValidator : public PCHReaderListener {
+  Preprocessor &PP;
+  PCHReader &Reader;
+
+  unsigned NumHeaderInfos;
+
+public:
+  PCHValidator(Preprocessor &PP, PCHReader &Reader)
+    : PP(PP), Reader(Reader), NumHeaderInfos(0) {}
+
+  virtual bool ReadLanguageOptions(const LangOptions &LangOpts);
+  virtual bool ReadTargetTriple(llvm::StringRef Triple);
+  virtual bool ReadPredefinesBuffer(llvm::StringRef PCHPredef,
+                                    FileID PCHBufferID,
+                                    llvm::StringRef OriginalFileName,
+                                    std::string &SuggestedPredefines);
+  virtual void ReadHeaderFileInfo(const HeaderFileInfo &HFI, unsigned ID);
+  virtual void ReadCounter(unsigned Value);
+
+private:
+  void Error(const char *Msg);
+};
+
+/// \brief Reads a precompiled head containing the contents of a
+/// translation unit.
+///
+/// The PCHReader class reads a bitstream (produced by the PCHWriter
+/// class) containing the serialized representation of a given
+/// abstract syntax tree and its supporting data structures. An
+/// instance of the PCHReader can be attached to an ASTContext object,
+/// which will provide access to the contents of the PCH file.
+///
+/// The PCH reader provides lazy de-serialization of declarations, as
+/// required when traversing the AST. Only those AST nodes that are
+/// actually required will be de-serialized.
+class PCHReader
+  : public ExternalPreprocessorSource,
+    public ExternalPreprocessingRecordSource,
+    public ExternalSemaSource,
+    public IdentifierInfoLookup,
+    public ExternalIdentifierLookup,
+    public ExternalSLocEntrySource {
+public:
+  enum PCHReadResult { Success, Failure, IgnorePCH };
+  friend class PCHValidator;
+private:
+  /// \ brief The receiver of some callbacks invoked by PCHReader.
+  llvm::OwningPtr<PCHReaderListener> Listener;
+
+  SourceManager &SourceMgr;
+  FileManager &FileMgr;
+  Diagnostic &Diags;
+
+  /// \brief The semantic analysis object that will be processing the
+  /// PCH file and the translation unit that uses it.
+  Sema *SemaObj;
+
+  /// \brief The preprocessor that will be loading the source file.
+  Preprocessor *PP;
+
+  /// \brief The AST context into which we'll read the PCH file.
+  ASTContext *Context;
+
+  /// \brief The PCH stat cache installed by this PCHReader, if any.
+  ///
+  /// The dynamic type of this stat cache is always PCHStatCache
+  void *StatCache;
+      
+  /// \brief The AST consumer.
+  ASTConsumer *Consumer;
+
+  /// \brief The bitstream reader from which we'll read the PCH file.
+  llvm::BitstreamReader StreamFile;
+  llvm::BitstreamCursor Stream;
+
+  /// \brief The cursor to the start of the preprocessor block, which stores
+  /// all of the macro definitions.
+  llvm::BitstreamCursor MacroCursor;
+      
+  /// DeclsCursor - This is a cursor to the start of the DECLS_BLOCK block.  It
+  /// has read all the abbreviations at the start of the block and is ready to
+  /// jump around with these in context.
+  llvm::BitstreamCursor DeclsCursor;
+
+  /// \brief The file name of the PCH file.
+  std::string FileName;
+
+  /// \brief The memory buffer that stores the data associated with
+  /// this PCH file.
+  llvm::OwningPtr<llvm::MemoryBuffer> Buffer;
+
+  /// \brief Offset type for all of the source location entries in the
+  /// PCH file.
+  const uint32_t *SLocOffsets;
+
+  /// \brief The number of source location entries in the PCH file.
+  unsigned TotalNumSLocEntries;
+
+  /// \brief Cursor used to read source location entries.
+  llvm::BitstreamCursor SLocEntryCursor;
+
+  /// \brief Offset of each type within the bitstream, indexed by the
+  /// type ID, or the representation of a Type*.
+  const uint32_t *TypeOffsets;
+
+  /// \brief Types that have already been loaded from the PCH file.
+  ///
+  /// When the pointer at index I is non-NULL, the type with
+  /// ID = (I + 1) << 3 has already been loaded from the PCH file.
+  std::vector<QualType> TypesLoaded;
+
+  /// \brief Offset of each declaration within the bitstream, indexed
+  /// by the declaration ID (-1).
+  const uint32_t *DeclOffsets;
+
+  /// \brief Declarations that have already been loaded from the PCH file.
+  ///
+  /// When the pointer at index I is non-NULL, the declaration with ID
+  /// = I + 1 has already been loaded.
+  std::vector<Decl *> DeclsLoaded;
+
+  typedef llvm::DenseMap<const DeclContext *, std::pair<uint64_t, uint64_t> >
+    DeclContextOffsetsMap;
+
+  /// \brief Offsets of the lexical and visible declarations for each
+  /// DeclContext.
+  DeclContextOffsetsMap DeclContextOffsets;
+
+  /// \brief Actual data for the on-disk hash table.
+  ///
+  // This pointer points into a memory buffer, where the on-disk hash
+  // table for identifiers actually lives.
+  const char *IdentifierTableData;
+
+  /// \brief A pointer to an on-disk hash table of opaque type
+  /// IdentifierHashTable.
+  void *IdentifierLookupTable;
+
+  /// \brief Offsets into the identifier table data.
+  ///
+  /// This array is indexed by the identifier ID (-1), and provides
+  /// the offset into IdentifierTableData where the string data is
+  /// stored.
+  const uint32_t *IdentifierOffsets;
+
+  /// \brief A vector containing identifiers that have already been
+  /// loaded.
+  ///
+  /// If the pointer at index I is non-NULL, then it refers to the
+  /// IdentifierInfo for the identifier with ID=I+1 that has already
+  /// been loaded.
+  std::vector<IdentifierInfo *> IdentifiersLoaded;
+
+  /// \brief A pointer to an on-disk hash table of opaque type
+  /// PCHMethodPoolLookupTable.
+  ///
+  /// This hash table provides the instance and factory methods
+  /// associated with every selector known in the PCH file.
+  void *MethodPoolLookupTable;
+
+  /// \brief A pointer to the character data that comprises the method
+  /// pool.
+  ///
+  /// The SelectorOffsets table refers into this memory.
+  const unsigned char *MethodPoolLookupTableData;
+
+  /// \brief The number of selectors stored in the method pool itself.
+  unsigned TotalSelectorsInMethodPool;
+
+  /// \brief Offsets into the method pool lookup table's data array
+  /// where each selector resides.
+  const uint32_t *SelectorOffsets;
+
+  /// \brief The total number of selectors stored in the PCH file.
+  unsigned TotalNumSelectors;
+
+  /// \brief A vector containing selectors that have already been loaded.
+  ///
+  /// This vector is indexed by the Selector ID (-1). NULL selector
+  /// entries indicate that the particular selector ID has not yet
+  /// been loaded.
+  llvm::SmallVector<Selector, 16> SelectorsLoaded;
+
+  /// \brief Offsets of all of the macro definitions in the preprocessing
+  /// record in the PCH file.
+  const uint32_t *MacroDefinitionOffsets;
+      
+  /// \brief The macro definitions we have already loaded.
+  llvm::SmallVector<MacroDefinition *, 16> MacroDefinitionsLoaded;
+      
+  /// \brief The number of preallocated preprocessing entities in the
+  /// preprocessing record.
+  unsigned NumPreallocatedPreprocessingEntities;
+      
+  /// \brief The set of external definitions stored in the the PCH
+  /// file.
+  llvm::SmallVector<uint64_t, 16> ExternalDefinitions;
+
+  /// \brief The set of tentative definitions stored in the the PCH
+  /// file.
+  llvm::SmallVector<uint64_t, 16> TentativeDefinitions;
+      
+  /// \brief The set of tentative definitions stored in the the PCH
+  /// file.
+  llvm::SmallVector<uint64_t, 16> UnusedStaticFuncs;
+
+  /// \brief The set of locally-scoped external declarations stored in
+  /// the the PCH file.
+  llvm::SmallVector<uint64_t, 16> LocallyScopedExternalDecls;
+
+  /// \brief The set of ext_vector type declarations stored in the the
+  /// PCH file.
+  llvm::SmallVector<uint64_t, 4> ExtVectorDecls;
+
+  /// \brief The set of Objective-C category definitions stored in the
+  /// the PCH file.
+  llvm::SmallVector<uint64_t, 4> ObjCCategoryImpls;
+
+  /// \brief The original file name that was used to build the PCH file, which
+  /// may have been modified for relocatable-pch support.
+  std::string OriginalFileName;
+
+  /// \brief The actual original file name that was used to build the PCH file.
+  std::string ActualOriginalFileName;
+
+  /// \brief Whether this precompiled header is a relocatable PCH file.
+  bool RelocatablePCH;
+
+  /// \brief The system include root to be used when loading the
+  /// precompiled header.
+  const char *isysroot;
+
+  /// \brief Mapping from switch-case IDs in the PCH file to
+  /// switch-case statements.
+  std::map<unsigned, SwitchCase *> SwitchCaseStmts;
+
+  /// \brief Mapping from label statement IDs in the PCH file to label
+  /// statements.
+  std::map<unsigned, LabelStmt *> LabelStmts;
+
+  /// \brief Mapping from label IDs to the set of "goto" statements
+  /// that point to that label before the label itself has been
+  /// de-serialized.
+  std::multimap<unsigned, GotoStmt *> UnresolvedGotoStmts;
+
+  /// \brief Mapping from label IDs to the set of address label
+  /// expressions that point to that label before the label itself has
+  /// been de-serialized.
+  std::multimap<unsigned, AddrLabelExpr *> UnresolvedAddrLabelExprs;
+
+  /// \brief The number of stat() calls that hit/missed the stat
+  /// cache.
+  unsigned NumStatHits, NumStatMisses;
+
+  /// \brief The number of source location entries de-serialized from
+  /// the PCH file.
+  unsigned NumSLocEntriesRead;
+
+  /// \brief The number of statements (and expressions) de-serialized
+  /// from the PCH file.
+  unsigned NumStatementsRead;
+
+  /// \brief The total number of statements (and expressions) stored
+  /// in the PCH file.
+  unsigned TotalNumStatements;
+
+  /// \brief The number of macros de-serialized from the PCH file.
+  unsigned NumMacrosRead;
+
+  /// \brief The number of method pool entries that have been read.
+  unsigned NumMethodPoolSelectorsRead;
+
+  /// \brief The number of times we have looked into the global method
+  /// pool and not found anything.
+  unsigned NumMethodPoolMisses;
+
+  /// \brief The total number of macros stored in the PCH file.
+  unsigned TotalNumMacros;
+
+  /// Number of lexical decl contexts read/total.
+  unsigned NumLexicalDeclContextsRead, TotalLexicalDeclContexts;
+
+  /// Number of visible decl contexts read/total.
+  unsigned NumVisibleDeclContextsRead, TotalVisibleDeclContexts;
+
+  /// \brief When a type or declaration is being loaded from the PCH file, an
+  /// instantance of this RAII object will be available on the stack to
+  /// indicate when we are in a recursive-loading situation.
+  class LoadingTypeOrDecl {
+    PCHReader &Reader;
+    LoadingTypeOrDecl *Parent;
+
+    LoadingTypeOrDecl(const LoadingTypeOrDecl&); // do not implement
+    LoadingTypeOrDecl &operator=(const LoadingTypeOrDecl&); // do not implement
+
+  public:
+    explicit LoadingTypeOrDecl(PCHReader &Reader);
+    ~LoadingTypeOrDecl();
+  };
+  friend class LoadingTypeOrDecl;
+
+  /// \brief If we are currently loading a type or declaration, points to the
+  /// most recent LoadingTypeOrDecl object on the stack.
+  LoadingTypeOrDecl *CurrentlyLoadingTypeOrDecl;
+
+  /// \brief An IdentifierInfo that has been loaded but whose top-level
+  /// declarations of the same name have not (yet) been loaded.
+  struct PendingIdentifierInfo {
+    IdentifierInfo *II;
+    llvm::SmallVector<uint32_t, 4> DeclIDs;
+  };
+
+  /// \brief The set of identifiers that were read while the PCH reader was
+  /// (recursively) loading declarations.
+  ///
+  /// The declarations on the identifier chain for these identifiers will be
+  /// loaded once the recursive loading has completed.
+  std::deque<PendingIdentifierInfo> PendingIdentifierInfos;
+
+  /// \brief FIXME: document!
+  llvm::SmallVector<uint64_t, 16> SpecialTypes;
+
+  /// \brief Contains declarations and definitions that will be
+  /// "interesting" to the ASTConsumer, when we get that AST consumer.
+  ///
+  /// "Interesting" declarations are those that have data that may
+  /// need to be emitted, such as inline function definitions or
+  /// Objective-C protocols.
+  llvm::SmallVector<Decl *, 16> InterestingDecls;
+
+  /// \brief The file ID for the predefines buffer in the PCH file.
+  FileID PCHPredefinesBufferID;
+
+  /// \brief Pointer to the beginning of the predefines buffer in the
+  /// PCH file.
+  const char *PCHPredefines;
+
+  /// \brief Length of the predefines buffer in the PCH file.
+  unsigned PCHPredefinesLen;
+
+  /// \brief Suggested contents of the predefines buffer, after this
+  /// PCH file has been processed.
+  ///
+  /// In most cases, this string will be empty, because the predefines
+  /// buffer computed to build the PCH file will be identical to the
+  /// predefines buffer computed from the command line. However, when
+  /// there are differences that the PCH reader can work around, this
+  /// predefines buffer may contain additional definitions.
+  std::string SuggestedPredefines;
+
+  void MaybeAddSystemRootToFilename(std::string &Filename);
+
+  PCHReadResult ReadPCHBlock();
+  bool CheckPredefinesBuffer(llvm::StringRef PCHPredef, FileID PCHBufferID);
+  bool ParseLineTable(llvm::SmallVectorImpl<uint64_t> &Record);
+  PCHReadResult ReadSourceManagerBlock();
+  PCHReadResult ReadSLocEntryRecord(unsigned ID);
+
+  bool ParseLanguageOptions(const llvm::SmallVectorImpl<uint64_t> &Record);
+  QualType ReadTypeRecord(uint64_t Offset);
+  void LoadedDecl(unsigned Index, Decl *D);
+  Decl *ReadDeclRecord(uint64_t Offset, unsigned Index);
+
+  /// \brief Produce an error diagnostic and return true.
+  ///
+  /// This routine should only be used for fatal errors that have to
+  /// do with non-routine failures (e.g., corrupted PCH file).
+  void Error(const char *Msg);
+
+  PCHReader(const PCHReader&); // do not implement
+  PCHReader &operator=(const PCHReader &); // do not implement
+public:
+  typedef llvm::SmallVector<uint64_t, 64> RecordData;
+
+  /// \brief Load the PCH file and validate its contents against the given
+  /// Preprocessor.
+  ///
+  /// \param PP the preprocessor associated with the context in which this
+  /// precompiled header will be loaded.
+  ///
+  /// \param Context the AST context that this precompiled header will be
+  /// loaded into.
+  ///
+  /// \param isysroot If non-NULL, the system include path specified by the
+  /// user. This is only used with relocatable PCH files. If non-NULL,
+  /// a relocatable PCH file will use the default path "/".
+  PCHReader(Preprocessor &PP, ASTContext *Context, const char *isysroot = 0);
+
+  /// \brief Load the PCH file without using any pre-initialized Preprocessor.
+  ///
+  /// The necessary information to initialize a Preprocessor later can be
+  /// obtained by setting a PCHReaderListener.
+  ///
+  /// \param SourceMgr the source manager into which the precompiled header
+  /// will be loaded.
+  ///
+  /// \param FileMgr the file manager into which the precompiled header will
+  /// be loaded.
+  ///
+  /// \param Diags the diagnostics system to use for reporting errors and
+  /// warnings relevant to loading the precompiled header.
+  ///
+  /// \param isysroot If non-NULL, the system include path specified by the
+  /// user. This is only used with relocatable PCH files. If non-NULL,
+  /// a relocatable PCH file will use the default path "/".
+  PCHReader(SourceManager &SourceMgr, FileManager &FileMgr,
+            Diagnostic &Diags, const char *isysroot = 0);
+  ~PCHReader();
+
+  /// \brief Load the precompiled header designated by the given file
+  /// name.
+  PCHReadResult ReadPCH(const std::string &FileName);
+
+  /// \brief Set the PCH callbacks listener.
+  void setListener(PCHReaderListener *listener) {
+    Listener.reset(listener);
+  }
+
+  /// \brief Set the Preprocessor to use.
+  void setPreprocessor(Preprocessor &pp);
+
+  /// \brief Sets and initializes the given Context.
+  void InitializeContext(ASTContext &Context);
+
+  /// \brief Retrieve the name of the PCH file
+  const std::string &getFileName() { return FileName; }
+
+  /// \brief Retrieve the name of the original source file name
+  const std::string &getOriginalSourceFile() { return OriginalFileName; }
+
+  /// \brief Retrieve the name of the original source file name
+  /// directly from the PCH file, without actually loading the PCH
+  /// file.
+  static std::string getOriginalSourceFile(const std::string &PCHFileName,
+                                           Diagnostic &Diags);
+
+  /// \brief Returns the suggested contents of the predefines buffer,
+  /// which contains a (typically-empty) subset of the predefines
+  /// build prior to including the precompiled header.
+  const std::string &getSuggestedPredefines() { return SuggestedPredefines; }
+      
+  /// \brief Read preprocessed entities into the 
+  virtual void ReadPreprocessedEntities();
+
+  /// \brief Reads a TemplateArgumentLocInfo appropriate for the
+  /// given TemplateArgument kind.
+  TemplateArgumentLocInfo
+  GetTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind,
+                             const RecordData &Record, unsigned &Idx);
+
+  /// \brief Reads a declarator info from the given record.
+  virtual TypeSourceInfo *GetTypeSourceInfo(const RecordData &Record,
+                                            unsigned &Idx);
+
+  /// \brief Resolve a type ID into a type, potentially building a new
+  /// type.
+  virtual QualType GetType(pch::TypeID ID);
+
+  /// \brief Resolve a declaration ID into a declaration, potentially
+  /// building a new declaration.
+  virtual Decl *GetDecl(pch::DeclID ID);
+
+  /// \brief Resolve the offset of a statement into a statement.
+  ///
+  /// This operation will read a new statement from the external
+  /// source each time it is called, and is meant to be used via a
+  /// LazyOffsetPtr (which is used by Decls for the body of functions, etc).
+  virtual Stmt *GetDeclStmt(uint64_t Offset);
+
+  /// ReadBlockAbbrevs - Enter a subblock of the specified BlockID with the
+  /// specified cursor.  Read the abbreviations that are at the top of the block
+  /// and then leave the cursor pointing into the block.
+  bool ReadBlockAbbrevs(llvm::BitstreamCursor &Cursor, unsigned BlockID);
+
+  /// \brief Read all of the declarations lexically stored in a
+  /// declaration context.
+  ///
+  /// \param DC The declaration context whose declarations will be
+  /// read.
+  ///
+  /// \param Decls Vector that will contain the declarations loaded
+  /// from the external source. The caller is responsible for merging
+  /// these declarations with any declarations already stored in the
+  /// declaration context.
+  ///
+  /// \returns true if there was an error while reading the
+  /// declarations for this declaration context.
+  virtual bool ReadDeclsLexicallyInContext(DeclContext *DC,
+                                 llvm::SmallVectorImpl<pch::DeclID> &Decls);
+
+  /// \brief Read all of the declarations visible from a declaration
+  /// context.
+  ///
+  /// \param DC The declaration context whose visible declarations
+  /// will be read.
+  ///
+  /// \param Decls A vector of visible declaration structures,
+  /// providing the mapping from each name visible in the declaration
+  /// context to the declaration IDs of declarations with that name.
+  ///
+  /// \returns true if there was an error while reading the
+  /// declarations for this declaration context.
+  ///
+  /// FIXME: Using this intermediate data structure results in an
+  /// extraneous copying of the data. Could we pass in a reference to
+  /// the StoredDeclsMap instead?
+  virtual bool ReadDeclsVisibleInContext(DeclContext *DC,
+                       llvm::SmallVectorImpl<VisibleDeclaration> & Decls);
+
+  /// \brief Function that will be invoked when we begin parsing a new
+  /// translation unit involving this external AST source.
+  ///
+  /// This function will provide all of the external definitions to
+  /// the ASTConsumer.
+  virtual void StartTranslationUnit(ASTConsumer *Consumer);
+
+  /// \brief Print some statistics about PCH usage.
+  virtual void PrintStats();
+
+  /// \brief Initialize the semantic source with the Sema instance
+  /// being used to perform semantic analysis on the abstract syntax
+  /// tree.
+  virtual void InitializeSema(Sema &S);
+
+  /// \brief Inform the semantic consumer that Sema is no longer available.
+  virtual void ForgetSema() { SemaObj = 0; }
+
+  /// \brief Retrieve the IdentifierInfo for the named identifier.
+  ///
+  /// This routine builds a new IdentifierInfo for the given identifier. If any
+  /// declarations with this name are visible from translation unit scope, their
+  /// declarations will be deserialized and introduced into the declaration
+  /// chain of the identifier.
+  virtual IdentifierInfo* get(const char *NameStart, const char *NameEnd);
+  IdentifierInfo* get(llvm::StringRef Name) {
+    return get(Name.begin(), Name.end());
+  }
+
+  /// \brief Load the contents of the global method pool for a given
+  /// selector.
+  ///
+  /// \returns a pair of Objective-C methods lists containing the
+  /// instance and factory methods, respectively, with this selector.
+  virtual std::pair<ObjCMethodList, ObjCMethodList>
+    ReadMethodPool(Selector Sel);
+
+  void SetIdentifierInfo(unsigned ID, IdentifierInfo *II);
+  void SetGloballyVisibleDecls(IdentifierInfo *II,
+                               const llvm::SmallVectorImpl<uint32_t> &DeclIDs,
+                               bool Nonrecursive = false);
+
+  /// \brief Report a diagnostic.
+  DiagnosticBuilder Diag(unsigned DiagID);
+
+  /// \brief Report a diagnostic.
+  DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID);
+
+  IdentifierInfo *DecodeIdentifierInfo(unsigned Idx);
+
+  IdentifierInfo *GetIdentifierInfo(const RecordData &Record, unsigned &Idx) {
+    return DecodeIdentifierInfo(Record[Idx++]);
+  }
+
+  virtual IdentifierInfo *GetIdentifier(unsigned ID) {
+    return DecodeIdentifierInfo(ID);
+  }
+
+  /// \brief Read the source location entry with index ID.
+  virtual void ReadSLocEntry(unsigned ID);
+
+  Selector DecodeSelector(unsigned Idx);
+
+  virtual Selector GetSelector(uint32_t ID);
+  virtual uint32_t GetNumKnownSelectors();
+
+  Selector GetSelector(const RecordData &Record, unsigned &Idx) {
+    return DecodeSelector(Record[Idx++]);
+  }
+  DeclarationName ReadDeclarationName(const RecordData &Record, unsigned &Idx);
+
+  /// \brief Read an integral value
+  llvm::APInt ReadAPInt(const RecordData &Record, unsigned &Idx);
+
+  /// \brief Read a signed integral value
+  llvm::APSInt ReadAPSInt(const RecordData &Record, unsigned &Idx);
+
+  /// \brief Read a floating-point value
+  llvm::APFloat ReadAPFloat(const RecordData &Record, unsigned &Idx);
+
+  // \brief Read a string
+  std::string ReadString(const RecordData &Record, unsigned &Idx);
+
+  /// \brief Reads attributes from the current stream position.
+  Attr *ReadAttributes();
+
+  /// \brief ReadDeclExpr - Reads an expression from the current decl cursor.
+  Expr *ReadDeclExpr();
+
+  /// \brief ReadTypeExpr - Reads an expression from the current type cursor.
+  Expr *ReadTypeExpr();
+
+  /// \brief Reads a statement from the specified cursor.
+  Stmt *ReadStmt(llvm::BitstreamCursor &Cursor);
+
+  /// \brief Read a statement from the current DeclCursor.
+  Stmt *ReadDeclStmt() {
+    return ReadStmt(DeclsCursor);
+  }
+
+  /// \brief Reads the macro record located at the given offset.
+  void ReadMacroRecord(uint64_t Offset);
+
+  /// \brief Read the set of macros defined by this external macro source.
+  virtual void ReadDefinedMacros();
+
+  /// \brief Retrieve the macro definition with the given ID.
+  MacroDefinition *getMacroDefinition(pch::IdentID ID);
+      
+  /// \brief Retrieve the AST context that this PCH reader
+  /// supplements.
+  ASTContext *getContext() { return Context; }
+
+  // \brief Contains declarations that were loaded before we have
+  // access to a Sema object.
+  llvm::SmallVector<NamedDecl *, 16> PreloadedDecls;
+
+  /// \brief Retrieve the semantic analysis object used to analyze the
+  /// translation unit in which the precompiled header is being
+  /// imported.
+  Sema *getSema() { return SemaObj; }
+
+  /// \brief Retrieve the stream that this PCH reader is reading from.
+  llvm::BitstreamCursor &getStream() { return Stream; }
+  llvm::BitstreamCursor &getDeclsCursor() { return DeclsCursor; }
+
+  /// \brief Retrieve the identifier table associated with the
+  /// preprocessor.
+  IdentifierTable &getIdentifierTable();
+
+  /// \brief Record that the given ID maps to the given switch-case
+  /// statement.
+  void RecordSwitchCaseID(SwitchCase *SC, unsigned ID);
+
+  /// \brief Retrieve the switch-case statement with the given ID.
+  SwitchCase *getSwitchCaseWithID(unsigned ID);
+
+  /// \brief Record that the given label statement has been
+  /// deserialized and has the given ID.
+  void RecordLabelStmt(LabelStmt *S, unsigned ID);
+
+  /// \brief Set the label of the given statement to the label
+  /// identified by ID.
+  ///
+  /// Depending on the order in which the label and other statements
+  /// referencing that label occur, this operation may complete
+  /// immediately (updating the statement) or it may queue the
+  /// statement to be back-patched later.
+  void SetLabelOf(GotoStmt *S, unsigned ID);
+
+  /// \brief Set the label of the given expression to the label
+  /// identified by ID.
+  ///
+  /// Depending on the order in which the label and other statements
+  /// referencing that label occur, this operation may complete
+  /// immediately (updating the statement) or it may queue the
+  /// statement to be back-patched later.
+  void SetLabelOf(AddrLabelExpr *S, unsigned ID);
+};
+
+/// \brief Helper class that saves the current stream position and
+/// then restores it when destroyed.
+struct SavedStreamPosition {
+  explicit SavedStreamPosition(llvm::BitstreamCursor &Cursor)
+  : Cursor(Cursor), Offset(Cursor.GetCurrentBitNo()) { }
+
+  ~SavedStreamPosition() {
+    Cursor.JumpToBit(Offset);
+  }
+
+private:
+  llvm::BitstreamCursor &Cursor;
+  uint64_t Offset;
+};
+
+inline void PCHValidator::Error(const char *Msg) {
+  Reader.Error(Msg);
+}
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Frontend/PCHWriter.h b/include/clang/Frontend/PCHWriter.h
new file mode 100644
index 0000000..e006de5
--- /dev/null
+++ b/include/clang/Frontend/PCHWriter.h
@@ -0,0 +1,350 @@
+//===--- PCHWriter.h - Precompiled Headers Writer ---------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the PCHWriter class, which writes a precompiled
+//  header containing a serialized representation of a translation
+//  unit.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_FRONTEND_PCH_WRITER_H
+#define LLVM_CLANG_FRONTEND_PCH_WRITER_H
+
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclarationName.h"
+#include "clang/Frontend/PCHBitCodes.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVector.h"
+#include <map>
+#include <queue>
+
+namespace llvm {
+  class APFloat;
+  class APInt;
+  class BitstreamWriter;
+}
+
+namespace clang {
+
+class ASTContext;
+class LabelStmt;
+class MacroDefinition;
+class MemorizeStatCalls;
+class Preprocessor;
+class Sema;
+class SourceManager;
+class SwitchCase;
+class TargetInfo;
+
+/// A structure for putting "fast"-unqualified QualTypes into a
+/// DenseMap.  This uses the standard pointer hash function.
+struct UnsafeQualTypeDenseMapInfo {
+  static inline bool isEqual(QualType A, QualType B) { return A == B; }
+  static inline QualType getEmptyKey() {
+    return QualType::getFromOpaquePtr((void*) 1);
+  }
+  static inline QualType getTombstoneKey() {
+    return QualType::getFromOpaquePtr((void*) 2);
+  }
+  static inline unsigned getHashValue(QualType T) {
+    assert(!T.getLocalFastQualifiers() && 
+           "hash invalid for types with fast quals");
+    uintptr_t v = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
+    return (unsigned(v) >> 4) ^ (unsigned(v) >> 9);
+  }
+};
+
+/// \brief Writes a precompiled header containing the contents of a
+/// translation unit.
+///
+/// The PCHWriter class produces a bitstream containing the serialized
+/// representation of a given abstract syntax tree and its supporting
+/// data structures. This bitstream can be de-serialized via an
+/// instance of the PCHReader class.
+class PCHWriter {
+public:
+  typedef llvm::SmallVector<uint64_t, 64> RecordData;
+
+private:
+  /// \brief The bitstream writer used to emit this precompiled header.
+  llvm::BitstreamWriter &Stream;
+
+  /// \brief Stores a declaration or a type to be written to the PCH file.
+  class DeclOrType {
+  public:
+    DeclOrType(Decl *D) : Stored(D), IsType(false) { }
+    DeclOrType(QualType T) : Stored(T.getAsOpaquePtr()), IsType(true) { }
+    
+    bool isType() const { return IsType; }
+    bool isDecl() const { return !IsType; }
+    
+    QualType getType() const {
+      assert(isType() && "Not a type!");
+      return QualType::getFromOpaquePtr(Stored);
+    }
+    
+    Decl *getDecl() const {
+      assert(isDecl() && "Not a decl!");
+      return static_cast<Decl *>(Stored);
+    }
+    
+  private:
+    void *Stored;
+    bool IsType;
+  };
+  
+  /// \brief The declarations and types to emit.
+  std::queue<DeclOrType> DeclTypesToEmit;
+  
+  /// \brief Map that provides the ID numbers of each declaration within
+  /// the output stream.
+  ///
+  /// The ID numbers of declarations are consecutive (in order of
+  /// discovery) and start at 2. 1 is reserved for the translation
+  /// unit, while 0 is reserved for NULL.
+  llvm::DenseMap<const Decl *, pch::DeclID> DeclIDs;
+
+  /// \brief Offset of each declaration in the bitstream, indexed by
+  /// the declaration's ID.
+  std::vector<uint32_t> DeclOffsets;
+
+  /// \brief Map that provides the ID numbers of each type within the
+  /// output stream.
+  ///
+  /// The ID numbers of types are consecutive (in order of discovery)
+  /// and start at 1. 0 is reserved for NULL. When types are actually
+  /// stored in the stream, the ID number is shifted by 2 bits to
+  /// allow for the const/volatile qualifiers.
+  ///
+  /// Keys in the map never have const/volatile qualifiers.
+  llvm::DenseMap<QualType, pch::TypeID, UnsafeQualTypeDenseMapInfo> TypeIDs;
+
+  /// \brief Offset of each type in the bitstream, indexed by
+  /// the type's ID.
+  std::vector<uint32_t> TypeOffsets;
+
+  /// \brief The type ID that will be assigned to the next new type.
+  pch::TypeID NextTypeID;
+
+  /// \brief Map that provides the ID numbers of each identifier in
+  /// the output stream.
+  ///
+  /// The ID numbers for identifiers are consecutive (in order of
+  /// discovery), starting at 1. An ID of zero refers to a NULL
+  /// IdentifierInfo.
+  llvm::DenseMap<const IdentifierInfo *, pch::IdentID> IdentifierIDs;
+
+  /// \brief Offsets of each of the identifier IDs into the identifier
+  /// table.
+  std::vector<uint32_t> IdentifierOffsets;
+
+  /// \brief Map that provides the ID numbers of each Selector.
+  llvm::DenseMap<Selector, pch::SelectorID> SelectorIDs;
+
+  /// \brief Offset of each selector within the method pool/selector
+  /// table, indexed by the Selector ID (-1).
+  std::vector<uint32_t> SelectorOffsets;
+
+  /// \brief A vector of all Selectors (ordered by ID).
+  std::vector<Selector> SelVector;
+
+  /// \brief Offsets of each of the macro identifiers into the
+  /// bitstream.
+  ///
+  /// For each identifier that is associated with a macro, this map
+  /// provides the offset into the bitstream where that macro is
+  /// defined.
+  llvm::DenseMap<const IdentifierInfo *, uint64_t> MacroOffsets;
+
+  /// \brief Mapping from macro definitions (as they occur in the preprocessing
+  /// record) to the index into the macro definitions table.
+  llvm::DenseMap<const MacroDefinition *, pch::IdentID> MacroDefinitions;
+  
+  /// \brief Mapping from the macro definition indices in \c MacroDefinitions
+  /// to the corresponding offsets within the preprocessor block.
+  std::vector<uint32_t> MacroDefinitionOffsets;
+  
+  /// \brief Declarations encountered that might be external
+  /// definitions.
+  ///
+  /// We keep track of external definitions (as well as tentative
+  /// definitions) as we are emitting declarations to the PCH
+  /// file. The PCH file contains a separate record for these external
+  /// definitions, which are provided to the AST consumer by the PCH
+  /// reader. This is behavior is required to properly cope with,
+  /// e.g., tentative variable definitions that occur within
+  /// headers. The declarations themselves are stored as declaration
+  /// IDs, since they will be written out to an EXTERNAL_DEFINITIONS
+  /// record.
+  llvm::SmallVector<uint64_t, 16> ExternalDefinitions;
+
+  /// \brief Statements that we've encountered while serializing a
+  /// declaration or type.
+  llvm::SmallVector<Stmt *, 8> StmtsToEmit;
+
+  /// \brief Mapping from SwitchCase statements to IDs.
+  std::map<SwitchCase *, unsigned> SwitchCaseIDs;
+
+  /// \brief Mapping from LabelStmt statements to IDs.
+  std::map<LabelStmt *, unsigned> LabelIDs;
+
+  /// \brief The number of statements written to the PCH file.
+  unsigned NumStatements;
+
+  /// \brief The number of macros written to the PCH file.
+  unsigned NumMacros;
+
+  /// \brief The number of lexical declcontexts written to the PCH
+  /// file.
+  unsigned NumLexicalDeclContexts;
+
+  /// \brief The number of visible declcontexts written to the PCH
+  /// file.
+  unsigned NumVisibleDeclContexts;
+
+  void WriteBlockInfoBlock();
+  void WriteMetadata(ASTContext &Context, const char *isysroot);
+  void WriteLanguageOptions(const LangOptions &LangOpts);
+  void WriteStatCache(MemorizeStatCalls &StatCalls, const char* isysroot);
+  void WriteSourceManagerBlock(SourceManager &SourceMgr,
+                               const Preprocessor &PP,
+                               const char* isysroot);
+  void WritePreprocessor(const Preprocessor &PP);
+  void WriteType(QualType T);
+  uint64_t WriteDeclContextLexicalBlock(ASTContext &Context, DeclContext *DC);
+  uint64_t WriteDeclContextVisibleBlock(ASTContext &Context, DeclContext *DC);
+
+  void WriteMethodPool(Sema &SemaRef);
+  void WriteIdentifierTable(Preprocessor &PP);
+  void WriteAttributeRecord(const Attr *Attr);
+
+  unsigned ParmVarDeclAbbrev;
+  void WriteDeclsBlockAbbrevs();
+  void WriteDecl(ASTContext &Context, Decl *D);
+  
+public:
+  /// \brief Create a new precompiled header writer that outputs to
+  /// the given bitstream.
+  PCHWriter(llvm::BitstreamWriter &Stream);
+
+  /// \brief Write a precompiled header for the given semantic analysis.
+  ///
+  /// \param SemaRef a reference to the semantic analysis object that processed
+  /// the AST to be written into the precompiled header.
+  ///
+  /// \param StatCalls the object that cached all of the stat() calls made while
+  /// searching for source files and headers.
+  ///
+  /// \param isysroot if non-NULL, write a relocatable PCH file whose headers
+  /// are relative to the given system root.
+  ///
+  /// \param PPRec Record of the preprocessing actions that occurred while
+  /// preprocessing this file, e.g., macro instantiations
+  void WritePCH(Sema &SemaRef, MemorizeStatCalls *StatCalls,
+                const char* isysroot);
+
+  /// \brief Emit a source location.
+  void AddSourceLocation(SourceLocation Loc, RecordData &Record);
+
+  /// \brief Emit an integral value.
+  void AddAPInt(const llvm::APInt &Value, RecordData &Record);
+
+  /// \brief Emit a signed integral value.
+  void AddAPSInt(const llvm::APSInt &Value, RecordData &Record);
+
+  /// \brief Emit a floating-point value.
+  void AddAPFloat(const llvm::APFloat &Value, RecordData &Record);
+
+  /// \brief Emit a reference to an identifier
+  void AddIdentifierRef(const IdentifierInfo *II, RecordData &Record);
+
+  /// \brief Emit a Selector (which is a smart pointer reference)
+  void AddSelectorRef(const Selector, RecordData &Record);
+
+  /// \brief Get the unique number used to refer to the given
+  /// identifier.
+  pch::IdentID getIdentifierRef(const IdentifierInfo *II);
+
+  /// \brief Retrieve the offset of the macro definition for the given
+  /// identifier.
+  ///
+  /// The identifier must refer to a macro.
+  uint64_t getMacroOffset(const IdentifierInfo *II) {
+    assert(MacroOffsets.find(II) != MacroOffsets.end() &&
+           "Identifier does not name a macro");
+    return MacroOffsets[II];
+  }
+
+  /// \brief Retrieve the ID number corresponding to the given macro 
+  /// definition.
+  pch::IdentID getMacroDefinitionID(MacroDefinition *MD);
+  
+  /// \brief Emit a reference to a type.
+  void AddTypeRef(QualType T, RecordData &Record);
+
+  /// \brief Emits a reference to a declarator info.
+  void AddTypeSourceInfo(TypeSourceInfo *TInfo, RecordData &Record);
+
+  /// \brief Emits a template argument location.
+  void AddTemplateArgumentLoc(const TemplateArgumentLoc &Arg,
+                              RecordData &Record);
+
+  /// \brief Emit a reference to a declaration.
+  void AddDeclRef(const Decl *D, RecordData &Record);
+
+  /// \brief Determine the declaration ID of an already-emitted
+  /// declaration.
+  pch::DeclID getDeclID(const Decl *D);
+
+  /// \brief Emit a declaration name.
+  void AddDeclarationName(DeclarationName Name, RecordData &Record);
+
+  /// \brief Add a string to the given record.
+  void AddString(const std::string &Str, RecordData &Record);
+
+  /// \brief Note that the identifier II occurs at the given offset
+  /// within the identifier table.
+  void SetIdentifierOffset(const IdentifierInfo *II, uint32_t Offset);
+
+  /// \brief Note that the selector Sel occurs at the given offset
+  /// within the method pool/selector table.
+  void SetSelectorOffset(Selector Sel, uint32_t Offset);
+
+  /// \brief Add the given statement or expression to the queue of
+  /// statements to emit.
+  ///
+  /// This routine should be used when emitting types and declarations
+  /// that have expressions as part of their formulation. Once the
+  /// type or declaration has been written, call FlushStmts() to write
+  /// the corresponding statements just after the type or
+  /// declaration.
+  void AddStmt(Stmt *S) { StmtsToEmit.push_back(S); }
+
+  /// \brief Write the given subexpression to the bitstream.
+  void WriteSubStmt(Stmt *S);
+
+  /// \brief Flush all of the statements and expressions that have
+  /// been added to the queue via AddStmt().
+  void FlushStmts();
+
+  /// \brief Record an ID for the given switch-case statement.
+  unsigned RecordSwitchCaseID(SwitchCase *S);
+
+  /// \brief Retrieve the ID for the given switch-case statement.
+  unsigned getSwitchCaseID(SwitchCase *S);
+
+  /// \brief Retrieve the ID for the given label statement, which may
+  /// or may not have been emitted yet.
+  unsigned GetLabelID(LabelStmt *S);
+
+  unsigned getParmVarDeclAbbrev() const { return ParmVarDeclAbbrev; }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Frontend/PathDiagnosticClients.h b/include/clang/Frontend/PathDiagnosticClients.h
new file mode 100644
index 0000000..f8d2eeb
--- /dev/null
+++ b/include/clang/Frontend/PathDiagnosticClients.h
@@ -0,0 +1,32 @@
+//===--- PathDiagnosticClients.h - Path Diagnostic Clients ------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the interface to create different path diagostic clients.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_PATH_DIAGNOSTIC_CLIENTS_H
+#define LLVM_CLANG_FRONTEND_PATH_DIAGNOSTIC_CLiENTS_H
+
+#include <string>
+
+namespace clang {
+
+class PathDiagnosticClient;
+class Preprocessor;
+
+PathDiagnosticClient*
+CreateHTMLDiagnosticClient(const std::string& prefix, const Preprocessor &PP);
+
+PathDiagnosticClient*
+CreatePlistDiagnosticClient(const std::string& prefix, const Preprocessor &PP,
+                            PathDiagnosticClient *SubPD = 0);
+
+} // end clang namespace
+#endif
diff --git a/include/clang/Frontend/PreprocessorOptions.h b/include/clang/Frontend/PreprocessorOptions.h
new file mode 100644
index 0000000..891359b
--- /dev/null
+++ b/include/clang/Frontend/PreprocessorOptions.h
@@ -0,0 +1,102 @@
+//===--- PreprocessorOptionms.h ---------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_PREPROCESSOROPTIONS_H_
+#define LLVM_CLANG_FRONTEND_PREPROCESSOROPTIONS_H_
+
+#include "llvm/ADT/StringRef.h"
+#include <cassert>
+#include <string>
+#include <utility>
+#include <vector>
+
+namespace llvm {
+  class MemoryBuffer;
+}
+
+namespace clang {
+
+class Preprocessor;
+class LangOptions;
+
+/// PreprocessorOptions - This class is used for passing the various options
+/// used in preprocessor initialization to InitializePreprocessor().
+class PreprocessorOptions {
+public:
+  std::vector<std::pair<std::string, bool/*isUndef*/> > Macros;
+  std::vector<std::string> Includes;
+  std::vector<std::string> MacroIncludes;
+
+  unsigned UsePredefines : 1; /// Initialize the preprocessor with the compiler
+                              /// and target specific predefines.
+
+  unsigned DetailedRecord : 1; /// Whether we should maintain a detailed
+                               /// record of all macro definitions and
+                               /// instantiations.
+  
+  /// The implicit PCH included at the start of the translation unit, or empty.
+  std::string ImplicitPCHInclude;
+
+  /// The implicit PTH input included at the start of the translation unit, or
+  /// empty.
+  std::string ImplicitPTHInclude;
+
+  /// If given, a PTH cache file to use for speeding up header parsing.
+  std::string TokenCache;
+
+  /// \brief The set of file remappings, which take existing files on
+  /// the system (the first part of each pair) and gives them the
+  /// contents of other files on the system (the second part of each
+  /// pair).
+  std::vector<std::pair<std::string, std::string> >  RemappedFiles;
+
+  /// \brief The set of file-to-buffer remappings, which take existing files
+  /// on the system (the first part of each pair) and gives them the contents
+  /// of the specified memory buffer (the second part of each pair).
+  std::vector<std::pair<std::string, const llvm::MemoryBuffer *> > 
+    RemappedFileBuffers;
+  
+  typedef std::vector<std::pair<std::string, std::string> >::const_iterator
+    remapped_file_iterator;
+  remapped_file_iterator remapped_file_begin() const { 
+    return RemappedFiles.begin();
+  }
+  remapped_file_iterator remapped_file_end() const { 
+    return RemappedFiles.end();
+  }
+
+  typedef std::vector<std::pair<std::string, const llvm::MemoryBuffer *> >::
+                                  const_iterator remapped_file_buffer_iterator;
+  remapped_file_buffer_iterator remapped_file_buffer_begin() const {
+    return RemappedFileBuffers.begin();
+  }
+  remapped_file_buffer_iterator remapped_file_buffer_end() const {
+    return RemappedFileBuffers.end();
+  }
+  
+public:
+  PreprocessorOptions() : UsePredefines(true), DetailedRecord(false) {}
+
+  void addMacroDef(llvm::StringRef Name) {
+    Macros.push_back(std::make_pair(Name, false));
+  }
+  void addMacroUndef(llvm::StringRef Name) {
+    Macros.push_back(std::make_pair(Name, true));
+  }
+  void addRemappedFile(llvm::StringRef From, llvm::StringRef To) {
+    RemappedFiles.push_back(std::make_pair(From, To));
+  }
+  void addRemappedFile(llvm::StringRef From, const llvm::MemoryBuffer * To) {
+    RemappedFileBuffers.push_back(std::make_pair(From, To));
+  }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Frontend/PreprocessorOutputOptions.h b/include/clang/Frontend/PreprocessorOutputOptions.h
new file mode 100644
index 0000000..a712a3d
--- /dev/null
+++ b/include/clang/Frontend/PreprocessorOutputOptions.h
@@ -0,0 +1,37 @@
+//===--- PreprocessorOutputOptions.h ----------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_PREPROCESSOROUTPUTOPTIONS_H
+#define LLVM_CLANG_FRONTEND_PREPROCESSOROUTPUTOPTIONS_H
+
+namespace clang {
+
+/// PreprocessorOutputOptions - Options for controlling the C preprocessor
+/// output (e.g., -E).
+class PreprocessorOutputOptions {
+public:
+  unsigned ShowCPP : 1;           ///< Print normal preprocessed output.
+  unsigned ShowMacros : 1;        ///< Print macro definitions.
+  unsigned ShowLineMarkers : 1;   ///< Show #line markers.
+  unsigned ShowComments : 1;      ///< Show comments.
+  unsigned ShowMacroComments : 1; ///< Show comments, even in macros.
+
+public:
+  PreprocessorOutputOptions() {
+    ShowCPP = 1;
+    ShowMacros = 0;
+    ShowLineMarkers = 1;
+    ShowComments = 0;
+    ShowMacroComments = 0;
+  }
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Frontend/StmtXML.def b/include/clang/Frontend/StmtXML.def
new file mode 100644
index 0000000..2f0da9e
--- /dev/null
+++ b/include/clang/Frontend/StmtXML.def
@@ -0,0 +1,513 @@
+//===-- StmtXML.def - Metadata about Stmt XML nodes ------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the XML statement database structure as written in
+//  <TranslationUnit> sub-nodes of the XML document.
+//  The semantics of the attributes and enums are mostly self-documenting
+//  by looking at the appropriate internally used functions and values.
+//  The following macros are used:
+//
+//  NODE_XML( CLASS, NAME ) - A node of name NAME denotes a concrete
+//  statement of class CLASS where CLASS is a class name used internally by clang.
+//  After a NODE_XML the definition of all (optional) attributes of that statement
+//  node and possible sub-nodes follows.
+//
+//  END_NODE_XML - Closes the attribute definition of the current node.
+//
+//  ID_ATTRIBUTE_XML - Some statement nodes have an "id" attribute containing a
+//  string, which value uniquely identify that statement. Other nodes may refer
+//  by reference attributes to this value (currently used only for Label).
+//
+//  TYPE_ATTRIBUTE_XML( FN ) - Type nodes refer to the result type id of an
+//  expression by a "type" attribute. FN is internally used by clang.
+//
+//  ATTRIBUTE_XML( FN, NAME ) - An attribute named NAME. FN is internally
+//  used by clang. A boolean attribute have the values "0" or "1".
+//
+//  ATTRIBUTE_SPECIAL_XML( FN, NAME ) - An attribute named NAME which deserves
+//  a special handling. See the appropriate documentations.
+//
+//  ATTRIBUTE_FILE_LOCATION_XML - A bunch of attributes denoting the location of
+//  a statement in the source file(s).
+//
+//  ATTRIBUTE_OPT_XML( FN, NAME ) - An optional attribute named NAME.
+//  Optional attributes are omitted for boolean types, if the value is false,
+//  for integral types, if the value is null and for strings,
+//  if the value is the empty string. FN is internally used by clang.
+//
+//  ATTRIBUTE_ENUM[_OPT]_XML( FN, NAME ) - An attribute named NAME. The value
+//  is an enumeration defined with ENUM_XML macros immediately following after
+//  that macro. An optional attribute is ommited, if the particular enum is the
+//  empty string. FN is internally used by clang.
+//
+//  ENUM_XML( VALUE, NAME ) - An enumeration element named NAME. VALUE is
+//  internally used by clang.
+//
+//  END_ENUM_XML - Closes the enumeration definition of the current attribute.
+//
+//  SUB_NODE_XML( CLASS ) - A mandatory sub-node of class CLASS or its sub-classes.
+//
+//  SUB_NODE_OPT_XML( CLASS ) - An optional sub-node of class CLASS or its sub-classes.
+//
+//  SUB_NODE_SEQUENCE_XML( CLASS ) - Zero or more sub-nodes of class CLASS or
+//  its sub-classes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef ATTRIBUTE_FILE_LOCATION_XML
+#  define ATTRIBUTE_FILE_LOCATION_XML             \
+     ATTRIBUTE_XML(getFilename(), "file")         \
+     ATTRIBUTE_XML(getLine(), "line")             \
+     ATTRIBUTE_XML(getColumn(), "col")            \
+     ATTRIBUTE_OPT_XML(getFilename(), "endfile")  \
+     ATTRIBUTE_OPT_XML(getLine(), "endline")      \
+     ATTRIBUTE_OPT_XML(getColumn(), "endcol")
+#endif
+
+#ifndef TYPE_ATTRIBUTE_XML
+#  define TYPE_ATTRIBUTE_XML( FN )     ATTRIBUTE_XML(FN, "type")
+#endif
+
+#ifndef CONTEXT_ATTRIBUTE_XML
+#  define CONTEXT_ATTRIBUTE_XML( FN )  ATTRIBUTE_XML(FN, "context")
+#endif
+
+NODE_XML(Stmt, "Stmt_Unsupported")                    // fallback for unsupproted statements
+  ATTRIBUTE_FILE_LOCATION_XML
+END_NODE_XML
+
+NODE_XML(NullStmt, "NullStmt")
+  ATTRIBUTE_FILE_LOCATION_XML
+END_NODE_XML
+
+NODE_XML(CompoundStmt, "CompoundStmt")
+  ATTRIBUTE_FILE_LOCATION_XML
+  ATTRIBUTE_XML(size(), "num_stmts")
+  SUB_NODE_SEQUENCE_XML(Stmt)
+END_NODE_XML
+
+NODE_XML(CaseStmt, "CaseStmt")                        // case expr: body;
+  ATTRIBUTE_FILE_LOCATION_XML
+  SUB_NODE_XML(Stmt)                                  // body
+  SUB_NODE_XML(Expr)                                  // expr
+  SUB_NODE_XML(Expr)                                  // rhs expr in gc extension: case expr .. expr: body;
+END_NODE_XML
+
+NODE_XML(DefaultStmt, "DefaultStmt")                  // default: body;
+  ATTRIBUTE_FILE_LOCATION_XML
+  SUB_NODE_XML(Stmt)                                  // body
+END_NODE_XML
+
+NODE_XML(LabelStmt, "LabelStmt")                      // Label: body;
+  ID_ATTRIBUTE_XML
+  ATTRIBUTE_FILE_LOCATION_XML
+  ATTRIBUTE_XML(getName(), "name")                    // string
+  SUB_NODE_XML(Stmt)                                  // body
+END_NODE_XML
+
+NODE_XML(IfStmt, "IfStmt")                            // if (cond) stmt1; else stmt2;
+  ATTRIBUTE_FILE_LOCATION_XML
+  SUB_NODE_XML(Expr)                                  // cond
+  SUB_NODE_XML(Stmt)                                  // stmt1
+  SUB_NODE_XML(Stmt)                                  // stmt2
+END_NODE_XML
+
+NODE_XML(SwitchStmt, "SwitchStmt")                    // switch (cond) body;
+  ATTRIBUTE_FILE_LOCATION_XML
+  SUB_NODE_XML(Expr)                                  // cond
+  SUB_NODE_XML(Stmt)                                  // body
+END_NODE_XML
+
+NODE_XML(WhileStmt, "WhileStmt")                      // while (cond) body;
+  ATTRIBUTE_FILE_LOCATION_XML
+  SUB_NODE_XML(Expr)                                  // cond
+  SUB_NODE_XML(Stmt)                                  // body
+END_NODE_XML
+
+NODE_XML(DoStmt, "DoStmt")                            // do body while (cond);
+  ATTRIBUTE_FILE_LOCATION_XML
+  SUB_NODE_XML(Expr)                                  // cond
+  SUB_NODE_XML(Stmt)                                  // body
+END_NODE_XML
+
+NODE_XML(ForStmt, "ForStmt")                          // for (init; cond; inc) body;
+  ATTRIBUTE_FILE_LOCATION_XML
+  SUB_NODE_XML(Stmt)                                  // init
+  SUB_NODE_XML(Expr)                                  // cond
+  SUB_NODE_XML(Expr)                                  // inc
+  SUB_NODE_XML(Stmt)                                  // body
+END_NODE_XML
+
+NODE_XML(GotoStmt, "GotoStmt")                        // goto label;
+  ATTRIBUTE_FILE_LOCATION_XML
+  ATTRIBUTE_XML(getLabel()->getName(), "name")        // informal string
+  ATTRIBUTE_XML(getLabel(), "ref")                    // id string
+END_NODE_XML
+
+NODE_XML(IndirectGotoStmt, "IndirectGotoStmt")        // goto expr;
+  ATTRIBUTE_FILE_LOCATION_XML
+  SUB_NODE_XML(Expr)                                  // expr
+END_NODE_XML
+
+NODE_XML(ContinueStmt, "ContinueStmt")                // continue
+  ATTRIBUTE_FILE_LOCATION_XML
+END_NODE_XML
+
+NODE_XML(BreakStmt, "BreakStmt")                      // break
+  ATTRIBUTE_FILE_LOCATION_XML
+END_NODE_XML
+
+NODE_XML(ReturnStmt, "ReturnStmt")                    // return expr;
+  ATTRIBUTE_FILE_LOCATION_XML
+  SUB_NODE_XML(Expr)                                  // expr
+END_NODE_XML
+
+NODE_XML(AsmStmt, "AsmStmt")                          // GNU inline-assembly statement extension
+  ATTRIBUTE_FILE_LOCATION_XML
+  // FIXME
+END_NODE_XML
+
+NODE_XML(DeclStmt, "DeclStmt")                        // a declaration statement
+  ATTRIBUTE_FILE_LOCATION_XML
+  SUB_NODE_SEQUENCE_XML(Decl)
+END_NODE_XML
+
+// C++ statements
+NODE_XML(CXXTryStmt, "CXXTryStmt")                    // try CompoundStmt CXXCatchStmt1 CXXCatchStmt2 ..
+  ATTRIBUTE_FILE_LOCATION_XML
+  ATTRIBUTE_XML(getNumHandlers(), "num_handlers")
+  SUB_NODE_XML(CompoundStmt)
+  SUB_NODE_SEQUENCE_XML(CXXCatchStmt)
+END_NODE_XML
+
+NODE_XML(CXXCatchStmt, "CXXCatchStmt")                // catch (decl) Stmt
+  ATTRIBUTE_FILE_LOCATION_XML
+  SUB_NODE_XML(VarDecl)
+  SUB_NODE_XML(Stmt)
+END_NODE_XML
+
+// Expressions
+NODE_XML(PredefinedExpr, "PredefinedExpr")
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+  ATTRIBUTE_ENUM_XML(getIdentType(), "kind")
+	  ENUM_XML(PredefinedExpr::Func, "__func__")
+	  ENUM_XML(PredefinedExpr::Function, "__FUNCTION__")
+	  ENUM_XML(PredefinedExpr::PrettyFunction, "__PRETTY_FUNCTION__")
+  END_ENUM_XML
+END_NODE_XML
+
+NODE_XML(DeclRefExpr, "DeclRefExpr")                  // an expression referring to a declared entity
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+  ATTRIBUTE_XML(getDecl(), "ref")                     // id string of the declaration
+  ATTRIBUTE_XML(getDecl()->getNameAsString(), "name") // informal
+  //ATTRIBUTE_ENUM_XML(getDecl()->getKind(), "kind")  // really needed here?
+END_NODE_XML
+
+NODE_XML(IntegerLiteral, "IntegerLiteral")
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+  ATTRIBUTE_XML(getValue(), "value")                  // (signed) integer
+END_NODE_XML
+
+NODE_XML(CharacterLiteral, "CharacterLiteral")
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+  ATTRIBUTE_XML(getValue(), "value")                  // unsigned
+END_NODE_XML
+
+NODE_XML(FloatingLiteral, "FloatingLiteral")
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+  // FIXME: output float as written in source (no approximation or the like)
+  //ATTRIBUTE_XML(getValueAsApproximateDouble(), "value")   // float
+END_NODE_XML
+
+NODE_XML(StringLiteral, "StringLiteral")
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+  ATTRIBUTE_SPECIAL_XML(getStrData(), "value")          // string, special handling for escaping needed
+  ATTRIBUTE_OPT_XML(isWide(), "is_wide")                // boolean
+END_NODE_XML
+
+NODE_XML(UnaryOperator, "UnaryOperator")                // op(expr) or (expr)op
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+  ATTRIBUTE_ENUM_XML(getOpcode(), "kind")
+    ENUM_XML(UnaryOperator::PostInc, "postinc")
+    ENUM_XML(UnaryOperator::PostDec, "postdec")
+    ENUM_XML(UnaryOperator::PreInc,  "preinc")
+    ENUM_XML(UnaryOperator::PreDec,  "predec")
+    ENUM_XML(UnaryOperator::AddrOf,  "addrof")
+    ENUM_XML(UnaryOperator::Deref,   "deref")
+    ENUM_XML(UnaryOperator::Plus,    "plus")
+    ENUM_XML(UnaryOperator::Minus,   "minus")
+    ENUM_XML(UnaryOperator::Not,     "not")             // bitwise not
+    ENUM_XML(UnaryOperator::LNot,    "lnot")            // boolean not
+    ENUM_XML(UnaryOperator::Real,    "__real")
+    ENUM_XML(UnaryOperator::Imag,    "__imag")
+    ENUM_XML(UnaryOperator::Extension, "__extension__")
+    ENUM_XML(UnaryOperator::OffsetOf,  "__builtin_offsetof")
+  END_ENUM_XML
+  SUB_NODE_XML(Expr)                                    // expr
+END_NODE_XML
+
+NODE_XML(BinaryOperator, "BinaryOperator")              // (expr1) op (expr2)
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+  ATTRIBUTE_ENUM_XML(getOpcode(), "kind")
+    ENUM_XML(BinaryOperator::PtrMemD  , "ptrmemd")
+    ENUM_XML(BinaryOperator::PtrMemI  , "ptrmemi")
+    ENUM_XML(BinaryOperator::Mul      , "mul")
+    ENUM_XML(BinaryOperator::Div      , "div")
+    ENUM_XML(BinaryOperator::Rem      , "rem")
+    ENUM_XML(BinaryOperator::Add      , "add")
+    ENUM_XML(BinaryOperator::Sub      , "sub")
+    ENUM_XML(BinaryOperator::Shl      , "shl")
+    ENUM_XML(BinaryOperator::Shr      , "shr")
+    ENUM_XML(BinaryOperator::LT       , "lt")
+    ENUM_XML(BinaryOperator::GT       , "gt")
+    ENUM_XML(BinaryOperator::LE       , "le")
+    ENUM_XML(BinaryOperator::GE       , "ge")
+    ENUM_XML(BinaryOperator::EQ       , "eq")
+    ENUM_XML(BinaryOperator::NE       , "ne")
+    ENUM_XML(BinaryOperator::And      , "and")          // bitwise and
+    ENUM_XML(BinaryOperator::Xor      , "xor")
+    ENUM_XML(BinaryOperator::Or       , "or")           // bitwise or
+    ENUM_XML(BinaryOperator::LAnd     , "land")         // boolean and
+    ENUM_XML(BinaryOperator::LOr      , "lor")          // boolean or
+    ENUM_XML(BinaryOperator::Assign   , "assign")
+    ENUM_XML(BinaryOperator::MulAssign, "mulassign")
+    ENUM_XML(BinaryOperator::DivAssign, "divassign")
+    ENUM_XML(BinaryOperator::RemAssign, "remassign")
+    ENUM_XML(BinaryOperator::AddAssign, "addassign")
+    ENUM_XML(BinaryOperator::SubAssign, "subassign")
+    ENUM_XML(BinaryOperator::ShlAssign, "shlassign")
+    ENUM_XML(BinaryOperator::ShrAssign, "shrassign")
+    ENUM_XML(BinaryOperator::AndAssign, "andassign")
+    ENUM_XML(BinaryOperator::XorAssign, "xorassign")
+    ENUM_XML(BinaryOperator::OrAssign , "orassign")
+    ENUM_XML(BinaryOperator::Comma    , "comma")
+  END_ENUM_XML
+  SUB_NODE_XML(Expr)                                    // expr1
+  SUB_NODE_XML(Expr)                                    // expr2
+END_NODE_XML
+
+// FIXME: is there a special class needed or is BinaryOperator sufficient?
+//NODE_XML(CompoundAssignOperator, "CompoundAssignOperator")
+
+NODE_XML(ConditionalOperator, "ConditionalOperator")    // expr1 ? expr2 : expr3
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+  SUB_NODE_XML(Expr)                                    // expr1
+  SUB_NODE_XML(Expr)                                    // expr2
+  SUB_NODE_XML(Expr)                                    // expr3
+END_NODE_XML
+
+NODE_XML(SizeOfAlignOfExpr, "SizeOfAlignOfExpr")        // sizeof(expr) or alignof(expr)
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+  ATTRIBUTE_XML(isSizeOf(), "is_sizeof")
+  ATTRIBUTE_XML(isArgumentType(), "is_type")            // "1" if expr denotes a type
+  ATTRIBUTE_SPECIAL_XML(getArgumentType(), "type_ref")  // optional, denotes the type of expr, if is_type=="1", special handling needed since getArgumentType() could assert
+  SUB_NODE_OPT_XML(Expr)                                // expr, if is_type=="0"
+END_NODE_XML
+
+NODE_XML(ArraySubscriptExpr, "ArraySubscriptExpr")      // expr1[expr2]
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+  SUB_NODE_XML(Expr)                                    // expr1
+  SUB_NODE_XML(Expr)                                    // expr2
+END_NODE_XML
+
+NODE_XML(CallExpr, "CallExpr")                          // fnexpr(arg1, arg2, ...)
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+  ATTRIBUTE_XML(getNumArgs(), "num_args")               // unsigned
+  SUB_NODE_XML(Expr)                                    // fnexpr
+  SUB_NODE_SEQUENCE_XML(Expr)                           // arg1..argN
+END_NODE_XML
+
+NODE_XML(MemberExpr, "MemberExpr")                      // expr->F or expr.F
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+  ATTRIBUTE_XML(isArrow(), "is_deref")
+  ATTRIBUTE_XML(getMemberDecl(), "ref")                 // refers to F
+  ATTRIBUTE_XML(getMemberDecl()->getNameAsString(), "name") // informal
+  SUB_NODE_XML(Expr)                                    // expr
+END_NODE_XML
+
+NODE_XML(CStyleCastExpr, "CStyleCastExpr")              // (type)expr
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+  ATTRIBUTE_XML(getTypeAsWritten(), "type_ref")         // denotes the type as written in the source code
+  SUB_NODE_XML(Expr)                                    // expr
+END_NODE_XML
+
+NODE_XML(ImplicitCastExpr, "ImplicitCastExpr")
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+  SUB_NODE_XML(Expr)
+END_NODE_XML
+
+NODE_XML(CompoundLiteralExpr, "CompoundLiteralExpr")    // [C99 6.5.2.5]
+  SUB_NODE_XML(Expr)                                    // init
+END_NODE_XML
+
+NODE_XML(ExtVectorElementExpr, "ExtVectorElementExpr")
+  SUB_NODE_XML(Expr)                                    // base
+END_NODE_XML
+
+NODE_XML(InitListExpr, "InitListExpr")                  // struct foo x = { expr1, { expr2, expr3 } };
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+  ATTRIBUTE_OPT_XML(getInitializedFieldInUnion(), "field_ref")  // if a union is initialized, this refers to the initialized union field id
+  ATTRIBUTE_XML(getNumInits(), "num_inits")             // unsigned
+  SUB_NODE_SEQUENCE_XML(Expr)                           // expr1..exprN
+END_NODE_XML
+
+NODE_XML(DesignatedInitExpr, "DesignatedInitExpr")
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+END_NODE_XML
+
+NODE_XML(ImplicitValueInitExpr, "ImplicitValueInitExpr")  //  Implicit value initializations occur within InitListExpr
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+END_NODE_XML
+
+NODE_XML(VAArgExpr, "VAArgExpr")                        // used for the builtin function __builtin_va_start(expr)
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+  SUB_NODE_XML(Expr)                                    // expr
+END_NODE_XML
+
+NODE_XML(ParenExpr, "ParenExpr")                        // this represents a parethesized expression "(expr)". Only formed if full location information is requested.
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+  SUB_NODE_XML(Expr)                                    // expr
+END_NODE_XML
+
+// GNU Extensions
+NODE_XML(AddrLabelExpr, "AddrLabelExpr")                // the GNU address of label extension, representing &&label.
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+  ATTRIBUTE_XML(getLabel(), "ref")                      // id string
+  SUB_NODE_XML(LabelStmt)                               // expr
+END_NODE_XML
+
+NODE_XML(StmtExpr, "StmtExpr")                          // StmtExpr contains a single CompoundStmt node, which it evaluates and takes the value of the last subexpression.
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+  SUB_NODE_XML(CompoundStmt)
+END_NODE_XML
+
+NODE_XML(TypesCompatibleExpr, "TypesCompatibleExpr")    // GNU builtin-in function __builtin_types_compatible_p
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+  ATTRIBUTE_XML(getArgType1(), "type1_ref")             // id of type1
+  ATTRIBUTE_XML(getArgType2(), "type2_ref")             // id of type2
+END_NODE_XML
+
+NODE_XML(ChooseExpr, "ChooseExpr")                      // GNU builtin-in function __builtin_choose_expr(expr1, expr2, expr3)
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+  SUB_NODE_XML(Expr)                                    // expr1
+  SUB_NODE_XML(Expr)                                    // expr2
+  SUB_NODE_XML(Expr)                                    // expr3
+END_NODE_XML
+
+NODE_XML(GNUNullExpr, "GNUNullExpr")                    // GNU __null extension
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+END_NODE_XML
+
+// C++ Expressions
+NODE_XML(CXXOperatorCallExpr, "CXXOperatorCallExpr")    // fnexpr(arg1, arg2, ...)
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+  ATTRIBUTE_XML(getNumArgs(), "num_args")               // unsigned
+  SUB_NODE_XML(Expr)                                    // fnexpr
+  SUB_NODE_SEQUENCE_XML(Expr)                           // arg1..argN
+END_NODE_XML
+
+NODE_XML(CXXNamedCastExpr, "CXXNamedCastExpr")          // xxx_cast<type>(expr)
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+  ATTRIBUTE_ENUM_XML(getStmtClass(), "kind")
+	  ENUM_XML(Stmt::CXXStaticCastExprClass, "static_cast")
+	  ENUM_XML(Stmt::CXXDynamicCastExprClass, "dynamic_cast")
+	  ENUM_XML(Stmt::CXXReinterpretCastExprClass, "reinterpret_cast")
+	  ENUM_XML(Stmt::CXXConstCastExprClass, "const_cast")
+  END_ENUM_XML
+  ATTRIBUTE_XML(getTypeAsWritten(), "type_ref")         // denotes the type as written in the source code
+  SUB_NODE_XML(Expr)                                    // expr
+END_NODE_XML
+
+NODE_XML(CXXMemberCallExpr, "CXXMemberCallExpr")        // fnexpr(arg1, arg2, ...)
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+  ATTRIBUTE_XML(getNumArgs(), "num_args")               // unsigned
+  SUB_NODE_XML(Expr)                                    // fnexpr
+  SUB_NODE_SEQUENCE_XML(Expr)                           // arg1..argN
+END_NODE_XML
+
+NODE_XML(CXXBoolLiteralExpr, "CXXBoolLiteralExpr")
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+  ATTRIBUTE_XML(getValue(), "value")                    // boolean
+END_NODE_XML
+
+NODE_XML(CXXNullPtrLiteralExpr, "CXXNullPtrLiteralExpr")  // [C++0x 2.14.7] C++ Pointer Literal
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+END_NODE_XML
+
+NODE_XML(CXXTypeidExpr, "CXXTypeidExpr")                // typeid(expr)
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+  ATTRIBUTE_XML(isTypeOperand(), "is_type")             // "1" if expr denotes a type
+  ATTRIBUTE_SPECIAL_XML(getTypeOperand(), "type_ref")   // optional, denotes the type of expr, if is_type=="1", special handling needed since getTypeOperand() could assert
+  SUB_NODE_OPT_XML(Expr)                                // expr, if is_type=="0"
+END_NODE_XML
+
+NODE_XML(CXXThisExpr, "CXXThisExpr")                    // this
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+END_NODE_XML
+
+NODE_XML(CXXThrowExpr, "CXXThrowExpr")                  // throw (expr);
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+  SUB_NODE_XML(Expr)                                    // NULL in case of "throw;"
+END_NODE_XML
+
+NODE_XML(CXXDefaultArgExpr, "CXXDefaultArgExpr")
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+  ATTRIBUTE_XML(getParam(), "ref")                      // id of the parameter declaration (the expression is a subnode of the declaration)
+END_NODE_XML
+
+//===----------------------------------------------------------------------===//
+#undef NODE_XML
+#undef ID_ATTRIBUTE_XML
+#undef TYPE_ATTRIBUTE_XML
+#undef ATTRIBUTE_XML
+#undef ATTRIBUTE_SPECIAL_XML
+#undef ATTRIBUTE_OPT_XML
+#undef ATTRIBUTE_ENUM_XML
+#undef ATTRIBUTE_ENUM_OPT_XML
+#undef ATTRIBUTE_FILE_LOCATION_XML
+#undef ENUM_XML
+#undef END_ENUM_XML
+#undef END_NODE_XML
+#undef SUB_NODE_XML
+#undef SUB_NODE_SEQUENCE_XML
+#undef SUB_NODE_OPT_XML
diff --git a/include/clang/Frontend/TextDiagnosticBuffer.h b/include/clang/Frontend/TextDiagnosticBuffer.h
new file mode 100644
index 0000000..380a1dd
--- /dev/null
+++ b/include/clang/Frontend/TextDiagnosticBuffer.h
@@ -0,0 +1,52 @@
+//===--- TextDiagnosticBuffer.h - Buffer Text Diagnostics -------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This is a concrete diagnostic client, which buffers the diagnostic messages.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_TEXT_DIAGNOSTIC_BUFFER_H_
+#define LLVM_CLANG_FRONTEND_TEXT_DIAGNOSTIC_BUFFER_H_
+
+#include "clang/Basic/Diagnostic.h"
+#include <vector>
+
+namespace clang {
+
+class Preprocessor;
+class SourceManager;
+
+class TextDiagnosticBuffer : public DiagnosticClient {
+public:
+  typedef std::vector<std::pair<SourceLocation, std::string> > DiagList;
+  typedef DiagList::iterator iterator;
+  typedef DiagList::const_iterator const_iterator;
+private:
+  DiagList Errors, Warnings, Notes;
+public:
+  const_iterator err_begin() const  { return Errors.begin(); }
+  const_iterator err_end() const    { return Errors.end(); }
+
+  const_iterator warn_begin() const { return Warnings.begin(); }
+  const_iterator warn_end() const   { return Warnings.end(); }
+
+  const_iterator note_begin() const { return Notes.begin(); }
+  const_iterator note_end() const   { return Notes.end(); }
+
+  virtual void HandleDiagnostic(Diagnostic::Level DiagLevel,
+                                const DiagnosticInfo &Info);
+
+  /// FlushDiagnostics - Flush the buffered diagnostics to an given
+  /// diagnostic engine.
+  void FlushDiagnostics(Diagnostic &Diags) const;
+};
+
+} // end namspace clang
+
+#endif
diff --git a/include/clang/Frontend/TextDiagnosticPrinter.h b/include/clang/Frontend/TextDiagnosticPrinter.h
new file mode 100644
index 0000000..3367136
--- /dev/null
+++ b/include/clang/Frontend/TextDiagnosticPrinter.h
@@ -0,0 +1,82 @@
+//===--- TextDiagnosticPrinter.h - Text Diagnostic Client -------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This is a concrete diagnostic client, which prints the diagnostics to
+// standard error.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_TEXT_DIAGNOSTIC_PRINTER_H_
+#define LLVM_CLANG_FRONTEND_TEXT_DIAGNOSTIC_PRINTER_H_
+
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/SourceLocation.h"
+
+namespace llvm {
+  class raw_ostream;
+}
+
+namespace clang {
+class DiagnosticOptions;
+class LangOptions;
+class SourceManager;
+
+class TextDiagnosticPrinter : public DiagnosticClient {
+  llvm::raw_ostream &OS;
+  const LangOptions *LangOpts;
+  const DiagnosticOptions *DiagOpts;
+
+  SourceLocation LastWarningLoc;
+  FullSourceLoc LastLoc;
+  unsigned LastCaretDiagnosticWasNote : 1;
+  unsigned OwnsOutputStream : 1;
+
+  /// A string to prefix to error messages.
+  std::string Prefix;
+
+public:
+  TextDiagnosticPrinter(llvm::raw_ostream &os, const DiagnosticOptions &diags,
+                        bool OwnsOutputStream = false);
+  virtual ~TextDiagnosticPrinter();
+
+  /// setPrefix - Set the diagnostic printer prefix string, which will be
+  /// printed at the start of any diagnostics. If empty, no prefix string is
+  /// used.
+  void setPrefix(std::string Value) { Prefix = Value; }
+
+  void BeginSourceFile(const LangOptions &LO, const Preprocessor *PP) {
+    LangOpts = &LO;
+  }
+
+  void EndSourceFile() {
+    LangOpts = 0;
+  }
+
+  void PrintIncludeStack(SourceLocation Loc, const SourceManager &SM);
+
+  void HighlightRange(const SourceRange &R,
+                      const SourceManager &SrcMgr,
+                      unsigned LineNo, FileID FID,
+                      std::string &CaretLine,
+                      const std::string &SourceLine);
+
+  void EmitCaretDiagnostic(SourceLocation Loc,
+                           SourceRange *Ranges, unsigned NumRanges,
+                           const SourceManager &SM,
+                           const FixItHint *Hints,
+                           unsigned NumHints,
+                           unsigned Columns);
+
+  virtual void HandleDiagnostic(Diagnostic::Level DiagLevel,
+                                const DiagnosticInfo &Info);
+};
+
+} // end namspace clang
+
+#endif
diff --git a/include/clang/Frontend/TypeXML.def b/include/clang/Frontend/TypeXML.def
new file mode 100644
index 0000000..3add99a
--- /dev/null
+++ b/include/clang/Frontend/TypeXML.def
@@ -0,0 +1,260 @@
+//===-- TypeXML.def - Metadata about Type XML nodes ------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the XML type info database as written in the   
+//  <ReferenceSection>/<Types> sub-nodes of the XML document. Type nodes 
+//  are referred by "type" reference attributes throughout the document.
+//  A type node never contains sub-nodes. 
+//  The semantics of the attributes and enums are mostly self-documenting
+//  by looking at the appropriate internally used functions and values.
+//  The following macros are used:
+//
+//  NODE_XML( CLASS, NAME ) - A node of name NAME denotes a concrete 
+//  type of class CLASS where CLASS is a class name used internally by clang. 
+//  After a NODE_XML the definition of all (optional) attributes of that type 
+//  node follows.
+//
+//  END_NODE_XML - Closes the attribute definition of the current node.
+//
+//  ID_ATTRIBUTE_XML - Each type node has an "id" attribute containing a 
+//  string, which value uniquely identify the type. Other nodes may refer 
+//  by "type" reference attributes to this value.
+//
+//  TYPE_ATTRIBUTE_XML( FN ) - Type nodes may refer to the ids of other type 
+//  nodes by a "type" attribute. FN is internally used by clang.
+// 
+//  CONTEXT_ATTRIBUTE_XML( FN ) - Type nodes may refer to the ids of their 
+//  declaration contexts by a "context" attribute. FN is internally used by 
+//  clang.
+//
+//  ATTRIBUTE_XML( FN, NAME ) - An attribute named NAME. FN is internally 
+//  used by clang. A boolean attribute have the values "0" or "1".
+//
+//  ATTRIBUTE_OPT_XML( FN, NAME ) - An optional attribute named NAME. 
+//  Optional attributes are omitted for boolean types, if the value is false, 
+//  for integral types, if the value is null and for strings, 
+//  if the value is the empty string. FN is internally used by clang.
+//
+//  ATTRIBUTE_ENUM[_OPT]_XML( FN, NAME ) - An attribute named NAME. The value
+//  is an enumeration defined with ENUM_XML macros immediately following after 
+//  that macro. An optional attribute is ommited, if the particular enum is the 
+//  empty string. FN is internally used by clang.
+//  
+//  ENUM_XML( VALUE, NAME ) - An enumeration element named NAME. VALUE is 
+//  internally used by clang.
+//
+//  END_ENUM_XML - Closes the enumeration definition of the current attribute.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef TYPE_ATTRIBUTE_XML
+#  define TYPE_ATTRIBUTE_XML( FN )     ATTRIBUTE_XML(FN, "type")
+#endif
+
+#ifndef CONTEXT_ATTRIBUTE_XML
+#  define CONTEXT_ATTRIBUTE_XML( FN )  ATTRIBUTE_XML(FN, "context")
+#endif
+
+
+NODE_XML(QualType, "CvQualifiedType")
+  ID_ATTRIBUTE_XML
+  TYPE_ATTRIBUTE_XML(getTypePtr())                      // the qualified type, e.g. for 'T* const' it's 'T*'
+  ATTRIBUTE_OPT_XML(isLocalConstQualified(), "const")        // boolean
+  ATTRIBUTE_OPT_XML(isLocalVolatileQualified(), "volatile")  // boolean
+  ATTRIBUTE_OPT_XML(isLocalRestrictQualified(), "restrict")  // boolean
+  ATTRIBUTE_OPT_XML(getObjCGCAttr(), "objc_gc")         // Qualifiers::GC
+  ATTRIBUTE_OPT_XML(getAddressSpace(), "address_space") // unsigned
+END_NODE_XML
+
+NODE_XML(BuiltinType, "FundamentalType")
+  ID_ATTRIBUTE_XML
+  ATTRIBUTE_ENUM_XML(getKind(), "kind")
+	  ENUM_XML(BuiltinType::Void, "void")
+	  ENUM_XML(BuiltinType::Bool, "bool")
+	  ENUM_XML(BuiltinType::Char_U, "char")               // not explicitely qualified char, depends on target platform
+	  ENUM_XML(BuiltinType::Char_S, "char")               // not explicitely qualified char, depends on target platform
+	  ENUM_XML(BuiltinType::SChar, "signed char")
+	  ENUM_XML(BuiltinType::Short, "short");
+	  ENUM_XML(BuiltinType::Int, "int");
+	  ENUM_XML(BuiltinType::Long, "long");
+	  ENUM_XML(BuiltinType::LongLong, "long long");
+	  ENUM_XML(BuiltinType::Int128, "__int128_t");
+	  ENUM_XML(BuiltinType::UChar, "unsigned char");
+	  ENUM_XML(BuiltinType::UShort, "unsigned short");
+	  ENUM_XML(BuiltinType::UInt, "unsigned int");
+	  ENUM_XML(BuiltinType::ULong, "unsigned long");
+	  ENUM_XML(BuiltinType::ULongLong, "unsigned long long");
+	  ENUM_XML(BuiltinType::UInt128, "__uint128_t");
+	  ENUM_XML(BuiltinType::Float, "float");
+	  ENUM_XML(BuiltinType::Double, "double");
+	  ENUM_XML(BuiltinType::LongDouble, "long double");
+	  ENUM_XML(BuiltinType::WChar, "wchar_t");
+	  ENUM_XML(BuiltinType::Char16, "char16_t");
+	  ENUM_XML(BuiltinType::Char32, "char32_t");
+	  ENUM_XML(BuiltinType::NullPtr, "nullptr_t");        // This is the type of C++0x 'nullptr'.
+	  ENUM_XML(BuiltinType::Overload, "overloaded");
+	  ENUM_XML(BuiltinType::Dependent, "dependent");
+  END_ENUM_XML
+END_NODE_XML
+
+NODE_XML(PointerType, "PointerType")    
+  ID_ATTRIBUTE_XML
+  TYPE_ATTRIBUTE_XML(getPointeeType())
+END_NODE_XML
+
+NODE_XML(LValueReferenceType, "ReferenceType")
+  ID_ATTRIBUTE_XML
+  TYPE_ATTRIBUTE_XML(getPointeeType())
+END_NODE_XML
+
+NODE_XML(RValueReferenceType, "ReferenceType")
+  ID_ATTRIBUTE_XML
+  TYPE_ATTRIBUTE_XML(getPointeeType())
+END_NODE_XML
+
+NODE_XML(FunctionNoProtoType, "FunctionNoProtoType")
+  ID_ATTRIBUTE_XML
+END_NODE_XML
+
+NODE_XML(FunctionProtoType, "FunctionType")
+  ID_ATTRIBUTE_XML
+  ATTRIBUTE_XML(getResultType(), "result_type")
+  ATTRIBUTE_OPT_XML(isVariadic(), "variadic")
+END_NODE_XML
+
+NODE_XML(TypedefType, "Typedef")
+  ID_ATTRIBUTE_XML
+  TYPE_ATTRIBUTE_XML(getDecl()->getUnderlyingType())
+  ATTRIBUTE_XML(getDecl()->getNameAsString(), "name")     // string
+  CONTEXT_ATTRIBUTE_XML(getDecl()->getDeclContext())
+END_NODE_XML
+
+NODE_XML(ComplexType, "ComplexType")                      // C99 complex types (_Complex float etc)
+  ID_ATTRIBUTE_XML
+  TYPE_ATTRIBUTE_XML(getElementType())
+END_NODE_XML
+
+NODE_XML(BlockPointerType, "BlockPointerType")
+  ID_ATTRIBUTE_XML
+  TYPE_ATTRIBUTE_XML(getPointeeType())                    // alway refers to a function type
+END_NODE_XML
+
+NODE_XML(MemberPointerType, "MemberPointerType")
+  ID_ATTRIBUTE_XML
+  TYPE_ATTRIBUTE_XML(getPointeeType())
+  ATTRIBUTE_XML(getClass(), "class_type")                 // refers to the class type id of which the pointee is a member
+END_NODE_XML
+
+NODE_XML(ConstantArrayType, "ArrayType")
+  ID_ATTRIBUTE_XML
+  TYPE_ATTRIBUTE_XML(getElementType())
+  ATTRIBUTE_XML(getSize(), "size")                        // unsigned                    
+  ATTRIBUTE_ENUM_OPT_XML(getSizeModifier(), "size_modifier")
+	  ENUM_XML(ArrayType::Normal, "")
+	  ENUM_XML(ArrayType::Static, "static")
+	  ENUM_XML(ArrayType::Star, "star")
+  END_ENUM_XML
+  ATTRIBUTE_OPT_XML(getIndexTypeCVRQualifiers(), "index_type_qualifier")   // unsigned
+END_NODE_XML
+
+NODE_XML(IncompleteArrayType, "IncompleteArrayType")
+  ID_ATTRIBUTE_XML
+  TYPE_ATTRIBUTE_XML(getElementType())
+END_NODE_XML
+
+NODE_XML(VariableArrayType, "VariableArrayType")
+  ID_ATTRIBUTE_XML
+  TYPE_ATTRIBUTE_XML(getElementType())
+  // note: the size expression is print at the point of declaration
+END_NODE_XML
+
+NODE_XML(DependentSizedArrayType, "DependentSizedArrayType")
+  ID_ATTRIBUTE_XML
+  TYPE_ATTRIBUTE_XML(getElementType())
+  // FIXME: how to deal with size expression?
+END_NODE_XML
+
+NODE_XML(VectorType, "VectorType")
+  ID_ATTRIBUTE_XML
+  TYPE_ATTRIBUTE_XML(getElementType())
+  ATTRIBUTE_XML(getNumElements(), "size")               // unsigned
+END_NODE_XML
+
+NODE_XML(ExtVectorType, "ExtVectorType")
+  ID_ATTRIBUTE_XML
+  TYPE_ATTRIBUTE_XML(getElementType())
+  ATTRIBUTE_XML(getNumElements(), "size")               // unsigned
+END_NODE_XML
+
+NODE_XML(TypeOfExprType, "TypeOfExprType")
+  ID_ATTRIBUTE_XML
+  // note: the typeof expression is print at the point of use
+END_NODE_XML
+
+NODE_XML(TypeOfType, "TypeOfType")
+  ID_ATTRIBUTE_XML
+  TYPE_ATTRIBUTE_XML(getUnderlyingType())
+END_NODE_XML
+
+
+NODE_XML(RecordType, "Record")
+  ID_ATTRIBUTE_XML
+  ATTRIBUTE_XML(getDecl()->getNameAsString(), "name")   // string
+  ATTRIBUTE_ENUM_XML(getDecl()->getTagKind(), "kind")
+    ENUM_XML(TagDecl::TK_struct, "struct")
+    ENUM_XML(TagDecl::TK_union, "union")
+    ENUM_XML(TagDecl::TK_class, "class")
+  END_ENUM_XML
+  CONTEXT_ATTRIBUTE_XML(getDecl()->getDeclContext())
+END_NODE_XML
+
+NODE_XML(EnumType, "Enum")
+  ID_ATTRIBUTE_XML
+  ATTRIBUTE_XML(getDecl()->getNameAsString(), "name")   // string
+  CONTEXT_ATTRIBUTE_XML(getDecl()->getDeclContext())
+END_NODE_XML
+
+NODE_XML(TemplateTypeParmType, "TemplateTypeParmType")
+  ID_ATTRIBUTE_XML
+END_NODE_XML
+
+NODE_XML(TemplateSpecializationType, "TemplateSpecializationType")
+  ID_ATTRIBUTE_XML
+END_NODE_XML
+
+NODE_XML(QualifiedNameType, "QualifiedNameType")
+  ID_ATTRIBUTE_XML
+  TYPE_ATTRIBUTE_XML(getNamedType())
+END_NODE_XML
+
+NODE_XML(DependentNameType, "DependentNameType")
+  ID_ATTRIBUTE_XML
+END_NODE_XML
+
+NODE_XML(ObjCInterfaceType, "ObjCInterfaceType")
+  ID_ATTRIBUTE_XML
+END_NODE_XML
+
+NODE_XML(ObjCObjectPointerType, "ObjCObjectPointerType")
+  ID_ATTRIBUTE_XML
+END_NODE_XML
+
+
+//===----------------------------------------------------------------------===//
+#undef NODE_XML
+#undef ID_ATTRIBUTE_XML                
+#undef TYPE_ATTRIBUTE_XML
+#undef CONTEXT_ATTRIBUTE_XML
+#undef ATTRIBUTE_XML
+#undef ATTRIBUTE_OPT_XML
+#undef ATTRIBUTE_ENUM_XML
+#undef ATTRIBUTE_ENUM_OPT_XML
+#undef ENUM_XML
+#undef END_ENUM_XML                    
+#undef END_NODE_XML                    
diff --git a/include/clang/Frontend/Utils.h b/include/clang/Frontend/Utils.h
new file mode 100644
index 0000000..c1d4831
--- /dev/null
+++ b/include/clang/Frontend/Utils.h
@@ -0,0 +1,93 @@
+//===--- Utils.h - Misc utilities for the front-end -------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This header contains miscellaneous utilities for various front-end actions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_UTILS_H
+#define LLVM_CLANG_FRONTEND_UTILS_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace llvm {
+class Triple;
+}
+
+namespace clang {
+class ASTConsumer;
+class Decl;
+class DependencyOutputOptions;
+class Diagnostic;
+class DiagnosticOptions;
+class HeaderSearch;
+class HeaderSearchOptions;
+class IdentifierTable;
+class LangOptions;
+class MinimalAction;
+class Preprocessor;
+class PreprocessorOptions;
+class PreprocessorOutputOptions;
+class SourceManager;
+class Stmt;
+class TargetInfo;
+class FrontendOptions;
+
+/// Normalize \arg File for use in a user defined #include directive (in the
+/// predefines buffer).
+std::string NormalizeDashIncludePath(llvm::StringRef File);
+
+/// Apply the header search options to get given HeaderSearch object.
+void ApplyHeaderSearchOptions(HeaderSearch &HS,
+                              const HeaderSearchOptions &HSOpts,
+                              const LangOptions &Lang,
+                              const llvm::Triple &triple);
+
+/// InitializePreprocessor - Initialize the preprocessor getting it and the
+/// environment ready to process a single file.
+void InitializePreprocessor(Preprocessor &PP,
+                            const PreprocessorOptions &PPOpts,
+                            const HeaderSearchOptions &HSOpts,
+                            const FrontendOptions &FEOpts);
+
+/// ProcessWarningOptions - Initialize the diagnostic client and process the
+/// warning options specified on the command line.
+void ProcessWarningOptions(Diagnostic &Diags, const DiagnosticOptions &Opts);
+
+/// DoPrintPreprocessedInput - Implement -E mode.
+void DoPrintPreprocessedInput(Preprocessor &PP, llvm::raw_ostream* OS,
+                              const PreprocessorOutputOptions &Opts);
+
+/// RewriteMacrosInInput - Implement -rewrite-macros mode.
+void RewriteMacrosInInput(Preprocessor &PP, llvm::raw_ostream* OS);
+
+/// RewriteMacrosInInput - A simple test for the TokenRewriter class.
+void DoRewriteTest(Preprocessor &PP, llvm::raw_ostream* OS);
+
+/// CreatePrintParserActionsAction - Return the actions implementation that
+/// implements the -parse-print-callbacks option.
+MinimalAction *CreatePrintParserActionsAction(Preprocessor &PP,
+                                              llvm::raw_ostream* OS);
+
+/// CheckDiagnostics - Gather the expected diagnostics and check them.
+bool CheckDiagnostics(Preprocessor &PP);
+
+/// AttachDependencyFileGen - Create a dependency file generator, and attach
+/// it to the given preprocessor.  This takes ownership of the output stream.
+void AttachDependencyFileGen(Preprocessor &PP,
+                             const DependencyOutputOptions &Opts);
+
+/// CacheTokens - Cache tokens for use with PCH. Note that this requires
+/// a seekable stream.
+void CacheTokens(Preprocessor &PP, llvm::raw_fd_ostream* OS);
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Frontend/VerifyDiagnosticsClient.h b/include/clang/Frontend/VerifyDiagnosticsClient.h
new file mode 100644
index 0000000..08adbb0
--- /dev/null
+++ b/include/clang/Frontend/VerifyDiagnosticsClient.h
@@ -0,0 +1,81 @@
+//===-- VerifyDiagnosticsClient.h - Verifying Diagnostic Client -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_VERIFYDIAGNOSTICSCLIENT_H
+#define LLVM_CLANG_FRONTEND_VERIFYDIAGNOSTICSCLIENT_H
+
+#include "clang/Basic/Diagnostic.h"
+#include "llvm/ADT/OwningPtr.h"
+
+namespace clang {
+
+class Diagnostic;
+class TextDiagnosticBuffer;
+
+/// VerifyDiagnosticsClient - Create a diagnostic client which will use markers
+/// in the input source to check that all the emitted diagnostics match those
+/// expected.
+///
+/// USING THE DIAGNOSTIC CHECKER:
+///
+/// Indicating that a line expects an error or a warning is simple. Put a
+/// comment on the line that has the diagnostic, use "expected-{error,warning}"
+/// to tag if it's an expected error or warning, and place the expected text
+/// between {{ and }} markers. The full text doesn't have to be included, only
+/// enough to ensure that the correct diagnostic was emitted.
+///
+/// Here's an example:
+///
+///   int A = B; // expected-error {{use of undeclared identifier 'B'}}
+///
+/// You can place as many diagnostics on one line as you wish. To make the code
+/// more readable, you can use slash-newline to separate out the diagnostics.
+///
+/// The simple syntax above allows each specification to match exactly one
+/// error.  You can use the extended syntax to customize this. The extended
+/// syntax is "expected-<type> <n> {{diag text}}", where <type> is one of
+/// "error", "warning" or "note", and <n> is a positive integer. This allows the
+/// diagnostic to appear as many times as specified. Example:
+///
+///   void f(); // expected-note 2 {{previous declaration is here}}
+///
+class VerifyDiagnosticsClient : public DiagnosticClient {
+public:
+  Diagnostic &Diags;
+  llvm::OwningPtr<DiagnosticClient> PrimaryClient;
+  llvm::OwningPtr<TextDiagnosticBuffer> Buffer;
+  Preprocessor *CurrentPreprocessor;
+  unsigned NumErrors;
+
+private:
+  void CheckDiagnostics();
+
+public:
+  /// Create a new verifying diagnostic client, which will issue errors to \arg
+  /// PrimaryClient when a diagnostic does not match what is expected (as
+  /// indicated in the source file). The verifying diagnostic client takes
+  /// ownership of \arg PrimaryClient.
+  VerifyDiagnosticsClient(Diagnostic &Diags, DiagnosticClient *PrimaryClient);
+  ~VerifyDiagnosticsClient();
+
+  virtual void BeginSourceFile(const LangOptions &LangOpts,
+                               const Preprocessor *PP);
+
+  virtual void EndSourceFile();
+
+  virtual void HandleDiagnostic(Diagnostic::Level DiagLevel,
+                                const DiagnosticInfo &Info);
+
+  /// HadErrors - Check if there were any mismatches in expected diagnostics.
+  bool HadErrors();
+};
+
+} // end namspace clang
+
+#endif
diff --git a/include/clang/Index/ASTLocation.h b/include/clang/Index/ASTLocation.h
new file mode 100644
index 0000000..fc18dae
--- /dev/null
+++ b/include/clang/Index/ASTLocation.h
@@ -0,0 +1,174 @@
+//===--- ASTLocation.h - A <Decl, Stmt> pair --------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  ASTLocation is Decl or a Stmt and its immediate Decl parent.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_INDEX_ASTLOCATION_H
+#define LLVM_CLANG_INDEX_ASTLOCATION_H
+
+#include "clang/AST/TypeLoc.h"
+#include "llvm/ADT/PointerIntPair.h"
+
+namespace llvm {
+  class raw_ostream;
+}
+
+namespace clang {
+  class Decl;
+  class Stmt;
+  class NamedDecl;
+
+namespace idx {
+  class TranslationUnit;
+
+/// \brief Represents a Decl or a Stmt and its immediate Decl parent. It's
+/// immutable.
+///
+/// ASTLocation is intended to be used as a "pointer" into the AST. It is either
+/// just a Decl, or a Stmt and its Decl parent. Since a single Stmt is devoid
+/// of context, its parent Decl provides all the additional missing information
+/// like the declaration context, ASTContext, etc.
+///
+class ASTLocation {
+public:
+  enum NodeKind {
+    N_Decl, N_NamedRef, N_Stmt, N_Type
+  };
+
+  struct NamedRef {
+    NamedDecl *ND;
+    SourceLocation Loc;
+    
+    NamedRef() : ND(0) { }
+    NamedRef(NamedDecl *nd, SourceLocation loc) : ND(nd), Loc(loc) { }
+  };
+
+private:
+  llvm::PointerIntPair<Decl *, 2, NodeKind> ParentDecl;
+
+  union {
+    Decl *D;
+    Stmt *Stm;
+    struct {
+      NamedDecl *ND;
+      unsigned RawLoc;
+    } NDRef;
+    struct {
+      void *TyPtr;
+      void *Data;
+    } Ty;
+  };
+
+public:
+  ASTLocation() { }
+
+  explicit ASTLocation(const Decl *d)
+    : ParentDecl(const_cast<Decl*>(d), N_Decl), D(const_cast<Decl*>(d)) { }
+
+  ASTLocation(const Decl *parentDecl, const Stmt *stm)
+    : ParentDecl(const_cast<Decl*>(parentDecl), N_Stmt),
+      Stm(const_cast<Stmt*>(stm)) {
+    if (!stm) ParentDecl.setPointer(0);
+  }
+
+  ASTLocation(const Decl *parentDecl, NamedDecl *ndRef, SourceLocation loc)
+    : ParentDecl(const_cast<Decl*>(parentDecl), N_NamedRef) {
+    if (ndRef) {
+      NDRef.ND = ndRef;
+      NDRef.RawLoc = loc.getRawEncoding();
+    } else
+      ParentDecl.setPointer(0);
+  }
+
+  ASTLocation(const Decl *parentDecl, TypeLoc tyLoc)
+    : ParentDecl(const_cast<Decl*>(parentDecl), N_Type) {
+    if (tyLoc) {
+      Ty.TyPtr = tyLoc.getType().getAsOpaquePtr();
+      Ty.Data = tyLoc.getOpaqueData();
+    } else
+      ParentDecl.setPointer(0);
+  }
+
+  bool isValid() const { return ParentDecl.getPointer() != 0; }
+  bool isInvalid() const { return !isValid(); }
+  
+  NodeKind getKind() const {
+    assert(isValid());
+    return (NodeKind)ParentDecl.getInt();
+  }
+  
+  Decl *getParentDecl() const { return ParentDecl.getPointer(); }
+  
+  Decl *AsDecl() const {
+    assert(getKind() == N_Decl);
+    return D;
+  }
+  Stmt *AsStmt() const {
+    assert(getKind() == N_Stmt);
+    return Stm;
+  }
+  NamedRef AsNamedRef() const {
+    assert(getKind() == N_NamedRef);
+    return NamedRef(NDRef.ND, SourceLocation::getFromRawEncoding(NDRef.RawLoc));
+  }
+  TypeLoc AsTypeLoc() const {
+    assert(getKind() == N_Type);
+    return TypeLoc(QualType::getFromOpaquePtr(Ty.TyPtr), Ty.Data);
+  }
+
+  Decl *dyn_AsDecl() const { return isValid() && getKind() == N_Decl ? D : 0; }
+  Stmt *dyn_AsStmt() const { return isValid() && getKind() == N_Stmt ? Stm : 0; }
+  NamedRef dyn_AsNamedRef() const {
+    return getKind() == N_Type ? AsNamedRef() : NamedRef();
+  }
+  TypeLoc dyn_AsTypeLoc() const {
+    return getKind() == N_Type ? AsTypeLoc() : TypeLoc();
+  }
+  
+  bool isDecl() const { return isValid() && getKind() == N_Decl; }
+  bool isStmt() const { return isValid() && getKind() == N_Stmt; }
+  bool isNamedRef() const { return isValid() && getKind() == N_NamedRef; }
+  bool isType() const { return isValid() && getKind() == N_Type; }
+
+  /// \brief Returns the declaration that this ASTLocation references.
+  ///
+  /// If this points to a Decl, that Decl is returned.
+  /// If this points to an Expr that references a Decl, that Decl is returned,
+  /// otherwise it returns NULL.
+  Decl *getReferencedDecl();
+  const Decl *getReferencedDecl() const {
+    return const_cast<ASTLocation*>(this)->getReferencedDecl();
+  }
+
+  SourceRange getSourceRange() const;
+
+  void print(llvm::raw_ostream &OS) const;
+};
+
+/// \brief Like ASTLocation but also contains the TranslationUnit that the
+/// ASTLocation originated from.
+class TULocation : public ASTLocation {
+  TranslationUnit *TU;
+
+public:
+  TULocation(TranslationUnit *tu, ASTLocation astLoc)
+    : ASTLocation(astLoc), TU(tu) {
+    assert(tu && "Passed null translation unit");
+  }
+
+  TranslationUnit *getTU() const { return TU; }
+};
+
+} // namespace idx
+
+} // namespace clang
+
+#endif
diff --git a/include/clang/Index/Analyzer.h b/include/clang/Index/Analyzer.h
new file mode 100644
index 0000000..f6b5465
--- /dev/null
+++ b/include/clang/Index/Analyzer.h
@@ -0,0 +1,56 @@
+//===--- Analyzer.h - Analysis for indexing information ---------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the Analyzer interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_INDEX_ANALYZER_H
+#define LLVM_CLANG_INDEX_ANALYZER_H
+
+namespace clang {
+  class Decl;
+  class ObjCMessageExpr;
+
+namespace idx {
+  class Program;
+  class IndexProvider;
+  class TULocationHandler;
+
+/// \brief Provides indexing information, like finding all references of an
+/// Entity across translation units.
+class Analyzer {
+  Program &Prog;
+  IndexProvider &Idxer;
+
+  Analyzer(const Analyzer&); // do not implement
+  Analyzer &operator=(const Analyzer &); // do not implement
+
+public:
+  explicit Analyzer(Program &prog, IndexProvider &idxer)
+    : Prog(prog), Idxer(idxer) { }
+
+  /// \brief Find all TULocations for declarations of the given Decl and pass
+  /// them to Handler.
+  void FindDeclarations(Decl *D, TULocationHandler &Handler);
+
+  /// \brief Find all TULocations for references of the given Decl and pass
+  /// them to Handler.
+  void FindReferences(Decl *D, TULocationHandler &Handler);
+
+  /// \brief Find methods that may respond to the given message and pass them
+  /// to Handler.
+  void FindObjCMethods(ObjCMessageExpr *MsgE, TULocationHandler &Handler);
+};
+
+} // namespace idx
+
+} // namespace clang
+
+#endif
diff --git a/include/clang/Index/CallGraph.h b/include/clang/Index/CallGraph.h
new file mode 100644
index 0000000..5edfe6f
--- /dev/null
+++ b/include/clang/Index/CallGraph.h
@@ -0,0 +1,146 @@
+//== CallGraph.cpp - Call graph building ------------------------*- C++ -*--==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defined the CallGraph and CallGraphNode classes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_CALLGRAPH
+#define LLVM_CLANG_ANALYSIS_CALLGRAPH
+
+#include "clang/Index/ASTLocation.h"
+#include "clang/Index/Entity.h"
+#include "clang/Index/Program.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/STLExtras.h"
+#include <vector>
+#include <map>
+
+namespace clang {
+
+class CallGraphNode {
+  idx::Entity F;
+  typedef std::pair<idx::ASTLocation, CallGraphNode*> CallRecord;
+  std::vector<CallRecord> CalledFunctions;
+
+public:
+  CallGraphNode(idx::Entity f) : F(f) {}
+
+  typedef std::vector<CallRecord>::iterator iterator;
+  typedef std::vector<CallRecord>::const_iterator const_iterator;
+
+  iterator begin() { return CalledFunctions.begin(); }
+  iterator end()   { return CalledFunctions.end(); }
+  const_iterator begin() const { return CalledFunctions.begin(); }
+  const_iterator end()   const { return CalledFunctions.end();   }
+
+  void addCallee(idx::ASTLocation L, CallGraphNode *Node) {
+    CalledFunctions.push_back(std::make_pair(L, Node));
+  }
+
+  bool hasCallee() const { return begin() != end(); }
+
+  std::string getName() const { return F.getPrintableName(); }
+
+  Decl *getDecl(ASTContext &Ctx) const { return F.getDecl(Ctx); }
+};
+
+class CallGraph {
+  /// Program manages all Entities.
+  idx::Program Prog;
+
+  typedef std::map<idx::Entity, CallGraphNode *> FunctionMapTy;
+
+  /// FunctionMap owns all CallGraphNodes.
+  FunctionMapTy FunctionMap;
+
+  /// CallerCtx maps a caller to its ASTContext.
+  llvm::DenseMap<CallGraphNode *, ASTContext *> CallerCtx;
+
+  /// Root node is the 'main' function or 0.
+  CallGraphNode *Root;
+
+  /// ExternalCallingNode has edges to all external functions.
+  CallGraphNode *ExternalCallingNode;
+
+public:
+  CallGraph();
+  ~CallGraph();
+
+  typedef FunctionMapTy::iterator iterator;
+  typedef FunctionMapTy::const_iterator const_iterator;
+
+  iterator begin() { return FunctionMap.begin(); }
+  iterator end()   { return FunctionMap.end();   }
+  const_iterator begin() const { return FunctionMap.begin(); }
+  const_iterator end()   const { return FunctionMap.end();   }
+
+  CallGraphNode *getRoot() { return Root; }
+
+  CallGraphNode *getExternalCallingNode() { return ExternalCallingNode; }
+
+  void addTU(ASTContext &AST);
+
+  idx::Program &getProgram() { return Prog; }
+
+  CallGraphNode *getOrInsertFunction(idx::Entity F);
+
+  Decl *getDecl(CallGraphNode *Node);
+
+  void print(llvm::raw_ostream &os);
+  void dump();
+
+  void ViewCallGraph() const;
+};
+
+} // end clang namespace
+
+namespace llvm {
+
+template <> struct GraphTraits<clang::CallGraph> {
+  typedef clang::CallGraph GraphType;
+  typedef clang::CallGraphNode NodeType;
+
+  typedef std::pair<clang::idx::ASTLocation, NodeType*> CGNPairTy;
+  typedef std::pointer_to_unary_function<CGNPairTy, NodeType*> CGNDerefFun;
+
+  typedef mapped_iterator<NodeType::iterator, CGNDerefFun> ChildIteratorType;
+
+  static NodeType *getEntryNode(GraphType *CG) {
+    return CG->getExternalCallingNode();
+  }
+
+  static ChildIteratorType child_begin(NodeType *N) {
+    return map_iterator(N->begin(), CGNDerefFun(CGNDeref));
+  }
+  static ChildIteratorType child_end(NodeType *N) {
+    return map_iterator(N->end(), CGNDerefFun(CGNDeref));
+  }
+
+  typedef std::pair<clang::idx::Entity, NodeType*> PairTy;
+  typedef std::pointer_to_unary_function<PairTy, NodeType*> DerefFun;
+
+  typedef mapped_iterator<GraphType::const_iterator, DerefFun> nodes_iterator;
+
+  static nodes_iterator nodes_begin(const GraphType &CG) {
+    return map_iterator(CG.begin(), DerefFun(CGDeref));
+  }
+  static nodes_iterator nodes_end(const GraphType &CG) {
+    return map_iterator(CG.end(), DerefFun(CGDeref));
+  }
+
+  static NodeType *CGNDeref(CGNPairTy P) { return P.second; }
+
+  static NodeType *CGDeref(PairTy P) { return P.second; }
+};
+
+} // end llvm namespace
+
+#endif
diff --git a/include/clang/Index/DeclReferenceMap.h b/include/clang/Index/DeclReferenceMap.h
new file mode 100644
index 0000000..73f2fe5
--- /dev/null
+++ b/include/clang/Index/DeclReferenceMap.h
@@ -0,0 +1,50 @@
+//===--- DeclReferenceMap.h - Map Decls to their references -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  DeclReferenceMap creates a mapping from Decls to the ASTLocations that
+//  reference them.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_INDEX_DECLREFERENCEMAP_H
+#define LLVM_CLANG_INDEX_DECLREFERENCEMAP_H
+
+#include "clang/Index/ASTLocation.h"
+#include "clang/Index/STLExtras.h"
+#include <map>
+
+namespace clang {
+  class ASTContext;
+  class NamedDecl;
+
+namespace idx {
+
+/// \brief Maps NamedDecls with the ASTLocations that reference them.
+///
+/// References are mapped and retrieved using the canonical decls.
+class DeclReferenceMap {
+public:
+  explicit DeclReferenceMap(ASTContext &Ctx);
+
+  typedef std::multimap<NamedDecl*, ASTLocation> MapTy;
+  typedef pair_value_iterator<MapTy::iterator> astlocation_iterator;
+
+  astlocation_iterator refs_begin(NamedDecl *D) const;
+  astlocation_iterator refs_end(NamedDecl *D) const;
+  bool refs_empty(NamedDecl *D) const;
+
+private:
+  mutable MapTy Map;
+};
+
+} // end idx namespace
+
+} // end clang namespace
+
+#endif
diff --git a/include/clang/Index/Entity.h b/include/clang/Index/Entity.h
new file mode 100644
index 0000000..c2aab62
--- /dev/null
+++ b/include/clang/Index/Entity.h
@@ -0,0 +1,144 @@
+//===--- Entity.h - Cross-translation-unit "token" for decls ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  Entity is a ASTContext-independent way to refer to declarations that are
+//  visible across translation units.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_INDEX_ENTITY_H
+#define LLVM_CLANG_INDEX_ENTITY_H
+
+#include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/DenseMap.h"
+#include <string>
+
+namespace clang {
+  class ASTContext;
+  class Decl;
+
+namespace idx {
+  class Program;
+  class EntityImpl;
+
+/// \brief A ASTContext-independent way to refer to declarations.
+///
+/// Entity is basically the link for declarations that are semantically the same
+/// in multiple ASTContexts. A client will convert a Decl into an Entity and
+/// later use that Entity to find the "same" Decl into another ASTContext.
+/// Declarations that are semantically the same and visible across translation
+/// units will be associated with the same Entity.
+///
+/// An Entity may also refer to declarations that cannot be visible across
+/// translation units, e.g. static functions with the same name in multiple
+/// translation units will be associated with different Entities.
+///
+/// Entities can be checked for equality but note that the same Program object
+/// should be used when getting Entities.
+///
+class Entity {
+  /// \brief Stores the Decl directly if it is not visible outside of its own
+  /// translation unit, otherwise it stores the associated EntityImpl.
+  llvm::PointerUnion<Decl *, EntityImpl *> Val;
+
+  explicit Entity(Decl *D);
+  explicit Entity(EntityImpl *impl) : Val(impl) { }
+  friend class EntityGetter;
+
+public:
+  Entity() { }
+
+  /// \brief Find the Decl that can be referred to by this entity.
+  Decl *getDecl(ASTContext &AST) const;
+
+  /// \brief If this Entity represents a declaration that is internal to its
+  /// translation unit, getInternalDecl() returns it.
+  Decl *getInternalDecl() const {
+    assert(isInternalToTU() && "This Entity is not internal!");
+    return Val.get<Decl *>();
+  }
+
+  /// \brief Get a printable name for debugging purpose.
+  std::string getPrintableName() const;
+
+  /// \brief Get an Entity associated with the given Decl.
+  /// \returns invalid Entity if an Entity cannot refer to this Decl.
+  static Entity get(Decl *D, Program &Prog);
+
+  /// \brief true if the Entity is not visible outside the trasnlation unit.
+  bool isInternalToTU() const {
+    assert(isValid() && "This Entity is not valid!");
+    return Val.is<Decl *>();
+  }
+
+  bool isValid() const { return !Val.isNull(); }
+  bool isInvalid() const { return !isValid(); }
+
+  void *getAsOpaquePtr() const { return Val.getOpaqueValue(); }
+  static Entity getFromOpaquePtr(void *Ptr) {
+    Entity Ent;
+    Ent.Val = llvm::PointerUnion<Decl *, EntityImpl *>::getFromOpaqueValue(Ptr);
+    return Ent;
+  }
+
+  friend bool operator==(const Entity &LHS, const Entity &RHS) {
+    return LHS.getAsOpaquePtr() == RHS.getAsOpaquePtr();
+  }
+
+  // For use in a std::map.
+  friend bool operator < (const Entity &LHS, const Entity &RHS) {
+    return LHS.getAsOpaquePtr() < RHS.getAsOpaquePtr();
+  }
+
+  // For use in DenseMap/DenseSet.
+  static Entity getEmptyMarker() {
+    Entity Ent;
+    Ent.Val =
+      llvm::PointerUnion<Decl *, EntityImpl *>::getFromOpaqueValue((void*)-1);
+    return Ent;
+  }
+  static Entity getTombstoneMarker() {
+    Entity Ent;
+    Ent.Val =
+      llvm::PointerUnion<Decl *, EntityImpl *>::getFromOpaqueValue((void*)-2);
+    return Ent;
+  }
+};
+
+} // namespace idx
+
+} // namespace clang
+
+namespace llvm {
+/// Define DenseMapInfo so that Entities can be used as keys in DenseMap and
+/// DenseSets.
+template<>
+struct DenseMapInfo<clang::idx::Entity> {
+  static inline clang::idx::Entity getEmptyKey() {
+    return clang::idx::Entity::getEmptyMarker();
+  }
+
+  static inline clang::idx::Entity getTombstoneKey() {
+    return clang::idx::Entity::getTombstoneMarker();
+  }
+
+  static unsigned getHashValue(clang::idx::Entity);
+
+  static inline bool
+  isEqual(clang::idx::Entity LHS, clang::idx::Entity RHS) {
+    return LHS == RHS;
+  }
+};
+  
+template <>
+struct isPodLike<clang::idx::Entity> { static const bool value = true; };
+
+}  // end namespace llvm
+
+#endif
diff --git a/include/clang/Index/GlobalSelector.h b/include/clang/Index/GlobalSelector.h
new file mode 100644
index 0000000..9cd83a8
--- /dev/null
+++ b/include/clang/Index/GlobalSelector.h
@@ -0,0 +1,100 @@
+//===--- GlobalSelector.h - Cross-translation-unit "token" for selectors --===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  GlobalSelector is a ASTContext-independent way to refer to selectors.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_INDEX_GLOBALSELECTOR_H
+#define LLVM_CLANG_INDEX_GLOBALSELECTOR_H
+
+#include "llvm/ADT/DenseMap.h"
+#include <string>
+
+namespace clang {
+  class ASTContext;
+  class Selector;
+
+namespace idx {
+  class Program;
+
+/// \brief A ASTContext-independent way to refer to selectors.
+class GlobalSelector {
+  void *Val;
+
+  explicit GlobalSelector(void *val) : Val(val) { }
+
+public:
+  GlobalSelector() : Val(0) { }
+
+  /// \brief Get the ASTContext-specific selector.
+  Selector getSelector(ASTContext &AST) const;
+
+  bool isValid() const { return Val != 0; }
+  bool isInvalid() const { return !isValid(); }
+
+  /// \brief Get a printable name for debugging purpose.
+  std::string getPrintableName() const;
+
+  /// \brief Get a GlobalSelector for the ASTContext-specific selector.
+  static GlobalSelector get(Selector Sel, Program &Prog);
+
+  void *getAsOpaquePtr() const { return Val; }
+
+  static GlobalSelector getFromOpaquePtr(void *Ptr) {
+    return GlobalSelector(Ptr);
+  }
+
+  friend bool operator==(const GlobalSelector &LHS, const GlobalSelector &RHS) {
+    return LHS.getAsOpaquePtr() == RHS.getAsOpaquePtr();
+  }
+
+  // For use in a std::map.
+  friend bool operator< (const GlobalSelector &LHS, const GlobalSelector &RHS) {
+    return LHS.getAsOpaquePtr() < RHS.getAsOpaquePtr();
+  }
+
+  // For use in DenseMap/DenseSet.
+  static GlobalSelector getEmptyMarker() { return GlobalSelector((void*)-1); }
+  static GlobalSelector getTombstoneMarker() {
+    return GlobalSelector((void*)-2);
+  }
+};
+
+} // namespace idx
+
+} // namespace clang
+
+namespace llvm {
+/// Define DenseMapInfo so that GlobalSelectors can be used as keys in DenseMap
+/// and DenseSets.
+template<>
+struct DenseMapInfo<clang::idx::GlobalSelector> {
+  static inline clang::idx::GlobalSelector getEmptyKey() {
+    return clang::idx::GlobalSelector::getEmptyMarker();
+  }
+
+  static inline clang::idx::GlobalSelector getTombstoneKey() {
+    return clang::idx::GlobalSelector::getTombstoneMarker();
+  }
+
+  static unsigned getHashValue(clang::idx::GlobalSelector);
+
+  static inline bool
+  isEqual(clang::idx::GlobalSelector LHS, clang::idx::GlobalSelector RHS) {
+    return LHS == RHS;
+  }
+};
+  
+template <>
+struct isPodLike<clang::idx::GlobalSelector> { static const bool value = true;};
+
+}  // end namespace llvm
+
+#endif
diff --git a/include/clang/Index/Handlers.h b/include/clang/Index/Handlers.h
new file mode 100644
index 0000000..655aef9
--- /dev/null
+++ b/include/clang/Index/Handlers.h
@@ -0,0 +1,81 @@
+//===--- Handlers.h - Interfaces for receiving information ------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  Abstract interfaces for receiving information.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_INDEX_HANDLERS_H
+#define LLVM_CLANG_INDEX_HANDLERS_H
+
+#include "llvm/ADT/SmallVector.h"
+
+namespace clang {
+
+namespace idx {
+  class Entity;
+  class TranslationUnit;
+  class TULocation;
+
+/// \brief Abstract interface for receiving Entities.
+class EntityHandler {
+public:
+  typedef Entity receiving_type;
+
+  virtual ~EntityHandler();
+  virtual void Handle(Entity Ent) = 0;
+};
+
+/// \brief Abstract interface for receiving TranslationUnits.
+class TranslationUnitHandler {
+public:
+  typedef TranslationUnit* receiving_type;
+
+  virtual ~TranslationUnitHandler();
+  virtual void Handle(TranslationUnit *TU) = 0;
+};
+
+/// \brief Abstract interface for receiving TULocations.
+class TULocationHandler {
+public:
+  typedef TULocation receiving_type;
+
+  virtual ~TULocationHandler();
+  virtual void Handle(TULocation TULoc) = 0;
+};
+
+/// \brief Helper for the Handler classes. Stores the objects into a vector.
+/// example:
+/// @code
+/// Storing<TranslationUnitHandler> TURes;
+/// IndexProvider.GetTranslationUnitsFor(Entity, TURes);
+/// for (Storing<TranslationUnitHandler>::iterator
+///   I = TURes.begin(), E = TURes.end(); I != E; ++I) { ....
+/// @endcode
+template <typename handler_type>
+class Storing : public handler_type {
+  typedef typename handler_type::receiving_type receiving_type;
+  typedef llvm::SmallVector<receiving_type, 8> StoreTy;
+  StoreTy Store;
+
+public:
+  virtual void Handle(receiving_type Obj) {
+    Store.push_back(Obj);
+  }
+
+  typedef typename StoreTy::const_iterator iterator;
+  iterator begin() const { return Store.begin(); }
+  iterator end() const { return Store.end(); }
+};
+
+} // namespace idx
+
+} // namespace clang
+
+#endif
diff --git a/include/clang/Index/IndexProvider.h b/include/clang/Index/IndexProvider.h
new file mode 100644
index 0000000..187dd93
--- /dev/null
+++ b/include/clang/Index/IndexProvider.h
@@ -0,0 +1,38 @@
+//===--- IndexProvider.h - Maps information to translation units -*- C++ -*-==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  Maps information to TranslationUnits.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_INDEX_INDEXPROVIDER_H
+#define LLVM_CLANG_INDEX_INDEXPROVIDER_H
+
+namespace clang {
+
+namespace idx {
+  class Entity;
+  class TranslationUnitHandler;
+  class GlobalSelector;
+
+/// \brief Maps information to TranslationUnits.
+class IndexProvider {
+public:
+  virtual ~IndexProvider();
+  virtual void GetTranslationUnitsFor(Entity Ent,
+                                      TranslationUnitHandler &Handler) = 0;
+  virtual void GetTranslationUnitsFor(GlobalSelector Sel,
+                                      TranslationUnitHandler &Handler) = 0;
+};
+
+} // namespace idx
+
+} // namespace clang
+
+#endif
diff --git a/include/clang/Index/Indexer.h b/include/clang/Index/Indexer.h
new file mode 100644
index 0000000..361e729
--- /dev/null
+++ b/include/clang/Index/Indexer.h
@@ -0,0 +1,64 @@
+//===--- Indexer.h - IndexProvider implementation ---------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  IndexProvider implementation.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_INDEX_INDEXER_H
+#define LLVM_CLANG_INDEX_INDEXER_H
+
+#include "clang/Index/IndexProvider.h"
+#include "clang/Index/Entity.h"
+#include "clang/Index/GlobalSelector.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/DenseMap.h"
+#include <map>
+
+namespace clang {
+  class ASTContext;
+
+namespace idx {
+  class Program;
+  class TranslationUnit;
+
+/// \brief Maps information to TranslationUnits.
+class Indexer : public IndexProvider {
+public:
+  typedef llvm::SmallPtrSet<TranslationUnit *, 4> TUSetTy;
+  typedef llvm::DenseMap<ASTContext *, TranslationUnit *> CtxTUMapTy;
+  typedef std::map<Entity, TUSetTy> MapTy;
+  typedef std::map<GlobalSelector, TUSetTy> SelMapTy;
+
+  explicit Indexer(Program &prog) :
+    Prog(prog) { }
+
+  Program &getProgram() const { return Prog; }
+
+  /// \brief Find all Entities and map them to the given translation unit.
+  void IndexAST(TranslationUnit *TU);
+
+  virtual void GetTranslationUnitsFor(Entity Ent,
+                                      TranslationUnitHandler &Handler);
+  virtual void GetTranslationUnitsFor(GlobalSelector Sel,
+                                      TranslationUnitHandler &Handler);
+
+private:
+  Program &Prog;
+
+  MapTy Map;
+  CtxTUMapTy CtxTUMap;
+  SelMapTy SelMap;
+};
+
+} // namespace idx
+
+} // namespace clang
+
+#endif
diff --git a/include/clang/Index/Program.h b/include/clang/Index/Program.h
new file mode 100644
index 0000000..8039192
--- /dev/null
+++ b/include/clang/Index/Program.h
@@ -0,0 +1,45 @@
+//===--- Program.h - Cross-translation unit information ---------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the idx::Program interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_INDEX_PROGRAM_H
+#define LLVM_CLANG_INDEX_PROGRAM_H
+
+namespace clang {
+  class ASTContext;
+
+namespace idx {
+  class EntityHandler;
+
+/// \brief Top level object that owns and maintains information
+/// that is common across translation units.
+class Program {
+  void *Impl;
+
+  Program(const Program&); // do not implement
+  Program &operator=(const Program &); // do not implement
+  friend class Entity;
+  friend class GlobalSelector;
+
+public:
+  Program();
+  ~Program();
+
+  /// \brief Traverses the AST and passes all the entities to the Handler.
+  void FindEntities(ASTContext &Ctx, EntityHandler &Handler);
+};
+
+} // namespace idx
+
+} // namespace clang
+
+#endif
diff --git a/include/clang/Index/STLExtras.h b/include/clang/Index/STLExtras.h
new file mode 100644
index 0000000..a3693c6
--- /dev/null
+++ b/include/clang/Index/STLExtras.h
@@ -0,0 +1,63 @@
+//===--- STLExtras.h - Helper STL related templates -------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  Helper templates for using with the STL.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_INDEX_STLEXTRAS_H
+#define LLVM_CLANG_INDEX_STLEXTRAS_H
+
+namespace clang {
+
+namespace idx {
+
+/// \brief Wraps an iterator whose value_type is a pair, and provides
+/// pair's second object as the value.
+template <typename iter_type>
+class pair_value_iterator {
+  iter_type I;
+
+public:
+  typedef typename iter_type::value_type::second_type value_type;
+  typedef value_type& reference;
+  typedef value_type* pointer;
+  typedef typename iter_type::iterator_category iterator_category;
+  typedef typename iter_type::difference_type   difference_type;
+
+  pair_value_iterator() { }
+  pair_value_iterator(iter_type i) : I(i) { }
+
+  reference operator*() const { return I->second; }
+  pointer operator->() const { return &I->second; }
+
+  pair_value_iterator& operator++() {
+    ++I;
+    return *this;
+  }
+
+  pair_value_iterator operator++(int) {
+    pair_value_iterator tmp(*this);
+    ++(*this);
+    return tmp;
+  }
+
+  friend bool operator==(pair_value_iterator L, pair_value_iterator R) {
+    return L.I == R.I;
+  }
+  friend bool operator!=(pair_value_iterator L, pair_value_iterator R) {
+    return L.I != R.I;
+  }
+};
+
+} // end idx namespace
+
+} // end clang namespace
+
+#endif
diff --git a/include/clang/Index/SelectorMap.h b/include/clang/Index/SelectorMap.h
new file mode 100644
index 0000000..be01702
--- /dev/null
+++ b/include/clang/Index/SelectorMap.h
@@ -0,0 +1,57 @@
+//===--- SelectorMap.h - Maps selectors to methods and messages -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  SelectorMap creates a mapping from selectors to ObjC method declarations
+//  and ObjC message expressions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_INDEX_SELECTORMAP_H
+#define LLVM_CLANG_INDEX_SELECTORMAP_H
+
+#include "clang/Index/ASTLocation.h"
+#include "clang/Index/STLExtras.h"
+#include "clang/Basic/IdentifierTable.h"
+#include <map>
+
+namespace clang {
+  class ASTContext;
+  class ObjCMethodDecl;
+
+namespace idx {
+
+/// \brief Maps NamedDecls with the ASTLocations that reference them.
+///
+/// References are mapped and retrieved using the canonical decls.
+class SelectorMap {
+public:
+  explicit SelectorMap(ASTContext &Ctx);
+
+  typedef std::multimap<Selector, ObjCMethodDecl *> SelMethMapTy;
+  typedef std::multimap<Selector, ASTLocation> SelRefMapTy;
+
+  typedef pair_value_iterator<SelMethMapTy::iterator> method_iterator;
+  typedef pair_value_iterator<SelRefMapTy::iterator> astlocation_iterator;
+
+  method_iterator methods_begin(Selector Sel) const;
+  method_iterator methods_end(Selector Sel) const;
+
+  astlocation_iterator refs_begin(Selector Sel) const;
+  astlocation_iterator refs_end(Selector Sel) const;
+
+private:
+  mutable SelMethMapTy SelMethMap;
+  mutable SelRefMapTy SelRefMap;
+};
+
+} // end idx namespace
+
+} // end clang namespace
+
+#endif
diff --git a/include/clang/Index/TranslationUnit.h b/include/clang/Index/TranslationUnit.h
new file mode 100644
index 0000000..bf9e78f
--- /dev/null
+++ b/include/clang/Index/TranslationUnit.h
@@ -0,0 +1,37 @@
+//===--- TranslationUnit.h - Interface for a translation unit ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  Abstract interface for a translation unit.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_INDEX_TRANSLATIONUNIT_H
+#define LLVM_CLANG_INDEX_TRANSLATIONUNIT_H
+
+namespace clang {
+  class ASTContext;
+
+namespace idx {
+  class DeclReferenceMap;
+  class SelectorMap;
+
+/// \brief Abstract interface for a translation unit.
+class TranslationUnit {
+public:
+  virtual ~TranslationUnit();
+  virtual ASTContext &getASTContext() = 0;
+  virtual DeclReferenceMap &getDeclReferenceMap() = 0;
+  virtual SelectorMap &getSelectorMap() = 0;
+};
+
+} // namespace idx
+
+} // namespace clang
+
+#endif
diff --git a/include/clang/Index/Utils.h b/include/clang/Index/Utils.h
new file mode 100644
index 0000000..f8e01f7
--- /dev/null
+++ b/include/clang/Index/Utils.h
@@ -0,0 +1,36 @@
+//===--- Utils.h - Misc utilities for indexing-----------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This header contains miscellaneous utilities for indexing related
+//  functionality.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_INDEX_UTILS_H
+#define LLVM_CLANG_INDEX_UTILS_H
+
+namespace clang {
+  class ASTContext;
+  class SourceLocation;
+  
+namespace idx {
+  class ASTLocation;
+
+/// \brief Returns the ASTLocation that a source location points to.
+///
+/// \returns the resolved ASTLocation or an invalid ASTLocation if the source
+/// location could not be resolved.
+ASTLocation ResolveLocationInAST(ASTContext &Ctx, SourceLocation Loc, 
+                                 ASTLocation *LastLoc = 0);
+
+} // end namespace idx
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Lex/DirectoryLookup.h b/include/clang/Lex/DirectoryLookup.h
new file mode 100644
index 0000000..64687a1
--- /dev/null
+++ b/include/clang/Lex/DirectoryLookup.h
@@ -0,0 +1,134 @@
+//===--- DirectoryLookup.h - Info for searching for headers -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the DirectoryLookup interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LEX_DIRECTORYLOOKUP_H
+#define LLVM_CLANG_LEX_DIRECTORYLOOKUP_H
+
+#include "clang/Basic/SourceManager.h"
+
+namespace llvm {
+  class StringRef;
+}
+namespace clang {
+class HeaderMap;
+class DirectoryEntry;
+class FileEntry;
+class HeaderSearch;
+
+/// DirectoryLookup - This class represents one entry in the search list that
+/// specifies the search order for directories in #include directives.  It
+/// represents either a directory, a framework, or a headermap.
+///
+class DirectoryLookup {
+public:
+  enum LookupType_t {
+    LT_NormalDir,
+    LT_Framework,
+    LT_HeaderMap
+  };
+private:
+  union {  // This union is discriminated by isHeaderMap.
+    /// Dir - This is the actual directory that we're referring to for a normal
+    /// directory or a framework.
+    const DirectoryEntry *Dir;
+
+    /// Map - This is the HeaderMap if this is a headermap lookup.
+    ///
+    const HeaderMap *Map;
+  } u;
+
+  /// DirCharacteristic - The type of directory this is: this is an instance of
+  /// SrcMgr::CharacteristicKind.
+  unsigned DirCharacteristic : 2;
+
+  /// UserSupplied - True if this is a user-supplied directory.
+  ///
+  bool UserSupplied : 1;
+
+  /// LookupType - This indicates whether this DirectoryLookup object is a
+  /// normal directory, a framework, or a headermap.
+  unsigned LookupType : 2;
+public:
+  /// DirectoryLookup ctor - Note that this ctor *does not take ownership* of
+  /// 'dir'.
+  DirectoryLookup(const DirectoryEntry *dir, SrcMgr::CharacteristicKind DT,
+                  bool isUser, bool isFramework)
+    : DirCharacteristic(DT), UserSupplied(isUser),
+     LookupType(isFramework ? LT_Framework : LT_NormalDir) {
+    u.Dir = dir;
+  }
+
+  /// DirectoryLookup ctor - Note that this ctor *does not take ownership* of
+  /// 'map'.
+  DirectoryLookup(const HeaderMap *map, SrcMgr::CharacteristicKind DT,
+                  bool isUser)
+    : DirCharacteristic(DT), UserSupplied(isUser), LookupType(LT_HeaderMap) {
+    u.Map = map;
+  }
+
+  /// getLookupType - Return the kind of directory lookup that this is: either a
+  /// normal directory, a framework path, or a HeaderMap.
+  LookupType_t getLookupType() const { return (LookupType_t)LookupType; }
+
+  /// getName - Return the directory or filename corresponding to this lookup
+  /// object.
+  const char *getName() const;
+
+  /// getDir - Return the directory that this entry refers to.
+  ///
+  const DirectoryEntry *getDir() const { return isNormalDir() ? u.Dir : 0; }
+
+  /// getFrameworkDir - Return the directory that this framework refers to.
+  ///
+  const DirectoryEntry *getFrameworkDir() const {
+    return isFramework() ? u.Dir : 0;
+  }
+
+  /// getHeaderMap - Return the directory that this entry refers to.
+  ///
+  const HeaderMap *getHeaderMap() const { return isHeaderMap() ? u.Map : 0; }
+
+  /// isNormalDir - Return true if this is a normal directory, not a header map.
+  bool isNormalDir() const { return getLookupType() == LT_NormalDir; }
+
+  /// isFramework - True if this is a framework directory.
+  ///
+  bool isFramework() const { return getLookupType() == LT_Framework; }
+
+  /// isHeaderMap - Return true if this is a header map, not a normal directory.
+  bool isHeaderMap() const { return getLookupType() == LT_HeaderMap; }
+
+  /// DirCharacteristic - The type of directory this is, one of the DirType enum
+  /// values.
+  SrcMgr::CharacteristicKind getDirCharacteristic() const {
+    return (SrcMgr::CharacteristicKind)DirCharacteristic;
+  }
+
+  /// isUserSupplied - True if this is a user-supplied directory.
+  ///
+  bool isUserSupplied() const { return UserSupplied; }
+
+
+  /// LookupFile - Lookup the specified file in this search path, returning it
+  /// if it exists or returning null if not.
+  const FileEntry *LookupFile(llvm::StringRef Filename, HeaderSearch &HS) const;
+
+private:
+  const FileEntry *DoFrameworkLookup(llvm::StringRef Filename,
+                                     HeaderSearch &HS) const;
+
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Lex/ExternalPreprocessorSource.h b/include/clang/Lex/ExternalPreprocessorSource.h
new file mode 100644
index 0000000..af5c389
--- /dev/null
+++ b/include/clang/Lex/ExternalPreprocessorSource.h
@@ -0,0 +1,34 @@
+//===- ExternalPreprocessorSource.h - Abstract Macro Interface --*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the ExternalPreprocessorSource interface, which enables
+//  construction of macro definitions from some external source.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_LEX_EXTERNAL_PREPROCESSOR_SOURCE_H
+#define LLVM_CLANG_LEX_EXTERNAL_PREPROCESSOR_SOURCE_H
+
+namespace clang {
+  
+/// \brief Abstract interface for external sources of preprocessor 
+/// information.
+///
+/// This abstract class allows an external sources (such as the \c PCHReader) 
+/// to provide additional macro definitions.
+class ExternalPreprocessorSource {
+public:
+  virtual ~ExternalPreprocessorSource();
+  
+  /// \brief Read the set of macros defined by this external macro source.
+  virtual void ReadDefinedMacros() = 0;
+};
+  
+}
+
+#endif // LLVM_CLANG_LEX_EXTERNAL_PREPROCESSOR_SOURCE_H
diff --git a/include/clang/Lex/HeaderMap.h b/include/clang/Lex/HeaderMap.h
new file mode 100644
index 0000000..9837e29
--- /dev/null
+++ b/include/clang/Lex/HeaderMap.h
@@ -0,0 +1,67 @@
+//===--- HeaderMap.h - A file that acts like dir of symlinks ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the HeaderMap interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LEX_HEADERMAP_H
+#define LLVM_CLANG_LEX_HEADERMAP_H
+
+namespace llvm {
+  class MemoryBuffer;
+  class StringRef;
+}
+namespace clang {
+  class FileEntry;
+  class FileManager;
+  struct HMapBucket;
+  struct HMapHeader;
+
+/// This class represents an Apple concept known as a 'header map'.  To the
+/// #include file resolution process, it basically acts like a directory of
+/// symlinks to files.  Its advantages are that it is dense and more efficient
+/// to create and process than a directory of symlinks.
+class HeaderMap {
+  HeaderMap(const HeaderMap&); // DO NOT IMPLEMENT
+  void operator=(const HeaderMap&); // DO NOT IMPLEMENT
+
+  const llvm::MemoryBuffer *FileBuffer;
+  bool NeedsBSwap;
+
+  HeaderMap(const llvm::MemoryBuffer *File, bool BSwap)
+    : FileBuffer(File), NeedsBSwap(BSwap) {
+  }
+public:
+  ~HeaderMap();
+
+  /// HeaderMap::Create - This attempts to load the specified file as a header
+  /// map.  If it doesn't look like a HeaderMap, it gives up and returns null.
+  static const HeaderMap *Create(const FileEntry *FE);
+
+  /// LookupFile - Check to see if the specified relative filename is located in
+  /// this HeaderMap.  If so, open it and return its FileEntry.
+  const FileEntry *LookupFile(llvm::StringRef Filename, FileManager &FM) const;
+
+  /// getFileName - Return the filename of the headermap.
+  const char *getFileName() const;
+
+  /// dump - Print the contents of this headermap to stderr.
+  void dump() const;
+
+private:
+  unsigned getEndianAdjustedWord(unsigned X) const;
+  const HMapHeader &getHeader() const;
+  HMapBucket getBucket(unsigned BucketNo) const;
+  const char *getString(unsigned StrTabIdx) const;
+};
+
+} // end namespace clang.
+
+#endif
diff --git a/include/clang/Lex/HeaderSearch.h b/include/clang/Lex/HeaderSearch.h
new file mode 100644
index 0000000..978585c
--- /dev/null
+++ b/include/clang/Lex/HeaderSearch.h
@@ -0,0 +1,235 @@
+//===--- HeaderSearch.h - Resolve Header File Locations ---------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the HeaderSearch interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LEX_HEADERSEARCH_H
+#define LLVM_CLANG_LEX_HEADERSEARCH_H
+
+#include "clang/Lex/DirectoryLookup.h"
+#include "llvm/ADT/StringMap.h"
+#include <vector>
+
+namespace clang {
+
+class ExternalIdentifierLookup;
+class FileEntry;
+class FileManager;
+class IdentifierInfo;
+
+/// HeaderFileInfo - The preprocessor keeps track of this information for each
+/// file that is #included.
+struct HeaderFileInfo {
+  /// isImport - True if this is a #import'd or #pragma once file.
+  bool isImport : 1;
+
+  /// DirInfo - Keep track of whether this is a system header, and if so,
+  /// whether it is C++ clean or not.  This can be set by the include paths or
+  /// by #pragma gcc system_header.  This is an instance of
+  /// SrcMgr::CharacteristicKind.
+  unsigned DirInfo : 2;
+
+  /// NumIncludes - This is the number of times the file has been included
+  /// already.
+  unsigned short NumIncludes;
+
+  /// ControllingMacro - If this file has a #ifndef XXX (or equivalent) guard
+  /// that protects the entire contents of the file, this is the identifier
+  /// for the macro that controls whether or not it has any effect.
+  ///
+  /// Note: Most clients should use getControllingMacro() to access
+  /// the controlling macro of this header, since
+  /// getControllingMacro() is able to load a controlling macro from
+  /// external storage.
+  const IdentifierInfo *ControllingMacro;
+
+  /// \brief The ID number of the controlling macro.
+  ///
+  /// This ID number will be non-zero when there is a controlling
+  /// macro whose IdentifierInfo may not yet have been loaded from
+  /// external storage.
+  unsigned ControllingMacroID;
+
+  HeaderFileInfo()
+    : isImport(false), DirInfo(SrcMgr::C_User),
+      NumIncludes(0), ControllingMacro(0), ControllingMacroID(0) {}
+
+  /// \brief Retrieve the controlling macro for this header file, if
+  /// any.
+  const IdentifierInfo *getControllingMacro(ExternalIdentifierLookup *External);
+};
+
+/// HeaderSearch - This class encapsulates the information needed to find the
+/// file referenced by a #include or #include_next, (sub-)framework lookup, etc.
+class HeaderSearch {
+  FileManager &FileMgr;
+
+  /// #include search path information.  Requests for #include "x" search the
+  /// directory of the #including file first, then each directory in SearchDirs
+  /// consequtively. Requests for <x> search the current dir first, then each
+  /// directory in SearchDirs, starting at SystemDirIdx, consequtively.  If
+  /// NoCurDirSearch is true, then the check for the file in the current
+  /// directory is supressed.
+  std::vector<DirectoryLookup> SearchDirs;
+  unsigned SystemDirIdx;
+  bool NoCurDirSearch;
+
+  /// FileInfo - This contains all of the preprocessor-specific data about files
+  /// that are included.  The vector is indexed by the FileEntry's UID.
+  ///
+  std::vector<HeaderFileInfo> FileInfo;
+
+  /// LookupFileCache - This is keeps track of each lookup performed by
+  /// LookupFile.  The first part of the value is the starting index in
+  /// SearchDirs that the cached search was performed from.  If there is a hit
+  /// and this value doesn't match the current query, the cache has to be
+  /// ignored.  The second value is the entry in SearchDirs that satisfied the
+  /// query.
+  llvm::StringMap<std::pair<unsigned, unsigned> > LookupFileCache;
+
+
+  /// FrameworkMap - This is a collection mapping a framework or subframework
+  /// name like "Carbon" to the Carbon.framework directory.
+  llvm::StringMap<const DirectoryEntry *> FrameworkMap;
+
+  /// HeaderMaps - This is a mapping from FileEntry -> HeaderMap, uniquing
+  /// headermaps.  This vector owns the headermap.
+  std::vector<std::pair<const FileEntry*, const HeaderMap*> > HeaderMaps;
+
+  /// \brief Entity used to resolve the identifier IDs of controlling
+  /// macros into IdentifierInfo pointers, as needed.
+  ExternalIdentifierLookup *ExternalLookup;
+
+  // Various statistics we track for performance analysis.
+  unsigned NumIncluded;
+  unsigned NumMultiIncludeFileOptzn;
+  unsigned NumFrameworkLookups, NumSubFrameworkLookups;
+
+  // HeaderSearch doesn't support default or copy construction.
+  explicit HeaderSearch();
+  explicit HeaderSearch(const HeaderSearch&);
+  void operator=(const HeaderSearch&);
+public:
+  HeaderSearch(FileManager &FM);
+  ~HeaderSearch();
+
+  FileManager &getFileMgr() const { return FileMgr; }
+
+  /// SetSearchPaths - Interface for setting the file search paths.
+  ///
+  void SetSearchPaths(const std::vector<DirectoryLookup> &dirs,
+                      unsigned systemDirIdx, bool noCurDirSearch) {
+    SearchDirs = dirs;
+    SystemDirIdx = systemDirIdx;
+    NoCurDirSearch = noCurDirSearch;
+    //LookupFileCache.clear();
+  }
+
+  /// ClearFileInfo - Forget everything we know about headers so far.
+  void ClearFileInfo() {
+    FileInfo.clear();
+  }
+
+  void SetExternalLookup(ExternalIdentifierLookup *EIL) {
+    ExternalLookup = EIL;
+  }
+
+  /// LookupFile - Given a "foo" or <foo> reference, look up the indicated file,
+  /// return null on failure.  isAngled indicates whether the file reference is
+  /// a <> reference.  If successful, this returns 'UsedDir', the
+  /// DirectoryLookup member the file was found in, or null if not applicable.
+  /// If CurDir is non-null, the file was found in the specified directory
+  /// search location.  This is used to implement #include_next.  CurFileEnt, if
+  /// non-null, indicates where the #including file is, in case a relative
+  /// search is needed.
+  const FileEntry *LookupFile(llvm::StringRef Filename, bool isAngled,
+                              const DirectoryLookup *FromDir,
+                              const DirectoryLookup *&CurDir,
+                              const FileEntry *CurFileEnt);
+
+  /// LookupSubframeworkHeader - Look up a subframework for the specified
+  /// #include file.  For example, if #include'ing <HIToolbox/HIToolbox.h> from
+  /// within ".../Carbon.framework/Headers/Carbon.h", check to see if HIToolbox
+  /// is a subframework within Carbon.framework.  If so, return the FileEntry
+  /// for the designated file, otherwise return null.
+  const FileEntry *LookupSubframeworkHeader(llvm::StringRef Filename,
+                                            const FileEntry *RelativeFileEnt);
+
+  /// LookupFrameworkCache - Look up the specified framework name in our
+  /// framework cache, returning the DirectoryEntry it is in if we know,
+  /// otherwise, return null.
+  const DirectoryEntry *&LookupFrameworkCache(llvm::StringRef FWName) {
+    return FrameworkMap.GetOrCreateValue(FWName).getValue();
+  }
+
+  /// ShouldEnterIncludeFile - Mark the specified file as a target of of a
+  /// #include, #include_next, or #import directive.  Return false if #including
+  /// the file will have no effect or true if we should include it.
+  bool ShouldEnterIncludeFile(const FileEntry *File, bool isImport);
+
+
+  /// getFileDirFlavor - Return whether the specified file is a normal header,
+  /// a system header, or a C++ friendly system header.
+  SrcMgr::CharacteristicKind getFileDirFlavor(const FileEntry *File) {
+    return (SrcMgr::CharacteristicKind)getFileInfo(File).DirInfo;
+  }
+
+  /// MarkFileIncludeOnce - Mark the specified file as a "once only" file, e.g.
+  /// due to #pragma once.
+  void MarkFileIncludeOnce(const FileEntry *File) {
+    getFileInfo(File).isImport = true;
+  }
+
+  /// MarkFileSystemHeader - Mark the specified file as a system header, e.g.
+  /// due to #pragma GCC system_header.
+  void MarkFileSystemHeader(const FileEntry *File) {
+    getFileInfo(File).DirInfo = SrcMgr::C_System;
+  }
+
+  /// IncrementIncludeCount - Increment the count for the number of times the
+  /// specified FileEntry has been entered.
+  void IncrementIncludeCount(const FileEntry *File) {
+    ++getFileInfo(File).NumIncludes;
+  }
+
+  /// SetFileControllingMacro - Mark the specified file as having a controlling
+  /// macro.  This is used by the multiple-include optimization to eliminate
+  /// no-op #includes.
+  void SetFileControllingMacro(const FileEntry *File,
+                               const IdentifierInfo *ControllingMacro) {
+    getFileInfo(File).ControllingMacro = ControllingMacro;
+  }
+
+  /// CreateHeaderMap - This method returns a HeaderMap for the specified
+  /// FileEntry, uniquing them through the the 'HeaderMaps' datastructure.
+  const HeaderMap *CreateHeaderMap(const FileEntry *FE);
+
+  void IncrementFrameworkLookupCount() { ++NumFrameworkLookups; }
+
+  typedef std::vector<HeaderFileInfo>::const_iterator header_file_iterator;
+  header_file_iterator header_file_begin() const { return FileInfo.begin(); }
+  header_file_iterator header_file_end() const { return FileInfo.end(); }
+  unsigned header_file_size() const { return FileInfo.size(); }
+
+  // Used by PCHReader.
+  void setHeaderFileInfoForUID(HeaderFileInfo HFI, unsigned UID);
+
+  void PrintStats();
+private:
+
+  /// getFileInfo - Return the HeaderFileInfo structure for the specified
+  /// FileEntry.
+  HeaderFileInfo &getFileInfo(const FileEntry *FE);
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Lex/LexDiagnostic.h b/include/clang/Lex/LexDiagnostic.h
new file mode 100644
index 0000000..a470aa0
--- /dev/null
+++ b/include/clang/Lex/LexDiagnostic.h
@@ -0,0 +1,27 @@
+//===--- DiagnosticLex.h - Diagnostics for liblex ---------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_DIAGNOSTICLEX_H
+#define LLVM_CLANG_DIAGNOSTICLEX_H
+
+#include "clang/Basic/Diagnostic.h"
+
+namespace clang {
+  namespace diag {
+    enum {
+#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE) ENUM,
+#define LEXSTART
+#include "clang/Basic/DiagnosticLexKinds.inc"
+#undef DIAG
+      NUM_BUILTIN_LEX_DIAGNOSTICS
+    };
+  }  // end namespace diag
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Lex/Lexer.h b/include/clang/Lex/Lexer.h
new file mode 100644
index 0000000..6a6e319
--- /dev/null
+++ b/include/clang/Lex/Lexer.h
@@ -0,0 +1,384 @@
+//===--- Lexer.h - C Language Family Lexer ----------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the Lexer interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LEXER_H
+#define LLVM_CLANG_LEXER_H
+
+#include "clang/Lex/PreprocessorLexer.h"
+#include "clang/Basic/LangOptions.h"
+#include "llvm/ADT/SmallVector.h"
+#include <string>
+#include <vector>
+#include <cassert>
+
+namespace clang {
+class Diagnostic;
+class SourceManager;
+class Preprocessor;
+class DiagnosticBuilder;
+
+/// Lexer - This provides a simple interface that turns a text buffer into a
+/// stream of tokens.  This provides no support for file reading or buffering,
+/// or buffering/seeking of tokens, only forward lexing is supported.  It relies
+/// on the specified Preprocessor object to handle preprocessor directives, etc.
+class Lexer : public PreprocessorLexer {
+  //===--------------------------------------------------------------------===//
+  // Constant configuration values for this lexer.
+  const char *BufferStart;       // Start of the buffer.
+  const char *BufferEnd;         // End of the buffer.
+  SourceLocation FileLoc;        // Location for start of file.
+  LangOptions Features;          // Features enabled by this language (cache).
+  bool Is_PragmaLexer : 1;       // True if lexer for _Pragma handling.
+  bool IsInConflictMarker : 1;   // True if in a VCS conflict marker '<<<<<<<'
+  
+  //===--------------------------------------------------------------------===//
+  // Context-specific lexing flags set by the preprocessor.
+  //
+
+  /// ExtendedTokenMode - The lexer can optionally keep comments and whitespace
+  /// and return them as tokens.  This is used for -C and -CC modes, and
+  /// whitespace preservation can be useful for some clients that want to lex
+  /// the file in raw mode and get every character from the file.
+  ///
+  /// When this is set to 2 it returns comments and whitespace.  When set to 1
+  /// it returns comments, when it is set to 0 it returns normal tokens only.
+  unsigned char ExtendedTokenMode;
+
+  //===--------------------------------------------------------------------===//
+  // Context that changes as the file is lexed.
+  // NOTE: any state that mutates when in raw mode must have save/restore code
+  // in Lexer::isNextPPTokenLParen.
+
+  // BufferPtr - Current pointer into the buffer.  This is the next character
+  // to be lexed.
+  const char *BufferPtr;
+
+  // IsAtStartOfLine - True if the next lexed token should get the "start of
+  // line" flag set on it.
+  bool IsAtStartOfLine;
+
+  Lexer(const Lexer&);          // DO NOT IMPLEMENT
+  void operator=(const Lexer&); // DO NOT IMPLEMENT
+  friend class Preprocessor;
+
+  void InitLexer(const char *BufStart, const char *BufPtr, const char *BufEnd);
+public:
+
+  /// Lexer constructor - Create a new lexer object for the specified buffer
+  /// with the specified preprocessor managing the lexing process.  This lexer
+  /// assumes that the associated file buffer and Preprocessor objects will
+  /// outlive it, so it doesn't take ownership of either of them.
+  Lexer(FileID FID, const llvm::MemoryBuffer *InputBuffer, Preprocessor &PP);
+
+  /// Lexer constructor - Create a new raw lexer object.  This object is only
+  /// suitable for calls to 'LexRawToken'.  This lexer assumes that the text
+  /// range will outlive it, so it doesn't take ownership of it.
+  Lexer(SourceLocation FileLoc, const LangOptions &Features,
+        const char *BufStart, const char *BufPtr, const char *BufEnd);
+
+  /// Lexer constructor - Create a new raw lexer object.  This object is only
+  /// suitable for calls to 'LexRawToken'.  This lexer assumes that the text
+  /// range will outlive it, so it doesn't take ownership of it.
+  Lexer(FileID FID, const llvm::MemoryBuffer *InputBuffer,
+        const SourceManager &SM, const LangOptions &Features);
+
+  /// Create_PragmaLexer: Lexer constructor - Create a new lexer object for
+  /// _Pragma expansion.  This has a variety of magic semantics that this method
+  /// sets up.  It returns a new'd Lexer that must be delete'd when done.
+  static Lexer *Create_PragmaLexer(SourceLocation SpellingLoc,
+                                   SourceLocation InstantiationLocStart,
+                                   SourceLocation InstantiationLocEnd,
+                                   unsigned TokLen, Preprocessor &PP);
+
+
+  /// getFeatures - Return the language features currently enabled.  NOTE: this
+  /// lexer modifies features as a file is parsed!
+  const LangOptions &getFeatures() const { return Features; }
+
+  /// getFileLoc - Return the File Location for the file we are lexing out of.
+  /// The physical location encodes the location where the characters come from,
+  /// the virtual location encodes where we should *claim* the characters came
+  /// from.  Currently this is only used by _Pragma handling.
+  SourceLocation getFileLoc() const { return FileLoc; }
+
+  /// Lex - Return the next token in the file.  If this is the end of file, it
+  /// return the tok::eof token.  Return true if an error occurred and
+  /// compilation should terminate, false if normal.  This implicitly involves
+  /// the preprocessor.
+  void Lex(Token &Result) {
+    // Start a new token.
+    Result.startToken();
+
+    // NOTE, any changes here should also change code after calls to
+    // Preprocessor::HandleDirective
+    if (IsAtStartOfLine) {
+      Result.setFlag(Token::StartOfLine);
+      IsAtStartOfLine = false;
+    }
+
+    // Get a token.  Note that this may delete the current lexer if the end of
+    // file is reached.
+    LexTokenInternal(Result);
+  }
+
+  /// isPragmaLexer - Returns true if this Lexer is being used to lex a pragma.
+  bool isPragmaLexer() const { return Is_PragmaLexer; }
+
+  /// IndirectLex - An indirect call to 'Lex' that can be invoked via
+  ///  the PreprocessorLexer interface.
+  void IndirectLex(Token &Result) { Lex(Result); }
+
+  /// LexFromRawLexer - Lex a token from a designated raw lexer (one with no
+  /// associated preprocessor object.  Return true if the 'next character to
+  /// read' pointer points at the end of the lexer buffer, false otherwise.
+  bool LexFromRawLexer(Token &Result) {
+    assert(LexingRawMode && "Not already in raw mode!");
+    Lex(Result);
+    // Note that lexing to the end of the buffer doesn't implicitly delete the
+    // lexer when in raw mode.
+    return BufferPtr == BufferEnd;
+  }
+
+  /// isKeepWhitespaceMode - Return true if the lexer should return tokens for
+  /// every character in the file, including whitespace and comments.  This
+  /// should only be used in raw mode, as the preprocessor is not prepared to
+  /// deal with the excess tokens.
+  bool isKeepWhitespaceMode() const {
+    return ExtendedTokenMode > 1;
+  }
+
+  /// SetKeepWhitespaceMode - This method lets clients enable or disable
+  /// whitespace retention mode.
+  void SetKeepWhitespaceMode(bool Val) {
+    assert((!Val || LexingRawMode) &&
+           "Can only enable whitespace retention in raw mode");
+    ExtendedTokenMode = Val ? 2 : 0;
+  }
+
+  /// inKeepCommentMode - Return true if the lexer should return comments as
+  /// tokens.
+  bool inKeepCommentMode() const {
+    return ExtendedTokenMode > 0;
+  }
+
+  /// SetCommentRetentionMode - Change the comment retention mode of the lexer
+  /// to the specified mode.  This is really only useful when lexing in raw
+  /// mode, because otherwise the lexer needs to manage this.
+  void SetCommentRetentionState(bool Mode) {
+    assert(!isKeepWhitespaceMode() &&
+           "Can't play with comment retention state when retaining whitespace");
+    ExtendedTokenMode = Mode ? 1 : 0;
+  }
+
+  const char *getBufferStart() const { return BufferStart; }
+
+  /// ReadToEndOfLine - Read the rest of the current preprocessor line as an
+  /// uninterpreted string.  This switches the lexer out of directive mode.
+  std::string ReadToEndOfLine();
+
+
+  /// Diag - Forwarding function for diagnostics.  This translate a source
+  /// position in the current buffer into a SourceLocation object for rendering.
+  DiagnosticBuilder Diag(const char *Loc, unsigned DiagID) const;
+
+  /// getSourceLocation - Return a source location identifier for the specified
+  /// offset in the current file.
+  SourceLocation getSourceLocation(const char *Loc, unsigned TokLen = 1) const;
+
+  /// getSourceLocation - Return a source location for the next character in
+  /// the current file.
+  SourceLocation getSourceLocation() { return getSourceLocation(BufferPtr); }
+
+  /// \brief Return the current location in the buffer.
+  const char *getBufferLocation() const { return BufferPtr; }
+  
+  /// Stringify - Convert the specified string into a C string by escaping '\'
+  /// and " characters.  This does not add surrounding ""'s to the string.
+  /// If Charify is true, this escapes the ' character instead of ".
+  static std::string Stringify(const std::string &Str, bool Charify = false);
+
+  /// Stringify - Convert the specified string into a C string by escaping '\'
+  /// and " characters.  This does not add surrounding ""'s to the string.
+  static void Stringify(llvm::SmallVectorImpl<char> &Str);
+
+  /// MeasureTokenLength - Relex the token at the specified location and return
+  /// its length in bytes in the input file.  If the token needs cleaning (e.g.
+  /// includes a trigraph or an escaped newline) then this count includes bytes
+  /// that are part of that.
+  static unsigned MeasureTokenLength(SourceLocation Loc,
+                                     const SourceManager &SM,
+                                     const LangOptions &LangOpts);
+
+  //===--------------------------------------------------------------------===//
+  // Internal implementation interfaces.
+private:
+
+  /// LexTokenInternal - Internal interface to lex a preprocessing token. Called
+  /// by Lex.
+  ///
+  void LexTokenInternal(Token &Result);
+
+  /// FormTokenWithChars - When we lex a token, we have identified a span
+  /// starting at BufferPtr, going to TokEnd that forms the token.  This method
+  /// takes that range and assigns it to the token as its location and size.  In
+  /// addition, since tokens cannot overlap, this also updates BufferPtr to be
+  /// TokEnd.
+  void FormTokenWithChars(Token &Result, const char *TokEnd,
+                          tok::TokenKind Kind) {
+    unsigned TokLen = TokEnd-BufferPtr;
+    Result.setLength(TokLen);
+    Result.setLocation(getSourceLocation(BufferPtr, TokLen));
+    Result.setKind(Kind);
+    BufferPtr = TokEnd;
+  }
+
+  /// isNextPPTokenLParen - Return 1 if the next unexpanded token will return a
+  /// tok::l_paren token, 0 if it is something else and 2 if there are no more
+  /// tokens in the buffer controlled by this lexer.
+  unsigned isNextPPTokenLParen();
+
+  //===--------------------------------------------------------------------===//
+  // Lexer character reading interfaces.
+public:
+
+  // This lexer is built on two interfaces for reading characters, both of which
+  // automatically provide phase 1/2 translation.  getAndAdvanceChar is used
+  // when we know that we will be reading a character from the input buffer and
+  // that this character will be part of the result token. This occurs in (f.e.)
+  // string processing, because we know we need to read until we find the
+  // closing '"' character.
+  //
+  // The second interface is the combination of getCharAndSize with
+  // ConsumeChar.  getCharAndSize reads a phase 1/2 translated character,
+  // returning it and its size.  If the lexer decides that this character is
+  // part of the current token, it calls ConsumeChar on it.  This two stage
+  // approach allows us to emit diagnostics for characters (e.g. warnings about
+  // trigraphs), knowing that they only are emitted if the character is
+  // consumed.
+
+  /// isObviouslySimpleCharacter - Return true if the specified character is
+  /// obviously the same in translation phase 1 and translation phase 3.  This
+  /// can return false for characters that end up being the same, but it will
+  /// never return true for something that needs to be mapped.
+  static bool isObviouslySimpleCharacter(char C) {
+    return C != '?' && C != '\\';
+  }
+
+  /// getAndAdvanceChar - Read a single 'character' from the specified buffer,
+  /// advance over it, and return it.  This is tricky in several cases.  Here we
+  /// just handle the trivial case and fall-back to the non-inlined
+  /// getCharAndSizeSlow method to handle the hard case.
+  inline char getAndAdvanceChar(const char *&Ptr, Token &Tok) {
+    // If this is not a trigraph and not a UCN or escaped newline, return
+    // quickly.
+    if (isObviouslySimpleCharacter(Ptr[0])) return *Ptr++;
+
+    unsigned Size = 0;
+    char C = getCharAndSizeSlow(Ptr, Size, &Tok);
+    Ptr += Size;
+    return C;
+  }
+
+private:
+  /// ConsumeChar - When a character (identified by getCharAndSize) is consumed
+  /// and added to a given token, check to see if there are diagnostics that
+  /// need to be emitted or flags that need to be set on the token.  If so, do
+  /// it.
+  const char *ConsumeChar(const char *Ptr, unsigned Size, Token &Tok) {
+    // Normal case, we consumed exactly one token.  Just return it.
+    if (Size == 1)
+      return Ptr+Size;
+
+    // Otherwise, re-lex the character with a current token, allowing
+    // diagnostics to be emitted and flags to be set.
+    Size = 0;
+    getCharAndSizeSlow(Ptr, Size, &Tok);
+    return Ptr+Size;
+  }
+
+  /// getCharAndSize - Peek a single 'character' from the specified buffer,
+  /// get its size, and return it.  This is tricky in several cases.  Here we
+  /// just handle the trivial case and fall-back to the non-inlined
+  /// getCharAndSizeSlow method to handle the hard case.
+  inline char getCharAndSize(const char *Ptr, unsigned &Size) {
+    // If this is not a trigraph and not a UCN or escaped newline, return
+    // quickly.
+    if (isObviouslySimpleCharacter(Ptr[0])) {
+      Size = 1;
+      return *Ptr;
+    }
+
+    Size = 0;
+    return getCharAndSizeSlow(Ptr, Size);
+  }
+
+  /// getCharAndSizeSlow - Handle the slow/uncommon case of the getCharAndSize
+  /// method.
+  char getCharAndSizeSlow(const char *Ptr, unsigned &Size, Token *Tok = 0);
+public:
+
+  /// getCharAndSizeNoWarn - Like the getCharAndSize method, but does not ever
+  /// emit a warning.
+  static inline char getCharAndSizeNoWarn(const char *Ptr, unsigned &Size,
+                                          const LangOptions &Features) {
+    // If this is not a trigraph and not a UCN or escaped newline, return
+    // quickly.
+    if (isObviouslySimpleCharacter(Ptr[0])) {
+      Size = 1;
+      return *Ptr;
+    }
+
+    Size = 0;
+    return getCharAndSizeSlowNoWarn(Ptr, Size, Features);
+  }
+
+  /// getEscapedNewLineSize - Return the size of the specified escaped newline,
+  /// or 0 if it is not an escaped newline. P[-1] is known to be a "\" on entry
+  /// to this function.
+  static unsigned getEscapedNewLineSize(const char *P);
+
+  /// SkipEscapedNewLines - If P points to an escaped newline (or a series of
+  /// them), skip over them and return the first non-escaped-newline found,
+  /// otherwise return P.
+  static const char *SkipEscapedNewLines(const char *P);
+private:
+
+  /// getCharAndSizeSlowNoWarn - Same as getCharAndSizeSlow, but never emits a
+  /// diagnostic.
+  static char getCharAndSizeSlowNoWarn(const char *Ptr, unsigned &Size,
+                                       const LangOptions &Features);
+
+  //===--------------------------------------------------------------------===//
+  // Other lexer functions.
+
+  // Helper functions to lex the remainder of a token of the specific type.
+  void LexIdentifier         (Token &Result, const char *CurPtr);
+  void LexNumericConstant    (Token &Result, const char *CurPtr);
+  void LexStringLiteral      (Token &Result, const char *CurPtr,bool Wide);
+  void LexAngledStringLiteral(Token &Result, const char *CurPtr);
+  void LexCharConstant       (Token &Result, const char *CurPtr);
+  bool LexEndOfFile          (Token &Result, const char *CurPtr);
+
+  bool SkipWhitespace        (Token &Result, const char *CurPtr);
+  bool SkipBCPLComment       (Token &Result, const char *CurPtr);
+  bool SkipBlockComment      (Token &Result, const char *CurPtr);
+  bool SaveBCPLComment       (Token &Result, const char *CurPtr);
+  
+  bool IsStartOfConflictMarker(const char *CurPtr);
+  bool HandleEndOfConflictMarker(const char *CurPtr);
+};
+
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Lex/LiteralSupport.h b/include/clang/Lex/LiteralSupport.h
new file mode 100644
index 0000000..2334d72
--- /dev/null
+++ b/include/clang/Lex/LiteralSupport.h
@@ -0,0 +1,172 @@
+//===--- LiteralSupport.h ---------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the NumericLiteralParser, CharLiteralParser, and
+// StringLiteralParser interfaces.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_LITERALSUPPORT_H
+#define CLANG_LITERALSUPPORT_H
+
+#include <string>
+#include "llvm/ADT/APFloat.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/System/DataTypes.h"
+
+namespace clang {
+
+class Diagnostic;
+class Preprocessor;
+class Token;
+class SourceLocation;
+class TargetInfo;
+
+/// NumericLiteralParser - This performs strict semantic analysis of the content
+/// of a ppnumber, classifying it as either integer, floating, or erroneous,
+/// determines the radix of the value and can convert it to a useful value.
+class NumericLiteralParser {
+  Preprocessor &PP; // needed for diagnostics
+
+  const char *const ThisTokBegin;
+  const char *const ThisTokEnd;
+  const char *DigitsBegin, *SuffixBegin; // markers
+  const char *s; // cursor
+
+  unsigned radix;
+
+  bool saw_exponent, saw_period;
+
+public:
+  NumericLiteralParser(const char *begin, const char *end,
+                       SourceLocation Loc, Preprocessor &PP);
+  bool hadError;
+  bool isUnsigned;
+  bool isLong;        // This is *not* set for long long.
+  bool isLongLong;
+  bool isFloat;       // 1.0f
+  bool isImaginary;   // 1.0i
+  bool isMicrosoftInteger;  // Microsoft suffix extension i8, i16, i32, or i64.
+
+  bool isIntegerLiteral() const {
+    return !saw_period && !saw_exponent;
+  }
+  bool isFloatingLiteral() const {
+    return saw_period || saw_exponent;
+  }
+  bool hasSuffix() const {
+    return SuffixBegin != ThisTokEnd;
+  }
+
+  unsigned getRadix() const { return radix; }
+
+  /// GetIntegerValue - Convert this numeric literal value to an APInt that
+  /// matches Val's input width.  If there is an overflow (i.e., if the unsigned
+  /// value read is larger than the APInt's bits will hold), set Val to the low
+  /// bits of the result and return true.  Otherwise, return false.
+  bool GetIntegerValue(llvm::APInt &Val);
+
+  /// GetFloatValue - Convert this numeric literal to a floating value, using
+  /// the specified APFloat fltSemantics (specifying float, double, etc).
+  /// The optional bool isExact (passed-by-reference) has its value
+  /// set to true if the returned APFloat can represent the number in the
+  /// literal exactly, and false otherwise.
+  llvm::APFloat::opStatus GetFloatValue(llvm::APFloat &Result);
+
+private:
+
+  void ParseNumberStartingWithZero(SourceLocation TokLoc);
+
+  /// SkipHexDigits - Read and skip over any hex digits, up to End.
+  /// Return a pointer to the first non-hex digit or End.
+  const char *SkipHexDigits(const char *ptr) {
+    while (ptr != ThisTokEnd && isxdigit(*ptr))
+      ptr++;
+    return ptr;
+  }
+
+  /// SkipOctalDigits - Read and skip over any octal digits, up to End.
+  /// Return a pointer to the first non-hex digit or End.
+  const char *SkipOctalDigits(const char *ptr) {
+    while (ptr != ThisTokEnd && ((*ptr >= '0') && (*ptr <= '7')))
+      ptr++;
+    return ptr;
+  }
+
+  /// SkipDigits - Read and skip over any digits, up to End.
+  /// Return a pointer to the first non-hex digit or End.
+  const char *SkipDigits(const char *ptr) {
+    while (ptr != ThisTokEnd && isdigit(*ptr))
+      ptr++;
+    return ptr;
+  }
+
+  /// SkipBinaryDigits - Read and skip over any binary digits, up to End.
+  /// Return a pointer to the first non-binary digit or End.
+  const char *SkipBinaryDigits(const char *ptr) {
+    while (ptr != ThisTokEnd && (*ptr == '0' || *ptr == '1'))
+      ptr++;
+    return ptr;
+  }
+
+};
+
+/// CharLiteralParser - Perform interpretation and semantic analysis of a
+/// character literal.
+class CharLiteralParser {
+  uint64_t Value;
+  bool IsWide;
+  bool IsMultiChar;
+  bool HadError;
+public:
+  CharLiteralParser(const char *begin, const char *end,
+                    SourceLocation Loc, Preprocessor &PP);
+
+  bool hadError() const { return HadError; }
+  bool isWide() const { return IsWide; }
+  bool isMultiChar() const { return IsMultiChar; }
+  uint64_t getValue() const { return Value; }
+};
+
+/// StringLiteralParser - This decodes string escape characters and performs
+/// wide string analysis and Translation Phase #6 (concatenation of string
+/// literals) (C99 5.1.1.2p1).
+class StringLiteralParser {
+  Preprocessor &PP;
+
+  unsigned MaxTokenLength;
+  unsigned SizeBound;
+  unsigned wchar_tByteWidth;
+  llvm::SmallString<512> ResultBuf;
+  char *ResultPtr; // cursor
+public:
+  StringLiteralParser(const Token *StringToks, unsigned NumStringToks,
+                      Preprocessor &PP);
+  bool hadError;
+  bool AnyWide;
+  bool Pascal;
+
+  const char *GetString() { return &ResultBuf[0]; }
+  unsigned GetStringLength() const { return ResultPtr-&ResultBuf[0]; }
+
+  unsigned GetNumStringChars() const {
+    if (AnyWide)
+      return GetStringLength() / wchar_tByteWidth;
+    return GetStringLength();
+  }
+  /// getOffsetOfStringByte - This function returns the offset of the
+  /// specified byte of the string data represented by Token.  This handles
+  /// advancing over escape sequences in the string.
+  static unsigned getOffsetOfStringByte(const Token &TheTok, unsigned ByteNo,
+                                        Preprocessor &PP);
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Lex/MacroInfo.h b/include/clang/Lex/MacroInfo.h
new file mode 100644
index 0000000..5887041
--- /dev/null
+++ b/include/clang/Lex/MacroInfo.h
@@ -0,0 +1,218 @@
+//===--- MacroInfo.h - Information about #defined identifiers ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the MacroInfo interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_MACROINFO_H
+#define LLVM_CLANG_MACROINFO_H
+
+#include "clang/Lex/Token.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Allocator.h"
+#include <vector>
+#include <cassert>
+
+namespace clang {
+  class Preprocessor;
+
+/// MacroInfo - Each identifier that is #define'd has an instance of this class
+/// associated with it, used to implement macro expansion.
+class MacroInfo {
+  //===--------------------------------------------------------------------===//
+  // State set when the macro is defined.
+
+  /// Location - This is the place the macro is defined.
+  SourceLocation Location;
+  /// EndLocation - The location of the last token in the macro.
+  SourceLocation EndLocation;
+
+  /// Arguments - The list of arguments for a function-like macro.  This can be
+  /// empty, for, e.g. "#define X()".  In a C99-style variadic macro, this
+  /// includes the __VA_ARGS__ identifier on the list.
+  IdentifierInfo **ArgumentList;
+  unsigned NumArguments;
+
+  /// ReplacementTokens - This is the list of tokens that the macro is defined
+  /// to.
+  llvm::SmallVector<Token, 8> ReplacementTokens;
+
+  /// IsFunctionLike - True if this macro is a function-like macro, false if it
+  /// is an object-like macro.
+  bool IsFunctionLike : 1;
+
+  /// IsC99Varargs - True if this macro is of the form "#define X(...)" or
+  /// "#define X(Y,Z,...)".  The __VA_ARGS__ token should be replaced with the
+  /// contents of "..." in an invocation.
+  bool IsC99Varargs : 1;
+
+  /// IsGNUVarargs -  True if this macro is of the form "#define X(a...)".  The
+  /// "a" identifier in the replacement list will be replaced with all arguments
+  /// of the macro starting with the specified one.
+  bool IsGNUVarargs : 1;
+
+  /// IsBuiltinMacro - True if this is a builtin macro, such as __LINE__, and if
+  /// it has not yet been redefined or undefined.
+  bool IsBuiltinMacro : 1;
+
+private:
+  //===--------------------------------------------------------------------===//
+  // State that changes as the macro is used.
+
+  /// IsDisabled - True if we have started an expansion of this macro already.
+  /// This disbles recursive expansion, which would be quite bad for things like
+  /// #define A A.
+  bool IsDisabled : 1;
+
+  /// IsUsed - True if this macro is either defined in the main file and has
+  /// been used, or if it is not defined in the main file.  This is used to
+  /// emit -Wunused-macros diagnostics.
+  bool IsUsed : 1;
+
+  ~MacroInfo() {
+    assert(ArgumentList == 0 && "Didn't call destroy before dtor!");
+  }
+
+public:
+  MacroInfo(SourceLocation DefLoc);
+
+  /// FreeArgumentList - Free the argument list of the macro, restoring it to a
+  /// state where it can be reused for other devious purposes.
+  void FreeArgumentList(llvm::BumpPtrAllocator &PPAllocator) {
+    PPAllocator.Deallocate(ArgumentList);
+    ArgumentList = 0;
+    NumArguments = 0;
+  }
+
+  /// Destroy - destroy this MacroInfo object.
+  void Destroy(llvm::BumpPtrAllocator &PPAllocator) {
+    FreeArgumentList(PPAllocator);
+    this->~MacroInfo();
+  }
+
+  /// getDefinitionLoc - Return the location that the macro was defined at.
+  ///
+  SourceLocation getDefinitionLoc() const { return Location; }
+
+  /// setDefinitionEndLoc - Set the location of the last token in the macro.
+  ///
+  void setDefinitionEndLoc(SourceLocation EndLoc) { EndLocation = EndLoc; }
+  /// getDefinitionEndLoc - Return the location of the last token in the macro.
+  ///
+  SourceLocation getDefinitionEndLoc() const { return EndLocation; }
+
+  /// isIdenticalTo - Return true if the specified macro definition is equal to
+  /// this macro in spelling, arguments, and whitespace.  This is used to emit
+  /// duplicate definition warnings.  This implements the rules in C99 6.10.3.
+  bool isIdenticalTo(const MacroInfo &Other, Preprocessor &PP) const;
+
+  /// setIsBuiltinMacro - Set or clear the isBuiltinMacro flag.
+  ///
+  void setIsBuiltinMacro(bool Val = true) {
+    IsBuiltinMacro = Val;
+  }
+
+  /// setIsUsed - Set the value of the IsUsed flag.
+  ///
+  void setIsUsed(bool Val) {
+    IsUsed = Val;
+  }
+
+  /// setArgumentList - Set the specified list of identifiers as the argument
+  /// list for this macro.
+  void setArgumentList(IdentifierInfo* const *List, unsigned NumArgs,
+                       llvm::BumpPtrAllocator &PPAllocator) {
+    assert(ArgumentList == 0 && NumArguments == 0 &&
+           "Argument list already set!");
+    if (NumArgs == 0) return;
+
+    NumArguments = NumArgs;
+    ArgumentList = PPAllocator.Allocate<IdentifierInfo*>(NumArgs);
+    for (unsigned i = 0; i != NumArgs; ++i)
+      ArgumentList[i] = List[i];
+  }
+
+  /// Arguments - The list of arguments for a function-like macro.  This can be
+  /// empty, for, e.g. "#define X()".
+  typedef IdentifierInfo* const *arg_iterator;
+  bool arg_empty() const { return NumArguments == 0; }
+  arg_iterator arg_begin() const { return ArgumentList; }
+  arg_iterator arg_end() const { return ArgumentList+NumArguments; }
+  unsigned getNumArgs() const { return NumArguments; }
+
+  /// getArgumentNum - Return the argument number of the specified identifier,
+  /// or -1 if the identifier is not a formal argument identifier.
+  int getArgumentNum(IdentifierInfo *Arg) const {
+    for (arg_iterator I = arg_begin(), E = arg_end(); I != E; ++I)
+      if (*I == Arg) return I-arg_begin();
+    return -1;
+  }
+
+  /// Function/Object-likeness.  Keep track of whether this macro has formal
+  /// parameters.
+  void setIsFunctionLike() { IsFunctionLike = true; }
+  bool isFunctionLike() const { return IsFunctionLike; }
+  bool isObjectLike() const { return !IsFunctionLike; }
+
+  /// Varargs querying methods.  This can only be set for function-like macros.
+  void setIsC99Varargs() { IsC99Varargs = true; }
+  void setIsGNUVarargs() { IsGNUVarargs = true; }
+  bool isC99Varargs() const { return IsC99Varargs; }
+  bool isGNUVarargs() const { return IsGNUVarargs; }
+  bool isVariadic() const { return IsC99Varargs | IsGNUVarargs; }
+
+  /// isBuiltinMacro - Return true if this macro is a builtin macro, such as
+  /// __LINE__, which requires processing before expansion.
+  bool isBuiltinMacro() const { return IsBuiltinMacro; }
+
+  /// isUsed - Return false if this macro is defined in the main file and has
+  /// not yet been used.
+  bool isUsed() const { return IsUsed; }
+
+  /// getNumTokens - Return the number of tokens that this macro expands to.
+  ///
+  unsigned getNumTokens() const {
+    return ReplacementTokens.size();
+  }
+
+  const Token &getReplacementToken(unsigned Tok) const {
+    assert(Tok < ReplacementTokens.size() && "Invalid token #");
+    return ReplacementTokens[Tok];
+  }
+
+  typedef llvm::SmallVector<Token, 8>::const_iterator tokens_iterator;
+  tokens_iterator tokens_begin() const { return ReplacementTokens.begin(); }
+  tokens_iterator tokens_end() const { return ReplacementTokens.end(); }
+  bool tokens_empty() const { return ReplacementTokens.empty(); }
+
+  /// AddTokenToBody - Add the specified token to the replacement text for the
+  /// macro.
+  void AddTokenToBody(const Token &Tok) {
+    ReplacementTokens.push_back(Tok);
+  }
+
+  /// isEnabled - Return true if this macro is enabled: in other words, that we
+  /// are not currently in an expansion of this macro.
+  bool isEnabled() const { return !IsDisabled; }
+
+  void EnableMacro() {
+    assert(IsDisabled && "Cannot enable an already-enabled macro!");
+    IsDisabled = false;
+  }
+
+  void DisableMacro() {
+    assert(!IsDisabled && "Cannot disable an already-disabled macro!");
+    IsDisabled = true;
+  }
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Lex/MultipleIncludeOpt.h b/include/clang/Lex/MultipleIncludeOpt.h
new file mode 100644
index 0000000..5d5d673
--- /dev/null
+++ b/include/clang/Lex/MultipleIncludeOpt.h
@@ -0,0 +1,130 @@
+//===--- MultipleIncludeOpt.h - Header Multiple-Include Optzn ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the MultipleIncludeOpt interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_MULTIPLEINCLUDEOPT_H
+#define LLVM_CLANG_MULTIPLEINCLUDEOPT_H
+
+namespace clang {
+class IdentifierInfo;
+
+/// MultipleIncludeOpt - This class implements the simple state machine that the
+/// Lexer class uses to detect files subject to the 'multiple-include'
+/// optimization.  The public methods in this class are triggered by various
+/// events that occur when a file is lexed, and after the entire file is lexed,
+/// information about which macro (if any) controls the header is returned.
+class MultipleIncludeOpt {
+  /// ReadAnyTokens - This is set to false when a file is first opened and true
+  /// any time a token is returned to the client or a (non-multiple-include)
+  /// directive is parsed.  When the final #endif is parsed this is reset back
+  /// to false, that way any tokens before the first #ifdef or after the last
+  /// #endif can be easily detected.
+  bool ReadAnyTokens;
+
+  /// ReadAnyTokens - This is set to false when a file is first opened and true
+  /// any time a token is returned to the client or a (non-multiple-include)
+  /// directive is parsed.  When the final #endif is parsed this is reset back
+  /// to false, that way any tokens before the first #ifdef or after the last
+  /// #endif can be easily detected.
+  bool DidMacroExpansion;
+
+  /// TheMacro - The controlling macro for a file, if valid.
+  ///
+  const IdentifierInfo *TheMacro;
+public:
+  MultipleIncludeOpt() {
+    ReadAnyTokens = false;
+    DidMacroExpansion = false;
+    TheMacro = 0;
+  }
+
+  /// Invalidate - Permenantly mark this file as not being suitable for the
+  /// include-file optimization.
+  void Invalidate() {
+    // If we have read tokens but have no controlling macro, the state-machine
+    // below can never "accept".
+    ReadAnyTokens = true;
+    TheMacro = 0;
+  }
+
+  /// getHasReadAnyTokensVal - This is used for the #ifndef hande-shake at the
+  /// top of the file when reading preprocessor directives.  Otherwise, reading
+  /// the "ifndef x" would count as reading tokens.
+  bool getHasReadAnyTokensVal() const { return ReadAnyTokens; }
+
+  // If a token is read, remember that we have seen a side-effect in this file.
+  void ReadToken() { ReadAnyTokens = true; }
+
+  /// ExpandedMacro - When a macro is expanded with this lexer as the current
+  /// buffer, this method is called to disable the MIOpt if needed.
+  void ExpandedMacro() { DidMacroExpansion = true; }
+
+  /// EnterTopLevelIFNDEF - When entering a top-level #ifndef directive (or the
+  /// "#if !defined" equivalent) without any preceding tokens, this method is
+  /// called.
+  ///
+  /// Note, we don't care about the input value of 'ReadAnyTokens'.  The caller
+  /// ensures that this is only called if there are no tokens read before the
+  /// #ifndef.  The caller is required to do this, because reading the #if line
+  /// obviously reads in in tokens.
+  void EnterTopLevelIFNDEF(const IdentifierInfo *M) {
+    // If the macro is already set, this is after the top-level #endif.
+    if (TheMacro)
+      return Invalidate();
+
+    // If we have already expanded a macro by the end of the #ifndef line, then
+    // there is a macro expansion *in* the #ifndef line.  This means that the
+    // condition could evaluate differently when subsequently #included.  Reject
+    // this.
+    if (DidMacroExpansion)
+      return Invalidate();
+
+    // Remember that we're in the #if and that we have the macro.
+    ReadAnyTokens = true;
+    TheMacro = M;
+  }
+
+  /// EnterTopLevelConditional - This is invoked when a top level conditional
+  /// (except #ifndef) is found.
+  void EnterTopLevelConditional() {
+    /// If a conditional directive (except #ifndef) is found at the top level,
+    /// there is a chunk of the file not guarded by the controlling macro.
+    Invalidate();
+  }
+
+  /// ExitTopLevelConditional - This method is called when the lexer exits the
+  /// top-level conditional.
+  void ExitTopLevelConditional() {
+    // If we have a macro, that means the top of the file was ok.  Set our state
+    // back to "not having read any tokens" so we can detect anything after the
+    // #endif.
+    if (!TheMacro) return Invalidate();
+
+    // At this point, we haven't "read any tokens" but we do have a controlling
+    // macro.
+    ReadAnyTokens = false;
+  }
+
+  /// GetControllingMacroAtEndOfFile - Once the entire file has been lexed, if
+  /// there is a controlling macro, return it.
+  const IdentifierInfo *GetControllingMacroAtEndOfFile() const {
+    // If we haven't read any tokens after the #endif, return the controlling
+    // macro if it's valid (if it isn't, it will be null).
+    if (!ReadAnyTokens)
+      return TheMacro;
+    return 0;
+  }
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Lex/PPCallbacks.h b/include/clang/Lex/PPCallbacks.h
new file mode 100644
index 0000000..d74124e
--- /dev/null
+++ b/include/clang/Lex/PPCallbacks.h
@@ -0,0 +1,148 @@
+//===--- PPCallbacks.h - Callbacks for Preprocessor actions -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the PPCallbacks interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LEX_PPCALLBACKS_H
+#define LLVM_CLANG_LEX_PPCALLBACKS_H
+
+#include "clang/Lex/DirectoryLookup.h"
+#include "clang/Basic/SourceLocation.h"
+#include <string>
+
+namespace clang {
+  class SourceLocation;
+  class Token;
+  class IdentifierInfo;
+  class MacroInfo;
+
+/// PPCallbacks - This interface provides a way to observe the actions of the
+/// preprocessor as it does its thing.  Clients can define their hooks here to
+/// implement preprocessor level tools.
+class PPCallbacks {
+public:
+  virtual ~PPCallbacks();
+
+  enum FileChangeReason {
+    EnterFile, ExitFile, SystemHeaderPragma, RenameFile
+  };
+
+  /// FileChanged - This callback is invoked whenever a source file is
+  /// entered or exited.  The SourceLocation indicates the new location, and
+  /// EnteringFile indicates whether this is because we are entering a new
+  /// #include'd file (when true) or whether we're exiting one because we ran
+  /// off the end (when false).
+  virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,
+                           SrcMgr::CharacteristicKind FileType) {
+  }
+
+  /// FileSkipped - This callback is invoked whenever a source file is
+  /// skipped as the result of header guard optimization.  ParentFile
+  /// is the file that #includes the skipped file.  FilenameTok is the
+  /// token in ParentFile that indicates the skipped file.
+  virtual void FileSkipped(const FileEntry &ParentFile,
+                           const Token &FilenameTok,
+                           SrcMgr::CharacteristicKind FileType) {
+  }
+
+  /// EndOfMainFile - This callback is invoked when the end of the main file is
+  /// reach, no subsequent callbacks will be made.
+  virtual void EndOfMainFile() {
+  }
+
+  /// Ident - This callback is invoked when a #ident or #sccs directive is read.
+  ///
+  virtual void Ident(SourceLocation Loc, const std::string &str) {
+  }
+
+  /// PragmaComment - This callback is invoked when a #pragma comment directive
+  /// is read.
+  ///
+  virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind,
+                             const std::string &Str) {
+  }
+
+  /// MacroExpands - This is called by
+  /// Preprocessor::HandleMacroExpandedIdentifier when a macro invocation is
+  /// found.
+  virtual void MacroExpands(const Token &Id, const MacroInfo* MI) {
+  }
+
+  /// MacroDefined - This hook is called whenever a macro definition is seen.
+  virtual void MacroDefined(const IdentifierInfo *II, const MacroInfo *MI) {
+  }
+
+  /// MacroUndefined - This hook is called whenever a macro #undef is seen.
+  /// MI is released immediately following this callback.
+  virtual void MacroUndefined(const IdentifierInfo *II, const MacroInfo *MI) {
+  }
+};
+
+/// PPChainedCallbacks - Simple wrapper class for chaining callbacks.
+class PPChainedCallbacks : public PPCallbacks {
+  PPCallbacks *First, *Second;
+
+public:
+  PPChainedCallbacks(PPCallbacks *_First, PPCallbacks *_Second)
+    : First(_First), Second(_Second) {}
+  ~PPChainedCallbacks() {
+    delete Second;
+    delete First;
+  }
+
+  virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,
+                           SrcMgr::CharacteristicKind FileType) {
+    First->FileChanged(Loc, Reason, FileType);
+    Second->FileChanged(Loc, Reason, FileType);
+  }
+
+  virtual void FileSkipped(const FileEntry &ParentFile,
+                           const Token &FilenameTok,
+                           SrcMgr::CharacteristicKind FileType) {
+    First->FileSkipped(ParentFile, FilenameTok, FileType);
+    Second->FileSkipped(ParentFile, FilenameTok, FileType);
+  }
+
+  virtual void EndOfMainFile() {
+    First->EndOfMainFile();
+    Second->EndOfMainFile();
+  }
+
+  virtual void Ident(SourceLocation Loc, const std::string &str) {
+    First->Ident(Loc, str);
+    Second->Ident(Loc, str);
+  }
+
+  virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind,
+                             const std::string &Str) {
+    First->PragmaComment(Loc, Kind, Str);
+    Second->PragmaComment(Loc, Kind, Str);
+  }
+
+  virtual void MacroExpands(const Token &Id, const MacroInfo* MI) {
+    First->MacroExpands(Id, MI);
+    Second->MacroExpands(Id, MI);
+  }
+
+  virtual void MacroDefined(const IdentifierInfo *II, const MacroInfo *MI) {
+    First->MacroDefined(II, MI);
+    Second->MacroDefined(II, MI);
+  }
+
+  virtual void MacroUndefined(const IdentifierInfo *II, const MacroInfo *MI) {
+    First->MacroUndefined(II, MI);
+    Second->MacroUndefined(II, MI);
+  }
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Lex/PTHLexer.h b/include/clang/Lex/PTHLexer.h
new file mode 100644
index 0000000..e96a8c5
--- /dev/null
+++ b/include/clang/Lex/PTHLexer.h
@@ -0,0 +1,104 @@
+//===--- PTHLexer.h - Lexer based on Pre-tokenized input --------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the PTHLexer interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_PTHLEXER_H
+#define LLVM_CLANG_PTHLEXER_H
+
+#include "clang/Lex/PreprocessorLexer.h"
+#include <vector>
+
+namespace clang {
+
+class PTHManager;
+class PTHSpellingSearch;
+
+class PTHLexer : public PreprocessorLexer {
+  SourceLocation FileStartLoc;
+
+  /// TokBuf - Buffer from PTH file containing raw token data.
+  const unsigned char* TokBuf;
+
+  /// CurPtr - Pointer into current offset of the token buffer where
+  ///  the next token will be read.
+  const unsigned char* CurPtr;
+
+  /// LastHashTokPtr - Pointer into TokBuf of the last processed '#'
+  ///  token that appears at the start of a line.
+  const unsigned char* LastHashTokPtr;
+
+  /// PPCond - Pointer to a side table in the PTH file that provides a
+  ///  a consise summary of the preproccessor conditional block structure.
+  ///  This is used to perform quick skipping of conditional blocks.
+  const unsigned char* PPCond;
+
+  /// CurPPCondPtr - Pointer inside PPCond that refers to the next entry
+  ///  to process when doing quick skipping of preprocessor blocks.
+  const unsigned char* CurPPCondPtr;
+
+  PTHLexer(const PTHLexer&);  // DO NOT IMPLEMENT
+  void operator=(const PTHLexer&); // DO NOT IMPLEMENT
+
+  /// ReadToken - Used by PTHLexer to read tokens TokBuf.
+  void ReadToken(Token& T);
+
+  /// PTHMgr - The PTHManager object that created this PTHLexer.
+  PTHManager& PTHMgr;
+
+  Token EofToken;
+
+protected:
+  friend class PTHManager;
+
+  /// Create a PTHLexer for the specified token stream.
+  PTHLexer(Preprocessor& pp, FileID FID, const unsigned char *D,
+           const unsigned char* ppcond, PTHManager &PM);
+public:
+
+  ~PTHLexer() {}
+
+  /// Lex - Return the next token.
+  void Lex(Token &Tok);
+
+  void getEOF(Token &Tok);
+
+  /// DiscardToEndOfLine - Read the rest of the current preprocessor line as an
+  /// uninterpreted string.  This switches the lexer out of directive mode.
+  void DiscardToEndOfLine();
+
+  /// isNextPPTokenLParen - Return 1 if the next unexpanded token will return a
+  /// tok::l_paren token, 0 if it is something else and 2 if there are no more
+  /// tokens controlled by this lexer.
+  unsigned isNextPPTokenLParen() {
+    // isNextPPTokenLParen is not on the hot path, and all we care about is
+    // whether or not we are at a token with kind tok::eof or tok::l_paren.
+    // Just read the first byte from the current token pointer to determine
+    // its kind.
+    tok::TokenKind x = (tok::TokenKind)*CurPtr;
+    return x == tok::eof ? 2 : x == tok::l_paren;
+  }
+
+  /// IndirectLex - An indirect call to 'Lex' that can be invoked via
+  ///  the PreprocessorLexer interface.
+  void IndirectLex(Token &Result) { Lex(Result); }
+
+  /// getSourceLocation - Return a source location for the token in
+  /// the current file.
+  SourceLocation getSourceLocation();
+
+  /// SkipBlock - Used by Preprocessor to skip the current conditional block.
+  bool SkipBlock();
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Lex/PTHManager.h b/include/clang/Lex/PTHManager.h
new file mode 100644
index 0000000..5e8a4f1
--- /dev/null
+++ b/include/clang/Lex/PTHManager.h
@@ -0,0 +1,140 @@
+//===--- PTHManager.h - Manager object for PTH processing -------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the PTHManager interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_PTHMANAGER_H
+#define LLVM_CLANG_PTHMANAGER_H
+
+#include "clang/Lex/PTHLexer.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/Diagnostic.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/Support/Allocator.h"
+#include <string>
+
+namespace llvm {
+  class MemoryBuffer;
+}
+
+namespace clang {
+
+class FileEntry;
+class PTHLexer;
+class Diagnostic;
+class StatSysCallCache;
+
+class PTHManager : public IdentifierInfoLookup {
+  friend class PTHLexer;
+
+  /// The memory mapped PTH file.
+  const llvm::MemoryBuffer* Buf;
+
+  /// Alloc - Allocator used for IdentifierInfo objects.
+  llvm::BumpPtrAllocator Alloc;
+
+  /// IdMap - A lazily generated cache mapping from persistent identifiers to
+  ///  IdentifierInfo*.
+  IdentifierInfo** PerIDCache;
+
+  /// FileLookup - Abstract data structure used for mapping between files
+  ///  and token data in the PTH file.
+  void* FileLookup;
+
+  /// IdDataTable - Array representing the mapping from persistent IDs to the
+  ///  data offset within the PTH file containing the information to
+  ///  reconsitute an IdentifierInfo.
+  const unsigned char* const IdDataTable;
+
+  /// SortedIdTable - Abstract data structure mapping from strings to
+  ///  persistent IDs.  This is used by get().
+  void* StringIdLookup;
+
+  /// NumIds - The number of identifiers in the PTH file.
+  const unsigned NumIds;
+
+  /// PP - The Preprocessor object that will use this PTHManager to create
+  ///  PTHLexer objects.
+  Preprocessor* PP;
+
+  /// SpellingBase - The base offset within the PTH memory buffer that
+  ///  contains the cached spellings for literals.
+  const unsigned char* const SpellingBase;
+
+  /// OriginalSourceFile - A null-terminated C-string that specifies the name
+  ///  if the file (if any) that was to used to generate the PTH cache.
+  const char* OriginalSourceFile;
+
+  /// This constructor is intended to only be called by the static 'Create'
+  /// method.
+  PTHManager(const llvm::MemoryBuffer* buf, void* fileLookup,
+             const unsigned char* idDataTable, IdentifierInfo** perIDCache,
+             void* stringIdLookup, unsigned numIds,
+             const unsigned char* spellingBase, const char *originalSourceFile);
+
+  // Do not implement.
+  PTHManager();
+  void operator=(const PTHManager&);
+
+  /// getSpellingAtPTHOffset - Used by PTHLexer classes to get the cached
+  ///  spelling for a token.
+  unsigned getSpellingAtPTHOffset(unsigned PTHOffset, const char*& Buffer);
+
+  /// GetIdentifierInfo - Used to reconstruct IdentifierInfo objects from the
+  ///  PTH file.
+  inline IdentifierInfo* GetIdentifierInfo(unsigned PersistentID) {
+    // Check if the IdentifierInfo has already been resolved.
+    if (IdentifierInfo* II = PerIDCache[PersistentID])
+      return II;
+    return LazilyCreateIdentifierInfo(PersistentID);
+  }
+  IdentifierInfo* LazilyCreateIdentifierInfo(unsigned PersistentID);
+
+public:
+  // The current PTH version.
+  enum { Version = 9 };
+
+  ~PTHManager();
+
+  /// getOriginalSourceFile - Return the full path to the original header
+  ///  file name that was used to generate the PTH cache.
+  const char* getOriginalSourceFile() const {
+    return OriginalSourceFile;
+  }
+
+  /// get - Return the identifier token info for the specified named identifier.
+  ///  Unlike the version in IdentifierTable, this returns a pointer instead
+  ///  of a reference.  If the pointer is NULL then the IdentifierInfo cannot
+  ///  be found.
+  IdentifierInfo *get(llvm::StringRef Name);
+
+  /// Create - This method creates PTHManager objects.  The 'file' argument
+  ///  is the name of the PTH file.  This method returns NULL upon failure.
+  static PTHManager *Create(const std::string& file, Diagnostic &Diags);
+
+  void setPreprocessor(Preprocessor *pp) { PP = pp; }
+
+  /// CreateLexer - Return a PTHLexer that "lexes" the cached tokens for the
+  ///  specified file.  This method returns NULL if no cached tokens exist.
+  ///  It is the responsibility of the caller to 'delete' the returned object.
+  PTHLexer *CreateLexer(FileID FID);
+
+  /// createStatCache - Returns a StatSysCallCache object for use with
+  ///  FileManager objects.  These objects use the PTH data to speed up
+  ///  calls to stat by memoizing their results from when the PTH file
+  ///  was generated.
+  StatSysCallCache *createStatCache();
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Lex/Pragma.h b/include/clang/Lex/Pragma.h
new file mode 100644
index 0000000..ef367fe
--- /dev/null
+++ b/include/clang/Lex/Pragma.h
@@ -0,0 +1,90 @@
+//===--- Pragma.h - Pragma registration and handling ------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the PragmaHandler and PragmaTable interfaces.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_PRAGMA_H
+#define LLVM_CLANG_PRAGMA_H
+
+#include <cassert>
+#include <vector>
+
+namespace clang {
+  class Preprocessor;
+  class Token;
+  class IdentifierInfo;
+  class PragmaNamespace;
+
+/// PragmaHandler - Instances of this interface defined to handle the various
+/// pragmas that the language front-end uses.  Each handler optionally has a
+/// name (e.g. "pack") and the HandlePragma method is invoked when a pragma with
+/// that identifier is found.  If a handler does not match any of the declared
+/// pragmas the handler with a null identifier is invoked, if it exists.
+///
+/// Note that the PragmaNamespace class can be used to subdivide pragmas, e.g.
+/// we treat "#pragma STDC" and "#pragma GCC" as namespaces that contain other
+/// pragmas.
+class PragmaHandler {
+  const IdentifierInfo *Name;
+public:
+  PragmaHandler(const IdentifierInfo *name) : Name(name) {}
+  virtual ~PragmaHandler();
+
+  const IdentifierInfo *getName() const { return Name; }
+  virtual void HandlePragma(Preprocessor &PP, Token &FirstToken) = 0;
+
+  /// getIfNamespace - If this is a namespace, return it.  This is equivalent to
+  /// using a dynamic_cast, but doesn't require RTTI.
+  virtual PragmaNamespace *getIfNamespace() { return 0; }
+};
+
+/// PragmaNamespace - This PragmaHandler subdivides the namespace of pragmas,
+/// allowing hierarchical pragmas to be defined.  Common examples of namespaces
+/// are "#pragma GCC", "#pragma STDC", and "#pragma omp", but any namespaces may
+/// be (potentially recursively) defined.
+class PragmaNamespace : public PragmaHandler {
+  /// Handlers - This is the list of handlers in this namespace.
+  ///
+  std::vector<PragmaHandler*> Handlers;
+public:
+  PragmaNamespace(const IdentifierInfo *Name) : PragmaHandler(Name) {}
+  virtual ~PragmaNamespace();
+
+  /// FindHandler - Check to see if there is already a handler for the
+  /// specified name.  If not, return the handler for the null identifier if it
+  /// exists, otherwise return null.  If IgnoreNull is true (the default) then
+  /// the null handler isn't returned on failure to match.
+  PragmaHandler *FindHandler(const IdentifierInfo *Name,
+                             bool IgnoreNull = true) const;
+
+  /// AddPragma - Add a pragma to this namespace.
+  ///
+  void AddPragma(PragmaHandler *Handler) {
+    Handlers.push_back(Handler);
+  }
+
+  /// RemovePragmaHandler - Remove the given handler from the
+  /// namespace.
+  void RemovePragmaHandler(PragmaHandler *Handler);
+
+  bool IsEmpty() {
+    return Handlers.empty();
+  }
+
+  virtual void HandlePragma(Preprocessor &PP, Token &FirstToken);
+
+  virtual PragmaNamespace *getIfNamespace() { return this; }
+};
+
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Lex/PreprocessingRecord.h b/include/clang/Lex/PreprocessingRecord.h
new file mode 100644
index 0000000..ef28af9
--- /dev/null
+++ b/include/clang/Lex/PreprocessingRecord.h
@@ -0,0 +1,274 @@
+//===--- PreprocessingRecord.h - Record of Preprocessing --------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the PreprocessingRecord class, which maintains a record
+//  of what occurred during preprocessing.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_LEX_PREPROCESSINGRECORD_H
+#define LLVM_CLANG_LEX_PREPROCESSINGRECORD_H
+
+#include "clang/Lex/PPCallbacks.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/Support/Allocator.h"
+#include <vector>
+
+namespace clang {
+  class IdentifierInfo;
+  class PreprocessingRecord;
+}
+
+/// \brief Allocates memory within a Clang preprocessing record.
+void* operator new(size_t bytes, clang::PreprocessingRecord& PR,
+                   unsigned alignment = 8) throw();
+
+/// \brief Frees memory allocated in a Clang preprocessing record.
+void operator delete(void* ptr, clang::PreprocessingRecord& PR,
+                     unsigned) throw();
+
+namespace clang {
+  class MacroDefinition;
+
+  /// \brief Base class that describes a preprocessed entity, which may be a
+  /// preprocessor directive or macro instantiation.
+  class PreprocessedEntity {
+  public:
+    /// \brief The kind of preprocessed entity an object describes.
+    enum EntityKind {
+      /// \brief A macro instantiation.
+      MacroInstantiationKind,
+      
+      /// \brief A preprocessing directive whose kind is not specified.
+      ///
+      /// This kind will be used for any preprocessing directive that does not
+      /// have a more specific kind within the \c DirectiveKind enumeration.
+      PreprocessingDirectiveKind,
+      
+      /// \brief A macro definition.
+      MacroDefinitionKind,
+      
+      FirstPreprocessingDirective = PreprocessingDirectiveKind,
+      LastPreprocessingDirective = MacroDefinitionKind
+    };
+
+  private:
+    /// \brief The kind of preprocessed entity that this object describes.
+    EntityKind Kind;
+    
+    /// \brief The source range that covers this preprocessed entity.
+    SourceRange Range;
+    
+  protected:
+    PreprocessedEntity(EntityKind Kind, SourceRange Range)
+      : Kind(Kind), Range(Range) { }
+    
+  public:
+    /// \brief Retrieve the kind of preprocessed entity stored in this object.
+    EntityKind getKind() const { return Kind; }
+    
+    /// \brief Retrieve the source range that covers this entire preprocessed 
+    /// entity.
+    SourceRange getSourceRange() const { return Range; }
+    
+    // Implement isa/cast/dyncast/etc.
+    static bool classof(const PreprocessedEntity *) { return true; }
+
+    // Only allow allocation of preprocessed entities using the allocator 
+    // in PreprocessingRecord or by doing a placement new.
+    void* operator new(size_t bytes, PreprocessingRecord& PR,
+                       unsigned alignment = 8) throw() {
+      return ::operator new(bytes, PR, alignment);
+    }
+    
+    void* operator new(size_t bytes, void* mem) throw() {
+      return mem;
+    }
+    
+    void operator delete(void* ptr, PreprocessingRecord& PR, 
+                         unsigned alignment) throw() {
+      return ::operator delete(ptr, PR, alignment);
+    }
+    
+    void operator delete(void*, std::size_t) throw() { }
+    void operator delete(void*, void*) throw() { }
+    
+  private:
+    // Make vanilla 'new' and 'delete' illegal for preprocessed entities.
+    void* operator new(size_t bytes) throw();
+    void operator delete(void* data) throw();
+  };
+  
+  /// \brief Records the location of a macro instantiation.
+  class MacroInstantiation : public PreprocessedEntity {
+    /// \brief The name of the macro being instantiation.
+    IdentifierInfo *Name;
+    
+    /// \brief The definition of this macro.
+    MacroDefinition *Definition;
+    
+  public:
+    MacroInstantiation(IdentifierInfo *Name, SourceRange Range,
+                       MacroDefinition *Definition)
+      : PreprocessedEntity(MacroInstantiationKind, Range), Name(Name), 
+        Definition(Definition) { }
+    
+    /// \brief The name of the macro being instantiated.
+    IdentifierInfo *getName() const { return Name; }
+    
+    /// \brief The definition of the macro being instantiated.
+    MacroDefinition *getDefinition() const { return Definition; }
+
+    // Implement isa/cast/dyncast/etc.
+    static bool classof(const PreprocessedEntity *PE) {
+      return PE->getKind() == MacroInstantiationKind;
+    }
+    static bool classof(const MacroInstantiation *) { return true; }
+
+  };
+  
+  /// \brief Records the presence of a preprocessor directive.
+  class PreprocessingDirective : public PreprocessedEntity {
+  public:
+    PreprocessingDirective(EntityKind Kind, SourceRange Range) 
+      : PreprocessedEntity(Kind, Range) { }
+    
+    // Implement isa/cast/dyncast/etc.
+    static bool classof(const PreprocessedEntity *PD) { 
+      return PD->getKind() >= FirstPreprocessingDirective &&
+             PD->getKind() <= LastPreprocessingDirective;
+    }
+    static bool classof(const PreprocessingDirective *) { return true; }    
+  };
+  
+  /// \brief Record the location of a macro definition.
+  class MacroDefinition : public PreprocessingDirective {
+    /// \brief The name of the macro being defined.
+    const IdentifierInfo *Name;
+    
+    /// \brief The location of the macro name in the macro definition.
+    SourceLocation Location;
+
+  public:
+    explicit MacroDefinition(const IdentifierInfo *Name, SourceLocation Location,
+                             SourceRange Range)
+      : PreprocessingDirective(MacroDefinitionKind, Range), Name(Name), 
+        Location(Location) { }
+    
+    /// \brief Retrieve the name of the macro being defined.
+    const IdentifierInfo *getName() const { return Name; }
+    
+    /// \brief Retrieve the location of the macro name in the definition.
+    SourceLocation getLocation() const { return Location; }
+    
+    // Implement isa/cast/dyncast/etc.
+    static bool classof(const PreprocessedEntity *PE) {
+      return PE->getKind() == MacroDefinitionKind;
+    }
+    static bool classof(const MacroDefinition *) { return true; }
+  };
+  
+  /// \brief An abstract class that should be subclassed by any external source
+  /// of preprocessing record entries.
+  class ExternalPreprocessingRecordSource {
+  public:
+    virtual ~ExternalPreprocessingRecordSource();
+    
+    /// \brief Read any preallocated preprocessed entities from the external
+    /// source.
+    virtual void ReadPreprocessedEntities() = 0;
+  };
+  
+  /// \brief A record of the steps taken while preprocessing a source file,
+  /// including the various preprocessing directives processed, macros 
+  /// instantiated, etc.
+  class PreprocessingRecord : public PPCallbacks {
+    /// \brief Allocator used to store preprocessing objects.
+    llvm::BumpPtrAllocator BumpAlloc;
+
+    /// \brief The set of preprocessed entities in this record, in order they
+    /// were seen.
+    std::vector<PreprocessedEntity *> PreprocessedEntities;
+    
+    /// \brief Mapping from MacroInfo structures to their definitions.
+    llvm::DenseMap<const MacroInfo *, MacroDefinition *> MacroDefinitions;
+
+    /// \brief External source of preprocessed entities.
+    ExternalPreprocessingRecordSource *ExternalSource;
+    
+    /// \brief The number of preallocated entities (that are known to the
+    /// external source).
+    unsigned NumPreallocatedEntities;
+    
+    /// \brief Whether we have already loaded all of the preallocated entities.
+    mutable bool LoadedPreallocatedEntities;
+    
+    void MaybeLoadPreallocatedEntities() const ;
+    
+  public:
+    PreprocessingRecord();
+    
+    /// \brief Allocate memory in the preprocessing record.
+    void *Allocate(unsigned Size, unsigned Align = 8) {
+      return BumpAlloc.Allocate(Size, Align);
+    }
+    
+    /// \brief Deallocate memory in the preprocessing record.
+    void Deallocate(void *Ptr) { }
+    
+    // Iteration over the preprocessed entities.
+    typedef std::vector<PreprocessedEntity *>::iterator iterator;
+    typedef std::vector<PreprocessedEntity *>::const_iterator const_iterator;
+    iterator begin(bool OnlyLocalEntities = false);
+    iterator end(bool OnlyLocalEntities = false);
+    const_iterator begin(bool OnlyLocalEntities = false) const;
+    const_iterator end(bool OnlyLocalEntities = false) const;
+    
+    /// \brief Add a new preprocessed entity to this record.
+    void addPreprocessedEntity(PreprocessedEntity *Entity);
+    
+    /// \brief Set the external source for preprocessed entities.
+    void SetExternalSource(ExternalPreprocessingRecordSource &Source,
+                           unsigned NumPreallocatedEntities);
+    
+    /// \brief Set the preallocated entry at the given index to the given
+    /// preprocessed entity.
+    void SetPreallocatedEntity(unsigned Index, PreprocessedEntity *Entity);
+
+    /// \brief Register a new macro definition.
+    void RegisterMacroDefinition(MacroInfo *Macro, MacroDefinition *MD);
+                           
+    /// \brief Retrieve the preprocessed entity at the given index.
+    PreprocessedEntity *getPreprocessedEntity(unsigned Index) {
+      assert(Index < PreprocessedEntities.size() &&
+             "Out-of-bounds preprocessed entity");
+      return PreprocessedEntities[Index];
+    }
+    
+    /// \brief Retrieve the macro definition that corresponds to the given
+    /// \c MacroInfo.
+    MacroDefinition *findMacroDefinition(const MacroInfo *MI);
+    
+    virtual void MacroExpands(const Token &Id, const MacroInfo* MI);
+    virtual void MacroDefined(const IdentifierInfo *II, const MacroInfo *MI);
+    virtual void MacroUndefined(const IdentifierInfo *II, const MacroInfo *MI);
+  };
+} // end namespace clang
+
+inline void* operator new(size_t bytes, clang::PreprocessingRecord& PR,
+                          unsigned alignment) throw() {
+  return PR.Allocate(bytes, alignment);
+}
+
+inline void operator delete(void* ptr, clang::PreprocessingRecord& PR,
+                            unsigned) throw() {
+  PR.Deallocate(ptr);
+}
+
+#endif // LLVM_CLANG_LEX_PREPROCESSINGRECORD_H
diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h
new file mode 100644
index 0000000..20d9fc5
--- /dev/null
+++ b/include/clang/Lex/Preprocessor.h
@@ -0,0 +1,941 @@
+//===--- Preprocessor.h - C Language Family Preprocessor --------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the Preprocessor interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LEX_PREPROCESSOR_H
+#define LLVM_CLANG_LEX_PREPROCESSOR_H
+
+#include "clang/Lex/Lexer.h"
+#include "clang/Lex/PTHLexer.h"
+#include "clang/Lex/PPCallbacks.h"
+#include "clang/Lex/TokenLexer.h"
+#include "clang/Lex/PTHManager.h"
+#include "clang/Basic/Builtins.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Allocator.h"
+#include <vector>
+
+namespace clang {
+
+class SourceManager;
+class ExternalPreprocessorSource;
+class FileManager;
+class FileEntry;
+class HeaderSearch;
+class PragmaNamespace;
+class PragmaHandler;
+class CommentHandler;
+class ScratchBuffer;
+class TargetInfo;
+class PPCallbacks;
+class DirectoryLookup;
+class PreprocessingRecord;
+  
+/// Preprocessor - This object engages in a tight little dance with the lexer to
+/// efficiently preprocess tokens.  Lexers know only about tokens within a
+/// single source file, and don't know anything about preprocessor-level issues
+/// like the #include stack, token expansion, etc.
+///
+class Preprocessor {
+  Diagnostic        *Diags;
+  LangOptions        Features;
+  const TargetInfo  &Target;
+  FileManager       &FileMgr;
+  SourceManager     &SourceMgr;
+  ScratchBuffer     *ScratchBuf;
+  HeaderSearch      &HeaderInfo;
+
+  /// \brief External source of macros.
+  ExternalPreprocessorSource *ExternalSource;
+
+  /// PTH - An optional PTHManager object used for getting tokens from
+  ///  a token cache rather than lexing the original source file.
+  llvm::OwningPtr<PTHManager> PTH;
+
+  /// BP - A BumpPtrAllocator object used to quickly allocate and release
+  ///  objects internal to the Preprocessor.
+  llvm::BumpPtrAllocator BP;
+
+  /// Identifiers for builtin macros and other builtins.
+  IdentifierInfo *Ident__LINE__, *Ident__FILE__;   // __LINE__, __FILE__
+  IdentifierInfo *Ident__DATE__, *Ident__TIME__;   // __DATE__, __TIME__
+  IdentifierInfo *Ident__INCLUDE_LEVEL__;          // __INCLUDE_LEVEL__
+  IdentifierInfo *Ident__BASE_FILE__;              // __BASE_FILE__
+  IdentifierInfo *Ident__TIMESTAMP__;              // __TIMESTAMP__
+  IdentifierInfo *Ident__COUNTER__;                // __COUNTER__
+  IdentifierInfo *Ident_Pragma, *Ident__VA_ARGS__; // _Pragma, __VA_ARGS__
+  IdentifierInfo *Ident__has_feature;              // __has_feature
+  IdentifierInfo *Ident__has_builtin;              // __has_builtin
+  IdentifierInfo *Ident__has_include;              // __has_include
+  IdentifierInfo *Ident__has_include_next;         // __has_include_next
+
+  SourceLocation DATELoc, TIMELoc;
+  unsigned CounterValue;  // Next __COUNTER__ value.
+
+  enum {
+    /// MaxIncludeStackDepth - Maximum depth of #includes.
+    MaxAllowedIncludeStackDepth = 200
+  };
+
+  // State that is set before the preprocessor begins.
+  bool KeepComments : 1;
+  bool KeepMacroComments : 1;
+
+  // State that changes while the preprocessor runs:
+  bool InMacroArgs : 1;            // True if parsing fn macro invocation args.
+
+  /// Whether the preprocessor owns the header search object.
+  bool OwnsHeaderSearch : 1;
+
+  /// DisableMacroExpansion - True if macro expansion is disabled.
+  bool DisableMacroExpansion : 1;
+
+  /// \brief Whether we have already loaded macros from the external source.
+  mutable bool ReadMacrosFromExternalSource : 1;
+
+  /// Identifiers - This is mapping/lookup information for all identifiers in
+  /// the program, including program keywords.
+  mutable IdentifierTable Identifiers;
+
+  /// Selectors - This table contains all the selectors in the program. Unlike
+  /// IdentifierTable above, this table *isn't* populated by the preprocessor.
+  /// It is declared/instantiated here because it's role/lifetime is
+  /// conceptually similar the IdentifierTable. In addition, the current control
+  /// flow (in clang::ParseAST()), make it convenient to put here.
+  /// FIXME: Make sure the lifetime of Identifiers/Selectors *isn't* tied to
+  /// the lifetime fo the preprocessor.
+  SelectorTable Selectors;
+
+  /// BuiltinInfo - Information about builtins.
+  Builtin::Context BuiltinInfo;
+
+  /// PragmaHandlers - This tracks all of the pragmas that the client registered
+  /// with this preprocessor.
+  PragmaNamespace *PragmaHandlers;
+
+  /// \brief Tracks all of the comment handlers that the client registered
+  /// with this preprocessor.
+  std::vector<CommentHandler *> CommentHandlers;
+
+  /// \brief The file that we're performing code-completion for, if any.
+  const FileEntry *CodeCompletionFile;
+
+  /// CurLexer - This is the current top of the stack that we're lexing from if
+  /// not expanding a macro and we are lexing directly from source code.
+  ///  Only one of CurLexer, CurPTHLexer, or CurTokenLexer will be non-null.
+  llvm::OwningPtr<Lexer> CurLexer;
+
+  /// CurPTHLexer - This is the current top of stack that we're lexing from if
+  ///  not expanding from a macro and we are lexing from a PTH cache.
+  ///  Only one of CurLexer, CurPTHLexer, or CurTokenLexer will be non-null.
+  llvm::OwningPtr<PTHLexer> CurPTHLexer;
+
+  /// CurPPLexer - This is the current top of the stack what we're lexing from
+  ///  if not expanding a macro.  This is an alias for either CurLexer or
+  ///  CurPTHLexer.
+  PreprocessorLexer *CurPPLexer;
+
+  /// CurLookup - The DirectoryLookup structure used to find the current
+  /// FileEntry, if CurLexer is non-null and if applicable.  This allows us to
+  /// implement #include_next and find directory-specific properties.
+  const DirectoryLookup *CurDirLookup;
+
+  /// CurTokenLexer - This is the current macro we are expanding, if we are
+  /// expanding a macro.  One of CurLexer and CurTokenLexer must be null.
+  llvm::OwningPtr<TokenLexer> CurTokenLexer;
+
+  /// IncludeMacroStack - This keeps track of the stack of files currently
+  /// #included, and macros currently being expanded from, not counting
+  /// CurLexer/CurTokenLexer.
+  struct IncludeStackInfo {
+    Lexer                 *TheLexer;
+    PTHLexer              *ThePTHLexer;
+    PreprocessorLexer     *ThePPLexer;
+    TokenLexer            *TheTokenLexer;
+    const DirectoryLookup *TheDirLookup;
+
+    IncludeStackInfo(Lexer *L, PTHLexer* P, PreprocessorLexer* PPL,
+                     TokenLexer* TL, const DirectoryLookup *D)
+      : TheLexer(L), ThePTHLexer(P), ThePPLexer(PPL), TheTokenLexer(TL),
+        TheDirLookup(D) {}
+  };
+  std::vector<IncludeStackInfo> IncludeMacroStack;
+
+  /// Callbacks - These are actions invoked when some preprocessor activity is
+  /// encountered (e.g. a file is #included, etc).
+  PPCallbacks *Callbacks;
+
+  /// Macros - For each IdentifierInfo with 'HasMacro' set, we keep a mapping
+  /// to the actual definition of the macro.
+  llvm::DenseMap<IdentifierInfo*, MacroInfo*> Macros;
+
+  /// MICache - A "freelist" of MacroInfo objects that can be reused for quick
+  /// allocation.
+  /// FIXME: why not use a singly linked list?
+  std::vector<MacroInfo*> MICache;
+
+  /// MacroArgCache - This is a "freelist" of MacroArg objects that can be
+  /// reused for quick allocation.
+  MacroArgs *MacroArgCache;
+  friend class MacroArgs;
+
+  // Various statistics we track for performance analysis.
+  unsigned NumDirectives, NumIncluded, NumDefined, NumUndefined, NumPragma;
+  unsigned NumIf, NumElse, NumEndif;
+  unsigned NumEnteredSourceFiles, MaxIncludeStackDepth;
+  unsigned NumMacroExpanded, NumFnMacroExpanded, NumBuiltinMacroExpanded;
+  unsigned NumFastMacroExpanded, NumTokenPaste, NumFastTokenPaste;
+  unsigned NumSkipped;
+
+  /// Predefines - This string is the predefined macros that preprocessor
+  /// should use from the command line etc.
+  std::string Predefines;
+
+  /// TokenLexerCache - Cache macro expanders to reduce malloc traffic.
+  enum { TokenLexerCacheSize = 8 };
+  unsigned NumCachedTokenLexers;
+  TokenLexer *TokenLexerCache[TokenLexerCacheSize];
+
+  /// \brief A record of the macro definitions and instantiations that
+  /// occurred during preprocessing. 
+  ///
+  /// This is an optional side structure that can be enabled with
+  /// \c createPreprocessingRecord() prior to preprocessing.
+  PreprocessingRecord *Record;
+  
+private:  // Cached tokens state.
+  typedef llvm::SmallVector<Token, 1> CachedTokensTy;
+
+  /// CachedTokens - Cached tokens are stored here when we do backtracking or
+  /// lookahead. They are "lexed" by the CachingLex() method.
+  CachedTokensTy CachedTokens;
+
+  /// CachedLexPos - The position of the cached token that CachingLex() should
+  /// "lex" next. If it points beyond the CachedTokens vector, it means that
+  /// a normal Lex() should be invoked.
+  CachedTokensTy::size_type CachedLexPos;
+
+  /// BacktrackPositions - Stack of backtrack positions, allowing nested
+  /// backtracks. The EnableBacktrackAtThisPos() method pushes a position to
+  /// indicate where CachedLexPos should be set when the BackTrack() method is
+  /// invoked (at which point the last position is popped).
+  std::vector<CachedTokensTy::size_type> BacktrackPositions;
+
+public:
+  Preprocessor(Diagnostic &diags, const LangOptions &opts,
+               const TargetInfo &target,
+               SourceManager &SM, HeaderSearch &Headers,
+               IdentifierInfoLookup *IILookup = 0,
+               bool OwnsHeaderSearch = false);
+
+  ~Preprocessor();
+
+  Diagnostic &getDiagnostics() const { return *Diags; }
+  void setDiagnostics(Diagnostic &D) { Diags = &D; }
+
+  const LangOptions &getLangOptions() const { return Features; }
+  const TargetInfo &getTargetInfo() const { return Target; }
+  FileManager &getFileManager() const { return FileMgr; }
+  SourceManager &getSourceManager() const { return SourceMgr; }
+  HeaderSearch &getHeaderSearchInfo() const { return HeaderInfo; }
+
+  IdentifierTable &getIdentifierTable() { return Identifiers; }
+  SelectorTable &getSelectorTable() { return Selectors; }
+  Builtin::Context &getBuiltinInfo() { return BuiltinInfo; }
+  llvm::BumpPtrAllocator &getPreprocessorAllocator() { return BP; }
+
+  void setPTHManager(PTHManager* pm);
+
+  PTHManager *getPTHManager() { return PTH.get(); }
+
+  void setExternalSource(ExternalPreprocessorSource *Source) {
+    ExternalSource = Source;
+  }
+
+  ExternalPreprocessorSource *getExternalSource() const {
+    return ExternalSource;
+  }
+
+  /// SetCommentRetentionState - Control whether or not the preprocessor retains
+  /// comments in output.
+  void SetCommentRetentionState(bool KeepComments, bool KeepMacroComments) {
+    this->KeepComments = KeepComments | KeepMacroComments;
+    this->KeepMacroComments = KeepMacroComments;
+  }
+
+  bool getCommentRetentionState() const { return KeepComments; }
+
+  /// isCurrentLexer - Return true if we are lexing directly from the specified
+  /// lexer.
+  bool isCurrentLexer(const PreprocessorLexer *L) const {
+    return CurPPLexer == L;
+  }
+
+  /// getCurrentLexer - Return the current lexer being lexed from.  Note
+  /// that this ignores any potentially active macro expansions and _Pragma
+  /// expansions going on at the time.
+  PreprocessorLexer *getCurrentLexer() const { return CurPPLexer; }
+
+  /// getCurrentFileLexer - Return the current file lexer being lexed from.  Note
+  /// that this ignores any potentially active macro expansions and _Pragma
+  /// expansions going on at the time.
+  PreprocessorLexer *getCurrentFileLexer() const;
+
+  /// getPPCallbacks/addPPCallbacks - Accessors for preprocessor callbacks.
+  /// Note that this class takes ownership of any PPCallbacks object given to
+  /// it.
+  PPCallbacks *getPPCallbacks() const { return Callbacks; }
+  void addPPCallbacks(PPCallbacks *C) {
+    if (Callbacks)
+      C = new PPChainedCallbacks(C, Callbacks);
+    Callbacks = C;
+  }
+
+  /// getMacroInfo - Given an identifier, return the MacroInfo it is #defined to
+  /// or null if it isn't #define'd.
+  MacroInfo *getMacroInfo(IdentifierInfo *II) const {
+    return II->hasMacroDefinition() ? Macros.find(II)->second : 0;
+  }
+
+  /// setMacroInfo - Specify a macro for this identifier.
+  ///
+  void setMacroInfo(IdentifierInfo *II, MacroInfo *MI);
+
+  /// macro_iterator/macro_begin/macro_end - This allows you to walk the current
+  /// state of the macro table.  This visits every currently-defined macro.
+  typedef llvm::DenseMap<IdentifierInfo*,
+                         MacroInfo*>::const_iterator macro_iterator;
+  macro_iterator macro_begin(bool IncludeExternalMacros = true) const;
+  macro_iterator macro_end(bool IncludeExternalMacros = true) const;
+
+  const std::string &getPredefines() const { return Predefines; }
+  /// setPredefines - Set the predefines for this Preprocessor.  These
+  /// predefines are automatically injected when parsing the main file.
+  void setPredefines(const char *P) { Predefines = P; }
+  void setPredefines(const std::string &P) { Predefines = P; }
+
+  /// getIdentifierInfo - Return information about the specified preprocessor
+  /// identifier token.  The version of this method that takes two character
+  /// pointers is preferred unless the identifier is already available as a
+  /// string (this avoids allocation and copying of memory to construct an
+  /// std::string).
+  IdentifierInfo *getIdentifierInfo(llvm::StringRef Name) const {
+    return &Identifiers.get(Name);
+  }
+
+  /// AddPragmaHandler - Add the specified pragma handler to the preprocessor.
+  /// If 'Namespace' is non-null, then it is a token required to exist on the
+  /// pragma line before the pragma string starts, e.g. "STDC" or "GCC".
+  void AddPragmaHandler(const char *Namespace, PragmaHandler *Handler);
+
+  /// RemovePragmaHandler - Remove the specific pragma handler from
+  /// the preprocessor. If \arg Namespace is non-null, then it should
+  /// be the namespace that \arg Handler was added to. It is an error
+  /// to remove a handler that has not been registered.
+  void RemovePragmaHandler(const char *Namespace, PragmaHandler *Handler);
+
+  /// \brief Add the specified comment handler to the preprocessor.
+  void AddCommentHandler(CommentHandler *Handler);
+
+  /// \brief Remove the specified comment handler.
+  ///
+  /// It is an error to remove a handler that has not been registered.
+  void RemoveCommentHandler(CommentHandler *Handler);
+
+  /// \brief Retrieve the preprocessing record, or NULL if there is no
+  /// preprocessing record.
+  PreprocessingRecord *getPreprocessingRecord() const { return Record; }
+  
+  /// \brief Create a new preprocessing record, which will keep track of 
+  /// all macro expansions, macro definitions, etc.
+  void createPreprocessingRecord();
+  
+  /// EnterMainSourceFile - Enter the specified FileID as the main source file,
+  /// which implicitly adds the builtin defines etc.
+  void EnterMainSourceFile();
+
+  /// EndSourceFile - Inform the preprocessor callbacks that processing is
+  /// complete.
+  void EndSourceFile();
+
+  /// EnterSourceFile - Add a source file to the top of the include stack and
+  /// start lexing tokens from it instead of the current buffer.  Emit an error
+  /// and don't enter the file on error.
+  void EnterSourceFile(FileID CurFileID, const DirectoryLookup *Dir,
+                       SourceLocation Loc);
+
+  /// EnterMacro - Add a Macro to the top of the include stack and start lexing
+  /// tokens from it instead of the current buffer.  Args specifies the
+  /// tokens input to a function-like macro.
+  ///
+  /// ILEnd specifies the location of the ')' for a function-like macro or the
+  /// identifier for an object-like macro.
+  void EnterMacro(Token &Identifier, SourceLocation ILEnd, MacroArgs *Args);
+
+  /// EnterTokenStream - Add a "macro" context to the top of the include stack,
+  /// which will cause the lexer to start returning the specified tokens.
+  ///
+  /// If DisableMacroExpansion is true, tokens lexed from the token stream will
+  /// not be subject to further macro expansion.  Otherwise, these tokens will
+  /// be re-macro-expanded when/if expansion is enabled.
+  ///
+  /// If OwnsTokens is false, this method assumes that the specified stream of
+  /// tokens has a permanent owner somewhere, so they do not need to be copied.
+  /// If it is true, it assumes the array of tokens is allocated with new[] and
+  /// must be freed.
+  ///
+  void EnterTokenStream(const Token *Toks, unsigned NumToks,
+                        bool DisableMacroExpansion, bool OwnsTokens);
+
+  /// RemoveTopOfLexerStack - Pop the current lexer/macro exp off the top of the
+  /// lexer stack.  This should only be used in situations where the current
+  /// state of the top-of-stack lexer is known.
+  void RemoveTopOfLexerStack();
+
+  /// EnableBacktrackAtThisPos - From the point that this method is called, and
+  /// until CommitBacktrackedTokens() or Backtrack() is called, the Preprocessor
+  /// keeps track of the lexed tokens so that a subsequent Backtrack() call will
+  /// make the Preprocessor re-lex the same tokens.
+  ///
+  /// Nested backtracks are allowed, meaning that EnableBacktrackAtThisPos can
+  /// be called multiple times and CommitBacktrackedTokens/Backtrack calls will
+  /// be combined with the EnableBacktrackAtThisPos calls in reverse order.
+  ///
+  /// NOTE: *DO NOT* forget to call either CommitBacktrackedTokens or Backtrack
+  /// at some point after EnableBacktrackAtThisPos. If you don't, caching of
+  /// tokens will continue indefinitely.
+  ///
+  void EnableBacktrackAtThisPos();
+
+  /// CommitBacktrackedTokens - Disable the last EnableBacktrackAtThisPos call.
+  void CommitBacktrackedTokens();
+
+  /// Backtrack - Make Preprocessor re-lex the tokens that were lexed since
+  /// EnableBacktrackAtThisPos() was previously called.
+  void Backtrack();
+
+  /// isBacktrackEnabled - True if EnableBacktrackAtThisPos() was called and
+  /// caching of tokens is on.
+  bool isBacktrackEnabled() const { return !BacktrackPositions.empty(); }
+
+  /// Lex - To lex a token from the preprocessor, just pull a token from the
+  /// current lexer or macro object.
+  void Lex(Token &Result) {
+    if (CurLexer)
+      CurLexer->Lex(Result);
+    else if (CurPTHLexer)
+      CurPTHLexer->Lex(Result);
+    else if (CurTokenLexer)
+      CurTokenLexer->Lex(Result);
+    else
+      CachingLex(Result);
+  }
+
+  /// LexNonComment - Lex a token.  If it's a comment, keep lexing until we get
+  /// something not a comment.  This is useful in -E -C mode where comments
+  /// would foul up preprocessor directive handling.
+  void LexNonComment(Token &Result) {
+    do
+      Lex(Result);
+    while (Result.getKind() == tok::comment);
+  }
+
+  /// LexUnexpandedToken - This is just like Lex, but this disables macro
+  /// expansion of identifier tokens.
+  void LexUnexpandedToken(Token &Result) {
+    // Disable macro expansion.
+    bool OldVal = DisableMacroExpansion;
+    DisableMacroExpansion = true;
+    // Lex the token.
+    Lex(Result);
+
+    // Reenable it.
+    DisableMacroExpansion = OldVal;
+  }
+
+  /// LookAhead - This peeks ahead N tokens and returns that token without
+  /// consuming any tokens.  LookAhead(0) returns the next token that would be
+  /// returned by Lex(), LookAhead(1) returns the token after it, etc.  This
+  /// returns normal tokens after phase 5.  As such, it is equivalent to using
+  /// 'Lex', not 'LexUnexpandedToken'.
+  const Token &LookAhead(unsigned N) {
+    if (CachedLexPos + N < CachedTokens.size())
+      return CachedTokens[CachedLexPos+N];
+    else
+      return PeekAhead(N+1);
+  }
+
+  /// RevertCachedTokens - When backtracking is enabled and tokens are cached,
+  /// this allows to revert a specific number of tokens.
+  /// Note that the number of tokens being reverted should be up to the last
+  /// backtrack position, not more.
+  void RevertCachedTokens(unsigned N) {
+    assert(isBacktrackEnabled() &&
+           "Should only be called when tokens are cached for backtracking");
+    assert(signed(CachedLexPos) - signed(N) >= signed(BacktrackPositions.back())
+         && "Should revert tokens up to the last backtrack position, not more");
+    assert(signed(CachedLexPos) - signed(N) >= 0 &&
+           "Corrupted backtrack positions ?");
+    CachedLexPos -= N;
+  }
+
+  /// EnterToken - Enters a token in the token stream to be lexed next. If
+  /// BackTrack() is called afterwards, the token will remain at the insertion
+  /// point.
+  void EnterToken(const Token &Tok) {
+    EnterCachingLexMode();
+    CachedTokens.insert(CachedTokens.begin()+CachedLexPos, Tok);
+  }
+
+  /// AnnotateCachedTokens - We notify the Preprocessor that if it is caching
+  /// tokens (because backtrack is enabled) it should replace the most recent
+  /// cached tokens with the given annotation token. This function has no effect
+  /// if backtracking is not enabled.
+  ///
+  /// Note that the use of this function is just for optimization; so that the
+  /// cached tokens doesn't get re-parsed and re-resolved after a backtrack is
+  /// invoked.
+  void AnnotateCachedTokens(const Token &Tok) {
+    assert(Tok.isAnnotation() && "Expected annotation token");
+    if (CachedLexPos != 0 && isBacktrackEnabled())
+      AnnotatePreviousCachedTokens(Tok);
+  }
+
+  /// \brief Replace the last token with an annotation token.
+  ///
+  /// Like AnnotateCachedTokens(), this routine replaces an
+  /// already-parsed (and resolved) token with an annotation
+  /// token. However, this routine only replaces the last token with
+  /// the annotation token; it does not affect any other cached
+  /// tokens. This function has no effect if backtracking is not
+  /// enabled.
+  void ReplaceLastTokenWithAnnotation(const Token &Tok) {
+    assert(Tok.isAnnotation() && "Expected annotation token");
+    if (CachedLexPos != 0 && isBacktrackEnabled())
+      CachedTokens[CachedLexPos-1] = Tok;
+  }
+
+  /// \brief Specify the point at which code-completion will be performed.
+  ///
+  /// \param File the file in which code completion should occur. If
+  /// this file is included multiple times, code-completion will
+  /// perform completion the first time it is included. If NULL, this
+  /// function clears out the code-completion point.
+  ///
+  /// \param Line the line at which code completion should occur
+  /// (1-based).
+  ///
+  /// \param Column the column at which code completion should occur
+  /// (1-based).
+  ///
+  /// \returns true if an error occurred, false otherwise.
+  bool SetCodeCompletionPoint(const FileEntry *File,
+                              unsigned Line, unsigned Column);
+
+  /// \brief Determine if this source location refers into the file
+  /// for which we are performing code completion.
+  bool isCodeCompletionFile(SourceLocation FileLoc) const;
+
+  /// Diag - Forwarding function for diagnostics.  This emits a diagnostic at
+  /// the specified Token's location, translating the token's start
+  /// position in the current buffer into a SourcePosition object for rendering.
+  DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) {
+    return Diags->Report(FullSourceLoc(Loc, getSourceManager()), DiagID);
+  }
+
+  DiagnosticBuilder Diag(const Token &Tok, unsigned DiagID) {
+    return Diags->Report(FullSourceLoc(Tok.getLocation(), getSourceManager()),
+                         DiagID);
+  }
+
+  /// getSpelling() - Return the 'spelling' of the Tok token.  The spelling of a
+  /// token is the characters used to represent the token in the source file
+  /// after trigraph expansion and escaped-newline folding.  In particular, this
+  /// wants to get the true, uncanonicalized, spelling of things like digraphs
+  /// UCNs, etc.
+  ///
+  /// \param Invalid If non-NULL, will be set \c true if an error occurs.
+  std::string getSpelling(const Token &Tok, bool *Invalid = 0) const;
+
+  /// getSpelling() - Return the 'spelling' of the Tok token.  The spelling of a
+  /// token is the characters used to represent the token in the source file
+  /// after trigraph expansion and escaped-newline folding.  In particular, this
+  /// wants to get the true, uncanonicalized, spelling of things like digraphs
+  /// UCNs, etc.
+  static std::string getSpelling(const Token &Tok,
+                                 const SourceManager &SourceMgr,
+                                 const LangOptions &Features, 
+                                 bool *Invalid = 0);
+
+  /// getSpelling - This method is used to get the spelling of a token into a
+  /// preallocated buffer, instead of as an std::string.  The caller is required
+  /// to allocate enough space for the token, which is guaranteed to be at least
+  /// Tok.getLength() bytes long.  The length of the actual result is returned.
+  ///
+  /// Note that this method may do two possible things: it may either fill in
+  /// the buffer specified with characters, or it may *change the input pointer*
+  /// to point to a constant buffer with the data already in it (avoiding a
+  /// copy).  The caller is not allowed to modify the returned buffer pointer
+  /// if an internal buffer is returned.
+  unsigned getSpelling(const Token &Tok, const char *&Buffer, 
+                       bool *Invalid = 0) const;
+
+  /// getSpelling - This method is used to get the spelling of a token into a
+  /// SmallVector. Note that the returned StringRef may not point to the
+  /// supplied buffer if a copy can be avoided.
+  llvm::StringRef getSpelling(const Token &Tok,
+                              llvm::SmallVectorImpl<char> &Buffer, 
+                              bool *Invalid = 0) const;
+
+  /// getSpellingOfSingleCharacterNumericConstant - Tok is a numeric constant
+  /// with length 1, return the character.
+  char getSpellingOfSingleCharacterNumericConstant(const Token &Tok, 
+                                                   bool *Invalid = 0) const {
+    assert(Tok.is(tok::numeric_constant) &&
+           Tok.getLength() == 1 && "Called on unsupported token");
+    assert(!Tok.needsCleaning() && "Token can't need cleaning with length 1");
+
+    // If the token is carrying a literal data pointer, just use it.
+    if (const char *D = Tok.getLiteralData())
+      return *D;
+
+    // Otherwise, fall back on getCharacterData, which is slower, but always
+    // works.
+    return *SourceMgr.getCharacterData(Tok.getLocation(), Invalid);
+  }
+
+  /// CreateString - Plop the specified string into a scratch buffer and set the
+  /// specified token's location and length to it.  If specified, the source
+  /// location provides a location of the instantiation point of the token.
+  void CreateString(const char *Buf, unsigned Len,
+                    Token &Tok, SourceLocation SourceLoc = SourceLocation());
+
+  /// \brief Computes the source location just past the end of the
+  /// token at this source location.
+  ///
+  /// This routine can be used to produce a source location that
+  /// points just past the end of the token referenced by \p Loc, and
+  /// is generally used when a diagnostic needs to point just after a
+  /// token where it expected something different that it received. If
+  /// the returned source location would not be meaningful (e.g., if
+  /// it points into a macro), this routine returns an invalid
+  /// source location.
+  ///
+  /// \param Offset an offset from the end of the token, where the source
+  /// location should refer to. The default offset (0) produces a source
+  /// location pointing just past the end of the token; an offset of 1 produces
+  /// a source location pointing to the last character in the token, etc.
+  SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset = 0);
+
+  /// DumpToken - Print the token to stderr, used for debugging.
+  ///
+  void DumpToken(const Token &Tok, bool DumpFlags = false) const;
+  void DumpLocation(SourceLocation Loc) const;
+  void DumpMacro(const MacroInfo &MI) const;
+
+  /// AdvanceToTokenCharacter - Given a location that specifies the start of a
+  /// token, return a new location that specifies a character within the token.
+  SourceLocation AdvanceToTokenCharacter(SourceLocation TokStart,unsigned Char);
+
+  /// IncrementPasteCounter - Increment the counters for the number of token
+  /// paste operations performed.  If fast was specified, this is a 'fast paste'
+  /// case we handled.
+  ///
+  void IncrementPasteCounter(bool isFast) {
+    if (isFast)
+      ++NumFastTokenPaste;
+    else
+      ++NumTokenPaste;
+  }
+
+  void PrintStats();
+
+  /// HandleMicrosoftCommentPaste - When the macro expander pastes together a
+  /// comment (/##/) in microsoft mode, this method handles updating the current
+  /// state, returning the token on the next source line.
+  void HandleMicrosoftCommentPaste(Token &Tok);
+
+  //===--------------------------------------------------------------------===//
+  // Preprocessor callback methods.  These are invoked by a lexer as various
+  // directives and events are found.
+
+  /// LookUpIdentifierInfo - Given a tok::identifier token, look up the
+  /// identifier information for the token and install it into the token.
+  IdentifierInfo *LookUpIdentifierInfo(Token &Identifier,
+                                       const char *BufPtr = 0) const;
+
+  /// HandleIdentifier - This callback is invoked when the lexer reads an
+  /// identifier and has filled in the tokens IdentifierInfo member.  This
+  /// callback potentially macro expands it or turns it into a named token (like
+  /// 'for').
+  void HandleIdentifier(Token &Identifier);
+
+
+  /// HandleEndOfFile - This callback is invoked when the lexer hits the end of
+  /// the current file.  This either returns the EOF token and returns true, or
+  /// pops a level off the include stack and returns false, at which point the
+  /// client should call lex again.
+  bool HandleEndOfFile(Token &Result, bool isEndOfMacro = false);
+
+  /// HandleEndOfTokenLexer - This callback is invoked when the current
+  /// TokenLexer hits the end of its token stream.
+  bool HandleEndOfTokenLexer(Token &Result);
+
+  /// HandleDirective - This callback is invoked when the lexer sees a # token
+  /// at the start of a line.  This consumes the directive, modifies the
+  /// lexer/preprocessor state, and advances the lexer(s) so that the next token
+  /// read is the correct one.
+  void HandleDirective(Token &Result);
+
+  /// CheckEndOfDirective - Ensure that the next token is a tok::eom token.  If
+  /// not, emit a diagnostic and consume up until the eom.  If EnableMacros is
+  /// true, then we consider macros that expand to zero tokens as being ok.
+  void CheckEndOfDirective(const char *Directive, bool EnableMacros = false);
+
+  /// DiscardUntilEndOfDirective - Read and discard all tokens remaining on the
+  /// current line until the tok::eom token is found.
+  void DiscardUntilEndOfDirective();
+
+  /// SawDateOrTime - This returns true if the preprocessor has seen a use of
+  /// __DATE__ or __TIME__ in the file so far.
+  bool SawDateOrTime() const {
+    return DATELoc != SourceLocation() || TIMELoc != SourceLocation();
+  }
+  unsigned getCounterValue() const { return CounterValue; }
+  void setCounterValue(unsigned V) { CounterValue = V; }
+
+  /// AllocateMacroInfo - Allocate a new MacroInfo object with the provide
+  ///  SourceLocation.
+  MacroInfo* AllocateMacroInfo(SourceLocation L);
+
+  /// GetIncludeFilenameSpelling - Turn the specified lexer token into a fully
+  /// checked and spelled filename, e.g. as an operand of #include. This returns
+  /// true if the input filename was in <>'s or false if it were in ""'s.  The
+  /// caller is expected to provide a buffer that is large enough to hold the
+  /// spelling of the filename, but is also expected to handle the case when
+  /// this method decides to use a different buffer.
+  bool GetIncludeFilenameSpelling(SourceLocation Loc,llvm::StringRef &Filename);
+
+  /// LookupFile - Given a "foo" or <foo> reference, look up the indicated file,
+  /// return null on failure.  isAngled indicates whether the file reference is
+  /// for system #include's or not (i.e. using <> instead of "").
+  const FileEntry *LookupFile(llvm::StringRef Filename,
+                              bool isAngled, const DirectoryLookup *FromDir,
+                              const DirectoryLookup *&CurDir);
+
+  /// GetCurLookup - The DirectoryLookup structure used to find the current
+  /// FileEntry, if CurLexer is non-null and if applicable.  This allows us to
+  /// implement #include_next and find directory-specific properties.
+  const DirectoryLookup *GetCurDirLookup() { return CurDirLookup; }
+
+  /// isInPrimaryFile - Return true if we're in the top-level file, not in a
+  /// #include.
+  bool isInPrimaryFile() const;
+
+  /// ConcatenateIncludeName - Handle cases where the #include name is expanded
+  /// from a macro as multiple tokens, which need to be glued together.  This
+  /// occurs for code like:
+  ///    #define FOO <a/b.h>
+  ///    #include FOO
+  /// because in this case, "<a/b.h>" is returned as 7 tokens, not one.
+  ///
+  /// This code concatenates and consumes tokens up to the '>' token.  It returns
+  /// false if the > was found, otherwise it returns true if it finds and consumes
+  /// the EOM marker.
+  bool ConcatenateIncludeName(llvm::SmallString<128> &FilenameBuffer);
+
+private:
+
+  void PushIncludeMacroStack() {
+    IncludeMacroStack.push_back(IncludeStackInfo(CurLexer.take(),
+                                                 CurPTHLexer.take(),
+                                                 CurPPLexer,
+                                                 CurTokenLexer.take(),
+                                                 CurDirLookup));
+    CurPPLexer = 0;
+  }
+
+  void PopIncludeMacroStack() {
+    CurLexer.reset(IncludeMacroStack.back().TheLexer);
+    CurPTHLexer.reset(IncludeMacroStack.back().ThePTHLexer);
+    CurPPLexer = IncludeMacroStack.back().ThePPLexer;
+    CurTokenLexer.reset(IncludeMacroStack.back().TheTokenLexer);
+    CurDirLookup  = IncludeMacroStack.back().TheDirLookup;
+    IncludeMacroStack.pop_back();
+  }
+
+  /// ReleaseMacroInfo - Release the specified MacroInfo.  This memory will
+  ///  be reused for allocating new MacroInfo objects.
+  void ReleaseMacroInfo(MacroInfo* MI);
+
+  /// ReadMacroName - Lex and validate a macro name, which occurs after a
+  /// #define or #undef.  This emits a diagnostic, sets the token kind to eom,
+  /// and discards the rest of the macro line if the macro name is invalid.
+  void ReadMacroName(Token &MacroNameTok, char isDefineUndef = 0);
+
+  /// ReadMacroDefinitionArgList - The ( starting an argument list of a macro
+  /// definition has just been read.  Lex the rest of the arguments and the
+  /// closing ), updating MI with what we learn.  Return true if an error occurs
+  /// parsing the arg list.
+  bool ReadMacroDefinitionArgList(MacroInfo *MI);
+
+  /// SkipExcludedConditionalBlock - We just read a #if or related directive and
+  /// decided that the subsequent tokens are in the #if'd out portion of the
+  /// file.  Lex the rest of the file, until we see an #endif.  If
+  /// FoundNonSkipPortion is true, then we have already emitted code for part of
+  /// this #if directive, so #else/#elif blocks should never be entered. If
+  /// FoundElse is false, then #else directives are ok, if not, then we have
+  /// already seen one so a #else directive is a duplicate.  When this returns,
+  /// the caller can lex the first valid token.
+  void SkipExcludedConditionalBlock(SourceLocation IfTokenLoc,
+                                    bool FoundNonSkipPortion, bool FoundElse);
+
+  /// PTHSkipExcludedConditionalBlock - A fast PTH version of
+  ///  SkipExcludedConditionalBlock.
+  void PTHSkipExcludedConditionalBlock();
+
+  /// EvaluateDirectiveExpression - Evaluate an integer constant expression that
+  /// may occur after a #if or #elif directive and return it as a bool.  If the
+  /// expression is equivalent to "!defined(X)" return X in IfNDefMacro.
+  bool EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro);
+
+  /// RegisterBuiltinPragmas - Install the standard preprocessor pragmas:
+  /// #pragma GCC poison/system_header/dependency and #pragma once.
+  void RegisterBuiltinPragmas();
+
+  /// RegisterBuiltinMacros - Register builtin macros, such as __LINE__ with the
+  /// identifier table.
+  void RegisterBuiltinMacros();
+
+  /// HandleMacroExpandedIdentifier - If an identifier token is read that is to
+  /// be expanded as a macro, handle it and return the next token as 'Tok'.  If
+  /// the macro should not be expanded return true, otherwise return false.
+  bool HandleMacroExpandedIdentifier(Token &Tok, MacroInfo *MI);
+
+  /// isNextPPTokenLParen - Determine whether the next preprocessor token to be
+  /// lexed is a '('.  If so, consume the token and return true, if not, this
+  /// method should have no observable side-effect on the lexed tokens.
+  bool isNextPPTokenLParen();
+
+  /// ReadFunctionLikeMacroArgs - After reading "MACRO(", this method is
+  /// invoked to read all of the formal arguments specified for the macro
+  /// invocation.  This returns null on error.
+  MacroArgs *ReadFunctionLikeMacroArgs(Token &MacroName, MacroInfo *MI,
+                                       SourceLocation &InstantiationEnd);
+
+  /// ExpandBuiltinMacro - If an identifier token is read that is to be expanded
+  /// as a builtin macro, handle it and return the next token as 'Tok'.
+  void ExpandBuiltinMacro(Token &Tok);
+
+  /// Handle_Pragma - Read a _Pragma directive, slice it up, process it, then
+  /// return the first token after the directive.  The _Pragma token has just
+  /// been read into 'Tok'.
+  void Handle_Pragma(Token &Tok);
+
+  /// EnterSourceFileWithLexer - Add a lexer to the top of the include stack and
+  /// start lexing tokens from it instead of the current buffer.
+  void EnterSourceFileWithLexer(Lexer *TheLexer, const DirectoryLookup *Dir);
+
+  /// EnterSourceFileWithPTH - Add a lexer to the top of the include stack and
+  /// start getting tokens from it using the PTH cache.
+  void EnterSourceFileWithPTH(PTHLexer *PL, const DirectoryLookup *Dir);
+
+  /// IsFileLexer - Returns true if we are lexing from a file and not a
+  ///  pragma or a macro.
+  static bool IsFileLexer(const Lexer* L, const PreprocessorLexer* P) {
+    return L ? !L->isPragmaLexer() : P != 0;
+  }
+
+  static bool IsFileLexer(const IncludeStackInfo& I) {
+    return IsFileLexer(I.TheLexer, I.ThePPLexer);
+  }
+
+  bool IsFileLexer() const {
+    return IsFileLexer(CurLexer.get(), CurPPLexer);
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Caching stuff.
+  void CachingLex(Token &Result);
+  bool InCachingLexMode() const { return CurPPLexer == 0 && CurTokenLexer == 0;}
+  void EnterCachingLexMode();
+  void ExitCachingLexMode() {
+    if (InCachingLexMode())
+      RemoveTopOfLexerStack();
+  }
+  const Token &PeekAhead(unsigned N);
+  void AnnotatePreviousCachedTokens(const Token &Tok);
+
+  //===--------------------------------------------------------------------===//
+  /// Handle*Directive - implement the various preprocessor directives.  These
+  /// should side-effect the current preprocessor object so that the next call
+  /// to Lex() will return the appropriate token next.
+  void HandleLineDirective(Token &Tok);
+  void HandleDigitDirective(Token &Tok);
+  void HandleUserDiagnosticDirective(Token &Tok, bool isWarning);
+  void HandleIdentSCCSDirective(Token &Tok);
+
+  // File inclusion.
+  void HandleIncludeDirective(Token &Tok,
+                              const DirectoryLookup *LookupFrom = 0,
+                              bool isImport = false);
+  void HandleIncludeNextDirective(Token &Tok);
+  void HandleIncludeMacrosDirective(Token &Tok);
+  void HandleImportDirective(Token &Tok);
+
+  // Macro handling.
+  void HandleDefineDirective(Token &Tok);
+  void HandleUndefDirective(Token &Tok);
+  // HandleAssertDirective(Token &Tok);
+  // HandleUnassertDirective(Token &Tok);
+
+  // Conditional Inclusion.
+  void HandleIfdefDirective(Token &Tok, bool isIfndef,
+                            bool ReadAnyTokensBeforeDirective);
+  void HandleIfDirective(Token &Tok, bool ReadAnyTokensBeforeDirective);
+  void HandleEndifDirective(Token &Tok);
+  void HandleElseDirective(Token &Tok);
+  void HandleElifDirective(Token &Tok);
+
+  // Pragmas.
+  void HandlePragmaDirective();
+public:
+  void HandlePragmaOnce(Token &OnceTok);
+  void HandlePragmaMark();
+  void HandlePragmaPoison(Token &PoisonTok);
+  void HandlePragmaSystemHeader(Token &SysHeaderTok);
+  void HandlePragmaDependency(Token &DependencyTok);
+  void HandlePragmaComment(Token &CommentTok);
+  // Return true and store the first token only if any CommentHandler
+  // has inserted some tokens and getCommentRetentionState() is false.
+  bool HandleComment(Token &Token, SourceRange Comment);
+};
+
+/// \brief Abstract base class that describes a handler that will receive
+/// source ranges for each of the comments encountered in the source file.
+class CommentHandler {
+public:
+  virtual ~CommentHandler();
+
+  // The handler shall return true if it has pushed any tokens
+  // to be read using e.g. EnterToken or EnterTokenStream.
+  virtual bool HandleComment(Preprocessor &PP, SourceRange Comment) = 0;
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Lex/PreprocessorLexer.h b/include/clang/Lex/PreprocessorLexer.h
new file mode 100644
index 0000000..477a213
--- /dev/null
+++ b/include/clang/Lex/PreprocessorLexer.h
@@ -0,0 +1,162 @@
+//===--- PreprocessorLexer.h - C Language Family Lexer ----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the PreprocessorLexer interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_PreprocessorLexer_H
+#define LLVM_CLANG_PreprocessorLexer_H
+
+#include "clang/Lex/MultipleIncludeOpt.h"
+#include "clang/Lex/Token.h"
+#include "llvm/ADT/SmallVector.h"
+#include <string>
+
+namespace clang {
+
+class FileEntry;
+class Preprocessor;
+
+class PreprocessorLexer {
+protected:
+  Preprocessor *PP;              // Preprocessor object controlling lexing.
+
+  /// The SourceManager FileID corresponding to the file being lexed.
+  const FileID FID;
+
+  //===--------------------------------------------------------------------===//
+  // Context-specific lexing flags set by the preprocessor.
+  //===--------------------------------------------------------------------===//
+
+  /// ParsingPreprocessorDirective - This is true when parsing #XXX.  This turns
+  /// '\n' into a tok::eom token.
+  bool ParsingPreprocessorDirective;
+
+  /// ParsingFilename - True after #include: this turns <xx> into a
+  /// tok::angle_string_literal token.
+  bool ParsingFilename;
+
+  /// LexingRawMode - True if in raw mode:  This flag disables interpretation of
+  /// tokens and is a far faster mode to lex in than non-raw-mode.  This flag:
+  ///  1. If EOF of the current lexer is found, the include stack isn't popped.
+  ///  2. Identifier information is not looked up for identifier tokens.  As an
+  ///     effect of this, implicit macro expansion is naturally disabled.
+  ///  3. "#" tokens at the start of a line are treated as normal tokens, not
+  ///     implicitly transformed by the lexer.
+  ///  4. All diagnostic messages are disabled.
+  ///  5. No callbacks are made into the preprocessor.
+  ///
+  /// Note that in raw mode that the PP pointer may be null.
+  bool LexingRawMode;
+
+  /// MIOpt - This is a state machine that detects the #ifndef-wrapping a file
+  /// idiom for the multiple-include optimization.
+  MultipleIncludeOpt MIOpt;
+
+  /// ConditionalStack - Information about the set of #if/#ifdef/#ifndef blocks
+  /// we are currently in.
+  llvm::SmallVector<PPConditionalInfo, 4> ConditionalStack;
+
+  PreprocessorLexer(const PreprocessorLexer&);          // DO NOT IMPLEMENT
+  void operator=(const PreprocessorLexer&); // DO NOT IMPLEMENT
+  friend class Preprocessor;
+
+  PreprocessorLexer(Preprocessor *pp, FileID fid)
+    : PP(pp), FID(fid), ParsingPreprocessorDirective(false),
+      ParsingFilename(false), LexingRawMode(false) {}
+
+  PreprocessorLexer()
+    : PP(0),
+      ParsingPreprocessorDirective(false),
+      ParsingFilename(false),
+      LexingRawMode(false) {}
+
+  virtual ~PreprocessorLexer() {}
+
+  virtual void IndirectLex(Token& Result) = 0;
+
+  /// getSourceLocation - Return the source location for the next observable
+  ///  location.
+  virtual SourceLocation getSourceLocation() = 0;
+
+  //===--------------------------------------------------------------------===//
+  // #if directive handling.
+
+  /// pushConditionalLevel - When we enter a #if directive, this keeps track of
+  /// what we are currently in for diagnostic emission (e.g. #if with missing
+  /// #endif).
+  void pushConditionalLevel(SourceLocation DirectiveStart, bool WasSkipping,
+                            bool FoundNonSkip, bool FoundElse) {
+    PPConditionalInfo CI;
+    CI.IfLoc = DirectiveStart;
+    CI.WasSkipping = WasSkipping;
+    CI.FoundNonSkip = FoundNonSkip;
+    CI.FoundElse = FoundElse;
+    ConditionalStack.push_back(CI);
+  }
+  void pushConditionalLevel(const PPConditionalInfo &CI) {
+    ConditionalStack.push_back(CI);
+  }
+
+  /// popConditionalLevel - Remove an entry off the top of the conditional
+  /// stack, returning information about it.  If the conditional stack is empty,
+  /// this returns true and does not fill in the arguments.
+  bool popConditionalLevel(PPConditionalInfo &CI) {
+    if (ConditionalStack.empty()) return true;
+    CI = ConditionalStack.back();
+    ConditionalStack.pop_back();
+    return false;
+  }
+
+  /// peekConditionalLevel - Return the top of the conditional stack.  This
+  /// requires that there be a conditional active.
+  PPConditionalInfo &peekConditionalLevel() {
+    assert(!ConditionalStack.empty() && "No conditionals active!");
+    return ConditionalStack.back();
+  }
+
+  unsigned getConditionalStackDepth() const { return ConditionalStack.size(); }
+
+public:
+
+  //===--------------------------------------------------------------------===//
+  // Misc. lexing methods.
+
+  /// LexIncludeFilename - After the preprocessor has parsed a #include, lex and
+  /// (potentially) macro expand the filename.  If the sequence parsed is not
+  /// lexically legal, emit a diagnostic and return a result EOM token.
+  void LexIncludeFilename(Token &Result);
+
+  /// setParsingPreprocessorDirective - Inform the lexer whether or not
+  ///  we are currently lexing a preprocessor directive.
+  void setParsingPreprocessorDirective(bool f) {
+    ParsingPreprocessorDirective = f;
+  }
+
+  /// isLexingRawMode - Return true if this lexer is in raw mode or not.
+  bool isLexingRawMode() const { return LexingRawMode; }
+
+  /// getPP - Return the preprocessor object for this lexer.
+  Preprocessor *getPP() const { return PP; }
+
+  FileID getFileID() const {
+    assert(PP &&
+      "PreprocessorLexer::getFileID() should only be used with a Preprocessor");
+    return FID;
+  }
+
+  /// getFileEntry - Return the FileEntry corresponding to this FileID.  Like
+  /// getFileID(), this only works for lexers with attached preprocessors.
+  const FileEntry *getFileEntry() const;
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Lex/ScratchBuffer.h b/include/clang/Lex/ScratchBuffer.h
new file mode 100644
index 0000000..f03515f
--- /dev/null
+++ b/include/clang/Lex/ScratchBuffer.h
@@ -0,0 +1,45 @@
+//===--- ScratchBuffer.h - Scratch space for forming tokens -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the ScratchBuffer interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SCRATCHBUFFER_H
+#define LLVM_CLANG_SCRATCHBUFFER_H
+
+#include "clang/Basic/SourceLocation.h"
+
+namespace clang {
+  class SourceManager;
+
+/// ScratchBuffer - This class exposes a simple interface for the dynamic
+/// construction of tokens.  This is used for builtin macros (e.g. __LINE__) as
+/// well as token pasting, etc.
+class ScratchBuffer {
+  SourceManager &SourceMgr;
+  char *CurBuffer;
+  SourceLocation BufferStartLoc;
+  unsigned BytesUsed;
+public:
+  ScratchBuffer(SourceManager &SM);
+
+  /// getToken - Splat the specified text into a temporary MemoryBuffer and
+  /// return a SourceLocation that refers to the token.  This is just like the
+  /// previous method, but returns a location that indicates the physloc of the
+  /// token.
+  SourceLocation getToken(const char *Buf, unsigned Len, const char *&DestPtr);
+
+private:
+  void AllocScratchBuffer(unsigned RequestLen);
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Lex/Token.h b/include/clang/Lex/Token.h
new file mode 100644
index 0000000..b5dde9a
--- /dev/null
+++ b/include/clang/Lex/Token.h
@@ -0,0 +1,257 @@
+//===--- Token.h - Token interface ------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the Token interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOKEN_H
+#define LLVM_CLANG_TOKEN_H
+
+#include "clang/Basic/TemplateKinds.h"
+#include "clang/Basic/TokenKinds.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/OperatorKinds.h"
+#include <cstdlib>
+
+namespace clang {
+
+class IdentifierInfo;
+
+/// Token - This structure provides full information about a lexed token.
+/// It is not intended to be space efficient, it is intended to return as much
+/// information as possible about each returned token.  This is expected to be
+/// compressed into a smaller form if memory footprint is important.
+///
+/// The parser can create a special "annotation token" representing a stream of
+/// tokens that were parsed and semantically resolved, e.g.: "foo::MyClass<int>"
+/// can be represented by a single typename annotation token that carries
+/// information about the SourceRange of the tokens and the type object.
+class Token {
+  /// The location of the token.
+  SourceLocation Loc;
+
+  // Conceptually these next two fields could be in a union.  However, this
+  // causes gcc 4.2 to pessimize LexTokenInternal, a very performance critical
+  // routine. Keeping as separate members with casts until a more beautiful fix
+  // presents itself.
+
+  /// UintData - This holds either the length of the token text, when
+  /// a normal token, or the end of the SourceRange when an annotation
+  /// token.
+  unsigned UintData;
+
+  /// PtrData - This is a union of four different pointer types, which depends
+  /// on what type of token this is:
+  ///  Identifiers, keywords, etc:
+  ///    This is an IdentifierInfo*, which contains the uniqued identifier
+  ///    spelling.
+  ///  Literals:  isLiteral() returns true.
+  ///    This is a pointer to the start of the token in a text buffer, which
+  ///    may be dirty (have trigraphs / escaped newlines).
+  ///  Annotations (resolved type names, C++ scopes, etc): isAnnotation().
+  ///    This is a pointer to sema-specific data for the annotation token.
+  ///  Other:
+  ///    This is null.
+  void *PtrData;
+
+  /// Kind - The actual flavor of token this is.
+  ///
+  unsigned char Kind; // DON'T make Kind a 'tok::TokenKind';
+                      // MSVC will treat it as a signed char and
+                      // TokenKinds > 127 won't be handled correctly.
+
+  /// Flags - Bits we track about this token, members of the TokenFlags enum.
+  unsigned char Flags;
+public:
+
+  // Various flags set per token:
+  enum TokenFlags {
+    StartOfLine   = 0x01,  // At start of line or only after whitespace.
+    LeadingSpace  = 0x02,  // Whitespace exists before this token.
+    DisableExpand = 0x04,  // This identifier may never be macro expanded.
+    NeedsCleaning = 0x08   // Contained an escaped newline or trigraph.
+  };
+
+  tok::TokenKind getKind() const { return (tok::TokenKind)Kind; }
+  void setKind(tok::TokenKind K) { Kind = K; }
+
+  /// is/isNot - Predicates to check if this token is a specific kind, as in
+  /// "if (Tok.is(tok::l_brace)) {...}".
+  bool is(tok::TokenKind K) const { return Kind == (unsigned) K; }
+  bool isNot(tok::TokenKind K) const { return Kind != (unsigned) K; }
+
+  /// isLiteral - Return true if this is a "literal", like a numeric
+  /// constant, string, etc.
+  bool isLiteral() const {
+    return is(tok::numeric_constant) || is(tok::char_constant) ||
+           is(tok::string_literal) || is(tok::wide_string_literal) ||
+           is(tok::angle_string_literal);
+  }
+
+  bool isAnnotation() const {
+    return is(tok::annot_typename) ||
+           is(tok::annot_cxxscope) ||
+           is(tok::annot_template_id);
+  }
+
+  /// getLocation - Return a source location identifier for the specified
+  /// offset in the current file.
+  SourceLocation getLocation() const { return Loc; }
+  unsigned getLength() const {
+    assert(!isAnnotation() && "Annotation tokens have no length field");
+    return UintData;
+  }
+
+  void setLocation(SourceLocation L) { Loc = L; }
+  void setLength(unsigned Len) {
+    assert(!isAnnotation() && "Annotation tokens have no length field");
+    UintData = Len;
+  }
+
+  SourceLocation getAnnotationEndLoc() const {
+    assert(isAnnotation() && "Used AnnotEndLocID on non-annotation token");
+    return SourceLocation::getFromRawEncoding(UintData);
+  }
+  void setAnnotationEndLoc(SourceLocation L) {
+    assert(isAnnotation() && "Used AnnotEndLocID on non-annotation token");
+    UintData = L.getRawEncoding();
+  }
+
+  SourceLocation getLastLoc() const {
+    return isAnnotation() ? getAnnotationEndLoc() : getLocation();
+  }
+
+  /// getAnnotationRange - SourceRange of the group of tokens that this
+  /// annotation token represents.
+  SourceRange getAnnotationRange() const {
+    return SourceRange(getLocation(), getAnnotationEndLoc());
+  }
+  void setAnnotationRange(SourceRange R) {
+    setLocation(R.getBegin());
+    setAnnotationEndLoc(R.getEnd());
+  }
+
+  const char *getName() const {
+    return tok::getTokenName( (tok::TokenKind) Kind);
+  }
+
+  /// startToken - Reset all flags to cleared.
+  ///
+  void startToken() {
+    Kind = tok::unknown;
+    Flags = 0;
+    PtrData = 0;
+    Loc = SourceLocation();
+  }
+
+  IdentifierInfo *getIdentifierInfo() const {
+    assert(!isAnnotation() && "Used IdentInfo on annotation token!");
+    if (isLiteral()) return 0;
+    return (IdentifierInfo*) PtrData;
+  }
+  void setIdentifierInfo(IdentifierInfo *II) {
+    PtrData = (void*) II;
+  }
+
+  /// getLiteralData - For a literal token (numeric constant, string, etc), this
+  /// returns a pointer to the start of it in the text buffer if known, null
+  /// otherwise.
+  const char *getLiteralData() const {
+    assert(isLiteral() && "Cannot get literal data of non-literal");
+    return reinterpret_cast<const char*>(PtrData);
+  }
+  void setLiteralData(const char *Ptr) {
+    assert(isLiteral() && "Cannot set literal data of non-literal");
+    PtrData = (void*)Ptr;
+  }
+
+  void *getAnnotationValue() const {
+    assert(isAnnotation() && "Used AnnotVal on non-annotation token");
+    return PtrData;
+  }
+  void setAnnotationValue(void *val) {
+    assert(isAnnotation() && "Used AnnotVal on non-annotation token");
+    PtrData = val;
+  }
+
+  /// setFlag - Set the specified flag.
+  void setFlag(TokenFlags Flag) {
+    Flags |= Flag;
+  }
+
+  /// clearFlag - Unset the specified flag.
+  void clearFlag(TokenFlags Flag) {
+    Flags &= ~Flag;
+  }
+
+  /// getFlags - Return the internal represtation of the flags.
+  ///  Only intended for low-level operations such as writing tokens to
+  //   disk.
+  unsigned getFlags() const {
+    return Flags;
+  }
+
+  /// setFlagValue - Set a flag to either true or false.
+  void setFlagValue(TokenFlags Flag, bool Val) {
+    if (Val)
+      setFlag(Flag);
+    else
+      clearFlag(Flag);
+  }
+
+  /// isAtStartOfLine - Return true if this token is at the start of a line.
+  ///
+  bool isAtStartOfLine() const { return (Flags & StartOfLine) ? true : false; }
+
+  /// hasLeadingSpace - Return true if this token has whitespace before it.
+  ///
+  bool hasLeadingSpace() const { return (Flags & LeadingSpace) ? true : false; }
+
+  /// isExpandDisabled - Return true if this identifier token should never
+  /// be expanded in the future, due to C99 6.10.3.4p2.
+  bool isExpandDisabled() const {
+    return (Flags & DisableExpand) ? true : false;
+  }
+
+  /// isObjCAtKeyword - Return true if we have an ObjC keyword identifier.
+  bool isObjCAtKeyword(tok::ObjCKeywordKind objcKey) const;
+
+  /// getObjCKeywordID - Return the ObjC keyword kind.
+  tok::ObjCKeywordKind getObjCKeywordID() const;
+
+  /// needsCleaning - Return true if this token has trigraphs or escaped
+  /// newlines in it.
+  ///
+  bool needsCleaning() const { return (Flags & NeedsCleaning) ? true : false; }
+};
+
+/// PPConditionalInfo - Information about the conditional stack (#if directives)
+/// currently active.
+struct PPConditionalInfo {
+  /// IfLoc - Location where the conditional started.
+  ///
+  SourceLocation IfLoc;
+
+  /// WasSkipping - True if this was contained in a skipping directive, e.g.
+  /// in a "#if 0" block.
+  bool WasSkipping;
+
+  /// FoundNonSkip - True if we have emitted tokens already, and now we're in
+  /// an #else block or something.  Only useful in Skipping blocks.
+  bool FoundNonSkip;
+
+  /// FoundElse - True if we've seen a #else in this block.  If so,
+  /// #elif/#else directives are not allowed.
+  bool FoundElse;
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Lex/TokenConcatenation.h b/include/clang/Lex/TokenConcatenation.h
new file mode 100644
index 0000000..094990a
--- /dev/null
+++ b/include/clang/Lex/TokenConcatenation.h
@@ -0,0 +1,75 @@
+//===--- TokenConcatenation.h - Token Concatenation Avoidance ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the TokenConcatenation class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_LEX_TOKEN_CONCATENATION_H
+#define CLANG_LEX_TOKEN_CONCATENATION_H
+
+#include "clang/Basic/TokenKinds.h"
+
+namespace clang {
+  class Preprocessor;
+  class Token;
+
+  /// TokenConcatenation class, which answers the question of
+  ///   "Is it safe to emit two tokens without a whitespace between them, or
+  ///    would that cause implicit concatenation of the tokens?"
+  ///
+  /// For example, it emitting two identifiers "foo" and "bar" next to each
+  /// other would cause the lexer to produce one "foobar" token.  Emitting "1"
+  /// and ")" next to each other is safe.
+  ///
+  class TokenConcatenation {
+    Preprocessor &PP;
+
+    enum AvoidConcatInfo {
+      /// By default, a token never needs to avoid concatenation.  Most tokens
+      /// (e.g. ',', ')', etc) don't cause a problem when concatenated.
+      aci_never_avoid_concat = 0,
+
+      /// aci_custom_firstchar - AvoidConcat contains custom code to handle this
+      /// token's requirements, and it needs to know the first character of the
+      /// token.
+      aci_custom_firstchar = 1,
+
+      /// aci_custom - AvoidConcat contains custom code to handle this token's
+      /// requirements, but it doesn't need to know the first character of the
+      /// token.
+      aci_custom = 2,
+
+      /// aci_avoid_equal - Many tokens cannot be safely followed by an '='
+      /// character.  For example, "<<" turns into "<<=" when followed by an =.
+      aci_avoid_equal = 4
+    };
+
+    /// TokenInfo - This array contains information for each token on what
+    /// action to take when avoiding concatenation of tokens in the AvoidConcat
+    /// method.
+    char TokenInfo[tok::NUM_TOKENS];
+  public:
+    TokenConcatenation(Preprocessor &PP);
+
+    bool AvoidConcat(const Token &PrevPrevTok, 
+                     const Token &PrevTok, 
+                     const Token &Tok) const;
+
+  private:
+    /// StartsWithL - Return true if the spelling of this token starts with 'L'.
+    bool StartsWithL(const Token &Tok) const;
+
+    /// IsIdentifierL - Return true if the spelling of this token is literally
+    /// 'L'.
+    bool IsIdentifierL(const Token &Tok) const;
+  };
+  } // end clang namespace
+
+#endif
diff --git a/include/clang/Lex/TokenLexer.h b/include/clang/Lex/TokenLexer.h
new file mode 100644
index 0000000..3f13e9c
--- /dev/null
+++ b/include/clang/Lex/TokenLexer.h
@@ -0,0 +1,154 @@
+//===--- TokenLexer.h - Lex from a token buffer -----------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the TokenLexer interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOKENLEXER_H
+#define LLVM_CLANG_TOKENLEXER_H
+
+#include "clang/Basic/SourceLocation.h"
+
+namespace clang {
+  class MacroInfo;
+  class Preprocessor;
+  class Token;
+  class MacroArgs;
+
+/// TokenLexer - This implements a lexer that returns token from a macro body
+/// or token stream instead of lexing from a character buffer.  This is used for
+/// macro expansion and _Pragma handling, for example.
+///
+class TokenLexer {
+  /// Macro - The macro we are expanding from.  This is null if expanding a
+  /// token stream.
+  ///
+  MacroInfo *Macro;
+
+  /// ActualArgs - The actual arguments specified for a function-like macro, or
+  /// null.  The TokenLexer owns the pointed-to object.
+  MacroArgs *ActualArgs;
+
+  /// PP - The current preprocessor object we are expanding for.
+  ///
+  Preprocessor &PP;
+
+  /// Tokens - This is the pointer to an array of tokens that the macro is
+  /// defined to, with arguments expanded for function-like macros.  If this is
+  /// a token stream, these are the tokens we are returning.  This points into
+  /// the macro definition we are lexing from, a scratch buffer allocated from
+  /// the preprocessor's bump pointer allocator, or some other buffer that we
+  /// may or may not own (depending on OwnsTokens).
+  const Token *Tokens;
+
+  /// NumTokens - This is the length of the Tokens array.
+  ///
+  unsigned NumTokens;
+
+  /// CurToken - This is the next token that Lex will return.
+  ///
+  unsigned CurToken;
+
+  /// InstantiateLocStart/End - The source location range where this macro was
+  /// instantiated.
+  SourceLocation InstantiateLocStart, InstantiateLocEnd;
+
+  /// Lexical information about the expansion point of the macro: the identifier
+  /// that the macro expanded from had these properties.
+  bool AtStartOfLine : 1;
+  bool HasLeadingSpace : 1;
+
+  /// OwnsTokens - This is true if this TokenLexer allocated the Tokens
+  /// array, and thus needs to free it when destroyed.  For simple object-like
+  /// macros (for example) we just point into the token buffer of the macro
+  /// definition, we don't make a copy of it.
+  bool OwnsTokens : 1;
+
+  /// DisableMacroExpansion - This is true when tokens lexed from the TokenLexer
+  /// should not be subject to further macro expansion.
+  bool DisableMacroExpansion : 1;
+
+  TokenLexer(const TokenLexer&);  // DO NOT IMPLEMENT
+  void operator=(const TokenLexer&); // DO NOT IMPLEMENT
+public:
+  /// Create a TokenLexer for the specified macro with the specified actual
+  /// arguments.  Note that this ctor takes ownership of the ActualArgs pointer.
+  /// ILEnd specifies the location of the ')' for a function-like macro or the
+  /// identifier for an object-like macro.
+  TokenLexer(Token &Tok, SourceLocation ILEnd, MacroArgs *ActualArgs,
+             Preprocessor &pp)
+    : Macro(0), ActualArgs(0), PP(pp), OwnsTokens(false) {
+    Init(Tok, ILEnd, ActualArgs);
+  }
+
+  /// Init - Initialize this TokenLexer to expand from the specified macro
+  /// with the specified argument information.  Note that this ctor takes
+  /// ownership of the ActualArgs pointer.  ILEnd specifies the location of the
+  /// ')' for a function-like macro or the identifier for an object-like macro.
+  void Init(Token &Tok, SourceLocation ILEnd, MacroArgs *ActualArgs);
+
+  /// Create a TokenLexer for the specified token stream.  If 'OwnsTokens' is
+  /// specified, this takes ownership of the tokens and delete[]'s them when
+  /// the token lexer is empty.
+  TokenLexer(const Token *TokArray, unsigned NumToks, bool DisableExpansion,
+             bool ownsTokens, Preprocessor &pp)
+    : Macro(0), ActualArgs(0), PP(pp), OwnsTokens(false) {
+    Init(TokArray, NumToks, DisableExpansion, ownsTokens);
+  }
+
+  /// Init - Initialize this TokenLexer with the specified token stream.
+  /// This does not take ownership of the specified token vector.
+  ///
+  /// DisableExpansion is true when macro expansion of tokens lexed from this
+  /// stream should be disabled.
+  void Init(const Token *TokArray, unsigned NumToks,
+            bool DisableMacroExpansion, bool OwnsTokens);
+
+  ~TokenLexer() { destroy(); }
+
+  /// isNextTokenLParen - If the next token lexed will pop this macro off the
+  /// expansion stack, return 2.  If the next unexpanded token is a '(', return
+  /// 1, otherwise return 0.
+  unsigned isNextTokenLParen() const;
+
+  /// Lex - Lex and return a token from this macro stream.
+  void Lex(Token &Tok);
+
+private:
+  void destroy();
+
+  /// isAtEnd - Return true if the next lex call will pop this macro off the
+  /// include stack.
+  bool isAtEnd() const {
+    return CurToken == NumTokens;
+  }
+
+  /// PasteTokens - Tok is the LHS of a ## operator, and CurToken is the ##
+  /// operator.  Read the ## and RHS, and paste the LHS/RHS together.  If there
+  /// are is another ## after it, chomp it iteratively.  Return the result as
+  /// Tok.  If this returns true, the caller should immediately return the
+  /// token.
+  bool PasteTokens(Token &Tok);
+
+  /// Expand the arguments of a function-like macro so that we can quickly
+  /// return preexpanded tokens from Tokens.
+  void ExpandFunctionArguments();
+
+  /// HandleMicrosoftCommentPaste - In microsoft compatibility mode, /##/ pastes
+  /// together to form a comment that comments out everything in the current
+  /// macro, other active macros, and anything left on the current physical
+  /// source line of the instantiated buffer.  Handle this by returning the
+  /// first token on the next line.
+  void HandleMicrosoftCommentPaste(Token &Tok);
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Makefile b/include/clang/Makefile
new file mode 100644
index 0000000..624292a
--- /dev/null
+++ b/include/clang/Makefile
@@ -0,0 +1,4 @@
+LEVEL = ../../../..
+DIRS := Basic Driver
+
+include $(LEVEL)/Makefile.common
diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h
new file mode 100644
index 0000000..6b16522
--- /dev/null
+++ b/include/clang/Parse/Action.h
@@ -0,0 +1,3073 @@
+//===--- Action.h - Parser Action Interface ---------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the Action and EmptyAction interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_PARSE_ACTION_H
+#define LLVM_CLANG_PARSE_ACTION_H
+
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/Specifiers.h"
+#include "clang/Basic/TemplateKinds.h"
+#include "clang/Basic/TypeTraits.h"
+#include "clang/Parse/DeclSpec.h"
+#include "clang/Parse/Ownership.h"
+#include "llvm/Support/PrettyStackTrace.h"
+#include "llvm/ADT/PointerUnion.h"
+
+namespace clang {
+  // Semantic.
+  class DeclSpec;
+  class ObjCDeclSpec;
+  class CXXScopeSpec;
+  class Declarator;
+  class AttributeList;
+  struct FieldDeclarator;
+  // Parse.
+  class Scope;
+  class Action;
+  class Selector;
+  class Designation;
+  class InitListDesignations;
+  // Lex.
+  class Preprocessor;
+  class Token;
+
+  // We can re-use the low bit of expression, statement, base, and
+  // member-initializer pointers for the "invalid" flag of
+  // ActionResult.
+  template<> struct IsResultPtrLowBitFree<0> { static const bool value = true;};
+  template<> struct IsResultPtrLowBitFree<1> { static const bool value = true;};
+  template<> struct IsResultPtrLowBitFree<3> { static const bool value = true;};
+  template<> struct IsResultPtrLowBitFree<4> { static const bool value = true;};
+  template<> struct IsResultPtrLowBitFree<5> { static const bool value = true;};
+
+/// Action - As the parser reads the input file and recognizes the productions
+/// of the grammar, it invokes methods on this class to turn the parsed input
+/// into something useful: e.g. a parse tree.
+///
+/// The callback methods that this class provides are phrased as actions that
+/// the parser has just done or is about to do when the method is called.  They
+/// are not requests that the actions module do the specified action.
+///
+/// All of the methods here are optional except getTypeName() and
+/// isCurrentClassName(), which must be specified in order for the
+/// parse to complete accurately.  The MinimalAction class does this
+/// bare-minimum of tracking to implement this functionality.
+class Action : public ActionBase {
+public:
+  /// Out-of-line virtual destructor to provide home for this class.
+  virtual ~Action();
+
+  // Types - Though these don't actually enforce strong typing, they document
+  // what types are required to be identical for the actions.
+  typedef ActionBase::ExprTy ExprTy;
+  typedef ActionBase::StmtTy StmtTy;
+
+  /// Expr/Stmt/Type/BaseResult - Provide a unique type to wrap
+  /// ExprTy/StmtTy/TypeTy/BaseTy, providing strong typing and
+  /// allowing for failure.
+  typedef ActionResult<0> ExprResult;
+  typedef ActionResult<1> StmtResult;
+  typedef ActionResult<2> TypeResult;
+  typedef ActionResult<3> BaseResult;
+  typedef ActionResult<4> MemInitResult;
+  typedef ActionResult<5, DeclPtrTy> DeclResult;
+
+  /// Same, but with ownership.
+  typedef ASTOwningResult<&ActionBase::DeleteExpr> OwningExprResult;
+  typedef ASTOwningResult<&ActionBase::DeleteStmt> OwningStmtResult;
+  // Note that these will replace ExprResult and StmtResult when the transition
+  // is complete.
+
+  /// Single expressions or statements as arguments.
+#if !defined(DISABLE_SMART_POINTERS)
+  typedef ASTOwningResult<&ActionBase::DeleteExpr> ExprArg;
+  typedef ASTOwningResult<&ActionBase::DeleteStmt> StmtArg;
+#else
+  typedef ASTOwningPtr<&ActionBase::DeleteExpr> ExprArg;
+  typedef ASTOwningPtr<&ActionBase::DeleteStmt> StmtArg;
+#endif
+
+  /// Multiple expressions or statements as arguments.
+  typedef ASTMultiPtr<&ActionBase::DeleteExpr> MultiExprArg;
+  typedef ASTMultiPtr<&ActionBase::DeleteStmt> MultiStmtArg;
+  typedef ASTMultiPtr<&ActionBase::DeleteTemplateParams> MultiTemplateParamsArg;
+
+  class FullExprArg {
+  public:
+    // FIXME: The const_cast here is ugly. RValue references would make this
+    // much nicer (or we could duplicate a bunch of the move semantics
+    // emulation code from Ownership.h).
+    FullExprArg(const FullExprArg& Other)
+      : Expr(move(const_cast<FullExprArg&>(Other).Expr)) {}
+
+    OwningExprResult release() {
+      return move(Expr);
+    }
+
+    ExprArg* operator->() {
+      return &Expr;
+    }
+
+  private:
+    // FIXME: No need to make the entire Action class a friend when it's just
+    // Action::FullExpr that needs access to the constructor below.
+    friend class Action;
+
+    explicit FullExprArg(ExprArg expr)
+      : Expr(move(expr)) {}
+
+    ExprArg Expr;
+  };
+
+  template<typename T>
+  FullExprArg MakeFullExpr(T &Arg) {
+      return FullExprArg(ActOnFinishFullExpr(move(Arg)));
+  }
+
+  // Utilities for Action implementations to return smart results.
+
+  OwningExprResult ExprError() { return OwningExprResult(*this, true); }
+  OwningStmtResult StmtError() { return OwningStmtResult(*this, true); }
+
+  OwningExprResult ExprError(const DiagnosticBuilder&) { return ExprError(); }
+  OwningStmtResult StmtError(const DiagnosticBuilder&) { return StmtError(); }
+
+  OwningExprResult ExprEmpty() { return OwningExprResult(*this, false); }
+  OwningStmtResult StmtEmpty() { return OwningStmtResult(*this, false); }
+
+  /// Statistics.
+  virtual void PrintStats() const {}
+
+  /// getDeclName - Return a pretty name for the specified decl if possible, or
+  /// an empty string if not.  This is used for pretty crash reporting.
+  virtual std::string getDeclName(DeclPtrTy D) { return ""; }
+
+  //===--------------------------------------------------------------------===//
+  // Declaration Tracking Callbacks.
+  //===--------------------------------------------------------------------===//
+
+  typedef uintptr_t ParsingDeclStackState;
+
+  /// PushParsingDeclaration - Notes that the parser has begun
+  /// processing a declaration of some sort.  Guaranteed to be matched
+  /// by a call to PopParsingDeclaration with the value returned by
+  /// this method.
+  virtual ParsingDeclStackState PushParsingDeclaration() {
+    return ParsingDeclStackState();
+  }
+
+  /// PopParsingDeclaration - Notes that the parser has completed
+  /// processing a declaration of some sort.  The decl will be empty
+  /// if the declaration didn't correspond to a full declaration (or
+  /// if the actions module returned an empty decl for it).
+  virtual void PopParsingDeclaration(ParsingDeclStackState S, DeclPtrTy D) {
+  }
+
+  /// ConvertDeclToDeclGroup - If the parser has one decl in a context where it
+  /// needs a decl group, it calls this to convert between the two
+  /// representations.
+  virtual DeclGroupPtrTy ConvertDeclToDeclGroup(DeclPtrTy Ptr) {
+    return DeclGroupPtrTy();
+  }
+
+  /// getTypeName - Return non-null if the specified identifier is a type name
+  /// in the current scope.
+  ///
+  /// \param II the identifier for which we are performing name lookup
+  ///
+  /// \param NameLoc the location of the identifier
+  ///
+  /// \param S the scope in which this name lookup occurs
+  ///
+  /// \param SS if non-NULL, the C++ scope specifier that precedes the
+  /// identifier
+  ///
+  /// \param isClassName whether this is a C++ class-name production, in
+  /// which we can end up referring to a member of an unknown specialization
+  /// that we know (from the grammar) is supposed to be a type. For example,
+  /// this occurs when deriving from "std::vector<T>::allocator_type", where T
+  /// is a template parameter.
+  ///
+  /// \param ObjectType if we're checking whether an identifier is a type
+  /// within a C++ member access expression, this will be the type of the 
+  /// 
+  /// \returns the type referred to by this identifier, or NULL if the type
+  /// does not name an identifier.
+  virtual TypeTy *getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
+                              Scope *S, CXXScopeSpec *SS = 0,
+                              bool isClassName = false,
+                              TypeTy *ObjectType = 0) = 0;
+
+  /// isTagName() - This method is called *for error recovery purposes only*
+  /// to determine if the specified name is a valid tag name ("struct foo").  If
+  /// so, this returns the TST for the tag corresponding to it (TST_enum,
+  /// TST_union, TST_struct, TST_class).  This is used to diagnose cases in C
+  /// where the user forgot to specify the tag.
+  virtual DeclSpec::TST isTagName(IdentifierInfo &II, Scope *S) {
+    return DeclSpec::TST_unspecified;
+  }
+
+  /// \brief Action called as part of error recovery when the parser has 
+  /// determined that the given name must refer to a type, but 
+  /// \c getTypeName() did not return a result.
+  ///
+  /// This callback permits the action to give a detailed diagnostic when an
+  /// unknown type name is encountered and, potentially, to try to recover
+  /// by producing a new type in \p SuggestedType.
+  ///
+  /// \param II the name that should be a type.
+  ///
+  /// \param IILoc the location of the name in the source.
+  ///
+  /// \param S the scope in which name lookup was performed.
+  ///
+  /// \param SS if non-NULL, the C++ scope specifier that preceded the name.
+  ///
+  /// \param SuggestedType if the action sets this type to a non-NULL type,
+  /// the parser will recovery by consuming the type name token and then 
+  /// pretending that the given type was the type it parsed.
+  ///
+  /// \returns true if a diagnostic was emitted, false otherwise. When false,
+  /// the parser itself will emit a generic "unknown type name" diagnostic.
+  virtual bool DiagnoseUnknownTypeName(const IdentifierInfo &II, 
+                                       SourceLocation IILoc,
+                                       Scope *S,
+                                       CXXScopeSpec *SS,
+                                       TypeTy *&SuggestedType) {
+    return false;
+  }
+                                       
+  /// isCurrentClassName - Return true if the specified name is the
+  /// name of the innermost C++ class type currently being defined.
+  virtual bool isCurrentClassName(const IdentifierInfo &II, Scope *S,
+                                  const CXXScopeSpec *SS = 0) = 0;
+
+  /// \brief Determine whether the given name refers to a template.
+  ///
+  /// This callback is used by the parser after it has seen a '<' to determine
+  /// whether the given name refers to a template and, if so, what kind of 
+  /// template.
+  ///
+  /// \param S the scope in which the name occurs.
+  ///
+  /// \param SS the C++ nested-name-specifier that precedes the template name,
+  /// if any.
+  ///
+  /// \param Name the name that we are querying to determine whether it is
+  /// a template.
+  ///
+  /// \param ObjectType if we are determining whether the given name is a 
+  /// template name in the context of a member access expression (e.g., 
+  /// \c p->X<int>), this is the type of the object referred to by the
+  /// member access (e.g., \c p).
+  ///
+  /// \param EnteringContext whether we are potentially entering the context
+  /// referred to by the nested-name-specifier \p SS, which allows semantic
+  /// analysis to look into uninstantiated templates.
+  ///
+  /// \param Template if the name does refer to a template, the declaration
+  /// of the template that the name refers to.
+  ///
+  /// \returns the kind of template that this name refers to.
+  virtual TemplateNameKind isTemplateName(Scope *S,
+                                          CXXScopeSpec &SS,
+                                          UnqualifiedId &Name,
+                                          TypeTy *ObjectType,
+                                          bool EnteringContext,
+                                          TemplateTy &Template) = 0;
+
+  /// \brief Action called as part of error recovery when the parser has 
+  /// determined that the given name must refer to a template, but 
+  /// \c isTemplateName() did not return a result.
+  ///
+  /// This callback permits the action to give a detailed diagnostic when an
+  /// unknown template name is encountered and, potentially, to try to recover
+  /// by producing a new template in \p SuggestedTemplate.
+  ///
+  /// \param II the name that should be a template.
+  ///
+  /// \param IILoc the location of the name in the source.
+  ///
+  /// \param S the scope in which name lookup was performed.
+  ///
+  /// \param SS the C++ scope specifier that preceded the name.
+  ///
+  /// \param SuggestedTemplate if the action sets this template to a non-NULL,
+  /// template, the parser will recover by consuming the template name token
+  /// and the template argument list that follows.
+  ///
+  /// \param SuggestedTemplateKind as input, the kind of template that we
+  /// expect (e.g., \c TNK_Type_template or \c TNK_Function_template). If the
+  /// action provides a suggested template, this should be set to the kind of
+  /// template.
+  ///
+  /// \returns true if a diagnostic was emitted, false otherwise. When false,
+  /// the parser itself will emit a generic "unknown template name" diagnostic.
+  virtual bool DiagnoseUnknownTemplateName(const IdentifierInfo &II, 
+                                           SourceLocation IILoc,
+                                           Scope *S,
+                                           const CXXScopeSpec *SS,
+                                           TemplateTy &SuggestedTemplate,
+                                           TemplateNameKind &SuggestedKind) {
+    return false;
+  }
+  
+  /// \brief Determine whether the given name refers to a non-type nested name
+  /// specifier, e.g., the name of a namespace or namespace alias.
+  ///
+  /// This actual is used in the parsing of pseudo-destructor names to 
+  /// distinguish a nested-name-specifier and a "type-name ::" when we
+  /// see the token sequence "X :: ~".
+  virtual bool isNonTypeNestedNameSpecifier(Scope *S, CXXScopeSpec &SS,
+                                            SourceLocation IdLoc,
+                                            IdentifierInfo &II,
+                                            TypeTy *ObjectType) {
+    return false;
+  }
+  
+  /// ActOnCXXGlobalScopeSpecifier - Return the object that represents the
+  /// global scope ('::').
+  virtual CXXScopeTy *ActOnCXXGlobalScopeSpecifier(Scope *S,
+                                                   SourceLocation CCLoc) {
+    return 0;
+  }
+  
+  /// \brief Parsed an identifier followed by '::' in a C++
+  /// nested-name-specifier.
+  ///
+  /// \param S the scope in which the nested-name-specifier was parsed.
+  ///
+  /// \param SS the nested-name-specifier that precedes the identifier. For
+  /// example, if we are parsing "foo::bar::", \p SS will describe the "foo::"
+  /// that has already been parsed.
+  ///
+  /// \param IdLoc the location of the identifier we have just parsed (e.g.,
+  /// the "bar" in "foo::bar::".
+  ///
+  /// \param CCLoc the location of the '::' at the end of the
+  /// nested-name-specifier.
+  ///
+  /// \param II the identifier that represents the scope that this
+  /// nested-name-specifier refers to, e.g., the "bar" in "foo::bar::".
+  ///
+  /// \param ObjectType if this nested-name-specifier occurs as part of a
+  /// C++ member access expression such as "x->Base::f", the type of the base
+  /// object (e.g., *x in the example, if "x" were a pointer).
+  ///
+  /// \param EnteringContext if true, then we intend to immediately enter the
+  /// context of this nested-name-specifier, e.g., for an out-of-line
+  /// definition of a class member.
+  ///
+  /// \returns a CXXScopeTy* object representing the C++ scope.
+  virtual CXXScopeTy *ActOnCXXNestedNameSpecifier(Scope *S,
+                                                  CXXScopeSpec &SS,
+                                                  SourceLocation IdLoc,
+                                                  SourceLocation CCLoc,
+                                                  IdentifierInfo &II,
+                                                  TypeTy *ObjectType,
+                                                  bool EnteringContext) {
+    return 0;
+  }
+  
+  /// IsInvalidUnlessNestedName - This method is used for error recovery
+  /// purposes to determine whether the specified identifier is only valid as
+  /// a nested name specifier, for example a namespace name.  It is
+  /// conservatively correct to always return false from this method.
+  ///
+  /// The arguments are the same as those passed to ActOnCXXNestedNameSpecifier.
+  virtual bool IsInvalidUnlessNestedName(Scope *S,
+                                         CXXScopeSpec &SS,
+                                         IdentifierInfo &II,
+                                         TypeTy *ObjectType,
+                                         bool EnteringContext) {
+    return false;
+  }
+
+  /// ActOnCXXNestedNameSpecifier - Called during parsing of a
+  /// nested-name-specifier that involves a template-id, e.g.,
+  /// "foo::bar<int, float>::", and now we need to build a scope
+  /// specifier. \p SS is empty or the previously parsed nested-name
+  /// part ("foo::"), \p Type is the already-parsed class template
+  /// specialization (or other template-id that names a type), \p
+  /// TypeRange is the source range where the type is located, and \p
+  /// CCLoc is the location of the trailing '::'.
+  virtual CXXScopeTy *ActOnCXXNestedNameSpecifier(Scope *S,
+                                                  const CXXScopeSpec &SS,
+                                                  TypeTy *Type,
+                                                  SourceRange TypeRange,
+                                                  SourceLocation CCLoc) {
+    return 0;
+  }
+
+  /// ShouldEnterDeclaratorScope - Called when a C++ scope specifier
+  /// is parsed as part of a declarator-id to determine whether a scope
+  /// should be entered.
+  ///
+  /// \param S the current scope
+  /// \param SS the scope being entered
+  /// \param isFriendDeclaration whether this is a friend declaration
+  virtual bool ShouldEnterDeclaratorScope(Scope *S, const CXXScopeSpec &SS) {
+    return false;
+  }
+
+  /// ActOnCXXEnterDeclaratorScope - Called when a C++ scope specifier (global
+  /// scope or nested-name-specifier) is parsed as part of a declarator-id.
+  /// After this method is called, according to [C++ 3.4.3p3], names should be
+  /// looked up in the declarator-id's scope, until the declarator is parsed and
+  /// ActOnCXXExitDeclaratorScope is called.
+  /// The 'SS' should be a non-empty valid CXXScopeSpec.
+  /// \returns true if an error occurred, false otherwise.
+  virtual bool ActOnCXXEnterDeclaratorScope(Scope *S, CXXScopeSpec &SS) {
+    return false;
+  }
+
+  /// ActOnCXXExitDeclaratorScope - Called when a declarator that previously
+  /// invoked ActOnCXXEnterDeclaratorScope(), is finished. 'SS' is the same
+  /// CXXScopeSpec that was passed to ActOnCXXEnterDeclaratorScope as well.
+  /// Used to indicate that names should revert to being looked up in the
+  /// defining scope.
+  virtual void ActOnCXXExitDeclaratorScope(Scope *S, const CXXScopeSpec &SS) {
+  }
+
+  /// ActOnCXXEnterDeclInitializer - Invoked when we are about to parse an
+  /// initializer for the declaration 'Dcl'.
+  /// After this method is called, according to [C++ 3.4.1p13], if 'Dcl' is a
+  /// static data member of class X, names should be looked up in the scope of
+  /// class X.
+  virtual void ActOnCXXEnterDeclInitializer(Scope *S, DeclPtrTy Dcl) {
+  }
+
+  /// ActOnCXXExitDeclInitializer - Invoked after we are finished parsing an
+  /// initializer for the declaration 'Dcl'.
+  virtual void ActOnCXXExitDeclInitializer(Scope *S, DeclPtrTy Dcl) {
+  }
+
+  /// ActOnDeclarator - This callback is invoked when a declarator is parsed and
+  /// 'Init' specifies the initializer if any.  This is for things like:
+  /// "int X = 4" or "typedef int foo".
+  ///
+  virtual DeclPtrTy ActOnDeclarator(Scope *S, Declarator &D) {
+    return DeclPtrTy();
+  }
+
+  /// ActOnParamDeclarator - This callback is invoked when a parameter
+  /// declarator is parsed. This callback only occurs for functions
+  /// with prototypes. S is the function prototype scope for the
+  /// parameters (C++ [basic.scope.proto]).
+  virtual DeclPtrTy ActOnParamDeclarator(Scope *S, Declarator &D) {
+    return DeclPtrTy();
+  }
+
+  /// \brief Parsed an exception object declaration within an Objective-C
+  /// @catch statement.
+  virtual DeclPtrTy ActOnObjCExceptionDecl(Scope *S, Declarator &D) {
+    return DeclPtrTy();
+  }
+
+  /// AddInitializerToDecl - This action is called immediately after
+  /// ActOnDeclarator (when an initializer is present). The code is factored
+  /// this way to make sure we are able to handle the following:
+  ///   void func() { int xx = xx; }
+  /// This allows ActOnDeclarator to register "xx" prior to parsing the
+  /// initializer. The declaration above should still result in a warning,
+  /// since the reference to "xx" is uninitialized.
+  virtual void AddInitializerToDecl(DeclPtrTy Dcl, ExprArg Init) {
+    return;
+  }
+
+  /// SetDeclDeleted - This action is called immediately after ActOnDeclarator
+  /// if =delete is parsed. C++0x [dcl.fct.def]p10
+  /// Note that this can be called even for variable declarations. It's the
+  /// action's job to reject it.
+  virtual void SetDeclDeleted(DeclPtrTy Dcl, SourceLocation DelLoc) {
+    return;
+  }
+
+  /// ActOnUninitializedDecl - This action is called immediately after
+  /// ActOnDeclarator (when an initializer is *not* present).
+  /// If TypeContainsUndeducedAuto is true, then the type of the declarator
+  /// has an undeduced 'auto' type somewhere.
+  virtual void ActOnUninitializedDecl(DeclPtrTy Dcl,
+                                      bool TypeContainsUndeducedAuto) {
+    return;
+  }
+
+  /// \brief Note that the given declaration had an initializer that could not
+  /// be parsed.
+  virtual void ActOnInitializerError(DeclPtrTy Dcl) {
+    return;
+  }
+  
+  /// FinalizeDeclaratorGroup - After a sequence of declarators are parsed, this
+  /// gives the actions implementation a chance to process the group as a whole.
+  virtual DeclGroupPtrTy FinalizeDeclaratorGroup(Scope *S, const DeclSpec& DS,
+                                                 DeclPtrTy *Group,
+                                                 unsigned NumDecls) {
+    return DeclGroupPtrTy();
+  }
+
+
+  /// @brief Indicates that all K&R-style parameter declarations have
+  /// been parsed prior to a function definition.
+  /// @param S  The function prototype scope.
+  /// @param D  The function declarator.
+  virtual void ActOnFinishKNRParamDeclarations(Scope *S, Declarator &D,
+                                               SourceLocation LocAfterDecls) {
+  }
+
+  /// ActOnStartOfFunctionDef - This is called at the start of a function
+  /// definition, instead of calling ActOnDeclarator.  The Declarator includes
+  /// information about formal arguments that are part of this function.
+  virtual DeclPtrTy ActOnStartOfFunctionDef(Scope *FnBodyScope, Declarator &D) {
+    // Default to ActOnDeclarator.
+    return ActOnStartOfFunctionDef(FnBodyScope,
+                                   ActOnDeclarator(FnBodyScope, D));
+  }
+
+  /// ActOnStartOfFunctionDef - This is called at the start of a function
+  /// definition, after the FunctionDecl has already been created.
+  virtual DeclPtrTy ActOnStartOfFunctionDef(Scope *FnBodyScope, DeclPtrTy D) {
+    return D;
+  }
+
+  virtual void ActOnStartOfObjCMethodDef(Scope *FnBodyScope, DeclPtrTy D) {
+    return;
+  }
+
+  /// ActOnFinishFunctionBody - This is called when a function body has
+  /// completed parsing.  Decl is returned by ParseStartOfFunctionDef.
+  virtual DeclPtrTy ActOnFinishFunctionBody(DeclPtrTy Decl, StmtArg Body) {
+    return Decl;
+  }
+
+  virtual DeclPtrTy ActOnFileScopeAsmDecl(SourceLocation Loc,
+                                          ExprArg AsmString) {
+    return DeclPtrTy();
+  }
+
+  /// ActOnPopScope - This callback is called immediately before the specified
+  /// scope is popped and deleted.
+  virtual void ActOnPopScope(SourceLocation Loc, Scope *S) {}
+
+  /// ActOnTranslationUnitScope - This callback is called once, immediately
+  /// after creating the translation unit scope (in Parser::Initialize).
+  virtual void ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) {}
+
+  /// ParsedFreeStandingDeclSpec - This method is invoked when a declspec with
+  /// no declarator (e.g. "struct foo;") is parsed.
+  virtual DeclPtrTy ParsedFreeStandingDeclSpec(Scope *S, DeclSpec &DS) {
+    return DeclPtrTy();
+  }
+
+  /// ActOnStartLinkageSpecification - Parsed the beginning of a C++
+  /// linkage specification, including the language and (if present)
+  /// the '{'. ExternLoc is the location of the 'extern', LangLoc is
+  /// the location of the language string literal, which is provided
+  /// by Lang/StrSize. LBraceLoc, if valid, provides the location of
+  /// the '{' brace. Otherwise, this linkage specification does not
+  /// have any braces.
+  virtual DeclPtrTy ActOnStartLinkageSpecification(Scope *S,
+                                                   SourceLocation ExternLoc,
+                                                   SourceLocation LangLoc,
+                                                   const char *Lang,
+                                                   unsigned StrSize,
+                                                   SourceLocation LBraceLoc) {
+    return DeclPtrTy();
+  }
+
+  /// ActOnFinishLinkageSpecification - Completely the definition of
+  /// the C++ linkage specification LinkageSpec. If RBraceLoc is
+  /// valid, it's the position of the closing '}' brace in a linkage
+  /// specification that uses braces.
+  virtual DeclPtrTy ActOnFinishLinkageSpecification(Scope *S,
+                                                    DeclPtrTy LinkageSpec,
+                                                    SourceLocation RBraceLoc) {
+    return LinkageSpec;
+  }
+
+  /// ActOnEndOfTranslationUnit - This is called at the very end of the
+  /// translation unit when EOF is reached and all but the top-level scope is
+  /// popped.
+  virtual void ActOnEndOfTranslationUnit() {}
+
+  //===--------------------------------------------------------------------===//
+  // Type Parsing Callbacks.
+  //===--------------------------------------------------------------------===//
+
+  /// ActOnTypeName - A type-name (type-id in C++) was parsed.
+  virtual TypeResult ActOnTypeName(Scope *S, Declarator &D) {
+    return TypeResult();
+  }
+
+  enum TagUseKind {
+    TUK_Reference,   // Reference to a tag:  'struct foo *X;'
+    TUK_Declaration, // Fwd decl of a tag:   'struct foo;'
+    TUK_Definition,  // Definition of a tag: 'struct foo { int X; } Y;'
+    TUK_Friend       // Friend declaration:  'friend struct foo;'
+  };
+
+  /// \brief The parser has encountered a tag (e.g., "class X") that should be
+  /// turned into a declaration by the action module.
+  ///
+  /// \param S the scope in which this tag occurs.
+  ///
+  /// \param TagSpec an instance of DeclSpec::TST, indicating what kind of tag
+  /// this is (struct/union/enum/class).
+  ///
+  /// \param TUK how the tag we have encountered is being used, which
+  /// can be a reference to a (possibly pre-existing) tag, a
+  /// declaration of that tag, or the beginning of a definition of
+  /// that tag.
+  ///
+  /// \param KWLoc the location of the "struct", "class", "union", or "enum"
+  /// keyword.
+  ///
+  /// \param SS C++ scope specifier that precedes the name of the tag, e.g.,
+  /// the "std::" in "class std::type_info".
+  ///
+  /// \param Name the name of the tag, e.g., "X" in "struct X". This parameter
+  /// may be NULL, to indicate an anonymous class/struct/union/enum type.
+  ///
+  /// \param NameLoc the location of the name of the tag.
+  ///
+  /// \param Attr the set of attributes that appertain to the tag.
+  ///
+  /// \param AS when this tag occurs within a C++ class, provides the
+  /// current access specifier (AS_public, AS_private, AS_protected).
+  /// Otherwise, it will be AS_none.
+  ///
+  /// \param TemplateParameterLists the set of C++ template parameter lists
+  /// that apply to this tag, if the tag is a declaration or definition (see
+  /// the \p TK parameter). The action module is responsible for determining,
+  /// based on the template parameter lists and the scope specifier, whether
+  /// the declared tag is a class template or not.
+  ///
+  /// \param OwnedDecl the callee should set this flag true when the returned
+  /// declaration is "owned" by this reference. Ownership is handled entirely
+  /// by the action module.
+  ///
+  /// \returns the declaration to which this tag refers.
+  virtual DeclPtrTy ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
+                             SourceLocation KWLoc, CXXScopeSpec &SS,
+                             IdentifierInfo *Name, SourceLocation NameLoc,
+                             AttributeList *Attr, AccessSpecifier AS,
+                             MultiTemplateParamsArg TemplateParameterLists,
+                             bool &OwnedDecl, bool &IsDependent) {
+    return DeclPtrTy();
+  }
+
+  /// Acts on a reference to a dependent tag name.  This arises in
+  /// cases like:
+  ///
+  ///    template <class T> class A;
+  ///    template <class T> class B {
+  ///      friend class A<T>::M;  // here
+  ///    };
+  ///
+  /// \param TagSpec an instance of DeclSpec::TST corresponding to the
+  /// tag specifier.
+  ///
+  /// \param TUK the tag use kind (either TUK_Friend or TUK_Reference)
+  ///
+  /// \param SS the scope specifier (always defined)
+  virtual TypeResult ActOnDependentTag(Scope *S,
+                                       unsigned TagSpec,
+                                       TagUseKind TUK,
+                                       const CXXScopeSpec &SS,
+                                       IdentifierInfo *Name,
+                                       SourceLocation KWLoc,
+                                       SourceLocation NameLoc) {
+    return TypeResult();
+  }
+
+  /// Act on @defs() element found when parsing a structure.  ClassName is the
+  /// name of the referenced class.
+  virtual void ActOnDefs(Scope *S, DeclPtrTy TagD, SourceLocation DeclStart,
+                         IdentifierInfo *ClassName,
+                         llvm::SmallVectorImpl<DeclPtrTy> &Decls) {}
+  virtual DeclPtrTy ActOnField(Scope *S, DeclPtrTy TagD,
+                               SourceLocation DeclStart,
+                               Declarator &D, ExprTy *BitfieldWidth) {
+    return DeclPtrTy();
+  }
+
+  virtual DeclPtrTy ActOnIvar(Scope *S, SourceLocation DeclStart,
+                              DeclPtrTy IntfDecl,
+                              Declarator &D, ExprTy *BitfieldWidth,
+                              tok::ObjCKeywordKind visibility) {
+    return DeclPtrTy();
+  }
+
+  virtual void ActOnFields(Scope* S, SourceLocation RecLoc, DeclPtrTy TagDecl,
+                           DeclPtrTy *Fields, unsigned NumFields,
+                           SourceLocation LBrac, SourceLocation RBrac,
+                           AttributeList *AttrList) {}
+
+  /// ActOnTagStartDefinition - Invoked when we have entered the
+  /// scope of a tag's definition (e.g., for an enumeration, class,
+  /// struct, or union).
+  virtual void ActOnTagStartDefinition(Scope *S, DeclPtrTy TagDecl) { }
+
+  /// ActOnStartCXXMemberDeclarations - Invoked when we have parsed a
+  /// C++ record definition's base-specifiers clause and are starting its
+  /// member declarations.
+  virtual void ActOnStartCXXMemberDeclarations(Scope *S, DeclPtrTy TagDecl,
+                                               SourceLocation LBraceLoc) { }
+
+  /// ActOnTagFinishDefinition - Invoked once we have finished parsing
+  /// the definition of a tag (enumeration, class, struct, or union).
+  ///
+  /// The scope is the scope of the tag definition.
+  virtual void ActOnTagFinishDefinition(Scope *S, DeclPtrTy TagDecl,
+                                        SourceLocation RBraceLoc) { }
+
+  /// ActOnTagDefinitionError - Invoked if there's an unrecoverable
+  /// error parsing the definition of a tag.
+  ///
+  /// The scope is the scope of the tag definition.
+  virtual void ActOnTagDefinitionError(Scope *S, DeclPtrTy TagDecl) { }
+
+  virtual DeclPtrTy ActOnEnumConstant(Scope *S, DeclPtrTy EnumDecl,
+                                      DeclPtrTy LastEnumConstant,
+                                      SourceLocation IdLoc, IdentifierInfo *Id,
+                                      SourceLocation EqualLoc, ExprTy *Val) {
+    return DeclPtrTy();
+  }
+  virtual void ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc,
+                             SourceLocation RBraceLoc, DeclPtrTy EnumDecl,
+                             DeclPtrTy *Elements, unsigned NumElements,
+                             Scope *S, AttributeList *AttrList) {}
+
+  //===--------------------------------------------------------------------===//
+  // Statement Parsing Callbacks.
+  //===--------------------------------------------------------------------===//
+
+  virtual OwningStmtResult ActOnNullStmt(SourceLocation SemiLoc) {
+    return StmtEmpty();
+  }
+
+  virtual OwningStmtResult ActOnCompoundStmt(SourceLocation L, SourceLocation R,
+                                             MultiStmtArg Elts,
+                                             bool isStmtExpr) {
+    return StmtEmpty();
+  }
+  virtual OwningStmtResult ActOnDeclStmt(DeclGroupPtrTy Decl,
+                                         SourceLocation StartLoc,
+                                         SourceLocation EndLoc) {
+    return StmtEmpty();
+  }
+
+  virtual void ActOnForEachDeclStmt(DeclGroupPtrTy Decl) {
+  }
+
+  virtual OwningStmtResult ActOnExprStmt(FullExprArg Expr) {
+    return OwningStmtResult(*this, Expr->release());
+  }
+
+  /// ActOnCaseStmt - Note that this handles the GNU 'case 1 ... 4' extension,
+  /// which can specify an RHS value.  The sub-statement of the case is
+  /// specified in a separate action.
+  virtual OwningStmtResult ActOnCaseStmt(SourceLocation CaseLoc, ExprArg LHSVal,
+                                         SourceLocation DotDotDotLoc,
+                                         ExprArg RHSVal,
+                                         SourceLocation ColonLoc) {
+    return StmtEmpty();
+  }
+
+  /// ActOnCaseStmtBody - This installs a statement as the body of a case.
+  virtual void ActOnCaseStmtBody(StmtTy *CaseStmt, StmtArg SubStmt) {}
+
+  virtual OwningStmtResult ActOnDefaultStmt(SourceLocation DefaultLoc,
+                                            SourceLocation ColonLoc,
+                                            StmtArg SubStmt, Scope *CurScope){
+    return StmtEmpty();
+  }
+
+  virtual OwningStmtResult ActOnLabelStmt(SourceLocation IdentLoc,
+                                          IdentifierInfo *II,
+                                          SourceLocation ColonLoc,
+                                          StmtArg SubStmt) {
+    return StmtEmpty();
+  }
+
+  /// \brief Parsed an "if" statement.
+  ///
+  /// \param IfLoc the location of the "if" keyword.
+  ///
+  /// \param CondVal if the "if" condition was parsed as an expression, 
+  /// the expression itself.
+  ///
+  /// \param CondVar if the "if" condition was parsed as a condition variable,
+  /// the condition variable itself.
+  ///
+  /// \param ThenVal the "then" statement.
+  ///
+  /// \param ElseLoc the location of the "else" keyword.
+  ///
+  /// \param ElseVal the "else" statement.
+  virtual OwningStmtResult ActOnIfStmt(SourceLocation IfLoc,
+                                       FullExprArg CondVal, 
+                                       DeclPtrTy CondVar,
+                                       StmtArg ThenVal,
+                                       SourceLocation ElseLoc,
+                                       StmtArg ElseVal) {
+    return StmtEmpty();
+  }
+
+  /// \brief Parsed the start of a "switch" statement.
+  ///
+  /// \param Cond if the "switch" condition was parsed as an expression, 
+  /// the expression itself.
+  ///
+  /// \param CondVar if the "switch" condition was parsed as a condition 
+  /// variable, the condition variable itself.
+  virtual OwningStmtResult ActOnStartOfSwitchStmt(FullExprArg Cond,
+                                                  DeclPtrTy CondVar) {
+    return StmtEmpty();
+  }
+
+  /// ActOnSwitchBodyError - This is called if there is an error parsing the
+  /// body of the switch stmt instead of ActOnFinishSwitchStmt.
+  virtual void ActOnSwitchBodyError(SourceLocation SwitchLoc, StmtArg Switch,
+                                    StmtArg Body) {}
+  
+  virtual OwningStmtResult ActOnFinishSwitchStmt(SourceLocation SwitchLoc,
+                                                 StmtArg Switch, StmtArg Body) {
+    return StmtEmpty();
+  }
+
+  /// \brief Parsed a "while" statement.
+  ///
+  /// \param Cond if the "while" condition was parsed as an expression, 
+  /// the expression itself.
+  ///
+  /// \param CondVar if the "while" condition was parsed as a condition 
+  /// variable, the condition variable itself.
+  ///
+  /// \param Body the body of the "while" loop.
+  virtual OwningStmtResult ActOnWhileStmt(SourceLocation WhileLoc,
+                                          FullExprArg Cond, DeclPtrTy CondVar,
+                                          StmtArg Body) {
+    return StmtEmpty();
+  }
+  virtual OwningStmtResult ActOnDoStmt(SourceLocation DoLoc, StmtArg Body,
+                                       SourceLocation WhileLoc,
+                                       SourceLocation CondLParen,
+                                       ExprArg Cond,
+                                       SourceLocation CondRParen) {
+    return StmtEmpty();
+  }
+
+  /// \brief Parsed a "for" statement.
+  ///
+  /// \param ForLoc the location of the "for" keyword.
+  ///
+  /// \param LParenLoc the location of the left parentheses.
+  ///
+  /// \param First the statement used to initialize the for loop.
+  ///
+  /// \param Second the condition to be checked during each iteration, if
+  /// that condition was parsed as an expression.
+  ///
+  /// \param SecondArg the condition variable to be checked during each 
+  /// iterator, if that condition was parsed as a variable declaration.
+  ///
+  /// \param Third the expression that will be evaluated to "increment" any
+  /// values prior to the next iteration.
+  ///
+  /// \param RParenLoc the location of the right parentheses.
+  ///
+  /// \param Body the body of the "body" loop.
+  virtual OwningStmtResult ActOnForStmt(SourceLocation ForLoc,
+                                        SourceLocation LParenLoc,
+                                        StmtArg First, FullExprArg Second,
+                                        DeclPtrTy SecondVar, FullExprArg Third, 
+                                        SourceLocation RParenLoc,
+                                        StmtArg Body) {
+    return StmtEmpty();
+  }
+  
+  virtual OwningStmtResult ActOnObjCForCollectionStmt(SourceLocation ForColLoc,
+                                       SourceLocation LParenLoc,
+                                       StmtArg First, ExprArg Second,
+                                       SourceLocation RParenLoc, StmtArg Body) {
+    return StmtEmpty();
+  }
+  virtual OwningStmtResult ActOnGotoStmt(SourceLocation GotoLoc,
+                                         SourceLocation LabelLoc,
+                                         IdentifierInfo *LabelII) {
+    return StmtEmpty();
+  }
+  virtual OwningStmtResult ActOnIndirectGotoStmt(SourceLocation GotoLoc,
+                                                 SourceLocation StarLoc,
+                                                 ExprArg DestExp) {
+    return StmtEmpty();
+  }
+  virtual OwningStmtResult ActOnContinueStmt(SourceLocation ContinueLoc,
+                                             Scope *CurScope) {
+    return StmtEmpty();
+  }
+  virtual OwningStmtResult ActOnBreakStmt(SourceLocation GotoLoc,
+                                          Scope *CurScope) {
+    return StmtEmpty();
+  }
+  virtual OwningStmtResult ActOnReturnStmt(SourceLocation ReturnLoc,
+                                           ExprArg RetValExp) {
+    return StmtEmpty();
+  }
+  virtual OwningStmtResult ActOnAsmStmt(SourceLocation AsmLoc,
+                                        bool IsSimple,
+                                        bool IsVolatile,
+                                        unsigned NumOutputs,
+                                        unsigned NumInputs,
+                                        IdentifierInfo **Names,
+                                        MultiExprArg Constraints,
+                                        MultiExprArg Exprs,
+                                        ExprArg AsmString,
+                                        MultiExprArg Clobbers,
+                                        SourceLocation RParenLoc,
+                                        bool MSAsm = false) {
+    return StmtEmpty();
+  }
+
+  // Objective-c statements
+  
+  /// \brief Parsed an Objective-C @catch statement.
+  ///
+  /// \param AtLoc The location of the '@' starting the '@catch'.
+  ///
+  /// \param RParen The location of the right parentheses ')' after the
+  /// exception variable.
+  ///
+  /// \param Parm The variable that will catch the exception. Will be NULL if 
+  /// this is a @catch(...) block.
+  ///
+  /// \param Body The body of the @catch block.
+  virtual OwningStmtResult ActOnObjCAtCatchStmt(SourceLocation AtLoc,
+                                                SourceLocation RParen,
+                                                DeclPtrTy Parm, StmtArg Body) {
+    return StmtEmpty();
+  }
+
+  /// \brief Parsed an Objective-C @finally statement.
+  ///
+  /// \param AtLoc The location of the '@' starting the '@finally'.
+  ///
+  /// \param Body The body of the @finally block.
+  virtual OwningStmtResult ActOnObjCAtFinallyStmt(SourceLocation AtLoc,
+                                                  StmtArg Body) {
+    return StmtEmpty();
+  }
+
+  /// \brief Parsed an Objective-C @try-@catch-@finally statement.
+  ///
+  /// \param AtLoc The location of the '@' starting '@try'.
+  ///
+  /// \param Try The body of the '@try' statement.
+  ///
+  /// \param CatchStmts The @catch statements.
+  ///
+  /// \param Finally The @finally statement.
+  virtual OwningStmtResult ActOnObjCAtTryStmt(SourceLocation AtLoc,
+                                              StmtArg Try, 
+                                              MultiStmtArg CatchStmts,
+                                              StmtArg Finally) {
+    return StmtEmpty();
+  }
+
+  virtual OwningStmtResult ActOnObjCAtThrowStmt(SourceLocation AtLoc,
+                                                ExprArg Throw,
+                                                Scope *CurScope) {
+    return StmtEmpty();
+  }
+
+  virtual OwningStmtResult ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc,
+                                                       ExprArg SynchExpr,
+                                                       StmtArg SynchBody) {
+    return StmtEmpty();
+  }
+
+  // C++ Statements
+  virtual DeclPtrTy ActOnExceptionDeclarator(Scope *S, Declarator &D) {
+    return DeclPtrTy();
+  }
+
+  virtual OwningStmtResult ActOnCXXCatchBlock(SourceLocation CatchLoc,
+                                              DeclPtrTy ExceptionDecl,
+                                              StmtArg HandlerBlock) {
+    return StmtEmpty();
+  }
+
+  virtual OwningStmtResult ActOnCXXTryBlock(SourceLocation TryLoc,
+                                            StmtArg TryBlock,
+                                            MultiStmtArg Handlers) {
+    return StmtEmpty();
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Expression Parsing Callbacks.
+  //===--------------------------------------------------------------------===//
+
+  /// \brief Describes how the expressions currently being parsed are
+  /// evaluated at run-time, if at all.
+  enum ExpressionEvaluationContext {
+    /// \brief The current expression and its subexpressions occur within an
+    /// unevaluated operand (C++0x [expr]p8), such as a constant expression
+    /// or the subexpression of \c sizeof, where the type or the value of the
+    /// expression may be significant but no code will be generated to evaluate
+    /// the value of the expression at run time.
+    Unevaluated,
+
+    /// \brief The current expression is potentially evaluated at run time,
+    /// which means that code may be generated to evaluate the value of the
+    /// expression at run time.
+    PotentiallyEvaluated,
+
+    /// \brief The current expression may be potentially evaluated or it may
+    /// be unevaluated, but it is impossible to tell from the lexical context.
+    /// This evaluation context is used primary for the operand of the C++
+    /// \c typeid expression, whose argument is potentially evaluated only when
+    /// it is an lvalue of polymorphic class type (C++ [basic.def.odr]p2).
+    PotentiallyPotentiallyEvaluated
+  };
+
+  /// \brief The parser is entering a new expression evaluation context.
+  ///
+  /// \param NewContext is the new expression evaluation context.
+  virtual void
+  PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext) { }
+
+  /// \brief The parser is exiting an expression evaluation context.
+  virtual void
+  PopExpressionEvaluationContext() { }
+
+  // Primary Expressions.
+
+  /// \brief Retrieve the source range that corresponds to the given
+  /// expression.
+  virtual SourceRange getExprRange(ExprTy *E) const {
+    return SourceRange();
+  }
+  
+  /// \brief Parsed an id-expression (C++) or identifier (C) in expression
+  /// context, e.g., the expression "x" that refers to a variable named "x".
+  ///
+  /// \param S the scope in which this id-expression or identifier occurs.
+  ///
+  /// \param SS the C++ nested-name-specifier that qualifies the name of the
+  /// value, e.g., "std::" in "std::sort".
+  ///
+  /// \param Name the name to which the id-expression refers. In C, this will
+  /// always be an identifier. In C++, it may also be an overloaded operator,
+  /// destructor name (if there is a nested-name-specifier), or template-id.
+  ///
+  /// \param HasTrailingLParen whether the next token following the 
+  /// id-expression or identifier is a left parentheses ('(').
+  ///
+  /// \param IsAddressOfOperand whether the token that precedes this 
+  /// id-expression or identifier was an ampersand ('&'), indicating that 
+  /// we will be taking the address of this expression.
+  virtual OwningExprResult ActOnIdExpression(Scope *S,
+                                             CXXScopeSpec &SS,
+                                             UnqualifiedId &Name,
+                                             bool HasTrailingLParen,
+                                             bool IsAddressOfOperand) {
+    return ExprEmpty();
+  }
+  
+  virtual OwningExprResult ActOnPredefinedExpr(SourceLocation Loc,
+                                               tok::TokenKind Kind) {
+    return ExprEmpty();
+  }
+  virtual OwningExprResult ActOnCharacterConstant(const Token &) {
+    return ExprEmpty();
+  }
+  virtual OwningExprResult ActOnNumericConstant(const Token &) {
+    return ExprEmpty();
+  }
+
+  /// ActOnStringLiteral - The specified tokens were lexed as pasted string
+  /// fragments (e.g. "foo" "bar" L"baz").
+  virtual OwningExprResult ActOnStringLiteral(const Token *Toks,
+                                              unsigned NumToks) {
+    return ExprEmpty();
+  }
+
+  virtual OwningExprResult ActOnParenExpr(SourceLocation L, SourceLocation R,
+                                          ExprArg Val) {
+    return move(Val);  // Default impl returns operand.
+  }
+
+  virtual OwningExprResult ActOnParenOrParenListExpr(SourceLocation L,
+                                              SourceLocation R,
+                                              MultiExprArg Val,
+                                              TypeTy *TypeOfCast=0) {
+    return ExprEmpty();
+  }
+
+  // Postfix Expressions.
+  virtual OwningExprResult ActOnPostfixUnaryOp(Scope *S, SourceLocation OpLoc,
+                                               tok::TokenKind Kind,
+                                               ExprArg Input) {
+    return ExprEmpty();
+  }
+  virtual OwningExprResult ActOnArraySubscriptExpr(Scope *S, ExprArg Base,
+                                                   SourceLocation LLoc,
+                                                   ExprArg Idx,
+                                                   SourceLocation RLoc) {
+    return ExprEmpty();
+  }
+
+  /// \brief Parsed a member access expresion (C99 6.5.2.3, C++ [expr.ref])
+  /// of the form \c x.m or \c p->m.
+  ///
+  /// \param S the scope in which the member access expression occurs.
+  ///
+  /// \param Base the class or pointer to class into which this member
+  /// access expression refers, e.g., \c x in \c x.m.
+  ///
+  /// \param OpLoc the location of the "." or "->" operator.
+  ///
+  /// \param OpKind the kind of member access operator, which will be either
+  /// tok::arrow ("->") or tok::period (".").
+  ///
+  /// \param SS in C++, the nested-name-specifier that precedes the member
+  /// name, if any.
+  ///
+  /// \param Member the name of the member that we are referring to. In C,
+  /// this will always store an identifier; in C++, we may also have operator
+  /// names, conversion function names, destructors, and template names.
+  ///
+  /// \param ObjCImpDecl the Objective-C implementation declaration.
+  /// FIXME: Do we really need this?
+  ///
+  /// \param HasTrailingLParen whether this member name is immediately followed
+  /// by a left parentheses ('(').
+  virtual OwningExprResult ActOnMemberAccessExpr(Scope *S, ExprArg Base,
+                                                 SourceLocation OpLoc,
+                                                 tok::TokenKind OpKind,
+                                                 CXXScopeSpec &SS,
+                                                 UnqualifiedId &Member,
+                                                 DeclPtrTy ObjCImpDecl,
+                                                 bool HasTrailingLParen) {
+    return ExprEmpty();
+  }
+                                                 
+  /// ActOnCallExpr - Handle a call to Fn with the specified array of arguments.
+  /// This provides the location of the left/right parens and a list of comma
+  /// locations.  There are guaranteed to be one fewer commas than arguments,
+  /// unless there are zero arguments.
+  virtual OwningExprResult ActOnCallExpr(Scope *S, ExprArg Fn,
+                                         SourceLocation LParenLoc,
+                                         MultiExprArg Args,
+                                         SourceLocation *CommaLocs,
+                                         SourceLocation RParenLoc) {
+    return ExprEmpty();
+  }
+
+  // Unary Operators.  'Tok' is the token for the operator.
+  virtual OwningExprResult ActOnUnaryOp(Scope *S, SourceLocation OpLoc,
+                                        tok::TokenKind Op, ExprArg Input) {
+    return ExprEmpty();
+  }
+  virtual OwningExprResult
+    ActOnSizeOfAlignOfExpr(SourceLocation OpLoc, bool isSizeof, bool isType,
+                           void *TyOrEx, const SourceRange &ArgRange) {
+    return ExprEmpty();
+  }
+
+  virtual OwningExprResult ActOnCompoundLiteral(SourceLocation LParen,
+                                                TypeTy *Ty,
+                                                SourceLocation RParen,
+                                                ExprArg Op) {
+    return ExprEmpty();
+  }
+  virtual OwningExprResult ActOnInitList(SourceLocation LParenLoc,
+                                         MultiExprArg InitList,
+                                         SourceLocation RParenLoc) {
+    return ExprEmpty();
+  }
+  /// @brief Parsed a C99 designated initializer.
+  ///
+  /// @param Desig Contains the designation with one or more designators.
+  ///
+  /// @param Loc The location of the '=' or ':' prior to the
+  /// initialization expression.
+  ///
+  /// @param GNUSyntax If true, then this designated initializer used
+  /// the deprecated GNU syntax @c fieldname:foo or @c [expr]foo rather
+  /// than the C99 syntax @c .fieldname=foo or @c [expr]=foo.
+  ///
+  /// @param Init The value that the entity (or entities) described by
+  /// the designation will be initialized with.
+  virtual OwningExprResult ActOnDesignatedInitializer(Designation &Desig,
+                                                      SourceLocation Loc,
+                                                      bool GNUSyntax,
+                                                      OwningExprResult Init) {
+    return ExprEmpty();
+  }
+
+  virtual OwningExprResult ActOnCastExpr(Scope *S, SourceLocation LParenLoc,
+                                         TypeTy *Ty, SourceLocation RParenLoc,
+                                         ExprArg Op) {
+    return ExprEmpty();
+  }
+
+  virtual bool TypeIsVectorType(TypeTy *Ty) {
+    return false;
+  }
+
+  virtual OwningExprResult ActOnBinOp(Scope *S, SourceLocation TokLoc,
+                                      tok::TokenKind Kind,
+                                      ExprArg LHS, ExprArg RHS) {
+    return ExprEmpty();
+  }
+
+  /// ActOnConditionalOp - Parse a ?: operation.  Note that 'LHS' may be null
+  /// in the case of a the GNU conditional expr extension.
+  virtual OwningExprResult ActOnConditionalOp(SourceLocation QuestionLoc,
+                                              SourceLocation ColonLoc,
+                                              ExprArg Cond, ExprArg LHS,
+                                              ExprArg RHS) {
+    return ExprEmpty();
+  }
+
+  //===---------------------- GNU Extension Expressions -------------------===//
+
+  virtual OwningExprResult ActOnAddrLabel(SourceLocation OpLoc,
+                                          SourceLocation LabLoc,
+                                          IdentifierInfo *LabelII) { // "&&foo"
+    return ExprEmpty();
+  }
+
+  virtual OwningExprResult ActOnStmtExpr(SourceLocation LPLoc, StmtArg SubStmt,
+                                         SourceLocation RPLoc) { // "({..})"
+    return ExprEmpty();
+  }
+
+  // __builtin_offsetof(type, identifier(.identifier|[expr])*)
+  struct OffsetOfComponent {
+    SourceLocation LocStart, LocEnd;
+    bool isBrackets;  // true if [expr], false if .ident
+    union {
+      IdentifierInfo *IdentInfo;
+      ExprTy *E;
+    } U;
+  };
+
+  virtual OwningExprResult ActOnBuiltinOffsetOf(Scope *S,
+                                                SourceLocation BuiltinLoc,
+                                                SourceLocation TypeLoc,
+                                                TypeTy *Arg1,
+                                                OffsetOfComponent *CompPtr,
+                                                unsigned NumComponents,
+                                                SourceLocation RParenLoc) {
+    return ExprEmpty();
+  }
+
+  // __builtin_types_compatible_p(type1, type2)
+  virtual OwningExprResult ActOnTypesCompatibleExpr(SourceLocation BuiltinLoc,
+                                                    TypeTy *arg1, TypeTy *arg2,
+                                                    SourceLocation RPLoc) {
+    return ExprEmpty();
+  }
+  // __builtin_choose_expr(constExpr, expr1, expr2)
+  virtual OwningExprResult ActOnChooseExpr(SourceLocation BuiltinLoc,
+                                           ExprArg cond, ExprArg expr1,
+                                           ExprArg expr2, SourceLocation RPLoc){
+    return ExprEmpty();
+  }
+
+  // __builtin_va_arg(expr, type)
+  virtual OwningExprResult ActOnVAArg(SourceLocation BuiltinLoc,
+                                      ExprArg expr, TypeTy *type,
+                                      SourceLocation RPLoc) {
+    return ExprEmpty();
+  }
+
+  /// ActOnGNUNullExpr - Parsed the GNU __null expression, the token
+  /// for which is at position TokenLoc.
+  virtual OwningExprResult ActOnGNUNullExpr(SourceLocation TokenLoc) {
+    return ExprEmpty();
+  }
+
+  //===------------------------- "Block" Extension ------------------------===//
+
+  /// ActOnBlockStart - This callback is invoked when a block literal is
+  /// started.  The result pointer is passed into the block finalizers.
+  virtual void ActOnBlockStart(SourceLocation CaretLoc, Scope *CurScope) {}
+
+  /// ActOnBlockArguments - This callback allows processing of block arguments.
+  /// If there are no arguments, this is still invoked.
+  virtual void ActOnBlockArguments(Declarator &ParamInfo, Scope *CurScope) {}
+
+  /// ActOnBlockError - If there is an error parsing a block, this callback
+  /// is invoked to pop the information about the block from the action impl.
+  virtual void ActOnBlockError(SourceLocation CaretLoc, Scope *CurScope) {}
+
+  /// ActOnBlockStmtExpr - This is called when the body of a block statement
+  /// literal was successfully completed.  ^(int x){...}
+  virtual OwningExprResult ActOnBlockStmtExpr(SourceLocation CaretLoc,
+                                              StmtArg Body,
+                                              Scope *CurScope) {
+    return ExprEmpty();
+  }
+
+  //===------------------------- C++ Declarations -------------------------===//
+
+  /// ActOnStartNamespaceDef - This is called at the start of a namespace
+  /// definition.
+  virtual DeclPtrTy ActOnStartNamespaceDef(Scope *S, SourceLocation IdentLoc,
+                                           IdentifierInfo *Ident,
+                                           SourceLocation LBrace,
+                                           AttributeList *AttrList) {
+    return DeclPtrTy();
+  }
+
+  /// ActOnFinishNamespaceDef - This callback is called after a namespace is
+  /// exited. Decl is returned by ActOnStartNamespaceDef.
+  virtual void ActOnFinishNamespaceDef(DeclPtrTy Dcl, SourceLocation RBrace) {
+    return;
+  }
+
+  /// ActOnUsingDirective - This is called when using-directive is parsed.
+  virtual DeclPtrTy ActOnUsingDirective(Scope *CurScope,
+                                        SourceLocation UsingLoc,
+                                        SourceLocation NamespcLoc,
+                                        CXXScopeSpec &SS,
+                                        SourceLocation IdentLoc,
+                                        IdentifierInfo *NamespcName,
+                                        AttributeList *AttrList);
+
+  /// ActOnNamespaceAliasDef - This is called when a namespace alias definition
+  /// is parsed.
+  virtual DeclPtrTy ActOnNamespaceAliasDef(Scope *CurScope,
+                                           SourceLocation NamespaceLoc,
+                                           SourceLocation AliasLoc,
+                                           IdentifierInfo *Alias,
+                                           CXXScopeSpec &SS,
+                                           SourceLocation IdentLoc,
+                                           IdentifierInfo *Ident) {
+    return DeclPtrTy();
+  }
+
+  /// \brief Parsed a C++ using-declaration.
+  ///
+  /// This callback will be invoked when the parser has parsed a C++
+  /// using-declaration, e.g.,
+  ///
+  /// \code
+  /// namespace std {
+  ///   template<typename T, typename Alloc> class vector;
+  /// }
+  ///
+  /// using std::vector; // using-declaration here
+  /// \endcode
+  ///
+  /// \param CurScope the scope in which this using declaration was parsed.
+  ///
+  /// \param AS the currently-active access specifier.
+  ///
+  /// \param HasUsingKeyword true if this was declared with an
+  ///   explicit 'using' keyword (i.e. if this is technically a using
+  ///   declaration, not an access declaration)
+  ///
+  /// \param UsingLoc the location of the 'using' keyword.
+  ///
+  /// \param SS the nested-name-specifier that precedes the name.
+  ///
+  /// \param Name the name to which the using declaration refers.
+  ///
+  /// \param AttrList attributes applied to this using declaration, if any.
+  ///
+  /// \param IsTypeName whether this using declaration started with the 
+  /// 'typename' keyword. FIXME: This will eventually be split into a 
+  /// separate action.
+  ///
+  /// \param TypenameLoc the location of the 'typename' keyword, if present
+  ///
+  /// \returns a representation of the using declaration.
+  virtual DeclPtrTy ActOnUsingDeclaration(Scope *CurScope,
+                                          AccessSpecifier AS,
+                                          bool HasUsingKeyword,
+                                          SourceLocation UsingLoc,
+                                          CXXScopeSpec &SS,
+                                          UnqualifiedId &Name,
+                                          AttributeList *AttrList,
+                                          bool IsTypeName,
+                                          SourceLocation TypenameLoc);
+
+  /// ActOnParamDefaultArgument - Parse default argument for function parameter
+  virtual void ActOnParamDefaultArgument(DeclPtrTy param,
+                                         SourceLocation EqualLoc,
+                                         ExprArg defarg) {
+  }
+
+  /// ActOnParamUnparsedDefaultArgument - We've seen a default
+  /// argument for a function parameter, but we can't parse it yet
+  /// because we're inside a class definition. Note that this default
+  /// argument will be parsed later.
+  virtual void ActOnParamUnparsedDefaultArgument(DeclPtrTy param,
+                                                 SourceLocation EqualLoc,
+                                                 SourceLocation ArgLoc) { }
+
+  /// ActOnParamDefaultArgumentError - Parsing or semantic analysis of
+  /// the default argument for the parameter param failed.
+  virtual void ActOnParamDefaultArgumentError(DeclPtrTy param) { }
+
+  /// AddCXXDirectInitializerToDecl - This action is called immediately after
+  /// ActOnDeclarator, when a C++ direct initializer is present.
+  /// e.g: "int x(1);"
+  virtual void AddCXXDirectInitializerToDecl(DeclPtrTy Dcl,
+                                             SourceLocation LParenLoc,
+                                             MultiExprArg Exprs,
+                                             SourceLocation *CommaLocs,
+                                             SourceLocation RParenLoc) {
+    return;
+  }
+
+  /// \brief Called when we re-enter a template parameter scope.
+  ///
+  /// This action occurs when we are going to parse an member
+  /// function's default arguments or inline definition after the
+  /// outermost class definition has been completed, and when one or
+  /// more of the class definitions enclosing the member function is a
+  /// template. The "entity" in the given scope will be set as it was
+  /// when we entered the scope of the template initially, and should
+  /// be used to, e.g., reintroduce the names of template parameters
+  /// into the current scope so that they can be found by name lookup.
+  ///
+  /// \param S The (new) template parameter scope.
+  ///
+  /// \param Template the class template declaration whose template
+  /// parameters should be reintroduced into the current scope.
+  virtual void ActOnReenterTemplateScope(Scope *S, DeclPtrTy Template) {
+  }
+
+  /// ActOnStartDelayedMemberDeclarations - We have completed parsing
+  /// a C++ class, and we are about to start parsing any parts of
+  /// member declarations that could not be parsed earlier.  Enter
+  /// the appropriate record scope.
+  virtual void ActOnStartDelayedMemberDeclarations(Scope *S,
+                                                   DeclPtrTy Record) {
+  }
+
+  /// ActOnStartDelayedCXXMethodDeclaration - We have completed
+  /// parsing a top-level (non-nested) C++ class, and we are now
+  /// parsing those parts of the given Method declaration that could
+  /// not be parsed earlier (C++ [class.mem]p2), such as default
+  /// arguments. This action should enter the scope of the given
+  /// Method declaration as if we had just parsed the qualified method
+  /// name. However, it should not bring the parameters into scope;
+  /// that will be performed by ActOnDelayedCXXMethodParameter.
+  virtual void ActOnStartDelayedCXXMethodDeclaration(Scope *S,
+                                                     DeclPtrTy Method) {
+  }
+
+  /// ActOnDelayedCXXMethodParameter - We've already started a delayed
+  /// C++ method declaration. We're (re-)introducing the given
+  /// function parameter into scope for use in parsing later parts of
+  /// the method declaration. For example, we could see an
+  /// ActOnParamDefaultArgument event for this parameter.
+  virtual void ActOnDelayedCXXMethodParameter(Scope *S, DeclPtrTy Param) {
+  }
+
+  /// ActOnFinishDelayedCXXMethodDeclaration - We have finished
+  /// processing the delayed method declaration for Method. The method
+  /// declaration is now considered finished. There may be a separate
+  /// ActOnStartOfFunctionDef action later (not necessarily
+  /// immediately!) for this method, if it was also defined inside the
+  /// class body.
+  virtual void ActOnFinishDelayedCXXMethodDeclaration(Scope *S,
+                                                      DeclPtrTy Method) {
+  }
+
+  /// ActOnFinishDelayedMemberDeclarations - We have finished parsing
+  /// a C++ class, and we are about to start parsing any parts of
+  /// member declarations that could not be parsed earlier.  Enter the
+  /// appropriate record scope.
+  virtual void ActOnFinishDelayedMemberDeclarations(Scope *S,
+                                                    DeclPtrTy Record) {
+  }
+
+  /// ActOnStaticAssertDeclaration - Parse a C++0x static_assert declaration.
+  virtual DeclPtrTy ActOnStaticAssertDeclaration(SourceLocation AssertLoc,
+                                                 ExprArg AssertExpr,
+                                                 ExprArg AssertMessageExpr) {
+    return DeclPtrTy();
+  }
+
+  /// ActOnFriendFunctionDecl - Parsed a friend function declarator.
+  /// The name is actually a slight misnomer, because the declarator
+  /// is not necessarily a function declarator.
+  virtual DeclPtrTy ActOnFriendFunctionDecl(Scope *S,
+                                            Declarator &D,
+                                            bool IsDefinition,
+                                            MultiTemplateParamsArg TParams) {
+    return DeclPtrTy();
+  }
+
+  /// ActOnFriendTypeDecl - Parsed a friend type declaration.
+  virtual DeclPtrTy ActOnFriendTypeDecl(Scope *S, const DeclSpec &DS,
+                                        MultiTemplateParamsArg TParams) {
+    return DeclPtrTy();
+  }
+
+  //===------------------------- C++ Expressions --------------------------===//
+
+  /// \brief Parsed a destructor name or pseudo-destructor name. 
+  ///
+  /// \returns the type being destructed.
+  virtual TypeTy *getDestructorName(SourceLocation TildeLoc,
+                                    IdentifierInfo &II, SourceLocation NameLoc,
+                                    Scope *S, CXXScopeSpec &SS,
+                                    TypeTy *ObjectType,
+                                    bool EnteringContext) {
+    return getTypeName(II, NameLoc, S, &SS, false, ObjectType);
+  }
+
+
+  /// ActOnCXXNamedCast - Parse {dynamic,static,reinterpret,const}_cast's.
+  virtual OwningExprResult ActOnCXXNamedCast(SourceLocation OpLoc,
+                                             tok::TokenKind Kind,
+                                             SourceLocation LAngleBracketLoc,
+                                             TypeTy *Ty,
+                                             SourceLocation RAngleBracketLoc,
+                                             SourceLocation LParenLoc,
+                                             ExprArg Op,
+                                             SourceLocation RParenLoc) {
+    return ExprEmpty();
+  }
+
+  /// ActOnCXXTypeidOfType - Parse typeid( type-id ).
+  virtual OwningExprResult ActOnCXXTypeid(SourceLocation OpLoc,
+                                          SourceLocation LParenLoc, bool isType,
+                                          void *TyOrExpr,
+                                          SourceLocation RParenLoc) {
+    return ExprEmpty();
+  }
+
+  /// ActOnCXXThis - Parse the C++ 'this' pointer.
+  virtual OwningExprResult ActOnCXXThis(SourceLocation ThisLoc) {
+    return ExprEmpty();
+  }
+
+  /// ActOnCXXBoolLiteral - Parse {true,false} literals.
+  virtual OwningExprResult ActOnCXXBoolLiteral(SourceLocation OpLoc,
+                                               tok::TokenKind Kind) {
+    return ExprEmpty();
+  }
+
+  /// ActOnCXXNullPtrLiteral - Parse 'nullptr'.
+  virtual OwningExprResult ActOnCXXNullPtrLiteral(SourceLocation Loc) {
+    return ExprEmpty();
+  }
+
+  /// ActOnCXXThrow - Parse throw expressions.
+  virtual OwningExprResult ActOnCXXThrow(SourceLocation OpLoc, ExprArg Op) {
+    return ExprEmpty();
+  }
+
+  /// ActOnCXXTypeConstructExpr - Parse construction of a specified type.
+  /// Can be interpreted either as function-style casting ("int(x)")
+  /// or class type construction ("ClassType(x,y,z)")
+  /// or creation of a value-initialized type ("int()").
+  virtual OwningExprResult ActOnCXXTypeConstructExpr(SourceRange TypeRange,
+                                                     TypeTy *TypeRep,
+                                                     SourceLocation LParenLoc,
+                                                     MultiExprArg Exprs,
+                                                     SourceLocation *CommaLocs,
+                                                     SourceLocation RParenLoc) {
+    return ExprEmpty();
+  }
+
+  /// \brief Parsed a condition declaration in a C++ if, switch, or while
+  /// statement.
+  /// 
+  /// This callback will be invoked after parsing the declaration of "x" in
+  ///
+  /// \code
+  /// if (int x = f()) {
+  ///   // ...
+  /// }
+  /// \endcode
+  ///
+  /// \param S the scope of the if, switch, or while statement.
+  ///
+  /// \param D the declarator that that describes the variable being declared.
+  virtual DeclResult ActOnCXXConditionDeclaration(Scope *S, Declarator &D) {
+    return DeclResult();
+  }
+
+  /// ActOnCXXNew - Parsed a C++ 'new' expression. UseGlobal is true if the
+  /// new was qualified (::new). In a full new like
+  /// @code new (p1, p2) type(c1, c2) @endcode
+  /// the p1 and p2 expressions will be in PlacementArgs and the c1 and c2
+  /// expressions in ConstructorArgs. The type is passed as a declarator.
+  virtual OwningExprResult ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal,
+                                       SourceLocation PlacementLParen,
+                                       MultiExprArg PlacementArgs,
+                                       SourceLocation PlacementRParen,
+                                       bool ParenTypeId, Declarator &D,
+                                       SourceLocation ConstructorLParen,
+                                       MultiExprArg ConstructorArgs,
+                                       SourceLocation ConstructorRParen) {
+    return ExprEmpty();
+  }
+
+  /// ActOnCXXDelete - Parsed a C++ 'delete' expression. UseGlobal is true if
+  /// the delete was qualified (::delete). ArrayForm is true if the array form
+  /// was used (delete[]).
+  virtual OwningExprResult ActOnCXXDelete(SourceLocation StartLoc,
+                                          bool UseGlobal, bool ArrayForm,
+                                          ExprArg Operand) {
+    return ExprEmpty();
+  }
+
+  virtual OwningExprResult ActOnUnaryTypeTrait(UnaryTypeTrait OTT,
+                                               SourceLocation KWLoc,
+                                               SourceLocation LParen,
+                                               TypeTy *Ty,
+                                               SourceLocation RParen) {
+    return ExprEmpty();
+  }
+
+  /// \brief Invoked when the parser is starting to parse a C++ member access
+  /// expression such as x.f or x->f.
+  ///
+  /// \param S the scope in which the member access expression occurs.
+  ///
+  /// \param Base the expression in which a member is being accessed, e.g., the
+  /// "x" in "x.f".
+  ///
+  /// \param OpLoc the location of the member access operator ("." or "->")
+  ///
+  /// \param OpKind the kind of member access operator ("." or "->")
+  ///
+  /// \param ObjectType originally NULL. The action should fill in this type
+  /// with the type into which name lookup should look to find the member in
+  /// the member access expression.
+  ///
+  /// \param MayBePseudoDestructor Originally false. The action should
+  /// set this true if the expression may end up being a
+  /// pseudo-destructor expression, indicating to the parser that it
+  /// shoudl be parsed as a pseudo-destructor rather than as a member
+  /// access expression. Note that this should apply both when the
+  /// object type is a scalar and when the object type is dependent.
+  ///
+  /// \returns the (possibly modified) \p Base expression
+  virtual OwningExprResult ActOnStartCXXMemberReference(Scope *S,
+                                                        ExprArg Base,
+                                                        SourceLocation OpLoc,
+                                                        tok::TokenKind OpKind,
+                                                        TypeTy *&ObjectType,
+                                                  bool &MayBePseudoDestructor) {
+    return ExprEmpty();
+  }
+
+  /// \brief Parsed a C++ pseudo-destructor expression or a dependent
+  /// member access expression that has the same syntactic form as a
+  /// pseudo-destructor expression.
+  ///
+  /// \param S The scope in which the member access expression occurs.
+  ///
+  /// \param Base The expression in which a member is being accessed, e.g., the
+  /// "x" in "x.f".
+  ///
+  /// \param OpLoc The location of the member access operator ("." or "->")
+  ///
+  /// \param OpKind The kind of member access operator ("." or "->")
+  ///
+  /// \param SS The nested-name-specifier that precedes the type names
+  /// in the grammar. Note that this nested-name-specifier will not
+  /// cover the last "type-name ::" in the grammar, because it isn't
+  /// necessarily a nested-name-specifier.
+  ///
+  /// \param FirstTypeName The type name that follows the optional
+  /// nested-name-specifier but precedes the '::', e.g., the first
+  /// type-name in "type-name :: type-name". This type name may be
+  /// empty. This will be either an identifier or a template-id.
+  ///
+  /// \param CCLoc The location of the '::' in "type-name ::
+  /// typename". May be invalid, if there is no \p FirstTypeName.
+  ///
+  /// \param TildeLoc The location of the '~'.
+  ///
+  /// \param SecondTypeName The type-name following the '~', which is
+  /// the name of the type being destroyed. This will be either an
+  /// identifier or a template-id.
+  ///
+  /// \param HasTrailingLParen Whether the next token in the stream is
+  /// a left parentheses.
+  virtual OwningExprResult ActOnPseudoDestructorExpr(Scope *S, ExprArg Base,
+                                                     SourceLocation OpLoc,
+                                                     tok::TokenKind OpKind,
+                                                     CXXScopeSpec &SS,
+                                                  UnqualifiedId &FirstTypeName,
+                                                     SourceLocation CCLoc,
+                                                     SourceLocation TildeLoc,
+                                                 UnqualifiedId &SecondTypeName,
+                                                     bool HasTrailingLParen) {
+    return ExprEmpty();
+  }
+
+  /// ActOnFinishFullExpr - Called whenever a full expression has been parsed.
+  /// (C++ [intro.execution]p12).
+  virtual OwningExprResult ActOnFinishFullExpr(ExprArg Expr) {
+    return move(Expr);
+  }
+
+  //===---------------------------- C++ Classes ---------------------------===//
+  /// ActOnBaseSpecifier - Parsed a base specifier
+  virtual BaseResult ActOnBaseSpecifier(DeclPtrTy classdecl,
+                                        SourceRange SpecifierRange,
+                                        bool Virtual, AccessSpecifier Access,
+                                        TypeTy *basetype,
+                                        SourceLocation BaseLoc) {
+    return BaseResult();
+  }
+
+  virtual void ActOnBaseSpecifiers(DeclPtrTy ClassDecl, BaseTy **Bases,
+                                   unsigned NumBases) {
+  }
+
+  /// ActOnCXXMemberDeclarator - This is invoked when a C++ class member
+  /// declarator is parsed. 'AS' is the access specifier, 'BitfieldWidth'
+  /// specifies the bitfield width if there is one and 'Init' specifies the
+  /// initializer if any.  'Deleted' is true if there's a =delete
+  /// specifier on the function.
+  virtual DeclPtrTy ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS,
+                                             Declarator &D,
+                                 MultiTemplateParamsArg TemplateParameterLists,
+                                             ExprTy *BitfieldWidth,
+                                             ExprTy *Init,
+                                             bool IsDefinition,
+                                             bool Deleted = false) {
+    return DeclPtrTy();
+  }
+
+  virtual MemInitResult ActOnMemInitializer(DeclPtrTy ConstructorDecl,
+                                            Scope *S,
+                                            CXXScopeSpec &SS,
+                                            IdentifierInfo *MemberOrBase,
+                                            TypeTy *TemplateTypeTy,
+                                            SourceLocation IdLoc,
+                                            SourceLocation LParenLoc,
+                                            ExprTy **Args, unsigned NumArgs,
+                                            SourceLocation *CommaLocs,
+                                            SourceLocation RParenLoc) {
+    return true;
+  }
+
+  /// ActOnMemInitializers - This is invoked when all of the member
+  /// initializers of a constructor have been parsed. ConstructorDecl
+  /// is the function declaration (which will be a C++ constructor in
+  /// a well-formed program), ColonLoc is the location of the ':' that
+  /// starts the constructor initializer, and MemInit/NumMemInits
+  /// contains the individual member (and base) initializers.
+  /// AnyErrors will be true if there were any invalid member initializers
+  /// that are not represented in the list.
+  virtual void ActOnMemInitializers(DeclPtrTy ConstructorDecl,
+                                    SourceLocation ColonLoc,
+                                    MemInitTy **MemInits, unsigned NumMemInits,
+                                    bool AnyErrors){
+  }
+
+ virtual void ActOnDefaultCtorInitializers(DeclPtrTy CDtorDecl) {}
+
+  /// ActOnFinishCXXMemberSpecification - Invoked after all member declarators
+  /// are parsed but *before* parsing of inline method definitions.
+  virtual void ActOnFinishCXXMemberSpecification(Scope* S, SourceLocation RLoc,
+                                                 DeclPtrTy TagDecl,
+                                                 SourceLocation LBrac,
+                                                 SourceLocation RBrac,
+                                                 AttributeList *AttrList) {
+  }
+
+  //===---------------------------C++ Templates----------------------------===//
+
+  /// ActOnTypeParameter - Called when a C++ template type parameter
+  /// (e.g., "typename T") has been parsed. Typename specifies whether
+  /// the keyword "typename" was used to declare the type parameter
+  /// (otherwise, "class" was used), ellipsis specifies whether this is a
+  /// C++0x parameter pack, EllipsisLoc specifies the start of the ellipsis,
+  /// and KeyLoc is the location of the "class" or "typename" keyword.
+  //  ParamName is the name of the parameter (NULL indicates an unnamed template
+  //  parameter) and ParamNameLoc is the location of the parameter name (if any)
+  /// If the type parameter has a default argument, it will be added
+  /// later via ActOnTypeParameterDefault. Depth and Position provide
+  /// the number of enclosing templates (see
+  /// ActOnTemplateParameterList) and the number of previous
+  /// parameters within this template parameter list.
+  virtual DeclPtrTy ActOnTypeParameter(Scope *S, bool Typename, bool Ellipsis,
+                                       SourceLocation EllipsisLoc,
+                                       SourceLocation KeyLoc,
+                                       IdentifierInfo *ParamName,
+                                       SourceLocation ParamNameLoc,
+                                       unsigned Depth, unsigned Position) {
+    return DeclPtrTy();
+  }
+
+  /// ActOnTypeParameterDefault - Adds a default argument (the type
+  /// Default) to the given template type parameter (TypeParam).
+  virtual void ActOnTypeParameterDefault(DeclPtrTy TypeParam,
+                                         SourceLocation EqualLoc,
+                                         SourceLocation DefaultLoc,
+                                         TypeTy *Default) {
+  }
+
+  /// ActOnNonTypeTemplateParameter - Called when a C++ non-type
+  /// template parameter (e.g., "int Size" in "template<int Size>
+  /// class Array") has been parsed. S is the current scope and D is
+  /// the parsed declarator. Depth and Position provide the number of
+  /// enclosing templates (see
+  /// ActOnTemplateParameterList) and the number of previous
+  /// parameters within this template parameter list.
+  virtual DeclPtrTy ActOnNonTypeTemplateParameter(Scope *S, Declarator &D,
+                                                  unsigned Depth,
+                                                  unsigned Position) {
+    return DeclPtrTy();
+  }
+
+  /// \brief Adds a default argument to the given non-type template
+  /// parameter.
+  virtual void ActOnNonTypeTemplateParameterDefault(DeclPtrTy TemplateParam,
+                                                    SourceLocation EqualLoc,
+                                                    ExprArg Default) {
+  }
+
+  /// ActOnTemplateTemplateParameter - Called when a C++ template template
+  /// parameter (e.g., "int T" in "template<template <typename> class T> class
+  /// Array") has been parsed. TmpLoc is the location of the "template" keyword,
+  /// TemplateParams is the sequence of parameters required by the template,
+  /// ParamName is the name of the parameter (null if unnamed), and ParamNameLoc
+  /// is the source location of the identifier (if given).
+  virtual DeclPtrTy ActOnTemplateTemplateParameter(Scope *S,
+                                                   SourceLocation TmpLoc,
+                                                   TemplateParamsTy *Params,
+                                                   IdentifierInfo *ParamName,
+                                                   SourceLocation ParamNameLoc,
+                                                   unsigned Depth,
+                                                   unsigned Position) {
+    return DeclPtrTy();
+  }
+
+  /// \brief Adds a default argument to the given template template
+  /// parameter.
+  virtual void ActOnTemplateTemplateParameterDefault(DeclPtrTy TemplateParam,
+                                                     SourceLocation EqualLoc,
+                                        const ParsedTemplateArgument &Default) {
+  }
+
+  /// ActOnTemplateParameterList - Called when a complete template
+  /// parameter list has been parsed, e.g.,
+  ///
+  /// @code
+  /// export template<typename T, T Size>
+  /// @endcode
+  ///
+  /// Depth is the number of enclosing template parameter lists. This
+  /// value does not include templates from outer scopes. For example:
+  ///
+  /// @code
+  /// template<typename T> // depth = 0
+  ///   class A {
+  ///     template<typename U> // depth = 0
+  ///       class B;
+  ///   };
+  ///
+  /// template<typename T> // depth = 0
+  ///   template<typename U> // depth = 1
+  ///     class A<T>::B { ... };
+  /// @endcode
+  ///
+  /// ExportLoc, if valid, is the position of the "export"
+  /// keyword. Otherwise, "export" was not specified.
+  /// TemplateLoc is the position of the template keyword, LAngleLoc
+  /// is the position of the left angle bracket, and RAngleLoc is the
+  /// position of the corresponding right angle bracket.
+  /// Params/NumParams provides the template parameters that were
+  /// parsed as part of the template-parameter-list.
+  virtual TemplateParamsTy *
+  ActOnTemplateParameterList(unsigned Depth,
+                             SourceLocation ExportLoc,
+                             SourceLocation TemplateLoc,
+                             SourceLocation LAngleLoc,
+                             DeclPtrTy *Params, unsigned NumParams,
+                             SourceLocation RAngleLoc) {
+    return 0;
+  }
+
+  /// \brief Form a type from a template and a list of template
+  /// arguments.
+  ///
+  /// This action merely forms the type for the template-id, possibly
+  /// checking well-formedness of the template arguments. It does not
+  /// imply the declaration of any entity.
+  ///
+  /// \param Template  A template whose specialization results in a
+  /// type, e.g., a class template or template template parameter.
+  virtual TypeResult ActOnTemplateIdType(TemplateTy Template,
+                                         SourceLocation TemplateLoc,
+                                         SourceLocation LAngleLoc,
+                                         ASTTemplateArgsPtr TemplateArgs,
+                                         SourceLocation RAngleLoc) {
+    return TypeResult();
+  }
+
+  /// \brief Note that a template ID was used with a tag.
+  ///
+  /// \param Type The result of ActOnTemplateIdType.
+  ///
+  /// \param TUK Either TUK_Reference or TUK_Friend.  Declarations and
+  /// definitions are interpreted as explicit instantiations or
+  /// specializations.
+  ///
+  /// \param TagSpec The tag keyword that was provided as part of the
+  /// elaborated-type-specifier;  either class, struct, union, or enum.
+  ///
+  /// \param TagLoc The location of the tag keyword.
+  virtual TypeResult ActOnTagTemplateIdType(TypeResult Type,
+                                            TagUseKind TUK,
+                                            DeclSpec::TST TagSpec,
+                                            SourceLocation TagLoc) {
+    return TypeResult();
+  }
+
+  /// \brief Form a dependent template name.
+  ///
+  /// This action forms a dependent template name given the template
+  /// name and its (presumably dependent) scope specifier. For
+  /// example, given "MetaFun::template apply", the scope specifier \p
+  /// SS will be "MetaFun::", \p TemplateKWLoc contains the location
+  /// of the "template" keyword, and "apply" is the \p Name.
+  ///
+  /// \param TemplateKWLoc the location of the "template" keyword (if any).
+  ///
+  /// \param SS the nested-name-specifier that precedes the "template" keyword
+  /// or the template name. If the dependent template name occurs in
+  /// a member access expression, e.g., "x.template f<T>", this
+  /// nested-name-specifier will be empty.
+  ///
+  /// \param Name the name of the template.
+  ///
+  /// \param ObjectType if this dependent template name occurs in the
+  /// context of a member access expression, the type of the object being
+  /// accessed.
+  ///
+  /// \param EnteringContext whether we are entering the context of this
+  /// template.
+  virtual TemplateTy ActOnDependentTemplateName(SourceLocation TemplateKWLoc,
+                                                CXXScopeSpec &SS,
+                                                UnqualifiedId &Name,
+                                                TypeTy *ObjectType,
+                                                bool EnteringContext) {
+    return TemplateTy();
+  }
+
+  /// \brief Process the declaration or definition of an explicit
+  /// class template specialization or a class template partial
+  /// specialization.
+  ///
+  /// This routine is invoked when an explicit class template
+  /// specialization or a class template partial specialization is
+  /// declared or defined, to introduce the (partial) specialization
+  /// and produce a declaration for it. In the following example,
+  /// ActOnClassTemplateSpecialization will be invoked for the
+  /// declarations at both A and B:
+  ///
+  /// \code
+  /// template<typename T> class X;
+  /// template<> class X<int> { }; // A: explicit specialization
+  /// template<typename T> class X<T*> { }; // B: partial specialization
+  /// \endcode
+  ///
+  /// Note that it is the job of semantic analysis to determine which
+  /// of the two cases actually occurred in the source code, since
+  /// they are parsed through the same path. The formulation of the
+  /// template parameter lists describes which case we are in.
+  ///
+  /// \param S the current scope
+  ///
+  /// \param TagSpec whether this declares a class, struct, or union
+  /// (template)
+  ///
+  /// \param TUK whether this is a declaration or a definition
+  ///
+  /// \param KWLoc the location of the 'class', 'struct', or 'union'
+  /// keyword.
+  ///
+  /// \param SS the scope specifier preceding the template-id
+  ///
+  /// \param Template the declaration of the class template that we
+  /// are specializing.
+  ///
+  /// \param Attr attributes on the specialization
+  ///
+  /// \param TemplateParameterLists the set of template parameter
+  /// lists that apply to this declaration. In a well-formed program,
+  /// the number of template parameter lists will be one more than the
+  /// number of template-ids in the scope specifier. However, it is
+  /// common for users to provide the wrong number of template
+  /// parameter lists (such as a missing \c template<> prior to a
+  /// specialization); the parser does not check this condition.
+  virtual DeclResult
+  ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagUseKind TUK,
+                                   SourceLocation KWLoc,
+                                   CXXScopeSpec &SS,
+                                   TemplateTy Template,
+                                   SourceLocation TemplateNameLoc,
+                                   SourceLocation LAngleLoc,
+                                   ASTTemplateArgsPtr TemplateArgs,
+                                   SourceLocation RAngleLoc,
+                                   AttributeList *Attr,
+                              MultiTemplateParamsArg TemplateParameterLists) {
+    return DeclResult();
+  }
+
+  /// \brief Invoked when a declarator that has one or more template parameter
+  /// lists has been parsed.
+  ///
+  /// This action is similar to ActOnDeclarator(), except that the declaration
+  /// being created somehow involves a template, e.g., it is a template
+  /// declaration or specialization.
+  virtual DeclPtrTy ActOnTemplateDeclarator(Scope *S,
+                              MultiTemplateParamsArg TemplateParameterLists,
+                                            Declarator &D) {
+    return DeclPtrTy();
+  }
+
+  /// \brief Invoked when the parser is beginning to parse a function template
+  /// or function template specialization definition.
+  virtual DeclPtrTy ActOnStartOfFunctionTemplateDef(Scope *FnBodyScope,
+                                MultiTemplateParamsArg TemplateParameterLists,
+                                                    Declarator &D) {
+    return DeclPtrTy();
+  }
+
+  /// \brief Process the explicit instantiation of a class template
+  /// specialization.
+  ///
+  /// This routine is invoked when an explicit instantiation of a
+  /// class template specialization is encountered. In the following
+  /// example, ActOnExplicitInstantiation will be invoked to force the
+  /// instantiation of X<int>:
+  ///
+  /// \code
+  /// template<typename T> class X { /* ... */ };
+  /// template class X<int>; // explicit instantiation
+  /// \endcode
+  ///
+  /// \param S the current scope
+  ///
+  /// \param ExternLoc the location of the 'extern' keyword that specifies that
+  /// this is an extern template (if any).
+  ///
+  /// \param TemplateLoc the location of the 'template' keyword that
+  /// specifies that this is an explicit instantiation.
+  ///
+  /// \param TagSpec whether this declares a class, struct, or union
+  /// (template).
+  ///
+  /// \param KWLoc the location of the 'class', 'struct', or 'union'
+  /// keyword.
+  ///
+  /// \param SS the scope specifier preceding the template-id.
+  ///
+  /// \param Template the declaration of the class template that we
+  /// are instantiation.
+  ///
+  /// \param LAngleLoc the location of the '<' token in the template-id.
+  ///
+  /// \param TemplateArgs the template arguments used to form the
+  /// template-id.
+  ///
+  /// \param TemplateArgLocs the locations of the template arguments.
+  ///
+  /// \param RAngleLoc the location of the '>' token in the template-id.
+  ///
+  /// \param Attr attributes that apply to this instantiation.
+  virtual DeclResult
+  ActOnExplicitInstantiation(Scope *S,
+                             SourceLocation ExternLoc,
+                             SourceLocation TemplateLoc,
+                             unsigned TagSpec,
+                             SourceLocation KWLoc,
+                             const CXXScopeSpec &SS,
+                             TemplateTy Template,
+                             SourceLocation TemplateNameLoc,
+                             SourceLocation LAngleLoc,
+                             ASTTemplateArgsPtr TemplateArgs,
+                             SourceLocation RAngleLoc,
+                             AttributeList *Attr) {
+    return DeclResult();
+  }
+
+  /// \brief Process the explicit instantiation of a member class of a
+  /// class template specialization.
+  ///
+  /// This routine is invoked when an explicit instantiation of a
+  /// member class of a class template specialization is
+  /// encountered. In the following example,
+  /// ActOnExplicitInstantiation will be invoked to force the
+  /// instantiation of X<int>::Inner:
+  ///
+  /// \code
+  /// template<typename T> class X { class Inner { /* ... */}; };
+  /// template class X<int>::Inner; // explicit instantiation
+  /// \endcode
+  ///
+  /// \param S the current scope
+  ///
+  /// \param ExternLoc the location of the 'extern' keyword that specifies that
+  /// this is an extern template (if any).
+  ///
+  /// \param TemplateLoc the location of the 'template' keyword that
+  /// specifies that this is an explicit instantiation.
+  ///
+  /// \param TagSpec whether this declares a class, struct, or union
+  /// (template).
+  ///
+  /// \param KWLoc the location of the 'class', 'struct', or 'union'
+  /// keyword.
+  ///
+  /// \param SS the scope specifier preceding the template-id.
+  ///
+  /// \param Template the declaration of the class template that we
+  /// are instantiation.
+  ///
+  /// \param LAngleLoc the location of the '<' token in the template-id.
+  ///
+  /// \param TemplateArgs the template arguments used to form the
+  /// template-id.
+  ///
+  /// \param TemplateArgLocs the locations of the template arguments.
+  ///
+  /// \param RAngleLoc the location of the '>' token in the template-id.
+  ///
+  /// \param Attr attributes that apply to this instantiation.
+  virtual DeclResult
+  ActOnExplicitInstantiation(Scope *S,
+                             SourceLocation ExternLoc,
+                             SourceLocation TemplateLoc,
+                             unsigned TagSpec,
+                             SourceLocation KWLoc,
+                             CXXScopeSpec &SS,
+                             IdentifierInfo *Name,
+                             SourceLocation NameLoc,
+                             AttributeList *Attr) {
+    return DeclResult();
+  }
+
+  /// \brief Process the explicit instantiation of a function template or a
+  /// member of a class template.
+  ///
+  /// This routine is invoked when an explicit instantiation of a
+  /// function template or member function of a class template specialization 
+  /// is encountered. In the following example,
+  /// ActOnExplicitInstantiation will be invoked to force the
+  /// instantiation of X<int>:
+  ///
+  /// \code
+  /// template<typename T> void f(T);
+  /// template void f(int); // explicit instantiation
+  /// \endcode
+  ///
+  /// \param S the current scope
+  ///
+  /// \param ExternLoc the location of the 'extern' keyword that specifies that
+  /// this is an extern template (if any).
+  ///
+  /// \param TemplateLoc the location of the 'template' keyword that
+  /// specifies that this is an explicit instantiation.
+  ///
+  /// \param D the declarator describing the declaration to be implicitly
+  /// instantiated.
+  virtual DeclResult ActOnExplicitInstantiation(Scope *S,
+                                                SourceLocation ExternLoc,
+                                                SourceLocation TemplateLoc,
+                                                Declarator &D) {
+    return DeclResult();
+  }
+                             
+                              
+  /// \brief Called when the parser has parsed a C++ typename
+  /// specifier that ends in an identifier, e.g., "typename T::type".
+  ///
+  /// \param TypenameLoc the location of the 'typename' keyword
+  /// \param SS the nested-name-specifier following the typename (e.g., 'T::').
+  /// \param II the identifier we're retrieving (e.g., 'type' in the example).
+  /// \param IdLoc the location of the identifier.
+  virtual TypeResult
+  ActOnTypenameType(SourceLocation TypenameLoc, const CXXScopeSpec &SS,
+                    const IdentifierInfo &II, SourceLocation IdLoc) {
+    return TypeResult();
+  }
+
+  /// \brief Called when the parser has parsed a C++ typename
+  /// specifier that ends in a template-id, e.g.,
+  /// "typename MetaFun::template apply<T1, T2>".
+  ///
+  /// \param TypenameLoc the location of the 'typename' keyword
+  /// \param SS the nested-name-specifier following the typename (e.g., 'T::').
+  /// \param TemplateLoc the location of the 'template' keyword, if any.
+  /// \param Ty the type that the typename specifier refers to.
+  virtual TypeResult
+  ActOnTypenameType(SourceLocation TypenameLoc, const CXXScopeSpec &SS,
+                    SourceLocation TemplateLoc, TypeTy *Ty) {
+    return TypeResult();
+  }
+
+  //===----------------------- Obj-C Declarations -------------------------===//
+
+  // ActOnStartClassInterface - this action is called immediately after parsing
+  // the prologue for a class interface (before parsing the instance
+  // variables). Instance variables are processed by ActOnFields().
+  virtual DeclPtrTy ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
+                                             IdentifierInfo *ClassName,
+                                             SourceLocation ClassLoc,
+                                             IdentifierInfo *SuperName,
+                                             SourceLocation SuperLoc,
+                                             const DeclPtrTy *ProtoRefs,
+                                             unsigned NumProtoRefs,
+                                             const SourceLocation *ProtoLocs,
+                                             SourceLocation EndProtoLoc,
+                                             AttributeList *AttrList) {
+    return DeclPtrTy();
+  }
+
+  /// ActOnCompatiblityAlias - this action is called after complete parsing of
+  /// @compaatibility_alias declaration. It sets up the alias relationships.
+  virtual DeclPtrTy ActOnCompatiblityAlias(
+    SourceLocation AtCompatibilityAliasLoc,
+    IdentifierInfo *AliasName,  SourceLocation AliasLocation,
+    IdentifierInfo *ClassName, SourceLocation ClassLocation) {
+    return DeclPtrTy();
+  }
+
+  // ActOnStartProtocolInterface - this action is called immdiately after
+  // parsing the prologue for a protocol interface.
+  virtual DeclPtrTy ActOnStartProtocolInterface(SourceLocation AtProtoLoc,
+                                                IdentifierInfo *ProtocolName,
+                                                SourceLocation ProtocolLoc,
+                                                const DeclPtrTy *ProtoRefs,
+                                                unsigned NumProtoRefs,
+                                                const SourceLocation *ProtoLocs,
+                                                SourceLocation EndProtoLoc,
+                                                AttributeList *AttrList) {
+    return DeclPtrTy();
+  }
+  // ActOnStartCategoryInterface - this action is called immdiately after
+  // parsing the prologue for a category interface.
+  virtual DeclPtrTy ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc,
+                                                IdentifierInfo *ClassName,
+                                                SourceLocation ClassLoc,
+                                                IdentifierInfo *CategoryName,
+                                                SourceLocation CategoryLoc,
+                                                const DeclPtrTy *ProtoRefs,
+                                                unsigned NumProtoRefs,
+                                                const SourceLocation *ProtoLocs,
+                                                SourceLocation EndProtoLoc) {
+    return DeclPtrTy();
+  }
+  // ActOnStartClassImplementation - this action is called immdiately after
+  // parsing the prologue for a class implementation. Instance variables are
+  // processed by ActOnFields().
+  virtual DeclPtrTy ActOnStartClassImplementation(
+    SourceLocation AtClassImplLoc,
+    IdentifierInfo *ClassName,
+    SourceLocation ClassLoc,
+    IdentifierInfo *SuperClassname,
+    SourceLocation SuperClassLoc) {
+    return DeclPtrTy();
+  }
+  // ActOnStartCategoryImplementation - this action is called immdiately after
+  // parsing the prologue for a category implementation.
+  virtual DeclPtrTy ActOnStartCategoryImplementation(
+    SourceLocation AtCatImplLoc,
+    IdentifierInfo *ClassName,
+    SourceLocation ClassLoc,
+    IdentifierInfo *CatName,
+    SourceLocation CatLoc) {
+    return DeclPtrTy();
+  }
+  // ActOnPropertyImplDecl - called for every property implementation
+  virtual DeclPtrTy ActOnPropertyImplDecl(
+   SourceLocation AtLoc,              // location of the @synthesize/@dynamic
+   SourceLocation PropertyNameLoc,    // location for the property name
+   bool ImplKind,                     // true for @synthesize, false for
+                                      // @dynamic
+   DeclPtrTy ClassImplDecl,           // class or category implementation
+   IdentifierInfo *propertyId,        // name of property
+   IdentifierInfo *propertyIvar) {    // name of the ivar
+    return DeclPtrTy();
+  }
+
+  struct ObjCArgInfo {
+    IdentifierInfo *Name;
+    SourceLocation NameLoc;
+    // The Type is null if no type was specified, and the DeclSpec is invalid
+    // in this case.
+    TypeTy *Type;
+    ObjCDeclSpec DeclSpec;
+
+    /// ArgAttrs - Attribute list for this argument.
+    AttributeList *ArgAttrs;
+  };
+
+  // ActOnMethodDeclaration - called for all method declarations.
+  virtual DeclPtrTy ActOnMethodDeclaration(
+    SourceLocation BeginLoc,   // location of the + or -.
+    SourceLocation EndLoc,     // location of the ; or {.
+    tok::TokenKind MethodType, // tok::minus for instance, tok::plus for class.
+    DeclPtrTy ClassDecl,       // class this methods belongs to.
+    ObjCDeclSpec &ReturnQT,    // for return type's in inout etc.
+    TypeTy *ReturnType,        // the method return type.
+    Selector Sel,              // a unique name for the method.
+    ObjCArgInfo *ArgInfo,      // ArgInfo: Has 'Sel.getNumArgs()' entries.
+    DeclaratorChunk::ParamInfo *CParamInfo, unsigned CNumArgs, // c-style args
+    AttributeList *MethodAttrList, // optional
+    // tok::objc_not_keyword, tok::objc_optional, tok::objc_required
+    tok::ObjCKeywordKind impKind,
+    bool isVariadic = false) {
+    return DeclPtrTy();
+  }
+  // ActOnAtEnd - called to mark the @end. For declarations (interfaces,
+  // protocols, categories), the parser passes all methods/properties.
+  // For class implementations, these values default to 0. For implementations,
+  // methods are processed incrementally (by ActOnMethodDeclaration above).
+  virtual void ActOnAtEnd(SourceRange AtEnd,
+                          DeclPtrTy classDecl,
+                          DeclPtrTy *allMethods = 0,
+                          unsigned allNum = 0,
+                          DeclPtrTy *allProperties = 0,
+                          unsigned pNum = 0,
+                          DeclGroupPtrTy *allTUVars = 0,
+                          unsigned tuvNum = 0) {
+  }
+  // ActOnProperty - called to build one property AST
+  virtual DeclPtrTy ActOnProperty(Scope *S, SourceLocation AtLoc,
+                                  FieldDeclarator &FD, ObjCDeclSpec &ODS,
+                                  Selector GetterSel, Selector SetterSel,
+                                  DeclPtrTy ClassCategory,
+                                  bool *OverridingProperty,
+                                  tok::ObjCKeywordKind MethodImplKind) {
+    return DeclPtrTy();
+  }
+
+  virtual OwningExprResult
+  ActOnClassPropertyRefExpr(IdentifierInfo &receiverName,
+                            IdentifierInfo &propertyName,
+                            SourceLocation receiverNameLoc,
+                            SourceLocation propertyNameLoc) {
+    return ExprEmpty();
+  }
+
+  /// \brief Describes the kind of message expression indicated by a message
+  /// send that starts with an identifier.
+  enum ObjCMessageKind {
+    /// \brief The message is sent to 'super'.
+    ObjCSuperMessage,
+    /// \brief The message is an instance message.
+    ObjCInstanceMessage,
+    /// \brief The message is a class message, and the identifier is a type
+    /// name.
+    ObjCClassMessage
+  };
+  
+  /// \brief Determine the kind of Objective-C message send that we will be
+  /// performing based on the identifier given.
+  ///
+  /// This action determines how a message send that starts with [
+  /// identifier (followed by another identifier) will be parsed,
+  /// e.g., as a class message, instance message, super message. The
+  /// result depends on the meaning of the given identifier. If the
+  /// identifier is unknown, the action should indicate that the
+  /// message is an instance message.
+  ///
+  /// By default, this routine applies syntactic disambiguation and uses
+  /// \c getTypeName() to determine whether the identifier refers to a type.
+  /// However, \c Action subclasses may override this routine to improve
+  /// error recovery.
+  ///
+  /// \param S The scope in which the message send occurs.
+  ///
+  /// \param Name The identifier following the '['. 
+  ///
+  /// \param NameLoc The location of the identifier.
+  ///
+  /// \param IsSuper Whether the name is the pseudo-keyword "super".
+  ///
+  /// \param HasTrailingDot Whether the name is followed by a period.
+  /// 
+  /// \param ReceiverType If this routine returns \c ObjCClassMessage,
+  /// this argument will be set to the receiver type.
+  ///
+  /// \returns The kind of message send.
+  virtual ObjCMessageKind getObjCMessageKind(Scope *S,
+                                             IdentifierInfo *Name,
+                                             SourceLocation NameLoc,
+                                             bool IsSuper,
+                                             bool HasTrailingDot,
+                                             TypeTy *&ReceiverType);
+
+  /// \brief Parsed a message send to 'super'.
+  ///
+  /// \param S The scope in which the message send occurs.
+  /// \param SuperLoc The location of the 'super' keyword.
+  /// \param Sel The selector to which the message is being sent.
+  /// \param LBracLoc The location of the opening square bracket ']'.
+  /// \param SelectorLoc The location of the first identifier in the selector.
+  /// \param RBrac The location of the closing square bracket ']'.
+  /// \param Args The message arguments.
+  virtual OwningExprResult ActOnSuperMessage(Scope *S, SourceLocation SuperLoc,
+                                             Selector Sel,
+                                             SourceLocation LBracLoc,
+                                             SourceLocation SelectorLoc,
+                                             SourceLocation RBracLoc,
+                                             MultiExprArg Args) {
+    return OwningExprResult(*this);
+  }
+
+  /// \brief Parsed a message send to a class.
+  ///
+  /// \param S The scope in which the message send occurs.
+  /// \param Receiver The type of the class receiving the message.
+  /// \param Sel The selector to which the message is being sent.
+  /// \param LBracLoc The location of the opening square bracket ']'.
+  /// \param SelectorLoc The location of the first identifier in the selector.
+  /// \param RBrac The location of the closing square bracket ']'.
+  /// \param Args The message arguments.
+  virtual OwningExprResult ActOnClassMessage(Scope *S,
+                                             TypeTy *Receiver,
+                                             Selector Sel,
+                                             SourceLocation LBracLoc, 
+                                             SourceLocation SelectorLoc,
+                                             SourceLocation RBracLoc,
+                                             MultiExprArg Args) {
+    return OwningExprResult(*this);
+  }
+
+  /// \brief Parsed a message send to an object instance.
+  ///
+  /// \param S The scope in which the message send occurs.
+  /// \param Receiver The expression that computes the receiver object.
+  /// \param Sel The selector to which the message is being sent.
+  /// \param LBracLoc The location of the opening square bracket ']'.
+  /// \param SelectorLoc The location of the first identifier in the selector.
+  /// \param RBrac The location of the closing square bracket ']'.
+  /// \param Args The message arguments.
+  virtual OwningExprResult ActOnInstanceMessage(Scope *S,
+                                                ExprArg Receiver,
+                                                Selector Sel,
+                                                SourceLocation LBracLoc, 
+                                                SourceLocation SelectorLoc, 
+                                                SourceLocation RBracLoc,
+                                                MultiExprArg Args) {
+    return OwningExprResult(*this);
+  }
+
+  virtual DeclPtrTy ActOnForwardClassDeclaration(
+    SourceLocation AtClassLoc,
+    IdentifierInfo **IdentList,
+    SourceLocation *IdentLocs,
+    unsigned NumElts) {
+    return DeclPtrTy();
+  }
+  virtual DeclPtrTy ActOnForwardProtocolDeclaration(
+    SourceLocation AtProtocolLoc,
+    const IdentifierLocPair*IdentList,
+    unsigned NumElts,
+    AttributeList *AttrList) {
+    return DeclPtrTy();
+  }
+
+  /// FindProtocolDeclaration - This routine looks up protocols and
+  /// issues error if they are not declared. It returns list of valid
+  /// protocols found.
+  virtual void FindProtocolDeclaration(bool WarnOnDeclarations,
+                                       const IdentifierLocPair *ProtocolId,
+                                       unsigned NumProtocols,
+                                 llvm::SmallVectorImpl<DeclPtrTy> &ResProtos) {
+  }
+
+  //===----------------------- Obj-C Expressions --------------------------===//
+
+  virtual ExprResult ParseObjCStringLiteral(SourceLocation *AtLocs,
+                                            ExprTy **Strings,
+                                            unsigned NumStrings) {
+    return ExprResult();
+  }
+
+  virtual ExprResult ParseObjCEncodeExpression(SourceLocation AtLoc,
+                                               SourceLocation EncLoc,
+                                               SourceLocation LParenLoc,
+                                               TypeTy *Ty,
+                                               SourceLocation RParenLoc) {
+    return ExprResult();
+  }
+
+  virtual ExprResult ParseObjCSelectorExpression(Selector Sel,
+                                                 SourceLocation AtLoc,
+                                                 SourceLocation SelLoc,
+                                                 SourceLocation LParenLoc,
+                                                 SourceLocation RParenLoc) {
+    return ExprResult();
+  }
+
+  virtual ExprResult ParseObjCProtocolExpression(IdentifierInfo *ProtocolId,
+                                                 SourceLocation AtLoc,
+                                                 SourceLocation ProtoLoc,
+                                                 SourceLocation LParenLoc,
+                                                 SourceLocation RParenLoc) {
+    return ExprResult();
+  }
+
+  //===---------------------------- Pragmas -------------------------------===//
+
+  enum PragmaPackKind {
+    PPK_Default, // #pragma pack([n])
+    PPK_Show,    // #pragma pack(show), only supported by MSVC.
+    PPK_Push,    // #pragma pack(push, [identifier], [n])
+    PPK_Pop      // #pragma pack(pop, [identifier], [n])
+  };
+
+  /// ActOnPragmaPack - Called on well formed #pragma pack(...).
+  virtual void ActOnPragmaPack(PragmaPackKind Kind,
+                               IdentifierInfo *Name,
+                               ExprTy *Alignment,
+                               SourceLocation PragmaLoc,
+                               SourceLocation LParenLoc,
+                               SourceLocation RParenLoc) {
+    return;
+  }
+
+  /// ActOnPragmaUnused - Called on well formed #pragma unused(...).
+  virtual void ActOnPragmaUnused(const Token *Identifiers,
+                                 unsigned NumIdentifiers, Scope *CurScope,
+                                 SourceLocation PragmaLoc,
+                                 SourceLocation LParenLoc,
+                                 SourceLocation RParenLoc) {
+    return;
+  }
+
+  /// ActOnPragmaWeakID - Called on well formed #pragma weak ident.
+  virtual void ActOnPragmaWeakID(IdentifierInfo* WeakName,
+                                 SourceLocation PragmaLoc,
+                                 SourceLocation WeakNameLoc) {
+    return;
+  }
+
+  /// ActOnPragmaWeakAlias - Called on well formed #pragma weak ident = ident.
+  virtual void ActOnPragmaWeakAlias(IdentifierInfo* WeakName,
+                                    IdentifierInfo* AliasName,
+                                    SourceLocation PragmaLoc,
+                                    SourceLocation WeakNameLoc,
+                                    SourceLocation AliasNameLoc) {
+    return;
+  }
+  
+  /// \name Code completion actions
+  ///
+  /// These actions are used to signal that a code-completion token has been
+  /// found at a point in the grammar where the Action implementation is
+  /// likely to be able to provide a list of possible completions, e.g.,
+  /// after the "." or "->" of a member access expression.
+  /// 
+  /// \todo Code completion for designated field initializers
+  /// \todo Code completion for call arguments after a function template-id
+  /// \todo Code completion within a call expression, object construction, etc.
+  /// \todo Code completion within a template argument list.
+  /// \todo Code completion for attributes.
+  //@{
+  
+  /// \brief Describes the context in which code completion occurs.
+  enum CodeCompletionContext {
+    /// \brief Code completion occurs at top-level or namespace context.
+    CCC_Namespace,
+    /// \brief Code completion occurs within a class, struct, or union.
+    CCC_Class,
+    /// \brief Code completion occurs within an Objective-C interface, protocol,
+    /// or category.
+    CCC_ObjCInterface,
+    /// \brief Code completion occurs within an Objective-C implementation or
+    /// category implementation
+    CCC_ObjCImplementation,
+    /// \brief Code completion occurs within the list of instance variables
+    /// in an Objective-C interface, protocol, category, or implementation.
+    CCC_ObjCInstanceVariableList,
+    /// \brief Code completion occurs following one or more template
+    /// headers.
+    CCC_Template,
+    /// \brief Code completion occurs following one or more template
+    /// headers within a class.
+    CCC_MemberTemplate,
+    /// \brief Code completion occurs within an expression.
+    CCC_Expression,
+    /// \brief Code completion occurs within a statement, which may
+    /// also be an expression or a declaration.
+    CCC_Statement,
+    /// \brief Code completion occurs at the beginning of the
+    /// initialization statement (or expression) in a for loop.
+    CCC_ForInit,
+    /// \brief Code completion ocurs within the condition of an if,
+    /// while, switch, or for statement.
+    CCC_Condition
+  };
+    
+  /// \brief Code completion for an ordinary name that occurs within the given
+  /// scope.
+  ///
+  /// \param S the scope in which the name occurs.
+  ///
+  /// \param CompletionContext the context in which code completion
+  /// occurs.
+  virtual void CodeCompleteOrdinaryName(Scope *S, 
+                                    CodeCompletionContext CompletionContext) { }
+  
+  /// \brief Code completion for a member access expression.
+  ///
+  /// This code completion action is invoked when the code-completion token
+  /// is found after the "." or "->" of a member access expression.
+  ///
+  /// \param S the scope in which the member access expression occurs.
+  ///
+  /// \param Base the base expression (e.g., the x in "x.foo") of the member
+  /// access.
+  ///
+  /// \param OpLoc the location of the "." or "->" operator.
+  ///
+  /// \param IsArrow true when the operator is "->", false when it is ".".
+  virtual void CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *Base,
+                                               SourceLocation OpLoc,
+                                               bool IsArrow) { }
+  
+  /// \brief Code completion for a reference to a tag.
+  ///
+  /// This code completion action is invoked when the code-completion
+  /// token is found after a tag keyword (struct, union, enum, or class).
+  ///
+  /// \param S the scope in which the tag reference occurs.
+  ///
+  /// \param TagSpec an instance of DeclSpec::TST, indicating what kind of tag
+  /// this is (struct/union/enum/class).
+  virtual void CodeCompleteTag(Scope *S, unsigned TagSpec) { }
+  
+  /// \brief Code completion for a case statement.
+  ///
+  /// \brief S the scope in which the case statement occurs.
+  virtual void CodeCompleteCase(Scope *S) { }
+  
+  /// \brief Code completion for a call.
+  ///
+  /// \brief S the scope in which the call occurs.
+  ///
+  /// \param Fn the expression describing the function being called.
+  ///
+  /// \param Args the arguments to the function call (so far).
+  ///
+  /// \param NumArgs the number of arguments in \p Args.
+  virtual void CodeCompleteCall(Scope *S, ExprTy *Fn,
+                                ExprTy **Args, unsigned NumArgs) { }
+                                
+  /// \brief Code completion for a C++ nested-name-specifier that precedes a
+  /// qualified-id of some form.
+  ///
+  /// This code completion action is invoked when the code-completion token
+  /// is found after the "::" of a nested-name-specifier.
+  ///
+  /// \param S the scope in which the nested-name-specifier occurs.
+  /// 
+  /// \param SS the scope specifier ending with "::".
+  ///
+  /// \parame EnteringContext whether we're entering the context of this
+  /// scope specifier.
+  virtual void CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
+                                       bool EnteringContext) { }
+  
+  /// \brief Code completion for a C++ "using" declaration or directive.
+  ///
+  /// This code completion action is invoked when the code-completion token is
+  /// found after the "using" keyword.
+  ///
+  /// \param S the scope in which the "using" occurs.
+  virtual void CodeCompleteUsing(Scope *S) { }
+  
+  /// \brief Code completion for a C++ using directive.
+  ///
+  /// This code completion action is invoked when the code-completion token is
+  /// found after "using namespace".
+  ///
+  /// \param S the scope in which the "using namespace" occurs.
+  virtual void CodeCompleteUsingDirective(Scope *S) { }
+  
+  /// \brief Code completion for a C++ namespace declaration or namespace
+  /// alias declaration.
+  ///
+  /// This code completion action is invoked when the code-completion token is
+  /// found after "namespace".
+  ///
+  /// \param S the scope in which the "namespace" token occurs.
+  virtual void CodeCompleteNamespaceDecl(Scope *S) { }
+
+  /// \brief Code completion for a C++ namespace alias declaration.
+  ///
+  /// This code completion action is invoked when the code-completion token is
+  /// found after "namespace identifier = ".
+  ///
+  /// \param S the scope in which the namespace alias declaration occurs.
+  virtual void CodeCompleteNamespaceAliasDecl(Scope *S) { }
+  
+  /// \brief Code completion for an operator name.
+  ///
+  /// This code completion action is invoked when the code-completion token is
+  /// found after the keyword "operator".
+  ///
+  /// \param S the scope in which the operator keyword occurs.
+  virtual void CodeCompleteOperatorName(Scope *S) { }
+
+  /// \brief Code completion after the '@' at the top level.
+  ///
+  /// \param S the scope in which the '@' occurs.
+  ///
+  /// \param ObjCImpDecl the Objective-C implementation or category 
+  /// implementation.
+  ///
+  /// \param InInterface whether we are in an Objective-C interface or
+  /// protocol.
+  virtual void CodeCompleteObjCAtDirective(Scope *S, DeclPtrTy ObjCImpDecl,
+                                           bool InInterface) { }
+
+  /// \brief Code completion after the '@' in the list of instance variables.
+  virtual void CodeCompleteObjCAtVisibility(Scope *S) { }
+  
+  /// \brief Code completion after the '@' in a statement.
+  virtual void CodeCompleteObjCAtStatement(Scope *S) { }
+
+  /// \brief Code completion after the '@' in an expression.
+  virtual void CodeCompleteObjCAtExpression(Scope *S) { }
+
+  /// \brief Code completion for an ObjC property decl.
+  ///
+  /// This code completion action is invoked when the code-completion token is
+  /// found after the left paren.
+  ///
+  /// \param S the scope in which the operator keyword occurs.  
+  virtual void CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) { }
+
+  /// \brief Code completion for the getter of an Objective-C property 
+  /// declaration.  
+  ///
+  /// This code completion action is invoked when the code-completion
+  /// token is found after the "getter = " in a property declaration.
+  ///
+  /// \param S the scope in which the property is being declared.
+  ///
+  /// \param ClassDecl the Objective-C class or category in which the property
+  /// is being defined.
+  ///
+  /// \param Methods the set of methods declared thus far within \p ClassDecl.
+  ///
+  /// \param NumMethods the number of methods in \p Methods
+  virtual void CodeCompleteObjCPropertyGetter(Scope *S, DeclPtrTy ClassDecl,
+                                              DeclPtrTy *Methods,
+                                              unsigned NumMethods) {
+  }
+
+  /// \brief Code completion for the setter of an Objective-C property 
+  /// declaration.  
+  ///
+  /// This code completion action is invoked when the code-completion
+  /// token is found after the "setter = " in a property declaration.
+  ///
+  /// \param S the scope in which the property is being declared.
+  ///
+  /// \param ClassDecl the Objective-C class or category in which the property
+  /// is being defined.
+  ///
+  /// \param Methods the set of methods declared thus far within \p ClassDecl.
+  ///
+  /// \param NumMethods the number of methods in \p Methods
+  virtual void CodeCompleteObjCPropertySetter(Scope *S, DeclPtrTy ClassDecl,
+                                              DeclPtrTy *Methods,
+                                              unsigned NumMethods) {
+  }
+
+  /// \brief Code completion for an ObjC message expression that sends
+  /// a message to the superclass.
+  ///
+  /// This code completion action is invoked when the code-completion token is
+  /// found after the class name and after each argument.
+  ///
+  /// \param S The scope in which the message expression occurs. 
+  /// \param SuperLoc The location of the 'super' keyword.
+  /// \param SelIdents The identifiers that describe the selector (thus far).
+  /// \param NumSelIdents The number of identifiers in \p SelIdents.
+  virtual void CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc,
+                                            IdentifierInfo **SelIdents,
+                                            unsigned NumSelIdents) { }
+
+  /// \brief Code completion for an ObjC message expression that refers to
+  /// a class method.
+  ///
+  /// This code completion action is invoked when the code-completion token is
+  /// found after the class name and after each argument.
+  ///
+  /// \param S The scope in which the message expression occurs. 
+  /// \param Receiver The type of the class that is receiving a message.
+  /// \param SelIdents The identifiers that describe the selector (thus far).
+  /// \param NumSelIdents The number of identifiers in \p SelIdents.
+  virtual void CodeCompleteObjCClassMessage(Scope *S, TypeTy *Receiver,
+                                            IdentifierInfo **SelIdents,
+                                            unsigned NumSelIdents) { }
+  
+  /// \brief Code completion for an ObjC message expression that refers to
+  /// an instance method.
+  ///
+  /// This code completion action is invoked when the code-completion token is
+  /// found after the receiver expression and after each argument.
+  ///
+  /// \param S the scope in which the operator keyword occurs.  
+  /// \param Receiver an expression for the receiver of the message. 
+  /// \param SelIdents the identifiers that describe the selector (thus far).
+  /// \param NumSelIdents the number of identifiers in \p SelIdents.
+  virtual void CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
+                                               IdentifierInfo **SelIdents,
+                                               unsigned NumSelIdents) { }
+
+  /// \brief Code completion for a list of protocol references in Objective-C,
+  /// such as P1 and P2 in \c id<P1,P2>.
+  ///
+  /// This code completion action is invoked prior to each identifier 
+  /// in the protocol list.
+  ///
+  /// \param Protocols the set of protocols that have already been parsed.
+  ///
+  /// \param NumProtocols the number of protocols that have already been
+  /// parsed.
+  virtual void CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
+                                                  unsigned NumProtocols) { }
+
+  /// \brief Code completion for a protocol declaration or definition, after
+  /// the @protocol but before any identifier.
+  ///
+  /// \param S the scope in which the protocol declaration occurs.
+  virtual void CodeCompleteObjCProtocolDecl(Scope *S) { }
+
+  /// \brief Code completion for an Objective-C interface, after the
+  /// @interface but before any identifier.
+  virtual void CodeCompleteObjCInterfaceDecl(Scope *S) { }
+
+  /// \brief Code completion for the superclass of an Objective-C
+  /// interface, after the ':'.
+  ///
+  /// \param S the scope in which the interface declaration occurs.
+  ///
+  /// \param ClassName the name of the class being defined.
+  virtual void CodeCompleteObjCSuperclass(Scope *S, 
+                                          IdentifierInfo *ClassName,
+                                          SourceLocation ClassNameLoc) {
+  }
+
+  /// \brief Code completion for an Objective-C implementation, after the
+  /// @implementation but before any identifier.
+  virtual void CodeCompleteObjCImplementationDecl(Scope *S) { }
+  
+  /// \brief Code completion for the category name in an Objective-C interface
+  /// declaration.
+  ///
+  /// This code completion action is invoked after the '(' that indicates
+  /// a category name within an Objective-C interface declaration.
+  virtual void CodeCompleteObjCInterfaceCategory(Scope *S, 
+                                                 IdentifierInfo *ClassName,
+                                                 SourceLocation ClassNameLoc) {
+  }
+
+  /// \brief Code completion for the category name in an Objective-C category
+  /// implementation.
+  ///
+  /// This code completion action is invoked after the '(' that indicates
+  /// the category name within an Objective-C category implementation.
+  virtual void CodeCompleteObjCImplementationCategory(Scope *S, 
+                                                      IdentifierInfo *ClassName,
+                                                  SourceLocation ClassNameLoc) {
+  }
+  
+  /// \brief Code completion for the property names when defining an
+  /// Objective-C property.
+  ///
+  /// This code completion action is invoked after @synthesize or @dynamic and
+  /// after each "," within one of those definitions.
+  virtual void CodeCompleteObjCPropertyDefinition(Scope *S, 
+                                                  DeclPtrTy ObjCImpDecl) {
+  }
+
+  /// \brief Code completion for the instance variable name that should 
+  /// follow an '=' when synthesizing an Objective-C property.
+  ///
+  /// This code completion action is invoked after each '=' that occurs within
+  /// an @synthesized definition.
+  virtual void CodeCompleteObjCPropertySynthesizeIvar(Scope *S, 
+                                                   IdentifierInfo *PropertyName,
+                                                  DeclPtrTy ObjCImpDecl) {
+  }
+
+  /// \brief Code completion for an Objective-C method declaration or
+  /// definition, which may occur within an interface, category,
+  /// extension, protocol, or implementation thereof (where applicable).
+  ///
+  /// This code completion action is invoked after the "-" or "+" that
+  /// starts a method declaration or definition, and after the return
+  /// type such a declaration (e.g., "- (id)").
+  ///
+  /// \param S The scope in which the completion occurs.
+  ///
+  /// \param IsInstanceMethod Whether this is an instance method
+  /// (introduced with '-'); otherwise, it's a class method
+  /// (introduced with '+').
+  ///
+  /// \param ReturnType If non-NULL, the specified return type of the method
+  /// being declared or defined.
+  ///
+  /// \param IDecl The interface, category, protocol, or
+  /// implementation, or category implementation in which this method
+  /// declaration or definition occurs.
+  virtual void CodeCompleteObjCMethodDecl(Scope *S, 
+                                          bool IsInstanceMethod,
+                                          TypeTy *ReturnType,
+                                          DeclPtrTy IDecl) {
+  }
+  //@}
+};
+
+/// MinimalAction - Minimal actions are used by light-weight clients of the
+/// parser that do not need name resolution or significant semantic analysis to
+/// be performed.  The actions implemented here are in the form of unresolved
+/// identifiers.  By using a simpler interface than the SemanticAction class,
+/// the parser doesn't have to build complex data structures and thus runs more
+/// quickly.
+class MinimalAction : public Action {
+  /// Translation Unit Scope - useful to Objective-C actions that need
+  /// to lookup file scope declarations in the "ordinary" C decl namespace.
+  /// For example, user-defined classes, built-in "id" type, etc.
+  Scope *TUScope;
+  IdentifierTable &Idents;
+  Preprocessor &PP;
+  void *TypeNameInfoTablePtr;
+public:
+  MinimalAction(Preprocessor &pp);
+  ~MinimalAction();
+
+  /// getTypeName - This looks at the IdentifierInfo::FETokenInfo field to
+  /// determine whether the name is a typedef or not in this scope.
+  ///
+  /// \param II the identifier for which we are performing name lookup
+  ///
+  /// \param NameLoc the location of the identifier
+  ///
+  /// \param S the scope in which this name lookup occurs
+  ///
+  /// \param SS if non-NULL, the C++ scope specifier that precedes the
+  /// identifier
+  ///
+  /// \param isClassName whether this is a C++ class-name production, in
+  /// which we can end up referring to a member of an unknown specialization
+  /// that we know (from the grammar) is supposed to be a type. For example,
+  /// this occurs when deriving from "std::vector<T>::allocator_type", where T
+  /// is a template parameter.
+  ///
+  /// \returns the type referred to by this identifier, or NULL if the type
+  /// does not name an identifier.
+  virtual TypeTy *getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
+                              Scope *S, CXXScopeSpec *SS,
+                              bool isClassName = false,
+                              TypeTy *ObjectType = 0);
+
+  /// isCurrentClassName - Always returns false, because MinimalAction
+  /// does not support C++ classes with constructors.
+  virtual bool isCurrentClassName(const IdentifierInfo& II, Scope *S,
+                                  const CXXScopeSpec *SS);
+
+  virtual TemplateNameKind isTemplateName(Scope *S,
+                                          CXXScopeSpec &SS,
+                                          UnqualifiedId &Name,
+                                          TypeTy *ObjectType,
+                                          bool EnteringContext,
+                                          TemplateTy &Template);
+  
+  /// ActOnDeclarator - If this is a typedef declarator, we modify the
+  /// IdentifierInfo::FETokenInfo field to keep track of this fact, until S is
+  /// popped.
+  virtual DeclPtrTy ActOnDeclarator(Scope *S, Declarator &D);
+
+  /// ActOnPopScope - When a scope is popped, if any typedefs are now
+  /// out-of-scope, they are removed from the IdentifierInfo::FETokenInfo field.
+  virtual void ActOnPopScope(SourceLocation Loc, Scope *S);
+  virtual void ActOnTranslationUnitScope(SourceLocation Loc, Scope *S);
+
+  virtual DeclPtrTy ActOnForwardClassDeclaration(SourceLocation AtClassLoc,
+                                                 IdentifierInfo **IdentList,
+                                                 SourceLocation *SLocs,
+                                                 unsigned NumElts);
+
+  virtual DeclPtrTy ActOnStartClassInterface(SourceLocation interLoc,
+                                             IdentifierInfo *ClassName,
+                                             SourceLocation ClassLoc,
+                                             IdentifierInfo *SuperName,
+                                             SourceLocation SuperLoc,
+                                             const DeclPtrTy *ProtoRefs,
+                                             unsigned NumProtoRefs,
+                                             const SourceLocation *ProtoLocs,
+                                             SourceLocation EndProtoLoc,
+                                             AttributeList *AttrList);
+};
+
+/// PrettyStackTraceActionsDecl - If a crash occurs in the parser while parsing
+/// something related to a virtualized decl, include that virtualized decl in
+/// the stack trace.
+class PrettyStackTraceActionsDecl : public llvm::PrettyStackTraceEntry {
+  Action::DeclPtrTy TheDecl;
+  SourceLocation Loc;
+  Action &Actions;
+  SourceManager &SM;
+  const char *Message;
+public:
+  PrettyStackTraceActionsDecl(Action::DeclPtrTy Decl, SourceLocation L,
+                              Action &actions, SourceManager &sm,
+                              const char *Msg)
+  : TheDecl(Decl), Loc(L), Actions(actions), SM(sm), Message(Msg) {}
+
+  virtual void print(llvm::raw_ostream &OS) const;
+};
+
+/// \brief RAII object that enters a new expression evaluation context.
+class EnterExpressionEvaluationContext {
+  /// \brief The action object.
+  Action &Actions;
+
+public:
+  EnterExpressionEvaluationContext(Action &Actions,
+                              Action::ExpressionEvaluationContext NewContext)
+    : Actions(Actions) {
+    Actions.PushExpressionEvaluationContext(NewContext);
+  }
+
+  ~EnterExpressionEvaluationContext() {
+    Actions.PopExpressionEvaluationContext();
+  }
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Parse/AttributeList.h b/include/clang/Parse/AttributeList.h
new file mode 100644
index 0000000..37acab9
--- /dev/null
+++ b/include/clang/Parse/AttributeList.h
@@ -0,0 +1,221 @@
+//===--- AttributeList.h ----------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the AttributeList class interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ATTRLIST_H
+#define LLVM_CLANG_ATTRLIST_H
+
+#include "clang/Parse/Ownership.h"
+#include "clang/Basic/SourceLocation.h"
+#include <cassert>
+
+namespace clang {
+  class IdentifierInfo;
+  class Action;
+
+/// AttributeList - Represents GCC's __attribute__ declaration. There are
+/// 4 forms of this construct...they are:
+///
+/// 1: __attribute__(( const )). ParmName/Args/NumArgs will all be unused.
+/// 2: __attribute__(( mode(byte) )). ParmName used, Args/NumArgs unused.
+/// 3: __attribute__(( format(printf, 1, 2) )). ParmName/Args/NumArgs all used.
+/// 4: __attribute__(( aligned(16) )). ParmName is unused, Args/Num used.
+///
+class AttributeList {
+  IdentifierInfo *AttrName;
+  SourceLocation AttrLoc;
+  IdentifierInfo *ScopeName;
+  SourceLocation ScopeLoc;
+  IdentifierInfo *ParmName;
+  SourceLocation ParmLoc;
+  ActionBase::ExprTy **Args;
+  unsigned NumArgs;
+  AttributeList *Next;
+  bool DeclspecAttribute, CXX0XAttribute;
+  AttributeList(const AttributeList &); // DO NOT IMPLEMENT
+  void operator=(const AttributeList &); // DO NOT IMPLEMENT
+public:
+  AttributeList(IdentifierInfo *AttrName, SourceLocation AttrLoc,
+                IdentifierInfo *ScopeName, SourceLocation ScopeLoc,
+                IdentifierInfo *ParmName, SourceLocation ParmLoc,
+                ActionBase::ExprTy **args, unsigned numargs,
+                AttributeList *Next, bool declspec = false, bool cxx0x = false);
+  ~AttributeList();
+
+  enum Kind {             // Please keep this list alphabetized.
+    AT_IBAction,          // Clang-specific.
+    AT_IBOutlet,          // Clang-specific.
+    AT_address_space,
+    AT_alias,
+    AT_aligned,
+    AT_always_inline,
+    AT_analyzer_noreturn,
+    AT_annotate,
+    AT_base_check,
+    AT_blocks,
+    AT_carries_dependency,
+    AT_cdecl,
+    AT_cleanup,
+    AT_const,
+    AT_constructor,
+    AT_deprecated,
+    AT_destructor,
+    AT_dllexport,
+    AT_dllimport,
+    AT_ext_vector_type,
+    AT_fastcall,
+    AT_final,
+    AT_format,
+    AT_format_arg,
+    AT_gnu_inline,
+    AT_hiding,
+    AT_malloc,
+    AT_mode,
+    AT_nodebug,
+    AT_noinline,
+    AT_no_instrument_function,
+    AT_nonnull,
+    AT_noreturn,
+    AT_nothrow,
+    AT_nsobject,
+    AT_objc_exception,
+    AT_override,
+    AT_cf_returns_not_retained, // Clang-specific.
+    AT_cf_returns_retained,     // Clang-specific.
+    AT_ns_returns_not_retained, // Clang-specific.
+    AT_ns_returns_retained,     // Clang-specific.
+    AT_objc_gc,
+    AT_overloadable,       // Clang-specific.
+    AT_packed,
+    AT_pure,
+    AT_regparm,
+    AT_section,
+    AT_sentinel,
+    AT_stdcall,
+    AT_transparent_union,
+    AT_unavailable,
+    AT_unused,
+    AT_used,
+    AT_vector_size,
+    AT_visibility,
+    AT_warn_unused_result,
+    AT_weak,
+    AT_weakref,
+    AT_weak_import,
+    AT_reqd_wg_size,
+    IgnoredAttribute,
+    UnknownAttribute
+  };
+
+  IdentifierInfo *getName() const { return AttrName; }
+  SourceLocation getLoc() const { return AttrLoc; }
+  
+  bool hasScope() const { return ScopeName; }
+  IdentifierInfo *getScopeName() const { return ScopeName; }
+  SourceLocation getScopeLoc() const { return ScopeLoc; }
+  
+  IdentifierInfo *getParameterName() const { return ParmName; }
+
+  bool isDeclspecAttribute() const { return DeclspecAttribute; }
+  bool isCXX0XAttribute() const { return CXX0XAttribute; }
+
+  Kind getKind() const { return getKind(getName()); }
+  static Kind getKind(const IdentifierInfo *Name);
+
+  AttributeList *getNext() const { return Next; }
+  void setNext(AttributeList *N) { Next = N; }
+
+  /// getNumArgs - Return the number of actual arguments to this attribute.
+  unsigned getNumArgs() const { return NumArgs; }
+
+  /// getArg - Return the specified argument.
+  ActionBase::ExprTy *getArg(unsigned Arg) const {
+    assert(Arg < NumArgs && "Arg access out of range!");
+    return Args[Arg];
+  }
+
+  class arg_iterator {
+    ActionBase::ExprTy** X;
+    unsigned Idx;
+  public:
+    arg_iterator(ActionBase::ExprTy** x, unsigned idx) : X(x), Idx(idx) {}
+
+    arg_iterator& operator++() {
+      ++Idx;
+      return *this;
+    }
+
+    bool operator==(const arg_iterator& I) const {
+      assert (X == I.X &&
+              "compared arg_iterators are for different argument lists");
+      return Idx == I.Idx;
+    }
+
+    bool operator!=(const arg_iterator& I) const {
+      return !operator==(I);
+    }
+
+    ActionBase::ExprTy* operator*() const {
+      return X[Idx];
+    }
+
+    unsigned getArgNum() const {
+      return Idx+1;
+    }
+  };
+
+  arg_iterator arg_begin() const {
+    return arg_iterator(Args, 0);
+  }
+
+  arg_iterator arg_end() const {
+    return arg_iterator(Args, NumArgs);
+  }
+};
+
+/// addAttributeLists - Add two AttributeLists together
+/// The right-hand list is appended to the left-hand list, if any
+/// A pointer to the joined list is returned.
+/// Note: the lists are not left unmodified.
+inline AttributeList* addAttributeLists (AttributeList *Left,
+                                         AttributeList *Right) {
+  if (!Left)
+    return Right;
+
+  AttributeList *next = Left, *prev;
+  do {
+    prev = next;
+    next = next->getNext();
+  } while (next);
+  prev->setNext(Right);
+  return Left;
+}
+
+/// CXX0XAttributeList - A wrapper around a C++0x attribute list.
+/// Stores, in addition to the list proper, whether or not an actual list was
+/// (as opposed to an empty list, which may be ill-formed in some places) and
+/// the source range of the list.
+struct CXX0XAttributeList { 
+  AttributeList *AttrList;
+  SourceRange Range;
+  bool HasAttr;
+  CXX0XAttributeList (AttributeList *attrList, SourceRange range, bool hasAttr)
+    : AttrList(attrList), Range(range), HasAttr (hasAttr) {
+  }
+  CXX0XAttributeList ()
+    : AttrList(0), Range(), HasAttr(false) {
+  }
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Parse/DeclSpec.h b/include/clang/Parse/DeclSpec.h
new file mode 100644
index 0000000..9c19a67
--- /dev/null
+++ b/include/clang/Parse/DeclSpec.h
@@ -0,0 +1,1323 @@
+//===--- SemaDeclSpec.h - Declaration Specifier Semantic Analys -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines interfaces used for Declaration Specifiers and Declarators.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_PARSE_DECLSPEC_H
+#define LLVM_CLANG_PARSE_DECLSPEC_H
+
+#include "clang/Parse/AttributeList.h"
+#include "clang/Lex/Token.h"
+#include "clang/Basic/OperatorKinds.h"
+#include "clang/Basic/Specifiers.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace clang {
+  class LangOptions;
+  class Diagnostic;
+  class IdentifierInfo;
+  class Preprocessor;
+  class Declarator;
+  struct TemplateIdAnnotation;
+
+/// CXXScopeSpec - Represents a C++ nested-name-specifier or a global scope
+/// specifier.  These can be in 3 states:
+///   1) Not present, identified by isEmpty()
+///   2) Present, identified by isNotEmpty()
+///      2.a) Valid, idenified by isValid()
+///      2.b) Invalid, identified by isInvalid().
+///
+/// isSet() is deprecated because it mostly corresponded to "valid" but was
+/// often used as if it meant "present".
+///
+/// The actual scope is described by getScopeRep().
+class CXXScopeSpec {
+  SourceRange Range;
+  void *ScopeRep;
+
+public:
+  CXXScopeSpec() : Range(), ScopeRep() { }
+
+  const SourceRange &getRange() const { return Range; }
+  void setRange(const SourceRange &R) { Range = R; }
+  void setBeginLoc(SourceLocation Loc) { Range.setBegin(Loc); }
+  void setEndLoc(SourceLocation Loc) { Range.setEnd(Loc); }
+  SourceLocation getBeginLoc() const { return Range.getBegin(); }
+  SourceLocation getEndLoc() const { return Range.getEnd(); }
+
+  ActionBase::CXXScopeTy *getScopeRep() const { return ScopeRep; }
+  void setScopeRep(ActionBase::CXXScopeTy *S) { ScopeRep = S; }
+
+  /// No scope specifier.
+  bool isEmpty() const { return !Range.isValid(); }
+  /// A scope specifier is present, but may be valid or invalid.
+  bool isNotEmpty() const { return !isEmpty(); }
+
+  /// An error occured during parsing of the scope specifier.
+  bool isInvalid() const { return isNotEmpty() && ScopeRep == 0; }
+  /// A scope specifier is present, and it refers to a real scope.
+  bool isValid() const { return isNotEmpty() && ScopeRep != 0; }
+
+  /// Deprecated.  Some call sites intend isNotEmpty() while others intend
+  /// isValid().
+  bool isSet() const { return ScopeRep != 0; }
+
+  void clear() {
+    Range = SourceRange();
+    ScopeRep = 0;
+  }
+};
+
+/// DeclSpec - This class captures information about "declaration specifiers",
+/// which encompasses storage-class-specifiers, type-specifiers,
+/// type-qualifiers, and function-specifiers.
+class DeclSpec {
+public:
+  // storage-class-specifier
+  // Note: The order of these enumerators is important for diagnostics.
+  enum SCS {
+    SCS_unspecified = 0,
+    SCS_typedef,
+    SCS_extern,
+    SCS_static,
+    SCS_auto,
+    SCS_register,
+    SCS_private_extern,
+    SCS_mutable
+  };
+
+  // Import type specifier width enumeration and constants.
+  typedef TypeSpecifierWidth TSW;
+  static const TSW TSW_unspecified = clang::TSW_unspecified;
+  static const TSW TSW_short = clang::TSW_short;
+  static const TSW TSW_long = clang::TSW_long;
+  static const TSW TSW_longlong = clang::TSW_longlong;
+  
+  enum TSC {
+    TSC_unspecified,
+    TSC_imaginary,
+    TSC_complex
+  };
+
+  // Import type specifier sign enumeration and constants.
+  typedef TypeSpecifierSign TSS;
+  static const TSS TSS_unspecified = clang::TSS_unspecified;
+  static const TSS TSS_signed = clang::TSS_signed;
+  static const TSS TSS_unsigned = clang::TSS_unsigned;
+
+  // Import type specifier type enumeration and constants.
+  typedef TypeSpecifierType TST;
+  static const TST TST_unspecified = clang::TST_unspecified;
+  static const TST TST_void = clang::TST_void;
+  static const TST TST_char = clang::TST_char;
+  static const TST TST_wchar = clang::TST_wchar;
+  static const TST TST_char16 = clang::TST_char16;
+  static const TST TST_char32 = clang::TST_char32;
+  static const TST TST_int = clang::TST_int;
+  static const TST TST_float = clang::TST_float;
+  static const TST TST_double = clang::TST_double;
+  static const TST TST_bool = clang::TST_bool;
+  static const TST TST_decimal32 = clang::TST_decimal32;
+  static const TST TST_decimal64 = clang::TST_decimal64;
+  static const TST TST_decimal128 = clang::TST_decimal128;
+  static const TST TST_enum = clang::TST_enum;
+  static const TST TST_union = clang::TST_union;
+  static const TST TST_struct = clang::TST_struct;
+  static const TST TST_class = clang::TST_class;
+  static const TST TST_typename = clang::TST_typename;
+  static const TST TST_typeofType = clang::TST_typeofType;
+  static const TST TST_typeofExpr = clang::TST_typeofExpr;
+  static const TST TST_decltype = clang::TST_decltype;
+  static const TST TST_auto = clang::TST_auto;
+  static const TST TST_error = clang::TST_error;
+
+  // type-qualifiers
+  enum TQ {   // NOTE: These flags must be kept in sync with Qualifiers::TQ.
+    TQ_unspecified = 0,
+    TQ_const       = 1,
+    TQ_restrict    = 2,
+    TQ_volatile    = 4
+  };
+
+  /// ParsedSpecifiers - Flags to query which specifiers were applied.  This is
+  /// returned by getParsedSpecifiers.
+  enum ParsedSpecifiers {
+    PQ_None                  = 0,
+    PQ_StorageClassSpecifier = 1,
+    PQ_TypeSpecifier         = 2,
+    PQ_TypeQualifier         = 4,
+    PQ_FunctionSpecifier     = 8
+  };
+
+private:
+
+  // storage-class-specifier
+  /*SCS*/unsigned StorageClassSpec : 3;
+  bool SCS_thread_specified : 1;
+
+  // type-specifier
+  /*TSW*/unsigned TypeSpecWidth : 2;
+  /*TSC*/unsigned TypeSpecComplex : 2;
+  /*TSS*/unsigned TypeSpecSign : 2;
+  /*TST*/unsigned TypeSpecType : 5;
+  bool TypeAltiVecVector : 1;
+  bool TypeAltiVecPixel : 1;
+  bool TypeSpecOwned : 1;
+
+  // type-qualifiers
+  unsigned TypeQualifiers : 3;  // Bitwise OR of TQ.
+
+  // function-specifier
+  bool FS_inline_specified : 1;
+  bool FS_virtual_specified : 1;
+  bool FS_explicit_specified : 1;
+
+  // friend-specifier
+  bool Friend_specified : 1;
+
+  // constexpr-specifier
+  bool Constexpr_specified : 1;
+
+  /*SCS*/unsigned StorageClassSpecAsWritten : 3;
+
+  /// TypeRep - This contains action-specific information about a specific TST.
+  /// For example, for a typedef or struct, it might contain the declaration for
+  /// these.
+  void *TypeRep;
+
+  // attributes.
+  AttributeList *AttrList;
+
+  // Scope specifier for the type spec, if applicable.
+  CXXScopeSpec TypeScope;
+
+  // List of protocol qualifiers for objective-c classes.  Used for
+  // protocol-qualified interfaces "NString<foo>" and protocol-qualified id
+  // "id<foo>".
+  const ActionBase::DeclPtrTy *ProtocolQualifiers;
+  unsigned NumProtocolQualifiers;
+  SourceLocation ProtocolLAngleLoc;
+  SourceLocation *ProtocolLocs;
+
+  // SourceLocation info.  These are null if the item wasn't specified or if
+  // the setting was synthesized.
+  SourceRange Range;
+
+  SourceLocation StorageClassSpecLoc, SCS_threadLoc;
+  SourceLocation TSWLoc, TSCLoc, TSSLoc, TSTLoc, AltiVecLoc;
+  SourceRange TypeofParensRange;
+  SourceLocation TQ_constLoc, TQ_restrictLoc, TQ_volatileLoc;
+  SourceLocation FS_inlineLoc, FS_virtualLoc, FS_explicitLoc;
+  SourceLocation FriendLoc, ConstexprLoc;
+
+  WrittenBuiltinSpecs writtenBS;
+  void SaveWrittenBuiltinSpecs();
+  void SaveStorageSpecifierAsWritten() {
+    StorageClassSpecAsWritten = StorageClassSpec;
+  }
+
+  DeclSpec(const DeclSpec&);       // DO NOT IMPLEMENT
+  void operator=(const DeclSpec&); // DO NOT IMPLEMENT
+public:
+
+  DeclSpec()
+    : StorageClassSpec(SCS_unspecified),
+      SCS_thread_specified(false),
+      TypeSpecWidth(TSW_unspecified),
+      TypeSpecComplex(TSC_unspecified),
+      TypeSpecSign(TSS_unspecified),
+      TypeSpecType(TST_unspecified),
+      TypeAltiVecVector(false),
+      TypeAltiVecPixel(false),
+      TypeSpecOwned(false),
+      TypeQualifiers(TSS_unspecified),
+      FS_inline_specified(false),
+      FS_virtual_specified(false),
+      FS_explicit_specified(false),
+      Friend_specified(false),
+      Constexpr_specified(false),
+      StorageClassSpecAsWritten(SCS_unspecified),
+      TypeRep(0),
+      AttrList(0),
+      ProtocolQualifiers(0),
+      NumProtocolQualifiers(0),
+      ProtocolLocs(0),
+      writtenBS() {
+  }
+  ~DeclSpec() {
+    delete AttrList;
+    delete [] ProtocolQualifiers;
+    delete [] ProtocolLocs;
+  }
+  // storage-class-specifier
+  SCS getStorageClassSpec() const { return (SCS)StorageClassSpec; }
+  bool isThreadSpecified() const { return SCS_thread_specified; }
+
+  SourceLocation getStorageClassSpecLoc() const { return StorageClassSpecLoc; }
+  SourceLocation getThreadSpecLoc() const { return SCS_threadLoc; }
+
+  void ClearStorageClassSpecs() {
+    StorageClassSpec     = DeclSpec::SCS_unspecified;
+    SCS_thread_specified = false;
+    StorageClassSpecLoc  = SourceLocation();
+    SCS_threadLoc        = SourceLocation();
+  }
+
+  // type-specifier
+  TSW getTypeSpecWidth() const { return (TSW)TypeSpecWidth; }
+  TSC getTypeSpecComplex() const { return (TSC)TypeSpecComplex; }
+  TSS getTypeSpecSign() const { return (TSS)TypeSpecSign; }
+  TST getTypeSpecType() const { return (TST)TypeSpecType; }
+  bool isTypeAltiVecVector() const { return TypeAltiVecVector; }
+  bool isTypeAltiVecPixel() const { return TypeAltiVecPixel; }
+  bool isTypeSpecOwned() const { return TypeSpecOwned; }
+  void *getTypeRep() const { return TypeRep; }
+  CXXScopeSpec &getTypeSpecScope() { return TypeScope; }
+  const CXXScopeSpec &getTypeSpecScope() const { return TypeScope; }
+
+  const SourceRange &getSourceRange() const { return Range; }
+  SourceLocation getTypeSpecWidthLoc() const { return TSWLoc; }
+  SourceLocation getTypeSpecComplexLoc() const { return TSCLoc; }
+  SourceLocation getTypeSpecSignLoc() const { return TSSLoc; }
+  SourceLocation getTypeSpecTypeLoc() const { return TSTLoc; }
+  SourceLocation getAltiVecLoc() const { return AltiVecLoc; }
+
+  SourceRange getTypeofParensRange() const { return TypeofParensRange; }
+  void setTypeofParensRange(SourceRange range) { TypeofParensRange = range; }
+
+  /// getSpecifierName - Turn a type-specifier-type into a string like "_Bool"
+  /// or "union".
+  static const char *getSpecifierName(DeclSpec::TST T);
+  static const char *getSpecifierName(DeclSpec::TQ Q);
+  static const char *getSpecifierName(DeclSpec::TSS S);
+  static const char *getSpecifierName(DeclSpec::TSC C);
+  static const char *getSpecifierName(DeclSpec::TSW W);
+  static const char *getSpecifierName(DeclSpec::SCS S);
+
+  // type-qualifiers
+
+  /// getTypeQualifiers - Return a set of TQs.
+  unsigned getTypeQualifiers() const { return TypeQualifiers; }
+  SourceLocation getConstSpecLoc() const { return TQ_constLoc; }
+  SourceLocation getRestrictSpecLoc() const { return TQ_restrictLoc; }
+  SourceLocation getVolatileSpecLoc() const { return TQ_volatileLoc; }
+
+  // function-specifier
+  bool isInlineSpecified() const { return FS_inline_specified; }
+  SourceLocation getInlineSpecLoc() const { return FS_inlineLoc; }
+
+  bool isVirtualSpecified() const { return FS_virtual_specified; }
+  SourceLocation getVirtualSpecLoc() const { return FS_virtualLoc; }
+
+  bool isExplicitSpecified() const { return FS_explicit_specified; }
+  SourceLocation getExplicitSpecLoc() const { return FS_explicitLoc; }
+
+  void ClearFunctionSpecs() {
+    FS_inline_specified = false;
+    FS_inlineLoc = SourceLocation();
+    FS_virtual_specified = false;
+    FS_virtualLoc = SourceLocation();
+    FS_explicit_specified = false;
+    FS_explicitLoc = SourceLocation();
+  }
+
+  /// hasTypeSpecifier - Return true if any type-specifier has been found.
+  bool hasTypeSpecifier() const {
+    return getTypeSpecType() != DeclSpec::TST_unspecified ||
+           getTypeSpecWidth() != DeclSpec::TSW_unspecified ||
+           getTypeSpecComplex() != DeclSpec::TSC_unspecified ||
+           getTypeSpecSign() != DeclSpec::TSS_unspecified;
+  }
+
+  /// getParsedSpecifiers - Return a bitmask of which flavors of specifiers this
+  /// DeclSpec includes.
+  ///
+  unsigned getParsedSpecifiers() const;
+
+  SCS getStorageClassSpecAsWritten() const {
+    return (SCS)StorageClassSpecAsWritten;
+  }
+
+  /// isEmpty - Return true if this declaration specifier is completely empty:
+  /// no tokens were parsed in the production of it.
+  bool isEmpty() const {
+    return getParsedSpecifiers() == DeclSpec::PQ_None;
+  }
+
+  void SetRangeStart(SourceLocation Loc) { Range.setBegin(Loc); }
+  void SetRangeEnd(SourceLocation Loc) { Range.setEnd(Loc); }
+
+  /// These methods set the specified attribute of the DeclSpec and
+  /// return false if there was no error.  If an error occurs (for
+  /// example, if we tried to set "auto" on a spec with "extern"
+  /// already set), they return true and set PrevSpec and DiagID
+  /// such that
+  ///   Diag(Loc, DiagID) << PrevSpec;
+  /// will yield a useful result.
+  ///
+  /// TODO: use a more general approach that still allows these
+  /// diagnostics to be ignored when desired.
+  bool SetStorageClassSpec(SCS S, SourceLocation Loc, const char *&PrevSpec,
+                           unsigned &DiagID);
+  bool SetStorageClassSpecThread(SourceLocation Loc, const char *&PrevSpec,
+                                 unsigned &DiagID);
+  bool SetTypeSpecWidth(TSW W, SourceLocation Loc, const char *&PrevSpec,
+                        unsigned &DiagID);
+  bool SetTypeSpecComplex(TSC C, SourceLocation Loc, const char *&PrevSpec,
+                          unsigned &DiagID);
+  bool SetTypeSpecSign(TSS S, SourceLocation Loc, const char *&PrevSpec,
+                       unsigned &DiagID);
+  bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec,
+                       unsigned &DiagID, void *Rep = 0, bool Owned = false);
+  bool SetTypeAltiVecVector(bool isAltiVecVector, SourceLocation Loc,
+                       const char *&PrevSpec, unsigned &DiagID);
+  bool SetTypeAltiVecPixel(bool isAltiVecPixel, SourceLocation Loc,
+                       const char *&PrevSpec, unsigned &DiagID);
+  bool SetTypeSpecError();
+  void UpdateTypeRep(void *Rep) { TypeRep = Rep; }
+
+  bool SetTypeQual(TQ T, SourceLocation Loc, const char *&PrevSpec,
+                   unsigned &DiagID, const LangOptions &Lang);
+
+  bool SetFunctionSpecInline(SourceLocation Loc, const char *&PrevSpec,
+                             unsigned &DiagID);
+  bool SetFunctionSpecVirtual(SourceLocation Loc, const char *&PrevSpec,
+                              unsigned &DiagID);
+  bool SetFunctionSpecExplicit(SourceLocation Loc, const char *&PrevSpec,
+                               unsigned &DiagID);
+
+  bool SetFriendSpec(SourceLocation Loc, const char *&PrevSpec,
+                     unsigned &DiagID);
+
+  bool SetConstexprSpec(SourceLocation Loc, const char *&PrevSpec,
+                        unsigned &DiagID);
+
+  bool isFriendSpecified() const { return Friend_specified; }
+  SourceLocation getFriendSpecLoc() const { return FriendLoc; }
+
+  bool isConstexprSpecified() const { return Constexpr_specified; }
+  SourceLocation getConstexprSpecLoc() const { return ConstexprLoc; }
+
+  /// AddAttributes - contatenates two attribute lists.
+  /// The GCC attribute syntax allows for the following:
+  ///
+  /// short __attribute__(( unused, deprecated ))
+  /// int __attribute__(( may_alias, aligned(16) )) var;
+  ///
+  /// This declares 4 attributes using 2 lists. The following syntax is
+  /// also allowed and equivalent to the previous declaration.
+  ///
+  /// short __attribute__((unused)) __attribute__((deprecated))
+  /// int __attribute__((may_alias)) __attribute__((aligned(16))) var;
+  ///
+  void AddAttributes(AttributeList *alist) {
+    AttrList = addAttributeLists(AttrList, alist);
+  }
+  void SetAttributes(AttributeList *AL) { AttrList = AL; }
+  const AttributeList *getAttributes() const { return AttrList; }
+  AttributeList *getAttributes() { return AttrList; }
+
+  /// TakeAttributes - Return the current attribute list and remove them from
+  /// the DeclSpec so that it doesn't own them.
+  AttributeList *TakeAttributes() {
+    AttributeList *AL = AttrList;
+    AttrList = 0;
+    return AL;
+  }
+
+  typedef const ActionBase::DeclPtrTy *ProtocolQualifierListTy;
+  ProtocolQualifierListTy getProtocolQualifiers() const {
+    return ProtocolQualifiers;
+  }
+  SourceLocation *getProtocolLocs() const { return ProtocolLocs; }
+  unsigned getNumProtocolQualifiers() const {
+    return NumProtocolQualifiers;
+  }
+  SourceLocation getProtocolLAngleLoc() const { return ProtocolLAngleLoc; }
+  void setProtocolQualifiers(const ActionBase::DeclPtrTy *Protos, unsigned NP,
+                             SourceLocation *ProtoLocs,
+                             SourceLocation LAngleLoc);
+
+  /// Finish - This does final analysis of the declspec, issuing diagnostics for
+  /// things like "_Imaginary" (lacking an FP type).  After calling this method,
+  /// DeclSpec is guaranteed self-consistent, even if an error occurred.
+  void Finish(Diagnostic &D, Preprocessor &PP);
+
+  const WrittenBuiltinSpecs& getWrittenBuiltinSpecs() const {
+    return writtenBS;
+  }
+
+  /// isMissingDeclaratorOk - This checks if this DeclSpec can stand alone,
+  /// without a Declarator. Only tag declspecs can stand alone.
+  bool isMissingDeclaratorOk();
+};
+
+/// ObjCDeclSpec - This class captures information about
+/// "declaration specifiers" specific to objective-c
+class ObjCDeclSpec {
+public:
+  /// ObjCDeclQualifier - Qualifier used on types in method declarations
+  enum ObjCDeclQualifier {
+    DQ_None = 0x0,
+    DQ_In = 0x1,
+    DQ_Inout = 0x2,
+    DQ_Out = 0x4,
+    DQ_Bycopy = 0x8,
+    DQ_Byref = 0x10,
+    DQ_Oneway = 0x20
+  };
+
+  /// PropertyAttributeKind - list of property attributes.
+  enum ObjCPropertyAttributeKind { DQ_PR_noattr = 0x0,
+    DQ_PR_readonly = 0x01,
+    DQ_PR_getter = 0x02,
+    DQ_PR_assign = 0x04,
+    DQ_PR_readwrite = 0x08,
+    DQ_PR_retain = 0x10,
+    DQ_PR_copy = 0x20,
+    DQ_PR_nonatomic = 0x40,
+    DQ_PR_setter = 0x80
+  };
+
+
+  ObjCDeclSpec()
+    : objcDeclQualifier(DQ_None), PropertyAttributes(DQ_PR_noattr),
+      GetterName(0), SetterName(0) { }
+  ObjCDeclQualifier getObjCDeclQualifier() const { return objcDeclQualifier; }
+  void setObjCDeclQualifier(ObjCDeclQualifier DQVal) {
+    objcDeclQualifier = (ObjCDeclQualifier) (objcDeclQualifier | DQVal);
+  }
+
+  ObjCPropertyAttributeKind getPropertyAttributes() const {
+    return ObjCPropertyAttributeKind(PropertyAttributes);
+  }
+  void setPropertyAttributes(ObjCPropertyAttributeKind PRVal) {
+    PropertyAttributes =
+      (ObjCPropertyAttributeKind)(PropertyAttributes | PRVal);
+  }
+
+  const IdentifierInfo *getGetterName() const { return GetterName; }
+  IdentifierInfo *getGetterName() { return GetterName; }
+  void setGetterName(IdentifierInfo *name) { GetterName = name; }
+
+  const IdentifierInfo *getSetterName() const { return SetterName; }
+  IdentifierInfo *getSetterName() { return SetterName; }
+  void setSetterName(IdentifierInfo *name) { SetterName = name; }
+private:
+  // FIXME: These two are unrelated and mutially exclusive. So perhaps
+  // we can put them in a union to reflect their mutual exclusiveness
+  // (space saving is negligible).
+  ObjCDeclQualifier objcDeclQualifier : 6;
+
+  // NOTE: VC++ treats enums as signed, avoid using ObjCPropertyAttributeKind
+  unsigned PropertyAttributes : 8;
+  IdentifierInfo *GetterName;    // getter name of NULL if no getter
+  IdentifierInfo *SetterName;    // setter name of NULL if no setter
+};
+
+/// \brief Represents a C++ unqualified-id that has been parsed. 
+class UnqualifiedId {
+private:
+  const UnqualifiedId &operator=(const UnqualifiedId &); // DO NOT IMPLEMENT
+  
+public:
+  /// \brief Describes the kind of unqualified-id parsed.
+  enum IdKind {
+    /// \brief An identifier.
+    IK_Identifier,
+    /// \brief An overloaded operator name, e.g., operator+.
+    IK_OperatorFunctionId,
+    /// \brief A conversion function name, e.g., operator int.
+    IK_ConversionFunctionId,
+    /// \brief A user-defined literal name, e.g., operator "" _i.
+    IK_LiteralOperatorId,
+    /// \brief A constructor name.
+    IK_ConstructorName,
+    /// \brief A constructor named via a template-id.
+    IK_ConstructorTemplateId,
+    /// \brief A destructor name.
+    IK_DestructorName,
+    /// \brief A template-id, e.g., f<int>.
+    IK_TemplateId
+  } Kind;
+
+  /// \brief Anonymous union that holds extra data associated with the
+  /// parsed unqualified-id.
+  union {
+    /// \brief When Kind == IK_Identifier, the parsed identifier, or when Kind
+    /// == IK_UserLiteralId, the identifier suffix.
+    IdentifierInfo *Identifier;
+    
+    /// \brief When Kind == IK_OperatorFunctionId, the overloaded operator
+    /// that we parsed.
+    struct {
+      /// \brief The kind of overloaded operator.
+      OverloadedOperatorKind Operator;
+      
+      /// \brief The source locations of the individual tokens that name
+      /// the operator, e.g., the "new", "[", and "]" tokens in 
+      /// operator new []. 
+      ///
+      /// Different operators have different numbers of tokens in their name,
+      /// up to three. Any remaining source locations in this array will be
+      /// set to an invalid value for operators with fewer than three tokens.
+      unsigned SymbolLocations[3];
+    } OperatorFunctionId;
+    
+    /// \brief When Kind == IK_ConversionFunctionId, the type that the 
+    /// conversion function names.
+    ActionBase::TypeTy *ConversionFunctionId;
+
+    /// \brief When Kind == IK_ConstructorName, the class-name of the type
+    /// whose constructor is being referenced.
+    ActionBase::TypeTy *ConstructorName;
+    
+    /// \brief When Kind == IK_DestructorName, the type referred to by the
+    /// class-name.
+    ActionBase::TypeTy *DestructorName;
+    
+    /// \brief When Kind == IK_TemplateId or IK_ConstructorTemplateId,
+    /// the template-id annotation that contains the template name and
+    /// template arguments.
+    TemplateIdAnnotation *TemplateId;
+  };
+  
+  /// \brief The location of the first token that describes this unqualified-id,
+  /// which will be the location of the identifier, "operator" keyword,
+  /// tilde (for a destructor), or the template name of a template-id.
+  SourceLocation StartLocation;
+  
+  /// \brief The location of the last token that describes this unqualified-id.
+  SourceLocation EndLocation;
+  
+  UnqualifiedId() : Kind(IK_Identifier), Identifier(0) { }
+  
+  /// \brief Do not use this copy constructor. It is temporary, and only
+  /// exists because we are holding FieldDeclarators in a SmallVector when we
+  /// don't actually need them.
+  ///
+  /// FIXME: Kill this copy constructor.
+  UnqualifiedId(const UnqualifiedId &Other) 
+    : Kind(IK_Identifier), Identifier(Other.Identifier), 
+      StartLocation(Other.StartLocation), EndLocation(Other.EndLocation) {
+    assert(Other.Kind == IK_Identifier && "Cannot copy non-identifiers");
+  }
+
+  /// \brief Destroy this unqualified-id.
+  ~UnqualifiedId() { clear(); }
+  
+  /// \brief Clear out this unqualified-id, setting it to default (invalid) 
+  /// state.
+  void clear();
+  
+  /// \brief Determine whether this unqualified-id refers to a valid name.
+  bool isValid() const { return StartLocation.isValid(); }
+
+  /// \brief Determine whether this unqualified-id refers to an invalid name.
+  bool isInvalid() const { return !isValid(); }
+  
+  /// \brief Determine what kind of name we have.
+  IdKind getKind() const { return Kind; }
+  
+  /// \brief Specify that this unqualified-id was parsed as an identifier.
+  ///
+  /// \param Id the parsed identifier.
+  /// \param IdLoc the location of the parsed identifier.
+  void setIdentifier(const IdentifierInfo *Id, SourceLocation IdLoc) {
+    Kind = IK_Identifier;
+    Identifier = const_cast<IdentifierInfo *>(Id);
+    StartLocation = EndLocation = IdLoc;
+  }
+  
+  /// \brief Specify that this unqualified-id was parsed as an 
+  /// operator-function-id.
+  ///
+  /// \param OperatorLoc the location of the 'operator' keyword.
+  ///
+  /// \param Op the overloaded operator.
+  ///
+  /// \param SymbolLocations the locations of the individual operator symbols
+  /// in the operator.
+  void setOperatorFunctionId(SourceLocation OperatorLoc, 
+                             OverloadedOperatorKind Op,
+                             SourceLocation SymbolLocations[3]);
+  
+  /// \brief Specify that this unqualified-id was parsed as a 
+  /// conversion-function-id.
+  ///
+  /// \param OperatorLoc the location of the 'operator' keyword.
+  ///
+  /// \param Ty the type to which this conversion function is converting.
+  ///
+  /// \param EndLoc the location of the last token that makes up the type name.
+  void setConversionFunctionId(SourceLocation OperatorLoc, 
+                               ActionBase::TypeTy *Ty,
+                               SourceLocation EndLoc) {
+    Kind = IK_ConversionFunctionId;
+    StartLocation = OperatorLoc;
+    EndLocation = EndLoc;
+    ConversionFunctionId = Ty;
+  }
+
+  /// \brief Specific that this unqualified-id was parsed as a
+  /// literal-operator-id.
+  ///
+  /// \param Id the parsed identifier.
+  ///
+  /// \param OpLoc the location of the 'operator' keyword.
+  ///
+  /// \param IdLoc the location of the identifier.
+  void setLiteralOperatorId(const IdentifierInfo *Id, SourceLocation OpLoc,
+                              SourceLocation IdLoc) {
+    Kind = IK_LiteralOperatorId;
+    Identifier = const_cast<IdentifierInfo *>(Id);
+    StartLocation = OpLoc;
+    EndLocation = IdLoc;
+  }
+  
+  /// \brief Specify that this unqualified-id was parsed as a constructor name.
+  ///
+  /// \param ClassType the class type referred to by the constructor name.
+  ///
+  /// \param ClassNameLoc the location of the class name.
+  ///
+  /// \param EndLoc the location of the last token that makes up the type name.
+  void setConstructorName(ActionBase::TypeTy *ClassType, 
+                          SourceLocation ClassNameLoc,
+                          SourceLocation EndLoc) {
+    Kind = IK_ConstructorName;
+    StartLocation = ClassNameLoc;
+    EndLocation = EndLoc;
+    ConstructorName = ClassType;
+  }
+
+  /// \brief Specify that this unqualified-id was parsed as a
+  /// template-id that names a constructor.
+  ///
+  /// \param TemplateId the template-id annotation that describes the parsed
+  /// template-id. This UnqualifiedId instance will take ownership of the
+  /// \p TemplateId and will free it on destruction.
+  void setConstructorTemplateId(TemplateIdAnnotation *TemplateId);
+
+  /// \brief Specify that this unqualified-id was parsed as a destructor name.
+  ///
+  /// \param TildeLoc the location of the '~' that introduces the destructor
+  /// name.
+  ///
+  /// \param ClassType the name of the class referred to by the destructor name.
+  void setDestructorName(SourceLocation TildeLoc, ActionBase::TypeTy *ClassType,
+                         SourceLocation EndLoc) {
+    Kind = IK_DestructorName;
+    StartLocation = TildeLoc;
+    EndLocation = EndLoc;
+    DestructorName = ClassType;
+  }
+  
+  /// \brief Specify that this unqualified-id was parsed as a template-id.
+  ///
+  /// \param TemplateId the template-id annotation that describes the parsed
+  /// template-id. This UnqualifiedId instance will take ownership of the
+  /// \p TemplateId and will free it on destruction.
+  void setTemplateId(TemplateIdAnnotation *TemplateId);
+
+  /// \brief Return the source range that covers this unqualified-id.
+  SourceRange getSourceRange() const { 
+    return SourceRange(StartLocation, EndLocation); 
+  }
+};
+  
+/// CachedTokens - A set of tokens that has been cached for later
+/// parsing.
+typedef llvm::SmallVector<Token, 4> CachedTokens;
+
+/// DeclaratorChunk - One instance of this struct is used for each type in a
+/// declarator that is parsed.
+///
+/// This is intended to be a small value object.
+struct DeclaratorChunk {
+  enum {
+    Pointer, Reference, Array, Function, BlockPointer, MemberPointer
+  } Kind;
+
+  /// Loc - The place where this type was defined.
+  SourceLocation Loc;
+  /// EndLoc - If valid, the place where this chunck ends.
+  SourceLocation EndLoc;
+
+  struct PointerTypeInfo {
+    /// The type qualifiers: const/volatile/restrict.
+    unsigned TypeQuals : 3;
+    AttributeList *AttrList;
+    void destroy() {
+      delete AttrList;
+    }
+  };
+
+  struct ReferenceTypeInfo {
+    /// The type qualifier: restrict. [GNU] C++ extension
+    bool HasRestrict : 1;
+    /// True if this is an lvalue reference, false if it's an rvalue reference.
+    bool LValueRef : 1;
+    AttributeList *AttrList;
+    void destroy() {
+      delete AttrList;
+    }
+  };
+
+  struct ArrayTypeInfo {
+    /// The type qualifiers for the array: const/volatile/restrict.
+    unsigned TypeQuals : 3;
+
+    /// True if this dimension included the 'static' keyword.
+    bool hasStatic : 1;
+
+    /// True if this dimension was [*].  In this case, NumElts is null.
+    bool isStar : 1;
+
+    /// This is the size of the array, or null if [] or [*] was specified.
+    /// Since the parser is multi-purpose, and we don't want to impose a root
+    /// expression class on all clients, NumElts is untyped.
+    ActionBase::ExprTy *NumElts;
+    void destroy() {}
+  };
+
+  /// ParamInfo - An array of paraminfo objects is allocated whenever a function
+  /// declarator is parsed.  There are two interesting styles of arguments here:
+  /// K&R-style identifier lists and parameter type lists.  K&R-style identifier
+  /// lists will have information about the identifier, but no type information.
+  /// Parameter type lists will have type info (if the actions module provides
+  /// it), but may have null identifier info: e.g. for 'void foo(int X, int)'.
+  struct ParamInfo {
+    IdentifierInfo *Ident;
+    SourceLocation IdentLoc;
+    ActionBase::DeclPtrTy Param;
+
+    /// DefaultArgTokens - When the parameter's default argument
+    /// cannot be parsed immediately (because it occurs within the
+    /// declaration of a member function), it will be stored here as a
+    /// sequence of tokens to be parsed once the class definition is
+    /// complete. Non-NULL indicates that there is a default argument.
+    CachedTokens *DefaultArgTokens;
+
+    ParamInfo() {}
+    ParamInfo(IdentifierInfo *ident, SourceLocation iloc,
+              ActionBase::DeclPtrTy param,
+              CachedTokens *DefArgTokens = 0)
+      : Ident(ident), IdentLoc(iloc), Param(param),
+        DefaultArgTokens(DefArgTokens) {}
+  };
+
+  struct TypeAndRange {
+    ActionBase::TypeTy *Ty;
+    SourceRange Range;
+  };
+
+  struct FunctionTypeInfo {
+    /// hasPrototype - This is true if the function had at least one typed
+    /// argument.  If the function is () or (a,b,c), then it has no prototype,
+    /// and is treated as a K&R-style function.
+    bool hasPrototype : 1;
+
+    /// isVariadic - If this function has a prototype, and if that
+    /// proto ends with ',...)', this is true. When true, EllipsisLoc
+    /// contains the location of the ellipsis.
+    bool isVariadic : 1;
+
+    /// The type qualifiers: const/volatile/restrict.
+    /// The qualifier bitmask values are the same as in QualType.
+    unsigned TypeQuals : 3;
+
+    /// hasExceptionSpec - True if the function has an exception specification.
+    bool hasExceptionSpec : 1;
+
+    /// hasAnyExceptionSpec - True if the function has a throw(...) specifier.
+    bool hasAnyExceptionSpec : 1;
+
+    /// DeleteArgInfo - If this is true, we need to delete[] ArgInfo.
+    bool DeleteArgInfo : 1;
+
+    /// When isVariadic is true, the location of the ellipsis in the source.
+    unsigned EllipsisLoc;
+
+    /// NumArgs - This is the number of formal arguments provided for the
+    /// declarator.
+    unsigned NumArgs;
+
+    /// NumExceptions - This is the number of types in the exception-decl, if
+    /// the function has one.
+    unsigned NumExceptions;
+
+    /// ThrowLoc - When hasExceptionSpec is true, the location of the throw
+    /// keyword introducing the spec.
+    unsigned ThrowLoc;
+
+    /// ArgInfo - This is a pointer to a new[]'d array of ParamInfo objects that
+    /// describe the arguments for this function declarator.  This is null if
+    /// there are no arguments specified.
+    ParamInfo *ArgInfo;
+
+    /// Exceptions - This is a pointer to a new[]'d array of TypeAndRange
+    /// objects that contain the types in the function's exception
+    /// specification and their locations.
+    TypeAndRange *Exceptions;
+
+    /// freeArgs - reset the argument list to having zero arguments.  This is
+    /// used in various places for error recovery.
+    void freeArgs() {
+      if (DeleteArgInfo) {
+        delete[] ArgInfo;
+        DeleteArgInfo = false;
+      }
+      NumArgs = 0;
+    }
+
+    void destroy() {
+      if (DeleteArgInfo)
+        delete[] ArgInfo;
+      delete[] Exceptions;
+    }
+
+    SourceLocation getEllipsisLoc() const {
+      return SourceLocation::getFromRawEncoding(EllipsisLoc);
+    }
+    SourceLocation getThrowLoc() const {
+      return SourceLocation::getFromRawEncoding(ThrowLoc);
+    }
+  };
+
+  struct BlockPointerTypeInfo {
+    /// For now, sema will catch these as invalid.
+    /// The type qualifiers: const/volatile/restrict.
+    unsigned TypeQuals : 3;
+    AttributeList *AttrList;
+    void destroy() {
+      delete AttrList;
+    }
+  };
+
+  struct MemberPointerTypeInfo {
+    /// The type qualifiers: const/volatile/restrict.
+    unsigned TypeQuals : 3;
+    AttributeList *AttrList;
+    // CXXScopeSpec has a constructor, so it can't be a direct member.
+    // So we need some pointer-aligned storage and a bit of trickery.
+    union {
+      void *Aligner;
+      char Mem[sizeof(CXXScopeSpec)];
+    } ScopeMem;
+    CXXScopeSpec &Scope() {
+      return *reinterpret_cast<CXXScopeSpec*>(ScopeMem.Mem);
+    }
+    const CXXScopeSpec &Scope() const {
+      return *reinterpret_cast<const CXXScopeSpec*>(ScopeMem.Mem);
+    }
+    void destroy() {
+      delete AttrList;
+      Scope().~CXXScopeSpec();
+    }
+  };
+
+  union {
+    PointerTypeInfo       Ptr;
+    ReferenceTypeInfo     Ref;
+    ArrayTypeInfo         Arr;
+    FunctionTypeInfo      Fun;
+    BlockPointerTypeInfo  Cls;
+    MemberPointerTypeInfo Mem;
+  };
+
+  void destroy() {
+    switch (Kind) {
+    default: assert(0 && "Unknown decl type!");
+    case DeclaratorChunk::Function:      return Fun.destroy();
+    case DeclaratorChunk::Pointer:       return Ptr.destroy();
+    case DeclaratorChunk::BlockPointer:  return Cls.destroy();
+    case DeclaratorChunk::Reference:     return Ref.destroy();
+    case DeclaratorChunk::Array:         return Arr.destroy();
+    case DeclaratorChunk::MemberPointer: return Mem.destroy();
+    }
+  }
+
+  /// getAttrs - If there are attributes applied to this declaratorchunk, return
+  /// them.
+  const AttributeList *getAttrs() const {
+    switch (Kind) {
+    default: assert(0 && "Unknown declarator kind!");
+    case Pointer:       return Ptr.AttrList;
+    case Reference:     return Ref.AttrList;
+    case MemberPointer: return Mem.AttrList;
+    case Array:         return 0;
+    case Function:      return 0;
+    case BlockPointer:  return Cls.AttrList;
+    }
+  }
+
+
+  /// getPointer - Return a DeclaratorChunk for a pointer.
+  ///
+  static DeclaratorChunk getPointer(unsigned TypeQuals, SourceLocation Loc,
+                                    AttributeList *AL) {
+    DeclaratorChunk I;
+    I.Kind          = Pointer;
+    I.Loc           = Loc;
+    I.Ptr.TypeQuals = TypeQuals;
+    I.Ptr.AttrList  = AL;
+    return I;
+  }
+
+  /// getReference - Return a DeclaratorChunk for a reference.
+  ///
+  static DeclaratorChunk getReference(unsigned TypeQuals, SourceLocation Loc,
+                                      AttributeList *AL, bool lvalue) {
+    DeclaratorChunk I;
+    I.Kind            = Reference;
+    I.Loc             = Loc;
+    I.Ref.HasRestrict = (TypeQuals & DeclSpec::TQ_restrict) != 0;
+    I.Ref.LValueRef   = lvalue;
+    I.Ref.AttrList  = AL;
+    return I;
+  }
+
+  /// getArray - Return a DeclaratorChunk for an array.
+  ///
+  static DeclaratorChunk getArray(unsigned TypeQuals, bool isStatic,
+                                  bool isStar, void *NumElts,
+                                  SourceLocation LBLoc, SourceLocation RBLoc) {
+    DeclaratorChunk I;
+    I.Kind          = Array;
+    I.Loc           = LBLoc;
+    I.EndLoc        = RBLoc;
+    I.Arr.TypeQuals = TypeQuals;
+    I.Arr.hasStatic = isStatic;
+    I.Arr.isStar    = isStar;
+    I.Arr.NumElts   = NumElts;
+    return I;
+  }
+
+  /// DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function.
+  /// "TheDeclarator" is the declarator that this will be added to.
+  static DeclaratorChunk getFunction(bool hasProto, bool isVariadic,
+                                     SourceLocation EllipsisLoc,
+                                     ParamInfo *ArgInfo, unsigned NumArgs,
+                                     unsigned TypeQuals, bool hasExceptionSpec,
+                                     SourceLocation ThrowLoc,
+                                     bool hasAnyExceptionSpec,
+                                     ActionBase::TypeTy **Exceptions,
+                                     SourceRange *ExceptionRanges,
+                                     unsigned NumExceptions,
+                                     SourceLocation LPLoc, SourceLocation RPLoc,
+                                     Declarator &TheDeclarator);
+
+  /// getBlockPointer - Return a DeclaratorChunk for a block.
+  ///
+  static DeclaratorChunk getBlockPointer(unsigned TypeQuals, SourceLocation Loc,
+                                         AttributeList *AL) {
+    DeclaratorChunk I;
+    I.Kind          = BlockPointer;
+    I.Loc           = Loc;
+    I.Cls.TypeQuals = TypeQuals;
+    I.Cls.AttrList  = AL;
+    return I;
+  }
+
+  static DeclaratorChunk getMemberPointer(const CXXScopeSpec &SS,
+                                          unsigned TypeQuals,
+                                          SourceLocation Loc,
+                                          AttributeList *AL) {
+    DeclaratorChunk I;
+    I.Kind          = MemberPointer;
+    I.Loc           = Loc;
+    I.Mem.TypeQuals = TypeQuals;
+    I.Mem.AttrList  = AL;
+    new (I.Mem.ScopeMem.Mem) CXXScopeSpec(SS);
+    return I;
+  }
+};
+
+/// Declarator - Information about one declarator, including the parsed type
+/// information and the identifier.  When the declarator is fully formed, this
+/// is turned into the appropriate Decl object.
+///
+/// Declarators come in two types: normal declarators and abstract declarators.
+/// Abstract declarators are used when parsing types, and don't have an
+/// identifier.  Normal declarators do have ID's.
+///
+/// Instances of this class should be a transient object that lives on the
+/// stack, not objects that are allocated in large quantities on the heap.
+class Declarator {
+public:
+  enum TheContext {
+    FileContext,         // File scope declaration.
+    PrototypeContext,    // Within a function prototype.
+    KNRTypeListContext,  // K&R type definition list for formals.
+    TypeNameContext,     // Abstract declarator for types.
+    MemberContext,       // Struct/Union field.
+    BlockContext,        // Declaration within a block in a function.
+    ForContext,          // Declaration within first part of a for loop.
+    ConditionContext,    // Condition declaration in a C++ if/switch/while/for.
+    TemplateParamContext,// Within a template parameter list.
+    CXXCatchContext,     // C++ catch exception-declaration
+    BlockLiteralContext  // Block literal declarator.
+  };
+
+private:
+  const DeclSpec &DS;
+  CXXScopeSpec SS;
+  UnqualifiedId Name;
+  SourceRange Range;
+
+  /// Context - Where we are parsing this declarator.
+  ///
+  TheContext Context;
+
+  /// DeclTypeInfo - This holds each type that the declarator includes as it is
+  /// parsed.  This is pushed from the identifier out, which means that element
+  /// #0 will be the most closely bound to the identifier, and
+  /// DeclTypeInfo.back() will be the least closely bound.
+  llvm::SmallVector<DeclaratorChunk, 8> DeclTypeInfo;
+
+  /// InvalidType - Set by Sema::GetTypeForDeclarator().
+  bool InvalidType : 1;
+
+  /// GroupingParens - Set by Parser::ParseParenDeclarator().
+  bool GroupingParens : 1;
+
+  /// AttrList - Attributes.
+  AttributeList *AttrList;
+
+  /// AsmLabel - The asm label, if specified.
+  ActionBase::ExprTy *AsmLabel;
+
+  /// InlineParams - This is a local array used for the first function decl
+  /// chunk to avoid going to the heap for the common case when we have one
+  /// function chunk in the declarator.
+  DeclaratorChunk::ParamInfo InlineParams[16];
+  bool InlineParamsUsed;
+
+  /// Extension - true if the declaration is preceded by __extension__.
+  bool Extension : 1;
+
+  friend struct DeclaratorChunk;
+
+public:
+  Declarator(const DeclSpec &ds, TheContext C)
+    : DS(ds), Range(ds.getSourceRange()), Context(C),
+      InvalidType(DS.getTypeSpecType() == DeclSpec::TST_error),
+      GroupingParens(false), AttrList(0), AsmLabel(0),
+      InlineParamsUsed(false), Extension(false) {
+  }
+
+  ~Declarator() {
+    clear();
+  }
+
+  /// getDeclSpec - Return the declaration-specifier that this declarator was
+  /// declared with.
+  const DeclSpec &getDeclSpec() const { return DS; }
+
+  /// getMutableDeclSpec - Return a non-const version of the DeclSpec.  This
+  /// should be used with extreme care: declspecs can often be shared between
+  /// multiple declarators, so mutating the DeclSpec affects all of the
+  /// Declarators.  This should only be done when the declspec is known to not
+  /// be shared or when in error recovery etc.
+  DeclSpec &getMutableDeclSpec() { return const_cast<DeclSpec &>(DS); }
+
+  /// getCXXScopeSpec - Return the C++ scope specifier (global scope or
+  /// nested-name-specifier) that is part of the declarator-id.
+  const CXXScopeSpec &getCXXScopeSpec() const { return SS; }
+  CXXScopeSpec &getCXXScopeSpec() { return SS; }
+
+  /// \brief Retrieve the name specified by this declarator.
+  UnqualifiedId &getName() { return Name; }
+  
+  TheContext getContext() const { return Context; }
+
+  /// getSourceRange - Get the source range that spans this declarator.
+  const SourceRange &getSourceRange() const { return Range; }
+
+  void SetSourceRange(SourceRange R) { Range = R; }
+  /// SetRangeBegin - Set the start of the source range to Loc, unless it's
+  /// invalid.
+  void SetRangeBegin(SourceLocation Loc) {
+    if (!Loc.isInvalid())
+      Range.setBegin(Loc);
+  }
+  /// SetRangeEnd - Set the end of the source range to Loc, unless it's invalid.
+  void SetRangeEnd(SourceLocation Loc) {
+    if (!Loc.isInvalid())
+      Range.setEnd(Loc);
+  }
+  /// ExtendWithDeclSpec - Extend the declarator source range to include the
+  /// given declspec, unless its location is invalid. Adopts the range start if
+  /// the current range start is invalid.
+  void ExtendWithDeclSpec(const DeclSpec &DS) {
+    const SourceRange &SR = DS.getSourceRange();
+    if (Range.getBegin().isInvalid())
+      Range.setBegin(SR.getBegin());
+    if (!SR.getEnd().isInvalid())
+      Range.setEnd(SR.getEnd());
+  }
+
+  /// clear - Reset the contents of this Declarator.
+  void clear() {
+    SS.clear();
+    Name.clear();
+    Range = DS.getSourceRange();
+    
+    for (unsigned i = 0, e = DeclTypeInfo.size(); i != e; ++i)
+      DeclTypeInfo[i].destroy();
+    DeclTypeInfo.clear();
+    delete AttrList;
+    AttrList = 0;
+    AsmLabel = 0;
+    InlineParamsUsed = false;
+  }
+
+  /// mayOmitIdentifier - Return true if the identifier is either optional or
+  /// not allowed.  This is true for typenames, prototypes, and template
+  /// parameter lists.
+  bool mayOmitIdentifier() const {
+    return Context == TypeNameContext || Context == PrototypeContext ||
+           Context == TemplateParamContext || Context == CXXCatchContext ||
+           Context == BlockLiteralContext;
+  }
+
+  /// mayHaveIdentifier - Return true if the identifier is either optional or
+  /// required.  This is true for normal declarators and prototypes, but not
+  /// typenames.
+  bool mayHaveIdentifier() const {
+    return Context != TypeNameContext && Context != BlockLiteralContext;
+  }
+
+  /// mayBeFollowedByCXXDirectInit - Return true if the declarator can be
+  /// followed by a C++ direct initializer, e.g. "int x(1);".
+  bool mayBeFollowedByCXXDirectInit() const {
+    return !hasGroupingParens() &&
+           (Context == FileContext  ||
+            Context == BlockContext ||
+            Context == ForContext);
+  }
+
+  /// isPastIdentifier - Return true if we have parsed beyond the point where
+  /// the
+  bool isPastIdentifier() const { return Name.isValid(); }
+
+  /// hasName - Whether this declarator has a name, which might be an
+  /// identifier (accessible via getIdentifier()) or some kind of
+  /// special C++ name (constructor, destructor, etc.).
+  bool hasName() const { 
+    return Name.getKind() != UnqualifiedId::IK_Identifier || Name.Identifier;
+  }
+
+  IdentifierInfo *getIdentifier() const { 
+    if (Name.getKind() == UnqualifiedId::IK_Identifier)
+      return Name.Identifier;
+    
+    return 0;
+  }
+  SourceLocation getIdentifierLoc() const { return Name.StartLocation; }
+
+  /// \brief Set the name of this declarator to be the given identifier.
+  void SetIdentifier(IdentifierInfo *Id, SourceLocation IdLoc) {
+    Name.setIdentifier(Id, IdLoc);
+  }
+  
+  /// AddTypeInfo - Add a chunk to this declarator. Also extend the range to
+  /// EndLoc, which should be the last token of the chunk.
+  void AddTypeInfo(const DeclaratorChunk &TI, SourceLocation EndLoc) {
+    DeclTypeInfo.push_back(TI);
+    if (!EndLoc.isInvalid())
+      SetRangeEnd(EndLoc);
+  }
+
+  /// getNumTypeObjects() - Return the number of types applied to this
+  /// declarator.
+  unsigned getNumTypeObjects() const { return DeclTypeInfo.size(); }
+
+  /// Return the specified TypeInfo from this declarator.  TypeInfo #0 is
+  /// closest to the identifier.
+  const DeclaratorChunk &getTypeObject(unsigned i) const {
+    assert(i < DeclTypeInfo.size() && "Invalid type chunk");
+    return DeclTypeInfo[i];
+  }
+  DeclaratorChunk &getTypeObject(unsigned i) {
+    assert(i < DeclTypeInfo.size() && "Invalid type chunk");
+    return DeclTypeInfo[i];
+  }
+
+  void DropFirstTypeObject()
+  {
+    assert(!DeclTypeInfo.empty() && "No type chunks to drop.");
+    DeclTypeInfo.front().destroy();
+    DeclTypeInfo.erase(DeclTypeInfo.begin());
+  }
+
+  /// isFunctionDeclarator - Once this declarator is fully parsed and formed,
+  /// this method returns true if the identifier is a function declarator.
+  bool isFunctionDeclarator() const {
+    return !DeclTypeInfo.empty() &&
+           DeclTypeInfo[0].Kind == DeclaratorChunk::Function;
+  }
+
+  /// AddAttributes - simply adds the attribute list to the Declarator.
+  /// These examples both add 3 attributes to "var":
+  ///  short int var __attribute__((aligned(16),common,deprecated));
+  ///  short int x, __attribute__((aligned(16)) var
+  ///                                 __attribute__((common,deprecated));
+  ///
+  /// Also extends the range of the declarator.
+  void AddAttributes(AttributeList *alist, SourceLocation LastLoc) {
+    AttrList = addAttributeLists(AttrList, alist);
+
+    if (!LastLoc.isInvalid())
+      SetRangeEnd(LastLoc);
+  }
+
+  const AttributeList *getAttributes() const { return AttrList; }
+  AttributeList *getAttributes() { return AttrList; }
+
+  /// hasAttributes - do we contain any attributes?
+  bool hasAttributes() const {
+    if (getAttributes() || getDeclSpec().getAttributes()) return true;
+    for (unsigned i = 0, e = getNumTypeObjects(); i != e; ++i)
+      if (getTypeObject(i).getAttrs())
+        return true;
+    return false;
+  }
+
+  void setAsmLabel(ActionBase::ExprTy *E) { AsmLabel = E; }
+  ActionBase::ExprTy *getAsmLabel() const { return AsmLabel; }
+
+  void setExtension(bool Val = true) { Extension = Val; }
+  bool getExtension() const { return Extension; }
+
+  void setInvalidType(bool Val = true) { InvalidType = Val; }
+  bool isInvalidType() const {
+    return InvalidType || DS.getTypeSpecType() == DeclSpec::TST_error;
+  }
+
+  void setGroupingParens(bool flag) { GroupingParens = flag; }
+  bool hasGroupingParens() const { return GroupingParens; }
+};
+
+/// FieldDeclarator - This little struct is used to capture information about
+/// structure field declarators, which is basically just a bitfield size.
+struct FieldDeclarator {
+  Declarator D;
+  ActionBase::ExprTy *BitfieldSize;
+  explicit FieldDeclarator(DeclSpec &DS) : D(DS, Declarator::MemberContext) {
+    BitfieldSize = 0;
+  }
+};
+  
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Parse/Designator.h b/include/clang/Parse/Designator.h
new file mode 100644
index 0000000..255af59
--- /dev/null
+++ b/include/clang/Parse/Designator.h
@@ -0,0 +1,239 @@
+//===--- Designator.h - Initialization Designator ---------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines interfaces used to represent Designators in the parser and
+// is the input to Actions module.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_PARSE_DESIGNATOR_H
+#define LLVM_CLANG_PARSE_DESIGNATOR_H
+
+#include "clang/Parse/Action.h"
+
+namespace clang {
+
+/// Designator - This class is a discriminated union which holds the various
+/// different sorts of designators possible.  A Designation is an array of
+/// these.  An example of a designator are things like this:
+///     [8] .field [47]        // C99 designation: 3 designators
+///     [8 ... 47]  field:     // GNU extensions: 2 designators
+/// These occur in initializers, e.g.:
+///  int a[10] = {2, 4, [8]=9, 10};
+///
+class Designator {
+public:
+  enum DesignatorKind {
+    FieldDesignator, ArrayDesignator, ArrayRangeDesignator
+  };
+private:
+  DesignatorKind Kind;
+
+  struct FieldDesignatorInfo {
+    const IdentifierInfo *II;
+    unsigned DotLoc;
+    unsigned NameLoc;
+  };
+  struct ArrayDesignatorInfo {
+    ActionBase::ExprTy *Index;
+    unsigned LBracketLoc;
+    mutable unsigned  RBracketLoc;
+  };
+  struct ArrayRangeDesignatorInfo {
+    ActionBase::ExprTy *Start, *End;
+    unsigned LBracketLoc, EllipsisLoc;
+    mutable unsigned RBracketLoc;
+  };
+
+  union {
+    FieldDesignatorInfo FieldInfo;
+    ArrayDesignatorInfo ArrayInfo;
+    ArrayRangeDesignatorInfo ArrayRangeInfo;
+  };
+
+public:
+
+  DesignatorKind getKind() const { return Kind; }
+  bool isFieldDesignator() const { return Kind == FieldDesignator; }
+  bool isArrayDesignator() const { return Kind == ArrayDesignator; }
+  bool isArrayRangeDesignator() const { return Kind == ArrayRangeDesignator; }
+
+  const IdentifierInfo *getField() const {
+    assert(isFieldDesignator() && "Invalid accessor");
+    return FieldInfo.II;
+  }
+
+  SourceLocation getDotLoc() const {
+    assert(isFieldDesignator() && "Invalid accessor");
+    return SourceLocation::getFromRawEncoding(FieldInfo.DotLoc);
+  }
+
+  SourceLocation getFieldLoc() const {
+    assert(isFieldDesignator() && "Invalid accessor");
+    return SourceLocation::getFromRawEncoding(FieldInfo.NameLoc);
+  }
+
+  ActionBase::ExprTy *getArrayIndex() const {
+    assert(isArrayDesignator() && "Invalid accessor");
+    return ArrayInfo.Index;
+  }
+
+  ActionBase::ExprTy *getArrayRangeStart() const {
+    assert(isArrayRangeDesignator() && "Invalid accessor");
+    return ArrayRangeInfo.Start;
+  }
+  ActionBase::ExprTy *getArrayRangeEnd() const {
+    assert(isArrayRangeDesignator() && "Invalid accessor");
+    return ArrayRangeInfo.End;
+  }
+
+  SourceLocation getLBracketLoc() const {
+    assert((isArrayDesignator() || isArrayRangeDesignator()) &&
+           "Invalid accessor");
+    if (isArrayDesignator())
+      return SourceLocation::getFromRawEncoding(ArrayInfo.LBracketLoc);
+    else
+      return SourceLocation::getFromRawEncoding(ArrayRangeInfo.LBracketLoc);
+  }
+
+  SourceLocation getRBracketLoc() const {
+    assert((isArrayDesignator() || isArrayRangeDesignator()) &&
+           "Invalid accessor");
+    if (isArrayDesignator())
+      return SourceLocation::getFromRawEncoding(ArrayInfo.RBracketLoc);
+    else
+      return SourceLocation::getFromRawEncoding(ArrayRangeInfo.RBracketLoc);
+  }
+
+  SourceLocation getEllipsisLoc() const {
+    assert(isArrayRangeDesignator() && "Invalid accessor");
+    return SourceLocation::getFromRawEncoding(ArrayRangeInfo.EllipsisLoc);
+  }
+
+  static Designator getField(const IdentifierInfo *II, SourceLocation DotLoc,
+                             SourceLocation NameLoc) {
+    Designator D;
+    D.Kind = FieldDesignator;
+    D.FieldInfo.II = II;
+    D.FieldInfo.DotLoc = DotLoc.getRawEncoding();
+    D.FieldInfo.NameLoc = NameLoc.getRawEncoding();
+    return D;
+  }
+
+  static Designator getArray(ActionBase::ExprTy *Index,
+                             SourceLocation LBracketLoc) {
+    Designator D;
+    D.Kind = ArrayDesignator;
+    D.ArrayInfo.Index = Index;
+    D.ArrayInfo.LBracketLoc = LBracketLoc.getRawEncoding();
+    D.ArrayInfo.RBracketLoc = 0;
+    return D;
+  }
+
+  static Designator getArrayRange(ActionBase::ExprTy *Start,
+                                  ActionBase::ExprTy *End,
+                                  SourceLocation LBracketLoc,
+                                  SourceLocation EllipsisLoc) {
+    Designator D;
+    D.Kind = ArrayRangeDesignator;
+    D.ArrayRangeInfo.Start = Start;
+    D.ArrayRangeInfo.End = End;
+    D.ArrayRangeInfo.LBracketLoc = LBracketLoc.getRawEncoding();
+    D.ArrayRangeInfo.EllipsisLoc = EllipsisLoc.getRawEncoding();
+    D.ArrayRangeInfo.RBracketLoc = 0;
+    return D;
+  }
+
+  void setRBracketLoc(SourceLocation RBracketLoc) const {
+    assert((isArrayDesignator() || isArrayRangeDesignator()) &&
+           "Invalid accessor");
+    if (isArrayDesignator())
+      ArrayInfo.RBracketLoc = RBracketLoc.getRawEncoding();
+    else
+      ArrayRangeInfo.RBracketLoc = RBracketLoc.getRawEncoding();
+  }
+
+  /// ClearExprs - Null out any expression references, which prevents them from
+  /// being 'delete'd later.
+  void ClearExprs(Action &Actions) {
+    switch (Kind) {
+    case FieldDesignator: return;
+    case ArrayDesignator:
+      ArrayInfo.Index = 0;
+      return;
+    case ArrayRangeDesignator:
+      ArrayRangeInfo.Start = 0;
+      ArrayRangeInfo.End = 0;
+      return;
+    }
+  }
+
+  /// FreeExprs - Release any unclaimed memory for the expressions in this
+  /// designator.
+  void FreeExprs(Action &Actions) {
+    switch (Kind) {
+    case FieldDesignator: return; // nothing to free.
+    case ArrayDesignator:
+      Actions.DeleteExpr(getArrayIndex());
+      return;
+    case ArrayRangeDesignator:
+      Actions.DeleteExpr(getArrayRangeStart());
+      Actions.DeleteExpr(getArrayRangeEnd());
+      return;
+    }
+  }
+};
+
+
+/// Designation - Represent a full designation, which is a sequence of
+/// designators.  This class is mostly a helper for InitListDesignations.
+class Designation {
+  /// InitIndex - The index of the initializer expression this is for.  For
+  /// example, if the initializer were "{ A, .foo=B, C }" a Designation would
+  /// exist with InitIndex=1, because element #1 has a designation.
+  unsigned InitIndex;
+
+  /// Designators - The actual designators for this initializer.
+  llvm::SmallVector<Designator, 2> Designators;
+
+  Designation(unsigned Idx) : InitIndex(Idx) {}
+public:
+  Designation() : InitIndex(4000) {}
+
+  /// AddDesignator - Add a designator to the end of this list.
+  void AddDesignator(Designator D) {
+    Designators.push_back(D);
+  }
+
+  bool empty() const { return Designators.empty(); }
+
+  unsigned getNumDesignators() const { return Designators.size(); }
+  const Designator &getDesignator(unsigned Idx) const {
+    assert(Idx < Designators.size());
+    return Designators[Idx];
+  }
+
+  /// ClearExprs - Null out any expression references, which prevents them from
+  /// being 'delete'd later.
+  void ClearExprs(Action &Actions) {
+    for (unsigned i = 0, e = Designators.size(); i != e; ++i)
+      Designators[i].ClearExprs(Actions);
+  }
+
+  /// FreeExprs - Release any unclaimed memory for the expressions in this
+  /// designation.
+  void FreeExprs(Action &Actions) {
+    for (unsigned i = 0, e = Designators.size(); i != e; ++i)
+      Designators[i].FreeExprs(Actions);
+  }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Parse/Ownership.h b/include/clang/Parse/Ownership.h
new file mode 100644
index 0000000..5eb9635
--- /dev/null
+++ b/include/clang/Parse/Ownership.h
@@ -0,0 +1,830 @@
+//===--- Ownership.h - Parser Ownership Helpers -----------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file contains classes for managing ownership of Stmt and Expr nodes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_PARSE_OWNERSHIP_H
+#define LLVM_CLANG_PARSE_OWNERSHIP_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/PointerIntPair.h"
+
+//===----------------------------------------------------------------------===//
+// OpaquePtr
+//===----------------------------------------------------------------------===//
+
+namespace clang {
+  class ActionBase;
+
+  /// OpaquePtr - This is a very simple POD type that wraps a pointer that the
+  /// Parser doesn't know about but that Sema or another client does.  The UID
+  /// template argument is used to make sure that "Decl" pointers are not
+  /// compatible with "Type" pointers for example.
+  template<int UID>
+  class OpaquePtr {
+    void *Ptr;
+  public:
+    OpaquePtr() : Ptr(0) {}
+
+    template <typename T>
+    T* getAs() const {
+      return llvm::PointerLikeTypeTraits<T*>::getFromVoidPointer(Ptr);
+    }
+
+    template <typename T>
+    T getAsVal() const {
+      return llvm::PointerLikeTypeTraits<T>::getFromVoidPointer(Ptr);
+    }
+
+    void *get() const { return Ptr; }
+
+    template<typename T>
+    static OpaquePtr make(T P) {
+      OpaquePtr R; R.set(P); return R;
+    }
+
+    template<typename T>
+    void set(T P) {
+      Ptr = llvm::PointerLikeTypeTraits<T>::getAsVoidPointer(P);
+    }
+
+    operator bool() const { return Ptr != 0; }
+  };
+}
+
+namespace llvm {
+  template <int UID>
+  class PointerLikeTypeTraits<clang::OpaquePtr<UID> > {
+  public:
+    static inline void *getAsVoidPointer(clang::OpaquePtr<UID> P) {
+      // FIXME: Doesn't work? return P.getAs< void >();
+      return P.get();
+    }
+    static inline clang::OpaquePtr<UID> getFromVoidPointer(void *P) {
+      return clang::OpaquePtr<UID>::make(P);
+    }
+    enum { NumLowBitsAvailable = 3 };
+  };
+}
+
+
+
+// -------------------------- About Move Emulation -------------------------- //
+// The smart pointer classes in this file attempt to emulate move semantics
+// as they appear in C++0x with rvalue references. Since C++03 doesn't have
+// rvalue references, some tricks are needed to get similar results.
+// Move semantics in C++0x have the following properties:
+// 1) "Moving" means transferring the value of an object to another object,
+//    similar to copying, but without caring what happens to the old object.
+//    In particular, this means that the new object can steal the old object's
+//    resources instead of creating a copy.
+// 2) Since moving can modify the source object, it must either be explicitly
+//    requested by the user, or the modifications must be unnoticeable.
+// 3) As such, C++0x moving is only allowed in three contexts:
+//    * By explicitly using std::move() to request it.
+//    * From a temporary object, since that object cannot be accessed
+//      afterwards anyway, thus making the state unobservable.
+//    * On function return, since the object is not observable afterwards.
+//
+// To sum up: moving from a named object should only be possible with an
+// explicit std::move(), or on function return. Moving from a temporary should
+// be implicitly done. Moving from a const object is forbidden.
+//
+// The emulation is not perfect, and has the following shortcomings:
+// * move() is not in namespace std.
+// * move() is required on function return.
+// * There are difficulties with implicit conversions.
+// * Microsoft's compiler must be given the /Za switch to successfully compile.
+//
+// -------------------------- Implementation -------------------------------- //
+// The move emulation relies on the peculiar reference binding semantics of
+// C++03: as a rule, a non-const reference may not bind to a temporary object,
+// except for the implicit object parameter in a member function call, which
+// can refer to a temporary even when not being const.
+// The moveable object has five important functions to facilitate moving:
+// * A private, unimplemented constructor taking a non-const reference to its
+//   own class. This constructor serves a two-fold purpose.
+//   - It prevents the creation of a copy constructor that takes a const
+//     reference. Temporaries would be able to bind to the argument of such a
+//     constructor, and that would be bad.
+//   - Named objects will bind to the non-const reference, but since it's
+//     private, this will fail to compile. This prevents implicit moving from
+//     named objects.
+//   There's also a copy assignment operator for the same purpose.
+// * An implicit, non-const conversion operator to a special mover type. This
+//   type represents the rvalue reference of C++0x. Being a non-const member,
+//   its implicit this parameter can bind to temporaries.
+// * A constructor that takes an object of this mover type. This constructor
+//   performs the actual move operation. There is an equivalent assignment
+//   operator.
+// There is also a free move() function that takes a non-const reference to
+// an object and returns a temporary. Internally, this function uses explicit
+// constructor calls to move the value from the referenced object to the return
+// value.
+//
+// There are now three possible scenarios of use.
+// * Copying from a const object. Constructor overload resolution will find the
+//   non-const copy constructor, and the move constructor. The first is not
+//   viable because the const object cannot be bound to the non-const reference.
+//   The second fails because the conversion to the mover object is non-const.
+//   Moving from a const object fails as intended.
+// * Copying from a named object. Constructor overload resolution will select
+//   the non-const copy constructor, but fail as intended, because this
+//   constructor is private.
+// * Copying from a temporary. Constructor overload resolution cannot select
+//   the non-const copy constructor, because the temporary cannot be bound to
+//   the non-const reference. It thus selects the move constructor. The
+//   temporary can be bound to the implicit this parameter of the conversion
+//   operator, because of the special binding rule. Construction succeeds.
+//   Note that the Microsoft compiler, as an extension, allows binding
+//   temporaries against non-const references. The compiler thus selects the
+//   non-const copy constructor and fails, because the constructor is private.
+//   Passing /Za (disable extensions) disables this behaviour.
+// The free move() function is used to move from a named object.
+//
+// Note that when passing an object of a different type (the classes below
+// have OwningResult and OwningPtr, which should be mixable), you get a problem.
+// Argument passing and function return use copy initialization rules. The
+// effect of this is that, when the source object is not already of the target
+// type, the compiler will first seek a way to convert the source object to the
+// target type, and only then attempt to copy the resulting object. This means
+// that when passing an OwningResult where an OwningPtr is expected, the
+// compiler will first seek a conversion from OwningResult to OwningPtr, then
+// copy the OwningPtr. The resulting conversion sequence is:
+// OwningResult object -> ResultMover -> OwningResult argument to
+// OwningPtr(OwningResult) -> OwningPtr -> PtrMover -> final OwningPtr
+// This conversion sequence is too complex to be allowed. Thus the special
+// move_* functions, which help the compiler out with some explicit
+// conversions.
+
+// Flip this switch to measure performance impact of the smart pointers.
+//#define DISABLE_SMART_POINTERS
+
+namespace llvm {
+  template<>
+  class PointerLikeTypeTraits<clang::ActionBase*> {
+    typedef clang::ActionBase* PT;
+  public:
+    static inline void *getAsVoidPointer(PT P) { return P; }
+    static inline PT getFromVoidPointer(void *P) {
+      return static_cast<PT>(P);
+    }
+    enum { NumLowBitsAvailable = 2 };
+  };
+}
+
+namespace clang {
+  // Basic
+  class DiagnosticBuilder;
+
+  // Determines whether the low bit of the result pointer for the
+  // given UID is always zero. If so, ActionResult will use that bit
+  // for it's "invalid" flag.
+  template<unsigned UID>
+  struct IsResultPtrLowBitFree {
+    static const bool value = false;
+  };
+
+  /// ActionBase - A small part split from Action because of the horrible
+  /// definition order dependencies between Action and the smart pointers.
+  class ActionBase {
+  public:
+    /// Out-of-line virtual destructor to provide home for this class.
+    virtual ~ActionBase();
+
+    // Types - Though these don't actually enforce strong typing, they document
+    // what types are required to be identical for the actions.
+    typedef OpaquePtr<0> DeclPtrTy;
+    typedef OpaquePtr<1> DeclGroupPtrTy;
+    typedef OpaquePtr<2> TemplateTy;
+    typedef void AttrTy;
+    typedef void BaseTy;
+    typedef void MemInitTy;
+    typedef void ExprTy;
+    typedef void StmtTy;
+    typedef void TemplateParamsTy;
+    typedef void CXXScopeTy;
+    typedef void TypeTy;  // FIXME: Change TypeTy to use OpaquePtr<N>.
+
+    /// ActionResult - This structure is used while parsing/acting on
+    /// expressions, stmts, etc.  It encapsulates both the object returned by
+    /// the action, plus a sense of whether or not it is valid.
+    /// When CompressInvalid is true, the "invalid" flag will be
+    /// stored in the low bit of the Val pointer.
+    template<unsigned UID,
+             typename PtrTy = void*,
+             bool CompressInvalid = IsResultPtrLowBitFree<UID>::value>
+    class ActionResult {
+      PtrTy Val;
+      bool Invalid;
+
+    public:
+      ActionResult(bool Invalid = false) : Val(PtrTy()), Invalid(Invalid) {}
+      template<typename ActualExprTy>
+      ActionResult(ActualExprTy val) : Val(val), Invalid(false) {}
+      ActionResult(const DiagnosticBuilder &) : Val(PtrTy()), Invalid(true) {}
+
+      PtrTy get() const { return Val; }
+      void set(PtrTy V) { Val = V; }
+      bool isInvalid() const { return Invalid; }
+
+      const ActionResult &operator=(PtrTy RHS) {
+        Val = RHS;
+        Invalid = false;
+        return *this;
+      }
+    };
+
+    // This ActionResult partial specialization places the "invalid"
+    // flag into the low bit of the pointer.
+    template<unsigned UID, typename PtrTy>
+    class ActionResult<UID, PtrTy, true> {
+      // A pointer whose low bit is 1 if this result is invalid, 0
+      // otherwise.
+      uintptr_t PtrWithInvalid;
+      typedef llvm::PointerLikeTypeTraits<PtrTy> PtrTraits;
+    public:
+      ActionResult(bool Invalid = false)
+        : PtrWithInvalid(static_cast<uintptr_t>(Invalid)) { }
+
+      template<typename ActualExprTy>
+      ActionResult(ActualExprTy *val) {
+        PtrTy V(val);
+        void *VP = PtrTraits::getAsVoidPointer(V);
+        PtrWithInvalid = reinterpret_cast<uintptr_t>(VP);
+        assert((PtrWithInvalid & 0x01) == 0 && "Badly aligned pointer");
+      }
+
+      ActionResult(PtrTy V) {
+        void *VP = PtrTraits::getAsVoidPointer(V);
+        PtrWithInvalid = reinterpret_cast<uintptr_t>(VP);
+        assert((PtrWithInvalid & 0x01) == 0 && "Badly aligned pointer");
+      }
+
+      ActionResult(const DiagnosticBuilder &) : PtrWithInvalid(0x01) { }
+
+      PtrTy get() const {
+        void *VP = reinterpret_cast<void *>(PtrWithInvalid & ~0x01);
+        return PtrTraits::getFromVoidPointer(VP);
+      }
+
+      void set(PtrTy V) {
+        void *VP = PtrTraits::getAsVoidPointer(V);
+        PtrWithInvalid = reinterpret_cast<uintptr_t>(VP);
+        assert((PtrWithInvalid & 0x01) == 0 && "Badly aligned pointer");
+      }
+
+      bool isInvalid() const { return PtrWithInvalid & 0x01; }
+
+      const ActionResult &operator=(PtrTy RHS) {
+        void *VP = PtrTraits::getAsVoidPointer(RHS);
+        PtrWithInvalid = reinterpret_cast<uintptr_t>(VP);
+        assert((PtrWithInvalid & 0x01) == 0 && "Badly aligned pointer");
+        return *this;
+      }
+    };
+
+    /// Deletion callbacks - Since the parser doesn't know the concrete types of
+    /// the AST nodes being generated, it must do callbacks to delete objects
+    /// when recovering from errors. These are in ActionBase because the smart
+    /// pointers need access to them.
+    virtual void DeleteExpr(ExprTy *E) {}
+    virtual void DeleteStmt(StmtTy *S) {}
+    virtual void DeleteTemplateParams(TemplateParamsTy *P) {}
+  };
+
+  /// ASTDestroyer - The type of an AST node destruction function pointer.
+  typedef void (ActionBase::*ASTDestroyer)(void *);
+
+  /// For the transition phase: translate from an ASTDestroyer to its
+  /// ActionResult UID.
+  template <ASTDestroyer Destroyer> struct DestroyerToUID;
+  template <> struct DestroyerToUID<&ActionBase::DeleteExpr> {
+    static const unsigned UID = 0;
+  };
+  template <> struct DestroyerToUID<&ActionBase::DeleteStmt> {
+    static const unsigned UID = 1;
+  };
+  /// ASTOwningResult - A moveable smart pointer for AST nodes that also
+  /// has an extra flag to indicate an additional success status.
+  template <ASTDestroyer Destroyer> class ASTOwningResult;
+
+  /// ASTMultiPtr - A moveable smart pointer to multiple AST nodes. Only owns
+  /// the individual pointers, not the array holding them.
+  template <ASTDestroyer Destroyer> class ASTMultiPtr;
+
+#if !defined(DISABLE_SMART_POINTERS)
+  namespace moving {
+    /// Move emulation helper for ASTOwningResult. NEVER EVER use this class
+    /// directly if you don't know what you're doing.
+    template <ASTDestroyer Destroyer>
+    class ASTResultMover {
+      ASTOwningResult<Destroyer> &Moved;
+
+    public:
+      ASTResultMover(ASTOwningResult<Destroyer> &moved) : Moved(moved) {}
+
+      ASTOwningResult<Destroyer> * operator ->() { return &Moved; }
+    };
+
+    /// Move emulation helper for ASTMultiPtr. NEVER EVER use this class
+    /// directly if you don't know what you're doing.
+    template <ASTDestroyer Destroyer>
+    class ASTMultiMover {
+      ASTMultiPtr<Destroyer> &Moved;
+
+    public:
+      ASTMultiMover(ASTMultiPtr<Destroyer> &moved) : Moved(moved) {}
+
+      ASTMultiPtr<Destroyer> * operator ->() { return &Moved; }
+
+      /// Reset the moved object's internal structures.
+      void release();
+    };
+  }
+#else
+
+  /// Kept only as a type-safe wrapper for a void pointer, when smart pointers
+  /// are disabled. When they are enabled, ASTOwningResult takes over.
+  template <ASTDestroyer Destroyer>
+  class ASTOwningPtr {
+    void *Node;
+
+  public:
+    explicit ASTOwningPtr(ActionBase &) : Node(0) {}
+    ASTOwningPtr(ActionBase &, void *node) : Node(node) {}
+    // Normal copying operators are defined implicitly.
+    ASTOwningPtr(const ASTOwningResult<Destroyer> &o);
+
+    ASTOwningPtr & operator =(void *raw) {
+      Node = raw;
+      return *this;
+    }
+
+    /// Access to the raw pointer.
+    void * get() const { return Node; }
+
+    /// Release the raw pointer.
+    void * take() {
+      return Node;
+    }
+
+    /// Take outside ownership of the raw pointer and cast it down.
+    template<typename T>
+    T *takeAs() {
+      return static_cast<T*>(Node);
+    }
+
+    /// Alias for interface familiarity with unique_ptr.
+    void * release() {
+      return take();
+    }
+  };
+#endif
+
+  // Important: There are two different implementations of
+  // ASTOwningResult below, depending on whether
+  // DISABLE_SMART_POINTERS is defined. If you make changes that
+  // affect the interface, be sure to compile and test both ways!
+
+#if !defined(DISABLE_SMART_POINTERS)
+  template <ASTDestroyer Destroyer>
+  class ASTOwningResult {
+    llvm::PointerIntPair<ActionBase*, 1, bool> ActionInv;
+    void *Ptr;
+
+    friend class moving::ASTResultMover<Destroyer>;
+
+    ASTOwningResult(ASTOwningResult&); // DO NOT IMPLEMENT
+    ASTOwningResult& operator =(ASTOwningResult&); // DO NOT IMPLEMENT
+
+    void destroy() {
+      if (Ptr) {
+        assert(ActionInv.getPointer() &&
+               "Smart pointer has node but no action.");
+        (ActionInv.getPointer()->*Destroyer)(Ptr);
+        Ptr = 0;
+      }
+    }
+
+  public:
+    typedef ActionBase::ActionResult<DestroyerToUID<Destroyer>::UID> DumbResult;
+
+    explicit ASTOwningResult(ActionBase &actions, bool invalid = false)
+      : ActionInv(&actions, invalid), Ptr(0) {}
+    ASTOwningResult(ActionBase &actions, void *node)
+      : ActionInv(&actions, false), Ptr(node) {}
+    ASTOwningResult(ActionBase &actions, const DumbResult &res)
+      : ActionInv(&actions, res.isInvalid()), Ptr(res.get()) {}
+    /// Move from another owning result
+    ASTOwningResult(moving::ASTResultMover<Destroyer> mover)
+      : ActionInv(mover->ActionInv),
+        Ptr(mover->Ptr) {
+      mover->Ptr = 0;
+    }
+
+    ~ASTOwningResult() {
+      destroy();
+    }
+
+    /// Move assignment from another owning result
+    ASTOwningResult &operator=(moving::ASTResultMover<Destroyer> mover) {
+      destroy();
+      ActionInv = mover->ActionInv;
+      Ptr = mover->Ptr;
+      mover->Ptr = 0;
+      return *this;
+    }
+
+    /// Assignment from a raw pointer. Takes ownership - beware!
+    ASTOwningResult &operator=(void *raw) {
+      destroy();
+      Ptr = raw;
+      ActionInv.setInt(false);
+      return *this;
+    }
+
+    /// Assignment from an ActionResult. Takes ownership - beware!
+    ASTOwningResult &operator=(const DumbResult &res) {
+      destroy();
+      Ptr = res.get();
+      ActionInv.setInt(res.isInvalid());
+      return *this;
+    }
+
+    /// Access to the raw pointer.
+    void *get() const { return Ptr; }
+
+    bool isInvalid() const { return ActionInv.getInt(); }
+
+    /// Does this point to a usable AST node? To be usable, the node must be
+    /// valid and non-null.
+    bool isUsable() const { return !isInvalid() && get(); }
+
+    /// Take outside ownership of the raw pointer.
+    void *take() {
+      if (isInvalid())
+        return 0;
+      void *tmp = Ptr;
+      Ptr = 0;
+      return tmp;
+    }
+
+    /// Take outside ownership of the raw pointer and cast it down.
+    template<typename T>
+    T *takeAs() {
+      return static_cast<T*>(take());
+    }
+
+    /// Alias for interface familiarity with unique_ptr.
+    void *release() { return take(); }
+
+    /// Pass ownership to a classical ActionResult.
+    DumbResult result() {
+      if (isInvalid())
+        return true;
+      return take();
+    }
+
+    /// Move hook
+    operator moving::ASTResultMover<Destroyer>() {
+      return moving::ASTResultMover<Destroyer>(*this);
+    }
+  };
+#else
+  template <ASTDestroyer Destroyer>
+  class ASTOwningResult {
+  public:
+    typedef ActionBase::ActionResult<DestroyerToUID<Destroyer>::UID> DumbResult;
+
+  private:
+    DumbResult Result;
+
+  public:
+    explicit ASTOwningResult(ActionBase &actions, bool invalid = false)
+      : Result(invalid) { }
+    ASTOwningResult(ActionBase &actions, void *node) : Result(node) { }
+    ASTOwningResult(ActionBase &actions, const DumbResult &res) : Result(res) { }
+    // Normal copying semantics are defined implicitly.
+    ASTOwningResult(const ASTOwningPtr<Destroyer> &o) : Result(o.get()) { }
+
+    /// Assignment from a raw pointer. Takes ownership - beware!
+    ASTOwningResult & operator =(void *raw) {
+      Result = raw;
+      return *this;
+    }
+
+    /// Assignment from an ActionResult. Takes ownership - beware!
+    ASTOwningResult & operator =(const DumbResult &res) {
+      Result = res;
+      return *this;
+    }
+
+    /// Access to the raw pointer.
+    void * get() const { return Result.get(); }
+
+    bool isInvalid() const { return Result.isInvalid(); }
+
+    /// Does this point to a usable AST node? To be usable, the node must be
+    /// valid and non-null.
+    bool isUsable() const { return !Result.isInvalid() && get(); }
+
+    /// Take outside ownership of the raw pointer.
+    void * take() {
+      return Result.get();
+    }
+
+    /// Take outside ownership of the raw pointer and cast it down.
+    template<typename T>
+    T *takeAs() {
+      return static_cast<T*>(take());
+    }
+
+    /// Alias for interface familiarity with unique_ptr.
+    void * release() { return take(); }
+
+    /// Pass ownership to a classical ActionResult.
+    DumbResult result() { return Result; }
+  };
+#endif
+
+  template <ASTDestroyer Destroyer>
+  class ASTMultiPtr {
+#if !defined(DISABLE_SMART_POINTERS)
+    ActionBase &Actions;
+#endif
+    void **Nodes;
+    unsigned Count;
+
+#if !defined(DISABLE_SMART_POINTERS)
+    friend class moving::ASTMultiMover<Destroyer>;
+
+#if defined(_MSC_VER)
+    //  Last tested with Visual Studio 2008.
+    //  Visual C++ appears to have a bug where it does not recognise
+    //  the return value from ASTMultiMover<Destroyer>::opeator-> as
+    //  being a pointer to ASTMultiPtr.  However, the diagnostics
+    //  suggest it has the right name, simply that the pointer type
+    //  is not convertible to itself.
+    //  Either way, a classic C-style hard cast resolves any issue.
+     static ASTMultiPtr* hack(moving::ASTMultiMover<Destroyer> & source) {
+       return (ASTMultiPtr*)source.operator->();
+     }
+#endif
+
+    ASTMultiPtr(ASTMultiPtr&); // DO NOT IMPLEMENT
+    // Reference member prevents copy assignment.
+
+    void destroy() {
+      assert((Count == 0 || Nodes) && "No nodes when count is not zero.");
+      for (unsigned i = 0; i < Count; ++i) {
+        if (Nodes[i])
+          (Actions.*Destroyer)(Nodes[i]);
+      }
+    }
+#endif
+
+  public:
+#if !defined(DISABLE_SMART_POINTERS)
+    explicit ASTMultiPtr(ActionBase &actions)
+      : Actions(actions), Nodes(0), Count(0) {}
+    ASTMultiPtr(ActionBase &actions, void **nodes, unsigned count)
+      : Actions(actions), Nodes(nodes), Count(count) {}
+    /// Move constructor
+    ASTMultiPtr(moving::ASTMultiMover<Destroyer> mover)
+#if defined(_MSC_VER)
+    //  Apply the visual C++ hack supplied above.
+    //  Last tested with Visual Studio 2008.
+      : Actions(hack(mover)->Actions), Nodes(hack(mover)->Nodes), Count(hack(mover)->Count) {
+#else
+      : Actions(mover->Actions), Nodes(mover->Nodes), Count(mover->Count) {
+#endif
+      mover.release();
+    }
+#else
+    // Normal copying implicitly defined
+    explicit ASTMultiPtr(ActionBase &) : Nodes(0), Count(0) {}
+    ASTMultiPtr(ActionBase &, void **nodes, unsigned count)
+      : Nodes(nodes), Count(count) {}
+    // Fake mover in Parse/AstGuard.h needs this:
+    ASTMultiPtr(void **nodes, unsigned count) : Nodes(nodes), Count(count) {}
+#endif
+
+#if !defined(DISABLE_SMART_POINTERS)
+    /// Move assignment
+    ASTMultiPtr & operator =(moving::ASTMultiMover<Destroyer> mover) {
+      destroy();
+      Nodes = mover->Nodes;
+      Count = mover->Count;
+      mover.release();
+      return *this;
+    }
+#endif
+
+    /// Access to the raw pointers.
+    void ** get() const { return Nodes; }
+
+    /// Access to the count.
+    unsigned size() const { return Count; }
+
+    void ** release() {
+#if !defined(DISABLE_SMART_POINTERS)
+      void **tmp = Nodes;
+      Nodes = 0;
+      Count = 0;
+      return tmp;
+#else
+      return Nodes;
+#endif
+    }
+
+#if !defined(DISABLE_SMART_POINTERS)
+    /// Move hook
+    operator moving::ASTMultiMover<Destroyer>() {
+      return moving::ASTMultiMover<Destroyer>(*this);
+    }
+#endif
+  };
+
+  class ParsedTemplateArgument;
+    
+  class ASTTemplateArgsPtr {
+#if !defined(DISABLE_SMART_POINTERS)
+    ActionBase &Actions;
+#endif
+    ParsedTemplateArgument *Args;
+    mutable unsigned Count;
+
+#if !defined(DISABLE_SMART_POINTERS)
+    void destroy();
+#endif
+    
+  public:
+    ASTTemplateArgsPtr(ActionBase &actions, ParsedTemplateArgument *args,
+                       unsigned count) :
+#if !defined(DISABLE_SMART_POINTERS)
+      Actions(actions),
+#endif
+      Args(args), Count(count) { }
+
+    // FIXME: Lame, not-fully-type-safe emulation of 'move semantics'.
+    ASTTemplateArgsPtr(ASTTemplateArgsPtr &Other) :
+#if !defined(DISABLE_SMART_POINTERS)
+      Actions(Other.Actions),
+#endif
+      Args(Other.Args), Count(Other.Count) {
+#if !defined(DISABLE_SMART_POINTERS)
+      Other.Count = 0;
+#endif
+    }
+
+    // FIXME: Lame, not-fully-type-safe emulation of 'move semantics'.
+    ASTTemplateArgsPtr& operator=(ASTTemplateArgsPtr &Other)  {
+#if !defined(DISABLE_SMART_POINTERS)
+      Actions = Other.Actions;
+#endif
+      Args = Other.Args;
+      Count = Other.Count;
+#if !defined(DISABLE_SMART_POINTERS)
+      Other.Count = 0;
+#endif
+      return *this;
+    }
+
+#if !defined(DISABLE_SMART_POINTERS)
+    ~ASTTemplateArgsPtr() { destroy(); }
+#endif
+
+    ParsedTemplateArgument *getArgs() const { return Args; }
+    unsigned size() const { return Count; }
+
+    void reset(ParsedTemplateArgument *args, unsigned count) {
+#if !defined(DISABLE_SMART_POINTERS)
+      destroy();
+#endif
+      Args = args;
+      Count = count;
+    }
+
+    const ParsedTemplateArgument &operator[](unsigned Arg) const;
+
+    ParsedTemplateArgument *release() const {
+#if !defined(DISABLE_SMART_POINTERS)
+      Count = 0;
+#endif
+      return Args;
+    }
+  };
+
+  /// \brief A small vector that owns a set of AST nodes.
+  template <ASTDestroyer Destroyer, unsigned N = 8>
+  class ASTOwningVector : public llvm::SmallVector<void *, N> {
+#if !defined(DISABLE_SMART_POINTERS)
+    ActionBase &Actions;
+    bool Owned;
+#endif
+
+    ASTOwningVector(ASTOwningVector &); // do not implement
+    ASTOwningVector &operator=(ASTOwningVector &); // do not implement
+
+  public:
+    explicit ASTOwningVector(ActionBase &Actions)
+#if !defined(DISABLE_SMART_POINTERS)
+      : Actions(Actions), Owned(true)
+#endif
+    { }
+
+#if !defined(DISABLE_SMART_POINTERS)
+    ~ASTOwningVector() {
+      if (!Owned)
+        return;
+
+      for (unsigned I = 0, Last = this->size(); I != Last; ++I)
+        (Actions.*Destroyer)((*this)[I]);
+    }
+#endif
+
+    void **take() {
+#if !defined(DISABLE_SMART_POINTERS)
+      Owned = false;
+#endif
+      return &this->front();
+    }
+
+    template<typename T> T **takeAs() { return (T**)take(); }
+
+#if !defined(DISABLE_SMART_POINTERS)
+    ActionBase &getActions() const { return Actions; }
+#endif
+  };
+
+  /// A SmallVector of statements, with stack size 32 (as that is the only one
+  /// used.)
+  typedef ASTOwningVector<&ActionBase::DeleteStmt, 32> StmtVector;
+  /// A SmallVector of expressions, with stack size 12 (the maximum used.)
+  typedef ASTOwningVector<&ActionBase::DeleteExpr, 12> ExprVector;
+
+  template <ASTDestroyer Destroyer, unsigned N> inline
+  ASTMultiPtr<Destroyer> move_arg(ASTOwningVector<Destroyer, N> &vec) {
+#if !defined(DISABLE_SMART_POINTERS)
+    return ASTMultiPtr<Destroyer>(vec.getActions(), vec.take(), vec.size());
+#else
+    return ASTMultiPtr<Destroyer>(vec.take(), vec.size());
+#endif
+  }
+
+#if !defined(DISABLE_SMART_POINTERS)
+
+  // Out-of-line implementations due to definition dependencies
+
+  template <ASTDestroyer Destroyer> inline
+  void moving::ASTMultiMover<Destroyer>::release() {
+    Moved.Nodes = 0;
+    Moved.Count = 0;
+  }
+
+  // Move overloads.
+
+  template <ASTDestroyer Destroyer> inline
+  ASTOwningResult<Destroyer> move(ASTOwningResult<Destroyer> &ptr) {
+    return ASTOwningResult<Destroyer>(moving::ASTResultMover<Destroyer>(ptr));
+  }
+
+  template <ASTDestroyer Destroyer> inline
+  ASTMultiPtr<Destroyer> move(ASTMultiPtr<Destroyer> &ptr) {
+    return ASTMultiPtr<Destroyer>(moving::ASTMultiMover<Destroyer>(ptr));
+  }
+
+#else
+
+  template <ASTDestroyer Destroyer> inline
+  ASTOwningPtr<Destroyer>::ASTOwningPtr(const ASTOwningResult<Destroyer> &o)
+    : Node(o.get()) { }
+
+  // These versions are hopefully no-ops.
+  template <ASTDestroyer Destroyer> inline
+  ASTOwningResult<Destroyer>& move(ASTOwningResult<Destroyer> &ptr) {
+    return ptr;
+  }
+
+  template <ASTDestroyer Destroyer> inline
+  ASTOwningPtr<Destroyer>& move(ASTOwningPtr<Destroyer> &ptr) {
+    return ptr;
+  }
+
+  template <ASTDestroyer Destroyer> inline
+  ASTMultiPtr<Destroyer>& move(ASTMultiPtr<Destroyer> &ptr) {
+    return ptr;
+  }
+#endif
+}
+
+#endif
diff --git a/include/clang/Parse/ParseDiagnostic.h b/include/clang/Parse/ParseDiagnostic.h
new file mode 100644
index 0000000..c702e2f
--- /dev/null
+++ b/include/clang/Parse/ParseDiagnostic.h
@@ -0,0 +1,27 @@
+//===--- DiagnosticParse.h - Diagnostics for libparse -----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_DIAGNOSTICPARSE_H
+#define LLVM_CLANG_DIAGNOSTICPARSE_H
+
+#include "clang/Basic/Diagnostic.h"
+
+namespace clang {
+  namespace diag {
+    enum {
+#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE) ENUM,
+#define PARSESTART
+#include "clang/Basic/DiagnosticParseKinds.inc"
+#undef DIAG
+      NUM_BUILTIN_PARSE_DIAGNOSTICS
+    };
+  }  // end namespace diag
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h
new file mode 100644
index 0000000..42a41d6
--- /dev/null
+++ b/include/clang/Parse/Parser.h
@@ -0,0 +1,1474 @@
+//===--- Parser.h - C Language Parser ---------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the Parser interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_PARSE_PARSER_H
+#define LLVM_CLANG_PARSE_PARSER_H
+
+#include "clang/Basic/Specifiers.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Parse/Action.h"
+#include "clang/Parse/DeclSpec.h"
+#include "llvm/ADT/OwningPtr.h"
+#include <stack>
+#include <list>
+
+namespace clang {
+  class AttributeList;
+  struct CXX0XAttributeList;
+  class PragmaHandler;
+  class Scope;
+  class DiagnosticBuilder;
+  class Parser;
+  class PragmaUnusedHandler;
+  class ColonProtectionRAIIObject;
+
+/// PrettyStackTraceParserEntry - If a crash happens while the parser is active,
+/// an entry is printed for it.
+class PrettyStackTraceParserEntry : public llvm::PrettyStackTraceEntry {
+  const Parser &P;
+public:
+  PrettyStackTraceParserEntry(const Parser &p) : P(p) {}
+  virtual void print(llvm::raw_ostream &OS) const;
+};
+
+/// PrecedenceLevels - These are precedences for the binary/ternary
+/// operators in the C99 grammar.  These have been named to relate
+/// with the C99 grammar productions.  Low precedences numbers bind
+/// more weakly than high numbers.
+namespace prec {
+  enum Level {
+    Unknown         = 0,    // Not binary operator.
+    Comma           = 1,    // ,
+    Assignment      = 2,    // =, *=, /=, %=, +=, -=, <<=, >>=, &=, ^=, |=
+    Conditional     = 3,    // ?
+    LogicalOr       = 4,    // ||
+    LogicalAnd      = 5,    // &&
+    InclusiveOr     = 6,    // |
+    ExclusiveOr     = 7,    // ^
+    And             = 8,    // &
+    Equality        = 9,    // ==, !=
+    Relational      = 10,   //  >=, <=, >, <
+    Shift           = 11,   // <<, >>
+    Additive        = 12,   // -, +
+    Multiplicative  = 13,   // *, /, %
+    PointerToMember = 14    // .*, ->*
+  };
+}
+
+/// Parser - This implements a parser for the C family of languages.  After
+/// parsing units of the grammar, productions are invoked to handle whatever has
+/// been read.
+///
+class Parser {
+  friend class PragmaUnusedHandler;
+  friend class ColonProtectionRAIIObject;
+  PrettyStackTraceParserEntry CrashInfo;
+
+  Preprocessor &PP;
+
+  /// Tok - The current token we are peeking ahead.  All parsing methods assume
+  /// that this is valid.
+  Token Tok;
+
+  // PrevTokLocation - The location of the token we previously
+  // consumed. This token is used for diagnostics where we expected to
+  // see a token following another token (e.g., the ';' at the end of
+  // a statement).
+  SourceLocation PrevTokLocation;
+
+  unsigned short ParenCount, BracketCount, BraceCount;
+
+  /// Actions - These are the callbacks we invoke as we parse various constructs
+  /// in the file.  This refers to the common base class between MinimalActions
+  /// and SemaActions for those uses that don't matter.
+  Action &Actions;
+
+  Scope *CurScope;
+  Diagnostic &Diags;
+
+  /// ScopeCache - Cache scopes to reduce malloc traffic.
+  enum { ScopeCacheSize = 16 };
+  unsigned NumCachedScopes;
+  Scope *ScopeCache[ScopeCacheSize];
+
+  /// Ident_super - IdentifierInfo for "super", to support fast
+  /// comparison.
+  IdentifierInfo *Ident_super;
+  /// Ident_vector and Ident_pixel - cached IdentifierInfo's for
+  /// "vector" and "pixel" fast comparison.  Only present if
+  /// AltiVec enabled.
+  IdentifierInfo *Ident_vector;
+  IdentifierInfo *Ident_pixel;
+
+  llvm::OwningPtr<PragmaHandler> PackHandler;
+  llvm::OwningPtr<PragmaHandler> UnusedHandler;
+  llvm::OwningPtr<PragmaHandler> WeakHandler;
+
+  /// Whether the '>' token acts as an operator or not. This will be
+  /// true except when we are parsing an expression within a C++
+  /// template argument list, where the '>' closes the template
+  /// argument list.
+  bool GreaterThanIsOperator;
+  
+  /// ColonIsSacred - When this is false, we aggressively try to recover from
+  /// code like "foo : bar" as if it were a typo for "foo :: bar".  This is not
+  /// safe in case statements and a few other things.  This is managed by the
+  /// ColonProtectionRAIIObject RAII object.
+  bool ColonIsSacred;
+
+  /// The "depth" of the template parameters currently being parsed.
+  unsigned TemplateParameterDepth;
+
+public:
+  Parser(Preprocessor &PP, Action &Actions);
+  ~Parser();
+
+  const LangOptions &getLang() const { return PP.getLangOptions(); }
+  const TargetInfo &getTargetInfo() const { return PP.getTargetInfo(); }
+  Preprocessor &getPreprocessor() const { return PP; }
+  Action &getActions() const { return Actions; }
+
+  const Token &getCurToken() const { return Tok; }
+
+  // Type forwarding.  All of these are statically 'void*', but they may all be
+  // different actual classes based on the actions in place.
+  typedef Action::ExprTy ExprTy;
+  typedef Action::StmtTy StmtTy;
+  typedef Action::DeclPtrTy DeclPtrTy;
+  typedef Action::DeclGroupPtrTy DeclGroupPtrTy;
+  typedef Action::TypeTy TypeTy;
+  typedef Action::BaseTy BaseTy;
+  typedef Action::MemInitTy MemInitTy;
+  typedef Action::CXXScopeTy CXXScopeTy;
+  typedef Action::TemplateParamsTy TemplateParamsTy;
+  typedef Action::TemplateTy TemplateTy;
+
+  typedef llvm::SmallVector<TemplateParamsTy *, 4> TemplateParameterLists;
+
+  typedef Action::ExprResult        ExprResult;
+  typedef Action::StmtResult        StmtResult;
+  typedef Action::BaseResult        BaseResult;
+  typedef Action::MemInitResult     MemInitResult;
+  typedef Action::TypeResult        TypeResult;
+
+  typedef Action::OwningExprResult OwningExprResult;
+  typedef Action::OwningStmtResult OwningStmtResult;
+
+  typedef Action::ExprArg ExprArg;
+  typedef Action::MultiStmtArg MultiStmtArg;
+  typedef Action::FullExprArg FullExprArg;
+
+  /// Adorns a ExprResult with Actions to make it an OwningExprResult
+  OwningExprResult Owned(ExprResult res) {
+    return OwningExprResult(Actions, res);
+  }
+  /// Adorns a StmtResult with Actions to make it an OwningStmtResult
+  OwningStmtResult Owned(StmtResult res) {
+    return OwningStmtResult(Actions, res);
+  }
+
+  OwningExprResult ExprError() { return OwningExprResult(Actions, true); }
+  OwningStmtResult StmtError() { return OwningStmtResult(Actions, true); }
+
+  OwningExprResult ExprError(const DiagnosticBuilder &) { return ExprError(); }
+  OwningStmtResult StmtError(const DiagnosticBuilder &) { return StmtError(); }
+
+  OwningExprResult ExprEmpty() { return OwningExprResult(Actions, false); }
+
+  // Parsing methods.
+
+  /// ParseTranslationUnit - All in one method that initializes parses, and
+  /// shuts down the parser.
+  void ParseTranslationUnit();
+
+  /// Initialize - Warm up the parser.
+  ///
+  void Initialize();
+
+  /// ParseTopLevelDecl - Parse one top-level declaration. Returns true if
+  /// the EOF was encountered.
+  bool ParseTopLevelDecl(DeclGroupPtrTy &Result);
+
+  DeclGroupPtrTy RetrievePendingObjCImpDecl();
+
+private:
+  //===--------------------------------------------------------------------===//
+  // Low-Level token peeking and consumption methods.
+  //
+
+  /// isTokenParen - Return true if the cur token is '(' or ')'.
+  bool isTokenParen() const {
+    return Tok.getKind() == tok::l_paren || Tok.getKind() == tok::r_paren;
+  }
+  /// isTokenBracket - Return true if the cur token is '[' or ']'.
+  bool isTokenBracket() const {
+    return Tok.getKind() == tok::l_square || Tok.getKind() == tok::r_square;
+  }
+  /// isTokenBrace - Return true if the cur token is '{' or '}'.
+  bool isTokenBrace() const {
+    return Tok.getKind() == tok::l_brace || Tok.getKind() == tok::r_brace;
+  }
+
+  /// isTokenStringLiteral - True if this token is a string-literal.
+  ///
+  bool isTokenStringLiteral() const {
+    return Tok.getKind() == tok::string_literal ||
+           Tok.getKind() == tok::wide_string_literal;
+  }
+
+  /// ConsumeToken - Consume the current 'peek token' and lex the next one.
+  /// This does not work with all kinds of tokens: strings and specific other
+  /// tokens must be consumed with custom methods below.  This returns the
+  /// location of the consumed token.
+  SourceLocation ConsumeToken() {
+    assert(!isTokenStringLiteral() && !isTokenParen() && !isTokenBracket() &&
+           !isTokenBrace() &&
+           "Should consume special tokens with Consume*Token");
+    PrevTokLocation = Tok.getLocation();
+    PP.Lex(Tok);
+    return PrevTokLocation;
+  }
+
+  /// ConsumeAnyToken - Dispatch to the right Consume* method based on the
+  /// current token type.  This should only be used in cases where the type of
+  /// the token really isn't known, e.g. in error recovery.
+  SourceLocation ConsumeAnyToken() {
+    if (isTokenParen())
+      return ConsumeParen();
+    else if (isTokenBracket())
+      return ConsumeBracket();
+    else if (isTokenBrace())
+      return ConsumeBrace();
+    else if (isTokenStringLiteral())
+      return ConsumeStringToken();
+    else
+      return ConsumeToken();
+  }
+
+  /// ConsumeParen - This consume method keeps the paren count up-to-date.
+  ///
+  SourceLocation ConsumeParen() {
+    assert(isTokenParen() && "wrong consume method");
+    if (Tok.getKind() == tok::l_paren)
+      ++ParenCount;
+    else if (ParenCount)
+      --ParenCount;       // Don't let unbalanced )'s drive the count negative.
+    PrevTokLocation = Tok.getLocation();
+    PP.Lex(Tok);
+    return PrevTokLocation;
+  }
+
+  /// ConsumeBracket - This consume method keeps the bracket count up-to-date.
+  ///
+  SourceLocation ConsumeBracket() {
+    assert(isTokenBracket() && "wrong consume method");
+    if (Tok.getKind() == tok::l_square)
+      ++BracketCount;
+    else if (BracketCount)
+      --BracketCount;     // Don't let unbalanced ]'s drive the count negative.
+
+    PrevTokLocation = Tok.getLocation();
+    PP.Lex(Tok);
+    return PrevTokLocation;
+  }
+
+  /// ConsumeBrace - This consume method keeps the brace count up-to-date.
+  ///
+  SourceLocation ConsumeBrace() {
+    assert(isTokenBrace() && "wrong consume method");
+    if (Tok.getKind() == tok::l_brace)
+      ++BraceCount;
+    else if (BraceCount)
+      --BraceCount;     // Don't let unbalanced }'s drive the count negative.
+
+    PrevTokLocation = Tok.getLocation();
+    PP.Lex(Tok);
+    return PrevTokLocation;
+  }
+
+  /// ConsumeStringToken - Consume the current 'peek token', lexing a new one
+  /// and returning the token kind.  This method is specific to strings, as it
+  /// handles string literal concatenation, as per C99 5.1.1.2, translation
+  /// phase #6.
+  SourceLocation ConsumeStringToken() {
+    assert(isTokenStringLiteral() &&
+           "Should only consume string literals with this method");
+    PrevTokLocation = Tok.getLocation();
+    PP.Lex(Tok);
+    return PrevTokLocation;
+  }
+
+  /// GetLookAheadToken - This peeks ahead N tokens and returns that token
+  /// without consuming any tokens.  LookAhead(0) returns 'Tok', LookAhead(1)
+  /// returns the token after Tok, etc.
+  ///
+  /// Note that this differs from the Preprocessor's LookAhead method, because
+  /// the Parser always has one token lexed that the preprocessor doesn't.
+  ///
+  const Token &GetLookAheadToken(unsigned N) {
+    if (N == 0 || Tok.is(tok::eof)) return Tok;
+    return PP.LookAhead(N-1);
+  }
+
+  /// NextToken - This peeks ahead one token and returns it without
+  /// consuming it.
+  const Token &NextToken() {
+    return PP.LookAhead(0);
+  }
+
+  /// TryAnnotateTypeOrScopeToken - If the current token position is on a
+  /// typename (possibly qualified in C++) or a C++ scope specifier not followed
+  /// by a typename, TryAnnotateTypeOrScopeToken will replace one or more tokens
+  /// with a single annotation token representing the typename or C++ scope
+  /// respectively.
+  /// This simplifies handling of C++ scope specifiers and allows efficient
+  /// backtracking without the need to re-parse and resolve nested-names and
+  /// typenames.
+  /// It will mainly be called when we expect to treat identifiers as typenames
+  /// (if they are typenames). For example, in C we do not expect identifiers
+  /// inside expressions to be treated as typenames so it will not be called
+  /// for expressions in C.
+  ///
+  /// This returns true if the token was annotated.
+  bool TryAnnotateTypeOrScopeToken(bool EnteringContext = false);
+
+  /// TryAnnotateCXXScopeToken - Like TryAnnotateTypeOrScopeToken but
+  /// only annotates C++ scope specifiers.  This returns true if there
+  /// was an unrecoverable error.
+  bool TryAnnotateCXXScopeToken(bool EnteringContext = false);
+
+  /// TryAltiVecToken - Check for context-sensitive AltiVec identifier tokens,
+  /// replacing them with the non-context-sensitive keywords.  This returns
+  /// true if the token was replaced.
+  bool TryAltiVecToken(DeclSpec &DS, SourceLocation Loc,
+                       const char *&PrevSpec, unsigned &DiagID,
+                       bool &isInvalid) {
+    if (!getLang().AltiVec ||
+        (Tok.getIdentifierInfo() != Ident_vector &&
+         Tok.getIdentifierInfo() != Ident_pixel))
+      return false;
+    
+    return TryAltiVecTokenOutOfLine(DS, Loc, PrevSpec, DiagID, isInvalid);
+  }
+
+  /// TryAltiVecVectorToken - Check for context-sensitive AltiVec vector
+  /// identifier token, replacing it with the non-context-sensitive __vector.
+  /// This returns true if the token was replaced.
+  bool TryAltiVecVectorToken() {
+    if (!getLang().AltiVec ||
+        Tok.getIdentifierInfo() != Ident_vector) return false;
+    return TryAltiVecVectorTokenOutOfLine();
+  }
+  
+  bool TryAltiVecVectorTokenOutOfLine();
+  bool TryAltiVecTokenOutOfLine(DeclSpec &DS, SourceLocation Loc,
+                                const char *&PrevSpec, unsigned &DiagID,
+                                bool &isInvalid);
+    
+  /// TentativeParsingAction - An object that is used as a kind of "tentative
+  /// parsing transaction". It gets instantiated to mark the token position and
+  /// after the token consumption is done, Commit() or Revert() is called to
+  /// either "commit the consumed tokens" or revert to the previously marked
+  /// token position. Example:
+  ///
+  ///   TentativeParsingAction TPA(*this);
+  ///   ConsumeToken();
+  ///   ....
+  ///   TPA.Revert();
+  ///
+  class TentativeParsingAction {
+    Parser &P;
+    Token PrevTok;
+    bool isActive;
+
+  public:
+    explicit TentativeParsingAction(Parser& p) : P(p) {
+      PrevTok = P.Tok;
+      P.PP.EnableBacktrackAtThisPos();
+      isActive = true;
+    }
+    void Commit() {
+      assert(isActive && "Parsing action was finished!");
+      P.PP.CommitBacktrackedTokens();
+      isActive = false;
+    }
+    void Revert() {
+      assert(isActive && "Parsing action was finished!");
+      P.PP.Backtrack();
+      P.Tok = PrevTok;
+      isActive = false;
+    }
+    ~TentativeParsingAction() {
+      assert(!isActive && "Forgot to call Commit or Revert!");
+    }
+  };
+
+
+  /// MatchRHSPunctuation - For punctuation with a LHS and RHS (e.g. '['/']'),
+  /// this helper function matches and consumes the specified RHS token if
+  /// present.  If not present, it emits the specified diagnostic indicating
+  /// that the parser failed to match the RHS of the token at LHSLoc.  LHSName
+  /// should be the name of the unmatched LHS token.  This returns the location
+  /// of the consumed token.
+  SourceLocation MatchRHSPunctuation(tok::TokenKind RHSTok,
+                                     SourceLocation LHSLoc);
+
+  /// ExpectAndConsume - The parser expects that 'ExpectedTok' is next in the
+  /// input.  If so, it is consumed and false is returned.
+  ///
+  /// If the input is malformed, this emits the specified diagnostic.  Next, if
+  /// SkipToTok is specified, it calls SkipUntil(SkipToTok).  Finally, true is
+  /// returned.
+  bool ExpectAndConsume(tok::TokenKind ExpectedTok, unsigned Diag,
+                        const char *DiagMsg = "",
+                        tok::TokenKind SkipToTok = tok::unknown);
+
+  //===--------------------------------------------------------------------===//
+  // Scope manipulation
+
+  /// ParseScope - Introduces a new scope for parsing. The kind of
+  /// scope is determined by ScopeFlags. Objects of this type should
+  /// be created on the stack to coincide with the position where the
+  /// parser enters the new scope, and this object's constructor will
+  /// create that new scope. Similarly, once the object is destroyed
+  /// the parser will exit the scope.
+  class ParseScope {
+    Parser *Self;
+    ParseScope(const ParseScope&); // do not implement
+    ParseScope& operator=(const ParseScope&); // do not implement
+
+  public:
+    // ParseScope - Construct a new object to manage a scope in the
+    // parser Self where the new Scope is created with the flags
+    // ScopeFlags, but only when ManageScope is true (the default). If
+    // ManageScope is false, this object does nothing.
+    ParseScope(Parser *Self, unsigned ScopeFlags, bool ManageScope = true)
+      : Self(Self) {
+      if (ManageScope)
+        Self->EnterScope(ScopeFlags);
+      else
+        this->Self = 0;
+    }
+
+    // Exit - Exit the scope associated with this object now, rather
+    // than waiting until the object is destroyed.
+    void Exit() {
+      if (Self) {
+        Self->ExitScope();
+        Self = 0;
+      }
+    }
+
+    ~ParseScope() {
+      Exit();
+    }
+  };
+
+  /// EnterScope - Start a new scope.
+  void EnterScope(unsigned ScopeFlags);
+
+  /// ExitScope - Pop a scope off the scope stack.
+  void ExitScope();
+
+  //===--------------------------------------------------------------------===//
+  // Diagnostic Emission and Error recovery.
+
+public:
+  DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID);
+  DiagnosticBuilder Diag(const Token &Tok, unsigned DiagID);
+
+private:
+  void SuggestParentheses(SourceLocation Loc, unsigned DK,
+                          SourceRange ParenRange);
+
+  /// SkipUntil - Read tokens until we get to the specified token, then consume
+  /// it (unless DontConsume is true).  Because we cannot guarantee that the
+  /// token will ever occur, this skips to the next token, or to some likely
+  /// good stopping point.  If StopAtSemi is true, skipping will stop at a ';'
+  /// character.
+  ///
+  /// If SkipUntil finds the specified token, it returns true, otherwise it
+  /// returns false.
+  bool SkipUntil(tok::TokenKind T, bool StopAtSemi = true,
+                 bool DontConsume = false) {
+    return SkipUntil(&T, 1, StopAtSemi, DontConsume);
+  }
+  bool SkipUntil(tok::TokenKind T1, tok::TokenKind T2, bool StopAtSemi = true,
+                 bool DontConsume = false) {
+    tok::TokenKind TokArray[] = {T1, T2};
+    return SkipUntil(TokArray, 2, StopAtSemi, DontConsume);
+  }
+  bool SkipUntil(const tok::TokenKind *Toks, unsigned NumToks,
+                 bool StopAtSemi = true, bool DontConsume = false);
+
+  //===--------------------------------------------------------------------===//
+  // Lexing and parsing of C++ inline methods.
+
+  struct LexedMethod {
+    Action::DeclPtrTy D;
+    CachedTokens Toks;
+
+    /// \brief Whether this member function had an associated template
+    /// scope. When true, D is a template declaration.
+    /// othewise, it is a member function declaration.
+    bool TemplateScope;
+
+    explicit LexedMethod(Action::DeclPtrTy MD) : D(MD), TemplateScope(false) {}
+  };
+
+  /// LateParsedDefaultArgument - Keeps track of a parameter that may
+  /// have a default argument that cannot be parsed yet because it
+  /// occurs within a member function declaration inside the class
+  /// (C++ [class.mem]p2).
+  struct LateParsedDefaultArgument {
+    explicit LateParsedDefaultArgument(Action::DeclPtrTy P,
+                                       CachedTokens *Toks = 0)
+      : Param(P), Toks(Toks) { }
+
+    /// Param - The parameter declaration for this parameter.
+    Action::DeclPtrTy Param;
+
+    /// Toks - The sequence of tokens that comprises the default
+    /// argument expression, not including the '=' or the terminating
+    /// ')' or ','. This will be NULL for parameters that have no
+    /// default argument.
+    CachedTokens *Toks;
+  };
+
+  /// LateParsedMethodDeclaration - A method declaration inside a class that
+  /// contains at least one entity whose parsing needs to be delayed
+  /// until the class itself is completely-defined, such as a default
+  /// argument (C++ [class.mem]p2).
+  struct LateParsedMethodDeclaration {
+    explicit LateParsedMethodDeclaration(Action::DeclPtrTy M)
+      : Method(M), TemplateScope(false) { }
+
+    /// Method - The method declaration.
+    Action::DeclPtrTy Method;
+
+    /// \brief Whether this member function had an associated template
+    /// scope. When true, D is a template declaration.
+    /// othewise, it is a member function declaration.
+    bool TemplateScope;
+
+    /// DefaultArgs - Contains the parameters of the function and
+    /// their default arguments. At least one of the parameters will
+    /// have a default argument, but all of the parameters of the
+    /// method will be stored so that they can be reintroduced into
+    /// scope at the appropriate times.
+    llvm::SmallVector<LateParsedDefaultArgument, 8> DefaultArgs;
+  };
+
+  /// LateParsedMethodDecls - During parsing of a top (non-nested) C++
+  /// class, its method declarations that contain parts that won't be
+  /// parsed until after the definiton is completed (C++ [class.mem]p2),
+  /// the method declarations will be stored here with the tokens that
+  /// will be parsed to create those entities.
+  typedef std::list<LateParsedMethodDeclaration> LateParsedMethodDecls;
+
+  /// LexedMethodsForTopClass - During parsing of a top (non-nested) C++ class,
+  /// its inline method definitions and the inline method definitions of its
+  /// nested classes are lexed and stored here.
+  typedef std::list<LexedMethod> LexedMethodsForTopClass;
+
+  /// \brief Representation of a class that has been parsed, including
+  /// any member function declarations or definitions that need to be
+  /// parsed after the corresponding top-level class is complete.
+  struct ParsingClass {
+    ParsingClass(DeclPtrTy TagOrTemplate, bool TopLevelClass)
+      : TopLevelClass(TopLevelClass), TemplateScope(false),
+        TagOrTemplate(TagOrTemplate) { }
+
+    /// \brief Whether this is a "top-level" class, meaning that it is
+    /// not nested within another class.
+    bool TopLevelClass : 1;
+
+    /// \brief Whether this class had an associated template
+    /// scope. When true, TagOrTemplate is a template declaration;
+    /// othewise, it is a tag declaration.
+    bool TemplateScope : 1;
+
+    /// \brief The class or class template whose definition we are parsing.
+    DeclPtrTy TagOrTemplate;
+
+    /// MethodDecls - Method declarations that contain pieces whose
+    /// parsing will be delayed until the class is fully defined.
+    LateParsedMethodDecls MethodDecls;
+
+    /// MethodDefs - Methods whose definitions will be parsed once the
+    /// class has been fully defined.
+    LexedMethodsForTopClass MethodDefs;
+
+    /// \brief Nested classes inside this class.
+    llvm::SmallVector<ParsingClass*, 4> NestedClasses;
+  };
+
+  /// \brief The stack of classes that is currently being
+  /// parsed. Nested and local classes will be pushed onto this stack
+  /// when they are parsed, and removed afterward.
+  std::stack<ParsingClass *> ClassStack;
+
+  ParsingClass &getCurrentClass() {
+    assert(!ClassStack.empty() && "No lexed method stacks!");
+    return *ClassStack.top();
+  }
+
+  /// \brief RAII object used to inform the actions that we're
+  /// currently parsing a declaration.  This is active when parsing a
+  /// variable's initializer, but not when parsing the body of a
+  /// class or function definition.
+  class ParsingDeclRAIIObject {
+    Action &Actions;
+    Action::ParsingDeclStackState State;
+    bool Popped;
+    
+  public:
+    ParsingDeclRAIIObject(Parser &P) : Actions(P.Actions) {
+      push();
+    }
+
+    ~ParsingDeclRAIIObject() {
+      abort();
+    }
+
+    /// Resets the RAII object for a new declaration.
+    void reset() {
+      abort();
+      push();
+    }
+
+    /// Signals that the context was completed without an appropriate
+    /// declaration being parsed.
+    void abort() {
+      pop(DeclPtrTy());
+    }
+
+    void complete(DeclPtrTy D) {
+      assert(!Popped && "ParsingDeclaration has already been popped!");
+      pop(D);
+    }
+
+  private:
+    void push() {
+      State = Actions.PushParsingDeclaration();
+      Popped = false;
+    }
+
+    void pop(DeclPtrTy D) {
+      if (!Popped) {
+        Actions.PopParsingDeclaration(State, D);
+        Popped = true;
+      }
+    }
+  };
+
+  /// A class for parsing a DeclSpec.
+  class ParsingDeclSpec : public DeclSpec {
+    ParsingDeclRAIIObject ParsingRAII;
+
+  public:
+    ParsingDeclSpec(Parser &P) : ParsingRAII(P) {
+    }
+
+    void complete(DeclPtrTy D) {
+      ParsingRAII.complete(D);
+    }
+
+    void abort() {
+      ParsingRAII.abort();
+    }
+  };
+
+  /// A class for parsing a declarator.
+  class ParsingDeclarator : public Declarator {
+    ParsingDeclRAIIObject ParsingRAII;
+
+  public:
+    ParsingDeclarator(Parser &P, const ParsingDeclSpec &DS, TheContext C)
+      : Declarator(DS, C), ParsingRAII(P) {
+    }
+
+    const ParsingDeclSpec &getDeclSpec() const {
+      return static_cast<const ParsingDeclSpec&>(Declarator::getDeclSpec());
+    }
+
+    ParsingDeclSpec &getMutableDeclSpec() const {
+      return const_cast<ParsingDeclSpec&>(getDeclSpec());
+    }
+
+    void clear() {
+      Declarator::clear();
+      ParsingRAII.reset();
+    }
+
+    void complete(DeclPtrTy D) {
+      ParsingRAII.complete(D);
+    }
+  };
+
+  /// \brief RAII object used to
+  class ParsingClassDefinition {
+    Parser &P;
+    bool Popped;
+
+  public:
+    ParsingClassDefinition(Parser &P, DeclPtrTy TagOrTemplate, bool TopLevelClass)
+      : P(P), Popped(false) {
+      P.PushParsingClass(TagOrTemplate, TopLevelClass);
+    }
+
+    /// \brief Pop this class of the stack.
+    void Pop() {
+      assert(!Popped && "Nested class has already been popped");
+      Popped = true;
+      P.PopParsingClass();
+    }
+
+    ~ParsingClassDefinition() {
+      if (!Popped)
+        P.PopParsingClass();
+    }
+  };
+
+  /// \brief Contains information about any template-specific
+  /// information that has been parsed prior to parsing declaration
+  /// specifiers.
+  struct ParsedTemplateInfo {
+    ParsedTemplateInfo()
+      : Kind(NonTemplate), TemplateParams(0), TemplateLoc() { }
+
+    ParsedTemplateInfo(TemplateParameterLists *TemplateParams,
+                       bool isSpecialization,
+                       bool lastParameterListWasEmpty = false)
+      : Kind(isSpecialization? ExplicitSpecialization : Template),
+        TemplateParams(TemplateParams), 
+        LastParameterListWasEmpty(lastParameterListWasEmpty) { }
+
+    explicit ParsedTemplateInfo(SourceLocation ExternLoc,
+                                SourceLocation TemplateLoc)
+      : Kind(ExplicitInstantiation), TemplateParams(0),
+        ExternLoc(ExternLoc), TemplateLoc(TemplateLoc),
+        LastParameterListWasEmpty(false){ }
+
+    /// \brief The kind of template we are parsing.
+    enum {
+      /// \brief We are not parsing a template at all.
+      NonTemplate = 0,
+      /// \brief We are parsing a template declaration.
+      Template,
+      /// \brief We are parsing an explicit specialization.
+      ExplicitSpecialization,
+      /// \brief We are parsing an explicit instantiation.
+      ExplicitInstantiation
+    } Kind;
+
+    /// \brief The template parameter lists, for template declarations
+    /// and explicit specializations.
+    TemplateParameterLists *TemplateParams;
+
+    /// \brief The location of the 'extern' keyword, if any, for an explicit
+    /// instantiation
+    SourceLocation ExternLoc;
+
+    /// \brief The location of the 'template' keyword, for an explicit
+    /// instantiation.
+    SourceLocation TemplateLoc;
+    
+    /// \brief Whether the last template parameter list was empty.
+    bool LastParameterListWasEmpty;
+  };
+
+  void PushParsingClass(DeclPtrTy TagOrTemplate, bool TopLevelClass);
+  void DeallocateParsedClasses(ParsingClass *Class);
+  void PopParsingClass();
+
+  DeclPtrTy ParseCXXInlineMethodDef(AccessSpecifier AS, Declarator &D,
+                                    const ParsedTemplateInfo &TemplateInfo);
+  void ParseLexedMethodDeclarations(ParsingClass &Class);
+  void ParseLexedMethodDefs(ParsingClass &Class);
+  bool ConsumeAndStoreUntil(tok::TokenKind T1,
+                            CachedTokens &Toks,
+                            bool StopAtSemi = true,
+                            bool ConsumeFinalToken = true) {
+    return ConsumeAndStoreUntil(T1, T1, Toks, StopAtSemi, ConsumeFinalToken);
+  }
+  bool ConsumeAndStoreUntil(tok::TokenKind T1, tok::TokenKind T2,
+                            CachedTokens &Toks,
+                            bool StopAtSemi = true,
+                            bool ConsumeFinalToken = true);
+
+  //===--------------------------------------------------------------------===//
+  // C99 6.9: External Definitions.
+  DeclGroupPtrTy ParseExternalDeclaration(CXX0XAttributeList Attr);
+  bool isDeclarationAfterDeclarator();
+  bool isStartOfFunctionDefinition();
+  DeclGroupPtrTy ParseDeclarationOrFunctionDefinition(AttributeList *Attr,
+            AccessSpecifier AS = AS_none);
+  DeclGroupPtrTy ParseDeclarationOrFunctionDefinition(ParsingDeclSpec &DS,
+                                                  AttributeList *Attr,
+                                                  AccessSpecifier AS = AS_none);
+  
+  DeclPtrTy ParseFunctionDefinition(ParsingDeclarator &D,
+                 const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo());
+  void ParseKNRParamDeclarations(Declarator &D);
+  // EndLoc, if non-NULL, is filled with the location of the last token of
+  // the simple-asm.
+  OwningExprResult ParseSimpleAsm(SourceLocation *EndLoc = 0);
+  OwningExprResult ParseAsmStringLiteral();
+
+  // Objective-C External Declarations
+  DeclPtrTy ParseObjCAtDirectives();
+  DeclPtrTy ParseObjCAtClassDeclaration(SourceLocation atLoc);
+  DeclPtrTy ParseObjCAtInterfaceDeclaration(SourceLocation atLoc,
+                                          AttributeList *prefixAttrs = 0);
+  void ParseObjCClassInstanceVariables(DeclPtrTy interfaceDecl,
+                                       tok::ObjCKeywordKind visibility,
+                                       SourceLocation atLoc);
+  bool ParseObjCProtocolReferences(llvm::SmallVectorImpl<Action::DeclPtrTy> &P,
+                                   llvm::SmallVectorImpl<SourceLocation> &PLocs,
+                                   bool WarnOnDeclarations,
+                                   SourceLocation &LAngleLoc,
+                                   SourceLocation &EndProtoLoc);
+  void ParseObjCInterfaceDeclList(DeclPtrTy interfaceDecl,
+                                  tok::ObjCKeywordKind contextKey);
+  DeclPtrTy ParseObjCAtProtocolDeclaration(SourceLocation atLoc,
+                                           AttributeList *prefixAttrs = 0);
+
+  DeclPtrTy ObjCImpDecl;
+  llvm::SmallVector<DeclPtrTy, 4> PendingObjCImpDecl;
+
+  DeclPtrTy ParseObjCAtImplementationDeclaration(SourceLocation atLoc);
+  DeclPtrTy ParseObjCAtEndDeclaration(SourceRange atEnd);
+  DeclPtrTy ParseObjCAtAliasDeclaration(SourceLocation atLoc);
+  DeclPtrTy ParseObjCPropertySynthesize(SourceLocation atLoc);
+  DeclPtrTy ParseObjCPropertyDynamic(SourceLocation atLoc);
+
+  IdentifierInfo *ParseObjCSelectorPiece(SourceLocation &MethodLocation);
+  // Definitions for Objective-c context sensitive keywords recognition.
+  enum ObjCTypeQual {
+    objc_in=0, objc_out, objc_inout, objc_oneway, objc_bycopy, objc_byref,
+    objc_NumQuals
+  };
+  IdentifierInfo *ObjCTypeQuals[objc_NumQuals];
+
+  bool isTokIdentifier_in() const;
+
+  TypeTy *ParseObjCTypeName(ObjCDeclSpec &DS);
+  void ParseObjCMethodRequirement();
+  DeclPtrTy ParseObjCMethodPrototype(DeclPtrTy classOrCat,
+            tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword);
+  DeclPtrTy ParseObjCMethodDecl(SourceLocation mLoc, tok::TokenKind mType,
+                                DeclPtrTy classDecl,
+            tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword);
+  void ParseObjCPropertyAttribute(ObjCDeclSpec &DS, DeclPtrTy ClassDecl,
+                                  DeclPtrTy *Methods, unsigned NumMethods);
+
+  DeclPtrTy ParseObjCMethodDefinition();
+
+  //===--------------------------------------------------------------------===//
+  // C99 6.5: Expressions.
+  
+  OwningExprResult ParseExpression();
+  OwningExprResult ParseConstantExpression();
+  // Expr that doesn't include commas.
+  OwningExprResult ParseAssignmentExpression();
+
+  OwningExprResult ParseExpressionWithLeadingAt(SourceLocation AtLoc);
+
+  OwningExprResult ParseExpressionWithLeadingExtension(SourceLocation ExtLoc);
+
+  OwningExprResult ParseRHSOfBinaryExpression(OwningExprResult LHS,
+                                              prec::Level MinPrec);
+  OwningExprResult ParseCastExpression(bool isUnaryExpression,
+                                       bool isAddressOfOperand,
+                                       bool &NotCastExpr,
+                                       TypeTy *TypeOfCast);
+  OwningExprResult ParseCastExpression(bool isUnaryExpression,
+                                       bool isAddressOfOperand = false,
+                                       TypeTy *TypeOfCast = 0);
+  OwningExprResult ParsePostfixExpressionSuffix(OwningExprResult LHS);
+  OwningExprResult ParseSizeofAlignofExpression();
+  OwningExprResult ParseBuiltinPrimaryExpression();
+
+  OwningExprResult ParseExprAfterTypeofSizeofAlignof(const Token &OpTok,
+                                                     bool &isCastExpr,
+                                                     TypeTy *&CastTy,
+                                                     SourceRange &CastRange);
+
+  static const unsigned ExprListSize = 12;
+  typedef llvm::SmallVector<ExprTy*, ExprListSize> ExprListTy;
+  typedef llvm::SmallVector<SourceLocation, ExprListSize> CommaLocsTy;
+
+  /// ParseExpressionList - Used for C/C++ (argument-)expression-list.
+  bool ParseExpressionList(ExprListTy &Exprs, CommaLocsTy &CommaLocs,
+                           void (Action::*Completer)(Scope *S, void *Data,
+                                                     ExprTy **Args,
+                                                     unsigned NumArgs) = 0,
+                           void *Data = 0);
+
+  /// ParenParseOption - Control what ParseParenExpression will parse.
+  enum ParenParseOption {
+    SimpleExpr,      // Only parse '(' expression ')'
+    CompoundStmt,    // Also allow '(' compound-statement ')'
+    CompoundLiteral, // Also allow '(' type-name ')' '{' ... '}'
+    CastExpr         // Also allow '(' type-name ')' <anything>
+  };
+  OwningExprResult ParseParenExpression(ParenParseOption &ExprType,
+                                        bool stopIfCastExpr,
+                                        TypeTy *TypeOfCast,
+                                        TypeTy *&CastTy,
+                                        SourceLocation &RParenLoc);
+
+  OwningExprResult ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType,
+                                                    TypeTy *&CastTy,
+                                                    SourceLocation LParenLoc,
+                                                    SourceLocation &RParenLoc);
+
+  OwningExprResult ParseCompoundLiteralExpression(TypeTy *Ty,
+                                                  SourceLocation LParenLoc,
+                                                  SourceLocation RParenLoc);
+
+  OwningExprResult ParseStringLiteralExpression();
+
+  //===--------------------------------------------------------------------===//
+  // C++ Expressions
+  OwningExprResult ParseCXXIdExpression(bool isAddressOfOperand = false);
+
+  bool ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS,
+                                      TypeTy *ObjectType,
+                                      bool EnteringContext,
+                                      bool *MayBePseudoDestructor = 0);
+
+  //===--------------------------------------------------------------------===//
+  // C++ 5.2p1: C++ Casts
+  OwningExprResult ParseCXXCasts();
+
+  //===--------------------------------------------------------------------===//
+  // C++ 5.2p1: C++ Type Identification
+  OwningExprResult ParseCXXTypeid();
+
+  //===--------------------------------------------------------------------===//
+  // C++ 5.2.4: C++ Pseudo-Destructor Expressions
+  OwningExprResult ParseCXXPseudoDestructor(ExprArg Base, SourceLocation OpLoc,
+                                            tok::TokenKind OpKind,
+                                            CXXScopeSpec &SS,
+                                            Action::TypeTy *ObjectType);
+
+  //===--------------------------------------------------------------------===//
+  // C++ 9.3.2: C++ 'this' pointer
+  OwningExprResult ParseCXXThis();
+
+  //===--------------------------------------------------------------------===//
+  // C++ 15: C++ Throw Expression
+  OwningExprResult ParseThrowExpression();
+  // EndLoc is filled with the location of the last token of the specification.
+  bool ParseExceptionSpecification(SourceLocation &EndLoc,
+                                   llvm::SmallVector<TypeTy*, 2> &Exceptions,
+                                   llvm::SmallVector<SourceRange, 2> &Ranges,
+                                   bool &hasAnyExceptionSpec);
+
+  //===--------------------------------------------------------------------===//
+  // C++ 2.13.5: C++ Boolean Literals
+  OwningExprResult ParseCXXBoolLiteral();
+
+  //===--------------------------------------------------------------------===//
+  // C++ 5.2.3: Explicit type conversion (functional notation)
+  OwningExprResult ParseCXXTypeConstructExpression(const DeclSpec &DS);
+
+  bool isCXXSimpleTypeSpecifier() const;
+
+  /// ParseCXXSimpleTypeSpecifier - [C++ 7.1.5.2] Simple type specifiers.
+  /// This should only be called when the current token is known to be part of
+  /// simple-type-specifier.
+  void ParseCXXSimpleTypeSpecifier(DeclSpec &DS);
+
+  bool ParseCXXTypeSpecifierSeq(DeclSpec &DS);
+
+  //===--------------------------------------------------------------------===//
+  // C++ 5.3.4 and 5.3.5: C++ new and delete
+  bool ParseExpressionListOrTypeId(ExprListTy &Exprs, Declarator &D);
+  void ParseDirectNewDeclarator(Declarator &D);
+  OwningExprResult ParseCXXNewExpression(bool UseGlobal, SourceLocation Start);
+  OwningExprResult ParseCXXDeleteExpression(bool UseGlobal,
+                                            SourceLocation Start);
+
+  //===--------------------------------------------------------------------===//
+  // C++ if/switch/while condition expression.
+  bool ParseCXXCondition(OwningExprResult &ExprResult, DeclPtrTy &DeclResult);
+
+  //===--------------------------------------------------------------------===//
+  // C++ types
+
+  //===--------------------------------------------------------------------===//
+  // C99 6.7.8: Initialization.
+
+  /// ParseInitializer
+  ///       initializer: [C99 6.7.8]
+  ///         assignment-expression
+  ///         '{' ...
+  OwningExprResult ParseInitializer() {
+    if (Tok.isNot(tok::l_brace))
+      return ParseAssignmentExpression();
+    return ParseBraceInitializer();
+  }
+  OwningExprResult ParseBraceInitializer();
+  OwningExprResult ParseInitializerWithPotentialDesignator();
+
+  //===--------------------------------------------------------------------===//
+  // clang Expressions
+
+  OwningExprResult ParseBlockLiteralExpression();  // ^{...}
+
+  //===--------------------------------------------------------------------===//
+  // Objective-C Expressions
+  OwningExprResult ParseObjCAtExpression(SourceLocation AtLocation);
+  OwningExprResult ParseObjCStringLiteral(SourceLocation AtLoc);
+  OwningExprResult ParseObjCEncodeExpression(SourceLocation AtLoc);
+  OwningExprResult ParseObjCSelectorExpression(SourceLocation AtLoc);
+  OwningExprResult ParseObjCProtocolExpression(SourceLocation AtLoc);
+  OwningExprResult ParseObjCMessageExpression();
+  OwningExprResult ParseObjCMessageExpressionBody(SourceLocation LBracloc,
+                                                  SourceLocation SuperLoc,
+                                                  TypeTy *ReceiverType,
+                                                  ExprArg ReceiverExpr);
+  OwningExprResult ParseAssignmentExprWithObjCMessageExprStart(
+      SourceLocation LBracloc, SourceLocation SuperLoc,
+      TypeTy *ReceiverType, ExprArg ReceiverExpr);
+  bool ParseObjCXXMessageReceiver(bool &IsExpr, void *&TypeOrExpr);
+
+  //===--------------------------------------------------------------------===//
+  // C99 6.8: Statements and Blocks.
+
+  OwningStmtResult ParseStatement() {
+    return ParseStatementOrDeclaration(true);
+  }
+  OwningStmtResult ParseStatementOrDeclaration(bool OnlyStatement = false);
+  OwningStmtResult ParseLabeledStatement(AttributeList *Attr);
+  OwningStmtResult ParseCaseStatement(AttributeList *Attr);
+  OwningStmtResult ParseDefaultStatement(AttributeList *Attr);
+  OwningStmtResult ParseCompoundStatement(AttributeList *Attr,
+                                          bool isStmtExpr = false);
+  OwningStmtResult ParseCompoundStatementBody(bool isStmtExpr = false);
+  bool ParseParenExprOrCondition(OwningExprResult &ExprResult,
+                                 DeclPtrTy &DeclResult);
+  OwningStmtResult ParseIfStatement(AttributeList *Attr);
+  OwningStmtResult ParseSwitchStatement(AttributeList *Attr);
+  OwningStmtResult ParseWhileStatement(AttributeList *Attr);
+  OwningStmtResult ParseDoStatement(AttributeList *Attr);
+  OwningStmtResult ParseForStatement(AttributeList *Attr);
+  OwningStmtResult ParseGotoStatement(AttributeList *Attr);
+  OwningStmtResult ParseContinueStatement(AttributeList *Attr);
+  OwningStmtResult ParseBreakStatement(AttributeList *Attr);
+  OwningStmtResult ParseReturnStatement(AttributeList *Attr);
+  OwningStmtResult ParseAsmStatement(bool &msAsm);
+  OwningStmtResult FuzzyParseMicrosoftAsmStatement();
+  bool ParseAsmOperandsOpt(llvm::SmallVectorImpl<IdentifierInfo *> &Names,
+                           llvm::SmallVectorImpl<ExprTy *> &Constraints,
+                           llvm::SmallVectorImpl<ExprTy *> &Exprs);
+
+  //===--------------------------------------------------------------------===//
+  // C++ 6: Statements and Blocks
+
+  OwningStmtResult ParseCXXTryBlock(AttributeList *Attr);
+  OwningStmtResult ParseCXXTryBlockCommon(SourceLocation TryLoc);
+  OwningStmtResult ParseCXXCatchBlock();
+
+  //===--------------------------------------------------------------------===//
+  // Objective-C Statements
+
+  OwningStmtResult ParseObjCAtStatement(SourceLocation atLoc);
+  OwningStmtResult ParseObjCTryStmt(SourceLocation atLoc);
+  OwningStmtResult ParseObjCThrowStmt(SourceLocation atLoc);
+  OwningStmtResult ParseObjCSynchronizedStmt(SourceLocation atLoc);
+
+
+  //===--------------------------------------------------------------------===//
+  // C99 6.7: Declarations.
+
+  /// A context for parsing declaration specifiers.  TODO: flesh this
+  /// out, there are other significant restrictions on specifiers than
+  /// would be best implemented in the parser.
+  enum DeclSpecContext {
+    DSC_normal, // normal context
+    DSC_class,  // class context, enables 'friend'
+    DSC_top_level // top-level/namespace declaration context
+  };
+
+  DeclGroupPtrTy ParseDeclaration(unsigned Context, SourceLocation &DeclEnd,
+                                  CXX0XAttributeList Attr);
+  DeclGroupPtrTy ParseSimpleDeclaration(unsigned Context,
+                                        SourceLocation &DeclEnd,
+                                        AttributeList *Attr,
+                                        bool RequireSemi);
+  DeclGroupPtrTy ParseDeclGroup(ParsingDeclSpec &DS, unsigned Context,
+                                bool AllowFunctionDefinitions,
+                                SourceLocation *DeclEnd = 0);
+  DeclPtrTy ParseDeclarationAfterDeclarator(Declarator &D,
+               const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo());
+  DeclPtrTy ParseFunctionStatementBody(DeclPtrTy Decl);
+  DeclPtrTy ParseFunctionTryBlock(DeclPtrTy Decl);
+
+  bool ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS,
+                        const ParsedTemplateInfo &TemplateInfo,
+                        AccessSpecifier AS);
+  DeclSpecContext getDeclSpecContextFromDeclaratorContext(unsigned Context);
+  void ParseDeclarationSpecifiers(DeclSpec &DS,
+                const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(),
+                                  AccessSpecifier AS = AS_none,
+                                  DeclSpecContext DSC = DSC_normal);
+  bool ParseOptionalTypeSpecifier(DeclSpec &DS, bool &isInvalid,
+                                  const char *&PrevSpec,
+                                  unsigned &DiagID,
+               const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(),
+                                  bool SuppressDeclarations = false);
+
+  void ParseSpecifierQualifierList(DeclSpec &DS);
+
+  void ParseObjCTypeQualifierList(ObjCDeclSpec &DS);
+
+  void ParseEnumSpecifier(SourceLocation TagLoc, DeclSpec &DS,
+                const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(),                          AccessSpecifier AS = AS_none);
+  void ParseEnumBody(SourceLocation StartLoc, DeclPtrTy TagDecl);
+  void ParseStructUnionBody(SourceLocation StartLoc, unsigned TagType,
+                            DeclPtrTy TagDecl);
+
+  struct FieldCallback {
+    virtual DeclPtrTy invoke(FieldDeclarator &Field) = 0;
+    virtual ~FieldCallback() {}
+
+  private:
+    virtual void _anchor();
+  };
+  struct ObjCPropertyCallback;
+
+  void ParseStructDeclaration(DeclSpec &DS, FieldCallback &Callback);
+
+  bool isDeclarationSpecifier();
+  bool isTypeSpecifierQualifier();
+  bool isTypeQualifier() const;
+  
+  /// isKnownToBeTypeSpecifier - Return true if we know that the specified token
+  /// is definitely a type-specifier.  Return false if it isn't part of a type
+  /// specifier or if we're not sure.
+  bool isKnownToBeTypeSpecifier(const Token &Tok) const;
+
+  /// isDeclarationStatement - Disambiguates between a declaration or an
+  /// expression statement, when parsing function bodies.
+  /// Returns true for declaration, false for expression.
+  bool isDeclarationStatement() {
+    if (getLang().CPlusPlus)
+      return isCXXDeclarationStatement();
+    return isDeclarationSpecifier();
+  }
+
+  /// isSimpleDeclaration - Disambiguates between a declaration or an
+  /// expression, mainly used for the C 'clause-1' or the C++
+  // 'for-init-statement' part of a 'for' statement.
+  /// Returns true for declaration, false for expression.
+  bool isSimpleDeclaration() {
+    if (getLang().CPlusPlus)
+      return isCXXSimpleDeclaration();
+    return isDeclarationSpecifier();
+  }
+
+  /// \brief Starting with a scope specifier, identifier, or
+  /// template-id that refers to the current class, determine whether
+  /// this is a constructor declarator.
+  bool isConstructorDeclarator();
+
+  /// \brief Specifies the context in which type-id/expression
+  /// disambiguation will occur.
+  enum TentativeCXXTypeIdContext {
+    TypeIdInParens,
+    TypeIdAsTemplateArgument
+  };
+
+
+  /// isTypeIdInParens - Assumes that a '(' was parsed and now we want to know
+  /// whether the parens contain an expression or a type-id.
+  /// Returns true for a type-id and false for an expression.
+  bool isTypeIdInParens(bool &isAmbiguous) {
+    if (getLang().CPlusPlus)
+      return isCXXTypeId(TypeIdInParens, isAmbiguous);
+    isAmbiguous = false;
+    return isTypeSpecifierQualifier();
+  }
+  bool isTypeIdInParens() {
+    bool isAmbiguous;
+    return isTypeIdInParens(isAmbiguous);
+  }
+
+  /// isCXXDeclarationStatement - C++-specialized function that disambiguates
+  /// between a declaration or an expression statement, when parsing function
+  /// bodies. Returns true for declaration, false for expression.
+  bool isCXXDeclarationStatement();
+
+  /// isCXXSimpleDeclaration - C++-specialized function that disambiguates
+  /// between a simple-declaration or an expression-statement.
+  /// If during the disambiguation process a parsing error is encountered,
+  /// the function returns true to let the declaration parsing code handle it.
+  /// Returns false if the statement is disambiguated as expression.
+  bool isCXXSimpleDeclaration();
+
+  /// isCXXFunctionDeclarator - Disambiguates between a function declarator or
+  /// a constructor-style initializer, when parsing declaration statements.
+  /// Returns true for function declarator and false for constructor-style
+  /// initializer. If 'warnIfAmbiguous' is true a warning will be emitted to
+  /// indicate that the parens were disambiguated as function declarator.
+  /// If during the disambiguation process a parsing error is encountered,
+  /// the function returns true to let the declaration parsing code handle it.
+  bool isCXXFunctionDeclarator(bool warnIfAmbiguous);
+
+  /// isCXXConditionDeclaration - Disambiguates between a declaration or an
+  /// expression for a condition of a if/switch/while/for statement.
+  /// If during the disambiguation process a parsing error is encountered,
+  /// the function returns true to let the declaration parsing code handle it.
+  bool isCXXConditionDeclaration();
+
+  bool isCXXTypeId(TentativeCXXTypeIdContext Context, bool &isAmbiguous);
+  bool isCXXTypeId(TentativeCXXTypeIdContext Context) {
+    bool isAmbiguous;
+    return isCXXTypeId(Context, isAmbiguous);
+  }
+
+  /// TPResult - Used as the result value for functions whose purpose is to
+  /// disambiguate C++ constructs by "tentatively parsing" them.
+  /// This is a class instead of a simple enum because the implicit enum-to-bool
+  /// conversions may cause subtle bugs.
+  class TPResult {
+    enum Result {
+      TPR_true,
+      TPR_false,
+      TPR_ambiguous,
+      TPR_error
+    };
+    Result Res;
+    TPResult(Result result) : Res(result) {}
+  public:
+    static TPResult True() { return TPR_true; }
+    static TPResult False() { return TPR_false; }
+    static TPResult Ambiguous() { return TPR_ambiguous; }
+    static TPResult Error() { return TPR_error; }
+
+    bool operator==(const TPResult &RHS) const { return Res == RHS.Res; }
+    bool operator!=(const TPResult &RHS) const { return Res != RHS.Res; }
+  };
+
+  /// isCXXDeclarationSpecifier - Returns TPResult::True() if it is a
+  /// declaration specifier, TPResult::False() if it is not,
+  /// TPResult::Ambiguous() if it could be either a decl-specifier or a
+  /// function-style cast, and TPResult::Error() if a parsing error was
+  /// encountered.
+  /// Doesn't consume tokens.
+  TPResult isCXXDeclarationSpecifier();
+
+  // "Tentative parsing" functions, used for disambiguation. If a parsing error
+  // is encountered they will return TPResult::Error().
+  // Returning TPResult::True()/False() indicates that the ambiguity was
+  // resolved and tentative parsing may stop. TPResult::Ambiguous() indicates
+  // that more tentative parsing is necessary for disambiguation.
+  // They all consume tokens, so backtracking should be used after calling them.
+
+  TPResult TryParseDeclarationSpecifier();
+  TPResult TryParseSimpleDeclaration();
+  TPResult TryParseTypeofSpecifier();
+  TPResult TryParseInitDeclaratorList();
+  TPResult TryParseDeclarator(bool mayBeAbstract, bool mayHaveIdentifier=true);
+  TPResult TryParseParameterDeclarationClause();
+  TPResult TryParseFunctionDeclarator();
+  TPResult TryParseBracketDeclarator();
+
+  TypeResult ParseTypeName(SourceRange *Range = 0);
+  void ParseBlockId();
+  // EndLoc, if non-NULL, is filled with the location of the last token of
+  // the attribute list.
+  CXX0XAttributeList ParseCXX0XAttributes(SourceLocation *EndLoc = 0);
+  AttributeList *ParseGNUAttributes(SourceLocation *EndLoc = 0);
+  AttributeList *ParseMicrosoftDeclSpec(AttributeList* CurrAttr = 0);
+  AttributeList *ParseMicrosoftTypeAttributes(AttributeList* CurrAttr = 0);
+  void ParseTypeofSpecifier(DeclSpec &DS);
+  void ParseDecltypeSpecifier(DeclSpec &DS);
+  
+  OwningExprResult ParseCXX0XAlignArgument(SourceLocation Start);
+
+  /// DeclaratorScopeObj - RAII object used in Parser::ParseDirectDeclarator to
+  /// enter a new C++ declarator scope and exit it when the function is
+  /// finished.
+  class DeclaratorScopeObj {
+    Parser &P;
+    CXXScopeSpec &SS;
+    bool EnteredScope;
+    bool CreatedScope;
+  public:
+    DeclaratorScopeObj(Parser &p, CXXScopeSpec &ss)
+      : P(p), SS(ss), EnteredScope(false), CreatedScope(false) {}
+
+    void EnterDeclaratorScope() {
+      assert(!EnteredScope && "Already entered the scope!");
+      assert(SS.isSet() && "C++ scope was not set!");
+
+      CreatedScope = true;
+      P.EnterScope(0); // Not a decl scope.
+
+      if (!P.Actions.ActOnCXXEnterDeclaratorScope(P.CurScope, SS))
+        EnteredScope = true;
+    }
+
+    ~DeclaratorScopeObj() {
+      if (EnteredScope) {
+        assert(SS.isSet() && "C++ scope was cleared ?");
+        P.Actions.ActOnCXXExitDeclaratorScope(P.CurScope, SS);
+      }
+      if (CreatedScope)
+        P.ExitScope();
+    }
+  };
+
+  /// ParseDeclarator - Parse and verify a newly-initialized declarator.
+  void ParseDeclarator(Declarator &D);
+  /// A function that parses a variant of direct-declarator.
+  typedef void (Parser::*DirectDeclParseFunction)(Declarator&);
+  void ParseDeclaratorInternal(Declarator &D,
+                               DirectDeclParseFunction DirectDeclParser);
+  void ParseTypeQualifierListOpt(DeclSpec &DS, bool GNUAttributesAllowed = true,
+                                 bool CXX0XAttributesAllowed = true);
+  void ParseDirectDeclarator(Declarator &D);
+  void ParseParenDeclarator(Declarator &D);
+  void ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
+                               AttributeList *AttrList = 0,
+                               bool RequiresArg = false);
+  void ParseFunctionDeclaratorIdentifierList(SourceLocation LParenLoc,
+                                             Declarator &D);
+  void ParseBracketDeclarator(Declarator &D);
+
+  //===--------------------------------------------------------------------===//
+  // C++ 7: Declarations [dcl.dcl]
+
+  bool isCXX0XAttributeSpecifier(bool FullLookahead = false, 
+                                 tok::TokenKind *After = 0);
+  
+  DeclPtrTy ParseNamespace(unsigned Context, SourceLocation &DeclEnd);
+  DeclPtrTy ParseLinkage(ParsingDeclSpec &DS, unsigned Context);
+  DeclPtrTy ParseUsingDirectiveOrDeclaration(unsigned Context,
+                                             SourceLocation &DeclEnd,
+                                             CXX0XAttributeList Attrs);
+  DeclPtrTy ParseUsingDirective(unsigned Context, SourceLocation UsingLoc,
+                                SourceLocation &DeclEnd,
+                                AttributeList *Attr);
+  DeclPtrTy ParseUsingDeclaration(unsigned Context, SourceLocation UsingLoc,
+                                  SourceLocation &DeclEnd,
+                                  AccessSpecifier AS = AS_none);
+  DeclPtrTy ParseStaticAssertDeclaration(SourceLocation &DeclEnd);
+  DeclPtrTy ParseNamespaceAlias(SourceLocation NamespaceLoc,
+                                SourceLocation AliasLoc, IdentifierInfo *Alias,
+                                SourceLocation &DeclEnd);
+
+  //===--------------------------------------------------------------------===//
+  // C++ 9: classes [class] and C structs/unions.
+  TypeResult ParseClassName(SourceLocation &EndLocation,
+                            CXXScopeSpec *SS = 0);
+  void ParseClassSpecifier(tok::TokenKind TagTokKind, SourceLocation TagLoc,
+                           DeclSpec &DS,
+                const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(),
+                           AccessSpecifier AS = AS_none,
+                           bool SuppressDeclarations = false);
+  void ParseCXXMemberSpecification(SourceLocation StartLoc, unsigned TagType,
+                                   DeclPtrTy TagDecl);
+  void ParseCXXClassMemberDeclaration(AccessSpecifier AS,
+                const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo());
+  void ParseConstructorInitializer(DeclPtrTy ConstructorDecl);
+  MemInitResult ParseMemInitializer(DeclPtrTy ConstructorDecl);
+  void HandleMemberFunctionDefaultArgs(Declarator& DeclaratorInfo,
+                                       DeclPtrTy ThisDecl);
+
+  //===--------------------------------------------------------------------===//
+  // C++ 10: Derived classes [class.derived]
+  void ParseBaseClause(DeclPtrTy ClassDecl);
+  BaseResult ParseBaseSpecifier(DeclPtrTy ClassDecl);
+  AccessSpecifier getAccessSpecifierIfPresent() const;
+
+  bool ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS, 
+                                    IdentifierInfo *Name,
+                                    SourceLocation NameLoc,
+                                    bool EnteringContext,
+                                    TypeTy *ObjectType,
+                                    UnqualifiedId &Id,
+                                    bool AssumeTemplateId = false);
+  bool ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext,
+                                  TypeTy *ObjectType,
+                                  UnqualifiedId &Result);
+  bool ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext,
+                          bool AllowDestructorName,
+                          bool AllowConstructorName,
+                          TypeTy *ObjectType,
+                          UnqualifiedId &Result);
+    
+  //===--------------------------------------------------------------------===//
+  // C++ 14: Templates [temp]
+  typedef llvm::SmallVector<DeclPtrTy, 4> TemplateParameterList;
+
+  // C++ 14.1: Template Parameters [temp.param]
+  DeclPtrTy ParseDeclarationStartingWithTemplate(unsigned Context,
+                                                 SourceLocation &DeclEnd,
+                                                 AccessSpecifier AS = AS_none);
+  DeclPtrTy ParseTemplateDeclarationOrSpecialization(unsigned Context,
+                                                     SourceLocation &DeclEnd,
+                                                     AccessSpecifier AS);
+  DeclPtrTy ParseSingleDeclarationAfterTemplate(
+                                       unsigned Context,
+                                       const ParsedTemplateInfo &TemplateInfo,
+                                       SourceLocation &DeclEnd,
+                                       AccessSpecifier AS=AS_none);
+  bool ParseTemplateParameters(unsigned Depth,
+                               TemplateParameterList &TemplateParams,
+                               SourceLocation &LAngleLoc,
+                               SourceLocation &RAngleLoc);
+  bool ParseTemplateParameterList(unsigned Depth,
+                                  TemplateParameterList &TemplateParams);
+  bool isStartOfTemplateTypeParameter();
+  DeclPtrTy ParseTemplateParameter(unsigned Depth, unsigned Position);
+  DeclPtrTy ParseTypeParameter(unsigned Depth, unsigned Position);
+  DeclPtrTy ParseTemplateTemplateParameter(unsigned Depth, unsigned Position);
+  DeclPtrTy ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position);
+  // C++ 14.3: Template arguments [temp.arg]
+  typedef llvm::SmallVector<ParsedTemplateArgument, 16> TemplateArgList;
+
+  bool ParseTemplateIdAfterTemplateName(TemplateTy Template,
+                                        SourceLocation TemplateNameLoc,
+                                        const CXXScopeSpec *SS,
+                                        bool ConsumeLastToken,
+                                        SourceLocation &LAngleLoc,
+                                        TemplateArgList &TemplateArgs,
+                                        SourceLocation &RAngleLoc);
+
+  bool AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK,
+                               const CXXScopeSpec *SS,
+                               UnqualifiedId &TemplateName,
+                               SourceLocation TemplateKWLoc = SourceLocation(),
+                               bool AllowTypeAnnotation = true);
+  void AnnotateTemplateIdTokenAsType(const CXXScopeSpec *SS = 0);
+  bool ParseTemplateArgumentList(TemplateArgList &TemplateArgs);
+  ParsedTemplateArgument ParseTemplateTemplateArgument();
+  ParsedTemplateArgument ParseTemplateArgument();
+  DeclPtrTy ParseExplicitInstantiation(SourceLocation ExternLoc,
+                                       SourceLocation TemplateLoc,
+                                       SourceLocation &DeclEnd);
+
+  //===--------------------------------------------------------------------===//
+  // GNU G++: Type Traits [Type-Traits.html in the GCC manual]
+  OwningExprResult ParseUnaryTypeTrait();
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Parse/Scope.h b/include/clang/Parse/Scope.h
new file mode 100644
index 0000000..d7a0e35
--- /dev/null
+++ b/include/clang/Parse/Scope.h
@@ -0,0 +1,329 @@
+//===--- Scope.h - Scope interface ------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the Scope interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_PARSE_SCOPE_H
+#define LLVM_CLANG_PARSE_SCOPE_H
+
+#include "clang/Parse/Action.h"
+#include "llvm/ADT/SmallPtrSet.h"
+
+namespace clang {
+
+/// Scope - A scope is a transient data structure that is used while parsing the
+/// program.  It assists with resolving identifiers to the appropriate
+/// declaration.
+///
+class Scope {
+public:
+  /// ScopeFlags - These are bitfields that are or'd together when creating a
+  /// scope, which defines the sorts of things the scope contains.
+  enum ScopeFlags {
+    /// FnScope - This indicates that the scope corresponds to a function, which
+    /// means that labels are set here.
+    FnScope       = 0x01,
+
+    /// BreakScope - This is a while,do,switch,for, etc that can have break
+    /// stmts embedded into it.
+    BreakScope    = 0x02,
+
+    /// ContinueScope - This is a while,do,for, which can have continue
+    /// stmt embedded into it.
+    ContinueScope = 0x04,
+
+    /// DeclScope - This is a scope that can contain a declaration.  Some scopes
+    /// just contain loop constructs but don't contain decls.
+    DeclScope = 0x08,
+
+    /// ControlScope - The controlling scope in a if/switch/while/for statement.
+    ControlScope = 0x10,
+
+    /// ClassScope - The scope of a struct/union/class definition.
+    ClassScope = 0x20,
+
+    /// BlockScope - This is a scope that corresponds to a block object.
+    /// Blocks serve as top-level scopes for some objects like labels, they
+    /// also prevent things like break and continue.  BlockScopes always have
+    /// the FnScope, BreakScope, ContinueScope, and DeclScope flags set as well.
+    BlockScope = 0x40,
+
+    /// TemplateParamScope - This is a scope that corresponds to the
+    /// template parameters of a C++ template. Template parameter
+    /// scope starts at the 'template' keyword and ends when the
+    /// template declaration ends.
+    TemplateParamScope = 0x80,
+
+    /// FunctionPrototypeScope - This is a scope that corresponds to the
+    /// parameters within a function prototype.
+    FunctionPrototypeScope = 0x100,
+
+    /// AtCatchScope - This is a scope that corresponds to the Objective-C
+    /// @catch statement.
+    AtCatchScope = 0x200,
+    
+    /// ObjCMethodScope - This scope corresponds to an Objective-C method body.
+    /// It always has FnScope and DeclScope set as well.
+    ObjCMethodScope = 0x400,
+    
+    /// ElseScope - This scoep corresponds to an 'else' scope of an if/then/else
+    /// statement.
+    ElseScope = 0x800
+  };
+private:
+  /// The parent scope for this scope.  This is null for the translation-unit
+  /// scope.
+  Scope *AnyParent;
+
+  /// Depth - This is the depth of this scope.  The translation-unit scope has
+  /// depth 0.
+  unsigned short Depth;
+
+  /// Flags - This contains a set of ScopeFlags, which indicates how the scope
+  /// interrelates with other control flow statements.
+  unsigned short Flags;
+
+  /// FnParent - If this scope has a parent scope that is a function body, this
+  /// pointer is non-null and points to it.  This is used for label processing.
+  Scope *FnParent;
+
+  /// BreakParent/ContinueParent - This is a direct link to the immediately
+  /// preceeding BreakParent/ContinueParent if this scope is not one, or null if
+  /// there is no containing break/continue scope.
+  Scope *BreakParent, *ContinueParent;
+
+  /// ControlParent - This is a direct link to the immediately
+  /// preceeding ControlParent if this scope is not one, or null if
+  /// there is no containing control scope.
+  Scope *ControlParent;
+
+  /// BlockParent - This is a direct link to the immediately containing
+  /// BlockScope if this scope is not one, or null if there is none.
+  Scope *BlockParent;
+
+  /// TemplateParamParent - This is a direct link to the
+  /// immediately containing template parameter scope. In the
+  /// case of nested templates, template parameter scopes can have
+  /// other template parameter scopes as parents.
+  Scope *TemplateParamParent;
+
+  /// DeclsInScope - This keeps track of all declarations in this scope.  When
+  /// the declaration is added to the scope, it is set as the current
+  /// declaration for the identifier in the IdentifierTable.  When the scope is
+  /// popped, these declarations are removed from the IdentifierTable's notion
+  /// of current declaration.  It is up to the current Action implementation to
+  /// implement these semantics.
+  typedef llvm::SmallPtrSet<Action::DeclPtrTy, 32> DeclSetTy;
+  DeclSetTy DeclsInScope;
+
+  /// Entity - The entity with which this scope is associated. For
+  /// example, the entity of a class scope is the class itself, the
+  /// entity of a function scope is a function, etc. This field is
+  /// maintained by the Action implementation.
+  void *Entity;
+
+  typedef llvm::SmallVector<Action::DeclPtrTy, 2> UsingDirectivesTy;
+  UsingDirectivesTy UsingDirectives;
+
+  /// \brief The number of errors at the start of the given scope.
+  unsigned NumErrorsAtStart;
+  
+public:
+  Scope(Scope *Parent, unsigned ScopeFlags) {
+    Init(Parent, ScopeFlags);
+  }
+
+  /// getFlags - Return the flags for this scope.
+  ///
+  unsigned getFlags() const { return Flags; }
+  void setFlags(unsigned F) { Flags = F; }
+
+  /// isBlockScope - Return true if this scope does not correspond to a
+  /// closure.
+  bool isBlockScope() const { return Flags & BlockScope; }
+
+  /// getParent - Return the scope that this is nested in.
+  ///
+  const Scope *getParent() const { return AnyParent; }
+  Scope *getParent() { return AnyParent; }
+
+  /// getFnParent - Return the closest scope that is a function body.
+  ///
+  const Scope *getFnParent() const { return FnParent; }
+  Scope *getFnParent() { return FnParent; }
+
+  /// getContinueParent - Return the closest scope that a continue statement
+  /// would be affected by.  If the closest scope is a closure scope, we know
+  /// that there is no loop *inside* the closure.
+  Scope *getContinueParent() {
+    if (ContinueParent && !ContinueParent->isBlockScope())
+      return ContinueParent;
+    return 0;
+  }
+
+  const Scope *getContinueParent() const {
+    return const_cast<Scope*>(this)->getContinueParent();
+  }
+
+  /// getBreakParent - Return the closest scope that a break statement
+  /// would be affected by.  If the closest scope is a block scope, we know
+  /// that there is no loop *inside* the block.
+  Scope *getBreakParent() {
+    if (BreakParent && !BreakParent->isBlockScope())
+      return BreakParent;
+    return 0;
+  }
+  const Scope *getBreakParent() const {
+    return const_cast<Scope*>(this)->getBreakParent();
+  }
+
+  Scope *getControlParent() { return ControlParent; }
+  const Scope *getControlParent() const { return ControlParent; }
+
+  Scope *getBlockParent() { return BlockParent; }
+  const Scope *getBlockParent() const { return BlockParent; }
+
+  Scope *getTemplateParamParent() { return TemplateParamParent; }
+  const Scope *getTemplateParamParent() const { return TemplateParamParent; }
+
+  typedef DeclSetTy::iterator decl_iterator;
+  decl_iterator decl_begin() const { return DeclsInScope.begin(); }
+  decl_iterator decl_end()   const { return DeclsInScope.end(); }
+  bool decl_empty()          const { return DeclsInScope.empty(); }
+
+  void AddDecl(Action::DeclPtrTy D) {
+    DeclsInScope.insert(D);
+  }
+
+  void RemoveDecl(Action::DeclPtrTy D) {
+    DeclsInScope.erase(D);
+  }
+
+  /// isDeclScope - Return true if this is the scope that the specified decl is
+  /// declared in.
+  bool isDeclScope(Action::DeclPtrTy D) {
+    return DeclsInScope.count(D) != 0;
+  }
+
+  void* getEntity() const { return Entity; }
+  void setEntity(void *E) { Entity = E; }
+
+  /// \brief Retrieve the number of errors that had been emitted when we
+  /// entered this scope.
+  unsigned getNumErrorsAtStart() const { return NumErrorsAtStart; }
+  
+  void setNumErrorsAtStart(unsigned NumErrors) {
+    NumErrorsAtStart = NumErrors;
+  }
+                           
+  /// isClassScope - Return true if this scope is a class/struct/union scope.
+  bool isClassScope() const {
+    return (getFlags() & Scope::ClassScope);
+  }
+
+  /// isInCXXInlineMethodScope - Return true if this scope is a C++ inline
+  /// method scope or is inside one.
+  bool isInCXXInlineMethodScope() const {
+    if (const Scope *FnS = getFnParent()) {
+      assert(FnS->getParent() && "TUScope not created?");
+      return FnS->getParent()->isClassScope();
+    }
+    return false;
+  }
+  
+  /// isInObjcMethodScope - Return true if this scope is, or is contained in, an
+  /// Objective-C method body.  Note that this method is not constant time.
+  bool isInObjcMethodScope() const {
+    for (const Scope *S = this; S; S = S->getParent()) {
+      // If this scope is an objc method scope, then we succeed.
+      if (S->getFlags() & ObjCMethodScope)
+        return true;
+    }
+    return false;
+  }
+
+  /// isTemplateParamScope - Return true if this scope is a C++
+  /// template parameter scope.
+  bool isTemplateParamScope() const {
+    return getFlags() & Scope::TemplateParamScope;
+  }
+
+  /// isFunctionPrototypeScope - Return true if this scope is a
+  /// function prototype scope.
+  bool isFunctionPrototypeScope() const {
+    return getFlags() & Scope::FunctionPrototypeScope;
+  }
+
+  /// isAtCatchScope - Return true if this scope is @catch.
+  bool isAtCatchScope() const {
+    return getFlags() & Scope::AtCatchScope;
+  }
+
+  typedef UsingDirectivesTy::iterator udir_iterator;
+  typedef UsingDirectivesTy::const_iterator const_udir_iterator;
+
+  void PushUsingDirective(Action::DeclPtrTy UDir) {
+    UsingDirectives.push_back(UDir);
+  }
+
+  udir_iterator using_directives_begin() {
+    return UsingDirectives.begin();
+  }
+
+  udir_iterator using_directives_end() {
+    return UsingDirectives.end();
+  }
+
+  const_udir_iterator using_directives_begin() const {
+    return UsingDirectives.begin();
+  }
+
+  const_udir_iterator using_directives_end() const {
+    return UsingDirectives.end();
+  }
+
+  /// Init - This is used by the parser to implement scope caching.
+  ///
+  void Init(Scope *Parent, unsigned ScopeFlags) {
+    AnyParent = Parent;
+    Depth = AnyParent ? AnyParent->Depth+1 : 0;
+    Flags = ScopeFlags;
+    
+    if (AnyParent) {
+      FnParent       = AnyParent->FnParent;
+      BreakParent    = AnyParent->BreakParent;
+      ContinueParent = AnyParent->ContinueParent;
+      ControlParent = AnyParent->ControlParent;
+      BlockParent  = AnyParent->BlockParent;
+      TemplateParamParent = AnyParent->TemplateParamParent;
+    } else {
+      FnParent = BreakParent = ContinueParent = BlockParent = 0;
+      ControlParent = 0;
+      TemplateParamParent = 0;
+    }
+
+    // If this scope is a function or contains breaks/continues, remember it.
+    if (Flags & FnScope)            FnParent = this;
+    if (Flags & BreakScope)         BreakParent = this;
+    if (Flags & ContinueScope)      ContinueParent = this;
+    if (Flags & ControlScope)       ControlParent = this;
+    if (Flags & BlockScope)         BlockParent = this;
+    if (Flags & TemplateParamScope) TemplateParamParent = this;
+    DeclsInScope.clear();
+    UsingDirectives.clear();
+    Entity = 0;
+    NumErrorsAtStart = 0;
+  }
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Parse/Template.h b/include/clang/Parse/Template.h
new file mode 100644
index 0000000..1f8ccfb
--- /dev/null
+++ b/include/clang/Parse/Template.h
@@ -0,0 +1,183 @@
+//===--- Template.h - Template Parsing Data Types -------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file provides data structures that store the parsed representation of
+//  templates.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_PARSE_TEMPLATE_H
+#define LLVM_CLANG_PARSE_TEMPLATE_H
+
+#include "clang/Parse/DeclSpec.h"
+#include "clang/Parse/Ownership.h"
+#include <cassert>
+
+namespace clang {  
+  /// \brief Represents the parsed form of a C++ template argument.
+  class ParsedTemplateArgument {
+  public:
+    /// \brief Describes the kind of template argument that was parsed.
+    enum KindType {
+      /// \brief A template type parameter, stored as a type.
+      Type,
+      /// \brief A non-type template parameter, stored as an expression.
+      NonType,
+      /// \brief A template template argument, stored as a template name.
+      Template
+    };
+
+    /// \brief Build an empty template argument. This template argument 
+    ParsedTemplateArgument() : Kind(Type), Arg(0) { }
+    
+    /// \brief Create a template type argument or non-type template argument.
+    ///
+    /// \param Arg the template type argument or non-type template argument.
+    /// \param Loc the location of the type.
+    ParsedTemplateArgument(KindType Kind, void *Arg, SourceLocation Loc)
+      : Kind(Kind), Arg(Arg), Loc(Loc) { }
+    
+    /// \brief Create a template template argument.
+    ///
+    /// \param SS the C++ scope specifier that precedes the template name, if
+    /// any.
+    ///
+    /// \param Template the template to which this template template 
+    /// argument refers.
+    ///
+    /// \param TemplateLoc the location of the template name.
+    ParsedTemplateArgument(const CXXScopeSpec &SS,
+                           ActionBase::TemplateTy Template, 
+                           SourceLocation TemplateLoc) 
+      : Kind(ParsedTemplateArgument::Template), Arg(Template.get()), 
+        Loc(TemplateLoc), SS(SS) { }
+    
+    /// \brief Determine whether the given template argument is invalid.
+    bool isInvalid() { return Arg == 0; }
+    
+    /// \brief Determine what kind of template argument we have.
+    KindType getKind() const { return Kind; }
+    
+    /// \brief Retrieve the template type argument's type.
+    ActionBase::TypeTy *getAsType() const {
+      assert(Kind == Type && "Not a template type argument");
+      return Arg;
+    }
+    
+    /// \brief Retrieve the non-type template argument's expression.
+    ActionBase::ExprTy *getAsExpr() const {
+      assert(Kind == NonType && "Not a non-type template argument");
+      return Arg;
+    }
+    
+    /// \brief Retrieve the template template argument's template name.
+    ActionBase::TemplateTy getAsTemplate() const {
+      assert(Kind == Template && "Not a template template argument");
+      return ActionBase::TemplateTy::make(Arg);
+    }
+    
+    /// \brief Retrieve the location of the template argument.
+    SourceLocation getLocation() const { return Loc; }
+    
+    /// \brief Retrieve the nested-name-specifier that precedes the template
+    /// name in a template template argument.
+    const CXXScopeSpec &getScopeSpec() const {
+      assert(Kind == Template && 
+             "Only template template arguments can have a scope specifier");
+      return SS;
+    }
+    
+  private:
+    KindType Kind;
+    
+    /// \brief The actual template argument representation, which may be
+    /// an \c ActionBase::TypeTy* (for a type), an ActionBase::ExprTy* (for an
+    /// expression), or an ActionBase::TemplateTy (for a template).
+    void *Arg;
+
+    /// \brief the location of the template argument.
+    SourceLocation Loc;
+    
+    /// \brief The nested-name-specifier that can accompany a template template
+    /// argument.
+    CXXScopeSpec SS;
+  };
+  
+  /// \brief Information about a template-id annotation
+  /// token.
+  ///
+  /// A template-id annotation token contains the template declaration, 
+  /// template arguments, whether those template arguments were types, 
+  /// expressions, or template names, and the source locations for important 
+  /// tokens. All of the information about template arguments is allocated 
+  /// directly after this structure.
+  struct TemplateIdAnnotation {
+    /// TemplateNameLoc - The location of the template name within the
+    /// source.
+    SourceLocation TemplateNameLoc;
+    
+    /// FIXME: Temporarily stores the name of a specialization
+    IdentifierInfo *Name;
+    
+    /// FIXME: Temporarily stores the overloaded operator kind.
+    OverloadedOperatorKind Operator;
+    
+    /// The declaration of the template corresponding to the
+    /// template-name. This is an Action::TemplateTy.
+    void *Template;
+    
+    /// The kind of template that Template refers to.
+    TemplateNameKind Kind;
+    
+    /// The location of the '<' before the template argument
+    /// list.
+    SourceLocation LAngleLoc;
+    
+    /// The location of the '>' after the template argument
+    /// list.
+    SourceLocation RAngleLoc;
+    
+    /// NumArgs - The number of template arguments.
+    unsigned NumArgs;
+    
+    /// \brief Retrieves a pointer to the template arguments
+    ParsedTemplateArgument *getTemplateArgs() { 
+      return reinterpret_cast<ParsedTemplateArgument *>(this + 1); 
+    }
+    
+    static TemplateIdAnnotation* Allocate(unsigned NumArgs) {
+      TemplateIdAnnotation *TemplateId
+      = (TemplateIdAnnotation *)std::malloc(sizeof(TemplateIdAnnotation) +
+                                      sizeof(ParsedTemplateArgument) * NumArgs);
+      TemplateId->NumArgs = NumArgs;
+      return TemplateId;
+    }
+    
+    void Destroy() { free(this); }
+  };
+  
+#if !defined(DISABLE_SMART_POINTERS)
+  inline void ASTTemplateArgsPtr::destroy() {
+    if (!Count)
+      return;
+    
+    for (unsigned I = 0; I != Count; ++I)
+      if (Args[I].getKind() == ParsedTemplateArgument::NonType)
+        Actions.DeleteExpr(Args[I].getAsExpr());
+    
+    Count = 0;
+  }
+#endif
+  
+  inline const ParsedTemplateArgument &
+  ASTTemplateArgsPtr::operator[](unsigned Arg) const { 
+    return Args[Arg]; 
+  }
+}
+
+#endif
diff --git a/include/clang/Rewrite/DeltaTree.h b/include/clang/Rewrite/DeltaTree.h
new file mode 100644
index 0000000..f32906a
--- /dev/null
+++ b/include/clang/Rewrite/DeltaTree.h
@@ -0,0 +1,48 @@
+//===--- DeltaTree.h - B-Tree for Rewrite Delta tracking --------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the DeltaTree class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_REWRITE_DELTATREE_H
+#define CLANG_REWRITE_DELTATREE_H
+
+namespace clang {
+
+  /// DeltaTree - a multiway search tree (BTree) structure with some fancy
+  /// features.  B-Trees are generally more memory and cache efficient than
+  /// binary trees, because they store multiple keys/values in each node.  This
+  /// implements a key/value mapping from index to delta, and allows fast lookup
+  /// on index.  However, an added (important) bonus is that it can also
+  /// efficiently tell us the full accumulated delta for a specific file offset
+  /// as well, without traversing the whole tree.
+  class DeltaTree {
+    void *Root;    // "DeltaTreeNode *"
+    void operator=(const DeltaTree&); // DO NOT IMPLEMENT
+  public:
+    DeltaTree();
+
+    // Note: Currently we only support copying when the RHS is empty.
+    DeltaTree(const DeltaTree &RHS);
+    ~DeltaTree();
+
+    /// getDeltaAt - Return the accumulated delta at the specified file offset.
+    /// This includes all insertions or delections that occurred *before* the
+    /// specified file index.
+    int getDeltaAt(unsigned FileIndex) const;
+
+    /// AddDelta - When a change is made that shifts around the text buffer,
+    /// this method is used to record that info.  It inserts a delta of 'Delta'
+    /// into the current DeltaTree at offset FileIndex.
+    void AddDelta(unsigned FileIndex, int Delta);
+  };
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Rewrite/HTMLRewrite.h b/include/clang/Rewrite/HTMLRewrite.h
new file mode 100644
index 0000000..88caf85
--- /dev/null
+++ b/include/clang/Rewrite/HTMLRewrite.h
@@ -0,0 +1,81 @@
+//==- HTMLRewrite.h - Translate source code into prettified HTML ---*- C++ -*-//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines a set of functions used for translating source code
+//  into beautified HTML.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_HTMLREWRITER_H
+#define LLVM_CLANG_HTMLREWRITER_H
+
+#include "clang/Basic/SourceLocation.h"
+#include <string>
+
+namespace clang {
+
+class Rewriter;
+class RewriteBuffer;
+class Preprocessor;
+
+namespace html {
+
+  /// HighlightRange - Highlight a range in the source code with the specified
+  /// start/end tags.  B/E must be in the same file.  This ensures that
+  /// start/end tags are placed at the start/end of each line if the range is
+  /// multiline.
+  void HighlightRange(Rewriter &R, SourceLocation B, SourceLocation E,
+                      const char *StartTag, const char *EndTag);
+
+  /// HighlightRange - Highlight a range in the source code with the specified
+  /// start/end tags.  The Start/end of the range must be in the same file.
+  /// This ensures that start/end tags are placed at the start/end of each line
+  /// if the range is multiline.
+  inline void HighlightRange(Rewriter &R, SourceRange Range,
+                             const char *StartTag, const char *EndTag) {
+    HighlightRange(R, Range.getBegin(), Range.getEnd(), StartTag, EndTag);
+  }
+
+  /// HighlightRange - This is the same as the above method, but takes
+  /// decomposed file locations.
+  void HighlightRange(RewriteBuffer &RB, unsigned B, unsigned E,
+                      const char *BufferStart,
+                      const char *StartTag, const char *EndTag);
+
+  /// EscapeText - HTMLize a specified file so that special characters are
+  /// are translated so that they are not interpreted as HTML tags.
+  void EscapeText(Rewriter& R, FileID FID,
+                  bool EscapeSpaces = false, bool ReplaceTabs = false);
+
+  /// EscapeText - HTMLized the provided string so that special characters
+  ///  in 's' are not interpreted as HTML tags.  Unlike the version of
+  ///  EscapeText that rewrites a file, this version by default replaces tabs
+  ///  with spaces.
+  std::string EscapeText(const std::string& s,
+                         bool EscapeSpaces = false, bool ReplaceTabs = false);
+
+  void AddLineNumbers(Rewriter& R, FileID FID);
+
+  void AddHeaderFooterInternalBuiltinCSS(Rewriter& R, FileID FID,
+                                         const char *title = NULL);
+
+  /// SyntaxHighlight - Relex the specified FileID and annotate the HTML with
+  /// information about keywords, comments, etc.
+  void SyntaxHighlight(Rewriter &R, FileID FID, const Preprocessor &PP);
+
+  /// HighlightMacros - This uses the macro table state from the end of the
+  /// file, to reexpand macros and insert (into the HTML) information about the
+  /// macro expansions.  This won't be perfectly perfect, but it will be
+  /// reasonably close.
+  void HighlightMacros(Rewriter &R, FileID FID, const Preprocessor &PP);
+
+} // end html namespace
+} // end clang namespace
+
+#endif
diff --git a/include/clang/Rewrite/RewriteRope.h b/include/clang/Rewrite/RewriteRope.h
new file mode 100644
index 0000000..c0bd741
--- /dev/null
+++ b/include/clang/Rewrite/RewriteRope.h
@@ -0,0 +1,230 @@
+//===--- RewriteRope.h - Rope specialized for rewriter ----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the RewriteRope class, which is a powerful string class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_REWRITEROPE_H
+#define LLVM_CLANG_REWRITEROPE_H
+
+#include <cstring>
+#include <cassert>
+#include <iterator>
+
+namespace clang {
+  //===--------------------------------------------------------------------===//
+  // RopeRefCountString Class
+  //===--------------------------------------------------------------------===//
+
+  /// RopeRefCountString - This struct is allocated with 'new char[]' from the
+  /// heap, and represents a reference counted chunk of string data.  When its
+  /// ref count drops to zero, it is delete[]'d.  This is primarily managed
+  /// through the RopePiece class below.
+  struct RopeRefCountString {
+    unsigned RefCount;
+    char Data[1];  //  Variable sized.
+
+    void addRef() {
+      if (this) ++RefCount;
+    }
+
+    void dropRef() {
+      if (this && --RefCount == 0)
+        delete [] (char*)this;
+    }
+  };
+
+  //===--------------------------------------------------------------------===//
+  // RopePiece Class
+  //===--------------------------------------------------------------------===//
+
+  /// RopePiece - This class represents a view into a RopeRefCountString object.
+  /// This allows references to string data to be efficiently chopped up and
+  /// moved around without having to push around the string data itself.
+  ///
+  /// For example, we could have a 1M RopePiece and want to insert something
+  /// into the middle of it.  To do this, we split it into two RopePiece objects
+  /// that both refer to the same underlying RopeRefCountString (just with
+  /// different offsets) which is a nice constant time operation.
+  struct RopePiece {
+    RopeRefCountString *StrData;
+    unsigned StartOffs;
+    unsigned EndOffs;
+
+    RopePiece() : StrData(0), StartOffs(0), EndOffs(0) {}
+
+    RopePiece(RopeRefCountString *Str, unsigned Start, unsigned End)
+      : StrData(Str), StartOffs(Start), EndOffs(End) {
+      StrData->addRef();
+    }
+    RopePiece(const RopePiece &RP)
+      : StrData(RP.StrData), StartOffs(RP.StartOffs), EndOffs(RP.EndOffs) {
+      StrData->addRef();
+    }
+
+    ~RopePiece() {
+      StrData->dropRef();
+    }
+
+    void operator=(const RopePiece &RHS) {
+      if (StrData != RHS.StrData) {
+        StrData->dropRef();
+        StrData = RHS.StrData;
+        StrData->addRef();
+      }
+      StartOffs = RHS.StartOffs;
+      EndOffs = RHS.EndOffs;
+    }
+
+    const char &operator[](unsigned Offset) const {
+      return StrData->Data[Offset+StartOffs];
+    }
+    char &operator[](unsigned Offset) {
+      return StrData->Data[Offset+StartOffs];
+    }
+
+    unsigned size() const { return EndOffs-StartOffs; }
+  };
+
+  //===--------------------------------------------------------------------===//
+  // RopePieceBTreeIterator Class
+  //===--------------------------------------------------------------------===//
+
+  /// RopePieceBTreeIterator - This class provides read-only forward iteration
+  /// over bytes that are in a RopePieceBTree.  This first iterates over bytes
+  /// in a RopePiece, then iterates over RopePiece's in a RopePieceBTreeLeaf,
+  /// then iterates over RopePieceBTreeLeaf's in a RopePieceBTree.
+  class RopePieceBTreeIterator :
+      public std::iterator<std::forward_iterator_tag, const char, ptrdiff_t> {
+    /// CurNode - The current B+Tree node that we are inspecting.
+    const void /*RopePieceBTreeLeaf*/ *CurNode;
+    /// CurPiece - The current RopePiece in the B+Tree node that we're
+    /// inspecting.
+    const RopePiece *CurPiece;
+    /// CurChar - The current byte in the RopePiece we are pointing to.
+    unsigned CurChar;
+  public:
+    // begin iterator.
+    RopePieceBTreeIterator(const void /*RopePieceBTreeNode*/ *N);
+    // end iterator
+    RopePieceBTreeIterator() : CurNode(0), CurPiece(0), CurChar(0) {}
+
+    char operator*() const {
+      return (*CurPiece)[CurChar];
+    }
+
+    bool operator==(const RopePieceBTreeIterator &RHS) const {
+      return CurPiece == RHS.CurPiece && CurChar == RHS.CurChar;
+    }
+    bool operator!=(const RopePieceBTreeIterator &RHS) const {
+      return !operator==(RHS);
+    }
+
+    RopePieceBTreeIterator& operator++() {   // Preincrement
+      if (CurChar+1 < CurPiece->size())
+        ++CurChar;
+      else
+        MoveToNextPiece();
+      return *this;
+    }
+    inline RopePieceBTreeIterator operator++(int) { // Postincrement
+      RopePieceBTreeIterator tmp = *this; ++*this; return tmp;
+    }
+  private:
+    void MoveToNextPiece();
+  };
+
+  //===--------------------------------------------------------------------===//
+  // RopePieceBTree Class
+  //===--------------------------------------------------------------------===//
+
+  class RopePieceBTree {
+    void /*RopePieceBTreeNode*/ *Root;
+    void operator=(const RopePieceBTree &); // DO NOT IMPLEMENT
+  public:
+    RopePieceBTree();
+    RopePieceBTree(const RopePieceBTree &RHS);
+    ~RopePieceBTree();
+
+    typedef RopePieceBTreeIterator iterator;
+    iterator begin() const { return iterator(Root); }
+    iterator end() const { return iterator(); }
+    unsigned size() const;
+    unsigned empty() const { return size() == 0; }
+
+    void clear();
+
+    void insert(unsigned Offset, const RopePiece &R);
+
+    void erase(unsigned Offset, unsigned NumBytes);
+  };
+
+  //===--------------------------------------------------------------------===//
+  // RewriteRope Class
+  //===--------------------------------------------------------------------===//
+
+/// RewriteRope - A powerful string class.  This class supports extremely
+/// efficient insertions and deletions into the middle of it, even for
+/// ridiculously long strings.
+class RewriteRope {
+  RopePieceBTree Chunks;
+
+  /// We allocate space for string data out of a buffer of size AllocChunkSize.
+  /// This keeps track of how much space is left.
+  RopeRefCountString *AllocBuffer;
+  unsigned AllocOffs;
+  enum { AllocChunkSize = 4080 };
+
+public:
+  RewriteRope() :  AllocBuffer(0), AllocOffs(AllocChunkSize) {}
+  RewriteRope(const RewriteRope &RHS)
+    : Chunks(RHS.Chunks), AllocBuffer(0), AllocOffs(AllocChunkSize) {
+  }
+
+  ~RewriteRope() {
+    // If we had an allocation buffer, drop our reference to it.
+    AllocBuffer->dropRef();
+  }
+
+  typedef RopePieceBTree::iterator iterator;
+  typedef RopePieceBTree::iterator const_iterator;
+  iterator begin() const { return Chunks.begin(); }
+  iterator end() const  { return Chunks.end(); }
+  unsigned size() const { return Chunks.size(); }
+
+  void clear() {
+    Chunks.clear();
+  }
+
+  void assign(const char *Start, const char *End) {
+    clear();
+    if (Start != End)
+      Chunks.insert(0, MakeRopeString(Start, End));
+  }
+
+  void insert(unsigned Offset, const char *Start, const char *End) {
+    assert(Offset <= size() && "Invalid position to insert!");
+    if (Start == End) return;
+    Chunks.insert(Offset, MakeRopeString(Start, End));
+  }
+
+  void erase(unsigned Offset, unsigned NumBytes) {
+    assert(Offset+NumBytes <= size() && "Invalid region to erase!");
+    if (NumBytes == 0) return;
+    Chunks.erase(Offset, NumBytes);
+  }
+
+private:
+  RopePiece MakeRopeString(const char *Start, const char *End);
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Rewrite/Rewriter.h b/include/clang/Rewrite/Rewriter.h
new file mode 100644
index 0000000..adda866
--- /dev/null
+++ b/include/clang/Rewrite/Rewriter.h
@@ -0,0 +1,225 @@
+//===--- Rewriter.h - Code rewriting interface ------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the Rewriter class, which is used for code
+//  transformations.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_REWRITER_H
+#define LLVM_CLANG_REWRITER_H
+
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Rewrite/DeltaTree.h"
+#include "clang/Rewrite/RewriteRope.h"
+#include "llvm/ADT/StringRef.h"
+#include <cstring>
+#include <map>
+#include <string>
+#include <vector>
+
+namespace llvm { class raw_ostream; }
+
+namespace clang {
+  class LangOptions;
+  class Rewriter;
+  class SourceManager;
+  class Stmt;
+
+/// RewriteBuffer - As code is rewritten, SourceBuffer's from the original
+/// input with modifications get a new RewriteBuffer associated with them.  The
+/// RewriteBuffer captures the modified text itself as well as information used
+/// to map between SourceLocation's in the original input and offsets in the
+/// RewriteBuffer.  For example, if text is inserted into the buffer, any
+/// locations after the insertion point have to be mapped.
+class RewriteBuffer {
+  friend class Rewriter;
+  /// Deltas - Keep track of all the deltas in the source code due to insertions
+  /// and deletions.
+  DeltaTree Deltas;
+
+  /// Buffer - This is the actual buffer itself.  Note that using a vector or
+  /// string is a horribly inefficient way to do this, we should use a rope
+  /// instead.
+  typedef RewriteRope BufferTy;
+  BufferTy Buffer;
+public:
+  typedef BufferTy::const_iterator iterator;
+  iterator begin() const { return Buffer.begin(); }
+  iterator end() const { return Buffer.end(); }
+  unsigned size() const { return Buffer.size(); }
+
+  llvm::raw_ostream &write(llvm::raw_ostream &) const;
+
+  /// RemoveText - Remove the specified text.
+  void RemoveText(unsigned OrigOffset, unsigned Size);
+
+  /// InsertText - Insert some text at the specified point, where the offset in
+  /// the buffer is specified relative to the original SourceBuffer.  The
+  /// text is inserted after the specified location.
+  ///
+  void InsertText(unsigned OrigOffset, const llvm::StringRef &Str,
+                  bool InsertAfter = true);
+
+
+  /// InsertTextBefore - Insert some text before the specified point, where the
+  /// offset in the buffer is specified relative to the original
+  /// SourceBuffer. The text is inserted before the specified location.  This is
+  /// method is the same as InsertText with "InsertAfter == false".
+  void InsertTextBefore(unsigned OrigOffset, const llvm::StringRef &Str) {
+    InsertText(OrigOffset, Str, false);
+  }
+
+  /// InsertTextAfter - Insert some text at the specified point, where the
+  /// offset in the buffer is specified relative to the original SourceBuffer.
+  /// The text is inserted after the specified location.
+  void InsertTextAfter(unsigned OrigOffset, const llvm::StringRef &Str) {
+    InsertText(OrigOffset, Str);
+  }
+
+  /// ReplaceText - This method replaces a range of characters in the input
+  /// buffer with a new string.  This is effectively a combined "remove/insert"
+  /// operation.
+  void ReplaceText(unsigned OrigOffset, unsigned OrigLength,
+                   const llvm::StringRef &NewStr);
+
+private:  // Methods only usable by Rewriter.
+
+  /// Initialize - Start this rewrite buffer out with a copy of the unmodified
+  /// input buffer.
+  void Initialize(const char *BufStart, const char *BufEnd) {
+    Buffer.assign(BufStart, BufEnd);
+  }
+
+  /// getMappedOffset - Given an offset into the original SourceBuffer that this
+  /// RewriteBuffer is based on, map it into the offset space of the
+  /// RewriteBuffer.  If AfterInserts is true and if the OrigOffset indicates a
+  /// position where text is inserted, the location returned will be after any
+  /// inserted text at the position.
+  unsigned getMappedOffset(unsigned OrigOffset,
+                           bool AfterInserts = false) const{
+    return Deltas.getDeltaAt(2*OrigOffset+AfterInserts)+OrigOffset;
+  }
+
+  /// AddInsertDelta - When an insertion is made at a position, this
+  /// method is used to record that information.
+  void AddInsertDelta(unsigned OrigOffset, int Change) {
+    return Deltas.AddDelta(2*OrigOffset, Change);
+  }
+
+  /// AddReplaceDelta - When a replacement/deletion is made at a position, this
+  /// method is used to record that information.
+  void AddReplaceDelta(unsigned OrigOffset, int Change) {
+    return Deltas.AddDelta(2*OrigOffset+1, Change);
+  }
+};
+
+
+/// Rewriter - This is the main interface to the rewrite buffers.  Its primary
+/// job is to dispatch high-level requests to the low-level RewriteBuffers that
+/// are involved.
+class Rewriter {
+  SourceManager *SourceMgr;
+  const LangOptions *LangOpts;
+  std::map<FileID, RewriteBuffer> RewriteBuffers;
+public:
+  typedef std::map<FileID, RewriteBuffer>::iterator buffer_iterator;
+
+  explicit Rewriter(SourceManager &SM, const LangOptions &LO)
+    : SourceMgr(&SM), LangOpts(&LO) {}
+  explicit Rewriter() : SourceMgr(0), LangOpts(0) {}
+
+  void setSourceMgr(SourceManager &SM, const LangOptions &LO) {
+    SourceMgr = &SM;
+    LangOpts = &LO;
+  }
+  SourceManager &getSourceMgr() { return *SourceMgr; }
+  const LangOptions &getLangOpts() { return *LangOpts; }
+
+  /// isRewritable - Return true if this location is a raw file location, which
+  /// is rewritable.  Locations from macros, etc are not rewritable.
+  static bool isRewritable(SourceLocation Loc) {
+    return Loc.isFileID();
+  }
+
+  /// getRangeSize - Return the size in bytes of the specified range if they
+  /// are in the same file.  If not, this returns -1.
+  int getRangeSize(SourceRange Range) const;
+
+  /// getRewrittenText - Return the rewritten form of the text in the specified
+  /// range.  If the start or end of the range was unrewritable or if they are
+  /// in different buffers, this returns an empty string.
+  ///
+  /// Note that this method is not particularly efficient.
+  ///
+  std::string getRewrittenText(SourceRange Range) const;
+
+  /// InsertText - Insert the specified string at the specified location in the
+  /// original buffer.  This method returns true (and does nothing) if the input
+  /// location was not rewritable, false otherwise.
+  bool InsertText(SourceLocation Loc, const llvm::StringRef &Str,
+                  bool InsertAfter = true);
+
+  /// InsertTextAfter - Insert the specified string at the specified location in
+  ///  the original buffer.  This method returns true (and does nothing) if
+  ///  the input location was not rewritable, false otherwise.  Text is
+  ///  inserted after any other text that has been previously inserted
+  ///  at the some point (the default behavior for InsertText).
+  bool InsertTextAfter(SourceLocation Loc, const llvm::StringRef &Str) {
+    return InsertText(Loc, Str);
+  }
+
+  /// InsertText - Insert the specified string at the specified location in the
+  /// original buffer.  This method returns true (and does nothing) if the input
+  /// location was not rewritable, false otherwise.  Text is
+  /// inserted before any other text that has been previously inserted
+  /// at the some point.
+  bool InsertTextBefore(SourceLocation Loc, const llvm::StringRef &Str) {
+    return InsertText(Loc, Str, false);
+  }
+
+  /// RemoveText - Remove the specified text region.
+  bool RemoveText(SourceLocation Start, unsigned Length);
+
+  /// ReplaceText - This method replaces a range of characters in the input
+  /// buffer with a new string.  This is effectively a combined "remove/insert"
+  /// operation.
+  bool ReplaceText(SourceLocation Start, unsigned OrigLength,
+                   const llvm::StringRef &NewStr);
+
+  /// ReplaceStmt - This replaces a Stmt/Expr with another, using the pretty
+  /// printer to generate the replacement code.  This returns true if the input
+  /// could not be rewritten, or false if successful.
+  bool ReplaceStmt(Stmt *From, Stmt *To);
+
+  /// getEditBuffer - This is like getRewriteBufferFor, but always returns a
+  /// buffer, and allows you to write on it directly.  This is useful if you
+  /// want efficient low-level access to apis for scribbling on one specific
+  /// FileID's buffer.
+  RewriteBuffer &getEditBuffer(FileID FID);
+
+  /// getRewriteBufferFor - Return the rewrite buffer for the specified FileID.
+  /// If no modification has been made to it, return null.
+  const RewriteBuffer *getRewriteBufferFor(FileID FID) const {
+    std::map<FileID, RewriteBuffer>::const_iterator I =
+      RewriteBuffers.find(FID);
+    return I == RewriteBuffers.end() ? 0 : &I->second;
+  }
+
+  // Iterators over rewrite buffers.
+  buffer_iterator buffer_begin() { return RewriteBuffers.begin(); }
+  buffer_iterator buffer_end() { return RewriteBuffers.end(); }
+
+private:
+  unsigned getLocationOffsetAndFileID(SourceLocation Loc, FileID &FID) const;
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Rewrite/TokenRewriter.h b/include/clang/Rewrite/TokenRewriter.h
new file mode 100644
index 0000000..62ea12a
--- /dev/null
+++ b/include/clang/Rewrite/TokenRewriter.h
@@ -0,0 +1,79 @@
+//===--- TokenRewriter.h - Token-based Rewriter -----------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the TokenRewriter class, which is used for code
+//  transformations.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOKENREWRITER_H
+#define LLVM_CLANG_TOKENREWRITER_H
+
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/OwningPtr.h"
+#include <list>
+#include <map>
+
+namespace clang {
+  class Token;
+  class LangOptions;
+  class ScratchBuffer;
+
+  class TokenRewriter {
+    /// TokenList - This is the list of raw tokens that make up this file.  Each
+    /// of these tokens has a unique SourceLocation, which is a FileID.
+    std::list<Token> TokenList;
+
+    /// TokenRefTy - This is the type used to refer to a token in the TokenList.
+    typedef std::list<Token>::iterator TokenRefTy;
+
+    /// TokenAtLoc - This map indicates which token exists at a specific
+    /// SourceLocation.  Since each token has a unique SourceLocation, this is a
+    /// one to one map.  The token can return its own location directly, to map
+    /// backwards.
+    std::map<SourceLocation, TokenRefTy> TokenAtLoc;
+
+    /// ScratchBuf - This is the buffer that we create scratch tokens from.
+    ///
+    llvm::OwningPtr<ScratchBuffer> ScratchBuf;
+
+    TokenRewriter(const TokenRewriter&);  // DO NOT IMPLEMENT
+    void operator=(const TokenRewriter&); // DO NOT IMPLEMENT.
+  public:
+    /// TokenRewriter - This creates a TokenRewriter for the file with the
+    /// specified FileID.
+    TokenRewriter(FileID FID, SourceManager &SM, const LangOptions &LO);
+    ~TokenRewriter();
+
+    typedef std::list<Token>::const_iterator token_iterator;
+    token_iterator token_begin() const { return TokenList.begin(); }
+    token_iterator token_end() const { return TokenList.end(); }
+
+
+    token_iterator AddTokenBefore(token_iterator I, const char *Val);
+    token_iterator AddTokenAfter(token_iterator I, const char *Val) {
+      assert(I != token_end() && "Cannot insert after token_end()!");
+      return AddTokenBefore(++I, Val);
+    }
+
+  private:
+    /// RemapIterator - Convert from token_iterator (a const iterator) to
+    /// TokenRefTy (a non-const iterator).
+    TokenRefTy RemapIterator(token_iterator I);
+
+    /// AddToken - Add the specified token into the Rewriter before the other
+    /// position.
+    TokenRefTy AddToken(const Token &T, TokenRefTy Where);
+  };
+
+
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Sema/CodeCompleteConsumer.h b/include/clang/Sema/CodeCompleteConsumer.h
new file mode 100644
index 0000000..348917a
--- /dev/null
+++ b/include/clang/Sema/CodeCompleteConsumer.h
@@ -0,0 +1,501 @@
+//===---- CodeCompleteConsumer.h - Code Completion Interface ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the CodeCompleteConsumer class.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_SEMA_CODECOMPLETECONSUMER_H
+#define LLVM_CLANG_SEMA_CODECOMPLETECONSUMER_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include <memory>
+#include <string>
+
+namespace llvm {
+class raw_ostream;
+}
+
+namespace clang {
+
+class FunctionDecl;
+class FunctionType;
+class FunctionTemplateDecl;
+class IdentifierInfo;
+class NamedDecl;
+class NestedNameSpecifier;
+class Sema;
+
+/// \brief A "string" used to describe how code completion can
+/// be performed for an entity.
+///
+/// A code completion string typically shows how a particular entity can be 
+/// used. For example, the code completion string for a function would show
+/// the syntax to call it, including the parentheses, placeholders for the 
+/// arguments, etc.  
+class CodeCompletionString {
+public:
+  /// \brief The different kinds of "chunks" that can occur within a code
+  /// completion string.
+  enum ChunkKind {
+    /// \brief The piece of text that the user is expected to type to
+    /// match the code-completion string, typically a keyword or the name of a
+    /// declarator or macro.
+    CK_TypedText,
+    /// \brief A piece of text that should be placed in the buffer, e.g.,
+    /// parentheses or a comma in a function call.
+    CK_Text,
+    /// \brief A code completion string that is entirely optional. For example,
+    /// an optional code completion string that describes the default arguments
+    /// in a function call.
+    CK_Optional,
+    /// \brief A string that acts as a placeholder for, e.g., a function 
+    /// call argument.
+    CK_Placeholder,
+    /// \brief A piece of text that describes something about the result but
+    /// should not be inserted into the buffer.
+    CK_Informative,
+    /// \brief A piece of text that describes the type of an entity or, for
+    /// functions and methods, the return type.
+    CK_ResultType,
+    /// \brief A piece of text that describes the parameter that corresponds
+    /// to the code-completion location within a function call, message send,
+    /// macro invocation, etc.
+    CK_CurrentParameter,
+    /// \brief A left parenthesis ('(').
+    CK_LeftParen,
+    /// \brief A right parenthesis (')').
+    CK_RightParen,
+    /// \brief A left bracket ('[').
+    CK_LeftBracket,
+    /// \brief A right bracket (']').
+    CK_RightBracket,
+    /// \brief A left brace ('{').
+    CK_LeftBrace,
+    /// \brief A right brace ('}').
+    CK_RightBrace,
+    /// \brief A left angle bracket ('<').
+    CK_LeftAngle,
+    /// \brief A right angle bracket ('>').
+    CK_RightAngle,
+    /// \brief A comma separator (',').
+    CK_Comma,
+    /// \brief A colon (':').
+    CK_Colon,
+    /// \brief A semicolon (';').
+    CK_SemiColon,
+    /// \brief An '=' sign.
+    CK_Equal,
+    /// \brief Horizontal whitespace (' ').
+    CK_HorizontalSpace,
+    /// \brief Verticle whitespace ('\n' or '\r\n', depending on the
+    /// platform).
+    CK_VerticalSpace
+  };
+  
+  /// \brief One piece of the code completion string.
+  struct Chunk {
+    /// \brief The kind of data stored in this piece of the code completion 
+    /// string.
+    ChunkKind Kind;
+    
+    union {
+      /// \brief The text string associated with a CK_Text, CK_Placeholder,
+      /// CK_Informative, or CK_Comma chunk.
+      /// The string is owned by the chunk and will be deallocated 
+      /// (with delete[]) when the chunk is destroyed.
+      const char *Text;
+      
+      /// \brief The code completion string associated with a CK_Optional chunk.
+      /// The optional code completion string is owned by the chunk, and will
+      /// be deallocated (with delete) when the chunk is destroyed.
+      CodeCompletionString *Optional;
+    };
+    
+    Chunk() : Kind(CK_Text), Text(0) { }
+    
+    Chunk(ChunkKind Kind, llvm::StringRef Text = "");
+    
+    /// \brief Create a new text chunk.
+    static Chunk CreateText(llvm::StringRef Text);
+
+    /// \brief Create a new optional chunk.
+    static Chunk CreateOptional(std::auto_ptr<CodeCompletionString> Optional);
+
+    /// \brief Create a new placeholder chunk.
+    static Chunk CreatePlaceholder(llvm::StringRef Placeholder);
+
+    /// \brief Create a new informative chunk.
+    static Chunk CreateInformative(llvm::StringRef Informative);
+
+    /// \brief Create a new result type chunk.
+    static Chunk CreateResultType(llvm::StringRef ResultType);
+
+    /// \brief Create a new current-parameter chunk.
+    static Chunk CreateCurrentParameter(llvm::StringRef CurrentParameter);
+
+    /// \brief Clone the given chunk.
+    Chunk Clone() const;
+    
+    /// \brief Destroy this chunk, deallocating any memory it owns.
+    void Destroy();
+  };
+  
+private:
+  /// \brief The chunks stored in this string.
+  llvm::SmallVector<Chunk, 4> Chunks;
+  
+  CodeCompletionString(const CodeCompletionString &); // DO NOT IMPLEMENT
+  CodeCompletionString &operator=(const CodeCompletionString &); // DITTO
+  
+public:
+  CodeCompletionString() { }
+  ~CodeCompletionString();
+  
+  typedef llvm::SmallVector<Chunk, 4>::const_iterator iterator;
+  iterator begin() const { return Chunks.begin(); }
+  iterator end() const { return Chunks.end(); }
+  bool empty() const { return Chunks.empty(); }
+  unsigned size() const { return Chunks.size(); }
+  
+  Chunk &operator[](unsigned I) {
+    assert(I < size() && "Chunk index out-of-range");
+    return Chunks[I];
+  }
+
+  const Chunk &operator[](unsigned I) const {
+    assert(I < size() && "Chunk index out-of-range");
+    return Chunks[I];
+  }
+  
+  /// \brief Add a new typed-text chunk.
+  /// The text string will be copied.
+  void AddTypedTextChunk(llvm::StringRef Text) { 
+    Chunks.push_back(Chunk(CK_TypedText, Text));
+  }
+  
+  /// \brief Add a new text chunk.
+  /// The text string will be copied.
+  void AddTextChunk(llvm::StringRef Text) { 
+    Chunks.push_back(Chunk::CreateText(Text)); 
+  }
+  
+  /// \brief Add a new optional chunk.
+  void AddOptionalChunk(std::auto_ptr<CodeCompletionString> Optional) {
+    Chunks.push_back(Chunk::CreateOptional(Optional));
+  }
+  
+  /// \brief Add a new placeholder chunk.
+  /// The placeholder text will be copied.
+  void AddPlaceholderChunk(llvm::StringRef Placeholder) {
+    Chunks.push_back(Chunk::CreatePlaceholder(Placeholder));
+  }
+
+  /// \brief Add a new informative chunk.
+  /// The text will be copied.
+  void AddInformativeChunk(llvm::StringRef Text) {
+    Chunks.push_back(Chunk::CreateInformative(Text));
+  }
+
+  /// \brief Add a new result-type chunk.
+  /// The text will be copied.
+  void AddResultTypeChunk(llvm::StringRef ResultType) {
+    Chunks.push_back(Chunk::CreateResultType(ResultType));
+  }
+  
+  /// \brief Add a new current-parameter chunk.
+  /// The text will be copied.
+  void AddCurrentParameterChunk(llvm::StringRef CurrentParameter) {
+    Chunks.push_back(Chunk::CreateCurrentParameter(CurrentParameter));
+  }
+  
+  /// \brief Add a new chunk.
+  void AddChunk(Chunk C) { Chunks.push_back(C); }
+  
+  /// \brief Returns the text in the TypedText chunk.
+  const char *getTypedText() const;
+
+  /// \brief Retrieve a string representation of the code completion string,
+  /// which is mainly useful for debugging.
+  std::string getAsString() const; 
+  
+  /// \brief Clone this code-completion string.
+  CodeCompletionString *Clone() const;
+  
+  /// \brief Serialize this code-completion string to the given stream.
+  void Serialize(llvm::raw_ostream &OS) const;
+  
+  /// \brief Deserialize a code-completion string from the given string.
+  static CodeCompletionString *Deserialize(const char *&Str, 
+                                           const char *StrEnd);
+};
+  
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, 
+                              const CodeCompletionString &CCS);
+
+/// \brief Abstract interface for a consumer of code-completion 
+/// information.
+class CodeCompleteConsumer {
+protected:
+  /// \brief Whether to include macros in the code-completion results.
+  bool IncludeMacros;
+
+  /// \brief Whether the output format for the code-completion consumer is
+  /// binary.
+  bool OutputIsBinary;
+  
+public:
+  /// \brief Captures a result of code completion.
+  struct Result {
+    /// \brief Describes the kind of result generated.
+    enum ResultKind {
+      RK_Declaration = 0, //< Refers to a declaration
+      RK_Keyword,         //< Refers to a keyword or symbol.
+      RK_Macro,           //< Refers to a macro
+      RK_Pattern          //< Refers to a precomputed pattern.
+    };
+    
+    /// \brief The kind of result stored here.
+    ResultKind Kind;
+    
+    union {
+      /// \brief When Kind == RK_Declaration, the declaration we are referring
+      /// to.
+      NamedDecl *Declaration;
+      
+      /// \brief When Kind == RK_Keyword, the string representing the keyword 
+      /// or symbol's spelling.
+      const char *Keyword;
+      
+      /// \brief When Kind == RK_Pattern, the code-completion string that
+      /// describes the completion text to insert.
+      CodeCompletionString *Pattern;
+      
+      /// \brief When Kind == RK_Macro, the identifier that refers to a macro.
+      IdentifierInfo *Macro;
+    };
+    
+    /// \brief Specifiers which parameter (of a function, Objective-C method,
+    /// macro, etc.) we should start with when formatting the result.
+    unsigned StartParameter;
+    
+    /// \brief Whether this result is hidden by another name.
+    bool Hidden : 1;
+    
+    /// \brief Whether this result was found via lookup into a base class.
+    bool QualifierIsInformative : 1;
+    
+    /// \brief Whether this declaration is the beginning of a 
+    /// nested-name-specifier and, therefore, should be followed by '::'.
+    bool StartsNestedNameSpecifier : 1;
+
+    /// \brief Whether all parameters (of a function, Objective-C
+    /// method, etc.) should be considered "informative".
+    bool AllParametersAreInformative : 1;
+
+    /// \brief If the result should have a nested-name-specifier, this is it.
+    /// When \c QualifierIsInformative, the nested-name-specifier is 
+    /// informative rather than required.
+    NestedNameSpecifier *Qualifier;
+    
+    /// \brief Build a result that refers to a declaration.
+    Result(NamedDecl *Declaration, 
+           NestedNameSpecifier *Qualifier = 0,
+           bool QualifierIsInformative = false)
+      : Kind(RK_Declaration), Declaration(Declaration), 
+        StartParameter(0), Hidden(false), 
+        QualifierIsInformative(QualifierIsInformative),
+        StartsNestedNameSpecifier(false), AllParametersAreInformative(false),
+        Qualifier(Qualifier) { }
+    
+    /// \brief Build a result that refers to a keyword or symbol.
+    Result(const char *Keyword)
+      : Kind(RK_Keyword), Keyword(Keyword), StartParameter(0),
+        Hidden(false), QualifierIsInformative(0), 
+        StartsNestedNameSpecifier(false), AllParametersAreInformative(false),
+        Qualifier(0) { }
+    
+    /// \brief Build a result that refers to a macro.
+    Result(IdentifierInfo *Macro)
+     : Kind(RK_Macro), Macro(Macro), StartParameter(0), 
+       Hidden(false), QualifierIsInformative(0), 
+       StartsNestedNameSpecifier(false), AllParametersAreInformative(false),
+       Qualifier(0) { }
+
+    /// \brief Build a result that refers to a pattern.
+    Result(CodeCompletionString *Pattern)
+      : Kind(RK_Pattern), Pattern(Pattern), StartParameter(0), 
+        Hidden(false), QualifierIsInformative(0), 
+        StartsNestedNameSpecifier(false), AllParametersAreInformative(false),
+        Qualifier(0) { }
+    
+    /// \brief Retrieve the declaration stored in this result.
+    NamedDecl *getDeclaration() const {
+      assert(Kind == RK_Declaration && "Not a declaration result");
+      return Declaration;
+    }
+    
+    /// \brief Retrieve the keyword stored in this result.
+    const char *getKeyword() const {
+      assert(Kind == RK_Keyword && "Not a keyword result");
+      return Keyword;
+    }
+    
+    /// \brief Create a new code-completion string that describes how to insert
+    /// this result into a program.
+    CodeCompletionString *CreateCodeCompletionString(Sema &S);
+    
+    void Destroy();
+  };
+    
+  class OverloadCandidate {
+  public:
+    /// \brief Describes the type of overload candidate.
+    enum CandidateKind {
+      /// \brief The candidate is a function declaration.
+      CK_Function,
+      /// \brief The candidate is a function template.
+      CK_FunctionTemplate,
+      /// \brief The "candidate" is actually a variable, expression, or block
+      /// for which we only have a function prototype.
+      CK_FunctionType
+    };
+    
+  private:
+    /// \brief The kind of overload candidate.
+    CandidateKind Kind;
+    
+    union {
+      /// \brief The function overload candidate, available when 
+      /// Kind == CK_Function.
+      FunctionDecl *Function;
+      
+      /// \brief The function template overload candidate, available when
+      /// Kind == CK_FunctionTemplate.
+      FunctionTemplateDecl *FunctionTemplate;
+      
+      /// \brief The function type that describes the entity being called,
+      /// when Kind == CK_FunctionType.
+      const FunctionType *Type;
+    };
+    
+  public:
+    OverloadCandidate(FunctionDecl *Function)
+      : Kind(CK_Function), Function(Function) { }
+
+    OverloadCandidate(FunctionTemplateDecl *FunctionTemplateDecl)
+      : Kind(CK_FunctionTemplate), FunctionTemplate(FunctionTemplate) { }
+
+    OverloadCandidate(const FunctionType *Type)
+      : Kind(CK_FunctionType), Type(Type) { }
+
+    /// \brief Determine the kind of overload candidate.
+    CandidateKind getKind() const { return Kind; }
+    
+    /// \brief Retrieve the function overload candidate or the templated 
+    /// function declaration for a function template.
+    FunctionDecl *getFunction() const;
+    
+    /// \brief Retrieve the function template overload candidate.
+    FunctionTemplateDecl *getFunctionTemplate() const {
+      assert(getKind() == CK_FunctionTemplate && "Not a function template");
+      return FunctionTemplate;
+    }
+    
+    /// \brief Retrieve the function type of the entity, regardless of how the
+    /// function is stored.
+    const FunctionType *getFunctionType() const;
+    
+    /// \brief Create a new code-completion string that describes the function
+    /// signature of this overload candidate.
+    CodeCompletionString *CreateSignatureString(unsigned CurrentArg, 
+                                                Sema &S) const;    
+  };
+  
+  CodeCompleteConsumer() : IncludeMacros(false), OutputIsBinary(false) { }
+  
+  CodeCompleteConsumer(bool IncludeMacros, bool OutputIsBinary)
+    : IncludeMacros(IncludeMacros), OutputIsBinary(OutputIsBinary) { }
+  
+  /// \brief Whether the code-completion consumer wants to see macros.
+  bool includeMacros() const { return IncludeMacros; }
+
+  /// \brief Determine whether the output of this consumer is binary.
+  bool isOutputBinary() const { return OutputIsBinary; }
+  
+  /// \brief Deregisters and destroys this code-completion consumer.
+  virtual ~CodeCompleteConsumer();
+
+  /// \name Code-completion callbacks
+  //@{
+  /// \brief Process the finalized code-completion results.
+  virtual void ProcessCodeCompleteResults(Sema &S, Result *Results,
+                                          unsigned NumResults) { }
+
+  /// \param S the semantic-analyzer object for which code-completion is being
+  /// done.
+  ///
+  /// \param CurrentArg the index of the current argument.
+  ///
+  /// \param Candidates an array of overload candidates.
+  ///
+  /// \param NumCandidates the number of overload candidates
+  virtual void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
+                                         OverloadCandidate *Candidates,
+                                         unsigned NumCandidates) { }
+  //@}
+};
+  
+/// \brief A simple code-completion consumer that prints the results it 
+/// receives in a simple format.
+class PrintingCodeCompleteConsumer : public CodeCompleteConsumer {
+  /// \brief The raw output stream.
+  llvm::raw_ostream &OS;
+    
+public:
+  /// \brief Create a new printing code-completion consumer that prints its
+  /// results to the given raw output stream.
+  PrintingCodeCompleteConsumer(bool IncludeMacros,
+                               llvm::raw_ostream &OS)
+    : CodeCompleteConsumer(IncludeMacros, false), OS(OS) { }
+  
+  /// \brief Prints the finalized code-completion results.
+  virtual void ProcessCodeCompleteResults(Sema &S, Result *Results,
+                                          unsigned NumResults);
+  
+  virtual void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
+                                         OverloadCandidate *Candidates,
+                                         unsigned NumCandidates);  
+};
+  
+/// \brief A code-completion consumer that prints the results it receives
+/// in a format that is parsable by the CIndex library.
+class CIndexCodeCompleteConsumer : public CodeCompleteConsumer {
+  /// \brief The raw output stream.
+  llvm::raw_ostream &OS;
+  
+public:
+  /// \brief Create a new CIndex code-completion consumer that prints its
+  /// results to the given raw output stream in a format readable to the CIndex
+  /// library.
+  CIndexCodeCompleteConsumer(bool IncludeMacros, llvm::raw_ostream &OS)
+    : CodeCompleteConsumer(IncludeMacros, true), OS(OS) { }
+  
+  /// \brief Prints the finalized code-completion results.
+  virtual void ProcessCodeCompleteResults(Sema &S, Result *Results, 
+                                          unsigned NumResults);
+  
+  virtual void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
+                                         OverloadCandidate *Candidates,
+                                         unsigned NumCandidates);  
+};
+  
+} // end namespace clang
+
+#endif // LLVM_CLANG_SEMA_CODECOMPLETECONSUMER_H
diff --git a/include/clang/Sema/ExternalSemaSource.h b/include/clang/Sema/ExternalSemaSource.h
new file mode 100644
index 0000000..d27e292
--- /dev/null
+++ b/include/clang/Sema/ExternalSemaSource.h
@@ -0,0 +1,59 @@
+//===--- ExternalSemaSource.h - External Sema Interface ---------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the ExternalSemaSource interface.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_SEMA_EXTERNAL_SEMA_SOURCE_H
+#define LLVM_CLANG_SEMA_EXTERNAL_SEMA_SOURCE_H
+
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/ExternalASTSource.h"
+
+namespace clang {
+
+class Sema;
+
+/// \brief An abstract interface that should be implemented by
+/// external AST sources that also provide information for semantic
+/// analysis.
+class ExternalSemaSource : public ExternalASTSource {
+public:
+  ExternalSemaSource() {
+    ExternalASTSource::SemaSource = true;
+  }
+
+  /// \brief Initialize the semantic source with the Sema instance
+  /// being used to perform semantic analysis on the abstract syntax
+  /// tree.
+  virtual void InitializeSema(Sema &S) {}
+
+  /// \brief Inform the semantic consumer that Sema is no longer available.
+  virtual void ForgetSema() {}
+
+  /// \brief Load the contents of the global method pool for a given
+  /// selector.
+  ///
+  /// \returns a pair of Objective-C methods lists containing the
+  /// instance and factory methods, respectively, with this selector.
+  virtual std::pair<ObjCMethodList, ObjCMethodList>
+  ReadMethodPool(Selector Sel) {
+    return std::pair<ObjCMethodList, ObjCMethodList>();
+  }
+
+  // isa/cast/dyn_cast support
+  static bool classof(const ExternalASTSource *Source) {
+    return Source->SemaSource;
+  }
+  static bool classof(const ExternalSemaSource *) { return true; }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Sema/ParseAST.h b/include/clang/Sema/ParseAST.h
new file mode 100644
index 0000000..f6cff2a
--- /dev/null
+++ b/include/clang/Sema/ParseAST.h
@@ -0,0 +1,43 @@
+//===--- ParseAST.h - Define the ParseAST method ----------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the clang::ParseAST method.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SEMA_PARSEAST_H
+#define LLVM_CLANG_SEMA_PARSEAST_H
+
+namespace clang {
+  class Preprocessor;
+  class ASTConsumer;
+  class ASTContext;
+  class CodeCompleteConsumer;
+  class Sema;
+
+  /// \brief Parse the entire file specified, notifying the ASTConsumer as
+  /// the file is parsed.
+  ///
+  /// This operation inserts the parsed decls into the translation
+  /// unit held by Ctx.
+  ///
+  /// \param CompleteTranslationUnit When true, the parsed file is
+  /// considered to be a complete translation unit, and any
+  /// end-of-translation-unit wrapup will be performed.
+  ///
+  /// \param CompletionConsumer If given, an object to consume code completion
+  /// results.
+  void ParseAST(Preprocessor &pp, ASTConsumer *C,
+                ASTContext &Ctx, bool PrintStats = false,
+                bool CompleteTranslationUnit = true,
+                CodeCompleteConsumer *CompletionConsumer = 0);
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Sema/SemaConsumer.h b/include/clang/Sema/SemaConsumer.h
new file mode 100644
index 0000000..3689a6e
--- /dev/null
+++ b/include/clang/Sema/SemaConsumer.h
@@ -0,0 +1,48 @@
+//===--- SemaConsumer.h - Abstract interface for AST semantics --*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the SemaConsumer class, a subclass of
+//  ASTConsumer that is used by AST clients that also require
+//  additional semantic analysis.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_SEMA_SEMACONSUMER_H
+#define LLVM_CLANG_SEMA_SEMACONSUMER_H
+
+#include "clang/AST/ASTConsumer.h"
+
+namespace clang {
+  class Sema;
+
+  /// \brief An abstract interface that should be implemented by
+  /// clients that read ASTs and then require further semantic
+  /// analysis of the entities in those ASTs.
+  class SemaConsumer : public ASTConsumer {
+  public:
+    SemaConsumer() {
+      ASTConsumer::SemaConsumer = true;
+    }
+
+    /// \brief Initialize the semantic consumer with the Sema instance
+    /// being used to perform semantic analysis on the abstract syntax
+    /// tree.
+    virtual void InitializeSema(Sema &S) {}
+
+    /// \brief Inform the semantic consumer that Sema is no longer available.
+    virtual void ForgetSema() {}
+
+    // isa/cast/dyn_cast support
+    static bool classof(const ASTConsumer *Consumer) {
+      return Consumer->SemaConsumer;
+    }
+    static bool classof(const SemaConsumer *) { return true; }
+  };
+}
+
+#endif
diff --git a/include/clang/Sema/SemaDiagnostic.h b/include/clang/Sema/SemaDiagnostic.h
new file mode 100644
index 0000000..d026339
--- /dev/null
+++ b/include/clang/Sema/SemaDiagnostic.h
@@ -0,0 +1,27 @@
+//===--- DiagnosticSema.h - Diagnostics for libsema -------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_DIAGNOSTICSEMA_H
+#define LLVM_CLANG_DIAGNOSTICSEMA_H
+
+#include "clang/Basic/Diagnostic.h"
+
+namespace clang {
+  namespace diag {
+    enum {
+#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE) ENUM,
+#define SEMASTART
+#include "clang/Basic/DiagnosticSemaKinds.inc"
+#undef DIAG
+      NUM_BUILTIN_SEMA_DIAGNOSTICS
+    };
+  }  // end namespace diag
+}  // end namespace clang
+
+#endif
diff --git a/lib/AST/APValue.cpp b/lib/AST/APValue.cpp
new file mode 100644
index 0000000..731d5e0
--- /dev/null
+++ b/lib/AST/APValue.cpp
@@ -0,0 +1,142 @@
+//===--- APValue.cpp - Union class for APFloat/APSInt/Complex -------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements the APValue class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/APValue.h"
+#include "clang/AST/CharUnits.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace clang;
+
+namespace {
+  struct LV {
+    Expr* Base;
+    CharUnits Offset;
+  };
+}
+
+APValue::APValue(Expr* B) : Kind(Uninitialized) {
+  MakeLValue(); setLValue(B, CharUnits::Zero());
+}
+
+const APValue &APValue::operator=(const APValue &RHS) {
+  if (Kind != RHS.Kind) {
+    MakeUninit();
+    if (RHS.isInt())
+      MakeInt();
+    else if (RHS.isFloat())
+      MakeFloat();
+    else if (RHS.isVector())
+      MakeVector();
+    else if (RHS.isComplexInt())
+      MakeComplexInt();
+    else if (RHS.isComplexFloat())
+      MakeComplexFloat();
+    else if (RHS.isLValue())
+      MakeLValue();
+  }
+  if (isInt())
+    setInt(RHS.getInt());
+  else if (isFloat())
+    setFloat(RHS.getFloat());
+  else if (isVector())
+    setVector(((const Vec *)(const char *)RHS.Data)->Elts,
+              RHS.getVectorLength());
+  else if (isComplexInt())
+    setComplexInt(RHS.getComplexIntReal(), RHS.getComplexIntImag());
+  else if (isComplexFloat())
+    setComplexFloat(RHS.getComplexFloatReal(), RHS.getComplexFloatImag());
+  else if (isLValue())
+    setLValue(RHS.getLValueBase(), RHS.getLValueOffset());
+  return *this;
+}
+
+void APValue::MakeUninit() {
+  if (Kind == Int)
+    ((APSInt*)(char*)Data)->~APSInt();
+  else if (Kind == Float)
+    ((APFloat*)(char*)Data)->~APFloat();
+  else if (Kind == Vector)
+    ((Vec*)(char*)Data)->~Vec();
+  else if (Kind == ComplexInt)
+    ((ComplexAPSInt*)(char*)Data)->~ComplexAPSInt();
+  else if (Kind == ComplexFloat)
+    ((ComplexAPFloat*)(char*)Data)->~ComplexAPFloat();
+  else if (Kind == LValue) {
+    ((LV*)(char*)Data)->~LV();
+  }
+  Kind = Uninitialized;
+}
+
+void APValue::dump() const {
+  print(llvm::errs());
+  llvm::errs() << '\n';
+}
+
+static double GetApproxValue(const llvm::APFloat &F) {
+  llvm::APFloat V = F;
+  bool ignored;
+  V.convert(llvm::APFloat::IEEEdouble, llvm::APFloat::rmNearestTiesToEven,
+            &ignored);
+  return V.convertToDouble();
+}
+
+void APValue::print(llvm::raw_ostream &OS) const {
+  switch (getKind()) {
+  default: assert(0 && "Unknown APValue kind!");
+  case Uninitialized:
+    OS << "Uninitialized";
+    return;
+  case Int:
+    OS << "Int: " << getInt();
+    return;
+  case Float:
+    OS << "Float: " << GetApproxValue(getFloat());
+    return;
+  case Vector:
+    OS << "Vector: " << getVectorElt(0);
+    for (unsigned i = 1; i != getVectorLength(); ++i)
+      OS << ", " << getVectorElt(i);
+    return;
+  case ComplexInt:
+    OS << "ComplexInt: " << getComplexIntReal() << ", " << getComplexIntImag();
+    return;
+  case ComplexFloat:
+    OS << "ComplexFloat: " << GetApproxValue(getComplexFloatReal())
+       << ", " << GetApproxValue(getComplexFloatImag());
+  case LValue:
+    OS << "LValue: <todo>";
+    return;
+  }
+}
+
+Expr* APValue::getLValueBase() const {
+  assert(isLValue() && "Invalid accessor");
+  return ((const LV*)(const void*)Data)->Base;
+}
+
+CharUnits APValue::getLValueOffset() const {
+    assert(isLValue() && "Invalid accessor");
+    return ((const LV*)(const void*)Data)->Offset;
+}
+
+void APValue::setLValue(Expr *B, const CharUnits &O) {
+  assert(isLValue() && "Invalid accessor");
+  ((LV*)(char*)Data)->Base = B;
+  ((LV*)(char*)Data)->Offset = O;
+}
+
+void APValue::MakeLValue() {
+  assert(isUninit() && "Bad state change");
+  new ((void*)(char*)Data) LV();
+  Kind = LValue;
+}
+
diff --git a/lib/AST/ASTConsumer.cpp b/lib/AST/ASTConsumer.cpp
new file mode 100644
index 0000000..f37cbde
--- /dev/null
+++ b/lib/AST/ASTConsumer.cpp
@@ -0,0 +1,19 @@
+//===--- ASTConsumer.cpp - Abstract interface for reading ASTs --*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the ASTConsumer class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/DeclGroup.h"
+using namespace clang;
+
+void ASTConsumer::HandleTopLevelDecl(DeclGroupRef D) {}
+
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
new file mode 100644
index 0000000..165105b
--- /dev/null
+++ b/lib/AST/ASTContext.cpp
@@ -0,0 +1,5124 @@
+//===--- ASTContext.cpp - Context to hold long-lived AST nodes ------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements the ASTContext interface.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/CharUnits.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/TypeLoc.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExternalASTSource.h"
+#include "clang/AST/RecordLayout.h"
+#include "clang/Basic/Builtins.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/TargetInfo.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/raw_ostream.h"
+#include "RecordLayoutBuilder.h"
+
+using namespace clang;
+
+enum FloatingRank {
+  FloatRank, DoubleRank, LongDoubleRank
+};
+
+ASTContext::ASTContext(const LangOptions& LOpts, SourceManager &SM,
+                       const TargetInfo &t,
+                       IdentifierTable &idents, SelectorTable &sels,
+                       Builtin::Context &builtins,
+                       bool FreeMem, unsigned size_reserve) :
+  GlobalNestedNameSpecifier(0), CFConstantStringTypeDecl(0),
+  NSConstantStringTypeDecl(0),
+  ObjCFastEnumerationStateTypeDecl(0), FILEDecl(0), jmp_bufDecl(0),
+  sigjmp_bufDecl(0), BlockDescriptorType(0), BlockDescriptorExtendedType(0),
+  SourceMgr(SM), LangOpts(LOpts), FreeMemory(FreeMem), Target(t),
+  Idents(idents), Selectors(sels),
+  BuiltinInfo(builtins), ExternalSource(0), PrintingPolicy(LOpts),
+  LastSDM(0, 0) {
+  ObjCIdRedefinitionType = QualType();
+  ObjCClassRedefinitionType = QualType();
+  ObjCSelRedefinitionType = QualType();
+  if (size_reserve > 0) Types.reserve(size_reserve);
+  TUDecl = TranslationUnitDecl::Create(*this);
+  InitBuiltinTypes();
+}
+
+ASTContext::~ASTContext() {
+  // Release the DenseMaps associated with DeclContext objects.
+  // FIXME: Is this the ideal solution?
+  ReleaseDeclContextMaps();
+
+  // Release all of the memory associated with overridden C++ methods.
+  for (llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector>::iterator 
+         OM = OverriddenMethods.begin(), OMEnd = OverriddenMethods.end();
+       OM != OMEnd; ++OM)
+    OM->second.Destroy();
+  
+  if (FreeMemory) {
+    // Deallocate all the types.
+    while (!Types.empty()) {
+      Types.back()->Destroy(*this);
+      Types.pop_back();
+    }
+
+    for (llvm::FoldingSet<ExtQuals>::iterator
+         I = ExtQualNodes.begin(), E = ExtQualNodes.end(); I != E; ) {
+      // Increment in loop to prevent using deallocated memory.
+      Deallocate(&*I++);
+    }
+
+    for (llvm::DenseMap<const RecordDecl*, const ASTRecordLayout*>::iterator
+         I = ASTRecordLayouts.begin(), E = ASTRecordLayouts.end(); I != E; ) {
+      // Increment in loop to prevent using deallocated memory.
+      if (ASTRecordLayout *R = const_cast<ASTRecordLayout*>((I++)->second))
+        R->Destroy(*this);
+    }
+
+    for (llvm::DenseMap<const ObjCContainerDecl*,
+         const ASTRecordLayout*>::iterator
+         I = ObjCLayouts.begin(), E = ObjCLayouts.end(); I != E; ) {
+      // Increment in loop to prevent using deallocated memory.
+      if (ASTRecordLayout *R = const_cast<ASTRecordLayout*>((I++)->second))
+        R->Destroy(*this);
+    }
+  }
+
+  // Destroy nested-name-specifiers.
+  for (llvm::FoldingSet<NestedNameSpecifier>::iterator
+         NNS = NestedNameSpecifiers.begin(),
+         NNSEnd = NestedNameSpecifiers.end();
+       NNS != NNSEnd; ) {
+    // Increment in loop to prevent using deallocated memory.
+    (*NNS++).Destroy(*this);
+  }
+
+  if (GlobalNestedNameSpecifier)
+    GlobalNestedNameSpecifier->Destroy(*this);
+
+  TUDecl->Destroy(*this);
+}
+
+void
+ASTContext::setExternalSource(llvm::OwningPtr<ExternalASTSource> &Source) {
+  ExternalSource.reset(Source.take());
+}
+
+void ASTContext::PrintStats() const {
+  fprintf(stderr, "*** AST Context Stats:\n");
+  fprintf(stderr, "  %d types total.\n", (int)Types.size());
+
+  unsigned counts[] = {
+#define TYPE(Name, Parent) 0,
+#define ABSTRACT_TYPE(Name, Parent)
+#include "clang/AST/TypeNodes.def"
+    0 // Extra
+  };
+
+  for (unsigned i = 0, e = Types.size(); i != e; ++i) {
+    Type *T = Types[i];
+    counts[(unsigned)T->getTypeClass()]++;
+  }
+
+  unsigned Idx = 0;
+  unsigned TotalBytes = 0;
+#define TYPE(Name, Parent)                                              \
+  if (counts[Idx])                                                      \
+    fprintf(stderr, "    %d %s types\n", (int)counts[Idx], #Name);      \
+  TotalBytes += counts[Idx] * sizeof(Name##Type);                       \
+  ++Idx;
+#define ABSTRACT_TYPE(Name, Parent)
+#include "clang/AST/TypeNodes.def"
+
+  fprintf(stderr, "Total bytes = %d\n", int(TotalBytes));
+
+  if (ExternalSource.get()) {
+    fprintf(stderr, "\n");
+    ExternalSource->PrintStats();
+  }
+}
+
+
+void ASTContext::InitBuiltinType(CanQualType &R, BuiltinType::Kind K) {
+  BuiltinType *Ty = new (*this, TypeAlignment) BuiltinType(K);
+  R = CanQualType::CreateUnsafe(QualType(Ty, 0));
+  Types.push_back(Ty);
+}
+
+void ASTContext::InitBuiltinTypes() {
+  assert(VoidTy.isNull() && "Context reinitialized?");
+
+  // C99 6.2.5p19.
+  InitBuiltinType(VoidTy,              BuiltinType::Void);
+
+  // C99 6.2.5p2.
+  InitBuiltinType(BoolTy,              BuiltinType::Bool);
+  // C99 6.2.5p3.
+  if (LangOpts.CharIsSigned)
+    InitBuiltinType(CharTy,            BuiltinType::Char_S);
+  else
+    InitBuiltinType(CharTy,            BuiltinType::Char_U);
+  // C99 6.2.5p4.
+  InitBuiltinType(SignedCharTy,        BuiltinType::SChar);
+  InitBuiltinType(ShortTy,             BuiltinType::Short);
+  InitBuiltinType(IntTy,               BuiltinType::Int);
+  InitBuiltinType(LongTy,              BuiltinType::Long);
+  InitBuiltinType(LongLongTy,          BuiltinType::LongLong);
+
+  // C99 6.2.5p6.
+  InitBuiltinType(UnsignedCharTy,      BuiltinType::UChar);
+  InitBuiltinType(UnsignedShortTy,     BuiltinType::UShort);
+  InitBuiltinType(UnsignedIntTy,       BuiltinType::UInt);
+  InitBuiltinType(UnsignedLongTy,      BuiltinType::ULong);
+  InitBuiltinType(UnsignedLongLongTy,  BuiltinType::ULongLong);
+
+  // C99 6.2.5p10.
+  InitBuiltinType(FloatTy,             BuiltinType::Float);
+  InitBuiltinType(DoubleTy,            BuiltinType::Double);
+  InitBuiltinType(LongDoubleTy,        BuiltinType::LongDouble);
+
+  // GNU extension, 128-bit integers.
+  InitBuiltinType(Int128Ty,            BuiltinType::Int128);
+  InitBuiltinType(UnsignedInt128Ty,    BuiltinType::UInt128);
+
+  if (LangOpts.CPlusPlus) // C++ 3.9.1p5
+    InitBuiltinType(WCharTy,           BuiltinType::WChar);
+  else // C99
+    WCharTy = getFromTargetType(Target.getWCharType());
+
+  if (LangOpts.CPlusPlus) // C++0x 3.9.1p5, extension for C++
+    InitBuiltinType(Char16Ty,           BuiltinType::Char16);
+  else // C99
+    Char16Ty = getFromTargetType(Target.getChar16Type());
+
+  if (LangOpts.CPlusPlus) // C++0x 3.9.1p5, extension for C++
+    InitBuiltinType(Char32Ty,           BuiltinType::Char32);
+  else // C99
+    Char32Ty = getFromTargetType(Target.getChar32Type());
+
+  // Placeholder type for functions.
+  InitBuiltinType(OverloadTy,          BuiltinType::Overload);
+
+  // Placeholder type for type-dependent expressions whose type is
+  // completely unknown. No code should ever check a type against
+  // DependentTy and users should never see it; however, it is here to
+  // help diagnose failures to properly check for type-dependent
+  // expressions.
+  InitBuiltinType(DependentTy,         BuiltinType::Dependent);
+
+  // Placeholder type for C++0x auto declarations whose real type has
+  // not yet been deduced.
+  InitBuiltinType(UndeducedAutoTy, BuiltinType::UndeducedAuto);
+
+  // C99 6.2.5p11.
+  FloatComplexTy      = getComplexType(FloatTy);
+  DoubleComplexTy     = getComplexType(DoubleTy);
+  LongDoubleComplexTy = getComplexType(LongDoubleTy);
+
+  BuiltinVaListType = QualType();
+
+  // "Builtin" typedefs set by Sema::ActOnTranslationUnitScope().
+  ObjCIdTypedefType = QualType();
+  ObjCClassTypedefType = QualType();
+  ObjCSelTypedefType = QualType();
+
+  // Builtin types for 'id', 'Class', and 'SEL'.
+  InitBuiltinType(ObjCBuiltinIdTy, BuiltinType::ObjCId);
+  InitBuiltinType(ObjCBuiltinClassTy, BuiltinType::ObjCClass);
+  InitBuiltinType(ObjCBuiltinSelTy, BuiltinType::ObjCSel);
+
+  ObjCConstantStringType = QualType();
+
+  // void * type
+  VoidPtrTy = getPointerType(VoidTy);
+
+  // nullptr type (C++0x 2.14.7)
+  InitBuiltinType(NullPtrTy,           BuiltinType::NullPtr);
+}
+
+MemberSpecializationInfo *
+ASTContext::getInstantiatedFromStaticDataMember(const VarDecl *Var) {
+  assert(Var->isStaticDataMember() && "Not a static data member");
+  llvm::DenseMap<const VarDecl *, MemberSpecializationInfo *>::iterator Pos
+    = InstantiatedFromStaticDataMember.find(Var);
+  if (Pos == InstantiatedFromStaticDataMember.end())
+    return 0;
+
+  return Pos->second;
+}
+
+void
+ASTContext::setInstantiatedFromStaticDataMember(VarDecl *Inst, VarDecl *Tmpl,
+                                                TemplateSpecializationKind TSK) {
+  assert(Inst->isStaticDataMember() && "Not a static data member");
+  assert(Tmpl->isStaticDataMember() && "Not a static data member");
+  assert(!InstantiatedFromStaticDataMember[Inst] &&
+         "Already noted what static data member was instantiated from");
+  InstantiatedFromStaticDataMember[Inst] 
+    = new (*this) MemberSpecializationInfo(Tmpl, TSK);
+}
+
+NamedDecl *
+ASTContext::getInstantiatedFromUsingDecl(UsingDecl *UUD) {
+  llvm::DenseMap<UsingDecl *, NamedDecl *>::const_iterator Pos
+    = InstantiatedFromUsingDecl.find(UUD);
+  if (Pos == InstantiatedFromUsingDecl.end())
+    return 0;
+
+  return Pos->second;
+}
+
+void
+ASTContext::setInstantiatedFromUsingDecl(UsingDecl *Inst, NamedDecl *Pattern) {
+  assert((isa<UsingDecl>(Pattern) ||
+          isa<UnresolvedUsingValueDecl>(Pattern) ||
+          isa<UnresolvedUsingTypenameDecl>(Pattern)) && 
+         "pattern decl is not a using decl");
+  assert(!InstantiatedFromUsingDecl[Inst] && "pattern already exists");
+  InstantiatedFromUsingDecl[Inst] = Pattern;
+}
+
+UsingShadowDecl *
+ASTContext::getInstantiatedFromUsingShadowDecl(UsingShadowDecl *Inst) {
+  llvm::DenseMap<UsingShadowDecl*, UsingShadowDecl*>::const_iterator Pos
+    = InstantiatedFromUsingShadowDecl.find(Inst);
+  if (Pos == InstantiatedFromUsingShadowDecl.end())
+    return 0;
+
+  return Pos->second;
+}
+
+void
+ASTContext::setInstantiatedFromUsingShadowDecl(UsingShadowDecl *Inst,
+                                               UsingShadowDecl *Pattern) {
+  assert(!InstantiatedFromUsingShadowDecl[Inst] && "pattern already exists");
+  InstantiatedFromUsingShadowDecl[Inst] = Pattern;
+}
+
+FieldDecl *ASTContext::getInstantiatedFromUnnamedFieldDecl(FieldDecl *Field) {
+  llvm::DenseMap<FieldDecl *, FieldDecl *>::iterator Pos
+    = InstantiatedFromUnnamedFieldDecl.find(Field);
+  if (Pos == InstantiatedFromUnnamedFieldDecl.end())
+    return 0;
+
+  return Pos->second;
+}
+
+void ASTContext::setInstantiatedFromUnnamedFieldDecl(FieldDecl *Inst,
+                                                     FieldDecl *Tmpl) {
+  assert(!Inst->getDeclName() && "Instantiated field decl is not unnamed");
+  assert(!Tmpl->getDeclName() && "Template field decl is not unnamed");
+  assert(!InstantiatedFromUnnamedFieldDecl[Inst] &&
+         "Already noted what unnamed field was instantiated from");
+
+  InstantiatedFromUnnamedFieldDecl[Inst] = Tmpl;
+}
+
+ASTContext::overridden_cxx_method_iterator
+ASTContext::overridden_methods_begin(const CXXMethodDecl *Method) const {
+  llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector>::const_iterator Pos
+    = OverriddenMethods.find(Method);
+  if (Pos == OverriddenMethods.end())
+    return 0;
+
+  return Pos->second.begin();
+}
+
+ASTContext::overridden_cxx_method_iterator
+ASTContext::overridden_methods_end(const CXXMethodDecl *Method) const {
+  llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector>::const_iterator Pos
+    = OverriddenMethods.find(Method);
+  if (Pos == OverriddenMethods.end())
+    return 0;
+
+  return Pos->second.end();
+}
+
+void ASTContext::addOverriddenMethod(const CXXMethodDecl *Method, 
+                                     const CXXMethodDecl *Overridden) {
+  OverriddenMethods[Method].push_back(Overridden);
+}
+
+namespace {
+  class BeforeInTranslationUnit
+    : std::binary_function<SourceRange, SourceRange, bool> {
+    SourceManager *SourceMgr;
+
+  public:
+    explicit BeforeInTranslationUnit(SourceManager *SM) : SourceMgr(SM) { }
+
+    bool operator()(SourceRange X, SourceRange Y) {
+      return SourceMgr->isBeforeInTranslationUnit(X.getBegin(), Y.getBegin());
+    }
+  };
+}
+
+//===----------------------------------------------------------------------===//
+//                         Type Sizing and Analysis
+//===----------------------------------------------------------------------===//
+
+/// getFloatTypeSemantics - Return the APFloat 'semantics' for the specified
+/// scalar floating point type.
+const llvm::fltSemantics &ASTContext::getFloatTypeSemantics(QualType T) const {
+  const BuiltinType *BT = T->getAs<BuiltinType>();
+  assert(BT && "Not a floating point type!");
+  switch (BT->getKind()) {
+  default: assert(0 && "Not a floating point type!");
+  case BuiltinType::Float:      return Target.getFloatFormat();
+  case BuiltinType::Double:     return Target.getDoubleFormat();
+  case BuiltinType::LongDouble: return Target.getLongDoubleFormat();
+  }
+}
+
+/// getDeclAlign - Return a conservative estimate of the alignment of the
+/// specified decl.  Note that bitfields do not have a valid alignment, so
+/// this method will assert on them.
+/// If @p RefAsPointee, references are treated like their underlying type
+/// (for alignof), else they're treated like pointers (for CodeGen).
+CharUnits ASTContext::getDeclAlign(const Decl *D, bool RefAsPointee) {
+  unsigned Align = Target.getCharWidth();
+
+  if (const AlignedAttr* AA = D->getAttr<AlignedAttr>())
+    Align = std::max(Align, AA->getMaxAlignment());
+
+  if (const ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
+    QualType T = VD->getType();
+    if (const ReferenceType* RT = T->getAs<ReferenceType>()) {
+      if (RefAsPointee)
+        T = RT->getPointeeType();
+      else
+        T = getPointerType(RT->getPointeeType());
+    }
+    if (!T->isIncompleteType() && !T->isFunctionType()) {
+      // Incomplete or function types default to 1.
+      while (isa<VariableArrayType>(T) || isa<IncompleteArrayType>(T))
+        T = cast<ArrayType>(T)->getElementType();
+
+      Align = std::max(Align, getPreferredTypeAlign(T.getTypePtr()));
+    }
+    if (const FieldDecl *FD = dyn_cast<FieldDecl>(VD)) {
+      // In the case of a field in a packed struct, we want the minimum
+      // of the alignment of the field and the alignment of the struct.
+      Align = std::min(Align,
+        getPreferredTypeAlign(FD->getParent()->getTypeForDecl()));
+    }
+  }
+
+  return CharUnits::fromQuantity(Align / Target.getCharWidth());
+}
+
+/// getTypeSize - Return the size of the specified type, in bits.  This method
+/// does not work on incomplete types.
+///
+/// FIXME: Pointers into different addr spaces could have different sizes and
+/// alignment requirements: getPointerInfo should take an AddrSpace, this
+/// should take a QualType, &c.
+std::pair<uint64_t, unsigned>
+ASTContext::getTypeInfo(const Type *T) {
+  uint64_t Width=0;
+  unsigned Align=8;
+  switch (T->getTypeClass()) {
+#define TYPE(Class, Base)
+#define ABSTRACT_TYPE(Class, Base)
+#define NON_CANONICAL_TYPE(Class, Base)
+#define DEPENDENT_TYPE(Class, Base) case Type::Class:
+#include "clang/AST/TypeNodes.def"
+    assert(false && "Should not see dependent types");
+    break;
+
+  case Type::FunctionNoProto:
+  case Type::FunctionProto:
+    // GCC extension: alignof(function) = 32 bits
+    Width = 0;
+    Align = 32;
+    break;
+
+  case Type::IncompleteArray:
+  case Type::VariableArray:
+    Width = 0;
+    Align = getTypeAlign(cast<ArrayType>(T)->getElementType());
+    break;
+
+  case Type::ConstantArray: {
+    const ConstantArrayType *CAT = cast<ConstantArrayType>(T);
+
+    std::pair<uint64_t, unsigned> EltInfo = getTypeInfo(CAT->getElementType());
+    Width = EltInfo.first*CAT->getSize().getZExtValue();
+    Align = EltInfo.second;
+    break;
+  }
+  case Type::ExtVector:
+  case Type::Vector: {
+    const VectorType *VT = cast<VectorType>(T);
+    std::pair<uint64_t, unsigned> EltInfo = getTypeInfo(VT->getElementType());
+    Width = EltInfo.first*VT->getNumElements();
+    Align = Width;
+    // If the alignment is not a power of 2, round up to the next power of 2.
+    // This happens for non-power-of-2 length vectors.
+    if (Align & (Align-1)) {
+      Align = llvm::NextPowerOf2(Align);
+      Width = llvm::RoundUpToAlignment(Width, Align);
+    }
+    break;
+  }
+
+  case Type::Builtin:
+    switch (cast<BuiltinType>(T)->getKind()) {
+    default: assert(0 && "Unknown builtin type!");
+    case BuiltinType::Void:
+      // GCC extension: alignof(void) = 8 bits.
+      Width = 0;
+      Align = 8;
+      break;
+
+    case BuiltinType::Bool:
+      Width = Target.getBoolWidth();
+      Align = Target.getBoolAlign();
+      break;
+    case BuiltinType::Char_S:
+    case BuiltinType::Char_U:
+    case BuiltinType::UChar:
+    case BuiltinType::SChar:
+      Width = Target.getCharWidth();
+      Align = Target.getCharAlign();
+      break;
+    case BuiltinType::WChar:
+      Width = Target.getWCharWidth();
+      Align = Target.getWCharAlign();
+      break;
+    case BuiltinType::Char16:
+      Width = Target.getChar16Width();
+      Align = Target.getChar16Align();
+      break;
+    case BuiltinType::Char32:
+      Width = Target.getChar32Width();
+      Align = Target.getChar32Align();
+      break;
+    case BuiltinType::UShort:
+    case BuiltinType::Short:
+      Width = Target.getShortWidth();
+      Align = Target.getShortAlign();
+      break;
+    case BuiltinType::UInt:
+    case BuiltinType::Int:
+      Width = Target.getIntWidth();
+      Align = Target.getIntAlign();
+      break;
+    case BuiltinType::ULong:
+    case BuiltinType::Long:
+      Width = Target.getLongWidth();
+      Align = Target.getLongAlign();
+      break;
+    case BuiltinType::ULongLong:
+    case BuiltinType::LongLong:
+      Width = Target.getLongLongWidth();
+      Align = Target.getLongLongAlign();
+      break;
+    case BuiltinType::Int128:
+    case BuiltinType::UInt128:
+      Width = 128;
+      Align = 128; // int128_t is 128-bit aligned on all targets.
+      break;
+    case BuiltinType::Float:
+      Width = Target.getFloatWidth();
+      Align = Target.getFloatAlign();
+      break;
+    case BuiltinType::Double:
+      Width = Target.getDoubleWidth();
+      Align = Target.getDoubleAlign();
+      break;
+    case BuiltinType::LongDouble:
+      Width = Target.getLongDoubleWidth();
+      Align = Target.getLongDoubleAlign();
+      break;
+    case BuiltinType::NullPtr:
+      Width = Target.getPointerWidth(0); // C++ 3.9.1p11: sizeof(nullptr_t)
+      Align = Target.getPointerAlign(0); //   == sizeof(void*)
+      break;
+    }
+    break;
+  case Type::ObjCObjectPointer:
+    Width = Target.getPointerWidth(0);
+    Align = Target.getPointerAlign(0);
+    break;
+  case Type::BlockPointer: {
+    unsigned AS = cast<BlockPointerType>(T)->getPointeeType().getAddressSpace();
+    Width = Target.getPointerWidth(AS);
+    Align = Target.getPointerAlign(AS);
+    break;
+  }
+  case Type::LValueReference:
+  case Type::RValueReference: {
+    // alignof and sizeof should never enter this code path here, so we go
+    // the pointer route.
+    unsigned AS = cast<ReferenceType>(T)->getPointeeType().getAddressSpace();
+    Width = Target.getPointerWidth(AS);
+    Align = Target.getPointerAlign(AS);
+    break;
+  }
+  case Type::Pointer: {
+    unsigned AS = cast<PointerType>(T)->getPointeeType().getAddressSpace();
+    Width = Target.getPointerWidth(AS);
+    Align = Target.getPointerAlign(AS);
+    break;
+  }
+  case Type::MemberPointer: {
+    QualType Pointee = cast<MemberPointerType>(T)->getPointeeType();
+    std::pair<uint64_t, unsigned> PtrDiffInfo =
+      getTypeInfo(getPointerDiffType());
+    Width = PtrDiffInfo.first;
+    if (Pointee->isFunctionType())
+      Width *= 2;
+    Align = PtrDiffInfo.second;
+    break;
+  }
+  case Type::Complex: {
+    // Complex types have the same alignment as their elements, but twice the
+    // size.
+    std::pair<uint64_t, unsigned> EltInfo =
+      getTypeInfo(cast<ComplexType>(T)->getElementType());
+    Width = EltInfo.first*2;
+    Align = EltInfo.second;
+    break;
+  }
+  case Type::ObjCInterface: {
+    const ObjCInterfaceType *ObjCI = cast<ObjCInterfaceType>(T);
+    const ASTRecordLayout &Layout = getASTObjCInterfaceLayout(ObjCI->getDecl());
+    Width = Layout.getSize();
+    Align = Layout.getAlignment();
+    break;
+  }
+  case Type::Record:
+  case Type::Enum: {
+    const TagType *TT = cast<TagType>(T);
+
+    if (TT->getDecl()->isInvalidDecl()) {
+      Width = 1;
+      Align = 1;
+      break;
+    }
+
+    if (const EnumType *ET = dyn_cast<EnumType>(TT))
+      return getTypeInfo(ET->getDecl()->getIntegerType());
+
+    const RecordType *RT = cast<RecordType>(TT);
+    const ASTRecordLayout &Layout = getASTRecordLayout(RT->getDecl());
+    Width = Layout.getSize();
+    Align = Layout.getAlignment();
+    break;
+  }
+
+  case Type::SubstTemplateTypeParm:
+    return getTypeInfo(cast<SubstTemplateTypeParmType>(T)->
+                       getReplacementType().getTypePtr());
+
+  case Type::Elaborated:
+    return getTypeInfo(cast<ElaboratedType>(T)->getUnderlyingType()
+                         .getTypePtr());
+
+  case Type::Typedef: {
+    const TypedefDecl *Typedef = cast<TypedefType>(T)->getDecl();
+    if (const AlignedAttr *Aligned = Typedef->getAttr<AlignedAttr>()) {
+      Align = std::max(Aligned->getMaxAlignment(),
+                       getTypeAlign(Typedef->getUnderlyingType().getTypePtr()));
+      Width = getTypeSize(Typedef->getUnderlyingType().getTypePtr());
+    } else
+      return getTypeInfo(Typedef->getUnderlyingType().getTypePtr());
+    break;
+  }
+
+  case Type::TypeOfExpr:
+    return getTypeInfo(cast<TypeOfExprType>(T)->getUnderlyingExpr()->getType()
+                         .getTypePtr());
+
+  case Type::TypeOf:
+    return getTypeInfo(cast<TypeOfType>(T)->getUnderlyingType().getTypePtr());
+
+  case Type::Decltype:
+    return getTypeInfo(cast<DecltypeType>(T)->getUnderlyingExpr()->getType()
+                        .getTypePtr());
+
+  case Type::QualifiedName:
+    return getTypeInfo(cast<QualifiedNameType>(T)->getNamedType().getTypePtr());
+
+  case Type::TemplateSpecialization:
+    assert(getCanonicalType(T) != T &&
+           "Cannot request the size of a dependent type");
+    // FIXME: this is likely to be wrong once we support template
+    // aliases, since a template alias could refer to a typedef that
+    // has an __aligned__ attribute on it.
+    return getTypeInfo(getCanonicalType(T));
+  }
+
+  assert(Align && (Align & (Align-1)) == 0 && "Alignment must be power of 2");
+  return std::make_pair(Width, Align);
+}
+
+/// getTypeSizeInChars - Return the size of the specified type, in characters.
+/// This method does not work on incomplete types.
+CharUnits ASTContext::getTypeSizeInChars(QualType T) {
+  return CharUnits::fromQuantity(getTypeSize(T) / getCharWidth());
+}
+CharUnits ASTContext::getTypeSizeInChars(const Type *T) {
+  return CharUnits::fromQuantity(getTypeSize(T) / getCharWidth());
+}
+
+/// getTypeAlignInChars - Return the ABI-specified alignment of a type, in 
+/// characters. This method does not work on incomplete types.
+CharUnits ASTContext::getTypeAlignInChars(QualType T) {
+  return CharUnits::fromQuantity(getTypeAlign(T) / getCharWidth());
+}
+CharUnits ASTContext::getTypeAlignInChars(const Type *T) {
+  return CharUnits::fromQuantity(getTypeAlign(T) / getCharWidth());
+}
+
+/// getPreferredTypeAlign - Return the "preferred" alignment of the specified
+/// type for the current target in bits.  This can be different than the ABI
+/// alignment in cases where it is beneficial for performance to overalign
+/// a data type.
+unsigned ASTContext::getPreferredTypeAlign(const Type *T) {
+  unsigned ABIAlign = getTypeAlign(T);
+
+  // Double and long long should be naturally aligned if possible.
+  if (const ComplexType* CT = T->getAs<ComplexType>())
+    T = CT->getElementType().getTypePtr();
+  if (T->isSpecificBuiltinType(BuiltinType::Double) ||
+      T->isSpecificBuiltinType(BuiltinType::LongLong))
+    return std::max(ABIAlign, (unsigned)getTypeSize(T));
+
+  return ABIAlign;
+}
+
+static void CollectLocalObjCIvars(ASTContext *Ctx,
+                                  const ObjCInterfaceDecl *OI,
+                                  llvm::SmallVectorImpl<FieldDecl*> &Fields) {
+  for (ObjCInterfaceDecl::ivar_iterator I = OI->ivar_begin(),
+       E = OI->ivar_end(); I != E; ++I) {
+    ObjCIvarDecl *IVDecl = *I;
+    if (!IVDecl->isInvalidDecl())
+      Fields.push_back(cast<FieldDecl>(IVDecl));
+  }
+}
+
+void ASTContext::CollectObjCIvars(const ObjCInterfaceDecl *OI,
+                             llvm::SmallVectorImpl<FieldDecl*> &Fields) {
+  if (const ObjCInterfaceDecl *SuperClass = OI->getSuperClass())
+    CollectObjCIvars(SuperClass, Fields);
+  CollectLocalObjCIvars(this, OI, Fields);
+}
+
+/// ShallowCollectObjCIvars -
+/// Collect all ivars, including those synthesized, in the current class.
+///
+void ASTContext::ShallowCollectObjCIvars(const ObjCInterfaceDecl *OI,
+                                 llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars) {
+  for (ObjCInterfaceDecl::ivar_iterator I = OI->ivar_begin(),
+         E = OI->ivar_end(); I != E; ++I) {
+     Ivars.push_back(*I);
+  }
+
+  CollectNonClassIvars(OI, Ivars);
+}
+
+/// CollectNonClassIvars -
+/// This routine collects all other ivars which are not declared in the class.
+/// This includes synthesized ivars (via @synthesize) and those in
+//  class's @implementation.
+///
+void ASTContext::CollectNonClassIvars(const ObjCInterfaceDecl *OI,
+                                llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars) {
+  // Find ivars declared in class extension.
+  if (const ObjCCategoryDecl *CDecl = OI->getClassExtension()) {
+    for (ObjCCategoryDecl::ivar_iterator I = CDecl->ivar_begin(),
+         E = CDecl->ivar_end(); I != E; ++I) {
+      Ivars.push_back(*I);
+    }
+  }
+
+  // Also add any ivar defined in this class's implementation.  This
+  // includes synthesized ivars.
+  if (ObjCImplementationDecl *ImplDecl = OI->getImplementation()) {
+    for (ObjCImplementationDecl::ivar_iterator I = ImplDecl->ivar_begin(),
+         E = ImplDecl->ivar_end(); I != E; ++I)
+      Ivars.push_back(*I);
+  }
+}
+
+/// CollectInheritedProtocols - Collect all protocols in current class and
+/// those inherited by it.
+void ASTContext::CollectInheritedProtocols(const Decl *CDecl,
+                          llvm::SmallPtrSet<ObjCProtocolDecl*, 8> &Protocols) {
+  if (const ObjCInterfaceDecl *OI = dyn_cast<ObjCInterfaceDecl>(CDecl)) {
+    for (ObjCInterfaceDecl::protocol_iterator P = OI->protocol_begin(),
+         PE = OI->protocol_end(); P != PE; ++P) {
+      ObjCProtocolDecl *Proto = (*P);
+      Protocols.insert(Proto);
+      for (ObjCProtocolDecl::protocol_iterator P = Proto->protocol_begin(),
+           PE = Proto->protocol_end(); P != PE; ++P) {
+        Protocols.insert(*P);
+        CollectInheritedProtocols(*P, Protocols);
+      }
+    }
+    
+    // Categories of this Interface.
+    for (const ObjCCategoryDecl *CDeclChain = OI->getCategoryList(); 
+         CDeclChain; CDeclChain = CDeclChain->getNextClassCategory())
+      CollectInheritedProtocols(CDeclChain, Protocols);
+    if (ObjCInterfaceDecl *SD = OI->getSuperClass())
+      while (SD) {
+        CollectInheritedProtocols(SD, Protocols);
+        SD = SD->getSuperClass();
+      }
+    return;
+  }
+  if (const ObjCCategoryDecl *OC = dyn_cast<ObjCCategoryDecl>(CDecl)) {
+    for (ObjCInterfaceDecl::protocol_iterator P = OC->protocol_begin(),
+         PE = OC->protocol_end(); P != PE; ++P) {
+      ObjCProtocolDecl *Proto = (*P);
+      Protocols.insert(Proto);
+      for (ObjCProtocolDecl::protocol_iterator P = Proto->protocol_begin(),
+           PE = Proto->protocol_end(); P != PE; ++P)
+        CollectInheritedProtocols(*P, Protocols);
+    }
+    return;
+  }
+  if (const ObjCProtocolDecl *OP = dyn_cast<ObjCProtocolDecl>(CDecl)) {
+    for (ObjCProtocolDecl::protocol_iterator P = OP->protocol_begin(),
+         PE = OP->protocol_end(); P != PE; ++P) {
+      ObjCProtocolDecl *Proto = (*P);
+      Protocols.insert(Proto);
+      for (ObjCProtocolDecl::protocol_iterator P = Proto->protocol_begin(),
+           PE = Proto->protocol_end(); P != PE; ++P)
+        CollectInheritedProtocols(*P, Protocols);
+    }
+    return;
+  }
+}
+
+/// CollectIvarsToConstructOrDestruct - Collect those ivars which require
+/// construction (construct=true) or destruction (construct=false)
+///
+void ASTContext::CollectIvarsToConstructOrDestruct(const ObjCInterfaceDecl *OI,
+                                llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars,
+                                bool construct) {
+  if (!getLangOptions().CPlusPlus)
+    return;
+  for (ObjCInterfaceDecl::ivar_iterator I = OI->ivar_begin(),
+       E = OI->ivar_end(); I != E; ++I) {
+    ObjCIvarDecl *Iv = (*I);
+    if (const RecordType *RT = Iv->getType()->getAs<RecordType>()) {
+      if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()))
+        if (construct && !RD->hasTrivialConstructor() ||
+            !construct && !RD->hasTrivialDestructor())
+          Ivars.push_back(*I);
+    }
+  }
+  
+  // Find ivars to construct/destruct in class extension.
+  if (const ObjCCategoryDecl *CDecl = OI->getClassExtension()) {
+    for (ObjCCategoryDecl::ivar_iterator I = CDecl->ivar_begin(),
+         E = CDecl->ivar_end(); I != E; ++I) {
+      ObjCIvarDecl *Iv = (*I);
+      if (const RecordType *RT = Iv->getType()->getAs<RecordType>()) {
+        if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()))
+          if (construct && !RD->hasTrivialConstructor() ||
+              !construct && !RD->hasTrivialDestructor())
+            Ivars.push_back(*I);
+      }
+    }
+  }
+  
+  // Also add any ivar defined in this class's implementation.  This
+  // includes synthesized ivars.
+  if (ObjCImplementationDecl *ImplDecl = OI->getImplementation()) {
+    for (ObjCImplementationDecl::ivar_iterator I = ImplDecl->ivar_begin(),
+         E = ImplDecl->ivar_end(); I != E; ++I) {
+      ObjCIvarDecl *Iv = (*I);
+      if (const RecordType *RT = Iv->getType()->getAs<RecordType>()) {
+        if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()))
+          if (construct && !RD->hasTrivialConstructor() ||
+              !construct && !RD->hasTrivialDestructor())
+            Ivars.push_back(*I);
+      }
+    }
+  }
+}
+
+unsigned ASTContext::CountNonClassIvars(const ObjCInterfaceDecl *OI) {
+  unsigned count = 0;  
+  // Count ivars declared in class extension.
+  if (const ObjCCategoryDecl *CDecl = OI->getClassExtension()) {
+    for (ObjCCategoryDecl::ivar_iterator I = CDecl->ivar_begin(),
+         E = CDecl->ivar_end(); I != E; ++I) {
+      ++count;
+    }
+  }
+  
+  // Count ivar defined in this class's implementation.  This
+  // includes synthesized ivars.
+  if (ObjCImplementationDecl *ImplDecl = OI->getImplementation())
+    for (ObjCImplementationDecl::ivar_iterator I = ImplDecl->ivar_begin(),
+         E = ImplDecl->ivar_end(); I != E; ++I)
+      ++count;
+  return count;
+}
+
+/// \brief Get the implementation of ObjCInterfaceDecl,or NULL if none exists.
+ObjCImplementationDecl *ASTContext::getObjCImplementation(ObjCInterfaceDecl *D) {
+  llvm::DenseMap<ObjCContainerDecl*, ObjCImplDecl*>::iterator
+    I = ObjCImpls.find(D);
+  if (I != ObjCImpls.end())
+    return cast<ObjCImplementationDecl>(I->second);
+  return 0;
+}
+/// \brief Get the implementation of ObjCCategoryDecl, or NULL if none exists.
+ObjCCategoryImplDecl *ASTContext::getObjCImplementation(ObjCCategoryDecl *D) {
+  llvm::DenseMap<ObjCContainerDecl*, ObjCImplDecl*>::iterator
+    I = ObjCImpls.find(D);
+  if (I != ObjCImpls.end())
+    return cast<ObjCCategoryImplDecl>(I->second);
+  return 0;
+}
+
+/// \brief Set the implementation of ObjCInterfaceDecl.
+void ASTContext::setObjCImplementation(ObjCInterfaceDecl *IFaceD,
+                           ObjCImplementationDecl *ImplD) {
+  assert(IFaceD && ImplD && "Passed null params");
+  ObjCImpls[IFaceD] = ImplD;
+}
+/// \brief Set the implementation of ObjCCategoryDecl.
+void ASTContext::setObjCImplementation(ObjCCategoryDecl *CatD,
+                           ObjCCategoryImplDecl *ImplD) {
+  assert(CatD && ImplD && "Passed null params");
+  ObjCImpls[CatD] = ImplD;
+}
+
+/// \brief Allocate an uninitialized TypeSourceInfo.
+///
+/// The caller should initialize the memory held by TypeSourceInfo using
+/// the TypeLoc wrappers.
+///
+/// \param T the type that will be the basis for type source info. This type
+/// should refer to how the declarator was written in source code, not to
+/// what type semantic analysis resolved the declarator to.
+TypeSourceInfo *ASTContext::CreateTypeSourceInfo(QualType T,
+                                                 unsigned DataSize) {
+  if (!DataSize)
+    DataSize = TypeLoc::getFullDataSizeForType(T);
+  else
+    assert(DataSize == TypeLoc::getFullDataSizeForType(T) &&
+           "incorrect data size provided to CreateTypeSourceInfo!");
+
+  TypeSourceInfo *TInfo =
+    (TypeSourceInfo*)BumpAlloc.Allocate(sizeof(TypeSourceInfo) + DataSize, 8);
+  new (TInfo) TypeSourceInfo(T);
+  return TInfo;
+}
+
+TypeSourceInfo *ASTContext::getTrivialTypeSourceInfo(QualType T,
+                                                     SourceLocation L) {
+  TypeSourceInfo *DI = CreateTypeSourceInfo(T);
+  DI->getTypeLoc().initialize(L);
+  return DI;
+}
+
+/// getInterfaceLayoutImpl - Get or compute information about the
+/// layout of the given interface.
+///
+/// \param Impl - If given, also include the layout of the interface's
+/// implementation. This may differ by including synthesized ivars.
+const ASTRecordLayout &
+ASTContext::getObjCLayout(const ObjCInterfaceDecl *D,
+                          const ObjCImplementationDecl *Impl) {
+  assert(!D->isForwardDecl() && "Invalid interface decl!");
+
+  // Look up this layout, if already laid out, return what we have.
+  ObjCContainerDecl *Key =
+    Impl ? (ObjCContainerDecl*) Impl : (ObjCContainerDecl*) D;
+  if (const ASTRecordLayout *Entry = ObjCLayouts[Key])
+    return *Entry;
+
+  // Add in synthesized ivar count if laying out an implementation.
+  if (Impl) {
+    unsigned SynthCount = CountNonClassIvars(D);
+    // If there aren't any sythesized ivars then reuse the interface
+    // entry. Note we can't cache this because we simply free all
+    // entries later; however we shouldn't look up implementations
+    // frequently.
+    if (SynthCount == 0)
+      return getObjCLayout(D, 0);
+  }
+
+  const ASTRecordLayout *NewEntry =
+    ASTRecordLayoutBuilder::ComputeLayout(*this, D, Impl);
+  ObjCLayouts[Key] = NewEntry;
+
+  return *NewEntry;
+}
+
+const ASTRecordLayout &
+ASTContext::getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D) {
+  return getObjCLayout(D, 0);
+}
+
+const ASTRecordLayout &
+ASTContext::getASTObjCImplementationLayout(const ObjCImplementationDecl *D) {
+  return getObjCLayout(D->getClassInterface(), D);
+}
+
+/// getASTRecordLayout - Get or compute information about the layout of the
+/// specified record (struct/union/class), which indicates its size and field
+/// position information.
+const ASTRecordLayout &ASTContext::getASTRecordLayout(const RecordDecl *D) {
+  D = D->getDefinition();
+  assert(D && "Cannot get layout of forward declarations!");
+
+  // Look up this layout, if already laid out, return what we have.
+  // Note that we can't save a reference to the entry because this function
+  // is recursive.
+  const ASTRecordLayout *Entry = ASTRecordLayouts[D];
+  if (Entry) return *Entry;
+
+  const ASTRecordLayout *NewEntry =
+    ASTRecordLayoutBuilder::ComputeLayout(*this, D);
+  ASTRecordLayouts[D] = NewEntry;
+
+  if (getLangOptions().DumpRecordLayouts) {
+    llvm::errs() << "\n*** Dumping AST Record Layout\n";
+    DumpRecordLayout(D, llvm::errs());
+  }
+
+  return *NewEntry;
+}
+
+const CXXMethodDecl *ASTContext::getKeyFunction(const CXXRecordDecl *RD) {
+  RD = cast<CXXRecordDecl>(RD->getDefinition());
+  assert(RD && "Cannot get key function for forward declarations!");
+  
+  const CXXMethodDecl *&Entry = KeyFunctions[RD];
+  if (!Entry) 
+    Entry = ASTRecordLayoutBuilder::ComputeKeyFunction(RD);
+  else
+    assert(Entry == ASTRecordLayoutBuilder::ComputeKeyFunction(RD) &&
+           "Key function changed!");
+  
+  return Entry;
+}
+
+//===----------------------------------------------------------------------===//
+//                   Type creation/memoization methods
+//===----------------------------------------------------------------------===//
+
+QualType ASTContext::getExtQualType(const Type *TypeNode, Qualifiers Quals) {
+  unsigned Fast = Quals.getFastQualifiers();
+  Quals.removeFastQualifiers();
+
+  // Check if we've already instantiated this type.
+  llvm::FoldingSetNodeID ID;
+  ExtQuals::Profile(ID, TypeNode, Quals);
+  void *InsertPos = 0;
+  if (ExtQuals *EQ = ExtQualNodes.FindNodeOrInsertPos(ID, InsertPos)) {
+    assert(EQ->getQualifiers() == Quals);
+    QualType T = QualType(EQ, Fast);
+    return T;
+  }
+
+  ExtQuals *New = new (*this, TypeAlignment) ExtQuals(*this, TypeNode, Quals);
+  ExtQualNodes.InsertNode(New, InsertPos);
+  QualType T = QualType(New, Fast);
+  return T;
+}
+
+QualType ASTContext::getVolatileType(QualType T) {
+  QualType CanT = getCanonicalType(T);
+  if (CanT.isVolatileQualified()) return T;
+
+  QualifierCollector Quals;
+  const Type *TypeNode = Quals.strip(T);
+  Quals.addVolatile();
+
+  return getExtQualType(TypeNode, Quals);
+}
+
+QualType ASTContext::getAddrSpaceQualType(QualType T, unsigned AddressSpace) {
+  QualType CanT = getCanonicalType(T);
+  if (CanT.getAddressSpace() == AddressSpace)
+    return T;
+
+  // If we are composing extended qualifiers together, merge together
+  // into one ExtQuals node.
+  QualifierCollector Quals;
+  const Type *TypeNode = Quals.strip(T);
+
+  // If this type already has an address space specified, it cannot get
+  // another one.
+  assert(!Quals.hasAddressSpace() &&
+         "Type cannot be in multiple addr spaces!");
+  Quals.addAddressSpace(AddressSpace);
+
+  return getExtQualType(TypeNode, Quals);
+}
+
+QualType ASTContext::getObjCGCQualType(QualType T,
+                                       Qualifiers::GC GCAttr) {
+  QualType CanT = getCanonicalType(T);
+  if (CanT.getObjCGCAttr() == GCAttr)
+    return T;
+
+  if (T->isPointerType()) {
+    QualType Pointee = T->getAs<PointerType>()->getPointeeType();
+    if (Pointee->isAnyPointerType()) {
+      QualType ResultType = getObjCGCQualType(Pointee, GCAttr);
+      return getPointerType(ResultType);
+    }
+  }
+
+  // If we are composing extended qualifiers together, merge together
+  // into one ExtQuals node.
+  QualifierCollector Quals;
+  const Type *TypeNode = Quals.strip(T);
+
+  // If this type already has an ObjCGC specified, it cannot get
+  // another one.
+  assert(!Quals.hasObjCGCAttr() &&
+         "Type cannot have multiple ObjCGCs!");
+  Quals.addObjCGCAttr(GCAttr);
+
+  return getExtQualType(TypeNode, Quals);
+}
+
+static QualType getExtFunctionType(ASTContext& Context, QualType T,
+                                        const FunctionType::ExtInfo &Info) {
+  QualType ResultType;
+  if (const PointerType *Pointer = T->getAs<PointerType>()) {
+    QualType Pointee = Pointer->getPointeeType();
+    ResultType = getExtFunctionType(Context, Pointee, Info);
+    if (ResultType == Pointee)
+      return T;
+
+    ResultType = Context.getPointerType(ResultType);
+  } else if (const BlockPointerType *BlockPointer
+                                              = T->getAs<BlockPointerType>()) {
+    QualType Pointee = BlockPointer->getPointeeType();
+    ResultType = getExtFunctionType(Context, Pointee, Info);
+    if (ResultType == Pointee)
+      return T;
+
+    ResultType = Context.getBlockPointerType(ResultType);
+   } else if (const FunctionType *F = T->getAs<FunctionType>()) {
+    if (F->getExtInfo() == Info)
+      return T;
+
+    if (const FunctionNoProtoType *FNPT = dyn_cast<FunctionNoProtoType>(F)) {
+      ResultType = Context.getFunctionNoProtoType(FNPT->getResultType(),
+                                                  Info);
+    } else {
+      const FunctionProtoType *FPT = cast<FunctionProtoType>(F);
+      ResultType
+        = Context.getFunctionType(FPT->getResultType(), FPT->arg_type_begin(),
+                                  FPT->getNumArgs(), FPT->isVariadic(),
+                                  FPT->getTypeQuals(),
+                                  FPT->hasExceptionSpec(),
+                                  FPT->hasAnyExceptionSpec(),
+                                  FPT->getNumExceptions(),
+                                  FPT->exception_begin(),
+                                  Info);
+    }
+  } else
+    return T;
+
+  return Context.getQualifiedType(ResultType, T.getLocalQualifiers());
+}
+
+QualType ASTContext::getNoReturnType(QualType T, bool AddNoReturn) {
+  FunctionType::ExtInfo Info = getFunctionExtInfo(T);
+  return getExtFunctionType(*this, T,
+                                 Info.withNoReturn(AddNoReturn));
+}
+
+QualType ASTContext::getCallConvType(QualType T, CallingConv CallConv) {
+  FunctionType::ExtInfo Info = getFunctionExtInfo(T);
+  return getExtFunctionType(*this, T,
+                            Info.withCallingConv(CallConv));
+}
+
+QualType ASTContext::getRegParmType(QualType T, unsigned RegParm) {
+  FunctionType::ExtInfo Info = getFunctionExtInfo(T);
+  return getExtFunctionType(*this, T,
+                                 Info.withRegParm(RegParm));
+}
+
+/// getComplexType - Return the uniqued reference to the type for a complex
+/// number with the specified element type.
+QualType ASTContext::getComplexType(QualType T) {
+  // Unique pointers, to guarantee there is only one pointer of a particular
+  // structure.
+  llvm::FoldingSetNodeID ID;
+  ComplexType::Profile(ID, T);
+
+  void *InsertPos = 0;
+  if (ComplexType *CT = ComplexTypes.FindNodeOrInsertPos(ID, InsertPos))
+    return QualType(CT, 0);
+
+  // If the pointee type isn't canonical, this won't be a canonical type either,
+  // so fill in the canonical type field.
+  QualType Canonical;
+  if (!T.isCanonical()) {
+    Canonical = getComplexType(getCanonicalType(T));
+
+    // Get the new insert position for the node we care about.
+    ComplexType *NewIP = ComplexTypes.FindNodeOrInsertPos(ID, InsertPos);
+    assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP;
+  }
+  ComplexType *New = new (*this, TypeAlignment) ComplexType(T, Canonical);
+  Types.push_back(New);
+  ComplexTypes.InsertNode(New, InsertPos);
+  return QualType(New, 0);
+}
+
+/// getPointerType - Return the uniqued reference to the type for a pointer to
+/// the specified type.
+QualType ASTContext::getPointerType(QualType T) {
+  // Unique pointers, to guarantee there is only one pointer of a particular
+  // structure.
+  llvm::FoldingSetNodeID ID;
+  PointerType::Profile(ID, T);
+
+  void *InsertPos = 0;
+  if (PointerType *PT = PointerTypes.FindNodeOrInsertPos(ID, InsertPos))
+    return QualType(PT, 0);
+
+  // If the pointee type isn't canonical, this won't be a canonical type either,
+  // so fill in the canonical type field.
+  QualType Canonical;
+  if (!T.isCanonical()) {
+    Canonical = getPointerType(getCanonicalType(T));
+
+    // Get the new insert position for the node we care about.
+    PointerType *NewIP = PointerTypes.FindNodeOrInsertPos(ID, InsertPos);
+    assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP;
+  }
+  PointerType *New = new (*this, TypeAlignment) PointerType(T, Canonical);
+  Types.push_back(New);
+  PointerTypes.InsertNode(New, InsertPos);
+  return QualType(New, 0);
+}
+
+/// getBlockPointerType - Return the uniqued reference to the type for
+/// a pointer to the specified block.
+QualType ASTContext::getBlockPointerType(QualType T) {
+  assert(T->isFunctionType() && "block of function types only");
+  // Unique pointers, to guarantee there is only one block of a particular
+  // structure.
+  llvm::FoldingSetNodeID ID;
+  BlockPointerType::Profile(ID, T);
+
+  void *InsertPos = 0;
+  if (BlockPointerType *PT =
+        BlockPointerTypes.FindNodeOrInsertPos(ID, InsertPos))
+    return QualType(PT, 0);
+
+  // If the block pointee type isn't canonical, this won't be a canonical
+  // type either so fill in the canonical type field.
+  QualType Canonical;
+  if (!T.isCanonical()) {
+    Canonical = getBlockPointerType(getCanonicalType(T));
+
+    // Get the new insert position for the node we care about.
+    BlockPointerType *NewIP =
+      BlockPointerTypes.FindNodeOrInsertPos(ID, InsertPos);
+    assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP;
+  }
+  BlockPointerType *New
+    = new (*this, TypeAlignment) BlockPointerType(T, Canonical);
+  Types.push_back(New);
+  BlockPointerTypes.InsertNode(New, InsertPos);
+  return QualType(New, 0);
+}
+
+/// getLValueReferenceType - Return the uniqued reference to the type for an
+/// lvalue reference to the specified type.
+QualType ASTContext::getLValueReferenceType(QualType T, bool SpelledAsLValue) {
+  // Unique pointers, to guarantee there is only one pointer of a particular
+  // structure.
+  llvm::FoldingSetNodeID ID;
+  ReferenceType::Profile(ID, T, SpelledAsLValue);
+
+  void *InsertPos = 0;
+  if (LValueReferenceType *RT =
+        LValueReferenceTypes.FindNodeOrInsertPos(ID, InsertPos))
+    return QualType(RT, 0);
+
+  const ReferenceType *InnerRef = T->getAs<ReferenceType>();
+
+  // If the referencee type isn't canonical, this won't be a canonical type
+  // either, so fill in the canonical type field.
+  QualType Canonical;
+  if (!SpelledAsLValue || InnerRef || !T.isCanonical()) {
+    QualType PointeeType = (InnerRef ? InnerRef->getPointeeType() : T);
+    Canonical = getLValueReferenceType(getCanonicalType(PointeeType));
+
+    // Get the new insert position for the node we care about.
+    LValueReferenceType *NewIP =
+      LValueReferenceTypes.FindNodeOrInsertPos(ID, InsertPos);
+    assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP;
+  }
+
+  LValueReferenceType *New
+    = new (*this, TypeAlignment) LValueReferenceType(T, Canonical,
+                                                     SpelledAsLValue);
+  Types.push_back(New);
+  LValueReferenceTypes.InsertNode(New, InsertPos);
+
+  return QualType(New, 0);
+}
+
+/// getRValueReferenceType - Return the uniqued reference to the type for an
+/// rvalue reference to the specified type.
+QualType ASTContext::getRValueReferenceType(QualType T) {
+  // Unique pointers, to guarantee there is only one pointer of a particular
+  // structure.
+  llvm::FoldingSetNodeID ID;
+  ReferenceType::Profile(ID, T, false);
+
+  void *InsertPos = 0;
+  if (RValueReferenceType *RT =
+        RValueReferenceTypes.FindNodeOrInsertPos(ID, InsertPos))
+    return QualType(RT, 0);
+
+  const ReferenceType *InnerRef = T->getAs<ReferenceType>();
+
+  // If the referencee type isn't canonical, this won't be a canonical type
+  // either, so fill in the canonical type field.
+  QualType Canonical;
+  if (InnerRef || !T.isCanonical()) {
+    QualType PointeeType = (InnerRef ? InnerRef->getPointeeType() : T);
+    Canonical = getRValueReferenceType(getCanonicalType(PointeeType));
+
+    // Get the new insert position for the node we care about.
+    RValueReferenceType *NewIP =
+      RValueReferenceTypes.FindNodeOrInsertPos(ID, InsertPos);
+    assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP;
+  }
+
+  RValueReferenceType *New
+    = new (*this, TypeAlignment) RValueReferenceType(T, Canonical);
+  Types.push_back(New);
+  RValueReferenceTypes.InsertNode(New, InsertPos);
+  return QualType(New, 0);
+}
+
+/// getMemberPointerType - Return the uniqued reference to the type for a
+/// member pointer to the specified type, in the specified class.
+QualType ASTContext::getMemberPointerType(QualType T, const Type *Cls) {
+  // Unique pointers, to guarantee there is only one pointer of a particular
+  // structure.
+  llvm::FoldingSetNodeID ID;
+  MemberPointerType::Profile(ID, T, Cls);
+
+  void *InsertPos = 0;
+  if (MemberPointerType *PT =
+      MemberPointerTypes.FindNodeOrInsertPos(ID, InsertPos))
+    return QualType(PT, 0);
+
+  // If the pointee or class type isn't canonical, this won't be a canonical
+  // type either, so fill in the canonical type field.
+  QualType Canonical;
+  if (!T.isCanonical() || !Cls->isCanonicalUnqualified()) {
+    Canonical = getMemberPointerType(getCanonicalType(T),getCanonicalType(Cls));
+
+    // Get the new insert position for the node we care about.
+    MemberPointerType *NewIP =
+      MemberPointerTypes.FindNodeOrInsertPos(ID, InsertPos);
+    assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP;
+  }
+  MemberPointerType *New
+    = new (*this, TypeAlignment) MemberPointerType(T, Cls, Canonical);
+  Types.push_back(New);
+  MemberPointerTypes.InsertNode(New, InsertPos);
+  return QualType(New, 0);
+}
+
+/// getConstantArrayType - Return the unique reference to the type for an
+/// array of the specified element type.
+QualType ASTContext::getConstantArrayType(QualType EltTy,
+                                          const llvm::APInt &ArySizeIn,
+                                          ArrayType::ArraySizeModifier ASM,
+                                          unsigned EltTypeQuals) {
+  assert((EltTy->isDependentType() ||
+          EltTy->isIncompleteType() || EltTy->isConstantSizeType()) &&
+         "Constant array of VLAs is illegal!");
+
+  // Convert the array size into a canonical width matching the pointer size for
+  // the target.
+  llvm::APInt ArySize(ArySizeIn);
+  ArySize.zextOrTrunc(Target.getPointerWidth(EltTy.getAddressSpace()));
+
+  llvm::FoldingSetNodeID ID;
+  ConstantArrayType::Profile(ID, EltTy, ArySize, ASM, EltTypeQuals);
+
+  void *InsertPos = 0;
+  if (ConstantArrayType *ATP =
+      ConstantArrayTypes.FindNodeOrInsertPos(ID, InsertPos))
+    return QualType(ATP, 0);
+
+  // If the element type isn't canonical, this won't be a canonical type either,
+  // so fill in the canonical type field.
+  QualType Canonical;
+  if (!EltTy.isCanonical()) {
+    Canonical = getConstantArrayType(getCanonicalType(EltTy), ArySize,
+                                     ASM, EltTypeQuals);
+    // Get the new insert position for the node we care about.
+    ConstantArrayType *NewIP =
+      ConstantArrayTypes.FindNodeOrInsertPos(ID, InsertPos);
+    assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP;
+  }
+
+  ConstantArrayType *New = new(*this,TypeAlignment)
+    ConstantArrayType(EltTy, Canonical, ArySize, ASM, EltTypeQuals);
+  ConstantArrayTypes.InsertNode(New, InsertPos);
+  Types.push_back(New);
+  return QualType(New, 0);
+}
+
+/// getVariableArrayType - Returns a non-unique reference to the type for a
+/// variable array of the specified element type.
+QualType ASTContext::getVariableArrayType(QualType EltTy,
+                                          Expr *NumElts,
+                                          ArrayType::ArraySizeModifier ASM,
+                                          unsigned EltTypeQuals,
+                                          SourceRange Brackets) {
+  // Since we don't unique expressions, it isn't possible to unique VLA's
+  // that have an expression provided for their size.
+
+  VariableArrayType *New = new(*this, TypeAlignment)
+    VariableArrayType(EltTy, QualType(), NumElts, ASM, EltTypeQuals, Brackets);
+
+  VariableArrayTypes.push_back(New);
+  Types.push_back(New);
+  return QualType(New, 0);
+}
+
+/// getDependentSizedArrayType - Returns a non-unique reference to
+/// the type for a dependently-sized array of the specified element
+/// type.
+QualType ASTContext::getDependentSizedArrayType(QualType EltTy,
+                                                Expr *NumElts,
+                                                ArrayType::ArraySizeModifier ASM,
+                                                unsigned EltTypeQuals,
+                                                SourceRange Brackets) {
+  assert((!NumElts || NumElts->isTypeDependent() || 
+          NumElts->isValueDependent()) &&
+         "Size must be type- or value-dependent!");
+
+  void *InsertPos = 0;
+  DependentSizedArrayType *Canon = 0;
+  llvm::FoldingSetNodeID ID;
+
+  if (NumElts) {
+    // Dependently-sized array types that do not have a specified
+    // number of elements will have their sizes deduced from an
+    // initializer.
+    DependentSizedArrayType::Profile(ID, *this, getCanonicalType(EltTy), ASM,
+                                     EltTypeQuals, NumElts);
+
+    Canon = DependentSizedArrayTypes.FindNodeOrInsertPos(ID, InsertPos);
+  }
+
+  DependentSizedArrayType *New;
+  if (Canon) {
+    // We already have a canonical version of this array type; use it as
+    // the canonical type for a newly-built type.
+    New = new (*this, TypeAlignment)
+      DependentSizedArrayType(*this, EltTy, QualType(Canon, 0),
+                              NumElts, ASM, EltTypeQuals, Brackets);
+  } else {
+    QualType CanonEltTy = getCanonicalType(EltTy);
+    if (CanonEltTy == EltTy) {
+      New = new (*this, TypeAlignment)
+        DependentSizedArrayType(*this, EltTy, QualType(),
+                                NumElts, ASM, EltTypeQuals, Brackets);
+
+      if (NumElts) {
+        DependentSizedArrayType *CanonCheck
+          = DependentSizedArrayTypes.FindNodeOrInsertPos(ID, InsertPos);
+        assert(!CanonCheck && "Dependent-sized canonical array type broken");
+        (void)CanonCheck;
+        DependentSizedArrayTypes.InsertNode(New, InsertPos);
+      }
+    } else {
+      QualType Canon = getDependentSizedArrayType(CanonEltTy, NumElts,
+                                                  ASM, EltTypeQuals,
+                                                  SourceRange());
+      New = new (*this, TypeAlignment)
+        DependentSizedArrayType(*this, EltTy, Canon,
+                                NumElts, ASM, EltTypeQuals, Brackets);
+    }
+  }
+
+  Types.push_back(New);
+  return QualType(New, 0);
+}
+
+QualType ASTContext::getIncompleteArrayType(QualType EltTy,
+                                            ArrayType::ArraySizeModifier ASM,
+                                            unsigned EltTypeQuals) {
+  llvm::FoldingSetNodeID ID;
+  IncompleteArrayType::Profile(ID, EltTy, ASM, EltTypeQuals);
+
+  void *InsertPos = 0;
+  if (IncompleteArrayType *ATP =
+       IncompleteArrayTypes.FindNodeOrInsertPos(ID, InsertPos))
+    return QualType(ATP, 0);
+
+  // If the element type isn't canonical, this won't be a canonical type
+  // either, so fill in the canonical type field.
+  QualType Canonical;
+
+  if (!EltTy.isCanonical()) {
+    Canonical = getIncompleteArrayType(getCanonicalType(EltTy),
+                                       ASM, EltTypeQuals);
+
+    // Get the new insert position for the node we care about.
+    IncompleteArrayType *NewIP =
+      IncompleteArrayTypes.FindNodeOrInsertPos(ID, InsertPos);
+    assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP;
+  }
+
+  IncompleteArrayType *New = new (*this, TypeAlignment)
+    IncompleteArrayType(EltTy, Canonical, ASM, EltTypeQuals);
+
+  IncompleteArrayTypes.InsertNode(New, InsertPos);
+  Types.push_back(New);
+  return QualType(New, 0);
+}
+
+/// getVectorType - Return the unique reference to a vector type of
+/// the specified element type and size. VectorType must be a built-in type.
+QualType ASTContext::getVectorType(QualType vecType, unsigned NumElts,
+                                   bool IsAltiVec, bool IsPixel) {
+  BuiltinType *baseType;
+
+  baseType = dyn_cast<BuiltinType>(getCanonicalType(vecType).getTypePtr());
+  assert(baseType != 0 && "getVectorType(): Expecting a built-in type");
+
+  // Check if we've already instantiated a vector of this type.
+  llvm::FoldingSetNodeID ID;
+  VectorType::Profile(ID, vecType, NumElts, Type::Vector,
+    IsAltiVec, IsPixel);
+  void *InsertPos = 0;
+  if (VectorType *VTP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos))
+    return QualType(VTP, 0);
+
+  // If the element type isn't canonical, this won't be a canonical type either,
+  // so fill in the canonical type field.
+  QualType Canonical;
+  if (!vecType.isCanonical() || IsAltiVec || IsPixel) {
+    Canonical = getVectorType(getCanonicalType(vecType),
+      NumElts, false, false);
+
+    // Get the new insert position for the node we care about.
+    VectorType *NewIP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos);
+    assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP;
+  }
+  VectorType *New = new (*this, TypeAlignment)
+    VectorType(vecType, NumElts, Canonical, IsAltiVec, IsPixel);
+  VectorTypes.InsertNode(New, InsertPos);
+  Types.push_back(New);
+  return QualType(New, 0);
+}
+
+/// getExtVectorType - Return the unique reference to an extended vector type of
+/// the specified element type and size. VectorType must be a built-in type.
+QualType ASTContext::getExtVectorType(QualType vecType, unsigned NumElts) {
+  BuiltinType *baseType;
+
+  baseType = dyn_cast<BuiltinType>(getCanonicalType(vecType).getTypePtr());
+  assert(baseType != 0 && "getExtVectorType(): Expecting a built-in type");
+
+  // Check if we've already instantiated a vector of this type.
+  llvm::FoldingSetNodeID ID;
+  VectorType::Profile(ID, vecType, NumElts, Type::ExtVector, false, false);
+  void *InsertPos = 0;
+  if (VectorType *VTP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos))
+    return QualType(VTP, 0);
+
+  // If the element type isn't canonical, this won't be a canonical type either,
+  // so fill in the canonical type field.
+  QualType Canonical;
+  if (!vecType.isCanonical()) {
+    Canonical = getExtVectorType(getCanonicalType(vecType), NumElts);
+
+    // Get the new insert position for the node we care about.
+    VectorType *NewIP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos);
+    assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP;
+  }
+  ExtVectorType *New = new (*this, TypeAlignment)
+    ExtVectorType(vecType, NumElts, Canonical);
+  VectorTypes.InsertNode(New, InsertPos);
+  Types.push_back(New);
+  return QualType(New, 0);
+}
+
+QualType ASTContext::getDependentSizedExtVectorType(QualType vecType,
+                                                    Expr *SizeExpr,
+                                                    SourceLocation AttrLoc) {
+  llvm::FoldingSetNodeID ID;
+  DependentSizedExtVectorType::Profile(ID, *this, getCanonicalType(vecType),
+                                       SizeExpr);
+
+  void *InsertPos = 0;
+  DependentSizedExtVectorType *Canon
+    = DependentSizedExtVectorTypes.FindNodeOrInsertPos(ID, InsertPos);
+  DependentSizedExtVectorType *New;
+  if (Canon) {
+    // We already have a canonical version of this array type; use it as
+    // the canonical type for a newly-built type.
+    New = new (*this, TypeAlignment)
+      DependentSizedExtVectorType(*this, vecType, QualType(Canon, 0),
+                                  SizeExpr, AttrLoc);
+  } else {
+    QualType CanonVecTy = getCanonicalType(vecType);
+    if (CanonVecTy == vecType) {
+      New = new (*this, TypeAlignment)
+        DependentSizedExtVectorType(*this, vecType, QualType(), SizeExpr,
+                                    AttrLoc);
+
+      DependentSizedExtVectorType *CanonCheck
+        = DependentSizedExtVectorTypes.FindNodeOrInsertPos(ID, InsertPos);
+      assert(!CanonCheck && "Dependent-sized ext_vector canonical type broken");
+      (void)CanonCheck;
+      DependentSizedExtVectorTypes.InsertNode(New, InsertPos);
+    } else {
+      QualType Canon = getDependentSizedExtVectorType(CanonVecTy, SizeExpr,
+                                                      SourceLocation());
+      New = new (*this, TypeAlignment) 
+        DependentSizedExtVectorType(*this, vecType, Canon, SizeExpr, AttrLoc);
+    }
+  }
+
+  Types.push_back(New);
+  return QualType(New, 0);
+}
+
+/// getFunctionNoProtoType - Return a K&R style C function type like 'int()'.
+///
+QualType ASTContext::getFunctionNoProtoType(QualType ResultTy,
+                                            const FunctionType::ExtInfo &Info) {
+  const CallingConv CallConv = Info.getCC();
+  // Unique functions, to guarantee there is only one function of a particular
+  // structure.
+  llvm::FoldingSetNodeID ID;
+  FunctionNoProtoType::Profile(ID, ResultTy, Info);
+
+  void *InsertPos = 0;
+  if (FunctionNoProtoType *FT =
+        FunctionNoProtoTypes.FindNodeOrInsertPos(ID, InsertPos))
+    return QualType(FT, 0);
+
+  QualType Canonical;
+  if (!ResultTy.isCanonical() ||
+      getCanonicalCallConv(CallConv) != CallConv) {
+    Canonical =
+      getFunctionNoProtoType(getCanonicalType(ResultTy),
+                     Info.withCallingConv(getCanonicalCallConv(CallConv)));
+
+    // Get the new insert position for the node we care about.
+    FunctionNoProtoType *NewIP =
+      FunctionNoProtoTypes.FindNodeOrInsertPos(ID, InsertPos);
+    assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP;
+  }
+
+  FunctionNoProtoType *New = new (*this, TypeAlignment)
+    FunctionNoProtoType(ResultTy, Canonical, Info);
+  Types.push_back(New);
+  FunctionNoProtoTypes.InsertNode(New, InsertPos);
+  return QualType(New, 0);
+}
+
+/// getFunctionType - Return a normal function type with a typed argument
+/// list.  isVariadic indicates whether the argument list includes '...'.
+QualType ASTContext::getFunctionType(QualType ResultTy,const QualType *ArgArray,
+                                     unsigned NumArgs, bool isVariadic,
+                                     unsigned TypeQuals, bool hasExceptionSpec,
+                                     bool hasAnyExceptionSpec, unsigned NumExs,
+                                     const QualType *ExArray,
+                                     const FunctionType::ExtInfo &Info) {
+  const CallingConv CallConv= Info.getCC();
+  // Unique functions, to guarantee there is only one function of a particular
+  // structure.
+  llvm::FoldingSetNodeID ID;
+  FunctionProtoType::Profile(ID, ResultTy, ArgArray, NumArgs, isVariadic,
+                             TypeQuals, hasExceptionSpec, hasAnyExceptionSpec,
+                             NumExs, ExArray, Info);
+
+  void *InsertPos = 0;
+  if (FunctionProtoType *FTP =
+        FunctionProtoTypes.FindNodeOrInsertPos(ID, InsertPos))
+    return QualType(FTP, 0);
+
+  // Determine whether the type being created is already canonical or not.
+  bool isCanonical = !hasExceptionSpec && ResultTy.isCanonical();
+  for (unsigned i = 0; i != NumArgs && isCanonical; ++i)
+    if (!ArgArray[i].isCanonicalAsParam())
+      isCanonical = false;
+
+  // If this type isn't canonical, get the canonical version of it.
+  // The exception spec is not part of the canonical type.
+  QualType Canonical;
+  if (!isCanonical || getCanonicalCallConv(CallConv) != CallConv) {
+    llvm::SmallVector<QualType, 16> CanonicalArgs;
+    CanonicalArgs.reserve(NumArgs);
+    for (unsigned i = 0; i != NumArgs; ++i)
+      CanonicalArgs.push_back(getCanonicalParamType(ArgArray[i]));
+
+    Canonical = getFunctionType(getCanonicalType(ResultTy),
+                                CanonicalArgs.data(), NumArgs,
+                                isVariadic, TypeQuals, false,
+                                false, 0, 0,
+                     Info.withCallingConv(getCanonicalCallConv(CallConv)));
+
+    // Get the new insert position for the node we care about.
+    FunctionProtoType *NewIP =
+      FunctionProtoTypes.FindNodeOrInsertPos(ID, InsertPos);
+    assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP;
+  }
+
+  // FunctionProtoType objects are allocated with extra bytes after them
+  // for two variable size arrays (for parameter and exception types) at the
+  // end of them.
+  FunctionProtoType *FTP =
+    (FunctionProtoType*)Allocate(sizeof(FunctionProtoType) +
+                                 NumArgs*sizeof(QualType) +
+                                 NumExs*sizeof(QualType), TypeAlignment);
+  new (FTP) FunctionProtoType(ResultTy, ArgArray, NumArgs, isVariadic,
+                              TypeQuals, hasExceptionSpec, hasAnyExceptionSpec,
+                              ExArray, NumExs, Canonical, Info);
+  Types.push_back(FTP);
+  FunctionProtoTypes.InsertNode(FTP, InsertPos);
+  return QualType(FTP, 0);
+}
+
+#ifndef NDEBUG
+static bool NeedsInjectedClassNameType(const RecordDecl *D) {
+  if (!isa<CXXRecordDecl>(D)) return false;
+  const CXXRecordDecl *RD = cast<CXXRecordDecl>(D);
+  if (isa<ClassTemplatePartialSpecializationDecl>(RD))
+    return true;
+  if (RD->getDescribedClassTemplate() &&
+      !isa<ClassTemplateSpecializationDecl>(RD))
+    return true;
+  return false;
+}
+#endif
+
+/// getInjectedClassNameType - Return the unique reference to the
+/// injected class name type for the specified templated declaration.
+QualType ASTContext::getInjectedClassNameType(CXXRecordDecl *Decl,
+                                              QualType TST) {
+  assert(NeedsInjectedClassNameType(Decl));
+  if (Decl->TypeForDecl) {
+    assert(isa<InjectedClassNameType>(Decl->TypeForDecl));
+  } else if (CXXRecordDecl *PrevDecl
+               = cast_or_null<CXXRecordDecl>(Decl->getPreviousDeclaration())) {
+    assert(PrevDecl->TypeForDecl && "previous declaration has no type");
+    Decl->TypeForDecl = PrevDecl->TypeForDecl;
+    assert(isa<InjectedClassNameType>(Decl->TypeForDecl));
+  } else {
+    Decl->TypeForDecl =
+      new (*this, TypeAlignment) InjectedClassNameType(Decl, TST);
+    Types.push_back(Decl->TypeForDecl);
+  }
+  return QualType(Decl->TypeForDecl, 0);
+}
+
+/// getTypeDeclType - Return the unique reference to the type for the
+/// specified type declaration.
+QualType ASTContext::getTypeDeclTypeSlow(const TypeDecl *Decl) {
+  assert(Decl && "Passed null for Decl param");
+  assert(!Decl->TypeForDecl && "TypeForDecl present in slow case");
+
+  if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(Decl))
+    return getTypedefType(Typedef);
+
+  if (const ObjCInterfaceDecl *ObjCInterface
+               = dyn_cast<ObjCInterfaceDecl>(Decl))
+    return getObjCInterfaceType(ObjCInterface);
+
+  assert(!isa<TemplateTypeParmDecl>(Decl) &&
+         "Template type parameter types are always available.");
+
+  if (const RecordDecl *Record = dyn_cast<RecordDecl>(Decl)) {
+    assert(!Record->getPreviousDeclaration() &&
+           "struct/union has previous declaration");
+    assert(!NeedsInjectedClassNameType(Record));
+    Decl->TypeForDecl = new (*this, TypeAlignment) RecordType(Record);
+  } else if (const EnumDecl *Enum = dyn_cast<EnumDecl>(Decl)) {
+    assert(!Enum->getPreviousDeclaration() &&
+           "enum has previous declaration");
+    Decl->TypeForDecl = new (*this, TypeAlignment) EnumType(Enum);
+  } else if (const UnresolvedUsingTypenameDecl *Using =
+               dyn_cast<UnresolvedUsingTypenameDecl>(Decl)) {
+    Decl->TypeForDecl = new (*this, TypeAlignment) UnresolvedUsingType(Using);
+  } else
+    llvm_unreachable("TypeDecl without a type?");
+
+  Types.push_back(Decl->TypeForDecl);
+  return QualType(Decl->TypeForDecl, 0);
+}
+
+/// getTypedefType - Return the unique reference to the type for the
+/// specified typename decl.
+QualType ASTContext::getTypedefType(const TypedefDecl *Decl) {
+  if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0);
+
+  QualType Canonical = getCanonicalType(Decl->getUnderlyingType());
+  Decl->TypeForDecl = new(*this, TypeAlignment)
+    TypedefType(Type::Typedef, Decl, Canonical);
+  Types.push_back(Decl->TypeForDecl);
+  return QualType(Decl->TypeForDecl, 0);
+}
+
+/// \brief Retrieve a substitution-result type.
+QualType
+ASTContext::getSubstTemplateTypeParmType(const TemplateTypeParmType *Parm,
+                                         QualType Replacement) {
+  assert(Replacement.isCanonical()
+         && "replacement types must always be canonical");
+
+  llvm::FoldingSetNodeID ID;
+  SubstTemplateTypeParmType::Profile(ID, Parm, Replacement);
+  void *InsertPos = 0;
+  SubstTemplateTypeParmType *SubstParm
+    = SubstTemplateTypeParmTypes.FindNodeOrInsertPos(ID, InsertPos);
+
+  if (!SubstParm) {
+    SubstParm = new (*this, TypeAlignment)
+      SubstTemplateTypeParmType(Parm, Replacement);
+    Types.push_back(SubstParm);
+    SubstTemplateTypeParmTypes.InsertNode(SubstParm, InsertPos);
+  }
+
+  return QualType(SubstParm, 0);
+}
+
+/// \brief Retrieve the template type parameter type for a template
+/// parameter or parameter pack with the given depth, index, and (optionally)
+/// name.
+QualType ASTContext::getTemplateTypeParmType(unsigned Depth, unsigned Index,
+                                             bool ParameterPack,
+                                             IdentifierInfo *Name) {
+  llvm::FoldingSetNodeID ID;
+  TemplateTypeParmType::Profile(ID, Depth, Index, ParameterPack, Name);
+  void *InsertPos = 0;
+  TemplateTypeParmType *TypeParm
+    = TemplateTypeParmTypes.FindNodeOrInsertPos(ID, InsertPos);
+
+  if (TypeParm)
+    return QualType(TypeParm, 0);
+
+  if (Name) {
+    QualType Canon = getTemplateTypeParmType(Depth, Index, ParameterPack);
+    TypeParm = new (*this, TypeAlignment)
+      TemplateTypeParmType(Depth, Index, ParameterPack, Name, Canon);
+
+    TemplateTypeParmType *TypeCheck 
+      = TemplateTypeParmTypes.FindNodeOrInsertPos(ID, InsertPos);
+    assert(!TypeCheck && "Template type parameter canonical type broken");
+    (void)TypeCheck;
+  } else
+    TypeParm = new (*this, TypeAlignment)
+      TemplateTypeParmType(Depth, Index, ParameterPack);
+
+  Types.push_back(TypeParm);
+  TemplateTypeParmTypes.InsertNode(TypeParm, InsertPos);
+
+  return QualType(TypeParm, 0);
+}
+
+TypeSourceInfo *
+ASTContext::getTemplateSpecializationTypeInfo(TemplateName Name,
+                                              SourceLocation NameLoc,
+                                        const TemplateArgumentListInfo &Args,
+                                              QualType CanonType) {
+  QualType TST = getTemplateSpecializationType(Name, Args, CanonType);
+
+  TypeSourceInfo *DI = CreateTypeSourceInfo(TST);
+  TemplateSpecializationTypeLoc TL
+    = cast<TemplateSpecializationTypeLoc>(DI->getTypeLoc());
+  TL.setTemplateNameLoc(NameLoc);
+  TL.setLAngleLoc(Args.getLAngleLoc());
+  TL.setRAngleLoc(Args.getRAngleLoc());
+  for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i)
+    TL.setArgLocInfo(i, Args[i].getLocInfo());
+  return DI;
+}
+
+QualType
+ASTContext::getTemplateSpecializationType(TemplateName Template,
+                                          const TemplateArgumentListInfo &Args,
+                                          QualType Canon,
+                                          bool IsCurrentInstantiation) {
+  unsigned NumArgs = Args.size();
+
+  llvm::SmallVector<TemplateArgument, 4> ArgVec;
+  ArgVec.reserve(NumArgs);
+  for (unsigned i = 0; i != NumArgs; ++i)
+    ArgVec.push_back(Args[i].getArgument());
+
+  return getTemplateSpecializationType(Template, ArgVec.data(), NumArgs,
+                                       Canon, IsCurrentInstantiation);
+}
+
+QualType
+ASTContext::getTemplateSpecializationType(TemplateName Template,
+                                          const TemplateArgument *Args,
+                                          unsigned NumArgs,
+                                          QualType Canon,
+                                          bool IsCurrentInstantiation) {
+  if (!Canon.isNull())
+    Canon = getCanonicalType(Canon);
+  else {
+    assert(!IsCurrentInstantiation &&
+           "current-instantiation specializations should always "
+           "have a canonical type");
+
+    // Build the canonical template specialization type.
+    TemplateName CanonTemplate = getCanonicalTemplateName(Template);
+    llvm::SmallVector<TemplateArgument, 4> CanonArgs;
+    CanonArgs.reserve(NumArgs);
+    for (unsigned I = 0; I != NumArgs; ++I)
+      CanonArgs.push_back(getCanonicalTemplateArgument(Args[I]));
+
+    // Determine whether this canonical template specialization type already
+    // exists.
+    llvm::FoldingSetNodeID ID;
+    TemplateSpecializationType::Profile(ID, CanonTemplate, false,
+                                        CanonArgs.data(), NumArgs, *this);
+
+    void *InsertPos = 0;
+    TemplateSpecializationType *Spec
+      = TemplateSpecializationTypes.FindNodeOrInsertPos(ID, InsertPos);
+
+    if (!Spec) {
+      // Allocate a new canonical template specialization type.
+      void *Mem = Allocate((sizeof(TemplateSpecializationType) +
+                            sizeof(TemplateArgument) * NumArgs),
+                           TypeAlignment);
+      Spec = new (Mem) TemplateSpecializationType(*this, CanonTemplate, false,
+                                                  CanonArgs.data(), NumArgs,
+                                                  Canon);
+      Types.push_back(Spec);
+      TemplateSpecializationTypes.InsertNode(Spec, InsertPos);
+    }
+
+    if (Canon.isNull())
+      Canon = QualType(Spec, 0);
+    assert(Canon->isDependentType() &&
+           "Non-dependent template-id type must have a canonical type");
+  }
+
+  // Allocate the (non-canonical) template specialization type, but don't
+  // try to unique it: these types typically have location information that
+  // we don't unique and don't want to lose.
+  void *Mem = Allocate((sizeof(TemplateSpecializationType) +
+                        sizeof(TemplateArgument) * NumArgs),
+                       TypeAlignment);
+  TemplateSpecializationType *Spec
+    = new (Mem) TemplateSpecializationType(*this, Template,
+                                           IsCurrentInstantiation,
+                                           Args, NumArgs,
+                                           Canon);
+
+  Types.push_back(Spec);
+  return QualType(Spec, 0);
+}
+
+QualType
+ASTContext::getQualifiedNameType(NestedNameSpecifier *NNS,
+                                 QualType NamedType) {
+  llvm::FoldingSetNodeID ID;
+  QualifiedNameType::Profile(ID, NNS, NamedType);
+
+  void *InsertPos = 0;
+  QualifiedNameType *T
+    = QualifiedNameTypes.FindNodeOrInsertPos(ID, InsertPos);
+  if (T)
+    return QualType(T, 0);
+
+  QualType Canon = NamedType;
+  if (!Canon.isCanonical()) {
+    Canon = getCanonicalType(NamedType);
+    QualifiedNameType *CheckT
+      = QualifiedNameTypes.FindNodeOrInsertPos(ID, InsertPos);
+    assert(!CheckT && "Qualified name canonical type broken");
+    (void)CheckT;
+  }
+
+  T = new (*this) QualifiedNameType(NNS, NamedType, Canon);
+  Types.push_back(T);
+  QualifiedNameTypes.InsertNode(T, InsertPos);
+  return QualType(T, 0);
+}
+
+QualType ASTContext::getDependentNameType(ElaboratedTypeKeyword Keyword,
+                                          NestedNameSpecifier *NNS,
+                                          const IdentifierInfo *Name,
+                                          QualType Canon) {
+  assert(NNS->isDependent() && "nested-name-specifier must be dependent");
+
+  if (Canon.isNull()) {
+    NestedNameSpecifier *CanonNNS = getCanonicalNestedNameSpecifier(NNS);
+    ElaboratedTypeKeyword CanonKeyword = Keyword;
+    if (Keyword == ETK_None)
+      CanonKeyword = ETK_Typename;
+    
+    if (CanonNNS != NNS || CanonKeyword != Keyword)
+      Canon = getDependentNameType(CanonKeyword, CanonNNS, Name);
+  }
+
+  llvm::FoldingSetNodeID ID;
+  DependentNameType::Profile(ID, Keyword, NNS, Name);
+
+  void *InsertPos = 0;
+  DependentNameType *T
+    = DependentNameTypes.FindNodeOrInsertPos(ID, InsertPos);
+  if (T)
+    return QualType(T, 0);
+
+  T = new (*this) DependentNameType(Keyword, NNS, Name, Canon);
+  Types.push_back(T);
+  DependentNameTypes.InsertNode(T, InsertPos);
+  return QualType(T, 0);
+}
+
+QualType
+ASTContext::getDependentNameType(ElaboratedTypeKeyword Keyword,
+                                 NestedNameSpecifier *NNS,
+                                 const TemplateSpecializationType *TemplateId,
+                                 QualType Canon) {
+  assert(NNS->isDependent() && "nested-name-specifier must be dependent");
+
+  llvm::FoldingSetNodeID ID;
+  DependentNameType::Profile(ID, Keyword, NNS, TemplateId);
+
+  void *InsertPos = 0;
+  DependentNameType *T
+    = DependentNameTypes.FindNodeOrInsertPos(ID, InsertPos);
+  if (T)
+    return QualType(T, 0);
+
+  if (Canon.isNull()) {
+    NestedNameSpecifier *CanonNNS = getCanonicalNestedNameSpecifier(NNS);
+    QualType CanonType = getCanonicalType(QualType(TemplateId, 0));
+    ElaboratedTypeKeyword CanonKeyword = Keyword;
+    if (Keyword == ETK_None)
+      CanonKeyword = ETK_Typename;
+    if (CanonNNS != NNS || CanonKeyword != Keyword ||
+        CanonType != QualType(TemplateId, 0)) {
+      const TemplateSpecializationType *CanonTemplateId
+        = CanonType->getAs<TemplateSpecializationType>();
+      assert(CanonTemplateId &&
+             "Canonical type must also be a template specialization type");
+      Canon = getDependentNameType(CanonKeyword, CanonNNS, CanonTemplateId);
+    }
+
+    DependentNameType *CheckT
+      = DependentNameTypes.FindNodeOrInsertPos(ID, InsertPos);
+    assert(!CheckT && "Typename canonical type is broken"); (void)CheckT;
+  }
+
+  T = new (*this) DependentNameType(Keyword, NNS, TemplateId, Canon);
+  Types.push_back(T);
+  DependentNameTypes.InsertNode(T, InsertPos);
+  return QualType(T, 0);
+}
+
+QualType
+ASTContext::getElaboratedType(QualType UnderlyingType,
+                              ElaboratedType::TagKind Tag) {
+  llvm::FoldingSetNodeID ID;
+  ElaboratedType::Profile(ID, UnderlyingType, Tag);
+
+  void *InsertPos = 0;
+  ElaboratedType *T = ElaboratedTypes.FindNodeOrInsertPos(ID, InsertPos);
+  if (T)
+    return QualType(T, 0);
+
+  QualType Canon = UnderlyingType;
+  if (!Canon.isCanonical()) {
+    Canon = getCanonicalType(Canon);
+    ElaboratedType *CheckT = ElaboratedTypes.FindNodeOrInsertPos(ID, InsertPos);
+    assert(!CheckT && "Elaborated canonical type is broken"); (void)CheckT;
+  }
+
+  T = new (*this) ElaboratedType(UnderlyingType, Tag, Canon);
+  Types.push_back(T);
+  ElaboratedTypes.InsertNode(T, InsertPos);
+  return QualType(T, 0);
+}
+
+/// CmpProtocolNames - Comparison predicate for sorting protocols
+/// alphabetically.
+static bool CmpProtocolNames(const ObjCProtocolDecl *LHS,
+                            const ObjCProtocolDecl *RHS) {
+  return LHS->getDeclName() < RHS->getDeclName();
+}
+
+static bool areSortedAndUniqued(ObjCProtocolDecl **Protocols,
+                                unsigned NumProtocols) {
+  if (NumProtocols == 0) return true;
+
+  for (unsigned i = 1; i != NumProtocols; ++i)
+    if (!CmpProtocolNames(Protocols[i-1], Protocols[i]))
+      return false;
+  return true;
+}
+
+static void SortAndUniqueProtocols(ObjCProtocolDecl **Protocols,
+                                   unsigned &NumProtocols) {
+  ObjCProtocolDecl **ProtocolsEnd = Protocols+NumProtocols;
+
+  // Sort protocols, keyed by name.
+  std::sort(Protocols, Protocols+NumProtocols, CmpProtocolNames);
+
+  // Remove duplicates.
+  ProtocolsEnd = std::unique(Protocols, ProtocolsEnd);
+  NumProtocols = ProtocolsEnd-Protocols;
+}
+
+/// getObjCObjectPointerType - Return a ObjCObjectPointerType type for
+/// the given interface decl and the conforming protocol list.
+QualType ASTContext::getObjCObjectPointerType(QualType InterfaceT,
+                                              ObjCProtocolDecl **Protocols,
+                                              unsigned NumProtocols,
+                                              unsigned Quals) {
+  llvm::FoldingSetNodeID ID;
+  ObjCObjectPointerType::Profile(ID, InterfaceT, Protocols, NumProtocols);
+  Qualifiers Qs = Qualifiers::fromCVRMask(Quals);
+
+  void *InsertPos = 0;
+  if (ObjCObjectPointerType *QT =
+              ObjCObjectPointerTypes.FindNodeOrInsertPos(ID, InsertPos))
+    return getQualifiedType(QualType(QT, 0), Qs);
+
+  // Sort the protocol list alphabetically to canonicalize it.
+  QualType Canonical;
+  if (!InterfaceT.isCanonical() || 
+      !areSortedAndUniqued(Protocols, NumProtocols)) {
+    if (!areSortedAndUniqued(Protocols, NumProtocols)) {
+      llvm::SmallVector<ObjCProtocolDecl*, 8> Sorted(NumProtocols);
+      unsigned UniqueCount = NumProtocols;
+
+      std::copy(Protocols, Protocols + NumProtocols, Sorted.begin());
+      SortAndUniqueProtocols(&Sorted[0], UniqueCount);
+
+      Canonical = getObjCObjectPointerType(getCanonicalType(InterfaceT),
+                                           &Sorted[0], UniqueCount);
+    } else {
+      Canonical = getObjCObjectPointerType(getCanonicalType(InterfaceT),
+                                           Protocols, NumProtocols);
+    }
+
+    // Regenerate InsertPos.
+    ObjCObjectPointerTypes.FindNodeOrInsertPos(ID, InsertPos);
+  }
+
+  // No match.
+  unsigned Size = sizeof(ObjCObjectPointerType) 
+                + NumProtocols * sizeof(ObjCProtocolDecl *);
+  void *Mem = Allocate(Size, TypeAlignment);
+  ObjCObjectPointerType *QType = new (Mem) ObjCObjectPointerType(Canonical, 
+                                                                 InterfaceT, 
+                                                                 Protocols,
+                                                                 NumProtocols);
+
+  Types.push_back(QType);
+  ObjCObjectPointerTypes.InsertNode(QType, InsertPos);
+  return getQualifiedType(QualType(QType, 0), Qs);
+}
+
+/// getObjCInterfaceType - Return the unique reference to the type for the
+/// specified ObjC interface decl. The list of protocols is optional.
+QualType ASTContext::getObjCInterfaceType(const ObjCInterfaceDecl *Decl,
+                       ObjCProtocolDecl **Protocols, unsigned NumProtocols) {
+  llvm::FoldingSetNodeID ID;
+  ObjCInterfaceType::Profile(ID, Decl, Protocols, NumProtocols);
+
+  void *InsertPos = 0;
+  if (ObjCInterfaceType *QT =
+      ObjCInterfaceTypes.FindNodeOrInsertPos(ID, InsertPos))
+    return QualType(QT, 0);
+
+  // Sort the protocol list alphabetically to canonicalize it.
+  QualType Canonical;
+  if (NumProtocols && !areSortedAndUniqued(Protocols, NumProtocols)) {
+    llvm::SmallVector<ObjCProtocolDecl*, 8> Sorted(NumProtocols);
+    std::copy(Protocols, Protocols + NumProtocols, Sorted.begin());
+
+    unsigned UniqueCount = NumProtocols;
+    SortAndUniqueProtocols(&Sorted[0], UniqueCount);
+
+    Canonical = getObjCInterfaceType(Decl, &Sorted[0], UniqueCount);
+
+    ObjCInterfaceTypes.FindNodeOrInsertPos(ID, InsertPos);
+  }
+
+  unsigned Size = sizeof(ObjCInterfaceType) 
+    + NumProtocols * sizeof(ObjCProtocolDecl *);
+  void *Mem = Allocate(Size, TypeAlignment);
+  ObjCInterfaceType *QType = new (Mem) ObjCInterfaceType(Canonical, 
+                                        const_cast<ObjCInterfaceDecl*>(Decl),
+                                                         Protocols, 
+                                                         NumProtocols);
+
+  Types.push_back(QType);
+  ObjCInterfaceTypes.InsertNode(QType, InsertPos);
+  return QualType(QType, 0);
+}
+
+/// getTypeOfExprType - Unlike many "get<Type>" functions, we can't unique
+/// TypeOfExprType AST's (since expression's are never shared). For example,
+/// multiple declarations that refer to "typeof(x)" all contain different
+/// DeclRefExpr's. This doesn't effect the type checker, since it operates
+/// on canonical type's (which are always unique).
+QualType ASTContext::getTypeOfExprType(Expr *tofExpr) {
+  TypeOfExprType *toe;
+  if (tofExpr->isTypeDependent()) {
+    llvm::FoldingSetNodeID ID;
+    DependentTypeOfExprType::Profile(ID, *this, tofExpr);
+
+    void *InsertPos = 0;
+    DependentTypeOfExprType *Canon
+      = DependentTypeOfExprTypes.FindNodeOrInsertPos(ID, InsertPos);
+    if (Canon) {
+      // We already have a "canonical" version of an identical, dependent
+      // typeof(expr) type. Use that as our canonical type.
+      toe = new (*this, TypeAlignment) TypeOfExprType(tofExpr,
+                                          QualType((TypeOfExprType*)Canon, 0));
+    }
+    else {
+      // Build a new, canonical typeof(expr) type.
+      Canon
+        = new (*this, TypeAlignment) DependentTypeOfExprType(*this, tofExpr);
+      DependentTypeOfExprTypes.InsertNode(Canon, InsertPos);
+      toe = Canon;
+    }
+  } else {
+    QualType Canonical = getCanonicalType(tofExpr->getType());
+    toe = new (*this, TypeAlignment) TypeOfExprType(tofExpr, Canonical);
+  }
+  Types.push_back(toe);
+  return QualType(toe, 0);
+}
+
+/// getTypeOfType -  Unlike many "get<Type>" functions, we don't unique
+/// TypeOfType AST's. The only motivation to unique these nodes would be
+/// memory savings. Since typeof(t) is fairly uncommon, space shouldn't be
+/// an issue. This doesn't effect the type checker, since it operates
+/// on canonical type's (which are always unique).
+QualType ASTContext::getTypeOfType(QualType tofType) {
+  QualType Canonical = getCanonicalType(tofType);
+  TypeOfType *tot = new (*this, TypeAlignment) TypeOfType(tofType, Canonical);
+  Types.push_back(tot);
+  return QualType(tot, 0);
+}
+
+/// getDecltypeForExpr - Given an expr, will return the decltype for that
+/// expression, according to the rules in C++0x [dcl.type.simple]p4
+static QualType getDecltypeForExpr(const Expr *e, ASTContext &Context) {
+  if (e->isTypeDependent())
+    return Context.DependentTy;
+
+  // If e is an id expression or a class member access, decltype(e) is defined
+  // as the type of the entity named by e.
+  if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(e)) {
+    if (const ValueDecl *VD = dyn_cast<ValueDecl>(DRE->getDecl()))
+      return VD->getType();
+  }
+  if (const MemberExpr *ME = dyn_cast<MemberExpr>(e)) {
+    if (const FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl()))
+      return FD->getType();
+  }
+  // If e is a function call or an invocation of an overloaded operator,
+  // (parentheses around e are ignored), decltype(e) is defined as the
+  // return type of that function.
+  if (const CallExpr *CE = dyn_cast<CallExpr>(e->IgnoreParens()))
+    return CE->getCallReturnType();
+
+  QualType T = e->getType();
+
+  // Otherwise, where T is the type of e, if e is an lvalue, decltype(e) is
+  // defined as T&, otherwise decltype(e) is defined as T.
+  if (e->isLvalue(Context) == Expr::LV_Valid)
+    T = Context.getLValueReferenceType(T);
+
+  return T;
+}
+
+/// getDecltypeType -  Unlike many "get<Type>" functions, we don't unique
+/// DecltypeType AST's. The only motivation to unique these nodes would be
+/// memory savings. Since decltype(t) is fairly uncommon, space shouldn't be
+/// an issue. This doesn't effect the type checker, since it operates
+/// on canonical type's (which are always unique).
+QualType ASTContext::getDecltypeType(Expr *e) {
+  DecltypeType *dt;
+  if (e->isTypeDependent()) {
+    llvm::FoldingSetNodeID ID;
+    DependentDecltypeType::Profile(ID, *this, e);
+
+    void *InsertPos = 0;
+    DependentDecltypeType *Canon
+      = DependentDecltypeTypes.FindNodeOrInsertPos(ID, InsertPos);
+    if (Canon) {
+      // We already have a "canonical" version of an equivalent, dependent
+      // decltype type. Use that as our canonical type.
+      dt = new (*this, TypeAlignment) DecltypeType(e, DependentTy,
+                                       QualType((DecltypeType*)Canon, 0));
+    }
+    else {
+      // Build a new, canonical typeof(expr) type.
+      Canon = new (*this, TypeAlignment) DependentDecltypeType(*this, e);
+      DependentDecltypeTypes.InsertNode(Canon, InsertPos);
+      dt = Canon;
+    }
+  } else {
+    QualType T = getDecltypeForExpr(e, *this);
+    dt = new (*this, TypeAlignment) DecltypeType(e, T, getCanonicalType(T));
+  }
+  Types.push_back(dt);
+  return QualType(dt, 0);
+}
+
+/// getTagDeclType - Return the unique reference to the type for the
+/// specified TagDecl (struct/union/class/enum) decl.
+QualType ASTContext::getTagDeclType(const TagDecl *Decl) {
+  assert (Decl);
+  // FIXME: What is the design on getTagDeclType when it requires casting
+  // away const?  mutable?
+  return getTypeDeclType(const_cast<TagDecl*>(Decl));
+}
+
+/// getSizeType - Return the unique type for "size_t" (C99 7.17), the result
+/// of the sizeof operator (C99 6.5.3.4p4). The value is target dependent and
+/// needs to agree with the definition in <stddef.h>.
+CanQualType ASTContext::getSizeType() const {
+  return getFromTargetType(Target.getSizeType());
+}
+
+/// getSignedWCharType - Return the type of "signed wchar_t".
+/// Used when in C++, as a GCC extension.
+QualType ASTContext::getSignedWCharType() const {
+  // FIXME: derive from "Target" ?
+  return WCharTy;
+}
+
+/// getUnsignedWCharType - Return the type of "unsigned wchar_t".
+/// Used when in C++, as a GCC extension.
+QualType ASTContext::getUnsignedWCharType() const {
+  // FIXME: derive from "Target" ?
+  return UnsignedIntTy;
+}
+
+/// getPointerDiffType - Return the unique type for "ptrdiff_t" (ref?)
+/// defined in <stddef.h>. Pointer - pointer requires this (C99 6.5.6p9).
+QualType ASTContext::getPointerDiffType() const {
+  return getFromTargetType(Target.getPtrDiffType(0));
+}
+
+//===----------------------------------------------------------------------===//
+//                              Type Operators
+//===----------------------------------------------------------------------===//
+
+CanQualType ASTContext::getCanonicalParamType(QualType T) {
+  // Push qualifiers into arrays, and then discard any remaining
+  // qualifiers.
+  T = getCanonicalType(T);
+  const Type *Ty = T.getTypePtr();
+
+  QualType Result;
+  if (isa<ArrayType>(Ty)) {
+    Result = getArrayDecayedType(QualType(Ty,0));
+  } else if (isa<FunctionType>(Ty)) {
+    Result = getPointerType(QualType(Ty, 0));
+  } else {
+    Result = QualType(Ty, 0);
+  }
+
+  return CanQualType::CreateUnsafe(Result);
+}
+
+/// getCanonicalType - Return the canonical (structural) type corresponding to
+/// the specified potentially non-canonical type.  The non-canonical version
+/// of a type may have many "decorated" versions of types.  Decorators can
+/// include typedefs, 'typeof' operators, etc. The returned type is guaranteed
+/// to be free of any of these, allowing two canonical types to be compared
+/// for exact equality with a simple pointer comparison.
+CanQualType ASTContext::getCanonicalType(QualType T) {
+  QualifierCollector Quals;
+  const Type *Ptr = Quals.strip(T);
+  QualType CanType = Ptr->getCanonicalTypeInternal();
+
+  // The canonical internal type will be the canonical type *except*
+  // that we push type qualifiers down through array types.
+
+  // If there are no new qualifiers to push down, stop here.
+  if (!Quals.hasQualifiers())
+    return CanQualType::CreateUnsafe(CanType);
+
+  // If the type qualifiers are on an array type, get the canonical
+  // type of the array with the qualifiers applied to the element
+  // type.
+  ArrayType *AT = dyn_cast<ArrayType>(CanType);
+  if (!AT)
+    return CanQualType::CreateUnsafe(getQualifiedType(CanType, Quals));
+
+  // Get the canonical version of the element with the extra qualifiers on it.
+  // This can recursively sink qualifiers through multiple levels of arrays.
+  QualType NewEltTy = getQualifiedType(AT->getElementType(), Quals);
+  NewEltTy = getCanonicalType(NewEltTy);
+
+  if (ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(AT))
+    return CanQualType::CreateUnsafe(
+             getConstantArrayType(NewEltTy, CAT->getSize(),
+                                  CAT->getSizeModifier(),
+                                  CAT->getIndexTypeCVRQualifiers()));
+  if (IncompleteArrayType *IAT = dyn_cast<IncompleteArrayType>(AT))
+    return CanQualType::CreateUnsafe(
+             getIncompleteArrayType(NewEltTy, IAT->getSizeModifier(),
+                                    IAT->getIndexTypeCVRQualifiers()));
+
+  if (DependentSizedArrayType *DSAT = dyn_cast<DependentSizedArrayType>(AT))
+    return CanQualType::CreateUnsafe(
+             getDependentSizedArrayType(NewEltTy,
+                                        DSAT->getSizeExpr() ?
+                                          DSAT->getSizeExpr()->Retain() : 0,
+                                        DSAT->getSizeModifier(),
+                                        DSAT->getIndexTypeCVRQualifiers(),
+                        DSAT->getBracketsRange())->getCanonicalTypeInternal());
+
+  VariableArrayType *VAT = cast<VariableArrayType>(AT);
+  return CanQualType::CreateUnsafe(getVariableArrayType(NewEltTy,
+                                                        VAT->getSizeExpr() ?
+                                              VAT->getSizeExpr()->Retain() : 0,
+                                                        VAT->getSizeModifier(),
+                                              VAT->getIndexTypeCVRQualifiers(),
+                                                     VAT->getBracketsRange()));
+}
+
+QualType ASTContext::getUnqualifiedArrayType(QualType T,
+                                             Qualifiers &Quals) {
+  Quals = T.getQualifiers();
+  if (!isa<ArrayType>(T)) {
+    return T.getUnqualifiedType();
+  }
+
+  const ArrayType *AT = cast<ArrayType>(T);
+  QualType Elt = AT->getElementType();
+  QualType UnqualElt = getUnqualifiedArrayType(Elt, Quals);
+  if (Elt == UnqualElt)
+    return T;
+
+  if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(T)) {
+    return getConstantArrayType(UnqualElt, CAT->getSize(),
+                                CAT->getSizeModifier(), 0);
+  }
+
+  if (const IncompleteArrayType *IAT = dyn_cast<IncompleteArrayType>(T)) {
+    return getIncompleteArrayType(UnqualElt, IAT->getSizeModifier(), 0);
+  }
+
+  const DependentSizedArrayType *DSAT = cast<DependentSizedArrayType>(T);
+  return getDependentSizedArrayType(UnqualElt, DSAT->getSizeExpr()->Retain(),
+                                    DSAT->getSizeModifier(), 0,
+                                    SourceRange());
+}
+
+DeclarationName ASTContext::getNameForTemplate(TemplateName Name) {
+  if (TemplateDecl *TD = Name.getAsTemplateDecl())
+    return TD->getDeclName();
+  
+  if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) {
+    if (DTN->isIdentifier()) {
+      return DeclarationNames.getIdentifier(DTN->getIdentifier());
+    } else {
+      return DeclarationNames.getCXXOperatorName(DTN->getOperator());
+    }
+  }
+
+  OverloadedTemplateStorage *Storage = Name.getAsOverloadedTemplate();
+  assert(Storage);
+  return (*Storage->begin())->getDeclName();
+}
+
+TemplateName ASTContext::getCanonicalTemplateName(TemplateName Name) {
+  // If this template name refers to a template, the canonical
+  // template name merely stores the template itself.
+  if (TemplateDecl *Template = Name.getAsTemplateDecl())
+    return TemplateName(cast<TemplateDecl>(Template->getCanonicalDecl()));
+
+  assert(!Name.getAsOverloadedTemplate());
+
+  DependentTemplateName *DTN = Name.getAsDependentTemplateName();
+  assert(DTN && "Non-dependent template names must refer to template decls.");
+  return DTN->CanonicalTemplateName;
+}
+
+bool ASTContext::hasSameTemplateName(TemplateName X, TemplateName Y) {
+  X = getCanonicalTemplateName(X);
+  Y = getCanonicalTemplateName(Y);
+  return X.getAsVoidPointer() == Y.getAsVoidPointer();
+}
+
+TemplateArgument
+ASTContext::getCanonicalTemplateArgument(const TemplateArgument &Arg) {
+  switch (Arg.getKind()) {
+    case TemplateArgument::Null:
+      return Arg;
+
+    case TemplateArgument::Expression:
+      return Arg;
+
+    case TemplateArgument::Declaration:
+      return TemplateArgument(Arg.getAsDecl()->getCanonicalDecl());
+
+    case TemplateArgument::Template:
+      return TemplateArgument(getCanonicalTemplateName(Arg.getAsTemplate()));
+      
+    case TemplateArgument::Integral:
+      return TemplateArgument(*Arg.getAsIntegral(),
+                              getCanonicalType(Arg.getIntegralType()));
+
+    case TemplateArgument::Type:
+      return TemplateArgument(getCanonicalType(Arg.getAsType()));
+
+    case TemplateArgument::Pack: {
+      // FIXME: Allocate in ASTContext
+      TemplateArgument *CanonArgs = new TemplateArgument[Arg.pack_size()];
+      unsigned Idx = 0;
+      for (TemplateArgument::pack_iterator A = Arg.pack_begin(),
+                                        AEnd = Arg.pack_end();
+           A != AEnd; (void)++A, ++Idx)
+        CanonArgs[Idx] = getCanonicalTemplateArgument(*A);
+
+      TemplateArgument Result;
+      Result.setArgumentPack(CanonArgs, Arg.pack_size(), false);
+      return Result;
+    }
+  }
+
+  // Silence GCC warning
+  assert(false && "Unhandled template argument kind");
+  return TemplateArgument();
+}
+
+NestedNameSpecifier *
+ASTContext::getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS) {
+  if (!NNS)
+    return 0;
+
+  switch (NNS->getKind()) {
+  case NestedNameSpecifier::Identifier:
+    // Canonicalize the prefix but keep the identifier the same.
+    return NestedNameSpecifier::Create(*this,
+                         getCanonicalNestedNameSpecifier(NNS->getPrefix()),
+                                       NNS->getAsIdentifier());
+
+  case NestedNameSpecifier::Namespace:
+    // A namespace is canonical; build a nested-name-specifier with
+    // this namespace and no prefix.
+    return NestedNameSpecifier::Create(*this, 0, NNS->getAsNamespace());
+
+  case NestedNameSpecifier::TypeSpec:
+  case NestedNameSpecifier::TypeSpecWithTemplate: {
+    QualType T = getCanonicalType(QualType(NNS->getAsType(), 0));
+    return NestedNameSpecifier::Create(*this, 0,
+                 NNS->getKind() == NestedNameSpecifier::TypeSpecWithTemplate,
+                                       T.getTypePtr());
+  }
+
+  case NestedNameSpecifier::Global:
+    // The global specifier is canonical and unique.
+    return NNS;
+  }
+
+  // Required to silence a GCC warning
+  return 0;
+}
+
+
+const ArrayType *ASTContext::getAsArrayType(QualType T) {
+  // Handle the non-qualified case efficiently.
+  if (!T.hasLocalQualifiers()) {
+    // Handle the common positive case fast.
+    if (const ArrayType *AT = dyn_cast<ArrayType>(T))
+      return AT;
+  }
+
+  // Handle the common negative case fast.
+  QualType CType = T->getCanonicalTypeInternal();
+  if (!isa<ArrayType>(CType))
+    return 0;
+
+  // Apply any qualifiers from the array type to the element type.  This
+  // implements C99 6.7.3p8: "If the specification of an array type includes
+  // any type qualifiers, the element type is so qualified, not the array type."
+
+  // If we get here, we either have type qualifiers on the type, or we have
+  // sugar such as a typedef in the way.  If we have type qualifiers on the type
+  // we must propagate them down into the element type.
+
+  QualifierCollector Qs;
+  const Type *Ty = Qs.strip(T.getDesugaredType());
+
+  // If we have a simple case, just return now.
+  const ArrayType *ATy = dyn_cast<ArrayType>(Ty);
+  if (ATy == 0 || Qs.empty())
+    return ATy;
+
+  // Otherwise, we have an array and we have qualifiers on it.  Push the
+  // qualifiers into the array element type and return a new array type.
+  // Get the canonical version of the element with the extra qualifiers on it.
+  // This can recursively sink qualifiers through multiple levels of arrays.
+  QualType NewEltTy = getQualifiedType(ATy->getElementType(), Qs);
+
+  if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(ATy))
+    return cast<ArrayType>(getConstantArrayType(NewEltTy, CAT->getSize(),
+                                                CAT->getSizeModifier(),
+                                           CAT->getIndexTypeCVRQualifiers()));
+  if (const IncompleteArrayType *IAT = dyn_cast<IncompleteArrayType>(ATy))
+    return cast<ArrayType>(getIncompleteArrayType(NewEltTy,
+                                                  IAT->getSizeModifier(),
+                                           IAT->getIndexTypeCVRQualifiers()));
+
+  if (const DependentSizedArrayType *DSAT
+        = dyn_cast<DependentSizedArrayType>(ATy))
+    return cast<ArrayType>(
+                     getDependentSizedArrayType(NewEltTy,
+                                                DSAT->getSizeExpr() ?
+                                              DSAT->getSizeExpr()->Retain() : 0,
+                                                DSAT->getSizeModifier(),
+                                              DSAT->getIndexTypeCVRQualifiers(),
+                                                DSAT->getBracketsRange()));
+
+  const VariableArrayType *VAT = cast<VariableArrayType>(ATy);
+  return cast<ArrayType>(getVariableArrayType(NewEltTy,
+                                              VAT->getSizeExpr() ?
+                                              VAT->getSizeExpr()->Retain() : 0,
+                                              VAT->getSizeModifier(),
+                                              VAT->getIndexTypeCVRQualifiers(),
+                                              VAT->getBracketsRange()));
+}
+
+
+/// getArrayDecayedType - Return the properly qualified result of decaying the
+/// specified array type to a pointer.  This operation is non-trivial when
+/// handling typedefs etc.  The canonical type of "T" must be an array type,
+/// this returns a pointer to a properly qualified element of the array.
+///
+/// See C99 6.7.5.3p7 and C99 6.3.2.1p3.
+QualType ASTContext::getArrayDecayedType(QualType Ty) {
+  // Get the element type with 'getAsArrayType' so that we don't lose any
+  // typedefs in the element type of the array.  This also handles propagation
+  // of type qualifiers from the array type into the element type if present
+  // (C99 6.7.3p8).
+  const ArrayType *PrettyArrayType = getAsArrayType(Ty);
+  assert(PrettyArrayType && "Not an array type!");
+
+  QualType PtrTy = getPointerType(PrettyArrayType->getElementType());
+
+  // int x[restrict 4] ->  int *restrict
+  return getQualifiedType(PtrTy, PrettyArrayType->getIndexTypeQualifiers());
+}
+
+QualType ASTContext::getBaseElementType(QualType QT) {
+  QualifierCollector Qs;
+  while (true) {
+    const Type *UT = Qs.strip(QT);
+    if (const ArrayType *AT = getAsArrayType(QualType(UT,0))) {
+      QT = AT->getElementType();
+    } else {
+      return Qs.apply(QT);
+    }
+  }
+}
+
+QualType ASTContext::getBaseElementType(const ArrayType *AT) {
+  QualType ElemTy = AT->getElementType();
+
+  if (const ArrayType *AT = getAsArrayType(ElemTy))
+    return getBaseElementType(AT);
+
+  return ElemTy;
+}
+
+/// getConstantArrayElementCount - Returns number of constant array elements.
+uint64_t
+ASTContext::getConstantArrayElementCount(const ConstantArrayType *CA)  const {
+  uint64_t ElementCount = 1;
+  do {
+    ElementCount *= CA->getSize().getZExtValue();
+    CA = dyn_cast<ConstantArrayType>(CA->getElementType());
+  } while (CA);
+  return ElementCount;
+}
+
+/// getFloatingRank - Return a relative rank for floating point types.
+/// This routine will assert if passed a built-in type that isn't a float.
+static FloatingRank getFloatingRank(QualType T) {
+  if (const ComplexType *CT = T->getAs<ComplexType>())
+    return getFloatingRank(CT->getElementType());
+
+  assert(T->getAs<BuiltinType>() && "getFloatingRank(): not a floating type");
+  switch (T->getAs<BuiltinType>()->getKind()) {
+  default: assert(0 && "getFloatingRank(): not a floating type");
+  case BuiltinType::Float:      return FloatRank;
+  case BuiltinType::Double:     return DoubleRank;
+  case BuiltinType::LongDouble: return LongDoubleRank;
+  }
+}
+
+/// getFloatingTypeOfSizeWithinDomain - Returns a real floating
+/// point or a complex type (based on typeDomain/typeSize).
+/// 'typeDomain' is a real floating point or complex type.
+/// 'typeSize' is a real floating point or complex type.
+QualType ASTContext::getFloatingTypeOfSizeWithinDomain(QualType Size,
+                                                       QualType Domain) const {
+  FloatingRank EltRank = getFloatingRank(Size);
+  if (Domain->isComplexType()) {
+    switch (EltRank) {
+    default: assert(0 && "getFloatingRank(): illegal value for rank");
+    case FloatRank:      return FloatComplexTy;
+    case DoubleRank:     return DoubleComplexTy;
+    case LongDoubleRank: return LongDoubleComplexTy;
+    }
+  }
+
+  assert(Domain->isRealFloatingType() && "Unknown domain!");
+  switch (EltRank) {
+  default: assert(0 && "getFloatingRank(): illegal value for rank");
+  case FloatRank:      return FloatTy;
+  case DoubleRank:     return DoubleTy;
+  case LongDoubleRank: return LongDoubleTy;
+  }
+}
+
+/// getFloatingTypeOrder - Compare the rank of the two specified floating
+/// point types, ignoring the domain of the type (i.e. 'double' ==
+/// '_Complex double').  If LHS > RHS, return 1.  If LHS == RHS, return 0. If
+/// LHS < RHS, return -1.
+int ASTContext::getFloatingTypeOrder(QualType LHS, QualType RHS) {
+  FloatingRank LHSR = getFloatingRank(LHS);
+  FloatingRank RHSR = getFloatingRank(RHS);
+
+  if (LHSR == RHSR)
+    return 0;
+  if (LHSR > RHSR)
+    return 1;
+  return -1;
+}
+
+/// getIntegerRank - Return an integer conversion rank (C99 6.3.1.1p1). This
+/// routine will assert if passed a built-in type that isn't an integer or enum,
+/// or if it is not canonicalized.
+unsigned ASTContext::getIntegerRank(Type *T) {
+  assert(T->isCanonicalUnqualified() && "T should be canonicalized");
+  if (EnumType* ET = dyn_cast<EnumType>(T))
+    T = ET->getDecl()->getPromotionType().getTypePtr();
+
+  if (T->isSpecificBuiltinType(BuiltinType::WChar))
+    T = getFromTargetType(Target.getWCharType()).getTypePtr();
+
+  if (T->isSpecificBuiltinType(BuiltinType::Char16))
+    T = getFromTargetType(Target.getChar16Type()).getTypePtr();
+
+  if (T->isSpecificBuiltinType(BuiltinType::Char32))
+    T = getFromTargetType(Target.getChar32Type()).getTypePtr();
+
+  switch (cast<BuiltinType>(T)->getKind()) {
+  default: assert(0 && "getIntegerRank(): not a built-in integer");
+  case BuiltinType::Bool:
+    return 1 + (getIntWidth(BoolTy) << 3);
+  case BuiltinType::Char_S:
+  case BuiltinType::Char_U:
+  case BuiltinType::SChar:
+  case BuiltinType::UChar:
+    return 2 + (getIntWidth(CharTy) << 3);
+  case BuiltinType::Short:
+  case BuiltinType::UShort:
+    return 3 + (getIntWidth(ShortTy) << 3);
+  case BuiltinType::Int:
+  case BuiltinType::UInt:
+    return 4 + (getIntWidth(IntTy) << 3);
+  case BuiltinType::Long:
+  case BuiltinType::ULong:
+    return 5 + (getIntWidth(LongTy) << 3);
+  case BuiltinType::LongLong:
+  case BuiltinType::ULongLong:
+    return 6 + (getIntWidth(LongLongTy) << 3);
+  case BuiltinType::Int128:
+  case BuiltinType::UInt128:
+    return 7 + (getIntWidth(Int128Ty) << 3);
+  }
+}
+
+/// \brief Whether this is a promotable bitfield reference according
+/// to C99 6.3.1.1p2, bullet 2 (and GCC extensions).
+///
+/// \returns the type this bit-field will promote to, or NULL if no
+/// promotion occurs.
+QualType ASTContext::isPromotableBitField(Expr *E) {
+  FieldDecl *Field = E->getBitField();
+  if (!Field)
+    return QualType();
+
+  QualType FT = Field->getType();
+
+  llvm::APSInt BitWidthAP = Field->getBitWidth()->EvaluateAsInt(*this);
+  uint64_t BitWidth = BitWidthAP.getZExtValue();
+  uint64_t IntSize = getTypeSize(IntTy);
+  // GCC extension compatibility: if the bit-field size is less than or equal
+  // to the size of int, it gets promoted no matter what its type is.
+  // For instance, unsigned long bf : 4 gets promoted to signed int.
+  if (BitWidth < IntSize)
+    return IntTy;
+
+  if (BitWidth == IntSize)
+    return FT->isSignedIntegerType() ? IntTy : UnsignedIntTy;
+
+  // Types bigger than int are not subject to promotions, and therefore act
+  // like the base type.
+  // FIXME: This doesn't quite match what gcc does, but what gcc does here
+  // is ridiculous.
+  return QualType();
+}
+
+/// getPromotedIntegerType - Returns the type that Promotable will
+/// promote to: C99 6.3.1.1p2, assuming that Promotable is a promotable
+/// integer type.
+QualType ASTContext::getPromotedIntegerType(QualType Promotable) {
+  assert(!Promotable.isNull());
+  assert(Promotable->isPromotableIntegerType());
+  if (const EnumType *ET = Promotable->getAs<EnumType>())
+    return ET->getDecl()->getPromotionType();
+  if (Promotable->isSignedIntegerType())
+    return IntTy;
+  uint64_t PromotableSize = getTypeSize(Promotable);
+  uint64_t IntSize = getTypeSize(IntTy);
+  assert(Promotable->isUnsignedIntegerType() && PromotableSize <= IntSize);
+  return (PromotableSize != IntSize) ? IntTy : UnsignedIntTy;
+}
+
+/// getIntegerTypeOrder - Returns the highest ranked integer type:
+/// C99 6.3.1.8p1.  If LHS > RHS, return 1.  If LHS == RHS, return 0. If
+/// LHS < RHS, return -1.
+int ASTContext::getIntegerTypeOrder(QualType LHS, QualType RHS) {
+  Type *LHSC = getCanonicalType(LHS).getTypePtr();
+  Type *RHSC = getCanonicalType(RHS).getTypePtr();
+  if (LHSC == RHSC) return 0;
+
+  bool LHSUnsigned = LHSC->isUnsignedIntegerType();
+  bool RHSUnsigned = RHSC->isUnsignedIntegerType();
+
+  unsigned LHSRank = getIntegerRank(LHSC);
+  unsigned RHSRank = getIntegerRank(RHSC);
+
+  if (LHSUnsigned == RHSUnsigned) {  // Both signed or both unsigned.
+    if (LHSRank == RHSRank) return 0;
+    return LHSRank > RHSRank ? 1 : -1;
+  }
+
+  // Otherwise, the LHS is signed and the RHS is unsigned or visa versa.
+  if (LHSUnsigned) {
+    // If the unsigned [LHS] type is larger, return it.
+    if (LHSRank >= RHSRank)
+      return 1;
+
+    // If the signed type can represent all values of the unsigned type, it
+    // wins.  Because we are dealing with 2's complement and types that are
+    // powers of two larger than each other, this is always safe.
+    return -1;
+  }
+
+  // If the unsigned [RHS] type is larger, return it.
+  if (RHSRank >= LHSRank)
+    return -1;
+
+  // If the signed type can represent all values of the unsigned type, it
+  // wins.  Because we are dealing with 2's complement and types that are
+  // powers of two larger than each other, this is always safe.
+  return 1;
+}
+
+static RecordDecl *
+CreateRecordDecl(ASTContext &Ctx, RecordDecl::TagKind TK, DeclContext *DC,
+                 SourceLocation L, IdentifierInfo *Id) {
+  if (Ctx.getLangOptions().CPlusPlus)
+    return CXXRecordDecl::Create(Ctx, TK, DC, L, Id);
+  else
+    return RecordDecl::Create(Ctx, TK, DC, L, Id);
+}
+                                    
+// getCFConstantStringType - Return the type used for constant CFStrings.
+QualType ASTContext::getCFConstantStringType() {
+  if (!CFConstantStringTypeDecl) {
+    CFConstantStringTypeDecl =
+      CreateRecordDecl(*this, TagDecl::TK_struct, TUDecl, SourceLocation(),
+                       &Idents.get("NSConstantString"));
+    CFConstantStringTypeDecl->startDefinition();
+
+    QualType FieldTypes[4];
+
+    // const int *isa;
+    FieldTypes[0] = getPointerType(IntTy.withConst());
+    // int flags;
+    FieldTypes[1] = IntTy;
+    // const char *str;
+    FieldTypes[2] = getPointerType(CharTy.withConst());
+    // long length;
+    FieldTypes[3] = LongTy;
+
+    // Create fields
+    for (unsigned i = 0; i < 4; ++i) {
+      FieldDecl *Field = FieldDecl::Create(*this, CFConstantStringTypeDecl,
+                                           SourceLocation(), 0,
+                                           FieldTypes[i], /*TInfo=*/0,
+                                           /*BitWidth=*/0,
+                                           /*Mutable=*/false);
+      CFConstantStringTypeDecl->addDecl(Field);
+    }
+
+    CFConstantStringTypeDecl->completeDefinition();
+  }
+
+  return getTagDeclType(CFConstantStringTypeDecl);
+}
+
+void ASTContext::setCFConstantStringType(QualType T) {
+  const RecordType *Rec = T->getAs<RecordType>();
+  assert(Rec && "Invalid CFConstantStringType");
+  CFConstantStringTypeDecl = Rec->getDecl();
+}
+
+// getNSConstantStringType - Return the type used for constant NSStrings.
+QualType ASTContext::getNSConstantStringType() {
+  if (!NSConstantStringTypeDecl) {
+    NSConstantStringTypeDecl =
+    CreateRecordDecl(*this, TagDecl::TK_struct, TUDecl, SourceLocation(),
+                     &Idents.get("__builtin_NSString"));
+    NSConstantStringTypeDecl->startDefinition();
+    
+    QualType FieldTypes[3];
+    
+    // const int *isa;
+    FieldTypes[0] = getPointerType(IntTy.withConst());
+    // const char *str;
+    FieldTypes[1] = getPointerType(CharTy.withConst());
+    // unsigned int length;
+    FieldTypes[2] = UnsignedIntTy;
+    
+    // Create fields
+    for (unsigned i = 0; i < 3; ++i) {
+      FieldDecl *Field = FieldDecl::Create(*this, NSConstantStringTypeDecl,
+                                           SourceLocation(), 0,
+                                           FieldTypes[i], /*TInfo=*/0,
+                                           /*BitWidth=*/0,
+                                           /*Mutable=*/false);
+      NSConstantStringTypeDecl->addDecl(Field);
+    }
+    
+    NSConstantStringTypeDecl->completeDefinition();
+  }
+  
+  return getTagDeclType(NSConstantStringTypeDecl);
+}
+
+void ASTContext::setNSConstantStringType(QualType T) {
+  const RecordType *Rec = T->getAs<RecordType>();
+  assert(Rec && "Invalid NSConstantStringType");
+  NSConstantStringTypeDecl = Rec->getDecl();
+}
+
+QualType ASTContext::getObjCFastEnumerationStateType() {
+  if (!ObjCFastEnumerationStateTypeDecl) {
+    ObjCFastEnumerationStateTypeDecl =
+      CreateRecordDecl(*this, TagDecl::TK_struct, TUDecl, SourceLocation(),
+                       &Idents.get("__objcFastEnumerationState"));
+    ObjCFastEnumerationStateTypeDecl->startDefinition();
+
+    QualType FieldTypes[] = {
+      UnsignedLongTy,
+      getPointerType(ObjCIdTypedefType),
+      getPointerType(UnsignedLongTy),
+      getConstantArrayType(UnsignedLongTy,
+                           llvm::APInt(32, 5), ArrayType::Normal, 0)
+    };
+
+    for (size_t i = 0; i < 4; ++i) {
+      FieldDecl *Field = FieldDecl::Create(*this,
+                                           ObjCFastEnumerationStateTypeDecl,
+                                           SourceLocation(), 0,
+                                           FieldTypes[i], /*TInfo=*/0,
+                                           /*BitWidth=*/0,
+                                           /*Mutable=*/false);
+      ObjCFastEnumerationStateTypeDecl->addDecl(Field);
+    }
+
+    ObjCFastEnumerationStateTypeDecl->completeDefinition();
+  }
+
+  return getTagDeclType(ObjCFastEnumerationStateTypeDecl);
+}
+
+QualType ASTContext::getBlockDescriptorType() {
+  if (BlockDescriptorType)
+    return getTagDeclType(BlockDescriptorType);
+
+  RecordDecl *T;
+  // FIXME: Needs the FlagAppleBlock bit.
+  T = CreateRecordDecl(*this, TagDecl::TK_struct, TUDecl, SourceLocation(),
+                       &Idents.get("__block_descriptor"));
+  T->startDefinition();
+  
+  QualType FieldTypes[] = {
+    UnsignedLongTy,
+    UnsignedLongTy,
+  };
+
+  const char *FieldNames[] = {
+    "reserved",
+    "Size"
+  };
+
+  for (size_t i = 0; i < 2; ++i) {
+    FieldDecl *Field = FieldDecl::Create(*this,
+                                         T,
+                                         SourceLocation(),
+                                         &Idents.get(FieldNames[i]),
+                                         FieldTypes[i], /*TInfo=*/0,
+                                         /*BitWidth=*/0,
+                                         /*Mutable=*/false);
+    T->addDecl(Field);
+  }
+
+  T->completeDefinition();
+
+  BlockDescriptorType = T;
+
+  return getTagDeclType(BlockDescriptorType);
+}
+
+void ASTContext::setBlockDescriptorType(QualType T) {
+  const RecordType *Rec = T->getAs<RecordType>();
+  assert(Rec && "Invalid BlockDescriptorType");
+  BlockDescriptorType = Rec->getDecl();
+}
+
+QualType ASTContext::getBlockDescriptorExtendedType() {
+  if (BlockDescriptorExtendedType)
+    return getTagDeclType(BlockDescriptorExtendedType);
+
+  RecordDecl *T;
+  // FIXME: Needs the FlagAppleBlock bit.
+  T = CreateRecordDecl(*this, TagDecl::TK_struct, TUDecl, SourceLocation(),
+                       &Idents.get("__block_descriptor_withcopydispose"));
+  T->startDefinition();
+  
+  QualType FieldTypes[] = {
+    UnsignedLongTy,
+    UnsignedLongTy,
+    getPointerType(VoidPtrTy),
+    getPointerType(VoidPtrTy)
+  };
+
+  const char *FieldNames[] = {
+    "reserved",
+    "Size",
+    "CopyFuncPtr",
+    "DestroyFuncPtr"
+  };
+
+  for (size_t i = 0; i < 4; ++i) {
+    FieldDecl *Field = FieldDecl::Create(*this,
+                                         T,
+                                         SourceLocation(),
+                                         &Idents.get(FieldNames[i]),
+                                         FieldTypes[i], /*TInfo=*/0,
+                                         /*BitWidth=*/0,
+                                         /*Mutable=*/false);
+    T->addDecl(Field);
+  }
+
+  T->completeDefinition();
+
+  BlockDescriptorExtendedType = T;
+
+  return getTagDeclType(BlockDescriptorExtendedType);
+}
+
+void ASTContext::setBlockDescriptorExtendedType(QualType T) {
+  const RecordType *Rec = T->getAs<RecordType>();
+  assert(Rec && "Invalid BlockDescriptorType");
+  BlockDescriptorExtendedType = Rec->getDecl();
+}
+
+bool ASTContext::BlockRequiresCopying(QualType Ty) {
+  if (Ty->isBlockPointerType())
+    return true;
+  if (isObjCNSObjectType(Ty))
+    return true;
+  if (Ty->isObjCObjectPointerType())
+    return true;
+  return false;
+}
+
+QualType ASTContext::BuildByRefType(const char *DeclName, QualType Ty) {
+  //  type = struct __Block_byref_1_X {
+  //    void *__isa;
+  //    struct __Block_byref_1_X *__forwarding;
+  //    unsigned int __flags;
+  //    unsigned int __size;
+  //    void *__copy_helper;		// as needed
+  //    void *__destroy_help		// as needed
+  //    int X;
+  //  } *
+
+  bool HasCopyAndDispose = BlockRequiresCopying(Ty);
+
+  // FIXME: Move up
+  static unsigned int UniqueBlockByRefTypeID = 0;
+  llvm::SmallString<36> Name;
+  llvm::raw_svector_ostream(Name) << "__Block_byref_" <<
+                                  ++UniqueBlockByRefTypeID << '_' << DeclName;
+  RecordDecl *T;
+  T = CreateRecordDecl(*this, TagDecl::TK_struct, TUDecl, SourceLocation(),
+                       &Idents.get(Name.str()));
+  T->startDefinition();
+  QualType Int32Ty = IntTy;
+  assert(getIntWidth(IntTy) == 32 && "non-32bit int not supported");
+  QualType FieldTypes[] = {
+    getPointerType(VoidPtrTy),
+    getPointerType(getTagDeclType(T)),
+    Int32Ty,
+    Int32Ty,
+    getPointerType(VoidPtrTy),
+    getPointerType(VoidPtrTy),
+    Ty
+  };
+
+  const char *FieldNames[] = {
+    "__isa",
+    "__forwarding",
+    "__flags",
+    "__size",
+    "__copy_helper",
+    "__destroy_helper",
+    DeclName,
+  };
+
+  for (size_t i = 0; i < 7; ++i) {
+    if (!HasCopyAndDispose && i >=4 && i <= 5)
+      continue;
+    FieldDecl *Field = FieldDecl::Create(*this, T, SourceLocation(),
+                                         &Idents.get(FieldNames[i]),
+                                         FieldTypes[i], /*TInfo=*/0,
+                                         /*BitWidth=*/0, /*Mutable=*/false);
+    T->addDecl(Field);
+  }
+
+  T->completeDefinition();
+
+  return getPointerType(getTagDeclType(T));
+}
+
+
+QualType ASTContext::getBlockParmType(
+  bool BlockHasCopyDispose,
+  llvm::SmallVector<const Expr *, 8> &BlockDeclRefDecls) {
+  // FIXME: Move up
+  static unsigned int UniqueBlockParmTypeID = 0;
+  llvm::SmallString<36> Name;
+  llvm::raw_svector_ostream(Name) << "__block_literal_"
+                                  << ++UniqueBlockParmTypeID;
+  RecordDecl *T;
+  T = CreateRecordDecl(*this, TagDecl::TK_struct, TUDecl, SourceLocation(),
+                       &Idents.get(Name.str()));
+  T->startDefinition();
+  QualType FieldTypes[] = {
+    getPointerType(VoidPtrTy),
+    IntTy,
+    IntTy,
+    getPointerType(VoidPtrTy),
+    (BlockHasCopyDispose ?
+     getPointerType(getBlockDescriptorExtendedType()) :
+     getPointerType(getBlockDescriptorType()))
+  };
+
+  const char *FieldNames[] = {
+    "__isa",
+    "__flags",
+    "__reserved",
+    "__FuncPtr",
+    "__descriptor"
+  };
+
+  for (size_t i = 0; i < 5; ++i) {
+    FieldDecl *Field = FieldDecl::Create(*this, T, SourceLocation(),
+                                         &Idents.get(FieldNames[i]),
+                                         FieldTypes[i], /*TInfo=*/0,
+                                         /*BitWidth=*/0, /*Mutable=*/false);
+    T->addDecl(Field);
+  }
+
+  for (size_t i = 0; i < BlockDeclRefDecls.size(); ++i) {
+    const Expr *E = BlockDeclRefDecls[i];
+    const BlockDeclRefExpr *BDRE = dyn_cast<BlockDeclRefExpr>(E);
+    clang::IdentifierInfo *Name = 0;
+    if (BDRE) {
+      const ValueDecl *D = BDRE->getDecl();
+      Name = &Idents.get(D->getName());
+    }
+    QualType FieldType = E->getType();
+
+    if (BDRE && BDRE->isByRef())
+      FieldType = BuildByRefType(BDRE->getDecl()->getNameAsCString(),
+                                 FieldType);
+
+    FieldDecl *Field = FieldDecl::Create(*this, T, SourceLocation(),
+                                         Name, FieldType, /*TInfo=*/0,
+                                         /*BitWidth=*/0, /*Mutable=*/false);
+    T->addDecl(Field);
+  }
+
+  T->completeDefinition();
+
+  return getPointerType(getTagDeclType(T));
+}
+
+void ASTContext::setObjCFastEnumerationStateType(QualType T) {
+  const RecordType *Rec = T->getAs<RecordType>();
+  assert(Rec && "Invalid ObjCFAstEnumerationStateType");
+  ObjCFastEnumerationStateTypeDecl = Rec->getDecl();
+}
+
+// This returns true if a type has been typedefed to BOOL:
+// typedef <type> BOOL;
+static bool isTypeTypedefedAsBOOL(QualType T) {
+  if (const TypedefType *TT = dyn_cast<TypedefType>(T))
+    if (IdentifierInfo *II = TT->getDecl()->getIdentifier())
+      return II->isStr("BOOL");
+
+  return false;
+}
+
+/// getObjCEncodingTypeSize returns size of type for objective-c encoding
+/// purpose.
+CharUnits ASTContext::getObjCEncodingTypeSize(QualType type) {
+  CharUnits sz = getTypeSizeInChars(type);
+
+  // Make all integer and enum types at least as large as an int
+  if (sz.isPositive() && type->isIntegralType())
+    sz = std::max(sz, getTypeSizeInChars(IntTy));
+  // Treat arrays as pointers, since that's how they're passed in.
+  else if (type->isArrayType())
+    sz = getTypeSizeInChars(VoidPtrTy);
+  return sz;
+}
+
+static inline 
+std::string charUnitsToString(const CharUnits &CU) {
+  return llvm::itostr(CU.getQuantity());
+}
+
+/// getObjCEncodingForBlockDecl - Return the encoded type for this block
+/// declaration.
+void ASTContext::getObjCEncodingForBlock(const BlockExpr *Expr, 
+                                             std::string& S) {
+  const BlockDecl *Decl = Expr->getBlockDecl();
+  QualType BlockTy =
+      Expr->getType()->getAs<BlockPointerType>()->getPointeeType();
+  // Encode result type.
+  getObjCEncodingForType(cast<FunctionType>(BlockTy)->getResultType(), S);
+  // Compute size of all parameters.
+  // Start with computing size of a pointer in number of bytes.
+  // FIXME: There might(should) be a better way of doing this computation!
+  SourceLocation Loc;
+  CharUnits PtrSize = getTypeSizeInChars(VoidPtrTy);
+  CharUnits ParmOffset = PtrSize;
+  for (BlockDecl::param_const_iterator PI = Decl->param_begin(),
+       E = Decl->param_end(); PI != E; ++PI) {
+    QualType PType = (*PI)->getType();
+    CharUnits sz = getObjCEncodingTypeSize(PType);
+    assert (sz.isPositive() && "BlockExpr - Incomplete param type");
+    ParmOffset += sz;
+  }
+  // Size of the argument frame
+  S += charUnitsToString(ParmOffset);
+  // Block pointer and offset.
+  S += "@?0";
+  ParmOffset = PtrSize;
+  
+  // Argument types.
+  ParmOffset = PtrSize;
+  for (BlockDecl::param_const_iterator PI = Decl->param_begin(), E =
+       Decl->param_end(); PI != E; ++PI) {
+    ParmVarDecl *PVDecl = *PI;
+    QualType PType = PVDecl->getOriginalType(); 
+    if (const ArrayType *AT =
+          dyn_cast<ArrayType>(PType->getCanonicalTypeInternal())) {
+      // Use array's original type only if it has known number of
+      // elements.
+      if (!isa<ConstantArrayType>(AT))
+        PType = PVDecl->getType();
+    } else if (PType->isFunctionType())
+      PType = PVDecl->getType();
+    getObjCEncodingForType(PType, S);
+    S += charUnitsToString(ParmOffset);
+    ParmOffset += getObjCEncodingTypeSize(PType);
+  }
+}
+
+/// getObjCEncodingForMethodDecl - Return the encoded type for this method
+/// declaration.
+void ASTContext::getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl,
+                                              std::string& S) {
+  // FIXME: This is not very efficient.
+  // Encode type qualifer, 'in', 'inout', etc. for the return type.
+  getObjCEncodingForTypeQualifier(Decl->getObjCDeclQualifier(), S);
+  // Encode result type.
+  getObjCEncodingForType(Decl->getResultType(), S);
+  // Compute size of all parameters.
+  // Start with computing size of a pointer in number of bytes.
+  // FIXME: There might(should) be a better way of doing this computation!
+  SourceLocation Loc;
+  CharUnits PtrSize = getTypeSizeInChars(VoidPtrTy);
+  // The first two arguments (self and _cmd) are pointers; account for
+  // their size.
+  CharUnits ParmOffset = 2 * PtrSize;
+  for (ObjCMethodDecl::param_iterator PI = Decl->param_begin(),
+       E = Decl->sel_param_end(); PI != E; ++PI) {
+    QualType PType = (*PI)->getType();
+    CharUnits sz = getObjCEncodingTypeSize(PType);
+    assert (sz.isPositive() && 
+        "getObjCEncodingForMethodDecl - Incomplete param type");
+    ParmOffset += sz;
+  }
+  S += charUnitsToString(ParmOffset);
+  S += "@0:";
+  S += charUnitsToString(PtrSize);
+
+  // Argument types.
+  ParmOffset = 2 * PtrSize;
+  for (ObjCMethodDecl::param_iterator PI = Decl->param_begin(),
+       E = Decl->sel_param_end(); PI != E; ++PI) {
+    ParmVarDecl *PVDecl = *PI;
+    QualType PType = PVDecl->getOriginalType();
+    if (const ArrayType *AT =
+          dyn_cast<ArrayType>(PType->getCanonicalTypeInternal())) {
+      // Use array's original type only if it has known number of
+      // elements.
+      if (!isa<ConstantArrayType>(AT))
+        PType = PVDecl->getType();
+    } else if (PType->isFunctionType())
+      PType = PVDecl->getType();
+    // Process argument qualifiers for user supplied arguments; such as,
+    // 'in', 'inout', etc.
+    getObjCEncodingForTypeQualifier(PVDecl->getObjCDeclQualifier(), S);
+    getObjCEncodingForType(PType, S);
+    S += charUnitsToString(ParmOffset);
+    ParmOffset += getObjCEncodingTypeSize(PType);
+  }
+}
+
+/// getObjCEncodingForPropertyDecl - Return the encoded type for this
+/// property declaration. If non-NULL, Container must be either an
+/// ObjCCategoryImplDecl or ObjCImplementationDecl; it should only be
+/// NULL when getting encodings for protocol properties.
+/// Property attributes are stored as a comma-delimited C string. The simple
+/// attributes readonly and bycopy are encoded as single characters. The
+/// parametrized attributes, getter=name, setter=name, and ivar=name, are
+/// encoded as single characters, followed by an identifier. Property types
+/// are also encoded as a parametrized attribute. The characters used to encode
+/// these attributes are defined by the following enumeration:
+/// @code
+/// enum PropertyAttributes {
+/// kPropertyReadOnly = 'R',   // property is read-only.
+/// kPropertyBycopy = 'C',     // property is a copy of the value last assigned
+/// kPropertyByref = '&',  // property is a reference to the value last assigned
+/// kPropertyDynamic = 'D',    // property is dynamic
+/// kPropertyGetter = 'G',     // followed by getter selector name
+/// kPropertySetter = 'S',     // followed by setter selector name
+/// kPropertyInstanceVariable = 'V'  // followed by instance variable  name
+/// kPropertyType = 't'              // followed by old-style type encoding.
+/// kPropertyWeak = 'W'              // 'weak' property
+/// kPropertyStrong = 'P'            // property GC'able
+/// kPropertyNonAtomic = 'N'         // property non-atomic
+/// };
+/// @endcode
+void ASTContext::getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD,
+                                                const Decl *Container,
+                                                std::string& S) {
+  // Collect information from the property implementation decl(s).
+  bool Dynamic = false;
+  ObjCPropertyImplDecl *SynthesizePID = 0;
+
+  // FIXME: Duplicated code due to poor abstraction.
+  if (Container) {
+    if (const ObjCCategoryImplDecl *CID =
+        dyn_cast<ObjCCategoryImplDecl>(Container)) {
+      for (ObjCCategoryImplDecl::propimpl_iterator
+             i = CID->propimpl_begin(), e = CID->propimpl_end();
+           i != e; ++i) {
+        ObjCPropertyImplDecl *PID = *i;
+        if (PID->getPropertyDecl() == PD) {
+          if (PID->getPropertyImplementation()==ObjCPropertyImplDecl::Dynamic) {
+            Dynamic = true;
+          } else {
+            SynthesizePID = PID;
+          }
+        }
+      }
+    } else {
+      const ObjCImplementationDecl *OID=cast<ObjCImplementationDecl>(Container);
+      for (ObjCCategoryImplDecl::propimpl_iterator
+             i = OID->propimpl_begin(), e = OID->propimpl_end();
+           i != e; ++i) {
+        ObjCPropertyImplDecl *PID = *i;
+        if (PID->getPropertyDecl() == PD) {
+          if (PID->getPropertyImplementation()==ObjCPropertyImplDecl::Dynamic) {
+            Dynamic = true;
+          } else {
+            SynthesizePID = PID;
+          }
+        }
+      }
+    }
+  }
+
+  // FIXME: This is not very efficient.
+  S = "T";
+
+  // Encode result type.
+  // GCC has some special rules regarding encoding of properties which
+  // closely resembles encoding of ivars.
+  getObjCEncodingForTypeImpl(PD->getType(), S, true, true, 0,
+                             true /* outermost type */,
+                             true /* encoding for property */);
+
+  if (PD->isReadOnly()) {
+    S += ",R";
+  } else {
+    switch (PD->getSetterKind()) {
+    case ObjCPropertyDecl::Assign: break;
+    case ObjCPropertyDecl::Copy:   S += ",C"; break;
+    case ObjCPropertyDecl::Retain: S += ",&"; break;
+    }
+  }
+
+  // It really isn't clear at all what this means, since properties
+  // are "dynamic by default".
+  if (Dynamic)
+    S += ",D";
+
+  if (PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_nonatomic)
+    S += ",N";
+
+  if (PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_getter) {
+    S += ",G";
+    S += PD->getGetterName().getAsString();
+  }
+
+  if (PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_setter) {
+    S += ",S";
+    S += PD->getSetterName().getAsString();
+  }
+
+  if (SynthesizePID) {
+    const ObjCIvarDecl *OID = SynthesizePID->getPropertyIvarDecl();
+    S += ",V";
+    S += OID->getNameAsString();
+  }
+
+  // FIXME: OBJCGC: weak & strong
+}
+
+/// getLegacyIntegralTypeEncoding -
+/// Another legacy compatibility encoding: 32-bit longs are encoded as
+/// 'l' or 'L' , but not always.  For typedefs, we need to use
+/// 'i' or 'I' instead if encoding a struct field, or a pointer!
+///
+void ASTContext::getLegacyIntegralTypeEncoding (QualType &PointeeTy) const {
+  if (isa<TypedefType>(PointeeTy.getTypePtr())) {
+    if (const BuiltinType *BT = PointeeTy->getAs<BuiltinType>()) {
+      if (BT->getKind() == BuiltinType::ULong &&
+          ((const_cast<ASTContext *>(this))->getIntWidth(PointeeTy) == 32))
+        PointeeTy = UnsignedIntTy;
+      else
+        if (BT->getKind() == BuiltinType::Long &&
+            ((const_cast<ASTContext *>(this))->getIntWidth(PointeeTy) == 32))
+          PointeeTy = IntTy;
+    }
+  }
+}
+
+void ASTContext::getObjCEncodingForType(QualType T, std::string& S,
+                                        const FieldDecl *Field) {
+  // We follow the behavior of gcc, expanding structures which are
+  // directly pointed to, and expanding embedded structures. Note that
+  // these rules are sufficient to prevent recursive encoding of the
+  // same type.
+  getObjCEncodingForTypeImpl(T, S, true, true, Field,
+                             true /* outermost type */);
+}
+
+static void EncodeBitField(const ASTContext *Context, std::string& S,
+                           const FieldDecl *FD) {
+  const Expr *E = FD->getBitWidth();
+  assert(E && "bitfield width not there - getObjCEncodingForTypeImpl");
+  ASTContext *Ctx = const_cast<ASTContext*>(Context);
+  unsigned N = E->EvaluateAsInt(*Ctx).getZExtValue();
+  S += 'b';
+  S += llvm::utostr(N);
+}
+
+// FIXME: Use SmallString for accumulating string.
+void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
+                                            bool ExpandPointedToStructures,
+                                            bool ExpandStructures,
+                                            const FieldDecl *FD,
+                                            bool OutermostType,
+                                            bool EncodingProperty) {
+  if (const BuiltinType *BT = T->getAs<BuiltinType>()) {
+    if (FD && FD->isBitField())
+      return EncodeBitField(this, S, FD);
+    char encoding;
+    switch (BT->getKind()) {
+    default: assert(0 && "Unhandled builtin type kind");
+    case BuiltinType::Void:       encoding = 'v'; break;
+    case BuiltinType::Bool:       encoding = 'B'; break;
+    case BuiltinType::Char_U:
+    case BuiltinType::UChar:      encoding = 'C'; break;
+    case BuiltinType::UShort:     encoding = 'S'; break;
+    case BuiltinType::UInt:       encoding = 'I'; break;
+    case BuiltinType::ULong:
+        encoding =
+          (const_cast<ASTContext *>(this))->getIntWidth(T) == 32 ? 'L' : 'Q';
+        break;
+    case BuiltinType::UInt128:    encoding = 'T'; break;
+    case BuiltinType::ULongLong:  encoding = 'Q'; break;
+    case BuiltinType::Char_S:
+    case BuiltinType::SChar:      encoding = 'c'; break;
+    case BuiltinType::Short:      encoding = 's'; break;
+    case BuiltinType::Int:        encoding = 'i'; break;
+    case BuiltinType::Long:
+      encoding =
+        (const_cast<ASTContext *>(this))->getIntWidth(T) == 32 ? 'l' : 'q';
+      break;
+    case BuiltinType::LongLong:   encoding = 'q'; break;
+    case BuiltinType::Int128:     encoding = 't'; break;
+    case BuiltinType::Float:      encoding = 'f'; break;
+    case BuiltinType::Double:     encoding = 'd'; break;
+    case BuiltinType::LongDouble: encoding = 'd'; break;
+    }
+
+    S += encoding;
+    return;
+  }
+
+  if (const ComplexType *CT = T->getAs<ComplexType>()) {
+    S += 'j';
+    getObjCEncodingForTypeImpl(CT->getElementType(), S, false, false, 0, false,
+                               false);
+    return;
+  }
+  
+  // encoding for pointer or r3eference types.
+  QualType PointeeTy;
+  if (const PointerType *PT = T->getAs<PointerType>()) {
+    if (PT->isObjCSelType()) {
+      S += ':';
+      return;
+    }
+    PointeeTy = PT->getPointeeType();
+  }
+  else if (const ReferenceType *RT = T->getAs<ReferenceType>())
+    PointeeTy = RT->getPointeeType();
+  if (!PointeeTy.isNull()) {
+    bool isReadOnly = false;
+    // For historical/compatibility reasons, the read-only qualifier of the
+    // pointee gets emitted _before_ the '^'.  The read-only qualifier of
+    // the pointer itself gets ignored, _unless_ we are looking at a typedef!
+    // Also, do not emit the 'r' for anything but the outermost type!
+    if (isa<TypedefType>(T.getTypePtr())) {
+      if (OutermostType && T.isConstQualified()) {
+        isReadOnly = true;
+        S += 'r';
+      }
+    } else if (OutermostType) {
+      QualType P = PointeeTy;
+      while (P->getAs<PointerType>())
+        P = P->getAs<PointerType>()->getPointeeType();
+      if (P.isConstQualified()) {
+        isReadOnly = true;
+        S += 'r';
+      }
+    }
+    if (isReadOnly) {
+      // Another legacy compatibility encoding. Some ObjC qualifier and type
+      // combinations need to be rearranged.
+      // Rewrite "in const" from "nr" to "rn"
+      const char * s = S.c_str();
+      int len = S.length();
+      if (len >= 2 && s[len-2] == 'n' && s[len-1] == 'r') {
+        std::string replace = "rn";
+        S.replace(S.end()-2, S.end(), replace);
+      }
+    }
+
+    if (PointeeTy->isCharType()) {
+      // char pointer types should be encoded as '*' unless it is a
+      // type that has been typedef'd to 'BOOL'.
+      if (!isTypeTypedefedAsBOOL(PointeeTy)) {
+        S += '*';
+        return;
+      }
+    } else if (const RecordType *RTy = PointeeTy->getAs<RecordType>()) {
+      // GCC binary compat: Need to convert "struct objc_class *" to "#".
+      if (RTy->getDecl()->getIdentifier() == &Idents.get("objc_class")) {
+        S += '#';
+        return;
+      }
+      // GCC binary compat: Need to convert "struct objc_object *" to "@".
+      if (RTy->getDecl()->getIdentifier() == &Idents.get("objc_object")) {
+        S += '@';
+        return;
+      }
+      // fall through...
+    }
+    S += '^';
+    getLegacyIntegralTypeEncoding(PointeeTy);
+
+    getObjCEncodingForTypeImpl(PointeeTy, S, false, ExpandPointedToStructures,
+                               NULL);
+    return;
+  }
+  
+  if (const ArrayType *AT =
+      // Ignore type qualifiers etc.
+        dyn_cast<ArrayType>(T->getCanonicalTypeInternal())) {
+    if (isa<IncompleteArrayType>(AT)) {
+      // Incomplete arrays are encoded as a pointer to the array element.
+      S += '^';
+
+      getObjCEncodingForTypeImpl(AT->getElementType(), S,
+                                 false, ExpandStructures, FD);
+    } else {
+      S += '[';
+
+      if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(AT))
+        S += llvm::utostr(CAT->getSize().getZExtValue());
+      else {
+        //Variable length arrays are encoded as a regular array with 0 elements.
+        assert(isa<VariableArrayType>(AT) && "Unknown array type!");
+        S += '0';
+      }
+
+      getObjCEncodingForTypeImpl(AT->getElementType(), S,
+                                 false, ExpandStructures, FD);
+      S += ']';
+    }
+    return;
+  }
+
+  if (T->getAs<FunctionType>()) {
+    S += '?';
+    return;
+  }
+
+  if (const RecordType *RTy = T->getAs<RecordType>()) {
+    RecordDecl *RDecl = RTy->getDecl();
+    S += RDecl->isUnion() ? '(' : '{';
+    // Anonymous structures print as '?'
+    if (const IdentifierInfo *II = RDecl->getIdentifier()) {
+      S += II->getName();
+    } else {
+      S += '?';
+    }
+    if (ExpandStructures) {
+      S += '=';
+      for (RecordDecl::field_iterator Field = RDecl->field_begin(),
+                                   FieldEnd = RDecl->field_end();
+           Field != FieldEnd; ++Field) {
+        if (FD) {
+          S += '"';
+          S += Field->getNameAsString();
+          S += '"';
+        }
+
+        // Special case bit-fields.
+        if (Field->isBitField()) {
+          getObjCEncodingForTypeImpl(Field->getType(), S, false, true,
+                                     (*Field));
+        } else {
+          QualType qt = Field->getType();
+          getLegacyIntegralTypeEncoding(qt);
+          getObjCEncodingForTypeImpl(qt, S, false, true,
+                                     FD);
+        }
+      }
+    }
+    S += RDecl->isUnion() ? ')' : '}';
+    return;
+  }
+
+  if (T->isEnumeralType()) {
+    if (FD && FD->isBitField())
+      EncodeBitField(this, S, FD);
+    else
+      S += 'i';
+    return;
+  }
+
+  if (T->isBlockPointerType()) {
+    S += "@?"; // Unlike a pointer-to-function, which is "^?".
+    return;
+  }
+
+  if (const ObjCInterfaceType *OIT = T->getAs<ObjCInterfaceType>()) {
+    // @encode(class_name)
+    ObjCInterfaceDecl *OI = OIT->getDecl();
+    S += '{';
+    const IdentifierInfo *II = OI->getIdentifier();
+    S += II->getName();
+    S += '=';
+    llvm::SmallVector<FieldDecl*, 32> RecFields;
+    CollectObjCIvars(OI, RecFields);
+    for (unsigned i = 0, e = RecFields.size(); i != e; ++i) {
+      if (RecFields[i]->isBitField())
+        getObjCEncodingForTypeImpl(RecFields[i]->getType(), S, false, true,
+                                   RecFields[i]);
+      else
+        getObjCEncodingForTypeImpl(RecFields[i]->getType(), S, false, true,
+                                   FD);
+    }
+    S += '}';
+    return;
+  }
+
+  if (const ObjCObjectPointerType *OPT = T->getAs<ObjCObjectPointerType>()) {
+    if (OPT->isObjCIdType()) {
+      S += '@';
+      return;
+    }
+
+    if (OPT->isObjCClassType() || OPT->isObjCQualifiedClassType()) {
+      // FIXME: Consider if we need to output qualifiers for 'Class<p>'.
+      // Since this is a binary compatibility issue, need to consult with runtime
+      // folks. Fortunately, this is a *very* obsure construct.
+      S += '#';
+      return;
+    }
+
+    if (OPT->isObjCQualifiedIdType()) {
+      getObjCEncodingForTypeImpl(getObjCIdType(), S,
+                                 ExpandPointedToStructures,
+                                 ExpandStructures, FD);
+      if (FD || EncodingProperty) {
+        // Note that we do extended encoding of protocol qualifer list
+        // Only when doing ivar or property encoding.
+        S += '"';
+        for (ObjCObjectPointerType::qual_iterator I = OPT->qual_begin(),
+             E = OPT->qual_end(); I != E; ++I) {
+          S += '<';
+          S += (*I)->getNameAsString();
+          S += '>';
+        }
+        S += '"';
+      }
+      return;
+    }
+
+    QualType PointeeTy = OPT->getPointeeType();
+    if (!EncodingProperty &&
+        isa<TypedefType>(PointeeTy.getTypePtr())) {
+      // Another historical/compatibility reason.
+      // We encode the underlying type which comes out as
+      // {...};
+      S += '^';
+      getObjCEncodingForTypeImpl(PointeeTy, S,
+                                 false, ExpandPointedToStructures,
+                                 NULL);
+      return;
+    }
+
+    S += '@';
+    if (OPT->getInterfaceDecl() && (FD || EncodingProperty)) {
+      S += '"';
+      S += OPT->getInterfaceDecl()->getIdentifier()->getName();
+      for (ObjCObjectPointerType::qual_iterator I = OPT->qual_begin(),
+           E = OPT->qual_end(); I != E; ++I) {
+        S += '<';
+        S += (*I)->getNameAsString();
+        S += '>';
+      }
+      S += '"';
+    }
+    return;
+  }
+
+  assert(0 && "@encode for type not implemented!");
+}
+
+void ASTContext::getObjCEncodingForTypeQualifier(Decl::ObjCDeclQualifier QT,
+                                                 std::string& S) const {
+  if (QT & Decl::OBJC_TQ_In)
+    S += 'n';
+  if (QT & Decl::OBJC_TQ_Inout)
+    S += 'N';
+  if (QT & Decl::OBJC_TQ_Out)
+    S += 'o';
+  if (QT & Decl::OBJC_TQ_Bycopy)
+    S += 'O';
+  if (QT & Decl::OBJC_TQ_Byref)
+    S += 'R';
+  if (QT & Decl::OBJC_TQ_Oneway)
+    S += 'V';
+}
+
+void ASTContext::setBuiltinVaListType(QualType T) {
+  assert(BuiltinVaListType.isNull() && "__builtin_va_list type already set!");
+
+  BuiltinVaListType = T;
+}
+
+void ASTContext::setObjCIdType(QualType T) {
+  ObjCIdTypedefType = T;
+}
+
+void ASTContext::setObjCSelType(QualType T) {
+  ObjCSelTypedefType = T;
+}
+
+void ASTContext::setObjCProtoType(QualType QT) {
+  ObjCProtoType = QT;
+}
+
+void ASTContext::setObjCClassType(QualType T) {
+  ObjCClassTypedefType = T;
+}
+
+void ASTContext::setObjCConstantStringInterface(ObjCInterfaceDecl *Decl) {
+  assert(ObjCConstantStringType.isNull() &&
+         "'NSConstantString' type already set!");
+
+  ObjCConstantStringType = getObjCInterfaceType(Decl);
+}
+
+/// \brief Retrieve the template name that corresponds to a non-empty
+/// lookup.
+TemplateName ASTContext::getOverloadedTemplateName(UnresolvedSetIterator Begin,
+                                                   UnresolvedSetIterator End) {
+  unsigned size = End - Begin;
+  assert(size > 1 && "set is not overloaded!");
+
+  void *memory = Allocate(sizeof(OverloadedTemplateStorage) +
+                          size * sizeof(FunctionTemplateDecl*));
+  OverloadedTemplateStorage *OT = new(memory) OverloadedTemplateStorage(size);
+
+  NamedDecl **Storage = OT->getStorage();
+  for (UnresolvedSetIterator I = Begin; I != End; ++I) {
+    NamedDecl *D = *I;
+    assert(isa<FunctionTemplateDecl>(D) ||
+           (isa<UsingShadowDecl>(D) &&
+            isa<FunctionTemplateDecl>(D->getUnderlyingDecl())));
+    *Storage++ = D;
+  }
+
+  return TemplateName(OT);
+}
+
+/// \brief Retrieve the template name that represents a qualified
+/// template name such as \c std::vector.
+TemplateName ASTContext::getQualifiedTemplateName(NestedNameSpecifier *NNS,
+                                                  bool TemplateKeyword,
+                                                  TemplateDecl *Template) {
+  // FIXME: Canonicalization?
+  llvm::FoldingSetNodeID ID;
+  QualifiedTemplateName::Profile(ID, NNS, TemplateKeyword, Template);
+
+  void *InsertPos = 0;
+  QualifiedTemplateName *QTN =
+    QualifiedTemplateNames.FindNodeOrInsertPos(ID, InsertPos);
+  if (!QTN) {
+    QTN = new (*this,4) QualifiedTemplateName(NNS, TemplateKeyword, Template);
+    QualifiedTemplateNames.InsertNode(QTN, InsertPos);
+  }
+
+  return TemplateName(QTN);
+}
+
+/// \brief Retrieve the template name that represents a dependent
+/// template name such as \c MetaFun::template apply.
+TemplateName ASTContext::getDependentTemplateName(NestedNameSpecifier *NNS,
+                                                  const IdentifierInfo *Name) {
+  assert((!NNS || NNS->isDependent()) &&
+         "Nested name specifier must be dependent");
+
+  llvm::FoldingSetNodeID ID;
+  DependentTemplateName::Profile(ID, NNS, Name);
+
+  void *InsertPos = 0;
+  DependentTemplateName *QTN =
+    DependentTemplateNames.FindNodeOrInsertPos(ID, InsertPos);
+
+  if (QTN)
+    return TemplateName(QTN);
+
+  NestedNameSpecifier *CanonNNS = getCanonicalNestedNameSpecifier(NNS);
+  if (CanonNNS == NNS) {
+    QTN = new (*this,4) DependentTemplateName(NNS, Name);
+  } else {
+    TemplateName Canon = getDependentTemplateName(CanonNNS, Name);
+    QTN = new (*this,4) DependentTemplateName(NNS, Name, Canon);
+    DependentTemplateName *CheckQTN =
+      DependentTemplateNames.FindNodeOrInsertPos(ID, InsertPos);
+    assert(!CheckQTN && "Dependent type name canonicalization broken");
+    (void)CheckQTN;
+  }
+
+  DependentTemplateNames.InsertNode(QTN, InsertPos);
+  return TemplateName(QTN);
+}
+
+/// \brief Retrieve the template name that represents a dependent
+/// template name such as \c MetaFun::template operator+.
+TemplateName 
+ASTContext::getDependentTemplateName(NestedNameSpecifier *NNS,
+                                     OverloadedOperatorKind Operator) {
+  assert((!NNS || NNS->isDependent()) &&
+         "Nested name specifier must be dependent");
+  
+  llvm::FoldingSetNodeID ID;
+  DependentTemplateName::Profile(ID, NNS, Operator);
+  
+  void *InsertPos = 0;
+  DependentTemplateName *QTN
+    = DependentTemplateNames.FindNodeOrInsertPos(ID, InsertPos);
+  
+  if (QTN)
+    return TemplateName(QTN);
+  
+  NestedNameSpecifier *CanonNNS = getCanonicalNestedNameSpecifier(NNS);
+  if (CanonNNS == NNS) {
+    QTN = new (*this,4) DependentTemplateName(NNS, Operator);
+  } else {
+    TemplateName Canon = getDependentTemplateName(CanonNNS, Operator);
+    QTN = new (*this,4) DependentTemplateName(NNS, Operator, Canon);
+    
+    DependentTemplateName *CheckQTN
+      = DependentTemplateNames.FindNodeOrInsertPos(ID, InsertPos);
+    assert(!CheckQTN && "Dependent template name canonicalization broken");
+    (void)CheckQTN;
+  }
+  
+  DependentTemplateNames.InsertNode(QTN, InsertPos);
+  return TemplateName(QTN);
+}
+
+/// getFromTargetType - Given one of the integer types provided by
+/// TargetInfo, produce the corresponding type. The unsigned @p Type
+/// is actually a value of type @c TargetInfo::IntType.
+CanQualType ASTContext::getFromTargetType(unsigned Type) const {
+  switch (Type) {
+  case TargetInfo::NoInt: return CanQualType();
+  case TargetInfo::SignedShort: return ShortTy;
+  case TargetInfo::UnsignedShort: return UnsignedShortTy;
+  case TargetInfo::SignedInt: return IntTy;
+  case TargetInfo::UnsignedInt: return UnsignedIntTy;
+  case TargetInfo::SignedLong: return LongTy;
+  case TargetInfo::UnsignedLong: return UnsignedLongTy;
+  case TargetInfo::SignedLongLong: return LongLongTy;
+  case TargetInfo::UnsignedLongLong: return UnsignedLongLongTy;
+  }
+
+  assert(false && "Unhandled TargetInfo::IntType value");
+  return CanQualType();
+}
+
+//===----------------------------------------------------------------------===//
+//                        Type Predicates.
+//===----------------------------------------------------------------------===//
+
+/// isObjCNSObjectType - Return true if this is an NSObject object using
+/// NSObject attribute on a c-style pointer type.
+/// FIXME - Make it work directly on types.
+/// FIXME: Move to Type.
+///
+bool ASTContext::isObjCNSObjectType(QualType Ty) const {
+  if (TypedefType *TDT = dyn_cast<TypedefType>(Ty)) {
+    if (TypedefDecl *TD = TDT->getDecl())
+      if (TD->getAttr<ObjCNSObjectAttr>())
+        return true;
+  }
+  return false;
+}
+
+/// getObjCGCAttr - Returns one of GCNone, Weak or Strong objc's
+/// garbage collection attribute.
+///
+Qualifiers::GC ASTContext::getObjCGCAttrKind(const QualType &Ty) const {
+  Qualifiers::GC GCAttrs = Qualifiers::GCNone;
+  if (getLangOptions().ObjC1 &&
+      getLangOptions().getGCMode() != LangOptions::NonGC) {
+    GCAttrs = Ty.getObjCGCAttr();
+    // Default behavious under objective-c's gc is for objective-c pointers
+    // (or pointers to them) be treated as though they were declared
+    // as __strong.
+    if (GCAttrs == Qualifiers::GCNone) {
+      if (Ty->isObjCObjectPointerType() || Ty->isBlockPointerType())
+        GCAttrs = Qualifiers::Strong;
+      else if (Ty->isPointerType())
+        return getObjCGCAttrKind(Ty->getAs<PointerType>()->getPointeeType());
+    }
+    // Non-pointers have none gc'able attribute regardless of the attribute
+    // set on them.
+    else if (!Ty->isAnyPointerType() && !Ty->isBlockPointerType())
+      return Qualifiers::GCNone;
+  }
+  return GCAttrs;
+}
+
+//===----------------------------------------------------------------------===//
+//                        Type Compatibility Testing
+//===----------------------------------------------------------------------===//
+
+/// areCompatVectorTypes - Return true if the two specified vector types are
+/// compatible.
+static bool areCompatVectorTypes(const VectorType *LHS,
+                                 const VectorType *RHS) {
+  assert(LHS->isCanonicalUnqualified() && RHS->isCanonicalUnqualified());
+  return LHS->getElementType() == RHS->getElementType() &&
+         LHS->getNumElements() == RHS->getNumElements();
+}
+
+//===----------------------------------------------------------------------===//
+// ObjCQualifiedIdTypesAreCompatible - Compatibility testing for qualified id's.
+//===----------------------------------------------------------------------===//
+
+/// ProtocolCompatibleWithProtocol - return 'true' if 'lProto' is in the
+/// inheritance hierarchy of 'rProto'.
+bool ASTContext::ProtocolCompatibleWithProtocol(ObjCProtocolDecl *lProto,
+                                                ObjCProtocolDecl *rProto) {
+  if (lProto == rProto)
+    return true;
+  for (ObjCProtocolDecl::protocol_iterator PI = rProto->protocol_begin(),
+       E = rProto->protocol_end(); PI != E; ++PI)
+    if (ProtocolCompatibleWithProtocol(lProto, *PI))
+      return true;
+  return false;
+}
+
+/// QualifiedIdConformsQualifiedId - compare id<p,...> with id<p1,...>
+/// return true if lhs's protocols conform to rhs's protocol; false
+/// otherwise.
+bool ASTContext::QualifiedIdConformsQualifiedId(QualType lhs, QualType rhs) {
+  if (lhs->isObjCQualifiedIdType() && rhs->isObjCQualifiedIdType())
+    return ObjCQualifiedIdTypesAreCompatible(lhs, rhs, false);
+  return false;
+}
+
+/// ObjCQualifiedIdTypesAreCompatible - We know that one of lhs/rhs is an
+/// ObjCQualifiedIDType.
+bool ASTContext::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs,
+                                                   bool compare) {
+  // Allow id<P..> and an 'id' or void* type in all cases.
+  if (lhs->isVoidPointerType() ||
+      lhs->isObjCIdType() || lhs->isObjCClassType())
+    return true;
+  else if (rhs->isVoidPointerType() ||
+           rhs->isObjCIdType() || rhs->isObjCClassType())
+    return true;
+
+  if (const ObjCObjectPointerType *lhsQID = lhs->getAsObjCQualifiedIdType()) {
+    const ObjCObjectPointerType *rhsOPT = rhs->getAs<ObjCObjectPointerType>();
+
+    if (!rhsOPT) return false;
+
+    if (rhsOPT->qual_empty()) {
+      // If the RHS is a unqualified interface pointer "NSString*",
+      // make sure we check the class hierarchy.
+      if (ObjCInterfaceDecl *rhsID = rhsOPT->getInterfaceDecl()) {
+        for (ObjCObjectPointerType::qual_iterator I = lhsQID->qual_begin(),
+             E = lhsQID->qual_end(); I != E; ++I) {
+          // when comparing an id<P> on lhs with a static type on rhs,
+          // see if static class implements all of id's protocols, directly or
+          // through its super class and categories.
+          if (!rhsID->ClassImplementsProtocol(*I, true))
+            return false;
+        }
+      }
+      // If there are no qualifiers and no interface, we have an 'id'.
+      return true;
+    }
+    // Both the right and left sides have qualifiers.
+    for (ObjCObjectPointerType::qual_iterator I = lhsQID->qual_begin(),
+         E = lhsQID->qual_end(); I != E; ++I) {
+      ObjCProtocolDecl *lhsProto = *I;
+      bool match = false;
+
+      // when comparing an id<P> on lhs with a static type on rhs,
+      // see if static class implements all of id's protocols, directly or
+      // through its super class and categories.
+      for (ObjCObjectPointerType::qual_iterator J = rhsOPT->qual_begin(),
+           E = rhsOPT->qual_end(); J != E; ++J) {
+        ObjCProtocolDecl *rhsProto = *J;
+        if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto) ||
+            (compare && ProtocolCompatibleWithProtocol(rhsProto, lhsProto))) {
+          match = true;
+          break;
+        }
+      }
+      // If the RHS is a qualified interface pointer "NSString<P>*",
+      // make sure we check the class hierarchy.
+      if (ObjCInterfaceDecl *rhsID = rhsOPT->getInterfaceDecl()) {
+        for (ObjCObjectPointerType::qual_iterator I = lhsQID->qual_begin(),
+             E = lhsQID->qual_end(); I != E; ++I) {
+          // when comparing an id<P> on lhs with a static type on rhs,
+          // see if static class implements all of id's protocols, directly or
+          // through its super class and categories.
+          if (rhsID->ClassImplementsProtocol(*I, true)) {
+            match = true;
+            break;
+          }
+        }
+      }
+      if (!match)
+        return false;
+    }
+
+    return true;
+  }
+
+  const ObjCObjectPointerType *rhsQID = rhs->getAsObjCQualifiedIdType();
+  assert(rhsQID && "One of the LHS/RHS should be id<x>");
+
+  if (const ObjCObjectPointerType *lhsOPT =
+        lhs->getAsObjCInterfacePointerType()) {
+    if (lhsOPT->qual_empty()) {
+      bool match = false;
+      if (ObjCInterfaceDecl *lhsID = lhsOPT->getInterfaceDecl()) {
+        for (ObjCObjectPointerType::qual_iterator I = rhsQID->qual_begin(),
+             E = rhsQID->qual_end(); I != E; ++I) {
+          // when comparing an id<P> on lhs with a static type on rhs,
+          // see if static class implements all of id's protocols, directly or
+          // through its super class and categories.
+          if (lhsID->ClassImplementsProtocol(*I, true)) {
+            match = true;
+            break;
+          }
+        }
+        if (!match)
+          return false;
+      }
+      return true;
+    }
+    // Both the right and left sides have qualifiers.
+    for (ObjCObjectPointerType::qual_iterator I = lhsOPT->qual_begin(),
+         E = lhsOPT->qual_end(); I != E; ++I) {
+      ObjCProtocolDecl *lhsProto = *I;
+      bool match = false;
+
+      // when comparing an id<P> on lhs with a static type on rhs,
+      // see if static class implements all of id's protocols, directly or
+      // through its super class and categories.
+      for (ObjCObjectPointerType::qual_iterator J = rhsQID->qual_begin(),
+           E = rhsQID->qual_end(); J != E; ++J) {
+        ObjCProtocolDecl *rhsProto = *J;
+        if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto) ||
+            (compare && ProtocolCompatibleWithProtocol(rhsProto, lhsProto))) {
+          match = true;
+          break;
+        }
+      }
+      if (!match)
+        return false;
+    }
+    return true;
+  }
+  return false;
+}
+
+/// canAssignObjCInterfaces - Return true if the two interface types are
+/// compatible for assignment from RHS to LHS.  This handles validation of any
+/// protocol qualifiers on the LHS or RHS.
+///
+bool ASTContext::canAssignObjCInterfaces(const ObjCObjectPointerType *LHSOPT,
+                                         const ObjCObjectPointerType *RHSOPT) {
+  // If either type represents the built-in 'id' or 'Class' types, return true.
+  if (LHSOPT->isObjCBuiltinType() || RHSOPT->isObjCBuiltinType())
+    return true;
+
+  if (LHSOPT->isObjCQualifiedIdType() || RHSOPT->isObjCQualifiedIdType())
+    return ObjCQualifiedIdTypesAreCompatible(QualType(LHSOPT,0),
+                                             QualType(RHSOPT,0),
+                                             false);
+
+  const ObjCInterfaceType* LHS = LHSOPT->getInterfaceType();
+  const ObjCInterfaceType* RHS = RHSOPT->getInterfaceType();
+  if (LHS && RHS) // We have 2 user-defined types.
+    return canAssignObjCInterfaces(LHS, RHS);
+
+  return false;
+}
+
+/// canAssignObjCInterfacesInBlockPointer - This routine is specifically written
+/// for providing type-safty for objective-c pointers used to pass/return 
+/// arguments in block literals. When passed as arguments, passing 'A*' where
+/// 'id' is expected is not OK. Passing 'Sub *" where 'Super *" is expected is
+/// not OK. For the return type, the opposite is not OK.
+bool ASTContext::canAssignObjCInterfacesInBlockPointer(
+                                         const ObjCObjectPointerType *LHSOPT,
+                                         const ObjCObjectPointerType *RHSOPT) {
+  if (RHSOPT->isObjCBuiltinType() || LHSOPT->isObjCIdType())
+    return true;
+  
+  if (LHSOPT->isObjCBuiltinType()) {
+    return RHSOPT->isObjCBuiltinType() || RHSOPT->isObjCQualifiedIdType();
+  }
+  
+  if (LHSOPT->isObjCQualifiedIdType() || RHSOPT->isObjCQualifiedIdType())
+    return ObjCQualifiedIdTypesAreCompatible(QualType(LHSOPT,0),
+                                             QualType(RHSOPT,0),
+                                             false);
+  
+  const ObjCInterfaceType* LHS = LHSOPT->getInterfaceType();
+  const ObjCInterfaceType* RHS = RHSOPT->getInterfaceType();
+  if (LHS && RHS)  { // We have 2 user-defined types.
+    if (LHS != RHS) {
+      if (LHS->getDecl()->isSuperClassOf(RHS->getDecl()))
+        return false;
+      if (RHS->getDecl()->isSuperClassOf(LHS->getDecl()))
+        return true;
+    }
+    else
+      return true;
+  }
+  return false;
+}
+
+/// getIntersectionOfProtocols - This routine finds the intersection of set
+/// of protocols inherited from two distinct objective-c pointer objects.
+/// It is used to build composite qualifier list of the composite type of
+/// the conditional expression involving two objective-c pointer objects.
+static 
+void getIntersectionOfProtocols(ASTContext &Context,
+                                const ObjCObjectPointerType *LHSOPT,
+                                const ObjCObjectPointerType *RHSOPT,
+      llvm::SmallVectorImpl<ObjCProtocolDecl *> &IntersectionOfProtocols) {
+  
+  const ObjCInterfaceType* LHS = LHSOPT->getInterfaceType();
+  const ObjCInterfaceType* RHS = RHSOPT->getInterfaceType();
+  
+  llvm::SmallPtrSet<ObjCProtocolDecl *, 8> InheritedProtocolSet;
+  unsigned LHSNumProtocols = LHS->getNumProtocols();
+  if (LHSNumProtocols > 0)
+    InheritedProtocolSet.insert(LHS->qual_begin(), LHS->qual_end());
+  else {
+    llvm::SmallPtrSet<ObjCProtocolDecl *, 8> LHSInheritedProtocols;
+    Context.CollectInheritedProtocols(LHS->getDecl(), LHSInheritedProtocols);
+    InheritedProtocolSet.insert(LHSInheritedProtocols.begin(), 
+                                LHSInheritedProtocols.end());
+  }
+  
+  unsigned RHSNumProtocols = RHS->getNumProtocols();
+  if (RHSNumProtocols > 0) {
+    ObjCProtocolDecl **RHSProtocols =
+      const_cast<ObjCProtocolDecl **>(RHS->qual_begin());
+    for (unsigned i = 0; i < RHSNumProtocols; ++i)
+      if (InheritedProtocolSet.count(RHSProtocols[i]))
+        IntersectionOfProtocols.push_back(RHSProtocols[i]);
+  }
+  else {
+    llvm::SmallPtrSet<ObjCProtocolDecl *, 8> RHSInheritedProtocols;
+    Context.CollectInheritedProtocols(RHS->getDecl(), RHSInheritedProtocols);
+    for (llvm::SmallPtrSet<ObjCProtocolDecl*,8>::iterator I = 
+         RHSInheritedProtocols.begin(),
+         E = RHSInheritedProtocols.end(); I != E; ++I) 
+      if (InheritedProtocolSet.count((*I)))
+        IntersectionOfProtocols.push_back((*I));
+  }
+}
+
+/// areCommonBaseCompatible - Returns common base class of the two classes if
+/// one found. Note that this is O'2 algorithm. But it will be called as the
+/// last type comparison in a ?-exp of ObjC pointer types before a 
+/// warning is issued. So, its invokation is extremely rare.
+QualType ASTContext::areCommonBaseCompatible(
+                                          const ObjCObjectPointerType *LHSOPT,
+                                          const ObjCObjectPointerType *RHSOPT) {
+  const ObjCInterfaceType* LHS = LHSOPT->getInterfaceType();
+  const ObjCInterfaceType* RHS = RHSOPT->getInterfaceType();
+  if (!LHS || !RHS)
+    return QualType();
+  
+  while (const ObjCInterfaceDecl *LHSIDecl = LHS->getDecl()->getSuperClass()) {
+    QualType LHSTy = getObjCInterfaceType(LHSIDecl);
+    LHS = LHSTy->getAs<ObjCInterfaceType>();
+    if (canAssignObjCInterfaces(LHS, RHS)) {
+      llvm::SmallVector<ObjCProtocolDecl *, 8> IntersectionOfProtocols;
+      getIntersectionOfProtocols(*this, 
+                                 LHSOPT, RHSOPT, IntersectionOfProtocols);
+      if (IntersectionOfProtocols.empty())
+        LHSTy = getObjCObjectPointerType(LHSTy);
+      else
+        LHSTy = getObjCObjectPointerType(LHSTy, &IntersectionOfProtocols[0],
+                                                IntersectionOfProtocols.size());
+      return LHSTy;
+    }
+  }
+    
+  return QualType();
+}
+
+bool ASTContext::canAssignObjCInterfaces(const ObjCInterfaceType *LHS,
+                                         const ObjCInterfaceType *RHS) {
+  // Verify that the base decls are compatible: the RHS must be a subclass of
+  // the LHS.
+  if (!LHS->getDecl()->isSuperClassOf(RHS->getDecl()))
+    return false;
+
+  // RHS must have a superset of the protocols in the LHS.  If the LHS is not
+  // protocol qualified at all, then we are good.
+  if (LHS->getNumProtocols() == 0)
+    return true;
+
+  // Okay, we know the LHS has protocol qualifiers.  If the RHS doesn't, then it
+  // isn't a superset.
+  if (RHS->getNumProtocols() == 0)
+    return true;  // FIXME: should return false!
+
+  for (ObjCInterfaceType::qual_iterator LHSPI = LHS->qual_begin(),
+                                        LHSPE = LHS->qual_end();
+       LHSPI != LHSPE; LHSPI++) {
+    bool RHSImplementsProtocol = false;
+
+    // If the RHS doesn't implement the protocol on the left, the types
+    // are incompatible.
+    for (ObjCInterfaceType::qual_iterator RHSPI = RHS->qual_begin(),
+                                          RHSPE = RHS->qual_end();
+         RHSPI != RHSPE; RHSPI++) {
+      if ((*RHSPI)->lookupProtocolNamed((*LHSPI)->getIdentifier())) {
+        RHSImplementsProtocol = true;
+        break;
+      }
+    }
+    // FIXME: For better diagnostics, consider passing back the protocol name.
+    if (!RHSImplementsProtocol)
+      return false;
+  }
+  // The RHS implements all protocols listed on the LHS.
+  return true;
+}
+
+bool ASTContext::areComparableObjCPointerTypes(QualType LHS, QualType RHS) {
+  // get the "pointed to" types
+  const ObjCObjectPointerType *LHSOPT = LHS->getAs<ObjCObjectPointerType>();
+  const ObjCObjectPointerType *RHSOPT = RHS->getAs<ObjCObjectPointerType>();
+
+  if (!LHSOPT || !RHSOPT)
+    return false;
+
+  return canAssignObjCInterfaces(LHSOPT, RHSOPT) ||
+         canAssignObjCInterfaces(RHSOPT, LHSOPT);
+}
+
+/// typesAreCompatible - C99 6.7.3p9: For two qualified types to be compatible,
+/// both shall have the identically qualified version of a compatible type.
+/// C99 6.2.7p1: Two types have compatible types if their types are the
+/// same. See 6.7.[2,3,5] for additional rules.
+bool ASTContext::typesAreCompatible(QualType LHS, QualType RHS) {
+  if (getLangOptions().CPlusPlus)
+    return hasSameType(LHS, RHS);
+  
+  return !mergeTypes(LHS, RHS).isNull();
+}
+
+bool ASTContext::typesAreBlockPointerCompatible(QualType LHS, QualType RHS) {
+  return !mergeTypes(LHS, RHS, true).isNull();
+}
+
+QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs, 
+                                        bool OfBlockPointer) {
+  const FunctionType *lbase = lhs->getAs<FunctionType>();
+  const FunctionType *rbase = rhs->getAs<FunctionType>();
+  const FunctionProtoType *lproto = dyn_cast<FunctionProtoType>(lbase);
+  const FunctionProtoType *rproto = dyn_cast<FunctionProtoType>(rbase);
+  bool allLTypes = true;
+  bool allRTypes = true;
+
+  // Check return type
+  QualType retType;
+  if (OfBlockPointer)
+    retType = mergeTypes(rbase->getResultType(), lbase->getResultType(), true);
+  else
+   retType = mergeTypes(lbase->getResultType(), rbase->getResultType());
+  if (retType.isNull()) return QualType();
+  if (getCanonicalType(retType) != getCanonicalType(lbase->getResultType()))
+    allLTypes = false;
+  if (getCanonicalType(retType) != getCanonicalType(rbase->getResultType()))
+    allRTypes = false;
+  // FIXME: double check this
+  // FIXME: should we error if lbase->getRegParmAttr() != 0 &&
+  //                           rbase->getRegParmAttr() != 0 &&
+  //                           lbase->getRegParmAttr() != rbase->getRegParmAttr()?
+  FunctionType::ExtInfo lbaseInfo = lbase->getExtInfo();
+  FunctionType::ExtInfo rbaseInfo = rbase->getExtInfo();
+  unsigned RegParm = lbaseInfo.getRegParm() == 0 ? rbaseInfo.getRegParm() :
+      lbaseInfo.getRegParm();
+  bool NoReturn = lbaseInfo.getNoReturn() || rbaseInfo.getNoReturn();
+  if (NoReturn != lbaseInfo.getNoReturn() ||
+      RegParm != lbaseInfo.getRegParm())
+    allLTypes = false;
+  if (NoReturn != rbaseInfo.getNoReturn() ||
+      RegParm != rbaseInfo.getRegParm())
+    allRTypes = false;
+  CallingConv lcc = lbaseInfo.getCC();
+  CallingConv rcc = rbaseInfo.getCC();
+  // Compatible functions must have compatible calling conventions
+  if (!isSameCallConv(lcc, rcc))
+    return QualType();
+
+  if (lproto && rproto) { // two C99 style function prototypes
+    assert(!lproto->hasExceptionSpec() && !rproto->hasExceptionSpec() &&
+           "C++ shouldn't be here");
+    unsigned lproto_nargs = lproto->getNumArgs();
+    unsigned rproto_nargs = rproto->getNumArgs();
+
+    // Compatible functions must have the same number of arguments
+    if (lproto_nargs != rproto_nargs)
+      return QualType();
+
+    // Variadic and non-variadic functions aren't compatible
+    if (lproto->isVariadic() != rproto->isVariadic())
+      return QualType();
+
+    if (lproto->getTypeQuals() != rproto->getTypeQuals())
+      return QualType();
+
+    // Check argument compatibility
+    llvm::SmallVector<QualType, 10> types;
+    for (unsigned i = 0; i < lproto_nargs; i++) {
+      QualType largtype = lproto->getArgType(i).getUnqualifiedType();
+      QualType rargtype = rproto->getArgType(i).getUnqualifiedType();
+      QualType argtype = mergeTypes(largtype, rargtype, OfBlockPointer);
+      if (argtype.isNull()) return QualType();
+      types.push_back(argtype);
+      if (getCanonicalType(argtype) != getCanonicalType(largtype))
+        allLTypes = false;
+      if (getCanonicalType(argtype) != getCanonicalType(rargtype))
+        allRTypes = false;
+    }
+    if (allLTypes) return lhs;
+    if (allRTypes) return rhs;
+    return getFunctionType(retType, types.begin(), types.size(),
+                           lproto->isVariadic(), lproto->getTypeQuals(),
+                           false, false, 0, 0,
+                           FunctionType::ExtInfo(NoReturn, RegParm, lcc));
+  }
+
+  if (lproto) allRTypes = false;
+  if (rproto) allLTypes = false;
+
+  const FunctionProtoType *proto = lproto ? lproto : rproto;
+  if (proto) {
+    assert(!proto->hasExceptionSpec() && "C++ shouldn't be here");
+    if (proto->isVariadic()) return QualType();
+    // Check that the types are compatible with the types that
+    // would result from default argument promotions (C99 6.7.5.3p15).
+    // The only types actually affected are promotable integer
+    // types and floats, which would be passed as a different
+    // type depending on whether the prototype is visible.
+    unsigned proto_nargs = proto->getNumArgs();
+    for (unsigned i = 0; i < proto_nargs; ++i) {
+      QualType argTy = proto->getArgType(i);
+      
+      // Look at the promotion type of enum types, since that is the type used
+      // to pass enum values.
+      if (const EnumType *Enum = argTy->getAs<EnumType>())
+        argTy = Enum->getDecl()->getPromotionType();
+      
+      if (argTy->isPromotableIntegerType() ||
+          getCanonicalType(argTy).getUnqualifiedType() == FloatTy)
+        return QualType();
+    }
+
+    if (allLTypes) return lhs;
+    if (allRTypes) return rhs;
+    return getFunctionType(retType, proto->arg_type_begin(),
+                           proto->getNumArgs(), proto->isVariadic(),
+                           proto->getTypeQuals(),
+                           false, false, 0, 0,
+                           FunctionType::ExtInfo(NoReturn, RegParm, lcc));
+  }
+
+  if (allLTypes) return lhs;
+  if (allRTypes) return rhs;
+  FunctionType::ExtInfo Info(NoReturn, RegParm, lcc);
+  return getFunctionNoProtoType(retType, Info);
+}
+
+QualType ASTContext::mergeTypes(QualType LHS, QualType RHS, 
+                                bool OfBlockPointer) {
+  // C++ [expr]: If an expression initially has the type "reference to T", the
+  // type is adjusted to "T" prior to any further analysis, the expression
+  // designates the object or function denoted by the reference, and the
+  // expression is an lvalue unless the reference is an rvalue reference and
+  // the expression is a function call (possibly inside parentheses).
+  assert(!LHS->getAs<ReferenceType>() && "LHS is a reference type?");
+  assert(!RHS->getAs<ReferenceType>() && "RHS is a reference type?");
+  
+  QualType LHSCan = getCanonicalType(LHS),
+           RHSCan = getCanonicalType(RHS);
+
+  // If two types are identical, they are compatible.
+  if (LHSCan == RHSCan)
+    return LHS;
+
+  // If the qualifiers are different, the types aren't compatible... mostly.
+  Qualifiers LQuals = LHSCan.getLocalQualifiers();
+  Qualifiers RQuals = RHSCan.getLocalQualifiers();
+  if (LQuals != RQuals) {
+    // If any of these qualifiers are different, we have a type
+    // mismatch.
+    if (LQuals.getCVRQualifiers() != RQuals.getCVRQualifiers() ||
+        LQuals.getAddressSpace() != RQuals.getAddressSpace())
+      return QualType();
+
+    // Exactly one GC qualifier difference is allowed: __strong is
+    // okay if the other type has no GC qualifier but is an Objective
+    // C object pointer (i.e. implicitly strong by default).  We fix
+    // this by pretending that the unqualified type was actually
+    // qualified __strong.
+    Qualifiers::GC GC_L = LQuals.getObjCGCAttr();
+    Qualifiers::GC GC_R = RQuals.getObjCGCAttr();
+    assert((GC_L != GC_R) && "unequal qualifier sets had only equal elements");
+
+    if (GC_L == Qualifiers::Weak || GC_R == Qualifiers::Weak)
+      return QualType();
+
+    if (GC_L == Qualifiers::Strong && RHSCan->isObjCObjectPointerType()) {
+      return mergeTypes(LHS, getObjCGCQualType(RHS, Qualifiers::Strong));
+    }
+    if (GC_R == Qualifiers::Strong && LHSCan->isObjCObjectPointerType()) {
+      return mergeTypes(getObjCGCQualType(LHS, Qualifiers::Strong), RHS);
+    }
+    return QualType();
+  }
+
+  // Okay, qualifiers are equal.
+
+  Type::TypeClass LHSClass = LHSCan->getTypeClass();
+  Type::TypeClass RHSClass = RHSCan->getTypeClass();
+
+  // We want to consider the two function types to be the same for these
+  // comparisons, just force one to the other.
+  if (LHSClass == Type::FunctionProto) LHSClass = Type::FunctionNoProto;
+  if (RHSClass == Type::FunctionProto) RHSClass = Type::FunctionNoProto;
+
+  // Same as above for arrays
+  if (LHSClass == Type::VariableArray || LHSClass == Type::IncompleteArray)
+    LHSClass = Type::ConstantArray;
+  if (RHSClass == Type::VariableArray || RHSClass == Type::IncompleteArray)
+    RHSClass = Type::ConstantArray;
+
+  // Canonicalize ExtVector -> Vector.
+  if (LHSClass == Type::ExtVector) LHSClass = Type::Vector;
+  if (RHSClass == Type::ExtVector) RHSClass = Type::Vector;
+
+  // If the canonical type classes don't match.
+  if (LHSClass != RHSClass) {
+    // C99 6.7.2.2p4: Each enumerated type shall be compatible with char,
+    // a signed integer type, or an unsigned integer type.
+    // Compatibility is based on the underlying type, not the promotion
+    // type.
+    if (const EnumType* ETy = LHS->getAs<EnumType>()) {
+      if (ETy->getDecl()->getIntegerType() == RHSCan.getUnqualifiedType())
+        return RHS;
+    }
+    if (const EnumType* ETy = RHS->getAs<EnumType>()) {
+      if (ETy->getDecl()->getIntegerType() == LHSCan.getUnqualifiedType())
+        return LHS;
+    }
+
+    return QualType();
+  }
+
+  // The canonical type classes match.
+  switch (LHSClass) {
+#define TYPE(Class, Base)
+#define ABSTRACT_TYPE(Class, Base)
+#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
+#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
+#define DEPENDENT_TYPE(Class, Base) case Type::Class:
+#include "clang/AST/TypeNodes.def"
+    assert(false && "Non-canonical and dependent types shouldn't get here");
+    return QualType();
+
+  case Type::LValueReference:
+  case Type::RValueReference:
+  case Type::MemberPointer:
+    assert(false && "C++ should never be in mergeTypes");
+    return QualType();
+
+  case Type::IncompleteArray:
+  case Type::VariableArray:
+  case Type::FunctionProto:
+  case Type::ExtVector:
+    assert(false && "Types are eliminated above");
+    return QualType();
+
+  case Type::Pointer:
+  {
+    // Merge two pointer types, while trying to preserve typedef info
+    QualType LHSPointee = LHS->getAs<PointerType>()->getPointeeType();
+    QualType RHSPointee = RHS->getAs<PointerType>()->getPointeeType();
+    QualType ResultType = mergeTypes(LHSPointee, RHSPointee);
+    if (ResultType.isNull()) return QualType();
+    if (getCanonicalType(LHSPointee) == getCanonicalType(ResultType))
+      return LHS;
+    if (getCanonicalType(RHSPointee) == getCanonicalType(ResultType))
+      return RHS;
+    return getPointerType(ResultType);
+  }
+  case Type::BlockPointer:
+  {
+    // Merge two block pointer types, while trying to preserve typedef info
+    QualType LHSPointee = LHS->getAs<BlockPointerType>()->getPointeeType();
+    QualType RHSPointee = RHS->getAs<BlockPointerType>()->getPointeeType();
+    QualType ResultType = mergeTypes(LHSPointee, RHSPointee, OfBlockPointer);
+    if (ResultType.isNull()) return QualType();
+    if (getCanonicalType(LHSPointee) == getCanonicalType(ResultType))
+      return LHS;
+    if (getCanonicalType(RHSPointee) == getCanonicalType(ResultType))
+      return RHS;
+    return getBlockPointerType(ResultType);
+  }
+  case Type::ConstantArray:
+  {
+    const ConstantArrayType* LCAT = getAsConstantArrayType(LHS);
+    const ConstantArrayType* RCAT = getAsConstantArrayType(RHS);
+    if (LCAT && RCAT && RCAT->getSize() != LCAT->getSize())
+      return QualType();
+
+    QualType LHSElem = getAsArrayType(LHS)->getElementType();
+    QualType RHSElem = getAsArrayType(RHS)->getElementType();
+    QualType ResultType = mergeTypes(LHSElem, RHSElem);
+    if (ResultType.isNull()) return QualType();
+    if (LCAT && getCanonicalType(LHSElem) == getCanonicalType(ResultType))
+      return LHS;
+    if (RCAT && getCanonicalType(RHSElem) == getCanonicalType(ResultType))
+      return RHS;
+    if (LCAT) return getConstantArrayType(ResultType, LCAT->getSize(),
+                                          ArrayType::ArraySizeModifier(), 0);
+    if (RCAT) return getConstantArrayType(ResultType, RCAT->getSize(),
+                                          ArrayType::ArraySizeModifier(), 0);
+    const VariableArrayType* LVAT = getAsVariableArrayType(LHS);
+    const VariableArrayType* RVAT = getAsVariableArrayType(RHS);
+    if (LVAT && getCanonicalType(LHSElem) == getCanonicalType(ResultType))
+      return LHS;
+    if (RVAT && getCanonicalType(RHSElem) == getCanonicalType(ResultType))
+      return RHS;
+    if (LVAT) {
+      // FIXME: This isn't correct! But tricky to implement because
+      // the array's size has to be the size of LHS, but the type
+      // has to be different.
+      return LHS;
+    }
+    if (RVAT) {
+      // FIXME: This isn't correct! But tricky to implement because
+      // the array's size has to be the size of RHS, but the type
+      // has to be different.
+      return RHS;
+    }
+    if (getCanonicalType(LHSElem) == getCanonicalType(ResultType)) return LHS;
+    if (getCanonicalType(RHSElem) == getCanonicalType(ResultType)) return RHS;
+    return getIncompleteArrayType(ResultType,
+                                  ArrayType::ArraySizeModifier(), 0);
+  }
+  case Type::FunctionNoProto:
+    return mergeFunctionTypes(LHS, RHS, OfBlockPointer);
+  case Type::Record:
+  case Type::Enum:
+    return QualType();
+  case Type::Builtin:
+    // Only exactly equal builtin types are compatible, which is tested above.
+    return QualType();
+  case Type::Complex:
+    // Distinct complex types are incompatible.
+    return QualType();
+  case Type::Vector:
+    // FIXME: The merged type should be an ExtVector!
+    if (areCompatVectorTypes(LHSCan->getAs<VectorType>(),
+                             RHSCan->getAs<VectorType>()))
+      return LHS;
+    return QualType();
+  case Type::ObjCInterface: {
+    // Check if the interfaces are assignment compatible.
+    // FIXME: This should be type compatibility, e.g. whether
+    // "LHS x; RHS x;" at global scope is legal.
+    const ObjCInterfaceType* LHSIface = LHS->getAs<ObjCInterfaceType>();
+    const ObjCInterfaceType* RHSIface = RHS->getAs<ObjCInterfaceType>();
+    if (LHSIface && RHSIface &&
+        canAssignObjCInterfaces(LHSIface, RHSIface))
+      return LHS;
+
+    return QualType();
+  }
+  case Type::ObjCObjectPointer: {
+    if (OfBlockPointer) {
+      if (canAssignObjCInterfacesInBlockPointer(
+                                          LHS->getAs<ObjCObjectPointerType>(),
+                                          RHS->getAs<ObjCObjectPointerType>()))
+      return LHS;
+      return QualType();
+    }
+    if (canAssignObjCInterfaces(LHS->getAs<ObjCObjectPointerType>(),
+                                RHS->getAs<ObjCObjectPointerType>()))
+      return LHS;
+
+    return QualType();
+    }
+  }
+
+  return QualType();
+}
+
+//===----------------------------------------------------------------------===//
+//                         Integer Predicates
+//===----------------------------------------------------------------------===//
+
+unsigned ASTContext::getIntWidth(QualType T) {
+  if (T->isBooleanType())
+    return 1;
+  if (EnumType *ET = dyn_cast<EnumType>(T))
+    T = ET->getDecl()->getIntegerType();
+  // For builtin types, just use the standard type sizing method
+  return (unsigned)getTypeSize(T);
+}
+
+QualType ASTContext::getCorrespondingUnsignedType(QualType T) {
+  assert(T->isSignedIntegerType() && "Unexpected type");
+  
+  // Turn <4 x signed int> -> <4 x unsigned int>
+  if (const VectorType *VTy = T->getAs<VectorType>())
+    return getVectorType(getCorrespondingUnsignedType(VTy->getElementType()),
+             VTy->getNumElements(), VTy->isAltiVec(), VTy->isPixel());
+
+  // For enums, we return the unsigned version of the base type.
+  if (const EnumType *ETy = T->getAs<EnumType>())
+    T = ETy->getDecl()->getIntegerType();
+  
+  const BuiltinType *BTy = T->getAs<BuiltinType>();
+  assert(BTy && "Unexpected signed integer type");
+  switch (BTy->getKind()) {
+  case BuiltinType::Char_S:
+  case BuiltinType::SChar:
+    return UnsignedCharTy;
+  case BuiltinType::Short:
+    return UnsignedShortTy;
+  case BuiltinType::Int:
+    return UnsignedIntTy;
+  case BuiltinType::Long:
+    return UnsignedLongTy;
+  case BuiltinType::LongLong:
+    return UnsignedLongLongTy;
+  case BuiltinType::Int128:
+    return UnsignedInt128Ty;
+  default:
+    assert(0 && "Unexpected signed integer type");
+    return QualType();
+  }
+}
+
+ExternalASTSource::~ExternalASTSource() { }
+
+void ExternalASTSource::PrintStats() { }
+
+
+//===----------------------------------------------------------------------===//
+//                          Builtin Type Computation
+//===----------------------------------------------------------------------===//
+
+/// DecodeTypeFromStr - This decodes one type descriptor from Str, advancing the
+/// pointer over the consumed characters.  This returns the resultant type.
+static QualType DecodeTypeFromStr(const char *&Str, ASTContext &Context,
+                                  ASTContext::GetBuiltinTypeError &Error,
+                                  bool AllowTypeModifiers = true) {
+  // Modifiers.
+  int HowLong = 0;
+  bool Signed = false, Unsigned = false;
+
+  // Read the modifiers first.
+  bool Done = false;
+  while (!Done) {
+    switch (*Str++) {
+    default: Done = true; --Str; break;
+    case 'S':
+      assert(!Unsigned && "Can't use both 'S' and 'U' modifiers!");
+      assert(!Signed && "Can't use 'S' modifier multiple times!");
+      Signed = true;
+      break;
+    case 'U':
+      assert(!Signed && "Can't use both 'S' and 'U' modifiers!");
+      assert(!Unsigned && "Can't use 'S' modifier multiple times!");
+      Unsigned = true;
+      break;
+    case 'L':
+      assert(HowLong <= 2 && "Can't have LLLL modifier");
+      ++HowLong;
+      break;
+    }
+  }
+
+  QualType Type;
+
+  // Read the base type.
+  switch (*Str++) {
+  default: assert(0 && "Unknown builtin type letter!");
+  case 'v':
+    assert(HowLong == 0 && !Signed && !Unsigned &&
+           "Bad modifiers used with 'v'!");
+    Type = Context.VoidTy;
+    break;
+  case 'f':
+    assert(HowLong == 0 && !Signed && !Unsigned &&
+           "Bad modifiers used with 'f'!");
+    Type = Context.FloatTy;
+    break;
+  case 'd':
+    assert(HowLong < 2 && !Signed && !Unsigned &&
+           "Bad modifiers used with 'd'!");
+    if (HowLong)
+      Type = Context.LongDoubleTy;
+    else
+      Type = Context.DoubleTy;
+    break;
+  case 's':
+    assert(HowLong == 0 && "Bad modifiers used with 's'!");
+    if (Unsigned)
+      Type = Context.UnsignedShortTy;
+    else
+      Type = Context.ShortTy;
+    break;
+  case 'i':
+    if (HowLong == 3)
+      Type = Unsigned ? Context.UnsignedInt128Ty : Context.Int128Ty;
+    else if (HowLong == 2)
+      Type = Unsigned ? Context.UnsignedLongLongTy : Context.LongLongTy;
+    else if (HowLong == 1)
+      Type = Unsigned ? Context.UnsignedLongTy : Context.LongTy;
+    else
+      Type = Unsigned ? Context.UnsignedIntTy : Context.IntTy;
+    break;
+  case 'c':
+    assert(HowLong == 0 && "Bad modifiers used with 'c'!");
+    if (Signed)
+      Type = Context.SignedCharTy;
+    else if (Unsigned)
+      Type = Context.UnsignedCharTy;
+    else
+      Type = Context.CharTy;
+    break;
+  case 'b': // boolean
+    assert(HowLong == 0 && !Signed && !Unsigned && "Bad modifiers for 'b'!");
+    Type = Context.BoolTy;
+    break;
+  case 'z':  // size_t.
+    assert(HowLong == 0 && !Signed && !Unsigned && "Bad modifiers for 'z'!");
+    Type = Context.getSizeType();
+    break;
+  case 'F':
+    Type = Context.getCFConstantStringType();
+    break;
+  case 'a':
+    Type = Context.getBuiltinVaListType();
+    assert(!Type.isNull() && "builtin va list type not initialized!");
+    break;
+  case 'A':
+    // This is a "reference" to a va_list; however, what exactly
+    // this means depends on how va_list is defined. There are two
+    // different kinds of va_list: ones passed by value, and ones
+    // passed by reference.  An example of a by-value va_list is
+    // x86, where va_list is a char*. An example of by-ref va_list
+    // is x86-64, where va_list is a __va_list_tag[1]. For x86,
+    // we want this argument to be a char*&; for x86-64, we want
+    // it to be a __va_list_tag*.
+    Type = Context.getBuiltinVaListType();
+    assert(!Type.isNull() && "builtin va list type not initialized!");
+    if (Type->isArrayType()) {
+      Type = Context.getArrayDecayedType(Type);
+    } else {
+      Type = Context.getLValueReferenceType(Type);
+    }
+    break;
+  case 'V': {
+    char *End;
+    unsigned NumElements = strtoul(Str, &End, 10);
+    assert(End != Str && "Missing vector size");
+
+    Str = End;
+
+    QualType ElementType = DecodeTypeFromStr(Str, Context, Error, false);
+    // FIXME: Don't know what to do about AltiVec.
+    Type = Context.getVectorType(ElementType, NumElements, false, false);
+    break;
+  }
+  case 'X': {
+    QualType ElementType = DecodeTypeFromStr(Str, Context, Error, false);
+    Type = Context.getComplexType(ElementType);
+    break;
+  }      
+  case 'P':
+    Type = Context.getFILEType();
+    if (Type.isNull()) {
+      Error = ASTContext::GE_Missing_stdio;
+      return QualType();
+    }
+    break;
+  case 'J':
+    if (Signed)
+      Type = Context.getsigjmp_bufType();
+    else
+      Type = Context.getjmp_bufType();
+
+    if (Type.isNull()) {
+      Error = ASTContext::GE_Missing_setjmp;
+      return QualType();
+    }
+    break;
+  }
+
+  if (!AllowTypeModifiers)
+    return Type;
+
+  Done = false;
+  while (!Done) {
+    switch (char c = *Str++) {
+      default: Done = true; --Str; break;
+      case '*':
+      case '&':
+        {
+          // Both pointers and references can have their pointee types
+          // qualified with an address space.
+          char *End;
+          unsigned AddrSpace = strtoul(Str, &End, 10);
+          if (End != Str && AddrSpace != 0) {
+            Type = Context.getAddrSpaceQualType(Type, AddrSpace);
+            Str = End;
+          }
+        }
+        if (c == '*')
+          Type = Context.getPointerType(Type);
+        else
+          Type = Context.getLValueReferenceType(Type);
+        break;
+      // FIXME: There's no way to have a built-in with an rvalue ref arg.
+      case 'C':
+        Type = Type.withConst();
+        break;
+      case 'D':
+        Type = Context.getVolatileType(Type);
+        break;
+    }
+  }
+
+  return Type;
+}
+
+/// GetBuiltinType - Return the type for the specified builtin.
+QualType ASTContext::GetBuiltinType(unsigned id,
+                                    GetBuiltinTypeError &Error) {
+  const char *TypeStr = BuiltinInfo.GetTypeString(id);
+
+  llvm::SmallVector<QualType, 8> ArgTypes;
+
+  Error = GE_None;
+  QualType ResType = DecodeTypeFromStr(TypeStr, *this, Error);
+  if (Error != GE_None)
+    return QualType();
+  while (TypeStr[0] && TypeStr[0] != '.') {
+    QualType Ty = DecodeTypeFromStr(TypeStr, *this, Error);
+    if (Error != GE_None)
+      return QualType();
+
+    // Do array -> pointer decay.  The builtin should use the decayed type.
+    if (Ty->isArrayType())
+      Ty = getArrayDecayedType(Ty);
+
+    ArgTypes.push_back(Ty);
+  }
+
+  assert((TypeStr[0] != '.' || TypeStr[1] == 0) &&
+         "'.' should only occur at end of builtin type list!");
+
+  // handle untyped/variadic arguments "T c99Style();" or "T cppStyle(...);".
+  if (ArgTypes.size() == 0 && TypeStr[0] == '.')
+    return getFunctionNoProtoType(ResType);
+
+  // FIXME: Should we create noreturn types?
+  return getFunctionType(ResType, ArgTypes.data(), ArgTypes.size(),
+                         TypeStr[0] == '.', 0, false, false, 0, 0,
+                         FunctionType::ExtInfo());
+}
+
+QualType
+ASTContext::UsualArithmeticConversionsType(QualType lhs, QualType rhs) {
+  // Perform the usual unary conversions. We do this early so that
+  // integral promotions to "int" can allow us to exit early, in the
+  // lhs == rhs check. Also, for conversion purposes, we ignore any
+  // qualifiers.  For example, "const float" and "float" are
+  // equivalent.
+  if (lhs->isPromotableIntegerType())
+    lhs = getPromotedIntegerType(lhs);
+  else
+    lhs = lhs.getUnqualifiedType();
+  if (rhs->isPromotableIntegerType())
+    rhs = getPromotedIntegerType(rhs);
+  else
+    rhs = rhs.getUnqualifiedType();
+
+  // If both types are identical, no conversion is needed.
+  if (lhs == rhs)
+    return lhs;
+
+  // If either side is a non-arithmetic type (e.g. a pointer), we are done.
+  // The caller can deal with this (e.g. pointer + int).
+  if (!lhs->isArithmeticType() || !rhs->isArithmeticType())
+    return lhs;
+
+  // At this point, we have two different arithmetic types.
+
+  // Handle complex types first (C99 6.3.1.8p1).
+  if (lhs->isComplexType() || rhs->isComplexType()) {
+    // if we have an integer operand, the result is the complex type.
+    if (rhs->isIntegerType() || rhs->isComplexIntegerType()) {
+      // convert the rhs to the lhs complex type.
+      return lhs;
+    }
+    if (lhs->isIntegerType() || lhs->isComplexIntegerType()) {
+      // convert the lhs to the rhs complex type.
+      return rhs;
+    }
+    // This handles complex/complex, complex/float, or float/complex.
+    // When both operands are complex, the shorter operand is converted to the
+    // type of the longer, and that is the type of the result. This corresponds
+    // to what is done when combining two real floating-point operands.
+    // The fun begins when size promotion occur across type domains.
+    // From H&S 6.3.4: When one operand is complex and the other is a real
+    // floating-point type, the less precise type is converted, within it's
+    // real or complex domain, to the precision of the other type. For example,
+    // when combining a "long double" with a "double _Complex", the
+    // "double _Complex" is promoted to "long double _Complex".
+    int result = getFloatingTypeOrder(lhs, rhs);
+
+    if (result > 0) { // The left side is bigger, convert rhs.
+      rhs = getFloatingTypeOfSizeWithinDomain(lhs, rhs);
+    } else if (result < 0) { // The right side is bigger, convert lhs.
+      lhs = getFloatingTypeOfSizeWithinDomain(rhs, lhs);
+    }
+    // At this point, lhs and rhs have the same rank/size. Now, make sure the
+    // domains match. This is a requirement for our implementation, C99
+    // does not require this promotion.
+    if (lhs != rhs) { // Domains don't match, we have complex/float mix.
+      if (lhs->isRealFloatingType()) { // handle "double, _Complex double".
+        return rhs;
+      } else { // handle "_Complex double, double".
+        return lhs;
+      }
+    }
+    return lhs; // The domain/size match exactly.
+  }
+  // Now handle "real" floating types (i.e. float, double, long double).
+  if (lhs->isRealFloatingType() || rhs->isRealFloatingType()) {
+    // if we have an integer operand, the result is the real floating type.
+    if (rhs->isIntegerType()) {
+      // convert rhs to the lhs floating point type.
+      return lhs;
+    }
+    if (rhs->isComplexIntegerType()) {
+      // convert rhs to the complex floating point type.
+      return getComplexType(lhs);
+    }
+    if (lhs->isIntegerType()) {
+      // convert lhs to the rhs floating point type.
+      return rhs;
+    }
+    if (lhs->isComplexIntegerType()) {
+      // convert lhs to the complex floating point type.
+      return getComplexType(rhs);
+    }
+    // We have two real floating types, float/complex combos were handled above.
+    // Convert the smaller operand to the bigger result.
+    int result = getFloatingTypeOrder(lhs, rhs);
+    if (result > 0) // convert the rhs
+      return lhs;
+    assert(result < 0 && "illegal float comparison");
+    return rhs;   // convert the lhs
+  }
+  if (lhs->isComplexIntegerType() || rhs->isComplexIntegerType()) {
+    // Handle GCC complex int extension.
+    const ComplexType *lhsComplexInt = lhs->getAsComplexIntegerType();
+    const ComplexType *rhsComplexInt = rhs->getAsComplexIntegerType();
+
+    if (lhsComplexInt && rhsComplexInt) {
+      if (getIntegerTypeOrder(lhsComplexInt->getElementType(),
+                              rhsComplexInt->getElementType()) >= 0)
+        return lhs; // convert the rhs
+      return rhs;
+    } else if (lhsComplexInt && rhs->isIntegerType()) {
+      // convert the rhs to the lhs complex type.
+      return lhs;
+    } else if (rhsComplexInt && lhs->isIntegerType()) {
+      // convert the lhs to the rhs complex type.
+      return rhs;
+    }
+  }
+  // Finally, we have two differing integer types.
+  // The rules for this case are in C99 6.3.1.8
+  int compare = getIntegerTypeOrder(lhs, rhs);
+  bool lhsSigned = lhs->isSignedIntegerType(),
+       rhsSigned = rhs->isSignedIntegerType();
+  QualType destType;
+  if (lhsSigned == rhsSigned) {
+    // Same signedness; use the higher-ranked type
+    destType = compare >= 0 ? lhs : rhs;
+  } else if (compare != (lhsSigned ? 1 : -1)) {
+    // The unsigned type has greater than or equal rank to the
+    // signed type, so use the unsigned type
+    destType = lhsSigned ? rhs : lhs;
+  } else if (getIntWidth(lhs) != getIntWidth(rhs)) {
+    // The two types are different widths; if we are here, that
+    // means the signed type is larger than the unsigned type, so
+    // use the signed type.
+    destType = lhsSigned ? lhs : rhs;
+  } else {
+    // The signed type is higher-ranked than the unsigned type,
+    // but isn't actually any bigger (like unsigned int and long
+    // on most 32-bit systems).  Use the unsigned type corresponding
+    // to the signed type.
+    destType = getCorrespondingUnsignedType(lhsSigned ? lhs : rhs);
+  }
+  return destType;
+}
diff --git a/lib/AST/ASTDiagnostic.cpp b/lib/AST/ASTDiagnostic.cpp
new file mode 100644
index 0000000..e4cd2a9
--- /dev/null
+++ b/lib/AST/ASTDiagnostic.cpp
@@ -0,0 +1,266 @@
+//===--- ASTDiagnostic.cpp - Diagnostic Printing Hooks for AST Nodes ------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a diagnostic formatting hook for AST elements.
+//
+//===----------------------------------------------------------------------===//
+#include "clang/AST/ASTDiagnostic.h"
+
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/Type.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace clang;
+
+/// Determines whether we should have an a.k.a. clause when
+/// pretty-printing a type.  There are three main criteria:
+///
+/// 1) Some types provide very minimal sugar that doesn't impede the
+///    user's understanding --- for example, elaborated type
+///    specifiers.  If this is all the sugar we see, we don't want an
+///    a.k.a. clause.
+/// 2) Some types are technically sugared but are much more familiar
+///    when seen in their sugared form --- for example, va_list,
+///    vector types, and the magic Objective C types.  We don't
+///    want to desugar these, even if we do produce an a.k.a. clause.
+/// 3) Some types may have already been desugared previously in this diagnostic.
+///    if this is the case, doing another "aka" would just be clutter.
+///
+static bool ShouldAKA(ASTContext &Context, QualType QT,
+                      const Diagnostic::ArgumentValue *PrevArgs,
+                      unsigned NumPrevArgs,
+                      QualType &DesugaredQT) {
+  QualType InputTy = QT;
+  
+  bool AKA = false;
+  QualifierCollector Qc;
+  
+  while (true) {
+    const Type *Ty = Qc.strip(QT);
+    
+    // Don't aka just because we saw an elaborated type...
+    if (isa<ElaboratedType>(Ty)) {
+      QT = cast<ElaboratedType>(Ty)->desugar();
+      continue;
+    }
+    
+    // ...or a qualified name type...
+    if (isa<QualifiedNameType>(Ty)) {
+      QT = cast<QualifiedNameType>(Ty)->desugar();
+      continue;
+    }
+
+    // ...or a substituted template type parameter.
+    if (isa<SubstTemplateTypeParmType>(Ty)) {
+      QT = cast<SubstTemplateTypeParmType>(Ty)->desugar();
+      continue;
+    }
+    
+    // Don't desugar template specializations. 
+    if (isa<TemplateSpecializationType>(Ty))
+      break;
+    
+    // Don't desugar magic Objective-C types.
+    if (QualType(Ty,0) == Context.getObjCIdType() ||
+        QualType(Ty,0) == Context.getObjCClassType() ||
+        QualType(Ty,0) == Context.getObjCSelType() ||
+        QualType(Ty,0) == Context.getObjCProtoType())
+      break;
+    
+    // Don't desugar va_list.
+    if (QualType(Ty,0) == Context.getBuiltinVaListType())
+      break;
+    
+    // Otherwise, do a single-step desugar.
+    QualType Underlying;
+    bool IsSugar = false;
+    switch (Ty->getTypeClass()) {
+#define ABSTRACT_TYPE(Class, Base)
+#define TYPE(Class, Base) \
+case Type::Class: { \
+const Class##Type *CTy = cast<Class##Type>(Ty); \
+if (CTy->isSugared()) { \
+IsSugar = true; \
+Underlying = CTy->desugar(); \
+} \
+break; \
+}
+#include "clang/AST/TypeNodes.def"
+    }
+    
+    // If it wasn't sugared, we're done.
+    if (!IsSugar)
+      break;
+    
+    // If the desugared type is a vector type, we don't want to expand
+    // it, it will turn into an attribute mess. People want their "vec4".
+    if (isa<VectorType>(Underlying))
+      break;
+    
+    // Don't desugar through the primary typedef of an anonymous type.
+    if (isa<TagType>(Underlying) && isa<TypedefType>(QT))
+      if (cast<TagType>(Underlying)->getDecl()->getTypedefForAnonDecl() ==
+          cast<TypedefType>(QT)->getDecl())
+        break;
+    
+    // Otherwise, we're tearing through something opaque; note that
+    // we'll eventually need an a.k.a. clause and keep going.
+    AKA = true;
+    QT = Underlying;
+    continue;
+  }
+  
+  // If we never tore through opaque sugar, don't print aka.
+  if (!AKA) return false;
+  
+  // If we did, check to see if we already desugared this type in this
+  // diagnostic.  If so, don't do it again.
+  for (unsigned i = 0; i != NumPrevArgs; ++i) {
+    // TODO: Handle ak_declcontext case.
+    if (PrevArgs[i].first == Diagnostic::ak_qualtype) {
+      void *Ptr = (void*)PrevArgs[i].second;
+      QualType PrevTy(QualType::getFromOpaquePtr(Ptr));
+      if (PrevTy == InputTy)
+        return false;
+    }
+  }
+  
+  DesugaredQT = Qc.apply(QT);
+  return true;
+}
+
+/// \brief Convert the given type to a string suitable for printing as part of 
+/// a diagnostic. 
+///
+/// \param Context the context in which the type was allocated
+/// \param Ty the type to print
+static std::string
+ConvertTypeToDiagnosticString(ASTContext &Context, QualType Ty,
+                              const Diagnostic::ArgumentValue *PrevArgs,
+                              unsigned NumPrevArgs) {
+  // FIXME: Playing with std::string is really slow.
+  std::string S = Ty.getAsString(Context.PrintingPolicy);
+  
+  // Consider producing an a.k.a. clause if removing all the direct
+  // sugar gives us something "significantly different".
+  
+  QualType DesugaredTy;
+  if (ShouldAKA(Context, Ty, PrevArgs, NumPrevArgs, DesugaredTy)) {
+    S = "'"+S+"' (aka '";
+    S += DesugaredTy.getAsString(Context.PrintingPolicy);
+    S += "')";
+    return S;
+  }
+  
+  S = "'" + S + "'";
+  return S;
+}
+
+void clang::FormatASTNodeDiagnosticArgument(Diagnostic::ArgumentKind Kind, 
+                                            intptr_t Val,
+                                            const char *Modifier, 
+                                            unsigned ModLen,
+                                            const char *Argument, 
+                                            unsigned ArgLen,
+                                    const Diagnostic::ArgumentValue *PrevArgs,
+                                            unsigned NumPrevArgs,
+                                            llvm::SmallVectorImpl<char> &Output,
+                                            void *Cookie) {
+  ASTContext &Context = *static_cast<ASTContext*>(Cookie);
+  
+  std::string S;
+  bool NeedQuotes = true;
+  
+  switch (Kind) {
+    default: assert(0 && "unknown ArgumentKind");
+    case Diagnostic::ak_qualtype: {
+      assert(ModLen == 0 && ArgLen == 0 &&
+             "Invalid modifier for QualType argument");
+      
+      QualType Ty(QualType::getFromOpaquePtr(reinterpret_cast<void*>(Val)));
+      S = ConvertTypeToDiagnosticString(Context, Ty, PrevArgs, NumPrevArgs);
+      NeedQuotes = false;
+      break;
+    }
+    case Diagnostic::ak_declarationname: {
+      DeclarationName N = DeclarationName::getFromOpaqueInteger(Val);
+      S = N.getAsString();
+      
+      if (ModLen == 9 && !memcmp(Modifier, "objcclass", 9) && ArgLen == 0)
+        S = '+' + S;
+      else if (ModLen == 12 && !memcmp(Modifier, "objcinstance", 12)
+                && ArgLen==0)
+        S = '-' + S;
+      else
+        assert(ModLen == 0 && ArgLen == 0 &&
+               "Invalid modifier for DeclarationName argument");
+      break;
+    }
+    case Diagnostic::ak_nameddecl: {
+      bool Qualified;
+      if (ModLen == 1 && Modifier[0] == 'q' && ArgLen == 0)
+        Qualified = true;
+      else {
+        assert(ModLen == 0 && ArgLen == 0 &&
+               "Invalid modifier for NamedDecl* argument");
+        Qualified = false;
+      }
+      reinterpret_cast<NamedDecl*>(Val)->
+      getNameForDiagnostic(S, Context.PrintingPolicy, Qualified);
+      break;
+    }
+    case Diagnostic::ak_nestednamespec: {
+      llvm::raw_string_ostream OS(S);
+      reinterpret_cast<NestedNameSpecifier*>(Val)->print(OS,
+                                                        Context.PrintingPolicy);
+      NeedQuotes = false;
+      break;
+    }
+    case Diagnostic::ak_declcontext: {
+      DeclContext *DC = reinterpret_cast<DeclContext *> (Val);
+      assert(DC && "Should never have a null declaration context");
+      
+      if (DC->isTranslationUnit()) {
+        // FIXME: Get these strings from some localized place
+        if (Context.getLangOptions().CPlusPlus)
+          S = "the global namespace";
+        else
+          S = "the global scope";
+      } else if (TypeDecl *Type = dyn_cast<TypeDecl>(DC)) {
+        S = ConvertTypeToDiagnosticString(Context, 
+                                          Context.getTypeDeclType(Type),
+                                          PrevArgs, NumPrevArgs);
+      } else {
+        // FIXME: Get these strings from some localized place
+        NamedDecl *ND = cast<NamedDecl>(DC);
+        if (isa<NamespaceDecl>(ND))
+          S += "namespace ";
+        else if (isa<ObjCMethodDecl>(ND))
+          S += "method ";
+        else if (isa<FunctionDecl>(ND))
+          S += "function ";
+        
+        S += "'";
+        ND->getNameForDiagnostic(S, Context.PrintingPolicy, true);
+        S += "'";
+      }
+      NeedQuotes = false;
+      break;
+    }
+  }
+  
+  if (NeedQuotes)
+    Output.push_back('\'');
+  
+  Output.append(S.begin(), S.end());
+  
+  if (NeedQuotes)
+    Output.push_back('\'');
+}
diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp
new file mode 100644
index 0000000..ae09d79
--- /dev/null
+++ b/lib/AST/ASTImporter.cpp
@@ -0,0 +1,3218 @@
+//===--- ASTImporter.cpp - Importing ASTs from other Contexts ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the ASTImporter class which imports AST nodes from one
+//  context into another context.
+//
+//===----------------------------------------------------------------------===//
+#include "clang/AST/ASTImporter.h"
+
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTDiagnostic.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclVisitor.h"
+#include "clang/AST/StmtVisitor.h"
+#include "clang/AST/TypeLoc.h"
+#include "clang/AST/TypeVisitor.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/SourceManager.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include <deque>
+
+using namespace clang;
+
+namespace {
+  class ASTNodeImporter : public TypeVisitor<ASTNodeImporter, QualType>,
+                          public DeclVisitor<ASTNodeImporter, Decl *>,
+                          public StmtVisitor<ASTNodeImporter, Stmt *> {
+    ASTImporter &Importer;
+    
+  public:
+    explicit ASTNodeImporter(ASTImporter &Importer) : Importer(Importer) { }
+    
+    using TypeVisitor<ASTNodeImporter, QualType>::Visit;
+    using DeclVisitor<ASTNodeImporter, Decl *>::Visit;
+    using StmtVisitor<ASTNodeImporter, Stmt *>::Visit;
+
+    // Importing types
+    QualType VisitType(Type *T);
+    QualType VisitBuiltinType(BuiltinType *T);
+    QualType VisitComplexType(ComplexType *T);
+    QualType VisitPointerType(PointerType *T);
+    QualType VisitBlockPointerType(BlockPointerType *T);
+    QualType VisitLValueReferenceType(LValueReferenceType *T);
+    QualType VisitRValueReferenceType(RValueReferenceType *T);
+    QualType VisitMemberPointerType(MemberPointerType *T);
+    QualType VisitConstantArrayType(ConstantArrayType *T);
+    QualType VisitIncompleteArrayType(IncompleteArrayType *T);
+    QualType VisitVariableArrayType(VariableArrayType *T);
+    // FIXME: DependentSizedArrayType
+    // FIXME: DependentSizedExtVectorType
+    QualType VisitVectorType(VectorType *T);
+    QualType VisitExtVectorType(ExtVectorType *T);
+    QualType VisitFunctionNoProtoType(FunctionNoProtoType *T);
+    QualType VisitFunctionProtoType(FunctionProtoType *T);
+    // FIXME: UnresolvedUsingType
+    QualType VisitTypedefType(TypedefType *T);
+    QualType VisitTypeOfExprType(TypeOfExprType *T);
+    // FIXME: DependentTypeOfExprType
+    QualType VisitTypeOfType(TypeOfType *T);
+    QualType VisitDecltypeType(DecltypeType *T);
+    // FIXME: DependentDecltypeType
+    QualType VisitRecordType(RecordType *T);
+    QualType VisitEnumType(EnumType *T);
+    QualType VisitElaboratedType(ElaboratedType *T);
+    // FIXME: TemplateTypeParmType
+    // FIXME: SubstTemplateTypeParmType
+    // FIXME: TemplateSpecializationType
+    QualType VisitQualifiedNameType(QualifiedNameType *T);
+    // FIXME: DependentNameType
+    QualType VisitObjCInterfaceType(ObjCInterfaceType *T);
+    QualType VisitObjCObjectPointerType(ObjCObjectPointerType *T);
+                            
+    // Importing declarations
+    bool ImportDeclParts(NamedDecl *D, DeclContext *&DC, 
+                         DeclContext *&LexicalDC, DeclarationName &Name, 
+                         SourceLocation &Loc);
+    void ImportDeclContext(DeclContext *FromDC);
+    bool IsStructuralMatch(RecordDecl *FromRecord, RecordDecl *ToRecord);
+    bool IsStructuralMatch(EnumDecl *FromEnum, EnumDecl *ToRecord);
+    Decl *VisitDecl(Decl *D);
+    Decl *VisitNamespaceDecl(NamespaceDecl *D);
+    Decl *VisitTypedefDecl(TypedefDecl *D);
+    Decl *VisitEnumDecl(EnumDecl *D);
+    Decl *VisitRecordDecl(RecordDecl *D);
+    Decl *VisitEnumConstantDecl(EnumConstantDecl *D);
+    Decl *VisitFunctionDecl(FunctionDecl *D);
+    Decl *VisitCXXMethodDecl(CXXMethodDecl *D);
+    Decl *VisitCXXConstructorDecl(CXXConstructorDecl *D);
+    Decl *VisitCXXDestructorDecl(CXXDestructorDecl *D);
+    Decl *VisitCXXConversionDecl(CXXConversionDecl *D);
+    Decl *VisitFieldDecl(FieldDecl *D);
+    Decl *VisitObjCIvarDecl(ObjCIvarDecl *D);
+    Decl *VisitVarDecl(VarDecl *D);
+    Decl *VisitImplicitParamDecl(ImplicitParamDecl *D);
+    Decl *VisitParmVarDecl(ParmVarDecl *D);
+    Decl *VisitObjCMethodDecl(ObjCMethodDecl *D);
+    Decl *VisitObjCCategoryDecl(ObjCCategoryDecl *D);
+    Decl *VisitObjCProtocolDecl(ObjCProtocolDecl *D);
+    Decl *VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
+    Decl *VisitObjCPropertyDecl(ObjCPropertyDecl *D);
+    Decl *VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D);
+    Decl *VisitObjCClassDecl(ObjCClassDecl *D);
+                            
+    // Importing statements
+    Stmt *VisitStmt(Stmt *S);
+
+    // Importing expressions
+    Expr *VisitExpr(Expr *E);
+    Expr *VisitDeclRefExpr(DeclRefExpr *E);
+    Expr *VisitIntegerLiteral(IntegerLiteral *E);
+    Expr *VisitCharacterLiteral(CharacterLiteral *E);
+    Expr *VisitParenExpr(ParenExpr *E);
+    Expr *VisitUnaryOperator(UnaryOperator *E);
+    Expr *VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E);
+    Expr *VisitBinaryOperator(BinaryOperator *E);
+    Expr *VisitCompoundAssignOperator(CompoundAssignOperator *E);
+    Expr *VisitImplicitCastExpr(ImplicitCastExpr *E);
+    Expr *VisitCStyleCastExpr(CStyleCastExpr *E);
+  };
+}
+
+//----------------------------------------------------------------------------
+// Structural Equivalence
+//----------------------------------------------------------------------------
+
+namespace {
+  struct StructuralEquivalenceContext {
+    /// \brief AST contexts for which we are checking structural equivalence.
+    ASTContext &C1, &C2;
+    
+    /// \brief Diagnostic object used to emit diagnostics.
+    Diagnostic &Diags;
+    
+    /// \brief The set of "tentative" equivalences between two canonical 
+    /// declarations, mapping from a declaration in the first context to the
+    /// declaration in the second context that we believe to be equivalent.
+    llvm::DenseMap<Decl *, Decl *> TentativeEquivalences;
+    
+    /// \brief Queue of declarations in the first context whose equivalence
+    /// with a declaration in the second context still needs to be verified.
+    std::deque<Decl *> DeclsToCheck;
+    
+    /// \brief Declaration (from, to) pairs that are known not to be equivalent
+    /// (which we have already complained about).
+    llvm::DenseSet<std::pair<Decl *, Decl *> > &NonEquivalentDecls;
+    
+    /// \brief Whether we're being strict about the spelling of types when 
+    /// unifying two types.
+    bool StrictTypeSpelling;
+    
+    StructuralEquivalenceContext(ASTContext &C1, ASTContext &C2,
+                                 Diagnostic &Diags,
+               llvm::DenseSet<std::pair<Decl *, Decl *> > &NonEquivalentDecls,
+                                 bool StrictTypeSpelling = false)
+      : C1(C1), C2(C2), Diags(Diags), NonEquivalentDecls(NonEquivalentDecls),
+        StrictTypeSpelling(StrictTypeSpelling) { }
+
+    /// \brief Determine whether the two declarations are structurally
+    /// equivalent.
+    bool IsStructurallyEquivalent(Decl *D1, Decl *D2);
+    
+    /// \brief Determine whether the two types are structurally equivalent.
+    bool IsStructurallyEquivalent(QualType T1, QualType T2);
+
+  private:
+    /// \brief Finish checking all of the structural equivalences.
+    ///
+    /// \returns true if an error occurred, false otherwise.
+    bool Finish();
+    
+  public:
+    DiagnosticBuilder Diag1(SourceLocation Loc, unsigned DiagID) {
+      return Diags.Report(FullSourceLoc(Loc, C1.getSourceManager()), DiagID);
+    }
+
+    DiagnosticBuilder Diag2(SourceLocation Loc, unsigned DiagID) {
+      return Diags.Report(FullSourceLoc(Loc, C2.getSourceManager()), DiagID);
+    }
+  };
+}
+
+static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
+                                     QualType T1, QualType T2);
+static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
+                                     Decl *D1, Decl *D2);
+
+/// \brief Determine if two APInts have the same value, after zero-extending
+/// one of them (if needed!) to ensure that the bit-widths match.
+static bool IsSameValue(const llvm::APInt &I1, const llvm::APInt &I2) {
+  if (I1.getBitWidth() == I2.getBitWidth())
+    return I1 == I2;
+  
+  if (I1.getBitWidth() > I2.getBitWidth())
+    return I1 == llvm::APInt(I2).zext(I1.getBitWidth());
+  
+  return llvm::APInt(I1).zext(I2.getBitWidth()) == I2;
+}
+
+/// \brief Determine if two APSInts have the same value, zero- or sign-extending
+/// as needed.
+static bool IsSameValue(const llvm::APSInt &I1, const llvm::APSInt &I2) {
+  if (I1.getBitWidth() == I2.getBitWidth() && I1.isSigned() == I2.isSigned())
+    return I1 == I2;
+  
+  // Check for a bit-width mismatch.
+  if (I1.getBitWidth() > I2.getBitWidth())
+    return IsSameValue(I1, llvm::APSInt(I2).extend(I1.getBitWidth()));
+  else if (I2.getBitWidth() > I1.getBitWidth())
+    return IsSameValue(llvm::APSInt(I1).extend(I2.getBitWidth()), I2);
+  
+  // We have a signedness mismatch. Turn the signed value into an unsigned 
+  // value.
+  if (I1.isSigned()) {
+    if (I1.isNegative())
+      return false;
+    
+    return llvm::APSInt(I1, true) == I2;
+  }
+ 
+  if (I2.isNegative())
+    return false;
+  
+  return I1 == llvm::APSInt(I2, true);
+}
+
+/// \brief Determine structural equivalence of two expressions.
+static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
+                                     Expr *E1, Expr *E2) {
+  if (!E1 || !E2)
+    return E1 == E2;
+  
+  // FIXME: Actually perform a structural comparison!
+  return true;
+}
+
+/// \brief Determine whether two identifiers are equivalent.
+static bool IsStructurallyEquivalent(const IdentifierInfo *Name1,
+                                     const IdentifierInfo *Name2) {
+  if (!Name1 || !Name2)
+    return Name1 == Name2;
+  
+  return Name1->getName() == Name2->getName();
+}
+
+/// \brief Determine whether two nested-name-specifiers are equivalent.
+static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
+                                     NestedNameSpecifier *NNS1,
+                                     NestedNameSpecifier *NNS2) {
+  // FIXME: Implement!
+  return true;
+}
+
+/// \brief Determine whether two template arguments are equivalent.
+static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
+                                     const TemplateArgument &Arg1,
+                                     const TemplateArgument &Arg2) {
+  // FIXME: Implement!
+  return true;
+}
+
+/// \brief Determine structural equivalence for the common part of array 
+/// types.
+static bool IsArrayStructurallyEquivalent(StructuralEquivalenceContext &Context,
+                                          const ArrayType *Array1, 
+                                          const ArrayType *Array2) {
+  if (!IsStructurallyEquivalent(Context, 
+                                Array1->getElementType(), 
+                                Array2->getElementType()))
+    return false;
+  if (Array1->getSizeModifier() != Array2->getSizeModifier())
+    return false;
+  if (Array1->getIndexTypeQualifiers() != Array2->getIndexTypeQualifiers())
+    return false;
+  
+  return true;
+}
+
+/// \brief Determine structural equivalence of two types.
+static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
+                                     QualType T1, QualType T2) {
+  if (T1.isNull() || T2.isNull())
+    return T1.isNull() && T2.isNull();
+  
+  if (!Context.StrictTypeSpelling) {
+    // We aren't being strict about token-to-token equivalence of types,
+    // so map down to the canonical type.
+    T1 = Context.C1.getCanonicalType(T1);
+    T2 = Context.C2.getCanonicalType(T2);
+  }
+  
+  if (T1.getQualifiers() != T2.getQualifiers())
+    return false;
+  
+  Type::TypeClass TC = T1->getTypeClass();
+  
+  if (T1->getTypeClass() != T2->getTypeClass()) {
+    // Compare function types with prototypes vs. without prototypes as if
+    // both did not have prototypes.
+    if (T1->getTypeClass() == Type::FunctionProto &&
+        T2->getTypeClass() == Type::FunctionNoProto)
+      TC = Type::FunctionNoProto;
+    else if (T1->getTypeClass() == Type::FunctionNoProto &&
+             T2->getTypeClass() == Type::FunctionProto)
+      TC = Type::FunctionNoProto;
+    else
+      return false;
+  }
+  
+  switch (TC) {
+  case Type::Builtin:
+    // FIXME: Deal with Char_S/Char_U. 
+    if (cast<BuiltinType>(T1)->getKind() != cast<BuiltinType>(T2)->getKind())
+      return false;
+    break;
+  
+  case Type::Complex:
+    if (!IsStructurallyEquivalent(Context,
+                                  cast<ComplexType>(T1)->getElementType(),
+                                  cast<ComplexType>(T2)->getElementType()))
+      return false;
+    break;
+  
+  case Type::Pointer:
+    if (!IsStructurallyEquivalent(Context,
+                                  cast<PointerType>(T1)->getPointeeType(),
+                                  cast<PointerType>(T2)->getPointeeType()))
+      return false;
+    break;
+
+  case Type::BlockPointer:
+    if (!IsStructurallyEquivalent(Context,
+                                  cast<BlockPointerType>(T1)->getPointeeType(),
+                                  cast<BlockPointerType>(T2)->getPointeeType()))
+      return false;
+    break;
+
+  case Type::LValueReference:
+  case Type::RValueReference: {
+    const ReferenceType *Ref1 = cast<ReferenceType>(T1);
+    const ReferenceType *Ref2 = cast<ReferenceType>(T2);
+    if (Ref1->isSpelledAsLValue() != Ref2->isSpelledAsLValue())
+      return false;
+    if (Ref1->isInnerRef() != Ref2->isInnerRef())
+      return false;
+    if (!IsStructurallyEquivalent(Context,
+                                  Ref1->getPointeeTypeAsWritten(),
+                                  Ref2->getPointeeTypeAsWritten()))
+      return false;
+    break;
+  }
+      
+  case Type::MemberPointer: {
+    const MemberPointerType *MemPtr1 = cast<MemberPointerType>(T1);
+    const MemberPointerType *MemPtr2 = cast<MemberPointerType>(T2);
+    if (!IsStructurallyEquivalent(Context,
+                                  MemPtr1->getPointeeType(),
+                                  MemPtr2->getPointeeType()))
+      return false;
+    if (!IsStructurallyEquivalent(Context,
+                                  QualType(MemPtr1->getClass(), 0),
+                                  QualType(MemPtr2->getClass(), 0)))
+      return false;
+    break;
+  }
+      
+  case Type::ConstantArray: {
+    const ConstantArrayType *Array1 = cast<ConstantArrayType>(T1);
+    const ConstantArrayType *Array2 = cast<ConstantArrayType>(T2);
+    if (!IsSameValue(Array1->getSize(), Array2->getSize()))
+      return false;
+    
+    if (!IsArrayStructurallyEquivalent(Context, Array1, Array2))
+      return false;
+    break;
+  }
+
+  case Type::IncompleteArray:
+    if (!IsArrayStructurallyEquivalent(Context, 
+                                       cast<ArrayType>(T1), 
+                                       cast<ArrayType>(T2)))
+      return false;
+    break;
+      
+  case Type::VariableArray: {
+    const VariableArrayType *Array1 = cast<VariableArrayType>(T1);
+    const VariableArrayType *Array2 = cast<VariableArrayType>(T2);
+    if (!IsStructurallyEquivalent(Context, 
+                                  Array1->getSizeExpr(), Array2->getSizeExpr()))
+      return false;
+    
+    if (!IsArrayStructurallyEquivalent(Context, Array1, Array2))
+      return false;
+    
+    break;
+  }
+  
+  case Type::DependentSizedArray: {
+    const DependentSizedArrayType *Array1 = cast<DependentSizedArrayType>(T1);
+    const DependentSizedArrayType *Array2 = cast<DependentSizedArrayType>(T2);
+    if (!IsStructurallyEquivalent(Context, 
+                                  Array1->getSizeExpr(), Array2->getSizeExpr()))
+      return false;
+    
+    if (!IsArrayStructurallyEquivalent(Context, Array1, Array2))
+      return false;
+    
+    break;
+  }
+      
+  case Type::DependentSizedExtVector: {
+    const DependentSizedExtVectorType *Vec1
+      = cast<DependentSizedExtVectorType>(T1);
+    const DependentSizedExtVectorType *Vec2
+      = cast<DependentSizedExtVectorType>(T2);
+    if (!IsStructurallyEquivalent(Context, 
+                                  Vec1->getSizeExpr(), Vec2->getSizeExpr()))
+      return false;
+    if (!IsStructurallyEquivalent(Context, 
+                                  Vec1->getElementType(), 
+                                  Vec2->getElementType()))
+      return false;
+    break;
+  }
+   
+  case Type::Vector: 
+  case Type::ExtVector: {
+    const VectorType *Vec1 = cast<VectorType>(T1);
+    const VectorType *Vec2 = cast<VectorType>(T2);
+    if (!IsStructurallyEquivalent(Context, 
+                                  Vec1->getElementType(),
+                                  Vec2->getElementType()))
+      return false;
+    if (Vec1->getNumElements() != Vec2->getNumElements())
+      return false;
+    if (Vec1->isAltiVec() != Vec2->isAltiVec())
+      return false;
+    if (Vec1->isPixel() != Vec2->isPixel())
+      return false;
+    break;
+  }
+
+  case Type::FunctionProto: {
+    const FunctionProtoType *Proto1 = cast<FunctionProtoType>(T1);
+    const FunctionProtoType *Proto2 = cast<FunctionProtoType>(T2);
+    if (Proto1->getNumArgs() != Proto2->getNumArgs())
+      return false;
+    for (unsigned I = 0, N = Proto1->getNumArgs(); I != N; ++I) {
+      if (!IsStructurallyEquivalent(Context, 
+                                    Proto1->getArgType(I),
+                                    Proto2->getArgType(I)))
+        return false;
+    }
+    if (Proto1->isVariadic() != Proto2->isVariadic())
+      return false;
+    if (Proto1->hasExceptionSpec() != Proto2->hasExceptionSpec())
+      return false;
+    if (Proto1->hasAnyExceptionSpec() != Proto2->hasAnyExceptionSpec())
+      return false;
+    if (Proto1->getNumExceptions() != Proto2->getNumExceptions())
+      return false;
+    for (unsigned I = 0, N = Proto1->getNumExceptions(); I != N; ++I) {
+      if (!IsStructurallyEquivalent(Context,
+                                    Proto1->getExceptionType(I),
+                                    Proto2->getExceptionType(I)))
+        return false;
+    }
+    if (Proto1->getTypeQuals() != Proto2->getTypeQuals())
+      return false;
+    
+    // Fall through to check the bits common with FunctionNoProtoType.
+  }
+      
+  case Type::FunctionNoProto: {
+    const FunctionType *Function1 = cast<FunctionType>(T1);
+    const FunctionType *Function2 = cast<FunctionType>(T2);
+    if (!IsStructurallyEquivalent(Context, 
+                                  Function1->getResultType(),
+                                  Function2->getResultType()))
+      return false;
+      if (Function1->getExtInfo() != Function2->getExtInfo())
+        return false;
+    break;
+  }
+   
+  case Type::UnresolvedUsing:
+    if (!IsStructurallyEquivalent(Context,
+                                  cast<UnresolvedUsingType>(T1)->getDecl(),
+                                  cast<UnresolvedUsingType>(T2)->getDecl()))
+      return false;
+      
+    break;
+      
+  case Type::Typedef:
+    if (!IsStructurallyEquivalent(Context,
+                                  cast<TypedefType>(T1)->getDecl(),
+                                  cast<TypedefType>(T2)->getDecl()))
+      return false;
+    break;
+      
+  case Type::TypeOfExpr:
+    if (!IsStructurallyEquivalent(Context,
+                                cast<TypeOfExprType>(T1)->getUnderlyingExpr(),
+                                cast<TypeOfExprType>(T2)->getUnderlyingExpr()))
+      return false;
+    break;
+      
+  case Type::TypeOf:
+    if (!IsStructurallyEquivalent(Context,
+                                  cast<TypeOfType>(T1)->getUnderlyingType(),
+                                  cast<TypeOfType>(T2)->getUnderlyingType()))
+      return false;
+    break;
+      
+  case Type::Decltype:
+    if (!IsStructurallyEquivalent(Context,
+                                  cast<DecltypeType>(T1)->getUnderlyingExpr(),
+                                  cast<DecltypeType>(T2)->getUnderlyingExpr()))
+      return false;
+    break;
+
+  case Type::Record:
+  case Type::Enum:
+    if (!IsStructurallyEquivalent(Context,
+                                  cast<TagType>(T1)->getDecl(),
+                                  cast<TagType>(T2)->getDecl()))
+      return false;
+    break;
+      
+  case Type::Elaborated: {
+    const ElaboratedType *Elab1 = cast<ElaboratedType>(T1);
+    const ElaboratedType *Elab2 = cast<ElaboratedType>(T2);
+    if (Elab1->getTagKind() != Elab2->getTagKind())
+      return false;
+    if (!IsStructurallyEquivalent(Context, 
+                                  Elab1->getUnderlyingType(),
+                                  Elab2->getUnderlyingType()))
+      return false;
+    break;
+  }
+   
+  case Type::TemplateTypeParm: {
+    const TemplateTypeParmType *Parm1 = cast<TemplateTypeParmType>(T1);
+    const TemplateTypeParmType *Parm2 = cast<TemplateTypeParmType>(T2);
+    if (Parm1->getDepth() != Parm2->getDepth())
+      return false;
+    if (Parm1->getIndex() != Parm2->getIndex())
+      return false;
+    if (Parm1->isParameterPack() != Parm2->isParameterPack())
+      return false;
+    
+    // Names of template type parameters are never significant.
+    break;
+  }
+      
+  case Type::SubstTemplateTypeParm: {
+    const SubstTemplateTypeParmType *Subst1
+      = cast<SubstTemplateTypeParmType>(T1);
+    const SubstTemplateTypeParmType *Subst2
+      = cast<SubstTemplateTypeParmType>(T2);
+    if (!IsStructurallyEquivalent(Context,
+                                  QualType(Subst1->getReplacedParameter(), 0),
+                                  QualType(Subst2->getReplacedParameter(), 0)))
+      return false;
+    if (!IsStructurallyEquivalent(Context, 
+                                  Subst1->getReplacementType(),
+                                  Subst2->getReplacementType()))
+      return false;
+    break;
+  }
+
+  case Type::TemplateSpecialization: {
+    const TemplateSpecializationType *Spec1
+      = cast<TemplateSpecializationType>(T1);
+    const TemplateSpecializationType *Spec2
+      = cast<TemplateSpecializationType>(T2);
+    if (!IsStructurallyEquivalent(Context,
+                                  Spec1->getTemplateName(),
+                                  Spec2->getTemplateName()))
+      return false;
+    if (Spec1->getNumArgs() != Spec2->getNumArgs())
+      return false;
+    for (unsigned I = 0, N = Spec1->getNumArgs(); I != N; ++I) {
+      if (!IsStructurallyEquivalent(Context, 
+                                    Spec1->getArg(I), Spec2->getArg(I)))
+        return false;
+    }
+    break;
+  }
+      
+  case Type::QualifiedName: {
+    const QualifiedNameType *Qual1 = cast<QualifiedNameType>(T1);
+    const QualifiedNameType *Qual2 = cast<QualifiedNameType>(T2);
+    if (!IsStructurallyEquivalent(Context, 
+                                  Qual1->getQualifier(), 
+                                  Qual2->getQualifier()))
+      return false;
+    if (!IsStructurallyEquivalent(Context,
+                                  Qual1->getNamedType(),
+                                  Qual2->getNamedType()))
+      return false;
+    break;
+  }
+
+  case Type::InjectedClassName: {
+    const InjectedClassNameType *Inj1 = cast<InjectedClassNameType>(T1);
+    const InjectedClassNameType *Inj2 = cast<InjectedClassNameType>(T2);
+    if (!IsStructurallyEquivalent(Context,
+                                  Inj1->getInjectedSpecializationType(),
+                                  Inj2->getInjectedSpecializationType()))
+      return false;
+    break;
+  }
+
+  case Type::DependentName: {
+    const DependentNameType *Typename1 = cast<DependentNameType>(T1);
+    const DependentNameType *Typename2 = cast<DependentNameType>(T2);
+    if (!IsStructurallyEquivalent(Context, 
+                                  Typename1->getQualifier(),
+                                  Typename2->getQualifier()))
+      return false;
+    if (!IsStructurallyEquivalent(Typename1->getIdentifier(),
+                                  Typename2->getIdentifier()))
+      return false;
+    if (!IsStructurallyEquivalent(Context,
+                                  QualType(Typename1->getTemplateId(), 0),
+                                  QualType(Typename2->getTemplateId(), 0)))
+      return false;
+    
+    break;
+  }
+  
+  case Type::ObjCInterface: {
+    const ObjCInterfaceType *Iface1 = cast<ObjCInterfaceType>(T1);
+    const ObjCInterfaceType *Iface2 = cast<ObjCInterfaceType>(T2);
+    if (!IsStructurallyEquivalent(Context, 
+                                  Iface1->getDecl(), Iface2->getDecl()))
+      return false;
+    if (Iface1->getNumProtocols() != Iface2->getNumProtocols())
+      return false;
+    for (unsigned I = 0, N = Iface1->getNumProtocols(); I != N; ++I) {
+      if (!IsStructurallyEquivalent(Context,
+                                    Iface1->getProtocol(I),
+                                    Iface2->getProtocol(I)))
+        return false;
+    }
+    break;
+  }
+
+  case Type::ObjCObjectPointer: {
+    const ObjCObjectPointerType *Ptr1 = cast<ObjCObjectPointerType>(T1);
+    const ObjCObjectPointerType *Ptr2 = cast<ObjCObjectPointerType>(T2);
+    if (!IsStructurallyEquivalent(Context, 
+                                  Ptr1->getPointeeType(),
+                                  Ptr2->getPointeeType()))
+      return false;
+    if (Ptr1->getNumProtocols() != Ptr2->getNumProtocols())
+      return false;
+    for (unsigned I = 0, N = Ptr1->getNumProtocols(); I != N; ++I) {
+      if (!IsStructurallyEquivalent(Context,
+                                    Ptr1->getProtocol(I),
+                                    Ptr2->getProtocol(I)))
+        return false;
+    }
+    break;
+  }
+      
+  } // end switch
+
+  return true;
+}
+
+/// \brief Determine structural equivalence of two records.
+static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
+                                     RecordDecl *D1, RecordDecl *D2) {
+  if (D1->isUnion() != D2->isUnion()) {
+    Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
+      << Context.C2.getTypeDeclType(D2);
+    Context.Diag1(D1->getLocation(), diag::note_odr_tag_kind_here)
+      << D1->getDeclName() << (unsigned)D1->getTagKind();
+    return false;
+  }
+  
+  // Compare the definitions of these two records. If either or both are
+  // incomplete, we assume that they are equivalent.
+  D1 = D1->getDefinition();
+  D2 = D2->getDefinition();
+  if (!D1 || !D2)
+    return true;
+  
+  if (CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(D1)) {
+    if (CXXRecordDecl *D2CXX = dyn_cast<CXXRecordDecl>(D2)) {
+      if (D1CXX->getNumBases() != D2CXX->getNumBases()) {
+        Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
+        << Context.C2.getTypeDeclType(D2);
+        Context.Diag2(D2->getLocation(), diag::note_odr_number_of_bases)
+        << D2CXX->getNumBases();
+        Context.Diag1(D1->getLocation(), diag::note_odr_number_of_bases)
+        << D1CXX->getNumBases();
+        return false;
+      }
+      
+      // Check the base classes. 
+      for (CXXRecordDecl::base_class_iterator Base1 = D1CXX->bases_begin(), 
+                                           BaseEnd1 = D1CXX->bases_end(),
+                                                Base2 = D2CXX->bases_begin();
+           Base1 != BaseEnd1;
+           ++Base1, ++Base2) {        
+        if (!IsStructurallyEquivalent(Context, 
+                                      Base1->getType(), Base2->getType())) {
+          Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
+            << Context.C2.getTypeDeclType(D2);
+          Context.Diag2(Base2->getSourceRange().getBegin(), diag::note_odr_base)
+            << Base2->getType()
+            << Base2->getSourceRange();
+          Context.Diag1(Base1->getSourceRange().getBegin(), diag::note_odr_base)
+            << Base1->getType()
+            << Base1->getSourceRange();
+          return false;
+        }
+        
+        // Check virtual vs. non-virtual inheritance mismatch.
+        if (Base1->isVirtual() != Base2->isVirtual()) {
+          Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
+            << Context.C2.getTypeDeclType(D2);
+          Context.Diag2(Base2->getSourceRange().getBegin(),
+                        diag::note_odr_virtual_base)
+            << Base2->isVirtual() << Base2->getSourceRange();
+          Context.Diag1(Base1->getSourceRange().getBegin(), diag::note_odr_base)
+            << Base1->isVirtual()
+            << Base1->getSourceRange();
+          return false;
+        }
+      }
+    } else if (D1CXX->getNumBases() > 0) {
+      Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
+        << Context.C2.getTypeDeclType(D2);
+      const CXXBaseSpecifier *Base1 = D1CXX->bases_begin();
+      Context.Diag1(Base1->getSourceRange().getBegin(), diag::note_odr_base)
+        << Base1->getType()
+        << Base1->getSourceRange();
+      Context.Diag2(D2->getLocation(), diag::note_odr_missing_base);
+      return false;
+    }
+  }
+  
+  // Check the fields for consistency.
+  CXXRecordDecl::field_iterator Field2 = D2->field_begin(),
+                             Field2End = D2->field_end();
+  for (CXXRecordDecl::field_iterator Field1 = D1->field_begin(),
+                                  Field1End = D1->field_end();
+       Field1 != Field1End;
+       ++Field1, ++Field2) {
+    if (Field2 == Field2End) {
+      Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
+        << Context.C2.getTypeDeclType(D2);
+      Context.Diag1(Field1->getLocation(), diag::note_odr_field)
+        << Field1->getDeclName() << Field1->getType();
+      Context.Diag2(D2->getLocation(), diag::note_odr_missing_field);
+      return false;
+    }
+    
+    if (!IsStructurallyEquivalent(Context, 
+                                  Field1->getType(), Field2->getType())) {
+      Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
+        << Context.C2.getTypeDeclType(D2);
+      Context.Diag2(Field2->getLocation(), diag::note_odr_field)
+        << Field2->getDeclName() << Field2->getType();
+      Context.Diag1(Field1->getLocation(), diag::note_odr_field)
+        << Field1->getDeclName() << Field1->getType();
+      return false;
+    }
+    
+    if (Field1->isBitField() != Field2->isBitField()) {
+      Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
+        << Context.C2.getTypeDeclType(D2);
+      if (Field1->isBitField()) {
+        llvm::APSInt Bits;
+        Field1->getBitWidth()->isIntegerConstantExpr(Bits, Context.C1);
+        Context.Diag1(Field1->getLocation(), diag::note_odr_bit_field)
+          << Field1->getDeclName() << Field1->getType()
+          << Bits.toString(10, false);
+        Context.Diag2(Field2->getLocation(), diag::note_odr_not_bit_field)
+          << Field2->getDeclName();
+      } else {
+        llvm::APSInt Bits;
+        Field2->getBitWidth()->isIntegerConstantExpr(Bits, Context.C2);
+        Context.Diag2(Field2->getLocation(), diag::note_odr_bit_field)
+          << Field2->getDeclName() << Field2->getType()
+          << Bits.toString(10, false);
+        Context.Diag1(Field1->getLocation(), 
+                          diag::note_odr_not_bit_field)
+        << Field1->getDeclName();
+      }
+      return false;
+    }
+    
+    if (Field1->isBitField()) {
+      // Make sure that the bit-fields are the same length.
+      llvm::APSInt Bits1, Bits2;
+      if (!Field1->getBitWidth()->isIntegerConstantExpr(Bits1, Context.C1))
+        return false;
+      if (!Field2->getBitWidth()->isIntegerConstantExpr(Bits2, Context.C2))
+        return false;
+      
+      if (!IsSameValue(Bits1, Bits2)) {
+        Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
+          << Context.C2.getTypeDeclType(D2);
+        Context.Diag2(Field2->getLocation(), diag::note_odr_bit_field)
+          << Field2->getDeclName() << Field2->getType()
+          << Bits2.toString(10, false);
+        Context.Diag1(Field1->getLocation(), diag::note_odr_bit_field)
+          << Field1->getDeclName() << Field1->getType()
+          << Bits1.toString(10, false);
+        return false;
+      }
+    }
+  }
+  
+  if (Field2 != Field2End) {
+    Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
+      << Context.C2.getTypeDeclType(D2);
+    Context.Diag2(Field2->getLocation(), diag::note_odr_field)
+      << Field2->getDeclName() << Field2->getType();
+    Context.Diag1(D1->getLocation(), diag::note_odr_missing_field);
+    return false;
+  }
+  
+  return true;
+}
+     
+/// \brief Determine structural equivalence of two enums.
+static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
+                                     EnumDecl *D1, EnumDecl *D2) {
+  EnumDecl::enumerator_iterator EC2 = D2->enumerator_begin(),
+                             EC2End = D2->enumerator_end();
+  for (EnumDecl::enumerator_iterator EC1 = D1->enumerator_begin(),
+                                  EC1End = D1->enumerator_end();
+       EC1 != EC1End; ++EC1, ++EC2) {
+    if (EC2 == EC2End) {
+      Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
+        << Context.C2.getTypeDeclType(D2);
+      Context.Diag1(EC1->getLocation(), diag::note_odr_enumerator)
+        << EC1->getDeclName() 
+        << EC1->getInitVal().toString(10);
+      Context.Diag2(D2->getLocation(), diag::note_odr_missing_enumerator);
+      return false;
+    }
+    
+    llvm::APSInt Val1 = EC1->getInitVal();
+    llvm::APSInt Val2 = EC2->getInitVal();
+    if (!IsSameValue(Val1, Val2) || 
+        !IsStructurallyEquivalent(EC1->getIdentifier(), EC2->getIdentifier())) {
+      Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
+        << Context.C2.getTypeDeclType(D2);
+      Context.Diag2(EC2->getLocation(), diag::note_odr_enumerator)
+        << EC2->getDeclName() 
+        << EC2->getInitVal().toString(10);
+      Context.Diag1(EC1->getLocation(), diag::note_odr_enumerator)
+        << EC1->getDeclName() 
+        << EC1->getInitVal().toString(10);
+      return false;
+    }
+  }
+  
+  if (EC2 != EC2End) {
+    Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
+      << Context.C2.getTypeDeclType(D2);
+    Context.Diag2(EC2->getLocation(), diag::note_odr_enumerator)
+      << EC2->getDeclName() 
+      << EC2->getInitVal().toString(10);
+    Context.Diag1(D1->getLocation(), diag::note_odr_missing_enumerator);
+    return false;
+  }
+  
+  return true;
+}
+  
+/// \brief Determine structural equivalence of two declarations.
+static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
+                                     Decl *D1, Decl *D2) {
+  // FIXME: Check for known structural equivalences via a callback of some sort.
+  
+  // Check whether we already know that these two declarations are not
+  // structurally equivalent.
+  if (Context.NonEquivalentDecls.count(std::make_pair(D1->getCanonicalDecl(),
+                                                      D2->getCanonicalDecl())))
+    return false;
+  
+  // Determine whether we've already produced a tentative equivalence for D1.
+  Decl *&EquivToD1 = Context.TentativeEquivalences[D1->getCanonicalDecl()];
+  if (EquivToD1)
+    return EquivToD1 == D2->getCanonicalDecl();
+  
+  // Produce a tentative equivalence D1 <-> D2, which will be checked later.
+  EquivToD1 = D2->getCanonicalDecl();
+  Context.DeclsToCheck.push_back(D1->getCanonicalDecl());
+  return true;
+}
+
+bool StructuralEquivalenceContext::IsStructurallyEquivalent(Decl *D1, 
+                                                            Decl *D2) {
+  if (!::IsStructurallyEquivalent(*this, D1, D2))
+    return false;
+  
+  return !Finish();
+}
+
+bool StructuralEquivalenceContext::IsStructurallyEquivalent(QualType T1, 
+                                                            QualType T2) {
+  if (!::IsStructurallyEquivalent(*this, T1, T2))
+    return false;
+  
+  return !Finish();
+}
+
+bool StructuralEquivalenceContext::Finish() {
+  while (!DeclsToCheck.empty()) {
+    // Check the next declaration.
+    Decl *D1 = DeclsToCheck.front();
+    DeclsToCheck.pop_front();
+    
+    Decl *D2 = TentativeEquivalences[D1];
+    assert(D2 && "Unrecorded tentative equivalence?");
+    
+    bool Equivalent = true;
+    
+    // FIXME: Switch on all declaration kinds. For now, we're just going to
+    // check the obvious ones.
+    if (RecordDecl *Record1 = dyn_cast<RecordDecl>(D1)) {
+      if (RecordDecl *Record2 = dyn_cast<RecordDecl>(D2)) {
+        // Check for equivalent structure names.
+        IdentifierInfo *Name1 = Record1->getIdentifier();
+        if (!Name1 && Record1->getTypedefForAnonDecl())
+          Name1 = Record1->getTypedefForAnonDecl()->getIdentifier();
+        IdentifierInfo *Name2 = Record2->getIdentifier();
+        if (!Name2 && Record2->getTypedefForAnonDecl())
+          Name2 = Record2->getTypedefForAnonDecl()->getIdentifier();
+        if (!::IsStructurallyEquivalent(Name1, Name2) ||
+            !::IsStructurallyEquivalent(*this, Record1, Record2))
+          Equivalent = false;
+      } else {
+        // Record/non-record mismatch.
+        Equivalent = false;
+      }
+    } else if (EnumDecl *Enum1 = dyn_cast<EnumDecl>(D1)) {
+      if (EnumDecl *Enum2 = dyn_cast<EnumDecl>(D2)) {
+        // Check for equivalent enum names.
+        IdentifierInfo *Name1 = Enum1->getIdentifier();
+        if (!Name1 && Enum1->getTypedefForAnonDecl())
+          Name1 = Enum1->getTypedefForAnonDecl()->getIdentifier();
+        IdentifierInfo *Name2 = Enum2->getIdentifier();
+        if (!Name2 && Enum2->getTypedefForAnonDecl())
+          Name2 = Enum2->getTypedefForAnonDecl()->getIdentifier();
+        if (!::IsStructurallyEquivalent(Name1, Name2) ||
+            !::IsStructurallyEquivalent(*this, Enum1, Enum2))
+          Equivalent = false;
+      } else {
+        // Enum/non-enum mismatch
+        Equivalent = false;
+      }
+    } else if (TypedefDecl *Typedef1 = dyn_cast<TypedefDecl>(D1)) {
+      if (TypedefDecl *Typedef2 = dyn_cast<TypedefDecl>(D2)) {
+        if (!::IsStructurallyEquivalent(Typedef1->getIdentifier(),
+                                        Typedef2->getIdentifier()) ||
+            !::IsStructurallyEquivalent(*this,
+                                        Typedef1->getUnderlyingType(),
+                                        Typedef2->getUnderlyingType()))
+          Equivalent = false;
+      } else {
+        // Typedef/non-typedef mismatch.
+        Equivalent = false;
+      }
+    } 
+
+    if (!Equivalent) {
+      // Note that these two declarations are not equivalent (and we already
+      // know about it).
+      NonEquivalentDecls.insert(std::make_pair(D1->getCanonicalDecl(),
+                                               D2->getCanonicalDecl()));
+      return true;
+    }
+    // FIXME: Check other declaration kinds!
+  }
+  
+  return false;
+}
+
+//----------------------------------------------------------------------------
+// Import Types
+//----------------------------------------------------------------------------
+
+QualType ASTNodeImporter::VisitType(Type *T) {
+  Importer.FromDiag(SourceLocation(), diag::err_unsupported_ast_node)
+    << T->getTypeClassName();
+  return QualType();
+}
+
+QualType ASTNodeImporter::VisitBuiltinType(BuiltinType *T) {
+  switch (T->getKind()) {
+  case BuiltinType::Void: return Importer.getToContext().VoidTy;
+  case BuiltinType::Bool: return Importer.getToContext().BoolTy;
+    
+  case BuiltinType::Char_U:
+    // The context we're importing from has an unsigned 'char'. If we're 
+    // importing into a context with a signed 'char', translate to 
+    // 'unsigned char' instead.
+    if (Importer.getToContext().getLangOptions().CharIsSigned)
+      return Importer.getToContext().UnsignedCharTy;
+    
+    return Importer.getToContext().CharTy;
+
+  case BuiltinType::UChar: return Importer.getToContext().UnsignedCharTy;
+    
+  case BuiltinType::Char16:
+    // FIXME: Make sure that the "to" context supports C++!
+    return Importer.getToContext().Char16Ty;
+    
+  case BuiltinType::Char32: 
+    // FIXME: Make sure that the "to" context supports C++!
+    return Importer.getToContext().Char32Ty;
+
+  case BuiltinType::UShort: return Importer.getToContext().UnsignedShortTy;
+  case BuiltinType::UInt: return Importer.getToContext().UnsignedIntTy;
+  case BuiltinType::ULong: return Importer.getToContext().UnsignedLongTy;
+  case BuiltinType::ULongLong: 
+    return Importer.getToContext().UnsignedLongLongTy;
+  case BuiltinType::UInt128: return Importer.getToContext().UnsignedInt128Ty;
+    
+  case BuiltinType::Char_S:
+    // The context we're importing from has an unsigned 'char'. If we're 
+    // importing into a context with a signed 'char', translate to 
+    // 'unsigned char' instead.
+    if (!Importer.getToContext().getLangOptions().CharIsSigned)
+      return Importer.getToContext().SignedCharTy;
+    
+    return Importer.getToContext().CharTy;
+
+  case BuiltinType::SChar: return Importer.getToContext().SignedCharTy;
+  case BuiltinType::WChar:
+    // FIXME: If not in C++, shall we translate to the C equivalent of
+    // wchar_t?
+    return Importer.getToContext().WCharTy;
+    
+  case BuiltinType::Short : return Importer.getToContext().ShortTy;
+  case BuiltinType::Int : return Importer.getToContext().IntTy;
+  case BuiltinType::Long : return Importer.getToContext().LongTy;
+  case BuiltinType::LongLong : return Importer.getToContext().LongLongTy;
+  case BuiltinType::Int128 : return Importer.getToContext().Int128Ty;
+  case BuiltinType::Float: return Importer.getToContext().FloatTy;
+  case BuiltinType::Double: return Importer.getToContext().DoubleTy;
+  case BuiltinType::LongDouble: return Importer.getToContext().LongDoubleTy;
+
+  case BuiltinType::NullPtr:
+    // FIXME: Make sure that the "to" context supports C++0x!
+    return Importer.getToContext().NullPtrTy;
+    
+  case BuiltinType::Overload: return Importer.getToContext().OverloadTy;
+  case BuiltinType::Dependent: return Importer.getToContext().DependentTy;
+  case BuiltinType::UndeducedAuto: 
+    // FIXME: Make sure that the "to" context supports C++0x!
+    return Importer.getToContext().UndeducedAutoTy;
+
+  case BuiltinType::ObjCId:
+    // FIXME: Make sure that the "to" context supports Objective-C!
+    return Importer.getToContext().ObjCBuiltinIdTy;
+    
+  case BuiltinType::ObjCClass:
+    return Importer.getToContext().ObjCBuiltinClassTy;
+
+  case BuiltinType::ObjCSel:
+    return Importer.getToContext().ObjCBuiltinSelTy;
+  }
+  
+  return QualType();
+}
+
+QualType ASTNodeImporter::VisitComplexType(ComplexType *T) {
+  QualType ToElementType = Importer.Import(T->getElementType());
+  if (ToElementType.isNull())
+    return QualType();
+  
+  return Importer.getToContext().getComplexType(ToElementType);
+}
+
+QualType ASTNodeImporter::VisitPointerType(PointerType *T) {
+  QualType ToPointeeType = Importer.Import(T->getPointeeType());
+  if (ToPointeeType.isNull())
+    return QualType();
+  
+  return Importer.getToContext().getPointerType(ToPointeeType);
+}
+
+QualType ASTNodeImporter::VisitBlockPointerType(BlockPointerType *T) {
+  // FIXME: Check for blocks support in "to" context.
+  QualType ToPointeeType = Importer.Import(T->getPointeeType());
+  if (ToPointeeType.isNull())
+    return QualType();
+  
+  return Importer.getToContext().getBlockPointerType(ToPointeeType);
+}
+
+QualType ASTNodeImporter::VisitLValueReferenceType(LValueReferenceType *T) {
+  // FIXME: Check for C++ support in "to" context.
+  QualType ToPointeeType = Importer.Import(T->getPointeeTypeAsWritten());
+  if (ToPointeeType.isNull())
+    return QualType();
+  
+  return Importer.getToContext().getLValueReferenceType(ToPointeeType);
+}
+
+QualType ASTNodeImporter::VisitRValueReferenceType(RValueReferenceType *T) {
+  // FIXME: Check for C++0x support in "to" context.
+  QualType ToPointeeType = Importer.Import(T->getPointeeTypeAsWritten());
+  if (ToPointeeType.isNull())
+    return QualType();
+  
+  return Importer.getToContext().getRValueReferenceType(ToPointeeType);  
+}
+
+QualType ASTNodeImporter::VisitMemberPointerType(MemberPointerType *T) {
+  // FIXME: Check for C++ support in "to" context.
+  QualType ToPointeeType = Importer.Import(T->getPointeeType());
+  if (ToPointeeType.isNull())
+    return QualType();
+  
+  QualType ClassType = Importer.Import(QualType(T->getClass(), 0));
+  return Importer.getToContext().getMemberPointerType(ToPointeeType, 
+                                                      ClassType.getTypePtr());
+}
+
+QualType ASTNodeImporter::VisitConstantArrayType(ConstantArrayType *T) {
+  QualType ToElementType = Importer.Import(T->getElementType());
+  if (ToElementType.isNull())
+    return QualType();
+  
+  return Importer.getToContext().getConstantArrayType(ToElementType, 
+                                                      T->getSize(),
+                                                      T->getSizeModifier(),
+                                               T->getIndexTypeCVRQualifiers());
+}
+
+QualType ASTNodeImporter::VisitIncompleteArrayType(IncompleteArrayType *T) {
+  QualType ToElementType = Importer.Import(T->getElementType());
+  if (ToElementType.isNull())
+    return QualType();
+  
+  return Importer.getToContext().getIncompleteArrayType(ToElementType, 
+                                                        T->getSizeModifier(),
+                                                T->getIndexTypeCVRQualifiers());
+}
+
+QualType ASTNodeImporter::VisitVariableArrayType(VariableArrayType *T) {
+  QualType ToElementType = Importer.Import(T->getElementType());
+  if (ToElementType.isNull())
+    return QualType();
+
+  Expr *Size = Importer.Import(T->getSizeExpr());
+  if (!Size)
+    return QualType();
+  
+  SourceRange Brackets = Importer.Import(T->getBracketsRange());
+  return Importer.getToContext().getVariableArrayType(ToElementType, Size,
+                                                      T->getSizeModifier(),
+                                                T->getIndexTypeCVRQualifiers(),
+                                                      Brackets);
+}
+
+QualType ASTNodeImporter::VisitVectorType(VectorType *T) {
+  QualType ToElementType = Importer.Import(T->getElementType());
+  if (ToElementType.isNull())
+    return QualType();
+  
+  return Importer.getToContext().getVectorType(ToElementType, 
+                                               T->getNumElements(),
+                                               T->isAltiVec(),
+                                               T->isPixel());
+}
+
+QualType ASTNodeImporter::VisitExtVectorType(ExtVectorType *T) {
+  QualType ToElementType = Importer.Import(T->getElementType());
+  if (ToElementType.isNull())
+    return QualType();
+  
+  return Importer.getToContext().getExtVectorType(ToElementType, 
+                                                  T->getNumElements());
+}
+
+QualType ASTNodeImporter::VisitFunctionNoProtoType(FunctionNoProtoType *T) {
+  // FIXME: What happens if we're importing a function without a prototype 
+  // into C++? Should we make it variadic?
+  QualType ToResultType = Importer.Import(T->getResultType());
+  if (ToResultType.isNull())
+    return QualType();
+
+  return Importer.getToContext().getFunctionNoProtoType(ToResultType,
+                                                        T->getExtInfo());
+}
+
+QualType ASTNodeImporter::VisitFunctionProtoType(FunctionProtoType *T) {
+  QualType ToResultType = Importer.Import(T->getResultType());
+  if (ToResultType.isNull())
+    return QualType();
+  
+  // Import argument types
+  llvm::SmallVector<QualType, 4> ArgTypes;
+  for (FunctionProtoType::arg_type_iterator A = T->arg_type_begin(),
+                                         AEnd = T->arg_type_end();
+       A != AEnd; ++A) {
+    QualType ArgType = Importer.Import(*A);
+    if (ArgType.isNull())
+      return QualType();
+    ArgTypes.push_back(ArgType);
+  }
+  
+  // Import exception types
+  llvm::SmallVector<QualType, 4> ExceptionTypes;
+  for (FunctionProtoType::exception_iterator E = T->exception_begin(),
+                                          EEnd = T->exception_end();
+       E != EEnd; ++E) {
+    QualType ExceptionType = Importer.Import(*E);
+    if (ExceptionType.isNull())
+      return QualType();
+    ExceptionTypes.push_back(ExceptionType);
+  }
+       
+  return Importer.getToContext().getFunctionType(ToResultType, ArgTypes.data(),
+                                                 ArgTypes.size(),
+                                                 T->isVariadic(),
+                                                 T->getTypeQuals(),
+                                                 T->hasExceptionSpec(), 
+                                                 T->hasAnyExceptionSpec(),
+                                                 ExceptionTypes.size(),
+                                                 ExceptionTypes.data(),
+                                                 T->getExtInfo());
+}
+
+QualType ASTNodeImporter::VisitTypedefType(TypedefType *T) {
+  TypedefDecl *ToDecl
+                 = dyn_cast_or_null<TypedefDecl>(Importer.Import(T->getDecl()));
+  if (!ToDecl)
+    return QualType();
+  
+  return Importer.getToContext().getTypeDeclType(ToDecl);
+}
+
+QualType ASTNodeImporter::VisitTypeOfExprType(TypeOfExprType *T) {
+  Expr *ToExpr = Importer.Import(T->getUnderlyingExpr());
+  if (!ToExpr)
+    return QualType();
+  
+  return Importer.getToContext().getTypeOfExprType(ToExpr);
+}
+
+QualType ASTNodeImporter::VisitTypeOfType(TypeOfType *T) {
+  QualType ToUnderlyingType = Importer.Import(T->getUnderlyingType());
+  if (ToUnderlyingType.isNull())
+    return QualType();
+  
+  return Importer.getToContext().getTypeOfType(ToUnderlyingType);
+}
+
+QualType ASTNodeImporter::VisitDecltypeType(DecltypeType *T) {
+  Expr *ToExpr = Importer.Import(T->getUnderlyingExpr());
+  if (!ToExpr)
+    return QualType();
+  
+  return Importer.getToContext().getDecltypeType(ToExpr);
+}
+
+QualType ASTNodeImporter::VisitRecordType(RecordType *T) {
+  RecordDecl *ToDecl
+    = dyn_cast_or_null<RecordDecl>(Importer.Import(T->getDecl()));
+  if (!ToDecl)
+    return QualType();
+
+  return Importer.getToContext().getTagDeclType(ToDecl);
+}
+
+QualType ASTNodeImporter::VisitEnumType(EnumType *T) {
+  EnumDecl *ToDecl
+    = dyn_cast_or_null<EnumDecl>(Importer.Import(T->getDecl()));
+  if (!ToDecl)
+    return QualType();
+
+  return Importer.getToContext().getTagDeclType(ToDecl);
+}
+
+QualType ASTNodeImporter::VisitElaboratedType(ElaboratedType *T) {
+  QualType ToUnderlyingType = Importer.Import(T->getUnderlyingType());
+  if (ToUnderlyingType.isNull())
+    return QualType();
+
+  return Importer.getToContext().getElaboratedType(ToUnderlyingType,
+                                                   T->getTagKind());
+}
+
+QualType ASTNodeImporter::VisitQualifiedNameType(QualifiedNameType *T) {
+  NestedNameSpecifier *ToQualifier = Importer.Import(T->getQualifier());
+  if (!ToQualifier)
+    return QualType();
+
+  QualType ToNamedType = Importer.Import(T->getNamedType());
+  if (ToNamedType.isNull())
+    return QualType();
+
+  return Importer.getToContext().getQualifiedNameType(ToQualifier, ToNamedType);
+}
+
+QualType ASTNodeImporter::VisitObjCInterfaceType(ObjCInterfaceType *T) {
+  ObjCInterfaceDecl *Class
+    = dyn_cast_or_null<ObjCInterfaceDecl>(Importer.Import(T->getDecl()));
+  if (!Class)
+    return QualType();
+
+  llvm::SmallVector<ObjCProtocolDecl *, 4> Protocols;
+  for (ObjCInterfaceType::qual_iterator P = T->qual_begin(), 
+                                     PEnd = T->qual_end();
+       P != PEnd; ++P) {
+    ObjCProtocolDecl *Protocol
+      = dyn_cast_or_null<ObjCProtocolDecl>(Importer.Import(*P));
+    if (!Protocol)
+      return QualType();
+    Protocols.push_back(Protocol);
+  }
+
+  return Importer.getToContext().getObjCInterfaceType(Class,
+                                                      Protocols.data(),
+                                                      Protocols.size());
+}
+
+QualType ASTNodeImporter::VisitObjCObjectPointerType(ObjCObjectPointerType *T) {
+  QualType ToPointeeType = Importer.Import(T->getPointeeType());
+  if (ToPointeeType.isNull())
+    return QualType();
+
+  llvm::SmallVector<ObjCProtocolDecl *, 4> Protocols;
+  for (ObjCObjectPointerType::qual_iterator P = T->qual_begin(), 
+                                         PEnd = T->qual_end();
+       P != PEnd; ++P) {
+    ObjCProtocolDecl *Protocol
+      = dyn_cast_or_null<ObjCProtocolDecl>(Importer.Import(*P));
+    if (!Protocol)
+      return QualType();
+    Protocols.push_back(Protocol);
+  }
+
+  return Importer.getToContext().getObjCObjectPointerType(ToPointeeType,
+                                                          Protocols.data(),
+                                                          Protocols.size());
+}
+
+//----------------------------------------------------------------------------
+// Import Declarations
+//----------------------------------------------------------------------------
+bool ASTNodeImporter::ImportDeclParts(NamedDecl *D, DeclContext *&DC, 
+                                      DeclContext *&LexicalDC, 
+                                      DeclarationName &Name, 
+                                      SourceLocation &Loc) {
+  // Import the context of this declaration.
+  DC = Importer.ImportContext(D->getDeclContext());
+  if (!DC)
+    return true;
+  
+  LexicalDC = DC;
+  if (D->getDeclContext() != D->getLexicalDeclContext()) {
+    LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
+    if (!LexicalDC)
+      return true;
+  }
+  
+  // Import the name of this declaration.
+  Name = Importer.Import(D->getDeclName());
+  if (D->getDeclName() && !Name)
+    return true;
+  
+  // Import the location of this declaration.
+  Loc = Importer.Import(D->getLocation());
+  return false;
+}
+
+void ASTNodeImporter::ImportDeclContext(DeclContext *FromDC) {
+  for (DeclContext::decl_iterator From = FromDC->decls_begin(),
+                               FromEnd = FromDC->decls_end();
+       From != FromEnd;
+       ++From)
+    Importer.Import(*From);
+}
+
+bool ASTNodeImporter::IsStructuralMatch(RecordDecl *FromRecord, 
+                                        RecordDecl *ToRecord) {
+  StructuralEquivalenceContext Ctx(Importer.getFromContext(),
+                                   Importer.getToContext(),
+                                   Importer.getDiags(),
+                                   Importer.getNonEquivalentDecls());
+  return Ctx.IsStructurallyEquivalent(FromRecord, ToRecord);
+}
+
+bool ASTNodeImporter::IsStructuralMatch(EnumDecl *FromEnum, EnumDecl *ToEnum) {
+  StructuralEquivalenceContext Ctx(Importer.getFromContext(),
+                                   Importer.getToContext(),
+                                   Importer.getDiags(),
+                                   Importer.getNonEquivalentDecls());
+  return Ctx.IsStructurallyEquivalent(FromEnum, ToEnum);
+}
+
+Decl *ASTNodeImporter::VisitDecl(Decl *D) {
+  Importer.FromDiag(D->getLocation(), diag::err_unsupported_ast_node)
+    << D->getDeclKindName();
+  return 0;
+}
+
+Decl *ASTNodeImporter::VisitNamespaceDecl(NamespaceDecl *D) {
+  // Import the major distinguishing characteristics of this namespace.
+  DeclContext *DC, *LexicalDC;
+  DeclarationName Name;
+  SourceLocation Loc;
+  if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
+    return 0;
+  
+  NamespaceDecl *MergeWithNamespace = 0;
+  if (!Name) {
+    // This is an anonymous namespace. Adopt an existing anonymous
+    // namespace if we can.
+    // FIXME: Not testable.
+    if (TranslationUnitDecl *TU = dyn_cast<TranslationUnitDecl>(DC))
+      MergeWithNamespace = TU->getAnonymousNamespace();
+    else
+      MergeWithNamespace = cast<NamespaceDecl>(DC)->getAnonymousNamespace();
+  } else {
+    llvm::SmallVector<NamedDecl *, 4> ConflictingDecls;
+    for (DeclContext::lookup_result Lookup = DC->lookup(Name);
+         Lookup.first != Lookup.second; 
+         ++Lookup.first) {
+      if (!(*Lookup.first)->isInIdentifierNamespace(Decl::IDNS_Namespace))
+        continue;
+      
+      if (NamespaceDecl *FoundNS = dyn_cast<NamespaceDecl>(*Lookup.first)) {
+        MergeWithNamespace = FoundNS;
+        ConflictingDecls.clear();
+        break;
+      }
+      
+      ConflictingDecls.push_back(*Lookup.first);
+    }
+    
+    if (!ConflictingDecls.empty()) {
+      Name = Importer.HandleNameConflict(Name, DC, Decl::IDNS_Namespace,
+                                         ConflictingDecls.data(), 
+                                         ConflictingDecls.size());
+    }
+  }
+  
+  // Create the "to" namespace, if needed.
+  NamespaceDecl *ToNamespace = MergeWithNamespace;
+  if (!ToNamespace) {
+    ToNamespace = NamespaceDecl::Create(Importer.getToContext(), DC, Loc,
+                                        Name.getAsIdentifierInfo());
+    ToNamespace->setLexicalDeclContext(LexicalDC);
+    LexicalDC->addDecl(ToNamespace);
+    
+    // If this is an anonymous namespace, register it as the anonymous
+    // namespace within its context.
+    if (!Name) {
+      if (TranslationUnitDecl *TU = dyn_cast<TranslationUnitDecl>(DC))
+        TU->setAnonymousNamespace(ToNamespace);
+      else
+        cast<NamespaceDecl>(DC)->setAnonymousNamespace(ToNamespace);
+    }
+  }
+  Importer.Imported(D, ToNamespace);
+  
+  ImportDeclContext(D);
+  
+  return ToNamespace;
+}
+
+Decl *ASTNodeImporter::VisitTypedefDecl(TypedefDecl *D) {
+  // Import the major distinguishing characteristics of this typedef.
+  DeclContext *DC, *LexicalDC;
+  DeclarationName Name;
+  SourceLocation Loc;
+  if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
+    return 0;
+  
+  // If this typedef is not in block scope, determine whether we've
+  // seen a typedef with the same name (that we can merge with) or any
+  // other entity by that name (which name lookup could conflict with).
+  if (!DC->isFunctionOrMethod()) {
+    llvm::SmallVector<NamedDecl *, 4> ConflictingDecls;
+    unsigned IDNS = Decl::IDNS_Ordinary;
+    for (DeclContext::lookup_result Lookup = DC->lookup(Name);
+         Lookup.first != Lookup.second; 
+         ++Lookup.first) {
+      if (!(*Lookup.first)->isInIdentifierNamespace(IDNS))
+        continue;
+      if (TypedefDecl *FoundTypedef = dyn_cast<TypedefDecl>(*Lookup.first)) {
+        if (Importer.IsStructurallyEquivalent(D->getUnderlyingType(),
+                                            FoundTypedef->getUnderlyingType()))
+          return Importer.Imported(D, FoundTypedef);
+      }
+      
+      ConflictingDecls.push_back(*Lookup.first);
+    }
+    
+    if (!ConflictingDecls.empty()) {
+      Name = Importer.HandleNameConflict(Name, DC, IDNS,
+                                         ConflictingDecls.data(), 
+                                         ConflictingDecls.size());
+      if (!Name)
+        return 0;
+    }
+  }
+  
+  // Import the underlying type of this typedef;
+  QualType T = Importer.Import(D->getUnderlyingType());
+  if (T.isNull())
+    return 0;
+  
+  // Create the new typedef node.
+  TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
+  TypedefDecl *ToTypedef = TypedefDecl::Create(Importer.getToContext(), DC,
+                                               Loc, Name.getAsIdentifierInfo(),
+                                               TInfo);
+  ToTypedef->setAccess(D->getAccess());
+  ToTypedef->setLexicalDeclContext(LexicalDC);
+  Importer.Imported(D, ToTypedef);
+  LexicalDC->addDecl(ToTypedef);
+  
+  return ToTypedef;
+}
+
+Decl *ASTNodeImporter::VisitEnumDecl(EnumDecl *D) {
+  // Import the major distinguishing characteristics of this enum.
+  DeclContext *DC, *LexicalDC;
+  DeclarationName Name;
+  SourceLocation Loc;
+  if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
+    return 0;
+  
+  // Figure out what enum name we're looking for.
+  unsigned IDNS = Decl::IDNS_Tag;
+  DeclarationName SearchName = Name;
+  if (!SearchName && D->getTypedefForAnonDecl()) {
+    SearchName = Importer.Import(D->getTypedefForAnonDecl()->getDeclName());
+    IDNS = Decl::IDNS_Ordinary;
+  } else if (Importer.getToContext().getLangOptions().CPlusPlus)
+    IDNS |= Decl::IDNS_Ordinary;
+  
+  // We may already have an enum of the same name; try to find and match it.
+  if (!DC->isFunctionOrMethod() && SearchName) {
+    llvm::SmallVector<NamedDecl *, 4> ConflictingDecls;
+    for (DeclContext::lookup_result Lookup = DC->lookup(Name);
+         Lookup.first != Lookup.second; 
+         ++Lookup.first) {
+      if (!(*Lookup.first)->isInIdentifierNamespace(IDNS))
+        continue;
+      
+      Decl *Found = *Lookup.first;
+      if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(Found)) {
+        if (const TagType *Tag = Typedef->getUnderlyingType()->getAs<TagType>())
+          Found = Tag->getDecl();
+      }
+      
+      if (EnumDecl *FoundEnum = dyn_cast<EnumDecl>(Found)) {
+        if (IsStructuralMatch(D, FoundEnum))
+          return Importer.Imported(D, FoundEnum);
+      }
+      
+      ConflictingDecls.push_back(*Lookup.first);
+    }
+    
+    if (!ConflictingDecls.empty()) {
+      Name = Importer.HandleNameConflict(Name, DC, IDNS,
+                                         ConflictingDecls.data(), 
+                                         ConflictingDecls.size());
+    }
+  }
+  
+  // Create the enum declaration.
+  EnumDecl *D2 = EnumDecl::Create(Importer.getToContext(), DC, Loc,
+                                      Name.getAsIdentifierInfo(),
+                                      Importer.Import(D->getTagKeywordLoc()),
+                                      0);
+  // Import the qualifier, if any.
+  if (D->getQualifier()) {
+    NestedNameSpecifier *NNS = Importer.Import(D->getQualifier());
+    SourceRange NNSRange = Importer.Import(D->getQualifierRange());
+    D2->setQualifierInfo(NNS, NNSRange);
+  }
+  D2->setAccess(D->getAccess());
+  D2->setLexicalDeclContext(LexicalDC);
+  Importer.Imported(D, D2);
+  LexicalDC->addDecl(D2);
+
+  // Import the integer type.
+  QualType ToIntegerType = Importer.Import(D->getIntegerType());
+  if (ToIntegerType.isNull())
+    return 0;
+  D2->setIntegerType(ToIntegerType);
+  
+  // Import the definition
+  if (D->isDefinition()) {
+    QualType T = Importer.Import(Importer.getFromContext().getTypeDeclType(D));
+    if (T.isNull())
+      return 0;
+
+    QualType ToPromotionType = Importer.Import(D->getPromotionType());
+    if (ToPromotionType.isNull())
+      return 0;
+    
+    D2->startDefinition();
+    ImportDeclContext(D);
+    D2->completeDefinition(T, ToPromotionType);
+  }
+  
+  return D2;
+}
+
+Decl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
+  // If this record has a definition in the translation unit we're coming from,
+  // but this particular declaration is not that definition, import the
+  // definition and map to that.
+  TagDecl *Definition = D->getDefinition();
+  if (Definition && Definition != D) {
+    Decl *ImportedDef = Importer.Import(Definition);
+    if (!ImportedDef)
+      return 0;
+    
+    return Importer.Imported(D, ImportedDef);
+  }
+  
+  // Import the major distinguishing characteristics of this record.
+  DeclContext *DC, *LexicalDC;
+  DeclarationName Name;
+  SourceLocation Loc;
+  if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
+    return 0;
+      
+  // Figure out what structure name we're looking for.
+  unsigned IDNS = Decl::IDNS_Tag;
+  DeclarationName SearchName = Name;
+  if (!SearchName && D->getTypedefForAnonDecl()) {
+    SearchName = Importer.Import(D->getTypedefForAnonDecl()->getDeclName());
+    IDNS = Decl::IDNS_Ordinary;
+  } else if (Importer.getToContext().getLangOptions().CPlusPlus)
+    IDNS |= Decl::IDNS_Ordinary;
+
+  // We may already have a record of the same name; try to find and match it.
+  RecordDecl *AdoptDecl = 0;
+  if (!DC->isFunctionOrMethod() && SearchName) {
+    llvm::SmallVector<NamedDecl *, 4> ConflictingDecls;
+    for (DeclContext::lookup_result Lookup = DC->lookup(Name);
+         Lookup.first != Lookup.second; 
+         ++Lookup.first) {
+      if (!(*Lookup.first)->isInIdentifierNamespace(IDNS))
+        continue;
+      
+      Decl *Found = *Lookup.first;
+      if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(Found)) {
+        if (const TagType *Tag = Typedef->getUnderlyingType()->getAs<TagType>())
+          Found = Tag->getDecl();
+      }
+      
+      if (RecordDecl *FoundRecord = dyn_cast<RecordDecl>(Found)) {
+        if (RecordDecl *FoundDef = FoundRecord->getDefinition()) {
+          if (!D->isDefinition() || IsStructuralMatch(D, FoundDef)) {
+            // The record types structurally match, or the "from" translation
+            // unit only had a forward declaration anyway; call it the same
+            // function.
+            // FIXME: For C++, we should also merge methods here.
+            return Importer.Imported(D, FoundDef);
+          }
+        } else {
+          // We have a forward declaration of this type, so adopt that forward
+          // declaration rather than building a new one.
+          AdoptDecl = FoundRecord;
+          continue;
+        }          
+      }
+      
+      ConflictingDecls.push_back(*Lookup.first);
+    }
+    
+    if (!ConflictingDecls.empty()) {
+      Name = Importer.HandleNameConflict(Name, DC, IDNS,
+                                         ConflictingDecls.data(), 
+                                         ConflictingDecls.size());
+    }
+  }
+  
+  // Create the record declaration.
+  RecordDecl *D2 = AdoptDecl;
+  if (!D2) {
+    if (CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(D)) {
+      CXXRecordDecl *D2CXX = CXXRecordDecl::Create(Importer.getToContext(), 
+                                                   D->getTagKind(),
+                                                   DC, Loc,
+                                                   Name.getAsIdentifierInfo(), 
+                                        Importer.Import(D->getTagKeywordLoc()));
+      D2 = D2CXX;
+      D2->setAccess(D->getAccess());
+      
+      if (D->isDefinition()) {
+        // Add base classes.
+        llvm::SmallVector<CXXBaseSpecifier *, 4> Bases;
+        for (CXXRecordDecl::base_class_iterator 
+                  Base1 = D1CXX->bases_begin(),
+               FromBaseEnd = D1CXX->bases_end();
+             Base1 != FromBaseEnd;
+             ++Base1) {
+          QualType T = Importer.Import(Base1->getType());
+          if (T.isNull())
+            return 0;
+          
+          Bases.push_back(
+            new (Importer.getToContext()) 
+                  CXXBaseSpecifier(Importer.Import(Base1->getSourceRange()),
+                                   Base1->isVirtual(),
+                                   Base1->isBaseOfClass(),
+                                   Base1->getAccessSpecifierAsWritten(),
+                                   T));
+        }
+        if (!Bases.empty())
+          D2CXX->setBases(Bases.data(), Bases.size());
+      }
+    } else {
+      D2 = RecordDecl::Create(Importer.getToContext(), D->getTagKind(),
+                                    DC, Loc,
+                                    Name.getAsIdentifierInfo(), 
+                                    Importer.Import(D->getTagKeywordLoc()));
+    }
+    // Import the qualifier, if any.
+    if (D->getQualifier()) {
+      NestedNameSpecifier *NNS = Importer.Import(D->getQualifier());
+      SourceRange NNSRange = Importer.Import(D->getQualifierRange());
+      D2->setQualifierInfo(NNS, NNSRange);
+    }
+    D2->setLexicalDeclContext(LexicalDC);
+    LexicalDC->addDecl(D2);
+  }
+  
+  Importer.Imported(D, D2);
+
+  if (D->isDefinition()) {
+    D2->startDefinition();
+    ImportDeclContext(D);
+    D2->completeDefinition();
+  }
+  
+  return D2;
+}
+
+Decl *ASTNodeImporter::VisitEnumConstantDecl(EnumConstantDecl *D) {
+  // Import the major distinguishing characteristics of this enumerator.
+  DeclContext *DC, *LexicalDC;
+  DeclarationName Name;
+  SourceLocation Loc;
+  if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
+    return 0;
+
+  QualType T = Importer.Import(D->getType());
+  if (T.isNull())
+    return 0;
+
+  // Determine whether there are any other declarations with the same name and 
+  // in the same context.
+  if (!LexicalDC->isFunctionOrMethod()) {
+    llvm::SmallVector<NamedDecl *, 4> ConflictingDecls;
+    unsigned IDNS = Decl::IDNS_Ordinary;
+    for (DeclContext::lookup_result Lookup = DC->lookup(Name);
+         Lookup.first != Lookup.second; 
+         ++Lookup.first) {
+      if (!(*Lookup.first)->isInIdentifierNamespace(IDNS))
+        continue;
+      
+      ConflictingDecls.push_back(*Lookup.first);
+    }
+    
+    if (!ConflictingDecls.empty()) {
+      Name = Importer.HandleNameConflict(Name, DC, IDNS,
+                                         ConflictingDecls.data(), 
+                                         ConflictingDecls.size());
+      if (!Name)
+        return 0;
+    }
+  }
+  
+  Expr *Init = Importer.Import(D->getInitExpr());
+  if (D->getInitExpr() && !Init)
+    return 0;
+  
+  EnumConstantDecl *ToEnumerator
+    = EnumConstantDecl::Create(Importer.getToContext(), cast<EnumDecl>(DC), Loc, 
+                               Name.getAsIdentifierInfo(), T, 
+                               Init, D->getInitVal());
+  ToEnumerator->setAccess(D->getAccess());
+  ToEnumerator->setLexicalDeclContext(LexicalDC);
+  Importer.Imported(D, ToEnumerator);
+  LexicalDC->addDecl(ToEnumerator);
+  return ToEnumerator;
+}
+
+Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
+  // Import the major distinguishing characteristics of this function.
+  DeclContext *DC, *LexicalDC;
+  DeclarationName Name;
+  SourceLocation Loc;
+  if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
+    return 0;
+  
+  // Try to find a function in our own ("to") context with the same name, same
+  // type, and in the same context as the function we're importing.
+  if (!LexicalDC->isFunctionOrMethod()) {
+    llvm::SmallVector<NamedDecl *, 4> ConflictingDecls;
+    unsigned IDNS = Decl::IDNS_Ordinary;
+    for (DeclContext::lookup_result Lookup = DC->lookup(Name);
+         Lookup.first != Lookup.second; 
+         ++Lookup.first) {
+      if (!(*Lookup.first)->isInIdentifierNamespace(IDNS))
+        continue;
+    
+      if (FunctionDecl *FoundFunction = dyn_cast<FunctionDecl>(*Lookup.first)) {
+        if (isExternalLinkage(FoundFunction->getLinkage()) &&
+            isExternalLinkage(D->getLinkage())) {
+          if (Importer.IsStructurallyEquivalent(D->getType(), 
+                                                FoundFunction->getType())) {
+            // FIXME: Actually try to merge the body and other attributes.
+            return Importer.Imported(D, FoundFunction);
+          }
+        
+          // FIXME: Check for overloading more carefully, e.g., by boosting
+          // Sema::IsOverload out to the AST library.
+          
+          // Function overloading is okay in C++.
+          if (Importer.getToContext().getLangOptions().CPlusPlus)
+            continue;
+          
+          // Complain about inconsistent function types.
+          Importer.ToDiag(Loc, diag::err_odr_function_type_inconsistent)
+            << Name << D->getType() << FoundFunction->getType();
+          Importer.ToDiag(FoundFunction->getLocation(), 
+                          diag::note_odr_value_here)
+            << FoundFunction->getType();
+        }
+      }
+      
+      ConflictingDecls.push_back(*Lookup.first);
+    }
+    
+    if (!ConflictingDecls.empty()) {
+      Name = Importer.HandleNameConflict(Name, DC, IDNS,
+                                         ConflictingDecls.data(), 
+                                         ConflictingDecls.size());
+      if (!Name)
+        return 0;
+    }    
+  }
+
+  // Import the type.
+  QualType T = Importer.Import(D->getType());
+  if (T.isNull())
+    return 0;
+  
+  // Import the function parameters.
+  llvm::SmallVector<ParmVarDecl *, 8> Parameters;
+  for (FunctionDecl::param_iterator P = D->param_begin(), PEnd = D->param_end();
+       P != PEnd; ++P) {
+    ParmVarDecl *ToP = cast_or_null<ParmVarDecl>(Importer.Import(*P));
+    if (!ToP)
+      return 0;
+    
+    Parameters.push_back(ToP);
+  }
+  
+  // Create the imported function.
+  TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
+  FunctionDecl *ToFunction = 0;
+  if (CXXConstructorDecl *FromConstructor = dyn_cast<CXXConstructorDecl>(D)) {
+    ToFunction = CXXConstructorDecl::Create(Importer.getToContext(),
+                                            cast<CXXRecordDecl>(DC),
+                                            Loc, Name, T, TInfo, 
+                                            FromConstructor->isExplicit(),
+                                            D->isInlineSpecified(), 
+                                            D->isImplicit());
+  } else if (isa<CXXDestructorDecl>(D)) {
+    ToFunction = CXXDestructorDecl::Create(Importer.getToContext(),
+                                           cast<CXXRecordDecl>(DC),
+                                           Loc, Name, T, 
+                                           D->isInlineSpecified(),
+                                           D->isImplicit());
+  } else if (CXXConversionDecl *FromConversion
+                                           = dyn_cast<CXXConversionDecl>(D)) {
+    ToFunction = CXXConversionDecl::Create(Importer.getToContext(), 
+                                           cast<CXXRecordDecl>(DC),
+                                           Loc, Name, T, TInfo,
+                                           D->isInlineSpecified(),
+                                           FromConversion->isExplicit());
+  } else {
+    ToFunction = FunctionDecl::Create(Importer.getToContext(), DC, Loc, 
+                                      Name, T, TInfo, D->getStorageClass(), 
+                                      D->getStorageClassAsWritten(),
+                                      D->isInlineSpecified(),
+                                      D->hasWrittenPrototype());
+  }
+
+  // Import the qualifier, if any.
+  if (D->getQualifier()) {
+    NestedNameSpecifier *NNS = Importer.Import(D->getQualifier());
+    SourceRange NNSRange = Importer.Import(D->getQualifierRange());
+    ToFunction->setQualifierInfo(NNS, NNSRange);
+  }
+  ToFunction->setAccess(D->getAccess());
+  ToFunction->setLexicalDeclContext(LexicalDC);
+  Importer.Imported(D, ToFunction);
+  LexicalDC->addDecl(ToFunction);
+
+  // Set the parameters.
+  for (unsigned I = 0, N = Parameters.size(); I != N; ++I) {
+    Parameters[I]->setOwningFunction(ToFunction);
+    ToFunction->addDecl(Parameters[I]);
+  }
+  ToFunction->setParams(Parameters.data(), Parameters.size());
+
+  // FIXME: Other bits to merge?
+  
+  return ToFunction;
+}
+
+Decl *ASTNodeImporter::VisitCXXMethodDecl(CXXMethodDecl *D) {
+  return VisitFunctionDecl(D);
+}
+
+Decl *ASTNodeImporter::VisitCXXConstructorDecl(CXXConstructorDecl *D) {
+  return VisitCXXMethodDecl(D);
+}
+
+Decl *ASTNodeImporter::VisitCXXDestructorDecl(CXXDestructorDecl *D) {
+  return VisitCXXMethodDecl(D);
+}
+
+Decl *ASTNodeImporter::VisitCXXConversionDecl(CXXConversionDecl *D) {
+  return VisitCXXMethodDecl(D);
+}
+
+Decl *ASTNodeImporter::VisitFieldDecl(FieldDecl *D) {
+  // Import the major distinguishing characteristics of a variable.
+  DeclContext *DC, *LexicalDC;
+  DeclarationName Name;
+  SourceLocation Loc;
+  if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
+    return 0;
+  
+  // Import the type.
+  QualType T = Importer.Import(D->getType());
+  if (T.isNull())
+    return 0;
+  
+  TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
+  Expr *BitWidth = Importer.Import(D->getBitWidth());
+  if (!BitWidth && D->getBitWidth())
+    return 0;
+  
+  FieldDecl *ToField = FieldDecl::Create(Importer.getToContext(), DC, 
+                                         Loc, Name.getAsIdentifierInfo(),
+                                         T, TInfo, BitWidth, D->isMutable());
+  ToField->setAccess(D->getAccess());
+  ToField->setLexicalDeclContext(LexicalDC);
+  Importer.Imported(D, ToField);
+  LexicalDC->addDecl(ToField);
+  return ToField;
+}
+
+Decl *ASTNodeImporter::VisitObjCIvarDecl(ObjCIvarDecl *D) {
+  // Import the major distinguishing characteristics of an ivar.
+  DeclContext *DC, *LexicalDC;
+  DeclarationName Name;
+  SourceLocation Loc;
+  if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
+    return 0;
+  
+  // Determine whether we've already imported this ivar 
+  for (DeclContext::lookup_result Lookup = DC->lookup(Name);
+       Lookup.first != Lookup.second; 
+       ++Lookup.first) {
+    if (ObjCIvarDecl *FoundIvar = dyn_cast<ObjCIvarDecl>(*Lookup.first)) {
+      if (Importer.IsStructurallyEquivalent(D->getType(), 
+                                            FoundIvar->getType())) {
+        Importer.Imported(D, FoundIvar);
+        return FoundIvar;
+      }
+
+      Importer.ToDiag(Loc, diag::err_odr_ivar_type_inconsistent)
+        << Name << D->getType() << FoundIvar->getType();
+      Importer.ToDiag(FoundIvar->getLocation(), diag::note_odr_value_here)
+        << FoundIvar->getType();
+      return 0;
+    }
+  }
+
+  // Import the type.
+  QualType T = Importer.Import(D->getType());
+  if (T.isNull())
+    return 0;
+  
+  TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
+  Expr *BitWidth = Importer.Import(D->getBitWidth());
+  if (!BitWidth && D->getBitWidth())
+    return 0;
+  
+  ObjCIvarDecl *ToIvar = ObjCIvarDecl::Create(Importer.getToContext(),
+                                              cast<ObjCContainerDecl>(DC),
+                                              Loc, Name.getAsIdentifierInfo(),
+                                              T, TInfo, D->getAccessControl(),
+                                              BitWidth);
+  ToIvar->setLexicalDeclContext(LexicalDC);
+  Importer.Imported(D, ToIvar);
+  LexicalDC->addDecl(ToIvar);
+  return ToIvar;
+  
+}
+
+Decl *ASTNodeImporter::VisitVarDecl(VarDecl *D) {
+  // Import the major distinguishing characteristics of a variable.
+  DeclContext *DC, *LexicalDC;
+  DeclarationName Name;
+  SourceLocation Loc;
+  if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
+    return 0;
+  
+  // Try to find a variable in our own ("to") context with the same name and
+  // in the same context as the variable we're importing.
+  if (D->isFileVarDecl()) {
+    VarDecl *MergeWithVar = 0;
+    llvm::SmallVector<NamedDecl *, 4> ConflictingDecls;
+    unsigned IDNS = Decl::IDNS_Ordinary;
+    for (DeclContext::lookup_result Lookup = DC->lookup(Name);
+         Lookup.first != Lookup.second; 
+         ++Lookup.first) {
+      if (!(*Lookup.first)->isInIdentifierNamespace(IDNS))
+        continue;
+      
+      if (VarDecl *FoundVar = dyn_cast<VarDecl>(*Lookup.first)) {
+        // We have found a variable that we may need to merge with. Check it.
+        if (isExternalLinkage(FoundVar->getLinkage()) &&
+            isExternalLinkage(D->getLinkage())) {
+          if (Importer.IsStructurallyEquivalent(D->getType(), 
+                                                FoundVar->getType())) {
+            MergeWithVar = FoundVar;
+            break;
+          }
+
+          const ArrayType *FoundArray
+            = Importer.getToContext().getAsArrayType(FoundVar->getType());
+          const ArrayType *TArray
+            = Importer.getToContext().getAsArrayType(D->getType());
+          if (FoundArray && TArray) {
+            if (isa<IncompleteArrayType>(FoundArray) &&
+                isa<ConstantArrayType>(TArray)) {
+              // Import the type.
+              QualType T = Importer.Import(D->getType());
+              if (T.isNull())
+                return 0;
+              
+              FoundVar->setType(T);
+              MergeWithVar = FoundVar;
+              break;
+            } else if (isa<IncompleteArrayType>(TArray) &&
+                       isa<ConstantArrayType>(FoundArray)) {
+              MergeWithVar = FoundVar;
+              break;
+            }
+          }
+
+          Importer.ToDiag(Loc, diag::err_odr_variable_type_inconsistent)
+            << Name << D->getType() << FoundVar->getType();
+          Importer.ToDiag(FoundVar->getLocation(), diag::note_odr_value_here)
+            << FoundVar->getType();
+        }
+      }
+      
+      ConflictingDecls.push_back(*Lookup.first);
+    }
+
+    if (MergeWithVar) {
+      // An equivalent variable with external linkage has been found. Link 
+      // the two declarations, then merge them.
+      Importer.Imported(D, MergeWithVar);
+      
+      if (VarDecl *DDef = D->getDefinition()) {
+        if (VarDecl *ExistingDef = MergeWithVar->getDefinition()) {
+          Importer.ToDiag(ExistingDef->getLocation(), 
+                          diag::err_odr_variable_multiple_def)
+            << Name;
+          Importer.FromDiag(DDef->getLocation(), diag::note_odr_defined_here);
+        } else {
+          Expr *Init = Importer.Import(DDef->getInit());
+          MergeWithVar->setInit(Init);
+        }
+      }
+      
+      return MergeWithVar;
+    }
+    
+    if (!ConflictingDecls.empty()) {
+      Name = Importer.HandleNameConflict(Name, DC, IDNS,
+                                         ConflictingDecls.data(), 
+                                         ConflictingDecls.size());
+      if (!Name)
+        return 0;
+    }
+  }
+    
+  // Import the type.
+  QualType T = Importer.Import(D->getType());
+  if (T.isNull())
+    return 0;
+  
+  // Create the imported variable.
+  TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
+  VarDecl *ToVar = VarDecl::Create(Importer.getToContext(), DC, Loc, 
+                                   Name.getAsIdentifierInfo(), T, TInfo,
+                                   D->getStorageClass(),
+                                   D->getStorageClassAsWritten());
+  // Import the qualifier, if any.
+  if (D->getQualifier()) {
+    NestedNameSpecifier *NNS = Importer.Import(D->getQualifier());
+    SourceRange NNSRange = Importer.Import(D->getQualifierRange());
+    ToVar->setQualifierInfo(NNS, NNSRange);
+  }
+  ToVar->setAccess(D->getAccess());
+  ToVar->setLexicalDeclContext(LexicalDC);
+  Importer.Imported(D, ToVar);
+  LexicalDC->addDecl(ToVar);
+
+  // Merge the initializer.
+  // FIXME: Can we really import any initializer? Alternatively, we could force
+  // ourselves to import every declaration of a variable and then only use
+  // getInit() here.
+  ToVar->setInit(Importer.Import(const_cast<Expr *>(D->getAnyInitializer())));
+
+  // FIXME: Other bits to merge?
+  
+  return ToVar;
+}
+
+Decl *ASTNodeImporter::VisitImplicitParamDecl(ImplicitParamDecl *D) {
+  // Parameters are created in the translation unit's context, then moved
+  // into the function declaration's context afterward.
+  DeclContext *DC = Importer.getToContext().getTranslationUnitDecl();
+  
+  // Import the name of this declaration.
+  DeclarationName Name = Importer.Import(D->getDeclName());
+  if (D->getDeclName() && !Name)
+    return 0;
+  
+  // Import the location of this declaration.
+  SourceLocation Loc = Importer.Import(D->getLocation());
+  
+  // Import the parameter's type.
+  QualType T = Importer.Import(D->getType());
+  if (T.isNull())
+    return 0;
+  
+  // Create the imported parameter.
+  ImplicitParamDecl *ToParm
+    = ImplicitParamDecl::Create(Importer.getToContext(), DC,
+                                Loc, Name.getAsIdentifierInfo(),
+                                T);
+  return Importer.Imported(D, ToParm);
+}
+
+Decl *ASTNodeImporter::VisitParmVarDecl(ParmVarDecl *D) {
+  // Parameters are created in the translation unit's context, then moved
+  // into the function declaration's context afterward.
+  DeclContext *DC = Importer.getToContext().getTranslationUnitDecl();
+  
+  // Import the name of this declaration.
+  DeclarationName Name = Importer.Import(D->getDeclName());
+  if (D->getDeclName() && !Name)
+    return 0;
+  
+  // Import the location of this declaration.
+  SourceLocation Loc = Importer.Import(D->getLocation());
+  
+  // Import the parameter's type.
+  QualType T = Importer.Import(D->getType());
+  if (T.isNull())
+    return 0;
+  
+  // Create the imported parameter.
+  TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
+  ParmVarDecl *ToParm = ParmVarDecl::Create(Importer.getToContext(), DC,
+                                            Loc, Name.getAsIdentifierInfo(),
+                                            T, TInfo, D->getStorageClass(),
+                                             D->getStorageClassAsWritten(),
+                                            /*FIXME: Default argument*/ 0);
+  ToParm->setHasInheritedDefaultArg(D->hasInheritedDefaultArg());
+  return Importer.Imported(D, ToParm);
+}
+
+Decl *ASTNodeImporter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
+  // Import the major distinguishing characteristics of a method.
+  DeclContext *DC, *LexicalDC;
+  DeclarationName Name;
+  SourceLocation Loc;
+  if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
+    return 0;
+  
+  for (DeclContext::lookup_result Lookup = DC->lookup(Name);
+       Lookup.first != Lookup.second; 
+       ++Lookup.first) {
+    if (ObjCMethodDecl *FoundMethod = dyn_cast<ObjCMethodDecl>(*Lookup.first)) {
+      if (FoundMethod->isInstanceMethod() != D->isInstanceMethod())
+        continue;
+
+      // Check return types.
+      if (!Importer.IsStructurallyEquivalent(D->getResultType(),
+                                             FoundMethod->getResultType())) {
+        Importer.ToDiag(Loc, diag::err_odr_objc_method_result_type_inconsistent)
+          << D->isInstanceMethod() << Name
+          << D->getResultType() << FoundMethod->getResultType();
+        Importer.ToDiag(FoundMethod->getLocation(), 
+                        diag::note_odr_objc_method_here)
+          << D->isInstanceMethod() << Name;
+        return 0;
+      }
+
+      // Check the number of parameters.
+      if (D->param_size() != FoundMethod->param_size()) {
+        Importer.ToDiag(Loc, diag::err_odr_objc_method_num_params_inconsistent)
+          << D->isInstanceMethod() << Name
+          << D->param_size() << FoundMethod->param_size();
+        Importer.ToDiag(FoundMethod->getLocation(), 
+                        diag::note_odr_objc_method_here)
+          << D->isInstanceMethod() << Name;
+        return 0;
+      }
+
+      // Check parameter types.
+      for (ObjCMethodDecl::param_iterator P = D->param_begin(), 
+             PEnd = D->param_end(), FoundP = FoundMethod->param_begin();
+           P != PEnd; ++P, ++FoundP) {
+        if (!Importer.IsStructurallyEquivalent((*P)->getType(), 
+                                               (*FoundP)->getType())) {
+          Importer.FromDiag((*P)->getLocation(), 
+                            diag::err_odr_objc_method_param_type_inconsistent)
+            << D->isInstanceMethod() << Name
+            << (*P)->getType() << (*FoundP)->getType();
+          Importer.ToDiag((*FoundP)->getLocation(), diag::note_odr_value_here)
+            << (*FoundP)->getType();
+          return 0;
+        }
+      }
+
+      // Check variadic/non-variadic.
+      // Check the number of parameters.
+      if (D->isVariadic() != FoundMethod->isVariadic()) {
+        Importer.ToDiag(Loc, diag::err_odr_objc_method_variadic_inconsistent)
+          << D->isInstanceMethod() << Name;
+        Importer.ToDiag(FoundMethod->getLocation(), 
+                        diag::note_odr_objc_method_here)
+          << D->isInstanceMethod() << Name;
+        return 0;
+      }
+
+      // FIXME: Any other bits we need to merge?
+      return Importer.Imported(D, FoundMethod);
+    }
+  }
+
+  // Import the result type.
+  QualType ResultTy = Importer.Import(D->getResultType());
+  if (ResultTy.isNull())
+    return 0;
+
+  TypeSourceInfo *ResultTInfo = Importer.Import(D->getResultTypeSourceInfo());
+
+  ObjCMethodDecl *ToMethod
+    = ObjCMethodDecl::Create(Importer.getToContext(),
+                             Loc,
+                             Importer.Import(D->getLocEnd()),
+                             Name.getObjCSelector(),
+                             ResultTy, ResultTInfo, DC,
+                             D->isInstanceMethod(),
+                             D->isVariadic(),
+                             D->isSynthesized(),
+                             D->getImplementationControl());
+
+  // FIXME: When we decide to merge method definitions, we'll need to
+  // deal with implicit parameters.
+
+  // Import the parameters
+  llvm::SmallVector<ParmVarDecl *, 5> ToParams;
+  for (ObjCMethodDecl::param_iterator FromP = D->param_begin(),
+                                   FromPEnd = D->param_end();
+       FromP != FromPEnd; 
+       ++FromP) {
+    ParmVarDecl *ToP = cast_or_null<ParmVarDecl>(Importer.Import(*FromP));
+    if (!ToP)
+      return 0;
+    
+    ToParams.push_back(ToP);
+  }
+  
+  // Set the parameters.
+  for (unsigned I = 0, N = ToParams.size(); I != N; ++I) {
+    ToParams[I]->setOwningFunction(ToMethod);
+    ToMethod->addDecl(ToParams[I]);
+  }
+  ToMethod->setMethodParams(Importer.getToContext(), 
+                            ToParams.data(), ToParams.size(),
+                            ToParams.size());
+
+  ToMethod->setLexicalDeclContext(LexicalDC);
+  Importer.Imported(D, ToMethod);
+  LexicalDC->addDecl(ToMethod);
+  return ToMethod;
+}
+
+Decl *ASTNodeImporter::VisitObjCCategoryDecl(ObjCCategoryDecl *D) {
+  // Import the major distinguishing characteristics of a category.
+  DeclContext *DC, *LexicalDC;
+  DeclarationName Name;
+  SourceLocation Loc;
+  if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
+    return 0;
+  
+  ObjCInterfaceDecl *ToInterface
+    = cast_or_null<ObjCInterfaceDecl>(Importer.Import(D->getClassInterface()));
+  if (!ToInterface)
+    return 0;
+  
+  // Determine if we've already encountered this category.
+  ObjCCategoryDecl *MergeWithCategory
+    = ToInterface->FindCategoryDeclaration(Name.getAsIdentifierInfo());
+  ObjCCategoryDecl *ToCategory = MergeWithCategory;
+  if (!ToCategory) {
+    ToCategory = ObjCCategoryDecl::Create(Importer.getToContext(), DC,
+                                          Importer.Import(D->getAtLoc()),
+                                          Loc, 
+                                       Importer.Import(D->getCategoryNameLoc()), 
+                                          Name.getAsIdentifierInfo());
+    ToCategory->setLexicalDeclContext(LexicalDC);
+    LexicalDC->addDecl(ToCategory);
+    Importer.Imported(D, ToCategory);
+    
+    // Link this category into its class's category list.
+    ToCategory->setClassInterface(ToInterface);
+    ToCategory->insertNextClassCategory();
+    
+    // Import protocols
+    llvm::SmallVector<ObjCProtocolDecl *, 4> Protocols;
+    llvm::SmallVector<SourceLocation, 4> ProtocolLocs;
+    ObjCCategoryDecl::protocol_loc_iterator FromProtoLoc
+      = D->protocol_loc_begin();
+    for (ObjCCategoryDecl::protocol_iterator FromProto = D->protocol_begin(),
+                                          FromProtoEnd = D->protocol_end();
+         FromProto != FromProtoEnd;
+         ++FromProto, ++FromProtoLoc) {
+      ObjCProtocolDecl *ToProto
+        = cast_or_null<ObjCProtocolDecl>(Importer.Import(*FromProto));
+      if (!ToProto)
+        return 0;
+      Protocols.push_back(ToProto);
+      ProtocolLocs.push_back(Importer.Import(*FromProtoLoc));
+    }
+    
+    // FIXME: If we're merging, make sure that the protocol list is the same.
+    ToCategory->setProtocolList(Protocols.data(), Protocols.size(),
+                                ProtocolLocs.data(), Importer.getToContext());
+    
+  } else {
+    Importer.Imported(D, ToCategory);
+  }
+  
+  // Import all of the members of this category.
+  ImportDeclContext(D);
+ 
+  // If we have an implementation, import it as well.
+  if (D->getImplementation()) {
+    ObjCCategoryImplDecl *Impl
+      = cast<ObjCCategoryImplDecl>(Importer.Import(D->getImplementation()));
+    if (!Impl)
+      return 0;
+    
+    ToCategory->setImplementation(Impl);
+  }
+  
+  return ToCategory;
+}
+
+Decl *ASTNodeImporter::VisitObjCProtocolDecl(ObjCProtocolDecl *D) {
+  // Import the major distinguishing characteristics of a protocol.
+  DeclContext *DC, *LexicalDC;
+  DeclarationName Name;
+  SourceLocation Loc;
+  if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
+    return 0;
+
+  ObjCProtocolDecl *MergeWithProtocol = 0;
+  for (DeclContext::lookup_result Lookup = DC->lookup(Name);
+       Lookup.first != Lookup.second; 
+       ++Lookup.first) {
+    if (!(*Lookup.first)->isInIdentifierNamespace(Decl::IDNS_ObjCProtocol))
+      continue;
+    
+    if ((MergeWithProtocol = dyn_cast<ObjCProtocolDecl>(*Lookup.first)))
+      break;
+  }
+  
+  ObjCProtocolDecl *ToProto = MergeWithProtocol;
+  if (!ToProto || ToProto->isForwardDecl()) {
+    if (!ToProto) {
+      ToProto = ObjCProtocolDecl::Create(Importer.getToContext(), DC, Loc,
+                                         Name.getAsIdentifierInfo());
+      ToProto->setForwardDecl(D->isForwardDecl());
+      ToProto->setLexicalDeclContext(LexicalDC);
+      LexicalDC->addDecl(ToProto);
+    }
+    Importer.Imported(D, ToProto);
+
+    // Import protocols
+    llvm::SmallVector<ObjCProtocolDecl *, 4> Protocols;
+    llvm::SmallVector<SourceLocation, 4> ProtocolLocs;
+    ObjCProtocolDecl::protocol_loc_iterator 
+      FromProtoLoc = D->protocol_loc_begin();
+    for (ObjCProtocolDecl::protocol_iterator FromProto = D->protocol_begin(),
+                                          FromProtoEnd = D->protocol_end();
+       FromProto != FromProtoEnd;
+       ++FromProto, ++FromProtoLoc) {
+      ObjCProtocolDecl *ToProto
+        = cast_or_null<ObjCProtocolDecl>(Importer.Import(*FromProto));
+      if (!ToProto)
+        return 0;
+      Protocols.push_back(ToProto);
+      ProtocolLocs.push_back(Importer.Import(*FromProtoLoc));
+    }
+    
+    // FIXME: If we're merging, make sure that the protocol list is the same.
+    ToProto->setProtocolList(Protocols.data(), Protocols.size(),
+                             ProtocolLocs.data(), Importer.getToContext());
+  } else {
+    Importer.Imported(D, ToProto);
+  }
+
+  // Import all of the members of this protocol.
+  ImportDeclContext(D);
+
+  return ToProto;
+}
+
+Decl *ASTNodeImporter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
+  // Import the major distinguishing characteristics of an @interface.
+  DeclContext *DC, *LexicalDC;
+  DeclarationName Name;
+  SourceLocation Loc;
+  if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
+    return 0;
+
+  ObjCInterfaceDecl *MergeWithIface = 0;
+  for (DeclContext::lookup_result Lookup = DC->lookup(Name);
+       Lookup.first != Lookup.second; 
+       ++Lookup.first) {
+    if (!(*Lookup.first)->isInIdentifierNamespace(Decl::IDNS_Ordinary))
+      continue;
+    
+    if ((MergeWithIface = dyn_cast<ObjCInterfaceDecl>(*Lookup.first)))
+      break;
+  }
+  
+  ObjCInterfaceDecl *ToIface = MergeWithIface;
+  if (!ToIface || ToIface->isForwardDecl()) {
+    if (!ToIface) {
+      ToIface = ObjCInterfaceDecl::Create(Importer.getToContext(),
+                                          DC, Loc,
+                                          Name.getAsIdentifierInfo(),
+                                          Importer.Import(D->getClassLoc()),
+                                          D->isForwardDecl(),
+                                          D->isImplicitInterfaceDecl());
+      ToIface->setForwardDecl(D->isForwardDecl());
+      ToIface->setLexicalDeclContext(LexicalDC);
+      LexicalDC->addDecl(ToIface);
+    }
+    Importer.Imported(D, ToIface);
+
+    if (D->getSuperClass()) {
+      ObjCInterfaceDecl *Super
+        = cast_or_null<ObjCInterfaceDecl>(Importer.Import(D->getSuperClass()));
+      if (!Super)
+        return 0;
+      
+      ToIface->setSuperClass(Super);
+      ToIface->setSuperClassLoc(Importer.Import(D->getSuperClassLoc()));
+    }
+    
+    // Import protocols
+    llvm::SmallVector<ObjCProtocolDecl *, 4> Protocols;
+    llvm::SmallVector<SourceLocation, 4> ProtocolLocs;
+    ObjCInterfaceDecl::protocol_loc_iterator 
+      FromProtoLoc = D->protocol_loc_begin();
+    for (ObjCInterfaceDecl::protocol_iterator FromProto = D->protocol_begin(),
+                                           FromProtoEnd = D->protocol_end();
+       FromProto != FromProtoEnd;
+       ++FromProto, ++FromProtoLoc) {
+      ObjCProtocolDecl *ToProto
+        = cast_or_null<ObjCProtocolDecl>(Importer.Import(*FromProto));
+      if (!ToProto)
+        return 0;
+      Protocols.push_back(ToProto);
+      ProtocolLocs.push_back(Importer.Import(*FromProtoLoc));
+    }
+    
+    // FIXME: If we're merging, make sure that the protocol list is the same.
+    ToIface->setProtocolList(Protocols.data(), Protocols.size(),
+                             ProtocolLocs.data(), Importer.getToContext());
+    
+    // Import @end range
+    ToIface->setAtEndRange(Importer.Import(D->getAtEndRange()));
+  } else {
+    Importer.Imported(D, ToIface);
+
+    // Check for consistency of superclasses.
+    DeclarationName FromSuperName, ToSuperName;
+    if (D->getSuperClass())
+      FromSuperName = Importer.Import(D->getSuperClass()->getDeclName());
+    if (ToIface->getSuperClass())
+      ToSuperName = ToIface->getSuperClass()->getDeclName();
+    if (FromSuperName != ToSuperName) {
+      Importer.ToDiag(ToIface->getLocation(), 
+                      diag::err_odr_objc_superclass_inconsistent)
+        << ToIface->getDeclName();
+      if (ToIface->getSuperClass())
+        Importer.ToDiag(ToIface->getSuperClassLoc(), 
+                        diag::note_odr_objc_superclass)
+          << ToIface->getSuperClass()->getDeclName();
+      else
+        Importer.ToDiag(ToIface->getLocation(), 
+                        diag::note_odr_objc_missing_superclass);
+      if (D->getSuperClass())
+        Importer.FromDiag(D->getSuperClassLoc(), 
+                          diag::note_odr_objc_superclass)
+          << D->getSuperClass()->getDeclName();
+      else
+        Importer.FromDiag(D->getLocation(), 
+                          diag::note_odr_objc_missing_superclass);
+      return 0;
+    }
+  }
+  
+  // Import categories. When the categories themselves are imported, they'll
+  // hook themselves into this interface.
+  for (ObjCCategoryDecl *FromCat = D->getCategoryList(); FromCat;
+       FromCat = FromCat->getNextClassCategory())
+    Importer.Import(FromCat);
+  
+  // Import all of the members of this class.
+  ImportDeclContext(D);
+  
+  // If we have an @implementation, import it as well.
+  if (D->getImplementation()) {
+    ObjCImplementationDecl *Impl
+      = cast<ObjCImplementationDecl>(Importer.Import(D->getImplementation()));
+    if (!Impl)
+      return 0;
+    
+    ToIface->setImplementation(Impl);
+  }
+  
+  return ToIface;
+}
+
+Decl *ASTNodeImporter::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
+  // Import the major distinguishing characteristics of an @property.
+  DeclContext *DC, *LexicalDC;
+  DeclarationName Name;
+  SourceLocation Loc;
+  if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
+    return 0;
+
+  // Check whether we have already imported this property.
+  for (DeclContext::lookup_result Lookup = DC->lookup(Name);
+       Lookup.first != Lookup.second; 
+       ++Lookup.first) {
+    if (ObjCPropertyDecl *FoundProp
+                                = dyn_cast<ObjCPropertyDecl>(*Lookup.first)) {
+      // Check property types.
+      if (!Importer.IsStructurallyEquivalent(D->getType(), 
+                                             FoundProp->getType())) {
+        Importer.ToDiag(Loc, diag::err_odr_objc_property_type_inconsistent)
+          << Name << D->getType() << FoundProp->getType();
+        Importer.ToDiag(FoundProp->getLocation(), diag::note_odr_value_here)
+          << FoundProp->getType();
+        return 0;
+      }
+
+      // FIXME: Check property attributes, getters, setters, etc.?
+
+      // Consider these properties to be equivalent.
+      Importer.Imported(D, FoundProp);
+      return FoundProp;
+    }
+  }
+
+  // Import the type.
+  QualType T = Importer.Import(D->getType());
+  if (T.isNull())
+    return 0;
+
+  // Create the new property.
+  ObjCPropertyDecl *ToProperty
+    = ObjCPropertyDecl::Create(Importer.getToContext(), DC, Loc,
+                               Name.getAsIdentifierInfo(), 
+                               Importer.Import(D->getAtLoc()),
+                               T,
+                               D->getPropertyImplementation());
+  Importer.Imported(D, ToProperty);
+  ToProperty->setLexicalDeclContext(LexicalDC);
+  LexicalDC->addDecl(ToProperty);
+
+  ToProperty->setPropertyAttributes(D->getPropertyAttributes());
+  ToProperty->setGetterName(Importer.Import(D->getGetterName()));
+  ToProperty->setSetterName(Importer.Import(D->getSetterName()));
+  ToProperty->setGetterMethodDecl(
+     cast_or_null<ObjCMethodDecl>(Importer.Import(D->getGetterMethodDecl())));
+  ToProperty->setSetterMethodDecl(
+     cast_or_null<ObjCMethodDecl>(Importer.Import(D->getSetterMethodDecl())));
+  ToProperty->setPropertyIvarDecl(
+       cast_or_null<ObjCIvarDecl>(Importer.Import(D->getPropertyIvarDecl())));
+  return ToProperty;
+}
+
+Decl *
+ASTNodeImporter::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D) {
+  // Import the context of this declaration.
+  DeclContext *DC = Importer.ImportContext(D->getDeclContext());
+  if (!DC)
+    return 0;
+  
+  DeclContext *LexicalDC = DC;
+  if (D->getDeclContext() != D->getLexicalDeclContext()) {
+    LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
+    if (!LexicalDC)
+      return 0;
+  }
+  
+  // Import the location of this declaration.
+  SourceLocation Loc = Importer.Import(D->getLocation());
+  
+  llvm::SmallVector<ObjCProtocolDecl *, 4> Protocols;
+  llvm::SmallVector<SourceLocation, 4> Locations;
+  ObjCForwardProtocolDecl::protocol_loc_iterator FromProtoLoc
+    = D->protocol_loc_begin();
+  for (ObjCForwardProtocolDecl::protocol_iterator FromProto
+         = D->protocol_begin(), FromProtoEnd = D->protocol_end();
+       FromProto != FromProtoEnd; 
+       ++FromProto, ++FromProtoLoc) {
+    ObjCProtocolDecl *ToProto
+      = cast_or_null<ObjCProtocolDecl>(Importer.Import(*FromProto));
+    if (!ToProto)
+      continue;
+    
+    Protocols.push_back(ToProto);
+    Locations.push_back(Importer.Import(*FromProtoLoc));
+  }
+  
+  ObjCForwardProtocolDecl *ToForward
+    = ObjCForwardProtocolDecl::Create(Importer.getToContext(), DC, Loc, 
+                                      Protocols.data(), Protocols.size(),
+                                      Locations.data());
+  ToForward->setLexicalDeclContext(LexicalDC);
+  LexicalDC->addDecl(ToForward);
+  Importer.Imported(D, ToForward);
+  return ToForward;
+}
+
+Decl *ASTNodeImporter::VisitObjCClassDecl(ObjCClassDecl *D) {
+  // Import the context of this declaration.
+  DeclContext *DC = Importer.ImportContext(D->getDeclContext());
+  if (!DC)
+    return 0;
+  
+  DeclContext *LexicalDC = DC;
+  if (D->getDeclContext() != D->getLexicalDeclContext()) {
+    LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
+    if (!LexicalDC)
+      return 0;
+  }
+  
+  // Import the location of this declaration.
+  SourceLocation Loc = Importer.Import(D->getLocation());
+
+  llvm::SmallVector<ObjCInterfaceDecl *, 4> Interfaces;
+  llvm::SmallVector<SourceLocation, 4> Locations;
+  for (ObjCClassDecl::iterator From = D->begin(), FromEnd = D->end();
+       From != FromEnd; ++From) {
+    ObjCInterfaceDecl *ToIface
+      = cast_or_null<ObjCInterfaceDecl>(Importer.Import(From->getInterface()));
+    if (!ToIface)
+      continue;
+    
+    Interfaces.push_back(ToIface);
+    Locations.push_back(Importer.Import(From->getLocation()));
+  }
+  
+  ObjCClassDecl *ToClass = ObjCClassDecl::Create(Importer.getToContext(), DC,
+                                                 Loc, 
+                                                 Interfaces.data(),
+                                                 Locations.data(),
+                                                 Interfaces.size());
+  ToClass->setLexicalDeclContext(LexicalDC);
+  LexicalDC->addDecl(ToClass);
+  Importer.Imported(D, ToClass);
+  return ToClass;
+}
+
+//----------------------------------------------------------------------------
+// Import Statements
+//----------------------------------------------------------------------------
+
+Stmt *ASTNodeImporter::VisitStmt(Stmt *S) {
+  Importer.FromDiag(S->getLocStart(), diag::err_unsupported_ast_node)
+    << S->getStmtClassName();
+  return 0;
+}
+
+//----------------------------------------------------------------------------
+// Import Expressions
+//----------------------------------------------------------------------------
+Expr *ASTNodeImporter::VisitExpr(Expr *E) {
+  Importer.FromDiag(E->getLocStart(), diag::err_unsupported_ast_node)
+    << E->getStmtClassName();
+  return 0;
+}
+
+Expr *ASTNodeImporter::VisitDeclRefExpr(DeclRefExpr *E) {
+  NestedNameSpecifier *Qualifier = 0;
+  if (E->getQualifier()) {
+    Qualifier = Importer.Import(E->getQualifier());
+    if (!E->getQualifier())
+      return 0;
+  }
+  
+  ValueDecl *ToD = cast_or_null<ValueDecl>(Importer.Import(E->getDecl()));
+  if (!ToD)
+    return 0;
+  
+  QualType T = Importer.Import(E->getType());
+  if (T.isNull())
+    return 0;
+  
+  return DeclRefExpr::Create(Importer.getToContext(), Qualifier,
+                             Importer.Import(E->getQualifierRange()),
+                             ToD,
+                             Importer.Import(E->getLocation()),
+                             T,
+                             /*FIXME:TemplateArgs=*/0);
+}
+
+Expr *ASTNodeImporter::VisitIntegerLiteral(IntegerLiteral *E) {
+  QualType T = Importer.Import(E->getType());
+  if (T.isNull())
+    return 0;
+
+  return new (Importer.getToContext()) 
+    IntegerLiteral(E->getValue(), T, Importer.Import(E->getLocation()));
+}
+
+Expr *ASTNodeImporter::VisitCharacterLiteral(CharacterLiteral *E) {
+  QualType T = Importer.Import(E->getType());
+  if (T.isNull())
+    return 0;
+  
+  return new (Importer.getToContext()) CharacterLiteral(E->getValue(), 
+                                                        E->isWide(), T,
+                                          Importer.Import(E->getLocation()));
+}
+
+Expr *ASTNodeImporter::VisitParenExpr(ParenExpr *E) {
+  Expr *SubExpr = Importer.Import(E->getSubExpr());
+  if (!SubExpr)
+    return 0;
+  
+  return new (Importer.getToContext()) 
+                                  ParenExpr(Importer.Import(E->getLParen()),
+                                            Importer.Import(E->getRParen()),
+                                            SubExpr);
+}
+
+Expr *ASTNodeImporter::VisitUnaryOperator(UnaryOperator *E) {
+  QualType T = Importer.Import(E->getType());
+  if (T.isNull())
+    return 0;
+
+  Expr *SubExpr = Importer.Import(E->getSubExpr());
+  if (!SubExpr)
+    return 0;
+  
+  return new (Importer.getToContext()) UnaryOperator(SubExpr, E->getOpcode(),
+                                                     T,
+                                         Importer.Import(E->getOperatorLoc()));                                        
+}
+
+Expr *ASTNodeImporter::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) {
+  QualType ResultType = Importer.Import(E->getType());
+  
+  if (E->isArgumentType()) {
+    TypeSourceInfo *TInfo = Importer.Import(E->getArgumentTypeInfo());
+    if (!TInfo)
+      return 0;
+    
+    return new (Importer.getToContext()) SizeOfAlignOfExpr(E->isSizeOf(),
+                                                           TInfo, ResultType,
+                                           Importer.Import(E->getOperatorLoc()),
+                                           Importer.Import(E->getRParenLoc()));
+  }
+  
+  Expr *SubExpr = Importer.Import(E->getArgumentExpr());
+  if (!SubExpr)
+    return 0;
+  
+  return new (Importer.getToContext()) SizeOfAlignOfExpr(E->isSizeOf(),
+                                                         SubExpr, ResultType,
+                                          Importer.Import(E->getOperatorLoc()),
+                                          Importer.Import(E->getRParenLoc()));
+}
+
+Expr *ASTNodeImporter::VisitBinaryOperator(BinaryOperator *E) {
+  QualType T = Importer.Import(E->getType());
+  if (T.isNull())
+    return 0;
+
+  Expr *LHS = Importer.Import(E->getLHS());
+  if (!LHS)
+    return 0;
+  
+  Expr *RHS = Importer.Import(E->getRHS());
+  if (!RHS)
+    return 0;
+  
+  return new (Importer.getToContext()) BinaryOperator(LHS, RHS, E->getOpcode(),
+                                                      T,
+                                          Importer.Import(E->getOperatorLoc()));
+}
+
+Expr *ASTNodeImporter::VisitCompoundAssignOperator(CompoundAssignOperator *E) {
+  QualType T = Importer.Import(E->getType());
+  if (T.isNull())
+    return 0;
+  
+  QualType CompLHSType = Importer.Import(E->getComputationLHSType());
+  if (CompLHSType.isNull())
+    return 0;
+  
+  QualType CompResultType = Importer.Import(E->getComputationResultType());
+  if (CompResultType.isNull())
+    return 0;
+  
+  Expr *LHS = Importer.Import(E->getLHS());
+  if (!LHS)
+    return 0;
+  
+  Expr *RHS = Importer.Import(E->getRHS());
+  if (!RHS)
+    return 0;
+  
+  return new (Importer.getToContext()) 
+                        CompoundAssignOperator(LHS, RHS, E->getOpcode(),
+                                               T, CompLHSType, CompResultType,
+                                          Importer.Import(E->getOperatorLoc()));
+}
+
+Expr *ASTNodeImporter::VisitImplicitCastExpr(ImplicitCastExpr *E) {
+  QualType T = Importer.Import(E->getType());
+  if (T.isNull())
+    return 0;
+
+  Expr *SubExpr = Importer.Import(E->getSubExpr());
+  if (!SubExpr)
+    return 0;
+  
+  // FIXME: Initialize the base path.
+  assert(E->getBasePath().empty() && "FIXME: Must copy base path!");
+  CXXBaseSpecifierArray BasePath;
+  return new (Importer.getToContext()) ImplicitCastExpr(T, E->getCastKind(),
+                                                        SubExpr, BasePath,
+                                                        E->isLvalueCast());
+}
+
+Expr *ASTNodeImporter::VisitCStyleCastExpr(CStyleCastExpr *E) {
+  QualType T = Importer.Import(E->getType());
+  if (T.isNull())
+    return 0;
+  
+  Expr *SubExpr = Importer.Import(E->getSubExpr());
+  if (!SubExpr)
+    return 0;
+
+  TypeSourceInfo *TInfo = Importer.Import(E->getTypeInfoAsWritten());
+  if (!TInfo && E->getTypeInfoAsWritten())
+    return 0;
+  
+  // FIXME: Initialize the base path.
+  assert(E->getBasePath().empty() && "FIXME: Must copy base path!");
+  CXXBaseSpecifierArray BasePath;
+  return new (Importer.getToContext()) CStyleCastExpr(T, E->getCastKind(),
+                                                      SubExpr, BasePath, TInfo,
+                                            Importer.Import(E->getLParenLoc()),
+                                            Importer.Import(E->getRParenLoc()));
+}
+
+ASTImporter::ASTImporter(Diagnostic &Diags,
+                         ASTContext &ToContext, FileManager &ToFileManager,
+                         ASTContext &FromContext, FileManager &FromFileManager)
+  : ToContext(ToContext), FromContext(FromContext),
+    ToFileManager(ToFileManager), FromFileManager(FromFileManager),
+    Diags(Diags) {
+  ImportedDecls[FromContext.getTranslationUnitDecl()]
+    = ToContext.getTranslationUnitDecl();
+}
+
+ASTImporter::~ASTImporter() { }
+
+QualType ASTImporter::Import(QualType FromT) {
+  if (FromT.isNull())
+    return QualType();
+  
+  // Check whether we've already imported this type.  
+  llvm::DenseMap<Type *, Type *>::iterator Pos
+    = ImportedTypes.find(FromT.getTypePtr());
+  if (Pos != ImportedTypes.end())
+    return ToContext.getQualifiedType(Pos->second, FromT.getQualifiers());
+  
+  // Import the type
+  ASTNodeImporter Importer(*this);
+  QualType ToT = Importer.Visit(FromT.getTypePtr());
+  if (ToT.isNull())
+    return ToT;
+  
+  // Record the imported type.
+  ImportedTypes[FromT.getTypePtr()] = ToT.getTypePtr();
+  
+  return ToContext.getQualifiedType(ToT, FromT.getQualifiers());
+}
+
+TypeSourceInfo *ASTImporter::Import(TypeSourceInfo *FromTSI) {
+  if (!FromTSI)
+    return FromTSI;
+
+  // FIXME: For now we just create a "trivial" type source info based
+  // on the type and a seingle location. Implement a real version of
+  // this.
+  QualType T = Import(FromTSI->getType());
+  if (T.isNull())
+    return 0;
+
+  return ToContext.getTrivialTypeSourceInfo(T, 
+                        FromTSI->getTypeLoc().getFullSourceRange().getBegin());
+}
+
+Decl *ASTImporter::Import(Decl *FromD) {
+  if (!FromD)
+    return 0;
+
+  // Check whether we've already imported this declaration.  
+  llvm::DenseMap<Decl *, Decl *>::iterator Pos = ImportedDecls.find(FromD);
+  if (Pos != ImportedDecls.end())
+    return Pos->second;
+  
+  // Import the type
+  ASTNodeImporter Importer(*this);
+  Decl *ToD = Importer.Visit(FromD);
+  if (!ToD)
+    return 0;
+  
+  // Record the imported declaration.
+  ImportedDecls[FromD] = ToD;
+  
+  if (TagDecl *FromTag = dyn_cast<TagDecl>(FromD)) {
+    // Keep track of anonymous tags that have an associated typedef.
+    if (FromTag->getTypedefForAnonDecl())
+      AnonTagsWithPendingTypedefs.push_back(FromTag);
+  } else if (TypedefDecl *FromTypedef = dyn_cast<TypedefDecl>(FromD)) {
+    // When we've finished transforming a typedef, see whether it was the
+    // typedef for an anonymous tag.
+    for (llvm::SmallVector<TagDecl *, 4>::iterator
+               FromTag = AnonTagsWithPendingTypedefs.begin(), 
+            FromTagEnd = AnonTagsWithPendingTypedefs.end();
+         FromTag != FromTagEnd; ++FromTag) {
+      if ((*FromTag)->getTypedefForAnonDecl() == FromTypedef) {
+        if (TagDecl *ToTag = cast_or_null<TagDecl>(Import(*FromTag))) {
+          // We found the typedef for an anonymous tag; link them.
+          ToTag->setTypedefForAnonDecl(cast<TypedefDecl>(ToD));
+          AnonTagsWithPendingTypedefs.erase(FromTag);
+          break;
+        }
+      }
+    }
+  }
+  
+  return ToD;
+}
+
+DeclContext *ASTImporter::ImportContext(DeclContext *FromDC) {
+  if (!FromDC)
+    return FromDC;
+
+  return cast_or_null<DeclContext>(Import(cast<Decl>(FromDC)));
+}
+
+Expr *ASTImporter::Import(Expr *FromE) {
+  if (!FromE)
+    return 0;
+
+  return cast_or_null<Expr>(Import(cast<Stmt>(FromE)));
+}
+
+Stmt *ASTImporter::Import(Stmt *FromS) {
+  if (!FromS)
+    return 0;
+
+  // Check whether we've already imported this declaration.  
+  llvm::DenseMap<Stmt *, Stmt *>::iterator Pos = ImportedStmts.find(FromS);
+  if (Pos != ImportedStmts.end())
+    return Pos->second;
+  
+  // Import the type
+  ASTNodeImporter Importer(*this);
+  Stmt *ToS = Importer.Visit(FromS);
+  if (!ToS)
+    return 0;
+  
+  // Record the imported declaration.
+  ImportedStmts[FromS] = ToS;
+  return ToS;
+}
+
+NestedNameSpecifier *ASTImporter::Import(NestedNameSpecifier *FromNNS) {
+  if (!FromNNS)
+    return 0;
+
+  // FIXME: Implement!
+  return 0;
+}
+
+SourceLocation ASTImporter::Import(SourceLocation FromLoc) {
+  if (FromLoc.isInvalid())
+    return SourceLocation();
+
+  SourceManager &FromSM = FromContext.getSourceManager();
+  
+  // For now, map everything down to its spelling location, so that we
+  // don't have to import macro instantiations.
+  // FIXME: Import macro instantiations!
+  FromLoc = FromSM.getSpellingLoc(FromLoc);
+  std::pair<FileID, unsigned> Decomposed = FromSM.getDecomposedLoc(FromLoc);
+  SourceManager &ToSM = ToContext.getSourceManager();
+  return ToSM.getLocForStartOfFile(Import(Decomposed.first))
+             .getFileLocWithOffset(Decomposed.second);
+}
+
+SourceRange ASTImporter::Import(SourceRange FromRange) {
+  return SourceRange(Import(FromRange.getBegin()), Import(FromRange.getEnd()));
+}
+
+FileID ASTImporter::Import(FileID FromID) {
+  llvm::DenseMap<unsigned, FileID>::iterator Pos
+    = ImportedFileIDs.find(FromID.getHashValue());
+  if (Pos != ImportedFileIDs.end())
+    return Pos->second;
+  
+  SourceManager &FromSM = FromContext.getSourceManager();
+  SourceManager &ToSM = ToContext.getSourceManager();
+  const SrcMgr::SLocEntry &FromSLoc = FromSM.getSLocEntry(FromID);
+  assert(FromSLoc.isFile() && "Cannot handle macro instantiations yet");
+  
+  // Include location of this file.
+  SourceLocation ToIncludeLoc = Import(FromSLoc.getFile().getIncludeLoc());
+  
+  // Map the FileID for to the "to" source manager.
+  FileID ToID;
+  const SrcMgr::ContentCache *Cache = FromSLoc.getFile().getContentCache();
+  if (Cache->Entry) {
+    // FIXME: We probably want to use getVirtualFile(), so we don't hit the
+    // disk again
+    // FIXME: We definitely want to re-use the existing MemoryBuffer, rather
+    // than mmap the files several times.
+    const FileEntry *Entry = ToFileManager.getFile(Cache->Entry->getName());
+    ToID = ToSM.createFileID(Entry, ToIncludeLoc, 
+                             FromSLoc.getFile().getFileCharacteristic());
+  } else {
+    // FIXME: We want to re-use the existing MemoryBuffer!
+    const llvm::MemoryBuffer *FromBuf = Cache->getBuffer(getDiags(), FromSM);
+    llvm::MemoryBuffer *ToBuf
+      = llvm::MemoryBuffer::getMemBufferCopy(FromBuf->getBuffer(),
+                                             FromBuf->getBufferIdentifier());
+    ToID = ToSM.createFileIDForMemBuffer(ToBuf);
+  }
+  
+  
+  ImportedFileIDs[FromID.getHashValue()] = ToID;
+  return ToID;
+}
+
+DeclarationName ASTImporter::Import(DeclarationName FromName) {
+  if (!FromName)
+    return DeclarationName();
+
+  switch (FromName.getNameKind()) {
+  case DeclarationName::Identifier:
+    return Import(FromName.getAsIdentifierInfo());
+
+  case DeclarationName::ObjCZeroArgSelector:
+  case DeclarationName::ObjCOneArgSelector:
+  case DeclarationName::ObjCMultiArgSelector:
+    return Import(FromName.getObjCSelector());
+
+  case DeclarationName::CXXConstructorName: {
+    QualType T = Import(FromName.getCXXNameType());
+    if (T.isNull())
+      return DeclarationName();
+
+    return ToContext.DeclarationNames.getCXXConstructorName(
+                                               ToContext.getCanonicalType(T));
+  }
+
+  case DeclarationName::CXXDestructorName: {
+    QualType T = Import(FromName.getCXXNameType());
+    if (T.isNull())
+      return DeclarationName();
+
+    return ToContext.DeclarationNames.getCXXDestructorName(
+                                               ToContext.getCanonicalType(T));
+  }
+
+  case DeclarationName::CXXConversionFunctionName: {
+    QualType T = Import(FromName.getCXXNameType());
+    if (T.isNull())
+      return DeclarationName();
+
+    return ToContext.DeclarationNames.getCXXConversionFunctionName(
+                                               ToContext.getCanonicalType(T));
+  }
+
+  case DeclarationName::CXXOperatorName:
+    return ToContext.DeclarationNames.getCXXOperatorName(
+                                          FromName.getCXXOverloadedOperator());
+
+  case DeclarationName::CXXLiteralOperatorName:
+    return ToContext.DeclarationNames.getCXXLiteralOperatorName(
+                                   Import(FromName.getCXXLiteralIdentifier()));
+
+  case DeclarationName::CXXUsingDirective:
+    // FIXME: STATICS!
+    return DeclarationName::getUsingDirectiveName();
+  }
+
+  // Silence bogus GCC warning
+  return DeclarationName();
+}
+
+IdentifierInfo *ASTImporter::Import(IdentifierInfo *FromId) {
+  if (!FromId)
+    return 0;
+
+  return &ToContext.Idents.get(FromId->getName());
+}
+
+Selector ASTImporter::Import(Selector FromSel) {
+  if (FromSel.isNull())
+    return Selector();
+
+  llvm::SmallVector<IdentifierInfo *, 4> Idents;
+  Idents.push_back(Import(FromSel.getIdentifierInfoForSlot(0)));
+  for (unsigned I = 1, N = FromSel.getNumArgs(); I < N; ++I)
+    Idents.push_back(Import(FromSel.getIdentifierInfoForSlot(I)));
+  return ToContext.Selectors.getSelector(FromSel.getNumArgs(), Idents.data());
+}
+
+DeclarationName ASTImporter::HandleNameConflict(DeclarationName Name,
+                                                DeclContext *DC,
+                                                unsigned IDNS,
+                                                NamedDecl **Decls,
+                                                unsigned NumDecls) {
+  return Name;
+}
+
+DiagnosticBuilder ASTImporter::ToDiag(SourceLocation Loc, unsigned DiagID) {
+  return Diags.Report(FullSourceLoc(Loc, ToContext.getSourceManager()), 
+                      DiagID);
+}
+
+DiagnosticBuilder ASTImporter::FromDiag(SourceLocation Loc, unsigned DiagID) {
+  return Diags.Report(FullSourceLoc(Loc, FromContext.getSourceManager()), 
+                      DiagID);
+}
+
+Decl *ASTImporter::Imported(Decl *From, Decl *To) {
+  ImportedDecls[From] = To;
+  return To;
+}
+
+bool ASTImporter::IsStructurallyEquivalent(QualType From, QualType To) {
+  llvm::DenseMap<Type *, Type *>::iterator Pos
+   = ImportedTypes.find(From.getTypePtr());
+  if (Pos != ImportedTypes.end() && ToContext.hasSameType(Import(From), To))
+    return true;
+      
+  StructuralEquivalenceContext Ctx(FromContext, ToContext, Diags, 
+                                   NonEquivalentDecls);
+  return Ctx.IsStructurallyEquivalent(From, To);
+}
diff --git a/lib/AST/Android.mk b/lib/AST/Android.mk
new file mode 100644
index 0000000..68f8f3c
--- /dev/null
+++ b/lib/AST/Android.mk
@@ -0,0 +1,56 @@
+LOCAL_PATH:= $(call my-dir)
+
+# For the host only
+# =====================================================
+include $(CLEAR_VARS)
+include $(CLEAR_TBLGEN_VARS)
+
+TBLGEN_TABLES :=    \
+	DiagnosticASTKinds.inc	\
+    DiagnosticCommonKinds.inc 
+
+clang_ast_SRC_FILES :=	\
+	APValue.cpp	\
+	ASTConsumer.cpp	\
+	ASTContext.cpp	\
+	ASTDiagnostic.cpp	\
+	ASTImporter.cpp	\
+	AttrImpl.cpp	\
+	CXXInheritance.cpp	\
+	Decl.cpp	\
+	DeclBase.cpp	\
+	DeclCXX.cpp	\
+	DeclFriend.cpp	\
+	DeclGroup.cpp	\
+	DeclObjC.cpp	\
+	DeclPrinter.cpp	\
+	DeclTemplate.cpp	\
+	DeclarationName.cpp	\
+	Expr.cpp	\
+	ExprCXX.cpp	\
+	ExprConstant.cpp	\
+	FullExpr.cpp	\
+	InheritViz.cpp	\
+	NestedNameSpecifier.cpp	\
+	ParentMap.cpp	\
+	RecordLayout.cpp	\
+	RecordLayoutBuilder.cpp	\
+	Stmt.cpp	\
+	StmtDumper.cpp	\
+	StmtIterator.cpp	\
+	StmtPrinter.cpp	\
+	StmtProfile.cpp	\
+	StmtViz.cpp	\
+	TemplateBase.cpp	\
+	TemplateName.cpp	\
+	Type.cpp	\
+	TypeLoc.cpp	\
+	TypePrinter.cpp
+
+LOCAL_SRC_FILES := $(clang_ast_SRC_FILES)
+
+LOCAL_MODULE:= libclangAST
+
+include $(CLANG_HOST_BUILD_MK)
+include $(CLANG_TBLGEN_RULES_MK)
+include $(BUILD_HOST_STATIC_LIBRARY)
diff --git a/lib/AST/AttrImpl.cpp b/lib/AST/AttrImpl.cpp
new file mode 100644
index 0000000..423aa06
--- /dev/null
+++ b/lib/AST/AttrImpl.cpp
@@ -0,0 +1,199 @@
+//===--- AttrImpl.cpp - Classes for representing attributes -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file contains out-of-line virtual methods for Attr classes.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/Attr.h"
+#include "clang/AST/ASTContext.h"
+using namespace clang;
+
+void Attr::Destroy(ASTContext &C) {
+  if (Next) {
+    Next->Destroy(C);
+    Next = 0;
+  }
+  this->~Attr();
+  C.Deallocate((void*)this);
+}
+
+AttrWithString::AttrWithString(Attr::Kind AK, ASTContext &C, llvm::StringRef s)
+  : Attr(AK) {
+  assert(!s.empty());
+  StrLen = s.size();
+  Str = new (C) char[StrLen];
+  memcpy(const_cast<char*>(Str), s.data(), StrLen);
+}
+
+void AttrWithString::Destroy(ASTContext &C) {
+  C.Deallocate(const_cast<char*>(Str));  
+  Attr::Destroy(C);
+}
+
+void AttrWithString::ReplaceString(ASTContext &C, llvm::StringRef newS) {
+  if (newS.size() > StrLen) {
+    C.Deallocate(const_cast<char*>(Str));
+    Str = new (C) char[newS.size()];
+  }
+  StrLen = newS.size();
+  memcpy(const_cast<char*>(Str), newS.data(), StrLen);
+}
+
+void FormatAttr::setType(ASTContext &C, llvm::StringRef type) {
+  ReplaceString(C, type);
+}
+
+NonNullAttr::NonNullAttr(ASTContext &C, unsigned* arg_nums, unsigned size)
+  : Attr(NonNull), ArgNums(0), Size(0) {  
+  if (size == 0)
+    return;
+  assert(arg_nums);
+  ArgNums = new (C) unsigned[size];
+  Size = size;
+  memcpy(ArgNums, arg_nums, sizeof(*ArgNums)*size);
+}
+
+void NonNullAttr::Destroy(ASTContext &C) {
+  if (ArgNums)
+    C.Deallocate(ArgNums);
+  Attr::Destroy(C);
+}
+
+#define DEF_SIMPLE_ATTR_CLONE(ATTR)                                     \
+  Attr *ATTR##Attr::clone(ASTContext &C) const {                        \
+    return ::new (C) ATTR##Attr;                                        \
+  }
+
+// FIXME: Can we use variadic macro to define DEF_SIMPLE_ATTR_CLONE for
+// "non-simple" classes?
+
+DEF_SIMPLE_ATTR_CLONE(AlwaysInline)
+DEF_SIMPLE_ATTR_CLONE(AnalyzerNoReturn)
+DEF_SIMPLE_ATTR_CLONE(BaseCheck)
+DEF_SIMPLE_ATTR_CLONE(CDecl)
+DEF_SIMPLE_ATTR_CLONE(CFReturnsNotRetained)
+DEF_SIMPLE_ATTR_CLONE(CFReturnsRetained)
+DEF_SIMPLE_ATTR_CLONE(Const)
+DEF_SIMPLE_ATTR_CLONE(DLLExport)
+DEF_SIMPLE_ATTR_CLONE(DLLImport)
+DEF_SIMPLE_ATTR_CLONE(Deprecated)
+DEF_SIMPLE_ATTR_CLONE(FastCall)
+DEF_SIMPLE_ATTR_CLONE(Final)
+DEF_SIMPLE_ATTR_CLONE(Hiding)
+DEF_SIMPLE_ATTR_CLONE(Malloc)
+DEF_SIMPLE_ATTR_CLONE(NSReturnsNotRetained)
+DEF_SIMPLE_ATTR_CLONE(NSReturnsRetained)
+DEF_SIMPLE_ATTR_CLONE(NoDebug)
+DEF_SIMPLE_ATTR_CLONE(NoInline)
+DEF_SIMPLE_ATTR_CLONE(NoReturn)
+DEF_SIMPLE_ATTR_CLONE(NoThrow)
+DEF_SIMPLE_ATTR_CLONE(ObjCException)
+DEF_SIMPLE_ATTR_CLONE(ObjCNSObject)
+DEF_SIMPLE_ATTR_CLONE(Override)
+DEF_SIMPLE_ATTR_CLONE(Packed)
+DEF_SIMPLE_ATTR_CLONE(Pure)
+DEF_SIMPLE_ATTR_CLONE(StdCall)
+DEF_SIMPLE_ATTR_CLONE(TransparentUnion)
+DEF_SIMPLE_ATTR_CLONE(Unavailable)
+DEF_SIMPLE_ATTR_CLONE(Unused)
+DEF_SIMPLE_ATTR_CLONE(Used)
+DEF_SIMPLE_ATTR_CLONE(WarnUnusedResult)
+DEF_SIMPLE_ATTR_CLONE(Weak)
+DEF_SIMPLE_ATTR_CLONE(WeakImport)
+DEF_SIMPLE_ATTR_CLONE(WeakRef)
+DEF_SIMPLE_ATTR_CLONE(X86ForceAlignArgPointer)
+
+Attr* PragmaPackAttr::clone(ASTContext &C) const {
+  return ::new (C) PragmaPackAttr(Alignment);
+}
+
+Attr* AlignedAttr::clone(ASTContext &C) const {
+  return ::new (C) AlignedAttr(Alignment);
+}
+
+Attr* AnnotateAttr::clone(ASTContext &C) const {
+  return ::new (C) AnnotateAttr(C, getAnnotation());
+}
+
+Attr *AsmLabelAttr::clone(ASTContext &C) const {
+  return ::new (C) AsmLabelAttr(C, getLabel());
+}
+
+Attr *AliasAttr::clone(ASTContext &C) const {
+  return ::new (C) AliasAttr(C, getAliasee());
+}
+
+Attr *ConstructorAttr::clone(ASTContext &C) const {
+  return ::new (C) ConstructorAttr(priority);
+}
+
+Attr *DestructorAttr::clone(ASTContext &C) const {
+  return ::new (C) DestructorAttr(priority);
+}
+
+Attr *IBOutletAttr::clone(ASTContext &C) const {
+  return ::new (C) IBOutletAttr;
+}
+
+Attr *IBActionAttr::clone(ASTContext &C) const {
+  return ::new (C) IBActionAttr;
+}
+
+Attr *GNUInlineAttr::clone(ASTContext &C) const {
+  return ::new (C) GNUInlineAttr;
+}
+
+Attr *SectionAttr::clone(ASTContext &C) const {
+  return ::new (C) SectionAttr(C, getName());
+}
+
+Attr *NonNullAttr::clone(ASTContext &C) const {
+  return ::new (C) NonNullAttr(C, ArgNums, Size);
+}
+
+Attr *FormatAttr::clone(ASTContext &C) const {
+  return ::new (C) FormatAttr(C, getType(), formatIdx, firstArg);
+}
+
+Attr *FormatArgAttr::clone(ASTContext &C) const {
+  return ::new (C) FormatArgAttr(formatIdx);
+}
+
+Attr *SentinelAttr::clone(ASTContext &C) const {
+  return ::new (C) SentinelAttr(sentinel, NullPos);
+}
+
+Attr *VisibilityAttr::clone(ASTContext &C) const {
+  return ::new (C) VisibilityAttr(VisibilityType);
+}
+
+Attr *OverloadableAttr::clone(ASTContext &C) const {
+  return ::new (C) OverloadableAttr;
+}
+
+Attr *BlocksAttr::clone(ASTContext &C) const {
+  return ::new (C) BlocksAttr(BlocksAttrType);
+}
+
+Attr *CleanupAttr::clone(ASTContext &C) const {
+  return ::new (C) CleanupAttr(FD);
+}
+
+Attr *RegparmAttr::clone(ASTContext &C) const {
+  return ::new (C) RegparmAttr(NumParams);
+}
+
+Attr *ReqdWorkGroupSizeAttr::clone(ASTContext &C) const {
+  return ::new (C) ReqdWorkGroupSizeAttr(X, Y, Z);
+}
+
+Attr *MSP430InterruptAttr::clone(ASTContext &C) const {
+  return ::new (C) MSP430InterruptAttr(Number);
+}
diff --git a/lib/AST/CMakeLists.txt b/lib/AST/CMakeLists.txt
new file mode 100644
index 0000000..91aaddc
--- /dev/null
+++ b/lib/AST/CMakeLists.txt
@@ -0,0 +1,42 @@
+set(LLVM_NO_RTTI 1)
+
+add_clang_library(clangAST
+  APValue.cpp
+  ASTConsumer.cpp
+  ASTContext.cpp
+  ASTDiagnostic.cpp
+  ASTImporter.cpp
+  AttrImpl.cpp
+  CXXInheritance.cpp
+  Decl.cpp
+  DeclarationName.cpp
+  DeclBase.cpp
+  DeclCXX.cpp
+  DeclFriend.cpp
+  DeclGroup.cpp
+  DeclObjC.cpp
+  DeclPrinter.cpp
+  DeclTemplate.cpp
+  Expr.cpp
+  ExprConstant.cpp
+  ExprCXX.cpp
+  FullExpr.cpp
+  InheritViz.cpp
+  NestedNameSpecifier.cpp
+  ParentMap.cpp
+  RecordLayout.cpp
+  RecordLayoutBuilder.cpp
+  Stmt.cpp
+  StmtDumper.cpp
+  StmtIterator.cpp
+  StmtPrinter.cpp
+  StmtProfile.cpp
+  StmtViz.cpp
+  TemplateBase.cpp
+  TemplateName.cpp
+  Type.cpp
+  TypeLoc.cpp
+  TypePrinter.cpp
+  )
+
+add_dependencies(clangAST ClangDiagnosticAST)
diff --git a/lib/AST/CXXInheritance.cpp b/lib/AST/CXXInheritance.cpp
new file mode 100644
index 0000000..a9f2230
--- /dev/null
+++ b/lib/AST/CXXInheritance.cpp
@@ -0,0 +1,655 @@
+//===------ CXXInheritance.cpp - C++ Inheritance ----------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides routines that help analyzing C++ inheritance hierarchies.
+//
+//===----------------------------------------------------------------------===//
+#include "clang/AST/CXXInheritance.h"
+#include "clang/AST/DeclCXX.h"
+#include <algorithm>
+#include <set>
+
+using namespace clang;
+
+/// \brief Computes the set of declarations referenced by these base
+/// paths.
+void CXXBasePaths::ComputeDeclsFound() {
+  assert(NumDeclsFound == 0 && !DeclsFound &&
+         "Already computed the set of declarations");
+  
+  std::set<NamedDecl *> Decls;
+  for (CXXBasePaths::paths_iterator Path = begin(), PathEnd = end();
+       Path != PathEnd; ++Path)
+    Decls.insert(*Path->Decls.first);
+  
+  NumDeclsFound = Decls.size();
+  DeclsFound = new NamedDecl * [NumDeclsFound];
+  std::copy(Decls.begin(), Decls.end(), DeclsFound);
+}
+
+CXXBasePaths::decl_iterator CXXBasePaths::found_decls_begin() {
+  if (NumDeclsFound == 0)
+    ComputeDeclsFound();
+  return DeclsFound;
+}
+
+CXXBasePaths::decl_iterator CXXBasePaths::found_decls_end() {
+  if (NumDeclsFound == 0)
+    ComputeDeclsFound();
+  return DeclsFound + NumDeclsFound;
+}
+
+/// isAmbiguous - Determines whether the set of paths provided is
+/// ambiguous, i.e., there are two or more paths that refer to
+/// different base class subobjects of the same type. BaseType must be
+/// an unqualified, canonical class type.
+bool CXXBasePaths::isAmbiguous(QualType BaseType) {
+  assert(BaseType.isCanonical() && "Base type must be the canonical type");
+  assert(BaseType.hasQualifiers() == 0 && "Base type must be unqualified");
+  std::pair<bool, unsigned>& Subobjects = ClassSubobjects[BaseType];
+  return Subobjects.second + (Subobjects.first? 1 : 0) > 1;
+}
+
+/// clear - Clear out all prior path information.
+void CXXBasePaths::clear() {
+  Paths.clear();
+  ClassSubobjects.clear();
+  ScratchPath.clear();
+  DetectedVirtual = 0;
+}
+
+/// @brief Swaps the contents of this CXXBasePaths structure with the
+/// contents of Other.
+void CXXBasePaths::swap(CXXBasePaths &Other) {
+  std::swap(Origin, Other.Origin);
+  Paths.swap(Other.Paths);
+  ClassSubobjects.swap(Other.ClassSubobjects);
+  std::swap(FindAmbiguities, Other.FindAmbiguities);
+  std::swap(RecordPaths, Other.RecordPaths);
+  std::swap(DetectVirtual, Other.DetectVirtual);
+  std::swap(DetectedVirtual, Other.DetectedVirtual);
+}
+
+bool CXXRecordDecl::isDerivedFrom(CXXRecordDecl *Base) const {
+  CXXBasePaths Paths(/*FindAmbiguities=*/false, /*RecordPaths=*/false,
+                     /*DetectVirtual=*/false);
+  return isDerivedFrom(Base, Paths);
+}
+
+bool CXXRecordDecl::isDerivedFrom(CXXRecordDecl *Base, CXXBasePaths &Paths) const {
+  if (getCanonicalDecl() == Base->getCanonicalDecl())
+    return false;
+  
+  Paths.setOrigin(const_cast<CXXRecordDecl*>(this));
+  return lookupInBases(&FindBaseClass, Base->getCanonicalDecl(), Paths);
+}
+
+bool CXXRecordDecl::isVirtuallyDerivedFrom(CXXRecordDecl *Base) const {
+  CXXBasePaths Paths(/*FindAmbiguities=*/false, /*RecordPaths=*/false,
+                     /*DetectVirtual=*/false);
+
+  if (getCanonicalDecl() == Base->getCanonicalDecl())
+    return false;
+  
+  Paths.setOrigin(const_cast<CXXRecordDecl*>(this));  
+  return lookupInBases(&FindVirtualBaseClass, Base->getCanonicalDecl(), Paths);
+}
+
+static bool BaseIsNot(const CXXRecordDecl *Base, void *OpaqueTarget) {
+  // OpaqueTarget is a CXXRecordDecl*.
+  return Base->getCanonicalDecl() != (const CXXRecordDecl*) OpaqueTarget;
+}
+
+bool CXXRecordDecl::isProvablyNotDerivedFrom(const CXXRecordDecl *Base) const {
+  return forallBases(BaseIsNot, (void*) Base->getCanonicalDecl());
+}
+
+bool CXXRecordDecl::forallBases(ForallBasesCallback *BaseMatches,
+                                void *OpaqueData,
+                                bool AllowShortCircuit) const {
+  llvm::SmallVector<const CXXRecordDecl*, 8> Queue;
+
+  const CXXRecordDecl *Record = this;
+  bool AllMatches = true;
+  while (true) {
+    for (CXXRecordDecl::base_class_const_iterator
+           I = Record->bases_begin(), E = Record->bases_end(); I != E; ++I) {
+      const RecordType *Ty = I->getType()->getAs<RecordType>();
+      if (!Ty) {
+        if (AllowShortCircuit) return false;
+        AllMatches = false;
+        continue;
+      }
+
+      CXXRecordDecl *Base = 
+            cast_or_null<CXXRecordDecl>(Ty->getDecl()->getDefinition());
+      if (!Base) {
+        if (AllowShortCircuit) return false;
+        AllMatches = false;
+        continue;
+      }
+      
+      Queue.push_back(Base);
+      if (!BaseMatches(Base, OpaqueData)) {
+        if (AllowShortCircuit) return false;
+        AllMatches = false;
+        continue;
+      }
+    }
+
+    if (Queue.empty()) break;
+    Record = Queue.back(); // not actually a queue.
+    Queue.pop_back();
+  }
+
+  return AllMatches;
+}
+
+bool CXXBasePaths::lookupInBases(ASTContext &Context, 
+                                 const CXXRecordDecl *Record,
+                               CXXRecordDecl::BaseMatchesCallback *BaseMatches, 
+                                 void *UserData) {
+  bool FoundPath = false;
+
+  // The access of the path down to this record.
+  AccessSpecifier AccessToHere = ScratchPath.Access;
+  bool IsFirstStep = ScratchPath.empty();
+
+  for (CXXRecordDecl::base_class_const_iterator BaseSpec = Record->bases_begin(),
+         BaseSpecEnd = Record->bases_end(); 
+       BaseSpec != BaseSpecEnd; 
+       ++BaseSpec) {
+    // Find the record of the base class subobjects for this type.
+    QualType BaseType = Context.getCanonicalType(BaseSpec->getType())
+                                                          .getUnqualifiedType();
+    
+    // C++ [temp.dep]p3:
+    //   In the definition of a class template or a member of a class template,
+    //   if a base class of the class template depends on a template-parameter,
+    //   the base class scope is not examined during unqualified name lookup 
+    //   either at the point of definition of the class template or member or 
+    //   during an instantiation of the class tem- plate or member.
+    if (BaseType->isDependentType())
+      continue;
+    
+    // Determine whether we need to visit this base class at all,
+    // updating the count of subobjects appropriately.
+    std::pair<bool, unsigned>& Subobjects = ClassSubobjects[BaseType];
+    bool VisitBase = true;
+    bool SetVirtual = false;
+    if (BaseSpec->isVirtual()) {
+      VisitBase = !Subobjects.first;
+      Subobjects.first = true;
+      if (isDetectingVirtual() && DetectedVirtual == 0) {
+        // If this is the first virtual we find, remember it. If it turns out
+        // there is no base path here, we'll reset it later.
+        DetectedVirtual = BaseType->getAs<RecordType>();
+        SetVirtual = true;
+      }
+    } else
+      ++Subobjects.second;
+    
+    if (isRecordingPaths()) {
+      // Add this base specifier to the current path.
+      CXXBasePathElement Element;
+      Element.Base = &*BaseSpec;
+      Element.Class = Record;
+      if (BaseSpec->isVirtual())
+        Element.SubobjectNumber = 0;
+      else
+        Element.SubobjectNumber = Subobjects.second;
+      ScratchPath.push_back(Element);
+
+      // Calculate the "top-down" access to this base class.
+      // The spec actually describes this bottom-up, but top-down is
+      // equivalent because the definition works out as follows:
+      // 1. Write down the access along each step in the inheritance
+      //    chain, followed by the access of the decl itself.
+      //    For example, in
+      //      class A { public: int foo; };
+      //      class B : protected A {};
+      //      class C : public B {};
+      //      class D : private C {};
+      //    we would write:
+      //      private public protected public
+      // 2. If 'private' appears anywhere except far-left, access is denied.
+      // 3. Otherwise, overall access is determined by the most restrictive
+      //    access in the sequence.
+      if (IsFirstStep)
+        ScratchPath.Access = BaseSpec->getAccessSpecifier();
+      else
+        ScratchPath.Access = CXXRecordDecl::MergeAccess(AccessToHere, 
+                                                 BaseSpec->getAccessSpecifier());
+    }
+    
+    // Track whether there's a path involving this specific base.
+    bool FoundPathThroughBase = false;
+    
+    if (BaseMatches(BaseSpec, ScratchPath, UserData)) {
+      // We've found a path that terminates at this base.
+      FoundPath = FoundPathThroughBase = true;
+      if (isRecordingPaths()) {
+        // We have a path. Make a copy of it before moving on.
+        Paths.push_back(ScratchPath);
+      } else if (!isFindingAmbiguities()) {
+        // We found a path and we don't care about ambiguities;
+        // return immediately.
+        return FoundPath;
+      }
+    } else if (VisitBase) {
+      CXXRecordDecl *BaseRecord
+        = cast<CXXRecordDecl>(BaseSpec->getType()->getAs<RecordType>()
+                                ->getDecl());
+      if (lookupInBases(Context, BaseRecord, BaseMatches, UserData)) {
+        // C++ [class.member.lookup]p2:
+        //   A member name f in one sub-object B hides a member name f in
+        //   a sub-object A if A is a base class sub-object of B. Any
+        //   declarations that are so hidden are eliminated from
+        //   consideration.
+        
+        // There is a path to a base class that meets the criteria. If we're 
+        // not collecting paths or finding ambiguities, we're done.
+        FoundPath = FoundPathThroughBase = true;
+        if (!isFindingAmbiguities())
+          return FoundPath;
+      }
+    }
+    
+    // Pop this base specifier off the current path (if we're
+    // collecting paths).
+    if (isRecordingPaths()) {
+      ScratchPath.pop_back();
+    }
+
+    // If we set a virtual earlier, and this isn't a path, forget it again.
+    if (SetVirtual && !FoundPathThroughBase) {
+      DetectedVirtual = 0;
+    }
+  }
+
+  // Reset the scratch path access.
+  ScratchPath.Access = AccessToHere;
+  
+  return FoundPath;
+}
+
+bool CXXRecordDecl::lookupInBases(BaseMatchesCallback *BaseMatches,
+                                  void *UserData,
+                                  CXXBasePaths &Paths) const {
+  // If we didn't find anything, report that.
+  if (!Paths.lookupInBases(getASTContext(), this, BaseMatches, UserData))
+    return false;
+
+  // If we're not recording paths or we won't ever find ambiguities,
+  // we're done.
+  if (!Paths.isRecordingPaths() || !Paths.isFindingAmbiguities())
+    return true;
+  
+  // C++ [class.member.lookup]p6:
+  //   When virtual base classes are used, a hidden declaration can be
+  //   reached along a path through the sub-object lattice that does
+  //   not pass through the hiding declaration. This is not an
+  //   ambiguity. The identical use with nonvirtual base classes is an
+  //   ambiguity; in that case there is no unique instance of the name
+  //   that hides all the others.
+  //
+  // FIXME: This is an O(N^2) algorithm, but DPG doesn't see an easy
+  // way to make it any faster.
+  for (CXXBasePaths::paths_iterator P = Paths.begin(), PEnd = Paths.end();
+       P != PEnd; /* increment in loop */) {
+    bool Hidden = false;
+
+    for (CXXBasePath::iterator PE = P->begin(), PEEnd = P->end();
+         PE != PEEnd && !Hidden; ++PE) {
+      if (PE->Base->isVirtual()) {
+        CXXRecordDecl *VBase = 0;
+        if (const RecordType *Record = PE->Base->getType()->getAs<RecordType>())
+          VBase = cast<CXXRecordDecl>(Record->getDecl());
+        if (!VBase)
+          break;
+
+        // The declaration(s) we found along this path were found in a
+        // subobject of a virtual base. Check whether this virtual
+        // base is a subobject of any other path; if so, then the
+        // declaration in this path are hidden by that patch.
+        for (CXXBasePaths::paths_iterator HidingP = Paths.begin(),
+                                       HidingPEnd = Paths.end();
+             HidingP != HidingPEnd;
+             ++HidingP) {
+          CXXRecordDecl *HidingClass = 0;
+          if (const RecordType *Record
+                       = HidingP->back().Base->getType()->getAs<RecordType>())
+            HidingClass = cast<CXXRecordDecl>(Record->getDecl());
+          if (!HidingClass)
+            break;
+
+          if (HidingClass->isVirtuallyDerivedFrom(VBase)) {
+            Hidden = true;
+            break;
+          }
+        }
+      }
+    }
+
+    if (Hidden)
+      P = Paths.Paths.erase(P);
+    else
+      ++P;
+  }
+  
+  return true;
+}
+
+bool CXXRecordDecl::FindBaseClass(const CXXBaseSpecifier *Specifier, 
+                                  CXXBasePath &Path,
+                                  void *BaseRecord) {
+  assert(((Decl *)BaseRecord)->getCanonicalDecl() == BaseRecord &&
+         "User data for FindBaseClass is not canonical!");
+  return Specifier->getType()->getAs<RecordType>()->getDecl()
+           ->getCanonicalDecl() == BaseRecord;
+}
+
+bool CXXRecordDecl::FindVirtualBaseClass(const CXXBaseSpecifier *Specifier, 
+                                         CXXBasePath &Path,
+                                         void *BaseRecord) {
+  assert(((Decl *)BaseRecord)->getCanonicalDecl() == BaseRecord &&
+         "User data for FindBaseClass is not canonical!");
+  return Specifier->isVirtual() &&
+         Specifier->getType()->getAs<RecordType>()->getDecl()
+           ->getCanonicalDecl() == BaseRecord;
+}
+
+bool CXXRecordDecl::FindTagMember(const CXXBaseSpecifier *Specifier, 
+                                  CXXBasePath &Path,
+                                  void *Name) {
+  RecordDecl *BaseRecord = Specifier->getType()->getAs<RecordType>()->getDecl();
+
+  DeclarationName N = DeclarationName::getFromOpaquePtr(Name);
+  for (Path.Decls = BaseRecord->lookup(N);
+       Path.Decls.first != Path.Decls.second;
+       ++Path.Decls.first) {
+    if ((*Path.Decls.first)->isInIdentifierNamespace(IDNS_Tag))
+      return true;
+  }
+
+  return false;
+}
+
+bool CXXRecordDecl::FindOrdinaryMember(const CXXBaseSpecifier *Specifier, 
+                                       CXXBasePath &Path,
+                                       void *Name) {
+  RecordDecl *BaseRecord = Specifier->getType()->getAs<RecordType>()->getDecl();
+  
+  const unsigned IDNS = IDNS_Ordinary | IDNS_Tag | IDNS_Member;
+  DeclarationName N = DeclarationName::getFromOpaquePtr(Name);
+  for (Path.Decls = BaseRecord->lookup(N);
+       Path.Decls.first != Path.Decls.second;
+       ++Path.Decls.first) {
+    if ((*Path.Decls.first)->isInIdentifierNamespace(IDNS))
+      return true;
+  }
+  
+  return false;
+}
+
+bool CXXRecordDecl::
+FindNestedNameSpecifierMember(const CXXBaseSpecifier *Specifier, 
+                              CXXBasePath &Path,
+                              void *Name) {
+  RecordDecl *BaseRecord = Specifier->getType()->getAs<RecordType>()->getDecl();
+  
+  DeclarationName N = DeclarationName::getFromOpaquePtr(Name);
+  for (Path.Decls = BaseRecord->lookup(N);
+       Path.Decls.first != Path.Decls.second;
+       ++Path.Decls.first) {
+    // FIXME: Refactor the "is it a nested-name-specifier?" check
+    if (isa<TypedefDecl>(*Path.Decls.first) ||
+        (*Path.Decls.first)->isInIdentifierNamespace(IDNS_Tag))
+      return true;
+  }
+  
+  return false;
+}
+
+void OverridingMethods::add(unsigned OverriddenSubobject, 
+                            UniqueVirtualMethod Overriding) {
+  llvm::SmallVector<UniqueVirtualMethod, 4> &SubobjectOverrides
+    = Overrides[OverriddenSubobject];
+  if (std::find(SubobjectOverrides.begin(), SubobjectOverrides.end(), 
+                Overriding) == SubobjectOverrides.end())
+    SubobjectOverrides.push_back(Overriding);
+}
+
+void OverridingMethods::add(const OverridingMethods &Other) {
+  for (const_iterator I = Other.begin(), IE = Other.end(); I != IE; ++I) {
+    for (overriding_const_iterator M = I->second.begin(), 
+                                MEnd = I->second.end();
+         M != MEnd; 
+         ++M)
+      add(I->first, *M);
+  }
+}
+
+void OverridingMethods::replaceAll(UniqueVirtualMethod Overriding) {
+  for (iterator I = begin(), IEnd = end(); I != IEnd; ++I) {
+    I->second.clear();
+    I->second.push_back(Overriding);
+  }
+}
+
+
+namespace {
+  class FinalOverriderCollector {
+    /// \brief The number of subobjects of a given class type that
+    /// occur within the class hierarchy.
+    llvm::DenseMap<const CXXRecordDecl *, unsigned> SubobjectCount;
+
+    /// \brief Overriders for each virtual base subobject.
+    llvm::DenseMap<const CXXRecordDecl *, CXXFinalOverriderMap *> VirtualOverriders;
+
+    CXXFinalOverriderMap FinalOverriders;
+
+  public:
+    ~FinalOverriderCollector();
+
+    void Collect(const CXXRecordDecl *RD, bool VirtualBase,
+                 const CXXRecordDecl *InVirtualSubobject,
+                 CXXFinalOverriderMap &Overriders);
+  };
+}
+
+void FinalOverriderCollector::Collect(const CXXRecordDecl *RD, 
+                                      bool VirtualBase,
+                                      const CXXRecordDecl *InVirtualSubobject,
+                                      CXXFinalOverriderMap &Overriders) {
+  unsigned SubobjectNumber = 0;
+  if (!VirtualBase)
+    SubobjectNumber
+      = ++SubobjectCount[cast<CXXRecordDecl>(RD->getCanonicalDecl())];
+
+  for (CXXRecordDecl::base_class_const_iterator Base = RD->bases_begin(),
+         BaseEnd = RD->bases_end(); Base != BaseEnd; ++Base) {
+    if (const RecordType *RT = Base->getType()->getAs<RecordType>()) {
+      const CXXRecordDecl *BaseDecl = cast<CXXRecordDecl>(RT->getDecl());
+      if (!BaseDecl->isPolymorphic())
+        continue;
+
+      if (Overriders.empty() && !Base->isVirtual()) {
+        // There are no other overriders of virtual member functions,
+        // so let the base class fill in our overriders for us.
+        Collect(BaseDecl, false, InVirtualSubobject, Overriders);
+        continue;
+      }
+
+      // Collect all of the overridders from the base class subobject
+      // and merge them into the set of overridders for this class.
+      // For virtual base classes, populate or use the cached virtual
+      // overrides so that we do not walk the virtual base class (and
+      // its base classes) more than once.
+      CXXFinalOverriderMap ComputedBaseOverriders;
+      CXXFinalOverriderMap *BaseOverriders = &ComputedBaseOverriders;
+      if (Base->isVirtual()) {
+        CXXFinalOverriderMap *&MyVirtualOverriders = VirtualOverriders[BaseDecl];
+        if (!MyVirtualOverriders) {
+          MyVirtualOverriders = new CXXFinalOverriderMap;
+          Collect(BaseDecl, true, BaseDecl, *MyVirtualOverriders);
+        }
+
+        BaseOverriders = MyVirtualOverriders;
+      } else
+        Collect(BaseDecl, false, InVirtualSubobject, ComputedBaseOverriders);
+
+      // Merge the overriders from this base class into our own set of
+      // overriders.
+      for (CXXFinalOverriderMap::iterator OM = BaseOverriders->begin(), 
+                               OMEnd = BaseOverriders->end();
+           OM != OMEnd;
+           ++OM) {
+        const CXXMethodDecl *CanonOM
+          = cast<CXXMethodDecl>(OM->first->getCanonicalDecl());
+        Overriders[CanonOM].add(OM->second);
+      }
+    }
+  }
+
+  for (CXXRecordDecl::method_iterator M = RD->method_begin(), 
+                                   MEnd = RD->method_end();
+       M != MEnd;
+       ++M) {
+    // We only care about virtual methods.
+    if (!M->isVirtual())
+      continue;
+
+    CXXMethodDecl *CanonM = cast<CXXMethodDecl>(M->getCanonicalDecl());
+
+    if (CanonM->begin_overridden_methods()
+                                       == CanonM->end_overridden_methods()) {
+      // This is a new virtual function that does not override any
+      // other virtual function. Add it to the map of virtual
+      // functions for which we are tracking overridders. 
+
+      // C++ [class.virtual]p2:
+      //   For convenience we say that any virtual function overrides itself.
+      Overriders[CanonM].add(SubobjectNumber,
+                             UniqueVirtualMethod(CanonM, SubobjectNumber,
+                                                 InVirtualSubobject));
+      continue;
+    }
+
+    // This virtual method overrides other virtual methods, so it does
+    // not add any new slots into the set of overriders. Instead, we
+    // replace entries in the set of overriders with the new
+    // overrider. To do so, we dig down to the original virtual
+    // functions using data recursion and update all of the methods it
+    // overrides.
+    typedef std::pair<CXXMethodDecl::method_iterator, 
+                      CXXMethodDecl::method_iterator> OverriddenMethods;
+    llvm::SmallVector<OverriddenMethods, 4> Stack;
+    Stack.push_back(std::make_pair(CanonM->begin_overridden_methods(),
+                                   CanonM->end_overridden_methods()));
+    while (!Stack.empty()) {
+      OverriddenMethods OverMethods = Stack.back();
+      Stack.pop_back();
+
+      for (; OverMethods.first != OverMethods.second; ++OverMethods.first) {
+        const CXXMethodDecl *CanonOM
+          = cast<CXXMethodDecl>((*OverMethods.first)->getCanonicalDecl());
+        if (CanonOM->begin_overridden_methods()
+                                       == CanonOM->end_overridden_methods()) {
+          // C++ [class.virtual]p2:
+          //   A virtual member function C::vf of a class object S is
+          //   a final overrider unless the most derived class (1.8)
+          //   of which S is a base class subobject (if any) declares
+          //   or inherits another member function that overrides vf.
+          //
+          // Treating this object like the most derived class, we
+          // replace any overrides from base classes with this
+          // overriding virtual function.
+          Overriders[CanonOM].replaceAll(
+                                 UniqueVirtualMethod(CanonM, SubobjectNumber,
+                                                     InVirtualSubobject));
+          continue;
+        } 
+
+        // Continue recursion to the methods that this virtual method
+        // overrides.
+        Stack.push_back(std::make_pair(CanonOM->begin_overridden_methods(),
+                                       CanonOM->end_overridden_methods()));
+      }
+    }
+  }
+}
+
+FinalOverriderCollector::~FinalOverriderCollector() {
+  for (llvm::DenseMap<const CXXRecordDecl *, CXXFinalOverriderMap *>::iterator
+         VO = VirtualOverriders.begin(), VOEnd = VirtualOverriders.end();
+       VO != VOEnd; 
+       ++VO)
+    delete VO->second;
+}
+
+void 
+CXXRecordDecl::getFinalOverriders(CXXFinalOverriderMap &FinalOverriders) const {
+  FinalOverriderCollector Collector;
+  Collector.Collect(this, false, 0, FinalOverriders);
+
+  // Weed out any final overriders that come from virtual base class
+  // subobjects that were hidden by other subobjects along any path.
+  // This is the final-overrider variant of C++ [class.member.lookup]p10.
+  for (CXXFinalOverriderMap::iterator OM = FinalOverriders.begin(), 
+                           OMEnd = FinalOverriders.end();
+       OM != OMEnd;
+       ++OM) {
+    for (OverridingMethods::iterator SO = OM->second.begin(), 
+                                  SOEnd = OM->second.end();
+         SO != SOEnd; 
+         ++SO) {
+      llvm::SmallVector<UniqueVirtualMethod, 4> &Overriding = SO->second;
+      if (Overriding.size() < 2)
+        continue;
+
+      for (llvm::SmallVector<UniqueVirtualMethod, 4>::iterator 
+             Pos = Overriding.begin(), PosEnd = Overriding.end();
+           Pos != PosEnd;
+           /* increment in loop */) {
+        if (!Pos->InVirtualSubobject) {
+          ++Pos;
+          continue;
+        }
+
+        // We have an overriding method in a virtual base class
+        // subobject (or non-virtual base class subobject thereof);
+        // determine whether there exists an other overriding method
+        // in a base class subobject that hides the virtual base class
+        // subobject.
+        bool Hidden = false;
+        for (llvm::SmallVector<UniqueVirtualMethod, 4>::iterator
+               OP = Overriding.begin(), OPEnd = Overriding.end();
+             OP != OPEnd && !Hidden; 
+             ++OP) {
+          if (Pos == OP)
+            continue;
+
+          if (OP->Method->getParent()->isVirtuallyDerivedFrom(
+                         const_cast<CXXRecordDecl *>(Pos->InVirtualSubobject)))
+            Hidden = true;
+        }
+
+        if (Hidden) {
+          // The current overriding function is hidden by another
+          // overriding function; remove this one.
+          Pos = Overriding.erase(Pos);
+          PosEnd = Overriding.end();
+        } else {
+          ++Pos;
+        }
+      }
+    }
+  }
+}
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
new file mode 100644
index 0000000..1d94c20
--- /dev/null
+++ b/lib/AST/Decl.cpp
@@ -0,0 +1,1722 @@
+//===--- Decl.cpp - Declaration AST Node Implementation -------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Decl subclasses.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/TypeLoc.h"
+#include "clang/AST/Stmt.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/PrettyPrinter.h"
+#include "clang/Basic/Builtins.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Parse/DeclSpec.h"
+#include "llvm/Support/ErrorHandling.h"
+#include <vector>
+
+using namespace clang;
+
+/// \brief Return the TypeLoc wrapper for the type source info.
+TypeLoc TypeSourceInfo::getTypeLoc() const {
+  return TypeLoc(Ty, (void*)(this + 1));
+}
+
+//===----------------------------------------------------------------------===//
+// NamedDecl Implementation
+//===----------------------------------------------------------------------===//
+
+/// \brief Get the most restrictive linkage for the types in the given
+/// template parameter list.
+static Linkage 
+getLinkageForTemplateParameterList(const TemplateParameterList *Params) {
+  Linkage L = ExternalLinkage;
+  for (TemplateParameterList::const_iterator P = Params->begin(),
+                                          PEnd = Params->end();
+       P != PEnd; ++P) {
+    if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P))
+      if (!NTTP->getType()->isDependentType()) {
+        L = minLinkage(L, NTTP->getType()->getLinkage());
+        continue;
+      }
+
+    if (TemplateTemplateParmDecl *TTP
+                                   = dyn_cast<TemplateTemplateParmDecl>(*P)) {
+      L = minLinkage(L, 
+            getLinkageForTemplateParameterList(TTP->getTemplateParameters()));
+    }
+  }
+
+  return L;
+}
+
+/// \brief Get the most restrictive linkage for the types and
+/// declarations in the given template argument list.
+static Linkage getLinkageForTemplateArgumentList(const TemplateArgument *Args,
+                                                 unsigned NumArgs) {
+  Linkage L = ExternalLinkage;
+
+  for (unsigned I = 0; I != NumArgs; ++I) {
+    switch (Args[I].getKind()) {
+    case TemplateArgument::Null:
+    case TemplateArgument::Integral:
+    case TemplateArgument::Expression:
+      break;
+      
+    case TemplateArgument::Type:
+      L = minLinkage(L, Args[I].getAsType()->getLinkage());
+      break;
+
+    case TemplateArgument::Declaration:
+      if (NamedDecl *ND = dyn_cast<NamedDecl>(Args[I].getAsDecl()))
+        L = minLinkage(L, ND->getLinkage());
+      if (ValueDecl *VD = dyn_cast<ValueDecl>(Args[I].getAsDecl()))
+        L = minLinkage(L, VD->getType()->getLinkage());
+      break;
+
+    case TemplateArgument::Template:
+      if (TemplateDecl *Template
+                                = Args[I].getAsTemplate().getAsTemplateDecl())
+        L = minLinkage(L, Template->getLinkage());
+      break;
+
+    case TemplateArgument::Pack:
+      L = minLinkage(L, 
+                     getLinkageForTemplateArgumentList(Args[I].pack_begin(),
+                                                       Args[I].pack_size()));
+      break;
+    }
+  }
+
+  return L;
+}
+
+static Linkage getLinkageForNamespaceScopeDecl(const NamedDecl *D) {
+  assert(D->getDeclContext()->getLookupContext()->isFileContext() &&
+         "Not a name having namespace scope");
+  ASTContext &Context = D->getASTContext();
+
+  // C++ [basic.link]p3:
+  //   A name having namespace scope (3.3.6) has internal linkage if it
+  //   is the name of
+  //     - an object, reference, function or function template that is
+  //       explicitly declared static; or,
+  // (This bullet corresponds to C99 6.2.2p3.)
+  if (const VarDecl *Var = dyn_cast<VarDecl>(D)) {
+    // Explicitly declared static.
+    if (Var->getStorageClass() == VarDecl::Static)
+      return InternalLinkage;
+
+    // - an object or reference that is explicitly declared const
+    //   and neither explicitly declared extern nor previously
+    //   declared to have external linkage; or
+    // (there is no equivalent in C99)
+    if (Context.getLangOptions().CPlusPlus &&
+        Var->getType().isConstant(Context) && 
+        Var->getStorageClass() != VarDecl::Extern &&
+        Var->getStorageClass() != VarDecl::PrivateExtern) {
+      bool FoundExtern = false;
+      for (const VarDecl *PrevVar = Var->getPreviousDeclaration();
+           PrevVar && !FoundExtern; 
+           PrevVar = PrevVar->getPreviousDeclaration())
+        if (isExternalLinkage(PrevVar->getLinkage()))
+          FoundExtern = true;
+      
+      if (!FoundExtern)
+        return InternalLinkage;
+    }
+  } else if (isa<FunctionDecl>(D) || isa<FunctionTemplateDecl>(D)) {
+    // C++ [temp]p4:
+    //   A non-member function template can have internal linkage; any
+    //   other template name shall have external linkage.
+    const FunctionDecl *Function = 0;
+    if (const FunctionTemplateDecl *FunTmpl
+                                        = dyn_cast<FunctionTemplateDecl>(D))
+      Function = FunTmpl->getTemplatedDecl();
+    else
+      Function = cast<FunctionDecl>(D);
+
+    // Explicitly declared static.
+    if (Function->getStorageClass() == FunctionDecl::Static)
+      return InternalLinkage;
+  } else if (const FieldDecl *Field = dyn_cast<FieldDecl>(D)) {
+    //   - a data member of an anonymous union.
+    if (cast<RecordDecl>(Field->getDeclContext())->isAnonymousStructOrUnion())
+      return InternalLinkage;
+  }
+
+  // C++ [basic.link]p4:
+  
+  //   A name having namespace scope has external linkage if it is the
+  //   name of
+  //
+  //     - an object or reference, unless it has internal linkage; or
+  if (const VarDecl *Var = dyn_cast<VarDecl>(D)) {
+    if (!Context.getLangOptions().CPlusPlus &&
+        (Var->getStorageClass() == VarDecl::Extern ||
+         Var->getStorageClass() == VarDecl::PrivateExtern)) {
+      // C99 6.2.2p4:
+      //   For an identifier declared with the storage-class specifier
+      //   extern in a scope in which a prior declaration of that
+      //   identifier is visible, if the prior declaration specifies
+      //   internal or external linkage, the linkage of the identifier
+      //   at the later declaration is the same as the linkage
+      //   specified at the prior declaration. If no prior declaration
+      //   is visible, or if the prior declaration specifies no
+      //   linkage, then the identifier has external linkage.
+      if (const VarDecl *PrevVar = Var->getPreviousDeclaration()) {
+        if (Linkage L = PrevVar->getLinkage())
+          return L;
+      }
+    }
+
+    // C99 6.2.2p5:
+    //   If the declaration of an identifier for an object has file
+    //   scope and no storage-class specifier, its linkage is
+    //   external.
+    if (Var->isInAnonymousNamespace())
+      return UniqueExternalLinkage;
+
+    return ExternalLinkage;
+  }
+
+  //     - a function, unless it has internal linkage; or
+  if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
+    // C99 6.2.2p5:
+    //   If the declaration of an identifier for a function has no
+    //   storage-class specifier, its linkage is determined exactly
+    //   as if it were declared with the storage-class specifier
+    //   extern.
+    if (!Context.getLangOptions().CPlusPlus &&
+        (Function->getStorageClass() == FunctionDecl::Extern ||
+         Function->getStorageClass() == FunctionDecl::PrivateExtern ||
+         Function->getStorageClass() == FunctionDecl::None)) {
+      // C99 6.2.2p4:
+      //   For an identifier declared with the storage-class specifier
+      //   extern in a scope in which a prior declaration of that
+      //   identifier is visible, if the prior declaration specifies
+      //   internal or external linkage, the linkage of the identifier
+      //   at the later declaration is the same as the linkage
+      //   specified at the prior declaration. If no prior declaration
+      //   is visible, or if the prior declaration specifies no
+      //   linkage, then the identifier has external linkage.
+      if (const FunctionDecl *PrevFunc = Function->getPreviousDeclaration()) {
+        if (Linkage L = PrevFunc->getLinkage())
+          return L;
+      }
+    }
+
+    if (Function->isInAnonymousNamespace())
+      return UniqueExternalLinkage;
+
+    if (FunctionTemplateSpecializationInfo *SpecInfo
+                               = Function->getTemplateSpecializationInfo()) {
+      Linkage L = SpecInfo->getTemplate()->getLinkage();
+      const TemplateArgumentList &TemplateArgs = *SpecInfo->TemplateArguments;
+      L = minLinkage(L, 
+                     getLinkageForTemplateArgumentList(
+                                          TemplateArgs.getFlatArgumentList(), 
+                                          TemplateArgs.flat_size()));
+      return L;
+    }
+
+    return ExternalLinkage;
+  }
+
+  //     - a named class (Clause 9), or an unnamed class defined in a
+  //       typedef declaration in which the class has the typedef name
+  //       for linkage purposes (7.1.3); or
+  //     - a named enumeration (7.2), or an unnamed enumeration
+  //       defined in a typedef declaration in which the enumeration
+  //       has the typedef name for linkage purposes (7.1.3); or
+  if (const TagDecl *Tag = dyn_cast<TagDecl>(D))
+    if (Tag->getDeclName() || Tag->getTypedefForAnonDecl()) {
+      if (Tag->isInAnonymousNamespace())
+        return UniqueExternalLinkage;
+
+      // If this is a class template specialization, consider the
+      // linkage of the template and template arguments.
+      if (const ClassTemplateSpecializationDecl *Spec
+            = dyn_cast<ClassTemplateSpecializationDecl>(Tag)) {
+        const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
+        Linkage L = getLinkageForTemplateArgumentList(
+                                          TemplateArgs.getFlatArgumentList(),
+                                                 TemplateArgs.flat_size());
+        return minLinkage(L, Spec->getSpecializedTemplate()->getLinkage());
+      }
+
+      return ExternalLinkage;
+    }
+
+  //     - an enumerator belonging to an enumeration with external linkage;
+  if (isa<EnumConstantDecl>(D)) {
+    Linkage L = cast<NamedDecl>(D->getDeclContext())->getLinkage();
+    if (isExternalLinkage(L))
+      return L;
+  }
+
+  //     - a template, unless it is a function template that has
+  //       internal linkage (Clause 14);
+  if (const TemplateDecl *Template = dyn_cast<TemplateDecl>(D)) {
+    if (D->isInAnonymousNamespace())
+      return UniqueExternalLinkage;
+
+    return getLinkageForTemplateParameterList(
+                                         Template->getTemplateParameters());
+  }
+
+  //     - a namespace (7.3), unless it is declared within an unnamed
+  //       namespace.
+  if (isa<NamespaceDecl>(D) && !D->isInAnonymousNamespace())
+    return ExternalLinkage;
+
+  return NoLinkage;
+}
+
+Linkage NamedDecl::getLinkage() const {
+
+  // Objective-C: treat all Objective-C declarations as having external
+  // linkage.
+  switch (getKind()) {
+    default:
+      break;
+    case Decl::ObjCAtDefsField:
+    case Decl::ObjCCategory:
+    case Decl::ObjCCategoryImpl:
+    case Decl::ObjCClass:
+    case Decl::ObjCCompatibleAlias:
+    case Decl::ObjCForwardProtocol:
+    case Decl::ObjCImplementation:
+    case Decl::ObjCInterface:
+    case Decl::ObjCIvar:
+    case Decl::ObjCMethod:
+    case Decl::ObjCProperty:
+    case Decl::ObjCPropertyImpl:
+    case Decl::ObjCProtocol:
+      return ExternalLinkage;
+  }
+
+  // Handle linkage for namespace-scope names.
+  if (getDeclContext()->getLookupContext()->isFileContext())
+    if (Linkage L = getLinkageForNamespaceScopeDecl(this))
+      return L;
+  
+  // C++ [basic.link]p5:
+  //   In addition, a member function, static data member, a named
+  //   class or enumeration of class scope, or an unnamed class or
+  //   enumeration defined in a class-scope typedef declaration such
+  //   that the class or enumeration has the typedef name for linkage
+  //   purposes (7.1.3), has external linkage if the name of the class
+  //   has external linkage.
+  if (getDeclContext()->isRecord() &&
+      (isa<CXXMethodDecl>(this) || isa<VarDecl>(this) ||
+       (isa<TagDecl>(this) &&
+        (getDeclName() || cast<TagDecl>(this)->getTypedefForAnonDecl())))) {
+    Linkage L = cast<RecordDecl>(getDeclContext())->getLinkage();
+    if (isExternalLinkage(L))
+      return L;
+  }
+
+  // C++ [basic.link]p6:
+  //   The name of a function declared in block scope and the name of
+  //   an object declared by a block scope extern declaration have
+  //   linkage. If there is a visible declaration of an entity with
+  //   linkage having the same name and type, ignoring entities
+  //   declared outside the innermost enclosing namespace scope, the
+  //   block scope declaration declares that same entity and receives
+  //   the linkage of the previous declaration. If there is more than
+  //   one such matching entity, the program is ill-formed. Otherwise,
+  //   if no matching entity is found, the block scope entity receives
+  //   external linkage.
+  if (getLexicalDeclContext()->isFunctionOrMethod()) {
+    if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(this)) {
+      if (Function->getPreviousDeclaration())
+        if (Linkage L = Function->getPreviousDeclaration()->getLinkage())
+          return L;
+
+      if (Function->isInAnonymousNamespace())
+        return UniqueExternalLinkage;
+
+      return ExternalLinkage;
+    }
+
+    if (const VarDecl *Var = dyn_cast<VarDecl>(this))
+      if (Var->getStorageClass() == VarDecl::Extern ||
+          Var->getStorageClass() == VarDecl::PrivateExtern) {
+        if (Var->getPreviousDeclaration())
+          if (Linkage L = Var->getPreviousDeclaration()->getLinkage())
+            return L;
+
+        if (Var->isInAnonymousNamespace())
+          return UniqueExternalLinkage;
+
+        return ExternalLinkage;
+      }
+  }
+
+  // C++ [basic.link]p6:
+  //   Names not covered by these rules have no linkage.
+  return NoLinkage;
+  }
+
+std::string NamedDecl::getQualifiedNameAsString() const {
+  return getQualifiedNameAsString(getASTContext().getLangOptions());
+}
+
+std::string NamedDecl::getQualifiedNameAsString(const PrintingPolicy &P) const {
+  // FIXME: Collect contexts, then accumulate names to avoid unnecessary
+  // std::string thrashing.
+  std::vector<std::string> Names;
+  std::string QualName;
+  const DeclContext *Ctx = getDeclContext();
+
+  if (Ctx->isFunctionOrMethod())
+    return getNameAsString();
+
+  while (Ctx) {
+    if (const ClassTemplateSpecializationDecl *Spec
+          = dyn_cast<ClassTemplateSpecializationDecl>(Ctx)) {
+      const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
+      std::string TemplateArgsStr
+        = TemplateSpecializationType::PrintTemplateArgumentList(
+                                           TemplateArgs.getFlatArgumentList(),
+                                           TemplateArgs.flat_size(),
+                                           P);
+      Names.push_back(Spec->getIdentifier()->getNameStart() + TemplateArgsStr);
+    } else if (const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(Ctx)) {
+      if (ND->isAnonymousNamespace())
+        Names.push_back("<anonymous namespace>");
+      else
+        Names.push_back(ND->getNameAsString());
+    } else if (const RecordDecl *RD = dyn_cast<RecordDecl>(Ctx)) {
+      if (!RD->getIdentifier()) {
+        std::string RecordString = "<anonymous ";
+        RecordString += RD->getKindName();
+        RecordString += ">";
+        Names.push_back(RecordString);
+      } else {
+        Names.push_back(RD->getNameAsString());
+      }
+    } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(Ctx)) {
+      std::string Proto = FD->getNameAsString();
+
+      const FunctionProtoType *FT = 0;
+      if (FD->hasWrittenPrototype())
+        FT = dyn_cast<FunctionProtoType>(FD->getType()->getAs<FunctionType>());
+
+      Proto += "(";
+      if (FT) {
+        llvm::raw_string_ostream POut(Proto);
+        unsigned NumParams = FD->getNumParams();
+        for (unsigned i = 0; i < NumParams; ++i) {
+          if (i)
+            POut << ", ";
+          std::string Param;
+          FD->getParamDecl(i)->getType().getAsStringInternal(Param, P);
+          POut << Param;
+        }
+
+        if (FT->isVariadic()) {
+          if (NumParams > 0)
+            POut << ", ";
+          POut << "...";
+        }
+      }
+      Proto += ")";
+
+      Names.push_back(Proto);
+    } else if (const NamedDecl *ND = dyn_cast<NamedDecl>(Ctx))
+      Names.push_back(ND->getNameAsString());
+    else
+      break;
+
+    Ctx = Ctx->getParent();
+  }
+
+  std::vector<std::string>::reverse_iterator
+    I = Names.rbegin(),
+    End = Names.rend();
+
+  for (; I!=End; ++I)
+    QualName += *I + "::";
+
+  if (getDeclName())
+    QualName += getNameAsString();
+  else
+    QualName += "<anonymous>";
+
+  return QualName;
+}
+
+bool NamedDecl::declarationReplaces(NamedDecl *OldD) const {
+  assert(getDeclName() == OldD->getDeclName() && "Declaration name mismatch");
+
+  // UsingDirectiveDecl's are not really NamedDecl's, and all have same name.
+  // We want to keep it, unless it nominates same namespace.
+  if (getKind() == Decl::UsingDirective) {
+    return cast<UsingDirectiveDecl>(this)->getNominatedNamespace() ==
+           cast<UsingDirectiveDecl>(OldD)->getNominatedNamespace();
+  }
+
+  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(this))
+    // For function declarations, we keep track of redeclarations.
+    return FD->getPreviousDeclaration() == OldD;
+
+  // For function templates, the underlying function declarations are linked.
+  if (const FunctionTemplateDecl *FunctionTemplate
+        = dyn_cast<FunctionTemplateDecl>(this))
+    if (const FunctionTemplateDecl *OldFunctionTemplate
+          = dyn_cast<FunctionTemplateDecl>(OldD))
+      return FunctionTemplate->getTemplatedDecl()
+               ->declarationReplaces(OldFunctionTemplate->getTemplatedDecl());
+
+  // For method declarations, we keep track of redeclarations.
+  if (isa<ObjCMethodDecl>(this))
+    return false;
+
+  if (isa<ObjCInterfaceDecl>(this) && isa<ObjCCompatibleAliasDecl>(OldD))
+    return true;
+
+  if (isa<UsingShadowDecl>(this) && isa<UsingShadowDecl>(OldD))
+    return cast<UsingShadowDecl>(this)->getTargetDecl() ==
+           cast<UsingShadowDecl>(OldD)->getTargetDecl();
+
+  // For non-function declarations, if the declarations are of the
+  // same kind then this must be a redeclaration, or semantic analysis
+  // would not have given us the new declaration.
+  return this->getKind() == OldD->getKind();
+}
+
+bool NamedDecl::hasLinkage() const {
+  return getLinkage() != NoLinkage;
+}
+
+NamedDecl *NamedDecl::getUnderlyingDecl() {
+  NamedDecl *ND = this;
+  while (true) {
+    if (UsingShadowDecl *UD = dyn_cast<UsingShadowDecl>(ND))
+      ND = UD->getTargetDecl();
+    else if (ObjCCompatibleAliasDecl *AD
+              = dyn_cast<ObjCCompatibleAliasDecl>(ND))
+      return AD->getClassInterface();
+    else
+      return ND;
+  }
+}
+
+bool NamedDecl::isCXXInstanceMember() const {
+  assert(isCXXClassMember() &&
+         "checking whether non-member is instance member");
+
+  const NamedDecl *D = this;
+  if (isa<UsingShadowDecl>(D))
+    D = cast<UsingShadowDecl>(D)->getTargetDecl();
+
+  if (isa<FieldDecl>(D))
+    return true;
+  if (isa<CXXMethodDecl>(D))
+    return cast<CXXMethodDecl>(D)->isInstance();
+  if (isa<FunctionTemplateDecl>(D))
+    return cast<CXXMethodDecl>(cast<FunctionTemplateDecl>(D)
+                                 ->getTemplatedDecl())->isInstance();
+  return false;
+}
+
+//===----------------------------------------------------------------------===//
+// DeclaratorDecl Implementation
+//===----------------------------------------------------------------------===//
+
+DeclaratorDecl::~DeclaratorDecl() {}
+void DeclaratorDecl::Destroy(ASTContext &C) {
+  if (hasExtInfo())
+    C.Deallocate(getExtInfo());
+  ValueDecl::Destroy(C);
+}
+
+SourceLocation DeclaratorDecl::getTypeSpecStartLoc() const {
+  if (DeclInfo) {
+    TypeLoc TL = getTypeSourceInfo()->getTypeLoc();
+    while (true) {
+      TypeLoc NextTL = TL.getNextTypeLoc();
+      if (!NextTL)
+        return TL.getSourceRange().getBegin();
+      TL = NextTL;
+    }
+  }
+  return SourceLocation();
+}
+
+void DeclaratorDecl::setQualifierInfo(NestedNameSpecifier *Qualifier,
+                                      SourceRange QualifierRange) {
+  if (Qualifier) {
+    // Make sure the extended decl info is allocated.
+    if (!hasExtInfo()) {
+      // Save (non-extended) type source info pointer.
+      TypeSourceInfo *savedTInfo = DeclInfo.get<TypeSourceInfo*>();
+      // Allocate external info struct.
+      DeclInfo = new (getASTContext()) ExtInfo;
+      // Restore savedTInfo into (extended) decl info.
+      getExtInfo()->TInfo = savedTInfo;
+    }
+    // Set qualifier info.
+    getExtInfo()->NNS = Qualifier;
+    getExtInfo()->NNSRange = QualifierRange;
+  }
+  else {
+    // Here Qualifier == 0, i.e., we are removing the qualifier (if any).
+    assert(QualifierRange.isInvalid());
+    if (hasExtInfo()) {
+      // Save type source info pointer.
+      TypeSourceInfo *savedTInfo = getExtInfo()->TInfo;
+      // Deallocate the extended decl info.
+      getASTContext().Deallocate(getExtInfo());
+      // Restore savedTInfo into (non-extended) decl info.
+      DeclInfo = savedTInfo;
+    }
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// VarDecl Implementation
+//===----------------------------------------------------------------------===//
+
+const char *VarDecl::getStorageClassSpecifierString(StorageClass SC) {
+  switch (SC) {
+  case VarDecl::None:          break;
+  case VarDecl::Auto:          return "auto"; break;
+  case VarDecl::Extern:        return "extern"; break;
+  case VarDecl::PrivateExtern: return "__private_extern__"; break;
+  case VarDecl::Register:      return "register"; break;
+  case VarDecl::Static:        return "static"; break;
+  }
+
+  assert(0 && "Invalid storage class");
+  return 0;
+}
+
+VarDecl *VarDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
+                         IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
+                         StorageClass S, StorageClass SCAsWritten) {
+  return new (C) VarDecl(Var, DC, L, Id, T, TInfo, S, SCAsWritten);
+}
+
+void VarDecl::Destroy(ASTContext& C) {
+  Expr *Init = getInit();
+  if (Init) {
+    Init->Destroy(C);
+    if (EvaluatedStmt *Eval = this->Init.dyn_cast<EvaluatedStmt *>()) {
+      Eval->~EvaluatedStmt();
+      C.Deallocate(Eval);
+    }
+  }
+  this->~VarDecl();
+  DeclaratorDecl::Destroy(C);
+}
+
+VarDecl::~VarDecl() {
+}
+
+SourceRange VarDecl::getSourceRange() const {
+  SourceLocation Start = getTypeSpecStartLoc();
+  if (Start.isInvalid())
+    Start = getLocation();
+  
+  if (getInit())
+    return SourceRange(Start, getInit()->getLocEnd());
+  return SourceRange(Start, getLocation());
+}
+
+bool VarDecl::isExternC() const {
+  ASTContext &Context = getASTContext();
+  if (!Context.getLangOptions().CPlusPlus)
+    return (getDeclContext()->isTranslationUnit() &&
+            getStorageClass() != Static) ||
+      (getDeclContext()->isFunctionOrMethod() && hasExternalStorage());
+
+  for (const DeclContext *DC = getDeclContext(); !DC->isTranslationUnit();
+       DC = DC->getParent()) {
+    if (const LinkageSpecDecl *Linkage = dyn_cast<LinkageSpecDecl>(DC))  {
+      if (Linkage->getLanguage() == LinkageSpecDecl::lang_c)
+        return getStorageClass() != Static;
+
+      break;
+    }
+
+    if (DC->isFunctionOrMethod())
+      return false;
+  }
+
+  return false;
+}
+
+VarDecl *VarDecl::getCanonicalDecl() {
+  return getFirstDeclaration();
+}
+
+VarDecl::DefinitionKind VarDecl::isThisDeclarationADefinition() const {
+  // C++ [basic.def]p2:
+  //   A declaration is a definition unless [...] it contains the 'extern'
+  //   specifier or a linkage-specification and neither an initializer [...],
+  //   it declares a static data member in a class declaration [...].
+  // C++ [temp.expl.spec]p15:
+  //   An explicit specialization of a static data member of a template is a
+  //   definition if the declaration includes an initializer; otherwise, it is
+  //   a declaration.
+  if (isStaticDataMember()) {
+    if (isOutOfLine() && (hasInit() ||
+          getTemplateSpecializationKind() != TSK_ExplicitSpecialization))
+      return Definition;
+    else
+      return DeclarationOnly;
+  }
+  // C99 6.7p5:
+  //   A definition of an identifier is a declaration for that identifier that
+  //   [...] causes storage to be reserved for that object.
+  // Note: that applies for all non-file-scope objects.
+  // C99 6.9.2p1:
+  //   If the declaration of an identifier for an object has file scope and an
+  //   initializer, the declaration is an external definition for the identifier
+  if (hasInit())
+    return Definition;
+  // AST for 'extern "C" int foo;' is annotated with 'extern'.
+  if (hasExternalStorage())
+    return DeclarationOnly;
+
+  // C99 6.9.2p2:
+  //   A declaration of an object that has file scope without an initializer,
+  //   and without a storage class specifier or the scs 'static', constitutes
+  //   a tentative definition.
+  // No such thing in C++.
+  if (!getASTContext().getLangOptions().CPlusPlus && isFileVarDecl())
+    return TentativeDefinition;
+
+  // What's left is (in C, block-scope) declarations without initializers or
+  // external storage. These are definitions.
+  return Definition;
+}
+
+VarDecl *VarDecl::getActingDefinition() {
+  DefinitionKind Kind = isThisDeclarationADefinition();
+  if (Kind != TentativeDefinition)
+    return 0;
+
+  VarDecl *LastTentative = false;
+  VarDecl *First = getFirstDeclaration();
+  for (redecl_iterator I = First->redecls_begin(), E = First->redecls_end();
+       I != E; ++I) {
+    Kind = (*I)->isThisDeclarationADefinition();
+    if (Kind == Definition)
+      return 0;
+    else if (Kind == TentativeDefinition)
+      LastTentative = *I;
+  }
+  return LastTentative;
+}
+
+bool VarDecl::isTentativeDefinitionNow() const {
+  DefinitionKind Kind = isThisDeclarationADefinition();
+  if (Kind != TentativeDefinition)
+    return false;
+
+  for (redecl_iterator I = redecls_begin(), E = redecls_end(); I != E; ++I) {
+    if ((*I)->isThisDeclarationADefinition() == Definition)
+      return false;
+  }
+  return true;
+}
+
+VarDecl *VarDecl::getDefinition() {
+  VarDecl *First = getFirstDeclaration();
+  for (redecl_iterator I = First->redecls_begin(), E = First->redecls_end();
+       I != E; ++I) {
+    if ((*I)->isThisDeclarationADefinition() == Definition)
+      return *I;
+  }
+  return 0;
+}
+
+const Expr *VarDecl::getAnyInitializer(const VarDecl *&D) const {
+  redecl_iterator I = redecls_begin(), E = redecls_end();
+  while (I != E && !I->getInit())
+    ++I;
+
+  if (I != E) {
+    D = *I;
+    return I->getInit();
+  }
+  return 0;
+}
+
+bool VarDecl::isOutOfLine() const {
+  if (Decl::isOutOfLine())
+    return true;
+
+  if (!isStaticDataMember())
+    return false;
+
+  // If this static data member was instantiated from a static data member of
+  // a class template, check whether that static data member was defined 
+  // out-of-line.
+  if (VarDecl *VD = getInstantiatedFromStaticDataMember())
+    return VD->isOutOfLine();
+  
+  return false;
+}
+
+VarDecl *VarDecl::getOutOfLineDefinition() {
+  if (!isStaticDataMember())
+    return 0;
+  
+  for (VarDecl::redecl_iterator RD = redecls_begin(), RDEnd = redecls_end();
+       RD != RDEnd; ++RD) {
+    if (RD->getLexicalDeclContext()->isFileContext())
+      return *RD;
+  }
+  
+  return 0;
+}
+
+void VarDecl::setInit(Expr *I) {
+  if (EvaluatedStmt *Eval = Init.dyn_cast<EvaluatedStmt *>()) {
+    Eval->~EvaluatedStmt();
+    getASTContext().Deallocate(Eval);
+  }
+
+  Init = I;
+}
+
+VarDecl *VarDecl::getInstantiatedFromStaticDataMember() const {
+  if (MemberSpecializationInfo *MSI = getMemberSpecializationInfo())
+    return cast<VarDecl>(MSI->getInstantiatedFrom());
+  
+  return 0;
+}
+
+TemplateSpecializationKind VarDecl::getTemplateSpecializationKind() const {
+  if (MemberSpecializationInfo *MSI = getMemberSpecializationInfo())
+    return MSI->getTemplateSpecializationKind();
+  
+  return TSK_Undeclared;
+}
+
+MemberSpecializationInfo *VarDecl::getMemberSpecializationInfo() const {
+  return getASTContext().getInstantiatedFromStaticDataMember(this);
+}
+
+void VarDecl::setTemplateSpecializationKind(TemplateSpecializationKind TSK,
+                                         SourceLocation PointOfInstantiation) {
+  MemberSpecializationInfo *MSI = getMemberSpecializationInfo();
+  assert(MSI && "Not an instantiated static data member?");
+  MSI->setTemplateSpecializationKind(TSK);
+  if (TSK != TSK_ExplicitSpecialization &&
+      PointOfInstantiation.isValid() &&
+      MSI->getPointOfInstantiation().isInvalid())
+    MSI->setPointOfInstantiation(PointOfInstantiation);
+}
+
+//===----------------------------------------------------------------------===//
+// ParmVarDecl Implementation
+//===----------------------------------------------------------------------===//
+
+ParmVarDecl *ParmVarDecl::Create(ASTContext &C, DeclContext *DC,
+                                 SourceLocation L, IdentifierInfo *Id,
+                                 QualType T, TypeSourceInfo *TInfo,
+                                 StorageClass S, StorageClass SCAsWritten,
+                                 Expr *DefArg) {
+  return new (C) ParmVarDecl(ParmVar, DC, L, Id, T, TInfo,
+                             S, SCAsWritten, DefArg);
+}
+
+Expr *ParmVarDecl::getDefaultArg() {
+  assert(!hasUnparsedDefaultArg() && "Default argument is not yet parsed!");
+  assert(!hasUninstantiatedDefaultArg() &&
+         "Default argument is not yet instantiated!");
+  
+  Expr *Arg = getInit();
+  if (CXXExprWithTemporaries *E = dyn_cast_or_null<CXXExprWithTemporaries>(Arg))
+    return E->getSubExpr();
+
+  return Arg;
+}
+
+unsigned ParmVarDecl::getNumDefaultArgTemporaries() const {
+  if (const CXXExprWithTemporaries *E = 
+        dyn_cast<CXXExprWithTemporaries>(getInit()))
+    return E->getNumTemporaries();
+
+  return 0;
+}
+
+CXXTemporary *ParmVarDecl::getDefaultArgTemporary(unsigned i) {
+  assert(getNumDefaultArgTemporaries() && 
+         "Default arguments does not have any temporaries!");
+
+  CXXExprWithTemporaries *E = cast<CXXExprWithTemporaries>(getInit());
+  return E->getTemporary(i);
+}
+
+SourceRange ParmVarDecl::getDefaultArgRange() const {
+  if (const Expr *E = getInit())
+    return E->getSourceRange();
+
+  if (hasUninstantiatedDefaultArg())
+    return getUninstantiatedDefaultArg()->getSourceRange();
+
+  return SourceRange();
+}
+
+//===----------------------------------------------------------------------===//
+// FunctionDecl Implementation
+//===----------------------------------------------------------------------===//
+
+void FunctionDecl::Destroy(ASTContext& C) {
+  if (Body && Body.isOffset())
+    Body.get(C.getExternalSource())->Destroy(C);
+
+  for (param_iterator I=param_begin(), E=param_end(); I!=E; ++I)
+    (*I)->Destroy(C);
+
+  FunctionTemplateSpecializationInfo *FTSInfo
+    = TemplateOrSpecialization.dyn_cast<FunctionTemplateSpecializationInfo*>();
+  if (FTSInfo)
+    C.Deallocate(FTSInfo);
+  
+  MemberSpecializationInfo *MSInfo
+    = TemplateOrSpecialization.dyn_cast<MemberSpecializationInfo*>();
+  if (MSInfo)
+    C.Deallocate(MSInfo);
+  
+  C.Deallocate(ParamInfo);
+
+  DeclaratorDecl::Destroy(C);
+}
+
+void FunctionDecl::getNameForDiagnostic(std::string &S,
+                                        const PrintingPolicy &Policy,
+                                        bool Qualified) const {
+  NamedDecl::getNameForDiagnostic(S, Policy, Qualified);
+  const TemplateArgumentList *TemplateArgs = getTemplateSpecializationArgs();
+  if (TemplateArgs)
+    S += TemplateSpecializationType::PrintTemplateArgumentList(
+                                         TemplateArgs->getFlatArgumentList(),
+                                         TemplateArgs->flat_size(),
+                                                               Policy);
+    
+}
+
+Stmt *FunctionDecl::getBody(const FunctionDecl *&Definition) const {
+  for (redecl_iterator I = redecls_begin(), E = redecls_end(); I != E; ++I) {
+    if (I->Body) {
+      Definition = *I;
+      return I->Body.get(getASTContext().getExternalSource());
+    }
+  }
+
+  return 0;
+}
+
+void FunctionDecl::setBody(Stmt *B) {
+  Body = B;
+  if (B)
+    EndRangeLoc = B->getLocEnd();
+}
+
+bool FunctionDecl::isMain() const {
+  ASTContext &Context = getASTContext();
+  return !Context.getLangOptions().Freestanding &&
+    getDeclContext()->getLookupContext()->isTranslationUnit() &&
+    getIdentifier() && getIdentifier()->isStr("main");
+}
+
+bool FunctionDecl::isExternC() const {
+  ASTContext &Context = getASTContext();
+  // In C, any non-static, non-overloadable function has external
+  // linkage.
+  if (!Context.getLangOptions().CPlusPlus)
+    return getStorageClass() != Static && !getAttr<OverloadableAttr>();
+
+  for (const DeclContext *DC = getDeclContext(); !DC->isTranslationUnit();
+       DC = DC->getParent()) {
+    if (const LinkageSpecDecl *Linkage = dyn_cast<LinkageSpecDecl>(DC))  {
+      if (Linkage->getLanguage() == LinkageSpecDecl::lang_c)
+        return getStorageClass() != Static &&
+               !getAttr<OverloadableAttr>();
+
+      break;
+    }
+  }
+
+  return false;
+}
+
+bool FunctionDecl::isGlobal() const {
+  if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(this))
+    return Method->isStatic();
+
+  if (getStorageClass() == Static)
+    return false;
+
+  for (const DeclContext *DC = getDeclContext();
+       DC->isNamespace();
+       DC = DC->getParent()) {
+    if (const NamespaceDecl *Namespace = cast<NamespaceDecl>(DC)) {
+      if (!Namespace->getDeclName())
+        return false;
+      break;
+    }
+  }
+
+  return true;
+}
+
+void
+FunctionDecl::setPreviousDeclaration(FunctionDecl *PrevDecl) {
+  redeclarable_base::setPreviousDeclaration(PrevDecl);
+
+  if (FunctionTemplateDecl *FunTmpl = getDescribedFunctionTemplate()) {
+    FunctionTemplateDecl *PrevFunTmpl
+      = PrevDecl? PrevDecl->getDescribedFunctionTemplate() : 0;
+    assert((!PrevDecl || PrevFunTmpl) && "Function/function template mismatch");
+    FunTmpl->setPreviousDeclaration(PrevFunTmpl);
+  }
+}
+
+const FunctionDecl *FunctionDecl::getCanonicalDecl() const {
+  return getFirstDeclaration();
+}
+
+FunctionDecl *FunctionDecl::getCanonicalDecl() {
+  return getFirstDeclaration();
+}
+
+/// \brief Returns a value indicating whether this function
+/// corresponds to a builtin function.
+///
+/// The function corresponds to a built-in function if it is
+/// declared at translation scope or within an extern "C" block and
+/// its name matches with the name of a builtin. The returned value
+/// will be 0 for functions that do not correspond to a builtin, a
+/// value of type \c Builtin::ID if in the target-independent range
+/// \c [1,Builtin::First), or a target-specific builtin value.
+unsigned FunctionDecl::getBuiltinID() const {
+  ASTContext &Context = getASTContext();
+  if (!getIdentifier() || !getIdentifier()->getBuiltinID())
+    return 0;
+
+  unsigned BuiltinID = getIdentifier()->getBuiltinID();
+  if (!Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID))
+    return BuiltinID;
+
+  // This function has the name of a known C library
+  // function. Determine whether it actually refers to the C library
+  // function or whether it just has the same name.
+
+  // If this is a static function, it's not a builtin.
+  if (getStorageClass() == Static)
+    return 0;
+
+  // If this function is at translation-unit scope and we're not in
+  // C++, it refers to the C library function.
+  if (!Context.getLangOptions().CPlusPlus &&
+      getDeclContext()->isTranslationUnit())
+    return BuiltinID;
+
+  // If the function is in an extern "C" linkage specification and is
+  // not marked "overloadable", it's the real function.
+  if (isa<LinkageSpecDecl>(getDeclContext()) &&
+      cast<LinkageSpecDecl>(getDeclContext())->getLanguage()
+        == LinkageSpecDecl::lang_c &&
+      !getAttr<OverloadableAttr>())
+    return BuiltinID;
+
+  // Not a builtin
+  return 0;
+}
+
+
+/// getNumParams - Return the number of parameters this function must have
+/// based on its FunctionType.  This is the length of the PararmInfo array
+/// after it has been created.
+unsigned FunctionDecl::getNumParams() const {
+  const FunctionType *FT = getType()->getAs<FunctionType>();
+  if (isa<FunctionNoProtoType>(FT))
+    return 0;
+  return cast<FunctionProtoType>(FT)->getNumArgs();
+
+}
+
+void FunctionDecl::setParams(ParmVarDecl **NewParamInfo, unsigned NumParams) {
+  assert(ParamInfo == 0 && "Already has param info!");
+  assert(NumParams == getNumParams() && "Parameter count mismatch!");
+
+  // Zero params -> null pointer.
+  if (NumParams) {
+    void *Mem = getASTContext().Allocate(sizeof(ParmVarDecl*)*NumParams);
+    ParamInfo = new (Mem) ParmVarDecl*[NumParams];
+    memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams);
+
+    // Update source range. The check below allows us to set EndRangeLoc before
+    // setting the parameters.
+    if (EndRangeLoc.isInvalid() || EndRangeLoc == getLocation())
+      EndRangeLoc = NewParamInfo[NumParams-1]->getLocEnd();
+  }
+}
+
+/// getMinRequiredArguments - Returns the minimum number of arguments
+/// needed to call this function. This may be fewer than the number of
+/// function parameters, if some of the parameters have default
+/// arguments (in C++).
+unsigned FunctionDecl::getMinRequiredArguments() const {
+  unsigned NumRequiredArgs = getNumParams();
+  while (NumRequiredArgs > 0
+         && getParamDecl(NumRequiredArgs-1)->hasDefaultArg())
+    --NumRequiredArgs;
+
+  return NumRequiredArgs;
+}
+
+bool FunctionDecl::isInlined() const {
+  // FIXME: This is not enough. Consider:
+  //
+  // inline void f();
+  // void f() { }
+  //
+  // f is inlined, but does not have inline specified.
+  // To fix this we should add an 'inline' flag to FunctionDecl.
+  if (isInlineSpecified())
+    return true;
+  
+  if (isa<CXXMethodDecl>(this)) {
+    if (!isOutOfLine() || getCanonicalDecl()->isInlineSpecified())
+      return true;
+  }
+
+  switch (getTemplateSpecializationKind()) {
+  case TSK_Undeclared:
+  case TSK_ExplicitSpecialization:
+    return false;
+
+  case TSK_ImplicitInstantiation:
+  case TSK_ExplicitInstantiationDeclaration:
+  case TSK_ExplicitInstantiationDefinition:
+    // Handle below.
+    break;
+  }
+
+  const FunctionDecl *PatternDecl = getTemplateInstantiationPattern();
+  Stmt *Pattern = 0;
+  if (PatternDecl)
+    Pattern = PatternDecl->getBody(PatternDecl);
+  
+  if (Pattern && PatternDecl)
+    return PatternDecl->isInlined();
+  
+  return false;
+}
+
+/// \brief For an inline function definition in C or C++, determine whether the 
+/// definition will be externally visible.
+///
+/// Inline function definitions are always available for inlining optimizations.
+/// However, depending on the language dialect, declaration specifiers, and
+/// attributes, the definition of an inline function may or may not be
+/// "externally" visible to other translation units in the program.
+///
+/// In C99, inline definitions are not externally visible by default. However,
+/// if even one of the global-scope declarations is marked "extern inline", the
+/// inline definition becomes externally visible (C99 6.7.4p6).
+///
+/// In GNU89 mode, or if the gnu_inline attribute is attached to the function
+/// definition, we use the GNU semantics for inline, which are nearly the 
+/// opposite of C99 semantics. In particular, "inline" by itself will create 
+/// an externally visible symbol, but "extern inline" will not create an 
+/// externally visible symbol.
+bool FunctionDecl::isInlineDefinitionExternallyVisible() const {
+  assert(isThisDeclarationADefinition() && "Must have the function definition");
+  assert(isInlined() && "Function must be inline");
+  ASTContext &Context = getASTContext();
+  
+  if (!Context.getLangOptions().C99 || hasAttr<GNUInlineAttr>()) {
+    // GNU inline semantics. Based on a number of examples, we came up with the
+    // following heuristic: if the "inline" keyword is present on a
+    // declaration of the function but "extern" is not present on that
+    // declaration, then the symbol is externally visible. Otherwise, the GNU
+    // "extern inline" semantics applies and the symbol is not externally
+    // visible.
+    for (redecl_iterator Redecl = redecls_begin(), RedeclEnd = redecls_end();
+         Redecl != RedeclEnd;
+         ++Redecl) {
+      if (Redecl->isInlineSpecified() && Redecl->getStorageClass() != Extern)
+        return true;
+    }
+    
+    // GNU "extern inline" semantics; no externally visible symbol.
+    return false;
+  }
+  
+  // C99 6.7.4p6:
+  //   [...] If all of the file scope declarations for a function in a 
+  //   translation unit include the inline function specifier without extern, 
+  //   then the definition in that translation unit is an inline definition.
+  for (redecl_iterator Redecl = redecls_begin(), RedeclEnd = redecls_end();
+       Redecl != RedeclEnd;
+       ++Redecl) {
+    // Only consider file-scope declarations in this test.
+    if (!Redecl->getLexicalDeclContext()->isTranslationUnit())
+      continue;
+    
+    if (!Redecl->isInlineSpecified() || Redecl->getStorageClass() == Extern) 
+      return true; // Not an inline definition
+  }
+  
+  // C99 6.7.4p6:
+  //   An inline definition does not provide an external definition for the 
+  //   function, and does not forbid an external definition in another 
+  //   translation unit.
+  return false;
+}
+
+/// getOverloadedOperator - Which C++ overloaded operator this
+/// function represents, if any.
+OverloadedOperatorKind FunctionDecl::getOverloadedOperator() const {
+  if (getDeclName().getNameKind() == DeclarationName::CXXOperatorName)
+    return getDeclName().getCXXOverloadedOperator();
+  else
+    return OO_None;
+}
+
+/// getLiteralIdentifier - The literal suffix identifier this function
+/// represents, if any.
+const IdentifierInfo *FunctionDecl::getLiteralIdentifier() const {
+  if (getDeclName().getNameKind() == DeclarationName::CXXLiteralOperatorName)
+    return getDeclName().getCXXLiteralIdentifier();
+  else
+    return 0;
+}
+
+FunctionDecl *FunctionDecl::getInstantiatedFromMemberFunction() const {
+  if (MemberSpecializationInfo *Info = getMemberSpecializationInfo())
+    return cast<FunctionDecl>(Info->getInstantiatedFrom());
+  
+  return 0;
+}
+
+MemberSpecializationInfo *FunctionDecl::getMemberSpecializationInfo() const {
+  return TemplateOrSpecialization.dyn_cast<MemberSpecializationInfo*>();
+}
+
+void 
+FunctionDecl::setInstantiationOfMemberFunction(FunctionDecl *FD,
+                                               TemplateSpecializationKind TSK) {
+  assert(TemplateOrSpecialization.isNull() && 
+         "Member function is already a specialization");
+  MemberSpecializationInfo *Info 
+    = new (getASTContext()) MemberSpecializationInfo(FD, TSK);
+  TemplateOrSpecialization = Info;
+}
+
+bool FunctionDecl::isImplicitlyInstantiable() const {
+  // If this function already has a definition or is invalid, it can't be
+  // implicitly instantiated.
+  if (isInvalidDecl() || getBody())
+    return false;
+  
+  switch (getTemplateSpecializationKind()) {
+  case TSK_Undeclared:
+  case TSK_ExplicitSpecialization:
+  case TSK_ExplicitInstantiationDefinition:
+    return false;
+      
+  case TSK_ImplicitInstantiation:
+    return true;
+
+  case TSK_ExplicitInstantiationDeclaration:
+    // Handled below.
+    break;
+  }
+
+  // Find the actual template from which we will instantiate.
+  const FunctionDecl *PatternDecl = getTemplateInstantiationPattern();
+  Stmt *Pattern = 0;
+  if (PatternDecl)
+    Pattern = PatternDecl->getBody(PatternDecl);
+  
+  // C++0x [temp.explicit]p9:
+  //   Except for inline functions, other explicit instantiation declarations
+  //   have the effect of suppressing the implicit instantiation of the entity
+  //   to which they refer. 
+  if (!Pattern || !PatternDecl)
+    return true;
+
+  return PatternDecl->isInlined();
+}                      
+   
+FunctionDecl *FunctionDecl::getTemplateInstantiationPattern() const {
+  if (FunctionTemplateDecl *Primary = getPrimaryTemplate()) {
+    while (Primary->getInstantiatedFromMemberTemplate()) {
+      // If we have hit a point where the user provided a specialization of
+      // this template, we're done looking.
+      if (Primary->isMemberSpecialization())
+        break;
+      
+      Primary = Primary->getInstantiatedFromMemberTemplate();
+    }
+    
+    return Primary->getTemplatedDecl();
+  } 
+    
+  return getInstantiatedFromMemberFunction();
+}
+
+FunctionTemplateDecl *FunctionDecl::getPrimaryTemplate() const {
+  if (FunctionTemplateSpecializationInfo *Info
+        = TemplateOrSpecialization
+            .dyn_cast<FunctionTemplateSpecializationInfo*>()) {
+    return Info->Template.getPointer();
+  }
+  return 0;
+}
+
+const TemplateArgumentList *
+FunctionDecl::getTemplateSpecializationArgs() const {
+  if (FunctionTemplateSpecializationInfo *Info
+        = TemplateOrSpecialization
+            .dyn_cast<FunctionTemplateSpecializationInfo*>()) {
+    return Info->TemplateArguments;
+  }
+  return 0;
+}
+
+void
+FunctionDecl::setFunctionTemplateSpecialization(FunctionTemplateDecl *Template,
+                                     const TemplateArgumentList *TemplateArgs,
+                                                void *InsertPos,
+                                              TemplateSpecializationKind TSK) {
+  assert(TSK != TSK_Undeclared && 
+         "Must specify the type of function template specialization");
+  FunctionTemplateSpecializationInfo *Info
+    = TemplateOrSpecialization.dyn_cast<FunctionTemplateSpecializationInfo*>();
+  if (!Info)
+    Info = new (getASTContext()) FunctionTemplateSpecializationInfo;
+
+  Info->Function = this;
+  Info->Template.setPointer(Template);
+  Info->Template.setInt(TSK - 1);
+  Info->TemplateArguments = TemplateArgs;
+  TemplateOrSpecialization = Info;
+
+  // Insert this function template specialization into the set of known
+  // function template specializations.
+  if (InsertPos)
+    Template->getSpecializations().InsertNode(Info, InsertPos);
+  else {
+    // Try to insert the new node. If there is an existing node, remove it 
+    // first.
+    FunctionTemplateSpecializationInfo *Existing
+      = Template->getSpecializations().GetOrInsertNode(Info);
+    if (Existing) {
+      Template->getSpecializations().RemoveNode(Existing);
+      Template->getSpecializations().GetOrInsertNode(Info);
+    }
+  }
+}
+
+void
+FunctionDecl::setDependentTemplateSpecialization(ASTContext &Context,
+                                    const UnresolvedSetImpl &Templates,
+                             const TemplateArgumentListInfo &TemplateArgs) {
+  assert(TemplateOrSpecialization.isNull());
+  size_t Size = sizeof(DependentFunctionTemplateSpecializationInfo);
+  Size += Templates.size() * sizeof(FunctionTemplateDecl*);
+  Size += TemplateArgs.size() * sizeof(TemplateArgumentLoc);
+  void *Buffer = Context.Allocate(Size);
+  DependentFunctionTemplateSpecializationInfo *Info =
+    new (Buffer) DependentFunctionTemplateSpecializationInfo(Templates,
+                                                             TemplateArgs);
+  TemplateOrSpecialization = Info;
+}
+
+DependentFunctionTemplateSpecializationInfo::
+DependentFunctionTemplateSpecializationInfo(const UnresolvedSetImpl &Ts,
+                                      const TemplateArgumentListInfo &TArgs)
+  : AngleLocs(TArgs.getLAngleLoc(), TArgs.getRAngleLoc()) {
+
+  d.NumTemplates = Ts.size();
+  d.NumArgs = TArgs.size();
+
+  FunctionTemplateDecl **TsArray =
+    const_cast<FunctionTemplateDecl**>(getTemplates());
+  for (unsigned I = 0, E = Ts.size(); I != E; ++I)
+    TsArray[I] = cast<FunctionTemplateDecl>(Ts[I]->getUnderlyingDecl());
+
+  TemplateArgumentLoc *ArgsArray =
+    const_cast<TemplateArgumentLoc*>(getTemplateArgs());
+  for (unsigned I = 0, E = TArgs.size(); I != E; ++I)
+    new (&ArgsArray[I]) TemplateArgumentLoc(TArgs[I]);
+}
+
+TemplateSpecializationKind FunctionDecl::getTemplateSpecializationKind() const {
+  // For a function template specialization, query the specialization
+  // information object.
+  FunctionTemplateSpecializationInfo *FTSInfo
+    = TemplateOrSpecialization.dyn_cast<FunctionTemplateSpecializationInfo*>();
+  if (FTSInfo)
+    return FTSInfo->getTemplateSpecializationKind();
+
+  MemberSpecializationInfo *MSInfo
+    = TemplateOrSpecialization.dyn_cast<MemberSpecializationInfo*>();
+  if (MSInfo)
+    return MSInfo->getTemplateSpecializationKind();
+  
+  return TSK_Undeclared;
+}
+
+void
+FunctionDecl::setTemplateSpecializationKind(TemplateSpecializationKind TSK,
+                                          SourceLocation PointOfInstantiation) {
+  if (FunctionTemplateSpecializationInfo *FTSInfo
+        = TemplateOrSpecialization.dyn_cast<
+                                    FunctionTemplateSpecializationInfo*>()) {
+    FTSInfo->setTemplateSpecializationKind(TSK);
+    if (TSK != TSK_ExplicitSpecialization &&
+        PointOfInstantiation.isValid() &&
+        FTSInfo->getPointOfInstantiation().isInvalid())
+      FTSInfo->setPointOfInstantiation(PointOfInstantiation);
+  } else if (MemberSpecializationInfo *MSInfo
+             = TemplateOrSpecialization.dyn_cast<MemberSpecializationInfo*>()) {
+    MSInfo->setTemplateSpecializationKind(TSK);
+    if (TSK != TSK_ExplicitSpecialization &&
+        PointOfInstantiation.isValid() &&
+        MSInfo->getPointOfInstantiation().isInvalid())
+      MSInfo->setPointOfInstantiation(PointOfInstantiation);
+  } else
+    assert(false && "Function cannot have a template specialization kind");
+}
+
+SourceLocation FunctionDecl::getPointOfInstantiation() const {
+  if (FunctionTemplateSpecializationInfo *FTSInfo
+        = TemplateOrSpecialization.dyn_cast<
+                                        FunctionTemplateSpecializationInfo*>())
+    return FTSInfo->getPointOfInstantiation();
+  else if (MemberSpecializationInfo *MSInfo
+             = TemplateOrSpecialization.dyn_cast<MemberSpecializationInfo*>())
+    return MSInfo->getPointOfInstantiation();
+  
+  return SourceLocation();
+}
+
+bool FunctionDecl::isOutOfLine() const {
+  if (Decl::isOutOfLine())
+    return true;
+  
+  // If this function was instantiated from a member function of a 
+  // class template, check whether that member function was defined out-of-line.
+  if (FunctionDecl *FD = getInstantiatedFromMemberFunction()) {
+    const FunctionDecl *Definition;
+    if (FD->getBody(Definition))
+      return Definition->isOutOfLine();
+  }
+  
+  // If this function was instantiated from a function template,
+  // check whether that function template was defined out-of-line.
+  if (FunctionTemplateDecl *FunTmpl = getPrimaryTemplate()) {
+    const FunctionDecl *Definition;
+    if (FunTmpl->getTemplatedDecl()->getBody(Definition))
+      return Definition->isOutOfLine();
+  }
+  
+  return false;
+}
+
+//===----------------------------------------------------------------------===//
+// FieldDecl Implementation
+//===----------------------------------------------------------------------===//
+
+FieldDecl *FieldDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
+                             IdentifierInfo *Id, QualType T,
+                             TypeSourceInfo *TInfo, Expr *BW, bool Mutable) {
+  return new (C) FieldDecl(Decl::Field, DC, L, Id, T, TInfo, BW, Mutable);
+}
+
+bool FieldDecl::isAnonymousStructOrUnion() const {
+  if (!isImplicit() || getDeclName())
+    return false;
+
+  if (const RecordType *Record = getType()->getAs<RecordType>())
+    return Record->getDecl()->isAnonymousStructOrUnion();
+
+  return false;
+}
+
+//===----------------------------------------------------------------------===//
+// TagDecl Implementation
+//===----------------------------------------------------------------------===//
+
+void TagDecl::Destroy(ASTContext &C) {
+  if (hasExtInfo())
+    C.Deallocate(getExtInfo());
+  TypeDecl::Destroy(C);
+}
+
+SourceRange TagDecl::getSourceRange() const {
+  SourceLocation E = RBraceLoc.isValid() ? RBraceLoc : getLocation();
+  return SourceRange(TagKeywordLoc, E);
+}
+
+TagDecl* TagDecl::getCanonicalDecl() {
+  return getFirstDeclaration();
+}
+
+void TagDecl::startDefinition() {
+  if (TagType *TagT = const_cast<TagType *>(TypeForDecl->getAs<TagType>())) {
+    TagT->decl.setPointer(this);
+    TagT->decl.setInt(1);
+  }
+
+  if (isa<CXXRecordDecl>(this)) {
+    CXXRecordDecl *D = cast<CXXRecordDecl>(this);
+    struct CXXRecordDecl::DefinitionData *Data = 
+      new (getASTContext()) struct CXXRecordDecl::DefinitionData(D);
+    for (redecl_iterator I = redecls_begin(), E = redecls_end(); I != E; ++I)
+      cast<CXXRecordDecl>(*I)->DefinitionData = Data;
+  }
+}
+
+void TagDecl::completeDefinition() {
+  assert((!isa<CXXRecordDecl>(this) ||
+          cast<CXXRecordDecl>(this)->hasDefinition()) &&
+         "definition completed but not started");
+
+  IsDefinition = true;
+  if (TagType *TagT = const_cast<TagType *>(TypeForDecl->getAs<TagType>())) {
+    assert(TagT->decl.getPointer() == this &&
+           "Attempt to redefine a tag definition?");
+    TagT->decl.setInt(0);
+  }
+}
+
+TagDecl* TagDecl::getDefinition() const {
+  if (isDefinition())
+    return const_cast<TagDecl *>(this);
+
+  for (redecl_iterator R = redecls_begin(), REnd = redecls_end();
+       R != REnd; ++R)
+    if (R->isDefinition())
+      return *R;
+
+  return 0;
+}
+
+TagDecl::TagKind TagDecl::getTagKindForTypeSpec(unsigned TypeSpec) {
+  switch (TypeSpec) {
+  default: llvm_unreachable("unexpected type specifier");
+  case DeclSpec::TST_struct: return TK_struct;
+  case DeclSpec::TST_class: return TK_class;
+  case DeclSpec::TST_union: return TK_union;
+  case DeclSpec::TST_enum: return TK_enum;
+  }
+}
+
+void TagDecl::setQualifierInfo(NestedNameSpecifier *Qualifier,
+                               SourceRange QualifierRange) {
+  if (Qualifier) {
+    // Make sure the extended qualifier info is allocated.
+    if (!hasExtInfo())
+      TypedefDeclOrQualifier = new (getASTContext()) ExtInfo;
+    // Set qualifier info.
+    getExtInfo()->NNS = Qualifier;
+    getExtInfo()->NNSRange = QualifierRange;
+  }
+  else {
+    // Here Qualifier == 0, i.e., we are removing the qualifier (if any).
+    assert(QualifierRange.isInvalid());
+    if (hasExtInfo()) {
+      getASTContext().Deallocate(getExtInfo());
+      TypedefDeclOrQualifier = (TypedefDecl*) 0;
+    }
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// EnumDecl Implementation
+//===----------------------------------------------------------------------===//
+
+EnumDecl *EnumDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
+                           IdentifierInfo *Id, SourceLocation TKL,
+                           EnumDecl *PrevDecl) {
+  EnumDecl *Enum = new (C) EnumDecl(DC, L, Id, PrevDecl, TKL);
+  C.getTypeDeclType(Enum, PrevDecl);
+  return Enum;
+}
+
+void EnumDecl::Destroy(ASTContext& C) {
+  TagDecl::Destroy(C);
+}
+
+void EnumDecl::completeDefinition(QualType NewType,
+                                  QualType NewPromotionType) {
+  assert(!isDefinition() && "Cannot redefine enums!");
+  IntegerType = NewType;
+  PromotionType = NewPromotionType;
+  TagDecl::completeDefinition();
+}
+
+//===----------------------------------------------------------------------===//
+// RecordDecl Implementation
+//===----------------------------------------------------------------------===//
+
+RecordDecl::RecordDecl(Kind DK, TagKind TK, DeclContext *DC, SourceLocation L,
+                       IdentifierInfo *Id, RecordDecl *PrevDecl,
+                       SourceLocation TKL)
+  : TagDecl(DK, TK, DC, L, Id, PrevDecl, TKL) {
+  HasFlexibleArrayMember = false;
+  AnonymousStructOrUnion = false;
+  HasObjectMember = false;
+  assert(classof(static_cast<Decl*>(this)) && "Invalid Kind!");
+}
+
+RecordDecl *RecordDecl::Create(ASTContext &C, TagKind TK, DeclContext *DC,
+                               SourceLocation L, IdentifierInfo *Id,
+                               SourceLocation TKL, RecordDecl* PrevDecl) {
+
+  RecordDecl* R = new (C) RecordDecl(Record, TK, DC, L, Id, PrevDecl, TKL);
+  C.getTypeDeclType(R, PrevDecl);
+  return R;
+}
+
+RecordDecl::~RecordDecl() {
+}
+
+void RecordDecl::Destroy(ASTContext& C) {
+  TagDecl::Destroy(C);
+}
+
+bool RecordDecl::isInjectedClassName() const {
+  return isImplicit() && getDeclName() && getDeclContext()->isRecord() &&
+    cast<RecordDecl>(getDeclContext())->getDeclName() == getDeclName();
+}
+
+/// completeDefinition - Notes that the definition of this type is now
+/// complete.
+void RecordDecl::completeDefinition() {
+  assert(!isDefinition() && "Cannot redefine record!");
+  TagDecl::completeDefinition();
+}
+
+//===----------------------------------------------------------------------===//
+// BlockDecl Implementation
+//===----------------------------------------------------------------------===//
+
+BlockDecl::~BlockDecl() {
+}
+
+void BlockDecl::Destroy(ASTContext& C) {
+  if (Body)
+    Body->Destroy(C);
+
+  for (param_iterator I=param_begin(), E=param_end(); I!=E; ++I)
+    (*I)->Destroy(C);
+
+  C.Deallocate(ParamInfo);
+  Decl::Destroy(C);
+}
+
+void BlockDecl::setParams(ParmVarDecl **NewParamInfo,
+                          unsigned NParms) {
+  assert(ParamInfo == 0 && "Already has param info!");
+
+  // Zero params -> null pointer.
+  if (NParms) {
+    NumParams = NParms;
+    void *Mem = getASTContext().Allocate(sizeof(ParmVarDecl*)*NumParams);
+    ParamInfo = new (Mem) ParmVarDecl*[NumParams];
+    memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams);
+  }
+}
+
+unsigned BlockDecl::getNumParams() const {
+  return NumParams;
+}
+
+
+//===----------------------------------------------------------------------===//
+// Other Decl Allocation/Deallocation Method Implementations
+//===----------------------------------------------------------------------===//
+
+TranslationUnitDecl *TranslationUnitDecl::Create(ASTContext &C) {
+  return new (C) TranslationUnitDecl(C);
+}
+
+NamespaceDecl *NamespaceDecl::Create(ASTContext &C, DeclContext *DC,
+                                     SourceLocation L, IdentifierInfo *Id) {
+  return new (C) NamespaceDecl(DC, L, Id);
+}
+
+void NamespaceDecl::Destroy(ASTContext& C) {
+  // NamespaceDecl uses "NextDeclarator" to chain namespace declarations
+  // together. They are all top-level Decls.
+
+  this->~NamespaceDecl();
+  Decl::Destroy(C);
+}
+
+
+ImplicitParamDecl *ImplicitParamDecl::Create(ASTContext &C, DeclContext *DC,
+    SourceLocation L, IdentifierInfo *Id, QualType T) {
+  return new (C) ImplicitParamDecl(ImplicitParam, DC, L, Id, T);
+}
+
+FunctionDecl *FunctionDecl::Create(ASTContext &C, DeclContext *DC,
+                                   SourceLocation L,
+                                   DeclarationName N, QualType T,
+                                   TypeSourceInfo *TInfo,
+                                   StorageClass S, StorageClass SCAsWritten,
+                                   bool isInline, bool hasWrittenPrototype) {
+  FunctionDecl *New = new (C) FunctionDecl(Function, DC, L, N, T, TInfo,
+                                           S, SCAsWritten, isInline);
+  New->HasWrittenPrototype = hasWrittenPrototype;
+  return New;
+}
+
+BlockDecl *BlockDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L) {
+  return new (C) BlockDecl(DC, L);
+}
+
+EnumConstantDecl *EnumConstantDecl::Create(ASTContext &C, EnumDecl *CD,
+                                           SourceLocation L,
+                                           IdentifierInfo *Id, QualType T,
+                                           Expr *E, const llvm::APSInt &V) {
+  return new (C) EnumConstantDecl(CD, L, Id, T, E, V);
+}
+
+void EnumConstantDecl::Destroy(ASTContext& C) {
+  if (Init) Init->Destroy(C);
+  ValueDecl::Destroy(C);
+}
+
+TypedefDecl *TypedefDecl::Create(ASTContext &C, DeclContext *DC,
+                                 SourceLocation L, IdentifierInfo *Id,
+                                 TypeSourceInfo *TInfo) {
+  return new (C) TypedefDecl(DC, L, Id, TInfo);
+}
+
+// Anchor TypedefDecl's vtable here.
+TypedefDecl::~TypedefDecl() {}
+
+FileScopeAsmDecl *FileScopeAsmDecl::Create(ASTContext &C, DeclContext *DC,
+                                           SourceLocation L,
+                                           StringLiteral *Str) {
+  return new (C) FileScopeAsmDecl(DC, L, Str);
+}
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp
new file mode 100644
index 0000000..b5aec0c
--- /dev/null
+++ b/lib/AST/DeclBase.cpp
@@ -0,0 +1,1024 @@
+//===--- DeclBase.cpp - Declaration AST Node Implementation ---------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Decl and DeclContext classes.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/DeclBase.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclContextInternals.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclFriend.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/DependentDiagnostic.h"
+#include "clang/AST/ExternalASTSource.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/Stmt.h"
+#include "clang/AST/StmtCXX.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <cstdio>
+#include <vector>
+using namespace clang;
+
+//===----------------------------------------------------------------------===//
+//  Statistics
+//===----------------------------------------------------------------------===//
+
+#define DECL(Derived, Base) static int n##Derived##s = 0;
+#include "clang/AST/DeclNodes.def"
+
+static bool StatSwitch = false;
+
+const char *Decl::getDeclKindName() const {
+  switch (DeclKind) {
+  default: assert(0 && "Declaration not in DeclNodes.def!");
+#define DECL(Derived, Base) case Derived: return #Derived;
+#include "clang/AST/DeclNodes.def"
+  }
+}
+
+void Decl::setInvalidDecl(bool Invalid) {
+  InvalidDecl = Invalid;
+  if (Invalid) {
+    // Defensive maneuver for ill-formed code: we're likely not to make it to
+    // a point where we set the access specifier, so default it to "public"
+    // to avoid triggering asserts elsewhere in the front end. 
+    setAccess(AS_public);
+  }
+}
+
+const char *DeclContext::getDeclKindName() const {
+  switch (DeclKind) {
+  default: assert(0 && "Declaration context not in DeclNodes.def!");
+#define DECL(Derived, Base) case Decl::Derived: return #Derived;
+#include "clang/AST/DeclNodes.def"
+  }
+}
+
+bool Decl::CollectingStats(bool Enable) {
+  if (Enable) StatSwitch = true;
+  return StatSwitch;
+}
+
+void Decl::PrintStats() {
+  fprintf(stderr, "*** Decl Stats:\n");
+
+  int totalDecls = 0;
+#define DECL(Derived, Base) totalDecls += n##Derived##s;
+#include "clang/AST/DeclNodes.def"
+  fprintf(stderr, "  %d decls total.\n", totalDecls);
+
+  int totalBytes = 0;
+#define DECL(Derived, Base)                                             \
+  if (n##Derived##s > 0) {                                              \
+    totalBytes += (int)(n##Derived##s * sizeof(Derived##Decl));         \
+    fprintf(stderr, "    %d " #Derived " decls, %d each (%d bytes)\n",  \
+            n##Derived##s, (int)sizeof(Derived##Decl),                  \
+            (int)(n##Derived##s * sizeof(Derived##Decl)));              \
+  }
+#include "clang/AST/DeclNodes.def"
+
+  fprintf(stderr, "Total bytes = %d\n", totalBytes);
+}
+
+void Decl::addDeclKind(Kind k) {
+  switch (k) {
+  default: assert(0 && "Declaration not in DeclNodes.def!");
+#define DECL(Derived, Base) case Derived: ++n##Derived##s; break;
+#include "clang/AST/DeclNodes.def"
+  }
+}
+
+bool Decl::isTemplateParameterPack() const {
+  if (const TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(this))
+    return TTP->isParameterPack();
+
+  return false;
+}
+
+bool Decl::isFunctionOrFunctionTemplate() const {
+  if (const UsingShadowDecl *UD = dyn_cast<UsingShadowDecl>(this))
+    return UD->getTargetDecl()->isFunctionOrFunctionTemplate();
+
+  return isa<FunctionDecl>(this) || isa<FunctionTemplateDecl>(this);
+}
+
+bool Decl::isDefinedOutsideFunctionOrMethod() const {
+  for (const DeclContext *DC = getDeclContext(); 
+       DC && !DC->isTranslationUnit(); 
+       DC = DC->getParent())
+    if (DC->isFunctionOrMethod())
+      return false;
+
+  return true;
+}
+
+
+//===----------------------------------------------------------------------===//
+// PrettyStackTraceDecl Implementation
+//===----------------------------------------------------------------------===//
+
+void PrettyStackTraceDecl::print(llvm::raw_ostream &OS) const {
+  SourceLocation TheLoc = Loc;
+  if (TheLoc.isInvalid() && TheDecl)
+    TheLoc = TheDecl->getLocation();
+
+  if (TheLoc.isValid()) {
+    TheLoc.print(OS, SM);
+    OS << ": ";
+  }
+
+  OS << Message;
+
+  if (const NamedDecl *DN = dyn_cast_or_null<NamedDecl>(TheDecl))
+    OS << " '" << DN->getQualifiedNameAsString() << '\'';
+  OS << '\n';
+}
+
+//===----------------------------------------------------------------------===//
+// Decl Implementation
+//===----------------------------------------------------------------------===//
+
+// Out-of-line virtual method providing a home for Decl.
+Decl::~Decl() {
+  assert(!HasAttrs && "attributes should have been freed by Destroy");
+}
+
+void Decl::setDeclContext(DeclContext *DC) {
+  if (isOutOfSemaDC())
+    delete getMultipleDC();
+
+  DeclCtx = DC;
+}
+
+void Decl::setLexicalDeclContext(DeclContext *DC) {
+  if (DC == getLexicalDeclContext())
+    return;
+
+  if (isInSemaDC()) {
+    MultipleDC *MDC = new (getASTContext()) MultipleDC();
+    MDC->SemanticDC = getDeclContext();
+    MDC->LexicalDC = DC;
+    DeclCtx = MDC;
+  } else {
+    getMultipleDC()->LexicalDC = DC;
+  }
+}
+
+bool Decl::isInAnonymousNamespace() const {
+  const DeclContext *DC = getDeclContext();
+  do {
+    if (const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(DC))
+      if (ND->isAnonymousNamespace())
+        return true;
+  } while ((DC = DC->getParent()));
+
+  return false;
+}
+
+TranslationUnitDecl *Decl::getTranslationUnitDecl() {
+  if (TranslationUnitDecl *TUD = dyn_cast<TranslationUnitDecl>(this))
+    return TUD;
+
+  DeclContext *DC = getDeclContext();
+  assert(DC && "This decl is not contained in a translation unit!");
+
+  while (!DC->isTranslationUnit()) {
+    DC = DC->getParent();
+    assert(DC && "This decl is not contained in a translation unit!");
+  }
+
+  return cast<TranslationUnitDecl>(DC);
+}
+
+ASTContext &Decl::getASTContext() const {
+  return getTranslationUnitDecl()->getASTContext();
+}
+
+bool Decl::isUsed() const { 
+  if (Used)
+    return true;
+  
+  // Check for used attribute.
+  if (hasAttr<UsedAttr>())
+    return true;
+  
+  // Check redeclarations for used attribute.
+  for (redecl_iterator I = redecls_begin(), E = redecls_end(); I != E; ++I) {
+    if (I->hasAttr<UsedAttr>() || I->Used)
+      return true;
+  }
+  
+  return false; 
+}
+
+
+unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) {
+  switch (DeclKind) {
+    case Function:
+    case CXXMethod:
+    case CXXConstructor:
+    case CXXDestructor:
+    case CXXConversion:
+    case EnumConstant:
+    case Var:
+    case ImplicitParam:
+    case ParmVar:
+    case NonTypeTemplateParm:
+    case ObjCMethod:
+    case ObjCProperty:
+      return IDNS_Ordinary;
+
+    case ObjCCompatibleAlias:
+    case ObjCInterface:
+      return IDNS_Ordinary | IDNS_Type;
+
+    case Typedef:
+    case UnresolvedUsingTypename:
+    case TemplateTypeParm:
+      return IDNS_Ordinary | IDNS_Type;
+
+    case UsingShadow:
+      return 0; // we'll actually overwrite this later
+
+    case UnresolvedUsingValue:
+      return IDNS_Ordinary | IDNS_Using;
+
+    case Using:
+      return IDNS_Using;
+
+    case ObjCProtocol:
+      return IDNS_ObjCProtocol;
+
+    case Field:
+    case ObjCAtDefsField:
+    case ObjCIvar:
+      return IDNS_Member;
+
+    case Record:
+    case CXXRecord:
+    case Enum:
+      return IDNS_Tag | IDNS_Type;
+
+    case Namespace:
+    case NamespaceAlias:
+      return IDNS_Namespace;
+
+    case FunctionTemplate:
+      return IDNS_Ordinary;
+
+    case ClassTemplate:
+    case TemplateTemplateParm:
+      return IDNS_Ordinary | IDNS_Tag | IDNS_Type;
+
+    // Never have names.
+    case Friend:
+    case FriendTemplate:
+    case LinkageSpec:
+    case FileScopeAsm:
+    case StaticAssert:
+    case ObjCClass:
+    case ObjCPropertyImpl:
+    case ObjCForwardProtocol:
+    case Block:
+    case TranslationUnit:
+
+    case UsingDirective:
+    case ClassTemplateSpecialization:
+    case ClassTemplatePartialSpecialization:
+    case ObjCImplementation:
+    case ObjCCategory:
+    case ObjCCategoryImpl:
+      // Never looked up by name.
+      return 0;
+  }
+
+  return 0;
+}
+
+void Decl::addAttr(Attr *NewAttr) {
+  Attr *&ExistingAttr = getASTContext().getDeclAttrs(this);
+
+  NewAttr->setNext(ExistingAttr);
+  ExistingAttr = NewAttr;
+
+  HasAttrs = true;
+}
+
+void Decl::invalidateAttrs() {
+  if (!HasAttrs) return;
+
+  HasAttrs = false;
+  getASTContext().eraseDeclAttrs(this);
+}
+
+const Attr *Decl::getAttrsImpl() const {
+  assert(HasAttrs && "getAttrs() should verify this!");
+  return getASTContext().getDeclAttrs(this);
+}
+
+void Decl::swapAttrs(Decl *RHS) {
+  bool HasLHSAttr = this->HasAttrs;
+  bool HasRHSAttr = RHS->HasAttrs;
+
+  // Usually, neither decl has attrs, nothing to do.
+  if (!HasLHSAttr && !HasRHSAttr) return;
+
+  // If 'this' has no attrs, swap the other way.
+  if (!HasLHSAttr)
+    return RHS->swapAttrs(this);
+
+  ASTContext &Context = getASTContext();
+
+  // Handle the case when both decls have attrs.
+  if (HasRHSAttr) {
+    std::swap(Context.getDeclAttrs(this), Context.getDeclAttrs(RHS));
+    return;
+  }
+
+  // Otherwise, LHS has an attr and RHS doesn't.
+  Context.getDeclAttrs(RHS) = Context.getDeclAttrs(this);
+  Context.eraseDeclAttrs(this);
+  this->HasAttrs = false;
+  RHS->HasAttrs = true;
+}
+
+
+void Decl::Destroy(ASTContext &C) {
+  // Free attributes for this decl.
+  if (HasAttrs) {
+    C.getDeclAttrs(this)->Destroy(C);
+    invalidateAttrs();
+    HasAttrs = false;
+  }
+
+#if 0
+  // FIXME: Once ownership is fully understood, we can enable this code
+  if (DeclContext *DC = dyn_cast<DeclContext>(this))
+    DC->decls_begin()->Destroy(C);
+
+  // Observe the unrolled recursion.  By setting N->NextDeclInContext = 0x0
+  // within the loop, only the Destroy method for the first Decl
+  // will deallocate all of the Decls in a chain.
+
+  Decl* N = getNextDeclInContext();
+
+  while (N) {
+    Decl* Tmp = N->getNextDeclInContext();
+    N->NextDeclInContext = 0;
+    N->Destroy(C);
+    N = Tmp;
+  }
+
+  if (isOutOfSemaDC())
+    delete (C) getMultipleDC();
+  
+  this->~Decl();
+  C.Deallocate((void *)this);
+#endif  
+}
+
+Decl *Decl::castFromDeclContext (const DeclContext *D) {
+  Decl::Kind DK = D->getDeclKind();
+  switch(DK) {
+#define DECL_CONTEXT(Name) \
+    case Decl::Name:     \
+      return static_cast<Name##Decl*>(const_cast<DeclContext*>(D));
+#define DECL_CONTEXT_BASE(Name)
+#include "clang/AST/DeclNodes.def"
+    default:
+#define DECL_CONTEXT_BASE(Name)                                   \
+      if (DK >= Decl::Name##First && DK <= Decl::Name##Last)    \
+        return static_cast<Name##Decl*>(const_cast<DeclContext*>(D));
+#include "clang/AST/DeclNodes.def"
+      assert(false && "a decl that inherits DeclContext isn't handled");
+      return 0;
+  }
+}
+
+DeclContext *Decl::castToDeclContext(const Decl *D) {
+  Decl::Kind DK = D->getKind();
+  switch(DK) {
+#define DECL_CONTEXT(Name) \
+    case Decl::Name:     \
+      return static_cast<Name##Decl*>(const_cast<Decl*>(D));
+#define DECL_CONTEXT_BASE(Name)
+#include "clang/AST/DeclNodes.def"
+    default:
+#define DECL_CONTEXT_BASE(Name)                                   \
+      if (DK >= Decl::Name##First && DK <= Decl::Name##Last)    \
+        return static_cast<Name##Decl*>(const_cast<Decl*>(D));
+#include "clang/AST/DeclNodes.def"
+      assert(false && "a decl that inherits DeclContext isn't handled");
+      return 0;
+  }
+}
+
+CompoundStmt* Decl::getCompoundBody() const {
+  return dyn_cast_or_null<CompoundStmt>(getBody());
+}
+
+SourceLocation Decl::getBodyRBrace() const {
+  Stmt *Body = getBody();
+  if (!Body)
+    return SourceLocation();
+  if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Body))
+    return CS->getRBracLoc();
+  assert(isa<CXXTryStmt>(Body) &&
+         "Body can only be CompoundStmt or CXXTryStmt");
+  return cast<CXXTryStmt>(Body)->getSourceRange().getEnd();
+}
+
+#ifndef NDEBUG
+void Decl::CheckAccessDeclContext() const {
+  // Suppress this check if any of the following hold:
+  // 1. this is the translation unit (and thus has no parent)
+  // 2. this is a template parameter (and thus doesn't belong to its context)
+  // 3. this is a ParmVarDecl (which can be in a record context during
+  //    the brief period between its creation and the creation of the
+  //    FunctionDecl)
+  // 4. the context is not a record
+  if (isa<TranslationUnitDecl>(this) ||
+      !isa<CXXRecordDecl>(getDeclContext()) ||
+      isInvalidDecl())
+    return;
+
+  assert(Access != AS_none &&
+         "Access specifier is AS_none inside a record decl");
+}
+
+#endif
+
+//===----------------------------------------------------------------------===//
+// DeclContext Implementation
+//===----------------------------------------------------------------------===//
+
+bool DeclContext::classof(const Decl *D) {
+  switch (D->getKind()) {
+#define DECL_CONTEXT(Name) case Decl::Name:
+#define DECL_CONTEXT_BASE(Name)
+#include "clang/AST/DeclNodes.def"
+      return true;
+    default:
+#define DECL_CONTEXT_BASE(Name)                   \
+      if (D->getKind() >= Decl::Name##First &&  \
+          D->getKind() <= Decl::Name##Last)     \
+        return true;
+#include "clang/AST/DeclNodes.def"
+      return false;
+  }
+}
+
+DeclContext::~DeclContext() {
+  // FIXME: Currently ~ASTContext will delete the StoredDeclsMaps because
+  // ~DeclContext() is not guaranteed to be called when ASTContext uses
+  // a BumpPtrAllocator.
+  // delete LookupPtr;
+}
+
+void DeclContext::DestroyDecls(ASTContext &C) {
+  for (decl_iterator D = decls_begin(); D != decls_end(); )
+    (*D++)->Destroy(C);
+}
+
+/// \brief Find the parent context of this context that will be
+/// used for unqualified name lookup.
+///
+/// Generally, the parent lookup context is the semantic context. However, for
+/// a friend function the parent lookup context is the lexical context, which
+/// is the class in which the friend is declared.
+DeclContext *DeclContext::getLookupParent() {
+  // FIXME: Find a better way to identify friends
+  if (isa<FunctionDecl>(this))
+    if (getParent()->getLookupContext()->isFileContext() &&
+        getLexicalParent()->getLookupContext()->isRecord())
+      return getLexicalParent();
+  
+  return getParent();
+}
+
+bool DeclContext::isDependentContext() const {
+  if (isFileContext())
+    return false;
+
+  if (isa<ClassTemplatePartialSpecializationDecl>(this))
+    return true;
+
+  if (const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(this))
+    if (Record->getDescribedClassTemplate())
+      return true;
+
+  if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(this)) {
+    if (Function->getDescribedFunctionTemplate())
+      return true;
+
+    // Friend function declarations are dependent if their *lexical*
+    // context is dependent.
+    if (cast<Decl>(this)->getFriendObjectKind())
+      return getLexicalParent()->isDependentContext();
+  }
+
+  return getParent() && getParent()->isDependentContext();
+}
+
+bool DeclContext::isTransparentContext() const {
+  if (DeclKind == Decl::Enum)
+    return true; // FIXME: Check for C++0x scoped enums
+  else if (DeclKind == Decl::LinkageSpec)
+    return true;
+  else if (DeclKind >= Decl::RecordFirst && DeclKind <= Decl::RecordLast)
+    return cast<RecordDecl>(this)->isAnonymousStructOrUnion();
+  else if (DeclKind == Decl::Namespace)
+    return false; // FIXME: Check for C++0x inline namespaces
+
+  return false;
+}
+
+bool DeclContext::Encloses(DeclContext *DC) {
+  if (getPrimaryContext() != this)
+    return getPrimaryContext()->Encloses(DC);
+
+  for (; DC; DC = DC->getParent())
+    if (DC->getPrimaryContext() == this)
+      return true;
+  return false;
+}
+
+DeclContext *DeclContext::getPrimaryContext() {
+  switch (DeclKind) {
+  case Decl::TranslationUnit:
+  case Decl::LinkageSpec:
+  case Decl::Block:
+    // There is only one DeclContext for these entities.
+    return this;
+
+  case Decl::Namespace:
+    // The original namespace is our primary context.
+    return static_cast<NamespaceDecl*>(this)->getOriginalNamespace();
+
+  case Decl::ObjCMethod:
+    return this;
+
+  case Decl::ObjCInterface:
+  case Decl::ObjCProtocol:
+  case Decl::ObjCCategory:
+    // FIXME: Can Objective-C interfaces be forward-declared?
+    return this;
+
+  case Decl::ObjCImplementation:
+  case Decl::ObjCCategoryImpl:
+    return this;
+
+  default:
+    if (DeclKind >= Decl::TagFirst && DeclKind <= Decl::TagLast) {
+      // If this is a tag type that has a definition or is currently
+      // being defined, that definition is our primary context.
+      TagDecl *Tag = cast<TagDecl>(this);
+      assert(isa<TagType>(Tag->TypeForDecl) ||
+             isa<InjectedClassNameType>(Tag->TypeForDecl));
+
+      if (TagDecl *Def = Tag->getDefinition())
+        return Def;
+
+      if (!isa<InjectedClassNameType>(Tag->TypeForDecl)) {
+        const TagType *TagTy = cast<TagType>(Tag->TypeForDecl);
+        if (TagTy->isBeingDefined())
+          // FIXME: is it necessarily being defined in the decl
+          // that owns the type?
+          return TagTy->getDecl();
+      }
+
+      return Tag;
+    }
+
+    assert(DeclKind >= Decl::FunctionFirst && DeclKind <= Decl::FunctionLast &&
+          "Unknown DeclContext kind");
+    return this;
+  }
+}
+
+DeclContext *DeclContext::getNextContext() {
+  switch (DeclKind) {
+  case Decl::Namespace:
+    // Return the next namespace
+    return static_cast<NamespaceDecl*>(this)->getNextNamespace();
+
+  default:
+    return 0;
+  }
+}
+
+/// \brief Load the declarations within this lexical storage from an
+/// external source.
+void
+DeclContext::LoadLexicalDeclsFromExternalStorage() const {
+  ExternalASTSource *Source = getParentASTContext().getExternalSource();
+  assert(hasExternalLexicalStorage() && Source && "No external storage?");
+
+  llvm::SmallVector<uint32_t, 64> Decls;
+  if (Source->ReadDeclsLexicallyInContext(const_cast<DeclContext *>(this),
+                                          Decls))
+    return;
+
+  // There is no longer any lexical storage in this context
+  ExternalLexicalStorage = false;
+
+  if (Decls.empty())
+    return;
+
+  // Resolve all of the declaration IDs into declarations, building up
+  // a chain of declarations via the Decl::NextDeclInContext field.
+  Decl *FirstNewDecl = 0;
+  Decl *PrevDecl = 0;
+  for (unsigned I = 0, N = Decls.size(); I != N; ++I) {
+    Decl *D = Source->GetDecl(Decls[I]);
+    if (PrevDecl)
+      PrevDecl->NextDeclInContext = D;
+    else
+      FirstNewDecl = D;
+
+    PrevDecl = D;
+  }
+
+  // Splice the newly-read declarations into the beginning of the list
+  // of declarations.
+  PrevDecl->NextDeclInContext = FirstDecl;
+  FirstDecl = FirstNewDecl;
+  if (!LastDecl)
+    LastDecl = PrevDecl;
+}
+
+void
+DeclContext::LoadVisibleDeclsFromExternalStorage() const {
+  DeclContext *This = const_cast<DeclContext *>(this);
+  ExternalASTSource *Source = getParentASTContext().getExternalSource();
+  assert(hasExternalVisibleStorage() && Source && "No external storage?");
+
+  llvm::SmallVector<VisibleDeclaration, 64> Decls;
+  if (Source->ReadDeclsVisibleInContext(This, Decls))
+    return;
+
+  // There is no longer any visible storage in this context
+  ExternalVisibleStorage = false;
+
+  // Load the declaration IDs for all of the names visible in this
+  // context.
+  assert(!LookupPtr && "Have a lookup map before de-serialization?");
+  StoredDeclsMap *Map = CreateStoredDeclsMap(getParentASTContext());
+  for (unsigned I = 0, N = Decls.size(); I != N; ++I) {
+    (*Map)[Decls[I].Name].setFromDeclIDs(Decls[I].Declarations);
+  }
+}
+
+DeclContext::decl_iterator DeclContext::decls_begin() const {
+  if (hasExternalLexicalStorage())
+    LoadLexicalDeclsFromExternalStorage();
+
+  // FIXME: Check whether we need to load some declarations from
+  // external storage.
+  return decl_iterator(FirstDecl);
+}
+
+DeclContext::decl_iterator DeclContext::decls_end() const {
+  if (hasExternalLexicalStorage())
+    LoadLexicalDeclsFromExternalStorage();
+
+  return decl_iterator();
+}
+
+bool DeclContext::decls_empty() const {
+  if (hasExternalLexicalStorage())
+    LoadLexicalDeclsFromExternalStorage();
+
+  return !FirstDecl;
+}
+
+void DeclContext::removeDecl(Decl *D) {
+  assert(D->getLexicalDeclContext() == this &&
+         "decl being removed from non-lexical context");
+  assert((D->NextDeclInContext || D == LastDecl) &&
+         "decl is not in decls list");
+
+  // Remove D from the decl chain.  This is O(n) but hopefully rare.
+  if (D == FirstDecl) {
+    if (D == LastDecl)
+      FirstDecl = LastDecl = 0;
+    else
+      FirstDecl = D->NextDeclInContext;
+  } else {
+    for (Decl *I = FirstDecl; true; I = I->NextDeclInContext) {
+      assert(I && "decl not found in linked list");
+      if (I->NextDeclInContext == D) {
+        I->NextDeclInContext = D->NextDeclInContext;
+        if (D == LastDecl) LastDecl = I;
+        break;
+      }
+    }
+  }
+  
+  // Mark that D is no longer in the decl chain.
+  D->NextDeclInContext = 0;
+
+  // Remove D from the lookup table if necessary.
+  if (isa<NamedDecl>(D)) {
+    NamedDecl *ND = cast<NamedDecl>(D);
+
+    StoredDeclsMap *Map = getPrimaryContext()->LookupPtr;
+    if (!Map) return;
+
+    StoredDeclsMap::iterator Pos = Map->find(ND->getDeclName());
+    assert(Pos != Map->end() && "no lookup entry for decl");
+    Pos->second.remove(ND);
+  }
+}
+
+void DeclContext::addHiddenDecl(Decl *D) {
+  assert(D->getLexicalDeclContext() == this &&
+         "Decl inserted into wrong lexical context");
+  assert(!D->getNextDeclInContext() && D != LastDecl &&
+         "Decl already inserted into a DeclContext");
+
+  if (FirstDecl) {
+    LastDecl->NextDeclInContext = D;
+    LastDecl = D;
+  } else {
+    FirstDecl = LastDecl = D;
+  }
+}
+
+void DeclContext::addDecl(Decl *D) {
+  addHiddenDecl(D);
+
+  if (NamedDecl *ND = dyn_cast<NamedDecl>(D))
+    ND->getDeclContext()->makeDeclVisibleInContext(ND);
+}
+
+/// buildLookup - Build the lookup data structure with all of the
+/// declarations in DCtx (and any other contexts linked to it or
+/// transparent contexts nested within it).
+void DeclContext::buildLookup(DeclContext *DCtx) {
+  for (; DCtx; DCtx = DCtx->getNextContext()) {
+    for (decl_iterator D = DCtx->decls_begin(),
+                    DEnd = DCtx->decls_end();
+         D != DEnd; ++D) {
+      // Insert this declaration into the lookup structure, but only
+      // if it's semantically in its decl context.  During non-lazy
+      // lookup building, this is implicitly enforced by addDecl.
+      if (NamedDecl *ND = dyn_cast<NamedDecl>(*D))
+        if (D->getDeclContext() == DCtx)
+          makeDeclVisibleInContextImpl(ND);
+
+      // Insert any forward-declared Objective-C interfaces into the lookup
+      // data structure.
+      if (ObjCClassDecl *Class = dyn_cast<ObjCClassDecl>(*D))
+        for (ObjCClassDecl::iterator I = Class->begin(), IEnd = Class->end();
+             I != IEnd; ++I)
+          makeDeclVisibleInContextImpl(I->getInterface());
+      
+      // If this declaration is itself a transparent declaration context,
+      // add its members (recursively).
+      if (DeclContext *InnerCtx = dyn_cast<DeclContext>(*D))
+        if (InnerCtx->isTransparentContext())
+          buildLookup(InnerCtx->getPrimaryContext());
+    }
+  }
+}
+
+DeclContext::lookup_result
+DeclContext::lookup(DeclarationName Name) {
+  DeclContext *PrimaryContext = getPrimaryContext();
+  if (PrimaryContext != this)
+    return PrimaryContext->lookup(Name);
+
+  if (hasExternalVisibleStorage())
+    LoadVisibleDeclsFromExternalStorage();
+
+  /// If there is no lookup data structure, build one now by walking
+  /// all of the linked DeclContexts (in declaration order!) and
+  /// inserting their values.
+  if (!LookupPtr) {
+    buildLookup(this);
+
+    if (!LookupPtr)
+      return lookup_result(0, 0);
+  }
+
+  StoredDeclsMap::iterator Pos = LookupPtr->find(Name);
+  if (Pos == LookupPtr->end())
+    return lookup_result(0, 0);
+  return Pos->second.getLookupResult(getParentASTContext());
+}
+
+DeclContext::lookup_const_result
+DeclContext::lookup(DeclarationName Name) const {
+  return const_cast<DeclContext*>(this)->lookup(Name);
+}
+
+DeclContext *DeclContext::getLookupContext() {
+  DeclContext *Ctx = this;
+  // Skip through transparent contexts.
+  while (Ctx->isTransparentContext())
+    Ctx = Ctx->getParent();
+  return Ctx;
+}
+
+DeclContext *DeclContext::getEnclosingNamespaceContext() {
+  DeclContext *Ctx = this;
+  // Skip through non-namespace, non-translation-unit contexts.
+  while (!Ctx->isFileContext() || Ctx->isTransparentContext())
+    Ctx = Ctx->getParent();
+  return Ctx->getPrimaryContext();
+}
+
+void DeclContext::makeDeclVisibleInContext(NamedDecl *D, bool Recoverable) {
+  // FIXME: This feels like a hack. Should DeclarationName support
+  // template-ids, or is there a better way to keep specializations
+  // from being visible?
+  if (isa<ClassTemplateSpecializationDecl>(D))
+    return;
+  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
+    if (FD->isFunctionTemplateSpecialization())
+      return;
+
+  DeclContext *PrimaryContext = getPrimaryContext();
+  if (PrimaryContext != this) {
+    PrimaryContext->makeDeclVisibleInContext(D, Recoverable);
+    return;
+  }
+
+  // If we already have a lookup data structure, perform the insertion
+  // into it. Otherwise, be lazy and don't build that structure until
+  // someone asks for it.
+  if (LookupPtr || !Recoverable)
+    makeDeclVisibleInContextImpl(D);
+
+  // If we are a transparent context, insert into our parent context,
+  // too. This operation is recursive.
+  if (isTransparentContext())
+    getParent()->makeDeclVisibleInContext(D, Recoverable);
+}
+
+void DeclContext::makeDeclVisibleInContextImpl(NamedDecl *D) {
+  // Skip unnamed declarations.
+  if (!D->getDeclName())
+    return;
+
+  // FIXME: This feels like a hack. Should DeclarationName support
+  // template-ids, or is there a better way to keep specializations
+  // from being visible?
+  if (isa<ClassTemplateSpecializationDecl>(D))
+    return;
+
+  ASTContext *C = 0;
+  if (!LookupPtr) {
+    C = &getParentASTContext();
+    CreateStoredDeclsMap(*C);
+  }
+
+  // Insert this declaration into the map.
+  StoredDeclsList &DeclNameEntries = (*LookupPtr)[D->getDeclName()];
+  if (DeclNameEntries.isNull()) {
+    DeclNameEntries.setOnlyValue(D);
+    return;
+  }
+
+  // If it is possible that this is a redeclaration, check to see if there is
+  // already a decl for which declarationReplaces returns true.  If there is
+  // one, just replace it and return.
+  if (!C)
+    C = &getParentASTContext();
+  
+  if (DeclNameEntries.HandleRedeclaration(*C, D))
+    return;
+
+  // Put this declaration into the appropriate slot.
+  DeclNameEntries.AddSubsequentDecl(D);
+}
+
+/// Returns iterator range [First, Last) of UsingDirectiveDecls stored within
+/// this context.
+DeclContext::udir_iterator_range
+DeclContext::getUsingDirectives() const {
+  lookup_const_result Result = lookup(UsingDirectiveDecl::getName());
+  return udir_iterator_range(reinterpret_cast<udir_iterator>(Result.first),
+                             reinterpret_cast<udir_iterator>(Result.second));
+}
+
+void StoredDeclsList::materializeDecls(ASTContext &Context) {
+  if (isNull())
+    return;
+
+  switch ((DataKind)(Data & 0x03)) {
+  case DK_Decl:
+  case DK_Decl_Vector:
+    break;
+
+  case DK_DeclID: {
+    // Resolve this declaration ID to an actual declaration by
+    // querying the external AST source.
+    unsigned DeclID = Data >> 2;
+
+    ExternalASTSource *Source = Context.getExternalSource();
+    assert(Source && "No external AST source available!");
+
+    Data = reinterpret_cast<uintptr_t>(Source->GetDecl(DeclID));
+    break;
+  }
+
+  case DK_ID_Vector: {
+    // We have a vector of declaration IDs. Resolve all of them to
+    // actual declarations.
+    VectorTy &Vector = *getAsVector();
+    ExternalASTSource *Source = Context.getExternalSource();
+    assert(Source && "No external AST source available!");
+
+    for (unsigned I = 0, N = Vector.size(); I != N; ++I)
+      Vector[I] = reinterpret_cast<uintptr_t>(Source->GetDecl(Vector[I]));
+
+    Data = (Data & ~0x03) | DK_Decl_Vector;
+    break;
+  }
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// Creation and Destruction of StoredDeclsMaps.                               //
+//===----------------------------------------------------------------------===//
+
+StoredDeclsMap *DeclContext::CreateStoredDeclsMap(ASTContext &C) const {
+  assert(!LookupPtr && "context already has a decls map");
+  assert(getPrimaryContext() == this &&
+         "creating decls map on non-primary context");
+
+  StoredDeclsMap *M;
+  bool Dependent = isDependentContext();
+  if (Dependent)
+    M = new DependentStoredDeclsMap();
+  else
+    M = new StoredDeclsMap();
+  M->Previous = C.LastSDM;
+  C.LastSDM = llvm::PointerIntPair<StoredDeclsMap*,1>(M, Dependent);
+  LookupPtr = M;
+  return M;
+}
+
+void ASTContext::ReleaseDeclContextMaps() {
+  // It's okay to delete DependentStoredDeclsMaps via a StoredDeclsMap
+  // pointer because the subclass doesn't add anything that needs to
+  // be deleted.
+  
+  StoredDeclsMap::DestroyAll(LastSDM.getPointer(), LastSDM.getInt());
+}
+
+void StoredDeclsMap::DestroyAll(StoredDeclsMap *Map, bool Dependent) {
+  while (Map) {
+    // Advance the iteration before we invalidate memory.
+    llvm::PointerIntPair<StoredDeclsMap*,1> Next = Map->Previous;
+
+    if (Dependent)
+      delete static_cast<DependentStoredDeclsMap*>(Map);
+    else
+      delete Map;
+
+    Map = Next.getPointer();
+    Dependent = Next.getInt();
+  }
+}
+
+DependentDiagnostic *DependentDiagnostic::Create(ASTContext &C,
+                                                 DeclContext *Parent,
+                                           const PartialDiagnostic &PDiag) {
+  assert(Parent->isDependentContext()
+         && "cannot iterate dependent diagnostics of non-dependent context");
+  Parent = Parent->getPrimaryContext();
+  if (!Parent->LookupPtr)
+    Parent->CreateStoredDeclsMap(C);
+
+  DependentStoredDeclsMap *Map
+    = static_cast<DependentStoredDeclsMap*>(Parent->LookupPtr);
+
+  // Allocate the copy of the PartialDiagnostic via the ASTContext's
+  // BumpPtrAllocator, rather than the ASTContext itself.
+  PartialDiagnostic::Storage *DiagStorage = 0;
+  if (PDiag.hasStorage())
+    DiagStorage = new (C) PartialDiagnostic::Storage;
+  
+  DependentDiagnostic *DD = new (C) DependentDiagnostic(PDiag, DiagStorage);
+
+  // TODO: Maybe we shouldn't reverse the order during insertion.
+  DD->NextDiagnostic = Map->FirstDiagnostic;
+  Map->FirstDiagnostic = DD;
+
+  return DD;
+}
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
new file mode 100644
index 0000000..e6e9ee6
--- /dev/null
+++ b/lib/AST/DeclCXX.cpp
@@ -0,0 +1,972 @@
+//===--- DeclCXX.cpp - C++ Declaration AST Node Implementation ------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the C++ related Decl classes.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/TypeLoc.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallPtrSet.h"
+using namespace clang;
+
+//===----------------------------------------------------------------------===//
+// Decl Allocation/Deallocation Method Implementations
+//===----------------------------------------------------------------------===//
+
+CXXRecordDecl::DefinitionData::DefinitionData(CXXRecordDecl *D)
+  : UserDeclaredConstructor(false), UserDeclaredCopyConstructor(false),
+    UserDeclaredCopyAssignment(false), UserDeclaredDestructor(false),
+    Aggregate(true), PlainOldData(true), Empty(true), Polymorphic(false),
+    Abstract(false), HasTrivialConstructor(true),
+    HasTrivialCopyConstructor(true), HasTrivialCopyAssignment(true),
+    HasTrivialDestructor(true), ComputedVisibleConversions(false),
+    Bases(0), NumBases(0), VBases(0), NumVBases(0),
+    Definition(D), FirstFriend(0) {
+}
+
+CXXRecordDecl::CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC,
+                             SourceLocation L, IdentifierInfo *Id,
+                             CXXRecordDecl *PrevDecl,
+                             SourceLocation TKL)
+  : RecordDecl(K, TK, DC, L, Id, PrevDecl, TKL),
+    DefinitionData(PrevDecl ? PrevDecl->DefinitionData : 0),
+    TemplateOrInstantiation() { }
+
+CXXRecordDecl *CXXRecordDecl::Create(ASTContext &C, TagKind TK, DeclContext *DC,
+                                     SourceLocation L, IdentifierInfo *Id,
+                                     SourceLocation TKL,
+                                     CXXRecordDecl* PrevDecl,
+                                     bool DelayTypeCreation) {
+  CXXRecordDecl* R = new (C) CXXRecordDecl(CXXRecord, TK, DC, L, Id,
+                                           PrevDecl, TKL);
+
+  // FIXME: DelayTypeCreation seems like such a hack
+  if (!DelayTypeCreation)
+    C.getTypeDeclType(R, PrevDecl);
+  return R;
+}
+
+CXXRecordDecl::~CXXRecordDecl() {
+}
+
+void CXXRecordDecl::Destroy(ASTContext &C) {
+  if (data().Definition == this) {
+    C.Deallocate(data().Bases);
+    C.Deallocate(data().VBases);
+    C.Deallocate(&data());
+  }
+  this->RecordDecl::Destroy(C);
+}
+
+void
+CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases,
+                        unsigned NumBases) {
+  ASTContext &C = getASTContext();
+  
+  // C++ [dcl.init.aggr]p1:
+  //   An aggregate is an array or a class (clause 9) with [...]
+  //   no base classes [...].
+  data().Aggregate = false;
+
+  if (data().Bases)
+    C.Deallocate(data().Bases);
+
+  // The set of seen virtual base types.
+  llvm::SmallPtrSet<CanQualType, 8> SeenVBaseTypes;
+  
+  // The virtual bases of this class.
+  llvm::SmallVector<const CXXBaseSpecifier *, 8> VBases;
+
+  data().Bases = new(C) CXXBaseSpecifier [NumBases];
+  data().NumBases = NumBases;
+  for (unsigned i = 0; i < NumBases; ++i) {
+    data().Bases[i] = *Bases[i];
+    // Keep track of inherited vbases for this base class.
+    const CXXBaseSpecifier *Base = Bases[i];
+    QualType BaseType = Base->getType();
+    // Skip dependent types; we can't do any checking on them now.
+    if (BaseType->isDependentType())
+      continue;
+    CXXRecordDecl *BaseClassDecl
+      = cast<CXXRecordDecl>(BaseType->getAs<RecordType>()->getDecl());
+
+    // Now go through all virtual bases of this base and add them.
+    for (CXXRecordDecl::base_class_iterator VBase =
+          BaseClassDecl->vbases_begin(),
+         E = BaseClassDecl->vbases_end(); VBase != E; ++VBase) {
+      // Add this base if it's not already in the list.
+      if (SeenVBaseTypes.insert(C.getCanonicalType(VBase->getType())))
+        VBases.push_back(VBase);
+    }
+
+    if (Base->isVirtual()) {
+      // Add this base if it's not already in the list.
+      if (SeenVBaseTypes.insert(C.getCanonicalType(BaseType)))
+          VBases.push_back(Base);
+    }
+
+  }
+  
+  if (VBases.empty())
+    return;
+
+  // Create base specifier for any direct or indirect virtual bases.
+  data().VBases = new (C) CXXBaseSpecifier[VBases.size()];
+  data().NumVBases = VBases.size();
+  for (int I = 0, E = VBases.size(); I != E; ++I) {
+    QualType VBaseType = VBases[I]->getType();
+    
+    // Skip dependent types; we can't do any checking on them now.
+    if (VBaseType->isDependentType())
+      continue;
+
+    CXXRecordDecl *VBaseClassDecl
+      = cast<CXXRecordDecl>(VBaseType->getAs<RecordType>()->getDecl());
+
+    data().VBases[I] =
+      CXXBaseSpecifier(VBaseClassDecl->getSourceRange(), true,
+                       VBaseClassDecl->getTagKind() == RecordDecl::TK_class,
+                       VBases[I]->getAccessSpecifier(), VBaseType);
+  }
+}
+
+/// Callback function for CXXRecordDecl::forallBases that acknowledges
+/// that it saw a base class.
+static bool SawBase(const CXXRecordDecl *, void *) {
+  return true;
+}
+
+bool CXXRecordDecl::hasAnyDependentBases() const {
+  if (!isDependentContext())
+    return false;
+
+  return !forallBases(SawBase, 0);
+}
+
+bool CXXRecordDecl::hasConstCopyConstructor(ASTContext &Context) const {
+  return getCopyConstructor(Context, Qualifiers::Const) != 0;
+}
+
+CXXConstructorDecl *CXXRecordDecl::getCopyConstructor(ASTContext &Context,
+                                                      unsigned TypeQuals) const{
+  QualType ClassType
+    = Context.getTypeDeclType(const_cast<CXXRecordDecl*>(this));
+  DeclarationName ConstructorName
+    = Context.DeclarationNames.getCXXConstructorName(
+                                          Context.getCanonicalType(ClassType));
+  unsigned FoundTQs;
+  DeclContext::lookup_const_iterator Con, ConEnd;
+  for (llvm::tie(Con, ConEnd) = this->lookup(ConstructorName);
+       Con != ConEnd; ++Con) {
+    // C++ [class.copy]p2:
+    //   A non-template constructor for class X is a copy constructor if [...]
+    if (isa<FunctionTemplateDecl>(*Con))
+      continue;
+
+    if (cast<CXXConstructorDecl>(*Con)->isCopyConstructor(FoundTQs)) {
+      if (((TypeQuals & Qualifiers::Const) == (FoundTQs & Qualifiers::Const)) ||
+          (!(TypeQuals & Qualifiers::Const) && (FoundTQs & Qualifiers::Const)))
+        return cast<CXXConstructorDecl>(*Con);
+
+    }
+  }
+  return 0;
+}
+
+bool CXXRecordDecl::hasConstCopyAssignment(ASTContext &Context,
+                                           const CXXMethodDecl *& MD) const {
+  QualType ClassType = Context.getCanonicalType(Context.getTypeDeclType(
+    const_cast<CXXRecordDecl*>(this)));
+  DeclarationName OpName =Context.DeclarationNames.getCXXOperatorName(OO_Equal);
+
+  DeclContext::lookup_const_iterator Op, OpEnd;
+  for (llvm::tie(Op, OpEnd) = this->lookup(OpName);
+       Op != OpEnd; ++Op) {
+    // C++ [class.copy]p9:
+    //   A user-declared copy assignment operator is a non-static non-template
+    //   member function of class X with exactly one parameter of type X, X&,
+    //   const X&, volatile X& or const volatile X&.
+    const CXXMethodDecl* Method = dyn_cast<CXXMethodDecl>(*Op);
+    if (!Method)
+      continue;
+
+    if (Method->isStatic())
+      continue;
+    if (Method->getPrimaryTemplate())
+      continue;
+    const FunctionProtoType *FnType =
+      Method->getType()->getAs<FunctionProtoType>();
+    assert(FnType && "Overloaded operator has no prototype.");
+    // Don't assert on this; an invalid decl might have been left in the AST.
+    if (FnType->getNumArgs() != 1 || FnType->isVariadic())
+      continue;
+    bool AcceptsConst = true;
+    QualType ArgType = FnType->getArgType(0);
+    if (const LValueReferenceType *Ref = ArgType->getAs<LValueReferenceType>()) {
+      ArgType = Ref->getPointeeType();
+      // Is it a non-const lvalue reference?
+      if (!ArgType.isConstQualified())
+        AcceptsConst = false;
+    }
+    if (!Context.hasSameUnqualifiedType(ArgType, ClassType))
+      continue;
+    MD = Method;
+    // We have a single argument of type cv X or cv X&, i.e. we've found the
+    // copy assignment operator. Return whether it accepts const arguments.
+    return AcceptsConst;
+  }
+  assert(isInvalidDecl() &&
+         "No copy assignment operator declared in valid code.");
+  return false;
+}
+
+void
+CXXRecordDecl::addedConstructor(ASTContext &Context,
+                                CXXConstructorDecl *ConDecl) {
+  assert(!ConDecl->isImplicit() && "addedConstructor - not for implicit decl");
+  // Note that we have a user-declared constructor.
+  data().UserDeclaredConstructor = true;
+
+  // C++ [dcl.init.aggr]p1:
+  //   An aggregate is an array or a class (clause 9) with no
+  //   user-declared constructors (12.1) [...].
+  data().Aggregate = false;
+
+  // C++ [class]p4:
+  //   A POD-struct is an aggregate class [...]
+  data().PlainOldData = false;
+
+  // C++ [class.ctor]p5:
+  //   A constructor is trivial if it is an implicitly-declared default
+  //   constructor.
+  // FIXME: C++0x: don't do this for "= default" default constructors.
+  data().HasTrivialConstructor = false;
+
+  // Note when we have a user-declared copy constructor, which will
+  // suppress the implicit declaration of a copy constructor.
+  if (ConDecl->isCopyConstructor()) {
+    data().UserDeclaredCopyConstructor = true;
+
+    // C++ [class.copy]p6:
+    //   A copy constructor is trivial if it is implicitly declared.
+    // FIXME: C++0x: don't do this for "= default" copy constructors.
+    data().HasTrivialCopyConstructor = false;
+  }
+}
+
+void CXXRecordDecl::addedAssignmentOperator(ASTContext &Context,
+                                            CXXMethodDecl *OpDecl) {
+  // We're interested specifically in copy assignment operators.
+  const FunctionProtoType *FnType = OpDecl->getType()->getAs<FunctionProtoType>();
+  assert(FnType && "Overloaded operator has no proto function type.");
+  assert(FnType->getNumArgs() == 1 && !FnType->isVariadic());
+  
+  // Copy assignment operators must be non-templates.
+  if (OpDecl->getPrimaryTemplate() || OpDecl->getDescribedFunctionTemplate())
+    return;
+  
+  QualType ArgType = FnType->getArgType(0);
+  if (const LValueReferenceType *Ref = ArgType->getAs<LValueReferenceType>())
+    ArgType = Ref->getPointeeType();
+
+  ArgType = ArgType.getUnqualifiedType();
+  QualType ClassType = Context.getCanonicalType(Context.getTypeDeclType(
+    const_cast<CXXRecordDecl*>(this)));
+
+  if (!Context.hasSameUnqualifiedType(ClassType, ArgType))
+    return;
+
+  // This is a copy assignment operator.
+  // Note on the decl that it is a copy assignment operator.
+  OpDecl->setCopyAssignment(true);
+
+  // Suppress the implicit declaration of a copy constructor.
+  data().UserDeclaredCopyAssignment = true;
+
+  // C++ [class.copy]p11:
+  //   A copy assignment operator is trivial if it is implicitly declared.
+  // FIXME: C++0x: don't do this for "= default" copy operators.
+  data().HasTrivialCopyAssignment = false;
+
+  // C++ [class]p4:
+  //   A POD-struct is an aggregate class that [...] has no user-defined copy
+  //   assignment operator [...].
+  data().PlainOldData = false;
+}
+
+static CanQualType GetConversionType(ASTContext &Context, NamedDecl *Conv) {
+  QualType T;
+  if (isa<UsingShadowDecl>(Conv))
+    Conv = cast<UsingShadowDecl>(Conv)->getTargetDecl();
+  if (FunctionTemplateDecl *ConvTemp = dyn_cast<FunctionTemplateDecl>(Conv))
+    T = ConvTemp->getTemplatedDecl()->getResultType();
+  else 
+    T = cast<CXXConversionDecl>(Conv)->getConversionType();
+  return Context.getCanonicalType(T);
+}
+
+/// Collect the visible conversions of a base class.
+///
+/// \param Base a base class of the class we're considering
+/// \param InVirtual whether this base class is a virtual base (or a base
+///   of a virtual base)
+/// \param Access the access along the inheritance path to this base
+/// \param ParentHiddenTypes the conversions provided by the inheritors
+///   of this base
+/// \param Output the set to which to add conversions from non-virtual bases
+/// \param VOutput the set to which to add conversions from virtual bases
+/// \param HiddenVBaseCs the set of conversions which were hidden in a
+///   virtual base along some inheritance path
+static void CollectVisibleConversions(ASTContext &Context,
+                                      CXXRecordDecl *Record,
+                                      bool InVirtual,
+                                      AccessSpecifier Access,
+                  const llvm::SmallPtrSet<CanQualType, 8> &ParentHiddenTypes,
+                                      UnresolvedSetImpl &Output,
+                                      UnresolvedSetImpl &VOutput,
+                           llvm::SmallPtrSet<NamedDecl*, 8> &HiddenVBaseCs) {
+  // The set of types which have conversions in this class or its
+  // subclasses.  As an optimization, we don't copy the derived set
+  // unless it might change.
+  const llvm::SmallPtrSet<CanQualType, 8> *HiddenTypes = &ParentHiddenTypes;
+  llvm::SmallPtrSet<CanQualType, 8> HiddenTypesBuffer;
+
+  // Collect the direct conversions and figure out which conversions
+  // will be hidden in the subclasses.
+  UnresolvedSetImpl &Cs = *Record->getConversionFunctions();
+  if (!Cs.empty()) {
+    HiddenTypesBuffer = ParentHiddenTypes;
+    HiddenTypes = &HiddenTypesBuffer;
+
+    for (UnresolvedSetIterator I = Cs.begin(), E = Cs.end(); I != E; ++I) {
+      bool Hidden =
+        !HiddenTypesBuffer.insert(GetConversionType(Context, I.getDecl()));
+
+      // If this conversion is hidden and we're in a virtual base,
+      // remember that it's hidden along some inheritance path.
+      if (Hidden && InVirtual)
+        HiddenVBaseCs.insert(cast<NamedDecl>(I.getDecl()->getCanonicalDecl()));
+
+      // If this conversion isn't hidden, add it to the appropriate output.
+      else if (!Hidden) {
+        AccessSpecifier IAccess
+          = CXXRecordDecl::MergeAccess(Access, I.getAccess());
+
+        if (InVirtual)
+          VOutput.addDecl(I.getDecl(), IAccess);
+        else
+          Output.addDecl(I.getDecl(), IAccess);
+      }
+    }
+  }
+
+  // Collect information recursively from any base classes.
+  for (CXXRecordDecl::base_class_iterator
+         I = Record->bases_begin(), E = Record->bases_end(); I != E; ++I) {
+    const RecordType *RT = I->getType()->getAs<RecordType>();
+    if (!RT) continue;
+
+    AccessSpecifier BaseAccess
+      = CXXRecordDecl::MergeAccess(Access, I->getAccessSpecifier());
+    bool BaseInVirtual = InVirtual || I->isVirtual();
+
+    CXXRecordDecl *Base = cast<CXXRecordDecl>(RT->getDecl());
+    CollectVisibleConversions(Context, Base, BaseInVirtual, BaseAccess,
+                              *HiddenTypes, Output, VOutput, HiddenVBaseCs);
+  }
+}
+
+/// Collect the visible conversions of a class.
+///
+/// This would be extremely straightforward if it weren't for virtual
+/// bases.  It might be worth special-casing that, really.
+static void CollectVisibleConversions(ASTContext &Context,
+                                      CXXRecordDecl *Record,
+                                      UnresolvedSetImpl &Output) {
+  // The collection of all conversions in virtual bases that we've
+  // found.  These will be added to the output as long as they don't
+  // appear in the hidden-conversions set.
+  UnresolvedSet<8> VBaseCs;
+  
+  // The set of conversions in virtual bases that we've determined to
+  // be hidden.
+  llvm::SmallPtrSet<NamedDecl*, 8> HiddenVBaseCs;
+
+  // The set of types hidden by classes derived from this one.
+  llvm::SmallPtrSet<CanQualType, 8> HiddenTypes;
+
+  // Go ahead and collect the direct conversions and add them to the
+  // hidden-types set.
+  UnresolvedSetImpl &Cs = *Record->getConversionFunctions();
+  Output.append(Cs.begin(), Cs.end());
+  for (UnresolvedSetIterator I = Cs.begin(), E = Cs.end(); I != E; ++I)
+    HiddenTypes.insert(GetConversionType(Context, I.getDecl()));
+
+  // Recursively collect conversions from base classes.
+  for (CXXRecordDecl::base_class_iterator
+         I = Record->bases_begin(), E = Record->bases_end(); I != E; ++I) {
+    const RecordType *RT = I->getType()->getAs<RecordType>();
+    if (!RT) continue;
+
+    CollectVisibleConversions(Context, cast<CXXRecordDecl>(RT->getDecl()),
+                              I->isVirtual(), I->getAccessSpecifier(),
+                              HiddenTypes, Output, VBaseCs, HiddenVBaseCs);
+  }
+
+  // Add any unhidden conversions provided by virtual bases.
+  for (UnresolvedSetIterator I = VBaseCs.begin(), E = VBaseCs.end();
+         I != E; ++I) {
+    if (!HiddenVBaseCs.count(cast<NamedDecl>(I.getDecl()->getCanonicalDecl())))
+      Output.addDecl(I.getDecl(), I.getAccess());
+  }
+}
+
+/// getVisibleConversionFunctions - get all conversion functions visible
+/// in current class; including conversion function templates.
+const UnresolvedSetImpl *CXXRecordDecl::getVisibleConversionFunctions() {
+  // If root class, all conversions are visible.
+  if (bases_begin() == bases_end())
+    return &data().Conversions;
+  // If visible conversion list is already evaluated, return it.
+  if (data().ComputedVisibleConversions)
+    return &data().VisibleConversions;
+  CollectVisibleConversions(getASTContext(), this, data().VisibleConversions);
+  data().ComputedVisibleConversions = true;
+  return &data().VisibleConversions;
+}
+
+#ifndef NDEBUG
+void CXXRecordDecl::CheckConversionFunction(NamedDecl *ConvDecl) {
+  assert(ConvDecl->getDeclContext() == this &&
+         "conversion function does not belong to this record");
+
+  ConvDecl = ConvDecl->getUnderlyingDecl();
+  if (FunctionTemplateDecl *Temp = dyn_cast<FunctionTemplateDecl>(ConvDecl)) {
+    assert(isa<CXXConversionDecl>(Temp->getTemplatedDecl()));
+  } else {
+    assert(isa<CXXConversionDecl>(ConvDecl));
+  }
+}
+#endif
+
+void CXXRecordDecl::removeConversion(const NamedDecl *ConvDecl) {
+  // This operation is O(N) but extremely rare.  Sema only uses it to
+  // remove UsingShadowDecls in a class that were followed by a direct
+  // declaration, e.g.:
+  //   class A : B {
+  //     using B::operator int;
+  //     operator int();
+  //   };
+  // This is uncommon by itself and even more uncommon in conjunction
+  // with sufficiently large numbers of directly-declared conversions
+  // that asymptotic behavior matters.
+
+  UnresolvedSetImpl &Convs = *getConversionFunctions();
+  for (unsigned I = 0, E = Convs.size(); I != E; ++I) {
+    if (Convs[I].getDecl() == ConvDecl) {
+      Convs.erase(I);
+      assert(std::find(Convs.begin(), Convs.end(), ConvDecl) == Convs.end()
+             && "conversion was found multiple times in unresolved set");
+      return;
+    }
+  }
+
+  llvm_unreachable("conversion not found in set!");
+}
+
+void CXXRecordDecl::setMethodAsVirtual(FunctionDecl *Method) {
+  Method->setVirtualAsWritten(true);
+  setAggregate(false);
+  setPOD(false);
+  setEmpty(false);
+  setPolymorphic(true);
+  setHasTrivialConstructor(false);
+  setHasTrivialCopyConstructor(false);
+  setHasTrivialCopyAssignment(false);
+}
+
+CXXRecordDecl *CXXRecordDecl::getInstantiatedFromMemberClass() const {
+  if (MemberSpecializationInfo *MSInfo = getMemberSpecializationInfo())
+    return cast<CXXRecordDecl>(MSInfo->getInstantiatedFrom());
+  
+  return 0;
+}
+
+MemberSpecializationInfo *CXXRecordDecl::getMemberSpecializationInfo() const {
+  return TemplateOrInstantiation.dyn_cast<MemberSpecializationInfo *>();
+}
+
+void 
+CXXRecordDecl::setInstantiationOfMemberClass(CXXRecordDecl *RD,
+                                             TemplateSpecializationKind TSK) {
+  assert(TemplateOrInstantiation.isNull() && 
+         "Previous template or instantiation?");
+  assert(!isa<ClassTemplateSpecializationDecl>(this));
+  TemplateOrInstantiation 
+    = new (getASTContext()) MemberSpecializationInfo(RD, TSK);
+}
+
+TemplateSpecializationKind CXXRecordDecl::getTemplateSpecializationKind() const{
+  if (const ClassTemplateSpecializationDecl *Spec
+        = dyn_cast<ClassTemplateSpecializationDecl>(this))
+    return Spec->getSpecializationKind();
+  
+  if (MemberSpecializationInfo *MSInfo = getMemberSpecializationInfo())
+    return MSInfo->getTemplateSpecializationKind();
+  
+  return TSK_Undeclared;
+}
+
+void 
+CXXRecordDecl::setTemplateSpecializationKind(TemplateSpecializationKind TSK) {
+  if (ClassTemplateSpecializationDecl *Spec
+      = dyn_cast<ClassTemplateSpecializationDecl>(this)) {
+    Spec->setSpecializationKind(TSK);
+    return;
+  }
+  
+  if (MemberSpecializationInfo *MSInfo = getMemberSpecializationInfo()) {
+    MSInfo->setTemplateSpecializationKind(TSK);
+    return;
+  }
+  
+  assert(false && "Not a class template or member class specialization");
+}
+
+CXXConstructorDecl *
+CXXRecordDecl::getDefaultConstructor(ASTContext &Context) {
+  QualType ClassType = Context.getTypeDeclType(this);
+  DeclarationName ConstructorName
+    = Context.DeclarationNames.getCXXConstructorName(
+                      Context.getCanonicalType(ClassType.getUnqualifiedType()));
+
+  DeclContext::lookup_const_iterator Con, ConEnd;
+  for (llvm::tie(Con, ConEnd) = lookup(ConstructorName);
+       Con != ConEnd; ++Con) {
+    // FIXME: In C++0x, a constructor template can be a default constructor.
+    if (isa<FunctionTemplateDecl>(*Con))
+      continue;
+
+    CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(*Con);
+    if (Constructor->isDefaultConstructor())
+      return Constructor;
+  }
+  return 0;
+}
+
+CXXDestructorDecl *CXXRecordDecl::getDestructor(ASTContext &Context) const {
+  QualType ClassType = Context.getTypeDeclType(this);
+
+  DeclarationName Name
+    = Context.DeclarationNames.getCXXDestructorName(
+                                          Context.getCanonicalType(ClassType));
+
+  DeclContext::lookup_const_iterator I, E;
+  llvm::tie(I, E) = lookup(Name);
+  assert(I != E && "Did not find a destructor!");
+
+  CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(*I);
+  assert(++I == E && "Found more than one destructor!");
+
+  return Dtor;
+}
+
+CXXMethodDecl *
+CXXMethodDecl::Create(ASTContext &C, CXXRecordDecl *RD,
+                      SourceLocation L, DeclarationName N,
+                      QualType T, TypeSourceInfo *TInfo,
+                      bool isStatic, StorageClass SCAsWritten, bool isInline) {
+  return new (C) CXXMethodDecl(CXXMethod, RD, L, N, T, TInfo,
+                               isStatic, SCAsWritten, isInline);
+}
+
+bool CXXMethodDecl::isUsualDeallocationFunction() const {
+  if (getOverloadedOperator() != OO_Delete &&
+      getOverloadedOperator() != OO_Array_Delete)
+    return false;
+
+  // C++ [basic.stc.dynamic.deallocation]p2:
+  //   A template instance is never a usual deallocation function,
+  //   regardless of its signature.
+  if (getPrimaryTemplate())
+    return false;
+
+  // C++ [basic.stc.dynamic.deallocation]p2:
+  //   If a class T has a member deallocation function named operator delete 
+  //   with exactly one parameter, then that function is a usual (non-placement)
+  //   deallocation function. [...]
+  if (getNumParams() == 1)
+    return true;
+  
+  // C++ [basic.stc.dynamic.deallocation]p2:
+  //   [...] If class T does not declare such an operator delete but does 
+  //   declare a member deallocation function named operator delete with 
+  //   exactly two parameters, the second of which has type std::size_t (18.1),
+  //   then this function is a usual deallocation function.
+  ASTContext &Context = getASTContext();
+  if (getNumParams() != 2 ||
+      !Context.hasSameUnqualifiedType(getParamDecl(1)->getType(),
+                                      Context.getSizeType()))
+    return false;
+                 
+  // This function is a usual deallocation function if there are no 
+  // single-parameter deallocation functions of the same kind.
+  for (DeclContext::lookup_const_result R = getDeclContext()->lookup(getDeclName());
+       R.first != R.second; ++R.first) {
+    if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(*R.first))
+      if (FD->getNumParams() == 1)
+        return false;
+  }
+  
+  return true;
+}
+
+void CXXMethodDecl::addOverriddenMethod(const CXXMethodDecl *MD) {
+  assert(MD->isCanonicalDecl() && "Method is not canonical!");
+  assert(!MD->getParent()->isDependentContext() &&
+         "Can't add an overridden method to a class template!");
+
+  getASTContext().addOverriddenMethod(this, MD);
+}
+
+CXXMethodDecl::method_iterator CXXMethodDecl::begin_overridden_methods() const {
+  return getASTContext().overridden_methods_begin(this);
+}
+
+CXXMethodDecl::method_iterator CXXMethodDecl::end_overridden_methods() const {
+  return getASTContext().overridden_methods_end(this);
+}
+
+QualType CXXMethodDecl::getThisType(ASTContext &C) const {
+  // C++ 9.3.2p1: The type of this in a member function of a class X is X*.
+  // If the member function is declared const, the type of this is const X*,
+  // if the member function is declared volatile, the type of this is
+  // volatile X*, and if the member function is declared const volatile,
+  // the type of this is const volatile X*.
+
+  assert(isInstance() && "No 'this' for static methods!");
+
+  QualType ClassTy = C.getTypeDeclType(getParent());
+  ClassTy = C.getQualifiedType(ClassTy,
+                               Qualifiers::fromCVRMask(getTypeQualifiers()));
+  return C.getPointerType(ClassTy);
+}
+
+bool CXXMethodDecl::hasInlineBody() const {
+  // If this function is a template instantiation, look at the template from 
+  // which it was instantiated.
+  const FunctionDecl *CheckFn = getTemplateInstantiationPattern();
+  if (!CheckFn)
+    CheckFn = this;
+  
+  const FunctionDecl *fn;
+  return CheckFn->getBody(fn) && !fn->isOutOfLine();
+}
+
+CXXBaseOrMemberInitializer::
+CXXBaseOrMemberInitializer(ASTContext &Context,
+                           TypeSourceInfo *TInfo, bool IsVirtual,
+                           SourceLocation L, Expr *Init, SourceLocation R)
+  : BaseOrMember(TInfo), Init(Init), AnonUnionMember(0), IsVirtual(IsVirtual),
+    LParenLoc(L), RParenLoc(R) 
+{
+}
+
+CXXBaseOrMemberInitializer::
+CXXBaseOrMemberInitializer(ASTContext &Context,
+                           FieldDecl *Member, SourceLocation MemberLoc,
+                           SourceLocation L, Expr *Init, SourceLocation R)
+  : BaseOrMember(Member), MemberLocation(MemberLoc), Init(Init), 
+    AnonUnionMember(0), LParenLoc(L), RParenLoc(R) 
+{
+}
+
+void CXXBaseOrMemberInitializer::Destroy(ASTContext &Context) {
+  if (Init)
+    Init->Destroy(Context);
+  this->~CXXBaseOrMemberInitializer();
+}
+
+TypeLoc CXXBaseOrMemberInitializer::getBaseClassLoc() const {
+  if (isBaseInitializer())
+    return BaseOrMember.get<TypeSourceInfo*>()->getTypeLoc();
+  else
+    return TypeLoc();
+}
+
+Type *CXXBaseOrMemberInitializer::getBaseClass() {
+  if (isBaseInitializer())
+    return BaseOrMember.get<TypeSourceInfo*>()->getType().getTypePtr();
+  else
+    return 0;
+}
+
+const Type *CXXBaseOrMemberInitializer::getBaseClass() const {
+  if (isBaseInitializer())
+    return BaseOrMember.get<TypeSourceInfo*>()->getType().getTypePtr();
+  else
+    return 0;
+}
+
+SourceLocation CXXBaseOrMemberInitializer::getSourceLocation() const {
+  if (isMemberInitializer())
+    return getMemberLocation();
+  
+  return getBaseClassLoc().getSourceRange().getBegin();
+}
+
+SourceRange CXXBaseOrMemberInitializer::getSourceRange() const {
+  return SourceRange(getSourceLocation(), getRParenLoc());
+}
+
+CXXConstructorDecl *
+CXXConstructorDecl::Create(ASTContext &C, CXXRecordDecl *RD,
+                           SourceLocation L, DeclarationName N,
+                           QualType T, TypeSourceInfo *TInfo,
+                           bool isExplicit,
+                           bool isInline,
+                           bool isImplicitlyDeclared) {
+  assert(N.getNameKind() == DeclarationName::CXXConstructorName &&
+         "Name must refer to a constructor");
+  return new (C) CXXConstructorDecl(RD, L, N, T, TInfo, isExplicit,
+                                    isInline, isImplicitlyDeclared);
+}
+
+bool CXXConstructorDecl::isDefaultConstructor() const {
+  // C++ [class.ctor]p5:
+  //   A default constructor for a class X is a constructor of class
+  //   X that can be called without an argument.
+  return (getNumParams() == 0) ||
+         (getNumParams() > 0 && getParamDecl(0)->hasDefaultArg());
+}
+
+bool
+CXXConstructorDecl::isCopyConstructor(unsigned &TypeQuals) const {
+  // C++ [class.copy]p2:
+  //   A non-template constructor for class X is a copy constructor
+  //   if its first parameter is of type X&, const X&, volatile X& or
+  //   const volatile X&, and either there are no other parameters
+  //   or else all other parameters have default arguments (8.3.6).
+  if ((getNumParams() < 1) ||
+      (getNumParams() > 1 && !getParamDecl(1)->hasDefaultArg()) ||
+      (getPrimaryTemplate() != 0) ||
+      (getDescribedFunctionTemplate() != 0))
+    return false;
+
+  const ParmVarDecl *Param = getParamDecl(0);
+
+  // Do we have a reference type? Rvalue references don't count.
+  const LValueReferenceType *ParamRefType =
+    Param->getType()->getAs<LValueReferenceType>();
+  if (!ParamRefType)
+    return false;
+
+  // Is it a reference to our class type?
+  ASTContext &Context = getASTContext();
+  
+  CanQualType PointeeType
+    = Context.getCanonicalType(ParamRefType->getPointeeType());
+  CanQualType ClassTy 
+    = Context.getCanonicalType(Context.getTagDeclType(getParent()));
+  if (PointeeType.getUnqualifiedType() != ClassTy)
+    return false;
+
+  // FIXME: other qualifiers?
+
+  // We have a copy constructor.
+  TypeQuals = PointeeType.getCVRQualifiers();
+  return true;
+}
+
+bool CXXConstructorDecl::isConvertingConstructor(bool AllowExplicit) const {
+  // C++ [class.conv.ctor]p1:
+  //   A constructor declared without the function-specifier explicit
+  //   that can be called with a single parameter specifies a
+  //   conversion from the type of its first parameter to the type of
+  //   its class. Such a constructor is called a converting
+  //   constructor.
+  if (isExplicit() && !AllowExplicit)
+    return false;
+
+  return (getNumParams() == 0 &&
+          getType()->getAs<FunctionProtoType>()->isVariadic()) ||
+         (getNumParams() == 1) ||
+         (getNumParams() > 1 && getParamDecl(1)->hasDefaultArg());
+}
+
+bool CXXConstructorDecl::isCopyConstructorLikeSpecialization() const {
+  if ((getNumParams() < 1) ||
+      (getNumParams() > 1 && !getParamDecl(1)->hasDefaultArg()) ||
+      (getPrimaryTemplate() == 0) ||
+      (getDescribedFunctionTemplate() != 0))
+    return false;
+
+  const ParmVarDecl *Param = getParamDecl(0);
+
+  ASTContext &Context = getASTContext();
+  CanQualType ParamType = Context.getCanonicalType(Param->getType());
+  
+  // Strip off the lvalue reference, if any.
+  if (CanQual<LValueReferenceType> ParamRefType
+                                    = ParamType->getAs<LValueReferenceType>())
+    ParamType = ParamRefType->getPointeeType();
+
+  
+  // Is it the same as our our class type?
+  CanQualType ClassTy 
+    = Context.getCanonicalType(Context.getTagDeclType(getParent()));
+  if (ParamType.getUnqualifiedType() != ClassTy)
+    return false;
+  
+  return true;  
+}
+
+CXXDestructorDecl *
+CXXDestructorDecl::Create(ASTContext &C, CXXRecordDecl *RD,
+                          SourceLocation L, DeclarationName N,
+                          QualType T, bool isInline,
+                          bool isImplicitlyDeclared) {
+  assert(N.getNameKind() == DeclarationName::CXXDestructorName &&
+         "Name must refer to a destructor");
+  return new (C) CXXDestructorDecl(RD, L, N, T, isInline, isImplicitlyDeclared);
+}
+
+void
+CXXConstructorDecl::Destroy(ASTContext& C) {
+  C.Deallocate(BaseOrMemberInitializers);
+  CXXMethodDecl::Destroy(C);
+}
+
+CXXConversionDecl *
+CXXConversionDecl::Create(ASTContext &C, CXXRecordDecl *RD,
+                          SourceLocation L, DeclarationName N,
+                          QualType T, TypeSourceInfo *TInfo,
+                          bool isInline, bool isExplicit) {
+  assert(N.getNameKind() == DeclarationName::CXXConversionFunctionName &&
+         "Name must refer to a conversion function");
+  return new (C) CXXConversionDecl(RD, L, N, T, TInfo, isInline, isExplicit);
+}
+
+LinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C,
+                                         DeclContext *DC,
+                                         SourceLocation L,
+                                         LanguageIDs Lang, bool Braces) {
+  return new (C) LinkageSpecDecl(DC, L, Lang, Braces);
+}
+
+UsingDirectiveDecl *UsingDirectiveDecl::Create(ASTContext &C, DeclContext *DC,
+                                               SourceLocation L,
+                                               SourceLocation NamespaceLoc,
+                                               SourceRange QualifierRange,
+                                               NestedNameSpecifier *Qualifier,
+                                               SourceLocation IdentLoc,
+                                               NamedDecl *Used,
+                                               DeclContext *CommonAncestor) {
+  if (NamespaceDecl *NS = dyn_cast_or_null<NamespaceDecl>(Used))
+    Used = NS->getOriginalNamespace();
+  return new (C) UsingDirectiveDecl(DC, L, NamespaceLoc, QualifierRange,
+                                    Qualifier, IdentLoc, Used, CommonAncestor);
+}
+
+NamespaceDecl *UsingDirectiveDecl::getNominatedNamespace() {
+  if (NamespaceAliasDecl *NA =
+        dyn_cast_or_null<NamespaceAliasDecl>(NominatedNamespace))
+    return NA->getNamespace();
+  return cast_or_null<NamespaceDecl>(NominatedNamespace);
+}
+
+NamespaceAliasDecl *NamespaceAliasDecl::Create(ASTContext &C, DeclContext *DC,
+                                               SourceLocation L,
+                                               SourceLocation AliasLoc,
+                                               IdentifierInfo *Alias,
+                                               SourceRange QualifierRange,
+                                               NestedNameSpecifier *Qualifier,
+                                               SourceLocation IdentLoc,
+                                               NamedDecl *Namespace) {
+  if (NamespaceDecl *NS = dyn_cast_or_null<NamespaceDecl>(Namespace))
+    Namespace = NS->getOriginalNamespace();
+  return new (C) NamespaceAliasDecl(DC, L, AliasLoc, Alias, QualifierRange,
+                                    Qualifier, IdentLoc, Namespace);
+}
+
+UsingDecl *UsingDecl::Create(ASTContext &C, DeclContext *DC,
+      SourceLocation L, SourceRange NNR, SourceLocation UL,
+      NestedNameSpecifier* TargetNNS, DeclarationName Name,
+      bool IsTypeNameArg) {
+  return new (C) UsingDecl(DC, L, NNR, UL, TargetNNS, Name, IsTypeNameArg);
+}
+
+UnresolvedUsingValueDecl *
+UnresolvedUsingValueDecl::Create(ASTContext &C, DeclContext *DC,
+                                 SourceLocation UsingLoc,
+                                 SourceRange TargetNNR,
+                                 NestedNameSpecifier *TargetNNS,
+                                 SourceLocation TargetNameLoc,
+                                 DeclarationName TargetName) {
+  return new (C) UnresolvedUsingValueDecl(DC, C.DependentTy, UsingLoc,
+                                          TargetNNR, TargetNNS,
+                                          TargetNameLoc, TargetName);
+}
+
+UnresolvedUsingTypenameDecl *
+UnresolvedUsingTypenameDecl::Create(ASTContext &C, DeclContext *DC,
+                                    SourceLocation UsingLoc,
+                                    SourceLocation TypenameLoc,
+                                    SourceRange TargetNNR,
+                                    NestedNameSpecifier *TargetNNS,
+                                    SourceLocation TargetNameLoc,
+                                    DeclarationName TargetName) {
+  return new (C) UnresolvedUsingTypenameDecl(DC, UsingLoc, TypenameLoc,
+                                             TargetNNR, TargetNNS,
+                                             TargetNameLoc,
+                                             TargetName.getAsIdentifierInfo());
+}
+
+StaticAssertDecl *StaticAssertDecl::Create(ASTContext &C, DeclContext *DC,
+                                           SourceLocation L, Expr *AssertExpr,
+                                           StringLiteral *Message) {
+  return new (C) StaticAssertDecl(DC, L, AssertExpr, Message);
+}
+
+void StaticAssertDecl::Destroy(ASTContext& C) {
+  AssertExpr->Destroy(C);
+  Message->Destroy(C);
+  Decl::Destroy(C);
+}
+
+StaticAssertDecl::~StaticAssertDecl() {
+}
+
+static const char *getAccessName(AccessSpecifier AS) {
+  switch (AS) {
+    default:
+    case AS_none:
+      assert("Invalid access specifier!");
+      return 0;
+    case AS_public:
+      return "public";
+    case AS_private:
+      return "private";
+    case AS_protected:
+      return "protected";
+  }
+}
+
+const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
+                                           AccessSpecifier AS) {
+  return DB << getAccessName(AS);
+}
+
+
diff --git a/lib/AST/DeclFriend.cpp b/lib/AST/DeclFriend.cpp
new file mode 100644
index 0000000..ab3552d
--- /dev/null
+++ b/lib/AST/DeclFriend.cpp
@@ -0,0 +1,41 @@
+//===--- DeclFriend.cpp - C++ Friend Declaration AST Node Implementation --===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the AST classes related to C++ friend
+// declarations.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/DeclFriend.h"
+#include "clang/AST/DeclTemplate.h"
+using namespace clang;
+
+FriendDecl *FriendDecl::Create(ASTContext &C, DeclContext *DC,
+                               SourceLocation L,
+                               FriendUnion Friend,
+                               SourceLocation FriendL) {
+#ifndef NDEBUG
+  if (Friend.is<NamedDecl*>()) {
+    NamedDecl *D = Friend.get<NamedDecl*>();
+    assert(isa<FunctionDecl>(D) ||
+           isa<CXXRecordDecl>(D) ||
+           isa<FunctionTemplateDecl>(D) ||
+           isa<ClassTemplateDecl>(D));
+
+    // As a temporary hack, we permit template instantiation to point
+    // to the original declaration when instantiating members.
+    assert(D->getFriendObjectKind() ||
+           (cast<CXXRecordDecl>(DC)->getTemplateSpecializationKind()));
+  }
+#endif
+
+  FriendDecl *FD = new (C) FriendDecl(DC, L, Friend, FriendL);
+  cast<CXXRecordDecl>(DC)->pushFriendDecl(FD);
+  return FD;
+}
diff --git a/lib/AST/DeclGroup.cpp b/lib/AST/DeclGroup.cpp
new file mode 100644
index 0000000..434bf00
--- /dev/null
+++ b/lib/AST/DeclGroup.cpp
@@ -0,0 +1,38 @@
+//===--- DeclGroup.cpp - Classes for representing groups of Decls -*- C++ -*-==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the DeclGroup and DeclGroupRef classes.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/DeclGroup.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/ASTContext.h"
+#include "llvm/Support/Allocator.h"
+using namespace clang;
+
+DeclGroup* DeclGroup::Create(ASTContext &C, Decl **Decls, unsigned NumDecls) {
+  assert(NumDecls > 1 && "Invalid DeclGroup");
+  unsigned Size = sizeof(DeclGroup) + sizeof(Decl*) * NumDecls;
+  void* Mem = C.Allocate(Size, llvm::AlignOf<DeclGroup>::Alignment);
+  new (Mem) DeclGroup(NumDecls, Decls);
+  return static_cast<DeclGroup*>(Mem);
+}
+
+DeclGroup::DeclGroup(unsigned numdecls, Decl** decls) : NumDecls(numdecls) {
+  assert(numdecls > 0);
+  assert(decls);
+  memcpy(this+1, decls, numdecls * sizeof(*decls));
+}
+
+void DeclGroup::Destroy(ASTContext& C) {
+  // Decls are destroyed by the DeclContext.
+  this->~DeclGroup();
+  C.Deallocate((void*) this);
+}
diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp
new file mode 100644
index 0000000..dc4aacd
--- /dev/null
+++ b/lib/AST/DeclObjC.cpp
@@ -0,0 +1,910 @@
+//===--- DeclObjC.cpp - ObjC Declaration AST Node Implementation ----------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Objective-C related Decl classes.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Stmt.h"
+#include "llvm/ADT/STLExtras.h"
+using namespace clang;
+
+//===----------------------------------------------------------------------===//
+// ObjCListBase
+//===----------------------------------------------------------------------===//
+
+void ObjCListBase::Destroy(ASTContext &Ctx) {
+  Ctx.Deallocate(List);
+  NumElts = 0;
+  List = 0;
+}
+
+void ObjCListBase::set(void *const* InList, unsigned Elts, ASTContext &Ctx) {
+  assert(List == 0 && "Elements already set!");
+  if (Elts == 0) return;  // Setting to an empty list is a noop.
+
+
+  List = new (Ctx) void*[Elts];
+  NumElts = Elts;
+  memcpy(List, InList, sizeof(void*)*Elts);
+}
+
+void ObjCProtocolList::set(ObjCProtocolDecl* const* InList, unsigned Elts, 
+                           const SourceLocation *Locs, ASTContext &Ctx) {
+  if (Elts == 0)
+    return;
+
+  Locations = new (Ctx) SourceLocation[Elts];
+  memcpy(Locations, Locs, sizeof(SourceLocation) * Elts);
+  set(InList, Elts, Ctx);
+}
+
+void ObjCProtocolList::Destroy(ASTContext &Ctx) {
+  Ctx.Deallocate(Locations);
+  Locations = 0;
+  ObjCList<ObjCProtocolDecl>::Destroy(Ctx);
+}
+
+//===----------------------------------------------------------------------===//
+// ObjCInterfaceDecl
+//===----------------------------------------------------------------------===//
+
+/// getIvarDecl - This method looks up an ivar in this ContextDecl.
+///
+ObjCIvarDecl *
+ObjCContainerDecl::getIvarDecl(IdentifierInfo *Id) const {
+  lookup_const_iterator Ivar, IvarEnd;
+  for (llvm::tie(Ivar, IvarEnd) = lookup(Id); Ivar != IvarEnd; ++Ivar) {
+    if (ObjCIvarDecl *ivar = dyn_cast<ObjCIvarDecl>(*Ivar))
+      return ivar;
+  }
+  return 0;
+}
+
+// Get the local instance/class method declared in this interface.
+ObjCMethodDecl *
+ObjCContainerDecl::getMethod(Selector Sel, bool isInstance) const {
+  // Since instance & class methods can have the same name, the loop below
+  // ensures we get the correct method.
+  //
+  // @interface Whatever
+  // - (int) class_method;
+  // + (float) class_method;
+  // @end
+  //
+  lookup_const_iterator Meth, MethEnd;
+  for (llvm::tie(Meth, MethEnd) = lookup(Sel); Meth != MethEnd; ++Meth) {
+    ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth);
+    if (MD && MD->isInstanceMethod() == isInstance)
+      return MD;
+  }
+  return 0;
+}
+
+ObjCPropertyDecl *
+ObjCPropertyDecl::findPropertyDecl(const DeclContext *DC,
+                                   IdentifierInfo *propertyID) {
+
+  DeclContext::lookup_const_iterator I, E;
+  llvm::tie(I, E) = DC->lookup(propertyID);
+  for ( ; I != E; ++I)
+    if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(*I))
+      return PD;
+
+  return 0;
+}
+
+/// FindPropertyDeclaration - Finds declaration of the property given its name
+/// in 'PropertyId' and returns it. It returns 0, if not found.
+ObjCPropertyDecl *
+ObjCContainerDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
+
+  if (ObjCPropertyDecl *PD =
+        ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(this), PropertyId))
+    return PD;
+
+  switch (getKind()) {
+    default:
+      break;
+    case Decl::ObjCProtocol: {
+      const ObjCProtocolDecl *PID = cast<ObjCProtocolDecl>(this);
+      for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
+           E = PID->protocol_end(); I != E; ++I)
+        if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
+          return P;
+      break;
+    }
+    case Decl::ObjCInterface: {
+      const ObjCInterfaceDecl *OID = cast<ObjCInterfaceDecl>(this);
+      // Look through categories.
+      for (ObjCCategoryDecl *Cat = OID->getCategoryList();
+           Cat; Cat = Cat->getNextClassCategory())
+        if (!Cat->IsClassExtension())
+          if (ObjCPropertyDecl *P = Cat->FindPropertyDeclaration(PropertyId))
+            return P;
+
+      // Look through protocols.
+      for (ObjCInterfaceDecl::protocol_iterator
+            I = OID->protocol_begin(), E = OID->protocol_end(); I != E; ++I)
+        if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
+          return P;
+
+      // Finally, check the super class.
+      if (const ObjCInterfaceDecl *superClass = OID->getSuperClass())
+        return superClass->FindPropertyDeclaration(PropertyId);
+      break;
+    }
+    case Decl::ObjCCategory: {
+      const ObjCCategoryDecl *OCD = cast<ObjCCategoryDecl>(this);
+      // Look through protocols.
+      if (!OCD->IsClassExtension())
+        for (ObjCCategoryDecl::protocol_iterator
+              I = OCD->protocol_begin(), E = OCD->protocol_end(); I != E; ++I)
+        if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
+          return P;
+
+      break;
+    }
+  }
+  return 0;
+}
+
+/// FindPropertyVisibleInPrimaryClass - Finds declaration of the property
+/// with name 'PropertyId' in the primary class; including those in protocols
+/// (direct or indirect) used by the primary class.
+///
+ObjCPropertyDecl *
+ObjCInterfaceDecl::FindPropertyVisibleInPrimaryClass(
+                                            IdentifierInfo *PropertyId) const {
+  if (ObjCPropertyDecl *PD =
+      ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(this), PropertyId))
+    return PD;
+
+  // Look through protocols.
+  for (ObjCInterfaceDecl::protocol_iterator
+        I = protocol_begin(), E = protocol_end(); I != E; ++I)
+    if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
+      return P;
+
+  return 0;
+}
+
+void ObjCInterfaceDecl::mergeClassExtensionProtocolList(
+                              ObjCProtocolDecl *const* ExtList, unsigned ExtNum,
+                              const SourceLocation *Locs,
+                              ASTContext &C)
+{
+  if (ReferencedProtocols.empty()) {
+    ReferencedProtocols.set(ExtList, ExtNum, Locs, C);
+    return;
+  }
+  // Check for duplicate protocol in class's protocol list.
+  // This is (O)2. But it is extremely rare and number of protocols in
+  // class or its extension are very few.
+  llvm::SmallVector<ObjCProtocolDecl*, 8> ProtocolRefs;
+  llvm::SmallVector<SourceLocation, 8> ProtocolLocs;
+  for (unsigned i = 0; i < ExtNum; i++) {
+    bool protocolExists = false;
+    ObjCProtocolDecl *ProtoInExtension = ExtList[i];
+    for (protocol_iterator p = protocol_begin(), e = protocol_end();
+         p != e; p++) {
+      ObjCProtocolDecl *Proto = (*p);
+      if (C.ProtocolCompatibleWithProtocol(ProtoInExtension, Proto)) {
+        protocolExists = true;
+        break;
+      }      
+    }
+    // Do we want to warn on a protocol in extension class which
+    // already exist in the class? Probably not.
+    if (!protocolExists) {
+      ProtocolRefs.push_back(ProtoInExtension);
+      ProtocolLocs.push_back(Locs[i]);
+    }
+  }
+  if (ProtocolRefs.empty())
+    return;
+  // Merge ProtocolRefs into class's protocol list;
+  protocol_loc_iterator pl = protocol_loc_begin();
+  for (protocol_iterator p = protocol_begin(), e = protocol_end();
+       p != e; ++p, ++pl) {
+    ProtocolRefs.push_back(*p);
+    ProtocolLocs.push_back(*pl);
+  }
+  ReferencedProtocols.Destroy(C);
+  unsigned NumProtoRefs = ProtocolRefs.size();
+  setProtocolList(ProtocolRefs.data(), NumProtoRefs, ProtocolLocs.data(), C);
+}
+
+/// getClassExtension - Find class extension of the given class.
+// FIXME. can speed it up, if need be.
+ObjCCategoryDecl* ObjCInterfaceDecl::getClassExtension() const {
+  const ObjCInterfaceDecl* ClassDecl = this;
+  for (ObjCCategoryDecl *CDecl = ClassDecl->getCategoryList(); CDecl;
+       CDecl = CDecl->getNextClassCategory())
+    if (CDecl->IsClassExtension())
+      return CDecl;
+  return 0;
+}
+
+ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(IdentifierInfo *ID,
+                                              ObjCInterfaceDecl *&clsDeclared) {
+  ObjCInterfaceDecl* ClassDecl = this;
+  while (ClassDecl != NULL) {
+    if (ObjCIvarDecl *I = ClassDecl->getIvarDecl(ID)) {
+      clsDeclared = ClassDecl;
+      return I;
+    }
+    if (const ObjCCategoryDecl *CDecl = ClassDecl->getClassExtension())
+      if (ObjCIvarDecl *I = CDecl->getIvarDecl(ID)) {
+        clsDeclared = ClassDecl;
+        return I;
+      }
+      
+    ClassDecl = ClassDecl->getSuperClass();
+  }
+  return NULL;
+}
+
+/// lookupInheritedClass - This method returns ObjCInterfaceDecl * of the super
+/// class whose name is passed as argument. If it is not one of the super classes
+/// the it returns NULL.
+ObjCInterfaceDecl *ObjCInterfaceDecl::lookupInheritedClass(
+                                        const IdentifierInfo*ICName) {
+  ObjCInterfaceDecl* ClassDecl = this;
+  while (ClassDecl != NULL) {
+    if (ClassDecl->getIdentifier() == ICName)
+      return ClassDecl;
+    ClassDecl = ClassDecl->getSuperClass();
+  }
+  return NULL;
+}
+
+/// lookupMethod - This method returns an instance/class method by looking in
+/// the class, its categories, and its super classes (using a linear search).
+ObjCMethodDecl *ObjCInterfaceDecl::lookupMethod(Selector Sel,
+                                                bool isInstance) const {
+  const ObjCInterfaceDecl* ClassDecl = this;
+  ObjCMethodDecl *MethodDecl = 0;
+
+  while (ClassDecl != NULL) {
+    if ((MethodDecl = ClassDecl->getMethod(Sel, isInstance)))
+      return MethodDecl;
+
+    // Didn't find one yet - look through protocols.
+    const ObjCList<ObjCProtocolDecl> &Protocols =
+      ClassDecl->getReferencedProtocols();
+    for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
+         E = Protocols.end(); I != E; ++I)
+      if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance)))
+        return MethodDecl;
+
+    // Didn't find one yet - now look through categories.
+    ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
+    while (CatDecl) {
+      if ((MethodDecl = CatDecl->getMethod(Sel, isInstance)))
+        return MethodDecl;
+
+      // Didn't find one yet - look through protocols.
+      const ObjCList<ObjCProtocolDecl> &Protocols =
+        CatDecl->getReferencedProtocols();
+      for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
+           E = Protocols.end(); I != E; ++I)
+        if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance)))
+          return MethodDecl;
+      CatDecl = CatDecl->getNextClassCategory();
+    }
+    ClassDecl = ClassDecl->getSuperClass();
+  }
+  return NULL;
+}
+
+ObjCMethodDecl *ObjCInterfaceDecl::lookupPrivateInstanceMethod(
+                                   const Selector &Sel) {
+  ObjCMethodDecl *Method = 0;
+  if (ObjCImplementationDecl *ImpDecl = getImplementation())
+    Method = ImpDecl->getInstanceMethod(Sel);
+  
+  if (!Method && getSuperClass())
+    return getSuperClass()->lookupPrivateInstanceMethod(Sel);
+  return Method;
+}
+
+//===----------------------------------------------------------------------===//
+// ObjCMethodDecl
+//===----------------------------------------------------------------------===//
+
+ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C,
+                                       SourceLocation beginLoc,
+                                       SourceLocation endLoc,
+                                       Selector SelInfo, QualType T,
+                                       TypeSourceInfo *ResultTInfo,
+                                       DeclContext *contextDecl,
+                                       bool isInstance,
+                                       bool isVariadic,
+                                       bool isSynthesized,
+                                       ImplementationControl impControl,
+                                       unsigned numSelectorArgs) {
+  return new (C) ObjCMethodDecl(beginLoc, endLoc,
+                                SelInfo, T, ResultTInfo, contextDecl,
+                                isInstance,
+                                isVariadic, isSynthesized, impControl,
+                                numSelectorArgs);
+}
+
+void ObjCMethodDecl::Destroy(ASTContext &C) {
+  if (Body) Body->Destroy(C);
+  if (SelfDecl) SelfDecl->Destroy(C);
+
+  for (param_iterator I=param_begin(), E=param_end(); I!=E; ++I)
+    if (*I) (*I)->Destroy(C);
+
+  ParamInfo.Destroy(C);
+
+  Decl::Destroy(C);
+}
+
+/// \brief A definition will return its interface declaration.
+/// An interface declaration will return its definition.
+/// Otherwise it will return itself.
+ObjCMethodDecl *ObjCMethodDecl::getNextRedeclaration() {
+  ASTContext &Ctx = getASTContext();
+  ObjCMethodDecl *Redecl = 0;
+  Decl *CtxD = cast<Decl>(getDeclContext());
+
+  if (ObjCInterfaceDecl *IFD = dyn_cast<ObjCInterfaceDecl>(CtxD)) {
+    if (ObjCImplementationDecl *ImplD = Ctx.getObjCImplementation(IFD))
+      Redecl = ImplD->getMethod(getSelector(), isInstanceMethod());
+
+  } else if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(CtxD)) {
+    if (ObjCCategoryImplDecl *ImplD = Ctx.getObjCImplementation(CD))
+      Redecl = ImplD->getMethod(getSelector(), isInstanceMethod());
+
+  } else if (ObjCImplementationDecl *ImplD =
+               dyn_cast<ObjCImplementationDecl>(CtxD)) {
+    if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
+      Redecl = IFD->getMethod(getSelector(), isInstanceMethod());
+
+  } else if (ObjCCategoryImplDecl *CImplD =
+               dyn_cast<ObjCCategoryImplDecl>(CtxD)) {
+    if (ObjCCategoryDecl *CatD = CImplD->getCategoryDecl())
+      Redecl = CatD->getMethod(getSelector(), isInstanceMethod());
+  }
+
+  return Redecl ? Redecl : this;
+}
+
+ObjCMethodDecl *ObjCMethodDecl::getCanonicalDecl() {
+  Decl *CtxD = cast<Decl>(getDeclContext());
+
+  if (ObjCImplementationDecl *ImplD = dyn_cast<ObjCImplementationDecl>(CtxD)) {
+    if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
+      if (ObjCMethodDecl *MD = IFD->getMethod(getSelector(),
+                                              isInstanceMethod()))
+        return MD;
+
+  } else if (ObjCCategoryImplDecl *CImplD =
+               dyn_cast<ObjCCategoryImplDecl>(CtxD)) {
+    if (ObjCCategoryDecl *CatD = CImplD->getCategoryDecl())
+      if (ObjCMethodDecl *MD = CatD->getMethod(getSelector(),
+                                               isInstanceMethod()))
+        return MD;
+  }
+
+  return this;
+}
+
+void ObjCMethodDecl::createImplicitParams(ASTContext &Context,
+                                          const ObjCInterfaceDecl *OID) {
+  QualType selfTy;
+  if (isInstanceMethod()) {
+    // There may be no interface context due to error in declaration
+    // of the interface (which has been reported). Recover gracefully.
+    if (OID) {
+      selfTy = Context.getObjCInterfaceType(OID);
+      selfTy = Context.getObjCObjectPointerType(selfTy);
+    } else {
+      selfTy = Context.getObjCIdType();
+    }
+  } else // we have a factory method.
+    selfTy = Context.getObjCClassType();
+
+  setSelfDecl(ImplicitParamDecl::Create(Context, this, SourceLocation(),
+                                        &Context.Idents.get("self"), selfTy));
+
+  setCmdDecl(ImplicitParamDecl::Create(Context, this, SourceLocation(),
+                                       &Context.Idents.get("_cmd"),
+                                       Context.getObjCSelType()));
+}
+
+ObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() {
+  if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(getDeclContext()))
+    return ID;
+  if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(getDeclContext()))
+    return CD->getClassInterface();
+  if (ObjCImplDecl *IMD = dyn_cast<ObjCImplDecl>(getDeclContext()))
+    return IMD->getClassInterface();
+
+  assert(!isa<ObjCProtocolDecl>(getDeclContext()) && "It's a protocol method");
+  assert(false && "unknown method context");
+  return 0;
+}
+
+//===----------------------------------------------------------------------===//
+// ObjCInterfaceDecl
+//===----------------------------------------------------------------------===//
+
+ObjCInterfaceDecl *ObjCInterfaceDecl::Create(ASTContext &C,
+                                             DeclContext *DC,
+                                             SourceLocation atLoc,
+                                             IdentifierInfo *Id,
+                                             SourceLocation ClassLoc,
+                                             bool ForwardDecl, bool isInternal){
+  return new (C) ObjCInterfaceDecl(DC, atLoc, Id, ClassLoc, ForwardDecl,
+                                     isInternal);
+}
+
+ObjCInterfaceDecl::
+ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id,
+                  SourceLocation CLoc, bool FD, bool isInternal)
+  : ObjCContainerDecl(ObjCInterface, DC, atLoc, Id),
+    TypeForDecl(0), SuperClass(0),
+    CategoryList(0), ForwardDecl(FD), InternalInterface(isInternal),
+    ClassLoc(CLoc) {
+}
+
+void ObjCInterfaceDecl::Destroy(ASTContext &C) {
+  for (ivar_iterator I = ivar_begin(), E = ivar_end(); I != E; ++I)
+    if (*I) (*I)->Destroy(C);
+
+  // FIXME: CategoryList?
+
+  // FIXME: Because there is no clear ownership
+  //  role between ObjCInterfaceDecls and the ObjCPropertyDecls that they
+  //  reference, we destroy ObjCPropertyDecls in ~TranslationUnit.
+  Decl::Destroy(C);
+}
+
+ObjCImplementationDecl *ObjCInterfaceDecl::getImplementation() const {
+  return getASTContext().getObjCImplementation(
+                                          const_cast<ObjCInterfaceDecl*>(this));
+}
+
+void ObjCInterfaceDecl::setImplementation(ObjCImplementationDecl *ImplD) {
+  getASTContext().setObjCImplementation(this, ImplD);
+}
+
+
+/// FindCategoryDeclaration - Finds category declaration in the list of
+/// categories for this class and returns it. Name of the category is passed
+/// in 'CategoryId'. If category not found, return 0;
+///
+ObjCCategoryDecl *
+ObjCInterfaceDecl::FindCategoryDeclaration(IdentifierInfo *CategoryId) const {
+  for (ObjCCategoryDecl *Category = getCategoryList();
+       Category; Category = Category->getNextClassCategory())
+    if (Category->getIdentifier() == CategoryId)
+      return Category;
+  return 0;
+}
+
+ObjCMethodDecl *
+ObjCInterfaceDecl::getCategoryInstanceMethod(Selector Sel) const {
+  for (ObjCCategoryDecl *Category = getCategoryList();
+       Category; Category = Category->getNextClassCategory())
+    if (ObjCCategoryImplDecl *Impl = Category->getImplementation())
+      if (ObjCMethodDecl *MD = Impl->getInstanceMethod(Sel))
+        return MD;
+  return 0;
+}
+
+ObjCMethodDecl *ObjCInterfaceDecl::getCategoryClassMethod(Selector Sel) const {
+  for (ObjCCategoryDecl *Category = getCategoryList();
+       Category; Category = Category->getNextClassCategory())
+    if (ObjCCategoryImplDecl *Impl = Category->getImplementation())
+      if (ObjCMethodDecl *MD = Impl->getClassMethod(Sel))
+        return MD;
+  return 0;
+}
+
+/// ClassImplementsProtocol - Checks that 'lProto' protocol
+/// has been implemented in IDecl class, its super class or categories (if
+/// lookupCategory is true).
+bool ObjCInterfaceDecl::ClassImplementsProtocol(ObjCProtocolDecl *lProto,
+                                    bool lookupCategory,
+                                    bool RHSIsQualifiedID) {
+  ObjCInterfaceDecl *IDecl = this;
+  // 1st, look up the class.
+  const ObjCList<ObjCProtocolDecl> &Protocols =
+  IDecl->getReferencedProtocols();
+
+  for (ObjCList<ObjCProtocolDecl>::iterator PI = Protocols.begin(),
+       E = Protocols.end(); PI != E; ++PI) {
+    if (getASTContext().ProtocolCompatibleWithProtocol(lProto, *PI))
+      return true;
+    // This is dubious and is added to be compatible with gcc.  In gcc, it is
+    // also allowed assigning a protocol-qualified 'id' type to a LHS object
+    // when protocol in qualified LHS is in list of protocols in the rhs 'id'
+    // object. This IMO, should be a bug.
+    // FIXME: Treat this as an extension, and flag this as an error when GCC
+    // extensions are not enabled.
+    if (RHSIsQualifiedID &&
+        getASTContext().ProtocolCompatibleWithProtocol(*PI, lProto))
+      return true;
+  }
+
+  // 2nd, look up the category.
+  if (lookupCategory)
+    for (ObjCCategoryDecl *CDecl = IDecl->getCategoryList(); CDecl;
+         CDecl = CDecl->getNextClassCategory()) {
+      for (ObjCCategoryDecl::protocol_iterator PI = CDecl->protocol_begin(),
+           E = CDecl->protocol_end(); PI != E; ++PI)
+        if (getASTContext().ProtocolCompatibleWithProtocol(lProto, *PI))
+          return true;
+    }
+
+  // 3rd, look up the super class(s)
+  if (IDecl->getSuperClass())
+    return
+  IDecl->getSuperClass()->ClassImplementsProtocol(lProto, lookupCategory,
+                                                  RHSIsQualifiedID);
+
+  return false;
+}
+
+//===----------------------------------------------------------------------===//
+// ObjCIvarDecl
+//===----------------------------------------------------------------------===//
+
+ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, ObjCContainerDecl *DC,
+                                   SourceLocation L, IdentifierInfo *Id,
+                                   QualType T, TypeSourceInfo *TInfo,
+                                   AccessControl ac, Expr *BW) {
+  if (DC) {
+    // Ivar's can only appear in interfaces, implementations (via synthesized
+    // properties), and class extensions (via direct declaration, or synthesized
+    // properties).
+    //
+    // FIXME: This should really be asserting this:
+    //   (isa<ObjCCategoryDecl>(DC) &&
+    //    cast<ObjCCategoryDecl>(DC)->IsClassExtension()))
+    // but unfortunately we sometimes place ivars into non-class extension
+    // categories on error. This breaks an AST invariant, and should not be
+    // fixed.
+    assert((isa<ObjCInterfaceDecl>(DC) || isa<ObjCImplementationDecl>(DC) ||
+            isa<ObjCCategoryDecl>(DC)) &&
+           "Invalid ivar decl context!");
+  }
+
+  return new (C) ObjCIvarDecl(DC, L, Id, T, TInfo, ac, BW);
+}
+
+const ObjCInterfaceDecl *ObjCIvarDecl::getContainingInterface() const {
+  const ObjCContainerDecl *DC = cast<ObjCContainerDecl>(getDeclContext());
+
+  switch (DC->getKind()) {
+  default:
+  case ObjCCategoryImpl:
+  case ObjCProtocol:
+    assert(0 && "invalid ivar container!");
+    return 0;
+
+    // Ivars can only appear in class extension categories.
+  case ObjCCategory: {
+    const ObjCCategoryDecl *CD = cast<ObjCCategoryDecl>(DC);
+    assert(CD->IsClassExtension() && "invalid container for ivar!");
+    return CD->getClassInterface();
+  }
+
+  case ObjCImplementation:
+    return cast<ObjCImplementationDecl>(DC)->getClassInterface();
+
+  case ObjCInterface:
+    return cast<ObjCInterfaceDecl>(DC);
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// ObjCAtDefsFieldDecl
+//===----------------------------------------------------------------------===//
+
+ObjCAtDefsFieldDecl
+*ObjCAtDefsFieldDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
+                             IdentifierInfo *Id, QualType T, Expr *BW) {
+  return new (C) ObjCAtDefsFieldDecl(DC, L, Id, T, BW);
+}
+
+void ObjCAtDefsFieldDecl::Destroy(ASTContext& C) {
+  this->~ObjCAtDefsFieldDecl();
+  C.Deallocate((void *)this);
+}
+
+//===----------------------------------------------------------------------===//
+// ObjCProtocolDecl
+//===----------------------------------------------------------------------===//
+
+ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C, DeclContext *DC,
+                                           SourceLocation L,
+                                           IdentifierInfo *Id) {
+  return new (C) ObjCProtocolDecl(DC, L, Id);
+}
+
+void ObjCProtocolDecl::Destroy(ASTContext &C) {
+  ReferencedProtocols.Destroy(C);
+  ObjCContainerDecl::Destroy(C);
+}
+
+ObjCProtocolDecl *ObjCProtocolDecl::lookupProtocolNamed(IdentifierInfo *Name) {
+  ObjCProtocolDecl *PDecl = this;
+
+  if (Name == getIdentifier())
+    return PDecl;
+
+  for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
+    if ((PDecl = (*I)->lookupProtocolNamed(Name)))
+      return PDecl;
+
+  return NULL;
+}
+
+// lookupMethod - Lookup a instance/class method in the protocol and protocols
+// it inherited.
+ObjCMethodDecl *ObjCProtocolDecl::lookupMethod(Selector Sel,
+                                               bool isInstance) const {
+  ObjCMethodDecl *MethodDecl = NULL;
+
+  if ((MethodDecl = getMethod(Sel, isInstance)))
+    return MethodDecl;
+
+  for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
+    if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance)))
+      return MethodDecl;
+  return NULL;
+}
+
+//===----------------------------------------------------------------------===//
+// ObjCClassDecl
+//===----------------------------------------------------------------------===//
+
+ObjCClassDecl::ObjCClassDecl(DeclContext *DC, SourceLocation L,
+                             ObjCInterfaceDecl *const *Elts,
+                             const SourceLocation *Locs,
+                             unsigned nElts,
+                             ASTContext &C)
+  : Decl(ObjCClass, DC, L) {
+  setClassList(C, Elts, Locs, nElts);
+}
+
+void ObjCClassDecl::setClassList(ASTContext &C, ObjCInterfaceDecl*const*List,
+                                 const SourceLocation *Locs, unsigned Num) {
+  ForwardDecls = (ObjCClassRef*) C.Allocate(sizeof(ObjCClassRef)*Num,
+                                            llvm::alignof<ObjCClassRef>());
+  for (unsigned i = 0; i < Num; ++i)
+    new (&ForwardDecls[i]) ObjCClassRef(List[i], Locs[i]);
+  
+  NumDecls = Num;
+}
+
+ObjCClassDecl *ObjCClassDecl::Create(ASTContext &C, DeclContext *DC,
+                                     SourceLocation L,
+                                     ObjCInterfaceDecl *const *Elts,
+                                     const SourceLocation *Locs,
+                                     unsigned nElts) {
+  return new (C) ObjCClassDecl(DC, L, Elts, Locs, nElts, C);
+}
+
+void ObjCClassDecl::Destroy(ASTContext &C) {
+  // ObjCInterfaceDecls registered with a DeclContext will get destroyed
+  // when the DeclContext is destroyed.  For those created only by a forward
+  // declaration, the first @class that created the ObjCInterfaceDecl gets
+  // to destroy it.
+  // FIXME: Note that this ownership role is very brittle; a better
+  // polict is surely need in the future.
+  for (iterator I = begin(), E = end(); I !=E ; ++I) {
+    ObjCInterfaceDecl *ID = I->getInterface();
+    if (ID->isForwardDecl() && ID->getLocStart() == getLocStart())
+      ID->Destroy(C);
+  }
+  
+  C.Deallocate(ForwardDecls);
+  Decl::Destroy(C);
+}
+
+SourceRange ObjCClassDecl::getSourceRange() const {
+  // FIXME: We should include the semicolon
+  assert(NumDecls);
+  return SourceRange(getLocation(), ForwardDecls[NumDecls-1].getLocation());
+}
+
+//===----------------------------------------------------------------------===//
+// ObjCForwardProtocolDecl
+//===----------------------------------------------------------------------===//
+
+ObjCForwardProtocolDecl::
+ObjCForwardProtocolDecl(DeclContext *DC, SourceLocation L,
+                        ObjCProtocolDecl *const *Elts, unsigned nElts,
+                        const SourceLocation *Locs, ASTContext &C)
+: Decl(ObjCForwardProtocol, DC, L) {
+  ReferencedProtocols.set(Elts, nElts, Locs, C);
+}
+
+
+ObjCForwardProtocolDecl *
+ObjCForwardProtocolDecl::Create(ASTContext &C, DeclContext *DC,
+                                SourceLocation L,
+                                ObjCProtocolDecl *const *Elts,
+                                unsigned NumElts,
+                                const SourceLocation *Locs) {
+  return new (C) ObjCForwardProtocolDecl(DC, L, Elts, NumElts, Locs, C);
+}
+
+void ObjCForwardProtocolDecl::Destroy(ASTContext &C) {
+  ReferencedProtocols.Destroy(C);
+  Decl::Destroy(C);
+}
+
+//===----------------------------------------------------------------------===//
+// ObjCCategoryDecl
+//===----------------------------------------------------------------------===//
+
+ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C, DeclContext *DC,
+                                           SourceLocation AtLoc, 
+                                           SourceLocation ClassNameLoc,
+                                           SourceLocation CategoryNameLoc,
+                                           IdentifierInfo *Id) {
+  return new (C) ObjCCategoryDecl(DC, AtLoc, ClassNameLoc, CategoryNameLoc, Id);
+}
+
+ObjCCategoryImplDecl *ObjCCategoryDecl::getImplementation() const {
+  return getASTContext().getObjCImplementation(
+                                           const_cast<ObjCCategoryDecl*>(this));
+}
+
+void ObjCCategoryDecl::setImplementation(ObjCCategoryImplDecl *ImplD) {
+  getASTContext().setObjCImplementation(this, ImplD);
+}
+
+
+//===----------------------------------------------------------------------===//
+// ObjCCategoryImplDecl
+//===----------------------------------------------------------------------===//
+
+ObjCCategoryImplDecl *
+ObjCCategoryImplDecl::Create(ASTContext &C, DeclContext *DC,
+                             SourceLocation L,IdentifierInfo *Id,
+                             ObjCInterfaceDecl *ClassInterface) {
+  return new (C) ObjCCategoryImplDecl(DC, L, Id, ClassInterface);
+}
+
+ObjCCategoryDecl *ObjCCategoryImplDecl::getCategoryDecl() const {
+  // The class interface might be NULL if we are working with invalid code.
+  if (const ObjCInterfaceDecl *ID = getClassInterface())
+    return ID->FindCategoryDeclaration(getIdentifier());
+  return 0;
+}
+
+
+void ObjCImplDecl::addPropertyImplementation(ObjCPropertyImplDecl *property) {
+  // FIXME: The context should be correct before we get here.
+  property->setLexicalDeclContext(this);
+  addDecl(property);
+}
+
+void ObjCImplDecl::setClassInterface(ObjCInterfaceDecl *IFace) {
+  ASTContext &Ctx = getASTContext();
+
+  if (ObjCImplementationDecl *ImplD
+        = dyn_cast_or_null<ObjCImplementationDecl>(this)) {
+    if (IFace)
+      Ctx.setObjCImplementation(IFace, ImplD);
+
+  } else if (ObjCCategoryImplDecl *ImplD =
+             dyn_cast_or_null<ObjCCategoryImplDecl>(this)) {
+    if (ObjCCategoryDecl *CD = IFace->FindCategoryDeclaration(getIdentifier()))
+      Ctx.setObjCImplementation(CD, ImplD);
+  }
+
+  ClassInterface = IFace;
+}
+
+/// FindPropertyImplIvarDecl - This method lookup the ivar in the list of
+/// properties implemented in this category @implementation block and returns
+/// the implemented property that uses it.
+///
+ObjCPropertyImplDecl *ObjCImplDecl::
+FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const {
+  for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i){
+    ObjCPropertyImplDecl *PID = *i;
+    if (PID->getPropertyIvarDecl() &&
+        PID->getPropertyIvarDecl()->getIdentifier() == ivarId)
+      return PID;
+  }
+  return 0;
+}
+
+/// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl
+/// added to the list of those properties @synthesized/@dynamic in this
+/// category @implementation block.
+///
+ObjCPropertyImplDecl *ObjCImplDecl::
+FindPropertyImplDecl(IdentifierInfo *Id) const {
+  for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i){
+    ObjCPropertyImplDecl *PID = *i;
+    if (PID->getPropertyDecl()->getIdentifier() == Id)
+      return PID;
+  }
+  return 0;
+}
+
+llvm::raw_ostream &clang::operator<<(llvm::raw_ostream &OS,
+                                     const ObjCCategoryImplDecl *CID) {
+  OS << CID->getName();
+  return OS;
+}
+
+//===----------------------------------------------------------------------===//
+// ObjCImplementationDecl
+//===----------------------------------------------------------------------===//
+
+ObjCImplementationDecl *
+ObjCImplementationDecl::Create(ASTContext &C, DeclContext *DC,
+                               SourceLocation L,
+                               ObjCInterfaceDecl *ClassInterface,
+                               ObjCInterfaceDecl *SuperDecl) {
+  return new (C) ObjCImplementationDecl(DC, L, ClassInterface, SuperDecl);
+}
+
+llvm::raw_ostream &clang::operator<<(llvm::raw_ostream &OS,
+                                     const ObjCImplementationDecl *ID) {
+  OS << ID->getName();
+  return OS;
+}
+
+//===----------------------------------------------------------------------===//
+// ObjCCompatibleAliasDecl
+//===----------------------------------------------------------------------===//
+
+ObjCCompatibleAliasDecl *
+ObjCCompatibleAliasDecl::Create(ASTContext &C, DeclContext *DC,
+                                SourceLocation L,
+                                IdentifierInfo *Id,
+                                ObjCInterfaceDecl* AliasedClass) {
+  return new (C) ObjCCompatibleAliasDecl(DC, L, Id, AliasedClass);
+}
+
+//===----------------------------------------------------------------------===//
+// ObjCPropertyDecl
+//===----------------------------------------------------------------------===//
+
+ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C, DeclContext *DC,
+                                           SourceLocation L,
+                                           IdentifierInfo *Id,
+                                           SourceLocation AtLoc,
+                                           QualType T,
+                                           PropertyControl propControl) {
+  return new (C) ObjCPropertyDecl(DC, L, Id, AtLoc, T);
+}
+
+
+//===----------------------------------------------------------------------===//
+// ObjCPropertyImplDecl
+//===----------------------------------------------------------------------===//
+
+ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C,
+                                                   DeclContext *DC,
+                                                   SourceLocation atLoc,
+                                                   SourceLocation L,
+                                                   ObjCPropertyDecl *property,
+                                                   Kind PK,
+                                                   ObjCIvarDecl *ivar) {
+  return new (C) ObjCPropertyImplDecl(DC, atLoc, L, property, PK, ivar);
+}
+
+
diff --git a/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp
new file mode 100644
index 0000000..5394924
--- /dev/null
+++ b/lib/AST/DeclPrinter.cpp
@@ -0,0 +1,881 @@
+//===--- DeclPrinter.cpp - Printing implementation for Decl ASTs ----------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Decl::dump method, which pretty print the
+// AST back out to C/Objective-C/C++/Objective-C++ code.
+//
+//===----------------------------------------------------------------------===//
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclVisitor.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/PrettyPrinter.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace clang;
+
+namespace {
+  class DeclPrinter : public DeclVisitor<DeclPrinter> {
+    llvm::raw_ostream &Out;
+    ASTContext &Context;
+    PrintingPolicy Policy;
+    unsigned Indentation;
+
+    llvm::raw_ostream& Indent() { return Indent(Indentation); }
+    llvm::raw_ostream& Indent(unsigned Indentation);
+    void ProcessDeclGroup(llvm::SmallVectorImpl<Decl*>& Decls);
+
+    void Print(AccessSpecifier AS);
+
+  public:
+    DeclPrinter(llvm::raw_ostream &Out, ASTContext &Context,
+                const PrintingPolicy &Policy,
+                unsigned Indentation = 0)
+      : Out(Out), Context(Context), Policy(Policy), Indentation(Indentation) { }
+
+    void VisitDeclContext(DeclContext *DC, bool Indent = true);
+
+    void VisitTranslationUnitDecl(TranslationUnitDecl *D);
+    void VisitTypedefDecl(TypedefDecl *D);
+    void VisitEnumDecl(EnumDecl *D);
+    void VisitRecordDecl(RecordDecl *D);
+    void VisitEnumConstantDecl(EnumConstantDecl *D);
+    void VisitFunctionDecl(FunctionDecl *D);
+    void VisitFieldDecl(FieldDecl *D);
+    void VisitVarDecl(VarDecl *D);
+    void VisitParmVarDecl(ParmVarDecl *D);
+    void VisitFileScopeAsmDecl(FileScopeAsmDecl *D);
+    void VisitNamespaceDecl(NamespaceDecl *D);
+    void VisitUsingDirectiveDecl(UsingDirectiveDecl *D);
+    void VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
+    void VisitCXXRecordDecl(CXXRecordDecl *D);
+    void VisitLinkageSpecDecl(LinkageSpecDecl *D);
+    void VisitTemplateDecl(TemplateDecl *D);
+    void VisitObjCMethodDecl(ObjCMethodDecl *D);
+    void VisitObjCClassDecl(ObjCClassDecl *D);
+    void VisitObjCImplementationDecl(ObjCImplementationDecl *D);
+    void VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
+    void VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D);
+    void VisitObjCProtocolDecl(ObjCProtocolDecl *D);
+    void VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D);
+    void VisitObjCCategoryDecl(ObjCCategoryDecl *D);
+    void VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *D);
+    void VisitObjCPropertyDecl(ObjCPropertyDecl *D);
+    void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D);
+    void VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D);
+    void VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D);
+    void VisitUsingDecl(UsingDecl *D);
+    void VisitUsingShadowDecl(UsingShadowDecl *D);
+  };
+}
+
+void Decl::print(llvm::raw_ostream &Out, unsigned Indentation) const {
+  print(Out, getASTContext().PrintingPolicy, Indentation);
+}
+
+void Decl::print(llvm::raw_ostream &Out, const PrintingPolicy &Policy,
+                 unsigned Indentation) const {
+  DeclPrinter Printer(Out, getASTContext(), Policy, Indentation);
+  Printer.Visit(const_cast<Decl*>(this));
+}
+
+static QualType GetBaseType(QualType T) {
+  // FIXME: This should be on the Type class!
+  QualType BaseType = T;
+  while (!BaseType->isSpecifierType()) {
+    if (isa<TypedefType>(BaseType))
+      break;
+    else if (const PointerType* PTy = BaseType->getAs<PointerType>())
+      BaseType = PTy->getPointeeType();
+    else if (const ArrayType* ATy = dyn_cast<ArrayType>(BaseType))
+      BaseType = ATy->getElementType();
+    else if (const FunctionType* FTy = BaseType->getAs<FunctionType>())
+      BaseType = FTy->getResultType();
+    else if (const VectorType *VTy = BaseType->getAs<VectorType>())
+      BaseType = VTy->getElementType();
+    else
+      assert(0 && "Unknown declarator!");
+  }
+  return BaseType;
+}
+
+static QualType getDeclType(Decl* D) {
+  if (TypedefDecl* TDD = dyn_cast<TypedefDecl>(D))
+    return TDD->getUnderlyingType();
+  if (ValueDecl* VD = dyn_cast<ValueDecl>(D))
+    return VD->getType();
+  return QualType();
+}
+
+void Decl::printGroup(Decl** Begin, unsigned NumDecls,
+                      llvm::raw_ostream &Out, const PrintingPolicy &Policy,
+                      unsigned Indentation) {
+  if (NumDecls == 1) {
+    (*Begin)->print(Out, Policy, Indentation);
+    return;
+  }
+
+  Decl** End = Begin + NumDecls;
+  TagDecl* TD = dyn_cast<TagDecl>(*Begin);
+  if (TD)
+    ++Begin;
+
+  PrintingPolicy SubPolicy(Policy);
+  if (TD && TD->isDefinition()) {
+    TD->print(Out, Policy, Indentation);
+    Out << " ";
+    SubPolicy.SuppressTag = true;
+  }
+
+  bool isFirst = true;
+  for ( ; Begin != End; ++Begin) {
+    if (isFirst) {
+      SubPolicy.SuppressSpecifiers = false;
+      isFirst = false;
+    } else {
+      if (!isFirst) Out << ", ";
+      SubPolicy.SuppressSpecifiers = true;
+    }
+
+    (*Begin)->print(Out, SubPolicy, Indentation);
+  }
+}
+
+void DeclContext::dumpDeclContext() const {
+  // Get the translation unit
+  const DeclContext *DC = this;
+  while (!DC->isTranslationUnit())
+    DC = DC->getParent();
+  
+  ASTContext &Ctx = cast<TranslationUnitDecl>(DC)->getASTContext();
+  DeclPrinter Printer(llvm::errs(), Ctx, Ctx.PrintingPolicy, 0);
+  Printer.VisitDeclContext(const_cast<DeclContext *>(this), /*Indent=*/false);
+}
+
+void Decl::dump() const {
+  print(llvm::errs());
+}
+
+llvm::raw_ostream& DeclPrinter::Indent(unsigned Indentation) {
+  for (unsigned i = 0; i != Indentation; ++i)
+    Out << "  ";
+  return Out;
+}
+
+void DeclPrinter::ProcessDeclGroup(llvm::SmallVectorImpl<Decl*>& Decls) {
+  this->Indent();
+  Decl::printGroup(Decls.data(), Decls.size(), Out, Policy, Indentation);
+  Out << ";\n";
+  Decls.clear();
+
+}
+
+void DeclPrinter::Print(AccessSpecifier AS) {
+  switch(AS) {
+  case AS_none:      assert(0 && "No access specifier!"); break;
+  case AS_public:    Out << "public"; break;
+  case AS_protected: Out << "protected"; break;
+  case AS_private:   Out << " private"; break;
+  }
+}
+
+//----------------------------------------------------------------------------
+// Common C declarations
+//----------------------------------------------------------------------------
+
+void DeclPrinter::VisitDeclContext(DeclContext *DC, bool Indent) {
+  if (Indent)
+    Indentation += Policy.Indentation;
+
+  bool PrintAccess = isa<CXXRecordDecl>(DC);
+  AccessSpecifier CurAS = AS_none;
+
+  llvm::SmallVector<Decl*, 2> Decls;
+  for (DeclContext::decl_iterator D = DC->decls_begin(), DEnd = DC->decls_end();
+       D != DEnd; ++D) {
+    if (!Policy.Dump) {
+      // Skip over implicit declarations in pretty-printing mode.
+      if (D->isImplicit()) continue;
+      // FIXME: Ugly hack so we don't pretty-print the builtin declaration
+      // of __builtin_va_list.  There should be some other way to check that.
+      if (isa<NamedDecl>(*D) && cast<NamedDecl>(*D)->getNameAsString() ==
+          "__builtin_va_list")
+        continue;
+    }
+
+    if (PrintAccess) {
+      AccessSpecifier AS = D->getAccess();
+
+      if (AS != CurAS) {
+        if (Indent)
+          this->Indent(Indentation - Policy.Indentation);
+        Print(AS);
+        Out << ":\n";
+        CurAS = AS;
+      }
+    }
+
+    // The next bits of code handles stuff like "struct {int x;} a,b"; we're
+    // forced to merge the declarations because there's no other way to
+    // refer to the struct in question.  This limited merging is safe without
+    // a bunch of other checks because it only merges declarations directly
+    // referring to the tag, not typedefs.
+    //
+    // Check whether the current declaration should be grouped with a previous
+    // unnamed struct.
+    QualType CurDeclType = getDeclType(*D);
+    if (!Decls.empty() && !CurDeclType.isNull()) {
+      QualType BaseType = GetBaseType(CurDeclType);
+      if (!BaseType.isNull() && isa<TagType>(BaseType) &&
+          cast<TagType>(BaseType)->getDecl() == Decls[0]) {
+        Decls.push_back(*D);
+        continue;
+      }
+    }
+
+    // If we have a merged group waiting to be handled, handle it now.
+    if (!Decls.empty())
+      ProcessDeclGroup(Decls);
+
+    // If the current declaration is an unnamed tag type, save it
+    // so we can merge it with the subsequent declaration(s) using it.
+    if (isa<TagDecl>(*D) && !cast<TagDecl>(*D)->getIdentifier()) {
+      Decls.push_back(*D);
+      continue;
+    }
+    this->Indent();
+    Visit(*D);
+
+    // FIXME: Need to be able to tell the DeclPrinter when
+    const char *Terminator = 0;
+    if (isa<FunctionDecl>(*D) &&
+        cast<FunctionDecl>(*D)->isThisDeclarationADefinition())
+      Terminator = 0;
+    else if (isa<ObjCMethodDecl>(*D) && cast<ObjCMethodDecl>(*D)->getBody())
+      Terminator = 0;
+    else if (isa<NamespaceDecl>(*D) || isa<LinkageSpecDecl>(*D) ||
+             isa<ObjCImplementationDecl>(*D) ||
+             isa<ObjCInterfaceDecl>(*D) ||
+             isa<ObjCProtocolDecl>(*D) ||
+             isa<ObjCCategoryImplDecl>(*D) ||
+             isa<ObjCCategoryDecl>(*D))
+      Terminator = 0;
+    else if (isa<EnumConstantDecl>(*D)) {
+      DeclContext::decl_iterator Next = D;
+      ++Next;
+      if (Next != DEnd)
+        Terminator = ",";
+    } else
+      Terminator = ";";
+
+    if (Terminator)
+      Out << Terminator;
+    Out << "\n";
+  }
+
+  if (!Decls.empty())
+    ProcessDeclGroup(Decls);
+
+  if (Indent)
+    Indentation -= Policy.Indentation;
+}
+
+void DeclPrinter::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
+  VisitDeclContext(D, false);
+}
+
+void DeclPrinter::VisitTypedefDecl(TypedefDecl *D) {
+  std::string S = D->getNameAsString();
+  D->getUnderlyingType().getAsStringInternal(S, Policy);
+  if (!Policy.SuppressSpecifiers)
+    Out << "typedef ";
+  Out << S;
+}
+
+void DeclPrinter::VisitEnumDecl(EnumDecl *D) {
+  Out << "enum " << D << " {\n";
+  VisitDeclContext(D);
+  Indent() << "}";
+}
+
+void DeclPrinter::VisitRecordDecl(RecordDecl *D) {
+  Out << D->getKindName();
+  if (D->getIdentifier())
+    Out << ' ' << D;
+
+  if (D->isDefinition()) {
+    Out << " {\n";
+    VisitDeclContext(D);
+    Indent() << "}";
+  }
+}
+
+void DeclPrinter::VisitEnumConstantDecl(EnumConstantDecl *D) {
+  Out << D;
+  if (Expr *Init = D->getInitExpr()) {
+    Out << " = ";
+    Init->printPretty(Out, Context, 0, Policy, Indentation);
+  }
+}
+
+void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {
+  if (!Policy.SuppressSpecifiers) {
+    switch (D->getStorageClass()) {
+    case FunctionDecl::None: break;
+    case FunctionDecl::Extern: Out << "extern "; break;
+    case FunctionDecl::Static: Out << "static "; break;
+    case FunctionDecl::PrivateExtern: Out << "__private_extern__ "; break;
+    }
+
+    if (D->isInlineSpecified())           Out << "inline ";
+    if (D->isVirtualAsWritten()) Out << "virtual ";
+  }
+
+  PrintingPolicy SubPolicy(Policy);
+  SubPolicy.SuppressSpecifiers = false;
+  std::string Proto = D->getNameAsString();
+  if (isa<FunctionType>(D->getType().getTypePtr())) {
+    const FunctionType *AFT = D->getType()->getAs<FunctionType>();
+
+    const FunctionProtoType *FT = 0;
+    if (D->hasWrittenPrototype())
+      FT = dyn_cast<FunctionProtoType>(AFT);
+
+    Proto += "(";
+    if (FT) {
+      llvm::raw_string_ostream POut(Proto);
+      DeclPrinter ParamPrinter(POut, Context, SubPolicy, Indentation);
+      for (unsigned i = 0, e = D->getNumParams(); i != e; ++i) {
+        if (i) POut << ", ";
+        ParamPrinter.VisitParmVarDecl(D->getParamDecl(i));
+      }
+
+      if (FT->isVariadic()) {
+        if (D->getNumParams()) POut << ", ";
+        POut << "...";
+      }
+    } else if (D->isThisDeclarationADefinition() && !D->hasPrototype()) {
+      for (unsigned i = 0, e = D->getNumParams(); i != e; ++i) {
+        if (i)
+          Proto += ", ";
+        Proto += D->getParamDecl(i)->getNameAsString();
+      }
+    }
+
+    Proto += ")";
+    
+    if (FT && FT->hasExceptionSpec()) {
+      Proto += " throw(";
+      if (FT->hasAnyExceptionSpec())
+        Proto += "...";
+      else 
+        for (unsigned I = 0, N = FT->getNumExceptions(); I != N; ++I) {
+          if (I)
+            Proto += ", ";
+          
+          
+          std::string ExceptionType;
+          FT->getExceptionType(I).getAsStringInternal(ExceptionType, SubPolicy);
+          Proto += ExceptionType;
+        }
+      Proto += ")";
+    }
+
+    if (D->hasAttr<NoReturnAttr>())
+      Proto += " __attribute((noreturn))";
+    if (CXXConstructorDecl *CDecl = dyn_cast<CXXConstructorDecl>(D)) {
+      if (CDecl->getNumBaseOrMemberInitializers() > 0) {
+        Proto += " : ";
+        Out << Proto;
+        Proto.clear();
+        for (CXXConstructorDecl::init_const_iterator B = CDecl->init_begin(),
+             E = CDecl->init_end();
+             B != E; ++B) {
+          CXXBaseOrMemberInitializer * BMInitializer = (*B);
+          if (B != CDecl->init_begin())
+            Out << ", ";
+          if (BMInitializer->isMemberInitializer()) {
+            FieldDecl *FD = BMInitializer->getMember();
+            Out << FD;
+          } else {
+            Out << QualType(BMInitializer->getBaseClass(), 0).getAsString();
+          }
+          
+          Out << "(";
+          if (!BMInitializer->getInit()) {
+            // Nothing to print
+          } else {
+            Expr *Init = BMInitializer->getInit();
+            if (CXXExprWithTemporaries *Tmp
+                  = dyn_cast<CXXExprWithTemporaries>(Init))
+              Init = Tmp->getSubExpr();
+            
+            Init = Init->IgnoreParens();
+            
+            Expr *SimpleInit = 0;
+            Expr **Args = 0;
+            unsigned NumArgs = 0;
+            if (ParenListExpr *ParenList = dyn_cast<ParenListExpr>(Init)) {
+              Args = ParenList->getExprs();
+              NumArgs = ParenList->getNumExprs();
+            } else if (CXXConstructExpr *Construct
+                                          = dyn_cast<CXXConstructExpr>(Init)) {
+              Args = Construct->getArgs();
+              NumArgs = Construct->getNumArgs();
+            } else
+              SimpleInit = Init;
+            
+            if (SimpleInit)
+              SimpleInit->printPretty(Out, Context, 0, Policy, Indentation);
+            else {
+              for (unsigned I = 0; I != NumArgs; ++I) {
+                if (isa<CXXDefaultArgExpr>(Args[I]))
+                  break;
+                
+                if (I)
+                  Out << ", ";
+                Args[I]->printPretty(Out, Context, 0, Policy, Indentation);
+              }
+            }
+          }
+          Out << ")";
+        }
+      }
+    }
+    else
+      AFT->getResultType().getAsStringInternal(Proto, Policy);
+  } else {
+    D->getType().getAsStringInternal(Proto, Policy);
+  }
+
+  Out << Proto;
+
+  if (D->isPure())
+    Out << " = 0";
+  else if (D->isDeleted())
+    Out << " = delete";
+  else if (D->isThisDeclarationADefinition()) {
+    if (!D->hasPrototype() && D->getNumParams()) {
+      // This is a K&R function definition, so we need to print the
+      // parameters.
+      Out << '\n';
+      DeclPrinter ParamPrinter(Out, Context, SubPolicy, Indentation);
+      Indentation += Policy.Indentation;
+      for (unsigned i = 0, e = D->getNumParams(); i != e; ++i) {
+        Indent();
+        ParamPrinter.VisitParmVarDecl(D->getParamDecl(i));
+        Out << ";\n";
+      }
+      Indentation -= Policy.Indentation;
+    } else
+      Out << ' ';
+
+    D->getBody()->printPretty(Out, Context, 0, SubPolicy, Indentation);
+    Out << '\n';
+  }
+}
+
+void DeclPrinter::VisitFieldDecl(FieldDecl *D) {
+  if (!Policy.SuppressSpecifiers && D->isMutable())
+    Out << "mutable ";
+
+  std::string Name = D->getNameAsString();
+  D->getType().getAsStringInternal(Name, Policy);
+  Out << Name;
+
+  if (D->isBitField()) {
+    Out << " : ";
+    D->getBitWidth()->printPretty(Out, Context, 0, Policy, Indentation);
+  }
+}
+
+void DeclPrinter::VisitVarDecl(VarDecl *D) {
+  if (!Policy.SuppressSpecifiers && D->getStorageClass() != VarDecl::None)
+    Out << VarDecl::getStorageClassSpecifierString(D->getStorageClass()) << " ";
+
+  if (!Policy.SuppressSpecifiers && D->isThreadSpecified())
+    Out << "__thread ";
+
+  std::string Name = D->getNameAsString();
+  QualType T = D->getType();
+  if (ParmVarDecl *Parm = dyn_cast<ParmVarDecl>(D))
+    T = Parm->getOriginalType();
+  T.getAsStringInternal(Name, Policy);
+  Out << Name;
+  if (D->getInit()) {
+    if (D->hasCXXDirectInitializer())
+      Out << "(";
+    else
+      Out << " = ";
+    D->getInit()->printPretty(Out, Context, 0, Policy, Indentation);
+    if (D->hasCXXDirectInitializer())
+      Out << ")";
+  }
+}
+
+void DeclPrinter::VisitParmVarDecl(ParmVarDecl *D) {
+  VisitVarDecl(D);
+}
+
+void DeclPrinter::VisitFileScopeAsmDecl(FileScopeAsmDecl *D) {
+  Out << "__asm (";
+  D->getAsmString()->printPretty(Out, Context, 0, Policy, Indentation);
+  Out << ")";
+}
+
+//----------------------------------------------------------------------------
+// C++ declarations
+//----------------------------------------------------------------------------
+void DeclPrinter::VisitNamespaceDecl(NamespaceDecl *D) {
+  Out << "namespace " << D << " {\n";
+  VisitDeclContext(D);
+  Indent() << "}";
+}
+
+void DeclPrinter::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
+  Out << "using namespace ";
+  if (D->getQualifier())
+    D->getQualifier()->print(Out, Policy);
+  Out << D->getNominatedNamespaceAsWritten();
+}
+
+void DeclPrinter::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
+  Out << "namespace " << D << " = ";
+  if (D->getQualifier())
+    D->getQualifier()->print(Out, Policy);
+  Out << D->getAliasedNamespace();
+}
+
+void DeclPrinter::VisitCXXRecordDecl(CXXRecordDecl *D) {
+  Out << D->getKindName();
+  if (D->getIdentifier())
+    Out << ' ' << D;
+
+  if (D->isDefinition()) {
+    // Print the base classes
+    if (D->getNumBases()) {
+      Out << " : ";
+      for (CXXRecordDecl::base_class_iterator Base = D->bases_begin(),
+             BaseEnd = D->bases_end(); Base != BaseEnd; ++Base) {
+        if (Base != D->bases_begin())
+          Out << ", ";
+
+        if (Base->isVirtual())
+          Out << "virtual ";
+
+        AccessSpecifier AS = Base->getAccessSpecifierAsWritten();
+        if (AS != AS_none)
+          Print(AS);
+        Out << " " << Base->getType().getAsString(Policy);
+      }
+    }
+
+    // Print the class definition
+    // FIXME: Doesn't print access specifiers, e.g., "public:"
+    Out << " {\n";
+    VisitDeclContext(D);
+    Indent() << "}";
+  }
+}
+
+void DeclPrinter::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
+  const char *l;
+  if (D->getLanguage() == LinkageSpecDecl::lang_c)
+    l = "C";
+  else {
+    assert(D->getLanguage() == LinkageSpecDecl::lang_cxx &&
+           "unknown language in linkage specification");
+    l = "C++";
+  }
+
+  Out << "extern \"" << l << "\" ";
+  if (D->hasBraces()) {
+    Out << "{\n";
+    VisitDeclContext(D);
+    Indent() << "}";
+  } else
+    Visit(*D->decls_begin());
+}
+
+void DeclPrinter::VisitTemplateDecl(TemplateDecl *D) {
+  Out << "template <";
+
+  TemplateParameterList *Params = D->getTemplateParameters();
+  for (unsigned i = 0, e = Params->size(); i != e; ++i) {
+    if (i != 0)
+      Out << ", ";
+
+    const Decl *Param = Params->getParam(i);
+    if (const TemplateTypeParmDecl *TTP =
+          dyn_cast<TemplateTypeParmDecl>(Param)) {
+
+      QualType ParamType =
+        Context.getTypeDeclType(const_cast<TemplateTypeParmDecl*>(TTP));
+
+      if (TTP->wasDeclaredWithTypename())
+        Out << "typename ";
+      else
+        Out << "class ";
+
+      if (TTP->isParameterPack())
+        Out << "... ";
+
+      Out << ParamType.getAsString(Policy);
+
+      if (TTP->hasDefaultArgument()) {
+        Out << " = ";
+        Out << TTP->getDefaultArgument().getAsString(Policy);
+      };
+    } else if (const NonTypeTemplateParmDecl *NTTP =
+                 dyn_cast<NonTypeTemplateParmDecl>(Param)) {
+      Out << NTTP->getType().getAsString(Policy);
+
+      if (IdentifierInfo *Name = NTTP->getIdentifier()) {
+        Out << ' ';
+        Out << Name->getName();
+      }
+
+      if (NTTP->hasDefaultArgument()) {
+        Out << " = ";
+        NTTP->getDefaultArgument()->printPretty(Out, Context, 0, Policy,
+                                                Indentation);
+      }
+    }
+  }
+
+  Out << "> ";
+
+  Visit(D->getTemplatedDecl());
+}
+
+//----------------------------------------------------------------------------
+// Objective-C declarations
+//----------------------------------------------------------------------------
+
+void DeclPrinter::VisitObjCClassDecl(ObjCClassDecl *D) {
+  Out << "@class ";
+  for (ObjCClassDecl::iterator I = D->begin(), E = D->end();
+       I != E; ++I) {
+    if (I != D->begin()) Out << ", ";
+    Out << I->getInterface();
+  }
+}
+
+void DeclPrinter::VisitObjCMethodDecl(ObjCMethodDecl *OMD) {
+  if (OMD->isInstanceMethod())
+    Out << "- ";
+  else
+    Out << "+ ";
+  if (!OMD->getResultType().isNull())
+    Out << '(' << OMD->getResultType().getAsString(Policy) << ")";
+
+  std::string name = OMD->getSelector().getAsString();
+  std::string::size_type pos, lastPos = 0;
+  for (ObjCMethodDecl::param_iterator PI = OMD->param_begin(),
+       E = OMD->param_end(); PI != E; ++PI) {
+    // FIXME: selector is missing here!
+    pos = name.find_first_of(":", lastPos);
+    Out << " " << name.substr(lastPos, pos - lastPos);
+    Out << ":(" << (*PI)->getType().getAsString(Policy) << ')' << *PI;
+    lastPos = pos + 1;
+  }
+
+  if (OMD->param_begin() == OMD->param_end())
+    Out << " " << name;
+
+  if (OMD->isVariadic())
+      Out << ", ...";
+
+  if (OMD->getBody()) {
+    Out << ' ';
+    OMD->getBody()->printPretty(Out, Context, 0, Policy);
+    Out << '\n';
+  }
+}
+
+void DeclPrinter::VisitObjCImplementationDecl(ObjCImplementationDecl *OID) {
+  std::string I = OID->getNameAsString();
+  ObjCInterfaceDecl *SID = OID->getSuperClass();
+
+  if (SID)
+    Out << "@implementation " << I << " : " << SID;
+  else
+    Out << "@implementation " << I;
+  Out << "\n";
+  VisitDeclContext(OID, false);
+  Out << "@end";
+}
+
+void DeclPrinter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *OID) {
+  std::string I = OID->getNameAsString();
+  ObjCInterfaceDecl *SID = OID->getSuperClass();
+
+  if (SID)
+    Out << "@interface " << I << " : " << SID;
+  else
+    Out << "@interface " << I;
+
+  // Protocols?
+  const ObjCList<ObjCProtocolDecl> &Protocols = OID->getReferencedProtocols();
+  if (!Protocols.empty()) {
+    for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
+         E = Protocols.end(); I != E; ++I)
+      Out << (I == Protocols.begin() ? '<' : ',') << *I;
+  }
+
+  if (!Protocols.empty())
+    Out << "> ";
+
+  if (OID->ivar_size() > 0) {
+    Out << "{\n";
+    Indentation += Policy.Indentation;
+    for (ObjCInterfaceDecl::ivar_iterator I = OID->ivar_begin(),
+         E = OID->ivar_end(); I != E; ++I) {
+      Indent() << (*I)->getType().getAsString(Policy) << ' ' << *I << ";\n";
+    }
+    Indentation -= Policy.Indentation;
+    Out << "}\n";
+  }
+
+  VisitDeclContext(OID, false);
+  Out << "@end";
+  // FIXME: implement the rest...
+}
+
+void DeclPrinter::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D) {
+  Out << "@protocol ";
+  for (ObjCForwardProtocolDecl::protocol_iterator I = D->protocol_begin(),
+         E = D->protocol_end();
+       I != E; ++I) {
+    if (I != D->protocol_begin()) Out << ", ";
+    Out << *I;
+  }
+}
+
+void DeclPrinter::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
+  Out << "@protocol " << PID << '\n';
+  VisitDeclContext(PID, false);
+  Out << "@end";
+}
+
+void DeclPrinter::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *PID) {
+  Out << "@implementation " << PID->getClassInterface() << '(' << PID << ")\n";
+
+  VisitDeclContext(PID, false);
+  Out << "@end";
+  // FIXME: implement the rest...
+}
+
+void DeclPrinter::VisitObjCCategoryDecl(ObjCCategoryDecl *PID) {
+  Out << "@interface " << PID->getClassInterface() << '(' << PID << ")\n";
+  VisitDeclContext(PID, false);
+  Out << "@end";
+
+  // FIXME: implement the rest...
+}
+
+void DeclPrinter::VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *AID) {
+  Out << "@compatibility_alias " << AID
+      << ' ' << AID->getClassInterface() << ";\n";
+}
+
+/// PrintObjCPropertyDecl - print a property declaration.
+///
+void DeclPrinter::VisitObjCPropertyDecl(ObjCPropertyDecl *PDecl) {
+  if (PDecl->getPropertyImplementation() == ObjCPropertyDecl::Required)
+    Out << "@required\n";
+  else if (PDecl->getPropertyImplementation() == ObjCPropertyDecl::Optional)
+    Out << "@optional\n";
+
+  Out << "@property";
+  if (PDecl->getPropertyAttributes() != ObjCPropertyDecl::OBJC_PR_noattr) {
+    bool first = true;
+    Out << " (";
+    if (PDecl->getPropertyAttributes() &
+        ObjCPropertyDecl::OBJC_PR_readonly) {
+      Out << (first ? ' ' : ',') << "readonly";
+      first = false;
+  }
+
+  if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_getter) {
+    Out << (first ? ' ' : ',') << "getter = "
+        << PDecl->getGetterName().getAsString();
+    first = false;
+  }
+  if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_setter) {
+    Out << (first ? ' ' : ',') << "setter = "
+        << PDecl->getSetterName().getAsString();
+    first = false;
+  }
+
+  if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_assign) {
+    Out << (first ? ' ' : ',') << "assign";
+    first = false;
+  }
+
+  if (PDecl->getPropertyAttributes() &
+      ObjCPropertyDecl::OBJC_PR_readwrite) {
+    Out << (first ? ' ' : ',') << "readwrite";
+    first = false;
+  }
+
+  if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_retain) {
+    Out << (first ? ' ' : ',') << "retain";
+    first = false;
+  }
+
+  if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_copy) {
+    Out << (first ? ' ' : ',') << "copy";
+    first = false;
+  }
+
+  if (PDecl->getPropertyAttributes() &
+      ObjCPropertyDecl::OBJC_PR_nonatomic) {
+    Out << (first ? ' ' : ',') << "nonatomic";
+    first = false;
+  }
+  Out << " )";
+  }
+  Out << ' ' << PDecl->getType().getAsString(Policy) << ' ' << PDecl;
+}
+
+void DeclPrinter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PID) {
+  if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize)
+    Out << "@synthesize ";
+  else
+    Out << "@dynamic ";
+  Out << PID->getPropertyDecl();
+  if (PID->getPropertyIvarDecl())
+    Out << '=' << PID->getPropertyIvarDecl();
+}
+
+void DeclPrinter::VisitUsingDecl(UsingDecl *D) {
+  Out << "using ";
+  D->getTargetNestedNameDecl()->print(Out, Policy);
+  Out << D;
+}
+
+void
+DeclPrinter::VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D) {
+  Out << "using typename ";
+  D->getTargetNestedNameSpecifier()->print(Out, Policy);
+  Out << D->getDeclName();
+}
+
+void DeclPrinter::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
+  Out << "using ";
+  D->getTargetNestedNameSpecifier()->print(Out, Policy);
+  Out << D->getDeclName();
+}
+
+void DeclPrinter::VisitUsingShadowDecl(UsingShadowDecl *D) {
+  // ignore
+}
diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp
new file mode 100644
index 0000000..e3d30a0
--- /dev/null
+++ b/lib/AST/DeclTemplate.cpp
@@ -0,0 +1,492 @@
+//===--- DeclTemplate.cpp - Template Declaration AST Node Implementation --===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the C++ related Decl classes for templates.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/TypeLoc.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "llvm/ADT/STLExtras.h"
+using namespace clang;
+
+//===----------------------------------------------------------------------===//
+// TemplateParameterList Implementation
+//===----------------------------------------------------------------------===//
+
+TemplateParameterList::TemplateParameterList(SourceLocation TemplateLoc,
+                                             SourceLocation LAngleLoc,
+                                             NamedDecl **Params, unsigned NumParams,
+                                             SourceLocation RAngleLoc)
+  : TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
+    NumParams(NumParams) {
+  for (unsigned Idx = 0; Idx < NumParams; ++Idx)
+    begin()[Idx] = Params[Idx];
+}
+
+TemplateParameterList *
+TemplateParameterList::Create(ASTContext &C, SourceLocation TemplateLoc,
+                              SourceLocation LAngleLoc, NamedDecl **Params,
+                              unsigned NumParams, SourceLocation RAngleLoc) {
+  unsigned Size = sizeof(TemplateParameterList) 
+                + sizeof(NamedDecl *) * NumParams;
+  unsigned Align = llvm::AlignOf<TemplateParameterList>::Alignment;
+  void *Mem = C.Allocate(Size, Align);
+  return new (Mem) TemplateParameterList(TemplateLoc, LAngleLoc, Params,
+                                         NumParams, RAngleLoc);
+}
+
+unsigned TemplateParameterList::getMinRequiredArguments() const {
+  unsigned NumRequiredArgs = size();
+  iterator Param = const_cast<TemplateParameterList *>(this)->end(),
+      ParamBegin = const_cast<TemplateParameterList *>(this)->begin();
+  while (Param != ParamBegin) {
+    --Param;
+
+    if (!(*Param)->isTemplateParameterPack() &&
+        !(isa<TemplateTypeParmDecl>(*Param) &&
+          cast<TemplateTypeParmDecl>(*Param)->hasDefaultArgument()) &&
+        !(isa<NonTypeTemplateParmDecl>(*Param) &&
+          cast<NonTypeTemplateParmDecl>(*Param)->hasDefaultArgument()) &&
+        !(isa<TemplateTemplateParmDecl>(*Param) &&
+          cast<TemplateTemplateParmDecl>(*Param)->hasDefaultArgument()))
+      break;
+
+    --NumRequiredArgs;
+  }
+
+  return NumRequiredArgs;
+}
+
+unsigned TemplateParameterList::getDepth() const {
+  if (size() == 0)
+    return 0;
+  
+  const NamedDecl *FirstParm = getParam(0);
+  if (const TemplateTypeParmDecl *TTP
+        = dyn_cast<TemplateTypeParmDecl>(FirstParm))
+    return TTP->getDepth();
+  else if (const NonTypeTemplateParmDecl *NTTP 
+             = dyn_cast<NonTypeTemplateParmDecl>(FirstParm))
+    return NTTP->getDepth();
+  else
+    return cast<TemplateTemplateParmDecl>(FirstParm)->getDepth();
+}
+
+//===----------------------------------------------------------------------===//
+// TemplateDecl Implementation
+//===----------------------------------------------------------------------===//
+
+TemplateDecl::~TemplateDecl() {
+}
+
+//===----------------------------------------------------------------------===//
+// FunctionTemplateDecl Implementation
+//===----------------------------------------------------------------------===//
+
+FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C,
+                                                   DeclContext *DC,
+                                                   SourceLocation L,
+                                                   DeclarationName Name,
+                                               TemplateParameterList *Params,
+                                                   NamedDecl *Decl) {
+  return new (C) FunctionTemplateDecl(DC, L, Name, Params, Decl);
+}
+
+void FunctionTemplateDecl::Destroy(ASTContext &C) {
+  if (Common *CommonPtr = CommonOrPrev.dyn_cast<Common*>()) {
+    for (llvm::FoldingSet<FunctionTemplateSpecializationInfo>::iterator
+              Spec = CommonPtr->Specializations.begin(),
+           SpecEnd = CommonPtr->Specializations.end();
+         Spec != SpecEnd; ++Spec)
+      C.Deallocate(&*Spec);
+  }
+
+  Decl::Destroy(C);
+}
+
+FunctionTemplateDecl *FunctionTemplateDecl::getCanonicalDecl() {
+  FunctionTemplateDecl *FunTmpl = this;
+  while (FunTmpl->getPreviousDeclaration())
+    FunTmpl = FunTmpl->getPreviousDeclaration();
+  return FunTmpl;
+}
+
+FunctionTemplateDecl::Common *FunctionTemplateDecl::getCommonPtr() {
+  // Find the first declaration of this function template.
+  FunctionTemplateDecl *First = this;
+  while (First->getPreviousDeclaration())
+    First = First->getPreviousDeclaration();
+
+  if (First->CommonOrPrev.isNull()) {
+    // FIXME: Allocate with the ASTContext
+    First->CommonOrPrev = new Common;
+  }
+  return First->CommonOrPrev.get<Common*>();
+}
+
+//===----------------------------------------------------------------------===//
+// ClassTemplateDecl Implementation
+//===----------------------------------------------------------------------===//
+
+ClassTemplateDecl *ClassTemplateDecl::getCanonicalDecl() {
+  ClassTemplateDecl *Template = this;
+  while (Template->getPreviousDeclaration())
+    Template = Template->getPreviousDeclaration();
+  return Template;
+}
+
+ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
+                                             DeclContext *DC,
+                                             SourceLocation L,
+                                             DeclarationName Name,
+                                             TemplateParameterList *Params,
+                                             NamedDecl *Decl,
+                                             ClassTemplateDecl *PrevDecl) {
+  Common *CommonPtr;
+  if (PrevDecl)
+    CommonPtr = PrevDecl->CommonPtr;
+  else
+    CommonPtr = new (C) Common;
+
+  return new (C) ClassTemplateDecl(DC, L, Name, Params, Decl, PrevDecl,
+                                   CommonPtr);
+}
+
+ClassTemplateDecl::~ClassTemplateDecl() {
+  assert(CommonPtr == 0 && "ClassTemplateDecl must be explicitly destroyed");
+}
+
+void ClassTemplateDecl::Destroy(ASTContext& C) {
+  if (!PreviousDeclaration) {
+    CommonPtr->~Common();
+    C.Deallocate((void*)CommonPtr);
+  }
+  CommonPtr = 0;
+
+  this->~ClassTemplateDecl();
+  C.Deallocate((void*)this);
+}
+
+ClassTemplatePartialSpecializationDecl *
+ClassTemplateDecl::findPartialSpecialization(QualType T) {
+  ASTContext &Context = getASTContext();
+  typedef llvm::FoldingSet<ClassTemplatePartialSpecializationDecl>::iterator
+    partial_spec_iterator;
+  for (partial_spec_iterator P = getPartialSpecializations().begin(),
+                          PEnd = getPartialSpecializations().end();
+       P != PEnd; ++P) {
+    if (Context.hasSameType(P->getInjectedSpecializationType(), T))
+      return &*P;
+  }
+
+  return 0;
+}
+
+QualType
+ClassTemplateDecl::getInjectedClassNameSpecialization(ASTContext &Context) {
+  if (!CommonPtr->InjectedClassNameType.isNull())
+    return CommonPtr->InjectedClassNameType;
+
+  // FIXME: n2800 14.6.1p1 should say how the template arguments
+  // corresponding to template parameter packs should be pack
+  // expansions. We already say that in 14.6.2.1p2, so it would be
+  // better to fix that redundancy.
+
+  TemplateParameterList *Params = getTemplateParameters();
+  llvm::SmallVector<TemplateArgument, 16> TemplateArgs;
+  TemplateArgs.reserve(Params->size());
+  for (TemplateParameterList::iterator Param = Params->begin(),
+                                    ParamEnd = Params->end();
+       Param != ParamEnd; ++Param) {
+    if (isa<TemplateTypeParmDecl>(*Param)) {
+      QualType ParamType = Context.getTypeDeclType(cast<TypeDecl>(*Param));
+      TemplateArgs.push_back(TemplateArgument(ParamType));
+    } else if (NonTypeTemplateParmDecl *NTTP =
+                 dyn_cast<NonTypeTemplateParmDecl>(*Param)) {
+      Expr *E = new (Context) DeclRefExpr(NTTP,
+                                          NTTP->getType().getNonReferenceType(),
+                                          NTTP->getLocation());
+      TemplateArgs.push_back(TemplateArgument(E));
+    } else {
+      TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*Param);
+      TemplateArgs.push_back(TemplateArgument(TemplateName(TTP)));
+    }
+  }
+
+  CommonPtr->InjectedClassNameType
+    = Context.getTemplateSpecializationType(TemplateName(this),
+                                            &TemplateArgs[0],
+                                            TemplateArgs.size());
+  return CommonPtr->InjectedClassNameType;
+}
+
+//===----------------------------------------------------------------------===//
+// TemplateTypeParm Allocation/Deallocation Method Implementations
+//===----------------------------------------------------------------------===//
+
+TemplateTypeParmDecl *
+TemplateTypeParmDecl::Create(ASTContext &C, DeclContext *DC,
+                             SourceLocation L, unsigned D, unsigned P,
+                             IdentifierInfo *Id, bool Typename,
+                             bool ParameterPack) {
+  QualType Type = C.getTemplateTypeParmType(D, P, ParameterPack, Id);
+  return new (C) TemplateTypeParmDecl(DC, L, Id, Typename, Type, ParameterPack);
+}
+
+SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
+  return DefaultArgument->getTypeLoc().getFullSourceRange().getBegin();
+}
+
+unsigned TemplateTypeParmDecl::getDepth() const {
+  return TypeForDecl->getAs<TemplateTypeParmType>()->getDepth();
+}
+
+unsigned TemplateTypeParmDecl::getIndex() const {
+  return TypeForDecl->getAs<TemplateTypeParmType>()->getIndex();
+}
+
+//===----------------------------------------------------------------------===//
+// NonTypeTemplateParmDecl Method Implementations
+//===----------------------------------------------------------------------===//
+
+NonTypeTemplateParmDecl *
+NonTypeTemplateParmDecl::Create(ASTContext &C, DeclContext *DC,
+                                SourceLocation L, unsigned D, unsigned P,
+                                IdentifierInfo *Id, QualType T,
+                                TypeSourceInfo *TInfo) {
+  return new (C) NonTypeTemplateParmDecl(DC, L, D, P, Id, T, TInfo);
+}
+
+SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
+  return DefaultArgument? DefaultArgument->getSourceRange().getBegin()
+                        : SourceLocation();
+}
+
+//===----------------------------------------------------------------------===//
+// TemplateTemplateParmDecl Method Implementations
+//===----------------------------------------------------------------------===//
+
+TemplateTemplateParmDecl *
+TemplateTemplateParmDecl::Create(ASTContext &C, DeclContext *DC,
+                                 SourceLocation L, unsigned D, unsigned P,
+                                 IdentifierInfo *Id,
+                                 TemplateParameterList *Params) {
+  return new (C) TemplateTemplateParmDecl(DC, L, D, P, Id, Params);
+}
+
+//===----------------------------------------------------------------------===//
+// TemplateArgumentListBuilder Implementation
+//===----------------------------------------------------------------------===//
+
+void TemplateArgumentListBuilder::Append(const TemplateArgument& Arg) {
+  switch (Arg.getKind()) {
+    default: break;
+    case TemplateArgument::Type:
+      assert(Arg.getAsType().isCanonical() && "Type must be canonical!");
+      break;
+  }
+
+  assert(NumFlatArgs < MaxFlatArgs && "Argument list builder is full!");
+  assert(!StructuredArgs &&
+         "Can't append arguments when an argument pack has been added!");
+
+  if (!FlatArgs)
+    FlatArgs = new TemplateArgument[MaxFlatArgs];
+
+  FlatArgs[NumFlatArgs++] = Arg;
+}
+
+void TemplateArgumentListBuilder::BeginPack() {
+  assert(!AddingToPack && "Already adding to pack!");
+  assert(!StructuredArgs && "Argument list already contains a pack!");
+
+  AddingToPack = true;
+  PackBeginIndex = NumFlatArgs;
+}
+
+void TemplateArgumentListBuilder::EndPack() {
+  assert(AddingToPack && "Not adding to pack!");
+  assert(!StructuredArgs && "Argument list already contains a pack!");
+
+  AddingToPack = false;
+
+  StructuredArgs = new TemplateArgument[MaxStructuredArgs];
+
+  // First copy the flat entries over to the list  (if any)
+  for (unsigned I = 0; I != PackBeginIndex; ++I) {
+    NumStructuredArgs++;
+    StructuredArgs[I] = FlatArgs[I];
+  }
+
+  // Next, set the pack.
+  TemplateArgument *PackArgs = 0;
+  unsigned NumPackArgs = NumFlatArgs - PackBeginIndex;
+  if (NumPackArgs)
+    PackArgs = &FlatArgs[PackBeginIndex];
+
+  StructuredArgs[NumStructuredArgs++].setArgumentPack(PackArgs, NumPackArgs,
+                                                      /*CopyArgs=*/false);
+}
+
+void TemplateArgumentListBuilder::ReleaseArgs() {
+  FlatArgs = 0;
+  NumFlatArgs = 0;
+  MaxFlatArgs = 0;
+  StructuredArgs = 0;
+  NumStructuredArgs = 0;
+  MaxStructuredArgs = 0;
+}
+
+//===----------------------------------------------------------------------===//
+// TemplateArgumentList Implementation
+//===----------------------------------------------------------------------===//
+TemplateArgumentList::TemplateArgumentList(ASTContext &Context,
+                                           TemplateArgumentListBuilder &Builder,
+                                           bool TakeArgs)
+  : FlatArguments(Builder.getFlatArguments(), TakeArgs),
+    NumFlatArguments(Builder.flatSize()),
+    StructuredArguments(Builder.getStructuredArguments(), TakeArgs),
+    NumStructuredArguments(Builder.structuredSize()) {
+
+  if (!TakeArgs)
+    return;
+
+  if (Builder.getStructuredArguments() == Builder.getFlatArguments())
+    StructuredArguments.setInt(0);
+  Builder.ReleaseArgs();
+}
+
+TemplateArgumentList::TemplateArgumentList(const TemplateArgumentList &Other)
+  : FlatArguments(Other.FlatArguments.getPointer(), 1),
+    NumFlatArguments(Other.flat_size()),
+    StructuredArguments(Other.StructuredArguments.getPointer(), 1),
+    NumStructuredArguments(Other.NumStructuredArguments) { }
+
+TemplateArgumentList::~TemplateArgumentList() {
+  // FIXME: Deallocate template arguments
+}
+
+//===----------------------------------------------------------------------===//
+// ClassTemplateSpecializationDecl Implementation
+//===----------------------------------------------------------------------===//
+ClassTemplateSpecializationDecl::
+ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK,
+                                DeclContext *DC, SourceLocation L,
+                                ClassTemplateDecl *SpecializedTemplate,
+                                TemplateArgumentListBuilder &Builder,
+                                ClassTemplateSpecializationDecl *PrevDecl)
+  : CXXRecordDecl(DK,
+                  SpecializedTemplate->getTemplatedDecl()->getTagKind(),
+                  DC, L,
+                  // FIXME: Should we use DeclarationName for the name of
+                  // class template specializations?
+                  SpecializedTemplate->getIdentifier(),
+                  PrevDecl),
+    SpecializedTemplate(SpecializedTemplate),
+    TypeAsWritten(0),
+    TemplateArgs(Context, Builder, /*TakeArgs=*/true),
+    SpecializationKind(TSK_Undeclared) {
+}
+
+ClassTemplateSpecializationDecl *
+ClassTemplateSpecializationDecl::Create(ASTContext &Context,
+                                        DeclContext *DC, SourceLocation L,
+                                        ClassTemplateDecl *SpecializedTemplate,
+                                        TemplateArgumentListBuilder &Builder,
+                                   ClassTemplateSpecializationDecl *PrevDecl) {
+  ClassTemplateSpecializationDecl *Result
+    = new (Context)ClassTemplateSpecializationDecl(Context,
+                                                   ClassTemplateSpecialization,
+                                                   DC, L,
+                                                   SpecializedTemplate,
+                                                   Builder,
+                                                   PrevDecl);
+  Context.getTypeDeclType(Result, PrevDecl);
+  return Result;
+}
+
+void ClassTemplateSpecializationDecl::Destroy(ASTContext &C) {
+  if (SpecializedPartialSpecialization *PartialSpec
+        = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
+    C.Deallocate(PartialSpec);
+
+  CXXRecordDecl::Destroy(C);
+}
+
+void
+ClassTemplateSpecializationDecl::getNameForDiagnostic(std::string &S,
+                                                  const PrintingPolicy &Policy,
+                                                      bool Qualified) const {
+  NamedDecl::getNameForDiagnostic(S, Policy, Qualified);
+
+  const TemplateArgumentList &TemplateArgs = getTemplateArgs();
+  S += TemplateSpecializationType::PrintTemplateArgumentList(
+                                       TemplateArgs.getFlatArgumentList(),
+                                       TemplateArgs.flat_size(),
+                                                             Policy);
+}
+
+ClassTemplateDecl *
+ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
+  if (SpecializedPartialSpecialization *PartialSpec
+      = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
+    return PartialSpec->PartialSpecialization->getSpecializedTemplate();
+  return SpecializedTemplate.get<ClassTemplateDecl*>();
+}
+
+//===----------------------------------------------------------------------===//
+// ClassTemplatePartialSpecializationDecl Implementation
+//===----------------------------------------------------------------------===//
+ClassTemplatePartialSpecializationDecl *
+ClassTemplatePartialSpecializationDecl::
+Create(ASTContext &Context, DeclContext *DC, SourceLocation L,
+       TemplateParameterList *Params,
+       ClassTemplateDecl *SpecializedTemplate,
+       TemplateArgumentListBuilder &Builder,
+       const TemplateArgumentListInfo &ArgInfos,
+       QualType CanonInjectedType,
+       ClassTemplatePartialSpecializationDecl *PrevDecl) {
+  unsigned N = ArgInfos.size();
+  TemplateArgumentLoc *ClonedArgs = new (Context) TemplateArgumentLoc[N];
+  for (unsigned I = 0; I != N; ++I)
+    ClonedArgs[I] = ArgInfos[I];
+
+  ClassTemplatePartialSpecializationDecl *Result
+    = new (Context)ClassTemplatePartialSpecializationDecl(Context,
+                                                          DC, L, Params,
+                                                          SpecializedTemplate,
+                                                          Builder,
+                                                          ClonedArgs, N,
+                                                          PrevDecl);
+  Result->setSpecializationKind(TSK_ExplicitSpecialization);
+
+  Context.getInjectedClassNameType(Result, CanonInjectedType);
+  return Result;
+}
+
+//===----------------------------------------------------------------------===//
+// FriendTemplateDecl Implementation
+//===----------------------------------------------------------------------===//
+
+FriendTemplateDecl *FriendTemplateDecl::Create(ASTContext &Context,
+                                               DeclContext *DC,
+                                               SourceLocation L,
+                                               unsigned NParams,
+                                               TemplateParameterList **Params,
+                                               FriendUnion Friend,
+                                               SourceLocation FLoc) {
+  FriendTemplateDecl *Result
+    = new (Context) FriendTemplateDecl(DC, L, NParams, Params, Friend, FLoc);
+  return Result;
+}
diff --git a/lib/AST/DeclarationName.cpp b/lib/AST/DeclarationName.cpp
new file mode 100644
index 0000000..4f85fca
--- /dev/null
+++ b/lib/AST/DeclarationName.cpp
@@ -0,0 +1,503 @@
+//===-- DeclarationName.cpp - Declaration names implementation --*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the DeclarationName and DeclarationNameTable
+// classes.
+//
+//===----------------------------------------------------------------------===//
+#include "clang/AST/DeclarationName.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/TypeOrdering.h"
+#include "clang/AST/Decl.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace clang;
+
+namespace clang {
+/// CXXSpecialName - Records the type associated with one of the
+/// "special" kinds of declaration names in C++, e.g., constructors,
+/// destructors, and conversion functions.
+class CXXSpecialName
+  : public DeclarationNameExtra, public llvm::FoldingSetNode {
+public:
+  /// Type - The type associated with this declaration name.
+  QualType Type;
+
+  /// FETokenInfo - Extra information associated with this declaration
+  /// name that can be used by the front end.
+  void *FETokenInfo;
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    ID.AddInteger(ExtraKindOrNumArgs);
+    ID.AddPointer(Type.getAsOpaquePtr());
+  }
+};
+
+/// CXXOperatorIdName - Contains extra information for the name of an
+/// overloaded operator in C++, such as "operator+.
+class CXXOperatorIdName : public DeclarationNameExtra {
+public:
+  /// FETokenInfo - Extra information associated with this operator
+  /// name that can be used by the front end.
+  void *FETokenInfo;
+};
+
+/// CXXLiberalOperatorName - Contains the actual identifier that makes up the
+/// name.
+///
+/// This identifier is stored here rather than directly in DeclarationName so as
+/// to allow Objective-C selectors, which are about a million times more common,
+/// to consume minimal memory.
+class CXXLiteralOperatorIdName
+  : public DeclarationNameExtra, public llvm::FoldingSetNode {
+public:
+  IdentifierInfo *ID;
+
+  void Profile(llvm::FoldingSetNodeID &FSID) {
+    FSID.AddPointer(ID);
+  }
+};
+
+static int compareInt(unsigned A, unsigned B) {
+  return (A < B ? -1 : (A > B ? 1 : 0));
+}
+
+int DeclarationName::compare(DeclarationName LHS, DeclarationName RHS) {
+  if (LHS.getNameKind() != RHS.getNameKind())
+    return (LHS.getNameKind() < RHS.getNameKind() ? -1 : 1);
+  
+  switch (LHS.getNameKind()) {
+  case DeclarationName::Identifier: {
+    IdentifierInfo *LII = LHS.getAsIdentifierInfo();
+    IdentifierInfo *RII = RHS.getAsIdentifierInfo();
+    if (!LII) return RII ? -1 : 0;
+    if (!RII) return 1;
+    
+    return LII->getName().compare(RII->getName());
+  }
+
+  case DeclarationName::ObjCZeroArgSelector:
+  case DeclarationName::ObjCOneArgSelector:
+  case DeclarationName::ObjCMultiArgSelector: {
+    Selector LHSSelector = LHS.getObjCSelector();
+    Selector RHSSelector = RHS.getObjCSelector();
+    unsigned LN = LHSSelector.getNumArgs(), RN = RHSSelector.getNumArgs();
+    for (unsigned I = 0, N = std::min(LN, RN); I != N; ++I) {
+      IdentifierInfo *LHSId = LHSSelector.getIdentifierInfoForSlot(I);
+      IdentifierInfo *RHSId = RHSSelector.getIdentifierInfoForSlot(I);
+        
+      switch (LHSId->getName().compare(RHSId->getName())) {
+      case -1: return true;
+      case 1: return false;
+      default: break;
+      }
+    }
+
+    return compareInt(LN, RN);
+  }
+  
+  case DeclarationName::CXXConstructorName:
+  case DeclarationName::CXXDestructorName:
+  case DeclarationName::CXXConversionFunctionName:
+    if (QualTypeOrdering()(LHS.getCXXNameType(), RHS.getCXXNameType()))
+      return -1;
+    if (QualTypeOrdering()(RHS.getCXXNameType(), LHS.getCXXNameType()))
+      return 1;
+    return 0;
+              
+  case DeclarationName::CXXOperatorName:
+    return compareInt(LHS.getCXXOverloadedOperator(),
+                      RHS.getCXXOverloadedOperator());
+
+  case DeclarationName::CXXLiteralOperatorName:
+    return LHS.getCXXLiteralIdentifier()->getName().compare(
+                                   RHS.getCXXLiteralIdentifier()->getName());
+              
+  case DeclarationName::CXXUsingDirective:
+    return 0;
+  }
+              
+  return 0;
+}
+
+} // end namespace clang
+
+DeclarationName::DeclarationName(Selector Sel) {
+  if (!Sel.getAsOpaquePtr()) {
+    Ptr = 0;
+    return;
+  }
+
+  switch (Sel.getNumArgs()) {
+  case 0:
+    Ptr = reinterpret_cast<uintptr_t>(Sel.getAsIdentifierInfo());
+    assert((Ptr & PtrMask) == 0 && "Improperly aligned IdentifierInfo");
+    Ptr |= StoredObjCZeroArgSelector;
+    break;
+
+  case 1:
+    Ptr = reinterpret_cast<uintptr_t>(Sel.getAsIdentifierInfo());
+    assert((Ptr & PtrMask) == 0 && "Improperly aligned IdentifierInfo");
+    Ptr |= StoredObjCOneArgSelector;
+    break;
+
+  default:
+    Ptr = Sel.InfoPtr & ~Selector::ArgFlags;
+    assert((Ptr & PtrMask) == 0 && "Improperly aligned MultiKeywordSelector");
+    Ptr |= StoredDeclarationNameExtra;
+    break;
+  }
+}
+
+DeclarationName::NameKind DeclarationName::getNameKind() const {
+  switch (getStoredNameKind()) {
+  case StoredIdentifier:          return Identifier;
+  case StoredObjCZeroArgSelector: return ObjCZeroArgSelector;
+  case StoredObjCOneArgSelector:  return ObjCOneArgSelector;
+
+  case StoredDeclarationNameExtra:
+    switch (getExtra()->ExtraKindOrNumArgs) {
+    case DeclarationNameExtra::CXXConstructor:
+      return CXXConstructorName;
+
+    case DeclarationNameExtra::CXXDestructor:
+      return CXXDestructorName;
+
+    case DeclarationNameExtra::CXXConversionFunction:
+      return CXXConversionFunctionName;
+
+    case DeclarationNameExtra::CXXLiteralOperator:
+      return CXXLiteralOperatorName;
+
+    case DeclarationNameExtra::CXXUsingDirective:
+      return CXXUsingDirective;
+
+    default:
+      // Check if we have one of the CXXOperator* enumeration values.
+      if (getExtra()->ExtraKindOrNumArgs <
+            DeclarationNameExtra::CXXUsingDirective)
+        return CXXOperatorName;
+
+      return ObjCMultiArgSelector;
+    }
+    break;
+  }
+
+  // Can't actually get here.
+  assert(0 && "This should be unreachable!");
+  return Identifier;
+}
+
+bool DeclarationName::isDependentName() const {
+  QualType T = getCXXNameType();
+  return !T.isNull() && T->isDependentType();
+}
+
+std::string DeclarationName::getAsString() const {
+  std::string Result;
+  llvm::raw_string_ostream OS(Result);
+  printName(OS);
+  return OS.str();
+}
+
+void DeclarationName::printName(llvm::raw_ostream &OS) const {
+  switch (getNameKind()) {
+  case Identifier:
+    if (const IdentifierInfo *II = getAsIdentifierInfo())
+      OS << II->getName();
+    return;
+
+  case ObjCZeroArgSelector:
+  case ObjCOneArgSelector:
+  case ObjCMultiArgSelector:
+    OS << getObjCSelector().getAsString();
+    return;
+
+  case CXXConstructorName: {
+    QualType ClassType = getCXXNameType();
+    if (const RecordType *ClassRec = ClassType->getAs<RecordType>())
+      OS << ClassRec->getDecl();
+    else
+      OS << ClassType.getAsString();
+    return;
+  }
+
+  case CXXDestructorName: {
+    OS << '~';
+    QualType Type = getCXXNameType();
+    if (const RecordType *Rec = Type->getAs<RecordType>())
+      OS << Rec->getDecl();
+    else
+      OS << Type.getAsString();
+    return;
+  }
+
+  case CXXOperatorName: {
+    static const char* const OperatorNames[NUM_OVERLOADED_OPERATORS] = {
+      0,
+#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
+      Spelling,
+#include "clang/Basic/OperatorKinds.def"
+    };
+    const char *OpName = OperatorNames[getCXXOverloadedOperator()];
+    assert(OpName && "not an overloaded operator");
+
+    OS << "operator";
+    if (OpName[0] >= 'a' && OpName[0] <= 'z')
+      OS << ' ';
+    OS << OpName;
+    return;
+  }
+
+  case CXXLiteralOperatorName:
+    OS << "operator \"\" " << getCXXLiteralIdentifier()->getName();
+    return;
+
+  case CXXConversionFunctionName: {
+    OS << "operator ";
+    QualType Type = getCXXNameType();
+    if (const RecordType *Rec = Type->getAs<RecordType>())
+      OS << Rec->getDecl();
+    else
+      OS << Type.getAsString();
+    return;
+  }
+  case CXXUsingDirective:
+    OS << "<using-directive>";
+    return;
+  }
+
+  assert(false && "Unexpected declaration name kind");
+}
+
+QualType DeclarationName::getCXXNameType() const {
+  if (CXXSpecialName *CXXName = getAsCXXSpecialName())
+    return CXXName->Type;
+  else
+    return QualType();
+}
+
+OverloadedOperatorKind DeclarationName::getCXXOverloadedOperator() const {
+  if (CXXOperatorIdName *CXXOp = getAsCXXOperatorIdName()) {
+    unsigned value
+      = CXXOp->ExtraKindOrNumArgs - DeclarationNameExtra::CXXConversionFunction;
+    return static_cast<OverloadedOperatorKind>(value);
+  } else {
+    return OO_None;
+  }
+}
+
+IdentifierInfo *DeclarationName::getCXXLiteralIdentifier() const {
+  if (CXXLiteralOperatorIdName *CXXLit = getAsCXXLiteralOperatorIdName())
+    return CXXLit->ID;
+  else
+    return 0;
+}
+
+Selector DeclarationName::getObjCSelector() const {
+  switch (getNameKind()) {
+  case ObjCZeroArgSelector:
+    return Selector(reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask), 0);
+
+  case ObjCOneArgSelector:
+    return Selector(reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask), 1);
+
+  case ObjCMultiArgSelector:
+    return Selector(reinterpret_cast<MultiKeywordSelector *>(Ptr & ~PtrMask));
+
+  default:
+    break;
+  }
+
+  return Selector();
+}
+
+void *DeclarationName::getFETokenInfoAsVoid() const {
+  switch (getNameKind()) {
+  case Identifier:
+    return getAsIdentifierInfo()->getFETokenInfo<void>();
+
+  case CXXConstructorName:
+  case CXXDestructorName:
+  case CXXConversionFunctionName:
+    return getAsCXXSpecialName()->FETokenInfo;
+
+  case CXXOperatorName:
+    return getAsCXXOperatorIdName()->FETokenInfo;
+
+  case CXXLiteralOperatorName:
+    return getCXXLiteralIdentifier()->getFETokenInfo<void>();
+
+  default:
+    assert(false && "Declaration name has no FETokenInfo");
+  }
+  return 0;
+}
+
+void DeclarationName::setFETokenInfo(void *T) {
+  switch (getNameKind()) {
+  case Identifier:
+    getAsIdentifierInfo()->setFETokenInfo(T);
+    break;
+
+  case CXXConstructorName:
+  case CXXDestructorName:
+  case CXXConversionFunctionName:
+    getAsCXXSpecialName()->FETokenInfo = T;
+    break;
+
+  case CXXOperatorName:
+    getAsCXXOperatorIdName()->FETokenInfo = T;
+    break;
+
+  case CXXLiteralOperatorName:
+    getCXXLiteralIdentifier()->setFETokenInfo(T);
+    break;
+
+  default:
+    assert(false && "Declaration name has no FETokenInfo");
+  }
+}
+
+DeclarationName DeclarationName::getUsingDirectiveName() {
+  // Single instance of DeclarationNameExtra for using-directive
+  static const DeclarationNameExtra UDirExtra =
+    { DeclarationNameExtra::CXXUsingDirective };
+
+  uintptr_t Ptr = reinterpret_cast<uintptr_t>(&UDirExtra);
+  Ptr |= StoredDeclarationNameExtra;
+
+  return DeclarationName(Ptr);
+}
+
+void DeclarationName::dump() const {
+  printName(llvm::errs());
+  llvm::errs() << '\n';
+}
+
+DeclarationNameTable::DeclarationNameTable() {
+  CXXSpecialNamesImpl = new llvm::FoldingSet<CXXSpecialName>;
+  CXXLiteralOperatorNames = new llvm::FoldingSet<CXXLiteralOperatorIdName>;
+
+  // Initialize the overloaded operator names.
+  CXXOperatorNames = new CXXOperatorIdName[NUM_OVERLOADED_OPERATORS];
+  for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op) {
+    CXXOperatorNames[Op].ExtraKindOrNumArgs
+      = Op + DeclarationNameExtra::CXXConversionFunction;
+    CXXOperatorNames[Op].FETokenInfo = 0;
+  }
+}
+
+DeclarationNameTable::~DeclarationNameTable() {
+  llvm::FoldingSet<CXXSpecialName> *SpecialNames =
+    static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
+  llvm::FoldingSetIterator<CXXSpecialName>
+                           SI = SpecialNames->begin(), SE = SpecialNames->end();
+
+  while (SI != SE) {
+    CXXSpecialName *n = &*SI++;
+    delete n;
+  }
+
+
+  llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
+    = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
+                                                      (CXXLiteralOperatorNames);
+  llvm::FoldingSetIterator<CXXLiteralOperatorIdName>
+                           LI = LiteralNames->begin(), LE = LiteralNames->end();
+
+  while (LI != LE) {
+    CXXLiteralOperatorIdName *n = &*LI++;
+    delete n;
+  }
+
+  delete SpecialNames;
+  delete LiteralNames;
+  delete [] CXXOperatorNames;
+}
+
+DeclarationName
+DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind,
+                                        CanQualType Ty) {
+  assert(Kind >= DeclarationName::CXXConstructorName &&
+         Kind <= DeclarationName::CXXConversionFunctionName &&
+         "Kind must be a C++ special name kind");
+  llvm::FoldingSet<CXXSpecialName> *SpecialNames
+    = static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
+
+  DeclarationNameExtra::ExtraKind EKind;
+  switch (Kind) {
+  case DeclarationName::CXXConstructorName:
+    EKind = DeclarationNameExtra::CXXConstructor;
+    assert(!Ty.hasQualifiers() &&"Constructor type must be unqualified");
+    break;
+  case DeclarationName::CXXDestructorName:
+    EKind = DeclarationNameExtra::CXXDestructor;
+    assert(!Ty.hasQualifiers() && "Destructor type must be unqualified");
+    break;
+  case DeclarationName::CXXConversionFunctionName:
+    EKind = DeclarationNameExtra::CXXConversionFunction;
+    break;
+  default:
+    return DeclarationName();
+  }
+
+  // Unique selector, to guarantee there is one per name.
+  llvm::FoldingSetNodeID ID;
+  ID.AddInteger(EKind);
+  ID.AddPointer(Ty.getAsOpaquePtr());
+
+  void *InsertPos = 0;
+  if (CXXSpecialName *Name = SpecialNames->FindNodeOrInsertPos(ID, InsertPos))
+    return DeclarationName(Name);
+
+  CXXSpecialName *SpecialName = new CXXSpecialName;
+  SpecialName->ExtraKindOrNumArgs = EKind;
+  SpecialName->Type = Ty;
+  SpecialName->FETokenInfo = 0;
+
+  SpecialNames->InsertNode(SpecialName, InsertPos);
+  return DeclarationName(SpecialName);
+}
+
+DeclarationName
+DeclarationNameTable::getCXXOperatorName(OverloadedOperatorKind Op) {
+  return DeclarationName(&CXXOperatorNames[(unsigned)Op]);
+}
+
+DeclarationName
+DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) {
+  llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
+    = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
+                                                      (CXXLiteralOperatorNames);
+
+  llvm::FoldingSetNodeID ID;
+  ID.AddPointer(II);
+
+  void *InsertPos = 0;
+  if (CXXLiteralOperatorIdName *Name =
+                               LiteralNames->FindNodeOrInsertPos(ID, InsertPos))
+    return DeclarationName (Name);
+  
+  CXXLiteralOperatorIdName *LiteralName = new CXXLiteralOperatorIdName;
+  LiteralName->ExtraKindOrNumArgs = DeclarationNameExtra::CXXLiteralOperator;
+  LiteralName->ID = II;
+
+  LiteralNames->InsertNode(LiteralName, InsertPos);
+  return DeclarationName(LiteralName);
+}
+
+unsigned
+llvm::DenseMapInfo<clang::DeclarationName>::
+getHashValue(clang::DeclarationName N) {
+  return DenseMapInfo<void*>::getHashValue(N.getAsOpaquePtr());
+}
+
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
new file mode 100644
index 0000000..72ffe00
--- /dev/null
+++ b/lib/AST/Expr.cpp
@@ -0,0 +1,2885 @@
+//===--- Expr.cpp - Expression AST Node Implementation --------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Expr class and subclasses.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/APValue.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/RecordLayout.h"
+#include "clang/AST/StmtVisitor.h"
+#include "clang/Basic/Builtins.h"
+#include "clang/Basic/TargetInfo.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+using namespace clang;
+
+/// isKnownToHaveBooleanValue - Return true if this is an integer expression
+/// that is known to return 0 or 1.  This happens for _Bool/bool expressions
+/// but also int expressions which are produced by things like comparisons in
+/// C.
+bool Expr::isKnownToHaveBooleanValue() const {
+  // If this value has _Bool type, it is obvious 0/1.
+  if (getType()->isBooleanType()) return true;
+  // If this is a non-scalar-integer type, we don't care enough to try. 
+  if (!getType()->isIntegralType()) return false;
+  
+  if (const ParenExpr *PE = dyn_cast<ParenExpr>(this))
+    return PE->getSubExpr()->isKnownToHaveBooleanValue();
+  
+  if (const UnaryOperator *UO = dyn_cast<UnaryOperator>(this)) {
+    switch (UO->getOpcode()) {
+    case UnaryOperator::Plus:
+    case UnaryOperator::Extension:
+      return UO->getSubExpr()->isKnownToHaveBooleanValue();
+    default:
+      return false;
+    }
+  }
+  
+  if (const CastExpr *CE = dyn_cast<CastExpr>(this))
+    return CE->getSubExpr()->isKnownToHaveBooleanValue();
+  
+  if (const BinaryOperator *BO = dyn_cast<BinaryOperator>(this)) {
+    switch (BO->getOpcode()) {
+    default: return false;
+    case BinaryOperator::LT:   // Relational operators.
+    case BinaryOperator::GT:
+    case BinaryOperator::LE:
+    case BinaryOperator::GE:
+    case BinaryOperator::EQ:   // Equality operators.
+    case BinaryOperator::NE:
+    case BinaryOperator::LAnd: // AND operator.
+    case BinaryOperator::LOr:  // Logical OR operator.
+      return true;
+        
+    case BinaryOperator::And:  // Bitwise AND operator.
+    case BinaryOperator::Xor:  // Bitwise XOR operator.
+    case BinaryOperator::Or:   // Bitwise OR operator.
+      // Handle things like (x==2)|(y==12).
+      return BO->getLHS()->isKnownToHaveBooleanValue() &&
+             BO->getRHS()->isKnownToHaveBooleanValue();
+        
+    case BinaryOperator::Comma:
+    case BinaryOperator::Assign:
+      return BO->getRHS()->isKnownToHaveBooleanValue();
+    }
+  }
+  
+  if (const ConditionalOperator *CO = dyn_cast<ConditionalOperator>(this))
+    return CO->getTrueExpr()->isKnownToHaveBooleanValue() &&
+           CO->getFalseExpr()->isKnownToHaveBooleanValue();
+  
+  return false;
+}
+
+//===----------------------------------------------------------------------===//
+// Primary Expressions.
+//===----------------------------------------------------------------------===//
+
+void ExplicitTemplateArgumentList::initializeFrom(
+                                      const TemplateArgumentListInfo &Info) {
+  LAngleLoc = Info.getLAngleLoc();
+  RAngleLoc = Info.getRAngleLoc();
+  NumTemplateArgs = Info.size();
+
+  TemplateArgumentLoc *ArgBuffer = getTemplateArgs();
+  for (unsigned i = 0; i != NumTemplateArgs; ++i)
+    new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]);
+}
+
+void ExplicitTemplateArgumentList::copyInto(
+                                      TemplateArgumentListInfo &Info) const {
+  Info.setLAngleLoc(LAngleLoc);
+  Info.setRAngleLoc(RAngleLoc);
+  for (unsigned I = 0; I != NumTemplateArgs; ++I)
+    Info.addArgument(getTemplateArgs()[I]);
+}
+
+std::size_t ExplicitTemplateArgumentList::sizeFor(
+                                      const TemplateArgumentListInfo &Info) {
+  return sizeof(ExplicitTemplateArgumentList) +
+         sizeof(TemplateArgumentLoc) * Info.size();
+}
+
+void DeclRefExpr::computeDependence() {
+  TypeDependent = false;
+  ValueDependent = false;
+  
+  NamedDecl *D = getDecl();
+
+  // (TD) C++ [temp.dep.expr]p3:
+  //   An id-expression is type-dependent if it contains:
+  //
+  // and 
+  //
+  // (VD) C++ [temp.dep.constexpr]p2:
+  //  An identifier is value-dependent if it is:
+
+  //  (TD)  - an identifier that was declared with dependent type
+  //  (VD)  - a name declared with a dependent type,
+  if (getType()->isDependentType()) {
+    TypeDependent = true;
+    ValueDependent = true;
+  }
+  //  (TD)  - a conversion-function-id that specifies a dependent type
+  else if (D->getDeclName().getNameKind() 
+                               == DeclarationName::CXXConversionFunctionName &&
+           D->getDeclName().getCXXNameType()->isDependentType()) {
+    TypeDependent = true;
+    ValueDependent = true;
+  }
+  //  (TD)  - a template-id that is dependent,
+  else if (hasExplicitTemplateArgumentList() && 
+           TemplateSpecializationType::anyDependentTemplateArguments(
+                                                       getTemplateArgs(), 
+                                                       getNumTemplateArgs())) {
+    TypeDependent = true;
+    ValueDependent = true;
+  }
+  //  (VD)  - the name of a non-type template parameter,
+  else if (isa<NonTypeTemplateParmDecl>(D))
+    ValueDependent = true;
+  //  (VD) - a constant with integral or enumeration type and is
+  //         initialized with an expression that is value-dependent.
+  else if (VarDecl *Var = dyn_cast<VarDecl>(D)) {
+    if (Var->getType()->isIntegralType() &&
+        Var->getType().getCVRQualifiers() == Qualifiers::Const) {
+      if (const Expr *Init = Var->getAnyInitializer())
+        if (Init->isValueDependent())
+          ValueDependent = true;
+    }
+  }
+  //  (TD)  - a nested-name-specifier or a qualified-id that names a
+  //          member of an unknown specialization.
+  //        (handled by DependentScopeDeclRefExpr)
+}
+
+DeclRefExpr::DeclRefExpr(NestedNameSpecifier *Qualifier, 
+                         SourceRange QualifierRange,
+                         ValueDecl *D, SourceLocation NameLoc,
+                         const TemplateArgumentListInfo *TemplateArgs,
+                         QualType T)
+  : Expr(DeclRefExprClass, T, false, false),
+    DecoratedD(D,
+               (Qualifier? HasQualifierFlag : 0) |
+               (TemplateArgs ? HasExplicitTemplateArgumentListFlag : 0)),
+    Loc(NameLoc) {
+  if (Qualifier) {
+    NameQualifier *NQ = getNameQualifier();
+    NQ->NNS = Qualifier;
+    NQ->Range = QualifierRange;
+  }
+      
+  if (TemplateArgs)
+    getExplicitTemplateArgumentList()->initializeFrom(*TemplateArgs);
+
+  computeDependence();
+}
+
+DeclRefExpr *DeclRefExpr::Create(ASTContext &Context,
+                                 NestedNameSpecifier *Qualifier,
+                                 SourceRange QualifierRange,
+                                 ValueDecl *D,
+                                 SourceLocation NameLoc,
+                                 QualType T,
+                                 const TemplateArgumentListInfo *TemplateArgs) {
+  std::size_t Size = sizeof(DeclRefExpr);
+  if (Qualifier != 0)
+    Size += sizeof(NameQualifier);
+  
+  if (TemplateArgs)
+    Size += ExplicitTemplateArgumentList::sizeFor(*TemplateArgs);
+  
+  void *Mem = Context.Allocate(Size, llvm::alignof<DeclRefExpr>());
+  return new (Mem) DeclRefExpr(Qualifier, QualifierRange, D, NameLoc,
+                               TemplateArgs, T);
+}
+
+SourceRange DeclRefExpr::getSourceRange() const {
+  // FIXME: Does not handle multi-token names well, e.g., operator[].
+  SourceRange R(Loc);
+  
+  if (hasQualifier())
+    R.setBegin(getQualifierRange().getBegin());
+  if (hasExplicitTemplateArgumentList())
+    R.setEnd(getRAngleLoc());
+  return R;
+}
+
+// FIXME: Maybe this should use DeclPrinter with a special "print predefined
+// expr" policy instead.
+std::string PredefinedExpr::ComputeName(IdentType IT, const Decl *CurrentDecl) {
+  ASTContext &Context = CurrentDecl->getASTContext();
+
+  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CurrentDecl)) {
+    if (IT != PrettyFunction && IT != PrettyFunctionNoVirtual)
+      return FD->getNameAsString();
+
+    llvm::SmallString<256> Name;
+    llvm::raw_svector_ostream Out(Name);
+
+    if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
+      if (MD->isVirtual() && IT != PrettyFunctionNoVirtual)
+        Out << "virtual ";
+      if (MD->isStatic())
+        Out << "static ";
+    }
+
+    PrintingPolicy Policy(Context.getLangOptions());
+
+    std::string Proto = FD->getQualifiedNameAsString(Policy);
+
+    const FunctionType *AFT = FD->getType()->getAs<FunctionType>();
+    const FunctionProtoType *FT = 0;
+    if (FD->hasWrittenPrototype())
+      FT = dyn_cast<FunctionProtoType>(AFT);
+
+    Proto += "(";
+    if (FT) {
+      llvm::raw_string_ostream POut(Proto);
+      for (unsigned i = 0, e = FD->getNumParams(); i != e; ++i) {
+        if (i) POut << ", ";
+        std::string Param;
+        FD->getParamDecl(i)->getType().getAsStringInternal(Param, Policy);
+        POut << Param;
+      }
+
+      if (FT->isVariadic()) {
+        if (FD->getNumParams()) POut << ", ";
+        POut << "...";
+      }
+    }
+    Proto += ")";
+
+    if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
+      Qualifiers ThisQuals = Qualifiers::fromCVRMask(MD->getTypeQualifiers());
+      if (ThisQuals.hasConst())
+        Proto += " const";
+      if (ThisQuals.hasVolatile())
+        Proto += " volatile";
+    }
+
+    if (!isa<CXXConstructorDecl>(FD) && !isa<CXXDestructorDecl>(FD))
+      AFT->getResultType().getAsStringInternal(Proto, Policy);
+
+    Out << Proto;
+
+    Out.flush();
+    return Name.str().str();
+  }
+  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(CurrentDecl)) {
+    llvm::SmallString<256> Name;
+    llvm::raw_svector_ostream Out(Name);
+    Out << (MD->isInstanceMethod() ? '-' : '+');
+    Out << '[';
+
+    // For incorrect code, there might not be an ObjCInterfaceDecl.  Do
+    // a null check to avoid a crash.
+    if (const ObjCInterfaceDecl *ID = MD->getClassInterface())
+      Out << ID;
+
+    if (const ObjCCategoryImplDecl *CID =
+        dyn_cast<ObjCCategoryImplDecl>(MD->getDeclContext()))
+      Out << '(' << CID << ')';
+
+    Out <<  ' ';
+    Out << MD->getSelector().getAsString();
+    Out <<  ']';
+
+    Out.flush();
+    return Name.str().str();
+  }
+  if (isa<TranslationUnitDecl>(CurrentDecl) && IT == PrettyFunction) {
+    // __PRETTY_FUNCTION__ -> "top level", the others produce an empty string.
+    return "top level";
+  }
+  return "";
+}
+
+/// getValueAsApproximateDouble - This returns the value as an inaccurate
+/// double.  Note that this may cause loss of precision, but is useful for
+/// debugging dumps, etc.
+double FloatingLiteral::getValueAsApproximateDouble() const {
+  llvm::APFloat V = getValue();
+  bool ignored;
+  V.convert(llvm::APFloat::IEEEdouble, llvm::APFloat::rmNearestTiesToEven,
+            &ignored);
+  return V.convertToDouble();
+}
+
+StringLiteral *StringLiteral::Create(ASTContext &C, const char *StrData,
+                                     unsigned ByteLength, bool Wide,
+                                     QualType Ty,
+                                     const SourceLocation *Loc,
+                                     unsigned NumStrs) {
+  // Allocate enough space for the StringLiteral plus an array of locations for
+  // any concatenated string tokens.
+  void *Mem = C.Allocate(sizeof(StringLiteral)+
+                         sizeof(SourceLocation)*(NumStrs-1),
+                         llvm::alignof<StringLiteral>());
+  StringLiteral *SL = new (Mem) StringLiteral(Ty);
+
+  // OPTIMIZE: could allocate this appended to the StringLiteral.
+  char *AStrData = new (C, 1) char[ByteLength];
+  memcpy(AStrData, StrData, ByteLength);
+  SL->StrData = AStrData;
+  SL->ByteLength = ByteLength;
+  SL->IsWide = Wide;
+  SL->TokLocs[0] = Loc[0];
+  SL->NumConcatenated = NumStrs;
+
+  if (NumStrs != 1)
+    memcpy(&SL->TokLocs[1], Loc+1, sizeof(SourceLocation)*(NumStrs-1));
+  return SL;
+}
+
+StringLiteral *StringLiteral::CreateEmpty(ASTContext &C, unsigned NumStrs) {
+  void *Mem = C.Allocate(sizeof(StringLiteral)+
+                         sizeof(SourceLocation)*(NumStrs-1),
+                         llvm::alignof<StringLiteral>());
+  StringLiteral *SL = new (Mem) StringLiteral(QualType());
+  SL->StrData = 0;
+  SL->ByteLength = 0;
+  SL->NumConcatenated = NumStrs;
+  return SL;
+}
+
+void StringLiteral::DoDestroy(ASTContext &C) {
+  C.Deallocate(const_cast<char*>(StrData));
+  Expr::DoDestroy(C);
+}
+
+void StringLiteral::setString(ASTContext &C, llvm::StringRef Str) {
+  if (StrData)
+    C.Deallocate(const_cast<char*>(StrData));
+
+  char *AStrData = new (C, 1) char[Str.size()];
+  memcpy(AStrData, Str.data(), Str.size());
+  StrData = AStrData;
+  ByteLength = Str.size();
+}
+
+/// getOpcodeStr - Turn an Opcode enum value into the punctuation char it
+/// corresponds to, e.g. "sizeof" or "[pre]++".
+const char *UnaryOperator::getOpcodeStr(Opcode Op) {
+  switch (Op) {
+  default: assert(0 && "Unknown unary operator");
+  case PostInc: return "++";
+  case PostDec: return "--";
+  case PreInc:  return "++";
+  case PreDec:  return "--";
+  case AddrOf:  return "&";
+  case Deref:   return "*";
+  case Plus:    return "+";
+  case Minus:   return "-";
+  case Not:     return "~";
+  case LNot:    return "!";
+  case Real:    return "__real";
+  case Imag:    return "__imag";
+  case Extension: return "__extension__";
+  case OffsetOf: return "__builtin_offsetof";
+  }
+}
+
+UnaryOperator::Opcode
+UnaryOperator::getOverloadedOpcode(OverloadedOperatorKind OO, bool Postfix) {
+  switch (OO) {
+  default: assert(false && "No unary operator for overloaded function");
+  case OO_PlusPlus:   return Postfix ? PostInc : PreInc;
+  case OO_MinusMinus: return Postfix ? PostDec : PreDec;
+  case OO_Amp:        return AddrOf;
+  case OO_Star:       return Deref;
+  case OO_Plus:       return Plus;
+  case OO_Minus:      return Minus;
+  case OO_Tilde:      return Not;
+  case OO_Exclaim:    return LNot;
+  }
+}
+
+OverloadedOperatorKind UnaryOperator::getOverloadedOperator(Opcode Opc) {
+  switch (Opc) {
+  case PostInc: case PreInc: return OO_PlusPlus;
+  case PostDec: case PreDec: return OO_MinusMinus;
+  case AddrOf: return OO_Amp;
+  case Deref: return OO_Star;
+  case Plus: return OO_Plus;
+  case Minus: return OO_Minus;
+  case Not: return OO_Tilde;
+  case LNot: return OO_Exclaim;
+  default: return OO_None;
+  }
+}
+
+
+//===----------------------------------------------------------------------===//
+// Postfix Operators.
+//===----------------------------------------------------------------------===//
+
+CallExpr::CallExpr(ASTContext& C, StmtClass SC, Expr *fn, Expr **args,
+                   unsigned numargs, QualType t, SourceLocation rparenloc)
+  : Expr(SC, t,
+         fn->isTypeDependent() || hasAnyTypeDependentArguments(args, numargs),
+         fn->isValueDependent() || hasAnyValueDependentArguments(args,numargs)),
+    NumArgs(numargs) {
+
+  SubExprs = new (C) Stmt*[numargs+1];
+  SubExprs[FN] = fn;
+  for (unsigned i = 0; i != numargs; ++i)
+    SubExprs[i+ARGS_START] = args[i];
+
+  RParenLoc = rparenloc;
+}
+
+CallExpr::CallExpr(ASTContext& C, Expr *fn, Expr **args, unsigned numargs,
+                   QualType t, SourceLocation rparenloc)
+  : Expr(CallExprClass, t,
+         fn->isTypeDependent() || hasAnyTypeDependentArguments(args, numargs),
+         fn->isValueDependent() || hasAnyValueDependentArguments(args,numargs)),
+    NumArgs(numargs) {
+
+  SubExprs = new (C) Stmt*[numargs+1];
+  SubExprs[FN] = fn;
+  for (unsigned i = 0; i != numargs; ++i)
+    SubExprs[i+ARGS_START] = args[i];
+
+  RParenLoc = rparenloc;
+}
+
+CallExpr::CallExpr(ASTContext &C, StmtClass SC, EmptyShell Empty)
+  : Expr(SC, Empty), SubExprs(0), NumArgs(0) {
+  SubExprs = new (C) Stmt*[1];
+}
+
+void CallExpr::DoDestroy(ASTContext& C) {
+  DestroyChildren(C);
+  if (SubExprs) C.Deallocate(SubExprs);
+  this->~CallExpr();
+  C.Deallocate(this);
+}
+
+Decl *CallExpr::getCalleeDecl() {
+  Expr *CEE = getCallee()->IgnoreParenCasts();
+  if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CEE))
+    return DRE->getDecl();
+  if (MemberExpr *ME = dyn_cast<MemberExpr>(CEE))
+    return ME->getMemberDecl();
+
+  return 0;
+}
+
+FunctionDecl *CallExpr::getDirectCallee() {
+  return dyn_cast_or_null<FunctionDecl>(getCalleeDecl());
+}
+
+/// setNumArgs - This changes the number of arguments present in this call.
+/// Any orphaned expressions are deleted by this, and any new operands are set
+/// to null.
+void CallExpr::setNumArgs(ASTContext& C, unsigned NumArgs) {
+  // No change, just return.
+  if (NumArgs == getNumArgs()) return;
+
+  // If shrinking # arguments, just delete the extras and forgot them.
+  if (NumArgs < getNumArgs()) {
+    for (unsigned i = NumArgs, e = getNumArgs(); i != e; ++i)
+      getArg(i)->Destroy(C);
+    this->NumArgs = NumArgs;
+    return;
+  }
+
+  // Otherwise, we are growing the # arguments.  New an bigger argument array.
+  Stmt **NewSubExprs = new (C) Stmt*[NumArgs+1];
+  // Copy over args.
+  for (unsigned i = 0; i != getNumArgs()+ARGS_START; ++i)
+    NewSubExprs[i] = SubExprs[i];
+  // Null out new args.
+  for (unsigned i = getNumArgs()+ARGS_START; i != NumArgs+ARGS_START; ++i)
+    NewSubExprs[i] = 0;
+
+  if (SubExprs) C.Deallocate(SubExprs);
+  SubExprs = NewSubExprs;
+  this->NumArgs = NumArgs;
+}
+
+/// isBuiltinCall - If this is a call to a builtin, return the builtin ID.  If
+/// not, return 0.
+unsigned CallExpr::isBuiltinCall(ASTContext &Context) const {
+  // All simple function calls (e.g. func()) are implicitly cast to pointer to
+  // function. As a result, we try and obtain the DeclRefExpr from the
+  // ImplicitCastExpr.
+  const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(getCallee());
+  if (!ICE) // FIXME: deal with more complex calls (e.g. (func)(), (*func)()).
+    return 0;
+
+  const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(ICE->getSubExpr());
+  if (!DRE)
+    return 0;
+
+  const FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl());
+  if (!FDecl)
+    return 0;
+
+  if (!FDecl->getIdentifier())
+    return 0;
+
+  return FDecl->getBuiltinID();
+}
+
+QualType CallExpr::getCallReturnType() const {
+  QualType CalleeType = getCallee()->getType();
+  if (const PointerType *FnTypePtr = CalleeType->getAs<PointerType>())
+    CalleeType = FnTypePtr->getPointeeType();
+  else if (const BlockPointerType *BPT = CalleeType->getAs<BlockPointerType>())
+    CalleeType = BPT->getPointeeType();
+
+  const FunctionType *FnType = CalleeType->getAs<FunctionType>();
+  return FnType->getResultType();
+}
+
+MemberExpr *MemberExpr::Create(ASTContext &C, Expr *base, bool isarrow,
+                               NestedNameSpecifier *qual,
+                               SourceRange qualrange,
+                               ValueDecl *memberdecl,
+                               DeclAccessPair founddecl,
+                               SourceLocation l,
+                               const TemplateArgumentListInfo *targs,
+                               QualType ty) {
+  std::size_t Size = sizeof(MemberExpr);
+
+  bool hasQualOrFound = (qual != 0 ||
+                         founddecl.getDecl() != memberdecl ||
+                         founddecl.getAccess() != memberdecl->getAccess());
+  if (hasQualOrFound)
+    Size += sizeof(MemberNameQualifier);
+
+  if (targs)
+    Size += ExplicitTemplateArgumentList::sizeFor(*targs);
+
+  void *Mem = C.Allocate(Size, llvm::alignof<MemberExpr>());
+  MemberExpr *E = new (Mem) MemberExpr(base, isarrow, memberdecl, l, ty);
+
+  if (hasQualOrFound) {
+    if (qual && qual->isDependent()) {
+      E->setValueDependent(true);
+      E->setTypeDependent(true);
+    }
+    E->HasQualifierOrFoundDecl = true;
+
+    MemberNameQualifier *NQ = E->getMemberQualifier();
+    NQ->NNS = qual;
+    NQ->Range = qualrange;
+    NQ->FoundDecl = founddecl;
+  }
+
+  if (targs) {
+    E->HasExplicitTemplateArgumentList = true;
+    E->getExplicitTemplateArgumentList()->initializeFrom(*targs);
+  }
+
+  return E;
+}
+
+const char *CastExpr::getCastKindName() const {
+  switch (getCastKind()) {
+  case CastExpr::CK_Unknown:
+    return "Unknown";
+  case CastExpr::CK_BitCast:
+    return "BitCast";
+  case CastExpr::CK_NoOp:
+    return "NoOp";
+  case CastExpr::CK_BaseToDerived:
+    return "BaseToDerived";
+  case CastExpr::CK_DerivedToBase:
+    return "DerivedToBase";
+  case CastExpr::CK_UncheckedDerivedToBase:
+    return "UncheckedDerivedToBase";
+  case CastExpr::CK_Dynamic:
+    return "Dynamic";
+  case CastExpr::CK_ToUnion:
+    return "ToUnion";
+  case CastExpr::CK_ArrayToPointerDecay:
+    return "ArrayToPointerDecay";
+  case CastExpr::CK_FunctionToPointerDecay:
+    return "FunctionToPointerDecay";
+  case CastExpr::CK_NullToMemberPointer:
+    return "NullToMemberPointer";
+  case CastExpr::CK_BaseToDerivedMemberPointer:
+    return "BaseToDerivedMemberPointer";
+  case CastExpr::CK_DerivedToBaseMemberPointer:
+    return "DerivedToBaseMemberPointer";
+  case CastExpr::CK_UserDefinedConversion:
+    return "UserDefinedConversion";
+  case CastExpr::CK_ConstructorConversion:
+    return "ConstructorConversion";
+  case CastExpr::CK_IntegralToPointer:
+    return "IntegralToPointer";
+  case CastExpr::CK_PointerToIntegral:
+    return "PointerToIntegral";
+  case CastExpr::CK_ToVoid:
+    return "ToVoid";
+  case CastExpr::CK_VectorSplat:
+    return "VectorSplat";
+  case CastExpr::CK_IntegralCast:
+    return "IntegralCast";
+  case CastExpr::CK_IntegralToFloating:
+    return "IntegralToFloating";
+  case CastExpr::CK_FloatingToIntegral:
+    return "FloatingToIntegral";
+  case CastExpr::CK_FloatingCast:
+    return "FloatingCast";
+  case CastExpr::CK_MemberPointerToBoolean:
+    return "MemberPointerToBoolean";
+  case CastExpr::CK_AnyPointerToObjCPointerCast:
+    return "AnyPointerToObjCPointerCast";
+  case CastExpr::CK_AnyPointerToBlockPointerCast:
+    return "AnyPointerToBlockPointerCast";
+  }
+
+  assert(0 && "Unhandled cast kind!");
+  return 0;
+}
+
+void CastExpr::DoDestroy(ASTContext &C)
+{
+  BasePath.Destroy();
+  Expr::DoDestroy(C);
+}
+
+Expr *CastExpr::getSubExprAsWritten() {
+  Expr *SubExpr = 0;
+  CastExpr *E = this;
+  do {
+    SubExpr = E->getSubExpr();
+    
+    // Skip any temporary bindings; they're implicit.
+    if (CXXBindTemporaryExpr *Binder = dyn_cast<CXXBindTemporaryExpr>(SubExpr))
+      SubExpr = Binder->getSubExpr();
+    
+    // Conversions by constructor and conversion functions have a
+    // subexpression describing the call; strip it off.
+    if (E->getCastKind() == CastExpr::CK_ConstructorConversion)
+      SubExpr = cast<CXXConstructExpr>(SubExpr)->getArg(0);
+    else if (E->getCastKind() == CastExpr::CK_UserDefinedConversion)
+      SubExpr = cast<CXXMemberCallExpr>(SubExpr)->getImplicitObjectArgument();
+    
+    // If the subexpression we're left with is an implicit cast, look
+    // through that, too.
+  } while ((E = dyn_cast<ImplicitCastExpr>(SubExpr)));  
+  
+  return SubExpr;
+}
+
+/// getOpcodeStr - Turn an Opcode enum value into the punctuation char it
+/// corresponds to, e.g. "<<=".
+const char *BinaryOperator::getOpcodeStr(Opcode Op) {
+  switch (Op) {
+  case PtrMemD:   return ".*";
+  case PtrMemI:   return "->*";
+  case Mul:       return "*";
+  case Div:       return "/";
+  case Rem:       return "%";
+  case Add:       return "+";
+  case Sub:       return "-";
+  case Shl:       return "<<";
+  case Shr:       return ">>";
+  case LT:        return "<";
+  case GT:        return ">";
+  case LE:        return "<=";
+  case GE:        return ">=";
+  case EQ:        return "==";
+  case NE:        return "!=";
+  case And:       return "&";
+  case Xor:       return "^";
+  case Or:        return "|";
+  case LAnd:      return "&&";
+  case LOr:       return "||";
+  case Assign:    return "=";
+  case MulAssign: return "*=";
+  case DivAssign: return "/=";
+  case RemAssign: return "%=";
+  case AddAssign: return "+=";
+  case SubAssign: return "-=";
+  case ShlAssign: return "<<=";
+  case ShrAssign: return ">>=";
+  case AndAssign: return "&=";
+  case XorAssign: return "^=";
+  case OrAssign:  return "|=";
+  case Comma:     return ",";
+  }
+
+  return "";
+}
+
+BinaryOperator::Opcode
+BinaryOperator::getOverloadedOpcode(OverloadedOperatorKind OO) {
+  switch (OO) {
+  default: assert(false && "Not an overloadable binary operator");
+  case OO_Plus: return Add;
+  case OO_Minus: return Sub;
+  case OO_Star: return Mul;
+  case OO_Slash: return Div;
+  case OO_Percent: return Rem;
+  case OO_Caret: return Xor;
+  case OO_Amp: return And;
+  case OO_Pipe: return Or;
+  case OO_Equal: return Assign;
+  case OO_Less: return LT;
+  case OO_Greater: return GT;
+  case OO_PlusEqual: return AddAssign;
+  case OO_MinusEqual: return SubAssign;
+  case OO_StarEqual: return MulAssign;
+  case OO_SlashEqual: return DivAssign;
+  case OO_PercentEqual: return RemAssign;
+  case OO_CaretEqual: return XorAssign;
+  case OO_AmpEqual: return AndAssign;
+  case OO_PipeEqual: return OrAssign;
+  case OO_LessLess: return Shl;
+  case OO_GreaterGreater: return Shr;
+  case OO_LessLessEqual: return ShlAssign;
+  case OO_GreaterGreaterEqual: return ShrAssign;
+  case OO_EqualEqual: return EQ;
+  case OO_ExclaimEqual: return NE;
+  case OO_LessEqual: return LE;
+  case OO_GreaterEqual: return GE;
+  case OO_AmpAmp: return LAnd;
+  case OO_PipePipe: return LOr;
+  case OO_Comma: return Comma;
+  case OO_ArrowStar: return PtrMemI;
+  }
+}
+
+OverloadedOperatorKind BinaryOperator::getOverloadedOperator(Opcode Opc) {
+  static const OverloadedOperatorKind OverOps[] = {
+    /* .* Cannot be overloaded */OO_None, OO_ArrowStar,
+    OO_Star, OO_Slash, OO_Percent,
+    OO_Plus, OO_Minus,
+    OO_LessLess, OO_GreaterGreater,
+    OO_Less, OO_Greater, OO_LessEqual, OO_GreaterEqual,
+    OO_EqualEqual, OO_ExclaimEqual,
+    OO_Amp,
+    OO_Caret,
+    OO_Pipe,
+    OO_AmpAmp,
+    OO_PipePipe,
+    OO_Equal, OO_StarEqual,
+    OO_SlashEqual, OO_PercentEqual,
+    OO_PlusEqual, OO_MinusEqual,
+    OO_LessLessEqual, OO_GreaterGreaterEqual,
+    OO_AmpEqual, OO_CaretEqual,
+    OO_PipeEqual,
+    OO_Comma
+  };
+  return OverOps[Opc];
+}
+
+InitListExpr::InitListExpr(ASTContext &C, SourceLocation lbraceloc,
+                           Expr **initExprs, unsigned numInits,
+                           SourceLocation rbraceloc)
+  : Expr(InitListExprClass, QualType(), false, false),
+    InitExprs(C, numInits),
+    LBraceLoc(lbraceloc), RBraceLoc(rbraceloc), SyntacticForm(0),
+    UnionFieldInit(0), HadArrayRangeDesignator(false) 
+{      
+  for (unsigned I = 0; I != numInits; ++I) {
+    if (initExprs[I]->isTypeDependent())
+      TypeDependent = true;
+    if (initExprs[I]->isValueDependent())
+      ValueDependent = true;
+  }
+      
+  InitExprs.insert(C, InitExprs.end(), initExprs, initExprs+numInits);
+}
+
+void InitListExpr::reserveInits(ASTContext &C, unsigned NumInits) {
+  if (NumInits > InitExprs.size())
+    InitExprs.reserve(C, NumInits);
+}
+
+void InitListExpr::resizeInits(ASTContext &C, unsigned NumInits) {
+  for (unsigned Idx = NumInits, LastIdx = InitExprs.size();
+       Idx < LastIdx; ++Idx)
+    InitExprs[Idx]->Destroy(C);
+  InitExprs.resize(C, NumInits, 0);
+}
+
+Expr *InitListExpr::updateInit(ASTContext &C, unsigned Init, Expr *expr) {
+  if (Init >= InitExprs.size()) {
+    InitExprs.insert(C, InitExprs.end(), Init - InitExprs.size() + 1, 0);
+    InitExprs.back() = expr;
+    return 0;
+  }
+
+  Expr *Result = cast_or_null<Expr>(InitExprs[Init]);
+  InitExprs[Init] = expr;
+  return Result;
+}
+
+/// getFunctionType - Return the underlying function type for this block.
+///
+const FunctionType *BlockExpr::getFunctionType() const {
+  return getType()->getAs<BlockPointerType>()->
+                    getPointeeType()->getAs<FunctionType>();
+}
+
+SourceLocation BlockExpr::getCaretLocation() const {
+  return TheBlock->getCaretLocation();
+}
+const Stmt *BlockExpr::getBody() const {
+  return TheBlock->getBody();
+}
+Stmt *BlockExpr::getBody() {
+  return TheBlock->getBody();
+}
+
+
+//===----------------------------------------------------------------------===//
+// Generic Expression Routines
+//===----------------------------------------------------------------------===//
+
+/// isUnusedResultAWarning - Return true if this immediate expression should
+/// be warned about if the result is unused.  If so, fill in Loc and Ranges
+/// with location to warn on and the source range[s] to report with the
+/// warning.
+bool Expr::isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1,
+                                  SourceRange &R2, ASTContext &Ctx) const {
+  // Don't warn if the expr is type dependent. The type could end up
+  // instantiating to void.
+  if (isTypeDependent())
+    return false;
+
+  switch (getStmtClass()) {
+  default:
+    if (getType()->isVoidType())
+      return false;
+    Loc = getExprLoc();
+    R1 = getSourceRange();
+    return true;
+  case ParenExprClass:
+    return cast<ParenExpr>(this)->getSubExpr()->
+      isUnusedResultAWarning(Loc, R1, R2, Ctx);
+  case UnaryOperatorClass: {
+    const UnaryOperator *UO = cast<UnaryOperator>(this);
+
+    switch (UO->getOpcode()) {
+    default: break;
+    case UnaryOperator::PostInc:
+    case UnaryOperator::PostDec:
+    case UnaryOperator::PreInc:
+    case UnaryOperator::PreDec:                 // ++/--
+      return false;  // Not a warning.
+    case UnaryOperator::Deref:
+      // Dereferencing a volatile pointer is a side-effect.
+      if (Ctx.getCanonicalType(getType()).isVolatileQualified())
+        return false;
+      break;
+    case UnaryOperator::Real:
+    case UnaryOperator::Imag:
+      // accessing a piece of a volatile complex is a side-effect.
+      if (Ctx.getCanonicalType(UO->getSubExpr()->getType())
+          .isVolatileQualified())
+        return false;
+      break;
+    case UnaryOperator::Extension:
+      return UO->getSubExpr()->isUnusedResultAWarning(Loc, R1, R2, Ctx);
+    }
+    Loc = UO->getOperatorLoc();
+    R1 = UO->getSubExpr()->getSourceRange();
+    return true;
+  }
+  case BinaryOperatorClass: {
+    const BinaryOperator *BO = cast<BinaryOperator>(this);
+    switch (BO->getOpcode()) {
+      default:
+        break;
+      // Consider ',', '||', '&&' to have side effects if the LHS or RHS does.
+      case BinaryOperator::Comma:
+        // ((foo = <blah>), 0) is an idiom for hiding the result (and
+        // lvalue-ness) of an assignment written in a macro.
+        if (IntegerLiteral *IE =
+              dyn_cast<IntegerLiteral>(BO->getRHS()->IgnoreParens()))
+          if (IE->getValue() == 0)
+            return false;
+      case BinaryOperator::LAnd:
+      case BinaryOperator::LOr:
+        return (BO->getLHS()->isUnusedResultAWarning(Loc, R1, R2, Ctx) ||
+                BO->getRHS()->isUnusedResultAWarning(Loc, R1, R2, Ctx));
+    }
+    if (BO->isAssignmentOp())
+      return false;
+    Loc = BO->getOperatorLoc();
+    R1 = BO->getLHS()->getSourceRange();
+    R2 = BO->getRHS()->getSourceRange();
+    return true;
+  }
+  case CompoundAssignOperatorClass:
+    return false;
+
+  case ConditionalOperatorClass: {
+    // The condition must be evaluated, but if either the LHS or RHS is a
+    // warning, warn about them.
+    const ConditionalOperator *Exp = cast<ConditionalOperator>(this);
+    if (Exp->getLHS() &&
+        Exp->getLHS()->isUnusedResultAWarning(Loc, R1, R2, Ctx))
+      return true;
+    return Exp->getRHS()->isUnusedResultAWarning(Loc, R1, R2, Ctx);
+  }
+
+  case MemberExprClass:
+    // If the base pointer or element is to a volatile pointer/field, accessing
+    // it is a side effect.
+    if (Ctx.getCanonicalType(getType()).isVolatileQualified())
+      return false;
+    Loc = cast<MemberExpr>(this)->getMemberLoc();
+    R1 = SourceRange(Loc, Loc);
+    R2 = cast<MemberExpr>(this)->getBase()->getSourceRange();
+    return true;
+
+  case ArraySubscriptExprClass:
+    // If the base pointer or element is to a volatile pointer/field, accessing
+    // it is a side effect.
+    if (Ctx.getCanonicalType(getType()).isVolatileQualified())
+      return false;
+    Loc = cast<ArraySubscriptExpr>(this)->getRBracketLoc();
+    R1 = cast<ArraySubscriptExpr>(this)->getLHS()->getSourceRange();
+    R2 = cast<ArraySubscriptExpr>(this)->getRHS()->getSourceRange();
+    return true;
+
+  case CallExprClass:
+  case CXXOperatorCallExprClass:
+  case CXXMemberCallExprClass: {
+    // If this is a direct call, get the callee.
+    const CallExpr *CE = cast<CallExpr>(this);
+    if (const Decl *FD = CE->getCalleeDecl()) {
+      // If the callee has attribute pure, const, or warn_unused_result, warn
+      // about it. void foo() { strlen("bar"); } should warn.
+      //
+      // Note: If new cases are added here, DiagnoseUnusedExprResult should be
+      // updated to match for QoI.
+      if (FD->getAttr<WarnUnusedResultAttr>() ||
+          FD->getAttr<PureAttr>() || FD->getAttr<ConstAttr>()) {
+        Loc = CE->getCallee()->getLocStart();
+        R1 = CE->getCallee()->getSourceRange();
+
+        if (unsigned NumArgs = CE->getNumArgs())
+          R2 = SourceRange(CE->getArg(0)->getLocStart(),
+                           CE->getArg(NumArgs-1)->getLocEnd());
+        return true;
+      }
+    }
+    return false;
+  }
+
+  case CXXTemporaryObjectExprClass:
+  case CXXConstructExprClass:
+    return false;
+
+  case ObjCMessageExprClass: {
+    const ObjCMessageExpr *ME = cast<ObjCMessageExpr>(this);
+    const ObjCMethodDecl *MD = ME->getMethodDecl();
+    if (MD && MD->getAttr<WarnUnusedResultAttr>()) {
+      Loc = getExprLoc();
+      return true;
+    }
+    return false;
+  }
+
+  case ObjCImplicitSetterGetterRefExprClass: {   // Dot syntax for message send.
+#if 0
+    const ObjCImplicitSetterGetterRefExpr *Ref =
+      cast<ObjCImplicitSetterGetterRefExpr>(this);
+    // FIXME: We really want the location of the '.' here.
+    Loc = Ref->getLocation();
+    R1 = SourceRange(Ref->getLocation(), Ref->getLocation());
+    if (Ref->getBase())
+      R2 = Ref->getBase()->getSourceRange();
+#else
+    Loc = getExprLoc();
+    R1 = getSourceRange();
+#endif
+    return true;
+  }
+  case StmtExprClass: {
+    // Statement exprs don't logically have side effects themselves, but are
+    // sometimes used in macros in ways that give them a type that is unused.
+    // For example ({ blah; foo(); }) will end up with a type if foo has a type.
+    // however, if the result of the stmt expr is dead, we don't want to emit a
+    // warning.
+    const CompoundStmt *CS = cast<StmtExpr>(this)->getSubStmt();
+    if (!CS->body_empty())
+      if (const Expr *E = dyn_cast<Expr>(CS->body_back()))
+        return E->isUnusedResultAWarning(Loc, R1, R2, Ctx);
+
+    if (getType()->isVoidType())
+      return false;
+    Loc = cast<StmtExpr>(this)->getLParenLoc();
+    R1 = getSourceRange();
+    return true;
+  }
+  case CStyleCastExprClass:
+    // If this is an explicit cast to void, allow it.  People do this when they
+    // think they know what they're doing :).
+    if (getType()->isVoidType())
+      return false;
+    Loc = cast<CStyleCastExpr>(this)->getLParenLoc();
+    R1 = cast<CStyleCastExpr>(this)->getSubExpr()->getSourceRange();
+    return true;
+  case CXXFunctionalCastExprClass: {
+    if (getType()->isVoidType())
+      return false;
+    const CastExpr *CE = cast<CastExpr>(this);
+    
+    // If this is a cast to void or a constructor conversion, check the operand.
+    // Otherwise, the result of the cast is unused.
+    if (CE->getCastKind() == CastExpr::CK_ToVoid ||
+        CE->getCastKind() == CastExpr::CK_ConstructorConversion)
+      return (cast<CastExpr>(this)->getSubExpr()
+              ->isUnusedResultAWarning(Loc, R1, R2, Ctx));
+    Loc = cast<CXXFunctionalCastExpr>(this)->getTypeBeginLoc();
+    R1 = cast<CXXFunctionalCastExpr>(this)->getSubExpr()->getSourceRange();
+    return true;
+  }
+
+  case ImplicitCastExprClass:
+    // Check the operand, since implicit casts are inserted by Sema
+    return (cast<ImplicitCastExpr>(this)
+            ->getSubExpr()->isUnusedResultAWarning(Loc, R1, R2, Ctx));
+
+  case CXXDefaultArgExprClass:
+    return (cast<CXXDefaultArgExpr>(this)
+            ->getExpr()->isUnusedResultAWarning(Loc, R1, R2, Ctx));
+
+  case CXXNewExprClass:
+    // FIXME: In theory, there might be new expressions that don't have side
+    // effects (e.g. a placement new with an uninitialized POD).
+  case CXXDeleteExprClass:
+    return false;
+  case CXXBindTemporaryExprClass:
+    return (cast<CXXBindTemporaryExpr>(this)
+            ->getSubExpr()->isUnusedResultAWarning(Loc, R1, R2, Ctx));
+  case CXXExprWithTemporariesClass:
+    return (cast<CXXExprWithTemporaries>(this)
+            ->getSubExpr()->isUnusedResultAWarning(Loc, R1, R2, Ctx));
+  }
+}
+
+/// DeclCanBeLvalue - Determine whether the given declaration can be
+/// an lvalue. This is a helper routine for isLvalue.
+static bool DeclCanBeLvalue(const NamedDecl *Decl, ASTContext &Ctx) {
+  // C++ [temp.param]p6:
+  //   A non-type non-reference template-parameter is not an lvalue.
+  if (const NonTypeTemplateParmDecl *NTTParm
+        = dyn_cast<NonTypeTemplateParmDecl>(Decl))
+    return NTTParm->getType()->isReferenceType();
+
+  return isa<VarDecl>(Decl) || isa<FieldDecl>(Decl) ||
+    // C++ 3.10p2: An lvalue refers to an object or function.
+    (Ctx.getLangOptions().CPlusPlus &&
+     (isa<FunctionDecl>(Decl) || isa<FunctionTemplateDecl>(Decl)));
+}
+
+/// isLvalue - C99 6.3.2.1: an lvalue is an expression with an object type or an
+/// incomplete type other than void. Nonarray expressions that can be lvalues:
+///  - name, where name must be a variable
+///  - e[i]
+///  - (e), where e must be an lvalue
+///  - e.name, where e must be an lvalue
+///  - e->name
+///  - *e, the type of e cannot be a function type
+///  - string-constant
+///  - (__real__ e) and (__imag__ e) where e is an lvalue  [GNU extension]
+///  - reference type [C++ [expr]]
+///
+Expr::isLvalueResult Expr::isLvalue(ASTContext &Ctx) const {
+  assert(!TR->isReferenceType() && "Expressions can't have reference type.");
+
+  isLvalueResult Res = isLvalueInternal(Ctx);
+  if (Res != LV_Valid || Ctx.getLangOptions().CPlusPlus)
+    return Res;
+
+  // first, check the type (C99 6.3.2.1). Expressions with function
+  // type in C are not lvalues, but they can be lvalues in C++.
+  if (TR->isFunctionType() || TR == Ctx.OverloadTy)
+    return LV_NotObjectType;
+
+  // Allow qualified void which is an incomplete type other than void (yuck).
+  if (TR->isVoidType() && !Ctx.getCanonicalType(TR).hasQualifiers())
+    return LV_IncompleteVoidType;
+
+  return LV_Valid;
+}
+
+// Check whether the expression can be sanely treated like an l-value
+Expr::isLvalueResult Expr::isLvalueInternal(ASTContext &Ctx) const {
+  switch (getStmtClass()) {
+  case ObjCIsaExprClass:
+  case StringLiteralClass:  // C99 6.5.1p4
+  case ObjCEncodeExprClass: // @encode behaves like its string in every way.
+    return LV_Valid;
+  case ArraySubscriptExprClass: // C99 6.5.3p4 (e1[e2] == (*((e1)+(e2))))
+    // For vectors, make sure base is an lvalue (i.e. not a function call).
+    if (cast<ArraySubscriptExpr>(this)->getBase()->getType()->isVectorType())
+      return cast<ArraySubscriptExpr>(this)->getBase()->isLvalue(Ctx);
+    return LV_Valid;
+  case DeclRefExprClass: { // C99 6.5.1p2
+    const NamedDecl *RefdDecl = cast<DeclRefExpr>(this)->getDecl();
+    if (DeclCanBeLvalue(RefdDecl, Ctx))
+      return LV_Valid;
+    break;
+  }
+  case BlockDeclRefExprClass: {
+    const BlockDeclRefExpr *BDR = cast<BlockDeclRefExpr>(this);
+    if (isa<VarDecl>(BDR->getDecl()))
+      return LV_Valid;
+    break;
+  }
+  case MemberExprClass: {
+    const MemberExpr *m = cast<MemberExpr>(this);
+    if (Ctx.getLangOptions().CPlusPlus) { // C++ [expr.ref]p4:
+      NamedDecl *Member = m->getMemberDecl();
+      // C++ [expr.ref]p4:
+      //   If E2 is declared to have type "reference to T", then E1.E2
+      //   is an lvalue.
+      if (ValueDecl *Value = dyn_cast<ValueDecl>(Member))
+        if (Value->getType()->isReferenceType())
+          return LV_Valid;
+
+      //   -- If E2 is a static data member [...] then E1.E2 is an lvalue.
+      if (isa<VarDecl>(Member) && Member->getDeclContext()->isRecord())
+        return LV_Valid;
+
+      //   -- If E2 is a non-static data member [...]. If E1 is an
+      //      lvalue, then E1.E2 is an lvalue.
+      if (isa<FieldDecl>(Member)) {
+        if (m->isArrow())
+          return LV_Valid;
+        return m->getBase()->isLvalue(Ctx);
+      }
+
+      //   -- If it refers to a static member function [...], then
+      //      E1.E2 is an lvalue.
+      //   -- Otherwise, if E1.E2 refers to a non-static member
+      //      function [...], then E1.E2 is not an lvalue.
+      if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Member))
+        return Method->isStatic()? LV_Valid : LV_MemberFunction;
+
+      //   -- If E2 is a member enumerator [...], the expression E1.E2
+      //      is not an lvalue.
+      if (isa<EnumConstantDecl>(Member))
+        return LV_InvalidExpression;
+
+        // Not an lvalue.
+      return LV_InvalidExpression;
+    }
+    
+    // C99 6.5.2.3p4
+    if (m->isArrow())
+      return LV_Valid;
+    Expr *BaseExp = m->getBase();
+    if (BaseExp->getStmtClass() == ObjCPropertyRefExprClass ||
+        BaseExp->getStmtClass() == ObjCImplicitSetterGetterRefExprClass)
+          return LV_SubObjCPropertySetting;
+    return 
+       BaseExp->isLvalue(Ctx);        
+  }
+  case UnaryOperatorClass:
+    if (cast<UnaryOperator>(this)->getOpcode() == UnaryOperator::Deref)
+      return LV_Valid; // C99 6.5.3p4
+
+    if (cast<UnaryOperator>(this)->getOpcode() == UnaryOperator::Real ||
+        cast<UnaryOperator>(this)->getOpcode() == UnaryOperator::Imag ||
+        cast<UnaryOperator>(this)->getOpcode() == UnaryOperator::Extension)
+      return cast<UnaryOperator>(this)->getSubExpr()->isLvalue(Ctx);  // GNU.
+
+    if (Ctx.getLangOptions().CPlusPlus && // C++ [expr.pre.incr]p1
+        (cast<UnaryOperator>(this)->getOpcode() == UnaryOperator::PreInc ||
+         cast<UnaryOperator>(this)->getOpcode() == UnaryOperator::PreDec))
+      return LV_Valid;
+    break;
+  case ImplicitCastExprClass:
+    if (cast<ImplicitCastExpr>(this)->isLvalueCast())
+      return LV_Valid;
+
+    // If this is a conversion to a class temporary, make a note of
+    // that.
+    if (Ctx.getLangOptions().CPlusPlus && getType()->isRecordType())
+      return LV_ClassTemporary;
+
+    break;
+  case ParenExprClass: // C99 6.5.1p5
+    return cast<ParenExpr>(this)->getSubExpr()->isLvalue(Ctx);
+  case BinaryOperatorClass:
+  case CompoundAssignOperatorClass: {
+    const BinaryOperator *BinOp = cast<BinaryOperator>(this);
+
+    if (Ctx.getLangOptions().CPlusPlus && // C++ [expr.comma]p1
+        BinOp->getOpcode() == BinaryOperator::Comma)
+      return BinOp->getRHS()->isLvalue(Ctx);
+
+    // C++ [expr.mptr.oper]p6
+    // The result of a .* expression is an lvalue only if its first operand is 
+    // an lvalue and its second operand is a pointer to data member. 
+    if (BinOp->getOpcode() == BinaryOperator::PtrMemD &&
+        !BinOp->getType()->isFunctionType())
+      return BinOp->getLHS()->isLvalue(Ctx);
+
+    // The result of an ->* expression is an lvalue only if its second operand 
+    // is a pointer to data member.
+    if (BinOp->getOpcode() == BinaryOperator::PtrMemI &&
+        !BinOp->getType()->isFunctionType()) {
+      QualType Ty = BinOp->getRHS()->getType();
+      if (Ty->isMemberPointerType() && !Ty->isMemberFunctionPointerType())
+        return LV_Valid;
+    }
+    
+    if (!BinOp->isAssignmentOp())
+      return LV_InvalidExpression;
+
+    if (Ctx.getLangOptions().CPlusPlus)
+      // C++ [expr.ass]p1:
+      //   The result of an assignment operation [...] is an lvalue.
+      return LV_Valid;
+
+
+    // C99 6.5.16:
+    //   An assignment expression [...] is not an lvalue.
+    return LV_InvalidExpression;
+  }
+  case CallExprClass:
+  case CXXOperatorCallExprClass:
+  case CXXMemberCallExprClass: {
+    // C++0x [expr.call]p10
+    //   A function call is an lvalue if and only if the result type
+    //   is an lvalue reference.
+    QualType ReturnType = cast<CallExpr>(this)->getCallReturnType();
+    if (ReturnType->isLValueReferenceType())
+      return LV_Valid;
+
+    // If the function is returning a class temporary, make a note of
+    // that.
+    if (Ctx.getLangOptions().CPlusPlus && ReturnType->isRecordType())
+      return LV_ClassTemporary;
+
+    break;
+  }
+  case CompoundLiteralExprClass: // C99 6.5.2.5p5
+    // FIXME: Is this what we want in C++?
+    return LV_Valid;
+  case ChooseExprClass:
+    // __builtin_choose_expr is an lvalue if the selected operand is.
+    return cast<ChooseExpr>(this)->getChosenSubExpr(Ctx)->isLvalue(Ctx);
+  case ExtVectorElementExprClass:
+    if (cast<ExtVectorElementExpr>(this)->containsDuplicateElements())
+      return LV_DuplicateVectorComponents;
+    return LV_Valid;
+  case ObjCIvarRefExprClass: // ObjC instance variables are lvalues.
+    return LV_Valid;
+  case ObjCPropertyRefExprClass: // FIXME: check if read-only property.
+    return LV_Valid;
+  case ObjCImplicitSetterGetterRefExprClass: // FIXME: check if read-only property.
+    return LV_Valid;
+  case PredefinedExprClass:
+    return LV_Valid;
+  case UnresolvedLookupExprClass:
+    return LV_Valid;
+  case CXXDefaultArgExprClass:
+    return cast<CXXDefaultArgExpr>(this)->getExpr()->isLvalue(Ctx);
+  case CStyleCastExprClass:
+  case CXXFunctionalCastExprClass:
+  case CXXStaticCastExprClass:
+  case CXXDynamicCastExprClass:
+  case CXXReinterpretCastExprClass:
+  case CXXConstCastExprClass:
+    // The result of an explicit cast is an lvalue if the type we are
+    // casting to is an lvalue reference type. See C++ [expr.cast]p1,
+    // C++ [expr.static.cast]p2, C++ [expr.dynamic.cast]p2,
+    // C++ [expr.reinterpret.cast]p1, C++ [expr.const.cast]p1.
+    if (cast<ExplicitCastExpr>(this)->getTypeAsWritten()->
+          isLValueReferenceType())
+      return LV_Valid;
+
+    // If this is a conversion to a class temporary, make a note of
+    // that.
+    if (Ctx.getLangOptions().CPlusPlus && 
+        cast<ExplicitCastExpr>(this)->getTypeAsWritten()->isRecordType())
+      return LV_ClassTemporary;
+
+    break;
+  case CXXTypeidExprClass:
+    // C++ 5.2.8p1: The result of a typeid expression is an lvalue of ...
+    return LV_Valid;
+  case CXXBindTemporaryExprClass:
+    return cast<CXXBindTemporaryExpr>(this)->getSubExpr()->
+      isLvalueInternal(Ctx);
+  case CXXBindReferenceExprClass:
+    // Something that's bound to a reference is always an lvalue.
+    return LV_Valid;
+  case ConditionalOperatorClass: {
+    // Complicated handling is only for C++.
+    if (!Ctx.getLangOptions().CPlusPlus)
+      return LV_InvalidExpression;
+
+    // Sema should have taken care to ensure that a CXXTemporaryObjectExpr is
+    // everywhere there's an object converted to an rvalue. Also, any other
+    // casts should be wrapped by ImplicitCastExprs. There's just the special
+    // case involving throws to work out.
+    const ConditionalOperator *Cond = cast<ConditionalOperator>(this);
+    Expr *True = Cond->getTrueExpr();
+    Expr *False = Cond->getFalseExpr();
+    // C++0x 5.16p2
+    //   If either the second or the third operand has type (cv) void, [...]
+    //   the result [...] is an rvalue.
+    if (True->getType()->isVoidType() || False->getType()->isVoidType())
+      return LV_InvalidExpression;
+
+    // Both sides must be lvalues for the result to be an lvalue.
+    if (True->isLvalue(Ctx) != LV_Valid || False->isLvalue(Ctx) != LV_Valid)
+      return LV_InvalidExpression;
+
+    // That's it.
+    return LV_Valid;
+  }
+
+  case Expr::CXXExprWithTemporariesClass:
+    return cast<CXXExprWithTemporaries>(this)->getSubExpr()->isLvalue(Ctx);
+
+  case Expr::ObjCMessageExprClass:
+    if (const ObjCMethodDecl *Method
+          = cast<ObjCMessageExpr>(this)->getMethodDecl())
+      if (Method->getResultType()->isLValueReferenceType())
+        return LV_Valid;
+    break;
+
+  case Expr::CXXConstructExprClass:
+  case Expr::CXXTemporaryObjectExprClass:
+  case Expr::CXXZeroInitValueExprClass:
+    return LV_ClassTemporary;
+
+  default:
+    break;
+  }
+  return LV_InvalidExpression;
+}
+
+/// isModifiableLvalue - C99 6.3.2.1: an lvalue that does not have array type,
+/// does not have an incomplete type, does not have a const-qualified type, and
+/// if it is a structure or union, does not have any member (including,
+/// recursively, any member or element of all contained aggregates or unions)
+/// with a const-qualified type.
+Expr::isModifiableLvalueResult
+Expr::isModifiableLvalue(ASTContext &Ctx, SourceLocation *Loc) const {
+  isLvalueResult lvalResult = isLvalue(Ctx);
+
+  switch (lvalResult) {
+  case LV_Valid:
+    // C++ 3.10p11: Functions cannot be modified, but pointers to
+    // functions can be modifiable.
+    if (Ctx.getLangOptions().CPlusPlus && TR->isFunctionType())
+      return MLV_NotObjectType;
+    break;
+
+  case LV_NotObjectType: return MLV_NotObjectType;
+  case LV_IncompleteVoidType: return MLV_IncompleteVoidType;
+  case LV_DuplicateVectorComponents: return MLV_DuplicateVectorComponents;
+  case LV_InvalidExpression:
+    // If the top level is a C-style cast, and the subexpression is a valid
+    // lvalue, then this is probably a use of the old-school "cast as lvalue"
+    // GCC extension.  We don't support it, but we want to produce good
+    // diagnostics when it happens so that the user knows why.
+    if (const CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(IgnoreParens())) {
+      if (CE->getSubExpr()->isLvalue(Ctx) == LV_Valid) {
+        if (Loc)
+          *Loc = CE->getLParenLoc();
+        return MLV_LValueCast;
+      }
+    }
+    return MLV_InvalidExpression;
+  case LV_MemberFunction: return MLV_MemberFunction;
+  case LV_SubObjCPropertySetting: return MLV_SubObjCPropertySetting;
+  case LV_ClassTemporary:
+    return MLV_ClassTemporary;
+  }
+
+  // The following is illegal:
+  //   void takeclosure(void (^C)(void));
+  //   void func() { int x = 1; takeclosure(^{ x = 7; }); }
+  //
+  if (const BlockDeclRefExpr *BDR = dyn_cast<BlockDeclRefExpr>(this)) {
+    if (!BDR->isByRef() && isa<VarDecl>(BDR->getDecl()))
+      return MLV_NotBlockQualified;
+  }
+
+  // Assigning to an 'implicit' property?
+  if (const ObjCImplicitSetterGetterRefExpr* Expr =
+        dyn_cast<ObjCImplicitSetterGetterRefExpr>(this)) {
+    if (Expr->getSetterMethod() == 0)
+      return MLV_NoSetterProperty;
+  }
+
+  QualType CT = Ctx.getCanonicalType(getType());
+
+  if (CT.isConstQualified())
+    return MLV_ConstQualified;
+  if (CT->isArrayType())
+    return MLV_ArrayType;
+  if (CT->isIncompleteType())
+    return MLV_IncompleteType;
+
+  if (const RecordType *r = CT->getAs<RecordType>()) {
+    if (r->hasConstFields())
+      return MLV_ConstQualified;
+  }
+
+  return MLV_Valid;
+}
+
+/// isOBJCGCCandidate - Check if an expression is objc gc'able.
+/// returns true, if it is; false otherwise.
+bool Expr::isOBJCGCCandidate(ASTContext &Ctx) const {
+  switch (getStmtClass()) {
+  default:
+    return false;
+  case ObjCIvarRefExprClass:
+    return true;
+  case Expr::UnaryOperatorClass:
+    return cast<UnaryOperator>(this)->getSubExpr()->isOBJCGCCandidate(Ctx);
+  case ParenExprClass:
+    return cast<ParenExpr>(this)->getSubExpr()->isOBJCGCCandidate(Ctx);
+  case ImplicitCastExprClass:
+    return cast<ImplicitCastExpr>(this)->getSubExpr()->isOBJCGCCandidate(Ctx);
+  case CStyleCastExprClass:
+    return cast<CStyleCastExpr>(this)->getSubExpr()->isOBJCGCCandidate(Ctx);
+  case DeclRefExprClass: {
+    const Decl *D = cast<DeclRefExpr>(this)->getDecl();
+    if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
+      if (VD->hasGlobalStorage())
+        return true;
+      QualType T = VD->getType();
+      // dereferencing to a  pointer is always a gc'able candidate,
+      // unless it is __weak.
+      return T->isPointerType() &&
+             (Ctx.getObjCGCAttrKind(T) != Qualifiers::Weak);
+    }
+    return false;
+  }
+  case MemberExprClass: {
+    const MemberExpr *M = cast<MemberExpr>(this);
+    return M->getBase()->isOBJCGCCandidate(Ctx);
+  }
+  case ArraySubscriptExprClass:
+    return cast<ArraySubscriptExpr>(this)->getBase()->isOBJCGCCandidate(Ctx);
+  }
+}
+Expr* Expr::IgnoreParens() {
+  Expr* E = this;
+  while (ParenExpr* P = dyn_cast<ParenExpr>(E))
+    E = P->getSubExpr();
+
+  return E;
+}
+
+/// IgnoreParenCasts - Ignore parentheses and casts.  Strip off any ParenExpr
+/// or CastExprs or ImplicitCastExprs, returning their operand.
+Expr *Expr::IgnoreParenCasts() {
+  Expr *E = this;
+  while (true) {
+    if (ParenExpr *P = dyn_cast<ParenExpr>(E))
+      E = P->getSubExpr();
+    else if (CastExpr *P = dyn_cast<CastExpr>(E))
+      E = P->getSubExpr();
+    else
+      return E;
+  }
+}
+
+/// IgnoreParenNoopCasts - Ignore parentheses and casts that do not change the
+/// value (including ptr->int casts of the same size).  Strip off any
+/// ParenExpr or CastExprs, returning their operand.
+Expr *Expr::IgnoreParenNoopCasts(ASTContext &Ctx) {
+  Expr *E = this;
+  while (true) {
+    if (ParenExpr *P = dyn_cast<ParenExpr>(E)) {
+      E = P->getSubExpr();
+      continue;
+    }
+
+    if (CastExpr *P = dyn_cast<CastExpr>(E)) {
+      // We ignore integer <-> casts that are of the same width, ptr<->ptr and
+      // ptr<->int casts of the same width.  We also ignore all identify casts.
+      Expr *SE = P->getSubExpr();
+
+      if (Ctx.hasSameUnqualifiedType(E->getType(), SE->getType())) {
+        E = SE;
+        continue;
+      }
+
+      if ((E->getType()->isPointerType() || E->getType()->isIntegralType()) &&
+          (SE->getType()->isPointerType() || SE->getType()->isIntegralType()) &&
+          Ctx.getTypeSize(E->getType()) == Ctx.getTypeSize(SE->getType())) {
+        E = SE;
+        continue;
+      }
+    }
+
+    return E;
+  }
+}
+
+bool Expr::isDefaultArgument() const {
+  const Expr *E = this;
+  while (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E))
+    E = ICE->getSubExprAsWritten();
+  
+  return isa<CXXDefaultArgExpr>(E);
+}
+
+/// \brief Skip over any no-op casts and any temporary-binding
+/// expressions.
+static const Expr *skipTemporaryBindingsAndNoOpCasts(const Expr *E) {
+  while (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) {
+    if (ICE->getCastKind() == CastExpr::CK_NoOp)
+      E = ICE->getSubExpr();
+    else
+      break;
+  }
+
+  while (const CXXBindTemporaryExpr *BE = dyn_cast<CXXBindTemporaryExpr>(E))
+    E = BE->getSubExpr();
+
+  while (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) {
+    if (ICE->getCastKind() == CastExpr::CK_NoOp)
+      E = ICE->getSubExpr();
+    else
+      break;
+  }
+  
+  return E;
+}
+
+const Expr *Expr::getTemporaryObject() const {
+  const Expr *E = skipTemporaryBindingsAndNoOpCasts(this);
+
+  // A cast can produce a temporary object. The object's construction
+  // is represented as a CXXConstructExpr.
+  if (const CastExpr *Cast = dyn_cast<CastExpr>(E)) {
+    // Only user-defined and constructor conversions can produce
+    // temporary objects.
+    if (Cast->getCastKind() != CastExpr::CK_ConstructorConversion &&
+        Cast->getCastKind() != CastExpr::CK_UserDefinedConversion)
+      return 0;
+
+    // Strip off temporary bindings and no-op casts.
+    const Expr *Sub = skipTemporaryBindingsAndNoOpCasts(Cast->getSubExpr());
+
+    // If this is a constructor conversion, see if we have an object
+    // construction.
+    if (Cast->getCastKind() == CastExpr::CK_ConstructorConversion)
+      return dyn_cast<CXXConstructExpr>(Sub);
+
+    // If this is a user-defined conversion, see if we have a call to
+    // a function that itself returns a temporary object.
+    if (Cast->getCastKind() == CastExpr::CK_UserDefinedConversion)
+      if (const CallExpr *CE = dyn_cast<CallExpr>(Sub))
+        if (CE->getCallReturnType()->isRecordType())
+          return CE;
+
+    return 0;
+  }
+
+  // A call returning a class type returns a temporary.
+  if (const CallExpr *CE = dyn_cast<CallExpr>(E)) {
+    if (CE->getCallReturnType()->isRecordType())
+      return CE;
+
+    return 0;
+  }
+
+  // Explicit temporary object constructors create temporaries.
+  return dyn_cast<CXXTemporaryObjectExpr>(E);
+}
+
+/// hasAnyTypeDependentArguments - Determines if any of the expressions
+/// in Exprs is type-dependent.
+bool Expr::hasAnyTypeDependentArguments(Expr** Exprs, unsigned NumExprs) {
+  for (unsigned I = 0; I < NumExprs; ++I)
+    if (Exprs[I]->isTypeDependent())
+      return true;
+
+  return false;
+}
+
+/// hasAnyValueDependentArguments - Determines if any of the expressions
+/// in Exprs is value-dependent.
+bool Expr::hasAnyValueDependentArguments(Expr** Exprs, unsigned NumExprs) {
+  for (unsigned I = 0; I < NumExprs; ++I)
+    if (Exprs[I]->isValueDependent())
+      return true;
+
+  return false;
+}
+
+bool Expr::isConstantInitializer(ASTContext &Ctx) const {
+  // This function is attempting whether an expression is an initializer
+  // which can be evaluated at compile-time.  isEvaluatable handles most
+  // of the cases, but it can't deal with some initializer-specific
+  // expressions, and it can't deal with aggregates; we deal with those here,
+  // and fall back to isEvaluatable for the other cases.
+
+  // FIXME: This function assumes the variable being assigned to
+  // isn't a reference type!
+
+  switch (getStmtClass()) {
+  default: break;
+  case StringLiteralClass:
+  case ObjCStringLiteralClass:
+  case ObjCEncodeExprClass:
+    return true;
+  case CompoundLiteralExprClass: {
+    // This handles gcc's extension that allows global initializers like
+    // "struct x {int x;} x = (struct x) {};".
+    // FIXME: This accepts other cases it shouldn't!
+    const Expr *Exp = cast<CompoundLiteralExpr>(this)->getInitializer();
+    return Exp->isConstantInitializer(Ctx);
+  }
+  case InitListExprClass: {
+    // FIXME: This doesn't deal with fields with reference types correctly.
+    // FIXME: This incorrectly allows pointers cast to integers to be assigned
+    // to bitfields.
+    const InitListExpr *Exp = cast<InitListExpr>(this);
+    unsigned numInits = Exp->getNumInits();
+    for (unsigned i = 0; i < numInits; i++) {
+      if (!Exp->getInit(i)->isConstantInitializer(Ctx))
+        return false;
+    }
+    return true;
+  }
+  case ImplicitValueInitExprClass:
+    return true;
+  case ParenExprClass:
+    return cast<ParenExpr>(this)->getSubExpr()->isConstantInitializer(Ctx);
+  case UnaryOperatorClass: {
+    const UnaryOperator* Exp = cast<UnaryOperator>(this);
+    if (Exp->getOpcode() == UnaryOperator::Extension)
+      return Exp->getSubExpr()->isConstantInitializer(Ctx);
+    break;
+  }
+  case BinaryOperatorClass: {
+    // Special case &&foo - &&bar.  It would be nice to generalize this somehow
+    // but this handles the common case.
+    const BinaryOperator *Exp = cast<BinaryOperator>(this);
+    if (Exp->getOpcode() == BinaryOperator::Sub &&
+        isa<AddrLabelExpr>(Exp->getLHS()->IgnoreParenNoopCasts(Ctx)) &&
+        isa<AddrLabelExpr>(Exp->getRHS()->IgnoreParenNoopCasts(Ctx)))
+      return true;
+    break;
+  }
+  case ImplicitCastExprClass:
+  case CStyleCastExprClass:
+    // Handle casts with a destination that's a struct or union; this
+    // deals with both the gcc no-op struct cast extension and the
+    // cast-to-union extension.
+    if (getType()->isRecordType())
+      return cast<CastExpr>(this)->getSubExpr()->isConstantInitializer(Ctx);
+      
+    // Integer->integer casts can be handled here, which is important for
+    // things like (int)(&&x-&&y).  Scary but true.
+    if (getType()->isIntegerType() &&
+        cast<CastExpr>(this)->getSubExpr()->getType()->isIntegerType())
+      return cast<CastExpr>(this)->getSubExpr()->isConstantInitializer(Ctx);
+      
+    break;
+  }
+  return isEvaluatable(Ctx);
+}
+
+/// isIntegerConstantExpr - this recursive routine will test if an expression is
+/// an integer constant expression.
+
+/// FIXME: Pass up a reason why! Invalid operation in i-c-e, division by zero,
+/// comma, etc
+///
+/// FIXME: Handle offsetof.  Two things to do:  Handle GCC's __builtin_offsetof
+/// to support gcc 4.0+  and handle the idiom GCC recognizes with a null pointer
+/// cast+dereference.
+
+// CheckICE - This function does the fundamental ICE checking: the returned
+// ICEDiag contains a Val of 0, 1, or 2, and a possibly null SourceLocation.
+// Note that to reduce code duplication, this helper does no evaluation
+// itself; the caller checks whether the expression is evaluatable, and
+// in the rare cases where CheckICE actually cares about the evaluated
+// value, it calls into Evalute.
+//
+// Meanings of Val:
+// 0: This expression is an ICE if it can be evaluated by Evaluate.
+// 1: This expression is not an ICE, but if it isn't evaluated, it's
+//    a legal subexpression for an ICE. This return value is used to handle
+//    the comma operator in C99 mode.
+// 2: This expression is not an ICE, and is not a legal subexpression for one.
+
+struct ICEDiag {
+  unsigned Val;
+  SourceLocation Loc;
+
+  public:
+  ICEDiag(unsigned v, SourceLocation l) : Val(v), Loc(l) {}
+  ICEDiag() : Val(0) {}
+};
+
+ICEDiag NoDiag() { return ICEDiag(); }
+
+static ICEDiag CheckEvalInICE(const Expr* E, ASTContext &Ctx) {
+  Expr::EvalResult EVResult;
+  if (!E->Evaluate(EVResult, Ctx) || EVResult.HasSideEffects ||
+      !EVResult.Val.isInt()) {
+    return ICEDiag(2, E->getLocStart());
+  }
+  return NoDiag();
+}
+
+static ICEDiag CheckICE(const Expr* E, ASTContext &Ctx) {
+  assert(!E->isValueDependent() && "Should not see value dependent exprs!");
+  if (!E->getType()->isIntegralType()) {
+    return ICEDiag(2, E->getLocStart());
+  }
+
+  switch (E->getStmtClass()) {
+#define STMT(Node, Base) case Expr::Node##Class:
+#define EXPR(Node, Base)
+#include "clang/AST/StmtNodes.def"
+  case Expr::PredefinedExprClass:
+  case Expr::FloatingLiteralClass:
+  case Expr::ImaginaryLiteralClass:
+  case Expr::StringLiteralClass:
+  case Expr::ArraySubscriptExprClass:
+  case Expr::MemberExprClass:
+  case Expr::CompoundAssignOperatorClass:
+  case Expr::CompoundLiteralExprClass:
+  case Expr::ExtVectorElementExprClass:
+  case Expr::InitListExprClass:
+  case Expr::DesignatedInitExprClass:
+  case Expr::ImplicitValueInitExprClass:
+  case Expr::ParenListExprClass:
+  case Expr::VAArgExprClass:
+  case Expr::AddrLabelExprClass:
+  case Expr::StmtExprClass:
+  case Expr::CXXMemberCallExprClass:
+  case Expr::CXXDynamicCastExprClass:
+  case Expr::CXXTypeidExprClass:
+  case Expr::CXXNullPtrLiteralExprClass:
+  case Expr::CXXThisExprClass:
+  case Expr::CXXThrowExprClass:
+  case Expr::CXXNewExprClass:
+  case Expr::CXXDeleteExprClass:
+  case Expr::CXXPseudoDestructorExprClass:
+  case Expr::UnresolvedLookupExprClass:
+  case Expr::DependentScopeDeclRefExprClass:
+  case Expr::CXXConstructExprClass:
+  case Expr::CXXBindTemporaryExprClass:
+  case Expr::CXXBindReferenceExprClass:
+  case Expr::CXXExprWithTemporariesClass:
+  case Expr::CXXTemporaryObjectExprClass:
+  case Expr::CXXUnresolvedConstructExprClass:
+  case Expr::CXXDependentScopeMemberExprClass:
+  case Expr::UnresolvedMemberExprClass:
+  case Expr::ObjCStringLiteralClass:
+  case Expr::ObjCEncodeExprClass:
+  case Expr::ObjCMessageExprClass:
+  case Expr::ObjCSelectorExprClass:
+  case Expr::ObjCProtocolExprClass:
+  case Expr::ObjCIvarRefExprClass:
+  case Expr::ObjCPropertyRefExprClass:
+  case Expr::ObjCImplicitSetterGetterRefExprClass:
+  case Expr::ObjCSuperExprClass:
+  case Expr::ObjCIsaExprClass:
+  case Expr::ShuffleVectorExprClass:
+  case Expr::BlockExprClass:
+  case Expr::BlockDeclRefExprClass:
+  case Expr::NoStmtClass:
+    return ICEDiag(2, E->getLocStart());
+
+  case Expr::GNUNullExprClass:
+    // GCC considers the GNU __null value to be an integral constant expression.
+    return NoDiag();
+
+  case Expr::ParenExprClass:
+    return CheckICE(cast<ParenExpr>(E)->getSubExpr(), Ctx);
+  case Expr::IntegerLiteralClass:
+  case Expr::CharacterLiteralClass:
+  case Expr::CXXBoolLiteralExprClass:
+  case Expr::CXXZeroInitValueExprClass:
+  case Expr::TypesCompatibleExprClass:
+  case Expr::UnaryTypeTraitExprClass:
+    return NoDiag();
+  case Expr::CallExprClass:
+  case Expr::CXXOperatorCallExprClass: {
+    const CallExpr *CE = cast<CallExpr>(E);
+    if (CE->isBuiltinCall(Ctx))
+      return CheckEvalInICE(E, Ctx);
+    return ICEDiag(2, E->getLocStart());
+  }
+  case Expr::DeclRefExprClass:
+    if (isa<EnumConstantDecl>(cast<DeclRefExpr>(E)->getDecl()))
+      return NoDiag();
+    if (Ctx.getLangOptions().CPlusPlus &&
+        E->getType().getCVRQualifiers() == Qualifiers::Const) {
+      const NamedDecl *D = cast<DeclRefExpr>(E)->getDecl();
+
+      // Parameter variables are never constants.  Without this check,
+      // getAnyInitializer() can find a default argument, which leads
+      // to chaos.
+      if (isa<ParmVarDecl>(D))
+        return ICEDiag(2, cast<DeclRefExpr>(E)->getLocation());
+
+      // C++ 7.1.5.1p2
+      //   A variable of non-volatile const-qualified integral or enumeration
+      //   type initialized by an ICE can be used in ICEs.
+      if (const VarDecl *Dcl = dyn_cast<VarDecl>(D)) {
+        Qualifiers Quals = Ctx.getCanonicalType(Dcl->getType()).getQualifiers();
+        if (Quals.hasVolatile() || !Quals.hasConst())
+          return ICEDiag(2, cast<DeclRefExpr>(E)->getLocation());
+        
+        // Look for a declaration of this variable that has an initializer.
+        const VarDecl *ID = 0;
+        const Expr *Init = Dcl->getAnyInitializer(ID);
+        if (Init) {
+          if (ID->isInitKnownICE()) {
+            // We have already checked whether this subexpression is an
+            // integral constant expression.
+            if (ID->isInitICE())
+              return NoDiag();
+            else
+              return ICEDiag(2, cast<DeclRefExpr>(E)->getLocation());
+          }
+
+          // It's an ICE whether or not the definition we found is
+          // out-of-line.  See DR 721 and the discussion in Clang PR
+          // 6206 for details.
+
+          if (Dcl->isCheckingICE()) {
+            return ICEDiag(2, cast<DeclRefExpr>(E)->getLocation());
+          }
+
+          Dcl->setCheckingICE();
+          ICEDiag Result = CheckICE(Init, Ctx);
+          // Cache the result of the ICE test.
+          Dcl->setInitKnownICE(Result.Val == 0);
+          return Result;
+        }
+      }
+    }
+    return ICEDiag(2, E->getLocStart());
+  case Expr::UnaryOperatorClass: {
+    const UnaryOperator *Exp = cast<UnaryOperator>(E);
+    switch (Exp->getOpcode()) {
+    case UnaryOperator::PostInc:
+    case UnaryOperator::PostDec:
+    case UnaryOperator::PreInc:
+    case UnaryOperator::PreDec:
+    case UnaryOperator::AddrOf:
+    case UnaryOperator::Deref:
+      return ICEDiag(2, E->getLocStart());
+
+    case UnaryOperator::Extension:
+    case UnaryOperator::LNot:
+    case UnaryOperator::Plus:
+    case UnaryOperator::Minus:
+    case UnaryOperator::Not:
+    case UnaryOperator::Real:
+    case UnaryOperator::Imag:
+      return CheckICE(Exp->getSubExpr(), Ctx);
+    case UnaryOperator::OffsetOf:
+      // Note that per C99, offsetof must be an ICE. And AFAIK, using
+      // Evaluate matches the proposed gcc behavior for cases like
+      // "offsetof(struct s{int x[4];}, x[!.0])".  This doesn't affect
+      // compliance: we should warn earlier for offsetof expressions with
+      // array subscripts that aren't ICEs, and if the array subscripts
+      // are ICEs, the value of the offsetof must be an integer constant.
+      return CheckEvalInICE(E, Ctx);
+    }
+  }
+  case Expr::SizeOfAlignOfExprClass: {
+    const SizeOfAlignOfExpr *Exp = cast<SizeOfAlignOfExpr>(E);
+    if (Exp->isSizeOf() && Exp->getTypeOfArgument()->isVariableArrayType())
+      return ICEDiag(2, E->getLocStart());
+    return NoDiag();
+  }
+  case Expr::BinaryOperatorClass: {
+    const BinaryOperator *Exp = cast<BinaryOperator>(E);
+    switch (Exp->getOpcode()) {
+    case BinaryOperator::PtrMemD:
+    case BinaryOperator::PtrMemI:
+    case BinaryOperator::Assign:
+    case BinaryOperator::MulAssign:
+    case BinaryOperator::DivAssign:
+    case BinaryOperator::RemAssign:
+    case BinaryOperator::AddAssign:
+    case BinaryOperator::SubAssign:
+    case BinaryOperator::ShlAssign:
+    case BinaryOperator::ShrAssign:
+    case BinaryOperator::AndAssign:
+    case BinaryOperator::XorAssign:
+    case BinaryOperator::OrAssign:
+      return ICEDiag(2, E->getLocStart());
+
+    case BinaryOperator::Mul:
+    case BinaryOperator::Div:
+    case BinaryOperator::Rem:
+    case BinaryOperator::Add:
+    case BinaryOperator::Sub:
+    case BinaryOperator::Shl:
+    case BinaryOperator::Shr:
+    case BinaryOperator::LT:
+    case BinaryOperator::GT:
+    case BinaryOperator::LE:
+    case BinaryOperator::GE:
+    case BinaryOperator::EQ:
+    case BinaryOperator::NE:
+    case BinaryOperator::And:
+    case BinaryOperator::Xor:
+    case BinaryOperator::Or:
+    case BinaryOperator::Comma: {
+      ICEDiag LHSResult = CheckICE(Exp->getLHS(), Ctx);
+      ICEDiag RHSResult = CheckICE(Exp->getRHS(), Ctx);
+      if (Exp->getOpcode() == BinaryOperator::Div ||
+          Exp->getOpcode() == BinaryOperator::Rem) {
+        // Evaluate gives an error for undefined Div/Rem, so make sure
+        // we don't evaluate one.
+        if (LHSResult.Val != 2 && RHSResult.Val != 2) {
+          llvm::APSInt REval = Exp->getRHS()->EvaluateAsInt(Ctx);
+          if (REval == 0)
+            return ICEDiag(1, E->getLocStart());
+          if (REval.isSigned() && REval.isAllOnesValue()) {
+            llvm::APSInt LEval = Exp->getLHS()->EvaluateAsInt(Ctx);
+            if (LEval.isMinSignedValue())
+              return ICEDiag(1, E->getLocStart());
+          }
+        }
+      }
+      if (Exp->getOpcode() == BinaryOperator::Comma) {
+        if (Ctx.getLangOptions().C99) {
+          // C99 6.6p3 introduces a strange edge case: comma can be in an ICE
+          // if it isn't evaluated.
+          if (LHSResult.Val == 0 && RHSResult.Val == 0)
+            return ICEDiag(1, E->getLocStart());
+        } else {
+          // In both C89 and C++, commas in ICEs are illegal.
+          return ICEDiag(2, E->getLocStart());
+        }
+      }
+      if (LHSResult.Val >= RHSResult.Val)
+        return LHSResult;
+      return RHSResult;
+    }
+    case BinaryOperator::LAnd:
+    case BinaryOperator::LOr: {
+      ICEDiag LHSResult = CheckICE(Exp->getLHS(), Ctx);
+      ICEDiag RHSResult = CheckICE(Exp->getRHS(), Ctx);
+      if (LHSResult.Val == 0 && RHSResult.Val == 1) {
+        // Rare case where the RHS has a comma "side-effect"; we need
+        // to actually check the condition to see whether the side
+        // with the comma is evaluated.
+        if ((Exp->getOpcode() == BinaryOperator::LAnd) !=
+            (Exp->getLHS()->EvaluateAsInt(Ctx) == 0))
+          return RHSResult;
+        return NoDiag();
+      }
+
+      if (LHSResult.Val >= RHSResult.Val)
+        return LHSResult;
+      return RHSResult;
+    }
+    }
+  }
+  case Expr::ImplicitCastExprClass:
+  case Expr::CStyleCastExprClass:
+  case Expr::CXXFunctionalCastExprClass:
+  case Expr::CXXStaticCastExprClass:
+  case Expr::CXXReinterpretCastExprClass:
+  case Expr::CXXConstCastExprClass: {
+    const Expr *SubExpr = cast<CastExpr>(E)->getSubExpr();
+    if (SubExpr->getType()->isIntegralType())
+      return CheckICE(SubExpr, Ctx);
+    if (isa<FloatingLiteral>(SubExpr->IgnoreParens()))
+      return NoDiag();
+    return ICEDiag(2, E->getLocStart());
+  }
+  case Expr::ConditionalOperatorClass: {
+    const ConditionalOperator *Exp = cast<ConditionalOperator>(E);
+    // If the condition (ignoring parens) is a __builtin_constant_p call,
+    // then only the true side is actually considered in an integer constant
+    // expression, and it is fully evaluated.  This is an important GNU
+    // extension.  See GCC PR38377 for discussion.
+    if (const CallExpr *CallCE = dyn_cast<CallExpr>(Exp->getCond()->IgnoreParenCasts()))
+      if (CallCE->isBuiltinCall(Ctx) == Builtin::BI__builtin_constant_p) {
+        Expr::EvalResult EVResult;
+        if (!E->Evaluate(EVResult, Ctx) || EVResult.HasSideEffects ||
+            !EVResult.Val.isInt()) {
+          return ICEDiag(2, E->getLocStart());
+        }
+        return NoDiag();
+      }
+    ICEDiag CondResult = CheckICE(Exp->getCond(), Ctx);
+    ICEDiag TrueResult = CheckICE(Exp->getTrueExpr(), Ctx);
+    ICEDiag FalseResult = CheckICE(Exp->getFalseExpr(), Ctx);
+    if (CondResult.Val == 2)
+      return CondResult;
+    if (TrueResult.Val == 2)
+      return TrueResult;
+    if (FalseResult.Val == 2)
+      return FalseResult;
+    if (CondResult.Val == 1)
+      return CondResult;
+    if (TrueResult.Val == 0 && FalseResult.Val == 0)
+      return NoDiag();
+    // Rare case where the diagnostics depend on which side is evaluated
+    // Note that if we get here, CondResult is 0, and at least one of
+    // TrueResult and FalseResult is non-zero.
+    if (Exp->getCond()->EvaluateAsInt(Ctx) == 0) {
+      return FalseResult;
+    }
+    return TrueResult;
+  }
+  case Expr::CXXDefaultArgExprClass:
+    return CheckICE(cast<CXXDefaultArgExpr>(E)->getExpr(), Ctx);
+  case Expr::ChooseExprClass: {
+    return CheckICE(cast<ChooseExpr>(E)->getChosenSubExpr(Ctx), Ctx);
+  }
+  }
+
+  // Silence a GCC warning
+  return ICEDiag(2, E->getLocStart());
+}
+
+bool Expr::isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx,
+                                 SourceLocation *Loc, bool isEvaluated) const {
+  ICEDiag d = CheckICE(this, Ctx);
+  if (d.Val != 0) {
+    if (Loc) *Loc = d.Loc;
+    return false;
+  }
+  EvalResult EvalResult;
+  if (!Evaluate(EvalResult, Ctx))
+    llvm_unreachable("ICE cannot be evaluated!");
+  assert(!EvalResult.HasSideEffects && "ICE with side effects!");
+  assert(EvalResult.Val.isInt() && "ICE that isn't integer!");
+  Result = EvalResult.Val.getInt();
+  return true;
+}
+
+/// isNullPointerConstant - C99 6.3.2.3p3 -  Return true if this is either an
+/// integer constant expression with the value zero, or if this is one that is
+/// cast to void*.
+bool Expr::isNullPointerConstant(ASTContext &Ctx,
+                                 NullPointerConstantValueDependence NPC) const {
+  if (isValueDependent()) {
+    switch (NPC) {
+    case NPC_NeverValueDependent:
+      assert(false && "Unexpected value dependent expression!");
+      // If the unthinkable happens, fall through to the safest alternative.
+        
+    case NPC_ValueDependentIsNull:
+      return isTypeDependent() || getType()->isIntegralType();
+        
+    case NPC_ValueDependentIsNotNull:
+      return false;
+    }
+  }
+
+  // Strip off a cast to void*, if it exists. Except in C++.
+  if (const ExplicitCastExpr *CE = dyn_cast<ExplicitCastExpr>(this)) {
+    if (!Ctx.getLangOptions().CPlusPlus) {
+      // Check that it is a cast to void*.
+      if (const PointerType *PT = CE->getType()->getAs<PointerType>()) {
+        QualType Pointee = PT->getPointeeType();
+        if (!Pointee.hasQualifiers() &&
+            Pointee->isVoidType() &&                              // to void*
+            CE->getSubExpr()->getType()->isIntegerType())         // from int.
+          return CE->getSubExpr()->isNullPointerConstant(Ctx, NPC);
+      }
+    }
+  } else if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(this)) {
+    // Ignore the ImplicitCastExpr type entirely.
+    return ICE->getSubExpr()->isNullPointerConstant(Ctx, NPC);
+  } else if (const ParenExpr *PE = dyn_cast<ParenExpr>(this)) {
+    // Accept ((void*)0) as a null pointer constant, as many other
+    // implementations do.
+    return PE->getSubExpr()->isNullPointerConstant(Ctx, NPC);
+  } else if (const CXXDefaultArgExpr *DefaultArg
+               = dyn_cast<CXXDefaultArgExpr>(this)) {
+    // See through default argument expressions
+    return DefaultArg->getExpr()->isNullPointerConstant(Ctx, NPC);
+  } else if (isa<GNUNullExpr>(this)) {
+    // The GNU __null extension is always a null pointer constant.
+    return true;
+  }
+
+  // C++0x nullptr_t is always a null pointer constant.
+  if (getType()->isNullPtrType())
+    return true;
+
+  // This expression must be an integer type.
+  if (!getType()->isIntegerType() || 
+      (Ctx.getLangOptions().CPlusPlus && getType()->isEnumeralType()))
+    return false;
+
+  // If we have an integer constant expression, we need to *evaluate* it and
+  // test for the value 0.
+  llvm::APSInt Result;
+  return isIntegerConstantExpr(Result, Ctx) && Result == 0;
+}
+
+FieldDecl *Expr::getBitField() {
+  Expr *E = this->IgnoreParens();
+
+  while (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) {
+    if (ICE->isLvalueCast() && ICE->getCastKind() == CastExpr::CK_NoOp)
+      E = ICE->getSubExpr()->IgnoreParens();
+    else
+      break;
+  }
+
+  if (MemberExpr *MemRef = dyn_cast<MemberExpr>(E))
+    if (FieldDecl *Field = dyn_cast<FieldDecl>(MemRef->getMemberDecl()))
+      if (Field->isBitField())
+        return Field;
+
+  if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(E))
+    if (BinOp->isAssignmentOp() && BinOp->getLHS())
+      return BinOp->getLHS()->getBitField();
+
+  return 0;
+}
+
+bool Expr::refersToVectorElement() const {
+  const Expr *E = this->IgnoreParens();
+  
+  while (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) {
+    if (ICE->isLvalueCast() && ICE->getCastKind() == CastExpr::CK_NoOp)
+      E = ICE->getSubExpr()->IgnoreParens();
+    else
+      break;
+  }
+  
+  if (const ArraySubscriptExpr *ASE = dyn_cast<ArraySubscriptExpr>(E))
+    return ASE->getBase()->getType()->isVectorType();
+
+  if (isa<ExtVectorElementExpr>(E))
+    return true;
+
+  return false;
+}
+
+/// isArrow - Return true if the base expression is a pointer to vector,
+/// return false if the base expression is a vector.
+bool ExtVectorElementExpr::isArrow() const {
+  return getBase()->getType()->isPointerType();
+}
+
+unsigned ExtVectorElementExpr::getNumElements() const {
+  if (const VectorType *VT = getType()->getAs<VectorType>())
+    return VT->getNumElements();
+  return 1;
+}
+
+/// containsDuplicateElements - Return true if any element access is repeated.
+bool ExtVectorElementExpr::containsDuplicateElements() const {
+  // FIXME: Refactor this code to an accessor on the AST node which returns the
+  // "type" of component access, and share with code below and in Sema.
+  llvm::StringRef Comp = Accessor->getName();
+
+  // Halving swizzles do not contain duplicate elements.
+  if (Comp == "hi" || Comp == "lo" || Comp == "even" || Comp == "odd")
+    return false;
+
+  // Advance past s-char prefix on hex swizzles.
+  if (Comp[0] == 's' || Comp[0] == 'S')
+    Comp = Comp.substr(1);
+
+  for (unsigned i = 0, e = Comp.size(); i != e; ++i)
+    if (Comp.substr(i + 1).find(Comp[i]) != llvm::StringRef::npos)
+        return true;
+
+  return false;
+}
+
+/// getEncodedElementAccess - We encode the fields as a llvm ConstantArray.
+void ExtVectorElementExpr::getEncodedElementAccess(
+                                  llvm::SmallVectorImpl<unsigned> &Elts) const {
+  llvm::StringRef Comp = Accessor->getName();
+  if (Comp[0] == 's' || Comp[0] == 'S')
+    Comp = Comp.substr(1);
+
+  bool isHi =   Comp == "hi";
+  bool isLo =   Comp == "lo";
+  bool isEven = Comp == "even";
+  bool isOdd  = Comp == "odd";
+
+  for (unsigned i = 0, e = getNumElements(); i != e; ++i) {
+    uint64_t Index;
+
+    if (isHi)
+      Index = e + i;
+    else if (isLo)
+      Index = i;
+    else if (isEven)
+      Index = 2 * i;
+    else if (isOdd)
+      Index = 2 * i + 1;
+    else
+      Index = ExtVectorType::getAccessorIdx(Comp[i]);
+
+    Elts.push_back(Index);
+  }
+}
+
+ObjCMessageExpr::ObjCMessageExpr(QualType T,
+                                 SourceLocation LBracLoc,
+                                 SourceLocation SuperLoc,
+                                 bool IsInstanceSuper,
+                                 QualType SuperType,
+                                 Selector Sel, 
+                                 ObjCMethodDecl *Method,
+                                 Expr **Args, unsigned NumArgs,
+                                 SourceLocation RBracLoc)
+  : Expr(ObjCMessageExprClass, T, /*TypeDependent=*/false,
+         /*ValueDependent=*/false),
+    NumArgs(NumArgs), Kind(IsInstanceSuper? SuperInstance : SuperClass),
+    HasMethod(Method != 0), SuperLoc(SuperLoc),
+    SelectorOrMethod(reinterpret_cast<uintptr_t>(Method? Method
+                                                       : Sel.getAsOpaquePtr())),
+    LBracLoc(LBracLoc), RBracLoc(RBracLoc) 
+{
+  setReceiverPointer(SuperType.getAsOpaquePtr());
+  if (NumArgs)
+    memcpy(getArgs(), Args, NumArgs * sizeof(Expr *));
+}
+
+ObjCMessageExpr::ObjCMessageExpr(QualType T,
+                                 SourceLocation LBracLoc,
+                                 TypeSourceInfo *Receiver,
+                                 Selector Sel, 
+                                 ObjCMethodDecl *Method,
+                                 Expr **Args, unsigned NumArgs,
+                                 SourceLocation RBracLoc)
+  : Expr(ObjCMessageExprClass, T, T->isDependentType(),
+         (T->isDependentType() || 
+          hasAnyValueDependentArguments(Args, NumArgs))),
+    NumArgs(NumArgs), Kind(Class), HasMethod(Method != 0),
+    SelectorOrMethod(reinterpret_cast<uintptr_t>(Method? Method
+                                                       : Sel.getAsOpaquePtr())),
+    LBracLoc(LBracLoc), RBracLoc(RBracLoc) 
+{
+  setReceiverPointer(Receiver);
+  if (NumArgs)
+    memcpy(getArgs(), Args, NumArgs * sizeof(Expr *));
+}
+
+ObjCMessageExpr::ObjCMessageExpr(QualType T,
+                                 SourceLocation LBracLoc,
+                                 Expr *Receiver,
+                                 Selector Sel, 
+                                 ObjCMethodDecl *Method,
+                                 Expr **Args, unsigned NumArgs,
+                                 SourceLocation RBracLoc)
+  : Expr(ObjCMessageExprClass, T, Receiver->isTypeDependent(),
+         (Receiver->isTypeDependent() || 
+          hasAnyValueDependentArguments(Args, NumArgs))),
+    NumArgs(NumArgs), Kind(Instance), HasMethod(Method != 0),
+    SelectorOrMethod(reinterpret_cast<uintptr_t>(Method? Method
+                                                       : Sel.getAsOpaquePtr())),
+    LBracLoc(LBracLoc), RBracLoc(RBracLoc) 
+{
+  setReceiverPointer(Receiver);
+  if (NumArgs)
+    memcpy(getArgs(), Args, NumArgs * sizeof(Expr *));
+}
+
+ObjCMessageExpr *ObjCMessageExpr::Create(ASTContext &Context, QualType T,
+                                         SourceLocation LBracLoc,
+                                         SourceLocation SuperLoc,
+                                         bool IsInstanceSuper,
+                                         QualType SuperType,
+                                         Selector Sel, 
+                                         ObjCMethodDecl *Method,
+                                         Expr **Args, unsigned NumArgs,
+                                         SourceLocation RBracLoc) {
+  unsigned Size = sizeof(ObjCMessageExpr) + sizeof(void *) + 
+    NumArgs * sizeof(Expr *);
+  void *Mem = Context.Allocate(Size, llvm::AlignOf<ObjCMessageExpr>::Alignment);
+  return new (Mem) ObjCMessageExpr(T, LBracLoc, SuperLoc, IsInstanceSuper,
+                                   SuperType, Sel, Method, Args, NumArgs, 
+                                   RBracLoc);
+}
+
+ObjCMessageExpr *ObjCMessageExpr::Create(ASTContext &Context, QualType T,
+                                         SourceLocation LBracLoc,
+                                         TypeSourceInfo *Receiver,
+                                         Selector Sel, 
+                                         ObjCMethodDecl *Method,
+                                         Expr **Args, unsigned NumArgs,
+                                         SourceLocation RBracLoc) {
+  unsigned Size = sizeof(ObjCMessageExpr) + sizeof(void *) + 
+    NumArgs * sizeof(Expr *);
+  void *Mem = Context.Allocate(Size, llvm::AlignOf<ObjCMessageExpr>::Alignment);
+  return new (Mem) ObjCMessageExpr(T, LBracLoc, Receiver, Sel, Method, Args, 
+                                   NumArgs, RBracLoc);
+}
+
+ObjCMessageExpr *ObjCMessageExpr::Create(ASTContext &Context, QualType T,
+                                         SourceLocation LBracLoc,
+                                         Expr *Receiver,
+                                         Selector Sel, 
+                                         ObjCMethodDecl *Method,
+                                         Expr **Args, unsigned NumArgs,
+                                         SourceLocation RBracLoc) {
+  unsigned Size = sizeof(ObjCMessageExpr) + sizeof(void *) + 
+    NumArgs * sizeof(Expr *);
+  void *Mem = Context.Allocate(Size, llvm::AlignOf<ObjCMessageExpr>::Alignment);
+  return new (Mem) ObjCMessageExpr(T, LBracLoc, Receiver, Sel, Method, Args, 
+                                   NumArgs, RBracLoc);
+}
+
+ObjCMessageExpr *ObjCMessageExpr::CreateEmpty(ASTContext &Context, 
+                                              unsigned NumArgs) {
+  unsigned Size = sizeof(ObjCMessageExpr) + sizeof(void *) + 
+    NumArgs * sizeof(Expr *);
+  void *Mem = Context.Allocate(Size, llvm::AlignOf<ObjCMessageExpr>::Alignment);
+  return new (Mem) ObjCMessageExpr(EmptyShell(), NumArgs);
+}
+         
+Selector ObjCMessageExpr::getSelector() const {
+  if (HasMethod)
+    return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod)
+                                                               ->getSelector();
+  return Selector(SelectorOrMethod); 
+}
+
+ObjCInterfaceDecl *ObjCMessageExpr::getReceiverInterface() const {
+  switch (getReceiverKind()) {
+  case Instance:
+    if (const ObjCObjectPointerType *Ptr
+          = getInstanceReceiver()->getType()->getAs<ObjCObjectPointerType>())
+      return Ptr->getInterfaceDecl();
+    break;
+
+  case Class:
+    if (const ObjCInterfaceType *Iface
+                       = getClassReceiver()->getAs<ObjCInterfaceType>())
+      return Iface->getDecl();
+    break;
+
+  case SuperInstance:
+    if (const ObjCObjectPointerType *Ptr
+          = getSuperType()->getAs<ObjCObjectPointerType>())
+      return Ptr->getInterfaceDecl();
+    break;
+
+  case SuperClass:
+    if (const ObjCObjectPointerType *Iface
+                       = getSuperType()->getAs<ObjCObjectPointerType>())
+      return Iface->getInterfaceDecl();
+    break;
+  }
+
+  return 0;
+}
+
+bool ChooseExpr::isConditionTrue(ASTContext &C) const {
+  return getCond()->EvaluateAsInt(C) != 0;
+}
+
+void ShuffleVectorExpr::setExprs(ASTContext &C, Expr ** Exprs,
+                                 unsigned NumExprs) {
+  if (SubExprs) C.Deallocate(SubExprs);
+
+  SubExprs = new (C) Stmt* [NumExprs];
+  this->NumExprs = NumExprs;
+  memcpy(SubExprs, Exprs, sizeof(Expr *) * NumExprs);
+}
+
+void ShuffleVectorExpr::DoDestroy(ASTContext& C) {
+  DestroyChildren(C);
+  if (SubExprs) C.Deallocate(SubExprs);
+  this->~ShuffleVectorExpr();
+  C.Deallocate(this);
+}
+
+void SizeOfAlignOfExpr::DoDestroy(ASTContext& C) {
+  // Override default behavior of traversing children. If this has a type
+  // operand and the type is a variable-length array, the child iteration
+  // will iterate over the size expression. However, this expression belongs
+  // to the type, not to this, so we don't want to delete it.
+  // We still want to delete this expression.
+  if (isArgumentType()) {
+    this->~SizeOfAlignOfExpr();
+    C.Deallocate(this);
+  }
+  else
+    Expr::DoDestroy(C);
+}
+
+//===----------------------------------------------------------------------===//
+//  DesignatedInitExpr
+//===----------------------------------------------------------------------===//
+
+IdentifierInfo *DesignatedInitExpr::Designator::getFieldName() {
+  assert(Kind == FieldDesignator && "Only valid on a field designator");
+  if (Field.NameOrField & 0x01)
+    return reinterpret_cast<IdentifierInfo *>(Field.NameOrField&~0x01);
+  else
+    return getField()->getIdentifier();
+}
+
+DesignatedInitExpr::DesignatedInitExpr(ASTContext &C, QualType Ty, 
+                                       unsigned NumDesignators,
+                                       const Designator *Designators,
+                                       SourceLocation EqualOrColonLoc,
+                                       bool GNUSyntax,
+                                       Expr **IndexExprs,
+                                       unsigned NumIndexExprs,
+                                       Expr *Init)
+  : Expr(DesignatedInitExprClass, Ty,
+         Init->isTypeDependent(), Init->isValueDependent()),
+    EqualOrColonLoc(EqualOrColonLoc), GNUSyntax(GNUSyntax),
+    NumDesignators(NumDesignators), NumSubExprs(NumIndexExprs + 1) {
+  this->Designators = new (C) Designator[NumDesignators];
+
+  // Record the initializer itself.
+  child_iterator Child = child_begin();
+  *Child++ = Init;
+
+  // Copy the designators and their subexpressions, computing
+  // value-dependence along the way.
+  unsigned IndexIdx = 0;
+  for (unsigned I = 0; I != NumDesignators; ++I) {
+    this->Designators[I] = Designators[I];
+
+    if (this->Designators[I].isArrayDesignator()) {
+      // Compute type- and value-dependence.
+      Expr *Index = IndexExprs[IndexIdx];
+      ValueDependent = ValueDependent ||
+        Index->isTypeDependent() || Index->isValueDependent();
+
+      // Copy the index expressions into permanent storage.
+      *Child++ = IndexExprs[IndexIdx++];
+    } else if (this->Designators[I].isArrayRangeDesignator()) {
+      // Compute type- and value-dependence.
+      Expr *Start = IndexExprs[IndexIdx];
+      Expr *End = IndexExprs[IndexIdx + 1];
+      ValueDependent = ValueDependent ||
+        Start->isTypeDependent() || Start->isValueDependent() ||
+        End->isTypeDependent() || End->isValueDependent();
+
+      // Copy the start/end expressions into permanent storage.
+      *Child++ = IndexExprs[IndexIdx++];
+      *Child++ = IndexExprs[IndexIdx++];
+    }
+  }
+
+  assert(IndexIdx == NumIndexExprs && "Wrong number of index expressions");
+}
+
+DesignatedInitExpr *
+DesignatedInitExpr::Create(ASTContext &C, Designator *Designators,
+                           unsigned NumDesignators,
+                           Expr **IndexExprs, unsigned NumIndexExprs,
+                           SourceLocation ColonOrEqualLoc,
+                           bool UsesColonSyntax, Expr *Init) {
+  void *Mem = C.Allocate(sizeof(DesignatedInitExpr) +
+                         sizeof(Stmt *) * (NumIndexExprs + 1), 8);
+  return new (Mem) DesignatedInitExpr(C, C.VoidTy, NumDesignators, Designators,
+                                      ColonOrEqualLoc, UsesColonSyntax,
+                                      IndexExprs, NumIndexExprs, Init);
+}
+
+DesignatedInitExpr *DesignatedInitExpr::CreateEmpty(ASTContext &C,
+                                                    unsigned NumIndexExprs) {
+  void *Mem = C.Allocate(sizeof(DesignatedInitExpr) +
+                         sizeof(Stmt *) * (NumIndexExprs + 1), 8);
+  return new (Mem) DesignatedInitExpr(NumIndexExprs + 1);
+}
+
+void DesignatedInitExpr::setDesignators(ASTContext &C,
+                                        const Designator *Desigs,
+                                        unsigned NumDesigs) {
+  DestroyDesignators(C);
+
+  Designators = new (C) Designator[NumDesigs];
+  NumDesignators = NumDesigs;
+  for (unsigned I = 0; I != NumDesigs; ++I)
+    Designators[I] = Desigs[I];
+}
+
+SourceRange DesignatedInitExpr::getSourceRange() const {
+  SourceLocation StartLoc;
+  Designator &First =
+    *const_cast<DesignatedInitExpr*>(this)->designators_begin();
+  if (First.isFieldDesignator()) {
+    if (GNUSyntax)
+      StartLoc = SourceLocation::getFromRawEncoding(First.Field.FieldLoc);
+    else
+      StartLoc = SourceLocation::getFromRawEncoding(First.Field.DotLoc);
+  } else
+    StartLoc =
+      SourceLocation::getFromRawEncoding(First.ArrayOrRange.LBracketLoc);
+  return SourceRange(StartLoc, getInit()->getSourceRange().getEnd());
+}
+
+Expr *DesignatedInitExpr::getArrayIndex(const Designator& D) {
+  assert(D.Kind == Designator::ArrayDesignator && "Requires array designator");
+  char* Ptr = static_cast<char*>(static_cast<void *>(this));
+  Ptr += sizeof(DesignatedInitExpr);
+  Stmt **SubExprs = reinterpret_cast<Stmt**>(reinterpret_cast<void**>(Ptr));
+  return cast<Expr>(*(SubExprs + D.ArrayOrRange.Index + 1));
+}
+
+Expr *DesignatedInitExpr::getArrayRangeStart(const Designator& D) {
+  assert(D.Kind == Designator::ArrayRangeDesignator &&
+         "Requires array range designator");
+  char* Ptr = static_cast<char*>(static_cast<void *>(this));
+  Ptr += sizeof(DesignatedInitExpr);
+  Stmt **SubExprs = reinterpret_cast<Stmt**>(reinterpret_cast<void**>(Ptr));
+  return cast<Expr>(*(SubExprs + D.ArrayOrRange.Index + 1));
+}
+
+Expr *DesignatedInitExpr::getArrayRangeEnd(const Designator& D) {
+  assert(D.Kind == Designator::ArrayRangeDesignator &&
+         "Requires array range designator");
+  char* Ptr = static_cast<char*>(static_cast<void *>(this));
+  Ptr += sizeof(DesignatedInitExpr);
+  Stmt **SubExprs = reinterpret_cast<Stmt**>(reinterpret_cast<void**>(Ptr));
+  return cast<Expr>(*(SubExprs + D.ArrayOrRange.Index + 2));
+}
+
+/// \brief Replaces the designator at index @p Idx with the series
+/// of designators in [First, Last).
+void DesignatedInitExpr::ExpandDesignator(ASTContext &C, unsigned Idx,
+                                          const Designator *First,
+                                          const Designator *Last) {
+  unsigned NumNewDesignators = Last - First;
+  if (NumNewDesignators == 0) {
+    std::copy_backward(Designators + Idx + 1,
+                       Designators + NumDesignators,
+                       Designators + Idx);
+    --NumNewDesignators;
+    return;
+  } else if (NumNewDesignators == 1) {
+    Designators[Idx] = *First;
+    return;
+  }
+
+  Designator *NewDesignators
+    = new (C) Designator[NumDesignators - 1 + NumNewDesignators];
+  std::copy(Designators, Designators + Idx, NewDesignators);
+  std::copy(First, Last, NewDesignators + Idx);
+  std::copy(Designators + Idx + 1, Designators + NumDesignators,
+            NewDesignators + Idx + NumNewDesignators);
+  DestroyDesignators(C);
+  Designators = NewDesignators;
+  NumDesignators = NumDesignators - 1 + NumNewDesignators;
+}
+
+void DesignatedInitExpr::DoDestroy(ASTContext &C) {
+  DestroyDesignators(C);
+  Expr::DoDestroy(C);
+}
+
+void DesignatedInitExpr::DestroyDesignators(ASTContext &C) {
+  for (unsigned I = 0; I != NumDesignators; ++I)
+    Designators[I].~Designator();
+  C.Deallocate(Designators);
+  Designators = 0;
+}
+
+ParenListExpr::ParenListExpr(ASTContext& C, SourceLocation lparenloc,
+                             Expr **exprs, unsigned nexprs,
+                             SourceLocation rparenloc)
+: Expr(ParenListExprClass, QualType(),
+       hasAnyTypeDependentArguments(exprs, nexprs),
+       hasAnyValueDependentArguments(exprs, nexprs)),
+  NumExprs(nexprs), LParenLoc(lparenloc), RParenLoc(rparenloc) {
+
+  Exprs = new (C) Stmt*[nexprs];
+  for (unsigned i = 0; i != nexprs; ++i)
+    Exprs[i] = exprs[i];
+}
+
+void ParenListExpr::DoDestroy(ASTContext& C) {
+  DestroyChildren(C);
+  if (Exprs) C.Deallocate(Exprs);
+  this->~ParenListExpr();
+  C.Deallocate(this);
+}
+
+//===----------------------------------------------------------------------===//
+//  ExprIterator.
+//===----------------------------------------------------------------------===//
+
+Expr* ExprIterator::operator[](size_t idx) { return cast<Expr>(I[idx]); }
+Expr* ExprIterator::operator*() const { return cast<Expr>(*I); }
+Expr* ExprIterator::operator->() const { return cast<Expr>(*I); }
+const Expr* ConstExprIterator::operator[](size_t idx) const {
+  return cast<Expr>(I[idx]);
+}
+const Expr* ConstExprIterator::operator*() const { return cast<Expr>(*I); }
+const Expr* ConstExprIterator::operator->() const { return cast<Expr>(*I); }
+
+//===----------------------------------------------------------------------===//
+//  Child Iterators for iterating over subexpressions/substatements
+//===----------------------------------------------------------------------===//
+
+// DeclRefExpr
+Stmt::child_iterator DeclRefExpr::child_begin() { return child_iterator(); }
+Stmt::child_iterator DeclRefExpr::child_end() { return child_iterator(); }
+
+// ObjCIvarRefExpr
+Stmt::child_iterator ObjCIvarRefExpr::child_begin() { return &Base; }
+Stmt::child_iterator ObjCIvarRefExpr::child_end() { return &Base+1; }
+
+// ObjCPropertyRefExpr
+Stmt::child_iterator ObjCPropertyRefExpr::child_begin() { return &Base; }
+Stmt::child_iterator ObjCPropertyRefExpr::child_end() { return &Base+1; }
+
+// ObjCImplicitSetterGetterRefExpr
+Stmt::child_iterator ObjCImplicitSetterGetterRefExpr::child_begin() {
+  return &Base;
+}
+Stmt::child_iterator ObjCImplicitSetterGetterRefExpr::child_end() {
+  return &Base+1;
+}
+
+// ObjCSuperExpr
+Stmt::child_iterator ObjCSuperExpr::child_begin() { return child_iterator(); }
+Stmt::child_iterator ObjCSuperExpr::child_end() { return child_iterator(); }
+
+// ObjCIsaExpr
+Stmt::child_iterator ObjCIsaExpr::child_begin() { return &Base; }
+Stmt::child_iterator ObjCIsaExpr::child_end() { return &Base+1; }
+
+// PredefinedExpr
+Stmt::child_iterator PredefinedExpr::child_begin() { return child_iterator(); }
+Stmt::child_iterator PredefinedExpr::child_end() { return child_iterator(); }
+
+// IntegerLiteral
+Stmt::child_iterator IntegerLiteral::child_begin() { return child_iterator(); }
+Stmt::child_iterator IntegerLiteral::child_end() { return child_iterator(); }
+
+// CharacterLiteral
+Stmt::child_iterator CharacterLiteral::child_begin() { return child_iterator();}
+Stmt::child_iterator CharacterLiteral::child_end() { return child_iterator(); }
+
+// FloatingLiteral
+Stmt::child_iterator FloatingLiteral::child_begin() { return child_iterator(); }
+Stmt::child_iterator FloatingLiteral::child_end() { return child_iterator(); }
+
+// ImaginaryLiteral
+Stmt::child_iterator ImaginaryLiteral::child_begin() { return &Val; }
+Stmt::child_iterator ImaginaryLiteral::child_end() { return &Val+1; }
+
+// StringLiteral
+Stmt::child_iterator StringLiteral::child_begin() { return child_iterator(); }
+Stmt::child_iterator StringLiteral::child_end() { return child_iterator(); }
+
+// ParenExpr
+Stmt::child_iterator ParenExpr::child_begin() { return &Val; }
+Stmt::child_iterator ParenExpr::child_end() { return &Val+1; }
+
+// UnaryOperator
+Stmt::child_iterator UnaryOperator::child_begin() { return &Val; }
+Stmt::child_iterator UnaryOperator::child_end() { return &Val+1; }
+
+// SizeOfAlignOfExpr
+Stmt::child_iterator SizeOfAlignOfExpr::child_begin() {
+  // If this is of a type and the type is a VLA type (and not a typedef), the
+  // size expression of the VLA needs to be treated as an executable expression.
+  // Why isn't this weirdness documented better in StmtIterator?
+  if (isArgumentType()) {
+    if (VariableArrayType* T = dyn_cast<VariableArrayType>(
+                                   getArgumentType().getTypePtr()))
+      return child_iterator(T);
+    return child_iterator();
+  }
+  return child_iterator(&Argument.Ex);
+}
+Stmt::child_iterator SizeOfAlignOfExpr::child_end() {
+  if (isArgumentType())
+    return child_iterator();
+  return child_iterator(&Argument.Ex + 1);
+}
+
+// ArraySubscriptExpr
+Stmt::child_iterator ArraySubscriptExpr::child_begin() {
+  return &SubExprs[0];
+}
+Stmt::child_iterator ArraySubscriptExpr::child_end() {
+  return &SubExprs[0]+END_EXPR;
+}
+
+// CallExpr
+Stmt::child_iterator CallExpr::child_begin() {
+  return &SubExprs[0];
+}
+Stmt::child_iterator CallExpr::child_end() {
+  return &SubExprs[0]+NumArgs+ARGS_START;
+}
+
+// MemberExpr
+Stmt::child_iterator MemberExpr::child_begin() { return &Base; }
+Stmt::child_iterator MemberExpr::child_end() { return &Base+1; }
+
+// ExtVectorElementExpr
+Stmt::child_iterator ExtVectorElementExpr::child_begin() { return &Base; }
+Stmt::child_iterator ExtVectorElementExpr::child_end() { return &Base+1; }
+
+// CompoundLiteralExpr
+Stmt::child_iterator CompoundLiteralExpr::child_begin() { return &Init; }
+Stmt::child_iterator CompoundLiteralExpr::child_end() { return &Init+1; }
+
+// CastExpr
+Stmt::child_iterator CastExpr::child_begin() { return &Op; }
+Stmt::child_iterator CastExpr::child_end() { return &Op+1; }
+
+// BinaryOperator
+Stmt::child_iterator BinaryOperator::child_begin() {
+  return &SubExprs[0];
+}
+Stmt::child_iterator BinaryOperator::child_end() {
+  return &SubExprs[0]+END_EXPR;
+}
+
+// ConditionalOperator
+Stmt::child_iterator ConditionalOperator::child_begin() {
+  return &SubExprs[0];
+}
+Stmt::child_iterator ConditionalOperator::child_end() {
+  return &SubExprs[0]+END_EXPR;
+}
+
+// AddrLabelExpr
+Stmt::child_iterator AddrLabelExpr::child_begin() { return child_iterator(); }
+Stmt::child_iterator AddrLabelExpr::child_end() { return child_iterator(); }
+
+// StmtExpr
+Stmt::child_iterator StmtExpr::child_begin() { return &SubStmt; }
+Stmt::child_iterator StmtExpr::child_end() { return &SubStmt+1; }
+
+// TypesCompatibleExpr
+Stmt::child_iterator TypesCompatibleExpr::child_begin() {
+  return child_iterator();
+}
+
+Stmt::child_iterator TypesCompatibleExpr::child_end() {
+  return child_iterator();
+}
+
+// ChooseExpr
+Stmt::child_iterator ChooseExpr::child_begin() { return &SubExprs[0]; }
+Stmt::child_iterator ChooseExpr::child_end() { return &SubExprs[0]+END_EXPR; }
+
+// GNUNullExpr
+Stmt::child_iterator GNUNullExpr::child_begin() { return child_iterator(); }
+Stmt::child_iterator GNUNullExpr::child_end() { return child_iterator(); }
+
+// ShuffleVectorExpr
+Stmt::child_iterator ShuffleVectorExpr::child_begin() {
+  return &SubExprs[0];
+}
+Stmt::child_iterator ShuffleVectorExpr::child_end() {
+  return &SubExprs[0]+NumExprs;
+}
+
+// VAArgExpr
+Stmt::child_iterator VAArgExpr::child_begin() { return &Val; }
+Stmt::child_iterator VAArgExpr::child_end() { return &Val+1; }
+
+// InitListExpr
+Stmt::child_iterator InitListExpr::child_begin() {
+  return InitExprs.size() ? &InitExprs[0] : 0;
+}
+Stmt::child_iterator InitListExpr::child_end() {
+  return InitExprs.size() ? &InitExprs[0] + InitExprs.size() : 0;
+}
+
+// DesignatedInitExpr
+Stmt::child_iterator DesignatedInitExpr::child_begin() {
+  char* Ptr = static_cast<char*>(static_cast<void *>(this));
+  Ptr += sizeof(DesignatedInitExpr);
+  return reinterpret_cast<Stmt**>(reinterpret_cast<void**>(Ptr));
+}
+Stmt::child_iterator DesignatedInitExpr::child_end() {
+  return child_iterator(&*child_begin() + NumSubExprs);
+}
+
+// ImplicitValueInitExpr
+Stmt::child_iterator ImplicitValueInitExpr::child_begin() {
+  return child_iterator();
+}
+
+Stmt::child_iterator ImplicitValueInitExpr::child_end() {
+  return child_iterator();
+}
+
+// ParenListExpr
+Stmt::child_iterator ParenListExpr::child_begin() {
+  return &Exprs[0];
+}
+Stmt::child_iterator ParenListExpr::child_end() {
+  return &Exprs[0]+NumExprs;
+}
+
+// ObjCStringLiteral
+Stmt::child_iterator ObjCStringLiteral::child_begin() {
+  return &String;
+}
+Stmt::child_iterator ObjCStringLiteral::child_end() {
+  return &String+1;
+}
+
+// ObjCEncodeExpr
+Stmt::child_iterator ObjCEncodeExpr::child_begin() { return child_iterator(); }
+Stmt::child_iterator ObjCEncodeExpr::child_end() { return child_iterator(); }
+
+// ObjCSelectorExpr
+Stmt::child_iterator ObjCSelectorExpr::child_begin() {
+  return child_iterator();
+}
+Stmt::child_iterator ObjCSelectorExpr::child_end() {
+  return child_iterator();
+}
+
+// ObjCProtocolExpr
+Stmt::child_iterator ObjCProtocolExpr::child_begin() {
+  return child_iterator();
+}
+Stmt::child_iterator ObjCProtocolExpr::child_end() {
+  return child_iterator();
+}
+
+// ObjCMessageExpr
+Stmt::child_iterator ObjCMessageExpr::child_begin() {
+  if (getReceiverKind() == Instance)
+    return reinterpret_cast<Stmt **>(this + 1);
+  return getArgs();
+}
+Stmt::child_iterator ObjCMessageExpr::child_end() {
+  return getArgs() + getNumArgs();
+}
+
+// Blocks
+Stmt::child_iterator BlockExpr::child_begin() { return child_iterator(); }
+Stmt::child_iterator BlockExpr::child_end() { return child_iterator(); }
+
+Stmt::child_iterator BlockDeclRefExpr::child_begin() { return child_iterator();}
+Stmt::child_iterator BlockDeclRefExpr::child_end() { return child_iterator(); }
diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp
new file mode 100644
index 0000000..5f90809
--- /dev/null
+++ b/lib/AST/ExprCXX.cpp
@@ -0,0 +1,762 @@
+//===--- ExprCXX.cpp - (C++) Expression AST Node Implementation -----------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the subclesses of Expr class declared in ExprCXX.h
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/TypeLoc.h"
+using namespace clang;
+
+
+//===----------------------------------------------------------------------===//
+//  Child Iterators for iterating over subexpressions/substatements
+//===----------------------------------------------------------------------===//
+
+QualType CXXTypeidExpr::getTypeOperand() const {
+  assert(isTypeOperand() && "Cannot call getTypeOperand for typeid(expr)");
+  return Operand.get<TypeSourceInfo *>()->getType().getNonReferenceType()
+                                                        .getUnqualifiedType();
+}
+
+// CXXTypeidExpr - has child iterators if the operand is an expression
+Stmt::child_iterator CXXTypeidExpr::child_begin() {
+  return isTypeOperand() ? child_iterator() 
+                         : reinterpret_cast<Stmt **>(&Operand);
+}
+Stmt::child_iterator CXXTypeidExpr::child_end() {
+  return isTypeOperand() ? child_iterator() 
+                         : reinterpret_cast<Stmt **>(&Operand) + 1;
+}
+
+// CXXBoolLiteralExpr
+Stmt::child_iterator CXXBoolLiteralExpr::child_begin() {
+  return child_iterator();
+}
+Stmt::child_iterator CXXBoolLiteralExpr::child_end() {
+  return child_iterator();
+}
+
+// CXXNullPtrLiteralExpr
+Stmt::child_iterator CXXNullPtrLiteralExpr::child_begin() {
+  return child_iterator();
+}
+Stmt::child_iterator CXXNullPtrLiteralExpr::child_end() {
+  return child_iterator();
+}
+
+// CXXThisExpr
+Stmt::child_iterator CXXThisExpr::child_begin() { return child_iterator(); }
+Stmt::child_iterator CXXThisExpr::child_end() { return child_iterator(); }
+
+// CXXThrowExpr
+Stmt::child_iterator CXXThrowExpr::child_begin() { return &Op; }
+Stmt::child_iterator CXXThrowExpr::child_end() {
+  // If Op is 0, we are processing throw; which has no children.
+  return Op ? &Op+1 : &Op;
+}
+
+// CXXDefaultArgExpr
+Stmt::child_iterator CXXDefaultArgExpr::child_begin() {
+  return child_iterator();
+}
+Stmt::child_iterator CXXDefaultArgExpr::child_end() {
+  return child_iterator();
+}
+
+// CXXZeroInitValueExpr
+Stmt::child_iterator CXXZeroInitValueExpr::child_begin() {
+  return child_iterator();
+}
+Stmt::child_iterator CXXZeroInitValueExpr::child_end() {
+  return child_iterator();
+}
+
+// CXXNewExpr
+CXXNewExpr::CXXNewExpr(ASTContext &C, bool globalNew, FunctionDecl *operatorNew,
+                       Expr **placementArgs, unsigned numPlaceArgs,
+                       bool parenTypeId, Expr *arraySize,
+                       CXXConstructorDecl *constructor, bool initializer,
+                       Expr **constructorArgs, unsigned numConsArgs,
+                       FunctionDecl *operatorDelete, QualType ty,
+                       SourceLocation startLoc, SourceLocation endLoc)
+  : Expr(CXXNewExprClass, ty, ty->isDependentType(), ty->isDependentType()),
+    GlobalNew(globalNew), ParenTypeId(parenTypeId),
+    Initializer(initializer), Array(arraySize), NumPlacementArgs(numPlaceArgs),
+    NumConstructorArgs(numConsArgs), OperatorNew(operatorNew),
+    OperatorDelete(operatorDelete), Constructor(constructor),
+    StartLoc(startLoc), EndLoc(endLoc) {
+  unsigned TotalSize = Array + NumPlacementArgs + NumConstructorArgs;
+  SubExprs = new (C) Stmt*[TotalSize];
+  unsigned i = 0;
+  if (Array)
+    SubExprs[i++] = arraySize;
+  for (unsigned j = 0; j < NumPlacementArgs; ++j)
+    SubExprs[i++] = placementArgs[j];
+  for (unsigned j = 0; j < NumConstructorArgs; ++j)
+    SubExprs[i++] = constructorArgs[j];
+  assert(i == TotalSize);
+}
+
+void CXXNewExpr::DoDestroy(ASTContext &C) {
+  DestroyChildren(C);
+  if (SubExprs)
+    C.Deallocate(SubExprs);
+  this->~CXXNewExpr();
+  C.Deallocate((void*)this);
+}
+
+Stmt::child_iterator CXXNewExpr::child_begin() { return &SubExprs[0]; }
+Stmt::child_iterator CXXNewExpr::child_end() {
+  return &SubExprs[0] + Array + getNumPlacementArgs() + getNumConstructorArgs();
+}
+
+// CXXDeleteExpr
+Stmt::child_iterator CXXDeleteExpr::child_begin() { return &Argument; }
+Stmt::child_iterator CXXDeleteExpr::child_end() { return &Argument+1; }
+
+// CXXPseudoDestructorExpr
+Stmt::child_iterator CXXPseudoDestructorExpr::child_begin() { return &Base; }
+Stmt::child_iterator CXXPseudoDestructorExpr::child_end() {
+  return &Base + 1;
+}
+
+PseudoDestructorTypeStorage::PseudoDestructorTypeStorage(TypeSourceInfo *Info)
+ : Type(Info) 
+{
+  Location = Info->getTypeLoc().getSourceRange().getBegin();
+}
+
+QualType CXXPseudoDestructorExpr::getDestroyedType() const {
+  if (TypeSourceInfo *TInfo = DestroyedType.getTypeSourceInfo())
+    return TInfo->getType();
+  
+  return QualType();
+}
+
+SourceRange CXXPseudoDestructorExpr::getSourceRange() const {
+  SourceLocation End = DestroyedType.getLocation();
+  if (TypeSourceInfo *TInfo = DestroyedType.getTypeSourceInfo())
+    End = TInfo->getTypeLoc().getSourceRange().getEnd();
+  return SourceRange(Base->getLocStart(), End);
+}
+
+
+// UnresolvedLookupExpr
+UnresolvedLookupExpr *
+UnresolvedLookupExpr::Create(ASTContext &C, bool Dependent,
+                             CXXRecordDecl *NamingClass,
+                             NestedNameSpecifier *Qualifier,
+                             SourceRange QualifierRange, DeclarationName Name,
+                             SourceLocation NameLoc, bool ADL,
+                             const TemplateArgumentListInfo &Args) 
+{
+  void *Mem = C.Allocate(sizeof(UnresolvedLookupExpr) + 
+                         ExplicitTemplateArgumentList::sizeFor(Args));
+  UnresolvedLookupExpr *ULE
+    = new (Mem) UnresolvedLookupExpr(Dependent ? C.DependentTy : C.OverloadTy,
+                                     Dependent, NamingClass,
+                                     Qualifier, QualifierRange,
+                                     Name, NameLoc, ADL,
+                                     /*Overload*/ true,
+                                     /*ExplicitTemplateArgs*/ true);
+
+  reinterpret_cast<ExplicitTemplateArgumentList*>(ULE+1)->initializeFrom(Args);
+
+  return ULE;
+}
+
+bool OverloadExpr::ComputeDependence(UnresolvedSetIterator Begin,
+                                     UnresolvedSetIterator End,
+                                     const TemplateArgumentListInfo *Args) {
+  for (UnresolvedSetImpl::const_iterator I = Begin; I != End; ++I)
+    if ((*I)->getDeclContext()->isDependentContext())
+      return true;
+
+  if (Args && TemplateSpecializationType::anyDependentTemplateArguments(*Args))
+    return true;
+
+  return false;
+}
+
+CXXRecordDecl *OverloadExpr::getNamingClass() const {
+  if (isa<UnresolvedLookupExpr>(this))
+    return cast<UnresolvedLookupExpr>(this)->getNamingClass();
+  else
+    return cast<UnresolvedMemberExpr>(this)->getNamingClass();
+}
+
+Stmt::child_iterator UnresolvedLookupExpr::child_begin() {
+  return child_iterator();
+}
+Stmt::child_iterator UnresolvedLookupExpr::child_end() {
+  return child_iterator();
+}
+// UnaryTypeTraitExpr
+Stmt::child_iterator UnaryTypeTraitExpr::child_begin() {
+  return child_iterator();
+}
+Stmt::child_iterator UnaryTypeTraitExpr::child_end() {
+  return child_iterator();
+}
+
+// DependentScopeDeclRefExpr
+DependentScopeDeclRefExpr *
+DependentScopeDeclRefExpr::Create(ASTContext &C,
+                                  NestedNameSpecifier *Qualifier,
+                                  SourceRange QualifierRange,
+                                  DeclarationName Name,
+                                  SourceLocation NameLoc,
+                                  const TemplateArgumentListInfo *Args) {
+  std::size_t size = sizeof(DependentScopeDeclRefExpr);
+  if (Args) size += ExplicitTemplateArgumentList::sizeFor(*Args);
+  void *Mem = C.Allocate(size);
+
+  DependentScopeDeclRefExpr *DRE
+    = new (Mem) DependentScopeDeclRefExpr(C.DependentTy,
+                                          Qualifier, QualifierRange,
+                                          Name, NameLoc,
+                                          Args != 0);
+
+  if (Args)
+    reinterpret_cast<ExplicitTemplateArgumentList*>(DRE+1)
+      ->initializeFrom(*Args);
+
+  return DRE;
+}
+
+StmtIterator DependentScopeDeclRefExpr::child_begin() {
+  return child_iterator();
+}
+
+StmtIterator DependentScopeDeclRefExpr::child_end() {
+  return child_iterator();
+}
+
+bool UnaryTypeTraitExpr::EvaluateTrait(ASTContext& C) const {
+  switch(UTT) {
+  default: assert(false && "Unknown type trait or not implemented");
+  case UTT_IsPOD: return QueriedType->isPODType();
+  case UTT_IsLiteral: return QueriedType->isLiteralType();
+  case UTT_IsClass: // Fallthrough
+  case UTT_IsUnion:
+    if (const RecordType *Record = QueriedType->getAs<RecordType>()) {
+      bool Union = Record->getDecl()->isUnion();
+      return UTT == UTT_IsUnion ? Union : !Union;
+    }
+    return false;
+  case UTT_IsEnum: return QueriedType->isEnumeralType();
+  case UTT_IsPolymorphic:
+    if (const RecordType *Record = QueriedType->getAs<RecordType>()) {
+      // Type traits are only parsed in C++, so we've got CXXRecords.
+      return cast<CXXRecordDecl>(Record->getDecl())->isPolymorphic();
+    }
+    return false;
+  case UTT_IsAbstract:
+    if (const RecordType *RT = QueriedType->getAs<RecordType>())
+      return cast<CXXRecordDecl>(RT->getDecl())->isAbstract();
+    return false;
+  case UTT_IsEmpty:
+    if (const RecordType *Record = QueriedType->getAs<RecordType>()) {
+      return !Record->getDecl()->isUnion()
+          && cast<CXXRecordDecl>(Record->getDecl())->isEmpty();
+    }
+    return false;
+  case UTT_HasTrivialConstructor:
+    // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
+    //   If __is_pod (type) is true then the trait is true, else if type is
+    //   a cv class or union type (or array thereof) with a trivial default
+    //   constructor ([class.ctor]) then the trait is true, else it is false.
+    if (QueriedType->isPODType())
+      return true;
+    if (const RecordType *RT =
+          C.getBaseElementType(QueriedType)->getAs<RecordType>())
+      return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialConstructor();
+    return false;
+  case UTT_HasTrivialCopy:
+    // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
+    //   If __is_pod (type) is true or type is a reference type then
+    //   the trait is true, else if type is a cv class or union type
+    //   with a trivial copy constructor ([class.copy]) then the trait
+    //   is true, else it is false.
+    if (QueriedType->isPODType() || QueriedType->isReferenceType())
+      return true;
+    if (const RecordType *RT = QueriedType->getAs<RecordType>())
+      return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialCopyConstructor();
+    return false;
+  case UTT_HasTrivialAssign:
+    // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
+    //   If type is const qualified or is a reference type then the
+    //   trait is false. Otherwise if __is_pod (type) is true then the
+    //   trait is true, else if type is a cv class or union type with
+    //   a trivial copy assignment ([class.copy]) then the trait is
+    //   true, else it is false.
+    // Note: the const and reference restrictions are interesting,
+    // given that const and reference members don't prevent a class
+    // from having a trivial copy assignment operator (but do cause
+    // errors if the copy assignment operator is actually used, q.v.
+    // [class.copy]p12).
+
+    if (C.getBaseElementType(QueriedType).isConstQualified())
+      return false;
+    if (QueriedType->isPODType())
+      return true;
+    if (const RecordType *RT = QueriedType->getAs<RecordType>())
+      return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialCopyAssignment();
+    return false;
+  case UTT_HasTrivialDestructor:
+    // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
+    //   If __is_pod (type) is true or type is a reference type
+    //   then the trait is true, else if type is a cv class or union
+    //   type (or array thereof) with a trivial destructor
+    //   ([class.dtor]) then the trait is true, else it is
+    //   false.
+    if (QueriedType->isPODType() || QueriedType->isReferenceType())
+      return true;
+    if (const RecordType *RT =
+          C.getBaseElementType(QueriedType)->getAs<RecordType>())
+      return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialDestructor();
+    return false;
+  }
+}
+
+SourceRange CXXConstructExpr::getSourceRange() const { 
+  // FIXME: Should we know where the parentheses are, if there are any?
+  for (std::reverse_iterator<Stmt**> I(&Args[NumArgs]), E(&Args[0]); I!=E;++I) {
+    // Ignore CXXDefaultExprs when computing the range, as they don't
+    // have a range.
+    if (!isa<CXXDefaultArgExpr>(*I))
+      return SourceRange(Loc, (*I)->getLocEnd());
+  }
+  
+  return SourceRange(Loc);
+}
+
+SourceRange CXXOperatorCallExpr::getSourceRange() const {
+  OverloadedOperatorKind Kind = getOperator();
+  if (Kind == OO_PlusPlus || Kind == OO_MinusMinus) {
+    if (getNumArgs() == 1)
+      // Prefix operator
+      return SourceRange(getOperatorLoc(),
+                         getArg(0)->getSourceRange().getEnd());
+    else
+      // Postfix operator
+      return SourceRange(getArg(0)->getSourceRange().getEnd(),
+                         getOperatorLoc());
+  } else if (Kind == OO_Call) {
+    return SourceRange(getArg(0)->getSourceRange().getBegin(), getRParenLoc());
+  } else if (Kind == OO_Subscript) {
+    return SourceRange(getArg(0)->getSourceRange().getBegin(), getRParenLoc());
+  } else if (getNumArgs() == 1) {
+    return SourceRange(getOperatorLoc(), getArg(0)->getSourceRange().getEnd());
+  } else if (getNumArgs() == 2) {
+    return SourceRange(getArg(0)->getSourceRange().getBegin(),
+                       getArg(1)->getSourceRange().getEnd());
+  } else {
+    return SourceRange();
+  }
+}
+
+Expr *CXXMemberCallExpr::getImplicitObjectArgument() {
+  if (MemberExpr *MemExpr = dyn_cast<MemberExpr>(getCallee()->IgnoreParens()))
+    return MemExpr->getBase();
+
+  // FIXME: Will eventually need to cope with member pointers.
+  return 0;
+}
+
+SourceRange CXXMemberCallExpr::getSourceRange() const {
+  SourceLocation LocStart = getCallee()->getLocStart();
+  if (LocStart.isInvalid() && getNumArgs() > 0)
+    LocStart = getArg(0)->getLocStart();
+  return SourceRange(LocStart, getRParenLoc());
+}
+
+
+//===----------------------------------------------------------------------===//
+//  Named casts
+//===----------------------------------------------------------------------===//
+
+/// getCastName - Get the name of the C++ cast being used, e.g.,
+/// "static_cast", "dynamic_cast", "reinterpret_cast", or
+/// "const_cast". The returned pointer must not be freed.
+const char *CXXNamedCastExpr::getCastName() const {
+  switch (getStmtClass()) {
+  case CXXStaticCastExprClass:      return "static_cast";
+  case CXXDynamicCastExprClass:     return "dynamic_cast";
+  case CXXReinterpretCastExprClass: return "reinterpret_cast";
+  case CXXConstCastExprClass:       return "const_cast";
+  default:                          return "<invalid cast>";
+  }
+}
+
+CXXDefaultArgExpr *
+CXXDefaultArgExpr::Create(ASTContext &C, SourceLocation Loc, 
+                          ParmVarDecl *Param, Expr *SubExpr) {
+  void *Mem = C.Allocate(sizeof(CXXDefaultArgExpr) + sizeof(Stmt *));
+  return new (Mem) CXXDefaultArgExpr(CXXDefaultArgExprClass, Loc, Param, 
+                                     SubExpr);
+}
+
+void CXXDefaultArgExpr::DoDestroy(ASTContext &C) {
+  if (Param.getInt())
+    getExpr()->Destroy(C);
+  this->~CXXDefaultArgExpr();
+  C.Deallocate(this);
+}
+
+CXXTemporary *CXXTemporary::Create(ASTContext &C,
+                                   const CXXDestructorDecl *Destructor) {
+  return new (C) CXXTemporary(Destructor);
+}
+
+void CXXTemporary::Destroy(ASTContext &Ctx) {
+  this->~CXXTemporary();
+  Ctx.Deallocate(this);
+}
+
+CXXBindTemporaryExpr *CXXBindTemporaryExpr::Create(ASTContext &C,
+                                                   CXXTemporary *Temp,
+                                                   Expr* SubExpr) {
+  assert(SubExpr->getType()->isRecordType() &&
+         "Expression bound to a temporary must have record type!");
+
+  return new (C) CXXBindTemporaryExpr(Temp, SubExpr);
+}
+
+void CXXBindTemporaryExpr::DoDestroy(ASTContext &C) {
+  Temp->Destroy(C);
+  this->~CXXBindTemporaryExpr();
+  C.Deallocate(this);
+}
+
+CXXBindReferenceExpr *CXXBindReferenceExpr::Create(ASTContext &C, Expr *SubExpr,
+                                                   bool ExtendsLifetime, 
+                                                   bool RequiresTemporaryCopy) {
+  return new (C) CXXBindReferenceExpr(SubExpr, 
+                                      ExtendsLifetime,
+                                      RequiresTemporaryCopy);
+}
+
+void CXXBindReferenceExpr::DoDestroy(ASTContext &C) {
+  this->~CXXBindReferenceExpr();
+  C.Deallocate(this);
+}
+
+CXXTemporaryObjectExpr::CXXTemporaryObjectExpr(ASTContext &C,
+                                               CXXConstructorDecl *Cons,
+                                               QualType writtenTy,
+                                               SourceLocation tyBeginLoc,
+                                               Expr **Args,
+                                               unsigned NumArgs,
+                                               SourceLocation rParenLoc)
+  : CXXConstructExpr(C, CXXTemporaryObjectExprClass, writtenTy, tyBeginLoc,
+                     Cons, false, Args, NumArgs),
+  TyBeginLoc(tyBeginLoc), RParenLoc(rParenLoc) {
+}
+
+CXXConstructExpr *CXXConstructExpr::Create(ASTContext &C, QualType T,
+                                           SourceLocation Loc,
+                                           CXXConstructorDecl *D, bool Elidable,
+                                           Expr **Args, unsigned NumArgs,
+                                           bool ZeroInitialization,
+                                           bool BaseInitialization) {
+  return new (C) CXXConstructExpr(C, CXXConstructExprClass, T, Loc, D, 
+                                  Elidable, Args, NumArgs, ZeroInitialization,
+                                  BaseInitialization);
+}
+
+CXXConstructExpr::CXXConstructExpr(ASTContext &C, StmtClass SC, QualType T,
+                                   SourceLocation Loc,
+                                   CXXConstructorDecl *D, bool elidable,
+                                   Expr **args, unsigned numargs,
+                                   bool ZeroInitialization,
+                                   bool BaseInitialization)
+: Expr(SC, T,
+       T->isDependentType(),
+       (T->isDependentType() ||
+        CallExpr::hasAnyValueDependentArguments(args, numargs))),
+  Constructor(D), Loc(Loc), Elidable(elidable), 
+  ZeroInitialization(ZeroInitialization), 
+  BaseInitialization(BaseInitialization), Args(0), NumArgs(numargs) 
+{
+  if (NumArgs) {
+    Args = new (C) Stmt*[NumArgs];
+    
+    for (unsigned i = 0; i != NumArgs; ++i) {
+      assert(args[i] && "NULL argument in CXXConstructExpr");
+      Args[i] = args[i];
+    }
+  }
+}
+
+CXXConstructExpr::CXXConstructExpr(EmptyShell Empty, ASTContext &C, 
+                                   unsigned numargs)
+  : Expr(CXXConstructExprClass, Empty), Args(0), NumArgs(numargs) 
+{
+  if (NumArgs)
+    Args = new (C) Stmt*[NumArgs];
+}
+
+void CXXConstructExpr::DoDestroy(ASTContext &C) {
+  DestroyChildren(C);
+  if (Args)
+    C.Deallocate(Args);
+  this->~CXXConstructExpr();
+  C.Deallocate(this);
+}
+
+CXXExprWithTemporaries::CXXExprWithTemporaries(Expr *subexpr,
+                                               CXXTemporary **temps,
+                                               unsigned numtemps)
+: Expr(CXXExprWithTemporariesClass, subexpr->getType(),
+       subexpr->isTypeDependent(), subexpr->isValueDependent()),
+  SubExpr(subexpr), Temps(0), NumTemps(numtemps) {
+  if (NumTemps > 0) {
+    Temps = new CXXTemporary*[NumTemps];
+    for (unsigned i = 0; i < NumTemps; ++i)
+      Temps[i] = temps[i];
+  }
+}
+
+CXXExprWithTemporaries *CXXExprWithTemporaries::Create(ASTContext &C,
+                                                       Expr *SubExpr,
+                                                       CXXTemporary **Temps,
+                                                       unsigned NumTemps) {
+  return new (C) CXXExprWithTemporaries(SubExpr, Temps, NumTemps);
+}
+
+void CXXExprWithTemporaries::DoDestroy(ASTContext &C) {
+  DestroyChildren(C);
+  this->~CXXExprWithTemporaries();
+  C.Deallocate(this);
+}
+
+CXXExprWithTemporaries::~CXXExprWithTemporaries() {
+  delete[] Temps;
+}
+
+// CXXBindTemporaryExpr
+Stmt::child_iterator CXXBindTemporaryExpr::child_begin() {
+  return &SubExpr;
+}
+
+Stmt::child_iterator CXXBindTemporaryExpr::child_end() {
+  return &SubExpr + 1;
+}
+
+// CXXBindReferenceExpr
+Stmt::child_iterator CXXBindReferenceExpr::child_begin() {
+  return &SubExpr;
+}
+
+Stmt::child_iterator CXXBindReferenceExpr::child_end() {
+  return &SubExpr + 1;
+}
+
+// CXXConstructExpr
+Stmt::child_iterator CXXConstructExpr::child_begin() {
+  return &Args[0];
+}
+Stmt::child_iterator CXXConstructExpr::child_end() {
+  return &Args[0]+NumArgs;
+}
+
+// CXXExprWithTemporaries
+Stmt::child_iterator CXXExprWithTemporaries::child_begin() {
+  return &SubExpr;
+}
+
+Stmt::child_iterator CXXExprWithTemporaries::child_end() {
+  return &SubExpr + 1;
+}
+
+CXXUnresolvedConstructExpr::CXXUnresolvedConstructExpr(
+                                                 SourceLocation TyBeginLoc,
+                                                 QualType T,
+                                                 SourceLocation LParenLoc,
+                                                 Expr **Args,
+                                                 unsigned NumArgs,
+                                                 SourceLocation RParenLoc)
+  : Expr(CXXUnresolvedConstructExprClass, T.getNonReferenceType(),
+         T->isDependentType(), true),
+    TyBeginLoc(TyBeginLoc),
+    Type(T),
+    LParenLoc(LParenLoc),
+    RParenLoc(RParenLoc),
+    NumArgs(NumArgs) {
+  Stmt **StoredArgs = reinterpret_cast<Stmt **>(this + 1);
+  memcpy(StoredArgs, Args, sizeof(Expr *) * NumArgs);
+}
+
+CXXUnresolvedConstructExpr *
+CXXUnresolvedConstructExpr::Create(ASTContext &C,
+                                   SourceLocation TyBegin,
+                                   QualType T,
+                                   SourceLocation LParenLoc,
+                                   Expr **Args,
+                                   unsigned NumArgs,
+                                   SourceLocation RParenLoc) {
+  void *Mem = C.Allocate(sizeof(CXXUnresolvedConstructExpr) +
+                         sizeof(Expr *) * NumArgs);
+  return new (Mem) CXXUnresolvedConstructExpr(TyBegin, T, LParenLoc,
+                                              Args, NumArgs, RParenLoc);
+}
+
+Stmt::child_iterator CXXUnresolvedConstructExpr::child_begin() {
+  return child_iterator(reinterpret_cast<Stmt **>(this + 1));
+}
+
+Stmt::child_iterator CXXUnresolvedConstructExpr::child_end() {
+  return child_iterator(reinterpret_cast<Stmt **>(this + 1) + NumArgs);
+}
+
+CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr(ASTContext &C,
+                                                 Expr *Base, QualType BaseType,
+                                                 bool IsArrow,
+                                                 SourceLocation OperatorLoc,
+                                                 NestedNameSpecifier *Qualifier,
+                                                 SourceRange QualifierRange,
+                                          NamedDecl *FirstQualifierFoundInScope,
+                                                 DeclarationName Member,
+                                                 SourceLocation MemberLoc,
+                                   const TemplateArgumentListInfo *TemplateArgs)
+  : Expr(CXXDependentScopeMemberExprClass, C.DependentTy, true, true),
+    Base(Base), BaseType(BaseType), IsArrow(IsArrow),
+    HasExplicitTemplateArgs(TemplateArgs != 0),
+    OperatorLoc(OperatorLoc),
+    Qualifier(Qualifier), QualifierRange(QualifierRange),
+    FirstQualifierFoundInScope(FirstQualifierFoundInScope),
+    Member(Member), MemberLoc(MemberLoc) {
+  if (TemplateArgs)
+    getExplicitTemplateArgumentList()->initializeFrom(*TemplateArgs);
+}
+
+CXXDependentScopeMemberExpr *
+CXXDependentScopeMemberExpr::Create(ASTContext &C,
+                                Expr *Base, QualType BaseType, bool IsArrow,
+                                SourceLocation OperatorLoc,
+                                NestedNameSpecifier *Qualifier,
+                                SourceRange QualifierRange,
+                                NamedDecl *FirstQualifierFoundInScope,
+                                DeclarationName Member,
+                                SourceLocation MemberLoc,
+                                const TemplateArgumentListInfo *TemplateArgs) {
+  if (!TemplateArgs)
+    return new (C) CXXDependentScopeMemberExpr(C, Base, BaseType,
+                                               IsArrow, OperatorLoc,
+                                               Qualifier, QualifierRange,
+                                               FirstQualifierFoundInScope,
+                                               Member, MemberLoc);
+
+  std::size_t size = sizeof(CXXDependentScopeMemberExpr);
+  if (TemplateArgs)
+    size += ExplicitTemplateArgumentList::sizeFor(*TemplateArgs);
+
+  void *Mem = C.Allocate(size, llvm::alignof<CXXDependentScopeMemberExpr>());
+  return new (Mem) CXXDependentScopeMemberExpr(C, Base, BaseType,
+                                               IsArrow, OperatorLoc,
+                                               Qualifier, QualifierRange,
+                                               FirstQualifierFoundInScope,
+                                               Member, MemberLoc, TemplateArgs);
+}
+
+Stmt::child_iterator CXXDependentScopeMemberExpr::child_begin() {
+  return child_iterator(&Base);
+}
+
+Stmt::child_iterator CXXDependentScopeMemberExpr::child_end() {
+  if (isImplicitAccess())
+    return child_iterator(&Base);
+  return child_iterator(&Base + 1);
+}
+
+UnresolvedMemberExpr::UnresolvedMemberExpr(QualType T, bool Dependent,
+                                           bool HasUnresolvedUsing,
+                                           Expr *Base, QualType BaseType,
+                                           bool IsArrow,
+                                           SourceLocation OperatorLoc,
+                                           NestedNameSpecifier *Qualifier,
+                                           SourceRange QualifierRange,
+                                           DeclarationName MemberName,
+                                           SourceLocation MemberLoc,
+                                   const TemplateArgumentListInfo *TemplateArgs)
+  : OverloadExpr(UnresolvedMemberExprClass, T, Dependent,
+                 Qualifier, QualifierRange, MemberName, MemberLoc,
+                 TemplateArgs != 0),
+    IsArrow(IsArrow), HasUnresolvedUsing(HasUnresolvedUsing),
+    Base(Base), BaseType(BaseType), OperatorLoc(OperatorLoc) {
+  if (TemplateArgs)
+    getExplicitTemplateArgs().initializeFrom(*TemplateArgs);
+}
+
+UnresolvedMemberExpr *
+UnresolvedMemberExpr::Create(ASTContext &C, bool Dependent,
+                             bool HasUnresolvedUsing,
+                             Expr *Base, QualType BaseType, bool IsArrow,
+                             SourceLocation OperatorLoc,
+                             NestedNameSpecifier *Qualifier,
+                             SourceRange QualifierRange,
+                             DeclarationName Member,
+                             SourceLocation MemberLoc,
+                             const TemplateArgumentListInfo *TemplateArgs) {
+  std::size_t size = sizeof(UnresolvedMemberExpr);
+  if (TemplateArgs)
+    size += ExplicitTemplateArgumentList::sizeFor(*TemplateArgs);
+
+  void *Mem = C.Allocate(size, llvm::alignof<UnresolvedMemberExpr>());
+  return new (Mem) UnresolvedMemberExpr(
+                             Dependent ? C.DependentTy : C.OverloadTy,
+                             Dependent, HasUnresolvedUsing, Base, BaseType,
+                             IsArrow, OperatorLoc, Qualifier, QualifierRange,
+                             Member, MemberLoc, TemplateArgs);
+}
+
+CXXRecordDecl *UnresolvedMemberExpr::getNamingClass() const {
+  // Unlike for UnresolvedLookupExpr, it is very easy to re-derive this.
+
+  // If there was a nested name specifier, it names the naming class.
+  // It can't be dependent: after all, we were actually able to do the
+  // lookup.
+  const RecordType *RT;
+  if (getQualifier()) {
+    Type *T = getQualifier()->getAsType();
+    assert(T && "qualifier in member expression does not name type");
+    RT = T->getAs<RecordType>();
+    assert(RT && "qualifier in member expression does not name record");
+
+  // Otherwise the naming class must have been the base class.
+  } else {
+    QualType BaseType = getBaseType().getNonReferenceType();
+    if (isArrow()) {
+      const PointerType *PT = BaseType->getAs<PointerType>();
+      assert(PT && "base of arrow member access is not pointer");
+      BaseType = PT->getPointeeType();
+    }
+    
+    RT = BaseType->getAs<RecordType>();
+    assert(RT && "base of member expression does not name record");
+  }
+  
+  return cast<CXXRecordDecl>(RT->getDecl());
+}
+
+Stmt::child_iterator UnresolvedMemberExpr::child_begin() {
+  return child_iterator(&Base);
+}
+
+Stmt::child_iterator UnresolvedMemberExpr::child_end() {
+  if (isImplicitAccess())
+    return child_iterator(&Base);
+  return child_iterator(&Base + 1);
+}
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
new file mode 100644
index 0000000..a52cf6f
--- /dev/null
+++ b/lib/AST/ExprConstant.cpp
@@ -0,0 +1,2076 @@
+//===--- ExprConstant.cpp - Expression Constant Evaluator -----------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Expr constant evaluator.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/APValue.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/CharUnits.h"
+#include "clang/AST/RecordLayout.h"
+#include "clang/AST/StmtVisitor.h"
+#include "clang/AST/ASTDiagnostic.h"
+#include "clang/Basic/Builtins.h"
+#include "clang/Basic/TargetInfo.h"
+#include "llvm/ADT/SmallString.h"
+#include <cstring>
+
+using namespace clang;
+using llvm::APSInt;
+using llvm::APFloat;
+
+/// EvalInfo - This is a private struct used by the evaluator to capture
+/// information about a subexpression as it is folded.  It retains information
+/// about the AST context, but also maintains information about the folded
+/// expression.
+///
+/// If an expression could be evaluated, it is still possible it is not a C
+/// "integer constant expression" or constant expression.  If not, this struct
+/// captures information about how and why not.
+///
+/// One bit of information passed *into* the request for constant folding
+/// indicates whether the subexpression is "evaluated" or not according to C
+/// rules.  For example, the RHS of (0 && foo()) is not evaluated.  We can
+/// evaluate the expression regardless of what the RHS is, but C only allows
+/// certain things in certain situations.
+struct EvalInfo {
+  ASTContext &Ctx;
+
+  /// EvalResult - Contains information about the evaluation.
+  Expr::EvalResult &EvalResult;
+
+  /// AnyLValue - Stack based LValue results are not discarded.
+  bool AnyLValue;
+
+  EvalInfo(ASTContext &ctx, Expr::EvalResult& evalresult,
+           bool anylvalue = false)
+    : Ctx(ctx), EvalResult(evalresult), AnyLValue(anylvalue) {}
+};
+
+
+static bool EvaluateLValue(const Expr *E, APValue &Result, EvalInfo &Info);
+static bool EvaluatePointer(const Expr *E, APValue &Result, EvalInfo &Info);
+static bool EvaluateInteger(const Expr *E, APSInt  &Result, EvalInfo &Info);
+static bool EvaluateIntegerOrLValue(const Expr *E, APValue  &Result,
+                                    EvalInfo &Info);
+static bool EvaluateFloat(const Expr *E, APFloat &Result, EvalInfo &Info);
+static bool EvaluateComplex(const Expr *E, APValue &Result, EvalInfo &Info);
+
+//===----------------------------------------------------------------------===//
+// Misc utilities
+//===----------------------------------------------------------------------===//
+
+static bool EvalPointerValueAsBool(APValue& Value, bool& Result) {
+  // FIXME: Is this accurate for all kinds of bases?  If not, what would
+  // the check look like?
+  Result = Value.getLValueBase() || !Value.getLValueOffset().isZero();
+  return true;
+}
+
+static bool HandleConversionToBool(const Expr* E, bool& Result,
+                                   EvalInfo &Info) {
+  if (E->getType()->isIntegralType()) {
+    APSInt IntResult;
+    if (!EvaluateInteger(E, IntResult, Info))
+      return false;
+    Result = IntResult != 0;
+    return true;
+  } else if (E->getType()->isRealFloatingType()) {
+    APFloat FloatResult(0.0);
+    if (!EvaluateFloat(E, FloatResult, Info))
+      return false;
+    Result = !FloatResult.isZero();
+    return true;
+  } else if (E->getType()->hasPointerRepresentation()) {
+    APValue PointerResult;
+    if (!EvaluatePointer(E, PointerResult, Info))
+      return false;
+    return EvalPointerValueAsBool(PointerResult, Result);
+  } else if (E->getType()->isAnyComplexType()) {
+    APValue ComplexResult;
+    if (!EvaluateComplex(E, ComplexResult, Info))
+      return false;
+    if (ComplexResult.isComplexFloat()) {
+      Result = !ComplexResult.getComplexFloatReal().isZero() ||
+               !ComplexResult.getComplexFloatImag().isZero();
+    } else {
+      Result = ComplexResult.getComplexIntReal().getBoolValue() ||
+               ComplexResult.getComplexIntImag().getBoolValue();
+    }
+    return true;
+  }
+
+  return false;
+}
+
+static APSInt HandleFloatToIntCast(QualType DestType, QualType SrcType,
+                                   APFloat &Value, ASTContext &Ctx) {
+  unsigned DestWidth = Ctx.getIntWidth(DestType);
+  // Determine whether we are converting to unsigned or signed.
+  bool DestSigned = DestType->isSignedIntegerType();
+
+  // FIXME: Warning for overflow.
+  uint64_t Space[4];
+  bool ignored;
+  (void)Value.convertToInteger(Space, DestWidth, DestSigned,
+                               llvm::APFloat::rmTowardZero, &ignored);
+  return APSInt(llvm::APInt(DestWidth, 4, Space), !DestSigned);
+}
+
+static APFloat HandleFloatToFloatCast(QualType DestType, QualType SrcType,
+                                      APFloat &Value, ASTContext &Ctx) {
+  bool ignored;
+  APFloat Result = Value;
+  Result.convert(Ctx.getFloatTypeSemantics(DestType),
+                 APFloat::rmNearestTiesToEven, &ignored);
+  return Result;
+}
+
+static APSInt HandleIntToIntCast(QualType DestType, QualType SrcType,
+                                 APSInt &Value, ASTContext &Ctx) {
+  unsigned DestWidth = Ctx.getIntWidth(DestType);
+  APSInt Result = Value;
+  // Figure out if this is a truncate, extend or noop cast.
+  // If the input is signed, do a sign extend, noop, or truncate.
+  Result.extOrTrunc(DestWidth);
+  Result.setIsUnsigned(DestType->isUnsignedIntegerType());
+  return Result;
+}
+
+static APFloat HandleIntToFloatCast(QualType DestType, QualType SrcType,
+                                    APSInt &Value, ASTContext &Ctx) {
+
+  APFloat Result(Ctx.getFloatTypeSemantics(DestType), 1);
+  Result.convertFromAPInt(Value, Value.isSigned(),
+                          APFloat::rmNearestTiesToEven);
+  return Result;
+}
+
+namespace {
+class HasSideEffect
+  : public StmtVisitor<HasSideEffect, bool> {
+  EvalInfo &Info;
+public:
+
+  HasSideEffect(EvalInfo &info) : Info(info) {}
+
+  // Unhandled nodes conservatively default to having side effects.
+  bool VisitStmt(Stmt *S) {
+    return true;
+  }
+
+  bool VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }
+  bool VisitDeclRefExpr(DeclRefExpr *E) {
+    if (Info.Ctx.getCanonicalType(E->getType()).isVolatileQualified())
+      return true;
+    return false;
+  }
+  // We don't want to evaluate BlockExprs multiple times, as they generate
+  // a ton of code.
+  bool VisitBlockExpr(BlockExpr *E) { return true; }
+  bool VisitPredefinedExpr(PredefinedExpr *E) { return false; }
+  bool VisitCompoundLiteralExpr(CompoundLiteralExpr *E)
+    { return Visit(E->getInitializer()); }
+  bool VisitMemberExpr(MemberExpr *E) { return Visit(E->getBase()); }
+  bool VisitIntegerLiteral(IntegerLiteral *E) { return false; }
+  bool VisitFloatingLiteral(FloatingLiteral *E) { return false; }
+  bool VisitStringLiteral(StringLiteral *E) { return false; }
+  bool VisitCharacterLiteral(CharacterLiteral *E) { return false; }
+  bool VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) { return false; }
+  bool VisitArraySubscriptExpr(ArraySubscriptExpr *E)
+    { return Visit(E->getLHS()) || Visit(E->getRHS()); }
+  bool VisitChooseExpr(ChooseExpr *E)
+    { return Visit(E->getChosenSubExpr(Info.Ctx)); }
+  bool VisitCastExpr(CastExpr *E) { return Visit(E->getSubExpr()); }
+  bool VisitBinAssign(BinaryOperator *E) { return true; }
+  bool VisitCompoundAssignOperator(BinaryOperator *E) { return true; }
+  bool VisitBinaryOperator(BinaryOperator *E)
+  { return Visit(E->getLHS()) || Visit(E->getRHS()); }
+  bool VisitUnaryPreInc(UnaryOperator *E) { return true; }
+  bool VisitUnaryPostInc(UnaryOperator *E) { return true; }
+  bool VisitUnaryPreDec(UnaryOperator *E) { return true; }
+  bool VisitUnaryPostDec(UnaryOperator *E) { return true; }
+  bool VisitUnaryDeref(UnaryOperator *E) {
+    if (Info.Ctx.getCanonicalType(E->getType()).isVolatileQualified())
+      return true;
+    return Visit(E->getSubExpr());
+  }
+  bool VisitUnaryOperator(UnaryOperator *E) { return Visit(E->getSubExpr()); }
+    
+  // Has side effects if any element does.
+  bool VisitInitListExpr(InitListExpr *E) {
+    for (unsigned i = 0, e = E->getNumInits(); i != e; ++i)
+      if (Visit(E->getInit(i))) return true;
+    return false;
+  }
+};
+
+} // end anonymous namespace
+
+//===----------------------------------------------------------------------===//
+// LValue Evaluation
+//===----------------------------------------------------------------------===//
+namespace {
+class LValueExprEvaluator
+  : public StmtVisitor<LValueExprEvaluator, APValue> {
+  EvalInfo &Info;
+public:
+
+  LValueExprEvaluator(EvalInfo &info) : Info(info) {}
+
+  APValue VisitStmt(Stmt *S) {
+    return APValue();
+  }
+
+  APValue VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }
+  APValue VisitDeclRefExpr(DeclRefExpr *E);
+  APValue VisitPredefinedExpr(PredefinedExpr *E) { return APValue(E); }
+  APValue VisitCompoundLiteralExpr(CompoundLiteralExpr *E);
+  APValue VisitMemberExpr(MemberExpr *E);
+  APValue VisitStringLiteral(StringLiteral *E) { return APValue(E); }
+  APValue VisitObjCEncodeExpr(ObjCEncodeExpr *E) { return APValue(E); }
+  APValue VisitArraySubscriptExpr(ArraySubscriptExpr *E);
+  APValue VisitUnaryDeref(UnaryOperator *E);
+  APValue VisitUnaryExtension(const UnaryOperator *E)
+    { return Visit(E->getSubExpr()); }
+  APValue VisitChooseExpr(const ChooseExpr *E)
+    { return Visit(E->getChosenSubExpr(Info.Ctx)); }
+
+  APValue VisitCastExpr(CastExpr *E) {
+    switch (E->getCastKind()) {
+    default:
+      return APValue();
+
+    case CastExpr::CK_NoOp:
+      return Visit(E->getSubExpr());
+    }
+  }
+  // FIXME: Missing: __real__, __imag__
+};
+} // end anonymous namespace
+
+static bool EvaluateLValue(const Expr* E, APValue& Result, EvalInfo &Info) {
+  Result = LValueExprEvaluator(Info).Visit(const_cast<Expr*>(E));
+  return Result.isLValue();
+}
+
+APValue LValueExprEvaluator::VisitDeclRefExpr(DeclRefExpr *E) {
+  if (isa<FunctionDecl>(E->getDecl())) {
+    return APValue(E);
+  } else if (VarDecl* VD = dyn_cast<VarDecl>(E->getDecl())) {
+    if (!Info.AnyLValue && !VD->hasGlobalStorage())
+      return APValue();
+    if (!VD->getType()->isReferenceType())
+      return APValue(E);
+    // FIXME: Check whether VD might be overridden!
+    if (const Expr *Init = VD->getAnyInitializer())
+      return Visit(const_cast<Expr *>(Init));
+  }
+
+  return APValue();
+}
+
+APValue LValueExprEvaluator::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
+  if (!Info.AnyLValue && !E->isFileScope())
+    return APValue();
+  return APValue(E);
+}
+
+APValue LValueExprEvaluator::VisitMemberExpr(MemberExpr *E) {
+  APValue result;
+  QualType Ty;
+  if (E->isArrow()) {
+    if (!EvaluatePointer(E->getBase(), result, Info))
+      return APValue();
+    Ty = E->getBase()->getType()->getAs<PointerType>()->getPointeeType();
+  } else {
+    result = Visit(E->getBase());
+    if (result.isUninit())
+      return APValue();
+    Ty = E->getBase()->getType();
+  }
+
+  RecordDecl *RD = Ty->getAs<RecordType>()->getDecl();
+  const ASTRecordLayout &RL = Info.Ctx.getASTRecordLayout(RD);
+
+  FieldDecl *FD = dyn_cast<FieldDecl>(E->getMemberDecl());
+  if (!FD) // FIXME: deal with other kinds of member expressions
+    return APValue();
+
+  if (FD->getType()->isReferenceType())
+    return APValue();
+
+  // FIXME: This is linear time.
+  unsigned i = 0;
+  for (RecordDecl::field_iterator Field = RD->field_begin(),
+                               FieldEnd = RD->field_end();
+       Field != FieldEnd; (void)++Field, ++i) {
+    if (*Field == FD)
+      break;
+  }
+
+  result.setLValue(result.getLValueBase(),
+                   result.getLValueOffset() + 
+                       CharUnits::fromQuantity(RL.getFieldOffset(i) / 8));
+
+  return result;
+}
+
+APValue LValueExprEvaluator::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
+  APValue Result;
+
+  if (!EvaluatePointer(E->getBase(), Result, Info))
+    return APValue();
+
+  APSInt Index;
+  if (!EvaluateInteger(E->getIdx(), Index, Info))
+    return APValue();
+
+  CharUnits ElementSize = Info.Ctx.getTypeSizeInChars(E->getType());
+
+  CharUnits Offset = Index.getSExtValue() * ElementSize;
+  Result.setLValue(Result.getLValueBase(),
+                   Result.getLValueOffset() + Offset);
+  return Result;
+}
+
+APValue LValueExprEvaluator::VisitUnaryDeref(UnaryOperator *E) {
+  APValue Result;
+  if (!EvaluatePointer(E->getSubExpr(), Result, Info))
+    return APValue();
+  return Result;
+}
+
+//===----------------------------------------------------------------------===//
+// Pointer Evaluation
+//===----------------------------------------------------------------------===//
+
+namespace {
+class PointerExprEvaluator
+  : public StmtVisitor<PointerExprEvaluator, APValue> {
+  EvalInfo &Info;
+public:
+
+  PointerExprEvaluator(EvalInfo &info) : Info(info) {}
+
+  APValue VisitStmt(Stmt *S) {
+    return APValue();
+  }
+
+  APValue VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }
+
+  APValue VisitBinaryOperator(const BinaryOperator *E);
+  APValue VisitCastExpr(CastExpr* E);
+  APValue VisitUnaryExtension(const UnaryOperator *E)
+      { return Visit(E->getSubExpr()); }
+  APValue VisitUnaryAddrOf(const UnaryOperator *E);
+  APValue VisitObjCStringLiteral(ObjCStringLiteral *E)
+      { return APValue(E); }
+  APValue VisitAddrLabelExpr(AddrLabelExpr *E)
+      { return APValue(E); }
+  APValue VisitCallExpr(CallExpr *E);
+  APValue VisitBlockExpr(BlockExpr *E) {
+    if (!E->hasBlockDeclRefExprs())
+      return APValue(E);
+    return APValue();
+  }
+  APValue VisitImplicitValueInitExpr(ImplicitValueInitExpr *E)
+      { return APValue((Expr*)0); }
+  APValue VisitConditionalOperator(ConditionalOperator *E);
+  APValue VisitChooseExpr(ChooseExpr *E)
+      { return Visit(E->getChosenSubExpr(Info.Ctx)); }
+  APValue VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E)
+      { return APValue((Expr*)0); }
+  // FIXME: Missing: @protocol, @selector
+};
+} // end anonymous namespace
+
+static bool EvaluatePointer(const Expr* E, APValue& Result, EvalInfo &Info) {
+  if (!E->getType()->hasPointerRepresentation())
+    return false;
+  Result = PointerExprEvaluator(Info).Visit(const_cast<Expr*>(E));
+  return Result.isLValue();
+}
+
+APValue PointerExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
+  if (E->getOpcode() != BinaryOperator::Add &&
+      E->getOpcode() != BinaryOperator::Sub)
+    return APValue();
+
+  const Expr *PExp = E->getLHS();
+  const Expr *IExp = E->getRHS();
+  if (IExp->getType()->isPointerType())
+    std::swap(PExp, IExp);
+
+  APValue ResultLValue;
+  if (!EvaluatePointer(PExp, ResultLValue, Info))
+    return APValue();
+
+  llvm::APSInt AdditionalOffset;
+  if (!EvaluateInteger(IExp, AdditionalOffset, Info))
+    return APValue();
+
+  // Compute the new offset in the appropriate width.
+
+  QualType PointeeType =
+    PExp->getType()->getAs<PointerType>()->getPointeeType();
+  llvm::APSInt SizeOfPointee(AdditionalOffset);
+
+  // Explicitly handle GNU void* and function pointer arithmetic extensions.
+  if (PointeeType->isVoidType() || PointeeType->isFunctionType())
+    SizeOfPointee = 1;
+  else
+    SizeOfPointee = Info.Ctx.getTypeSizeInChars(PointeeType).getQuantity();
+
+  llvm::APSInt Offset(AdditionalOffset);
+  Offset = ResultLValue.getLValueOffset().getQuantity();
+  if (E->getOpcode() == BinaryOperator::Add)
+    Offset += AdditionalOffset * SizeOfPointee;
+  else
+    Offset -= AdditionalOffset * SizeOfPointee;
+
+  // Sign extend prior to converting back to a char unit.
+  if (Offset.getBitWidth() < 64)
+    Offset.extend(64);
+  return APValue(ResultLValue.getLValueBase(),
+                 CharUnits::fromQuantity(Offset.getLimitedValue()));
+}
+
+APValue PointerExprEvaluator::VisitUnaryAddrOf(const UnaryOperator *E) {
+  APValue result;
+  if (EvaluateLValue(E->getSubExpr(), result, Info))
+    return result;
+  return APValue();
+}
+
+
+APValue PointerExprEvaluator::VisitCastExpr(CastExpr* E) {
+  Expr* SubExpr = E->getSubExpr();
+
+  switch (E->getCastKind()) {
+  default:
+    break;
+
+  case CastExpr::CK_Unknown: {
+    // FIXME: The handling for CK_Unknown is ugly/shouldn't be necessary!
+
+    // Check for pointer->pointer cast
+    if (SubExpr->getType()->isPointerType() ||
+        SubExpr->getType()->isObjCObjectPointerType() ||
+        SubExpr->getType()->isNullPtrType() ||
+        SubExpr->getType()->isBlockPointerType())
+      return Visit(SubExpr);
+
+    if (SubExpr->getType()->isIntegralType()) {
+      APValue Result;
+      if (!EvaluateIntegerOrLValue(SubExpr, Result, Info))
+        break;
+
+      if (Result.isInt()) {
+        Result.getInt().extOrTrunc((unsigned)Info.Ctx.getTypeSize(E->getType()));
+        return APValue(0, 
+                       CharUnits::fromQuantity(Result.getInt().getZExtValue()));
+      }
+
+      // Cast is of an lvalue, no need to change value.
+      return Result;
+    }
+    break;
+  }
+
+  case CastExpr::CK_NoOp:
+  case CastExpr::CK_BitCast:
+  case CastExpr::CK_AnyPointerToObjCPointerCast:
+  case CastExpr::CK_AnyPointerToBlockPointerCast:
+    return Visit(SubExpr);
+
+  case CastExpr::CK_IntegralToPointer: {
+    APValue Result;
+    if (!EvaluateIntegerOrLValue(SubExpr, Result, Info))
+      break;
+
+    if (Result.isInt()) {
+      Result.getInt().extOrTrunc((unsigned)Info.Ctx.getTypeSize(E->getType()));
+      return APValue(0, 
+                     CharUnits::fromQuantity(Result.getInt().getZExtValue()));
+    }
+
+    // Cast is of an lvalue, no need to change value.
+    return Result;
+  }
+  case CastExpr::CK_ArrayToPointerDecay:
+  case CastExpr::CK_FunctionToPointerDecay: {
+    APValue Result;
+    if (EvaluateLValue(SubExpr, Result, Info))
+      return Result;
+    break;
+  }
+  }
+
+  return APValue();
+}
+
+APValue PointerExprEvaluator::VisitCallExpr(CallExpr *E) {
+  if (E->isBuiltinCall(Info.Ctx) ==
+        Builtin::BI__builtin___CFStringMakeConstantString ||
+      E->isBuiltinCall(Info.Ctx) ==
+        Builtin::BI__builtin___NSStringMakeConstantString)
+    return APValue(E);
+  return APValue();
+}
+
+APValue PointerExprEvaluator::VisitConditionalOperator(ConditionalOperator *E) {
+  bool BoolResult;
+  if (!HandleConversionToBool(E->getCond(), BoolResult, Info))
+    return APValue();
+
+  Expr* EvalExpr = BoolResult ? E->getTrueExpr() : E->getFalseExpr();
+
+  APValue Result;
+  if (EvaluatePointer(EvalExpr, Result, Info))
+    return Result;
+  return APValue();
+}
+
+//===----------------------------------------------------------------------===//
+// Vector Evaluation
+//===----------------------------------------------------------------------===//
+
+namespace {
+  class VectorExprEvaluator
+  : public StmtVisitor<VectorExprEvaluator, APValue> {
+    EvalInfo &Info;
+    APValue GetZeroVector(QualType VecType);
+  public:
+
+    VectorExprEvaluator(EvalInfo &info) : Info(info) {}
+
+    APValue VisitStmt(Stmt *S) {
+      return APValue();
+    }
+
+    APValue VisitParenExpr(ParenExpr *E)
+        { return Visit(E->getSubExpr()); }
+    APValue VisitUnaryExtension(const UnaryOperator *E)
+      { return Visit(E->getSubExpr()); }
+    APValue VisitUnaryPlus(const UnaryOperator *E)
+      { return Visit(E->getSubExpr()); }
+    APValue VisitUnaryReal(const UnaryOperator *E)
+      { return Visit(E->getSubExpr()); }
+    APValue VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E)
+      { return GetZeroVector(E->getType()); }
+    APValue VisitCastExpr(const CastExpr* E);
+    APValue VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
+    APValue VisitInitListExpr(const InitListExpr *E);
+    APValue VisitConditionalOperator(const ConditionalOperator *E);
+    APValue VisitChooseExpr(const ChooseExpr *E)
+      { return Visit(E->getChosenSubExpr(Info.Ctx)); }
+    APValue VisitUnaryImag(const UnaryOperator *E);
+    // FIXME: Missing: unary -, unary ~, binary add/sub/mul/div,
+    //                 binary comparisons, binary and/or/xor,
+    //                 shufflevector, ExtVectorElementExpr
+    //        (Note that these require implementing conversions
+    //         between vector types.)
+  };
+} // end anonymous namespace
+
+static bool EvaluateVector(const Expr* E, APValue& Result, EvalInfo &Info) {
+  if (!E->getType()->isVectorType())
+    return false;
+  Result = VectorExprEvaluator(Info).Visit(const_cast<Expr*>(E));
+  return !Result.isUninit();
+}
+
+APValue VectorExprEvaluator::VisitCastExpr(const CastExpr* E) {
+  const VectorType *VTy = E->getType()->getAs<VectorType>();
+  QualType EltTy = VTy->getElementType();
+  unsigned NElts = VTy->getNumElements();
+  unsigned EltWidth = Info.Ctx.getTypeSize(EltTy);
+
+  const Expr* SE = E->getSubExpr();
+  QualType SETy = SE->getType();
+  APValue Result = APValue();
+
+  // Check for vector->vector bitcast and scalar->vector splat.
+  if (SETy->isVectorType()) {
+    return this->Visit(const_cast<Expr*>(SE));
+  } else if (SETy->isIntegerType()) {
+    APSInt IntResult;
+    if (!EvaluateInteger(SE, IntResult, Info))
+      return APValue();
+    Result = APValue(IntResult);
+  } else if (SETy->isRealFloatingType()) {
+    APFloat F(0.0);
+    if (!EvaluateFloat(SE, F, Info))
+      return APValue();
+    Result = APValue(F);
+  } else
+    return APValue();
+
+  // For casts of a scalar to ExtVector, convert the scalar to the element type
+  // and splat it to all elements.
+  if (E->getType()->isExtVectorType()) {
+    if (EltTy->isIntegerType() && Result.isInt())
+      Result = APValue(HandleIntToIntCast(EltTy, SETy, Result.getInt(),
+                                          Info.Ctx));
+    else if (EltTy->isIntegerType())
+      Result = APValue(HandleFloatToIntCast(EltTy, SETy, Result.getFloat(),
+                                            Info.Ctx));
+    else if (EltTy->isRealFloatingType() && Result.isInt())
+      Result = APValue(HandleIntToFloatCast(EltTy, SETy, Result.getInt(),
+                                            Info.Ctx));
+    else if (EltTy->isRealFloatingType())
+      Result = APValue(HandleFloatToFloatCast(EltTy, SETy, Result.getFloat(),
+                                              Info.Ctx));
+    else
+      return APValue();
+
+    // Splat and create vector APValue.
+    llvm::SmallVector<APValue, 4> Elts(NElts, Result);
+    return APValue(&Elts[0], Elts.size());
+  }
+
+  // For casts of a scalar to regular gcc-style vector type, bitcast the scalar
+  // to the vector. To construct the APValue vector initializer, bitcast the
+  // initializing value to an APInt, and shift out the bits pertaining to each
+  // element.
+  APSInt Init;
+  Init = Result.isInt() ? Result.getInt() : Result.getFloat().bitcastToAPInt();
+
+  llvm::SmallVector<APValue, 4> Elts;
+  for (unsigned i = 0; i != NElts; ++i) {
+    APSInt Tmp = Init;
+    Tmp.extOrTrunc(EltWidth);
+
+    if (EltTy->isIntegerType())
+      Elts.push_back(APValue(Tmp));
+    else if (EltTy->isRealFloatingType())
+      Elts.push_back(APValue(APFloat(Tmp)));
+    else
+      return APValue();
+
+    Init >>= EltWidth;
+  }
+  return APValue(&Elts[0], Elts.size());
+}
+
+APValue
+VectorExprEvaluator::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
+  return this->Visit(const_cast<Expr*>(E->getInitializer()));
+}
+
+APValue
+VectorExprEvaluator::VisitInitListExpr(const InitListExpr *E) {
+  const VectorType *VT = E->getType()->getAs<VectorType>();
+  unsigned NumInits = E->getNumInits();
+  unsigned NumElements = VT->getNumElements();
+
+  QualType EltTy = VT->getElementType();
+  llvm::SmallVector<APValue, 4> Elements;
+
+  for (unsigned i = 0; i < NumElements; i++) {
+    if (EltTy->isIntegerType()) {
+      llvm::APSInt sInt(32);
+      if (i < NumInits) {
+        if (!EvaluateInteger(E->getInit(i), sInt, Info))
+          return APValue();
+      } else {
+        sInt = Info.Ctx.MakeIntValue(0, EltTy);
+      }
+      Elements.push_back(APValue(sInt));
+    } else {
+      llvm::APFloat f(0.0);
+      if (i < NumInits) {
+        if (!EvaluateFloat(E->getInit(i), f, Info))
+          return APValue();
+      } else {
+        f = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy));
+      }
+      Elements.push_back(APValue(f));
+    }
+  }
+  return APValue(&Elements[0], Elements.size());
+}
+
+APValue
+VectorExprEvaluator::GetZeroVector(QualType T) {
+  const VectorType *VT = T->getAs<VectorType>();
+  QualType EltTy = VT->getElementType();
+  APValue ZeroElement;
+  if (EltTy->isIntegerType())
+    ZeroElement = APValue(Info.Ctx.MakeIntValue(0, EltTy));
+  else
+    ZeroElement =
+        APValue(APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy)));
+
+  llvm::SmallVector<APValue, 4> Elements(VT->getNumElements(), ZeroElement);
+  return APValue(&Elements[0], Elements.size());
+}
+
+APValue VectorExprEvaluator::VisitConditionalOperator(const ConditionalOperator *E) {
+  bool BoolResult;
+  if (!HandleConversionToBool(E->getCond(), BoolResult, Info))
+    return APValue();
+
+  Expr* EvalExpr = BoolResult ? E->getTrueExpr() : E->getFalseExpr();
+
+  APValue Result;
+  if (EvaluateVector(EvalExpr, Result, Info))
+    return Result;
+  return APValue();
+}
+
+APValue VectorExprEvaluator::VisitUnaryImag(const UnaryOperator *E) {
+  if (!E->getSubExpr()->isEvaluatable(Info.Ctx))
+    Info.EvalResult.HasSideEffects = true;
+  return GetZeroVector(E->getType());
+}
+
+//===----------------------------------------------------------------------===//
+// Integer Evaluation
+//===----------------------------------------------------------------------===//
+
+namespace {
+class IntExprEvaluator
+  : public StmtVisitor<IntExprEvaluator, bool> {
+  EvalInfo &Info;
+  APValue &Result;
+public:
+  IntExprEvaluator(EvalInfo &info, APValue &result)
+    : Info(info), Result(result) {}
+
+  bool Success(const llvm::APSInt &SI, const Expr *E) {
+    assert(E->getType()->isIntegralType() && "Invalid evaluation result.");
+    assert(SI.isSigned() == E->getType()->isSignedIntegerType() &&
+           "Invalid evaluation result.");
+    assert(SI.getBitWidth() == Info.Ctx.getIntWidth(E->getType()) &&
+           "Invalid evaluation result.");
+    Result = APValue(SI);
+    return true;
+  }
+
+  bool Success(const llvm::APInt &I, const Expr *E) {
+    assert(E->getType()->isIntegralType() && "Invalid evaluation result.");
+    assert(I.getBitWidth() == Info.Ctx.getIntWidth(E->getType()) &&
+           "Invalid evaluation result.");
+    Result = APValue(APSInt(I));
+    Result.getInt().setIsUnsigned(E->getType()->isUnsignedIntegerType());
+    return true;
+  }
+
+  bool Success(uint64_t Value, const Expr *E) {
+    assert(E->getType()->isIntegralType() && "Invalid evaluation result.");
+    Result = APValue(Info.Ctx.MakeIntValue(Value, E->getType()));
+    return true;
+  }
+
+  bool Error(SourceLocation L, diag::kind D, const Expr *E) {
+    // Take the first error.
+    if (Info.EvalResult.Diag == 0) {
+      Info.EvalResult.DiagLoc = L;
+      Info.EvalResult.Diag = D;
+      Info.EvalResult.DiagExpr = E;
+    }
+    return false;
+  }
+
+  //===--------------------------------------------------------------------===//
+  //                            Visitor Methods
+  //===--------------------------------------------------------------------===//
+
+  bool VisitStmt(Stmt *) {
+    assert(0 && "This should be called on integers, stmts are not integers");
+    return false;
+  }
+
+  bool VisitExpr(Expr *E) {
+    return Error(E->getLocStart(), diag::note_invalid_subexpr_in_ice, E);
+  }
+
+  bool VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }
+
+  bool VisitIntegerLiteral(const IntegerLiteral *E) {
+    return Success(E->getValue(), E);
+  }
+  bool VisitCharacterLiteral(const CharacterLiteral *E) {
+    return Success(E->getValue(), E);
+  }
+  bool VisitTypesCompatibleExpr(const TypesCompatibleExpr *E) {
+    // Per gcc docs "this built-in function ignores top level
+    // qualifiers".  We need to use the canonical version to properly
+    // be able to strip CRV qualifiers from the type.
+    QualType T0 = Info.Ctx.getCanonicalType(E->getArgType1());
+    QualType T1 = Info.Ctx.getCanonicalType(E->getArgType2());
+    return Success(Info.Ctx.typesAreCompatible(T0.getUnqualifiedType(),
+                                               T1.getUnqualifiedType()),
+                   E);
+  }
+
+  bool CheckReferencedDecl(const Expr *E, const Decl *D);
+  bool VisitDeclRefExpr(const DeclRefExpr *E) {
+    return CheckReferencedDecl(E, E->getDecl());
+  }
+  bool VisitMemberExpr(const MemberExpr *E) {
+    if (CheckReferencedDecl(E, E->getMemberDecl())) {
+      // Conservatively assume a MemberExpr will have side-effects
+      Info.EvalResult.HasSideEffects = true;
+      return true;
+    }
+    return false;
+  }
+
+  bool VisitCallExpr(CallExpr *E);
+  bool VisitBinaryOperator(const BinaryOperator *E);
+  bool VisitUnaryOperator(const UnaryOperator *E);
+  bool VisitConditionalOperator(const ConditionalOperator *E);
+
+  bool VisitCastExpr(CastExpr* E);
+  bool VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr *E);
+
+  bool VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E) {
+    return Success(E->getValue(), E);
+  }
+
+  bool VisitGNUNullExpr(const GNUNullExpr *E) {
+    return Success(0, E);
+  }
+
+  bool VisitCXXZeroInitValueExpr(const CXXZeroInitValueExpr *E) {
+    return Success(0, E);
+  }
+
+  bool VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E) {
+    return Success(0, E);
+  }
+
+  bool VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E) {
+    return Success(E->EvaluateTrait(Info.Ctx), E);
+  }
+
+  bool VisitChooseExpr(const ChooseExpr *E) {
+    return Visit(E->getChosenSubExpr(Info.Ctx));
+  }
+
+  bool VisitUnaryReal(const UnaryOperator *E);
+  bool VisitUnaryImag(const UnaryOperator *E);
+
+private:
+  CharUnits GetAlignOfExpr(const Expr *E);
+  CharUnits GetAlignOfType(QualType T);
+  // FIXME: Missing: array subscript of vector, member of vector
+};
+} // end anonymous namespace
+
+static bool EvaluateIntegerOrLValue(const Expr* E, APValue &Result, EvalInfo &Info) {
+  if (!E->getType()->isIntegralType())
+    return false;
+
+  return IntExprEvaluator(Info, Result).Visit(const_cast<Expr*>(E));
+}
+
+static bool EvaluateInteger(const Expr* E, APSInt &Result, EvalInfo &Info) {
+  APValue Val;
+  if (!EvaluateIntegerOrLValue(E, Val, Info) || !Val.isInt())
+    return false;
+  Result = Val.getInt();
+  return true;
+}
+
+bool IntExprEvaluator::CheckReferencedDecl(const Expr* E, const Decl* D) {
+  // Enums are integer constant exprs.
+  if (const EnumConstantDecl *ECD = dyn_cast<EnumConstantDecl>(D))
+    return Success(ECD->getInitVal(), E);
+
+  // In C++, const, non-volatile integers initialized with ICEs are ICEs.
+  // In C, they can also be folded, although they are not ICEs.
+  if (Info.Ctx.getCanonicalType(E->getType()).getCVRQualifiers() 
+                                                        == Qualifiers::Const) {
+
+    if (isa<ParmVarDecl>(D))
+      return Error(E->getLocStart(), diag::note_invalid_subexpr_in_ice, E);
+
+    if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
+      if (const Expr *Init = VD->getAnyInitializer()) {
+        if (APValue *V = VD->getEvaluatedValue()) {
+          if (V->isInt())
+            return Success(V->getInt(), E);
+          return Error(E->getLocStart(), diag::note_invalid_subexpr_in_ice, E);
+        }
+
+        if (VD->isEvaluatingValue())
+          return Error(E->getLocStart(), diag::note_invalid_subexpr_in_ice, E);
+
+        VD->setEvaluatingValue();
+
+        if (Visit(const_cast<Expr*>(Init))) {
+          // Cache the evaluated value in the variable declaration.
+          VD->setEvaluatedValue(Result);
+          return true;
+        }
+
+        VD->setEvaluatedValue(APValue());
+        return false;
+      }
+    }
+  }
+
+  // Otherwise, random variable references are not constants.
+  return Error(E->getLocStart(), diag::note_invalid_subexpr_in_ice, E);
+}
+
+/// EvaluateBuiltinClassifyType - Evaluate __builtin_classify_type the same way
+/// as GCC.
+static int EvaluateBuiltinClassifyType(const CallExpr *E) {
+  // The following enum mimics the values returned by GCC.
+  // FIXME: Does GCC differ between lvalue and rvalue references here?
+  enum gcc_type_class {
+    no_type_class = -1,
+    void_type_class, integer_type_class, char_type_class,
+    enumeral_type_class, boolean_type_class,
+    pointer_type_class, reference_type_class, offset_type_class,
+    real_type_class, complex_type_class,
+    function_type_class, method_type_class,
+    record_type_class, union_type_class,
+    array_type_class, string_type_class,
+    lang_type_class
+  };
+
+  // If no argument was supplied, default to "no_type_class". This isn't
+  // ideal, however it is what gcc does.
+  if (E->getNumArgs() == 0)
+    return no_type_class;
+
+  QualType ArgTy = E->getArg(0)->getType();
+  if (ArgTy->isVoidType())
+    return void_type_class;
+  else if (ArgTy->isEnumeralType())
+    return enumeral_type_class;
+  else if (ArgTy->isBooleanType())
+    return boolean_type_class;
+  else if (ArgTy->isCharType())
+    return string_type_class; // gcc doesn't appear to use char_type_class
+  else if (ArgTy->isIntegerType())
+    return integer_type_class;
+  else if (ArgTy->isPointerType())
+    return pointer_type_class;
+  else if (ArgTy->isReferenceType())
+    return reference_type_class;
+  else if (ArgTy->isRealType())
+    return real_type_class;
+  else if (ArgTy->isComplexType())
+    return complex_type_class;
+  else if (ArgTy->isFunctionType())
+    return function_type_class;
+  else if (ArgTy->isStructureOrClassType())
+    return record_type_class;
+  else if (ArgTy->isUnionType())
+    return union_type_class;
+  else if (ArgTy->isArrayType())
+    return array_type_class;
+  else if (ArgTy->isUnionType())
+    return union_type_class;
+  else  // FIXME: offset_type_class, method_type_class, & lang_type_class?
+    assert(0 && "CallExpr::isBuiltinClassifyType(): unimplemented type");
+  return -1;
+}
+
+bool IntExprEvaluator::VisitCallExpr(CallExpr *E) {
+  switch (E->isBuiltinCall(Info.Ctx)) {
+  default:
+    return Error(E->getLocStart(), diag::note_invalid_subexpr_in_ice, E);
+
+  case Builtin::BI__builtin_object_size: {
+    const Expr *Arg = E->getArg(0)->IgnoreParens();
+    Expr::EvalResult Base;
+    
+    // TODO: Perhaps we should let LLVM lower this?
+    if (Arg->EvaluateAsAny(Base, Info.Ctx)
+        && Base.Val.getKind() == APValue::LValue
+        && !Base.HasSideEffects)
+      if (const Expr *LVBase = Base.Val.getLValueBase())
+        if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(LVBase)) {
+          if (const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl())) {
+            if (!VD->getType()->isIncompleteType()
+                && VD->getType()->isObjectType()
+                && !VD->getType()->isVariablyModifiedType()
+                && !VD->getType()->isDependentType()) {
+              CharUnits Size = Info.Ctx.getTypeSizeInChars(VD->getType());
+              CharUnits Offset = Base.Val.getLValueOffset();
+              if (!Offset.isNegative() && Offset <= Size)
+                Size -= Offset;
+              else
+                Size = CharUnits::Zero();
+              return Success(Size.getQuantity(), E);
+            }
+          }
+        }
+
+    // If evaluating the argument has side-effects we can't determine
+    // the size of the object and lower it to unknown now.
+    if (E->getArg(0)->HasSideEffects(Info.Ctx)) {
+      if (E->getArg(1)->EvaluateAsInt(Info.Ctx).getZExtValue() <= 1)
+        return Success(-1ULL, E);
+      return Success(0, E);
+    }
+
+    return Error(E->getLocStart(), diag::note_invalid_subexpr_in_ice, E);
+  }
+
+  case Builtin::BI__builtin_classify_type:
+    return Success(EvaluateBuiltinClassifyType(E), E);
+
+  case Builtin::BI__builtin_constant_p:
+    // __builtin_constant_p always has one operand: it returns true if that
+    // operand can be folded, false otherwise.
+    return Success(E->getArg(0)->isEvaluatable(Info.Ctx), E);
+      
+  case Builtin::BI__builtin_eh_return_data_regno: {
+    int Operand = E->getArg(0)->EvaluateAsInt(Info.Ctx).getZExtValue();
+    Operand = Info.Ctx.Target.getEHDataRegisterNumber(Operand);
+    return Success(Operand, E);
+  }
+
+  case Builtin::BI__builtin_expect:
+    return Visit(E->getArg(0));
+  }
+}
+
+bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
+  if (E->getOpcode() == BinaryOperator::Comma) {
+    if (!Visit(E->getRHS()))
+      return false;
+
+    // If we can't evaluate the LHS, it might have side effects;
+    // conservatively mark it.
+    if (!E->getLHS()->isEvaluatable(Info.Ctx))
+      Info.EvalResult.HasSideEffects = true;
+
+    return true;
+  }
+
+  if (E->isLogicalOp()) {
+    // These need to be handled specially because the operands aren't
+    // necessarily integral
+    bool lhsResult, rhsResult;
+
+    if (HandleConversionToBool(E->getLHS(), lhsResult, Info)) {
+      // We were able to evaluate the LHS, see if we can get away with not
+      // evaluating the RHS: 0 && X -> 0, 1 || X -> 1
+      if (lhsResult == (E->getOpcode() == BinaryOperator::LOr))
+        return Success(lhsResult, E);
+
+      if (HandleConversionToBool(E->getRHS(), rhsResult, Info)) {
+        if (E->getOpcode() == BinaryOperator::LOr)
+          return Success(lhsResult || rhsResult, E);
+        else
+          return Success(lhsResult && rhsResult, E);
+      }
+    } else {
+      if (HandleConversionToBool(E->getRHS(), rhsResult, Info)) {
+        // We can't evaluate the LHS; however, sometimes the result
+        // is determined by the RHS: X && 0 -> 0, X || 1 -> 1.
+        if (rhsResult == (E->getOpcode() == BinaryOperator::LOr) ||
+            !rhsResult == (E->getOpcode() == BinaryOperator::LAnd)) {
+          // Since we weren't able to evaluate the left hand side, it
+          // must have had side effects.
+          Info.EvalResult.HasSideEffects = true;
+
+          return Success(rhsResult, E);
+        }
+      }
+    }
+
+    return false;
+  }
+
+  QualType LHSTy = E->getLHS()->getType();
+  QualType RHSTy = E->getRHS()->getType();
+
+  if (LHSTy->isAnyComplexType()) {
+    assert(RHSTy->isAnyComplexType() && "Invalid comparison");
+    APValue LHS, RHS;
+
+    if (!EvaluateComplex(E->getLHS(), LHS, Info))
+      return false;
+
+    if (!EvaluateComplex(E->getRHS(), RHS, Info))
+      return false;
+
+    if (LHS.isComplexFloat()) {
+      APFloat::cmpResult CR_r =
+        LHS.getComplexFloatReal().compare(RHS.getComplexFloatReal());
+      APFloat::cmpResult CR_i =
+        LHS.getComplexFloatImag().compare(RHS.getComplexFloatImag());
+
+      if (E->getOpcode() == BinaryOperator::EQ)
+        return Success((CR_r == APFloat::cmpEqual &&
+                        CR_i == APFloat::cmpEqual), E);
+      else {
+        assert(E->getOpcode() == BinaryOperator::NE &&
+               "Invalid complex comparison.");
+        return Success(((CR_r == APFloat::cmpGreaterThan ||
+                         CR_r == APFloat::cmpLessThan) &&
+                        (CR_i == APFloat::cmpGreaterThan ||
+                         CR_i == APFloat::cmpLessThan)), E);
+      }
+    } else {
+      if (E->getOpcode() == BinaryOperator::EQ)
+        return Success((LHS.getComplexIntReal() == RHS.getComplexIntReal() &&
+                        LHS.getComplexIntImag() == RHS.getComplexIntImag()), E);
+      else {
+        assert(E->getOpcode() == BinaryOperator::NE &&
+               "Invalid compex comparison.");
+        return Success((LHS.getComplexIntReal() != RHS.getComplexIntReal() ||
+                        LHS.getComplexIntImag() != RHS.getComplexIntImag()), E);
+      }
+    }
+  }
+
+  if (LHSTy->isRealFloatingType() &&
+      RHSTy->isRealFloatingType()) {
+    APFloat RHS(0.0), LHS(0.0);
+
+    if (!EvaluateFloat(E->getRHS(), RHS, Info))
+      return false;
+
+    if (!EvaluateFloat(E->getLHS(), LHS, Info))
+      return false;
+
+    APFloat::cmpResult CR = LHS.compare(RHS);
+
+    switch (E->getOpcode()) {
+    default:
+      assert(0 && "Invalid binary operator!");
+    case BinaryOperator::LT:
+      return Success(CR == APFloat::cmpLessThan, E);
+    case BinaryOperator::GT:
+      return Success(CR == APFloat::cmpGreaterThan, E);
+    case BinaryOperator::LE:
+      return Success(CR == APFloat::cmpLessThan || CR == APFloat::cmpEqual, E);
+    case BinaryOperator::GE:
+      return Success(CR == APFloat::cmpGreaterThan || CR == APFloat::cmpEqual,
+                     E);
+    case BinaryOperator::EQ:
+      return Success(CR == APFloat::cmpEqual, E);
+    case BinaryOperator::NE:
+      return Success(CR == APFloat::cmpGreaterThan
+                     || CR == APFloat::cmpLessThan, E);
+    }
+  }
+
+  if (LHSTy->isPointerType() && RHSTy->isPointerType()) {
+    if (E->getOpcode() == BinaryOperator::Sub || E->isEqualityOp()) {
+      APValue LHSValue;
+      if (!EvaluatePointer(E->getLHS(), LHSValue, Info))
+        return false;
+
+      APValue RHSValue;
+      if (!EvaluatePointer(E->getRHS(), RHSValue, Info))
+        return false;
+
+      // Reject any bases from the normal codepath; we special-case comparisons
+      // to null.
+      if (LHSValue.getLValueBase()) {
+        if (!E->isEqualityOp())
+          return false;
+        if (RHSValue.getLValueBase() || !RHSValue.getLValueOffset().isZero())
+          return false;
+        bool bres;
+        if (!EvalPointerValueAsBool(LHSValue, bres))
+          return false;
+        return Success(bres ^ (E->getOpcode() == BinaryOperator::EQ), E);
+      } else if (RHSValue.getLValueBase()) {
+        if (!E->isEqualityOp())
+          return false;
+        if (LHSValue.getLValueBase() || !LHSValue.getLValueOffset().isZero())
+          return false;
+        bool bres;
+        if (!EvalPointerValueAsBool(RHSValue, bres))
+          return false;
+        return Success(bres ^ (E->getOpcode() == BinaryOperator::EQ), E);
+      }
+
+      if (E->getOpcode() == BinaryOperator::Sub) {
+        QualType Type = E->getLHS()->getType();
+        QualType ElementType = Type->getAs<PointerType>()->getPointeeType();
+
+        CharUnits ElementSize = CharUnits::One();
+        if (!ElementType->isVoidType() && !ElementType->isFunctionType())
+          ElementSize = Info.Ctx.getTypeSizeInChars(ElementType);
+
+        CharUnits Diff = LHSValue.getLValueOffset() - 
+                             RHSValue.getLValueOffset();
+        return Success(Diff / ElementSize, E);
+      }
+      bool Result;
+      if (E->getOpcode() == BinaryOperator::EQ) {
+        Result = LHSValue.getLValueOffset() == RHSValue.getLValueOffset();
+      } else {
+        Result = LHSValue.getLValueOffset() != RHSValue.getLValueOffset();
+      }
+      return Success(Result, E);
+    }
+  }
+  if (!LHSTy->isIntegralType() ||
+      !RHSTy->isIntegralType()) {
+    // We can't continue from here for non-integral types, and they
+    // could potentially confuse the following operations.
+    return false;
+  }
+
+  // The LHS of a constant expr is always evaluated and needed.
+  if (!Visit(E->getLHS()))
+    return false; // error in subexpression.
+
+  APValue RHSVal;
+  if (!EvaluateIntegerOrLValue(E->getRHS(), RHSVal, Info))
+    return false;
+
+  // Handle cases like (unsigned long)&a + 4.
+  if (E->isAdditiveOp() && Result.isLValue() && RHSVal.isInt()) {
+    CharUnits Offset = Result.getLValueOffset();
+    CharUnits AdditionalOffset = CharUnits::fromQuantity(
+                                     RHSVal.getInt().getZExtValue());
+    if (E->getOpcode() == BinaryOperator::Add)
+      Offset += AdditionalOffset;
+    else
+      Offset -= AdditionalOffset;
+    Result = APValue(Result.getLValueBase(), Offset);
+    return true;
+  }
+
+  // Handle cases like 4 + (unsigned long)&a
+  if (E->getOpcode() == BinaryOperator::Add &&
+        RHSVal.isLValue() && Result.isInt()) {
+    CharUnits Offset = RHSVal.getLValueOffset();
+    Offset += CharUnits::fromQuantity(Result.getInt().getZExtValue());
+    Result = APValue(RHSVal.getLValueBase(), Offset);
+    return true;
+  }
+
+  // All the following cases expect both operands to be an integer
+  if (!Result.isInt() || !RHSVal.isInt())
+    return false;
+
+  APSInt& RHS = RHSVal.getInt();
+
+  switch (E->getOpcode()) {
+  default:
+    return Error(E->getOperatorLoc(), diag::note_invalid_subexpr_in_ice, E);
+  case BinaryOperator::Mul: return Success(Result.getInt() * RHS, E);
+  case BinaryOperator::Add: return Success(Result.getInt() + RHS, E);
+  case BinaryOperator::Sub: return Success(Result.getInt() - RHS, E);
+  case BinaryOperator::And: return Success(Result.getInt() & RHS, E);
+  case BinaryOperator::Xor: return Success(Result.getInt() ^ RHS, E);
+  case BinaryOperator::Or:  return Success(Result.getInt() | RHS, E);
+  case BinaryOperator::Div:
+    if (RHS == 0)
+      return Error(E->getOperatorLoc(), diag::note_expr_divide_by_zero, E);
+    return Success(Result.getInt() / RHS, E);
+  case BinaryOperator::Rem:
+    if (RHS == 0)
+      return Error(E->getOperatorLoc(), diag::note_expr_divide_by_zero, E);
+    return Success(Result.getInt() % RHS, E);
+  case BinaryOperator::Shl: {
+    // FIXME: Warn about out of range shift amounts!
+    unsigned SA =
+      (unsigned) RHS.getLimitedValue(Result.getInt().getBitWidth()-1);
+    return Success(Result.getInt() << SA, E);
+  }
+  case BinaryOperator::Shr: {
+    unsigned SA =
+      (unsigned) RHS.getLimitedValue(Result.getInt().getBitWidth()-1);
+    return Success(Result.getInt() >> SA, E);
+  }
+
+  case BinaryOperator::LT: return Success(Result.getInt() < RHS, E);
+  case BinaryOperator::GT: return Success(Result.getInt() > RHS, E);
+  case BinaryOperator::LE: return Success(Result.getInt() <= RHS, E);
+  case BinaryOperator::GE: return Success(Result.getInt() >= RHS, E);
+  case BinaryOperator::EQ: return Success(Result.getInt() == RHS, E);
+  case BinaryOperator::NE: return Success(Result.getInt() != RHS, E);
+  }
+}
+
+bool IntExprEvaluator::VisitConditionalOperator(const ConditionalOperator *E) {
+  bool Cond;
+  if (!HandleConversionToBool(E->getCond(), Cond, Info))
+    return false;
+
+  return Visit(Cond ? E->getTrueExpr() : E->getFalseExpr());
+}
+
+CharUnits IntExprEvaluator::GetAlignOfType(QualType T) {
+  // C++ [expr.sizeof]p2: "When applied to a reference or a reference type,
+  //   the result is the size of the referenced type."
+  // C++ [expr.alignof]p3: "When alignof is applied to a reference type, the
+  //   result shall be the alignment of the referenced type."
+  if (const ReferenceType *Ref = T->getAs<ReferenceType>())
+    T = Ref->getPointeeType();
+
+  // Get information about the alignment.
+  unsigned CharSize = Info.Ctx.Target.getCharWidth();
+
+  // __alignof is defined to return the preferred alignment.
+  return CharUnits::fromQuantity(
+      Info.Ctx.getPreferredTypeAlign(T.getTypePtr()) / CharSize);
+}
+
+CharUnits IntExprEvaluator::GetAlignOfExpr(const Expr *E) {
+  E = E->IgnoreParens();
+
+  // alignof decl is always accepted, even if it doesn't make sense: we default
+  // to 1 in those cases.
+  if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
+    return Info.Ctx.getDeclAlign(DRE->getDecl(), 
+                                 /*RefAsPointee*/true);
+
+  if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
+    return Info.Ctx.getDeclAlign(ME->getMemberDecl(),
+                                 /*RefAsPointee*/true);
+
+  return GetAlignOfType(E->getType());
+}
+
+
+/// VisitSizeAlignOfExpr - Evaluate a sizeof or alignof with a result as the
+/// expression's type.
+bool IntExprEvaluator::VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr *E) {
+  // Handle alignof separately.
+  if (!E->isSizeOf()) {
+    if (E->isArgumentType())
+      return Success(GetAlignOfType(E->getArgumentType()).getQuantity(), E);
+    else
+      return Success(GetAlignOfExpr(E->getArgumentExpr()).getQuantity(), E);
+  }
+
+  QualType SrcTy = E->getTypeOfArgument();
+  // C++ [expr.sizeof]p2: "When applied to a reference or a reference type,
+  //   the result is the size of the referenced type."
+  // C++ [expr.alignof]p3: "When alignof is applied to a reference type, the
+  //   result shall be the alignment of the referenced type."
+  if (const ReferenceType *Ref = SrcTy->getAs<ReferenceType>())
+    SrcTy = Ref->getPointeeType();
+
+  // sizeof(void), __alignof__(void), sizeof(function) = 1 as a gcc
+  // extension.
+  if (SrcTy->isVoidType() || SrcTy->isFunctionType())
+    return Success(1, E);
+
+  // sizeof(vla) is not a constantexpr: C99 6.5.3.4p2.
+  if (!SrcTy->isConstantSizeType())
+    return false;
+
+  // Get information about the size.
+  return Success(Info.Ctx.getTypeSizeInChars(SrcTy).getQuantity(), E);
+}
+
+bool IntExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) {
+  // Special case unary operators that do not need their subexpression
+  // evaluated.  offsetof/sizeof/alignof are all special.
+  if (E->isOffsetOfOp()) {
+    // The AST for offsetof is defined in such a way that we can just
+    // directly Evaluate it as an l-value.
+    APValue LV;
+    if (!EvaluateLValue(E->getSubExpr(), LV, Info))
+      return false;
+    if (LV.getLValueBase())
+      return false;
+    return Success(LV.getLValueOffset().getQuantity(), E);
+  }
+
+  if (E->getOpcode() == UnaryOperator::LNot) {
+    // LNot's operand isn't necessarily an integer, so we handle it specially.
+    bool bres;
+    if (!HandleConversionToBool(E->getSubExpr(), bres, Info))
+      return false;
+    return Success(!bres, E);
+  }
+
+  // Only handle integral operations...
+  if (!E->getSubExpr()->getType()->isIntegralType())
+    return false;
+
+  // Get the operand value into 'Result'.
+  if (!Visit(E->getSubExpr()))
+    return false;
+
+  switch (E->getOpcode()) {
+  default:
+    // Address, indirect, pre/post inc/dec, etc are not valid constant exprs.
+    // See C99 6.6p3.
+    return Error(E->getOperatorLoc(), diag::note_invalid_subexpr_in_ice, E);
+  case UnaryOperator::Extension:
+    // FIXME: Should extension allow i-c-e extension expressions in its scope?
+    // If so, we could clear the diagnostic ID.
+    return true;
+  case UnaryOperator::Plus:
+    // The result is always just the subexpr.
+    return true;
+  case UnaryOperator::Minus:
+    if (!Result.isInt()) return false;
+    return Success(-Result.getInt(), E);
+  case UnaryOperator::Not:
+    if (!Result.isInt()) return false;
+    return Success(~Result.getInt(), E);
+  }
+}
+
+/// HandleCast - This is used to evaluate implicit or explicit casts where the
+/// result type is integer.
+bool IntExprEvaluator::VisitCastExpr(CastExpr *E) {
+  Expr *SubExpr = E->getSubExpr();
+  QualType DestType = E->getType();
+  QualType SrcType = SubExpr->getType();
+
+  if (DestType->isBooleanType()) {
+    bool BoolResult;
+    if (!HandleConversionToBool(SubExpr, BoolResult, Info))
+      return false;
+    return Success(BoolResult, E);
+  }
+
+  // Handle simple integer->integer casts.
+  if (SrcType->isIntegralType()) {
+    if (!Visit(SubExpr))
+      return false;
+
+    if (!Result.isInt()) {
+      // Only allow casts of lvalues if they are lossless.
+      return Info.Ctx.getTypeSize(DestType) == Info.Ctx.getTypeSize(SrcType);
+    }
+
+    return Success(HandleIntToIntCast(DestType, SrcType,
+                                      Result.getInt(), Info.Ctx), E);
+  }
+
+  // FIXME: Clean this up!
+  if (SrcType->isPointerType()) {
+    APValue LV;
+    if (!EvaluatePointer(SubExpr, LV, Info))
+      return false;
+
+    if (LV.getLValueBase()) {
+      // Only allow based lvalue casts if they are lossless.
+      if (Info.Ctx.getTypeSize(DestType) != Info.Ctx.getTypeSize(SrcType))
+        return false;
+
+      Result = LV;
+      return true;
+    }
+
+    APSInt AsInt = Info.Ctx.MakeIntValue(LV.getLValueOffset().getQuantity(), 
+                                         SrcType);
+    return Success(HandleIntToIntCast(DestType, SrcType, AsInt, Info.Ctx), E);
+  }
+
+  if (SrcType->isArrayType() || SrcType->isFunctionType()) {
+    // This handles double-conversion cases, where there's both
+    // an l-value promotion and an implicit conversion to int.
+    APValue LV;
+    if (!EvaluateLValue(SubExpr, LV, Info))
+      return false;
+
+    if (Info.Ctx.getTypeSize(DestType) != Info.Ctx.getTypeSize(Info.Ctx.VoidPtrTy))
+      return false;
+
+    Result = LV;
+    return true;
+  }
+
+  if (SrcType->isAnyComplexType()) {
+    APValue C;
+    if (!EvaluateComplex(SubExpr, C, Info))
+      return false;
+    if (C.isComplexFloat())
+      return Success(HandleFloatToIntCast(DestType, SrcType,
+                                          C.getComplexFloatReal(), Info.Ctx),
+                     E);
+    else
+      return Success(HandleIntToIntCast(DestType, SrcType,
+                                        C.getComplexIntReal(), Info.Ctx), E);
+  }
+  // FIXME: Handle vectors
+
+  if (!SrcType->isRealFloatingType())
+    return Error(E->getExprLoc(), diag::note_invalid_subexpr_in_ice, E);
+
+  APFloat F(0.0);
+  if (!EvaluateFloat(SubExpr, F, Info))
+    return Error(E->getExprLoc(), diag::note_invalid_subexpr_in_ice, E);
+
+  return Success(HandleFloatToIntCast(DestType, SrcType, F, Info.Ctx), E);
+}
+
+bool IntExprEvaluator::VisitUnaryReal(const UnaryOperator *E) {
+  if (E->getSubExpr()->getType()->isAnyComplexType()) {
+    APValue LV;
+    if (!EvaluateComplex(E->getSubExpr(), LV, Info) || !LV.isComplexInt())
+      return Error(E->getExprLoc(), diag::note_invalid_subexpr_in_ice, E);
+    return Success(LV.getComplexIntReal(), E);
+  }
+
+  return Visit(E->getSubExpr());
+}
+
+bool IntExprEvaluator::VisitUnaryImag(const UnaryOperator *E) {
+  if (E->getSubExpr()->getType()->isComplexIntegerType()) {
+    APValue LV;
+    if (!EvaluateComplex(E->getSubExpr(), LV, Info) || !LV.isComplexInt())
+      return Error(E->getExprLoc(), diag::note_invalid_subexpr_in_ice, E);
+    return Success(LV.getComplexIntImag(), E);
+  }
+
+  if (!E->getSubExpr()->isEvaluatable(Info.Ctx))
+    Info.EvalResult.HasSideEffects = true;
+  return Success(0, E);
+}
+
+//===----------------------------------------------------------------------===//
+// Float Evaluation
+//===----------------------------------------------------------------------===//
+
+namespace {
+class FloatExprEvaluator
+  : public StmtVisitor<FloatExprEvaluator, bool> {
+  EvalInfo &Info;
+  APFloat &Result;
+public:
+  FloatExprEvaluator(EvalInfo &info, APFloat &result)
+    : Info(info), Result(result) {}
+
+  bool VisitStmt(Stmt *S) {
+    return false;
+  }
+
+  bool VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }
+  bool VisitCallExpr(const CallExpr *E);
+
+  bool VisitUnaryOperator(const UnaryOperator *E);
+  bool VisitBinaryOperator(const BinaryOperator *E);
+  bool VisitFloatingLiteral(const FloatingLiteral *E);
+  bool VisitCastExpr(CastExpr *E);
+  bool VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E);
+  bool VisitConditionalOperator(ConditionalOperator *E);
+
+  bool VisitChooseExpr(const ChooseExpr *E)
+    { return Visit(E->getChosenSubExpr(Info.Ctx)); }
+  bool VisitUnaryExtension(const UnaryOperator *E)
+    { return Visit(E->getSubExpr()); }
+
+  // FIXME: Missing: __real__/__imag__, array subscript of vector,
+  //                 member of vector, ImplicitValueInitExpr
+};
+} // end anonymous namespace
+
+static bool EvaluateFloat(const Expr* E, APFloat& Result, EvalInfo &Info) {
+  return FloatExprEvaluator(Info, Result).Visit(const_cast<Expr*>(E));
+}
+
+static bool TryEvaluateBuiltinNaN(ASTContext &Context,
+                                  QualType ResultTy,
+                                  const Expr *Arg,
+                                  bool SNaN,
+                                  llvm::APFloat &Result) {
+  const StringLiteral *S = dyn_cast<StringLiteral>(Arg->IgnoreParenCasts());
+  if (!S) return false;
+
+  const llvm::fltSemantics &Sem = Context.getFloatTypeSemantics(ResultTy);
+
+  llvm::APInt fill;
+
+  // Treat empty strings as if they were zero.
+  if (S->getString().empty())
+    fill = llvm::APInt(32, 0);
+  else if (S->getString().getAsInteger(0, fill))
+    return false;
+
+  if (SNaN)
+    Result = llvm::APFloat::getSNaN(Sem, false, &fill);
+  else
+    Result = llvm::APFloat::getQNaN(Sem, false, &fill);
+  return true;
+}
+
+bool FloatExprEvaluator::VisitCallExpr(const CallExpr *E) {
+  switch (E->isBuiltinCall(Info.Ctx)) {
+  default: return false;
+  case Builtin::BI__builtin_huge_val:
+  case Builtin::BI__builtin_huge_valf:
+  case Builtin::BI__builtin_huge_vall:
+  case Builtin::BI__builtin_inf:
+  case Builtin::BI__builtin_inff:
+  case Builtin::BI__builtin_infl: {
+    const llvm::fltSemantics &Sem =
+      Info.Ctx.getFloatTypeSemantics(E->getType());
+    Result = llvm::APFloat::getInf(Sem);
+    return true;
+  }
+
+  case Builtin::BI__builtin_nans:
+  case Builtin::BI__builtin_nansf:
+  case Builtin::BI__builtin_nansl:
+    return TryEvaluateBuiltinNaN(Info.Ctx, E->getType(), E->getArg(0),
+                                 true, Result);
+
+  case Builtin::BI__builtin_nan:
+  case Builtin::BI__builtin_nanf:
+  case Builtin::BI__builtin_nanl:
+    // If this is __builtin_nan() turn this into a nan, otherwise we
+    // can't constant fold it.
+    return TryEvaluateBuiltinNaN(Info.Ctx, E->getType(), E->getArg(0),
+                                 false, Result);
+
+  case Builtin::BI__builtin_fabs:
+  case Builtin::BI__builtin_fabsf:
+  case Builtin::BI__builtin_fabsl:
+    if (!EvaluateFloat(E->getArg(0), Result, Info))
+      return false;
+
+    if (Result.isNegative())
+      Result.changeSign();
+    return true;
+
+  case Builtin::BI__builtin_copysign:
+  case Builtin::BI__builtin_copysignf:
+  case Builtin::BI__builtin_copysignl: {
+    APFloat RHS(0.);
+    if (!EvaluateFloat(E->getArg(0), Result, Info) ||
+        !EvaluateFloat(E->getArg(1), RHS, Info))
+      return false;
+    Result.copySign(RHS);
+    return true;
+  }
+  }
+}
+
+bool FloatExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) {
+  if (E->getOpcode() == UnaryOperator::Deref)
+    return false;
+
+  if (!EvaluateFloat(E->getSubExpr(), Result, Info))
+    return false;
+
+  switch (E->getOpcode()) {
+  default: return false;
+  case UnaryOperator::Plus:
+    return true;
+  case UnaryOperator::Minus:
+    Result.changeSign();
+    return true;
+  }
+}
+
+bool FloatExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
+  if (E->getOpcode() == BinaryOperator::Comma) {
+    if (!EvaluateFloat(E->getRHS(), Result, Info))
+      return false;
+
+    // If we can't evaluate the LHS, it might have side effects;
+    // conservatively mark it.
+    if (!E->getLHS()->isEvaluatable(Info.Ctx))
+      Info.EvalResult.HasSideEffects = true;
+
+    return true;
+  }
+
+  // FIXME: Diagnostics?  I really don't understand how the warnings
+  // and errors are supposed to work.
+  APFloat RHS(0.0);
+  if (!EvaluateFloat(E->getLHS(), Result, Info))
+    return false;
+  if (!EvaluateFloat(E->getRHS(), RHS, Info))
+    return false;
+
+  switch (E->getOpcode()) {
+  default: return false;
+  case BinaryOperator::Mul:
+    Result.multiply(RHS, APFloat::rmNearestTiesToEven);
+    return true;
+  case BinaryOperator::Add:
+    Result.add(RHS, APFloat::rmNearestTiesToEven);
+    return true;
+  case BinaryOperator::Sub:
+    Result.subtract(RHS, APFloat::rmNearestTiesToEven);
+    return true;
+  case BinaryOperator::Div:
+    Result.divide(RHS, APFloat::rmNearestTiesToEven);
+    return true;
+  }
+}
+
+bool FloatExprEvaluator::VisitFloatingLiteral(const FloatingLiteral *E) {
+  Result = E->getValue();
+  return true;
+}
+
+bool FloatExprEvaluator::VisitCastExpr(CastExpr *E) {
+  Expr* SubExpr = E->getSubExpr();
+
+  if (SubExpr->getType()->isIntegralType()) {
+    APSInt IntResult;
+    if (!EvaluateInteger(SubExpr, IntResult, Info))
+      return false;
+    Result = HandleIntToFloatCast(E->getType(), SubExpr->getType(),
+                                  IntResult, Info.Ctx);
+    return true;
+  }
+  if (SubExpr->getType()->isRealFloatingType()) {
+    if (!Visit(SubExpr))
+      return false;
+    Result = HandleFloatToFloatCast(E->getType(), SubExpr->getType(),
+                                    Result, Info.Ctx);
+    return true;
+  }
+  // FIXME: Handle complex types
+
+  return false;
+}
+
+bool FloatExprEvaluator::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) {
+  Result = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(E->getType()));
+  return true;
+}
+
+bool FloatExprEvaluator::VisitConditionalOperator(ConditionalOperator *E) {
+  bool Cond;
+  if (!HandleConversionToBool(E->getCond(), Cond, Info))
+    return false;
+
+  return Visit(Cond ? E->getTrueExpr() : E->getFalseExpr());
+}
+
+//===----------------------------------------------------------------------===//
+// Complex Evaluation (for float and integer)
+//===----------------------------------------------------------------------===//
+
+namespace {
+class ComplexExprEvaluator
+  : public StmtVisitor<ComplexExprEvaluator, APValue> {
+  EvalInfo &Info;
+
+public:
+  ComplexExprEvaluator(EvalInfo &info) : Info(info) {}
+
+  //===--------------------------------------------------------------------===//
+  //                            Visitor Methods
+  //===--------------------------------------------------------------------===//
+
+  APValue VisitStmt(Stmt *S) {
+    return APValue();
+  }
+
+  APValue VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }
+
+  APValue VisitImaginaryLiteral(ImaginaryLiteral *E) {
+    Expr* SubExpr = E->getSubExpr();
+
+    if (SubExpr->getType()->isRealFloatingType()) {
+      APFloat Result(0.0);
+
+      if (!EvaluateFloat(SubExpr, Result, Info))
+        return APValue();
+
+      return APValue(APFloat(Result.getSemantics(), APFloat::fcZero, false),
+                     Result);
+    } else {
+      assert(SubExpr->getType()->isIntegerType() &&
+             "Unexpected imaginary literal.");
+
+      llvm::APSInt Result;
+      if (!EvaluateInteger(SubExpr, Result, Info))
+        return APValue();
+
+      llvm::APSInt Zero(Result.getBitWidth(), !Result.isSigned());
+      Zero = 0;
+      return APValue(Zero, Result);
+    }
+  }
+
+  APValue VisitCastExpr(CastExpr *E) {
+    Expr* SubExpr = E->getSubExpr();
+    QualType EltType = E->getType()->getAs<ComplexType>()->getElementType();
+    QualType SubType = SubExpr->getType();
+
+    if (SubType->isRealFloatingType()) {
+      APFloat Result(0.0);
+
+      if (!EvaluateFloat(SubExpr, Result, Info))
+        return APValue();
+
+      if (EltType->isRealFloatingType()) {
+        Result = HandleFloatToFloatCast(EltType, SubType, Result, Info.Ctx);
+        return APValue(Result,
+                       APFloat(Result.getSemantics(), APFloat::fcZero, false));
+      } else {
+        llvm::APSInt IResult;
+        IResult = HandleFloatToIntCast(EltType, SubType, Result, Info.Ctx);
+        llvm::APSInt Zero(IResult.getBitWidth(), !IResult.isSigned());
+        Zero = 0;
+        return APValue(IResult, Zero);
+      }
+    } else if (SubType->isIntegerType()) {
+      APSInt Result;
+
+      if (!EvaluateInteger(SubExpr, Result, Info))
+        return APValue();
+
+      if (EltType->isRealFloatingType()) {
+        APFloat FResult =
+            HandleIntToFloatCast(EltType, SubType, Result, Info.Ctx);
+        return APValue(FResult,
+                       APFloat(FResult.getSemantics(), APFloat::fcZero, false));
+      } else {
+        Result = HandleIntToIntCast(EltType, SubType, Result, Info.Ctx);
+        llvm::APSInt Zero(Result.getBitWidth(), !Result.isSigned());
+        Zero = 0;
+        return APValue(Result, Zero);
+      }
+    } else if (const ComplexType *CT = SubType->getAs<ComplexType>()) {
+      APValue Src;
+
+      if (!EvaluateComplex(SubExpr, Src, Info))
+        return APValue();
+
+      QualType SrcType = CT->getElementType();
+
+      if (Src.isComplexFloat()) {
+        if (EltType->isRealFloatingType()) {
+          return APValue(HandleFloatToFloatCast(EltType, SrcType,
+                                                Src.getComplexFloatReal(),
+                                                Info.Ctx),
+                         HandleFloatToFloatCast(EltType, SrcType,
+                                                Src.getComplexFloatImag(),
+                                                Info.Ctx));
+        } else {
+          return APValue(HandleFloatToIntCast(EltType, SrcType,
+                                              Src.getComplexFloatReal(),
+                                              Info.Ctx),
+                         HandleFloatToIntCast(EltType, SrcType,
+                                              Src.getComplexFloatImag(),
+                                              Info.Ctx));
+        }
+      } else {
+        assert(Src.isComplexInt() && "Invalid evaluate result.");
+        if (EltType->isRealFloatingType()) {
+          return APValue(HandleIntToFloatCast(EltType, SrcType,
+                                              Src.getComplexIntReal(),
+                                              Info.Ctx),
+                         HandleIntToFloatCast(EltType, SrcType,
+                                              Src.getComplexIntImag(),
+                                              Info.Ctx));
+        } else {
+          return APValue(HandleIntToIntCast(EltType, SrcType,
+                                            Src.getComplexIntReal(),
+                                            Info.Ctx),
+                         HandleIntToIntCast(EltType, SrcType,
+                                            Src.getComplexIntImag(),
+                                            Info.Ctx));
+        }
+      }
+    }
+
+    // FIXME: Handle more casts.
+    return APValue();
+  }
+
+  APValue VisitBinaryOperator(const BinaryOperator *E);
+  APValue VisitChooseExpr(const ChooseExpr *E)
+    { return Visit(E->getChosenSubExpr(Info.Ctx)); }
+  APValue VisitUnaryExtension(const UnaryOperator *E)
+    { return Visit(E->getSubExpr()); }
+  // FIXME Missing: unary +/-/~, binary div, ImplicitValueInitExpr,
+  //                conditional ?:, comma
+};
+} // end anonymous namespace
+
+static bool EvaluateComplex(const Expr *E, APValue &Result, EvalInfo &Info) {
+  Result = ComplexExprEvaluator(Info).Visit(const_cast<Expr*>(E));
+  assert((!Result.isComplexFloat() ||
+          (&Result.getComplexFloatReal().getSemantics() ==
+           &Result.getComplexFloatImag().getSemantics())) &&
+         "Invalid complex evaluation.");
+  return Result.isComplexFloat() || Result.isComplexInt();
+}
+
+APValue ComplexExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
+  APValue Result, RHS;
+
+  if (!EvaluateComplex(E->getLHS(), Result, Info))
+    return APValue();
+
+  if (!EvaluateComplex(E->getRHS(), RHS, Info))
+    return APValue();
+
+  assert(Result.isComplexFloat() == RHS.isComplexFloat() &&
+         "Invalid operands to binary operator.");
+  switch (E->getOpcode()) {
+  default: return APValue();
+  case BinaryOperator::Add:
+    if (Result.isComplexFloat()) {
+      Result.getComplexFloatReal().add(RHS.getComplexFloatReal(),
+                                       APFloat::rmNearestTiesToEven);
+      Result.getComplexFloatImag().add(RHS.getComplexFloatImag(),
+                                       APFloat::rmNearestTiesToEven);
+    } else {
+      Result.getComplexIntReal() += RHS.getComplexIntReal();
+      Result.getComplexIntImag() += RHS.getComplexIntImag();
+    }
+    break;
+  case BinaryOperator::Sub:
+    if (Result.isComplexFloat()) {
+      Result.getComplexFloatReal().subtract(RHS.getComplexFloatReal(),
+                                            APFloat::rmNearestTiesToEven);
+      Result.getComplexFloatImag().subtract(RHS.getComplexFloatImag(),
+                                            APFloat::rmNearestTiesToEven);
+    } else {
+      Result.getComplexIntReal() -= RHS.getComplexIntReal();
+      Result.getComplexIntImag() -= RHS.getComplexIntImag();
+    }
+    break;
+  case BinaryOperator::Mul:
+    if (Result.isComplexFloat()) {
+      APValue LHS = Result;
+      APFloat &LHS_r = LHS.getComplexFloatReal();
+      APFloat &LHS_i = LHS.getComplexFloatImag();
+      APFloat &RHS_r = RHS.getComplexFloatReal();
+      APFloat &RHS_i = RHS.getComplexFloatImag();
+
+      APFloat Tmp = LHS_r;
+      Tmp.multiply(RHS_r, APFloat::rmNearestTiesToEven);
+      Result.getComplexFloatReal() = Tmp;
+      Tmp = LHS_i;
+      Tmp.multiply(RHS_i, APFloat::rmNearestTiesToEven);
+      Result.getComplexFloatReal().subtract(Tmp, APFloat::rmNearestTiesToEven);
+
+      Tmp = LHS_r;
+      Tmp.multiply(RHS_i, APFloat::rmNearestTiesToEven);
+      Result.getComplexFloatImag() = Tmp;
+      Tmp = LHS_i;
+      Tmp.multiply(RHS_r, APFloat::rmNearestTiesToEven);
+      Result.getComplexFloatImag().add(Tmp, APFloat::rmNearestTiesToEven);
+    } else {
+      APValue LHS = Result;
+      Result.getComplexIntReal() =
+        (LHS.getComplexIntReal() * RHS.getComplexIntReal() -
+         LHS.getComplexIntImag() * RHS.getComplexIntImag());
+      Result.getComplexIntImag() =
+        (LHS.getComplexIntReal() * RHS.getComplexIntImag() +
+         LHS.getComplexIntImag() * RHS.getComplexIntReal());
+    }
+    break;
+  }
+
+  return Result;
+}
+
+//===----------------------------------------------------------------------===//
+// Top level Expr::Evaluate method.
+//===----------------------------------------------------------------------===//
+
+/// Evaluate - Return true if this is a constant which we can fold using
+/// any crazy technique (that has nothing to do with language standards) that
+/// we want to.  If this function returns true, it returns the folded constant
+/// in Result.
+bool Expr::Evaluate(EvalResult &Result, ASTContext &Ctx) const {
+  EvalInfo Info(Ctx, Result);
+
+  if (getType()->isVectorType()) {
+    if (!EvaluateVector(this, Result.Val, Info))
+      return false;
+  } else if (getType()->isIntegerType()) {
+    if (!IntExprEvaluator(Info, Result.Val).Visit(const_cast<Expr*>(this)))
+      return false;
+  } else if (getType()->hasPointerRepresentation()) {
+    if (!EvaluatePointer(this, Result.Val, Info))
+      return false;
+  } else if (getType()->isRealFloatingType()) {
+    llvm::APFloat f(0.0);
+    if (!EvaluateFloat(this, f, Info))
+      return false;
+
+    Result.Val = APValue(f);
+  } else if (getType()->isAnyComplexType()) {
+    if (!EvaluateComplex(this, Result.Val, Info))
+      return false;
+  } else
+    return false;
+
+  return true;
+}
+
+bool Expr::EvaluateAsAny(EvalResult &Result, ASTContext &Ctx) const {
+  EvalInfo Info(Ctx, Result, true);
+
+  if (getType()->isVectorType()) {
+    if (!EvaluateVector(this, Result.Val, Info))
+      return false;
+  } else if (getType()->isIntegerType()) {
+    if (!IntExprEvaluator(Info, Result.Val).Visit(const_cast<Expr*>(this)))
+      return false;
+  } else if (getType()->hasPointerRepresentation()) {
+    if (!EvaluatePointer(this, Result.Val, Info))
+      return false;
+  } else if (getType()->isRealFloatingType()) {
+    llvm::APFloat f(0.0);
+    if (!EvaluateFloat(this, f, Info))
+      return false;
+
+    Result.Val = APValue(f);
+  } else if (getType()->isAnyComplexType()) {
+    if (!EvaluateComplex(this, Result.Val, Info))
+      return false;
+  } else
+    return false;
+
+  return true;
+}
+
+bool Expr::EvaluateAsBooleanCondition(bool &Result, ASTContext &Ctx) const {
+  EvalResult Scratch;
+  EvalInfo Info(Ctx, Scratch);
+
+  return HandleConversionToBool(this, Result, Info);
+}
+
+bool Expr::EvaluateAsLValue(EvalResult &Result, ASTContext &Ctx) const {
+  EvalInfo Info(Ctx, Result);
+
+  return EvaluateLValue(this, Result.Val, Info) && !Result.HasSideEffects;
+}
+
+bool Expr::EvaluateAsAnyLValue(EvalResult &Result, ASTContext &Ctx) const {
+  EvalInfo Info(Ctx, Result, true);
+
+  return EvaluateLValue(this, Result.Val, Info) && !Result.HasSideEffects;
+}
+
+/// isEvaluatable - Call Evaluate to see if this expression can be constant
+/// folded, but discard the result.
+bool Expr::isEvaluatable(ASTContext &Ctx) const {
+  EvalResult Result;
+  return Evaluate(Result, Ctx) && !Result.HasSideEffects;
+}
+
+bool Expr::HasSideEffects(ASTContext &Ctx) const {
+  Expr::EvalResult Result;
+  EvalInfo Info(Ctx, Result);
+  return HasSideEffect(Info).Visit(const_cast<Expr*>(this));
+}
+
+APSInt Expr::EvaluateAsInt(ASTContext &Ctx) const {
+  EvalResult EvalResult;
+  bool Result = Evaluate(EvalResult, Ctx);
+  Result = Result;
+  assert(Result && "Could not evaluate expression");
+  assert(EvalResult.Val.isInt() && "Expression did not evaluate to integer");
+
+  return EvalResult.Val.getInt();
+}
diff --git a/lib/AST/FullExpr.cpp b/lib/AST/FullExpr.cpp
new file mode 100644
index 0000000..f47284f
--- /dev/null
+++ b/lib/AST/FullExpr.cpp
@@ -0,0 +1,58 @@
+//===--- FullExpr.cpp - C++ full expression class ---------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the FullExpr interface, to be used for type safe handling
+//  of full expressions.
+//
+//  Full expressions are described in C++ [intro.execution]p12.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/FullExpr.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
+#include "llvm/Support/AlignOf.h"
+using namespace clang;
+
+FullExpr FullExpr::Create(ASTContext &Context, Expr *SubExpr,
+                          CXXTemporary **Temporaries, unsigned NumTemporaries) {
+  FullExpr E;
+
+  if (!NumTemporaries) {
+      E.SubExpr = SubExpr;
+      return E;
+  }
+
+  unsigned Size = sizeof(FullExpr) 
+      + sizeof(CXXTemporary *) * NumTemporaries;
+
+  unsigned Align = llvm::AlignOf<ExprAndTemporaries>::Alignment;
+  ExprAndTemporaries *ET = 
+      static_cast<ExprAndTemporaries *>(Context.Allocate(Size, Align));
+
+  ET->SubExpr = SubExpr;
+  std::copy(Temporaries, Temporaries + NumTemporaries, ET->temps_begin());
+    
+  return E;
+}
+
+void FullExpr::Destroy(ASTContext &Context) {
+  if (Expr *E = SubExpr.dyn_cast<Expr *>()) {
+    E->Destroy(Context);
+    return;
+  }
+  
+  ExprAndTemporaries *ET = SubExpr.get<ExprAndTemporaries *>();
+  for (ExprAndTemporaries::temps_iterator i = ET->temps_begin(), 
+       e = ET->temps_end(); i != e; ++i)
+    (*i)->Destroy(Context);
+
+  Context.Deallocate(ET);
+}
diff --git a/lib/AST/InheritViz.cpp b/lib/AST/InheritViz.cpp
new file mode 100644
index 0000000..c47a9da
--- /dev/null
+++ b/lib/AST/InheritViz.cpp
@@ -0,0 +1,168 @@
+//===- InheritViz.cpp - Graphviz visualization for inheritance --*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements CXXRecordDecl::viewInheritance, which
+//  generates a GraphViz DOT file that depicts the class inheritance
+//  diagram and then calls Graphviz/dot+gv on it.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/TypeOrdering.h"
+#include "llvm/Support/GraphWriter.h"
+#include "llvm/Support/raw_ostream.h"
+#include <map>
+
+using namespace llvm;
+
+namespace clang {
+
+/// InheritanceHierarchyWriter - Helper class that writes out a
+/// GraphViz file that diagrams the inheritance hierarchy starting at
+/// a given C++ class type. Note that we do not use LLVM's
+/// GraphWriter, because the interface does not permit us to properly
+/// differentiate between uses of types as virtual bases
+/// vs. non-virtual bases.
+class InheritanceHierarchyWriter {
+  ASTContext& Context;
+  llvm::raw_ostream &Out;
+  std::map<QualType, int, QualTypeOrdering> DirectBaseCount;
+  std::set<QualType, QualTypeOrdering> KnownVirtualBases;
+
+public:
+  InheritanceHierarchyWriter(ASTContext& Context, llvm::raw_ostream& Out)
+    : Context(Context), Out(Out) { }
+
+  void WriteGraph(QualType Type) {
+    Out << "digraph \"" << DOT::EscapeString(Type.getAsString()) << "\" {\n";
+    WriteNode(Type, false);
+    Out << "}\n";
+  }
+
+protected:
+  /// WriteNode - Write out the description of node in the inheritance
+  /// diagram, which may be a base class or it may be the root node.
+  void WriteNode(QualType Type, bool FromVirtual);
+
+  /// WriteNodeReference - Write out a reference to the given node,
+  /// using a unique identifier for each direct base and for the
+  /// (only) virtual base.
+  llvm::raw_ostream& WriteNodeReference(QualType Type, bool FromVirtual);
+};
+
+void InheritanceHierarchyWriter::WriteNode(QualType Type, bool FromVirtual) {
+  QualType CanonType = Context.getCanonicalType(Type);
+
+  if (FromVirtual) {
+    if (KnownVirtualBases.find(CanonType) != KnownVirtualBases.end())
+      return;
+
+    // We haven't seen this virtual base before, so display it and
+    // its bases.
+    KnownVirtualBases.insert(CanonType);
+  }
+
+  // Declare the node itself.
+  Out << "  ";
+  WriteNodeReference(Type, FromVirtual);
+
+  // Give the node a label based on the name of the class.
+  std::string TypeName = Type.getAsString();
+  Out << " [ shape=\"box\", label=\"" << DOT::EscapeString(TypeName);
+
+  // If the name of the class was a typedef or something different
+  // from the "real" class name, show the real class name in
+  // parentheses so we don't confuse ourselves.
+  if (TypeName != CanonType.getAsString()) {
+    Out << "\\n(" << CanonType.getAsString() << ")";
+  }
+
+  // Finished describing the node.
+  Out << " \"];\n";
+
+  // Display the base classes.
+  const CXXRecordDecl *Decl
+    = static_cast<const CXXRecordDecl *>(Type->getAs<RecordType>()->getDecl());
+  for (CXXRecordDecl::base_class_const_iterator Base = Decl->bases_begin();
+       Base != Decl->bases_end(); ++Base) {
+    QualType CanonBaseType = Context.getCanonicalType(Base->getType());
+
+    // If this is not virtual inheritance, bump the direct base
+    // count for the type.
+    if (!Base->isVirtual())
+      ++DirectBaseCount[CanonBaseType];
+
+    // Write out the node (if we need to).
+    WriteNode(Base->getType(), Base->isVirtual());
+
+    // Write out the edge.
+    Out << "  ";
+    WriteNodeReference(Type, FromVirtual);
+    Out << " -> ";
+    WriteNodeReference(Base->getType(), Base->isVirtual());
+
+    // Write out edge attributes to show the kind of inheritance.
+    if (Base->isVirtual()) {
+      Out << " [ style=\"dashed\" ]";
+    }
+    Out << ";";
+  }
+}
+
+/// WriteNodeReference - Write out a reference to the given node,
+/// using a unique identifier for each direct base and for the
+/// (only) virtual base.
+llvm::raw_ostream&
+InheritanceHierarchyWriter::WriteNodeReference(QualType Type,
+                                               bool FromVirtual) {
+  QualType CanonType = Context.getCanonicalType(Type);
+
+  Out << "Class_" << CanonType.getAsOpaquePtr();
+  if (!FromVirtual)
+    Out << "_" << DirectBaseCount[CanonType];
+  return Out;
+}
+
+/// viewInheritance - Display the inheritance hierarchy of this C++
+/// class using GraphViz.
+void CXXRecordDecl::viewInheritance(ASTContext& Context) const {
+  QualType Self = Context.getTypeDeclType(const_cast<CXXRecordDecl *>(this));
+  std::string ErrMsg;
+  sys::Path Filename = sys::Path::GetTemporaryDirectory(&ErrMsg);
+  if (Filename.isEmpty()) {
+    llvm::errs() << "Error: " << ErrMsg << "\n";
+    return;
+  }
+  Filename.appendComponent(Self.getAsString() + ".dot");
+  if (Filename.makeUnique(true,&ErrMsg)) {
+    llvm::errs() << "Error: " << ErrMsg << "\n";
+    return;
+  }
+
+  llvm::errs() << "Writing '" << Filename.c_str() << "'... ";
+
+  llvm::raw_fd_ostream O(Filename.c_str(), ErrMsg);
+
+  if (ErrMsg.empty()) {
+    InheritanceHierarchyWriter Writer(Context, O);
+    Writer.WriteGraph(Self);
+    llvm::errs() << " done. \n";
+
+    O.close();
+
+    // Display the graph
+    DisplayGraph(Filename);
+  } else {
+    llvm::errs() << "error opening file for writing!\n";
+  }
+}
+
+}
diff --git a/lib/AST/Makefile b/lib/AST/Makefile
new file mode 100644
index 0000000..ede2577
--- /dev/null
+++ b/lib/AST/Makefile
@@ -0,0 +1,21 @@
+##===- clang/lib/AST/Makefile ------------------------------*- Makefile -*-===##
+# 
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+# 
+##===----------------------------------------------------------------------===##
+#
+#  This implements the AST library for the C-Language front-end.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../../../..
+LIBRARYNAME := clangAST
+BUILD_ARCHIVE = 1
+
+CPP.Flags += -I$(PROJ_SRC_DIR)/../../include -I$(PROJ_OBJ_DIR)/../../include
+
+include $(LEVEL)/Makefile.common
+
diff --git a/lib/AST/NestedNameSpecifier.cpp b/lib/AST/NestedNameSpecifier.cpp
new file mode 100644
index 0000000..45518e9
--- /dev/null
+++ b/lib/AST/NestedNameSpecifier.cpp
@@ -0,0 +1,186 @@
+//===--- NestedNameSpecifier.cpp - C++ nested name specifiers -----*- C++ -*-=//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the NestedNameSpecifier class, which represents
+//  a C++ nested-name-specifier.
+//
+//===----------------------------------------------------------------------===//
+#include "clang/AST/NestedNameSpecifier.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/PrettyPrinter.h"
+#include "clang/AST/Type.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cassert>
+
+using namespace clang;
+
+NestedNameSpecifier *
+NestedNameSpecifier::FindOrInsert(ASTContext &Context,
+                                  const NestedNameSpecifier &Mockup) {
+  llvm::FoldingSetNodeID ID;
+  Mockup.Profile(ID);
+
+  void *InsertPos = 0;
+  NestedNameSpecifier *NNS
+    = Context.NestedNameSpecifiers.FindNodeOrInsertPos(ID, InsertPos);
+  if (!NNS) {
+    NNS = new (Context, 4) NestedNameSpecifier(Mockup);
+    Context.NestedNameSpecifiers.InsertNode(NNS, InsertPos);
+  }
+
+  return NNS;
+}
+
+NestedNameSpecifier *
+NestedNameSpecifier::Create(ASTContext &Context, NestedNameSpecifier *Prefix,
+                            IdentifierInfo *II) {
+  assert(II && "Identifier cannot be NULL");
+  assert((!Prefix || Prefix->isDependent()) && "Prefix must be dependent");
+
+  NestedNameSpecifier Mockup;
+  Mockup.Prefix.setPointer(Prefix);
+  Mockup.Prefix.setInt(Identifier);
+  Mockup.Specifier = II;
+  return FindOrInsert(Context, Mockup);
+}
+
+NestedNameSpecifier *
+NestedNameSpecifier::Create(ASTContext &Context, NestedNameSpecifier *Prefix,
+                            NamespaceDecl *NS) {
+  assert(NS && "Namespace cannot be NULL");
+  assert((!Prefix ||
+          (Prefix->getAsType() == 0 && Prefix->getAsIdentifier() == 0)) &&
+         "Broken nested name specifier");
+  NestedNameSpecifier Mockup;
+  Mockup.Prefix.setPointer(Prefix);
+  Mockup.Prefix.setInt(Namespace);
+  Mockup.Specifier = NS;
+  return FindOrInsert(Context, Mockup);
+}
+
+NestedNameSpecifier *
+NestedNameSpecifier::Create(ASTContext &Context, NestedNameSpecifier *Prefix,
+                            bool Template, Type *T) {
+  assert(T && "Type cannot be NULL");
+  NestedNameSpecifier Mockup;
+  Mockup.Prefix.setPointer(Prefix);
+  Mockup.Prefix.setInt(Template? TypeSpecWithTemplate : TypeSpec);
+  Mockup.Specifier = T;
+  return FindOrInsert(Context, Mockup);
+}
+
+NestedNameSpecifier *
+NestedNameSpecifier::Create(ASTContext &Context, IdentifierInfo *II) {
+  assert(II && "Identifier cannot be NULL");
+  NestedNameSpecifier Mockup;
+  Mockup.Prefix.setPointer(0);
+  Mockup.Prefix.setInt(Identifier);
+  Mockup.Specifier = II;
+  return FindOrInsert(Context, Mockup);
+}
+
+NestedNameSpecifier *NestedNameSpecifier::GlobalSpecifier(ASTContext &Context) {
+  if (!Context.GlobalNestedNameSpecifier)
+    Context.GlobalNestedNameSpecifier = new (Context, 4) NestedNameSpecifier();
+  return Context.GlobalNestedNameSpecifier;
+}
+
+/// \brief Whether this nested name specifier refers to a dependent
+/// type or not.
+bool NestedNameSpecifier::isDependent() const {
+  switch (getKind()) {
+  case Identifier:
+    // Identifier specifiers always represent dependent types
+    return true;
+
+  case Namespace:
+  case Global:
+    return false;
+
+  case TypeSpec:
+  case TypeSpecWithTemplate:
+    return getAsType()->isDependentType();
+  }
+
+  // Necessary to suppress a GCC warning.
+  return false;
+}
+
+/// \brief Print this nested name specifier to the given output
+/// stream.
+void
+NestedNameSpecifier::print(llvm::raw_ostream &OS,
+                           const PrintingPolicy &Policy) const {
+  if (getPrefix())
+    getPrefix()->print(OS, Policy);
+
+  switch (getKind()) {
+  case Identifier:
+    OS << getAsIdentifier()->getName();
+    break;
+
+  case Namespace:
+    OS << getAsNamespace()->getIdentifier()->getName();
+    break;
+
+  case Global:
+    break;
+
+  case TypeSpecWithTemplate:
+    OS << "template ";
+    // Fall through to print the type.
+
+  case TypeSpec: {
+    std::string TypeStr;
+    Type *T = getAsType();
+
+    PrintingPolicy InnerPolicy(Policy);
+    InnerPolicy.SuppressScope = true;
+
+    // Nested-name-specifiers are intended to contain minimally-qualified
+    // types. An actual QualifiedNameType will not occur, since we'll store
+    // just the type that is referred to in the nested-name-specifier (e.g.,
+    // a TypedefType, TagType, etc.). However, when we are dealing with
+    // dependent template-id types (e.g., Outer<T>::template Inner<U>),
+    // the type requires its own nested-name-specifier for uniqueness, so we
+    // suppress that nested-name-specifier during printing.
+    assert(!isa<QualifiedNameType>(T) &&
+           "Qualified name type in nested-name-specifier");
+    if (const TemplateSpecializationType *SpecType
+          = dyn_cast<TemplateSpecializationType>(T)) {
+      // Print the template name without its corresponding
+      // nested-name-specifier.
+      SpecType->getTemplateName().print(OS, InnerPolicy, true);
+
+      // Print the template argument list.
+      TypeStr = TemplateSpecializationType::PrintTemplateArgumentList(
+                                                          SpecType->getArgs(),
+                                                       SpecType->getNumArgs(),
+                                                                 InnerPolicy);
+    } else {
+      // Print the type normally
+      TypeStr = QualType(T, 0).getAsString(InnerPolicy);
+    }
+    OS << TypeStr;
+    break;
+  }
+  }
+
+  OS << "::";
+}
+
+void NestedNameSpecifier::Destroy(ASTContext &Context) {
+  this->~NestedNameSpecifier();
+  Context.Deallocate((void *)this);
+}
+
+void NestedNameSpecifier::dump(const LangOptions &LO) {
+  print(llvm::errs(), PrintingPolicy(LO));
+}
diff --git a/lib/AST/ParentMap.cpp b/lib/AST/ParentMap.cpp
new file mode 100644
index 0000000..48251d5
--- /dev/null
+++ b/lib/AST/ParentMap.cpp
@@ -0,0 +1,94 @@
+//===--- ParentMap.cpp - Mappings from Stmts to their Parents ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the ParentMap class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/ParentMap.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/Expr.h"
+#include "llvm/ADT/DenseMap.h"
+
+using namespace clang;
+
+typedef llvm::DenseMap<Stmt*, Stmt*> MapTy;
+
+static void BuildParentMap(MapTy& M, Stmt* S) {
+  for (Stmt::child_iterator I=S->child_begin(), E=S->child_end(); I!=E; ++I)
+    if (*I) {
+      M[*I] = S;
+      BuildParentMap(M, *I);
+    }
+}
+
+ParentMap::ParentMap(Stmt* S) : Impl(0) {
+  if (S) {
+    MapTy *M = new MapTy();
+    BuildParentMap(*M, S);
+    Impl = M;
+  }
+}
+
+ParentMap::~ParentMap() {
+  delete (MapTy*) Impl;
+}
+
+Stmt* ParentMap::getParent(Stmt* S) const {
+  MapTy* M = (MapTy*) Impl;
+  MapTy::iterator I = M->find(S);
+  return I == M->end() ? 0 : I->second;
+}
+
+Stmt *ParentMap::getParentIgnoreParens(Stmt *S) const {
+  do { S = getParent(S); } while (S && isa<ParenExpr>(S));
+  return S;
+}
+
+bool ParentMap::isConsumedExpr(Expr* E) const {
+  Stmt *P = getParent(E);
+  Stmt *DirectChild = E;
+
+  // Ignore parents that are parentheses or casts.
+  while (P && (isa<ParenExpr>(P) || isa<CastExpr>(P))) {
+    DirectChild = P;
+    P = getParent(P);
+  }
+
+  if (!P)
+    return false;
+
+  switch (P->getStmtClass()) {
+    default:
+      return isa<Expr>(P);
+    case Stmt::DeclStmtClass:
+      return true;
+    case Stmt::BinaryOperatorClass: {
+      BinaryOperator *BE = cast<BinaryOperator>(P);
+      // If it is a comma, only the right side is consumed.
+      // If it isn't a comma, both sides are consumed.
+      return BE->getOpcode()!=BinaryOperator::Comma ||DirectChild==BE->getRHS();
+    }
+    case Stmt::ForStmtClass:
+      return DirectChild == cast<ForStmt>(P)->getCond();
+    case Stmt::WhileStmtClass:
+      return DirectChild == cast<WhileStmt>(P)->getCond();
+    case Stmt::DoStmtClass:
+      return DirectChild == cast<DoStmt>(P)->getCond();
+    case Stmt::IfStmtClass:
+      return DirectChild == cast<IfStmt>(P)->getCond();
+    case Stmt::IndirectGotoStmtClass:
+      return DirectChild == cast<IndirectGotoStmt>(P)->getTarget();
+    case Stmt::SwitchStmtClass:
+      return DirectChild == cast<SwitchStmt>(P)->getCond();
+    case Stmt::ReturnStmtClass:
+      return true;
+  }
+}
+
diff --git a/lib/AST/RecordLayout.cpp b/lib/AST/RecordLayout.cpp
new file mode 100644
index 0000000..ade2483
--- /dev/null
+++ b/lib/AST/RecordLayout.cpp
@@ -0,0 +1,74 @@
+//===-- RecordLayout.cpp - Layout information for a struct/union -*- C++ -*-==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the RecordLayout interface.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/RecordLayout.h"
+
+using namespace clang;
+
+void ASTRecordLayout::Destroy(ASTContext &Ctx) {
+  if (FieldOffsets)
+    Ctx.Deallocate(FieldOffsets);
+  if (CXXInfo)
+    Ctx.Deallocate(CXXInfo);
+  this->~ASTRecordLayout();
+  Ctx.Deallocate(this);
+}
+
+ASTRecordLayout::ASTRecordLayout(ASTContext &Ctx, uint64_t size, unsigned alignment,
+                unsigned datasize, const uint64_t *fieldoffsets,
+                unsigned fieldcount)
+  : Size(size), DataSize(datasize), FieldOffsets(0), Alignment(alignment),
+    FieldCount(fieldcount), CXXInfo(0) {
+  if (FieldCount > 0)  {
+    FieldOffsets = new (Ctx) uint64_t[FieldCount];
+    memcpy(FieldOffsets, fieldoffsets, FieldCount * sizeof(*FieldOffsets));
+  }
+}
+
+// Constructor for C++ records.
+ASTRecordLayout::ASTRecordLayout(ASTContext &Ctx,
+                                 uint64_t size, unsigned alignment,
+                                 uint64_t datasize,
+                                 const uint64_t *fieldoffsets,
+                                 unsigned fieldcount,
+                                 uint64_t nonvirtualsize,
+                                 unsigned nonvirtualalign,
+                                 const PrimaryBaseInfo &PrimaryBase,
+                                 const BaseOffsetsMapTy& BaseOffsets,
+                                 const BaseOffsetsMapTy& VBaseOffsets)
+  : Size(size), DataSize(datasize), FieldOffsets(0), Alignment(alignment),
+    FieldCount(fieldcount), CXXInfo(new (Ctx) CXXRecordLayoutInfo)
+{
+  if (FieldCount > 0)  {
+    FieldOffsets = new (Ctx) uint64_t[FieldCount];
+    memcpy(FieldOffsets, fieldoffsets, FieldCount * sizeof(*FieldOffsets));
+  }
+
+  CXXInfo->PrimaryBase = PrimaryBase;
+  CXXInfo->NonVirtualSize = nonvirtualsize;
+  CXXInfo->NonVirtualAlign = nonvirtualalign;
+  CXXInfo->BaseOffsets = BaseOffsets;
+  CXXInfo->VBaseOffsets = VBaseOffsets;
+
+#ifndef NDEBUG
+    if (const CXXRecordDecl *PrimaryBase = getPrimaryBase()) {
+      if (getPrimaryBaseWasVirtual())
+        assert(getVBaseClassOffset(PrimaryBase) == 0 &&
+               "Primary virtual base must be at offset 0!");
+      else
+        assert(getBaseClassOffset(PrimaryBase) == 0 &&
+               "Primary base must be at offset 0!");
+    }
+#endif        
+}
diff --git a/lib/AST/RecordLayoutBuilder.cpp b/lib/AST/RecordLayoutBuilder.cpp
new file mode 100644
index 0000000..3782985
--- /dev/null
+++ b/lib/AST/RecordLayoutBuilder.cpp
@@ -0,0 +1,1017 @@
+//=== ASTRecordLayoutBuilder.cpp - Helper class for building record layouts ==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "RecordLayoutBuilder.h"
+
+#include "clang/AST/Attr.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/Expr.h"
+#include "clang/Basic/TargetInfo.h"
+#include "llvm/Support/Format.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/Support/MathExtras.h"
+
+using namespace clang;
+
+ASTRecordLayoutBuilder::ASTRecordLayoutBuilder(ASTContext &Context)
+  : Context(Context), Size(0), Alignment(8), Packed(false), 
+  UnfilledBitsInLastByte(0), MaxFieldAlignment(0), DataSize(0), IsUnion(false),
+  NonVirtualSize(0), NonVirtualAlignment(8), FirstNearlyEmptyVBase(0) { }
+
+/// IsNearlyEmpty - Indicates when a class has a vtable pointer, but
+/// no other data.
+bool ASTRecordLayoutBuilder::IsNearlyEmpty(const CXXRecordDecl *RD) const {
+  // FIXME: Audit the corners
+  if (!RD->isDynamicClass())
+    return false;
+  const ASTRecordLayout &BaseInfo = Context.getASTRecordLayout(RD);
+  if (BaseInfo.getNonVirtualSize() == Context.Target.getPointerWidth(0))
+    return true;
+  return false;
+}
+
+void ASTRecordLayoutBuilder::IdentifyPrimaryBases(const CXXRecordDecl *RD) {
+  const ASTRecordLayout::PrimaryBaseInfo &BaseInfo =
+    Context.getASTRecordLayout(RD).getPrimaryBaseInfo();
+
+  // If the record has a primary base class that is virtual, add it to the set
+  // of primary bases.
+  if (BaseInfo.isVirtual())
+    IndirectPrimaryBases.insert(BaseInfo.getBase());
+
+  // Now traverse all bases and find primary bases for them.
+  for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
+         e = RD->bases_end(); i != e; ++i) {
+    assert(!i->getType()->isDependentType() &&
+           "Cannot layout class with dependent bases.");
+    const CXXRecordDecl *Base =
+      cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
+
+    // Only bases with virtual bases participate in computing the
+    // indirect primary virtual base classes.
+    if (Base->getNumVBases())
+      IdentifyPrimaryBases(Base);
+  }
+}
+
+void
+ASTRecordLayoutBuilder::SelectPrimaryVBase(const CXXRecordDecl *RD) {
+  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
+         E = RD->bases_end(); I != E; ++I) {
+    assert(!I->getType()->isDependentType() &&
+           "Cannot layout class with dependent bases.");
+
+    const CXXRecordDecl *Base =
+      cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+
+    // Check if this is a nearly empty virtual base.
+    if (I->isVirtual() && IsNearlyEmpty(Base)) {
+      // If it's not an indirect primary base, then we've found our primary
+      // base.
+      if (!IndirectPrimaryBases.count(Base)) {
+        PrimaryBase = ASTRecordLayout::PrimaryBaseInfo(Base,
+                                                       /*IsVirtual=*/true);
+        return;
+      }
+
+      // Is this the first nearly empty virtual base?
+      if (!FirstNearlyEmptyVBase)
+        FirstNearlyEmptyVBase = Base;
+    }
+
+    SelectPrimaryVBase(Base);
+    if (PrimaryBase.getBase())
+      return;
+  }
+}
+
+/// DeterminePrimaryBase - Determine the primary base of the given class.
+void ASTRecordLayoutBuilder::DeterminePrimaryBase(const CXXRecordDecl *RD) {
+  // If the class isn't dynamic, it won't have a primary base.
+  if (!RD->isDynamicClass())
+    return;
+
+  // Compute all the primary virtual bases for all of our direct and
+  // indirect bases, and record all their primary virtual base classes.
+  for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
+         e = RD->bases_end(); i != e; ++i) {
+    assert(!i->getType()->isDependentType() &&
+           "Cannot lay out class with dependent bases.");
+    const CXXRecordDecl *Base =
+      cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
+    IdentifyPrimaryBases(Base);
+  }
+
+  // If the record has a dynamic base class, attempt to choose a primary base
+  // class. It is the first (in direct base class order) non-virtual dynamic
+  // base class, if one exists.
+  for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
+         e = RD->bases_end(); i != e; ++i) {
+    // Ignore virtual bases.
+    if (i->isVirtual())
+      continue;
+
+    const CXXRecordDecl *Base =
+      cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
+
+    if (Base->isDynamicClass()) {
+      // We found it.
+      PrimaryBase = ASTRecordLayout::PrimaryBaseInfo(Base, /*IsVirtual=*/false);
+      return;
+    }
+  }
+
+  // Otherwise, it is the first nearly empty virtual base that is not an
+  // indirect primary virtual base class, if one exists.
+  if (RD->getNumVBases() != 0) {
+    SelectPrimaryVBase(RD);
+    if (PrimaryBase.getBase())
+      return;
+  }
+
+  // Otherwise, it is the first nearly empty virtual base that is not an
+  // indirect primary virtual base class, if one exists.
+  if (FirstNearlyEmptyVBase) {
+    PrimaryBase = ASTRecordLayout::PrimaryBaseInfo(FirstNearlyEmptyVBase,
+                                                   /*IsVirtual=*/true);
+    return;
+  }
+
+  // Otherwise there is no primary base class.
+  assert(!PrimaryBase.getBase() && "Should not get here with a primary base!");
+
+  // Allocate the virtual table pointer at offset zero.
+  assert(DataSize == 0 && "Vtable pointer must be at offset zero!");
+
+  // Update the size.
+  Size += Context.Target.getPointerWidth(0);
+  DataSize = Size;
+
+  // Update the alignment.
+  UpdateAlignment(Context.Target.getPointerAlign(0));
+}
+
+void
+ASTRecordLayoutBuilder::LayoutNonVirtualBases(const CXXRecordDecl *RD) {
+  // First, determine the primary base class.
+  DeterminePrimaryBase(RD);
+
+  // If we have a primary base class, lay it out.
+  if (const CXXRecordDecl *Base = PrimaryBase.getBase()) {
+    if (PrimaryBase.isVirtual()) {
+      // We have a virtual primary base, insert it as an indirect primary base.
+      IndirectPrimaryBases.insert(Base);
+
+      assert(!VisitedVirtualBases.count(Base) && "vbase already visited!");
+      VisitedVirtualBases.insert(Base);
+      
+      LayoutVirtualBase(Base);
+    } else
+      LayoutNonVirtualBase(Base);
+  }
+
+  // Now lay out the non-virtual bases.
+  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
+         E = RD->bases_end(); I != E; ++I) {
+
+    // Ignore virtual bases.
+    if (I->isVirtual())
+      continue;
+
+    const CXXRecordDecl *Base =
+      cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+
+    // Skip the primary base.
+    if (Base == PrimaryBase.getBase() && !PrimaryBase.isVirtual())
+      continue;
+
+    // Lay out the base.
+    LayoutNonVirtualBase(Base);
+  }
+}
+
+void ASTRecordLayoutBuilder::LayoutNonVirtualBase(const CXXRecordDecl *RD) {
+  // Layout the base.
+  uint64_t Offset = LayoutBase(RD);
+
+  // Add its base class offset.
+  if (!Bases.insert(std::make_pair(RD, Offset)).second)
+    assert(false && "Added same base offset more than once!");
+}
+
+void
+ASTRecordLayoutBuilder::AddPrimaryVirtualBaseOffsets(const CXXRecordDecl *RD, 
+                                        uint64_t Offset,
+                                        const CXXRecordDecl *MostDerivedClass) {
+  // We already have the offset for the primary base of the most derived class.
+  if (RD != MostDerivedClass) {
+    const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
+    const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
+
+    // If this is a primary virtual base and we haven't seen it before, add it.
+    if (PrimaryBase && Layout.getPrimaryBaseWasVirtual() &&
+        !VBases.count(PrimaryBase))
+      VBases.insert(std::make_pair(PrimaryBase, Offset));
+  }
+
+  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
+       E = RD->bases_end(); I != E; ++I) {
+    assert(!I->getType()->isDependentType() &&
+           "Cannot layout class with dependent bases.");
+    
+    const CXXRecordDecl *BaseDecl =
+      cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+
+    if (!BaseDecl->getNumVBases()) {
+      // This base isn't interesting since it doesn't have any virtual bases.
+      continue;
+    }
+    
+    // Compute the offset of this base.
+    uint64_t BaseOffset;
+    
+    if (I->isVirtual()) {
+      // If we don't know this vbase yet, don't visit it. It will be visited
+      // later.
+      if (!VBases.count(BaseDecl)) {
+        continue;
+      }
+      
+      // Check if we've already visited this base.
+      if (!VisitedVirtualBases.insert(BaseDecl))
+        continue;
+
+      // We want the vbase offset from the class we're currently laying out.
+      BaseOffset = VBases[BaseDecl];
+    } else if (RD == MostDerivedClass) {
+      // We want the base offset from the class we're currently laying out.
+      assert(Bases.count(BaseDecl) && "Did not find base!");
+      BaseOffset = Bases[BaseDecl];
+    } else {
+      const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
+      BaseOffset = Offset + Layout.getBaseClassOffset(BaseDecl);
+    }
+
+    AddPrimaryVirtualBaseOffsets(BaseDecl, BaseOffset, MostDerivedClass);
+  }
+}
+
+void
+ASTRecordLayoutBuilder::LayoutVirtualBases(const CXXRecordDecl *RD,
+                                        const CXXRecordDecl *MostDerivedClass) {
+  const CXXRecordDecl *PrimaryBase;
+  bool PrimaryBaseIsVirtual;
+
+  if (MostDerivedClass == RD) {
+    PrimaryBase = this->PrimaryBase.getBase();
+    PrimaryBaseIsVirtual = this->PrimaryBase.isVirtual();
+  } else {
+    const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
+    PrimaryBase = Layout.getPrimaryBase();
+    PrimaryBaseIsVirtual = Layout.getPrimaryBaseWasVirtual();
+  }
+
+  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
+         E = RD->bases_end(); I != E; ++I) {
+    assert(!I->getType()->isDependentType() &&
+           "Cannot layout class with dependent bases.");
+
+    const CXXRecordDecl *Base =
+      cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+
+    if (I->isVirtual()) {
+      if (PrimaryBase != Base || !PrimaryBaseIsVirtual) {
+        bool IndirectPrimaryBase = IndirectPrimaryBases.count(Base);
+
+        // Only lay out the virtual base if it's not an indirect primary base.
+        if (!IndirectPrimaryBase) {
+          // Only visit virtual bases once.
+          if (!VisitedVirtualBases.insert(Base))
+            continue;
+          
+          LayoutVirtualBase(Base);
+        }
+      }
+    }
+
+    if (!Base->getNumVBases()) {
+      // This base isn't interesting since it doesn't have any virtual bases.
+      continue;
+    }
+
+    LayoutVirtualBases(Base, MostDerivedClass);
+  }
+}
+
+void ASTRecordLayoutBuilder::LayoutVirtualBase(const CXXRecordDecl *RD) {
+  // Layout the base.
+  uint64_t Offset = LayoutBase(RD);
+
+  // Add its base class offset.
+  if (!VBases.insert(std::make_pair(RD, Offset)).second)
+    assert(false && "Added same vbase offset more than once!");
+}
+
+uint64_t ASTRecordLayoutBuilder::LayoutBase(const CXXRecordDecl *RD) {
+  const ASTRecordLayout &BaseInfo = Context.getASTRecordLayout(RD);
+
+  // If we have an empty base class, try to place it at offset 0.
+  if (RD->isEmpty() && canPlaceRecordAtOffset(RD, 0)) {
+    // We were able to place the class at offset 0.
+    UpdateEmptyClassOffsets(RD, 0);
+
+    Size = std::max(Size, BaseInfo.getSize());
+
+    return 0;
+  }
+
+  unsigned BaseAlign = BaseInfo.getNonVirtualAlign();
+
+  // Round up the current record size to the base's alignment boundary.
+  uint64_t Offset = llvm::RoundUpToAlignment(DataSize, BaseAlign);
+
+  // Try to place the base.
+  while (true) {
+    if (canPlaceRecordAtOffset(RD, Offset))
+      break;
+
+    Offset += BaseAlign;
+  }
+
+  if (!RD->isEmpty()) {
+    // Update the data size.
+    DataSize = Offset + BaseInfo.getNonVirtualSize();
+
+    Size = std::max(Size, DataSize);
+  } else
+    Size = std::max(Size, Offset + BaseInfo.getSize());
+
+  // Remember max struct/class alignment.
+  UpdateAlignment(BaseAlign);
+
+  UpdateEmptyClassOffsets(RD, Offset);
+  return Offset;
+}
+
+bool ASTRecordLayoutBuilder::canPlaceRecordAtOffset(const CXXRecordDecl *RD,
+                                                    uint64_t Offset) const {
+  // Look for an empty class with the same type at the same offset.
+  for (EmptyClassOffsetsTy::const_iterator I =
+         EmptyClassOffsets.lower_bound(Offset),
+         E = EmptyClassOffsets.upper_bound(Offset); I != E; ++I) {
+
+    if (I->second == RD)
+      return false;
+  }
+
+  const ASTRecordLayout &Info = Context.getASTRecordLayout(RD);
+
+  // Check bases.
+  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
+         E = RD->bases_end(); I != E; ++I) {
+    assert(!I->getType()->isDependentType() &&
+           "Cannot layout class with dependent bases.");
+    if (I->isVirtual())
+      continue;
+
+    const CXXRecordDecl *Base =
+      cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+
+    uint64_t BaseClassOffset = Info.getBaseClassOffset(Base);
+
+    if (!canPlaceRecordAtOffset(Base, Offset + BaseClassOffset))
+      return false;
+  }
+
+  // Check fields.
+  unsigned FieldNo = 0;
+  for (CXXRecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
+       I != E; ++I, ++FieldNo) {
+    const FieldDecl *FD = *I;
+
+    uint64_t FieldOffset = Info.getFieldOffset(FieldNo);
+
+    if (!canPlaceFieldAtOffset(FD, Offset + FieldOffset))
+      return false;
+  }
+
+  // FIXME: virtual bases.
+  return true;
+}
+
+bool ASTRecordLayoutBuilder::canPlaceFieldAtOffset(const FieldDecl *FD,
+                                                   uint64_t Offset) const {
+  QualType T = FD->getType();
+  if (const RecordType *RT = T->getAs<RecordType>()) {
+    if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()))
+      return canPlaceRecordAtOffset(RD, Offset);
+  }
+
+  if (const ConstantArrayType *AT = Context.getAsConstantArrayType(T)) {
+    QualType ElemTy = Context.getBaseElementType(AT);
+    const RecordType *RT = ElemTy->getAs<RecordType>();
+    if (!RT)
+      return true;
+    const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());
+    if (!RD)
+      return true;
+
+    const ASTRecordLayout &Info = Context.getASTRecordLayout(RD);
+
+    uint64_t NumElements = Context.getConstantArrayElementCount(AT);
+    uint64_t ElementOffset = Offset;
+    for (uint64_t I = 0; I != NumElements; ++I) {
+      if (!canPlaceRecordAtOffset(RD, ElementOffset))
+        return false;
+
+      ElementOffset += Info.getSize();
+    }
+  }
+
+  return true;
+}
+
+void ASTRecordLayoutBuilder::UpdateEmptyClassOffsets(const CXXRecordDecl *RD,
+                                                     uint64_t Offset) {
+  if (RD->isEmpty())
+    EmptyClassOffsets.insert(std::make_pair(Offset, RD));
+
+  const ASTRecordLayout &Info = Context.getASTRecordLayout(RD);
+
+  // Update bases.
+  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
+         E = RD->bases_end(); I != E; ++I) {
+    assert(!I->getType()->isDependentType() &&
+           "Cannot layout class with dependent bases.");
+    if (I->isVirtual())
+      continue;
+
+    const CXXRecordDecl *Base =
+      cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+
+    uint64_t BaseClassOffset = Info.getBaseClassOffset(Base);
+    UpdateEmptyClassOffsets(Base, Offset + BaseClassOffset);
+  }
+
+  // Update fields.
+  unsigned FieldNo = 0;
+  for (CXXRecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
+       I != E; ++I, ++FieldNo) {
+    const FieldDecl *FD = *I;
+
+    uint64_t FieldOffset = Info.getFieldOffset(FieldNo);
+    UpdateEmptyClassOffsets(FD, Offset + FieldOffset);
+  }
+
+  // FIXME: Update virtual bases.
+}
+
+void
+ASTRecordLayoutBuilder::UpdateEmptyClassOffsets(const FieldDecl *FD,
+                                                uint64_t Offset) {
+  QualType T = FD->getType();
+
+  if (const RecordType *RT = T->getAs<RecordType>()) {
+    if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
+      UpdateEmptyClassOffsets(RD, Offset);
+      return;
+    }
+  }
+
+  if (const ConstantArrayType *AT = Context.getAsConstantArrayType(T)) {
+    QualType ElemTy = Context.getBaseElementType(AT);
+    const RecordType *RT = ElemTy->getAs<RecordType>();
+    if (!RT)
+      return;
+    const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());
+    if (!RD)
+      return;
+
+    const ASTRecordLayout &Info = Context.getASTRecordLayout(RD);
+
+    uint64_t NumElements = Context.getConstantArrayElementCount(AT);
+    uint64_t ElementOffset = Offset;
+
+    for (uint64_t I = 0; I != NumElements; ++I) {
+      UpdateEmptyClassOffsets(RD, ElementOffset);
+      ElementOffset += Info.getSize();
+    }
+  }
+}
+
+void ASTRecordLayoutBuilder::Layout(const RecordDecl *D) {
+  IsUnion = D->isUnion();
+
+  Packed = D->hasAttr<PackedAttr>();
+
+  // The #pragma pack attribute specifies the maximum field alignment.
+  if (const PragmaPackAttr *PPA = D->getAttr<PragmaPackAttr>())
+    MaxFieldAlignment = PPA->getAlignment();
+
+  if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
+    UpdateAlignment(AA->getMaxAlignment());
+
+  // If this is a C++ class, lay out the vtable and the non-virtual bases.
+  const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D);
+  if (RD)
+    LayoutNonVirtualBases(RD);
+
+  LayoutFields(D);
+
+  NonVirtualSize = Size;
+  NonVirtualAlignment = Alignment;
+
+  // If this is a C++ class, lay out its virtual bases and add its primary
+  // virtual base offsets.
+  if (RD) {
+    LayoutVirtualBases(RD, RD);
+
+    VisitedVirtualBases.clear();
+    AddPrimaryVirtualBaseOffsets(RD, 0, RD);
+  }
+
+  // Finally, round the size of the total struct up to the alignment of the
+  // struct itself.
+  FinishLayout();
+  
+#ifndef NDEBUG
+  if (RD) {
+    // Check that we have base offsets for all bases.
+    for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
+         E = RD->bases_end(); I != E; ++I) {
+      if (I->isVirtual())
+        continue;
+      
+      const CXXRecordDecl *BaseDecl =
+        cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+      
+      assert(Bases.count(BaseDecl) && "Did not find base offset!");
+    }
+    
+    // And all virtual bases.
+    for (CXXRecordDecl::base_class_const_iterator I = RD->vbases_begin(),
+         E = RD->vbases_end(); I != E; ++I) {
+      const CXXRecordDecl *BaseDecl =
+        cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+      
+      assert(VBases.count(BaseDecl) && "Did not find base offset!");
+    }
+  }
+#endif
+}
+
+// FIXME. Impl is no longer needed.
+void ASTRecordLayoutBuilder::Layout(const ObjCInterfaceDecl *D,
+                                    const ObjCImplementationDecl *Impl) {
+  if (ObjCInterfaceDecl *SD = D->getSuperClass()) {
+    const ASTRecordLayout &SL = Context.getASTObjCInterfaceLayout(SD);
+
+    UpdateAlignment(SL.getAlignment());
+
+    // We start laying out ivars not at the end of the superclass
+    // structure, but at the next byte following the last field.
+    Size = llvm::RoundUpToAlignment(SL.getDataSize(), 8);
+    DataSize = Size;
+  }
+
+  Packed = D->hasAttr<PackedAttr>();
+
+  // The #pragma pack attribute specifies the maximum field alignment.
+  if (const PragmaPackAttr *PPA = D->getAttr<PragmaPackAttr>())
+    MaxFieldAlignment = PPA->getAlignment();
+
+  if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
+    UpdateAlignment(AA->getMaxAlignment());
+  // Layout each ivar sequentially.
+  llvm::SmallVector<ObjCIvarDecl*, 16> Ivars;
+  Context.ShallowCollectObjCIvars(D, Ivars);
+  for (unsigned i = 0, e = Ivars.size(); i != e; ++i)
+    LayoutField(Ivars[i]);
+
+  // Finally, round the size of the total struct up to the alignment of the
+  // struct itself.
+  FinishLayout();
+}
+
+void ASTRecordLayoutBuilder::LayoutFields(const RecordDecl *D) {
+  // Layout each field, for now, just sequentially, respecting alignment.  In
+  // the future, this will need to be tweakable by targets.
+  for (RecordDecl::field_iterator Field = D->field_begin(),
+         FieldEnd = D->field_end(); Field != FieldEnd; ++Field)
+    LayoutField(*Field);
+}
+
+void ASTRecordLayoutBuilder::LayoutWideBitField(uint64_t FieldSize, 
+                                                uint64_t TypeSize) {
+  assert(Context.getLangOptions().CPlusPlus &&
+         "Can only have wide bit-fields in C++!");
+  
+  // Itanium C++ ABI 2.4:
+  //   If sizeof(T)*8 < n, let T' be the largest integral POD type with 
+  //   sizeof(T')*8 <= n.
+  
+  QualType IntegralPODTypes[] = {
+    Context.UnsignedCharTy, Context.UnsignedShortTy, Context.UnsignedIntTy, 
+    Context.UnsignedLongTy, Context.UnsignedLongLongTy
+  };
+
+  QualType Type;
+  for (unsigned I = 0, E = llvm::array_lengthof(IntegralPODTypes);
+       I != E; ++I) {
+    uint64_t Size = Context.getTypeSize(IntegralPODTypes[I]);
+
+    if (Size > FieldSize)
+      break;
+
+    Type = IntegralPODTypes[I];
+  }
+  assert(!Type.isNull() && "Did not find a type!");
+  
+  unsigned TypeAlign = Context.getTypeAlign(Type);
+
+  // We're not going to use any of the unfilled bits in the last byte.
+  UnfilledBitsInLastByte = 0;
+
+  uint64_t FieldOffset;
+  
+  if (IsUnion) {
+    DataSize = std::max(DataSize, FieldSize);
+    FieldOffset = 0;
+  } else {
+    // The bitfield is allocated starting at the next offset aligned appropriately
+    // for T', with length n bits. 
+    FieldOffset = llvm::RoundUpToAlignment(DataSize, TypeAlign);
+    
+    uint64_t NewSizeInBits = FieldOffset + FieldSize;
+    
+    DataSize = llvm::RoundUpToAlignment(NewSizeInBits, 8);
+    UnfilledBitsInLastByte = DataSize - NewSizeInBits;
+  }
+
+  // Place this field at the current location.
+  FieldOffsets.push_back(FieldOffset);
+
+  // Update the size.
+  Size = std::max(Size, DataSize);
+  
+  // Remember max struct/class alignment.
+  UpdateAlignment(TypeAlign);
+}
+
+void ASTRecordLayoutBuilder::LayoutBitField(const FieldDecl *D) {
+  bool FieldPacked = Packed || D->hasAttr<PackedAttr>();
+  uint64_t FieldOffset = IsUnion ? 0 : (DataSize - UnfilledBitsInLastByte);
+  uint64_t FieldSize = D->getBitWidth()->EvaluateAsInt(Context).getZExtValue();
+
+  std::pair<uint64_t, unsigned> FieldInfo = Context.getTypeInfo(D->getType());
+  uint64_t TypeSize = FieldInfo.first;
+  unsigned FieldAlign = FieldInfo.second;
+
+  if (FieldSize > TypeSize) {
+    LayoutWideBitField(FieldSize, TypeSize);
+    return;
+  }
+
+  if (FieldPacked || !Context.Target.useBitFieldTypeAlignment())
+    FieldAlign = 1;
+  if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
+    FieldAlign = std::max(FieldAlign, AA->getMaxAlignment());
+
+  // The maximum field alignment overrides the aligned attribute.
+  if (MaxFieldAlignment)
+    FieldAlign = std::min(FieldAlign, MaxFieldAlignment);
+
+  // Check if we need to add padding to give the field the correct alignment.
+  if (FieldSize == 0 || (FieldOffset & (FieldAlign-1)) + FieldSize > TypeSize)
+    FieldOffset = (FieldOffset + (FieldAlign-1)) & ~(FieldAlign-1);
+
+  // Padding members don't affect overall alignment.
+  if (!D->getIdentifier())
+    FieldAlign = 1;
+
+  // Place this field at the current location.
+  FieldOffsets.push_back(FieldOffset);
+
+  // Update DataSize to include the last byte containing (part of) the bitfield.
+  if (IsUnion) {
+    // FIXME: I think FieldSize should be TypeSize here.
+    DataSize = std::max(DataSize, FieldSize);
+  } else {
+    uint64_t NewSizeInBits = FieldOffset + FieldSize;
+
+    DataSize = llvm::RoundUpToAlignment(NewSizeInBits, 8);
+    UnfilledBitsInLastByte = DataSize - NewSizeInBits;
+  }
+
+  // Update the size.
+  Size = std::max(Size, DataSize);
+
+  // Remember max struct/class alignment.
+  UpdateAlignment(FieldAlign);
+}
+
+void ASTRecordLayoutBuilder::LayoutField(const FieldDecl *D) {
+  if (D->isBitField()) {
+    LayoutBitField(D);
+    return;
+  }
+
+  // Reset the unfilled bits.
+  UnfilledBitsInLastByte = 0;
+
+  bool FieldPacked = Packed || D->hasAttr<PackedAttr>();
+  uint64_t FieldOffset = IsUnion ? 0 : DataSize;
+  uint64_t FieldSize;
+  unsigned FieldAlign;
+
+  if (D->getType()->isIncompleteArrayType()) {
+    // This is a flexible array member; we can't directly
+    // query getTypeInfo about these, so we figure it out here.
+    // Flexible array members don't have any size, but they
+    // have to be aligned appropriately for their element type.
+    FieldSize = 0;
+    const ArrayType* ATy = Context.getAsArrayType(D->getType());
+    FieldAlign = Context.getTypeAlign(ATy->getElementType());
+  } else if (const ReferenceType *RT = D->getType()->getAs<ReferenceType>()) {
+    unsigned AS = RT->getPointeeType().getAddressSpace();
+    FieldSize = Context.Target.getPointerWidth(AS);
+    FieldAlign = Context.Target.getPointerAlign(AS);
+  } else {
+    std::pair<uint64_t, unsigned> FieldInfo = Context.getTypeInfo(D->getType());
+    FieldSize = FieldInfo.first;
+    FieldAlign = FieldInfo.second;
+  }
+
+  if (FieldPacked)
+    FieldAlign = 8;
+  if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
+    FieldAlign = std::max(FieldAlign, AA->getMaxAlignment());
+
+  // The maximum field alignment overrides the aligned attribute.
+  if (MaxFieldAlignment)
+    FieldAlign = std::min(FieldAlign, MaxFieldAlignment);
+
+  // Round up the current record size to the field's alignment boundary.
+  FieldOffset = llvm::RoundUpToAlignment(FieldOffset, FieldAlign);
+
+  if (!IsUnion) {
+    while (true) {
+      // Check if we can place the field at this offset.
+      if (canPlaceFieldAtOffset(D, FieldOffset))
+        break;
+
+      // We couldn't place the field at the offset. Try again at a new offset.
+      FieldOffset += FieldAlign;
+    }
+
+    UpdateEmptyClassOffsets(D, FieldOffset);
+  }
+
+  // Place this field at the current location.
+  FieldOffsets.push_back(FieldOffset);
+
+  // Reserve space for this field.
+  if (IsUnion)
+    Size = std::max(Size, FieldSize);
+  else
+    Size = FieldOffset + FieldSize;
+
+  // Update the data size.
+  DataSize = Size;
+
+  // Remember max struct/class alignment.
+  UpdateAlignment(FieldAlign);
+}
+
+void ASTRecordLayoutBuilder::FinishLayout() {
+  // In C++, records cannot be of size 0.
+  if (Context.getLangOptions().CPlusPlus && Size == 0)
+    Size = 8;
+  // Finally, round the size of the record up to the alignment of the
+  // record itself.
+  Size = llvm::RoundUpToAlignment(Size, Alignment);
+}
+
+void ASTRecordLayoutBuilder::UpdateAlignment(unsigned NewAlignment) {
+  if (NewAlignment <= Alignment)
+    return;
+
+  assert(llvm::isPowerOf2_32(NewAlignment && "Alignment not a power of 2"));
+
+  Alignment = NewAlignment;
+}
+
+const ASTRecordLayout *
+ASTRecordLayoutBuilder::ComputeLayout(ASTContext &Ctx,
+                                      const RecordDecl *D) {
+  ASTRecordLayoutBuilder Builder(Ctx);
+
+  Builder.Layout(D);
+
+  if (!isa<CXXRecordDecl>(D))
+    return new (Ctx) ASTRecordLayout(Ctx, Builder.Size, Builder.Alignment,
+                                     Builder.Size,
+                                     Builder.FieldOffsets.data(),
+                                     Builder.FieldOffsets.size());
+
+  // FIXME: This is not always correct. See the part about bitfields at
+  // http://www.codesourcery.com/public/cxx-abi/abi.html#POD for more info.
+  // FIXME: IsPODForThePurposeOfLayout should be stored in the record layout.
+  bool IsPODForThePurposeOfLayout = cast<CXXRecordDecl>(D)->isPOD();
+
+  // FIXME: This should be done in FinalizeLayout.
+  uint64_t DataSize =
+    IsPODForThePurposeOfLayout ? Builder.Size : Builder.DataSize;
+  uint64_t NonVirtualSize =
+    IsPODForThePurposeOfLayout ? DataSize : Builder.NonVirtualSize;
+
+  return new (Ctx) ASTRecordLayout(Ctx, Builder.Size, Builder.Alignment,
+                                   DataSize, Builder.FieldOffsets.data(),
+                                   Builder.FieldOffsets.size(),
+                                   NonVirtualSize,
+                                   Builder.NonVirtualAlignment,
+                                   Builder.PrimaryBase,
+                                   Builder.Bases, Builder.VBases);
+}
+
+const ASTRecordLayout *
+ASTRecordLayoutBuilder::ComputeLayout(ASTContext &Ctx,
+                                      const ObjCInterfaceDecl *D,
+                                      const ObjCImplementationDecl *Impl) {
+  ASTRecordLayoutBuilder Builder(Ctx);
+
+  Builder.Layout(D, Impl);
+
+  return new (Ctx) ASTRecordLayout(Ctx, Builder.Size, Builder.Alignment,
+                                   Builder.DataSize,
+                                   Builder.FieldOffsets.data(),
+                                   Builder.FieldOffsets.size());
+}
+
+const CXXMethodDecl *
+ASTRecordLayoutBuilder::ComputeKeyFunction(const CXXRecordDecl *RD) {
+  assert(RD->isDynamicClass() && "Class does not have any virtual methods!");
+
+  // If a class isn't polymorphic it doesn't have a key function.
+  if (!RD->isPolymorphic())
+    return 0;
+
+  // A class inside an anonymous namespace doesn't have a key function.  (Or
+  // at least, there's no point to assigning a key function to such a class;
+  // this doesn't affect the ABI.)
+  if (RD->isInAnonymousNamespace())
+    return 0;
+
+  for (CXXRecordDecl::method_iterator I = RD->method_begin(),
+         E = RD->method_end(); I != E; ++I) {
+    const CXXMethodDecl *MD = *I;
+
+    if (!MD->isVirtual())
+      continue;
+
+    if (MD->isPure())
+      continue;
+
+    // Ignore implicit member functions, they are always marked as inline, but
+    // they don't have a body until they're defined.
+    if (MD->isImplicit())
+      continue;
+
+    if (MD->isInlineSpecified())
+      continue;
+
+    if (MD->hasInlineBody())
+      continue;
+
+    // We found it.
+    return MD;
+  }
+
+  return 0;
+}
+
+static void PrintOffset(llvm::raw_ostream &OS,
+                        uint64_t Offset, unsigned IndentLevel) {
+  OS << llvm::format("%4d | ", Offset);
+  OS.indent(IndentLevel * 2);
+}
+
+static void DumpCXXRecordLayout(llvm::raw_ostream &OS,
+                                const CXXRecordDecl *RD, ASTContext &C,
+                                uint64_t Offset,
+                                unsigned IndentLevel,
+                                const char* Description,
+                                bool IncludeVirtualBases) {
+  const ASTRecordLayout &Info = C.getASTRecordLayout(RD);
+
+  PrintOffset(OS, Offset, IndentLevel);
+  OS << C.getTypeDeclType(const_cast<CXXRecordDecl *>(RD)).getAsString();
+  if (Description)
+    OS << ' ' << Description;
+  if (RD->isEmpty())
+    OS << " (empty)";
+  OS << '\n';
+
+  IndentLevel++;
+
+  const CXXRecordDecl *PrimaryBase = Info.getPrimaryBase();
+
+  // Vtable pointer.
+  if (RD->isDynamicClass() && !PrimaryBase) {
+    PrintOffset(OS, Offset, IndentLevel);
+    OS << '(' << RD << " vtable pointer)\n";
+  }
+  // Dump (non-virtual) bases
+  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
+         E = RD->bases_end(); I != E; ++I) {
+    assert(!I->getType()->isDependentType() &&
+           "Cannot layout class with dependent bases.");
+    if (I->isVirtual())
+      continue;
+
+    const CXXRecordDecl *Base =
+      cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+
+    uint64_t BaseOffset = Offset + Info.getBaseClassOffset(Base) / 8;
+
+    DumpCXXRecordLayout(OS, Base, C, BaseOffset, IndentLevel,
+                        Base == PrimaryBase ? "(primary base)" : "(base)",
+                        /*IncludeVirtualBases=*/false);
+  }
+
+  // Dump fields.
+  uint64_t FieldNo = 0;
+  for (CXXRecordDecl::field_iterator I = RD->field_begin(),
+         E = RD->field_end(); I != E; ++I, ++FieldNo) {
+    const FieldDecl *Field = *I;
+    uint64_t FieldOffset = Offset + Info.getFieldOffset(FieldNo) / 8;
+
+    if (const RecordType *RT = Field->getType()->getAs<RecordType>()) {
+      if (const CXXRecordDecl *D = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
+        DumpCXXRecordLayout(OS, D, C, FieldOffset, IndentLevel,
+                            Field->getNameAsCString(),
+                            /*IncludeVirtualBases=*/true);
+        continue;
+      }
+    }
+
+    PrintOffset(OS, FieldOffset, IndentLevel);
+    OS << Field->getType().getAsString() << ' ' << Field << '\n';
+  }
+
+  if (!IncludeVirtualBases)
+    return;
+
+  // Dump virtual bases.
+  for (CXXRecordDecl::base_class_const_iterator I = RD->vbases_begin(),
+         E = RD->vbases_end(); I != E; ++I) {
+    assert(I->isVirtual() && "Found non-virtual class!");
+    const CXXRecordDecl *VBase =
+      cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+
+    uint64_t VBaseOffset = Offset + Info.getVBaseClassOffset(VBase) / 8;
+    DumpCXXRecordLayout(OS, VBase, C, VBaseOffset, IndentLevel,
+                        VBase == PrimaryBase ?
+                        "(primary virtual base)" : "(virtual base)",
+                        /*IncludeVirtualBases=*/false);
+  }
+
+  OS << "  sizeof=" << Info.getSize() / 8;
+  OS << ", dsize=" << Info.getDataSize() / 8;
+  OS << ", align=" << Info.getAlignment() / 8 << '\n';
+  OS << "  nvsize=" << Info.getNonVirtualSize() / 8;
+  OS << ", nvalign=" << Info.getNonVirtualAlign() / 8 << '\n';
+  OS << '\n';
+}
+
+void ASTContext::DumpRecordLayout(const RecordDecl *RD,
+                                  llvm::raw_ostream &OS) {
+  const ASTRecordLayout &Info = getASTRecordLayout(RD);
+
+  if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
+    return DumpCXXRecordLayout(OS, CXXRD, *this, 0, 0, 0,
+                               /*IncludeVirtualBases=*/true);
+
+  OS << "Type: " << getTypeDeclType(RD).getAsString() << "\n";
+  OS << "Record: ";
+  RD->dump();
+  OS << "\nLayout: ";
+  OS << "<ASTRecordLayout\n";
+  OS << "  Size:" << Info.getSize() << "\n";
+  OS << "  DataSize:" << Info.getDataSize() << "\n";
+  OS << "  Alignment:" << Info.getAlignment() << "\n";
+  OS << "  FieldOffsets: [";
+  for (unsigned i = 0, e = Info.getFieldCount(); i != e; ++i) {
+    if (i) OS << ", ";
+    OS << Info.getFieldOffset(i);
+  }
+  OS << "]>\n";
+}
diff --git a/lib/AST/RecordLayoutBuilder.h b/lib/AST/RecordLayoutBuilder.h
new file mode 100644
index 0000000..f277c29
--- /dev/null
+++ b/lib/AST/RecordLayoutBuilder.h
@@ -0,0 +1,170 @@
+//===- ASTRecordLayoutBuilder.h - Helper class for building record layouts ===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_RECORDLAYOUTBUILDER_H
+#define LLVM_CLANG_AST_RECORDLAYOUTBUILDER_H
+
+#include "clang/AST/RecordLayout.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/System/DataTypes.h"
+#include <map>
+
+namespace clang {
+  class ASTContext;
+  class ASTRecordLayout;
+  class CXXRecordDecl;
+  class FieldDecl;
+  class ObjCImplementationDecl;
+  class ObjCInterfaceDecl;
+  class RecordDecl;
+
+class ASTRecordLayoutBuilder {
+  ASTContext &Context;
+
+  /// Size - The current size of the record layout.
+  uint64_t Size;
+  
+  /// Alignment - The current alignment of the record layout.
+  unsigned Alignment;
+  
+  llvm::SmallVector<uint64_t, 16> FieldOffsets;
+
+  /// Packed - Whether the record is packed or not.
+  bool Packed;
+
+  /// UnfilledBitsInLastByte - If the last field laid out was a bitfield,
+  /// this contains the number of bits in the last byte that can be used for
+  /// an adjacent bitfield if necessary.
+  unsigned char UnfilledBitsInLastByte;
+  
+  /// MaxFieldAlignment - The maximum allowed field alignment. This is set by
+  /// #pragma pack. 
+  unsigned MaxFieldAlignment;
+  
+  /// DataSize - The data size of the record being laid out.
+  uint64_t DataSize;
+  
+  bool IsUnion;
+
+  uint64_t NonVirtualSize;
+  unsigned NonVirtualAlignment;
+  
+  /// PrimaryBase - the primary base class (if one exists) of the class
+  /// we're laying out.
+  ASTRecordLayout::PrimaryBaseInfo PrimaryBase;
+
+  /// Bases - base classes and their offsets in the record.
+  ASTRecordLayout::BaseOffsetsMapTy Bases;
+  
+  // VBases - virtual base classes and their offsets in the record.
+  ASTRecordLayout::BaseOffsetsMapTy VBases;
+
+  /// IndirectPrimaryBases - Virtual base classes, direct or indirect, that are
+  /// primary base classes for some other direct or indirect base class.
+  llvm::SmallSet<const CXXRecordDecl*, 32> IndirectPrimaryBases;
+  
+  /// FirstNearlyEmptyVBase - The first nearly empty virtual base class in
+  /// inheritance graph order. Used for determining the primary base class.
+  const CXXRecordDecl *FirstNearlyEmptyVBase;
+
+  /// VisitedVirtualBases - A set of all the visited virtual bases, used to
+  /// avoid visiting virtual bases more than once.
+  llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBases;
+  
+  /// EmptyClassOffsets - A map from offsets to empty record decls.
+  typedef std::multimap<uint64_t, const CXXRecordDecl *> EmptyClassOffsetsTy;
+  EmptyClassOffsetsTy EmptyClassOffsets;
+  
+  ASTRecordLayoutBuilder(ASTContext &Ctx);
+
+  void Layout(const RecordDecl *D);
+  void Layout(const CXXRecordDecl *D);
+  void Layout(const ObjCInterfaceDecl *D,
+              const ObjCImplementationDecl *Impl);
+
+  void LayoutFields(const RecordDecl *D);
+  void LayoutField(const FieldDecl *D);
+  void LayoutWideBitField(uint64_t FieldSize, uint64_t TypeSize);
+  void LayoutBitField(const FieldDecl *D);
+
+  /// DeterminePrimaryBase - Determine the primary base of the given class.
+  void DeterminePrimaryBase(const CXXRecordDecl *RD);
+
+  void SelectPrimaryVBase(const CXXRecordDecl *RD);
+  
+  /// IdentifyPrimaryBases - Identify all virtual base classes, direct or 
+  /// indirect, that are primary base classes for some other direct or indirect 
+  /// base class.
+  void IdentifyPrimaryBases(const CXXRecordDecl *RD);
+  
+  bool IsNearlyEmpty(const CXXRecordDecl *RD) const;
+  
+  /// LayoutNonVirtualBases - Determines the primary base class (if any) and 
+  /// lays it out. Will then proceed to lay out all non-virtual base clasess.
+  void LayoutNonVirtualBases(const CXXRecordDecl *RD);
+
+  /// LayoutNonVirtualBase - Lays out a single non-virtual base.
+  void LayoutNonVirtualBase(const CXXRecordDecl *RD);
+
+  void AddPrimaryVirtualBaseOffsets(const CXXRecordDecl *RD, uint64_t Offset,
+                                    const CXXRecordDecl *MostDerivedClass);
+
+  /// LayoutVirtualBases - Lays out all the virtual bases.
+  void LayoutVirtualBases(const CXXRecordDecl *RD,
+                          const CXXRecordDecl *MostDerivedClass);
+
+  /// LayoutVirtualBase - Lays out a single virtual base.
+  void LayoutVirtualBase(const CXXRecordDecl *RD);
+
+  /// LayoutBase - Will lay out a base and return the offset where it was 
+  /// placed, in bits.
+  uint64_t LayoutBase(const CXXRecordDecl *RD);
+
+  /// canPlaceRecordAtOffset - Return whether a record (either a base class
+  /// or a field) can be placed at the given offset. 
+  /// Returns false if placing the record will result in two components 
+  /// (direct or indirect) of the same type having the same offset.
+  bool canPlaceRecordAtOffset(const CXXRecordDecl *RD, uint64_t Offset) const;
+
+  /// canPlaceFieldAtOffset - Return whether a field can be placed at the given
+  /// offset.
+  bool canPlaceFieldAtOffset(const FieldDecl *FD, uint64_t Offset) const;
+
+  /// UpdateEmptyClassOffsets - Called after a record (either a base class
+  /// or a field) has been placed at the given offset. Will update the
+  /// EmptyClassOffsets map if the class is empty or has any empty bases or
+  /// fields.
+  void UpdateEmptyClassOffsets(const CXXRecordDecl *RD, uint64_t Offset);
+
+  /// UpdateEmptyClassOffsets - Called after a field has been placed at the 
+  /// given offset.
+  void UpdateEmptyClassOffsets(const FieldDecl *FD, uint64_t Offset);
+  
+  /// FinishLayout - Finalize record layout. Adjust record size based on the
+  /// alignment.
+  void FinishLayout();
+
+  void UpdateAlignment(unsigned NewAlignment);
+
+  ASTRecordLayoutBuilder(const ASTRecordLayoutBuilder&);   // DO NOT IMPLEMENT
+  void operator=(const ASTRecordLayoutBuilder&); // DO NOT IMPLEMENT
+public:
+  static const ASTRecordLayout *ComputeLayout(ASTContext &Ctx,
+                                              const RecordDecl *RD);
+  static const ASTRecordLayout *ComputeLayout(ASTContext &Ctx,
+                                              const ObjCInterfaceDecl *D,
+                                            const ObjCImplementationDecl *Impl);
+  static const CXXMethodDecl *ComputeKeyFunction(const CXXRecordDecl *RD);
+};
+
+} // end namespace clang
+
+#endif
+
diff --git a/lib/AST/Stmt.cpp b/lib/AST/Stmt.cpp
new file mode 100644
index 0000000..67fd74c
--- /dev/null
+++ b/lib/AST/Stmt.cpp
@@ -0,0 +1,708 @@
+//===--- Stmt.cpp - Statement AST Node Implementation ---------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Stmt class and statement subclasses.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/Stmt.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/ExprObjC.h"
+#include "clang/AST/StmtCXX.h"
+#include "clang/AST/StmtObjC.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTDiagnostic.h"
+#include "clang/Basic/TargetInfo.h"
+#include <cstdio>
+using namespace clang;
+
+static struct StmtClassNameTable {
+  const char *Name;
+  unsigned Counter;
+  unsigned Size;
+} StmtClassInfo[Stmt::lastExprConstant+1];
+
+static StmtClassNameTable &getStmtInfoTableEntry(Stmt::StmtClass E) {
+  static bool Initialized = false;
+  if (Initialized)
+    return StmtClassInfo[E];
+
+  // Intialize the table on the first use.
+  Initialized = true;
+#define ABSTRACT_EXPR(CLASS, PARENT)
+#define STMT(CLASS, PARENT) \
+  StmtClassInfo[(unsigned)Stmt::CLASS##Class].Name = #CLASS;    \
+  StmtClassInfo[(unsigned)Stmt::CLASS##Class].Size = sizeof(CLASS);
+#include "clang/AST/StmtNodes.def"
+
+  return StmtClassInfo[E];
+}
+
+const char *Stmt::getStmtClassName() const {
+  return getStmtInfoTableEntry((StmtClass)sClass).Name;
+}
+
+void Stmt::PrintStats() {
+  // Ensure the table is primed.
+  getStmtInfoTableEntry(Stmt::NullStmtClass);
+
+  unsigned sum = 0;
+  fprintf(stderr, "*** Stmt/Expr Stats:\n");
+  for (int i = 0; i != Stmt::lastExprConstant+1; i++) {
+    if (StmtClassInfo[i].Name == 0) continue;
+    sum += StmtClassInfo[i].Counter;
+  }
+  fprintf(stderr, "  %d stmts/exprs total.\n", sum);
+  sum = 0;
+  for (int i = 0; i != Stmt::lastExprConstant+1; i++) {
+    if (StmtClassInfo[i].Name == 0) continue;
+    if (StmtClassInfo[i].Counter == 0) continue;
+    fprintf(stderr, "    %d %s, %d each (%d bytes)\n",
+            StmtClassInfo[i].Counter, StmtClassInfo[i].Name,
+            StmtClassInfo[i].Size,
+            StmtClassInfo[i].Counter*StmtClassInfo[i].Size);
+    sum += StmtClassInfo[i].Counter*StmtClassInfo[i].Size;
+  }
+  fprintf(stderr, "Total bytes = %d\n", sum);
+}
+
+void Stmt::addStmtClass(StmtClass s) {
+  ++getStmtInfoTableEntry(s).Counter;
+}
+
+static bool StatSwitch = false;
+
+bool Stmt::CollectingStats(bool Enable) {
+  if (Enable) StatSwitch = true;
+  return StatSwitch;
+}
+
+void CompoundStmt::setStmts(ASTContext &C, Stmt **Stmts, unsigned NumStmts) {
+  if (this->Body)
+    C.Deallocate(Body);
+  this->NumStmts = NumStmts;
+
+  Body = new (C) Stmt*[NumStmts];
+  memcpy(Body, Stmts, sizeof(Stmt *) * NumStmts);
+}
+
+const char *LabelStmt::getName() const {
+  return getID()->getNameStart();
+}
+
+// This is defined here to avoid polluting Stmt.h with importing Expr.h
+SourceRange ReturnStmt::getSourceRange() const {
+  if (RetExpr)
+    return SourceRange(RetLoc, RetExpr->getLocEnd());
+  else
+    return SourceRange(RetLoc);
+}
+
+bool Stmt::hasImplicitControlFlow() const {
+  switch (sClass) {
+    default:
+      return false;
+
+    case CallExprClass:
+    case ConditionalOperatorClass:
+    case ChooseExprClass:
+    case StmtExprClass:
+    case DeclStmtClass:
+      return true;
+
+    case Stmt::BinaryOperatorClass: {
+      const BinaryOperator* B = cast<BinaryOperator>(this);
+      if (B->isLogicalOp() || B->getOpcode() == BinaryOperator::Comma)
+        return true;
+      else
+        return false;
+    }
+  }
+}
+
+Expr *AsmStmt::getOutputExpr(unsigned i) {
+  return cast<Expr>(Exprs[i]);
+}
+
+/// getOutputConstraint - Return the constraint string for the specified
+/// output operand.  All output constraints are known to be non-empty (either
+/// '=' or '+').
+llvm::StringRef AsmStmt::getOutputConstraint(unsigned i) const {
+  return getOutputConstraintLiteral(i)->getString();
+}
+
+/// getNumPlusOperands - Return the number of output operands that have a "+"
+/// constraint.
+unsigned AsmStmt::getNumPlusOperands() const {
+  unsigned Res = 0;
+  for (unsigned i = 0, e = getNumOutputs(); i != e; ++i)
+    if (isOutputPlusConstraint(i))
+      ++Res;
+  return Res;
+}
+
+Expr *AsmStmt::getInputExpr(unsigned i) {
+  return cast<Expr>(Exprs[i + NumOutputs]);
+}
+
+/// getInputConstraint - Return the specified input constraint.  Unlike output
+/// constraints, these can be empty.
+llvm::StringRef AsmStmt::getInputConstraint(unsigned i) const {
+  return getInputConstraintLiteral(i)->getString();
+}
+
+
+void AsmStmt::setOutputsAndInputsAndClobbers(ASTContext &C,
+                                             IdentifierInfo **Names,
+                                             StringLiteral **Constraints,
+                                             Stmt **Exprs,
+                                             unsigned NumOutputs,
+                                             unsigned NumInputs,                                      
+                                             StringLiteral **Clobbers,
+                                             unsigned NumClobbers) {
+  this->NumOutputs = NumOutputs;
+  this->NumInputs = NumInputs;
+  this->NumClobbers = NumClobbers;
+
+  unsigned NumExprs = NumOutputs + NumInputs;
+  
+  C.Deallocate(this->Names);
+  this->Names = new (C) IdentifierInfo*[NumExprs];
+  std::copy(Names, Names + NumExprs, this->Names);
+  
+  C.Deallocate(this->Exprs);
+  this->Exprs = new (C) Stmt*[NumExprs];
+  std::copy(Exprs, Exprs + NumExprs, this->Exprs);
+  
+  C.Deallocate(this->Constraints);
+  this->Constraints = new (C) StringLiteral*[NumExprs];
+  std::copy(Constraints, Constraints + NumExprs, this->Constraints);
+  
+  C.Deallocate(this->Clobbers);
+  this->Clobbers = new (C) StringLiteral*[NumClobbers];
+  std::copy(Clobbers, Clobbers + NumClobbers, this->Clobbers);
+}
+
+/// getNamedOperand - Given a symbolic operand reference like %[foo],
+/// translate this into a numeric value needed to reference the same operand.
+/// This returns -1 if the operand name is invalid.
+int AsmStmt::getNamedOperand(llvm::StringRef SymbolicName) const {
+  unsigned NumPlusOperands = 0;
+
+  // Check if this is an output operand.
+  for (unsigned i = 0, e = getNumOutputs(); i != e; ++i) {
+    if (getOutputName(i) == SymbolicName)
+      return i;
+  }
+
+  for (unsigned i = 0, e = getNumInputs(); i != e; ++i)
+    if (getInputName(i) == SymbolicName)
+      return getNumOutputs() + NumPlusOperands + i;
+
+  // Not found.
+  return -1;
+}
+
+/// AnalyzeAsmString - Analyze the asm string of the current asm, decomposing
+/// it into pieces.  If the asm string is erroneous, emit errors and return
+/// true, otherwise return false.
+unsigned AsmStmt::AnalyzeAsmString(llvm::SmallVectorImpl<AsmStringPiece>&Pieces,
+                                   ASTContext &C, unsigned &DiagOffs) const {
+  const char *StrStart = getAsmString()->getStrData();
+  const char *StrEnd = StrStart + getAsmString()->getByteLength();
+  const char *CurPtr = StrStart;
+
+  // "Simple" inline asms have no constraints or operands, just convert the asm
+  // string to escape $'s.
+  if (isSimple()) {
+    std::string Result;
+    for (; CurPtr != StrEnd; ++CurPtr) {
+      switch (*CurPtr) {
+      case '$':
+        Result += "$$";
+        break;
+      default:
+        Result += *CurPtr;
+        break;
+      }
+    }
+    Pieces.push_back(AsmStringPiece(Result));
+    return 0;
+  }
+
+  // CurStringPiece - The current string that we are building up as we scan the
+  // asm string.
+  std::string CurStringPiece;
+
+  bool HasVariants = !C.Target.hasNoAsmVariants();
+  
+  while (1) {
+    // Done with the string?
+    if (CurPtr == StrEnd) {
+      if (!CurStringPiece.empty())
+        Pieces.push_back(AsmStringPiece(CurStringPiece));
+      return 0;
+    }
+
+    char CurChar = *CurPtr++;
+    switch (CurChar) {
+    case '$': CurStringPiece += "$$"; continue;
+    case '{': CurStringPiece += (HasVariants ? "$(" : "{"); continue;
+    case '|': CurStringPiece += (HasVariants ? "$|" : "|"); continue;
+    case '}': CurStringPiece += (HasVariants ? "$)" : "}"); continue;
+    case '%':
+      break;
+    default:
+      CurStringPiece += CurChar;
+      continue;
+    }
+    
+    // Escaped "%" character in asm string.
+    if (CurPtr == StrEnd) {
+      // % at end of string is invalid (no escape).
+      DiagOffs = CurPtr-StrStart-1;
+      return diag::err_asm_invalid_escape;
+    }
+
+    char EscapedChar = *CurPtr++;
+    if (EscapedChar == '%') {  // %% -> %
+      // Escaped percentage sign.
+      CurStringPiece += '%';
+      continue;
+    }
+
+    if (EscapedChar == '=') {  // %= -> Generate an unique ID.
+      CurStringPiece += "${:uid}";
+      continue;
+    }
+
+    // Otherwise, we have an operand.  If we have accumulated a string so far,
+    // add it to the Pieces list.
+    if (!CurStringPiece.empty()) {
+      Pieces.push_back(AsmStringPiece(CurStringPiece));
+      CurStringPiece.clear();
+    }
+
+    // Handle %x4 and %x[foo] by capturing x as the modifier character.
+    char Modifier = '\0';
+    if (isalpha(EscapedChar)) {
+      Modifier = EscapedChar;
+      EscapedChar = *CurPtr++;
+    }
+
+    if (isdigit(EscapedChar)) {
+      // %n - Assembler operand n
+      unsigned N = 0;
+
+      --CurPtr;
+      while (CurPtr != StrEnd && isdigit(*CurPtr))
+        N = N*10 + ((*CurPtr++)-'0');
+
+      unsigned NumOperands =
+        getNumOutputs() + getNumPlusOperands() + getNumInputs();
+      if (N >= NumOperands) {
+        DiagOffs = CurPtr-StrStart-1;
+        return diag::err_asm_invalid_operand_number;
+      }
+
+      Pieces.push_back(AsmStringPiece(N, Modifier));
+      continue;
+    }
+
+    // Handle %[foo], a symbolic operand reference.
+    if (EscapedChar == '[') {
+      DiagOffs = CurPtr-StrStart-1;
+
+      // Find the ']'.
+      const char *NameEnd = (const char*)memchr(CurPtr, ']', StrEnd-CurPtr);
+      if (NameEnd == 0)
+        return diag::err_asm_unterminated_symbolic_operand_name;
+      if (NameEnd == CurPtr)
+        return diag::err_asm_empty_symbolic_operand_name;
+
+      llvm::StringRef SymbolicName(CurPtr, NameEnd - CurPtr);
+
+      int N = getNamedOperand(SymbolicName);
+      if (N == -1) {
+        // Verify that an operand with that name exists.
+        DiagOffs = CurPtr-StrStart;
+        return diag::err_asm_unknown_symbolic_operand_name;
+      }
+      Pieces.push_back(AsmStringPiece(N, Modifier));
+
+      CurPtr = NameEnd+1;
+      continue;
+    }
+
+    DiagOffs = CurPtr-StrStart-1;
+    return diag::err_asm_invalid_escape;
+  }
+}
+
+QualType CXXCatchStmt::getCaughtType() const {
+  if (ExceptionDecl)
+    return ExceptionDecl->getType();
+  return QualType();
+}
+
+//===----------------------------------------------------------------------===//
+// Constructors
+//===----------------------------------------------------------------------===//
+
+AsmStmt::AsmStmt(ASTContext &C, SourceLocation asmloc, bool issimple, 
+                 bool isvolatile, bool msasm, 
+                 unsigned numoutputs, unsigned numinputs,
+                 IdentifierInfo **names, StringLiteral **constraints,
+                 Expr **exprs, StringLiteral *asmstr, unsigned numclobbers,
+                 StringLiteral **clobbers, SourceLocation rparenloc)
+  : Stmt(AsmStmtClass), AsmLoc(asmloc), RParenLoc(rparenloc), AsmStr(asmstr)
+  , IsSimple(issimple), IsVolatile(isvolatile), MSAsm(msasm)
+  , NumOutputs(numoutputs), NumInputs(numinputs), NumClobbers(numclobbers) {
+
+  unsigned NumExprs = NumOutputs +NumInputs;
+    
+  Names = new (C) IdentifierInfo*[NumExprs];
+  std::copy(names, names + NumExprs, Names);
+
+  Exprs = new (C) Stmt*[NumExprs];
+  std::copy(exprs, exprs + NumExprs, Exprs);
+
+  Constraints = new (C) StringLiteral*[NumExprs];
+  std::copy(constraints, constraints + NumExprs, Constraints);
+
+  Clobbers = new (C) StringLiteral*[NumClobbers];
+  std::copy(clobbers, clobbers + NumClobbers, Clobbers);
+}
+
+ObjCForCollectionStmt::ObjCForCollectionStmt(Stmt *Elem, Expr *Collect,
+                                             Stmt *Body,  SourceLocation FCL,
+                                             SourceLocation RPL)
+: Stmt(ObjCForCollectionStmtClass) {
+  SubExprs[ELEM] = Elem;
+  SubExprs[COLLECTION] = reinterpret_cast<Stmt*>(Collect);
+  SubExprs[BODY] = Body;
+  ForLoc = FCL;
+  RParenLoc = RPL;
+}
+
+ObjCAtTryStmt::ObjCAtTryStmt(SourceLocation atTryLoc, Stmt *atTryStmt,
+                             Stmt **CatchStmts, unsigned NumCatchStmts,
+                             Stmt *atFinallyStmt)
+  : Stmt(ObjCAtTryStmtClass), AtTryLoc(atTryLoc),
+    NumCatchStmts(NumCatchStmts), HasFinally(atFinallyStmt != 0)
+{
+  Stmt **Stmts = getStmts();
+  Stmts[0] = atTryStmt;
+  for (unsigned I = 0; I != NumCatchStmts; ++I)
+    Stmts[I + 1] = CatchStmts[I];
+  
+  if (HasFinally)
+    Stmts[NumCatchStmts + 1] = atFinallyStmt;
+}
+
+ObjCAtTryStmt *ObjCAtTryStmt::Create(ASTContext &Context, 
+                                     SourceLocation atTryLoc, 
+                                     Stmt *atTryStmt,
+                                     Stmt **CatchStmts, 
+                                     unsigned NumCatchStmts,
+                                     Stmt *atFinallyStmt) {
+  unsigned Size = sizeof(ObjCAtTryStmt) + 
+    (1 + NumCatchStmts + (atFinallyStmt != 0)) * sizeof(Stmt *);
+  void *Mem = Context.Allocate(Size, llvm::alignof<ObjCAtTryStmt>());
+  return new (Mem) ObjCAtTryStmt(atTryLoc, atTryStmt, CatchStmts, NumCatchStmts,
+                                 atFinallyStmt);
+}
+
+ObjCAtTryStmt *ObjCAtTryStmt::CreateEmpty(ASTContext &Context, 
+                                                 unsigned NumCatchStmts,
+                                                 bool HasFinally) {
+  unsigned Size = sizeof(ObjCAtTryStmt) + 
+    (1 + NumCatchStmts + HasFinally) * sizeof(Stmt *);
+  void *Mem = Context.Allocate(Size, llvm::alignof<ObjCAtTryStmt>());
+  return new (Mem) ObjCAtTryStmt(EmptyShell(), NumCatchStmts, HasFinally);  
+}
+
+SourceRange ObjCAtTryStmt::getSourceRange() const {
+  SourceLocation EndLoc;
+  if (HasFinally)
+    EndLoc = getFinallyStmt()->getLocEnd();
+  else if (NumCatchStmts)
+    EndLoc = getCatchStmt(NumCatchStmts - 1)->getLocEnd();
+  else
+    EndLoc = getTryBody()->getLocEnd();
+  
+  return SourceRange(AtTryLoc, EndLoc);
+}
+
+CXXTryStmt *CXXTryStmt::Create(ASTContext &C, SourceLocation tryLoc,
+                               Stmt *tryBlock, Stmt **handlers, 
+                               unsigned numHandlers) {
+  std::size_t Size = sizeof(CXXTryStmt);
+  Size += ((numHandlers + 1) * sizeof(Stmt));
+
+  void *Mem = C.Allocate(Size, llvm::alignof<CXXTryStmt>());
+  return new (Mem) CXXTryStmt(tryLoc, tryBlock, handlers, numHandlers);
+}
+
+CXXTryStmt::CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock,
+                       Stmt **handlers, unsigned numHandlers)
+  : Stmt(CXXTryStmtClass), TryLoc(tryLoc), NumHandlers(numHandlers) {
+  Stmt **Stmts = reinterpret_cast<Stmt **>(this + 1);
+  Stmts[0] = tryBlock;
+  std::copy(handlers, handlers + NumHandlers, Stmts + 1);
+}
+
+//===----------------------------------------------------------------------===//
+// AST Destruction.
+//===----------------------------------------------------------------------===//
+
+void Stmt::DestroyChildren(ASTContext &C) {
+  for (child_iterator I = child_begin(), E = child_end(); I !=E; )
+    if (Stmt* Child = *I++) Child->Destroy(C);
+}
+
+static void BranchDestroy(ASTContext &C, Stmt *S, Stmt **SubExprs,
+                          unsigned NumExprs) {
+  // We do not use child_iterator here because that will include
+  // the expressions referenced by the condition variable.
+  for (Stmt **I = SubExprs, **E = SubExprs + NumExprs; I != E; ++I)
+    if (Stmt *Child = *I) Child->Destroy(C);
+  
+  S->~Stmt();
+  C.Deallocate((void *) S);
+}
+
+void Stmt::DoDestroy(ASTContext &C) {
+  DestroyChildren(C);
+  this->~Stmt();
+  C.Deallocate((void *)this);
+}
+
+void CXXCatchStmt::DoDestroy(ASTContext& C) {
+  if (ExceptionDecl)
+    ExceptionDecl->Destroy(C);
+  Stmt::DoDestroy(C);
+}
+
+void DeclStmt::DoDestroy(ASTContext &C) {
+  // Don't use StmtIterator to iterate over the Decls, as that can recurse
+  // into VLA size expressions (which are owned by the VLA).  Further, Decls
+  // are owned by the DeclContext, and will be destroyed with them.
+  if (DG.isDeclGroup())
+    DG.getDeclGroup().Destroy(C);
+}
+
+void IfStmt::DoDestroy(ASTContext &C) {
+  BranchDestroy(C, this, SubExprs, END_EXPR);
+}
+
+void ForStmt::DoDestroy(ASTContext &C) {
+  BranchDestroy(C, this, SubExprs, END_EXPR);
+}
+
+void SwitchStmt::DoDestroy(ASTContext &C) {
+  // Destroy the SwitchCase statements in this switch. In the normal
+  // case, this loop will merely decrement the reference counts from
+  // the Retain() calls in addSwitchCase();
+  SwitchCase *SC = FirstCase;
+  while (SC) {
+    SwitchCase *Next = SC->getNextSwitchCase();
+    SC->Destroy(C);
+    SC = Next;
+  }
+  
+  BranchDestroy(C, this, SubExprs, END_EXPR);
+}
+
+void WhileStmt::DoDestroy(ASTContext &C) {
+  BranchDestroy(C, this, SubExprs, END_EXPR);
+}
+
+void AsmStmt::DoDestroy(ASTContext &C) {
+  DestroyChildren(C);
+  
+  C.Deallocate(Names);
+  C.Deallocate(Constraints);
+  C.Deallocate(Exprs);
+  C.Deallocate(Clobbers);
+  
+  this->~AsmStmt();
+  C.Deallocate((void *)this);
+}
+
+//===----------------------------------------------------------------------===//
+//  Child Iterators for iterating over subexpressions/substatements
+//===----------------------------------------------------------------------===//
+
+// DeclStmt
+Stmt::child_iterator DeclStmt::child_begin() {
+  return StmtIterator(DG.begin(), DG.end());
+}
+
+Stmt::child_iterator DeclStmt::child_end() {
+  return StmtIterator(DG.end(), DG.end());
+}
+
+// NullStmt
+Stmt::child_iterator NullStmt::child_begin() { return child_iterator(); }
+Stmt::child_iterator NullStmt::child_end() { return child_iterator(); }
+
+// CompoundStmt
+Stmt::child_iterator CompoundStmt::child_begin() { return &Body[0]; }
+Stmt::child_iterator CompoundStmt::child_end() { return &Body[0]+NumStmts; }
+
+// CaseStmt
+Stmt::child_iterator CaseStmt::child_begin() { return &SubExprs[0]; }
+Stmt::child_iterator CaseStmt::child_end() { return &SubExprs[END_EXPR]; }
+
+// DefaultStmt
+Stmt::child_iterator DefaultStmt::child_begin() { return &SubStmt; }
+Stmt::child_iterator DefaultStmt::child_end() { return &SubStmt+1; }
+
+// LabelStmt
+Stmt::child_iterator LabelStmt::child_begin() { return &SubStmt; }
+Stmt::child_iterator LabelStmt::child_end() { return &SubStmt+1; }
+
+// IfStmt
+Stmt::child_iterator IfStmt::child_begin() {
+  return child_iterator(Var, &SubExprs[0]);
+}
+Stmt::child_iterator IfStmt::child_end() {
+  return child_iterator(0, &SubExprs[0]+END_EXPR);
+}
+
+// SwitchStmt
+Stmt::child_iterator SwitchStmt::child_begin() {
+  return child_iterator(Var, &SubExprs[0]);
+}
+Stmt::child_iterator SwitchStmt::child_end() {
+  return child_iterator(0, &SubExprs[0]+END_EXPR);
+}
+
+// WhileStmt
+Stmt::child_iterator WhileStmt::child_begin() {
+  return child_iterator(Var, &SubExprs[0]);
+}
+Stmt::child_iterator WhileStmt::child_end() {
+  return child_iterator(0, &SubExprs[0]+END_EXPR);
+}
+
+// DoStmt
+Stmt::child_iterator DoStmt::child_begin() { return &SubExprs[0]; }
+Stmt::child_iterator DoStmt::child_end() { return &SubExprs[0]+END_EXPR; }
+
+// ForStmt
+Stmt::child_iterator ForStmt::child_begin() {
+  return child_iterator(CondVar, &SubExprs[0]);
+}
+Stmt::child_iterator ForStmt::child_end() {
+  return child_iterator(0, &SubExprs[0]+END_EXPR);
+}
+
+// ObjCForCollectionStmt
+Stmt::child_iterator ObjCForCollectionStmt::child_begin() {
+  return &SubExprs[0];
+}
+Stmt::child_iterator ObjCForCollectionStmt::child_end() {
+  return &SubExprs[0]+END_EXPR;
+}
+
+// GotoStmt
+Stmt::child_iterator GotoStmt::child_begin() { return child_iterator(); }
+Stmt::child_iterator GotoStmt::child_end() { return child_iterator(); }
+
+// IndirectGotoStmt
+Expr* IndirectGotoStmt::getTarget() { return cast<Expr>(Target); }
+const Expr* IndirectGotoStmt::getTarget() const { return cast<Expr>(Target); }
+
+Stmt::child_iterator IndirectGotoStmt::child_begin() { return &Target; }
+Stmt::child_iterator IndirectGotoStmt::child_end() { return &Target+1; }
+
+// ContinueStmt
+Stmt::child_iterator ContinueStmt::child_begin() { return child_iterator(); }
+Stmt::child_iterator ContinueStmt::child_end() { return child_iterator(); }
+
+// BreakStmt
+Stmt::child_iterator BreakStmt::child_begin() { return child_iterator(); }
+Stmt::child_iterator BreakStmt::child_end() { return child_iterator(); }
+
+// ReturnStmt
+const Expr* ReturnStmt::getRetValue() const {
+  return cast_or_null<Expr>(RetExpr);
+}
+Expr* ReturnStmt::getRetValue() {
+  return cast_or_null<Expr>(RetExpr);
+}
+
+Stmt::child_iterator ReturnStmt::child_begin() {
+  return &RetExpr;
+}
+Stmt::child_iterator ReturnStmt::child_end() {
+  return RetExpr ? &RetExpr+1 : &RetExpr;
+}
+
+// AsmStmt
+Stmt::child_iterator AsmStmt::child_begin() {
+  return NumOutputs + NumInputs == 0 ? 0 : &Exprs[0];
+}
+Stmt::child_iterator AsmStmt::child_end() {
+  return NumOutputs + NumInputs == 0 ? 0 : &Exprs[0] + NumOutputs + NumInputs;
+}
+
+// ObjCAtCatchStmt
+Stmt::child_iterator ObjCAtCatchStmt::child_begin() { return &Body; }
+Stmt::child_iterator ObjCAtCatchStmt::child_end() { return &Body + 1; }
+
+// ObjCAtFinallyStmt
+Stmt::child_iterator ObjCAtFinallyStmt::child_begin() { return &AtFinallyStmt; }
+Stmt::child_iterator ObjCAtFinallyStmt::child_end() { return &AtFinallyStmt+1; }
+
+// ObjCAtTryStmt
+Stmt::child_iterator ObjCAtTryStmt::child_begin() { return getStmts(); }
+
+Stmt::child_iterator ObjCAtTryStmt::child_end() {
+  return getStmts() + 1 + NumCatchStmts + HasFinally;
+}
+
+// ObjCAtThrowStmt
+Stmt::child_iterator ObjCAtThrowStmt::child_begin() {
+  return &Throw;
+}
+
+Stmt::child_iterator ObjCAtThrowStmt::child_end() {
+  return &Throw+1;
+}
+
+// ObjCAtSynchronizedStmt
+Stmt::child_iterator ObjCAtSynchronizedStmt::child_begin() {
+  return &SubStmts[0];
+}
+
+Stmt::child_iterator ObjCAtSynchronizedStmt::child_end() {
+  return &SubStmts[0]+END_EXPR;
+}
+
+// CXXCatchStmt
+Stmt::child_iterator CXXCatchStmt::child_begin() {
+  return &HandlerBlock;
+}
+
+Stmt::child_iterator CXXCatchStmt::child_end() {
+  return &HandlerBlock + 1;
+}
+
+// CXXTryStmt
+Stmt::child_iterator CXXTryStmt::child_begin() {
+  return reinterpret_cast<Stmt **>(this + 1);
+}
+
+Stmt::child_iterator CXXTryStmt::child_end() {
+  return reinterpret_cast<Stmt **>(this + 1) + NumHandlers + 1;
+}
diff --git a/lib/AST/StmtDumper.cpp b/lib/AST/StmtDumper.cpp
new file mode 100644
index 0000000..ca62ed1
--- /dev/null
+++ b/lib/AST/StmtDumper.cpp
@@ -0,0 +1,645 @@
+//===--- StmtDumper.cpp - Dumping implementation for Stmt ASTs ------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Stmt::dump/Stmt::print methods, which dump out the
+// AST in a form that exposes type details and other fields.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/StmtVisitor.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/PrettyPrinter.h"
+#include "clang/Basic/SourceManager.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace clang;
+
+//===----------------------------------------------------------------------===//
+// StmtDumper Visitor
+//===----------------------------------------------------------------------===//
+
+namespace  {
+  class StmtDumper : public StmtVisitor<StmtDumper> {
+    SourceManager *SM;
+    llvm::raw_ostream &OS;
+    unsigned IndentLevel;
+
+    /// MaxDepth - When doing a normal dump (not dumpAll) we only want to dump
+    /// the first few levels of an AST.  This keeps track of how many ast levels
+    /// are left.
+    unsigned MaxDepth;
+
+    /// LastLocFilename/LastLocLine - Keep track of the last location we print
+    /// out so that we can print out deltas from then on out.
+    const char *LastLocFilename;
+    unsigned LastLocLine;
+
+  public:
+    StmtDumper(SourceManager *sm, llvm::raw_ostream &os, unsigned maxDepth)
+      : SM(sm), OS(os), IndentLevel(0-1), MaxDepth(maxDepth) {
+      LastLocFilename = "";
+      LastLocLine = ~0U;
+    }
+
+    void DumpSubTree(Stmt *S) {
+      // Prune the recursion if not using dump all.
+      if (MaxDepth == 0) return;
+
+      ++IndentLevel;
+      if (S) {
+        if (DeclStmt* DS = dyn_cast<DeclStmt>(S))
+          VisitDeclStmt(DS);
+        else {
+          Visit(S);
+
+          // Print out children.
+          Stmt::child_iterator CI = S->child_begin(), CE = S->child_end();
+          if (CI != CE) {
+            while (CI != CE) {
+              OS << '\n';
+              DumpSubTree(*CI++);
+            }
+          }
+          OS << ')';
+        }
+      } else {
+        Indent();
+        OS << "<<<NULL>>>";
+      }
+      --IndentLevel;
+    }
+
+    void DumpDeclarator(Decl *D);
+
+    void Indent() const {
+      for (int i = 0, e = IndentLevel; i < e; ++i)
+        OS << "  ";
+    }
+
+    void DumpType(QualType T) {
+      OS << "'" << T.getAsString() << "'";
+
+      if (!T.isNull()) {
+        // If the type is sugared, also dump a (shallow) desugared type.
+        QualType Simplified = T.getDesugaredType();
+        if (Simplified != T)
+          OS << ":'" << Simplified.getAsString() << "'";
+      }
+    }
+    void DumpStmt(const Stmt *Node) {
+      Indent();
+      OS << "(" << Node->getStmtClassName()
+         << " " << (void*)Node;
+      DumpSourceRange(Node);
+    }
+    void DumpExpr(const Expr *Node) {
+      DumpStmt(Node);
+      OS << ' ';
+      DumpType(Node->getType());
+    }
+    void DumpSourceRange(const Stmt *Node);
+    void DumpLocation(SourceLocation Loc);
+
+    // Stmts.
+    void VisitStmt(Stmt *Node);
+    void VisitDeclStmt(DeclStmt *Node);
+    void VisitLabelStmt(LabelStmt *Node);
+    void VisitGotoStmt(GotoStmt *Node);
+
+    // Exprs
+    void VisitExpr(Expr *Node);
+    void VisitCastExpr(CastExpr *Node);
+    void VisitImplicitCastExpr(ImplicitCastExpr *Node);
+    void VisitDeclRefExpr(DeclRefExpr *Node);
+    void VisitPredefinedExpr(PredefinedExpr *Node);
+    void VisitCharacterLiteral(CharacterLiteral *Node);
+    void VisitIntegerLiteral(IntegerLiteral *Node);
+    void VisitFloatingLiteral(FloatingLiteral *Node);
+    void VisitStringLiteral(StringLiteral *Str);
+    void VisitUnaryOperator(UnaryOperator *Node);
+    void VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *Node);
+    void VisitMemberExpr(MemberExpr *Node);
+    void VisitExtVectorElementExpr(ExtVectorElementExpr *Node);
+    void VisitBinaryOperator(BinaryOperator *Node);
+    void VisitCompoundAssignOperator(CompoundAssignOperator *Node);
+    void VisitAddrLabelExpr(AddrLabelExpr *Node);
+    void VisitTypesCompatibleExpr(TypesCompatibleExpr *Node);
+
+    // C++
+    void VisitCXXNamedCastExpr(CXXNamedCastExpr *Node);
+    void VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node);
+    void VisitCXXThisExpr(CXXThisExpr *Node);
+    void VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node);
+    void VisitCXXConstructExpr(CXXConstructExpr *Node);
+    void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *Node);
+    void VisitCXXExprWithTemporaries(CXXExprWithTemporaries *Node);
+    void VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node);
+    void DumpCXXTemporary(CXXTemporary *Temporary);
+
+    // ObjC
+    void VisitObjCAtCatchStmt(ObjCAtCatchStmt *Node);
+    void VisitObjCEncodeExpr(ObjCEncodeExpr *Node);
+    void VisitObjCMessageExpr(ObjCMessageExpr* Node);
+    void VisitObjCSelectorExpr(ObjCSelectorExpr *Node);
+    void VisitObjCProtocolExpr(ObjCProtocolExpr *Node);
+    void VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node);
+    void VisitObjCImplicitSetterGetterRefExpr(
+                                          ObjCImplicitSetterGetterRefExpr *Node);
+    void VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node);
+    void VisitObjCSuperExpr(ObjCSuperExpr *Node);
+  };
+}
+
+//===----------------------------------------------------------------------===//
+//  Utilities
+//===----------------------------------------------------------------------===//
+
+void StmtDumper::DumpLocation(SourceLocation Loc) {
+  SourceLocation SpellingLoc = SM->getSpellingLoc(Loc);
+
+  if (SpellingLoc.isInvalid()) {
+    OS << "<invalid sloc>";
+    return;
+  }
+
+  // The general format we print out is filename:line:col, but we drop pieces
+  // that haven't changed since the last loc printed.
+  PresumedLoc PLoc = SM->getPresumedLoc(SpellingLoc);
+
+  if (strcmp(PLoc.getFilename(), LastLocFilename) != 0) {
+    OS << PLoc.getFilename() << ':' << PLoc.getLine()
+       << ':' << PLoc.getColumn();
+    LastLocFilename = PLoc.getFilename();
+    LastLocLine = PLoc.getLine();
+  } else if (PLoc.getLine() != LastLocLine) {
+    OS << "line" << ':' << PLoc.getLine()
+       << ':' << PLoc.getColumn();
+    LastLocLine = PLoc.getLine();
+  } else {
+    OS << "col" << ':' << PLoc.getColumn();
+  }
+}
+
+void StmtDumper::DumpSourceRange(const Stmt *Node) {
+  // Can't translate locations if a SourceManager isn't available.
+  if (SM == 0) return;
+
+  // TODO: If the parent expression is available, we can print a delta vs its
+  // location.
+  SourceRange R = Node->getSourceRange();
+
+  OS << " <";
+  DumpLocation(R.getBegin());
+  if (R.getBegin() != R.getEnd()) {
+    OS << ", ";
+    DumpLocation(R.getEnd());
+  }
+  OS << ">";
+
+  // <t2.c:123:421[blah], t2.c:412:321>
+
+}
+
+
+//===----------------------------------------------------------------------===//
+//  Stmt printing methods.
+//===----------------------------------------------------------------------===//
+
+void StmtDumper::VisitStmt(Stmt *Node) {
+  DumpStmt(Node);
+}
+
+void StmtDumper::DumpDeclarator(Decl *D) {
+  // FIXME: Need to complete/beautify this... this code simply shows the
+  // nodes are where they need to be.
+  if (TypedefDecl *localType = dyn_cast<TypedefDecl>(D)) {
+    OS << "\"typedef " << localType->getUnderlyingType().getAsString()
+       << ' ' << localType << '"';
+  } else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
+    OS << "\"";
+    // Emit storage class for vardecls.
+    if (VarDecl *V = dyn_cast<VarDecl>(VD)) {
+      if (V->getStorageClass() != VarDecl::None)
+        OS << VarDecl::getStorageClassSpecifierString(V->getStorageClass())
+           << " ";
+    }
+
+    std::string Name = VD->getNameAsString();
+    VD->getType().getAsStringInternal(Name,
+                          PrintingPolicy(VD->getASTContext().getLangOptions()));
+    OS << Name;
+
+    // If this is a vardecl with an initializer, emit it.
+    if (VarDecl *V = dyn_cast<VarDecl>(VD)) {
+      if (V->getInit()) {
+        OS << " =\n";
+        DumpSubTree(V->getInit());
+      }
+    }
+    OS << '"';
+  } else if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
+    // print a free standing tag decl (e.g. "struct x;").
+    const char *tagname;
+    if (const IdentifierInfo *II = TD->getIdentifier())
+      tagname = II->getNameStart();
+    else
+      tagname = "<anonymous>";
+    OS << '"' << TD->getKindName() << ' ' << tagname << ";\"";
+    // FIXME: print tag bodies.
+  } else if (UsingDirectiveDecl *UD = dyn_cast<UsingDirectiveDecl>(D)) {
+    // print using-directive decl (e.g. "using namespace x;")
+    const char *ns;
+    if (const IdentifierInfo *II = UD->getNominatedNamespace()->getIdentifier())
+      ns = II->getNameStart();
+    else
+      ns = "<anonymous>";
+    OS << '"' << UD->getDeclKindName() << ns << ";\"";
+  } else {
+    assert(0 && "Unexpected decl");
+  }
+}
+
+void StmtDumper::VisitDeclStmt(DeclStmt *Node) {
+  DumpStmt(Node);
+  OS << "\n";
+  for (DeclStmt::decl_iterator DI = Node->decl_begin(), DE = Node->decl_end();
+       DI != DE; ++DI) {
+    Decl* D = *DI;
+    ++IndentLevel;
+    Indent();
+    OS << (void*) D << " ";
+    DumpDeclarator(D);
+    if (DI+1 != DE)
+      OS << "\n";
+    --IndentLevel;
+  }
+}
+
+void StmtDumper::VisitLabelStmt(LabelStmt *Node) {
+  DumpStmt(Node);
+  OS << " '" << Node->getName() << "'";
+}
+
+void StmtDumper::VisitGotoStmt(GotoStmt *Node) {
+  DumpStmt(Node);
+  OS << " '" << Node->getLabel()->getName()
+     << "':" << (void*)Node->getLabel();
+}
+
+//===----------------------------------------------------------------------===//
+//  Expr printing methods.
+//===----------------------------------------------------------------------===//
+
+void StmtDumper::VisitExpr(Expr *Node) {
+  DumpExpr(Node);
+}
+
+static void DumpBasePath(llvm::raw_ostream &OS, CastExpr *Node) {
+  if (Node->getBasePath().empty())
+    return;
+
+  OS << " (";
+  bool First = true;
+  for (CXXBaseSpecifierArray::iterator I = Node->getBasePath().begin(),
+       E = Node->getBasePath().end(); I != E; ++I) {
+    const CXXBaseSpecifier *Base = *I;
+    if (!First)
+      OS << " -> ";
+    
+    const CXXRecordDecl *RD =
+    cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
+    
+    if (Base->isVirtual())
+      OS << "virtual ";
+    OS << RD->getName();
+    First = false;
+  }
+    
+  OS << ')';
+}
+
+void StmtDumper::VisitCastExpr(CastExpr *Node) {
+  DumpExpr(Node);
+  OS << " <" << Node->getCastKindName();
+  DumpBasePath(OS, Node);
+  OS << ">";
+}
+
+void StmtDumper::VisitImplicitCastExpr(ImplicitCastExpr *Node) {
+  VisitCastExpr(Node);
+  if (Node->isLvalueCast())
+    OS << " lvalue";
+}
+
+void StmtDumper::VisitDeclRefExpr(DeclRefExpr *Node) {
+  DumpExpr(Node);
+
+  OS << " ";
+  switch (Node->getDecl()->getKind()) {
+  default: OS << "Decl"; break;
+  case Decl::Function: OS << "FunctionDecl"; break;
+  case Decl::Var: OS << "Var"; break;
+  case Decl::ParmVar: OS << "ParmVar"; break;
+  case Decl::EnumConstant: OS << "EnumConstant"; break;
+  case Decl::Typedef: OS << "Typedef"; break;
+  case Decl::Record: OS << "Record"; break;
+  case Decl::Enum: OS << "Enum"; break;
+  case Decl::CXXRecord: OS << "CXXRecord"; break;
+  case Decl::ObjCInterface: OS << "ObjCInterface"; break;
+  case Decl::ObjCClass: OS << "ObjCClass"; break;
+  }
+
+  OS << "='" << Node->getDecl() << "' " << (void*)Node->getDecl();
+}
+
+void StmtDumper::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node) {
+  DumpExpr(Node);
+  OS << " (";
+  if (!Node->requiresADL()) OS << "no ";
+  OS << "ADL) = '" << Node->getName() << '\'';
+
+  UnresolvedLookupExpr::decls_iterator
+    I = Node->decls_begin(), E = Node->decls_end();
+  if (I == E) OS << " empty";
+  for (; I != E; ++I)
+    OS << " " << (void*) *I;
+}
+
+void StmtDumper::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) {
+  DumpExpr(Node);
+
+  OS << " " << Node->getDecl()->getDeclKindName()
+     << "Decl='" << Node->getDecl()
+     << "' " << (void*)Node->getDecl();
+  if (Node->isFreeIvar())
+    OS << " isFreeIvar";
+}
+
+void StmtDumper::VisitPredefinedExpr(PredefinedExpr *Node) {
+  DumpExpr(Node);
+  switch (Node->getIdentType()) {
+  default: assert(0 && "unknown case");
+  case PredefinedExpr::Func:           OS <<  " __func__"; break;
+  case PredefinedExpr::Function:       OS <<  " __FUNCTION__"; break;
+  case PredefinedExpr::PrettyFunction: OS <<  " __PRETTY_FUNCTION__";break;
+  }
+}
+
+void StmtDumper::VisitCharacterLiteral(CharacterLiteral *Node) {
+  DumpExpr(Node);
+  OS << Node->getValue();
+}
+
+void StmtDumper::VisitIntegerLiteral(IntegerLiteral *Node) {
+  DumpExpr(Node);
+
+  bool isSigned = Node->getType()->isSignedIntegerType();
+  OS << " " << Node->getValue().toString(10, isSigned);
+}
+void StmtDumper::VisitFloatingLiteral(FloatingLiteral *Node) {
+  DumpExpr(Node);
+  OS << " " << Node->getValueAsApproximateDouble();
+}
+
+void StmtDumper::VisitStringLiteral(StringLiteral *Str) {
+  DumpExpr(Str);
+  // FIXME: this doesn't print wstrings right.
+  OS << " ";
+  if (Str->isWide())
+    OS << "L";
+  OS << '"';
+  OS.write_escaped(llvm::StringRef(Str->getStrData(),
+                                   Str->getByteLength()));
+  OS << '"';
+}
+
+void StmtDumper::VisitUnaryOperator(UnaryOperator *Node) {
+  DumpExpr(Node);
+  OS << " " << (Node->isPostfix() ? "postfix" : "prefix")
+     << " '" << UnaryOperator::getOpcodeStr(Node->getOpcode()) << "'";
+}
+void StmtDumper::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *Node) {
+  DumpExpr(Node);
+  OS << " " << (Node->isSizeOf() ? "sizeof" : "alignof") << " ";
+  if (Node->isArgumentType())
+    DumpType(Node->getArgumentType());
+}
+
+void StmtDumper::VisitMemberExpr(MemberExpr *Node) {
+  DumpExpr(Node);
+  OS << " " << (Node->isArrow() ? "->" : ".")
+     << Node->getMemberDecl() << ' '
+     << (void*)Node->getMemberDecl();
+}
+void StmtDumper::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) {
+  DumpExpr(Node);
+  OS << " " << Node->getAccessor().getNameStart();
+}
+void StmtDumper::VisitBinaryOperator(BinaryOperator *Node) {
+  DumpExpr(Node);
+  OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode()) << "'";
+}
+void StmtDumper::VisitCompoundAssignOperator(CompoundAssignOperator *Node) {
+  DumpExpr(Node);
+  OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode())
+     << "' ComputeLHSTy=";
+  DumpType(Node->getComputationLHSType());
+  OS << " ComputeResultTy=";
+  DumpType(Node->getComputationResultType());
+}
+
+// GNU extensions.
+
+void StmtDumper::VisitAddrLabelExpr(AddrLabelExpr *Node) {
+  DumpExpr(Node);
+  OS << " " << Node->getLabel()->getName()
+     << " " << (void*)Node->getLabel();
+}
+
+void StmtDumper::VisitTypesCompatibleExpr(TypesCompatibleExpr *Node) {
+  DumpExpr(Node);
+  OS << " ";
+  DumpType(Node->getArgType1());
+  OS << " ";
+  DumpType(Node->getArgType2());
+}
+
+//===----------------------------------------------------------------------===//
+// C++ Expressions
+//===----------------------------------------------------------------------===//
+
+void StmtDumper::VisitCXXNamedCastExpr(CXXNamedCastExpr *Node) {
+  DumpExpr(Node);
+  OS << " " << Node->getCastName() 
+     << "<" << Node->getTypeAsWritten().getAsString() << ">"
+     << " <" << Node->getCastKindName();
+  DumpBasePath(OS, Node);
+  OS << ">";
+}
+
+void StmtDumper::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) {
+  DumpExpr(Node);
+  OS << " " << (Node->getValue() ? "true" : "false");
+}
+
+void StmtDumper::VisitCXXThisExpr(CXXThisExpr *Node) {
+  DumpExpr(Node);
+  OS << " this";
+}
+
+void StmtDumper::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node) {
+  DumpExpr(Node);
+  OS << " functional cast to " << Node->getTypeAsWritten().getAsString();
+}
+
+void StmtDumper::VisitCXXConstructExpr(CXXConstructExpr *Node) {
+  DumpExpr(Node);
+  CXXConstructorDecl *Ctor = Node->getConstructor();
+  DumpType(Ctor->getType());
+  if (Node->isElidable())
+    OS << " elidable";
+}
+
+void StmtDumper::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *Node) {
+  DumpExpr(Node);
+  OS << " ";
+  DumpCXXTemporary(Node->getTemporary());
+}
+
+void StmtDumper::VisitCXXExprWithTemporaries(CXXExprWithTemporaries *Node) {
+  DumpExpr(Node);
+  ++IndentLevel;
+  for (unsigned i = 0, e = Node->getNumTemporaries(); i != e; ++i) {
+    OS << "\n";
+    Indent();
+    DumpCXXTemporary(Node->getTemporary(i));
+  }
+  --IndentLevel;
+}
+
+void StmtDumper::DumpCXXTemporary(CXXTemporary *Temporary) {
+  OS << "(CXXTemporary " << (void *)Temporary << ")";
+}
+
+//===----------------------------------------------------------------------===//
+// Obj-C Expressions
+//===----------------------------------------------------------------------===//
+
+void StmtDumper::VisitObjCMessageExpr(ObjCMessageExpr* Node) {
+  DumpExpr(Node);
+  OS << " selector=" << Node->getSelector().getAsString();
+  switch (Node->getReceiverKind()) {
+  case ObjCMessageExpr::Instance:
+    break;
+
+  case ObjCMessageExpr::Class:
+    OS << " class=";
+    DumpType(Node->getClassReceiver());
+    break;
+
+  case ObjCMessageExpr::SuperInstance:
+    OS << " super (instance)";
+    break;
+
+  case ObjCMessageExpr::SuperClass:
+    OS << " super (class)";
+    break;
+  }
+}
+
+void StmtDumper::VisitObjCAtCatchStmt(ObjCAtCatchStmt *Node) {
+  DumpStmt(Node);
+  if (VarDecl *CatchParam = Node->getCatchParamDecl()) {
+    OS << " catch parm = ";
+    DumpDeclarator(CatchParam);
+  } else {
+    OS << " catch all";
+  }
+}
+
+void StmtDumper::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) {
+  DumpExpr(Node);
+  OS << " ";
+  DumpType(Node->getEncodedType());
+}
+
+void StmtDumper::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) {
+  DumpExpr(Node);
+
+  OS << " " << Node->getSelector().getAsString();
+}
+
+void StmtDumper::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) {
+  DumpExpr(Node);
+
+  OS << ' ' << Node->getProtocol();
+}
+
+void StmtDumper::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) {
+  DumpExpr(Node);
+
+  OS << " Kind=PropertyRef Property=\"" << Node->getProperty() << '"';
+}
+
+void StmtDumper::VisitObjCImplicitSetterGetterRefExpr(
+                                        ObjCImplicitSetterGetterRefExpr *Node) {
+  DumpExpr(Node);
+
+  ObjCMethodDecl *Getter = Node->getGetterMethod();
+  ObjCMethodDecl *Setter = Node->getSetterMethod();
+  OS << " Kind=MethodRef Getter=\""
+     << Getter->getSelector().getAsString()
+     << "\" Setter=\"";
+  if (Setter)
+    OS << Setter->getSelector().getAsString();
+  else
+    OS << "(null)";
+  OS << "\"";
+}
+
+void StmtDumper::VisitObjCSuperExpr(ObjCSuperExpr *Node) {
+  DumpExpr(Node);
+  OS << " super";
+}
+
+//===----------------------------------------------------------------------===//
+// Stmt method implementations
+//===----------------------------------------------------------------------===//
+
+/// dump - This does a local dump of the specified AST fragment.  It dumps the
+/// specified node and a few nodes underneath it, but not the whole subtree.
+/// This is useful in a debugger.
+void Stmt::dump(SourceManager &SM) const {
+  StmtDumper P(&SM, llvm::errs(), 4);
+  P.DumpSubTree(const_cast<Stmt*>(this));
+  llvm::errs() << "\n";
+}
+
+/// dump - This does a local dump of the specified AST fragment.  It dumps the
+/// specified node and a few nodes underneath it, but not the whole subtree.
+/// This is useful in a debugger.
+void Stmt::dump() const {
+  StmtDumper P(0, llvm::errs(), 4);
+  P.DumpSubTree(const_cast<Stmt*>(this));
+  llvm::errs() << "\n";
+}
+
+/// dumpAll - This does a dump of the specified AST fragment and all subtrees.
+void Stmt::dumpAll(SourceManager &SM) const {
+  StmtDumper P(&SM, llvm::errs(), ~0U);
+  P.DumpSubTree(const_cast<Stmt*>(this));
+  llvm::errs() << "\n";
+}
+
+/// dumpAll - This does a dump of the specified AST fragment and all subtrees.
+void Stmt::dumpAll() const {
+  StmtDumper P(0, llvm::errs(), ~0U);
+  P.DumpSubTree(const_cast<Stmt*>(this));
+  llvm::errs() << "\n";
+}
diff --git a/lib/AST/StmtIterator.cpp b/lib/AST/StmtIterator.cpp
new file mode 100644
index 0000000..7fc7c96
--- /dev/null
+++ b/lib/AST/StmtIterator.cpp
@@ -0,0 +1,155 @@
+//===--- StmtIterator.cpp - Iterators for Statements ------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines internal methods for StmtIterator.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/StmtIterator.h"
+#include "clang/AST/Decl.h"
+
+using namespace clang;
+
+// FIXME: Add support for dependent-sized array types in C++?
+// Does it even make sense to build a CFG for an uninstantiated template?
+static inline VariableArrayType* FindVA(Type* t) {
+  while (ArrayType* vt = dyn_cast<ArrayType>(t)) {
+    if (VariableArrayType* vat = dyn_cast<VariableArrayType>(vt))
+      if (vat->getSizeExpr())
+        return vat;
+
+    t = vt->getElementType().getTypePtr();
+  }
+
+  return NULL;
+}
+
+void StmtIteratorBase::NextVA() {
+  assert (getVAPtr());
+
+  VariableArrayType* p = getVAPtr();
+  p = FindVA(p->getElementType().getTypePtr());
+  setVAPtr(p);
+
+  if (p)
+    return;
+
+  if (inDecl()) {
+    if (VarDecl* VD = dyn_cast<VarDecl>(decl))
+      if (VD->Init)
+        return;
+
+    NextDecl();
+  }
+  else if (inDeclGroup()) {
+    if (VarDecl* VD = dyn_cast<VarDecl>(*DGI))
+      if (VD->Init)
+        return;
+
+    NextDecl();
+  }
+  else {
+    assert (inSizeOfTypeVA());
+    assert(!decl);
+    RawVAPtr = 0;
+  }
+}
+
+void StmtIteratorBase::NextDecl(bool ImmediateAdvance) {
+  assert (getVAPtr() == NULL);
+
+  if (inDecl()) {
+    assert(decl);
+
+    // FIXME: SIMPLIFY AWAY.
+    if (ImmediateAdvance)
+      decl = 0;
+    else if (HandleDecl(decl))
+      return;
+  }
+  else {
+    assert(inDeclGroup());
+
+    if (ImmediateAdvance)
+      ++DGI;
+
+    for ( ; DGI != DGE; ++DGI)
+      if (HandleDecl(*DGI))
+        return;
+  }
+
+  RawVAPtr = 0;
+}
+
+bool StmtIteratorBase::HandleDecl(Decl* D) {
+
+  if (VarDecl* VD = dyn_cast<VarDecl>(D)) {
+    if (VariableArrayType* VAPtr = FindVA(VD->getType().getTypePtr())) {
+      setVAPtr(VAPtr);
+      return true;
+    }
+
+    if (VD->getInit())
+      return true;
+  }
+  else if (TypedefDecl* TD = dyn_cast<TypedefDecl>(D)) {
+    if (VariableArrayType* VAPtr =
+        FindVA(TD->getUnderlyingType().getTypePtr())) {
+      setVAPtr(VAPtr);
+      return true;
+    }
+  }
+  else if (EnumConstantDecl* ECD = dyn_cast<EnumConstantDecl>(D)) {
+    if (ECD->getInitExpr())
+      return true;
+  }
+
+  return false;
+}
+
+StmtIteratorBase::StmtIteratorBase(Decl *d, Stmt **s)
+  : stmt(s), decl(d), RawVAPtr(d ? DeclMode : 0) {
+  if (decl)
+    NextDecl(false);
+}
+
+StmtIteratorBase::StmtIteratorBase(Decl** dgi, Decl** dge)
+  : stmt(0), DGI(dgi), RawVAPtr(DeclGroupMode), DGE(dge) {
+  NextDecl(false);
+}
+
+StmtIteratorBase::StmtIteratorBase(VariableArrayType* t)
+  : stmt(0), decl(0), RawVAPtr(SizeOfTypeVAMode) {
+  RawVAPtr |= reinterpret_cast<uintptr_t>(t);
+}
+
+Stmt*& StmtIteratorBase::GetDeclExpr() const {
+
+  if (VariableArrayType* VAPtr = getVAPtr()) {
+    assert (VAPtr->SizeExpr);
+    return VAPtr->SizeExpr;
+  }
+
+  assert (inDecl() || inDeclGroup());
+
+  if (inDeclGroup()) {
+    VarDecl* VD = cast<VarDecl>(*DGI);
+    return *VD->getInitAddress();
+  }
+
+  assert (inDecl());
+
+  if (VarDecl* VD = dyn_cast<VarDecl>(decl)) {
+    assert (VD->Init);
+    return *VD->getInitAddress();
+  }
+
+  EnumConstantDecl* ECD = cast<EnumConstantDecl>(decl);
+  return ECD->Init;
+}
diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp
new file mode 100644
index 0000000..3996528
--- /dev/null
+++ b/lib/AST/StmtPrinter.cpp
@@ -0,0 +1,1350 @@
+//===--- StmtPrinter.cpp - Printing implementation for Stmt ASTs ----------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Stmt::dumpPretty/Stmt::printPretty methods, which
+// pretty print the AST back out to C code.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/StmtVisitor.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/PrettyPrinter.h"
+#include "llvm/Support/Format.h"
+using namespace clang;
+
+//===----------------------------------------------------------------------===//
+// StmtPrinter Visitor
+//===----------------------------------------------------------------------===//
+
+namespace  {
+  class StmtPrinter : public StmtVisitor<StmtPrinter> {
+    llvm::raw_ostream &OS;
+    ASTContext &Context;
+    unsigned IndentLevel;
+    clang::PrinterHelper* Helper;
+    PrintingPolicy Policy;
+
+  public:
+    StmtPrinter(llvm::raw_ostream &os, ASTContext &C, PrinterHelper* helper,
+                const PrintingPolicy &Policy,
+                unsigned Indentation = 0)
+      : OS(os), Context(C), IndentLevel(Indentation), Helper(helper),
+        Policy(Policy) {}
+
+    void PrintStmt(Stmt *S) {
+      PrintStmt(S, Policy.Indentation);
+    }
+
+    void PrintStmt(Stmt *S, int SubIndent) {
+      IndentLevel += SubIndent;
+      if (S && isa<Expr>(S)) {
+        // If this is an expr used in a stmt context, indent and newline it.
+        Indent();
+        Visit(S);
+        OS << ";\n";
+      } else if (S) {
+        Visit(S);
+      } else {
+        Indent() << "<<<NULL STATEMENT>>>\n";
+      }
+      IndentLevel -= SubIndent;
+    }
+
+    void PrintRawCompoundStmt(CompoundStmt *S);
+    void PrintRawDecl(Decl *D);
+    void PrintRawDeclStmt(DeclStmt *S);
+    void PrintRawIfStmt(IfStmt *If);
+    void PrintRawCXXCatchStmt(CXXCatchStmt *Catch);
+
+    void PrintExpr(Expr *E) {
+      if (E)
+        Visit(E);
+      else
+        OS << "<null expr>";
+    }
+
+    llvm::raw_ostream &Indent(int Delta = 0) {
+      for (int i = 0, e = IndentLevel+Delta; i < e; ++i)
+        OS << "  ";
+      return OS;
+    }
+
+    bool PrintOffsetOfDesignator(Expr *E);
+    void VisitUnaryOffsetOf(UnaryOperator *Node);
+
+    void Visit(Stmt* S) {
+      if (Helper && Helper->handledStmt(S,OS))
+          return;
+      else StmtVisitor<StmtPrinter>::Visit(S);
+    }
+
+    void VisitStmt(Stmt *Node);
+#define STMT(CLASS, PARENT) \
+    void Visit##CLASS(CLASS *Node);
+#include "clang/AST/StmtNodes.def"
+  };
+}
+
+//===----------------------------------------------------------------------===//
+//  Stmt printing methods.
+//===----------------------------------------------------------------------===//
+
+void StmtPrinter::VisitStmt(Stmt *Node) {
+  Indent() << "<<unknown stmt type>>\n";
+}
+
+/// PrintRawCompoundStmt - Print a compound stmt without indenting the {, and
+/// with no newline after the }.
+void StmtPrinter::PrintRawCompoundStmt(CompoundStmt *Node) {
+  OS << "{\n";
+  for (CompoundStmt::body_iterator I = Node->body_begin(), E = Node->body_end();
+       I != E; ++I)
+    PrintStmt(*I);
+
+  Indent() << "}";
+}
+
+void StmtPrinter::PrintRawDecl(Decl *D) {
+  D->print(OS, Policy, IndentLevel);
+}
+
+void StmtPrinter::PrintRawDeclStmt(DeclStmt *S) {
+  DeclStmt::decl_iterator Begin = S->decl_begin(), End = S->decl_end();
+  llvm::SmallVector<Decl*, 2> Decls;
+  for ( ; Begin != End; ++Begin)
+    Decls.push_back(*Begin);
+
+  Decl::printGroup(Decls.data(), Decls.size(), OS, Policy, IndentLevel);
+}
+
+void StmtPrinter::VisitNullStmt(NullStmt *Node) {
+  Indent() << ";\n";
+}
+
+void StmtPrinter::VisitDeclStmt(DeclStmt *Node) {
+  Indent();
+  PrintRawDeclStmt(Node);
+  OS << ";\n";
+}
+
+void StmtPrinter::VisitCompoundStmt(CompoundStmt *Node) {
+  Indent();
+  PrintRawCompoundStmt(Node);
+  OS << "\n";
+}
+
+void StmtPrinter::VisitCaseStmt(CaseStmt *Node) {
+  Indent(-1) << "case ";
+  PrintExpr(Node->getLHS());
+  if (Node->getRHS()) {
+    OS << " ... ";
+    PrintExpr(Node->getRHS());
+  }
+  OS << ":\n";
+
+  PrintStmt(Node->getSubStmt(), 0);
+}
+
+void StmtPrinter::VisitDefaultStmt(DefaultStmt *Node) {
+  Indent(-1) << "default:\n";
+  PrintStmt(Node->getSubStmt(), 0);
+}
+
+void StmtPrinter::VisitLabelStmt(LabelStmt *Node) {
+  Indent(-1) << Node->getName() << ":\n";
+  PrintStmt(Node->getSubStmt(), 0);
+}
+
+void StmtPrinter::PrintRawIfStmt(IfStmt *If) {
+  OS << "if (";
+  PrintExpr(If->getCond());
+  OS << ')';
+
+  if (CompoundStmt *CS = dyn_cast<CompoundStmt>(If->getThen())) {
+    OS << ' ';
+    PrintRawCompoundStmt(CS);
+    OS << (If->getElse() ? ' ' : '\n');
+  } else {
+    OS << '\n';
+    PrintStmt(If->getThen());
+    if (If->getElse()) Indent();
+  }
+
+  if (Stmt *Else = If->getElse()) {
+    OS << "else";
+
+    if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Else)) {
+      OS << ' ';
+      PrintRawCompoundStmt(CS);
+      OS << '\n';
+    } else if (IfStmt *ElseIf = dyn_cast<IfStmt>(Else)) {
+      OS << ' ';
+      PrintRawIfStmt(ElseIf);
+    } else {
+      OS << '\n';
+      PrintStmt(If->getElse());
+    }
+  }
+}
+
+void StmtPrinter::VisitIfStmt(IfStmt *If) {
+  Indent();
+  PrintRawIfStmt(If);
+}
+
+void StmtPrinter::VisitSwitchStmt(SwitchStmt *Node) {
+  Indent() << "switch (";
+  PrintExpr(Node->getCond());
+  OS << ")";
+
+  // Pretty print compoundstmt bodies (very common).
+  if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
+    OS << " ";
+    PrintRawCompoundStmt(CS);
+    OS << "\n";
+  } else {
+    OS << "\n";
+    PrintStmt(Node->getBody());
+  }
+}
+
+void StmtPrinter::VisitSwitchCase(SwitchCase*) {
+  assert(0 && "SwitchCase is an abstract class");
+}
+
+void StmtPrinter::VisitWhileStmt(WhileStmt *Node) {
+  Indent() << "while (";
+  PrintExpr(Node->getCond());
+  OS << ")\n";
+  PrintStmt(Node->getBody());
+}
+
+void StmtPrinter::VisitDoStmt(DoStmt *Node) {
+  Indent() << "do ";
+  if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
+    PrintRawCompoundStmt(CS);
+    OS << " ";
+  } else {
+    OS << "\n";
+    PrintStmt(Node->getBody());
+    Indent();
+  }
+
+  OS << "while (";
+  PrintExpr(Node->getCond());
+  OS << ");\n";
+}
+
+void StmtPrinter::VisitForStmt(ForStmt *Node) {
+  Indent() << "for (";
+  if (Node->getInit()) {
+    if (DeclStmt *DS = dyn_cast<DeclStmt>(Node->getInit()))
+      PrintRawDeclStmt(DS);
+    else
+      PrintExpr(cast<Expr>(Node->getInit()));
+  }
+  OS << ";";
+  if (Node->getCond()) {
+    OS << " ";
+    PrintExpr(Node->getCond());
+  }
+  OS << ";";
+  if (Node->getInc()) {
+    OS << " ";
+    PrintExpr(Node->getInc());
+  }
+  OS << ") ";
+
+  if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
+    PrintRawCompoundStmt(CS);
+    OS << "\n";
+  } else {
+    OS << "\n";
+    PrintStmt(Node->getBody());
+  }
+}
+
+void StmtPrinter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *Node) {
+  Indent() << "for (";
+  if (DeclStmt *DS = dyn_cast<DeclStmt>(Node->getElement()))
+    PrintRawDeclStmt(DS);
+  else
+    PrintExpr(cast<Expr>(Node->getElement()));
+  OS << " in ";
+  PrintExpr(Node->getCollection());
+  OS << ") ";
+
+  if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
+    PrintRawCompoundStmt(CS);
+    OS << "\n";
+  } else {
+    OS << "\n";
+    PrintStmt(Node->getBody());
+  }
+}
+
+void StmtPrinter::VisitGotoStmt(GotoStmt *Node) {
+  Indent() << "goto " << Node->getLabel()->getName() << ";\n";
+}
+
+void StmtPrinter::VisitIndirectGotoStmt(IndirectGotoStmt *Node) {
+  Indent() << "goto *";
+  PrintExpr(Node->getTarget());
+  OS << ";\n";
+}
+
+void StmtPrinter::VisitContinueStmt(ContinueStmt *Node) {
+  Indent() << "continue;\n";
+}
+
+void StmtPrinter::VisitBreakStmt(BreakStmt *Node) {
+  Indent() << "break;\n";
+}
+
+
+void StmtPrinter::VisitReturnStmt(ReturnStmt *Node) {
+  Indent() << "return";
+  if (Node->getRetValue()) {
+    OS << " ";
+    PrintExpr(Node->getRetValue());
+  }
+  OS << ";\n";
+}
+
+
+void StmtPrinter::VisitAsmStmt(AsmStmt *Node) {
+  Indent() << "asm ";
+
+  if (Node->isVolatile())
+    OS << "volatile ";
+
+  OS << "(";
+  VisitStringLiteral(Node->getAsmString());
+
+  // Outputs
+  if (Node->getNumOutputs() != 0 || Node->getNumInputs() != 0 ||
+      Node->getNumClobbers() != 0)
+    OS << " : ";
+
+  for (unsigned i = 0, e = Node->getNumOutputs(); i != e; ++i) {
+    if (i != 0)
+      OS << ", ";
+
+    if (!Node->getOutputName(i).empty()) {
+      OS << '[';
+      OS << Node->getOutputName(i);
+      OS << "] ";
+    }
+
+    VisitStringLiteral(Node->getOutputConstraintLiteral(i));
+    OS << " ";
+    Visit(Node->getOutputExpr(i));
+  }
+
+  // Inputs
+  if (Node->getNumInputs() != 0 || Node->getNumClobbers() != 0)
+    OS << " : ";
+
+  for (unsigned i = 0, e = Node->getNumInputs(); i != e; ++i) {
+    if (i != 0)
+      OS << ", ";
+
+    if (!Node->getInputName(i).empty()) {
+      OS << '[';
+      OS << Node->getInputName(i);
+      OS << "] ";
+    }
+
+    VisitStringLiteral(Node->getInputConstraintLiteral(i));
+    OS << " ";
+    Visit(Node->getInputExpr(i));
+  }
+
+  // Clobbers
+  if (Node->getNumClobbers() != 0)
+    OS << " : ";
+
+  for (unsigned i = 0, e = Node->getNumClobbers(); i != e; ++i) {
+    if (i != 0)
+      OS << ", ";
+
+    VisitStringLiteral(Node->getClobber(i));
+  }
+
+  OS << ");\n";
+}
+
+void StmtPrinter::VisitObjCAtTryStmt(ObjCAtTryStmt *Node) {
+  Indent() << "@try";
+  if (CompoundStmt *TS = dyn_cast<CompoundStmt>(Node->getTryBody())) {
+    PrintRawCompoundStmt(TS);
+    OS << "\n";
+  }
+
+  for (unsigned I = 0, N = Node->getNumCatchStmts(); I != N; ++I) {
+    ObjCAtCatchStmt *catchStmt = Node->getCatchStmt(I);
+    Indent() << "@catch(";
+    if (catchStmt->getCatchParamDecl()) {
+      if (Decl *DS = catchStmt->getCatchParamDecl())
+        PrintRawDecl(DS);
+    }
+    OS << ")";
+    if (CompoundStmt *CS = dyn_cast<CompoundStmt>(catchStmt->getCatchBody())) {
+      PrintRawCompoundStmt(CS);
+      OS << "\n";
+    }
+  }
+
+  if (ObjCAtFinallyStmt *FS = static_cast<ObjCAtFinallyStmt *>(
+        Node->getFinallyStmt())) {
+    Indent() << "@finally";
+    PrintRawCompoundStmt(dyn_cast<CompoundStmt>(FS->getFinallyBody()));
+    OS << "\n";
+  }
+}
+
+void StmtPrinter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *Node) {
+}
+
+void StmtPrinter::VisitObjCAtCatchStmt (ObjCAtCatchStmt *Node) {
+  Indent() << "@catch (...) { /* todo */ } \n";
+}
+
+void StmtPrinter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *Node) {
+  Indent() << "@throw";
+  if (Node->getThrowExpr()) {
+    OS << " ";
+    PrintExpr(Node->getThrowExpr());
+  }
+  OS << ";\n";
+}
+
+void StmtPrinter::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *Node) {
+  Indent() << "@synchronized (";
+  PrintExpr(Node->getSynchExpr());
+  OS << ")";
+  PrintRawCompoundStmt(Node->getSynchBody());
+  OS << "\n";
+}
+
+void StmtPrinter::PrintRawCXXCatchStmt(CXXCatchStmt *Node) {
+  OS << "catch (";
+  if (Decl *ExDecl = Node->getExceptionDecl())
+    PrintRawDecl(ExDecl);
+  else
+    OS << "...";
+  OS << ") ";
+  PrintRawCompoundStmt(cast<CompoundStmt>(Node->getHandlerBlock()));
+}
+
+void StmtPrinter::VisitCXXCatchStmt(CXXCatchStmt *Node) {
+  Indent();
+  PrintRawCXXCatchStmt(Node);
+  OS << "\n";
+}
+
+void StmtPrinter::VisitCXXTryStmt(CXXTryStmt *Node) {
+  Indent() << "try ";
+  PrintRawCompoundStmt(Node->getTryBlock());
+  for (unsigned i = 0, e = Node->getNumHandlers(); i < e; ++i) {
+    OS << " ";
+    PrintRawCXXCatchStmt(Node->getHandler(i));
+  }
+  OS << "\n";
+}
+
+//===----------------------------------------------------------------------===//
+//  Expr printing methods.
+//===----------------------------------------------------------------------===//
+
+void StmtPrinter::VisitExpr(Expr *Node) {
+  OS << "<<unknown expr type>>";
+}
+
+void StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) {
+  if (NestedNameSpecifier *Qualifier = Node->getQualifier())
+    Qualifier->print(OS, Policy);
+  OS << Node->getDecl();
+  if (Node->hasExplicitTemplateArgumentList())
+    OS << TemplateSpecializationType::PrintTemplateArgumentList(
+                                                    Node->getTemplateArgs(),
+                                                    Node->getNumTemplateArgs(),
+                                                    Policy);  
+}
+
+void StmtPrinter::VisitDependentScopeDeclRefExpr(
+                                           DependentScopeDeclRefExpr *Node) {
+  Node->getQualifier()->print(OS, Policy);
+  OS << Node->getDeclName().getAsString();
+  if (Node->hasExplicitTemplateArgs())
+    OS << TemplateSpecializationType::PrintTemplateArgumentList(
+                                                   Node->getTemplateArgs(),
+                                                   Node->getNumTemplateArgs(),
+                                                   Policy);
+}
+
+void StmtPrinter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node) {
+  if (Node->getQualifier())
+    Node->getQualifier()->print(OS, Policy);
+  OS << Node->getName().getAsString();
+  if (Node->hasExplicitTemplateArgs())
+    OS << TemplateSpecializationType::PrintTemplateArgumentList(
+                                                   Node->getTemplateArgs(),
+                                                   Node->getNumTemplateArgs(),
+                                                   Policy);
+}
+
+void StmtPrinter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) {
+  if (Node->getBase()) {
+    PrintExpr(Node->getBase());
+    OS << (Node->isArrow() ? "->" : ".");
+  }
+  OS << Node->getDecl();
+}
+
+void StmtPrinter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) {
+  if (Node->getBase()) {
+    PrintExpr(Node->getBase());
+    OS << ".";
+  }
+  OS << Node->getProperty()->getNameAsCString();
+}
+
+void StmtPrinter::VisitObjCImplicitSetterGetterRefExpr(
+                                        ObjCImplicitSetterGetterRefExpr *Node) {
+  if (Node->getBase()) {
+    PrintExpr(Node->getBase());
+    OS << ".";
+  }
+  if (Node->getGetterMethod())
+    OS << Node->getGetterMethod();
+
+}
+
+void StmtPrinter::VisitPredefinedExpr(PredefinedExpr *Node) {
+  switch (Node->getIdentType()) {
+    default:
+      assert(0 && "unknown case");
+    case PredefinedExpr::Func:
+      OS << "__func__";
+      break;
+    case PredefinedExpr::Function:
+      OS << "__FUNCTION__";
+      break;
+    case PredefinedExpr::PrettyFunction:
+      OS << "__PRETTY_FUNCTION__";
+      break;
+  }
+}
+
+void StmtPrinter::VisitCharacterLiteral(CharacterLiteral *Node) {
+  unsigned value = Node->getValue();
+  if (Node->isWide())
+    OS << "L";
+  switch (value) {
+  case '\\':
+    OS << "'\\\\'";
+    break;
+  case '\'':
+    OS << "'\\''";
+    break;
+  case '\a':
+    // TODO: K&R: the meaning of '\\a' is different in traditional C
+    OS << "'\\a'";
+    break;
+  case '\b':
+    OS << "'\\b'";
+    break;
+  // Nonstandard escape sequence.
+  /*case '\e':
+    OS << "'\\e'";
+    break;*/
+  case '\f':
+    OS << "'\\f'";
+    break;
+  case '\n':
+    OS << "'\\n'";
+    break;
+  case '\r':
+    OS << "'\\r'";
+    break;
+  case '\t':
+    OS << "'\\t'";
+    break;
+  case '\v':
+    OS << "'\\v'";
+    break;
+  default:
+    if (value < 256 && isprint(value)) {
+      OS << "'" << (char)value << "'";
+    } else if (value < 256) {
+      OS << "'\\x" << llvm::format("%x", value) << "'";
+    } else {
+      // FIXME what to really do here?
+      OS << value;
+    }
+  }
+}
+
+void StmtPrinter::VisitIntegerLiteral(IntegerLiteral *Node) {
+  bool isSigned = Node->getType()->isSignedIntegerType();
+  OS << Node->getValue().toString(10, isSigned);
+
+  // Emit suffixes.  Integer literals are always a builtin integer type.
+  switch (Node->getType()->getAs<BuiltinType>()->getKind()) {
+  default: assert(0 && "Unexpected type for integer literal!");
+  case BuiltinType::Int:       break; // no suffix.
+  case BuiltinType::UInt:      OS << 'U'; break;
+  case BuiltinType::Long:      OS << 'L'; break;
+  case BuiltinType::ULong:     OS << "UL"; break;
+  case BuiltinType::LongLong:  OS << "LL"; break;
+  case BuiltinType::ULongLong: OS << "ULL"; break;
+  }
+}
+void StmtPrinter::VisitFloatingLiteral(FloatingLiteral *Node) {
+  // FIXME: print value more precisely.
+  OS << Node->getValueAsApproximateDouble();
+}
+
+void StmtPrinter::VisitImaginaryLiteral(ImaginaryLiteral *Node) {
+  PrintExpr(Node->getSubExpr());
+  OS << "i";
+}
+
+void StmtPrinter::VisitStringLiteral(StringLiteral *Str) {
+  if (Str->isWide()) OS << 'L';
+  OS << '"';
+
+  // FIXME: this doesn't print wstrings right.
+  for (unsigned i = 0, e = Str->getByteLength(); i != e; ++i) {
+    unsigned char Char = Str->getStrData()[i];
+
+    switch (Char) {
+    default:
+      if (isprint(Char))
+        OS << (char)Char;
+      else  // Output anything hard as an octal escape.
+        OS << '\\'
+        << (char)('0'+ ((Char >> 6) & 7))
+        << (char)('0'+ ((Char >> 3) & 7))
+        << (char)('0'+ ((Char >> 0) & 7));
+      break;
+    // Handle some common non-printable cases to make dumps prettier.
+    case '\\': OS << "\\\\"; break;
+    case '"': OS << "\\\""; break;
+    case '\n': OS << "\\n"; break;
+    case '\t': OS << "\\t"; break;
+    case '\a': OS << "\\a"; break;
+    case '\b': OS << "\\b"; break;
+    }
+  }
+  OS << '"';
+}
+void StmtPrinter::VisitParenExpr(ParenExpr *Node) {
+  OS << "(";
+  PrintExpr(Node->getSubExpr());
+  OS << ")";
+}
+void StmtPrinter::VisitUnaryOperator(UnaryOperator *Node) {
+  if (!Node->isPostfix()) {
+    OS << UnaryOperator::getOpcodeStr(Node->getOpcode());
+
+    // Print a space if this is an "identifier operator" like __real, or if
+    // it might be concatenated incorrectly like '+'.
+    switch (Node->getOpcode()) {
+    default: break;
+    case UnaryOperator::Real:
+    case UnaryOperator::Imag:
+    case UnaryOperator::Extension:
+      OS << ' ';
+      break;
+    case UnaryOperator::Plus:
+    case UnaryOperator::Minus:
+      if (isa<UnaryOperator>(Node->getSubExpr()))
+        OS << ' ';
+      break;
+    }
+  }
+  PrintExpr(Node->getSubExpr());
+
+  if (Node->isPostfix())
+    OS << UnaryOperator::getOpcodeStr(Node->getOpcode());
+}
+
+bool StmtPrinter::PrintOffsetOfDesignator(Expr *E) {
+  if (isa<UnaryOperator>(E)) {
+    // Base case, print the type and comma.
+    OS << E->getType().getAsString() << ", ";
+    return true;
+  } else if (ArraySubscriptExpr *ASE = dyn_cast<ArraySubscriptExpr>(E)) {
+    PrintOffsetOfDesignator(ASE->getLHS());
+    OS << "[";
+    PrintExpr(ASE->getRHS());
+    OS << "]";
+    return false;
+  } else {
+    MemberExpr *ME = cast<MemberExpr>(E);
+    bool IsFirst = PrintOffsetOfDesignator(ME->getBase());
+    OS << (IsFirst ? "" : ".") << ME->getMemberDecl();
+    return false;
+  }
+}
+
+void StmtPrinter::VisitUnaryOffsetOf(UnaryOperator *Node) {
+  OS << "__builtin_offsetof(";
+  PrintOffsetOfDesignator(Node->getSubExpr());
+  OS << ")";
+}
+
+void StmtPrinter::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *Node) {
+  OS << (Node->isSizeOf() ? "sizeof" : "__alignof");
+  if (Node->isArgumentType())
+    OS << "(" << Node->getArgumentType().getAsString() << ")";
+  else {
+    OS << " ";
+    PrintExpr(Node->getArgumentExpr());
+  }
+}
+void StmtPrinter::VisitArraySubscriptExpr(ArraySubscriptExpr *Node) {
+  PrintExpr(Node->getLHS());
+  OS << "[";
+  PrintExpr(Node->getRHS());
+  OS << "]";
+}
+
+void StmtPrinter::VisitCallExpr(CallExpr *Call) {
+  PrintExpr(Call->getCallee());
+  OS << "(";
+  for (unsigned i = 0, e = Call->getNumArgs(); i != e; ++i) {
+    if (isa<CXXDefaultArgExpr>(Call->getArg(i))) {
+      // Don't print any defaulted arguments
+      break;
+    }
+
+    if (i) OS << ", ";
+    PrintExpr(Call->getArg(i));
+  }
+  OS << ")";
+}
+void StmtPrinter::VisitMemberExpr(MemberExpr *Node) {
+  // FIXME: Suppress printing implicit bases (like "this")
+  PrintExpr(Node->getBase());
+  if (FieldDecl *FD = dyn_cast<FieldDecl>(Node->getMemberDecl()))
+    if (FD->isAnonymousStructOrUnion())
+      return;
+  OS << (Node->isArrow() ? "->" : ".");
+  if (NestedNameSpecifier *Qualifier = Node->getQualifier())
+    Qualifier->print(OS, Policy);
+
+  OS << Node->getMemberDecl();
+
+  if (Node->hasExplicitTemplateArgumentList())
+    OS << TemplateSpecializationType::PrintTemplateArgumentList(
+                                                    Node->getTemplateArgs(),
+                                                    Node->getNumTemplateArgs(),
+                                                                Policy);
+}
+void StmtPrinter::VisitObjCIsaExpr(ObjCIsaExpr *Node) {
+  PrintExpr(Node->getBase());
+  OS << (Node->isArrow() ? "->isa" : ".isa");
+}
+
+void StmtPrinter::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) {
+  PrintExpr(Node->getBase());
+  OS << ".";
+  OS << Node->getAccessor().getName();
+}
+void StmtPrinter::VisitCastExpr(CastExpr *) {
+  assert(0 && "CastExpr is an abstract class");
+}
+void StmtPrinter::VisitExplicitCastExpr(ExplicitCastExpr *) {
+  assert(0 && "ExplicitCastExpr is an abstract class");
+}
+void StmtPrinter::VisitCStyleCastExpr(CStyleCastExpr *Node) {
+  OS << "(" << Node->getType().getAsString() << ")";
+  PrintExpr(Node->getSubExpr());
+}
+void StmtPrinter::VisitCompoundLiteralExpr(CompoundLiteralExpr *Node) {
+  OS << "(" << Node->getType().getAsString() << ")";
+  PrintExpr(Node->getInitializer());
+}
+void StmtPrinter::VisitImplicitCastExpr(ImplicitCastExpr *Node) {
+  // No need to print anything, simply forward to the sub expression.
+  PrintExpr(Node->getSubExpr());
+}
+void StmtPrinter::VisitBinaryOperator(BinaryOperator *Node) {
+  PrintExpr(Node->getLHS());
+  OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
+  PrintExpr(Node->getRHS());
+}
+void StmtPrinter::VisitCompoundAssignOperator(CompoundAssignOperator *Node) {
+  PrintExpr(Node->getLHS());
+  OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
+  PrintExpr(Node->getRHS());
+}
+void StmtPrinter::VisitConditionalOperator(ConditionalOperator *Node) {
+  PrintExpr(Node->getCond());
+
+  if (Node->getLHS()) {
+    OS << " ? ";
+    PrintExpr(Node->getLHS());
+    OS << " : ";
+  }
+  else { // Handle GCC extension where LHS can be NULL.
+    OS << " ?: ";
+  }
+
+  PrintExpr(Node->getRHS());
+}
+
+// GNU extensions.
+
+void StmtPrinter::VisitAddrLabelExpr(AddrLabelExpr *Node) {
+  OS << "&&" << Node->getLabel()->getName();
+}
+
+void StmtPrinter::VisitStmtExpr(StmtExpr *E) {
+  OS << "(";
+  PrintRawCompoundStmt(E->getSubStmt());
+  OS << ")";
+}
+
+void StmtPrinter::VisitTypesCompatibleExpr(TypesCompatibleExpr *Node) {
+  OS << "__builtin_types_compatible_p(";
+  OS << Node->getArgType1().getAsString() << ",";
+  OS << Node->getArgType2().getAsString() << ")";
+}
+
+void StmtPrinter::VisitChooseExpr(ChooseExpr *Node) {
+  OS << "__builtin_choose_expr(";
+  PrintExpr(Node->getCond());
+  OS << ", ";
+  PrintExpr(Node->getLHS());
+  OS << ", ";
+  PrintExpr(Node->getRHS());
+  OS << ")";
+}
+
+void StmtPrinter::VisitGNUNullExpr(GNUNullExpr *) {
+  OS << "__null";
+}
+
+void StmtPrinter::VisitShuffleVectorExpr(ShuffleVectorExpr *Node) {
+  OS << "__builtin_shufflevector(";
+  for (unsigned i = 0, e = Node->getNumSubExprs(); i != e; ++i) {
+    if (i) OS << ", ";
+    PrintExpr(Node->getExpr(i));
+  }
+  OS << ")";
+}
+
+void StmtPrinter::VisitInitListExpr(InitListExpr* Node) {
+  if (Node->getSyntacticForm()) {
+    Visit(Node->getSyntacticForm());
+    return;
+  }
+
+  OS << "{ ";
+  for (unsigned i = 0, e = Node->getNumInits(); i != e; ++i) {
+    if (i) OS << ", ";
+    if (Node->getInit(i))
+      PrintExpr(Node->getInit(i));
+    else
+      OS << "0";
+  }
+  OS << " }";
+}
+
+void StmtPrinter::VisitParenListExpr(ParenListExpr* Node) {
+  OS << "( ";
+  for (unsigned i = 0, e = Node->getNumExprs(); i != e; ++i) {
+    if (i) OS << ", ";
+    PrintExpr(Node->getExpr(i));
+  }
+  OS << " )";
+}
+
+void StmtPrinter::VisitDesignatedInitExpr(DesignatedInitExpr *Node) {
+  for (DesignatedInitExpr::designators_iterator D = Node->designators_begin(),
+                      DEnd = Node->designators_end();
+       D != DEnd; ++D) {
+    if (D->isFieldDesignator()) {
+      if (D->getDotLoc().isInvalid())
+        OS << D->getFieldName()->getName() << ":";
+      else
+        OS << "." << D->getFieldName()->getName();
+    } else {
+      OS << "[";
+      if (D->isArrayDesignator()) {
+        PrintExpr(Node->getArrayIndex(*D));
+      } else {
+        PrintExpr(Node->getArrayRangeStart(*D));
+        OS << " ... ";
+        PrintExpr(Node->getArrayRangeEnd(*D));
+      }
+      OS << "]";
+    }
+  }
+
+  OS << " = ";
+  PrintExpr(Node->getInit());
+}
+
+void StmtPrinter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *Node) {
+  if (Policy.LangOpts.CPlusPlus)
+    OS << "/*implicit*/" << Node->getType().getAsString(Policy) << "()";
+  else {
+    OS << "/*implicit*/(" << Node->getType().getAsString(Policy) << ")";
+    if (Node->getType()->isRecordType())
+      OS << "{}";
+    else
+      OS << 0;
+  }
+}
+
+void StmtPrinter::VisitVAArgExpr(VAArgExpr *Node) {
+  OS << "__builtin_va_arg(";
+  PrintExpr(Node->getSubExpr());
+  OS << ", ";
+  OS << Node->getType().getAsString();
+  OS << ")";
+}
+
+// C++
+void StmtPrinter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *Node) {
+  const char *OpStrings[NUM_OVERLOADED_OPERATORS] = {
+    "",
+#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
+    Spelling,
+#include "clang/Basic/OperatorKinds.def"
+  };
+
+  OverloadedOperatorKind Kind = Node->getOperator();
+  if (Kind == OO_PlusPlus || Kind == OO_MinusMinus) {
+    if (Node->getNumArgs() == 1) {
+      OS << OpStrings[Kind] << ' ';
+      PrintExpr(Node->getArg(0));
+    } else {
+      PrintExpr(Node->getArg(0));
+      OS << ' ' << OpStrings[Kind];
+    }
+  } else if (Kind == OO_Call) {
+    PrintExpr(Node->getArg(0));
+    OS << '(';
+    for (unsigned ArgIdx = 1; ArgIdx < Node->getNumArgs(); ++ArgIdx) {
+      if (ArgIdx > 1)
+        OS << ", ";
+      if (!isa<CXXDefaultArgExpr>(Node->getArg(ArgIdx)))
+        PrintExpr(Node->getArg(ArgIdx));
+    }
+    OS << ')';
+  } else if (Kind == OO_Subscript) {
+    PrintExpr(Node->getArg(0));
+    OS << '[';
+    PrintExpr(Node->getArg(1));
+    OS << ']';
+  } else if (Node->getNumArgs() == 1) {
+    OS << OpStrings[Kind] << ' ';
+    PrintExpr(Node->getArg(0));
+  } else if (Node->getNumArgs() == 2) {
+    PrintExpr(Node->getArg(0));
+    OS << ' ' << OpStrings[Kind] << ' ';
+    PrintExpr(Node->getArg(1));
+  } else {
+    assert(false && "unknown overloaded operator");
+  }
+}
+
+void StmtPrinter::VisitCXXMemberCallExpr(CXXMemberCallExpr *Node) {
+  VisitCallExpr(cast<CallExpr>(Node));
+}
+
+void StmtPrinter::VisitCXXNamedCastExpr(CXXNamedCastExpr *Node) {
+  OS << Node->getCastName() << '<';
+  OS << Node->getTypeAsWritten().getAsString() << ">(";
+  PrintExpr(Node->getSubExpr());
+  OS << ")";
+}
+
+void StmtPrinter::VisitCXXStaticCastExpr(CXXStaticCastExpr *Node) {
+  VisitCXXNamedCastExpr(Node);
+}
+
+void StmtPrinter::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *Node) {
+  VisitCXXNamedCastExpr(Node);
+}
+
+void StmtPrinter::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *Node) {
+  VisitCXXNamedCastExpr(Node);
+}
+
+void StmtPrinter::VisitCXXConstCastExpr(CXXConstCastExpr *Node) {
+  VisitCXXNamedCastExpr(Node);
+}
+
+void StmtPrinter::VisitCXXTypeidExpr(CXXTypeidExpr *Node) {
+  OS << "typeid(";
+  if (Node->isTypeOperand()) {
+    OS << Node->getTypeOperand().getAsString();
+  } else {
+    PrintExpr(Node->getExprOperand());
+  }
+  OS << ")";
+}
+
+void StmtPrinter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) {
+  OS << (Node->getValue() ? "true" : "false");
+}
+
+void StmtPrinter::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *Node) {
+  OS << "nullptr";
+}
+
+void StmtPrinter::VisitCXXThisExpr(CXXThisExpr *Node) {
+  OS << "this";
+}
+
+void StmtPrinter::VisitCXXThrowExpr(CXXThrowExpr *Node) {
+  if (Node->getSubExpr() == 0)
+    OS << "throw";
+  else {
+    OS << "throw ";
+    PrintExpr(Node->getSubExpr());
+  }
+}
+
+void StmtPrinter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *Node) {
+  // Nothing to print: we picked up the default argument
+}
+
+void StmtPrinter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node) {
+  OS << Node->getType().getAsString();
+  OS << "(";
+  PrintExpr(Node->getSubExpr());
+  OS << ")";
+}
+
+void StmtPrinter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *Node) {
+  PrintExpr(Node->getSubExpr());
+}
+
+void StmtPrinter::VisitCXXBindReferenceExpr(CXXBindReferenceExpr *Node) {
+  PrintExpr(Node->getSubExpr());
+}
+
+void StmtPrinter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *Node) {
+  OS << Node->getType().getAsString();
+  OS << "(";
+  for (CXXTemporaryObjectExpr::arg_iterator Arg = Node->arg_begin(),
+                                         ArgEnd = Node->arg_end();
+       Arg != ArgEnd; ++Arg) {
+    if (Arg != Node->arg_begin())
+      OS << ", ";
+    PrintExpr(*Arg);
+  }
+  OS << ")";
+}
+
+void StmtPrinter::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *Node) {
+  OS << Node->getType().getAsString() << "()";
+}
+
+void StmtPrinter::VisitCXXNewExpr(CXXNewExpr *E) {
+  if (E->isGlobalNew())
+    OS << "::";
+  OS << "new ";
+  unsigned NumPlace = E->getNumPlacementArgs();
+  if (NumPlace > 0) {
+    OS << "(";
+    PrintExpr(E->getPlacementArg(0));
+    for (unsigned i = 1; i < NumPlace; ++i) {
+      OS << ", ";
+      PrintExpr(E->getPlacementArg(i));
+    }
+    OS << ") ";
+  }
+  if (E->isParenTypeId())
+    OS << "(";
+  std::string TypeS;
+  if (Expr *Size = E->getArraySize()) {
+    llvm::raw_string_ostream s(TypeS);
+    Size->printPretty(s, Context, Helper, Policy);
+    s.flush();
+    TypeS = "[" + TypeS + "]";
+  }
+  E->getAllocatedType().getAsStringInternal(TypeS, Policy);
+  OS << TypeS;
+  if (E->isParenTypeId())
+    OS << ")";
+
+  if (E->hasInitializer()) {
+    OS << "(";
+    unsigned NumCons = E->getNumConstructorArgs();
+    if (NumCons > 0) {
+      PrintExpr(E->getConstructorArg(0));
+      for (unsigned i = 1; i < NumCons; ++i) {
+        OS << ", ";
+        PrintExpr(E->getConstructorArg(i));
+      }
+    }
+    OS << ")";
+  }
+}
+
+void StmtPrinter::VisitCXXDeleteExpr(CXXDeleteExpr *E) {
+  if (E->isGlobalDelete())
+    OS << "::";
+  OS << "delete ";
+  if (E->isArrayForm())
+    OS << "[] ";
+  PrintExpr(E->getArgument());
+}
+
+void StmtPrinter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
+  PrintExpr(E->getBase());
+  if (E->isArrow())
+    OS << "->";
+  else
+    OS << '.';
+  if (E->getQualifier())
+    E->getQualifier()->print(OS, Policy);
+
+  std::string TypeS;
+  if (IdentifierInfo *II = E->getDestroyedTypeIdentifier())
+    OS << II->getName();
+  else
+    E->getDestroyedType().getAsStringInternal(TypeS, Policy);
+  OS << TypeS;
+}
+
+void StmtPrinter::VisitCXXConstructExpr(CXXConstructExpr *E) {
+  // FIXME. For now we just print a trivial constructor call expression,
+  // constructing its first argument object.
+  if (E->getNumArgs() == 1) {
+    CXXConstructorDecl *CD = E->getConstructor();
+    if (CD->isTrivial())
+      PrintExpr(E->getArg(0));
+  }
+  // Nothing to print.
+}
+
+void StmtPrinter::VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E) {
+  // Just forward to the sub expression.
+  PrintExpr(E->getSubExpr());
+}
+
+void
+StmtPrinter::VisitCXXUnresolvedConstructExpr(
+                                           CXXUnresolvedConstructExpr *Node) {
+  OS << Node->getTypeAsWritten().getAsString();
+  OS << "(";
+  for (CXXUnresolvedConstructExpr::arg_iterator Arg = Node->arg_begin(),
+                                             ArgEnd = Node->arg_end();
+       Arg != ArgEnd; ++Arg) {
+    if (Arg != Node->arg_begin())
+      OS << ", ";
+    PrintExpr(*Arg);
+  }
+  OS << ")";
+}
+
+void StmtPrinter::VisitCXXDependentScopeMemberExpr(
+                                         CXXDependentScopeMemberExpr *Node) {
+  if (!Node->isImplicitAccess()) {
+    PrintExpr(Node->getBase());
+    OS << (Node->isArrow() ? "->" : ".");
+  }
+  if (NestedNameSpecifier *Qualifier = Node->getQualifier())
+    Qualifier->print(OS, Policy);
+  else if (Node->hasExplicitTemplateArgs())
+    // FIXME: Track use of "template" keyword explicitly?
+    OS << "template ";
+
+  OS << Node->getMember().getAsString();
+
+  if (Node->hasExplicitTemplateArgs()) {
+    OS << TemplateSpecializationType::PrintTemplateArgumentList(
+                                                    Node->getTemplateArgs(),
+                                                    Node->getNumTemplateArgs(),
+                                                    Policy);
+  }
+}
+
+void StmtPrinter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *Node) {
+  if (!Node->isImplicitAccess()) {
+    PrintExpr(Node->getBase());
+    OS << (Node->isArrow() ? "->" : ".");
+  }
+  if (NestedNameSpecifier *Qualifier = Node->getQualifier())
+    Qualifier->print(OS, Policy);
+
+  // FIXME: this might originally have been written with 'template'
+
+  OS << Node->getMemberName().getAsString();
+
+  if (Node->hasExplicitTemplateArgs()) {
+    OS << TemplateSpecializationType::PrintTemplateArgumentList(
+                                                    Node->getTemplateArgs(),
+                                                    Node->getNumTemplateArgs(),
+                                                    Policy);
+  }
+}
+
+static const char *getTypeTraitName(UnaryTypeTrait UTT) {
+  switch (UTT) {
+  default: assert(false && "Unknown type trait");
+  case UTT_HasNothrowAssign:      return "__has_nothrow_assign";
+  case UTT_HasNothrowCopy:        return "__has_nothrow_copy";
+  case UTT_HasNothrowConstructor: return "__has_nothrow_constructor";
+  case UTT_HasTrivialAssign:      return "__has_trivial_assign";
+  case UTT_HasTrivialCopy:        return "__has_trivial_copy";
+  case UTT_HasTrivialConstructor: return "__has_trivial_constructor";
+  case UTT_HasTrivialDestructor:  return "__has_trivial_destructor";
+  case UTT_HasVirtualDestructor:  return "__has_virtual_destructor";
+  case UTT_IsAbstract:            return "__is_abstract";
+  case UTT_IsClass:               return "__is_class";
+  case UTT_IsEmpty:               return "__is_empty";
+  case UTT_IsEnum:                return "__is_enum";
+  case UTT_IsPOD:                 return "__is_pod";
+  case UTT_IsPolymorphic:         return "__is_polymorphic";
+  case UTT_IsUnion:               return "__is_union";
+  }
+}
+
+void StmtPrinter::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
+  OS << getTypeTraitName(E->getTrait()) << "("
+     << E->getQueriedType().getAsString() << ")";
+}
+
+// Obj-C
+
+void StmtPrinter::VisitObjCStringLiteral(ObjCStringLiteral *Node) {
+  OS << "@";
+  VisitStringLiteral(Node->getString());
+}
+
+void StmtPrinter::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) {
+  OS << "@encode(" << Node->getEncodedType().getAsString() << ')';
+}
+
+void StmtPrinter::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) {
+  OS << "@selector(" << Node->getSelector().getAsString() << ')';
+}
+
+void StmtPrinter::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) {
+  OS << "@protocol(" << Node->getProtocol() << ')';
+}
+
+void StmtPrinter::VisitObjCMessageExpr(ObjCMessageExpr *Mess) {
+  OS << "[";
+  switch (Mess->getReceiverKind()) {
+  case ObjCMessageExpr::Instance:
+    PrintExpr(Mess->getInstanceReceiver());
+    break;
+
+  case ObjCMessageExpr::Class:
+    OS << Mess->getClassReceiver().getAsString(Policy);
+    break;
+
+  case ObjCMessageExpr::SuperInstance:
+  case ObjCMessageExpr::SuperClass:
+    OS << "Super";
+    break;
+  }
+
+  OS << ' ';
+  Selector selector = Mess->getSelector();
+  if (selector.isUnarySelector()) {
+    OS << selector.getIdentifierInfoForSlot(0)->getName();
+  } else {
+    for (unsigned i = 0, e = Mess->getNumArgs(); i != e; ++i) {
+      if (i < selector.getNumArgs()) {
+        if (i > 0) OS << ' ';
+        if (selector.getIdentifierInfoForSlot(i))
+          OS << selector.getIdentifierInfoForSlot(i)->getName() << ':';
+        else
+           OS << ":";
+      }
+      else OS << ", "; // Handle variadic methods.
+
+      PrintExpr(Mess->getArg(i));
+    }
+  }
+  OS << "]";
+}
+
+void StmtPrinter::VisitObjCSuperExpr(ObjCSuperExpr *) {
+  OS << "super";
+}
+
+void StmtPrinter::VisitBlockExpr(BlockExpr *Node) {
+  BlockDecl *BD = Node->getBlockDecl();
+  OS << "^";
+
+  const FunctionType *AFT = Node->getFunctionType();
+
+  if (isa<FunctionNoProtoType>(AFT)) {
+    OS << "()";
+  } else if (!BD->param_empty() || cast<FunctionProtoType>(AFT)->isVariadic()) {
+    OS << '(';
+    std::string ParamStr;
+    for (BlockDecl::param_iterator AI = BD->param_begin(),
+         E = BD->param_end(); AI != E; ++AI) {
+      if (AI != BD->param_begin()) OS << ", ";
+      ParamStr = (*AI)->getNameAsString();
+      (*AI)->getType().getAsStringInternal(ParamStr, Policy);
+      OS << ParamStr;
+    }
+
+    const FunctionProtoType *FT = cast<FunctionProtoType>(AFT);
+    if (FT->isVariadic()) {
+      if (!BD->param_empty()) OS << ", ";
+      OS << "...";
+    }
+    OS << ')';
+  }
+}
+
+void StmtPrinter::VisitBlockDeclRefExpr(BlockDeclRefExpr *Node) {
+  OS << Node->getDecl();
+}
+//===----------------------------------------------------------------------===//
+// Stmt method implementations
+//===----------------------------------------------------------------------===//
+
+void Stmt::dumpPretty(ASTContext& Context) const {
+  printPretty(llvm::errs(), Context, 0,
+              PrintingPolicy(Context.getLangOptions()));
+}
+
+void Stmt::printPretty(llvm::raw_ostream &OS, ASTContext& Context,
+                       PrinterHelper* Helper,
+                       const PrintingPolicy &Policy,
+                       unsigned Indentation) const {
+  if (this == 0) {
+    OS << "<NULL>";
+    return;
+  }
+
+  if (Policy.Dump && &Context) {
+    dump(Context.getSourceManager());
+    return;
+  }
+
+  StmtPrinter P(OS, Context, Helper, Policy, Indentation);
+  P.Visit(const_cast<Stmt*>(this));
+}
+
+//===----------------------------------------------------------------------===//
+// PrinterHelper
+//===----------------------------------------------------------------------===//
+
+// Implement virtual destructor.
+PrinterHelper::~PrinterHelper() {}
diff --git a/lib/AST/StmtProfile.cpp b/lib/AST/StmtProfile.cpp
new file mode 100644
index 0000000..3a19ec2
--- /dev/null
+++ b/lib/AST/StmtProfile.cpp
@@ -0,0 +1,741 @@
+//===---- StmtProfile.cpp - Profile implementation for Stmt ASTs ----------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Stmt::Profile method, which builds a unique bit
+// representation that identifies a statement/expression.
+//
+//===----------------------------------------------------------------------===//
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/ExprObjC.h"
+#include "clang/AST/StmtVisitor.h"
+#include "llvm/ADT/FoldingSet.h"
+using namespace clang;
+
+namespace {
+  class StmtProfiler : public StmtVisitor<StmtProfiler> {
+    llvm::FoldingSetNodeID &ID;
+    ASTContext &Context;
+    bool Canonical;
+
+  public:
+    StmtProfiler(llvm::FoldingSetNodeID &ID, ASTContext &Context,
+                 bool Canonical)
+      : ID(ID), Context(Context), Canonical(Canonical) { }
+
+    void VisitStmt(Stmt *S);
+
+#define STMT(Node, Base) void Visit##Node(Node *S);
+#include "clang/AST/StmtNodes.def"
+
+    /// \brief Visit a declaration that is referenced within an expression
+    /// or statement.
+    void VisitDecl(Decl *D);
+
+    /// \brief Visit a type that is referenced within an expression or
+    /// statement.
+    void VisitType(QualType T);
+
+    /// \brief Visit a name that occurs within an expression or statement.
+    void VisitName(DeclarationName Name);
+
+    /// \brief Visit a nested-name-specifier that occurs within an expression
+    /// or statement.
+    void VisitNestedNameSpecifier(NestedNameSpecifier *NNS);
+
+    /// \brief Visit a template name that occurs within an expression or
+    /// statement.
+    void VisitTemplateName(TemplateName Name);
+
+    /// \brief Visit template arguments that occur within an expression or
+    /// statement.
+    void VisitTemplateArguments(const TemplateArgumentLoc *Args, unsigned NumArgs);
+
+    /// \brief Visit a single template argument.
+    void VisitTemplateArgument(const TemplateArgument &Arg);
+  };
+}
+
+void StmtProfiler::VisitStmt(Stmt *S) {
+  ID.AddInteger(S->getStmtClass());
+  for (Stmt::child_iterator C = S->child_begin(), CEnd = S->child_end();
+       C != CEnd; ++C)
+    Visit(*C);
+}
+
+void StmtProfiler::VisitDeclStmt(DeclStmt *S) {
+  VisitStmt(S);
+  for (DeclStmt::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
+       D != DEnd; ++D)
+    VisitDecl(*D);
+}
+
+void StmtProfiler::VisitNullStmt(NullStmt *S) {
+  VisitStmt(S);
+}
+
+void StmtProfiler::VisitCompoundStmt(CompoundStmt *S) {
+  VisitStmt(S);
+}
+
+void StmtProfiler::VisitSwitchCase(SwitchCase *S) {
+  VisitStmt(S);
+}
+
+void StmtProfiler::VisitCaseStmt(CaseStmt *S) {
+  VisitStmt(S);
+}
+
+void StmtProfiler::VisitDefaultStmt(DefaultStmt *S) {
+  VisitStmt(S);
+}
+
+void StmtProfiler::VisitLabelStmt(LabelStmt *S) {
+  VisitStmt(S);
+  VisitName(S->getID());
+}
+
+void StmtProfiler::VisitIfStmt(IfStmt *S) {
+  VisitStmt(S);
+  VisitDecl(S->getConditionVariable());
+}
+
+void StmtProfiler::VisitSwitchStmt(SwitchStmt *S) {
+  VisitStmt(S);
+  VisitDecl(S->getConditionVariable());
+}
+
+void StmtProfiler::VisitWhileStmt(WhileStmt *S) {
+  VisitStmt(S);
+  VisitDecl(S->getConditionVariable());
+}
+
+void StmtProfiler::VisitDoStmt(DoStmt *S) {
+  VisitStmt(S);
+}
+
+void StmtProfiler::VisitForStmt(ForStmt *S) {
+  VisitStmt(S);
+}
+
+void StmtProfiler::VisitGotoStmt(GotoStmt *S) {
+  VisitStmt(S);
+  VisitName(S->getLabel()->getID());
+}
+
+void StmtProfiler::VisitIndirectGotoStmt(IndirectGotoStmt *S) {
+  VisitStmt(S);
+}
+
+void StmtProfiler::VisitContinueStmt(ContinueStmt *S) {
+  VisitStmt(S);
+}
+
+void StmtProfiler::VisitBreakStmt(BreakStmt *S) {
+  VisitStmt(S);
+}
+
+void StmtProfiler::VisitReturnStmt(ReturnStmt *S) {
+  VisitStmt(S);
+}
+
+void StmtProfiler::VisitAsmStmt(AsmStmt *S) {
+  VisitStmt(S);
+  ID.AddBoolean(S->isVolatile());
+  ID.AddBoolean(S->isSimple());
+  VisitStringLiteral(S->getAsmString());
+  ID.AddInteger(S->getNumOutputs());
+  for (unsigned I = 0, N = S->getNumOutputs(); I != N; ++I) {
+    ID.AddString(S->getOutputName(I));
+    VisitStringLiteral(S->getOutputConstraintLiteral(I));
+  }
+  ID.AddInteger(S->getNumInputs());
+  for (unsigned I = 0, N = S->getNumInputs(); I != N; ++I) {
+    ID.AddString(S->getInputName(I));
+    VisitStringLiteral(S->getInputConstraintLiteral(I));
+  }
+  ID.AddInteger(S->getNumClobbers());
+  for (unsigned I = 0, N = S->getNumClobbers(); I != N; ++I)
+    VisitStringLiteral(S->getClobber(I));
+}
+
+void StmtProfiler::VisitCXXCatchStmt(CXXCatchStmt *S) {
+  VisitStmt(S);
+  VisitType(S->getCaughtType());
+}
+
+void StmtProfiler::VisitCXXTryStmt(CXXTryStmt *S) {
+  VisitStmt(S);
+}
+
+void StmtProfiler::VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) {
+  VisitStmt(S);
+}
+
+void StmtProfiler::VisitObjCAtCatchStmt(ObjCAtCatchStmt *S) {
+  VisitStmt(S);
+  ID.AddBoolean(S->hasEllipsis());
+  if (S->getCatchParamDecl())
+    VisitType(S->getCatchParamDecl()->getType());
+}
+
+void StmtProfiler::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
+  VisitStmt(S);
+}
+
+void StmtProfiler::VisitObjCAtTryStmt(ObjCAtTryStmt *S) {
+  VisitStmt(S);
+}
+
+void StmtProfiler::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *S) {
+  VisitStmt(S);
+}
+
+void StmtProfiler::VisitObjCAtThrowStmt(ObjCAtThrowStmt *S) {
+  VisitStmt(S);
+}
+
+void StmtProfiler::VisitExpr(Expr *S) {
+  VisitStmt(S);
+}
+
+void StmtProfiler::VisitDeclRefExpr(DeclRefExpr *S) {
+  VisitExpr(S);
+  VisitNestedNameSpecifier(S->getQualifier());
+  VisitDecl(S->getDecl());
+  VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
+}
+
+void StmtProfiler::VisitPredefinedExpr(PredefinedExpr *S) {
+  VisitExpr(S);
+  ID.AddInteger(S->getIdentType());
+}
+
+void StmtProfiler::VisitIntegerLiteral(IntegerLiteral *S) {
+  VisitExpr(S);
+  S->getValue().Profile(ID);
+}
+
+void StmtProfiler::VisitCharacterLiteral(CharacterLiteral *S) {
+  VisitExpr(S);
+  ID.AddBoolean(S->isWide());
+  ID.AddInteger(S->getValue());
+}
+
+void StmtProfiler::VisitFloatingLiteral(FloatingLiteral *S) {
+  VisitExpr(S);
+  S->getValue().Profile(ID);
+  ID.AddBoolean(S->isExact());
+}
+
+void StmtProfiler::VisitImaginaryLiteral(ImaginaryLiteral *S) {
+  VisitExpr(S);
+}
+
+void StmtProfiler::VisitStringLiteral(StringLiteral *S) {
+  VisitExpr(S);
+  ID.AddString(S->getString());
+  ID.AddBoolean(S->isWide());
+}
+
+void StmtProfiler::VisitParenExpr(ParenExpr *S) {
+  VisitExpr(S);
+}
+
+void StmtProfiler::VisitParenListExpr(ParenListExpr *S) {
+  VisitExpr(S);
+}
+
+void StmtProfiler::VisitUnaryOperator(UnaryOperator *S) {
+  VisitExpr(S);
+  ID.AddInteger(S->getOpcode());
+}
+
+void StmtProfiler::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *S) {
+  VisitExpr(S);
+  ID.AddBoolean(S->isSizeOf());
+  if (S->isArgumentType())
+    VisitType(S->getArgumentType());
+}
+
+void StmtProfiler::VisitArraySubscriptExpr(ArraySubscriptExpr *S) {
+  VisitExpr(S);
+}
+
+void StmtProfiler::VisitCallExpr(CallExpr *S) {
+  VisitExpr(S);
+}
+
+void StmtProfiler::VisitMemberExpr(MemberExpr *S) {
+  VisitExpr(S);
+  VisitDecl(S->getMemberDecl());
+  VisitNestedNameSpecifier(S->getQualifier());
+  ID.AddBoolean(S->isArrow());
+}
+
+void StmtProfiler::VisitCompoundLiteralExpr(CompoundLiteralExpr *S) {
+  VisitExpr(S);
+  ID.AddBoolean(S->isFileScope());
+}
+
+void StmtProfiler::VisitCastExpr(CastExpr *S) {
+  VisitExpr(S);
+}
+
+void StmtProfiler::VisitImplicitCastExpr(ImplicitCastExpr *S) {
+  VisitCastExpr(S);
+  ID.AddBoolean(S->isLvalueCast());
+}
+
+void StmtProfiler::VisitExplicitCastExpr(ExplicitCastExpr *S) {
+  VisitCastExpr(S);
+  VisitType(S->getTypeAsWritten());
+}
+
+void StmtProfiler::VisitCStyleCastExpr(CStyleCastExpr *S) {
+  VisitExplicitCastExpr(S);
+}
+
+void StmtProfiler::VisitBinaryOperator(BinaryOperator *S) {
+  VisitExpr(S);
+  ID.AddInteger(S->getOpcode());
+}
+
+void StmtProfiler::VisitCompoundAssignOperator(CompoundAssignOperator *S) {
+  VisitBinaryOperator(S);
+}
+
+void StmtProfiler::VisitConditionalOperator(ConditionalOperator *S) {
+  VisitExpr(S);
+}
+
+void StmtProfiler::VisitAddrLabelExpr(AddrLabelExpr *S) {
+  VisitExpr(S);
+  VisitName(S->getLabel()->getID());
+}
+
+void StmtProfiler::VisitStmtExpr(StmtExpr *S) {
+  VisitExpr(S);
+}
+
+void StmtProfiler::VisitTypesCompatibleExpr(TypesCompatibleExpr *S) {
+  VisitExpr(S);
+  VisitType(S->getArgType1());
+  VisitType(S->getArgType2());
+}
+
+void StmtProfiler::VisitShuffleVectorExpr(ShuffleVectorExpr *S) {
+  VisitExpr(S);
+}
+
+void StmtProfiler::VisitChooseExpr(ChooseExpr *S) {
+  VisitExpr(S);
+}
+
+void StmtProfiler::VisitGNUNullExpr(GNUNullExpr *S) {
+  VisitExpr(S);
+}
+
+void StmtProfiler::VisitVAArgExpr(VAArgExpr *S) {
+  VisitExpr(S);
+}
+
+void StmtProfiler::VisitInitListExpr(InitListExpr *S) {
+  if (S->getSyntacticForm()) {
+    VisitInitListExpr(S->getSyntacticForm());
+    return;
+  }
+
+  VisitExpr(S);
+}
+
+void StmtProfiler::VisitDesignatedInitExpr(DesignatedInitExpr *S) {
+  VisitExpr(S);
+  ID.AddBoolean(S->usesGNUSyntax());
+  for (DesignatedInitExpr::designators_iterator D = S->designators_begin(),
+                                             DEnd = S->designators_end();
+       D != DEnd; ++D) {
+    if (D->isFieldDesignator()) {
+      ID.AddInteger(0);
+      VisitName(D->getFieldName());
+      continue;
+    }
+
+    if (D->isArrayDesignator()) {
+      ID.AddInteger(1);
+    } else {
+      assert(D->isArrayRangeDesignator());
+      ID.AddInteger(2);
+    }
+    ID.AddInteger(D->getFirstExprIndex());
+  }
+}
+
+void StmtProfiler::VisitImplicitValueInitExpr(ImplicitValueInitExpr *S) {
+  VisitExpr(S);
+}
+
+void StmtProfiler::VisitExtVectorElementExpr(ExtVectorElementExpr *S) {
+  VisitExpr(S);
+  VisitName(&S->getAccessor());
+}
+
+void StmtProfiler::VisitBlockExpr(BlockExpr *S) {
+  VisitExpr(S);
+  VisitDecl(S->getBlockDecl());
+}
+
+void StmtProfiler::VisitBlockDeclRefExpr(BlockDeclRefExpr *S) {
+  VisitExpr(S);
+  VisitDecl(S->getDecl());
+  ID.AddBoolean(S->isByRef());
+  ID.AddBoolean(S->isConstQualAdded());
+}
+
+void StmtProfiler::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *S) {
+  VisitCallExpr(S);
+  ID.AddInteger(S->getOperator());
+}
+
+void StmtProfiler::VisitCXXMemberCallExpr(CXXMemberCallExpr *S) {
+  VisitCallExpr(S);
+}
+
+void StmtProfiler::VisitCXXNamedCastExpr(CXXNamedCastExpr *S) {
+  VisitExplicitCastExpr(S);
+}
+
+void StmtProfiler::VisitCXXStaticCastExpr(CXXStaticCastExpr *S) {
+  VisitCXXNamedCastExpr(S);
+}
+
+void StmtProfiler::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *S) {
+  VisitCXXNamedCastExpr(S);
+}
+
+void StmtProfiler::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *S) {
+  VisitCXXNamedCastExpr(S);
+}
+
+void StmtProfiler::VisitCXXConstCastExpr(CXXConstCastExpr *S) {
+  VisitCXXNamedCastExpr(S);
+}
+
+void StmtProfiler::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *S) {
+  VisitExpr(S);
+  ID.AddBoolean(S->getValue());
+}
+
+void StmtProfiler::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *S) {
+  VisitExpr(S);
+}
+
+void StmtProfiler::VisitCXXTypeidExpr(CXXTypeidExpr *S) {
+  VisitExpr(S);
+  if (S->isTypeOperand())
+    VisitType(S->getTypeOperand());
+}
+
+void StmtProfiler::VisitCXXThisExpr(CXXThisExpr *S) {
+  VisitExpr(S);
+}
+
+void StmtProfiler::VisitCXXThrowExpr(CXXThrowExpr *S) {
+  VisitExpr(S);
+}
+
+void StmtProfiler::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *S) {
+  VisitExpr(S);
+  VisitDecl(S->getParam());
+}
+
+void StmtProfiler::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *S) {
+  VisitExpr(S);
+  VisitDecl(
+         const_cast<CXXDestructorDecl *>(S->getTemporary()->getDestructor()));
+}
+
+void StmtProfiler::VisitCXXBindReferenceExpr(CXXBindReferenceExpr *S) {
+  VisitExpr(S);
+}
+
+void StmtProfiler::VisitCXXConstructExpr(CXXConstructExpr *S) {
+  VisitExpr(S);
+  VisitDecl(S->getConstructor());
+  ID.AddBoolean(S->isElidable());
+}
+
+void StmtProfiler::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *S) {
+  VisitExplicitCastExpr(S);
+}
+
+void StmtProfiler::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *S) {
+  VisitCXXConstructExpr(S);
+}
+
+void StmtProfiler::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *S) {
+  VisitExpr(S);
+}
+
+void StmtProfiler::VisitCXXDeleteExpr(CXXDeleteExpr *S) {
+  VisitExpr(S);
+  ID.AddBoolean(S->isGlobalDelete());
+  ID.AddBoolean(S->isArrayForm());
+  VisitDecl(S->getOperatorDelete());
+}
+
+
+void StmtProfiler::VisitCXXNewExpr(CXXNewExpr *S) {
+  VisitExpr(S);
+  VisitType(S->getAllocatedType());
+  VisitDecl(S->getOperatorNew());
+  VisitDecl(S->getOperatorDelete());
+  VisitDecl(S->getConstructor());
+  ID.AddBoolean(S->isArray());
+  ID.AddInteger(S->getNumPlacementArgs());
+  ID.AddBoolean(S->isGlobalNew());
+  ID.AddBoolean(S->isParenTypeId());
+  ID.AddBoolean(S->hasInitializer());
+  ID.AddInteger(S->getNumConstructorArgs());
+}
+
+void StmtProfiler::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *S) {
+  VisitExpr(S);
+  ID.AddBoolean(S->isArrow());
+  VisitNestedNameSpecifier(S->getQualifier());
+  VisitType(S->getDestroyedType());
+}
+
+void
+StmtProfiler::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *S) {
+  VisitExpr(S);
+  VisitNestedNameSpecifier(S->getQualifier());
+  VisitName(S->getName());
+  ID.AddBoolean(S->hasExplicitTemplateArgs());
+  if (S->hasExplicitTemplateArgs())
+    VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
+}
+
+void StmtProfiler::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *S) {
+  VisitExpr(S);
+  ID.AddInteger(S->getTrait());
+  VisitType(S->getQueriedType());
+}
+
+void
+StmtProfiler::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *S) {
+  VisitExpr(S);
+  VisitName(S->getDeclName());
+  VisitNestedNameSpecifier(S->getQualifier());
+  ID.AddBoolean(S->hasExplicitTemplateArgs());
+  if (S->hasExplicitTemplateArgs())
+    VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
+}
+
+void StmtProfiler::VisitCXXExprWithTemporaries(CXXExprWithTemporaries *S) {
+  VisitExpr(S);
+  for (unsigned I = 0, N = S->getNumTemporaries(); I != N; ++I)
+    VisitDecl(
+      const_cast<CXXDestructorDecl *>(S->getTemporary(I)->getDestructor()));
+}
+
+void
+StmtProfiler::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *S) {
+  VisitExpr(S);
+  VisitType(S->getTypeAsWritten());
+}
+
+void
+StmtProfiler::VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *S) {
+  ID.AddBoolean(S->isImplicitAccess());
+  if (!S->isImplicitAccess()) {
+    VisitExpr(S);
+    ID.AddBoolean(S->isArrow());
+  }
+  VisitNestedNameSpecifier(S->getQualifier());
+  VisitName(S->getMember());
+  ID.AddBoolean(S->hasExplicitTemplateArgs());
+  if (S->hasExplicitTemplateArgs())
+    VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
+}
+
+void StmtProfiler::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *S) {
+  ID.AddBoolean(S->isImplicitAccess());
+  if (!S->isImplicitAccess()) {
+    VisitExpr(S);
+    ID.AddBoolean(S->isArrow());
+  }
+  VisitNestedNameSpecifier(S->getQualifier());
+  VisitName(S->getMemberName());
+  ID.AddBoolean(S->hasExplicitTemplateArgs());
+  if (S->hasExplicitTemplateArgs())
+    VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
+}
+
+void StmtProfiler::VisitObjCStringLiteral(ObjCStringLiteral *S) {
+  VisitExpr(S);
+}
+
+void StmtProfiler::VisitObjCEncodeExpr(ObjCEncodeExpr *S) {
+  VisitExpr(S);
+  VisitType(S->getEncodedType());
+}
+
+void StmtProfiler::VisitObjCSelectorExpr(ObjCSelectorExpr *S) {
+  VisitExpr(S);
+  VisitName(S->getSelector());
+}
+
+void StmtProfiler::VisitObjCProtocolExpr(ObjCProtocolExpr *S) {
+  VisitExpr(S);
+  VisitDecl(S->getProtocol());
+}
+
+void StmtProfiler::VisitObjCIvarRefExpr(ObjCIvarRefExpr *S) {
+  VisitExpr(S);
+  VisitDecl(S->getDecl());
+  ID.AddBoolean(S->isArrow());
+  ID.AddBoolean(S->isFreeIvar());
+}
+
+void StmtProfiler::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *S) {
+  VisitExpr(S);
+  VisitDecl(S->getProperty());
+}
+
+void StmtProfiler::VisitObjCImplicitSetterGetterRefExpr(
+                                  ObjCImplicitSetterGetterRefExpr *S) {
+  VisitExpr(S);
+  VisitDecl(S->getGetterMethod());
+  VisitDecl(S->getSetterMethod());
+  VisitDecl(S->getInterfaceDecl());
+}
+
+void StmtProfiler::VisitObjCMessageExpr(ObjCMessageExpr *S) {
+  VisitExpr(S);
+  VisitName(S->getSelector());
+  VisitDecl(S->getMethodDecl());
+}
+
+void StmtProfiler::VisitObjCSuperExpr(ObjCSuperExpr *S) {
+  VisitExpr(S);
+}
+
+void StmtProfiler::VisitObjCIsaExpr(ObjCIsaExpr *S) {
+  VisitExpr(S);
+  ID.AddBoolean(S->isArrow());
+}
+
+void StmtProfiler::VisitDecl(Decl *D) {
+  ID.AddInteger(D? D->getKind() : 0);
+
+  if (Canonical && D) {
+    if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D)) {
+      ID.AddInteger(NTTP->getDepth());
+      ID.AddInteger(NTTP->getIndex());
+      VisitType(NTTP->getType());
+      return;
+    }
+
+    if (ParmVarDecl *Parm = dyn_cast<ParmVarDecl>(D)) {
+      // The Itanium C++ ABI uses the type of a parameter when mangling
+      // expressions that involve function parameters, so we will use the
+      // parameter's type for establishing function parameter identity. That
+      // way, our definition of "equivalent" (per C++ [temp.over.link])
+      // matches the definition of "equivalent" used for name mangling.
+      VisitType(Parm->getType());
+      return;
+    }
+
+    if (TemplateTemplateParmDecl *TTP = dyn_cast<TemplateTemplateParmDecl>(D)) {
+      ID.AddInteger(TTP->getDepth());
+      ID.AddInteger(TTP->getIndex());
+      return;
+    }
+  }
+
+  ID.AddPointer(D? D->getCanonicalDecl() : 0);
+}
+
+void StmtProfiler::VisitType(QualType T) {
+  if (Canonical)
+    T = Context.getCanonicalType(T);
+
+  ID.AddPointer(T.getAsOpaquePtr());
+}
+
+void StmtProfiler::VisitName(DeclarationName Name) {
+  ID.AddPointer(Name.getAsOpaquePtr());
+}
+
+void StmtProfiler::VisitNestedNameSpecifier(NestedNameSpecifier *NNS) {
+  if (Canonical)
+    NNS = Context.getCanonicalNestedNameSpecifier(NNS);
+  ID.AddPointer(NNS);
+}
+
+void StmtProfiler::VisitTemplateName(TemplateName Name) {
+  if (Canonical)
+    Name = Context.getCanonicalTemplateName(Name);
+
+  Name.Profile(ID);
+}
+
+void StmtProfiler::VisitTemplateArguments(const TemplateArgumentLoc *Args,
+                                          unsigned NumArgs) {
+  ID.AddInteger(NumArgs);
+  for (unsigned I = 0; I != NumArgs; ++I)
+    VisitTemplateArgument(Args[I].getArgument());
+}
+
+void StmtProfiler::VisitTemplateArgument(const TemplateArgument &Arg) {
+  // Mostly repetitive with TemplateArgument::Profile!
+  ID.AddInteger(Arg.getKind());
+  switch (Arg.getKind()) {
+  case TemplateArgument::Null:
+    break;
+
+  case TemplateArgument::Type:
+    VisitType(Arg.getAsType());
+    break;
+
+  case TemplateArgument::Template:
+    VisitTemplateName(Arg.getAsTemplate());
+    break;
+      
+  case TemplateArgument::Declaration:
+    VisitDecl(Arg.getAsDecl());
+    break;
+
+  case TemplateArgument::Integral:
+    Arg.getAsIntegral()->Profile(ID);
+    VisitType(Arg.getIntegralType());
+    break;
+
+  case TemplateArgument::Expression:
+    Visit(Arg.getAsExpr());
+    break;
+
+  case TemplateArgument::Pack:
+    const TemplateArgument *Pack = Arg.pack_begin();
+    for (unsigned i = 0, e = Arg.pack_size(); i != e; ++i)
+      VisitTemplateArgument(Pack[i]);
+    break;
+  }
+}
+
+void Stmt::Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context,
+                   bool Canonical) {
+  StmtProfiler Profiler(ID, Context, Canonical);
+  Profiler.Visit(this);
+}
diff --git a/lib/AST/StmtViz.cpp b/lib/AST/StmtViz.cpp
new file mode 100644
index 0000000..8be287e
--- /dev/null
+++ b/lib/AST/StmtViz.cpp
@@ -0,0 +1,62 @@
+//===--- StmtViz.cpp - Graphviz visualization for Stmt ASTs -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements Stmt::viewAST, which generates a Graphviz DOT file
+//  that depicts the AST and then calls Graphviz/dot+gv on it.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/StmtGraphTraits.h"
+#include "clang/AST/Decl.h"
+#include "llvm/Support/GraphWriter.h"
+
+using namespace clang;
+
+void Stmt::viewAST() const {
+#ifndef NDEBUG
+  llvm::ViewGraph(this,"AST");
+#else
+  llvm::errs() << "Stmt::viewAST is only available in debug builds on "
+               << "systems with Graphviz or gv!\n";
+#endif
+}
+
+namespace llvm {
+template<>
+struct DOTGraphTraits<const Stmt*> : public DefaultDOTGraphTraits {
+  DOTGraphTraits (bool isSimple=false) : DefaultDOTGraphTraits(isSimple) {}
+
+  static std::string getNodeLabel(const Stmt* Node, const Stmt* Graph) {
+
+#ifndef NDEBUG
+    std::string OutSStr;
+    llvm::raw_string_ostream Out(OutSStr);
+
+    if (Node)
+      Out << Node->getStmtClassName();
+    else
+      Out << "<NULL>";
+
+    std::string OutStr = Out.str();
+    if (OutStr[0] == '\n') OutStr.erase(OutStr.begin());
+
+    // Process string output to make it nicer...
+    for (unsigned i = 0; i != OutStr.length(); ++i)
+      if (OutStr[i] == '\n') {                            // Left justify
+        OutStr[i] = '\\';
+        OutStr.insert(OutStr.begin()+i+1, 'l');
+      }
+
+    return OutStr;
+#else
+    return "";
+#endif
+  }
+};
+} // end namespace llvm
diff --git a/lib/AST/TemplateBase.cpp b/lib/AST/TemplateBase.cpp
new file mode 100644
index 0000000..e9b1725
--- /dev/null
+++ b/lib/AST/TemplateBase.cpp
@@ -0,0 +1,121 @@
+//===--- TemplateBase.cpp - Common template AST class implementation ------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements common classes used throughout C++ template
+// representations.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/FoldingSet.h"
+#include "clang/AST/TemplateBase.h"
+#include "clang/AST/DeclBase.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/TypeLoc.h"
+
+using namespace clang;
+
+//===----------------------------------------------------------------------===//
+// TemplateArgument Implementation
+//===----------------------------------------------------------------------===//
+
+/// \brief Construct a template argument pack.
+void TemplateArgument::setArgumentPack(TemplateArgument *args, unsigned NumArgs,
+                                       bool CopyArgs) {
+  assert(isNull() && "Must call setArgumentPack on a null argument");
+
+  Kind = Pack;
+  Args.NumArgs = NumArgs;
+  Args.CopyArgs = CopyArgs;
+  if (!Args.CopyArgs) {
+    Args.Args = args;
+    return;
+  }
+
+  // FIXME: Allocate in ASTContext
+  Args.Args = new TemplateArgument[NumArgs];
+  for (unsigned I = 0; I != Args.NumArgs; ++I)
+    Args.Args[I] = args[I];
+}
+
+void TemplateArgument::Profile(llvm::FoldingSetNodeID &ID,
+                               ASTContext &Context) const {
+  ID.AddInteger(Kind);
+  switch (Kind) {
+  case Null:
+    break;
+
+  case Type:
+    getAsType().Profile(ID);
+    break;
+
+  case Declaration:
+    ID.AddPointer(getAsDecl()? getAsDecl()->getCanonicalDecl() : 0);
+    break;
+
+  case Template:
+    if (TemplateTemplateParmDecl *TTP
+          = dyn_cast_or_null<TemplateTemplateParmDecl>(
+                                       getAsTemplate().getAsTemplateDecl())) {
+      ID.AddBoolean(true);
+      ID.AddInteger(TTP->getDepth());
+      ID.AddInteger(TTP->getPosition());
+    } else {
+      ID.AddBoolean(false);
+      ID.AddPointer(Context.getCanonicalTemplateName(getAsTemplate())
+                      .getAsVoidPointer());
+    }
+    break;
+      
+  case Integral:
+    getAsIntegral()->Profile(ID);
+    getIntegralType().Profile(ID);
+    break;
+
+  case Expression:
+    getAsExpr()->Profile(ID, Context, true);
+    break;
+
+  case Pack:
+    ID.AddInteger(Args.NumArgs);
+    for (unsigned I = 0; I != Args.NumArgs; ++I)
+      Args.Args[I].Profile(ID, Context);
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// TemplateArgumentLoc Implementation
+//===----------------------------------------------------------------------===//
+
+SourceRange TemplateArgumentLoc::getSourceRange() const {
+  switch (Argument.getKind()) {
+  case TemplateArgument::Expression:
+    return getSourceExpression()->getSourceRange();
+      
+  case TemplateArgument::Declaration:
+    return getSourceDeclExpression()->getSourceRange();
+      
+  case TemplateArgument::Type:
+    return getTypeSourceInfo()->getTypeLoc().getFullSourceRange();
+      
+  case TemplateArgument::Template:
+    if (getTemplateQualifierRange().isValid())
+      return SourceRange(getTemplateQualifierRange().getBegin(),
+                         getTemplateNameLoc());
+    return SourceRange(getTemplateNameLoc());
+      
+  case TemplateArgument::Integral:
+  case TemplateArgument::Pack:
+  case TemplateArgument::Null:
+    return SourceRange();
+  }
+
+  // Silence bonus gcc warning.
+  return SourceRange();
+}
diff --git a/lib/AST/TemplateName.cpp b/lib/AST/TemplateName.cpp
new file mode 100644
index 0000000..14722f7
--- /dev/null
+++ b/lib/AST/TemplateName.cpp
@@ -0,0 +1,86 @@
+//===--- TemplateName.h - C++ Template Name Representation-------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the TemplateName interface and subclasses.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/TemplateName.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/NestedNameSpecifier.h"
+#include "clang/AST/PrettyPrinter.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/LangOptions.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace clang;
+using namespace llvm;
+
+TemplateDecl *TemplateName::getAsTemplateDecl() const {
+  if (TemplateDecl *Template = Storage.dyn_cast<TemplateDecl *>())
+    return Template;
+
+  if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName())
+    return QTN->getTemplateDecl();
+
+  return 0;
+}
+
+bool TemplateName::isDependent() const {
+  if (TemplateDecl *Template = getAsTemplateDecl()) {
+    return isa<TemplateTemplateParmDecl>(Template) ||
+      Template->getDeclContext()->isDependentContext();
+  }
+
+  assert(!getAsOverloadedTemplate() &&
+         "overloaded templates shouldn't survive to here");
+
+  return true;
+}
+
+void
+TemplateName::print(llvm::raw_ostream &OS, const PrintingPolicy &Policy,
+                    bool SuppressNNS) const {
+  if (TemplateDecl *Template = Storage.dyn_cast<TemplateDecl *>())
+    OS << Template;
+  else if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName()) {
+    if (!SuppressNNS)
+      QTN->getQualifier()->print(OS, Policy);
+    if (QTN->hasTemplateKeyword())
+      OS << "template ";
+    OS << QTN->getDecl();
+  } else if (DependentTemplateName *DTN = getAsDependentTemplateName()) {
+    if (!SuppressNNS && DTN->getQualifier())
+      DTN->getQualifier()->print(OS, Policy);
+    OS << "template ";
+    
+    if (DTN->isIdentifier())
+      OS << DTN->getIdentifier()->getName();
+    else
+      OS << "operator " << getOperatorSpelling(DTN->getOperator());
+  }
+}
+
+const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
+                                           TemplateName N) {
+  std::string NameStr;
+  raw_string_ostream OS(NameStr);
+  LangOptions LO;
+  LO.CPlusPlus = true;
+  LO.Bool = true;
+  N.print(OS, PrintingPolicy(LO));
+  OS.flush();
+  return DB << NameStr;
+}
+
+void TemplateName::dump() const {
+  LangOptions LO;  // FIXME!
+  LO.CPlusPlus = true;
+  LO.Bool = true;
+  print(llvm::errs(), PrintingPolicy(LO));
+}
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
new file mode 100644
index 0000000..52ee60b
--- /dev/null
+++ b/lib/AST/Type.cpp
@@ -0,0 +1,1161 @@
+//===--- Type.cpp - Type representation and manipulation ------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements type-related functionality.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/PrettyPrinter.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace clang;
+
+bool QualType::isConstant(QualType T, ASTContext &Ctx) {
+  if (T.isConstQualified())
+    return true;
+
+  if (const ArrayType *AT = Ctx.getAsArrayType(T))
+    return AT->getElementType().isConstant(Ctx);
+
+  return false;
+}
+
+void Type::Destroy(ASTContext& C) {
+  this->~Type();
+  C.Deallocate(this);
+}
+
+void VariableArrayType::Destroy(ASTContext& C) {
+  if (SizeExpr)
+    SizeExpr->Destroy(C);
+  this->~VariableArrayType();
+  C.Deallocate(this);
+}
+
+void DependentSizedArrayType::Destroy(ASTContext& C) {
+  // FIXME: Resource contention like in ConstantArrayWithExprType ?
+  // May crash, depending on platform or a particular build.
+  // SizeExpr->Destroy(C);
+  this->~DependentSizedArrayType();
+  C.Deallocate(this);
+}
+
+void DependentSizedArrayType::Profile(llvm::FoldingSetNodeID &ID,
+                                      ASTContext &Context,
+                                      QualType ET,
+                                      ArraySizeModifier SizeMod,
+                                      unsigned TypeQuals,
+                                      Expr *E) {
+  ID.AddPointer(ET.getAsOpaquePtr());
+  ID.AddInteger(SizeMod);
+  ID.AddInteger(TypeQuals);
+  E->Profile(ID, Context, true);
+}
+
+void
+DependentSizedExtVectorType::Profile(llvm::FoldingSetNodeID &ID,
+                                     ASTContext &Context,
+                                     QualType ElementType, Expr *SizeExpr) {
+  ID.AddPointer(ElementType.getAsOpaquePtr());
+  SizeExpr->Profile(ID, Context, true);
+}
+
+void DependentSizedExtVectorType::Destroy(ASTContext& C) {
+  // FIXME: Deallocate size expression, once we're cloning properly.
+//  if (SizeExpr)
+//    SizeExpr->Destroy(C);
+  this->~DependentSizedExtVectorType();
+  C.Deallocate(this);
+}
+
+/// getArrayElementTypeNoTypeQual - If this is an array type, return the
+/// element type of the array, potentially with type qualifiers missing.
+/// This method should never be used when type qualifiers are meaningful.
+const Type *Type::getArrayElementTypeNoTypeQual() const {
+  // If this is directly an array type, return it.
+  if (const ArrayType *ATy = dyn_cast<ArrayType>(this))
+    return ATy->getElementType().getTypePtr();
+
+  // If the canonical form of this type isn't the right kind, reject it.
+  if (!isa<ArrayType>(CanonicalType))
+    return 0;
+
+  // If this is a typedef for an array type, strip the typedef off without
+  // losing all typedef information.
+  return cast<ArrayType>(getUnqualifiedDesugaredType())
+    ->getElementType().getTypePtr();
+}
+
+/// \brief Retrieve the unqualified variant of the given type, removing as
+/// little sugar as possible.
+///
+/// This routine looks through various kinds of sugar to find the 
+/// least-desuraged type that is unqualified. For example, given:
+///
+/// \code
+/// typedef int Integer;
+/// typedef const Integer CInteger;
+/// typedef CInteger DifferenceType;
+/// \endcode
+///
+/// Executing \c getUnqualifiedTypeSlow() on the type \c DifferenceType will
+/// desugar until we hit the type \c Integer, which has no qualifiers on it.
+QualType QualType::getUnqualifiedTypeSlow() const {
+  QualType Cur = *this;
+  while (true) {
+    if (!Cur.hasQualifiers())
+      return Cur;
+    
+    const Type *CurTy = Cur.getTypePtr();
+    switch (CurTy->getTypeClass()) {
+#define ABSTRACT_TYPE(Class, Parent)
+#define TYPE(Class, Parent)                                  \
+    case Type::Class: {                                      \
+      const Class##Type *Ty = cast<Class##Type>(CurTy);      \
+      if (!Ty->isSugared())                                  \
+        return Cur.getLocalUnqualifiedType();                \
+      Cur = Ty->desugar();                                   \
+      break;                                                 \
+    }
+#include "clang/AST/TypeNodes.def"
+    }
+  }
+  
+  return Cur.getUnqualifiedType();
+}
+
+/// getDesugaredType - Return the specified type with any "sugar" removed from
+/// the type.  This takes off typedefs, typeof's etc.  If the outer level of
+/// the type is already concrete, it returns it unmodified.  This is similar
+/// to getting the canonical type, but it doesn't remove *all* typedefs.  For
+/// example, it returns "T*" as "T*", (not as "int*"), because the pointer is
+/// concrete.
+QualType QualType::getDesugaredType(QualType T) {
+  QualifierCollector Qs;
+
+  QualType Cur = T;
+  while (true) {
+    const Type *CurTy = Qs.strip(Cur);
+    switch (CurTy->getTypeClass()) {
+#define ABSTRACT_TYPE(Class, Parent)
+#define TYPE(Class, Parent) \
+    case Type::Class: { \
+      const Class##Type *Ty = cast<Class##Type>(CurTy); \
+      if (!Ty->isSugared()) \
+        return Qs.apply(Cur); \
+      Cur = Ty->desugar(); \
+      break; \
+    }
+#include "clang/AST/TypeNodes.def"
+    }
+  }
+}
+
+/// getUnqualifiedDesugaredType - Pull any qualifiers and syntactic
+/// sugar off the given type.  This should produce an object of the
+/// same dynamic type as the canonical type.
+const Type *Type::getUnqualifiedDesugaredType() const {
+  const Type *Cur = this;
+
+  while (true) {
+    switch (Cur->getTypeClass()) {
+#define ABSTRACT_TYPE(Class, Parent)
+#define TYPE(Class, Parent) \
+    case Class: { \
+      const Class##Type *Ty = cast<Class##Type>(Cur); \
+      if (!Ty->isSugared()) return Cur; \
+      Cur = Ty->desugar().getTypePtr(); \
+      break; \
+    }
+#include "clang/AST/TypeNodes.def"
+    }
+  }
+}
+
+/// isVoidType - Helper method to determine if this is the 'void' type.
+bool Type::isVoidType() const {
+  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
+    return BT->getKind() == BuiltinType::Void;
+  return false;
+}
+
+bool Type::isObjectType() const {
+  if (isa<FunctionType>(CanonicalType) || isa<ReferenceType>(CanonicalType) ||
+      isa<IncompleteArrayType>(CanonicalType) || isVoidType())
+    return false;
+  return true;
+}
+
+bool Type::isDerivedType() const {
+  switch (CanonicalType->getTypeClass()) {
+  case Pointer:
+  case VariableArray:
+  case ConstantArray:
+  case IncompleteArray:
+  case FunctionProto:
+  case FunctionNoProto:
+  case LValueReference:
+  case RValueReference:
+  case Record:
+    return true;
+  default:
+    return false;
+  }
+}
+
+bool Type::isClassType() const {
+  if (const RecordType *RT = getAs<RecordType>())
+    return RT->getDecl()->isClass();
+  return false;
+}
+bool Type::isStructureType() const {
+  if (const RecordType *RT = getAs<RecordType>())
+    return RT->getDecl()->isStruct();
+  return false;
+}
+bool Type::isStructureOrClassType() const {
+  if (const RecordType *RT = getAs<RecordType>())
+    return RT->getDecl()->isStruct() || RT->getDecl()->isClass();
+  return false;
+}
+bool Type::isVoidPointerType() const {
+  if (const PointerType *PT = getAs<PointerType>())
+    return PT->getPointeeType()->isVoidType();
+  return false;
+}
+
+bool Type::isUnionType() const {
+  if (const RecordType *RT = getAs<RecordType>())
+    return RT->getDecl()->isUnion();
+  return false;
+}
+
+bool Type::isComplexType() const {
+  if (const ComplexType *CT = dyn_cast<ComplexType>(CanonicalType))
+    return CT->getElementType()->isFloatingType();
+  return false;
+}
+
+bool Type::isComplexIntegerType() const {
+  // Check for GCC complex integer extension.
+  return getAsComplexIntegerType();
+}
+
+const ComplexType *Type::getAsComplexIntegerType() const {
+  if (const ComplexType *Complex = getAs<ComplexType>())
+    if (Complex->getElementType()->isIntegerType())
+      return Complex;
+  return 0;
+}
+
+QualType Type::getPointeeType() const {
+  if (const PointerType *PT = getAs<PointerType>())
+    return PT->getPointeeType();
+  if (const ObjCObjectPointerType *OPT = getAs<ObjCObjectPointerType>())
+    return OPT->getPointeeType();
+  if (const BlockPointerType *BPT = getAs<BlockPointerType>())
+    return BPT->getPointeeType();
+  if (const ReferenceType *RT = getAs<ReferenceType>())
+    return RT->getPointeeType();
+  return QualType();
+}
+
+/// isVariablyModifiedType (C99 6.7.5p3) - Return true for variable length
+/// array types and types that contain variable array types in their
+/// declarator
+bool Type::isVariablyModifiedType() const {
+  // A VLA is a variably modified type.
+  if (isVariableArrayType())
+    return true;
+
+  // An array can contain a variably modified type
+  if (const Type *T = getArrayElementTypeNoTypeQual())
+    return T->isVariablyModifiedType();
+
+  // A pointer can point to a variably modified type.
+  // Also, C++ references and member pointers can point to a variably modified
+  // type, where VLAs appear as an extension to C++, and should be treated
+  // correctly.
+  if (const PointerType *PT = getAs<PointerType>())
+    return PT->getPointeeType()->isVariablyModifiedType();
+  if (const ReferenceType *RT = getAs<ReferenceType>())
+    return RT->getPointeeType()->isVariablyModifiedType();
+  if (const MemberPointerType *PT = getAs<MemberPointerType>())
+    return PT->getPointeeType()->isVariablyModifiedType();
+
+  // A function can return a variably modified type
+  // This one isn't completely obvious, but it follows from the
+  // definition in C99 6.7.5p3. Because of this rule, it's
+  // illegal to declare a function returning a variably modified type.
+  if (const FunctionType *FT = getAs<FunctionType>())
+    return FT->getResultType()->isVariablyModifiedType();
+
+  return false;
+}
+
+const RecordType *Type::getAsStructureType() const {
+  // If this is directly a structure type, return it.
+  if (const RecordType *RT = dyn_cast<RecordType>(this)) {
+    if (RT->getDecl()->isStruct())
+      return RT;
+  }
+
+  // If the canonical form of this type isn't the right kind, reject it.
+  if (const RecordType *RT = dyn_cast<RecordType>(CanonicalType)) {
+    if (!RT->getDecl()->isStruct())
+      return 0;
+
+    // If this is a typedef for a structure type, strip the typedef off without
+    // losing all typedef information.
+    return cast<RecordType>(getUnqualifiedDesugaredType());
+  }
+  return 0;
+}
+
+const RecordType *Type::getAsUnionType() const {
+  // If this is directly a union type, return it.
+  if (const RecordType *RT = dyn_cast<RecordType>(this)) {
+    if (RT->getDecl()->isUnion())
+      return RT;
+  }
+
+  // If the canonical form of this type isn't the right kind, reject it.
+  if (const RecordType *RT = dyn_cast<RecordType>(CanonicalType)) {
+    if (!RT->getDecl()->isUnion())
+      return 0;
+
+    // If this is a typedef for a union type, strip the typedef off without
+    // losing all typedef information.
+    return cast<RecordType>(getUnqualifiedDesugaredType());
+  }
+
+  return 0;
+}
+
+ObjCInterfaceType::ObjCInterfaceType(QualType Canonical,
+                                     ObjCInterfaceDecl *D,
+                                     ObjCProtocolDecl **Protos, unsigned NumP) :
+  Type(ObjCInterface, Canonical, /*Dependent=*/false),
+  Decl(D), NumProtocols(NumP)
+{
+  if (NumProtocols)
+    memcpy(reinterpret_cast<ObjCProtocolDecl**>(this + 1), Protos, 
+           NumProtocols * sizeof(*Protos));
+}
+
+void ObjCInterfaceType::Destroy(ASTContext& C) {
+  this->~ObjCInterfaceType();
+  C.Deallocate(this);
+}
+
+const ObjCInterfaceType *Type::getAsObjCQualifiedInterfaceType() const {
+  // There is no sugar for ObjCInterfaceType's, just return the canonical
+  // type pointer if it is the right class.  There is no typedef information to
+  // return and these cannot be Address-space qualified.
+  if (const ObjCInterfaceType *OIT = getAs<ObjCInterfaceType>())
+    if (OIT->getNumProtocols())
+      return OIT;
+  return 0;
+}
+
+bool Type::isObjCQualifiedInterfaceType() const {
+  return getAsObjCQualifiedInterfaceType() != 0;
+}
+
+ObjCObjectPointerType::ObjCObjectPointerType(QualType Canonical, QualType T,
+                                             ObjCProtocolDecl **Protos,
+                                             unsigned NumP) :
+  Type(ObjCObjectPointer, Canonical, /*Dependent=*/false),
+  PointeeType(T), NumProtocols(NumP)
+{
+  if (NumProtocols)
+    memcpy(reinterpret_cast<ObjCProtocolDecl **>(this + 1), Protos, 
+           NumProtocols * sizeof(*Protos));
+}
+
+void ObjCObjectPointerType::Destroy(ASTContext& C) {
+  this->~ObjCObjectPointerType();
+  C.Deallocate(this);
+}
+
+const ObjCObjectPointerType *Type::getAsObjCQualifiedIdType() const {
+  // There is no sugar for ObjCQualifiedIdType's, just return the canonical
+  // type pointer if it is the right class.
+  if (const ObjCObjectPointerType *OPT = getAs<ObjCObjectPointerType>()) {
+    if (OPT->isObjCQualifiedIdType())
+      return OPT;
+  }
+  return 0;
+}
+
+const ObjCObjectPointerType *Type::getAsObjCInterfacePointerType() const {
+  if (const ObjCObjectPointerType *OPT = getAs<ObjCObjectPointerType>()) {
+    if (OPT->getInterfaceType())
+      return OPT;
+  }
+  return 0;
+}
+
+const CXXRecordDecl *Type::getCXXRecordDeclForPointerType() const {
+  if (const PointerType *PT = getAs<PointerType>())
+    if (const RecordType *RT = PT->getPointeeType()->getAs<RecordType>())
+      return dyn_cast<CXXRecordDecl>(RT->getDecl());
+  return 0;
+}
+
+bool Type::isIntegerType() const {
+  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
+    return BT->getKind() >= BuiltinType::Bool &&
+           BT->getKind() <= BuiltinType::Int128;
+  if (const TagType *TT = dyn_cast<TagType>(CanonicalType))
+    // Incomplete enum types are not treated as integer types.
+    // FIXME: In C++, enum types are never integer types.
+    if (TT->getDecl()->isEnum() && TT->getDecl()->isDefinition())
+      return true;
+  if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
+    return VT->getElementType()->isIntegerType();
+  return false;
+}
+
+bool Type::isIntegralType() const {
+  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
+    return BT->getKind() >= BuiltinType::Bool &&
+    BT->getKind() <= BuiltinType::Int128;
+  if (const TagType *TT = dyn_cast<TagType>(CanonicalType))
+    if (TT->getDecl()->isEnum() && TT->getDecl()->isDefinition())
+      return true;  // Complete enum types are integral.
+                    // FIXME: In C++, enum types are never integral.
+  return false;
+}
+
+bool Type::isEnumeralType() const {
+  if (const TagType *TT = dyn_cast<TagType>(CanonicalType))
+    return TT->getDecl()->isEnum();
+  return false;
+}
+
+bool Type::isBooleanType() const {
+  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
+    return BT->getKind() == BuiltinType::Bool;
+  return false;
+}
+
+bool Type::isCharType() const {
+  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
+    return BT->getKind() == BuiltinType::Char_U ||
+           BT->getKind() == BuiltinType::UChar ||
+           BT->getKind() == BuiltinType::Char_S ||
+           BT->getKind() == BuiltinType::SChar;
+  return false;
+}
+
+bool Type::isWideCharType() const {
+  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
+    return BT->getKind() == BuiltinType::WChar;
+  return false;
+}
+
+/// \brief Determine whether this type is any of the built-in character
+/// types.
+bool Type::isAnyCharacterType() const {
+  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
+    return (BT->getKind() >= BuiltinType::Char_U &&
+            BT->getKind() <= BuiltinType::Char32) ||
+           (BT->getKind() >= BuiltinType::Char_S &&
+            BT->getKind() <= BuiltinType::WChar);
+  
+  return false;
+}
+
+/// isSignedIntegerType - Return true if this is an integer type that is
+/// signed, according to C99 6.2.5p4 [char, signed char, short, int, long..],
+/// an enum decl which has a signed representation, or a vector of signed
+/// integer element type.
+bool Type::isSignedIntegerType() const {
+  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) {
+    return BT->getKind() >= BuiltinType::Char_S &&
+           BT->getKind() <= BuiltinType::Int128;
+  }
+
+  if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType))
+    return ET->getDecl()->getIntegerType()->isSignedIntegerType();
+
+  if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
+    return VT->getElementType()->isSignedIntegerType();
+  return false;
+}
+
+/// isUnsignedIntegerType - Return true if this is an integer type that is
+/// unsigned, according to C99 6.2.5p6 [which returns true for _Bool], an enum
+/// decl which has an unsigned representation, or a vector of unsigned integer
+/// element type.
+bool Type::isUnsignedIntegerType() const {
+  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) {
+    return BT->getKind() >= BuiltinType::Bool &&
+           BT->getKind() <= BuiltinType::UInt128;
+  }
+
+  if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType))
+    return ET->getDecl()->getIntegerType()->isUnsignedIntegerType();
+
+  if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
+    return VT->getElementType()->isUnsignedIntegerType();
+  return false;
+}
+
+bool Type::isFloatingType() const {
+  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
+    return BT->getKind() >= BuiltinType::Float &&
+           BT->getKind() <= BuiltinType::LongDouble;
+  if (const ComplexType *CT = dyn_cast<ComplexType>(CanonicalType))
+    return CT->getElementType()->isFloatingType();
+  if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
+    return VT->getElementType()->isFloatingType();
+  return false;
+}
+
+bool Type::isRealFloatingType() const {
+  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
+    return BT->isFloatingPoint();
+  if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
+    return VT->getElementType()->isRealFloatingType();
+  return false;
+}
+
+bool Type::isRealType() const {
+  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
+    return BT->getKind() >= BuiltinType::Bool &&
+           BT->getKind() <= BuiltinType::LongDouble;
+  if (const TagType *TT = dyn_cast<TagType>(CanonicalType))
+    return TT->getDecl()->isEnum() && TT->getDecl()->isDefinition();
+  if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
+    return VT->getElementType()->isRealType();
+  return false;
+}
+
+bool Type::isArithmeticType() const {
+  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
+    return BT->getKind() >= BuiltinType::Bool &&
+           BT->getKind() <= BuiltinType::LongDouble;
+  if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType))
+    // GCC allows forward declaration of enum types (forbid by C99 6.7.2.3p2).
+    // If a body isn't seen by the time we get here, return false.
+    return ET->getDecl()->isDefinition();
+  return isa<ComplexType>(CanonicalType) || isa<VectorType>(CanonicalType);
+}
+
+bool Type::isScalarType() const {
+  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
+    return BT->getKind() != BuiltinType::Void;
+  if (const TagType *TT = dyn_cast<TagType>(CanonicalType)) {
+    // Enums are scalar types, but only if they are defined.  Incomplete enums
+    // are not treated as scalar types.
+    if (TT->getDecl()->isEnum() && TT->getDecl()->isDefinition())
+      return true;
+    return false;
+  }
+  return isa<PointerType>(CanonicalType) ||
+         isa<BlockPointerType>(CanonicalType) ||
+         isa<MemberPointerType>(CanonicalType) ||
+         isa<ComplexType>(CanonicalType) ||
+         isa<ObjCObjectPointerType>(CanonicalType);
+}
+
+/// \brief Determines whether the type is a C++ aggregate type or C
+/// aggregate or union type.
+///
+/// An aggregate type is an array or a class type (struct, union, or
+/// class) that has no user-declared constructors, no private or
+/// protected non-static data members, no base classes, and no virtual
+/// functions (C++ [dcl.init.aggr]p1). The notion of an aggregate type
+/// subsumes the notion of C aggregates (C99 6.2.5p21) because it also
+/// includes union types.
+bool Type::isAggregateType() const {
+  if (const RecordType *Record = dyn_cast<RecordType>(CanonicalType)) {
+    if (CXXRecordDecl *ClassDecl = dyn_cast<CXXRecordDecl>(Record->getDecl()))
+      return ClassDecl->isAggregate();
+
+    return true;
+  }
+
+  return isa<ArrayType>(CanonicalType);
+}
+
+/// isConstantSizeType - Return true if this is not a variable sized type,
+/// according to the rules of C99 6.7.5p3.  It is not legal to call this on
+/// incomplete types or dependent types.
+bool Type::isConstantSizeType() const {
+  assert(!isIncompleteType() && "This doesn't make sense for incomplete types");
+  assert(!isDependentType() && "This doesn't make sense for dependent types");
+  // The VAT must have a size, as it is known to be complete.
+  return !isa<VariableArrayType>(CanonicalType);
+}
+
+/// isIncompleteType - Return true if this is an incomplete type (C99 6.2.5p1)
+/// - a type that can describe objects, but which lacks information needed to
+/// determine its size.
+bool Type::isIncompleteType() const {
+  switch (CanonicalType->getTypeClass()) {
+  default: return false;
+  case Builtin:
+    // Void is the only incomplete builtin type.  Per C99 6.2.5p19, it can never
+    // be completed.
+    return isVoidType();
+  case Record:
+  case Enum:
+    // A tagged type (struct/union/enum/class) is incomplete if the decl is a
+    // forward declaration, but not a full definition (C99 6.2.5p22).
+    return !cast<TagType>(CanonicalType)->getDecl()->isDefinition();
+  case ConstantArray:
+    // An array is incomplete if its element type is incomplete
+    // (C++ [dcl.array]p1).
+    // We don't handle variable arrays (they're not allowed in C++) or
+    // dependent-sized arrays (dependent types are never treated as incomplete).
+    return cast<ArrayType>(CanonicalType)->getElementType()->isIncompleteType();
+  case IncompleteArray:
+    // An array of unknown size is an incomplete type (C99 6.2.5p22).
+    return true;
+  case ObjCInterface:
+    // ObjC interfaces are incomplete if they are @class, not @interface.
+    return cast<ObjCInterfaceType>(this)->getDecl()->isForwardDecl();
+  }
+}
+
+/// isPODType - Return true if this is a plain-old-data type (C++ 3.9p10)
+bool Type::isPODType() const {
+  // The compiler shouldn't query this for incomplete types, but the user might.
+  // We return false for that case.
+  if (isIncompleteType())
+    return false;
+
+  switch (CanonicalType->getTypeClass()) {
+    // Everything not explicitly mentioned is not POD.
+  default: return false;
+  case VariableArray:
+  case ConstantArray:
+    // IncompleteArray is caught by isIncompleteType() above.
+    return cast<ArrayType>(CanonicalType)->getElementType()->isPODType();
+
+  case Builtin:
+  case Complex:
+  case Pointer:
+  case MemberPointer:
+  case Vector:
+  case ExtVector:
+  case ObjCObjectPointer:
+  case BlockPointer:
+    return true;
+
+  case Enum:
+    return true;
+
+  case Record:
+    if (CXXRecordDecl *ClassDecl
+          = dyn_cast<CXXRecordDecl>(cast<RecordType>(CanonicalType)->getDecl()))
+      return ClassDecl->isPOD();
+
+    // C struct/union is POD.
+    return true;
+  }
+}
+
+bool Type::isLiteralType() const {
+  if (isIncompleteType())
+    return false;
+
+  // C++0x [basic.types]p10:
+  //   A type is a literal type if it is:
+  switch (CanonicalType->getTypeClass()) {
+    // We're whitelisting
+  default: return false;
+
+    //   -- a scalar type
+  case Builtin:
+  case Complex:
+  case Pointer:
+  case MemberPointer:
+  case Vector:
+  case ExtVector:
+  case ObjCObjectPointer:
+  case Enum:
+    return true;
+
+    //   -- a class type with ...
+  case Record:
+    // FIXME: Do the tests
+    return false;
+
+    //   -- an array of literal type
+    // Extension: variable arrays cannot be literal types, since they're
+    // runtime-sized.
+  case ConstantArray:
+    return cast<ArrayType>(CanonicalType)->getElementType()->isLiteralType();
+  }
+}
+
+bool Type::isPromotableIntegerType() const {
+  if (const BuiltinType *BT = getAs<BuiltinType>())
+    switch (BT->getKind()) {
+    case BuiltinType::Bool:
+    case BuiltinType::Char_S:
+    case BuiltinType::Char_U:
+    case BuiltinType::SChar:
+    case BuiltinType::UChar:
+    case BuiltinType::Short:
+    case BuiltinType::UShort:
+      return true;
+    default:
+      return false;
+    }
+
+  // Enumerated types are promotable to their compatible integer types
+  // (C99 6.3.1.1) a.k.a. its underlying type (C++ [conv.prom]p2).
+  if (const EnumType *ET = getAs<EnumType>()){
+    if (this->isDependentType() || ET->getDecl()->getPromotionType().isNull())
+      return false;
+    
+    const BuiltinType *BT
+      = ET->getDecl()->getPromotionType()->getAs<BuiltinType>();
+    return BT->getKind() == BuiltinType::Int
+           || BT->getKind() == BuiltinType::UInt;
+  }
+  
+  return false;
+}
+
+bool Type::isNullPtrType() const {
+  if (const BuiltinType *BT = getAs<BuiltinType>())
+    return BT->getKind() == BuiltinType::NullPtr;
+  return false;
+}
+
+bool Type::isSpecifierType() const {
+  // Note that this intentionally does not use the canonical type.
+  switch (getTypeClass()) {
+  case Builtin:
+  case Record:
+  case Enum:
+  case Typedef:
+  case Complex:
+  case TypeOfExpr:
+  case TypeOf:
+  case TemplateTypeParm:
+  case SubstTemplateTypeParm:
+  case TemplateSpecialization:
+  case QualifiedName:
+  case DependentName:
+  case ObjCInterface:
+  case ObjCObjectPointer:
+  case Elaborated:
+    return true;
+  default:
+    return false;
+  }
+}
+
+bool Type::isElaboratedTypeSpecifier() const {
+  if (getTypeClass() == Elaborated)
+    return true;
+  
+  if (const DependentNameType *Dependent = dyn_cast<DependentNameType>(this)) {
+    switch (Dependent->getKeyword()) {
+    case ETK_None:
+    case ETK_Typename:
+      return false;
+        
+    case ETK_Class:
+    case ETK_Struct:
+    case ETK_Union:
+    case ETK_Enum:
+      return true;
+    }
+  }
+  
+  return false;
+}
+
+const char *Type::getTypeClassName() const {
+  switch (TC) {
+  default: assert(0 && "Type class not in TypeNodes.def!");
+#define ABSTRACT_TYPE(Derived, Base)
+#define TYPE(Derived, Base) case Derived: return #Derived;
+#include "clang/AST/TypeNodes.def"
+  }
+}
+
+const char *BuiltinType::getName(const LangOptions &LO) const {
+  switch (getKind()) {
+  default: assert(0 && "Unknown builtin type!");
+  case Void:              return "void";
+  case Bool:              return LO.Bool ? "bool" : "_Bool";
+  case Char_S:            return "char";
+  case Char_U:            return "char";
+  case SChar:             return "signed char";
+  case Short:             return "short";
+  case Int:               return "int";
+  case Long:              return "long";
+  case LongLong:          return "long long";
+  case Int128:            return "__int128_t";
+  case UChar:             return "unsigned char";
+  case UShort:            return "unsigned short";
+  case UInt:              return "unsigned int";
+  case ULong:             return "unsigned long";
+  case ULongLong:         return "unsigned long long";
+  case UInt128:           return "__uint128_t";
+  case Float:             return "float";
+  case Double:            return "double";
+  case LongDouble:        return "long double";
+  case WChar:             return "wchar_t";
+  case Char16:            return "char16_t";
+  case Char32:            return "char32_t";
+  case NullPtr:           return "nullptr_t";
+  case Overload:          return "<overloaded function type>";
+  case Dependent:         return "<dependent type>";
+  case UndeducedAuto:     return "auto";
+  case ObjCId:            return "id";
+  case ObjCClass:         return "Class";
+  case ObjCSel:         return "SEL";
+  }
+}
+
+llvm::StringRef FunctionType::getNameForCallConv(CallingConv CC) {
+  switch (CC) {
+  case CC_Default: llvm_unreachable("no name for default cc");
+  default: return "";
+
+  case CC_C: return "cdecl";
+  case CC_X86StdCall: return "stdcall";
+  case CC_X86FastCall: return "fastcall";
+  }
+}
+
+void FunctionProtoType::Profile(llvm::FoldingSetNodeID &ID, QualType Result,
+                                arg_type_iterator ArgTys,
+                                unsigned NumArgs, bool isVariadic,
+                                unsigned TypeQuals, bool hasExceptionSpec,
+                                bool anyExceptionSpec, unsigned NumExceptions,
+                                exception_iterator Exs,
+                                const FunctionType::ExtInfo &Info) {
+  ID.AddPointer(Result.getAsOpaquePtr());
+  for (unsigned i = 0; i != NumArgs; ++i)
+    ID.AddPointer(ArgTys[i].getAsOpaquePtr());
+  ID.AddInteger(isVariadic);
+  ID.AddInteger(TypeQuals);
+  ID.AddInteger(hasExceptionSpec);
+  if (hasExceptionSpec) {
+    ID.AddInteger(anyExceptionSpec);
+    for (unsigned i = 0; i != NumExceptions; ++i)
+      ID.AddPointer(Exs[i].getAsOpaquePtr());
+  }
+  ID.AddInteger(Info.getNoReturn());
+  ID.AddInteger(Info.getRegParm());
+  ID.AddInteger(Info.getCC());
+}
+
+void FunctionProtoType::Profile(llvm::FoldingSetNodeID &ID) {
+  Profile(ID, getResultType(), arg_type_begin(), NumArgs, isVariadic(),
+          getTypeQuals(), hasExceptionSpec(), hasAnyExceptionSpec(),
+          getNumExceptions(), exception_begin(),
+          getExtInfo());
+}
+
+void ObjCObjectPointerType::Profile(llvm::FoldingSetNodeID &ID,
+                                    QualType OIT, 
+                                    ObjCProtocolDecl * const *protocols,
+                                    unsigned NumProtocols) {
+  ID.AddPointer(OIT.getAsOpaquePtr());
+  for (unsigned i = 0; i != NumProtocols; i++)
+    ID.AddPointer(protocols[i]);
+}
+
+void ObjCObjectPointerType::Profile(llvm::FoldingSetNodeID &ID) {
+  Profile(ID, getPointeeType(), qual_begin(), getNumProtocols());
+}
+
+/// LookThroughTypedefs - Return the ultimate type this typedef corresponds to
+/// potentially looking through *all* consequtive typedefs.  This returns the
+/// sum of the type qualifiers, so if you have:
+///   typedef const int A;
+///   typedef volatile A B;
+/// looking through the typedefs for B will give you "const volatile A".
+///
+QualType TypedefType::LookThroughTypedefs() const {
+  // Usually, there is only a single level of typedefs, be fast in that case.
+  QualType FirstType = getDecl()->getUnderlyingType();
+  if (!isa<TypedefType>(FirstType))
+    return FirstType;
+
+  // Otherwise, do the fully general loop.
+  QualifierCollector Qs;
+
+  QualType CurType;
+  const TypedefType *TDT = this;
+  do {
+    CurType = TDT->getDecl()->getUnderlyingType();
+    TDT = dyn_cast<TypedefType>(Qs.strip(CurType));
+  } while (TDT);
+
+  return Qs.apply(CurType);
+}
+
+QualType TypedefType::desugar() const {
+  return getDecl()->getUnderlyingType();
+}
+
+TypeOfExprType::TypeOfExprType(Expr *E, QualType can)
+  : Type(TypeOfExpr, can, E->isTypeDependent()), TOExpr(E) {
+}
+
+QualType TypeOfExprType::desugar() const {
+  return getUnderlyingExpr()->getType();
+}
+
+void DependentTypeOfExprType::Profile(llvm::FoldingSetNodeID &ID,
+                                      ASTContext &Context, Expr *E) {
+  E->Profile(ID, Context, true);
+}
+
+DecltypeType::DecltypeType(Expr *E, QualType underlyingType, QualType can)
+  : Type(Decltype, can, E->isTypeDependent()), E(E),
+  UnderlyingType(underlyingType) {
+}
+
+DependentDecltypeType::DependentDecltypeType(ASTContext &Context, Expr *E)
+  : DecltypeType(E, Context.DependentTy), Context(Context) { }
+
+void DependentDecltypeType::Profile(llvm::FoldingSetNodeID &ID,
+                                    ASTContext &Context, Expr *E) {
+  E->Profile(ID, Context, true);
+}
+
+TagType::TagType(TypeClass TC, const TagDecl *D, QualType can)
+  : Type(TC, can, D->isDependentType()),
+    decl(const_cast<TagDecl*>(D), 0) {}
+
+bool RecordType::classof(const TagType *TT) {
+  return isa<RecordDecl>(TT->getDecl());
+}
+
+bool EnumType::classof(const TagType *TT) {
+  return isa<EnumDecl>(TT->getDecl());
+}
+
+static bool isDependent(const TemplateArgument &Arg) {
+  switch (Arg.getKind()) {
+  case TemplateArgument::Null:
+    assert(false && "Should not have a NULL template argument");
+    return false;
+
+  case TemplateArgument::Type:
+    return Arg.getAsType()->isDependentType();
+
+  case TemplateArgument::Template:
+    return Arg.getAsTemplate().isDependent();
+      
+  case TemplateArgument::Declaration:
+  case TemplateArgument::Integral:
+    // Never dependent
+    return false;
+
+  case TemplateArgument::Expression:
+    return (Arg.getAsExpr()->isTypeDependent() ||
+            Arg.getAsExpr()->isValueDependent());
+
+  case TemplateArgument::Pack:
+    assert(0 && "FIXME: Implement!");
+    return false;
+  }
+
+  return false;
+}
+
+bool TemplateSpecializationType::
+anyDependentTemplateArguments(const TemplateArgumentListInfo &Args) {
+  return anyDependentTemplateArguments(Args.getArgumentArray(), Args.size());
+}
+
+bool TemplateSpecializationType::
+anyDependentTemplateArguments(const TemplateArgumentLoc *Args, unsigned N) {
+  for (unsigned i = 0; i != N; ++i)
+    if (isDependent(Args[i].getArgument()))
+      return true;
+  return false;
+}
+
+bool TemplateSpecializationType::
+anyDependentTemplateArguments(const TemplateArgument *Args, unsigned N) {
+  for (unsigned i = 0; i != N; ++i)
+    if (isDependent(Args[i]))
+      return true;
+  return false;
+}
+
+TemplateSpecializationType::
+TemplateSpecializationType(ASTContext &Context, TemplateName T,
+                           bool IsCurrentInstantiation,
+                           const TemplateArgument *Args,
+                           unsigned NumArgs, QualType Canon)
+  : Type(TemplateSpecialization,
+         Canon.isNull()? QualType(this, 0) : Canon,
+         T.isDependent() || anyDependentTemplateArguments(Args, NumArgs)),
+    ContextAndCurrentInstantiation(&Context, IsCurrentInstantiation),
+    Template(T), NumArgs(NumArgs) {
+  assert((!Canon.isNull() ||
+          T.isDependent() || anyDependentTemplateArguments(Args, NumArgs)) &&
+         "No canonical type for non-dependent class template specialization");
+
+  TemplateArgument *TemplateArgs
+    = reinterpret_cast<TemplateArgument *>(this + 1);
+  for (unsigned Arg = 0; Arg < NumArgs; ++Arg)
+    new (&TemplateArgs[Arg]) TemplateArgument(Args[Arg]);
+}
+
+void TemplateSpecializationType::Destroy(ASTContext& C) {
+  for (unsigned Arg = 0; Arg < NumArgs; ++Arg) {
+    // FIXME: Not all expressions get cloned, so we can't yet perform
+    // this destruction.
+    //    if (Expr *E = getArg(Arg).getAsExpr())
+    //      E->Destroy(C);
+  }
+}
+
+TemplateSpecializationType::iterator
+TemplateSpecializationType::end() const {
+  return begin() + getNumArgs();
+}
+
+const TemplateArgument &
+TemplateSpecializationType::getArg(unsigned Idx) const {
+  assert(Idx < getNumArgs() && "Template argument out of range");
+  return getArgs()[Idx];
+}
+
+void
+TemplateSpecializationType::Profile(llvm::FoldingSetNodeID &ID,
+                                    TemplateName T,
+                                    bool IsCurrentInstantiation,
+                                    const TemplateArgument *Args,
+                                    unsigned NumArgs,
+                                    ASTContext &Context) {
+  ID.AddBoolean(IsCurrentInstantiation);
+  T.Profile(ID);
+  for (unsigned Idx = 0; Idx < NumArgs; ++Idx)
+    Args[Idx].Profile(ID, Context);
+}
+
+QualType QualifierCollector::apply(QualType QT) const {
+  if (!hasNonFastQualifiers())
+    return QT.withFastQualifiers(getFastQualifiers());
+
+  assert(Context && "extended qualifiers but no context!");
+  return Context->getQualifiedType(QT, *this);
+}
+
+QualType QualifierCollector::apply(const Type *T) const {
+  if (!hasNonFastQualifiers())
+    return QualType(T, getFastQualifiers());
+
+  assert(Context && "extended qualifiers but no context!");
+  return Context->getQualifiedType(T, *this);
+}
+
+void ObjCInterfaceType::Profile(llvm::FoldingSetNodeID &ID,
+                                         const ObjCInterfaceDecl *Decl,
+                                         ObjCProtocolDecl * const *protocols,
+                                         unsigned NumProtocols) {
+  ID.AddPointer(Decl);
+  for (unsigned i = 0; i != NumProtocols; i++)
+    ID.AddPointer(protocols[i]);
+}
+
+void ObjCInterfaceType::Profile(llvm::FoldingSetNodeID &ID) {
+  Profile(ID, getDecl(), qual_begin(), getNumProtocols());
+}
+
+Linkage Type::getLinkage() const { 
+  // C++ [basic.link]p8:
+  //   Names not covered by these rules have no linkage.
+  if (this != CanonicalType.getTypePtr())
+    return CanonicalType->getLinkage();
+
+  return NoLinkage; 
+}
+
+Linkage BuiltinType::getLinkage() const {
+  // C++ [basic.link]p8:
+  //   A type is said to have linkage if and only if:
+  //     - it is a fundamental type (3.9.1); or
+  return ExternalLinkage;
+}
+
+Linkage TagType::getLinkage() const {
+  // C++ [basic.link]p8:
+  //     - it is a class or enumeration type that is named (or has a name for
+  //       linkage purposes (7.1.3)) and the name has linkage; or
+  //     -  it is a specialization of a class template (14); or
+  return getDecl()->getLinkage();
+}
+
+// C++ [basic.link]p8:
+//   - it is a compound type (3.9.2) other than a class or enumeration, 
+//     compounded exclusively from types that have linkage; or
+Linkage ComplexType::getLinkage() const {
+  return ElementType->getLinkage();
+}
+
+Linkage PointerType::getLinkage() const {
+  return PointeeType->getLinkage();
+}
+
+Linkage BlockPointerType::getLinkage() const {
+  return PointeeType->getLinkage();
+}
+
+Linkage ReferenceType::getLinkage() const {
+  return PointeeType->getLinkage();
+}
+
+Linkage MemberPointerType::getLinkage() const {
+  return minLinkage(Class->getLinkage(), PointeeType->getLinkage());
+}
+
+Linkage ArrayType::getLinkage() const {
+  return ElementType->getLinkage();
+}
+
+Linkage VectorType::getLinkage() const {
+  return ElementType->getLinkage();
+}
+
+Linkage FunctionNoProtoType::getLinkage() const {
+  return getResultType()->getLinkage();
+}
+
+Linkage FunctionProtoType::getLinkage() const {
+  Linkage L = getResultType()->getLinkage();
+  for (arg_type_iterator A = arg_type_begin(), AEnd = arg_type_end();
+       A != AEnd; ++A)
+    L = minLinkage(L, (*A)->getLinkage());
+
+  return L;
+}
+
+Linkage ObjCInterfaceType::getLinkage() const {
+  return ExternalLinkage;
+}
+
+Linkage ObjCObjectPointerType::getLinkage() const {
+  return ExternalLinkage;
+}
diff --git a/lib/AST/TypeLoc.cpp b/lib/AST/TypeLoc.cpp
new file mode 100644
index 0000000..fd9fbc1
--- /dev/null
+++ b/lib/AST/TypeLoc.cpp
@@ -0,0 +1,191 @@
+//===--- TypeLoc.cpp - Type Source Info Wrapper -----------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the TypeLoc subclasses implementations.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/raw_ostream.h"
+#include "clang/AST/TypeLocVisitor.h"
+#include "clang/AST/Expr.h"
+#include "llvm/Support/ErrorHandling.h"
+using namespace clang;
+
+//===----------------------------------------------------------------------===//
+// TypeLoc Implementation
+//===----------------------------------------------------------------------===//
+
+namespace {
+  class TypeLocRanger : public TypeLocVisitor<TypeLocRanger, SourceRange> {
+  public:
+#define ABSTRACT_TYPELOC(CLASS, PARENT)
+#define TYPELOC(CLASS, PARENT) \
+    SourceRange Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
+      return TyLoc.getSourceRange(); \
+    }
+#include "clang/AST/TypeLocNodes.def"
+  };
+}
+
+SourceRange TypeLoc::getSourceRangeImpl(TypeLoc TL) {
+  if (TL.isNull()) return SourceRange();
+  return TypeLocRanger().Visit(TL);
+}
+
+namespace {
+  class TypeSizer : public TypeLocVisitor<TypeSizer, unsigned> {
+  public:
+#define ABSTRACT_TYPELOC(CLASS, PARENT)
+#define TYPELOC(CLASS, PARENT) \
+    unsigned Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
+      return TyLoc.getFullDataSize(); \
+    }
+#include "clang/AST/TypeLocNodes.def"
+  };
+}
+
+/// \brief Returns the size of the type source info data block.
+unsigned TypeLoc::getFullDataSizeForType(QualType Ty) {
+  if (Ty.isNull()) return 0;
+  return TypeSizer().Visit(TypeLoc(Ty, 0));
+}
+
+namespace {
+  class NextLoc : public TypeLocVisitor<NextLoc, TypeLoc> {
+  public:
+#define ABSTRACT_TYPELOC(CLASS, PARENT)
+#define TYPELOC(CLASS, PARENT) \
+    TypeLoc Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
+      return TyLoc.getNextTypeLoc(); \
+    }
+#include "clang/AST/TypeLocNodes.def"
+  };
+}
+
+/// \brief Get the next TypeLoc pointed by this TypeLoc, e.g for "int*" the
+/// TypeLoc is a PointerLoc and next TypeLoc is for "int".
+TypeLoc TypeLoc::getNextTypeLocImpl(TypeLoc TL) {
+  return NextLoc().Visit(TL);
+}
+
+namespace {
+  struct TypeLocInitializer : public TypeLocVisitor<TypeLocInitializer> {
+    SourceLocation Loc;
+    TypeLocInitializer(SourceLocation Loc) : Loc(Loc) {}
+  
+#define ABSTRACT_TYPELOC(CLASS, PARENT)
+#define TYPELOC(CLASS, PARENT) \
+    void Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
+      TyLoc.initializeLocal(Loc); \
+    }
+#include "clang/AST/TypeLocNodes.def"
+  };
+}
+
+/// \brief Initializes a type location, and all of its children
+/// recursively, as if the entire tree had been written in the
+/// given location.
+void TypeLoc::initializeImpl(TypeLoc TL, SourceLocation Loc) {
+  do {
+    TypeLocInitializer(Loc).Visit(TL);
+  } while ((TL = TL.getNextTypeLoc()));
+}
+
+namespace {
+  struct TSTChecker : public TypeLocVisitor<TSTChecker, bool> {
+    // Overload resolution does the real work for us.
+    static bool isTypeSpec(TypeSpecTypeLoc _) { return true; }
+    static bool isTypeSpec(TypeLoc _) { return false; }
+
+#define ABSTRACT_TYPELOC(CLASS, PARENT)
+#define TYPELOC(CLASS, PARENT) \
+    bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
+      return isTypeSpec(TyLoc); \
+    }
+#include "clang/AST/TypeLocNodes.def"
+  };
+}
+
+
+/// \brief Determines if the given type loc corresponds to a
+/// TypeSpecTypeLoc.  Since there is not actually a TypeSpecType in
+/// the type hierarchy, this is made somewhat complicated.
+///
+/// There are a lot of types that currently use TypeSpecTypeLoc
+/// because it's a convenient base class.  Ideally we would not accept
+/// those here, but ideally we would have better implementations for
+/// them.
+bool TypeSpecTypeLoc::classof(const TypeLoc *TL) {
+  if (TL->getType().hasLocalQualifiers()) return false;
+  return TSTChecker().Visit(*TL);
+}
+
+// Reimplemented to account for GNU/C++ extension
+//     typeof unary-expression
+// where there are no parentheses.
+SourceRange TypeOfExprTypeLoc::getSourceRange() const {
+  if (getRParenLoc().isValid())
+    return SourceRange(getTypeofLoc(), getRParenLoc());
+  else
+    return SourceRange(getTypeofLoc(),
+                       getUnderlyingExpr()->getSourceRange().getEnd());
+}
+
+
+TypeSpecifierType BuiltinTypeLoc::getWrittenTypeSpec() const {
+  if (needsExtraLocalData())
+    return static_cast<TypeSpecifierType>(getWrittenBuiltinSpecs().Type);
+  else {
+    switch (getTypePtr()->getKind()) {
+    case BuiltinType::Void:
+      return TST_void;
+    case BuiltinType::Bool:
+      return TST_bool;
+    case BuiltinType::Char_U:
+    case BuiltinType::Char_S:
+      return TST_char;
+    case BuiltinType::Char16:
+      return TST_char16;        
+    case BuiltinType::Char32:
+      return TST_char32;
+    case BuiltinType::WChar:
+      return TST_wchar;
+    case BuiltinType::UndeducedAuto:
+      return TST_auto;
+        
+    case BuiltinType::UChar:
+    case BuiltinType::UShort:
+    case BuiltinType::UInt:
+    case BuiltinType::ULong:
+    case BuiltinType::ULongLong:
+    case BuiltinType::UInt128:
+    case BuiltinType::SChar:
+    case BuiltinType::Short:
+    case BuiltinType::Int:
+    case BuiltinType::Long:
+    case BuiltinType::LongLong:
+    case BuiltinType::Int128:
+    case BuiltinType::Float:
+    case BuiltinType::Double:
+    case BuiltinType::LongDouble:
+      llvm_unreachable("Builtin type needs extra local data!");
+      // Fall through, if the impossible happens.
+        
+    case BuiltinType::NullPtr:
+    case BuiltinType::Overload:
+    case BuiltinType::Dependent:
+    case BuiltinType::ObjCId:
+    case BuiltinType::ObjCClass:
+    case BuiltinType::ObjCSel:
+      return TST_unspecified;
+    }
+  }
+  
+  return TST_unspecified;
+}
diff --git a/lib/AST/TypePrinter.cpp b/lib/AST/TypePrinter.cpp
new file mode 100644
index 0000000..7953b86
--- /dev/null
+++ b/lib/AST/TypePrinter.cpp
@@ -0,0 +1,835 @@
+//===--- TypePrinter.cpp - Pretty-Print Clang Types -----------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This contains code to print types from Clang's type system.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/PrettyPrinter.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/SourceManager.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace clang;
+
+namespace {
+  class TypePrinter {
+    PrintingPolicy Policy;
+
+  public:
+    explicit TypePrinter(const PrintingPolicy &Policy) : Policy(Policy) { }
+    
+    void Print(QualType T, std::string &S);
+    void AppendScope(DeclContext *DC, std::string &S);
+    void PrintTag(TagDecl *T, std::string &S);
+#define ABSTRACT_TYPE(CLASS, PARENT)
+#define TYPE(CLASS, PARENT) \
+  void Print##CLASS(const CLASS##Type *T, std::string &S);
+#include "clang/AST/TypeNodes.def"
+  };
+}
+
+static void AppendTypeQualList(std::string &S, unsigned TypeQuals) {
+  if (TypeQuals & Qualifiers::Const) {
+    if (!S.empty()) S += ' ';
+    S += "const";
+  }
+  if (TypeQuals & Qualifiers::Volatile) {
+    if (!S.empty()) S += ' ';
+    S += "volatile";
+  }
+  if (TypeQuals & Qualifiers::Restrict) {
+    if (!S.empty()) S += ' ';
+    S += "restrict";
+  }
+}
+
+void TypePrinter::Print(QualType T, std::string &S) {
+  if (T.isNull()) {
+    S += "NULL TYPE";
+    return;
+  }
+  
+  if (Policy.SuppressSpecifiers && T->isSpecifierType())
+    return;
+  
+  // Print qualifiers as appropriate.
+  Qualifiers Quals = T.getLocalQualifiers();
+  if (!Quals.empty()) {
+    std::string TQS;
+    Quals.getAsStringInternal(TQS, Policy);
+    
+    if (!S.empty()) {
+      TQS += ' ';
+      TQS += S;
+    }
+    std::swap(S, TQS);
+  }
+  
+  switch (T->getTypeClass()) {
+#define ABSTRACT_TYPE(CLASS, PARENT)
+#define TYPE(CLASS, PARENT) case Type::CLASS:                \
+    Print##CLASS(cast<CLASS##Type>(T.getTypePtr()), S);      \
+    break;
+#include "clang/AST/TypeNodes.def"
+  }
+}
+
+void TypePrinter::PrintBuiltin(const BuiltinType *T, std::string &S) {
+  if (S.empty()) {
+    S = T->getName(Policy.LangOpts);
+  } else {
+    // Prefix the basic type, e.g. 'int X'.
+    S = ' ' + S;
+    S = T->getName(Policy.LangOpts) + S;
+  }
+}
+
+void TypePrinter::PrintComplex(const ComplexType *T, std::string &S) {
+  Print(T->getElementType(), S);
+  S = "_Complex " + S;
+}
+
+void TypePrinter::PrintPointer(const PointerType *T, std::string &S) { 
+  S = '*' + S;
+  
+  // Handle things like 'int (*A)[4];' correctly.
+  // FIXME: this should include vectors, but vectors use attributes I guess.
+  if (isa<ArrayType>(T->getPointeeType()))
+    S = '(' + S + ')';
+  
+  Print(T->getPointeeType(), S);
+}
+
+void TypePrinter::PrintBlockPointer(const BlockPointerType *T, std::string &S) {
+  S = '^' + S;
+  Print(T->getPointeeType(), S);
+}
+
+void TypePrinter::PrintLValueReference(const LValueReferenceType *T, 
+                                       std::string &S) { 
+  S = '&' + S;
+  
+  // Handle things like 'int (&A)[4];' correctly.
+  // FIXME: this should include vectors, but vectors use attributes I guess.
+  if (isa<ArrayType>(T->getPointeeTypeAsWritten()))
+    S = '(' + S + ')';
+  
+  Print(T->getPointeeTypeAsWritten(), S);
+}
+
+void TypePrinter::PrintRValueReference(const RValueReferenceType *T, 
+                                       std::string &S) { 
+  S = "&&" + S;
+  
+  // Handle things like 'int (&&A)[4];' correctly.
+  // FIXME: this should include vectors, but vectors use attributes I guess.
+  if (isa<ArrayType>(T->getPointeeTypeAsWritten()))
+    S = '(' + S + ')';
+  
+  Print(T->getPointeeTypeAsWritten(), S);
+}
+
+void TypePrinter::PrintMemberPointer(const MemberPointerType *T, 
+                                     std::string &S) { 
+  std::string C;
+  Print(QualType(T->getClass(), 0), C);
+  C += "::*";
+  S = C + S;
+  
+  // Handle things like 'int (Cls::*A)[4];' correctly.
+  // FIXME: this should include vectors, but vectors use attributes I guess.
+  if (isa<ArrayType>(T->getPointeeType()))
+    S = '(' + S + ')';
+  
+  Print(T->getPointeeType(), S);
+}
+
+void TypePrinter::PrintConstantArray(const ConstantArrayType *T, 
+                                     std::string &S) {
+  S += '[';
+  S += llvm::utostr(T->getSize().getZExtValue());
+  S += ']';
+  
+  Print(T->getElementType(), S);
+}
+
+void TypePrinter::PrintIncompleteArray(const IncompleteArrayType *T, 
+                                       std::string &S) {
+  S += "[]";
+  Print(T->getElementType(), S);
+}
+
+void TypePrinter::PrintVariableArray(const VariableArrayType *T, 
+                                     std::string &S) { 
+  S += '[';
+  
+  if (T->getIndexTypeQualifiers().hasQualifiers()) {
+    AppendTypeQualList(S, T->getIndexTypeCVRQualifiers());
+    S += ' ';
+  }
+  
+  if (T->getSizeModifier() == VariableArrayType::Static)
+    S += "static";
+  else if (T->getSizeModifier() == VariableArrayType::Star)
+    S += '*';
+  
+  if (T->getSizeExpr()) {
+    std::string SStr;
+    llvm::raw_string_ostream s(SStr);
+    T->getSizeExpr()->printPretty(s, 0, Policy);
+    S += s.str();
+  }
+  S += ']';
+  
+  Print(T->getElementType(), S);
+}
+
+void TypePrinter::PrintDependentSizedArray(const DependentSizedArrayType *T, 
+                                           std::string &S) {  
+  S += '[';
+  
+  if (T->getSizeExpr()) {
+    std::string SStr;
+    llvm::raw_string_ostream s(SStr);
+    T->getSizeExpr()->printPretty(s, 0, Policy);
+    S += s.str();
+  }
+  S += ']';
+  
+  Print(T->getElementType(), S);
+}
+
+void TypePrinter::PrintDependentSizedExtVector(
+                                          const DependentSizedExtVectorType *T, 
+                                               std::string &S) { 
+  Print(T->getElementType(), S);
+  
+  S += " __attribute__((ext_vector_type(";
+  if (T->getSizeExpr()) {
+    std::string SStr;
+    llvm::raw_string_ostream s(SStr);
+    T->getSizeExpr()->printPretty(s, 0, Policy);
+    S += s.str();
+  }
+  S += ")))";  
+}
+
+void TypePrinter::PrintVector(const VectorType *T, std::string &S) { 
+  if (T->isAltiVec()) {
+    if (T->isPixel())
+      S = "__vector __pixel " + S;
+    else {
+      Print(T->getElementType(), S);
+      S = "__vector " + S;
+    }
+  } else {
+    // FIXME: We prefer to print the size directly here, but have no way
+    // to get the size of the type.
+    Print(T->getElementType(), S);
+    std::string V = "__attribute__((__vector_size__(";
+    V += llvm::utostr_32(T->getNumElements()); // convert back to bytes.
+    std::string ET;
+    Print(T->getElementType(), ET);
+    V += " * sizeof(" + ET + ")))) ";
+    S = V + S;
+  }
+}
+
+void TypePrinter::PrintExtVector(const ExtVectorType *T, std::string &S) { 
+  S += " __attribute__((ext_vector_type(";
+  S += llvm::utostr_32(T->getNumElements());
+  S += ")))";
+  Print(T->getElementType(), S);
+}
+
+void TypePrinter::PrintFunctionProto(const FunctionProtoType *T, 
+                                     std::string &S) { 
+  // If needed for precedence reasons, wrap the inner part in grouping parens.
+  if (!S.empty())
+    S = "(" + S + ")";
+  
+  S += "(";
+  std::string Tmp;
+  PrintingPolicy ParamPolicy(Policy);
+  ParamPolicy.SuppressSpecifiers = false;
+  for (unsigned i = 0, e = T->getNumArgs(); i != e; ++i) {
+    if (i) S += ", ";
+    Print(T->getArgType(i), Tmp);
+    S += Tmp;
+    Tmp.clear();
+  }
+  
+  if (T->isVariadic()) {
+    if (T->getNumArgs())
+      S += ", ";
+    S += "...";
+  } else if (T->getNumArgs() == 0 && !Policy.LangOpts.CPlusPlus) {
+    // Do not emit int() if we have a proto, emit 'int(void)'.
+    S += "void";
+  }
+  
+  S += ")";
+
+  FunctionType::ExtInfo Info = T->getExtInfo();
+  switch(Info.getCC()) {
+  case CC_Default:
+  default: break;
+  case CC_C:
+    S += " __attribute__((cdecl))";
+    break;
+  case CC_X86StdCall:
+    S += " __attribute__((stdcall))";
+    break;
+  case CC_X86FastCall:
+    S += " __attribute__((fastcall))";
+    break;
+  }
+  if (Info.getNoReturn())
+    S += " __attribute__((noreturn))";
+  if (Info.getRegParm())
+    S += " __attribute__((regparm (" +
+        llvm::utostr_32(Info.getRegParm()) + ")))";
+  
+  if (T->hasExceptionSpec()) {
+    S += " throw(";
+    if (T->hasAnyExceptionSpec())
+      S += "...";
+    else 
+      for (unsigned I = 0, N = T->getNumExceptions(); I != N; ++I) {
+        if (I)
+          S += ", ";
+
+        std::string ExceptionType;
+        Print(T->getExceptionType(I), ExceptionType);
+        S += ExceptionType;
+      }
+    S += ")";
+  }
+
+  AppendTypeQualList(S, T->getTypeQuals());
+  
+  Print(T->getResultType(), S);
+}
+
+void TypePrinter::PrintFunctionNoProto(const FunctionNoProtoType *T, 
+                                       std::string &S) { 
+  // If needed for precedence reasons, wrap the inner part in grouping parens.
+  if (!S.empty())
+    S = "(" + S + ")";
+  
+  S += "()";
+  if (T->getNoReturnAttr())
+    S += " __attribute__((noreturn))";
+  Print(T->getResultType(), S);
+}
+
+static void PrintTypeSpec(const NamedDecl *D, std::string &S) {
+  IdentifierInfo *II = D->getIdentifier();
+  if (S.empty())
+    S = II->getName().str();
+  else
+    S = II->getName().str() + ' ' + S;
+}
+
+void TypePrinter::PrintUnresolvedUsing(const UnresolvedUsingType *T,
+                                       std::string &S) {
+  PrintTypeSpec(T->getDecl(), S);
+}
+
+void TypePrinter::PrintTypedef(const TypedefType *T, std::string &S) { 
+  PrintTypeSpec(T->getDecl(), S);
+}
+
+void TypePrinter::PrintTypeOfExpr(const TypeOfExprType *T, std::string &S) {
+  if (!S.empty())    // Prefix the basic type, e.g. 'typeof(e) X'.
+    S = ' ' + S;
+  std::string Str;
+  llvm::raw_string_ostream s(Str);
+  T->getUnderlyingExpr()->printPretty(s, 0, Policy);
+  S = "typeof " + s.str() + S;
+}
+
+void TypePrinter::PrintTypeOf(const TypeOfType *T, std::string &S) { 
+  if (!S.empty())    // Prefix the basic type, e.g. 'typeof(t) X'.
+    S = ' ' + S;
+  std::string Tmp;
+  Print(T->getUnderlyingType(), Tmp);
+  S = "typeof(" + Tmp + ")" + S;
+}
+
+void TypePrinter::PrintDecltype(const DecltypeType *T, std::string &S) { 
+  if (!S.empty())    // Prefix the basic type, e.g. 'decltype(t) X'.
+    S = ' ' + S;
+  std::string Str;
+  llvm::raw_string_ostream s(Str);
+  T->getUnderlyingExpr()->printPretty(s, 0, Policy);
+  S = "decltype(" + s.str() + ")" + S;
+}
+
+/// Appends the given scope to the end of a string.
+void TypePrinter::AppendScope(DeclContext *DC, std::string &Buffer) {
+  if (DC->isTranslationUnit()) return;
+  AppendScope(DC->getParent(), Buffer);
+
+  unsigned OldSize = Buffer.size();
+
+  if (NamespaceDecl *NS = dyn_cast<NamespaceDecl>(DC)) {
+    if (NS->getIdentifier())
+      Buffer += NS->getNameAsString();
+    else
+      Buffer += "<anonymous>";
+  } else if (ClassTemplateSpecializationDecl *Spec
+               = dyn_cast<ClassTemplateSpecializationDecl>(DC)) {
+    const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
+    std::string TemplateArgsStr
+      = TemplateSpecializationType::PrintTemplateArgumentList(
+                                            TemplateArgs.getFlatArgumentList(),
+                                            TemplateArgs.flat_size(),
+                                            Policy);
+    Buffer += Spec->getIdentifier()->getName();
+    Buffer += TemplateArgsStr;
+  } else if (TagDecl *Tag = dyn_cast<TagDecl>(DC)) {
+    if (TypedefDecl *Typedef = Tag->getTypedefForAnonDecl())
+      Buffer += Typedef->getIdentifier()->getName();
+    else if (Tag->getIdentifier())
+      Buffer += Tag->getIdentifier()->getName();
+  }
+
+  if (Buffer.size() != OldSize)
+    Buffer += "::";
+}
+
+void TypePrinter::PrintTag(TagDecl *D, std::string &InnerString) {
+  if (Policy.SuppressTag)
+    return;
+
+  std::string Buffer;
+  bool HasKindDecoration = false;
+
+  // We don't print tags unless this is an elaborated type.
+  // In C, we just assume every RecordType is an elaborated type.
+  if (!Policy.LangOpts.CPlusPlus && !D->getTypedefForAnonDecl()) {
+    HasKindDecoration = true;
+    Buffer += D->getKindName();
+    Buffer += ' ';
+  }
+
+  if (!Policy.SuppressScope)
+    // Compute the full nested-name-specifier for this type. In C,
+    // this will always be empty.
+    AppendScope(D->getDeclContext(), Buffer);
+
+  if (const IdentifierInfo *II = D->getIdentifier())
+    Buffer += II->getNameStart();
+  else if (TypedefDecl *Typedef = D->getTypedefForAnonDecl()) {
+    assert(Typedef->getIdentifier() && "Typedef without identifier?");
+    Buffer += Typedef->getIdentifier()->getNameStart();
+  } else {
+    // Make an unambiguous representation for anonymous types, e.g.
+    //   <anonymous enum at /usr/include/string.h:120:9>
+    llvm::raw_string_ostream OS(Buffer);
+    OS << "<anonymous";
+
+    if (Policy.AnonymousTagLocations) {
+      // Suppress the redundant tag keyword if we just printed one.
+      // We don't have to worry about ElaboratedTypes here because you can't
+      // refer to an anonymous type with one.
+      if (!HasKindDecoration)
+        OS << " " << D->getKindName();
+
+      PresumedLoc PLoc = D->getASTContext().getSourceManager().getPresumedLoc(
+        D->getLocation());
+      OS << " at " << PLoc.getFilename()
+         << ':' << PLoc.getLine()
+         << ':' << PLoc.getColumn();
+    }
+    
+    OS << '>';
+    OS.flush();
+  }
+
+  // If this is a class template specialization, print the template
+  // arguments.
+  if (ClassTemplateSpecializationDecl *Spec
+        = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
+    const TemplateArgument *Args;
+    unsigned NumArgs;
+    if (TypeSourceInfo *TAW = Spec->getTypeAsWritten()) {
+      const TemplateSpecializationType *TST =
+        cast<TemplateSpecializationType>(TAW->getType());
+      Args = TST->getArgs();
+      NumArgs = TST->getNumArgs();
+    } else {
+      const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
+      Args = TemplateArgs.getFlatArgumentList();
+      NumArgs = TemplateArgs.flat_size();
+    }
+    Buffer += TemplateSpecializationType::PrintTemplateArgumentList(Args,
+                                                                    NumArgs,
+                                                                    Policy);
+  }
+
+  if (!InnerString.empty()) {
+    Buffer += ' ';
+    Buffer += InnerString;
+  }
+
+  std::swap(Buffer, InnerString);
+}
+
+void TypePrinter::PrintRecord(const RecordType *T, std::string &S) {
+  PrintTag(T->getDecl(), S);
+}
+
+void TypePrinter::PrintEnum(const EnumType *T, std::string &S) { 
+  PrintTag(T->getDecl(), S);
+}
+
+void TypePrinter::PrintElaborated(const ElaboratedType *T, std::string &S) { 
+  Print(T->getUnderlyingType(), S);
+
+  // We don't actually make these in C, but the language options
+  // sometimes lie to us -- for example, if someone calls
+  // QualType::getAsString().  Just suppress the redundant tag if so.
+  if (Policy.LangOpts.CPlusPlus)
+    S = std::string(T->getNameForTagKind(T->getTagKind())) + ' ' + S;  
+}
+
+void TypePrinter::PrintTemplateTypeParm(const TemplateTypeParmType *T, 
+                                        std::string &S) { 
+  if (!S.empty())    // Prefix the basic type, e.g. 'parmname X'.
+    S = ' ' + S;
+  
+  if (!T->getName())
+    S = "type-parameter-" + llvm::utostr_32(T->getDepth()) + '-' +
+        llvm::utostr_32(T->getIndex()) + S;
+  else
+    S = T->getName()->getName().str() + S;  
+}
+
+void TypePrinter::PrintSubstTemplateTypeParm(const SubstTemplateTypeParmType *T, 
+                                             std::string &S) { 
+  Print(T->getReplacementType(), S);
+}
+
+void TypePrinter::PrintTemplateSpecialization(
+                                            const TemplateSpecializationType *T, 
+                                              std::string &S) { 
+  std::string SpecString;
+  
+  {
+    llvm::raw_string_ostream OS(SpecString);
+    T->getTemplateName().print(OS, Policy);
+  }
+  
+  SpecString += TemplateSpecializationType::PrintTemplateArgumentList(
+                                                                  T->getArgs(), 
+                                                                T->getNumArgs(), 
+                                                                      Policy);
+  if (S.empty())
+    S.swap(SpecString);
+  else
+    S = SpecString + ' ' + S;
+}
+
+void TypePrinter::PrintInjectedClassName(const InjectedClassNameType *T,
+                                         std::string &S) {
+  PrintTemplateSpecialization(T->getInjectedTST(), S);
+}
+
+void TypePrinter::PrintQualifiedName(const QualifiedNameType *T, 
+                                     std::string &S) { 
+  std::string MyString;
+  
+  {
+    llvm::raw_string_ostream OS(MyString);
+    T->getQualifier()->print(OS, Policy);
+  }
+  
+  std::string TypeStr;
+  PrintingPolicy InnerPolicy(Policy);
+  InnerPolicy.SuppressScope = true;
+  TypePrinter(InnerPolicy).Print(T->getNamedType(), TypeStr);
+  
+  MyString += TypeStr;
+  if (S.empty())
+    S.swap(MyString);
+  else
+    S = MyString + ' ' + S;  
+}
+
+void TypePrinter::PrintDependentName(const DependentNameType *T, std::string &S) { 
+  std::string MyString;
+  
+  {
+    llvm::raw_string_ostream OS(MyString);
+    switch (T->getKeyword()) {
+    case ETK_None: break;
+    case ETK_Typename: OS << "typename "; break;
+    case ETK_Class: OS << "class "; break;
+    case ETK_Struct: OS << "struct "; break;
+    case ETK_Union: OS << "union "; break;
+    case ETK_Enum: OS << "enum "; break;
+    }
+    
+    T->getQualifier()->print(OS, Policy);
+    
+    if (const IdentifierInfo *Ident = T->getIdentifier())
+      OS << Ident->getName();
+    else if (const TemplateSpecializationType *Spec = T->getTemplateId()) {
+      Spec->getTemplateName().print(OS, Policy, true);
+      OS << TemplateSpecializationType::PrintTemplateArgumentList(
+                                                            Spec->getArgs(),
+                                                            Spec->getNumArgs(),
+                                                            Policy);
+    }
+  }
+  
+  if (S.empty())
+    S.swap(MyString);
+  else
+    S = MyString + ' ' + S;
+}
+
+void TypePrinter::PrintObjCInterface(const ObjCInterfaceType *T, 
+                                     std::string &S) { 
+  if (!S.empty())    // Prefix the basic type, e.g. 'typedefname X'.
+    S = ' ' + S;
+  
+  std::string ObjCQIString = T->getDecl()->getNameAsString();
+  if (T->getNumProtocols()) {
+    ObjCQIString += '<';
+    bool isFirst = true;
+    for (ObjCInterfaceType::qual_iterator I = T->qual_begin(), 
+                                          E = T->qual_end(); 
+         I != E; ++I) {
+      if (isFirst)
+        isFirst = false;
+      else
+        ObjCQIString += ',';
+      ObjCQIString += (*I)->getNameAsString();
+    }
+    ObjCQIString += '>';
+  }
+  S = ObjCQIString + S;
+}
+
+void TypePrinter::PrintObjCObjectPointer(const ObjCObjectPointerType *T, 
+                                         std::string &S) { 
+  std::string ObjCQIString;
+  
+  if (T->isObjCIdType() || T->isObjCQualifiedIdType())
+    ObjCQIString = "id";
+  else if (T->isObjCClassType() || T->isObjCQualifiedClassType())
+    ObjCQIString = "Class";
+  else if (T->isObjCSelType())
+    ObjCQIString = "SEL";
+  else
+    ObjCQIString = T->getInterfaceDecl()->getNameAsString();
+  
+  if (!T->qual_empty()) {
+    ObjCQIString += '<';
+    for (ObjCObjectPointerType::qual_iterator I = T->qual_begin(), 
+                                              E = T->qual_end();
+         I != E; ++I) {
+      ObjCQIString += (*I)->getNameAsString();
+      if (I+1 != E)
+        ObjCQIString += ',';
+    }
+    ObjCQIString += '>';
+  }
+  
+  T->getPointeeType().getLocalQualifiers().getAsStringInternal(ObjCQIString, 
+                                                               Policy);
+  
+  if (!T->isObjCIdType() && !T->isObjCQualifiedIdType())
+    ObjCQIString += " *"; // Don't forget the implicit pointer.
+  else if (!S.empty()) // Prefix the basic type, e.g. 'typedefname X'.
+    S = ' ' + S;
+  
+  S = ObjCQIString + S;  
+}
+
+static void PrintTemplateArgument(std::string &Buffer,
+                                  const TemplateArgument &Arg,
+                                  const PrintingPolicy &Policy) {
+  switch (Arg.getKind()) {
+    case TemplateArgument::Null:
+      assert(false && "Null template argument");
+      break;
+      
+    case TemplateArgument::Type:
+      Arg.getAsType().getAsStringInternal(Buffer, Policy);
+      break;
+      
+    case TemplateArgument::Declaration:
+      Buffer = cast<NamedDecl>(Arg.getAsDecl())->getNameAsString();
+      break;
+      
+    case TemplateArgument::Template: {
+      llvm::raw_string_ostream s(Buffer);
+      Arg.getAsTemplate().print(s, Policy);
+      break;
+    }
+      
+    case TemplateArgument::Integral:
+      Buffer = Arg.getAsIntegral()->toString(10, true);
+      break;
+      
+    case TemplateArgument::Expression: {
+      llvm::raw_string_ostream s(Buffer);
+      Arg.getAsExpr()->printPretty(s, 0, Policy);
+      break;
+    }
+      
+    case TemplateArgument::Pack:
+      assert(0 && "FIXME: Implement!");
+      break;
+  }
+}
+
+std::string TemplateSpecializationType::
+  PrintTemplateArgumentList(const TemplateArgumentListInfo &Args,
+                            const PrintingPolicy &Policy) {
+  return PrintTemplateArgumentList(Args.getArgumentArray(),
+                                   Args.size(),
+                                   Policy);
+}
+
+std::string
+TemplateSpecializationType::PrintTemplateArgumentList(
+                                                const TemplateArgument *Args,
+                                                unsigned NumArgs,
+                                                const PrintingPolicy &Policy) {
+  std::string SpecString;
+  SpecString += '<';
+  for (unsigned Arg = 0; Arg < NumArgs; ++Arg) {
+    if (Arg)
+      SpecString += ", ";
+    
+    // Print the argument into a string.
+    std::string ArgString;
+    PrintTemplateArgument(ArgString, Args[Arg], Policy);
+    
+    // If this is the first argument and its string representation
+    // begins with the global scope specifier ('::foo'), add a space
+    // to avoid printing the diagraph '<:'.
+    if (!Arg && !ArgString.empty() && ArgString[0] == ':')
+      SpecString += ' ';
+    
+    SpecString += ArgString;
+  }
+  
+  // If the last character of our string is '>', add another space to
+  // keep the two '>''s separate tokens. We don't *have* to do this in
+  // C++0x, but it's still good hygiene.
+  if (SpecString[SpecString.size() - 1] == '>')
+    SpecString += ' ';
+  
+  SpecString += '>';
+  
+  return SpecString;
+}
+
+// Sadly, repeat all that with TemplateArgLoc.
+std::string TemplateSpecializationType::
+PrintTemplateArgumentList(const TemplateArgumentLoc *Args, unsigned NumArgs,
+                          const PrintingPolicy &Policy) {
+  std::string SpecString;
+  SpecString += '<';
+  for (unsigned Arg = 0; Arg < NumArgs; ++Arg) {
+    if (Arg)
+      SpecString += ", ";
+    
+    // Print the argument into a string.
+    std::string ArgString;
+    PrintTemplateArgument(ArgString, Args[Arg].getArgument(), Policy);
+    
+    // If this is the first argument and its string representation
+    // begins with the global scope specifier ('::foo'), add a space
+    // to avoid printing the diagraph '<:'.
+    if (!Arg && !ArgString.empty() && ArgString[0] == ':')
+      SpecString += ' ';
+    
+    SpecString += ArgString;
+  }
+  
+  // If the last character of our string is '>', add another space to
+  // keep the two '>''s separate tokens. We don't *have* to do this in
+  // C++0x, but it's still good hygiene.
+  if (SpecString[SpecString.size() - 1] == '>')
+    SpecString += ' ';
+  
+  SpecString += '>';
+  
+  return SpecString;
+}
+
+void QualType::dump(const char *msg) const {
+  std::string R = "identifier";
+  LangOptions LO;
+  getAsStringInternal(R, PrintingPolicy(LO));
+  if (msg)
+    llvm::errs() << msg << ": ";
+  llvm::errs() << R << "\n";
+}
+void QualType::dump() const {
+  dump("");
+}
+
+void Type::dump() const {
+  QualType(this, 0).dump();
+}
+
+std::string Qualifiers::getAsString() const {
+  LangOptions LO;
+  return getAsString(PrintingPolicy(LO));
+}
+
+// Appends qualifiers to the given string, separated by spaces.  Will
+// prefix a space if the string is non-empty.  Will not append a final
+// space.
+void Qualifiers::getAsStringInternal(std::string &S,
+                                     const PrintingPolicy&) const {
+  AppendTypeQualList(S, getCVRQualifiers());
+  if (unsigned AddressSpace = getAddressSpace()) {
+    if (!S.empty()) S += ' ';
+    S += "__attribute__((address_space(";
+    S += llvm::utostr_32(AddressSpace);
+    S += ")))";
+  }
+  if (Qualifiers::GC GCAttrType = getObjCGCAttr()) {
+    if (!S.empty()) S += ' ';
+    S += "__attribute__((objc_gc(";
+    if (GCAttrType == Qualifiers::Weak)
+      S += "weak";
+    else
+      S += "strong";
+    S += ")))";
+  }
+}
+
+std::string QualType::getAsString() const {
+  std::string S;
+  LangOptions LO;
+  getAsStringInternal(S, PrintingPolicy(LO));
+  return S;
+}
+
+void QualType::getAsStringInternal(std::string &S,
+                                   const PrintingPolicy &Policy) const {
+  TypePrinter Printer(Policy);
+  Printer.Print(*this, S);
+}
diff --git a/lib/Analysis/AnalysisContext.cpp b/lib/Analysis/AnalysisContext.cpp
new file mode 100644
index 0000000..06d8aec
--- /dev/null
+++ b/lib/Analysis/AnalysisContext.cpp
@@ -0,0 +1,325 @@
+//== AnalysisContext.cpp - Analysis context for Path Sens analysis -*- C++ -*-//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines AnalysisContext, a class that manages the analysis context
+// data for path sensitive analysis.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/ParentMap.h"
+#include "clang/AST/StmtVisitor.h"
+#include "clang/Analysis/Analyses/LiveVariables.h"
+#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Analysis/CFG.h"
+#include "clang/Analysis/Support/BumpVector.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/Support/ErrorHandling.h"
+
+using namespace clang;
+
+void AnalysisContextManager::clear() {
+  for (ContextMap::iterator I = Contexts.begin(), E = Contexts.end(); I!=E; ++I)
+    delete I->second;
+  Contexts.clear();
+}
+
+Stmt *AnalysisContext::getBody() {
+  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
+    return FD->getBody();
+  else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
+    return MD->getBody();
+  else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
+    return BD->getBody();
+  else if (const FunctionTemplateDecl *FunTmpl
+           = dyn_cast_or_null<FunctionTemplateDecl>(D))
+    return FunTmpl->getTemplatedDecl()->getBody();
+
+  llvm_unreachable("unknown code decl");
+}
+
+const ImplicitParamDecl *AnalysisContext::getSelfDecl() const {
+  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
+    return MD->getSelfDecl();
+
+  return NULL;
+}
+
+CFG *AnalysisContext::getCFG() {
+  if (!builtCFG) {
+    cfg = CFG::buildCFG(D, getBody(), &D->getASTContext(), AddEHEdges);
+    // Even when the cfg is not successfully built, we don't
+    // want to try building it again.
+    builtCFG = true;
+  }
+  return cfg;
+}
+
+ParentMap &AnalysisContext::getParentMap() {
+  if (!PM)
+    PM = new ParentMap(getBody());
+  return *PM;
+}
+
+LiveVariables *AnalysisContext::getLiveVariables() {
+  if (!liveness) {
+    CFG *c = getCFG();
+    if (!c)
+      return 0;
+
+    liveness = new LiveVariables(*this);
+    liveness->runOnCFG(*c);
+    liveness->runOnAllBlocks(*c, 0, true);
+  }
+
+  return liveness;
+}
+
+AnalysisContext *AnalysisContextManager::getContext(const Decl *D) {
+  AnalysisContext *&AC = Contexts[D];
+  if (!AC)
+    AC = new AnalysisContext(D);
+
+  return AC;
+}
+
+//===----------------------------------------------------------------------===//
+// FoldingSet profiling.
+//===----------------------------------------------------------------------===//
+
+void LocationContext::ProfileCommon(llvm::FoldingSetNodeID &ID,
+                                    ContextKind ck,
+                                    AnalysisContext *ctx,
+                                    const LocationContext *parent,
+                                    const void* data) {
+  ID.AddInteger(ck);
+  ID.AddPointer(ctx);
+  ID.AddPointer(parent);
+  ID.AddPointer(data);
+}
+
+void StackFrameContext::Profile(llvm::FoldingSetNodeID &ID) {
+  Profile(ID, getAnalysisContext(), getParent(), CallSite, Block, Index);
+}
+
+void ScopeContext::Profile(llvm::FoldingSetNodeID &ID) {
+  Profile(ID, getAnalysisContext(), getParent(), Enter);
+}
+
+void BlockInvocationContext::Profile(llvm::FoldingSetNodeID &ID) {
+  Profile(ID, getAnalysisContext(), getParent(), BD);
+}
+
+//===----------------------------------------------------------------------===//
+// LocationContext creation.
+//===----------------------------------------------------------------------===//
+
+template <typename LOC, typename DATA>
+const LOC*
+LocationContextManager::getLocationContext(AnalysisContext *ctx,
+                                           const LocationContext *parent,
+                                           const DATA *d) {
+  llvm::FoldingSetNodeID ID;
+  LOC::Profile(ID, ctx, parent, d);
+  void *InsertPos;
+
+  LOC *L = cast_or_null<LOC>(Contexts.FindNodeOrInsertPos(ID, InsertPos));
+
+  if (!L) {
+    L = new LOC(ctx, parent, d);
+    Contexts.InsertNode(L, InsertPos);
+  }
+  return L;
+}
+
+const StackFrameContext*
+LocationContextManager::getStackFrame(AnalysisContext *ctx,
+                                      const LocationContext *parent,
+                                      const Stmt *s, const CFGBlock *blk,
+                                      unsigned idx) {
+  llvm::FoldingSetNodeID ID;
+  StackFrameContext::Profile(ID, ctx, parent, s, blk, idx);
+  void *InsertPos;
+  StackFrameContext *L =
+   cast_or_null<StackFrameContext>(Contexts.FindNodeOrInsertPos(ID, InsertPos));
+  if (!L) {
+    L = new StackFrameContext(ctx, parent, s, blk, idx);
+    Contexts.InsertNode(L, InsertPos);
+  }
+  return L;
+}
+
+const ScopeContext *
+LocationContextManager::getScope(AnalysisContext *ctx,
+                                 const LocationContext *parent,
+                                 const Stmt *s) {
+  return getLocationContext<ScopeContext, Stmt>(ctx, parent, s);
+}
+
+//===----------------------------------------------------------------------===//
+// LocationContext methods.
+//===----------------------------------------------------------------------===//
+
+const StackFrameContext *LocationContext::getCurrentStackFrame() const {
+  const LocationContext *LC = this;
+  while (LC) {
+    if (const StackFrameContext *SFC = dyn_cast<StackFrameContext>(LC))
+      return SFC;
+    LC = LC->getParent();
+  }
+  return NULL;
+}
+
+const StackFrameContext *
+LocationContext::getStackFrameForDeclContext(const DeclContext *DC) const {
+  const LocationContext *LC = this;
+  while (LC) {
+    if (const StackFrameContext *SFC = dyn_cast<StackFrameContext>(LC)) {
+      if (cast<DeclContext>(SFC->getDecl()) == DC)
+        return SFC;
+    }
+    LC = LC->getParent();
+  }
+  return NULL;
+}
+
+bool LocationContext::isParentOf(const LocationContext *LC) const {
+  do {
+    const LocationContext *Parent = LC->getParent();
+    if (Parent == this)
+      return true;
+    else
+      LC = Parent;
+  } while (LC);
+
+  return false;
+}
+
+//===----------------------------------------------------------------------===//
+// Lazily generated map to query the external variables referenced by a Block.
+//===----------------------------------------------------------------------===//
+
+namespace {
+class FindBlockDeclRefExprsVals : public StmtVisitor<FindBlockDeclRefExprsVals>{
+  BumpVector<const VarDecl*> &BEVals;
+  BumpVectorContext &BC;
+  llvm::DenseMap<const VarDecl*, unsigned> Visited;
+  llvm::SmallSet<const DeclContext*, 4> IgnoredContexts;
+public:
+  FindBlockDeclRefExprsVals(BumpVector<const VarDecl*> &bevals,
+                            BumpVectorContext &bc)
+  : BEVals(bevals), BC(bc) {}
+
+  bool IsTrackedDecl(const VarDecl *VD) {
+    const DeclContext *DC = VD->getDeclContext();
+    return IgnoredContexts.count(DC) == 0;
+  }
+
+  void VisitStmt(Stmt *S) {
+    for (Stmt::child_iterator I = S->child_begin(), E = S->child_end();I!=E;++I)
+      if (Stmt *child = *I)
+        Visit(child);
+  }
+
+  void VisitDeclRefExpr(const DeclRefExpr *DR) {
+    // Non-local variables are also directly modified.
+    if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl()))
+      if (!VD->hasLocalStorage()) {
+        unsigned &flag = Visited[VD];
+        if (!flag) {
+          flag = 1;
+          BEVals.push_back(VD, BC);
+        }
+      }
+  }
+
+  void VisitBlockDeclRefExpr(BlockDeclRefExpr *DR) {
+    if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
+      unsigned &flag = Visited[VD];
+      if (!flag) {
+        flag = 1;
+        if (IsTrackedDecl(VD))
+          BEVals.push_back(VD, BC);
+      }
+    }
+  }
+
+  void VisitBlockExpr(BlockExpr *BR) {
+    // Blocks containing blocks can transitively capture more variables.
+    IgnoredContexts.insert(BR->getBlockDecl());
+    Visit(BR->getBlockDecl()->getBody());
+  }
+};
+} // end anonymous namespace
+
+typedef BumpVector<const VarDecl*> DeclVec;
+
+static DeclVec* LazyInitializeReferencedDecls(const BlockDecl *BD,
+                                              void *&Vec,
+                                              llvm::BumpPtrAllocator &A) {
+  if (Vec)
+    return (DeclVec*) Vec;
+
+  BumpVectorContext BC(A);
+  DeclVec *BV = (DeclVec*) A.Allocate<DeclVec>();
+  new (BV) DeclVec(BC, 10);
+
+  // Find the referenced variables.
+  FindBlockDeclRefExprsVals F(*BV, BC);
+  F.Visit(BD->getBody());
+
+  Vec = BV;
+  return BV;
+}
+
+std::pair<AnalysisContext::referenced_decls_iterator,
+          AnalysisContext::referenced_decls_iterator>
+AnalysisContext::getReferencedBlockVars(const BlockDecl *BD) {
+  if (!ReferencedBlockVars)
+    ReferencedBlockVars = new llvm::DenseMap<const BlockDecl*,void*>();
+
+  DeclVec *V = LazyInitializeReferencedDecls(BD, (*ReferencedBlockVars)[BD], A);
+  return std::make_pair(V->begin(), V->end());
+}
+
+//===----------------------------------------------------------------------===//
+// Cleanup.
+//===----------------------------------------------------------------------===//
+
+AnalysisContext::~AnalysisContext() {
+  delete cfg;
+  delete liveness;
+  delete PM;
+  delete ReferencedBlockVars;
+}
+
+AnalysisContextManager::~AnalysisContextManager() {
+  for (ContextMap::iterator I = Contexts.begin(), E = Contexts.end(); I!=E; ++I)
+    delete I->second;
+}
+
+LocationContext::~LocationContext() {}
+
+LocationContextManager::~LocationContextManager() {
+  clear();
+}
+
+void LocationContextManager::clear() {
+  for (llvm::FoldingSet<LocationContext>::iterator I = Contexts.begin(),
+       E = Contexts.end(); I != E; ) {
+    LocationContext *LC = &*I;
+    ++I;
+    delete LC;
+  }
+
+  Contexts.clear();
+}
+
diff --git a/lib/Analysis/Android.mk b/lib/Analysis/Android.mk
new file mode 100644
index 0000000..c43aa61
--- /dev/null
+++ b/lib/Analysis/Android.mk
@@ -0,0 +1,27 @@
+LOCAL_PATH:= $(call my-dir)
+
+# For the host only
+# =====================================================
+include $(CLEAR_VARS)
+include $(CLEAR_TBLGEN_VARS)
+
+TBLGEN_TABLES :=    \
+    DiagnosticCommonKinds.inc	\
+	DiagnosticAnalysisKinds.inc
+
+clang_analysis_SRC_FILES :=	\
+	AnalysisContext.cpp	\
+	CFG.cpp	\
+	LiveVariables.cpp	\
+	PrintfFormatString.cpp	\
+	ReachableCode.cpp	\
+	UninitializedValues.cpp
+	
+
+LOCAL_SRC_FILES := $(clang_analysis_SRC_FILES)
+
+LOCAL_MODULE:= libclangAnalysis
+
+include $(CLANG_HOST_BUILD_MK)
+include $(CLANG_TBLGEN_RULES_MK)
+include $(BUILD_HOST_STATIC_LIBRARY)
diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp
new file mode 100644
index 0000000..e447657
--- /dev/null
+++ b/lib/Analysis/CFG.cpp
@@ -0,0 +1,2368 @@
+//===--- CFG.cpp - Classes for representing and building CFGs----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the CFG and CFGBuilder classes for representing and
+//  building Control-Flow Graphs (CFGs) from ASTs.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Analysis/Support/SaveAndRestore.h"
+#include "clang/Analysis/CFG.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/StmtVisitor.h"
+#include "clang/AST/PrettyPrinter.h"
+#include "llvm/Support/GraphWriter.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Format.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/OwningPtr.h"
+
+using namespace clang;
+
+namespace {
+
+static SourceLocation GetEndLoc(Decl* D) {
+  if (VarDecl* VD = dyn_cast<VarDecl>(D))
+    if (Expr* Ex = VD->getInit())
+      return Ex->getSourceRange().getEnd();
+
+  return D->getLocation();
+}
+  
+class AddStmtChoice {
+public:
+  enum Kind { NotAlwaysAdd = 0,
+              AlwaysAdd = 1,
+              AsLValueNotAlwaysAdd = 2,
+              AlwaysAddAsLValue = 3 };
+
+  AddStmtChoice(Kind kind) : k(kind) {}
+
+  bool alwaysAdd() const { return (unsigned)k & 0x1; }
+  bool asLValue() const { return k >= AsLValueNotAlwaysAdd; }
+
+private:
+  Kind k;
+};
+
+/// CFGBuilder - This class implements CFG construction from an AST.
+///   The builder is stateful: an instance of the builder should be used to only
+///   construct a single CFG.
+///
+///   Example usage:
+///
+///     CFGBuilder builder;
+///     CFG* cfg = builder.BuildAST(stmt1);
+///
+///  CFG construction is done via a recursive walk of an AST.  We actually parse
+///  the AST in reverse order so that the successor of a basic block is
+///  constructed prior to its predecessor.  This allows us to nicely capture
+///  implicit fall-throughs without extra basic blocks.
+///
+class CFGBuilder {
+  ASTContext *Context;
+  llvm::OwningPtr<CFG> cfg;
+
+  CFGBlock* Block;
+  CFGBlock* Succ;
+  CFGBlock* ContinueTargetBlock;
+  CFGBlock* BreakTargetBlock;
+  CFGBlock* SwitchTerminatedBlock;
+  CFGBlock* DefaultCaseBlock;
+  CFGBlock* TryTerminatedBlock;
+
+  // LabelMap records the mapping from Label expressions to their blocks.
+  typedef llvm::DenseMap<LabelStmt*,CFGBlock*> LabelMapTy;
+  LabelMapTy LabelMap;
+
+  // A list of blocks that end with a "goto" that must be backpatched to their
+  // resolved targets upon completion of CFG construction.
+  typedef std::vector<CFGBlock*> BackpatchBlocksTy;
+  BackpatchBlocksTy BackpatchBlocks;
+
+  // A list of labels whose address has been taken (for indirect gotos).
+  typedef llvm::SmallPtrSet<LabelStmt*,5> LabelSetTy;
+  LabelSetTy AddressTakenLabels;
+
+public:
+  explicit CFGBuilder() : cfg(new CFG()), // crew a new CFG
+                          Block(NULL), Succ(NULL),
+                          ContinueTargetBlock(NULL), BreakTargetBlock(NULL),
+                          SwitchTerminatedBlock(NULL), DefaultCaseBlock(NULL),
+                          TryTerminatedBlock(NULL) {}
+
+  // buildCFG - Used by external clients to construct the CFG.
+  CFG* buildCFG(const Decl *D, Stmt *Statement, ASTContext *C, bool AddEHEdges,
+                bool AddScopes);
+
+private:
+  // Visitors to walk an AST and construct the CFG.
+  CFGBlock *VisitAddrLabelExpr(AddrLabelExpr *A, AddStmtChoice asc);
+  CFGBlock *VisitBinaryOperator(BinaryOperator *B, AddStmtChoice asc);
+  CFGBlock *VisitBlockExpr(BlockExpr* E, AddStmtChoice asc);
+  CFGBlock *VisitBreakStmt(BreakStmt *B);
+  CFGBlock *VisitCXXCatchStmt(CXXCatchStmt *S);
+  CFGBlock *VisitCXXThrowExpr(CXXThrowExpr *T);
+  CFGBlock *VisitCXXTryStmt(CXXTryStmt *S);
+  CFGBlock *VisitCXXMemberCallExpr(CXXMemberCallExpr *C, AddStmtChoice asc);
+  CFGBlock *VisitCallExpr(CallExpr *C, AddStmtChoice asc);
+  CFGBlock *VisitCaseStmt(CaseStmt *C);
+  CFGBlock *VisitChooseExpr(ChooseExpr *C, AddStmtChoice asc);
+  CFGBlock *VisitCompoundStmt(CompoundStmt *C);
+  CFGBlock *VisitConditionalOperator(ConditionalOperator *C, AddStmtChoice asc);
+  CFGBlock *VisitContinueStmt(ContinueStmt *C);
+  CFGBlock *VisitDeclStmt(DeclStmt *DS);
+  CFGBlock *VisitDeclSubExpr(Decl* D);
+  CFGBlock *VisitDefaultStmt(DefaultStmt *D);
+  CFGBlock *VisitDoStmt(DoStmt *D);
+  CFGBlock *VisitForStmt(ForStmt *F);
+  CFGBlock *VisitGotoStmt(GotoStmt* G);
+  CFGBlock *VisitIfStmt(IfStmt *I);
+  CFGBlock *VisitIndirectGotoStmt(IndirectGotoStmt *I);
+  CFGBlock *VisitLabelStmt(LabelStmt *L);
+  CFGBlock *VisitMemberExpr(MemberExpr *M, AddStmtChoice asc);
+  CFGBlock *VisitObjCAtCatchStmt(ObjCAtCatchStmt *S);
+  CFGBlock *VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *S);
+  CFGBlock *VisitObjCAtThrowStmt(ObjCAtThrowStmt *S);
+  CFGBlock *VisitObjCAtTryStmt(ObjCAtTryStmt *S);
+  CFGBlock *VisitObjCForCollectionStmt(ObjCForCollectionStmt *S);
+  CFGBlock *VisitReturnStmt(ReturnStmt* R);
+  CFGBlock *VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E, AddStmtChoice asc);
+  CFGBlock *VisitStmtExpr(StmtExpr *S, AddStmtChoice asc);
+  CFGBlock *VisitSwitchStmt(SwitchStmt *S);
+  CFGBlock *VisitWhileStmt(WhileStmt *W);
+
+  CFGBlock *Visit(Stmt *S, AddStmtChoice asc = AddStmtChoice::NotAlwaysAdd);
+  CFGBlock *VisitStmt(Stmt *S, AddStmtChoice asc);
+  CFGBlock *VisitChildren(Stmt* S);
+
+  // NYS == Not Yet Supported
+  CFGBlock* NYS() {
+    badCFG = true;
+    return Block;
+  }
+
+  CFGBlock *StartScope(Stmt *S, CFGBlock *B) {
+    if (!AddScopes)
+      return B;
+
+    if (B == 0)
+      B = createBlock();
+    B->StartScope(S, cfg->getBumpVectorContext());
+    return B;
+  }
+
+  void EndScope(Stmt *S) {
+    if (!AddScopes)
+      return;
+
+    if (Block == 0)
+      Block = createBlock();
+    Block->EndScope(S, cfg->getBumpVectorContext());
+  }
+
+  void autoCreateBlock() { if (!Block) Block = createBlock(); }
+  CFGBlock *createBlock(bool add_successor = true);
+  bool FinishBlock(CFGBlock* B);
+  CFGBlock *addStmt(Stmt *S, AddStmtChoice asc = AddStmtChoice::AlwaysAdd) {
+    return Visit(S, asc);
+  }
+  
+  void AppendStmt(CFGBlock *B, Stmt *S,
+                  AddStmtChoice asc = AddStmtChoice::AlwaysAdd) {
+    B->appendStmt(S, cfg->getBumpVectorContext(), asc.asLValue());
+  }
+  
+  void AddSuccessor(CFGBlock *B, CFGBlock *S) {
+    B->addSuccessor(S, cfg->getBumpVectorContext());
+  }
+
+  /// TryResult - a class representing a variant over the values
+  ///  'true', 'false', or 'unknown'.  This is returned by TryEvaluateBool,
+  ///  and is used by the CFGBuilder to decide if a branch condition
+  ///  can be decided up front during CFG construction.
+  class TryResult {
+    int X;
+  public:
+    TryResult(bool b) : X(b ? 1 : 0) {}
+    TryResult() : X(-1) {}
+
+    bool isTrue() const { return X == 1; }
+    bool isFalse() const { return X == 0; }
+    bool isKnown() const { return X >= 0; }
+    void negate() {
+      assert(isKnown());
+      X ^= 0x1;
+    }
+  };
+
+  /// TryEvaluateBool - Try and evaluate the Stmt and return 0 or 1
+  /// if we can evaluate to a known value, otherwise return -1.
+  TryResult TryEvaluateBool(Expr *S) {
+    Expr::EvalResult Result;
+    if (!S->isTypeDependent() && !S->isValueDependent() &&
+        S->Evaluate(Result, *Context) && Result.Val.isInt())
+      return Result.Val.getInt().getBoolValue();
+
+    return TryResult();
+  }
+
+  bool badCFG;
+
+  // True iff EH edges on CallExprs should be added to the CFG.
+  bool AddEHEdges;
+
+  // True iff scope start and scope end notes should be added to the CFG.
+  bool AddScopes;
+};
+
+// FIXME: Add support for dependent-sized array types in C++?
+// Does it even make sense to build a CFG for an uninstantiated template?
+static VariableArrayType* FindVA(Type* t) {
+  while (ArrayType* vt = dyn_cast<ArrayType>(t)) {
+    if (VariableArrayType* vat = dyn_cast<VariableArrayType>(vt))
+      if (vat->getSizeExpr())
+        return vat;
+
+    t = vt->getElementType().getTypePtr();
+  }
+
+  return 0;
+}
+
+/// BuildCFG - Constructs a CFG from an AST (a Stmt*).  The AST can represent an
+///  arbitrary statement.  Examples include a single expression or a function
+///  body (compound statement).  The ownership of the returned CFG is
+///  transferred to the caller.  If CFG construction fails, this method returns
+///  NULL.
+CFG* CFGBuilder::buildCFG(const Decl *D, Stmt* Statement, ASTContext* C,
+                          bool addehedges, bool AddScopes) {
+  AddEHEdges = addehedges;
+  Context = C;
+  assert(cfg.get());
+  if (!Statement)
+    return NULL;
+
+  this->AddScopes = AddScopes;
+  badCFG = false;
+
+  // Create an empty block that will serve as the exit block for the CFG.  Since
+  // this is the first block added to the CFG, it will be implicitly registered
+  // as the exit block.
+  Succ = createBlock();
+  assert(Succ == &cfg->getExit());
+  Block = NULL;  // the EXIT block is empty.  Create all other blocks lazily.
+
+  // Visit the statements and create the CFG.
+  CFGBlock* B = addStmt(Statement);
+
+  if (const CXXConstructorDecl *CD = dyn_cast_or_null<CXXConstructorDecl>(D)) {
+    // FIXME: Add code for base initializers and member initializers.
+    (void)CD;
+  }
+  if (!B)
+    B = Succ;
+
+  if (B) {
+    // Finalize the last constructed block.  This usually involves reversing the
+    // order of the statements in the block.
+    if (Block) FinishBlock(B);
+
+    // Backpatch the gotos whose label -> block mappings we didn't know when we
+    // encountered them.
+    for (BackpatchBlocksTy::iterator I = BackpatchBlocks.begin(),
+         E = BackpatchBlocks.end(); I != E; ++I ) {
+
+      CFGBlock* B = *I;
+      GotoStmt* G = cast<GotoStmt>(B->getTerminator());
+      LabelMapTy::iterator LI = LabelMap.find(G->getLabel());
+
+      // If there is no target for the goto, then we are looking at an
+      // incomplete AST.  Handle this by not registering a successor.
+      if (LI == LabelMap.end()) continue;
+
+      AddSuccessor(B, LI->second);
+    }
+
+    // Add successors to the Indirect Goto Dispatch block (if we have one).
+    if (CFGBlock* B = cfg->getIndirectGotoBlock())
+      for (LabelSetTy::iterator I = AddressTakenLabels.begin(),
+           E = AddressTakenLabels.end(); I != E; ++I ) {
+
+        // Lookup the target block.
+        LabelMapTy::iterator LI = LabelMap.find(*I);
+
+        // If there is no target block that contains label, then we are looking
+        // at an incomplete AST.  Handle this by not registering a successor.
+        if (LI == LabelMap.end()) continue;
+
+        AddSuccessor(B, LI->second);
+      }
+
+    Succ = B;
+  }
+
+  // Create an empty entry block that has no predecessors.
+  cfg->setEntry(createBlock());
+
+  return badCFG ? NULL : cfg.take();
+}
+
+/// createBlock - Used to lazily create blocks that are connected
+///  to the current (global) succcessor.
+CFGBlock* CFGBuilder::createBlock(bool add_successor) {
+  CFGBlock* B = cfg->createBlock();
+  if (add_successor && Succ)
+    AddSuccessor(B, Succ);
+  return B;
+}
+
+/// FinishBlock - "Finalize" the block by checking if we have a bad CFG.
+bool CFGBuilder::FinishBlock(CFGBlock* B) {
+  if (badCFG)
+    return false;
+
+  assert(B);
+  return true;
+}
+
+/// Visit - Walk the subtree of a statement and add extra
+///   blocks for ternary operators, &&, and ||.  We also process "," and
+///   DeclStmts (which may contain nested control-flow).
+CFGBlock* CFGBuilder::Visit(Stmt * S, AddStmtChoice asc) {
+tryAgain:
+  switch (S->getStmtClass()) {
+    default:
+      return VisitStmt(S, asc);
+
+    case Stmt::AddrLabelExprClass:
+      return VisitAddrLabelExpr(cast<AddrLabelExpr>(S), asc);
+
+    case Stmt::BinaryOperatorClass:
+      return VisitBinaryOperator(cast<BinaryOperator>(S), asc);
+
+    case Stmt::BlockExprClass:
+      return VisitBlockExpr(cast<BlockExpr>(S), asc);
+
+    case Stmt::BreakStmtClass:
+      return VisitBreakStmt(cast<BreakStmt>(S));
+
+    case Stmt::CallExprClass:
+      return VisitCallExpr(cast<CallExpr>(S), asc);
+
+    case Stmt::CaseStmtClass:
+      return VisitCaseStmt(cast<CaseStmt>(S));
+
+    case Stmt::ChooseExprClass:
+      return VisitChooseExpr(cast<ChooseExpr>(S), asc);
+
+    case Stmt::CompoundStmtClass:
+      return VisitCompoundStmt(cast<CompoundStmt>(S));
+
+    case Stmt::ConditionalOperatorClass:
+      return VisitConditionalOperator(cast<ConditionalOperator>(S), asc);
+
+    case Stmt::ContinueStmtClass:
+      return VisitContinueStmt(cast<ContinueStmt>(S));
+
+    case Stmt::CXXCatchStmtClass:
+      return VisitCXXCatchStmt(cast<CXXCatchStmt>(S));
+
+    case Stmt::CXXMemberCallExprClass:
+      return VisitCXXMemberCallExpr(cast<CXXMemberCallExpr>(S), asc);
+
+    case Stmt::CXXThrowExprClass:
+      return VisitCXXThrowExpr(cast<CXXThrowExpr>(S));
+      
+    case Stmt::CXXTryStmtClass:
+      return VisitCXXTryStmt(cast<CXXTryStmt>(S));
+      
+    case Stmt::DeclStmtClass:
+      return VisitDeclStmt(cast<DeclStmt>(S));
+
+    case Stmt::DefaultStmtClass:
+      return VisitDefaultStmt(cast<DefaultStmt>(S));
+
+    case Stmt::DoStmtClass:
+      return VisitDoStmt(cast<DoStmt>(S));
+
+    case Stmt::ForStmtClass:
+      return VisitForStmt(cast<ForStmt>(S));
+
+    case Stmt::GotoStmtClass:
+      return VisitGotoStmt(cast<GotoStmt>(S));
+
+    case Stmt::IfStmtClass:
+      return VisitIfStmt(cast<IfStmt>(S));
+
+    case Stmt::IndirectGotoStmtClass:
+      return VisitIndirectGotoStmt(cast<IndirectGotoStmt>(S));
+
+    case Stmt::LabelStmtClass:
+      return VisitLabelStmt(cast<LabelStmt>(S));
+
+    case Stmt::MemberExprClass:
+      return VisitMemberExpr(cast<MemberExpr>(S), asc);
+
+    case Stmt::ObjCAtCatchStmtClass:
+      return VisitObjCAtCatchStmt(cast<ObjCAtCatchStmt>(S));
+
+    case Stmt::ObjCAtSynchronizedStmtClass:
+      return VisitObjCAtSynchronizedStmt(cast<ObjCAtSynchronizedStmt>(S));
+
+    case Stmt::ObjCAtThrowStmtClass:
+      return VisitObjCAtThrowStmt(cast<ObjCAtThrowStmt>(S));
+
+    case Stmt::ObjCAtTryStmtClass:
+      return VisitObjCAtTryStmt(cast<ObjCAtTryStmt>(S));
+
+    case Stmt::ObjCForCollectionStmtClass:
+      return VisitObjCForCollectionStmt(cast<ObjCForCollectionStmt>(S));
+
+    case Stmt::ParenExprClass:
+      S = cast<ParenExpr>(S)->getSubExpr();
+      goto tryAgain;
+
+    case Stmt::NullStmtClass:
+      return Block;
+
+    case Stmt::ReturnStmtClass:
+      return VisitReturnStmt(cast<ReturnStmt>(S));
+
+    case Stmt::SizeOfAlignOfExprClass:
+      return VisitSizeOfAlignOfExpr(cast<SizeOfAlignOfExpr>(S), asc);
+
+    case Stmt::StmtExprClass:
+      return VisitStmtExpr(cast<StmtExpr>(S), asc);
+
+    case Stmt::SwitchStmtClass:
+      return VisitSwitchStmt(cast<SwitchStmt>(S));
+
+    case Stmt::WhileStmtClass:
+      return VisitWhileStmt(cast<WhileStmt>(S));
+  }
+}
+
+CFGBlock *CFGBuilder::VisitStmt(Stmt *S, AddStmtChoice asc) {
+  if (asc.alwaysAdd()) {
+    autoCreateBlock();
+    AppendStmt(Block, S, asc);
+  }
+
+  return VisitChildren(S);
+}
+
+/// VisitChildren - Visit the children of a Stmt.
+CFGBlock *CFGBuilder::VisitChildren(Stmt* Terminator) {
+  CFGBlock *B = Block;
+  for (Stmt::child_iterator I = Terminator->child_begin(),
+         E = Terminator->child_end(); I != E; ++I) {
+    if (*I) B = Visit(*I);
+  }
+  return B;
+}
+
+CFGBlock *CFGBuilder::VisitAddrLabelExpr(AddrLabelExpr *A,
+                                         AddStmtChoice asc) {
+  AddressTakenLabels.insert(A->getLabel());
+
+  if (asc.alwaysAdd()) {
+    autoCreateBlock();
+    AppendStmt(Block, A, asc);
+  }
+
+  return Block;
+}
+
+CFGBlock *CFGBuilder::VisitBinaryOperator(BinaryOperator *B,
+                                          AddStmtChoice asc) {
+  if (B->isLogicalOp()) { // && or ||
+    CFGBlock* ConfluenceBlock = Block ? Block : createBlock();
+    AppendStmt(ConfluenceBlock, B, asc);
+
+    if (!FinishBlock(ConfluenceBlock))
+      return 0;
+
+    // create the block evaluating the LHS
+    CFGBlock* LHSBlock = createBlock(false);
+    LHSBlock->setTerminator(B);
+
+    // create the block evaluating the RHS
+    Succ = ConfluenceBlock;
+    Block = NULL;
+    CFGBlock* RHSBlock = addStmt(B->getRHS());
+    if (!FinishBlock(RHSBlock))
+      return 0;
+
+    // See if this is a known constant.
+    TryResult KnownVal = TryEvaluateBool(B->getLHS());
+    if (KnownVal.isKnown() && (B->getOpcode() == BinaryOperator::LOr))
+      KnownVal.negate();
+
+    // Now link the LHSBlock with RHSBlock.
+    if (B->getOpcode() == BinaryOperator::LOr) {
+      AddSuccessor(LHSBlock, KnownVal.isTrue() ? NULL : ConfluenceBlock);
+      AddSuccessor(LHSBlock, KnownVal.isFalse() ? NULL : RHSBlock);
+    } else {
+      assert(B->getOpcode() == BinaryOperator::LAnd);
+      AddSuccessor(LHSBlock, KnownVal.isFalse() ? NULL : RHSBlock);
+      AddSuccessor(LHSBlock, KnownVal.isTrue() ? NULL : ConfluenceBlock);
+    }
+
+    // Generate the blocks for evaluating the LHS.
+    Block = LHSBlock;
+    return addStmt(B->getLHS());
+  }
+  else if (B->getOpcode() == BinaryOperator::Comma) { // ,
+    autoCreateBlock();
+    AppendStmt(Block, B, asc);
+    addStmt(B->getRHS());
+    return addStmt(B->getLHS());
+  }
+
+  return VisitStmt(B, asc);
+}
+
+CFGBlock *CFGBuilder::VisitBlockExpr(BlockExpr *E, AddStmtChoice asc) {
+  if (asc.alwaysAdd()) {
+    autoCreateBlock();
+    AppendStmt(Block, E, asc);
+  }
+  return Block;
+}
+
+CFGBlock *CFGBuilder::VisitBreakStmt(BreakStmt *B) {
+  // "break" is a control-flow statement.  Thus we stop processing the current
+  // block.
+  if (Block && !FinishBlock(Block))
+      return 0;
+
+  // Now create a new block that ends with the break statement.
+  Block = createBlock(false);
+  Block->setTerminator(B);
+
+  // If there is no target for the break, then we are looking at an incomplete
+  // AST.  This means that the CFG cannot be constructed.
+  if (BreakTargetBlock)
+    AddSuccessor(Block, BreakTargetBlock);
+  else
+    badCFG = true;
+
+
+  return Block;
+}
+
+static bool CanThrow(Expr *E) {
+  QualType Ty = E->getType();
+  if (Ty->isFunctionPointerType())
+    Ty = Ty->getAs<PointerType>()->getPointeeType();
+  else if (Ty->isBlockPointerType())
+    Ty = Ty->getAs<BlockPointerType>()->getPointeeType();
+    
+  const FunctionType *FT = Ty->getAs<FunctionType>();
+  if (FT) {
+    if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FT))
+      if (Proto->hasEmptyExceptionSpec())
+        return false;
+  }
+  return true;
+}
+
+CFGBlock *CFGBuilder::VisitCallExpr(CallExpr *C, AddStmtChoice asc) {
+  // If this is a call to a no-return function, this stops the block here.
+  bool NoReturn = false;
+  if (getFunctionExtInfo(*C->getCallee()->getType()).getNoReturn()) {
+    NoReturn = true;
+  }
+
+  bool AddEHEdge = false;
+
+  // Languages without exceptions are assumed to not throw.
+  if (Context->getLangOptions().Exceptions) {
+    if (AddEHEdges)
+      AddEHEdge = true;
+  }
+
+  if (FunctionDecl *FD = C->getDirectCallee()) {
+    if (FD->hasAttr<NoReturnAttr>())
+      NoReturn = true;
+    if (FD->hasAttr<NoThrowAttr>())
+      AddEHEdge = false;
+  }
+
+  if (!CanThrow(C->getCallee()))
+    AddEHEdge = false;
+
+  if (!NoReturn && !AddEHEdge)
+    return VisitStmt(C, AddStmtChoice::AlwaysAdd);
+
+  if (Block) {
+    Succ = Block;
+    if (!FinishBlock(Block))
+      return 0;
+  }
+
+  Block = createBlock(!NoReturn);
+  AppendStmt(Block, C, asc);
+
+  if (NoReturn) {
+    // Wire this to the exit block directly.
+    AddSuccessor(Block, &cfg->getExit());
+  }
+  if (AddEHEdge) {
+    // Add exceptional edges.
+    if (TryTerminatedBlock)
+      AddSuccessor(Block, TryTerminatedBlock);
+    else
+      AddSuccessor(Block, &cfg->getExit());
+  }
+
+  return VisitChildren(C);
+}
+
+CFGBlock *CFGBuilder::VisitChooseExpr(ChooseExpr *C,
+                                      AddStmtChoice asc) {
+  CFGBlock* ConfluenceBlock = Block ? Block : createBlock();
+  AppendStmt(ConfluenceBlock, C, asc);
+  if (!FinishBlock(ConfluenceBlock))
+    return 0;
+
+  asc = asc.asLValue() ? AddStmtChoice::AlwaysAddAsLValue
+                       : AddStmtChoice::AlwaysAdd;
+
+  Succ = ConfluenceBlock;
+  Block = NULL;
+  CFGBlock* LHSBlock = addStmt(C->getLHS(), asc);
+  if (!FinishBlock(LHSBlock))
+    return 0;
+
+  Succ = ConfluenceBlock;
+  Block = NULL;
+  CFGBlock* RHSBlock = addStmt(C->getRHS(), asc);
+  if (!FinishBlock(RHSBlock))
+    return 0;
+
+  Block = createBlock(false);
+  // See if this is a known constant.
+  const TryResult& KnownVal = TryEvaluateBool(C->getCond());
+  AddSuccessor(Block, KnownVal.isFalse() ? NULL : LHSBlock);
+  AddSuccessor(Block, KnownVal.isTrue() ? NULL : RHSBlock);
+  Block->setTerminator(C);
+  return addStmt(C->getCond());
+}
+
+
+CFGBlock* CFGBuilder::VisitCompoundStmt(CompoundStmt* C) {
+  EndScope(C);
+
+  CFGBlock* LastBlock = Block;
+
+  for (CompoundStmt::reverse_body_iterator I=C->body_rbegin(), E=C->body_rend();
+       I != E; ++I ) {
+    LastBlock = addStmt(*I);
+
+    if (badCFG)
+      return NULL;
+  }
+
+  LastBlock = StartScope(C, LastBlock);
+
+  return LastBlock;
+}
+
+CFGBlock *CFGBuilder::VisitConditionalOperator(ConditionalOperator *C,
+                                               AddStmtChoice asc) {
+  // Create the confluence block that will "merge" the results of the ternary
+  // expression.
+  CFGBlock* ConfluenceBlock = Block ? Block : createBlock();
+  AppendStmt(ConfluenceBlock, C, asc);
+  if (!FinishBlock(ConfluenceBlock))
+    return 0;
+
+  asc = asc.asLValue() ? AddStmtChoice::AlwaysAddAsLValue
+                       : AddStmtChoice::AlwaysAdd;
+
+  // Create a block for the LHS expression if there is an LHS expression.  A
+  // GCC extension allows LHS to be NULL, causing the condition to be the
+  // value that is returned instead.
+  //  e.g: x ?: y is shorthand for: x ? x : y;
+  Succ = ConfluenceBlock;
+  Block = NULL;
+  CFGBlock* LHSBlock = NULL;
+  if (C->getLHS()) {
+    LHSBlock = addStmt(C->getLHS(), asc);
+    if (!FinishBlock(LHSBlock))
+      return 0;
+    Block = NULL;
+  }
+
+  // Create the block for the RHS expression.
+  Succ = ConfluenceBlock;
+  CFGBlock* RHSBlock = addStmt(C->getRHS(), asc);
+  if (!FinishBlock(RHSBlock))
+    return 0;
+
+  // Create the block that will contain the condition.
+  Block = createBlock(false);
+
+  // See if this is a known constant.
+  const TryResult& KnownVal = TryEvaluateBool(C->getCond());
+  if (LHSBlock) {
+    AddSuccessor(Block, KnownVal.isFalse() ? NULL : LHSBlock);
+  } else {
+    if (KnownVal.isFalse()) {
+      // If we know the condition is false, add NULL as the successor for
+      // the block containing the condition.  In this case, the confluence
+      // block will have just one predecessor.
+      AddSuccessor(Block, 0);
+      assert(ConfluenceBlock->pred_size() == 1);
+    } else {
+      // If we have no LHS expression, add the ConfluenceBlock as a direct
+      // successor for the block containing the condition.  Moreover, we need to
+      // reverse the order of the predecessors in the ConfluenceBlock because
+      // the RHSBlock will have been added to the succcessors already, and we
+      // want the first predecessor to the the block containing the expression
+      // for the case when the ternary expression evaluates to true.
+      AddSuccessor(Block, ConfluenceBlock);
+      assert(ConfluenceBlock->pred_size() == 2);
+      std::reverse(ConfluenceBlock->pred_begin(),
+                   ConfluenceBlock->pred_end());
+    }
+  }
+
+  AddSuccessor(Block, KnownVal.isTrue() ? NULL : RHSBlock);
+  Block->setTerminator(C);
+  return addStmt(C->getCond());
+}
+
+CFGBlock *CFGBuilder::VisitDeclStmt(DeclStmt *DS) {
+  autoCreateBlock();
+
+  if (DS->isSingleDecl()) {
+    AppendStmt(Block, DS);
+    return VisitDeclSubExpr(DS->getSingleDecl());
+  }
+
+  CFGBlock *B = 0;
+
+  // FIXME: Add a reverse iterator for DeclStmt to avoid this extra copy.
+  typedef llvm::SmallVector<Decl*,10> BufTy;
+  BufTy Buf(DS->decl_begin(), DS->decl_end());
+
+  for (BufTy::reverse_iterator I = Buf.rbegin(), E = Buf.rend(); I != E; ++I) {
+    // Get the alignment of the new DeclStmt, padding out to >=8 bytes.
+    unsigned A = llvm::AlignOf<DeclStmt>::Alignment < 8
+               ? 8 : llvm::AlignOf<DeclStmt>::Alignment;
+
+    // Allocate the DeclStmt using the BumpPtrAllocator.  It will get
+    // automatically freed with the CFG.
+    DeclGroupRef DG(*I);
+    Decl *D = *I;
+    void *Mem = cfg->getAllocator().Allocate(sizeof(DeclStmt), A);
+    DeclStmt *DSNew = new (Mem) DeclStmt(DG, D->getLocation(), GetEndLoc(D));
+
+    // Append the fake DeclStmt to block.
+    AppendStmt(Block, DSNew);
+    B = VisitDeclSubExpr(D);
+  }
+
+  return B;
+}
+
+/// VisitDeclSubExpr - Utility method to add block-level expressions for
+///  initializers in Decls.
+CFGBlock *CFGBuilder::VisitDeclSubExpr(Decl* D) {
+  assert(Block);
+
+  VarDecl *VD = dyn_cast<VarDecl>(D);
+
+  if (!VD)
+    return Block;
+
+  Expr *Init = VD->getInit();
+
+  if (Init) {
+    AddStmtChoice::Kind k =
+      VD->getType()->isReferenceType() ? AddStmtChoice::AsLValueNotAlwaysAdd
+                                       : AddStmtChoice::NotAlwaysAdd;
+    Visit(Init, AddStmtChoice(k));
+  }
+
+  // If the type of VD is a VLA, then we must process its size expressions.
+  for (VariableArrayType* VA = FindVA(VD->getType().getTypePtr()); VA != 0;
+       VA = FindVA(VA->getElementType().getTypePtr()))
+    Block = addStmt(VA->getSizeExpr());
+
+  return Block;
+}
+
+CFGBlock* CFGBuilder::VisitIfStmt(IfStmt* I) {
+  // We may see an if statement in the middle of a basic block, or it may be the
+  // first statement we are processing.  In either case, we create a new basic
+  // block.  First, we create the blocks for the then...else statements, and
+  // then we create the block containing the if statement.  If we were in the
+  // middle of a block, we stop processing that block.  That block is then the
+  // implicit successor for the "then" and "else" clauses.
+
+  // The block we were proccessing is now finished.  Make it the successor
+  // block.
+  if (Block) {
+    Succ = Block;
+    if (!FinishBlock(Block))
+      return 0;
+  }
+
+  // Process the false branch.
+  CFGBlock* ElseBlock = Succ;
+
+  if (Stmt* Else = I->getElse()) {
+    SaveAndRestore<CFGBlock*> sv(Succ);
+
+    // NULL out Block so that the recursive call to Visit will
+    // create a new basic block.
+    Block = NULL;
+    ElseBlock = addStmt(Else);
+
+    if (!ElseBlock) // Can occur when the Else body has all NullStmts.
+      ElseBlock = sv.get();
+    else if (Block) {
+      if (!FinishBlock(ElseBlock))
+        return 0;
+    }
+  }
+
+  // Process the true branch.
+  CFGBlock* ThenBlock;
+  {
+    Stmt* Then = I->getThen();
+    assert(Then);
+    SaveAndRestore<CFGBlock*> sv(Succ);
+    Block = NULL;
+    ThenBlock = addStmt(Then);
+
+    if (!ThenBlock) {
+      // We can reach here if the "then" body has all NullStmts.
+      // Create an empty block so we can distinguish between true and false
+      // branches in path-sensitive analyses.
+      ThenBlock = createBlock(false);
+      AddSuccessor(ThenBlock, sv.get());
+    } else if (Block) {
+      if (!FinishBlock(ThenBlock))
+        return 0;
+    }
+  }
+
+  // Now create a new block containing the if statement.
+  Block = createBlock(false);
+
+  // Set the terminator of the new block to the If statement.
+  Block->setTerminator(I);
+
+  // See if this is a known constant.
+  const TryResult &KnownVal = TryEvaluateBool(I->getCond());
+
+  // Now add the successors.
+  AddSuccessor(Block, KnownVal.isFalse() ? NULL : ThenBlock);
+  AddSuccessor(Block, KnownVal.isTrue()? NULL : ElseBlock);
+
+  // Add the condition as the last statement in the new block.  This may create
+  // new blocks as the condition may contain control-flow.  Any newly created
+  // blocks will be pointed to be "Block".
+  Block = addStmt(I->getCond());
+  
+  // Finally, if the IfStmt contains a condition variable, add both the IfStmt
+  // and the condition variable initialization to the CFG.
+  if (VarDecl *VD = I->getConditionVariable()) {
+    if (Expr *Init = VD->getInit()) {
+      autoCreateBlock();
+      AppendStmt(Block, I, AddStmtChoice::AlwaysAdd);
+      addStmt(Init);
+    }
+  }
+  
+  return Block;
+}
+
+
+CFGBlock* CFGBuilder::VisitReturnStmt(ReturnStmt* R) {
+  // If we were in the middle of a block we stop processing that block.
+  //
+  // NOTE: If a "return" appears in the middle of a block, this means that the
+  //       code afterwards is DEAD (unreachable).  We still keep a basic block
+  //       for that code; a simple "mark-and-sweep" from the entry block will be
+  //       able to report such dead blocks.
+  if (Block)
+    FinishBlock(Block);
+
+  // Create the new block.
+  Block = createBlock(false);
+
+  // The Exit block is the only successor.
+  AddSuccessor(Block, &cfg->getExit());
+
+  // Add the return statement to the block.  This may create new blocks if R
+  // contains control-flow (short-circuit operations).
+  return VisitStmt(R, AddStmtChoice::AlwaysAdd);
+}
+
+CFGBlock* CFGBuilder::VisitLabelStmt(LabelStmt* L) {
+  // Get the block of the labeled statement.  Add it to our map.
+  addStmt(L->getSubStmt());
+  CFGBlock* LabelBlock = Block;
+
+  if (!LabelBlock)              // This can happen when the body is empty, i.e.
+    LabelBlock = createBlock(); // scopes that only contains NullStmts.
+
+  assert(LabelMap.find(L) == LabelMap.end() && "label already in map");
+  LabelMap[ L ] = LabelBlock;
+
+  // Labels partition blocks, so this is the end of the basic block we were
+  // processing (L is the block's label).  Because this is label (and we have
+  // already processed the substatement) there is no extra control-flow to worry
+  // about.
+  LabelBlock->setLabel(L);
+  if (!FinishBlock(LabelBlock))
+    return 0;
+
+  // We set Block to NULL to allow lazy creation of a new block (if necessary);
+  Block = NULL;
+
+  // This block is now the implicit successor of other blocks.
+  Succ = LabelBlock;
+
+  return LabelBlock;
+}
+
+CFGBlock* CFGBuilder::VisitGotoStmt(GotoStmt* G) {
+  // Goto is a control-flow statement.  Thus we stop processing the current
+  // block and create a new one.
+  if (Block)
+    FinishBlock(Block);
+
+  Block = createBlock(false);
+  Block->setTerminator(G);
+
+  // If we already know the mapping to the label block add the successor now.
+  LabelMapTy::iterator I = LabelMap.find(G->getLabel());
+
+  if (I == LabelMap.end())
+    // We will need to backpatch this block later.
+    BackpatchBlocks.push_back(Block);
+  else
+    AddSuccessor(Block, I->second);
+
+  return Block;
+}
+
+CFGBlock* CFGBuilder::VisitForStmt(ForStmt* F) {
+  CFGBlock* LoopSuccessor = NULL;
+
+  // "for" is a control-flow statement.  Thus we stop processing the current
+  // block.
+  if (Block) {
+    if (!FinishBlock(Block))
+      return 0;
+    LoopSuccessor = Block;
+  } else
+    LoopSuccessor = Succ;
+
+  // Because of short-circuit evaluation, the condition of the loop can span
+  // multiple basic blocks.  Thus we need the "Entry" and "Exit" blocks that
+  // evaluate the condition.
+  CFGBlock* ExitConditionBlock = createBlock(false);
+  CFGBlock* EntryConditionBlock = ExitConditionBlock;
+
+  // Set the terminator for the "exit" condition block.
+  ExitConditionBlock->setTerminator(F);
+
+  // Now add the actual condition to the condition block.  Because the condition
+  // itself may contain control-flow, new blocks may be created.
+  if (Stmt* C = F->getCond()) {
+    Block = ExitConditionBlock;
+    EntryConditionBlock = addStmt(C);
+    assert(Block == EntryConditionBlock);
+
+    // If this block contains a condition variable, add both the condition
+    // variable and initializer to the CFG.
+    if (VarDecl *VD = F->getConditionVariable()) {
+      if (Expr *Init = VD->getInit()) {
+        autoCreateBlock();
+        AppendStmt(Block, F, AddStmtChoice::AlwaysAdd);
+        EntryConditionBlock = addStmt(Init);
+        assert(Block == EntryConditionBlock);
+      }
+    }
+    
+    if (Block) {
+      if (!FinishBlock(EntryConditionBlock))
+        return 0;
+    }
+  }
+
+  // The condition block is the implicit successor for the loop body as well as
+  // any code above the loop.
+  Succ = EntryConditionBlock;
+
+  // See if this is a known constant.
+  TryResult KnownVal(true);
+
+  if (F->getCond())
+    KnownVal = TryEvaluateBool(F->getCond());
+
+  // Now create the loop body.
+  {
+    assert(F->getBody());
+
+    // Save the current values for Block, Succ, and continue and break targets
+    SaveAndRestore<CFGBlock*> save_Block(Block), save_Succ(Succ),
+      save_continue(ContinueTargetBlock),
+      save_break(BreakTargetBlock);
+
+    // Create a new block to contain the (bottom) of the loop body.
+    Block = NULL;
+
+    if (Stmt* I = F->getInc()) {
+      // Generate increment code in its own basic block.  This is the target of
+      // continue statements.
+      Succ = addStmt(I);
+    } else {
+      // No increment code.  Create a special, empty, block that is used as the
+      // target block for "looping back" to the start of the loop.
+      assert(Succ == EntryConditionBlock);
+      Succ = createBlock();
+    }
+
+    // Finish up the increment (or empty) block if it hasn't been already.
+    if (Block) {
+      assert(Block == Succ);
+      if (!FinishBlock(Block))
+        return 0;
+      Block = 0;
+    }
+
+    ContinueTargetBlock = Succ;
+
+    // The starting block for the loop increment is the block that should
+    // represent the 'loop target' for looping back to the start of the loop.
+    ContinueTargetBlock->setLoopTarget(F);
+
+    // All breaks should go to the code following the loop.
+    BreakTargetBlock = LoopSuccessor;
+
+    // Now populate the body block, and in the process create new blocks as we
+    // walk the body of the loop.
+    CFGBlock* BodyBlock = addStmt(F->getBody());
+
+    if (!BodyBlock)
+      BodyBlock = ContinueTargetBlock; // can happen for "for (...;...;...) ;"
+    else if (Block && !FinishBlock(BodyBlock))
+      return 0;
+
+    // This new body block is a successor to our "exit" condition block.
+    AddSuccessor(ExitConditionBlock, KnownVal.isFalse() ? NULL : BodyBlock);
+  }
+
+  // Link up the condition block with the code that follows the loop.  (the
+  // false branch).
+  AddSuccessor(ExitConditionBlock, KnownVal.isTrue() ? NULL : LoopSuccessor);
+
+  // If the loop contains initialization, create a new block for those
+  // statements.  This block can also contain statements that precede the loop.
+  if (Stmt* I = F->getInit()) {
+    Block = createBlock();
+    return addStmt(I);
+  } else {
+    // There is no loop initialization.  We are thus basically a while loop.
+    // NULL out Block to force lazy block construction.
+    Block = NULL;
+    Succ = EntryConditionBlock;
+    return EntryConditionBlock;
+  }
+}
+
+CFGBlock *CFGBuilder::VisitMemberExpr(MemberExpr *M, AddStmtChoice asc) {
+  if (asc.alwaysAdd()) {
+    autoCreateBlock();
+    AppendStmt(Block, M, asc);
+  }
+  return Visit(M->getBase(),
+               M->isArrow() ? AddStmtChoice::NotAlwaysAdd
+                            : AddStmtChoice::AsLValueNotAlwaysAdd);
+}
+
+CFGBlock* CFGBuilder::VisitObjCForCollectionStmt(ObjCForCollectionStmt* S) {
+  // Objective-C fast enumeration 'for' statements:
+  //  http://developer.apple.com/documentation/Cocoa/Conceptual/ObjectiveC
+  //
+  //  for ( Type newVariable in collection_expression ) { statements }
+  //
+  //  becomes:
+  //
+  //   prologue:
+  //     1. collection_expression
+  //     T. jump to loop_entry
+  //   loop_entry:
+  //     1. side-effects of element expression
+  //     1. ObjCForCollectionStmt [performs binding to newVariable]
+  //     T. ObjCForCollectionStmt  TB, FB  [jumps to TB if newVariable != nil]
+  //   TB:
+  //     statements
+  //     T. jump to loop_entry
+  //   FB:
+  //     what comes after
+  //
+  //  and
+  //
+  //  Type existingItem;
+  //  for ( existingItem in expression ) { statements }
+  //
+  //  becomes:
+  //
+  //   the same with newVariable replaced with existingItem; the binding works
+  //   the same except that for one ObjCForCollectionStmt::getElement() returns
+  //   a DeclStmt and the other returns a DeclRefExpr.
+  //
+
+  CFGBlock* LoopSuccessor = 0;
+
+  if (Block) {
+    if (!FinishBlock(Block))
+      return 0;
+    LoopSuccessor = Block;
+    Block = 0;
+  } else
+    LoopSuccessor = Succ;
+
+  // Build the condition blocks.
+  CFGBlock* ExitConditionBlock = createBlock(false);
+  CFGBlock* EntryConditionBlock = ExitConditionBlock;
+
+  // Set the terminator for the "exit" condition block.
+  ExitConditionBlock->setTerminator(S);
+
+  // The last statement in the block should be the ObjCForCollectionStmt, which
+  // performs the actual binding to 'element' and determines if there are any
+  // more items in the collection.
+  AppendStmt(ExitConditionBlock, S);
+  Block = ExitConditionBlock;
+
+  // Walk the 'element' expression to see if there are any side-effects.  We
+  // generate new blocks as necesary.  We DON'T add the statement by default to
+  // the CFG unless it contains control-flow.
+  EntryConditionBlock = Visit(S->getElement(), AddStmtChoice::NotAlwaysAdd);
+  if (Block) {
+    if (!FinishBlock(EntryConditionBlock))
+      return 0;
+    Block = 0;
+  }
+
+  // The condition block is the implicit successor for the loop body as well as
+  // any code above the loop.
+  Succ = EntryConditionBlock;
+
+  // Now create the true branch.
+  {
+    // Save the current values for Succ, continue and break targets.
+    SaveAndRestore<CFGBlock*> save_Succ(Succ),
+      save_continue(ContinueTargetBlock), save_break(BreakTargetBlock);
+
+    BreakTargetBlock = LoopSuccessor;
+    ContinueTargetBlock = EntryConditionBlock;
+
+    CFGBlock* BodyBlock = addStmt(S->getBody());
+
+    if (!BodyBlock)
+      BodyBlock = EntryConditionBlock; // can happen for "for (X in Y) ;"
+    else if (Block) {
+      if (!FinishBlock(BodyBlock))
+        return 0;
+    }
+
+    // This new body block is a successor to our "exit" condition block.
+    AddSuccessor(ExitConditionBlock, BodyBlock);
+  }
+
+  // Link up the condition block with the code that follows the loop.
+  // (the false branch).
+  AddSuccessor(ExitConditionBlock, LoopSuccessor);
+
+  // Now create a prologue block to contain the collection expression.
+  Block = createBlock();
+  return addStmt(S->getCollection());
+}
+
+CFGBlock* CFGBuilder::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt* S) {
+  // FIXME: Add locking 'primitives' to CFG for @synchronized.
+
+  // Inline the body.
+  CFGBlock *SyncBlock = addStmt(S->getSynchBody());
+
+  // The sync body starts its own basic block.  This makes it a little easier
+  // for diagnostic clients.
+  if (SyncBlock) {
+    if (!FinishBlock(SyncBlock))
+      return 0;
+
+    Block = 0;
+  }
+
+  Succ = SyncBlock;
+
+  // Inline the sync expression.
+  return addStmt(S->getSynchExpr());
+}
+
+CFGBlock* CFGBuilder::VisitObjCAtTryStmt(ObjCAtTryStmt* S) {
+  // FIXME
+  return NYS();
+}
+
+CFGBlock* CFGBuilder::VisitWhileStmt(WhileStmt* W) {
+  CFGBlock* LoopSuccessor = NULL;
+
+  // "while" is a control-flow statement.  Thus we stop processing the current
+  // block.
+  if (Block) {
+    if (!FinishBlock(Block))
+      return 0;
+    LoopSuccessor = Block;
+  } else
+    LoopSuccessor = Succ;
+
+  // Because of short-circuit evaluation, the condition of the loop can span
+  // multiple basic blocks.  Thus we need the "Entry" and "Exit" blocks that
+  // evaluate the condition.
+  CFGBlock* ExitConditionBlock = createBlock(false);
+  CFGBlock* EntryConditionBlock = ExitConditionBlock;
+
+  // Set the terminator for the "exit" condition block.
+  ExitConditionBlock->setTerminator(W);
+
+  // Now add the actual condition to the condition block.  Because the condition
+  // itself may contain control-flow, new blocks may be created.  Thus we update
+  // "Succ" after adding the condition.
+  if (Stmt* C = W->getCond()) {
+    Block = ExitConditionBlock;
+    EntryConditionBlock = addStmt(C);
+    assert(Block == EntryConditionBlock);
+    
+    // If this block contains a condition variable, add both the condition
+    // variable and initializer to the CFG.
+    if (VarDecl *VD = W->getConditionVariable()) {
+      if (Expr *Init = VD->getInit()) {
+        autoCreateBlock();
+        AppendStmt(Block, W, AddStmtChoice::AlwaysAdd);
+        EntryConditionBlock = addStmt(Init);
+        assert(Block == EntryConditionBlock);
+      }
+    }
+
+    if (Block) {
+      if (!FinishBlock(EntryConditionBlock))
+        return 0;
+    }
+  }
+
+  // The condition block is the implicit successor for the loop body as well as
+  // any code above the loop.
+  Succ = EntryConditionBlock;
+
+  // See if this is a known constant.
+  const TryResult& KnownVal = TryEvaluateBool(W->getCond());
+
+  // Process the loop body.
+  {
+    assert(W->getBody());
+
+    // Save the current values for Block, Succ, and continue and break targets
+    SaveAndRestore<CFGBlock*> save_Block(Block), save_Succ(Succ),
+                              save_continue(ContinueTargetBlock),
+                              save_break(BreakTargetBlock);
+
+    // Create an empty block to represent the transition block for looping back
+    // to the head of the loop.
+    Block = 0;
+    assert(Succ == EntryConditionBlock);
+    Succ = createBlock();
+    Succ->setLoopTarget(W);
+    ContinueTargetBlock = Succ;
+
+    // All breaks should go to the code following the loop.
+    BreakTargetBlock = LoopSuccessor;
+
+    // NULL out Block to force lazy instantiation of blocks for the body.
+    Block = NULL;
+
+    // Create the body.  The returned block is the entry to the loop body.
+    CFGBlock* BodyBlock = addStmt(W->getBody());
+
+    if (!BodyBlock)
+      BodyBlock = ContinueTargetBlock; // can happen for "while(...) ;"
+    else if (Block) {
+      if (!FinishBlock(BodyBlock))
+        return 0;
+    }
+
+    // Add the loop body entry as a successor to the condition.
+    AddSuccessor(ExitConditionBlock, KnownVal.isFalse() ? NULL : BodyBlock);
+  }
+
+  // Link up the condition block with the code that follows the loop.  (the
+  // false branch).
+  AddSuccessor(ExitConditionBlock, KnownVal.isTrue() ? NULL : LoopSuccessor);
+
+  // There can be no more statements in the condition block since we loop back
+  // to this block.  NULL out Block to force lazy creation of another block.
+  Block = NULL;
+
+  // Return the condition block, which is the dominating block for the loop.
+  Succ = EntryConditionBlock;
+  return EntryConditionBlock;
+}
+
+
+CFGBlock *CFGBuilder::VisitObjCAtCatchStmt(ObjCAtCatchStmt* S) {
+  // FIXME: For now we pretend that @catch and the code it contains does not
+  //  exit.
+  return Block;
+}
+
+CFGBlock* CFGBuilder::VisitObjCAtThrowStmt(ObjCAtThrowStmt* S) {
+  // FIXME: This isn't complete.  We basically treat @throw like a return
+  //  statement.
+
+  // If we were in the middle of a block we stop processing that block.
+  if (Block && !FinishBlock(Block))
+    return 0;
+
+  // Create the new block.
+  Block = createBlock(false);
+
+  // The Exit block is the only successor.
+  AddSuccessor(Block, &cfg->getExit());
+
+  // Add the statement to the block.  This may create new blocks if S contains
+  // control-flow (short-circuit operations).
+  return VisitStmt(S, AddStmtChoice::AlwaysAdd);
+}
+
+CFGBlock* CFGBuilder::VisitCXXThrowExpr(CXXThrowExpr* T) {
+  // If we were in the middle of a block we stop processing that block.
+  if (Block && !FinishBlock(Block))
+    return 0;
+
+  // Create the new block.
+  Block = createBlock(false);
+
+  if (TryTerminatedBlock)
+    // The current try statement is the only successor.
+    AddSuccessor(Block, TryTerminatedBlock);
+  else 
+    // otherwise the Exit block is the only successor.
+    AddSuccessor(Block, &cfg->getExit());
+
+  // Add the statement to the block.  This may create new blocks if S contains
+  // control-flow (short-circuit operations).
+  return VisitStmt(T, AddStmtChoice::AlwaysAdd);
+}
+
+CFGBlock *CFGBuilder::VisitDoStmt(DoStmt* D) {
+  CFGBlock* LoopSuccessor = NULL;
+
+  // "do...while" is a control-flow statement.  Thus we stop processing the
+  // current block.
+  if (Block) {
+    if (!FinishBlock(Block))
+      return 0;
+    LoopSuccessor = Block;
+  } else
+    LoopSuccessor = Succ;
+
+  // Because of short-circuit evaluation, the condition of the loop can span
+  // multiple basic blocks.  Thus we need the "Entry" and "Exit" blocks that
+  // evaluate the condition.
+  CFGBlock* ExitConditionBlock = createBlock(false);
+  CFGBlock* EntryConditionBlock = ExitConditionBlock;
+
+  // Set the terminator for the "exit" condition block.
+  ExitConditionBlock->setTerminator(D);
+
+  // Now add the actual condition to the condition block.  Because the condition
+  // itself may contain control-flow, new blocks may be created.
+  if (Stmt* C = D->getCond()) {
+    Block = ExitConditionBlock;
+    EntryConditionBlock = addStmt(C);
+    if (Block) {
+      if (!FinishBlock(EntryConditionBlock))
+        return 0;
+    }
+  }
+
+  // The condition block is the implicit successor for the loop body.
+  Succ = EntryConditionBlock;
+
+  // See if this is a known constant.
+  const TryResult &KnownVal = TryEvaluateBool(D->getCond());
+
+  // Process the loop body.
+  CFGBlock* BodyBlock = NULL;
+  {
+    assert(D->getBody());
+
+    // Save the current values for Block, Succ, and continue and break targets
+    SaveAndRestore<CFGBlock*> save_Block(Block), save_Succ(Succ),
+      save_continue(ContinueTargetBlock),
+      save_break(BreakTargetBlock);
+
+    // All continues within this loop should go to the condition block
+    ContinueTargetBlock = EntryConditionBlock;
+
+    // All breaks should go to the code following the loop.
+    BreakTargetBlock = LoopSuccessor;
+
+    // NULL out Block to force lazy instantiation of blocks for the body.
+    Block = NULL;
+
+    // Create the body.  The returned block is the entry to the loop body.
+    BodyBlock = addStmt(D->getBody());
+
+    if (!BodyBlock)
+      BodyBlock = EntryConditionBlock; // can happen for "do ; while(...)"
+    else if (Block) {
+      if (!FinishBlock(BodyBlock))
+        return 0;
+    }
+
+    // Add an intermediate block between the BodyBlock and the
+    // ExitConditionBlock to represent the "loop back" transition.  Create an
+    // empty block to represent the transition block for looping back to the
+    // head of the loop.
+    // FIXME: Can we do this more efficiently without adding another block?
+    Block = NULL;
+    Succ = BodyBlock;
+    CFGBlock *LoopBackBlock = createBlock();
+    LoopBackBlock->setLoopTarget(D);
+
+    // Add the loop body entry as a successor to the condition.
+    AddSuccessor(ExitConditionBlock, KnownVal.isFalse() ? NULL : LoopBackBlock);
+  }
+
+  // Link up the condition block with the code that follows the loop.
+  // (the false branch).
+  AddSuccessor(ExitConditionBlock, KnownVal.isTrue() ? NULL : LoopSuccessor);
+
+  // There can be no more statements in the body block(s) since we loop back to
+  // the body.  NULL out Block to force lazy creation of another block.
+  Block = NULL;
+
+  // Return the loop body, which is the dominating block for the loop.
+  Succ = BodyBlock;
+  return BodyBlock;
+}
+
+CFGBlock* CFGBuilder::VisitContinueStmt(ContinueStmt* C) {
+  // "continue" is a control-flow statement.  Thus we stop processing the
+  // current block.
+  if (Block && !FinishBlock(Block))
+      return 0;
+
+  // Now create a new block that ends with the continue statement.
+  Block = createBlock(false);
+  Block->setTerminator(C);
+
+  // If there is no target for the continue, then we are looking at an
+  // incomplete AST.  This means the CFG cannot be constructed.
+  if (ContinueTargetBlock)
+    AddSuccessor(Block, ContinueTargetBlock);
+  else
+    badCFG = true;
+
+  return Block;
+}
+
+CFGBlock *CFGBuilder::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E,
+                                             AddStmtChoice asc) {
+
+  if (asc.alwaysAdd()) {
+    autoCreateBlock();
+    AppendStmt(Block, E);
+  }
+
+  // VLA types have expressions that must be evaluated.
+  if (E->isArgumentType()) {
+    for (VariableArrayType* VA = FindVA(E->getArgumentType().getTypePtr());
+         VA != 0; VA = FindVA(VA->getElementType().getTypePtr()))
+      addStmt(VA->getSizeExpr());
+  }
+
+  return Block;
+}
+
+/// VisitStmtExpr - Utility method to handle (nested) statement
+///  expressions (a GCC extension).
+CFGBlock* CFGBuilder::VisitStmtExpr(StmtExpr *SE, AddStmtChoice asc) {
+  if (asc.alwaysAdd()) {
+    autoCreateBlock();
+    AppendStmt(Block, SE);
+  }
+  return VisitCompoundStmt(SE->getSubStmt());
+}
+
+CFGBlock* CFGBuilder::VisitSwitchStmt(SwitchStmt* Terminator) {
+  // "switch" is a control-flow statement.  Thus we stop processing the current
+  // block.
+  CFGBlock* SwitchSuccessor = NULL;
+
+  if (Block) {
+    if (!FinishBlock(Block))
+      return 0;
+    SwitchSuccessor = Block;
+  } else SwitchSuccessor = Succ;
+
+  // Save the current "switch" context.
+  SaveAndRestore<CFGBlock*> save_switch(SwitchTerminatedBlock),
+                            save_break(BreakTargetBlock),
+                            save_default(DefaultCaseBlock);
+
+  // Set the "default" case to be the block after the switch statement.  If the
+  // switch statement contains a "default:", this value will be overwritten with
+  // the block for that code.
+  DefaultCaseBlock = SwitchSuccessor;
+
+  // Create a new block that will contain the switch statement.
+  SwitchTerminatedBlock = createBlock(false);
+
+  // Now process the switch body.  The code after the switch is the implicit
+  // successor.
+  Succ = SwitchSuccessor;
+  BreakTargetBlock = SwitchSuccessor;
+
+  // When visiting the body, the case statements should automatically get linked
+  // up to the switch.  We also don't keep a pointer to the body, since all
+  // control-flow from the switch goes to case/default statements.
+  assert(Terminator->getBody() && "switch must contain a non-NULL body");
+  Block = NULL;
+  CFGBlock *BodyBlock = addStmt(Terminator->getBody());
+  if (Block) {
+    if (!FinishBlock(BodyBlock))
+      return 0;
+  }
+
+  // If we have no "default:" case, the default transition is to the code
+  // following the switch body.
+  AddSuccessor(SwitchTerminatedBlock, DefaultCaseBlock);
+
+  // Add the terminator and condition in the switch block.
+  SwitchTerminatedBlock->setTerminator(Terminator);
+  assert(Terminator->getCond() && "switch condition must be non-NULL");
+  Block = SwitchTerminatedBlock;
+  Block = addStmt(Terminator->getCond());
+  
+  // Finally, if the SwitchStmt contains a condition variable, add both the
+  // SwitchStmt and the condition variable initialization to the CFG.
+  if (VarDecl *VD = Terminator->getConditionVariable()) {
+    if (Expr *Init = VD->getInit()) {
+      autoCreateBlock();
+      AppendStmt(Block, Terminator, AddStmtChoice::AlwaysAdd);
+      addStmt(Init);
+    }
+  }
+  
+  return Block;
+}
+
+CFGBlock* CFGBuilder::VisitCaseStmt(CaseStmt* CS) {
+  // CaseStmts are essentially labels, so they are the first statement in a
+  // block.
+
+  if (CS->getSubStmt())
+    addStmt(CS->getSubStmt());
+
+  CFGBlock* CaseBlock = Block;
+  if (!CaseBlock)
+    CaseBlock = createBlock();
+
+  // Cases statements partition blocks, so this is the top of the basic block we
+  // were processing (the "case XXX:" is the label).
+  CaseBlock->setLabel(CS);
+
+  if (!FinishBlock(CaseBlock))
+    return 0;
+
+  // Add this block to the list of successors for the block with the switch
+  // statement.
+  assert(SwitchTerminatedBlock);
+  AddSuccessor(SwitchTerminatedBlock, CaseBlock);
+
+  // We set Block to NULL to allow lazy creation of a new block (if necessary)
+  Block = NULL;
+
+  // This block is now the implicit successor of other blocks.
+  Succ = CaseBlock;
+
+  return CaseBlock;
+}
+
+CFGBlock* CFGBuilder::VisitDefaultStmt(DefaultStmt* Terminator) {
+  if (Terminator->getSubStmt())
+    addStmt(Terminator->getSubStmt());
+
+  DefaultCaseBlock = Block;
+
+  if (!DefaultCaseBlock)
+    DefaultCaseBlock = createBlock();
+
+  // Default statements partition blocks, so this is the top of the basic block
+  // we were processing (the "default:" is the label).
+  DefaultCaseBlock->setLabel(Terminator);
+
+  if (!FinishBlock(DefaultCaseBlock))
+    return 0;
+
+  // Unlike case statements, we don't add the default block to the successors
+  // for the switch statement immediately.  This is done when we finish
+  // processing the switch statement.  This allows for the default case
+  // (including a fall-through to the code after the switch statement) to always
+  // be the last successor of a switch-terminated block.
+
+  // We set Block to NULL to allow lazy creation of a new block (if necessary)
+  Block = NULL;
+
+  // This block is now the implicit successor of other blocks.
+  Succ = DefaultCaseBlock;
+
+  return DefaultCaseBlock;
+}
+
+CFGBlock *CFGBuilder::VisitCXXTryStmt(CXXTryStmt *Terminator) {
+  // "try"/"catch" is a control-flow statement.  Thus we stop processing the
+  // current block.
+  CFGBlock* TrySuccessor = NULL;
+
+  if (Block) {
+    if (!FinishBlock(Block))
+      return 0;
+    TrySuccessor = Block;
+  } else TrySuccessor = Succ;
+
+  CFGBlock *PrevTryTerminatedBlock = TryTerminatedBlock;
+
+  // Create a new block that will contain the try statement.
+  CFGBlock *NewTryTerminatedBlock = createBlock(false);
+  // Add the terminator in the try block.
+  NewTryTerminatedBlock->setTerminator(Terminator);
+
+  bool HasCatchAll = false;
+  for (unsigned h = 0; h <Terminator->getNumHandlers(); ++h) {
+    // The code after the try is the implicit successor.
+    Succ = TrySuccessor;
+    CXXCatchStmt *CS = Terminator->getHandler(h);
+    if (CS->getExceptionDecl() == 0) {
+      HasCatchAll = true;
+    }
+    Block = NULL;
+    CFGBlock *CatchBlock = VisitCXXCatchStmt(CS);
+    if (CatchBlock == 0)
+      return 0;
+    // Add this block to the list of successors for the block with the try
+    // statement.
+    AddSuccessor(NewTryTerminatedBlock, CatchBlock);
+  }
+  if (!HasCatchAll) {
+    if (PrevTryTerminatedBlock)
+      AddSuccessor(NewTryTerminatedBlock, PrevTryTerminatedBlock);
+    else
+      AddSuccessor(NewTryTerminatedBlock, &cfg->getExit());
+  }
+
+  // The code after the try is the implicit successor.
+  Succ = TrySuccessor;
+
+  // Save the current "try" context.
+  SaveAndRestore<CFGBlock*> save_try(TryTerminatedBlock);
+  TryTerminatedBlock = NewTryTerminatedBlock;
+
+  assert(Terminator->getTryBlock() && "try must contain a non-NULL body");
+  Block = NULL;
+  Block = addStmt(Terminator->getTryBlock());
+  return Block;
+}
+
+CFGBlock* CFGBuilder::VisitCXXCatchStmt(CXXCatchStmt* CS) {
+  // CXXCatchStmt are treated like labels, so they are the first statement in a
+  // block.
+
+  if (CS->getHandlerBlock())
+    addStmt(CS->getHandlerBlock());
+
+  CFGBlock* CatchBlock = Block;
+  if (!CatchBlock)
+    CatchBlock = createBlock();
+
+  CatchBlock->setLabel(CS);
+
+  if (!FinishBlock(CatchBlock))
+    return 0;
+
+  // We set Block to NULL to allow lazy creation of a new block (if necessary)
+  Block = NULL;
+
+  return CatchBlock;
+}
+
+CFGBlock *CFGBuilder::VisitCXXMemberCallExpr(CXXMemberCallExpr *C, 
+                                             AddStmtChoice asc) {
+  AddStmtChoice::Kind K = asc.asLValue() ? AddStmtChoice::AlwaysAddAsLValue 
+                                         : AddStmtChoice::AlwaysAdd;
+  autoCreateBlock();
+  AppendStmt(Block, C, AddStmtChoice(K));
+  return VisitChildren(C);
+}
+
+CFGBlock* CFGBuilder::VisitIndirectGotoStmt(IndirectGotoStmt* I) {
+  // Lazily create the indirect-goto dispatch block if there isn't one already.
+  CFGBlock* IBlock = cfg->getIndirectGotoBlock();
+
+  if (!IBlock) {
+    IBlock = createBlock(false);
+    cfg->setIndirectGotoBlock(IBlock);
+  }
+
+  // IndirectGoto is a control-flow statement.  Thus we stop processing the
+  // current block and create a new one.
+  if (Block && !FinishBlock(Block))
+    return 0;
+
+  Block = createBlock(false);
+  Block->setTerminator(I);
+  AddSuccessor(Block, IBlock);
+  return addStmt(I->getTarget());
+}
+
+} // end anonymous namespace
+
+/// createBlock - Constructs and adds a new CFGBlock to the CFG.  The block has
+///  no successors or predecessors.  If this is the first block created in the
+///  CFG, it is automatically set to be the Entry and Exit of the CFG.
+CFGBlock* CFG::createBlock() {
+  bool first_block = begin() == end();
+
+  // Create the block.
+  CFGBlock *Mem = getAllocator().Allocate<CFGBlock>();
+  new (Mem) CFGBlock(NumBlockIDs++, BlkBVC);
+  Blocks.push_back(Mem, BlkBVC);
+
+  // If this is the first block, set it as the Entry and Exit.
+  if (first_block)
+    Entry = Exit = &back();
+
+  // Return the block.
+  return &back();
+}
+
+/// buildCFG - Constructs a CFG from an AST.  Ownership of the returned
+///  CFG is returned to the caller.
+CFG* CFG::buildCFG(const Decl *D, Stmt* Statement, ASTContext *C,
+                   bool AddEHEdges, bool AddScopes) {
+  CFGBuilder Builder;
+  return Builder.buildCFG(D, Statement, C, AddEHEdges, AddScopes);
+}
+
+//===----------------------------------------------------------------------===//
+// CFG: Queries for BlkExprs.
+//===----------------------------------------------------------------------===//
+
+namespace {
+  typedef llvm::DenseMap<const Stmt*,unsigned> BlkExprMapTy;
+}
+
+static void FindSubExprAssignments(Stmt *S,
+                                   llvm::SmallPtrSet<Expr*,50>& Set) {
+  if (!S)
+    return;
+
+  for (Stmt::child_iterator I=S->child_begin(), E=S->child_end(); I!=E; ++I) {
+    Stmt *child = *I;    
+    if (!child)
+      continue;
+    
+    if (BinaryOperator* B = dyn_cast<BinaryOperator>(child))
+      if (B->isAssignmentOp()) Set.insert(B);
+
+    FindSubExprAssignments(child, Set);
+  }
+}
+
+static BlkExprMapTy* PopulateBlkExprMap(CFG& cfg) {
+  BlkExprMapTy* M = new BlkExprMapTy();
+
+  // Look for assignments that are used as subexpressions.  These are the only
+  // assignments that we want to *possibly* register as a block-level
+  // expression.  Basically, if an assignment occurs both in a subexpression and
+  // at the block-level, it is a block-level expression.
+  llvm::SmallPtrSet<Expr*,50> SubExprAssignments;
+
+  for (CFG::iterator I=cfg.begin(), E=cfg.end(); I != E; ++I)
+    for (CFGBlock::iterator BI=(*I)->begin(), EI=(*I)->end(); BI != EI; ++BI)
+      FindSubExprAssignments(*BI, SubExprAssignments);
+
+  for (CFG::iterator I=cfg.begin(), E=cfg.end(); I != E; ++I) {
+
+    // Iterate over the statements again on identify the Expr* and Stmt* at the
+    // block-level that are block-level expressions.
+
+    for (CFGBlock::iterator BI=(*I)->begin(), EI=(*I)->end(); BI != EI; ++BI)
+      if (Expr* Exp = dyn_cast<Expr>(*BI)) {
+
+        if (BinaryOperator* B = dyn_cast<BinaryOperator>(Exp)) {
+          // Assignment expressions that are not nested within another
+          // expression are really "statements" whose value is never used by
+          // another expression.
+          if (B->isAssignmentOp() && !SubExprAssignments.count(Exp))
+            continue;
+        } else if (const StmtExpr* Terminator = dyn_cast<StmtExpr>(Exp)) {
+          // Special handling for statement expressions.  The last statement in
+          // the statement expression is also a block-level expr.
+          const CompoundStmt* C = Terminator->getSubStmt();
+          if (!C->body_empty()) {
+            unsigned x = M->size();
+            (*M)[C->body_back()] = x;
+          }
+        }
+
+        unsigned x = M->size();
+        (*M)[Exp] = x;
+      }
+
+    // Look at terminators.  The condition is a block-level expression.
+
+    Stmt* S = (*I)->getTerminatorCondition();
+
+    if (S && M->find(S) == M->end()) {
+        unsigned x = M->size();
+        (*M)[S] = x;
+    }
+  }
+
+  return M;
+}
+
+CFG::BlkExprNumTy CFG::getBlkExprNum(const Stmt* S) {
+  assert(S != NULL);
+  if (!BlkExprMap) { BlkExprMap = (void*) PopulateBlkExprMap(*this); }
+
+  BlkExprMapTy* M = reinterpret_cast<BlkExprMapTy*>(BlkExprMap);
+  BlkExprMapTy::iterator I = M->find(S);
+  return (I == M->end()) ? CFG::BlkExprNumTy() : CFG::BlkExprNumTy(I->second);
+}
+
+unsigned CFG::getNumBlkExprs() {
+  if (const BlkExprMapTy* M = reinterpret_cast<const BlkExprMapTy*>(BlkExprMap))
+    return M->size();
+  else {
+    // We assume callers interested in the number of BlkExprs will want
+    // the map constructed if it doesn't already exist.
+    BlkExprMap = (void*) PopulateBlkExprMap(*this);
+    return reinterpret_cast<BlkExprMapTy*>(BlkExprMap)->size();
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// Cleanup: CFG dstor.
+//===----------------------------------------------------------------------===//
+
+CFG::~CFG() {
+  delete reinterpret_cast<const BlkExprMapTy*>(BlkExprMap);
+}
+
+//===----------------------------------------------------------------------===//
+// CFG pretty printing
+//===----------------------------------------------------------------------===//
+
+namespace {
+
+class StmtPrinterHelper : public PrinterHelper  {
+  typedef llvm::DenseMap<Stmt*,std::pair<unsigned,unsigned> > StmtMapTy;
+  StmtMapTy StmtMap;
+  signed CurrentBlock;
+  unsigned CurrentStmt;
+  const LangOptions &LangOpts;
+public:
+
+  StmtPrinterHelper(const CFG* cfg, const LangOptions &LO)
+    : CurrentBlock(0), CurrentStmt(0), LangOpts(LO) {
+    for (CFG::const_iterator I = cfg->begin(), E = cfg->end(); I != E; ++I ) {
+      unsigned j = 1;
+      for (CFGBlock::const_iterator BI = (*I)->begin(), BEnd = (*I)->end() ;
+           BI != BEnd; ++BI, ++j )
+        StmtMap[*BI] = std::make_pair((*I)->getBlockID(),j);
+      }
+  }
+
+  virtual ~StmtPrinterHelper() {}
+
+  const LangOptions &getLangOpts() const { return LangOpts; }
+  void setBlockID(signed i) { CurrentBlock = i; }
+  void setStmtID(unsigned i) { CurrentStmt = i; }
+
+  virtual bool handledStmt(Stmt* Terminator, llvm::raw_ostream& OS) {
+
+    StmtMapTy::iterator I = StmtMap.find(Terminator);
+
+    if (I == StmtMap.end())
+      return false;
+
+    if (CurrentBlock >= 0 && I->second.first == (unsigned) CurrentBlock
+                          && I->second.second == CurrentStmt) {
+      return false;
+    }
+
+    OS << "[B" << I->second.first << "." << I->second.second << "]";
+    return true;
+  }
+};
+} // end anonymous namespace
+
+
+namespace {
+class CFGBlockTerminatorPrint
+  : public StmtVisitor<CFGBlockTerminatorPrint,void> {
+
+  llvm::raw_ostream& OS;
+  StmtPrinterHelper* Helper;
+  PrintingPolicy Policy;
+public:
+  CFGBlockTerminatorPrint(llvm::raw_ostream& os, StmtPrinterHelper* helper,
+                          const PrintingPolicy &Policy)
+    : OS(os), Helper(helper), Policy(Policy) {}
+
+  void VisitIfStmt(IfStmt* I) {
+    OS << "if ";
+    I->getCond()->printPretty(OS,Helper,Policy);
+  }
+
+  // Default case.
+  void VisitStmt(Stmt* Terminator) {
+    Terminator->printPretty(OS, Helper, Policy);
+  }
+
+  void VisitForStmt(ForStmt* F) {
+    OS << "for (" ;
+    if (F->getInit())
+      OS << "...";
+    OS << "; ";
+    if (Stmt* C = F->getCond())
+      C->printPretty(OS, Helper, Policy);
+    OS << "; ";
+    if (F->getInc())
+      OS << "...";
+    OS << ")";
+  }
+
+  void VisitWhileStmt(WhileStmt* W) {
+    OS << "while " ;
+    if (Stmt* C = W->getCond())
+      C->printPretty(OS, Helper, Policy);
+  }
+
+  void VisitDoStmt(DoStmt* D) {
+    OS << "do ... while ";
+    if (Stmt* C = D->getCond())
+      C->printPretty(OS, Helper, Policy);
+  }
+
+  void VisitSwitchStmt(SwitchStmt* Terminator) {
+    OS << "switch ";
+    Terminator->getCond()->printPretty(OS, Helper, Policy);
+  }
+
+  void VisitCXXTryStmt(CXXTryStmt* CS) {
+    OS << "try ...";
+  }
+
+  void VisitConditionalOperator(ConditionalOperator* C) {
+    C->getCond()->printPretty(OS, Helper, Policy);
+    OS << " ? ... : ...";
+  }
+
+  void VisitChooseExpr(ChooseExpr* C) {
+    OS << "__builtin_choose_expr( ";
+    C->getCond()->printPretty(OS, Helper, Policy);
+    OS << " )";
+  }
+
+  void VisitIndirectGotoStmt(IndirectGotoStmt* I) {
+    OS << "goto *";
+    I->getTarget()->printPretty(OS, Helper, Policy);
+  }
+
+  void VisitBinaryOperator(BinaryOperator* B) {
+    if (!B->isLogicalOp()) {
+      VisitExpr(B);
+      return;
+    }
+
+    B->getLHS()->printPretty(OS, Helper, Policy);
+
+    switch (B->getOpcode()) {
+      case BinaryOperator::LOr:
+        OS << " || ...";
+        return;
+      case BinaryOperator::LAnd:
+        OS << " && ...";
+        return;
+      default:
+        assert(false && "Invalid logical operator.");
+    }
+  }
+
+  void VisitExpr(Expr* E) {
+    E->printPretty(OS, Helper, Policy);
+  }
+};
+} // end anonymous namespace
+
+
+static void print_stmt(llvm::raw_ostream &OS, StmtPrinterHelper* Helper,
+                       const CFGElement &E) {
+  Stmt *Terminator = E;
+
+  if (E.asStartScope()) {
+    OS << "start scope\n";
+    return;
+  }
+  if (E.asEndScope()) {
+    OS << "end scope\n";
+    return;
+  }
+
+  if (Helper) {
+    // special printing for statement-expressions.
+    if (StmtExpr* SE = dyn_cast<StmtExpr>(Terminator)) {
+      CompoundStmt* Sub = SE->getSubStmt();
+
+      if (Sub->child_begin() != Sub->child_end()) {
+        OS << "({ ... ; ";
+        Helper->handledStmt(*SE->getSubStmt()->body_rbegin(),OS);
+        OS << " })\n";
+        return;
+      }
+    }
+
+    // special printing for comma expressions.
+    if (BinaryOperator* B = dyn_cast<BinaryOperator>(Terminator)) {
+      if (B->getOpcode() == BinaryOperator::Comma) {
+        OS << "... , ";
+        Helper->handledStmt(B->getRHS(),OS);
+        OS << '\n';
+        return;
+      }
+    }
+  }
+
+  Terminator->printPretty(OS, Helper, PrintingPolicy(Helper->getLangOpts()));
+
+  // Expressions need a newline.
+  if (isa<Expr>(Terminator)) OS << '\n';
+}
+
+static void print_block(llvm::raw_ostream& OS, const CFG* cfg,
+                        const CFGBlock& B,
+                        StmtPrinterHelper* Helper, bool print_edges) {
+
+  if (Helper) Helper->setBlockID(B.getBlockID());
+
+  // Print the header.
+  OS << "\n [ B" << B.getBlockID();
+
+  if (&B == &cfg->getEntry())
+    OS << " (ENTRY) ]\n";
+  else if (&B == &cfg->getExit())
+    OS << " (EXIT) ]\n";
+  else if (&B == cfg->getIndirectGotoBlock())
+    OS << " (INDIRECT GOTO DISPATCH) ]\n";
+  else
+    OS << " ]\n";
+
+  // Print the label of this block.
+  if (Stmt* Label = const_cast<Stmt*>(B.getLabel())) {
+
+    if (print_edges)
+      OS << "    ";
+
+    if (LabelStmt* L = dyn_cast<LabelStmt>(Label))
+      OS << L->getName();
+    else if (CaseStmt* C = dyn_cast<CaseStmt>(Label)) {
+      OS << "case ";
+      C->getLHS()->printPretty(OS, Helper,
+                               PrintingPolicy(Helper->getLangOpts()));
+      if (C->getRHS()) {
+        OS << " ... ";
+        C->getRHS()->printPretty(OS, Helper,
+                                 PrintingPolicy(Helper->getLangOpts()));
+      }
+    } else if (isa<DefaultStmt>(Label))
+      OS << "default";
+    else if (CXXCatchStmt *CS = dyn_cast<CXXCatchStmt>(Label)) {
+      OS << "catch (";
+      if (CS->getExceptionDecl())
+        CS->getExceptionDecl()->print(OS, PrintingPolicy(Helper->getLangOpts()),
+                                      0);
+      else
+        OS << "...";
+      OS << ")";
+
+    } else
+      assert(false && "Invalid label statement in CFGBlock.");
+
+    OS << ":\n";
+  }
+
+  // Iterate through the statements in the block and print them.
+  unsigned j = 1;
+
+  for (CFGBlock::const_iterator I = B.begin(), E = B.end() ;
+       I != E ; ++I, ++j ) {
+
+    // Print the statement # in the basic block and the statement itself.
+    if (print_edges)
+      OS << "    ";
+
+    OS << llvm::format("%3d", j) << ": ";
+
+    if (Helper)
+      Helper->setStmtID(j);
+
+    print_stmt(OS,Helper,*I);
+  }
+
+  // Print the terminator of this block.
+  if (B.getTerminator()) {
+    if (print_edges)
+      OS << "    ";
+
+    OS << "  T: ";
+
+    if (Helper) Helper->setBlockID(-1);
+
+    CFGBlockTerminatorPrint TPrinter(OS, Helper,
+                                     PrintingPolicy(Helper->getLangOpts()));
+    TPrinter.Visit(const_cast<Stmt*>(B.getTerminator()));
+    OS << '\n';
+  }
+
+  if (print_edges) {
+    // Print the predecessors of this block.
+    OS << "    Predecessors (" << B.pred_size() << "):";
+    unsigned i = 0;
+
+    for (CFGBlock::const_pred_iterator I = B.pred_begin(), E = B.pred_end();
+         I != E; ++I, ++i) {
+
+      if (i == 8 || (i-8) == 0)
+        OS << "\n     ";
+
+      OS << " B" << (*I)->getBlockID();
+    }
+
+    OS << '\n';
+
+    // Print the successors of this block.
+    OS << "    Successors (" << B.succ_size() << "):";
+    i = 0;
+
+    for (CFGBlock::const_succ_iterator I = B.succ_begin(), E = B.succ_end();
+         I != E; ++I, ++i) {
+
+      if (i == 8 || (i-8) % 10 == 0)
+        OS << "\n    ";
+
+      if (*I)
+        OS << " B" << (*I)->getBlockID();
+      else
+        OS  << " NULL";
+    }
+
+    OS << '\n';
+  }
+}
+
+
+/// dump - A simple pretty printer of a CFG that outputs to stderr.
+void CFG::dump(const LangOptions &LO) const { print(llvm::errs(), LO); }
+
+/// print - A simple pretty printer of a CFG that outputs to an ostream.
+void CFG::print(llvm::raw_ostream &OS, const LangOptions &LO) const {
+  StmtPrinterHelper Helper(this, LO);
+
+  // Print the entry block.
+  print_block(OS, this, getEntry(), &Helper, true);
+
+  // Iterate through the CFGBlocks and print them one by one.
+  for (const_iterator I = Blocks.begin(), E = Blocks.end() ; I != E ; ++I) {
+    // Skip the entry block, because we already printed it.
+    if (&(**I) == &getEntry() || &(**I) == &getExit())
+      continue;
+
+    print_block(OS, this, **I, &Helper, true);
+  }
+
+  // Print the exit block.
+  print_block(OS, this, getExit(), &Helper, true);
+  OS.flush();
+}
+
+/// dump - A simply pretty printer of a CFGBlock that outputs to stderr.
+void CFGBlock::dump(const CFG* cfg, const LangOptions &LO) const {
+  print(llvm::errs(), cfg, LO);
+}
+
+/// print - A simple pretty printer of a CFGBlock that outputs to an ostream.
+///   Generally this will only be called from CFG::print.
+void CFGBlock::print(llvm::raw_ostream& OS, const CFG* cfg,
+                     const LangOptions &LO) const {
+  StmtPrinterHelper Helper(cfg, LO);
+  print_block(OS, cfg, *this, &Helper, true);
+}
+
+/// printTerminator - A simple pretty printer of the terminator of a CFGBlock.
+void CFGBlock::printTerminator(llvm::raw_ostream &OS,
+                               const LangOptions &LO) const {
+  CFGBlockTerminatorPrint TPrinter(OS, NULL, PrintingPolicy(LO));
+  TPrinter.Visit(const_cast<Stmt*>(getTerminator()));
+}
+
+Stmt* CFGBlock::getTerminatorCondition() {
+
+  if (!Terminator)
+    return NULL;
+
+  Expr* E = NULL;
+
+  switch (Terminator->getStmtClass()) {
+    default:
+      break;
+
+    case Stmt::ForStmtClass:
+      E = cast<ForStmt>(Terminator)->getCond();
+      break;
+
+    case Stmt::WhileStmtClass:
+      E = cast<WhileStmt>(Terminator)->getCond();
+      break;
+
+    case Stmt::DoStmtClass:
+      E = cast<DoStmt>(Terminator)->getCond();
+      break;
+
+    case Stmt::IfStmtClass:
+      E = cast<IfStmt>(Terminator)->getCond();
+      break;
+
+    case Stmt::ChooseExprClass:
+      E = cast<ChooseExpr>(Terminator)->getCond();
+      break;
+
+    case Stmt::IndirectGotoStmtClass:
+      E = cast<IndirectGotoStmt>(Terminator)->getTarget();
+      break;
+
+    case Stmt::SwitchStmtClass:
+      E = cast<SwitchStmt>(Terminator)->getCond();
+      break;
+
+    case Stmt::ConditionalOperatorClass:
+      E = cast<ConditionalOperator>(Terminator)->getCond();
+      break;
+
+    case Stmt::BinaryOperatorClass: // '&&' and '||'
+      E = cast<BinaryOperator>(Terminator)->getLHS();
+      break;
+
+    case Stmt::ObjCForCollectionStmtClass:
+      return Terminator;
+  }
+
+  return E ? E->IgnoreParens() : NULL;
+}
+
+bool CFGBlock::hasBinaryBranchTerminator() const {
+
+  if (!Terminator)
+    return false;
+
+  Expr* E = NULL;
+
+  switch (Terminator->getStmtClass()) {
+    default:
+      return false;
+
+    case Stmt::ForStmtClass:
+    case Stmt::WhileStmtClass:
+    case Stmt::DoStmtClass:
+    case Stmt::IfStmtClass:
+    case Stmt::ChooseExprClass:
+    case Stmt::ConditionalOperatorClass:
+    case Stmt::BinaryOperatorClass:
+      return true;
+  }
+
+  return E ? E->IgnoreParens() : NULL;
+}
+
+
+//===----------------------------------------------------------------------===//
+// CFG Graphviz Visualization
+//===----------------------------------------------------------------------===//
+
+
+#ifndef NDEBUG
+static StmtPrinterHelper* GraphHelper;
+#endif
+
+void CFG::viewCFG(const LangOptions &LO) const {
+#ifndef NDEBUG
+  StmtPrinterHelper H(this, LO);
+  GraphHelper = &H;
+  llvm::ViewGraph(this,"CFG");
+  GraphHelper = NULL;
+#endif
+}
+
+namespace llvm {
+template<>
+struct DOTGraphTraits<const CFG*> : public DefaultDOTGraphTraits {
+
+  DOTGraphTraits (bool isSimple=false) : DefaultDOTGraphTraits(isSimple) {}
+
+  static std::string getNodeLabel(const CFGBlock* Node, const CFG* Graph) {
+
+#ifndef NDEBUG
+    std::string OutSStr;
+    llvm::raw_string_ostream Out(OutSStr);
+    print_block(Out,Graph, *Node, GraphHelper, false);
+    std::string& OutStr = Out.str();
+
+    if (OutStr[0] == '\n') OutStr.erase(OutStr.begin());
+
+    // Process string output to make it nicer...
+    for (unsigned i = 0; i != OutStr.length(); ++i)
+      if (OutStr[i] == '\n') {                            // Left justify
+        OutStr[i] = '\\';
+        OutStr.insert(OutStr.begin()+i+1, 'l');
+      }
+
+    return OutStr;
+#else
+    return "";
+#endif
+  }
+};
+} // end namespace llvm
diff --git a/lib/Analysis/CMakeLists.txt b/lib/Analysis/CMakeLists.txt
new file mode 100644
index 0000000..b4e0e24
--- /dev/null
+++ b/lib/Analysis/CMakeLists.txt
@@ -0,0 +1,12 @@
+set(LLVM_NO_RTTI 1)
+
+add_clang_library(clangAnalysis
+  AnalysisContext.cpp
+  CFG.cpp
+  LiveVariables.cpp
+  PrintfFormatString.cpp
+  ReachableCode.cpp
+  UninitializedValues.cpp
+  )
+
+add_dependencies(clangAnalysis ClangDiagnosticAnalysis)
diff --git a/lib/Analysis/LiveVariables.cpp b/lib/Analysis/LiveVariables.cpp
new file mode 100644
index 0000000..01a36a1
--- /dev/null
+++ b/lib/Analysis/LiveVariables.cpp
@@ -0,0 +1,382 @@
+//=- LiveVariables.cpp - Live Variable Analysis for Source CFGs -*- C++ --*-==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements Live Variables analysis for source-level CFGs.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Analysis/Analyses/LiveVariables.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Expr.h"
+#include "clang/Analysis/CFG.h"
+#include "clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h"
+#include "clang/Analysis/FlowSensitive/DataflowSolver.h"
+#include "clang/Analysis/Support/SaveAndRestore.h"
+#include "clang/Analysis/AnalysisContext.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace clang;
+
+//===----------------------------------------------------------------------===//
+// Useful constants.
+//===----------------------------------------------------------------------===//
+
+static const bool Alive = true;
+static const bool Dead = false;
+
+//===----------------------------------------------------------------------===//
+// Dataflow initialization logic.
+//===----------------------------------------------------------------------===//
+
+namespace {
+class RegisterDecls
+  : public CFGRecStmtDeclVisitor<RegisterDecls> {
+
+  LiveVariables::AnalysisDataTy& AD;
+
+  typedef llvm::SmallVector<VarDecl*, 20> AlwaysLiveTy;
+  AlwaysLiveTy AlwaysLive;
+
+
+public:
+  RegisterDecls(LiveVariables::AnalysisDataTy& ad) : AD(ad) {}
+
+  ~RegisterDecls() {
+
+    AD.AlwaysLive.resetValues(AD);
+
+    for (AlwaysLiveTy::iterator I = AlwaysLive.begin(), E = AlwaysLive.end();
+         I != E; ++ I)
+      AD.AlwaysLive(*I, AD) = Alive;
+  }
+
+  void VisitImplicitParamDecl(ImplicitParamDecl* IPD) {
+    // Register the VarDecl for tracking.
+    AD.Register(IPD);
+  }
+
+  void VisitVarDecl(VarDecl* VD) {
+    // Register the VarDecl for tracking.
+    AD.Register(VD);
+
+    // Does the variable have global storage?  If so, it is always live.
+    if (VD->hasGlobalStorage())
+      AlwaysLive.push_back(VD);
+  }
+
+  CFG& getCFG() { return AD.getCFG(); }
+};
+} // end anonymous namespace
+
+LiveVariables::LiveVariables(AnalysisContext &AC) {  
+  // Register all referenced VarDecls.
+  CFG &cfg = *AC.getCFG();
+  getAnalysisData().setCFG(cfg);
+  getAnalysisData().setContext(AC.getASTContext());
+  getAnalysisData().AC = &AC;
+
+  RegisterDecls R(getAnalysisData());
+  cfg.VisitBlockStmts(R);
+
+  // Register all parameters even if they didn't occur in the function body.
+  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(AC.getDecl()))
+    for (FunctionDecl::param_const_iterator PI = FD->param_begin(), 
+           PE = FD->param_end(); PI != PE; ++PI)
+      getAnalysisData().Register(*PI);
+}
+
+//===----------------------------------------------------------------------===//
+// Transfer functions.
+//===----------------------------------------------------------------------===//
+
+namespace {
+
+class TransferFuncs : public CFGRecStmtVisitor<TransferFuncs>{
+  LiveVariables::AnalysisDataTy& AD;
+  LiveVariables::ValTy LiveState;
+public:
+  TransferFuncs(LiveVariables::AnalysisDataTy& ad) : AD(ad) {}
+
+  LiveVariables::ValTy& getVal() { return LiveState; }
+  CFG& getCFG() { return AD.getCFG(); }
+
+  void VisitDeclRefExpr(DeclRefExpr* DR);
+  void VisitBinaryOperator(BinaryOperator* B);
+  void VisitBlockExpr(BlockExpr *B);
+  void VisitAssign(BinaryOperator* B);
+  void VisitDeclStmt(DeclStmt* DS);
+  void BlockStmt_VisitObjCForCollectionStmt(ObjCForCollectionStmt* S);
+  void VisitUnaryOperator(UnaryOperator* U);
+  void Visit(Stmt *S);
+  void VisitTerminator(CFGBlock* B);
+  
+  /// VisitConditionVariableInit - Handle the initialization of condition
+  ///  variables at branches.  Valid statements include IfStmt, ForStmt,
+  ///  WhileStmt, and SwitchStmt.
+  void VisitConditionVariableInit(Stmt *S);
+
+  void SetTopValue(LiveVariables::ValTy& V) {
+    V = AD.AlwaysLive;
+  }
+
+};
+
+void TransferFuncs::Visit(Stmt *S) {
+
+  if (S == getCurrentBlkStmt()) {
+
+    if (AD.Observer)
+      AD.Observer->ObserveStmt(S,AD,LiveState);
+
+    if (getCFG().isBlkExpr(S))
+      LiveState(S, AD) = Dead;
+
+    StmtVisitor<TransferFuncs,void>::Visit(S);
+  }
+  else if (!getCFG().isBlkExpr(S)) {
+
+    if (AD.Observer)
+      AD.Observer->ObserveStmt(S,AD,LiveState);
+
+    StmtVisitor<TransferFuncs,void>::Visit(S);
+
+  }
+  else {
+    // For block-level expressions, mark that they are live.
+    LiveState(S,AD) = Alive;
+  }
+}
+  
+void TransferFuncs::VisitConditionVariableInit(Stmt *S) {
+  assert(!getCFG().isBlkExpr(S));
+  CFGRecStmtVisitor<TransferFuncs>::VisitConditionVariableInit(S);
+}
+
+void TransferFuncs::VisitTerminator(CFGBlock* B) {
+
+  const Stmt* E = B->getTerminatorCondition();
+
+  if (!E)
+    return;
+
+  assert (getCFG().isBlkExpr(E));
+  LiveState(E, AD) = Alive;
+}
+
+void TransferFuncs::VisitDeclRefExpr(DeclRefExpr* DR) {
+  if (VarDecl* V = dyn_cast<VarDecl>(DR->getDecl()))
+    LiveState(V, AD) = Alive;
+}
+  
+void TransferFuncs::VisitBlockExpr(BlockExpr *BE) {
+  AnalysisContext::referenced_decls_iterator I, E;
+  llvm::tie(I, E) = AD.AC->getReferencedBlockVars(BE->getBlockDecl());
+  for ( ; I != E ; ++I) {
+    DeclBitVector_Types::Idx i = AD.getIdx(*I);
+    if (i.isValid())
+      LiveState.getBit(i) = Alive;
+  }
+}
+
+void TransferFuncs::VisitBinaryOperator(BinaryOperator* B) {
+  if (B->isAssignmentOp()) VisitAssign(B);
+  else VisitStmt(B);
+}
+
+void
+TransferFuncs::BlockStmt_VisitObjCForCollectionStmt(ObjCForCollectionStmt* S) {
+
+  // This is a block-level expression.  Its value is 'dead' before this point.
+  LiveState(S, AD) = Dead;
+
+  // This represents a 'use' of the collection.
+  Visit(S->getCollection());
+
+  // This represents a 'kill' for the variable.
+  Stmt* Element = S->getElement();
+  DeclRefExpr* DR = 0;
+  VarDecl* VD = 0;
+
+  if (DeclStmt* DS = dyn_cast<DeclStmt>(Element))
+    VD = cast<VarDecl>(DS->getSingleDecl());
+  else {
+    Expr* ElemExpr = cast<Expr>(Element)->IgnoreParens();
+    if ((DR = dyn_cast<DeclRefExpr>(ElemExpr)))
+      VD = cast<VarDecl>(DR->getDecl());
+    else {
+      Visit(ElemExpr);
+      return;
+    }
+  }
+
+  if (VD) {
+    LiveState(VD, AD) = Dead;
+    if (AD.Observer && DR) { AD.Observer->ObserverKill(DR); }
+  }
+}
+
+
+void TransferFuncs::VisitUnaryOperator(UnaryOperator* U) {
+  Expr *E = U->getSubExpr();
+
+  switch (U->getOpcode()) {
+  case UnaryOperator::PostInc:
+  case UnaryOperator::PostDec:
+  case UnaryOperator::PreInc:
+  case UnaryOperator::PreDec:
+    // Walk through the subexpressions, blasting through ParenExprs
+    // until we either find a DeclRefExpr or some non-DeclRefExpr
+    // expression.
+    if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(E->IgnoreParens()))
+      if (VarDecl* VD = dyn_cast<VarDecl>(DR->getDecl())) {
+        // Treat the --/++ operator as a kill.
+        if (AD.Observer) { AD.Observer->ObserverKill(DR); }
+        LiveState(VD, AD) = Alive;
+        return VisitDeclRefExpr(DR);
+      }
+
+    // Fall-through.
+
+  default:
+    return Visit(E);
+  }
+}
+
+void TransferFuncs::VisitAssign(BinaryOperator* B) {
+  Expr* LHS = B->getLHS();
+
+  // Assigning to a variable?
+  if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(LHS->IgnoreParens())) {
+
+    // Update liveness inforamtion.
+    unsigned bit = AD.getIdx(DR->getDecl());
+    LiveState.getDeclBit(bit) = Dead | AD.AlwaysLive.getDeclBit(bit);
+
+    if (AD.Observer) { AD.Observer->ObserverKill(DR); }
+
+    // Handle things like +=, etc., which also generate "uses"
+    // of a variable.  Do this just by visiting the subexpression.
+    if (B->getOpcode() != BinaryOperator::Assign)
+      VisitDeclRefExpr(DR);
+  }
+  else // Not assigning to a variable.  Process LHS as usual.
+    Visit(LHS);
+
+  Visit(B->getRHS());
+}
+
+void TransferFuncs::VisitDeclStmt(DeclStmt* DS) {
+  // Declarations effectively "kill" a variable since they cannot
+  // possibly be live before they are declared.
+  for (DeclStmt::decl_iterator DI=DS->decl_begin(), DE = DS->decl_end();
+       DI != DE; ++DI)
+    if (VarDecl* VD = dyn_cast<VarDecl>(*DI)) {
+      // Update liveness information by killing the VarDecl.
+      unsigned bit = AD.getIdx(VD);
+      LiveState.getDeclBit(bit) = Dead | AD.AlwaysLive.getDeclBit(bit);
+
+      // The initializer is evaluated after the variable comes into scope, but
+      // before the DeclStmt (which binds the value to the variable).
+      // Since this is a reverse dataflow analysis, we must evaluate the
+      // transfer function for this expression after the DeclStmt.  If the
+      // initializer references the variable (which is bad) then we extend
+      // its liveness.
+      if (Expr* Init = VD->getInit())
+        Visit(Init);
+
+      if (const VariableArrayType* VT =
+            AD.getContext().getAsVariableArrayType(VD->getType())) {
+        StmtIterator I(const_cast<VariableArrayType*>(VT));
+        StmtIterator E;
+        for (; I != E; ++I) Visit(*I);
+      }
+    }
+}
+
+} // end anonymous namespace
+
+//===----------------------------------------------------------------------===//
+// Merge operator: if something is live on any successor block, it is live
+//  in the current block (a set union).
+//===----------------------------------------------------------------------===//
+
+namespace {
+  typedef StmtDeclBitVector_Types::Union Merge;
+  typedef DataflowSolver<LiveVariables, TransferFuncs, Merge> Solver;
+} // end anonymous namespace
+
+//===----------------------------------------------------------------------===//
+// External interface to run Liveness analysis.
+//===----------------------------------------------------------------------===//
+
+void LiveVariables::runOnCFG(CFG& cfg) {
+  Solver S(*this);
+  S.runOnCFG(cfg);
+}
+
+void LiveVariables::runOnAllBlocks(const CFG& cfg,
+                                   LiveVariables::ObserverTy* Obs,
+                                   bool recordStmtValues) {
+  Solver S(*this);
+  SaveAndRestore<LiveVariables::ObserverTy*> SRObs(getAnalysisData().Observer,
+                                                   Obs);
+  S.runOnAllBlocks(cfg, recordStmtValues);
+}
+
+//===----------------------------------------------------------------------===//
+// liveness queries
+//
+
+bool LiveVariables::isLive(const CFGBlock* B, const VarDecl* D) const {
+  DeclBitVector_Types::Idx i = getAnalysisData().getIdx(D);
+  return i.isValid() ? getBlockData(B).getBit(i) : false;
+}
+
+bool LiveVariables::isLive(const ValTy& Live, const VarDecl* D) const {
+  DeclBitVector_Types::Idx i = getAnalysisData().getIdx(D);
+  return i.isValid() ? Live.getBit(i) : false;
+}
+
+bool LiveVariables::isLive(const Stmt* Loc, const Stmt* StmtVal) const {
+  return getStmtData(Loc)(StmtVal,getAnalysisData());
+}
+
+bool LiveVariables::isLive(const Stmt* Loc, const VarDecl* D) const {
+  return getStmtData(Loc)(D,getAnalysisData());
+}
+
+//===----------------------------------------------------------------------===//
+// printing liveness state for debugging
+//
+
+void LiveVariables::dumpLiveness(const ValTy& V, const SourceManager& SM) const {
+  const AnalysisDataTy& AD = getAnalysisData();
+
+  for (AnalysisDataTy::decl_iterator I = AD.begin_decl(),
+                                     E = AD.end_decl(); I!=E; ++I)
+    if (V.getDeclBit(I->second)) {
+      llvm::errs() << "  " << I->first->getIdentifier()->getName() << " <";
+      I->first->getLocation().dump(SM);
+      llvm::errs() << ">\n";
+    }
+}
+
+void LiveVariables::dumpBlockLiveness(const SourceManager& M) const {
+  for (BlockDataMapTy::const_iterator I = getBlockDataMap().begin(),
+       E = getBlockDataMap().end(); I!=E; ++I) {
+    llvm::errs() << "\n[ B" << I->first->getBlockID()
+                 << " (live variables at block exit) ]\n";
+    dumpLiveness(I->second,M);
+  }
+
+  llvm::errs() << "\n";
+}
diff --git a/lib/Analysis/Makefile b/lib/Analysis/Makefile
new file mode 100644
index 0000000..9b47380
--- /dev/null
+++ b/lib/Analysis/Makefile
@@ -0,0 +1,21 @@
+##===- clang/lib/Analysis/Makefile -------------------------*- Makefile -*-===##
+# 
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+# 
+##===----------------------------------------------------------------------===##
+#
+# This implements analyses built on top of source-level CFGs. 
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../../../..
+LIBRARYNAME := clangAnalysis
+BUILD_ARCHIVE = 1
+
+CPP.Flags += -I$(PROJ_SRC_DIR)/../../include -I$(PROJ_OBJ_DIR)/../../include
+
+include $(LEVEL)/Makefile.common
+
diff --git a/lib/Analysis/PrintfFormatString.cpp b/lib/Analysis/PrintfFormatString.cpp
new file mode 100644
index 0000000..c38aae3
--- /dev/null
+++ b/lib/Analysis/PrintfFormatString.cpp
@@ -0,0 +1,584 @@
+//= PrintfFormatStrings.cpp - Analysis of printf format strings --*- C++ -*-==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Handling of format string in printf and friends.  The structure of format
+// strings for fprintf() are described in C99 7.19.6.1.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Analysis/Analyses/PrintfFormatString.h"
+#include "clang/AST/ASTContext.h"
+
+using clang::analyze_printf::ArgTypeResult;
+using clang::analyze_printf::FormatSpecifier;
+using clang::analyze_printf::FormatStringHandler;
+using clang::analyze_printf::OptionalAmount;
+using clang::analyze_printf::PositionContext;
+
+using namespace clang;
+
+namespace {
+class FormatSpecifierResult {
+  FormatSpecifier FS;
+  const char *Start;
+  bool Stop;
+public:
+  FormatSpecifierResult(bool stop = false)
+    : Start(0), Stop(stop) {}
+  FormatSpecifierResult(const char *start,
+                        const FormatSpecifier &fs)
+    : FS(fs), Start(start), Stop(false) {}
+
+
+  const char *getStart() const { return Start; }
+  bool shouldStop() const { return Stop; }
+  bool hasValue() const { return Start != 0; }
+  const FormatSpecifier &getValue() const {
+    assert(hasValue());
+    return FS;
+  }
+  const FormatSpecifier &getValue() { return FS; }
+};
+} // end anonymous namespace
+
+template <typename T>
+class UpdateOnReturn {
+  T &ValueToUpdate;
+  const T &ValueToCopy;
+public:
+  UpdateOnReturn(T &valueToUpdate, const T &valueToCopy)
+    : ValueToUpdate(valueToUpdate), ValueToCopy(valueToCopy) {}
+
+  ~UpdateOnReturn() {
+    ValueToUpdate = ValueToCopy;
+  }
+};
+
+//===----------------------------------------------------------------------===//
+// Methods for parsing format strings.
+//===----------------------------------------------------------------------===//
+
+static OptionalAmount ParseAmount(const char *&Beg, const char *E) {
+  const char *I = Beg;
+  UpdateOnReturn <const char*> UpdateBeg(Beg, I);
+
+  unsigned accumulator = 0;
+  bool hasDigits = false;
+
+  for ( ; I != E; ++I) {
+    char c = *I;
+    if (c >= '0' && c <= '9') {
+      hasDigits = true;
+      accumulator = (accumulator * 10) + (c - '0');
+      continue;
+    }
+
+    if (hasDigits)
+      return OptionalAmount(OptionalAmount::Constant, accumulator, Beg);
+
+    break;
+  }
+
+  return OptionalAmount();
+}
+
+static OptionalAmount ParseNonPositionAmount(const char *&Beg, const char *E,
+                                             unsigned &argIndex) {
+  if (*Beg == '*') {
+    ++Beg;
+    return OptionalAmount(OptionalAmount::Arg, argIndex++, Beg);
+  }
+
+  return ParseAmount(Beg, E);
+}
+
+static OptionalAmount ParsePositionAmount(FormatStringHandler &H,
+                                          const char *Start,
+                                          const char *&Beg, const char *E,
+                                          PositionContext p) {
+  if (*Beg == '*') {
+    const char *I = Beg + 1;
+    const OptionalAmount &Amt = ParseAmount(I, E);
+
+    if (Amt.getHowSpecified() == OptionalAmount::NotSpecified) {
+      H.HandleInvalidPosition(Beg, I - Beg, p);
+      return OptionalAmount(false);
+    }
+
+    if (I== E) {
+      // No more characters left?
+      H.HandleIncompleteFormatSpecifier(Start, E - Start);
+      return OptionalAmount(false);
+    }
+
+    assert(Amt.getHowSpecified() == OptionalAmount::Constant);
+
+    if (*I == '$') {
+      // Special case: '*0$', since this is an easy mistake.
+      if (Amt.getConstantAmount() == 0) {
+        H.HandleZeroPosition(Beg, I - Beg + 1);
+        return OptionalAmount(false);
+      }
+
+      const char *Tmp = Beg;
+      Beg = ++I;
+
+      return OptionalAmount(OptionalAmount::Arg, Amt.getConstantAmount() - 1,
+                            Tmp);
+    }
+
+    H.HandleInvalidPosition(Beg, I - Beg, p);
+    return OptionalAmount(false);
+  }
+
+  return ParseAmount(Beg, E);
+}
+
+static bool ParsePrecision(FormatStringHandler &H, FormatSpecifier &FS,
+                           const char *Start, const char *&Beg, const char *E,
+                           unsigned *argIndex) {
+  if (argIndex) {
+    FS.setPrecision(ParseNonPositionAmount(Beg, E, *argIndex));
+  }
+  else {
+    const OptionalAmount Amt = ParsePositionAmount(H, Start, Beg, E,
+                                                  analyze_printf::PrecisionPos);
+    if (Amt.isInvalid())
+      return true;
+    FS.setPrecision(Amt);
+  }
+  return false;
+}
+
+static bool ParseFieldWidth(FormatStringHandler &H, FormatSpecifier &FS,
+                            const char *Start, const char *&Beg, const char *E,
+                            unsigned *argIndex) {
+  // FIXME: Support negative field widths.
+  if (argIndex) {
+    FS.setFieldWidth(ParseNonPositionAmount(Beg, E, *argIndex));
+  }
+  else {
+    const OptionalAmount Amt = ParsePositionAmount(H, Start, Beg, E,
+                                                 analyze_printf::FieldWidthPos);
+    if (Amt.isInvalid())
+      return true;
+    FS.setFieldWidth(Amt);
+  }
+  return false;
+}
+
+
+static bool ParseArgPosition(FormatStringHandler &H,
+                             FormatSpecifier &FS, const char *Start,
+                             const char *&Beg, const char *E) {
+
+  using namespace clang::analyze_printf;
+  const char *I = Beg;
+
+  const OptionalAmount &Amt = ParseAmount(I, E);
+
+  if (I == E) {
+    // No more characters left?
+    H.HandleIncompleteFormatSpecifier(Start, E - Start);
+    return true;
+  }
+
+  if (Amt.getHowSpecified() == OptionalAmount::Constant && *(I++) == '$') {
+    // Special case: '%0$', since this is an easy mistake.
+    if (Amt.getConstantAmount() == 0) {
+      H.HandleZeroPosition(Start, I - Start);
+      return true;
+    }
+
+    FS.setArgIndex(Amt.getConstantAmount() - 1);
+    FS.setUsesPositionalArg();
+    // Update the caller's pointer if we decided to consume
+    // these characters.
+    Beg = I;
+    return false;
+  }
+
+  return false;
+}
+
+static FormatSpecifierResult ParseFormatSpecifier(FormatStringHandler &H,
+                                                  const char *&Beg,
+                                                  const char *E,
+                                                  unsigned &argIndex) {
+
+  using namespace clang::analyze_printf;
+
+  const char *I = Beg;
+  const char *Start = 0;
+  UpdateOnReturn <const char*> UpdateBeg(Beg, I);
+
+  // Look for a '%' character that indicates the start of a format specifier.
+  for ( ; I != E ; ++I) {
+    char c = *I;
+    if (c == '\0') {
+      // Detect spurious null characters, which are likely errors.
+      H.HandleNullChar(I);
+      return true;
+    }
+    if (c == '%') {
+      Start = I++;  // Record the start of the format specifier.
+      break;
+    }
+  }
+
+  // No format specifier found?
+  if (!Start)
+    return false;
+
+  if (I == E) {
+    // No more characters left?
+    H.HandleIncompleteFormatSpecifier(Start, E - Start);
+    return true;
+  }
+
+  FormatSpecifier FS;
+  if (ParseArgPosition(H, FS, Start, I, E))
+    return true;
+
+  if (I == E) {
+    // No more characters left?
+    H.HandleIncompleteFormatSpecifier(Start, E - Start);
+    return true;
+  }
+
+  // Look for flags (if any).
+  bool hasMore = true;
+  for ( ; I != E; ++I) {
+    switch (*I) {
+      default: hasMore = false; break;
+      case '-': FS.setIsLeftJustified(); break;
+      case '+': FS.setHasPlusPrefix(); break;
+      case ' ': FS.setHasSpacePrefix(); break;
+      case '#': FS.setHasAlternativeForm(); break;
+      case '0': FS.setHasLeadingZeros(); break;
+    }
+    if (!hasMore)
+      break;
+  }
+
+  if (I == E) {
+    // No more characters left?
+    H.HandleIncompleteFormatSpecifier(Start, E - Start);
+    return true;
+  }
+
+  // Look for the field width (if any).
+  if (ParseFieldWidth(H, FS, Start, I, E,
+                      FS.usesPositionalArg() ? 0 : &argIndex))
+    return true;
+
+  if (I == E) {
+    // No more characters left?
+    H.HandleIncompleteFormatSpecifier(Start, E - Start);
+    return true;
+  }
+
+  // Look for the precision (if any).
+  if (*I == '.') {
+    ++I;
+    if (I == E) {
+      H.HandleIncompleteFormatSpecifier(Start, E - Start);
+      return true;
+    }
+
+    if (ParsePrecision(H, FS, Start, I, E,
+                       FS.usesPositionalArg() ? 0 : &argIndex))
+      return true;
+
+    if (I == E) {
+      // No more characters left?
+      H.HandleIncompleteFormatSpecifier(Start, E - Start);
+      return true;
+    }
+  }
+
+  // Look for the length modifier.
+  LengthModifier lm = None;
+  switch (*I) {
+    default:
+      break;
+    case 'h':
+      ++I;
+      lm = (I != E && *I == 'h') ? ++I, AsChar : AsShort;
+      break;
+    case 'l':
+      ++I;
+      lm = (I != E && *I == 'l') ? ++I, AsLongLong : AsLong;
+      break;
+    case 'j': lm = AsIntMax;     ++I; break;
+    case 'z': lm = AsSizeT;      ++I; break;
+    case 't': lm = AsPtrDiff;    ++I; break;
+    case 'L': lm = AsLongDouble; ++I; break;
+    case 'q': lm = AsLongLong;   ++I; break;
+  }
+  FS.setLengthModifier(lm);
+
+  if (I == E) {
+    // No more characters left?
+    H.HandleIncompleteFormatSpecifier(Start, E - Start);
+    return true;
+  }
+
+  if (*I == '\0') {
+    // Detect spurious null characters, which are likely errors.
+    H.HandleNullChar(I);
+    return true;
+  }
+
+  // Finally, look for the conversion specifier.
+  const char *conversionPosition = I++;
+  ConversionSpecifier::Kind k = ConversionSpecifier::InvalidSpecifier;
+  switch (*conversionPosition) {
+    default:
+      break;
+    // C99: 7.19.6.1 (section 8).
+    case '%': k = ConversionSpecifier::PercentArg;   break;
+    case 'A': k = ConversionSpecifier::AArg; break;
+    case 'E': k = ConversionSpecifier::EArg; break;
+    case 'F': k = ConversionSpecifier::FArg; break;
+    case 'G': k = ConversionSpecifier::GArg; break;
+    case 'X': k = ConversionSpecifier::XArg; break;
+    case 'a': k = ConversionSpecifier::aArg; break;
+    case 'c': k = ConversionSpecifier::IntAsCharArg; break;
+    case 'd': k = ConversionSpecifier::dArg; break;
+    case 'e': k = ConversionSpecifier::eArg; break;
+    case 'f': k = ConversionSpecifier::fArg; break;
+    case 'g': k = ConversionSpecifier::gArg; break;
+    case 'i': k = ConversionSpecifier::iArg; break;
+    case 'n': k = ConversionSpecifier::OutIntPtrArg; break;
+    case 'o': k = ConversionSpecifier::oArg; break;
+    case 'p': k = ConversionSpecifier::VoidPtrArg;   break;
+    case 's': k = ConversionSpecifier::CStrArg;      break;
+    case 'u': k = ConversionSpecifier::uArg; break;
+    case 'x': k = ConversionSpecifier::xArg; break;
+    // Mac OS X (unicode) specific
+    case 'C': k = ConversionSpecifier::CArg; break;
+    case 'S': k = ConversionSpecifier::UnicodeStrArg; break;
+    // Objective-C.
+    case '@': k = ConversionSpecifier::ObjCObjArg; break;
+    // Glibc specific.
+    case 'm': k = ConversionSpecifier::PrintErrno; break;
+  }
+  ConversionSpecifier CS(conversionPosition, k);
+  FS.setConversionSpecifier(CS);
+  if (CS.consumesDataArgument() && !FS.usesPositionalArg())
+    FS.setArgIndex(argIndex++);
+
+  if (k == ConversionSpecifier::InvalidSpecifier) {
+    // Assume the conversion takes one argument.
+    return !H.HandleInvalidConversionSpecifier(FS, Beg, I - Beg);
+  }
+  return FormatSpecifierResult(Start, FS);
+}
+
+bool clang::analyze_printf::ParseFormatString(FormatStringHandler &H,
+                       const char *I, const char *E) {
+
+  unsigned argIndex = 0;
+
+  // Keep looking for a format specifier until we have exhausted the string.
+  while (I != E) {
+    const FormatSpecifierResult &FSR = ParseFormatSpecifier(H, I, E, argIndex);
+    // Did a fail-stop error of any kind occur when parsing the specifier?
+    // If so, don't do any more processing.
+    if (FSR.shouldStop())
+      return true;;
+    // Did we exhaust the string or encounter an error that
+    // we can recover from?
+    if (!FSR.hasValue())
+      continue;
+    // We have a format specifier.  Pass it to the callback.
+    if (!H.HandleFormatSpecifier(FSR.getValue(), FSR.getStart(),
+                                 I - FSR.getStart()))
+      return true;
+  }
+  assert(I == E && "Format string not exhausted");
+  return false;
+}
+
+FormatStringHandler::~FormatStringHandler() {}
+
+//===----------------------------------------------------------------------===//
+// Methods on ArgTypeResult.
+//===----------------------------------------------------------------------===//
+
+bool ArgTypeResult::matchesType(ASTContext &C, QualType argTy) const {
+  assert(isValid());
+
+  if (K == UnknownTy)
+    return true;
+
+  if (K == SpecificTy) {
+    argTy = C.getCanonicalType(argTy).getUnqualifiedType();
+
+    if (T == argTy)
+      return true;
+
+    if (const BuiltinType *BT = argTy->getAs<BuiltinType>())
+      switch (BT->getKind()) {
+        default:
+          break;
+        case BuiltinType::Char_S:
+        case BuiltinType::SChar:
+          return T == C.UnsignedCharTy;
+        case BuiltinType::Char_U:
+        case BuiltinType::UChar:
+          return T == C.SignedCharTy;
+        case BuiltinType::Short:
+          return T == C.UnsignedShortTy;
+        case BuiltinType::UShort:
+          return T == C.ShortTy;
+        case BuiltinType::Int:
+          return T == C.UnsignedIntTy;
+        case BuiltinType::UInt:
+          return T == C.IntTy;
+        case BuiltinType::Long:
+          return T == C.UnsignedLongTy;
+        case BuiltinType::ULong:
+          return T == C.LongTy;
+        case BuiltinType::LongLong:
+          return T == C.UnsignedLongLongTy;
+        case BuiltinType::ULongLong:
+          return T == C.LongLongTy;
+      }
+
+    return false;
+  }
+
+  if (K == CStrTy) {
+    const PointerType *PT = argTy->getAs<PointerType>();
+    if (!PT)
+      return false;
+
+    QualType pointeeTy = PT->getPointeeType();
+
+    if (const BuiltinType *BT = pointeeTy->getAs<BuiltinType>())
+      switch (BT->getKind()) {
+        case BuiltinType::Void:
+        case BuiltinType::Char_U:
+        case BuiltinType::UChar:
+        case BuiltinType::Char_S:
+        case BuiltinType::SChar:
+          return true;
+        default:
+          break;
+      }
+
+    return false;
+  }
+
+  if (K == WCStrTy) {
+    const PointerType *PT = argTy->getAs<PointerType>();
+    if (!PT)
+      return false;
+
+    QualType pointeeTy =
+      C.getCanonicalType(PT->getPointeeType()).getUnqualifiedType();
+
+    return pointeeTy == C.getWCharType();
+  }
+
+  return false;
+}
+
+QualType ArgTypeResult::getRepresentativeType(ASTContext &C) const {
+  assert(isValid());
+  if (K == SpecificTy)
+    return T;
+  if (K == CStrTy)
+    return C.getPointerType(C.CharTy);
+  if (K == WCStrTy)
+    return C.getPointerType(C.getWCharType());
+  if (K == ObjCPointerTy)
+    return C.ObjCBuiltinIdTy;
+
+  return QualType();
+}
+
+//===----------------------------------------------------------------------===//
+// Methods on OptionalAmount.
+//===----------------------------------------------------------------------===//
+
+ArgTypeResult OptionalAmount::getArgType(ASTContext &Ctx) const {
+  return Ctx.IntTy;
+}
+
+//===----------------------------------------------------------------------===//
+// Methods on FormatSpecifier.
+//===----------------------------------------------------------------------===//
+
+ArgTypeResult FormatSpecifier::getArgType(ASTContext &Ctx) const {
+  if (!CS.consumesDataArgument())
+    return ArgTypeResult::Invalid();
+
+  if (CS.isIntArg())
+    switch (LM) {
+      case AsLongDouble:
+        return ArgTypeResult::Invalid();
+      case None: return Ctx.IntTy;
+      case AsChar: return Ctx.SignedCharTy;
+      case AsShort: return Ctx.ShortTy;
+      case AsLong: return Ctx.LongTy;
+      case AsLongLong: return Ctx.LongLongTy;
+      case AsIntMax:
+        // FIXME: Return unknown for now.
+        return ArgTypeResult();
+      case AsSizeT: return Ctx.getSizeType();
+      case AsPtrDiff: return Ctx.getPointerDiffType();
+    }
+
+  if (CS.isUIntArg())
+    switch (LM) {
+      case AsLongDouble:
+        return ArgTypeResult::Invalid();
+      case None: return Ctx.UnsignedIntTy;
+      case AsChar: return Ctx.UnsignedCharTy;
+      case AsShort: return Ctx.UnsignedShortTy;
+      case AsLong: return Ctx.UnsignedLongTy;
+      case AsLongLong: return Ctx.UnsignedLongLongTy;
+      case AsIntMax:
+        // FIXME: Return unknown for now.
+        return ArgTypeResult();
+      case AsSizeT:
+        // FIXME: How to get the corresponding unsigned
+        // version of size_t?
+        return ArgTypeResult();
+      case AsPtrDiff:
+        // FIXME: How to get the corresponding unsigned
+        // version of ptrdiff_t?
+        return ArgTypeResult();
+    }
+
+  if (CS.isDoubleArg()) {
+    if (LM == AsLongDouble)
+      return Ctx.LongDoubleTy;
+    return Ctx.DoubleTy;
+  }
+
+  switch (CS.getKind()) {
+    case ConversionSpecifier::CStrArg:
+      return ArgTypeResult(LM == AsWideChar ? ArgTypeResult::WCStrTy                                            : ArgTypeResult::CStrTy);
+    case ConversionSpecifier::UnicodeStrArg:
+      // FIXME: This appears to be Mac OS X specific.
+      return ArgTypeResult::WCStrTy;
+    case ConversionSpecifier::CArg:
+      return Ctx.WCharTy;
+    default:
+      break;
+  }
+
+  // FIXME: Handle other cases.
+  return ArgTypeResult();
+}
+
diff --git a/lib/Analysis/ReachableCode.cpp b/lib/Analysis/ReachableCode.cpp
new file mode 100644
index 0000000..f959e5c
--- /dev/null
+++ b/lib/Analysis/ReachableCode.cpp
@@ -0,0 +1,278 @@
+//=- ReachableCodePathInsensitive.cpp ---------------------------*- C++ --*-==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a flow-sensitive, path-insensitive analysis of
+// determining reachable blocks within a CFG.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/SmallVector.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/StmtCXX.h"
+#include "clang/Analysis/Analyses/ReachableCode.h"
+#include "clang/Analysis/CFG.h"
+#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Basic/SourceManager.h"
+
+using namespace clang;
+
+static SourceLocation GetUnreachableLoc(const CFGBlock &b, SourceRange &R1,
+                                        SourceRange &R2) {
+  const Stmt *S = 0;
+  unsigned sn = 0;
+  R1 = R2 = SourceRange();
+
+top:
+  if (sn < b.size())
+    S = b[sn].getStmt();
+  else if (b.getTerminator())
+    S = b.getTerminator();
+  else
+    return SourceLocation();
+
+  switch (S->getStmtClass()) {
+    case Expr::BinaryOperatorClass: {
+      const BinaryOperator *BO = cast<BinaryOperator>(S);
+      if (BO->getOpcode() == BinaryOperator::Comma) {
+        if (sn+1 < b.size())
+          return b[sn+1].getStmt()->getLocStart();
+        const CFGBlock *n = &b;
+        while (1) {
+          if (n->getTerminator())
+            return n->getTerminator()->getLocStart();
+          if (n->succ_size() != 1)
+            return SourceLocation();
+          n = n[0].succ_begin()[0];
+          if (n->pred_size() != 1)
+            return SourceLocation();
+          if (!n->empty())
+            return n[0][0].getStmt()->getLocStart();
+        }
+      }
+      R1 = BO->getLHS()->getSourceRange();
+      R2 = BO->getRHS()->getSourceRange();
+      return BO->getOperatorLoc();
+    }
+    case Expr::UnaryOperatorClass: {
+      const UnaryOperator *UO = cast<UnaryOperator>(S);
+      R1 = UO->getSubExpr()->getSourceRange();
+      return UO->getOperatorLoc();
+    }
+    case Expr::CompoundAssignOperatorClass: {
+      const CompoundAssignOperator *CAO = cast<CompoundAssignOperator>(S);
+      R1 = CAO->getLHS()->getSourceRange();
+      R2 = CAO->getRHS()->getSourceRange();
+      return CAO->getOperatorLoc();
+    }
+    case Expr::ConditionalOperatorClass: {
+      const ConditionalOperator *CO = cast<ConditionalOperator>(S);
+      return CO->getQuestionLoc();
+    }
+    case Expr::MemberExprClass: {
+      const MemberExpr *ME = cast<MemberExpr>(S);
+      R1 = ME->getSourceRange();
+      return ME->getMemberLoc();
+    }
+    case Expr::ArraySubscriptExprClass: {
+      const ArraySubscriptExpr *ASE = cast<ArraySubscriptExpr>(S);
+      R1 = ASE->getLHS()->getSourceRange();
+      R2 = ASE->getRHS()->getSourceRange();
+      return ASE->getRBracketLoc();
+    }
+    case Expr::CStyleCastExprClass: {
+      const CStyleCastExpr *CSC = cast<CStyleCastExpr>(S);
+      R1 = CSC->getSubExpr()->getSourceRange();
+      return CSC->getLParenLoc();
+    }
+    case Expr::CXXFunctionalCastExprClass: {
+      const CXXFunctionalCastExpr *CE = cast <CXXFunctionalCastExpr>(S);
+      R1 = CE->getSubExpr()->getSourceRange();
+      return CE->getTypeBeginLoc();
+    }
+    case Expr::ImplicitCastExprClass:
+      ++sn;
+      goto top;
+    case Stmt::CXXTryStmtClass: {
+      return cast<CXXTryStmt>(S)->getHandler(0)->getCatchLoc();
+    }
+    default: ;
+  }
+  R1 = S->getSourceRange();
+  return S->getLocStart();
+}
+
+static SourceLocation MarkLiveTop(const CFGBlock *Start,
+                                  llvm::BitVector &reachable,
+                                  SourceManager &SM) {
+
+  // Prep work worklist.
+  llvm::SmallVector<const CFGBlock*, 32> WL;
+  WL.push_back(Start);
+
+  SourceRange R1, R2;
+  SourceLocation top = GetUnreachableLoc(*Start, R1, R2);
+
+  bool FromMainFile = false;
+  bool FromSystemHeader = false;
+  bool TopValid = false;
+
+  if (top.isValid()) {
+    FromMainFile = SM.isFromMainFile(top);
+    FromSystemHeader = SM.isInSystemHeader(top);
+    TopValid = true;
+  }
+
+  // Solve
+  while (!WL.empty()) {
+    const CFGBlock *item = WL.back();
+    WL.pop_back();
+
+    SourceLocation c = GetUnreachableLoc(*item, R1, R2);
+    if (c.isValid()
+        && (!TopValid
+            || (SM.isFromMainFile(c) && !FromMainFile)
+            || (FromSystemHeader && !SM.isInSystemHeader(c))
+            || SM.isBeforeInTranslationUnit(c, top))) {
+          top = c;
+          FromMainFile = SM.isFromMainFile(top);
+          FromSystemHeader = SM.isInSystemHeader(top);
+        }
+
+    reachable.set(item->getBlockID());
+    for (CFGBlock::const_succ_iterator I=item->succ_begin(), E=item->succ_end();
+         I != E; ++I)
+      if (const CFGBlock *B = *I) {
+        unsigned blockID = B->getBlockID();
+        if (!reachable[blockID]) {
+          reachable.set(blockID);
+          WL.push_back(B);
+        }
+      }
+  }
+
+  return top;
+}
+
+static int LineCmp(const void *p1, const void *p2) {
+  SourceLocation *Line1 = (SourceLocation *)p1;
+  SourceLocation *Line2 = (SourceLocation *)p2;
+  return !(*Line1 < *Line2);
+}
+
+namespace {
+struct ErrLoc {
+  SourceLocation Loc;
+  SourceRange R1;
+  SourceRange R2;
+  ErrLoc(SourceLocation l, SourceRange r1, SourceRange r2)
+  : Loc(l), R1(r1), R2(r2) { }
+};
+}
+namespace clang { namespace reachable_code {
+
+/// ScanReachableFromBlock - Mark all blocks reachable from Start.
+/// Returns the total number of blocks that were marked reachable.
+unsigned ScanReachableFromBlock(const CFGBlock &Start,
+                                llvm::BitVector &Reachable) {
+  unsigned count = 0;
+  llvm::SmallVector<const CFGBlock*, 32> WL;
+
+    // Prep work queue
+  Reachable.set(Start.getBlockID());
+  ++count;
+  WL.push_back(&Start);
+
+    // Find the reachable blocks from 'Start'.
+  while (!WL.empty()) {
+    const CFGBlock *item = WL.back();
+    WL.pop_back();
+
+      // Look at the successors and mark then reachable.
+    for (CFGBlock::const_succ_iterator I=item->succ_begin(), E=item->succ_end();
+         I != E; ++I)
+      if (const CFGBlock *B = *I) {
+        unsigned blockID = B->getBlockID();
+        if (!Reachable[blockID]) {
+          Reachable.set(blockID);
+          ++count;
+          WL.push_back(B);
+        }
+      }
+  }
+  return count;
+}
+
+void FindUnreachableCode(AnalysisContext &AC, Callback &CB) {
+  CFG *cfg = AC.getCFG();
+  if (!cfg)
+    return;
+
+  // Scan for reachable blocks.
+  llvm::BitVector reachable(cfg->getNumBlockIDs());
+  unsigned numReachable = ScanReachableFromBlock(cfg->getEntry(), reachable);
+
+    // If there are no unreachable blocks, we're done.
+  if (numReachable == cfg->getNumBlockIDs())
+    return;
+
+  SourceRange R1, R2;
+
+  llvm::SmallVector<ErrLoc, 24> lines;
+  bool AddEHEdges = AC.getAddEHEdges();
+
+  // First, give warnings for blocks with no predecessors, as they
+  // can't be part of a loop.
+  for (CFG::iterator I = cfg->begin(), E = cfg->end(); I != E; ++I) {
+    CFGBlock &b = **I;
+    if (!reachable[b.getBlockID()]) {
+      if (b.pred_empty()) {
+        if (!AddEHEdges && dyn_cast_or_null<CXXTryStmt>(b.getTerminator())) {
+            // When not adding EH edges from calls, catch clauses
+            // can otherwise seem dead.  Avoid noting them as dead.
+          numReachable += ScanReachableFromBlock(b, reachable);
+          continue;
+        }
+        SourceLocation c = GetUnreachableLoc(b, R1, R2);
+        if (!c.isValid()) {
+            // Blocks without a location can't produce a warning, so don't mark
+            // reachable blocks from here as live.
+          reachable.set(b.getBlockID());
+          ++numReachable;
+          continue;
+        }
+        lines.push_back(ErrLoc(c, R1, R2));
+          // Avoid excessive errors by marking everything reachable from here
+        numReachable += ScanReachableFromBlock(b, reachable);
+      }
+    }
+  }
+
+  if (numReachable < cfg->getNumBlockIDs()) {
+      // And then give warnings for the tops of loops.
+    for (CFG::iterator I = cfg->begin(), E = cfg->end(); I != E; ++I) {
+      CFGBlock &b = **I;
+      if (!reachable[b.getBlockID()])
+          // Avoid excessive errors by marking everything reachable from here
+        lines.push_back(ErrLoc(MarkLiveTop(&b, reachable,
+                                         AC.getASTContext().getSourceManager()),
+                               SourceRange(), SourceRange()));
+    }
+  }
+
+  llvm::array_pod_sort(lines.begin(), lines.end(), LineCmp);
+
+  for (llvm::SmallVectorImpl<ErrLoc>::iterator I=lines.begin(), E=lines.end();
+       I != E; ++I)
+    if (I->Loc.isValid())
+      CB.HandleUnreachable(I->Loc, I->R1, I->R2);
+}
+
+}} // end namespace clang::reachable_code
diff --git a/lib/Analysis/UninitializedValues.cpp b/lib/Analysis/UninitializedValues.cpp
new file mode 100644
index 0000000..7a62864
--- /dev/null
+++ b/lib/Analysis/UninitializedValues.cpp
@@ -0,0 +1,314 @@
+//==- UninitializedValues.cpp - Find Uninitialized Values -------*- C++ --*-==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements Uninitialized Values analysis for source-level CFGs.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Analysis/Analyses/UninitializedValues.h"
+#include "clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h"
+#include "clang/Analysis/AnalysisDiagnostic.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/Analysis/FlowSensitive/DataflowSolver.h"
+
+#include "llvm/ADT/SmallPtrSet.h"
+
+using namespace clang;
+
+//===----------------------------------------------------------------------===//
+// Dataflow initialization logic.
+//===----------------------------------------------------------------------===//
+
+namespace {
+
+class RegisterDecls
+  : public CFGRecStmtDeclVisitor<RegisterDecls> {
+
+  UninitializedValues::AnalysisDataTy& AD;
+public:
+  RegisterDecls(UninitializedValues::AnalysisDataTy& ad) :  AD(ad) {}
+
+  void VisitVarDecl(VarDecl* VD) { AD.Register(VD); }
+  CFG& getCFG() { return AD.getCFG(); }
+};
+
+} // end anonymous namespace
+
+void UninitializedValues::InitializeValues(const CFG& cfg) {
+  RegisterDecls R(getAnalysisData());
+  cfg.VisitBlockStmts(R);
+}
+
+//===----------------------------------------------------------------------===//
+// Transfer functions.
+//===----------------------------------------------------------------------===//
+
+namespace {
+class TransferFuncs
+  : public CFGStmtVisitor<TransferFuncs,bool> {
+
+  UninitializedValues::ValTy V;
+  UninitializedValues::AnalysisDataTy& AD;
+public:
+  TransferFuncs(UninitializedValues::AnalysisDataTy& ad) : AD(ad) {}
+
+  UninitializedValues::ValTy& getVal() { return V; }
+  CFG& getCFG() { return AD.getCFG(); }
+
+  void SetTopValue(UninitializedValues::ValTy& X) {
+    X.setDeclValues(AD);
+    X.resetBlkExprValues(AD);
+  }
+
+  bool VisitDeclRefExpr(DeclRefExpr* DR);
+  bool VisitBinaryOperator(BinaryOperator* B);
+  bool VisitUnaryOperator(UnaryOperator* U);
+  bool VisitStmt(Stmt* S);
+  bool VisitCallExpr(CallExpr* C);
+  bool VisitDeclStmt(DeclStmt* D);
+  bool VisitConditionalOperator(ConditionalOperator* C);
+  bool BlockStmt_VisitObjCForCollectionStmt(ObjCForCollectionStmt* S);
+
+  bool Visit(Stmt *S);
+  bool BlockStmt_VisitExpr(Expr* E);
+
+  void VisitTerminator(CFGBlock* B) { }
+};
+
+static const bool Initialized = false;
+static const bool Uninitialized = true;
+
+bool TransferFuncs::VisitDeclRefExpr(DeclRefExpr* DR) {
+
+  if (VarDecl* VD = dyn_cast<VarDecl>(DR->getDecl()))
+    if (VD->isBlockVarDecl()) {
+
+      if (AD.Observer)
+        AD.Observer->ObserveDeclRefExpr(V, AD, DR, VD);
+
+      // Pseudo-hack to prevent cascade of warnings.  If an accessed variable
+      // is uninitialized, then we are already going to flag a warning for
+      // this variable, which a "source" of uninitialized values.
+      // We can otherwise do a full "taint" of uninitialized values.  The
+      // client has both options by toggling AD.FullUninitTaint.
+
+      if (AD.FullUninitTaint)
+        return V(VD,AD);
+    }
+
+  return Initialized;
+}
+
+static VarDecl* FindBlockVarDecl(Expr* E) {
+
+  // Blast through casts and parentheses to find any DeclRefExprs that
+  // refer to a block VarDecl.
+
+  if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(E->IgnoreParenCasts()))
+    if (VarDecl* VD = dyn_cast<VarDecl>(DR->getDecl()))
+      if (VD->isBlockVarDecl()) return VD;
+
+  return NULL;
+}
+
+bool TransferFuncs::VisitBinaryOperator(BinaryOperator* B) {
+
+  if (VarDecl* VD = FindBlockVarDecl(B->getLHS()))
+    if (B->isAssignmentOp()) {
+      if (B->getOpcode() == BinaryOperator::Assign)
+        return V(VD,AD) = Visit(B->getRHS());
+      else // Handle +=, -=, *=, etc.  We do want '&', not '&&'.
+        return V(VD,AD) = Visit(B->getLHS()) & Visit(B->getRHS());
+    }
+
+  return VisitStmt(B);
+}
+
+bool TransferFuncs::VisitDeclStmt(DeclStmt* S) {
+  for (DeclStmt::decl_iterator I=S->decl_begin(), E=S->decl_end(); I!=E; ++I) {
+    VarDecl *VD = dyn_cast<VarDecl>(*I);
+    if (VD && VD->isBlockVarDecl()) {
+      if (Stmt* I = VD->getInit()) {
+        // Visit the subexpression to check for uses of uninitialized values,
+        // even if we don't propagate that value.
+        bool isSubExprUninit = Visit(I);
+        V(VD,AD) = AD.FullUninitTaint ? isSubExprUninit : Initialized;
+      }
+      else {
+        // Special case for declarations of array types.  For things like:
+        //
+        //  char x[10];
+        //
+        // we should treat "x" as being initialized, because the variable
+        // "x" really refers to the memory block.  Clearly x[1] is
+        // uninitialized, but expressions like "(char *) x" really do refer to
+        // an initialized value.  This simple dataflow analysis does not reason
+        // about the contents of arrays, although it could be potentially
+        // extended to do so if the array were of constant size.
+        if (VD->getType()->isArrayType())
+          V(VD,AD) = Initialized;
+        else
+          V(VD,AD) = Uninitialized;
+      }
+    }
+  }
+  return Uninitialized; // Value is never consumed.
+}
+
+bool TransferFuncs::VisitCallExpr(CallExpr* C) {
+  VisitChildren(C);
+  return Initialized;
+}
+
+bool TransferFuncs::VisitUnaryOperator(UnaryOperator* U) {
+  switch (U->getOpcode()) {
+    case UnaryOperator::AddrOf: {
+      VarDecl* VD = FindBlockVarDecl(U->getSubExpr());
+      if (VD && VD->isBlockVarDecl())
+        return V(VD,AD) = Initialized;
+      break;
+    }
+
+    default:
+      break;
+  }
+
+  return Visit(U->getSubExpr());
+}
+
+bool
+TransferFuncs::BlockStmt_VisitObjCForCollectionStmt(ObjCForCollectionStmt* S) {
+  // This represents a use of the 'collection'
+  bool x = Visit(S->getCollection());
+
+  if (x == Uninitialized)
+    return Uninitialized;
+
+  // This represents an initialization of the 'element' value.
+  Stmt* Element = S->getElement();
+  VarDecl* VD = 0;
+
+  if (DeclStmt* DS = dyn_cast<DeclStmt>(Element))
+    VD = cast<VarDecl>(DS->getSingleDecl());
+  else {
+    Expr* ElemExpr = cast<Expr>(Element)->IgnoreParens();
+
+    // Initialize the value of the reference variable.
+    if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(ElemExpr))
+      VD = cast<VarDecl>(DR->getDecl());
+    else
+      return Visit(ElemExpr);
+  }
+
+  V(VD,AD) = Initialized;
+  return Initialized;
+}
+
+
+bool TransferFuncs::VisitConditionalOperator(ConditionalOperator* C) {
+  Visit(C->getCond());
+
+  bool rhsResult = Visit(C->getRHS());
+  // Handle the GNU extension for missing LHS.
+  if (Expr *lhs = C->getLHS())
+    return Visit(lhs) & rhsResult; // Yes: we want &, not &&.
+  else
+    return rhsResult;
+}
+
+bool TransferFuncs::VisitStmt(Stmt* S) {
+  bool x = Initialized;
+
+  // We don't stop at the first subexpression that is Uninitialized because
+  // evaluating some subexpressions may result in propogating "Uninitialized"
+  // or "Initialized" to variables referenced in the other subexpressions.
+  for (Stmt::child_iterator I=S->child_begin(), E=S->child_end(); I!=E; ++I)
+    if (*I && Visit(*I) == Uninitialized) x = Uninitialized;
+
+  return x;
+}
+
+bool TransferFuncs::Visit(Stmt *S) {
+  if (AD.isTracked(static_cast<Expr*>(S))) return V(static_cast<Expr*>(S),AD);
+  else return static_cast<CFGStmtVisitor<TransferFuncs,bool>*>(this)->Visit(S);
+}
+
+bool TransferFuncs::BlockStmt_VisitExpr(Expr* E) {
+  bool x = static_cast<CFGStmtVisitor<TransferFuncs,bool>*>(this)->Visit(E);
+  if (AD.isTracked(E)) V(E,AD) = x;
+  return x;
+}
+
+} // end anonymous namespace
+
+//===----------------------------------------------------------------------===//
+// Merge operator.
+//
+//  In our transfer functions we take the approach that any
+//  combination of uninitialized values, e.g.
+//      Uninitialized + ___ = Uninitialized.
+//
+//  Merges take the same approach, preferring soundness.  At a confluence point,
+//  if any predecessor has a variable marked uninitialized, the value is
+//  uninitialized at the confluence point.
+//===----------------------------------------------------------------------===//
+
+namespace {
+  typedef StmtDeclBitVector_Types::Union Merge;
+  typedef DataflowSolver<UninitializedValues,TransferFuncs,Merge> Solver;
+}
+
+//===----------------------------------------------------------------------===//
+// Uninitialized values checker.   Scan an AST and flag variable uses
+//===----------------------------------------------------------------------===//
+
+UninitializedValues_ValueTypes::ObserverTy::~ObserverTy() {}
+
+namespace {
+class UninitializedValuesChecker
+  : public UninitializedValues::ObserverTy {
+
+  ASTContext &Ctx;
+  Diagnostic &Diags;
+  llvm::SmallPtrSet<VarDecl*,10> AlreadyWarned;
+
+public:
+  UninitializedValuesChecker(ASTContext &ctx, Diagnostic &diags)
+    : Ctx(ctx), Diags(diags) {}
+
+  virtual void ObserveDeclRefExpr(UninitializedValues::ValTy& V,
+                                  UninitializedValues::AnalysisDataTy& AD,
+                                  DeclRefExpr* DR, VarDecl* VD) {
+
+    assert ( AD.isTracked(VD) && "Unknown VarDecl.");
+
+    if (V(VD,AD) == Uninitialized)
+      if (AlreadyWarned.insert(VD))
+        Diags.Report(Ctx.getFullLoc(DR->getSourceRange().getBegin()),
+                     diag::warn_uninit_val);
+  }
+};
+} // end anonymous namespace
+
+namespace clang {
+void CheckUninitializedValues(CFG& cfg, ASTContext &Ctx, Diagnostic &Diags,
+                              bool FullUninitTaint) {
+
+  // Compute the uninitialized values information.
+  UninitializedValues U(cfg);
+  U.getAnalysisData().FullUninitTaint = FullUninitTaint;
+  Solver S(U);
+  S.runOnCFG(cfg);
+
+  // Scan for DeclRefExprs that use uninitialized values.
+  UninitializedValuesChecker Observer(Ctx,Diags);
+  U.getAnalysisData().Observer = &Observer;
+  S.runOnAllBlocks(cfg);
+}
+} // end namespace clang
diff --git a/lib/Basic/Android.mk b/lib/Basic/Android.mk
new file mode 100644
index 0000000..128c258
--- /dev/null
+++ b/lib/Basic/Android.mk
@@ -0,0 +1,38 @@
+LOCAL_PATH:= $(call my-dir)
+
+# For the host only
+# =====================================================
+include $(CLEAR_VARS)
+include $(CLEAR_TBLGEN_VARS)
+
+TBLGEN_TABLES :=    \
+	DiagnosticGroups.inc	\
+	DiagnosticASTKinds.inc	\
+	DiagnosticLexKinds.inc	\
+	DiagnosticSemaKinds.inc	\
+    DiagnosticCommonKinds.inc	\
+	DiagnosticDriverKinds.inc	\
+	DiagnosticParseKinds.inc	\
+	DiagnosticAnalysisKinds.inc	\
+	DiagnosticFrontendKinds.inc
+
+clang_basic_SRC_FILES :=	\
+	Builtins.cpp	\
+	ConvertUTF.c	\
+	Diagnostic.cpp	\
+	FileManager.cpp	\
+	IdentifierTable.cpp	\
+	SourceLocation.cpp	\
+	SourceManager.cpp	\
+	TargetInfo.cpp	\
+	Targets.cpp	\
+	TokenKinds.cpp	\
+	Version.cpp
+
+LOCAL_SRC_FILES := $(clang_basic_SRC_FILES)
+
+LOCAL_MODULE:= libclangBasic
+
+include $(CLANG_HOST_BUILD_MK)
+include $(CLANG_TBLGEN_RULES_MK)
+include $(BUILD_HOST_STATIC_LIBRARY)
diff --git a/lib/Basic/Builtins.cpp b/lib/Basic/Builtins.cpp
new file mode 100644
index 0000000..1a32937
--- /dev/null
+++ b/lib/Basic/Builtins.cpp
@@ -0,0 +1,95 @@
+//===--- Builtins.cpp - Builtin function implementation -------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements various things for builtin functions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Basic/Builtins.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/TargetInfo.h"
+using namespace clang;
+
+static const Builtin::Info BuiltinInfo[] = {
+  { "not a builtin function", 0, 0, 0, false },
+#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, false },
+#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER, false },
+#include "clang/Basic/Builtins.def"
+};
+
+const Builtin::Info &Builtin::Context::GetRecord(unsigned ID) const {
+  if (ID < Builtin::FirstTSBuiltin)
+    return BuiltinInfo[ID];
+  assert(ID - Builtin::FirstTSBuiltin < NumTSRecords && "Invalid builtin ID!");
+  return TSRecords[ID - Builtin::FirstTSBuiltin];
+}
+
+Builtin::Context::Context(const TargetInfo &Target) {
+  // Get the target specific builtins from the target.
+  TSRecords = 0;
+  NumTSRecords = 0;
+  Target.getTargetBuiltins(TSRecords, NumTSRecords);
+}
+
+/// InitializeBuiltins - Mark the identifiers for all the builtins with their
+/// appropriate builtin ID # and mark any non-portable builtin identifiers as
+/// such.
+void Builtin::Context::InitializeBuiltins(IdentifierTable &Table,
+                                          bool NoBuiltins) {
+  // Step #1: mark all target-independent builtins with their ID's.
+  for (unsigned i = Builtin::NotBuiltin+1; i != Builtin::FirstTSBuiltin; ++i)
+    if (!BuiltinInfo[i].Suppressed &&
+        (!NoBuiltins || !strchr(BuiltinInfo[i].Attributes, 'f')))
+      Table.get(BuiltinInfo[i].Name).setBuiltinID(i);
+
+  // Step #2: Register target-specific builtins.
+  for (unsigned i = 0, e = NumTSRecords; i != e; ++i)
+    if (!TSRecords[i].Suppressed &&
+        (!NoBuiltins ||
+         (TSRecords[i].Attributes &&
+          !strchr(TSRecords[i].Attributes, 'f'))))
+      Table.get(TSRecords[i].Name).setBuiltinID(i+Builtin::FirstTSBuiltin);
+}
+
+void
+Builtin::Context::GetBuiltinNames(llvm::SmallVectorImpl<const char *> &Names,
+                                  bool NoBuiltins) {
+  // Final all target-independent names
+  for (unsigned i = Builtin::NotBuiltin+1; i != Builtin::FirstTSBuiltin; ++i)
+    if (!BuiltinInfo[i].Suppressed &&
+        (!NoBuiltins || !strchr(BuiltinInfo[i].Attributes, 'f')))
+      Names.push_back(BuiltinInfo[i].Name);
+
+  // Find target-specific names.
+  for (unsigned i = 0, e = NumTSRecords; i != e; ++i)
+    if (!TSRecords[i].Suppressed &&
+        (!NoBuiltins ||
+         (TSRecords[i].Attributes &&
+          !strchr(TSRecords[i].Attributes, 'f'))))
+      Names.push_back(TSRecords[i].Name);
+}
+
+bool
+Builtin::Context::isPrintfLike(unsigned ID, unsigned &FormatIdx,
+                               bool &HasVAListArg) {
+  const char *Printf = strpbrk(GetRecord(ID).Attributes, "pP");
+  if (!Printf)
+    return false;
+
+  HasVAListArg = (*Printf == 'P');
+
+  ++Printf;
+  assert(*Printf == ':' && "p or P specifier must have be followed by a ':'");
+  ++Printf;
+
+  assert(strchr(Printf, ':') && "printf specifier must end with a ':'");
+  FormatIdx = strtol(Printf, 0, 10);
+  return true;
+}
+
diff --git a/lib/Basic/CMakeLists.txt b/lib/Basic/CMakeLists.txt
new file mode 100644
index 0000000..1a89acc
--- /dev/null
+++ b/lib/Basic/CMakeLists.txt
@@ -0,0 +1,36 @@
+set(LLVM_NO_RTTI 1)
+
+add_clang_library(clangBasic
+  Builtins.cpp
+  ConvertUTF.c
+  Diagnostic.cpp
+  FileManager.cpp
+  IdentifierTable.cpp
+  SourceLocation.cpp
+  SourceManager.cpp
+  TargetInfo.cpp
+  Targets.cpp
+  TokenKinds.cpp
+  Version.cpp
+  )
+
+# Determine Subversion revision.
+# FIXME: This only gets updated when CMake is run, so this revision number
+# may be out-of-date!
+find_package(Subversion)
+if (Subversion_FOUND AND EXISTS "${CLANG_SOURCE_DIR}/.svn")
+  Subversion_WC_INFO(${CLANG_SOURCE_DIR} CLANG)
+  set_source_files_properties(Version.cpp
+    PROPERTIES COMPILE_DEFINITIONS "SVN_REVISION=\"${CLANG_WC_REVISION}\"")
+endif()
+
+add_dependencies(clangBasic 
+                 ClangDiagnosticAnalysis
+                 ClangDiagnosticAST
+                 ClangDiagnosticCommon
+                 ClangDiagnosticDriver
+                 ClangDiagnosticFrontend
+                 ClangDiagnosticGroups
+                 ClangDiagnosticLex
+                 ClangDiagnosticParse
+                 ClangDiagnosticSema)
diff --git a/lib/Basic/ConvertUTF.c b/lib/Basic/ConvertUTF.c
new file mode 100644
index 0000000..124e386
--- /dev/null
+++ b/lib/Basic/ConvertUTF.c
@@ -0,0 +1,547 @@
+/*===--- ConvertUTF.c - Universal Character Names conversions ---------------===
+ *
+ *                     The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ *===------------------------------------------------------------------------=*/
+/*
+ * Copyright 2001-2004 Unicode, Inc.
+ * 
+ * Disclaimer
+ * 
+ * This source code is provided as is by Unicode, Inc. No claims are
+ * made as to fitness for any particular purpose. No warranties of any
+ * kind are expressed or implied. The recipient agrees to determine
+ * applicability of information provided. If this file has been
+ * purchased on magnetic or optical media from Unicode, Inc., the
+ * sole remedy for any claim will be exchange of defective media
+ * within 90 days of receipt.
+ * 
+ * Limitations on Rights to Redistribute This Code
+ * 
+ * Unicode, Inc. hereby grants the right to freely use the information
+ * supplied in this file in the creation of products supporting the
+ * Unicode Standard, and to make copies of this file in any form
+ * for internal or external distribution as long as this notice
+ * remains attached.
+ */
+
+/* ---------------------------------------------------------------------
+
+    Conversions between UTF32, UTF-16, and UTF-8. Source code file.
+    Author: Mark E. Davis, 1994.
+    Rev History: Rick McGowan, fixes & updates May 2001.
+    Sept 2001: fixed const & error conditions per
+        mods suggested by S. Parent & A. Lillich.
+    June 2002: Tim Dodd added detection and handling of incomplete
+        source sequences, enhanced error detection, added casts
+        to eliminate compiler warnings.
+    July 2003: slight mods to back out aggressive FFFE detection.
+    Jan 2004: updated switches in from-UTF8 conversions.
+    Oct 2004: updated to use UNI_MAX_LEGAL_UTF32 in UTF-32 conversions.
+
+    See the header file "ConvertUTF.h" for complete documentation.
+
+------------------------------------------------------------------------ */
+
+
+#include "clang/Basic/ConvertUTF.h"
+#ifdef CVTUTF_DEBUG
+#include <stdio.h>
+#endif
+
+static const int halfShift  = 10; /* used for shifting by 10 bits */
+
+static const UTF32 halfBase = 0x0010000UL;
+static const UTF32 halfMask = 0x3FFUL;
+
+#define UNI_SUR_HIGH_START  (UTF32)0xD800
+#define UNI_SUR_HIGH_END    (UTF32)0xDBFF
+#define UNI_SUR_LOW_START   (UTF32)0xDC00
+#define UNI_SUR_LOW_END     (UTF32)0xDFFF
+#define false      0
+#define true        1
+
+/* --------------------------------------------------------------------- */
+
+/*
+ * Index into the table below with the first byte of a UTF-8 sequence to
+ * get the number of trailing bytes that are supposed to follow it.
+ * Note that *legal* UTF-8 values can't have 4 or 5-bytes. The table is
+ * left as-is for anyone who may want to do such conversion, which was
+ * allowed in earlier algorithms.
+ */
+static const char trailingBytesForUTF8[256] = {
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+    2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5
+};
+
+/*
+ * Magic values subtracted from a buffer value during UTF8 conversion.
+ * This table contains as many values as there might be trailing bytes
+ * in a UTF-8 sequence.
+ */
+static const UTF32 offsetsFromUTF8[6] = { 0x00000000UL, 0x00003080UL, 0x000E2080UL, 
+                     0x03C82080UL, 0xFA082080UL, 0x82082080UL };
+
+/*
+ * Once the bits are split out into bytes of UTF-8, this is a mask OR-ed
+ * into the first byte, depending on how many bytes follow.  There are
+ * as many entries in this table as there are UTF-8 sequence types.
+ * (I.e., one byte sequence, two byte... etc.). Remember that sequencs
+ * for *legal* UTF-8 will be 4 or fewer bytes total.
+ */
+static const UTF8 firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
+
+/* --------------------------------------------------------------------- */
+
+/* The interface converts a whole buffer to avoid function-call overhead.
+ * Constants have been gathered. Loops & conditionals have been removed as
+ * much as possible for efficiency, in favor of drop-through switches.
+ * (See "Note A" at the bottom of the file for equivalent code.)
+ * If your compiler supports it, the "isLegalUTF8" call can be turned
+ * into an inline function.
+ */
+
+#ifdef CLANG_NEEDS_THESE_ONE_DAY
+
+/* --------------------------------------------------------------------- */
+
+ConversionResult ConvertUTF32toUTF16 (
+        const UTF32** sourceStart, const UTF32* sourceEnd, 
+        UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) {
+    ConversionResult result = conversionOK;
+    const UTF32* source = *sourceStart;
+    UTF16* target = *targetStart;
+    while (source < sourceEnd) {
+        UTF32 ch;
+        if (target >= targetEnd) {
+            result = targetExhausted; break;
+        }
+        ch = *source++;
+        if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */
+            /* UTF-16 surrogate values are illegal in UTF-32; 0xffff or 0xfffe are both reserved values */
+            if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
+                if (flags == strictConversion) {
+                    --source; /* return to the illegal value itself */
+                    result = sourceIllegal;
+                    break;
+                } else {
+                    *target++ = UNI_REPLACEMENT_CHAR;
+                }
+            } else {
+                *target++ = (UTF16)ch; /* normal case */
+            }
+        } else if (ch > UNI_MAX_LEGAL_UTF32) {
+            if (flags == strictConversion) {
+                result = sourceIllegal;
+            } else {
+                *target++ = UNI_REPLACEMENT_CHAR;
+            }
+        } else {
+            /* target is a character in range 0xFFFF - 0x10FFFF. */
+            if (target + 1 >= targetEnd) {
+                --source; /* Back up source pointer! */
+                result = targetExhausted; break;
+            }
+            ch -= halfBase;
+            *target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START);
+            *target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START);
+        }
+    }
+    *sourceStart = source;
+    *targetStart = target;
+    return result;
+}
+
+/* --------------------------------------------------------------------- */
+
+ConversionResult ConvertUTF16toUTF32 (
+        const UTF16** sourceStart, const UTF16* sourceEnd, 
+        UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags) {
+    ConversionResult result = conversionOK;
+    const UTF16* source = *sourceStart;
+    UTF32* target = *targetStart;
+    UTF32 ch, ch2;
+    while (source < sourceEnd) {
+        const UTF16* oldSource = source; /*  In case we have to back up because of target overflow. */
+        ch = *source++;
+        /* If we have a surrogate pair, convert to UTF32 first. */
+        if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) {
+            /* If the 16 bits following the high surrogate are in the source buffer... */
+            if (source < sourceEnd) {
+                ch2 = *source;
+                /* If it's a low surrogate, convert to UTF32. */
+                if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) {
+                    ch = ((ch - UNI_SUR_HIGH_START) << halfShift)
+                        + (ch2 - UNI_SUR_LOW_START) + halfBase;
+                    ++source;
+                } else if (flags == strictConversion) { /* it's an unpaired high surrogate */
+                    --source; /* return to the illegal value itself */
+                    result = sourceIllegal;
+                    break;
+                }
+            } else { /* We don't have the 16 bits following the high surrogate. */
+                --source; /* return to the high surrogate */
+                result = sourceExhausted;
+                break;
+            }
+        } else if (flags == strictConversion) {
+            /* UTF-16 surrogate values are illegal in UTF-32 */
+            if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) {
+                --source; /* return to the illegal value itself */
+                result = sourceIllegal;
+                break;
+            }
+        }
+        if (target >= targetEnd) {
+            source = oldSource; /* Back up source pointer! */
+            result = targetExhausted; break;
+        }
+        *target++ = ch;
+    }
+    *sourceStart = source;
+    *targetStart = target;
+#ifdef CVTUTF_DEBUG
+if (result == sourceIllegal) {
+    fprintf(stderr, "ConvertUTF16toUTF32 illegal seq 0x%04x,%04x\n", ch, ch2);
+    fflush(stderr);
+}
+#endif
+    return result;
+}
+ConversionResult ConvertUTF16toUTF8 (
+        const UTF16** sourceStart, const UTF16* sourceEnd, 
+        UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags) {
+    ConversionResult result = conversionOK;
+    const UTF16* source = *sourceStart;
+    UTF8* target = *targetStart;
+    while (source < sourceEnd) {
+        UTF32 ch;
+        unsigned short bytesToWrite = 0;
+        const UTF32 byteMask = 0xBF;
+        const UTF32 byteMark = 0x80; 
+        const UTF16* oldSource = source; /* In case we have to back up because of target overflow. */
+        ch = *source++;
+        /* If we have a surrogate pair, convert to UTF32 first. */
+        if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) {
+            /* If the 16 bits following the high surrogate are in the source buffer... */
+            if (source < sourceEnd) {
+                UTF32 ch2 = *source;
+                /* If it's a low surrogate, convert to UTF32. */
+                if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) {
+                    ch = ((ch - UNI_SUR_HIGH_START) << halfShift)
+                        + (ch2 - UNI_SUR_LOW_START) + halfBase;
+                    ++source;
+                } else if (flags == strictConversion) { /* it's an unpaired high surrogate */
+                    --source; /* return to the illegal value itself */
+                    result = sourceIllegal;
+                    break;
+                }
+            } else { /* We don't have the 16 bits following the high surrogate. */
+                --source; /* return to the high surrogate */
+                result = sourceExhausted;
+                break;
+            }
+        } else if (flags == strictConversion) {
+            /* UTF-16 surrogate values are illegal in UTF-32 */
+            if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) {
+                --source; /* return to the illegal value itself */
+                result = sourceIllegal;
+                break;
+            }
+        }
+        /* Figure out how many bytes the result will require */
+        if (ch < (UTF32)0x80) {      bytesToWrite = 1;
+        } else if (ch < (UTF32)0x800) {     bytesToWrite = 2;
+        } else if (ch < (UTF32)0x10000) {   bytesToWrite = 3;
+        } else if (ch < (UTF32)0x110000) {  bytesToWrite = 4;
+        } else {                            bytesToWrite = 3;
+                                            ch = UNI_REPLACEMENT_CHAR;
+        }
+
+        target += bytesToWrite;
+        if (target > targetEnd) {
+            source = oldSource; /* Back up source pointer! */
+            target -= bytesToWrite; result = targetExhausted; break;
+        }
+        switch (bytesToWrite) { /* note: everything falls through. */
+            case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
+            case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
+            case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
+            case 1: *--target =  (UTF8)(ch | firstByteMark[bytesToWrite]);
+        }
+        target += bytesToWrite;
+    }
+    *sourceStart = source;
+    *targetStart = target;
+    return result;
+}
+
+/* --------------------------------------------------------------------- */
+
+ConversionResult ConvertUTF32toUTF8 (
+        const UTF32** sourceStart, const UTF32* sourceEnd, 
+        UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags) {
+    ConversionResult result = conversionOK;
+    const UTF32* source = *sourceStart;
+    UTF8* target = *targetStart;
+    while (source < sourceEnd) {
+        UTF32 ch;
+        unsigned short bytesToWrite = 0;
+        const UTF32 byteMask = 0xBF;
+        const UTF32 byteMark = 0x80; 
+        ch = *source++;
+        if (flags == strictConversion ) {
+            /* UTF-16 surrogate values are illegal in UTF-32 */
+            if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
+                --source; /* return to the illegal value itself */
+                result = sourceIllegal;
+                break;
+            }
+        }
+        /*
+         * Figure out how many bytes the result will require. Turn any
+         * illegally large UTF32 things (> Plane 17) into replacement chars.
+         */
+        if (ch < (UTF32)0x80) {      bytesToWrite = 1;
+        } else if (ch < (UTF32)0x800) {     bytesToWrite = 2;
+        } else if (ch < (UTF32)0x10000) {   bytesToWrite = 3;
+        } else if (ch <= UNI_MAX_LEGAL_UTF32) {  bytesToWrite = 4;
+        } else {                            bytesToWrite = 3;
+                                            ch = UNI_REPLACEMENT_CHAR;
+                                            result = sourceIllegal;
+        }
+        
+        target += bytesToWrite;
+        if (target > targetEnd) {
+            --source; /* Back up source pointer! */
+            target -= bytesToWrite; result = targetExhausted; break;
+        }
+        switch (bytesToWrite) { /* note: everything falls through. */
+            case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
+            case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
+            case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
+            case 1: *--target = (UTF8) (ch | firstByteMark[bytesToWrite]);
+        }
+        target += bytesToWrite;
+    }
+    *sourceStart = source;
+    *targetStart = target;
+    return result;
+}
+
+/* --------------------------------------------------------------------- */
+
+ConversionResult ConvertUTF8toUTF32 (
+        const UTF8** sourceStart, const UTF8* sourceEnd, 
+        UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags) {
+    ConversionResult result = conversionOK;
+    const UTF8* source = *sourceStart;
+    UTF32* target = *targetStart;
+    while (source < sourceEnd) {
+        UTF32 ch = 0;
+        unsigned short extraBytesToRead = trailingBytesForUTF8[*source];
+        if (source + extraBytesToRead >= sourceEnd) {
+            result = sourceExhausted; break;
+        }
+        /* Do this check whether lenient or strict */
+        if (!isLegalUTF8(source, extraBytesToRead+1)) {
+            result = sourceIllegal;
+            break;
+        }
+        /*
+         * The cases all fall through. See "Note A" below.
+         */
+        switch (extraBytesToRead) {
+            case 5: ch += *source++; ch <<= 6;
+            case 4: ch += *source++; ch <<= 6;
+            case 3: ch += *source++; ch <<= 6;
+            case 2: ch += *source++; ch <<= 6;
+            case 1: ch += *source++; ch <<= 6;
+            case 0: ch += *source++;
+        }
+        ch -= offsetsFromUTF8[extraBytesToRead];
+
+        if (target >= targetEnd) {
+            source -= (extraBytesToRead+1); /* Back up the source pointer! */
+            result = targetExhausted; break;
+        }
+        if (ch <= UNI_MAX_LEGAL_UTF32) {
+            /*
+             * UTF-16 surrogate values are illegal in UTF-32, and anything
+             * over Plane 17 (> 0x10FFFF) is illegal.
+             */
+            if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
+                if (flags == strictConversion) {
+                    source -= (extraBytesToRead+1); /* return to the illegal value itself */
+                    result = sourceIllegal;
+                    break;
+                } else {
+                    *target++ = UNI_REPLACEMENT_CHAR;
+                }
+            } else {
+                *target++ = ch;
+            }
+        } else { /* i.e., ch > UNI_MAX_LEGAL_UTF32 */
+            result = sourceIllegal;
+            *target++ = UNI_REPLACEMENT_CHAR;
+        }
+    }
+    *sourceStart = source;
+    *targetStart = target;
+    return result;
+}
+#endif
+
+/* --------------------------------------------------------------------- */
+
+/*
+ * Utility routine to tell whether a sequence of bytes is legal UTF-8.
+ * This must be called with the length pre-determined by the first byte.
+ * If not calling this from ConvertUTF8to*, then the length can be set by:
+ *  length = trailingBytesForUTF8[*source]+1;
+ * and the sequence is illegal right away if there aren't that many bytes
+ * available.
+ * If presented with a length > 4, this returns false.  The Unicode
+ * definition of UTF-8 goes up to 4-byte sequences.
+ */
+
+static Boolean isLegalUTF8(const UTF8 *source, int length) {
+    UTF8 a;
+    const UTF8 *srcptr = source+length;
+    switch (length) {
+    default: return false;
+        /* Everything else falls through when "true"... */
+    case 4: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false;
+    case 3: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false;
+    case 2: if ((a = (*--srcptr)) > 0xBF) return false;
+
+        switch (*source) {
+            /* no fall-through in this inner switch */
+            case 0xE0: if (a < 0xA0) return false; break;
+            case 0xED: if (a > 0x9F) return false; break;
+            case 0xF0: if (a < 0x90) return false; break;
+            case 0xF4: if (a > 0x8F) return false; break;
+            default:   if (a < 0x80) return false;
+        }
+
+    case 1: if (*source >= 0x80 && *source < 0xC2) return false;
+    }
+    if (*source > 0xF4) return false;
+    return true;
+}
+
+/* --------------------------------------------------------------------- */
+
+/*
+ * Exported function to return whether a UTF-8 sequence is legal or not.
+ * This is not used here; it's just exported.
+ */
+Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd) {
+    int length = trailingBytesForUTF8[*source]+1;
+    if (source+length > sourceEnd) {
+        return false;
+    }
+    return isLegalUTF8(source, length);
+}
+
+/* --------------------------------------------------------------------- */
+
+ConversionResult ConvertUTF8toUTF16 (
+        const UTF8** sourceStart, const UTF8* sourceEnd, 
+        UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) {
+    ConversionResult result = conversionOK;
+    const UTF8* source = *sourceStart;
+    UTF16* target = *targetStart;
+    while (source < sourceEnd) {
+        UTF32 ch = 0;
+        unsigned short extraBytesToRead = trailingBytesForUTF8[*source];
+        if (source + extraBytesToRead >= sourceEnd) {
+            result = sourceExhausted; break;
+        }
+        /* Do this check whether lenient or strict */
+        if (!isLegalUTF8(source, extraBytesToRead+1)) {
+            result = sourceIllegal;
+            break;
+        }
+        /*
+         * The cases all fall through. See "Note A" below.
+         */
+        switch (extraBytesToRead) {
+            case 5: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */
+            case 4: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */
+            case 3: ch += *source++; ch <<= 6;
+            case 2: ch += *source++; ch <<= 6;
+            case 1: ch += *source++; ch <<= 6;
+            case 0: ch += *source++;
+        }
+        ch -= offsetsFromUTF8[extraBytesToRead];
+
+        if (target >= targetEnd) {
+            source -= (extraBytesToRead+1); /* Back up source pointer! */
+            result = targetExhausted; break;
+        }
+        if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */
+            /* UTF-16 surrogate values are illegal in UTF-32 */
+            if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
+                if (flags == strictConversion) {
+                    source -= (extraBytesToRead+1); /* return to the illegal value itself */
+                    result = sourceIllegal;
+                    break;
+                } else {
+                    *target++ = UNI_REPLACEMENT_CHAR;
+                }
+            } else {
+                *target++ = (UTF16)ch; /* normal case */
+            }
+        } else if (ch > UNI_MAX_UTF16) {
+            if (flags == strictConversion) {
+                result = sourceIllegal;
+                source -= (extraBytesToRead+1); /* return to the start */
+                break; /* Bail out; shouldn't continue */
+            } else {
+                *target++ = UNI_REPLACEMENT_CHAR;
+            }
+        } else {
+            /* target is a character in range 0xFFFF - 0x10FFFF. */
+            if (target + 1 >= targetEnd) {
+                source -= (extraBytesToRead+1); /* Back up source pointer! */
+                result = targetExhausted; break;
+            }
+            ch -= halfBase;
+            *target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START);
+            *target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START);
+        }
+    }
+    *sourceStart = source;
+    *targetStart = target;
+    return result;
+}
+
+/* ---------------------------------------------------------------------
+
+    Note A.
+    The fall-through switches in UTF-8 reading code save a
+    temp variable, some decrements & conditionals.  The switches
+    are equivalent to the following loop:
+        {
+            int tmpBytesToRead = extraBytesToRead+1;
+            do {
+                ch += *source++;
+                --tmpBytesToRead;
+                if (tmpBytesToRead) ch <<= 6;
+            } while (tmpBytesToRead > 0);
+        }
+    In UTF-8 writing code, the switches on "bytesToWrite" are
+    similarly unrolled loops.
+
+   --------------------------------------------------------------------- */
diff --git a/lib/Basic/Diagnostic.cpp b/lib/Basic/Diagnostic.cpp
new file mode 100644
index 0000000..1870195
--- /dev/null
+++ b/lib/Basic/Diagnostic.cpp
@@ -0,0 +1,1291 @@
+//===--- Diagnostic.cpp - C Language Family Diagnostic Handling -----------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements the Diagnostic-related interfaces.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/ASTDiagnostic.h"
+#include "clang/Analysis/AnalysisDiagnostic.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/PartialDiagnostic.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Driver/DriverDiagnostic.h"
+#include "clang/Frontend/FrontendDiagnostic.h"
+#include "clang/Lex/LexDiagnostic.h"
+#include "clang/Parse/ParseDiagnostic.h"
+#include "clang/Sema/SemaDiagnostic.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
+
+#include <vector>
+#include <map>
+#include <cstring>
+using namespace clang;
+
+//===----------------------------------------------------------------------===//
+// Builtin Diagnostic information
+//===----------------------------------------------------------------------===//
+
+// Diagnostic classes.
+enum {
+  CLASS_NOTE       = 0x01,
+  CLASS_WARNING    = 0x02,
+  CLASS_EXTENSION  = 0x03,
+  CLASS_ERROR      = 0x04
+};
+
+struct StaticDiagInfoRec {
+  unsigned short DiagID;
+  unsigned Mapping : 3;
+  unsigned Class : 3;
+  bool SFINAE : 1;
+  const char *Description;
+  const char *OptionGroup;
+
+  bool operator<(const StaticDiagInfoRec &RHS) const {
+    return DiagID < RHS.DiagID;
+  }
+  bool operator>(const StaticDiagInfoRec &RHS) const {
+    return DiagID > RHS.DiagID;
+  }
+};
+
+static const StaticDiagInfoRec StaticDiagInfo[] = {
+#define DIAG(ENUM,CLASS,DEFAULT_MAPPING,DESC,GROUP,SFINAE)    \
+  { diag::ENUM, DEFAULT_MAPPING, CLASS, SFINAE, DESC, GROUP },
+#include "clang/Basic/DiagnosticCommonKinds.inc"
+#include "clang/Basic/DiagnosticDriverKinds.inc"
+#include "clang/Basic/DiagnosticFrontendKinds.inc"
+#include "clang/Basic/DiagnosticLexKinds.inc"
+#include "clang/Basic/DiagnosticParseKinds.inc"
+#include "clang/Basic/DiagnosticASTKinds.inc"
+#include "clang/Basic/DiagnosticSemaKinds.inc"
+#include "clang/Basic/DiagnosticAnalysisKinds.inc"
+  { 0, 0, 0, 0, 0, 0}
+};
+#undef DIAG
+
+/// GetDiagInfo - Return the StaticDiagInfoRec entry for the specified DiagID,
+/// or null if the ID is invalid.
+static const StaticDiagInfoRec *GetDiagInfo(unsigned DiagID) {
+  unsigned NumDiagEntries = sizeof(StaticDiagInfo)/sizeof(StaticDiagInfo[0])-1;
+
+  // If assertions are enabled, verify that the StaticDiagInfo array is sorted.
+#ifndef NDEBUG
+  static bool IsFirst = true;
+  if (IsFirst) {
+    for (unsigned i = 1; i != NumDiagEntries; ++i) {
+      assert(StaticDiagInfo[i-1].DiagID != StaticDiagInfo[i].DiagID &&
+             "Diag ID conflict, the enums at the start of clang::diag (in "
+             "Diagnostic.h) probably need to be increased");
+
+      assert(StaticDiagInfo[i-1] < StaticDiagInfo[i] &&
+             "Improperly sorted diag info");
+    }
+    IsFirst = false;
+  }
+#endif
+
+  // Search the diagnostic table with a binary search.
+  StaticDiagInfoRec Find = { DiagID, 0, 0, 0, 0, 0 };
+
+  const StaticDiagInfoRec *Found =
+    std::lower_bound(StaticDiagInfo, StaticDiagInfo + NumDiagEntries, Find);
+  if (Found == StaticDiagInfo + NumDiagEntries ||
+      Found->DiagID != DiagID)
+    return 0;
+
+  return Found;
+}
+
+static unsigned GetDefaultDiagMapping(unsigned DiagID) {
+  if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
+    return Info->Mapping;
+  return diag::MAP_FATAL;
+}
+
+/// getWarningOptionForDiag - Return the lowest-level warning option that
+/// enables the specified diagnostic.  If there is no -Wfoo flag that controls
+/// the diagnostic, this returns null.
+const char *Diagnostic::getWarningOptionForDiag(unsigned DiagID) {
+  if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
+    return Info->OptionGroup;
+  return 0;
+}
+
+Diagnostic::SFINAEResponse 
+Diagnostic::getDiagnosticSFINAEResponse(unsigned DiagID) {
+  if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID)) {
+    if (!Info->SFINAE)
+      return SFINAE_Report;
+
+    if (Info->Class == CLASS_ERROR)
+      return SFINAE_SubstitutionFailure;
+    
+    // Suppress notes, warnings, and extensions;
+    return SFINAE_Suppress;
+  }
+  
+  return SFINAE_Report;
+}
+
+/// getDiagClass - Return the class field of the diagnostic.
+///
+static unsigned getBuiltinDiagClass(unsigned DiagID) {
+  if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
+    return Info->Class;
+  return ~0U;
+}
+
+//===----------------------------------------------------------------------===//
+// Custom Diagnostic information
+//===----------------------------------------------------------------------===//
+
+namespace clang {
+  namespace diag {
+    class CustomDiagInfo {
+      typedef std::pair<Diagnostic::Level, std::string> DiagDesc;
+      std::vector<DiagDesc> DiagInfo;
+      std::map<DiagDesc, unsigned> DiagIDs;
+    public:
+
+      /// getDescription - Return the description of the specified custom
+      /// diagnostic.
+      const char *getDescription(unsigned DiagID) const {
+        assert(this && DiagID-DIAG_UPPER_LIMIT < DiagInfo.size() &&
+               "Invalid diagnosic ID");
+        return DiagInfo[DiagID-DIAG_UPPER_LIMIT].second.c_str();
+      }
+
+      /// getLevel - Return the level of the specified custom diagnostic.
+      Diagnostic::Level getLevel(unsigned DiagID) const {
+        assert(this && DiagID-DIAG_UPPER_LIMIT < DiagInfo.size() &&
+               "Invalid diagnosic ID");
+        return DiagInfo[DiagID-DIAG_UPPER_LIMIT].first;
+      }
+
+      unsigned getOrCreateDiagID(Diagnostic::Level L, llvm::StringRef Message,
+                                 Diagnostic &Diags) {
+        DiagDesc D(L, Message);
+        // Check to see if it already exists.
+        std::map<DiagDesc, unsigned>::iterator I = DiagIDs.lower_bound(D);
+        if (I != DiagIDs.end() && I->first == D)
+          return I->second;
+
+        // If not, assign a new ID.
+        unsigned ID = DiagInfo.size()+DIAG_UPPER_LIMIT;
+        DiagIDs.insert(std::make_pair(D, ID));
+        DiagInfo.push_back(D);
+        return ID;
+      }
+    };
+
+  } // end diag namespace
+} // end clang namespace
+
+
+//===----------------------------------------------------------------------===//
+// Common Diagnostic implementation
+//===----------------------------------------------------------------------===//
+
+static void DummyArgToStringFn(Diagnostic::ArgumentKind AK, intptr_t QT,
+                               const char *Modifier, unsigned ML,
+                               const char *Argument, unsigned ArgLen,
+                               const Diagnostic::ArgumentValue *PrevArgs,
+                               unsigned NumPrevArgs,
+                               llvm::SmallVectorImpl<char> &Output,
+                               void *Cookie) {
+  const char *Str = "<can't format argument>";
+  Output.append(Str, Str+strlen(Str));
+}
+
+
+Diagnostic::Diagnostic(DiagnosticClient *client) : Client(client) {
+  AllExtensionsSilenced = 0;
+  IgnoreAllWarnings = false;
+  WarningsAsErrors = false;
+  ErrorsAsFatal = false;
+  SuppressSystemWarnings = false;
+  SuppressAllDiagnostics = false;
+  ExtBehavior = Ext_Ignore;
+
+  ErrorOccurred = false;
+  FatalErrorOccurred = false;
+  ErrorLimit = 0;
+  TemplateBacktraceLimit = 0;
+
+  NumWarnings = 0;
+  NumErrors = 0;
+  NumErrorsSuppressed = 0;
+  CustomDiagInfo = 0;
+  CurDiagID = ~0U;
+  LastDiagLevel = Ignored;
+
+  ArgToStringFn = DummyArgToStringFn;
+  ArgToStringCookie = 0;
+
+  DelayedDiagID = 0;
+
+  // Set all mappings to 'unset'.
+  DiagMappings BlankDiags(diag::DIAG_UPPER_LIMIT/2, 0);
+  DiagMappingsStack.push_back(BlankDiags);
+}
+
+Diagnostic::~Diagnostic() {
+  delete CustomDiagInfo;
+}
+
+
+void Diagnostic::pushMappings() {
+  // Avoids undefined behavior when the stack has to resize.
+  DiagMappingsStack.reserve(DiagMappingsStack.size() + 1);
+  DiagMappingsStack.push_back(DiagMappingsStack.back());
+}
+
+bool Diagnostic::popMappings() {
+  if (DiagMappingsStack.size() == 1)
+    return false;
+
+  DiagMappingsStack.pop_back();
+  return true;
+}
+
+/// getCustomDiagID - Return an ID for a diagnostic with the specified message
+/// and level.  If this is the first request for this diagnosic, it is
+/// registered and created, otherwise the existing ID is returned.
+unsigned Diagnostic::getCustomDiagID(Level L, llvm::StringRef Message) {
+  if (CustomDiagInfo == 0)
+    CustomDiagInfo = new diag::CustomDiagInfo();
+  return CustomDiagInfo->getOrCreateDiagID(L, Message, *this);
+}
+
+
+/// isBuiltinWarningOrExtension - Return true if the unmapped diagnostic
+/// level of the specified diagnostic ID is a Warning or Extension.
+/// This only works on builtin diagnostics, not custom ones, and is not legal to
+/// call on NOTEs.
+bool Diagnostic::isBuiltinWarningOrExtension(unsigned DiagID) {
+  return DiagID < diag::DIAG_UPPER_LIMIT &&
+         getBuiltinDiagClass(DiagID) != CLASS_ERROR;
+}
+
+/// \brief Determine whether the given built-in diagnostic ID is a
+/// Note.
+bool Diagnostic::isBuiltinNote(unsigned DiagID) {
+  return DiagID < diag::DIAG_UPPER_LIMIT &&
+    getBuiltinDiagClass(DiagID) == CLASS_NOTE;
+}
+
+/// isBuiltinExtensionDiag - Determine whether the given built-in diagnostic
+/// ID is for an extension of some sort.  This also returns EnabledByDefault,
+/// which is set to indicate whether the diagnostic is ignored by default (in
+/// which case -pedantic enables it) or treated as a warning/error by default.
+///
+bool Diagnostic::isBuiltinExtensionDiag(unsigned DiagID,
+                                        bool &EnabledByDefault) {
+  if (DiagID >= diag::DIAG_UPPER_LIMIT ||
+      getBuiltinDiagClass(DiagID) != CLASS_EXTENSION)
+    return false;
+  
+  EnabledByDefault = StaticDiagInfo[DiagID].Mapping != diag::MAP_IGNORE;
+  return true;
+}
+
+
+/// getDescription - Given a diagnostic ID, return a description of the
+/// issue.
+const char *Diagnostic::getDescription(unsigned DiagID) const {
+  if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
+    return Info->Description;
+  return CustomDiagInfo->getDescription(DiagID);
+}
+
+void Diagnostic::SetDelayedDiagnostic(unsigned DiagID, llvm::StringRef Arg1,
+                                      llvm::StringRef Arg2) {
+  if (DelayedDiagID)
+    return;
+
+  DelayedDiagID = DiagID;
+  DelayedDiagArg1 = Arg1.str();
+  DelayedDiagArg2 = Arg2.str();
+}
+
+void Diagnostic::ReportDelayed() {
+  Report(DelayedDiagID) << DelayedDiagArg1 << DelayedDiagArg2;
+  DelayedDiagID = 0;
+  DelayedDiagArg1.clear();
+  DelayedDiagArg2.clear();
+}
+
+/// getDiagnosticLevel - Based on the way the client configured the Diagnostic
+/// object, classify the specified diagnostic ID into a Level, consumable by
+/// the DiagnosticClient.
+Diagnostic::Level Diagnostic::getDiagnosticLevel(unsigned DiagID) const {
+  // Handle custom diagnostics, which cannot be mapped.
+  if (DiagID >= diag::DIAG_UPPER_LIMIT)
+    return CustomDiagInfo->getLevel(DiagID);
+
+  unsigned DiagClass = getBuiltinDiagClass(DiagID);
+  assert(DiagClass != CLASS_NOTE && "Cannot get diagnostic level of a note!");
+  return getDiagnosticLevel(DiagID, DiagClass);
+}
+
+/// getDiagnosticLevel - Based on the way the client configured the Diagnostic
+/// object, classify the specified diagnostic ID into a Level, consumable by
+/// the DiagnosticClient.
+Diagnostic::Level
+Diagnostic::getDiagnosticLevel(unsigned DiagID, unsigned DiagClass) const {
+  // Specific non-error diagnostics may be mapped to various levels from ignored
+  // to error.  Errors can only be mapped to fatal.
+  Diagnostic::Level Result = Diagnostic::Fatal;
+
+  // Get the mapping information, if unset, compute it lazily.
+  unsigned MappingInfo = getDiagnosticMappingInfo((diag::kind)DiagID);
+  if (MappingInfo == 0) {
+    MappingInfo = GetDefaultDiagMapping(DiagID);
+    setDiagnosticMappingInternal(DiagID, MappingInfo, false);
+  }
+
+  switch (MappingInfo & 7) {
+  default: assert(0 && "Unknown mapping!");
+  case diag::MAP_IGNORE:
+    // Ignore this, unless this is an extension diagnostic and we're mapping
+    // them onto warnings or errors.
+    if (!isBuiltinExtensionDiag(DiagID) ||  // Not an extension
+        ExtBehavior == Ext_Ignore ||        // Extensions ignored anyway
+        (MappingInfo & 8) != 0)             // User explicitly mapped it.
+      return Diagnostic::Ignored;
+    Result = Diagnostic::Warning;
+    if (ExtBehavior == Ext_Error) Result = Diagnostic::Error;
+    if (Result == Diagnostic::Error && ErrorsAsFatal)
+      Result = Diagnostic::Fatal;
+    break;
+  case diag::MAP_ERROR:
+    Result = Diagnostic::Error;
+    if (ErrorsAsFatal)
+      Result = Diagnostic::Fatal;
+    break;
+  case diag::MAP_FATAL:
+    Result = Diagnostic::Fatal;
+    break;
+  case diag::MAP_WARNING:
+    // If warnings are globally mapped to ignore or error, do it.
+    if (IgnoreAllWarnings)
+      return Diagnostic::Ignored;
+
+    Result = Diagnostic::Warning;
+
+    // If this is an extension diagnostic and we're in -pedantic-error mode, and
+    // if the user didn't explicitly map it, upgrade to an error.
+    if (ExtBehavior == Ext_Error &&
+        (MappingInfo & 8) == 0 &&
+        isBuiltinExtensionDiag(DiagID))
+      Result = Diagnostic::Error;
+
+    if (WarningsAsErrors)
+      Result = Diagnostic::Error;
+    if (Result == Diagnostic::Error && ErrorsAsFatal)
+      Result = Diagnostic::Fatal;
+    break;
+
+  case diag::MAP_WARNING_NO_WERROR:
+    // Diagnostics specified with -Wno-error=foo should be set to warnings, but
+    // not be adjusted by -Werror or -pedantic-errors.
+    Result = Diagnostic::Warning;
+
+    // If warnings are globally mapped to ignore or error, do it.
+    if (IgnoreAllWarnings)
+      return Diagnostic::Ignored;
+
+    break;
+
+  case diag::MAP_ERROR_NO_WFATAL:
+    // Diagnostics specified as -Wno-fatal-error=foo should be errors, but
+    // unaffected by -Wfatal-errors.
+    Result = Diagnostic::Error;
+    break;
+  }
+
+  // Okay, we're about to return this as a "diagnostic to emit" one last check:
+  // if this is any sort of extension warning, and if we're in an __extension__
+  // block, silence it.
+  if (AllExtensionsSilenced && isBuiltinExtensionDiag(DiagID))
+    return Diagnostic::Ignored;
+
+  return Result;
+}
+
+struct WarningOption {
+  const char  *Name;
+  const short *Members;
+  const char  *SubGroups;
+};
+
+#define GET_DIAG_ARRAYS
+#include "clang/Basic/DiagnosticGroups.inc"
+#undef GET_DIAG_ARRAYS
+
+// Second the table of options, sorted by name for fast binary lookup.
+static const WarningOption OptionTable[] = {
+#define GET_DIAG_TABLE
+#include "clang/Basic/DiagnosticGroups.inc"
+#undef GET_DIAG_TABLE
+};
+static const size_t OptionTableSize =
+sizeof(OptionTable) / sizeof(OptionTable[0]);
+
+static bool WarningOptionCompare(const WarningOption &LHS,
+                                 const WarningOption &RHS) {
+  return strcmp(LHS.Name, RHS.Name) < 0;
+}
+
+static void MapGroupMembers(const WarningOption *Group, diag::Mapping Mapping,
+                            Diagnostic &Diags) {
+  // Option exists, poke all the members of its diagnostic set.
+  if (const short *Member = Group->Members) {
+    for (; *Member != -1; ++Member)
+      Diags.setDiagnosticMapping(*Member, Mapping);
+  }
+
+  // Enable/disable all subgroups along with this one.
+  if (const char *SubGroups = Group->SubGroups) {
+    for (; *SubGroups != (char)-1; ++SubGroups)
+      MapGroupMembers(&OptionTable[(unsigned char)*SubGroups], Mapping, Diags);
+  }
+}
+
+/// setDiagnosticGroupMapping - Change an entire diagnostic group (e.g.
+/// "unknown-pragmas" to have the specified mapping.  This returns true and
+/// ignores the request if "Group" was unknown, false otherwise.
+bool Diagnostic::setDiagnosticGroupMapping(const char *Group,
+                                           diag::Mapping Map) {
+
+  WarningOption Key = { Group, 0, 0 };
+  const WarningOption *Found =
+  std::lower_bound(OptionTable, OptionTable + OptionTableSize, Key,
+                   WarningOptionCompare);
+  if (Found == OptionTable + OptionTableSize ||
+      strcmp(Found->Name, Group) != 0)
+    return true;  // Option not found.
+
+  MapGroupMembers(Found, Map, *this);
+  return false;
+}
+
+
+/// ProcessDiag - This is the method used to report a diagnostic that is
+/// finally fully formed.
+bool Diagnostic::ProcessDiag() {
+  DiagnosticInfo Info(this);
+
+  if (SuppressAllDiagnostics)
+    return false;
+  
+  // Figure out the diagnostic level of this message.
+  Diagnostic::Level DiagLevel;
+  unsigned DiagID = Info.getID();
+
+  // ShouldEmitInSystemHeader - True if this diagnostic should be produced even
+  // in a system header.
+  bool ShouldEmitInSystemHeader;
+
+  if (DiagID >= diag::DIAG_UPPER_LIMIT) {
+    // Handle custom diagnostics, which cannot be mapped.
+    DiagLevel = CustomDiagInfo->getLevel(DiagID);
+
+    // Custom diagnostics always are emitted in system headers.
+    ShouldEmitInSystemHeader = true;
+  } else {
+    // Get the class of the diagnostic.  If this is a NOTE, map it onto whatever
+    // the diagnostic level was for the previous diagnostic so that it is
+    // filtered the same as the previous diagnostic.
+    unsigned DiagClass = getBuiltinDiagClass(DiagID);
+    if (DiagClass == CLASS_NOTE) {
+      DiagLevel = Diagnostic::Note;
+      ShouldEmitInSystemHeader = false;  // extra consideration is needed
+    } else {
+      // If this is not an error and we are in a system header, we ignore it.
+      // Check the original Diag ID here, because we also want to ignore
+      // extensions and warnings in -Werror and -pedantic-errors modes, which
+      // *map* warnings/extensions to errors.
+      ShouldEmitInSystemHeader = DiagClass == CLASS_ERROR;
+
+      DiagLevel = getDiagnosticLevel(DiagID, DiagClass);
+    }
+  }
+
+  if (DiagLevel != Diagnostic::Note) {
+    // Record that a fatal error occurred only when we see a second
+    // non-note diagnostic. This allows notes to be attached to the
+    // fatal error, but suppresses any diagnostics that follow those
+    // notes.
+    if (LastDiagLevel == Diagnostic::Fatal)
+      FatalErrorOccurred = true;
+
+    LastDiagLevel = DiagLevel;
+  }
+
+  // If a fatal error has already been emitted, silence all subsequent
+  // diagnostics.
+  if (FatalErrorOccurred) {
+    if (DiagLevel >= Diagnostic::Error) {
+      ++NumErrors;
+      ++NumErrorsSuppressed;
+    }
+    
+    return false;
+  }
+
+  // If the client doesn't care about this message, don't issue it.  If this is
+  // a note and the last real diagnostic was ignored, ignore it too.
+  if (DiagLevel == Diagnostic::Ignored ||
+      (DiagLevel == Diagnostic::Note && LastDiagLevel == Diagnostic::Ignored))
+    return false;
+
+  // If this diagnostic is in a system header and is not a clang error, suppress
+  // it.
+  if (SuppressSystemWarnings && !ShouldEmitInSystemHeader &&
+      Info.getLocation().isValid() &&
+      Info.getLocation().getInstantiationLoc().isInSystemHeader() &&
+      (DiagLevel != Diagnostic::Note || LastDiagLevel == Diagnostic::Ignored)) {
+    LastDiagLevel = Diagnostic::Ignored;
+    return false;
+  }
+
+  if (DiagLevel >= Diagnostic::Error) {
+    ErrorOccurred = true;
+    ++NumErrors;
+    
+    // If we've emitted a lot of errors, emit a fatal error after it to stop a
+    // flood of bogus errors.
+    if (ErrorLimit && NumErrors >= ErrorLimit &&
+        DiagLevel == Diagnostic::Error)
+      SetDelayedDiagnostic(diag::fatal_too_many_errors);
+  }
+
+  // Finally, report it.
+  Client->HandleDiagnostic(DiagLevel, Info);
+  if (Client->IncludeInDiagnosticCounts()) {
+    if (DiagLevel == Diagnostic::Warning)
+      ++NumWarnings;
+  }
+
+  CurDiagID = ~0U;
+
+  return true;
+}
+
+bool DiagnosticBuilder::Emit() {
+  // If DiagObj is null, then its soul was stolen by the copy ctor
+  // or the user called Emit().
+  if (DiagObj == 0) return false;
+
+  // When emitting diagnostics, we set the final argument count into
+  // the Diagnostic object.
+  DiagObj->NumDiagArgs = NumArgs;
+  DiagObj->NumDiagRanges = NumRanges;
+  DiagObj->NumFixItHints = NumFixItHints;
+
+  // Process the diagnostic, sending the accumulated information to the
+  // DiagnosticClient.
+  bool Emitted = DiagObj->ProcessDiag();
+
+  // Clear out the current diagnostic object.
+  unsigned DiagID = DiagObj->CurDiagID;
+  DiagObj->Clear();
+
+  // If there was a delayed diagnostic, emit it now.
+  if (DiagObj->DelayedDiagID && DiagObj->DelayedDiagID != DiagID)
+    DiagObj->ReportDelayed();
+
+  // This diagnostic is dead.
+  DiagObj = 0;
+
+  return Emitted;
+}
+
+
+DiagnosticClient::~DiagnosticClient() {}
+
+
+/// ModifierIs - Return true if the specified modifier matches specified string.
+template <std::size_t StrLen>
+static bool ModifierIs(const char *Modifier, unsigned ModifierLen,
+                       const char (&Str)[StrLen]) {
+  return StrLen-1 == ModifierLen && !memcmp(Modifier, Str, StrLen-1);
+}
+
+/// ScanForward - Scans forward, looking for the given character, skipping
+/// nested clauses and escaped characters.
+static const char *ScanFormat(const char *I, const char *E, char Target) {
+  unsigned Depth = 0;
+
+  for ( ; I != E; ++I) {
+    if (Depth == 0 && *I == Target) return I;
+    if (Depth != 0 && *I == '}') Depth--;
+
+    if (*I == '%') {
+      I++;
+      if (I == E) break;
+
+      // Escaped characters get implicitly skipped here.
+
+      // Format specifier.
+      if (!isdigit(*I) && !ispunct(*I)) {
+        for (I++; I != E && !isdigit(*I) && *I != '{'; I++) ;
+        if (I == E) break;
+        if (*I == '{')
+          Depth++;
+      }
+    }
+  }
+  return E;
+}
+
+/// HandleSelectModifier - Handle the integer 'select' modifier.  This is used
+/// like this:  %select{foo|bar|baz}2.  This means that the integer argument
+/// "%2" has a value from 0-2.  If the value is 0, the diagnostic prints 'foo'.
+/// If the value is 1, it prints 'bar'.  If it has the value 2, it prints 'baz'.
+/// This is very useful for certain classes of variant diagnostics.
+static void HandleSelectModifier(const DiagnosticInfo &DInfo, unsigned ValNo,
+                                 const char *Argument, unsigned ArgumentLen,
+                                 llvm::SmallVectorImpl<char> &OutStr) {
+  const char *ArgumentEnd = Argument+ArgumentLen;
+
+  // Skip over 'ValNo' |'s.
+  while (ValNo) {
+    const char *NextVal = ScanFormat(Argument, ArgumentEnd, '|');
+    assert(NextVal != ArgumentEnd && "Value for integer select modifier was"
+           " larger than the number of options in the diagnostic string!");
+    Argument = NextVal+1;  // Skip this string.
+    --ValNo;
+  }
+
+  // Get the end of the value.  This is either the } or the |.
+  const char *EndPtr = ScanFormat(Argument, ArgumentEnd, '|');
+
+  // Recursively format the result of the select clause into the output string.
+  DInfo.FormatDiagnostic(Argument, EndPtr, OutStr);
+}
+
+/// HandleIntegerSModifier - Handle the integer 's' modifier.  This adds the
+/// letter 's' to the string if the value is not 1.  This is used in cases like
+/// this:  "you idiot, you have %4 parameter%s4!".
+static void HandleIntegerSModifier(unsigned ValNo,
+                                   llvm::SmallVectorImpl<char> &OutStr) {
+  if (ValNo != 1)
+    OutStr.push_back('s');
+}
+
+/// HandleOrdinalModifier - Handle the integer 'ord' modifier.  This
+/// prints the ordinal form of the given integer, with 1 corresponding
+/// to the first ordinal.  Currently this is hard-coded to use the
+/// English form.
+static void HandleOrdinalModifier(unsigned ValNo,
+                                  llvm::SmallVectorImpl<char> &OutStr) {
+  assert(ValNo != 0 && "ValNo must be strictly positive!");
+
+  llvm::raw_svector_ostream Out(OutStr);
+
+  // We could use text forms for the first N ordinals, but the numeric
+  // forms are actually nicer in diagnostics because they stand out.
+  Out << ValNo;
+
+  // It is critically important that we do this perfectly for
+  // user-written sequences with over 100 elements.
+  switch (ValNo % 100) {
+  case 11:
+  case 12:
+  case 13:
+    Out << "th"; return;
+  default:
+    switch (ValNo % 10) {
+    case 1: Out << "st"; return;
+    case 2: Out << "nd"; return;
+    case 3: Out << "rd"; return;
+    default: Out << "th"; return;
+    }
+  }
+}
+
+
+/// PluralNumber - Parse an unsigned integer and advance Start.
+static unsigned PluralNumber(const char *&Start, const char *End) {
+  // Programming 101: Parse a decimal number :-)
+  unsigned Val = 0;
+  while (Start != End && *Start >= '0' && *Start <= '9') {
+    Val *= 10;
+    Val += *Start - '0';
+    ++Start;
+  }
+  return Val;
+}
+
+/// TestPluralRange - Test if Val is in the parsed range. Modifies Start.
+static bool TestPluralRange(unsigned Val, const char *&Start, const char *End) {
+  if (*Start != '[') {
+    unsigned Ref = PluralNumber(Start, End);
+    return Ref == Val;
+  }
+
+  ++Start;
+  unsigned Low = PluralNumber(Start, End);
+  assert(*Start == ',' && "Bad plural expression syntax: expected ,");
+  ++Start;
+  unsigned High = PluralNumber(Start, End);
+  assert(*Start == ']' && "Bad plural expression syntax: expected )");
+  ++Start;
+  return Low <= Val && Val <= High;
+}
+
+/// EvalPluralExpr - Actual expression evaluator for HandlePluralModifier.
+static bool EvalPluralExpr(unsigned ValNo, const char *Start, const char *End) {
+  // Empty condition?
+  if (*Start == ':')
+    return true;
+
+  while (1) {
+    char C = *Start;
+    if (C == '%') {
+      // Modulo expression
+      ++Start;
+      unsigned Arg = PluralNumber(Start, End);
+      assert(*Start == '=' && "Bad plural expression syntax: expected =");
+      ++Start;
+      unsigned ValMod = ValNo % Arg;
+      if (TestPluralRange(ValMod, Start, End))
+        return true;
+    } else {
+      assert((C == '[' || (C >= '0' && C <= '9')) &&
+             "Bad plural expression syntax: unexpected character");
+      // Range expression
+      if (TestPluralRange(ValNo, Start, End))
+        return true;
+    }
+
+    // Scan for next or-expr part.
+    Start = std::find(Start, End, ',');
+    if (Start == End)
+      break;
+    ++Start;
+  }
+  return false;
+}
+
+/// HandlePluralModifier - Handle the integer 'plural' modifier. This is used
+/// for complex plural forms, or in languages where all plurals are complex.
+/// The syntax is: %plural{cond1:form1|cond2:form2|:form3}, where condn are
+/// conditions that are tested in order, the form corresponding to the first
+/// that applies being emitted. The empty condition is always true, making the
+/// last form a default case.
+/// Conditions are simple boolean expressions, where n is the number argument.
+/// Here are the rules.
+/// condition  := expression | empty
+/// empty      :=                             -> always true
+/// expression := numeric [',' expression]    -> logical or
+/// numeric    := range                       -> true if n in range
+///             | '%' number '=' range        -> true if n % number in range
+/// range      := number
+///             | '[' number ',' number ']'   -> ranges are inclusive both ends
+///
+/// Here are some examples from the GNU gettext manual written in this form:
+/// English:
+/// {1:form0|:form1}
+/// Latvian:
+/// {0:form2|%100=11,%10=0,%10=[2,9]:form1|:form0}
+/// Gaeilge:
+/// {1:form0|2:form1|:form2}
+/// Romanian:
+/// {1:form0|0,%100=[1,19]:form1|:form2}
+/// Lithuanian:
+/// {%10=0,%100=[10,19]:form2|%10=1:form0|:form1}
+/// Russian (requires repeated form):
+/// {%100=[11,14]:form2|%10=1:form0|%10=[2,4]:form1|:form2}
+/// Slovak
+/// {1:form0|[2,4]:form1|:form2}
+/// Polish (requires repeated form):
+/// {1:form0|%100=[10,20]:form2|%10=[2,4]:form1|:form2}
+static void HandlePluralModifier(unsigned ValNo,
+                                 const char *Argument, unsigned ArgumentLen,
+                                 llvm::SmallVectorImpl<char> &OutStr) {
+  const char *ArgumentEnd = Argument + ArgumentLen;
+  while (1) {
+    assert(Argument < ArgumentEnd && "Plural expression didn't match.");
+    const char *ExprEnd = Argument;
+    while (*ExprEnd != ':') {
+      assert(ExprEnd != ArgumentEnd && "Plural missing expression end");
+      ++ExprEnd;
+    }
+    if (EvalPluralExpr(ValNo, Argument, ExprEnd)) {
+      Argument = ExprEnd + 1;
+      ExprEnd = ScanFormat(Argument, ArgumentEnd, '|');
+      OutStr.append(Argument, ExprEnd);
+      return;
+    }
+    Argument = ScanFormat(Argument, ArgumentEnd - 1, '|') + 1;
+  }
+}
+
+
+/// FormatDiagnostic - Format this diagnostic into a string, substituting the
+/// formal arguments into the %0 slots.  The result is appended onto the Str
+/// array.
+void DiagnosticInfo::
+FormatDiagnostic(llvm::SmallVectorImpl<char> &OutStr) const {
+  const char *DiagStr = getDiags()->getDescription(getID());
+  const char *DiagEnd = DiagStr+strlen(DiagStr);
+
+  FormatDiagnostic(DiagStr, DiagEnd, OutStr);
+}
+
+void DiagnosticInfo::
+FormatDiagnostic(const char *DiagStr, const char *DiagEnd,
+                 llvm::SmallVectorImpl<char> &OutStr) const {
+
+  /// FormattedArgs - Keep track of all of the arguments formatted by
+  /// ConvertArgToString and pass them into subsequent calls to
+  /// ConvertArgToString, allowing the implementation to avoid redundancies in
+  /// obvious cases.
+  llvm::SmallVector<Diagnostic::ArgumentValue, 8> FormattedArgs;
+  
+  while (DiagStr != DiagEnd) {
+    if (DiagStr[0] != '%') {
+      // Append non-%0 substrings to Str if we have one.
+      const char *StrEnd = std::find(DiagStr, DiagEnd, '%');
+      OutStr.append(DiagStr, StrEnd);
+      DiagStr = StrEnd;
+      continue;
+    } else if (ispunct(DiagStr[1])) {
+      OutStr.push_back(DiagStr[1]);  // %% -> %.
+      DiagStr += 2;
+      continue;
+    }
+
+    // Skip the %.
+    ++DiagStr;
+
+    // This must be a placeholder for a diagnostic argument.  The format for a
+    // placeholder is one of "%0", "%modifier0", or "%modifier{arguments}0".
+    // The digit is a number from 0-9 indicating which argument this comes from.
+    // The modifier is a string of digits from the set [-a-z]+, arguments is a
+    // brace enclosed string.
+    const char *Modifier = 0, *Argument = 0;
+    unsigned ModifierLen = 0, ArgumentLen = 0;
+
+    // Check to see if we have a modifier.  If so eat it.
+    if (!isdigit(DiagStr[0])) {
+      Modifier = DiagStr;
+      while (DiagStr[0] == '-' ||
+             (DiagStr[0] >= 'a' && DiagStr[0] <= 'z'))
+        ++DiagStr;
+      ModifierLen = DiagStr-Modifier;
+
+      // If we have an argument, get it next.
+      if (DiagStr[0] == '{') {
+        ++DiagStr; // Skip {.
+        Argument = DiagStr;
+
+        DiagStr = ScanFormat(DiagStr, DiagEnd, '}');
+        assert(DiagStr != DiagEnd && "Mismatched {}'s in diagnostic string!");
+        ArgumentLen = DiagStr-Argument;
+        ++DiagStr;  // Skip }.
+      }
+    }
+
+    assert(isdigit(*DiagStr) && "Invalid format for argument in diagnostic");
+    unsigned ArgNo = *DiagStr++ - '0';
+
+    Diagnostic::ArgumentKind Kind = getArgKind(ArgNo);
+    
+    switch (Kind) {
+    // ---- STRINGS ----
+    case Diagnostic::ak_std_string: {
+      const std::string &S = getArgStdStr(ArgNo);
+      assert(ModifierLen == 0 && "No modifiers for strings yet");
+      OutStr.append(S.begin(), S.end());
+      break;
+    }
+    case Diagnostic::ak_c_string: {
+      const char *S = getArgCStr(ArgNo);
+      assert(ModifierLen == 0 && "No modifiers for strings yet");
+
+      // Don't crash if get passed a null pointer by accident.
+      if (!S)
+        S = "(null)";
+
+      OutStr.append(S, S + strlen(S));
+      break;
+    }
+    // ---- INTEGERS ----
+    case Diagnostic::ak_sint: {
+      int Val = getArgSInt(ArgNo);
+
+      if (ModifierIs(Modifier, ModifierLen, "select")) {
+        HandleSelectModifier(*this, (unsigned)Val, Argument, ArgumentLen, OutStr);
+      } else if (ModifierIs(Modifier, ModifierLen, "s")) {
+        HandleIntegerSModifier(Val, OutStr);
+      } else if (ModifierIs(Modifier, ModifierLen, "plural")) {
+        HandlePluralModifier((unsigned)Val, Argument, ArgumentLen, OutStr);
+      } else if (ModifierIs(Modifier, ModifierLen, "ordinal")) {
+        HandleOrdinalModifier((unsigned)Val, OutStr);
+      } else {
+        assert(ModifierLen == 0 && "Unknown integer modifier");
+        llvm::raw_svector_ostream(OutStr) << Val;
+      }
+      break;
+    }
+    case Diagnostic::ak_uint: {
+      unsigned Val = getArgUInt(ArgNo);
+
+      if (ModifierIs(Modifier, ModifierLen, "select")) {
+        HandleSelectModifier(*this, Val, Argument, ArgumentLen, OutStr);
+      } else if (ModifierIs(Modifier, ModifierLen, "s")) {
+        HandleIntegerSModifier(Val, OutStr);
+      } else if (ModifierIs(Modifier, ModifierLen, "plural")) {
+        HandlePluralModifier((unsigned)Val, Argument, ArgumentLen, OutStr);
+      } else if (ModifierIs(Modifier, ModifierLen, "ordinal")) {
+        HandleOrdinalModifier(Val, OutStr);
+      } else {
+        assert(ModifierLen == 0 && "Unknown integer modifier");
+        llvm::raw_svector_ostream(OutStr) << Val;
+      }
+      break;
+    }
+    // ---- NAMES and TYPES ----
+    case Diagnostic::ak_identifierinfo: {
+      const IdentifierInfo *II = getArgIdentifier(ArgNo);
+      assert(ModifierLen == 0 && "No modifiers for strings yet");
+
+      // Don't crash if get passed a null pointer by accident.
+      if (!II) {
+        const char *S = "(null)";
+        OutStr.append(S, S + strlen(S));
+        continue;
+      }
+
+      llvm::raw_svector_ostream(OutStr) << '\'' << II->getName() << '\'';
+      break;
+    }
+    case Diagnostic::ak_qualtype:
+    case Diagnostic::ak_declarationname:
+    case Diagnostic::ak_nameddecl:
+    case Diagnostic::ak_nestednamespec:
+    case Diagnostic::ak_declcontext:
+      getDiags()->ConvertArgToString(Kind, getRawArg(ArgNo),
+                                     Modifier, ModifierLen,
+                                     Argument, ArgumentLen,
+                                     FormattedArgs.data(), FormattedArgs.size(),
+                                     OutStr);
+      break;
+    }
+    
+    // Remember this argument info for subsequent formatting operations.  Turn
+    // std::strings into a null terminated string to make it be the same case as
+    // all the other ones.
+    if (Kind != Diagnostic::ak_std_string)
+      FormattedArgs.push_back(std::make_pair(Kind, getRawArg(ArgNo)));
+    else
+      FormattedArgs.push_back(std::make_pair(Diagnostic::ak_c_string,
+                                        (intptr_t)getArgStdStr(ArgNo).c_str()));
+    
+  }
+}
+
+StoredDiagnostic::StoredDiagnostic() { }
+
+StoredDiagnostic::StoredDiagnostic(Diagnostic::Level Level, 
+                                   llvm::StringRef Message)
+  : Level(Level), Loc(), Message(Message) { }
+
+StoredDiagnostic::StoredDiagnostic(Diagnostic::Level Level, 
+                                   const DiagnosticInfo &Info)
+  : Level(Level), Loc(Info.getLocation()) 
+{
+  llvm::SmallString<64> Message;
+  Info.FormatDiagnostic(Message);
+  this->Message.assign(Message.begin(), Message.end());
+
+  Ranges.reserve(Info.getNumRanges());
+  for (unsigned I = 0, N = Info.getNumRanges(); I != N; ++I)
+    Ranges.push_back(Info.getRange(I));
+
+  FixIts.reserve(Info.getNumFixItHints());
+  for (unsigned I = 0, N = Info.getNumFixItHints(); I != N; ++I)
+    FixIts.push_back(Info.getFixItHint(I));
+}
+
+StoredDiagnostic::~StoredDiagnostic() { }
+
+static void WriteUnsigned(llvm::raw_ostream &OS, unsigned Value) {
+  OS.write((const char *)&Value, sizeof(unsigned));
+}
+
+static void WriteString(llvm::raw_ostream &OS, llvm::StringRef String) {
+  WriteUnsigned(OS, String.size());
+  OS.write(String.data(), String.size());
+}
+
+static void WriteSourceLocation(llvm::raw_ostream &OS, 
+                                SourceManager *SM,
+                                SourceLocation Location) {
+  if (!SM || Location.isInvalid()) {
+    // If we don't have a source manager or this location is invalid,
+    // just write an invalid location.
+    WriteUnsigned(OS, 0);
+    WriteUnsigned(OS, 0);
+    WriteUnsigned(OS, 0);
+    return;
+  }
+
+  Location = SM->getInstantiationLoc(Location);
+  std::pair<FileID, unsigned> Decomposed = SM->getDecomposedLoc(Location);
+
+  const FileEntry *FE = SM->getFileEntryForID(Decomposed.first);
+  if (FE)
+    WriteString(OS, FE->getName());
+  else {
+    // Fallback to using the buffer name when there is no entry.
+    WriteString(OS, SM->getBuffer(Decomposed.first)->getBufferIdentifier());
+  }
+
+  WriteUnsigned(OS, SM->getLineNumber(Decomposed.first, Decomposed.second));
+  WriteUnsigned(OS, SM->getColumnNumber(Decomposed.first, Decomposed.second));
+}
+
+void StoredDiagnostic::Serialize(llvm::raw_ostream &OS) const {
+  SourceManager *SM = 0;
+  if (getLocation().isValid())
+    SM = &const_cast<SourceManager &>(getLocation().getManager());
+
+  // Write a short header to help identify diagnostics.
+  OS << (char)0x06 << (char)0x07;
+  
+  // Write the diagnostic level and location.
+  WriteUnsigned(OS, (unsigned)Level);
+  WriteSourceLocation(OS, SM, getLocation());
+
+  // Write the diagnostic message.
+  llvm::SmallString<64> Message;
+  WriteString(OS, getMessage());
+  
+  // Count the number of ranges that don't point into macros, since
+  // only simple file ranges serialize well.
+  unsigned NumNonMacroRanges = 0;
+  for (range_iterator R = range_begin(), REnd = range_end(); R != REnd; ++R) {
+    if (R->getBegin().isMacroID() || R->getEnd().isMacroID())
+      continue;
+
+    ++NumNonMacroRanges;
+  }
+
+  // Write the ranges.
+  WriteUnsigned(OS, NumNonMacroRanges);
+  if (NumNonMacroRanges) {
+    for (range_iterator R = range_begin(), REnd = range_end(); R != REnd; ++R) {
+      if (R->getBegin().isMacroID() || R->getEnd().isMacroID())
+        continue;
+      
+      WriteSourceLocation(OS, SM, R->getBegin());
+      WriteSourceLocation(OS, SM, R->getEnd());
+    }
+  }
+
+  // Determine if all of the fix-its involve rewrites with simple file
+  // locations (not in macro instantiations). If so, we can write
+  // fix-it information.
+  unsigned NumFixIts = 0;
+  for (fixit_iterator F = fixit_begin(), FEnd = fixit_end(); F != FEnd; ++F) {
+    if (F->RemoveRange.isValid() &&
+        (F->RemoveRange.getBegin().isMacroID() ||
+         F->RemoveRange.getEnd().isMacroID())) {
+      NumFixIts = 0;
+      break;
+    }
+
+    if (F->InsertionLoc.isValid() && F->InsertionLoc.isMacroID()) {
+      NumFixIts = 0;
+      break;
+    }
+
+    ++NumFixIts;
+  }
+
+  // Write the fix-its.
+  WriteUnsigned(OS, NumFixIts);
+  for (fixit_iterator F = fixit_begin(), FEnd = fixit_end(); F != FEnd; ++F) {
+    WriteSourceLocation(OS, SM, F->RemoveRange.getBegin());
+    WriteSourceLocation(OS, SM, F->RemoveRange.getEnd());
+    WriteSourceLocation(OS, SM, F->InsertionLoc);
+    WriteString(OS, F->CodeToInsert);
+  }
+}
+
+static bool ReadUnsigned(const char *&Memory, const char *MemoryEnd,
+                         unsigned &Value) {
+  if (Memory + sizeof(unsigned) > MemoryEnd)
+    return true;
+
+  memmove(&Value, Memory, sizeof(unsigned));
+  Memory += sizeof(unsigned);
+  return false;
+}
+
+static bool ReadSourceLocation(FileManager &FM, SourceManager &SM,
+                               const char *&Memory, const char *MemoryEnd,
+                               SourceLocation &Location) {
+  // Read the filename.
+  unsigned FileNameLen = 0;
+  if (ReadUnsigned(Memory, MemoryEnd, FileNameLen) || 
+      Memory + FileNameLen > MemoryEnd)
+    return true;
+
+  llvm::StringRef FileName(Memory, FileNameLen);
+  Memory += FileNameLen;
+
+  // Read the line, column.
+  unsigned Line = 0, Column = 0;
+  if (ReadUnsigned(Memory, MemoryEnd, Line) ||
+      ReadUnsigned(Memory, MemoryEnd, Column))
+    return true;
+
+  if (FileName.empty()) {
+    Location = SourceLocation();
+    return false;
+  }
+
+  const FileEntry *File = FM.getFile(FileName);
+  if (!File)
+    return true;
+
+  // Make sure that this file has an entry in the source manager.
+  if (!SM.hasFileInfo(File))
+    SM.createFileID(File, SourceLocation(), SrcMgr::C_User);
+
+  Location = SM.getLocation(File, Line, Column);
+  return false;
+}
+
+StoredDiagnostic 
+StoredDiagnostic::Deserialize(FileManager &FM, SourceManager &SM, 
+                              const char *&Memory, const char *MemoryEnd) {
+  while (true) {
+    if (Memory == MemoryEnd)
+      return StoredDiagnostic();
+    
+    if (*Memory != 0x06) {
+      ++Memory;
+      continue;
+    }
+    
+    ++Memory;
+    if (Memory == MemoryEnd)
+      return StoredDiagnostic();
+  
+    if (*Memory != 0x07) {
+      ++Memory;
+      continue;
+    }
+    
+    // We found the header. We're done.
+    ++Memory;
+    break;
+  }
+  
+  // Read the severity level.
+  unsigned Level = 0;
+  if (ReadUnsigned(Memory, MemoryEnd, Level) || Level > Diagnostic::Fatal)
+    return StoredDiagnostic();
+
+  // Read the source location.
+  SourceLocation Location;
+  if (ReadSourceLocation(FM, SM, Memory, MemoryEnd, Location))
+    return StoredDiagnostic();
+
+  // Read the diagnostic text.
+  if (Memory == MemoryEnd)
+    return StoredDiagnostic();
+
+  unsigned MessageLen = 0;
+  if (ReadUnsigned(Memory, MemoryEnd, MessageLen) ||
+      Memory + MessageLen > MemoryEnd)
+    return StoredDiagnostic();
+  
+  llvm::StringRef Message(Memory, MessageLen);
+  Memory += MessageLen;
+
+
+  // At this point, we have enough information to form a diagnostic. Do so.
+  StoredDiagnostic Diag;
+  Diag.Level = (Diagnostic::Level)Level;
+  Diag.Loc = FullSourceLoc(Location, SM);
+  Diag.Message = Message;
+  if (Memory == MemoryEnd)
+    return Diag;
+
+  // Read the source ranges.
+  unsigned NumSourceRanges = 0;
+  if (ReadUnsigned(Memory, MemoryEnd, NumSourceRanges))
+    return Diag;
+  for (unsigned I = 0; I != NumSourceRanges; ++I) {
+    SourceLocation Begin, End;
+    if (ReadSourceLocation(FM, SM, Memory, MemoryEnd, Begin) ||
+        ReadSourceLocation(FM, SM, Memory, MemoryEnd, End))
+      return Diag;
+
+    Diag.Ranges.push_back(SourceRange(Begin, End));
+  }
+
+  // Read the fix-it hints.
+  unsigned NumFixIts = 0;
+  if (ReadUnsigned(Memory, MemoryEnd, NumFixIts))
+    return Diag;
+  for (unsigned I = 0; I != NumFixIts; ++I) {
+    SourceLocation RemoveBegin, RemoveEnd, InsertionLoc;
+    unsigned InsertLen = 0;
+    if (ReadSourceLocation(FM, SM, Memory, MemoryEnd, RemoveBegin) ||
+        ReadSourceLocation(FM, SM, Memory, MemoryEnd, RemoveEnd) ||
+        ReadSourceLocation(FM, SM, Memory, MemoryEnd, InsertionLoc) ||
+        ReadUnsigned(Memory, MemoryEnd, InsertLen) ||
+        Memory + InsertLen > MemoryEnd) {
+      Diag.FixIts.clear();
+      return Diag;
+    }
+
+    FixItHint Hint;
+    Hint.RemoveRange = SourceRange(RemoveBegin, RemoveEnd);
+    Hint.InsertionLoc = InsertionLoc;
+    Hint.CodeToInsert.assign(Memory, Memory + InsertLen);
+    Memory += InsertLen;
+    Diag.FixIts.push_back(Hint);
+  }
+
+  return Diag;
+}
+
+/// IncludeInDiagnosticCounts - This method (whose default implementation
+///  returns true) indicates whether the diagnostics handled by this
+///  DiagnosticClient should be included in the number of diagnostics
+///  reported by Diagnostic.
+bool DiagnosticClient::IncludeInDiagnosticCounts() const { return true; }
+
+PartialDiagnostic::StorageAllocator::StorageAllocator() {
+  for (unsigned I = 0; I != NumCached; ++I)
+    FreeList[I] = Cached + I;
+  NumFreeListEntries = NumCached;
+}
+
+PartialDiagnostic::StorageAllocator::~StorageAllocator() {
+  assert(NumFreeListEntries == NumCached && "A partial is on the lamb");
+}
diff --git a/lib/Basic/FileManager.cpp b/lib/Basic/FileManager.cpp
new file mode 100644
index 0000000..c4296c3
--- /dev/null
+++ b/lib/Basic/FileManager.cpp
@@ -0,0 +1,398 @@
+///===--- FileManager.cpp - File System Probing and Caching ----------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements the FileManager interface.
+//
+//===----------------------------------------------------------------------===//
+//
+// TODO: This should index all interesting directories with dirent calls.
+//  getdirentries ?
+//  opendir/readdir_r/closedir ?
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Basic/FileManager.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/System/Path.h"
+#include "llvm/Config/config.h"
+#include <map>
+#include <set>
+#include <string>
+using namespace clang;
+
+// FIXME: Enhance libsystem to support inode and other fields.
+#include <sys/stat.h>
+
+#if defined(_MSC_VER)
+#define S_ISDIR(s) (_S_IFDIR & s)
+#endif
+
+/// NON_EXISTENT_DIR - A special value distinct from null that is used to
+/// represent a dir name that doesn't exist on the disk.
+#define NON_EXISTENT_DIR reinterpret_cast<DirectoryEntry*>((intptr_t)-1)
+
+//===----------------------------------------------------------------------===//
+// Windows.
+//===----------------------------------------------------------------------===//
+
+#ifdef LLVM_ON_WIN32
+
+#define IS_DIR_SEPARATOR_CHAR(x) ((x) == '/' || (x) == '\\')
+
+namespace {
+  static std::string GetFullPath(const char *relPath) {
+    char *absPathStrPtr = _fullpath(NULL, relPath, 0);
+    assert(absPathStrPtr && "_fullpath() returned NULL!");
+
+    std::string absPath(absPathStrPtr);
+
+    free(absPathStrPtr);
+    return absPath;
+  }
+}
+
+class FileManager::UniqueDirContainer {
+  /// UniqueDirs - Cache from full path to existing directories/files.
+  ///
+  llvm::StringMap<DirectoryEntry> UniqueDirs;
+
+public:
+  DirectoryEntry &getDirectory(const char *Name, struct stat &StatBuf) {
+    std::string FullPath(GetFullPath(Name));
+    return UniqueDirs.GetOrCreateValue(
+                              FullPath.c_str(),
+                              FullPath.c_str() + FullPath.size()
+                                                                ).getValue();
+  }
+
+  size_t size() { return UniqueDirs.size(); }
+};
+
+class FileManager::UniqueFileContainer {
+  /// UniqueFiles - Cache from full path to existing directories/files.
+  ///
+  llvm::StringMap<FileEntry, llvm::BumpPtrAllocator> UniqueFiles;
+
+public:
+  FileEntry &getFile(const char *Name, struct stat &StatBuf) {
+    std::string FullPath(GetFullPath(Name));
+    return UniqueFiles.GetOrCreateValue(
+                               FullPath.c_str(),
+                               FullPath.c_str() + FullPath.size()
+                                                                 ).getValue();
+  }
+
+  size_t size() { return UniqueFiles.size(); }
+};
+
+//===----------------------------------------------------------------------===//
+// Unix-like Systems.
+//===----------------------------------------------------------------------===//
+
+#else
+
+#define IS_DIR_SEPARATOR_CHAR(x) ((x) == '/')
+
+class FileManager::UniqueDirContainer {
+  /// UniqueDirs - Cache from ID's to existing directories/files.
+  ///
+  std::map<std::pair<dev_t, ino_t>, DirectoryEntry> UniqueDirs;
+
+public:
+  DirectoryEntry &getDirectory(const char *Name, struct stat &StatBuf) {
+    return UniqueDirs[std::make_pair(StatBuf.st_dev, StatBuf.st_ino)];
+  }
+
+  size_t size() { return UniqueDirs.size(); }
+};
+
+class FileManager::UniqueFileContainer {
+  /// UniqueFiles - Cache from ID's to existing directories/files.
+  ///
+  std::set<FileEntry> UniqueFiles;
+
+public:
+  FileEntry &getFile(const char *Name, struct stat &StatBuf) {
+    return
+      const_cast<FileEntry&>(
+                    *UniqueFiles.insert(FileEntry(StatBuf.st_dev,
+                                                  StatBuf.st_ino,
+                                                  StatBuf.st_mode)).first);
+  }
+
+  size_t size() { return UniqueFiles.size(); }
+};
+
+#endif
+
+//===----------------------------------------------------------------------===//
+// Common logic.
+//===----------------------------------------------------------------------===//
+
+FileManager::FileManager()
+  : UniqueDirs(*new UniqueDirContainer),
+    UniqueFiles(*new UniqueFileContainer),
+    DirEntries(64), FileEntries(64), NextFileUID(0) {
+  NumDirLookups = NumFileLookups = 0;
+  NumDirCacheMisses = NumFileCacheMisses = 0;
+}
+
+FileManager::~FileManager() {
+  delete &UniqueDirs;
+  delete &UniqueFiles;
+  for (llvm::SmallVectorImpl<FileEntry *>::iterator
+         V = VirtualFileEntries.begin(),
+         VEnd = VirtualFileEntries.end();
+       V != VEnd; 
+       ++V)
+    delete *V;
+}
+
+void FileManager::addStatCache(StatSysCallCache *statCache, bool AtBeginning) {
+  assert(statCache && "No stat cache provided?");
+  if (AtBeginning || StatCache.get() == 0) {
+    statCache->setNextStatCache(StatCache.take());
+    StatCache.reset(statCache);
+    return;
+  }
+  
+  StatSysCallCache *LastCache = StatCache.get();
+  while (LastCache->getNextStatCache())
+    LastCache = LastCache->getNextStatCache();
+  
+  LastCache->setNextStatCache(statCache);
+}
+
+void FileManager::removeStatCache(StatSysCallCache *statCache) {
+  if (!statCache)
+    return;
+  
+  if (StatCache.get() == statCache) {
+    // This is the first stat cache.
+    StatCache.reset(StatCache->takeNextStatCache());
+    return;
+  }
+  
+  // Find the stat cache in the list.
+  StatSysCallCache *PrevCache = StatCache.get();
+  while (PrevCache && PrevCache->getNextStatCache() != statCache)
+    PrevCache = PrevCache->getNextStatCache();
+  if (PrevCache)
+    PrevCache->setNextStatCache(statCache->getNextStatCache());
+  else
+    assert(false && "Stat cache not found for removal");
+}
+
+/// \brief Retrieve the directory that the given file name resides in.
+static const DirectoryEntry *getDirectoryFromFile(FileManager &FileMgr,
+                                                  const char *NameStart,
+                                                  const char *NameEnd) {
+  // Figure out what directory it is in.   If the string contains a / in it,
+  // strip off everything after it.
+  // FIXME: this logic should be in sys::Path.
+  const char *SlashPos = NameEnd-1;
+  while (SlashPos >= NameStart && !IS_DIR_SEPARATOR_CHAR(SlashPos[0]))
+    --SlashPos;
+  // Ignore duplicate //'s.
+  while (SlashPos > NameStart && IS_DIR_SEPARATOR_CHAR(SlashPos[-1]))
+    --SlashPos;
+
+  if (SlashPos < NameStart) {
+    // Use the current directory if file has no path component.
+    const char *Name = ".";
+    return FileMgr.getDirectory(Name, Name+1);
+  } else if (SlashPos == NameEnd-1)
+    return 0;       // If filename ends with a /, it's a directory.
+  else
+    return FileMgr.getDirectory(NameStart, SlashPos);
+}
+
+/// getDirectory - Lookup, cache, and verify the specified directory.  This
+/// returns null if the directory doesn't exist.
+///
+const DirectoryEntry *FileManager::getDirectory(const char *NameStart,
+                                                const char *NameEnd) {
+  // stat doesn't like trailing separators (at least on Windows).
+  if (((NameEnd - NameStart) > 1) &&
+      ((*(NameEnd - 1) == '/') || (*(NameEnd - 1) == '\\')))
+    NameEnd--;
+
+  ++NumDirLookups;
+  llvm::StringMapEntry<DirectoryEntry *> &NamedDirEnt =
+    DirEntries.GetOrCreateValue(NameStart, NameEnd);
+
+  // See if there is already an entry in the map.
+  if (NamedDirEnt.getValue())
+    return NamedDirEnt.getValue() == NON_EXISTENT_DIR
+              ? 0 : NamedDirEnt.getValue();
+
+  ++NumDirCacheMisses;
+
+  // By default, initialize it to invalid.
+  NamedDirEnt.setValue(NON_EXISTENT_DIR);
+
+  // Get the null-terminated directory name as stored as the key of the
+  // DirEntries map.
+  const char *InterndDirName = NamedDirEnt.getKeyData();
+
+  // Check to see if the directory exists.
+  struct stat StatBuf;
+  if (stat_cached(InterndDirName, &StatBuf) ||   // Error stat'ing.
+      !S_ISDIR(StatBuf.st_mode))          // Not a directory?
+    return 0;
+
+  // It exists.  See if we have already opened a directory with the same inode.
+  // This occurs when one dir is symlinked to another, for example.
+  DirectoryEntry &UDE = UniqueDirs.getDirectory(InterndDirName, StatBuf);
+
+  NamedDirEnt.setValue(&UDE);
+  if (UDE.getName()) // Already have an entry with this inode, return it.
+    return &UDE;
+
+  // Otherwise, we don't have this directory yet, add it.  We use the string
+  // key from the DirEntries map as the string.
+  UDE.Name  = InterndDirName;
+  return &UDE;
+}
+
+/// NON_EXISTENT_FILE - A special value distinct from null that is used to
+/// represent a filename that doesn't exist on the disk.
+#define NON_EXISTENT_FILE reinterpret_cast<FileEntry*>((intptr_t)-1)
+
+/// getFile - Lookup, cache, and verify the specified file.  This returns null
+/// if the file doesn't exist.
+///
+const FileEntry *FileManager::getFile(const char *NameStart,
+                                      const char *NameEnd) {
+  ++NumFileLookups;
+
+  // See if there is already an entry in the map.
+  llvm::StringMapEntry<FileEntry *> &NamedFileEnt =
+    FileEntries.GetOrCreateValue(NameStart, NameEnd);
+
+  // See if there is already an entry in the map.
+  if (NamedFileEnt.getValue())
+    return NamedFileEnt.getValue() == NON_EXISTENT_FILE
+                 ? 0 : NamedFileEnt.getValue();
+
+  ++NumFileCacheMisses;
+
+  // By default, initialize it to invalid.
+  NamedFileEnt.setValue(NON_EXISTENT_FILE);
+
+
+  // Get the null-terminated file name as stored as the key of the
+  // FileEntries map.
+  const char *InterndFileName = NamedFileEnt.getKeyData();
+
+  const DirectoryEntry *DirInfo
+    = getDirectoryFromFile(*this, NameStart, NameEnd);
+  if (DirInfo == 0)  // Directory doesn't exist, file can't exist.
+    return 0;
+
+  // FIXME: Use the directory info to prune this, before doing the stat syscall.
+  // FIXME: This will reduce the # syscalls.
+
+  // Nope, there isn't.  Check to see if the file exists.
+  struct stat StatBuf;
+  //llvm::errs() << "STATING: " << Filename;
+  if (stat_cached(InterndFileName, &StatBuf) ||   // Error stat'ing.
+        S_ISDIR(StatBuf.st_mode)) {           // A directory?
+    // If this file doesn't exist, we leave a null in FileEntries for this path.
+    //llvm::errs() << ": Not existing\n";
+    return 0;
+  }
+  //llvm::errs() << ": exists\n";
+
+  // It exists.  See if we have already opened a file with the same inode.
+  // This occurs when one dir is symlinked to another, for example.
+  FileEntry &UFE = UniqueFiles.getFile(InterndFileName, StatBuf);
+
+  NamedFileEnt.setValue(&UFE);
+  if (UFE.getName())  // Already have an entry with this inode, return it.
+    return &UFE;
+
+  // Otherwise, we don't have this directory yet, add it.
+  // FIXME: Change the name to be a char* that points back to the 'FileEntries'
+  // key.
+  UFE.Name    = InterndFileName;
+  UFE.Size    = StatBuf.st_size;
+  UFE.ModTime = StatBuf.st_mtime;
+  UFE.Dir     = DirInfo;
+  UFE.UID     = NextFileUID++;
+  return &UFE;
+}
+
+const FileEntry *
+FileManager::getVirtualFile(const llvm::StringRef &Filename,
+                            off_t Size, time_t ModificationTime) {
+  const char *NameStart = Filename.begin(), *NameEnd = Filename.end();
+
+  ++NumFileLookups;
+
+  // See if there is already an entry in the map.
+  llvm::StringMapEntry<FileEntry *> &NamedFileEnt =
+    FileEntries.GetOrCreateValue(NameStart, NameEnd);
+
+  // See if there is already an entry in the map.
+  if (NamedFileEnt.getValue())
+    return NamedFileEnt.getValue() == NON_EXISTENT_FILE
+                 ? 0 : NamedFileEnt.getValue();
+
+  ++NumFileCacheMisses;
+
+  // By default, initialize it to invalid.
+  NamedFileEnt.setValue(NON_EXISTENT_FILE);
+
+  const DirectoryEntry *DirInfo
+    = getDirectoryFromFile(*this, NameStart, NameEnd);
+  if (DirInfo == 0)  // Directory doesn't exist, file can't exist.
+    return 0;
+
+  FileEntry *UFE = new FileEntry();
+  VirtualFileEntries.push_back(UFE);
+  NamedFileEnt.setValue(UFE);
+
+  UFE->Name    = NamedFileEnt.getKeyData();
+  UFE->Size    = Size;
+  UFE->ModTime = ModificationTime;
+  UFE->Dir     = DirInfo;
+  UFE->UID     = NextFileUID++;
+  return UFE;
+}
+
+void FileManager::PrintStats() const {
+  llvm::errs() << "\n*** File Manager Stats:\n";
+  llvm::errs() << UniqueFiles.size() << " files found, "
+               << UniqueDirs.size() << " dirs found.\n";
+  llvm::errs() << NumDirLookups << " dir lookups, "
+               << NumDirCacheMisses << " dir cache misses.\n";
+  llvm::errs() << NumFileLookups << " file lookups, "
+               << NumFileCacheMisses << " file cache misses.\n";
+
+  //llvm::errs() << PagesMapped << BytesOfPagesMapped << FSLookups;
+}
+
+int MemorizeStatCalls::stat(const char *path, struct stat *buf) {
+  int result = StatSysCallCache::stat(path, buf);
+  
+  // Do not cache failed stats, it is easy to construct common inconsistent
+  // situations if we do, and they are not important for PCH performance (which
+  // currently only needs the stats to construct the initial FileManager
+  // entries).
+  if (result != 0)
+    return result;
+
+  // Cache file 'stat' results and directories with absolutely paths.
+  if (!S_ISDIR(buf->st_mode) || llvm::sys::Path(path).isAbsolute())
+    StatCalls[path] = StatResult(result, *buf);
+
+  return result;
+}
diff --git a/lib/Basic/IdentifierTable.cpp b/lib/Basic/IdentifierTable.cpp
new file mode 100644
index 0000000..ed0de8c
--- /dev/null
+++ b/lib/Basic/IdentifierTable.cpp
@@ -0,0 +1,400 @@
+//===--- IdentifierTable.cpp - Hash table for identifier lookup -----------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the IdentifierInfo, IdentifierVisitor, and
+// IdentifierTable interfaces.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/LangOptions.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cstdio>
+
+using namespace clang;
+
+//===----------------------------------------------------------------------===//
+// IdentifierInfo Implementation
+//===----------------------------------------------------------------------===//
+
+IdentifierInfo::IdentifierInfo() {
+  TokenID = tok::identifier;
+  ObjCOrBuiltinID = 0;
+  HasMacro = false;
+  IsExtension = false;
+  IsPoisoned = false;
+  IsCPPOperatorKeyword = false;
+  NeedsHandleIdentifier = false;
+  FETokenInfo = 0;
+  Entry = 0;
+}
+
+//===----------------------------------------------------------------------===//
+// IdentifierTable Implementation
+//===----------------------------------------------------------------------===//
+
+IdentifierInfoLookup::~IdentifierInfoLookup() {}
+
+ExternalIdentifierLookup::~ExternalIdentifierLookup() {}
+
+IdentifierTable::IdentifierTable(const LangOptions &LangOpts,
+                                 IdentifierInfoLookup* externalLookup)
+  : HashTable(8192), // Start with space for 8K identifiers.
+    ExternalLookup(externalLookup) {
+
+  // Populate the identifier table with info about keywords for the current
+  // language.
+  AddKeywords(LangOpts);
+}
+
+//===----------------------------------------------------------------------===//
+// Language Keyword Implementation
+//===----------------------------------------------------------------------===//
+
+// Constants for TokenKinds.def
+namespace {
+  enum {
+    KEYALL = 1,
+    KEYC99 = 2,
+    KEYCXX = 4,
+    KEYCXX0X = 8,
+    KEYGNU = 16,
+    KEYMS = 32,
+    BOOLSUPPORT = 64,
+    KEYALTIVEC = 128
+  };
+}
+
+/// AddKeyword - This method is used to associate a token ID with specific
+/// identifiers because they are language keywords.  This causes the lexer to
+/// automatically map matching identifiers to specialized token codes.
+///
+/// The C90/C99/CPP/CPP0x flags are set to 2 if the token should be
+/// enabled in the specified langauge, set to 1 if it is an extension
+/// in the specified language, and set to 0 if disabled in the
+/// specified language.
+static void AddKeyword(llvm::StringRef Keyword,
+                       tok::TokenKind TokenCode, unsigned Flags,
+                       const LangOptions &LangOpts, IdentifierTable &Table) {
+  unsigned AddResult = 0;
+  if (Flags & KEYALL) AddResult = 2;
+  else if (LangOpts.CPlusPlus && (Flags & KEYCXX)) AddResult = 2;
+  else if (LangOpts.CPlusPlus0x && (Flags & KEYCXX0X)) AddResult = 2;
+  else if (LangOpts.C99 && (Flags & KEYC99)) AddResult = 2;
+  else if (LangOpts.GNUKeywords && (Flags & KEYGNU)) AddResult = 1;
+  else if (LangOpts.Microsoft && (Flags & KEYMS)) AddResult = 1;
+  else if (LangOpts.Bool && (Flags & BOOLSUPPORT)) AddResult = 2;
+  else if (LangOpts.AltiVec && (Flags & KEYALTIVEC)) AddResult = 2;
+
+  // Don't add this keyword if disabled in this language.
+  if (AddResult == 0) return;
+
+  IdentifierInfo &Info = Table.get(Keyword);
+  Info.setTokenID(TokenCode);
+  Info.setIsExtensionToken(AddResult == 1);
+}
+
+/// AddCXXOperatorKeyword - Register a C++ operator keyword alternative
+/// representations.
+static void AddCXXOperatorKeyword(llvm::StringRef Keyword,
+                                  tok::TokenKind TokenCode,
+                                  IdentifierTable &Table) {
+  IdentifierInfo &Info = Table.get(Keyword);
+  Info.setTokenID(TokenCode);
+  Info.setIsCPlusPlusOperatorKeyword();
+}
+
+/// AddObjCKeyword - Register an Objective-C @keyword like "class" "selector" or
+/// "property".
+static void AddObjCKeyword(llvm::StringRef Name,
+                           tok::ObjCKeywordKind ObjCID,
+                           IdentifierTable &Table) {
+  Table.get(Name).setObjCKeywordID(ObjCID);
+}
+
+/// AddKeywords - Add all keywords to the symbol table.
+///
+void IdentifierTable::AddKeywords(const LangOptions &LangOpts) {
+  // Add keywords and tokens for the current language.
+#define KEYWORD(NAME, FLAGS) \
+  AddKeyword(llvm::StringRef(#NAME), tok::kw_ ## NAME,  \
+             FLAGS, LangOpts, *this);
+#define ALIAS(NAME, TOK, FLAGS) \
+  AddKeyword(llvm::StringRef(NAME), tok::kw_ ## TOK,  \
+             FLAGS, LangOpts, *this);
+#define CXX_KEYWORD_OPERATOR(NAME, ALIAS) \
+  if (LangOpts.CXXOperatorNames)          \
+    AddCXXOperatorKeyword(llvm::StringRef(#NAME), tok::ALIAS, *this);
+#define OBJC1_AT_KEYWORD(NAME) \
+  if (LangOpts.ObjC1)          \
+    AddObjCKeyword(llvm::StringRef(#NAME), tok::objc_##NAME, *this);
+#define OBJC2_AT_KEYWORD(NAME) \
+  if (LangOpts.ObjC2)          \
+    AddObjCKeyword(llvm::StringRef(#NAME), tok::objc_##NAME, *this);
+#include "clang/Basic/TokenKinds.def"
+}
+
+tok::PPKeywordKind IdentifierInfo::getPPKeywordID() const {
+  // We use a perfect hash function here involving the length of the keyword,
+  // the first and third character.  For preprocessor ID's there are no
+  // collisions (if there were, the switch below would complain about duplicate
+  // case values).  Note that this depends on 'if' being null terminated.
+
+#define HASH(LEN, FIRST, THIRD) \
+  (LEN << 5) + (((FIRST-'a') + (THIRD-'a')) & 31)
+#define CASE(LEN, FIRST, THIRD, NAME) \
+  case HASH(LEN, FIRST, THIRD): \
+    return memcmp(Name, #NAME, LEN) ? tok::pp_not_keyword : tok::pp_ ## NAME
+
+  unsigned Len = getLength();
+  if (Len < 2) return tok::pp_not_keyword;
+  const char *Name = getNameStart();
+  switch (HASH(Len, Name[0], Name[2])) {
+  default: return tok::pp_not_keyword;
+  CASE( 2, 'i', '\0', if);
+  CASE( 4, 'e', 'i', elif);
+  CASE( 4, 'e', 's', else);
+  CASE( 4, 'l', 'n', line);
+  CASE( 4, 's', 'c', sccs);
+  CASE( 5, 'e', 'd', endif);
+  CASE( 5, 'e', 'r', error);
+  CASE( 5, 'i', 'e', ident);
+  CASE( 5, 'i', 'd', ifdef);
+  CASE( 5, 'u', 'd', undef);
+
+  CASE( 6, 'a', 's', assert);
+  CASE( 6, 'd', 'f', define);
+  CASE( 6, 'i', 'n', ifndef);
+  CASE( 6, 'i', 'p', import);
+  CASE( 6, 'p', 'a', pragma);
+
+  CASE( 7, 'd', 'f', defined);
+  CASE( 7, 'i', 'c', include);
+  CASE( 7, 'w', 'r', warning);
+
+  CASE( 8, 'u', 'a', unassert);
+  CASE(12, 'i', 'c', include_next);
+
+  CASE(16, '_', 'i', __include_macros);
+#undef CASE
+#undef HASH
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// Stats Implementation
+//===----------------------------------------------------------------------===//
+
+/// PrintStats - Print statistics about how well the identifier table is doing
+/// at hashing identifiers.
+void IdentifierTable::PrintStats() const {
+  unsigned NumBuckets = HashTable.getNumBuckets();
+  unsigned NumIdentifiers = HashTable.getNumItems();
+  unsigned NumEmptyBuckets = NumBuckets-NumIdentifiers;
+  unsigned AverageIdentifierSize = 0;
+  unsigned MaxIdentifierLength = 0;
+
+  // TODO: Figure out maximum times an identifier had to probe for -stats.
+  for (llvm::StringMap<IdentifierInfo*, llvm::BumpPtrAllocator>::const_iterator
+       I = HashTable.begin(), E = HashTable.end(); I != E; ++I) {
+    unsigned IdLen = I->getKeyLength();
+    AverageIdentifierSize += IdLen;
+    if (MaxIdentifierLength < IdLen)
+      MaxIdentifierLength = IdLen;
+  }
+
+  fprintf(stderr, "\n*** Identifier Table Stats:\n");
+  fprintf(stderr, "# Identifiers:   %d\n", NumIdentifiers);
+  fprintf(stderr, "# Empty Buckets: %d\n", NumEmptyBuckets);
+  fprintf(stderr, "Hash density (#identifiers per bucket): %f\n",
+          NumIdentifiers/(double)NumBuckets);
+  fprintf(stderr, "Ave identifier length: %f\n",
+          (AverageIdentifierSize/(double)NumIdentifiers));
+  fprintf(stderr, "Max identifier length: %d\n", MaxIdentifierLength);
+
+  // Compute statistics about the memory allocated for identifiers.
+  HashTable.getAllocator().PrintStats();
+}
+
+//===----------------------------------------------------------------------===//
+// SelectorTable Implementation
+//===----------------------------------------------------------------------===//
+
+unsigned llvm::DenseMapInfo<clang::Selector>::getHashValue(clang::Selector S) {
+  return DenseMapInfo<void*>::getHashValue(S.getAsOpaquePtr());
+}
+
+namespace clang {
+/// MultiKeywordSelector - One of these variable length records is kept for each
+/// selector containing more than one keyword. We use a folding set
+/// to unique aggregate names (keyword selectors in ObjC parlance). Access to
+/// this class is provided strictly through Selector.
+class MultiKeywordSelector
+  : public DeclarationNameExtra, public llvm::FoldingSetNode {
+  MultiKeywordSelector(unsigned nKeys) {
+    ExtraKindOrNumArgs = NUM_EXTRA_KINDS + nKeys;
+  }
+public:
+  // Constructor for keyword selectors.
+  MultiKeywordSelector(unsigned nKeys, IdentifierInfo **IIV) {
+    assert((nKeys > 1) && "not a multi-keyword selector");
+    ExtraKindOrNumArgs = NUM_EXTRA_KINDS + nKeys;
+
+    // Fill in the trailing keyword array.
+    IdentifierInfo **KeyInfo = reinterpret_cast<IdentifierInfo **>(this+1);
+    for (unsigned i = 0; i != nKeys; ++i)
+      KeyInfo[i] = IIV[i];
+  }
+
+  // getName - Derive the full selector name and return it.
+  std::string getName() const;
+
+  unsigned getNumArgs() const { return ExtraKindOrNumArgs - NUM_EXTRA_KINDS; }
+
+  typedef IdentifierInfo *const *keyword_iterator;
+  keyword_iterator keyword_begin() const {
+    return reinterpret_cast<keyword_iterator>(this+1);
+  }
+  keyword_iterator keyword_end() const {
+    return keyword_begin()+getNumArgs();
+  }
+  IdentifierInfo *getIdentifierInfoForSlot(unsigned i) const {
+    assert(i < getNumArgs() && "getIdentifierInfoForSlot(): illegal index");
+    return keyword_begin()[i];
+  }
+  static void Profile(llvm::FoldingSetNodeID &ID,
+                      keyword_iterator ArgTys, unsigned NumArgs) {
+    ID.AddInteger(NumArgs);
+    for (unsigned i = 0; i != NumArgs; ++i)
+      ID.AddPointer(ArgTys[i]);
+  }
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    Profile(ID, keyword_begin(), getNumArgs());
+  }
+};
+} // end namespace clang.
+
+unsigned Selector::getNumArgs() const {
+  unsigned IIF = getIdentifierInfoFlag();
+  if (IIF == ZeroArg)
+    return 0;
+  if (IIF == OneArg)
+    return 1;
+  // We point to a MultiKeywordSelector (pointer doesn't contain any flags).
+  MultiKeywordSelector *SI = reinterpret_cast<MultiKeywordSelector *>(InfoPtr);
+  return SI->getNumArgs();
+}
+
+IdentifierInfo *Selector::getIdentifierInfoForSlot(unsigned argIndex) const {
+  if (getIdentifierInfoFlag()) {
+    assert(argIndex == 0 && "illegal keyword index");
+    return getAsIdentifierInfo();
+  }
+  // We point to a MultiKeywordSelector (pointer doesn't contain any flags).
+  MultiKeywordSelector *SI = reinterpret_cast<MultiKeywordSelector *>(InfoPtr);
+  return SI->getIdentifierInfoForSlot(argIndex);
+}
+
+std::string MultiKeywordSelector::getName() const {
+  llvm::SmallString<256> Str;
+  llvm::raw_svector_ostream OS(Str);
+  for (keyword_iterator I = keyword_begin(), E = keyword_end(); I != E; ++I) {
+    if (*I)
+      OS << (*I)->getName();
+    OS << ':';
+  }
+
+  return OS.str();
+}
+
+std::string Selector::getAsString() const {
+  if (InfoPtr == 0)
+    return "<null selector>";
+
+  if (InfoPtr & ArgFlags) {
+    IdentifierInfo *II = getAsIdentifierInfo();
+
+    // If the number of arguments is 0 then II is guaranteed to not be null.
+    if (getNumArgs() == 0)
+      return II->getName();
+
+    if (!II)
+      return ":";
+
+    return II->getName().str() + ":";
+  }
+
+  // We have a multiple keyword selector (no embedded flags).
+  return reinterpret_cast<MultiKeywordSelector *>(InfoPtr)->getName();
+}
+
+
+namespace {
+  struct SelectorTableImpl {
+    llvm::FoldingSet<MultiKeywordSelector> Table;
+    llvm::BumpPtrAllocator Allocator;
+  };
+} // end anonymous namespace.
+
+static SelectorTableImpl &getSelectorTableImpl(void *P) {
+  return *static_cast<SelectorTableImpl*>(P);
+}
+
+
+Selector SelectorTable::getSelector(unsigned nKeys, IdentifierInfo **IIV) {
+  if (nKeys < 2)
+    return Selector(IIV[0], nKeys);
+
+  SelectorTableImpl &SelTabImpl = getSelectorTableImpl(Impl);
+
+  // Unique selector, to guarantee there is one per name.
+  llvm::FoldingSetNodeID ID;
+  MultiKeywordSelector::Profile(ID, IIV, nKeys);
+
+  void *InsertPos = 0;
+  if (MultiKeywordSelector *SI =
+        SelTabImpl.Table.FindNodeOrInsertPos(ID, InsertPos))
+    return Selector(SI);
+
+  // MultiKeywordSelector objects are not allocated with new because they have a
+  // variable size array (for parameter types) at the end of them.
+  unsigned Size = sizeof(MultiKeywordSelector) + nKeys*sizeof(IdentifierInfo *);
+  MultiKeywordSelector *SI =
+    (MultiKeywordSelector*)SelTabImpl.Allocator.Allocate(Size,
+                                         llvm::alignof<MultiKeywordSelector>());
+  new (SI) MultiKeywordSelector(nKeys, IIV);
+  SelTabImpl.Table.InsertNode(SI, InsertPos);
+  return Selector(SI);
+}
+
+SelectorTable::SelectorTable() {
+  Impl = new SelectorTableImpl();
+}
+
+SelectorTable::~SelectorTable() {
+  delete &getSelectorTableImpl(Impl);
+}
+
+const char *clang::getOperatorSpelling(OverloadedOperatorKind Operator) {
+  switch (Operator) {
+  case OO_None:
+  case NUM_OVERLOADED_OPERATORS:
+    return 0;
+
+#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
+  case OO_##Name: return Spelling;
+#include "clang/Basic/OperatorKinds.def"
+  }
+
+  return 0;
+}
+
diff --git a/lib/Basic/Makefile b/lib/Basic/Makefile
new file mode 100644
index 0000000..58ac7eb
--- /dev/null
+++ b/lib/Basic/Makefile
@@ -0,0 +1,35 @@
+##===- clang/lib/Basic/Makefile ----------------------------*- Makefile -*-===##
+# 
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+# 
+##===----------------------------------------------------------------------===##
+#
+#  This implements the Basic library for the C-Language front-end.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../../../..
+LIBRARYNAME := clangBasic
+BUILD_ARCHIVE = 1
+
+CPPFLAGS += -I$(PROJ_SRC_DIR)/../../include -I$(PROJ_OBJ_DIR)/../../include
+ifdef CLANG_VENDOR
+CPPFLAGS += -DCLANG_VENDOR='"$(CLANG_VENDOR) "'
+endif
+
+include $(LEVEL)/Makefile.common
+
+SVN_REVISION := $(shell $(LLVM_SRC_ROOT)/utils/GetSourceVersion $(PROJ_SRC_DIR)/../..)
+
+CPP.Defines += -I$(PROJ_SRC_DIR)/../../include -I$(PROJ_OBJ_DIR)/../../include \
+         -DSVN_REVISION='"$(SVN_REVISION)"'
+
+$(ObjDir)/.ver-svn .ver: $(ObjDir)/.dir
+	@if [ '$(SVN_REVISION)' != '$(shell cat $(ObjDir)/.ver-svn 2>/dev/null)' ]; then\
+		echo '$(SVN_REVISION)' > $(ObjDir)/.ver-svn;			\
+	fi
+$(ObjDir)/.ver-svn: .ver
+$(ObjDir)/Version.o: $(ObjDir)/.ver-svn
diff --git a/lib/Basic/SourceLocation.cpp b/lib/Basic/SourceLocation.cpp
new file mode 100644
index 0000000..7412b95
--- /dev/null
+++ b/lib/Basic/SourceLocation.cpp
@@ -0,0 +1,124 @@
+//==--- SourceLocation.cpp - Compact identifier for Source Files -*- C++ -*-==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines accessor methods for the FullSourceLoc class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/PrettyStackTrace.h"
+#include "clang/Basic/SourceManager.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cstdio>
+using namespace clang;
+
+//===----------------------------------------------------------------------===//
+// PrettyStackTraceLoc
+//===----------------------------------------------------------------------===//
+
+void PrettyStackTraceLoc::print(llvm::raw_ostream &OS) const {
+  if (Loc.isValid()) {
+    Loc.print(OS, SM);
+    OS << ": ";
+  }
+  OS << Message << '\n';
+}
+
+//===----------------------------------------------------------------------===//
+// SourceLocation
+//===----------------------------------------------------------------------===//
+
+void SourceLocation::print(llvm::raw_ostream &OS, const SourceManager &SM)const{
+  if (!isValid()) {
+    OS << "<invalid loc>";
+    return;
+  }
+
+  if (isFileID()) {
+    PresumedLoc PLoc = SM.getPresumedLoc(*this);
+    // The instantiation and spelling pos is identical for file locs.
+    OS << PLoc.getFilename() << ':' << PLoc.getLine()
+       << ':' << PLoc.getColumn();
+    return;
+  }
+
+  SM.getInstantiationLoc(*this).print(OS, SM);
+
+  OS << " <Spelling=";
+  SM.getSpellingLoc(*this).print(OS, SM);
+  OS << '>';
+}
+
+void SourceLocation::dump(const SourceManager &SM) const {
+  print(llvm::errs(), SM);
+}
+
+//===----------------------------------------------------------------------===//
+// FullSourceLoc
+//===----------------------------------------------------------------------===//
+
+FileID FullSourceLoc::getFileID() const {
+  assert(isValid());
+  return SrcMgr->getFileID(*this);
+}
+
+
+FullSourceLoc FullSourceLoc::getInstantiationLoc() const {
+  assert(isValid());
+  return FullSourceLoc(SrcMgr->getInstantiationLoc(*this), *SrcMgr);
+}
+
+FullSourceLoc FullSourceLoc::getSpellingLoc() const {
+  assert(isValid());
+  return FullSourceLoc(SrcMgr->getSpellingLoc(*this), *SrcMgr);
+}
+
+unsigned FullSourceLoc::getInstantiationLineNumber(bool *Invalid) const {
+  assert(isValid());
+  return SrcMgr->getInstantiationLineNumber(*this, Invalid);
+}
+
+unsigned FullSourceLoc::getInstantiationColumnNumber(bool *Invalid) const {
+  assert(isValid());
+  return SrcMgr->getInstantiationColumnNumber(*this, Invalid);
+}
+
+unsigned FullSourceLoc::getSpellingLineNumber(bool *Invalid) const {
+  assert(isValid());
+  return SrcMgr->getSpellingLineNumber(*this, Invalid);
+}
+
+unsigned FullSourceLoc::getSpellingColumnNumber(bool *Invalid) const {
+  assert(isValid());
+  return SrcMgr->getSpellingColumnNumber(*this, Invalid);
+}
+
+bool FullSourceLoc::isInSystemHeader() const {
+  assert(isValid());
+  return SrcMgr->isInSystemHeader(*this);
+}
+
+const char *FullSourceLoc::getCharacterData(bool *Invalid) const {
+  assert(isValid());
+  return SrcMgr->getCharacterData(*this, Invalid);
+}
+
+const llvm::MemoryBuffer* FullSourceLoc::getBuffer(bool *Invalid) const {
+  assert(isValid());
+  return SrcMgr->getBuffer(SrcMgr->getFileID(*this), Invalid);
+}
+
+llvm::StringRef FullSourceLoc::getBufferData(bool *Invalid) const {
+  return getBuffer(Invalid)->getBuffer();
+}
+
+std::pair<FileID, unsigned> FullSourceLoc::getDecomposedLoc() const {
+  return SrcMgr->getDecomposedLoc(*this);
+}
diff --git a/lib/Basic/SourceManager.cpp b/lib/Basic/SourceManager.cpp
new file mode 100644
index 0000000..3ecab1d
--- /dev/null
+++ b/lib/Basic/SourceManager.cpp
@@ -0,0 +1,1271 @@
+//===--- SourceManager.cpp - Track and cache source files -----------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements the SourceManager interface.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/SourceManagerInternals.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/FileManager.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/System/Path.h"
+#include <algorithm>
+#include <string>
+#include <cstring>
+
+using namespace clang;
+using namespace SrcMgr;
+using llvm::MemoryBuffer;
+
+//===----------------------------------------------------------------------===//
+// SourceManager Helper Classes
+//===----------------------------------------------------------------------===//
+
+ContentCache::~ContentCache() {
+  delete Buffer.getPointer();
+}
+
+/// getSizeBytesMapped - Returns the number of bytes actually mapped for
+///  this ContentCache.  This can be 0 if the MemBuffer was not actually
+///  instantiated.
+unsigned ContentCache::getSizeBytesMapped() const {
+  return Buffer.getPointer() ? Buffer.getPointer()->getBufferSize() : 0;
+}
+
+/// getSize - Returns the size of the content encapsulated by this ContentCache.
+///  This can be the size of the source file or the size of an arbitrary
+///  scratch buffer.  If the ContentCache encapsulates a source file, that
+///  file is not lazily brought in from disk to satisfy this query.
+unsigned ContentCache::getSize() const {
+  return Buffer.getPointer() ? (unsigned) Buffer.getPointer()->getBufferSize()
+                             : (unsigned) Entry->getSize();
+}
+
+void ContentCache::replaceBuffer(const llvm::MemoryBuffer *B) {
+  assert(B != Buffer.getPointer());
+  
+  delete Buffer.getPointer();
+  Buffer.setPointer(B);
+  Buffer.setInt(false);
+}
+
+const llvm::MemoryBuffer *ContentCache::getBuffer(Diagnostic &Diag,
+                                                  const SourceManager &SM,
+                                                  SourceLocation Loc,
+                                                  bool *Invalid) const {
+  if (Invalid)
+    *Invalid = false;
+      
+  // Lazily create the Buffer for ContentCaches that wrap files.
+  if (!Buffer.getPointer() && Entry) {
+    std::string ErrorStr;
+    struct stat FileInfo;
+    Buffer.setPointer(MemoryBuffer::getFile(Entry->getName(), &ErrorStr,
+                                            Entry->getSize(), &FileInfo));
+    Buffer.setInt(false);
+    
+    // If we were unable to open the file, then we are in an inconsistent
+    // situation where the content cache referenced a file which no longer
+    // exists. Most likely, we were using a stat cache with an invalid entry but
+    // the file could also have been removed during processing. Since we can't
+    // really deal with this situation, just create an empty buffer.
+    //
+    // FIXME: This is definitely not ideal, but our immediate clients can't
+    // currently handle returning a null entry here. Ideally we should detect
+    // that we are in an inconsistent situation and error out as quickly as
+    // possible.
+    if (!Buffer.getPointer()) {
+      const llvm::StringRef FillStr("<<<MISSING SOURCE FILE>>>\n");
+      Buffer.setPointer(MemoryBuffer::getNewMemBuffer(Entry->getSize(), 
+                                                      "<invalid>"));
+      char *Ptr = const_cast<char*>(Buffer.getPointer()->getBufferStart());
+      for (unsigned i = 0, e = Entry->getSize(); i != e; ++i)
+        Ptr[i] = FillStr[i % FillStr.size()];
+
+      if (Diag.isDiagnosticInFlight())
+        Diag.SetDelayedDiagnostic(diag::err_cannot_open_file, 
+                                  Entry->getName(), ErrorStr);
+      else 
+        Diag.Report(FullSourceLoc(Loc, SM), diag::err_cannot_open_file)
+          << Entry->getName() << ErrorStr;
+
+      Buffer.setInt(true);
+
+    // FIXME: This conditionalization is horrible, but we see spurious failures
+    // in the test suite due to this warning and no one has had time to hunt it
+    // down. So for now, we just don't emit this diagnostic on Win32, and hope
+    // nothing bad happens.
+    //
+    // PR6812.
+#if !defined(LLVM_ON_WIN32)
+    } else if (FileInfo.st_size != Entry->getSize() ||
+               FileInfo.st_mtime != Entry->getModificationTime()) {
+      // Check that the file's size and modification time are the same
+      // as in the file entry (which may have come from a stat cache).
+      if (Diag.isDiagnosticInFlight())
+        Diag.SetDelayedDiagnostic(diag::err_file_modified,
+                                  Entry->getName());
+      else
+        Diag.Report(FullSourceLoc(Loc, SM), diag::err_file_modified)
+          << Entry->getName();
+
+      Buffer.setInt(true);
+#endif
+    }
+    
+    // If the buffer is valid, check to see if it has a UTF Byte Order Mark
+    // (BOM).  We only support UTF-8 without a BOM right now.  See
+    // http://en.wikipedia.org/wiki/Byte_order_mark for more information.
+    if (!Buffer.getInt()) {
+      llvm::StringRef BufStr = Buffer.getPointer()->getBuffer();
+      const char *BOM = 0;
+      if (BufStr.startswith("\xFE\xBB\xBF"))
+        BOM = "UTF-8";
+      else if (BufStr.startswith("\xFE\xFF"))
+        BOM = "UTF-16 (BE)";
+      else if (BufStr.startswith("\xFF\xFE"))
+        BOM = "UTF-16 (LE)";
+      else if (BufStr.startswith(llvm::StringRef("\x00\x00\xFE\xFF", 4)))
+        BOM = "UTF-32 (BE)";
+      else if (BufStr.startswith(llvm::StringRef("\xFF\xFE\x00\x00", 4)))
+        BOM = "UTF-32 (LE)";
+      else if (BufStr.startswith("\x2B\x2F\x76"))
+        BOM = "UTF-7";
+      else if (BufStr.startswith("\xF7\x64\x4C"))
+        BOM = "UTF-1";
+      else if (BufStr.startswith("\xDD\x73\x66\x73"))
+        BOM = "UTF-EBCDIC";
+      else if (BufStr.startswith("\x0E\xFE\xFF"))
+        BOM = "SDSU";
+      else if (BufStr.startswith("\xFB\xEE\x28"))
+        BOM = "BOCU-1";
+      else if (BufStr.startswith("\x84\x31\x95\x33"))
+        BOM = "BOCU-1";
+      
+      if (BOM) {
+        Diag.Report(FullSourceLoc(Loc, SM), diag::err_unsupported_bom)
+          << BOM << Entry->getName();
+        Buffer.setInt(1);
+      }
+    }
+  }
+  
+  if (Invalid)
+    *Invalid = Buffer.getInt();
+  
+  return Buffer.getPointer();
+}
+
+unsigned LineTableInfo::getLineTableFilenameID(const char *Ptr, unsigned Len) {
+  // Look up the filename in the string table, returning the pre-existing value
+  // if it exists.
+  llvm::StringMapEntry<unsigned> &Entry =
+    FilenameIDs.GetOrCreateValue(Ptr, Ptr+Len, ~0U);
+  if (Entry.getValue() != ~0U)
+    return Entry.getValue();
+
+  // Otherwise, assign this the next available ID.
+  Entry.setValue(FilenamesByID.size());
+  FilenamesByID.push_back(&Entry);
+  return FilenamesByID.size()-1;
+}
+
+/// AddLineNote - Add a line note to the line table that indicates that there
+/// is a #line at the specified FID/Offset location which changes the presumed
+/// location to LineNo/FilenameID.
+void LineTableInfo::AddLineNote(unsigned FID, unsigned Offset,
+                                unsigned LineNo, int FilenameID) {
+  std::vector<LineEntry> &Entries = LineEntries[FID];
+
+  assert((Entries.empty() || Entries.back().FileOffset < Offset) &&
+         "Adding line entries out of order!");
+
+  SrcMgr::CharacteristicKind Kind = SrcMgr::C_User;
+  unsigned IncludeOffset = 0;
+
+  if (!Entries.empty()) {
+    // If this is a '#line 4' after '#line 42 "foo.h"', make sure to remember
+    // that we are still in "foo.h".
+    if (FilenameID == -1)
+      FilenameID = Entries.back().FilenameID;
+
+    // If we are after a line marker that switched us to system header mode, or
+    // that set #include information, preserve it.
+    Kind = Entries.back().FileKind;
+    IncludeOffset = Entries.back().IncludeOffset;
+  }
+
+  Entries.push_back(LineEntry::get(Offset, LineNo, FilenameID, Kind,
+                                   IncludeOffset));
+}
+
+/// AddLineNote This is the same as the previous version of AddLineNote, but is
+/// used for GNU line markers.  If EntryExit is 0, then this doesn't change the
+/// presumed #include stack.  If it is 1, this is a file entry, if it is 2 then
+/// this is a file exit.  FileKind specifies whether this is a system header or
+/// extern C system header.
+void LineTableInfo::AddLineNote(unsigned FID, unsigned Offset,
+                                unsigned LineNo, int FilenameID,
+                                unsigned EntryExit,
+                                SrcMgr::CharacteristicKind FileKind) {
+  assert(FilenameID != -1 && "Unspecified filename should use other accessor");
+
+  std::vector<LineEntry> &Entries = LineEntries[FID];
+
+  assert((Entries.empty() || Entries.back().FileOffset < Offset) &&
+         "Adding line entries out of order!");
+
+  unsigned IncludeOffset = 0;
+  if (EntryExit == 0) {  // No #include stack change.
+    IncludeOffset = Entries.empty() ? 0 : Entries.back().IncludeOffset;
+  } else if (EntryExit == 1) {
+    IncludeOffset = Offset-1;
+  } else if (EntryExit == 2) {
+    assert(!Entries.empty() && Entries.back().IncludeOffset &&
+       "PPDirectives should have caught case when popping empty include stack");
+
+    // Get the include loc of the last entries' include loc as our include loc.
+    IncludeOffset = 0;
+    if (const LineEntry *PrevEntry =
+          FindNearestLineEntry(FID, Entries.back().IncludeOffset))
+      IncludeOffset = PrevEntry->IncludeOffset;
+  }
+
+  Entries.push_back(LineEntry::get(Offset, LineNo, FilenameID, FileKind,
+                                   IncludeOffset));
+}
+
+
+/// FindNearestLineEntry - Find the line entry nearest to FID that is before
+/// it.  If there is no line entry before Offset in FID, return null.
+const LineEntry *LineTableInfo::FindNearestLineEntry(unsigned FID,
+                                                     unsigned Offset) {
+  const std::vector<LineEntry> &Entries = LineEntries[FID];
+  assert(!Entries.empty() && "No #line entries for this FID after all!");
+
+  // It is very common for the query to be after the last #line, check this
+  // first.
+  if (Entries.back().FileOffset <= Offset)
+    return &Entries.back();
+
+  // Do a binary search to find the maximal element that is still before Offset.
+  std::vector<LineEntry>::const_iterator I =
+    std::upper_bound(Entries.begin(), Entries.end(), Offset);
+  if (I == Entries.begin()) return 0;
+  return &*--I;
+}
+
+/// \brief Add a new line entry that has already been encoded into
+/// the internal representation of the line table.
+void LineTableInfo::AddEntry(unsigned FID,
+                             const std::vector<LineEntry> &Entries) {
+  LineEntries[FID] = Entries;
+}
+
+/// getLineTableFilenameID - Return the uniqued ID for the specified filename.
+///
+unsigned SourceManager::getLineTableFilenameID(const char *Ptr, unsigned Len) {
+  if (LineTable == 0)
+    LineTable = new LineTableInfo();
+  return LineTable->getLineTableFilenameID(Ptr, Len);
+}
+
+
+/// AddLineNote - Add a line note to the line table for the FileID and offset
+/// specified by Loc.  If FilenameID is -1, it is considered to be
+/// unspecified.
+void SourceManager::AddLineNote(SourceLocation Loc, unsigned LineNo,
+                                int FilenameID) {
+  std::pair<FileID, unsigned> LocInfo = getDecomposedInstantiationLoc(Loc);
+
+  const SrcMgr::FileInfo &FileInfo = getSLocEntry(LocInfo.first).getFile();
+
+  // Remember that this file has #line directives now if it doesn't already.
+  const_cast<SrcMgr::FileInfo&>(FileInfo).setHasLineDirectives();
+
+  if (LineTable == 0)
+    LineTable = new LineTableInfo();
+  LineTable->AddLineNote(LocInfo.first.ID, LocInfo.second, LineNo, FilenameID);
+}
+
+/// AddLineNote - Add a GNU line marker to the line table.
+void SourceManager::AddLineNote(SourceLocation Loc, unsigned LineNo,
+                                int FilenameID, bool IsFileEntry,
+                                bool IsFileExit, bool IsSystemHeader,
+                                bool IsExternCHeader) {
+  // If there is no filename and no flags, this is treated just like a #line,
+  // which does not change the flags of the previous line marker.
+  if (FilenameID == -1) {
+    assert(!IsFileEntry && !IsFileExit && !IsSystemHeader && !IsExternCHeader &&
+           "Can't set flags without setting the filename!");
+    return AddLineNote(Loc, LineNo, FilenameID);
+  }
+
+  std::pair<FileID, unsigned> LocInfo = getDecomposedInstantiationLoc(Loc);
+  const SrcMgr::FileInfo &FileInfo = getSLocEntry(LocInfo.first).getFile();
+
+  // Remember that this file has #line directives now if it doesn't already.
+  const_cast<SrcMgr::FileInfo&>(FileInfo).setHasLineDirectives();
+
+  if (LineTable == 0)
+    LineTable = new LineTableInfo();
+
+  SrcMgr::CharacteristicKind FileKind;
+  if (IsExternCHeader)
+    FileKind = SrcMgr::C_ExternCSystem;
+  else if (IsSystemHeader)
+    FileKind = SrcMgr::C_System;
+  else
+    FileKind = SrcMgr::C_User;
+
+  unsigned EntryExit = 0;
+  if (IsFileEntry)
+    EntryExit = 1;
+  else if (IsFileExit)
+    EntryExit = 2;
+
+  LineTable->AddLineNote(LocInfo.first.ID, LocInfo.second, LineNo, FilenameID,
+                         EntryExit, FileKind);
+}
+
+LineTableInfo &SourceManager::getLineTable() {
+  if (LineTable == 0)
+    LineTable = new LineTableInfo();
+  return *LineTable;
+}
+
+//===----------------------------------------------------------------------===//
+// Private 'Create' methods.
+//===----------------------------------------------------------------------===//
+
+SourceManager::~SourceManager() {
+  delete LineTable;
+
+  // Delete FileEntry objects corresponding to content caches.  Since the actual
+  // content cache objects are bump pointer allocated, we just have to run the
+  // dtors, but we call the deallocate method for completeness.
+  for (unsigned i = 0, e = MemBufferInfos.size(); i != e; ++i) {
+    MemBufferInfos[i]->~ContentCache();
+    ContentCacheAlloc.Deallocate(MemBufferInfos[i]);
+  }
+  for (llvm::DenseMap<const FileEntry*, SrcMgr::ContentCache*>::iterator
+       I = FileInfos.begin(), E = FileInfos.end(); I != E; ++I) {
+    I->second->~ContentCache();
+    ContentCacheAlloc.Deallocate(I->second);
+  }
+}
+
+void SourceManager::clearIDTables() {
+  MainFileID = FileID();
+  SLocEntryTable.clear();
+  LastLineNoFileIDQuery = FileID();
+  LastLineNoContentCache = 0;
+  LastFileIDLookup = FileID();
+
+  if (LineTable)
+    LineTable->clear();
+
+  // Use up FileID #0 as an invalid instantiation.
+  NextOffset = 0;
+  createInstantiationLoc(SourceLocation(),SourceLocation(),SourceLocation(), 1);
+}
+
+/// getOrCreateContentCache - Create or return a cached ContentCache for the
+/// specified file.
+const ContentCache *
+SourceManager::getOrCreateContentCache(const FileEntry *FileEnt) {
+  assert(FileEnt && "Didn't specify a file entry to use?");
+
+  // Do we already have information about this file?
+  ContentCache *&Entry = FileInfos[FileEnt];
+  if (Entry) return Entry;
+
+  // Nope, create a new Cache entry.  Make sure it is at least 8-byte aligned
+  // so that FileInfo can use the low 3 bits of the pointer for its own
+  // nefarious purposes.
+  unsigned EntryAlign = llvm::AlignOf<ContentCache>::Alignment;
+  EntryAlign = std::max(8U, EntryAlign);
+  Entry = ContentCacheAlloc.Allocate<ContentCache>(1, EntryAlign);
+  new (Entry) ContentCache(FileEnt);
+  return Entry;
+}
+
+
+/// createMemBufferContentCache - Create a new ContentCache for the specified
+///  memory buffer.  This does no caching.
+const ContentCache*
+SourceManager::createMemBufferContentCache(const MemoryBuffer *Buffer) {
+  // Add a new ContentCache to the MemBufferInfos list and return it.  Make sure
+  // it is at least 8-byte aligned so that FileInfo can use the low 3 bits of
+  // the pointer for its own nefarious purposes.
+  unsigned EntryAlign = llvm::AlignOf<ContentCache>::Alignment;
+  EntryAlign = std::max(8U, EntryAlign);
+  ContentCache *Entry = ContentCacheAlloc.Allocate<ContentCache>(1, EntryAlign);
+  new (Entry) ContentCache();
+  MemBufferInfos.push_back(Entry);
+  Entry->setBuffer(Buffer);
+  return Entry;
+}
+
+void SourceManager::PreallocateSLocEntries(ExternalSLocEntrySource *Source,
+                                           unsigned NumSLocEntries,
+                                           unsigned NextOffset) {
+  ExternalSLocEntries = Source;
+  this->NextOffset = NextOffset;
+  SLocEntryLoaded.resize(NumSLocEntries + 1);
+  SLocEntryLoaded[0] = true;
+  SLocEntryTable.resize(SLocEntryTable.size() + NumSLocEntries);
+}
+
+void SourceManager::ClearPreallocatedSLocEntries() {
+  unsigned I = 0;
+  for (unsigned N = SLocEntryLoaded.size(); I != N; ++I)
+    if (!SLocEntryLoaded[I])
+      break;
+
+  // We've already loaded all preallocated source location entries.
+  if (I == SLocEntryLoaded.size())
+    return;
+
+  // Remove everything from location I onward.
+  SLocEntryTable.resize(I);
+  SLocEntryLoaded.clear();
+  ExternalSLocEntries = 0;
+}
+
+
+//===----------------------------------------------------------------------===//
+// Methods to create new FileID's and instantiations.
+//===----------------------------------------------------------------------===//
+
+/// createFileID - Create a new fileID for the specified ContentCache and
+/// include position.  This works regardless of whether the ContentCache
+/// corresponds to a file or some other input source.
+FileID SourceManager::createFileID(const ContentCache *File,
+                                   SourceLocation IncludePos,
+                                   SrcMgr::CharacteristicKind FileCharacter,
+                                   unsigned PreallocatedID,
+                                   unsigned Offset) {
+  if (PreallocatedID) {
+    // If we're filling in a preallocated ID, just load in the file
+    // entry and return.
+    assert(PreallocatedID < SLocEntryLoaded.size() &&
+           "Preallocate ID out-of-range");
+    assert(!SLocEntryLoaded[PreallocatedID] &&
+           "Source location entry already loaded");
+    assert(Offset && "Preallocate source location cannot have zero offset");
+    SLocEntryTable[PreallocatedID]
+      = SLocEntry::get(Offset, FileInfo::get(IncludePos, File, FileCharacter));
+    SLocEntryLoaded[PreallocatedID] = true;
+    FileID FID = FileID::get(PreallocatedID);
+    return FID;
+  }
+
+  SLocEntryTable.push_back(SLocEntry::get(NextOffset,
+                                          FileInfo::get(IncludePos, File,
+                                                        FileCharacter)));
+  unsigned FileSize = File->getSize();
+  assert(NextOffset+FileSize+1 > NextOffset && "Ran out of source locations!");
+  NextOffset += FileSize+1;
+
+  // Set LastFileIDLookup to the newly created file.  The next getFileID call is
+  // almost guaranteed to be from that file.
+  FileID FID = FileID::get(SLocEntryTable.size()-1);
+  return LastFileIDLookup = FID;
+}
+
+/// createInstantiationLoc - Return a new SourceLocation that encodes the fact
+/// that a token from SpellingLoc should actually be referenced from
+/// InstantiationLoc.
+SourceLocation SourceManager::createInstantiationLoc(SourceLocation SpellingLoc,
+                                                     SourceLocation ILocStart,
+                                                     SourceLocation ILocEnd,
+                                                     unsigned TokLength,
+                                                     unsigned PreallocatedID,
+                                                     unsigned Offset) {
+  InstantiationInfo II = InstantiationInfo::get(ILocStart,ILocEnd, SpellingLoc);
+  if (PreallocatedID) {
+    // If we're filling in a preallocated ID, just load in the
+    // instantiation entry and return.
+    assert(PreallocatedID < SLocEntryLoaded.size() &&
+           "Preallocate ID out-of-range");
+    assert(!SLocEntryLoaded[PreallocatedID] &&
+           "Source location entry already loaded");
+    assert(Offset && "Preallocate source location cannot have zero offset");
+    SLocEntryTable[PreallocatedID] = SLocEntry::get(Offset, II);
+    SLocEntryLoaded[PreallocatedID] = true;
+    return SourceLocation::getMacroLoc(Offset);
+  }
+  SLocEntryTable.push_back(SLocEntry::get(NextOffset, II));
+  assert(NextOffset+TokLength+1 > NextOffset && "Ran out of source locations!");
+  NextOffset += TokLength+1;
+  return SourceLocation::getMacroLoc(NextOffset-(TokLength+1));
+}
+
+const llvm::MemoryBuffer *
+SourceManager::getMemoryBufferForFile(const FileEntry *File,
+                                      bool *Invalid) {
+  const SrcMgr::ContentCache *IR = getOrCreateContentCache(File);
+  assert(IR && "getOrCreateContentCache() cannot return NULL");
+  return IR->getBuffer(Diag, *this, SourceLocation(), Invalid);
+}
+
+bool SourceManager::overrideFileContents(const FileEntry *SourceFile,
+                                         const llvm::MemoryBuffer *Buffer) {
+  const SrcMgr::ContentCache *IR = getOrCreateContentCache(SourceFile);
+  if (IR == 0)
+    return true;
+
+  const_cast<SrcMgr::ContentCache *>(IR)->replaceBuffer(Buffer);
+  return false;
+}
+
+llvm::StringRef SourceManager::getBufferData(FileID FID, bool *Invalid) const {
+  bool MyInvalid = false;
+  const llvm::MemoryBuffer *Buf = getBuffer(FID, &MyInvalid);
+  if (Invalid)
+    *Invalid = MyInvalid;
+
+  if (MyInvalid)
+    return "";
+  
+  return Buf->getBuffer();
+}
+
+//===----------------------------------------------------------------------===//
+// SourceLocation manipulation methods.
+//===----------------------------------------------------------------------===//
+
+/// getFileIDSlow - Return the FileID for a SourceLocation.  This is a very hot
+/// method that is used for all SourceManager queries that start with a
+/// SourceLocation object.  It is responsible for finding the entry in
+/// SLocEntryTable which contains the specified location.
+///
+FileID SourceManager::getFileIDSlow(unsigned SLocOffset) const {
+  assert(SLocOffset && "Invalid FileID");
+
+  // After the first and second level caches, I see two common sorts of
+  // behavior: 1) a lot of searched FileID's are "near" the cached file location
+  // or are "near" the cached instantiation location.  2) others are just
+  // completely random and may be a very long way away.
+  //
+  // To handle this, we do a linear search for up to 8 steps to catch #1 quickly
+  // then we fall back to a less cache efficient, but more scalable, binary
+  // search to find the location.
+
+  // See if this is near the file point - worst case we start scanning from the
+  // most newly created FileID.
+  std::vector<SrcMgr::SLocEntry>::const_iterator I;
+
+  if (SLocEntryTable[LastFileIDLookup.ID].getOffset() < SLocOffset) {
+    // Neither loc prunes our search.
+    I = SLocEntryTable.end();
+  } else {
+    // Perhaps it is near the file point.
+    I = SLocEntryTable.begin()+LastFileIDLookup.ID;
+  }
+
+  // Find the FileID that contains this.  "I" is an iterator that points to a
+  // FileID whose offset is known to be larger than SLocOffset.
+  unsigned NumProbes = 0;
+  while (1) {
+    --I;
+    if (ExternalSLocEntries)
+      getSLocEntry(FileID::get(I - SLocEntryTable.begin()));
+    if (I->getOffset() <= SLocOffset) {
+#if 0
+      printf("lin %d -> %d [%s] %d %d\n", SLocOffset,
+             I-SLocEntryTable.begin(),
+             I->isInstantiation() ? "inst" : "file",
+             LastFileIDLookup.ID,  int(SLocEntryTable.end()-I));
+#endif
+      FileID Res = FileID::get(I-SLocEntryTable.begin());
+
+      // If this isn't an instantiation, remember it.  We have good locality
+      // across FileID lookups.
+      if (!I->isInstantiation())
+        LastFileIDLookup = Res;
+      NumLinearScans += NumProbes+1;
+      return Res;
+    }
+    if (++NumProbes == 8)
+      break;
+  }
+
+  // Convert "I" back into an index.  We know that it is an entry whose index is
+  // larger than the offset we are looking for.
+  unsigned GreaterIndex = I-SLocEntryTable.begin();
+  // LessIndex - This is the lower bound of the range that we're searching.
+  // We know that the offset corresponding to the FileID is is less than
+  // SLocOffset.
+  unsigned LessIndex = 0;
+  NumProbes = 0;
+  while (1) {
+    unsigned MiddleIndex = (GreaterIndex-LessIndex)/2+LessIndex;
+    unsigned MidOffset = getSLocEntry(FileID::get(MiddleIndex)).getOffset();
+
+    ++NumProbes;
+
+    // If the offset of the midpoint is too large, chop the high side of the
+    // range to the midpoint.
+    if (MidOffset > SLocOffset) {
+      GreaterIndex = MiddleIndex;
+      continue;
+    }
+
+    // If the middle index contains the value, succeed and return.
+    if (isOffsetInFileID(FileID::get(MiddleIndex), SLocOffset)) {
+#if 0
+      printf("bin %d -> %d [%s] %d %d\n", SLocOffset,
+             I-SLocEntryTable.begin(),
+             I->isInstantiation() ? "inst" : "file",
+             LastFileIDLookup.ID, int(SLocEntryTable.end()-I));
+#endif
+      FileID Res = FileID::get(MiddleIndex);
+
+      // If this isn't an instantiation, remember it.  We have good locality
+      // across FileID lookups.
+      if (!I->isInstantiation())
+        LastFileIDLookup = Res;
+      NumBinaryProbes += NumProbes;
+      return Res;
+    }
+
+    // Otherwise, move the low-side up to the middle index.
+    LessIndex = MiddleIndex;
+  }
+}
+
+SourceLocation SourceManager::
+getInstantiationLocSlowCase(SourceLocation Loc) const {
+  do {
+    // Note: If Loc indicates an offset into a token that came from a macro
+    // expansion (e.g. the 5th character of the token) we do not want to add
+    // this offset when going to the instantiation location.  The instatiation
+    // location is the macro invocation, which the offset has nothing to do
+    // with.  This is unlike when we get the spelling loc, because the offset
+    // directly correspond to the token whose spelling we're inspecting.
+    Loc = getSLocEntry(getFileID(Loc)).getInstantiation()
+                   .getInstantiationLocStart();
+  } while (!Loc.isFileID());
+
+  return Loc;
+}
+
+SourceLocation SourceManager::getSpellingLocSlowCase(SourceLocation Loc) const {
+  do {
+    std::pair<FileID, unsigned> LocInfo = getDecomposedLoc(Loc);
+    Loc = getSLocEntry(LocInfo.first).getInstantiation().getSpellingLoc();
+    Loc = Loc.getFileLocWithOffset(LocInfo.second);
+  } while (!Loc.isFileID());
+  return Loc;
+}
+
+
+std::pair<FileID, unsigned>
+SourceManager::getDecomposedInstantiationLocSlowCase(const SrcMgr::SLocEntry *E,
+                                                     unsigned Offset) const {
+  // If this is an instantiation record, walk through all the instantiation
+  // points.
+  FileID FID;
+  SourceLocation Loc;
+  do {
+    Loc = E->getInstantiation().getInstantiationLocStart();
+
+    FID = getFileID(Loc);
+    E = &getSLocEntry(FID);
+    Offset += Loc.getOffset()-E->getOffset();
+  } while (!Loc.isFileID());
+
+  return std::make_pair(FID, Offset);
+}
+
+std::pair<FileID, unsigned>
+SourceManager::getDecomposedSpellingLocSlowCase(const SrcMgr::SLocEntry *E,
+                                                unsigned Offset) const {
+  // If this is an instantiation record, walk through all the instantiation
+  // points.
+  FileID FID;
+  SourceLocation Loc;
+  do {
+    Loc = E->getInstantiation().getSpellingLoc();
+
+    FID = getFileID(Loc);
+    E = &getSLocEntry(FID);
+    Offset += Loc.getOffset()-E->getOffset();
+  } while (!Loc.isFileID());
+
+  return std::make_pair(FID, Offset);
+}
+
+/// getImmediateSpellingLoc - Given a SourceLocation object, return the
+/// spelling location referenced by the ID.  This is the first level down
+/// towards the place where the characters that make up the lexed token can be
+/// found.  This should not generally be used by clients.
+SourceLocation SourceManager::getImmediateSpellingLoc(SourceLocation Loc) const{
+  if (Loc.isFileID()) return Loc;
+  std::pair<FileID, unsigned> LocInfo = getDecomposedLoc(Loc);
+  Loc = getSLocEntry(LocInfo.first).getInstantiation().getSpellingLoc();
+  return Loc.getFileLocWithOffset(LocInfo.second);
+}
+
+
+/// getImmediateInstantiationRange - Loc is required to be an instantiation
+/// location.  Return the start/end of the instantiation information.
+std::pair<SourceLocation,SourceLocation>
+SourceManager::getImmediateInstantiationRange(SourceLocation Loc) const {
+  assert(Loc.isMacroID() && "Not an instantiation loc!");
+  const InstantiationInfo &II = getSLocEntry(getFileID(Loc)).getInstantiation();
+  return II.getInstantiationLocRange();
+}
+
+/// getInstantiationRange - Given a SourceLocation object, return the
+/// range of tokens covered by the instantiation in the ultimate file.
+std::pair<SourceLocation,SourceLocation>
+SourceManager::getInstantiationRange(SourceLocation Loc) const {
+  if (Loc.isFileID()) return std::make_pair(Loc, Loc);
+
+  std::pair<SourceLocation,SourceLocation> Res =
+    getImmediateInstantiationRange(Loc);
+
+  // Fully resolve the start and end locations to their ultimate instantiation
+  // points.
+  while (!Res.first.isFileID())
+    Res.first = getImmediateInstantiationRange(Res.first).first;
+  while (!Res.second.isFileID())
+    Res.second = getImmediateInstantiationRange(Res.second).second;
+  return Res;
+}
+
+
+
+//===----------------------------------------------------------------------===//
+// Queries about the code at a SourceLocation.
+//===----------------------------------------------------------------------===//
+
+/// getCharacterData - Return a pointer to the start of the specified location
+/// in the appropriate MemoryBuffer.
+const char *SourceManager::getCharacterData(SourceLocation SL,
+                                            bool *Invalid) const {
+  // Note that this is a hot function in the getSpelling() path, which is
+  // heavily used by -E mode.
+  std::pair<FileID, unsigned> LocInfo = getDecomposedSpellingLoc(SL);
+
+  // Note that calling 'getBuffer()' may lazily page in a source file.
+  bool CharDataInvalid = false;
+  const llvm::MemoryBuffer *Buffer
+    = getSLocEntry(LocInfo.first).getFile().getContentCache()
+    ->getBuffer(Diag, *this, SourceLocation(), &CharDataInvalid);
+  if (Invalid)
+    *Invalid = CharDataInvalid;
+  return Buffer->getBufferStart() + (CharDataInvalid? 0 : LocInfo.second);
+}
+
+
+/// getColumnNumber - Return the column # for the specified file position.
+/// this is significantly cheaper to compute than the line number.
+unsigned SourceManager::getColumnNumber(FileID FID, unsigned FilePos,
+                                        bool *Invalid) const {
+  bool MyInvalid = false;
+  const char *Buf = getBuffer(FID, &MyInvalid)->getBufferStart();
+  if (Invalid)
+    *Invalid = MyInvalid;
+
+  if (MyInvalid)
+    return 1;
+
+  unsigned LineStart = FilePos;
+  while (LineStart && Buf[LineStart-1] != '\n' && Buf[LineStart-1] != '\r')
+    --LineStart;
+  return FilePos-LineStart+1;
+}
+
+unsigned SourceManager::getSpellingColumnNumber(SourceLocation Loc,
+                                                bool *Invalid) const {
+  if (Loc.isInvalid()) return 0;
+  std::pair<FileID, unsigned> LocInfo = getDecomposedSpellingLoc(Loc);
+  return getColumnNumber(LocInfo.first, LocInfo.second, Invalid);
+}
+
+unsigned SourceManager::getInstantiationColumnNumber(SourceLocation Loc,
+                                                     bool *Invalid) const {
+  if (Loc.isInvalid()) return 0;
+  std::pair<FileID, unsigned> LocInfo = getDecomposedInstantiationLoc(Loc);
+  return getColumnNumber(LocInfo.first, LocInfo.second, Invalid);
+}
+
+static DISABLE_INLINE void
+ComputeLineNumbers(Diagnostic &Diag, ContentCache *FI,
+                   llvm::BumpPtrAllocator &Alloc,
+                   const SourceManager &SM, bool &Invalid);
+static void ComputeLineNumbers(Diagnostic &Diag, ContentCache *FI, 
+                               llvm::BumpPtrAllocator &Alloc,
+                               const SourceManager &SM, bool &Invalid) {
+  // Note that calling 'getBuffer()' may lazily page in the file.
+  const MemoryBuffer *Buffer = FI->getBuffer(Diag, SM, SourceLocation(),
+                                             &Invalid);
+  if (Invalid)
+    return;
+
+  // Find the file offsets of all of the *physical* source lines.  This does
+  // not look at trigraphs, escaped newlines, or anything else tricky.
+  std::vector<unsigned> LineOffsets;
+
+  // Line #1 starts at char 0.
+  LineOffsets.push_back(0);
+
+  const unsigned char *Buf = (const unsigned char *)Buffer->getBufferStart();
+  const unsigned char *End = (const unsigned char *)Buffer->getBufferEnd();
+  unsigned Offs = 0;
+  while (1) {
+    // Skip over the contents of the line.
+    // TODO: Vectorize this?  This is very performance sensitive for programs
+    // with lots of diagnostics and in -E mode.
+    const unsigned char *NextBuf = (const unsigned char *)Buf;
+    while (*NextBuf != '\n' && *NextBuf != '\r' && *NextBuf != '\0')
+      ++NextBuf;
+    Offs += NextBuf-Buf;
+    Buf = NextBuf;
+
+    if (Buf[0] == '\n' || Buf[0] == '\r') {
+      // If this is \n\r or \r\n, skip both characters.
+      if ((Buf[1] == '\n' || Buf[1] == '\r') && Buf[0] != Buf[1])
+        ++Offs, ++Buf;
+      ++Offs, ++Buf;
+      LineOffsets.push_back(Offs);
+    } else {
+      // Otherwise, this is a null.  If end of file, exit.
+      if (Buf == End) break;
+      // Otherwise, skip the null.
+      ++Offs, ++Buf;
+    }
+  }
+
+  // Copy the offsets into the FileInfo structure.
+  FI->NumLines = LineOffsets.size();
+  FI->SourceLineCache = Alloc.Allocate<unsigned>(LineOffsets.size());
+  std::copy(LineOffsets.begin(), LineOffsets.end(), FI->SourceLineCache);
+}
+
+/// getLineNumber - Given a SourceLocation, return the spelling line number
+/// for the position indicated.  This requires building and caching a table of
+/// line offsets for the MemoryBuffer, so this is not cheap: use only when
+/// about to emit a diagnostic.
+unsigned SourceManager::getLineNumber(FileID FID, unsigned FilePos, 
+                                      bool *Invalid) const {
+  ContentCache *Content;
+  if (LastLineNoFileIDQuery == FID)
+    Content = LastLineNoContentCache;
+  else
+    Content = const_cast<ContentCache*>(getSLocEntry(FID)
+                                        .getFile().getContentCache());
+
+  // If this is the first use of line information for this buffer, compute the
+  /// SourceLineCache for it on demand.
+  if (Content->SourceLineCache == 0) {
+    bool MyInvalid = false;
+    ComputeLineNumbers(Diag, Content, ContentCacheAlloc, *this, MyInvalid);
+    if (Invalid)
+      *Invalid = MyInvalid;
+    if (MyInvalid)
+      return 1;
+  } else if (Invalid)
+    *Invalid = false;
+
+  // Okay, we know we have a line number table.  Do a binary search to find the
+  // line number that this character position lands on.
+  unsigned *SourceLineCache = Content->SourceLineCache;
+  unsigned *SourceLineCacheStart = SourceLineCache;
+  unsigned *SourceLineCacheEnd = SourceLineCache + Content->NumLines;
+
+  unsigned QueriedFilePos = FilePos+1;
+
+  // FIXME: I would like to be convinced that this code is worth being as
+  // complicated as it is, binary search isn't that slow.
+  //
+  // If it is worth being optimized, then in my opinion it could be more
+  // performant, simpler, and more obviously correct by just "galloping" outward
+  // from the queried file position. In fact, this could be incorporated into a
+  // generic algorithm such as lower_bound_with_hint.
+  //
+  // If someone gives me a test case where this matters, and I will do it! - DWD
+
+  // If the previous query was to the same file, we know both the file pos from
+  // that query and the line number returned.  This allows us to narrow the
+  // search space from the entire file to something near the match.
+  if (LastLineNoFileIDQuery == FID) {
+    if (QueriedFilePos >= LastLineNoFilePos) {
+      // FIXME: Potential overflow?
+      SourceLineCache = SourceLineCache+LastLineNoResult-1;
+
+      // The query is likely to be nearby the previous one.  Here we check to
+      // see if it is within 5, 10 or 20 lines.  It can be far away in cases
+      // where big comment blocks and vertical whitespace eat up lines but
+      // contribute no tokens.
+      if (SourceLineCache+5 < SourceLineCacheEnd) {
+        if (SourceLineCache[5] > QueriedFilePos)
+          SourceLineCacheEnd = SourceLineCache+5;
+        else if (SourceLineCache+10 < SourceLineCacheEnd) {
+          if (SourceLineCache[10] > QueriedFilePos)
+            SourceLineCacheEnd = SourceLineCache+10;
+          else if (SourceLineCache+20 < SourceLineCacheEnd) {
+            if (SourceLineCache[20] > QueriedFilePos)
+              SourceLineCacheEnd = SourceLineCache+20;
+          }
+        }
+      }
+    } else {
+      if (LastLineNoResult < Content->NumLines)
+        SourceLineCacheEnd = SourceLineCache+LastLineNoResult+1;
+    }
+  }
+
+  // If the spread is large, do a "radix" test as our initial guess, based on
+  // the assumption that lines average to approximately the same length.
+  // NOTE: This is currently disabled, as it does not appear to be profitable in
+  // initial measurements.
+  if (0 && SourceLineCacheEnd-SourceLineCache > 20) {
+    unsigned FileLen = Content->SourceLineCache[Content->NumLines-1];
+
+    // Take a stab at guessing where it is.
+    unsigned ApproxPos = Content->NumLines*QueriedFilePos / FileLen;
+
+    // Check for -10 and +10 lines.
+    unsigned LowerBound = std::max(int(ApproxPos-10), 0);
+    unsigned UpperBound = std::min(ApproxPos+10, FileLen);
+
+    // If the computed lower bound is less than the query location, move it in.
+    if (SourceLineCache < SourceLineCacheStart+LowerBound &&
+        SourceLineCacheStart[LowerBound] < QueriedFilePos)
+      SourceLineCache = SourceLineCacheStart+LowerBound;
+
+    // If the computed upper bound is greater than the query location, move it.
+    if (SourceLineCacheEnd > SourceLineCacheStart+UpperBound &&
+        SourceLineCacheStart[UpperBound] >= QueriedFilePos)
+      SourceLineCacheEnd = SourceLineCacheStart+UpperBound;
+  }
+
+  unsigned *Pos
+    = std::lower_bound(SourceLineCache, SourceLineCacheEnd, QueriedFilePos);
+  unsigned LineNo = Pos-SourceLineCacheStart;
+
+  LastLineNoFileIDQuery = FID;
+  LastLineNoContentCache = Content;
+  LastLineNoFilePos = QueriedFilePos;
+  LastLineNoResult = LineNo;
+  return LineNo;
+}
+
+unsigned SourceManager::getInstantiationLineNumber(SourceLocation Loc, 
+                                                   bool *Invalid) const {
+  if (Loc.isInvalid()) return 0;
+  std::pair<FileID, unsigned> LocInfo = getDecomposedInstantiationLoc(Loc);
+  return getLineNumber(LocInfo.first, LocInfo.second);
+}
+unsigned SourceManager::getSpellingLineNumber(SourceLocation Loc, 
+                                              bool *Invalid) const {
+  if (Loc.isInvalid()) return 0;
+  std::pair<FileID, unsigned> LocInfo = getDecomposedSpellingLoc(Loc);
+  return getLineNumber(LocInfo.first, LocInfo.second);
+}
+
+/// getFileCharacteristic - return the file characteristic of the specified
+/// source location, indicating whether this is a normal file, a system
+/// header, or an "implicit extern C" system header.
+///
+/// This state can be modified with flags on GNU linemarker directives like:
+///   # 4 "foo.h" 3
+/// which changes all source locations in the current file after that to be
+/// considered to be from a system header.
+SrcMgr::CharacteristicKind
+SourceManager::getFileCharacteristic(SourceLocation Loc) const {
+  assert(!Loc.isInvalid() && "Can't get file characteristic of invalid loc!");
+  std::pair<FileID, unsigned> LocInfo = getDecomposedInstantiationLoc(Loc);
+  const SrcMgr::FileInfo &FI = getSLocEntry(LocInfo.first).getFile();
+
+  // If there are no #line directives in this file, just return the whole-file
+  // state.
+  if (!FI.hasLineDirectives())
+    return FI.getFileCharacteristic();
+
+  assert(LineTable && "Can't have linetable entries without a LineTable!");
+  // See if there is a #line directive before the location.
+  const LineEntry *Entry =
+    LineTable->FindNearestLineEntry(LocInfo.first.ID, LocInfo.second);
+
+  // If this is before the first line marker, use the file characteristic.
+  if (!Entry)
+    return FI.getFileCharacteristic();
+
+  return Entry->FileKind;
+}
+
+/// Return the filename or buffer identifier of the buffer the location is in.
+/// Note that this name does not respect #line directives.  Use getPresumedLoc
+/// for normal clients.
+const char *SourceManager::getBufferName(SourceLocation Loc, 
+                                         bool *Invalid) const {
+  if (Loc.isInvalid()) return "<invalid loc>";
+
+  return getBuffer(getFileID(Loc), Invalid)->getBufferIdentifier();
+}
+
+
+/// getPresumedLoc - This method returns the "presumed" location of a
+/// SourceLocation specifies.  A "presumed location" can be modified by #line
+/// or GNU line marker directives.  This provides a view on the data that a
+/// user should see in diagnostics, for example.
+///
+/// Note that a presumed location is always given as the instantiation point
+/// of an instantiation location, not at the spelling location.
+PresumedLoc SourceManager::getPresumedLoc(SourceLocation Loc) const {
+  if (Loc.isInvalid()) return PresumedLoc();
+
+  // Presumed locations are always for instantiation points.
+  std::pair<FileID, unsigned> LocInfo = getDecomposedInstantiationLoc(Loc);
+
+  const SrcMgr::FileInfo &FI = getSLocEntry(LocInfo.first).getFile();
+  const SrcMgr::ContentCache *C = FI.getContentCache();
+
+  // To get the source name, first consult the FileEntry (if one exists)
+  // before the MemBuffer as this will avoid unnecessarily paging in the
+  // MemBuffer.
+  const char *Filename;
+  if (C->Entry)
+    Filename = C->Entry->getName();
+  else
+    Filename = C->getBuffer(Diag, *this)->getBufferIdentifier();
+  unsigned LineNo = getLineNumber(LocInfo.first, LocInfo.second);
+  unsigned ColNo  = getColumnNumber(LocInfo.first, LocInfo.second);
+  SourceLocation IncludeLoc = FI.getIncludeLoc();
+
+  // If we have #line directives in this file, update and overwrite the physical
+  // location info if appropriate.
+  if (FI.hasLineDirectives()) {
+    assert(LineTable && "Can't have linetable entries without a LineTable!");
+    // See if there is a #line directive before this.  If so, get it.
+    if (const LineEntry *Entry =
+          LineTable->FindNearestLineEntry(LocInfo.first.ID, LocInfo.second)) {
+      // If the LineEntry indicates a filename, use it.
+      if (Entry->FilenameID != -1)
+        Filename = LineTable->getFilename(Entry->FilenameID);
+
+      // Use the line number specified by the LineEntry.  This line number may
+      // be multiple lines down from the line entry.  Add the difference in
+      // physical line numbers from the query point and the line marker to the
+      // total.
+      unsigned MarkerLineNo = getLineNumber(LocInfo.first, Entry->FileOffset);
+      LineNo = Entry->LineNo + (LineNo-MarkerLineNo-1);
+
+      // Note that column numbers are not molested by line markers.
+
+      // Handle virtual #include manipulation.
+      if (Entry->IncludeOffset) {
+        IncludeLoc = getLocForStartOfFile(LocInfo.first);
+        IncludeLoc = IncludeLoc.getFileLocWithOffset(Entry->IncludeOffset);
+      }
+    }
+  }
+
+  return PresumedLoc(Filename, LineNo, ColNo, IncludeLoc);
+}
+
+//===----------------------------------------------------------------------===//
+// Other miscellaneous methods.
+//===----------------------------------------------------------------------===//
+
+/// \brief Get the source location for the given file:line:col triplet.
+///
+/// If the source file is included multiple times, the source location will
+/// be based upon the first inclusion.
+SourceLocation SourceManager::getLocation(const FileEntry *SourceFile,
+                                          unsigned Line, unsigned Col) const {
+  assert(SourceFile && "Null source file!");
+  assert(Line && Col && "Line and column should start from 1!");
+
+  fileinfo_iterator FI = FileInfos.find(SourceFile);
+  if (FI == FileInfos.end())
+    return SourceLocation();
+  ContentCache *Content = FI->second;
+
+  // If this is the first use of line information for this buffer, compute the
+  /// SourceLineCache for it on demand.
+  if (Content->SourceLineCache == 0) {
+    bool MyInvalid = false;
+    ComputeLineNumbers(Diag, Content, ContentCacheAlloc, *this, MyInvalid);
+    if (MyInvalid)
+      return SourceLocation();
+  }
+
+  // Find the first file ID that corresponds to the given file.
+  FileID FirstFID;
+
+  // First, check the main file ID, since it is common to look for a
+  // location in the main file.
+  if (!MainFileID.isInvalid()) {
+    const SLocEntry &MainSLoc = getSLocEntry(MainFileID);
+    if (MainSLoc.isFile() && MainSLoc.getFile().getContentCache() == Content)
+      FirstFID = MainFileID;
+  }
+
+  if (FirstFID.isInvalid()) {
+    // The location we're looking for isn't in the main file; look
+    // through all of the source locations.
+    for (unsigned I = 0, N = sloc_entry_size(); I != N; ++I) {
+      const SLocEntry &SLoc = getSLocEntry(I);
+      if (SLoc.isFile() && SLoc.getFile().getContentCache() == Content) {
+        FirstFID = FileID::get(I);
+        break;
+      }
+    }
+  }
+    
+  if (FirstFID.isInvalid())
+    return SourceLocation();
+
+  if (Line > Content->NumLines) {
+    unsigned Size = Content->getBuffer(Diag, *this)->getBufferSize();
+    if (Size > 0)
+      --Size;
+    return getLocForStartOfFile(FirstFID).getFileLocWithOffset(Size);
+  }
+
+  unsigned FilePos = Content->SourceLineCache[Line - 1];
+  const char *Buf = Content->getBuffer(Diag, *this)->getBufferStart() + FilePos;
+  unsigned BufLength = Content->getBuffer(Diag, *this)->getBufferEnd() - Buf;
+  unsigned i = 0;
+
+  // Check that the given column is valid.
+  while (i < BufLength-1 && i < Col-1 && Buf[i] != '\n' && Buf[i] != '\r')
+    ++i;
+  if (i < Col-1)
+    return getLocForStartOfFile(FirstFID).getFileLocWithOffset(FilePos + i);
+
+  return getLocForStartOfFile(FirstFID).getFileLocWithOffset(FilePos + Col - 1);
+}
+
+/// \brief Determines the order of 2 source locations in the translation unit.
+///
+/// \returns true if LHS source location comes before RHS, false otherwise.
+bool SourceManager::isBeforeInTranslationUnit(SourceLocation LHS,
+                                              SourceLocation RHS) const {
+  assert(LHS.isValid() && RHS.isValid() && "Passed invalid source location!");
+  if (LHS == RHS)
+    return false;
+
+  std::pair<FileID, unsigned> LOffs = getDecomposedLoc(LHS);
+  std::pair<FileID, unsigned> ROffs = getDecomposedLoc(RHS);
+
+  // If the source locations are in the same file, just compare offsets.
+  if (LOffs.first == ROffs.first)
+    return LOffs.second < ROffs.second;
+
+  // If we are comparing a source location with multiple locations in the same
+  // file, we get a big win by caching the result.
+
+  if (LastLFIDForBeforeTUCheck == LOffs.first &&
+      LastRFIDForBeforeTUCheck == ROffs.first)
+    return LastResForBeforeTUCheck;
+
+  LastLFIDForBeforeTUCheck = LOffs.first;
+  LastRFIDForBeforeTUCheck = ROffs.first;
+
+  // "Traverse" the include/instantiation stacks of both locations and try to
+  // find a common "ancestor".
+  //
+  // First we traverse the stack of the right location and check each level
+  // against the level of the left location, while collecting all levels in a
+  // "stack map".
+
+  std::map<FileID, unsigned> ROffsMap;
+  ROffsMap[ROffs.first] = ROffs.second;
+
+  while (1) {
+    SourceLocation UpperLoc;
+    const SrcMgr::SLocEntry &Entry = getSLocEntry(ROffs.first);
+    if (Entry.isInstantiation())
+      UpperLoc = Entry.getInstantiation().getInstantiationLocStart();
+    else
+      UpperLoc = Entry.getFile().getIncludeLoc();
+
+    if (UpperLoc.isInvalid())
+      break; // We reached the top.
+
+    ROffs = getDecomposedLoc(UpperLoc);
+
+    if (LOffs.first == ROffs.first)
+      return LastResForBeforeTUCheck = LOffs.second < ROffs.second;
+
+    ROffsMap[ROffs.first] = ROffs.second;
+  }
+
+  // We didn't find a common ancestor. Now traverse the stack of the left
+  // location, checking against the stack map of the right location.
+
+  while (1) {
+    SourceLocation UpperLoc;
+    const SrcMgr::SLocEntry &Entry = getSLocEntry(LOffs.first);
+    if (Entry.isInstantiation())
+      UpperLoc = Entry.getInstantiation().getInstantiationLocStart();
+    else
+      UpperLoc = Entry.getFile().getIncludeLoc();
+
+    if (UpperLoc.isInvalid())
+      break; // We reached the top.
+
+    LOffs = getDecomposedLoc(UpperLoc);
+
+    std::map<FileID, unsigned>::iterator I = ROffsMap.find(LOffs.first);
+    if (I != ROffsMap.end())
+      return LastResForBeforeTUCheck = LOffs.second < I->second;
+  }
+
+  // There is no common ancestor, most probably because one location is in the
+  // predefines buffer.
+  //
+  // FIXME: We should rearrange the external interface so this simply never
+  // happens; it can't conceptually happen. Also see PR5662.
+
+  // If exactly one location is a memory buffer, assume it preceeds the other.
+  bool LIsMB = !getSLocEntry(LOffs.first).getFile().getContentCache()->Entry;
+  bool RIsMB = !getSLocEntry(ROffs.first).getFile().getContentCache()->Entry;
+  if (LIsMB != RIsMB)
+    return LastResForBeforeTUCheck = LIsMB;
+
+  // Otherwise, just assume FileIDs were created in order.
+  return LastResForBeforeTUCheck = (LOffs.first < ROffs.first);
+}
+
+/// PrintStats - Print statistics to stderr.
+///
+void SourceManager::PrintStats() const {
+  llvm::errs() << "\n*** Source Manager Stats:\n";
+  llvm::errs() << FileInfos.size() << " files mapped, " << MemBufferInfos.size()
+               << " mem buffers mapped.\n";
+  llvm::errs() << SLocEntryTable.size() << " SLocEntry's allocated, "
+               << NextOffset << "B of Sloc address space used.\n";
+
+  unsigned NumLineNumsComputed = 0;
+  unsigned NumFileBytesMapped = 0;
+  for (fileinfo_iterator I = fileinfo_begin(), E = fileinfo_end(); I != E; ++I){
+    NumLineNumsComputed += I->second->SourceLineCache != 0;
+    NumFileBytesMapped  += I->second->getSizeBytesMapped();
+  }
+
+  llvm::errs() << NumFileBytesMapped << " bytes of files mapped, "
+               << NumLineNumsComputed << " files with line #'s computed.\n";
+  llvm::errs() << "FileID scans: " << NumLinearScans << " linear, "
+               << NumBinaryProbes << " binary.\n";
+}
+
+ExternalSLocEntrySource::~ExternalSLocEntrySource() { }
diff --git a/lib/Basic/TargetInfo.cpp b/lib/Basic/TargetInfo.cpp
new file mode 100644
index 0000000..4c0c59a
--- /dev/null
+++ b/lib/Basic/TargetInfo.cpp
@@ -0,0 +1,383 @@
+//===--- TargetInfo.cpp - Information about Target machine ----------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements the TargetInfo and TargetInfoImpl interfaces.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Basic/TargetInfo.h"
+#include "clang/Basic/LangOptions.h"
+#include "llvm/ADT/APFloat.h"
+#include "llvm/ADT/STLExtras.h"
+#include <cstdlib>
+using namespace clang;
+
+// TargetInfo Constructor.
+TargetInfo::TargetInfo(const std::string &T) : Triple(T) {
+  // Set defaults.  Defaults are set for a 32-bit RISC platform, like PPC or
+  // SPARC.  These should be overridden by concrete targets as needed.
+  TLSSupported = true;
+  NoAsmVariants = false;
+  PointerWidth = PointerAlign = 32;
+  IntWidth = IntAlign = 32;
+  LongWidth = LongAlign = 32;
+  LongLongWidth = LongLongAlign = 64;
+  FloatWidth = 32;
+  FloatAlign = 32;
+  DoubleWidth = 64;
+  DoubleAlign = 64;
+  LongDoubleWidth = 64;
+  LongDoubleAlign = 64;
+  SizeType = UnsignedLong;
+  PtrDiffType = SignedLong;
+  IntMaxType = SignedLongLong;
+  UIntMaxType = UnsignedLongLong;
+  IntPtrType = SignedLong;
+  WCharType = SignedInt;
+  WIntType = SignedInt;
+  Char16Type = UnsignedShort;
+  Char32Type = UnsignedInt;
+  Int64Type = SignedLongLong;
+  SigAtomicType = SignedInt;
+  UseBitFieldTypeAlignment = true;
+  FloatFormat = &llvm::APFloat::IEEEsingle;
+  DoubleFormat = &llvm::APFloat::IEEEdouble;
+  LongDoubleFormat = &llvm::APFloat::IEEEdouble;
+  DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
+                      "i64:64:64-f32:32:32-f64:64:64-n32";
+  UserLabelPrefix = "_";
+}
+
+// Out of line virtual dtor for TargetInfo.
+TargetInfo::~TargetInfo() {}
+
+/// getTypeName - Return the user string for the specified integer type enum.
+/// For example, SignedShort -> "short".
+const char *TargetInfo::getTypeName(IntType T) {
+  switch (T) {
+  default: assert(0 && "not an integer!");
+  case SignedShort:      return "short";
+  case UnsignedShort:    return "unsigned short";
+  case SignedInt:        return "int";
+  case UnsignedInt:      return "unsigned int";
+  case SignedLong:       return "long int";
+  case UnsignedLong:     return "long unsigned int";
+  case SignedLongLong:   return "long long int";
+  case UnsignedLongLong: return "long long unsigned int";
+  }
+}
+
+/// getTypeConstantSuffix - Return the constant suffix for the specified
+/// integer type enum. For example, SignedLong -> "L".
+const char *TargetInfo::getTypeConstantSuffix(IntType T) {
+  switch (T) {
+  default: assert(0 && "not an integer!");
+  case SignedShort:
+  case SignedInt:        return "";
+  case SignedLong:       return "L";
+  case SignedLongLong:   return "LL";
+  case UnsignedShort:
+  case UnsignedInt:      return "U";
+  case UnsignedLong:     return "UL";
+  case UnsignedLongLong: return "ULL";
+  }
+}
+
+/// getTypeWidth - Return the width (in bits) of the specified integer type 
+/// enum. For example, SignedInt -> getIntWidth().
+unsigned TargetInfo::getTypeWidth(IntType T) const {
+  switch (T) {
+  default: assert(0 && "not an integer!");
+  case SignedShort:
+  case UnsignedShort:    return getShortWidth();
+  case SignedInt:
+  case UnsignedInt:      return getIntWidth();
+  case SignedLong:
+  case UnsignedLong:     return getLongWidth();
+  case SignedLongLong:
+  case UnsignedLongLong: return getLongLongWidth();
+  };
+}
+
+/// getTypeAlign - Return the alignment (in bits) of the specified integer type 
+/// enum. For example, SignedInt -> getIntAlign().
+unsigned TargetInfo::getTypeAlign(IntType T) const {
+  switch (T) {
+  default: assert(0 && "not an integer!");
+  case SignedShort:
+  case UnsignedShort:    return getShortAlign();
+  case SignedInt:
+  case UnsignedInt:      return getIntAlign();
+  case SignedLong:
+  case UnsignedLong:     return getLongAlign();
+  case SignedLongLong:
+  case UnsignedLongLong: return getLongLongAlign();
+  };
+}
+
+/// isTypeSigned - Return whether an integer types is signed. Returns true if
+/// the type is signed; false otherwise.
+bool TargetInfo::isTypeSigned(IntType T) const {
+  switch (T) {
+  default: assert(0 && "not an integer!");
+  case SignedShort:
+  case SignedInt:
+  case SignedLong:
+  case SignedLongLong:   
+    return true;
+  case UnsignedShort:
+  case UnsignedInt:
+  case UnsignedLong:
+  case UnsignedLongLong: 
+    return false;
+  };
+}
+
+/// setForcedLangOptions - Set forced language options.
+/// Apply changes to the target information with respect to certain
+/// language options which change the target configuration.
+void TargetInfo::setForcedLangOptions(LangOptions &Opts) {
+  if (Opts.NoBitFieldTypeAlign)
+    UseBitFieldTypeAlignment = false;
+  if (Opts.ShortWChar)
+    WCharType = UnsignedShort;
+}
+
+//===----------------------------------------------------------------------===//
+
+
+static llvm::StringRef removeGCCRegisterPrefix(llvm::StringRef Name) {
+  if (Name[0] == '%' || Name[0] == '#')
+    Name = Name.substr(1);
+  
+  return Name;
+}
+
+/// isValidGCCRegisterName - Returns whether the passed in string
+/// is a valid register name according to GCC. This is used by Sema for
+/// inline asm statements.
+bool TargetInfo::isValidGCCRegisterName(llvm::StringRef Name) const {
+  if (Name.empty())
+    return false;
+  
+  const char * const *Names;
+  unsigned NumNames;
+
+  // Get rid of any register prefix.
+  Name = removeGCCRegisterPrefix(Name);
+
+  if (Name == "memory" || Name == "cc")
+    return true;
+
+  getGCCRegNames(Names, NumNames);
+
+  // If we have a number it maps to an entry in the register name array.
+  if (isdigit(Name[0])) {
+    int n;
+    if (!Name.getAsInteger(0, n))
+      return n >= 0 && (unsigned)n < NumNames;
+  }
+
+  // Check register names.
+  for (unsigned i = 0; i < NumNames; i++) {
+    if (Name == Names[i])
+      return true;
+  }
+
+  // Now check aliases.
+  const GCCRegAlias *Aliases;
+  unsigned NumAliases;
+
+  getGCCRegAliases(Aliases, NumAliases);
+  for (unsigned i = 0; i < NumAliases; i++) {
+    for (unsigned j = 0 ; j < llvm::array_lengthof(Aliases[i].Aliases); j++) {
+      if (!Aliases[i].Aliases[j])
+        break;
+      if (Aliases[i].Aliases[j] == Name)
+        return true;
+    }
+  }
+
+  return false;
+}
+
+llvm::StringRef 
+TargetInfo::getNormalizedGCCRegisterName(llvm::StringRef Name) const {
+  assert(isValidGCCRegisterName(Name) && "Invalid register passed in");
+
+  // Get rid of any register prefix.
+  Name = removeGCCRegisterPrefix(Name);
+
+  const char * const *Names;
+  unsigned NumNames;
+
+  getGCCRegNames(Names, NumNames);
+
+  // First, check if we have a number.
+  if (isdigit(Name[0])) {
+    int n;
+    if (!Name.getAsInteger(0, n)) {
+      assert(n >= 0 && (unsigned)n < NumNames &&
+             "Out of bounds register number!");
+      return Names[n];
+    }
+  }
+
+  // Now check aliases.
+  const GCCRegAlias *Aliases;
+  unsigned NumAliases;
+
+  getGCCRegAliases(Aliases, NumAliases);
+  for (unsigned i = 0; i < NumAliases; i++) {
+    for (unsigned j = 0 ; j < llvm::array_lengthof(Aliases[i].Aliases); j++) {
+      if (!Aliases[i].Aliases[j])
+        break;
+      if (Aliases[i].Aliases[j] == Name)
+        return Aliases[i].Register;
+    }
+  }
+
+  return Name;
+}
+
+bool TargetInfo::validateOutputConstraint(ConstraintInfo &Info) const {
+  const char *Name = Info.getConstraintStr().c_str();
+  // An output constraint must start with '=' or '+'
+  if (*Name != '=' && *Name != '+')
+    return false;
+
+  if (*Name == '+')
+    Info.setIsReadWrite();
+
+  Name++;
+  while (*Name) {
+    switch (*Name) {
+    default:
+      if (!validateAsmConstraint(Name, Info)) {
+        // FIXME: We temporarily return false
+        // so we can add more constraints as we hit it.
+        // Eventually, an unknown constraint should just be treated as 'g'.
+        return false;
+      }
+    case '&': // early clobber.
+      break;
+    case '%': // commutative.
+      // FIXME: Check that there is a another register after this one.
+      break;
+    case 'r': // general register.
+      Info.setAllowsRegister();
+      break;
+    case 'm': // memory operand.
+      Info.setAllowsMemory();
+      break;
+    case 'g': // general register, memory operand or immediate integer.
+    case 'X': // any operand.
+      Info.setAllowsRegister();
+      Info.setAllowsMemory();
+      break;
+    }
+
+    Name++;
+  }
+
+  return true;
+}
+
+bool TargetInfo::resolveSymbolicName(const char *&Name,
+                                     ConstraintInfo *OutputConstraints,
+                                     unsigned NumOutputs,
+                                     unsigned &Index) const {
+  assert(*Name == '[' && "Symbolic name did not start with '['");
+  Name++;
+  const char *Start = Name;
+  while (*Name && *Name != ']')
+    Name++;
+
+  if (!*Name) {
+    // Missing ']'
+    return false;
+  }
+
+  std::string SymbolicName(Start, Name - Start);
+
+  for (Index = 0; Index != NumOutputs; ++Index)
+    if (SymbolicName == OutputConstraints[Index].getName())
+      return true;
+
+  return false;
+}
+
+bool TargetInfo::validateInputConstraint(ConstraintInfo *OutputConstraints,
+                                         unsigned NumOutputs,
+                                         ConstraintInfo &Info) const {
+  const char *Name = Info.ConstraintStr.c_str();
+
+  while (*Name) {
+    switch (*Name) {
+    default:
+      // Check if we have a matching constraint
+      if (*Name >= '0' && *Name <= '9') {
+        unsigned i = *Name - '0';
+
+        // Check if matching constraint is out of bounds.
+        if (i >= NumOutputs)
+          return false;
+
+        // The constraint should have the same info as the respective
+        // output constraint.
+        Info.setTiedOperand(i, OutputConstraints[i]);
+      } else if (!validateAsmConstraint(Name, Info)) {
+        // FIXME: This error return is in place temporarily so we can
+        // add more constraints as we hit it.  Eventually, an unknown
+        // constraint should just be treated as 'g'.
+        return false;
+      }
+      break;
+    case '[': {
+      unsigned Index = 0;
+      if (!resolveSymbolicName(Name, OutputConstraints, NumOutputs, Index))
+        return false;
+
+      break;
+    }
+    case '%': // commutative
+      // FIXME: Fail if % is used with the last operand.
+      break;
+    case 'i': // immediate integer.
+    case 'n': // immediate integer with a known value.
+      break;
+    case 'I':  // Various constant constraints with target-specific meanings.
+    case 'J':
+    case 'K':
+    case 'L':
+    case 'M':
+    case 'N':
+    case 'O':
+    case 'P':
+      break;
+    case 'r': // general register.
+      Info.setAllowsRegister();
+      break;
+    case 'm': // memory operand.
+    case 'o': // offsettable memory operand
+    case 'V': // non-offsettable memory operand
+      Info.setAllowsMemory();
+      break;
+    case 'g': // general register, memory operand or immediate integer.
+    case 'X': // any operand.
+      Info.setAllowsRegister();
+      Info.setAllowsMemory();
+      break;
+    }
+
+    Name++;
+  }
+
+  return true;
+}
diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp
new file mode 100644
index 0000000..3d5048c
--- /dev/null
+++ b/lib/Basic/Targets.cpp
@@ -0,0 +1,2473 @@
+//===--- Targets.cpp - Implement -arch option and targets -----------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements construction of a TargetInfo object from a
+// target triple.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Basic/TargetInfo.h"
+#include "clang/Basic/Builtins.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/MacroBuilder.h"
+#include "clang/Basic/TargetBuiltins.h"
+#include "clang/Basic/TargetOptions.h"
+#include "llvm/ADT/APFloat.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/MC/MCSectionMachO.h"
+#include <algorithm>
+using namespace clang;
+
+//===----------------------------------------------------------------------===//
+//  Common code shared among targets.
+//===----------------------------------------------------------------------===//
+
+/// DefineStd - Define a macro name and standard variants.  For example if
+/// MacroName is "unix", then this will define "__unix", "__unix__", and "unix"
+/// when in GNU mode.
+static void DefineStd(MacroBuilder &Builder, llvm::StringRef MacroName,
+                      const LangOptions &Opts) {
+  assert(MacroName[0] != '_' && "Identifier should be in the user's namespace");
+
+  // If in GNU mode (e.g. -std=gnu99 but not -std=c99) define the raw identifier
+  // in the user's namespace.
+  if (Opts.GNUMode)
+    Builder.defineMacro(MacroName);
+
+  // Define __unix.
+  Builder.defineMacro("__" + MacroName);
+
+  // Define __unix__.
+  Builder.defineMacro("__" + MacroName + "__");
+}
+
+//===----------------------------------------------------------------------===//
+// Defines specific to certain operating systems.
+//===----------------------------------------------------------------------===//
+
+namespace {
+template<typename TgtInfo>
+class OSTargetInfo : public TgtInfo {
+protected:
+  virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
+                            MacroBuilder &Builder) const=0;
+public:
+  OSTargetInfo(const std::string& triple) : TgtInfo(triple) {}
+  virtual void getTargetDefines(const LangOptions &Opts,
+                                MacroBuilder &Builder) const {
+    TgtInfo::getTargetDefines(Opts, Builder);
+    getOSDefines(Opts, TgtInfo::getTriple(), Builder);
+  }
+
+};
+} // end anonymous namespace
+
+
+static void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts,
+                             const llvm::Triple &Triple) {
+  Builder.defineMacro("__APPLE_CC__", "5621");
+  Builder.defineMacro("__APPLE__");
+  Builder.defineMacro("__MACH__");
+  Builder.defineMacro("OBJC_NEW_PROPERTIES");
+
+  // __weak is always defined, for use in blocks and with objc pointers.
+  Builder.defineMacro("__weak", "__attribute__((objc_gc(weak)))");
+
+  // Darwin defines __strong even in C mode (just to nothing).
+  if (!Opts.ObjC1 || Opts.getGCMode() == LangOptions::NonGC)
+    Builder.defineMacro("__strong", "");
+  else
+    Builder.defineMacro("__strong", "__attribute__((objc_gc(strong)))");
+
+  if (Opts.Static)
+    Builder.defineMacro("__STATIC__");
+  else
+    Builder.defineMacro("__DYNAMIC__");
+
+  if (Opts.POSIXThreads)
+    Builder.defineMacro("_REENTRANT");
+
+  // Get the OS version number from the triple.
+  unsigned Maj, Min, Rev;
+
+  // If no version was given, default to to 10.4.0, for simplifying tests.
+  if (Triple.getOSName() == "darwin") {
+    Min = Rev = 0;
+    Maj = 8;
+  } else
+    Triple.getDarwinNumber(Maj, Min, Rev);
+
+  // Set the appropriate OS version define.
+  if (Triple.getEnvironmentName() == "iphoneos") {
+    assert(Maj < 10 && Min < 99 && Rev < 99 && "Invalid version!");
+    char Str[6];
+    Str[0] = '0' + Maj;
+    Str[1] = '0' + (Min / 10);
+    Str[2] = '0' + (Min % 10);
+    Str[3] = '0' + (Rev / 10);
+    Str[4] = '0' + (Rev % 10);
+    Str[5] = '\0';
+    Builder.defineMacro("__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__", Str);
+  } else {
+    // For historical reasons that make little sense, the version passed here is
+    // the "darwin" version, which drops the 10 and offsets by 4.
+    Rev = Min;
+    Min = Maj - 4;
+    Maj = 10;
+
+    assert(Triple.getEnvironmentName().empty() && "Invalid environment!");
+    assert(Maj < 99 && Min < 10 && Rev < 10 && "Invalid version!");
+    char Str[5];
+    Str[0] = '0' + (Maj / 10);
+    Str[1] = '0' + (Maj % 10);
+    Str[2] = '0' + Min;
+    Str[3] = '0' + Rev;
+    Str[4] = '\0';
+    Builder.defineMacro("__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__", Str);
+  }
+}
+
+namespace {
+template<typename Target>
+class DarwinTargetInfo : public OSTargetInfo<Target> {
+protected:
+  virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
+                            MacroBuilder &Builder) const {
+    getDarwinDefines(Builder, Opts, Triple);
+  }
+
+public:
+  DarwinTargetInfo(const std::string& triple) :
+    OSTargetInfo<Target>(triple) {
+      this->TLSSupported = false;
+    }
+
+  virtual std::string isValidSectionSpecifier(llvm::StringRef SR) const {
+    // Let MCSectionMachO validate this.
+    llvm::StringRef Segment, Section;
+    unsigned TAA, StubSize;
+    return llvm::MCSectionMachO::ParseSectionSpecifier(SR, Segment, Section,
+                                                       TAA, StubSize);
+  }
+};
+
+
+// DragonFlyBSD Target
+template<typename Target>
+class DragonFlyBSDTargetInfo : public OSTargetInfo<Target> {
+protected:
+  virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
+                            MacroBuilder &Builder) const {
+    // DragonFly defines; list based off of gcc output
+    Builder.defineMacro("__DragonFly__");
+    Builder.defineMacro("__DragonFly_cc_version", "100001");
+    Builder.defineMacro("__ELF__");
+    Builder.defineMacro("__KPRINTF_ATTRIBUTE__");
+    Builder.defineMacro("__tune_i386__");
+    DefineStd(Builder, "unix", Opts);
+  }
+public:
+  DragonFlyBSDTargetInfo(const std::string &triple)
+    : OSTargetInfo<Target>(triple) {}
+};
+
+// FreeBSD Target
+template<typename Target>
+class FreeBSDTargetInfo : public OSTargetInfo<Target> {
+protected:
+  virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
+                            MacroBuilder &Builder) const {
+    // FreeBSD defines; list based off of gcc output
+
+    // FIXME: Move version number handling to llvm::Triple.
+    llvm::StringRef Release = Triple.getOSName().substr(strlen("freebsd"), 1);
+
+    Builder.defineMacro("__FreeBSD__", Release);
+    Builder.defineMacro("__FreeBSD_cc_version", Release + "00001");
+    Builder.defineMacro("__KPRINTF_ATTRIBUTE__");
+    DefineStd(Builder, "unix", Opts);
+    Builder.defineMacro("__ELF__");
+  }
+public:
+  FreeBSDTargetInfo(const std::string &triple)
+    : OSTargetInfo<Target>(triple) {
+      this->UserLabelPrefix = "";
+    }
+};
+
+// Linux target
+template<typename Target>
+class LinuxTargetInfo : public OSTargetInfo<Target> {
+protected:
+  virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
+                            MacroBuilder &Builder) const {
+    // Linux defines; list based off of gcc output
+    DefineStd(Builder, "unix", Opts);
+    DefineStd(Builder, "linux", Opts);
+    Builder.defineMacro("__gnu_linux__");
+    Builder.defineMacro("__ELF__");
+    if (Opts.POSIXThreads)
+      Builder.defineMacro("_REENTRANT");
+    if (Opts.CPlusPlus)
+      Builder.defineMacro("_GNU_SOURCE");
+  }
+public:
+  LinuxTargetInfo(const std::string& triple)
+    : OSTargetInfo<Target>(triple) {
+    this->UserLabelPrefix = "";
+  }
+};
+
+// NetBSD Target
+template<typename Target>
+class NetBSDTargetInfo : public OSTargetInfo<Target> {
+protected:
+  virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
+                            MacroBuilder &Builder) const {
+    // NetBSD defines; list based off of gcc output
+    Builder.defineMacro("__NetBSD__");
+    Builder.defineMacro("__unix__");
+    Builder.defineMacro("__ELF__");
+    if (Opts.POSIXThreads)
+      Builder.defineMacro("_POSIX_THREADS");
+  }
+public:
+  NetBSDTargetInfo(const std::string &triple)
+    : OSTargetInfo<Target>(triple) {
+      this->UserLabelPrefix = "";
+    }
+};
+
+// OpenBSD Target
+template<typename Target>
+class OpenBSDTargetInfo : public OSTargetInfo<Target> {
+protected:
+  virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
+                            MacroBuilder &Builder) const {
+    // OpenBSD defines; list based off of gcc output
+
+    Builder.defineMacro("__OpenBSD__");
+    DefineStd(Builder, "unix", Opts);
+    Builder.defineMacro("__ELF__");
+    if (Opts.POSIXThreads)
+      Builder.defineMacro("_POSIX_THREADS");
+  }
+public:
+  OpenBSDTargetInfo(const std::string &triple)
+    : OSTargetInfo<Target>(triple) {}
+};
+
+// PSP Target
+template<typename Target>
+class PSPTargetInfo : public OSTargetInfo<Target> {
+protected:
+  virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
+                            MacroBuilder &Builder) const {
+    // PSP defines; list based on the output of the pspdev gcc toolchain.
+    Builder.defineMacro("PSP");
+    Builder.defineMacro("_PSP");
+    Builder.defineMacro("__psp__");
+    Builder.defineMacro("__ELF__");
+  }
+public:
+  PSPTargetInfo(const std::string& triple)
+    : OSTargetInfo<Target>(triple) {
+    this->UserLabelPrefix = "";
+  }
+};
+
+// PS3 PPU Target
+template<typename Target>
+class PS3PPUTargetInfo : public OSTargetInfo<Target> {
+protected:
+  virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
+                            MacroBuilder &Builder) const {
+    // PS3 PPU defines.
+    Builder.defineMacro("__PPC__");
+    Builder.defineMacro("__PPU__");
+    Builder.defineMacro("__CELLOS_LV2__");
+    Builder.defineMacro("__ELF__");
+    Builder.defineMacro("__LP32__");
+  }
+public:
+  PS3PPUTargetInfo(const std::string& triple)
+    : OSTargetInfo<Target>(triple) {
+    this->UserLabelPrefix = "";
+    this->LongWidth = this->LongAlign = this->PointerWidth = this->PointerAlign = 32;
+    this->SizeType = TargetInfo::UnsignedInt;
+  }
+};
+
+// FIXME: Need a real SPU target.
+// PS3 SPU Target
+template<typename Target>
+class PS3SPUTargetInfo : public OSTargetInfo<Target> {
+protected:
+  virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
+                            MacroBuilder &Builder) const {
+    // PS3 PPU defines.
+    Builder.defineMacro("__SPU__");
+    Builder.defineMacro("__ELF__");
+  }
+public:
+  PS3SPUTargetInfo(const std::string& triple)
+    : OSTargetInfo<Target>(triple) {
+    this->UserLabelPrefix = "";
+  }
+};
+
+// AuroraUX target
+template<typename Target>
+class AuroraUXTargetInfo : public OSTargetInfo<Target> {
+protected:
+  virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
+                            MacroBuilder &Builder) const {
+    DefineStd(Builder, "sun", Opts);
+    DefineStd(Builder, "unix", Opts);
+    Builder.defineMacro("__ELF__");
+    Builder.defineMacro("__svr4__");
+    Builder.defineMacro("__SVR4");
+  }
+public:
+  AuroraUXTargetInfo(const std::string& triple)
+    : OSTargetInfo<Target>(triple) {
+    this->UserLabelPrefix = "";
+    this->WCharType = this->SignedLong;
+    // FIXME: WIntType should be SignedLong
+  }
+};
+
+// Solaris target
+template<typename Target>
+class SolarisTargetInfo : public OSTargetInfo<Target> {
+protected:
+  virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
+                            MacroBuilder &Builder) const {
+    DefineStd(Builder, "sun", Opts);
+    DefineStd(Builder, "unix", Opts);
+    Builder.defineMacro("__ELF__");
+    Builder.defineMacro("__svr4__");
+    Builder.defineMacro("__SVR4");
+  }
+public:
+  SolarisTargetInfo(const std::string& triple)
+    : OSTargetInfo<Target>(triple) {
+    this->UserLabelPrefix = "";
+    this->WCharType = this->SignedLong;
+    // FIXME: WIntType should be SignedLong
+  }
+};
+} // end anonymous namespace.
+
+//===----------------------------------------------------------------------===//
+// Specific target implementations.
+//===----------------------------------------------------------------------===//
+
+namespace {
+// PPC abstract base class
+class PPCTargetInfo : public TargetInfo {
+  static const Builtin::Info BuiltinInfo[];
+  static const char * const GCCRegNames[];
+  static const TargetInfo::GCCRegAlias GCCRegAliases[];
+
+public:
+  PPCTargetInfo(const std::string& triple) : TargetInfo(triple) {}
+
+  virtual void getTargetBuiltins(const Builtin::Info *&Records,
+                                 unsigned &NumRecords) const {
+    Records = BuiltinInfo;
+    NumRecords = clang::PPC::LastTSBuiltin-Builtin::FirstTSBuiltin;
+  }
+
+  virtual void getTargetDefines(const LangOptions &Opts,
+                                MacroBuilder &Builder) const;
+
+  virtual const char *getVAListDeclaration() const {
+    return "typedef char* __builtin_va_list;";
+    // This is the right definition for ABI/V4: System V.4/eabi.
+    /*return "typedef struct __va_list_tag {"
+           "  unsigned char gpr;"
+           "  unsigned char fpr;"
+           "  unsigned short reserved;"
+           "  void* overflow_arg_area;"
+           "  void* reg_save_area;"
+           "} __builtin_va_list[1];";*/
+  }
+  virtual void getGCCRegNames(const char * const *&Names,
+                              unsigned &NumNames) const;
+  virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
+                                unsigned &NumAliases) const;
+  virtual bool validateAsmConstraint(const char *&Name,
+                                     TargetInfo::ConstraintInfo &Info) const {
+    switch (*Name) {
+    default: return false;
+    case 'O': // Zero
+      return true;
+    case 'b': // Base register
+    case 'f': // Floating point register
+      Info.setAllowsRegister();
+      return true;
+    }
+  }
+  virtual const char *getClobbers() const {
+    return "";
+  }
+};
+
+const Builtin::Info PPCTargetInfo::BuiltinInfo[] = {
+#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, false },
+#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER, false },
+#include "clang/Basic/BuiltinsPPC.def"
+};
+
+
+/// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific
+/// #defines that are not tied to a specific subtarget.
+void PPCTargetInfo::getTargetDefines(const LangOptions &Opts,
+                                     MacroBuilder &Builder) const {
+  // Target identification.
+  Builder.defineMacro("__ppc__");
+  Builder.defineMacro("_ARCH_PPC");
+  Builder.defineMacro("__powerpc__");
+  Builder.defineMacro("__POWERPC__");
+  if (PointerWidth == 64) {
+    Builder.defineMacro("_ARCH_PPC64");
+    Builder.defineMacro("_LP64");
+    Builder.defineMacro("__LP64__");
+    Builder.defineMacro("__powerpc64__");
+    Builder.defineMacro("__ppc64__");
+  } else {
+    Builder.defineMacro("__ppc__");
+  }
+
+  // Target properties.
+  Builder.defineMacro("_BIG_ENDIAN");
+  Builder.defineMacro("__BIG_ENDIAN__");
+
+  // Subtarget options.
+  Builder.defineMacro("__NATURAL_ALIGNMENT__");
+  Builder.defineMacro("__REGISTER_PREFIX__", "");
+
+  // FIXME: Should be controlled by command line option.
+  Builder.defineMacro("__LONG_DOUBLE_128__");
+  
+  if (Opts.AltiVec) {
+    Builder.defineMacro("__VEC__", "10206");
+    Builder.defineMacro("__ALTIVEC__");
+  }
+}
+
+
+const char * const PPCTargetInfo::GCCRegNames[] = {
+  "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+  "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+  "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
+  "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
+  "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
+  "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
+  "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
+  "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
+  "mq", "lr", "ctr", "ap",
+  "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",
+  "xer",
+  "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7",
+  "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15",
+  "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",
+  "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",
+  "vrsave", "vscr",
+  "spe_acc", "spefscr",
+  "sfp"
+};
+
+void PPCTargetInfo::getGCCRegNames(const char * const *&Names,
+                                   unsigned &NumNames) const {
+  Names = GCCRegNames;
+  NumNames = llvm::array_lengthof(GCCRegNames);
+}
+
+const TargetInfo::GCCRegAlias PPCTargetInfo::GCCRegAliases[] = {
+  // While some of these aliases do map to different registers
+  // they still share the same register name.
+  { { "0" }, "r0" },
+  { { "1"}, "r1" },
+  { { "2" }, "r2" },
+  { { "3" }, "r3" },
+  { { "4" }, "r4" },
+  { { "5" }, "r5" },
+  { { "6" }, "r6" },
+  { { "7" }, "r7" },
+  { { "8" }, "r8" },
+  { { "9" }, "r9" },
+  { { "10" }, "r10" },
+  { { "11" }, "r11" },
+  { { "12" }, "r12" },
+  { { "13" }, "r13" },
+  { { "14" }, "r14" },
+  { { "15" }, "r15" },
+  { { "16" }, "r16" },
+  { { "17" }, "r17" },
+  { { "18" }, "r18" },
+  { { "19" }, "r19" },
+  { { "20" }, "r20" },
+  { { "21" }, "r21" },
+  { { "22" }, "r22" },
+  { { "23" }, "r23" },
+  { { "24" }, "r24" },
+  { { "25" }, "r25" },
+  { { "26" }, "r26" },
+  { { "27" }, "r27" },
+  { { "28" }, "r28" },
+  { { "29" }, "r29" },
+  { { "30" }, "r30" },
+  { { "31" }, "r31" },
+  { { "fr0" }, "f0" },
+  { { "fr1" }, "f1" },
+  { { "fr2" }, "f2" },
+  { { "fr3" }, "f3" },
+  { { "fr4" }, "f4" },
+  { { "fr5" }, "f5" },
+  { { "fr6" }, "f6" },
+  { { "fr7" }, "f7" },
+  { { "fr8" }, "f8" },
+  { { "fr9" }, "f9" },
+  { { "fr10" }, "f10" },
+  { { "fr11" }, "f11" },
+  { { "fr12" }, "f12" },
+  { { "fr13" }, "f13" },
+  { { "fr14" }, "f14" },
+  { { "fr15" }, "f15" },
+  { { "fr16" }, "f16" },
+  { { "fr17" }, "f17" },
+  { { "fr18" }, "f18" },
+  { { "fr19" }, "f19" },
+  { { "fr20" }, "f20" },
+  { { "fr21" }, "f21" },
+  { { "fr22" }, "f22" },
+  { { "fr23" }, "f23" },
+  { { "fr24" }, "f24" },
+  { { "fr25" }, "f25" },
+  { { "fr26" }, "f26" },
+  { { "fr27" }, "f27" },
+  { { "fr28" }, "f28" },
+  { { "fr29" }, "f29" },
+  { { "fr30" }, "f30" },
+  { { "fr31" }, "f31" },
+  { { "cc" }, "cr0" },
+};
+
+void PPCTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
+                                     unsigned &NumAliases) const {
+  Aliases = GCCRegAliases;
+  NumAliases = llvm::array_lengthof(GCCRegAliases);
+}
+} // end anonymous namespace.
+
+namespace {
+class PPC32TargetInfo : public PPCTargetInfo {
+public:
+  PPC32TargetInfo(const std::string &triple) : PPCTargetInfo(triple) {
+    DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
+                        "i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32";
+
+    if (getTriple().getOS() == llvm::Triple::FreeBSD)
+        this->SizeType = TargetInfo::UnsignedInt;
+  }
+};
+} // end anonymous namespace.
+
+namespace {
+class PPC64TargetInfo : public PPCTargetInfo {
+public:
+  PPC64TargetInfo(const std::string& triple) : PPCTargetInfo(triple) {
+    LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
+    IntMaxType = SignedLong;
+    UIntMaxType = UnsignedLong;
+    Int64Type = SignedLong;
+    DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
+                        "i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32:64";
+  }
+};
+} // end anonymous namespace.
+
+namespace {
+// MBlaze abstract base class
+class MBlazeTargetInfo : public TargetInfo {
+  static const char * const GCCRegNames[];
+  static const TargetInfo::GCCRegAlias GCCRegAliases[];
+
+public:
+  MBlazeTargetInfo(const std::string& triple) : TargetInfo(triple) {
+    DescriptionString = "E-p:32:32-i8:8:8-i16:16:16-i64:32:32-f64:32:32-"
+                        "v64:32:32-v128:32:32-n32";
+  }
+
+  virtual void getTargetBuiltins(const Builtin::Info *&Records,
+                                 unsigned &NumRecords) const {
+    // FIXME: Implement.
+    Records = 0;
+    NumRecords = 0;
+  }
+
+  virtual void getTargetDefines(const LangOptions &Opts,
+                                MacroBuilder &Builder) const;
+
+  virtual const char *getVAListDeclaration() const {
+    return "typedef char* __builtin_va_list;";
+  }
+  virtual const char *getTargetPrefix() const {
+    return "mblaze";
+  }
+  virtual void getGCCRegNames(const char * const *&Names,
+                              unsigned &NumNames) const;
+  virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
+                                unsigned &NumAliases) const;
+  virtual bool validateAsmConstraint(const char *&Name,
+                                     TargetInfo::ConstraintInfo &Info) const {
+    switch (*Name) {
+    default: return false;
+    case 'O': // Zero
+      return true;
+    case 'b': // Base register
+    case 'f': // Floating point register
+      Info.setAllowsRegister();
+      return true;
+    }
+  }
+  virtual const char *getClobbers() const {
+    return "";
+  }
+};
+
+/// MBlazeTargetInfo::getTargetDefines - Return a set of the MBlaze-specific
+/// #defines that are not tied to a specific subtarget.
+void MBlazeTargetInfo::getTargetDefines(const LangOptions &Opts,
+                                     MacroBuilder &Builder) const {
+  // Target identification.
+  Builder.defineMacro("__microblaze__");
+  Builder.defineMacro("_ARCH_MICROBLAZE");
+  Builder.defineMacro("__MICROBLAZE__");
+
+  // Target properties.
+  Builder.defineMacro("_BIG_ENDIAN");
+  Builder.defineMacro("__BIG_ENDIAN__");
+
+  // Subtarget options.
+  Builder.defineMacro("__REGISTER_PREFIX__", "");
+}
+
+
+const char * const MBlazeTargetInfo::GCCRegNames[] = {
+  "r0",   "r1",   "r2",   "r3",   "r4",   "r5",   "r6",   "r7",
+  "r8",   "r9",   "r10",  "r11",  "r12",  "r13",  "r14",  "r15",
+  "r16",  "r17",  "r18",  "r19",  "r20",  "r21",  "r22",  "r23",
+  "r24",  "r25",  "r26",  "r27",  "r28",  "r29",  "r30",  "r31",
+  "$f0",  "$f1",  "$f2",  "$f3",  "$f4",  "$f5",  "$f6",  "$f7",
+  "$f8",  "$f9",  "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
+  "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
+  "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",
+  "hi",   "lo",   "accum","rmsr", "$fcc1","$fcc2","$fcc3","$fcc4",
+  "$fcc5","$fcc6","$fcc7","$ap",  "$rap", "$frp"
+};
+
+void MBlazeTargetInfo::getGCCRegNames(const char * const *&Names,
+                                   unsigned &NumNames) const {
+  Names = GCCRegNames;
+  NumNames = llvm::array_lengthof(GCCRegNames);
+}
+
+const TargetInfo::GCCRegAlias MBlazeTargetInfo::GCCRegAliases[] = {
+  { {"f0"},  "r0" },
+  { {"f1"},  "r1" },
+  { {"f2"},  "r2" },
+  { {"f3"},  "r3" },
+  { {"f4"},  "r4" },
+  { {"f5"},  "r5" },
+  { {"f6"},  "r6" },
+  { {"f7"},  "r7" },
+  { {"f8"},  "r8" },
+  { {"f9"},  "r9" },
+  { {"f10"}, "r10" },
+  { {"f11"}, "r11" },
+  { {"f12"}, "r12" },
+  { {"f13"}, "r13" },
+  { {"f14"}, "r14" },
+  { {"f15"}, "r15" },
+  { {"f16"}, "r16" },
+  { {"f17"}, "r17" },
+  { {"f18"}, "r18" },
+  { {"f19"}, "r19" },
+  { {"f20"}, "r20" },
+  { {"f21"}, "r21" },
+  { {"f22"}, "r22" },
+  { {"f23"}, "r23" },
+  { {"f24"}, "r24" },
+  { {"f25"}, "r25" },
+  { {"f26"}, "r26" },
+  { {"f27"}, "r27" },
+  { {"f28"}, "r28" },
+  { {"f29"}, "r29" },
+  { {"f30"}, "r30" },
+  { {"f31"}, "r31" },
+};
+
+void MBlazeTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
+                                     unsigned &NumAliases) const {
+  Aliases = GCCRegAliases;
+  NumAliases = llvm::array_lengthof(GCCRegAliases);
+}
+} // end anonymous namespace.
+
+namespace {
+// Namespace for x86 abstract base class
+const Builtin::Info BuiltinInfo[] = {
+#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, false },
+#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER, false },
+#include "clang/Basic/BuiltinsX86.def"
+};
+
+static const char* const GCCRegNames[] = {
+  "ax", "dx", "cx", "bx", "si", "di", "bp", "sp",
+  "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)",
+  "argp", "flags", "fspr", "dirflag", "frame",
+  "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
+  "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7",
+  "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+  "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"
+};
+
+const TargetInfo::GCCRegAlias GCCRegAliases[] = {
+  { { "al", "ah", "eax", "rax" }, "ax" },
+  { { "bl", "bh", "ebx", "rbx" }, "bx" },
+  { { "cl", "ch", "ecx", "rcx" }, "cx" },
+  { { "dl", "dh", "edx", "rdx" }, "dx" },
+  { { "esi", "rsi" }, "si" },
+  { { "edi", "rdi" }, "di" },
+  { { "esp", "rsp" }, "sp" },
+  { { "ebp", "rbp" }, "bp" },
+};
+
+// X86 target abstract base class; x86-32 and x86-64 are very close, so
+// most of the implementation can be shared.
+class X86TargetInfo : public TargetInfo {
+  enum X86SSEEnum {
+    NoMMXSSE, MMX, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42
+  } SSELevel;
+  enum AMD3DNowEnum {
+    NoAMD3DNow, AMD3DNow, AMD3DNowAthlon
+  } AMD3DNowLevel;
+
+  bool HasAES;
+  
+public:
+  X86TargetInfo(const std::string& triple)
+    : TargetInfo(triple), SSELevel(NoMMXSSE), AMD3DNowLevel(NoAMD3DNow),
+      HasAES(false) {
+    LongDoubleFormat = &llvm::APFloat::x87DoubleExtended;
+  }
+  virtual void getTargetBuiltins(const Builtin::Info *&Records,
+                                 unsigned &NumRecords) const {
+    Records = BuiltinInfo;
+    NumRecords = clang::X86::LastTSBuiltin-Builtin::FirstTSBuiltin;
+  }
+  virtual void getGCCRegNames(const char * const *&Names,
+                              unsigned &NumNames) const {
+    Names = GCCRegNames;
+    NumNames = llvm::array_lengthof(GCCRegNames);
+  }
+  virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
+                                unsigned &NumAliases) const {
+    Aliases = GCCRegAliases;
+    NumAliases = llvm::array_lengthof(GCCRegAliases);
+  }
+  virtual bool validateAsmConstraint(const char *&Name,
+                                     TargetInfo::ConstraintInfo &info) const;
+  virtual std::string convertConstraint(const char Constraint) const;
+  virtual const char *getClobbers() const {
+    return "~{dirflag},~{fpsr},~{flags}";
+  }
+  virtual void getTargetDefines(const LangOptions &Opts,
+                                MacroBuilder &Builder) const;
+  virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
+                                 const std::string &Name,
+                                 bool Enabled) const;
+  virtual void getDefaultFeatures(const std::string &CPU,
+                                  llvm::StringMap<bool> &Features) const;
+  virtual void HandleTargetFeatures(std::vector<std::string> &Features);
+};
+
+void X86TargetInfo::getDefaultFeatures(const std::string &CPU,
+                                       llvm::StringMap<bool> &Features) const {
+  // FIXME: This should not be here.
+  Features["3dnow"] = false;
+  Features["3dnowa"] = false;
+  Features["mmx"] = false;
+  Features["sse"] = false;
+  Features["sse2"] = false;
+  Features["sse3"] = false;
+  Features["ssse3"] = false;
+  Features["sse41"] = false;
+  Features["sse42"] = false;
+  Features["aes"] = false;
+
+  // LLVM does not currently recognize this.
+  // Features["sse4a"] = false;
+
+  // FIXME: This *really* should not be here.
+
+  // X86_64 always has SSE2.
+  if (PointerWidth == 64)
+    Features["sse2"] = Features["sse"] = Features["mmx"] = true;
+
+  if (CPU == "generic" || CPU == "i386" || CPU == "i486" || CPU == "i586" ||
+      CPU == "pentium" || CPU == "i686" || CPU == "pentiumpro")
+    ;
+  else if (CPU == "pentium-mmx" || CPU == "pentium2")
+    setFeatureEnabled(Features, "mmx", true);
+  else if (CPU == "pentium3")
+    setFeatureEnabled(Features, "sse", true);
+  else if (CPU == "pentium-m" || CPU == "pentium4" || CPU == "x86-64")
+    setFeatureEnabled(Features, "sse2", true);
+  else if (CPU == "yonah" || CPU == "prescott" || CPU == "nocona")
+    setFeatureEnabled(Features, "sse3", true);
+  else if (CPU == "core2")
+    setFeatureEnabled(Features, "ssse3", true);
+  else if (CPU == "penryn") {
+    setFeatureEnabled(Features, "sse4", true);
+    Features["sse42"] = false;
+  } else if (CPU == "atom")
+    setFeatureEnabled(Features, "sse3", true);
+  else if (CPU == "corei7") {
+    setFeatureEnabled(Features, "sse4", true);
+    setFeatureEnabled(Features, "aes", true);
+  }
+  else if (CPU == "k6" || CPU == "winchip-c6")
+    setFeatureEnabled(Features, "mmx", true);
+  else if (CPU == "k6-2" || CPU == "k6-3" || CPU == "athlon" ||
+           CPU == "athlon-tbird" || CPU == "winchip2" || CPU == "c3") {
+    setFeatureEnabled(Features, "mmx", true);
+    setFeatureEnabled(Features, "3dnow", true);
+  } else if (CPU == "athlon-4" || CPU == "athlon-xp" || CPU == "athlon-mp") {
+    setFeatureEnabled(Features, "sse", true);
+    setFeatureEnabled(Features, "3dnowa", true);
+  } else if (CPU == "k8" || CPU == "opteron" || CPU == "athlon64" ||
+           CPU == "athlon-fx") {
+    setFeatureEnabled(Features, "sse2", true);
+    setFeatureEnabled(Features, "3dnowa", true);
+  } else if (CPU == "c3-2")
+    setFeatureEnabled(Features, "sse", true);
+}
+
+bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
+                                      const std::string &Name,
+                                      bool Enabled) const {
+  // FIXME: This *really* should not be here.  We need some way of translating
+  // options into llvm subtarget features.
+  if (!Features.count(Name) &&
+      (Name != "sse4" && Name != "sse4.2" && Name != "sse4.1"))
+    return false;
+
+  if (Enabled) {
+    if (Name == "mmx")
+      Features["mmx"] = true;
+    else if (Name == "sse")
+      Features["mmx"] = Features["sse"] = true;
+    else if (Name == "sse2")
+      Features["mmx"] = Features["sse"] = Features["sse2"] = true;
+    else if (Name == "sse3")
+      Features["mmx"] = Features["sse"] = Features["sse2"] =
+        Features["sse3"] = true;
+    else if (Name == "ssse3")
+      Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
+        Features["ssse3"] = true;
+    else if (Name == "sse4" || Name == "sse4.2")
+      Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
+        Features["ssse3"] = Features["sse41"] = Features["sse42"] = true;
+    else if (Name == "sse4.1")
+      Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
+        Features["ssse3"] = Features["sse41"] = true;
+    else if (Name == "3dnow")
+      Features["3dnowa"] = true;
+    else if (Name == "3dnowa")
+      Features["3dnow"] = Features["3dnowa"] = true;
+    else if (Name == "aes")
+      Features["aes"] = true;
+  } else {
+    if (Name == "mmx")
+      Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
+        Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
+    else if (Name == "sse")
+      Features["sse"] = Features["sse2"] = Features["sse3"] =
+        Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
+    else if (Name == "sse2")
+      Features["sse2"] = Features["sse3"] = Features["ssse3"] =
+        Features["sse41"] = Features["sse42"] = false;
+    else if (Name == "sse3")
+      Features["sse3"] = Features["ssse3"] = Features["sse41"] =
+        Features["sse42"] = false;
+    else if (Name == "ssse3")
+      Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
+    else if (Name == "sse4")
+      Features["sse41"] = Features["sse42"] = false;
+    else if (Name == "sse4.2")
+      Features["sse42"] = false;
+    else if (Name == "sse4.1")
+      Features["sse41"] = Features["sse42"] = false;
+    else if (Name == "3dnow")
+      Features["3dnow"] = Features["3dnowa"] = false;
+    else if (Name == "3dnowa")
+      Features["3dnowa"] = false;
+    else if (Name == "aes")
+      Features["aes"] = false;
+  }
+
+  return true;
+}
+
+/// HandleTargetOptions - Perform initialization based on the user
+/// configured set of features.
+void X86TargetInfo::HandleTargetFeatures(std::vector<std::string> &Features) {
+  // Remember the maximum enabled sselevel.
+  for (unsigned i = 0, e = Features.size(); i !=e; ++i) {
+    // Ignore disabled features.
+    if (Features[i][0] == '-')
+      continue;
+
+    if (Features[i].substr(1) == "aes") {
+      HasAES = true;
+      continue;
+    }
+
+    assert(Features[i][0] == '+' && "Invalid target feature!");
+    X86SSEEnum Level = llvm::StringSwitch<X86SSEEnum>(Features[i].substr(1))
+      .Case("sse42", SSE42)
+      .Case("sse41", SSE41)
+      .Case("ssse3", SSSE3)
+      .Case("sse3", SSE3)
+      .Case("sse2", SSE2)
+      .Case("sse", SSE1)
+      .Case("mmx", MMX)
+      .Default(NoMMXSSE);
+    SSELevel = std::max(SSELevel, Level);
+    
+    AMD3DNowEnum ThreeDNowLevel = 
+      llvm::StringSwitch<AMD3DNowEnum>(Features[i].substr(1))
+        .Case("3dnowa", AMD3DNowAthlon)
+        .Case("3dnow", AMD3DNow)
+        .Default(NoAMD3DNow);
+    
+    AMD3DNowLevel = std::max(AMD3DNowLevel, ThreeDNowLevel);
+  }
+}
+
+/// X86TargetInfo::getTargetDefines - Return a set of the X86-specific #defines
+/// that are not tied to a specific subtarget.
+void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
+                                     MacroBuilder &Builder) const {
+  // Target identification.
+  if (PointerWidth == 64) {
+    Builder.defineMacro("_LP64");
+    Builder.defineMacro("__LP64__");
+    Builder.defineMacro("__amd64__");
+    Builder.defineMacro("__amd64");
+    Builder.defineMacro("__x86_64");
+    Builder.defineMacro("__x86_64__");
+  } else {
+    DefineStd(Builder, "i386", Opts);
+  }
+
+  if (HasAES)
+    Builder.defineMacro("__AES__");
+
+  // Target properties.
+  Builder.defineMacro("__LITTLE_ENDIAN__");
+
+  // Subtarget options.
+  Builder.defineMacro("__nocona");
+  Builder.defineMacro("__nocona__");
+  Builder.defineMacro("__tune_nocona__");
+  Builder.defineMacro("__REGISTER_PREFIX__", "");
+
+  // Define __NO_MATH_INLINES on linux/x86 so that we don't get inline
+  // functions in glibc header files that use FP Stack inline asm which the
+  // backend can't deal with (PR879).
+  Builder.defineMacro("__NO_MATH_INLINES");
+
+  // Each case falls through to the previous one here.
+  switch (SSELevel) {
+  case SSE42:
+    Builder.defineMacro("__SSE4_2__");
+  case SSE41:
+    Builder.defineMacro("__SSE4_1__");
+  case SSSE3:
+    Builder.defineMacro("__SSSE3__");
+  case SSE3:
+    Builder.defineMacro("__SSE3__");
+  case SSE2:
+    Builder.defineMacro("__SSE2__");
+    Builder.defineMacro("__SSE2_MATH__");  // -mfp-math=sse always implied.
+  case SSE1:
+    Builder.defineMacro("__SSE__");
+    Builder.defineMacro("__SSE_MATH__");   // -mfp-math=sse always implied.
+  case MMX:
+    Builder.defineMacro("__MMX__");
+  case NoMMXSSE:
+    break;
+  }
+  
+  // Each case falls through to the previous one here.
+  switch (AMD3DNowLevel) {
+  case AMD3DNowAthlon:
+    Builder.defineMacro("__3dNOW_A__");
+  case AMD3DNow:
+    Builder.defineMacro("__3dNOW__");
+  case NoAMD3DNow:
+    break;
+  }
+}
+
+
+bool
+X86TargetInfo::validateAsmConstraint(const char *&Name,
+                                     TargetInfo::ConstraintInfo &Info) const {
+  switch (*Name) {
+  default: return false;
+  case 'a': // eax.
+  case 'b': // ebx.
+  case 'c': // ecx.
+  case 'd': // edx.
+  case 'S': // esi.
+  case 'D': // edi.
+  case 'A': // edx:eax.
+  case 't': // top of floating point stack.
+  case 'u': // second from top of floating point stack.
+  case 'q': // Any register accessible as [r]l: a, b, c, and d.
+  case 'y': // Any MMX register.
+  case 'x': // Any SSE register.
+  case 'Q': // Any register accessible as [r]h: a, b, c, and d.
+  case 'e': // 32-bit signed integer constant for use with zero-extending
+            // x86_64 instructions.
+  case 'Z': // 32-bit unsigned integer constant for use with zero-extending
+            // x86_64 instructions.
+  case 'N': // unsigned 8-bit integer constant for use with in and out
+            // instructions.
+  case 'R': // "legacy" registers: ax, bx, cx, dx, di, si, sp, bp.
+    Info.setAllowsRegister();
+    return true;
+  }
+}
+
+std::string
+X86TargetInfo::convertConstraint(const char Constraint) const {
+  switch (Constraint) {
+  case 'a': return std::string("{ax}");
+  case 'b': return std::string("{bx}");
+  case 'c': return std::string("{cx}");
+  case 'd': return std::string("{dx}");
+  case 'S': return std::string("{si}");
+  case 'D': return std::string("{di}");
+  case 't': // top of floating point stack.
+    return std::string("{st}");
+  case 'u': // second from top of floating point stack.
+    return std::string("{st(1)}"); // second from top of floating point stack.
+  default:
+    return std::string(1, Constraint);
+  }
+}
+} // end anonymous namespace
+
+namespace {
+// X86-32 generic target
+class X86_32TargetInfo : public X86TargetInfo {
+public:
+  X86_32TargetInfo(const std::string& triple) : X86TargetInfo(triple) {
+    DoubleAlign = LongLongAlign = 32;
+    LongDoubleWidth = 96;
+    LongDoubleAlign = 32;
+    DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
+                        "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
+                        "a0:0:64-f80:32:32-n8:16:32";
+    SizeType = UnsignedInt;
+    PtrDiffType = SignedInt;
+    IntPtrType = SignedInt;
+    RegParmMax = 3;
+  }
+  virtual const char *getVAListDeclaration() const {
+    return "typedef char* __builtin_va_list;";
+  }
+  
+  int getEHDataRegisterNumber(unsigned RegNo) const {
+    if (RegNo == 0) return 0;
+    if (RegNo == 1) return 2;
+    return -1;
+  }
+};
+} // end anonymous namespace
+
+namespace {
+class OpenBSDI386TargetInfo : public OpenBSDTargetInfo<X86_32TargetInfo> {
+public:
+  OpenBSDI386TargetInfo(const std::string& triple) :
+    OpenBSDTargetInfo<X86_32TargetInfo>(triple) {
+    SizeType = UnsignedLong;
+    IntPtrType = SignedLong;
+    PtrDiffType = SignedLong;
+  }
+};
+} // end anonymous namespace
+
+namespace {
+class DarwinI386TargetInfo : public DarwinTargetInfo<X86_32TargetInfo> {
+public:
+  DarwinI386TargetInfo(const std::string& triple) :
+    DarwinTargetInfo<X86_32TargetInfo>(triple) {
+    LongDoubleWidth = 128;
+    LongDoubleAlign = 128;
+    SizeType = UnsignedLong;
+    IntPtrType = SignedLong;
+    DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
+                        "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
+                        "a0:0:64-f80:128:128-n8:16:32";
+  }
+
+};
+} // end anonymous namespace
+
+namespace {
+// x86-32 Windows target
+class WindowsX86_32TargetInfo : public X86_32TargetInfo {
+public:
+  WindowsX86_32TargetInfo(const std::string& triple)
+    : X86_32TargetInfo(triple) {
+    TLSSupported = false;
+    WCharType = UnsignedShort;
+    DoubleAlign = LongLongAlign = 64;
+    DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
+                        "i64:64:64-f32:32:32-f64:64:64-f80:128:128-v64:64:64-"
+                        "v128:128:128-a0:0:64-f80:32:32-n8:16:32";
+  }
+  virtual void getTargetDefines(const LangOptions &Opts,
+                                MacroBuilder &Builder) const {
+    X86_32TargetInfo::getTargetDefines(Opts, Builder);
+    // This list is based off of the the list of things MingW defines
+    Builder.defineMacro("_WIN32");
+    DefineStd(Builder, "WIN32", Opts);
+    DefineStd(Builder, "WINNT", Opts);
+    Builder.defineMacro("_X86_");
+  }
+};
+} // end anonymous namespace
+
+namespace {
+
+// x86-32 Windows Visual Studio target
+class VisualStudioWindowsX86_32TargetInfo : public WindowsX86_32TargetInfo {
+public:
+  VisualStudioWindowsX86_32TargetInfo(const std::string& triple)
+    : WindowsX86_32TargetInfo(triple) {
+  }
+  virtual void getTargetDefines(const LangOptions &Opts,
+                                MacroBuilder &Builder) const {
+    WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder);
+    // The value of the following reflects processor type.
+    // 300=386, 400=486, 500=Pentium, 600=Blend (default)
+    // We lost the original triple, so we use the default.
+    Builder.defineMacro("_M_IX86", "600");
+  }
+};
+} // end anonymous namespace
+
+namespace {
+// x86-32 MinGW target
+class MinGWX86_32TargetInfo : public WindowsX86_32TargetInfo {
+public:
+  MinGWX86_32TargetInfo(const std::string& triple)
+    : WindowsX86_32TargetInfo(triple) {
+  }
+  virtual void getTargetDefines(const LangOptions &Opts,
+                                MacroBuilder &Builder) const {
+    WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder);
+    Builder.defineMacro("__MSVCRT__");
+    Builder.defineMacro("__MINGW32__");
+    Builder.defineMacro("__declspec", "__declspec");
+  }
+};
+} // end anonymous namespace
+
+namespace {
+// x86-32 Cygwin target
+class CygwinX86_32TargetInfo : public X86_32TargetInfo {
+public:
+  CygwinX86_32TargetInfo(const std::string& triple)
+    : X86_32TargetInfo(triple) {
+    TLSSupported = false;
+    WCharType = UnsignedShort;
+    DoubleAlign = LongLongAlign = 64;
+    DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
+                        "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
+                        "a0:0:64-f80:32:32-n8:16:32";
+  }
+  virtual void getTargetDefines(const LangOptions &Opts,
+                                MacroBuilder &Builder) const {
+    X86_32TargetInfo::getTargetDefines(Opts, Builder);
+    Builder.defineMacro("__CYGWIN__");
+    Builder.defineMacro("__CYGWIN32__");
+    DefineStd(Builder, "unix", Opts);
+    if (Opts.CPlusPlus)
+      Builder.defineMacro("_GNU_SOURCE");
+  }
+};
+} // end anonymous namespace
+
+namespace {
+// x86-32 Haiku target
+class HaikuX86_32TargetInfo : public X86_32TargetInfo {
+public:
+  HaikuX86_32TargetInfo(const std::string& triple)
+    : X86_32TargetInfo(triple) {
+    SizeType = UnsignedLong;
+    IntPtrType = SignedLong;
+    PtrDiffType = SignedLong;
+  }                                       	
+  virtual void getTargetDefines(const LangOptions &Opts,
+                                MacroBuilder &Builder) const {
+    X86_32TargetInfo::getTargetDefines(Opts, Builder);
+    Builder.defineMacro("__INTEL__");
+    Builder.defineMacro("__HAIKU__");
+  }
+};
+} // end anonymous namespace
+
+namespace {
+// x86-64 generic target
+class X86_64TargetInfo : public X86TargetInfo {
+public:
+  X86_64TargetInfo(const std::string &triple) : X86TargetInfo(triple) {
+    LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
+    LongDoubleWidth = 128;
+    LongDoubleAlign = 128;
+    IntMaxType = SignedLong;
+    UIntMaxType = UnsignedLong;
+    Int64Type = SignedLong;
+    RegParmMax = 6;
+
+    DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
+                        "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
+                        "a0:0:64-s0:64:64-f80:128:128-n8:16:32:64";
+  }
+  virtual const char *getVAListDeclaration() const {
+    return "typedef struct __va_list_tag {"
+           "  unsigned gp_offset;"
+           "  unsigned fp_offset;"
+           "  void* overflow_arg_area;"
+           "  void* reg_save_area;"
+           "} __va_list_tag;"
+           "typedef __va_list_tag __builtin_va_list[1];";
+  }
+  
+  int getEHDataRegisterNumber(unsigned RegNo) const {
+    if (RegNo == 0) return 0;
+    if (RegNo == 1) return 1;
+    return -1;
+  }
+};
+} // end anonymous namespace
+
+namespace {
+// x86-64 Windows target
+class WindowsX86_64TargetInfo : public X86_64TargetInfo {
+public:
+  WindowsX86_64TargetInfo(const std::string& triple)
+    : X86_64TargetInfo(triple) {
+    TLSSupported = false;
+    WCharType = UnsignedShort;
+    LongWidth = LongAlign = 32;
+    DoubleAlign = LongLongAlign = 64;
+  }
+  virtual void getTargetDefines(const LangOptions &Opts,
+                                MacroBuilder &Builder) const {
+    X86_64TargetInfo::getTargetDefines(Opts, Builder);
+    Builder.defineMacro("_WIN64");
+    DefineStd(Builder, "WIN64", Opts);
+  }
+};
+} // end anonymous namespace
+
+namespace {
+// x86-64 Windows Visual Studio target
+class VisualStudioWindowsX86_64TargetInfo : public WindowsX86_64TargetInfo {
+public:
+  VisualStudioWindowsX86_64TargetInfo(const std::string& triple)
+    : WindowsX86_64TargetInfo(triple) {
+  }
+  virtual void getTargetDefines(const LangOptions &Opts,
+                                MacroBuilder &Builder) const {
+    WindowsX86_64TargetInfo::getTargetDefines(Opts, Builder);
+    Builder.defineMacro("_M_X64");
+  }
+  virtual const char *getVAListDeclaration() const {
+    return "typedef char* va_list;";
+  }
+};
+} // end anonymous namespace
+
+namespace {
+// x86-64 MinGW target
+class MinGWX86_64TargetInfo : public WindowsX86_64TargetInfo {
+public:
+  MinGWX86_64TargetInfo(const std::string& triple)
+    : WindowsX86_64TargetInfo(triple) {
+  }
+  virtual void getTargetDefines(const LangOptions &Opts,
+                                MacroBuilder &Builder) const {
+    WindowsX86_64TargetInfo::getTargetDefines(Opts, Builder);
+    Builder.defineMacro("__MSVCRT__");
+    Builder.defineMacro("__MINGW64__");
+    Builder.defineMacro("__declspec");
+  }
+};
+} // end anonymous namespace
+
+namespace {
+class DarwinX86_64TargetInfo : public DarwinTargetInfo<X86_64TargetInfo> {
+public:
+  DarwinX86_64TargetInfo(const std::string& triple)
+      : DarwinTargetInfo<X86_64TargetInfo>(triple) {
+    Int64Type = SignedLongLong;
+  }
+};
+} // end anonymous namespace
+
+namespace {
+class OpenBSDX86_64TargetInfo : public OpenBSDTargetInfo<X86_64TargetInfo> {
+public:
+  OpenBSDX86_64TargetInfo(const std::string& triple)
+      : OpenBSDTargetInfo<X86_64TargetInfo>(triple) {
+    IntMaxType = SignedLongLong;
+    UIntMaxType = UnsignedLongLong;
+    Int64Type = SignedLongLong;
+  }
+};
+} // end anonymous namespace
+
+namespace {
+class ARMTargetInfo : public TargetInfo {
+  // Possible FPU choices.
+  enum FPUMode {
+    NoFPU,
+    VFP2FPU,
+    VFP3FPU,
+    NeonFPU
+  };
+
+  static bool FPUModeIsVFP(FPUMode Mode) {
+    return Mode >= VFP2FPU && Mode <= NeonFPU;
+  }
+
+  static const TargetInfo::GCCRegAlias GCCRegAliases[];
+  static const char * const GCCRegNames[];
+
+  std::string ABI, CPU;
+
+  unsigned FPU : 3;
+
+  unsigned IsThumb : 1;
+
+  // Initialized via features.
+  unsigned SoftFloat : 1;
+  unsigned SoftFloatABI : 1;
+
+  static const Builtin::Info BuiltinInfo[];
+
+public:
+  ARMTargetInfo(const std::string &TripleStr)
+    : TargetInfo(TripleStr), ABI("aapcs-linux"), CPU("arm1136j-s")
+  {
+    SizeType = UnsignedInt;
+    PtrDiffType = SignedInt;
+
+    // {} in inline assembly are neon specifiers, not assembly variant
+    // specifiers.
+    NoAsmVariants = true;
+    
+    // FIXME: Should we just treat this as a feature?
+    IsThumb = getTriple().getArchName().startswith("thumb");
+    if (IsThumb) {
+      DescriptionString = ("e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-"
+                           "i64:64:64-f32:32:32-f64:64:64-"
+                           "v64:64:64-v128:128:128-a0:0:32-n32");
+    } else {
+      DescriptionString = ("e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
+                           "i64:64:64-f32:32:32-f64:64:64-"
+                           "v64:64:64-v128:128:128-a0:0:64-n32");
+    }
+  }
+  virtual const char *getABI() const { return ABI.c_str(); }
+  virtual bool setABI(const std::string &Name) {
+    ABI = Name;
+
+    // The defaults (above) are for AAPCS, check if we need to change them.
+    //
+    // FIXME: We need support for -meabi... we could just mangle it into the
+    // name.
+    if (Name == "apcs-gnu") {
+      DoubleAlign = LongLongAlign = LongDoubleAlign = 32;
+      SizeType = UnsignedLong;
+
+      // Do not respect the alignment of bit-field types when laying out
+      // structures. This corresponds to PCC_BITFIELD_TYPE_MATTERS in gcc.
+      UseBitFieldTypeAlignment = false;
+
+      if (IsThumb) {
+        DescriptionString = ("e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-"
+                             "i64:32:32-f32:32:32-f64:32:32-"
+                             "v64:64:64-v128:128:128-a0:0:32-n32");
+      } else {
+        DescriptionString = ("e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
+                             "i64:32:32-f32:32:32-f64:32:32-"
+                             "v64:64:64-v128:128:128-a0:0:64-n32");
+      }
+
+      // FIXME: Override "preferred align" for double and long long.
+    } else if (Name == "aapcs") {
+      // FIXME: Enumerated types are variable width in straight AAPCS.
+    } else if (Name == "aapcs-linux") {
+      ;
+    } else
+      return false;
+
+    return true;
+  }
+
+  void getDefaultFeatures(const std::string &CPU,
+                          llvm::StringMap<bool> &Features) const {
+    // FIXME: This should not be here.
+    Features["vfp2"] = false;
+    Features["vfp3"] = false;
+    Features["neon"] = false;
+
+    if (CPU == "arm1136jf-s" || CPU == "arm1176jzf-s" || CPU == "mpcore")
+      Features["vfp2"] = true;
+    else if (CPU == "cortex-a8" || CPU == "cortex-a9")
+      Features["neon"] = true;
+  }
+  
+  virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
+                                 const std::string &Name,
+                                 bool Enabled) const {
+    if (Name == "soft-float" || Name == "soft-float-abi") {
+      Features[Name] = Enabled;
+    } else if (Name == "vfp2" || Name == "vfp3" || Name == "neon") {
+      // These effectively are a single option, reset them when any is enabled.
+      if (Enabled)
+        Features["vfp2"] = Features["vfp3"] = Features["neon"] = false;
+      Features[Name] = Enabled;
+    } else
+      return false;
+
+    return true;
+  }
+
+  virtual void HandleTargetFeatures(std::vector<std::string> &Features) {
+    FPU = NoFPU;
+    SoftFloat = SoftFloatABI = false;
+    for (unsigned i = 0, e = Features.size(); i != e; ++i) {
+      if (Features[i] == "+soft-float")
+        SoftFloat = true;
+      else if (Features[i] == "+soft-float-abi")
+        SoftFloatABI = true;
+      else if (Features[i] == "+vfp2")
+        FPU = VFP2FPU;
+      else if (Features[i] == "+vfp3")
+        FPU = VFP3FPU;
+      else if (Features[i] == "+neon")
+        FPU = NeonFPU;
+    }
+
+    // Remove front-end specific options which the backend handles differently.
+    std::vector<std::string>::iterator it;
+    it = std::find(Features.begin(), Features.end(), "+soft-float");
+    if (it != Features.end())
+      Features.erase(it);
+    it = std::find(Features.begin(), Features.end(), "+soft-float-abi");
+    if (it != Features.end())
+      Features.erase(it);
+  }
+
+  static const char *getCPUDefineSuffix(llvm::StringRef Name) {
+    return llvm::StringSwitch<const char*>(Name)
+      .Cases("arm8", "arm810", "4")
+      .Cases("strongarm", "strongarm110", "strongarm1100", "strongarm1110", "4")
+      .Cases("arm7tdmi", "arm7tdmi-s", "arm710t", "arm720t", "arm9", "4T")
+      .Cases("arm9tdmi", "arm920", "arm920t", "arm922t", "arm940t", "4T")
+      .Case("ep9312", "4T")
+      .Cases("arm10tdmi", "arm1020t", "5T")
+      .Cases("arm9e", "arm946e-s", "arm966e-s", "arm968e-s", "5TE")
+      .Case("arm926ej-s", "5TEJ")
+      .Cases("arm10e", "arm1020e", "arm1022e", "5TE")
+      .Cases("xscale", "iwmmxt", "5TE")
+      .Case("arm1136j-s", "6J")
+      .Cases("arm1176jz-s", "arm1176jzf-s", "6ZK")
+      .Cases("arm1136jf-s", "mpcorenovfp", "mpcore", "6K")
+      .Cases("arm1156t2-s", "arm1156t2f-s", "6T2")
+      .Cases("cortex-a8", "cortex-a9", "7A")
+      .Default(0);
+  }
+  virtual bool setCPU(const std::string &Name) {
+    if (!getCPUDefineSuffix(Name))
+      return false;
+
+    CPU = Name;
+    return true;
+  }
+  virtual void getTargetDefines(const LangOptions &Opts,
+                                MacroBuilder &Builder) const {
+    // Target identification.
+    Builder.defineMacro("__arm");
+    Builder.defineMacro("__arm__");
+
+    // Target properties.
+    Builder.defineMacro("__ARMEL__");
+    Builder.defineMacro("__LITTLE_ENDIAN__");
+    Builder.defineMacro("__REGISTER_PREFIX__", "");
+
+    llvm::StringRef CPUArch = getCPUDefineSuffix(CPU);
+    Builder.defineMacro("__ARM_ARCH_" + CPUArch + "__");
+
+    // Subtarget options.
+
+    // FIXME: It's more complicated than this and we don't really support
+    // interworking.
+    if ('5' <= CPUArch[0] && CPUArch[0] <= '7')
+      Builder.defineMacro("__THUMB_INTERWORK__");
+
+    if (ABI == "aapcs" || ABI == "aapcs-linux")
+      Builder.defineMacro("__ARM_EABI__");
+
+    if (SoftFloat)
+      Builder.defineMacro("__SOFTFP__");
+
+    if (CPU == "xscale")
+      Builder.defineMacro("__XSCALE__");
+
+    bool IsThumb2 = IsThumb && (CPUArch == "6T2" || CPUArch.startswith("7"));
+    if (IsThumb) {
+      Builder.defineMacro("__THUMBEL__");
+      Builder.defineMacro("__thumb__");
+      if (IsThumb2)
+        Builder.defineMacro("__thumb2__");
+    }
+
+    // Note, this is always on in gcc, even though it doesn't make sense.
+    Builder.defineMacro("__APCS_32__");
+
+    if (FPUModeIsVFP((FPUMode) FPU))
+      Builder.defineMacro("__VFP_FP__");
+
+    // This only gets set when Neon instructions are actually available, unlike
+    // the VFP define, hence the soft float and arch check. This is subtly
+    // different from gcc, we follow the intent which was that it should be set
+    // when Neon instructions are actually available.
+    if (FPU == NeonFPU && !SoftFloat && IsThumb2)
+      Builder.defineMacro("__ARM_NEON__");
+  }
+  virtual void getTargetBuiltins(const Builtin::Info *&Records,
+                                 unsigned &NumRecords) const {
+    Records = BuiltinInfo;
+    NumRecords = clang::ARM::LastTSBuiltin-Builtin::FirstTSBuiltin;
+  }
+  virtual const char *getVAListDeclaration() const {
+    return "typedef char* __builtin_va_list;";
+  }
+  virtual void getGCCRegNames(const char * const *&Names,
+                              unsigned &NumNames) const;
+  virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
+                                unsigned &NumAliases) const;
+  virtual bool validateAsmConstraint(const char *&Name,
+                                     TargetInfo::ConstraintInfo &Info) const {
+    // FIXME: Check if this is complete
+    switch (*Name) {
+    default:
+    case 'l': // r0-r7
+    case 'h': // r8-r15
+    case 'w': // VFP Floating point register single precision
+    case 'P': // VFP Floating point register double precision
+      Info.setAllowsRegister();
+      return true;
+    }
+    return false;
+  }
+  virtual const char *getClobbers() const {
+    // FIXME: Is this really right?
+    return "";
+  }
+};
+
+const char * const ARMTargetInfo::GCCRegNames[] = {
+  "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+  "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
+};
+
+void ARMTargetInfo::getGCCRegNames(const char * const *&Names,
+                                       unsigned &NumNames) const {
+  Names = GCCRegNames;
+  NumNames = llvm::array_lengthof(GCCRegNames);
+}
+
+const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = {
+
+  { { "a1" }, "r0" },
+  { { "a2" }, "r1" },
+  { { "a3" }, "r2" },
+  { { "a4" }, "r3" },
+  { { "v1" }, "r4" },
+  { { "v2" }, "r5" },
+  { { "v3" }, "r6" },
+  { { "v4" }, "r7" },
+  { { "v5" }, "r8" },
+  { { "v6", "rfp" }, "r9" },
+  { { "sl" }, "r10" },
+  { { "fp" }, "r11" },
+  { { "ip" }, "r12" },
+  { { "sp" }, "r13" },
+  { { "lr" }, "r14" },
+  { { "pc" }, "r15" },
+};
+
+void ARMTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
+                                       unsigned &NumAliases) const {
+  Aliases = GCCRegAliases;
+  NumAliases = llvm::array_lengthof(GCCRegAliases);
+}
+
+const Builtin::Info ARMTargetInfo::BuiltinInfo[] = {
+#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, false },
+#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER, false },
+#include "clang/Basic/BuiltinsARM.def"
+};
+} // end anonymous namespace.
+
+
+namespace {
+class DarwinARMTargetInfo :
+  public DarwinTargetInfo<ARMTargetInfo> {
+protected:
+  virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
+                            MacroBuilder &Builder) const {
+    getDarwinDefines(Builder, Opts, Triple);
+  }
+
+public:
+  DarwinARMTargetInfo(const std::string& triple)
+    : DarwinTargetInfo<ARMTargetInfo>(triple) {}
+};
+} // end anonymous namespace.
+
+namespace {
+class SparcV8TargetInfo : public TargetInfo {
+  static const TargetInfo::GCCRegAlias GCCRegAliases[];
+  static const char * const GCCRegNames[];
+public:
+  SparcV8TargetInfo(const std::string& triple) : TargetInfo(triple) {
+    // FIXME: Support Sparc quad-precision long double?
+    DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
+                        "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32";
+  }
+  virtual void getTargetDefines(const LangOptions &Opts,
+                                MacroBuilder &Builder) const {
+    DefineStd(Builder, "sparc", Opts);
+    Builder.defineMacro("__sparcv8");
+    Builder.defineMacro("__REGISTER_PREFIX__", "");
+  }
+  virtual void getTargetBuiltins(const Builtin::Info *&Records,
+                                 unsigned &NumRecords) const {
+    // FIXME: Implement!
+  }
+  virtual const char *getVAListDeclaration() const {
+    return "typedef void* __builtin_va_list;";
+  }
+  virtual void getGCCRegNames(const char * const *&Names,
+                              unsigned &NumNames) const;
+  virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
+                                unsigned &NumAliases) const;
+  virtual bool validateAsmConstraint(const char *&Name,
+                                     TargetInfo::ConstraintInfo &info) const {
+    // FIXME: Implement!
+    return false;
+  }
+  virtual const char *getClobbers() const {
+    // FIXME: Implement!
+    return "";
+  }
+};
+
+const char * const SparcV8TargetInfo::GCCRegNames[] = {
+  "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+  "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+  "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
+  "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31"
+};
+
+void SparcV8TargetInfo::getGCCRegNames(const char * const *&Names,
+                                       unsigned &NumNames) const {
+  Names = GCCRegNames;
+  NumNames = llvm::array_lengthof(GCCRegNames);
+}
+
+const TargetInfo::GCCRegAlias SparcV8TargetInfo::GCCRegAliases[] = {
+  { { "g0" }, "r0" },
+  { { "g1" }, "r1" },
+  { { "g2" }, "r2" },
+  { { "g3" }, "r3" },
+  { { "g4" }, "r4" },
+  { { "g5" }, "r5" },
+  { { "g6" }, "r6" },
+  { { "g7" }, "r7" },
+  { { "o0" }, "r8" },
+  { { "o1" }, "r9" },
+  { { "o2" }, "r10" },
+  { { "o3" }, "r11" },
+  { { "o4" }, "r12" },
+  { { "o5" }, "r13" },
+  { { "o6", "sp" }, "r14" },
+  { { "o7" }, "r15" },
+  { { "l0" }, "r16" },
+  { { "l1" }, "r17" },
+  { { "l2" }, "r18" },
+  { { "l3" }, "r19" },
+  { { "l4" }, "r20" },
+  { { "l5" }, "r21" },
+  { { "l6" }, "r22" },
+  { { "l7" }, "r23" },
+  { { "i0" }, "r24" },
+  { { "i1" }, "r25" },
+  { { "i2" }, "r26" },
+  { { "i3" }, "r27" },
+  { { "i4" }, "r28" },
+  { { "i5" }, "r29" },
+  { { "i6", "fp" }, "r30" },
+  { { "i7" }, "r31" },
+};
+
+void SparcV8TargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
+                                         unsigned &NumAliases) const {
+  Aliases = GCCRegAliases;
+  NumAliases = llvm::array_lengthof(GCCRegAliases);
+}
+} // end anonymous namespace.
+
+namespace {
+class AuroraUXSparcV8TargetInfo : public AuroraUXTargetInfo<SparcV8TargetInfo> {
+public:
+  AuroraUXSparcV8TargetInfo(const std::string& triple) :
+      AuroraUXTargetInfo<SparcV8TargetInfo>(triple) {
+    SizeType = UnsignedInt;
+    PtrDiffType = SignedInt;
+  }
+};
+class SolarisSparcV8TargetInfo : public SolarisTargetInfo<SparcV8TargetInfo> {
+public:
+  SolarisSparcV8TargetInfo(const std::string& triple) :
+      SolarisTargetInfo<SparcV8TargetInfo>(triple) {
+    SizeType = UnsignedInt;
+    PtrDiffType = SignedInt;
+  }
+};
+} // end anonymous namespace.
+
+namespace {
+  class PIC16TargetInfo : public TargetInfo{
+  public:
+    PIC16TargetInfo(const std::string& triple) : TargetInfo(triple) {
+      TLSSupported = false;
+      IntWidth = 16;
+      LongWidth = LongLongWidth = 32;
+      PointerWidth = 16;
+      IntAlign = 8;
+      LongAlign = LongLongAlign = 8;
+      PointerAlign = 8;
+      SizeType = UnsignedInt;
+      IntMaxType = SignedLong;
+      UIntMaxType = UnsignedLong;
+      IntPtrType = SignedShort;
+      PtrDiffType = SignedInt;
+      SigAtomicType = SignedLong;
+      FloatWidth = 32;
+      FloatAlign = 32;
+      DoubleWidth = 32;
+      DoubleAlign = 32;
+      LongDoubleWidth = 32;
+      LongDoubleAlign = 32;
+      FloatFormat = &llvm::APFloat::IEEEsingle;
+      DoubleFormat = &llvm::APFloat::IEEEsingle;
+      LongDoubleFormat = &llvm::APFloat::IEEEsingle;
+      DescriptionString = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8-f32:32:32-n8";
+
+    }
+    virtual uint64_t getPointerWidthV(unsigned AddrSpace) const { return 16; }
+    virtual uint64_t getPointerAlignV(unsigned AddrSpace) const { return 8; }
+    virtual void getTargetDefines(const LangOptions &Opts,
+                                MacroBuilder &Builder) const {
+      Builder.defineMacro("__pic16");
+      Builder.defineMacro("__PIC16");
+      Builder.defineMacro("rom", "__attribute__((address_space(1)))");
+      Builder.defineMacro("ram", "__attribute__((address_space(0)))");
+      Builder.defineMacro("__section(SectName)",
+             "__attribute__((section(SectName)))");
+      Builder.defineMacro("near",
+             "__attribute__((section(\"Address=NEAR\")))");
+      Builder.defineMacro("__address(Addr)",
+             "__attribute__((section(\"Address=\"#Addr)))");
+      Builder.defineMacro("__config(conf)", "asm(\"CONFIG \"#conf)");
+      Builder.defineMacro("__idlocs(value)", "asm(\"__IDLOCS \"#value)");
+      Builder.defineMacro("interrupt",
+             "__attribute__((section(\"interrupt=0x4\"))) \
+             __attribute__((used))");
+    }
+    virtual void getTargetBuiltins(const Builtin::Info *&Records,
+                                   unsigned &NumRecords) const {}
+    virtual const char *getVAListDeclaration() const {
+      return "typedef char* __builtin_va_list;";
+    }
+    virtual const char *getClobbers() const {
+      return "";
+    }
+    virtual void getGCCRegNames(const char * const *&Names,
+                                unsigned &NumNames) const {}
+    virtual bool validateAsmConstraint(const char *&Name,
+                                       TargetInfo::ConstraintInfo &info) const {
+      return true;
+    }
+    virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
+                                  unsigned &NumAliases) const {}
+    virtual bool useGlobalsForAutomaticVariables() const {return true;}
+  };
+}
+
+namespace {
+  class MSP430TargetInfo : public TargetInfo {
+    static const char * const GCCRegNames[];
+  public:
+    MSP430TargetInfo(const std::string& triple) : TargetInfo(triple) {
+      TLSSupported = false;
+      IntWidth = 16; IntAlign = 16;
+      LongWidth = 32; LongLongWidth = 64;
+      LongAlign = LongLongAlign = 16;
+      PointerWidth = 16; PointerAlign = 16;
+      SizeType = UnsignedInt;
+      IntMaxType = SignedLong;
+      UIntMaxType = UnsignedLong;
+      IntPtrType = SignedShort;
+      PtrDiffType = SignedInt;
+      SigAtomicType = SignedLong;
+      DescriptionString = "e-p:16:16:16-i8:8:8-i16:16:16-i32:16:32-n8:16";
+   }
+    virtual void getTargetDefines(const LangOptions &Opts,
+                                  MacroBuilder &Builder) const {
+      Builder.defineMacro("MSP430");
+      Builder.defineMacro("__MSP430__");
+      // FIXME: defines for different 'flavours' of MCU
+    }
+    virtual void getTargetBuiltins(const Builtin::Info *&Records,
+                                   unsigned &NumRecords) const {
+     // FIXME: Implement.
+      Records = 0;
+      NumRecords = 0;
+    }
+    virtual void getGCCRegNames(const char * const *&Names,
+                                unsigned &NumNames) const;
+    virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
+                                  unsigned &NumAliases) const {
+      // No aliases.
+      Aliases = 0;
+      NumAliases = 0;
+    }
+    virtual bool validateAsmConstraint(const char *&Name,
+                                       TargetInfo::ConstraintInfo &info) const {
+      // No target constraints for now.
+      return false;
+    }
+    virtual const char *getClobbers() const {
+      // FIXME: Is this really right?
+      return "";
+    }
+    virtual const char *getVAListDeclaration() const {
+      // FIXME: implement
+      return "typedef char* __builtin_va_list;";
+   }
+  };
+
+  const char * const MSP430TargetInfo::GCCRegNames[] = {
+    "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+    "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
+  };
+
+  void MSP430TargetInfo::getGCCRegNames(const char * const *&Names,
+                                        unsigned &NumNames) const {
+    Names = GCCRegNames;
+    NumNames = llvm::array_lengthof(GCCRegNames);
+  }
+}
+
+
+namespace {
+  class SystemZTargetInfo : public TargetInfo {
+    static const char * const GCCRegNames[];
+  public:
+    SystemZTargetInfo(const std::string& triple) : TargetInfo(triple) {
+      TLSSupported = false;
+      IntWidth = IntAlign = 32;
+      LongWidth = LongLongWidth = LongAlign = LongLongAlign = 64;
+      PointerWidth = PointerAlign = 64;
+      DescriptionString = "E-p:64:64:64-i8:8:16-i16:16:16-i32:32:32-"
+      "i64:64:64-f32:32:32-f64:64:64-f128:128:128-a0:16:16-n32:64";
+   }
+    virtual void getTargetDefines(const LangOptions &Opts,
+                                  MacroBuilder &Builder) const {
+      Builder.defineMacro("__s390__");
+      Builder.defineMacro("__s390x__");
+    }
+    virtual void getTargetBuiltins(const Builtin::Info *&Records,
+                                   unsigned &NumRecords) const {
+      // FIXME: Implement.
+      Records = 0;
+      NumRecords = 0;
+    }
+
+    virtual void getGCCRegNames(const char * const *&Names,
+                                unsigned &NumNames) const;
+    virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
+                                  unsigned &NumAliases) const {
+      // No aliases.
+      Aliases = 0;
+      NumAliases = 0;
+    }
+    virtual bool validateAsmConstraint(const char *&Name,
+                                       TargetInfo::ConstraintInfo &info) const {
+      // FIXME: implement
+      return true;
+    }
+    virtual const char *getClobbers() const {
+      // FIXME: Is this really right?
+      return "";
+    }
+    virtual const char *getVAListDeclaration() const {
+      // FIXME: implement
+      return "typedef char* __builtin_va_list;";
+   }
+  };
+
+  const char * const SystemZTargetInfo::GCCRegNames[] = {
+    "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+    "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
+  };
+
+  void SystemZTargetInfo::getGCCRegNames(const char * const *&Names,
+                                         unsigned &NumNames) const {
+    Names = GCCRegNames;
+    NumNames = llvm::array_lengthof(GCCRegNames);
+  }
+}
+
+namespace {
+  class BlackfinTargetInfo : public TargetInfo {
+    static const char * const GCCRegNames[];
+  public:
+    BlackfinTargetInfo(const std::string& triple) : TargetInfo(triple) {
+      TLSSupported = false;
+      DoubleAlign = 32;
+      LongLongAlign = 32;
+      LongDoubleAlign = 32;
+      DescriptionString = "e-p:32:32-i64:32-f64:32-n32";
+    }
+
+    virtual void getTargetDefines(const LangOptions &Opts,
+                                  MacroBuilder &Builder) const {
+      DefineStd(Builder, "bfin", Opts);
+      DefineStd(Builder, "BFIN", Opts);
+      Builder.defineMacro("__ADSPBLACKFIN__");
+      // FIXME: This one is really dependent on -mcpu
+      Builder.defineMacro("__ADSPLPBLACKFIN__");
+      // FIXME: Add cpu-dependent defines and __SILICON_REVISION__
+    }
+
+    virtual void getTargetBuiltins(const Builtin::Info *&Records,
+                                   unsigned &NumRecords) const {
+      // FIXME: Implement.
+      Records = 0;
+      NumRecords = 0;
+    }
+
+    virtual void getGCCRegNames(const char * const *&Names,
+                                unsigned &NumNames) const;
+
+    virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
+                                  unsigned &NumAliases) const {
+      // No aliases.
+      Aliases = 0;
+      NumAliases = 0;
+    }
+
+    virtual bool validateAsmConstraint(const char *&Name,
+                                       TargetInfo::ConstraintInfo &Info) const {
+      if (strchr("adzDWeABbvfcCtukxywZY", Name[0])) {
+        Info.setAllowsRegister();
+        return true;
+      }
+      return false;
+    }
+
+    virtual const char *getClobbers() const {
+      return "";
+    }
+
+    virtual const char *getVAListDeclaration() const {
+      return "typedef char* __builtin_va_list;";
+    }
+  };
+
+  const char * const BlackfinTargetInfo::GCCRegNames[] = {
+    "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+    "p0", "p1", "p2", "p3", "p4", "p5", "sp", "fp",
+    "i0", "i1", "i2", "i3", "b0", "b1", "b2", "b3",
+    "l0", "l1", "l2", "l3", "m0", "m1", "m2", "m3",
+    "a0", "a1", "cc",
+    "rets", "reti", "retx", "retn", "rete", "astat", "seqstat", "usp",
+    "argp", "lt0", "lt1", "lc0", "lc1", "lb0", "lb1"
+  };
+
+  void BlackfinTargetInfo::getGCCRegNames(const char * const *&Names,
+                                          unsigned &NumNames) const {
+    Names = GCCRegNames;
+    NumNames = llvm::array_lengthof(GCCRegNames);
+  }
+}
+
+namespace {
+
+  // LLVM and Clang cannot be used directly to output native binaries for
+  // target, but is used to compile C code to llvm bitcode with correct
+  // type and alignment information.
+  //
+  // TCE uses the llvm bitcode as input and uses it for generating customized
+  // target processor and program binary. TCE co-design environment is
+  // publicly available in http://tce.cs.tut.fi
+
+  class TCETargetInfo : public TargetInfo{
+  public:
+    TCETargetInfo(const std::string& triple) : TargetInfo(triple) {
+      TLSSupported = false;
+      IntWidth = 32;
+      LongWidth = LongLongWidth = 32;
+      PointerWidth = 32;
+      IntAlign = 32;
+      LongAlign = LongLongAlign = 32;
+      PointerAlign = 32;
+      SizeType = UnsignedInt;
+      IntMaxType = SignedLong;
+      UIntMaxType = UnsignedLong;
+      IntPtrType = SignedInt;
+      PtrDiffType = SignedInt;
+      FloatWidth = 32;
+      FloatAlign = 32;
+      DoubleWidth = 32;
+      DoubleAlign = 32;
+      LongDoubleWidth = 32;
+      LongDoubleAlign = 32;
+      FloatFormat = &llvm::APFloat::IEEEsingle;
+      DoubleFormat = &llvm::APFloat::IEEEsingle;
+      LongDoubleFormat = &llvm::APFloat::IEEEsingle;
+      DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:32-"
+                          "i16:16:32-i32:32:32-i64:32:32-"
+                          "f32:32:32-f64:64:64-v64:64:64-"
+                          "v128:128:128-a0:0:64-n32";
+    }
+
+    virtual void getTargetDefines(const LangOptions &Opts,
+                                  MacroBuilder &Builder) const {
+      DefineStd(Builder, "tce", Opts);
+      Builder.defineMacro("__TCE__");
+      Builder.defineMacro("__TCE_V1__");
+    }
+    virtual void getTargetBuiltins(const Builtin::Info *&Records,
+                                   unsigned &NumRecords) const {}
+    virtual const char *getClobbers() const {
+      return "";
+    }
+    virtual const char *getVAListDeclaration() const {
+      return "typedef void* __builtin_va_list;";
+    }
+    virtual void getGCCRegNames(const char * const *&Names,
+                                unsigned &NumNames) const {}
+    virtual bool validateAsmConstraint(const char *&Name,
+                                       TargetInfo::ConstraintInfo &info) const {
+      return true;
+    }
+    virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
+                                  unsigned &NumAliases) const {}
+  };
+}
+
+namespace {
+class MipsTargetInfo : public TargetInfo {
+  std::string ABI, CPU;
+  static const TargetInfo::GCCRegAlias GCCRegAliases[];
+  static const char * const GCCRegNames[];
+public:
+  MipsTargetInfo(const std::string& triple) : TargetInfo(triple), ABI("o32") {
+    DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
+                        "i64:32:64-f32:32:32-f64:64:64-v64:64:64-n32";
+  }
+  virtual const char *getABI() const { return ABI.c_str(); }
+  virtual bool setABI(const std::string &Name) {
+
+    if ((Name == "o32") || (Name == "eabi")) {
+      ABI = Name;
+      return true;
+    } else
+      return false;
+  }
+  virtual bool setCPU(const std::string &Name) {
+    CPU = Name;
+    return true;
+  }
+  void getDefaultFeatures(const std::string &CPU,
+                          llvm::StringMap<bool> &Features) const {
+    Features[ABI] = true;
+    Features[CPU] = true;
+  }
+  virtual void getArchDefines(const LangOptions &Opts,
+                                MacroBuilder &Builder) const {
+    if (ABI == "o32")
+      Builder.defineMacro("__mips_o32");
+    else if (ABI == "eabi")
+      Builder.defineMacro("__mips_eabi");
+  }
+  virtual void getTargetDefines(const LangOptions &Opts,
+                                MacroBuilder &Builder) const {
+    DefineStd(Builder, "mips", Opts);
+    Builder.defineMacro("_mips");
+    DefineStd(Builder, "MIPSEB", Opts);
+    Builder.defineMacro("_MIPSEB");
+    Builder.defineMacro("__REGISTER_PREFIX__", "");
+    getArchDefines(Opts, Builder);
+  }
+  virtual void getTargetBuiltins(const Builtin::Info *&Records,
+                                 unsigned &NumRecords) const {
+    // FIXME: Implement!
+  }
+  virtual const char *getVAListDeclaration() const {
+    return "typedef void* __builtin_va_list;";
+  }
+  virtual void getGCCRegNames(const char * const *&Names,
+                              unsigned &NumNames) const;
+  virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
+                                unsigned &NumAliases) const;
+  virtual bool validateAsmConstraint(const char *&Name,
+                                     TargetInfo::ConstraintInfo &Info) const {
+    switch (*Name) {
+    default:
+    case 'r': // CPU registers.
+    case 'd': // Equivalent to "r" unless generating MIPS16 code.
+    case 'y': // Equivalent to "r", backwards compatibility only.
+    case 'f': // floating-point registers.
+      Info.setAllowsRegister();
+      return true;
+    }
+    return false;
+  }
+
+  virtual const char *getClobbers() const {
+    // FIXME: Implement!
+    return "";
+  }
+};
+
+const char * const MipsTargetInfo::GCCRegNames[] = {
+  "$0",   "$1",   "$2",   "$3",   "$4",   "$5",   "$6",   "$7", 
+  "$8",   "$9",   "$10",  "$11",  "$12",  "$13",  "$14",  "$15",
+  "$16",  "$17",  "$18",  "$19",  "$20",  "$21",  "$22",  "$23",
+  "$24",  "$25",  "$26",  "$27",  "$28",  "$sp",  "$fp",  "$31",
+  "$f0",  "$f1",  "$f2",  "$f3",  "$f4",  "$f5",  "$f6",  "$f7",
+  "$f8",  "$f9",  "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
+  "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
+  "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",
+  "hi",   "lo",   "",     "$fcc0","$fcc1","$fcc2","$fcc3","$fcc4",
+  "$fcc5","$fcc6","$fcc7"
+};
+
+void MipsTargetInfo::getGCCRegNames(const char * const *&Names,
+                                       unsigned &NumNames) const {
+  Names = GCCRegNames;
+  NumNames = llvm::array_lengthof(GCCRegNames);
+}
+
+const TargetInfo::GCCRegAlias MipsTargetInfo::GCCRegAliases[] = {
+  { { "at" },  "$1" },
+  { { "v0" },  "$2" },
+  { { "v1" },  "$3" },
+  { { "a0" },  "$4" },
+  { { "a1" },  "$5" },
+  { { "a2" },  "$6" },
+  { { "a3" },  "$7" },
+  { { "t0" },  "$8" },
+  { { "t1" },  "$9" },
+  { { "t2" }, "$10" },
+  { { "t3" }, "$11" },
+  { { "t4" }, "$12" },
+  { { "t5" }, "$13" },
+  { { "t6" }, "$14" },
+  { { "t7" }, "$15" },
+  { { "s0" }, "$16" },
+  { { "s1" }, "$17" },
+  { { "s2" }, "$18" },
+  { { "s3" }, "$19" },
+  { { "s4" }, "$20" },
+  { { "s5" }, "$21" },
+  { { "s6" }, "$22" },
+  { { "s7" }, "$23" },
+  { { "t8" }, "$24" },
+  { { "t9" }, "$25" },
+  { { "k0" }, "$26" },
+  { { "k1" }, "$27" },
+  { { "gp" }, "$28" },
+  { { "sp" }, "$29" },
+  { { "fp" }, "$30" },
+  { { "ra" }, "$31" }
+};
+
+void MipsTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
+                                         unsigned &NumAliases) const {
+  Aliases = GCCRegAliases;
+  NumAliases = llvm::array_lengthof(GCCRegAliases);
+}
+} // end anonymous namespace.
+
+namespace {
+class MipselTargetInfo : public MipsTargetInfo {
+public:
+  MipselTargetInfo(const std::string& triple) : MipsTargetInfo(triple) {
+    DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
+                        "i64:32:64-f32:32:32-f64:64:64-v64:64:64-n32";
+  }
+
+  virtual void getTargetDefines(const LangOptions &Opts,
+                                MacroBuilder &Builder) const;
+};
+
+void MipselTargetInfo::getTargetDefines(const LangOptions &Opts,
+                                        MacroBuilder &Builder) const {
+  DefineStd(Builder, "mips", Opts);
+  Builder.defineMacro("_mips");
+  DefineStd(Builder, "MIPSEL", Opts);
+  Builder.defineMacro("_MIPSEL");
+  Builder.defineMacro("__REGISTER_PREFIX__", "");
+  getArchDefines(Opts, Builder);
+}
+} // end anonymous namespace.
+
+//===----------------------------------------------------------------------===//
+// Driver code
+//===----------------------------------------------------------------------===//
+
+static TargetInfo *AllocateTarget(const std::string &T) {
+  llvm::Triple Triple(T);
+  llvm::Triple::OSType os = Triple.getOS();
+
+  switch (Triple.getArch()) {
+  default:
+    return NULL;
+
+  case llvm::Triple::arm:
+  case llvm::Triple::thumb:
+    switch (os) {
+    case llvm::Triple::Darwin:
+      return new DarwinARMTargetInfo(T);
+    case llvm::Triple::FreeBSD:
+      return new FreeBSDTargetInfo<ARMTargetInfo>(T);
+    default:
+      return new ARMTargetInfo(T);
+    }
+
+  case llvm::Triple::bfin:
+    return new BlackfinTargetInfo(T);
+
+  case llvm::Triple::msp430:
+    return new MSP430TargetInfo(T);
+
+  case llvm::Triple::mips:
+    if (os == llvm::Triple::Psp)
+      return new PSPTargetInfo<MipsTargetInfo>(T);
+    if (os == llvm::Triple::Linux)
+      return new LinuxTargetInfo<MipsTargetInfo>(T);
+    return new MipsTargetInfo(T);
+
+  case llvm::Triple::mipsel:
+    if (os == llvm::Triple::Psp)
+      return new PSPTargetInfo<MipselTargetInfo>(T);
+    if (os == llvm::Triple::Linux)
+      return new LinuxTargetInfo<MipselTargetInfo>(T);
+    return new MipselTargetInfo(T);
+
+  case llvm::Triple::pic16:
+    return new PIC16TargetInfo(T);
+
+  case llvm::Triple::ppc:
+    if (os == llvm::Triple::Darwin)
+      return new DarwinTargetInfo<PPCTargetInfo>(T);
+    else if (os == llvm::Triple::FreeBSD)
+      return new FreeBSDTargetInfo<PPC32TargetInfo>(T);
+    return new PPC32TargetInfo(T);
+
+  case llvm::Triple::ppc64:
+    if (os == llvm::Triple::Darwin)
+      return new DarwinTargetInfo<PPC64TargetInfo>(T);
+    else if (os == llvm::Triple::Lv2)
+      return new PS3PPUTargetInfo<PPC64TargetInfo>(T);
+    else if (os == llvm::Triple::FreeBSD)
+      return new FreeBSDTargetInfo<PPC64TargetInfo>(T);
+    return new PPC64TargetInfo(T);
+
+  case llvm::Triple::mblaze:
+    return new MBlazeTargetInfo(T);
+
+  case llvm::Triple::sparc:
+    if (os == llvm::Triple::AuroraUX)
+      return new AuroraUXSparcV8TargetInfo(T);
+    if (os == llvm::Triple::Solaris)
+      return new SolarisSparcV8TargetInfo(T);
+    return new SparcV8TargetInfo(T);
+
+  // FIXME: Need a real SPU target.
+  case llvm::Triple::cellspu:
+    return new PS3SPUTargetInfo<PPC64TargetInfo>(T);
+
+  case llvm::Triple::systemz:
+    return new SystemZTargetInfo(T);
+
+  case llvm::Triple::tce:
+    return new TCETargetInfo(T);
+
+  case llvm::Triple::x86:
+    switch (os) {
+    case llvm::Triple::AuroraUX:
+      return new AuroraUXTargetInfo<X86_32TargetInfo>(T);
+    case llvm::Triple::Darwin:
+      return new DarwinI386TargetInfo(T);
+    case llvm::Triple::Linux:
+      return new LinuxTargetInfo<X86_32TargetInfo>(T);
+    case llvm::Triple::DragonFly:
+      return new DragonFlyBSDTargetInfo<X86_32TargetInfo>(T);
+    case llvm::Triple::NetBSD:
+      return new NetBSDTargetInfo<X86_32TargetInfo>(T);
+    case llvm::Triple::OpenBSD:
+      return new OpenBSDI386TargetInfo(T);
+    case llvm::Triple::FreeBSD:
+      return new FreeBSDTargetInfo<X86_32TargetInfo>(T);
+    case llvm::Triple::Solaris:
+      return new SolarisTargetInfo<X86_32TargetInfo>(T);
+    case llvm::Triple::Cygwin:
+      return new CygwinX86_32TargetInfo(T);
+    case llvm::Triple::MinGW32:
+      return new MinGWX86_32TargetInfo(T);
+    case llvm::Triple::Win32:
+      return new VisualStudioWindowsX86_32TargetInfo(T);
+    case llvm::Triple::Haiku:
+      return new HaikuX86_32TargetInfo(T);
+    default:
+      return new X86_32TargetInfo(T);
+    }
+
+  case llvm::Triple::x86_64:
+    switch (os) {
+    case llvm::Triple::AuroraUX:
+      return new AuroraUXTargetInfo<X86_64TargetInfo>(T);
+    case llvm::Triple::Darwin:
+      return new DarwinX86_64TargetInfo(T);
+    case llvm::Triple::Linux:
+      return new LinuxTargetInfo<X86_64TargetInfo>(T);
+    case llvm::Triple::DragonFly:
+      return new DragonFlyBSDTargetInfo<X86_64TargetInfo>(T);
+    case llvm::Triple::NetBSD:
+      return new NetBSDTargetInfo<X86_64TargetInfo>(T);
+    case llvm::Triple::OpenBSD:
+      return new OpenBSDX86_64TargetInfo(T);
+    case llvm::Triple::FreeBSD:
+      return new FreeBSDTargetInfo<X86_64TargetInfo>(T);
+    case llvm::Triple::Solaris:
+      return new SolarisTargetInfo<X86_64TargetInfo>(T);
+    case llvm::Triple::MinGW64:
+      return new MinGWX86_64TargetInfo(T);
+    case llvm::Triple::Win32:   // This is what Triple.h supports now.
+      return new VisualStudioWindowsX86_64TargetInfo(T);
+    default:
+      return new X86_64TargetInfo(T);
+    }
+  }
+}
+
+/// CreateTargetInfo - Return the target info object for the specified target
+/// triple.
+TargetInfo *TargetInfo::CreateTargetInfo(Diagnostic &Diags,
+                                         TargetOptions &Opts) {
+  llvm::Triple Triple(Opts.Triple);
+
+  // Construct the target
+  llvm::OwningPtr<TargetInfo> Target(AllocateTarget(Triple.str()));
+  if (!Target) {
+    Diags.Report(diag::err_target_unknown_triple) << Triple.str();
+    return 0;
+  }
+
+  // Set the target CPU if specified.
+  if (!Opts.CPU.empty() && !Target->setCPU(Opts.CPU)) {
+    Diags.Report(diag::err_target_unknown_cpu) << Opts.CPU;
+    return 0;
+  }
+
+  // Set the target ABI if specified.
+  if (!Opts.ABI.empty() && !Target->setABI(Opts.ABI)) {
+    Diags.Report(diag::err_target_unknown_abi) << Opts.ABI;
+    return 0;
+  }
+
+  // Compute the default target features, we need the target to handle this
+  // because features may have dependencies on one another.
+  llvm::StringMap<bool> Features;
+  Target->getDefaultFeatures(Opts.CPU, Features);
+
+  // Apply the user specified deltas.
+  for (std::vector<std::string>::const_iterator it = Opts.Features.begin(),
+         ie = Opts.Features.end(); it != ie; ++it) {
+    const char *Name = it->c_str();
+
+    // Apply the feature via the target.
+    if ((Name[0] != '-' && Name[0] != '+') ||
+        !Target->setFeatureEnabled(Features, Name + 1, (Name[0] == '+'))) {
+      Diags.Report(diag::err_target_invalid_feature) << Name;
+      return 0;
+    }
+  }
+
+  // Add the features to the compile options.
+  //
+  // FIXME: If we are completely confident that we have the right set, we only
+  // need to pass the minuses.
+  Opts.Features.clear();
+  for (llvm::StringMap<bool>::const_iterator it = Features.begin(),
+         ie = Features.end(); it != ie; ++it)
+    Opts.Features.push_back(std::string(it->second ? "+" : "-") + it->first());
+  Target->HandleTargetFeatures(Opts.Features);
+
+  return Target.take();
+}
diff --git a/lib/Basic/TokenKinds.cpp b/lib/Basic/TokenKinds.cpp
new file mode 100644
index 0000000..8cdc1e3
--- /dev/null
+++ b/lib/Basic/TokenKinds.cpp
@@ -0,0 +1,39 @@
+//===--- TokenKinds.cpp - Token Kinds Support -----------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements the TokenKind enum and support functions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Basic/TokenKinds.h"
+
+#include <cassert>
+using namespace clang;
+
+static const char * const TokNames[] = {
+#define TOK(X) #X,
+#define KEYWORD(X,Y) #X,
+#include "clang/Basic/TokenKinds.def"
+  0
+};
+
+const char *tok::getTokenName(enum TokenKind Kind) {
+  assert(Kind < tok::NUM_TOKENS);
+  return TokNames[Kind];
+}
+
+const char *tok::getTokenSimpleSpelling(enum TokenKind Kind) {
+  switch (Kind) {
+#define PUNCTUATOR(X,Y) case X: return Y;
+#include "clang/Basic/TokenKinds.def"
+  default: break;
+  }
+
+  return 0;
+}
diff --git a/lib/Basic/Version.cpp b/lib/Basic/Version.cpp
new file mode 100644
index 0000000..dc87d14
--- /dev/null
+++ b/lib/Basic/Version.cpp
@@ -0,0 +1,75 @@
+//===- Version.cpp - Clang Version Number -----------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines several version-related utility functions for Clang.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Basic/Version.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cstring>
+#include <cstdlib>
+
+using namespace std;
+
+namespace clang {
+  
+llvm::StringRef getClangRepositoryPath() {
+  static const char URL[] = "$URL: http://llvm.org/svn/llvm-project/cfe/trunk/lib/Basic/Version.cpp $";
+  const char *URLEnd = URL + strlen(URL);
+
+  const char *End = strstr(URL, "/lib/Basic");
+  if (End)
+    URLEnd = End;
+
+  End = strstr(URL, "/clang/tools/clang");
+  if (End)
+    URLEnd = End;
+
+  const char *Begin = strstr(URL, "cfe/");
+  if (Begin)
+    return llvm::StringRef(Begin + 4, URLEnd - Begin - 4);
+
+  return llvm::StringRef(URL, URLEnd - URL);
+}
+
+std::string getClangRevision() {
+#ifdef SVN_REVISION
+  if (SVN_REVISION[0] != '\0') {
+    std::string revision;
+    llvm::raw_string_ostream OS(revision);
+    OS << strtol(SVN_REVISION, 0, 10);
+    return OS.str();
+  }
+#endif
+  return "";
+}
+
+std::string getClangFullRepositoryVersion() {
+  std::string buf;
+  llvm::raw_string_ostream OS(buf);
+  OS << getClangRepositoryPath();
+  const std::string &Revision = getClangRevision();
+  if (!Revision.empty())
+    OS << ' ' << Revision;
+  return OS.str();
+}
+  
+std::string getClangFullVersion() {
+  std::string buf;
+  llvm::raw_string_ostream OS(buf);
+#ifdef CLANG_VENDOR
+  OS << CLANG_VENDOR;
+#endif
+  OS << "clang version " CLANG_VERSION_STRING " ("
+     << getClangFullRepositoryVersion() << ')';
+  return OS.str();
+}
+
+} // end namespace clang
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
new file mode 100644
index 0000000..bc2cd46
--- /dev/null
+++ b/lib/CMakeLists.txt
@@ -0,0 +1,13 @@
+add_subdirectory(Headers)
+add_subdirectory(Basic)
+add_subdirectory(Lex)
+add_subdirectory(Parse)
+add_subdirectory(AST)
+add_subdirectory(Sema)
+add_subdirectory(CodeGen)
+add_subdirectory(Analysis)
+add_subdirectory(Rewrite)
+add_subdirectory(Driver)
+add_subdirectory(Frontend)
+add_subdirectory(Index)
+add_subdirectory(Checker)
diff --git a/lib/Checker/AdjustedReturnValueChecker.cpp b/lib/Checker/AdjustedReturnValueChecker.cpp
new file mode 100644
index 0000000..b92f2e7
--- /dev/null
+++ b/lib/Checker/AdjustedReturnValueChecker.cpp
@@ -0,0 +1,96 @@
+//== AdjustedReturnValueChecker.cpp -----------------------------*- C++ -*--==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines AdjustedReturnValueChecker, a simple check to see if the
+// return value of a function call is different than the one the caller thinks
+// it is.
+//
+//===----------------------------------------------------------------------===//
+
+#include "GRExprEngineInternalChecks.h"
+#include "clang/Checker/BugReporter/BugReporter.h"
+#include "clang/Checker/PathSensitive/GRExprEngine.h"
+#include "clang/Checker/PathSensitive/CheckerVisitor.h"
+
+using namespace clang;
+
+namespace {
+class AdjustedReturnValueChecker : 
+    public CheckerVisitor<AdjustedReturnValueChecker> {      
+public:
+  AdjustedReturnValueChecker() {}
+
+  void PostVisitCallExpr(CheckerContext &C, const CallExpr *CE);
+      
+  static void *getTag() {
+    static int x = 0; return &x;
+  }      
+};
+}
+
+void clang::RegisterAdjustedReturnValueChecker(GRExprEngine &Eng) {
+  Eng.registerCheck(new AdjustedReturnValueChecker());
+}
+
+void AdjustedReturnValueChecker::PostVisitCallExpr(CheckerContext &C,
+                                                   const CallExpr *CE) {
+  
+  // Get the result type of the call.
+  QualType expectedResultTy = CE->getType();
+
+  // Fetch the signature of the called function.
+  const GRState *state = C.getState();
+
+  SVal V = state->getSVal(CE);
+  
+  if (V.isUnknown())
+    return;
+  
+  // Casting to void?  Discard the value.
+  if (expectedResultTy->isVoidType()) {
+    C.GenerateNode(state->BindExpr(CE, UnknownVal()));
+    return;
+  }                   
+
+  const MemRegion *callee = state->getSVal(CE->getCallee()).getAsRegion();
+  if (!callee)
+    return;
+
+  QualType actualResultTy;
+  
+  if (const FunctionTextRegion *FT = dyn_cast<FunctionTextRegion>(callee)) {
+    const FunctionDecl *FD = FT->getDecl();
+    actualResultTy = FD->getResultType();
+  }
+  else if (const BlockDataRegion *BD = dyn_cast<BlockDataRegion>(callee)) {
+    const BlockTextRegion *BR = BD->getCodeRegion();
+    const BlockPointerType *BT =
+      BR->getLocationType(C.getASTContext())->getAs<BlockPointerType>();
+    const FunctionType *FT = BT->getPointeeType()->getAs<FunctionType>();
+    actualResultTy = FT->getResultType();
+  }
+
+  // Can this happen?
+  if (actualResultTy.isNull())
+    return;
+
+  // For now, ignore references.
+  if (actualResultTy->getAs<ReferenceType>())
+    return;
+  
+
+  // Are they the same?
+  if (expectedResultTy != actualResultTy) {
+    // FIXME: Do more checking and actual emit an error. At least performing
+    // the cast avoids some assertion failures elsewhere.
+    SValuator &SVator = C.getSValuator();
+    V = SVator.EvalCast(V, expectedResultTy, actualResultTy);
+    C.GenerateNode(state->BindExpr(CE, V));
+  }
+}
diff --git a/lib/Checker/AggExprVisitor.cpp b/lib/Checker/AggExprVisitor.cpp
new file mode 100644
index 0000000..343afec
--- /dev/null
+++ b/lib/Checker/AggExprVisitor.cpp
@@ -0,0 +1,55 @@
+//=-- AggExprVisitor.cpp - evaluating expressions of C++ class type -*- C++ -*-=
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines AggExprVisitor class, which contains lots of boiler
+// plate code for evaluating expressions of C++ class type.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Checker/PathSensitive/GRExprEngine.h"
+#include "clang/AST/StmtVisitor.h"
+
+using namespace clang;
+
+namespace {
+class AggExprVisitor : public StmtVisitor<AggExprVisitor> {
+  SVal DestPtr;
+  ExplodedNode *Pred;
+  ExplodedNodeSet &DstSet;
+  GRExprEngine &Eng;
+
+public:
+  AggExprVisitor(SVal dest, ExplodedNode *N, ExplodedNodeSet &dst, 
+                 GRExprEngine &eng)
+    : DestPtr(dest), Pred(N), DstSet(dst), Eng(eng) {}
+
+  void VisitCastExpr(CastExpr *E);
+  void VisitCXXConstructExpr(CXXConstructExpr *E);
+};
+}
+
+void AggExprVisitor::VisitCastExpr(CastExpr *E) {
+  switch (E->getCastKind()) {
+  default: 
+    assert(0 && "Unhandled cast kind");
+  case CastExpr::CK_NoOp:
+  case CastExpr::CK_ConstructorConversion:
+    Visit(E->getSubExpr());
+    break;
+  }
+}
+
+void AggExprVisitor::VisitCXXConstructExpr(CXXConstructExpr *E) {
+  Eng.VisitCXXConstructExpr(E, DestPtr, Pred, DstSet);
+}
+
+void GRExprEngine::VisitAggExpr(const Expr *E, SVal Dest, ExplodedNode *Pred,
+                                ExplodedNodeSet &Dst) {
+  AggExprVisitor(Dest, Pred, Dst, *this).Visit(const_cast<Expr *>(E));
+}
diff --git a/lib/Checker/ArrayBoundChecker.cpp b/lib/Checker/ArrayBoundChecker.cpp
new file mode 100644
index 0000000..746b3f9
--- /dev/null
+++ b/lib/Checker/ArrayBoundChecker.cpp
@@ -0,0 +1,91 @@
+//== ArrayBoundChecker.cpp ------------------------------*- C++ -*--==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines ArrayBoundChecker, which is a path-sensitive check
+// which looks for an out-of-bound array element access.
+//
+//===----------------------------------------------------------------------===//
+
+#include "GRExprEngineInternalChecks.h"
+#include "clang/Checker/BugReporter/BugType.h"
+#include "clang/Checker/PathSensitive/CheckerVisitor.h"
+#include "clang/Checker/PathSensitive/GRExprEngine.h"
+
+using namespace clang;
+
+namespace {
+class ArrayBoundChecker : 
+    public CheckerVisitor<ArrayBoundChecker> {      
+  BuiltinBug *BT;
+public:
+    ArrayBoundChecker() : BT(0) {}
+    static void *getTag();
+    void VisitLocation(CheckerContext &C, const Stmt *S, SVal l);
+};
+}
+
+void clang::RegisterArrayBoundChecker(GRExprEngine &Eng) {
+  Eng.registerCheck(new ArrayBoundChecker());
+}
+
+void *ArrayBoundChecker::getTag() {
+  static int x = 0; return &x;
+}
+
+void ArrayBoundChecker::VisitLocation(CheckerContext &C, const Stmt *S, SVal l){
+  // Check for out of bound array element access.
+  const MemRegion *R = l.getAsRegion();
+  if (!R)
+    return;
+
+  R = R->StripCasts();
+
+  const ElementRegion *ER = dyn_cast<ElementRegion>(R);
+  if (!ER)
+    return;
+
+  // Get the index of the accessed element.
+  DefinedOrUnknownSVal &Idx = cast<DefinedOrUnknownSVal>(ER->getIndex());
+
+  const GRState *state = C.getState();
+
+  // Get the size of the array.
+  DefinedOrUnknownSVal NumElements 
+    = C.getStoreManager().getSizeInElements(state, ER->getSuperRegion(), 
+                                         ER->getValueType(C.getASTContext()));
+
+  const GRState *StInBound = state->AssumeInBound(Idx, NumElements, true);
+  const GRState *StOutBound = state->AssumeInBound(Idx, NumElements, false);
+  if (StOutBound && !StInBound) {
+    ExplodedNode *N = C.GenerateSink(StOutBound);
+    if (!N)
+      return;
+  
+    if (!BT)
+      BT = new BuiltinBug("Out-of-bound array access",
+                       "Access out-of-bound array element (buffer overflow)");
+
+    // FIXME: It would be nice to eventually make this diagnostic more clear,
+    // e.g., by referencing the original declaration or by saying *why* this
+    // reference is outside the range.
+
+    // Generate a report for this bug.
+    RangedBugReport *report = 
+      new RangedBugReport(*BT, BT->getDescription(), N);
+
+    report->addRange(S->getSourceRange());
+    C.EmitReport(report);
+    return;
+  }
+  
+  // Array bound check succeeded.  From this point forward the array bound
+  // should always succeed.
+  assert(StInBound);
+  C.addTransition(StInBound);
+}
diff --git a/lib/Checker/AttrNonNullChecker.cpp b/lib/Checker/AttrNonNullChecker.cpp
new file mode 100644
index 0000000..309a74c
--- /dev/null
+++ b/lib/Checker/AttrNonNullChecker.cpp
@@ -0,0 +1,112 @@
+//===--- AttrNonNullChecker.h - Undefined arguments checker ----*- C++ -*--===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This defines AttrNonNullChecker, a builtin check in GRExprEngine that 
+// performs checks for arguments declared to have nonnull attribute.
+//
+//===----------------------------------------------------------------------===//
+
+#include "GRExprEngineInternalChecks.h"
+#include "clang/Checker/BugReporter/BugType.h"
+#include "clang/Checker/PathSensitive/CheckerVisitor.h"
+
+using namespace clang;
+
+namespace {
+class AttrNonNullChecker
+  : public CheckerVisitor<AttrNonNullChecker> {
+  BugType *BT;
+public:
+  AttrNonNullChecker() : BT(0) {}
+  static void *getTag() {
+    static int x = 0;
+    return &x;
+  }
+  void PreVisitCallExpr(CheckerContext &C, const CallExpr *CE);
+};
+} // end anonymous namespace
+
+void clang::RegisterAttrNonNullChecker(GRExprEngine &Eng) {
+  Eng.registerCheck(new AttrNonNullChecker());
+}
+
+void AttrNonNullChecker::PreVisitCallExpr(CheckerContext &C, 
+                                          const CallExpr *CE) {
+  const GRState *state = C.getState();
+
+  // Check if the callee has a 'nonnull' attribute.
+  SVal X = state->getSVal(CE->getCallee());
+
+  const FunctionDecl* FD = X.getAsFunctionDecl();
+  if (!FD)
+    return;
+
+  const NonNullAttr* Att = FD->getAttr<NonNullAttr>();
+  if (!Att)
+    return;
+
+  // Iterate through the arguments of CE and check them for null.
+  unsigned idx = 0;
+
+  for (CallExpr::const_arg_iterator I=CE->arg_begin(), E=CE->arg_end(); I!=E;
+       ++I, ++idx) {
+
+    if (!Att->isNonNull(idx))
+      continue;
+
+    const SVal &V = state->getSVal(*I);
+    const DefinedSVal *DV = dyn_cast<DefinedSVal>(&V);
+
+    if (!DV)
+      continue;
+
+    ConstraintManager &CM = C.getConstraintManager();
+    const GRState *stateNotNull, *stateNull;
+    llvm::tie(stateNotNull, stateNull) = CM.AssumeDual(state, *DV);
+
+    if (stateNull && !stateNotNull) {
+      // Generate an error node.  Check for a null node in case
+      // we cache out.
+      if (ExplodedNode *errorNode = C.GenerateSink(stateNull)) {
+
+        // Lazily allocate the BugType object if it hasn't already been
+        // created. Ownership is transferred to the BugReporter object once
+        // the BugReport is passed to 'EmitWarning'.
+        if (!BT)
+          BT = new BugType("Argument with 'nonnull' attribute passed null",
+                           "API");
+
+        EnhancedBugReport *R =
+          new EnhancedBugReport(*BT,
+                                "Null pointer passed as an argument to a "
+                                "'nonnull' parameter", errorNode);
+
+        // Highlight the range of the argument that was null.
+        const Expr *arg = *I;
+        R->addRange(arg->getSourceRange());
+        R->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue, arg);
+
+        // Emit the bug report.
+        C.EmitReport(R);
+      }
+
+      // Always return.  Either we cached out or we just emitted an error.
+      return;
+    }
+
+    // If a pointer value passed the check we should assume that it is
+    // indeed not null from this point forward.
+    assert(stateNotNull);
+    state = stateNotNull;
+  }
+
+  // If we reach here all of the arguments passed the nonnull check.
+  // If 'state' has been updated generated a new node.
+  C.addTransition(state);
+}
diff --git a/lib/Checker/BasicConstraintManager.cpp b/lib/Checker/BasicConstraintManager.cpp
new file mode 100644
index 0000000..e89546e
--- /dev/null
+++ b/lib/Checker/BasicConstraintManager.cpp
@@ -0,0 +1,317 @@
+//== BasicConstraintManager.cpp - Manage basic constraints.------*- C++ -*--==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines BasicConstraintManager, a class that tracks simple
+//  equality and inequality constraints on symbolic values of GRState.
+//
+//===----------------------------------------------------------------------===//
+
+#include "SimpleConstraintManager.h"
+#include "clang/Checker/PathSensitive/GRState.h"
+#include "clang/Checker/PathSensitive/GRStateTrait.h"
+#include "clang/Checker/PathSensitive/GRTransferFuncs.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace clang;
+
+
+namespace { class ConstNotEq {}; }
+namespace { class ConstEq {}; }
+
+typedef llvm::ImmutableMap<SymbolRef,GRState::IntSetTy> ConstNotEqTy;
+typedef llvm::ImmutableMap<SymbolRef,const llvm::APSInt*> ConstEqTy;
+
+static int ConstEqIndex = 0;
+static int ConstNotEqIndex = 0;
+
+namespace clang {
+template<>
+struct GRStateTrait<ConstNotEq> : public GRStatePartialTrait<ConstNotEqTy> {
+  static inline void* GDMIndex() { return &ConstNotEqIndex; }
+};
+
+template<>
+struct GRStateTrait<ConstEq> : public GRStatePartialTrait<ConstEqTy> {
+  static inline void* GDMIndex() { return &ConstEqIndex; }
+};
+}
+
+namespace {
+// BasicConstraintManager only tracks equality and inequality constraints of
+// constants and integer variables.
+class BasicConstraintManager
+  : public SimpleConstraintManager {
+  GRState::IntSetTy::Factory ISetFactory;
+public:
+  BasicConstraintManager(GRStateManager &statemgr, GRSubEngine &subengine)
+    : SimpleConstraintManager(subengine), 
+      ISetFactory(statemgr.getAllocator()) {}
+
+  const GRState* AssumeSymNE(const GRState* state, SymbolRef sym,
+                             const llvm::APSInt& V);
+
+  const GRState* AssumeSymEQ(const GRState* state, SymbolRef sym,
+                             const llvm::APSInt& V);
+
+  const GRState* AssumeSymLT(const GRState* state, SymbolRef sym,
+                             const llvm::APSInt& V);
+
+  const GRState* AssumeSymGT(const GRState* state, SymbolRef sym,
+                             const llvm::APSInt& V);
+
+  const GRState* AssumeSymGE(const GRState* state, SymbolRef sym,
+                             const llvm::APSInt& V);
+
+  const GRState* AssumeSymLE(const GRState* state, SymbolRef sym,
+                             const llvm::APSInt& V);
+
+  const GRState* AddEQ(const GRState* state, SymbolRef sym, const llvm::APSInt& V);
+
+  const GRState* AddNE(const GRState* state, SymbolRef sym, const llvm::APSInt& V);
+
+  const llvm::APSInt* getSymVal(const GRState* state, SymbolRef sym) const;
+  bool isNotEqual(const GRState* state, SymbolRef sym, const llvm::APSInt& V)
+      const;
+  bool isEqual(const GRState* state, SymbolRef sym, const llvm::APSInt& V)
+      const;
+
+  const GRState* RemoveDeadBindings(const GRState* state, SymbolReaper& SymReaper);
+
+  void print(const GRState* state, llvm::raw_ostream& Out,
+             const char* nl, const char *sep);
+};
+
+} // end anonymous namespace
+
+ConstraintManager* clang::CreateBasicConstraintManager(GRStateManager& statemgr,
+                                                       GRSubEngine &subengine) {
+  return new BasicConstraintManager(statemgr, subengine);
+}
+
+const GRState*
+BasicConstraintManager::AssumeSymNE(const GRState *state, SymbolRef sym,
+                                    const llvm::APSInt& V) {
+  // First, determine if sym == X, where X != V.
+  if (const llvm::APSInt* X = getSymVal(state, sym)) {
+    bool isFeasible = (*X != V);
+    return isFeasible ? state : NULL;
+  }
+
+  // Second, determine if sym != V.
+  if (isNotEqual(state, sym, V))
+    return state;
+
+  // If we reach here, sym is not a constant and we don't know if it is != V.
+  // Make that assumption.
+  return AddNE(state, sym, V);
+}
+
+const GRState *BasicConstraintManager::AssumeSymEQ(const GRState *state,
+                                                   SymbolRef sym,
+                                                   const llvm::APSInt &V) {
+  // First, determine if sym == X, where X != V.
+  if (const llvm::APSInt* X = getSymVal(state, sym)) {
+    bool isFeasible = *X == V;
+    return isFeasible ? state : NULL;
+  }
+
+  // Second, determine if sym != V.
+  if (isNotEqual(state, sym, V))
+    return NULL;
+
+  // If we reach here, sym is not a constant and we don't know if it is == V.
+  // Make that assumption.
+  return AddEQ(state, sym, V);
+}
+
+// These logic will be handled in another ConstraintManager.
+const GRState *BasicConstraintManager::AssumeSymLT(const GRState *state,
+                                                   SymbolRef sym,
+                                                   const llvm::APSInt& V) {
+  // Is 'V' the smallest possible value?
+  if (V == llvm::APSInt::getMinValue(V.getBitWidth(), V.isUnsigned())) {
+    // sym cannot be any value less than 'V'.  This path is infeasible.
+    return NULL;
+  }
+
+  // FIXME: For now have assuming x < y be the same as assuming sym != V;
+  return AssumeSymNE(state, sym, V);
+}
+
+const GRState *BasicConstraintManager::AssumeSymGT(const GRState *state,
+                                                   SymbolRef sym,
+                                                   const llvm::APSInt& V) {
+
+  // Is 'V' the largest possible value?
+  if (V == llvm::APSInt::getMaxValue(V.getBitWidth(), V.isUnsigned())) {
+    // sym cannot be any value greater than 'V'.  This path is infeasible.
+    return NULL;
+  }
+
+  // FIXME: For now have assuming x > y be the same as assuming sym != V;
+  return AssumeSymNE(state, sym, V);
+}
+
+const GRState *BasicConstraintManager::AssumeSymGE(const GRState *state,
+                                                   SymbolRef sym,
+                                                   const llvm::APSInt &V) {
+
+  // Reject a path if the value of sym is a constant X and !(X >= V).
+  if (const llvm::APSInt *X = getSymVal(state, sym)) {
+    bool isFeasible = *X >= V;
+    return isFeasible ? state : NULL;
+  }
+
+  // Sym is not a constant, but it is worth looking to see if V is the
+  // maximum integer value.
+  if (V == llvm::APSInt::getMaxValue(V.getBitWidth(), V.isUnsigned())) {
+    // If we know that sym != V, then this condition is infeasible since
+    // there is no other value greater than V.
+    bool isFeasible = !isNotEqual(state, sym, V);
+
+    // If the path is still feasible then as a consequence we know that
+    // 'sym == V' because we cannot have 'sym > V' (no larger values).
+    // Add this constraint.
+    return isFeasible ? AddEQ(state, sym, V) : NULL;
+  }
+
+  return state;
+}
+
+const GRState*
+BasicConstraintManager::AssumeSymLE(const GRState* state, SymbolRef sym,
+                                    const llvm::APSInt& V) {
+
+  // Reject a path if the value of sym is a constant X and !(X <= V).
+  if (const llvm::APSInt* X = getSymVal(state, sym)) {
+    bool isFeasible = *X <= V;
+    return isFeasible ? state : NULL;
+  }
+
+  // Sym is not a constant, but it is worth looking to see if V is the
+  // minimum integer value.
+  if (V == llvm::APSInt::getMinValue(V.getBitWidth(), V.isUnsigned())) {
+    // If we know that sym != V, then this condition is infeasible since
+    // there is no other value less than V.
+    bool isFeasible = !isNotEqual(state, sym, V);
+
+    // If the path is still feasible then as a consequence we know that
+    // 'sym == V' because we cannot have 'sym < V' (no smaller values).
+    // Add this constraint.
+    return isFeasible ? AddEQ(state, sym, V) : NULL;
+  }
+
+  return state;
+}
+
+const GRState* BasicConstraintManager::AddEQ(const GRState* state, SymbolRef sym,
+                                             const llvm::APSInt& V) {
+  // Create a new state with the old binding replaced.
+  return state->set<ConstEq>(sym, &V);
+}
+
+const GRState* BasicConstraintManager::AddNE(const GRState* state, SymbolRef sym,
+                                             const llvm::APSInt& V) {
+
+  // First, retrieve the NE-set associated with the given symbol.
+  ConstNotEqTy::data_type* T = state->get<ConstNotEq>(sym);
+  GRState::IntSetTy S = T ? *T : ISetFactory.GetEmptySet();
+
+  // Now add V to the NE set.
+  S = ISetFactory.Add(S, &V);
+
+  // Create a new state with the old binding replaced.
+  return state->set<ConstNotEq>(sym, S);
+}
+
+const llvm::APSInt* BasicConstraintManager::getSymVal(const GRState* state,
+                                                      SymbolRef sym) const {
+  const ConstEqTy::data_type* T = state->get<ConstEq>(sym);
+  return T ? *T : NULL;
+}
+
+bool BasicConstraintManager::isNotEqual(const GRState* state, SymbolRef sym,
+                                        const llvm::APSInt& V) const {
+
+  // Retrieve the NE-set associated with the given symbol.
+  const ConstNotEqTy::data_type* T = state->get<ConstNotEq>(sym);
+
+  // See if V is present in the NE-set.
+  return T ? T->contains(&V) : false;
+}
+
+bool BasicConstraintManager::isEqual(const GRState* state, SymbolRef sym,
+                                     const llvm::APSInt& V) const {
+  // Retrieve the EQ-set associated with the given symbol.
+  const ConstEqTy::data_type* T = state->get<ConstEq>(sym);
+  // See if V is present in the EQ-set.
+  return T ? **T == V : false;
+}
+
+/// Scan all symbols referenced by the constraints. If the symbol is not alive
+/// as marked in LSymbols, mark it as dead in DSymbols.
+const GRState*
+BasicConstraintManager::RemoveDeadBindings(const GRState* state,
+                                           SymbolReaper& SymReaper) {
+
+  ConstEqTy CE = state->get<ConstEq>();
+  ConstEqTy::Factory& CEFactory = state->get_context<ConstEq>();
+
+  for (ConstEqTy::iterator I = CE.begin(), E = CE.end(); I!=E; ++I) {
+    SymbolRef sym = I.getKey();
+    if (SymReaper.maybeDead(sym)) CE = CEFactory.Remove(CE, sym);
+  }
+  state = state->set<ConstEq>(CE);
+
+  ConstNotEqTy CNE = state->get<ConstNotEq>();
+  ConstNotEqTy::Factory& CNEFactory = state->get_context<ConstNotEq>();
+
+  for (ConstNotEqTy::iterator I = CNE.begin(), E = CNE.end(); I != E; ++I) {
+    SymbolRef sym = I.getKey();
+    if (SymReaper.maybeDead(sym)) CNE = CNEFactory.Remove(CNE, sym);
+  }
+
+  return state->set<ConstNotEq>(CNE);
+}
+
+void BasicConstraintManager::print(const GRState* state, llvm::raw_ostream& Out,
+                                   const char* nl, const char *sep) {
+  // Print equality constraints.
+
+  ConstEqTy CE = state->get<ConstEq>();
+
+  if (!CE.isEmpty()) {
+    Out << nl << sep << "'==' constraints:";
+    for (ConstEqTy::iterator I = CE.begin(), E = CE.end(); I!=E; ++I)
+      Out << nl << " $" << I.getKey() << " : " << *I.getData();
+  }
+
+  // Print != constraints.
+
+  ConstNotEqTy CNE = state->get<ConstNotEq>();
+
+  if (!CNE.isEmpty()) {
+    Out << nl << sep << "'!=' constraints:";
+
+    for (ConstNotEqTy::iterator I = CNE.begin(), EI = CNE.end(); I!=EI; ++I) {
+      Out << nl << " $" << I.getKey() << " : ";
+      bool isFirst = true;
+
+      GRState::IntSetTy::iterator J = I.getData().begin(),
+                                  EJ = I.getData().end();
+
+      for ( ; J != EJ; ++J) {
+        if (isFirst) isFirst = false;
+        else Out << ", ";
+
+        Out << (*J)->getSExtValue(); // Hack: should print to raw_ostream.
+      }
+    }
+  }
+}
diff --git a/lib/Checker/BasicObjCFoundationChecks.cpp b/lib/Checker/BasicObjCFoundationChecks.cpp
new file mode 100644
index 0000000..e7275ca
--- /dev/null
+++ b/lib/Checker/BasicObjCFoundationChecks.cpp
@@ -0,0 +1,577 @@
+//== BasicObjCFoundationChecks.cpp - Simple Apple-Foundation checks -*- C++ -*--
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines BasicObjCFoundationChecks, a class that encapsulates
+//  a set of simple checks to run on Objective-C code using Apple's Foundation
+//  classes.
+//
+//===----------------------------------------------------------------------===//
+
+#include "BasicObjCFoundationChecks.h"
+
+#include "clang/Checker/PathSensitive/ExplodedGraph.h"
+#include "clang/Checker/PathSensitive/GRSimpleAPICheck.h"
+#include "clang/Checker/PathSensitive/GRExprEngine.h"
+#include "clang/Checker/PathSensitive/GRState.h"
+#include "clang/Checker/BugReporter/BugType.h"
+#include "clang/Checker/PathSensitive/MemRegion.h"
+#include "clang/Checker/PathSensitive/CheckerVisitor.h"
+#include "clang/Checker/Checkers/LocalCheckers.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprObjC.h"
+#include "clang/AST/ASTContext.h"
+
+using namespace clang;
+
+static const ObjCInterfaceType* GetReceiverType(const ObjCMessageExpr* ME) {
+  QualType T;
+  switch (ME->getReceiverKind()) {
+  case ObjCMessageExpr::Instance:
+    T = ME->getInstanceReceiver()->getType();
+    break;
+
+  case ObjCMessageExpr::SuperInstance:
+    T = ME->getSuperType();
+    break;
+
+  case ObjCMessageExpr::Class:
+  case ObjCMessageExpr::SuperClass:
+    return 0;
+  }
+
+  if (const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>())
+    return PT->getInterfaceType();
+
+  return NULL;
+}
+
+static const char* GetReceiverNameType(const ObjCMessageExpr* ME) {
+  if (const ObjCInterfaceType *ReceiverType = GetReceiverType(ME))
+    return ReceiverType->getDecl()->getIdentifier()->getNameStart();
+  return NULL;
+}
+
+namespace {
+
+class APIMisuse : public BugType {
+public:
+  APIMisuse(const char* name) : BugType(name, "API Misuse (Apple)") {}
+};
+
+class BasicObjCFoundationChecks : public GRSimpleAPICheck {
+  APIMisuse *BT;
+  BugReporter& BR;
+  ASTContext &Ctx;
+
+  bool isNSString(const ObjCInterfaceType *T, llvm::StringRef suffix);
+  bool AuditNSString(ExplodedNode* N, const ObjCMessageExpr* ME);
+
+  void Warn(ExplodedNode* N, const Expr* E, const std::string& s);
+  void WarnNilArg(ExplodedNode* N, const Expr* E);
+
+  bool CheckNilArg(ExplodedNode* N, unsigned Arg);
+
+public:
+  BasicObjCFoundationChecks(ASTContext& ctx, BugReporter& br)
+    : BT(0), BR(br), Ctx(ctx) {}
+
+  bool Audit(ExplodedNode* N, GRStateManager&);
+
+private:
+  void WarnNilArg(ExplodedNode* N, const ObjCMessageExpr* ME, unsigned Arg) {
+    std::string sbuf;
+    llvm::raw_string_ostream os(sbuf);
+    os << "Argument to '" << GetReceiverNameType(ME) << "' method '"
+       << ME->getSelector().getAsString() << "' cannot be nil.";
+
+    // Lazily create the BugType object for NilArg.  This will be owned
+    // by the BugReporter object 'BR' once we call BR.EmitWarning.
+    if (!BT) BT = new APIMisuse("nil argument");
+
+    RangedBugReport *R = new RangedBugReport(*BT, os.str(), N);
+    R->addRange(ME->getArg(Arg)->getSourceRange());
+    BR.EmitReport(R);
+  }
+};
+
+} // end anonymous namespace
+
+
+GRSimpleAPICheck*
+clang::CreateBasicObjCFoundationChecks(ASTContext& Ctx, BugReporter& BR) {
+  return new BasicObjCFoundationChecks(Ctx, BR);
+}
+
+
+
+bool BasicObjCFoundationChecks::Audit(ExplodedNode* N,
+                                      GRStateManager&) {
+
+  const ObjCMessageExpr* ME =
+    cast<ObjCMessageExpr>(cast<PostStmt>(N->getLocation()).getStmt());
+
+  const ObjCInterfaceType *ReceiverType = GetReceiverType(ME);
+
+  if (!ReceiverType)
+    return false;
+
+  if (isNSString(ReceiverType,
+                 ReceiverType->getDecl()->getIdentifier()->getName()))
+    return AuditNSString(N, ME);
+
+  return false;
+}
+
+static inline bool isNil(SVal X) {
+  return isa<loc::ConcreteInt>(X);
+}
+
+//===----------------------------------------------------------------------===//
+// Error reporting.
+//===----------------------------------------------------------------------===//
+
+bool BasicObjCFoundationChecks::CheckNilArg(ExplodedNode* N, unsigned Arg) {
+  const ObjCMessageExpr* ME =
+    cast<ObjCMessageExpr>(cast<PostStmt>(N->getLocation()).getStmt());
+
+  const Expr * E = ME->getArg(Arg);
+
+  if (isNil(N->getState()->getSVal(E))) {
+    WarnNilArg(N, ME, Arg);
+    return true;
+  }
+
+  return false;
+}
+
+//===----------------------------------------------------------------------===//
+// NSString checking.
+//===----------------------------------------------------------------------===//
+
+bool BasicObjCFoundationChecks::isNSString(const ObjCInterfaceType *T,
+                                           llvm::StringRef ClassName) {
+  return ClassName == "NSString" || ClassName == "NSMutableString";
+}
+
+bool BasicObjCFoundationChecks::AuditNSString(ExplodedNode* N,
+                                              const ObjCMessageExpr* ME) {
+
+  Selector S = ME->getSelector();
+
+  if (S.isUnarySelector())
+    return false;
+
+  // FIXME: This is going to be really slow doing these checks with
+  //  lexical comparisons.
+
+  std::string NameStr = S.getAsString();
+  llvm::StringRef Name(NameStr);
+  assert(!Name.empty());
+
+  // FIXME: Checking for initWithFormat: will not work in most cases
+  //  yet because [NSString alloc] returns id, not NSString*.  We will
+  //  need support for tracking expected-type information in the analyzer
+  //  to find these errors.
+  if (Name == "caseInsensitiveCompare:" ||
+      Name == "compare:" ||
+      Name == "compare:options:" ||
+      Name == "compare:options:range:" ||
+      Name == "compare:options:range:locale:" ||
+      Name == "componentsSeparatedByCharactersInSet:" ||
+      Name == "initWithFormat:")
+    return CheckNilArg(N, 0);
+
+  return false;
+}
+
+//===----------------------------------------------------------------------===//
+// Error reporting.
+//===----------------------------------------------------------------------===//
+
+namespace {
+
+class AuditCFNumberCreate : public GRSimpleAPICheck {
+  APIMisuse* BT;
+
+  // FIXME: Either this should be refactored into GRSimpleAPICheck, or
+  //   it should always be passed with a call to Audit.  The latter
+  //   approach makes this class more stateless.
+  ASTContext& Ctx;
+  IdentifierInfo* II;
+  BugReporter& BR;
+
+public:
+  AuditCFNumberCreate(ASTContext& ctx, BugReporter& br)
+  : BT(0), Ctx(ctx), II(&Ctx.Idents.get("CFNumberCreate")), BR(br){}
+
+  ~AuditCFNumberCreate() {}
+
+  bool Audit(ExplodedNode* N, GRStateManager&);
+
+private:
+  void AddError(const TypedRegion* R, const Expr* Ex, ExplodedNode *N,
+                uint64_t SourceSize, uint64_t TargetSize, uint64_t NumberKind);
+};
+} // end anonymous namespace
+
+enum CFNumberType {
+  kCFNumberSInt8Type = 1,
+  kCFNumberSInt16Type = 2,
+  kCFNumberSInt32Type = 3,
+  kCFNumberSInt64Type = 4,
+  kCFNumberFloat32Type = 5,
+  kCFNumberFloat64Type = 6,
+  kCFNumberCharType = 7,
+  kCFNumberShortType = 8,
+  kCFNumberIntType = 9,
+  kCFNumberLongType = 10,
+  kCFNumberLongLongType = 11,
+  kCFNumberFloatType = 12,
+  kCFNumberDoubleType = 13,
+  kCFNumberCFIndexType = 14,
+  kCFNumberNSIntegerType = 15,
+  kCFNumberCGFloatType = 16
+};
+
+namespace {
+  template<typename T>
+  class Optional {
+    bool IsKnown;
+    T Val;
+  public:
+    Optional() : IsKnown(false), Val(0) {}
+    Optional(const T& val) : IsKnown(true), Val(val) {}
+
+    bool isKnown() const { return IsKnown; }
+
+    const T& getValue() const {
+      assert (isKnown());
+      return Val;
+    }
+
+    operator const T&() const {
+      return getValue();
+    }
+  };
+}
+
+static Optional<uint64_t> GetCFNumberSize(ASTContext& Ctx, uint64_t i) {
+  static const unsigned char FixedSize[] = { 8, 16, 32, 64, 32, 64 };
+
+  if (i < kCFNumberCharType)
+    return FixedSize[i-1];
+
+  QualType T;
+
+  switch (i) {
+    case kCFNumberCharType:     T = Ctx.CharTy;     break;
+    case kCFNumberShortType:    T = Ctx.ShortTy;    break;
+    case kCFNumberIntType:      T = Ctx.IntTy;      break;
+    case kCFNumberLongType:     T = Ctx.LongTy;     break;
+    case kCFNumberLongLongType: T = Ctx.LongLongTy; break;
+    case kCFNumberFloatType:    T = Ctx.FloatTy;    break;
+    case kCFNumberDoubleType:   T = Ctx.DoubleTy;   break;
+    case kCFNumberCFIndexType:
+    case kCFNumberNSIntegerType:
+    case kCFNumberCGFloatType:
+      // FIXME: We need a way to map from names to Type*.
+    default:
+      return Optional<uint64_t>();
+  }
+
+  return Ctx.getTypeSize(T);
+}
+
+#if 0
+static const char* GetCFNumberTypeStr(uint64_t i) {
+  static const char* Names[] = {
+    "kCFNumberSInt8Type",
+    "kCFNumberSInt16Type",
+    "kCFNumberSInt32Type",
+    "kCFNumberSInt64Type",
+    "kCFNumberFloat32Type",
+    "kCFNumberFloat64Type",
+    "kCFNumberCharType",
+    "kCFNumberShortType",
+    "kCFNumberIntType",
+    "kCFNumberLongType",
+    "kCFNumberLongLongType",
+    "kCFNumberFloatType",
+    "kCFNumberDoubleType",
+    "kCFNumberCFIndexType",
+    "kCFNumberNSIntegerType",
+    "kCFNumberCGFloatType"
+  };
+
+  return i <= kCFNumberCGFloatType ? Names[i-1] : "Invalid CFNumberType";
+}
+#endif
+
+bool AuditCFNumberCreate::Audit(ExplodedNode* N,GRStateManager&){
+  const CallExpr* CE =
+    cast<CallExpr>(cast<PostStmt>(N->getLocation()).getStmt());
+  const Expr* Callee = CE->getCallee();
+  SVal CallV = N->getState()->getSVal(Callee);
+  const FunctionDecl* FD = CallV.getAsFunctionDecl();
+
+  if (!FD || FD->getIdentifier() != II || CE->getNumArgs()!=3)
+    return false;
+
+  // Get the value of the "theType" argument.
+  SVal TheTypeVal = N->getState()->getSVal(CE->getArg(1));
+
+    // FIXME: We really should allow ranges of valid theType values, and
+    //   bifurcate the state appropriately.
+  nonloc::ConcreteInt* V = dyn_cast<nonloc::ConcreteInt>(&TheTypeVal);
+
+  if (!V)
+    return false;
+
+  uint64_t NumberKind = V->getValue().getLimitedValue();
+  Optional<uint64_t> TargetSize = GetCFNumberSize(Ctx, NumberKind);
+
+  // FIXME: In some cases we can emit an error.
+  if (!TargetSize.isKnown())
+    return false;
+
+  // Look at the value of the integer being passed by reference.  Essentially
+  // we want to catch cases where the value passed in is not equal to the
+  // size of the type being created.
+  SVal TheValueExpr = N->getState()->getSVal(CE->getArg(2));
+
+  // FIXME: Eventually we should handle arbitrary locations.  We can do this
+  //  by having an enhanced memory model that does low-level typing.
+  loc::MemRegionVal* LV = dyn_cast<loc::MemRegionVal>(&TheValueExpr);
+
+  if (!LV)
+    return false;
+
+  const TypedRegion* R = dyn_cast<TypedRegion>(LV->StripCasts());
+
+  if (!R)
+    return false;
+
+  QualType T = Ctx.getCanonicalType(R->getValueType(Ctx));
+
+  // FIXME: If the pointee isn't an integer type, should we flag a warning?
+  //  People can do weird stuff with pointers.
+
+  if (!T->isIntegerType())
+    return false;
+
+  uint64_t SourceSize = Ctx.getTypeSize(T);
+
+  // CHECK: is SourceSize == TargetSize
+
+  if (SourceSize == TargetSize)
+    return false;
+
+  AddError(R, CE->getArg(2), N, SourceSize, TargetSize, NumberKind);
+
+  // FIXME: We can actually create an abstract "CFNumber" object that has
+  //  the bits initialized to the provided values.
+  return SourceSize < TargetSize;
+}
+
+void AuditCFNumberCreate::AddError(const TypedRegion* R, const Expr* Ex,
+                                   ExplodedNode *N,
+                                   uint64_t SourceSize, uint64_t TargetSize,
+                                   uint64_t NumberKind) {
+
+  std::string sbuf;
+  llvm::raw_string_ostream os(sbuf);
+
+  os << (SourceSize == 8 ? "An " : "A ")
+     << SourceSize << " bit integer is used to initialize a CFNumber "
+        "object that represents "
+     << (TargetSize == 8 ? "an " : "a ")
+     << TargetSize << " bit integer. ";
+
+  if (SourceSize < TargetSize)
+    os << (TargetSize - SourceSize)
+       << " bits of the CFNumber value will be garbage." ;
+  else
+    os << (SourceSize - TargetSize)
+       << " bits of the input integer will be lost.";
+
+  // Lazily create the BugType object.  This will be owned
+  // by the BugReporter object 'BR' once we call BR.EmitWarning.
+  if (!BT) BT = new APIMisuse("Bad use of CFNumberCreate");
+  RangedBugReport *report = new RangedBugReport(*BT, os.str(), N);
+  report->addRange(Ex->getSourceRange());
+  BR.EmitReport(report);
+}
+
+GRSimpleAPICheck*
+clang::CreateAuditCFNumberCreate(ASTContext& Ctx, BugReporter& BR) {
+  return new AuditCFNumberCreate(Ctx, BR);
+}
+
+//===----------------------------------------------------------------------===//
+// CFRetain/CFRelease auditing for null arguments.
+//===----------------------------------------------------------------------===//
+
+namespace {
+class AuditCFRetainRelease : public GRSimpleAPICheck {
+  APIMisuse *BT;
+
+  // FIXME: Either this should be refactored into GRSimpleAPICheck, or
+  //   it should always be passed with a call to Audit.  The latter
+  //   approach makes this class more stateless.
+  ASTContext& Ctx;
+  IdentifierInfo *Retain, *Release;
+  BugReporter& BR;
+
+public:
+  AuditCFRetainRelease(ASTContext& ctx, BugReporter& br)
+  : BT(0), Ctx(ctx),
+    Retain(&Ctx.Idents.get("CFRetain")), Release(&Ctx.Idents.get("CFRelease")),
+    BR(br){}
+
+  ~AuditCFRetainRelease() {}
+
+  bool Audit(ExplodedNode* N, GRStateManager&);
+};
+} // end anonymous namespace
+
+
+bool AuditCFRetainRelease::Audit(ExplodedNode* N, GRStateManager&) {
+  const CallExpr* CE = cast<CallExpr>(cast<PostStmt>(N->getLocation()).getStmt());
+
+  // If the CallExpr doesn't have exactly 1 argument just give up checking.
+  if (CE->getNumArgs() != 1)
+    return false;
+
+  // Check if we called CFRetain/CFRelease.
+  const GRState* state = N->getState();
+  SVal X = state->getSVal(CE->getCallee());
+  const FunctionDecl* FD = X.getAsFunctionDecl();
+
+  if (!FD)
+    return false;
+
+  const IdentifierInfo *FuncII = FD->getIdentifier();
+  if (!(FuncII == Retain || FuncII == Release))
+    return false;
+
+  // Finally, check if the argument is NULL.
+  // FIXME: We should be able to bifurcate the state here, as a successful
+  // check will result in the value not being NULL afterwards.
+  // FIXME: Need a way to register vistors for the BugReporter.  Would like
+  // to benefit from the same diagnostics that regular null dereference
+  // reporting has.
+  if (state->getStateManager().isEqual(state, CE->getArg(0), 0)) {
+    if (!BT)
+      BT = new APIMisuse("null passed to CFRetain/CFRelease");
+
+    const char *description = (FuncII == Retain)
+                            ? "Null pointer argument in call to CFRetain"
+                            : "Null pointer argument in call to CFRelease";
+
+    RangedBugReport *report = new RangedBugReport(*BT, description, N);
+    report->addRange(CE->getArg(0)->getSourceRange());
+    BR.EmitReport(report);
+    return true;
+  }
+
+  return false;
+}
+
+
+GRSimpleAPICheck*
+clang::CreateAuditCFRetainRelease(ASTContext& Ctx, BugReporter& BR) {
+  return new AuditCFRetainRelease(Ctx, BR);
+}
+
+//===----------------------------------------------------------------------===//
+// Check for sending 'retain', 'release', or 'autorelease' directly to a Class.
+//===----------------------------------------------------------------------===//
+
+namespace {
+class ClassReleaseChecker :
+    public CheckerVisitor<ClassReleaseChecker> {
+  Selector releaseS;
+  Selector retainS;
+  Selector autoreleaseS;
+  Selector drainS;
+  BugType *BT;
+public:
+  ClassReleaseChecker(ASTContext &Ctx)
+    : releaseS(GetNullarySelector("release", Ctx)),
+      retainS(GetNullarySelector("retain", Ctx)),
+      autoreleaseS(GetNullarySelector("autorelease", Ctx)),
+      drainS(GetNullarySelector("drain", Ctx)),
+      BT(0) {}
+
+  static void *getTag() { static int x = 0; return &x; }
+      
+  void PreVisitObjCMessageExpr(CheckerContext &C, const ObjCMessageExpr *ME);    
+};
+}
+
+void ClassReleaseChecker::PreVisitObjCMessageExpr(CheckerContext &C,
+                                                  const ObjCMessageExpr *ME) {
+  ObjCInterfaceDecl *Class = 0;
+  switch (ME->getReceiverKind()) {
+  case ObjCMessageExpr::Class:
+    Class = ME->getClassReceiver()->getAs<ObjCInterfaceType>()->getDecl();
+    break;
+
+  case ObjCMessageExpr::SuperClass:
+    Class = ME->getSuperType()->getAs<ObjCInterfaceType>()->getDecl();
+    break;
+
+  case ObjCMessageExpr::Instance:
+  case ObjCMessageExpr::SuperInstance:
+    return;
+  }
+
+  Selector S = ME->getSelector();
+  if (!(S == releaseS || S == retainS || S == autoreleaseS || S == drainS))
+    return;
+  
+  if (!BT)
+    BT = new APIMisuse("message incorrectly sent to class instead of class "
+                       "instance");
+  
+  ExplodedNode *N = C.GenerateNode();
+
+  if (!N)
+    return;
+  
+  llvm::SmallString<200> buf;
+  llvm::raw_svector_ostream os(buf);
+
+  os << "The '" << S.getAsString() << "' message should be sent to instances "
+        "of class '" << Class->getName()
+     << "' and not the class directly";
+  
+  RangedBugReport *report = new RangedBugReport(*BT, os.str(), N);
+  report->addRange(ME->getSourceRange());
+  C.EmitReport(report);
+}
+
+//===----------------------------------------------------------------------===//
+// Check registration.
+//===----------------------------------------------------------------------===//
+
+void clang::RegisterAppleChecks(GRExprEngine& Eng, const Decl &D) {
+  ASTContext& Ctx = Eng.getContext();
+  BugReporter &BR = Eng.getBugReporter();
+
+  Eng.AddCheck(CreateBasicObjCFoundationChecks(Ctx, BR),
+               Stmt::ObjCMessageExprClass);
+  Eng.AddCheck(CreateAuditCFNumberCreate(Ctx, BR), Stmt::CallExprClass);
+  Eng.AddCheck(CreateAuditCFRetainRelease(Ctx, BR), Stmt::CallExprClass);
+
+  RegisterNSErrorChecks(BR, Eng, D);
+  RegisterNSAutoreleasePoolChecks(Eng);
+  Eng.registerCheck(new ClassReleaseChecker(Ctx));
+}
diff --git a/lib/Checker/BasicObjCFoundationChecks.h b/lib/Checker/BasicObjCFoundationChecks.h
new file mode 100644
index 0000000..679c6dc
--- /dev/null
+++ b/lib/Checker/BasicObjCFoundationChecks.h
@@ -0,0 +1,41 @@
+//== BasicObjCFoundationChecks.h - Simple Apple-Foundation checks -*- C++ -*--//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines BasicObjCFoundationChecks, a class that encapsulates
+//  a set of simple checks to run on Objective-C code using Apple's Foundation
+//  classes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_BASICOBJCFOUNDATIONCHECKS
+#define LLVM_CLANG_ANALYSIS_BASICOBJCFOUNDATIONCHECKS
+
+namespace clang {
+
+class ASTContext;
+class BugReporter;
+class Decl;
+class GRExprEngine;
+class GRSimpleAPICheck;
+
+GRSimpleAPICheck *CreateBasicObjCFoundationChecks(ASTContext& Ctx,
+                                                  BugReporter& BR);
+
+GRSimpleAPICheck *CreateAuditCFNumberCreate(ASTContext& Ctx,
+                                            BugReporter& BR);
+
+GRSimpleAPICheck *CreateAuditCFRetainRelease(ASTContext& Ctx,
+                                             BugReporter& BR);
+
+void RegisterNSErrorChecks(BugReporter& BR, GRExprEngine &Eng, const Decl &D);
+void RegisterNSAutoreleasePoolChecks(GRExprEngine &Eng);
+
+} // end clang namespace
+
+#endif
diff --git a/lib/Checker/BasicStore.cpp b/lib/Checker/BasicStore.cpp
new file mode 100644
index 0000000..34470af
--- /dev/null
+++ b/lib/Checker/BasicStore.cpp
@@ -0,0 +1,508 @@
+//== BasicStore.cpp - Basic map from Locations to Values --------*- C++ -*--==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defined the BasicStore and BasicStoreManager classes.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/ExprObjC.h"
+#include "clang/Analysis/Analyses/LiveVariables.h"
+#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Checker/PathSensitive/GRState.h"
+#include "llvm/ADT/ImmutableMap.h"
+
+using namespace clang;
+
+typedef llvm::ImmutableMap<const MemRegion*,SVal> BindingsTy;
+
+namespace {
+
+class BasicStoreSubRegionMap : public SubRegionMap {
+public:
+  BasicStoreSubRegionMap() {}
+
+  bool iterSubRegions(const MemRegion* R, Visitor& V) const {
+    return true; // Do nothing.  No subregions.
+  }
+};
+
+class BasicStoreManager : public StoreManager {
+  BindingsTy::Factory VBFactory;
+public:
+  BasicStoreManager(GRStateManager& mgr)
+    : StoreManager(mgr), VBFactory(mgr.getAllocator()) {}
+
+  ~BasicStoreManager() {}
+
+  SubRegionMap *getSubRegionMap(Store store) {
+    return new BasicStoreSubRegionMap();
+  }
+
+  SVal Retrieve(Store store, Loc loc, QualType T = QualType());
+
+  Store InvalidateRegion(Store store, const MemRegion *R, const Expr *E, 
+                         unsigned Count, InvalidatedSymbols *IS);
+
+  Store scanForIvars(Stmt *B, const Decl* SelfDecl,
+                     const MemRegion *SelfRegion, Store St);
+
+  Store Bind(Store St, Loc loc, SVal V);
+  Store Remove(Store St, Loc loc);
+  Store getInitialStore(const LocationContext *InitLoc);
+
+  // FIXME: Investigate what is using this. This method should be removed.
+  virtual Loc getLoc(const VarDecl* VD, const LocationContext *LC) {
+    return ValMgr.makeLoc(MRMgr.getVarRegion(VD, LC));
+  }
+
+  Store BindCompoundLiteral(Store store, const CompoundLiteralExpr*,
+                            const LocationContext*, SVal val) {
+    return store;
+  }
+
+  /// ArrayToPointer - Used by GRExprEngine::VistCast to handle implicit
+  ///  conversions between arrays and pointers.
+  SVal ArrayToPointer(Loc Array) { return Array; }
+
+  /// RemoveDeadBindings - Scans a BasicStore of 'state' for dead values.
+  ///  It updatees the GRState object in place with the values removed.
+  Store RemoveDeadBindings(Store store, Stmt* Loc, 
+                           const StackFrameContext *LCtx,
+                           SymbolReaper& SymReaper,
+                          llvm::SmallVectorImpl<const MemRegion*>& RegionRoots);
+
+  void iterBindings(Store store, BindingsHandler& f);
+
+  Store BindDecl(Store store, const VarRegion *VR, SVal InitVal) {
+    return BindDeclInternal(store, VR, &InitVal);
+  }
+
+  Store BindDeclWithNoInit(Store store, const VarRegion *VR) {
+    return BindDeclInternal(store, VR, 0);
+  }
+
+  Store BindDeclInternal(Store store, const VarRegion *VR, SVal *InitVal);
+
+  static inline BindingsTy GetBindings(Store store) {
+    return BindingsTy(static_cast<const BindingsTy::TreeTy*>(store));
+  }
+
+  void print(Store store, llvm::raw_ostream& Out, const char* nl,
+             const char *sep);
+
+private:
+  SVal LazyRetrieve(Store store, const TypedRegion *R);
+
+  ASTContext& getContext() { return StateMgr.getContext(); }
+};
+
+} // end anonymous namespace
+
+
+StoreManager* clang::CreateBasicStoreManager(GRStateManager& StMgr) {
+  return new BasicStoreManager(StMgr);
+}
+
+static bool isHigherOrderRawPtr(QualType T, ASTContext &C) {
+  bool foundPointer = false;
+  while (1) {
+    const PointerType *PT = T->getAs<PointerType>();
+    if (!PT) {
+      if (!foundPointer)
+        return false;
+
+      // intptr_t* or intptr_t**, etc?
+      if (T->isIntegerType() && C.getTypeSize(T) == C.getTypeSize(C.VoidPtrTy))
+        return true;
+
+      QualType X = C.getCanonicalType(T).getUnqualifiedType();
+      return X == C.VoidTy;
+    }
+
+    foundPointer = true;
+    T = PT->getPointeeType();
+  }
+}
+
+SVal BasicStoreManager::LazyRetrieve(Store store, const TypedRegion *R) {
+  const VarRegion *VR = dyn_cast<VarRegion>(R);
+  if (!VR)
+    return UnknownVal();
+
+  const VarDecl *VD = VR->getDecl();
+  QualType T = VD->getType();
+
+  // Only handle simple types that we can symbolicate.
+  if (!SymbolManager::canSymbolicate(T) || !T->isScalarType())
+    return UnknownVal();
+
+  // Globals and parameters start with symbolic values.
+  // Local variables initially are undefined.
+  if (VR->hasGlobalsOrParametersStorage() ||
+      isa<UnknownSpaceRegion>(VR->getMemorySpace()))
+    return ValMgr.getRegionValueSymbolVal(R);
+  return UndefinedVal();
+}
+
+SVal BasicStoreManager::Retrieve(Store store, Loc loc, QualType T) {
+  if (isa<UnknownVal>(loc))
+    return UnknownVal();
+
+  assert(!isa<UndefinedVal>(loc));
+
+  switch (loc.getSubKind()) {
+
+    case loc::MemRegionKind: {
+      const MemRegion* R = cast<loc::MemRegionVal>(loc).getRegion();
+
+      if (!(isa<VarRegion>(R) || isa<ObjCIvarRegion>(R)))
+        return UnknownVal();
+
+      BindingsTy B = GetBindings(store);
+      BindingsTy::data_type *Val = B.lookup(R);
+      const TypedRegion *TR = cast<TypedRegion>(R);
+
+      if (Val)
+        return CastRetrievedVal(*Val, TR, T);
+
+      SVal V = LazyRetrieve(store, TR);
+      return V.isUnknownOrUndef() ? V : CastRetrievedVal(V, TR, T);
+    }
+
+    case loc::ConcreteIntKind:
+      // Some clients may call GetSVal with such an option simply because
+      // they are doing a quick scan through their Locs (potentially to
+      // invalidate their bindings).  Just return Undefined.
+      return UndefinedVal();
+
+    default:
+      assert (false && "Invalid Loc.");
+      break;
+  }
+
+  return UnknownVal();
+}
+
+Store BasicStoreManager::Bind(Store store, Loc loc, SVal V) {
+  if (isa<loc::ConcreteInt>(loc))
+    return store;
+
+  const MemRegion* R = cast<loc::MemRegionVal>(loc).getRegion();
+  ASTContext &C = StateMgr.getContext();
+
+  // Special case: handle store of pointer values (Loc) to pointers via
+  // a cast to intXX_t*, void*, etc.  This is needed to handle
+  // OSCompareAndSwap32Barrier/OSCompareAndSwap64Barrier.
+  if (isa<Loc>(V) || isa<nonloc::LocAsInteger>(V))
+    if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
+      // FIXME: Should check for index 0.
+      QualType T = ER->getLocationType(C);
+
+      if (isHigherOrderRawPtr(T, C))
+        R = ER->getSuperRegion();
+    }
+
+  if (!(isa<VarRegion>(R) || isa<ObjCIvarRegion>(R)))
+    return store;
+
+  const TypedRegion *TyR = cast<TypedRegion>(R);
+
+  // Do not bind to arrays.  We need to explicitly check for this so that
+  // we do not encounter any weirdness of trying to load/store from arrays.
+  if (TyR->isBoundable() && TyR->getValueType(C)->isArrayType())
+    return store;
+
+  if (nonloc::LocAsInteger *X = dyn_cast<nonloc::LocAsInteger>(&V)) {
+    // Only convert 'V' to a location iff the underlying region type
+    // is a location as well.
+    // FIXME: We are allowing a store of an arbitrary location to
+    // a pointer.  We may wish to flag a type error here if the types
+    // are incompatible.  This may also cause lots of breakage
+    // elsewhere. Food for thought.
+    if (TyR->isBoundable() && Loc::IsLocType(TyR->getValueType(C)))
+      V = X->getLoc();
+  }
+
+  BindingsTy B = GetBindings(store);
+  return V.isUnknown()
+    ? VBFactory.Remove(B, R).getRoot()
+    : VBFactory.Add(B, R, V).getRoot();
+}
+
+Store BasicStoreManager::Remove(Store store, Loc loc) {
+  switch (loc.getSubKind()) {
+    case loc::MemRegionKind: {
+      const MemRegion* R = cast<loc::MemRegionVal>(loc).getRegion();
+
+      if (!(isa<VarRegion>(R) || isa<ObjCIvarRegion>(R)))
+        return store;
+
+      return VBFactory.Remove(GetBindings(store), R).getRoot();
+    }
+    default:
+      assert ("Remove for given Loc type not yet implemented.");
+      return store;
+  }
+}
+
+Store BasicStoreManager::RemoveDeadBindings(Store store, Stmt* Loc,
+                                            const StackFrameContext *LCtx,
+                                            SymbolReaper& SymReaper,
+                           llvm::SmallVectorImpl<const MemRegion*>& RegionRoots)
+{
+  BindingsTy B = GetBindings(store);
+  typedef SVal::symbol_iterator symbol_iterator;
+
+  // Iterate over the variable bindings.
+  for (BindingsTy::iterator I=B.begin(), E=B.end(); I!=E ; ++I) {
+    if (const VarRegion *VR = dyn_cast<VarRegion>(I.getKey())) {
+      if (SymReaper.isLive(Loc, VR))
+        RegionRoots.push_back(VR);
+      else
+        continue;
+    }
+    else if (isa<ObjCIvarRegion>(I.getKey())) {
+      RegionRoots.push_back(I.getKey());
+    }
+    else
+      continue;
+
+    // Mark the bindings in the data as live.
+    SVal X = I.getData();
+    for (symbol_iterator SI=X.symbol_begin(), SE=X.symbol_end(); SI!=SE; ++SI)
+      SymReaper.markLive(*SI);
+  }
+
+  // Scan for live variables and live symbols.
+  llvm::SmallPtrSet<const MemRegion*, 10> Marked;
+
+  while (!RegionRoots.empty()) {
+    const MemRegion* MR = RegionRoots.back();
+    RegionRoots.pop_back();
+
+    while (MR) {
+      if (const SymbolicRegion* SymR = dyn_cast<SymbolicRegion>(MR)) {
+        SymReaper.markLive(SymR->getSymbol());
+        break;
+      }
+      else if (isa<VarRegion>(MR) || isa<ObjCIvarRegion>(MR)) {
+        if (Marked.count(MR))
+          break;
+
+        Marked.insert(MR);
+        SVal X = Retrieve(store, loc::MemRegionVal(MR));
+
+        // FIXME: We need to handle symbols nested in region definitions.
+        for (symbol_iterator SI=X.symbol_begin(),SE=X.symbol_end();SI!=SE;++SI)
+          SymReaper.markLive(*SI);
+
+        if (!isa<loc::MemRegionVal>(X))
+          break;
+
+        const loc::MemRegionVal& LVD = cast<loc::MemRegionVal>(X);
+        RegionRoots.push_back(LVD.getRegion());
+        break;
+      }
+      else if (const SubRegion* R = dyn_cast<SubRegion>(MR))
+        MR = R->getSuperRegion();
+      else
+        break;
+    }
+  }
+
+  // Remove dead variable bindings.
+  for (BindingsTy::iterator I=B.begin(), E=B.end(); I!=E ; ++I) {
+    const MemRegion* R = I.getKey();
+
+    if (!Marked.count(R)) {
+      store = Remove(store, ValMgr.makeLoc(R));
+      SVal X = I.getData();
+
+      for (symbol_iterator SI=X.symbol_begin(), SE=X.symbol_end(); SI!=SE; ++SI)
+        SymReaper.maybeDead(*SI);
+    }
+  }
+
+  return store;
+}
+
+Store BasicStoreManager::scanForIvars(Stmt *B, const Decl* SelfDecl,
+                                      const MemRegion *SelfRegion, Store St) {
+  for (Stmt::child_iterator CI=B->child_begin(), CE=B->child_end();
+       CI != CE; ++CI) {
+
+    if (!*CI)
+      continue;
+
+    // Check if the statement is an ivar reference.  We only
+    // care about self.ivar.
+    if (ObjCIvarRefExpr *IV = dyn_cast<ObjCIvarRefExpr>(*CI)) {
+      const Expr *Base = IV->getBase()->IgnoreParenCasts();
+      if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Base)) {
+        if (DR->getDecl() == SelfDecl) {
+          const ObjCIvarRegion *IVR = MRMgr.getObjCIvarRegion(IV->getDecl(),
+                                                         SelfRegion);
+          SVal X = ValMgr.getRegionValueSymbolVal(IVR);
+          St = Bind(St, ValMgr.makeLoc(IVR), X);
+        }
+      }
+    }
+    else
+      St = scanForIvars(*CI, SelfDecl, SelfRegion, St);
+  }
+
+  return St;
+}
+
+Store BasicStoreManager::getInitialStore(const LocationContext *InitLoc) {
+  // The LiveVariables information already has a compilation of all VarDecls
+  // used in the function.  Iterate through this set, and "symbolicate"
+  // any VarDecl whose value originally comes from outside the function.
+  typedef LiveVariables::AnalysisDataTy LVDataTy;
+  LVDataTy& D = InitLoc->getLiveVariables()->getAnalysisData();
+  Store St = VBFactory.GetEmptyMap().getRoot();
+
+  for (LVDataTy::decl_iterator I=D.begin_decl(), E=D.end_decl(); I != E; ++I) {
+    NamedDecl* ND = const_cast<NamedDecl*>(I->first);
+
+    // Handle implicit parameters.
+    if (ImplicitParamDecl* PD = dyn_cast<ImplicitParamDecl>(ND)) {
+      const Decl& CD = *InitLoc->getDecl();
+      if (const ObjCMethodDecl* MD = dyn_cast<ObjCMethodDecl>(&CD)) {
+        if (MD->getSelfDecl() == PD) {
+          // FIXME: Add type constraints (when they become available) to
+          // SelfRegion?  (i.e., it implements MD->getClassInterface()).
+          const VarRegion *VR = MRMgr.getVarRegion(PD, InitLoc);
+          const MemRegion *SelfRegion =
+            ValMgr.getRegionValueSymbolVal(VR).getAsRegion();
+          assert(SelfRegion);
+          St = Bind(St, ValMgr.makeLoc(VR), loc::MemRegionVal(SelfRegion));
+          // Scan the method for ivar references.  While this requires an
+          // entire AST scan, the cost should not be high in practice.
+          St = scanForIvars(MD->getBody(), PD, SelfRegion, St);
+        }
+      }
+    }
+  }
+
+  return St;
+}
+
+Store BasicStoreManager::BindDeclInternal(Store store, const VarRegion* VR,
+                                          SVal* InitVal) {
+
+  BasicValueFactory& BasicVals = StateMgr.getBasicVals();
+  const VarDecl *VD = VR->getDecl();
+
+  // BasicStore does not model arrays and structs.
+  if (VD->getType()->isArrayType() || VD->getType()->isStructureOrClassType())
+    return store;
+
+  if (VD->hasGlobalStorage()) {
+    // Handle variables with global storage: extern, static, PrivateExtern.
+
+    // FIXME:: static variables may have an initializer, but the second time a
+    // function is called those values may not be current. Currently, a function
+    // will not be called more than once.
+
+    // Static global variables should not be visited here.
+    assert(!(VD->getStorageClass() == VarDecl::Static &&
+             VD->isFileVarDecl()));
+
+    // Process static variables.
+    if (VD->getStorageClass() == VarDecl::Static) {
+      // C99: 6.7.8 Initialization
+      //  If an object that has static storage duration is not initialized
+      //  explicitly, then:
+      //   —if it has pointer type, it is initialized to a null pointer;
+      //   —if it has arithmetic type, it is initialized to (positive or
+      //     unsigned) zero;
+      if (!InitVal) {
+        QualType T = VD->getType();
+        if (Loc::IsLocType(T))
+          store = Bind(store, loc::MemRegionVal(VR),
+                       loc::ConcreteInt(BasicVals.getValue(0, T)));
+        else if (T->isIntegerType())
+          store = Bind(store, loc::MemRegionVal(VR),
+                       nonloc::ConcreteInt(BasicVals.getValue(0, T)));
+        else {
+          // assert(0 && "ignore other types of variables");
+        }
+      } else {
+        store = Bind(store, loc::MemRegionVal(VR), *InitVal);
+      }
+    }
+  } else {
+    // Process local scalar variables.
+    QualType T = VD->getType();
+    if (ValMgr.getSymbolManager().canSymbolicate(T)) {
+      SVal V = InitVal ? *InitVal : UndefinedVal();
+      store = Bind(store, loc::MemRegionVal(VR), V);
+    }
+  }
+
+  return store;
+}
+
+void BasicStoreManager::print(Store store, llvm::raw_ostream& Out,
+                              const char* nl, const char *sep) {
+
+  BindingsTy B = GetBindings(store);
+  Out << "Variables:" << nl;
+
+  bool isFirst = true;
+
+  for (BindingsTy::iterator I=B.begin(), E=B.end(); I != E; ++I) {
+    if (isFirst)
+      isFirst = false;
+    else
+      Out << nl;
+
+    Out << ' ' << I.getKey() << " : " << I.getData();
+  }
+}
+
+
+void BasicStoreManager::iterBindings(Store store, BindingsHandler& f) {
+  BindingsTy B = GetBindings(store);
+
+  for (BindingsTy::iterator I=B.begin(), E=B.end(); I != E; ++I)
+    f.HandleBinding(*this, store, I.getKey(), I.getData());
+
+}
+
+StoreManager::BindingsHandler::~BindingsHandler() {}
+
+//===----------------------------------------------------------------------===//
+// Binding invalidation.
+//===----------------------------------------------------------------------===//
+
+Store BasicStoreManager::InvalidateRegion(Store store,
+                                          const MemRegion *R,
+                                          const Expr *E,
+                                          unsigned Count,
+                                          InvalidatedSymbols *IS) {
+  R = R->StripCasts();
+
+  if (!(isa<VarRegion>(R) || isa<ObjCIvarRegion>(R)))
+      return store;
+
+  if (IS) {
+    BindingsTy B = GetBindings(store);
+    if (BindingsTy::data_type *Val = B.lookup(R)) {
+      if (SymbolRef Sym = Val->getAsSymbol())
+        IS->insert(Sym);
+    }
+  }
+
+  QualType T = cast<TypedRegion>(R)->getValueType(R->getContext());
+  SVal V = ValMgr.getConjuredSymbolVal(R, E, T, Count);
+  return Bind(store, loc::MemRegionVal(R), V);
+}
+
diff --git a/lib/Checker/BasicValueFactory.cpp b/lib/Checker/BasicValueFactory.cpp
new file mode 100644
index 0000000..246beea
--- /dev/null
+++ b/lib/Checker/BasicValueFactory.cpp
@@ -0,0 +1,289 @@
+//=== BasicValueFactory.cpp - Basic values for Path Sens analysis --*- C++ -*-//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines BasicValueFactory, a class that manages the lifetime
+//  of APSInt objects and symbolic constraints used by GRExprEngine
+//  and related classes.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Checker/PathSensitive/BasicValueFactory.h"
+
+using namespace clang;
+
+void CompoundValData::Profile(llvm::FoldingSetNodeID& ID, QualType T,
+                              llvm::ImmutableList<SVal> L) {
+  T.Profile(ID);
+  ID.AddPointer(L.getInternalPointer());
+}
+
+void LazyCompoundValData::Profile(llvm::FoldingSetNodeID& ID,
+                                  const void *store,const TypedRegion *region) {
+  ID.AddPointer(store);
+  ID.AddPointer(region);
+}
+
+typedef std::pair<SVal, uintptr_t> SValData;
+typedef std::pair<SVal, SVal> SValPair;
+
+namespace llvm {
+template<> struct FoldingSetTrait<SValData> {
+  static inline void Profile(const SValData& X, llvm::FoldingSetNodeID& ID) {
+    X.first.Profile(ID);
+    ID.AddPointer( (void*) X.second);
+  }
+};
+
+template<> struct FoldingSetTrait<SValPair> {
+  static inline void Profile(const SValPair& X, llvm::FoldingSetNodeID& ID) {
+    X.first.Profile(ID);
+    X.second.Profile(ID);
+  }
+};
+}
+
+typedef llvm::FoldingSet<llvm::FoldingSetNodeWrapper<SValData> >
+  PersistentSValsTy;
+
+typedef llvm::FoldingSet<llvm::FoldingSetNodeWrapper<SValPair> >
+  PersistentSValPairsTy;
+
+BasicValueFactory::~BasicValueFactory() {
+  // Note that the dstor for the contents of APSIntSet will never be called,
+  // so we iterate over the set and invoke the dstor for each APSInt.  This
+  // frees an aux. memory allocated to represent very large constants.
+  for (APSIntSetTy::iterator I=APSIntSet.begin(), E=APSIntSet.end(); I!=E; ++I)
+    I->getValue().~APSInt();
+
+  delete (PersistentSValsTy*) PersistentSVals;
+  delete (PersistentSValPairsTy*) PersistentSValPairs;
+}
+
+const llvm::APSInt& BasicValueFactory::getValue(const llvm::APSInt& X) {
+  llvm::FoldingSetNodeID ID;
+  void* InsertPos;
+  typedef llvm::FoldingSetNodeWrapper<llvm::APSInt> FoldNodeTy;
+
+  X.Profile(ID);
+  FoldNodeTy* P = APSIntSet.FindNodeOrInsertPos(ID, InsertPos);
+
+  if (!P) {
+    P = (FoldNodeTy*) BPAlloc.Allocate<FoldNodeTy>();
+    new (P) FoldNodeTy(X);
+    APSIntSet.InsertNode(P, InsertPos);
+  }
+
+  return *P;
+}
+
+const llvm::APSInt& BasicValueFactory::getValue(const llvm::APInt& X,
+                                                bool isUnsigned) {
+  llvm::APSInt V(X, isUnsigned);
+  return getValue(V);
+}
+
+const llvm::APSInt& BasicValueFactory::getValue(uint64_t X, unsigned BitWidth,
+                                           bool isUnsigned) {
+  llvm::APSInt V(BitWidth, isUnsigned);
+  V = X;
+  return getValue(V);
+}
+
+const llvm::APSInt& BasicValueFactory::getValue(uint64_t X, QualType T) {
+
+  unsigned bits = Ctx.getTypeSize(T);
+  llvm::APSInt V(bits, T->isUnsignedIntegerType() || Loc::IsLocType(T));
+  V = X;
+  return getValue(V);
+}
+
+const CompoundValData*
+BasicValueFactory::getCompoundValData(QualType T,
+                                      llvm::ImmutableList<SVal> Vals) {
+
+  llvm::FoldingSetNodeID ID;
+  CompoundValData::Profile(ID, T, Vals);
+  void* InsertPos;
+
+  CompoundValData* D = CompoundValDataSet.FindNodeOrInsertPos(ID, InsertPos);
+
+  if (!D) {
+    D = (CompoundValData*) BPAlloc.Allocate<CompoundValData>();
+    new (D) CompoundValData(T, Vals);
+    CompoundValDataSet.InsertNode(D, InsertPos);
+  }
+
+  return D;
+}
+
+const LazyCompoundValData*
+BasicValueFactory::getLazyCompoundValData(const void *store,
+                                          const TypedRegion *region) {
+  llvm::FoldingSetNodeID ID;
+  LazyCompoundValData::Profile(ID, store, region);
+  void* InsertPos;
+
+  LazyCompoundValData *D =
+    LazyCompoundValDataSet.FindNodeOrInsertPos(ID, InsertPos);
+
+  if (!D) {
+    D = (LazyCompoundValData*) BPAlloc.Allocate<LazyCompoundValData>();
+    new (D) LazyCompoundValData(store, region);
+    LazyCompoundValDataSet.InsertNode(D, InsertPos);
+  }
+
+  return D;
+}
+
+const llvm::APSInt*
+BasicValueFactory::EvaluateAPSInt(BinaryOperator::Opcode Op,
+                             const llvm::APSInt& V1, const llvm::APSInt& V2) {
+
+  switch (Op) {
+    default:
+      assert (false && "Invalid Opcode.");
+
+    case BinaryOperator::Mul:
+      return &getValue( V1 * V2 );
+
+    case BinaryOperator::Div:
+      return &getValue( V1 / V2 );
+
+    case BinaryOperator::Rem:
+      return &getValue( V1 % V2 );
+
+    case BinaryOperator::Add:
+      return &getValue( V1 + V2 );
+
+    case BinaryOperator::Sub:
+      return &getValue( V1 - V2 );
+
+    case BinaryOperator::Shl: {
+
+      // FIXME: This logic should probably go higher up, where we can
+      // test these conditions symbolically.
+
+      // FIXME: Expand these checks to include all undefined behavior.
+
+      if (V2.isSigned() && V2.isNegative())
+        return NULL;
+
+      uint64_t Amt = V2.getZExtValue();
+
+      if (Amt > V1.getBitWidth())
+        return NULL;
+
+      return &getValue( V1.operator<<( (unsigned) Amt ));
+    }
+
+    case BinaryOperator::Shr: {
+
+      // FIXME: This logic should probably go higher up, where we can
+      // test these conditions symbolically.
+
+      // FIXME: Expand these checks to include all undefined behavior.
+
+      if (V2.isSigned() && V2.isNegative())
+        return NULL;
+
+      uint64_t Amt = V2.getZExtValue();
+
+      if (Amt > V1.getBitWidth())
+        return NULL;
+
+      return &getValue( V1.operator>>( (unsigned) Amt ));
+    }
+
+    case BinaryOperator::LT:
+      return &getTruthValue( V1 < V2 );
+
+    case BinaryOperator::GT:
+      return &getTruthValue( V1 > V2 );
+
+    case BinaryOperator::LE:
+      return &getTruthValue( V1 <= V2 );
+
+    case BinaryOperator::GE:
+      return &getTruthValue( V1 >= V2 );
+
+    case BinaryOperator::EQ:
+      return &getTruthValue( V1 == V2 );
+
+    case BinaryOperator::NE:
+      return &getTruthValue( V1 != V2 );
+
+      // Note: LAnd, LOr, Comma are handled specially by higher-level logic.
+
+    case BinaryOperator::And:
+      return &getValue( V1 & V2 );
+
+    case BinaryOperator::Or:
+      return &getValue( V1 | V2 );
+
+    case BinaryOperator::Xor:
+      return &getValue( V1 ^ V2 );
+  }
+}
+
+
+const std::pair<SVal, uintptr_t>&
+BasicValueFactory::getPersistentSValWithData(const SVal& V, uintptr_t Data) {
+
+  // Lazily create the folding set.
+  if (!PersistentSVals) PersistentSVals = new PersistentSValsTy();
+
+  llvm::FoldingSetNodeID ID;
+  void* InsertPos;
+  V.Profile(ID);
+  ID.AddPointer((void*) Data);
+
+  PersistentSValsTy& Map = *((PersistentSValsTy*) PersistentSVals);
+
+  typedef llvm::FoldingSetNodeWrapper<SValData> FoldNodeTy;
+  FoldNodeTy* P = Map.FindNodeOrInsertPos(ID, InsertPos);
+
+  if (!P) {
+    P = (FoldNodeTy*) BPAlloc.Allocate<FoldNodeTy>();
+    new (P) FoldNodeTy(std::make_pair(V, Data));
+    Map.InsertNode(P, InsertPos);
+  }
+
+  return P->getValue();
+}
+
+const std::pair<SVal, SVal>&
+BasicValueFactory::getPersistentSValPair(const SVal& V1, const SVal& V2) {
+
+  // Lazily create the folding set.
+  if (!PersistentSValPairs) PersistentSValPairs = new PersistentSValPairsTy();
+
+  llvm::FoldingSetNodeID ID;
+  void* InsertPos;
+  V1.Profile(ID);
+  V2.Profile(ID);
+
+  PersistentSValPairsTy& Map = *((PersistentSValPairsTy*) PersistentSValPairs);
+
+  typedef llvm::FoldingSetNodeWrapper<SValPair> FoldNodeTy;
+  FoldNodeTy* P = Map.FindNodeOrInsertPos(ID, InsertPos);
+
+  if (!P) {
+    P = (FoldNodeTy*) BPAlloc.Allocate<FoldNodeTy>();
+    new (P) FoldNodeTy(std::make_pair(V1, V2));
+    Map.InsertNode(P, InsertPos);
+  }
+
+  return P->getValue();
+}
+
+const SVal* BasicValueFactory::getPersistentSVal(SVal X) {
+  return &getPersistentSValWithData(X, 0).first;
+}
+
+
diff --git a/lib/Checker/BugReporter.cpp b/lib/Checker/BugReporter.cpp
new file mode 100644
index 0000000..3bcc03f
--- /dev/null
+++ b/lib/Checker/BugReporter.cpp
@@ -0,0 +1,1896 @@
+// BugReporter.cpp - Generate PathDiagnostics for Bugs ------------*- C++ -*--//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines BugReporter, a utility class for generating
+//  PathDiagnostics.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Checker/BugReporter/BugReporter.h"
+#include "clang/Checker/BugReporter/BugType.h"
+#include "clang/Checker/PathSensitive/GRExprEngine.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/Analysis/CFG.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/ParentMap.h"
+#include "clang/AST/StmtObjC.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Analysis/ProgramPoint.h"
+#include "clang/Checker/BugReporter/PathDiagnostic.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/OwningPtr.h"
+#include <queue>
+
+using namespace clang;
+
+BugReporterVisitor::~BugReporterVisitor() {}
+BugReporterContext::~BugReporterContext() {
+  for (visitor_iterator I = visitor_begin(), E = visitor_end(); I != E; ++I)
+    if ((*I)->isOwnedByReporterContext()) delete *I;
+}
+
+void BugReporterContext::addVisitor(BugReporterVisitor* visitor) {
+  if (!visitor)
+    return;
+
+  llvm::FoldingSetNodeID ID;
+  visitor->Profile(ID);
+  void *InsertPos;
+
+  if (CallbacksSet.FindNodeOrInsertPos(ID, InsertPos)) {
+    delete visitor;
+    return;
+  }
+
+  CallbacksSet.InsertNode(visitor, InsertPos);
+  Callbacks = F.Add(visitor, Callbacks);
+}
+
+//===----------------------------------------------------------------------===//
+// Helper routines for walking the ExplodedGraph and fetching statements.
+//===----------------------------------------------------------------------===//
+
+static inline const Stmt* GetStmt(const ProgramPoint &P) {
+  if (const StmtPoint* SP = dyn_cast<StmtPoint>(&P))
+    return SP->getStmt();
+  else if (const BlockEdge* BE = dyn_cast<BlockEdge>(&P))
+    return BE->getSrc()->getTerminator();
+
+  return 0;
+}
+
+static inline const ExplodedNode*
+GetPredecessorNode(const ExplodedNode* N) {
+  return N->pred_empty() ? NULL : *(N->pred_begin());
+}
+
+static inline const ExplodedNode*
+GetSuccessorNode(const ExplodedNode* N) {
+  return N->succ_empty() ? NULL : *(N->succ_begin());
+}
+
+static const Stmt* GetPreviousStmt(const ExplodedNode* N) {
+  for (N = GetPredecessorNode(N); N; N = GetPredecessorNode(N))
+    if (const Stmt *S = GetStmt(N->getLocation()))
+      return S;
+
+  return 0;
+}
+
+static const Stmt* GetNextStmt(const ExplodedNode* N) {
+  for (N = GetSuccessorNode(N); N; N = GetSuccessorNode(N))
+    if (const Stmt *S = GetStmt(N->getLocation())) {
+      // Check if the statement is '?' or '&&'/'||'.  These are "merges",
+      // not actual statement points.
+      switch (S->getStmtClass()) {
+        case Stmt::ChooseExprClass:
+        case Stmt::ConditionalOperatorClass: continue;
+        case Stmt::BinaryOperatorClass: {
+          BinaryOperator::Opcode Op = cast<BinaryOperator>(S)->getOpcode();
+          if (Op == BinaryOperator::LAnd || Op == BinaryOperator::LOr)
+            continue;
+          break;
+        }
+        default:
+          break;
+      }
+
+      // Some expressions don't have locations.
+      if (S->getLocStart().isInvalid())
+        continue;
+
+      return S;
+    }
+
+  return 0;
+}
+
+static inline const Stmt*
+GetCurrentOrPreviousStmt(const ExplodedNode* N) {
+  if (const Stmt *S = GetStmt(N->getLocation()))
+    return S;
+
+  return GetPreviousStmt(N);
+}
+
+static inline const Stmt*
+GetCurrentOrNextStmt(const ExplodedNode* N) {
+  if (const Stmt *S = GetStmt(N->getLocation()))
+    return S;
+
+  return GetNextStmt(N);
+}
+
+//===----------------------------------------------------------------------===//
+// PathDiagnosticBuilder and its associated routines and helper objects.
+//===----------------------------------------------------------------------===//
+
+typedef llvm::DenseMap<const ExplodedNode*,
+const ExplodedNode*> NodeBackMap;
+
+namespace {
+class NodeMapClosure : public BugReport::NodeResolver {
+  NodeBackMap& M;
+public:
+  NodeMapClosure(NodeBackMap *m) : M(*m) {}
+  ~NodeMapClosure() {}
+
+  const ExplodedNode* getOriginalNode(const ExplodedNode* N) {
+    NodeBackMap::iterator I = M.find(N);
+    return I == M.end() ? 0 : I->second;
+  }
+};
+
+class PathDiagnosticBuilder : public BugReporterContext {
+  BugReport *R;
+  PathDiagnosticClient *PDC;
+  llvm::OwningPtr<ParentMap> PM;
+  NodeMapClosure NMC;
+public:
+  PathDiagnosticBuilder(GRBugReporter &br,
+                        BugReport *r, NodeBackMap *Backmap,
+                        PathDiagnosticClient *pdc)
+    : BugReporterContext(br),
+      R(r), PDC(pdc), NMC(Backmap) {
+    addVisitor(R);
+  }
+
+  PathDiagnosticLocation ExecutionContinues(const ExplodedNode* N);
+
+  PathDiagnosticLocation ExecutionContinues(llvm::raw_string_ostream& os,
+                                            const ExplodedNode* N);
+
+  Decl const &getCodeDecl() { return R->getEndNode()->getCodeDecl(); }
+
+  ParentMap& getParentMap() { return R->getEndNode()->getParentMap(); }
+
+  const Stmt *getParent(const Stmt *S) {
+    return getParentMap().getParent(S);
+  }
+
+  virtual NodeMapClosure& getNodeResolver() { return NMC; }
+  BugReport& getReport() { return *R; }
+
+  PathDiagnosticLocation getEnclosingStmtLocation(const Stmt *S);
+
+  PathDiagnosticLocation
+  getEnclosingStmtLocation(const PathDiagnosticLocation &L) {
+    if (const Stmt *S = L.asStmt())
+      return getEnclosingStmtLocation(S);
+
+    return L;
+  }
+
+  PathDiagnosticClient::PathGenerationScheme getGenerationScheme() const {
+    return PDC ? PDC->getGenerationScheme() : PathDiagnosticClient::Extensive;
+  }
+
+  bool supportsLogicalOpControlFlow() const {
+    return PDC ? PDC->supportsLogicalOpControlFlow() : true;
+  }
+};
+} // end anonymous namespace
+
+PathDiagnosticLocation
+PathDiagnosticBuilder::ExecutionContinues(const ExplodedNode* N) {
+  if (const Stmt *S = GetNextStmt(N))
+    return PathDiagnosticLocation(S, getSourceManager());
+
+  return FullSourceLoc(N->getLocationContext()->getDecl()->getBodyRBrace(),
+                       getSourceManager());
+}
+
+PathDiagnosticLocation
+PathDiagnosticBuilder::ExecutionContinues(llvm::raw_string_ostream& os,
+                                          const ExplodedNode* N) {
+
+  // Slow, but probably doesn't matter.
+  if (os.str().empty())
+    os << ' ';
+
+  const PathDiagnosticLocation &Loc = ExecutionContinues(N);
+
+  if (Loc.asStmt())
+    os << "Execution continues on line "
+       << getSourceManager().getInstantiationLineNumber(Loc.asLocation())
+       << '.';
+  else {
+    os << "Execution jumps to the end of the ";
+    const Decl *D = N->getLocationContext()->getDecl();
+    if (isa<ObjCMethodDecl>(D))
+      os << "method";
+    else if (isa<FunctionDecl>(D))
+      os << "function";
+    else {
+      assert(isa<BlockDecl>(D));
+      os << "anonymous block";
+    }
+    os << '.';
+  }
+
+  return Loc;
+}
+
+static bool IsNested(const Stmt *S, ParentMap &PM) {
+  if (isa<Expr>(S) && PM.isConsumedExpr(cast<Expr>(S)))
+    return true;
+
+  const Stmt *Parent = PM.getParentIgnoreParens(S);
+
+  if (Parent)
+    switch (Parent->getStmtClass()) {
+      case Stmt::ForStmtClass:
+      case Stmt::DoStmtClass:
+      case Stmt::WhileStmtClass:
+        return true;
+      default:
+        break;
+    }
+
+  return false;
+}
+
+PathDiagnosticLocation
+PathDiagnosticBuilder::getEnclosingStmtLocation(const Stmt *S) {
+  assert(S && "Null Stmt* passed to getEnclosingStmtLocation");
+  ParentMap &P = getParentMap();
+  SourceManager &SMgr = getSourceManager();
+
+  while (IsNested(S, P)) {
+    const Stmt *Parent = P.getParentIgnoreParens(S);
+
+    if (!Parent)
+      break;
+
+    switch (Parent->getStmtClass()) {
+      case Stmt::BinaryOperatorClass: {
+        const BinaryOperator *B = cast<BinaryOperator>(Parent);
+        if (B->isLogicalOp())
+          return PathDiagnosticLocation(S, SMgr);
+        break;
+      }
+      case Stmt::CompoundStmtClass:
+      case Stmt::StmtExprClass:
+        return PathDiagnosticLocation(S, SMgr);
+      case Stmt::ChooseExprClass:
+        // Similar to '?' if we are referring to condition, just have the edge
+        // point to the entire choose expression.
+        if (cast<ChooseExpr>(Parent)->getCond() == S)
+          return PathDiagnosticLocation(Parent, SMgr);
+        else
+          return PathDiagnosticLocation(S, SMgr);
+      case Stmt::ConditionalOperatorClass:
+        // For '?', if we are referring to condition, just have the edge point
+        // to the entire '?' expression.
+        if (cast<ConditionalOperator>(Parent)->getCond() == S)
+          return PathDiagnosticLocation(Parent, SMgr);
+        else
+          return PathDiagnosticLocation(S, SMgr);
+      case Stmt::DoStmtClass:
+          return PathDiagnosticLocation(S, SMgr);
+      case Stmt::ForStmtClass:
+        if (cast<ForStmt>(Parent)->getBody() == S)
+          return PathDiagnosticLocation(S, SMgr);
+        break;
+      case Stmt::IfStmtClass:
+        if (cast<IfStmt>(Parent)->getCond() != S)
+          return PathDiagnosticLocation(S, SMgr);
+        break;
+      case Stmt::ObjCForCollectionStmtClass:
+        if (cast<ObjCForCollectionStmt>(Parent)->getBody() == S)
+          return PathDiagnosticLocation(S, SMgr);
+        break;
+      case Stmt::WhileStmtClass:
+        if (cast<WhileStmt>(Parent)->getCond() != S)
+          return PathDiagnosticLocation(S, SMgr);
+        break;
+      default:
+        break;
+    }
+
+    S = Parent;
+  }
+
+  assert(S && "Cannot have null Stmt for PathDiagnosticLocation");
+
+  // Special case: DeclStmts can appear in for statement declarations, in which
+  //  case the ForStmt is the context.
+  if (isa<DeclStmt>(S)) {
+    if (const Stmt *Parent = P.getParent(S)) {
+      switch (Parent->getStmtClass()) {
+        case Stmt::ForStmtClass:
+        case Stmt::ObjCForCollectionStmtClass:
+          return PathDiagnosticLocation(Parent, SMgr);
+        default:
+          break;
+      }
+    }
+  }
+  else if (isa<BinaryOperator>(S)) {
+    // Special case: the binary operator represents the initialization
+    // code in a for statement (this can happen when the variable being
+    // initialized is an old variable.
+    if (const ForStmt *FS =
+          dyn_cast_or_null<ForStmt>(P.getParentIgnoreParens(S))) {
+      if (FS->getInit() == S)
+        return PathDiagnosticLocation(FS, SMgr);
+    }
+  }
+
+  return PathDiagnosticLocation(S, SMgr);
+}
+
+//===----------------------------------------------------------------------===//
+// ScanNotableSymbols: closure-like callback for scanning Store bindings.
+//===----------------------------------------------------------------------===//
+
+static const VarDecl*
+GetMostRecentVarDeclBinding(const ExplodedNode* N,
+                            GRStateManager& VMgr, SVal X) {
+
+  for ( ; N ; N = N->pred_empty() ? 0 : *N->pred_begin()) {
+
+    ProgramPoint P = N->getLocation();
+
+    if (!isa<PostStmt>(P))
+      continue;
+
+    const DeclRefExpr* DR = dyn_cast<DeclRefExpr>(cast<PostStmt>(P).getStmt());
+
+    if (!DR)
+      continue;
+
+    SVal Y = N->getState()->getSVal(DR);
+
+    if (X != Y)
+      continue;
+
+    const VarDecl* VD = dyn_cast<VarDecl>(DR->getDecl());
+
+    if (!VD)
+      continue;
+
+    return VD;
+  }
+
+  return 0;
+}
+
+namespace {
+class NotableSymbolHandler
+: public StoreManager::BindingsHandler {
+
+  SymbolRef Sym;
+  const GRState* PrevSt;
+  const Stmt* S;
+  GRStateManager& VMgr;
+  const ExplodedNode* Pred;
+  PathDiagnostic& PD;
+  BugReporter& BR;
+
+public:
+
+  NotableSymbolHandler(SymbolRef sym, const GRState* prevst, const Stmt* s,
+                       GRStateManager& vmgr, const ExplodedNode* pred,
+                       PathDiagnostic& pd, BugReporter& br)
+  : Sym(sym), PrevSt(prevst), S(s), VMgr(vmgr), Pred(pred), PD(pd), BR(br) {}
+
+  bool HandleBinding(StoreManager& SMgr, Store store, const MemRegion* R,
+                     SVal V) {
+
+    SymbolRef ScanSym = V.getAsSymbol();
+
+    if (ScanSym != Sym)
+      return true;
+
+    // Check if the previous state has this binding.
+    SVal X = PrevSt->getSVal(loc::MemRegionVal(R));
+
+    if (X == V) // Same binding?
+      return true;
+
+    // Different binding.  Only handle assignments for now.  We don't pull
+    // this check out of the loop because we will eventually handle other
+    // cases.
+
+    VarDecl *VD = 0;
+
+    if (const BinaryOperator* B = dyn_cast<BinaryOperator>(S)) {
+      if (!B->isAssignmentOp())
+        return true;
+
+      // What variable did we assign to?
+      DeclRefExpr* DR = dyn_cast<DeclRefExpr>(B->getLHS()->IgnoreParenCasts());
+
+      if (!DR)
+        return true;
+
+      VD = dyn_cast<VarDecl>(DR->getDecl());
+    }
+    else if (const DeclStmt* DS = dyn_cast<DeclStmt>(S)) {
+      // FIXME: Eventually CFGs won't have DeclStmts.  Right now we
+      //  assume that each DeclStmt has a single Decl.  This invariant
+      //  holds by contruction in the CFG.
+      VD = dyn_cast<VarDecl>(*DS->decl_begin());
+    }
+
+    if (!VD)
+      return true;
+
+    // What is the most recently referenced variable with this binding?
+    const VarDecl* MostRecent = GetMostRecentVarDeclBinding(Pred, VMgr, V);
+
+    if (!MostRecent)
+      return true;
+
+    // Create the diagnostic.
+    FullSourceLoc L(S->getLocStart(), BR.getSourceManager());
+
+    if (Loc::IsLocType(VD->getType())) {
+      std::string msg = "'" + std::string(VD->getNameAsString()) +
+      "' now aliases '" + MostRecent->getNameAsString() + "'";
+
+      PD.push_front(new PathDiagnosticEventPiece(L, msg));
+    }
+
+    return true;
+  }
+};
+}
+
+static void HandleNotableSymbol(const ExplodedNode* N,
+                                const Stmt* S,
+                                SymbolRef Sym, BugReporter& BR,
+                                PathDiagnostic& PD) {
+
+  const ExplodedNode* Pred = N->pred_empty() ? 0 : *N->pred_begin();
+  const GRState* PrevSt = Pred ? Pred->getState() : 0;
+
+  if (!PrevSt)
+    return;
+
+  // Look at the region bindings of the current state that map to the
+  // specified symbol.  Are any of them not in the previous state?
+  GRStateManager& VMgr = cast<GRBugReporter>(BR).getStateManager();
+  NotableSymbolHandler H(Sym, PrevSt, S, VMgr, Pred, PD, BR);
+  cast<GRBugReporter>(BR).getStateManager().iterBindings(N->getState(), H);
+}
+
+namespace {
+class ScanNotableSymbols
+: public StoreManager::BindingsHandler {
+
+  llvm::SmallSet<SymbolRef, 10> AlreadyProcessed;
+  const ExplodedNode* N;
+  const Stmt* S;
+  GRBugReporter& BR;
+  PathDiagnostic& PD;
+
+public:
+  ScanNotableSymbols(const ExplodedNode* n, const Stmt* s,
+                     GRBugReporter& br, PathDiagnostic& pd)
+  : N(n), S(s), BR(br), PD(pd) {}
+
+  bool HandleBinding(StoreManager& SMgr, Store store,
+                     const MemRegion* R, SVal V) {
+
+    SymbolRef ScanSym = V.getAsSymbol();
+
+    if (!ScanSym)
+      return true;
+
+    if (!BR.isNotable(ScanSym))
+      return true;
+
+    if (AlreadyProcessed.count(ScanSym))
+      return true;
+
+    AlreadyProcessed.insert(ScanSym);
+
+    HandleNotableSymbol(N, S, ScanSym, BR, PD);
+    return true;
+  }
+};
+} // end anonymous namespace
+
+//===----------------------------------------------------------------------===//
+// "Minimal" path diagnostic generation algorithm.
+//===----------------------------------------------------------------------===//
+
+static void CompactPathDiagnostic(PathDiagnostic &PD, const SourceManager& SM);
+
+static void GenerateMinimalPathDiagnostic(PathDiagnostic& PD,
+                                          PathDiagnosticBuilder &PDB,
+                                          const ExplodedNode *N) {
+
+  SourceManager& SMgr = PDB.getSourceManager();
+  const ExplodedNode* NextNode = N->pred_empty()
+                                        ? NULL : *(N->pred_begin());
+  while (NextNode) {
+    N = NextNode;
+    NextNode = GetPredecessorNode(N);
+
+    ProgramPoint P = N->getLocation();
+
+    if (const BlockEdge* BE = dyn_cast<BlockEdge>(&P)) {
+      CFGBlock* Src = BE->getSrc();
+      CFGBlock* Dst = BE->getDst();
+      Stmt* T = Src->getTerminator();
+
+      if (!T)
+        continue;
+
+      FullSourceLoc Start(T->getLocStart(), SMgr);
+
+      switch (T->getStmtClass()) {
+        default:
+          break;
+
+        case Stmt::GotoStmtClass:
+        case Stmt::IndirectGotoStmtClass: {
+          const Stmt* S = GetNextStmt(N);
+
+          if (!S)
+            continue;
+
+          std::string sbuf;
+          llvm::raw_string_ostream os(sbuf);
+          const PathDiagnosticLocation &End = PDB.getEnclosingStmtLocation(S);
+
+          os << "Control jumps to line "
+          << End.asLocation().getInstantiationLineNumber();
+          PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
+                                                           os.str()));
+          break;
+        }
+
+        case Stmt::SwitchStmtClass: {
+          // Figure out what case arm we took.
+          std::string sbuf;
+          llvm::raw_string_ostream os(sbuf);
+
+          if (Stmt* S = Dst->getLabel()) {
+            PathDiagnosticLocation End(S, SMgr);
+
+            switch (S->getStmtClass()) {
+              default:
+                os << "No cases match in the switch statement. "
+                "Control jumps to line "
+                << End.asLocation().getInstantiationLineNumber();
+                break;
+              case Stmt::DefaultStmtClass:
+                os << "Control jumps to the 'default' case at line "
+                << End.asLocation().getInstantiationLineNumber();
+                break;
+
+              case Stmt::CaseStmtClass: {
+                os << "Control jumps to 'case ";
+                CaseStmt* Case = cast<CaseStmt>(S);
+                Expr* LHS = Case->getLHS()->IgnoreParenCasts();
+
+                // Determine if it is an enum.
+                bool GetRawInt = true;
+
+                if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(LHS)) {
+                  // FIXME: Maybe this should be an assertion.  Are there cases
+                  // were it is not an EnumConstantDecl?
+                  EnumConstantDecl* D =
+                  dyn_cast<EnumConstantDecl>(DR->getDecl());
+
+                  if (D) {
+                    GetRawInt = false;
+                    os << D;
+                  }
+                }
+
+                if (GetRawInt)
+                  os << LHS->EvaluateAsInt(PDB.getASTContext());
+
+                os << ":'  at line "
+                << End.asLocation().getInstantiationLineNumber();
+                break;
+              }
+            }
+            PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
+                                                             os.str()));
+          }
+          else {
+            os << "'Default' branch taken. ";
+            const PathDiagnosticLocation &End = PDB.ExecutionContinues(os, N);
+            PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
+                                                             os.str()));
+          }
+
+          break;
+        }
+
+        case Stmt::BreakStmtClass:
+        case Stmt::ContinueStmtClass: {
+          std::string sbuf;
+          llvm::raw_string_ostream os(sbuf);
+          PathDiagnosticLocation End = PDB.ExecutionContinues(os, N);
+          PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
+                                                           os.str()));
+          break;
+        }
+
+          // Determine control-flow for ternary '?'.
+        case Stmt::ConditionalOperatorClass: {
+          std::string sbuf;
+          llvm::raw_string_ostream os(sbuf);
+          os << "'?' condition is ";
+
+          if (*(Src->succ_begin()+1) == Dst)
+            os << "false";
+          else
+            os << "true";
+
+          PathDiagnosticLocation End = PDB.ExecutionContinues(N);
+
+          if (const Stmt *S = End.asStmt())
+            End = PDB.getEnclosingStmtLocation(S);
+
+          PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
+                                                           os.str()));
+          break;
+        }
+
+          // Determine control-flow for short-circuited '&&' and '||'.
+        case Stmt::BinaryOperatorClass: {
+          if (!PDB.supportsLogicalOpControlFlow())
+            break;
+
+          BinaryOperator *B = cast<BinaryOperator>(T);
+          std::string sbuf;
+          llvm::raw_string_ostream os(sbuf);
+          os << "Left side of '";
+
+          if (B->getOpcode() == BinaryOperator::LAnd) {
+            os << "&&" << "' is ";
+
+            if (*(Src->succ_begin()+1) == Dst) {
+              os << "false";
+              PathDiagnosticLocation End(B->getLHS(), SMgr);
+              PathDiagnosticLocation Start(B->getOperatorLoc(), SMgr);
+              PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
+                                                               os.str()));
+            }
+            else {
+              os << "true";
+              PathDiagnosticLocation Start(B->getLHS(), SMgr);
+              PathDiagnosticLocation End = PDB.ExecutionContinues(N);
+              PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
+                                                               os.str()));
+            }
+          }
+          else {
+            assert(B->getOpcode() == BinaryOperator::LOr);
+            os << "||" << "' is ";
+
+            if (*(Src->succ_begin()+1) == Dst) {
+              os << "false";
+              PathDiagnosticLocation Start(B->getLHS(), SMgr);
+              PathDiagnosticLocation End = PDB.ExecutionContinues(N);
+              PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
+                                                               os.str()));
+            }
+            else {
+              os << "true";
+              PathDiagnosticLocation End(B->getLHS(), SMgr);
+              PathDiagnosticLocation Start(B->getOperatorLoc(), SMgr);
+              PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
+                                                               os.str()));
+            }
+          }
+
+          break;
+        }
+
+        case Stmt::DoStmtClass:  {
+          if (*(Src->succ_begin()) == Dst) {
+            std::string sbuf;
+            llvm::raw_string_ostream os(sbuf);
+
+            os << "Loop condition is true. ";
+            PathDiagnosticLocation End = PDB.ExecutionContinues(os, N);
+
+            if (const Stmt *S = End.asStmt())
+              End = PDB.getEnclosingStmtLocation(S);
+
+            PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
+                                                             os.str()));
+          }
+          else {
+            PathDiagnosticLocation End = PDB.ExecutionContinues(N);
+
+            if (const Stmt *S = End.asStmt())
+              End = PDB.getEnclosingStmtLocation(S);
+
+            PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
+                              "Loop condition is false.  Exiting loop"));
+          }
+
+          break;
+        }
+
+        case Stmt::WhileStmtClass:
+        case Stmt::ForStmtClass: {
+          if (*(Src->succ_begin()+1) == Dst) {
+            std::string sbuf;
+            llvm::raw_string_ostream os(sbuf);
+
+            os << "Loop condition is false. ";
+            PathDiagnosticLocation End = PDB.ExecutionContinues(os, N);
+            if (const Stmt *S = End.asStmt())
+              End = PDB.getEnclosingStmtLocation(S);
+
+            PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
+                                                             os.str()));
+          }
+          else {
+            PathDiagnosticLocation End = PDB.ExecutionContinues(N);
+            if (const Stmt *S = End.asStmt())
+              End = PDB.getEnclosingStmtLocation(S);
+
+            PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
+                            "Loop condition is true.  Entering loop body"));
+          }
+
+          break;
+        }
+
+        case Stmt::IfStmtClass: {
+          PathDiagnosticLocation End = PDB.ExecutionContinues(N);
+
+          if (const Stmt *S = End.asStmt())
+            End = PDB.getEnclosingStmtLocation(S);
+
+          if (*(Src->succ_begin()+1) == Dst)
+            PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
+                                                        "Taking false branch"));
+          else
+            PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
+                                                         "Taking true branch"));
+
+          break;
+        }
+      }
+    }
+
+    if (NextNode) {
+      for (BugReporterContext::visitor_iterator I = PDB.visitor_begin(),
+           E = PDB.visitor_end(); I!=E; ++I) {
+        if (PathDiagnosticPiece* p = (*I)->VisitNode(N, NextNode, PDB))
+          PD.push_front(p);
+      }
+    }
+
+    if (const PostStmt* PS = dyn_cast<PostStmt>(&P)) {
+      // Scan the region bindings, and see if a "notable" symbol has a new
+      // lval binding.
+      ScanNotableSymbols SNS(N, PS->getStmt(), PDB.getBugReporter(), PD);
+      PDB.getStateManager().iterBindings(N->getState(), SNS);
+    }
+  }
+
+  // After constructing the full PathDiagnostic, do a pass over it to compact
+  // PathDiagnosticPieces that occur within a macro.
+  CompactPathDiagnostic(PD, PDB.getSourceManager());
+}
+
+//===----------------------------------------------------------------------===//
+// "Extensive" PathDiagnostic generation.
+//===----------------------------------------------------------------------===//
+
+static bool IsControlFlowExpr(const Stmt *S) {
+  const Expr *E = dyn_cast<Expr>(S);
+
+  if (!E)
+    return false;
+
+  E = E->IgnoreParenCasts();
+
+  if (isa<ConditionalOperator>(E))
+    return true;
+
+  if (const BinaryOperator *B = dyn_cast<BinaryOperator>(E))
+    if (B->isLogicalOp())
+      return true;
+
+  return false;
+}
+
+namespace {
+class ContextLocation : public PathDiagnosticLocation {
+  bool IsDead;
+public:
+  ContextLocation(const PathDiagnosticLocation &L, bool isdead = false)
+    : PathDiagnosticLocation(L), IsDead(isdead) {}
+
+  void markDead() { IsDead = true; }
+  bool isDead() const { return IsDead; }
+};
+
+class EdgeBuilder {
+  std::vector<ContextLocation> CLocs;
+  typedef std::vector<ContextLocation>::iterator iterator;
+  PathDiagnostic &PD;
+  PathDiagnosticBuilder &PDB;
+  PathDiagnosticLocation PrevLoc;
+
+  bool IsConsumedExpr(const PathDiagnosticLocation &L);
+
+  bool containsLocation(const PathDiagnosticLocation &Container,
+                        const PathDiagnosticLocation &Containee);
+
+  PathDiagnosticLocation getContextLocation(const PathDiagnosticLocation &L);
+
+  PathDiagnosticLocation cleanUpLocation(PathDiagnosticLocation L,
+                                         bool firstCharOnly = false) {
+    if (const Stmt *S = L.asStmt()) {
+      const Stmt *Original = S;
+      while (1) {
+        // Adjust the location for some expressions that are best referenced
+        // by one of their subexpressions.
+        switch (S->getStmtClass()) {
+          default:
+            break;
+          case Stmt::ParenExprClass:
+            S = cast<ParenExpr>(S)->IgnoreParens();
+            firstCharOnly = true;
+            continue;
+          case Stmt::ConditionalOperatorClass:
+            S = cast<ConditionalOperator>(S)->getCond();
+            firstCharOnly = true;
+            continue;
+          case Stmt::ChooseExprClass:
+            S = cast<ChooseExpr>(S)->getCond();
+            firstCharOnly = true;
+            continue;
+          case Stmt::BinaryOperatorClass:
+            S = cast<BinaryOperator>(S)->getLHS();
+            firstCharOnly = true;
+            continue;
+        }
+
+        break;
+      }
+
+      if (S != Original)
+        L = PathDiagnosticLocation(S, L.getManager());
+    }
+
+    if (firstCharOnly)
+      L = PathDiagnosticLocation(L.asLocation());
+
+    return L;
+  }
+
+  void popLocation() {
+    if (!CLocs.back().isDead() && CLocs.back().asLocation().isFileID()) {
+      // For contexts, we only one the first character as the range.
+      rawAddEdge(cleanUpLocation(CLocs.back(), true));
+    }
+    CLocs.pop_back();
+  }
+
+  PathDiagnosticLocation IgnoreParens(const PathDiagnosticLocation &L);
+
+public:
+  EdgeBuilder(PathDiagnostic &pd, PathDiagnosticBuilder &pdb)
+    : PD(pd), PDB(pdb) {
+
+      // If the PathDiagnostic already has pieces, add the enclosing statement
+      // of the first piece as a context as well.
+      if (!PD.empty()) {
+        PrevLoc = PD.begin()->getLocation();
+
+        if (const Stmt *S = PrevLoc.asStmt())
+          addExtendedContext(PDB.getEnclosingStmtLocation(S).asStmt());
+      }
+  }
+
+  ~EdgeBuilder() {
+    while (!CLocs.empty()) popLocation();
+
+    // Finally, add an initial edge from the start location of the first
+    // statement (if it doesn't already exist).
+    // FIXME: Should handle CXXTryStmt if analyser starts supporting C++.
+    if (const CompoundStmt *CS =
+          PDB.getCodeDecl().getCompoundBody())
+      if (!CS->body_empty()) {
+        SourceLocation Loc = (*CS->body_begin())->getLocStart();
+        rawAddEdge(PathDiagnosticLocation(Loc, PDB.getSourceManager()));
+      }
+
+  }
+
+  void addEdge(PathDiagnosticLocation NewLoc, bool alwaysAdd = false);
+
+  void addEdge(const Stmt *S, bool alwaysAdd = false) {
+    addEdge(PathDiagnosticLocation(S, PDB.getSourceManager()), alwaysAdd);
+  }
+
+  void rawAddEdge(PathDiagnosticLocation NewLoc);
+
+  void addContext(const Stmt *S);
+  void addExtendedContext(const Stmt *S);
+};
+} // end anonymous namespace
+
+
+PathDiagnosticLocation
+EdgeBuilder::getContextLocation(const PathDiagnosticLocation &L) {
+  if (const Stmt *S = L.asStmt()) {
+    if (IsControlFlowExpr(S))
+      return L;
+
+    return PDB.getEnclosingStmtLocation(S);
+  }
+
+  return L;
+}
+
+bool EdgeBuilder::containsLocation(const PathDiagnosticLocation &Container,
+                                   const PathDiagnosticLocation &Containee) {
+
+  if (Container == Containee)
+    return true;
+
+  if (Container.asDecl())
+    return true;
+
+  if (const Stmt *S = Containee.asStmt())
+    if (const Stmt *ContainerS = Container.asStmt()) {
+      while (S) {
+        if (S == ContainerS)
+          return true;
+        S = PDB.getParent(S);
+      }
+      return false;
+    }
+
+  // Less accurate: compare using source ranges.
+  SourceRange ContainerR = Container.asRange();
+  SourceRange ContaineeR = Containee.asRange();
+
+  SourceManager &SM = PDB.getSourceManager();
+  SourceLocation ContainerRBeg = SM.getInstantiationLoc(ContainerR.getBegin());
+  SourceLocation ContainerREnd = SM.getInstantiationLoc(ContainerR.getEnd());
+  SourceLocation ContaineeRBeg = SM.getInstantiationLoc(ContaineeR.getBegin());
+  SourceLocation ContaineeREnd = SM.getInstantiationLoc(ContaineeR.getEnd());
+
+  unsigned ContainerBegLine = SM.getInstantiationLineNumber(ContainerRBeg);
+  unsigned ContainerEndLine = SM.getInstantiationLineNumber(ContainerREnd);
+  unsigned ContaineeBegLine = SM.getInstantiationLineNumber(ContaineeRBeg);
+  unsigned ContaineeEndLine = SM.getInstantiationLineNumber(ContaineeREnd);
+
+  assert(ContainerBegLine <= ContainerEndLine);
+  assert(ContaineeBegLine <= ContaineeEndLine);
+
+  return (ContainerBegLine <= ContaineeBegLine &&
+          ContainerEndLine >= ContaineeEndLine &&
+          (ContainerBegLine != ContaineeBegLine ||
+           SM.getInstantiationColumnNumber(ContainerRBeg) <=
+           SM.getInstantiationColumnNumber(ContaineeRBeg)) &&
+          (ContainerEndLine != ContaineeEndLine ||
+           SM.getInstantiationColumnNumber(ContainerREnd) >=
+           SM.getInstantiationColumnNumber(ContainerREnd)));
+}
+
+PathDiagnosticLocation
+EdgeBuilder::IgnoreParens(const PathDiagnosticLocation &L) {
+  if (const Expr* E = dyn_cast_or_null<Expr>(L.asStmt()))
+      return PathDiagnosticLocation(E->IgnoreParenCasts(),
+                                    PDB.getSourceManager());
+  return L;
+}
+
+void EdgeBuilder::rawAddEdge(PathDiagnosticLocation NewLoc) {
+  if (!PrevLoc.isValid()) {
+    PrevLoc = NewLoc;
+    return;
+  }
+
+  const PathDiagnosticLocation &NewLocClean = cleanUpLocation(NewLoc);
+  const PathDiagnosticLocation &PrevLocClean = cleanUpLocation(PrevLoc);
+
+  if (NewLocClean.asLocation() == PrevLocClean.asLocation())
+    return;
+
+  // FIXME: Ignore intra-macro edges for now.
+  if (NewLocClean.asLocation().getInstantiationLoc() ==
+      PrevLocClean.asLocation().getInstantiationLoc())
+    return;
+
+  PD.push_front(new PathDiagnosticControlFlowPiece(NewLocClean, PrevLocClean));
+  PrevLoc = NewLoc;
+}
+
+void EdgeBuilder::addEdge(PathDiagnosticLocation NewLoc, bool alwaysAdd) {
+
+  if (!alwaysAdd && NewLoc.asLocation().isMacroID())
+    return;
+
+  const PathDiagnosticLocation &CLoc = getContextLocation(NewLoc);
+
+  while (!CLocs.empty()) {
+    ContextLocation &TopContextLoc = CLocs.back();
+
+    // Is the top location context the same as the one for the new location?
+    if (TopContextLoc == CLoc) {
+      if (alwaysAdd) {
+        if (IsConsumedExpr(TopContextLoc) &&
+            !IsControlFlowExpr(TopContextLoc.asStmt()))
+            TopContextLoc.markDead();
+
+        rawAddEdge(NewLoc);
+      }
+
+      return;
+    }
+
+    if (containsLocation(TopContextLoc, CLoc)) {
+      if (alwaysAdd) {
+        rawAddEdge(NewLoc);
+
+        if (IsConsumedExpr(CLoc) && !IsControlFlowExpr(CLoc.asStmt())) {
+          CLocs.push_back(ContextLocation(CLoc, true));
+          return;
+        }
+      }
+
+      CLocs.push_back(CLoc);
+      return;
+    }
+
+    // Context does not contain the location.  Flush it.
+    popLocation();
+  }
+
+  // If we reach here, there is no enclosing context.  Just add the edge.
+  rawAddEdge(NewLoc);
+}
+
+bool EdgeBuilder::IsConsumedExpr(const PathDiagnosticLocation &L) {
+  if (const Expr *X = dyn_cast_or_null<Expr>(L.asStmt()))
+    return PDB.getParentMap().isConsumedExpr(X) && !IsControlFlowExpr(X);
+
+  return false;
+}
+
+void EdgeBuilder::addExtendedContext(const Stmt *S) {
+  if (!S)
+    return;
+
+  const Stmt *Parent = PDB.getParent(S);
+  while (Parent) {
+    if (isa<CompoundStmt>(Parent))
+      Parent = PDB.getParent(Parent);
+    else
+      break;
+  }
+
+  if (Parent) {
+    switch (Parent->getStmtClass()) {
+      case Stmt::DoStmtClass:
+      case Stmt::ObjCAtSynchronizedStmtClass:
+        addContext(Parent);
+      default:
+        break;
+    }
+  }
+
+  addContext(S);
+}
+
+void EdgeBuilder::addContext(const Stmt *S) {
+  if (!S)
+    return;
+
+  PathDiagnosticLocation L(S, PDB.getSourceManager());
+
+  while (!CLocs.empty()) {
+    const PathDiagnosticLocation &TopContextLoc = CLocs.back();
+
+    // Is the top location context the same as the one for the new location?
+    if (TopContextLoc == L)
+      return;
+
+    if (containsLocation(TopContextLoc, L)) {
+      CLocs.push_back(L);
+      return;
+    }
+
+    // Context does not contain the location.  Flush it.
+    popLocation();
+  }
+
+  CLocs.push_back(L);
+}
+
+static void GenerateExtensivePathDiagnostic(PathDiagnostic& PD,
+                                            PathDiagnosticBuilder &PDB,
+                                            const ExplodedNode *N) {
+  EdgeBuilder EB(PD, PDB);
+
+  const ExplodedNode* NextNode = N->pred_empty() ? NULL : *(N->pred_begin());
+  while (NextNode) {
+    N = NextNode;
+    NextNode = GetPredecessorNode(N);
+    ProgramPoint P = N->getLocation();
+
+    do {
+      // Block edges.
+      if (const BlockEdge *BE = dyn_cast<BlockEdge>(&P)) {
+        const CFGBlock &Blk = *BE->getSrc();
+        const Stmt *Term = Blk.getTerminator();
+
+        // Are we jumping to the head of a loop?  Add a special diagnostic.
+        if (const Stmt *Loop = BE->getDst()->getLoopTarget()) {
+          PathDiagnosticLocation L(Loop, PDB.getSourceManager());
+          const CompoundStmt *CS = NULL;
+
+          if (!Term) {
+            if (const ForStmt *FS = dyn_cast<ForStmt>(Loop))
+              CS = dyn_cast<CompoundStmt>(FS->getBody());
+            else if (const WhileStmt *WS = dyn_cast<WhileStmt>(Loop))
+              CS = dyn_cast<CompoundStmt>(WS->getBody());
+          }
+
+          PathDiagnosticEventPiece *p =
+            new PathDiagnosticEventPiece(L,
+                                        "Looping back to the head of the loop");
+
+          EB.addEdge(p->getLocation(), true);
+          PD.push_front(p);
+
+          if (CS) {
+            PathDiagnosticLocation BL(CS->getRBracLoc(),
+                                      PDB.getSourceManager());
+            BL = PathDiagnosticLocation(BL.asLocation());
+            EB.addEdge(BL);
+          }
+        }
+
+        if (Term)
+          EB.addContext(Term);
+
+        break;
+      }
+
+      if (const BlockEntrance *BE = dyn_cast<BlockEntrance>(&P)) {
+        if (const Stmt* S = BE->getFirstStmt()) {
+         if (IsControlFlowExpr(S)) {
+           // Add the proper context for '&&', '||', and '?'.
+           EB.addContext(S);
+         }
+         else
+           EB.addExtendedContext(PDB.getEnclosingStmtLocation(S).asStmt());
+        }
+
+        break;
+      }
+    } while (0);
+
+    if (!NextNode)
+      continue;
+
+    for (BugReporterContext::visitor_iterator I = PDB.visitor_begin(),
+         E = PDB.visitor_end(); I!=E; ++I) {
+      if (PathDiagnosticPiece* p = (*I)->VisitNode(N, NextNode, PDB)) {
+        const PathDiagnosticLocation &Loc = p->getLocation();
+        EB.addEdge(Loc, true);
+        PD.push_front(p);
+        if (const Stmt *S = Loc.asStmt())
+          EB.addExtendedContext(PDB.getEnclosingStmtLocation(S).asStmt());
+      }
+    }
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// Methods for BugType and subclasses.
+//===----------------------------------------------------------------------===//
+BugType::~BugType() {
+  // Free up the equivalence class objects.  Observe that we get a pointer to
+  // the object first before incrementing the iterator, as destroying the
+  // node before doing so means we will read from freed memory.
+  for (iterator I = begin(), E = end(); I !=E; ) {
+    BugReportEquivClass *EQ = &*I;
+    ++I;
+    delete EQ;
+  }
+}
+void BugType::FlushReports(BugReporter &BR) {}
+
+//===----------------------------------------------------------------------===//
+// Methods for BugReport and subclasses.
+//===----------------------------------------------------------------------===//
+BugReport::~BugReport() {}
+RangedBugReport::~RangedBugReport() {}
+
+const Stmt* BugReport::getStmt() const {
+  ProgramPoint ProgP = EndNode->getLocation();
+  const Stmt *S = NULL;
+
+  if (BlockEntrance* BE = dyn_cast<BlockEntrance>(&ProgP)) {
+    CFGBlock &Exit = ProgP.getLocationContext()->getCFG()->getExit();
+    if (BE->getBlock() == &Exit)
+      S = GetPreviousStmt(EndNode);
+  }
+  if (!S)
+    S = GetStmt(ProgP);
+
+  return S;
+}
+
+PathDiagnosticPiece*
+BugReport::getEndPath(BugReporterContext& BRC,
+                      const ExplodedNode* EndPathNode) {
+
+  const Stmt* S = getStmt();
+
+  if (!S)
+    return NULL;
+
+  const SourceRange *Beg, *End;
+  getRanges(Beg, End);
+  PathDiagnosticLocation L(S, BRC.getSourceManager());
+
+  // Only add the statement itself as a range if we didn't specify any
+  // special ranges for this report.
+  PathDiagnosticPiece* P = new PathDiagnosticEventPiece(L, getDescription(),
+                                                        Beg == End);
+
+  for (; Beg != End; ++Beg)
+    P->addRange(*Beg);
+
+  return P;
+}
+
+void BugReport::getRanges(const SourceRange*& beg, const SourceRange*& end) {
+  if (const Expr* E = dyn_cast_or_null<Expr>(getStmt())) {
+    R = E->getSourceRange();
+    assert(R.isValid());
+    beg = &R;
+    end = beg+1;
+  }
+  else
+    beg = end = 0;
+}
+
+SourceLocation BugReport::getLocation() const {
+  if (EndNode)
+    if (const Stmt* S = GetCurrentOrPreviousStmt(EndNode)) {
+      // For member expressions, return the location of the '.' or '->'.
+      if (const MemberExpr *ME = dyn_cast<MemberExpr>(S))
+        return ME->getMemberLoc();
+      // For binary operators, return the location of the operator.
+      if (const BinaryOperator *B = dyn_cast<BinaryOperator>(S))
+        return B->getOperatorLoc();
+
+      return S->getLocStart();
+    }
+
+  return FullSourceLoc();
+}
+
+PathDiagnosticPiece* BugReport::VisitNode(const ExplodedNode* N,
+                                          const ExplodedNode* PrevN,
+                                          BugReporterContext &BRC) {
+  return NULL;
+}
+
+//===----------------------------------------------------------------------===//
+// Methods for BugReporter and subclasses.
+//===----------------------------------------------------------------------===//
+
+BugReportEquivClass::~BugReportEquivClass() {
+  for (iterator I=begin(), E=end(); I!=E; ++I) delete *I;
+}
+
+GRBugReporter::~GRBugReporter() { }
+BugReporterData::~BugReporterData() {}
+
+ExplodedGraph &GRBugReporter::getGraph() { return Eng.getGraph(); }
+
+GRStateManager&
+GRBugReporter::getStateManager() { return Eng.getStateManager(); }
+
+BugReporter::~BugReporter() { FlushReports(); }
+
+void BugReporter::FlushReports() {
+  if (BugTypes.isEmpty())
+    return;
+
+  // First flush the warnings for each BugType.  This may end up creating new
+  // warnings and new BugTypes.  Because ImmutableSet is a functional data
+  // structure, we do not need to worry about the iterators being invalidated.
+  for (BugTypesTy::iterator I=BugTypes.begin(), E=BugTypes.end(); I!=E; ++I)
+    const_cast<BugType*>(*I)->FlushReports(*this);
+
+  // Iterate through BugTypes a second time.  BugTypes may have been updated
+  // with new BugType objects and new warnings.
+  for (BugTypesTy::iterator I=BugTypes.begin(), E=BugTypes.end(); I!=E; ++I) {
+    BugType *BT = const_cast<BugType*>(*I);
+
+    typedef llvm::FoldingSet<BugReportEquivClass> SetTy;
+    SetTy& EQClasses = BT->EQClasses;
+
+    for (SetTy::iterator EI=EQClasses.begin(), EE=EQClasses.end(); EI!=EE;++EI){
+      BugReportEquivClass& EQ = *EI;
+      FlushReport(EQ);
+    }
+
+    // Delete the BugType object.
+    delete BT;
+  }
+
+  // Remove all references to the BugType objects.
+  BugTypes = F.GetEmptySet();
+}
+
+//===----------------------------------------------------------------------===//
+// PathDiagnostics generation.
+//===----------------------------------------------------------------------===//
+
+static std::pair<std::pair<ExplodedGraph*, NodeBackMap*>,
+                 std::pair<ExplodedNode*, unsigned> >
+MakeReportGraph(const ExplodedGraph* G,
+                const ExplodedNode** NStart,
+                const ExplodedNode** NEnd) {
+
+  // Create the trimmed graph.  It will contain the shortest paths from the
+  // error nodes to the root.  In the new graph we should only have one
+  // error node unless there are two or more error nodes with the same minimum
+  // path length.
+  ExplodedGraph* GTrim;
+  InterExplodedGraphMap* NMap;
+
+  llvm::DenseMap<const void*, const void*> InverseMap;
+  llvm::tie(GTrim, NMap) = G->Trim(NStart, NEnd, &InverseMap);
+
+  // Create owning pointers for GTrim and NMap just to ensure that they are
+  // released when this function exists.
+  llvm::OwningPtr<ExplodedGraph> AutoReleaseGTrim(GTrim);
+  llvm::OwningPtr<InterExplodedGraphMap> AutoReleaseNMap(NMap);
+
+  // Find the (first) error node in the trimmed graph.  We just need to consult
+  // the node map (NMap) which maps from nodes in the original graph to nodes
+  // in the new graph.
+
+  std::queue<const ExplodedNode*> WS;
+  typedef llvm::DenseMap<const ExplodedNode*, unsigned> IndexMapTy;
+  IndexMapTy IndexMap;
+
+  for (const ExplodedNode** I = NStart; I != NEnd; ++I)
+    if (const ExplodedNode *N = NMap->getMappedNode(*I)) {
+      unsigned NodeIndex = (I - NStart) / sizeof(*I);
+      WS.push(N);
+      IndexMap[*I] = NodeIndex;
+    }
+
+  assert(!WS.empty() && "No error node found in the trimmed graph.");
+
+  // Create a new (third!) graph with a single path.  This is the graph
+  // that will be returned to the caller.
+  ExplodedGraph *GNew = new ExplodedGraph(GTrim->getContext());
+
+  // Sometimes the trimmed graph can contain a cycle.  Perform a reverse BFS
+  // to the root node, and then construct a new graph that contains only
+  // a single path.
+  llvm::DenseMap<const void*,unsigned> Visited;
+
+  unsigned cnt = 0;
+  const ExplodedNode* Root = 0;
+
+  while (!WS.empty()) {
+    const ExplodedNode* Node = WS.front();
+    WS.pop();
+
+    if (Visited.find(Node) != Visited.end())
+      continue;
+
+    Visited[Node] = cnt++;
+
+    if (Node->pred_empty()) {
+      Root = Node;
+      break;
+    }
+
+    for (ExplodedNode::const_pred_iterator I=Node->pred_begin(),
+         E=Node->pred_end(); I!=E; ++I)
+      WS.push(*I);
+  }
+
+  assert(Root);
+
+  // Now walk from the root down the BFS path, always taking the successor
+  // with the lowest number.
+  ExplodedNode *Last = 0, *First = 0;
+  NodeBackMap *BM = new NodeBackMap();
+  unsigned NodeIndex = 0;
+
+  for ( const ExplodedNode *N = Root ;;) {
+    // Lookup the number associated with the current node.
+    llvm::DenseMap<const void*,unsigned>::iterator I = Visited.find(N);
+    assert(I != Visited.end());
+
+    // Create the equivalent node in the new graph with the same state
+    // and location.
+    ExplodedNode* NewN = GNew->getNode(N->getLocation(), N->getState());
+
+    // Store the mapping to the original node.
+    llvm::DenseMap<const void*, const void*>::iterator IMitr=InverseMap.find(N);
+    assert(IMitr != InverseMap.end() && "No mapping to original node.");
+    (*BM)[NewN] = (const ExplodedNode*) IMitr->second;
+
+    // Link up the new node with the previous node.
+    if (Last)
+      NewN->addPredecessor(Last, *GNew);
+
+    Last = NewN;
+
+    // Are we at the final node?
+    IndexMapTy::iterator IMI =
+      IndexMap.find((const ExplodedNode*)(IMitr->second));
+    if (IMI != IndexMap.end()) {
+      First = NewN;
+      NodeIndex = IMI->second;
+      break;
+    }
+
+    // Find the next successor node.  We choose the node that is marked
+    // with the lowest DFS number.
+    ExplodedNode::const_succ_iterator SI = N->succ_begin();
+    ExplodedNode::const_succ_iterator SE = N->succ_end();
+    N = 0;
+
+    for (unsigned MinVal = 0; SI != SE; ++SI) {
+
+      I = Visited.find(*SI);
+
+      if (I == Visited.end())
+        continue;
+
+      if (!N || I->second < MinVal) {
+        N = *SI;
+        MinVal = I->second;
+      }
+    }
+
+    assert(N);
+  }
+
+  assert(First);
+
+  return std::make_pair(std::make_pair(GNew, BM),
+                        std::make_pair(First, NodeIndex));
+}
+
+/// CompactPathDiagnostic - This function postprocesses a PathDiagnostic object
+///  and collapses PathDiagosticPieces that are expanded by macros.
+static void CompactPathDiagnostic(PathDiagnostic &PD, const SourceManager& SM) {
+  typedef std::vector<std::pair<PathDiagnosticMacroPiece*, SourceLocation> >
+          MacroStackTy;
+
+  typedef std::vector<PathDiagnosticPiece*>
+          PiecesTy;
+
+  MacroStackTy MacroStack;
+  PiecesTy Pieces;
+
+  for (PathDiagnostic::iterator I = PD.begin(), E = PD.end(); I!=E; ++I) {
+    // Get the location of the PathDiagnosticPiece.
+    const FullSourceLoc Loc = I->getLocation().asLocation();
+
+    // Determine the instantiation location, which is the location we group
+    // related PathDiagnosticPieces.
+    SourceLocation InstantiationLoc = Loc.isMacroID() ?
+                                      SM.getInstantiationLoc(Loc) :
+                                      SourceLocation();
+
+    if (Loc.isFileID()) {
+      MacroStack.clear();
+      Pieces.push_back(&*I);
+      continue;
+    }
+
+    assert(Loc.isMacroID());
+
+    // Is the PathDiagnosticPiece within the same macro group?
+    if (!MacroStack.empty() && InstantiationLoc == MacroStack.back().second) {
+      MacroStack.back().first->push_back(&*I);
+      continue;
+    }
+
+    // We aren't in the same group.  Are we descending into a new macro
+    // or are part of an old one?
+    PathDiagnosticMacroPiece *MacroGroup = 0;
+
+    SourceLocation ParentInstantiationLoc = InstantiationLoc.isMacroID() ?
+                                          SM.getInstantiationLoc(Loc) :
+                                          SourceLocation();
+
+    // Walk the entire macro stack.
+    while (!MacroStack.empty()) {
+      if (InstantiationLoc == MacroStack.back().second) {
+        MacroGroup = MacroStack.back().first;
+        break;
+      }
+
+      if (ParentInstantiationLoc == MacroStack.back().second) {
+        MacroGroup = MacroStack.back().first;
+        break;
+      }
+
+      MacroStack.pop_back();
+    }
+
+    if (!MacroGroup || ParentInstantiationLoc == MacroStack.back().second) {
+      // Create a new macro group and add it to the stack.
+      PathDiagnosticMacroPiece *NewGroup = new PathDiagnosticMacroPiece(Loc);
+
+      if (MacroGroup)
+        MacroGroup->push_back(NewGroup);
+      else {
+        assert(InstantiationLoc.isFileID());
+        Pieces.push_back(NewGroup);
+      }
+
+      MacroGroup = NewGroup;
+      MacroStack.push_back(std::make_pair(MacroGroup, InstantiationLoc));
+    }
+
+    // Finally, add the PathDiagnosticPiece to the group.
+    MacroGroup->push_back(&*I);
+  }
+
+  // Now take the pieces and construct a new PathDiagnostic.
+  PD.resetPath(false);
+
+  for (PiecesTy::iterator I=Pieces.begin(), E=Pieces.end(); I!=E; ++I) {
+    if (PathDiagnosticMacroPiece *MP=dyn_cast<PathDiagnosticMacroPiece>(*I))
+      if (!MP->containsEvent()) {
+        delete MP;
+        continue;
+      }
+
+    PD.push_back(*I);
+  }
+}
+
+void GRBugReporter::GeneratePathDiagnostic(PathDiagnostic& PD,
+                                           BugReportEquivClass& EQ) {
+
+  std::vector<const ExplodedNode*> Nodes;
+
+  for (BugReportEquivClass::iterator I=EQ.begin(), E=EQ.end(); I!=E; ++I) {
+    const ExplodedNode* N = I->getEndNode();
+    if (N) Nodes.push_back(N);
+  }
+
+  if (Nodes.empty())
+    return;
+
+  // Construct a new graph that contains only a single path from the error
+  // node to a root.
+  const std::pair<std::pair<ExplodedGraph*, NodeBackMap*>,
+  std::pair<ExplodedNode*, unsigned> >&
+  GPair = MakeReportGraph(&getGraph(), &Nodes[0], &Nodes[0] + Nodes.size());
+
+  // Find the BugReport with the original location.
+  BugReport *R = 0;
+  unsigned i = 0;
+  for (BugReportEquivClass::iterator I=EQ.begin(), E=EQ.end(); I!=E; ++I, ++i)
+    if (i == GPair.second.second) { R = *I; break; }
+
+  assert(R && "No original report found for sliced graph.");
+
+  llvm::OwningPtr<ExplodedGraph> ReportGraph(GPair.first.first);
+  llvm::OwningPtr<NodeBackMap> BackMap(GPair.first.second);
+  const ExplodedNode *N = GPair.second.first;
+
+  // Start building the path diagnostic...
+  PathDiagnosticBuilder PDB(*this, R, BackMap.get(), getPathDiagnosticClient());
+
+  if (PathDiagnosticPiece* Piece = R->getEndPath(PDB, N))
+    PD.push_back(Piece);
+  else
+    return;
+
+  // Register node visitors.
+  R->registerInitialVisitors(PDB, N);
+  bugreporter::registerNilReceiverVisitor(PDB);
+
+  switch (PDB.getGenerationScheme()) {
+    case PathDiagnosticClient::Extensive:
+      GenerateExtensivePathDiagnostic(PD, PDB, N);
+      break;
+    case PathDiagnosticClient::Minimal:
+      GenerateMinimalPathDiagnostic(PD, PDB, N);
+      break;
+  }
+}
+
+void BugReporter::Register(BugType *BT) {
+  BugTypes = F.Add(BugTypes, BT);
+}
+
+void BugReporter::EmitReport(BugReport* R) {
+  // Compute the bug report's hash to determine its equivalence class.
+  llvm::FoldingSetNodeID ID;
+  R->Profile(ID);
+
+  // Lookup the equivance class.  If there isn't one, create it.
+  BugType& BT = R->getBugType();
+  Register(&BT);
+  void *InsertPos;
+  BugReportEquivClass* EQ = BT.EQClasses.FindNodeOrInsertPos(ID, InsertPos);
+
+  if (!EQ) {
+    EQ = new BugReportEquivClass(R);
+    BT.EQClasses.InsertNode(EQ, InsertPos);
+  }
+  else
+    EQ->AddReport(R);
+}
+
+
+//===----------------------------------------------------------------------===//
+// Emitting reports in equivalence classes.
+//===----------------------------------------------------------------------===//
+
+namespace {
+struct FRIEC_WLItem {
+  const ExplodedNode *N;
+  ExplodedNode::const_succ_iterator I, E;
+  
+  FRIEC_WLItem(const ExplodedNode *n)
+  : N(n), I(N->succ_begin()), E(N->succ_end()) {}
+};  
+}
+
+static BugReport *FindReportInEquivalenceClass(BugReportEquivClass& EQ) {
+  BugReportEquivClass::iterator I = EQ.begin(), E = EQ.end();
+  assert(I != E);
+  BugReport *R = *I;
+  BugType& BT = R->getBugType();
+  
+  if (!BT.isSuppressOnSink())
+    return R;
+  
+  // For bug reports that should be suppressed when all paths are post-dominated
+  // by a sink node, iterate through the reports in the equivalence class
+  // until we find one that isn't post-dominated (if one exists).  We use a
+  // DFS traversal of the ExplodedGraph to find a non-sink node.  We could write
+  // this as a recursive function, but we don't want to risk blowing out the
+  // stack for very long paths.
+  for (; I != E; ++I) {
+    R = *I;
+    const ExplodedNode *N = R->getEndNode();
+
+    if (!N)
+      continue;
+
+    if (N->isSink()) {
+      assert(false &&
+           "BugType::isSuppressSink() should not be 'true' for sink end nodes");
+      return R;
+    }
+    
+    if (N->succ_empty())
+      return R;
+    
+    // At this point we know that 'N' is not a sink and it has at least one
+    // successor.  Use a DFS worklist to find a non-sink end-of-path node.    
+    typedef FRIEC_WLItem WLItem;
+    typedef llvm::SmallVector<WLItem, 10> DFSWorkList;
+    llvm::DenseMap<const ExplodedNode *, unsigned> Visited;
+    
+    DFSWorkList WL;
+    WL.push_back(N);
+    Visited[N] = 1;
+    
+    while (!WL.empty()) {
+      WLItem &WI = WL.back();
+      assert(!WI.N->succ_empty());
+            
+      for (; WI.I != WI.E; ++WI.I) {
+        const ExplodedNode *Succ = *WI.I;        
+        // End-of-path node?
+        if (Succ->succ_empty()) {
+          // If we found an end-of-path node that is not a sink, then return
+          // this report.
+          if (!Succ->isSink())
+            return R;
+         
+          // Found a sink?  Continue on to the next successor.
+          continue;
+        }
+        
+        // Mark the successor as visited.  If it hasn't been explored,
+        // enqueue it to the DFS worklist.
+        unsigned &mark = Visited[Succ];
+        if (!mark) {
+          mark = 1;
+          WL.push_back(Succ);
+          break;
+        }
+      }
+      
+      if (&WL.back() == &WI)
+        WL.pop_back();
+    }
+  }
+  
+  // If we reach here, the end nodes for all reports in the equivalence
+  // class are post-dominated by a sink node.
+  return NULL;
+}
+
+
+//===----------------------------------------------------------------------===//
+// DiagnosticCache.  This is a hack to cache analyzer diagnostics.  It
+// uses global state, which eventually should go elsewhere.
+//===----------------------------------------------------------------------===//
+namespace {
+class DiagCacheItem : public llvm::FoldingSetNode {
+  llvm::FoldingSetNodeID ID;
+public:
+  DiagCacheItem(BugReport *R, PathDiagnostic *PD) {
+    ID.AddString(R->getBugType().getName());
+    ID.AddString(R->getBugType().getCategory());
+    ID.AddString(R->getDescription());
+    ID.AddInteger(R->getLocation().getRawEncoding());
+    PD->Profile(ID);    
+  }
+  
+  void Profile(llvm::FoldingSetNodeID &id) {
+    id = ID;
+  }
+  
+  llvm::FoldingSetNodeID &getID() { return ID; }
+};
+}
+
+static bool IsCachedDiagnostic(BugReport *R, PathDiagnostic *PD) {
+  // FIXME: Eventually this diagnostic cache should reside in something
+  // like AnalysisManager instead of being a static variable.  This is
+  // really unsafe in the long term.
+  typedef llvm::FoldingSet<DiagCacheItem> DiagnosticCache;
+  static DiagnosticCache DC;
+  
+  void *InsertPos;
+  DiagCacheItem *Item = new DiagCacheItem(R, PD);
+  
+  if (DC.FindNodeOrInsertPos(Item->getID(), InsertPos)) {
+    delete Item;
+    return true;
+  }
+  
+  DC.InsertNode(Item, InsertPos);
+  return false;
+}
+
+void BugReporter::FlushReport(BugReportEquivClass& EQ) {
+  BugReport *R = FindReportInEquivalenceClass(EQ);
+
+  if (!R)
+    return;
+  
+  PathDiagnosticClient* PD = getPathDiagnosticClient();
+
+  // FIXME: Make sure we use the 'R' for the path that was actually used.
+  // Probably doesn't make a difference in practice.
+  BugType& BT = R->getBugType();
+
+  llvm::OwningPtr<PathDiagnostic>
+    D(new PathDiagnostic(R->getBugType().getName(),
+                         !PD || PD->useVerboseDescription()
+                         ? R->getDescription() : R->getShortDescription(),
+                         BT.getCategory()));
+
+  GeneratePathDiagnostic(*D.get(), EQ);
+
+  if (IsCachedDiagnostic(R, D.get()))
+    return;
+  
+  // Get the meta data.
+  std::pair<const char**, const char**> Meta = R->getExtraDescriptiveText();
+  for (const char** s = Meta.first; s != Meta.second; ++s)
+    D->addMeta(*s);
+
+  // Emit a summary diagnostic to the regular Diagnostics engine.
+  const SourceRange *Beg = 0, *End = 0;
+  R->getRanges(Beg, End);
+  Diagnostic& Diag = getDiagnostic();
+  FullSourceLoc L(R->getLocation(), getSourceManager());
+  
+  // Search the description for '%', as that will be interpretted as a
+  // format character by FormatDiagnostics.
+  llvm::StringRef desc = R->getShortDescription();
+  unsigned ErrorDiag;
+  {
+    llvm::SmallString<512> TmpStr;
+    llvm::raw_svector_ostream Out(TmpStr);
+    for (llvm::StringRef::iterator I=desc.begin(), E=desc.end(); I!=E; ++I)
+      if (*I == '%')
+        Out << "%%";
+      else
+        Out << *I;
+    
+    Out.flush();
+    ErrorDiag = Diag.getCustomDiagID(Diagnostic::Warning, TmpStr);
+  }        
+
+  switch (End-Beg) {
+    default: assert(0 && "Don't handle this many ranges yet!");
+    case 0: Diag.Report(L, ErrorDiag); break;
+    case 1: Diag.Report(L, ErrorDiag) << Beg[0]; break;
+    case 2: Diag.Report(L, ErrorDiag) << Beg[0] << Beg[1]; break;
+    case 3: Diag.Report(L, ErrorDiag) << Beg[0] << Beg[1] << Beg[2]; break;
+  }
+
+  // Emit a full diagnostic for the path if we have a PathDiagnosticClient.
+  if (!PD)
+    return;
+
+  if (D->empty()) {
+    PathDiagnosticPiece* piece =
+      new PathDiagnosticEventPiece(L, R->getDescription());
+
+    for ( ; Beg != End; ++Beg) piece->addRange(*Beg);
+    D->push_back(piece);
+  }
+
+  PD->HandlePathDiagnostic(D.take());
+}
+
+void BugReporter::EmitBasicReport(llvm::StringRef name, llvm::StringRef str,
+                                  SourceLocation Loc,
+                                  SourceRange* RBeg, unsigned NumRanges) {
+  EmitBasicReport(name, "", str, Loc, RBeg, NumRanges);
+}
+
+void BugReporter::EmitBasicReport(llvm::StringRef name,
+                                  llvm::StringRef category,
+                                  llvm::StringRef str, SourceLocation Loc,
+                                  SourceRange* RBeg, unsigned NumRanges) {
+
+  // 'BT' will be owned by BugReporter as soon as we call 'EmitReport'.
+  BugType *BT = new BugType(name, category);
+  FullSourceLoc L = getContext().getFullLoc(Loc);
+  RangedBugReport *R = new DiagBugReport(*BT, str, L);
+  for ( ; NumRanges > 0 ; --NumRanges, ++RBeg) R->addRange(*RBeg);
+  EmitReport(R);
+}
diff --git a/lib/Checker/BugReporterVisitors.cpp b/lib/Checker/BugReporterVisitors.cpp
new file mode 100644
index 0000000..776e12b
--- /dev/null
+++ b/lib/Checker/BugReporterVisitors.cpp
@@ -0,0 +1,423 @@
+// BugReporterVisitors.cpp - Helpers for reporting bugs -----------*- C++ -*--//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines a set of BugReporter "visitors" which can be used to
+//  enhance the diagnostics reported for a bug.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprObjC.h"
+#include "clang/Checker/BugReporter/BugReporter.h"
+#include "clang/Checker/BugReporter/PathDiagnostic.h"
+#include "clang/Checker/PathSensitive/ExplodedGraph.h"
+#include "clang/Checker/PathSensitive/GRState.h"
+
+using namespace clang;
+
+//===----------------------------------------------------------------------===//
+// Utility functions.
+//===----------------------------------------------------------------------===//
+
+const Stmt *clang::bugreporter::GetDerefExpr(const ExplodedNode *N) {
+  // Pattern match for a few useful cases (do something smarter later):
+  //   a[0], p->f, *p
+  const Stmt *S = N->getLocationAs<PostStmt>()->getStmt();
+
+  if (const UnaryOperator *U = dyn_cast<UnaryOperator>(S)) {
+    if (U->getOpcode() == UnaryOperator::Deref)
+      return U->getSubExpr()->IgnoreParenCasts();
+  }
+  else if (const MemberExpr *ME = dyn_cast<MemberExpr>(S)) {
+    return ME->getBase()->IgnoreParenCasts();
+  }
+  else if (const ArraySubscriptExpr *AE = dyn_cast<ArraySubscriptExpr>(S)) {
+    // Retrieve the base for arrays since BasicStoreManager doesn't know how
+    // to reason about them.
+    return AE->getBase();
+  }
+
+  return NULL;
+}
+
+const Stmt*
+clang::bugreporter::GetDenomExpr(const ExplodedNode *N) {
+  const Stmt *S = N->getLocationAs<PreStmt>()->getStmt();
+  if (const BinaryOperator *BE = dyn_cast<BinaryOperator>(S))
+    return BE->getRHS();
+  return NULL;
+}
+
+const Stmt*
+clang::bugreporter::GetCalleeExpr(const ExplodedNode *N) {
+  // Callee is checked as a PreVisit to the CallExpr.
+  const Stmt *S = N->getLocationAs<PreStmt>()->getStmt();
+  if (const CallExpr *CE = dyn_cast<CallExpr>(S))
+    return CE->getCallee();
+  return NULL;
+}
+
+const Stmt*
+clang::bugreporter::GetRetValExpr(const ExplodedNode *N) {
+  const Stmt *S = N->getLocationAs<PostStmt>()->getStmt();
+  if (const ReturnStmt *RS = dyn_cast<ReturnStmt>(S))
+    return RS->getRetValue();
+  return NULL;
+}
+
+//===----------------------------------------------------------------------===//
+// Definitions for bug reporter visitors.
+//===----------------------------------------------------------------------===//
+
+namespace {
+class FindLastStoreBRVisitor : public BugReporterVisitor {
+  const MemRegion *R;
+  SVal V;
+  bool satisfied;
+  const ExplodedNode *StoreSite;
+public:
+  FindLastStoreBRVisitor(SVal v, const MemRegion *r)
+  : R(r), V(v), satisfied(false), StoreSite(0) {}
+
+  virtual void Profile(llvm::FoldingSetNodeID &ID) const {
+    static int tag = 0;
+    ID.AddPointer(&tag);
+    ID.AddPointer(R);
+    ID.Add(V);
+  }
+
+  PathDiagnosticPiece* VisitNode(const ExplodedNode *N,
+                                 const ExplodedNode *PrevN,
+                                 BugReporterContext& BRC) {
+
+    if (satisfied)
+      return NULL;
+
+    if (!StoreSite) {
+      const ExplodedNode *Node = N, *Last = NULL;
+
+      for ( ; Node ; Last = Node, Node = Node->getFirstPred()) {
+
+        if (const VarRegion *VR = dyn_cast<VarRegion>(R)) {
+          if (const PostStmt *P = Node->getLocationAs<PostStmt>())
+            if (const DeclStmt *DS = P->getStmtAs<DeclStmt>())
+              if (DS->getSingleDecl() == VR->getDecl()) {
+                Last = Node;
+                break;
+              }
+        }
+
+        if (Node->getState()->getSVal(R) != V)
+          break;
+      }
+
+      if (!Node || !Last) {
+        satisfied = true;
+        return NULL;
+      }
+
+      StoreSite = Last;
+    }
+
+    if (StoreSite != N)
+      return NULL;
+
+    satisfied = true;
+    llvm::SmallString<256> sbuf;
+    llvm::raw_svector_ostream os(sbuf);
+
+    if (const PostStmt *PS = N->getLocationAs<PostStmt>()) {
+      if (const DeclStmt *DS = PS->getStmtAs<DeclStmt>()) {
+
+        if (const VarRegion *VR = dyn_cast<VarRegion>(R)) {
+          os << "Variable '" << VR->getDecl() << "' ";
+        }
+        else
+          return NULL;
+
+        if (isa<loc::ConcreteInt>(V)) {
+          bool b = false;
+          ASTContext &C = BRC.getASTContext();
+          if (R->isBoundable()) {
+            if (const TypedRegion *TR = dyn_cast<TypedRegion>(R)) {
+              if (TR->getValueType(C)->isObjCObjectPointerType()) {
+                os << "initialized to nil";
+                b = true;
+              }
+            }
+          }
+
+          if (!b)
+            os << "initialized to a null pointer value";
+        }
+        else if (isa<nonloc::ConcreteInt>(V)) {
+          os << "initialized to " << cast<nonloc::ConcreteInt>(V).getValue();
+        }
+        else if (V.isUndef()) {
+          if (isa<VarRegion>(R)) {
+            const VarDecl *VD = cast<VarDecl>(DS->getSingleDecl());
+            if (VD->getInit())
+              os << "initialized to a garbage value";
+            else
+              os << "declared without an initial value";
+          }
+        }
+      }
+    }
+
+    if (os.str().empty()) {
+      if (isa<loc::ConcreteInt>(V)) {
+        bool b = false;
+        ASTContext &C = BRC.getASTContext();
+        if (R->isBoundable()) {
+          if (const TypedRegion *TR = dyn_cast<TypedRegion>(R)) {
+            if (TR->getValueType(C)->isObjCObjectPointerType()) {
+              os << "nil object reference stored to ";
+              b = true;
+            }
+          }
+        }
+
+        if (!b)
+          os << "Null pointer value stored to ";
+      }
+      else if (V.isUndef()) {
+        os << "Uninitialized value stored to ";
+      }
+      else if (isa<nonloc::ConcreteInt>(V)) {
+        os << "The value " << cast<nonloc::ConcreteInt>(V).getValue()
+           << " is assigned to ";
+      }
+      else
+        return NULL;
+
+      if (const VarRegion *VR = dyn_cast<VarRegion>(R)) {
+        os << '\'' << VR->getDecl() << '\'';
+      }
+      else
+        return NULL;
+    }
+
+    // FIXME: Refactor this into BugReporterContext.
+    const Stmt *S = 0;
+    ProgramPoint P = N->getLocation();
+
+    if (BlockEdge *BE = dyn_cast<BlockEdge>(&P)) {
+      CFGBlock *BSrc = BE->getSrc();
+      S = BSrc->getTerminatorCondition();
+    }
+    else if (PostStmt *PS = dyn_cast<PostStmt>(&P)) {
+      S = PS->getStmt();
+    }
+
+    if (!S)
+      return NULL;
+
+    // Construct a new PathDiagnosticPiece.
+    PathDiagnosticLocation L(S, BRC.getSourceManager());
+    return new PathDiagnosticEventPiece(L, os.str());
+  }
+};
+
+
+static void registerFindLastStore(BugReporterContext& BRC, const MemRegion *R,
+                                  SVal V) {
+  BRC.addVisitor(new FindLastStoreBRVisitor(V, R));
+}
+
+class TrackConstraintBRVisitor : public BugReporterVisitor {
+  DefinedSVal Constraint;
+  const bool Assumption;
+  bool isSatisfied;
+public:
+  TrackConstraintBRVisitor(DefinedSVal constraint, bool assumption)
+  : Constraint(constraint), Assumption(assumption), isSatisfied(false) {}
+
+  void Profile(llvm::FoldingSetNodeID &ID) const {
+    static int tag = 0;
+    ID.AddPointer(&tag);
+    ID.AddBoolean(Assumption);
+    ID.Add(Constraint);
+  }
+
+  PathDiagnosticPiece* VisitNode(const ExplodedNode *N,
+                                 const ExplodedNode *PrevN,
+                                 BugReporterContext& BRC) {
+    if (isSatisfied)
+      return NULL;
+
+    // Check if in the previous state it was feasible for this constraint
+    // to *not* be true.
+    if (PrevN->getState()->Assume(Constraint, !Assumption)) {
+
+      isSatisfied = true;
+
+      // As a sanity check, make sure that the negation of the constraint
+      // was infeasible in the current state.  If it is feasible, we somehow
+      // missed the transition point.
+      if (N->getState()->Assume(Constraint, !Assumption))
+        return NULL;
+
+      // We found the transition point for the constraint.  We now need to
+      // pretty-print the constraint. (work-in-progress)
+      std::string sbuf;
+      llvm::raw_string_ostream os(sbuf);
+
+      if (isa<Loc>(Constraint)) {
+        os << "Assuming pointer value is ";
+        os << (Assumption ? "non-null" : "null");
+      }
+
+      if (os.str().empty())
+        return NULL;
+
+      // FIXME: Refactor this into BugReporterContext.
+      const Stmt *S = 0;
+      ProgramPoint P = N->getLocation();
+
+      if (BlockEdge *BE = dyn_cast<BlockEdge>(&P)) {
+        CFGBlock *BSrc = BE->getSrc();
+        S = BSrc->getTerminatorCondition();
+      }
+      else if (PostStmt *PS = dyn_cast<PostStmt>(&P)) {
+        S = PS->getStmt();
+      }
+
+      if (!S)
+        return NULL;
+
+      // Construct a new PathDiagnosticPiece.
+      PathDiagnosticLocation L(S, BRC.getSourceManager());
+      return new PathDiagnosticEventPiece(L, os.str());
+    }
+
+    return NULL;
+  }
+};
+} // end anonymous namespace
+
+static void registerTrackConstraint(BugReporterContext& BRC,
+                                    DefinedSVal Constraint,
+                                    bool Assumption) {
+  BRC.addVisitor(new TrackConstraintBRVisitor(Constraint, Assumption));
+}
+
+void clang::bugreporter::registerTrackNullOrUndefValue(BugReporterContext& BRC,
+                                                       const void *data,
+                                                       const ExplodedNode* N) {
+
+  const Stmt *S = static_cast<const Stmt*>(data);
+
+  if (!S)
+    return;
+
+  GRStateManager &StateMgr = BRC.getStateManager();
+  const GRState *state = N->getState();
+
+  if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(S)) {
+    if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
+      const VarRegion *R =
+      StateMgr.getRegionManager().getVarRegion(VD, N->getLocationContext());
+
+      // What did we load?
+      SVal V = state->getSVal(S);
+
+      if (isa<loc::ConcreteInt>(V) || isa<nonloc::ConcreteInt>(V)
+          || V.isUndef()) {
+        ::registerFindLastStore(BRC, R, V);
+      }
+    }
+  }
+
+  SVal V = state->getSValAsScalarOrLoc(S);
+
+  // Uncomment this to find cases where we aren't properly getting the
+  // base value that was dereferenced.
+  // assert(!V.isUnknownOrUndef());
+
+  // Is it a symbolic value?
+  if (loc::MemRegionVal *L = dyn_cast<loc::MemRegionVal>(&V)) {
+    const SubRegion *R = cast<SubRegion>(L->getRegion());
+    while (R && !isa<SymbolicRegion>(R)) {
+      R = dyn_cast<SubRegion>(R->getSuperRegion());
+    }
+
+    if (R) {
+      assert(isa<SymbolicRegion>(R));
+      registerTrackConstraint(BRC, loc::MemRegionVal(R), false);
+    }
+  }
+}
+
+void clang::bugreporter::registerFindLastStore(BugReporterContext& BRC,
+                                               const void *data,
+                                               const ExplodedNode* N) {
+
+  const MemRegion *R = static_cast<const MemRegion*>(data);
+
+  if (!R)
+    return;
+
+  const GRState *state = N->getState();
+  SVal V = state->getSVal(R);
+
+  if (V.isUnknown())
+    return;
+
+  BRC.addVisitor(new FindLastStoreBRVisitor(V, R));
+}
+
+
+namespace {
+class NilReceiverVisitor : public BugReporterVisitor {
+public:
+  NilReceiverVisitor() {}
+
+  void Profile(llvm::FoldingSetNodeID &ID) const {
+    static int x = 0;
+    ID.AddPointer(&x);
+  }
+
+  PathDiagnosticPiece* VisitNode(const ExplodedNode *N,
+                                 const ExplodedNode *PrevN,
+                                 BugReporterContext& BRC) {
+
+    const PostStmt *P = N->getLocationAs<PostStmt>();
+    if (!P)
+      return 0;
+    const ObjCMessageExpr *ME = P->getStmtAs<ObjCMessageExpr>();
+    if (!ME)
+      return 0;
+    const Expr *Receiver = ME->getInstanceReceiver();
+    if (!Receiver)
+      return 0;
+    const GRState *state = N->getState();
+    const SVal &V = state->getSVal(Receiver);
+    const DefinedOrUnknownSVal *DV = dyn_cast<DefinedOrUnknownSVal>(&V);
+    if (!DV)
+      return 0;
+    state = state->Assume(*DV, true);
+    if (state)
+      return 0;
+
+    // The receiver was nil, and hence the method was skipped.
+    // Register a BugReporterVisitor to issue a message telling us how
+    // the receiver was null.
+    bugreporter::registerTrackNullOrUndefValue(BRC, Receiver, N);
+    // Issue a message saying that the method was skipped.
+    PathDiagnosticLocation L(Receiver, BRC.getSourceManager());
+    return new PathDiagnosticEventPiece(L, "No method actually called "
+                                           "because the receiver is nil");
+  }
+};
+} // end anonymous namespace
+
+void clang::bugreporter::registerNilReceiverVisitor(BugReporterContext &BRC) {
+  BRC.addVisitor(new NilReceiverVisitor());
+}
diff --git a/lib/Checker/BuiltinFunctionChecker.cpp b/lib/Checker/BuiltinFunctionChecker.cpp
new file mode 100644
index 0000000..9c8b516
--- /dev/null
+++ b/lib/Checker/BuiltinFunctionChecker.cpp
@@ -0,0 +1,75 @@
+//=== BuiltinFunctionChecker.cpp --------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This checker evaluates clang builtin functions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "GRExprEngineInternalChecks.h"
+#include "clang/Checker/PathSensitive/Checker.h"
+#include "clang/Basic/Builtins.h"
+
+using namespace clang;
+
+namespace {
+
+class BuiltinFunctionChecker : public Checker {
+public:
+  static void *getTag() { static int tag = 0; return &tag; }
+  virtual bool EvalCallExpr(CheckerContext &C, const CallExpr *CE);
+};
+
+}
+
+void clang::RegisterBuiltinFunctionChecker(GRExprEngine &Eng) {
+  Eng.registerCheck(new BuiltinFunctionChecker());
+}
+
+bool BuiltinFunctionChecker::EvalCallExpr(CheckerContext &C,const CallExpr *CE){
+  const GRState *state = C.getState();
+  const Expr *Callee = CE->getCallee();
+  SVal L = state->getSVal(Callee);
+  const FunctionDecl *FD = L.getAsFunctionDecl();
+
+  if (!FD)
+    return false;
+
+  unsigned id = FD->getBuiltinID();
+
+  if (!id)
+    return false;
+
+  switch (id) {
+  case Builtin::BI__builtin_expect: {
+    // For __builtin_expect, just return the value of the subexpression.
+    assert (CE->arg_begin() != CE->arg_end());
+    SVal X = state->getSVal(*(CE->arg_begin()));
+    C.GenerateNode(state->BindExpr(CE, X));
+    return true;
+  }
+
+  case Builtin::BI__builtin_alloca: {
+    // FIXME: Refactor into StoreManager itself?
+    MemRegionManager& RM = C.getStoreManager().getRegionManager();
+    const MemRegion* R =
+      RM.getAllocaRegion(CE, C.getNodeBuilder().getCurrentBlockCount(),
+                         C.getPredecessor()->getLocationContext());
+
+    // Set the extent of the region in bytes. This enables us to use the
+    // SVal of the argument directly. If we save the extent in bits, we
+    // cannot represent values like symbol*8.
+    SVal Extent = state->getSVal(*(CE->arg_begin()));
+    state = C.getStoreManager().setExtent(state, R, Extent);
+    C.GenerateNode(state->BindExpr(CE, loc::MemRegionVal(R)));
+    return true;
+  }
+  }
+
+  return false;
+}
diff --git a/lib/Checker/CFRefCount.cpp b/lib/Checker/CFRefCount.cpp
new file mode 100644
index 0000000..d26ee1d
--- /dev/null
+++ b/lib/Checker/CFRefCount.cpp
@@ -0,0 +1,3575 @@
+// CFRefCount.cpp - Transfer functions for tracking simple values -*- C++ -*--//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the methods for CFRefCount, which implements
+//  a reference count checker for Core Foundation (Mac OS X).
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/StmtVisitor.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Checker/BugReporter/BugType.h"
+#include "clang/Checker/BugReporter/PathDiagnostic.h"
+#include "clang/Checker/Checkers/LocalCheckers.h"
+#include "clang/Checker/DomainSpecific/CocoaConventions.h"
+#include "clang/Checker/PathSensitive/CheckerVisitor.h"
+#include "clang/Checker/PathSensitive/GRExprEngineBuilders.h"
+#include "clang/Checker/PathSensitive/GRStateTrait.h"
+#include "clang/Checker/PathSensitive/GRTransferFuncs.h"
+#include "clang/Checker/PathSensitive/SymbolManager.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/ImmutableList.h"
+#include "llvm/ADT/ImmutableMap.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringExtras.h"
+#include <stdarg.h>
+
+using namespace clang;
+using llvm::StringRef;
+using llvm::StrInStrNoCase;
+
+static const ObjCMethodDecl*
+ResolveToInterfaceMethodDecl(const ObjCMethodDecl *MD) {
+  ObjCInterfaceDecl *ID =
+    const_cast<ObjCInterfaceDecl*>(MD->getClassInterface());
+
+  return MD->isInstanceMethod()
+         ? ID->lookupInstanceMethod(MD->getSelector())
+         : ID->lookupClassMethod(MD->getSelector());
+}
+
+namespace {
+class GenericNodeBuilder {
+  GRStmtNodeBuilder *SNB;
+  Stmt *S;
+  const void *tag;
+  GREndPathNodeBuilder *ENB;
+public:
+  GenericNodeBuilder(GRStmtNodeBuilder &snb, Stmt *s,
+                     const void *t)
+  : SNB(&snb), S(s), tag(t), ENB(0) {}
+
+  GenericNodeBuilder(GREndPathNodeBuilder &enb)
+  : SNB(0), S(0), tag(0), ENB(&enb) {}
+
+  ExplodedNode *MakeNode(const GRState *state, ExplodedNode *Pred) {
+    if (SNB)
+      return SNB->generateNode(PostStmt(S, Pred->getLocationContext(), tag),
+                               state, Pred);
+
+    assert(ENB);
+    return ENB->generateNode(state, Pred);
+  }
+};
+} // end anonymous namespace
+
+//===----------------------------------------------------------------------===//
+// Primitives used for constructing summaries for function/method calls.
+//===----------------------------------------------------------------------===//
+
+/// ArgEffect is used to summarize a function/method call's effect on a
+/// particular argument.
+enum ArgEffect { Autorelease, Dealloc, DecRef, DecRefMsg, DoNothing,
+                 DoNothingByRef, IncRefMsg, IncRef, MakeCollectable, MayEscape,
+                 NewAutoreleasePool, SelfOwn, StopTracking };
+
+namespace llvm {
+template <> struct FoldingSetTrait<ArgEffect> {
+static inline void Profile(const ArgEffect X, FoldingSetNodeID& ID) {
+  ID.AddInteger((unsigned) X);
+}
+};
+} // end llvm namespace
+
+/// ArgEffects summarizes the effects of a function/method call on all of
+/// its arguments.
+typedef llvm::ImmutableMap<unsigned,ArgEffect> ArgEffects;
+
+namespace {
+
+///  RetEffect is used to summarize a function/method call's behavior with
+///  respect to its return value.
+class RetEffect {
+public:
+  enum Kind { NoRet, Alias, OwnedSymbol, OwnedAllocatedSymbol,
+              NotOwnedSymbol, GCNotOwnedSymbol, ReceiverAlias,
+              OwnedWhenTrackedReceiver };
+
+  enum ObjKind { CF, ObjC, AnyObj };
+
+private:
+  Kind K;
+  ObjKind O;
+  unsigned index;
+
+  RetEffect(Kind k, unsigned idx = 0) : K(k), O(AnyObj), index(idx) {}
+  RetEffect(Kind k, ObjKind o) : K(k), O(o), index(0) {}
+
+public:
+  Kind getKind() const { return K; }
+
+  ObjKind getObjKind() const { return O; }
+
+  unsigned getIndex() const {
+    assert(getKind() == Alias);
+    return index;
+  }
+
+  bool isOwned() const {
+    return K == OwnedSymbol || K == OwnedAllocatedSymbol ||
+           K == OwnedWhenTrackedReceiver;
+  }
+
+  static RetEffect MakeOwnedWhenTrackedReceiver() {
+    return RetEffect(OwnedWhenTrackedReceiver, ObjC);
+  }
+
+  static RetEffect MakeAlias(unsigned Idx) {
+    return RetEffect(Alias, Idx);
+  }
+  static RetEffect MakeReceiverAlias() {
+    return RetEffect(ReceiverAlias);
+  }
+  static RetEffect MakeOwned(ObjKind o, bool isAllocated = false) {
+    return RetEffect(isAllocated ? OwnedAllocatedSymbol : OwnedSymbol, o);
+  }
+  static RetEffect MakeNotOwned(ObjKind o) {
+    return RetEffect(NotOwnedSymbol, o);
+  }
+  static RetEffect MakeGCNotOwned() {
+    return RetEffect(GCNotOwnedSymbol, ObjC);
+  }
+
+  static RetEffect MakeNoRet() {
+    return RetEffect(NoRet);
+  }
+
+  void Profile(llvm::FoldingSetNodeID& ID) const {
+    ID.AddInteger((unsigned)K);
+    ID.AddInteger((unsigned)O);
+    ID.AddInteger(index);
+  }
+};
+
+//===----------------------------------------------------------------------===//
+// Reference-counting logic (typestate + counts).
+//===----------------------------------------------------------------------===//
+
+class RefVal {
+public:
+  enum Kind {
+    Owned = 0, // Owning reference.
+    NotOwned,  // Reference is not owned by still valid (not freed).
+    Released,  // Object has been released.
+    ReturnedOwned, // Returned object passes ownership to caller.
+    ReturnedNotOwned, // Return object does not pass ownership to caller.
+    ERROR_START,
+    ErrorDeallocNotOwned, // -dealloc called on non-owned object.
+    ErrorDeallocGC, // Calling -dealloc with GC enabled.
+    ErrorUseAfterRelease, // Object used after released.
+    ErrorReleaseNotOwned, // Release of an object that was not owned.
+    ERROR_LEAK_START,
+    ErrorLeak,  // A memory leak due to excessive reference counts.
+    ErrorLeakReturned, // A memory leak due to the returning method not having
+                       // the correct naming conventions.
+    ErrorGCLeakReturned,
+    ErrorOverAutorelease,
+    ErrorReturnedNotOwned
+  };
+  
+private:
+  Kind kind;
+  RetEffect::ObjKind okind;
+  unsigned Cnt;
+  unsigned ACnt;
+  QualType T;
+  
+  RefVal(Kind k, RetEffect::ObjKind o, unsigned cnt, unsigned acnt, QualType t)
+  : kind(k), okind(o), Cnt(cnt), ACnt(acnt), T(t) {}
+  
+  RefVal(Kind k, unsigned cnt = 0)
+  : kind(k), okind(RetEffect::AnyObj), Cnt(cnt), ACnt(0) {}
+  
+public:
+  Kind getKind() const { return kind; }
+  
+  RetEffect::ObjKind getObjKind() const { return okind; }
+  
+  unsigned getCount() const { return Cnt; }
+  unsigned getAutoreleaseCount() const { return ACnt; }
+  unsigned getCombinedCounts() const { return Cnt + ACnt; }
+  void clearCounts() { Cnt = 0; ACnt = 0; }
+  void setCount(unsigned i) { Cnt = i; }
+  void setAutoreleaseCount(unsigned i) { ACnt = i; }
+  
+  QualType getType() const { return T; }
+  
+  // Useful predicates.
+  
+  static bool isError(Kind k) { return k >= ERROR_START; }
+  
+  static bool isLeak(Kind k) { return k >= ERROR_LEAK_START; }
+  
+  bool isOwned() const {
+    return getKind() == Owned;
+  }
+  
+  bool isNotOwned() const {
+    return getKind() == NotOwned;
+  }
+  
+  bool isReturnedOwned() const {
+    return getKind() == ReturnedOwned;
+  }
+  
+  bool isReturnedNotOwned() const {
+    return getKind() == ReturnedNotOwned;
+  }
+  
+  bool isNonLeakError() const {
+    Kind k = getKind();
+    return isError(k) && !isLeak(k);
+  }
+  
+  static RefVal makeOwned(RetEffect::ObjKind o, QualType t,
+                          unsigned Count = 1) {
+    return RefVal(Owned, o, Count, 0, t);
+  }
+  
+  static RefVal makeNotOwned(RetEffect::ObjKind o, QualType t,
+                             unsigned Count = 0) {
+    return RefVal(NotOwned, o, Count, 0, t);
+  }
+  
+  // Comparison, profiling, and pretty-printing.
+  
+  bool operator==(const RefVal& X) const {
+    return kind == X.kind && Cnt == X.Cnt && T == X.T && ACnt == X.ACnt;
+  }
+  
+  RefVal operator-(size_t i) const {
+    return RefVal(getKind(), getObjKind(), getCount() - i,
+                  getAutoreleaseCount(), getType());
+  }
+  
+  RefVal operator+(size_t i) const {
+    return RefVal(getKind(), getObjKind(), getCount() + i,
+                  getAutoreleaseCount(), getType());
+  }
+  
+  RefVal operator^(Kind k) const {
+    return RefVal(k, getObjKind(), getCount(), getAutoreleaseCount(),
+                  getType());
+  }
+  
+  RefVal autorelease() const {
+    return RefVal(getKind(), getObjKind(), getCount(), getAutoreleaseCount()+1,
+                  getType());
+  }
+  
+  void Profile(llvm::FoldingSetNodeID& ID) const {
+    ID.AddInteger((unsigned) kind);
+    ID.AddInteger(Cnt);
+    ID.AddInteger(ACnt);
+    ID.Add(T);
+  }
+  
+  void print(llvm::raw_ostream& Out) const;
+};
+
+void RefVal::print(llvm::raw_ostream& Out) const {
+  if (!T.isNull())
+    Out << "Tracked Type:" << T.getAsString() << '\n';
+  
+  switch (getKind()) {
+    default: assert(false);
+    case Owned: {
+      Out << "Owned";
+      unsigned cnt = getCount();
+      if (cnt) Out << " (+ " << cnt << ")";
+      break;
+    }
+      
+    case NotOwned: {
+      Out << "NotOwned";
+      unsigned cnt = getCount();
+      if (cnt) Out << " (+ " << cnt << ")";
+      break;
+    }
+      
+    case ReturnedOwned: {
+      Out << "ReturnedOwned";
+      unsigned cnt = getCount();
+      if (cnt) Out << " (+ " << cnt << ")";
+      break;
+    }
+      
+    case ReturnedNotOwned: {
+      Out << "ReturnedNotOwned";
+      unsigned cnt = getCount();
+      if (cnt) Out << " (+ " << cnt << ")";
+      break;
+    }
+      
+    case Released:
+      Out << "Released";
+      break;
+      
+    case ErrorDeallocGC:
+      Out << "-dealloc (GC)";
+      break;
+      
+    case ErrorDeallocNotOwned:
+      Out << "-dealloc (not-owned)";
+      break;
+      
+    case ErrorLeak:
+      Out << "Leaked";
+      break;
+      
+    case ErrorLeakReturned:
+      Out << "Leaked (Bad naming)";
+      break;
+      
+    case ErrorGCLeakReturned:
+      Out << "Leaked (GC-ed at return)";
+      break;
+      
+    case ErrorUseAfterRelease:
+      Out << "Use-After-Release [ERROR]";
+      break;
+      
+    case ErrorReleaseNotOwned:
+      Out << "Release of Not-Owned [ERROR]";
+      break;
+      
+    case RefVal::ErrorOverAutorelease:
+      Out << "Over autoreleased";
+      break;
+      
+    case RefVal::ErrorReturnedNotOwned:
+      Out << "Non-owned object returned instead of owned";
+      break;
+  }
+  
+  if (ACnt) {
+    Out << " [ARC +" << ACnt << ']';
+  }
+}
+} //end anonymous namespace
+
+//===----------------------------------------------------------------------===//
+// RefBindings - State used to track object reference counts.
+//===----------------------------------------------------------------------===//
+
+typedef llvm::ImmutableMap<SymbolRef, RefVal> RefBindings;
+
+namespace clang {
+  template<>
+  struct GRStateTrait<RefBindings> : public GRStatePartialTrait<RefBindings> {
+    static void* GDMIndex() {
+      static int RefBIndex = 0;
+      return &RefBIndex;
+    }
+  };
+}
+
+//===----------------------------------------------------------------------===//
+// Summaries
+//===----------------------------------------------------------------------===//
+
+namespace {
+class RetainSummary {
+  /// Args - an ordered vector of (index, ArgEffect) pairs, where index
+  ///  specifies the argument (starting from 0).  This can be sparsely
+  ///  populated; arguments with no entry in Args use 'DefaultArgEffect'.
+  ArgEffects Args;
+
+  /// DefaultArgEffect - The default ArgEffect to apply to arguments that
+  ///  do not have an entry in Args.
+  ArgEffect   DefaultArgEffect;
+
+  /// Receiver - If this summary applies to an Objective-C message expression,
+  ///  this is the effect applied to the state of the receiver.
+  ArgEffect   Receiver;
+
+  /// Ret - The effect on the return value.  Used to indicate if the
+  ///  function/method call returns a new tracked symbol, returns an
+  ///  alias of one of the arguments in the call, and so on.
+  RetEffect   Ret;
+
+  /// EndPath - Indicates that execution of this method/function should
+  ///  terminate the simulation of a path.
+  bool EndPath;
+
+public:
+  RetainSummary(ArgEffects A, RetEffect R, ArgEffect defaultEff,
+                ArgEffect ReceiverEff, bool endpath = false)
+    : Args(A), DefaultArgEffect(defaultEff), Receiver(ReceiverEff), Ret(R),
+      EndPath(endpath) {}
+
+  /// getArg - Return the argument effect on the argument specified by
+  ///  idx (starting from 0).
+  ArgEffect getArg(unsigned idx) const {
+    if (const ArgEffect *AE = Args.lookup(idx))
+      return *AE;
+
+    return DefaultArgEffect;
+  }
+
+  /// setDefaultArgEffect - Set the default argument effect.
+  void setDefaultArgEffect(ArgEffect E) {
+    DefaultArgEffect = E;
+  }
+
+  /// setArg - Set the argument effect on the argument specified by idx.
+  void setArgEffect(ArgEffects::Factory& AF, unsigned idx, ArgEffect E) {
+    Args = AF.Add(Args, idx, E);
+  }
+
+  /// getRetEffect - Returns the effect on the return value of the call.
+  RetEffect getRetEffect() const { return Ret; }
+
+  /// setRetEffect - Set the effect of the return value of the call.
+  void setRetEffect(RetEffect E) { Ret = E; }
+
+  /// isEndPath - Returns true if executing the given method/function should
+  ///  terminate the path.
+  bool isEndPath() const { return EndPath; }
+
+  /// getReceiverEffect - Returns the effect on the receiver of the call.
+  ///  This is only meaningful if the summary applies to an ObjCMessageExpr*.
+  ArgEffect getReceiverEffect() const { return Receiver; }
+
+  /// setReceiverEffect - Set the effect on the receiver of the call.
+  void setReceiverEffect(ArgEffect E) { Receiver = E; }
+
+  typedef ArgEffects::iterator ExprIterator;
+
+  ExprIterator begin_args() const { return Args.begin(); }
+  ExprIterator end_args()   const { return Args.end(); }
+
+  static void Profile(llvm::FoldingSetNodeID& ID, ArgEffects A,
+                      RetEffect RetEff, ArgEffect DefaultEff,
+                      ArgEffect ReceiverEff, bool EndPath) {
+    ID.Add(A);
+    ID.Add(RetEff);
+    ID.AddInteger((unsigned) DefaultEff);
+    ID.AddInteger((unsigned) ReceiverEff);
+    ID.AddInteger((unsigned) EndPath);
+  }
+
+  void Profile(llvm::FoldingSetNodeID& ID) const {
+    Profile(ID, Args, Ret, DefaultArgEffect, Receiver, EndPath);
+  }
+};
+} // end anonymous namespace
+
+//===----------------------------------------------------------------------===//
+// Data structures for constructing summaries.
+//===----------------------------------------------------------------------===//
+
+namespace {
+class ObjCSummaryKey {
+  IdentifierInfo* II;
+  Selector S;
+public:
+  ObjCSummaryKey(IdentifierInfo* ii, Selector s)
+    : II(ii), S(s) {}
+
+  ObjCSummaryKey(const ObjCInterfaceDecl* d, Selector s)
+    : II(d ? d->getIdentifier() : 0), S(s) {}
+
+  ObjCSummaryKey(const ObjCInterfaceDecl* d, IdentifierInfo *ii, Selector s)
+    : II(d ? d->getIdentifier() : ii), S(s) {}
+
+  ObjCSummaryKey(Selector s)
+    : II(0), S(s) {}
+
+  IdentifierInfo* getIdentifier() const { return II; }
+  Selector getSelector() const { return S; }
+};
+}
+
+namespace llvm {
+template <> struct DenseMapInfo<ObjCSummaryKey> {
+  static inline ObjCSummaryKey getEmptyKey() {
+    return ObjCSummaryKey(DenseMapInfo<IdentifierInfo*>::getEmptyKey(),
+                          DenseMapInfo<Selector>::getEmptyKey());
+  }
+
+  static inline ObjCSummaryKey getTombstoneKey() {
+    return ObjCSummaryKey(DenseMapInfo<IdentifierInfo*>::getTombstoneKey(),
+                          DenseMapInfo<Selector>::getTombstoneKey());
+  }
+
+  static unsigned getHashValue(const ObjCSummaryKey &V) {
+    return (DenseMapInfo<IdentifierInfo*>::getHashValue(V.getIdentifier())
+            & 0x88888888)
+        | (DenseMapInfo<Selector>::getHashValue(V.getSelector())
+            & 0x55555555);
+  }
+
+  static bool isEqual(const ObjCSummaryKey& LHS, const ObjCSummaryKey& RHS) {
+    return DenseMapInfo<IdentifierInfo*>::isEqual(LHS.getIdentifier(),
+                                                  RHS.getIdentifier()) &&
+           DenseMapInfo<Selector>::isEqual(LHS.getSelector(),
+                                           RHS.getSelector());
+  }
+
+};
+template <>
+struct isPodLike<ObjCSummaryKey> { static const bool value = true; };
+} // end llvm namespace
+
+namespace {
+class ObjCSummaryCache {
+  typedef llvm::DenseMap<ObjCSummaryKey, RetainSummary*> MapTy;
+  MapTy M;
+public:
+  ObjCSummaryCache() {}
+
+  RetainSummary* find(const ObjCInterfaceDecl* D, IdentifierInfo *ClsName,
+                Selector S) {
+    // Lookup the method using the decl for the class @interface.  If we
+    // have no decl, lookup using the class name.
+    return D ? find(D, S) : find(ClsName, S);
+  }
+
+  RetainSummary* find(const ObjCInterfaceDecl* D, Selector S) {
+    // Do a lookup with the (D,S) pair.  If we find a match return
+    // the iterator.
+    ObjCSummaryKey K(D, S);
+    MapTy::iterator I = M.find(K);
+
+    if (I != M.end() || !D)
+      return I->second;
+
+    // Walk the super chain.  If we find a hit with a parent, we'll end
+    // up returning that summary.  We actually allow that key (null,S), as
+    // we cache summaries for the null ObjCInterfaceDecl* to allow us to
+    // generate initial summaries without having to worry about NSObject
+    // being declared.
+    // FIXME: We may change this at some point.
+    for (ObjCInterfaceDecl* C=D->getSuperClass() ;; C=C->getSuperClass()) {
+      if ((I = M.find(ObjCSummaryKey(C, S))) != M.end())
+        break;
+
+      if (!C)
+        return NULL;
+    }
+
+    // Cache the summary with original key to make the next lookup faster
+    // and return the iterator.
+    RetainSummary *Summ = I->second;
+    M[K] = Summ;
+    return Summ;
+  }
+
+
+  RetainSummary* find(Expr* Receiver, Selector S) {
+    return find(getReceiverDecl(Receiver), S);
+  }
+
+  RetainSummary* find(IdentifierInfo* II, Selector S) {
+    // FIXME: Class method lookup.  Right now we dont' have a good way
+    // of going between IdentifierInfo* and the class hierarchy.
+    MapTy::iterator I = M.find(ObjCSummaryKey(II, S));
+
+    if (I == M.end())
+      I = M.find(ObjCSummaryKey(S));
+
+    return I == M.end() ? NULL : I->second;
+  }
+
+  const ObjCInterfaceDecl* getReceiverDecl(Expr* E) {
+    if (const ObjCObjectPointerType* PT =
+        E->getType()->getAs<ObjCObjectPointerType>())
+      return PT->getInterfaceDecl();
+
+    return NULL;
+  }
+
+  RetainSummary*& operator[](ObjCMessageExpr* ME) {
+
+    Selector S = ME->getSelector();
+
+    const ObjCInterfaceDecl* OD = 0;
+    bool IsInstanceMessage = false;
+    switch (ME->getReceiverKind()) {
+    case ObjCMessageExpr::Instance:
+      OD = getReceiverDecl(ME->getInstanceReceiver());
+      IsInstanceMessage = true;
+      break;
+
+    case ObjCMessageExpr::SuperInstance:
+      IsInstanceMessage = true;
+      OD = ME->getSuperType()->getAs<ObjCObjectPointerType>()
+                                                        ->getInterfaceDecl();
+      break;
+
+    case ObjCMessageExpr::Class:
+      OD = ME->getClassReceiver()->getAs<ObjCInterfaceType>()->getDecl();
+      break;
+
+    case ObjCMessageExpr::SuperClass:
+      OD = ME->getSuperType()->getAs<ObjCInterfaceType>()->getDecl();
+      break;
+    }
+
+    if (IsInstanceMessage)
+      return OD ? M[ObjCSummaryKey(OD->getIdentifier(), S)] : M[S];
+
+    return M[ObjCSummaryKey(OD->getIdentifier(), S)];
+  }
+
+  RetainSummary*& operator[](ObjCSummaryKey K) {
+    return M[K];
+  }
+
+  RetainSummary*& operator[](Selector S) {
+    return M[ ObjCSummaryKey(S) ];
+  }
+};
+} // end anonymous namespace
+
+//===----------------------------------------------------------------------===//
+// Data structures for managing collections of summaries.
+//===----------------------------------------------------------------------===//
+
+namespace {
+class RetainSummaryManager {
+
+  //==-----------------------------------------------------------------==//
+  //  Typedefs.
+  //==-----------------------------------------------------------------==//
+
+  typedef llvm::DenseMap<FunctionDecl*, RetainSummary*>
+          FuncSummariesTy;
+
+  typedef ObjCSummaryCache ObjCMethodSummariesTy;
+
+  //==-----------------------------------------------------------------==//
+  //  Data.
+  //==-----------------------------------------------------------------==//
+
+  /// Ctx - The ASTContext object for the analyzed ASTs.
+  ASTContext& Ctx;
+
+  /// CFDictionaryCreateII - An IdentifierInfo* representing the indentifier
+  ///  "CFDictionaryCreate".
+  IdentifierInfo* CFDictionaryCreateII;
+
+  /// GCEnabled - Records whether or not the analyzed code runs in GC mode.
+  const bool GCEnabled;
+
+  /// FuncSummaries - A map from FunctionDecls to summaries.
+  FuncSummariesTy FuncSummaries;
+
+  /// ObjCClassMethodSummaries - A map from selectors (for instance methods)
+  ///  to summaries.
+  ObjCMethodSummariesTy ObjCClassMethodSummaries;
+
+  /// ObjCMethodSummaries - A map from selectors to summaries.
+  ObjCMethodSummariesTy ObjCMethodSummaries;
+
+  /// BPAlloc - A BumpPtrAllocator used for allocating summaries, ArgEffects,
+  ///  and all other data used by the checker.
+  llvm::BumpPtrAllocator BPAlloc;
+
+  /// AF - A factory for ArgEffects objects.
+  ArgEffects::Factory AF;
+
+  /// ScratchArgs - A holding buffer for construct ArgEffects.
+  ArgEffects ScratchArgs;
+
+  /// ObjCAllocRetE - Default return effect for methods returning Objective-C
+  ///  objects.
+  RetEffect ObjCAllocRetE;
+
+  /// ObjCInitRetE - Default return effect for init methods returning
+  ///   Objective-C objects.
+  RetEffect ObjCInitRetE;
+
+  RetainSummary DefaultSummary;
+  RetainSummary* StopSummary;
+
+  //==-----------------------------------------------------------------==//
+  //  Methods.
+  //==-----------------------------------------------------------------==//
+
+  /// getArgEffects - Returns a persistent ArgEffects object based on the
+  ///  data in ScratchArgs.
+  ArgEffects getArgEffects();
+
+  enum UnaryFuncKind { cfretain, cfrelease, cfmakecollectable };
+
+public:
+  RetEffect getObjAllocRetEffect() const { return ObjCAllocRetE; }
+
+  RetainSummary *getDefaultSummary() {
+    RetainSummary *Summ = (RetainSummary*) BPAlloc.Allocate<RetainSummary>();
+    return new (Summ) RetainSummary(DefaultSummary);
+  }
+
+  RetainSummary* getUnarySummary(const FunctionType* FT, UnaryFuncKind func);
+
+  RetainSummary* getCFSummaryCreateRule(FunctionDecl* FD);
+  RetainSummary* getCFSummaryGetRule(FunctionDecl* FD);
+  RetainSummary* getCFCreateGetRuleSummary(FunctionDecl* FD, StringRef FName);
+
+  RetainSummary* getPersistentSummary(ArgEffects AE, RetEffect RetEff,
+                                      ArgEffect ReceiverEff = DoNothing,
+                                      ArgEffect DefaultEff = MayEscape,
+                                      bool isEndPath = false);
+
+  RetainSummary* getPersistentSummary(RetEffect RE,
+                                      ArgEffect ReceiverEff = DoNothing,
+                                      ArgEffect DefaultEff = MayEscape) {
+    return getPersistentSummary(getArgEffects(), RE, ReceiverEff, DefaultEff);
+  }
+
+  RetainSummary *getPersistentStopSummary() {
+    if (StopSummary)
+      return StopSummary;
+
+    StopSummary = getPersistentSummary(RetEffect::MakeNoRet(),
+                                       StopTracking, StopTracking);
+
+    return StopSummary;
+  }
+
+  RetainSummary *getInitMethodSummary(QualType RetTy);
+
+  void InitializeClassMethodSummaries();
+  void InitializeMethodSummaries();
+private:
+
+  void addClsMethSummary(IdentifierInfo* ClsII, Selector S,
+                         RetainSummary* Summ) {
+    ObjCClassMethodSummaries[ObjCSummaryKey(ClsII, S)] = Summ;
+  }
+
+  void addNSObjectClsMethSummary(Selector S, RetainSummary *Summ) {
+    ObjCClassMethodSummaries[S] = Summ;
+  }
+
+  void addNSObjectMethSummary(Selector S, RetainSummary *Summ) {
+    ObjCMethodSummaries[S] = Summ;
+  }
+
+  void addClassMethSummary(const char* Cls, const char* nullaryName,
+                           RetainSummary *Summ) {
+    IdentifierInfo* ClsII = &Ctx.Idents.get(Cls);
+    Selector S = GetNullarySelector(nullaryName, Ctx);
+    ObjCClassMethodSummaries[ObjCSummaryKey(ClsII, S)]  = Summ;
+  }
+
+  void addInstMethSummary(const char* Cls, const char* nullaryName,
+                          RetainSummary *Summ) {
+    IdentifierInfo* ClsII = &Ctx.Idents.get(Cls);
+    Selector S = GetNullarySelector(nullaryName, Ctx);
+    ObjCMethodSummaries[ObjCSummaryKey(ClsII, S)]  = Summ;
+  }
+
+  Selector generateSelector(va_list argp) {
+    llvm::SmallVector<IdentifierInfo*, 10> II;
+
+    while (const char* s = va_arg(argp, const char*))
+      II.push_back(&Ctx.Idents.get(s));
+
+    return Ctx.Selectors.getSelector(II.size(), &II[0]);
+  }
+
+  void addMethodSummary(IdentifierInfo *ClsII, ObjCMethodSummariesTy& Summaries,
+                        RetainSummary* Summ, va_list argp) {
+    Selector S = generateSelector(argp);
+    Summaries[ObjCSummaryKey(ClsII, S)] = Summ;
+  }
+
+  void addInstMethSummary(const char* Cls, RetainSummary* Summ, ...) {
+    va_list argp;
+    va_start(argp, Summ);
+    addMethodSummary(&Ctx.Idents.get(Cls), ObjCMethodSummaries, Summ, argp);
+    va_end(argp);
+  }
+
+  void addClsMethSummary(const char* Cls, RetainSummary* Summ, ...) {
+    va_list argp;
+    va_start(argp, Summ);
+    addMethodSummary(&Ctx.Idents.get(Cls),ObjCClassMethodSummaries, Summ, argp);
+    va_end(argp);
+  }
+
+  void addClsMethSummary(IdentifierInfo *II, RetainSummary* Summ, ...) {
+    va_list argp;
+    va_start(argp, Summ);
+    addMethodSummary(II, ObjCClassMethodSummaries, Summ, argp);
+    va_end(argp);
+  }
+
+  void addPanicSummary(const char* Cls, ...) {
+    RetainSummary* Summ = getPersistentSummary(AF.GetEmptyMap(),
+                                               RetEffect::MakeNoRet(),
+                                               DoNothing,  DoNothing, true);
+    va_list argp;
+    va_start (argp, Cls);
+    addMethodSummary(&Ctx.Idents.get(Cls), ObjCMethodSummaries, Summ, argp);
+    va_end(argp);
+  }
+
+public:
+
+  RetainSummaryManager(ASTContext& ctx, bool gcenabled)
+   : Ctx(ctx),
+     CFDictionaryCreateII(&ctx.Idents.get("CFDictionaryCreate")),
+     GCEnabled(gcenabled), AF(BPAlloc), ScratchArgs(AF.GetEmptyMap()),
+     ObjCAllocRetE(gcenabled ? RetEffect::MakeGCNotOwned()
+                             : RetEffect::MakeOwned(RetEffect::ObjC, true)),
+     ObjCInitRetE(gcenabled ? RetEffect::MakeGCNotOwned()
+                            : RetEffect::MakeOwnedWhenTrackedReceiver()),
+     DefaultSummary(AF.GetEmptyMap() /* per-argument effects (none) */,
+                    RetEffect::MakeNoRet() /* return effect */,
+                    MayEscape, /* default argument effect */
+                    DoNothing /* receiver effect */),
+     StopSummary(0) {
+
+    InitializeClassMethodSummaries();
+    InitializeMethodSummaries();
+  }
+
+  ~RetainSummaryManager();
+
+  RetainSummary* getSummary(FunctionDecl* FD);
+
+  RetainSummary *getInstanceMethodSummary(const ObjCMessageExpr *ME,
+                                          const GRState *state,
+                                          const LocationContext *LC);
+  
+  RetainSummary* getInstanceMethodSummary(const ObjCMessageExpr* ME,
+                                          const ObjCInterfaceDecl* ID) {
+    return getInstanceMethodSummary(ME->getSelector(), 0,
+                            ID, ME->getMethodDecl(), ME->getType());
+  }
+
+  RetainSummary* getInstanceMethodSummary(Selector S, IdentifierInfo *ClsName,
+                                          const ObjCInterfaceDecl* ID,
+                                          const ObjCMethodDecl *MD,
+                                          QualType RetTy);
+
+  RetainSummary *getClassMethodSummary(Selector S, IdentifierInfo *ClsName,
+                                       const ObjCInterfaceDecl *ID,
+                                       const ObjCMethodDecl *MD,
+                                       QualType RetTy);
+
+  RetainSummary *getClassMethodSummary(const ObjCMessageExpr *ME) {
+    ObjCInterfaceDecl *Class = 0;
+    switch (ME->getReceiverKind()) {
+    case ObjCMessageExpr::Class:
+    case ObjCMessageExpr::SuperClass:
+      Class = ME->getReceiverInterface();
+      break;
+
+    case ObjCMessageExpr::Instance:
+    case ObjCMessageExpr::SuperInstance:
+      break;
+    }
+
+    return getClassMethodSummary(ME->getSelector(), 
+                                 Class? Class->getIdentifier() : 0,
+                                 Class,
+                                 ME->getMethodDecl(), ME->getType());
+  }
+
+  /// getMethodSummary - This version of getMethodSummary is used to query
+  ///  the summary for the current method being analyzed.
+  RetainSummary *getMethodSummary(const ObjCMethodDecl *MD) {
+    // FIXME: Eventually this should be unneeded.
+    const ObjCInterfaceDecl *ID = MD->getClassInterface();
+    Selector S = MD->getSelector();
+    IdentifierInfo *ClsName = ID->getIdentifier();
+    QualType ResultTy = MD->getResultType();
+
+    // Resolve the method decl last.
+    if (const ObjCMethodDecl *InterfaceMD = ResolveToInterfaceMethodDecl(MD))
+      MD = InterfaceMD;
+
+    if (MD->isInstanceMethod())
+      return getInstanceMethodSummary(S, ClsName, ID, MD, ResultTy);
+    else
+      return getClassMethodSummary(S, ClsName, ID, MD, ResultTy);
+  }
+
+  RetainSummary* getCommonMethodSummary(const ObjCMethodDecl* MD,
+                                        Selector S, QualType RetTy);
+
+  void updateSummaryFromAnnotations(RetainSummary &Summ,
+                                    const ObjCMethodDecl *MD);
+
+  void updateSummaryFromAnnotations(RetainSummary &Summ,
+                                    const FunctionDecl *FD);
+
+  bool isGCEnabled() const { return GCEnabled; }
+
+  RetainSummary *copySummary(RetainSummary *OldSumm) {
+    RetainSummary *Summ = (RetainSummary*) BPAlloc.Allocate<RetainSummary>();
+    new (Summ) RetainSummary(*OldSumm);
+    return Summ;
+  }
+};
+
+} // end anonymous namespace
+
+//===----------------------------------------------------------------------===//
+// Implementation of checker data structures.
+//===----------------------------------------------------------------------===//
+
+RetainSummaryManager::~RetainSummaryManager() {}
+
+ArgEffects RetainSummaryManager::getArgEffects() {
+  ArgEffects AE = ScratchArgs;
+  ScratchArgs = AF.GetEmptyMap();
+  return AE;
+}
+
+RetainSummary*
+RetainSummaryManager::getPersistentSummary(ArgEffects AE, RetEffect RetEff,
+                                           ArgEffect ReceiverEff,
+                                           ArgEffect DefaultEff,
+                                           bool isEndPath) {
+  // Create the summary and return it.
+  RetainSummary *Summ = (RetainSummary*) BPAlloc.Allocate<RetainSummary>();
+  new (Summ) RetainSummary(AE, RetEff, DefaultEff, ReceiverEff, isEndPath);
+  return Summ;
+}
+
+//===----------------------------------------------------------------------===//
+// Summary creation for functions (largely uses of Core Foundation).
+//===----------------------------------------------------------------------===//
+
+static bool isRetain(FunctionDecl* FD, StringRef FName) {
+  return FName.endswith("Retain");
+}
+
+static bool isRelease(FunctionDecl* FD, StringRef FName) {
+  return FName.endswith("Release");
+}
+
+RetainSummary* RetainSummaryManager::getSummary(FunctionDecl* FD) {
+  // Look up a summary in our cache of FunctionDecls -> Summaries.
+  FuncSummariesTy::iterator I = FuncSummaries.find(FD);
+  if (I != FuncSummaries.end())
+    return I->second;
+
+  // No summary?  Generate one.
+  RetainSummary *S = 0;
+
+  do {
+    // We generate "stop" summaries for implicitly defined functions.
+    if (FD->isImplicit()) {
+      S = getPersistentStopSummary();
+      break;
+    }
+
+    // [PR 3337] Use 'getAs<FunctionType>' to strip away any typedefs on the
+    // function's type.
+    const FunctionType* FT = FD->getType()->getAs<FunctionType>();
+    const IdentifierInfo *II = FD->getIdentifier();
+    if (!II)
+      break;
+
+    StringRef FName = II->getName();
+
+    // Strip away preceding '_'.  Doing this here will effect all the checks
+    // down below.
+    FName = FName.substr(FName.find_first_not_of('_'));
+
+    // Inspect the result type.
+    QualType RetTy = FT->getResultType();
+
+    // FIXME: This should all be refactored into a chain of "summary lookup"
+    //  filters.
+    assert(ScratchArgs.isEmpty());
+
+    if (FName == "pthread_create") {
+      // Part of: <rdar://problem/7299394>.  This will be addressed
+      // better with IPA.
+      S = getPersistentStopSummary();
+    } else if (FName == "NSMakeCollectable") {
+      // Handle: id NSMakeCollectable(CFTypeRef)
+      S = (RetTy->isObjCIdType())
+          ? getUnarySummary(FT, cfmakecollectable)
+          : getPersistentStopSummary();
+    } else if (FName == "IOBSDNameMatching" ||
+               FName == "IOServiceMatching" ||
+               FName == "IOServiceNameMatching" ||
+               FName == "IORegistryEntryIDMatching" ||
+               FName == "IOOpenFirmwarePathMatching") {
+      // Part of <rdar://problem/6961230>. (IOKit)
+      // This should be addressed using a API table.
+      S = getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF, true),
+                               DoNothing, DoNothing);
+    } else if (FName == "IOServiceGetMatchingService" ||
+               FName == "IOServiceGetMatchingServices") {
+      // FIXES: <rdar://problem/6326900>
+      // This should be addressed using a API table.  This strcmp is also
+      // a little gross, but there is no need to super optimize here.
+      ScratchArgs = AF.Add(ScratchArgs, 1, DecRef);
+      S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);
+    } else if (FName == "IOServiceAddNotification" ||
+               FName == "IOServiceAddMatchingNotification") {
+      // Part of <rdar://problem/6961230>. (IOKit)
+      // This should be addressed using a API table.
+      ScratchArgs = AF.Add(ScratchArgs, 2, DecRef);
+      S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);
+    } else if (FName == "CVPixelBufferCreateWithBytes") {
+      // FIXES: <rdar://problem/7283567>
+      // Eventually this can be improved by recognizing that the pixel
+      // buffer passed to CVPixelBufferCreateWithBytes is released via
+      // a callback and doing full IPA to make sure this is done correctly.
+      // FIXME: This function has an out parameter that returns an
+      // allocated object.
+      ScratchArgs = AF.Add(ScratchArgs, 7, StopTracking);
+      S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);
+    } else if (FName == "CGBitmapContextCreateWithData") {
+      // FIXES: <rdar://problem/7358899>
+      // Eventually this can be improved by recognizing that 'releaseInfo'
+      // passed to CGBitmapContextCreateWithData is released via
+      // a callback and doing full IPA to make sure this is done correctly.
+      ScratchArgs = AF.Add(ScratchArgs, 8, StopTracking);
+      S = getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF, true),
+                               DoNothing, DoNothing);
+    } else if (FName == "CVPixelBufferCreateWithPlanarBytes") {
+      // FIXES: <rdar://problem/7283567>
+      // Eventually this can be improved by recognizing that the pixel
+      // buffer passed to CVPixelBufferCreateWithPlanarBytes is released
+      // via a callback and doing full IPA to make sure this is done
+      // correctly.
+      ScratchArgs = AF.Add(ScratchArgs, 12, StopTracking);
+      S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);
+    }
+
+    // Did we get a summary?
+    if (S)
+      break;
+
+    // Enable this code once the semantics of NSDeallocateObject are resolved
+    // for GC.  <rdar://problem/6619988>
+#if 0
+    // Handle: NSDeallocateObject(id anObject);
+    // This method does allow 'nil' (although we don't check it now).
+    if (strcmp(FName, "NSDeallocateObject") == 0) {
+      return RetTy == Ctx.VoidTy
+        ? getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, Dealloc)
+        : getPersistentStopSummary();
+    }
+#endif
+
+    if (RetTy->isPointerType()) {
+      // For CoreFoundation ('CF') types.
+      if (cocoa::isRefType(RetTy, "CF", FName)) {
+        if (isRetain(FD, FName))
+          S = getUnarySummary(FT, cfretain);
+        else if (FName.find("MakeCollectable") != StringRef::npos)
+          S = getUnarySummary(FT, cfmakecollectable);
+        else
+          S = getCFCreateGetRuleSummary(FD, FName);
+
+        break;
+      }
+
+      // For CoreGraphics ('CG') types.
+      if (cocoa::isRefType(RetTy, "CG", FName)) {
+        if (isRetain(FD, FName))
+          S = getUnarySummary(FT, cfretain);
+        else
+          S = getCFCreateGetRuleSummary(FD, FName);
+
+        break;
+      }
+
+      // For the Disk Arbitration API (DiskArbitration/DADisk.h)
+      if (cocoa::isRefType(RetTy, "DADisk") ||
+          cocoa::isRefType(RetTy, "DADissenter") ||
+          cocoa::isRefType(RetTy, "DASessionRef")) {
+        S = getCFCreateGetRuleSummary(FD, FName);
+        break;
+      }
+
+      break;
+    }
+
+    // Check for release functions, the only kind of functions that we care
+    // about that don't return a pointer type.
+    if (FName[0] == 'C' && (FName[1] == 'F' || FName[1] == 'G')) {
+      // Test for 'CGCF'.
+      FName = FName.substr(FName.startswith("CGCF") ? 4 : 2);
+
+      if (isRelease(FD, FName))
+        S = getUnarySummary(FT, cfrelease);
+      else {
+        assert (ScratchArgs.isEmpty());
+        // Remaining CoreFoundation and CoreGraphics functions.
+        // We use to assume that they all strictly followed the ownership idiom
+        // and that ownership cannot be transferred.  While this is technically
+        // correct, many methods allow a tracked object to escape.  For example:
+        //
+        //   CFMutableDictionaryRef x = CFDictionaryCreateMutable(...);
+        //   CFDictionaryAddValue(y, key, x);
+        //   CFRelease(x);
+        //   ... it is okay to use 'x' since 'y' has a reference to it
+        //
+        // We handle this and similar cases with the follow heuristic.  If the
+        // function name contains "InsertValue", "SetValue", "AddValue",
+        // "AppendValue", or "SetAttribute", then we assume that arguments may
+        // "escape."  This means that something else holds on to the object,
+        // allowing it be used even after its local retain count drops to 0.
+        ArgEffect E = (StrInStrNoCase(FName, "InsertValue") != StringRef::npos||
+                       StrInStrNoCase(FName, "AddValue") != StringRef::npos ||
+                       StrInStrNoCase(FName, "SetValue") != StringRef::npos ||
+                       StrInStrNoCase(FName, "AppendValue") != StringRef::npos||
+                       StrInStrNoCase(FName, "SetAttribute") != StringRef::npos)
+                      ? MayEscape : DoNothing;
+
+        S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, E);
+      }
+    }
+  }
+  while (0);
+
+  if (!S)
+    S = getDefaultSummary();
+
+  // Annotations override defaults.
+  assert(S);
+  updateSummaryFromAnnotations(*S, FD);
+
+  FuncSummaries[FD] = S;
+  return S;
+}
+
+RetainSummary*
+RetainSummaryManager::getCFCreateGetRuleSummary(FunctionDecl* FD,
+                                                StringRef FName) {
+
+  if (FName.find("Create") != StringRef::npos ||
+      FName.find("Copy") != StringRef::npos)
+    return getCFSummaryCreateRule(FD);
+
+  if (FName.find("Get") != StringRef::npos)
+    return getCFSummaryGetRule(FD);
+
+  return getDefaultSummary();
+}
+
+RetainSummary*
+RetainSummaryManager::getUnarySummary(const FunctionType* FT,
+                                      UnaryFuncKind func) {
+
+  // Sanity check that this is *really* a unary function.  This can
+  // happen if people do weird things.
+  const FunctionProtoType* FTP = dyn_cast<FunctionProtoType>(FT);
+  if (!FTP || FTP->getNumArgs() != 1)
+    return getPersistentStopSummary();
+
+  assert (ScratchArgs.isEmpty());
+
+  switch (func) {
+    case cfretain: {
+      ScratchArgs = AF.Add(ScratchArgs, 0, IncRef);
+      return getPersistentSummary(RetEffect::MakeAlias(0),
+                                  DoNothing, DoNothing);
+    }
+
+    case cfrelease: {
+      ScratchArgs = AF.Add(ScratchArgs, 0, DecRef);
+      return getPersistentSummary(RetEffect::MakeNoRet(),
+                                  DoNothing, DoNothing);
+    }
+
+    case cfmakecollectable: {
+      ScratchArgs = AF.Add(ScratchArgs, 0, MakeCollectable);
+      return getPersistentSummary(RetEffect::MakeAlias(0),DoNothing, DoNothing);
+    }
+
+    default:
+      assert (false && "Not a supported unary function.");
+      return getDefaultSummary();
+  }
+}
+
+RetainSummary* RetainSummaryManager::getCFSummaryCreateRule(FunctionDecl* FD) {
+  assert (ScratchArgs.isEmpty());
+
+  if (FD->getIdentifier() == CFDictionaryCreateII) {
+    ScratchArgs = AF.Add(ScratchArgs, 1, DoNothingByRef);
+    ScratchArgs = AF.Add(ScratchArgs, 2, DoNothingByRef);
+  }
+
+  return getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF, true));
+}
+
+RetainSummary* RetainSummaryManager::getCFSummaryGetRule(FunctionDecl* FD) {
+  assert (ScratchArgs.isEmpty());
+  return getPersistentSummary(RetEffect::MakeNotOwned(RetEffect::CF),
+                              DoNothing, DoNothing);
+}
+
+//===----------------------------------------------------------------------===//
+// Summary creation for Selectors.
+//===----------------------------------------------------------------------===//
+
+RetainSummary*
+RetainSummaryManager::getInitMethodSummary(QualType RetTy) {
+  assert(ScratchArgs.isEmpty());
+  // 'init' methods conceptually return a newly allocated object and claim
+  // the receiver.
+  if (cocoa::isCocoaObjectRef(RetTy) || cocoa::isCFObjectRef(RetTy))
+    return getPersistentSummary(ObjCInitRetE, DecRefMsg);
+
+  return getDefaultSummary();
+}
+
+void
+RetainSummaryManager::updateSummaryFromAnnotations(RetainSummary &Summ,
+                                                   const FunctionDecl *FD) {
+  if (!FD)
+    return;
+
+  QualType RetTy = FD->getResultType();
+
+  // Determine if there is a special return effect for this method.
+  if (cocoa::isCocoaObjectRef(RetTy)) {
+    if (FD->getAttr<NSReturnsRetainedAttr>()) {
+      Summ.setRetEffect(ObjCAllocRetE);
+    }
+    else if (FD->getAttr<CFReturnsRetainedAttr>()) {
+      Summ.setRetEffect(RetEffect::MakeOwned(RetEffect::CF, true));
+    }
+    else if (FD->getAttr<NSReturnsNotRetainedAttr>()) {
+      Summ.setRetEffect(RetEffect::MakeNotOwned(RetEffect::ObjC));
+    }
+    else if (FD->getAttr<CFReturnsNotRetainedAttr>()) {
+      Summ.setRetEffect(RetEffect::MakeNotOwned(RetEffect::CF));
+    }
+  }
+  else if (RetTy->getAs<PointerType>()) {
+    if (FD->getAttr<CFReturnsRetainedAttr>()) {
+      Summ.setRetEffect(RetEffect::MakeOwned(RetEffect::CF, true));
+    }
+  }
+}
+
+void
+RetainSummaryManager::updateSummaryFromAnnotations(RetainSummary &Summ,
+                                                  const ObjCMethodDecl *MD) {
+  if (!MD)
+    return;
+
+  bool isTrackedLoc = false;
+
+  // Determine if there is a special return effect for this method.
+  if (cocoa::isCocoaObjectRef(MD->getResultType())) {
+    if (MD->getAttr<NSReturnsRetainedAttr>()) {
+      Summ.setRetEffect(ObjCAllocRetE);
+      return;
+    }
+    if (MD->getAttr<NSReturnsNotRetainedAttr>()) {
+      Summ.setRetEffect(RetEffect::MakeNotOwned(RetEffect::ObjC));
+      return;
+    }
+
+    isTrackedLoc = true;
+  }
+
+  if (!isTrackedLoc)
+    isTrackedLoc = MD->getResultType()->getAs<PointerType>() != NULL;
+
+  if (isTrackedLoc) {
+    if (MD->getAttr<CFReturnsRetainedAttr>())
+      Summ.setRetEffect(RetEffect::MakeOwned(RetEffect::CF, true));
+    else if (MD->getAttr<CFReturnsNotRetainedAttr>())
+      Summ.setRetEffect(RetEffect::MakeNotOwned(RetEffect::CF));
+  }
+}
+
+RetainSummary*
+RetainSummaryManager::getCommonMethodSummary(const ObjCMethodDecl* MD,
+                                             Selector S, QualType RetTy) {
+
+  if (MD) {
+    // Scan the method decl for 'void*' arguments.  These should be treated
+    // as 'StopTracking' because they are often used with delegates.
+    // Delegates are a frequent form of false positives with the retain
+    // count checker.
+    unsigned i = 0;
+    for (ObjCMethodDecl::param_iterator I = MD->param_begin(),
+         E = MD->param_end(); I != E; ++I, ++i)
+      if (ParmVarDecl *PD = *I) {
+        QualType Ty = Ctx.getCanonicalType(PD->getType());
+        if (Ty.getLocalUnqualifiedType() == Ctx.VoidPtrTy)
+          ScratchArgs = AF.Add(ScratchArgs, i, StopTracking);
+      }
+  }
+
+  // Any special effect for the receiver?
+  ArgEffect ReceiverEff = DoNothing;
+
+  // If one of the arguments in the selector has the keyword 'delegate' we
+  // should stop tracking the reference count for the receiver.  This is
+  // because the reference count is quite possibly handled by a delegate
+  // method.
+  if (S.isKeywordSelector()) {
+    const std::string &str = S.getAsString();
+    assert(!str.empty());
+    if (StrInStrNoCase(str, "delegate:") != StringRef::npos)
+      ReceiverEff = StopTracking;
+  }
+
+  // Look for methods that return an owned object.
+  if (cocoa::isCocoaObjectRef(RetTy)) {
+    // EXPERIMENTAL: Assume the Cocoa conventions for all objects returned
+    //  by instance methods.
+    RetEffect E = cocoa::followsFundamentalRule(S)
+                  ? ObjCAllocRetE : RetEffect::MakeNotOwned(RetEffect::ObjC);
+
+    return getPersistentSummary(E, ReceiverEff, MayEscape);
+  }
+
+  // Look for methods that return an owned core foundation object.
+  if (cocoa::isCFObjectRef(RetTy)) {
+    RetEffect E = cocoa::followsFundamentalRule(S)
+      ? RetEffect::MakeOwned(RetEffect::CF, true)
+      : RetEffect::MakeNotOwned(RetEffect::CF);
+
+    return getPersistentSummary(E, ReceiverEff, MayEscape);
+  }
+
+  if (ScratchArgs.isEmpty() && ReceiverEff == DoNothing)
+    return getDefaultSummary();
+
+  return getPersistentSummary(RetEffect::MakeNoRet(), ReceiverEff, MayEscape);
+}
+
+RetainSummary*
+RetainSummaryManager::getInstanceMethodSummary(const ObjCMessageExpr *ME,
+                                               const GRState *state,
+                                               const LocationContext *LC) {
+
+  // We need the type-information of the tracked receiver object
+  // Retrieve it from the state.
+  const Expr *Receiver = ME->getInstanceReceiver();
+  const ObjCInterfaceDecl* ID = 0;
+
+  // FIXME: Is this really working as expected?  There are cases where
+  //  we just use the 'ID' from the message expression.
+  SVal receiverV;
+
+  if (const Expr *Receiver = ME->getInstanceReceiver()) {
+    receiverV = state->getSValAsScalarOrLoc(Receiver);
+  
+    // FIXME: Eventually replace the use of state->get<RefBindings> with
+    // a generic API for reasoning about the Objective-C types of symbolic
+    // objects.
+    if (SymbolRef Sym = receiverV.getAsLocSymbol())
+      if (const RefVal *T = state->get<RefBindings>(Sym))
+        if (const ObjCObjectPointerType* PT = 
+            T->getType()->getAs<ObjCObjectPointerType>())
+          ID = PT->getInterfaceDecl();
+  
+    // FIXME: this is a hack.  This may or may not be the actual method
+    //  that is called.
+    if (!ID) {
+      if (const ObjCObjectPointerType *PT =
+          Receiver->getType()->getAs<ObjCObjectPointerType>())
+        ID = PT->getInterfaceDecl();
+    }
+  } else {
+    // FIXME: Hack for 'super'.
+    ID = ME->getReceiverInterface();
+  }
+
+  // FIXME: The receiver could be a reference to a class, meaning that
+  //  we should use the class method.
+  RetainSummary *Summ = getInstanceMethodSummary(ME, ID);
+  
+  // Special-case: are we sending a mesage to "self"?
+  //  This is a hack.  When we have full-IP this should be removed.
+  if (isa<ObjCMethodDecl>(LC->getDecl()) && Receiver) {
+    if (const loc::MemRegionVal *L = dyn_cast<loc::MemRegionVal>(&receiverV)) {
+      // Get the region associated with 'self'.
+      if (const ImplicitParamDecl *SelfDecl = LC->getSelfDecl()) {
+        SVal SelfVal = state->getSVal(state->getRegion(SelfDecl, LC));
+        if (L->StripCasts() == SelfVal.getAsRegion()) {
+          // Update the summary to make the default argument effect
+          // 'StopTracking'.
+          Summ = copySummary(Summ);
+          Summ->setDefaultArgEffect(StopTracking);
+        }
+      }
+    }
+  }
+  
+  return Summ ? Summ : getDefaultSummary();
+}
+
+RetainSummary*
+RetainSummaryManager::getInstanceMethodSummary(Selector S,
+                                               IdentifierInfo *ClsName,
+                                               const ObjCInterfaceDecl* ID,
+                                               const ObjCMethodDecl *MD,
+                                               QualType RetTy) {
+
+  // Look up a summary in our summary cache.
+  RetainSummary *Summ = ObjCMethodSummaries.find(ID, ClsName, S);
+
+  if (!Summ) {
+    assert(ScratchArgs.isEmpty());
+
+    // "initXXX": pass-through for receiver.
+    if (cocoa::deriveNamingConvention(S) == cocoa::InitRule)
+      Summ = getInitMethodSummary(RetTy);
+    else
+      Summ = getCommonMethodSummary(MD, S, RetTy);
+
+    // Annotations override defaults.
+    updateSummaryFromAnnotations(*Summ, MD);
+
+    // Memoize the summary.
+    ObjCMethodSummaries[ObjCSummaryKey(ID, ClsName, S)] = Summ;
+  }
+
+  return Summ;
+}
+
+RetainSummary*
+RetainSummaryManager::getClassMethodSummary(Selector S, IdentifierInfo *ClsName,
+                                            const ObjCInterfaceDecl *ID,
+                                            const ObjCMethodDecl *MD,
+                                            QualType RetTy) {
+
+  assert(ClsName && "Class name must be specified.");
+  RetainSummary *Summ = ObjCClassMethodSummaries.find(ID, ClsName, S);
+
+  if (!Summ) {
+    Summ = getCommonMethodSummary(MD, S, RetTy);
+    // Annotations override defaults.
+    updateSummaryFromAnnotations(*Summ, MD);
+    // Memoize the summary.
+    ObjCClassMethodSummaries[ObjCSummaryKey(ID, ClsName, S)] = Summ;
+  }
+
+  return Summ;
+}
+
+void RetainSummaryManager::InitializeClassMethodSummaries() {
+  assert(ScratchArgs.isEmpty());
+  RetainSummary* Summ = getPersistentSummary(ObjCAllocRetE);
+
+  // Create the summaries for "alloc", "new", and "allocWithZone:" for
+  // NSObject and its derivatives.
+  addNSObjectClsMethSummary(GetNullarySelector("alloc", Ctx), Summ);
+  addNSObjectClsMethSummary(GetNullarySelector("new", Ctx), Summ);
+  addNSObjectClsMethSummary(GetUnarySelector("allocWithZone", Ctx), Summ);
+
+  // Create the [NSAssertionHandler currentHander] summary.
+  addClassMethSummary("NSAssertionHandler", "currentHandler",
+                getPersistentSummary(RetEffect::MakeNotOwned(RetEffect::ObjC)));
+
+  // Create the [NSAutoreleasePool addObject:] summary.
+  ScratchArgs = AF.Add(ScratchArgs, 0, Autorelease);
+  addClassMethSummary("NSAutoreleasePool", "addObject",
+                      getPersistentSummary(RetEffect::MakeNoRet(),
+                                           DoNothing, Autorelease));
+
+  // Create a summary for [NSCursor dragCopyCursor].
+  addClassMethSummary("NSCursor", "dragCopyCursor",
+                      getPersistentSummary(RetEffect::MakeNoRet(), DoNothing,
+                                           DoNothing));
+
+  // Create the summaries for [NSObject performSelector...].  We treat
+  // these as 'stop tracking' for the arguments because they are often
+  // used for delegates that can release the object.  When we have better
+  // inter-procedural analysis we can potentially do something better.  This
+  // workaround is to remove false positives.
+  Summ = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, StopTracking);
+  IdentifierInfo *NSObjectII = &Ctx.Idents.get("NSObject");
+  addClsMethSummary(NSObjectII, Summ, "performSelector", "withObject",
+                    "afterDelay", NULL);
+  addClsMethSummary(NSObjectII, Summ, "performSelector", "withObject",
+                    "afterDelay", "inModes", NULL);
+  addClsMethSummary(NSObjectII, Summ, "performSelectorOnMainThread",
+                    "withObject", "waitUntilDone", NULL);
+  addClsMethSummary(NSObjectII, Summ, "performSelectorOnMainThread",
+                    "withObject", "waitUntilDone", "modes", NULL);
+  addClsMethSummary(NSObjectII, Summ, "performSelector", "onThread",
+                    "withObject", "waitUntilDone", NULL);
+  addClsMethSummary(NSObjectII, Summ, "performSelector", "onThread",
+                    "withObject", "waitUntilDone", "modes", NULL);
+  addClsMethSummary(NSObjectII, Summ, "performSelectorInBackground",
+                    "withObject", NULL);
+
+  // Specially handle NSData.
+  RetainSummary *dataWithBytesNoCopySumm =
+    getPersistentSummary(RetEffect::MakeNotOwned(RetEffect::ObjC), DoNothing,
+                         DoNothing);
+  addClsMethSummary("NSData", dataWithBytesNoCopySumm,
+                    "dataWithBytesNoCopy", "length", NULL);
+  addClsMethSummary("NSData", dataWithBytesNoCopySumm,
+                    "dataWithBytesNoCopy", "length", "freeWhenDone", NULL);
+}
+
+void RetainSummaryManager::InitializeMethodSummaries() {
+
+  assert (ScratchArgs.isEmpty());
+
+  // Create the "init" selector.  It just acts as a pass-through for the
+  // receiver.
+  RetainSummary *InitSumm = getPersistentSummary(ObjCInitRetE, DecRefMsg);
+  addNSObjectMethSummary(GetNullarySelector("init", Ctx), InitSumm);
+
+  // awakeAfterUsingCoder: behaves basically like an 'init' method.  It
+  // claims the receiver and returns a retained object.
+  addNSObjectMethSummary(GetUnarySelector("awakeAfterUsingCoder", Ctx),
+                         InitSumm);
+
+  // The next methods are allocators.
+  RetainSummary *AllocSumm = getPersistentSummary(ObjCAllocRetE);
+  RetainSummary *CFAllocSumm =
+    getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF, true));
+
+  // Create the "copy" selector.
+  addNSObjectMethSummary(GetNullarySelector("copy", Ctx), AllocSumm);
+
+  // Create the "mutableCopy" selector.
+  addNSObjectMethSummary(GetNullarySelector("mutableCopy", Ctx), AllocSumm);
+
+  // Create the "retain" selector.
+  RetEffect E = RetEffect::MakeReceiverAlias();
+  RetainSummary *Summ = getPersistentSummary(E, IncRefMsg);
+  addNSObjectMethSummary(GetNullarySelector("retain", Ctx), Summ);
+
+  // Create the "release" selector.
+  Summ = getPersistentSummary(E, DecRefMsg);
+  addNSObjectMethSummary(GetNullarySelector("release", Ctx), Summ);
+
+  // Create the "drain" selector.
+  Summ = getPersistentSummary(E, isGCEnabled() ? DoNothing : DecRef);
+  addNSObjectMethSummary(GetNullarySelector("drain", Ctx), Summ);
+
+  // Create the -dealloc summary.
+  Summ = getPersistentSummary(RetEffect::MakeNoRet(), Dealloc);
+  addNSObjectMethSummary(GetNullarySelector("dealloc", Ctx), Summ);
+
+  // Create the "autorelease" selector.
+  Summ = getPersistentSummary(E, Autorelease);
+  addNSObjectMethSummary(GetNullarySelector("autorelease", Ctx), Summ);
+
+  // Specially handle NSAutoreleasePool.
+  addInstMethSummary("NSAutoreleasePool", "init",
+                     getPersistentSummary(RetEffect::MakeReceiverAlias(),
+                                          NewAutoreleasePool));
+
+  // For NSWindow, allocated objects are (initially) self-owned.
+  // FIXME: For now we opt for false negatives with NSWindow, as these objects
+  //  self-own themselves.  However, they only do this once they are displayed.
+  //  Thus, we need to track an NSWindow's display status.
+  //  This is tracked in <rdar://problem/6062711>.
+  //  See also http://llvm.org/bugs/show_bug.cgi?id=3714.
+  RetainSummary *NoTrackYet = getPersistentSummary(RetEffect::MakeNoRet(),
+                                                   StopTracking,
+                                                   StopTracking);
+
+  addClassMethSummary("NSWindow", "alloc", NoTrackYet);
+
+#if 0
+  addInstMethSummary("NSWindow", NoTrackYet, "initWithContentRect",
+                     "styleMask", "backing", "defer", NULL);
+
+  addInstMethSummary("NSWindow", NoTrackYet, "initWithContentRect",
+                     "styleMask", "backing", "defer", "screen", NULL);
+#endif
+
+  // For NSPanel (which subclasses NSWindow), allocated objects are not
+  //  self-owned.
+  // FIXME: For now we don't track NSPanels. object for the same reason
+  //   as for NSWindow objects.
+  addClassMethSummary("NSPanel", "alloc", NoTrackYet);
+
+#if 0
+  addInstMethSummary("NSPanel", NoTrackYet, "initWithContentRect",
+                     "styleMask", "backing", "defer", NULL);
+
+  addInstMethSummary("NSPanel", NoTrackYet, "initWithContentRect",
+                     "styleMask", "backing", "defer", "screen", NULL);
+#endif
+
+  // Don't track allocated autorelease pools yet, as it is okay to prematurely
+  // exit a method.
+  addClassMethSummary("NSAutoreleasePool", "alloc", NoTrackYet);
+
+  // Create NSAssertionHandler summaries.
+  addPanicSummary("NSAssertionHandler", "handleFailureInFunction", "file",
+                  "lineNumber", "description", NULL);
+
+  addPanicSummary("NSAssertionHandler", "handleFailureInMethod", "object",
+                  "file", "lineNumber", "description", NULL);
+
+  // Create summaries QCRenderer/QCView -createSnapShotImageOfType:
+  addInstMethSummary("QCRenderer", AllocSumm,
+                     "createSnapshotImageOfType", NULL);
+  addInstMethSummary("QCView", AllocSumm,
+                     "createSnapshotImageOfType", NULL);
+
+  // Create summaries for CIContext, 'createCGImage' and
+  // 'createCGLayerWithSize'.  These objects are CF objects, and are not
+  // automatically garbage collected.
+  addInstMethSummary("CIContext", CFAllocSumm,
+                     "createCGImage", "fromRect", NULL);
+  addInstMethSummary("CIContext", CFAllocSumm,
+                     "createCGImage", "fromRect", "format", "colorSpace", NULL);
+  addInstMethSummary("CIContext", CFAllocSumm, "createCGLayerWithSize",
+           "info", NULL);
+}
+
+//===----------------------------------------------------------------------===//
+// AutoreleaseBindings - State used to track objects in autorelease pools.
+//===----------------------------------------------------------------------===//
+
+typedef llvm::ImmutableMap<SymbolRef, unsigned> ARCounts;
+typedef llvm::ImmutableMap<SymbolRef, ARCounts> ARPoolContents;
+typedef llvm::ImmutableList<SymbolRef> ARStack;
+
+static int AutoRCIndex = 0;
+static int AutoRBIndex = 0;
+
+namespace { class AutoreleasePoolContents {}; }
+namespace { class AutoreleaseStack {}; }
+
+namespace clang {
+template<> struct GRStateTrait<AutoreleaseStack>
+  : public GRStatePartialTrait<ARStack> {
+  static inline void* GDMIndex() { return &AutoRBIndex; }
+};
+
+template<> struct GRStateTrait<AutoreleasePoolContents>
+  : public GRStatePartialTrait<ARPoolContents> {
+  static inline void* GDMIndex() { return &AutoRCIndex; }
+};
+} // end clang namespace
+
+static SymbolRef GetCurrentAutoreleasePool(const GRState* state) {
+  ARStack stack = state->get<AutoreleaseStack>();
+  return stack.isEmpty() ? SymbolRef() : stack.getHead();
+}
+
+static const GRState * SendAutorelease(const GRState *state,
+                                       ARCounts::Factory &F, SymbolRef sym) {
+
+  SymbolRef pool = GetCurrentAutoreleasePool(state);
+  const ARCounts *cnts = state->get<AutoreleasePoolContents>(pool);
+  ARCounts newCnts(0);
+
+  if (cnts) {
+    const unsigned *cnt = (*cnts).lookup(sym);
+    newCnts = F.Add(*cnts, sym, cnt ? *cnt  + 1 : 1);
+  }
+  else
+    newCnts = F.Add(F.GetEmptyMap(), sym, 1);
+
+  return state->set<AutoreleasePoolContents>(pool, newCnts);
+}
+
+//===----------------------------------------------------------------------===//
+// Transfer functions.
+//===----------------------------------------------------------------------===//
+
+namespace {
+
+class CFRefCount : public GRTransferFuncs {
+public:
+  class BindingsPrinter : public GRState::Printer {
+  public:
+    virtual void Print(llvm::raw_ostream& Out, const GRState* state,
+                       const char* nl, const char* sep);
+  };
+
+private:
+  typedef llvm::DenseMap<const ExplodedNode*, const RetainSummary*>
+    SummaryLogTy;
+
+  RetainSummaryManager Summaries;
+  SummaryLogTy SummaryLog;
+  const LangOptions&   LOpts;
+  ARCounts::Factory    ARCountFactory;
+
+  BugType *useAfterRelease, *releaseNotOwned;
+  BugType *deallocGC, *deallocNotOwned;
+  BugType *leakWithinFunction, *leakAtReturn;
+  BugType *overAutorelease;
+  BugType *returnNotOwnedForOwned;
+  BugReporter *BR;
+
+  const GRState * Update(const GRState * state, SymbolRef sym, RefVal V, ArgEffect E,
+                    RefVal::Kind& hasErr);
+
+  void ProcessNonLeakError(ExplodedNodeSet& Dst,
+                           GRStmtNodeBuilder& Builder,
+                           Expr* NodeExpr, Expr* ErrorExpr,
+                           ExplodedNode* Pred,
+                           const GRState* St,
+                           RefVal::Kind hasErr, SymbolRef Sym);
+
+  const GRState * HandleSymbolDeath(const GRState * state, SymbolRef sid, RefVal V,
+                               llvm::SmallVectorImpl<SymbolRef> &Leaked);
+
+  ExplodedNode* ProcessLeaks(const GRState * state,
+                                      llvm::SmallVectorImpl<SymbolRef> &Leaked,
+                                      GenericNodeBuilder &Builder,
+                                      GRExprEngine &Eng,
+                                      ExplodedNode *Pred = 0);
+
+public:
+  CFRefCount(ASTContext& Ctx, bool gcenabled, const LangOptions& lopts)
+    : Summaries(Ctx, gcenabled),
+      LOpts(lopts), useAfterRelease(0), releaseNotOwned(0),
+      deallocGC(0), deallocNotOwned(0),
+      leakWithinFunction(0), leakAtReturn(0), overAutorelease(0),
+      returnNotOwnedForOwned(0), BR(0) {}
+
+  virtual ~CFRefCount() {}
+
+  void RegisterChecks(GRExprEngine &Eng);
+
+  virtual void RegisterPrinters(std::vector<GRState::Printer*>& Printers) {
+    Printers.push_back(new BindingsPrinter());
+  }
+
+  bool isGCEnabled() const { return Summaries.isGCEnabled(); }
+  const LangOptions& getLangOptions() const { return LOpts; }
+
+  const RetainSummary *getSummaryOfNode(const ExplodedNode *N) const {
+    SummaryLogTy::const_iterator I = SummaryLog.find(N);
+    return I == SummaryLog.end() ? 0 : I->second;
+  }
+
+  // Calls.
+
+  void EvalSummary(ExplodedNodeSet& Dst,
+                   GRExprEngine& Eng,
+                   GRStmtNodeBuilder& Builder,
+                   Expr* Ex,
+                   Expr* Receiver,
+                   const RetainSummary& Summ,
+                   const MemRegion *Callee,
+                   ExprIterator arg_beg, ExprIterator arg_end,
+                   ExplodedNode* Pred, const GRState *state);
+
+  virtual void EvalCall(ExplodedNodeSet& Dst,
+                        GRExprEngine& Eng,
+                        GRStmtNodeBuilder& Builder,
+                        CallExpr* CE, SVal L,
+                        ExplodedNode* Pred);
+
+
+  virtual void EvalObjCMessageExpr(ExplodedNodeSet& Dst,
+                                   GRExprEngine& Engine,
+                                   GRStmtNodeBuilder& Builder,
+                                   ObjCMessageExpr* ME,
+                                   ExplodedNode* Pred,
+                                   const GRState *state);
+
+  bool EvalObjCMessageExprAux(ExplodedNodeSet& Dst,
+                              GRExprEngine& Engine,
+                              GRStmtNodeBuilder& Builder,
+                              ObjCMessageExpr* ME,
+                              ExplodedNode* Pred);
+
+  // Stores.
+  virtual void EvalBind(GRStmtNodeBuilderRef& B, SVal location, SVal val);
+
+  // End-of-path.
+
+  virtual void EvalEndPath(GRExprEngine& Engine,
+                           GREndPathNodeBuilder& Builder);
+
+  virtual void EvalDeadSymbols(ExplodedNodeSet& Dst,
+                               GRExprEngine& Engine,
+                               GRStmtNodeBuilder& Builder,
+                               ExplodedNode* Pred,
+                               Stmt* S, const GRState* state,
+                               SymbolReaper& SymReaper);
+
+  std::pair<ExplodedNode*, const GRState *>
+  HandleAutoreleaseCounts(const GRState * state, GenericNodeBuilder Bd,
+                          ExplodedNode* Pred, GRExprEngine &Eng,
+                          SymbolRef Sym, RefVal V, bool &stop);
+  // Return statements.
+
+  virtual void EvalReturn(ExplodedNodeSet& Dst,
+                          GRExprEngine& Engine,
+                          GRStmtNodeBuilder& Builder,
+                          ReturnStmt* S,
+                          ExplodedNode* Pred);
+
+  // Assumptions.
+
+  virtual const GRState *EvalAssume(const GRState* state, SVal condition,
+                                    bool assumption);
+};
+
+} // end anonymous namespace
+
+static void PrintPool(llvm::raw_ostream &Out, SymbolRef Sym,
+                      const GRState *state) {
+  Out << ' ';
+  if (Sym)
+    Out << Sym->getSymbolID();
+  else
+    Out << "<pool>";
+  Out << ":{";
+
+  // Get the contents of the pool.
+  if (const ARCounts *cnts = state->get<AutoreleasePoolContents>(Sym))
+    for (ARCounts::iterator J=cnts->begin(), EJ=cnts->end(); J != EJ; ++J)
+      Out << '(' << J.getKey() << ',' << J.getData() << ')';
+
+  Out << '}';
+}
+
+void CFRefCount::BindingsPrinter::Print(llvm::raw_ostream& Out,
+                                        const GRState* state,
+                                        const char* nl, const char* sep) {
+
+  RefBindings B = state->get<RefBindings>();
+
+  if (!B.isEmpty())
+    Out << sep << nl;
+
+  for (RefBindings::iterator I=B.begin(), E=B.end(); I!=E; ++I) {
+    Out << (*I).first << " : ";
+    (*I).second.print(Out);
+    Out << nl;
+  }
+
+  // Print the autorelease stack.
+  Out << sep << nl << "AR pool stack:";
+  ARStack stack = state->get<AutoreleaseStack>();
+
+  PrintPool(Out, SymbolRef(), state);  // Print the caller's pool.
+  for (ARStack::iterator I=stack.begin(), E=stack.end(); I!=E; ++I)
+    PrintPool(Out, *I, state);
+
+  Out << nl;
+}
+
+//===----------------------------------------------------------------------===//
+// Error reporting.
+//===----------------------------------------------------------------------===//
+
+namespace {
+
+  //===-------------===//
+  // Bug Descriptions. //
+  //===-------------===//
+
+  class CFRefBug : public BugType {
+  protected:
+    CFRefCount& TF;
+
+    CFRefBug(CFRefCount* tf, llvm::StringRef name)
+    : BugType(name, "Memory (Core Foundation/Objective-C)"), TF(*tf) {}
+  public:
+
+    CFRefCount& getTF() { return TF; }
+    const CFRefCount& getTF() const { return TF; }
+
+    // FIXME: Eventually remove.
+    virtual const char* getDescription() const = 0;
+
+    virtual bool isLeak() const { return false; }
+  };
+
+  class UseAfterRelease : public CFRefBug {
+  public:
+    UseAfterRelease(CFRefCount* tf)
+    : CFRefBug(tf, "Use-after-release") {}
+
+    const char* getDescription() const {
+      return "Reference-counted object is used after it is released";
+    }
+  };
+
+  class BadRelease : public CFRefBug {
+  public:
+    BadRelease(CFRefCount* tf) : CFRefBug(tf, "Bad release") {}
+
+    const char* getDescription() const {
+      return "Incorrect decrement of the reference count of an object that is "
+             "not owned at this point by the caller";
+    }
+  };
+
+  class DeallocGC : public CFRefBug {
+  public:
+    DeallocGC(CFRefCount *tf)
+      : CFRefBug(tf, "-dealloc called while using garbage collection") {}
+
+    const char *getDescription() const {
+      return "-dealloc called while using garbage collection";
+    }
+  };
+
+  class DeallocNotOwned : public CFRefBug {
+  public:
+    DeallocNotOwned(CFRefCount *tf)
+      : CFRefBug(tf, "-dealloc sent to non-exclusively owned object") {}
+
+    const char *getDescription() const {
+      return "-dealloc sent to object that may be referenced elsewhere";
+    }
+  };
+
+  class OverAutorelease : public CFRefBug {
+  public:
+    OverAutorelease(CFRefCount *tf) :
+      CFRefBug(tf, "Object sent -autorelease too many times") {}
+
+    const char *getDescription() const {
+      return "Object sent -autorelease too many times";
+    }
+  };
+
+  class ReturnedNotOwnedForOwned : public CFRefBug {
+  public:
+    ReturnedNotOwnedForOwned(CFRefCount *tf) :
+      CFRefBug(tf, "Method should return an owned object") {}
+
+    const char *getDescription() const {
+      return "Object with +0 retain counts returned to caller where a +1 "
+             "(owning) retain count is expected";
+    }
+  };
+
+  class Leak : public CFRefBug {
+    const bool isReturn;
+  protected:
+    Leak(CFRefCount* tf, llvm::StringRef name, bool isRet)
+    : CFRefBug(tf, name), isReturn(isRet) {}
+  public:
+
+    const char* getDescription() const { return ""; }
+
+    bool isLeak() const { return true; }
+  };
+
+  class LeakAtReturn : public Leak {
+  public:
+    LeakAtReturn(CFRefCount* tf, llvm::StringRef name)
+    : Leak(tf, name, true) {}
+  };
+
+  class LeakWithinFunction : public Leak {
+  public:
+    LeakWithinFunction(CFRefCount* tf, llvm::StringRef name)
+    : Leak(tf, name, false) {}
+  };
+
+  //===---------===//
+  // Bug Reports.  //
+  //===---------===//
+
+  class CFRefReport : public RangedBugReport {
+  protected:
+    SymbolRef Sym;
+    const CFRefCount &TF;
+  public:
+    CFRefReport(CFRefBug& D, const CFRefCount &tf,
+                ExplodedNode *n, SymbolRef sym)
+      : RangedBugReport(D, D.getDescription(), n), Sym(sym), TF(tf) {}
+
+    CFRefReport(CFRefBug& D, const CFRefCount &tf,
+                ExplodedNode *n, SymbolRef sym, llvm::StringRef endText)
+      : RangedBugReport(D, D.getDescription(), endText, n), Sym(sym), TF(tf) {}
+
+    virtual ~CFRefReport() {}
+
+    CFRefBug& getBugType() {
+      return (CFRefBug&) RangedBugReport::getBugType();
+    }
+    const CFRefBug& getBugType() const {
+      return (const CFRefBug&) RangedBugReport::getBugType();
+    }
+
+    virtual void getRanges(const SourceRange*& beg, const SourceRange*& end) {
+      if (!getBugType().isLeak())
+        RangedBugReport::getRanges(beg, end);
+      else
+        beg = end = 0;
+    }
+
+    SymbolRef getSymbol() const { return Sym; }
+
+    PathDiagnosticPiece* getEndPath(BugReporterContext& BRC,
+                                    const ExplodedNode* N);
+
+    std::pair<const char**,const char**> getExtraDescriptiveText();
+
+    PathDiagnosticPiece* VisitNode(const ExplodedNode* N,
+                                   const ExplodedNode* PrevN,
+                                   BugReporterContext& BRC);
+  };
+
+  class CFRefLeakReport : public CFRefReport {
+    SourceLocation AllocSite;
+    const MemRegion* AllocBinding;
+  public:
+    CFRefLeakReport(CFRefBug& D, const CFRefCount &tf,
+                    ExplodedNode *n, SymbolRef sym,
+                    GRExprEngine& Eng);
+
+    PathDiagnosticPiece* getEndPath(BugReporterContext& BRC,
+                                    const ExplodedNode* N);
+
+    SourceLocation getLocation() const { return AllocSite; }
+  };
+} // end anonymous namespace
+
+
+
+static const char* Msgs[] = {
+  // GC only
+  "Code is compiled to only use garbage collection",
+  // No GC.
+  "Code is compiled to use reference counts",
+  // Hybrid, with GC.
+  "Code is compiled to use either garbage collection (GC) or reference counts"
+  " (non-GC).  The bug occurs with GC enabled",
+  // Hybrid, without GC
+  "Code is compiled to use either garbage collection (GC) or reference counts"
+  " (non-GC).  The bug occurs in non-GC mode"
+};
+
+std::pair<const char**,const char**> CFRefReport::getExtraDescriptiveText() {
+  CFRefCount& TF = static_cast<CFRefBug&>(getBugType()).getTF();
+
+  switch (TF.getLangOptions().getGCMode()) {
+    default:
+      assert(false);
+
+    case LangOptions::GCOnly:
+      assert (TF.isGCEnabled());
+      return std::make_pair(&Msgs[0], &Msgs[0]+1);
+
+    case LangOptions::NonGC:
+      assert (!TF.isGCEnabled());
+      return std::make_pair(&Msgs[1], &Msgs[1]+1);
+
+    case LangOptions::HybridGC:
+      if (TF.isGCEnabled())
+        return std::make_pair(&Msgs[2], &Msgs[2]+1);
+      else
+        return std::make_pair(&Msgs[3], &Msgs[3]+1);
+  }
+}
+
+static inline bool contains(const llvm::SmallVectorImpl<ArgEffect>& V,
+                            ArgEffect X) {
+  for (llvm::SmallVectorImpl<ArgEffect>::const_iterator I=V.begin(), E=V.end();
+       I!=E; ++I)
+    if (*I == X) return true;
+
+  return false;
+}
+
+PathDiagnosticPiece* CFRefReport::VisitNode(const ExplodedNode* N,
+                                            const ExplodedNode* PrevN,
+                                            BugReporterContext& BRC) {
+
+  if (!isa<PostStmt>(N->getLocation()))
+    return NULL;
+
+  // Check if the type state has changed.
+  const GRState *PrevSt = PrevN->getState();
+  const GRState *CurrSt = N->getState();
+
+  const RefVal* CurrT = CurrSt->get<RefBindings>(Sym);
+  if (!CurrT) return NULL;
+
+  const RefVal &CurrV = *CurrT;
+  const RefVal *PrevT = PrevSt->get<RefBindings>(Sym);
+
+  // Create a string buffer to constain all the useful things we want
+  // to tell the user.
+  std::string sbuf;
+  llvm::raw_string_ostream os(sbuf);
+
+  // This is the allocation site since the previous node had no bindings
+  // for this symbol.
+  if (!PrevT) {
+    const Stmt* S = cast<PostStmt>(N->getLocation()).getStmt();
+
+    if (const CallExpr *CE = dyn_cast<CallExpr>(S)) {
+      // Get the name of the callee (if it is available).
+      SVal X = CurrSt->getSValAsScalarOrLoc(CE->getCallee());
+      if (const FunctionDecl* FD = X.getAsFunctionDecl())
+        os << "Call to function '" << FD << '\'';
+      else
+        os << "function call";
+    }
+    else {
+      assert (isa<ObjCMessageExpr>(S));
+      os << "Method";
+    }
+
+    if (CurrV.getObjKind() == RetEffect::CF) {
+      os << " returns a Core Foundation object with a ";
+    }
+    else {
+      assert (CurrV.getObjKind() == RetEffect::ObjC);
+      os << " returns an Objective-C object with a ";
+    }
+
+    if (CurrV.isOwned()) {
+      os << "+1 retain count (owning reference).";
+
+      if (static_cast<CFRefBug&>(getBugType()).getTF().isGCEnabled()) {
+        assert(CurrV.getObjKind() == RetEffect::CF);
+        os << "  "
+        "Core Foundation objects are not automatically garbage collected.";
+      }
+    }
+    else {
+      assert (CurrV.isNotOwned());
+      os << "+0 retain count (non-owning reference).";
+    }
+
+    PathDiagnosticLocation Pos(S, BRC.getSourceManager());
+    return new PathDiagnosticEventPiece(Pos, os.str());
+  }
+
+  // Gather up the effects that were performed on the object at this
+  // program point
+  llvm::SmallVector<ArgEffect, 2> AEffects;
+
+  if (const RetainSummary *Summ =
+        TF.getSummaryOfNode(BRC.getNodeResolver().getOriginalNode(N))) {
+    // We only have summaries attached to nodes after evaluating CallExpr and
+    // ObjCMessageExprs.
+    const Stmt* S = cast<PostStmt>(N->getLocation()).getStmt();
+
+    if (const CallExpr *CE = dyn_cast<CallExpr>(S)) {
+      // Iterate through the parameter expressions and see if the symbol
+      // was ever passed as an argument.
+      unsigned i = 0;
+
+      for (CallExpr::const_arg_iterator AI=CE->arg_begin(), AE=CE->arg_end();
+           AI!=AE; ++AI, ++i) {
+
+        // Retrieve the value of the argument.  Is it the symbol
+        // we are interested in?
+        if (CurrSt->getSValAsScalarOrLoc(*AI).getAsLocSymbol() != Sym)
+          continue;
+
+        // We have an argument.  Get the effect!
+        AEffects.push_back(Summ->getArg(i));
+      }
+    }
+    else if (const ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(S)) {
+      if (const Expr *receiver = ME->getInstanceReceiver())
+        if (CurrSt->getSValAsScalarOrLoc(receiver).getAsLocSymbol() == Sym) {
+          // The symbol we are tracking is the receiver.
+          AEffects.push_back(Summ->getReceiverEffect());
+        }
+    }
+  }
+
+  do {
+    // Get the previous type state.
+    RefVal PrevV = *PrevT;
+
+    // Specially handle -dealloc.
+    if (!TF.isGCEnabled() && contains(AEffects, Dealloc)) {
+      // Determine if the object's reference count was pushed to zero.
+      assert(!(PrevV == CurrV) && "The typestate *must* have changed.");
+      // We may not have transitioned to 'release' if we hit an error.
+      // This case is handled elsewhere.
+      if (CurrV.getKind() == RefVal::Released) {
+        assert(CurrV.getCombinedCounts() == 0);
+        os << "Object released by directly sending the '-dealloc' message";
+        break;
+      }
+    }
+
+    // Specially handle CFMakeCollectable and friends.
+    if (contains(AEffects, MakeCollectable)) {
+      // Get the name of the function.
+      const Stmt* S = cast<PostStmt>(N->getLocation()).getStmt();
+      SVal X = CurrSt->getSValAsScalarOrLoc(cast<CallExpr>(S)->getCallee());
+      const FunctionDecl* FD = X.getAsFunctionDecl();
+      const std::string& FName = FD->getNameAsString();
+
+      if (TF.isGCEnabled()) {
+        // Determine if the object's reference count was pushed to zero.
+        assert(!(PrevV == CurrV) && "The typestate *must* have changed.");
+
+        os << "In GC mode a call to '" << FName
+        <<  "' decrements an object's retain count and registers the "
+        "object with the garbage collector. ";
+
+        if (CurrV.getKind() == RefVal::Released) {
+          assert(CurrV.getCount() == 0);
+          os << "Since it now has a 0 retain count the object can be "
+          "automatically collected by the garbage collector.";
+        }
+        else
+          os << "An object must have a 0 retain count to be garbage collected. "
+          "After this call its retain count is +" << CurrV.getCount()
+          << '.';
+      }
+      else
+        os << "When GC is not enabled a call to '" << FName
+        << "' has no effect on its argument.";
+
+      // Nothing more to say.
+      break;
+    }
+
+    // Determine if the typestate has changed.
+    if (!(PrevV == CurrV))
+      switch (CurrV.getKind()) {
+        case RefVal::Owned:
+        case RefVal::NotOwned:
+
+          if (PrevV.getCount() == CurrV.getCount()) {
+            // Did an autorelease message get sent?
+            if (PrevV.getAutoreleaseCount() == CurrV.getAutoreleaseCount())
+              return 0;
+
+            assert(PrevV.getAutoreleaseCount() < CurrV.getAutoreleaseCount());
+            os << "Object sent -autorelease message";
+            break;
+          }
+
+          if (PrevV.getCount() > CurrV.getCount())
+            os << "Reference count decremented.";
+          else
+            os << "Reference count incremented.";
+
+          if (unsigned Count = CurrV.getCount())
+            os << " The object now has a +" << Count << " retain count.";
+
+          if (PrevV.getKind() == RefVal::Released) {
+            assert(TF.isGCEnabled() && CurrV.getCount() > 0);
+            os << " The object is not eligible for garbage collection until the "
+            "retain count reaches 0 again.";
+          }
+
+          break;
+
+        case RefVal::Released:
+          os << "Object released.";
+          break;
+
+        case RefVal::ReturnedOwned:
+          os << "Object returned to caller as an owning reference (single retain "
+          "count transferred to caller).";
+          break;
+
+        case RefVal::ReturnedNotOwned:
+          os << "Object returned to caller with a +0 (non-owning) retain count.";
+          break;
+
+        default:
+          return NULL;
+      }
+
+    // Emit any remaining diagnostics for the argument effects (if any).
+    for (llvm::SmallVectorImpl<ArgEffect>::iterator I=AEffects.begin(),
+         E=AEffects.end(); I != E; ++I) {
+
+      // A bunch of things have alternate behavior under GC.
+      if (TF.isGCEnabled())
+        switch (*I) {
+          default: break;
+          case Autorelease:
+            os << "In GC mode an 'autorelease' has no effect.";
+            continue;
+          case IncRefMsg:
+            os << "In GC mode the 'retain' message has no effect.";
+            continue;
+          case DecRefMsg:
+            os << "In GC mode the 'release' message has no effect.";
+            continue;
+        }
+    }
+  } while (0);
+
+  if (os.str().empty())
+    return 0; // We have nothing to say!
+
+  const Stmt* S = cast<PostStmt>(N->getLocation()).getStmt();
+  PathDiagnosticLocation Pos(S, BRC.getSourceManager());
+  PathDiagnosticPiece* P = new PathDiagnosticEventPiece(Pos, os.str());
+
+  // Add the range by scanning the children of the statement for any bindings
+  // to Sym.
+  for (Stmt::const_child_iterator I = S->child_begin(), E = S->child_end();
+       I!=E; ++I)
+    if (const Expr* Exp = dyn_cast_or_null<Expr>(*I))
+      if (CurrSt->getSValAsScalarOrLoc(Exp).getAsLocSymbol() == Sym) {
+        P->addRange(Exp->getSourceRange());
+        break;
+      }
+
+  return P;
+}
+
+namespace {
+  class FindUniqueBinding :
+  public StoreManager::BindingsHandler {
+    SymbolRef Sym;
+    const MemRegion* Binding;
+    bool First;
+
+  public:
+    FindUniqueBinding(SymbolRef sym) : Sym(sym), Binding(0), First(true) {}
+
+    bool HandleBinding(StoreManager& SMgr, Store store, const MemRegion* R,
+                       SVal val) {
+
+      SymbolRef SymV = val.getAsSymbol();
+      if (!SymV || SymV != Sym)
+        return true;
+
+      if (Binding) {
+        First = false;
+        return false;
+      }
+      else
+        Binding = R;
+
+      return true;
+    }
+
+    operator bool() { return First && Binding; }
+    const MemRegion* getRegion() { return Binding; }
+  };
+}
+
+static std::pair<const ExplodedNode*,const MemRegion*>
+GetAllocationSite(GRStateManager& StateMgr, const ExplodedNode* N,
+                  SymbolRef Sym) {
+
+  // Find both first node that referred to the tracked symbol and the
+  // memory location that value was store to.
+  const ExplodedNode* Last = N;
+  const MemRegion* FirstBinding = 0;
+
+  while (N) {
+    const GRState* St = N->getState();
+    RefBindings B = St->get<RefBindings>();
+
+    if (!B.lookup(Sym))
+      break;
+
+    FindUniqueBinding FB(Sym);
+    StateMgr.iterBindings(St, FB);
+    if (FB) FirstBinding = FB.getRegion();
+
+    Last = N;
+    N = N->pred_empty() ? NULL : *(N->pred_begin());
+  }
+
+  return std::make_pair(Last, FirstBinding);
+}
+
+PathDiagnosticPiece*
+CFRefReport::getEndPath(BugReporterContext& BRC,
+                        const ExplodedNode* EndN) {
+  // Tell the BugReporterContext to report cases when the tracked symbol is
+  // assigned to different variables, etc.
+  BRC.addNotableSymbol(Sym);
+  return RangedBugReport::getEndPath(BRC, EndN);
+}
+
+PathDiagnosticPiece*
+CFRefLeakReport::getEndPath(BugReporterContext& BRC,
+                            const ExplodedNode* EndN){
+
+  // Tell the BugReporterContext to report cases when the tracked symbol is
+  // assigned to different variables, etc.
+  BRC.addNotableSymbol(Sym);
+
+  // We are reporting a leak.  Walk up the graph to get to the first node where
+  // the symbol appeared, and also get the first VarDecl that tracked object
+  // is stored to.
+  const ExplodedNode* AllocNode = 0;
+  const MemRegion* FirstBinding = 0;
+
+  llvm::tie(AllocNode, FirstBinding) =
+    GetAllocationSite(BRC.getStateManager(), EndN, Sym);
+
+  // Get the allocate site.
+  assert(AllocNode);
+  const Stmt* FirstStmt = cast<PostStmt>(AllocNode->getLocation()).getStmt();
+
+  SourceManager& SMgr = BRC.getSourceManager();
+  unsigned AllocLine =SMgr.getInstantiationLineNumber(FirstStmt->getLocStart());
+
+  // Compute an actual location for the leak.  Sometimes a leak doesn't
+  // occur at an actual statement (e.g., transition between blocks; end
+  // of function) so we need to walk the graph and compute a real location.
+  const ExplodedNode* LeakN = EndN;
+  PathDiagnosticLocation L;
+
+  while (LeakN) {
+    ProgramPoint P = LeakN->getLocation();
+
+    if (const PostStmt *PS = dyn_cast<PostStmt>(&P)) {
+      L = PathDiagnosticLocation(PS->getStmt()->getLocStart(), SMgr);
+      break;
+    }
+    else if (const BlockEdge *BE = dyn_cast<BlockEdge>(&P)) {
+      if (const Stmt* Term = BE->getSrc()->getTerminator()) {
+        L = PathDiagnosticLocation(Term->getLocStart(), SMgr);
+        break;
+      }
+    }
+
+    LeakN = LeakN->succ_empty() ? 0 : *(LeakN->succ_begin());
+  }
+
+  if (!L.isValid()) {
+    const Decl &D = EndN->getCodeDecl();
+    L = PathDiagnosticLocation(D.getBodyRBrace(), SMgr);
+  }
+
+  std::string sbuf;
+  llvm::raw_string_ostream os(sbuf);
+
+  os << "Object allocated on line " << AllocLine;
+
+  if (FirstBinding)
+    os << " and stored into '" << FirstBinding->getString() << '\'';
+
+  // Get the retain count.
+  const RefVal* RV = EndN->getState()->get<RefBindings>(Sym);
+
+  if (RV->getKind() == RefVal::ErrorLeakReturned) {
+    // FIXME: Per comments in rdar://6320065, "create" only applies to CF
+    // ojbects.  Only "copy", "alloc", "retain" and "new" transfer ownership
+    // to the caller for NS objects.
+    ObjCMethodDecl& MD = cast<ObjCMethodDecl>(EndN->getCodeDecl());
+    os << " is returned from a method whose name ('"
+       << MD.getSelector().getAsString()
+    << "') does not contain 'copy' or otherwise starts with"
+    " 'new' or 'alloc'.  This violates the naming convention rules given"
+    " in the Memory Management Guide for Cocoa (object leaked)";
+  }
+  else if (RV->getKind() == RefVal::ErrorGCLeakReturned) {
+    ObjCMethodDecl& MD = cast<ObjCMethodDecl>(EndN->getCodeDecl());
+    os << " and returned from method '" << MD.getSelector().getAsString()
+       << "' is potentially leaked when using garbage collection.  Callers "
+          "of this method do not expect a returned object with a +1 retain "
+          "count since they expect the object to be managed by the garbage "
+          "collector";
+  }
+  else
+    os << " is no longer referenced after this point and has a retain count of"
+          " +" << RV->getCount() << " (object leaked)";
+
+  return new PathDiagnosticEventPiece(L, os.str());
+}
+
+CFRefLeakReport::CFRefLeakReport(CFRefBug& D, const CFRefCount &tf,
+                                 ExplodedNode *n,
+                                 SymbolRef sym, GRExprEngine& Eng)
+: CFRefReport(D, tf, n, sym) {
+
+  // Most bug reports are cached at the location where they occured.
+  // With leaks, we want to unique them by the location where they were
+  // allocated, and only report a single path.  To do this, we need to find
+  // the allocation site of a piece of tracked memory, which we do via a
+  // call to GetAllocationSite.  This will walk the ExplodedGraph backwards.
+  // Note that this is *not* the trimmed graph; we are guaranteed, however,
+  // that all ancestor nodes that represent the allocation site have the
+  // same SourceLocation.
+  const ExplodedNode* AllocNode = 0;
+
+  llvm::tie(AllocNode, AllocBinding) =  // Set AllocBinding.
+    GetAllocationSite(Eng.getStateManager(), getEndNode(), getSymbol());
+
+  // Get the SourceLocation for the allocation site.
+  ProgramPoint P = AllocNode->getLocation();
+  AllocSite = cast<PostStmt>(P).getStmt()->getLocStart();
+
+  // Fill in the description of the bug.
+  Description.clear();
+  llvm::raw_string_ostream os(Description);
+  SourceManager& SMgr = Eng.getContext().getSourceManager();
+  unsigned AllocLine = SMgr.getInstantiationLineNumber(AllocSite);
+  os << "Potential leak ";
+  if (tf.isGCEnabled()) {
+    os << "(when using garbage collection) ";
+  }
+  os << "of an object allocated on line " << AllocLine;
+
+  // FIXME: AllocBinding doesn't get populated for RegionStore yet.
+  if (AllocBinding)
+    os << " and stored into '" << AllocBinding->getString() << '\'';
+}
+
+//===----------------------------------------------------------------------===//
+// Main checker logic.
+//===----------------------------------------------------------------------===//
+
+/// GetReturnType - Used to get the return type of a message expression or
+///  function call with the intention of affixing that type to a tracked symbol.
+///  While the the return type can be queried directly from RetEx, when
+///  invoking class methods we augment to the return type to be that of
+///  a pointer to the class (as opposed it just being id).
+static QualType GetReturnType(const Expr* RetE, ASTContext& Ctx) {
+  QualType RetTy = RetE->getType();
+  // If RetE is not a message expression just return its type.
+  // If RetE is a message expression, return its types if it is something
+  /// more specific than id.
+  if (const ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(RetE))
+    if (const ObjCObjectPointerType *PT = RetTy->getAs<ObjCObjectPointerType>())
+      if (PT->isObjCQualifiedIdType() || PT->isObjCIdType() ||
+          PT->isObjCClassType()) {
+        // At this point we know the return type of the message expression is
+        // id, id<...>, or Class. If we have an ObjCInterfaceDecl, we know this
+        // is a call to a class method whose type we can resolve.  In such
+        // cases, promote the return type to XXX* (where XXX is the class).
+        const ObjCInterfaceDecl *D = ME->getReceiverInterface();
+        return !D ? RetTy : Ctx.getPointerType(Ctx.getObjCInterfaceType(D));
+      }
+
+  return RetTy;
+}
+
+void CFRefCount::EvalSummary(ExplodedNodeSet& Dst,
+                             GRExprEngine& Eng,
+                             GRStmtNodeBuilder& Builder,
+                             Expr* Ex,
+                             Expr* Receiver,
+                             const RetainSummary& Summ,
+                             const MemRegion *Callee,
+                             ExprIterator arg_beg, ExprIterator arg_end,
+                             ExplodedNode* Pred, const GRState *state) {
+
+  // Evaluate the effect of the arguments.
+  RefVal::Kind hasErr = (RefVal::Kind) 0;
+  unsigned idx = 0;
+  Expr* ErrorExpr = NULL;
+  SymbolRef ErrorSym = 0;
+
+  llvm::SmallVector<const MemRegion*, 10> RegionsToInvalidate;
+  
+  for (ExprIterator I = arg_beg; I != arg_end; ++I, ++idx) {
+    SVal V = state->getSValAsScalarOrLoc(*I);
+    SymbolRef Sym = V.getAsLocSymbol();
+
+    if (Sym)
+      if (RefBindings::data_type* T = state->get<RefBindings>(Sym)) {
+        state = Update(state, Sym, *T, Summ.getArg(idx), hasErr);
+        if (hasErr) {
+          ErrorExpr = *I;
+          ErrorSym = Sym;
+          break;
+        }
+        continue;
+      }
+
+  tryAgain:
+    if (isa<Loc>(V)) {
+      if (loc::MemRegionVal* MR = dyn_cast<loc::MemRegionVal>(&V)) {
+        if (Summ.getArg(idx) == DoNothingByRef)
+          continue;
+
+        // Invalidate the value of the variable passed by reference.
+        const MemRegion *R = MR->getRegion();
+
+        // Are we dealing with an ElementRegion?  If the element type is
+        // a basic integer type (e.g., char, int) and the underying region
+        // is a variable region then strip off the ElementRegion.
+        // FIXME: We really need to think about this for the general case
+        //   as sometimes we are reasoning about arrays and other times
+        //   about (char*), etc., is just a form of passing raw bytes.
+        //   e.g., void *p = alloca(); foo((char*)p);
+        if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
+          // Checking for 'integral type' is probably too promiscuous, but
+          // we'll leave it in for now until we have a systematic way of
+          // handling all of these cases.  Eventually we need to come up
+          // with an interface to StoreManager so that this logic can be
+          // approriately delegated to the respective StoreManagers while
+          // still allowing us to do checker-specific logic (e.g.,
+          // invalidating reference counts), probably via callbacks.
+          if (ER->getElementType()->isIntegralType()) {
+            const MemRegion *superReg = ER->getSuperRegion();
+            if (isa<VarRegion>(superReg) || isa<FieldRegion>(superReg) ||
+                isa<ObjCIvarRegion>(superReg))
+              R = cast<TypedRegion>(superReg);
+          }
+          // FIXME: What about layers of ElementRegions?
+        }
+        
+        // Mark this region for invalidation.  We batch invalidate regions
+        // below for efficiency.
+        RegionsToInvalidate.push_back(R);
+        continue;
+      }
+      else {
+        // Nuke all other arguments passed by reference.
+        // FIXME: is this necessary or correct? This handles the non-Region
+        //  cases.  Is it ever valid to store to these?
+        state = state->unbindLoc(cast<Loc>(V));
+      }
+    }
+    else if (isa<nonloc::LocAsInteger>(V)) {
+      // If we are passing a location wrapped as an integer, unwrap it and
+      // invalidate the values referred by the location.
+      V = cast<nonloc::LocAsInteger>(V).getLoc();
+      goto tryAgain;
+    }
+  }
+  
+  // Block calls result in all captured values passed-via-reference to be
+  // invalidated.
+  if (const BlockDataRegion *BR = dyn_cast_or_null<BlockDataRegion>(Callee)) {
+    RegionsToInvalidate.push_back(BR);
+  }
+  
+  // Invalidate regions we designed for invalidation use the batch invalidation
+  // API.
+  if (!RegionsToInvalidate.empty()) {    
+    // FIXME: We can have collisions on the conjured symbol if the
+    //  expression *I also creates conjured symbols.  We probably want
+    //  to identify conjured symbols by an expression pair: the enclosing
+    //  expression (the context) and the expression itself.  This should
+    //  disambiguate conjured symbols.
+    unsigned Count = Builder.getCurrentBlockCount();
+    StoreManager& StoreMgr = Eng.getStateManager().getStoreManager();
+
+    
+    StoreManager::InvalidatedSymbols IS;
+    Store store = state->getStore();
+    store = StoreMgr.InvalidateRegions(store, RegionsToInvalidate.data(),
+                                       RegionsToInvalidate.data() +
+                                       RegionsToInvalidate.size(),
+                                       Ex, Count, &IS);
+    state = state->makeWithStore(store);
+    for (StoreManager::InvalidatedSymbols::iterator I = IS.begin(),
+         E = IS.end(); I!=E; ++I) {
+        // Remove any existing reference-count binding.
+      state = state->remove<RefBindings>(*I);
+    }
+  }
+
+  // Evaluate the effect on the message receiver.
+  if (!ErrorExpr && Receiver) {
+    SymbolRef Sym = state->getSValAsScalarOrLoc(Receiver).getAsLocSymbol();
+    if (Sym) {
+      if (const RefVal* T = state->get<RefBindings>(Sym)) {
+        state = Update(state, Sym, *T, Summ.getReceiverEffect(), hasErr);
+        if (hasErr) {
+          ErrorExpr = Receiver;
+          ErrorSym = Sym;
+        }
+      }
+    }
+  }
+
+  // Process any errors.
+  if (hasErr) {
+    ProcessNonLeakError(Dst, Builder, Ex, ErrorExpr, Pred, state,
+                        hasErr, ErrorSym);
+    return;
+  }
+
+  // Consult the summary for the return value.
+  RetEffect RE = Summ.getRetEffect();
+
+  if (RE.getKind() == RetEffect::OwnedWhenTrackedReceiver) {
+    bool found = false;
+    if (Receiver) {
+      SVal V = state->getSValAsScalarOrLoc(Receiver);
+      if (SymbolRef Sym = V.getAsLocSymbol())
+        if (state->get<RefBindings>(Sym)) {
+          found = true;
+          RE = Summaries.getObjAllocRetEffect();
+        }
+    } // FIXME: Otherwise, this is a send-to-super instance message.
+    if (!found)
+      RE = RetEffect::MakeNoRet();
+  }
+
+  switch (RE.getKind()) {
+    default:
+      assert (false && "Unhandled RetEffect."); break;
+
+    case RetEffect::NoRet: {
+      // Make up a symbol for the return value (not reference counted).
+      // FIXME: Most of this logic is not specific to the retain/release
+      // checker.
+
+      // FIXME: We eventually should handle structs and other compound types
+      // that are returned by value.
+
+      QualType T = Ex->getType();
+
+      // For CallExpr, use the result type to know if it returns a reference.
+      if (const CallExpr *CE = dyn_cast<CallExpr>(Ex)) {
+        const Expr *Callee = CE->getCallee();
+        if (const FunctionDecl *FD = state->getSVal(Callee).getAsFunctionDecl())
+          T = FD->getResultType();
+      }
+      else if (const ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(Ex)) {
+        if (const ObjCMethodDecl *MD = ME->getMethodDecl())
+          T = MD->getResultType();
+      }
+
+      if (Loc::IsLocType(T) || (T->isIntegerType() && T->isScalarType())) {
+        unsigned Count = Builder.getCurrentBlockCount();
+        ValueManager &ValMgr = Eng.getValueManager();
+        SVal X = ValMgr.getConjuredSymbolVal(NULL, Ex, T, Count);
+        state = state->BindExpr(Ex, X, false);
+      }
+
+      break;
+    }
+
+    case RetEffect::Alias: {
+      unsigned idx = RE.getIndex();
+      assert (arg_end >= arg_beg);
+      assert (idx < (unsigned) (arg_end - arg_beg));
+      SVal V = state->getSValAsScalarOrLoc(*(arg_beg+idx));
+      state = state->BindExpr(Ex, V, false);
+      break;
+    }
+
+    case RetEffect::ReceiverAlias: {
+      assert (Receiver);
+      SVal V = state->getSValAsScalarOrLoc(Receiver);
+      state = state->BindExpr(Ex, V, false);
+      break;
+    }
+
+    case RetEffect::OwnedAllocatedSymbol:
+    case RetEffect::OwnedSymbol: {
+      unsigned Count = Builder.getCurrentBlockCount();
+      ValueManager &ValMgr = Eng.getValueManager();
+      SymbolRef Sym = ValMgr.getConjuredSymbol(Ex, Count);
+      QualType RetT = GetReturnType(Ex, ValMgr.getContext());
+      state = state->set<RefBindings>(Sym, RefVal::makeOwned(RE.getObjKind(),
+                                                            RetT));
+      state = state->BindExpr(Ex, ValMgr.makeLoc(Sym), false);
+
+      // FIXME: Add a flag to the checker where allocations are assumed to
+      // *not fail.
+#if 0
+      if (RE.getKind() == RetEffect::OwnedAllocatedSymbol) {
+        bool isFeasible;
+        state = state.Assume(loc::SymbolVal(Sym), true, isFeasible);
+        assert(isFeasible && "Cannot assume fresh symbol is non-null.");
+      }
+#endif
+
+      break;
+    }
+
+    case RetEffect::GCNotOwnedSymbol:
+    case RetEffect::NotOwnedSymbol: {
+      unsigned Count = Builder.getCurrentBlockCount();
+      ValueManager &ValMgr = Eng.getValueManager();
+      SymbolRef Sym = ValMgr.getConjuredSymbol(Ex, Count);
+      QualType RetT = GetReturnType(Ex, ValMgr.getContext());
+      state = state->set<RefBindings>(Sym, RefVal::makeNotOwned(RE.getObjKind(),
+                                                               RetT));
+      state = state->BindExpr(Ex, ValMgr.makeLoc(Sym), false);
+      break;
+    }
+  }
+
+  // Generate a sink node if we are at the end of a path.
+  ExplodedNode *NewNode =
+    Summ.isEndPath() ? Builder.MakeSinkNode(Dst, Ex, Pred, state)
+                     : Builder.MakeNode(Dst, Ex, Pred, state);
+
+  // Annotate the edge with summary we used.
+  if (NewNode) SummaryLog[NewNode] = &Summ;
+}
+
+
+void CFRefCount::EvalCall(ExplodedNodeSet& Dst,
+                          GRExprEngine& Eng,
+                          GRStmtNodeBuilder& Builder,
+                          CallExpr* CE, SVal L,
+                          ExplodedNode* Pred) {
+
+  RetainSummary *Summ = 0;
+  
+  // FIXME: Better support for blocks.  For now we stop tracking anything
+  // that is passed to blocks.
+  // FIXME: Need to handle variables that are "captured" by the block.
+  if (dyn_cast_or_null<BlockDataRegion>(L.getAsRegion())) {
+    Summ = Summaries.getPersistentStopSummary();
+  }
+  else {
+    const FunctionDecl* FD = L.getAsFunctionDecl();
+    Summ = !FD ? Summaries.getDefaultSummary() :
+                 Summaries.getSummary(const_cast<FunctionDecl*>(FD));
+  }
+
+  assert(Summ);
+  EvalSummary(Dst, Eng, Builder, CE, 0, *Summ, L.getAsRegion(),
+              CE->arg_begin(), CE->arg_end(), Pred, Builder.GetState(Pred));
+}
+
+void CFRefCount::EvalObjCMessageExpr(ExplodedNodeSet& Dst,
+                                     GRExprEngine& Eng,
+                                     GRStmtNodeBuilder& Builder,
+                                     ObjCMessageExpr* ME,
+                                     ExplodedNode* Pred,
+                                     const GRState *state) {
+  RetainSummary *Summ =
+    ME->isInstanceMessage()
+      ? Summaries.getInstanceMethodSummary(ME, state,Pred->getLocationContext())
+      : Summaries.getClassMethodSummary(ME);
+
+  assert(Summ && "RetainSummary is null");
+  EvalSummary(Dst, Eng, Builder, ME, ME->getInstanceReceiver(), *Summ, NULL,
+              ME->arg_begin(), ME->arg_end(), Pred, state);
+}
+
+namespace {
+class StopTrackingCallback : public SymbolVisitor {
+  const GRState *state;
+public:
+  StopTrackingCallback(const GRState *st) : state(st) {}
+  const GRState *getState() const { return state; }
+
+  bool VisitSymbol(SymbolRef sym) {
+    state = state->remove<RefBindings>(sym);
+    return true;
+  }
+};
+} // end anonymous namespace
+
+
+void CFRefCount::EvalBind(GRStmtNodeBuilderRef& B, SVal location, SVal val) {
+  // Are we storing to something that causes the value to "escape"?
+  bool escapes = false;
+
+  // A value escapes in three possible cases (this may change):
+  //
+  // (1) we are binding to something that is not a memory region.
+  // (2) we are binding to a memregion that does not have stack storage
+  // (3) we are binding to a memregion with stack storage that the store
+  //     does not understand.
+  const GRState *state = B.getState();
+
+  if (!isa<loc::MemRegionVal>(location))
+    escapes = true;
+  else {
+    const MemRegion* R = cast<loc::MemRegionVal>(location).getRegion();
+    escapes = !R->hasStackStorage();
+
+    if (!escapes) {
+      // To test (3), generate a new state with the binding removed.  If it is
+      // the same state, then it escapes (since the store cannot represent
+      // the binding).
+      escapes = (state == (state->bindLoc(cast<Loc>(location), UnknownVal())));
+    }
+  }
+
+  // If our store can represent the binding and we aren't storing to something
+  // that doesn't have local storage then just return and have the simulation
+  // state continue as is.
+  if (!escapes)
+      return;
+
+  // Otherwise, find all symbols referenced by 'val' that we are tracking
+  // and stop tracking them.
+  B.MakeNode(state->scanReachableSymbols<StopTrackingCallback>(val).getState());
+}
+
+ // Return statements.
+
+void CFRefCount::EvalReturn(ExplodedNodeSet& Dst,
+                            GRExprEngine& Eng,
+                            GRStmtNodeBuilder& Builder,
+                            ReturnStmt* S,
+                            ExplodedNode* Pred) {
+
+  Expr* RetE = S->getRetValue();
+  if (!RetE)
+    return;
+
+  const GRState *state = Builder.GetState(Pred);
+  SymbolRef Sym = state->getSValAsScalarOrLoc(RetE).getAsLocSymbol();
+
+  if (!Sym)
+    return;
+
+  // Get the reference count binding (if any).
+  const RefVal* T = state->get<RefBindings>(Sym);
+
+  if (!T)
+    return;
+
+  // Change the reference count.
+  RefVal X = *T;
+
+  switch (X.getKind()) {
+    case RefVal::Owned: {
+      unsigned cnt = X.getCount();
+      assert (cnt > 0);
+      X.setCount(cnt - 1);
+      X = X ^ RefVal::ReturnedOwned;
+      break;
+    }
+
+    case RefVal::NotOwned: {
+      unsigned cnt = X.getCount();
+      if (cnt) {
+        X.setCount(cnt - 1);
+        X = X ^ RefVal::ReturnedOwned;
+      }
+      else {
+        X = X ^ RefVal::ReturnedNotOwned;
+      }
+      break;
+    }
+
+    default:
+      return;
+  }
+
+  // Update the binding.
+  state = state->set<RefBindings>(Sym, X);
+  Pred = Builder.MakeNode(Dst, S, Pred, state);
+
+  // Did we cache out?
+  if (!Pred)
+    return;
+
+  // Update the autorelease counts.
+  static unsigned autoreleasetag = 0;
+  GenericNodeBuilder Bd(Builder, S, &autoreleasetag);
+  bool stop = false;
+  llvm::tie(Pred, state) = HandleAutoreleaseCounts(state , Bd, Pred, Eng, Sym,
+                                                   X, stop);
+
+  // Did we cache out?
+  if (!Pred || stop)
+    return;
+
+  // Get the updated binding.
+  T = state->get<RefBindings>(Sym);
+  assert(T);
+  X = *T;
+
+  // Any leaks or other errors?
+  if (X.isReturnedOwned() && X.getCount() == 0) {
+    Decl const *CD = &Pred->getCodeDecl();
+    if (const ObjCMethodDecl* MD = dyn_cast<ObjCMethodDecl>(CD)) {
+      const RetainSummary &Summ = *Summaries.getMethodSummary(MD);
+      RetEffect RE = Summ.getRetEffect();
+      bool hasError = false;
+
+      if (RE.getKind() != RetEffect::NoRet) {
+        if (isGCEnabled() && RE.getObjKind() == RetEffect::ObjC) {
+          // Things are more complicated with garbage collection.  If the
+          // returned object is suppose to be an Objective-C object, we have
+          // a leak (as the caller expects a GC'ed object) because no
+          // method should return ownership unless it returns a CF object.
+          hasError = true;
+          X = X ^ RefVal::ErrorGCLeakReturned;
+        }
+        else if (!RE.isOwned()) {
+          // Either we are using GC and the returned object is a CF type
+          // or we aren't using GC.  In either case, we expect that the
+          // enclosing method is expected to return ownership.
+          hasError = true;
+          X = X ^ RefVal::ErrorLeakReturned;
+        }
+      }
+
+      if (hasError) {
+        // Generate an error node.
+        static int ReturnOwnLeakTag = 0;
+        state = state->set<RefBindings>(Sym, X);
+        ExplodedNode *N =
+          Builder.generateNode(PostStmt(S, Pred->getLocationContext(),
+                                        &ReturnOwnLeakTag), state, Pred);
+        if (N) {
+          CFRefReport *report =
+            new CFRefLeakReport(*static_cast<CFRefBug*>(leakAtReturn), *this,
+                                N, Sym, Eng);
+          BR->EmitReport(report);
+        }
+      }
+    }
+  }
+  else if (X.isReturnedNotOwned()) {
+    Decl const *CD = &Pred->getCodeDecl();
+    if (const ObjCMethodDecl* MD = dyn_cast<ObjCMethodDecl>(CD)) {
+      const RetainSummary &Summ = *Summaries.getMethodSummary(MD);
+      if (Summ.getRetEffect().isOwned()) {
+        // Trying to return a not owned object to a caller expecting an
+        // owned object.
+
+        static int ReturnNotOwnedForOwnedTag = 0;
+        state = state->set<RefBindings>(Sym, X ^ RefVal::ErrorReturnedNotOwned);
+        if (ExplodedNode *N =
+            Builder.generateNode(PostStmt(S, Pred->getLocationContext(),
+                                          &ReturnNotOwnedForOwnedTag),
+                                 state, Pred)) {
+            CFRefReport *report =
+                new CFRefReport(*static_cast<CFRefBug*>(returnNotOwnedForOwned),
+                                *this, N, Sym);
+            BR->EmitReport(report);
+        }
+      }
+    }
+  }
+}
+
+// Assumptions.
+
+const GRState* CFRefCount::EvalAssume(const GRState *state,
+                                      SVal Cond, bool Assumption) {
+
+  // FIXME: We may add to the interface of EvalAssume the list of symbols
+  //  whose assumptions have changed.  For now we just iterate through the
+  //  bindings and check if any of the tracked symbols are NULL.  This isn't
+  //  too bad since the number of symbols we will track in practice are
+  //  probably small and EvalAssume is only called at branches and a few
+  //  other places.
+  RefBindings B = state->get<RefBindings>();
+
+  if (B.isEmpty())
+    return state;
+
+  bool changed = false;
+  RefBindings::Factory& RefBFactory = state->get_context<RefBindings>();
+
+  for (RefBindings::iterator I=B.begin(), E=B.end(); I!=E; ++I) {
+    // Check if the symbol is null (or equal to any constant).
+    // If this is the case, stop tracking the symbol.
+    if (state->getSymVal(I.getKey())) {
+      changed = true;
+      B = RefBFactory.Remove(B, I.getKey());
+    }
+  }
+
+  if (changed)
+    state = state->set<RefBindings>(B);
+
+  return state;
+}
+
+const GRState * CFRefCount::Update(const GRState * state, SymbolRef sym,
+                              RefVal V, ArgEffect E,
+                              RefVal::Kind& hasErr) {
+
+  // In GC mode [... release] and [... retain] do nothing.
+  switch (E) {
+    default: break;
+    case IncRefMsg: E = isGCEnabled() ? DoNothing : IncRef; break;
+    case DecRefMsg: E = isGCEnabled() ? DoNothing : DecRef; break;
+    case MakeCollectable: E = isGCEnabled() ? DecRef : DoNothing; break;
+    case NewAutoreleasePool: E = isGCEnabled() ? DoNothing :
+                                                 NewAutoreleasePool; break;
+  }
+
+  // Handle all use-after-releases.
+  if (!isGCEnabled() && V.getKind() == RefVal::Released) {
+    V = V ^ RefVal::ErrorUseAfterRelease;
+    hasErr = V.getKind();
+    return state->set<RefBindings>(sym, V);
+  }
+
+  switch (E) {
+    default:
+      assert (false && "Unhandled CFRef transition.");
+
+    case Dealloc:
+      // Any use of -dealloc in GC is *bad*.
+      if (isGCEnabled()) {
+        V = V ^ RefVal::ErrorDeallocGC;
+        hasErr = V.getKind();
+        break;
+      }
+
+      switch (V.getKind()) {
+        default:
+          assert(false && "Invalid case.");
+        case RefVal::Owned:
+          // The object immediately transitions to the released state.
+          V = V ^ RefVal::Released;
+          V.clearCounts();
+          return state->set<RefBindings>(sym, V);
+        case RefVal::NotOwned:
+          V = V ^ RefVal::ErrorDeallocNotOwned;
+          hasErr = V.getKind();
+          break;
+      }
+      break;
+
+    case NewAutoreleasePool:
+      assert(!isGCEnabled());
+      return state->add<AutoreleaseStack>(sym);
+
+    case MayEscape:
+      if (V.getKind() == RefVal::Owned) {
+        V = V ^ RefVal::NotOwned;
+        break;
+      }
+
+      // Fall-through.
+
+    case DoNothingByRef:
+    case DoNothing:
+      return state;
+
+    case Autorelease:
+      if (isGCEnabled())
+        return state;
+
+      // Update the autorelease counts.
+      state = SendAutorelease(state, ARCountFactory, sym);
+      V = V.autorelease();
+      break;
+
+    case StopTracking:
+      return state->remove<RefBindings>(sym);
+
+    case IncRef:
+      switch (V.getKind()) {
+        default:
+          assert(false);
+
+        case RefVal::Owned:
+        case RefVal::NotOwned:
+          V = V + 1;
+          break;
+        case RefVal::Released:
+          // Non-GC cases are handled above.
+          assert(isGCEnabled());
+          V = (V ^ RefVal::Owned) + 1;
+          break;
+      }
+      break;
+
+    case SelfOwn:
+      V = V ^ RefVal::NotOwned;
+      // Fall-through.
+    case DecRef:
+      switch (V.getKind()) {
+        default:
+          // case 'RefVal::Released' handled above.
+          assert (false);
+
+        case RefVal::Owned:
+          assert(V.getCount() > 0);
+          if (V.getCount() == 1) V = V ^ RefVal::Released;
+          V = V - 1;
+          break;
+
+        case RefVal::NotOwned:
+          if (V.getCount() > 0)
+            V = V - 1;
+          else {
+            V = V ^ RefVal::ErrorReleaseNotOwned;
+            hasErr = V.getKind();
+          }
+          break;
+
+        case RefVal::Released:
+          // Non-GC cases are handled above.
+          assert(isGCEnabled());
+          V = V ^ RefVal::ErrorUseAfterRelease;
+          hasErr = V.getKind();
+          break;
+      }
+      break;
+  }
+  return state->set<RefBindings>(sym, V);
+}
+
+//===----------------------------------------------------------------------===//
+// Handle dead symbols and end-of-path.
+//===----------------------------------------------------------------------===//
+
+std::pair<ExplodedNode*, const GRState *>
+CFRefCount::HandleAutoreleaseCounts(const GRState * state, GenericNodeBuilder Bd,
+                                    ExplodedNode* Pred,
+                                    GRExprEngine &Eng,
+                                    SymbolRef Sym, RefVal V, bool &stop) {
+
+  unsigned ACnt = V.getAutoreleaseCount();
+  stop = false;
+
+  // No autorelease counts?  Nothing to be done.
+  if (!ACnt)
+    return std::make_pair(Pred, state);
+
+  assert(!isGCEnabled() && "Autorelease counts in GC mode?");
+  unsigned Cnt = V.getCount();
+
+  // FIXME: Handle sending 'autorelease' to already released object.
+
+  if (V.getKind() == RefVal::ReturnedOwned)
+    ++Cnt;
+
+  if (ACnt <= Cnt) {
+    if (ACnt == Cnt) {
+      V.clearCounts();
+      if (V.getKind() == RefVal::ReturnedOwned)
+        V = V ^ RefVal::ReturnedNotOwned;
+      else
+        V = V ^ RefVal::NotOwned;
+    }
+    else {
+      V.setCount(Cnt - ACnt);
+      V.setAutoreleaseCount(0);
+    }
+    state = state->set<RefBindings>(Sym, V);
+    ExplodedNode *N = Bd.MakeNode(state, Pred);
+    stop = (N == 0);
+    return std::make_pair(N, state);
+  }
+
+  // Woah!  More autorelease counts then retain counts left.
+  // Emit hard error.
+  stop = true;
+  V = V ^ RefVal::ErrorOverAutorelease;
+  state = state->set<RefBindings>(Sym, V);
+
+  if (ExplodedNode *N = Bd.MakeNode(state, Pred)) {
+    N->markAsSink();
+
+    std::string sbuf;
+    llvm::raw_string_ostream os(sbuf);
+    os << "Object over-autoreleased: object was sent -autorelease";
+    if (V.getAutoreleaseCount() > 1)
+      os << V.getAutoreleaseCount() << " times";
+    os << " but the object has ";
+    if (V.getCount() == 0)
+      os << "zero (locally visible)";
+    else
+      os << "+" << V.getCount();
+    os << " retain counts";
+
+    CFRefReport *report =
+      new CFRefReport(*static_cast<CFRefBug*>(overAutorelease),
+                      *this, N, Sym, os.str());
+    BR->EmitReport(report);
+  }
+
+  return std::make_pair((ExplodedNode*)0, state);
+}
+
+const GRState *
+CFRefCount::HandleSymbolDeath(const GRState * state, SymbolRef sid, RefVal V,
+                              llvm::SmallVectorImpl<SymbolRef> &Leaked) {
+
+  bool hasLeak = V.isOwned() ||
+  ((V.isNotOwned() || V.isReturnedOwned()) && V.getCount() > 0);
+
+  if (!hasLeak)
+    return state->remove<RefBindings>(sid);
+
+  Leaked.push_back(sid);
+  return state->set<RefBindings>(sid, V ^ RefVal::ErrorLeak);
+}
+
+ExplodedNode*
+CFRefCount::ProcessLeaks(const GRState * state,
+                         llvm::SmallVectorImpl<SymbolRef> &Leaked,
+                         GenericNodeBuilder &Builder,
+                         GRExprEngine& Eng,
+                         ExplodedNode *Pred) {
+
+  if (Leaked.empty())
+    return Pred;
+
+  // Generate an intermediate node representing the leak point.
+  ExplodedNode *N = Builder.MakeNode(state, Pred);
+
+  if (N) {
+    for (llvm::SmallVectorImpl<SymbolRef>::iterator
+         I = Leaked.begin(), E = Leaked.end(); I != E; ++I) {
+
+      CFRefBug *BT = static_cast<CFRefBug*>(Pred ? leakWithinFunction
+                                                 : leakAtReturn);
+      assert(BT && "BugType not initialized.");
+      CFRefLeakReport* report = new CFRefLeakReport(*BT, *this, N, *I, Eng);
+      BR->EmitReport(report);
+    }
+  }
+
+  return N;
+}
+
+void CFRefCount::EvalEndPath(GRExprEngine& Eng,
+                             GREndPathNodeBuilder& Builder) {
+
+  const GRState *state = Builder.getState();
+  GenericNodeBuilder Bd(Builder);
+  RefBindings B = state->get<RefBindings>();
+  ExplodedNode *Pred = 0;
+
+  for (RefBindings::iterator I = B.begin(), E = B.end(); I != E; ++I) {
+    bool stop = false;
+    llvm::tie(Pred, state) = HandleAutoreleaseCounts(state, Bd, Pred, Eng,
+                                                     (*I).first,
+                                                     (*I).second, stop);
+
+    if (stop)
+      return;
+  }
+
+  B = state->get<RefBindings>();
+  llvm::SmallVector<SymbolRef, 10> Leaked;
+
+  for (RefBindings::iterator I = B.begin(), E = B.end(); I != E; ++I)
+    state = HandleSymbolDeath(state, (*I).first, (*I).second, Leaked);
+
+  ProcessLeaks(state, Leaked, Bd, Eng, Pred);
+}
+
+void CFRefCount::EvalDeadSymbols(ExplodedNodeSet& Dst,
+                                 GRExprEngine& Eng,
+                                 GRStmtNodeBuilder& Builder,
+                                 ExplodedNode* Pred,
+                                 Stmt* S,
+                                 const GRState* state,
+                                 SymbolReaper& SymReaper) {
+
+  RefBindings B = state->get<RefBindings>();
+
+  // Update counts from autorelease pools
+  for (SymbolReaper::dead_iterator I = SymReaper.dead_begin(),
+       E = SymReaper.dead_end(); I != E; ++I) {
+    SymbolRef Sym = *I;
+    if (const RefVal* T = B.lookup(Sym)){
+      // Use the symbol as the tag.
+      // FIXME: This might not be as unique as we would like.
+      GenericNodeBuilder Bd(Builder, S, Sym);
+      bool stop = false;
+      llvm::tie(Pred, state) = HandleAutoreleaseCounts(state, Bd, Pred, Eng,
+                                                       Sym, *T, stop);
+      if (stop)
+        return;
+    }
+  }
+
+  B = state->get<RefBindings>();
+  llvm::SmallVector<SymbolRef, 10> Leaked;
+
+  for (SymbolReaper::dead_iterator I = SymReaper.dead_begin(),
+       E = SymReaper.dead_end(); I != E; ++I) {
+      if (const RefVal* T = B.lookup(*I))
+        state = HandleSymbolDeath(state, *I, *T, Leaked);
+  }
+
+  static unsigned LeakPPTag = 0;
+  {
+    GenericNodeBuilder Bd(Builder, S, &LeakPPTag);
+    Pred = ProcessLeaks(state, Leaked, Bd, Eng, Pred);
+  }
+
+  // Did we cache out?
+  if (!Pred)
+    return;
+
+  // Now generate a new node that nukes the old bindings.
+  RefBindings::Factory& F = state->get_context<RefBindings>();
+
+  for (SymbolReaper::dead_iterator I = SymReaper.dead_begin(),
+       E = SymReaper.dead_end(); I!=E; ++I) B = F.Remove(B, *I);
+
+  state = state->set<RefBindings>(B);
+  Builder.MakeNode(Dst, S, Pred, state);
+}
+
+void CFRefCount::ProcessNonLeakError(ExplodedNodeSet& Dst,
+                                     GRStmtNodeBuilder& Builder,
+                                     Expr* NodeExpr, Expr* ErrorExpr,
+                                     ExplodedNode* Pred,
+                                     const GRState* St,
+                                     RefVal::Kind hasErr, SymbolRef Sym) {
+  Builder.BuildSinks = true;
+  ExplodedNode *N  = Builder.MakeNode(Dst, NodeExpr, Pred, St);
+
+  if (!N)
+    return;
+
+  CFRefBug *BT = 0;
+
+  switch (hasErr) {
+    default:
+      assert(false && "Unhandled error.");
+      return;
+    case RefVal::ErrorUseAfterRelease:
+      BT = static_cast<CFRefBug*>(useAfterRelease);
+      break;
+    case RefVal::ErrorReleaseNotOwned:
+      BT = static_cast<CFRefBug*>(releaseNotOwned);
+      break;
+    case RefVal::ErrorDeallocGC:
+      BT = static_cast<CFRefBug*>(deallocGC);
+      break;
+    case RefVal::ErrorDeallocNotOwned:
+      BT = static_cast<CFRefBug*>(deallocNotOwned);
+      break;
+  }
+
+  CFRefReport *report = new CFRefReport(*BT, *this, N, Sym);
+  report->addRange(ErrorExpr->getSourceRange());
+  BR->EmitReport(report);
+}
+
+//===----------------------------------------------------------------------===//
+// Pieces of the retain/release checker implemented using a CheckerVisitor.
+// More pieces of the retain/release checker will be migrated to this interface
+// (ideally, all of it some day).
+//===----------------------------------------------------------------------===//
+
+namespace {
+class RetainReleaseChecker
+  : public CheckerVisitor<RetainReleaseChecker> {
+  CFRefCount *TF;
+public:
+    RetainReleaseChecker(CFRefCount *tf) : TF(tf) {}
+    static void* getTag() { static int x = 0; return &x; }
+    
+    void PostVisitBlockExpr(CheckerContext &C, const BlockExpr *BE);
+};
+} // end anonymous namespace
+
+
+void RetainReleaseChecker::PostVisitBlockExpr(CheckerContext &C,
+                                              const BlockExpr *BE) {
+  
+  // Scan the BlockDecRefExprs for any object the retain/release checker
+  // may be tracking.  
+  if (!BE->hasBlockDeclRefExprs())
+    return;
+  
+  const GRState *state = C.getState();
+  const BlockDataRegion *R =
+    cast<BlockDataRegion>(state->getSVal(BE).getAsRegion());
+  
+  BlockDataRegion::referenced_vars_iterator I = R->referenced_vars_begin(),
+                                            E = R->referenced_vars_end();
+  
+  if (I == E)
+    return;
+  
+  // FIXME: For now we invalidate the tracking of all symbols passed to blocks
+  // via captured variables, even though captured variables result in a copy
+  // and in implicit increment/decrement of a retain count.
+  llvm::SmallVector<const MemRegion*, 10> Regions;
+  const LocationContext *LC = C.getPredecessor()->getLocationContext();
+  MemRegionManager &MemMgr = C.getValueManager().getRegionManager();
+  
+  for ( ; I != E; ++I) {
+    const VarRegion *VR = *I;
+    if (VR->getSuperRegion() == R) {
+      VR = MemMgr.getVarRegion(VR->getDecl(), LC);
+    }
+    Regions.push_back(VR);
+  }
+  
+  state =
+    state->scanReachableSymbols<StopTrackingCallback>(Regions.data(),
+                                    Regions.data() + Regions.size()).getState();
+  C.addTransition(state);
+}
+
+//===----------------------------------------------------------------------===//
+// Transfer function creation for external clients.
+//===----------------------------------------------------------------------===//
+
+void CFRefCount::RegisterChecks(GRExprEngine& Eng) {
+  BugReporter &BR = Eng.getBugReporter();
+  
+  useAfterRelease = new UseAfterRelease(this);
+  BR.Register(useAfterRelease);
+  
+  releaseNotOwned = new BadRelease(this);
+  BR.Register(releaseNotOwned);
+  
+  deallocGC = new DeallocGC(this);
+  BR.Register(deallocGC);
+  
+  deallocNotOwned = new DeallocNotOwned(this);
+  BR.Register(deallocNotOwned);
+  
+  overAutorelease = new OverAutorelease(this);
+  BR.Register(overAutorelease);
+  
+  returnNotOwnedForOwned = new ReturnedNotOwnedForOwned(this);
+  BR.Register(returnNotOwnedForOwned);
+  
+  // First register "return" leaks.
+  const char* name = 0;
+  
+  if (isGCEnabled())
+    name = "Leak of returned object when using garbage collection";
+  else if (getLangOptions().getGCMode() == LangOptions::HybridGC)
+    name = "Leak of returned object when not using garbage collection (GC) in "
+    "dual GC/non-GC code";
+  else {
+    assert(getLangOptions().getGCMode() == LangOptions::NonGC);
+    name = "Leak of returned object";
+  }
+  
+  // Leaks should not be reported if they are post-dominated by a sink.
+  leakAtReturn = new LeakAtReturn(this, name);
+  leakAtReturn->setSuppressOnSink(true);
+  BR.Register(leakAtReturn);
+  
+  // Second, register leaks within a function/method.
+  if (isGCEnabled())
+    name = "Leak of object when using garbage collection";
+  else if (getLangOptions().getGCMode() == LangOptions::HybridGC)
+    name = "Leak of object when not using garbage collection (GC) in "
+    "dual GC/non-GC code";
+  else {
+    assert(getLangOptions().getGCMode() == LangOptions::NonGC);
+    name = "Leak";
+  }
+  
+  // Leaks should not be reported if they are post-dominated by sinks.
+  leakWithinFunction = new LeakWithinFunction(this, name);
+  leakWithinFunction->setSuppressOnSink(true);
+  BR.Register(leakWithinFunction);
+  
+  // Save the reference to the BugReporter.
+  this->BR = &BR;
+  
+  // Register the RetainReleaseChecker with the GRExprEngine object.
+  // Functionality in CFRefCount will be migrated to RetainReleaseChecker
+  // over time.
+  Eng.registerCheck(new RetainReleaseChecker(this));
+}
+
+GRTransferFuncs* clang::MakeCFRefCountTF(ASTContext& Ctx, bool GCEnabled,
+                                         const LangOptions& lopts) {
+  return new CFRefCount(Ctx, GCEnabled, lopts);
+}
diff --git a/lib/Checker/CMakeLists.txt b/lib/Checker/CMakeLists.txt
new file mode 100644
index 0000000..82e93a4
--- /dev/null
+++ b/lib/Checker/CMakeLists.txt
@@ -0,0 +1,71 @@
+set(LLVM_NO_RTTI 1)
+
+add_clang_library(clangChecker
+  AdjustedReturnValueChecker.cpp
+  AggExprVisitor.cpp
+  ArrayBoundChecker.cpp
+  AttrNonNullChecker.cpp
+  BasicConstraintManager.cpp
+  BasicObjCFoundationChecks.cpp
+  BasicStore.cpp
+  BasicValueFactory.cpp
+  BugReporter.cpp
+  BugReporterVisitors.cpp
+  BuiltinFunctionChecker.cpp
+  CallAndMessageChecker.cpp
+  CallInliner.cpp
+  CastToStructChecker.cpp
+  CFRefCount.cpp
+  CheckDeadStores.cpp
+  Checker.cpp
+  CheckObjCDealloc.cpp
+  CheckObjCInstMethSignature.cpp
+  CheckSecuritySyntaxOnly.cpp
+  CheckSizeofPointer.cpp
+  CocoaConventions.cpp
+  DereferenceChecker.cpp
+  DivZeroChecker.cpp
+  Environment.cpp
+  ExplodedGraph.cpp
+  FixedAddressChecker.cpp
+  FlatStore.cpp
+  GRBlockCounter.cpp
+  GRCoreEngine.cpp
+  GRCXXExprEngine.cpp
+  GRExprEngine.cpp
+  GRExprEngineExperimentalChecks.cpp
+  GRState.cpp
+  LLVMConventionsChecker.cpp
+  MacOSXAPIChecker.cpp
+  MallocChecker.cpp
+  ManagerRegistry.cpp
+  MemRegion.cpp
+  NoReturnFunctionChecker.cpp
+  NSAutoreleasePoolChecker.cpp
+  NSErrorChecker.cpp
+  ObjCUnusedIVarsChecker.cpp
+  OSAtomicChecker.cpp
+  PathDiagnostic.cpp
+  PointerArithChecker.cpp
+  PointerSubChecker.cpp
+  PthreadLockChecker.cpp
+  RangeConstraintManager.cpp
+  RegionStore.cpp
+  ReturnPointerRangeChecker.cpp
+  ReturnStackAddressChecker.cpp
+  ReturnUndefChecker.cpp
+  SimpleConstraintManager.cpp
+  SimpleSValuator.cpp
+  Store.cpp
+  SVals.cpp
+  SValuator.cpp
+  SymbolManager.cpp
+  UndefBranchChecker.cpp
+  UndefCapturedBlockVarChecker.cpp
+  UndefinedArraySubscriptChecker.cpp
+  UndefinedAssignmentChecker.cpp
+  UndefResultChecker.cpp
+  UnixAPIChecker.cpp
+  ValueManager.cpp
+  VLASizeChecker.cpp
+  )
diff --git a/lib/Checker/CallAndMessageChecker.cpp b/lib/Checker/CallAndMessageChecker.cpp
new file mode 100644
index 0000000..c619d75
--- /dev/null
+++ b/lib/Checker/CallAndMessageChecker.cpp
@@ -0,0 +1,346 @@
+//===--- CallAndMessageChecker.cpp ------------------------------*- C++ -*--==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This defines CallAndMessageChecker, a builtin checker that checks for various
+// errors of call and objc message expressions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "GRExprEngineInternalChecks.h"
+#include "clang/AST/ParentMap.h"
+#include "clang/Basic/TargetInfo.h"
+#include "clang/Checker/BugReporter/BugType.h"
+#include "clang/Checker/PathSensitive/CheckerVisitor.h"
+
+using namespace clang;
+
+namespace {
+class CallAndMessageChecker
+  : public CheckerVisitor<CallAndMessageChecker> {
+  BugType *BT_call_null;
+  BugType *BT_call_undef;
+  BugType *BT_call_arg;
+  BugType *BT_msg_undef;
+  BugType *BT_msg_arg;
+  BugType *BT_msg_ret;
+public:
+  CallAndMessageChecker() :
+    BT_call_null(0), BT_call_undef(0), BT_call_arg(0),
+    BT_msg_undef(0), BT_msg_arg(0), BT_msg_ret(0) {}
+
+  static void *getTag() {
+    static int x = 0;
+    return &x;
+  }
+
+  void PreVisitCallExpr(CheckerContext &C, const CallExpr *CE);
+  void PreVisitObjCMessageExpr(CheckerContext &C, const ObjCMessageExpr *ME);
+  bool EvalNilReceiver(CheckerContext &C, const ObjCMessageExpr *ME);
+
+private:
+  bool PreVisitProcessArg(CheckerContext &C, const Expr *Ex,
+                          const char *BT_desc, BugType *&BT);
+
+  void EmitBadCall(BugType *BT, CheckerContext &C, const CallExpr *CE);
+  void EmitNilReceiverBug(CheckerContext &C, const ObjCMessageExpr *ME,
+                          ExplodedNode *N);
+
+  void HandleNilReceiver(CheckerContext &C, const GRState *state,
+                         const ObjCMessageExpr *ME);
+
+  void LazyInit_BT(const char *desc, BugType *&BT) {
+    if (!BT)
+      BT = new BuiltinBug(desc);
+  }
+};
+} // end anonymous namespace
+
+void clang::RegisterCallAndMessageChecker(GRExprEngine &Eng) {
+  Eng.registerCheck(new CallAndMessageChecker());
+}
+
+void CallAndMessageChecker::EmitBadCall(BugType *BT, CheckerContext &C,
+                                        const CallExpr *CE) {
+  ExplodedNode *N = C.GenerateSink();
+  if (!N)
+    return;
+
+  EnhancedBugReport *R = new EnhancedBugReport(*BT, BT->getName(), N);
+  R->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue,
+                       bugreporter::GetCalleeExpr(N));
+  C.EmitReport(R);
+}
+
+bool CallAndMessageChecker::PreVisitProcessArg(CheckerContext &C,
+                                               const Expr *Ex,
+                                               const char *BT_desc,
+                                               BugType *&BT) {
+
+  const SVal &V = C.getState()->getSVal(Ex);
+
+  if (V.isUndef()) {
+    if (ExplodedNode *N = C.GenerateSink()) {
+      LazyInit_BT(BT_desc, BT);
+
+      // Generate a report for this bug.
+      EnhancedBugReport *R = new EnhancedBugReport(*BT, BT->getName(), N);
+      R->addRange(Ex->getSourceRange());
+      R->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue, Ex);
+      C.EmitReport(R);
+    }
+    return true;
+  }
+
+  if (const nonloc::LazyCompoundVal *LV =
+        dyn_cast<nonloc::LazyCompoundVal>(&V)) {
+
+    class FindUninitializedField {
+    public:
+      llvm::SmallVector<const FieldDecl *, 10> FieldChain;
+    private:
+      ASTContext &C;
+      StoreManager &StoreMgr;
+      MemRegionManager &MrMgr;
+      Store store;
+    public:
+      FindUninitializedField(ASTContext &c, StoreManager &storeMgr,
+                             MemRegionManager &mrMgr, Store s)
+      : C(c), StoreMgr(storeMgr), MrMgr(mrMgr), store(s) {}
+
+      bool Find(const TypedRegion *R) {
+        QualType T = R->getValueType(C);
+        if (const RecordType *RT = T->getAsStructureType()) {
+          const RecordDecl *RD = RT->getDecl()->getDefinition();
+          assert(RD && "Referred record has no definition");
+          for (RecordDecl::field_iterator I =
+               RD->field_begin(), E = RD->field_end(); I!=E; ++I) {
+            const FieldRegion *FR = MrMgr.getFieldRegion(*I, R);
+            FieldChain.push_back(*I);
+            T = (*I)->getType();
+            if (T->getAsStructureType()) {
+              if (Find(FR))
+                return true;
+            }
+            else {
+              const SVal &V = StoreMgr.Retrieve(store, loc::MemRegionVal(FR));
+              if (V.isUndef())
+                return true;
+            }
+            FieldChain.pop_back();
+          }
+        }
+
+        return false;
+      }
+    };
+
+    const LazyCompoundValData *D = LV->getCVData();
+    FindUninitializedField F(C.getASTContext(),
+                             C.getState()->getStateManager().getStoreManager(),
+                             C.getValueManager().getRegionManager(),
+                             D->getStore());
+
+    if (F.Find(D->getRegion())) {
+      if (ExplodedNode *N = C.GenerateSink()) {
+        LazyInit_BT(BT_desc, BT);
+        llvm::SmallString<512> Str;
+        llvm::raw_svector_ostream os(Str);
+        os << "Passed-by-value struct argument contains uninitialized data";
+
+        if (F.FieldChain.size() == 1)
+          os << " (e.g., field: '" << F.FieldChain[0] << "')";
+        else {
+          os << " (e.g., via the field chain: '";
+          bool first = true;
+          for (llvm::SmallVectorImpl<const FieldDecl *>::iterator
+               DI = F.FieldChain.begin(), DE = F.FieldChain.end(); DI!=DE;++DI){
+            if (first)
+              first = false;
+            else
+              os << '.';
+            os << *DI;
+          }
+          os << "')";
+        }
+
+        // Generate a report for this bug.
+        EnhancedBugReport *R = new EnhancedBugReport(*BT, os.str(), N);
+        R->addRange(Ex->getSourceRange());
+
+        // FIXME: enhance track back for uninitialized value for arbitrary
+        // memregions
+        C.EmitReport(R);
+      }
+      return true;
+    }
+  }
+
+  return false;
+}
+
+void CallAndMessageChecker::PreVisitCallExpr(CheckerContext &C,
+                                             const CallExpr *CE){
+
+  const Expr *Callee = CE->getCallee()->IgnoreParens();
+  SVal L = C.getState()->getSVal(Callee);
+
+  if (L.isUndef()) {
+    if (!BT_call_undef)
+      BT_call_undef =
+        new BuiltinBug("Called function pointer is an undefined pointer value");
+    EmitBadCall(BT_call_undef, C, CE);
+    return;
+  }
+
+  if (isa<loc::ConcreteInt>(L)) {
+    if (!BT_call_null)
+      BT_call_null =
+        new BuiltinBug("Called function pointer is null (null dereference)");
+    EmitBadCall(BT_call_null, C, CE);
+  }
+
+  for (CallExpr::const_arg_iterator I = CE->arg_begin(), E = CE->arg_end();
+       I != E; ++I)
+    if (PreVisitProcessArg(C, *I,
+                           "Pass-by-value argument in function call is"
+                           " undefined", BT_call_arg))
+      return;
+}
+
+void CallAndMessageChecker::PreVisitObjCMessageExpr(CheckerContext &C,
+                                                    const ObjCMessageExpr *ME) {
+
+  const GRState *state = C.getState();
+
+  // FIXME: Handle 'super'?
+  if (const Expr *receiver = ME->getInstanceReceiver())
+    if (state->getSVal(receiver).isUndef()) {
+      if (ExplodedNode *N = C.GenerateSink()) {
+        if (!BT_msg_undef)
+          BT_msg_undef =
+            new BuiltinBug("Receiver in message expression is a garbage value");
+        EnhancedBugReport *R =
+          new EnhancedBugReport(*BT_msg_undef, BT_msg_undef->getName(), N);
+        R->addRange(receiver->getSourceRange());
+        R->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue,
+                             receiver);
+        C.EmitReport(R);
+      }
+      return;
+    }
+
+  // Check for any arguments that are uninitialized/undefined.
+  for (ObjCMessageExpr::const_arg_iterator I = ME->arg_begin(),
+         E = ME->arg_end(); I != E; ++I)
+    if (PreVisitProcessArg(C, *I,
+                           "Pass-by-value argument in message expression "
+                           "is undefined", BT_msg_arg))
+        return;
+}
+
+bool CallAndMessageChecker::EvalNilReceiver(CheckerContext &C,
+                                            const ObjCMessageExpr *ME) {
+  HandleNilReceiver(C, C.getState(), ME);
+  return true; // Nil receiver is not handled elsewhere.
+}
+
+void CallAndMessageChecker::EmitNilReceiverBug(CheckerContext &C,
+                                               const ObjCMessageExpr *ME,
+                                               ExplodedNode *N) {
+
+  if (!BT_msg_ret)
+    BT_msg_ret =
+      new BuiltinBug("Receiver in message expression is "
+                     "'nil' and returns a garbage value");
+
+  llvm::SmallString<200> buf;
+  llvm::raw_svector_ostream os(buf);
+  os << "The receiver of message '" << ME->getSelector().getAsString()
+     << "' is nil and returns a value of type '"
+     << ME->getType().getAsString() << "' that will be garbage";
+
+  EnhancedBugReport *report = new EnhancedBugReport(*BT_msg_ret, os.str(), N);
+  if (const Expr *receiver = ME->getInstanceReceiver()) {
+    report->addRange(receiver->getSourceRange());
+    report->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue,
+                              receiver);
+  }
+  C.EmitReport(report);
+}
+
+static bool SupportsNilWithFloatRet(const llvm::Triple &triple) {
+  return triple.getVendor() == llvm::Triple::Apple &&
+         triple.getDarwinMajorNumber() >= 9;
+}
+
+void CallAndMessageChecker::HandleNilReceiver(CheckerContext &C,
+                                              const GRState *state,
+                                              const ObjCMessageExpr *ME) {
+
+  // Check the return type of the message expression.  A message to nil will
+  // return different values depending on the return type and the architecture.
+  QualType RetTy = ME->getType();
+
+  ASTContext &Ctx = C.getASTContext();
+  CanQualType CanRetTy = Ctx.getCanonicalType(RetTy);
+
+  if (CanRetTy->isStructureOrClassType()) {
+    // FIXME: At some point we shouldn't rely on isConsumedExpr(), but instead
+    // have the "use of undefined value" be smarter about where the
+    // undefined value came from.
+    if (C.getPredecessor()->getParentMap().isConsumedExpr(ME)) {
+      if (ExplodedNode* N = C.GenerateSink(state))
+        EmitNilReceiverBug(C, ME, N);
+      return;
+    }
+
+    // The result is not consumed by a surrounding expression.  Just propagate
+    // the current state.
+    C.addTransition(state);
+    return;
+  }
+
+  // Other cases: check if the return type is smaller than void*.
+  if (CanRetTy != Ctx.VoidTy &&
+      C.getPredecessor()->getParentMap().isConsumedExpr(ME)) {
+    // Compute: sizeof(void *) and sizeof(return type)
+    const uint64_t voidPtrSize = Ctx.getTypeSize(Ctx.VoidPtrTy);
+    const uint64_t returnTypeSize = Ctx.getTypeSize(CanRetTy);
+
+    if (voidPtrSize < returnTypeSize &&
+        !(SupportsNilWithFloatRet(Ctx.Target.getTriple()) &&
+          (Ctx.FloatTy == CanRetTy ||
+           Ctx.DoubleTy == CanRetTy ||
+           Ctx.LongDoubleTy == CanRetTy ||
+           Ctx.LongLongTy == CanRetTy))) {
+      if (ExplodedNode* N = C.GenerateSink(state))
+        EmitNilReceiverBug(C, ME, N);
+      return;
+    }
+
+    // Handle the safe cases where the return value is 0 if the
+    // receiver is nil.
+    //
+    // FIXME: For now take the conservative approach that we only
+    // return null values if we *know* that the receiver is nil.
+    // This is because we can have surprises like:
+    //
+    //   ... = [[NSScreens screens] objectAtIndex:0];
+    //
+    // What can happen is that [... screens] could return nil, but
+    // it most likely isn't nil.  We should assume the semantics
+    // of this case unless we have *a lot* more knowledge.
+    //
+    SVal V = C.getValueManager().makeZeroVal(ME->getType());
+    C.GenerateNode(state->BindExpr(ME, V));
+    return;
+  }
+
+  C.addTransition(state);
+}
diff --git a/lib/Checker/CallInliner.cpp b/lib/Checker/CallInliner.cpp
new file mode 100644
index 0000000..88e1a05
--- /dev/null
+++ b/lib/Checker/CallInliner.cpp
@@ -0,0 +1,54 @@
+//===--- CallInliner.cpp - Transfer function that inlines callee ----------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements the callee inlining transfer function.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Checker/PathSensitive/CheckerVisitor.h"
+#include "clang/Checker/PathSensitive/GRState.h"
+#include "clang/Checker/Checkers/LocalCheckers.h"
+
+using namespace clang;
+
+namespace {
+class CallInliner : public Checker {
+public:
+  static void *getTag() {
+    static int x;
+    return &x;
+  }
+
+  virtual bool EvalCallExpr(CheckerContext &C, const CallExpr *CE);
+};
+}
+
+void clang::RegisterCallInliner(GRExprEngine &Eng) {
+  Eng.registerCheck(new CallInliner());
+}
+
+bool CallInliner::EvalCallExpr(CheckerContext &C, const CallExpr *CE) {
+  const GRState *state = C.getState();
+  const Expr *Callee = CE->getCallee();
+  SVal L = state->getSVal(Callee);
+  
+  const FunctionDecl *FD = L.getAsFunctionDecl();
+  if (!FD)
+    return false;
+
+  if (!FD->getBody(FD))
+    return false;
+
+  // Now we have the definition of the callee, create a CallEnter node.
+  CallEnter Loc(CE, FD, C.getPredecessor()->getLocationContext());
+  C.addTransition(state, Loc);
+
+  return true;
+}
+
diff --git a/lib/Checker/CastToStructChecker.cpp b/lib/Checker/CastToStructChecker.cpp
new file mode 100644
index 0000000..eeaed97
--- /dev/null
+++ b/lib/Checker/CastToStructChecker.cpp
@@ -0,0 +1,78 @@
+//=== CastToStructChecker.cpp - Fixed address usage checker ----*- C++ -*--===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This files defines CastToStructChecker, a builtin checker that checks for
+// cast from non-struct pointer to struct pointer.
+// This check corresponds to CWE-588.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Checker/BugReporter/BugType.h"
+#include "clang/Checker/PathSensitive/CheckerVisitor.h"
+#include "GRExprEngineInternalChecks.h"
+
+using namespace clang;
+
+namespace {
+class CastToStructChecker 
+  : public CheckerVisitor<CastToStructChecker> {
+  BuiltinBug *BT;
+public:
+  CastToStructChecker() : BT(0) {}
+  static void *getTag();
+  void PreVisitCastExpr(CheckerContext &C, const CastExpr *B);
+};
+}
+
+void *CastToStructChecker::getTag() {
+  static int x;
+  return &x;
+}
+
+void CastToStructChecker::PreVisitCastExpr(CheckerContext &C,
+                                           const CastExpr *CE) {
+  const Expr *E = CE->getSubExpr();
+  ASTContext &Ctx = C.getASTContext();
+  QualType OrigTy = Ctx.getCanonicalType(E->getType());
+  QualType ToTy = Ctx.getCanonicalType(CE->getType());
+
+  PointerType *OrigPTy = dyn_cast<PointerType>(OrigTy.getTypePtr());
+  PointerType *ToPTy = dyn_cast<PointerType>(ToTy.getTypePtr());
+
+  if (!ToPTy || !OrigPTy)
+    return;
+
+  QualType OrigPointeeTy = OrigPTy->getPointeeType();
+  QualType ToPointeeTy = ToPTy->getPointeeType();
+
+  if (!ToPointeeTy->isStructureOrClassType())
+    return;
+
+  // We allow cast from void*.
+  if (OrigPointeeTy->isVoidType())
+    return;
+
+  // Now the cast-to-type is struct pointer, the original type is not void*.
+  if (!OrigPointeeTy->isRecordType()) {
+    if (ExplodedNode *N = C.GenerateNode()) {
+      if (!BT)
+        BT = new BuiltinBug("Cast from non-struct type to struct type",
+                            "Casting a non-structure type to a structure type "
+                            "and accessing a field can lead to memory access "
+                            "errors or data corruption.");
+      RangedBugReport *R = new RangedBugReport(*BT,BT->getDescription(), N);
+      R->addRange(CE->getSourceRange());
+      C.EmitReport(R);
+    }
+  }
+}
+
+void clang::RegisterCastToStructChecker(GRExprEngine &Eng) {
+  Eng.registerCheck(new CastToStructChecker());
+}
diff --git a/lib/Checker/CheckDeadStores.cpp b/lib/Checker/CheckDeadStores.cpp
new file mode 100644
index 0000000..d6ea187
--- /dev/null
+++ b/lib/Checker/CheckDeadStores.cpp
@@ -0,0 +1,289 @@
+//==- DeadStores.cpp - Check for stores to dead variables --------*- C++ -*-==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines a DeadStores, a flow-sensitive checker that looks for
+//  stores to variables that are no longer live.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Checker/Checkers/LocalCheckers.h"
+#include "clang/Analysis/Analyses/LiveVariables.h"
+#include "clang/Analysis/Visitors/CFGRecStmtVisitor.h"
+#include "clang/Checker/BugReporter/BugReporter.h"
+#include "clang/Checker/PathSensitive/GRExprEngine.h"
+#include "clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/ParentMap.h"
+#include "llvm/ADT/SmallPtrSet.h"
+
+using namespace clang;
+
+namespace {
+
+class DeadStoreObs : public LiveVariables::ObserverTy {
+  ASTContext &Ctx;
+  BugReporter& BR;
+  ParentMap& Parents;
+  llvm::SmallPtrSet<VarDecl*, 20> Escaped;
+
+  enum DeadStoreKind { Standard, Enclosing, DeadIncrement, DeadInit };
+
+public:
+  DeadStoreObs(ASTContext &ctx, BugReporter& br, ParentMap& parents,
+               llvm::SmallPtrSet<VarDecl*, 20> &escaped)
+    : Ctx(ctx), BR(br), Parents(parents), Escaped(escaped) {}
+
+  virtual ~DeadStoreObs() {}
+
+  void Report(VarDecl* V, DeadStoreKind dsk, SourceLocation L, SourceRange R) {
+    if (Escaped.count(V))
+      return;
+
+    std::string name = V->getNameAsString();
+
+    const char* BugType = 0;
+    std::string msg;
+
+    switch (dsk) {
+      default:
+        assert(false && "Impossible dead store type.");
+
+      case DeadInit:
+        BugType = "Dead initialization";
+        msg = "Value stored to '" + name +
+          "' during its initialization is never read";
+        break;
+
+      case DeadIncrement:
+        BugType = "Dead increment";
+      case Standard:
+        if (!BugType) BugType = "Dead assignment";
+        msg = "Value stored to '" + name + "' is never read";
+        break;
+
+      case Enclosing:
+        BugType = "Dead nested assignment";
+        msg = "Although the value stored to '" + name +
+          "' is used in the enclosing expression, the value is never actually"
+          " read from '" + name + "'";
+        break;
+    }
+
+    BR.EmitBasicReport(BugType, "Dead store", msg, L, R);
+  }
+
+  void CheckVarDecl(VarDecl* VD, Expr* Ex, Expr* Val,
+                    DeadStoreKind dsk,
+                    const LiveVariables::AnalysisDataTy& AD,
+                    const LiveVariables::ValTy& Live) {
+
+    if (!VD->hasLocalStorage())
+      return;
+    // Reference types confuse the dead stores checker.  Skip them
+    // for now.
+    if (VD->getType()->getAs<ReferenceType>())
+      return;
+
+    if (!Live(VD, AD) && 
+        !(VD->getAttr<UnusedAttr>() || VD->getAttr<BlocksAttr>()))
+      Report(VD, dsk, Ex->getSourceRange().getBegin(),
+             Val->getSourceRange());
+  }
+
+  void CheckDeclRef(DeclRefExpr* DR, Expr* Val, DeadStoreKind dsk,
+                    const LiveVariables::AnalysisDataTy& AD,
+                    const LiveVariables::ValTy& Live) {
+    if (VarDecl* VD = dyn_cast<VarDecl>(DR->getDecl()))
+      CheckVarDecl(VD, DR, Val, dsk, AD, Live);
+  }
+
+  bool isIncrement(VarDecl* VD, BinaryOperator* B) {
+    if (B->isCompoundAssignmentOp())
+      return true;
+
+    Expr* RHS = B->getRHS()->IgnoreParenCasts();
+    BinaryOperator* BRHS = dyn_cast<BinaryOperator>(RHS);
+
+    if (!BRHS)
+      return false;
+
+    DeclRefExpr *DR;
+
+    if ((DR = dyn_cast<DeclRefExpr>(BRHS->getLHS()->IgnoreParenCasts())))
+      if (DR->getDecl() == VD)
+        return true;
+
+    if ((DR = dyn_cast<DeclRefExpr>(BRHS->getRHS()->IgnoreParenCasts())))
+      if (DR->getDecl() == VD)
+        return true;
+
+    return false;
+  }
+
+  virtual void ObserveStmt(Stmt* S,
+                           const LiveVariables::AnalysisDataTy& AD,
+                           const LiveVariables::ValTy& Live) {
+
+    // Skip statements in macros.
+    if (S->getLocStart().isMacroID())
+      return;
+
+    if (BinaryOperator* B = dyn_cast<BinaryOperator>(S)) {
+      if (!B->isAssignmentOp()) return; // Skip non-assignments.
+
+      if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(B->getLHS()))
+        if (VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
+          // Special case: check for assigning null to a pointer.
+          //  This is a common form of defensive programming.
+          QualType T = VD->getType();
+          if (T->isPointerType() || T->isObjCObjectPointerType()) {
+            if (B->getRHS()->isNullPointerConstant(Ctx,
+                                              Expr::NPC_ValueDependentIsNull))
+              return;
+          }
+
+          Expr* RHS = B->getRHS()->IgnoreParenCasts();
+          // Special case: self-assignments.  These are often used to shut up
+          //  "unused variable" compiler warnings.
+          if (DeclRefExpr* RhsDR = dyn_cast<DeclRefExpr>(RHS))
+            if (VD == dyn_cast<VarDecl>(RhsDR->getDecl()))
+              return;
+
+          // Otherwise, issue a warning.
+          DeadStoreKind dsk = Parents.isConsumedExpr(B)
+                              ? Enclosing
+                              : (isIncrement(VD,B) ? DeadIncrement : Standard);
+
+          CheckVarDecl(VD, DR, B->getRHS(), dsk, AD, Live);
+        }
+    }
+    else if (UnaryOperator* U = dyn_cast<UnaryOperator>(S)) {
+      if (!U->isIncrementOp())
+        return;
+
+      // Handle: ++x within a subexpression.  The solution is not warn
+      //  about preincrements to dead variables when the preincrement occurs
+      //  as a subexpression.  This can lead to false negatives, e.g. "(++x);"
+      //  A generalized dead code checker should find such issues.
+      if (U->isPrefix() && Parents.isConsumedExpr(U))
+        return;
+
+      Expr *Ex = U->getSubExpr()->IgnoreParenCasts();
+
+      if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(Ex))
+        CheckDeclRef(DR, U, DeadIncrement, AD, Live);
+    }
+    else if (DeclStmt* DS = dyn_cast<DeclStmt>(S))
+      // Iterate through the decls.  Warn if any initializers are complex
+      // expressions that are not live (never used).
+      for (DeclStmt::decl_iterator DI=DS->decl_begin(), DE=DS->decl_end();
+           DI != DE; ++DI) {
+
+        VarDecl* V = dyn_cast<VarDecl>(*DI);
+
+        if (!V)
+          continue;
+          
+        if (V->hasLocalStorage()) {          
+          // Reference types confuse the dead stores checker.  Skip them
+          // for now.
+          if (V->getType()->getAs<ReferenceType>())
+            return;
+            
+          if (Expr* E = V->getInit()) {
+            // Don't warn on C++ objects (yet) until we can show that their
+            // constructors/destructors don't have side effects.
+            if (isa<CXXConstructExpr>(E))
+              return;
+
+            if (isa<CXXExprWithTemporaries>(E))
+              return;
+            
+            // A dead initialization is a variable that is dead after it
+            // is initialized.  We don't flag warnings for those variables
+            // marked 'unused'.
+            if (!Live(V, AD) && V->getAttr<UnusedAttr>() == 0) {
+              // Special case: check for initializations with constants.
+              //
+              //  e.g. : int x = 0;
+              //
+              // If x is EVER assigned a new value later, don't issue
+              // a warning.  This is because such initialization can be
+              // due to defensive programming.
+              if (E->isConstantInitializer(Ctx))
+                return;
+
+              if (DeclRefExpr *DRE=dyn_cast<DeclRefExpr>(E->IgnoreParenCasts()))
+                if (VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl())) {
+                  // Special case: check for initialization from constant
+                  //  variables.
+                  //
+                  //  e.g. extern const int MyConstant;
+                  //       int x = MyConstant;
+                  //
+                  if (VD->hasGlobalStorage() &&
+                      VD->getType().isConstQualified())
+                    return;
+                  // Special case: check for initialization from scalar
+                  //  parameters.  This is often a form of defensive
+                  //  programming.  Non-scalars are still an error since
+                  //  because it more likely represents an actual algorithmic
+                  //  bug.
+                  if (isa<ParmVarDecl>(VD) && VD->getType()->isScalarType())
+                    return;
+                }
+
+              Report(V, DeadInit, V->getLocation(), E->getSourceRange());
+            }
+          }
+        }
+      }
+  }
+};
+
+} // end anonymous namespace
+
+//===----------------------------------------------------------------------===//
+// Driver function to invoke the Dead-Stores checker on a CFG.
+//===----------------------------------------------------------------------===//
+
+namespace {
+class FindEscaped : public CFGRecStmtDeclVisitor<FindEscaped>{
+  CFG *cfg;
+public:
+  FindEscaped(CFG *c) : cfg(c) {}
+
+  CFG& getCFG() { return *cfg; }
+
+  llvm::SmallPtrSet<VarDecl*, 20> Escaped;
+
+  void VisitUnaryOperator(UnaryOperator* U) {
+    // Check for '&'.  Any VarDecl whose value has its address-taken we
+    // treat as escaped.
+    Expr* E = U->getSubExpr()->IgnoreParenCasts();
+    if (U->getOpcode() == UnaryOperator::AddrOf)
+      if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(E))
+        if (VarDecl* VD = dyn_cast<VarDecl>(DR->getDecl())) {
+          Escaped.insert(VD);
+          return;
+        }
+    Visit(E);
+  }
+};
+} // end anonymous namespace
+
+
+void clang::CheckDeadStores(CFG &cfg, LiveVariables &L, ParentMap &pmap, 
+                            BugReporter& BR) {
+  FindEscaped FS(&cfg);
+  FS.getCFG().VisitBlockStmts(FS);
+  DeadStoreObs A(BR.getContext(), BR, pmap, FS.Escaped);
+  L.runOnAllBlocks(cfg, &A);
+}
diff --git a/lib/Checker/CheckObjCDealloc.cpp b/lib/Checker/CheckObjCDealloc.cpp
new file mode 100644
index 0000000..c23be87
--- /dev/null
+++ b/lib/Checker/CheckObjCDealloc.cpp
@@ -0,0 +1,260 @@
+//==- CheckObjCDealloc.cpp - Check ObjC -dealloc implementation --*- C++ -*-==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines a CheckObjCDealloc, a checker that
+//  analyzes an Objective-C class's implementation to determine if it
+//  correctly implements -dealloc.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Checker/Checkers/LocalCheckers.h"
+#include "clang/Checker/BugReporter/PathDiagnostic.h"
+#include "clang/Checker/BugReporter/BugReporter.h"
+#include "clang/AST/ExprObjC.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/Basic/LangOptions.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace clang;
+
+static bool scan_dealloc(Stmt* S, Selector Dealloc) {
+
+  if (ObjCMessageExpr* ME = dyn_cast<ObjCMessageExpr>(S))
+    if (ME->getSelector() == Dealloc) {
+      switch (ME->getReceiverKind()) {
+      case ObjCMessageExpr::Instance: return false;
+      case ObjCMessageExpr::SuperInstance: return true;
+      case ObjCMessageExpr::Class: break;
+      case ObjCMessageExpr::SuperClass: break;
+      }
+    }
+
+  // Recurse to children.
+
+  for (Stmt::child_iterator I = S->child_begin(), E= S->child_end(); I!=E; ++I)
+    if (*I && scan_dealloc(*I, Dealloc))
+      return true;
+
+  return false;
+}
+
+static bool scan_ivar_release(Stmt* S, ObjCIvarDecl* ID,
+                              const ObjCPropertyDecl* PD,
+                              Selector Release,
+                              IdentifierInfo* SelfII,
+                              ASTContext& Ctx) {
+
+  // [mMyIvar release]
+  if (ObjCMessageExpr* ME = dyn_cast<ObjCMessageExpr>(S))
+    if (ME->getSelector() == Release)
+      if (ME->getInstanceReceiver())
+        if (Expr* Receiver = ME->getInstanceReceiver()->IgnoreParenCasts())
+          if (ObjCIvarRefExpr* E = dyn_cast<ObjCIvarRefExpr>(Receiver))
+            if (E->getDecl() == ID)
+              return true;
+
+  // [self setMyIvar:nil];
+  if (ObjCMessageExpr* ME = dyn_cast<ObjCMessageExpr>(S))
+    if (ME->getInstanceReceiver())
+      if (Expr* Receiver = ME->getInstanceReceiver()->IgnoreParenCasts())
+        if (DeclRefExpr* E = dyn_cast<DeclRefExpr>(Receiver))
+          if (E->getDecl()->getIdentifier() == SelfII)
+            if (ME->getMethodDecl() == PD->getSetterMethodDecl() &&
+                ME->getNumArgs() == 1 &&
+                ME->getArg(0)->isNullPointerConstant(Ctx, 
+                                              Expr::NPC_ValueDependentIsNull))
+              return true;
+
+  // self.myIvar = nil;
+  if (BinaryOperator* BO = dyn_cast<BinaryOperator>(S))
+    if (BO->isAssignmentOp())
+      if (ObjCPropertyRefExpr* PRE =
+         dyn_cast<ObjCPropertyRefExpr>(BO->getLHS()->IgnoreParenCasts()))
+          if (PRE->getProperty() == PD)
+            if (BO->getRHS()->isNullPointerConstant(Ctx, 
+                                            Expr::NPC_ValueDependentIsNull)) {
+              // This is only a 'release' if the property kind is not
+              // 'assign'.
+              return PD->getSetterKind() != ObjCPropertyDecl::Assign;;
+            }
+
+  // Recurse to children.
+  for (Stmt::child_iterator I = S->child_begin(), E= S->child_end(); I!=E; ++I)
+    if (*I && scan_ivar_release(*I, ID, PD, Release, SelfII, Ctx))
+      return true;
+
+  return false;
+}
+
+void clang::CheckObjCDealloc(const ObjCImplementationDecl* D,
+                             const LangOptions& LOpts, BugReporter& BR) {
+
+  assert (LOpts.getGCMode() != LangOptions::GCOnly);
+
+  ASTContext& Ctx = BR.getContext();
+  const ObjCInterfaceDecl* ID = D->getClassInterface();
+
+  // Does the class contain any ivars that are pointers (or id<...>)?
+  // If not, skip the check entirely.
+  // NOTE: This is motivated by PR 2517:
+  //        http://llvm.org/bugs/show_bug.cgi?id=2517
+
+  bool containsPointerIvar = false;
+
+  for (ObjCInterfaceDecl::ivar_iterator I=ID->ivar_begin(), E=ID->ivar_end();
+       I!=E; ++I) {
+
+    ObjCIvarDecl* ID = *I;
+    QualType T = ID->getType();
+
+    if (!T->isObjCObjectPointerType() ||
+        ID->getAttr<IBOutletAttr>()) // Skip IBOutlets.
+      continue;
+
+    containsPointerIvar = true;
+    break;
+  }
+
+  if (!containsPointerIvar)
+    return;
+
+  // Determine if the class subclasses NSObject.
+  IdentifierInfo* NSObjectII = &Ctx.Idents.get("NSObject");
+  IdentifierInfo* SenTestCaseII = &Ctx.Idents.get("SenTestCase");
+
+
+  for ( ; ID ; ID = ID->getSuperClass()) {
+    IdentifierInfo *II = ID->getIdentifier();
+
+    if (II == NSObjectII)
+      break;
+
+    // FIXME: For now, ignore classes that subclass SenTestCase, as these don't
+    // need to implement -dealloc.  They implement tear down in another way,
+    // which we should try and catch later.
+    //  http://llvm.org/bugs/show_bug.cgi?id=3187
+    if (II == SenTestCaseII)
+      return;
+  }
+
+  if (!ID)
+    return;
+
+  // Get the "dealloc" selector.
+  IdentifierInfo* II = &Ctx.Idents.get("dealloc");
+  Selector S = Ctx.Selectors.getSelector(0, &II);
+  ObjCMethodDecl* MD = 0;
+
+  // Scan the instance methods for "dealloc".
+  for (ObjCImplementationDecl::instmeth_iterator I = D->instmeth_begin(),
+       E = D->instmeth_end(); I!=E; ++I) {
+
+    if ((*I)->getSelector() == S) {
+      MD = *I;
+      break;
+    }
+  }
+
+  if (!MD) { // No dealloc found.
+
+    const char* name = LOpts.getGCMode() == LangOptions::NonGC
+                       ? "missing -dealloc"
+                       : "missing -dealloc (Hybrid MM, non-GC)";
+
+    std::string buf;
+    llvm::raw_string_ostream os(buf);
+    os << "Objective-C class '" << D << "' lacks a 'dealloc' instance method";
+
+    BR.EmitBasicReport(name, os.str(), D->getLocStart());
+    return;
+  }
+
+  // dealloc found.  Scan for missing [super dealloc].
+  if (MD->getBody() && !scan_dealloc(MD->getBody(), S)) {
+
+    const char* name = LOpts.getGCMode() == LangOptions::NonGC
+                       ? "missing [super dealloc]"
+                       : "missing [super dealloc] (Hybrid MM, non-GC)";
+
+    std::string buf;
+    llvm::raw_string_ostream os(buf);
+    os << "The 'dealloc' instance method in Objective-C class '" << D
+       << "' does not send a 'dealloc' message to its super class"
+           " (missing [super dealloc])";
+
+    BR.EmitBasicReport(name, os.str(), D->getLocStart());
+    return;
+  }
+
+  // Get the "release" selector.
+  IdentifierInfo* RII = &Ctx.Idents.get("release");
+  Selector RS = Ctx.Selectors.getSelector(0, &RII);
+
+  // Get the "self" identifier
+  IdentifierInfo* SelfII = &Ctx.Idents.get("self");
+
+  // Scan for missing and extra releases of ivars used by implementations
+  // of synthesized properties
+  for (ObjCImplementationDecl::propimpl_iterator I = D->propimpl_begin(),
+       E = D->propimpl_end(); I!=E; ++I) {
+
+    // We can only check the synthesized properties
+    if ((*I)->getPropertyImplementation() != ObjCPropertyImplDecl::Synthesize)
+      continue;
+
+    ObjCIvarDecl* ID = (*I)->getPropertyIvarDecl();
+    if (!ID)
+      continue;
+
+    QualType T = ID->getType();
+    if (!T->isObjCObjectPointerType()) // Skip non-pointer ivars
+      continue;
+
+    const ObjCPropertyDecl* PD = (*I)->getPropertyDecl();
+    if (!PD)
+      continue;
+
+    // ivars cannot be set via read-only properties, so we'll skip them
+    if (PD->isReadOnly())
+       continue;
+
+    // ivar must be released if and only if the kind of setter was not 'assign'
+    bool requiresRelease = PD->getSetterKind() != ObjCPropertyDecl::Assign;
+    if (scan_ivar_release(MD->getBody(), ID, PD, RS, SelfII, Ctx)
+       != requiresRelease) {
+      const char *name;
+      const char* category = "Memory (Core Foundation/Objective-C)";
+
+      std::string buf;
+      llvm::raw_string_ostream os(buf);
+
+      if (requiresRelease) {
+        name = LOpts.getGCMode() == LangOptions::NonGC
+               ? "missing ivar release (leak)"
+               : "missing ivar release (Hybrid MM, non-GC)";
+
+        os << "The '" << ID
+           << "' instance variable was retained by a synthesized property but "
+              "wasn't released in 'dealloc'";
+      } else {
+        name = LOpts.getGCMode() == LangOptions::NonGC
+               ? "extra ivar release (use-after-release)"
+               : "extra ivar release (Hybrid MM, non-GC)";
+
+        os << "The '" << ID
+           << "' instance variable was not retained by a synthesized property "
+              "but was released in 'dealloc'";
+      }
+
+      BR.EmitBasicReport(name, category, os.str(), (*I)->getLocation());
+    }
+  }
+}
+
diff --git a/lib/Checker/CheckObjCInstMethSignature.cpp b/lib/Checker/CheckObjCInstMethSignature.cpp
new file mode 100644
index 0000000..76a0923
--- /dev/null
+++ b/lib/Checker/CheckObjCInstMethSignature.cpp
@@ -0,0 +1,119 @@
+//=- CheckObjCInstMethodRetTy.cpp - Check ObjC method signatures -*- C++ -*-==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines a CheckObjCInstMethSignature, a flow-insenstive check
+//  that determines if an Objective-C class interface incorrectly redefines
+//  the method signature in a subclass.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Checker/Checkers/LocalCheckers.h"
+#include "clang/Checker/BugReporter/PathDiagnostic.h"
+#include "clang/Checker/BugReporter/BugReporter.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/ASTContext.h"
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace clang;
+
+static bool AreTypesCompatible(QualType Derived, QualType Ancestor,
+                               ASTContext& C) {
+
+  // Right now don't compare the compatibility of pointers.  That involves
+  // looking at subtyping relationships.  FIXME: Future patch.
+  if (Derived->isAnyPointerType() &&  Ancestor->isAnyPointerType())
+    return true;
+
+  return C.typesAreCompatible(Derived, Ancestor);
+}
+
+static void CompareReturnTypes(const ObjCMethodDecl *MethDerived,
+                               const ObjCMethodDecl *MethAncestor,
+                               BugReporter &BR, ASTContext &Ctx,
+                               const ObjCImplementationDecl *ID) {
+
+  QualType ResDerived  = MethDerived->getResultType();
+  QualType ResAncestor = MethAncestor->getResultType();
+
+  if (!AreTypesCompatible(ResDerived, ResAncestor, Ctx)) {
+    std::string sbuf;
+    llvm::raw_string_ostream os(sbuf);
+
+    os << "The Objective-C class '"
+       << MethDerived->getClassInterface()
+       << "', which is derived from class '"
+       << MethAncestor->getClassInterface()
+       << "', defines the instance method '"
+       << MethDerived->getSelector().getAsString()
+       << "' whose return type is '"
+       << ResDerived.getAsString()
+       << "'.  A method with the same name (same selector) is also defined in "
+          "class '"
+       << MethAncestor->getClassInterface()
+       << "' and has a return type of '"
+       << ResAncestor.getAsString()
+       << "'.  These two types are incompatible, and may result in undefined "
+          "behavior for clients of these classes.";
+
+    BR.EmitBasicReport("Incompatible instance method return type",
+                       os.str(), MethDerived->getLocStart());
+  }
+}
+
+void clang::CheckObjCInstMethSignature(const ObjCImplementationDecl* ID,
+                                       BugReporter& BR) {
+
+  const ObjCInterfaceDecl* D = ID->getClassInterface();
+  const ObjCInterfaceDecl* C = D->getSuperClass();
+
+  if (!C)
+    return;
+
+  ASTContext& Ctx = BR.getContext();
+
+  // Build a DenseMap of the methods for quick querying.
+  typedef llvm::DenseMap<Selector,ObjCMethodDecl*> MapTy;
+  MapTy IMeths;
+  unsigned NumMethods = 0;
+
+  for (ObjCImplementationDecl::instmeth_iterator I=ID->instmeth_begin(),
+       E=ID->instmeth_end(); I!=E; ++I) {
+
+    ObjCMethodDecl* M = *I;
+    IMeths[M->getSelector()] = M;
+    ++NumMethods;
+  }
+
+  // Now recurse the class hierarchy chain looking for methods with the
+  // same signatures.
+  while (C && NumMethods) {
+    for (ObjCInterfaceDecl::instmeth_iterator I=C->instmeth_begin(),
+         E=C->instmeth_end(); I!=E; ++I) {
+
+      ObjCMethodDecl* M = *I;
+      Selector S = M->getSelector();
+
+      MapTy::iterator MI = IMeths.find(S);
+
+      if (MI == IMeths.end() || MI->second == 0)
+        continue;
+
+      --NumMethods;
+      ObjCMethodDecl* MethDerived = MI->second;
+      MI->second = 0;
+
+      CompareReturnTypes(MethDerived, M, BR, Ctx, ID);
+    }
+
+    C = C->getSuperClass();
+  }
+}
diff --git a/lib/Checker/CheckSecuritySyntaxOnly.cpp b/lib/Checker/CheckSecuritySyntaxOnly.cpp
new file mode 100644
index 0000000..74e12b1
--- /dev/null
+++ b/lib/Checker/CheckSecuritySyntaxOnly.cpp
@@ -0,0 +1,494 @@
+//==- CheckSecuritySyntaxOnly.cpp - Basic security checks --------*- C++ -*-==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines a set of flow-insensitive security checks.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Basic/TargetInfo.h"
+#include "clang/Checker/BugReporter/BugReporter.h"
+#include "clang/Checker/Checkers/LocalCheckers.h"
+#include "clang/AST/StmtVisitor.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace clang;
+
+static bool isArc4RandomAvailable(const ASTContext &Ctx) {
+  const llvm::Triple &T = Ctx.Target.getTriple();
+  return T.getVendor() == llvm::Triple::Apple ||
+         T.getOS() == llvm::Triple::FreeBSD;
+}
+
+namespace {
+class WalkAST : public StmtVisitor<WalkAST> {
+  BugReporter &BR;
+  IdentifierInfo *II_gets;
+  IdentifierInfo *II_getpw;
+  IdentifierInfo *II_mktemp;
+  enum { num_rands = 9 };
+  IdentifierInfo *II_rand[num_rands];
+  IdentifierInfo *II_random;
+  enum { num_setids = 6 };
+  IdentifierInfo *II_setid[num_setids];
+
+  const bool CheckRand;
+
+public:
+  WalkAST(BugReporter &br) : BR(br),
+			     II_gets(0), II_getpw(0), II_mktemp(0),
+			     II_rand(), II_random(0), II_setid(),
+                 CheckRand(isArc4RandomAvailable(BR.getContext())) {}
+
+  // Statement visitor methods.
+  void VisitCallExpr(CallExpr *CE);
+  void VisitForStmt(ForStmt *S);
+  void VisitCompoundStmt (CompoundStmt *S);
+  void VisitStmt(Stmt *S) { VisitChildren(S); }
+
+  void VisitChildren(Stmt *S);
+
+  // Helpers.
+  IdentifierInfo *GetIdentifier(IdentifierInfo *& II, const char *str);
+
+  // Checker-specific methods.
+  void CheckLoopConditionForFloat(const ForStmt *FS);
+  void CheckCall_gets(const CallExpr *CE, const FunctionDecl *FD);
+  void CheckCall_getpw(const CallExpr *CE, const FunctionDecl *FD);
+  void CheckCall_mktemp(const CallExpr *CE, const FunctionDecl *FD);
+  void CheckCall_rand(const CallExpr *CE, const FunctionDecl *FD);
+  void CheckCall_random(const CallExpr *CE, const FunctionDecl *FD);
+  void CheckUncheckedReturnValue(CallExpr *CE);
+};
+} // end anonymous namespace
+
+//===----------------------------------------------------------------------===//
+// Helper methods.
+//===----------------------------------------------------------------------===//
+
+IdentifierInfo *WalkAST::GetIdentifier(IdentifierInfo *& II, const char *str) {
+  if (!II)
+    II = &BR.getContext().Idents.get(str);
+
+  return II;
+}
+
+//===----------------------------------------------------------------------===//
+// AST walking.
+//===----------------------------------------------------------------------===//
+
+void WalkAST::VisitChildren(Stmt *S) {
+  for (Stmt::child_iterator I = S->child_begin(), E = S->child_end(); I!=E; ++I)
+    if (Stmt *child = *I)
+      Visit(child);
+}
+
+void WalkAST::VisitCallExpr(CallExpr *CE) {
+  if (const FunctionDecl *FD = CE->getDirectCallee()) {
+    CheckCall_gets(CE, FD);
+    CheckCall_getpw(CE, FD);
+    CheckCall_mktemp(CE, FD);
+    if (CheckRand) {
+      CheckCall_rand(CE, FD);
+      CheckCall_random(CE, FD);
+    }
+  }
+
+  // Recurse and check children.
+  VisitChildren(CE);
+}
+
+void WalkAST::VisitCompoundStmt(CompoundStmt *S) {
+  for (Stmt::child_iterator I = S->child_begin(), E = S->child_end(); I!=E; ++I)
+    if (Stmt *child = *I) {
+      if (CallExpr *CE = dyn_cast<CallExpr>(child))
+        CheckUncheckedReturnValue(CE);
+      Visit(child);
+    }
+}
+
+void WalkAST::VisitForStmt(ForStmt *FS) {
+  CheckLoopConditionForFloat(FS);
+
+  // Recurse and check children.
+  VisitChildren(FS);
+}
+
+//===----------------------------------------------------------------------===//
+// Check: floating poing variable used as loop counter.
+// Originally: <rdar://problem/6336718>
+// Implements: CERT security coding advisory FLP-30.
+//===----------------------------------------------------------------------===//
+
+static const DeclRefExpr*
+GetIncrementedVar(const Expr *expr, const VarDecl *x, const VarDecl *y) {
+  expr = expr->IgnoreParenCasts();
+
+  if (const BinaryOperator *B = dyn_cast<BinaryOperator>(expr)) {
+    if (!(B->isAssignmentOp() || B->isCompoundAssignmentOp() ||
+          B->getOpcode() == BinaryOperator::Comma))
+      return NULL;
+
+    if (const DeclRefExpr *lhs = GetIncrementedVar(B->getLHS(), x, y))
+      return lhs;
+
+    if (const DeclRefExpr *rhs = GetIncrementedVar(B->getRHS(), x, y))
+      return rhs;
+
+    return NULL;
+  }
+
+  if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(expr)) {
+    const NamedDecl *ND = DR->getDecl();
+    return ND == x || ND == y ? DR : NULL;
+  }
+
+  if (const UnaryOperator *U = dyn_cast<UnaryOperator>(expr))
+    return U->isIncrementDecrementOp()
+      ? GetIncrementedVar(U->getSubExpr(), x, y) : NULL;
+
+  return NULL;
+}
+
+/// CheckLoopConditionForFloat - This check looks for 'for' statements that
+///  use a floating point variable as a loop counter.
+///  CERT: FLP30-C, FLP30-CPP.
+///
+void WalkAST::CheckLoopConditionForFloat(const ForStmt *FS) {
+  // Does the loop have a condition?
+  const Expr *condition = FS->getCond();
+
+  if (!condition)
+    return;
+
+  // Does the loop have an increment?
+  const Expr *increment = FS->getInc();
+
+  if (!increment)
+    return;
+
+  // Strip away '()' and casts.
+  condition = condition->IgnoreParenCasts();
+  increment = increment->IgnoreParenCasts();
+
+  // Is the loop condition a comparison?
+  const BinaryOperator *B = dyn_cast<BinaryOperator>(condition);
+
+  if (!B)
+    return;
+
+  // Is this a comparison?
+  if (!(B->isRelationalOp() || B->isEqualityOp()))
+    return;
+
+  // Are we comparing variables?
+  const DeclRefExpr *drLHS = dyn_cast<DeclRefExpr>(B->getLHS()->IgnoreParens());
+  const DeclRefExpr *drRHS = dyn_cast<DeclRefExpr>(B->getRHS()->IgnoreParens());
+
+  // Does at least one of the variables have a floating point type?
+  drLHS = drLHS && drLHS->getType()->isFloatingType() ? drLHS : NULL;
+  drRHS = drRHS && drRHS->getType()->isFloatingType() ? drRHS : NULL;
+
+  if (!drLHS && !drRHS)
+    return;
+
+  const VarDecl *vdLHS = drLHS ? dyn_cast<VarDecl>(drLHS->getDecl()) : NULL;
+  const VarDecl *vdRHS = drRHS ? dyn_cast<VarDecl>(drRHS->getDecl()) : NULL;
+
+  if (!vdLHS && !vdRHS)
+    return;
+
+  // Does either variable appear in increment?
+  const DeclRefExpr *drInc = GetIncrementedVar(increment, vdLHS, vdRHS);
+
+  if (!drInc)
+    return;
+
+  // Emit the error.  First figure out which DeclRefExpr in the condition
+  // referenced the compared variable.
+  const DeclRefExpr *drCond = vdLHS == drInc->getDecl() ? drLHS : drRHS;
+
+  llvm::SmallVector<SourceRange, 2> ranges;
+  llvm::SmallString<256> sbuf;
+  llvm::raw_svector_ostream os(sbuf);
+
+  os << "Variable '" << drCond->getDecl()->getNameAsCString()
+     << "' with floating point type '" << drCond->getType().getAsString()
+     << "' should not be used as a loop counter";
+
+  ranges.push_back(drCond->getSourceRange());
+  ranges.push_back(drInc->getSourceRange());
+
+  const char *bugType = "Floating point variable used as loop counter";
+  BR.EmitBasicReport(bugType, "Security", os.str(),
+                     FS->getLocStart(), ranges.data(), ranges.size());
+}
+
+//===----------------------------------------------------------------------===//
+// Check: Any use of 'gets' is insecure.
+// Originally: <rdar://problem/6335715>
+// Implements (part of): 300-BSI (buildsecurityin.us-cert.gov)
+// CWE-242: Use of Inherently Dangerous Function
+//===----------------------------------------------------------------------===//
+
+void WalkAST::CheckCall_gets(const CallExpr *CE, const FunctionDecl *FD) {
+  if (FD->getIdentifier() != GetIdentifier(II_gets, "gets"))
+    return;
+
+  const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(FD->getType());
+  if (!FPT)
+    return;
+
+  // Verify that the function takes a single argument.
+  if (FPT->getNumArgs() != 1)
+    return;
+
+  // Is the argument a 'char*'?
+  const PointerType *PT = dyn_cast<PointerType>(FPT->getArgType(0));
+  if (!PT)
+    return;
+
+  if (PT->getPointeeType().getUnqualifiedType() != BR.getContext().CharTy)
+    return;
+
+  // Issue a warning.
+  SourceRange R = CE->getCallee()->getSourceRange();
+  BR.EmitBasicReport("Potential buffer overflow in call to 'gets'",
+                     "Security",
+                     "Call to function 'gets' is extremely insecure as it can "
+                     "always result in a buffer overflow",
+                     CE->getLocStart(), &R, 1);
+}
+
+//===----------------------------------------------------------------------===//
+// Check: Any use of 'getpwd' is insecure.
+// CWE-477: Use of Obsolete Functions
+//===----------------------------------------------------------------------===//
+
+void WalkAST::CheckCall_getpw(const CallExpr *CE, const FunctionDecl *FD) {
+  if (FD->getIdentifier() != GetIdentifier(II_getpw, "getpw"))
+    return;
+
+  const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(FD->getType());
+  if (!FPT)
+    return;
+
+  // Verify that the function takes two arguments.
+  if (FPT->getNumArgs() != 2)
+    return;
+
+  // Verify the first argument type is integer.
+  if (!FPT->getArgType(0)->isIntegerType())
+    return;
+
+  // Verify the second argument type is char*.
+  const PointerType *PT = dyn_cast<PointerType>(FPT->getArgType(1));
+  if (!PT)
+    return;
+
+  if (PT->getPointeeType().getUnqualifiedType() != BR.getContext().CharTy)
+    return;
+
+  // Issue a warning.
+  SourceRange R = CE->getCallee()->getSourceRange();
+  BR.EmitBasicReport("Potential buffer overflow in call to 'getpw'",
+                     "Security",
+                     "The getpw() function is dangerous as it may overflow the "
+                     "provided buffer. It is obsoleted by getpwuid().",
+                     CE->getLocStart(), &R, 1);
+}
+
+//===----------------------------------------------------------------------===//
+// Check: Any use of 'mktemp' is insecure.It is obsoleted by mkstemp().
+// CWE-377: Insecure Temporary File
+//===----------------------------------------------------------------------===//
+
+void WalkAST::CheckCall_mktemp(const CallExpr *CE, const FunctionDecl *FD) {
+  if (FD->getIdentifier() != GetIdentifier(II_mktemp, "mktemp"))
+    return;
+
+  const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(FD->getType());
+  if(!FPT)
+    return;
+
+  // Verify that the funcion takes a single argument.
+  if (FPT->getNumArgs() != 1)
+    return;
+
+  // Verify that the argument is Pointer Type.
+  const PointerType *PT = dyn_cast<PointerType>(FPT->getArgType(0));
+  if (!PT)
+    return;
+
+  // Verify that the argument is a 'char*'.
+  if (PT->getPointeeType().getUnqualifiedType() != BR.getContext().CharTy)
+    return;
+
+  // Issue a waring.
+  SourceRange R = CE->getCallee()->getSourceRange();
+  BR.EmitBasicReport("Potential insecure temporary file in call 'mktemp'",
+		     "Security",
+		     "Call to function 'mktemp' is insecure as it always "
+		     "creates or uses insecure temporary file.  Use 'mkstemp' instead",
+		     CE->getLocStart(), &R, 1);
+}
+
+//===----------------------------------------------------------------------===//
+// Check: Linear congruent random number generators should not be used
+// Originally: <rdar://problem/63371000>
+// CWE-338: Use of cryptographically weak prng
+//===----------------------------------------------------------------------===//
+
+void WalkAST::CheckCall_rand(const CallExpr *CE, const FunctionDecl *FD) {
+  if (II_rand[0] == NULL) {
+    // This check applies to these functions
+    static const char * const identifiers[num_rands] = {
+      "drand48", "erand48", "jrand48", "lrand48", "mrand48", "nrand48",
+      "lcong48",
+      "rand", "rand_r"
+    };
+
+    for (size_t i = 0; i < num_rands; i++)
+      II_rand[i] = &BR.getContext().Idents.get(identifiers[i]);
+  }
+
+  const IdentifierInfo *id = FD->getIdentifier();
+  size_t identifierid;
+
+  for (identifierid = 0; identifierid < num_rands; identifierid++)
+    if (id == II_rand[identifierid])
+      break;
+
+  if (identifierid >= num_rands)
+    return;
+
+  const FunctionProtoType *FTP = dyn_cast<FunctionProtoType>(FD->getType());
+  if (!FTP)
+    return;
+
+  if (FTP->getNumArgs() == 1) {
+    // Is the argument an 'unsigned short *'?
+    // (Actually any integer type is allowed.)
+    const PointerType *PT = dyn_cast<PointerType>(FTP->getArgType(0));
+    if (!PT)
+      return;
+
+    if (! PT->getPointeeType()->isIntegerType())
+      return;
+  }
+  else if (FTP->getNumArgs() != 0)
+    return;
+
+  // Issue a warning.
+  llvm::SmallString<256> buf1;
+  llvm::raw_svector_ostream os1(buf1);
+  os1 << '\'' << FD << "' is a poor random number generator";
+
+  llvm::SmallString<256> buf2;
+  llvm::raw_svector_ostream os2(buf2);
+  os2 << "Function '" << FD
+      << "' is obsolete because it implements a poor random number generator."
+      << "  Use 'arc4random' instead";
+
+  SourceRange R = CE->getCallee()->getSourceRange();
+  BR.EmitBasicReport(os1.str(), "Security", os2.str(),CE->getLocStart(), &R, 1);
+}
+
+//===----------------------------------------------------------------------===//
+// Check: 'random' should not be used
+// Originally: <rdar://problem/63371000>
+//===----------------------------------------------------------------------===//
+
+void WalkAST::CheckCall_random(const CallExpr *CE, const FunctionDecl *FD) {
+  if (FD->getIdentifier() != GetIdentifier(II_random, "random"))
+    return;
+
+  const FunctionProtoType *FTP = dyn_cast<FunctionProtoType>(FD->getType());
+  if (!FTP)
+    return;
+
+  // Verify that the function takes no argument.
+  if (FTP->getNumArgs() != 0)
+    return;
+
+  // Issue a warning.
+  SourceRange R = CE->getCallee()->getSourceRange();
+  BR.EmitBasicReport("'random' is not a secure random number generator",
+                     "Security",
+                     "The 'random' function produces a sequence of values that "
+                     "an adversary may be able to predict.  Use 'arc4random' "
+                     "instead", CE->getLocStart(), &R, 1);
+}
+
+//===----------------------------------------------------------------------===//
+// Check: Should check whether privileges are dropped successfully.
+// Originally: <rdar://problem/6337132>
+//===----------------------------------------------------------------------===//
+
+void WalkAST::CheckUncheckedReturnValue(CallExpr *CE) {
+  const FunctionDecl *FD = CE->getDirectCallee();
+  if (!FD)
+    return;
+
+  if (II_setid[0] == NULL) {
+    static const char * const identifiers[num_setids] = {
+      "setuid", "setgid", "seteuid", "setegid",
+      "setreuid", "setregid"
+    };
+
+    for (size_t i = 0; i < num_setids; i++)
+      II_setid[i] = &BR.getContext().Idents.get(identifiers[i]);
+  }
+
+  const IdentifierInfo *id = FD->getIdentifier();
+  size_t identifierid;
+
+  for (identifierid = 0; identifierid < num_setids; identifierid++)
+    if (id == II_setid[identifierid])
+      break;
+
+  if (identifierid >= num_setids)
+    return;
+
+  const FunctionProtoType *FTP = dyn_cast<FunctionProtoType>(FD->getType());
+  if (!FTP)
+    return;
+
+  // Verify that the function takes one or two arguments (depending on
+  //   the function).
+  if (FTP->getNumArgs() != (identifierid < 4 ? 1 : 2))
+    return;
+
+  // The arguments must be integers.
+  for (unsigned i = 0; i < FTP->getNumArgs(); i++)
+    if (! FTP->getArgType(i)->isIntegerType())
+      return;
+
+  // Issue a warning.
+  llvm::SmallString<256> buf1;
+  llvm::raw_svector_ostream os1(buf1);
+  os1 << "Return value is not checked in call to '" << FD << '\'';
+
+  llvm::SmallString<256> buf2;
+  llvm::raw_svector_ostream os2(buf2);
+  os2 << "The return value from the call to '" << FD
+      << "' is not checked.  If an error occurs in '" << FD
+      << "', the following code may execute with unexpected privileges";
+
+  SourceRange R = CE->getCallee()->getSourceRange();
+  BR.EmitBasicReport(os1.str(), "Security", os2.str(),CE->getLocStart(), &R, 1);
+}
+
+//===----------------------------------------------------------------------===//
+// Entry point for check.
+//===----------------------------------------------------------------------===//
+
+void clang::CheckSecuritySyntaxOnly(const Decl *D, BugReporter &BR) {
+  WalkAST walker(BR);
+  walker.Visit(D->getBody());
+}
diff --git a/lib/Checker/CheckSizeofPointer.cpp b/lib/Checker/CheckSizeofPointer.cpp
new file mode 100644
index 0000000..bbe494c
--- /dev/null
+++ b/lib/Checker/CheckSizeofPointer.cpp
@@ -0,0 +1,71 @@
+//==- CheckSizeofPointer.cpp - Check for sizeof on pointers ------*- C++ -*-==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines a check for unintended use of sizeof() on pointer
+//  expressions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Checker/BugReporter/BugReporter.h"
+#include "clang/AST/StmtVisitor.h"
+#include "clang/Checker/Checkers/LocalCheckers.h"
+
+using namespace clang;
+
+namespace {
+class WalkAST : public StmtVisitor<WalkAST> {
+  BugReporter &BR;
+
+public:
+  WalkAST(BugReporter &br) : BR(br) {}
+  void VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E);
+  void VisitStmt(Stmt *S) { VisitChildren(S); }
+  void VisitChildren(Stmt *S);
+};
+}
+
+void WalkAST::VisitChildren(Stmt *S) {
+  for (Stmt::child_iterator I = S->child_begin(), E = S->child_end(); I!=E; ++I)
+    if (Stmt *child = *I)
+      Visit(child);
+}
+
+// CWE-467: Use of sizeof() on a Pointer Type
+void WalkAST::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) {
+  if (!E->isSizeOf())
+    return;
+
+  // If an explicit type is used in the code, usually the coder knows what he is
+  // doing.
+  if (E->isArgumentType())
+    return;
+
+  QualType T = E->getTypeOfArgument();
+  if (T->isPointerType()) {
+
+    // Many false positives have the form 'sizeof *p'. This is reasonable 
+    // because people know what they are doing when they intentionally 
+    // dereference the pointer.
+    Expr *ArgEx = E->getArgumentExpr();
+    if (!isa<DeclRefExpr>(ArgEx->IgnoreParens()))
+      return;
+
+    SourceRange R = ArgEx->getSourceRange();
+    BR.EmitBasicReport("Potential unintended use of sizeof() on pointer type",
+                       "Logic",
+                       "The code calls sizeof() on a pointer type. "
+                       "This can produce an unexpected result.",
+                       E->getLocStart(), &R, 1);
+  }
+}
+
+void clang::CheckSizeofPointer(const Decl *D, BugReporter &BR) {
+  WalkAST walker(BR);
+  walker.Visit(D->getBody());
+}
diff --git a/lib/Checker/Checker.cpp b/lib/Checker/Checker.cpp
new file mode 100644
index 0000000..36323b9
--- /dev/null
+++ b/lib/Checker/Checker.cpp
@@ -0,0 +1,35 @@
+//== Checker.h - Abstract interface for checkers -----------------*- C++ -*--=//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines Checker and CheckerVisitor, classes used for creating
+//  domain-specific checks.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Checker/PathSensitive/Checker.h"
+using namespace clang;
+
+Checker::~Checker() {}
+
+CheckerContext::~CheckerContext() {
+  // Do we need to autotransition?  'Dst' can get populated in a variety of
+  // ways, including 'addTransition()' adding the predecessor node to Dst
+  // without actually generated a new node.  We also shouldn't autotransition
+  // if we are building sinks or we generated a node and decided to not
+  // add it as a transition.
+  if (Dst.size() == size && !B.BuildSinks && !B.HasGeneratedNode) {
+    if (ST && ST != B.GetState(Pred)) {
+      static int autoTransitionTag = 0;
+      B.Tag = &autoTransitionTag;
+      addTransition(ST);
+    }
+    else
+      Dst.Add(Pred);
+  }
+}
diff --git a/lib/Checker/CocoaConventions.cpp b/lib/Checker/CocoaConventions.cpp
new file mode 100644
index 0000000..3ba887c
--- /dev/null
+++ b/lib/Checker/CocoaConventions.cpp
@@ -0,0 +1,195 @@
+//===- CocoaConventions.h - Special handling of Cocoa conventions -*- C++ -*--//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines 
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Checker/DomainSpecific/CocoaConventions.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclObjC.h"
+#include "llvm/ADT/StringExtras.h"
+
+using namespace clang;
+
+using llvm::StringRef;
+
+// The "fundamental rule" for naming conventions of methods:
+//  (url broken into two lines)
+//  http://developer.apple.com/documentation/Cocoa/Conceptual/
+//     MemoryMgmt/Tasks/MemoryManagementRules.html
+//
+// "You take ownership of an object if you create it using a method whose name
+//  begins with "alloc" or "new" or contains "copy" (for example, alloc,
+//  newObject, or mutableCopy), or if you send it a retain message. You are
+//  responsible for relinquishing ownership of objects you own using release
+//  or autorelease. Any other time you receive an object, you must
+//  not release it."
+//
+
+static bool isWordEnd(char ch, char prev, char next) {
+  return ch == '\0'
+      || (islower(prev) && isupper(ch)) // xxxC
+      || (isupper(prev) && isupper(ch) && islower(next)) // XXCreate
+      || !isalpha(ch);
+}
+
+static const char* parseWord(const char* s) {
+  char ch = *s, prev = '\0';
+  assert(ch != '\0');
+  char next = *(s+1);
+  while (!isWordEnd(ch, prev, next)) {
+    prev = ch;
+    ch = next;
+    next = *((++s)+1);
+  }
+  return s;
+}
+
+cocoa::NamingConvention cocoa::deriveNamingConvention(Selector S) {
+  IdentifierInfo *II = S.getIdentifierInfoForSlot(0);
+
+  if (!II)
+    return NoConvention;
+
+  const char *s = II->getNameStart();
+
+  // A method/function name may contain a prefix.  We don't know it is there,
+  // however, until we encounter the first '_'.
+  bool InPossiblePrefix = true;
+  bool AtBeginning = true;
+  NamingConvention C = NoConvention;
+
+  while (*s != '\0') {
+    // Skip '_'.
+    if (*s == '_') {
+      if (InPossiblePrefix) {
+        // If we already have a convention, return it.  Otherwise, skip
+        // the prefix as if it wasn't there.
+        if (C != NoConvention)
+          break;
+        
+        InPossiblePrefix = false;
+        AtBeginning = true;
+        assert(C == NoConvention);
+      }
+      ++s;
+      continue;
+    }
+
+    // Skip numbers, ':', etc.
+    if (!isalpha(*s)) {
+      ++s;
+      continue;
+    }
+
+    const char *wordEnd = parseWord(s);
+    assert(wordEnd > s);
+    unsigned len = wordEnd - s;
+
+    switch (len) {
+    default:
+      break;
+    case 3:
+      // Methods starting with 'new' follow the create rule.
+      if (AtBeginning && StringRef(s, len).equals_lower("new"))
+        C = CreateRule;
+      break;
+    case 4:
+      // Methods starting with 'alloc' or contain 'copy' follow the
+      // create rule
+      if (C == NoConvention && StringRef(s, len).equals_lower("copy"))
+        C = CreateRule;
+      else // Methods starting with 'init' follow the init rule.
+        if (AtBeginning && StringRef(s, len).equals_lower("init"))
+          C = InitRule;
+      break;
+    case 5:
+      if (AtBeginning && StringRef(s, len).equals_lower("alloc"))
+        C = CreateRule;
+      break;
+    }
+
+    // If we aren't in the prefix and have a derived convention then just
+    // return it now.
+    if (!InPossiblePrefix && C != NoConvention)
+      return C;
+
+    AtBeginning = false;
+    s = wordEnd;
+  }
+
+  // We will get here if there wasn't more than one word
+  // after the prefix.
+  return C;
+}
+
+bool cocoa::isRefType(QualType RetTy, llvm::StringRef Prefix,
+                      llvm::StringRef Name) {
+  // Recursively walk the typedef stack, allowing typedefs of reference types.
+  while (TypedefType* TD = dyn_cast<TypedefType>(RetTy.getTypePtr())) {
+    llvm::StringRef TDName = TD->getDecl()->getIdentifier()->getName();
+    if (TDName.startswith(Prefix) && TDName.endswith("Ref"))
+      return true;
+    
+    RetTy = TD->getDecl()->getUnderlyingType();
+  }
+  
+  if (Name.empty())
+    return false;
+  
+  // Is the type void*?
+  const PointerType* PT = RetTy->getAs<PointerType>();
+  if (!(PT->getPointeeType().getUnqualifiedType()->isVoidType()))
+    return false;
+  
+  // Does the name start with the prefix?
+  return Name.startswith(Prefix);
+}
+
+bool cocoa::isCFObjectRef(QualType T) {
+  return isRefType(T, "CF") || // Core Foundation.
+         isRefType(T, "CG") || // Core Graphics.
+         isRefType(T, "DADisk") || // Disk Arbitration API.
+         isRefType(T, "DADissenter") ||
+         isRefType(T, "DASessionRef");
+}
+
+
+bool cocoa::isCocoaObjectRef(QualType Ty) {
+  if (!Ty->isObjCObjectPointerType())
+    return false;
+  
+  const ObjCObjectPointerType *PT = Ty->getAs<ObjCObjectPointerType>();
+  
+  // Can be true for objects with the 'NSObject' attribute.
+  if (!PT)
+    return true;
+  
+  // We assume that id<..>, id, and "Class" all represent tracked objects.
+  if (PT->isObjCIdType() || PT->isObjCQualifiedIdType() ||
+      PT->isObjCClassType())
+    return true;
+  
+  // Does the interface subclass NSObject?
+  // FIXME: We can memoize here if this gets too expensive.
+  const ObjCInterfaceDecl *ID = PT->getInterfaceDecl();
+  
+  // Assume that anything declared with a forward declaration and no
+  // @interface subclasses NSObject.
+  if (ID->isForwardDecl())
+    return true;
+  
+  for ( ; ID ; ID = ID->getSuperClass())
+    if (ID->getIdentifier()->getName() == "NSObject")
+      return true;
+  
+  return false;
+}
diff --git a/lib/Checker/DereferenceChecker.cpp b/lib/Checker/DereferenceChecker.cpp
new file mode 100644
index 0000000..af74c79
--- /dev/null
+++ b/lib/Checker/DereferenceChecker.cpp
@@ -0,0 +1,156 @@
+//== NullDerefChecker.cpp - Null dereference checker ------------*- C++ -*--==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This defines NullDerefChecker, a builtin check in GRExprEngine that performs
+// checks for null pointers at loads and stores.
+//
+//===----------------------------------------------------------------------===//
+
+#include "GRExprEngineInternalChecks.h"
+#include "clang/Checker/BugReporter/BugType.h"
+#include "clang/Checker/Checkers/DereferenceChecker.h"
+#include "clang/Checker/PathSensitive/Checker.h"
+#include "clang/Checker/PathSensitive/GRExprEngine.h"
+
+using namespace clang;
+
+namespace {
+class DereferenceChecker : public Checker {
+  BuiltinBug *BT_null;
+  BuiltinBug *BT_undef;
+  llvm::SmallVector<ExplodedNode*, 2> ImplicitNullDerefNodes;
+public:
+  DereferenceChecker() : BT_null(0), BT_undef(0) {}
+  static void *getTag() { static int tag = 0; return &tag; }
+  void VisitLocation(CheckerContext &C, const Stmt *S, SVal location);
+
+  std::pair<ExplodedNode * const*, ExplodedNode * const*>
+  getImplicitNodes() const {
+    return std::make_pair(ImplicitNullDerefNodes.data(),
+                          ImplicitNullDerefNodes.data() +
+                          ImplicitNullDerefNodes.size());
+  }
+};
+} // end anonymous namespace
+
+void clang::RegisterDereferenceChecker(GRExprEngine &Eng) {
+  Eng.registerCheck(new DereferenceChecker());
+}
+
+std::pair<ExplodedNode * const *, ExplodedNode * const *>
+clang::GetImplicitNullDereferences(GRExprEngine &Eng) {
+  DereferenceChecker *checker = Eng.getChecker<DereferenceChecker>();
+  if (!checker)
+    return std::make_pair((ExplodedNode * const *) 0,
+                          (ExplodedNode * const *) 0);
+  return checker->getImplicitNodes();
+}
+
+void DereferenceChecker::VisitLocation(CheckerContext &C, const Stmt *S,
+                                       SVal l) {
+  // Check for dereference of an undefined value.
+  if (l.isUndef()) {
+    if (ExplodedNode *N = C.GenerateSink()) {
+      if (!BT_undef)
+        BT_undef = new BuiltinBug("Dereference of undefined pointer value");
+
+      EnhancedBugReport *report =
+        new EnhancedBugReport(*BT_undef, BT_undef->getDescription(), N);
+      report->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue,
+                                bugreporter::GetDerefExpr(N));
+      C.EmitReport(report);
+    }
+    return;
+  }
+
+  DefinedOrUnknownSVal location = cast<DefinedOrUnknownSVal>(l);
+
+  // Check for null dereferences.
+  if (!isa<Loc>(location))
+    return;
+
+  const GRState *state = C.getState();
+  const GRState *notNullState, *nullState;
+  llvm::tie(notNullState, nullState) = state->Assume(location);
+
+  // The explicit NULL case.
+  if (nullState) {
+    if (!notNullState) {
+      // Generate an error node.
+      ExplodedNode *N = C.GenerateSink(nullState);
+      if (!N)
+        return;
+
+      // We know that 'location' cannot be non-null.  This is what
+      // we call an "explicit" null dereference.
+      if (!BT_null)
+        BT_null = new BuiltinBug("Dereference of null pointer");
+
+      llvm::SmallString<100> buf;
+      llvm::SmallVector<SourceRange, 2> Ranges;
+
+      switch (S->getStmtClass()) {
+        case Stmt::UnaryOperatorClass: {
+          const UnaryOperator *U = cast<UnaryOperator>(S);
+          const Expr *SU = U->getSubExpr()->IgnoreParens();
+          if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(SU)) {
+            if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
+              llvm::raw_svector_ostream os(buf);
+              os << "Dereference of null pointer (loaded from variable '"
+                 << VD->getName() << "')";
+              Ranges.push_back(DR->getSourceRange());
+            }
+          }
+          break;
+        }
+        case Stmt::MemberExprClass: {
+          const MemberExpr *M = cast<MemberExpr>(S);
+          if (M->isArrow())
+            if (DeclRefExpr *DR =
+                dyn_cast<DeclRefExpr>(M->getBase()->IgnoreParenCasts())) {
+              if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
+                llvm::raw_svector_ostream os(buf);
+                os << "Field access results in a dereference of a null pointer "
+                      "(loaded from variable '" << VD->getName() << "')";
+                Ranges.push_back(M->getBase()->getSourceRange());
+              }
+            }
+          break;
+        }
+        default:
+          break;
+      }
+
+      EnhancedBugReport *report =
+        new EnhancedBugReport(*BT_null,
+                              buf.empty() ? BT_null->getDescription():buf.str(),
+                              N);
+
+      report->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue,
+                                bugreporter::GetDerefExpr(N));
+
+      for (llvm::SmallVectorImpl<SourceRange>::iterator
+            I = Ranges.begin(), E = Ranges.end(); I!=E; ++I)
+        report->addRange(*I);
+
+      C.EmitReport(report);
+      return;
+    }
+    else {
+      // Otherwise, we have the case where the location could either be
+      // null or not-null.  Record the error node as an "implicit" null
+      // dereference.
+      if (ExplodedNode *N = C.GenerateSink(nullState))
+        ImplicitNullDerefNodes.push_back(N);
+    }
+  }
+
+  // From this point forward, we know that the location is not null.
+  C.addTransition(notNullState);
+}
diff --git a/lib/Checker/DivZeroChecker.cpp b/lib/Checker/DivZeroChecker.cpp
new file mode 100644
index 0000000..e09a871
--- /dev/null
+++ b/lib/Checker/DivZeroChecker.cpp
@@ -0,0 +1,85 @@
+//== DivZeroChecker.cpp - Division by zero checker --------------*- C++ -*--==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This defines DivZeroChecker, a builtin check in GRExprEngine that performs
+// checks for division by zeros.
+//
+//===----------------------------------------------------------------------===//
+
+#include "GRExprEngineInternalChecks.h"
+#include "clang/Checker/BugReporter/BugType.h"
+#include "clang/Checker/PathSensitive/CheckerVisitor.h"
+
+using namespace clang;
+
+namespace {
+class DivZeroChecker : public CheckerVisitor<DivZeroChecker> {
+  BuiltinBug *BT;
+public:
+  DivZeroChecker() : BT(0) {}  
+  static void *getTag();
+  void PreVisitBinaryOperator(CheckerContext &C, const BinaryOperator *B);
+};  
+} // end anonymous namespace
+
+void clang::RegisterDivZeroChecker(GRExprEngine &Eng) {
+  Eng.registerCheck(new DivZeroChecker());
+}
+
+void *DivZeroChecker::getTag() {
+  static int x;
+  return &x;
+}
+
+void DivZeroChecker::PreVisitBinaryOperator(CheckerContext &C,
+                                            const BinaryOperator *B) {
+  BinaryOperator::Opcode Op = B->getOpcode();
+  if (Op != BinaryOperator::Div &&
+      Op != BinaryOperator::Rem &&
+      Op != BinaryOperator::DivAssign &&
+      Op != BinaryOperator::RemAssign)
+    return;
+
+  if (!B->getRHS()->getType()->isIntegerType() ||
+      !B->getRHS()->getType()->isScalarType())
+    return;
+
+  SVal Denom = C.getState()->getSVal(B->getRHS());
+  const DefinedSVal *DV = dyn_cast<DefinedSVal>(&Denom);
+
+  // Divide-by-undefined handled in the generic checking for uses of
+  // undefined values.
+  if (!DV)
+    return;
+
+  // Check for divide by zero.
+  ConstraintManager &CM = C.getConstraintManager();
+  const GRState *stateNotZero, *stateZero;
+  llvm::tie(stateNotZero, stateZero) = CM.AssumeDual(C.getState(), *DV);
+
+  if (stateZero && !stateNotZero) {
+    if (ExplodedNode *N = C.GenerateSink(stateZero)) {
+      if (!BT)
+        BT = new BuiltinBug("Division by zero");
+
+      EnhancedBugReport *R = 
+        new EnhancedBugReport(*BT, BT->getDescription(), N);
+
+      R->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue,
+                           bugreporter::GetDenomExpr(N));
+
+      C.EmitReport(R);
+    }
+    return;
+  }
+
+  // If we get here, then the denom should not be zero. We abandon the implicit
+  // zero denom case for now.
+  C.addTransition(stateNotZero);
+}
diff --git a/lib/Checker/Environment.cpp b/lib/Checker/Environment.cpp
new file mode 100644
index 0000000..addfc21
--- /dev/null
+++ b/lib/Checker/Environment.cpp
@@ -0,0 +1,191 @@
+//== Environment.cpp - Map from Stmt* to Locations/Values -------*- C++ -*--==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defined the Environment and EnvironmentManager classes.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Analysis/CFG.h"
+#include "clang/Checker/PathSensitive/GRState.h"
+
+using namespace clang;
+
+SVal Environment::GetSVal(const Stmt *E, ValueManager& ValMgr) const {
+
+  for (;;) {
+
+    switch (E->getStmtClass()) {
+
+      case Stmt::AddrLabelExprClass:
+        return ValMgr.makeLoc(cast<AddrLabelExpr>(E));
+
+        // ParenExprs are no-ops.
+
+      case Stmt::ParenExprClass:
+        E = cast<ParenExpr>(E)->getSubExpr();
+        continue;
+
+      case Stmt::CharacterLiteralClass: {
+        const CharacterLiteral* C = cast<CharacterLiteral>(E);
+        return ValMgr.makeIntVal(C->getValue(), C->getType());
+      }
+
+      case Stmt::CXXBoolLiteralExprClass: {
+        const SVal *X = ExprBindings.lookup(E);
+        if (X) 
+          return *X;
+        else 
+          return ValMgr.makeIntVal(cast<CXXBoolLiteralExpr>(E));
+      }
+      case Stmt::IntegerLiteralClass: {
+        // In C++, this expression may have been bound to a temporary object.
+        SVal const *X = ExprBindings.lookup(E);
+        if (X)
+          return *X;
+        else
+          return ValMgr.makeIntVal(cast<IntegerLiteral>(E));
+      }
+
+      // Casts where the source and target type are the same
+      // are no-ops.  We blast through these to get the descendant
+      // subexpression that has a value.
+
+      case Stmt::ImplicitCastExprClass:
+      case Stmt::CStyleCastExprClass: {
+        const CastExpr* C = cast<CastExpr>(E);
+        QualType CT = C->getType();
+
+        if (CT->isVoidType())
+          return UnknownVal();
+
+        break;
+      }
+
+        // Handle all other Stmt* using a lookup.
+
+      default:
+        break;
+    };
+
+    break;
+  }
+
+  return LookupExpr(E);
+}
+
+Environment EnvironmentManager::BindExpr(Environment Env, const Stmt *S,
+                                         SVal V, bool Invalidate) {
+  assert(S);
+
+  if (V.isUnknown()) {
+    if (Invalidate)
+      return Environment(F.Remove(Env.ExprBindings, S));
+    else
+      return Env;
+  }
+
+  return Environment(F.Add(Env.ExprBindings, S, V));
+}
+
+namespace {
+class MarkLiveCallback : public SymbolVisitor {
+  SymbolReaper &SymReaper;
+public:
+  MarkLiveCallback(SymbolReaper &symreaper) : SymReaper(symreaper) {}
+  bool VisitSymbol(SymbolRef sym) { SymReaper.markLive(sym); return true; }
+};
+} // end anonymous namespace
+
+static bool isBlockExprInCallers(const Stmt *E, const LocationContext *LC) {
+  const LocationContext *ParentLC = LC->getParent();
+  while (ParentLC) {
+    CFG &C = *ParentLC->getCFG();
+    if (C.isBlkExpr(E))
+      return true;
+    ParentLC = ParentLC->getParent();
+  }
+
+  return false;
+}
+
+
+// RemoveDeadBindings:
+//  - Remove subexpression bindings.
+//  - Remove dead block expression bindings.
+//  - Keep live block expression bindings:
+//   - Mark their reachable symbols live in SymbolReaper,
+//     see ScanReachableSymbols.
+//   - Mark the region in DRoots if the binding is a loc::MemRegionVal.
+
+Environment
+EnvironmentManager::RemoveDeadBindings(Environment Env, const Stmt *S,
+                                       SymbolReaper &SymReaper,
+                                       const GRState *ST,
+                              llvm::SmallVectorImpl<const MemRegion*> &DRoots) {
+
+  CFG &C = *SymReaper.getLocationContext()->getCFG();
+
+  // We construct a new Environment object entirely, as this is cheaper than
+  // individually removing all the subexpression bindings (which will greatly
+  // outnumber block-level expression bindings).
+  Environment NewEnv = getInitialEnvironment();
+
+  // Iterate over the block-expr bindings.
+  for (Environment::iterator I = Env.begin(), E = Env.end();
+       I != E; ++I) {
+
+    const Stmt *BlkExpr = I.getKey();
+    const SVal &X = I.getData();
+
+    // Block-level expressions in callers are assumed always live.
+    if (isBlockExprInCallers(BlkExpr, SymReaper.getLocationContext())) {
+      NewEnv.ExprBindings = F.Add(NewEnv.ExprBindings, BlkExpr, X);
+
+      if (isa<loc::MemRegionVal>(X)) {
+        const MemRegion* R = cast<loc::MemRegionVal>(X).getRegion();
+        DRoots.push_back(R);
+      }
+
+      // Mark all symbols in the block expr's value live.
+      MarkLiveCallback cb(SymReaper);
+      ST->scanReachableSymbols(X, cb);
+      continue;
+    }
+
+    // Not a block-level expression?
+    if (!C.isBlkExpr(BlkExpr))
+      continue;
+
+    if (SymReaper.isLive(S, BlkExpr)) {
+      // Copy the binding to the new map.
+      NewEnv.ExprBindings = F.Add(NewEnv.ExprBindings, BlkExpr, X);
+
+      // If the block expr's value is a memory region, then mark that region.
+      if (isa<loc::MemRegionVal>(X)) {
+        const MemRegion* R = cast<loc::MemRegionVal>(X).getRegion();
+        DRoots.push_back(R);
+      }
+
+      // Mark all symbols in the block expr's value live.
+      MarkLiveCallback cb(SymReaper);
+      ST->scanReachableSymbols(X, cb);
+      continue;
+    }
+
+    // Otherwise the expression is dead with a couple exceptions.
+    // Do not misclean LogicalExpr or ConditionalOperator.  It is dead at the
+    // beginning of itself, but we need its UndefinedVal to determine its
+    // SVal.
+    if (X.isUndef() && cast<UndefinedVal>(X).getData())
+      NewEnv.ExprBindings = F.Add(NewEnv.ExprBindings, BlkExpr, X);
+  }
+
+  return NewEnv;
+}
diff --git a/lib/Checker/ExplodedGraph.cpp b/lib/Checker/ExplodedGraph.cpp
new file mode 100644
index 0000000..20429b9
--- /dev/null
+++ b/lib/Checker/ExplodedGraph.cpp
@@ -0,0 +1,281 @@
+//=-- ExplodedGraph.cpp - Local, Path-Sens. "Exploded Graph" -*- C++ -*------=//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the template classes ExplodedNode and ExplodedGraph,
+//  which represent a path-sensitive, intra-procedural "exploded graph."
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Checker/PathSensitive/ExplodedGraph.h"
+#include "clang/Checker/PathSensitive/GRState.h"
+#include "clang/AST/Stmt.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVector.h"
+#include <vector>
+
+using namespace clang;
+
+//===----------------------------------------------------------------------===//
+// Node auditing.
+//===----------------------------------------------------------------------===//
+
+// An out of line virtual method to provide a home for the class vtable.
+ExplodedNode::Auditor::~Auditor() {}
+
+#ifndef NDEBUG
+static ExplodedNode::Auditor* NodeAuditor = 0;
+#endif
+
+void ExplodedNode::SetAuditor(ExplodedNode::Auditor* A) {
+#ifndef NDEBUG
+  NodeAuditor = A;
+#endif
+}
+
+//===----------------------------------------------------------------------===//
+// ExplodedNode.
+//===----------------------------------------------------------------------===//
+
+static inline BumpVector<ExplodedNode*>& getVector(void* P) {
+  return *reinterpret_cast<BumpVector<ExplodedNode*>*>(P);
+}
+
+void ExplodedNode::addPredecessor(ExplodedNode* V, ExplodedGraph &G) {
+  assert (!V->isSink());
+  Preds.addNode(V, G);
+  V->Succs.addNode(this, G);
+#ifndef NDEBUG
+  if (NodeAuditor) NodeAuditor->AddEdge(V, this);
+#endif
+}
+
+void ExplodedNode::NodeGroup::addNode(ExplodedNode* N, ExplodedGraph &G) {
+  assert((reinterpret_cast<uintptr_t>(N) & Mask) == 0x0);
+  assert(!getFlag());
+
+  if (getKind() == Size1) {
+    if (ExplodedNode* NOld = getNode()) {
+      BumpVectorContext &Ctx = G.getNodeAllocator();
+      BumpVector<ExplodedNode*> *V = 
+        G.getAllocator().Allocate<BumpVector<ExplodedNode*> >();
+      new (V) BumpVector<ExplodedNode*>(Ctx, 4);
+      
+      assert((reinterpret_cast<uintptr_t>(V) & Mask) == 0x0);
+      V->push_back(NOld, Ctx);
+      V->push_back(N, Ctx);
+      P = reinterpret_cast<uintptr_t>(V) | SizeOther;
+      assert(getPtr() == (void*) V);
+      assert(getKind() == SizeOther);
+    }
+    else {
+      P = reinterpret_cast<uintptr_t>(N);
+      assert(getKind() == Size1);
+    }
+  }
+  else {
+    assert(getKind() == SizeOther);
+    getVector(getPtr()).push_back(N, G.getNodeAllocator());
+  }
+}
+
+unsigned ExplodedNode::NodeGroup::size() const {
+  if (getFlag())
+    return 0;
+
+  if (getKind() == Size1)
+    return getNode() ? 1 : 0;
+  else
+    return getVector(getPtr()).size();
+}
+
+ExplodedNode **ExplodedNode::NodeGroup::begin() const {
+  if (getFlag())
+    return NULL;
+
+  if (getKind() == Size1)
+    return (ExplodedNode**) (getPtr() ? &P : NULL);
+  else
+    return const_cast<ExplodedNode**>(&*(getVector(getPtr()).begin()));
+}
+
+ExplodedNode** ExplodedNode::NodeGroup::end() const {
+  if (getFlag())
+    return NULL;
+
+  if (getKind() == Size1)
+    return (ExplodedNode**) (getPtr() ? &P+1 : NULL);
+  else {
+    // Dereferencing end() is undefined behaviour. The vector is not empty, so
+    // we can dereference the last elem and then add 1 to the result.
+    return const_cast<ExplodedNode**>(getVector(getPtr()).end());
+  }
+}
+
+ExplodedNode *ExplodedGraph::getNode(const ProgramPoint& L,
+                                     const GRState* State, bool* IsNew) {
+  // Profile 'State' to determine if we already have an existing node.
+  llvm::FoldingSetNodeID profile;
+  void* InsertPos = 0;
+
+  NodeTy::Profile(profile, L, State);
+  NodeTy* V = Nodes.FindNodeOrInsertPos(profile, InsertPos);
+
+  if (!V) {
+    // Allocate a new node.
+    V = (NodeTy*) getAllocator().Allocate<NodeTy>();
+    new (V) NodeTy(L, State);
+
+    // Insert the node into the node set and return it.
+    Nodes.InsertNode(V, InsertPos);
+
+    ++NumNodes;
+
+    if (IsNew) *IsNew = true;
+  }
+  else
+    if (IsNew) *IsNew = false;
+
+  return V;
+}
+
+std::pair<ExplodedGraph*, InterExplodedGraphMap*>
+ExplodedGraph::Trim(const NodeTy* const* NBeg, const NodeTy* const* NEnd,
+               llvm::DenseMap<const void*, const void*> *InverseMap) const {
+
+  if (NBeg == NEnd)
+    return std::make_pair((ExplodedGraph*) 0,
+                          (InterExplodedGraphMap*) 0);
+
+  assert (NBeg < NEnd);
+
+  llvm::OwningPtr<InterExplodedGraphMap> M(new InterExplodedGraphMap());
+
+  ExplodedGraph* G = TrimInternal(NBeg, NEnd, M.get(), InverseMap);
+
+  return std::make_pair(static_cast<ExplodedGraph*>(G), M.take());
+}
+
+ExplodedGraph*
+ExplodedGraph::TrimInternal(const ExplodedNode* const* BeginSources,
+                            const ExplodedNode* const* EndSources,
+                            InterExplodedGraphMap* M,
+                   llvm::DenseMap<const void*, const void*> *InverseMap) const {
+
+  typedef llvm::DenseSet<const ExplodedNode*> Pass1Ty;
+  Pass1Ty Pass1;
+
+  typedef llvm::DenseMap<const ExplodedNode*, ExplodedNode*> Pass2Ty;
+  Pass2Ty& Pass2 = M->M;
+
+  llvm::SmallVector<const ExplodedNode*, 10> WL1, WL2;
+
+  // ===- Pass 1 (reverse DFS) -===
+  for (const ExplodedNode* const* I = BeginSources; I != EndSources; ++I) {
+    assert(*I);
+    WL1.push_back(*I);
+  }
+
+  // Process the first worklist until it is empty.  Because it is a std::list
+  // it acts like a FIFO queue.
+  while (!WL1.empty()) {
+    const ExplodedNode *N = WL1.back();
+    WL1.pop_back();
+
+    // Have we already visited this node?  If so, continue to the next one.
+    if (Pass1.count(N))
+      continue;
+
+    // Otherwise, mark this node as visited.
+    Pass1.insert(N);
+
+    // If this is a root enqueue it to the second worklist.
+    if (N->Preds.empty()) {
+      WL2.push_back(N);
+      continue;
+    }
+
+    // Visit our predecessors and enqueue them.
+    for (ExplodedNode** I=N->Preds.begin(), **E=N->Preds.end(); I!=E; ++I)
+      WL1.push_back(*I);
+  }
+
+  // We didn't hit a root? Return with a null pointer for the new graph.
+  if (WL2.empty())
+    return 0;
+
+  // Create an empty graph.
+  ExplodedGraph* G = MakeEmptyGraph();
+
+  // ===- Pass 2 (forward DFS to construct the new graph) -===
+  while (!WL2.empty()) {
+    const ExplodedNode* N = WL2.back();
+    WL2.pop_back();
+
+    // Skip this node if we have already processed it.
+    if (Pass2.find(N) != Pass2.end())
+      continue;
+
+    // Create the corresponding node in the new graph and record the mapping
+    // from the old node to the new node.
+    ExplodedNode* NewN = G->getNode(N->getLocation(), N->State, NULL);
+    Pass2[N] = NewN;
+
+    // Also record the reverse mapping from the new node to the old node.
+    if (InverseMap) (*InverseMap)[NewN] = N;
+
+    // If this node is a root, designate it as such in the graph.
+    if (N->Preds.empty())
+      G->addRoot(NewN);
+
+    // In the case that some of the intended predecessors of NewN have already
+    // been created, we should hook them up as predecessors.
+
+    // Walk through the predecessors of 'N' and hook up their corresponding
+    // nodes in the new graph (if any) to the freshly created node.
+    for (ExplodedNode **I=N->Preds.begin(), **E=N->Preds.end(); I!=E; ++I) {
+      Pass2Ty::iterator PI = Pass2.find(*I);
+      if (PI == Pass2.end())
+        continue;
+
+      NewN->addPredecessor(PI->second, *G);
+    }
+
+    // In the case that some of the intended successors of NewN have already
+    // been created, we should hook them up as successors.  Otherwise, enqueue
+    // the new nodes from the original graph that should have nodes created
+    // in the new graph.
+    for (ExplodedNode **I=N->Succs.begin(), **E=N->Succs.end(); I!=E; ++I) {
+      Pass2Ty::iterator PI = Pass2.find(*I);
+      if (PI != Pass2.end()) {
+        PI->second->addPredecessor(NewN, *G);
+        continue;
+      }
+
+      // Enqueue nodes to the worklist that were marked during pass 1.
+      if (Pass1.count(*I))
+        WL2.push_back(*I);
+    }
+
+    // Finally, explictly mark all nodes without any successors as sinks.
+    if (N->isSink())
+      NewN->markAsSink();
+  }
+
+  return G;
+}
+
+ExplodedNode*
+InterExplodedGraphMap::getMappedNode(const ExplodedNode* N) const {
+  llvm::DenseMap<const ExplodedNode*, ExplodedNode*>::const_iterator I =
+    M.find(N);
+
+  return I == M.end() ? 0 : I->second;
+}
+
diff --git a/lib/Checker/FixedAddressChecker.cpp b/lib/Checker/FixedAddressChecker.cpp
new file mode 100644
index 0000000..4fce45b
--- /dev/null
+++ b/lib/Checker/FixedAddressChecker.cpp
@@ -0,0 +1,71 @@
+//=== FixedAddressChecker.cpp - Fixed address usage checker ----*- C++ -*--===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This files defines FixedAddressChecker, a builtin checker that checks for
+// assignment of a fixed address to a pointer.
+// This check corresponds to CWE-587.
+//
+//===----------------------------------------------------------------------===//
+
+#include "GRExprEngineInternalChecks.h"
+#include "clang/Checker/BugReporter/BugType.h"
+#include "clang/Checker/PathSensitive/CheckerVisitor.h"
+
+using namespace clang;
+
+namespace {
+class FixedAddressChecker 
+  : public CheckerVisitor<FixedAddressChecker> {
+  BuiltinBug *BT;
+public:
+  FixedAddressChecker() : BT(0) {}
+  static void *getTag();
+  void PreVisitBinaryOperator(CheckerContext &C, const BinaryOperator *B);
+};
+}
+
+void *FixedAddressChecker::getTag() {
+  static int x;
+  return &x;
+}
+
+void FixedAddressChecker::PreVisitBinaryOperator(CheckerContext &C,
+                                                 const BinaryOperator *B) {
+  // Using a fixed address is not portable because that address will probably
+  // not be valid in all environments or platforms.
+
+  if (B->getOpcode() != BinaryOperator::Assign)
+    return;
+
+  QualType T = B->getType();
+  if (!T->isPointerType())
+    return;
+
+  const GRState *state = C.getState();
+
+  SVal RV = state->getSVal(B->getRHS());
+
+  if (!RV.isConstant() || RV.isZeroConstant())
+    return;
+
+  if (ExplodedNode *N = C.GenerateNode()) {
+    if (!BT)
+      BT = new BuiltinBug("Use fixed address", 
+                          "Using a fixed address is not portable because that "
+                          "address will probably not be valid in all "
+                          "environments or platforms.");
+    RangedBugReport *R = new RangedBugReport(*BT, BT->getDescription(), N);
+    R->addRange(B->getRHS()->getSourceRange());
+    C.EmitReport(R);
+  }
+}
+
+void clang::RegisterFixedAddressChecker(GRExprEngine &Eng) {
+  Eng.registerCheck(new FixedAddressChecker());
+}
diff --git a/lib/Checker/FlatStore.cpp b/lib/Checker/FlatStore.cpp
new file mode 100644
index 0000000..2af9ffa
--- /dev/null
+++ b/lib/Checker/FlatStore.cpp
@@ -0,0 +1,168 @@
+//=== FlatStore.cpp - Flat region-based store model -------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Checker/PathSensitive/GRState.h"
+#include "llvm/ADT/ImmutableIntervalMap.h"
+#include "llvm/Support/ErrorHandling.h"
+
+using namespace clang;
+using llvm::Interval;
+
+// The actual store type.
+typedef llvm::ImmutableIntervalMap<SVal> BindingVal;
+typedef llvm::ImmutableMap<const MemRegion *, BindingVal> RegionBindings;
+
+namespace {
+class FlatStoreManager : public StoreManager {
+  RegionBindings::Factory RBFactory;
+  BindingVal::Factory BVFactory;
+
+public:
+  FlatStoreManager(GRStateManager &mgr) 
+    : StoreManager(mgr), 
+      RBFactory(mgr.getAllocator()), 
+      BVFactory(mgr.getAllocator()) {}
+
+  SVal Retrieve(Store store, Loc L, QualType T);
+  Store Bind(Store store, Loc L, SVal val);
+  Store Remove(Store St, Loc L);
+  Store BindCompoundLiteral(Store store, const CompoundLiteralExpr* cl,
+                            const LocationContext *LC, SVal v);
+
+  Store getInitialStore(const LocationContext *InitLoc) {
+    return RBFactory.GetEmptyMap().getRoot();
+  }
+
+  SubRegionMap *getSubRegionMap(Store store) {
+    return 0;
+  }
+
+  SVal ArrayToPointer(Loc Array);
+  Store RemoveDeadBindings(Store store, Stmt* Loc, 
+                           const StackFrameContext *LCtx,
+                           SymbolReaper& SymReaper,
+                         llvm::SmallVectorImpl<const MemRegion*>& RegionRoots){
+    return store;
+  }
+
+  Store BindDecl(Store store, const VarRegion *VR, SVal initVal);
+
+  Store BindDeclWithNoInit(Store store, const VarRegion *VR);
+
+  typedef llvm::DenseSet<SymbolRef> InvalidatedSymbols;
+  
+  Store InvalidateRegion(Store store, const MemRegion *R, const Expr *E, 
+                         unsigned Count, InvalidatedSymbols *IS);
+
+  void print(Store store, llvm::raw_ostream& Out, const char* nl, 
+             const char *sep);
+  void iterBindings(Store store, BindingsHandler& f);
+
+private:
+  static RegionBindings getRegionBindings(Store store) {
+    return RegionBindings(static_cast<const RegionBindings::TreeTy*>(store));
+  }
+
+  Interval RegionToInterval(const MemRegion *R);
+
+  SVal RetrieveRegionWithNoBinding(const MemRegion *R, QualType T);
+};
+} // end anonymous namespace
+
+StoreManager *clang::CreateFlatStoreManager(GRStateManager &StMgr) {
+  return new FlatStoreManager(StMgr);
+}
+
+SVal FlatStoreManager::Retrieve(Store store, Loc L, QualType T) {
+  const MemRegion *R = cast<loc::MemRegionVal>(L).getRegion();
+  Interval I = RegionToInterval(R);
+  RegionBindings B = getRegionBindings(store);
+  const BindingVal *BV = B.lookup(R);
+  if (BV) {
+    const SVal *V = BVFactory.Lookup(*BV, I);
+    if (V)
+      return *V;
+    else
+      return RetrieveRegionWithNoBinding(R, T);
+  }
+  return RetrieveRegionWithNoBinding(R, T);
+}
+
+SVal FlatStoreManager::RetrieveRegionWithNoBinding(const MemRegion *R,
+                                                   QualType T) {
+  if (R->hasStackNonParametersStorage())
+    return UndefinedVal();
+  else
+    return ValMgr.getRegionValueSymbolVal(cast<TypedRegion>(R));
+}
+
+Store FlatStoreManager::Bind(Store store, Loc L, SVal val) {
+  const MemRegion *R = cast<loc::MemRegionVal>(L).getRegion();
+  RegionBindings B = getRegionBindings(store);
+  const BindingVal *V = B.lookup(R);
+
+  BindingVal BV = BVFactory.GetEmptyMap();
+  if (V)
+    BV = *V;
+
+  Interval I = RegionToInterval(R);
+  BV = BVFactory.Add(BV, I, val);
+  B = RBFactory.Add(B, R, BV);
+  return B.getRoot();
+}
+
+Store FlatStoreManager::Remove(Store store, Loc L) {
+  return store;
+}
+
+Store FlatStoreManager::BindCompoundLiteral(Store store,
+                                            const CompoundLiteralExpr* cl,
+                                            const LocationContext *LC,
+                                            SVal v) {
+  return store;
+}
+
+SVal FlatStoreManager::ArrayToPointer(Loc Array) {
+  return Array;
+}
+
+Store FlatStoreManager::BindDecl(Store store, const VarRegion *VR, 
+                                 SVal initVal) {
+  return store;
+}
+
+Store FlatStoreManager::BindDeclWithNoInit(Store store, const VarRegion *VR) {
+  return store;
+}
+
+Store FlatStoreManager::InvalidateRegion(Store store, const MemRegion *R,
+                                         const Expr *E, unsigned Count,
+                                         InvalidatedSymbols *IS) {
+  return store;
+}
+
+void FlatStoreManager::print(Store store, llvm::raw_ostream& Out, 
+                             const char* nl, const char *sep) {
+}
+
+void FlatStoreManager::iterBindings(Store store, BindingsHandler& f) {
+}
+
+Interval FlatStoreManager::RegionToInterval(const MemRegion *R) { 
+  switch (R->getKind()) {
+  case MemRegion::VarRegionKind: {
+    QualType T = cast<VarRegion>(R)->getValueType(Ctx);
+    uint64_t Size = Ctx.getTypeSize(T);
+    return Interval(0, Size-1);
+  }
+  default:
+    llvm_unreachable("Region kind unhandled.");
+    return Interval(0, 0);
+  }
+}
diff --git a/lib/Checker/GRBlockCounter.cpp b/lib/Checker/GRBlockCounter.cpp
new file mode 100644
index 0000000..cd26060
--- /dev/null
+++ b/lib/Checker/GRBlockCounter.cpp
@@ -0,0 +1,85 @@
+//==- GRBlockCounter.h - ADT for counting block visits -------------*- C++ -*-//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines GRBlockCounter, an abstract data type used to count
+//  the number of times a given block has been visited along a path
+//  analyzed by GRCoreEngine.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Checker/PathSensitive/GRBlockCounter.h"
+#include "llvm/ADT/ImmutableMap.h"
+
+using namespace clang;
+
+namespace {
+
+class CountKey {
+  const StackFrameContext *CallSite;
+  unsigned BlockID;
+
+public:
+  CountKey(const StackFrameContext *CS, unsigned ID) 
+    : CallSite(CS), BlockID(ID) {}
+
+  bool operator==(const CountKey &RHS) const {
+    return (CallSite == RHS.CallSite) && (BlockID == RHS.BlockID);
+  }
+
+  bool operator<(const CountKey &RHS) const {
+    return (CallSite == RHS.CallSite) ? (BlockID < RHS.BlockID) 
+                                      : (CallSite < RHS.CallSite);
+  }
+
+  void Profile(llvm::FoldingSetNodeID &ID) const {
+    ID.AddPointer(CallSite);
+    ID.AddInteger(BlockID);
+  }
+};
+
+}
+
+typedef llvm::ImmutableMap<CountKey, unsigned> CountMap;
+
+static inline CountMap GetMap(void* D) {
+  return CountMap(static_cast<CountMap::TreeTy*>(D));
+}
+
+static inline CountMap::Factory& GetFactory(void* F) {
+  return *static_cast<CountMap::Factory*>(F);
+}
+
+unsigned GRBlockCounter::getNumVisited(const StackFrameContext *CallSite, 
+                                       unsigned BlockID) const {
+  CountMap M = GetMap(Data);
+  CountMap::data_type* T = M.lookup(CountKey(CallSite, BlockID));
+  return T ? *T : 0;
+}
+
+GRBlockCounter::Factory::Factory(llvm::BumpPtrAllocator& Alloc) {
+  F = new CountMap::Factory(Alloc);
+}
+
+GRBlockCounter::Factory::~Factory() {
+  delete static_cast<CountMap::Factory*>(F);
+}
+
+GRBlockCounter
+GRBlockCounter::Factory::IncrementCount(GRBlockCounter BC, 
+                                        const StackFrameContext *CallSite,
+                                        unsigned BlockID) {
+  return GRBlockCounter(GetFactory(F).Add(GetMap(BC.Data), 
+                                          CountKey(CallSite, BlockID),
+                             BC.getNumVisited(CallSite, BlockID)+1).getRoot());
+}
+
+GRBlockCounter
+GRBlockCounter::Factory::GetEmptyCounter() {
+  return GRBlockCounter(GetFactory(F).GetEmptyMap().getRoot());
+}
diff --git a/lib/Checker/GRCXXExprEngine.cpp b/lib/Checker/GRCXXExprEngine.cpp
new file mode 100644
index 0000000..00ac995
--- /dev/null
+++ b/lib/Checker/GRCXXExprEngine.cpp
@@ -0,0 +1,246 @@
+//===- GRCXXExprEngine.cpp - C++ expr evaluation engine ---------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the C++ expression evaluation engine.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Checker/PathSensitive/AnalysisManager.h"
+#include "clang/Checker/PathSensitive/GRExprEngine.h"
+#include "clang/AST/DeclCXX.h"
+
+using namespace clang;
+
+void GRExprEngine::EvalArguments(ExprIterator AI, ExprIterator AE,
+                                 const FunctionProtoType *FnType, 
+                                 ExplodedNode *Pred, ExplodedNodeSet &Dst) {
+  llvm::SmallVector<CallExprWLItem, 20> WorkList;
+  WorkList.reserve(AE - AI);
+  WorkList.push_back(CallExprWLItem(AI, Pred));
+
+  while (!WorkList.empty()) {
+    CallExprWLItem Item = WorkList.back();
+    WorkList.pop_back();
+
+    if (Item.I == AE) {
+      Dst.insert(Item.N);
+      continue;
+    }
+
+    ExplodedNodeSet Tmp;
+    const unsigned ParamIdx = Item.I - AI;
+    bool VisitAsLvalue = FnType? FnType->getArgType(ParamIdx)->isReferenceType()
+                               : false;
+    if (VisitAsLvalue)
+      VisitLValue(*Item.I, Item.N, Tmp);
+    else
+      Visit(*Item.I, Item.N, Tmp);
+
+    ++(Item.I);
+    for (ExplodedNodeSet::iterator NI=Tmp.begin(), NE=Tmp.end(); NI != NE; ++NI)
+      WorkList.push_back(CallExprWLItem(Item.I, *NI));
+  }
+}
+
+const CXXThisRegion *GRExprEngine::getCXXThisRegion(const CXXMethodDecl *D,
+                                                 const StackFrameContext *SFC) {
+  Type *T = D->getParent()->getTypeForDecl();
+  QualType PT = getContext().getPointerType(QualType(T,0));
+  return ValMgr.getRegionManager().getCXXThisRegion(PT, SFC);
+}
+
+void GRExprEngine::CreateCXXTemporaryObject(Expr *Ex, ExplodedNode *Pred,
+                                            ExplodedNodeSet &Dst) {
+  ExplodedNodeSet Tmp;
+  Visit(Ex, Pred, Tmp);
+  for (ExplodedNodeSet::iterator I = Tmp.begin(), E = Tmp.end(); I != E; ++I) {
+    const GRState *state = GetState(*I);
+
+    // Bind the temporary object to the value of the expression. Then bind
+    // the expression to the location of the object.
+    SVal V = state->getSVal(Ex);
+
+    const MemRegion *R =
+      ValMgr.getRegionManager().getCXXObjectRegion(Ex,
+                                                   Pred->getLocationContext());
+
+    state = state->bindLoc(loc::MemRegionVal(R), V);
+    MakeNode(Dst, Ex, Pred, state->BindExpr(Ex, loc::MemRegionVal(R)));
+  }
+}
+
+void GRExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *E, SVal Dest,
+                                         ExplodedNode *Pred,
+                                         ExplodedNodeSet &Dst) {
+  if (E->isElidable()) {
+    VisitAggExpr(E->getArg(0), Dest, Pred, Dst);
+    return;
+  }
+
+  const CXXConstructorDecl *CD = E->getConstructor();
+  assert(CD);
+
+  if (!CD->isThisDeclarationADefinition())
+    // FIXME: invalidate the object.
+    return;
+
+  
+  // Evaluate other arguments.
+  ExplodedNodeSet ArgsEvaluated;
+  const FunctionProtoType *FnType = CD->getType()->getAs<FunctionProtoType>();
+  EvalArguments(const_cast<CXXConstructExpr*>(E)->arg_begin(),
+                const_cast<CXXConstructExpr*>(E)->arg_end(),
+                FnType, Pred, ArgsEvaluated);
+  // The callee stack frame context used to create the 'this' parameter region.
+  const StackFrameContext *SFC = AMgr.getStackFrame(CD, 
+                                                    Pred->getLocationContext(),
+                                   E, Builder->getBlock(), Builder->getIndex());
+
+  const CXXThisRegion *ThisR = getCXXThisRegion(E->getConstructor(), SFC);
+
+  CallEnter Loc(E, CD, Pred->getLocationContext());
+  for (ExplodedNodeSet::iterator NI = ArgsEvaluated.begin(),
+                                 NE = ArgsEvaluated.end(); NI != NE; ++NI) {
+    const GRState *state = GetState(*NI);
+    // Setup 'this' region.
+    state = state->bindLoc(loc::MemRegionVal(ThisR), Dest);
+    ExplodedNode *N = Builder->generateNode(Loc, state, Pred);
+    if (N)
+      Dst.Add(N);
+  }
+}
+
+void GRExprEngine::VisitCXXMemberCallExpr(const CXXMemberCallExpr *MCE, 
+                                          ExplodedNode *Pred, 
+                                          ExplodedNodeSet &Dst) {
+  // Get the method type.
+  const FunctionProtoType *FnType = 
+                       MCE->getCallee()->getType()->getAs<FunctionProtoType>();
+  assert(FnType && "Method type not available");
+
+  // Evaluate explicit arguments with a worklist.
+  ExplodedNodeSet ArgsEvaluated;
+  EvalArguments(const_cast<CXXMemberCallExpr*>(MCE)->arg_begin(),
+                const_cast<CXXMemberCallExpr*>(MCE)->arg_end(),
+                FnType, Pred, ArgsEvaluated);
+ 
+  // Evaluate the implicit object argument.
+  ExplodedNodeSet AllArgsEvaluated;
+  const MemberExpr *ME = dyn_cast<MemberExpr>(MCE->getCallee()->IgnoreParens());
+  if (!ME)
+    return;
+  Expr *ObjArgExpr = ME->getBase();
+  for (ExplodedNodeSet::iterator I = ArgsEvaluated.begin(), 
+                                 E = ArgsEvaluated.end(); I != E; ++I) {
+    if (ME->isArrow())
+      Visit(ObjArgExpr, *I, AllArgsEvaluated);
+    else
+      VisitLValue(ObjArgExpr, *I, AllArgsEvaluated);
+  }
+
+  const CXXMethodDecl *MD = cast<CXXMethodDecl>(ME->getMemberDecl());
+  assert(MD && "not a CXXMethodDecl?");
+
+  if (!MD->isThisDeclarationADefinition())
+    // FIXME: conservative method call evaluation.
+    return;
+
+  const StackFrameContext *SFC = AMgr.getStackFrame(MD, 
+                                                    Pred->getLocationContext(),
+                                                    MCE, 
+                                                    Builder->getBlock(), 
+                                                    Builder->getIndex());
+  const CXXThisRegion *ThisR = getCXXThisRegion(MD, SFC);
+  CallEnter Loc(MCE, MD, Pred->getLocationContext());
+  for (ExplodedNodeSet::iterator I = AllArgsEvaluated.begin(),
+         E = AllArgsEvaluated.end(); I != E; ++I) {
+    // Set up 'this' region.
+    const GRState *state = GetState(*I);
+    state = state->bindLoc(loc::MemRegionVal(ThisR),state->getSVal(ObjArgExpr));
+    ExplodedNode *N = Builder->generateNode(Loc, state, *I);
+    if (N)
+      Dst.Add(N);
+  }
+}
+
+void GRExprEngine::VisitCXXNewExpr(CXXNewExpr *CNE, ExplodedNode *Pred,
+                                   ExplodedNodeSet &Dst) {
+  if (CNE->isArray()) {
+    // FIXME: allocating an array has not been handled.
+    return;
+  }
+
+  unsigned Count = Builder->getCurrentBlockCount();
+  DefinedOrUnknownSVal SymVal = getValueManager().getConjuredSymbolVal(NULL,CNE, 
+                                                         CNE->getType(), Count);
+  const MemRegion *NewReg = cast<loc::MemRegionVal>(SymVal).getRegion();
+
+  QualType ObjTy = CNE->getType()->getAs<PointerType>()->getPointeeType();
+
+  const ElementRegion *EleReg = 
+                         getStoreManager().GetElementZeroRegion(NewReg, ObjTy);
+
+  // Evaluate constructor arguments.
+  const FunctionProtoType *FnType = NULL;
+  const CXXConstructorDecl *CD = CNE->getConstructor();
+  if (CD)
+    FnType = CD->getType()->getAs<FunctionProtoType>();
+  ExplodedNodeSet ArgsEvaluated;
+  EvalArguments(CNE->constructor_arg_begin(), CNE->constructor_arg_end(),
+                FnType, Pred, ArgsEvaluated);
+
+  // Initialize the object region and bind the 'new' expression.
+  for (ExplodedNodeSet::iterator I = ArgsEvaluated.begin(), 
+                                 E = ArgsEvaluated.end(); I != E; ++I) {
+    const GRState *state = GetState(*I);
+
+    if (ObjTy->isRecordType()) {
+      Store store = state->getStore();
+      StoreManager::InvalidatedSymbols IS;
+      store = getStoreManager().InvalidateRegion(store, EleReg, CNE, Count, &IS);
+      state = state->makeWithStore(store);
+    } else {
+      if (CNE->hasInitializer()) {
+        SVal V = state->getSVal(*CNE->constructor_arg_begin());
+        state = state->bindLoc(loc::MemRegionVal(EleReg), V);
+      } else {
+        // Explicitly set to undefined, because currently we retrieve symbolic
+        // value from symbolic region.
+        state = state->bindLoc(loc::MemRegionVal(EleReg), UndefinedVal());
+      }
+    }
+    state = state->BindExpr(CNE, loc::MemRegionVal(EleReg));
+    MakeNode(Dst, CNE, *I, state);
+  }
+}
+
+void GRExprEngine::VisitCXXDeleteExpr(CXXDeleteExpr *CDE, ExplodedNode *Pred,
+                                      ExplodedNodeSet &Dst) {
+  // Should do more checking.
+  ExplodedNodeSet ArgEvaluated;
+  Visit(CDE->getArgument(), Pred, ArgEvaluated);
+  for (ExplodedNodeSet::iterator I = ArgEvaluated.begin(), 
+                                 E = ArgEvaluated.end(); I != E; ++I) {
+    const GRState *state = GetState(*I);
+    MakeNode(Dst, CDE, *I, state);
+  }
+}
+
+void GRExprEngine::VisitCXXThisExpr(CXXThisExpr *TE, ExplodedNode *Pred,
+                                    ExplodedNodeSet &Dst) {
+  // Get the this object region from StoreManager.
+  const MemRegion *R =
+    ValMgr.getRegionManager().getCXXThisRegion(
+                                  getContext().getCanonicalType(TE->getType()),
+                                               Pred->getLocationContext());
+
+  const GRState *state = GetState(Pred);
+  SVal V = state->getSVal(loc::MemRegionVal(R));
+  MakeNode(Dst, TE, Pred, state->BindExpr(TE, V));
+}
diff --git a/lib/Checker/GRCoreEngine.cpp b/lib/Checker/GRCoreEngine.cpp
new file mode 100644
index 0000000..23a87d3
--- /dev/null
+++ b/lib/Checker/GRCoreEngine.cpp
@@ -0,0 +1,722 @@
+//==- GRCoreEngine.cpp - Path-Sensitive Dataflow Engine ------------*- C++ -*-//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines a generic engine for intraprocedural, path-sensitive,
+//  dataflow analysis via graph reachability engine.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Checker/PathSensitive/GRCoreEngine.h"
+#include "clang/Checker/PathSensitive/GRExprEngine.h"
+#include "clang/AST/Expr.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/ADT/DenseMap.h"
+#include <vector>
+#include <queue>
+
+using llvm::cast;
+using llvm::isa;
+using namespace clang;
+
+//===----------------------------------------------------------------------===//
+// Worklist classes for exploration of reachable states.
+//===----------------------------------------------------------------------===//
+
+namespace {
+class DFS : public GRWorkList {
+  llvm::SmallVector<GRWorkListUnit,20> Stack;
+public:
+  virtual bool hasWork() const {
+    return !Stack.empty();
+  }
+
+  virtual void Enqueue(const GRWorkListUnit& U) {
+    Stack.push_back(U);
+  }
+
+  virtual GRWorkListUnit Dequeue() {
+    assert (!Stack.empty());
+    const GRWorkListUnit& U = Stack.back();
+    Stack.pop_back(); // This technically "invalidates" U, but we are fine.
+    return U;
+  }
+};
+
+class BFS : public GRWorkList {
+  std::queue<GRWorkListUnit> Queue;
+public:
+  virtual bool hasWork() const {
+    return !Queue.empty();
+  }
+
+  virtual void Enqueue(const GRWorkListUnit& U) {
+    Queue.push(U);
+  }
+
+  virtual GRWorkListUnit Dequeue() {
+    // Don't use const reference.  The subsequent pop_back() might make it
+    // unsafe.
+    GRWorkListUnit U = Queue.front();
+    Queue.pop();
+    return U;
+  }
+};
+
+} // end anonymous namespace
+
+// Place the dstor for GRWorkList here because it contains virtual member
+// functions, and we the code for the dstor generated in one compilation unit.
+GRWorkList::~GRWorkList() {}
+
+GRWorkList *GRWorkList::MakeDFS() { return new DFS(); }
+GRWorkList *GRWorkList::MakeBFS() { return new BFS(); }
+
+namespace {
+  class BFSBlockDFSContents : public GRWorkList {
+    std::queue<GRWorkListUnit> Queue;
+    llvm::SmallVector<GRWorkListUnit,20> Stack;
+  public:
+    virtual bool hasWork() const {
+      return !Queue.empty() || !Stack.empty();
+    }
+
+    virtual void Enqueue(const GRWorkListUnit& U) {
+      if (isa<BlockEntrance>(U.getNode()->getLocation()))
+        Queue.push(U);
+      else
+        Stack.push_back(U);
+    }
+
+    virtual GRWorkListUnit Dequeue() {
+      // Process all basic blocks to completion.
+      if (!Stack.empty()) {
+        const GRWorkListUnit& U = Stack.back();
+        Stack.pop_back(); // This technically "invalidates" U, but we are fine.
+        return U;
+      }
+
+      assert(!Queue.empty());
+      // Don't use const reference.  The subsequent pop_back() might make it
+      // unsafe.
+      GRWorkListUnit U = Queue.front();
+      Queue.pop();
+      return U;
+    }
+  };
+} // end anonymous namespace
+
+GRWorkList* GRWorkList::MakeBFSBlockDFSContents() {
+  return new BFSBlockDFSContents();
+}
+
+//===----------------------------------------------------------------------===//
+// Core analysis engine.
+//===----------------------------------------------------------------------===//
+void GRCoreEngine::ProcessEndPath(GREndPathNodeBuilder& Builder) {
+  SubEngine.ProcessEndPath(Builder);
+}
+
+void GRCoreEngine::ProcessStmt(CFGElement E, GRStmtNodeBuilder& Builder) {
+  SubEngine.ProcessStmt(E, Builder);
+}
+
+bool GRCoreEngine::ProcessBlockEntrance(CFGBlock* Blk, const ExplodedNode *Pred,
+                                        GRBlockCounter BC) {
+  return SubEngine.ProcessBlockEntrance(Blk, Pred, BC);
+}
+
+void GRCoreEngine::ProcessBranch(Stmt* Condition, Stmt* Terminator,
+                   GRBranchNodeBuilder& Builder) {
+  SubEngine.ProcessBranch(Condition, Terminator, Builder);
+}
+
+void GRCoreEngine::ProcessIndirectGoto(GRIndirectGotoNodeBuilder& Builder) {
+  SubEngine.ProcessIndirectGoto(Builder);
+}
+
+void GRCoreEngine::ProcessSwitch(GRSwitchNodeBuilder& Builder) {
+  SubEngine.ProcessSwitch(Builder);
+}
+
+void GRCoreEngine::ProcessCallEnter(GRCallEnterNodeBuilder &Builder) {
+  SubEngine.ProcessCallEnter(Builder);
+}
+
+void GRCoreEngine::ProcessCallExit(GRCallExitNodeBuilder &Builder) {
+  SubEngine.ProcessCallExit(Builder);
+}
+
+/// ExecuteWorkList - Run the worklist algorithm for a maximum number of steps.
+bool GRCoreEngine::ExecuteWorkList(const LocationContext *L, unsigned Steps) {
+
+  if (G->num_roots() == 0) { // Initialize the analysis by constructing
+    // the root if none exists.
+
+    CFGBlock* Entry = &(L->getCFG()->getEntry());
+
+    assert (Entry->empty() &&
+            "Entry block must be empty.");
+
+    assert (Entry->succ_size() == 1 &&
+            "Entry block must have 1 successor.");
+
+    // Get the solitary successor.
+    CFGBlock* Succ = *(Entry->succ_begin());
+
+    // Construct an edge representing the
+    // starting location in the function.
+    BlockEdge StartLoc(Entry, Succ, L);
+
+    // Set the current block counter to being empty.
+    WList->setBlockCounter(BCounterFactory.GetEmptyCounter());
+
+    // Generate the root.
+    GenerateNode(StartLoc, getInitialState(L), 0);
+  }
+
+  while (Steps && WList->hasWork()) {
+    --Steps;
+    const GRWorkListUnit& WU = WList->Dequeue();
+
+    // Set the current block counter.
+    WList->setBlockCounter(WU.getBlockCounter());
+
+    // Retrieve the node.
+    ExplodedNode* Node = WU.getNode();
+
+    // Dispatch on the location type.
+    switch (Node->getLocation().getKind()) {
+      case ProgramPoint::BlockEdgeKind:
+        HandleBlockEdge(cast<BlockEdge>(Node->getLocation()), Node);
+        break;
+
+      case ProgramPoint::BlockEntranceKind:
+        HandleBlockEntrance(cast<BlockEntrance>(Node->getLocation()), Node);
+        break;
+
+      case ProgramPoint::BlockExitKind:
+        assert (false && "BlockExit location never occur in forward analysis.");
+        break;
+
+      case ProgramPoint::CallEnterKind:
+        HandleCallEnter(cast<CallEnter>(Node->getLocation()), WU.getBlock(), 
+                        WU.getIndex(), Node);
+        break;
+
+      case ProgramPoint::CallExitKind:
+        HandleCallExit(cast<CallExit>(Node->getLocation()), Node);
+        break;
+
+      default:
+        assert(isa<PostStmt>(Node->getLocation()));
+        HandlePostStmt(cast<PostStmt>(Node->getLocation()), WU.getBlock(),
+                       WU.getIndex(), Node);
+        break;
+    }
+  }
+
+  return WList->hasWork();
+}
+
+void GRCoreEngine::HandleCallEnter(const CallEnter &L, const CFGBlock *Block,
+                                   unsigned Index, ExplodedNode *Pred) {
+  GRCallEnterNodeBuilder Builder(*this, Pred, L.getCallExpr(), L.getCallee(), 
+                                 Block, Index);
+  ProcessCallEnter(Builder);
+}
+
+void GRCoreEngine::HandleCallExit(const CallExit &L, ExplodedNode *Pred) {
+  GRCallExitNodeBuilder Builder(*this, Pred);
+  ProcessCallExit(Builder);
+}
+
+void GRCoreEngine::HandleBlockEdge(const BlockEdge& L, ExplodedNode* Pred) {
+
+  CFGBlock* Blk = L.getDst();
+
+  // Check if we are entering the EXIT block.
+  if (Blk == &(L.getLocationContext()->getCFG()->getExit())) {
+
+    assert (L.getLocationContext()->getCFG()->getExit().size() == 0
+            && "EXIT block cannot contain Stmts.");
+
+    // Process the final state transition.
+    GREndPathNodeBuilder Builder(Blk, Pred, this);
+    ProcessEndPath(Builder);
+
+    // This path is done. Don't enqueue any more nodes.
+    return;
+  }
+
+  // FIXME: Should we allow ProcessBlockEntrance to also manipulate state?
+
+  if (ProcessBlockEntrance(Blk, Pred, WList->getBlockCounter()))
+    GenerateNode(BlockEntrance(Blk, Pred->getLocationContext()), Pred->State, Pred);
+}
+
+void GRCoreEngine::HandleBlockEntrance(const BlockEntrance& L,
+                                       ExplodedNode* Pred) {
+
+  // Increment the block counter.
+  GRBlockCounter Counter = WList->getBlockCounter();
+  Counter = BCounterFactory.IncrementCount(Counter, 
+                             Pred->getLocationContext()->getCurrentStackFrame(),
+                                           L.getBlock()->getBlockID());
+  WList->setBlockCounter(Counter);
+
+  // Process the entrance of the block.
+  if (CFGElement E = L.getFirstElement()) {
+    GRStmtNodeBuilder Builder(L.getBlock(), 0, Pred, this,
+                              SubEngine.getStateManager());
+    ProcessStmt(E, Builder);
+  }
+  else
+    HandleBlockExit(L.getBlock(), Pred);
+}
+
+void GRCoreEngine::HandleBlockExit(CFGBlock * B, ExplodedNode* Pred) {
+
+  if (Stmt* Term = B->getTerminator()) {
+    switch (Term->getStmtClass()) {
+      default:
+        assert(false && "Analysis for this terminator not implemented.");
+        break;
+
+      case Stmt::BinaryOperatorClass: // '&&' and '||'
+        HandleBranch(cast<BinaryOperator>(Term)->getLHS(), Term, B, Pred);
+        return;
+
+      case Stmt::ConditionalOperatorClass:
+        HandleBranch(cast<ConditionalOperator>(Term)->getCond(), Term, B, Pred);
+        return;
+
+        // FIXME: Use constant-folding in CFG construction to simplify this
+        // case.
+
+      case Stmt::ChooseExprClass:
+        HandleBranch(cast<ChooseExpr>(Term)->getCond(), Term, B, Pred);
+        return;
+
+      case Stmt::DoStmtClass:
+        HandleBranch(cast<DoStmt>(Term)->getCond(), Term, B, Pred);
+        return;
+
+      case Stmt::ForStmtClass:
+        HandleBranch(cast<ForStmt>(Term)->getCond(), Term, B, Pred);
+        return;
+
+      case Stmt::ContinueStmtClass:
+      case Stmt::BreakStmtClass:
+      case Stmt::GotoStmtClass:
+        break;
+
+      case Stmt::IfStmtClass:
+        HandleBranch(cast<IfStmt>(Term)->getCond(), Term, B, Pred);
+        return;
+
+      case Stmt::IndirectGotoStmtClass: {
+        // Only 1 successor: the indirect goto dispatch block.
+        assert (B->succ_size() == 1);
+
+        GRIndirectGotoNodeBuilder
+           builder(Pred, B, cast<IndirectGotoStmt>(Term)->getTarget(),
+                   *(B->succ_begin()), this);
+
+        ProcessIndirectGoto(builder);
+        return;
+      }
+
+      case Stmt::ObjCForCollectionStmtClass: {
+        // In the case of ObjCForCollectionStmt, it appears twice in a CFG:
+        //
+        //  (1) inside a basic block, which represents the binding of the
+        //      'element' variable to a value.
+        //  (2) in a terminator, which represents the branch.
+        //
+        // For (1), subengines will bind a value (i.e., 0 or 1) indicating
+        // whether or not collection contains any more elements.  We cannot
+        // just test to see if the element is nil because a container can
+        // contain nil elements.
+        HandleBranch(Term, Term, B, Pred);
+        return;
+      }
+
+      case Stmt::SwitchStmtClass: {
+        GRSwitchNodeBuilder builder(Pred, B, cast<SwitchStmt>(Term)->getCond(),
+                                    this);
+
+        ProcessSwitch(builder);
+        return;
+      }
+
+      case Stmt::WhileStmtClass:
+        HandleBranch(cast<WhileStmt>(Term)->getCond(), Term, B, Pred);
+        return;
+    }
+  }
+
+  assert (B->succ_size() == 1 &&
+          "Blocks with no terminator should have at most 1 successor.");
+
+  GenerateNode(BlockEdge(B, *(B->succ_begin()), Pred->getLocationContext()),
+               Pred->State, Pred);
+}
+
+void GRCoreEngine::HandleBranch(Stmt* Cond, Stmt* Term, CFGBlock * B,
+                                ExplodedNode* Pred) {
+  assert (B->succ_size() == 2);
+
+  GRBranchNodeBuilder Builder(B, *(B->succ_begin()), *(B->succ_begin()+1),
+                              Pred, this);
+
+  ProcessBranch(Cond, Term, Builder);
+}
+
+void GRCoreEngine::HandlePostStmt(const PostStmt& L, CFGBlock* B,
+                                  unsigned StmtIdx, ExplodedNode* Pred) {
+
+  assert (!B->empty());
+
+  if (StmtIdx == B->size())
+    HandleBlockExit(B, Pred);
+  else {
+    GRStmtNodeBuilder Builder(B, StmtIdx, Pred, this,
+                              SubEngine.getStateManager());
+    ProcessStmt((*B)[StmtIdx], Builder);
+  }
+}
+
+/// GenerateNode - Utility method to generate nodes, hook up successors,
+///  and add nodes to the worklist.
+void GRCoreEngine::GenerateNode(const ProgramPoint& Loc,
+                                const GRState* State, ExplodedNode* Pred) {
+
+  bool IsNew;
+  ExplodedNode* Node = G->getNode(Loc, State, &IsNew);
+
+  if (Pred)
+    Node->addPredecessor(Pred, *G);  // Link 'Node' with its predecessor.
+  else {
+    assert (IsNew);
+    G->addRoot(Node);  // 'Node' has no predecessor.  Make it a root.
+  }
+
+  // Only add 'Node' to the worklist if it was freshly generated.
+  if (IsNew) WList->Enqueue(Node);
+}
+
+GRStmtNodeBuilder::GRStmtNodeBuilder(CFGBlock* b, unsigned idx,
+                                     ExplodedNode* N, GRCoreEngine* e,
+                                     GRStateManager &mgr)
+  : Eng(*e), B(*b), Idx(idx), Pred(N), Mgr(mgr), Auditor(0),
+    PurgingDeadSymbols(false), BuildSinks(false), HasGeneratedNode(false),
+    PointKind(ProgramPoint::PostStmtKind), Tag(0) {
+  Deferred.insert(N);
+  CleanedState = Pred->getState();
+}
+
+GRStmtNodeBuilder::~GRStmtNodeBuilder() {
+  for (DeferredTy::iterator I=Deferred.begin(), E=Deferred.end(); I!=E; ++I)
+    if (!(*I)->isSink())
+      GenerateAutoTransition(*I);
+}
+
+void GRStmtNodeBuilder::GenerateAutoTransition(ExplodedNode* N) {
+  assert (!N->isSink());
+
+  // Check if this node entered a callee.
+  if (isa<CallEnter>(N->getLocation())) {
+    // Still use the index of the CallExpr. It's needed to create the callee
+    // StackFrameContext.
+    Eng.WList->Enqueue(N, B, Idx);
+    return;
+  }
+
+  PostStmt Loc(getStmt(), N->getLocationContext());
+
+  if (Loc == N->getLocation()) {
+    // Note: 'N' should be a fresh node because otherwise it shouldn't be
+    // a member of Deferred.
+    Eng.WList->Enqueue(N, B, Idx+1);
+    return;
+  }
+
+  bool IsNew;
+  ExplodedNode* Succ = Eng.G->getNode(Loc, N->State, &IsNew);
+  Succ->addPredecessor(N, *Eng.G);
+
+  if (IsNew)
+    Eng.WList->Enqueue(Succ, B, Idx+1);
+}
+
+ExplodedNode* GRStmtNodeBuilder::MakeNode(ExplodedNodeSet& Dst, Stmt* S, 
+                                          ExplodedNode* Pred, const GRState* St,
+                                          ProgramPoint::Kind K) {
+  const GRState* PredState = GetState(Pred);
+
+  // If the state hasn't changed, don't generate a new node.
+  if (!BuildSinks && St == PredState && Auditor == 0) {
+    Dst.Add(Pred);
+    return NULL;
+  }
+
+  ExplodedNode* N = generateNode(S, St, Pred, K);
+
+  if (N) {
+    if (BuildSinks)
+      N->markAsSink();
+    else {
+      if (Auditor && Auditor->Audit(N, Mgr))
+        N->markAsSink();
+      
+      Dst.Add(N);
+    }
+  }
+  
+  return N;
+}
+
+static ProgramPoint GetProgramPoint(const Stmt *S, ProgramPoint::Kind K,
+                                    const LocationContext *LC, const void *tag){
+  switch (K) {
+    default:
+      assert(false && "Unhandled ProgramPoint kind");    
+    case ProgramPoint::PreStmtKind:
+      return PreStmt(S, LC, tag);
+    case ProgramPoint::PostStmtKind:
+      return PostStmt(S, LC, tag);
+    case ProgramPoint::PreLoadKind:
+      return PreLoad(S, LC, tag);
+    case ProgramPoint::PostLoadKind:
+      return PostLoad(S, LC, tag);
+    case ProgramPoint::PreStoreKind:
+      return PreStore(S, LC, tag);
+    case ProgramPoint::PostStoreKind:
+      return PostStore(S, LC, tag);
+    case ProgramPoint::PostLValueKind:
+      return PostLValue(S, LC, tag);
+    case ProgramPoint::PostPurgeDeadSymbolsKind:
+      return PostPurgeDeadSymbols(S, LC, tag);
+  }
+}
+
+ExplodedNode*
+GRStmtNodeBuilder::generateNodeInternal(const Stmt* S, const GRState* state,
+                                        ExplodedNode* Pred,
+                                        ProgramPoint::Kind K,
+                                        const void *tag) {
+  
+  const ProgramPoint &L = GetProgramPoint(S, K, Pred->getLocationContext(),tag);
+  return generateNodeInternal(L, state, Pred);
+}
+
+ExplodedNode*
+GRStmtNodeBuilder::generateNodeInternal(const ProgramPoint &Loc,
+                                        const GRState* State,
+                                        ExplodedNode* Pred) {
+  bool IsNew;
+  ExplodedNode* N = Eng.G->getNode(Loc, State, &IsNew);
+  N->addPredecessor(Pred, *Eng.G);
+  Deferred.erase(Pred);
+
+  if (IsNew) {
+    Deferred.insert(N);
+    return N;
+  }
+
+  return NULL;
+}
+
+ExplodedNode* GRBranchNodeBuilder::generateNode(const GRState* State,
+                                                bool branch) {
+
+  // If the branch has been marked infeasible we should not generate a node.
+  if (!isFeasible(branch))
+    return NULL;
+
+  bool IsNew;
+
+  ExplodedNode* Succ =
+    Eng.G->getNode(BlockEdge(Src,branch ? DstT:DstF,Pred->getLocationContext()),
+                   State, &IsNew);
+
+  Succ->addPredecessor(Pred, *Eng.G);
+
+  if (branch)
+    GeneratedTrue = true;
+  else
+    GeneratedFalse = true;
+
+  if (IsNew) {
+    Deferred.push_back(Succ);
+    return Succ;
+  }
+
+  return NULL;
+}
+
+GRBranchNodeBuilder::~GRBranchNodeBuilder() {
+  if (!GeneratedTrue) generateNode(Pred->State, true);
+  if (!GeneratedFalse) generateNode(Pred->State, false);
+
+  for (DeferredTy::iterator I=Deferred.begin(), E=Deferred.end(); I!=E; ++I)
+    if (!(*I)->isSink()) Eng.WList->Enqueue(*I);
+}
+
+
+ExplodedNode*
+GRIndirectGotoNodeBuilder::generateNode(const iterator& I, const GRState* St,
+                                        bool isSink) {
+  bool IsNew;
+
+  ExplodedNode* Succ = Eng.G->getNode(BlockEdge(Src, I.getBlock(),
+                                      Pred->getLocationContext()), St, &IsNew);
+
+  Succ->addPredecessor(Pred, *Eng.G);
+
+  if (IsNew) {
+
+    if (isSink)
+      Succ->markAsSink();
+    else
+      Eng.WList->Enqueue(Succ);
+
+    return Succ;
+  }
+
+  return NULL;
+}
+
+
+ExplodedNode*
+GRSwitchNodeBuilder::generateCaseStmtNode(const iterator& I, const GRState* St){
+
+  bool IsNew;
+
+  ExplodedNode* Succ = Eng.G->getNode(BlockEdge(Src, I.getBlock(),
+                                       Pred->getLocationContext()), St, &IsNew);
+  Succ->addPredecessor(Pred, *Eng.G);
+
+  if (IsNew) {
+    Eng.WList->Enqueue(Succ);
+    return Succ;
+  }
+
+  return NULL;
+}
+
+
+ExplodedNode*
+GRSwitchNodeBuilder::generateDefaultCaseNode(const GRState* St, bool isSink) {
+
+  // Get the block for the default case.
+  assert (Src->succ_rbegin() != Src->succ_rend());
+  CFGBlock* DefaultBlock = *Src->succ_rbegin();
+
+  bool IsNew;
+
+  ExplodedNode* Succ = Eng.G->getNode(BlockEdge(Src, DefaultBlock,
+                                       Pred->getLocationContext()), St, &IsNew);
+  Succ->addPredecessor(Pred, *Eng.G);
+
+  if (IsNew) {
+    if (isSink)
+      Succ->markAsSink();
+    else
+      Eng.WList->Enqueue(Succ);
+
+    return Succ;
+  }
+
+  return NULL;
+}
+
+GREndPathNodeBuilder::~GREndPathNodeBuilder() {
+  // Auto-generate an EOP node if one has not been generated.
+  if (!HasGeneratedNode) {
+    // If we are in an inlined call, generate CallExit node.
+    if (Pred->getLocationContext()->getParent())
+      GenerateCallExitNode(Pred->State);
+    else
+      generateNode(Pred->State);
+  }
+}
+
+ExplodedNode*
+GREndPathNodeBuilder::generateNode(const GRState* State, const void *tag,
+                                   ExplodedNode* P) {
+  HasGeneratedNode = true;
+  bool IsNew;
+
+  ExplodedNode* Node = Eng.G->getNode(BlockEntrance(&B,
+                               Pred->getLocationContext(), tag), State, &IsNew);
+
+  Node->addPredecessor(P ? P : Pred, *Eng.G);
+
+  if (IsNew) {
+    Eng.G->addEndOfPath(Node);
+    return Node;
+  }
+
+  return NULL;
+}
+
+void GREndPathNodeBuilder::GenerateCallExitNode(const GRState *state) {
+  HasGeneratedNode = true;
+  // Create a CallExit node and enqueue it.
+  const StackFrameContext *LocCtx
+                         = cast<StackFrameContext>(Pred->getLocationContext());
+  const Stmt *CE = LocCtx->getCallSite();
+
+  // Use the the callee location context.
+  CallExit Loc(CE, LocCtx);
+
+  bool isNew;
+  ExplodedNode *Node = Eng.G->getNode(Loc, state, &isNew);
+  Node->addPredecessor(Pred, *Eng.G);
+
+  if (isNew)
+    Eng.WList->Enqueue(Node);
+}
+                                                
+
+void GRCallEnterNodeBuilder::GenerateNode(const GRState *state,
+                                          const LocationContext *LocCtx) {
+  // Get the callee entry block.
+  const CFGBlock *Entry = &(LocCtx->getCFG()->getEntry());
+  assert(Entry->empty());
+  assert(Entry->succ_size() == 1);
+
+  // Get the solitary successor.
+  const CFGBlock *SuccB = *(Entry->succ_begin());
+
+  // Construct an edge representing the starting location in the callee.
+  BlockEdge Loc(Entry, SuccB, LocCtx);
+
+  bool isNew;
+  ExplodedNode *Node = Eng.G->getNode(Loc, state, &isNew);
+  Node->addPredecessor(const_cast<ExplodedNode*>(Pred), *Eng.G);
+
+  if (isNew)
+    Eng.WList->Enqueue(Node);
+}
+
+void GRCallExitNodeBuilder::GenerateNode(const GRState *state) {
+  // Get the callee's location context.
+  const StackFrameContext *LocCtx 
+                         = cast<StackFrameContext>(Pred->getLocationContext());
+
+  PostStmt Loc(LocCtx->getCallSite(), LocCtx->getParent());
+  bool isNew;
+  ExplodedNode *Node = Eng.G->getNode(Loc, state, &isNew);
+  Node->addPredecessor(const_cast<ExplodedNode*>(Pred), *Eng.G);
+  if (isNew)
+    Eng.WList->Enqueue(Node, *const_cast<CFGBlock*>(LocCtx->getCallSiteBlock()),
+                       LocCtx->getIndex() + 1);
+}
diff --git a/lib/Checker/GRExprEngine.cpp b/lib/Checker/GRExprEngine.cpp
new file mode 100644
index 0000000..c11a16f
--- /dev/null
+++ b/lib/Checker/GRExprEngine.cpp
@@ -0,0 +1,3437 @@
+//=-- GRExprEngine.cpp - Path-Sensitive Expression-Level Dataflow ---*- C++ -*-=
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines a meta-engine for path-sensitive dataflow analysis that
+//  is built on GREngine, but provides the boilerplate to execute transfer
+//  functions and build the ExplodedGraph at the expression level.
+//
+//===----------------------------------------------------------------------===//
+#include "GRExprEngineInternalChecks.h"
+#include "clang/Checker/BugReporter/BugType.h"
+#include "clang/Checker/PathSensitive/AnalysisManager.h"
+#include "clang/Checker/PathSensitive/GRExprEngine.h"
+#include "clang/Checker/PathSensitive/GRExprEngineBuilders.h"
+#include "clang/Checker/PathSensitive/Checker.h"
+#include "clang/AST/CharUnits.h"
+#include "clang/AST/ParentMap.h"
+#include "clang/AST/StmtObjC.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/Basic/Builtins.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/PrettyStackTrace.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/ADT/ImmutableList.h"
+
+#ifndef NDEBUG
+#include "llvm/Support/GraphWriter.h"
+#endif
+
+using namespace clang;
+using llvm::dyn_cast;
+using llvm::dyn_cast_or_null;
+using llvm::cast;
+using llvm::APSInt;
+
+namespace {
+  // Trait class for recording returned expression in the state.
+  struct ReturnExpr {
+    static int TagInt;
+    typedef const Stmt *data_type;
+  };
+  int ReturnExpr::TagInt; 
+}
+
+//===----------------------------------------------------------------------===//
+// Utility functions.
+//===----------------------------------------------------------------------===//
+
+static inline Selector GetNullarySelector(const char* name, ASTContext& Ctx) {
+  IdentifierInfo* II = &Ctx.Idents.get(name);
+  return Ctx.Selectors.getSelector(0, &II);
+}
+
+
+static QualType GetCalleeReturnType(const CallExpr *CE) {
+  const Expr *Callee = CE->getCallee();
+  QualType T = Callee->getType();
+  if (const PointerType *PT = T->getAs<PointerType>()) {
+    const FunctionType *FT = PT->getPointeeType()->getAs<FunctionType>();
+    T = FT->getResultType();
+  }
+  else {
+    const BlockPointerType *BT = T->getAs<BlockPointerType>();
+    T = BT->getPointeeType()->getAs<FunctionType>()->getResultType();
+  }
+  return T;
+}
+
+static bool CalleeReturnsReference(const CallExpr *CE) {
+  return (bool) GetCalleeReturnType(CE)->getAs<ReferenceType>();
+}
+
+static bool ReceiverReturnsReference(const ObjCMessageExpr *ME) {
+  const ObjCMethodDecl *MD = ME->getMethodDecl();
+  if (!MD)
+    return false;
+  return MD->getResultType()->getAs<ReferenceType>();
+}
+
+#ifndef NDEBUG
+static bool ReceiverReturnsReferenceOrRecord(const ObjCMessageExpr *ME) {
+  const ObjCMethodDecl *MD = ME->getMethodDecl();
+  if (!MD)
+    return false;
+  QualType T = MD->getResultType();
+  return T->getAs<RecordType>() || T->getAs<ReferenceType>();
+}
+
+static bool CalleeReturnsReferenceOrRecord(const CallExpr *CE) {
+  QualType T = GetCalleeReturnType(CE);
+  return T->getAs<ReferenceType>() || T->getAs<RecordType>();
+}
+#endif
+
+//===----------------------------------------------------------------------===//
+// Batch auditor.  DEPRECATED.
+//===----------------------------------------------------------------------===//
+
+namespace {
+
+class MappedBatchAuditor : public GRSimpleAPICheck {
+  typedef llvm::ImmutableList<GRSimpleAPICheck*> Checks;
+  typedef llvm::DenseMap<void*,Checks> MapTy;
+
+  MapTy M;
+  Checks::Factory F;
+  Checks AllStmts;
+
+public:
+  MappedBatchAuditor(llvm::BumpPtrAllocator& Alloc) :
+    F(Alloc), AllStmts(F.GetEmptyList()) {}
+
+  virtual ~MappedBatchAuditor() {
+    llvm::DenseSet<GRSimpleAPICheck*> AlreadyVisited;
+
+    for (MapTy::iterator MI = M.begin(), ME = M.end(); MI != ME; ++MI)
+      for (Checks::iterator I=MI->second.begin(), E=MI->second.end(); I!=E;++I){
+
+        GRSimpleAPICheck* check = *I;
+
+        if (AlreadyVisited.count(check))
+          continue;
+
+        AlreadyVisited.insert(check);
+        delete check;
+      }
+  }
+
+  void AddCheck(GRSimpleAPICheck *A, Stmt::StmtClass C) {
+    assert (A && "Check cannot be null.");
+    void* key = reinterpret_cast<void*>((uintptr_t) C);
+    MapTy::iterator I = M.find(key);
+    M[key] = F.Concat(A, I == M.end() ? F.GetEmptyList() : I->second);
+  }
+
+  void AddCheck(GRSimpleAPICheck *A) {
+    assert (A && "Check cannot be null.");
+    AllStmts = F.Concat(A, AllStmts);
+  }
+
+  virtual bool Audit(ExplodedNode* N, GRStateManager& VMgr) {
+    // First handle the auditors that accept all statements.
+    bool isSink = false;
+    for (Checks::iterator I = AllStmts.begin(), E = AllStmts.end(); I!=E; ++I)
+      isSink |= (*I)->Audit(N, VMgr);
+
+    // Next handle the auditors that accept only specific statements.
+    const Stmt* S = cast<PostStmt>(N->getLocation()).getStmt();
+    void* key = reinterpret_cast<void*>((uintptr_t) S->getStmtClass());
+    MapTy::iterator MI = M.find(key);
+    if (MI != M.end()) {
+      for (Checks::iterator I=MI->second.begin(), E=MI->second.end(); I!=E; ++I)
+        isSink |= (*I)->Audit(N, VMgr);
+    }
+
+    return isSink;
+  }
+};
+
+} // end anonymous namespace
+
+//===----------------------------------------------------------------------===//
+// Checker worklist routines.
+//===----------------------------------------------------------------------===//
+
+void GRExprEngine::CheckerVisit(Stmt *S, ExplodedNodeSet &Dst,
+                                ExplodedNodeSet &Src, bool isPrevisit) {
+
+  if (Checkers.empty()) {
+    Dst.insert(Src);
+    return;
+  }
+
+  ExplodedNodeSet Tmp;
+  ExplodedNodeSet *PrevSet = &Src;
+
+  for (CheckersOrdered::iterator I=Checkers.begin(),E=Checkers.end(); I!=E;++I){
+    ExplodedNodeSet *CurrSet = 0;
+    if (I+1 == E)
+      CurrSet = &Dst;
+    else {
+      CurrSet = (PrevSet == &Tmp) ? &Src : &Tmp;
+      CurrSet->clear();
+    }
+    void *tag = I->first;
+    Checker *checker = I->second;
+
+    for (ExplodedNodeSet::iterator NI = PrevSet->begin(), NE = PrevSet->end();
+         NI != NE; ++NI)
+      checker->GR_Visit(*CurrSet, *Builder, *this, S, *NI, tag, isPrevisit);
+    PrevSet = CurrSet;
+  }
+
+  // Don't autotransition.  The CheckerContext objects should do this
+  // automatically.
+}
+
+void GRExprEngine::CheckerEvalNilReceiver(const ObjCMessageExpr *ME,
+                                          ExplodedNodeSet &Dst,
+                                          const GRState *state,
+                                          ExplodedNode *Pred) {
+  bool Evaluated = false;
+  ExplodedNodeSet DstTmp;
+
+  for (CheckersOrdered::iterator I=Checkers.begin(),E=Checkers.end();I!=E;++I) {
+    void *tag = I->first;
+    Checker *checker = I->second;
+
+    if (checker->GR_EvalNilReceiver(DstTmp, *Builder, *this, ME, Pred, state,
+                                    tag)) {
+      Evaluated = true;
+      break;
+    } else
+      // The checker didn't evaluate the expr. Restore the Dst.
+      DstTmp.clear();
+  }
+
+  if (Evaluated)
+    Dst.insert(DstTmp);
+  else
+    Dst.insert(Pred);
+}
+
+// CheckerEvalCall returns true if one of the checkers processed the node.
+// This may return void when all call evaluation logic goes to some checker
+// in the future.
+bool GRExprEngine::CheckerEvalCall(const CallExpr *CE,
+                                   ExplodedNodeSet &Dst,
+                                   ExplodedNode *Pred) {
+  bool Evaluated = false;
+  ExplodedNodeSet DstTmp;
+
+  for (CheckersOrdered::iterator I=Checkers.begin(),E=Checkers.end();I!=E;++I) {
+    void *tag = I->first;
+    Checker *checker = I->second;
+
+    if (checker->GR_EvalCallExpr(DstTmp, *Builder, *this, CE, Pred, tag)) {
+      Evaluated = true;
+      break;
+    } else
+      // The checker didn't evaluate the expr. Restore the DstTmp set.
+      DstTmp.clear();
+  }
+
+  if (Evaluated)
+    Dst.insert(DstTmp);
+  else
+    Dst.insert(Pred);
+
+  return Evaluated;
+}
+
+// FIXME: This is largely copy-paste from CheckerVisit().  Need to
+// unify.
+void GRExprEngine::CheckerVisitBind(const Stmt *AssignE, const Stmt *StoreE,
+                                    ExplodedNodeSet &Dst,
+                                    ExplodedNodeSet &Src,
+                                    SVal location, SVal val, bool isPrevisit) {
+
+  if (Checkers.empty()) {
+    Dst.insert(Src);
+    return;
+  }
+
+  ExplodedNodeSet Tmp;
+  ExplodedNodeSet *PrevSet = &Src;
+
+  for (CheckersOrdered::iterator I=Checkers.begin(),E=Checkers.end(); I!=E; ++I)
+  {
+    ExplodedNodeSet *CurrSet = 0;
+    if (I+1 == E)
+      CurrSet = &Dst;
+    else {
+      CurrSet = (PrevSet == &Tmp) ? &Src : &Tmp;
+      CurrSet->clear();
+    }
+
+    void *tag = I->first;
+    Checker *checker = I->second;
+
+    for (ExplodedNodeSet::iterator NI = PrevSet->begin(), NE = PrevSet->end();
+         NI != NE; ++NI)
+      checker->GR_VisitBind(*CurrSet, *Builder, *this, AssignE, StoreE,
+                            *NI, tag, location, val, isPrevisit);
+
+    // Update which NodeSet is the current one.
+    PrevSet = CurrSet;
+  }
+
+  // Don't autotransition.  The CheckerContext objects should do this
+  // automatically.
+}
+//===----------------------------------------------------------------------===//
+// Engine construction and deletion.
+//===----------------------------------------------------------------------===//
+
+static void RegisterInternalChecks(GRExprEngine &Eng) {
+  // Register internal "built-in" BugTypes with the BugReporter. These BugTypes
+  // are different than what probably many checks will do since they don't
+  // create BugReports on-the-fly but instead wait until GRExprEngine finishes
+  // analyzing a function.  Generation of BugReport objects is done via a call
+  // to 'FlushReports' from BugReporter.
+  // The following checks do not need to have their associated BugTypes
+  // explicitly registered with the BugReporter.  If they issue any BugReports,
+  // their associated BugType will get registered with the BugReporter
+  // automatically.  Note that the check itself is owned by the GRExprEngine
+  // object.
+  RegisterAdjustedReturnValueChecker(Eng);
+  RegisterAttrNonNullChecker(Eng);
+  RegisterCallAndMessageChecker(Eng);
+  RegisterDereferenceChecker(Eng);
+  RegisterVLASizeChecker(Eng);
+  RegisterDivZeroChecker(Eng);
+  RegisterReturnStackAddressChecker(Eng);
+  RegisterReturnUndefChecker(Eng);
+  RegisterUndefinedArraySubscriptChecker(Eng);
+  RegisterUndefinedAssignmentChecker(Eng);
+  RegisterUndefBranchChecker(Eng);
+  RegisterUndefCapturedBlockVarChecker(Eng);
+  RegisterUndefResultChecker(Eng);
+
+  // This is not a checker yet.
+  RegisterNoReturnFunctionChecker(Eng);
+  RegisterBuiltinFunctionChecker(Eng);
+  RegisterOSAtomicChecker(Eng);
+  RegisterUnixAPIChecker(Eng);
+  RegisterMacOSXAPIChecker(Eng);
+}
+
+GRExprEngine::GRExprEngine(AnalysisManager &mgr, GRTransferFuncs *tf)
+  : AMgr(mgr),
+    CoreEngine(mgr.getASTContext(), *this),
+    G(CoreEngine.getGraph()),
+    Builder(NULL),
+    StateMgr(G.getContext(), mgr.getStoreManagerCreator(),
+             mgr.getConstraintManagerCreator(), G.getAllocator(),
+             *this),
+    SymMgr(StateMgr.getSymbolManager()),
+    ValMgr(StateMgr.getValueManager()),
+    SVator(ValMgr.getSValuator()),
+    CurrentStmt(NULL),
+    NSExceptionII(NULL), NSExceptionInstanceRaiseSelectors(NULL),
+    RaiseSel(GetNullarySelector("raise", G.getContext())),
+    BR(mgr, *this), TF(tf) {
+  // Register internal checks.
+  RegisterInternalChecks(*this);
+
+  // FIXME: Eventually remove the TF object entirely.
+  TF->RegisterChecks(*this);
+  TF->RegisterPrinters(getStateManager().Printers);
+}
+
+GRExprEngine::~GRExprEngine() {
+  BR.FlushReports();
+  delete [] NSExceptionInstanceRaiseSelectors;
+  for (CheckersOrdered::iterator I=Checkers.begin(), E=Checkers.end(); I!=E;++I)
+    delete I->second;
+}
+
+//===----------------------------------------------------------------------===//
+// Utility methods.
+//===----------------------------------------------------------------------===//
+
+void GRExprEngine::AddCheck(GRSimpleAPICheck* A, Stmt::StmtClass C) {
+  if (!BatchAuditor)
+    BatchAuditor.reset(new MappedBatchAuditor(getGraph().getAllocator()));
+
+  ((MappedBatchAuditor*) BatchAuditor.get())->AddCheck(A, C);
+}
+
+void GRExprEngine::AddCheck(GRSimpleAPICheck *A) {
+  if (!BatchAuditor)
+    BatchAuditor.reset(new MappedBatchAuditor(getGraph().getAllocator()));
+
+  ((MappedBatchAuditor*) BatchAuditor.get())->AddCheck(A);
+}
+
+const GRState* GRExprEngine::getInitialState(const LocationContext *InitLoc) {
+  const GRState *state = StateMgr.getInitialState(InitLoc);
+
+  // Preconditions.
+
+  // FIXME: It would be nice if we had a more general mechanism to add
+  // such preconditions.  Some day.
+  do {
+    const Decl *D = InitLoc->getDecl();
+    if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+      // Precondition: the first argument of 'main' is an integer guaranteed
+      //  to be > 0.
+      const IdentifierInfo *II = FD->getIdentifier();
+      if (!II || !(II->getName() == "main" && FD->getNumParams() > 0))
+        break;
+
+      const ParmVarDecl *PD = FD->getParamDecl(0);
+      QualType T = PD->getType();
+      if (!T->isIntegerType())
+        break;
+
+      const MemRegion *R = state->getRegion(PD, InitLoc);
+      if (!R)
+        break;
+
+      SVal V = state->getSVal(loc::MemRegionVal(R));
+      SVal Constraint_untested = EvalBinOp(state, BinaryOperator::GT, V,
+                                           ValMgr.makeZeroVal(T),
+                                           getContext().IntTy);
+
+      DefinedOrUnknownSVal *Constraint =
+        dyn_cast<DefinedOrUnknownSVal>(&Constraint_untested);
+
+      if (!Constraint)
+        break;
+
+      if (const GRState *newState = state->Assume(*Constraint, true))
+        state = newState;
+
+      break;
+    }
+
+    if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
+      // Precondition: 'self' is always non-null upon entry to an Objective-C
+      // method.
+      const ImplicitParamDecl *SelfD = MD->getSelfDecl();
+      const MemRegion *R = state->getRegion(SelfD, InitLoc);
+      SVal V = state->getSVal(loc::MemRegionVal(R));
+
+      if (const Loc *LV = dyn_cast<Loc>(&V)) {
+        // Assume that the pointer value in 'self' is non-null.
+        state = state->Assume(*LV, true);
+        assert(state && "'self' cannot be null");
+      }
+    }
+  } while (0);
+
+  return state;
+}
+
+//===----------------------------------------------------------------------===//
+// Top-level transfer function logic (Dispatcher).
+//===----------------------------------------------------------------------===//
+
+/// EvalAssume - Called by ConstraintManager. Used to call checker-specific
+///  logic for handling assumptions on symbolic values.
+const GRState *GRExprEngine::ProcessAssume(const GRState *state, SVal cond,
+                                           bool assumption) {
+  for (CheckersOrdered::iterator I = Checkers.begin(), E = Checkers.end();
+        I != E; ++I) {
+
+    if (!state)
+      return NULL;
+
+    state = I->second->EvalAssume(state, cond, assumption);
+  }
+
+  if (!state)
+    return NULL;
+
+  return TF->EvalAssume(state, cond, assumption);
+}
+
+void GRExprEngine::ProcessStmt(CFGElement CE, GRStmtNodeBuilder& builder) {
+  CurrentStmt = CE.getStmt();
+  PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
+                                CurrentStmt->getLocStart(),
+                                "Error evaluating statement");
+
+  Builder = &builder;
+  EntryNode = builder.getBasePredecessor();
+
+  // Set up our simple checks.
+  if (BatchAuditor)
+    Builder->setAuditor(BatchAuditor.get());
+
+  // Create the cleaned state.
+  const ExplodedNode *BasePred = Builder->getBasePredecessor();
+
+  SymbolReaper SymReaper(BasePred->getLocationContext(), SymMgr);
+
+  CleanedState = AMgr.shouldPurgeDead()
+    ? StateMgr.RemoveDeadBindings(EntryNode->getState(), CurrentStmt, 
+                         BasePred->getLocationContext()->getCurrentStackFrame(),
+                                  SymReaper)
+    : EntryNode->getState();
+
+  // Process any special transfer function for dead symbols.
+  ExplodedNodeSet Tmp;
+
+  if (!SymReaper.hasDeadSymbols())
+    Tmp.Add(EntryNode);
+  else {
+    SaveAndRestore<bool> OldSink(Builder->BuildSinks);
+    SaveOr OldHasGen(Builder->HasGeneratedNode);
+
+    SaveAndRestore<bool> OldPurgeDeadSymbols(Builder->PurgingDeadSymbols);
+    Builder->PurgingDeadSymbols = true;
+
+    // FIXME: This should soon be removed.
+    ExplodedNodeSet Tmp2;
+    getTF().EvalDeadSymbols(Tmp2, *this, *Builder, EntryNode, CurrentStmt,
+                            CleanedState, SymReaper);
+
+    if (Checkers.empty())
+      Tmp.insert(Tmp2);
+    else {
+      ExplodedNodeSet Tmp3;
+      ExplodedNodeSet *SrcSet = &Tmp2;
+      for (CheckersOrdered::iterator I = Checkers.begin(), E = Checkers.end();
+           I != E; ++I) {
+        ExplodedNodeSet *DstSet = 0;
+        if (I+1 == E)
+          DstSet = &Tmp;
+        else {
+          DstSet = (SrcSet == &Tmp2) ? &Tmp3 : &Tmp2;
+          DstSet->clear();
+        }
+
+        void *tag = I->first;
+        Checker *checker = I->second;
+        for (ExplodedNodeSet::iterator NI = SrcSet->begin(), NE = SrcSet->end();
+             NI != NE; ++NI)
+          checker->GR_EvalDeadSymbols(*DstSet, *Builder, *this, CurrentStmt,
+                                      *NI, SymReaper, tag);
+        SrcSet = DstSet;
+      }
+    }
+
+    if (!Builder->BuildSinks && !Builder->HasGeneratedNode)
+      Tmp.Add(EntryNode);
+  }
+
+  bool HasAutoGenerated = false;
+
+  for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
+
+    ExplodedNodeSet Dst;
+
+    // Set the cleaned state.
+    Builder->SetCleanedState(*I == EntryNode ? CleanedState : GetState(*I));
+
+    // Visit the statement.
+    if (CE.asLValue())
+      VisitLValue(cast<Expr>(CurrentStmt), *I, Dst);
+    else
+      Visit(CurrentStmt, *I, Dst);
+
+    // Do we need to auto-generate a node?  We only need to do this to generate
+    // a node with a "cleaned" state; GRCoreEngine will actually handle
+    // auto-transitions for other cases.
+    if (Dst.size() == 1 && *Dst.begin() == EntryNode
+        && !Builder->HasGeneratedNode && !HasAutoGenerated) {
+      HasAutoGenerated = true;
+      builder.generateNode(CurrentStmt, GetState(EntryNode), *I);
+    }
+  }
+
+  // NULL out these variables to cleanup.
+  CleanedState = NULL;
+  EntryNode = NULL;
+
+  CurrentStmt = 0;
+
+  Builder = NULL;
+}
+
+void GRExprEngine::Visit(Stmt* S, ExplodedNode* Pred, ExplodedNodeSet& Dst) {
+  PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
+                                S->getLocStart(),
+                                "Error evaluating statement");
+
+  // FIXME: add metadata to the CFG so that we can disable
+  //  this check when we KNOW that there is no block-level subexpression.
+  //  The motivation is that this check requires a hashtable lookup.
+
+  if (S != CurrentStmt && Pred->getLocationContext()->getCFG()->isBlkExpr(S)) {
+    Dst.Add(Pred);
+    return;
+  }
+
+  switch (S->getStmtClass()) {
+    // C++ stuff we don't support yet.
+    case Stmt::CXXBindReferenceExprClass:
+    case Stmt::CXXBindTemporaryExprClass:
+    case Stmt::CXXCatchStmtClass:
+    case Stmt::CXXConstructExprClass:
+    case Stmt::CXXDefaultArgExprClass:
+    case Stmt::CXXDependentScopeMemberExprClass:
+    case Stmt::CXXExprWithTemporariesClass:
+    case Stmt::CXXNullPtrLiteralExprClass:
+    case Stmt::CXXPseudoDestructorExprClass:
+    case Stmt::CXXTemporaryObjectExprClass:
+    case Stmt::CXXThrowExprClass:
+    case Stmt::CXXTryStmtClass:
+    case Stmt::CXXTypeidExprClass:
+    case Stmt::CXXUnresolvedConstructExprClass:
+    case Stmt::CXXZeroInitValueExprClass:
+    case Stmt::DependentScopeDeclRefExprClass:
+    case Stmt::UnaryTypeTraitExprClass:
+    case Stmt::UnresolvedLookupExprClass:
+    case Stmt::UnresolvedMemberExprClass:
+    {
+      SaveAndRestore<bool> OldSink(Builder->BuildSinks);
+      Builder->BuildSinks = true;
+      MakeNode(Dst, S, Pred, GetState(Pred));
+      break;
+    }
+
+    // Cases that should never be evaluated simply because they shouldn't
+    // appear in the CFG.
+    case Stmt::BreakStmtClass:
+    case Stmt::CaseStmtClass:
+    case Stmt::CompoundStmtClass:
+    case Stmt::ContinueStmtClass:
+    case Stmt::DefaultStmtClass:
+    case Stmt::DoStmtClass:
+    case Stmt::GotoStmtClass:
+    case Stmt::IndirectGotoStmtClass:
+    case Stmt::LabelStmtClass:
+    case Stmt::NoStmtClass:
+    case Stmt::NullStmtClass:
+    case Stmt::SwitchCaseClass:
+      llvm_unreachable("Stmt should not be in analyzer evaluation loop");
+      break;
+
+    // Cases not handled yet; but will handle some day.
+    case Stmt::DesignatedInitExprClass:
+    case Stmt::ExtVectorElementExprClass:
+    case Stmt::GNUNullExprClass:
+    case Stmt::ImaginaryLiteralClass:
+    case Stmt::ImplicitValueInitExprClass:
+    case Stmt::ObjCAtCatchStmtClass:
+    case Stmt::ObjCAtFinallyStmtClass:
+    case Stmt::ObjCAtSynchronizedStmtClass:
+    case Stmt::ObjCAtTryStmtClass:
+    case Stmt::ObjCEncodeExprClass:
+    case Stmt::ObjCImplicitSetterGetterRefExprClass:
+    case Stmt::ObjCIsaExprClass:
+    case Stmt::ObjCPropertyRefExprClass:
+    case Stmt::ObjCProtocolExprClass:
+    case Stmt::ObjCSelectorExprClass:
+    case Stmt::ObjCStringLiteralClass:
+    case Stmt::ObjCSuperExprClass:
+    case Stmt::ParenListExprClass:
+    case Stmt::PredefinedExprClass:
+    case Stmt::ShuffleVectorExprClass:
+    case Stmt::TypesCompatibleExprClass:
+    case Stmt::VAArgExprClass:
+        // Fall through.
+
+    // Cases we intentionally don't evaluate, since they don't need
+    // to be explicitly evaluated.
+    case Stmt::AddrLabelExprClass:
+    case Stmt::IntegerLiteralClass:
+    case Stmt::CharacterLiteralClass:
+    case Stmt::CXXBoolLiteralExprClass:
+    case Stmt::FloatingLiteralClass:
+      Dst.Add(Pred); // No-op. Simply propagate the current state unchanged.
+      break;
+
+    case Stmt::ArraySubscriptExprClass:
+      VisitArraySubscriptExpr(cast<ArraySubscriptExpr>(S), Pred, Dst, false);
+      break;
+
+    case Stmt::AsmStmtClass:
+      VisitAsmStmt(cast<AsmStmt>(S), Pred, Dst);
+      break;
+
+    case Stmt::BlockDeclRefExprClass:
+      VisitBlockDeclRefExpr(cast<BlockDeclRefExpr>(S), Pred, Dst, false);
+      break;
+
+    case Stmt::BlockExprClass:
+      VisitBlockExpr(cast<BlockExpr>(S), Pred, Dst);
+      break;
+
+    case Stmt::BinaryOperatorClass: {
+      BinaryOperator* B = cast<BinaryOperator>(S);
+
+      if (B->isLogicalOp()) {
+        VisitLogicalExpr(B, Pred, Dst);
+        break;
+      }
+      else if (B->getOpcode() == BinaryOperator::Comma) {
+        const GRState* state = GetState(Pred);
+        MakeNode(Dst, B, Pred, state->BindExpr(B, state->getSVal(B->getRHS())));
+        break;
+      }
+
+      if (AMgr.shouldEagerlyAssume() &&
+          (B->isRelationalOp() || B->isEqualityOp())) {
+        ExplodedNodeSet Tmp;
+        VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Tmp, false);
+        EvalEagerlyAssume(Dst, Tmp, cast<Expr>(S));
+      }
+      else
+        VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst, false);
+
+      break;
+    }
+
+    case Stmt::CallExprClass:
+    case Stmt::CXXOperatorCallExprClass: {
+      CallExpr* C = cast<CallExpr>(S);
+      VisitCall(C, Pred, C->arg_begin(), C->arg_end(), Dst, false);
+      break;
+    }
+
+    case Stmt::CXXMemberCallExprClass: {
+      CXXMemberCallExpr *MCE = cast<CXXMemberCallExpr>(S);
+      VisitCXXMemberCallExpr(MCE, Pred, Dst);
+      break;
+    }
+
+    case Stmt::CXXNewExprClass: {
+      CXXNewExpr *NE = cast<CXXNewExpr>(S);
+      VisitCXXNewExpr(NE, Pred, Dst);
+      break;
+    }
+
+    case Stmt::CXXDeleteExprClass: {
+      CXXDeleteExpr *CDE = cast<CXXDeleteExpr>(S);
+      VisitCXXDeleteExpr(CDE, Pred, Dst);
+      break;
+    }
+      // FIXME: ChooseExpr is really a constant.  We need to fix
+      //        the CFG do not model them as explicit control-flow.
+
+    case Stmt::ChooseExprClass: { // __builtin_choose_expr
+      ChooseExpr* C = cast<ChooseExpr>(S);
+      VisitGuardedExpr(C, C->getLHS(), C->getRHS(), Pred, Dst);
+      break;
+    }
+
+    case Stmt::CompoundAssignOperatorClass:
+      VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst, false);
+      break;
+
+    case Stmt::CompoundLiteralExprClass:
+      VisitCompoundLiteralExpr(cast<CompoundLiteralExpr>(S), Pred, Dst, false);
+      break;
+
+    case Stmt::ConditionalOperatorClass: { // '?' operator
+      ConditionalOperator* C = cast<ConditionalOperator>(S);
+      VisitGuardedExpr(C, C->getLHS(), C->getRHS(), Pred, Dst);
+      break;
+    }
+
+    case Stmt::CXXThisExprClass:
+      VisitCXXThisExpr(cast<CXXThisExpr>(S), Pred, Dst);
+      break;
+
+    case Stmt::DeclRefExprClass:
+      VisitDeclRefExpr(cast<DeclRefExpr>(S), Pred, Dst, false);
+      break;
+
+    case Stmt::DeclStmtClass:
+      VisitDeclStmt(cast<DeclStmt>(S), Pred, Dst);
+      break;
+
+    case Stmt::ForStmtClass:
+      // This case isn't for branch processing, but for handling the
+      // initialization of a condition variable.
+      VisitCondInit(cast<ForStmt>(S)->getConditionVariable(), S, Pred, Dst);
+      break;
+
+    case Stmt::ImplicitCastExprClass:
+    case Stmt::CStyleCastExprClass:
+    case Stmt::CXXStaticCastExprClass:
+    case Stmt::CXXDynamicCastExprClass:
+    case Stmt::CXXReinterpretCastExprClass:
+    case Stmt::CXXConstCastExprClass:
+    case Stmt::CXXFunctionalCastExprClass: {
+      CastExpr* C = cast<CastExpr>(S);
+      VisitCast(C, C->getSubExpr(), Pred, Dst, false);
+      break;
+    }
+
+    case Stmt::IfStmtClass:
+      // This case isn't for branch processing, but for handling the
+      // initialization of a condition variable.
+      VisitCondInit(cast<IfStmt>(S)->getConditionVariable(), S, Pred, Dst);
+      break;
+
+    case Stmt::InitListExprClass:
+      VisitInitListExpr(cast<InitListExpr>(S), Pred, Dst);
+      break;
+
+    case Stmt::MemberExprClass:
+      VisitMemberExpr(cast<MemberExpr>(S), Pred, Dst, false);
+      break;
+
+    case Stmt::ObjCIvarRefExprClass:
+      VisitObjCIvarRefExpr(cast<ObjCIvarRefExpr>(S), Pred, Dst, false);
+      break;
+
+    case Stmt::ObjCForCollectionStmtClass:
+      VisitObjCForCollectionStmt(cast<ObjCForCollectionStmt>(S), Pred, Dst);
+      break;
+
+    case Stmt::ObjCMessageExprClass:
+      VisitObjCMessageExpr(cast<ObjCMessageExpr>(S), Pred, Dst, false);
+      break;
+
+    case Stmt::ObjCAtThrowStmtClass: {
+      // FIXME: This is not complete.  We basically treat @throw as
+      // an abort.
+      SaveAndRestore<bool> OldSink(Builder->BuildSinks);
+      Builder->BuildSinks = true;
+      MakeNode(Dst, S, Pred, GetState(Pred));
+      break;
+    }
+
+    case Stmt::ParenExprClass:
+      Visit(cast<ParenExpr>(S)->getSubExpr()->IgnoreParens(), Pred, Dst);
+      break;
+
+    case Stmt::ReturnStmtClass:
+      VisitReturnStmt(cast<ReturnStmt>(S), Pred, Dst);
+      break;
+
+    case Stmt::SizeOfAlignOfExprClass:
+      VisitSizeOfAlignOfExpr(cast<SizeOfAlignOfExpr>(S), Pred, Dst);
+      break;
+
+    case Stmt::StmtExprClass: {
+      StmtExpr* SE = cast<StmtExpr>(S);
+
+      if (SE->getSubStmt()->body_empty()) {
+        // Empty statement expression.
+        assert(SE->getType() == getContext().VoidTy
+               && "Empty statement expression must have void type.");
+        Dst.Add(Pred);
+        break;
+      }
+
+      if (Expr* LastExpr = dyn_cast<Expr>(*SE->getSubStmt()->body_rbegin())) {
+        const GRState* state = GetState(Pred);
+        MakeNode(Dst, SE, Pred, state->BindExpr(SE, state->getSVal(LastExpr)));
+      }
+      else
+        Dst.Add(Pred);
+
+      break;
+    }
+
+    case Stmt::StringLiteralClass:
+      VisitLValue(cast<StringLiteral>(S), Pred, Dst);
+      break;
+
+    case Stmt::SwitchStmtClass:
+      // This case isn't for branch processing, but for handling the
+      // initialization of a condition variable.
+      VisitCondInit(cast<SwitchStmt>(S)->getConditionVariable(), S, Pred, Dst);
+      break;
+
+    case Stmt::UnaryOperatorClass: {
+      UnaryOperator *U = cast<UnaryOperator>(S);
+      if (AMgr.shouldEagerlyAssume()&&(U->getOpcode() == UnaryOperator::LNot)) {
+        ExplodedNodeSet Tmp;
+        VisitUnaryOperator(U, Pred, Tmp, false);
+        EvalEagerlyAssume(Dst, Tmp, U);
+      }
+      else
+        VisitUnaryOperator(U, Pred, Dst, false);
+      break;
+    }
+
+    case Stmt::WhileStmtClass:
+      // This case isn't for branch processing, but for handling the
+      // initialization of a condition variable.
+      VisitCondInit(cast<WhileStmt>(S)->getConditionVariable(), S, Pred, Dst);
+      break;
+  }
+}
+
+void GRExprEngine::VisitLValue(Expr* Ex, ExplodedNode* Pred,
+                               ExplodedNodeSet& Dst) {
+
+  PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
+                                Ex->getLocStart(),
+                                "Error evaluating statement");
+
+
+  Ex = Ex->IgnoreParens();
+
+  if (Ex != CurrentStmt && Pred->getLocationContext()->getCFG()->isBlkExpr(Ex)){
+    Dst.Add(Pred);
+    return;
+  }
+
+  switch (Ex->getStmtClass()) {
+    // C++ stuff we don't support yet.
+    case Stmt::CXXExprWithTemporariesClass:
+    case Stmt::CXXMemberCallExprClass:
+    case Stmt::CXXZeroInitValueExprClass: {
+      SaveAndRestore<bool> OldSink(Builder->BuildSinks);
+      Builder->BuildSinks = true;
+      MakeNode(Dst, Ex, Pred, GetState(Pred));
+      break;
+    }
+
+    case Stmt::ArraySubscriptExprClass:
+      VisitArraySubscriptExpr(cast<ArraySubscriptExpr>(Ex), Pred, Dst, true);
+      return;
+
+    case Stmt::BinaryOperatorClass:
+    case Stmt::CompoundAssignOperatorClass:
+      VisitBinaryOperator(cast<BinaryOperator>(Ex), Pred, Dst, true);
+      return;
+
+    case Stmt::BlockDeclRefExprClass:
+      VisitBlockDeclRefExpr(cast<BlockDeclRefExpr>(Ex), Pred, Dst, true);
+      return;
+
+    case Stmt::CallExprClass:
+    case Stmt::CXXOperatorCallExprClass: {
+      CallExpr *C = cast<CallExpr>(Ex);
+      assert(CalleeReturnsReferenceOrRecord(C));
+      VisitCall(C, Pred, C->arg_begin(), C->arg_end(), Dst, true);
+      break;
+    }
+
+    case Stmt::CompoundLiteralExprClass:
+      VisitCompoundLiteralExpr(cast<CompoundLiteralExpr>(Ex), Pred, Dst, true);
+      return;
+
+    case Stmt::DeclRefExprClass:
+      VisitDeclRefExpr(cast<DeclRefExpr>(Ex), Pred, Dst, true);
+      return;
+
+    case Stmt::ImplicitCastExprClass:
+    case Stmt::CStyleCastExprClass: {
+      CastExpr *C = cast<CastExpr>(Ex);
+      QualType T = Ex->getType();
+      VisitCast(C, C->getSubExpr(), Pred, Dst, true);
+      break;
+    }
+
+    case Stmt::MemberExprClass:
+      VisitMemberExpr(cast<MemberExpr>(Ex), Pred, Dst, true);
+      return;
+
+    case Stmt::ObjCIvarRefExprClass:
+      VisitObjCIvarRefExpr(cast<ObjCIvarRefExpr>(Ex), Pred, Dst, true);
+      return;
+
+    case Stmt::ObjCMessageExprClass: {
+      ObjCMessageExpr *ME = cast<ObjCMessageExpr>(Ex);
+      assert(ReceiverReturnsReferenceOrRecord(ME));
+      VisitObjCMessageExpr(ME, Pred, Dst, true);
+      return;
+    }
+
+    case Stmt::ObjCIsaExprClass:
+      // FIXME: Do something more intelligent with 'x->isa = ...'.
+      //  For now, just ignore the assignment.
+      return;
+
+    case Stmt::ObjCPropertyRefExprClass:
+    case Stmt::ObjCImplicitSetterGetterRefExprClass:
+      // FIXME: Property assignments are lvalues, but not really "locations".
+      //  e.g.:  self.x = something;
+      //  Here the "self.x" really can translate to a method call (setter) when
+      //  the assignment is made.  Moreover, the entire assignment expression
+      //  evaluate to whatever "something" is, not calling the "getter" for
+      //  the property (which would make sense since it can have side effects).
+      //  We'll probably treat this as a location, but not one that we can
+      //  take the address of.  Perhaps we need a new SVal class for cases
+      //  like thsis?
+      //  Note that we have a similar problem for bitfields, since they don't
+      //  have "locations" in the sense that we can take their address.
+      Dst.Add(Pred);
+      return;
+
+    case Stmt::StringLiteralClass: {
+      const GRState* state = GetState(Pred);
+      SVal V = state->getLValue(cast<StringLiteral>(Ex));
+      MakeNode(Dst, Ex, Pred, state->BindExpr(Ex, V));
+      return;
+    }
+
+    case Stmt::UnaryOperatorClass:
+      VisitUnaryOperator(cast<UnaryOperator>(Ex), Pred, Dst, true);
+      return;
+
+    // In C++, binding an rvalue to a reference requires to create an object.
+    case Stmt::CXXBoolLiteralExprClass:
+    case Stmt::IntegerLiteralClass:
+      CreateCXXTemporaryObject(Ex, Pred, Dst);
+      return;
+
+    default:
+      // Arbitrary subexpressions can return aggregate temporaries that
+      // can be used in a lvalue context.  We need to enhance our support
+      // of such temporaries in both the environment and the store, so right
+      // now we just do a regular visit.
+      assert ((Ex->getType()->isAggregateType()) &&
+              "Other kinds of expressions with non-aggregate/union types do"
+              " not have lvalues.");
+
+      Visit(Ex, Pred, Dst);
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// Block entrance.  (Update counters).
+//===----------------------------------------------------------------------===//
+
+bool GRExprEngine::ProcessBlockEntrance(CFGBlock* B, const ExplodedNode *Pred,
+                                        GRBlockCounter BC) {
+
+  return BC.getNumVisited(Pred->getLocationContext()->getCurrentStackFrame(), 
+                          B->getBlockID()) < 3;
+}
+
+//===----------------------------------------------------------------------===//
+// Generic node creation.
+//===----------------------------------------------------------------------===//
+
+ExplodedNode* GRExprEngine::MakeNode(ExplodedNodeSet& Dst, Stmt* S,
+                                     ExplodedNode* Pred, const GRState* St,
+                                     ProgramPoint::Kind K, const void *tag) {
+  assert (Builder && "GRStmtNodeBuilder not present.");
+  SaveAndRestore<const void*> OldTag(Builder->Tag);
+  Builder->Tag = tag;
+  return Builder->MakeNode(Dst, S, Pred, St, K);
+}
+
+//===----------------------------------------------------------------------===//
+// Branch processing.
+//===----------------------------------------------------------------------===//
+
+const GRState* GRExprEngine::MarkBranch(const GRState* state,
+                                           Stmt* Terminator,
+                                           bool branchTaken) {
+
+  switch (Terminator->getStmtClass()) {
+    default:
+      return state;
+
+    case Stmt::BinaryOperatorClass: { // '&&' and '||'
+
+      BinaryOperator* B = cast<BinaryOperator>(Terminator);
+      BinaryOperator::Opcode Op = B->getOpcode();
+
+      assert (Op == BinaryOperator::LAnd || Op == BinaryOperator::LOr);
+
+      // For &&, if we take the true branch, then the value of the whole
+      // expression is that of the RHS expression.
+      //
+      // For ||, if we take the false branch, then the value of the whole
+      // expression is that of the RHS expression.
+
+      Expr* Ex = (Op == BinaryOperator::LAnd && branchTaken) ||
+                 (Op == BinaryOperator::LOr && !branchTaken)
+               ? B->getRHS() : B->getLHS();
+
+      return state->BindExpr(B, UndefinedVal(Ex));
+    }
+
+    case Stmt::ConditionalOperatorClass: { // ?:
+
+      ConditionalOperator* C = cast<ConditionalOperator>(Terminator);
+
+      // For ?, if branchTaken == true then the value is either the LHS or
+      // the condition itself. (GNU extension).
+
+      Expr* Ex;
+
+      if (branchTaken)
+        Ex = C->getLHS() ? C->getLHS() : C->getCond();
+      else
+        Ex = C->getRHS();
+
+      return state->BindExpr(C, UndefinedVal(Ex));
+    }
+
+    case Stmt::ChooseExprClass: { // ?:
+
+      ChooseExpr* C = cast<ChooseExpr>(Terminator);
+
+      Expr* Ex = branchTaken ? C->getLHS() : C->getRHS();
+      return state->BindExpr(C, UndefinedVal(Ex));
+    }
+  }
+}
+
+/// RecoverCastedSymbol - A helper function for ProcessBranch that is used
+/// to try to recover some path-sensitivity for casts of symbolic
+/// integers that promote their values (which are currently not tracked well).
+/// This function returns the SVal bound to Condition->IgnoreCasts if all the
+//  cast(s) did was sign-extend the original value.
+static SVal RecoverCastedSymbol(GRStateManager& StateMgr, const GRState* state,
+                                Stmt* Condition, ASTContext& Ctx) {
+
+  Expr *Ex = dyn_cast<Expr>(Condition);
+  if (!Ex)
+    return UnknownVal();
+
+  uint64_t bits = 0;
+  bool bitsInit = false;
+
+  while (CastExpr *CE = dyn_cast<CastExpr>(Ex)) {
+    QualType T = CE->getType();
+
+    if (!T->isIntegerType())
+      return UnknownVal();
+
+    uint64_t newBits = Ctx.getTypeSize(T);
+    if (!bitsInit || newBits < bits) {
+      bitsInit = true;
+      bits = newBits;
+    }
+
+    Ex = CE->getSubExpr();
+  }
+
+  // We reached a non-cast.  Is it a symbolic value?
+  QualType T = Ex->getType();
+
+  if (!bitsInit || !T->isIntegerType() || Ctx.getTypeSize(T) > bits)
+    return UnknownVal();
+
+  return state->getSVal(Ex);
+}
+
+void GRExprEngine::ProcessBranch(Stmt* Condition, Stmt* Term,
+                                 GRBranchNodeBuilder& builder) {
+
+  // Check for NULL conditions; e.g. "for(;;)"
+  if (!Condition) {
+    builder.markInfeasible(false);
+    return;
+  }
+
+  PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
+                                Condition->getLocStart(),
+                                "Error evaluating branch");
+
+  for (CheckersOrdered::iterator I=Checkers.begin(),E=Checkers.end();I!=E;++I) {
+    void *tag = I->first;
+    Checker *checker = I->second;
+    checker->VisitBranchCondition(builder, *this, Condition, tag);
+  }
+
+  // If the branch condition is undefined, return;
+  if (!builder.isFeasible(true) && !builder.isFeasible(false))
+    return;
+
+  const GRState* PrevState = builder.getState();
+  SVal X = PrevState->getSVal(Condition);
+
+  if (X.isUnknown()) {
+    // Give it a chance to recover from unknown.
+    if (const Expr *Ex = dyn_cast<Expr>(Condition)) {
+      if (Ex->getType()->isIntegerType()) {
+        // Try to recover some path-sensitivity.  Right now casts of symbolic
+        // integers that promote their values are currently not tracked well.
+        // If 'Condition' is such an expression, try and recover the
+        // underlying value and use that instead.
+        SVal recovered = RecoverCastedSymbol(getStateManager(),
+                                             builder.getState(), Condition,
+                                             getContext());
+
+        if (!recovered.isUnknown()) {
+          X = recovered;
+        }
+      }
+    }
+    // If the condition is still unknown, give up.
+    if (X.isUnknown()) {
+      builder.generateNode(MarkBranch(PrevState, Term, true), true);
+      builder.generateNode(MarkBranch(PrevState, Term, false), false);
+      return;
+    }
+  }
+
+  DefinedSVal V = cast<DefinedSVal>(X);
+
+  // Process the true branch.
+  if (builder.isFeasible(true)) {
+    if (const GRState *state = PrevState->Assume(V, true))
+      builder.generateNode(MarkBranch(state, Term, true), true);
+    else
+      builder.markInfeasible(true);
+  }
+
+  // Process the false branch.
+  if (builder.isFeasible(false)) {
+    if (const GRState *state = PrevState->Assume(V, false))
+      builder.generateNode(MarkBranch(state, Term, false), false);
+    else
+      builder.markInfeasible(false);
+  }
+}
+
+/// ProcessIndirectGoto - Called by GRCoreEngine.  Used to generate successor
+///  nodes by processing the 'effects' of a computed goto jump.
+void GRExprEngine::ProcessIndirectGoto(GRIndirectGotoNodeBuilder& builder) {
+
+  const GRState *state = builder.getState();
+  SVal V = state->getSVal(builder.getTarget());
+
+  // Three possibilities:
+  //
+  //   (1) We know the computed label.
+  //   (2) The label is NULL (or some other constant), or Undefined.
+  //   (3) We have no clue about the label.  Dispatch to all targets.
+  //
+
+  typedef GRIndirectGotoNodeBuilder::iterator iterator;
+
+  if (isa<loc::GotoLabel>(V)) {
+    LabelStmt* L = cast<loc::GotoLabel>(V).getLabel();
+
+    for (iterator I=builder.begin(), E=builder.end(); I != E; ++I) {
+      if (I.getLabel() == L) {
+        builder.generateNode(I, state);
+        return;
+      }
+    }
+
+    assert (false && "No block with label.");
+    return;
+  }
+
+  if (isa<loc::ConcreteInt>(V) || isa<UndefinedVal>(V)) {
+    // Dispatch to the first target and mark it as a sink.
+    //ExplodedNode* N = builder.generateNode(builder.begin(), state, true);
+    // FIXME: add checker visit.
+    //    UndefBranches.insert(N);
+    return;
+  }
+
+  // This is really a catch-all.  We don't support symbolics yet.
+  // FIXME: Implement dispatch for symbolic pointers.
+
+  for (iterator I=builder.begin(), E=builder.end(); I != E; ++I)
+    builder.generateNode(I, state);
+}
+
+
+void GRExprEngine::VisitGuardedExpr(Expr* Ex, Expr* L, Expr* R,
+                                    ExplodedNode* Pred, ExplodedNodeSet& Dst) {
+
+  assert(Ex == CurrentStmt &&
+         Pred->getLocationContext()->getCFG()->isBlkExpr(Ex));
+
+  const GRState* state = GetState(Pred);
+  SVal X = state->getSVal(Ex);
+
+  assert (X.isUndef());
+
+  Expr *SE = (Expr*) cast<UndefinedVal>(X).getData();
+  assert(SE);
+  X = state->getSVal(SE);
+
+  // Make sure that we invalidate the previous binding.
+  MakeNode(Dst, Ex, Pred, state->BindExpr(Ex, X, true));
+}
+
+/// ProcessEndPath - Called by GRCoreEngine.  Used to generate end-of-path
+///  nodes when the control reaches the end of a function.
+void GRExprEngine::ProcessEndPath(GREndPathNodeBuilder& builder) {
+  getTF().EvalEndPath(*this, builder);
+  StateMgr.EndPath(builder.getState());
+  for (CheckersOrdered::iterator I=Checkers.begin(),E=Checkers.end(); I!=E;++I){
+    void *tag = I->first;
+    Checker *checker = I->second;
+    checker->EvalEndPath(builder, tag, *this);
+  }
+}
+
+/// ProcessSwitch - Called by GRCoreEngine.  Used to generate successor
+///  nodes by processing the 'effects' of a switch statement.
+void GRExprEngine::ProcessSwitch(GRSwitchNodeBuilder& builder) {
+  typedef GRSwitchNodeBuilder::iterator iterator;
+  const GRState* state = builder.getState();
+  Expr* CondE = builder.getCondition();
+  SVal  CondV_untested = state->getSVal(CondE);
+
+  if (CondV_untested.isUndef()) {
+    //ExplodedNode* N = builder.generateDefaultCaseNode(state, true);
+    // FIXME: add checker
+    //UndefBranches.insert(N);
+
+    return;
+  }
+  DefinedOrUnknownSVal CondV = cast<DefinedOrUnknownSVal>(CondV_untested);
+
+  const GRState *DefaultSt = state;
+  bool defaultIsFeasible = false;
+
+  for (iterator I = builder.begin(), EI = builder.end(); I != EI; ++I) {
+    CaseStmt* Case = cast<CaseStmt>(I.getCase());
+
+    // Evaluate the LHS of the case value.
+    Expr::EvalResult V1;
+    bool b = Case->getLHS()->Evaluate(V1, getContext());
+
+    // Sanity checks.  These go away in Release builds.
+    assert(b && V1.Val.isInt() && !V1.HasSideEffects
+             && "Case condition must evaluate to an integer constant.");
+    b = b; // silence unused variable warning
+    assert(V1.Val.getInt().getBitWidth() ==
+           getContext().getTypeSize(CondE->getType()));
+
+    // Get the RHS of the case, if it exists.
+    Expr::EvalResult V2;
+
+    if (Expr* E = Case->getRHS()) {
+      b = E->Evaluate(V2, getContext());
+      assert(b && V2.Val.isInt() && !V2.HasSideEffects
+             && "Case condition must evaluate to an integer constant.");
+      b = b; // silence unused variable warning
+    }
+    else
+      V2 = V1;
+
+    // FIXME: Eventually we should replace the logic below with a range
+    //  comparison, rather than concretize the values within the range.
+    //  This should be easy once we have "ranges" for NonLVals.
+
+    do {
+      nonloc::ConcreteInt CaseVal(getBasicVals().getValue(V1.Val.getInt()));
+      DefinedOrUnknownSVal Res = SVator.EvalEQ(DefaultSt ? DefaultSt : state,
+                                               CondV, CaseVal);
+
+      // Now "assume" that the case matches.
+      if (const GRState* stateNew = state->Assume(Res, true)) {
+        builder.generateCaseStmtNode(I, stateNew);
+
+        // If CondV evaluates to a constant, then we know that this
+        // is the *only* case that we can take, so stop evaluating the
+        // others.
+        if (isa<nonloc::ConcreteInt>(CondV))
+          return;
+      }
+
+      // Now "assume" that the case doesn't match.  Add this state
+      // to the default state (if it is feasible).
+      if (DefaultSt) {
+        if (const GRState *stateNew = DefaultSt->Assume(Res, false)) {
+          defaultIsFeasible = true;
+          DefaultSt = stateNew;
+        }
+        else {
+          defaultIsFeasible = false;
+          DefaultSt = NULL;
+        }
+      }
+
+      // Concretize the next value in the range.
+      if (V1.Val.getInt() == V2.Val.getInt())
+        break;
+
+      ++V1.Val.getInt();
+      assert (V1.Val.getInt() <= V2.Val.getInt());
+
+    } while (true);
+  }
+
+  // If we reach here, than we know that the default branch is
+  // possible.
+  if (defaultIsFeasible) builder.generateDefaultCaseNode(DefaultSt);
+}
+
+void GRExprEngine::ProcessCallEnter(GRCallEnterNodeBuilder &B) {
+  const FunctionDecl *FD = B.getCallee();
+  const StackFrameContext *LocCtx = AMgr.getStackFrame(FD, 
+                                                       B.getLocationContext(),
+                                                       B.getCallExpr(),
+                                                       B.getBlock(),
+                                                       B.getIndex());
+
+  const GRState *state = B.getState();
+  state = getStoreManager().EnterStackFrame(state, LocCtx);
+
+  B.GenerateNode(state, LocCtx);
+}
+
+void GRExprEngine::ProcessCallExit(GRCallExitNodeBuilder &B) {
+  const GRState *state = B.getState();
+  const ExplodedNode *Pred = B.getPredecessor();
+  const StackFrameContext *LocCtx = 
+                            cast<StackFrameContext>(Pred->getLocationContext());
+  const Stmt *CE = LocCtx->getCallSite();
+
+  // If the callee returns an expression, bind its value to CallExpr.
+  const Stmt *ReturnedExpr = state->get<ReturnExpr>();
+  if (ReturnedExpr) {
+    SVal RetVal = state->getSVal(ReturnedExpr);
+    state = state->BindExpr(CE, RetVal);
+    // Clear the return expr GDM.
+    state = state->remove<ReturnExpr>();
+  }
+
+  // Bind the constructed object value to CXXConstructExpr.
+  if (const CXXConstructExpr *CCE = dyn_cast<CXXConstructExpr>(CE)) {
+    const CXXThisRegion *ThisR = getCXXThisRegion(CCE->getConstructor(),LocCtx);
+    // We might not have 'this' region in the binding if we didn't inline
+    // the ctor call.
+    SVal ThisV = state->getSVal(ThisR);
+    loc::MemRegionVal *V = dyn_cast<loc::MemRegionVal>(&ThisV);
+    if (V) {
+      SVal ObjVal = state->getSVal(V->getRegion());
+      assert(isa<nonloc::LazyCompoundVal>(ObjVal));
+      state = state->BindExpr(CCE, ObjVal);
+    }
+  }
+
+  B.GenerateNode(state);
+}
+
+//===----------------------------------------------------------------------===//
+// Transfer functions: logical operations ('&&', '||').
+//===----------------------------------------------------------------------===//
+
+void GRExprEngine::VisitLogicalExpr(BinaryOperator* B, ExplodedNode* Pred,
+                                    ExplodedNodeSet& Dst) {
+
+  assert(B->getOpcode() == BinaryOperator::LAnd ||
+         B->getOpcode() == BinaryOperator::LOr);
+
+  assert(B==CurrentStmt && Pred->getLocationContext()->getCFG()->isBlkExpr(B));
+
+  const GRState* state = GetState(Pred);
+  SVal X = state->getSVal(B);
+  assert(X.isUndef());
+
+  const Expr *Ex = (const Expr*) cast<UndefinedVal>(X).getData();
+  assert(Ex);
+
+  if (Ex == B->getRHS()) {
+    X = state->getSVal(Ex);
+
+    // Handle undefined values.
+    if (X.isUndef()) {
+      MakeNode(Dst, B, Pred, state->BindExpr(B, X));
+      return;
+    }
+
+    DefinedOrUnknownSVal XD = cast<DefinedOrUnknownSVal>(X);
+
+    // We took the RHS.  Because the value of the '&&' or '||' expression must
+    // evaluate to 0 or 1, we must assume the value of the RHS evaluates to 0
+    // or 1.  Alternatively, we could take a lazy approach, and calculate this
+    // value later when necessary.  We don't have the machinery in place for
+    // this right now, and since most logical expressions are used for branches,
+    // the payoff is not likely to be large.  Instead, we do eager evaluation.
+    if (const GRState *newState = state->Assume(XD, true))
+      MakeNode(Dst, B, Pred,
+               newState->BindExpr(B, ValMgr.makeIntVal(1U, B->getType())));
+
+    if (const GRState *newState = state->Assume(XD, false))
+      MakeNode(Dst, B, Pred,
+               newState->BindExpr(B, ValMgr.makeIntVal(0U, B->getType())));
+  }
+  else {
+    // We took the LHS expression.  Depending on whether we are '&&' or
+    // '||' we know what the value of the expression is via properties of
+    // the short-circuiting.
+    X = ValMgr.makeIntVal(B->getOpcode() == BinaryOperator::LAnd ? 0U : 1U,
+                          B->getType());
+    MakeNode(Dst, B, Pred, state->BindExpr(B, X));
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// Transfer functions: Loads and stores.
+//===----------------------------------------------------------------------===//
+
+void GRExprEngine::VisitBlockExpr(BlockExpr *BE, ExplodedNode *Pred,
+                                  ExplodedNodeSet &Dst) {
+
+  ExplodedNodeSet Tmp;
+
+  CanQualType T = getContext().getCanonicalType(BE->getType());
+  SVal V = ValMgr.getBlockPointer(BE->getBlockDecl(), T,
+                                  Pred->getLocationContext());
+
+  MakeNode(Tmp, BE, Pred, GetState(Pred)->BindExpr(BE, V),
+           ProgramPoint::PostLValueKind);
+
+  // Post-visit the BlockExpr.
+  CheckerVisit(BE, Dst, Tmp, false);
+}
+
+void GRExprEngine::VisitDeclRefExpr(DeclRefExpr *Ex, ExplodedNode *Pred,
+                                    ExplodedNodeSet &Dst, bool asLValue) {
+  VisitCommonDeclRefExpr(Ex, Ex->getDecl(), Pred, Dst, asLValue);
+}
+
+void GRExprEngine::VisitBlockDeclRefExpr(BlockDeclRefExpr *Ex,
+                                         ExplodedNode *Pred,
+                                    ExplodedNodeSet &Dst, bool asLValue) {
+  VisitCommonDeclRefExpr(Ex, Ex->getDecl(), Pred, Dst, asLValue);
+}
+
+void GRExprEngine::VisitCommonDeclRefExpr(Expr *Ex, const NamedDecl *D,
+                                          ExplodedNode *Pred,
+                                          ExplodedNodeSet &Dst, bool asLValue) {
+
+  const GRState *state = GetState(Pred);
+
+  if (const VarDecl* VD = dyn_cast<VarDecl>(D)) {
+
+    SVal V = state->getLValue(VD, Pred->getLocationContext());
+
+    if (asLValue) {
+      // For references, the 'lvalue' is the pointer address stored in the
+      // reference region.
+      if (VD->getType()->isReferenceType()) {
+        if (const MemRegion *R = V.getAsRegion())
+          V = state->getSVal(R);
+        else
+          V = UnknownVal();
+      }
+
+      MakeNode(Dst, Ex, Pred, state->BindExpr(Ex, V),
+               ProgramPoint::PostLValueKind);
+    }
+    else
+      EvalLoad(Dst, Ex, Pred, state, V);
+
+    return;
+  } else if (const EnumConstantDecl* ED = dyn_cast<EnumConstantDecl>(D)) {
+    assert(!asLValue && "EnumConstantDecl does not have lvalue.");
+
+    SVal V = ValMgr.makeIntVal(ED->getInitVal());
+    MakeNode(Dst, Ex, Pred, state->BindExpr(Ex, V));
+    return;
+
+  } else if (const FunctionDecl* FD = dyn_cast<FunctionDecl>(D)) {
+    // This code is valid regardless of the value of 'isLValue'.
+    SVal V = ValMgr.getFunctionPointer(FD);
+    MakeNode(Dst, Ex, Pred, state->BindExpr(Ex, V),
+             ProgramPoint::PostLValueKind);
+    return;
+  }
+
+  assert (false &&
+          "ValueDecl support for this ValueDecl not implemented.");
+}
+
+/// VisitArraySubscriptExpr - Transfer function for array accesses
+void GRExprEngine::VisitArraySubscriptExpr(ArraySubscriptExpr* A,
+                                           ExplodedNode* Pred,
+                                           ExplodedNodeSet& Dst, bool asLValue){
+
+  Expr* Base = A->getBase()->IgnoreParens();
+  Expr* Idx  = A->getIdx()->IgnoreParens();
+  ExplodedNodeSet Tmp;
+
+  if (Base->getType()->isVectorType()) {
+    // For vector types get its lvalue.
+    // FIXME: This may not be correct.  Is the rvalue of a vector its location?
+    //  In fact, I think this is just a hack.  We need to get the right
+    // semantics.
+    VisitLValue(Base, Pred, Tmp);
+  }
+  else
+    Visit(Base, Pred, Tmp);   // Get Base's rvalue, which should be an LocVal.
+
+  for (ExplodedNodeSet::iterator I1=Tmp.begin(), E1=Tmp.end(); I1!=E1; ++I1) {
+    ExplodedNodeSet Tmp2;
+    Visit(Idx, *I1, Tmp2);     // Evaluate the index.
+
+    ExplodedNodeSet Tmp3;
+    CheckerVisit(A, Tmp3, Tmp2, true);
+
+    for (ExplodedNodeSet::iterator I2=Tmp3.begin(),E2=Tmp3.end();I2!=E2; ++I2) {
+      const GRState* state = GetState(*I2);
+      SVal V = state->getLValue(A->getType(), state->getSVal(Idx),
+                                state->getSVal(Base));
+
+      if (asLValue)
+        MakeNode(Dst, A, *I2, state->BindExpr(A, V),
+                 ProgramPoint::PostLValueKind);
+      else
+        EvalLoad(Dst, A, *I2, state, V);
+    }
+  }
+}
+
+/// VisitMemberExpr - Transfer function for member expressions.
+void GRExprEngine::VisitMemberExpr(MemberExpr* M, ExplodedNode* Pred,
+                                   ExplodedNodeSet& Dst, bool asLValue) {
+
+  Expr* Base = M->getBase()->IgnoreParens();
+  ExplodedNodeSet Tmp;
+
+  if (M->isArrow())
+    Visit(Base, Pred, Tmp);        // p->f = ...  or   ... = p->f
+  else
+    VisitLValue(Base, Pred, Tmp);  // x.f = ...   or   ... = x.f
+
+  FieldDecl *Field = dyn_cast<FieldDecl>(M->getMemberDecl());
+  if (!Field) // FIXME: skipping member expressions for non-fields
+    return;
+
+  for (ExplodedNodeSet::iterator I = Tmp.begin(), E = Tmp.end(); I != E; ++I) {
+    const GRState* state = GetState(*I);
+    // FIXME: Should we insert some assumption logic in here to determine
+    // if "Base" is a valid piece of memory?  Before we put this assumption
+    // later when using FieldOffset lvals (which we no longer have).
+    SVal L = state->getLValue(Field, state->getSVal(Base));
+
+    if (asLValue)
+      MakeNode(Dst, M, *I, state->BindExpr(M, L), ProgramPoint::PostLValueKind);
+    else
+      EvalLoad(Dst, M, *I, state, L);
+  }
+}
+
+/// EvalBind - Handle the semantics of binding a value to a specific location.
+///  This method is used by EvalStore and (soon) VisitDeclStmt, and others.
+void GRExprEngine::EvalBind(ExplodedNodeSet& Dst, Stmt *AssignE,
+                            Stmt* StoreE, ExplodedNode* Pred,
+                            const GRState* state, SVal location, SVal Val,
+                            bool atDeclInit) {
+
+
+  // Do a previsit of the bind.
+  ExplodedNodeSet CheckedSet, Src;
+  Src.Add(Pred);
+  CheckerVisitBind(AssignE, StoreE, CheckedSet, Src, location, Val, true);
+
+  for (ExplodedNodeSet::iterator I = CheckedSet.begin(), E = CheckedSet.end();
+       I!=E; ++I) {
+
+    if (Pred != *I)
+      state = GetState(*I);
+
+    const GRState* newState = 0;
+
+    if (atDeclInit) {
+      const VarRegion *VR =
+        cast<VarRegion>(cast<loc::MemRegionVal>(location).getRegion());
+
+      newState = state->bindDecl(VR, Val);
+    }
+    else {
+      if (location.isUnknown()) {
+        // We know that the new state will be the same as the old state since
+        // the location of the binding is "unknown".  Consequently, there
+        // is no reason to just create a new node.
+        newState = state;
+      }
+      else {
+        // We are binding to a value other than 'unknown'.  Perform the binding
+        // using the StoreManager.
+        newState = state->bindLoc(cast<Loc>(location), Val);
+      }
+    }
+
+    // The next thing to do is check if the GRTransferFuncs object wants to
+    // update the state based on the new binding.  If the GRTransferFunc object
+    // doesn't do anything, just auto-propagate the current state.
+    GRStmtNodeBuilderRef BuilderRef(Dst, *Builder, *this, *I, newState, StoreE,
+                                    newState != state);
+
+    getTF().EvalBind(BuilderRef, location, Val);
+  }
+}
+
+/// EvalStore - Handle the semantics of a store via an assignment.
+///  @param Dst The node set to store generated state nodes
+///  @param Ex The expression representing the location of the store
+///  @param state The current simulation state
+///  @param location The location to store the value
+///  @param Val The value to be stored
+void GRExprEngine::EvalStore(ExplodedNodeSet& Dst, Expr *AssignE,
+                             Expr* StoreE,
+                             ExplodedNode* Pred,
+                             const GRState* state, SVal location, SVal Val,
+                             const void *tag) {
+
+  assert(Builder && "GRStmtNodeBuilder must be defined.");
+
+  // Evaluate the location (checks for bad dereferences).
+  ExplodedNodeSet Tmp;
+  EvalLocation(Tmp, StoreE, Pred, state, location, tag, false);
+
+  if (Tmp.empty())
+    return;
+
+  assert(!location.isUndef());
+
+  SaveAndRestore<ProgramPoint::Kind> OldSPointKind(Builder->PointKind,
+                                                   ProgramPoint::PostStoreKind);
+  SaveAndRestore<const void*> OldTag(Builder->Tag, tag);
+
+  // Proceed with the store.
+  for (ExplodedNodeSet::iterator NI=Tmp.begin(), NE=Tmp.end(); NI!=NE; ++NI)
+    EvalBind(Dst, AssignE, StoreE, *NI, GetState(*NI), location, Val);
+}
+
+void GRExprEngine::EvalLoad(ExplodedNodeSet& Dst, Expr *Ex, ExplodedNode* Pred,
+                            const GRState* state, SVal location,
+                            const void *tag, QualType LoadTy) {
+
+  // Are we loading from a region?  This actually results in two loads; one
+  // to fetch the address of the referenced value and one to fetch the
+  // referenced value.
+  if (const TypedRegion *TR =
+        dyn_cast_or_null<TypedRegion>(location.getAsRegion())) {
+
+    QualType ValTy = TR->getValueType(getContext());
+    if (const ReferenceType *RT = ValTy->getAs<ReferenceType>()) {
+      static int loadReferenceTag = 0;
+      ExplodedNodeSet Tmp;
+      EvalLoadCommon(Tmp, Ex, Pred, state, location, &loadReferenceTag,
+                     getContext().getPointerType(RT->getPointeeType()));
+
+      // Perform the load from the referenced value.
+      for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end() ; I!=E; ++I) {
+        state = GetState(*I);
+        location = state->getSVal(Ex);
+        EvalLoadCommon(Dst, Ex, *I, state, location, tag, LoadTy);
+      }
+      return;
+    }
+  }
+
+  EvalLoadCommon(Dst, Ex, Pred, state, location, tag, LoadTy);
+}
+
+void GRExprEngine::EvalLoadCommon(ExplodedNodeSet& Dst, Expr *Ex,
+                                  ExplodedNode* Pred,
+                                  const GRState* state, SVal location,
+                                  const void *tag, QualType LoadTy) {
+
+  // Evaluate the location (checks for bad dereferences).
+  ExplodedNodeSet Tmp;
+  EvalLocation(Tmp, Ex, Pred, state, location, tag, true);
+
+  if (Tmp.empty())
+    return;
+
+  assert(!location.isUndef());
+
+  SaveAndRestore<ProgramPoint::Kind> OldSPointKind(Builder->PointKind);
+  SaveAndRestore<const void*> OldTag(Builder->Tag);
+
+  // Proceed with the load.
+  for (ExplodedNodeSet::iterator NI=Tmp.begin(), NE=Tmp.end(); NI!=NE; ++NI) {
+    state = GetState(*NI);
+    if (location.isUnknown()) {
+      // This is important.  We must nuke the old binding.
+      MakeNode(Dst, Ex, *NI, state->BindExpr(Ex, UnknownVal()),
+               ProgramPoint::PostLoadKind, tag);
+    }
+    else {
+      SVal V = state->getSVal(cast<Loc>(location), LoadTy.isNull() ?
+                                                     Ex->getType() : LoadTy);
+      MakeNode(Dst, Ex, *NI, state->BindExpr(Ex, V), ProgramPoint::PostLoadKind,
+               tag);
+    }
+  }
+}
+
+void GRExprEngine::EvalLocation(ExplodedNodeSet &Dst, Stmt *S,
+                                ExplodedNode* Pred,
+                                const GRState* state, SVal location,
+                                const void *tag, bool isLoad) {
+  // Early checks for performance reason.
+  if (location.isUnknown() || Checkers.empty()) {
+    Dst.Add(Pred);
+    return;
+  }
+
+  ExplodedNodeSet Src, Tmp;
+  Src.Add(Pred);
+  ExplodedNodeSet *PrevSet = &Src;
+
+  for (CheckersOrdered::iterator I=Checkers.begin(),E=Checkers.end(); I!=E; ++I)
+  {
+    ExplodedNodeSet *CurrSet = 0;
+    if (I+1 == E)
+      CurrSet = &Dst;
+    else {
+      CurrSet = (PrevSet == &Tmp) ? &Src : &Tmp;
+      CurrSet->clear();
+    }
+
+    void *tag = I->first;
+    Checker *checker = I->second;
+
+    for (ExplodedNodeSet::iterator NI = PrevSet->begin(), NE = PrevSet->end();
+         NI != NE; ++NI) {
+      // Use the 'state' argument only when the predecessor node is the
+      // same as Pred.  This allows us to catch updates to the state.
+      checker->GR_VisitLocation(*CurrSet, *Builder, *this, S, *NI,
+                                *NI == Pred ? state : GetState(*NI),
+                                location, tag, isLoad);
+    }
+
+    // Update which NodeSet is the current one.
+    PrevSet = CurrSet;
+  }
+}
+
+void GRExprEngine::VisitCall(CallExpr* CE, ExplodedNode* Pred,
+                             CallExpr::arg_iterator AI,
+                             CallExpr::arg_iterator AE,
+                             ExplodedNodeSet& Dst, bool asLValue) {
+
+  // Determine the type of function we're calling (if available).
+  const FunctionProtoType *Proto = NULL;
+  QualType FnType = CE->getCallee()->IgnoreParens()->getType();
+  if (const PointerType *FnTypePtr = FnType->getAs<PointerType>())
+    Proto = FnTypePtr->getPointeeType()->getAs<FunctionProtoType>();
+
+  // Create a worklist to process the arguments.
+  llvm::SmallVector<CallExprWLItem, 20> WorkList;
+  WorkList.reserve(AE - AI);
+  WorkList.push_back(CallExprWLItem(AI, Pred));
+
+  ExplodedNodeSet ArgsEvaluated;
+
+  while (!WorkList.empty()) {
+    CallExprWLItem Item = WorkList.back();
+    WorkList.pop_back();
+
+    if (Item.I == AE) {
+      ArgsEvaluated.insert(Item.N);
+      continue;
+    }
+
+    // Evaluate the argument.
+    ExplodedNodeSet Tmp;
+    const unsigned ParamIdx = Item.I - AI;
+
+    bool VisitAsLvalue = false;
+    if (Proto && ParamIdx < Proto->getNumArgs())
+      VisitAsLvalue = Proto->getArgType(ParamIdx)->isReferenceType();
+
+    if (VisitAsLvalue)
+      VisitLValue(*Item.I, Item.N, Tmp);
+    else
+      Visit(*Item.I, Item.N, Tmp);
+
+    // Enqueue evaluating the next argument on the worklist.
+    ++(Item.I);
+
+    for (ExplodedNodeSet::iterator NI=Tmp.begin(), NE=Tmp.end(); NI!=NE; ++NI)
+      WorkList.push_back(CallExprWLItem(Item.I, *NI));
+  }
+
+  // Now process the call itself.
+  ExplodedNodeSet DstTmp;
+  Expr* Callee = CE->getCallee()->IgnoreParens();
+
+  for (ExplodedNodeSet::iterator NI=ArgsEvaluated.begin(),
+                                 NE=ArgsEvaluated.end(); NI != NE; ++NI) {
+    // Evaluate the callee.
+    ExplodedNodeSet DstTmp2;
+    Visit(Callee, *NI, DstTmp2);
+    // Perform the previsit of the CallExpr, storing the results in DstTmp.
+    CheckerVisit(CE, DstTmp, DstTmp2, true);
+  }
+
+  // Finally, evaluate the function call.  We try each of the checkers
+  // to see if the can evaluate the function call.
+  ExplodedNodeSet DstTmp3;
+
+
+  for (ExplodedNodeSet::iterator DI = DstTmp.begin(), DE = DstTmp.end();
+       DI != DE; ++DI) {
+
+    const GRState* state = GetState(*DI);
+    SVal L = state->getSVal(Callee);
+
+    // FIXME: Add support for symbolic function calls (calls involving
+    //  function pointer values that are symbolic).
+    SaveAndRestore<bool> OldSink(Builder->BuildSinks);
+    ExplodedNodeSet DstChecker;
+
+    // If the callee is processed by a checker, skip the rest logic.
+    if (CheckerEvalCall(CE, DstChecker, *DI))
+      DstTmp3.insert(DstChecker);
+    else {
+      for (ExplodedNodeSet::iterator DI_Checker = DstChecker.begin(),
+           DE_Checker = DstChecker.end();
+           DI_Checker != DE_Checker; ++DI_Checker) {
+
+        // Dispatch to the plug-in transfer function.
+        unsigned OldSize = DstTmp3.size();
+        SaveOr OldHasGen(Builder->HasGeneratedNode);
+        Pred = *DI_Checker;
+
+        // Dispatch to transfer function logic to handle the call itself.
+        // FIXME: Allow us to chain together transfer functions.
+        assert(Builder && "GRStmtNodeBuilder must be defined.");
+        getTF().EvalCall(DstTmp3, *this, *Builder, CE, L, Pred);
+
+        // Handle the case where no nodes where generated.  Auto-generate that
+        // contains the updated state if we aren't generating sinks.
+        if (!Builder->BuildSinks && DstTmp3.size() == OldSize &&
+            !Builder->HasGeneratedNode)
+          MakeNode(DstTmp3, CE, Pred, state);
+      }
+    }
+  }
+
+  // Finally, perform the post-condition check of the CallExpr and store
+  // the created nodes in 'Dst'.
+
+  if (!(!asLValue && CalleeReturnsReference(CE))) {
+    CheckerVisit(CE, Dst, DstTmp3, false);
+    return;
+  }
+
+  // Handle the case where the called function returns a reference but
+  // we expect an rvalue.  For such cases, convert the reference to
+  // an rvalue.
+  // FIXME: This conversion doesn't actually happen unless the result
+  //  of CallExpr is consumed by another expression.
+  ExplodedNodeSet DstTmp4;
+  CheckerVisit(CE, DstTmp4, DstTmp3, false);
+  QualType LoadTy = CE->getType();
+
+  static int *ConvertToRvalueTag = 0;
+  for (ExplodedNodeSet::iterator NI = DstTmp4.begin(), NE = DstTmp4.end();
+       NI!=NE; ++NI) {
+    const GRState *state = GetState(*NI);
+    EvalLoad(Dst, CE, *NI, state, state->getSVal(CE),
+             &ConvertToRvalueTag, LoadTy);
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// Transfer function: Objective-C ivar references.
+//===----------------------------------------------------------------------===//
+
+static std::pair<const void*,const void*> EagerlyAssumeTag
+  = std::pair<const void*,const void*>(&EagerlyAssumeTag,0);
+
+void GRExprEngine::EvalEagerlyAssume(ExplodedNodeSet &Dst, ExplodedNodeSet &Src,
+                                     Expr *Ex) {
+  for (ExplodedNodeSet::iterator I=Src.begin(), E=Src.end(); I!=E; ++I) {
+    ExplodedNode *Pred = *I;
+
+    // Test if the previous node was as the same expression.  This can happen
+    // when the expression fails to evaluate to anything meaningful and
+    // (as an optimization) we don't generate a node.
+    ProgramPoint P = Pred->getLocation();
+    if (!isa<PostStmt>(P) || cast<PostStmt>(P).getStmt() != Ex) {
+      Dst.Add(Pred);
+      continue;
+    }
+
+    const GRState* state = GetState(Pred);
+    SVal V = state->getSVal(Ex);
+    if (nonloc::SymExprVal *SEV = dyn_cast<nonloc::SymExprVal>(&V)) {
+      // First assume that the condition is true.
+      if (const GRState *stateTrue = state->Assume(*SEV, true)) {
+        stateTrue = stateTrue->BindExpr(Ex,
+                                        ValMgr.makeIntVal(1U, Ex->getType()));
+        Dst.Add(Builder->generateNode(PostStmtCustom(Ex,
+                                &EagerlyAssumeTag, Pred->getLocationContext()),
+                                      stateTrue, Pred));
+      }
+
+      // Next, assume that the condition is false.
+      if (const GRState *stateFalse = state->Assume(*SEV, false)) {
+        stateFalse = stateFalse->BindExpr(Ex,
+                                          ValMgr.makeIntVal(0U, Ex->getType()));
+        Dst.Add(Builder->generateNode(PostStmtCustom(Ex, &EagerlyAssumeTag,
+                                                   Pred->getLocationContext()),
+                                      stateFalse, Pred));
+      }
+    }
+    else
+      Dst.Add(Pred);
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// Transfer function: Objective-C ivar references.
+//===----------------------------------------------------------------------===//
+
+void GRExprEngine::VisitObjCIvarRefExpr(ObjCIvarRefExpr* Ex, ExplodedNode* Pred,
+                                        ExplodedNodeSet& Dst, bool asLValue) {
+
+  Expr* Base = cast<Expr>(Ex->getBase());
+  ExplodedNodeSet Tmp;
+  Visit(Base, Pred, Tmp);
+
+  for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
+    const GRState* state = GetState(*I);
+    SVal BaseVal = state->getSVal(Base);
+    SVal location = state->getLValue(Ex->getDecl(), BaseVal);
+
+    if (asLValue)
+      MakeNode(Dst, Ex, *I, state->BindExpr(Ex, location));
+    else
+      EvalLoad(Dst, Ex, *I, state, location);
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// Transfer function: Objective-C fast enumeration 'for' statements.
+//===----------------------------------------------------------------------===//
+
+void GRExprEngine::VisitObjCForCollectionStmt(ObjCForCollectionStmt* S,
+                                     ExplodedNode* Pred, ExplodedNodeSet& Dst) {
+
+  // ObjCForCollectionStmts are processed in two places.  This method
+  // handles the case where an ObjCForCollectionStmt* occurs as one of the
+  // statements within a basic block.  This transfer function does two things:
+  //
+  //  (1) binds the next container value to 'element'.  This creates a new
+  //      node in the ExplodedGraph.
+  //
+  //  (2) binds the value 0/1 to the ObjCForCollectionStmt* itself, indicating
+  //      whether or not the container has any more elements.  This value
+  //      will be tested in ProcessBranch.  We need to explicitly bind
+  //      this value because a container can contain nil elements.
+  //
+  // FIXME: Eventually this logic should actually do dispatches to
+  //   'countByEnumeratingWithState:objects:count:' (NSFastEnumeration).
+  //   This will require simulating a temporary NSFastEnumerationState, either
+  //   through an SVal or through the use of MemRegions.  This value can
+  //   be affixed to the ObjCForCollectionStmt* instead of 0/1; when the loop
+  //   terminates we reclaim the temporary (it goes out of scope) and we
+  //   we can test if the SVal is 0 or if the MemRegion is null (depending
+  //   on what approach we take).
+  //
+  //  For now: simulate (1) by assigning either a symbol or nil if the
+  //    container is empty.  Thus this transfer function will by default
+  //    result in state splitting.
+
+  Stmt* elem = S->getElement();
+  SVal ElementV;
+
+  if (DeclStmt* DS = dyn_cast<DeclStmt>(elem)) {
+    VarDecl* ElemD = cast<VarDecl>(DS->getSingleDecl());
+    assert (ElemD->getInit() == 0);
+    ElementV = GetState(Pred)->getLValue(ElemD, Pred->getLocationContext());
+    VisitObjCForCollectionStmtAux(S, Pred, Dst, ElementV);
+    return;
+  }
+
+  ExplodedNodeSet Tmp;
+  VisitLValue(cast<Expr>(elem), Pred, Tmp);
+
+  for (ExplodedNodeSet::iterator I = Tmp.begin(), E = Tmp.end(); I!=E; ++I) {
+    const GRState* state = GetState(*I);
+    VisitObjCForCollectionStmtAux(S, *I, Dst, state->getSVal(elem));
+  }
+}
+
+void GRExprEngine::VisitObjCForCollectionStmtAux(ObjCForCollectionStmt* S,
+                                       ExplodedNode* Pred, ExplodedNodeSet& Dst,
+                                                 SVal ElementV) {
+
+  // Check if the location we are writing back to is a null pointer.
+  Stmt* elem = S->getElement();
+  ExplodedNodeSet Tmp;
+  EvalLocation(Tmp, elem, Pred, GetState(Pred), ElementV, NULL, false);
+
+  if (Tmp.empty())
+    return;
+
+  for (ExplodedNodeSet::iterator NI=Tmp.begin(), NE=Tmp.end(); NI!=NE; ++NI) {
+    Pred = *NI;
+    const GRState *state = GetState(Pred);
+
+    // Handle the case where the container still has elements.
+    SVal TrueV = ValMgr.makeTruthVal(1);
+    const GRState *hasElems = state->BindExpr(S, TrueV);
+
+    // Handle the case where the container has no elements.
+    SVal FalseV = ValMgr.makeTruthVal(0);
+    const GRState *noElems = state->BindExpr(S, FalseV);
+
+    if (loc::MemRegionVal* MV = dyn_cast<loc::MemRegionVal>(&ElementV))
+      if (const TypedRegion* R = dyn_cast<TypedRegion>(MV->getRegion())) {
+        // FIXME: The proper thing to do is to really iterate over the
+        //  container.  We will do this with dispatch logic to the store.
+        //  For now, just 'conjure' up a symbolic value.
+        QualType T = R->getValueType(getContext());
+        assert(Loc::IsLocType(T));
+        unsigned Count = Builder->getCurrentBlockCount();
+        SymbolRef Sym = SymMgr.getConjuredSymbol(elem, T, Count);
+        SVal V = ValMgr.makeLoc(Sym);
+        hasElems = hasElems->bindLoc(ElementV, V);
+
+        // Bind the location to 'nil' on the false branch.
+        SVal nilV = ValMgr.makeIntVal(0, T);
+        noElems = noElems->bindLoc(ElementV, nilV);
+      }
+
+    // Create the new nodes.
+    MakeNode(Dst, S, Pred, hasElems);
+    MakeNode(Dst, S, Pred, noElems);
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// Transfer function: Objective-C message expressions.
+//===----------------------------------------------------------------------===//
+
+namespace {
+class ObjCMsgWLItem {
+public:
+  ObjCMessageExpr::arg_iterator I;
+  ExplodedNode *N;
+
+  ObjCMsgWLItem(const ObjCMessageExpr::arg_iterator &i, ExplodedNode *n)
+    : I(i), N(n) {}
+};
+} // end anonymous namespace
+
+void GRExprEngine::VisitObjCMessageExpr(ObjCMessageExpr* ME, ExplodedNode* Pred,
+                                        ExplodedNodeSet& Dst, bool asLValue){
+
+  // Create a worklist to process both the arguments.
+  llvm::SmallVector<ObjCMsgWLItem, 20> WL;
+
+  // But first evaluate the receiver (if any).
+  ObjCMessageExpr::arg_iterator AI = ME->arg_begin(), AE = ME->arg_end();
+  if (Expr *Receiver = ME->getInstanceReceiver()) {
+    ExplodedNodeSet Tmp;
+    Visit(Receiver, Pred, Tmp);
+
+    if (Tmp.empty())
+      return;
+
+    for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I)
+      WL.push_back(ObjCMsgWLItem(AI, *I));
+  }
+  else
+    WL.push_back(ObjCMsgWLItem(AI, Pred));
+
+  // Evaluate the arguments.
+  ExplodedNodeSet ArgsEvaluated;
+  while (!WL.empty()) {
+    ObjCMsgWLItem Item = WL.back();
+    WL.pop_back();
+
+    if (Item.I == AE) {
+      ArgsEvaluated.insert(Item.N);
+      continue;
+    }
+
+    // Evaluate the subexpression.
+    ExplodedNodeSet Tmp;
+
+    // FIXME: [Objective-C++] handle arguments that are references
+    Visit(*Item.I, Item.N, Tmp);
+
+    // Enqueue evaluating the next argument on the worklist.
+    ++(Item.I);
+    for (ExplodedNodeSet::iterator NI=Tmp.begin(), NE=Tmp.end(); NI!=NE; ++NI)
+      WL.push_back(ObjCMsgWLItem(Item.I, *NI));
+  }
+
+  // Now that the arguments are processed, handle the previsits checks.
+  ExplodedNodeSet DstPrevisit;
+  CheckerVisit(ME, DstPrevisit, ArgsEvaluated, true);
+
+  // Proceed with evaluate the message expression.
+  ExplodedNodeSet DstEval;
+
+  for (ExplodedNodeSet::iterator DI = DstPrevisit.begin(),
+                                 DE = DstPrevisit.end(); DI != DE; ++DI) {
+
+    Pred = *DI;
+    bool RaisesException = false;
+    unsigned OldSize = DstEval.size();
+    SaveAndRestore<bool> OldSink(Builder->BuildSinks);
+    SaveOr OldHasGen(Builder->HasGeneratedNode);
+
+    if (const Expr *Receiver = ME->getInstanceReceiver()) {
+      const GRState *state = GetState(Pred);
+
+      // Bifurcate the state into nil and non-nil ones.
+      DefinedOrUnknownSVal receiverVal =
+        cast<DefinedOrUnknownSVal>(state->getSVal(Receiver));
+
+      const GRState *notNilState, *nilState;
+      llvm::tie(notNilState, nilState) = state->Assume(receiverVal);
+
+      // There are three cases: can be nil or non-nil, must be nil, must be
+      // non-nil. We handle must be nil, and merge the rest two into non-nil.
+      if (nilState && !notNilState) {
+        CheckerEvalNilReceiver(ME, DstEval, nilState, Pred);
+        continue;
+      }
+
+      // Check if the "raise" message was sent.
+      assert(notNilState);
+      if (ME->getSelector() == RaiseSel)
+        RaisesException = true;
+
+      // Check if we raise an exception.  For now treat these as sinks.
+      // Eventually we will want to handle exceptions properly.
+      if (RaisesException)
+        Builder->BuildSinks = true;
+
+      // Dispatch to plug-in transfer function.
+      EvalObjCMessageExpr(DstEval, ME, Pred, notNilState);
+    }
+    else if (ObjCInterfaceDecl *Iface = ME->getReceiverInterface()) {
+      IdentifierInfo* ClsName = Iface->getIdentifier();
+      Selector S = ME->getSelector();
+
+      // Check for special instance methods.
+      if (!NSExceptionII) {
+        ASTContext& Ctx = getContext();
+        NSExceptionII = &Ctx.Idents.get("NSException");
+      }
+
+      if (ClsName == NSExceptionII) {
+        enum { NUM_RAISE_SELECTORS = 2 };
+
+        // Lazily create a cache of the selectors.
+        if (!NSExceptionInstanceRaiseSelectors) {
+          ASTContext& Ctx = getContext();
+          NSExceptionInstanceRaiseSelectors =
+            new Selector[NUM_RAISE_SELECTORS];
+          llvm::SmallVector<IdentifierInfo*, NUM_RAISE_SELECTORS> II;
+          unsigned idx = 0;
+
+          // raise:format:
+          II.push_back(&Ctx.Idents.get("raise"));
+          II.push_back(&Ctx.Idents.get("format"));
+          NSExceptionInstanceRaiseSelectors[idx++] =
+            Ctx.Selectors.getSelector(II.size(), &II[0]);
+
+          // raise:format::arguments:
+          II.push_back(&Ctx.Idents.get("arguments"));
+          NSExceptionInstanceRaiseSelectors[idx++] =
+            Ctx.Selectors.getSelector(II.size(), &II[0]);
+        }
+
+        for (unsigned i = 0; i < NUM_RAISE_SELECTORS; ++i)
+          if (S == NSExceptionInstanceRaiseSelectors[i]) {
+            RaisesException = true;
+            break;
+          }
+      }
+
+      // Check if we raise an exception.  For now treat these as sinks.
+      // Eventually we will want to handle exceptions properly.
+      if (RaisesException)
+        Builder->BuildSinks = true;
+
+      // Dispatch to plug-in transfer function.
+      EvalObjCMessageExpr(DstEval, ME, Pred, Builder->GetState(Pred));
+    }
+
+    // Handle the case where no nodes where generated.  Auto-generate that
+    // contains the updated state if we aren't generating sinks.
+    if (!Builder->BuildSinks && DstEval.size() == OldSize &&
+        !Builder->HasGeneratedNode)
+      MakeNode(DstEval, ME, Pred, GetState(Pred));
+  }
+
+  // Finally, perform the post-condition check of the ObjCMessageExpr and store
+  // the created nodes in 'Dst'.
+  if (!(!asLValue && ReceiverReturnsReference(ME))) {
+    CheckerVisit(ME, Dst, DstEval, false);
+    return;
+  }
+
+  // Handle the case where the message expression returns a reference but
+  // we expect an rvalue.  For such cases, convert the reference to
+  // an rvalue.
+  // FIXME: This conversion doesn't actually happen unless the result
+  //  of ObjCMessageExpr is consumed by another expression.
+  ExplodedNodeSet DstRValueConvert;
+  CheckerVisit(ME, DstRValueConvert, DstEval, false);
+  QualType LoadTy = ME->getType();
+
+  static int *ConvertToRvalueTag = 0;
+  for (ExplodedNodeSet::iterator NI = DstRValueConvert.begin(),
+       NE = DstRValueConvert.end(); NI != NE; ++NI) {
+    const GRState *state = GetState(*NI);
+    EvalLoad(Dst, ME, *NI, state, state->getSVal(ME),
+             &ConvertToRvalueTag, LoadTy);
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// Transfer functions: Miscellaneous statements.
+//===----------------------------------------------------------------------===//
+
+void GRExprEngine::VisitCast(CastExpr *CastE, Expr *Ex, ExplodedNode *Pred,
+                             ExplodedNodeSet &Dst, bool asLValue) {
+  ExplodedNodeSet S1;
+  QualType T = CastE->getType();
+  QualType ExTy = Ex->getType();
+
+  if (const ExplicitCastExpr *ExCast=dyn_cast_or_null<ExplicitCastExpr>(CastE))
+    T = ExCast->getTypeAsWritten();
+
+  if (ExTy->isArrayType() || ExTy->isFunctionType() || T->isReferenceType() ||
+      asLValue)
+    VisitLValue(Ex, Pred, S1);
+  else
+    Visit(Ex, Pred, S1);
+
+  ExplodedNodeSet S2;
+  CheckerVisit(CastE, S2, S1, true);
+
+  // If we are evaluating the cast in an lvalue context, we implicitly want
+  // the cast to evaluate to a location.
+  if (asLValue) {
+    ASTContext &Ctx = getContext();
+    T = Ctx.getPointerType(Ctx.getCanonicalType(T));
+    ExTy = Ctx.getPointerType(Ctx.getCanonicalType(ExTy));
+  }
+
+  switch (CastE->getCastKind()) {
+  case CastExpr::CK_ToVoid:
+    assert(!asLValue);
+    for (ExplodedNodeSet::iterator I = S2.begin(), E = S2.end(); I != E; ++I)
+      Dst.Add(*I);
+    return;
+
+  case CastExpr::CK_NoOp:
+  case CastExpr::CK_FunctionToPointerDecay:
+    for (ExplodedNodeSet::iterator I = S2.begin(), E = S2.end(); I != E; ++I) {
+      // Copy the SVal of Ex to CastE.
+      ExplodedNode *N = *I;
+      const GRState *state = GetState(N);
+      SVal V = state->getSVal(Ex);
+      state = state->BindExpr(CastE, V);
+      MakeNode(Dst, CastE, N, state);
+    }
+    return;
+
+  case CastExpr::CK_Unknown:
+  case CastExpr::CK_ArrayToPointerDecay:
+  case CastExpr::CK_BitCast:
+  case CastExpr::CK_IntegralCast:
+  case CastExpr::CK_IntegralToPointer:
+  case CastExpr::CK_PointerToIntegral:
+  case CastExpr::CK_IntegralToFloating:
+  case CastExpr::CK_FloatingToIntegral:
+  case CastExpr::CK_FloatingCast:
+  case CastExpr::CK_AnyPointerToObjCPointerCast:
+  case CastExpr::CK_AnyPointerToBlockPointerCast:
+  case CastExpr::CK_DerivedToBase:
+  case CastExpr::CK_UncheckedDerivedToBase:
+    // Delegate to SValuator to process.
+    for (ExplodedNodeSet::iterator I = S2.begin(), E = S2.end(); I != E; ++I) {
+      ExplodedNode* N = *I;
+      const GRState* state = GetState(N);
+      SVal V = state->getSVal(Ex);
+      V = SVator.EvalCast(V, T, ExTy);
+      state = state->BindExpr(CastE, V);
+      MakeNode(Dst, CastE, N, state);
+    }
+    return;
+
+  default:
+    llvm::errs() << "Cast kind " << CastE->getCastKind() << " not handled.\n";
+    assert(0);
+  }
+}
+
+void GRExprEngine::VisitCompoundLiteralExpr(CompoundLiteralExpr* CL,
+                                            ExplodedNode* Pred,
+                                            ExplodedNodeSet& Dst,
+                                            bool asLValue) {
+  InitListExpr* ILE = cast<InitListExpr>(CL->getInitializer()->IgnoreParens());
+  ExplodedNodeSet Tmp;
+  Visit(ILE, Pred, Tmp);
+
+  for (ExplodedNodeSet::iterator I = Tmp.begin(), EI = Tmp.end(); I!=EI; ++I) {
+    const GRState* state = GetState(*I);
+    SVal ILV = state->getSVal(ILE);
+    const LocationContext *LC = (*I)->getLocationContext();
+    state = state->bindCompoundLiteral(CL, LC, ILV);
+
+    if (asLValue) {
+      MakeNode(Dst, CL, *I, state->BindExpr(CL, state->getLValue(CL, LC)));
+    }
+    else
+      MakeNode(Dst, CL, *I, state->BindExpr(CL, ILV));
+  }
+}
+
+void GRExprEngine::VisitDeclStmt(DeclStmt *DS, ExplodedNode *Pred,
+                                 ExplodedNodeSet& Dst) {
+
+  // The CFG has one DeclStmt per Decl.
+  Decl* D = *DS->decl_begin();
+
+  if (!D || !isa<VarDecl>(D))
+    return;
+
+  const VarDecl* VD = dyn_cast<VarDecl>(D);
+  Expr* InitEx = const_cast<Expr*>(VD->getInit());
+
+  // FIXME: static variables may have an initializer, but the second
+  //  time a function is called those values may not be current.
+  ExplodedNodeSet Tmp;
+
+  if (InitEx) {
+    QualType InitTy = InitEx->getType();
+    if (getContext().getLangOptions().CPlusPlus && InitTy->isRecordType()) {
+      // Delegate expressions of C++ record type evaluation to AggExprVisitor.
+      VisitAggExpr(InitEx, GetState(Pred)->getLValue(VD,
+                                       Pred->getLocationContext()), Pred, Dst);
+      return;
+    } else if (VD->getType()->isReferenceType())
+      VisitLValue(InitEx, Pred, Tmp);
+    else
+      Visit(InitEx, Pred, Tmp);
+  }
+  else
+    Tmp.Add(Pred);
+
+  ExplodedNodeSet Tmp2;
+  CheckerVisit(DS, Tmp2, Tmp, true);
+
+  for (ExplodedNodeSet::iterator I=Tmp2.begin(), E=Tmp2.end(); I!=E; ++I) {
+    ExplodedNode *N = *I;
+    const GRState *state = GetState(N);
+
+    // Decls without InitExpr are not initialized explicitly.
+    const LocationContext *LC = N->getLocationContext();
+
+    if (InitEx) {
+      SVal InitVal = state->getSVal(InitEx);
+
+      // Recover some path-sensitivity if a scalar value evaluated to
+      // UnknownVal.
+      if ((InitVal.isUnknown() ||
+          !getConstraintManager().canReasonAbout(InitVal)) &&
+          !VD->getType()->isReferenceType()) {
+        InitVal = ValMgr.getConjuredSymbolVal(NULL, InitEx,
+                                               Builder->getCurrentBlockCount());
+      }
+
+      EvalBind(Dst, DS, DS, *I, state,
+               loc::MemRegionVal(state->getRegion(VD, LC)), InitVal, true);
+    }
+    else {
+      state = state->bindDeclWithNoInit(state->getRegion(VD, LC));
+      MakeNode(Dst, DS, *I, state);
+    }
+  }
+}
+
+void GRExprEngine::VisitCondInit(VarDecl *VD, Stmt *S,
+                                 ExplodedNode *Pred, ExplodedNodeSet& Dst) {
+
+  Expr* InitEx = VD->getInit();
+  ExplodedNodeSet Tmp;
+  Visit(InitEx, Pred, Tmp);
+
+  for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
+    ExplodedNode *N = *I;
+    const GRState *state = GetState(N);
+
+    const LocationContext *LC = N->getLocationContext();
+    SVal InitVal = state->getSVal(InitEx);
+
+    // Recover some path-sensitivity if a scalar value evaluated to
+    // UnknownVal.
+    if (InitVal.isUnknown() ||
+        !getConstraintManager().canReasonAbout(InitVal)) {
+      InitVal = ValMgr.getConjuredSymbolVal(NULL, InitEx,
+                                            Builder->getCurrentBlockCount());
+    }
+
+    EvalBind(Dst, S, S, N, state,
+             loc::MemRegionVal(state->getRegion(VD, LC)), InitVal, true);
+  }
+}
+
+namespace {
+  // This class is used by VisitInitListExpr as an item in a worklist
+  // for processing the values contained in an InitListExpr.
+class InitListWLItem {
+public:
+  llvm::ImmutableList<SVal> Vals;
+  ExplodedNode* N;
+  InitListExpr::reverse_iterator Itr;
+
+  InitListWLItem(ExplodedNode* n, llvm::ImmutableList<SVal> vals,
+                 InitListExpr::reverse_iterator itr)
+  : Vals(vals), N(n), Itr(itr) {}
+};
+}
+
+
+void GRExprEngine::VisitInitListExpr(InitListExpr* E, ExplodedNode* Pred,
+                                     ExplodedNodeSet& Dst) {
+
+  const GRState* state = GetState(Pred);
+  QualType T = getContext().getCanonicalType(E->getType());
+  unsigned NumInitElements = E->getNumInits();
+
+  if (T->isArrayType() || T->isRecordType() || T->isVectorType()) {
+    llvm::ImmutableList<SVal> StartVals = getBasicVals().getEmptySValList();
+
+    // Handle base case where the initializer has no elements.
+    // e.g: static int* myArray[] = {};
+    if (NumInitElements == 0) {
+      SVal V = ValMgr.makeCompoundVal(T, StartVals);
+      MakeNode(Dst, E, Pred, state->BindExpr(E, V));
+      return;
+    }
+
+    // Create a worklist to process the initializers.
+    llvm::SmallVector<InitListWLItem, 10> WorkList;
+    WorkList.reserve(NumInitElements);
+    WorkList.push_back(InitListWLItem(Pred, StartVals, E->rbegin()));
+    InitListExpr::reverse_iterator ItrEnd = E->rend();
+    assert(!(E->rbegin() == E->rend()));
+
+    // Process the worklist until it is empty.
+    while (!WorkList.empty()) {
+      InitListWLItem X = WorkList.back();
+      WorkList.pop_back();
+
+      ExplodedNodeSet Tmp;
+      Visit(*X.Itr, X.N, Tmp);
+
+      InitListExpr::reverse_iterator NewItr = X.Itr + 1;
+
+      for (ExplodedNodeSet::iterator NI=Tmp.begin(),NE=Tmp.end();NI!=NE;++NI) {
+        // Get the last initializer value.
+        state = GetState(*NI);
+        SVal InitV = state->getSVal(cast<Expr>(*X.Itr));
+
+        // Construct the new list of values by prepending the new value to
+        // the already constructed list.
+        llvm::ImmutableList<SVal> NewVals =
+          getBasicVals().consVals(InitV, X.Vals);
+
+        if (NewItr == ItrEnd) {
+          // Now we have a list holding all init values. Make CompoundValData.
+          SVal V = ValMgr.makeCompoundVal(T, NewVals);
+
+          // Make final state and node.
+          MakeNode(Dst, E, *NI, state->BindExpr(E, V));
+        }
+        else {
+          // Still some initializer values to go.  Push them onto the worklist.
+          WorkList.push_back(InitListWLItem(*NI, NewVals, NewItr));
+        }
+      }
+    }
+
+    return;
+  }
+
+  if (Loc::IsLocType(T) || T->isIntegerType()) {
+    assert (E->getNumInits() == 1);
+    ExplodedNodeSet Tmp;
+    Expr* Init = E->getInit(0);
+    Visit(Init, Pred, Tmp);
+    for (ExplodedNodeSet::iterator I=Tmp.begin(), EI=Tmp.end(); I != EI; ++I) {
+      state = GetState(*I);
+      MakeNode(Dst, E, *I, state->BindExpr(E, state->getSVal(Init)));
+    }
+    return;
+  }
+
+  assert(0 && "unprocessed InitListExpr type");
+}
+
+/// VisitSizeOfAlignOfExpr - Transfer function for sizeof(type).
+void GRExprEngine::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr* Ex,
+                                          ExplodedNode* Pred,
+                                          ExplodedNodeSet& Dst) {
+  QualType T = Ex->getTypeOfArgument();
+  CharUnits amt;
+
+  if (Ex->isSizeOf()) {
+    if (T == getContext().VoidTy) {
+      // sizeof(void) == 1 byte.
+      amt = CharUnits::One();
+    }
+    else if (!T.getTypePtr()->isConstantSizeType()) {
+      // FIXME: Add support for VLAs.
+      Dst.Add(Pred);
+      return;
+    }
+    else if (T->isObjCInterfaceType()) {
+      // Some code tries to take the sizeof an ObjCInterfaceType, relying that
+      // the compiler has laid out its representation.  Just report Unknown
+      // for these.
+      Dst.Add(Pred);
+      return;
+    }
+    else {
+      // All other cases.
+      amt = getContext().getTypeSizeInChars(T);
+    }
+  }
+  else  // Get alignment of the type.
+    amt = getContext().getTypeAlignInChars(T);
+
+  MakeNode(Dst, Ex, Pred,
+           GetState(Pred)->BindExpr(Ex,
+              ValMgr.makeIntVal(amt.getQuantity(), Ex->getType())));
+}
+
+
+void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, ExplodedNode* Pred,
+                                      ExplodedNodeSet& Dst, bool asLValue) {
+
+  switch (U->getOpcode()) {
+
+    default:
+      break;
+
+    case UnaryOperator::Deref: {
+
+      Expr* Ex = U->getSubExpr()->IgnoreParens();
+      ExplodedNodeSet Tmp;
+      Visit(Ex, Pred, Tmp);
+
+      for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
+
+        const GRState* state = GetState(*I);
+        SVal location = state->getSVal(Ex);
+
+        if (asLValue)
+          MakeNode(Dst, U, *I, state->BindExpr(U, location),
+                   ProgramPoint::PostLValueKind);
+        else
+          EvalLoad(Dst, U, *I, state, location);
+      }
+
+      return;
+    }
+
+    case UnaryOperator::Real: {
+
+      Expr* Ex = U->getSubExpr()->IgnoreParens();
+      ExplodedNodeSet Tmp;
+      Visit(Ex, Pred, Tmp);
+
+      for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
+
+        // FIXME: We don't have complex SValues yet.
+        if (Ex->getType()->isAnyComplexType()) {
+          // Just report "Unknown."
+          Dst.Add(*I);
+          continue;
+        }
+
+        // For all other types, UnaryOperator::Real is an identity operation.
+        assert (U->getType() == Ex->getType());
+        const GRState* state = GetState(*I);
+        MakeNode(Dst, U, *I, state->BindExpr(U, state->getSVal(Ex)));
+      }
+
+      return;
+    }
+
+    case UnaryOperator::Imag: {
+
+      Expr* Ex = U->getSubExpr()->IgnoreParens();
+      ExplodedNodeSet Tmp;
+      Visit(Ex, Pred, Tmp);
+
+      for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
+        // FIXME: We don't have complex SValues yet.
+        if (Ex->getType()->isAnyComplexType()) {
+          // Just report "Unknown."
+          Dst.Add(*I);
+          continue;
+        }
+
+        // For all other types, UnaryOperator::Float returns 0.
+        assert (Ex->getType()->isIntegerType());
+        const GRState* state = GetState(*I);
+        SVal X = ValMgr.makeZeroVal(Ex->getType());
+        MakeNode(Dst, U, *I, state->BindExpr(U, X));
+      }
+
+      return;
+    }
+
+    case UnaryOperator::OffsetOf: {
+      Expr::EvalResult Res;
+      if (U->Evaluate(Res, getContext()) && Res.Val.isInt()) {
+        const APSInt &IV = Res.Val.getInt();
+        assert(IV.getBitWidth() == getContext().getTypeSize(U->getType()));
+        assert(U->getType()->isIntegerType());
+        assert(IV.isSigned() == U->getType()->isSignedIntegerType());
+        SVal X = ValMgr.makeIntVal(IV);
+        MakeNode(Dst, U, Pred, GetState(Pred)->BindExpr(U, X));
+        return;
+      }
+      // FIXME: Handle the case where __builtin_offsetof is not a constant.
+      Dst.Add(Pred);
+      return;
+    }
+
+    case UnaryOperator::Plus: assert (!asLValue);  // FALL-THROUGH.
+    case UnaryOperator::Extension: {
+
+      // Unary "+" is a no-op, similar to a parentheses.  We still have places
+      // where it may be a block-level expression, so we need to
+      // generate an extra node that just propagates the value of the
+      // subexpression.
+
+      Expr* Ex = U->getSubExpr()->IgnoreParens();
+      ExplodedNodeSet Tmp;
+      Visit(Ex, Pred, Tmp);
+
+      for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
+        const GRState* state = GetState(*I);
+        MakeNode(Dst, U, *I, state->BindExpr(U, state->getSVal(Ex)));
+      }
+
+      return;
+    }
+
+    case UnaryOperator::AddrOf: {
+
+      assert(!asLValue);
+      Expr* Ex = U->getSubExpr()->IgnoreParens();
+      ExplodedNodeSet Tmp;
+      VisitLValue(Ex, Pred, Tmp);
+
+      for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
+        const GRState* state = GetState(*I);
+        SVal V = state->getSVal(Ex);
+        state = state->BindExpr(U, V);
+        MakeNode(Dst, U, *I, state);
+      }
+
+      return;
+    }
+
+    case UnaryOperator::LNot:
+    case UnaryOperator::Minus:
+    case UnaryOperator::Not: {
+
+      assert (!asLValue);
+      Expr* Ex = U->getSubExpr()->IgnoreParens();
+      ExplodedNodeSet Tmp;
+      Visit(Ex, Pred, Tmp);
+
+      for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
+        const GRState* state = GetState(*I);
+
+        // Get the value of the subexpression.
+        SVal V = state->getSVal(Ex);
+
+        if (V.isUnknownOrUndef()) {
+          MakeNode(Dst, U, *I, state->BindExpr(U, V));
+          continue;
+        }
+
+//        QualType DstT = getContext().getCanonicalType(U->getType());
+//        QualType SrcT = getContext().getCanonicalType(Ex->getType());
+//
+//        if (DstT != SrcT) // Perform promotions.
+//          V = EvalCast(V, DstT);
+//
+//        if (V.isUnknownOrUndef()) {
+//          MakeNode(Dst, U, *I, BindExpr(St, U, V));
+//          continue;
+//        }
+
+        switch (U->getOpcode()) {
+          default:
+            assert(false && "Invalid Opcode.");
+            break;
+
+          case UnaryOperator::Not:
+            // FIXME: Do we need to handle promotions?
+            state = state->BindExpr(U, EvalComplement(cast<NonLoc>(V)));
+            break;
+
+          case UnaryOperator::Minus:
+            // FIXME: Do we need to handle promotions?
+            state = state->BindExpr(U, EvalMinus(cast<NonLoc>(V)));
+            break;
+
+          case UnaryOperator::LNot:
+
+            // C99 6.5.3.3: "The expression !E is equivalent to (0==E)."
+            //
+            //  Note: technically we do "E == 0", but this is the same in the
+            //    transfer functions as "0 == E".
+            SVal Result;
+
+            if (isa<Loc>(V)) {
+              Loc X = ValMgr.makeNull();
+              Result = EvalBinOp(state, BinaryOperator::EQ, cast<Loc>(V), X,
+                                 U->getType());
+            }
+            else {
+              nonloc::ConcreteInt X(getBasicVals().getValue(0, Ex->getType()));
+              Result = EvalBinOp(state, BinaryOperator::EQ, cast<NonLoc>(V), X,
+                                 U->getType());
+            }
+
+            state = state->BindExpr(U, Result);
+
+            break;
+        }
+
+        MakeNode(Dst, U, *I, state);
+      }
+
+      return;
+    }
+  }
+
+  // Handle ++ and -- (both pre- and post-increment).
+
+  assert (U->isIncrementDecrementOp());
+  ExplodedNodeSet Tmp;
+  Expr* Ex = U->getSubExpr()->IgnoreParens();
+  VisitLValue(Ex, Pred, Tmp);
+
+  for (ExplodedNodeSet::iterator I = Tmp.begin(), E = Tmp.end(); I!=E; ++I) {
+
+    const GRState* state = GetState(*I);
+    SVal V1 = state->getSVal(Ex);
+
+    // Perform a load.
+    ExplodedNodeSet Tmp2;
+    EvalLoad(Tmp2, Ex, *I, state, V1);
+
+    for (ExplodedNodeSet::iterator I2=Tmp2.begin(), E2=Tmp2.end();I2!=E2;++I2) {
+
+      state = GetState(*I2);
+      SVal V2_untested = state->getSVal(Ex);
+
+      // Propagate unknown and undefined values.
+      if (V2_untested.isUnknownOrUndef()) {
+        MakeNode(Dst, U, *I2, state->BindExpr(U, V2_untested));
+        continue;
+      }
+      DefinedSVal V2 = cast<DefinedSVal>(V2_untested);
+
+      // Handle all other values.
+      BinaryOperator::Opcode Op = U->isIncrementOp() ? BinaryOperator::Add
+                                                     : BinaryOperator::Sub;
+
+      // If the UnaryOperator has non-location type, use its type to create the
+      // constant value. If the UnaryOperator has location type, create the
+      // constant with int type and pointer width.
+      SVal RHS;
+
+      if (U->getType()->isAnyPointerType())
+        RHS = ValMgr.makeIntValWithPtrWidth(1, false);
+      else
+        RHS = ValMgr.makeIntVal(1, U->getType());
+
+      SVal Result = EvalBinOp(state, Op, V2, RHS, U->getType());
+
+      // Conjure a new symbol if necessary to recover precision.
+      if (Result.isUnknown() || !getConstraintManager().canReasonAbout(Result)){
+        DefinedOrUnknownSVal SymVal =
+          ValMgr.getConjuredSymbolVal(NULL, Ex,
+                                      Builder->getCurrentBlockCount());
+        Result = SymVal;
+
+        // If the value is a location, ++/-- should always preserve
+        // non-nullness.  Check if the original value was non-null, and if so
+        // propagate that constraint.
+        if (Loc::IsLocType(U->getType())) {
+          DefinedOrUnknownSVal Constraint =
+            SVator.EvalEQ(state, V2, ValMgr.makeZeroVal(U->getType()));
+
+          if (!state->Assume(Constraint, true)) {
+            // It isn't feasible for the original value to be null.
+            // Propagate this constraint.
+            Constraint = SVator.EvalEQ(state, SymVal,
+                                       ValMgr.makeZeroVal(U->getType()));
+
+
+            state = state->Assume(Constraint, false);
+            assert(state);
+          }
+        }
+      }
+
+      state = state->BindExpr(U, U->isPostfix() ? V2 : Result);
+
+      // Perform the store.
+      EvalStore(Dst, NULL, U, *I2, state, V1, Result);
+    }
+  }
+}
+
+void GRExprEngine::VisitAsmStmt(AsmStmt* A, ExplodedNode* Pred,
+                                ExplodedNodeSet& Dst) {
+  VisitAsmStmtHelperOutputs(A, A->begin_outputs(), A->end_outputs(), Pred, Dst);
+}
+
+void GRExprEngine::VisitAsmStmtHelperOutputs(AsmStmt* A,
+                                             AsmStmt::outputs_iterator I,
+                                             AsmStmt::outputs_iterator E,
+                                     ExplodedNode* Pred, ExplodedNodeSet& Dst) {
+  if (I == E) {
+    VisitAsmStmtHelperInputs(A, A->begin_inputs(), A->end_inputs(), Pred, Dst);
+    return;
+  }
+
+  ExplodedNodeSet Tmp;
+  VisitLValue(*I, Pred, Tmp);
+
+  ++I;
+
+  for (ExplodedNodeSet::iterator NI = Tmp.begin(), NE = Tmp.end();NI != NE;++NI)
+    VisitAsmStmtHelperOutputs(A, I, E, *NI, Dst);
+}
+
+void GRExprEngine::VisitAsmStmtHelperInputs(AsmStmt* A,
+                                            AsmStmt::inputs_iterator I,
+                                            AsmStmt::inputs_iterator E,
+                                            ExplodedNode* Pred,
+                                            ExplodedNodeSet& Dst) {
+  if (I == E) {
+
+    // We have processed both the inputs and the outputs.  All of the outputs
+    // should evaluate to Locs.  Nuke all of their values.
+
+    // FIXME: Some day in the future it would be nice to allow a "plug-in"
+    // which interprets the inline asm and stores proper results in the
+    // outputs.
+
+    const GRState* state = GetState(Pred);
+
+    for (AsmStmt::outputs_iterator OI = A->begin_outputs(),
+                                   OE = A->end_outputs(); OI != OE; ++OI) {
+
+      SVal X = state->getSVal(*OI);
+      assert (!isa<NonLoc>(X));  // Should be an Lval, or unknown, undef.
+
+      if (isa<Loc>(X))
+        state = state->bindLoc(cast<Loc>(X), UnknownVal());
+    }
+
+    MakeNode(Dst, A, Pred, state);
+    return;
+  }
+
+  ExplodedNodeSet Tmp;
+  Visit(*I, Pred, Tmp);
+
+  ++I;
+
+  for (ExplodedNodeSet::iterator NI = Tmp.begin(), NE = Tmp.end(); NI!=NE; ++NI)
+    VisitAsmStmtHelperInputs(A, I, E, *NI, Dst);
+}
+
+void GRExprEngine::VisitReturnStmt(ReturnStmt *RS, ExplodedNode *Pred,
+                                   ExplodedNodeSet &Dst) {
+  ExplodedNodeSet Src;
+  if (Expr *RetE = RS->getRetValue()) {
+    // Record the returned expression in the state. It will be used in
+    // ProcessCallExit to bind the return value to the call expr.
+    {
+      static int Tag = 0;
+      SaveAndRestore<const void *> OldTag(Builder->Tag, &Tag);
+      const GRState *state = GetState(Pred);
+      state = state->set<ReturnExpr>(RetE);
+      Pred = Builder->generateNode(RetE, state, Pred);
+    }
+    // We may get a NULL Pred because we generated a cached node.
+    if (Pred)
+      Visit(RetE, Pred, Src);
+  }
+  else {
+    Src.Add(Pred);
+  }
+
+  ExplodedNodeSet CheckedSet;
+  CheckerVisit(RS, CheckedSet, Src, true);
+
+  for (ExplodedNodeSet::iterator I = CheckedSet.begin(), E = CheckedSet.end();
+       I != E; ++I) {
+
+    assert(Builder && "GRStmtNodeBuilder must be defined.");
+
+    Pred = *I;
+    unsigned size = Dst.size();
+
+    SaveAndRestore<bool> OldSink(Builder->BuildSinks);
+    SaveOr OldHasGen(Builder->HasGeneratedNode);
+
+    getTF().EvalReturn(Dst, *this, *Builder, RS, Pred);
+
+    // Handle the case where no nodes where generated.
+    if (!Builder->BuildSinks && Dst.size() == size &&
+        !Builder->HasGeneratedNode)
+      MakeNode(Dst, RS, Pred, GetState(Pred));
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// Transfer functions: Binary operators.
+//===----------------------------------------------------------------------===//
+
+void GRExprEngine::VisitBinaryOperator(BinaryOperator* B,
+                                       ExplodedNode* Pred,
+                                       ExplodedNodeSet& Dst, bool asLValue) {
+
+  ExplodedNodeSet Tmp1;
+  Expr* LHS = B->getLHS()->IgnoreParens();
+  Expr* RHS = B->getRHS()->IgnoreParens();
+
+  // FIXME: Add proper support for ObjCImplicitSetterGetterRefExpr.
+  if (isa<ObjCImplicitSetterGetterRefExpr>(LHS)) {
+    Visit(RHS, Pred, Dst);
+    return;
+  }
+
+  if (B->isAssignmentOp())
+    VisitLValue(LHS, Pred, Tmp1);
+  else
+    Visit(LHS, Pred, Tmp1);
+
+  ExplodedNodeSet Tmp3;
+
+  for (ExplodedNodeSet::iterator I1=Tmp1.begin(), E1=Tmp1.end(); I1!=E1; ++I1) {
+    SVal LeftV = GetState(*I1)->getSVal(LHS);
+    ExplodedNodeSet Tmp2;
+    Visit(RHS, *I1, Tmp2);
+
+    ExplodedNodeSet CheckedSet;
+    CheckerVisit(B, CheckedSet, Tmp2, true);
+
+    // With both the LHS and RHS evaluated, process the operation itself.
+
+    for (ExplodedNodeSet::iterator I2=CheckedSet.begin(), E2=CheckedSet.end();
+         I2 != E2; ++I2) {
+
+      const GRState *state = GetState(*I2);
+      const GRState *OldSt = state;
+      SVal RightV = state->getSVal(RHS);
+
+      BinaryOperator::Opcode Op = B->getOpcode();
+
+      if (Op == BinaryOperator::Assign) {
+        // EXPERIMENTAL: "Conjured" symbols.
+        // FIXME: Handle structs.
+        QualType T = RHS->getType();
+
+        if ((RightV.isUnknown()||!getConstraintManager().canReasonAbout(RightV))
+            && (Loc::IsLocType(T) || (T->isScalarType()&&T->isIntegerType()))) {
+          unsigned Count = Builder->getCurrentBlockCount();
+          RightV = ValMgr.getConjuredSymbolVal(NULL, B->getRHS(), Count);
+        }
+
+        SVal ExprVal = asLValue ? LeftV : RightV;
+
+        // Simulate the effects of a "store":  bind the value of the RHS
+        // to the L-Value represented by the LHS.
+        EvalStore(Tmp3, B, LHS, *I2, state->BindExpr(B, ExprVal), LeftV,RightV);
+        continue;
+      }
+
+      if (!B->isAssignmentOp()) {
+        // Process non-assignments except commas or short-circuited
+        // logical expressions (LAnd and LOr).
+        SVal Result = EvalBinOp(state, Op, LeftV, RightV, B->getType());
+
+        if (Result.isUnknown()) {
+          if (OldSt != state) {
+            // Generate a new node if we have already created a new state.
+            MakeNode(Tmp3, B, *I2, state);
+          }
+          else
+            Tmp3.Add(*I2);
+
+          continue;
+        }
+
+        state = state->BindExpr(B, Result);
+
+        MakeNode(Tmp3, B, *I2, state);
+        continue;
+      }
+
+      assert (B->isCompoundAssignmentOp());
+
+      switch (Op) {
+        default:
+          assert(0 && "Invalid opcode for compound assignment.");
+        case BinaryOperator::MulAssign: Op = BinaryOperator::Mul; break;
+        case BinaryOperator::DivAssign: Op = BinaryOperator::Div; break;
+        case BinaryOperator::RemAssign: Op = BinaryOperator::Rem; break;
+        case BinaryOperator::AddAssign: Op = BinaryOperator::Add; break;
+        case BinaryOperator::SubAssign: Op = BinaryOperator::Sub; break;
+        case BinaryOperator::ShlAssign: Op = BinaryOperator::Shl; break;
+        case BinaryOperator::ShrAssign: Op = BinaryOperator::Shr; break;
+        case BinaryOperator::AndAssign: Op = BinaryOperator::And; break;
+        case BinaryOperator::XorAssign: Op = BinaryOperator::Xor; break;
+        case BinaryOperator::OrAssign:  Op = BinaryOperator::Or;  break;
+      }
+
+      // Perform a load (the LHS).  This performs the checks for
+      // null dereferences, and so on.
+      ExplodedNodeSet Tmp4;
+      SVal location = state->getSVal(LHS);
+      EvalLoad(Tmp4, LHS, *I2, state, location);
+
+      for (ExplodedNodeSet::iterator I4=Tmp4.begin(), E4=Tmp4.end(); I4!=E4;
+           ++I4) {
+        state = GetState(*I4);
+        SVal V = state->getSVal(LHS);
+
+        // Get the computation type.
+        QualType CTy =
+          cast<CompoundAssignOperator>(B)->getComputationResultType();
+        CTy = getContext().getCanonicalType(CTy);
+
+        QualType CLHSTy =
+          cast<CompoundAssignOperator>(B)->getComputationLHSType();
+        CLHSTy = getContext().getCanonicalType(CLHSTy);
+
+        QualType LTy = getContext().getCanonicalType(LHS->getType());
+        QualType RTy = getContext().getCanonicalType(RHS->getType());
+
+        // Promote LHS.
+        V = SVator.EvalCast(V, CLHSTy, LTy);
+
+        // Compute the result of the operation.
+        SVal Result = SVator.EvalCast(EvalBinOp(state, Op, V, RightV, CTy),
+                                      B->getType(), CTy);
+
+        // EXPERIMENTAL: "Conjured" symbols.
+        // FIXME: Handle structs.
+
+        SVal LHSVal;
+
+        if ((Result.isUnknown() ||
+             !getConstraintManager().canReasonAbout(Result))
+            && (Loc::IsLocType(CTy)
+                || (CTy->isScalarType() && CTy->isIntegerType()))) {
+
+          unsigned Count = Builder->getCurrentBlockCount();
+
+          // The symbolic value is actually for the type of the left-hand side
+          // expression, not the computation type, as this is the value the
+          // LValue on the LHS will bind to.
+          LHSVal = ValMgr.getConjuredSymbolVal(NULL, B->getRHS(), LTy, Count);
+
+          // However, we need to convert the symbol to the computation type.
+          Result = SVator.EvalCast(LHSVal, CTy, LTy);
+        }
+        else {
+          // The left-hand side may bind to a different value then the
+          // computation type.
+          LHSVal = SVator.EvalCast(Result, LTy, CTy);
+        }
+
+        EvalStore(Tmp3, B, LHS, *I4, state->BindExpr(B, Result),
+                  location, LHSVal);
+      }
+    }
+  }
+
+  CheckerVisit(B, Dst, Tmp3, false);
+}
+
+//===----------------------------------------------------------------------===//
+// Checker registration/lookup.
+//===----------------------------------------------------------------------===//
+
+Checker *GRExprEngine::lookupChecker(void *tag) const {
+  CheckerMap::const_iterator I = CheckerM.find(tag);
+  return (I == CheckerM.end()) ? NULL : Checkers[I->second].second;
+}
+
+//===----------------------------------------------------------------------===//
+// Visualization.
+//===----------------------------------------------------------------------===//
+
+#ifndef NDEBUG
+static GRExprEngine* GraphPrintCheckerState;
+static SourceManager* GraphPrintSourceManager;
+
+namespace llvm {
+template<>
+struct DOTGraphTraits<ExplodedNode*> :
+  public DefaultDOTGraphTraits {
+
+  DOTGraphTraits (bool isSimple=false) : DefaultDOTGraphTraits(isSimple) {}
+
+  // FIXME: Since we do not cache error nodes in GRExprEngine now, this does not
+  // work.
+  static std::string getNodeAttributes(const ExplodedNode* N, void*) {
+
+#if 0
+      // FIXME: Replace with a general scheme to tell if the node is
+      // an error node.
+    if (GraphPrintCheckerState->isImplicitNullDeref(N) ||
+        GraphPrintCheckerState->isExplicitNullDeref(N) ||
+        GraphPrintCheckerState->isUndefDeref(N) ||
+        GraphPrintCheckerState->isUndefStore(N) ||
+        GraphPrintCheckerState->isUndefControlFlow(N) ||
+        GraphPrintCheckerState->isUndefResult(N) ||
+        GraphPrintCheckerState->isBadCall(N) ||
+        GraphPrintCheckerState->isUndefArg(N))
+      return "color=\"red\",style=\"filled\"";
+
+    if (GraphPrintCheckerState->isNoReturnCall(N))
+      return "color=\"blue\",style=\"filled\"";
+#endif
+    return "";
+  }
+
+  static std::string getNodeLabel(const ExplodedNode* N, void*){
+
+    std::string sbuf;
+    llvm::raw_string_ostream Out(sbuf);
+
+    // Program Location.
+    ProgramPoint Loc = N->getLocation();
+
+    switch (Loc.getKind()) {
+      case ProgramPoint::BlockEntranceKind:
+        Out << "Block Entrance: B"
+            << cast<BlockEntrance>(Loc).getBlock()->getBlockID();
+        break;
+
+      case ProgramPoint::BlockExitKind:
+        assert (false);
+        break;
+
+      case ProgramPoint::CallEnterKind:
+        Out << "CallEnter";
+        break;
+
+      case ProgramPoint::CallExitKind:
+        Out << "CallExit";
+        break;
+
+      default: {
+        if (StmtPoint *L = dyn_cast<StmtPoint>(&Loc)) {
+          const Stmt* S = L->getStmt();
+          SourceLocation SLoc = S->getLocStart();
+
+          Out << S->getStmtClassName() << ' ' << (void*) S << ' ';
+          LangOptions LO; // FIXME.
+          S->printPretty(Out, 0, PrintingPolicy(LO));
+
+          if (SLoc.isFileID()) {
+            Out << "\\lline="
+              << GraphPrintSourceManager->getInstantiationLineNumber(SLoc)
+              << " col="
+              << GraphPrintSourceManager->getInstantiationColumnNumber(SLoc)
+              << "\\l";
+          }
+
+          if (isa<PreStmt>(Loc))
+            Out << "\\lPreStmt\\l;";
+          else if (isa<PostLoad>(Loc))
+            Out << "\\lPostLoad\\l;";
+          else if (isa<PostStore>(Loc))
+            Out << "\\lPostStore\\l";
+          else if (isa<PostLValue>(Loc))
+            Out << "\\lPostLValue\\l";
+
+#if 0
+            // FIXME: Replace with a general scheme to determine
+            // the name of the check.
+          if (GraphPrintCheckerState->isImplicitNullDeref(N))
+            Out << "\\|Implicit-Null Dereference.\\l";
+          else if (GraphPrintCheckerState->isExplicitNullDeref(N))
+            Out << "\\|Explicit-Null Dereference.\\l";
+          else if (GraphPrintCheckerState->isUndefDeref(N))
+            Out << "\\|Dereference of undefialied value.\\l";
+          else if (GraphPrintCheckerState->isUndefStore(N))
+            Out << "\\|Store to Undefined Loc.";
+          else if (GraphPrintCheckerState->isUndefResult(N))
+            Out << "\\|Result of operation is undefined.";
+          else if (GraphPrintCheckerState->isNoReturnCall(N))
+            Out << "\\|Call to function marked \"noreturn\".";
+          else if (GraphPrintCheckerState->isBadCall(N))
+            Out << "\\|Call to NULL/Undefined.";
+          else if (GraphPrintCheckerState->isUndefArg(N))
+            Out << "\\|Argument in call is undefined";
+#endif
+
+          break;
+        }
+
+        const BlockEdge& E = cast<BlockEdge>(Loc);
+        Out << "Edge: (B" << E.getSrc()->getBlockID() << ", B"
+            << E.getDst()->getBlockID()  << ')';
+
+        if (Stmt* T = E.getSrc()->getTerminator()) {
+
+          SourceLocation SLoc = T->getLocStart();
+
+          Out << "\\|Terminator: ";
+          LangOptions LO; // FIXME.
+          E.getSrc()->printTerminator(Out, LO);
+
+          if (SLoc.isFileID()) {
+            Out << "\\lline="
+              << GraphPrintSourceManager->getInstantiationLineNumber(SLoc)
+              << " col="
+              << GraphPrintSourceManager->getInstantiationColumnNumber(SLoc);
+          }
+
+          if (isa<SwitchStmt>(T)) {
+            Stmt* Label = E.getDst()->getLabel();
+
+            if (Label) {
+              if (CaseStmt* C = dyn_cast<CaseStmt>(Label)) {
+                Out << "\\lcase ";
+                LangOptions LO; // FIXME.
+                C->getLHS()->printPretty(Out, 0, PrintingPolicy(LO));
+
+                if (Stmt* RHS = C->getRHS()) {
+                  Out << " .. ";
+                  RHS->printPretty(Out, 0, PrintingPolicy(LO));
+                }
+
+                Out << ":";
+              }
+              else {
+                assert (isa<DefaultStmt>(Label));
+                Out << "\\ldefault:";
+              }
+            }
+            else
+              Out << "\\l(implicit) default:";
+          }
+          else if (isa<IndirectGotoStmt>(T)) {
+            // FIXME
+          }
+          else {
+            Out << "\\lCondition: ";
+            if (*E.getSrc()->succ_begin() == E.getDst())
+              Out << "true";
+            else
+              Out << "false";
+          }
+
+          Out << "\\l";
+        }
+
+#if 0
+          // FIXME: Replace with a general scheme to determine
+          // the name of the check.
+        if (GraphPrintCheckerState->isUndefControlFlow(N)) {
+          Out << "\\|Control-flow based on\\lUndefined value.\\l";
+        }
+#endif
+      }
+    }
+
+    Out << "\\|StateID: " << (void*) N->getState() << "\\|";
+
+    const GRState *state = N->getState();
+    state->printDOT(Out, *N->getLocationContext()->getCFG());
+
+    Out << "\\l";
+    return Out.str();
+  }
+};
+} // end llvm namespace
+#endif
+
+#ifndef NDEBUG
+template <typename ITERATOR>
+ExplodedNode* GetGraphNode(ITERATOR I) { return *I; }
+
+template <> ExplodedNode*
+GetGraphNode<llvm::DenseMap<ExplodedNode*, Expr*>::iterator>
+  (llvm::DenseMap<ExplodedNode*, Expr*>::iterator I) {
+  return I->first;
+}
+#endif
+
+void GRExprEngine::ViewGraph(bool trim) {
+#ifndef NDEBUG
+  if (trim) {
+    std::vector<ExplodedNode*> Src;
+
+    // Flush any outstanding reports to make sure we cover all the nodes.
+    // This does not cause them to get displayed.
+    for (BugReporter::iterator I=BR.begin(), E=BR.end(); I!=E; ++I)
+      const_cast<BugType*>(*I)->FlushReports(BR);
+
+    // Iterate through the reports and get their nodes.
+    for (BugReporter::iterator I=BR.begin(), E=BR.end(); I!=E; ++I) {
+      for (BugType::const_iterator I2=(*I)->begin(), E2=(*I)->end();
+           I2!=E2; ++I2) {
+        const BugReportEquivClass& EQ = *I2;
+        const BugReport &R = **EQ.begin();
+        ExplodedNode *N = const_cast<ExplodedNode*>(R.getEndNode());
+        if (N) Src.push_back(N);
+      }
+    }
+
+    ViewGraph(&Src[0], &Src[0]+Src.size());
+  }
+  else {
+    GraphPrintCheckerState = this;
+    GraphPrintSourceManager = &getContext().getSourceManager();
+
+    llvm::ViewGraph(*G.roots_begin(), "GRExprEngine");
+
+    GraphPrintCheckerState = NULL;
+    GraphPrintSourceManager = NULL;
+  }
+#endif
+}
+
+void GRExprEngine::ViewGraph(ExplodedNode** Beg, ExplodedNode** End) {
+#ifndef NDEBUG
+  GraphPrintCheckerState = this;
+  GraphPrintSourceManager = &getContext().getSourceManager();
+
+  std::auto_ptr<ExplodedGraph> TrimmedG(G.Trim(Beg, End).first);
+
+  if (!TrimmedG.get())
+    llvm::errs() << "warning: Trimmed ExplodedGraph is empty.\n";
+  else
+    llvm::ViewGraph(*TrimmedG->roots_begin(), "TrimmedGRExprEngine");
+
+  GraphPrintCheckerState = NULL;
+  GraphPrintSourceManager = NULL;
+#endif
+}
diff --git a/lib/Checker/GRExprEngineExperimentalChecks.cpp b/lib/Checker/GRExprEngineExperimentalChecks.cpp
new file mode 100644
index 0000000..89b4e4b
--- /dev/null
+++ b/lib/Checker/GRExprEngineExperimentalChecks.cpp
@@ -0,0 +1,40 @@
+//=-- GRExprEngineExperimentalChecks.h ------------------------------*- C++ -*-=
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines functions to instantiate and register experimental
+//  checks in GRExprEngine.
+//
+//===----------------------------------------------------------------------===//
+
+#include "GRExprEngineInternalChecks.h"
+#include "GRExprEngineExperimentalChecks.h"
+#include "clang/Checker/Checkers/LocalCheckers.h"
+
+using namespace clang;
+
+void clang::RegisterExperimentalChecks(GRExprEngine &Eng) {  
+  // These are checks that never belong as internal checks
+  // within GRExprEngine.
+  RegisterPthreadLockChecker(Eng);  
+  RegisterMallocChecker(Eng);
+}
+
+void clang::RegisterExperimentalInternalChecks(GRExprEngine &Eng) {
+  // These are internal checks that should eventually migrate to
+  // RegisterInternalChecks() once they have been further tested.
+  
+  // Note that this must be registered after ReturnStackAddresEngsChecker.
+  RegisterReturnPointerRangeChecker(Eng);
+  
+  RegisterFixedAddressChecker(Eng);
+  RegisterPointerSubChecker(Eng);
+  RegisterPointerArithChecker(Eng);
+  RegisterCastToStructChecker(Eng);
+  RegisterArrayBoundChecker(Eng);
+}
diff --git a/lib/Checker/GRExprEngineExperimentalChecks.h b/lib/Checker/GRExprEngineExperimentalChecks.h
new file mode 100644
index 0000000..9a9da32
--- /dev/null
+++ b/lib/Checker/GRExprEngineExperimentalChecks.h
@@ -0,0 +1,26 @@
+//=-- GRExprEngineExperimentalChecks.h ------------------------------*- C++ -*-=
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines functions to instantiate and register experimental
+//  checks in GRExprEngine.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_GREXPRENGINE_EXPERIMENTAL_CHECKS
+#define LLVM_CLANG_GREXPRENGINE_EXPERIMENTAL_CHECKS
+
+namespace clang {
+
+class GRExprEngine;
+
+void RegisterPthreadLockChecker(GRExprEngine &Eng);
+void RegisterMallocChecker(GRExprEngine &Eng);
+
+} // end clang namespace
+#endif
diff --git a/lib/Checker/GRExprEngineInternalChecks.h b/lib/Checker/GRExprEngineInternalChecks.h
new file mode 100644
index 0000000..d117600
--- /dev/null
+++ b/lib/Checker/GRExprEngineInternalChecks.h
@@ -0,0 +1,51 @@
+//=-- GRExprEngineInternalChecks.h- Builtin GRExprEngine Checks -----*- C++ -*-=
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines functions to instantiate and register the "built-in"
+//  checks in GRExprEngine.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_GREXPRENGINE_INTERNAL_CHECKS
+#define LLVM_CLANG_GREXPRENGINE_INTERNAL_CHECKS
+
+namespace clang {
+
+class GRExprEngine;
+
+// Foundational checks that handle basic semantics.
+void RegisterAdjustedReturnValueChecker(GRExprEngine &Eng);
+void RegisterArrayBoundChecker(GRExprEngine &Eng);
+void RegisterAttrNonNullChecker(GRExprEngine &Eng);
+void RegisterBuiltinFunctionChecker(GRExprEngine &Eng);
+void RegisterCallAndMessageChecker(GRExprEngine &Eng);
+void RegisterCastToStructChecker(GRExprEngine &Eng);
+void RegisterDereferenceChecker(GRExprEngine &Eng);
+void RegisterDivZeroChecker(GRExprEngine &Eng);
+void RegisterFixedAddressChecker(GRExprEngine &Eng);
+void RegisterNoReturnFunctionChecker(GRExprEngine &Eng);
+void RegisterPointerArithChecker(GRExprEngine &Eng);
+void RegisterPointerSubChecker(GRExprEngine &Eng);
+void RegisterReturnPointerRangeChecker(GRExprEngine &Eng);
+void RegisterReturnStackAddressChecker(GRExprEngine &Eng);
+void RegisterReturnUndefChecker(GRExprEngine &Eng);
+void RegisterUndefBranchChecker(GRExprEngine &Eng);
+void RegisterUndefCapturedBlockVarChecker(GRExprEngine &Eng);
+void RegisterUndefResultChecker(GRExprEngine &Eng);
+void RegisterUndefinedArraySubscriptChecker(GRExprEngine &Eng);
+void RegisterUndefinedAssignmentChecker(GRExprEngine &Eng);
+void RegisterVLASizeChecker(GRExprEngine &Eng);
+
+// API checks.
+void RegisterMacOSXAPIChecker(GRExprEngine &Eng);
+void RegisterOSAtomicChecker(GRExprEngine &Eng);
+void RegisterUnixAPIChecker(GRExprEngine &Eng);
+
+} // end clang namespace
+#endif
diff --git a/lib/Checker/GRState.cpp b/lib/Checker/GRState.cpp
new file mode 100644
index 0000000..f68e10b
--- /dev/null
+++ b/lib/Checker/GRState.cpp
@@ -0,0 +1,371 @@
+//= GRState.cpp - Path-Sensitive "State" for tracking values -----*- C++ -*--=//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements GRState and GRStateManager.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Analysis/CFG.h"
+#include "clang/Checker/PathSensitive/GRStateTrait.h"
+#include "clang/Checker/PathSensitive/GRState.h"
+#include "clang/Checker/PathSensitive/GRTransferFuncs.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace clang;
+
+// Give the vtable for ConstraintManager somewhere to live.
+// FIXME: Move this elsewhere.
+ConstraintManager::~ConstraintManager() {}
+
+GRStateManager::~GRStateManager() {
+  for (std::vector<GRState::Printer*>::iterator I=Printers.begin(),
+        E=Printers.end(); I!=E; ++I)
+    delete *I;
+
+  for (GDMContextsTy::iterator I=GDMContexts.begin(), E=GDMContexts.end();
+       I!=E; ++I)
+    I->second.second(I->second.first);
+}
+
+const GRState*
+GRStateManager::RemoveDeadBindings(const GRState* state, Stmt* Loc,
+                                   const StackFrameContext *LCtx,
+                                   SymbolReaper& SymReaper) {
+
+  // This code essentially performs a "mark-and-sweep" of the VariableBindings.
+  // The roots are any Block-level exprs and Decls that our liveness algorithm
+  // tells us are live.  We then see what Decls they may reference, and keep
+  // those around.  This code more than likely can be made faster, and the
+  // frequency of which this method is called should be experimented with
+  // for optimum performance.
+  llvm::SmallVector<const MemRegion*, 10> RegionRoots;
+  GRState NewState = *state;
+
+  NewState.Env = EnvMgr.RemoveDeadBindings(NewState.Env, Loc, SymReaper,
+                                           state, RegionRoots);
+
+  // Clean up the store.
+  NewState.St = StoreMgr->RemoveDeadBindings(NewState.St, Loc, LCtx, SymReaper, 
+                                             RegionRoots);
+
+  return ConstraintMgr->RemoveDeadBindings(getPersistentState(NewState),
+                                           SymReaper);
+}
+
+const GRState *GRState::unbindLoc(Loc LV) const {
+  Store OldStore = getStore();
+  Store NewStore = getStateManager().StoreMgr->Remove(OldStore, LV);
+
+  if (NewStore == OldStore)
+    return this;
+
+  GRState NewSt = *this;
+  NewSt.St = NewStore;
+  return getStateManager().getPersistentState(NewSt);
+}
+
+SVal GRState::getSValAsScalarOrLoc(const MemRegion *R) const {
+  // We only want to do fetches from regions that we can actually bind
+  // values.  For example, SymbolicRegions of type 'id<...>' cannot
+  // have direct bindings (but their can be bindings on their subregions).
+  if (!R->isBoundable())
+    return UnknownVal();
+
+  if (const TypedRegion *TR = dyn_cast<TypedRegion>(R)) {
+    QualType T = TR->getValueType(getStateManager().getContext());
+    if (Loc::IsLocType(T) || T->isIntegerType())
+      return getSVal(R);
+  }
+
+  return UnknownVal();
+}
+
+
+const GRState *GRState::BindExpr(const Stmt* Ex, SVal V, bool Invalidate) const{
+  Environment NewEnv = getStateManager().EnvMgr.BindExpr(Env, Ex, V,
+                                                         Invalidate);
+  if (NewEnv == Env)
+    return this;
+
+  GRState NewSt = *this;
+  NewSt.Env = NewEnv;
+  return getStateManager().getPersistentState(NewSt);
+}
+
+const GRState* GRStateManager::getInitialState(const LocationContext *InitLoc) {
+  GRState State(this,
+                EnvMgr.getInitialEnvironment(),
+                StoreMgr->getInitialStore(InitLoc),
+                GDMFactory.GetEmptyMap());
+
+  return getPersistentState(State);
+}
+
+const GRState* GRStateManager::getPersistentState(GRState& State) {
+
+  llvm::FoldingSetNodeID ID;
+  State.Profile(ID);
+  void* InsertPos;
+
+  if (GRState* I = StateSet.FindNodeOrInsertPos(ID, InsertPos))
+    return I;
+
+  GRState* I = (GRState*) Alloc.Allocate<GRState>();
+  new (I) GRState(State);
+  StateSet.InsertNode(I, InsertPos);
+  return I;
+}
+
+const GRState* GRState::makeWithStore(Store store) const {
+  GRState NewSt = *this;
+  NewSt.St = store;
+  return getStateManager().getPersistentState(NewSt);
+}
+
+//===----------------------------------------------------------------------===//
+//  State pretty-printing.
+//===----------------------------------------------------------------------===//
+
+void GRState::print(llvm::raw_ostream& Out, CFG &C, const char* nl,
+                    const char* sep) const {
+  // Print the store.
+  GRStateManager &Mgr = getStateManager();
+  Mgr.getStoreManager().print(getStore(), Out, nl, sep);
+
+  // Print Subexpression bindings.
+  bool isFirst = true;
+
+  for (Environment::iterator I = Env.begin(), E = Env.end(); I != E; ++I) {
+    if (C.isBlkExpr(I.getKey()))
+      continue;
+
+    if (isFirst) {
+      Out << nl << nl << "Sub-Expressions:" << nl;
+      isFirst = false;
+    }
+    else { Out << nl; }
+
+    Out << " (" << (void*) I.getKey() << ") ";
+    LangOptions LO; // FIXME.
+    I.getKey()->printPretty(Out, 0, PrintingPolicy(LO));
+    Out << " : " << I.getData();
+  }
+
+  // Print block-expression bindings.
+  isFirst = true;
+
+  for (Environment::iterator I = Env.begin(), E = Env.end(); I != E; ++I) {
+    if (!C.isBlkExpr(I.getKey()))
+      continue;
+
+    if (isFirst) {
+      Out << nl << nl << "Block-level Expressions:" << nl;
+      isFirst = false;
+    }
+    else { Out << nl; }
+
+    Out << " (" << (void*) I.getKey() << ") ";
+    LangOptions LO; // FIXME.
+    I.getKey()->printPretty(Out, 0, PrintingPolicy(LO));
+    Out << " : " << I.getData();
+  }
+
+  Mgr.getConstraintManager().print(this, Out, nl, sep);
+
+  // Print checker-specific data.
+  for (std::vector<Printer*>::iterator I = Mgr.Printers.begin(),
+                                       E = Mgr.Printers.end(); I != E; ++I) {
+    (*I)->Print(Out, this, nl, sep);
+  }
+}
+
+void GRState::printDOT(llvm::raw_ostream& Out, CFG &C) const {
+  print(Out, C, "\\l", "\\|");
+}
+
+void GRState::printStdErr(CFG &C) const {
+  print(llvm::errs(), C);
+}
+
+//===----------------------------------------------------------------------===//
+// Generic Data Map.
+//===----------------------------------------------------------------------===//
+
+void* const* GRState::FindGDM(void* K) const {
+  return GDM.lookup(K);
+}
+
+void*
+GRStateManager::FindGDMContext(void* K,
+                               void* (*CreateContext)(llvm::BumpPtrAllocator&),
+                               void (*DeleteContext)(void*)) {
+
+  std::pair<void*, void (*)(void*)>& p = GDMContexts[K];
+  if (!p.first) {
+    p.first = CreateContext(Alloc);
+    p.second = DeleteContext;
+  }
+
+  return p.first;
+}
+
+const GRState* GRStateManager::addGDM(const GRState* St, void* Key, void* Data){
+  GRState::GenericDataMap M1 = St->getGDM();
+  GRState::GenericDataMap M2 = GDMFactory.Add(M1, Key, Data);
+
+  if (M1 == M2)
+    return St;
+
+  GRState NewSt = *St;
+  NewSt.GDM = M2;
+  return getPersistentState(NewSt);
+}
+
+const GRState *GRStateManager::removeGDM(const GRState *state, void *Key) {
+  GRState::GenericDataMap OldM = state->getGDM();
+  GRState::GenericDataMap NewM = GDMFactory.Remove(OldM, Key);
+
+  if (NewM == OldM)
+    return state;
+
+  GRState NewState = *state;
+  NewState.GDM = NewM;
+  return getPersistentState(NewState);
+}
+
+//===----------------------------------------------------------------------===//
+// Utility.
+//===----------------------------------------------------------------------===//
+
+namespace {
+class ScanReachableSymbols : public SubRegionMap::Visitor  {
+  typedef llvm::DenseSet<const MemRegion*> VisitedRegionsTy;
+
+  VisitedRegionsTy visited;
+  const GRState *state;
+  SymbolVisitor &visitor;
+  llvm::OwningPtr<SubRegionMap> SRM;
+public:
+
+  ScanReachableSymbols(const GRState *st, SymbolVisitor& v)
+    : state(st), visitor(v) {}
+
+  bool scan(nonloc::CompoundVal val);
+  bool scan(SVal val);
+  bool scan(const MemRegion *R);
+
+  // From SubRegionMap::Visitor.
+  bool Visit(const MemRegion* Parent, const MemRegion* SubRegion) {
+    return scan(SubRegion);
+  }
+};
+}
+
+bool ScanReachableSymbols::scan(nonloc::CompoundVal val) {
+  for (nonloc::CompoundVal::iterator I=val.begin(), E=val.end(); I!=E; ++I)
+    if (!scan(*I))
+      return false;
+
+  return true;
+}
+
+bool ScanReachableSymbols::scan(SVal val) {
+  if (loc::MemRegionVal *X = dyn_cast<loc::MemRegionVal>(&val))
+    return scan(X->getRegion());
+
+  if (nonloc::LocAsInteger *X = dyn_cast<nonloc::LocAsInteger>(&val))
+    return scan(X->getLoc());
+
+  if (SymbolRef Sym = val.getAsSymbol())
+    return visitor.VisitSymbol(Sym);
+
+  if (nonloc::CompoundVal *X = dyn_cast<nonloc::CompoundVal>(&val))
+    return scan(*X);
+
+  return true;
+}
+
+bool ScanReachableSymbols::scan(const MemRegion *R) {
+  if (isa<MemSpaceRegion>(R) || visited.count(R))
+    return true;
+
+  visited.insert(R);
+
+  // If this is a symbolic region, visit the symbol for the region.
+  if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R))
+    if (!visitor.VisitSymbol(SR->getSymbol()))
+      return false;
+
+  // If this is a subregion, also visit the parent regions.
+  if (const SubRegion *SR = dyn_cast<SubRegion>(R))
+    if (!scan(SR->getSuperRegion()))
+      return false;
+
+  // Now look at the binding to this region (if any).
+  if (!scan(state->getSValAsScalarOrLoc(R)))
+    return false;
+
+  // Now look at the subregions.
+  if (!SRM.get())
+    SRM.reset(state->getStateManager().getStoreManager().
+                                           getSubRegionMap(state->getStore()));
+
+  return SRM->iterSubRegions(R, *this);
+}
+
+bool GRState::scanReachableSymbols(SVal val, SymbolVisitor& visitor) const {
+  ScanReachableSymbols S(this, visitor);
+  return S.scan(val);
+}
+
+bool GRState::scanReachableSymbols(const SVal *I, const SVal *E,
+                                   SymbolVisitor &visitor) const {
+  ScanReachableSymbols S(this, visitor);
+  for ( ; I != E; ++I) {
+    if (!S.scan(*I))
+      return false;
+  }
+  return true;
+}
+
+bool GRState::scanReachableSymbols(const MemRegion * const *I,
+                                   const MemRegion * const *E,
+                                   SymbolVisitor &visitor) const {
+  ScanReachableSymbols S(this, visitor);
+  for ( ; I != E; ++I) {
+    if (!S.scan(*I))
+      return false;
+  }
+  return true;
+}
+
+//===----------------------------------------------------------------------===//
+// Queries.
+//===----------------------------------------------------------------------===//
+
+bool GRStateManager::isEqual(const GRState* state, const Expr* Ex,
+                             const llvm::APSInt& Y) {
+
+  SVal V = state->getSVal(Ex);
+
+  if (loc::ConcreteInt* X = dyn_cast<loc::ConcreteInt>(&V))
+    return X->getValue() == Y;
+
+  if (nonloc::ConcreteInt* X = dyn_cast<nonloc::ConcreteInt>(&V))
+    return X->getValue() == Y;
+
+  if (SymbolRef Sym = V.getAsSymbol())
+    return ConstraintMgr->isEqual(state, Sym, Y);
+
+  return false;
+}
+
+bool GRStateManager::isEqual(const GRState* state, const Expr* Ex, uint64_t x) {
+  return isEqual(state, Ex, getBasicVals().getValue(x, Ex->getType()));
+}
diff --git a/lib/Checker/LLVMConventionsChecker.cpp b/lib/Checker/LLVMConventionsChecker.cpp
new file mode 100644
index 0000000..14f0fc1
--- /dev/null
+++ b/lib/Checker/LLVMConventionsChecker.cpp
@@ -0,0 +1,335 @@
+//=== LLVMConventionsChecker.cpp - Check LLVM codebase conventions ---*- C++ -*-
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This defines LLVMConventionsChecker, a bunch of small little checks
+// for checking specific coding conventions in the LLVM/Clang codebase.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/StmtVisitor.h"
+#include "clang/Checker/Checkers/LocalCheckers.h"
+#include "clang/Checker/BugReporter/BugReporter.h"
+#include <string>
+#include "llvm/ADT/StringRef.h"
+
+using namespace clang;
+
+//===----------------------------------------------------------------------===//
+// Generic type checking routines.
+//===----------------------------------------------------------------------===//
+
+static bool IsLLVMStringRef(QualType T) {
+  const RecordType *RT = T->getAs<RecordType>();
+  if (!RT)
+    return false;
+
+  return llvm::StringRef(QualType(RT, 0).getAsString()) ==
+          "class llvm::StringRef";
+}
+
+static bool InStdNamespace(const Decl *D) {
+  const DeclContext *DC = D->getDeclContext();
+  const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(D->getDeclContext());
+  if (!ND)
+    return false;
+  const IdentifierInfo *II = ND->getIdentifier();
+  if (!II || II->getName() != "std")
+    return false;
+  DC = ND->getDeclContext();
+  return isa<TranslationUnitDecl>(DC);
+}
+
+static bool IsStdString(QualType T) {
+  if (const QualifiedNameType *QT = T->getAs<QualifiedNameType>())
+    T = QT->getNamedType();
+
+  const TypedefType *TT = T->getAs<TypedefType>();
+  if (!TT)
+    return false;
+
+  const TypedefDecl *TD = TT->getDecl();
+
+  if (!InStdNamespace(TD))
+    return false;
+
+  return TD->getName() == "string";
+}
+
+static bool InClangNamespace(const Decl *D) {
+  const DeclContext *DC = D->getDeclContext();
+  const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(D->getDeclContext());
+  if (!ND)
+    return false;
+  const IdentifierInfo *II = ND->getIdentifier();
+  if (!II || II->getName() != "clang")
+    return false;
+  DC = ND->getDeclContext();
+  return isa<TranslationUnitDecl>(DC);
+}
+
+static bool InLLVMNamespace(const Decl *D) {
+  const DeclContext *DC = D->getDeclContext();
+  const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(D->getDeclContext());
+  if (!ND)
+    return false;
+  const IdentifierInfo *II = ND->getIdentifier();
+  if (!II || II->getName() != "llvm")
+    return false;
+  DC = ND->getDeclContext();
+  return isa<TranslationUnitDecl>(DC);
+}
+
+static bool IsClangType(const RecordDecl *RD) {
+  return RD->getName() == "Type" && InClangNamespace(RD);
+}
+
+static bool IsClangDecl(const RecordDecl *RD) {
+  return RD->getName() == "Decl" && InClangNamespace(RD);
+}
+
+static bool IsClangStmt(const RecordDecl *RD) {
+  return RD->getName() == "Stmt" && InClangNamespace(RD);
+}
+
+static bool isClangAttr(const RecordDecl *RD) {
+  return RD->getName() == "Attr" && InClangNamespace(RD);
+}
+
+static bool IsStdVector(QualType T) {
+  const TemplateSpecializationType *TS = T->getAs<TemplateSpecializationType>();
+  if (!TS)
+    return false;
+
+  TemplateName TM = TS->getTemplateName();
+  TemplateDecl *TD = TM.getAsTemplateDecl();
+
+  if (!TD || !InStdNamespace(TD))
+    return false;
+
+  return TD->getName() == "vector";
+}
+
+static bool IsSmallVector(QualType T) {
+  const TemplateSpecializationType *TS = T->getAs<TemplateSpecializationType>();
+  if (!TS)
+    return false;
+
+  TemplateName TM = TS->getTemplateName();
+  TemplateDecl *TD = TM.getAsTemplateDecl();
+
+  if (!TD || !InLLVMNamespace(TD))
+    return false;
+
+  return TD->getName() == "SmallVector";
+}
+
+//===----------------------------------------------------------------------===//
+// CHECK: a llvm::StringRef should not be bound to a temporary std::string whose
+// lifetime is shorter than the StringRef's.
+//===----------------------------------------------------------------------===//
+
+namespace {
+class StringRefCheckerVisitor : public StmtVisitor<StringRefCheckerVisitor> {
+  BugReporter &BR;
+public:
+  StringRefCheckerVisitor(BugReporter &br) : BR(br) {}
+  void VisitChildren(Stmt *S) {
+    for (Stmt::child_iterator I = S->child_begin(), E = S->child_end() ;
+      I != E; ++I)
+      if (Stmt *child = *I)
+        Visit(child);
+  }
+  void VisitStmt(Stmt *S) { VisitChildren(S); }
+  void VisitDeclStmt(DeclStmt *DS);
+private:
+  void VisitVarDecl(VarDecl *VD);
+  void CheckStringRefBoundtoTemporaryString(VarDecl *VD);
+};
+} // end anonymous namespace
+
+static void CheckStringRefAssignedTemporary(const Decl *D, BugReporter &BR) {
+  StringRefCheckerVisitor walker(BR);
+  walker.Visit(D->getBody());
+}
+
+void StringRefCheckerVisitor::VisitDeclStmt(DeclStmt *S) {
+  VisitChildren(S);
+
+  for (DeclStmt::decl_iterator I = S->decl_begin(), E = S->decl_end();I!=E; ++I)
+    if (VarDecl *VD = dyn_cast<VarDecl>(*I))
+      VisitVarDecl(VD);
+}
+
+void StringRefCheckerVisitor::VisitVarDecl(VarDecl *VD) {
+  Expr *Init = VD->getInit();
+  if (!Init)
+    return;
+
+  // Pattern match for:
+  // llvm::StringRef x = call() (where call returns std::string)
+  if (!IsLLVMStringRef(VD->getType()))
+    return;
+  CXXExprWithTemporaries *Ex1 = dyn_cast<CXXExprWithTemporaries>(Init);
+  if (!Ex1)
+    return;
+  CXXConstructExpr *Ex2 = dyn_cast<CXXConstructExpr>(Ex1->getSubExpr());
+  if (!Ex2 || Ex2->getNumArgs() != 1)
+    return;
+  ImplicitCastExpr *Ex3 = dyn_cast<ImplicitCastExpr>(Ex2->getArg(0));
+  if (!Ex3)
+    return;
+  CXXConstructExpr *Ex4 = dyn_cast<CXXConstructExpr>(Ex3->getSubExpr());
+  if (!Ex4 || Ex4->getNumArgs() != 1)
+    return;
+  ImplicitCastExpr *Ex5 = dyn_cast<ImplicitCastExpr>(Ex4->getArg(0));
+  if (!Ex5)
+    return;
+  CXXBindTemporaryExpr *Ex6 = dyn_cast<CXXBindTemporaryExpr>(Ex5->getSubExpr());
+  if (!Ex6 || !IsStdString(Ex6->getType()))
+    return;
+
+  // Okay, badness!  Report an error.
+  const char *desc = "StringRef should not be bound to temporary "
+                     "std::string that it outlives";
+
+  BR.EmitBasicReport(desc, "LLVM Conventions", desc,
+                     VD->getLocStart(), Init->getSourceRange());
+}
+
+//===----------------------------------------------------------------------===//
+// CHECK: Clang AST nodes should not have fields that can allocate
+//   memory.
+//===----------------------------------------------------------------------===//
+
+static bool AllocatesMemory(QualType T) {
+  return IsStdVector(T) || IsStdString(T) || IsSmallVector(T);
+}
+
+// This type checking could be sped up via dynamic programming.
+static bool IsPartOfAST(const CXXRecordDecl *R) {
+  if (IsClangStmt(R) || IsClangType(R) || IsClangDecl(R) || isClangAttr(R))
+    return true;
+
+  for (CXXRecordDecl::base_class_const_iterator I = R->bases_begin(),
+                                                E = R->bases_end(); I!=E; ++I) {
+    CXXBaseSpecifier BS = *I;
+    QualType T = BS.getType();
+    if (const RecordType *baseT = T->getAs<RecordType>()) {
+      CXXRecordDecl *baseD = cast<CXXRecordDecl>(baseT->getDecl());
+      if (IsPartOfAST(baseD))
+        return true;
+    }
+  }
+
+  return false;
+}
+
+namespace {
+class ASTFieldVisitor {
+  llvm::SmallVector<FieldDecl*, 10> FieldChain;
+  CXXRecordDecl *Root;
+  BugReporter &BR;
+public:
+  ASTFieldVisitor(CXXRecordDecl *root, BugReporter &br)
+    : Root(root), BR(br) {}
+
+  void Visit(FieldDecl *D);
+  void ReportError(QualType T);
+};
+} // end anonymous namespace
+
+static void CheckASTMemory(CXXRecordDecl *R, BugReporter &BR) {
+  if (!IsPartOfAST(R))
+    return;
+
+  for (RecordDecl::field_iterator I = R->field_begin(), E = R->field_end();
+       I != E; ++I) {
+    ASTFieldVisitor walker(R, BR);
+    walker.Visit(*I);
+  }
+}
+
+void ASTFieldVisitor::Visit(FieldDecl *D) {
+  FieldChain.push_back(D);
+
+  QualType T = D->getType();
+
+  if (AllocatesMemory(T))
+    ReportError(T);
+
+  if (const RecordType *RT = T->getAs<RecordType>()) {
+    const RecordDecl *RD = RT->getDecl()->getDefinition();
+    for (RecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
+         I != E; ++I)
+      Visit(*I);
+  }
+
+  FieldChain.pop_back();
+}
+
+void ASTFieldVisitor::ReportError(QualType T) {
+  llvm::SmallString<1024> buf;
+  llvm::raw_svector_ostream os(buf);
+
+  os << "AST class '" << Root->getName() << "' has a field '"
+     << FieldChain.front()->getName() << "' that allocates heap memory";
+  if (FieldChain.size() > 1) {
+    os << " via the following chain: ";
+    bool isFirst = true;
+    for (llvm::SmallVectorImpl<FieldDecl*>::iterator I=FieldChain.begin(),
+         E=FieldChain.end(); I!=E; ++I) {
+      if (!isFirst)
+        os << '.';
+      else
+        isFirst = false;
+      os << (*I)->getName();
+    }
+  }
+  os << " (type " << FieldChain.back()->getType().getAsString() << ")";
+  os.flush();
+
+  // Note that this will fire for every translation unit that uses this
+  // class.  This is suboptimal, but at least scan-build will merge
+  // duplicate HTML reports.  In the future we need a unified way of merging
+  // duplicate reports across translation units.  For C++ classes we cannot
+  // just report warnings when we see an out-of-line method definition for a
+  // class, as that heuristic doesn't always work (the complete definition of
+  // the class may be in the header file, for example).
+  BR.EmitBasicReport("AST node allocates heap memory", "LLVM Conventions",
+                     os.str(), FieldChain.front()->getLocStart());
+}
+
+//===----------------------------------------------------------------------===//
+// Entry point for all checks.
+//===----------------------------------------------------------------------===//
+
+static void ScanCodeDecls(DeclContext *DC, BugReporter &BR) {
+  for (DeclContext::decl_iterator I=DC->decls_begin(), E=DC->decls_end();
+       I!=E ; ++I) {
+
+    Decl *D = *I;
+
+    if (D->getBody())
+      CheckStringRefAssignedTemporary(D, BR);
+
+    if (CXXRecordDecl *R = dyn_cast<CXXRecordDecl>(D))
+      if (R->isDefinition())
+        CheckASTMemory(R, BR);
+
+    if (DeclContext *DC_child = dyn_cast<DeclContext>(D))
+      ScanCodeDecls(DC_child, BR);
+  }
+}
+
+void clang::CheckLLVMConventions(TranslationUnitDecl &TU,
+                                 BugReporter &BR) {
+  ScanCodeDecls(&TU, BR);
+}
+
diff --git a/lib/Checker/MacOSXAPIChecker.cpp b/lib/Checker/MacOSXAPIChecker.cpp
new file mode 100644
index 0000000..bcd96e7
--- /dev/null
+++ b/lib/Checker/MacOSXAPIChecker.cpp
@@ -0,0 +1,141 @@
+// MacOSXAPIChecker.h - Checks proper use of various MacOS X APIs --*- C++ -*-//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This defines MacOSXAPIChecker, which is an assortment of checks on calls
+// to various, widely used Mac OS X functions.
+//
+// FIXME: What's currently in BasicObjCFoundationChecks.cpp should be migrated
+// to here, using the new Checker interface.
+//
+//===----------------------------------------------------------------------===//
+
+#include "GRExprEngineInternalChecks.h"
+#include "clang/Basic/TargetInfo.h"
+#include "clang/Checker/BugReporter/BugType.h"
+#include "clang/Checker/PathSensitive/CheckerVisitor.h"
+#include "clang/Checker/PathSensitive/GRStateTrait.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace clang;
+
+namespace {
+class MacOSXAPIChecker : public CheckerVisitor<MacOSXAPIChecker> {
+  enum SubChecks {
+    DispatchOnce = 0,
+    DispatchOnceF,
+    NumChecks
+  };
+
+  BugType *BTypes[NumChecks];
+
+public:
+  MacOSXAPIChecker() { memset(BTypes, 0, sizeof(*BTypes) * NumChecks); }
+  static void *getTag() { static unsigned tag = 0; return &tag; }
+
+  void PreVisitCallExpr(CheckerContext &C, const CallExpr *CE);
+};
+} //end anonymous namespace
+
+void clang::RegisterMacOSXAPIChecker(GRExprEngine &Eng) {
+  if (Eng.getContext().Target.getTriple().getVendor() == llvm::Triple::Apple)
+    Eng.registerCheck(new MacOSXAPIChecker());
+}
+
+//===----------------------------------------------------------------------===//
+// dispatch_once and dispatch_once_f
+//===----------------------------------------------------------------------===//
+
+static void CheckDispatchOnce(CheckerContext &C, const CallExpr *CE,
+                              BugType *&BT, const IdentifierInfo *FI) {
+
+  if (!BT) {
+    llvm::SmallString<128> S;
+    llvm::raw_svector_ostream os(S);
+    os << "Improper use of '" << FI->getName() << '\'';
+    BT = new BugType(os.str(), "Mac OS X API");
+  }
+
+  if (CE->getNumArgs() < 1)
+    return;
+
+  // Check if the first argument is stack allocated.  If so, issue a warning
+  // because that's likely to be bad news.
+  const GRState *state = C.getState();
+  const MemRegion *R = state->getSVal(CE->getArg(0)).getAsRegion();
+  if (!R || !isa<StackSpaceRegion>(R->getMemorySpace()))
+    return;
+
+  ExplodedNode *N = C.GenerateSink(state);
+  if (!N)
+    return;
+
+  llvm::SmallString<256> S;
+  llvm::raw_svector_ostream os(S);
+  os << "Call to '" << FI->getName() << "' uses";
+  if (const VarRegion *VR = dyn_cast<VarRegion>(R))
+    os << " the local variable '" << VR->getDecl()->getName() << '\'';
+  else
+    os << " stack allocated memory";
+  os << " for the predicate value.  Using such transient memory for "
+        "the predicate is potentially dangerous.";
+  if (isa<VarRegion>(R) && isa<StackLocalsSpaceRegion>(R->getMemorySpace()))
+    os << "  Perhaps you intended to declare the variable as 'static'?";
+
+  EnhancedBugReport *report = new EnhancedBugReport(*BT, os.str(), N);
+  report->addRange(CE->getArg(0)->getSourceRange());
+  C.EmitReport(report);
+}
+
+//===----------------------------------------------------------------------===//
+// Central dispatch function.
+//===----------------------------------------------------------------------===//
+
+typedef void (*SubChecker)(CheckerContext &C, const CallExpr *CE, BugType *&BT,
+                           const IdentifierInfo *FI);
+namespace {
+  class SubCheck {
+    SubChecker SC;
+    BugType **BT;
+  public:
+    SubCheck(SubChecker sc, BugType *& bt) : SC(sc), BT(&bt) {}
+    SubCheck() : SC(NULL), BT(NULL) {}
+
+    void run(CheckerContext &C, const CallExpr *CE,
+             const IdentifierInfo *FI) const {
+      if (SC)
+        SC(C, CE, *BT, FI);
+    }
+  };
+} // end anonymous namespace
+
+void MacOSXAPIChecker::PreVisitCallExpr(CheckerContext &C, const CallExpr *CE) {
+  // FIXME: Mostly copy and paste from UnixAPIChecker.  Should refactor.
+  const GRState *state = C.getState();
+  const Expr *Callee = CE->getCallee();
+  const FunctionTextRegion *Fn =
+    dyn_cast_or_null<FunctionTextRegion>(state->getSVal(Callee).getAsRegion());
+
+  if (!Fn)
+    return;
+
+  const IdentifierInfo *FI = Fn->getDecl()->getIdentifier();
+  if (!FI)
+    return;
+
+  const SubCheck &SC =
+    llvm::StringSwitch<SubCheck>(FI->getName())
+      .Case("dispatch_once", SubCheck(CheckDispatchOnce, BTypes[DispatchOnce]))
+      .Case("dispatch_once_f", SubCheck(CheckDispatchOnce,
+                                        BTypes[DispatchOnceF]))
+      .Default(SubCheck());
+
+  SC.run(C, CE, FI);
+}
diff --git a/lib/Checker/Makefile b/lib/Checker/Makefile
new file mode 100644
index 0000000..c45ab29
--- /dev/null
+++ b/lib/Checker/Makefile
@@ -0,0 +1,21 @@
+##===- clang/lib/Checker/Makefile --------------------------*- Makefile -*-===##
+# 
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+# 
+##===----------------------------------------------------------------------===##
+#
+# This implements analyses built on top of source-level CFGs. 
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../../../..
+LIBRARYNAME := clangChecker
+BUILD_ARCHIVE = 1
+
+CPP.Flags += -I$(PROJ_SRC_DIR)/../../include -I$(PROJ_OBJ_DIR)/../../include
+
+include $(LEVEL)/Makefile.common
+
diff --git a/lib/Checker/MallocChecker.cpp b/lib/Checker/MallocChecker.cpp
new file mode 100644
index 0000000..a22df30
--- /dev/null
+++ b/lib/Checker/MallocChecker.cpp
@@ -0,0 +1,364 @@
+//=== MallocChecker.cpp - A malloc/free checker -------------------*- C++ -*--//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines malloc/free checker, which checks for potential memory
+// leaks, double free, and use-after-free problems.
+//
+//===----------------------------------------------------------------------===//
+
+#include "GRExprEngineExperimentalChecks.h"
+#include "clang/Checker/BugReporter/BugType.h"
+#include "clang/Checker/PathSensitive/CheckerVisitor.h"
+#include "clang/Checker/PathSensitive/GRState.h"
+#include "clang/Checker/PathSensitive/GRStateTrait.h"
+#include "clang/Checker/PathSensitive/SymbolManager.h"
+#include "llvm/ADT/ImmutableMap.h"
+using namespace clang;
+
+namespace {
+
+class RefState {
+  enum Kind { AllocateUnchecked, AllocateFailed, Released, Escaped } K;
+  const Stmt *S;
+
+public:
+  RefState(Kind k, const Stmt *s) : K(k), S(s) {}
+
+  bool isAllocated() const { return K == AllocateUnchecked; }
+  bool isReleased() const { return K == Released; }
+  bool isEscaped() const { return K == Escaped; }
+
+  bool operator==(const RefState &X) const {
+    return K == X.K && S == X.S;
+  }
+
+  static RefState getAllocateUnchecked(const Stmt *s) { 
+    return RefState(AllocateUnchecked, s); 
+  }
+  static RefState getAllocateFailed() {
+    return RefState(AllocateFailed, 0);
+  }
+  static RefState getReleased(const Stmt *s) { return RefState(Released, s); }
+  static RefState getEscaped(const Stmt *s) { return RefState(Escaped, s); }
+
+  void Profile(llvm::FoldingSetNodeID &ID) const {
+    ID.AddInteger(K);
+    ID.AddPointer(S);
+  }
+};
+
+class RegionState {};
+
+class MallocChecker : public CheckerVisitor<MallocChecker> {
+  BuiltinBug *BT_DoubleFree;
+  BuiltinBug *BT_Leak;
+  BuiltinBug *BT_UseFree;
+  IdentifierInfo *II_malloc, *II_free, *II_realloc;
+
+public:
+  MallocChecker() 
+    : BT_DoubleFree(0), BT_Leak(0), BT_UseFree(0), 
+      II_malloc(0), II_free(0), II_realloc(0) {}
+  static void *getTag();
+  bool EvalCallExpr(CheckerContext &C, const CallExpr *CE);
+  void EvalDeadSymbols(CheckerContext &C,const Stmt *S,SymbolReaper &SymReaper);
+  void EvalEndPath(GREndPathNodeBuilder &B, void *tag, GRExprEngine &Eng);
+  void PreVisitReturnStmt(CheckerContext &C, const ReturnStmt *S);
+  const GRState *EvalAssume(const GRState *state, SVal Cond, bool Assumption);
+  void VisitLocation(CheckerContext &C, const Stmt *S, SVal l);
+
+private:
+  void MallocMem(CheckerContext &C, const CallExpr *CE);
+  const GRState *MallocMemAux(CheckerContext &C, const CallExpr *CE,
+                              const Expr *SizeEx, const GRState *state);
+  void FreeMem(CheckerContext &C, const CallExpr *CE);
+  const GRState *FreeMemAux(CheckerContext &C, const CallExpr *CE,
+                            const GRState *state);
+
+  void ReallocMem(CheckerContext &C, const CallExpr *CE);
+};
+} // end anonymous namespace
+
+typedef llvm::ImmutableMap<SymbolRef, RefState> RegionStateTy;
+
+namespace clang {
+  template <>
+  struct GRStateTrait<RegionState> 
+    : public GRStatePartialTrait<llvm::ImmutableMap<SymbolRef, RefState> > {
+    static void *GDMIndex() { return MallocChecker::getTag(); }
+  };
+}
+
+void clang::RegisterMallocChecker(GRExprEngine &Eng) {
+  Eng.registerCheck(new MallocChecker());
+}
+
+void *MallocChecker::getTag() {
+  static int x;
+  return &x;
+}
+
+bool MallocChecker::EvalCallExpr(CheckerContext &C, const CallExpr *CE) {
+  const GRState *state = C.getState();
+  const Expr *Callee = CE->getCallee();
+  SVal L = state->getSVal(Callee);
+
+  const FunctionDecl *FD = L.getAsFunctionDecl();
+  if (!FD)
+    return false;
+
+  ASTContext &Ctx = C.getASTContext();
+  if (!II_malloc)
+    II_malloc = &Ctx.Idents.get("malloc");
+  if (!II_free)
+    II_free = &Ctx.Idents.get("free");
+  if (!II_realloc)
+    II_realloc = &Ctx.Idents.get("realloc");
+
+  if (FD->getIdentifier() == II_malloc) {
+    MallocMem(C, CE);
+    return true;
+  }
+
+  if (FD->getIdentifier() == II_free) {
+    FreeMem(C, CE);
+    return true;
+  }
+
+  if (FD->getIdentifier() == II_realloc) {
+    ReallocMem(C, CE);
+    return true;
+  }
+
+  return false;
+}
+
+void MallocChecker::MallocMem(CheckerContext &C, const CallExpr *CE) {
+  const GRState *state = MallocMemAux(C, CE, CE->getArg(0), C.getState());
+  C.addTransition(state);
+}
+
+const GRState *MallocChecker::MallocMemAux(CheckerContext &C,  
+                                           const CallExpr *CE,
+                                           const Expr *SizeEx,
+                                           const GRState *state) {
+  unsigned Count = C.getNodeBuilder().getCurrentBlockCount();
+  ValueManager &ValMgr = C.getValueManager();
+
+  SVal RetVal = ValMgr.getConjuredSymbolVal(NULL, CE, CE->getType(), Count);
+
+  SVal Size = state->getSVal(SizeEx);
+
+  state = C.getEngine().getStoreManager().setExtent(state, RetVal.getAsRegion(),
+                                                    Size);
+
+  state = state->BindExpr(CE, RetVal);
+  
+  SymbolRef Sym = RetVal.getAsLocSymbol();
+  assert(Sym);
+  // Set the symbol's state to Allocated.
+  return state->set<RegionState>(Sym, RefState::getAllocateUnchecked(CE));
+}
+
+void MallocChecker::FreeMem(CheckerContext &C, const CallExpr *CE) {
+  const GRState *state = FreeMemAux(C, CE, C.getState());
+
+  if (state)
+    C.addTransition(state);
+}
+
+const GRState *MallocChecker::FreeMemAux(CheckerContext &C, const CallExpr *CE,
+                                         const GRState *state) {
+  SVal ArgVal = state->getSVal(CE->getArg(0));
+
+  // If ptr is NULL, no operation is preformed.
+  if (ArgVal.isZeroConstant())
+    return state;
+
+  SymbolRef Sym = ArgVal.getAsLocSymbol();
+  assert(Sym);
+
+  const RefState *RS = state->get<RegionState>(Sym);
+
+  // If the symbol has not been tracked, return. This is possible when free() is
+  // called on a pointer that does not get its pointee directly from malloc(). 
+  // Full support of this requires inter-procedural analysis.
+  if (!RS)
+    return state;
+
+  // Check double free.
+  if (RS->isReleased()) {
+    ExplodedNode *N = C.GenerateSink();
+    if (N) {
+      if (!BT_DoubleFree)
+        BT_DoubleFree = new BuiltinBug("Double free",
+                         "Try to free a memory block that has been released");
+      // FIXME: should find where it's freed last time.
+      BugReport *R = new BugReport(*BT_DoubleFree, 
+                                   BT_DoubleFree->getDescription(), N);
+      C.EmitReport(R);
+    }
+    return NULL;
+  }
+
+  // Normal free.
+  return state->set<RegionState>(Sym, RefState::getReleased(CE));
+}
+
+void MallocChecker::ReallocMem(CheckerContext &C, const CallExpr *CE) {
+  const GRState *state = C.getState();
+  const Expr *Arg0 = CE->getArg(0);
+  DefinedOrUnknownSVal Arg0Val=cast<DefinedOrUnknownSVal>(state->getSVal(Arg0));
+
+  ValueManager &ValMgr = C.getValueManager();
+  SValuator &SVator = C.getSValuator();
+
+  DefinedOrUnknownSVal PtrEQ = SVator.EvalEQ(state, Arg0Val, ValMgr.makeNull());
+
+  // If the ptr is NULL, the call is equivalent to malloc(size).
+  if (const GRState *stateEqual = state->Assume(PtrEQ, true)) {
+    // Hack: set the NULL symbolic region to released to suppress false warning.
+    // In the future we should add more states for allocated regions, e.g., 
+    // CheckedNull, CheckedNonNull.
+    
+    SymbolRef Sym = Arg0Val.getAsLocSymbol();
+    if (Sym)
+      stateEqual = stateEqual->set<RegionState>(Sym, RefState::getReleased(CE));
+
+    const GRState *stateMalloc = MallocMemAux(C, CE, CE->getArg(1), stateEqual);
+    C.addTransition(stateMalloc);
+  }
+
+  if (const GRState *stateNotEqual = state->Assume(PtrEQ, false)) {
+    const Expr *Arg1 = CE->getArg(1);
+    DefinedOrUnknownSVal Arg1Val = 
+      cast<DefinedOrUnknownSVal>(stateNotEqual->getSVal(Arg1));
+    DefinedOrUnknownSVal SizeZero = SVator.EvalEQ(stateNotEqual, Arg1Val,
+                                      ValMgr.makeIntValWithPtrWidth(0, false));
+
+    if (const GRState *stateSizeZero = stateNotEqual->Assume(SizeZero, true)) {
+      const GRState *stateFree = FreeMemAux(C, CE, stateSizeZero);
+      if (stateFree)
+        C.addTransition(stateFree->BindExpr(CE, UndefinedVal(), true));
+    }
+
+    if (const GRState *stateSizeNotZero=stateNotEqual->Assume(SizeZero,false)) {
+      const GRState *stateFree = FreeMemAux(C, CE, stateSizeNotZero);
+      if (stateFree) {
+        // FIXME: We should copy the content of the original buffer.
+        const GRState *stateRealloc = MallocMemAux(C, CE, CE->getArg(1), 
+                                                   stateFree);
+        C.addTransition(stateRealloc);
+      }
+    }
+  }
+}
+
+void MallocChecker::EvalDeadSymbols(CheckerContext &C, const Stmt *S,
+                                    SymbolReaper &SymReaper) {
+  for (SymbolReaper::dead_iterator I = SymReaper.dead_begin(),
+         E = SymReaper.dead_end(); I != E; ++I) {
+    SymbolRef Sym = *I;
+    const GRState *state = C.getState();
+    const RefState *RS = state->get<RegionState>(Sym);
+    if (!RS)
+      return;
+
+    if (RS->isAllocated()) {
+      ExplodedNode *N = C.GenerateSink();
+      if (N) {
+        if (!BT_Leak)
+          BT_Leak = new BuiltinBug("Memory leak",
+                     "Allocated memory never released. Potential memory leak.");
+        // FIXME: where it is allocated.
+        BugReport *R = new BugReport(*BT_Leak, BT_Leak->getDescription(), N);
+        C.EmitReport(R);
+      }
+    }
+  }
+}
+
+void MallocChecker::EvalEndPath(GREndPathNodeBuilder &B, void *tag,
+                                GRExprEngine &Eng) {
+  SaveAndRestore<bool> OldHasGen(B.HasGeneratedNode);
+  const GRState *state = B.getState();
+  typedef llvm::ImmutableMap<SymbolRef, RefState> SymMap;
+  SymMap M = state->get<RegionState>();
+
+  for (SymMap::iterator I = M.begin(), E = M.end(); I != E; ++I) {
+    RefState RS = I->second;
+    if (RS.isAllocated()) {
+      ExplodedNode *N = B.generateNode(state, tag, B.getPredecessor());
+      if (N) {
+        if (!BT_Leak)
+          BT_Leak = new BuiltinBug("Memory leak",
+                     "Allocated memory never released. Potential memory leak.");
+        BugReport *R = new BugReport(*BT_Leak, BT_Leak->getDescription(), N);
+        Eng.getBugReporter().EmitReport(R);
+      }
+    }
+  }
+}
+
+void MallocChecker::PreVisitReturnStmt(CheckerContext &C, const ReturnStmt *S) {
+  const Expr *RetE = S->getRetValue();
+  if (!RetE)
+    return;
+
+  const GRState *state = C.getState();
+
+  SymbolRef Sym = state->getSVal(RetE).getAsSymbol();
+
+  if (!Sym)
+    return;
+
+  const RefState *RS = state->get<RegionState>(Sym);
+  if (!RS)
+    return;
+
+  // FIXME: check other cases.
+  if (RS->isAllocated())
+    state = state->set<RegionState>(Sym, RefState::getEscaped(S));
+
+  C.addTransition(state);
+}
+
+const GRState *MallocChecker::EvalAssume(const GRState *state, SVal Cond, 
+                                         bool Assumption) {
+  // If a symblic region is assumed to NULL, set its state to AllocateFailed.
+  // FIXME: should also check symbols assumed to non-null.
+
+  RegionStateTy RS = state->get<RegionState>();
+
+  for (RegionStateTy::iterator I = RS.begin(), E = RS.end(); I != E; ++I) {
+    if (state->getSymVal(I.getKey()))
+      state = state->set<RegionState>(I.getKey(),RefState::getAllocateFailed());
+  }
+
+  return state;
+}
+
+// Check if the location is a freed symbolic region.
+void MallocChecker::VisitLocation(CheckerContext &C, const Stmt *S, SVal l) {
+  SymbolRef Sym = l.getLocSymbolInBase();
+  if (Sym) {
+    const RefState *RS = C.getState()->get<RegionState>(Sym);
+    if (RS)
+      if (RS->isReleased()) {
+        ExplodedNode *N = C.GenerateSink();
+        if (!BT_UseFree)
+          BT_UseFree = new BuiltinBug("Use dynamically allocated memory after"
+                                      " it is freed.");
+
+        BugReport *R = new BugReport(*BT_UseFree, BT_UseFree->getDescription(),
+                                     N);
+        C.EmitReport(R);
+      }
+  }
+}
diff --git a/lib/Checker/ManagerRegistry.cpp b/lib/Checker/ManagerRegistry.cpp
new file mode 100644
index 0000000..d11a997
--- /dev/null
+++ b/lib/Checker/ManagerRegistry.cpp
@@ -0,0 +1,20 @@
+//===- ManagerRegistry.cpp - Pluggble Analyzer module creators --*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the pluggable analyzer module creators.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Checker/ManagerRegistry.h"
+
+using namespace clang;
+
+StoreManagerCreator ManagerRegistry::StoreMgrCreator = 0;
+
+ConstraintManagerCreator ManagerRegistry::ConstraintMgrCreator = 0;
diff --git a/lib/Checker/MemRegion.cpp b/lib/Checker/MemRegion.cpp
new file mode 100644
index 0000000..9a664c7
--- /dev/null
+++ b/lib/Checker/MemRegion.cpp
@@ -0,0 +1,807 @@
+//== MemRegion.cpp - Abstract memory regions for static analysis --*- C++ -*--//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines MemRegion and its subclasses.  MemRegion defines a
+//  partially-typed abstraction of memory useful for path-sensitive dataflow
+//  analyses.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Checker/PathSensitive/MemRegion.h"
+#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Analysis/Support/BumpVector.h"
+#include "clang/AST/CharUnits.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace clang;
+
+//===----------------------------------------------------------------------===//
+// MemRegion Construction.
+//===----------------------------------------------------------------------===//
+
+template<typename RegionTy> struct MemRegionManagerTrait;
+
+template <typename RegionTy, typename A1>
+RegionTy* MemRegionManager::getRegion(const A1 a1) {
+  
+  const typename MemRegionManagerTrait<RegionTy>::SuperRegionTy *superRegion =
+  MemRegionManagerTrait<RegionTy>::getSuperRegion(*this, a1);
+  
+  llvm::FoldingSetNodeID ID;
+  RegionTy::ProfileRegion(ID, a1, superRegion);
+  void* InsertPos;
+  RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
+                                                                   InsertPos));
+  
+  if (!R) {
+    R = (RegionTy*) A.Allocate<RegionTy>();
+    new (R) RegionTy(a1, superRegion);
+    Regions.InsertNode(R, InsertPos);
+  }
+  
+  return R;
+}
+
+template <typename RegionTy, typename A1>
+RegionTy* MemRegionManager::getSubRegion(const A1 a1,
+                                         const MemRegion *superRegion) {
+  llvm::FoldingSetNodeID ID;
+  RegionTy::ProfileRegion(ID, a1, superRegion);
+  void* InsertPos;
+  RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
+                                                                   InsertPos));
+  
+  if (!R) {
+    R = (RegionTy*) A.Allocate<RegionTy>();
+    new (R) RegionTy(a1, superRegion);
+    Regions.InsertNode(R, InsertPos);
+  }
+  
+  return R;
+}
+
+template <typename RegionTy, typename A1, typename A2>
+RegionTy* MemRegionManager::getRegion(const A1 a1, const A2 a2) {
+  
+  const typename MemRegionManagerTrait<RegionTy>::SuperRegionTy *superRegion =
+  MemRegionManagerTrait<RegionTy>::getSuperRegion(*this, a1, a2);
+  
+  llvm::FoldingSetNodeID ID;
+  RegionTy::ProfileRegion(ID, a1, a2, superRegion);
+  void* InsertPos;
+  RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
+                                                                   InsertPos));
+  
+  if (!R) {
+    R = (RegionTy*) A.Allocate<RegionTy>();
+    new (R) RegionTy(a1, a2, superRegion);
+    Regions.InsertNode(R, InsertPos);
+  }
+  
+  return R;
+}
+
+template <typename RegionTy, typename A1, typename A2>
+RegionTy* MemRegionManager::getSubRegion(const A1 a1, const A2 a2,
+                                         const MemRegion *superRegion) {
+  
+  llvm::FoldingSetNodeID ID;
+  RegionTy::ProfileRegion(ID, a1, a2, superRegion);
+  void* InsertPos;
+  RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
+                                                                   InsertPos));
+  
+  if (!R) {
+    R = (RegionTy*) A.Allocate<RegionTy>();
+    new (R) RegionTy(a1, a2, superRegion);
+    Regions.InsertNode(R, InsertPos);
+  }
+  
+  return R;
+}
+
+template <typename RegionTy, typename A1, typename A2, typename A3>
+RegionTy* MemRegionManager::getSubRegion(const A1 a1, const A2 a2, const A3 a3,
+                                         const MemRegion *superRegion) {
+  
+  llvm::FoldingSetNodeID ID;
+  RegionTy::ProfileRegion(ID, a1, a2, a3, superRegion);
+  void* InsertPos;
+  RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
+                                                                   InsertPos));
+  
+  if (!R) {
+    R = (RegionTy*) A.Allocate<RegionTy>();
+    new (R) RegionTy(a1, a2, a3, superRegion);
+    Regions.InsertNode(R, InsertPos);
+  }
+  
+  return R;
+}
+
+//===----------------------------------------------------------------------===//
+// Object destruction.
+//===----------------------------------------------------------------------===//
+
+MemRegion::~MemRegion() {}
+
+MemRegionManager::~MemRegionManager() {
+  // All regions and their data are BumpPtrAllocated.  No need to call
+  // their destructors.
+}
+
+//===----------------------------------------------------------------------===//
+// Basic methods.
+//===----------------------------------------------------------------------===//
+
+bool SubRegion::isSubRegionOf(const MemRegion* R) const {
+  const MemRegion* r = getSuperRegion();
+  while (r != 0) {
+    if (r == R)
+      return true;
+    if (const SubRegion* sr = dyn_cast<SubRegion>(r))
+      r = sr->getSuperRegion();
+    else
+      break;
+  }
+  return false;
+}
+
+MemRegionManager* SubRegion::getMemRegionManager() const {
+  const SubRegion* r = this;
+  do {
+    const MemRegion *superRegion = r->getSuperRegion();
+    if (const SubRegion *sr = dyn_cast<SubRegion>(superRegion)) {
+      r = sr;
+      continue;
+    }
+    return superRegion->getMemRegionManager();
+  } while (1);
+}
+
+const StackFrameContext *VarRegion::getStackFrame() const {
+  const StackSpaceRegion *SSR = dyn_cast<StackSpaceRegion>(getMemorySpace());
+  return SSR ? SSR->getStackFrame() : NULL;
+}
+
+//===----------------------------------------------------------------------===//
+// FoldingSet profiling.
+//===----------------------------------------------------------------------===//
+
+void MemSpaceRegion::Profile(llvm::FoldingSetNodeID& ID) const {
+  ID.AddInteger((unsigned)getKind());
+}
+
+void StackSpaceRegion::Profile(llvm::FoldingSetNodeID &ID) const {
+  ID.AddInteger((unsigned)getKind());
+  ID.AddPointer(getStackFrame());
+}
+
+void StringRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
+                                 const StringLiteral* Str,
+                                 const MemRegion* superRegion) {
+  ID.AddInteger((unsigned) StringRegionKind);
+  ID.AddPointer(Str);
+  ID.AddPointer(superRegion);
+}
+
+void AllocaRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
+                                 const Expr* Ex, unsigned cnt,
+                                 const MemRegion *) {
+  ID.AddInteger((unsigned) AllocaRegionKind);
+  ID.AddPointer(Ex);
+  ID.AddInteger(cnt);
+}
+
+void AllocaRegion::Profile(llvm::FoldingSetNodeID& ID) const {
+  ProfileRegion(ID, Ex, Cnt, superRegion);
+}
+
+void CompoundLiteralRegion::Profile(llvm::FoldingSetNodeID& ID) const {
+  CompoundLiteralRegion::ProfileRegion(ID, CL, superRegion);
+}
+
+void CompoundLiteralRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
+                                          const CompoundLiteralExpr* CL,
+                                          const MemRegion* superRegion) {
+  ID.AddInteger((unsigned) CompoundLiteralRegionKind);
+  ID.AddPointer(CL);
+  ID.AddPointer(superRegion);
+}
+
+void CXXThisRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
+                                  const PointerType *PT,
+                                  const MemRegion *sRegion) {
+  ID.AddInteger((unsigned) CXXThisRegionKind);
+  ID.AddPointer(PT);
+  ID.AddPointer(sRegion);
+}
+
+void CXXThisRegion::Profile(llvm::FoldingSetNodeID &ID) const {
+  CXXThisRegion::ProfileRegion(ID, ThisPointerTy, superRegion);
+}
+                                  
+void DeclRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl* D,
+                               const MemRegion* superRegion, Kind k) {
+  ID.AddInteger((unsigned) k);
+  ID.AddPointer(D);
+  ID.AddPointer(superRegion);
+}
+
+void DeclRegion::Profile(llvm::FoldingSetNodeID& ID) const {
+  DeclRegion::ProfileRegion(ID, D, superRegion, getKind());
+}
+
+void VarRegion::Profile(llvm::FoldingSetNodeID &ID) const {
+  VarRegion::ProfileRegion(ID, getDecl(), superRegion);
+}
+
+void SymbolicRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, SymbolRef sym,
+                                   const MemRegion *sreg) {
+  ID.AddInteger((unsigned) MemRegion::SymbolicRegionKind);
+  ID.Add(sym);
+  ID.AddPointer(sreg);
+}
+
+void SymbolicRegion::Profile(llvm::FoldingSetNodeID& ID) const {
+  SymbolicRegion::ProfileRegion(ID, sym, getSuperRegion());
+}
+
+void ElementRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
+                                  QualType ElementType, SVal Idx,
+                                  const MemRegion* superRegion) {
+  ID.AddInteger(MemRegion::ElementRegionKind);
+  ID.Add(ElementType);
+  ID.AddPointer(superRegion);
+  Idx.Profile(ID);
+}
+
+void ElementRegion::Profile(llvm::FoldingSetNodeID& ID) const {
+  ElementRegion::ProfileRegion(ID, ElementType, Index, superRegion);
+}
+
+void FunctionTextRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
+                                       const FunctionDecl *FD,
+                                       const MemRegion*) {
+  ID.AddInteger(MemRegion::FunctionTextRegionKind);
+  ID.AddPointer(FD);
+}
+
+void FunctionTextRegion::Profile(llvm::FoldingSetNodeID& ID) const {
+  FunctionTextRegion::ProfileRegion(ID, FD, superRegion);
+}
+
+void BlockTextRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
+                                    const BlockDecl *BD, CanQualType,
+                                    const AnalysisContext *AC,
+                                    const MemRegion*) {
+  ID.AddInteger(MemRegion::BlockTextRegionKind);
+  ID.AddPointer(BD);
+}
+
+void BlockTextRegion::Profile(llvm::FoldingSetNodeID& ID) const {
+  BlockTextRegion::ProfileRegion(ID, BD, locTy, AC, superRegion);
+}
+
+void BlockDataRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
+                                    const BlockTextRegion *BC,
+                                    const LocationContext *LC,
+                                    const MemRegion *sReg) {
+  ID.AddInteger(MemRegion::BlockDataRegionKind);
+  ID.AddPointer(BC);
+  ID.AddPointer(LC);
+  ID.AddPointer(sReg);
+}
+
+void BlockDataRegion::Profile(llvm::FoldingSetNodeID& ID) const {
+  BlockDataRegion::ProfileRegion(ID, BC, LC, getSuperRegion());
+}
+
+void CXXObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
+                                    Expr const *Ex,
+                                    const MemRegion *sReg) {
+  ID.AddPointer(Ex);
+  ID.AddPointer(sReg);
+}
+
+void CXXObjectRegion::Profile(llvm::FoldingSetNodeID &ID) const {
+  ProfileRegion(ID, Ex, getSuperRegion());
+}
+
+//===----------------------------------------------------------------------===//
+// Region pretty-printing.
+//===----------------------------------------------------------------------===//
+
+void MemRegion::dump() const {
+  dumpToStream(llvm::errs());
+}
+
+std::string MemRegion::getString() const {
+  std::string s;
+  llvm::raw_string_ostream os(s);
+  dumpToStream(os);
+  return os.str();
+}
+
+void MemRegion::dumpToStream(llvm::raw_ostream& os) const {
+  os << "<Unknown Region>";
+}
+
+void AllocaRegion::dumpToStream(llvm::raw_ostream& os) const {
+  os << "alloca{" << (void*) Ex << ',' << Cnt << '}';
+}
+
+void FunctionTextRegion::dumpToStream(llvm::raw_ostream& os) const {
+  os << "code{" << getDecl()->getDeclName().getAsString() << '}';
+}
+
+void BlockTextRegion::dumpToStream(llvm::raw_ostream& os) const {
+  os << "block_code{" << (void*) this << '}';
+}
+
+void BlockDataRegion::dumpToStream(llvm::raw_ostream& os) const {
+  os << "block_data{" << BC << '}';
+}
+
+
+void CompoundLiteralRegion::dumpToStream(llvm::raw_ostream& os) const {
+  // FIXME: More elaborate pretty-printing.
+  os << "{ " << (void*) CL <<  " }";
+}
+
+void CXXThisRegion::dumpToStream(llvm::raw_ostream &os) const {
+  os << "this";
+}
+
+void ElementRegion::dumpToStream(llvm::raw_ostream& os) const {
+  os << "element{" << superRegion << ','
+     << Index << ',' << getElementType().getAsString() << '}';
+}
+
+void FieldRegion::dumpToStream(llvm::raw_ostream& os) const {
+  os << superRegion << "->" << getDecl();
+}
+
+void ObjCIvarRegion::dumpToStream(llvm::raw_ostream& os) const {
+  os << "ivar{" << superRegion << ',' << getDecl() << '}';
+}
+
+void StringRegion::dumpToStream(llvm::raw_ostream& os) const {
+  Str->printPretty(os, 0, PrintingPolicy(getContext().getLangOptions()));
+}
+
+void SymbolicRegion::dumpToStream(llvm::raw_ostream& os) const {
+  os << "SymRegion{" << sym << '}';
+}
+
+void VarRegion::dumpToStream(llvm::raw_ostream& os) const {
+  os << cast<VarDecl>(D);
+}
+
+void RegionRawOffset::dump() const {
+  dumpToStream(llvm::errs());
+}
+
+void RegionRawOffset::dumpToStream(llvm::raw_ostream& os) const {
+  os << "raw_offset{" << getRegion() << ',' << getByteOffset() << '}';
+}
+
+//===----------------------------------------------------------------------===//
+// MemRegionManager methods.
+//===----------------------------------------------------------------------===//
+
+template <typename REG>
+const REG *MemRegionManager::LazyAllocate(REG*& region) {
+  if (!region) {
+    region = (REG*) A.Allocate<REG>();
+    new (region) REG(this);
+  }
+
+  return region;
+}
+
+template <typename REG, typename ARG>
+const REG *MemRegionManager::LazyAllocate(REG*& region, ARG a) {
+  if (!region) {
+    region = (REG*) A.Allocate<REG>();
+    new (region) REG(this, a);
+  }
+  
+  return region;
+}
+
+const StackLocalsSpaceRegion*
+MemRegionManager::getStackLocalsRegion(const StackFrameContext *STC) {
+  assert(STC);
+  StackLocalsSpaceRegion *&R = StackLocalsSpaceRegions[STC];
+
+  if (R)
+    return R;
+
+  R = A.Allocate<StackLocalsSpaceRegion>();
+  new (R) StackLocalsSpaceRegion(this, STC);
+  return R;
+}
+
+const StackArgumentsSpaceRegion *
+MemRegionManager::getStackArgumentsRegion(const StackFrameContext *STC) {
+  assert(STC);
+  StackArgumentsSpaceRegion *&R = StackArgumentsSpaceRegions[STC];
+
+  if (R)
+    return R;
+
+  R = A.Allocate<StackArgumentsSpaceRegion>();
+  new (R) StackArgumentsSpaceRegion(this, STC);
+  return R;
+}
+
+const GlobalsSpaceRegion *MemRegionManager::getGlobalsRegion() {
+  return LazyAllocate(globals);
+}
+
+const HeapSpaceRegion *MemRegionManager::getHeapRegion() {
+  return LazyAllocate(heap);
+}
+
+const MemSpaceRegion *MemRegionManager::getUnknownRegion() {
+  return LazyAllocate(unknown);
+}
+
+const MemSpaceRegion *MemRegionManager::getCodeRegion() {
+  return LazyAllocate(code);
+}
+
+//===----------------------------------------------------------------------===//
+// Constructing regions.
+//===----------------------------------------------------------------------===//
+
+const StringRegion* MemRegionManager::getStringRegion(const StringLiteral* Str) {
+  return getSubRegion<StringRegion>(Str, getGlobalsRegion());
+}
+
+const VarRegion* MemRegionManager::getVarRegion(const VarDecl *D,
+                                                const LocationContext *LC) {
+  const MemRegion *sReg = 0;
+
+  if (D->hasLocalStorage()) {    
+    // FIXME: Once we implement scope handling, we will need to properly lookup
+    // 'D' to the proper LocationContext.
+    const DeclContext *DC = D->getDeclContext();
+    const StackFrameContext *STC = LC->getStackFrameForDeclContext(DC);
+
+    if (!STC)
+      sReg = getUnknownRegion();
+    else {
+      sReg = isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D)
+            ? static_cast<const MemRegion*>(getStackArgumentsRegion(STC))
+            : static_cast<const MemRegion*>(getStackLocalsRegion(STC));
+    }
+  }
+  else {
+    sReg = getGlobalsRegion();
+  }
+  
+  return getSubRegion<VarRegion>(D, sReg);
+}
+
+const VarRegion *MemRegionManager::getVarRegion(const VarDecl *D,
+                                                const MemRegion *superR) {
+  return getSubRegion<VarRegion>(D, superR);
+}
+
+const BlockDataRegion *
+MemRegionManager::getBlockDataRegion(const BlockTextRegion *BC,
+                                     const LocationContext *LC) {
+  const MemRegion *sReg = 0;
+  
+  if (LC) {    
+    // FIXME: Once we implement scope handling, we want the parent region
+    // to be the scope.  
+    const StackFrameContext *STC = LC->getCurrentStackFrame();
+    assert(STC);
+    sReg = getStackLocalsRegion(STC);
+  }
+  else {
+    // We allow 'LC' to be NULL for cases where want BlockDataRegions
+    // without context-sensitivity.
+    sReg = getUnknownRegion();
+  }
+
+  return getSubRegion<BlockDataRegion>(BC, LC, sReg);
+}
+
+const CompoundLiteralRegion*
+MemRegionManager::getCompoundLiteralRegion(const CompoundLiteralExpr* CL,
+                                           const LocationContext *LC) {
+  
+  const MemRegion *sReg = 0;
+  
+  if (CL->isFileScope())
+    sReg = getGlobalsRegion();
+  else {
+    const StackFrameContext *STC = LC->getCurrentStackFrame();
+    assert(STC);
+    sReg = getStackLocalsRegion(STC);
+  }
+  
+  return getSubRegion<CompoundLiteralRegion>(CL, sReg);
+}
+
+const ElementRegion*
+MemRegionManager::getElementRegion(QualType elementType, SVal Idx,
+                                   const MemRegion* superRegion,
+                                   ASTContext& Ctx){
+
+  QualType T = Ctx.getCanonicalType(elementType);
+
+  llvm::FoldingSetNodeID ID;
+  ElementRegion::ProfileRegion(ID, T, Idx, superRegion);
+
+  void* InsertPos;
+  MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
+  ElementRegion* R = cast_or_null<ElementRegion>(data);
+
+  if (!R) {
+    R = (ElementRegion*) A.Allocate<ElementRegion>();
+    new (R) ElementRegion(T, Idx, superRegion);
+    Regions.InsertNode(R, InsertPos);
+  }
+
+  return R;
+}
+
+const FunctionTextRegion *
+MemRegionManager::getFunctionTextRegion(const FunctionDecl *FD) {
+  return getSubRegion<FunctionTextRegion>(FD, getCodeRegion());
+}
+
+const BlockTextRegion *
+MemRegionManager::getBlockTextRegion(const BlockDecl *BD, CanQualType locTy,
+                                     AnalysisContext *AC) {
+  return getSubRegion<BlockTextRegion>(BD, locTy, AC, getCodeRegion());
+}
+
+
+/// getSymbolicRegion - Retrieve or create a "symbolic" memory region.
+const SymbolicRegion *MemRegionManager::getSymbolicRegion(SymbolRef sym) {
+  return getSubRegion<SymbolicRegion>(sym, getUnknownRegion());
+}
+
+const FieldRegion*
+MemRegionManager::getFieldRegion(const FieldDecl* d,
+                                 const MemRegion* superRegion){
+  return getSubRegion<FieldRegion>(d, superRegion);
+}
+
+const ObjCIvarRegion*
+MemRegionManager::getObjCIvarRegion(const ObjCIvarDecl* d,
+                                    const MemRegion* superRegion) {
+  return getSubRegion<ObjCIvarRegion>(d, superRegion);
+}
+
+const CXXObjectRegion*
+MemRegionManager::getCXXObjectRegion(Expr const *E,
+                                     LocationContext const *LC) {
+  const StackFrameContext *SFC = LC->getCurrentStackFrame();
+  assert(SFC);
+  return getSubRegion<CXXObjectRegion>(E, getStackLocalsRegion(SFC));
+}
+
+const CXXThisRegion*
+MemRegionManager::getCXXThisRegion(QualType thisPointerTy,
+                                   const LocationContext *LC) {
+  const StackFrameContext *STC = LC->getCurrentStackFrame();
+  assert(STC);
+  const PointerType *PT = thisPointerTy->getAs<PointerType>();
+  assert(PT);
+  return getSubRegion<CXXThisRegion>(PT, getStackArgumentsRegion(STC));
+}
+
+const AllocaRegion*
+MemRegionManager::getAllocaRegion(const Expr* E, unsigned cnt,
+                                  const LocationContext *LC) {
+  const StackFrameContext *STC = LC->getCurrentStackFrame();
+  assert(STC);
+  return getSubRegion<AllocaRegion>(E, cnt, getStackLocalsRegion(STC));
+}
+
+const MemSpaceRegion *MemRegion::getMemorySpace() const {
+  const MemRegion *R = this;
+  const SubRegion* SR = dyn_cast<SubRegion>(this);
+
+  while (SR) {
+    R = SR->getSuperRegion();
+    SR = dyn_cast<SubRegion>(R);
+  }
+
+  return dyn_cast<MemSpaceRegion>(R);
+}
+
+bool MemRegion::hasStackStorage() const {
+  return isa<StackSpaceRegion>(getMemorySpace());
+}
+
+bool MemRegion::hasStackNonParametersStorage() const {
+  return isa<StackLocalsSpaceRegion>(getMemorySpace());
+}
+
+bool MemRegion::hasStackParametersStorage() const {
+  return isa<StackArgumentsSpaceRegion>(getMemorySpace());
+}
+
+bool MemRegion::hasGlobalsOrParametersStorage() const {
+  const MemSpaceRegion *MS = getMemorySpace();
+  return isa<StackArgumentsSpaceRegion>(MS) ||
+         isa<GlobalsSpaceRegion>(MS);
+}
+
+// getBaseRegion strips away all elements and fields, and get the base region
+// of them.
+const MemRegion *MemRegion::getBaseRegion() const {
+  const MemRegion *R = this;
+  while (true) {
+    switch (R->getKind()) {
+      case MemRegion::ElementRegionKind:
+      case MemRegion::FieldRegionKind:
+      case MemRegion::ObjCIvarRegionKind:
+        R = cast<SubRegion>(R)->getSuperRegion();
+        continue;
+      default:
+        break;
+    }
+    break;
+  }
+  return R;
+}
+
+//===----------------------------------------------------------------------===//
+// View handling.
+//===----------------------------------------------------------------------===//
+
+const MemRegion *MemRegion::StripCasts() const {
+  const MemRegion *R = this;
+  while (true) {
+    if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
+      // FIXME: generalize.  Essentially we want to strip away ElementRegions
+      // that were layered on a symbolic region because of casts.  We only
+      // want to strip away ElementRegions, however, where the index is 0.
+      SVal index = ER->getIndex();
+      if (nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&index)) {
+        if (CI->getValue().getSExtValue() == 0) {
+          R = ER->getSuperRegion();
+          continue;
+        }
+      }
+    }
+    break;
+  }
+  return R;
+}
+
+// FIXME: Merge with the implementation of the same method in Store.cpp
+static bool IsCompleteType(ASTContext &Ctx, QualType Ty) {
+  if (const RecordType *RT = Ty->getAs<RecordType>()) {
+    const RecordDecl *D = RT->getDecl();
+    if (!D->getDefinition())
+      return false;
+  }
+
+  return true;
+}
+
+RegionRawOffset ElementRegion::getAsRawOffset() const {
+  CharUnits offset = CharUnits::Zero();
+  const ElementRegion *ER = this;
+  const MemRegion *superR = NULL;
+  ASTContext &C = getContext();
+
+  // FIXME: Handle multi-dimensional arrays.
+
+  while (ER) {
+    superR = ER->getSuperRegion();
+
+    // FIXME: generalize to symbolic offsets.
+    SVal index = ER->getIndex();
+    if (nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&index)) {
+      // Update the offset.
+      int64_t i = CI->getValue().getSExtValue();
+
+      if (i != 0) {
+        QualType elemType = ER->getElementType();
+
+        // If we are pointing to an incomplete type, go no further.
+        if (!IsCompleteType(C, elemType)) {
+          superR = ER;
+          break;
+        }
+
+        CharUnits size = C.getTypeSizeInChars(elemType);
+        offset += (i * size);
+      }
+
+      // Go to the next ElementRegion (if any).
+      ER = dyn_cast<ElementRegion>(superR);
+      continue;
+    }
+
+    return NULL;
+  }
+
+  assert(superR && "super region cannot be NULL");
+  return RegionRawOffset(superR, offset.getQuantity());
+}
+
+//===----------------------------------------------------------------------===//
+// BlockDataRegion
+//===----------------------------------------------------------------------===//
+
+void BlockDataRegion::LazyInitializeReferencedVars() {
+  if (ReferencedVars)
+    return;
+
+  AnalysisContext *AC = getCodeRegion()->getAnalysisContext();
+  AnalysisContext::referenced_decls_iterator I, E;
+  llvm::tie(I, E) = AC->getReferencedBlockVars(BC->getDecl());
+  
+  if (I == E) {
+    ReferencedVars = (void*) 0x1;
+    return;
+  }
+    
+  MemRegionManager &MemMgr = *getMemRegionManager();
+  llvm::BumpPtrAllocator &A = MemMgr.getAllocator();
+  BumpVectorContext BC(A);
+  
+  typedef BumpVector<const MemRegion*> VarVec;
+  VarVec *BV = (VarVec*) A.Allocate<VarVec>();
+  new (BV) VarVec(BC, E - I);
+  
+  for ( ; I != E; ++I) {
+    const VarDecl *VD = *I;
+    const VarRegion *VR = 0;
+    
+    if (!VD->getAttr<BlocksAttr>() && VD->hasLocalStorage())
+      VR = MemMgr.getVarRegion(VD, this);
+    else {
+      if (LC)
+        VR = MemMgr.getVarRegion(VD, LC);
+      else {
+        VR = MemMgr.getVarRegion(VD, MemMgr.getUnknownRegion());
+      }
+    }
+    
+    assert(VR);
+    BV->push_back(VR, BC);
+  }
+  
+  ReferencedVars = BV;
+}
+
+BlockDataRegion::referenced_vars_iterator
+BlockDataRegion::referenced_vars_begin() const {
+  const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars();
+
+  BumpVector<const MemRegion*> *Vec =
+    static_cast<BumpVector<const MemRegion*>*>(ReferencedVars);
+  
+  return BlockDataRegion::referenced_vars_iterator(Vec == (void*) 0x1 ?
+                                                   NULL : Vec->begin());
+}
+
+BlockDataRegion::referenced_vars_iterator
+BlockDataRegion::referenced_vars_end() const {
+  const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars();
+
+  BumpVector<const MemRegion*> *Vec =
+    static_cast<BumpVector<const MemRegion*>*>(ReferencedVars);
+  
+  return BlockDataRegion::referenced_vars_iterator(Vec == (void*) 0x1 ?
+                                                   NULL : Vec->end());
+}
diff --git a/lib/Checker/NSAutoreleasePoolChecker.cpp b/lib/Checker/NSAutoreleasePoolChecker.cpp
new file mode 100644
index 0000000..48f03a3
--- /dev/null
+++ b/lib/Checker/NSAutoreleasePoolChecker.cpp
@@ -0,0 +1,86 @@
+//=- NSAutoreleasePoolChecker.cpp --------------------------------*- C++ -*-==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines a NSAutoreleasePoolChecker, a small checker that warns
+//  about subpar uses of NSAutoreleasePool.  Note that while the check itself
+//  (in it's current form) could be written as a flow-insensitive check, in
+//  can be potentially enhanced in the future with flow-sensitive information.
+//  It is also a good example of the CheckerVisitor interface. 
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Checker/BugReporter/BugReporter.h"
+#include "clang/Checker/PathSensitive/GRExprEngine.h"
+#include "clang/Checker/PathSensitive/CheckerVisitor.h"
+#include "BasicObjCFoundationChecks.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/Decl.h"
+
+using namespace clang;
+
+namespace {
+class NSAutoreleasePoolChecker
+  : public CheckerVisitor<NSAutoreleasePoolChecker> {
+      
+  Selector releaseS;
+
+public:
+    NSAutoreleasePoolChecker(Selector release_s) : releaseS(release_s) {}
+    
+  static void *getTag() {
+    static int x = 0;
+    return &x;
+  }
+
+  void PreVisitObjCMessageExpr(CheckerContext &C, const ObjCMessageExpr *ME);    
+};
+
+} // end anonymous namespace
+
+
+void clang::RegisterNSAutoreleasePoolChecks(GRExprEngine &Eng) {
+  ASTContext &Ctx = Eng.getContext();
+  if (Ctx.getLangOptions().getGCMode() != LangOptions::NonGC) {    
+    Eng.registerCheck(new NSAutoreleasePoolChecker(GetNullarySelector("release",
+                                                                      Ctx)));
+  }
+}
+
+void
+NSAutoreleasePoolChecker::PreVisitObjCMessageExpr(CheckerContext &C,
+                                                  const ObjCMessageExpr *ME) {
+  
+  const Expr *receiver = ME->getInstanceReceiver();
+  if (!receiver)
+    return;
+  
+  // FIXME: Enhance with value-tracking information instead of consulting
+  // the type of the expression.
+  const ObjCObjectPointerType* PT =
+    receiver->getType()->getAs<ObjCObjectPointerType>();
+  
+  if (!PT)
+    return;  
+  const ObjCInterfaceDecl* OD = PT->getInterfaceDecl();
+  if (!OD)
+    return;  
+  if (!OD->getIdentifier()->getName().equals("NSAutoreleasePool"))
+    return;
+  
+  // Sending 'release' message?
+  if (ME->getSelector() != releaseS)
+    return;
+                     
+  SourceRange R = ME->getSourceRange();
+
+  C.getBugReporter().EmitBasicReport("Use -drain instead of -release",
+    "API Upgrade (Apple)",
+    "Use -drain instead of -release when using NSAutoreleasePool "
+    "and garbage collection", ME->getLocStart(), &R, 1);
+}
diff --git a/lib/Checker/NSErrorChecker.cpp b/lib/Checker/NSErrorChecker.cpp
new file mode 100644
index 0000000..e30d54c
--- /dev/null
+++ b/lib/Checker/NSErrorChecker.cpp
@@ -0,0 +1,237 @@
+//=- NSErrorCheckerer.cpp - Coding conventions for uses of NSError -*- C++ -*-==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines a CheckNSError, a flow-insenstive check
+//  that determines if an Objective-C class interface correctly returns
+//  a non-void return type.
+//
+//  File under feature request PR 2600.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Checker/Checkers/LocalCheckers.h"
+#include "clang/Checker/BugReporter/BugType.h"
+#include "clang/Checker/PathSensitive/GRExprEngine.h"
+#include "clang/Checker/Checkers/DereferenceChecker.h"
+#include "BasicObjCFoundationChecks.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/Decl.h"
+#include "llvm/ADT/SmallVector.h"
+
+using namespace clang;
+
+namespace {
+class NSErrorChecker : public BugType {
+  const Decl &CodeDecl;
+  const bool isNSErrorWarning;
+  IdentifierInfo * const II;
+  GRExprEngine &Eng;
+
+  void CheckSignature(const ObjCMethodDecl& MD, QualType& ResultTy,
+                      llvm::SmallVectorImpl<VarDecl*>& ErrorParams);
+
+  void CheckSignature(const FunctionDecl& MD, QualType& ResultTy,
+                      llvm::SmallVectorImpl<VarDecl*>& ErrorParams);
+
+  bool CheckNSErrorArgument(QualType ArgTy);
+  bool CheckCFErrorArgument(QualType ArgTy);
+
+  void CheckParamDeref(const VarDecl *V, const LocationContext *LC,
+                       const GRState *state, BugReporter& BR);
+
+  void EmitRetTyWarning(BugReporter& BR, const Decl& CodeDecl);
+
+public:
+  NSErrorChecker(const Decl &D, bool isNSError, GRExprEngine& eng)
+    : BugType(isNSError ? "NSError** null dereference"
+                        : "CFErrorRef* null dereference",
+              "Coding conventions (Apple)"),
+    CodeDecl(D),
+    isNSErrorWarning(isNSError),
+    II(&eng.getContext().Idents.get(isNSErrorWarning ? "NSError":"CFErrorRef")),
+    Eng(eng) {}
+
+  void FlushReports(BugReporter& BR);
+};
+
+} // end anonymous namespace
+
+void clang::RegisterNSErrorChecks(BugReporter& BR, GRExprEngine &Eng,
+                                  const Decl &D) {
+  BR.Register(new NSErrorChecker(D, true, Eng));
+  BR.Register(new NSErrorChecker(D, false, Eng));
+}
+
+void NSErrorChecker::FlushReports(BugReporter& BR) {
+  // Get the analysis engine and the exploded analysis graph.
+  ExplodedGraph& G = Eng.getGraph();
+
+  // Get the ASTContext, which is useful for querying type information.
+  ASTContext &Ctx = BR.getContext();
+
+  QualType ResultTy;
+  llvm::SmallVector<VarDecl*, 5> ErrorParams;
+
+  if (const ObjCMethodDecl* MD = dyn_cast<ObjCMethodDecl>(&CodeDecl))
+    CheckSignature(*MD, ResultTy, ErrorParams);
+  else if (const FunctionDecl* FD = dyn_cast<FunctionDecl>(&CodeDecl))
+    CheckSignature(*FD, ResultTy, ErrorParams);
+  else
+    return;
+
+  if (ErrorParams.empty())
+    return;
+
+  if (ResultTy == Ctx.VoidTy) EmitRetTyWarning(BR, CodeDecl);
+
+  for (ExplodedGraph::roots_iterator RI=G.roots_begin(), RE=G.roots_end();
+       RI!=RE; ++RI) {
+    // Scan the parameters for an implicit null dereference.
+    for (llvm::SmallVectorImpl<VarDecl*>::iterator I=ErrorParams.begin(),
+          E=ErrorParams.end(); I!=E; ++I)
+        CheckParamDeref(*I, (*RI)->getLocationContext(), (*RI)->getState(), BR);
+  }
+}
+
+void NSErrorChecker::EmitRetTyWarning(BugReporter& BR, const Decl& CodeDecl) {
+  std::string sbuf;
+  llvm::raw_string_ostream os(sbuf);
+
+  if (isa<ObjCMethodDecl>(CodeDecl))
+    os << "Method";
+  else
+    os << "Function";
+
+  os << " accepting ";
+  os << (isNSErrorWarning ? "NSError**" : "CFErrorRef*");
+  os << " should have a non-void return value to indicate whether or not an "
+        "error occurred";
+
+  BR.EmitBasicReport(isNSErrorWarning
+                     ? "Bad return type when passing NSError**"
+                     : "Bad return type when passing CFError*",
+                     getCategory(), os.str(),
+                     CodeDecl.getLocation());
+}
+
+void
+NSErrorChecker::CheckSignature(const ObjCMethodDecl& M, QualType& ResultTy,
+                             llvm::SmallVectorImpl<VarDecl*>& ErrorParams) {
+
+  ResultTy = M.getResultType();
+
+  for (ObjCMethodDecl::param_iterator I=M.param_begin(),
+       E=M.param_end(); I!=E; ++I)  {
+
+    QualType T = (*I)->getType();
+
+    if (isNSErrorWarning) {
+      if (CheckNSErrorArgument(T)) ErrorParams.push_back(*I);
+    }
+    else if (CheckCFErrorArgument(T))
+      ErrorParams.push_back(*I);
+  }
+}
+
+void
+NSErrorChecker::CheckSignature(const FunctionDecl& F, QualType& ResultTy,
+                             llvm::SmallVectorImpl<VarDecl*>& ErrorParams) {
+
+  ResultTy = F.getResultType();
+
+  for (FunctionDecl::param_const_iterator I = F.param_begin(),
+                                          E = F.param_end(); I != E; ++I)  {
+
+    QualType T = (*I)->getType();
+
+    if (isNSErrorWarning) {
+      if (CheckNSErrorArgument(T)) ErrorParams.push_back(*I);
+    }
+    else if (CheckCFErrorArgument(T))
+      ErrorParams.push_back(*I);
+  }
+}
+
+
+bool NSErrorChecker::CheckNSErrorArgument(QualType ArgTy) {
+
+  const PointerType* PPT = ArgTy->getAs<PointerType>();
+  if (!PPT)
+    return false;
+
+  const ObjCObjectPointerType* PT =
+    PPT->getPointeeType()->getAs<ObjCObjectPointerType>();
+
+  if (!PT)
+    return false;
+
+  const ObjCInterfaceDecl *ID = PT->getInterfaceDecl();
+
+  // FIXME: Can ID ever be NULL?
+  if (ID)
+    return II == ID->getIdentifier();
+
+  return false;
+}
+
+bool NSErrorChecker::CheckCFErrorArgument(QualType ArgTy) {
+
+  const PointerType* PPT = ArgTy->getAs<PointerType>();
+  if (!PPT) return false;
+
+  const TypedefType* TT = PPT->getPointeeType()->getAs<TypedefType>();
+  if (!TT) return false;
+
+  return TT->getDecl()->getIdentifier() == II;
+}
+
+void NSErrorChecker::CheckParamDeref(const VarDecl *Param,
+                                   const LocationContext *LC,
+                                   const GRState *rootState,
+                                   BugReporter& BR) {
+
+  SVal ParamL = rootState->getLValue(Param, LC);
+  const MemRegion* ParamR = cast<loc::MemRegionVal>(ParamL).getRegionAs<VarRegion>();
+  assert (ParamR && "Parameters always have VarRegions.");
+  SVal ParamSVal = rootState->getSVal(ParamR);
+
+  // FIXME: For now assume that ParamSVal is symbolic.  We need to generalize
+  // this later.
+  SymbolRef ParamSym = ParamSVal.getAsLocSymbol();
+  if (!ParamSym)
+    return;
+
+  // Iterate over the implicit-null dereferences.
+  ExplodedNode *const* I,  *const* E;
+  llvm::tie(I, E) = GetImplicitNullDereferences(Eng);
+  for ( ; I != E; ++I) {
+    const GRState *state = (*I)->getState();
+    SVal location = state->getSVal((*I)->getLocationAs<StmtPoint>()->getStmt());
+    if (location.getAsSymbol() != ParamSym)
+      continue;
+
+    // Emit an error.
+    std::string sbuf;
+    llvm::raw_string_ostream os(sbuf);
+      os << "Potential null dereference.  According to coding standards ";
+
+    if (isNSErrorWarning)
+      os << "in 'Creating and Returning NSError Objects' the parameter '";
+    else
+      os << "documented in CoreFoundation/CFError.h the parameter '";
+
+    os << Param << "' may be null.";
+
+    BugReport *report = new BugReport(*this, os.str(), *I);
+    // FIXME: Notable symbols are now part of the report.  We should
+    //  add support for notable symbols in BugReport.
+    //    BR.addNotableSymbol(SV->getSymbol());
+    BR.EmitReport(report);
+  }
+}
diff --git a/lib/Checker/NoReturnFunctionChecker.cpp b/lib/Checker/NoReturnFunctionChecker.cpp
new file mode 100644
index 0000000..12527e0
--- /dev/null
+++ b/lib/Checker/NoReturnFunctionChecker.cpp
@@ -0,0 +1,79 @@
+//=== NoReturnFunctionChecker.cpp -------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This defines NoReturnFunctionChecker, which evaluates functions that do not
+// return to the caller.
+//
+//===----------------------------------------------------------------------===//
+
+#include "GRExprEngineInternalChecks.h"
+#include "clang/Checker/PathSensitive/CheckerVisitor.h"
+#include "llvm/ADT/StringSwitch.h"
+
+using namespace clang;
+
+namespace {
+
+class NoReturnFunctionChecker : public CheckerVisitor<NoReturnFunctionChecker> {
+public:
+  static void *getTag() { static int tag = 0; return &tag; }
+  void PostVisitCallExpr(CheckerContext &C, const CallExpr *CE);
+};
+
+}
+
+void clang::RegisterNoReturnFunctionChecker(GRExprEngine &Eng) {
+  Eng.registerCheck(new NoReturnFunctionChecker());
+}
+
+void NoReturnFunctionChecker::PostVisitCallExpr(CheckerContext &C,
+                                                const CallExpr *CE) {
+  const GRState *state = C.getState();
+  const Expr *Callee = CE->getCallee();
+
+  bool BuildSinks = getFunctionExtInfo(Callee->getType()).getNoReturn();
+
+  if (!BuildSinks) {
+    SVal L = state->getSVal(Callee);
+    const FunctionDecl *FD = L.getAsFunctionDecl();
+    if (!FD)
+      return;
+
+    if (FD->getAttr<AnalyzerNoReturnAttr>())
+      BuildSinks = true;
+    else if (const IdentifierInfo *II = FD->getIdentifier()) {
+      // HACK: Some functions are not marked noreturn, and don't return.
+      //  Here are a few hardwired ones.  If this takes too long, we can
+      //  potentially cache these results.
+      BuildSinks
+        = llvm::StringSwitch<bool>(llvm::StringRef(II->getName()))
+            .Case("exit", true)
+            .Case("panic", true)
+            .Case("error", true)
+            .Case("Assert", true)
+            // FIXME: This is just a wrapper around throwing an exception.
+            //  Eventually inter-procedural analysis should handle this easily.
+            .Case("ziperr", true)
+            .Case("assfail", true)
+            .Case("db_error", true)
+            .Case("__assert", true)
+            .Case("__assert_rtn", true)
+            .Case("__assert_fail", true)
+            .Case("dtrace_assfail", true)
+            .Case("yy_fatal_error", true)
+            .Case("_XCAssertionFailureHandler", true)
+            .Case("_DTAssertionFailureHandler", true)
+            .Case("_TSAssertionFailureHandler", true)
+            .Default(false);
+    }
+  }
+
+  if (BuildSinks)
+    C.GenerateSink(CE);
+}
diff --git a/lib/Checker/OSAtomicChecker.cpp b/lib/Checker/OSAtomicChecker.cpp
new file mode 100644
index 0000000..e743528
--- /dev/null
+++ b/lib/Checker/OSAtomicChecker.cpp
@@ -0,0 +1,196 @@
+//=== OSAtomicChecker.cpp - OSAtomic functions evaluator --------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This checker evaluates OSAtomic functions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "GRExprEngineInternalChecks.h"
+#include "clang/Checker/PathSensitive/Checker.h"
+#include "clang/Basic/Builtins.h"
+
+using namespace clang;
+
+namespace {
+
+class OSAtomicChecker : public Checker {
+public:
+  static void *getTag() { static int tag = 0; return &tag; }
+  virtual bool EvalCallExpr(CheckerContext &C, const CallExpr *CE);
+
+private:
+  bool EvalOSAtomicCompareAndSwap(CheckerContext &C, const CallExpr *CE);
+};
+
+}
+
+void clang::RegisterOSAtomicChecker(GRExprEngine &Eng) {
+  Eng.registerCheck(new OSAtomicChecker());
+}
+
+bool OSAtomicChecker::EvalCallExpr(CheckerContext &C,const CallExpr *CE) {
+  const GRState *state = C.getState();
+  const Expr *Callee = CE->getCallee();
+  SVal L = state->getSVal(Callee);
+
+  const FunctionDecl* FD = L.getAsFunctionDecl();
+  if (!FD)
+    return false;
+
+  const IdentifierInfo *II = FD->getIdentifier();
+  if (!II)
+    return false;
+  
+  llvm::StringRef FName(II->getName());
+
+  // Check for compare and swap.
+  if (FName.startswith("OSAtomicCompareAndSwap") ||
+      FName.startswith("objc_atomicCompareAndSwap"))
+    return EvalOSAtomicCompareAndSwap(C, CE);
+
+  // FIXME: Other atomics.
+  return false;
+}
+
+bool OSAtomicChecker::EvalOSAtomicCompareAndSwap(CheckerContext &C, 
+                                                 const CallExpr *CE) {
+  // Not enough arguments to match OSAtomicCompareAndSwap?
+  if (CE->getNumArgs() != 3)
+    return false;
+
+  ASTContext &Ctx = C.getASTContext();
+  const Expr *oldValueExpr = CE->getArg(0);
+  QualType oldValueType = Ctx.getCanonicalType(oldValueExpr->getType());
+
+  const Expr *newValueExpr = CE->getArg(1);
+  QualType newValueType = Ctx.getCanonicalType(newValueExpr->getType());
+
+  // Do the types of 'oldValue' and 'newValue' match?
+  if (oldValueType != newValueType)
+    return false;
+
+  const Expr *theValueExpr = CE->getArg(2);
+  const PointerType *theValueType=theValueExpr->getType()->getAs<PointerType>();
+
+  // theValueType not a pointer?
+  if (!theValueType)
+    return false;
+
+  QualType theValueTypePointee =
+    Ctx.getCanonicalType(theValueType->getPointeeType()).getUnqualifiedType();
+
+  // The pointee must match newValueType and oldValueType.
+  if (theValueTypePointee != newValueType)
+    return false;
+
+  static unsigned magic_load = 0;
+  static unsigned magic_store = 0;
+
+  const void *OSAtomicLoadTag = &magic_load;
+  const void *OSAtomicStoreTag = &magic_store;
+
+  // Load 'theValue'.
+  GRExprEngine &Engine = C.getEngine();
+  const GRState *state = C.getState();
+  ExplodedNodeSet Tmp;
+  SVal location = state->getSVal(theValueExpr);
+  // Here we should use the value type of the region as the load type.
+  QualType LoadTy;
+  if (const TypedRegion *TR =
+      dyn_cast_or_null<TypedRegion>(location.getAsRegion())) {
+    LoadTy = TR->getValueType(Ctx);
+  }
+  Engine.EvalLoad(Tmp, const_cast<Expr *>(theValueExpr), C.getPredecessor(), 
+                  state, location, OSAtomicLoadTag, LoadTy);
+
+  if (Tmp.empty()) {
+    // If no nodes were generated, other checkers must generated sinks. But 
+    // since the builder state was restored, we set it manually to prevent 
+    // auto transition.
+    // FIXME: there should be a better approach.
+    C.getNodeBuilder().BuildSinks = true;
+    return true;
+  }
+ 
+  for (ExplodedNodeSet::iterator I = Tmp.begin(), E = Tmp.end();
+       I != E; ++I) {
+
+    ExplodedNode *N = *I;
+    const GRState *stateLoad = N->getState();
+    SVal theValueVal_untested = stateLoad->getSVal(theValueExpr);
+    SVal oldValueVal_untested = stateLoad->getSVal(oldValueExpr);
+
+    // FIXME: Issue an error.
+    if (theValueVal_untested.isUndef() || oldValueVal_untested.isUndef()) {
+      return false;
+    }
+    
+    DefinedOrUnknownSVal theValueVal =
+      cast<DefinedOrUnknownSVal>(theValueVal_untested);
+    DefinedOrUnknownSVal oldValueVal =
+      cast<DefinedOrUnknownSVal>(oldValueVal_untested);
+
+    SValuator &SVator = Engine.getSValuator();
+
+    // Perform the comparison.
+    DefinedOrUnknownSVal Cmp = SVator.EvalEQ(stateLoad,theValueVal,oldValueVal);
+
+    const GRState *stateEqual = stateLoad->Assume(Cmp, true);
+
+    // Were they equal?
+    if (stateEqual) {
+      // Perform the store.
+      ExplodedNodeSet TmpStore;
+      SVal val = stateEqual->getSVal(newValueExpr);
+
+      // Handle implicit value casts.
+      if (const TypedRegion *R =
+          dyn_cast_or_null<TypedRegion>(location.getAsRegion())) {
+        val = SVator.EvalCast(val,R->getValueType(Ctx),newValueExpr->getType());
+      }
+
+      Engine.EvalStore(TmpStore, NULL, const_cast<Expr *>(theValueExpr), N, 
+                       stateEqual, location, val, OSAtomicStoreTag);
+
+      if (TmpStore.empty()) {
+        // If no nodes were generated, other checkers must generated sinks. But 
+        // since the builder state was restored, we set it manually to prevent 
+        // auto transition.
+        // FIXME: there should be a better approach.
+        C.getNodeBuilder().BuildSinks = true;
+        return true;
+      }
+
+      // Now bind the result of the comparison.
+      for (ExplodedNodeSet::iterator I2 = TmpStore.begin(),
+           E2 = TmpStore.end(); I2 != E2; ++I2) {
+        ExplodedNode *predNew = *I2;
+        const GRState *stateNew = predNew->getState();
+        // Check for 'void' return type if we have a bogus function prototype.
+        SVal Res = UnknownVal();
+        QualType T = CE->getType();
+        if (!T->isVoidType())
+          Res = Engine.getValueManager().makeTruthVal(true, T);
+        C.GenerateNode(stateNew->BindExpr(CE, Res), predNew);
+      }
+    }
+
+    // Were they not equal?
+    if (const GRState *stateNotEqual = stateLoad->Assume(Cmp, false)) {
+      // Check for 'void' return type if we have a bogus function prototype.
+      SVal Res = UnknownVal();
+      QualType T = CE->getType();
+      if (!T->isVoidType())
+        Res = Engine.getValueManager().makeTruthVal(false, CE->getType());
+      C.GenerateNode(stateNotEqual->BindExpr(CE, Res), N);
+    }
+  }
+
+  return true;
+}
diff --git a/lib/Checker/ObjCUnusedIVarsChecker.cpp b/lib/Checker/ObjCUnusedIVarsChecker.cpp
new file mode 100644
index 0000000..0e47621
--- /dev/null
+++ b/lib/Checker/ObjCUnusedIVarsChecker.cpp
@@ -0,0 +1,160 @@
+//==- ObjCUnusedIVarsChecker.cpp - Check for unused ivars --------*- C++ -*-==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines a CheckObjCUnusedIvars, a checker that
+//  analyzes an Objective-C class's interface/implementation to determine if it
+//  has any ivars that are never accessed.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Checker/Checkers/LocalCheckers.h"
+#include "clang/Checker/BugReporter/PathDiagnostic.h"
+#include "clang/Checker/BugReporter/BugReporter.h"
+#include "clang/AST/ExprObjC.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/SourceManager.h"
+
+using namespace clang;
+
+enum IVarState { Unused, Used };
+typedef llvm::DenseMap<const ObjCIvarDecl*,IVarState> IvarUsageMap;
+
+static void Scan(IvarUsageMap& M, const Stmt* S) {
+  if (!S)
+    return;
+
+  if (const ObjCIvarRefExpr *Ex = dyn_cast<ObjCIvarRefExpr>(S)) {
+    const ObjCIvarDecl *D = Ex->getDecl();
+    IvarUsageMap::iterator I = M.find(D);
+    if (I != M.end())
+      I->second = Used;
+    return;
+  }
+
+  // Blocks can reference an instance variable of a class.
+  if (const BlockExpr *BE = dyn_cast<BlockExpr>(S)) {
+    Scan(M, BE->getBody());
+    return;
+  }
+
+  for (Stmt::const_child_iterator I=S->child_begin(),E=S->child_end(); I!=E;++I)
+    Scan(M, *I);
+}
+
+static void Scan(IvarUsageMap& M, const ObjCPropertyImplDecl* D) {
+  if (!D)
+    return;
+
+  const ObjCIvarDecl* ID = D->getPropertyIvarDecl();
+
+  if (!ID)
+    return;
+
+  IvarUsageMap::iterator I = M.find(ID);
+  if (I != M.end())
+    I->second = Used;
+}
+
+static void Scan(IvarUsageMap& M, const ObjCContainerDecl* D) {
+  // Scan the methods for accesses.
+  for (ObjCContainerDecl::instmeth_iterator I = D->instmeth_begin(),
+       E = D->instmeth_end(); I!=E; ++I)
+    Scan(M, (*I)->getBody());
+
+  if (const ObjCImplementationDecl *ID = dyn_cast<ObjCImplementationDecl>(D)) {
+    // Scan for @synthesized property methods that act as setters/getters
+    // to an ivar.
+    for (ObjCImplementationDecl::propimpl_iterator I = ID->propimpl_begin(),
+         E = ID->propimpl_end(); I!=E; ++I)
+      Scan(M, *I);
+
+    // Scan the associated categories as well.
+    for (const ObjCCategoryDecl *CD =
+          ID->getClassInterface()->getCategoryList(); CD ;
+          CD = CD->getNextClassCategory()) {
+      if (const ObjCCategoryImplDecl *CID = CD->getImplementation())
+        Scan(M, CID);
+    }
+  }
+}
+
+static void Scan(IvarUsageMap &M, const DeclContext *C, const FileID FID,
+                 SourceManager &SM) {
+  for (DeclContext::decl_iterator I=C->decls_begin(), E=C->decls_end();
+       I!=E; ++I)
+    if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(*I)) {
+      SourceLocation L = FD->getLocStart();
+      if (SM.getFileID(L) == FID)
+        Scan(M, FD->getBody());
+    }
+}
+
+void clang::CheckObjCUnusedIvar(const ObjCImplementationDecl *D,
+                                BugReporter &BR) {
+
+  const ObjCInterfaceDecl* ID = D->getClassInterface();
+  IvarUsageMap M;
+
+  // Iterate over the ivars.
+  for (ObjCInterfaceDecl::ivar_iterator I=ID->ivar_begin(),
+        E=ID->ivar_end(); I!=E; ++I) {
+
+    const ObjCIvarDecl* ID = *I;
+
+    // Ignore ivars that...
+    // (a) aren't private
+    // (b) explicitly marked unused
+    // (c) are iboutlets
+    if (ID->getAccessControl() != ObjCIvarDecl::Private ||
+        ID->getAttr<UnusedAttr>() || ID->getAttr<IBOutletAttr>())
+      continue;
+
+    M[ID] = Unused;
+  }
+
+  if (M.empty())
+    return;
+
+  // Now scan the implementation declaration.
+  Scan(M, D);
+
+  // Any potentially unused ivars?
+  bool hasUnused = false;
+  for (IvarUsageMap::iterator I = M.begin(), E = M.end(); I!=E; ++I)
+    if (I->second == Unused) {
+      hasUnused = true;
+      break;
+    }
+
+  if (!hasUnused)
+    return;
+
+  // We found some potentially unused ivars.  Scan the entire translation unit
+  // for functions inside the @implementation that reference these ivars.
+  // FIXME: In the future hopefully we can just use the lexical DeclContext
+  // to go from the ObjCImplementationDecl to the lexically "nested"
+  // C functions.
+  SourceManager &SM = BR.getSourceManager();
+  Scan(M, D->getDeclContext(), SM.getFileID(D->getLocation()), SM);
+
+  // Find ivars that are unused.
+  for (IvarUsageMap::iterator I = M.begin(), E = M.end(); I!=E; ++I)
+    if (I->second == Unused) {
+      std::string sbuf;
+      llvm::raw_string_ostream os(sbuf);
+      os << "Instance variable '" << I->first << "' in class '" << ID
+         << "' is never used by the methods in its @implementation "
+            "(although it may be used by category methods).";
+
+      BR.EmitBasicReport("Unused instance variable", "Optimization",
+                         os.str(), I->first->getLocation());
+    }
+}
diff --git a/lib/Checker/PathDiagnostic.cpp b/lib/Checker/PathDiagnostic.cpp
new file mode 100644
index 0000000..963923c
--- /dev/null
+++ b/lib/Checker/PathDiagnostic.cpp
@@ -0,0 +1,281 @@
+//===--- PathDiagnostic.cpp - Path-Specific Diagnostic Handling -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the PathDiagnostic-related interfaces.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Checker/BugReporter/PathDiagnostic.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/StmtCXX.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/Casting.h"
+
+using namespace clang;
+using llvm::dyn_cast;
+using llvm::isa;
+
+bool PathDiagnosticMacroPiece::containsEvent() const {
+  for (const_iterator I = begin(), E = end(); I!=E; ++I) {
+    if (isa<PathDiagnosticEventPiece>(*I))
+      return true;
+
+    if (PathDiagnosticMacroPiece *MP = dyn_cast<PathDiagnosticMacroPiece>(*I))
+      if (MP->containsEvent())
+        return true;
+  }
+
+  return false;
+}
+
+static llvm::StringRef StripTrailingDots(llvm::StringRef s) {
+  for (llvm::StringRef::size_type i = s.size(); i != 0; --i)
+    if (s[i - 1] != '.')
+      return s.substr(0, i);
+  return "";
+}
+
+PathDiagnosticPiece::PathDiagnosticPiece(llvm::StringRef s,
+                                         Kind k, DisplayHint hint)
+  : str(StripTrailingDots(s)), kind(k), Hint(hint) {}
+
+PathDiagnosticPiece::PathDiagnosticPiece(Kind k, DisplayHint hint)
+  : kind(k), Hint(hint) {}
+
+PathDiagnosticPiece::~PathDiagnosticPiece() {}
+PathDiagnosticEventPiece::~PathDiagnosticEventPiece() {}
+PathDiagnosticControlFlowPiece::~PathDiagnosticControlFlowPiece() {}
+
+PathDiagnosticMacroPiece::~PathDiagnosticMacroPiece() {
+  for (iterator I = begin(), E = end(); I != E; ++I) delete *I;
+}
+
+PathDiagnostic::PathDiagnostic() : Size(0) {}
+
+PathDiagnostic::~PathDiagnostic() {
+  for (iterator I = begin(), E = end(); I != E; ++I) delete &*I;
+}
+
+void PathDiagnostic::resetPath(bool deletePieces) {
+  Size = 0;
+
+  if (deletePieces)
+    for (iterator I=begin(), E=end(); I!=E; ++I)
+      delete &*I;
+
+  path.clear();
+}
+
+
+PathDiagnostic::PathDiagnostic(llvm::StringRef bugtype, llvm::StringRef desc,
+                               llvm::StringRef category)
+  : Size(0),
+    BugType(StripTrailingDots(bugtype)),
+    Desc(StripTrailingDots(desc)),
+    Category(StripTrailingDots(category)) {}
+
+void PathDiagnosticClient::HandleDiagnostic(Diagnostic::Level DiagLevel,
+                                            const DiagnosticInfo &Info) {
+
+  // Create a PathDiagnostic with a single piece.
+
+  PathDiagnostic* D = new PathDiagnostic();
+
+  const char *LevelStr;
+  switch (DiagLevel) {
+  default:
+  case Diagnostic::Ignored: assert(0 && "Invalid diagnostic type");
+  case Diagnostic::Note:    LevelStr = "note: "; break;
+  case Diagnostic::Warning: LevelStr = "warning: "; break;
+  case Diagnostic::Error:   LevelStr = "error: "; break;
+  case Diagnostic::Fatal:   LevelStr = "fatal error: "; break;
+  }
+
+  llvm::SmallString<100> StrC;
+  StrC += LevelStr;
+  Info.FormatDiagnostic(StrC);
+
+  PathDiagnosticPiece *P =
+    new PathDiagnosticEventPiece(Info.getLocation(), StrC.str());
+
+  for (unsigned i = 0, e = Info.getNumRanges(); i != e; ++i)
+    P->addRange(Info.getRange(i));
+  for (unsigned i = 0, e = Info.getNumFixItHints(); i != e; ++i)
+    P->addFixItHint(Info.getFixItHint(i));
+  D->push_front(P);
+
+  HandlePathDiagnostic(D);
+}
+
+//===----------------------------------------------------------------------===//
+// PathDiagnosticLocation methods.
+//===----------------------------------------------------------------------===//
+
+FullSourceLoc PathDiagnosticLocation::asLocation() const {
+  assert(isValid());
+  // Note that we want a 'switch' here so that the compiler can warn us in
+  // case we add more cases.
+  switch (K) {
+    case SingleLocK:
+    case RangeK:
+      break;
+    case StmtK:
+      return FullSourceLoc(S->getLocStart(), const_cast<SourceManager&>(*SM));
+    case DeclK:
+      return FullSourceLoc(D->getLocation(), const_cast<SourceManager&>(*SM));
+  }
+
+  return FullSourceLoc(R.getBegin(), const_cast<SourceManager&>(*SM));
+}
+
+PathDiagnosticRange PathDiagnosticLocation::asRange() const {
+  assert(isValid());
+  // Note that we want a 'switch' here so that the compiler can warn us in
+  // case we add more cases.
+  switch (K) {
+    case SingleLocK:
+      return PathDiagnosticRange(R, true);
+    case RangeK:
+      break;
+    case StmtK: {
+      const Stmt *S = asStmt();
+      switch (S->getStmtClass()) {
+        default:
+          break;
+        case Stmt::DeclStmtClass: {
+          const DeclStmt *DS = cast<DeclStmt>(S);
+          if (DS->isSingleDecl()) {
+            // Should always be the case, but we'll be defensive.
+            return SourceRange(DS->getLocStart(),
+                               DS->getSingleDecl()->getLocation());
+          }
+          break;
+        }
+          // FIXME: Provide better range information for different
+          //  terminators.
+        case Stmt::IfStmtClass:
+        case Stmt::WhileStmtClass:
+        case Stmt::DoStmtClass:
+        case Stmt::ForStmtClass:
+        case Stmt::ChooseExprClass:
+        case Stmt::IndirectGotoStmtClass:
+        case Stmt::SwitchStmtClass:
+        case Stmt::ConditionalOperatorClass:
+        case Stmt::ObjCForCollectionStmtClass: {
+          SourceLocation L = S->getLocStart();
+          return SourceRange(L, L);
+        }
+      }
+
+      return S->getSourceRange();
+    }
+    case DeclK:
+      if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
+        return MD->getSourceRange();
+      if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+        // FIXME: We would like to always get the function body, even
+        // when it needs to be de-serialized, but getting the
+        // ASTContext here requires significant changes.
+        if (Stmt *Body = FD->getBody()) {
+          if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Body))
+            return CS->getSourceRange();
+          else
+            return cast<CXXTryStmt>(Body)->getSourceRange();
+        }
+      }
+      else {
+        SourceLocation L = D->getLocation();
+        return PathDiagnosticRange(SourceRange(L, L), true);
+      }
+  }
+
+  return R;
+}
+
+void PathDiagnosticLocation::flatten() {
+  if (K == StmtK) {
+    R = asRange();
+    K = RangeK;
+    S = 0;
+    D = 0;
+  }
+  else if (K == DeclK) {
+    SourceLocation L = D->getLocation();
+    R = SourceRange(L, L);
+    K = SingleLocK;
+    S = 0;
+    D = 0;
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// FoldingSet profiling methods.
+//===----------------------------------------------------------------------===//
+
+void PathDiagnosticLocation::Profile(llvm::FoldingSetNodeID &ID) const {
+  ID.AddInteger((unsigned) K);
+  switch (K) {
+    case RangeK:
+      ID.AddInteger(R.getBegin().getRawEncoding());
+      ID.AddInteger(R.getEnd().getRawEncoding());
+      break;      
+    case SingleLocK:
+      ID.AddInteger(R.getBegin().getRawEncoding());
+      break;
+    case StmtK:
+      ID.Add(S);
+      break;
+    case DeclK:
+      ID.Add(D);
+      break;
+  }
+  return;
+}
+
+void PathDiagnosticPiece::Profile(llvm::FoldingSetNodeID &ID) const {
+  ID.AddInteger((unsigned) getKind());
+  ID.AddString(str);
+  // FIXME: Add profiling support for code hints.
+  ID.AddInteger((unsigned) getDisplayHint());
+  for (range_iterator I = ranges_begin(), E = ranges_end(); I != E; ++I) {
+    ID.AddInteger(I->getBegin().getRawEncoding());
+    ID.AddInteger(I->getEnd().getRawEncoding());
+  }  
+}
+
+void PathDiagnosticSpotPiece::Profile(llvm::FoldingSetNodeID &ID) const {
+  PathDiagnosticPiece::Profile(ID);
+  ID.Add(Pos);
+}
+
+void PathDiagnosticControlFlowPiece::Profile(llvm::FoldingSetNodeID &ID) const {
+  PathDiagnosticPiece::Profile(ID);
+  for (const_iterator I = begin(), E = end(); I != E; ++I)
+    ID.Add(*I);
+}
+
+void PathDiagnosticMacroPiece::Profile(llvm::FoldingSetNodeID &ID) const {
+  PathDiagnosticSpotPiece::Profile(ID);
+  for (const_iterator I = begin(), E = end(); I != E; ++I)
+    ID.Add(**I);
+}
+
+void PathDiagnostic::Profile(llvm::FoldingSetNodeID &ID) const {
+  ID.AddInteger(Size);
+  ID.AddString(BugType);
+  ID.AddString(Desc);
+  ID.AddString(Category);
+  for (const_iterator I = begin(), E = end(); I != E; ++I)
+    ID.Add(*I);
+  
+  for (meta_iterator I = meta_begin(), E = meta_end(); I != E; ++I)
+    ID.AddString(*I);
+}
diff --git a/lib/Checker/PointerArithChecker.cpp b/lib/Checker/PointerArithChecker.cpp
new file mode 100644
index 0000000..ed60c42
--- /dev/null
+++ b/lib/Checker/PointerArithChecker.cpp
@@ -0,0 +1,72 @@
+//=== PointerArithChecker.cpp - Pointer arithmetic checker -----*- C++ -*--===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This files defines PointerArithChecker, a builtin checker that checks for
+// pointer arithmetic on locations other than array elements.
+//
+//===----------------------------------------------------------------------===//
+
+#include "GRExprEngineInternalChecks.h"
+#include "clang/Checker/BugReporter/BugType.h"
+#include "clang/Checker/PathSensitive/CheckerVisitor.h"
+
+using namespace clang;
+
+namespace {
+class PointerArithChecker 
+  : public CheckerVisitor<PointerArithChecker> {
+  BuiltinBug *BT;
+public:
+  PointerArithChecker() : BT(0) {}
+  static void *getTag();
+  void PreVisitBinaryOperator(CheckerContext &C, const BinaryOperator *B);
+};
+}
+
+void *PointerArithChecker::getTag() {
+  static int x;
+  return &x;
+}
+
+void PointerArithChecker::PreVisitBinaryOperator(CheckerContext &C,
+                                                 const BinaryOperator *B) {
+  if (B->getOpcode() != BinaryOperator::Sub &&
+      B->getOpcode() != BinaryOperator::Add)
+    return;
+
+  const GRState *state = C.getState();
+  SVal LV = state->getSVal(B->getLHS());
+  SVal RV = state->getSVal(B->getRHS());
+
+  const MemRegion *LR = LV.getAsRegion();
+
+  if (!LR || !RV.isConstant())
+    return;
+
+  // If pointer arithmetic is done on variables of non-array type, this often
+  // means behavior rely on memory organization, which is dangerous.
+  if (isa<VarRegion>(LR) || isa<CodeTextRegion>(LR) || 
+      isa<CompoundLiteralRegion>(LR)) {
+
+    if (ExplodedNode *N = C.GenerateNode()) {
+      if (!BT)
+        BT = new BuiltinBug("Dangerous pointer arithmetic",
+                            "Pointer arithmetic done on non-array variables "
+                            "means reliance on memory layout, which is "
+                            "dangerous.");
+      RangedBugReport *R = new RangedBugReport(*BT, BT->getDescription(), N);
+      R->addRange(B->getSourceRange());
+      C.EmitReport(R);
+    }
+  }
+}
+
+void clang::RegisterPointerArithChecker(GRExprEngine &Eng) {
+  Eng.registerCheck(new PointerArithChecker());
+}
diff --git a/lib/Checker/PointerSubChecker.cpp b/lib/Checker/PointerSubChecker.cpp
new file mode 100644
index 0000000..bc0fd24
--- /dev/null
+++ b/lib/Checker/PointerSubChecker.cpp
@@ -0,0 +1,78 @@
+//=== PointerSubChecker.cpp - Pointer subtraction checker ------*- C++ -*--===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This files defines PointerSubChecker, a builtin checker that checks for
+// pointer subtractions on two pointers pointing to different memory chunks. 
+// This check corresponds to CWE-469.
+//
+//===----------------------------------------------------------------------===//
+
+#include "GRExprEngineInternalChecks.h"
+#include "clang/Checker/BugReporter/BugType.h"
+#include "clang/Checker/PathSensitive/CheckerVisitor.h"
+
+using namespace clang;
+
+namespace {
+class PointerSubChecker 
+  : public CheckerVisitor<PointerSubChecker> {
+  BuiltinBug *BT;
+public:
+  PointerSubChecker() : BT(0) {}
+  static void *getTag();
+  void PreVisitBinaryOperator(CheckerContext &C, const BinaryOperator *B);
+};
+}
+
+void *PointerSubChecker::getTag() {
+  static int x;
+  return &x;
+}
+
+void PointerSubChecker::PreVisitBinaryOperator(CheckerContext &C,
+                                               const BinaryOperator *B) {
+  // When doing pointer subtraction, if the two pointers do not point to the
+  // same memory chunk, emit a warning.
+  if (B->getOpcode() != BinaryOperator::Sub)
+    return;
+
+  const GRState *state = C.getState();
+  SVal LV = state->getSVal(B->getLHS());
+  SVal RV = state->getSVal(B->getRHS());
+
+  const MemRegion *LR = LV.getAsRegion();
+  const MemRegion *RR = RV.getAsRegion();
+
+  if (!(LR && RR))
+    return;
+
+  const MemRegion *BaseLR = LR->getBaseRegion();
+  const MemRegion *BaseRR = RR->getBaseRegion();
+
+  if (BaseLR == BaseRR)
+    return;
+
+  // Allow arithmetic on different symbolic regions.
+  if (isa<SymbolicRegion>(BaseLR) || isa<SymbolicRegion>(BaseRR))
+    return;
+
+  if (ExplodedNode *N = C.GenerateNode()) {
+    if (!BT)
+      BT = new BuiltinBug("Pointer subtraction", 
+                          "Subtraction of two pointers that do not point to "
+                          "the same memory chunk may cause incorrect result.");
+    RangedBugReport *R = new RangedBugReport(*BT, BT->getDescription(), N);
+    R->addRange(B->getSourceRange());
+    C.EmitReport(R);
+  }
+}
+
+void clang::RegisterPointerSubChecker(GRExprEngine &Eng) {
+  Eng.registerCheck(new PointerSubChecker());
+}
diff --git a/lib/Checker/PthreadLockChecker.cpp b/lib/Checker/PthreadLockChecker.cpp
new file mode 100644
index 0000000..74e266c
--- /dev/null
+++ b/lib/Checker/PthreadLockChecker.cpp
@@ -0,0 +1,141 @@
+//===--- PthreadLockChecker.h - Undefined arguments checker ----*- C++ -*--===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This defines PthreadLockChecker, a simple lock -> unlock checker.  Eventually
+// this shouldn't be registered with GRExprEngineInternalChecks.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Checker/PathSensitive/CheckerVisitor.h"
+#include "clang/Checker/BugReporter/BugReporter.h"
+#include "clang/Checker/PathSensitive/GRStateTrait.h"
+#include "GRExprEngineExperimentalChecks.h"
+#include "llvm/ADT/ImmutableSet.h"
+
+using namespace clang;
+
+namespace {
+class PthreadLockChecker
+  : public CheckerVisitor<PthreadLockChecker> {
+  BugType *BT;
+public:
+  PthreadLockChecker() : BT(0) {}
+  static void *getTag() {
+    static int x = 0;
+    return &x;
+  }
+  void PostVisitCallExpr(CheckerContext &C, const CallExpr *CE);
+    
+  void AcquireLock(CheckerContext &C, const CallExpr *CE,
+                   SVal lock, bool isTryLock);
+    
+  void ReleaseLock(CheckerContext &C, const CallExpr *CE,
+                    SVal lock);
+
+};
+} // end anonymous namespace
+
+// GDM Entry for tracking lock state.
+namespace { class LockSet {}; }
+namespace clang {
+template <> struct GRStateTrait<LockSet> :
+  public GRStatePartialTrait<llvm::ImmutableSet<const MemRegion*> > {
+    static void* GDMIndex() { return PthreadLockChecker::getTag(); }
+};
+} // end clang namespace
+
+void clang::RegisterPthreadLockChecker(GRExprEngine &Eng) {
+  Eng.registerCheck(new PthreadLockChecker());
+}
+
+
+void PthreadLockChecker::PostVisitCallExpr(CheckerContext &C,
+                                           const CallExpr *CE) {
+  const GRState *state = C.getState();
+  const Expr *Callee = CE->getCallee();
+  const FunctionTextRegion *R =
+    dyn_cast_or_null<FunctionTextRegion>(state->getSVal(Callee).getAsRegion());
+  
+  if (!R)
+    return;
+  
+  llvm::StringRef FName = R->getDecl()->getName();
+  
+  if (FName == "pthread_mutex_lock") {
+    if (CE->getNumArgs() != 1)
+      return;
+    AcquireLock(C, CE, state->getSVal(CE->getArg(0)), false);
+  }
+  else if (FName == "pthread_mutex_trylock") {
+    if (CE->getNumArgs() != 1)
+      return;
+    AcquireLock(C, CE, state->getSVal(CE->getArg(0)), true);
+  }  
+  else if (FName == "pthread_mutex_unlock") {
+    if (CE->getNumArgs() != 1)
+      return;
+    ReleaseLock(C, CE, state->getSVal(CE->getArg(0)));
+  }
+}
+
+void PthreadLockChecker::AcquireLock(CheckerContext &C, const CallExpr *CE,
+                                     SVal lock, bool isTryLock) {
+  
+  const MemRegion *lockR = lock.getAsRegion();
+  if (!lockR)
+    return;
+  
+  const GRState *state = C.getState();
+  
+  SVal X = state->getSVal(CE);
+  if (X.isUnknownOrUndef())
+    return;
+  
+  DefinedSVal retVal = cast<DefinedSVal>(X);
+  const GRState *lockSucc = state;
+  
+  if (isTryLock) {
+      // Bifurcate the state, and allow a mode where the lock acquisition fails.
+    const GRState *lockFail;
+    llvm::tie(lockFail, lockSucc) = state->Assume(retVal);    
+    assert(lockFail && lockSucc);
+    C.addTransition(C.GenerateNode(CE, lockFail));
+  }
+  else {
+      // Assume that the return value was 0.
+    lockSucc = state->Assume(retVal, false);
+    assert(lockSucc);
+  }
+  
+    // Record that the lock was acquired.  
+  lockSucc = lockSucc->add<LockSet>(lockR);
+  
+  C.addTransition(lockSucc != state ? C.GenerateNode(CE, lockSucc) :
+                  C.getPredecessor());
+}
+
+void PthreadLockChecker::ReleaseLock(CheckerContext &C, const CallExpr *CE,
+                                     SVal lock) {
+
+  const MemRegion *lockR = lock.getAsRegion();
+  if (!lockR)
+    return;
+  
+  const GRState *state = C.getState();
+
+  // Record that the lock was released.  
+  // FIXME: Handle unlocking locks that were never acquired.  This may
+  // require IPA for wrappers.
+  const GRState *unlockState = state->remove<LockSet>(lockR);
+  
+  if (state == unlockState)
+    return;
+  
+  C.addTransition(C.GenerateNode(CE, unlockState));  
+}
diff --git a/lib/Checker/RangeConstraintManager.cpp b/lib/Checker/RangeConstraintManager.cpp
new file mode 100644
index 0000000..c904c33
--- /dev/null
+++ b/lib/Checker/RangeConstraintManager.cpp
@@ -0,0 +1,359 @@
+//== RangeConstraintManager.cpp - Manage range constraints.------*- C++ -*--==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines RangeConstraintManager, a class that tracks simple
+//  equality and inequality constraints on symbolic values of GRState.
+//
+//===----------------------------------------------------------------------===//
+
+#include "SimpleConstraintManager.h"
+#include "clang/Checker/PathSensitive/GRState.h"
+#include "clang/Checker/PathSensitive/GRStateTrait.h"
+#include "clang/Checker/PathSensitive/GRTransferFuncs.h"
+#include "clang/Checker/ManagerRegistry.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/ImmutableSet.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace clang;
+
+namespace { class ConstraintRange {}; }
+static int ConstraintRangeIndex = 0;
+
+/// A Range represents the closed range [from, to].  The caller must
+/// guarantee that from <= to.  Note that Range is immutable, so as not
+/// to subvert RangeSet's immutability.
+namespace {
+class Range : public std::pair<const llvm::APSInt*,
+                                                const llvm::APSInt*> {
+public:
+  Range(const llvm::APSInt &from, const llvm::APSInt &to)
+    : std::pair<const llvm::APSInt*, const llvm::APSInt*>(&from, &to) {
+    assert(from <= to);
+  }
+  bool Includes(const llvm::APSInt &v) const {
+    return *first <= v && v <= *second;
+  }
+  const llvm::APSInt &From() const {
+    return *first;
+  }
+  const llvm::APSInt &To() const {
+    return *second;
+  }
+  const llvm::APSInt *getConcreteValue() const {
+    return &From() == &To() ? &From() : NULL;
+  }
+
+  void Profile(llvm::FoldingSetNodeID &ID) const {
+    ID.AddPointer(&From());
+    ID.AddPointer(&To());
+  }
+};
+
+
+class RangeTrait : public llvm::ImutContainerInfo<Range> {
+public:
+  // When comparing if one Range is less than another, we should compare
+  // the actual APSInt values instead of their pointers.  This keeps the order
+  // consistent (instead of comparing by pointer values) and can potentially
+  // be used to speed up some of the operations in RangeSet.
+  static inline bool isLess(key_type_ref lhs, key_type_ref rhs) {
+    return *lhs.first < *rhs.first || (!(*rhs.first < *lhs.first) &&
+                                       *lhs.second < *rhs.second);
+  }
+};
+
+/// RangeSet contains a set of ranges. If the set is empty, then
+///  there the value of a symbol is overly constrained and there are no
+///  possible values for that symbol.
+class RangeSet {
+  typedef llvm::ImmutableSet<Range, RangeTrait> PrimRangeSet;
+  PrimRangeSet ranges; // no need to make const, since it is an
+                       // ImmutableSet - this allows default operator=
+                       // to work.
+public:
+  typedef PrimRangeSet::Factory Factory;
+  typedef PrimRangeSet::iterator iterator;
+
+  RangeSet(PrimRangeSet RS) : ranges(RS) {}
+  RangeSet(Factory& F) : ranges(F.GetEmptySet()) {}
+
+  iterator begin() const { return ranges.begin(); }
+  iterator end() const { return ranges.end(); }
+
+  bool isEmpty() const { return ranges.isEmpty(); }
+
+  /// Construct a new RangeSet representing '{ [from, to] }'.
+  RangeSet(Factory &F, const llvm::APSInt &from, const llvm::APSInt &to)
+    : ranges(F.Add(F.GetEmptySet(), Range(from, to))) {}
+
+  /// Profile - Generates a hash profile of this RangeSet for use
+  ///  by FoldingSet.
+  void Profile(llvm::FoldingSetNodeID &ID) const { ranges.Profile(ID); }
+
+  /// getConcreteValue - If a symbol is contrained to equal a specific integer
+  ///  constant then this method returns that value.  Otherwise, it returns
+  ///  NULL.
+  const llvm::APSInt* getConcreteValue() const {
+    return ranges.isSingleton() ? ranges.begin()->getConcreteValue() : 0;
+  }
+
+  /// AddEQ - Create a new RangeSet with the additional constraint that the
+  ///  value be equal to V.
+  RangeSet AddEQ(BasicValueFactory &BV, Factory &F, const llvm::APSInt &V) {
+    // Search for a range that includes 'V'.  If so, return a new RangeSet
+    // representing { [V, V] }.
+    for (PrimRangeSet::iterator i = begin(), e = end(); i!=e; ++i)
+      if (i->Includes(V))
+        return RangeSet(F, V, V);
+
+    return RangeSet(F);
+  }
+
+  /// AddNE - Create a new RangeSet with the additional constraint that the
+  ///  value be not be equal to V.
+  RangeSet AddNE(BasicValueFactory &BV, Factory &F, const llvm::APSInt &V) {
+    PrimRangeSet newRanges = ranges;
+
+    // FIXME: We can perhaps enhance ImmutableSet to do this search for us
+    // in log(N) time using the sorted property of the internal AVL tree.
+    for (iterator i = begin(), e = end(); i != e; ++i) {
+      if (i->Includes(V)) {
+        // Remove the old range.
+        newRanges = F.Remove(newRanges, *i);
+        // Split the old range into possibly one or two ranges.
+        if (V != i->From())
+          newRanges = F.Add(newRanges, Range(i->From(), BV.Sub1(V)));
+        if (V != i->To())
+          newRanges = F.Add(newRanges, Range(BV.Add1(V), i->To()));
+        // All of the ranges are non-overlapping, so we can stop.
+        break;
+      }
+    }
+
+    return newRanges;
+  }
+
+  /// AddNE - Create a new RangeSet with the additional constraint that the
+  ///  value be less than V.
+  RangeSet AddLT(BasicValueFactory &BV, Factory &F, const llvm::APSInt &V) {
+    PrimRangeSet newRanges = F.GetEmptySet();
+
+    for (iterator i = begin(), e = end() ; i != e ; ++i) {
+      if (i->Includes(V) && i->From() < V)
+        newRanges = F.Add(newRanges, Range(i->From(), BV.Sub1(V)));
+      else if (i->To() < V)
+        newRanges = F.Add(newRanges, *i);
+    }
+
+    return newRanges;
+  }
+
+  RangeSet AddLE(BasicValueFactory &BV, Factory &F, const llvm::APSInt &V) {
+    PrimRangeSet newRanges = F.GetEmptySet();
+
+    for (iterator i = begin(), e = end(); i != e; ++i) {
+      // Strictly we should test for includes *V + 1, but no harm is
+      // done by this formulation
+      if (i->Includes(V))
+        newRanges = F.Add(newRanges, Range(i->From(), V));
+      else if (i->To() <= V)
+        newRanges = F.Add(newRanges, *i);
+    }
+
+    return newRanges;
+  }
+
+  RangeSet AddGT(BasicValueFactory &BV, Factory &F, const llvm::APSInt &V) {
+    PrimRangeSet newRanges = F.GetEmptySet();
+
+    for (PrimRangeSet::iterator i = begin(), e = end(); i != e; ++i) {
+      if (i->Includes(V) && i->To() > V)
+        newRanges = F.Add(newRanges, Range(BV.Add1(V), i->To()));
+      else if (i->From() > V)
+        newRanges = F.Add(newRanges, *i);
+    }
+
+    return newRanges;
+  }
+
+  RangeSet AddGE(BasicValueFactory &BV, Factory &F, const llvm::APSInt &V) {
+    PrimRangeSet newRanges = F.GetEmptySet();
+
+    for (PrimRangeSet::iterator i = begin(), e = end(); i != e; ++i) {
+      // Strictly we should test for includes *V - 1, but no harm is
+      // done by this formulation
+      if (i->Includes(V))
+        newRanges = F.Add(newRanges, Range(V, i->To()));
+      else if (i->From() >= V)
+        newRanges = F.Add(newRanges, *i);
+    }
+
+    return newRanges;
+  }
+
+  void print(llvm::raw_ostream &os) const {
+    bool isFirst = true;
+    os << "{ ";
+    for (iterator i = begin(), e = end(); i != e; ++i) {
+      if (isFirst)
+        isFirst = false;
+      else
+        os << ", ";
+
+      os << '[' << i->From().toString(10) << ", " << i->To().toString(10)
+         << ']';
+    }
+    os << " }";
+  }
+
+  bool operator==(const RangeSet &other) const {
+    return ranges == other.ranges;
+  }
+};
+} // end anonymous namespace
+
+typedef llvm::ImmutableMap<SymbolRef,RangeSet> ConstraintRangeTy;
+
+namespace clang {
+template<>
+struct GRStateTrait<ConstraintRange>
+  : public GRStatePartialTrait<ConstraintRangeTy> {
+  static inline void* GDMIndex() { return &ConstraintRangeIndex; }
+};
+}
+
+namespace {
+class RangeConstraintManager : public SimpleConstraintManager{
+  RangeSet GetRange(const GRState *state, SymbolRef sym);
+public:
+  RangeConstraintManager(GRSubEngine &subengine)
+    : SimpleConstraintManager(subengine) {}
+
+  const GRState* AssumeSymNE(const GRState* St, SymbolRef sym,
+                             const llvm::APSInt& V);
+
+  const GRState* AssumeSymEQ(const GRState* St, SymbolRef sym,
+                             const llvm::APSInt& V);
+
+  const GRState* AssumeSymLT(const GRState* St, SymbolRef sym,
+                             const llvm::APSInt& V);
+
+  const GRState* AssumeSymGT(const GRState* St, SymbolRef sym,
+                             const llvm::APSInt& V);
+
+  const GRState* AssumeSymGE(const GRState* St, SymbolRef sym,
+                             const llvm::APSInt& V);
+
+  const GRState* AssumeSymLE(const GRState* St, SymbolRef sym,
+                             const llvm::APSInt& V);
+
+  const llvm::APSInt* getSymVal(const GRState* St, SymbolRef sym) const;
+
+  // FIXME: Refactor into SimpleConstraintManager?
+  bool isEqual(const GRState* St, SymbolRef sym, const llvm::APSInt& V) const {
+    const llvm::APSInt *i = getSymVal(St, sym);
+    return i ? *i == V : false;
+  }
+
+  const GRState* RemoveDeadBindings(const GRState* St, SymbolReaper& SymReaper);
+
+  void print(const GRState* St, llvm::raw_ostream& Out,
+             const char* nl, const char *sep);
+
+private:
+  RangeSet::Factory F;
+};
+
+} // end anonymous namespace
+
+ConstraintManager* clang::CreateRangeConstraintManager(GRStateManager&,
+                                                       GRSubEngine &subeng) {
+  return new RangeConstraintManager(subeng);
+}
+
+const llvm::APSInt* RangeConstraintManager::getSymVal(const GRState* St,
+                                                      SymbolRef sym) const {
+  const ConstraintRangeTy::data_type *T = St->get<ConstraintRange>(sym);
+  return T ? T->getConcreteValue() : NULL;
+}
+
+/// Scan all symbols referenced by the constraints. If the symbol is not alive
+/// as marked in LSymbols, mark it as dead in DSymbols.
+const GRState*
+RangeConstraintManager::RemoveDeadBindings(const GRState* state,
+                                           SymbolReaper& SymReaper) {
+
+  ConstraintRangeTy CR = state->get<ConstraintRange>();
+  ConstraintRangeTy::Factory& CRFactory = state->get_context<ConstraintRange>();
+
+  for (ConstraintRangeTy::iterator I = CR.begin(), E = CR.end(); I != E; ++I) {
+    SymbolRef sym = I.getKey();
+    if (SymReaper.maybeDead(sym))
+      CR = CRFactory.Remove(CR, sym);
+  }
+
+  return state->set<ConstraintRange>(CR);
+}
+
+//===------------------------------------------------------------------------===
+// AssumeSymX methods: public interface for RangeConstraintManager.
+//===------------------------------------------------------------------------===/
+
+RangeSet
+RangeConstraintManager::GetRange(const GRState *state, SymbolRef sym) {
+  if (ConstraintRangeTy::data_type* V = state->get<ConstraintRange>(sym))
+    return *V;
+
+  // Lazily generate a new RangeSet representing all possible values for the
+  // given symbol type.
+  QualType T = state->getSymbolManager().getType(sym);
+  BasicValueFactory& BV = state->getBasicVals();
+  return RangeSet(F, BV.getMinValue(T), BV.getMaxValue(T));
+}
+
+//===------------------------------------------------------------------------===
+// AssumeSymX methods: public interface for RangeConstraintManager.
+//===------------------------------------------------------------------------===/
+
+#define AssumeX(OP)\
+const GRState*\
+RangeConstraintManager::AssumeSym ## OP(const GRState* state, SymbolRef sym,\
+  const llvm::APSInt& V){\
+  const RangeSet& R = GetRange(state, sym).Add##OP(state->getBasicVals(), F, V);\
+  return !R.isEmpty() ? state->set<ConstraintRange>(sym, R) : NULL;\
+}
+
+AssumeX(EQ)
+AssumeX(NE)
+AssumeX(LT)
+AssumeX(GT)
+AssumeX(LE)
+AssumeX(GE)
+
+//===------------------------------------------------------------------------===
+// Pretty-printing.
+//===------------------------------------------------------------------------===/
+
+void RangeConstraintManager::print(const GRState* St, llvm::raw_ostream& Out,
+                                   const char* nl, const char *sep) {
+
+  ConstraintRangeTy Ranges = St->get<ConstraintRange>();
+
+  if (Ranges.isEmpty())
+    return;
+
+  Out << nl << sep << "ranges of symbol values:";
+
+  for (ConstraintRangeTy::iterator I=Ranges.begin(), E=Ranges.end(); I!=E; ++I){
+    Out << nl << ' ' << I.getKey() << " : ";
+    I.getData().print(Out);
+  }
+}
diff --git a/lib/Checker/RegionStore.cpp b/lib/Checker/RegionStore.cpp
new file mode 100644
index 0000000..1e15d43
--- /dev/null
+++ b/lib/Checker/RegionStore.cpp
@@ -0,0 +1,1904 @@
+//== RegionStore.cpp - Field-sensitive store model --------------*- C++ -*--==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a basic region store model. In this model, we do have field
+// sensitivity. But we assume nothing about the heap shape. So recursive data
+// structures are largely ignored. Basically we do 1-limiting analysis.
+// Parameter pointers are assumed with no aliasing. Pointee objects of
+// parameters are created lazily.
+//
+//===----------------------------------------------------------------------===//
+#include "clang/AST/CharUnits.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/Analysis/Analyses/LiveVariables.h"
+#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Basic/TargetInfo.h"
+#include "clang/Checker/PathSensitive/GRState.h"
+#include "clang/Checker/PathSensitive/GRStateTrait.h"
+#include "clang/Checker/PathSensitive/MemRegion.h"
+#include "llvm/ADT/ImmutableList.h"
+#include "llvm/ADT/ImmutableMap.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace clang;
+using llvm::Optional;
+
+//===----------------------------------------------------------------------===//
+// Representation of binding keys.
+//===----------------------------------------------------------------------===//
+
+namespace {
+class BindingKey {
+public:
+  enum Kind { Direct = 0x0, Default = 0x1 };
+private:
+  llvm ::PointerIntPair<const MemRegion*, 1> P;
+  uint64_t Offset;
+
+  explicit BindingKey(const MemRegion *r, uint64_t offset, Kind k)
+    : P(r, (unsigned) k), Offset(offset) { assert(r); }
+public:
+
+  bool isDefault() const { return P.getInt() == Default; }
+  bool isDirect() const { return P.getInt() == Direct; }
+
+  const MemRegion *getRegion() const { return P.getPointer(); }
+  uint64_t getOffset() const { return Offset; }
+
+  void Profile(llvm::FoldingSetNodeID& ID) const {
+    ID.AddPointer(P.getOpaqueValue());
+    ID.AddInteger(Offset);
+  }
+
+  static BindingKey Make(const MemRegion *R, Kind k);
+
+  bool operator<(const BindingKey &X) const {
+    if (P.getOpaqueValue() < X.P.getOpaqueValue())
+      return true;
+    if (P.getOpaqueValue() > X.P.getOpaqueValue())
+      return false;
+    return Offset < X.Offset;
+  }
+
+  bool operator==(const BindingKey &X) const {
+    return P.getOpaqueValue() == X.P.getOpaqueValue() &&
+           Offset == X.Offset;
+  }
+};
+} // end anonymous namespace
+
+namespace llvm {
+  static inline
+  llvm::raw_ostream& operator<<(llvm::raw_ostream& os, BindingKey K) {
+    os << '(' << K.getRegion() << ',' << K.getOffset()
+       << ',' << (K.isDirect() ? "direct" : "default")
+       << ')';
+    return os;
+  }
+} // end llvm namespace
+
+//===----------------------------------------------------------------------===//
+// Actual Store type.
+//===----------------------------------------------------------------------===//
+
+typedef llvm::ImmutableMap<BindingKey, SVal> RegionBindings;
+
+//===----------------------------------------------------------------------===//
+// Fine-grained control of RegionStoreManager.
+//===----------------------------------------------------------------------===//
+
+namespace {
+struct minimal_features_tag {};
+struct maximal_features_tag {};
+
+class RegionStoreFeatures {
+  bool SupportsFields;
+  bool SupportsRemaining;
+
+public:
+  RegionStoreFeatures(minimal_features_tag) :
+    SupportsFields(false), SupportsRemaining(false) {}
+
+  RegionStoreFeatures(maximal_features_tag) :
+    SupportsFields(true), SupportsRemaining(false) {}
+
+  void enableFields(bool t) { SupportsFields = t; }
+
+  bool supportsFields() const { return SupportsFields; }
+  bool supportsRemaining() const { return SupportsRemaining; }
+};
+}
+
+//===----------------------------------------------------------------------===//
+// Region "Extents"
+//===----------------------------------------------------------------------===//
+//
+//  MemRegions represent chunks of memory with a size (their "extent").  This
+//  GDM entry tracks the extents for regions.  Extents are in bytes.
+//
+namespace { class RegionExtents {}; }
+static int RegionExtentsIndex = 0;
+namespace clang {
+  template<> struct GRStateTrait<RegionExtents>
+    : public GRStatePartialTrait<llvm::ImmutableMap<const MemRegion*, SVal> > {
+    static void* GDMIndex() { return &RegionExtentsIndex; }
+  };
+}
+
+//===----------------------------------------------------------------------===//
+// Utility functions.
+//===----------------------------------------------------------------------===//
+
+static bool IsAnyPointerOrIntptr(QualType ty, ASTContext &Ctx) {
+  if (ty->isAnyPointerType())
+    return true;
+
+  return ty->isIntegerType() && ty->isScalarType() &&
+         Ctx.getTypeSize(ty) == Ctx.getTypeSize(Ctx.VoidPtrTy);
+}
+
+//===----------------------------------------------------------------------===//
+// Main RegionStore logic.
+//===----------------------------------------------------------------------===//
+
+namespace {
+
+class RegionStoreSubRegionMap : public SubRegionMap {
+public:
+  typedef llvm::ImmutableSet<const MemRegion*> Set;
+  typedef llvm::DenseMap<const MemRegion*, Set> Map;
+private:
+  Set::Factory F;
+  Map M;
+public:
+  bool add(const MemRegion* Parent, const MemRegion* SubRegion) {
+    Map::iterator I = M.find(Parent);
+
+    if (I == M.end()) {
+      M.insert(std::make_pair(Parent, F.Add(F.GetEmptySet(), SubRegion)));
+      return true;
+    }
+
+    I->second = F.Add(I->second, SubRegion);
+    return false;
+  }
+
+  void process(llvm::SmallVectorImpl<const SubRegion*> &WL, const SubRegion *R);
+
+  ~RegionStoreSubRegionMap() {}
+
+  const Set *getSubRegions(const MemRegion *Parent) const {
+    Map::const_iterator I = M.find(Parent);
+    return I == M.end() ? NULL : &I->second;
+  }
+
+  bool iterSubRegions(const MemRegion* Parent, Visitor& V) const {
+    Map::const_iterator I = M.find(Parent);
+
+    if (I == M.end())
+      return true;
+
+    Set S = I->second;
+    for (Set::iterator SI=S.begin(),SE=S.end(); SI != SE; ++SI) {
+      if (!V.Visit(Parent, *SI))
+        return false;
+    }
+
+    return true;
+  }
+};
+
+
+class RegionStoreManager : public StoreManager {
+  const RegionStoreFeatures Features;
+  RegionBindings::Factory RBFactory;
+
+public:
+  RegionStoreManager(GRStateManager& mgr, const RegionStoreFeatures &f)
+    : StoreManager(mgr),
+      Features(f),
+      RBFactory(mgr.getAllocator()) {}
+
+  SubRegionMap *getSubRegionMap(Store store) {
+    return getRegionStoreSubRegionMap(store);
+  }
+
+  RegionStoreSubRegionMap *getRegionStoreSubRegionMap(Store store);
+
+  Optional<SVal> getBinding(RegionBindings B, const MemRegion *R);
+  Optional<SVal> getDirectBinding(RegionBindings B, const MemRegion *R);
+  /// getDefaultBinding - Returns an SVal* representing an optional default
+  ///  binding associated with a region and its subregions.
+  Optional<SVal> getDefaultBinding(RegionBindings B, const MemRegion *R);
+
+  /// setImplicitDefaultValue - Set the default binding for the provided
+  ///  MemRegion to the value implicitly defined for compound literals when
+  ///  the value is not specified.
+  Store setImplicitDefaultValue(Store store, const MemRegion *R, QualType T);
+
+  /// ArrayToPointer - Emulates the "decay" of an array to a pointer
+  ///  type.  'Array' represents the lvalue of the array being decayed
+  ///  to a pointer, and the returned SVal represents the decayed
+  ///  version of that lvalue (i.e., a pointer to the first element of
+  ///  the array).  This is called by GRExprEngine when evaluating
+  ///  casts from arrays to pointers.
+  SVal ArrayToPointer(Loc Array);
+
+  SVal EvalBinOp(BinaryOperator::Opcode Op,Loc L, NonLoc R, QualType resultTy);
+
+  Store getInitialStore(const LocationContext *InitLoc) {
+    return RBFactory.GetEmptyMap().getRoot();
+  }
+
+  //===-------------------------------------------------------------------===//
+  // Binding values to regions.
+  //===-------------------------------------------------------------------===//
+
+  Store InvalidateRegion(Store store, const MemRegion *R, const Expr *E,
+                         unsigned Count, InvalidatedSymbols *IS) {
+    return RegionStoreManager::InvalidateRegions(store, &R, &R+1, E, Count, IS);
+  }
+
+  Store InvalidateRegions(Store store,
+                          const MemRegion * const *Begin,
+                          const MemRegion * const *End,
+                          const Expr *E, unsigned Count,
+                          InvalidatedSymbols *IS);
+
+public:   // Made public for helper classes.
+
+  void RemoveSubRegionBindings(RegionBindings &B, const MemRegion *R,
+                               RegionStoreSubRegionMap &M);
+
+  RegionBindings Add(RegionBindings B, BindingKey K, SVal V);
+
+  RegionBindings Add(RegionBindings B, const MemRegion *R,
+                     BindingKey::Kind k, SVal V);
+
+  const SVal *Lookup(RegionBindings B, BindingKey K);
+  const SVal *Lookup(RegionBindings B, const MemRegion *R, BindingKey::Kind k);
+
+  RegionBindings Remove(RegionBindings B, BindingKey K);
+  RegionBindings Remove(RegionBindings B, const MemRegion *R,
+                        BindingKey::Kind k);
+
+  RegionBindings Remove(RegionBindings B, const MemRegion *R) {
+    return Remove(Remove(B, R, BindingKey::Direct), R, BindingKey::Default);
+  }
+
+  Store Remove(Store store, BindingKey K);
+
+public: // Part of public interface to class.
+
+  Store Bind(Store store, Loc LV, SVal V);
+
+  Store BindCompoundLiteral(Store store, const CompoundLiteralExpr* CL,
+                            const LocationContext *LC, SVal V);
+
+  Store BindDecl(Store store, const VarRegion *VR, SVal InitVal);
+
+  Store BindDeclWithNoInit(Store store, const VarRegion *) {
+    return store;
+  }
+
+  /// BindStruct - Bind a compound value to a structure.
+  Store BindStruct(Store store, const TypedRegion* R, SVal V);
+
+  Store BindArray(Store store, const TypedRegion* R, SVal V);
+
+  /// KillStruct - Set the entire struct to unknown.
+  Store KillStruct(Store store, const TypedRegion* R);
+
+  Store Remove(Store store, Loc LV);
+
+
+  //===------------------------------------------------------------------===//
+  // Loading values from regions.
+  //===------------------------------------------------------------------===//
+
+  /// The high level logic for this method is this:
+  /// Retrieve (L)
+  ///   if L has binding
+  ///     return L's binding
+  ///   else if L is in killset
+  ///     return unknown
+  ///   else
+  ///     if L is on stack or heap
+  ///       return undefined
+  ///     else
+  ///       return symbolic
+  SVal Retrieve(Store store, Loc L, QualType T = QualType());
+
+  SVal RetrieveElement(Store store, const ElementRegion *R);
+
+  SVal RetrieveField(Store store, const FieldRegion *R);
+
+  SVal RetrieveObjCIvar(Store store, const ObjCIvarRegion *R);
+
+  SVal RetrieveVar(Store store, const VarRegion *R);
+
+  SVal RetrieveLazySymbol(const TypedRegion *R);
+
+  SVal RetrieveFieldOrElementCommon(Store store, const TypedRegion *R,
+                                    QualType Ty, const MemRegion *superR);
+
+  /// Retrieve the values in a struct and return a CompoundVal, used when doing
+  /// struct copy:
+  /// struct s x, y;
+  /// x = y;
+  /// y's value is retrieved by this method.
+  SVal RetrieveStruct(Store store, const TypedRegion* R);
+
+  SVal RetrieveArray(Store store, const TypedRegion* R);
+
+  /// Get the state and region whose binding this region R corresponds to.
+  std::pair<Store, const MemRegion*>
+  GetLazyBinding(RegionBindings B, const MemRegion *R);
+
+  Store CopyLazyBindings(nonloc::LazyCompoundVal V, Store store,
+                         const TypedRegion *R);
+
+  //===------------------------------------------------------------------===//
+  // State pruning.
+  //===------------------------------------------------------------------===//
+
+  /// RemoveDeadBindings - Scans the RegionStore of 'state' for dead values.
+  ///  It returns a new Store with these values removed.
+  Store RemoveDeadBindings(Store store, Stmt* Loc, 
+                           const StackFrameContext *LCtx,
+                           SymbolReaper& SymReaper,
+                          llvm::SmallVectorImpl<const MemRegion*>& RegionRoots);
+
+  const GRState *EnterStackFrame(const GRState *state,
+                                 const StackFrameContext *frame);
+
+  //===------------------------------------------------------------------===//
+  // Region "extents".
+  //===------------------------------------------------------------------===//
+
+  const GRState *setExtent(const GRState *state,const MemRegion* R,SVal Extent);
+  DefinedOrUnknownSVal getSizeInElements(const GRState *state,
+                                         const MemRegion* R, QualType EleTy);
+
+  //===------------------------------------------------------------------===//
+  // Utility methods.
+  //===------------------------------------------------------------------===//
+
+  static inline RegionBindings GetRegionBindings(Store store) {
+    return RegionBindings(static_cast<const RegionBindings::TreeTy*>(store));
+  }
+
+  void print(Store store, llvm::raw_ostream& Out, const char* nl,
+             const char *sep);
+
+  void iterBindings(Store store, BindingsHandler& f) {
+    // FIXME: Implement.
+  }
+
+  // FIXME: Remove.
+  BasicValueFactory& getBasicVals() {
+      return StateMgr.getBasicVals();
+  }
+
+  // FIXME: Remove.
+  ASTContext& getContext() { return StateMgr.getContext(); }
+};
+
+} // end anonymous namespace
+
+//===----------------------------------------------------------------------===//
+// RegionStore creation.
+//===----------------------------------------------------------------------===//
+
+StoreManager *clang::CreateRegionStoreManager(GRStateManager& StMgr) {
+  RegionStoreFeatures F = maximal_features_tag();
+  return new RegionStoreManager(StMgr, F);
+}
+
+StoreManager *clang::CreateFieldsOnlyRegionStoreManager(GRStateManager &StMgr) {
+  RegionStoreFeatures F = minimal_features_tag();
+  F.enableFields(true);
+  return new RegionStoreManager(StMgr, F);
+}
+
+void
+RegionStoreSubRegionMap::process(llvm::SmallVectorImpl<const SubRegion*> &WL,
+                                 const SubRegion *R) {
+  const MemRegion *superR = R->getSuperRegion();
+  if (add(superR, R))
+    if (const SubRegion *sr = dyn_cast<SubRegion>(superR))
+      WL.push_back(sr);
+}
+
+RegionStoreSubRegionMap*
+RegionStoreManager::getRegionStoreSubRegionMap(Store store) {
+  RegionBindings B = GetRegionBindings(store);
+  RegionStoreSubRegionMap *M = new RegionStoreSubRegionMap();
+
+  llvm::SmallVector<const SubRegion*, 10> WL;
+
+  for (RegionBindings::iterator I=B.begin(), E=B.end(); I!=E; ++I)
+    if (const SubRegion *R = dyn_cast<SubRegion>(I.getKey().getRegion()))
+      M->process(WL, R);
+
+  // We also need to record in the subregion map "intermediate" regions that
+  // don't have direct bindings but are super regions of those that do.
+  while (!WL.empty()) {
+    const SubRegion *R = WL.back();
+    WL.pop_back();
+    M->process(WL, R);
+  }
+
+  return M;
+}
+
+//===----------------------------------------------------------------------===//
+// Region Cluster analysis.
+//===----------------------------------------------------------------------===//
+
+namespace {
+template <typename DERIVED>
+class ClusterAnalysis  {
+protected:
+  typedef BumpVector<BindingKey> RegionCluster;
+  typedef llvm::DenseMap<const MemRegion *, RegionCluster *> ClusterMap;
+  llvm::DenseMap<const RegionCluster*, unsigned> Visited;
+  typedef llvm::SmallVector<std::pair<const MemRegion *, RegionCluster*>, 10>
+    WorkList;
+
+  BumpVectorContext BVC;
+  ClusterMap ClusterM;
+  WorkList WL;
+
+  RegionStoreManager &RM;
+  ASTContext &Ctx;
+  ValueManager &ValMgr;
+
+  RegionBindings B;
+
+public:
+  ClusterAnalysis(RegionStoreManager &rm, GRStateManager &StateMgr,
+                  RegionBindings b)
+    : RM(rm), Ctx(StateMgr.getContext()), ValMgr(StateMgr.getValueManager()),
+      B(b) {}
+
+  RegionBindings getRegionBindings() const { return B; }
+
+  void AddToCluster(BindingKey K) {
+    const MemRegion *R = K.getRegion();
+    const MemRegion *baseR = R->getBaseRegion();
+    RegionCluster &C = getCluster(baseR);
+    C.push_back(K, BVC);
+    static_cast<DERIVED*>(this)->VisitAddedToCluster(baseR, C);
+  }
+
+  bool isVisited(const MemRegion *R) {
+    return (bool) Visited[&getCluster(R->getBaseRegion())];
+  }
+
+  RegionCluster& getCluster(const MemRegion *R) {
+    RegionCluster *&CRef = ClusterM[R];
+    if (!CRef) {
+      void *Mem = BVC.getAllocator().template Allocate<RegionCluster>();
+      CRef = new (Mem) RegionCluster(BVC, 10);
+    }
+    return *CRef;
+  }
+
+  void GenerateClusters() {
+      // Scan the entire set of bindings and make the region clusters.
+    for (RegionBindings::iterator RI = B.begin(), RE = B.end(); RI != RE; ++RI){
+      AddToCluster(RI.getKey());
+      if (const MemRegion *R = RI.getData().getAsRegion()) {
+        // Generate a cluster, but don't add the region to the cluster
+        // if there aren't any bindings.
+        getCluster(R->getBaseRegion());
+      }
+    }
+  }
+
+  bool AddToWorkList(const MemRegion *R, RegionCluster &C) {
+    if (unsigned &visited = Visited[&C])
+      return false;
+    else
+      visited = 1;
+
+    WL.push_back(std::make_pair(R, &C));
+    return true;
+  }
+
+  bool AddToWorkList(BindingKey K) {
+    return AddToWorkList(K.getRegion());
+  }
+
+  bool AddToWorkList(const MemRegion *R) {
+    const MemRegion *baseR = R->getBaseRegion();
+    return AddToWorkList(baseR, getCluster(baseR));
+  }
+
+  void RunWorkList() {
+    while (!WL.empty()) {
+      const MemRegion *baseR;
+      RegionCluster *C;
+      llvm::tie(baseR, C) = WL.back();
+      WL.pop_back();
+
+        // First visit the cluster.
+      static_cast<DERIVED*>(this)->VisitCluster(baseR, C->begin(), C->end());
+
+        // Next, visit the base region.
+      static_cast<DERIVED*>(this)->VisitBaseRegion(baseR);
+    }
+  }
+
+public:
+  void VisitAddedToCluster(const MemRegion *baseR, RegionCluster &C) {}
+  void VisitCluster(const MemRegion *baseR, BindingKey *I, BindingKey *E) {}
+  void VisitBaseRegion(const MemRegion *baseR) {}
+};
+}
+
+//===----------------------------------------------------------------------===//
+// Binding invalidation.
+//===----------------------------------------------------------------------===//
+
+void RegionStoreManager::RemoveSubRegionBindings(RegionBindings &B,
+                                                 const MemRegion *R,
+                                                 RegionStoreSubRegionMap &M) {
+
+  if (const RegionStoreSubRegionMap::Set *S = M.getSubRegions(R))
+    for (RegionStoreSubRegionMap::Set::iterator I = S->begin(), E = S->end();
+         I != E; ++I)
+      RemoveSubRegionBindings(B, *I, M);
+
+  B = Remove(B, R);
+}
+
+namespace {
+class InvalidateRegionsWorker : public ClusterAnalysis<InvalidateRegionsWorker>
+{
+  const Expr *Ex;
+  unsigned Count;
+  StoreManager::InvalidatedSymbols *IS;
+public:
+  InvalidateRegionsWorker(RegionStoreManager &rm,
+                          GRStateManager &stateMgr,
+                          RegionBindings b,
+                          const Expr *ex, unsigned count,
+                          StoreManager::InvalidatedSymbols *is)
+    : ClusterAnalysis<InvalidateRegionsWorker>(rm, stateMgr, b),
+      Ex(ex), Count(count), IS(is) {}
+
+  void VisitCluster(const MemRegion *baseR, BindingKey *I, BindingKey *E);
+  void VisitBaseRegion(const MemRegion *baseR);
+
+private:
+  void VisitBinding(SVal V);
+};
+}
+
+void InvalidateRegionsWorker::VisitBinding(SVal V) {
+  // A symbol?  Mark it touched by the invalidation.
+  if (IS)
+    if (SymbolRef Sym = V.getAsSymbol())
+      IS->insert(Sym);
+
+  if (const MemRegion *R = V.getAsRegion()) {
+    AddToWorkList(R);
+    return;
+  }
+
+  // Is it a LazyCompoundVal?  All references get invalidated as well.
+  if (const nonloc::LazyCompoundVal *LCS =
+        dyn_cast<nonloc::LazyCompoundVal>(&V)) {
+
+    const MemRegion *LazyR = LCS->getRegion();
+    RegionBindings B = RegionStoreManager::GetRegionBindings(LCS->getStore());
+
+    for (RegionBindings::iterator RI = B.begin(), RE = B.end(); RI != RE; ++RI){
+      const MemRegion *baseR = RI.getKey().getRegion();
+      if (cast<SubRegion>(baseR)->isSubRegionOf(LazyR))
+        VisitBinding(RI.getData());
+    }
+
+    return;
+  }
+}
+
+void InvalidateRegionsWorker::VisitCluster(const MemRegion *baseR,
+                                           BindingKey *I, BindingKey *E) {
+  for ( ; I != E; ++I) {
+    // Get the old binding.  Is it a region?  If so, add it to the worklist.
+    const BindingKey &K = *I;
+    if (const SVal *V = RM.Lookup(B, K))
+      VisitBinding(*V);
+
+    B = RM.Remove(B, K);
+  }
+}
+
+void InvalidateRegionsWorker::VisitBaseRegion(const MemRegion *baseR) {
+  if (IS) {
+    // Symbolic region?  Mark that symbol touched by the invalidation.
+    if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(baseR))
+      IS->insert(SR->getSymbol());
+  }
+
+  // BlockDataRegion?  If so, invalidate captured variables that are passed
+  // by reference.
+  if (const BlockDataRegion *BR = dyn_cast<BlockDataRegion>(baseR)) {
+    for (BlockDataRegion::referenced_vars_iterator
+         BI = BR->referenced_vars_begin(), BE = BR->referenced_vars_end() ;
+         BI != BE; ++BI) {
+      const VarRegion *VR = *BI;
+      const VarDecl *VD = VR->getDecl();
+      if (VD->getAttr<BlocksAttr>() || !VD->hasLocalStorage())
+        AddToWorkList(VR);
+    }
+    return;
+  }
+
+  if (isa<AllocaRegion>(baseR) || isa<SymbolicRegion>(baseR)) {
+    // Invalidate the region by setting its default value to
+    // conjured symbol. The type of the symbol is irrelavant.
+    DefinedOrUnknownSVal V = ValMgr.getConjuredSymbolVal(baseR, Ex, Ctx.IntTy,
+                                                         Count);
+    B = RM.Add(B, baseR, BindingKey::Default, V);
+    return;
+  }
+
+  if (!baseR->isBoundable())
+    return;
+
+  const TypedRegion *TR = cast<TypedRegion>(baseR);
+  QualType T = TR->getValueType(Ctx);
+
+    // Invalidate the binding.
+  if (const RecordType *RT = T->getAsStructureType()) {
+    const RecordDecl *RD = RT->getDecl()->getDefinition();
+      // No record definition.  There is nothing we can do.
+    if (!RD) {
+      B = RM.Remove(B, baseR);
+      return;
+    }
+
+      // Invalidate the region by setting its default value to
+      // conjured symbol. The type of the symbol is irrelavant.
+    DefinedOrUnknownSVal V = ValMgr.getConjuredSymbolVal(baseR, Ex, Ctx.IntTy,
+                                                         Count);
+    B = RM.Add(B, baseR, BindingKey::Default, V);
+    return;
+  }
+
+  if (const ArrayType *AT = Ctx.getAsArrayType(T)) {
+      // Set the default value of the array to conjured symbol.
+    DefinedOrUnknownSVal V =
+    ValMgr.getConjuredSymbolVal(baseR, Ex, AT->getElementType(), Count);
+    B = RM.Add(B, baseR, BindingKey::Default, V);
+    return;
+  }
+
+  DefinedOrUnknownSVal V = ValMgr.getConjuredSymbolVal(baseR, Ex, T, Count);
+  assert(SymbolManager::canSymbolicate(T) || V.isUnknown());
+  B = RM.Add(B, baseR, BindingKey::Direct, V);
+}
+
+Store RegionStoreManager::InvalidateRegions(Store store,
+                                            const MemRegion * const *I,
+                                            const MemRegion * const *E,
+                                            const Expr *Ex, unsigned Count,
+                                            InvalidatedSymbols *IS) {
+  InvalidateRegionsWorker W(*this, StateMgr,
+                            RegionStoreManager::GetRegionBindings(store),
+                            Ex, Count, IS);
+
+  // Scan the bindings and generate the clusters.
+  W.GenerateClusters();
+
+  // Add I .. E to the worklist.
+  for ( ; I != E; ++I)
+    W.AddToWorkList(*I);
+
+  W.RunWorkList();
+
+  // Return the new bindings.
+  return W.getRegionBindings().getRoot();
+}
+
+//===----------------------------------------------------------------------===//
+// Extents for regions.
+//===----------------------------------------------------------------------===//
+
+DefinedOrUnknownSVal RegionStoreManager::getSizeInElements(const GRState *state,
+                                                           const MemRegion *R,
+                                                           QualType EleTy) {
+
+  switch (R->getKind()) {
+    case MemRegion::CXXThisRegionKind:
+      assert(0 && "Cannot get size of 'this' region");
+    case MemRegion::GenericMemSpaceRegionKind:
+    case MemRegion::StackLocalsSpaceRegionKind:
+    case MemRegion::StackArgumentsSpaceRegionKind:
+    case MemRegion::HeapSpaceRegionKind:
+    case MemRegion::GlobalsSpaceRegionKind:
+    case MemRegion::UnknownSpaceRegionKind:
+      assert(0 && "Cannot index into a MemSpace");
+      return UnknownVal();
+
+    case MemRegion::FunctionTextRegionKind:
+    case MemRegion::BlockTextRegionKind:
+    case MemRegion::BlockDataRegionKind:
+      // Technically this can happen if people do funny things with casts.
+      return UnknownVal();
+
+      // Not yet handled.
+    case MemRegion::AllocaRegionKind:
+    case MemRegion::CompoundLiteralRegionKind:
+    case MemRegion::ElementRegionKind:
+    case MemRegion::FieldRegionKind:
+    case MemRegion::ObjCIvarRegionKind:
+    case MemRegion::CXXObjectRegionKind:
+      return UnknownVal();
+
+    case MemRegion::SymbolicRegionKind: {
+      const SVal *Size = state->get<RegionExtents>(R);
+      if (!Size)
+        return UnknownVal();
+      const nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(Size);
+      if (!CI)
+        return UnknownVal();
+
+      CharUnits RegionSize =
+        CharUnits::fromQuantity(CI->getValue().getSExtValue());
+      CharUnits EleSize = getContext().getTypeSizeInChars(EleTy);
+      assert(RegionSize % EleSize == 0);
+
+      return ValMgr.makeIntVal(RegionSize / EleSize, false);
+    }
+
+    case MemRegion::StringRegionKind: {
+      const StringLiteral* Str = cast<StringRegion>(R)->getStringLiteral();
+      // We intentionally made the size value signed because it participates in
+      // operations with signed indices.
+      return ValMgr.makeIntVal(Str->getByteLength()+1, false);
+    }
+
+    case MemRegion::VarRegionKind: {
+      const VarRegion* VR = cast<VarRegion>(R);
+      // Get the type of the variable.
+      QualType T = VR->getDesugaredValueType(getContext());
+
+      // FIXME: Handle variable-length arrays.
+      if (isa<VariableArrayType>(T))
+        return UnknownVal();
+
+      if (const ConstantArrayType* CAT = dyn_cast<ConstantArrayType>(T)) {
+        // return the size as signed integer.
+        return ValMgr.makeIntVal(CAT->getSize(), false);
+      }
+
+      // Clients can reinterpret ordinary variables as arrays, possibly of
+      // another type. The width is rounded down to ensure that an access is
+      // entirely within bounds.
+      CharUnits VarSize = getContext().getTypeSizeInChars(T);
+      CharUnits EleSize = getContext().getTypeSizeInChars(EleTy);
+      return ValMgr.makeIntVal(VarSize / EleSize, false);
+    }
+  }
+
+  assert(0 && "Unreachable");
+  return UnknownVal();
+}
+
+const GRState *RegionStoreManager::setExtent(const GRState *state,
+                                             const MemRegion *region,
+                                             SVal extent) {
+  return state->set<RegionExtents>(region, extent);
+}
+
+//===----------------------------------------------------------------------===//
+// Location and region casting.
+//===----------------------------------------------------------------------===//
+
+/// ArrayToPointer - Emulates the "decay" of an array to a pointer
+///  type.  'Array' represents the lvalue of the array being decayed
+///  to a pointer, and the returned SVal represents the decayed
+///  version of that lvalue (i.e., a pointer to the first element of
+///  the array).  This is called by GRExprEngine when evaluating casts
+///  from arrays to pointers.
+SVal RegionStoreManager::ArrayToPointer(Loc Array) {
+  if (!isa<loc::MemRegionVal>(Array))
+    return UnknownVal();
+
+  const MemRegion* R = cast<loc::MemRegionVal>(&Array)->getRegion();
+  const TypedRegion* ArrayR = dyn_cast<TypedRegion>(R);
+
+  if (!ArrayR)
+    return UnknownVal();
+
+  // Strip off typedefs from the ArrayRegion's ValueType.
+  QualType T = ArrayR->getValueType(getContext()).getDesugaredType();
+  ArrayType *AT = cast<ArrayType>(T);
+  T = AT->getElementType();
+
+  SVal ZeroIdx = ValMgr.makeZeroArrayIndex();
+  return loc::MemRegionVal(MRMgr.getElementRegion(T, ZeroIdx, ArrayR,
+                                                  getContext()));
+}
+
+//===----------------------------------------------------------------------===//
+// Pointer arithmetic.
+//===----------------------------------------------------------------------===//
+
+SVal RegionStoreManager::EvalBinOp(BinaryOperator::Opcode Op, Loc L, NonLoc R,
+                                   QualType resultTy) {
+  // Assume the base location is MemRegionVal.
+  if (!isa<loc::MemRegionVal>(L))
+    return UnknownVal();
+
+  const MemRegion* MR = cast<loc::MemRegionVal>(L).getRegion();
+  const ElementRegion *ER = 0;
+
+  switch (MR->getKind()) {
+    case MemRegion::SymbolicRegionKind: {
+      const SymbolicRegion *SR = cast<SymbolicRegion>(MR);
+      SymbolRef Sym = SR->getSymbol();
+      QualType T = Sym->getType(getContext());
+      QualType EleTy;
+
+      if (const PointerType *PT = T->getAs<PointerType>())
+        EleTy = PT->getPointeeType();
+      else
+        EleTy = T->getAs<ObjCObjectPointerType>()->getPointeeType();
+
+      SVal ZeroIdx = ValMgr.makeZeroArrayIndex();
+      ER = MRMgr.getElementRegion(EleTy, ZeroIdx, SR, getContext());
+      break;
+    }
+    case MemRegion::AllocaRegionKind: {
+      const AllocaRegion *AR = cast<AllocaRegion>(MR);
+      QualType T = getContext().CharTy; // Create an ElementRegion of bytes.
+      QualType EleTy = T->getAs<PointerType>()->getPointeeType();
+      SVal ZeroIdx = ValMgr.makeZeroArrayIndex();
+      ER = MRMgr.getElementRegion(EleTy, ZeroIdx, AR, getContext());
+      break;
+    }
+
+    case MemRegion::ElementRegionKind: {
+      ER = cast<ElementRegion>(MR);
+      break;
+    }
+
+    // Not yet handled.
+    case MemRegion::VarRegionKind:
+    case MemRegion::StringRegionKind: {
+
+    }
+    // Fall-through.
+    case MemRegion::CompoundLiteralRegionKind:
+    case MemRegion::FieldRegionKind:
+    case MemRegion::ObjCIvarRegionKind:
+    case MemRegion::CXXObjectRegionKind:
+      return UnknownVal();
+
+    case MemRegion::FunctionTextRegionKind:
+    case MemRegion::BlockTextRegionKind:
+    case MemRegion::BlockDataRegionKind:
+      // Technically this can happen if people do funny things with casts.
+      return UnknownVal();
+
+    case MemRegion::CXXThisRegionKind:
+      assert(0 &&
+             "Cannot perform pointer arithmetic on implicit argument 'this'");
+    case MemRegion::GenericMemSpaceRegionKind:
+    case MemRegion::StackLocalsSpaceRegionKind:
+    case MemRegion::StackArgumentsSpaceRegionKind:
+    case MemRegion::HeapSpaceRegionKind:
+    case MemRegion::GlobalsSpaceRegionKind:
+    case MemRegion::UnknownSpaceRegionKind:
+      assert(0 && "Cannot perform pointer arithmetic on a MemSpace");
+      return UnknownVal();
+  }
+
+  SVal Idx = ER->getIndex();
+  nonloc::ConcreteInt* Base = dyn_cast<nonloc::ConcreteInt>(&Idx);
+
+  // For now, only support:
+  //  (a) concrete integer indices that can easily be resolved
+  //  (b) 0 + symbolic index
+  if (Base) {
+    if (nonloc::ConcreteInt *Offset = dyn_cast<nonloc::ConcreteInt>(&R)) {
+      // FIXME: Should use SValuator here.
+      SVal NewIdx =
+        Base->evalBinOp(ValMgr, Op,
+                cast<nonloc::ConcreteInt>(ValMgr.convertToArrayIndex(*Offset)));
+      const MemRegion* NewER =
+        MRMgr.getElementRegion(ER->getElementType(), NewIdx,
+                               ER->getSuperRegion(), getContext());
+      return ValMgr.makeLoc(NewER);
+    }
+    if (0 == Base->getValue()) {
+      const MemRegion* NewER =
+        MRMgr.getElementRegion(ER->getElementType(), R,
+                               ER->getSuperRegion(), getContext());
+      return ValMgr.makeLoc(NewER);
+    }
+  }
+
+  return UnknownVal();
+}
+
+//===----------------------------------------------------------------------===//
+// Loading values from regions.
+//===----------------------------------------------------------------------===//
+
+Optional<SVal> RegionStoreManager::getDirectBinding(RegionBindings B,
+                                                 const MemRegion *R) {
+  if (const SVal *V = Lookup(B, R, BindingKey::Direct))
+    return *V;
+
+  return Optional<SVal>();
+}
+
+Optional<SVal> RegionStoreManager::getDefaultBinding(RegionBindings B,
+                                                     const MemRegion *R) {
+  if (R->isBoundable())
+    if (const TypedRegion *TR = dyn_cast<TypedRegion>(R))
+      if (TR->getValueType(getContext())->isUnionType())
+        return UnknownVal();
+
+  if (const SVal *V = Lookup(B, R, BindingKey::Default))
+    return *V;
+
+  return Optional<SVal>();
+}
+
+Optional<SVal> RegionStoreManager::getBinding(RegionBindings B,
+                                              const MemRegion *R) {
+
+  if (const Optional<SVal> &V = getDirectBinding(B, R))
+    return V;
+
+  return getDefaultBinding(B, R);
+}
+
+static bool IsReinterpreted(QualType RTy, QualType UsedTy, ASTContext &Ctx) {
+  RTy = Ctx.getCanonicalType(RTy);
+  UsedTy = Ctx.getCanonicalType(UsedTy);
+
+  if (RTy == UsedTy)
+    return false;
+
+
+  // Recursively check the types.  We basically want to see if a pointer value
+  // is ever reinterpreted as a non-pointer, e.g. void** and intptr_t*
+  // represents a reinterpretation.
+  if (Loc::IsLocType(RTy) && Loc::IsLocType(UsedTy)) {
+    const PointerType *PRTy = RTy->getAs<PointerType>();
+    const PointerType *PUsedTy = UsedTy->getAs<PointerType>();
+
+    return PUsedTy && PRTy &&
+           IsReinterpreted(PRTy->getPointeeType(),
+                           PUsedTy->getPointeeType(), Ctx);
+  }
+
+  return true;
+}
+
+SVal RegionStoreManager::Retrieve(Store store, Loc L, QualType T) {
+  assert(!isa<UnknownVal>(L) && "location unknown");
+  assert(!isa<UndefinedVal>(L) && "location undefined");
+
+  // FIXME: Is this even possible?  Shouldn't this be treated as a null
+  //  dereference at a higher level?
+  if (isa<loc::ConcreteInt>(L))
+    return UndefinedVal();
+
+  const MemRegion *MR = cast<loc::MemRegionVal>(L).getRegion();
+
+  if (isa<AllocaRegion>(MR) || isa<SymbolicRegion>(MR))
+    MR = GetElementZeroRegion(MR, T);
+
+  if (isa<CodeTextRegion>(MR)) {
+    assert(0 && "Why load from a code text region?");
+    return UnknownVal();
+  }
+
+  // FIXME: Perhaps this method should just take a 'const MemRegion*' argument
+  //  instead of 'Loc', and have the other Loc cases handled at a higher level.
+  const TypedRegion *R = cast<TypedRegion>(MR);
+  QualType RTy = R->getValueType(getContext());
+
+  // FIXME: We should eventually handle funny addressing.  e.g.:
+  //
+  //   int x = ...;
+  //   int *p = &x;
+  //   char *q = (char*) p;
+  //   char c = *q;  // returns the first byte of 'x'.
+  //
+  // Such funny addressing will occur due to layering of regions.
+
+#if 0
+  ASTContext &Ctx = getContext();
+  if (!T.isNull() && IsReinterpreted(RTy, T, Ctx)) {
+    SVal ZeroIdx = ValMgr.makeZeroArrayIndex();
+    R = MRMgr.getElementRegion(T, ZeroIdx, R, Ctx);
+    RTy = T;
+    assert(Ctx.getCanonicalType(RTy) ==
+           Ctx.getCanonicalType(R->getValueType(Ctx)));
+  }
+#endif
+
+  if (RTy->isStructureOrClassType())
+    return RetrieveStruct(store, R);
+
+  // FIXME: Handle unions.
+  if (RTy->isUnionType())
+    return UnknownVal();
+
+  if (RTy->isArrayType())
+    return RetrieveArray(store, R);
+
+  // FIXME: handle Vector types.
+  if (RTy->isVectorType())
+    return UnknownVal();
+
+  if (const FieldRegion* FR = dyn_cast<FieldRegion>(R))
+    return CastRetrievedVal(RetrieveField(store, FR), FR, T, false);
+
+  if (const ElementRegion* ER = dyn_cast<ElementRegion>(R)) {
+    // FIXME: Here we actually perform an implicit conversion from the loaded
+    // value to the element type.  Eventually we want to compose these values
+    // more intelligently.  For example, an 'element' can encompass multiple
+    // bound regions (e.g., several bound bytes), or could be a subset of
+    // a larger value.
+    return CastRetrievedVal(RetrieveElement(store, ER), ER, T, false);
+  }
+
+  if (const ObjCIvarRegion *IVR = dyn_cast<ObjCIvarRegion>(R)) {
+    // FIXME: Here we actually perform an implicit conversion from the loaded
+    // value to the ivar type.  What we should model is stores to ivars
+    // that blow past the extent of the ivar.  If the address of the ivar is
+    // reinterpretted, it is possible we stored a different value that could
+    // fit within the ivar.  Either we need to cast these when storing them
+    // or reinterpret them lazily (as we do here).
+    return CastRetrievedVal(RetrieveObjCIvar(store, IVR), IVR, T, false);
+  }
+
+  if (const VarRegion *VR = dyn_cast<VarRegion>(R)) {
+    // FIXME: Here we actually perform an implicit conversion from the loaded
+    // value to the variable type.  What we should model is stores to variables
+    // that blow past the extent of the variable.  If the address of the
+    // variable is reinterpretted, it is possible we stored a different value
+    // that could fit within the variable.  Either we need to cast these when
+    // storing them or reinterpret them lazily (as we do here).
+    return CastRetrievedVal(RetrieveVar(store, VR), VR, T, false);
+  }
+
+  RegionBindings B = GetRegionBindings(store);
+  const SVal *V = Lookup(B, R, BindingKey::Direct);
+
+  // Check if the region has a binding.
+  if (V)
+    return *V;
+
+  // The location does not have a bound value.  This means that it has
+  // the value it had upon its creation and/or entry to the analyzed
+  // function/method.  These are either symbolic values or 'undefined'.
+  if (R->hasStackNonParametersStorage()) {
+    // All stack variables are considered to have undefined values
+    // upon creation.  All heap allocated blocks are considered to
+    // have undefined values as well unless they are explicitly bound
+    // to specific values.
+    return UndefinedVal();
+  }
+
+  // All other values are symbolic.
+  return ValMgr.getRegionValueSymbolVal(R);
+}
+
+std::pair<Store, const MemRegion *>
+RegionStoreManager::GetLazyBinding(RegionBindings B, const MemRegion *R) {
+  if (Optional<SVal> OV = getDirectBinding(B, R))
+    if (const nonloc::LazyCompoundVal *V =
+        dyn_cast<nonloc::LazyCompoundVal>(OV.getPointer()))
+      return std::make_pair(V->getStore(), V->getRegion());
+
+  if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
+    const std::pair<Store, const MemRegion *> &X =
+      GetLazyBinding(B, ER->getSuperRegion());
+
+    if (X.second)
+      return std::make_pair(X.first,
+                            MRMgr.getElementRegionWithSuper(ER, X.second));
+  }
+  else if (const FieldRegion *FR = dyn_cast<FieldRegion>(R)) {
+    const std::pair<Store, const MemRegion *> &X =
+      GetLazyBinding(B, FR->getSuperRegion());
+
+    if (X.second)
+      return std::make_pair(X.first,
+                            MRMgr.getFieldRegionWithSuper(FR, X.second));
+  }
+  // The NULL MemRegion indicates an non-existent lazy binding. A NULL Store is
+  // possible for a valid lazy binding.
+  return std::make_pair((Store) 0, (const MemRegion *) 0);
+}
+
+SVal RegionStoreManager::RetrieveElement(Store store,
+                                         const ElementRegion* R) {
+  // Check if the region has a binding.
+  RegionBindings B = GetRegionBindings(store);
+  if (const Optional<SVal> &V = getDirectBinding(B, R))
+    return *V;
+
+  const MemRegion* superR = R->getSuperRegion();
+
+  // Check if the region is an element region of a string literal.
+  if (const StringRegion *StrR=dyn_cast<StringRegion>(superR)) {
+    // FIXME: Handle loads from strings where the literal is treated as
+    // an integer, e.g., *((unsigned int*)"hello")
+    ASTContext &Ctx = getContext();
+    QualType T = Ctx.getAsArrayType(StrR->getValueType(Ctx))->getElementType();
+    if (T != Ctx.getCanonicalType(R->getElementType()))
+      return UnknownVal();
+
+    const StringLiteral *Str = StrR->getStringLiteral();
+    SVal Idx = R->getIndex();
+    if (nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&Idx)) {
+      int64_t i = CI->getValue().getSExtValue();
+      int64_t byteLength = Str->getByteLength();
+      if (i > byteLength) {
+        // Buffer overflow checking in GRExprEngine should handle this case,
+        // but we shouldn't rely on it to not overflow here if that checking
+        // is disabled.
+        return UnknownVal();
+      }
+      char c = (i == byteLength) ? '\0' : Str->getStrData()[i];
+      return ValMgr.makeIntVal(c, T);
+    }
+  }
+
+  // Check if the immediate super region has a direct binding.
+  if (const Optional<SVal> &V = getDirectBinding(B, superR)) {
+    if (SymbolRef parentSym = V->getAsSymbol())
+      return ValMgr.getDerivedRegionValueSymbolVal(parentSym, R);
+
+    if (V->isUnknownOrUndef())
+      return *V;
+
+    // Handle LazyCompoundVals for the immediate super region.  Other cases
+    // are handled in 'RetrieveFieldOrElementCommon'.
+    if (const nonloc::LazyCompoundVal *LCV =
+        dyn_cast<nonloc::LazyCompoundVal>(V)) {
+
+      R = MRMgr.getElementRegionWithSuper(R, LCV->getRegion());
+      return RetrieveElement(LCV->getStore(), R);
+    }
+
+    // Other cases: give up.
+    return UnknownVal();
+  }
+
+  return RetrieveFieldOrElementCommon(store, R, R->getElementType(), superR);
+}
+
+SVal RegionStoreManager::RetrieveField(Store store,
+                                       const FieldRegion* R) {
+
+  // Check if the region has a binding.
+  RegionBindings B = GetRegionBindings(store);
+  if (const Optional<SVal> &V = getDirectBinding(B, R))
+    return *V;
+
+  QualType Ty = R->getValueType(getContext());
+  return RetrieveFieldOrElementCommon(store, R, Ty, R->getSuperRegion());
+}
+
+SVal RegionStoreManager::RetrieveFieldOrElementCommon(Store store,
+                                                      const TypedRegion *R,
+                                                      QualType Ty,
+                                                      const MemRegion *superR) {
+
+  // At this point we have already checked in either RetrieveElement or
+  // RetrieveField if 'R' has a direct binding.
+
+  RegionBindings B = GetRegionBindings(store);
+
+  while (superR) {
+    if (const Optional<SVal> &D = getDefaultBinding(B, superR)) {
+      if (SymbolRef parentSym = D->getAsSymbol())
+        return ValMgr.getDerivedRegionValueSymbolVal(parentSym, R);
+
+      if (D->isZeroConstant())
+        return ValMgr.makeZeroVal(Ty);
+
+      if (D->isUnknown())
+        return *D;
+
+      assert(0 && "Unknown default value");
+    }
+
+    // If our super region is a field or element itself, walk up the region
+    // hierarchy to see if there is a default value installed in an ancestor.
+    if (isa<FieldRegion>(superR) || isa<ElementRegion>(superR)) {
+      superR = cast<SubRegion>(superR)->getSuperRegion();
+      continue;
+    }
+
+    break;
+  }
+
+  // Lazy binding?
+  Store lazyBindingStore = NULL;
+  const MemRegion *lazyBindingRegion = NULL;
+  llvm::tie(lazyBindingStore, lazyBindingRegion) = GetLazyBinding(B, R);
+
+  if (lazyBindingRegion) {
+    if (const ElementRegion *ER = dyn_cast<ElementRegion>(lazyBindingRegion))
+      return RetrieveElement(lazyBindingStore, ER);
+    return RetrieveField(lazyBindingStore,
+                         cast<FieldRegion>(lazyBindingRegion));
+  }
+
+  if (R->hasStackNonParametersStorage()) {
+    if (isa<ElementRegion>(R)) {
+      // Currently we don't reason specially about Clang-style vectors.  Check
+      // if superR is a vector and if so return Unknown.
+      if (const TypedRegion *typedSuperR = dyn_cast<TypedRegion>(superR)) {
+        if (typedSuperR->getValueType(getContext())->isVectorType())
+          return UnknownVal();
+      }
+    }
+
+    return UndefinedVal();
+  }
+
+  // All other values are symbolic.
+  return ValMgr.getRegionValueSymbolVal(R);
+}
+
+SVal RegionStoreManager::RetrieveObjCIvar(Store store, const ObjCIvarRegion* R){
+
+    // Check if the region has a binding.
+  RegionBindings B = GetRegionBindings(store);
+
+  if (const Optional<SVal> &V = getDirectBinding(B, R))
+    return *V;
+
+  const MemRegion *superR = R->getSuperRegion();
+
+  // Check if the super region has a default binding.
+  if (const Optional<SVal> &V = getDefaultBinding(B, superR)) {
+    if (SymbolRef parentSym = V->getAsSymbol())
+      return ValMgr.getDerivedRegionValueSymbolVal(parentSym, R);
+
+    // Other cases: give up.
+    return UnknownVal();
+  }
+
+  return RetrieveLazySymbol(R);
+}
+
+SVal RegionStoreManager::RetrieveVar(Store store, const VarRegion *R) {
+
+  // Check if the region has a binding.
+  RegionBindings B = GetRegionBindings(store);
+
+  if (const Optional<SVal> &V = getDirectBinding(B, R))
+    return *V;
+
+  // Lazily derive a value for the VarRegion.
+  const VarDecl *VD = R->getDecl();
+  QualType T = VD->getType();
+  const MemSpaceRegion *MS = R->getMemorySpace();
+
+  if (isa<UnknownSpaceRegion>(MS) ||
+      isa<StackArgumentsSpaceRegion>(MS))
+    return ValMgr.getRegionValueSymbolVal(R);
+
+  if (isa<GlobalsSpaceRegion>(MS)) {
+    if (VD->isFileVarDecl()) {
+      // Is 'VD' declared constant?  If so, retrieve the constant value.
+      QualType CT = Ctx.getCanonicalType(T);
+      if (CT.isConstQualified()) {
+        const Expr *Init = VD->getInit();
+        // Do the null check first, as we want to call 'IgnoreParenCasts'.
+        if (Init)
+          if (const IntegerLiteral *IL =
+              dyn_cast<IntegerLiteral>(Init->IgnoreParenCasts())) {
+            const nonloc::ConcreteInt &V = ValMgr.makeIntVal(IL);
+            return ValMgr.getSValuator().EvalCast(V, Init->getType(),
+                                                  IL->getType());
+          }
+      }
+
+      return ValMgr.getRegionValueSymbolVal(R);
+    }
+
+    if (T->isIntegerType())
+      return ValMgr.makeIntVal(0, T);
+    if (T->isPointerType())
+      return ValMgr.makeNull();
+
+    return UnknownVal();
+  }
+
+  return UndefinedVal();
+}
+
+SVal RegionStoreManager::RetrieveLazySymbol(const TypedRegion *R) {
+
+  QualType valTy = R->getValueType(getContext());
+
+  // All other values are symbolic.
+  return ValMgr.getRegionValueSymbolVal(R);
+}
+
+SVal RegionStoreManager::RetrieveStruct(Store store, const TypedRegion* R) {
+  QualType T = R->getValueType(getContext());
+  assert(T->isStructureOrClassType());
+  return ValMgr.makeLazyCompoundVal(store, R);
+}
+
+SVal RegionStoreManager::RetrieveArray(Store store, const TypedRegion * R) {
+  assert(isa<ConstantArrayType>(R->getValueType(getContext())));
+  return ValMgr.makeLazyCompoundVal(store, R);
+}
+
+//===----------------------------------------------------------------------===//
+// Binding values to regions.
+//===----------------------------------------------------------------------===//
+
+Store RegionStoreManager::Remove(Store store, Loc L) {
+  if (isa<loc::MemRegionVal>(L))
+    if (const MemRegion* R = cast<loc::MemRegionVal>(L).getRegion())
+      return Remove(GetRegionBindings(store), R).getRoot();
+
+  return store;
+}
+
+Store RegionStoreManager::Bind(Store store, Loc L, SVal V) {
+  if (isa<loc::ConcreteInt>(L))
+    return store;
+
+  // If we get here, the location should be a region.
+  const MemRegion *R = cast<loc::MemRegionVal>(L).getRegion();
+
+  // Check if the region is a struct region.
+  if (const TypedRegion* TR = dyn_cast<TypedRegion>(R))
+    if (TR->getValueType(getContext())->isStructureOrClassType())
+      return BindStruct(store, TR, V);
+
+  // Special case: the current region represents a cast and it and the super
+  // region both have pointer types or intptr_t types.  If so, perform the
+  // bind to the super region.
+  // This is needed to support OSAtomicCompareAndSwap and friends or other
+  // loads that treat integers as pointers and vis versa.
+  if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
+    if (ER->getIndex().isZeroConstant()) {
+      if (const TypedRegion *superR =
+            dyn_cast<TypedRegion>(ER->getSuperRegion())) {
+        ASTContext &Ctx = getContext();
+        QualType superTy = superR->getValueType(Ctx);
+        QualType erTy = ER->getValueType(Ctx);
+
+        if (IsAnyPointerOrIntptr(superTy, Ctx) &&
+            IsAnyPointerOrIntptr(erTy, Ctx)) {
+          V = ValMgr.getSValuator().EvalCast(V, superTy, erTy);
+          return Bind(store, loc::MemRegionVal(superR), V);
+        }
+        // For now, just invalidate the fields of the struct/union/class.
+        // FIXME: Precisely handle the fields of the record.
+        if (superTy->isRecordType())
+          return InvalidateRegion(store, superR, NULL, 0, NULL);
+      }
+    }
+  }
+  else if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R)) {
+    // Binding directly to a symbolic region should be treated as binding
+    // to element 0.
+    QualType T = SR->getSymbol()->getType(getContext());
+
+    // FIXME: Is this the right way to handle symbols that are references?
+    if (const PointerType *PT = T->getAs<PointerType>())
+      T = PT->getPointeeType();
+    else
+      T = T->getAs<ReferenceType>()->getPointeeType();
+
+    R = GetElementZeroRegion(SR, T);
+  }
+
+  // Perform the binding.
+  RegionBindings B = GetRegionBindings(store);
+  return Add(B, R, BindingKey::Direct, V).getRoot();
+}
+
+Store RegionStoreManager::BindDecl(Store store, const VarRegion *VR,
+                                   SVal InitVal) {
+
+  QualType T = VR->getDecl()->getType();
+
+  if (T->isArrayType())
+    return BindArray(store, VR, InitVal);
+  if (T->isStructureOrClassType())
+    return BindStruct(store, VR, InitVal);
+
+  return Bind(store, ValMgr.makeLoc(VR), InitVal);
+}
+
+// FIXME: this method should be merged into Bind().
+Store RegionStoreManager::BindCompoundLiteral(Store store,
+                                              const CompoundLiteralExpr *CL,
+                                              const LocationContext *LC,
+                                              SVal V) {
+  return Bind(store, loc::MemRegionVal(MRMgr.getCompoundLiteralRegion(CL, LC)),
+              V);
+}
+
+Store RegionStoreManager::setImplicitDefaultValue(Store store,
+                                                  const MemRegion *R,
+                                                  QualType T) {
+  RegionBindings B = GetRegionBindings(store);
+  SVal V;
+
+  if (Loc::IsLocType(T))
+    V = ValMgr.makeNull();
+  else if (T->isIntegerType())
+    V = ValMgr.makeZeroVal(T);
+  else if (T->isStructureOrClassType() || T->isArrayType()) {
+    // Set the default value to a zero constant when it is a structure
+    // or array.  The type doesn't really matter.
+    V = ValMgr.makeZeroVal(ValMgr.getContext().IntTy);
+  }
+  else {
+    return store;
+  }
+
+  return Add(B, R, BindingKey::Default, V).getRoot();
+}
+
+Store RegionStoreManager::BindArray(Store store, const TypedRegion* R,
+                                    SVal Init) {
+
+  ASTContext &Ctx = getContext();
+  const ArrayType *AT =
+    cast<ArrayType>(Ctx.getCanonicalType(R->getValueType(Ctx)));
+  QualType ElementTy = AT->getElementType();
+  Optional<uint64_t> Size;
+
+  if (const ConstantArrayType* CAT = dyn_cast<ConstantArrayType>(AT))
+    Size = CAT->getSize().getZExtValue();
+
+  // Check if the init expr is a StringLiteral.
+  if (isa<loc::MemRegionVal>(Init)) {
+    const MemRegion* InitR = cast<loc::MemRegionVal>(Init).getRegion();
+    const StringLiteral* S = cast<StringRegion>(InitR)->getStringLiteral();
+    const char* str = S->getStrData();
+    unsigned len = S->getByteLength();
+    unsigned j = 0;
+
+    // Copy bytes from the string literal into the target array. Trailing bytes
+    // in the array that are not covered by the string literal are initialized
+    // to zero.
+
+    // We assume that string constants are bound to
+    // constant arrays.
+    uint64_t size = Size.getValue();
+
+    for (uint64_t i = 0; i < size; ++i, ++j) {
+      if (j >= len)
+        break;
+
+      SVal Idx = ValMgr.makeArrayIndex(i);
+      const ElementRegion* ER = MRMgr.getElementRegion(ElementTy, Idx, R,
+                                                       getContext());
+
+      SVal V = ValMgr.makeIntVal(str[j], sizeof(char)*8, true);
+      store = Bind(store, loc::MemRegionVal(ER), V);
+    }
+
+    return store;
+  }
+
+  // Handle lazy compound values.
+  if (nonloc::LazyCompoundVal *LCV = dyn_cast<nonloc::LazyCompoundVal>(&Init))
+    return CopyLazyBindings(*LCV, store, R);
+
+  // Remaining case: explicit compound values.
+
+  if (Init.isUnknown())
+    return setImplicitDefaultValue(store, R, ElementTy);
+
+  nonloc::CompoundVal& CV = cast<nonloc::CompoundVal>(Init);
+  nonloc::CompoundVal::iterator VI = CV.begin(), VE = CV.end();
+  uint64_t i = 0;
+
+  for (; Size.hasValue() ? i < Size.getValue() : true ; ++i, ++VI) {
+    // The init list might be shorter than the array length.
+    if (VI == VE)
+      break;
+
+    SVal Idx = ValMgr.makeArrayIndex(i);
+    const ElementRegion *ER = MRMgr.getElementRegion(ElementTy, Idx, R, getContext());
+
+    if (ElementTy->isStructureOrClassType())
+      store = BindStruct(store, ER, *VI);
+    else
+      store = Bind(store, ValMgr.makeLoc(ER), *VI);
+  }
+
+  // If the init list is shorter than the array length, set the
+  // array default value.
+  if (Size.hasValue() && i < Size.getValue())
+    store = setImplicitDefaultValue(store, R, ElementTy);
+
+  return store;
+}
+
+Store RegionStoreManager::BindStruct(Store store, const TypedRegion* R,
+                                     SVal V) {
+
+  if (!Features.supportsFields())
+    return store;
+
+  QualType T = R->getValueType(getContext());
+  assert(T->isStructureOrClassType());
+
+  const RecordType* RT = T->getAs<RecordType>();
+  RecordDecl* RD = RT->getDecl();
+
+  if (!RD->isDefinition())
+    return store;
+
+  // Handle lazy compound values.
+  if (const nonloc::LazyCompoundVal *LCV=dyn_cast<nonloc::LazyCompoundVal>(&V))
+    return CopyLazyBindings(*LCV, store, R);
+
+  // We may get non-CompoundVal accidentally due to imprecise cast logic.
+  // Ignore them and kill the field values.
+  if (V.isUnknown() || !isa<nonloc::CompoundVal>(V))
+    return KillStruct(store, R);
+
+  nonloc::CompoundVal& CV = cast<nonloc::CompoundVal>(V);
+  nonloc::CompoundVal::iterator VI = CV.begin(), VE = CV.end();
+
+  RecordDecl::field_iterator FI, FE;
+
+  for (FI = RD->field_begin(), FE = RD->field_end(); FI != FE; ++FI, ++VI) {
+
+    if (VI == VE)
+      break;
+
+    QualType FTy = (*FI)->getType();
+    const FieldRegion* FR = MRMgr.getFieldRegion(*FI, R);
+
+    if (FTy->isArrayType())
+      store = BindArray(store, FR, *VI);
+    else if (FTy->isStructureOrClassType())
+      store = BindStruct(store, FR, *VI);
+    else
+      store = Bind(store, ValMgr.makeLoc(FR), *VI);
+  }
+
+  // There may be fewer values in the initialize list than the fields of struct.
+  if (FI != FE) {
+    RegionBindings B = GetRegionBindings(store);
+    B = Add(B, R, BindingKey::Default, ValMgr.makeIntVal(0, false));
+    store = B.getRoot();
+  }
+
+  return store;
+}
+
+Store RegionStoreManager::KillStruct(Store store, const TypedRegion* R) {
+  RegionBindings B = GetRegionBindings(store);
+  llvm::OwningPtr<RegionStoreSubRegionMap>
+    SubRegions(getRegionStoreSubRegionMap(store));
+  RemoveSubRegionBindings(B, R, *SubRegions);
+
+  // Set the default value of the struct region to "unknown".
+  return Add(B, R, BindingKey::Default, UnknownVal()).getRoot();
+}
+
+Store RegionStoreManager::CopyLazyBindings(nonloc::LazyCompoundVal V,
+                                           Store store, const TypedRegion *R) {
+
+  // Nuke the old bindings stemming from R.
+  RegionBindings B = GetRegionBindings(store);
+
+  llvm::OwningPtr<RegionStoreSubRegionMap>
+    SubRegions(getRegionStoreSubRegionMap(store));
+
+  // B and DVM are updated after the call to RemoveSubRegionBindings.
+  RemoveSubRegionBindings(B, R, *SubRegions.get());
+
+  // Now copy the bindings.  This amounts to just binding 'V' to 'R'.  This
+  // results in a zero-copy algorithm.
+  return Add(B, R, BindingKey::Direct, V).getRoot();
+}
+
+//===----------------------------------------------------------------------===//
+// "Raw" retrievals and bindings.
+//===----------------------------------------------------------------------===//
+
+BindingKey BindingKey::Make(const MemRegion *R, Kind k) {
+  if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
+    const RegionRawOffset &O = ER->getAsRawOffset();
+
+    if (O.getRegion())
+      return BindingKey(O.getRegion(), O.getByteOffset(), k);
+
+    // FIXME: There are some ElementRegions for which we cannot compute
+    // raw offsets yet, including regions with symbolic offsets.
+  }
+
+  return BindingKey(R, 0, k);
+}
+
+RegionBindings RegionStoreManager::Add(RegionBindings B, BindingKey K, SVal V) {
+  return RBFactory.Add(B, K, V);
+}
+
+RegionBindings RegionStoreManager::Add(RegionBindings B, const MemRegion *R,
+                                       BindingKey::Kind k, SVal V) {
+  return Add(B, BindingKey::Make(R, k), V);
+}
+
+const SVal *RegionStoreManager::Lookup(RegionBindings B, BindingKey K) {
+  return B.lookup(K);
+}
+
+const SVal *RegionStoreManager::Lookup(RegionBindings B,
+                                       const MemRegion *R,
+                                       BindingKey::Kind k) {
+  return Lookup(B, BindingKey::Make(R, k));
+}
+
+RegionBindings RegionStoreManager::Remove(RegionBindings B, BindingKey K) {
+  return RBFactory.Remove(B, K);
+}
+
+RegionBindings RegionStoreManager::Remove(RegionBindings B, const MemRegion *R,
+                                          BindingKey::Kind k){
+  return Remove(B, BindingKey::Make(R, k));
+}
+
+Store RegionStoreManager::Remove(Store store, BindingKey K) {
+  RegionBindings B = GetRegionBindings(store);
+  return Remove(B, K).getRoot();
+}
+
+//===----------------------------------------------------------------------===//
+// State pruning.
+//===----------------------------------------------------------------------===//
+
+namespace {
+class RemoveDeadBindingsWorker :
+  public ClusterAnalysis<RemoveDeadBindingsWorker> {
+  llvm::SmallVector<const SymbolicRegion*, 12> Postponed;
+  SymbolReaper &SymReaper;
+  Stmt *Loc;
+  const StackFrameContext *CurrentLCtx;
+  
+public:
+  RemoveDeadBindingsWorker(RegionStoreManager &rm, GRStateManager &stateMgr,
+                           RegionBindings b, SymbolReaper &symReaper,
+                           Stmt *loc, const StackFrameContext *LCtx)
+    : ClusterAnalysis<RemoveDeadBindingsWorker>(rm, stateMgr, b),
+      SymReaper(symReaper), Loc(loc), CurrentLCtx(LCtx) {}
+
+  // Called by ClusterAnalysis.
+  void VisitAddedToCluster(const MemRegion *baseR, RegionCluster &C);
+  void VisitCluster(const MemRegion *baseR, BindingKey *I, BindingKey *E);
+
+  void VisitBindingKey(BindingKey K);
+  bool UpdatePostponed();
+  void VisitBinding(SVal V);
+};
+}
+
+void RemoveDeadBindingsWorker::VisitAddedToCluster(const MemRegion *baseR,
+                                                   RegionCluster &C) {
+
+  if (const VarRegion *VR = dyn_cast<VarRegion>(baseR)) {
+    if (SymReaper.isLive(Loc, VR))
+      AddToWorkList(baseR, C);
+
+    return;
+  }
+
+  if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(baseR)) {
+    if (SymReaper.isLive(SR->getSymbol()))
+      AddToWorkList(SR, C);
+    else
+      Postponed.push_back(SR);
+
+    return;
+  }
+
+  // CXXThisRegion in the current or parent location context is live.
+  if (const CXXThisRegion *TR = dyn_cast<CXXThisRegion>(baseR)) {
+    const StackArgumentsSpaceRegion *StackReg = 
+      cast<StackArgumentsSpaceRegion>(TR->getSuperRegion());
+    const StackFrameContext *RegCtx = StackReg->getStackFrame();
+    if (RegCtx == CurrentLCtx || RegCtx->isParentOf(CurrentLCtx))
+      AddToWorkList(TR, C);
+  }
+}
+
+void RemoveDeadBindingsWorker::VisitCluster(const MemRegion *baseR,
+                                            BindingKey *I, BindingKey *E) {
+  for ( ; I != E; ++I)
+    VisitBindingKey(*I);
+}
+
+void RemoveDeadBindingsWorker::VisitBinding(SVal V) {
+  // Is it a LazyCompoundVal?  All referenced regions are live as well.
+  if (const nonloc::LazyCompoundVal *LCS =
+      dyn_cast<nonloc::LazyCompoundVal>(&V)) {
+
+    const MemRegion *LazyR = LCS->getRegion();
+    RegionBindings B = RegionStoreManager::GetRegionBindings(LCS->getStore());
+    for (RegionBindings::iterator RI = B.begin(), RE = B.end(); RI != RE; ++RI){
+      const MemRegion *baseR = RI.getKey().getRegion();
+      if (cast<SubRegion>(baseR)->isSubRegionOf(LazyR))
+        VisitBinding(RI.getData());
+    }
+    return;
+  }
+
+  // If V is a region, then add it to the worklist.
+  if (const MemRegion *R = V.getAsRegion())
+    AddToWorkList(R);
+
+    // Update the set of live symbols.
+  for (SVal::symbol_iterator SI=V.symbol_begin(), SE=V.symbol_end();
+       SI!=SE;++SI)
+    SymReaper.markLive(*SI);
+}
+
+void RemoveDeadBindingsWorker::VisitBindingKey(BindingKey K) {
+  const MemRegion *R = K.getRegion();
+
+  // Mark this region "live" by adding it to the worklist.  This will cause
+  // use to visit all regions in the cluster (if we haven't visited them
+  // already).
+  if (AddToWorkList(R)) {
+    // Mark the symbol for any live SymbolicRegion as "live".  This means we
+    // should continue to track that symbol.
+    if (const SymbolicRegion *SymR = dyn_cast<SymbolicRegion>(R))
+      SymReaper.markLive(SymR->getSymbol());
+
+    // For BlockDataRegions, enqueue the VarRegions for variables marked
+    // with __block (passed-by-reference).
+    // via BlockDeclRefExprs.
+    if (const BlockDataRegion *BD = dyn_cast<BlockDataRegion>(R)) {
+      for (BlockDataRegion::referenced_vars_iterator
+           RI = BD->referenced_vars_begin(), RE = BD->referenced_vars_end();
+           RI != RE; ++RI) {
+        if ((*RI)->getDecl()->getAttr<BlocksAttr>())
+          AddToWorkList(*RI);
+      }
+
+      // No possible data bindings on a BlockDataRegion.
+      return;
+    }
+  }
+
+  // Visit the data binding for K.
+  if (const SVal *V = RM.Lookup(B, K))
+    VisitBinding(*V);
+}
+
+bool RemoveDeadBindingsWorker::UpdatePostponed() {
+  // See if any postponed SymbolicRegions are actually live now, after
+  // having done a scan.
+  bool changed = false;
+
+  for (llvm::SmallVectorImpl<const SymbolicRegion*>::iterator
+        I = Postponed.begin(), E = Postponed.end() ; I != E ; ++I) {
+    if (const SymbolicRegion *SR = cast_or_null<SymbolicRegion>(*I)) {
+      if (SymReaper.isLive(SR->getSymbol())) {
+        changed |= AddToWorkList(SR);
+        *I = NULL;
+      }
+    }
+  }
+
+  return changed;
+}
+
+Store RegionStoreManager::RemoveDeadBindings(Store store, Stmt* Loc,
+                                             const StackFrameContext *LCtx,
+                                             SymbolReaper& SymReaper,
+                           llvm::SmallVectorImpl<const MemRegion*>& RegionRoots)
+{
+  RegionBindings B = GetRegionBindings(store);
+  RemoveDeadBindingsWorker W(*this, StateMgr, B, SymReaper, Loc, LCtx);
+  W.GenerateClusters();
+
+  // Enqueue the region roots onto the worklist.
+  for (llvm::SmallVectorImpl<const MemRegion*>::iterator I=RegionRoots.begin(),
+       E=RegionRoots.end(); I!=E; ++I)
+    W.AddToWorkList(*I);
+
+  do W.RunWorkList(); while (W.UpdatePostponed());
+
+  // We have now scanned the store, marking reachable regions and symbols
+  // as live.  We now remove all the regions that are dead from the store
+  // as well as update DSymbols with the set symbols that are now dead.
+  for (RegionBindings::iterator I = B.begin(), E = B.end(); I != E; ++I) {
+    const BindingKey &K = I.getKey();
+
+    // If the cluster has been visited, we know the region has been marked.
+    if (W.isVisited(K.getRegion()))
+      continue;
+
+    // Remove the dead entry.
+    B = Remove(B, K);
+
+    // Mark all non-live symbols that this binding references as dead.
+    if (const SymbolicRegion* SymR = dyn_cast<SymbolicRegion>(K.getRegion()))
+      SymReaper.maybeDead(SymR->getSymbol());
+
+    SVal X = I.getData();
+    SVal::symbol_iterator SI = X.symbol_begin(), SE = X.symbol_end();
+    for (; SI != SE; ++SI)
+      SymReaper.maybeDead(*SI);
+  }
+
+  return B.getRoot();
+}
+
+
+GRState const *RegionStoreManager::EnterStackFrame(GRState const *state,
+                                               StackFrameContext const *frame) {
+  FunctionDecl const *FD = cast<FunctionDecl>(frame->getDecl());
+  FunctionDecl::param_const_iterator PI = FD->param_begin();
+  Store store = state->getStore();
+
+  if (CallExpr const *CE = dyn_cast<CallExpr>(frame->getCallSite())) {
+    CallExpr::const_arg_iterator AI = CE->arg_begin(), AE = CE->arg_end();
+
+    // Copy the arg expression value to the arg variables.
+    for (; AI != AE; ++AI, ++PI) {
+      SVal ArgVal = state->getSVal(*AI);
+      store = Bind(store, ValMgr.makeLoc(MRMgr.getVarRegion(*PI,frame)),ArgVal);
+    }
+  } else if (const CXXConstructExpr *CE = 
+               dyn_cast<CXXConstructExpr>(frame->getCallSite())) {
+    CXXConstructExpr::const_arg_iterator AI = CE->arg_begin(), 
+      AE = CE->arg_end();
+
+    // Copy the arg expression value to the arg variables.
+    for (; AI != AE; ++AI, ++PI) {
+      SVal ArgVal = state->getSVal(*AI);
+      store = Bind(store, ValMgr.makeLoc(MRMgr.getVarRegion(*PI,frame)),ArgVal);
+    }
+  } else
+    assert(0 && "Unhandled call expression.");
+
+  return state->makeWithStore(store);
+}
+
+//===----------------------------------------------------------------------===//
+// Utility methods.
+//===----------------------------------------------------------------------===//
+
+void RegionStoreManager::print(Store store, llvm::raw_ostream& OS,
+                               const char* nl, const char *sep) {
+  RegionBindings B = GetRegionBindings(store);
+  OS << "Store (direct and default bindings):" << nl;
+
+  for (RegionBindings::iterator I = B.begin(), E = B.end(); I != E; ++I)
+    OS << ' ' << I.getKey() << " : " << I.getData() << nl;
+}
diff --git a/lib/Checker/ReturnPointerRangeChecker.cpp b/lib/Checker/ReturnPointerRangeChecker.cpp
new file mode 100644
index 0000000..14edf56
--- /dev/null
+++ b/lib/Checker/ReturnPointerRangeChecker.cpp
@@ -0,0 +1,97 @@
+//== ReturnPointerRangeChecker.cpp ------------------------------*- C++ -*--==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines ReturnPointerRangeChecker, which is a path-sensitive check
+// which looks for an out-of-bound pointer being returned to callers.
+//
+//===----------------------------------------------------------------------===//
+
+#include "GRExprEngineInternalChecks.h"
+#include "clang/Checker/BugReporter/BugType.h"
+#include "clang/Checker/PathSensitive/CheckerVisitor.h"
+#include "clang/Checker/PathSensitive/GRExprEngine.h"
+
+using namespace clang;
+
+namespace {
+class ReturnPointerRangeChecker : 
+    public CheckerVisitor<ReturnPointerRangeChecker> {      
+  BuiltinBug *BT;
+public:
+    ReturnPointerRangeChecker() : BT(0) {}
+    static void *getTag();
+    void PreVisitReturnStmt(CheckerContext &C, const ReturnStmt *RS);
+};
+}
+
+void clang::RegisterReturnPointerRangeChecker(GRExprEngine &Eng) {
+  Eng.registerCheck(new ReturnPointerRangeChecker());
+}
+
+void *ReturnPointerRangeChecker::getTag() {
+  static int x = 0; return &x;
+}
+
+void ReturnPointerRangeChecker::PreVisitReturnStmt(CheckerContext &C,
+                                                   const ReturnStmt *RS) {
+  const GRState *state = C.getState();
+
+  const Expr *RetE = RS->getRetValue();
+  if (!RetE)
+    return;
+ 
+  SVal V = state->getSVal(RetE);
+  const MemRegion *R = V.getAsRegion();
+  if (!R)
+    return;
+
+  R = R->StripCasts();
+  if (!R)
+    return;
+
+  const ElementRegion *ER = dyn_cast_or_null<ElementRegion>(R);
+  if (!ER)
+    return;
+
+  DefinedOrUnknownSVal &Idx = cast<DefinedOrUnknownSVal>(ER->getIndex());
+
+  // FIXME: All of this out-of-bounds checking should eventually be refactored
+  // into a common place.
+
+  DefinedOrUnknownSVal NumElements
+    = C.getStoreManager().getSizeInElements(state, ER->getSuperRegion(),
+                                           ER->getValueType(C.getASTContext()));
+
+  const GRState *StInBound = state->AssumeInBound(Idx, NumElements, true);
+  const GRState *StOutBound = state->AssumeInBound(Idx, NumElements, false);
+  if (StOutBound && !StInBound) {
+    ExplodedNode *N = C.GenerateSink(StOutBound);
+
+    if (!N)
+      return;
+  
+    // FIXME: This bug correspond to CWE-466.  Eventually we should have bug
+    // types explicitly reference such exploit categories (when applicable).
+    if (!BT)
+      BT = new BuiltinBug("Return of pointer value outside of expected range",
+           "Returned pointer value points outside the original object "
+           "(potential buffer overflow)");
+
+    // FIXME: It would be nice to eventually make this diagnostic more clear,
+    // e.g., by referencing the original declaration or by saying *why* this
+    // reference is outside the range.
+
+    // Generate a report for this bug.
+    RangedBugReport *report = 
+      new RangedBugReport(*BT, BT->getDescription(), N);
+
+    report->addRange(RetE->getSourceRange());
+    C.EmitReport(report);
+  }
+}
diff --git a/lib/Checker/ReturnStackAddressChecker.cpp b/lib/Checker/ReturnStackAddressChecker.cpp
new file mode 100644
index 0000000..35b1cde
--- /dev/null
+++ b/lib/Checker/ReturnStackAddressChecker.cpp
@@ -0,0 +1,125 @@
+//== ReturnStackAddressChecker.cpp ------------------------------*- C++ -*--==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines ReturnStackAddressChecker, which is a path-sensitive
+// check which looks for the addresses of stack variables being returned to
+// callers.
+//
+//===----------------------------------------------------------------------===//
+
+#include "GRExprEngineInternalChecks.h"
+#include "clang/Checker/BugReporter/BugType.h"
+#include "clang/Checker/PathSensitive/GRExprEngine.h"
+#include "clang/Checker/PathSensitive/CheckerVisitor.h"
+#include "clang/Basic/SourceManager.h"
+#include "llvm/ADT/SmallString.h"
+
+using namespace clang;
+
+namespace {
+class ReturnStackAddressChecker : 
+    public CheckerVisitor<ReturnStackAddressChecker> {      
+  BuiltinBug *BT;
+public:
+  ReturnStackAddressChecker() : BT(0) {}
+  static void *getTag();
+  void PreVisitReturnStmt(CheckerContext &C, const ReturnStmt *RS);
+private:
+  void EmitStackError(CheckerContext &C, const MemRegion *R, const Expr *RetE);
+};
+}
+
+void clang::RegisterReturnStackAddressChecker(GRExprEngine &Eng) {
+  Eng.registerCheck(new ReturnStackAddressChecker());
+}
+
+void *ReturnStackAddressChecker::getTag() {
+  static int x = 0; return &x;
+}
+
+void ReturnStackAddressChecker::EmitStackError(CheckerContext &C,
+                                               const MemRegion *R,
+                                               const Expr *RetE) {
+	ExplodedNode *N = C.GenerateSink();
+
+	if (!N)
+		return;
+
+	if (!BT)
+		BT = new BuiltinBug("Return of address to stack-allocated memory");
+
+	// Generate a report for this bug.
+	llvm::SmallString<512> buf;
+	llvm::raw_svector_ostream os(buf);
+	SourceRange range;
+
+	// Get the base region, stripping away fields and elements.
+	R = R->getBaseRegion();
+
+	// Check if the region is a compound literal.
+	if (const CompoundLiteralRegion* CR = dyn_cast<CompoundLiteralRegion>(R)) {    
+		const CompoundLiteralExpr* CL = CR->getLiteralExpr();
+		os << "Address of stack memory associated with a compound literal "
+          "declared on line "
+       << C.getSourceManager().getInstantiationLineNumber(CL->getLocStart())
+       << " returned to caller";    
+		range = CL->getSourceRange();
+	}
+	else if (const AllocaRegion* AR = dyn_cast<AllocaRegion>(R)) {
+		const Expr* ARE = AR->getExpr();
+		SourceLocation L = ARE->getLocStart();
+		range = ARE->getSourceRange();    
+		os << "Address of stack memory allocated by call to alloca() on line "
+       << C.getSourceManager().getInstantiationLineNumber(L)
+       << " returned to caller";
+	}
+	else if (const BlockDataRegion *BR = dyn_cast<BlockDataRegion>(R)) {
+		const BlockDecl *BD = BR->getCodeRegion()->getDecl();
+		SourceLocation L = BD->getLocStart();
+		range = BD->getSourceRange();
+		os << "Address of stack-allocated block declared on line "
+       << C.getSourceManager().getInstantiationLineNumber(L)
+       << " returned to caller";
+	}
+	else if (const VarRegion *VR = dyn_cast<VarRegion>(R)) {
+		os << "Address of stack memory associated with local variable '"
+       << VR->getString() << "' returned";
+		range = VR->getDecl()->getSourceRange();
+	}
+	else {
+		assert(false && "Invalid region in ReturnStackAddressChecker.");
+		return;
+	}
+
+	RangedBugReport *report = new RangedBugReport(*BT, os.str(), N);
+	report->addRange(RetE->getSourceRange());
+	if (range.isValid())
+		report->addRange(range);
+
+	C.EmitReport(report);
+}	
+
+void ReturnStackAddressChecker::PreVisitReturnStmt(CheckerContext &C,
+                                                   const ReturnStmt *RS) {
+  
+  const Expr *RetE = RS->getRetValue();
+  if (!RetE)
+    return;
+ 
+  SVal V = C.getState()->getSVal(RetE);
+  const MemRegion *R = V.getAsRegion();
+
+  if (!R || !R->hasStackStorage())
+    return;  
+  
+  if (R->hasStackStorage()) {
+    EmitStackError(C, R, RetE);
+    return;
+  }
+}
diff --git a/lib/Checker/ReturnUndefChecker.cpp b/lib/Checker/ReturnUndefChecker.cpp
new file mode 100644
index 0000000..52a0b30
--- /dev/null
+++ b/lib/Checker/ReturnUndefChecker.cpp
@@ -0,0 +1,67 @@
+//== ReturnUndefChecker.cpp -------------------------------------*- C++ -*--==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines ReturnUndefChecker, which is a path-sensitive
+// check which looks for undefined or garbage values being returned to the
+// caller.
+//
+//===----------------------------------------------------------------------===//
+
+#include "GRExprEngineInternalChecks.h"
+#include "clang/Checker/BugReporter/BugType.h"
+#include "clang/Checker/PathSensitive/CheckerVisitor.h"
+#include "clang/Checker/PathSensitive/GRExprEngine.h"
+
+using namespace clang;
+
+namespace {
+class ReturnUndefChecker : 
+    public CheckerVisitor<ReturnUndefChecker> {      
+  BuiltinBug *BT;
+public:
+    ReturnUndefChecker() : BT(0) {}
+    static void *getTag();
+    void PreVisitReturnStmt(CheckerContext &C, const ReturnStmt *RS);
+};
+}
+
+void clang::RegisterReturnUndefChecker(GRExprEngine &Eng) {
+  Eng.registerCheck(new ReturnUndefChecker());
+}
+
+void *ReturnUndefChecker::getTag() {
+  static int x = 0; return &x;
+}
+
+void ReturnUndefChecker::PreVisitReturnStmt(CheckerContext &C,
+                                            const ReturnStmt *RS) {
+ 
+  const Expr *RetE = RS->getRetValue();
+  if (!RetE)
+    return;
+  
+  if (!C.getState()->getSVal(RetE).isUndef())
+    return;
+  
+  ExplodedNode *N = C.GenerateSink();
+
+  if (!N)
+    return;
+  
+  if (!BT)
+    BT = new BuiltinBug("Garbage return value",
+                        "Undefined or garbage value returned to caller");
+    
+  EnhancedBugReport *report = 
+    new EnhancedBugReport(*BT, BT->getDescription(), N);
+
+  report->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue, RetE);
+
+  C.EmitReport(report);
+}
diff --git a/lib/Checker/SVals.cpp b/lib/Checker/SVals.cpp
new file mode 100644
index 0000000..d756be7
--- /dev/null
+++ b/lib/Checker/SVals.cpp
@@ -0,0 +1,347 @@
+//= RValues.cpp - Abstract RValues for Path-Sens. Value Tracking -*- C++ -*-==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines SVal, Loc, and NonLoc, classes that represent
+//  abstract r-values for use with path-sensitive value tracking.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Checker/PathSensitive/GRState.h"
+#include "clang/Basic/IdentifierTable.h"
+
+using namespace clang;
+using llvm::dyn_cast;
+using llvm::cast;
+using llvm::APSInt;
+
+//===----------------------------------------------------------------------===//
+// Symbol iteration within an SVal.
+//===----------------------------------------------------------------------===//
+
+
+//===----------------------------------------------------------------------===//
+// Utility methods.
+//===----------------------------------------------------------------------===//
+
+bool SVal::hasConjuredSymbol() const {
+  if (const nonloc::SymbolVal* SV = dyn_cast<nonloc::SymbolVal>(this)) {
+    SymbolRef sym = SV->getSymbol();
+    if (isa<SymbolConjured>(sym))
+      return true;
+  }
+
+  if (const loc::MemRegionVal *RV = dyn_cast<loc::MemRegionVal>(this)) {
+    const MemRegion *R = RV->getRegion();
+    if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R)) {
+      SymbolRef sym = SR->getSymbol();
+      if (isa<SymbolConjured>(sym))
+        return true;
+    }
+  }
+
+  return false;
+}
+
+const FunctionDecl *SVal::getAsFunctionDecl() const {
+  if (const loc::MemRegionVal* X = dyn_cast<loc::MemRegionVal>(this)) {
+    const MemRegion* R = X->getRegion();
+    if (const FunctionTextRegion *CTR = R->getAs<FunctionTextRegion>())
+      return CTR->getDecl();
+  }
+
+  return NULL;
+}
+
+/// getAsLocSymbol - If this SVal is a location (subclasses Loc) and
+///  wraps a symbol, return that SymbolRef.  Otherwise return 0.
+// FIXME: should we consider SymbolRef wrapped in CodeTextRegion?
+SymbolRef SVal::getAsLocSymbol() const {
+  if (const loc::MemRegionVal *X = dyn_cast<loc::MemRegionVal>(this)) {
+    const MemRegion *R = X->StripCasts();
+    if (const SymbolicRegion *SymR = dyn_cast<SymbolicRegion>(R))
+      return SymR->getSymbol();
+  }
+  return NULL;
+}
+
+/// Get the symbol in the SVal or its base region.
+SymbolRef SVal::getLocSymbolInBase() const {
+  const loc::MemRegionVal *X = dyn_cast<loc::MemRegionVal>(this);
+
+  if (!X)
+    return 0;
+
+  const MemRegion *R = X->getRegion();
+
+  while (const SubRegion *SR = dyn_cast<SubRegion>(R)) {
+    if (const SymbolicRegion *SymR = dyn_cast<SymbolicRegion>(SR))
+      return SymR->getSymbol();
+    else
+      R = SR->getSuperRegion();
+  }
+
+  return 0;
+}
+
+/// getAsSymbol - If this Sval wraps a symbol return that SymbolRef.
+///  Otherwise return 0.
+// FIXME: should we consider SymbolRef wrapped in CodeTextRegion?
+SymbolRef SVal::getAsSymbol() const {
+  if (const nonloc::SymbolVal *X = dyn_cast<nonloc::SymbolVal>(this))
+    return X->getSymbol();
+
+  if (const nonloc::SymExprVal *X = dyn_cast<nonloc::SymExprVal>(this))
+    if (SymbolRef Y = dyn_cast<SymbolData>(X->getSymbolicExpression()))
+      return Y;
+
+  return getAsLocSymbol();
+}
+
+/// getAsSymbolicExpression - If this Sval wraps a symbolic expression then
+///  return that expression.  Otherwise return NULL.
+const SymExpr *SVal::getAsSymbolicExpression() const {
+  if (const nonloc::SymExprVal *X = dyn_cast<nonloc::SymExprVal>(this))
+    return X->getSymbolicExpression();
+
+  return getAsSymbol();
+}
+
+const MemRegion *SVal::getAsRegion() const {
+  if (const loc::MemRegionVal *X = dyn_cast<loc::MemRegionVal>(this))
+    return X->getRegion();
+
+  if (const nonloc::LocAsInteger *X = dyn_cast<nonloc::LocAsInteger>(this)) {
+    return X->getLoc().getAsRegion();
+  }
+
+  return 0;
+}
+
+const MemRegion *loc::MemRegionVal::StripCasts() const {
+  const MemRegion *R = getRegion();
+  return R ?  R->StripCasts() : NULL;
+}
+
+bool SVal::symbol_iterator::operator==(const symbol_iterator &X) const {
+  return itr == X.itr;
+}
+
+bool SVal::symbol_iterator::operator!=(const symbol_iterator &X) const {
+  return itr != X.itr;
+}
+
+SVal::symbol_iterator::symbol_iterator(const SymExpr *SE) {
+  itr.push_back(SE);
+  while (!isa<SymbolData>(itr.back())) expand();
+}
+
+SVal::symbol_iterator& SVal::symbol_iterator::operator++() {
+  assert(!itr.empty() && "attempting to iterate on an 'end' iterator");
+  assert(isa<SymbolData>(itr.back()));
+  itr.pop_back();
+  if (!itr.empty())
+    while (!isa<SymbolData>(itr.back())) expand();
+  return *this;
+}
+
+SymbolRef SVal::symbol_iterator::operator*() {
+  assert(!itr.empty() && "attempting to dereference an 'end' iterator");
+  return cast<SymbolData>(itr.back());
+}
+
+void SVal::symbol_iterator::expand() {
+  const SymExpr *SE = itr.back();
+  itr.pop_back();
+
+  if (const SymIntExpr *SIE = dyn_cast<SymIntExpr>(SE)) {
+    itr.push_back(SIE->getLHS());
+    return;
+  }
+  else if (const SymSymExpr *SSE = dyn_cast<SymSymExpr>(SE)) {
+    itr.push_back(SSE->getLHS());
+    itr.push_back(SSE->getRHS());
+    return;
+  }
+
+  assert(false && "unhandled expansion case");
+}
+
+const void *nonloc::LazyCompoundVal::getStore() const {
+  return static_cast<const LazyCompoundValData*>(Data)->getStore();
+}
+
+const TypedRegion *nonloc::LazyCompoundVal::getRegion() const {
+  return static_cast<const LazyCompoundValData*>(Data)->getRegion();
+}
+
+//===----------------------------------------------------------------------===//
+// Other Iterators.
+//===----------------------------------------------------------------------===//
+
+nonloc::CompoundVal::iterator nonloc::CompoundVal::begin() const {
+  return getValue()->begin();
+}
+
+nonloc::CompoundVal::iterator nonloc::CompoundVal::end() const {
+  return getValue()->end();
+}
+
+//===----------------------------------------------------------------------===//
+// Useful predicates.
+//===----------------------------------------------------------------------===//
+
+bool SVal::isConstant() const {
+  return isa<nonloc::ConcreteInt>(this) || isa<loc::ConcreteInt>(this);
+}
+
+bool SVal::isZeroConstant() const {
+  if (isa<loc::ConcreteInt>(*this))
+    return cast<loc::ConcreteInt>(*this).getValue() == 0;
+  else if (isa<nonloc::ConcreteInt>(*this))
+    return cast<nonloc::ConcreteInt>(*this).getValue() == 0;
+  else
+    return false;
+}
+
+
+//===----------------------------------------------------------------------===//
+// Transfer function dispatch for Non-Locs.
+//===----------------------------------------------------------------------===//
+
+SVal nonloc::ConcreteInt::evalBinOp(ValueManager &ValMgr,
+                                    BinaryOperator::Opcode Op,
+                                    const nonloc::ConcreteInt& R) const {
+  const llvm::APSInt* X =
+    ValMgr.getBasicValueFactory().EvaluateAPSInt(Op, getValue(), R.getValue());
+
+  if (X)
+    return nonloc::ConcreteInt(*X);
+  else
+    return UndefinedVal();
+}
+
+nonloc::ConcreteInt
+nonloc::ConcreteInt::evalComplement(ValueManager &ValMgr) const {
+  return ValMgr.makeIntVal(~getValue());
+}
+
+nonloc::ConcreteInt nonloc::ConcreteInt::evalMinus(ValueManager &ValMgr) const {
+  return ValMgr.makeIntVal(-getValue());
+}
+
+//===----------------------------------------------------------------------===//
+// Transfer function dispatch for Locs.
+//===----------------------------------------------------------------------===//
+
+SVal loc::ConcreteInt::EvalBinOp(BasicValueFactory& BasicVals,
+                                 BinaryOperator::Opcode Op,
+                                 const loc::ConcreteInt& R) const {
+
+  assert (Op == BinaryOperator::Add || Op == BinaryOperator::Sub ||
+          (Op >= BinaryOperator::LT && Op <= BinaryOperator::NE));
+
+  const llvm::APSInt* X = BasicVals.EvaluateAPSInt(Op, getValue(), R.getValue());
+
+  if (X)
+    return loc::ConcreteInt(*X);
+  else
+    return UndefinedVal();
+}
+
+//===----------------------------------------------------------------------===//
+// Pretty-Printing.
+//===----------------------------------------------------------------------===//
+
+void SVal::dump() const { dumpToStream(llvm::errs()); }
+
+void SVal::dumpToStream(llvm::raw_ostream& os) const {
+  switch (getBaseKind()) {
+    case UnknownKind:
+      os << "Invalid";
+      break;
+    case NonLocKind:
+      cast<NonLoc>(this)->dumpToStream(os);
+      break;
+    case LocKind:
+      cast<Loc>(this)->dumpToStream(os);
+      break;
+    case UndefinedKind:
+      os << "Undefined";
+      break;
+    default:
+      assert (false && "Invalid SVal.");
+  }
+}
+
+void NonLoc::dumpToStream(llvm::raw_ostream& os) const {
+  switch (getSubKind()) {
+    case nonloc::ConcreteIntKind:
+      os << cast<nonloc::ConcreteInt>(this)->getValue().getZExtValue();
+      if (cast<nonloc::ConcreteInt>(this)->getValue().isUnsigned())
+        os << 'U';
+      break;
+    case nonloc::SymbolValKind:
+      os << '$' << cast<nonloc::SymbolVal>(this)->getSymbol();
+      break;
+    case nonloc::SymExprValKind: {
+      const nonloc::SymExprVal& C = *cast<nonloc::SymExprVal>(this);
+      const SymExpr *SE = C.getSymbolicExpression();
+      os << SE;
+      break;
+    }
+    case nonloc::LocAsIntegerKind: {
+      const nonloc::LocAsInteger& C = *cast<nonloc::LocAsInteger>(this);
+      os << C.getLoc() << " [as " << C.getNumBits() << " bit integer]";
+      break;
+    }
+    case nonloc::CompoundValKind: {
+      const nonloc::CompoundVal& C = *cast<nonloc::CompoundVal>(this);
+      os << "compoundVal{";
+      bool first = true;
+      for (nonloc::CompoundVal::iterator I=C.begin(), E=C.end(); I!=E; ++I) {
+        if (first) {
+          os << ' '; first = false;
+        }
+        else
+          os << ", ";
+
+        (*I).dumpToStream(os);
+      }
+      os << "}";
+      break;
+    }
+    case nonloc::LazyCompoundValKind: {
+      const nonloc::LazyCompoundVal &C = *cast<nonloc::LazyCompoundVal>(this);
+      os << "lazyCompoundVal{" << const_cast<void *>(C.getStore())
+         << ',' << C.getRegion()
+         << '}';
+      break;
+    }
+    default:
+      assert (false && "Pretty-printed not implemented for this NonLoc.");
+      break;
+  }
+}
+
+void Loc::dumpToStream(llvm::raw_ostream& os) const {
+  switch (getSubKind()) {
+    case loc::ConcreteIntKind:
+      os << cast<loc::ConcreteInt>(this)->getValue().getZExtValue() << " (Loc)";
+      break;
+    case loc::GotoLabelKind:
+      os << "&&" << cast<loc::GotoLabel>(this)->getLabel()->getID()->getName();
+      break;
+    case loc::MemRegionKind:
+      os << '&' << cast<loc::MemRegionVal>(this)->getRegion()->getString();
+      break;
+    default:
+      assert(false && "Pretty-printing not implemented for this Loc.");
+      break;
+  }
+}
diff --git a/lib/Checker/SValuator.cpp b/lib/Checker/SValuator.cpp
new file mode 100644
index 0000000..542fc1b
--- /dev/null
+++ b/lib/Checker/SValuator.cpp
@@ -0,0 +1,157 @@
+// SValuator.cpp - Basic class for all SValuator implementations --*- C++ -*--//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines SValuator, the base class for all (complete) SValuator
+//  implementations.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Checker/PathSensitive/SValuator.h"
+#include "clang/Checker/PathSensitive/GRState.h"
+
+using namespace clang;
+
+
+SVal SValuator::EvalBinOp(const GRState *ST, BinaryOperator::Opcode Op,
+                          SVal L, SVal R, QualType T) {
+
+  if (L.isUndef() || R.isUndef())
+    return UndefinedVal();
+
+  if (L.isUnknown() || R.isUnknown())
+    return UnknownVal();
+
+  if (isa<Loc>(L)) {
+    if (isa<Loc>(R))
+      return EvalBinOpLL(Op, cast<Loc>(L), cast<Loc>(R), T);
+
+    return EvalBinOpLN(ST, Op, cast<Loc>(L), cast<NonLoc>(R), T);
+  }
+
+  if (isa<Loc>(R)) {
+    // Support pointer arithmetic where the increment/decrement operand
+    // is on the left and the pointer on the right.
+    assert(Op == BinaryOperator::Add || Op == BinaryOperator::Sub);
+
+    // Commute the operands.
+    return EvalBinOpLN(ST, Op, cast<Loc>(R), cast<NonLoc>(L), T);
+  }
+
+  return EvalBinOpNN(ST, Op, cast<NonLoc>(L), cast<NonLoc>(R), T);
+}
+
+DefinedOrUnknownSVal SValuator::EvalEQ(const GRState *ST,
+                                       DefinedOrUnknownSVal L,
+                                       DefinedOrUnknownSVal R) {
+  return cast<DefinedOrUnknownSVal>(EvalBinOp(ST, BinaryOperator::EQ, L, R,
+                                              ValMgr.getContext().IntTy));
+}
+
+SVal SValuator::EvalCast(SVal val, QualType castTy, QualType originalTy) {
+  if (val.isUnknownOrUndef() || castTy == originalTy)
+    return val;
+
+  ASTContext &C = ValMgr.getContext();
+
+  // For const casts, just propagate the value.
+  if (!castTy->isVariableArrayType() && !originalTy->isVariableArrayType())
+    if (C.hasSameUnqualifiedType(castTy, originalTy))
+      return val;
+
+  // Check for casts to real or complex numbers.  We don't handle these at all
+  // right now.
+  if (castTy->isFloatingType() || castTy->isAnyComplexType())
+    return UnknownVal();
+  
+  // Check for casts from integers to integers.
+  if (castTy->isIntegerType() && originalTy->isIntegerType())
+    return EvalCastNL(cast<NonLoc>(val), castTy);
+
+  // Check for casts from pointers to integers.
+  if (castTy->isIntegerType() && Loc::IsLocType(originalTy))
+    return EvalCastL(cast<Loc>(val), castTy);
+
+  // Check for casts from integers to pointers.
+  if (Loc::IsLocType(castTy) && originalTy->isIntegerType()) {
+    if (nonloc::LocAsInteger *LV = dyn_cast<nonloc::LocAsInteger>(&val)) {
+      if (const MemRegion *R = LV->getLoc().getAsRegion()) {
+        StoreManager &storeMgr = ValMgr.getStateManager().getStoreManager();
+        R = storeMgr.CastRegion(R, castTy);
+        return R ? SVal(loc::MemRegionVal(R)) : UnknownVal();
+      }
+      return LV->getLoc();
+    }
+    goto DispatchCast;
+  }
+
+  // Just pass through function and block pointers.
+  if (originalTy->isBlockPointerType() || originalTy->isFunctionPointerType()) {
+    assert(Loc::IsLocType(castTy));
+    return val;
+  }
+
+  // Check for casts from array type to another type.
+  if (originalTy->isArrayType()) {
+    // We will always decay to a pointer.
+    val = ValMgr.getStateManager().ArrayToPointer(cast<Loc>(val));
+
+    // Are we casting from an array to a pointer?  If so just pass on
+    // the decayed value.
+    if (castTy->isPointerType())
+      return val;
+
+    // Are we casting from an array to an integer?  If so, cast the decayed
+    // pointer value to an integer.
+    assert(castTy->isIntegerType());
+
+    // FIXME: Keep these here for now in case we decide soon that we
+    // need the original decayed type.
+    //    QualType elemTy = cast<ArrayType>(originalTy)->getElementType();
+    //    QualType pointerTy = C.getPointerType(elemTy);
+    return EvalCastL(cast<Loc>(val), castTy);
+  }
+
+  // Check for casts from a region to a specific type.
+  if (const MemRegion *R = val.getAsRegion()) {
+    // FIXME: We should handle the case where we strip off view layers to get
+    //  to a desugared type.
+
+    assert(Loc::IsLocType(castTy));
+    // We get a symbolic function pointer for a dereference of a function
+    // pointer, but it is of function type. Example:
+
+    //  struct FPRec {
+    //    void (*my_func)(int * x);
+    //  };
+    //
+    //  int bar(int x);
+    //
+    //  int f1_a(struct FPRec* foo) {
+    //    int x;
+    //    (*foo->my_func)(&x);
+    //    return bar(x)+1; // no-warning
+    //  }
+
+    assert(Loc::IsLocType(originalTy) || originalTy->isFunctionType() ||
+           originalTy->isBlockPointerType());
+
+    StoreManager &storeMgr = ValMgr.getStateManager().getStoreManager();
+
+    // Delegate to store manager to get the result of casting a region to a
+    // different type.  If the MemRegion* returned is NULL, this expression
+    // evaluates to UnknownVal.
+    R = storeMgr.CastRegion(R, castTy);
+    return R ? SVal(loc::MemRegionVal(R)) : UnknownVal();
+  }
+
+DispatchCast:
+  // All other cases.
+  return isa<Loc>(val) ? EvalCastL(cast<Loc>(val), castTy)
+                       : EvalCastNL(cast<NonLoc>(val), castTy);
+}
diff --git a/lib/Checker/SimpleConstraintManager.cpp b/lib/Checker/SimpleConstraintManager.cpp
new file mode 100644
index 0000000..8c423a9
--- /dev/null
+++ b/lib/Checker/SimpleConstraintManager.cpp
@@ -0,0 +1,249 @@
+//== SimpleConstraintManager.cpp --------------------------------*- C++ -*--==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines SimpleConstraintManager, a class that holds code shared
+//  between BasicConstraintManager and RangeConstraintManager.
+//
+//===----------------------------------------------------------------------===//
+
+#include "SimpleConstraintManager.h"
+#include "clang/Checker/PathSensitive/GRExprEngine.h"
+#include "clang/Checker/PathSensitive/GRState.h"
+#include "clang/Checker/PathSensitive/Checker.h"
+
+namespace clang {
+
+SimpleConstraintManager::~SimpleConstraintManager() {}
+
+bool SimpleConstraintManager::canReasonAbout(SVal X) const {
+  if (nonloc::SymExprVal *SymVal = dyn_cast<nonloc::SymExprVal>(&X)) {
+    const SymExpr *SE = SymVal->getSymbolicExpression();
+
+    if (isa<SymbolData>(SE))
+      return true;
+
+    if (const SymIntExpr *SIE = dyn_cast<SymIntExpr>(SE)) {
+      switch (SIE->getOpcode()) {
+          // We don't reason yet about bitwise-constraints on symbolic values.
+        case BinaryOperator::And:
+        case BinaryOperator::Or:
+        case BinaryOperator::Xor:
+          return false;
+        // We don't reason yet about arithmetic constraints on symbolic values.
+        case BinaryOperator::Mul:
+        case BinaryOperator::Div:
+        case BinaryOperator::Rem:
+        case BinaryOperator::Add:
+        case BinaryOperator::Sub:
+        case BinaryOperator::Shl:
+        case BinaryOperator::Shr:
+          return false;
+        // All other cases.
+        default:
+          return true;
+      }
+    }
+
+    return false;
+  }
+
+  return true;
+}
+
+const GRState *SimpleConstraintManager::Assume(const GRState *state,
+                                               DefinedSVal Cond,
+                                               bool Assumption) {
+  if (isa<NonLoc>(Cond))
+    return Assume(state, cast<NonLoc>(Cond), Assumption);
+  else
+    return Assume(state, cast<Loc>(Cond), Assumption);
+}
+
+const GRState *SimpleConstraintManager::Assume(const GRState *state, Loc cond,
+                                               bool assumption) {
+  state = AssumeAux(state, cond, assumption);
+  return SU.ProcessAssume(state, cond, assumption);
+}
+
+const GRState *SimpleConstraintManager::AssumeAux(const GRState *state,
+                                                  Loc Cond, bool Assumption) {
+
+  BasicValueFactory &BasicVals = state->getBasicVals();
+
+  switch (Cond.getSubKind()) {
+  default:
+    assert (false && "'Assume' not implemented for this Loc.");
+    return state;
+
+  case loc::MemRegionKind: {
+    // FIXME: Should this go into the storemanager?
+
+    const MemRegion *R = cast<loc::MemRegionVal>(Cond).getRegion();
+    const SubRegion *SubR = dyn_cast<SubRegion>(R);
+
+    while (SubR) {
+      // FIXME: now we only find the first symbolic region.
+      if (const SymbolicRegion *SymR = dyn_cast<SymbolicRegion>(SubR)) {
+        if (Assumption)
+          return AssumeSymNE(state, SymR->getSymbol(),
+                             BasicVals.getZeroWithPtrWidth());
+        else
+          return AssumeSymEQ(state, SymR->getSymbol(),
+                             BasicVals.getZeroWithPtrWidth());
+      }
+      SubR = dyn_cast<SubRegion>(SubR->getSuperRegion());
+    }
+
+    // FALL-THROUGH.
+  }
+
+  case loc::GotoLabelKind:
+    return Assumption ? state : NULL;
+
+  case loc::ConcreteIntKind: {
+    bool b = cast<loc::ConcreteInt>(Cond).getValue() != 0;
+    bool isFeasible = b ? Assumption : !Assumption;
+    return isFeasible ? state : NULL;
+  }
+  } // end switch
+}
+
+const GRState *SimpleConstraintManager::Assume(const GRState *state,
+                                               NonLoc cond,
+                                               bool assumption) {
+  state = AssumeAux(state, cond, assumption);
+  return SU.ProcessAssume(state, cond, assumption);
+}
+
+const GRState *SimpleConstraintManager::AssumeAux(const GRState *state,
+                                                  NonLoc Cond,
+                                                  bool Assumption) {
+
+  // We cannot reason about SymIntExpr and SymSymExpr.
+  if (!canReasonAbout(Cond)) {
+    // Just return the current state indicating that the path is feasible.
+    // This may be an over-approximation of what is possible.
+    return state;
+  }
+
+  BasicValueFactory &BasicVals = state->getBasicVals();
+  SymbolManager &SymMgr = state->getSymbolManager();
+
+  switch (Cond.getSubKind()) {
+  default:
+    assert(false && "'Assume' not implemented for this NonLoc");
+
+  case nonloc::SymbolValKind: {
+    nonloc::SymbolVal& SV = cast<nonloc::SymbolVal>(Cond);
+    SymbolRef sym = SV.getSymbol();
+    QualType T =  SymMgr.getType(sym);
+    const llvm::APSInt &zero = BasicVals.getValue(0, T);
+
+    return Assumption ? AssumeSymNE(state, sym, zero)
+                      : AssumeSymEQ(state, sym, zero);
+  }
+
+  case nonloc::SymExprValKind: {
+    nonloc::SymExprVal V = cast<nonloc::SymExprVal>(Cond);
+    if (const SymIntExpr *SE = dyn_cast<SymIntExpr>(V.getSymbolicExpression())){
+      // FIXME: This is a hack.  It silently converts the RHS integer to be
+      // of the same type as on the left side.  This should be removed once
+      // we support truncation/extension of symbolic values.      
+      GRStateManager &StateMgr = state->getStateManager();
+      ASTContext &Ctx = StateMgr.getContext();
+      QualType LHSType = SE->getLHS()->getType(Ctx);
+      BasicValueFactory &BasicVals = StateMgr.getBasicVals();
+      const llvm::APSInt &RHS = BasicVals.Convert(LHSType, SE->getRHS());
+      SymIntExpr SENew(SE->getLHS(), SE->getOpcode(), RHS, SE->getType(Ctx));
+
+      return AssumeSymInt(state, Assumption, &SENew);
+    }
+
+    // For all other symbolic expressions, over-approximate and consider
+    // the constraint feasible.
+    return state;
+  }
+
+  case nonloc::ConcreteIntKind: {
+    bool b = cast<nonloc::ConcreteInt>(Cond).getValue() != 0;
+    bool isFeasible = b ? Assumption : !Assumption;
+    return isFeasible ? state : NULL;
+  }
+
+  case nonloc::LocAsIntegerKind:
+    return AssumeAux(state, cast<nonloc::LocAsInteger>(Cond).getLoc(),
+                     Assumption);
+  } // end switch
+}
+
+const GRState *SimpleConstraintManager::AssumeSymInt(const GRState *state,
+                                                     bool Assumption,
+                                                     const SymIntExpr *SE) {
+
+
+  // Here we assume that LHS is a symbol.  This is consistent with the
+  // rest of the constraint manager logic.
+  SymbolRef Sym = cast<SymbolData>(SE->getLHS());
+  const llvm::APSInt &Int = SE->getRHS();
+
+  switch (SE->getOpcode()) {
+  default:
+    // No logic yet for other operators.  Assume the constraint is feasible.
+    return state;
+
+  case BinaryOperator::EQ:
+    return Assumption ? AssumeSymEQ(state, Sym, Int)
+                      : AssumeSymNE(state, Sym, Int);
+
+  case BinaryOperator::NE:
+    return Assumption ? AssumeSymNE(state, Sym, Int)
+                      : AssumeSymEQ(state, Sym, Int);
+  case BinaryOperator::GT:
+    return Assumption ? AssumeSymGT(state, Sym, Int)
+                      : AssumeSymLE(state, Sym, Int);
+
+  case BinaryOperator::GE:
+    return Assumption ? AssumeSymGE(state, Sym, Int)
+                      : AssumeSymLT(state, Sym, Int);
+
+  case BinaryOperator::LT:
+    return Assumption ? AssumeSymLT(state, Sym, Int)
+                      : AssumeSymGE(state, Sym, Int);
+
+  case BinaryOperator::LE:
+    return Assumption ? AssumeSymLE(state, Sym, Int)
+                      : AssumeSymGT(state, Sym, Int);
+  } // end switch
+}
+
+const GRState *SimpleConstraintManager::AssumeInBound(const GRState *state,
+                                                      DefinedSVal Idx,
+                                                      DefinedSVal UpperBound,
+                                                      bool Assumption) {
+
+  // Only support ConcreteInt for now.
+  if (!(isa<nonloc::ConcreteInt>(Idx) && isa<nonloc::ConcreteInt>(UpperBound)))
+    return state;
+
+  const llvm::APSInt& Zero = state->getBasicVals().getZeroWithPtrWidth(false);
+  llvm::APSInt IdxV = cast<nonloc::ConcreteInt>(Idx).getValue();
+  // IdxV might be too narrow.
+  if (IdxV.getBitWidth() < Zero.getBitWidth())
+    IdxV.extend(Zero.getBitWidth());
+  // UBV might be too narrow, too.
+  llvm::APSInt UBV = cast<nonloc::ConcreteInt>(UpperBound).getValue();
+  if (UBV.getBitWidth() < Zero.getBitWidth())
+    UBV.extend(Zero.getBitWidth());
+
+  bool InBound = (Zero <= IdxV) && (IdxV < UBV);
+  bool isFeasible = Assumption ? InBound : !InBound;
+  return isFeasible ? state : NULL;
+}
+
+}  // end of namespace clang
diff --git a/lib/Checker/SimpleConstraintManager.h b/lib/Checker/SimpleConstraintManager.h
new file mode 100644
index 0000000..5f20e00
--- /dev/null
+++ b/lib/Checker/SimpleConstraintManager.h
@@ -0,0 +1,83 @@
+//== SimpleConstraintManager.h ----------------------------------*- C++ -*--==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  Code shared between BasicConstraintManager and RangeConstraintManager.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_SIMPLE_CONSTRAINT_MANAGER_H
+#define LLVM_CLANG_ANALYSIS_SIMPLE_CONSTRAINT_MANAGER_H
+
+#include "clang/Checker/PathSensitive/ConstraintManager.h"
+#include "clang/Checker/PathSensitive/GRState.h"
+
+namespace clang {
+
+class SimpleConstraintManager : public ConstraintManager {
+  GRSubEngine &SU;
+public:
+  SimpleConstraintManager(GRSubEngine &subengine) : SU(subengine) {}
+  virtual ~SimpleConstraintManager();
+
+  //===------------------------------------------------------------------===//
+  // Common implementation for the interface provided by ConstraintManager.
+  //===------------------------------------------------------------------===//
+
+  bool canReasonAbout(SVal X) const;
+
+  const GRState *Assume(const GRState *state, DefinedSVal Cond,
+                        bool Assumption);
+
+  const GRState *Assume(const GRState *state, Loc Cond, bool Assumption);
+
+  const GRState *Assume(const GRState *state, NonLoc Cond, bool Assumption);
+
+  const GRState *AssumeSymInt(const GRState *state, bool Assumption,
+                              const SymIntExpr *SE);
+
+  const GRState *AssumeInBound(const GRState *state, DefinedSVal Idx,
+                               DefinedSVal UpperBound,
+                               bool Assumption);
+
+protected:
+
+  //===------------------------------------------------------------------===//
+  // Interface that subclasses must implement.
+  //===------------------------------------------------------------------===//
+
+  virtual const GRState *AssumeSymNE(const GRState *state, SymbolRef sym,
+                                     const llvm::APSInt& V) = 0;
+
+  virtual const GRState *AssumeSymEQ(const GRState *state, SymbolRef sym,
+                                     const llvm::APSInt& V) = 0;
+
+  virtual const GRState *AssumeSymLT(const GRState *state, SymbolRef sym,
+                                     const llvm::APSInt& V) = 0;
+
+  virtual const GRState *AssumeSymGT(const GRState *state, SymbolRef sym,
+                                     const llvm::APSInt& V) = 0;
+
+  virtual const GRState *AssumeSymLE(const GRState *state, SymbolRef sym,
+                                     const llvm::APSInt& V) = 0;
+
+  virtual const GRState *AssumeSymGE(const GRState *state, SymbolRef sym,
+                                     const llvm::APSInt& V) = 0;
+
+  //===------------------------------------------------------------------===//
+  // Internal implementation.
+  //===------------------------------------------------------------------===//
+
+  const GRState *AssumeAux(const GRState *state, Loc Cond,bool Assumption);
+
+  const GRState *AssumeAux(const GRState *state, NonLoc Cond, bool Assumption);
+};
+
+}  // end clang namespace
+
+#endif
diff --git a/lib/Checker/SimpleSValuator.cpp b/lib/Checker/SimpleSValuator.cpp
new file mode 100644
index 0000000..dd38a43
--- /dev/null
+++ b/lib/Checker/SimpleSValuator.cpp
@@ -0,0 +1,434 @@
+// SimpleSValuator.cpp - A basic SValuator ------------------------*- C++ -*--//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines SimpleSValuator, a basic implementation of SValuator.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Checker/PathSensitive/SValuator.h"
+#include "clang/Checker/PathSensitive/GRState.h"
+
+using namespace clang;
+
+namespace {
+class SimpleSValuator : public SValuator {
+protected:
+  virtual SVal EvalCastNL(NonLoc val, QualType castTy);
+  virtual SVal EvalCastL(Loc val, QualType castTy);
+
+public:
+  SimpleSValuator(ValueManager &valMgr) : SValuator(valMgr) {}
+  virtual ~SimpleSValuator() {}
+
+  virtual SVal EvalMinus(NonLoc val);
+  virtual SVal EvalComplement(NonLoc val);
+  virtual SVal EvalBinOpNN(const GRState *state, BinaryOperator::Opcode op,
+                           NonLoc lhs, NonLoc rhs, QualType resultTy);
+  virtual SVal EvalBinOpLL(BinaryOperator::Opcode op, Loc lhs, Loc rhs,
+                           QualType resultTy);
+  virtual SVal EvalBinOpLN(const GRState *state, BinaryOperator::Opcode op,
+                           Loc lhs, NonLoc rhs, QualType resultTy);
+};
+} // end anonymous namespace
+
+SValuator *clang::CreateSimpleSValuator(ValueManager &valMgr) {
+  return new SimpleSValuator(valMgr);
+}
+
+//===----------------------------------------------------------------------===//
+// Transfer function for Casts.
+//===----------------------------------------------------------------------===//
+
+SVal SimpleSValuator::EvalCastNL(NonLoc val, QualType castTy) {
+
+  bool isLocType = Loc::IsLocType(castTy);
+
+  if (nonloc::LocAsInteger *LI = dyn_cast<nonloc::LocAsInteger>(&val)) {
+    if (isLocType)
+      return LI->getLoc();
+
+    // FIXME: Correctly support promotions/truncations.
+    ASTContext &Ctx = ValMgr.getContext();
+    unsigned castSize = Ctx.getTypeSize(castTy);
+    if (castSize == LI->getNumBits())
+      return val;
+
+    return ValMgr.makeLocAsInteger(LI->getLoc(), castSize);
+  }
+
+  if (const SymExpr *se = val.getAsSymbolicExpression()) {
+    ASTContext &Ctx = ValMgr.getContext();
+    QualType T = Ctx.getCanonicalType(se->getType(Ctx));
+    if (T == Ctx.getCanonicalType(castTy))
+      return val;
+    
+    // FIXME: Remove this hack when we support symbolic truncation/extension.
+    // HACK: If both castTy and T are integers, ignore the cast.  This is
+    // not a permanent solution.  Eventually we want to precisely handle
+    // extension/truncation of symbolic integers.  This prevents us from losing
+    // precision when we assign 'x = y' and 'y' is symbolic and x and y are
+    // different integer types.
+    if (T->isIntegerType() && castTy->isIntegerType())
+      return val;
+
+    return UnknownVal();
+  }
+
+  if (!isa<nonloc::ConcreteInt>(val))
+    return UnknownVal();
+
+  // Only handle casts from integers to integers.
+  if (!isLocType && !castTy->isIntegerType())
+    return UnknownVal();
+
+  llvm::APSInt i = cast<nonloc::ConcreteInt>(val).getValue();
+  i.setIsUnsigned(castTy->isUnsignedIntegerType() || Loc::IsLocType(castTy));
+  i.extOrTrunc(ValMgr.getContext().getTypeSize(castTy));
+
+  if (isLocType)
+    return ValMgr.makeIntLocVal(i);
+  else
+    return ValMgr.makeIntVal(i);
+}
+
+SVal SimpleSValuator::EvalCastL(Loc val, QualType castTy) {
+
+  // Casts from pointers -> pointers, just return the lval.
+  //
+  // Casts from pointers -> references, just return the lval.  These
+  //   can be introduced by the frontend for corner cases, e.g
+  //   casting from va_list* to __builtin_va_list&.
+  //
+  if (Loc::IsLocType(castTy) || castTy->isReferenceType())
+    return val;
+
+  // FIXME: Handle transparent unions where a value can be "transparently"
+  //  lifted into a union type.
+  if (castTy->isUnionType())
+    return UnknownVal();
+
+  if (castTy->isIntegerType()) {
+    unsigned BitWidth = ValMgr.getContext().getTypeSize(castTy);
+
+    if (!isa<loc::ConcreteInt>(val))
+      return ValMgr.makeLocAsInteger(val, BitWidth);
+
+    llvm::APSInt i = cast<loc::ConcreteInt>(val).getValue();
+    i.setIsUnsigned(castTy->isUnsignedIntegerType() || Loc::IsLocType(castTy));
+    i.extOrTrunc(BitWidth);
+    return ValMgr.makeIntVal(i);
+  }
+
+  // All other cases: return 'UnknownVal'.  This includes casting pointers
+  // to floats, which is probably badness it itself, but this is a good
+  // intermediate solution until we do something better.
+  return UnknownVal();
+}
+
+//===----------------------------------------------------------------------===//
+// Transfer function for unary operators.
+//===----------------------------------------------------------------------===//
+
+SVal SimpleSValuator::EvalMinus(NonLoc val) {
+  switch (val.getSubKind()) {
+  case nonloc::ConcreteIntKind:
+    return cast<nonloc::ConcreteInt>(val).evalMinus(ValMgr);
+  default:
+    return UnknownVal();
+  }
+}
+
+SVal SimpleSValuator::EvalComplement(NonLoc X) {
+  switch (X.getSubKind()) {
+  case nonloc::ConcreteIntKind:
+    return cast<nonloc::ConcreteInt>(X).evalComplement(ValMgr);
+  default:
+    return UnknownVal();
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// Transfer function for binary operators.
+//===----------------------------------------------------------------------===//
+
+static BinaryOperator::Opcode NegateComparison(BinaryOperator::Opcode op) {
+  switch (op) {
+  default:
+    assert(false && "Invalid opcode.");
+  case BinaryOperator::LT: return BinaryOperator::GE;
+  case BinaryOperator::GT: return BinaryOperator::LE;
+  case BinaryOperator::LE: return BinaryOperator::GT;
+  case BinaryOperator::GE: return BinaryOperator::LT;
+  case BinaryOperator::EQ: return BinaryOperator::NE;
+  case BinaryOperator::NE: return BinaryOperator::EQ;
+  }
+}
+
+// Equality operators for Locs.
+// FIXME: All this logic will be revamped when we have MemRegion::getLocation()
+// implemented.
+
+static SVal EvalEquality(ValueManager &ValMgr, Loc lhs, Loc rhs, bool isEqual,
+                         QualType resultTy) {
+
+  switch (lhs.getSubKind()) {
+    default:
+      assert(false && "EQ/NE not implemented for this Loc.");
+      return UnknownVal();
+
+    case loc::ConcreteIntKind: {
+      if (SymbolRef rSym = rhs.getAsSymbol())
+        return ValMgr.makeNonLoc(rSym,
+                                 isEqual ? BinaryOperator::EQ
+                                 : BinaryOperator::NE,
+                                 cast<loc::ConcreteInt>(lhs).getValue(),
+                                 resultTy);
+      break;
+    }
+    case loc::MemRegionKind: {
+      if (SymbolRef lSym = lhs.getAsLocSymbol()) {
+        if (isa<loc::ConcreteInt>(rhs)) {
+          return ValMgr.makeNonLoc(lSym,
+                                   isEqual ? BinaryOperator::EQ
+                                   : BinaryOperator::NE,
+                                   cast<loc::ConcreteInt>(rhs).getValue(),
+                                   resultTy);
+        }
+      }
+      break;
+    }
+
+    case loc::GotoLabelKind:
+      break;
+  }
+
+  return ValMgr.makeTruthVal(isEqual ? lhs == rhs : lhs != rhs, resultTy);
+}
+
+SVal SimpleSValuator::EvalBinOpNN(const GRState *state,
+                                  BinaryOperator::Opcode op,
+                                  NonLoc lhs, NonLoc rhs,
+                                  QualType resultTy)  {
+  // Handle trivial case where left-side and right-side are the same.
+  if (lhs == rhs)
+    switch (op) {
+      default:
+        break;
+      case BinaryOperator::EQ:
+      case BinaryOperator::LE:
+      case BinaryOperator::GE:
+        return ValMgr.makeTruthVal(true, resultTy);
+      case BinaryOperator::LT:
+      case BinaryOperator::GT:
+      case BinaryOperator::NE:
+        return ValMgr.makeTruthVal(false, resultTy);
+    }
+
+  while (1) {
+    switch (lhs.getSubKind()) {
+    default:
+      return UnknownVal();
+    case nonloc::LocAsIntegerKind: {
+      Loc lhsL = cast<nonloc::LocAsInteger>(lhs).getLoc();
+      switch (rhs.getSubKind()) {
+        case nonloc::LocAsIntegerKind:
+          return EvalBinOpLL(op, lhsL, cast<nonloc::LocAsInteger>(rhs).getLoc(),
+                             resultTy);
+        case nonloc::ConcreteIntKind: {
+          // Transform the integer into a location and compare.
+          ASTContext& Ctx = ValMgr.getContext();
+          llvm::APSInt i = cast<nonloc::ConcreteInt>(rhs).getValue();
+          i.setIsUnsigned(true);
+          i.extOrTrunc(Ctx.getTypeSize(Ctx.VoidPtrTy));
+          return EvalBinOpLL(op, lhsL, ValMgr.makeLoc(i), resultTy);
+        }
+        default:
+          switch (op) {
+            case BinaryOperator::EQ:
+              return ValMgr.makeTruthVal(false, resultTy);
+            case BinaryOperator::NE:
+              return ValMgr.makeTruthVal(true, resultTy);
+            default:
+              // This case also handles pointer arithmetic.
+              return UnknownVal();
+          }
+      }
+    }
+    case nonloc::SymExprValKind: {
+      // Logical not?
+      if (!(op == BinaryOperator::EQ && rhs.isZeroConstant()))
+        return UnknownVal();
+
+      const SymExpr *symExpr =
+        cast<nonloc::SymExprVal>(lhs).getSymbolicExpression();
+
+      // Only handle ($sym op constant) for now.
+      if (const SymIntExpr *symIntExpr = dyn_cast<SymIntExpr>(symExpr)) {
+        BinaryOperator::Opcode opc = symIntExpr->getOpcode();
+        switch (opc) {
+          case BinaryOperator::LAnd:
+          case BinaryOperator::LOr:
+            assert(false && "Logical operators handled by branching logic.");
+            return UnknownVal();
+          case BinaryOperator::Assign:
+          case BinaryOperator::MulAssign:
+          case BinaryOperator::DivAssign:
+          case BinaryOperator::RemAssign:
+          case BinaryOperator::AddAssign:
+          case BinaryOperator::SubAssign:
+          case BinaryOperator::ShlAssign:
+          case BinaryOperator::ShrAssign:
+          case BinaryOperator::AndAssign:
+          case BinaryOperator::XorAssign:
+          case BinaryOperator::OrAssign:
+          case BinaryOperator::Comma:
+            assert(false && "'=' and ',' operators handled by GRExprEngine.");
+            return UnknownVal();
+          case BinaryOperator::PtrMemD:
+          case BinaryOperator::PtrMemI:
+            assert(false && "Pointer arithmetic not handled here.");
+            return UnknownVal();
+          case BinaryOperator::Mul:
+          case BinaryOperator::Div:
+          case BinaryOperator::Rem:
+          case BinaryOperator::Add:
+          case BinaryOperator::Sub:
+          case BinaryOperator::Shl:
+          case BinaryOperator::Shr:
+          case BinaryOperator::And:
+          case BinaryOperator::Xor:
+          case BinaryOperator::Or:
+            // Not handled yet.
+            return UnknownVal();
+          case BinaryOperator::LT:
+          case BinaryOperator::GT:
+          case BinaryOperator::LE:
+          case BinaryOperator::GE:
+          case BinaryOperator::EQ:
+          case BinaryOperator::NE:
+            opc = NegateComparison(opc);
+            assert(symIntExpr->getType(ValMgr.getContext()) == resultTy);
+            return ValMgr.makeNonLoc(symIntExpr->getLHS(), opc,
+                                     symIntExpr->getRHS(), resultTy);
+        }
+      }
+    }
+    case nonloc::ConcreteIntKind: {
+      if (isa<nonloc::ConcreteInt>(rhs)) {
+        const nonloc::ConcreteInt& lhsInt = cast<nonloc::ConcreteInt>(lhs);
+        return lhsInt.evalBinOp(ValMgr, op, cast<nonloc::ConcreteInt>(rhs));
+      }
+      else {
+        // Swap the left and right sides and flip the operator if doing so
+        // allows us to better reason about the expression (this is a form
+        // of expression canonicalization).
+        NonLoc tmp = rhs;
+        rhs = lhs;
+        lhs = tmp;
+
+        switch (op) {
+          case BinaryOperator::LT: op = BinaryOperator::GT; continue;
+          case BinaryOperator::GT: op = BinaryOperator::LT; continue;
+          case BinaryOperator::LE: op = BinaryOperator::GE; continue;
+          case BinaryOperator::GE: op = BinaryOperator::LE; continue;
+          case BinaryOperator::EQ:
+          case BinaryOperator::NE:
+          case BinaryOperator::Add:
+          case BinaryOperator::Mul:
+            continue;
+          default:
+            return UnknownVal();
+        }
+      }
+    }
+    case nonloc::SymbolValKind: {
+      nonloc::SymbolVal *slhs = cast<nonloc::SymbolVal>(&lhs);
+      SymbolRef Sym = slhs->getSymbol();
+      
+      // Does the symbol simplify to a constant?  If so, "fold" the constant
+      // by setting 'lhs' to a ConcreteInt and try again.
+      if (Sym->getType(ValMgr.getContext())->isIntegerType())
+        if (const llvm::APSInt *Constant = state->getSymVal(Sym)) {
+          // The symbol evaluates to a constant. If necessary, promote the
+          // folded constant (LHS) to the result type.
+          BasicValueFactory &BVF = ValMgr.getBasicValueFactory();
+          const llvm::APSInt &lhs_I = BVF.Convert(resultTy, *Constant);
+          lhs = nonloc::ConcreteInt(lhs_I);
+          
+          // Also promote the RHS (if necessary).
+
+          // For shifts, it necessary promote the RHS to the result type.
+          if (BinaryOperator::isShiftOp(op))
+            continue;
+          
+          // Other operators: do an implicit conversion.  This shouldn't be
+          // necessary once we support truncation/extension of symbolic values.
+          if (nonloc::ConcreteInt *rhs_I = dyn_cast<nonloc::ConcreteInt>(&rhs)){
+            rhs = nonloc::ConcreteInt(BVF.Convert(resultTy, rhs_I->getValue()));
+          }
+          
+          continue;
+        }
+      
+      if (isa<nonloc::ConcreteInt>(rhs)) {
+        return ValMgr.makeNonLoc(slhs->getSymbol(), op,
+                                 cast<nonloc::ConcreteInt>(rhs).getValue(),
+                                 resultTy);
+      }
+
+      return UnknownVal();
+    }
+    }
+  }
+}
+
+SVal SimpleSValuator::EvalBinOpLL(BinaryOperator::Opcode op, Loc lhs, Loc rhs,
+                                  QualType resultTy) {
+  switch (op) {
+    default:
+      return UnknownVal();
+    case BinaryOperator::EQ:
+    case BinaryOperator::NE:
+      return EvalEquality(ValMgr, lhs, rhs, op == BinaryOperator::EQ, resultTy);
+    case BinaryOperator::LT:
+    case BinaryOperator::GT:
+      // FIXME: Generalize.  For now, just handle the trivial case where
+      //  the two locations are identical.
+      if (lhs == rhs)
+        return ValMgr.makeTruthVal(false, resultTy);
+      return UnknownVal();
+  }
+}
+
+SVal SimpleSValuator::EvalBinOpLN(const GRState *state,
+                                  BinaryOperator::Opcode op,
+                                  Loc lhs, NonLoc rhs, QualType resultTy) {
+  // Special case: 'rhs' is an integer that has the same width as a pointer and
+  // we are using the integer location in a comparison.  Normally this cannot be
+  // triggered, but transfer functions like those for OSCommpareAndSwapBarrier32
+  // can generate comparisons that trigger this code.
+  // FIXME: Are all locations guaranteed to have pointer width?
+  if (BinaryOperator::isEqualityOp(op)) {
+    if (nonloc::ConcreteInt *rhsInt = dyn_cast<nonloc::ConcreteInt>(&rhs)) {
+      const llvm::APSInt *x = &rhsInt->getValue();
+      ASTContext &ctx = ValMgr.getContext();
+      if (ctx.getTypeSize(ctx.VoidPtrTy) == x->getBitWidth()) {
+        // Convert the signedness of the integer (if necessary).
+        if (x->isSigned())
+          x = &ValMgr.getBasicValueFactory().getValue(*x, true);
+
+        return EvalBinOpLL(op, lhs, loc::ConcreteInt(*x), resultTy);
+      }
+    }
+  }
+
+  // Delegate pointer arithmetic to the StoreManager.
+  return state->getStateManager().getStoreManager().EvalBinOp(op, lhs,
+                                                              rhs, resultTy);
+}
diff --git a/lib/Checker/Store.cpp b/lib/Checker/Store.cpp
new file mode 100644
index 0000000..c12065b
--- /dev/null
+++ b/lib/Checker/Store.cpp
@@ -0,0 +1,335 @@
+//== Store.cpp - Interface for maps from Locations to Values ----*- C++ -*--==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defined the types Store and StoreManager.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Checker/PathSensitive/Store.h"
+#include "clang/Checker/PathSensitive/GRState.h"
+#include "clang/AST/CharUnits.h"
+
+using namespace clang;
+
+StoreManager::StoreManager(GRStateManager &stateMgr)
+  : ValMgr(stateMgr.getValueManager()), StateMgr(stateMgr),
+    MRMgr(ValMgr.getRegionManager()), Ctx(stateMgr.getContext()) {}
+
+const MemRegion *StoreManager::MakeElementRegion(const MemRegion *Base,
+                                              QualType EleTy, uint64_t index) {
+  SVal idx = ValMgr.makeArrayIndex(index);
+  return MRMgr.getElementRegion(EleTy, idx, Base, ValMgr.getContext());
+}
+
+// FIXME: Merge with the implementation of the same method in MemRegion.cpp
+static bool IsCompleteType(ASTContext &Ctx, QualType Ty) {
+  if (const RecordType *RT = Ty->getAs<RecordType>()) {
+    const RecordDecl *D = RT->getDecl();
+    if (!D->getDefinition())
+      return false;
+  }
+
+  return true;
+}
+
+const ElementRegion *StoreManager::GetElementZeroRegion(const MemRegion *R, 
+                                                        QualType T) {
+  SVal idx = ValMgr.makeZeroArrayIndex();
+  assert(!T.isNull());
+  return MRMgr.getElementRegion(T, idx, R, Ctx);
+}
+
+const MemRegion *StoreManager::CastRegion(const MemRegion *R, QualType CastToTy) {
+
+  ASTContext& Ctx = StateMgr.getContext();
+
+  // Handle casts to Objective-C objects.
+  if (CastToTy->isObjCObjectPointerType())
+    return R->StripCasts();
+
+  if (CastToTy->isBlockPointerType()) {
+    // FIXME: We may need different solutions, depending on the symbol
+    // involved.  Blocks can be casted to/from 'id', as they can be treated
+    // as Objective-C objects.  This could possibly be handled by enhancing
+    // our reasoning of downcasts of symbolic objects.
+    if (isa<CodeTextRegion>(R) || isa<SymbolicRegion>(R))
+      return R;
+
+    // We don't know what to make of it.  Return a NULL region, which
+    // will be interpretted as UnknownVal.
+    return NULL;
+  }
+
+  // Now assume we are casting from pointer to pointer. Other cases should
+  // already be handled.
+  QualType PointeeTy = CastToTy->getAs<PointerType>()->getPointeeType();
+  QualType CanonPointeeTy = Ctx.getCanonicalType(PointeeTy);
+
+  // Handle casts to void*.  We just pass the region through.
+  if (CanonPointeeTy.getLocalUnqualifiedType() == Ctx.VoidTy)
+    return R;
+
+  // Handle casts from compatible types.
+  if (R->isBoundable())
+    if (const TypedRegion *TR = dyn_cast<TypedRegion>(R)) {
+      QualType ObjTy = Ctx.getCanonicalType(TR->getValueType(Ctx));
+      if (CanonPointeeTy == ObjTy)
+        return R;
+    }
+
+  // Process region cast according to the kind of the region being cast.
+  switch (R->getKind()) {
+    case MemRegion::CXXThisRegionKind:
+    case MemRegion::GenericMemSpaceRegionKind:
+    case MemRegion::StackLocalsSpaceRegionKind:
+    case MemRegion::StackArgumentsSpaceRegionKind:
+    case MemRegion::HeapSpaceRegionKind:
+    case MemRegion::UnknownSpaceRegionKind:
+    case MemRegion::GlobalsSpaceRegionKind: {
+      assert(0 && "Invalid region cast");
+      break;
+    }
+    
+    case MemRegion::FunctionTextRegionKind:
+    case MemRegion::BlockTextRegionKind:
+    case MemRegion::BlockDataRegionKind: {
+      // CodeTextRegion should be cast to only a function or block pointer type,
+      // although they can in practice be casted to anything, e.g, void*, char*,
+      // etc.  
+      // Just return the region.
+      return R;
+    }
+
+    case MemRegion::StringRegionKind:
+      // FIXME: Need to handle arbitrary downcasts.
+    case MemRegion::SymbolicRegionKind:
+    case MemRegion::AllocaRegionKind:
+    case MemRegion::CompoundLiteralRegionKind:
+    case MemRegion::FieldRegionKind:
+    case MemRegion::ObjCIvarRegionKind:
+    case MemRegion::VarRegionKind:
+    case MemRegion::CXXObjectRegionKind:
+      return MakeElementRegion(R, PointeeTy);
+
+    case MemRegion::ElementRegionKind: {
+      // If we are casting from an ElementRegion to another type, the
+      // algorithm is as follows:
+      //
+      // (1) Compute the "raw offset" of the ElementRegion from the
+      //     base region.  This is done by calling 'getAsRawOffset()'.
+      //
+      // (2a) If we get a 'RegionRawOffset' after calling
+      //      'getAsRawOffset()', determine if the absolute offset
+      //      can be exactly divided into chunks of the size of the
+      //      casted-pointee type.  If so, create a new ElementRegion with
+      //      the pointee-cast type as the new ElementType and the index
+      //      being the offset divded by the chunk size.  If not, create
+      //      a new ElementRegion at offset 0 off the raw offset region.
+      //
+      // (2b) If we don't a get a 'RegionRawOffset' after calling
+      //      'getAsRawOffset()', it means that we are at offset 0.
+      //
+      // FIXME: Handle symbolic raw offsets.
+
+      const ElementRegion *elementR = cast<ElementRegion>(R);
+      const RegionRawOffset &rawOff = elementR->getAsRawOffset();
+      const MemRegion *baseR = rawOff.getRegion();
+
+      // If we cannot compute a raw offset, throw up our hands and return
+      // a NULL MemRegion*.
+      if (!baseR)
+        return NULL;
+
+      CharUnits off = CharUnits::fromQuantity(rawOff.getByteOffset());
+
+      if (off.isZero()) {
+        // Edge case: we are at 0 bytes off the beginning of baseR.  We
+        // check to see if type we are casting to is the same as the base
+        // region.  If so, just return the base region.
+        if (const TypedRegion *TR = dyn_cast<TypedRegion>(baseR)) {
+          QualType ObjTy = Ctx.getCanonicalType(TR->getValueType(Ctx));
+          QualType CanonPointeeTy = Ctx.getCanonicalType(PointeeTy);
+          if (CanonPointeeTy == ObjTy)
+            return baseR;
+        }
+
+        // Otherwise, create a new ElementRegion at offset 0.
+        return MakeElementRegion(baseR, PointeeTy);
+      }
+
+      // We have a non-zero offset from the base region.  We want to determine
+      // if the offset can be evenly divided by sizeof(PointeeTy).  If so,
+      // we create an ElementRegion whose index is that value.  Otherwise, we
+      // create two ElementRegions, one that reflects a raw offset and the other
+      // that reflects the cast.
+
+      // Compute the index for the new ElementRegion.
+      int64_t newIndex = 0;
+      const MemRegion *newSuperR = 0;
+
+      // We can only compute sizeof(PointeeTy) if it is a complete type.
+      if (IsCompleteType(Ctx, PointeeTy)) {
+        // Compute the size in **bytes**.
+        CharUnits pointeeTySize = Ctx.getTypeSizeInChars(PointeeTy);
+        if (!pointeeTySize.isZero()) {
+          // Is the offset a multiple of the size?  If so, we can layer the
+          // ElementRegion (with elementType == PointeeTy) directly on top of
+          // the base region.
+          if (off % pointeeTySize == 0) {
+            newIndex = off / pointeeTySize;
+            newSuperR = baseR;
+          }
+        }
+      }
+
+      if (!newSuperR) {
+        // Create an intermediate ElementRegion to represent the raw byte.
+        // This will be the super region of the final ElementRegion.
+        newSuperR = MakeElementRegion(baseR, Ctx.CharTy, off.getQuantity());
+      }
+
+      return MakeElementRegion(newSuperR, PointeeTy, newIndex);
+    }
+  }
+
+  assert(0 && "unreachable");
+  return 0;
+}
+
+
+/// CastRetrievedVal - Used by subclasses of StoreManager to implement
+///  implicit casts that arise from loads from regions that are reinterpreted
+///  as another region.
+SVal StoreManager::CastRetrievedVal(SVal V, const TypedRegion *R,
+                                    QualType castTy, bool performTestOnly) {
+  
+  if (castTy.isNull())
+    return V;
+  
+  ASTContext &Ctx = ValMgr.getContext();
+
+  if (performTestOnly) {  
+    // Automatically translate references to pointers.
+    QualType T = R->getValueType(Ctx);
+    if (const ReferenceType *RT = T->getAs<ReferenceType>())
+      T = Ctx.getPointerType(RT->getPointeeType());
+    
+    assert(ValMgr.getContext().hasSameUnqualifiedType(castTy, T));
+    return V;
+  }
+  
+  if (const Loc *L = dyn_cast<Loc>(&V))
+    return ValMgr.getSValuator().EvalCastL(*L, castTy);
+  else if (const NonLoc *NL = dyn_cast<NonLoc>(&V))
+    return ValMgr.getSValuator().EvalCastNL(*NL, castTy);
+  
+  return V;
+}
+
+Store StoreManager::InvalidateRegions(Store store,
+                                      const MemRegion * const *I,
+                                      const MemRegion * const *End,
+                                      const Expr *E, unsigned Count,
+                                      InvalidatedSymbols *IS) {
+  for ( ; I != End ; ++I)
+    store = InvalidateRegion(store, *I, E, Count, IS);
+  
+  return store;
+}
+
+SVal StoreManager::getLValueFieldOrIvar(const Decl* D, SVal Base) {
+  if (Base.isUnknownOrUndef())
+    return Base;
+
+  Loc BaseL = cast<Loc>(Base);
+  const MemRegion* BaseR = 0;
+
+  switch (BaseL.getSubKind()) {
+  case loc::MemRegionKind:
+    BaseR = cast<loc::MemRegionVal>(BaseL).getRegion();
+    break;
+
+  case loc::GotoLabelKind:
+    // These are anormal cases. Flag an undefined value.
+    return UndefinedVal();
+
+  case loc::ConcreteIntKind:
+    // While these seem funny, this can happen through casts.
+    // FIXME: What we should return is the field offset.  For example,
+    //  add the field offset to the integer value.  That way funny things
+    //  like this work properly:  &(((struct foo *) 0xa)->f)
+    return Base;
+
+  default:
+    assert(0 && "Unhandled Base.");
+    return Base;
+  }
+
+  // NOTE: We must have this check first because ObjCIvarDecl is a subclass
+  // of FieldDecl.
+  if (const ObjCIvarDecl *ID = dyn_cast<ObjCIvarDecl>(D))
+    return loc::MemRegionVal(MRMgr.getObjCIvarRegion(ID, BaseR));
+
+  return loc::MemRegionVal(MRMgr.getFieldRegion(cast<FieldDecl>(D), BaseR));
+}
+
+SVal StoreManager::getLValueElement(QualType elementType, SVal Offset, 
+                                    SVal Base) {
+
+  // If the base is an unknown or undefined value, just return it back.
+  // FIXME: For absolute pointer addresses, we just return that value back as
+  //  well, although in reality we should return the offset added to that
+  //  value.
+  if (Base.isUnknownOrUndef() || isa<loc::ConcreteInt>(Base))
+    return Base;
+
+  // Only handle integer offsets... for now.
+  if (!isa<nonloc::ConcreteInt>(Offset))
+    return UnknownVal();
+
+  const MemRegion* BaseRegion = cast<loc::MemRegionVal>(Base).getRegion();
+
+  // Pointer of any type can be cast and used as array base.
+  const ElementRegion *ElemR = dyn_cast<ElementRegion>(BaseRegion);
+
+  // Convert the offset to the appropriate size and signedness.
+  Offset = ValMgr.convertToArrayIndex(Offset);
+
+  if (!ElemR) {
+    //
+    // If the base region is not an ElementRegion, create one.
+    // This can happen in the following example:
+    //
+    //   char *p = __builtin_alloc(10);
+    //   p[1] = 8;
+    //
+    //  Observe that 'p' binds to an AllocaRegion.
+    //
+    return loc::MemRegionVal(MRMgr.getElementRegion(elementType, Offset,
+                                                    BaseRegion, Ctx));
+  }
+
+  SVal BaseIdx = ElemR->getIndex();
+
+  if (!isa<nonloc::ConcreteInt>(BaseIdx))
+    return UnknownVal();
+
+  const llvm::APSInt& BaseIdxI = cast<nonloc::ConcreteInt>(BaseIdx).getValue();
+  const llvm::APSInt& OffI = cast<nonloc::ConcreteInt>(Offset).getValue();
+  assert(BaseIdxI.isSigned());
+
+  // Compute the new index.
+  SVal NewIdx = nonloc::ConcreteInt(
+                      ValMgr.getBasicValueFactory().getValue(BaseIdxI + OffI));
+
+  // Construct the new ElementRegion.
+  const MemRegion *ArrayR = ElemR->getSuperRegion();
+  return loc::MemRegionVal(MRMgr.getElementRegion(elementType, NewIdx, ArrayR,
+                                                  Ctx));
+}
diff --git a/lib/Checker/SymbolManager.cpp b/lib/Checker/SymbolManager.cpp
new file mode 100644
index 0000000..f3a803c
--- /dev/null
+++ b/lib/Checker/SymbolManager.cpp
@@ -0,0 +1,231 @@
+//== SymbolManager.h - Management of Symbolic Values ------------*- C++ -*--==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines SymbolManager, a class that manages symbolic values
+//  created for use by GRExprEngine and related classes.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Checker/PathSensitive/SymbolManager.h"
+#include "clang/Analysis/Analyses/LiveVariables.h"
+#include "clang/Checker/PathSensitive/MemRegion.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace clang;
+
+void SymExpr::dump() const {
+  dumpToStream(llvm::errs());
+}
+
+static void print(llvm::raw_ostream& os, BinaryOperator::Opcode Op) {
+  switch (Op) {
+    default:
+      assert(false && "operator printing not implemented");
+      break;
+    case BinaryOperator::Mul: os << '*'  ; break;
+    case BinaryOperator::Div: os << '/'  ; break;
+    case BinaryOperator::Rem: os << '%'  ; break;
+    case BinaryOperator::Add: os << '+'  ; break;
+    case BinaryOperator::Sub: os << '-'  ; break;
+    case BinaryOperator::Shl: os << "<<" ; break;
+    case BinaryOperator::Shr: os << ">>" ; break;
+    case BinaryOperator::LT:  os << "<"  ; break;
+    case BinaryOperator::GT:  os << '>'  ; break;
+    case BinaryOperator::LE:  os << "<=" ; break;
+    case BinaryOperator::GE:  os << ">=" ; break;
+    case BinaryOperator::EQ:  os << "==" ; break;
+    case BinaryOperator::NE:  os << "!=" ; break;
+    case BinaryOperator::And: os << '&'  ; break;
+    case BinaryOperator::Xor: os << '^'  ; break;
+    case BinaryOperator::Or:  os << '|'  ; break;
+  }
+}
+
+void SymIntExpr::dumpToStream(llvm::raw_ostream& os) const {
+  os << '(';
+  getLHS()->dumpToStream(os);
+  os << ") ";
+  print(os, getOpcode());
+  os << ' ' << getRHS().getZExtValue();
+  if (getRHS().isUnsigned()) os << 'U';
+}
+
+void SymSymExpr::dumpToStream(llvm::raw_ostream& os) const {
+  os << '(';
+  getLHS()->dumpToStream(os);
+  os << ") ";
+  os << '(';
+  getRHS()->dumpToStream(os);
+  os << ')';
+}
+
+void SymbolConjured::dumpToStream(llvm::raw_ostream& os) const {
+  os << "conj_$" << getSymbolID() << '{' << T.getAsString() << '}';
+}
+
+void SymbolDerived::dumpToStream(llvm::raw_ostream& os) const {
+  os << "derived_$" << getSymbolID() << '{'
+     << getParentSymbol() << ',' << getRegion() << '}';
+}
+
+void SymbolRegionValue::dumpToStream(llvm::raw_ostream& os) const {
+  os << "reg_$" << getSymbolID() << "<" << R << ">";
+}
+
+const SymbolRegionValue*
+SymbolManager::getRegionValueSymbol(const TypedRegion* R) {
+  llvm::FoldingSetNodeID profile;
+  SymbolRegionValue::Profile(profile, R);
+  void* InsertPos;
+  SymExpr *SD = DataSet.FindNodeOrInsertPos(profile, InsertPos);
+  if (!SD) {
+    SD = (SymExpr*) BPAlloc.Allocate<SymbolRegionValue>();
+    new (SD) SymbolRegionValue(SymbolCounter, R);
+    DataSet.InsertNode(SD, InsertPos);
+    ++SymbolCounter;
+  }
+
+  return cast<SymbolRegionValue>(SD);
+}
+
+const SymbolConjured*
+SymbolManager::getConjuredSymbol(const Stmt* E, QualType T, unsigned Count,
+                                 const void* SymbolTag) {
+
+  llvm::FoldingSetNodeID profile;
+  SymbolConjured::Profile(profile, E, T, Count, SymbolTag);
+  void* InsertPos;
+  SymExpr *SD = DataSet.FindNodeOrInsertPos(profile, InsertPos);
+  if (!SD) {
+    SD = (SymExpr*) BPAlloc.Allocate<SymbolConjured>();
+    new (SD) SymbolConjured(SymbolCounter, E, T, Count, SymbolTag);
+    DataSet.InsertNode(SD, InsertPos);
+    ++SymbolCounter;
+  }
+
+  return cast<SymbolConjured>(SD);
+}
+
+const SymbolDerived*
+SymbolManager::getDerivedSymbol(SymbolRef parentSymbol,
+                                const TypedRegion *R) {
+
+  llvm::FoldingSetNodeID profile;
+  SymbolDerived::Profile(profile, parentSymbol, R);
+  void* InsertPos;
+  SymExpr *SD = DataSet.FindNodeOrInsertPos(profile, InsertPos);
+  if (!SD) {
+    SD = (SymExpr*) BPAlloc.Allocate<SymbolDerived>();
+    new (SD) SymbolDerived(SymbolCounter, parentSymbol, R);
+    DataSet.InsertNode(SD, InsertPos);
+    ++SymbolCounter;
+  }
+
+  return cast<SymbolDerived>(SD);
+}
+
+const SymIntExpr *SymbolManager::getSymIntExpr(const SymExpr *lhs,
+                                               BinaryOperator::Opcode op,
+                                               const llvm::APSInt& v,
+                                               QualType t) {
+  llvm::FoldingSetNodeID ID;
+  SymIntExpr::Profile(ID, lhs, op, v, t);
+  void *InsertPos;
+  SymExpr *data = DataSet.FindNodeOrInsertPos(ID, InsertPos);
+
+  if (!data) {
+    data = (SymIntExpr*) BPAlloc.Allocate<SymIntExpr>();
+    new (data) SymIntExpr(lhs, op, v, t);
+    DataSet.InsertNode(data, InsertPos);
+  }
+
+  return cast<SymIntExpr>(data);
+}
+
+const SymSymExpr *SymbolManager::getSymSymExpr(const SymExpr *lhs,
+                                               BinaryOperator::Opcode op,
+                                               const SymExpr *rhs,
+                                               QualType t) {
+  llvm::FoldingSetNodeID ID;
+  SymSymExpr::Profile(ID, lhs, op, rhs, t);
+  void *InsertPos;
+  SymExpr *data = DataSet.FindNodeOrInsertPos(ID, InsertPos);
+
+  if (!data) {
+    data = (SymSymExpr*) BPAlloc.Allocate<SymSymExpr>();
+    new (data) SymSymExpr(lhs, op, rhs, t);
+    DataSet.InsertNode(data, InsertPos);
+  }
+
+  return cast<SymSymExpr>(data);
+}
+
+QualType SymbolConjured::getType(ASTContext&) const {
+  return T;
+}
+
+
+QualType SymbolDerived::getType(ASTContext& Ctx) const {
+  return R->getValueType(Ctx);
+}
+
+QualType SymbolRegionValue::getType(ASTContext& C) const {
+  return R->getValueType(C);
+}
+
+SymbolManager::~SymbolManager() {}
+
+bool SymbolManager::canSymbolicate(QualType T) {
+  return Loc::IsLocType(T) || (T->isIntegerType() && T->isScalarType());
+}
+
+void SymbolReaper::markLive(SymbolRef sym) {
+  TheLiving.insert(sym);
+  TheDead.erase(sym);
+}
+
+bool SymbolReaper::maybeDead(SymbolRef sym) {
+  if (isLive(sym))
+    return false;
+
+  TheDead.insert(sym);
+  return true;
+}
+
+bool SymbolReaper::isLive(SymbolRef sym) {
+  if (TheLiving.count(sym))
+    return true;
+
+  if (const SymbolDerived *derived = dyn_cast<SymbolDerived>(sym)) {
+    if (isLive(derived->getParentSymbol())) {
+      markLive(sym);
+      return true;
+    }
+    return false;
+  }
+
+  // Interogate the symbol.  It may derive from an input value to
+  // the analyzed function/method.
+  return isa<SymbolRegionValue>(sym);
+}
+
+bool SymbolReaper::isLive(const Stmt* Loc, const Stmt* ExprVal) const {
+  return LCtx->getLiveVariables()->isLive(Loc, ExprVal);
+}
+
+bool SymbolReaper::isLive(const Stmt *Loc, const VarRegion *VR) const {
+  const StackFrameContext *SFC = VR->getStackFrame();
+
+  if (SFC == LCtx->getCurrentStackFrame())
+    return LCtx->getLiveVariables()->isLive(Loc, VR->getDecl());
+  else
+    return SFC->isParentOf(LCtx->getCurrentStackFrame());
+}
+
+SymbolVisitor::~SymbolVisitor() {}
diff --git a/lib/Checker/UndefBranchChecker.cpp b/lib/Checker/UndefBranchChecker.cpp
new file mode 100644
index 0000000..9088345
--- /dev/null
+++ b/lib/Checker/UndefBranchChecker.cpp
@@ -0,0 +1,118 @@
+//=== UndefBranchChecker.cpp -----------------------------------*- C++ -*--===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines UndefBranchChecker, which checks for undefined branch
+// condition.
+//
+//===----------------------------------------------------------------------===//
+
+#include "GRExprEngineInternalChecks.h"
+#include "clang/Checker/BugReporter/BugType.h"
+#include "clang/Checker/PathSensitive/Checker.h"
+
+using namespace clang;
+
+namespace {
+
+class UndefBranchChecker : public Checker {
+  BuiltinBug *BT;
+
+  struct FindUndefExpr {
+    GRStateManager& VM;
+    const GRState* St;
+
+    FindUndefExpr(GRStateManager& V, const GRState* S) : VM(V), St(S) {}
+
+    Expr* FindExpr(Expr* Ex) {
+      if (!MatchesCriteria(Ex))
+        return 0;
+
+      for (Stmt::child_iterator I=Ex->child_begin(), E=Ex->child_end();I!=E;++I)
+        if (Expr* ExI = dyn_cast_or_null<Expr>(*I)) {
+          Expr* E2 = FindExpr(ExI);
+          if (E2) return E2;
+        }
+
+      return Ex;
+    }
+
+    bool MatchesCriteria(Expr* Ex) { return St->getSVal(Ex).isUndef(); }
+  };
+
+public:
+  UndefBranchChecker() : BT(0) {}
+  static void *getTag();
+  void VisitBranchCondition(GRBranchNodeBuilder &Builder, GRExprEngine &Eng,
+                            Stmt *Condition, void *tag);
+};
+
+}
+
+void clang::RegisterUndefBranchChecker(GRExprEngine &Eng) {
+  Eng.registerCheck(new UndefBranchChecker());
+}
+
+void *UndefBranchChecker::getTag() {
+  static int x;
+  return &x;
+}
+
+void UndefBranchChecker::VisitBranchCondition(GRBranchNodeBuilder &Builder, 
+                                              GRExprEngine &Eng,
+                                              Stmt *Condition, void *tag) {
+  const GRState *state = Builder.getState();
+  SVal X = state->getSVal(Condition);
+  if (X.isUndef()) {
+    ExplodedNode *N = Builder.generateNode(state, true);
+    if (N) {
+      N->markAsSink();
+      if (!BT)
+        BT = new BuiltinBug("Branch condition evaluates to a garbage value");
+
+      // What's going on here: we want to highlight the subexpression of the
+      // condition that is the most likely source of the "uninitialized
+      // branch condition."  We do a recursive walk of the condition's
+      // subexpressions and roughly look for the most nested subexpression
+      // that binds to Undefined.  We then highlight that expression's range.
+      BlockEdge B = cast<BlockEdge>(N->getLocation());
+      Expr* Ex = cast<Expr>(B.getSrc()->getTerminatorCondition());
+      assert (Ex && "Block must have a terminator.");
+
+      // Get the predecessor node and check if is a PostStmt with the Stmt
+      // being the terminator condition.  We want to inspect the state
+      // of that node instead because it will contain main information about
+      // the subexpressions.
+      assert (!N->pred_empty());
+
+      // Note: any predecessor will do.  They should have identical state,
+      // since all the BlockEdge did was act as an error sink since the value
+      // had to already be undefined.
+      ExplodedNode *PrevN = *N->pred_begin();
+      ProgramPoint P = PrevN->getLocation();
+      const GRState* St = N->getState();
+
+      if (PostStmt* PS = dyn_cast<PostStmt>(&P))
+        if (PS->getStmt() == Ex)
+          St = PrevN->getState();
+
+      FindUndefExpr FindIt(Eng.getStateManager(), St);
+      Ex = FindIt.FindExpr(Ex);
+
+      // Emit the bug report.
+      EnhancedBugReport *R = new EnhancedBugReport(*BT, BT->getDescription(),N);
+      R->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue, Ex);
+      R->addRange(Ex->getSourceRange());
+
+      Eng.getBugReporter().EmitReport(R);
+    }
+
+    Builder.markInfeasible(true);
+    Builder.markInfeasible(false);
+  }
+}
diff --git a/lib/Checker/UndefCapturedBlockVarChecker.cpp b/lib/Checker/UndefCapturedBlockVarChecker.cpp
new file mode 100644
index 0000000..b1010c9
--- /dev/null
+++ b/lib/Checker/UndefCapturedBlockVarChecker.cpp
@@ -0,0 +1,101 @@
+// UndefCapturedBlockVarChecker.cpp - Uninitialized captured vars -*- C++ -*-=//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This checker detects blocks that capture uninitialized values.
+//
+//===----------------------------------------------------------------------===//
+
+#include "GRExprEngineInternalChecks.h"
+#include "clang/Checker/PathSensitive/CheckerVisitor.h"
+#include "clang/Checker/PathSensitive/GRExprEngine.h"
+#include "clang/Checker/BugReporter/BugType.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace clang;
+
+namespace {
+class UndefCapturedBlockVarChecker
+  : public CheckerVisitor<UndefCapturedBlockVarChecker> {
+ BugType *BT;
+
+public:
+  UndefCapturedBlockVarChecker() : BT(0) {}
+  static void *getTag() { static int tag = 0; return &tag; }
+  void PostVisitBlockExpr(CheckerContext &C, const BlockExpr *BE);
+};
+} // end anonymous namespace
+
+void clang::RegisterUndefCapturedBlockVarChecker(GRExprEngine &Eng) {
+  Eng.registerCheck(new UndefCapturedBlockVarChecker());
+}
+
+static const BlockDeclRefExpr *FindBlockDeclRefExpr(const Stmt *S,
+                                                    const VarDecl *VD){
+  if (const BlockDeclRefExpr *BR = dyn_cast<BlockDeclRefExpr>(S))
+    if (BR->getDecl() == VD)
+      return BR;
+
+  for (Stmt::const_child_iterator I = S->child_begin(), E = S->child_end();
+       I!=E; ++I)
+    if (const Stmt *child = *I) {
+      const BlockDeclRefExpr *BR = FindBlockDeclRefExpr(child, VD);
+      if (BR)
+        return BR;
+    }
+
+  return NULL;
+}
+
+void
+UndefCapturedBlockVarChecker::PostVisitBlockExpr(CheckerContext &C,
+                                                 const BlockExpr *BE) {
+  if (!BE->hasBlockDeclRefExprs())
+    return;
+
+  const GRState *state = C.getState();
+  const BlockDataRegion *R =
+    cast<BlockDataRegion>(state->getSVal(BE).getAsRegion());
+
+  BlockDataRegion::referenced_vars_iterator I = R->referenced_vars_begin(),
+                                            E = R->referenced_vars_end();
+
+  for (; I != E; ++I) {
+    // This VarRegion is the region associated with the block; we need
+    // the one associated with the encompassing context.
+    const VarRegion *VR = *I;
+    const VarDecl *VD = VR->getDecl();
+
+    if (VD->getAttr<BlocksAttr>() || !VD->hasLocalStorage())
+      continue;
+
+    // Get the VarRegion associated with VD in the local stack frame.
+    const LocationContext *LC = C.getPredecessor()->getLocationContext();
+    VR = C.getValueManager().getRegionManager().getVarRegion(VD, LC);
+
+    if (state->getSVal(VR).isUndef())
+      if (ExplodedNode *N = C.GenerateSink()) {
+        if (!BT)
+          BT = new BuiltinBug("Captured block variable is uninitialized");
+
+        // Generate a bug report.
+        llvm::SmallString<128> buf;
+        llvm::raw_svector_ostream os(buf);
+
+        os << "Variable '" << VD->getName() << "' is captured by block with "
+              "a garbage value";
+
+        EnhancedBugReport *R = new EnhancedBugReport(*BT, os.str(), N);
+        if (const Expr *Ex = FindBlockDeclRefExpr(BE->getBody(), VD))
+          R->addRange(Ex->getSourceRange());
+        R->addVisitorCreator(bugreporter::registerFindLastStore, VR);
+        // need location of block
+        C.EmitReport(R);
+      }
+  }
+}
diff --git a/lib/Checker/UndefResultChecker.cpp b/lib/Checker/UndefResultChecker.cpp
new file mode 100644
index 0000000..8b07aed
--- /dev/null
+++ b/lib/Checker/UndefResultChecker.cpp
@@ -0,0 +1,86 @@
+//=== UndefResultChecker.cpp ------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This defines UndefResultChecker, a builtin check in GRExprEngine that 
+// performs checks for undefined results of non-assignment binary operators.
+//
+//===----------------------------------------------------------------------===//
+
+#include "GRExprEngineInternalChecks.h"
+#include "clang/Checker/BugReporter/BugType.h"
+#include "clang/Checker/PathSensitive/CheckerVisitor.h"
+#include "clang/Checker/PathSensitive/GRExprEngine.h"
+
+using namespace clang;
+
+namespace {
+class UndefResultChecker 
+  : public CheckerVisitor<UndefResultChecker> {
+
+  BugType *BT;
+  
+public:
+  UndefResultChecker() : BT(0) {}
+  static void *getTag() { static int tag = 0; return &tag; }
+  void PostVisitBinaryOperator(CheckerContext &C, const BinaryOperator *B);
+};
+} // end anonymous namespace
+
+void clang::RegisterUndefResultChecker(GRExprEngine &Eng) {
+  Eng.registerCheck(new UndefResultChecker());
+}
+
+void UndefResultChecker::PostVisitBinaryOperator(CheckerContext &C, 
+                                                 const BinaryOperator *B) {
+  const GRState *state = C.getState();
+  if (state->getSVal(B).isUndef()) {
+    // Generate an error node.
+    ExplodedNode *N = C.GenerateSink();
+    if (!N)
+      return;
+    
+    if (!BT)
+      BT = new BuiltinBug("Result of operation is garbage or undefined");
+
+    llvm::SmallString<256> sbuf;
+    llvm::raw_svector_ostream OS(sbuf);
+    const Expr *Ex = NULL;
+    bool isLeft = true;
+    
+    if (state->getSVal(B->getLHS()).isUndef()) {
+      Ex = B->getLHS()->IgnoreParenCasts();
+      isLeft = true;
+    }
+    else if (state->getSVal(B->getRHS()).isUndef()) {
+      Ex = B->getRHS()->IgnoreParenCasts();
+      isLeft = false;
+    }
+    
+    if (Ex) {
+      OS << "The " << (isLeft ? "left" : "right")
+         << " operand of '"
+         << BinaryOperator::getOpcodeStr(B->getOpcode())
+         << "' is a garbage value";
+    }          
+    else {
+      // Neither operand was undefined, but the result is undefined.
+      OS << "The result of the '"
+         << BinaryOperator::getOpcodeStr(B->getOpcode())
+         << "' expression is undefined";
+    }
+    EnhancedBugReport *report = new EnhancedBugReport(*BT, OS.str(), N);
+    if (Ex) {
+      report->addRange(Ex->getSourceRange());
+      report->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue, Ex);
+    }
+    else
+      report->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue, B);
+    C.EmitReport(report);
+  }
+}
diff --git a/lib/Checker/UndefinedArraySubscriptChecker.cpp b/lib/Checker/UndefinedArraySubscriptChecker.cpp
new file mode 100644
index 0000000..148629e
--- /dev/null
+++ b/lib/Checker/UndefinedArraySubscriptChecker.cpp
@@ -0,0 +1,56 @@
+//===--- UndefinedArraySubscriptChecker.h ----------------------*- C++ -*--===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This defines UndefinedArraySubscriptChecker, a builtin check in GRExprEngine
+// that performs checks for undefined array subscripts.
+//
+//===----------------------------------------------------------------------===//
+
+#include "GRExprEngineInternalChecks.h"
+#include "clang/Checker/BugReporter/BugType.h"
+#include "clang/Checker/PathSensitive/CheckerVisitor.h"
+
+using namespace clang;
+
+namespace {
+class UndefinedArraySubscriptChecker
+  : public CheckerVisitor<UndefinedArraySubscriptChecker> {
+  BugType *BT;
+public:
+  UndefinedArraySubscriptChecker() : BT(0) {}
+  static void *getTag() {
+    static int x = 0;
+    return &x;
+  }
+  void PreVisitArraySubscriptExpr(CheckerContext &C, 
+                                  const ArraySubscriptExpr *A);
+};
+} // end anonymous namespace
+
+void clang::RegisterUndefinedArraySubscriptChecker(GRExprEngine &Eng) {
+  Eng.registerCheck(new UndefinedArraySubscriptChecker());
+}
+
+void 
+UndefinedArraySubscriptChecker::PreVisitArraySubscriptExpr(CheckerContext &C, 
+                                                const ArraySubscriptExpr *A) {
+  if (C.getState()->getSVal(A->getIdx()).isUndef()) {
+    if (ExplodedNode *N = C.GenerateSink()) {
+      if (!BT)
+        BT = new BuiltinBug("Array subscript is undefined");
+
+      // Generate a report for this bug.
+      EnhancedBugReport *R = new EnhancedBugReport(*BT, BT->getName(), N);
+      R->addRange(A->getIdx()->getSourceRange());
+      R->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue, 
+                           A->getIdx());
+      C.EmitReport(R);
+    }
+  }
+}
diff --git a/lib/Checker/UndefinedAssignmentChecker.cpp b/lib/Checker/UndefinedAssignmentChecker.cpp
new file mode 100644
index 0000000..6cef60e
--- /dev/null
+++ b/lib/Checker/UndefinedAssignmentChecker.cpp
@@ -0,0 +1,95 @@
+//===--- UndefinedAssignmentChecker.h ---------------------------*- C++ -*--==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This defines UndefinedAssginmentChecker, a builtin check in GRExprEngine that
+// checks for assigning undefined values.
+//
+//===----------------------------------------------------------------------===//
+
+#include "GRExprEngineInternalChecks.h"
+#include "clang/Checker/BugReporter/BugType.h"
+#include "clang/Checker/PathSensitive/CheckerVisitor.h"
+
+using namespace clang;
+
+namespace {
+class UndefinedAssignmentChecker
+  : public CheckerVisitor<UndefinedAssignmentChecker> {
+  BugType *BT;
+public:
+  UndefinedAssignmentChecker() : BT(0) {}
+  static void *getTag();
+  virtual void PreVisitBind(CheckerContext &C, const Stmt *AssignE,
+                            const Stmt *StoreE, SVal location,
+                            SVal val);
+};
+}
+
+void clang::RegisterUndefinedAssignmentChecker(GRExprEngine &Eng){
+  Eng.registerCheck(new UndefinedAssignmentChecker());
+}
+
+void *UndefinedAssignmentChecker::getTag() {
+  static int x = 0;
+  return &x;
+}
+
+void UndefinedAssignmentChecker::PreVisitBind(CheckerContext &C,
+                                              const Stmt *AssignE,
+                                              const Stmt *StoreE,
+                                              SVal location,
+                                              SVal val) {
+  if (!val.isUndef())
+    return;
+
+  ExplodedNode *N = C.GenerateSink();
+
+  if (!N)
+    return;
+
+  const char *str = "Assigned value is garbage or undefined";
+
+  if (!BT)
+    BT = new BuiltinBug(str);
+
+  // Generate a report for this bug.
+  const Expr *ex = 0;
+
+  while (AssignE) {
+    if (const BinaryOperator *B = dyn_cast<BinaryOperator>(AssignE)) {
+      if (B->isCompoundAssignmentOp()) {
+        const GRState *state = C.getState();
+        if (state->getSVal(B->getLHS()).isUndef()) {
+          str = "The left expression of the compound assignment is an "
+                "uninitialized value. The computed value will also be garbage";
+          ex = B->getLHS();
+          break;
+        }
+      }
+
+      ex = B->getRHS();
+      break;
+    }
+
+    if (const DeclStmt *DS = dyn_cast<DeclStmt>(AssignE)) {
+      const VarDecl* VD = dyn_cast<VarDecl>(DS->getSingleDecl());
+      ex = VD->getInit();
+    }
+
+    break;
+  }
+
+  EnhancedBugReport *R = new EnhancedBugReport(*BT, str, N);
+  if (ex) {
+    R->addRange(ex->getSourceRange());
+    R->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue, ex);
+  }
+  C.EmitReport(R);
+}
+
diff --git a/lib/Checker/UnixAPIChecker.cpp b/lib/Checker/UnixAPIChecker.cpp
new file mode 100644
index 0000000..e9b8f09
--- /dev/null
+++ b/lib/Checker/UnixAPIChecker.cpp
@@ -0,0 +1,222 @@
+//= UnixAPIChecker.h - Checks preconditions for various Unix APIs --*- C++ -*-//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This defines UnixAPIChecker, which is an assortment of checks on calls
+// to various, widely used UNIX/Posix functions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "GRExprEngineInternalChecks.h"
+#include "clang/Basic/TargetInfo.h"
+#include "clang/Checker/BugReporter/BugType.h"
+#include "clang/Checker/PathSensitive/CheckerVisitor.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/StringSwitch.h"
+#include <fcntl.h>
+
+using namespace clang;
+using llvm::Optional;
+
+namespace {
+class UnixAPIChecker : public CheckerVisitor<UnixAPIChecker> {
+  enum SubChecks {
+    OpenFn = 0,
+    PthreadOnceFn = 1,
+    NumChecks
+  };
+
+  BugType *BTypes[NumChecks];
+
+public:
+  Optional<uint64_t> Val_O_CREAT;
+
+public:
+  UnixAPIChecker() { memset(BTypes, 0, sizeof(*BTypes) * NumChecks); }
+  static void *getTag() { static unsigned tag = 0; return &tag; }
+
+  void PreVisitCallExpr(CheckerContext &C, const CallExpr *CE);
+};
+} //end anonymous namespace
+
+void clang::RegisterUnixAPIChecker(GRExprEngine &Eng) {
+  Eng.registerCheck(new UnixAPIChecker());
+}
+
+//===----------------------------------------------------------------------===//
+// Utility functions.
+//===----------------------------------------------------------------------===//
+
+static inline void LazyInitialize(BugType *&BT, const char *name) {
+  if (BT)
+    return;
+  BT = new BugType(name, "Unix API");
+}
+
+//===----------------------------------------------------------------------===//
+// "open" (man 2 open)
+//===----------------------------------------------------------------------===//
+
+static void CheckOpen(CheckerContext &C, UnixAPIChecker &UC,
+                      const CallExpr *CE, BugType *&BT) {
+  // The definition of O_CREAT is platform specific.  We need a better way
+  // of querying this information from the checking environment.
+  if (!UC.Val_O_CREAT.hasValue()) {
+    if (C.getASTContext().Target.getTriple().getVendor() == llvm::Triple::Apple)
+      UC.Val_O_CREAT = 0x0200;
+    else {
+      // FIXME: We need a more general way of getting the O_CREAT value.
+      // We could possibly grovel through the preprocessor state, but
+      // that would require passing the Preprocessor object to the GRExprEngine.
+      return;
+    }
+  }
+
+  LazyInitialize(BT, "Improper use of 'open'");
+
+  // Look at the 'oflags' argument for the O_CREAT flag.
+  const GRState *state = C.getState();
+
+  if (CE->getNumArgs() < 2) {
+    // The frontend should issue a warning for this case, so this is a sanity
+    // check.
+    return;
+  }
+
+  // Now check if oflags has O_CREAT set.
+  const Expr *oflagsEx = CE->getArg(1);
+  const SVal V = state->getSVal(oflagsEx);
+  if (!isa<NonLoc>(V)) {
+    // The case where 'V' can be a location can only be due to a bad header,
+    // so in this case bail out.
+    return;
+  }
+  NonLoc oflags = cast<NonLoc>(V);
+  NonLoc ocreateFlag =
+    cast<NonLoc>(C.getValueManager().makeIntVal(UC.Val_O_CREAT.getValue(),
+                                                oflagsEx->getType()));
+  SVal maskedFlagsUC = C.getSValuator().EvalBinOpNN(state, BinaryOperator::And,
+                                                    oflags, ocreateFlag,
+                                                    oflagsEx->getType());
+  if (maskedFlagsUC.isUnknownOrUndef())
+    return;
+  DefinedSVal maskedFlags = cast<DefinedSVal>(maskedFlagsUC);
+
+  // Check if maskedFlags is non-zero.
+  const GRState *trueState, *falseState;
+  llvm::tie(trueState, falseState) = state->Assume(maskedFlags);
+
+  // Only emit an error if the value of 'maskedFlags' is properly
+  // constrained;
+  if (!(trueState && !falseState))
+    return;
+
+  if (CE->getNumArgs() < 3) {
+    ExplodedNode *N = C.GenerateSink(trueState);
+    if (!N)
+      return;
+
+    EnhancedBugReport *report =
+      new EnhancedBugReport(*BT,
+                            "Call to 'open' requires a third argument when "
+                            "the 'O_CREAT' flag is set", N);
+    report->addRange(oflagsEx->getSourceRange());
+    C.EmitReport(report);
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// pthread_once
+//===----------------------------------------------------------------------===//
+
+static void CheckPthreadOnce(CheckerContext &C, UnixAPIChecker &,
+                             const CallExpr *CE, BugType *&BT) {
+
+  // This is similar to 'CheckDispatchOnce' in the MacOSXAPIChecker.
+  // They can possibly be refactored.
+
+  LazyInitialize(BT, "Improper use of 'pthread_once'");
+
+  if (CE->getNumArgs() < 1)
+    return;
+
+  // Check if the first argument is stack allocated.  If so, issue a warning
+  // because that's likely to be bad news.
+  const GRState *state = C.getState();
+  const MemRegion *R = state->getSVal(CE->getArg(0)).getAsRegion();
+  if (!R || !isa<StackSpaceRegion>(R->getMemorySpace()))
+    return;
+
+  ExplodedNode *N = C.GenerateSink(state);
+  if (!N)
+    return;
+
+  llvm::SmallString<256> S;
+  llvm::raw_svector_ostream os(S);
+  os << "Call to 'pthread_once' uses";
+  if (const VarRegion *VR = dyn_cast<VarRegion>(R))
+    os << " the local variable '" << VR->getDecl()->getName() << '\'';
+  else
+    os << " stack allocated memory";
+  os << " for the \"control\" value.  Using such transient memory for "
+  "the control value is potentially dangerous.";
+  if (isa<VarRegion>(R) && isa<StackLocalsSpaceRegion>(R->getMemorySpace()))
+    os << "  Perhaps you intended to declare the variable as 'static'?";
+
+  EnhancedBugReport *report = new EnhancedBugReport(*BT, os.str(), N);
+  report->addRange(CE->getArg(0)->getSourceRange());
+  C.EmitReport(report);
+}
+
+//===----------------------------------------------------------------------===//
+// Central dispatch function.
+//===----------------------------------------------------------------------===//
+
+typedef void (*SubChecker)(CheckerContext &C, UnixAPIChecker &UC,
+                           const CallExpr *CE, BugType *&BT);
+namespace {
+  class SubCheck {
+    SubChecker SC;
+    UnixAPIChecker *UC;
+    BugType **BT;
+  public:
+    SubCheck(SubChecker sc, UnixAPIChecker *uc, BugType *& bt) : SC(sc), UC(uc),
+      BT(&bt) {}
+    SubCheck() : SC(NULL), UC(NULL), BT(NULL) {}
+
+    void run(CheckerContext &C, const CallExpr *CE) const {
+      if (SC)
+        SC(C, *UC, CE, *BT);
+    }
+  };
+} // end anonymous namespace
+
+void UnixAPIChecker::PreVisitCallExpr(CheckerContext &C, const CallExpr *CE) {
+  // Get the callee.  All the functions we care about are C functions
+  // with simple identifiers.
+  const GRState *state = C.getState();
+  const Expr *Callee = CE->getCallee();
+  const FunctionTextRegion *Fn =
+    dyn_cast_or_null<FunctionTextRegion>(state->getSVal(Callee).getAsRegion());
+
+  if (!Fn)
+    return;
+
+  const IdentifierInfo *FI = Fn->getDecl()->getIdentifier();
+  if (!FI)
+    return;
+
+  const SubCheck &SC =
+    llvm::StringSwitch<SubCheck>(FI->getName())
+      .Case("open", SubCheck(CheckOpen, this, BTypes[OpenFn]))
+      .Case("pthread_once", SubCheck(CheckPthreadOnce, this,
+                                     BTypes[PthreadOnceFn]))
+      .Default(SubCheck());
+
+  SC.run(C, CE);
+}
diff --git a/lib/Checker/VLASizeChecker.cpp b/lib/Checker/VLASizeChecker.cpp
new file mode 100644
index 0000000..cea9d19
--- /dev/null
+++ b/lib/Checker/VLASizeChecker.cpp
@@ -0,0 +1,96 @@
+//=== VLASizeChecker.cpp - Undefined dereference checker --------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This defines VLASizeChecker, a builtin check in GRExprEngine that 
+// performs checks for declaration of VLA of undefined or zero size.
+//
+//===----------------------------------------------------------------------===//
+
+#include "GRExprEngineInternalChecks.h"
+#include "clang/Checker/BugReporter/BugType.h"
+#include "clang/Checker/PathSensitive/CheckerVisitor.h"
+#include "clang/Checker/PathSensitive/GRExprEngine.h"
+
+using namespace clang;
+
+namespace {
+class VLASizeChecker : public CheckerVisitor<VLASizeChecker> {
+  BugType *BT_zero;
+  BugType *BT_undef;
+  
+public:
+  VLASizeChecker() : BT_zero(0), BT_undef(0) {}
+  static void *getTag() { static int tag = 0; return &tag; }
+  void PreVisitDeclStmt(CheckerContext &C, const DeclStmt *DS);
+};
+} // end anonymous namespace
+
+void clang::RegisterVLASizeChecker(GRExprEngine &Eng) {
+  Eng.registerCheck(new VLASizeChecker());
+}
+
+void VLASizeChecker::PreVisitDeclStmt(CheckerContext &C, const DeclStmt *DS) {
+  if (!DS->isSingleDecl())
+    return;
+  
+  const VarDecl *VD = dyn_cast<VarDecl>(DS->getSingleDecl());
+  if (!VD)
+    return;
+  
+  const VariableArrayType *VLA
+    = C.getASTContext().getAsVariableArrayType(VD->getType());
+  if (!VLA)
+    return;
+
+  // FIXME: Handle multi-dimensional VLAs.
+  const Expr* SE = VLA->getSizeExpr();
+  const GRState *state = C.getState();
+  SVal sizeV = state->getSVal(SE);
+
+  if (sizeV.isUndef()) {
+    // Generate an error node.
+    ExplodedNode *N = C.GenerateSink();
+    if (!N)
+      return;
+    
+    if (!BT_undef)
+      BT_undef = new BuiltinBug("Declared variable-length array (VLA) uses a "
+                                "garbage value as its size");
+
+    EnhancedBugReport *report =
+      new EnhancedBugReport(*BT_undef, BT_undef->getName(), N);
+    report->addRange(SE->getSourceRange());
+    report->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue, SE);
+    C.EmitReport(report);
+    return;
+  }
+  
+  // Check if the size is zero.
+  DefinedOrUnknownSVal sizeD = cast<DefinedOrUnknownSVal>(sizeV);
+
+  const GRState *stateNotZero, *stateZero;
+  llvm::tie(stateNotZero, stateZero) = state->Assume(sizeD);
+
+  if (stateZero && !stateNotZero) {
+    ExplodedNode* N = C.GenerateSink(stateZero);
+    if (!BT_zero)
+      BT_zero = new BuiltinBug("Declared variable-length array (VLA) has zero "
+                               "size");
+
+    EnhancedBugReport *report =
+      new EnhancedBugReport(*BT_zero, BT_zero->getName(), N);
+    report->addRange(SE->getSourceRange());
+    report->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue, SE);
+    C.EmitReport(report);
+    return;
+  }
+ 
+  // From this point on, assume that the size is not zero.
+  C.addTransition(stateNotZero);
+}
diff --git a/lib/Checker/ValueManager.cpp b/lib/Checker/ValueManager.cpp
new file mode 100644
index 0000000..aa0c3c8
--- /dev/null
+++ b/lib/Checker/ValueManager.cpp
@@ -0,0 +1,149 @@
+//== ValueManager.cpp - Aggregate manager of symbols and SVals --*- C++ -*--==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines ValueManager, a class that manages symbolic values
+//  and SVals created for use by GRExprEngine and related classes.  It
+//  wraps and owns SymbolManager, MemRegionManager, and BasicValueFactory.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Checker/PathSensitive/ValueManager.h"
+#include "clang/Analysis/AnalysisContext.h"
+
+using namespace clang;
+using namespace llvm;
+
+//===----------------------------------------------------------------------===//
+// Utility methods for constructing SVals.
+//===----------------------------------------------------------------------===//
+
+DefinedOrUnknownSVal ValueManager::makeZeroVal(QualType T) {
+  if (Loc::IsLocType(T))
+    return makeNull();
+
+  if (T->isIntegerType())
+    return makeIntVal(0, T);
+
+  // FIXME: Handle floats.
+  // FIXME: Handle structs.
+  return UnknownVal();
+}
+
+//===----------------------------------------------------------------------===//
+// Utility methods for constructing Non-Locs.
+//===----------------------------------------------------------------------===//
+
+NonLoc ValueManager::makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op,
+                                const APSInt& v, QualType T) {
+  // The Environment ensures we always get a persistent APSInt in
+  // BasicValueFactory, so we don't need to get the APSInt from
+  // BasicValueFactory again.
+  assert(!Loc::IsLocType(T));
+  return nonloc::SymExprVal(SymMgr.getSymIntExpr(lhs, op, v, T));
+}
+
+NonLoc ValueManager::makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op,
+                                const SymExpr *rhs, QualType T) {
+  assert(SymMgr.getType(lhs) == SymMgr.getType(rhs));
+  assert(!Loc::IsLocType(T));
+  return nonloc::SymExprVal(SymMgr.getSymSymExpr(lhs, op, rhs, T));
+}
+
+
+SVal ValueManager::convertToArrayIndex(SVal V) {
+  if (V.isUnknownOrUndef())
+    return V;
+
+  // Common case: we have an appropriately sized integer.
+  if (nonloc::ConcreteInt* CI = dyn_cast<nonloc::ConcreteInt>(&V)) {
+    const llvm::APSInt& I = CI->getValue();
+    if (I.getBitWidth() == ArrayIndexWidth && I.isSigned())
+      return V;
+  }
+
+  return SVator->EvalCastNL(cast<NonLoc>(V), ArrayIndexTy);
+}
+
+DefinedOrUnknownSVal 
+ValueManager::getRegionValueSymbolVal(const TypedRegion* R) {
+  QualType T = R->getValueType(SymMgr.getContext());
+
+  if (!SymbolManager::canSymbolicate(T))
+    return UnknownVal();
+
+  SymbolRef sym = SymMgr.getRegionValueSymbol(R);
+
+  if (Loc::IsLocType(T))
+    return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym));
+
+  return nonloc::SymbolVal(sym);
+}
+
+DefinedOrUnknownSVal ValueManager::getConjuredSymbolVal(const void *SymbolTag,
+                                                        const Expr *E,
+                                                        unsigned Count) {
+  QualType T = E->getType();
+
+  if (!SymbolManager::canSymbolicate(T))
+    return UnknownVal();
+
+  SymbolRef sym = SymMgr.getConjuredSymbol(E, Count, SymbolTag);
+
+  if (Loc::IsLocType(T))
+    return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym));
+
+  return nonloc::SymbolVal(sym);
+}
+
+DefinedOrUnknownSVal ValueManager::getConjuredSymbolVal(const void *SymbolTag,
+                                                        const Expr *E,
+                                                        QualType T,
+                                                        unsigned Count) {
+  
+  if (!SymbolManager::canSymbolicate(T))
+    return UnknownVal();
+
+  SymbolRef sym = SymMgr.getConjuredSymbol(E, T, Count, SymbolTag);
+
+  if (Loc::IsLocType(T))
+    return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym));
+
+  return nonloc::SymbolVal(sym);
+}
+
+
+DefinedOrUnknownSVal
+ValueManager::getDerivedRegionValueSymbolVal(SymbolRef parentSymbol,
+                                             const TypedRegion *R) {
+  QualType T = R->getValueType(R->getContext());
+
+  if (!SymbolManager::canSymbolicate(T))
+    return UnknownVal();
+
+  SymbolRef sym = SymMgr.getDerivedSymbol(parentSymbol, R);
+
+  if (Loc::IsLocType(T))
+    return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym));
+
+  return nonloc::SymbolVal(sym);
+}
+
+DefinedSVal ValueManager::getFunctionPointer(const FunctionDecl* FD) {
+  return loc::MemRegionVal(MemMgr.getFunctionTextRegion(FD));
+}
+
+DefinedSVal ValueManager::getBlockPointer(const BlockDecl *D,
+                                          CanQualType locTy,
+                                          const LocationContext *LC) {
+  const BlockTextRegion *BC =
+    MemMgr.getBlockTextRegion(D, locTy, LC->getAnalysisContext());
+  const BlockDataRegion *BD = MemMgr.getBlockDataRegion(BC, LC);
+  return loc::MemRegionVal(BD);
+}
+
diff --git a/lib/CodeGen/ABIInfo.h b/lib/CodeGen/ABIInfo.h
new file mode 100644
index 0000000..1ab2f55
--- /dev/null
+++ b/lib/CodeGen/ABIInfo.h
@@ -0,0 +1,153 @@
+//===----- ABIInfo.h - ABI information access & encapsulation ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_CODEGEN_ABIINFO_H
+#define CLANG_CODEGEN_ABIINFO_H
+
+#include "clang/AST/Type.h"
+
+#include <cassert>
+
+namespace llvm {
+  class Type;
+  class Value;
+  class LLVMContext;
+}
+
+namespace clang {
+  class ASTContext;
+
+  // FIXME: This is a layering issue if we want to move ABIInfo
+  // down. Fortunately CGFunctionInfo has no real tie to CodeGen.
+  namespace CodeGen {
+    class CGFunctionInfo;
+    class CodeGenFunction;
+  }
+
+  /* FIXME: All of this stuff should be part of the target interface
+     somehow. It is currently here because it is not clear how to factor
+     the targets to support this, since the Targets currently live in a
+     layer below types n'stuff.
+  */
+
+  /// ABIArgInfo - Helper class to encapsulate information about how a
+  /// specific C type should be passed to or returned from a function.
+  class ABIArgInfo {
+  public:
+    enum Kind {
+      Direct,    /// Pass the argument directly using the normal
+                 /// converted LLVM type. Complex and structure types
+                 /// are passed using first class aggregates.
+
+      Extend,    /// Valid only for integer argument types. Same as 'direct'
+                 /// but also emit a zero/sign extension attribute.
+
+      Indirect,  /// Pass the argument indirectly via a hidden pointer
+                 /// with the specified alignment (0 indicates default
+                 /// alignment).
+
+      Ignore,    /// Ignore the argument (treat as void). Useful for
+                 /// void and empty structs.
+
+      Coerce,    /// Only valid for aggregate return types, the argument
+                 /// should be accessed by coercion to a provided type.
+
+      Expand,    /// Only valid for aggregate argument types. The
+                 /// structure should be expanded into consecutive
+                 /// arguments for its constituent fields. Currently
+                 /// expand is only allowed on structures whose fields
+                 /// are all scalar types or are themselves expandable
+                 /// types.
+
+      KindFirst=Direct, KindLast=Expand
+    };
+
+  private:
+    Kind TheKind;
+    const llvm::Type *TypeData;
+    unsigned UIntData;
+    bool BoolData;
+
+    ABIArgInfo(Kind K, const llvm::Type *TD=0,
+               unsigned UI=0, bool B = false) 
+      : TheKind(K), TypeData(TD), UIntData(UI), BoolData(B) {}
+
+  public:
+    ABIArgInfo() : TheKind(Direct), TypeData(0), UIntData(0) {}
+
+    static ABIArgInfo getDirect() {
+      return ABIArgInfo(Direct);
+    }
+    static ABIArgInfo getExtend() {
+      return ABIArgInfo(Extend);
+    }
+    static ABIArgInfo getIgnore() {
+      return ABIArgInfo(Ignore);
+    }
+    static ABIArgInfo getCoerce(const llvm::Type *T) {
+      return ABIArgInfo(Coerce, T);
+    }
+    static ABIArgInfo getIndirect(unsigned Alignment, bool ByVal = true) {
+      return ABIArgInfo(Indirect, 0, Alignment, ByVal);
+    }
+    static ABIArgInfo getExpand() {
+      return ABIArgInfo(Expand);
+    }
+
+    Kind getKind() const { return TheKind; }
+    bool isDirect() const { return TheKind == Direct; }
+    bool isExtend() const { return TheKind == Extend; }
+    bool isIgnore() const { return TheKind == Ignore; }
+    bool isCoerce() const { return TheKind == Coerce; }
+    bool isIndirect() const { return TheKind == Indirect; }
+    bool isExpand() const { return TheKind == Expand; }
+
+    // Coerce accessors
+    const llvm::Type *getCoerceToType() const {
+      assert(TheKind == Coerce && "Invalid kind!");
+      return TypeData;
+    }
+
+    // Indirect accessors
+    unsigned getIndirectAlign() const {
+      assert(TheKind == Indirect && "Invalid kind!");
+      return UIntData;
+    }
+
+    bool getIndirectByVal() const {
+      assert(TheKind == Indirect && "Invalid kind!");
+      return BoolData;
+    }
+    
+    void dump() const;
+  };
+
+  /// ABIInfo - Target specific hooks for defining how a type should be
+  /// passed or returned from functions.
+  class ABIInfo {
+  public:
+    virtual ~ABIInfo();
+
+    virtual void computeInfo(CodeGen::CGFunctionInfo &FI,
+                             ASTContext &Ctx,
+                             llvm::LLVMContext &VMContext) const = 0;
+
+    /// EmitVAArg - Emit the target dependent code to load a value of
+    /// \arg Ty from the va_list pointed to by \arg VAListAddr.
+
+    // FIXME: This is a gaping layering violation if we wanted to drop
+    // the ABI information any lower than CodeGen. Of course, for
+    // VAArg handling it has to be at this level; there is no way to
+    // abstract this out.
+    virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
+                                   CodeGen::CodeGenFunction &CGF) const = 0;
+  };
+}  // end namespace clang
+
+#endif
diff --git a/lib/CodeGen/Android.mk b/lib/CodeGen/Android.mk
new file mode 100644
index 0000000..c73002d
--- /dev/null
+++ b/lib/CodeGen/Android.mk
@@ -0,0 +1,50 @@
+LOCAL_PATH:= $(call my-dir)
+
+# For the host only
+# =====================================================
+include $(CLEAR_VARS)
+include $(CLEAR_TBLGEN_VARS)
+
+TBLGEN_TABLES :=    \
+    DiagnosticCommonKinds.inc 
+
+clang_codegen_SRC_FILES :=	\
+	CGBlocks.cpp	\
+	CGBuiltin.cpp	\
+	CGCXX.cpp	\
+	CGCall.cpp	\
+	CGClass.cpp	\
+	CGDebugInfo.cpp	\
+	CGDecl.cpp	\
+	CGDeclCXX.cpp	\
+	CGException.cpp	\
+	CGExpr.cpp	\
+	CGExprAgg.cpp	\
+	CGExprCXX.cpp	\
+	CGExprComplex.cpp	\
+	CGExprConstant.cpp	\
+	CGExprScalar.cpp	\
+	CGObjC.cpp	\
+	CGObjCGNU.cpp	\
+	CGObjCMac.cpp	\
+	CGRTTI.cpp	\
+	CGRecordLayoutBuilder.cpp	\
+	CGStmt.cpp	\
+	CGTemporaries.cpp	\
+	CGVTT.cpp	\
+	CGVTables.cpp	\
+	CodeGenFunction.cpp	\
+	CodeGenModule.cpp	\
+	CodeGenTypes.cpp	\
+	Mangle.cpp	\
+	ModuleBuilder.cpp	\
+	TargetInfo.cpp
+
+LOCAL_SRC_FILES := $(clang_codegen_SRC_FILES)
+
+LOCAL_MODULE:= libclangCodeGen
+
+include $(CLANG_HOST_BUILD_MK)
+include $(CLANG_TBLGEN_RULES_MK)
+include $(LLVM_GEN_INTRINSICS_MK)
+include $(BUILD_HOST_STATIC_LIBRARY)
diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp
new file mode 100644
index 0000000..2997b21
--- /dev/null
+++ b/lib/CodeGen/CGBlocks.cpp
@@ -0,0 +1,1197 @@
+//===--- CGBlocks.cpp - Emit LLVM Code for declarations -------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This contains code to emit blocks.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CGDebugInfo.h"
+#include "CodeGenFunction.h"
+#include "CGObjCRuntime.h"
+#include "CodeGenModule.h"
+#include "clang/AST/DeclObjC.h"
+#include "llvm/Module.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/Target/TargetData.h"
+#include <algorithm>
+
+using namespace clang;
+using namespace CodeGen;
+
+llvm::Constant *CodeGenFunction::
+BuildDescriptorBlockDecl(const BlockExpr *BE, bool BlockHasCopyDispose, CharUnits Size,
+                         const llvm::StructType* Ty,
+                         std::vector<HelperInfo> *NoteForHelper) {
+  const llvm::Type *UnsignedLongTy
+    = CGM.getTypes().ConvertType(getContext().UnsignedLongTy);
+  llvm::Constant *C;
+  std::vector<llvm::Constant*> Elts;
+
+  // reserved
+  C = llvm::ConstantInt::get(UnsignedLongTy, 0);
+  Elts.push_back(C);
+
+  // Size
+  // FIXME: What is the right way to say this doesn't fit?  We should give
+  // a user diagnostic in that case.  Better fix would be to change the
+  // API to size_t.
+  C = llvm::ConstantInt::get(UnsignedLongTy, Size.getQuantity());
+  Elts.push_back(C);
+
+  // optional copy/dispose helpers
+  if (BlockHasCopyDispose) {
+    // copy_func_helper_decl
+    Elts.push_back(BuildCopyHelper(Ty, NoteForHelper));
+
+    // destroy_func_decl
+    Elts.push_back(BuildDestroyHelper(Ty, NoteForHelper));
+  }
+
+  // Signature.  non-optional ObjC-style method descriptor @encode sequence
+  std::string BlockTypeEncoding;
+  CGM.getContext().getObjCEncodingForBlock(BE, BlockTypeEncoding);
+
+  Elts.push_back(llvm::ConstantExpr::getBitCast(
+          CGM.GetAddrOfConstantCString(BlockTypeEncoding), PtrToInt8Ty));
+  
+  // Layout.
+  C = llvm::ConstantInt::get(UnsignedLongTy, 0);
+  Elts.push_back(C);
+
+  C = llvm::ConstantStruct::get(VMContext, Elts, false);
+
+  C = new llvm::GlobalVariable(CGM.getModule(), C->getType(), true,
+                               llvm::GlobalValue::InternalLinkage,
+                               C, "__block_descriptor_tmp");
+  return C;
+}
+
+llvm::Constant *BlockModule::getNSConcreteGlobalBlock() {
+  if (NSConcreteGlobalBlock == 0)
+    NSConcreteGlobalBlock = CGM.CreateRuntimeVariable(PtrToInt8Ty,
+                                                      "_NSConcreteGlobalBlock");
+  return NSConcreteGlobalBlock;
+}
+
+llvm::Constant *BlockModule::getNSConcreteStackBlock() {
+  if (NSConcreteStackBlock == 0)
+    NSConcreteStackBlock = CGM.CreateRuntimeVariable(PtrToInt8Ty,
+                                                     "_NSConcreteStackBlock");
+  return NSConcreteStackBlock;
+}
+
+static void CollectBlockDeclRefInfo(
+  const Stmt *S, CodeGenFunction::BlockInfo &Info,
+  llvm::SmallSet<const DeclContext *, 16> &InnerContexts) {
+  for (Stmt::const_child_iterator I = S->child_begin(), E = S->child_end();
+       I != E; ++I)
+    if (*I)
+      CollectBlockDeclRefInfo(*I, Info, InnerContexts);
+
+  // We want to ensure we walk down into block literals so we can find
+  // all nested BlockDeclRefExprs.
+  if (const BlockExpr *BE = dyn_cast<BlockExpr>(S)) {
+    InnerContexts.insert(cast<DeclContext>(BE->getBlockDecl()));
+    CollectBlockDeclRefInfo(BE->getBody(), Info, InnerContexts);
+  }
+
+  if (const BlockDeclRefExpr *BDRE = dyn_cast<BlockDeclRefExpr>(S)) {
+    // FIXME: Handle enums.
+    if (isa<FunctionDecl>(BDRE->getDecl()))
+      return;
+
+    // Only Decls that escape are added.
+    if (!InnerContexts.count(BDRE->getDecl()->getDeclContext()))
+      Info.DeclRefs.push_back(BDRE);
+  }
+}
+
+/// CanBlockBeGlobal - Given a BlockInfo struct, determines if a block can be
+/// declared as a global variable instead of on the stack.
+static bool CanBlockBeGlobal(const CodeGenFunction::BlockInfo &Info) {
+  return Info.DeclRefs.empty();
+}
+
+/// AllocateAllBlockDeclRefs - Preallocate all nested BlockDeclRefExprs to
+/// ensure we can generate the debug information for the parameter for the block
+/// invoke function.
+static void AllocateAllBlockDeclRefs(const CodeGenFunction::BlockInfo &Info,
+                                     CodeGenFunction *CGF) {
+  // FIXME: Also always forward the this pointer in C++ as well.
+
+  for (size_t i = 0; i < Info.DeclRefs.size(); ++i)
+    CGF->AllocateBlockDecl(Info.DeclRefs[i]);
+}
+
+// FIXME: Push most into CGM, passing down a few bits, like current function
+// name.
+llvm::Value *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) {
+
+  std::string Name = CurFn->getName();
+  CodeGenFunction::BlockInfo Info(0, Name.c_str());
+  llvm::SmallSet<const DeclContext *, 16> InnerContexts;
+  InnerContexts.insert(BE->getBlockDecl());
+  CollectBlockDeclRefInfo(BE->getBody(), Info, InnerContexts);
+
+  // Check if the block can be global.
+  // FIXME: This test doesn't work for nested blocks yet.  Longer term, I'd like
+  // to just have one code path.  We should move this function into CGM and pass
+  // CGF, then we can just check to see if CGF is 0.
+  if (0 && CanBlockBeGlobal(Info))
+    return CGM.GetAddrOfGlobalBlock(BE, Name.c_str());
+
+  size_t BlockFields = 5;
+
+  std::vector<llvm::Constant*> Elts(BlockFields);
+
+  llvm::Constant *C;
+  llvm::Value *V;
+
+  {
+    // C = BuildBlockStructInitlist();
+    unsigned int flags = BLOCK_HAS_SIGNATURE;
+
+    // We run this first so that we set BlockHasCopyDispose from the entire
+    // block literal.
+    // __invoke
+    CharUnits subBlockSize; 
+    CharUnits subBlockAlign;
+    llvm::SmallVector<const Expr *, 8> subBlockDeclRefDecls;
+    bool subBlockHasCopyDispose = false;
+    llvm::Function *Fn
+      = CodeGenFunction(CGM).GenerateBlockFunction(BE, Info, CurFuncDecl,
+                                                   LocalDeclMap,
+                                                   subBlockSize,
+                                                   subBlockAlign,
+                                                   subBlockDeclRefDecls,
+                                                   subBlockHasCopyDispose);
+    BlockHasCopyDispose |= subBlockHasCopyDispose;
+    Elts[3] = Fn;
+
+    // FIXME: Don't use BlockHasCopyDispose, it is set more often then
+    // necessary, for example: { ^{ __block int i; ^{ i = 1; }(); }(); }
+    if (subBlockHasCopyDispose)
+      flags |= BLOCK_HAS_COPY_DISPOSE;
+
+    // __isa
+    C = CGM.getNSConcreteStackBlock();
+    C = llvm::ConstantExpr::getBitCast(C, PtrToInt8Ty);
+    Elts[0] = C;
+
+    // __flags
+    {
+      QualType BPT = BE->getType();
+      const FunctionType *ftype = BPT->getPointeeType()->getAs<FunctionType>();
+      QualType ResultType = ftype->getResultType();
+    
+      CallArgList Args;
+      CodeGenTypes &Types = CGM.getTypes();
+      const CGFunctionInfo &FnInfo = Types.getFunctionInfo(ResultType, Args,
+                                                       FunctionType::ExtInfo());
+      if (CGM.ReturnTypeUsesSret(FnInfo))
+        flags |= BLOCK_USE_STRET;
+    }
+    const llvm::IntegerType *IntTy = cast<llvm::IntegerType>(
+      CGM.getTypes().ConvertType(CGM.getContext().IntTy));
+    C = llvm::ConstantInt::get(IntTy, flags);
+    Elts[1] = C;
+
+    // __reserved
+    C = llvm::ConstantInt::get(IntTy, 0);
+    Elts[2] = C;
+
+    if (subBlockDeclRefDecls.size() == 0) {
+      // __descriptor
+      Elts[4] = BuildDescriptorBlockDecl(BE, subBlockHasCopyDispose, subBlockSize,
+                                         0, 0);
+
+      // Optimize to being a global block.
+      Elts[0] = CGM.getNSConcreteGlobalBlock();
+      
+      Elts[1] = llvm::ConstantInt::get(IntTy, flags|BLOCK_IS_GLOBAL);
+
+      C = llvm::ConstantStruct::get(VMContext, Elts, false);
+
+      C = new llvm::GlobalVariable(CGM.getModule(), C->getType(), true,
+                                   llvm::GlobalValue::InternalLinkage, C,
+                                   "__block_holder_tmp_" +
+                                   llvm::Twine(CGM.getGlobalUniqueCount()));
+      QualType BPT = BE->getType();
+      C = llvm::ConstantExpr::getBitCast(C, ConvertType(BPT));
+      return C;
+    }
+
+    std::vector<const llvm::Type *> Types(BlockFields+subBlockDeclRefDecls.size());
+    for (int i=0; i<4; ++i)
+      Types[i] = Elts[i]->getType();
+    Types[4] = PtrToInt8Ty;
+
+    for (unsigned i=0; i < subBlockDeclRefDecls.size(); ++i) {
+      const Expr *E = subBlockDeclRefDecls[i];
+      const BlockDeclRefExpr *BDRE = dyn_cast<BlockDeclRefExpr>(E);
+      QualType Ty = E->getType();
+      if (BDRE && BDRE->isByRef()) {
+        Types[i+BlockFields] = llvm::PointerType::get(BuildByRefType(BDRE->getDecl()), 0);
+      } else
+        Types[i+BlockFields] = ConvertType(Ty);
+    }
+
+    llvm::StructType *Ty = llvm::StructType::get(VMContext, Types, true);
+
+    llvm::AllocaInst *A = CreateTempAlloca(Ty);
+    A->setAlignment(subBlockAlign.getQuantity());
+    V = A;
+
+    std::vector<HelperInfo> NoteForHelper(subBlockDeclRefDecls.size());
+    int helpersize = 0;
+
+    for (unsigned i=0; i<4; ++i)
+      Builder.CreateStore(Elts[i], Builder.CreateStructGEP(V, i, "block.tmp"));
+
+    for (unsigned i=0; i < subBlockDeclRefDecls.size(); ++i)
+      {
+        // FIXME: Push const down.
+        Expr *E = const_cast<Expr*>(subBlockDeclRefDecls[i]);
+        DeclRefExpr *DR;
+        ValueDecl *VD;
+
+        DR = dyn_cast<DeclRefExpr>(E);
+        // Skip padding.
+        if (DR) continue;
+
+        BlockDeclRefExpr *BDRE = dyn_cast<BlockDeclRefExpr>(E);
+        VD = BDRE->getDecl();
+
+        llvm::Value* Addr = Builder.CreateStructGEP(V, i+BlockFields, "tmp");
+        NoteForHelper[helpersize].index = i+5;
+        NoteForHelper[helpersize].RequiresCopying
+          = BlockRequiresCopying(VD->getType());
+        NoteForHelper[helpersize].flag
+          = (VD->getType()->isBlockPointerType()
+             ? BLOCK_FIELD_IS_BLOCK
+             : BLOCK_FIELD_IS_OBJECT);
+
+        if (LocalDeclMap[VD]) {
+          if (BDRE->isByRef()) {
+            NoteForHelper[helpersize].flag = BLOCK_FIELD_IS_BYREF |
+              // FIXME: Someone double check this.
+              (VD->getType().isObjCGCWeak() ? BLOCK_FIELD_IS_WEAK : 0);
+            llvm::Value *Loc = LocalDeclMap[VD];
+            Loc = Builder.CreateStructGEP(Loc, 1, "forwarding");
+            Loc = Builder.CreateLoad(Loc);
+            Builder.CreateStore(Loc, Addr);
+            ++helpersize;
+            continue;
+          } else
+            E = new (getContext()) DeclRefExpr (VD,
+                                                VD->getType(), 
+                                                SourceLocation());
+        }
+        if (BDRE->isByRef()) {
+          NoteForHelper[helpersize].flag = BLOCK_FIELD_IS_BYREF |
+            // FIXME: Someone double check this.
+            (VD->getType().isObjCGCWeak() ? BLOCK_FIELD_IS_WEAK : 0);
+          E = new (getContext())
+            UnaryOperator(E, UnaryOperator::AddrOf,
+                          getContext().getPointerType(E->getType()),
+                          SourceLocation());
+        }
+        ++helpersize;
+
+        RValue r = EmitAnyExpr(E, Addr, false);
+        if (r.isScalar()) {
+          llvm::Value *Loc = r.getScalarVal();
+          const llvm::Type *Ty = Types[i+BlockFields];
+          if  (BDRE->isByRef()) {
+            // E is now the address of the value field, instead, we want the
+            // address of the actual ByRef struct.  We optimize this slightly
+            // compared to gcc by not grabbing the forwarding slot as this must
+            // be done during Block_copy for us, and we can postpone the work
+            // until then.
+            CharUnits offset = BlockDecls[BDRE->getDecl()];
+
+            llvm::Value *BlockLiteral = LoadBlockStruct();
+
+            Loc = Builder.CreateGEP(BlockLiteral,
+                       llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext),
+                                                           offset.getQuantity()),
+                                    "block.literal");
+            Ty = llvm::PointerType::get(Ty, 0);
+            Loc = Builder.CreateBitCast(Loc, Ty);
+            Loc = Builder.CreateLoad(Loc);
+            // Loc = Builder.CreateBitCast(Loc, Ty);
+          }
+          Builder.CreateStore(Loc, Addr);
+        } else if (r.isComplex())
+          // FIXME: implement
+          ErrorUnsupported(BE, "complex in block literal");
+        else if (r.isAggregate())
+          ; // Already created into the destination
+        else
+          assert (0 && "bad block variable");
+        // FIXME: Ensure that the offset created by the backend for
+        // the struct matches the previously computed offset in BlockDecls.
+      }
+    NoteForHelper.resize(helpersize);
+
+    // __descriptor
+    llvm::Value *Descriptor = BuildDescriptorBlockDecl(BE,
+                                                       subBlockHasCopyDispose,
+                                                       subBlockSize, Ty,
+                                                       &NoteForHelper);
+    Descriptor = Builder.CreateBitCast(Descriptor, PtrToInt8Ty);
+    Builder.CreateStore(Descriptor, Builder.CreateStructGEP(V, 4, "block.tmp"));
+  }
+
+  QualType BPT = BE->getType();
+  V = Builder.CreateBitCast(V, ConvertType(BPT));
+  // See if this is a __weak block variable and the must call objc_read_weak
+  // on it.
+  const FunctionType *ftype = BPT->getPointeeType()->getAs<FunctionType>();
+  QualType RES = ftype->getResultType();
+  if (RES.isObjCGCWeak()) {
+    // Must cast argument to id*
+    const llvm::Type *ObjectPtrTy = 
+      ConvertType(CGM.getContext().getObjCIdType());
+    const llvm::Type *PtrObjectPtrTy = 
+      llvm::PointerType::getUnqual(ObjectPtrTy);
+    V = Builder.CreateBitCast(V, PtrObjectPtrTy);
+    V =  CGM.getObjCRuntime().EmitObjCWeakRead(*this, V);
+  }
+  return V;
+}
+
+
+const llvm::Type *BlockModule::getBlockDescriptorType() {
+  if (BlockDescriptorType)
+    return BlockDescriptorType;
+
+  const llvm::Type *UnsignedLongTy =
+    getTypes().ConvertType(getContext().UnsignedLongTy);
+
+  // struct __block_descriptor {
+  //   unsigned long reserved;
+  //   unsigned long block_size;
+  //
+  //   // later, the following will be added
+  //
+  //   struct {
+  //     void (*copyHelper)();
+  //     void (*copyHelper)();
+  //   } helpers;                // !!! optional
+  //
+  //   const char *signature;   // the block signature
+  //   const char *layout;      // reserved
+  // };
+  BlockDescriptorType = llvm::StructType::get(UnsignedLongTy->getContext(),
+                                              UnsignedLongTy,
+                                              UnsignedLongTy,
+                                              NULL);
+
+  getModule().addTypeName("struct.__block_descriptor",
+                          BlockDescriptorType);
+
+  return BlockDescriptorType;
+}
+
+const llvm::Type *BlockModule::getGenericBlockLiteralType() {
+  if (GenericBlockLiteralType)
+    return GenericBlockLiteralType;
+
+  const llvm::Type *BlockDescPtrTy =
+    llvm::PointerType::getUnqual(getBlockDescriptorType());
+
+  const llvm::IntegerType *IntTy = cast<llvm::IntegerType>(
+    getTypes().ConvertType(getContext().IntTy));
+
+  // struct __block_literal_generic {
+  //   void *__isa;
+  //   int __flags;
+  //   int __reserved;
+  //   void (*__invoke)(void *);
+  //   struct __block_descriptor *__descriptor;
+  // };
+  GenericBlockLiteralType = llvm::StructType::get(IntTy->getContext(),
+                                                  PtrToInt8Ty,
+                                                  IntTy,
+                                                  IntTy,
+                                                  PtrToInt8Ty,
+                                                  BlockDescPtrTy,
+                                                  NULL);
+
+  getModule().addTypeName("struct.__block_literal_generic",
+                          GenericBlockLiteralType);
+
+  return GenericBlockLiteralType;
+}
+
+
+RValue CodeGenFunction::EmitBlockCallExpr(const CallExpr* E, 
+                                          ReturnValueSlot ReturnValue) {
+  const BlockPointerType *BPT =
+    E->getCallee()->getType()->getAs<BlockPointerType>();
+
+  llvm::Value *Callee = EmitScalarExpr(E->getCallee());
+
+  // Get a pointer to the generic block literal.
+  const llvm::Type *BlockLiteralTy =
+    llvm::PointerType::getUnqual(CGM.getGenericBlockLiteralType());
+
+  // Bitcast the callee to a block literal.
+  llvm::Value *BlockLiteral =
+    Builder.CreateBitCast(Callee, BlockLiteralTy, "block.literal");
+
+  // Get the function pointer from the literal.
+  llvm::Value *FuncPtr = Builder.CreateStructGEP(BlockLiteral, 3, "tmp");
+
+  BlockLiteral =
+    Builder.CreateBitCast(BlockLiteral,
+                          llvm::Type::getInt8PtrTy(VMContext),
+                          "tmp");
+
+  // Add the block literal.
+  QualType VoidPtrTy = getContext().getPointerType(getContext().VoidTy);
+  CallArgList Args;
+  Args.push_back(std::make_pair(RValue::get(BlockLiteral), VoidPtrTy));
+
+  QualType FnType = BPT->getPointeeType();
+
+  // And the rest of the arguments.
+  EmitCallArgs(Args, FnType->getAs<FunctionProtoType>(),
+               E->arg_begin(), E->arg_end());
+
+  // Load the function.
+  llvm::Value *Func = Builder.CreateLoad(FuncPtr, "tmp");
+
+  const FunctionType *FuncTy = FnType->getAs<FunctionType>();
+  QualType ResultType = FuncTy->getResultType();
+
+  const CGFunctionInfo &FnInfo =
+    CGM.getTypes().getFunctionInfo(ResultType, Args,
+                                   FuncTy->getExtInfo());
+
+  // Cast the function pointer to the right type.
+  const llvm::Type *BlockFTy =
+    CGM.getTypes().GetFunctionType(FnInfo, false);
+
+  const llvm::Type *BlockFTyPtr = llvm::PointerType::getUnqual(BlockFTy);
+  Func = Builder.CreateBitCast(Func, BlockFTyPtr);
+
+  // And call the block.
+  return EmitCall(FnInfo, Func, ReturnValue, Args);
+}
+
+CharUnits CodeGenFunction::AllocateBlockDecl(const BlockDeclRefExpr *E) {
+  const ValueDecl *VD = E->getDecl();
+  CharUnits &offset = BlockDecls[VD];
+
+  // See if we have already allocated an offset for this variable.
+  if (offset.isPositive())
+    return offset;
+
+  // Don't run the expensive check, unless we have to.
+  if (!BlockHasCopyDispose)
+    if (E->isByRef()
+        || BlockRequiresCopying(E->getType()))
+      BlockHasCopyDispose = true;
+
+  // if not, allocate one now.
+  offset = getBlockOffset(E);
+
+  return offset;
+}
+
+llvm::Value *CodeGenFunction::GetAddrOfBlockDecl(const BlockDeclRefExpr *E) {
+  const ValueDecl *VD = E->getDecl();
+  CharUnits offset = AllocateBlockDecl(E);
+  
+
+  llvm::Value *BlockLiteral = LoadBlockStruct();
+  llvm::Value *V = Builder.CreateGEP(BlockLiteral,
+                       llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext),
+                                                         offset.getQuantity()),
+                                     "block.literal");
+  if (E->isByRef()) {
+    const llvm::Type *PtrStructTy
+      = llvm::PointerType::get(BuildByRefType(VD), 0);
+    // The block literal will need a copy/destroy helper.
+    BlockHasCopyDispose = true;
+    
+    const llvm::Type *Ty = PtrStructTy;
+    Ty = llvm::PointerType::get(Ty, 0);
+    V = Builder.CreateBitCast(V, Ty);
+    V = Builder.CreateLoad(V);
+    V = Builder.CreateStructGEP(V, 1, "forwarding");
+    V = Builder.CreateLoad(V);
+    V = Builder.CreateBitCast(V, PtrStructTy);
+    V = Builder.CreateStructGEP(V, getByRefValueLLVMField(VD), 
+                                VD->getNameAsString());
+  } else {
+    const llvm::Type *Ty = CGM.getTypes().ConvertType(VD->getType());
+
+    Ty = llvm::PointerType::get(Ty, 0);
+    V = Builder.CreateBitCast(V, Ty);
+  }
+  return V;
+}
+
+void CodeGenFunction::BlockForwardSelf() {
+  const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl);
+  ImplicitParamDecl *SelfDecl = OMD->getSelfDecl();
+  llvm::Value *&DMEntry = LocalDeclMap[SelfDecl];
+  if (DMEntry)
+    return;
+  // FIXME - Eliminate BlockDeclRefExprs, clients don't need/want to care
+  BlockDeclRefExpr *BDRE = new (getContext())
+    BlockDeclRefExpr(SelfDecl,
+                     SelfDecl->getType(), SourceLocation(), false);
+  DMEntry = GetAddrOfBlockDecl(BDRE);
+}
+
+llvm::Constant *
+BlockModule::GetAddrOfGlobalBlock(const BlockExpr *BE, const char * n) {
+  // Generate the block descriptor.
+  const llvm::Type *UnsignedLongTy = Types.ConvertType(Context.UnsignedLongTy);
+  const llvm::IntegerType *IntTy = cast<llvm::IntegerType>(
+    getTypes().ConvertType(getContext().IntTy));
+
+  llvm::Constant *DescriptorFields[4];
+
+  // Reserved
+  DescriptorFields[0] = llvm::Constant::getNullValue(UnsignedLongTy);
+
+  // Block literal size. For global blocks we just use the size of the generic
+  // block literal struct.
+  CharUnits BlockLiteralSize = 
+    CGM.GetTargetTypeStoreSize(getGenericBlockLiteralType());
+  DescriptorFields[1] =
+    llvm::ConstantInt::get(UnsignedLongTy,BlockLiteralSize.getQuantity());
+  
+  // signature.  non-optional ObjC-style method descriptor @encode sequence
+  std::string BlockTypeEncoding;
+  CGM.getContext().getObjCEncodingForBlock(BE, BlockTypeEncoding);
+
+  DescriptorFields[2] = llvm::ConstantExpr::getBitCast(
+          CGM.GetAddrOfConstantCString(BlockTypeEncoding), PtrToInt8Ty);
+  
+  // layout
+  DescriptorFields[3] =
+    llvm::ConstantInt::get(UnsignedLongTy,0);
+
+  // build the structure from the 4 elements
+  llvm::Constant *DescriptorStruct =
+    llvm::ConstantStruct::get(VMContext, &DescriptorFields[0], 4, false);
+
+  llvm::GlobalVariable *Descriptor =
+    new llvm::GlobalVariable(getModule(), DescriptorStruct->getType(), true,
+                             llvm::GlobalVariable::InternalLinkage,
+                             DescriptorStruct, "__block_descriptor_global");
+
+  int FieldCount = 5;
+  // Generate the constants for the block literal.
+
+  std::vector<llvm::Constant*> LiteralFields(FieldCount);
+
+  CodeGenFunction::BlockInfo Info(0, n);
+  CharUnits subBlockSize; 
+  CharUnits subBlockAlign;
+  llvm::SmallVector<const Expr *, 8> subBlockDeclRefDecls;
+  bool subBlockHasCopyDispose = false;
+  llvm::DenseMap<const Decl*, llvm::Value*> LocalDeclMap;
+  llvm::Function *Fn
+    = CodeGenFunction(CGM).GenerateBlockFunction(BE, Info, 0, LocalDeclMap,
+                                                 subBlockSize,
+                                                 subBlockAlign,
+                                                 subBlockDeclRefDecls,
+                                                 subBlockHasCopyDispose);
+  assert(subBlockSize == BlockLiteralSize
+         && "no imports allowed for global block");
+
+  // isa
+  LiteralFields[0] = getNSConcreteGlobalBlock();
+
+  // Flags
+  LiteralFields[1] =
+    llvm::ConstantInt::get(IntTy, BLOCK_IS_GLOBAL | BLOCK_HAS_SIGNATURE);
+
+  // Reserved
+  LiteralFields[2] = llvm::Constant::getNullValue(IntTy);
+
+  // Function
+  LiteralFields[3] = Fn;
+
+  // Descriptor
+  LiteralFields[4] = Descriptor;
+  
+  llvm::Constant *BlockLiteralStruct =
+    llvm::ConstantStruct::get(VMContext, LiteralFields, false);
+
+  llvm::GlobalVariable *BlockLiteral =
+    new llvm::GlobalVariable(getModule(), BlockLiteralStruct->getType(), true,
+                             llvm::GlobalVariable::InternalLinkage,
+                             BlockLiteralStruct, "__block_literal_global");
+
+  return BlockLiteral;
+}
+
+llvm::Value *CodeGenFunction::LoadBlockStruct() {
+  llvm::Value *V = Builder.CreateLoad(LocalDeclMap[getBlockStructDecl()],
+                                      "self");
+  // For now, we codegen based upon byte offsets.
+  return Builder.CreateBitCast(V, PtrToInt8Ty);
+}
+
+llvm::Function *
+CodeGenFunction::GenerateBlockFunction(const BlockExpr *BExpr,
+                                       const BlockInfo& Info,
+                                       const Decl *OuterFuncDecl,
+                                  llvm::DenseMap<const Decl*, llvm::Value*> ldm,
+                                       CharUnits &Size,
+                                       CharUnits &Align,
+                       llvm::SmallVector<const Expr *, 8> &subBlockDeclRefDecls,
+                                       bool &subBlockHasCopyDispose) {
+
+  // Check if we should generate debug info for this block.
+  if (CGM.getDebugInfo())
+    DebugInfo = CGM.getDebugInfo();
+
+  // Arrange for local static and local extern declarations to appear
+  // to be local to this function as well, as they are directly referenced
+  // in a block.
+  for (llvm::DenseMap<const Decl *, llvm::Value*>::iterator i = ldm.begin();
+       i != ldm.end();
+       ++i) {
+    const VarDecl *VD = dyn_cast<VarDecl>(i->first);
+
+    if (VD->getStorageClass() == VarDecl::Static || VD->hasExternalStorage())
+      LocalDeclMap[VD] = i->second;
+  }
+
+  BlockOffset = 
+      CGM.GetTargetTypeStoreSize(CGM.getGenericBlockLiteralType());
+  BlockAlign = getContext().getTypeAlignInChars(getContext().VoidPtrTy);
+
+  const FunctionType *BlockFunctionType = BExpr->getFunctionType();
+  QualType ResultType;
+  FunctionType::ExtInfo EInfo = getFunctionExtInfo(*BlockFunctionType);
+  bool IsVariadic;
+  if (const FunctionProtoType *FTy =
+      dyn_cast<FunctionProtoType>(BlockFunctionType)) {
+    ResultType = FTy->getResultType();
+    IsVariadic = FTy->isVariadic();
+  } else {
+    // K&R style block.
+    ResultType = BlockFunctionType->getResultType();
+    IsVariadic = false;
+  }
+
+  FunctionArgList Args;
+
+  CurFuncDecl = OuterFuncDecl;
+
+  const BlockDecl *BD = BExpr->getBlockDecl();
+
+  IdentifierInfo *II = &CGM.getContext().Idents.get(".block_descriptor");
+
+  // Allocate all BlockDeclRefDecls, so we can calculate the right ParmTy below.
+  AllocateAllBlockDeclRefs(Info, this);
+
+  QualType ParmTy = getContext().getBlockParmType(BlockHasCopyDispose,
+                                                  BlockDeclRefDecls);
+  // FIXME: This leaks
+  ImplicitParamDecl *SelfDecl =
+    ImplicitParamDecl::Create(getContext(), 0,
+                              SourceLocation(), II,
+                              ParmTy);
+
+  Args.push_back(std::make_pair(SelfDecl, SelfDecl->getType()));
+  BlockStructDecl = SelfDecl;
+
+  for (BlockDecl::param_const_iterator i = BD->param_begin(),
+       e = BD->param_end(); i != e; ++i)
+    Args.push_back(std::make_pair(*i, (*i)->getType()));
+
+  const CGFunctionInfo &FI =
+    CGM.getTypes().getFunctionInfo(ResultType, Args, EInfo);
+
+  CodeGenTypes &Types = CGM.getTypes();
+  const llvm::FunctionType *LTy = Types.GetFunctionType(FI, IsVariadic);
+
+  llvm::Function *Fn =
+    llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage,
+                           llvm::Twine("__") + Info.Name + "_block_invoke_",
+                           &CGM.getModule());
+
+  CGM.SetInternalFunctionAttributes(BD, Fn, FI);
+
+  StartFunction(BD, ResultType, Fn, Args,
+                BExpr->getBody()->getLocEnd());
+
+  CurFuncDecl = OuterFuncDecl;
+  CurCodeDecl = BD;
+
+  // Save a spot to insert the debug information for all the BlockDeclRefDecls.
+  llvm::BasicBlock *entry = Builder.GetInsertBlock();
+  llvm::BasicBlock::iterator entry_ptr = Builder.GetInsertPoint();
+  --entry_ptr;
+
+  EmitStmt(BExpr->getBody());
+
+  // Remember where we were...
+  llvm::BasicBlock *resume = Builder.GetInsertBlock();
+
+  // Go back to the entry.
+  ++entry_ptr;
+  Builder.SetInsertPoint(entry, entry_ptr);
+
+  if (CGDebugInfo *DI = getDebugInfo()) {
+    // Emit debug information for all the BlockDeclRefDecls.
+    for (unsigned i = 0, e = BlockDeclRefDecls.size(); i != e; ++i) {
+      if (const BlockDeclRefExpr *BDRE = 
+            dyn_cast<BlockDeclRefExpr>(BlockDeclRefDecls[i])) {
+        const ValueDecl *D = BDRE->getDecl();
+        DI->setLocation(D->getLocation());
+        DI->EmitDeclareOfBlockDeclRefVariable(BDRE,
+                                             LocalDeclMap[getBlockStructDecl()],
+                                              Builder, this);
+      }
+    }
+  }
+  // And resume where we left off.
+  if (resume == 0)
+    Builder.ClearInsertionPoint();
+  else
+    Builder.SetInsertPoint(resume);
+
+  FinishFunction(cast<CompoundStmt>(BExpr->getBody())->getRBracLoc());
+
+  // The runtime needs a minimum alignment of a void *.
+  CharUnits MinAlign = getContext().getTypeAlignInChars(getContext().VoidPtrTy);
+  BlockOffset = CharUnits::fromQuantity(
+      llvm::RoundUpToAlignment(BlockOffset.getQuantity(), 
+                               MinAlign.getQuantity()));
+
+  Size = BlockOffset;
+  Align = BlockAlign;
+  subBlockDeclRefDecls = BlockDeclRefDecls;
+  subBlockHasCopyDispose |= BlockHasCopyDispose;
+  return Fn;
+}
+
+CharUnits BlockFunction::getBlockOffset(const BlockDeclRefExpr *BDRE) {
+  const ValueDecl *D = dyn_cast<ValueDecl>(BDRE->getDecl());
+
+  CharUnits Size = getContext().getTypeSizeInChars(D->getType());
+  CharUnits Align = getContext().getDeclAlign(D);
+
+  if (BDRE->isByRef()) {
+    Size = getContext().getTypeSizeInChars(getContext().VoidPtrTy);
+    Align = getContext().getTypeAlignInChars(getContext().VoidPtrTy);
+  }
+
+  assert ((Align.isPositive()) && "alignment must be 1 byte or more");
+
+  CharUnits OldOffset = BlockOffset;
+
+  // Ensure proper alignment, even if it means we have to have a gap
+  BlockOffset = CharUnits::fromQuantity(
+      llvm::RoundUpToAlignment(BlockOffset.getQuantity(), Align.getQuantity()));
+  BlockAlign = std::max(Align, BlockAlign);
+
+  CharUnits Pad = BlockOffset - OldOffset;
+  if (Pad.isPositive()) {
+    llvm::ArrayType::get(llvm::Type::getInt8Ty(VMContext), Pad.getQuantity());
+    QualType PadTy = getContext().getConstantArrayType(getContext().CharTy,
+                                                       llvm::APInt(32, 
+                                                         Pad.getQuantity()),
+                                                       ArrayType::Normal, 0);
+    ValueDecl *PadDecl = VarDecl::Create(getContext(), 0, SourceLocation(),
+                                         0, QualType(PadTy), 0,
+                                         VarDecl::None, VarDecl::None);
+    Expr *E;
+    E = new (getContext()) DeclRefExpr(PadDecl, PadDecl->getType(),
+                                       SourceLocation());
+    BlockDeclRefDecls.push_back(E);
+  }
+  BlockDeclRefDecls.push_back(BDRE);
+
+  BlockOffset += Size;
+  return BlockOffset-Size;
+}
+
+llvm::Constant *BlockFunction::
+GenerateCopyHelperFunction(bool BlockHasCopyDispose, const llvm::StructType *T,
+                           std::vector<HelperInfo> *NoteForHelperp) {
+  QualType R = getContext().VoidTy;
+
+  FunctionArgList Args;
+  // FIXME: This leaks
+  ImplicitParamDecl *Dst =
+    ImplicitParamDecl::Create(getContext(), 0,
+                              SourceLocation(), 0,
+                              getContext().getPointerType(getContext().VoidTy));
+  Args.push_back(std::make_pair(Dst, Dst->getType()));
+  ImplicitParamDecl *Src =
+    ImplicitParamDecl::Create(getContext(), 0,
+                              SourceLocation(), 0,
+                              getContext().getPointerType(getContext().VoidTy));
+  Args.push_back(std::make_pair(Src, Src->getType()));
+
+  const CGFunctionInfo &FI =
+      CGM.getTypes().getFunctionInfo(R, Args, FunctionType::ExtInfo());
+
+  // FIXME: We'd like to put these into a mergable by content, with
+  // internal linkage.
+  CodeGenTypes &Types = CGM.getTypes();
+  const llvm::FunctionType *LTy = Types.GetFunctionType(FI, false);
+
+  llvm::Function *Fn =
+    llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage,
+                           "__copy_helper_block_", &CGM.getModule());
+
+  IdentifierInfo *II
+    = &CGM.getContext().Idents.get("__copy_helper_block_");
+
+  FunctionDecl *FD = FunctionDecl::Create(getContext(),
+                                          getContext().getTranslationUnitDecl(),
+                                          SourceLocation(), II, R, 0,
+                                          FunctionDecl::Static,
+                                          FunctionDecl::None,
+                                          false,
+                                          true);
+  CGF.StartFunction(FD, R, Fn, Args, SourceLocation());
+
+  llvm::Value *SrcObj = CGF.GetAddrOfLocalVar(Src);
+  llvm::Type *PtrPtrT;
+
+  if (NoteForHelperp) {
+    std::vector<HelperInfo> &NoteForHelper = *NoteForHelperp;
+
+    PtrPtrT = llvm::PointerType::get(llvm::PointerType::get(T, 0), 0);
+    SrcObj = Builder.CreateBitCast(SrcObj, PtrPtrT);
+    SrcObj = Builder.CreateLoad(SrcObj);
+
+    llvm::Value *DstObj = CGF.GetAddrOfLocalVar(Dst);
+    llvm::Type *PtrPtrT;
+    PtrPtrT = llvm::PointerType::get(llvm::PointerType::get(T, 0), 0);
+    DstObj = Builder.CreateBitCast(DstObj, PtrPtrT);
+    DstObj = Builder.CreateLoad(DstObj);
+
+    for (unsigned i=0; i < NoteForHelper.size(); ++i) {
+      int flag = NoteForHelper[i].flag;
+      int index = NoteForHelper[i].index;
+
+      if ((NoteForHelper[i].flag & BLOCK_FIELD_IS_BYREF)
+          || NoteForHelper[i].RequiresCopying) {
+        llvm::Value *Srcv = SrcObj;
+        Srcv = Builder.CreateStructGEP(Srcv, index);
+        Srcv = Builder.CreateBitCast(Srcv,
+                                     llvm::PointerType::get(PtrToInt8Ty, 0));
+        Srcv = Builder.CreateLoad(Srcv);
+
+        llvm::Value *Dstv = Builder.CreateStructGEP(DstObj, index);
+        Dstv = Builder.CreateBitCast(Dstv, PtrToInt8Ty);
+
+        llvm::Value *N = llvm::ConstantInt::get(
+              llvm::Type::getInt32Ty(T->getContext()), flag);
+        llvm::Value *F = getBlockObjectAssign();
+        Builder.CreateCall3(F, Dstv, Srcv, N);
+      }
+    }
+  }
+
+  CGF.FinishFunction();
+
+  return llvm::ConstantExpr::getBitCast(Fn, PtrToInt8Ty);
+}
+
+llvm::Constant *BlockFunction::
+GenerateDestroyHelperFunction(bool BlockHasCopyDispose,
+                              const llvm::StructType* T,
+                              std::vector<HelperInfo> *NoteForHelperp) {
+  QualType R = getContext().VoidTy;
+
+  FunctionArgList Args;
+  // FIXME: This leaks
+  ImplicitParamDecl *Src =
+    ImplicitParamDecl::Create(getContext(), 0,
+                              SourceLocation(), 0,
+                              getContext().getPointerType(getContext().VoidTy));
+
+  Args.push_back(std::make_pair(Src, Src->getType()));
+
+  const CGFunctionInfo &FI =
+      CGM.getTypes().getFunctionInfo(R, Args, FunctionType::ExtInfo());
+
+  // FIXME: We'd like to put these into a mergable by content, with
+  // internal linkage.
+  CodeGenTypes &Types = CGM.getTypes();
+  const llvm::FunctionType *LTy = Types.GetFunctionType(FI, false);
+
+  llvm::Function *Fn =
+    llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage,
+                           "__destroy_helper_block_", &CGM.getModule());
+
+  IdentifierInfo *II
+    = &CGM.getContext().Idents.get("__destroy_helper_block_");
+
+  FunctionDecl *FD = FunctionDecl::Create(getContext(),
+                                          getContext().getTranslationUnitDecl(),
+                                          SourceLocation(), II, R, 0,
+                                          FunctionDecl::Static,
+                                          FunctionDecl::None,
+                                          false, true);
+  CGF.StartFunction(FD, R, Fn, Args, SourceLocation());
+
+  if (NoteForHelperp) {
+    std::vector<HelperInfo> &NoteForHelper = *NoteForHelperp;
+
+    llvm::Value *SrcObj = CGF.GetAddrOfLocalVar(Src);
+    llvm::Type *PtrPtrT;
+    PtrPtrT = llvm::PointerType::get(llvm::PointerType::get(T, 0), 0);
+    SrcObj = Builder.CreateBitCast(SrcObj, PtrPtrT);
+    SrcObj = Builder.CreateLoad(SrcObj);
+
+    for (unsigned i=0; i < NoteForHelper.size(); ++i) {
+      int flag = NoteForHelper[i].flag;
+      int index = NoteForHelper[i].index;
+
+      if ((NoteForHelper[i].flag & BLOCK_FIELD_IS_BYREF)
+          || NoteForHelper[i].RequiresCopying) {
+        llvm::Value *Srcv = SrcObj;
+        Srcv = Builder.CreateStructGEP(Srcv, index);
+        Srcv = Builder.CreateBitCast(Srcv,
+                                     llvm::PointerType::get(PtrToInt8Ty, 0));
+        Srcv = Builder.CreateLoad(Srcv);
+
+        BuildBlockRelease(Srcv, flag);
+      }
+    }
+  }
+
+  CGF.FinishFunction();
+
+  return llvm::ConstantExpr::getBitCast(Fn, PtrToInt8Ty);
+}
+
+llvm::Constant *BlockFunction::BuildCopyHelper(const llvm::StructType *T,
+                                       std::vector<HelperInfo> *NoteForHelper) {
+  return CodeGenFunction(CGM).GenerateCopyHelperFunction(BlockHasCopyDispose,
+                                                         T, NoteForHelper);
+}
+
+llvm::Constant *BlockFunction::BuildDestroyHelper(const llvm::StructType *T,
+                                      std::vector<HelperInfo> *NoteForHelperp) {
+  return CodeGenFunction(CGM).GenerateDestroyHelperFunction(BlockHasCopyDispose,
+                                                            T, NoteForHelperp);
+}
+
+llvm::Constant *BlockFunction::
+GeneratebyrefCopyHelperFunction(const llvm::Type *T, int flag) {
+  QualType R = getContext().VoidTy;
+
+  FunctionArgList Args;
+  // FIXME: This leaks
+  ImplicitParamDecl *Dst =
+    ImplicitParamDecl::Create(getContext(), 0,
+                              SourceLocation(), 0,
+                              getContext().getPointerType(getContext().VoidTy));
+  Args.push_back(std::make_pair(Dst, Dst->getType()));
+
+  // FIXME: This leaks
+  ImplicitParamDecl *Src =
+    ImplicitParamDecl::Create(getContext(), 0,
+                              SourceLocation(), 0,
+                              getContext().getPointerType(getContext().VoidTy));
+  Args.push_back(std::make_pair(Src, Src->getType()));
+
+  const CGFunctionInfo &FI =
+      CGM.getTypes().getFunctionInfo(R, Args, FunctionType::ExtInfo());
+
+  CodeGenTypes &Types = CGM.getTypes();
+  const llvm::FunctionType *LTy = Types.GetFunctionType(FI, false);
+
+  // FIXME: We'd like to put these into a mergable by content, with
+  // internal linkage.
+  llvm::Function *Fn =
+    llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage,
+                           "__Block_byref_id_object_copy_", &CGM.getModule());
+
+  IdentifierInfo *II
+    = &CGM.getContext().Idents.get("__Block_byref_id_object_copy_");
+
+  FunctionDecl *FD = FunctionDecl::Create(getContext(),
+                                          getContext().getTranslationUnitDecl(),
+                                          SourceLocation(), II, R, 0,
+                                          FunctionDecl::Static,
+                                          FunctionDecl::None,
+                                          false, true);
+  CGF.StartFunction(FD, R, Fn, Args, SourceLocation());
+
+  // dst->x
+  llvm::Value *V = CGF.GetAddrOfLocalVar(Dst);
+  V = Builder.CreateBitCast(V, llvm::PointerType::get(T, 0));
+  V = Builder.CreateLoad(V);
+  V = Builder.CreateStructGEP(V, 6, "x");
+  llvm::Value *DstObj = Builder.CreateBitCast(V, PtrToInt8Ty);
+
+  // src->x
+  V = CGF.GetAddrOfLocalVar(Src);
+  V = Builder.CreateLoad(V);
+  V = Builder.CreateBitCast(V, T);
+  V = Builder.CreateStructGEP(V, 6, "x");
+  V = Builder.CreateBitCast(V, llvm::PointerType::get(PtrToInt8Ty, 0));
+  llvm::Value *SrcObj = Builder.CreateLoad(V);
+
+  flag |= BLOCK_BYREF_CALLER;
+
+  llvm::Value *N = llvm::ConstantInt::get(
+          llvm::Type::getInt32Ty(T->getContext()), flag);
+  llvm::Value *F = getBlockObjectAssign();
+  Builder.CreateCall3(F, DstObj, SrcObj, N);
+
+  CGF.FinishFunction();
+
+  return llvm::ConstantExpr::getBitCast(Fn, PtrToInt8Ty);
+}
+
+llvm::Constant *
+BlockFunction::GeneratebyrefDestroyHelperFunction(const llvm::Type *T,
+                                                  int flag) {
+  QualType R = getContext().VoidTy;
+
+  FunctionArgList Args;
+  // FIXME: This leaks
+  ImplicitParamDecl *Src =
+    ImplicitParamDecl::Create(getContext(), 0,
+                              SourceLocation(), 0,
+                              getContext().getPointerType(getContext().VoidTy));
+
+  Args.push_back(std::make_pair(Src, Src->getType()));
+
+  const CGFunctionInfo &FI =
+      CGM.getTypes().getFunctionInfo(R, Args, FunctionType::ExtInfo());
+
+  CodeGenTypes &Types = CGM.getTypes();
+  const llvm::FunctionType *LTy = Types.GetFunctionType(FI, false);
+
+  // FIXME: We'd like to put these into a mergable by content, with
+  // internal linkage.
+  llvm::Function *Fn =
+    llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage,
+                           "__Block_byref_id_object_dispose_",
+                           &CGM.getModule());
+
+  IdentifierInfo *II
+    = &CGM.getContext().Idents.get("__Block_byref_id_object_dispose_");
+
+  FunctionDecl *FD = FunctionDecl::Create(getContext(),
+                                          getContext().getTranslationUnitDecl(),
+                                          SourceLocation(), II, R, 0,
+                                          FunctionDecl::Static,
+                                          FunctionDecl::None,
+                                          false, true);
+  CGF.StartFunction(FD, R, Fn, Args, SourceLocation());
+
+  llvm::Value *V = CGF.GetAddrOfLocalVar(Src);
+  V = Builder.CreateBitCast(V, llvm::PointerType::get(T, 0));
+  V = Builder.CreateLoad(V);
+  V = Builder.CreateStructGEP(V, 6, "x");
+  V = Builder.CreateBitCast(V, llvm::PointerType::get(PtrToInt8Ty, 0));
+  V = Builder.CreateLoad(V);
+
+  flag |= BLOCK_BYREF_CALLER;
+  BuildBlockRelease(V, flag);
+  CGF.FinishFunction();
+
+  return llvm::ConstantExpr::getBitCast(Fn, PtrToInt8Ty);
+}
+
+llvm::Constant *BlockFunction::BuildbyrefCopyHelper(const llvm::Type *T,
+                                                    int Flag, unsigned Align) {
+  // All alignments below that of pointer alignment collapse down to just
+  // pointer alignment, as we always have at least that much alignment to begin
+  // with.
+  Align /= unsigned(CGF.Target.getPointerAlign(0)/8);
+  
+  // As an optimization, we only generate a single function of each kind we
+  // might need.  We need a different one for each alignment and for each
+  // setting of flags.  We mix Align and flag to get the kind.
+  uint64_t Kind = (uint64_t)Align*BLOCK_BYREF_CURRENT_MAX + Flag;
+  llvm::Constant *&Entry = CGM.AssignCache[Kind];
+  if (Entry)
+    return Entry;
+  return Entry = CodeGenFunction(CGM).GeneratebyrefCopyHelperFunction(T, Flag);
+}
+
+llvm::Constant *BlockFunction::BuildbyrefDestroyHelper(const llvm::Type *T,
+                                                       int Flag,
+                                                       unsigned Align) {
+  // All alignments below that of pointer alignment collpase down to just
+  // pointer alignment, as we always have at least that much alignment to begin
+  // with.
+  Align /= unsigned(CGF.Target.getPointerAlign(0)/8);
+  
+  // As an optimization, we only generate a single function of each kind we
+  // might need.  We need a different one for each alignment and for each
+  // setting of flags.  We mix Align and flag to get the kind.
+  uint64_t Kind = (uint64_t)Align*BLOCK_BYREF_CURRENT_MAX + Flag;
+  llvm::Constant *&Entry = CGM.DestroyCache[Kind];
+  if (Entry)
+    return Entry;
+  return Entry=CodeGenFunction(CGM).GeneratebyrefDestroyHelperFunction(T, Flag);
+}
+
+llvm::Value *BlockFunction::getBlockObjectDispose() {
+  if (CGM.BlockObjectDispose == 0) {
+    const llvm::FunctionType *FTy;
+    std::vector<const llvm::Type*> ArgTys;
+    const llvm::Type *ResultType = llvm::Type::getVoidTy(VMContext);
+    ArgTys.push_back(PtrToInt8Ty);
+    ArgTys.push_back(llvm::Type::getInt32Ty(VMContext));
+    FTy = llvm::FunctionType::get(ResultType, ArgTys, false);
+    CGM.BlockObjectDispose
+      = CGM.CreateRuntimeFunction(FTy, "_Block_object_dispose");
+  }
+  return CGM.BlockObjectDispose;
+}
+
+llvm::Value *BlockFunction::getBlockObjectAssign() {
+  if (CGM.BlockObjectAssign == 0) {
+    const llvm::FunctionType *FTy;
+    std::vector<const llvm::Type*> ArgTys;
+    const llvm::Type *ResultType = llvm::Type::getVoidTy(VMContext);
+    ArgTys.push_back(PtrToInt8Ty);
+    ArgTys.push_back(PtrToInt8Ty);
+    ArgTys.push_back(llvm::Type::getInt32Ty(VMContext));
+    FTy = llvm::FunctionType::get(ResultType, ArgTys, false);
+    CGM.BlockObjectAssign
+      = CGM.CreateRuntimeFunction(FTy, "_Block_object_assign");
+  }
+  return CGM.BlockObjectAssign;
+}
+
+void BlockFunction::BuildBlockRelease(llvm::Value *V, int flag) {
+  llvm::Value *F = getBlockObjectDispose();
+  llvm::Value *N;
+  V = Builder.CreateBitCast(V, PtrToInt8Ty);
+  N = llvm::ConstantInt::get(llvm::Type::getInt32Ty(V->getContext()), flag);
+  Builder.CreateCall2(F, V, N);
+}
+
+ASTContext &BlockFunction::getContext() const { return CGM.getContext(); }
+
+BlockFunction::BlockFunction(CodeGenModule &cgm, CodeGenFunction &cgf,
+                             CGBuilderTy &B)
+  : CGM(cgm), CGF(cgf), VMContext(cgm.getLLVMContext()), Builder(B) {
+  PtrToInt8Ty = llvm::PointerType::getUnqual(
+            llvm::Type::getInt8Ty(VMContext));
+
+  BlockHasCopyDispose = false;
+}
diff --git a/lib/CodeGen/CGBlocks.h b/lib/CodeGen/CGBlocks.h
new file mode 100644
index 0000000..5646d00
--- /dev/null
+++ b/lib/CodeGen/CGBlocks.h
@@ -0,0 +1,228 @@
+//===-- CGBlocks.h - state for LLVM CodeGen for blocks ----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This is the internal state used for llvm translation for block literals.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_CODEGEN_CGBLOCKS_H
+#define CLANG_CODEGEN_CGBLOCKS_H
+
+#include "CodeGenTypes.h"
+#include "clang/AST/Type.h"
+#include "llvm/Module.h"
+#include "llvm/ADT/SmallVector.h"
+#include "clang/Basic/TargetInfo.h"
+#include "clang/AST/CharUnits.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/ExprObjC.h"
+
+#include <vector>
+#include <map>
+
+#include "CGBuilder.h"
+#include "CGCall.h"
+#include "CGValue.h"
+
+namespace llvm {
+  class Module;
+  class Constant;
+  class Function;
+  class GlobalValue;
+  class TargetData;
+  class FunctionType;
+  class PointerType;
+  class Value;
+  class LLVMContext;
+}
+
+namespace clang {
+
+namespace CodeGen {
+class CodeGenModule;
+
+class BlockBase {
+public:
+    enum {
+        BLOCK_HAS_COPY_DISPOSE =  (1 << 25),
+        BLOCK_HAS_CXX_OBJ =       (1 << 26),
+        BLOCK_IS_GLOBAL =         (1 << 28),
+        BLOCK_USE_STRET =         (1 << 29),
+        BLOCK_HAS_SIGNATURE  =    (1 << 30)
+    };
+};
+
+
+class BlockModule : public BlockBase {
+  ASTContext &Context;
+  llvm::Module &TheModule;
+  const llvm::TargetData &TheTargetData;
+  CodeGenTypes &Types;
+  CodeGenModule &CGM;
+  llvm::LLVMContext &VMContext;
+
+  ASTContext &getContext() const { return Context; }
+  llvm::Module &getModule() const { return TheModule; }
+  CodeGenTypes &getTypes() { return Types; }
+  const llvm::TargetData &getTargetData() const { return TheTargetData; }
+public:
+  llvm::Constant *getNSConcreteGlobalBlock();
+  llvm::Constant *getNSConcreteStackBlock();
+  int getGlobalUniqueCount() { return ++Block.GlobalUniqueCount; }
+  const llvm::Type *getBlockDescriptorType();
+
+  const llvm::Type *getGenericBlockLiteralType();
+
+  llvm::Constant *GetAddrOfGlobalBlock(const BlockExpr *BE, const char *);
+
+  /// NSConcreteGlobalBlock - Cached reference to the class pointer for global
+  /// blocks.
+  llvm::Constant *NSConcreteGlobalBlock;
+
+  /// NSConcreteStackBlock - Cached reference to the class poinnter for stack
+  /// blocks.
+  llvm::Constant *NSConcreteStackBlock;
+
+  const llvm::Type *BlockDescriptorType;
+  const llvm::Type *GenericBlockLiteralType;
+
+  struct {
+    int GlobalUniqueCount;
+  } Block;
+
+  llvm::Value *BlockObjectAssign;
+  llvm::Value *BlockObjectDispose;
+  const llvm::Type *PtrToInt8Ty;
+
+  std::map<uint64_t, llvm::Constant *> AssignCache;
+  std::map<uint64_t, llvm::Constant *> DestroyCache;
+
+  BlockModule(ASTContext &C, llvm::Module &M, const llvm::TargetData &TD,
+              CodeGenTypes &T, CodeGenModule &CodeGen)
+    : Context(C), TheModule(M), TheTargetData(TD), Types(T),
+      CGM(CodeGen), VMContext(M.getContext()),
+      NSConcreteGlobalBlock(0), NSConcreteStackBlock(0), BlockDescriptorType(0),
+      GenericBlockLiteralType(0),
+      BlockObjectAssign(0), BlockObjectDispose(0) {
+    Block.GlobalUniqueCount = 0;
+    PtrToInt8Ty = llvm::Type::getInt8PtrTy(M.getContext());
+  }
+
+  bool BlockRequiresCopying(QualType Ty)
+    { return getContext().BlockRequiresCopying(Ty); }
+};
+
+class BlockFunction : public BlockBase {
+  CodeGenModule &CGM;
+  CodeGenFunction &CGF;
+  ASTContext &getContext() const;
+
+protected:
+  llvm::LLVMContext &VMContext;
+
+public:
+  const llvm::PointerType *PtrToInt8Ty;
+  struct HelperInfo {
+    int index;
+    int flag;
+    bool RequiresCopying;
+  };
+
+  enum {
+    BLOCK_FIELD_IS_OBJECT   =  3,  /* id, NSObject, __attribute__((NSObject)),
+                                      block, ... */
+    BLOCK_FIELD_IS_BLOCK    =  7,  /* a block variable */
+    BLOCK_FIELD_IS_BYREF    =  8,  /* the on stack structure holding the __block
+                                      variable */
+    BLOCK_FIELD_IS_WEAK     = 16,  /* declared __weak, only used in byref copy
+                                      helpers */
+    BLOCK_BYREF_CALLER      = 128,  /* called from __block (byref) copy/dispose
+                                      support routines */
+    BLOCK_BYREF_CURRENT_MAX = 256
+  };
+
+  /// BlockInfo - Information to generate a block literal.
+  struct BlockInfo {
+    /// BlockLiteralTy - The type of the block literal.
+    const llvm::Type *BlockLiteralTy;
+
+    /// Name - the name of the function this block was created for, if any.
+    const char *Name;
+
+    /// ByCopyDeclRefs - Variables from parent scopes that have been imported
+    /// into this block.
+    llvm::SmallVector<const BlockDeclRefExpr *, 8> DeclRefs;
+
+    BlockInfo(const llvm::Type *blt, const char *n)
+      : BlockLiteralTy(blt), Name(n) {
+      // Skip asm prefix, if any.
+      if (Name && Name[0] == '\01')
+        ++Name;
+    }
+  };
+
+  CGBuilderTy &Builder;
+
+  BlockFunction(CodeGenModule &cgm, CodeGenFunction &cgf, CGBuilderTy &B);
+
+  /// BlockOffset - The offset in bytes for the next allocation of an
+  /// imported block variable.
+  CharUnits BlockOffset;
+  /// BlockAlign - Maximal alignment needed for the Block expressed in 
+  /// characters.
+  CharUnits BlockAlign;
+
+  /// getBlockOffset - Allocate an offset for the ValueDecl from a
+  /// BlockDeclRefExpr in a block literal (BlockExpr).
+  CharUnits getBlockOffset(const BlockDeclRefExpr *E);
+
+  /// BlockHasCopyDispose - True iff the block uses copy/dispose.
+  bool BlockHasCopyDispose;
+
+  /// BlockDeclRefDecls - Decls from BlockDeclRefExprs in apperance order
+  /// in a block literal.  Decls without names are used for padding.
+  llvm::SmallVector<const Expr *, 8> BlockDeclRefDecls;
+
+  /// BlockDecls - Offsets for all Decls in BlockDeclRefExprs.
+  std::map<const Decl*, CharUnits> BlockDecls;
+
+  ImplicitParamDecl *BlockStructDecl;
+  ImplicitParamDecl *getBlockStructDecl() { return BlockStructDecl; }
+
+  llvm::Constant *GenerateCopyHelperFunction(bool, const llvm::StructType *,
+                                             std::vector<HelperInfo> *);
+  llvm::Constant *GenerateDestroyHelperFunction(bool, const llvm::StructType *,
+                                                std::vector<HelperInfo> *);
+
+  llvm::Constant *BuildCopyHelper(const llvm::StructType *,
+                                  std::vector<HelperInfo> *);
+  llvm::Constant *BuildDestroyHelper(const llvm::StructType *,
+                                     std::vector<HelperInfo> *);
+
+  llvm::Constant *GeneratebyrefCopyHelperFunction(const llvm::Type *, int flag);
+  llvm::Constant *GeneratebyrefDestroyHelperFunction(const llvm::Type *T, int);
+
+  llvm::Constant *BuildbyrefCopyHelper(const llvm::Type *T, int flag,
+                                       unsigned Align);
+  llvm::Constant *BuildbyrefDestroyHelper(const llvm::Type *T, int flag,
+                                          unsigned Align);
+
+  llvm::Value *getBlockObjectAssign();
+  llvm::Value *getBlockObjectDispose();
+  void BuildBlockRelease(llvm::Value *DeclPtr, int flag = BLOCK_FIELD_IS_BYREF);
+
+  bool BlockRequiresCopying(QualType Ty)
+    { return getContext().BlockRequiresCopying(Ty); }
+};
+
+}  // end namespace CodeGen
+}  // end namespace clang
+
+#endif
diff --git a/lib/CodeGen/CGBuilder.h b/lib/CodeGen/CGBuilder.h
new file mode 100644
index 0000000..ed56bd9
--- /dev/null
+++ b/lib/CodeGen/CGBuilder.h
@@ -0,0 +1,26 @@
+//===-- CGBuilder.h - Choose IRBuilder implementation  ----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_CODEGEN_CGBUILDER_H
+#define CLANG_CODEGEN_CGBUILDER_H
+
+#include "llvm/Support/IRBuilder.h"
+
+namespace clang {
+namespace CodeGen {
+  // Don't preserve names on values in an optimized build.
+#ifdef NDEBUG
+  typedef llvm::IRBuilder<false> CGBuilderTy;
+#else
+  typedef llvm::IRBuilder<> CGBuilderTy;
+#endif
+}  // end namespace CodeGen
+}  // end namespace clang
+
+#endif
diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp
new file mode 100644
index 0000000..95c41db
--- /dev/null
+++ b/lib/CodeGen/CGBuiltin.cpp
@@ -0,0 +1,1102 @@
+//===---- CGBuiltin.cpp - Emit LLVM Code for builtins ---------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This contains code to emit Builtin calls as LLVM code.
+//
+//===----------------------------------------------------------------------===//
+
+#include "TargetInfo.h"
+#include "CodeGenFunction.h"
+#include "CodeGenModule.h"
+#include "clang/Basic/TargetInfo.h"
+#include "clang/AST/APValue.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/Basic/TargetBuiltins.h"
+#include "llvm/Intrinsics.h"
+#include "llvm/Target/TargetData.h"
+using namespace clang;
+using namespace CodeGen;
+using namespace llvm;
+
+static void EmitMemoryBarrier(CodeGenFunction &CGF,
+                              bool LoadLoad, bool LoadStore,
+                              bool StoreLoad, bool StoreStore,
+                              bool Device) {
+  Value *True = llvm::ConstantInt::getTrue(CGF.getLLVMContext());
+  Value *False = llvm::ConstantInt::getFalse(CGF.getLLVMContext());
+  Value *C[5] = { LoadLoad ? True : False,
+                  LoadStore ? True : False,
+                  StoreLoad ? True : False,
+                  StoreStore  ? True : False,
+                  Device ? True : False };
+  CGF.Builder.CreateCall(CGF.CGM.getIntrinsic(Intrinsic::memory_barrier),
+                         C, C + 5);
+}
+
+// The atomic builtins are also full memory barriers. This is a utility for
+// wrapping a call to the builtins with memory barriers.
+static Value *EmitCallWithBarrier(CodeGenFunction &CGF, Value *Fn,
+                                  Value **ArgBegin, Value **ArgEnd) {
+  // FIXME: We need a target hook for whether this applies to device memory or
+  // not.
+  bool Device = true;
+
+  // Create barriers both before and after the call.
+  EmitMemoryBarrier(CGF, true, true, true, true, Device);
+  Value *Result = CGF.Builder.CreateCall(Fn, ArgBegin, ArgEnd);
+  EmitMemoryBarrier(CGF, true, true, true, true, Device);
+  return Result;
+}
+
+/// Utility to insert an atomic instruction based on Instrinsic::ID
+/// and the expression node.
+static RValue EmitBinaryAtomic(CodeGenFunction &CGF,
+                               Intrinsic::ID Id, const CallExpr *E) {
+  Value *Args[2] = { CGF.EmitScalarExpr(E->getArg(0)),
+                     CGF.EmitScalarExpr(E->getArg(1)) };
+  const llvm::Type *ResType[2];
+  ResType[0] = CGF.ConvertType(E->getType());
+  ResType[1] = CGF.ConvertType(E->getArg(0)->getType());
+  Value *AtomF = CGF.CGM.getIntrinsic(Id, ResType, 2);
+  return RValue::get(EmitCallWithBarrier(CGF, AtomF, Args, Args + 2));
+}
+
+/// Utility to insert an atomic instruction based Instrinsic::ID and
+// the expression node, where the return value is the result of the
+// operation.
+static RValue EmitBinaryAtomicPost(CodeGenFunction& CGF,
+                                   Intrinsic::ID Id, const CallExpr *E,
+                                   Instruction::BinaryOps Op) {
+  const llvm::Type *ResType[2];
+  ResType[0] = CGF.ConvertType(E->getType());
+  ResType[1] = CGF.ConvertType(E->getArg(0)->getType());
+  Value *AtomF = CGF.CGM.getIntrinsic(Id, ResType, 2);
+  Value *Args[2] = { CGF.EmitScalarExpr(E->getArg(0)),
+                     CGF.EmitScalarExpr(E->getArg(1)) };
+  Value *Result = EmitCallWithBarrier(CGF, AtomF, Args, Args + 2);
+  return RValue::get(CGF.Builder.CreateBinOp(Op, Result, Args[1]));
+}
+
+static llvm::ConstantInt *getInt32(llvm::LLVMContext &Context, int32_t Value) {
+  return llvm::ConstantInt::get(llvm::Type::getInt32Ty(Context), Value);
+}
+
+RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
+                                        unsigned BuiltinID, const CallExpr *E) {
+  // See if we can constant fold this builtin.  If so, don't emit it at all.
+  Expr::EvalResult Result;
+  if (E->Evaluate(Result, CGM.getContext())) {
+    if (Result.Val.isInt())
+      return RValue::get(llvm::ConstantInt::get(VMContext,
+                                                Result.Val.getInt()));
+    else if (Result.Val.isFloat())
+      return RValue::get(ConstantFP::get(VMContext, Result.Val.getFloat()));
+  }
+
+  switch (BuiltinID) {
+  default: break;  // Handle intrinsics and libm functions below.
+  case Builtin::BI__builtin___CFStringMakeConstantString:
+  case Builtin::BI__builtin___NSStringMakeConstantString:
+    return RValue::get(CGM.EmitConstantExpr(E, E->getType(), 0));
+  case Builtin::BI__builtin_stdarg_start:
+  case Builtin::BI__builtin_va_start:
+  case Builtin::BI__builtin_va_end: {
+    Value *ArgValue = EmitVAListRef(E->getArg(0));
+    const llvm::Type *DestType = llvm::Type::getInt8PtrTy(VMContext);
+    if (ArgValue->getType() != DestType)
+      ArgValue = Builder.CreateBitCast(ArgValue, DestType,
+                                       ArgValue->getName().data());
+
+    Intrinsic::ID inst = (BuiltinID == Builtin::BI__builtin_va_end) ?
+      Intrinsic::vaend : Intrinsic::vastart;
+    return RValue::get(Builder.CreateCall(CGM.getIntrinsic(inst), ArgValue));
+  }
+  case Builtin::BI__builtin_va_copy: {
+    Value *DstPtr = EmitVAListRef(E->getArg(0));
+    Value *SrcPtr = EmitVAListRef(E->getArg(1));
+
+    const llvm::Type *Type = llvm::Type::getInt8PtrTy(VMContext);
+
+    DstPtr = Builder.CreateBitCast(DstPtr, Type);
+    SrcPtr = Builder.CreateBitCast(SrcPtr, Type);
+    return RValue::get(Builder.CreateCall2(CGM.getIntrinsic(Intrinsic::vacopy),
+                                           DstPtr, SrcPtr));
+  }
+  case Builtin::BI__builtin_abs: {
+    Value *ArgValue = EmitScalarExpr(E->getArg(0));
+
+    Value *NegOp = Builder.CreateNeg(ArgValue, "neg");
+    Value *CmpResult =
+    Builder.CreateICmpSGE(ArgValue,
+                          llvm::Constant::getNullValue(ArgValue->getType()),
+                                                            "abscond");
+    Value *Result =
+      Builder.CreateSelect(CmpResult, ArgValue, NegOp, "abs");
+
+    return RValue::get(Result);
+  }
+  case Builtin::BI__builtin_ctz:
+  case Builtin::BI__builtin_ctzl:
+  case Builtin::BI__builtin_ctzll: {
+    Value *ArgValue = EmitScalarExpr(E->getArg(0));
+
+    const llvm::Type *ArgType = ArgValue->getType();
+    Value *F = CGM.getIntrinsic(Intrinsic::cttz, &ArgType, 1);
+
+    const llvm::Type *ResultType = ConvertType(E->getType());
+    Value *Result = Builder.CreateCall(F, ArgValue, "tmp");
+    if (Result->getType() != ResultType)
+      Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true,
+                                     "cast");
+    return RValue::get(Result);
+  }
+  case Builtin::BI__builtin_clz:
+  case Builtin::BI__builtin_clzl:
+  case Builtin::BI__builtin_clzll: {
+    Value *ArgValue = EmitScalarExpr(E->getArg(0));
+
+    const llvm::Type *ArgType = ArgValue->getType();
+    Value *F = CGM.getIntrinsic(Intrinsic::ctlz, &ArgType, 1);
+
+    const llvm::Type *ResultType = ConvertType(E->getType());
+    Value *Result = Builder.CreateCall(F, ArgValue, "tmp");
+    if (Result->getType() != ResultType)
+      Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true,
+                                     "cast");
+    return RValue::get(Result);
+  }
+  case Builtin::BI__builtin_ffs:
+  case Builtin::BI__builtin_ffsl:
+  case Builtin::BI__builtin_ffsll: {
+    // ffs(x) -> x ? cttz(x) + 1 : 0
+    Value *ArgValue = EmitScalarExpr(E->getArg(0));
+
+    const llvm::Type *ArgType = ArgValue->getType();
+    Value *F = CGM.getIntrinsic(Intrinsic::cttz, &ArgType, 1);
+
+    const llvm::Type *ResultType = ConvertType(E->getType());
+    Value *Tmp = Builder.CreateAdd(Builder.CreateCall(F, ArgValue, "tmp"),
+                                   llvm::ConstantInt::get(ArgType, 1), "tmp");
+    Value *Zero = llvm::Constant::getNullValue(ArgType);
+    Value *IsZero = Builder.CreateICmpEQ(ArgValue, Zero, "iszero");
+    Value *Result = Builder.CreateSelect(IsZero, Zero, Tmp, "ffs");
+    if (Result->getType() != ResultType)
+      Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true,
+                                     "cast");
+    return RValue::get(Result);
+  }
+  case Builtin::BI__builtin_parity:
+  case Builtin::BI__builtin_parityl:
+  case Builtin::BI__builtin_parityll: {
+    // parity(x) -> ctpop(x) & 1
+    Value *ArgValue = EmitScalarExpr(E->getArg(0));
+
+    const llvm::Type *ArgType = ArgValue->getType();
+    Value *F = CGM.getIntrinsic(Intrinsic::ctpop, &ArgType, 1);
+
+    const llvm::Type *ResultType = ConvertType(E->getType());
+    Value *Tmp = Builder.CreateCall(F, ArgValue, "tmp");
+    Value *Result = Builder.CreateAnd(Tmp, llvm::ConstantInt::get(ArgType, 1),
+                                      "tmp");
+    if (Result->getType() != ResultType)
+      Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true,
+                                     "cast");
+    return RValue::get(Result);
+  }
+  case Builtin::BI__builtin_popcount:
+  case Builtin::BI__builtin_popcountl:
+  case Builtin::BI__builtin_popcountll: {
+    Value *ArgValue = EmitScalarExpr(E->getArg(0));
+
+    const llvm::Type *ArgType = ArgValue->getType();
+    Value *F = CGM.getIntrinsic(Intrinsic::ctpop, &ArgType, 1);
+
+    const llvm::Type *ResultType = ConvertType(E->getType());
+    Value *Result = Builder.CreateCall(F, ArgValue, "tmp");
+    if (Result->getType() != ResultType)
+      Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true,
+                                     "cast");
+    return RValue::get(Result);
+  }
+  case Builtin::BI__builtin_expect:
+    // FIXME: pass expect through to LLVM
+    return RValue::get(EmitScalarExpr(E->getArg(0)));
+  case Builtin::BI__builtin_bswap32:
+  case Builtin::BI__builtin_bswap64: {
+    Value *ArgValue = EmitScalarExpr(E->getArg(0));
+    const llvm::Type *ArgType = ArgValue->getType();
+    Value *F = CGM.getIntrinsic(Intrinsic::bswap, &ArgType, 1);
+    return RValue::get(Builder.CreateCall(F, ArgValue, "tmp"));
+  }
+  case Builtin::BI__builtin_object_size: {
+    // We pass this builtin onto the optimizer so that it can
+    // figure out the object size in more complex cases.
+    const llvm::Type *ResType[] = {
+      ConvertType(E->getType())
+    };
+    
+    // LLVM only supports 0 and 2, make sure that we pass along that
+    // as a boolean.
+    Value *Ty = EmitScalarExpr(E->getArg(1));
+    ConstantInt *CI = dyn_cast<ConstantInt>(Ty);
+    assert(CI);
+    uint64_t val = CI->getZExtValue();
+    CI = ConstantInt::get(llvm::Type::getInt1Ty(VMContext), (val & 0x2) >> 1);    
+    
+    Value *F = CGM.getIntrinsic(Intrinsic::objectsize, ResType, 1);
+    return RValue::get(Builder.CreateCall2(F,
+                                           EmitScalarExpr(E->getArg(0)),
+                                           CI));
+  }
+  case Builtin::BI__builtin_prefetch: {
+    Value *Locality, *RW, *Address = EmitScalarExpr(E->getArg(0));
+    // FIXME: Technically these constants should of type 'int', yes?
+    RW = (E->getNumArgs() > 1) ? EmitScalarExpr(E->getArg(1)) :
+      llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 0);
+    Locality = (E->getNumArgs() > 2) ? EmitScalarExpr(E->getArg(2)) :
+      llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 3);
+    Value *F = CGM.getIntrinsic(Intrinsic::prefetch, 0, 0);
+    return RValue::get(Builder.CreateCall3(F, Address, RW, Locality));
+  }
+  case Builtin::BI__builtin_trap: {
+    Value *F = CGM.getIntrinsic(Intrinsic::trap, 0, 0);
+    return RValue::get(Builder.CreateCall(F));
+  }
+  case Builtin::BI__builtin_unreachable: {
+    if (CatchUndefined && HaveInsertPoint())
+      EmitBranch(getTrapBB());
+    Value *V = Builder.CreateUnreachable();
+    Builder.ClearInsertionPoint();
+    return RValue::get(V);
+  }
+      
+  case Builtin::BI__builtin_powi:
+  case Builtin::BI__builtin_powif:
+  case Builtin::BI__builtin_powil: {
+    Value *Base = EmitScalarExpr(E->getArg(0));
+    Value *Exponent = EmitScalarExpr(E->getArg(1));
+    const llvm::Type *ArgType = Base->getType();
+    Value *F = CGM.getIntrinsic(Intrinsic::powi, &ArgType, 1);
+    return RValue::get(Builder.CreateCall2(F, Base, Exponent, "tmp"));
+  }
+
+  case Builtin::BI__builtin_isgreater:
+  case Builtin::BI__builtin_isgreaterequal:
+  case Builtin::BI__builtin_isless:
+  case Builtin::BI__builtin_islessequal:
+  case Builtin::BI__builtin_islessgreater:
+  case Builtin::BI__builtin_isunordered: {
+    // Ordered comparisons: we know the arguments to these are matching scalar
+    // floating point values.
+    Value *LHS = EmitScalarExpr(E->getArg(0));
+    Value *RHS = EmitScalarExpr(E->getArg(1));
+
+    switch (BuiltinID) {
+    default: assert(0 && "Unknown ordered comparison");
+    case Builtin::BI__builtin_isgreater:
+      LHS = Builder.CreateFCmpOGT(LHS, RHS, "cmp");
+      break;
+    case Builtin::BI__builtin_isgreaterequal:
+      LHS = Builder.CreateFCmpOGE(LHS, RHS, "cmp");
+      break;
+    case Builtin::BI__builtin_isless:
+      LHS = Builder.CreateFCmpOLT(LHS, RHS, "cmp");
+      break;
+    case Builtin::BI__builtin_islessequal:
+      LHS = Builder.CreateFCmpOLE(LHS, RHS, "cmp");
+      break;
+    case Builtin::BI__builtin_islessgreater:
+      LHS = Builder.CreateFCmpONE(LHS, RHS, "cmp");
+      break;
+    case Builtin::BI__builtin_isunordered:
+      LHS = Builder.CreateFCmpUNO(LHS, RHS, "cmp");
+      break;
+    }
+    // ZExt bool to int type.
+    return RValue::get(Builder.CreateZExt(LHS, ConvertType(E->getType()),
+                                          "tmp"));
+  }
+  case Builtin::BI__builtin_isnan: {
+    Value *V = EmitScalarExpr(E->getArg(0));
+    V = Builder.CreateFCmpUNO(V, V, "cmp");
+    return RValue::get(Builder.CreateZExt(V, ConvertType(E->getType()), "tmp"));
+  }
+  case Builtin::BIalloca:
+  case Builtin::BI__builtin_alloca: {
+    // FIXME: LLVM IR Should allow alloca with an i64 size!
+    Value *Size = EmitScalarExpr(E->getArg(0));
+    Size = Builder.CreateIntCast(Size, llvm::Type::getInt32Ty(VMContext), false, "tmp");
+    return RValue::get(Builder.CreateAlloca(llvm::Type::getInt8Ty(VMContext), Size, "tmp"));
+  }
+  case Builtin::BIbzero:
+  case Builtin::BI__builtin_bzero: {
+    Value *Address = EmitScalarExpr(E->getArg(0));
+    Value *SizeVal = EmitScalarExpr(E->getArg(1));
+    Builder.CreateCall5(CGM.getMemSetFn(Address->getType(), SizeVal->getType()),
+                   Address,
+                   llvm::ConstantInt::get(llvm::Type::getInt8Ty(VMContext), 0),
+                   SizeVal,
+                   llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 1),
+                   llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), 0));
+    return RValue::get(Address);
+  }
+  case Builtin::BImemcpy:
+  case Builtin::BI__builtin_memcpy: {
+    Value *Address = EmitScalarExpr(E->getArg(0));
+    Value *SrcAddr = EmitScalarExpr(E->getArg(1));
+    Value *SizeVal = EmitScalarExpr(E->getArg(2));
+    Builder.CreateCall5(CGM.getMemCpyFn(Address->getType(), SrcAddr->getType(),
+                                        SizeVal->getType()),
+                  Address, SrcAddr, SizeVal, 
+                  llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 1),
+                  llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), 0));
+    return RValue::get(Address);
+  }
+  case Builtin::BImemmove:
+  case Builtin::BI__builtin_memmove: {
+    Value *Address = EmitScalarExpr(E->getArg(0));
+    Value *SrcAddr = EmitScalarExpr(E->getArg(1));
+    Value *SizeVal = EmitScalarExpr(E->getArg(2));
+    Builder.CreateCall5(CGM.getMemMoveFn(Address->getType(), SrcAddr->getType(),
+                                         SizeVal->getType()),
+                  Address, SrcAddr, SizeVal, 
+                  llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 1),
+                  llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), 0));
+    return RValue::get(Address);
+  }
+  case Builtin::BImemset:
+  case Builtin::BI__builtin_memset: {
+    Value *Address = EmitScalarExpr(E->getArg(0));
+    Value *SizeVal = EmitScalarExpr(E->getArg(2));
+    Builder.CreateCall5(CGM.getMemSetFn(Address->getType(), SizeVal->getType()),
+                  Address,
+                  Builder.CreateTrunc(EmitScalarExpr(E->getArg(1)),
+                                      llvm::Type::getInt8Ty(VMContext)),
+                  SizeVal,
+                  llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 1),
+                  llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), 0));
+    return RValue::get(Address);
+  }
+  case Builtin::BI__builtin_dwarf_cfa: {
+    // The offset in bytes from the first argument to the CFA.
+    //
+    // Why on earth is this in the frontend?  Is there any reason at
+    // all that the backend can't reasonably determine this while
+    // lowering llvm.eh.dwarf.cfa()?
+    //
+    // TODO: If there's a satisfactory reason, add a target hook for
+    // this instead of hard-coding 0, which is correct for most targets.
+    int32_t Offset = 0;
+
+    Value *F = CGM.getIntrinsic(Intrinsic::eh_dwarf_cfa, 0, 0);
+    return RValue::get(Builder.CreateCall(F, getInt32(VMContext, Offset)));
+  }
+  case Builtin::BI__builtin_return_address: {
+    Value *Depth = EmitScalarExpr(E->getArg(0));
+    Depth = Builder.CreateIntCast(Depth,
+                                  llvm::Type::getInt32Ty(VMContext),
+                                  false, "tmp");
+    Value *F = CGM.getIntrinsic(Intrinsic::returnaddress, 0, 0);
+    return RValue::get(Builder.CreateCall(F, Depth));
+  }
+  case Builtin::BI__builtin_frame_address: {
+    Value *Depth = EmitScalarExpr(E->getArg(0));
+    Depth = Builder.CreateIntCast(Depth,
+                                  llvm::Type::getInt32Ty(VMContext),
+                                  false, "tmp");
+    Value *F = CGM.getIntrinsic(Intrinsic::frameaddress, 0, 0);
+    return RValue::get(Builder.CreateCall(F, Depth));
+  }
+  case Builtin::BI__builtin_extract_return_addr: {
+    Value *Address = EmitScalarExpr(E->getArg(0));
+    Value *Result = getTargetHooks().decodeReturnAddress(*this, Address);
+    return RValue::get(Result);
+  }
+  case Builtin::BI__builtin_frob_return_addr: {
+    Value *Address = EmitScalarExpr(E->getArg(0));
+    Value *Result = getTargetHooks().encodeReturnAddress(*this, Address);
+    return RValue::get(Result);
+  }
+  case Builtin::BI__builtin_dwarf_sp_column: {
+    const llvm::IntegerType *Ty
+      = cast<llvm::IntegerType>(ConvertType(E->getType()));
+    int Column = getTargetHooks().getDwarfEHStackPointer(CGM);
+    if (Column == -1) {
+      CGM.ErrorUnsupported(E, "__builtin_dwarf_sp_column");
+      return RValue::get(llvm::UndefValue::get(Ty));
+    }
+    return RValue::get(llvm::ConstantInt::get(Ty, Column, true));
+  }
+  case Builtin::BI__builtin_init_dwarf_reg_size_table: {
+    Value *Address = EmitScalarExpr(E->getArg(0));
+    if (getTargetHooks().initDwarfEHRegSizeTable(*this, Address))
+      CGM.ErrorUnsupported(E, "__builtin_init_dwarf_reg_size_table");
+    return RValue::get(llvm::UndefValue::get(ConvertType(E->getType())));
+  }
+  case Builtin::BI__builtin_eh_return: {
+    Value *Int = EmitScalarExpr(E->getArg(0));
+    Value *Ptr = EmitScalarExpr(E->getArg(1));
+
+    const llvm::IntegerType *IntTy = cast<llvm::IntegerType>(Int->getType());
+    assert((IntTy->getBitWidth() == 32 || IntTy->getBitWidth() == 64) &&
+           "LLVM's __builtin_eh_return only supports 32- and 64-bit variants");
+    Value *F = CGM.getIntrinsic(IntTy->getBitWidth() == 32
+                                  ? Intrinsic::eh_return_i32
+                                  : Intrinsic::eh_return_i64,
+                                0, 0);
+    Builder.CreateCall2(F, Int, Ptr);
+    Value *V = Builder.CreateUnreachable();
+    Builder.ClearInsertionPoint();
+    return RValue::get(V);
+  }
+  case Builtin::BI__builtin_unwind_init: {
+    Value *F = CGM.getIntrinsic(Intrinsic::eh_unwind_init, 0, 0);
+    return RValue::get(Builder.CreateCall(F));
+  }
+  case Builtin::BI__builtin_extend_pointer: {
+    // Extends a pointer to the size of an _Unwind_Word, which is
+    // uint64_t on all platforms.  Generally this gets poked into a
+    // register and eventually used as an address, so if the
+    // addressing registers are wider than pointers and the platform
+    // doesn't implicitly ignore high-order bits when doing
+    // addressing, we need to make sure we zext / sext based on
+    // the platform's expectations.
+    //
+    // See: http://gcc.gnu.org/ml/gcc-bugs/2002-02/msg00237.html
+
+    LLVMContext &C = CGM.getLLVMContext();
+
+    // Cast the pointer to intptr_t.
+    Value *Ptr = EmitScalarExpr(E->getArg(0));
+    const llvm::IntegerType *IntPtrTy = CGM.getTargetData().getIntPtrType(C);
+    Value *Result = Builder.CreatePtrToInt(Ptr, IntPtrTy, "extend.cast");
+
+    // If that's 64 bits, we're done.
+    if (IntPtrTy->getBitWidth() == 64)
+      return RValue::get(Result);
+
+    // Otherwise, ask the codegen data what to do.
+    const llvm::IntegerType *Int64Ty = llvm::IntegerType::get(C, 64);
+    if (getTargetHooks().extendPointerWithSExt())
+      return RValue::get(Builder.CreateSExt(Result, Int64Ty, "extend.sext"));
+    else
+      return RValue::get(Builder.CreateZExt(Result, Int64Ty, "extend.zext"));
+  }
+#if 0
+  // FIXME: Finish/enable when LLVM backend support stabilizes
+  case Builtin::BI__builtin_setjmp: {
+    Value *Buf = EmitScalarExpr(E->getArg(0));
+    // Store the frame pointer to the buffer
+    Value *FrameAddrF = CGM.getIntrinsic(Intrinsic::frameaddress, 0, 0);
+    Value *FrameAddr =
+        Builder.CreateCall(FrameAddrF,
+                           Constant::getNullValue(llvm::Type::getInt32Ty(VMContext)));
+    Builder.CreateStore(FrameAddr, Buf);
+    // Call the setjmp intrinsic
+    Value *F = CGM.getIntrinsic(Intrinsic::eh_sjlj_setjmp, 0, 0);
+    const llvm::Type *DestType = llvm::Type::getInt8PtrTy(VMContext);
+    Buf = Builder.CreateBitCast(Buf, DestType);
+    return RValue::get(Builder.CreateCall(F, Buf));
+  }
+  case Builtin::BI__builtin_longjmp: {
+    Value *F = CGM.getIntrinsic(Intrinsic::eh_sjlj_longjmp, 0, 0);
+    Value *Buf = EmitScalarExpr(E->getArg(0));
+    const llvm::Type *DestType = llvm::Type::getInt8PtrTy(VMContext);
+    Buf = Builder.CreateBitCast(Buf, DestType);
+    return RValue::get(Builder.CreateCall(F, Buf));
+  }
+#endif
+  case Builtin::BI__sync_fetch_and_add:
+  case Builtin::BI__sync_fetch_and_sub:
+  case Builtin::BI__sync_fetch_and_or:
+  case Builtin::BI__sync_fetch_and_and:
+  case Builtin::BI__sync_fetch_and_xor:
+  case Builtin::BI__sync_add_and_fetch:
+  case Builtin::BI__sync_sub_and_fetch:
+  case Builtin::BI__sync_and_and_fetch:
+  case Builtin::BI__sync_or_and_fetch:
+  case Builtin::BI__sync_xor_and_fetch:
+  case Builtin::BI__sync_val_compare_and_swap:
+  case Builtin::BI__sync_bool_compare_and_swap:
+  case Builtin::BI__sync_lock_test_and_set:
+  case Builtin::BI__sync_lock_release:
+    assert(0 && "Shouldn't make it through sema");
+  case Builtin::BI__sync_fetch_and_add_1:
+  case Builtin::BI__sync_fetch_and_add_2:
+  case Builtin::BI__sync_fetch_and_add_4:
+  case Builtin::BI__sync_fetch_and_add_8:
+  case Builtin::BI__sync_fetch_and_add_16:
+    return EmitBinaryAtomic(*this, Intrinsic::atomic_load_add, E);
+  case Builtin::BI__sync_fetch_and_sub_1:
+  case Builtin::BI__sync_fetch_and_sub_2:
+  case Builtin::BI__sync_fetch_and_sub_4:
+  case Builtin::BI__sync_fetch_and_sub_8:
+  case Builtin::BI__sync_fetch_and_sub_16:
+    return EmitBinaryAtomic(*this, Intrinsic::atomic_load_sub, E);
+  case Builtin::BI__sync_fetch_and_or_1:
+  case Builtin::BI__sync_fetch_and_or_2:
+  case Builtin::BI__sync_fetch_and_or_4:
+  case Builtin::BI__sync_fetch_and_or_8:
+  case Builtin::BI__sync_fetch_and_or_16:
+    return EmitBinaryAtomic(*this, Intrinsic::atomic_load_or, E);
+  case Builtin::BI__sync_fetch_and_and_1:
+  case Builtin::BI__sync_fetch_and_and_2:
+  case Builtin::BI__sync_fetch_and_and_4:
+  case Builtin::BI__sync_fetch_and_and_8:
+  case Builtin::BI__sync_fetch_and_and_16:
+    return EmitBinaryAtomic(*this, Intrinsic::atomic_load_and, E);
+  case Builtin::BI__sync_fetch_and_xor_1:
+  case Builtin::BI__sync_fetch_and_xor_2:
+  case Builtin::BI__sync_fetch_and_xor_4:
+  case Builtin::BI__sync_fetch_and_xor_8:
+  case Builtin::BI__sync_fetch_and_xor_16:
+    return EmitBinaryAtomic(*this, Intrinsic::atomic_load_xor, E);
+
+  // Clang extensions: not overloaded yet.
+  case Builtin::BI__sync_fetch_and_min:
+    return EmitBinaryAtomic(*this, Intrinsic::atomic_load_min, E);
+  case Builtin::BI__sync_fetch_and_max:
+    return EmitBinaryAtomic(*this, Intrinsic::atomic_load_max, E);
+  case Builtin::BI__sync_fetch_and_umin:
+    return EmitBinaryAtomic(*this, Intrinsic::atomic_load_umin, E);
+  case Builtin::BI__sync_fetch_and_umax:
+    return EmitBinaryAtomic(*this, Intrinsic::atomic_load_umax, E);
+
+  case Builtin::BI__sync_add_and_fetch_1:
+  case Builtin::BI__sync_add_and_fetch_2:
+  case Builtin::BI__sync_add_and_fetch_4:
+  case Builtin::BI__sync_add_and_fetch_8:
+  case Builtin::BI__sync_add_and_fetch_16:
+    return EmitBinaryAtomicPost(*this, Intrinsic::atomic_load_add, E,
+                                llvm::Instruction::Add);
+  case Builtin::BI__sync_sub_and_fetch_1:
+  case Builtin::BI__sync_sub_and_fetch_2:
+  case Builtin::BI__sync_sub_and_fetch_4:
+  case Builtin::BI__sync_sub_and_fetch_8:
+  case Builtin::BI__sync_sub_and_fetch_16:
+    return EmitBinaryAtomicPost(*this, Intrinsic::atomic_load_sub, E,
+                                llvm::Instruction::Sub);
+  case Builtin::BI__sync_and_and_fetch_1:
+  case Builtin::BI__sync_and_and_fetch_2:
+  case Builtin::BI__sync_and_and_fetch_4:
+  case Builtin::BI__sync_and_and_fetch_8:
+  case Builtin::BI__sync_and_and_fetch_16:
+    return EmitBinaryAtomicPost(*this, Intrinsic::atomic_load_and, E,
+                                llvm::Instruction::And);
+  case Builtin::BI__sync_or_and_fetch_1:
+  case Builtin::BI__sync_or_and_fetch_2:
+  case Builtin::BI__sync_or_and_fetch_4:
+  case Builtin::BI__sync_or_and_fetch_8:
+  case Builtin::BI__sync_or_and_fetch_16:
+    return EmitBinaryAtomicPost(*this, Intrinsic::atomic_load_or, E,
+                                llvm::Instruction::Or);
+  case Builtin::BI__sync_xor_and_fetch_1:
+  case Builtin::BI__sync_xor_and_fetch_2:
+  case Builtin::BI__sync_xor_and_fetch_4:
+  case Builtin::BI__sync_xor_and_fetch_8:
+  case Builtin::BI__sync_xor_and_fetch_16:
+    return EmitBinaryAtomicPost(*this, Intrinsic::atomic_load_xor, E,
+                                llvm::Instruction::Xor);
+
+  case Builtin::BI__sync_val_compare_and_swap_1:
+  case Builtin::BI__sync_val_compare_and_swap_2:
+  case Builtin::BI__sync_val_compare_and_swap_4:
+  case Builtin::BI__sync_val_compare_and_swap_8:
+  case Builtin::BI__sync_val_compare_and_swap_16: {
+    const llvm::Type *ResType[2];
+    ResType[0]= ConvertType(E->getType());
+    ResType[1] = ConvertType(E->getArg(0)->getType());
+    Value *AtomF = CGM.getIntrinsic(Intrinsic::atomic_cmp_swap, ResType, 2);
+    Value *Args[3] = { EmitScalarExpr(E->getArg(0)),
+                       EmitScalarExpr(E->getArg(1)),
+                       EmitScalarExpr(E->getArg(2)) };
+    return RValue::get(EmitCallWithBarrier(*this, AtomF, Args, Args + 3));
+  }
+
+  case Builtin::BI__sync_bool_compare_and_swap_1:
+  case Builtin::BI__sync_bool_compare_and_swap_2:
+  case Builtin::BI__sync_bool_compare_and_swap_4:
+  case Builtin::BI__sync_bool_compare_and_swap_8:
+  case Builtin::BI__sync_bool_compare_and_swap_16: {
+    const llvm::Type *ResType[2];
+    ResType[0]= ConvertType(E->getArg(1)->getType());
+    ResType[1] = llvm::PointerType::getUnqual(ResType[0]);
+    Value *AtomF = CGM.getIntrinsic(Intrinsic::atomic_cmp_swap, ResType, 2);
+    Value *OldVal = EmitScalarExpr(E->getArg(1));
+    Value *Args[3] = { EmitScalarExpr(E->getArg(0)),
+                       OldVal,
+                       EmitScalarExpr(E->getArg(2)) };
+    Value *PrevVal = EmitCallWithBarrier(*this, AtomF, Args, Args + 3);
+    Value *Result = Builder.CreateICmpEQ(PrevVal, OldVal);
+    // zext bool to int.
+    return RValue::get(Builder.CreateZExt(Result, ConvertType(E->getType())));
+  }
+
+  case Builtin::BI__sync_lock_test_and_set_1:
+  case Builtin::BI__sync_lock_test_and_set_2:
+  case Builtin::BI__sync_lock_test_and_set_4:
+  case Builtin::BI__sync_lock_test_and_set_8:
+  case Builtin::BI__sync_lock_test_and_set_16:
+    return EmitBinaryAtomic(*this, Intrinsic::atomic_swap, E);
+
+  case Builtin::BI__sync_lock_release_1:
+  case Builtin::BI__sync_lock_release_2:
+  case Builtin::BI__sync_lock_release_4:
+  case Builtin::BI__sync_lock_release_8:
+  case Builtin::BI__sync_lock_release_16: {
+    Value *Ptr = EmitScalarExpr(E->getArg(0));
+    const llvm::Type *ElTy =
+      cast<llvm::PointerType>(Ptr->getType())->getElementType();
+    llvm::StoreInst *Store = 
+      Builder.CreateStore(llvm::Constant::getNullValue(ElTy), Ptr);
+    Store->setVolatile(true);
+    return RValue::get(0);
+  }
+
+  case Builtin::BI__sync_synchronize: {
+    // We assume like gcc appears to, that this only applies to cached memory.
+    EmitMemoryBarrier(*this, true, true, true, true, false);
+    return RValue::get(0);
+  }
+
+  case Builtin::BI__builtin_llvm_memory_barrier: {
+    Value *C[5] = {
+      EmitScalarExpr(E->getArg(0)),
+      EmitScalarExpr(E->getArg(1)),
+      EmitScalarExpr(E->getArg(2)),
+      EmitScalarExpr(E->getArg(3)),
+      EmitScalarExpr(E->getArg(4))
+    };
+    Builder.CreateCall(CGM.getIntrinsic(Intrinsic::memory_barrier), C, C + 5);
+    return RValue::get(0);
+  }
+      
+    // Library functions with special handling.
+  case Builtin::BIsqrt:
+  case Builtin::BIsqrtf:
+  case Builtin::BIsqrtl: {
+    // TODO: there is currently no set of optimizer flags
+    // sufficient for us to rewrite sqrt to @llvm.sqrt.
+    // -fmath-errno=0 is not good enough; we need finiteness.
+    // We could probably precondition the call with an ult
+    // against 0, but is that worth the complexity?
+    break;
+  }
+
+  case Builtin::BIpow:
+  case Builtin::BIpowf:
+  case Builtin::BIpowl: {
+    // Rewrite sqrt to intrinsic if allowed.
+    if (!FD->hasAttr<ConstAttr>())
+      break;
+    Value *Base = EmitScalarExpr(E->getArg(0));
+    Value *Exponent = EmitScalarExpr(E->getArg(1));
+    const llvm::Type *ArgType = Base->getType();
+    Value *F = CGM.getIntrinsic(Intrinsic::pow, &ArgType, 1);
+    return RValue::get(Builder.CreateCall2(F, Base, Exponent, "tmp"));
+  }
+
+  case Builtin::BI__builtin_signbit:
+  case Builtin::BI__builtin_signbitf:
+  case Builtin::BI__builtin_signbitl: {
+    LLVMContext &C = CGM.getLLVMContext();
+
+    Value *Arg = EmitScalarExpr(E->getArg(0));
+    const llvm::Type *ArgTy = Arg->getType();
+    if (ArgTy->isPPC_FP128Ty())
+      break; // FIXME: I'm not sure what the right implementation is here.
+    int ArgWidth = ArgTy->getPrimitiveSizeInBits();
+    const llvm::Type *ArgIntTy = llvm::IntegerType::get(C, ArgWidth);
+    Value *BCArg = Builder.CreateBitCast(Arg, ArgIntTy);
+    Value *ZeroCmp = llvm::Constant::getNullValue(ArgIntTy);
+    Value *Result = Builder.CreateICmpSLT(BCArg, ZeroCmp);
+    return RValue::get(Builder.CreateZExt(Result, ConvertType(E->getType())));
+  }
+  }
+
+  // If this is an alias for a libm function (e.g. __builtin_sin) turn it into
+  // that function.
+  if (getContext().BuiltinInfo.isLibFunction(BuiltinID) ||
+      getContext().BuiltinInfo.isPredefinedLibFunction(BuiltinID))
+    return EmitCall(E->getCallee()->getType(),
+                    CGM.getBuiltinLibFunction(FD, BuiltinID),
+                    ReturnValueSlot(),
+                    E->arg_begin(), E->arg_end());
+
+  // See if we have a target specific intrinsic.
+  const char *Name = getContext().BuiltinInfo.GetName(BuiltinID);
+  Intrinsic::ID IntrinsicID = Intrinsic::not_intrinsic;
+  if (const char *Prefix =
+      llvm::Triple::getArchTypePrefix(Target.getTriple().getArch()))
+    IntrinsicID = Intrinsic::getIntrinsicForGCCBuiltin(Prefix, Name);
+
+  if (IntrinsicID != Intrinsic::not_intrinsic) {
+    SmallVector<Value*, 16> Args;
+
+    Function *F = CGM.getIntrinsic(IntrinsicID);
+    const llvm::FunctionType *FTy = F->getFunctionType();
+
+    for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) {
+      Value *ArgValue = EmitScalarExpr(E->getArg(i));
+
+      // If the intrinsic arg type is different from the builtin arg type
+      // we need to do a bit cast.
+      const llvm::Type *PTy = FTy->getParamType(i);
+      if (PTy != ArgValue->getType()) {
+        assert(PTy->canLosslesslyBitCastTo(FTy->getParamType(i)) &&
+               "Must be able to losslessly bit cast to param");
+        ArgValue = Builder.CreateBitCast(ArgValue, PTy);
+      }
+
+      Args.push_back(ArgValue);
+    }
+
+    Value *V = Builder.CreateCall(F, Args.data(), Args.data() + Args.size());
+    QualType BuiltinRetType = E->getType();
+
+    const llvm::Type *RetTy = llvm::Type::getVoidTy(VMContext);
+    if (!BuiltinRetType->isVoidType()) RetTy = ConvertType(BuiltinRetType);
+
+    if (RetTy != V->getType()) {
+      assert(V->getType()->canLosslesslyBitCastTo(RetTy) &&
+             "Must be able to losslessly bit cast result type");
+      V = Builder.CreateBitCast(V, RetTy);
+    }
+
+    return RValue::get(V);
+  }
+
+  // See if we have a target specific builtin that needs to be lowered.
+  if (Value *V = EmitTargetBuiltinExpr(BuiltinID, E))
+    return RValue::get(V);
+
+  ErrorUnsupported(E, "builtin function");
+
+  // Unknown builtin, for now just dump it out and return undef.
+  if (hasAggregateLLVMType(E->getType()))
+    return RValue::getAggregate(CreateMemTemp(E->getType()));
+  return RValue::get(llvm::UndefValue::get(ConvertType(E->getType())));
+}
+
+Value *CodeGenFunction::EmitTargetBuiltinExpr(unsigned BuiltinID,
+                                              const CallExpr *E) {
+  switch (Target.getTriple().getArch()) {
+  case llvm::Triple::arm:
+  case llvm::Triple::thumb:
+    return EmitARMBuiltinExpr(BuiltinID, E);
+  case llvm::Triple::x86:
+  case llvm::Triple::x86_64:
+    return EmitX86BuiltinExpr(BuiltinID, E);
+  case llvm::Triple::ppc:
+  case llvm::Triple::ppc64:
+    return EmitPPCBuiltinExpr(BuiltinID, E);
+  default:
+    return 0;
+  }
+}
+
+Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID,
+                                           const CallExpr *E) {
+  switch (BuiltinID) {
+  default: return 0;
+
+  case ARM::BI__builtin_thread_pointer: {
+    Value *AtomF = CGM.getIntrinsic(Intrinsic::arm_thread_pointer, 0, 0);
+    return Builder.CreateCall(AtomF);
+  }
+  }
+}
+
+Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID,
+                                           const CallExpr *E) {
+
+  llvm::SmallVector<Value*, 4> Ops;
+
+  for (unsigned i = 0, e = E->getNumArgs(); i != e; i++)
+    Ops.push_back(EmitScalarExpr(E->getArg(i)));
+
+  switch (BuiltinID) {
+  default: return 0;
+  case X86::BI__builtin_ia32_pslldi128:
+  case X86::BI__builtin_ia32_psllqi128:
+  case X86::BI__builtin_ia32_psllwi128:
+  case X86::BI__builtin_ia32_psradi128:
+  case X86::BI__builtin_ia32_psrawi128:
+  case X86::BI__builtin_ia32_psrldi128:
+  case X86::BI__builtin_ia32_psrlqi128:
+  case X86::BI__builtin_ia32_psrlwi128: {
+    Ops[1] = Builder.CreateZExt(Ops[1], llvm::Type::getInt64Ty(VMContext), "zext");
+    const llvm::Type *Ty = llvm::VectorType::get(llvm::Type::getInt64Ty(VMContext), 2);
+    llvm::Value *Zero = llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 0);
+    Ops[1] = Builder.CreateInsertElement(llvm::UndefValue::get(Ty),
+                                         Ops[1], Zero, "insert");
+    Ops[1] = Builder.CreateBitCast(Ops[1], Ops[0]->getType(), "bitcast");
+    const char *name = 0;
+    Intrinsic::ID ID = Intrinsic::not_intrinsic;
+
+    switch (BuiltinID) {
+    default: assert(0 && "Unsupported shift intrinsic!");
+    case X86::BI__builtin_ia32_pslldi128:
+      name = "pslldi";
+      ID = Intrinsic::x86_sse2_psll_d;
+      break;
+    case X86::BI__builtin_ia32_psllqi128:
+      name = "psllqi";
+      ID = Intrinsic::x86_sse2_psll_q;
+      break;
+    case X86::BI__builtin_ia32_psllwi128:
+      name = "psllwi";
+      ID = Intrinsic::x86_sse2_psll_w;
+      break;
+    case X86::BI__builtin_ia32_psradi128:
+      name = "psradi";
+      ID = Intrinsic::x86_sse2_psra_d;
+      break;
+    case X86::BI__builtin_ia32_psrawi128:
+      name = "psrawi";
+      ID = Intrinsic::x86_sse2_psra_w;
+      break;
+    case X86::BI__builtin_ia32_psrldi128:
+      name = "psrldi";
+      ID = Intrinsic::x86_sse2_psrl_d;
+      break;
+    case X86::BI__builtin_ia32_psrlqi128:
+      name = "psrlqi";
+      ID = Intrinsic::x86_sse2_psrl_q;
+      break;
+    case X86::BI__builtin_ia32_psrlwi128:
+      name = "psrlwi";
+      ID = Intrinsic::x86_sse2_psrl_w;
+      break;
+    }
+    llvm::Function *F = CGM.getIntrinsic(ID);
+    return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), name);
+  }
+  case X86::BI__builtin_ia32_pslldi:
+  case X86::BI__builtin_ia32_psllqi:
+  case X86::BI__builtin_ia32_psllwi:
+  case X86::BI__builtin_ia32_psradi:
+  case X86::BI__builtin_ia32_psrawi:
+  case X86::BI__builtin_ia32_psrldi:
+  case X86::BI__builtin_ia32_psrlqi:
+  case X86::BI__builtin_ia32_psrlwi: {
+    Ops[1] = Builder.CreateZExt(Ops[1], llvm::Type::getInt64Ty(VMContext), "zext");
+    const llvm::Type *Ty = llvm::VectorType::get(llvm::Type::getInt64Ty(VMContext), 1);
+    Ops[1] = Builder.CreateBitCast(Ops[1], Ty, "bitcast");
+    const char *name = 0;
+    Intrinsic::ID ID = Intrinsic::not_intrinsic;
+
+    switch (BuiltinID) {
+    default: assert(0 && "Unsupported shift intrinsic!");
+    case X86::BI__builtin_ia32_pslldi:
+      name = "pslldi";
+      ID = Intrinsic::x86_mmx_psll_d;
+      break;
+    case X86::BI__builtin_ia32_psllqi:
+      name = "psllqi";
+      ID = Intrinsic::x86_mmx_psll_q;
+      break;
+    case X86::BI__builtin_ia32_psllwi:
+      name = "psllwi";
+      ID = Intrinsic::x86_mmx_psll_w;
+      break;
+    case X86::BI__builtin_ia32_psradi:
+      name = "psradi";
+      ID = Intrinsic::x86_mmx_psra_d;
+      break;
+    case X86::BI__builtin_ia32_psrawi:
+      name = "psrawi";
+      ID = Intrinsic::x86_mmx_psra_w;
+      break;
+    case X86::BI__builtin_ia32_psrldi:
+      name = "psrldi";
+      ID = Intrinsic::x86_mmx_psrl_d;
+      break;
+    case X86::BI__builtin_ia32_psrlqi:
+      name = "psrlqi";
+      ID = Intrinsic::x86_mmx_psrl_q;
+      break;
+    case X86::BI__builtin_ia32_psrlwi:
+      name = "psrlwi";
+      ID = Intrinsic::x86_mmx_psrl_w;
+      break;
+    }
+    llvm::Function *F = CGM.getIntrinsic(ID);
+    return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), name);
+  }
+  case X86::BI__builtin_ia32_cmpps: {
+    llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_sse_cmp_ps);
+    return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), "cmpps");
+  }
+  case X86::BI__builtin_ia32_cmpss: {
+    llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_sse_cmp_ss);
+    return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), "cmpss");
+  }
+  case X86::BI__builtin_ia32_ldmxcsr: {
+    const llvm::Type *PtrTy = llvm::Type::getInt8PtrTy(VMContext);
+    Value *One = llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 1);
+    Value *Tmp = Builder.CreateAlloca(llvm::Type::getInt32Ty(VMContext), One, "tmp");
+    Builder.CreateStore(Ops[0], Tmp);
+    return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_ldmxcsr),
+                              Builder.CreateBitCast(Tmp, PtrTy));
+  }
+  case X86::BI__builtin_ia32_stmxcsr: {
+    const llvm::Type *PtrTy = llvm::Type::getInt8PtrTy(VMContext);
+    Value *One = llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 1);
+    Value *Tmp = Builder.CreateAlloca(llvm::Type::getInt32Ty(VMContext), One, "tmp");
+    One = Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_stmxcsr),
+                             Builder.CreateBitCast(Tmp, PtrTy));
+    return Builder.CreateLoad(Tmp, "stmxcsr");
+  }
+  case X86::BI__builtin_ia32_cmppd: {
+    llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_sse2_cmp_pd);
+    return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), "cmppd");
+  }
+  case X86::BI__builtin_ia32_cmpsd: {
+    llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_sse2_cmp_sd);
+    return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), "cmpsd");
+  }
+  case X86::BI__builtin_ia32_storehps:
+  case X86::BI__builtin_ia32_storelps: {
+    const llvm::Type *EltTy = llvm::Type::getInt64Ty(VMContext);
+    llvm::Type *PtrTy = llvm::PointerType::getUnqual(EltTy);
+    llvm::Type *VecTy = llvm::VectorType::get(EltTy, 2);
+
+    // cast val v2i64
+    Ops[1] = Builder.CreateBitCast(Ops[1], VecTy, "cast");
+
+    // extract (0, 1)
+    unsigned Index = BuiltinID == X86::BI__builtin_ia32_storelps ? 0 : 1;
+    llvm::Value *Idx = llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), Index);
+    Ops[1] = Builder.CreateExtractElement(Ops[1], Idx, "extract");
+
+    // cast pointer to i64 & store
+    Ops[0] = Builder.CreateBitCast(Ops[0], PtrTy);
+    return Builder.CreateStore(Ops[1], Ops[0]);
+  }
+  case X86::BI__builtin_ia32_palignr: {
+    unsigned shiftVal = cast<llvm::ConstantInt>(Ops[2])->getZExtValue();
+    
+    // If palignr is shifting the pair of input vectors less than 9 bytes,
+    // emit a shuffle instruction.
+    if (shiftVal <= 8) {
+      const llvm::Type *IntTy = llvm::Type::getInt32Ty(VMContext);
+
+      llvm::SmallVector<llvm::Constant*, 8> Indices;
+      for (unsigned i = 0; i != 8; ++i)
+        Indices.push_back(llvm::ConstantInt::get(IntTy, shiftVal + i));
+      
+      Value* SV = llvm::ConstantVector::get(Indices.begin(), Indices.size());
+      return Builder.CreateShuffleVector(Ops[1], Ops[0], SV, "palignr");
+    }
+    
+    // If palignr is shifting the pair of input vectors more than 8 but less
+    // than 16 bytes, emit a logical right shift of the destination.
+    if (shiftVal < 16) {
+      // MMX has these as 1 x i64 vectors for some odd optimization reasons.
+      const llvm::Type *EltTy = llvm::Type::getInt64Ty(VMContext);
+      const llvm::Type *VecTy = llvm::VectorType::get(EltTy, 1);
+      
+      Ops[0] = Builder.CreateBitCast(Ops[0], VecTy, "cast");
+      Ops[1] = llvm::ConstantInt::get(VecTy, (shiftVal-8) * 8);
+      
+      // create i32 constant
+      llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_mmx_psrl_q);
+      return Builder.CreateCall(F, &Ops[0], &Ops[0] + 2, "palignr");
+    }
+    
+    // If palignr is shifting the pair of vectors more than 32 bytes, emit zero.
+    return llvm::Constant::getNullValue(ConvertType(E->getType()));
+  }
+  case X86::BI__builtin_ia32_palignr128: {
+    unsigned shiftVal = cast<llvm::ConstantInt>(Ops[2])->getZExtValue();
+    
+    // If palignr is shifting the pair of input vectors less than 17 bytes,
+    // emit a shuffle instruction.
+    if (shiftVal <= 16) {
+      const llvm::Type *IntTy = llvm::Type::getInt32Ty(VMContext);
+
+      llvm::SmallVector<llvm::Constant*, 16> Indices;
+      for (unsigned i = 0; i != 16; ++i)
+        Indices.push_back(llvm::ConstantInt::get(IntTy, shiftVal + i));
+      
+      Value* SV = llvm::ConstantVector::get(Indices.begin(), Indices.size());
+      return Builder.CreateShuffleVector(Ops[1], Ops[0], SV, "palignr");
+    }
+    
+    // If palignr is shifting the pair of input vectors more than 16 but less
+    // than 32 bytes, emit a logical right shift of the destination.
+    if (shiftVal < 32) {
+      const llvm::Type *EltTy = llvm::Type::getInt64Ty(VMContext);
+      const llvm::Type *VecTy = llvm::VectorType::get(EltTy, 2);
+      const llvm::Type *IntTy = llvm::Type::getInt32Ty(VMContext);
+      
+      Ops[0] = Builder.CreateBitCast(Ops[0], VecTy, "cast");
+      Ops[1] = llvm::ConstantInt::get(IntTy, (shiftVal-16) * 8);
+      
+      // create i32 constant
+      llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_sse2_psrl_dq);
+      return Builder.CreateCall(F, &Ops[0], &Ops[0] + 2, "palignr");
+    }
+    
+    // If palignr is shifting the pair of vectors more than 32 bytes, emit zero.
+    return llvm::Constant::getNullValue(ConvertType(E->getType()));
+  }
+  }
+}
+
+Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID,
+                                           const CallExpr *E) {
+  llvm::SmallVector<Value*, 4> Ops;
+
+  for (unsigned i = 0, e = E->getNumArgs(); i != e; i++)
+    Ops.push_back(EmitScalarExpr(E->getArg(i)));
+
+  Intrinsic::ID ID = Intrinsic::not_intrinsic;
+
+  switch (BuiltinID) {
+  default: return 0;
+
+  // vec_st
+  case PPC::BI__builtin_altivec_stvx:
+  case PPC::BI__builtin_altivec_stvxl:
+  case PPC::BI__builtin_altivec_stvebx:
+  case PPC::BI__builtin_altivec_stvehx:
+  case PPC::BI__builtin_altivec_stvewx:
+  {
+    Ops[2] = Builder.CreateBitCast(Ops[2], llvm::Type::getInt8PtrTy(VMContext));
+    Ops[1] = !isa<Constant>(Ops[1]) || !cast<Constant>(Ops[1])->isNullValue()
+           ? Builder.CreateGEP(Ops[2], Ops[1], "tmp") : Ops[2];
+    Ops.pop_back();
+
+    switch (BuiltinID) {
+    default: assert(0 && "Unsupported vavg intrinsic!");
+    case PPC::BI__builtin_altivec_stvx:
+      ID = Intrinsic::ppc_altivec_stvx;
+      break;
+    case PPC::BI__builtin_altivec_stvxl:
+      ID = Intrinsic::ppc_altivec_stvxl;
+      break;
+    case PPC::BI__builtin_altivec_stvebx:
+      ID = Intrinsic::ppc_altivec_stvebx;
+      break;
+    case PPC::BI__builtin_altivec_stvehx:
+      ID = Intrinsic::ppc_altivec_stvehx;
+      break;
+    case PPC::BI__builtin_altivec_stvewx:
+      ID = Intrinsic::ppc_altivec_stvewx;
+      break;
+    }
+    llvm::Function *F = CGM.getIntrinsic(ID);
+    return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), "");
+  }
+  }
+  return 0;
+}
diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp
new file mode 100644
index 0000000..74cf113
--- /dev/null
+++ b/lib/CodeGen/CGCXX.cpp
@@ -0,0 +1,329 @@
+//===--- CGDecl.cpp - Emit LLVM Code for declarations ---------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This contains code dealing with C++ code generation.
+//
+//===----------------------------------------------------------------------===//
+
+// We might split this into multiple files if it gets too unwieldy
+
+#include "CodeGenFunction.h"
+#include "CodeGenModule.h"
+#include "Mangle.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/RecordLayout.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/StmtCXX.h"
+#include "clang/CodeGen/CodeGenOptions.h"
+#include "llvm/ADT/StringExtras.h"
+using namespace clang;
+using namespace CodeGen;
+
+/// Determines whether the given function has a trivial body that does
+/// not require any specific codegen.
+static bool HasTrivialBody(const FunctionDecl *FD) {
+  Stmt *S = FD->getBody();
+  if (!S)
+    return true;
+  if (isa<CompoundStmt>(S) && cast<CompoundStmt>(S)->body_empty())
+    return true;
+  return false;
+}
+
+/// Try to emit a base destructor as an alias to its primary
+/// base-class destructor.
+bool CodeGenModule::TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D) {
+  if (!getCodeGenOpts().CXXCtorDtorAliases)
+    return true;
+
+  // If the destructor doesn't have a trivial body, we have to emit it
+  // separately.
+  if (!HasTrivialBody(D))
+    return true;
+
+  const CXXRecordDecl *Class = D->getParent();
+
+  // If we need to manipulate a VTT parameter, give up.
+  if (Class->getNumVBases()) {
+    // Extra Credit:  passing extra parameters is perfectly safe
+    // in many calling conventions, so only bail out if the ctor's
+    // calling convention is nonstandard.
+    return true;
+  }
+
+  // If any fields have a non-trivial destructor, we have to emit it
+  // separately.
+  for (CXXRecordDecl::field_iterator I = Class->field_begin(),
+         E = Class->field_end(); I != E; ++I)
+    if (const RecordType *RT = (*I)->getType()->getAs<RecordType>())
+      if (!cast<CXXRecordDecl>(RT->getDecl())->hasTrivialDestructor())
+        return true;
+
+  // Try to find a unique base class with a non-trivial destructor.
+  const CXXRecordDecl *UniqueBase = 0;
+  for (CXXRecordDecl::base_class_const_iterator I = Class->bases_begin(),
+         E = Class->bases_end(); I != E; ++I) {
+
+    // We're in the base destructor, so skip virtual bases.
+    if (I->isVirtual()) continue;
+
+    // Skip base classes with trivial destructors.
+    const CXXRecordDecl *Base
+      = cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+    if (Base->hasTrivialDestructor()) continue;
+
+    // If we've already found a base class with a non-trivial
+    // destructor, give up.
+    if (UniqueBase) return true;
+    UniqueBase = Base;
+  }
+
+  // If we didn't find any bases with a non-trivial destructor, then
+  // the base destructor is actually effectively trivial, which can
+  // happen if it was needlessly user-defined or if there are virtual
+  // bases with non-trivial destructors.
+  if (!UniqueBase)
+    return true;
+
+  /// If we don't have a definition for the destructor yet, don't
+  /// emit.  We can't emit aliases to declarations; that's just not
+  /// how aliases work.
+  const CXXDestructorDecl *BaseD = UniqueBase->getDestructor(getContext());
+  if (!BaseD->isImplicit() && !BaseD->getBody())
+    return true;
+
+  // If the base is at a non-zero offset, give up.
+  const ASTRecordLayout &ClassLayout = Context.getASTRecordLayout(Class);
+  if (ClassLayout.getBaseClassOffset(UniqueBase) != 0)
+    return true;
+
+  return TryEmitDefinitionAsAlias(GlobalDecl(D, Dtor_Base),
+                                  GlobalDecl(BaseD, Dtor_Base));
+}
+
+/// Try to emit a definition as a global alias for another definition.
+bool CodeGenModule::TryEmitDefinitionAsAlias(GlobalDecl AliasDecl,
+                                             GlobalDecl TargetDecl) {
+  if (!getCodeGenOpts().CXXCtorDtorAliases)
+    return true;
+
+  // The alias will use the linkage of the referrent.  If we can't
+  // support aliases with that linkage, fail.
+  llvm::GlobalValue::LinkageTypes Linkage
+    = getFunctionLinkage(cast<FunctionDecl>(AliasDecl.getDecl()));
+
+  switch (Linkage) {
+  // We can definitely emit aliases to definitions with external linkage.
+  case llvm::GlobalValue::ExternalLinkage:
+  case llvm::GlobalValue::ExternalWeakLinkage:
+    break;
+
+  // Same with local linkage.
+  case llvm::GlobalValue::InternalLinkage:
+  case llvm::GlobalValue::PrivateLinkage:
+  case llvm::GlobalValue::LinkerPrivateLinkage:
+    break;
+
+  // We should try to support linkonce linkages.
+  case llvm::GlobalValue::LinkOnceAnyLinkage:
+  case llvm::GlobalValue::LinkOnceODRLinkage:
+    return true;
+
+  // Other linkages will probably never be supported.
+  default:
+    return true;
+  }
+
+  llvm::GlobalValue::LinkageTypes TargetLinkage
+    = getFunctionLinkage(cast<FunctionDecl>(TargetDecl.getDecl()));
+
+  if (llvm::GlobalValue::isWeakForLinker(TargetLinkage))
+    return true;
+
+  // Derive the type for the alias.
+  const llvm::PointerType *AliasType
+    = getTypes().GetFunctionType(AliasDecl)->getPointerTo();
+
+  // Find the referrent.  Some aliases might require a bitcast, in
+  // which case the caller is responsible for ensuring the soundness
+  // of these semantics.
+  llvm::GlobalValue *Ref = cast<llvm::GlobalValue>(GetAddrOfGlobal(TargetDecl));
+  llvm::Constant *Aliasee = Ref;
+  if (Ref->getType() != AliasType)
+    Aliasee = llvm::ConstantExpr::getBitCast(Ref, AliasType);
+
+  // Create the alias with no name.
+  llvm::GlobalAlias *Alias = 
+    new llvm::GlobalAlias(AliasType, Linkage, "", Aliasee, &getModule());
+
+  // Switch any previous uses to the alias.
+  MangleBuffer MangledName;
+  getMangledName(MangledName, AliasDecl);
+  llvm::GlobalValue *Entry = GetGlobalValue(MangledName);
+  if (Entry) {
+    assert(Entry->isDeclaration() && "definition already exists for alias");
+    assert(Entry->getType() == AliasType &&
+           "declaration exists with different type");
+    Alias->takeName(Entry);
+    Entry->replaceAllUsesWith(Alias);
+    Entry->eraseFromParent();
+  } else {
+    Alias->setName(MangledName.getString());
+  }
+
+  // Finally, set up the alias with its proper name and attributes.
+  SetCommonAttributes(AliasDecl.getDecl(), Alias);
+
+  return false;
+}
+
+void CodeGenModule::EmitCXXConstructors(const CXXConstructorDecl *D) {
+  // The constructor used for constructing this as a complete class;
+  // constucts the virtual bases, then calls the base constructor.
+  EmitGlobal(GlobalDecl(D, Ctor_Complete));
+
+  // The constructor used for constructing this as a base class;
+  // ignores virtual bases.
+  EmitGlobal(GlobalDecl(D, Ctor_Base));
+}
+
+void CodeGenModule::EmitCXXConstructor(const CXXConstructorDecl *D,
+                                       CXXCtorType Type) {
+  // The complete constructor is equivalent to the base constructor
+  // for classes with no virtual bases.  Try to emit it as an alias.
+  if (Type == Ctor_Complete &&
+      !D->getParent()->getNumVBases() &&
+      !TryEmitDefinitionAsAlias(GlobalDecl(D, Ctor_Complete),
+                                GlobalDecl(D, Ctor_Base)))
+    return;
+
+  llvm::Function *Fn = cast<llvm::Function>(GetAddrOfCXXConstructor(D, Type));
+
+  CodeGenFunction(*this).GenerateCode(GlobalDecl(D, Type), Fn);
+
+  SetFunctionDefinitionAttributes(D, Fn);
+  SetLLVMFunctionAttributesForDefinition(D, Fn);
+}
+
+llvm::GlobalValue *
+CodeGenModule::GetAddrOfCXXConstructor(const CXXConstructorDecl *D,
+                                       CXXCtorType Type) {
+  MangleBuffer Name;
+  getMangledCXXCtorName(Name, D, Type);
+  if (llvm::GlobalValue *V = GetGlobalValue(Name))
+    return V;
+
+  const FunctionProtoType *FPT = D->getType()->getAs<FunctionProtoType>();
+  const llvm::FunctionType *FTy =
+    getTypes().GetFunctionType(getTypes().getFunctionInfo(D, Type), 
+                               FPT->isVariadic());
+  return cast<llvm::Function>(
+                      GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(D, Type)));
+}
+
+void CodeGenModule::getMangledCXXCtorName(MangleBuffer &Name,
+                                          const CXXConstructorDecl *D,
+                                          CXXCtorType Type) {
+  getMangleContext().mangleCXXCtor(D, Type, Name.getBuffer());
+}
+
+void CodeGenModule::EmitCXXDestructors(const CXXDestructorDecl *D) {
+  // The destructor in a virtual table is always a 'deleting'
+  // destructor, which calls the complete destructor and then uses the
+  // appropriate operator delete.
+  if (D->isVirtual())
+    EmitGlobal(GlobalDecl(D, Dtor_Deleting));
+
+  // The destructor used for destructing this as a most-derived class;
+  // call the base destructor and then destructs any virtual bases.
+  EmitGlobal(GlobalDecl(D, Dtor_Complete));
+
+  // The destructor used for destructing this as a base class; ignores
+  // virtual bases.
+  EmitGlobal(GlobalDecl(D, Dtor_Base));
+}
+
+void CodeGenModule::EmitCXXDestructor(const CXXDestructorDecl *D,
+                                      CXXDtorType Type) {
+  // The complete destructor is equivalent to the base destructor for
+  // classes with no virtual bases, so try to emit it as an alias.
+  if (Type == Dtor_Complete &&
+      !D->getParent()->getNumVBases() &&
+      !TryEmitDefinitionAsAlias(GlobalDecl(D, Dtor_Complete),
+                                GlobalDecl(D, Dtor_Base)))
+    return;
+
+  // The base destructor is equivalent to the base destructor of its
+  // base class if there is exactly one non-virtual base class with a
+  // non-trivial destructor, there are no fields with a non-trivial
+  // destructor, and the body of the destructor is trivial.
+  if (Type == Dtor_Base && !TryEmitBaseDestructorAsAlias(D))
+    return;
+
+  llvm::Function *Fn = cast<llvm::Function>(GetAddrOfCXXDestructor(D, Type));
+
+  CodeGenFunction(*this).GenerateCode(GlobalDecl(D, Type), Fn);
+
+  SetFunctionDefinitionAttributes(D, Fn);
+  SetLLVMFunctionAttributesForDefinition(D, Fn);
+}
+
+llvm::GlobalValue *
+CodeGenModule::GetAddrOfCXXDestructor(const CXXDestructorDecl *D,
+                                      CXXDtorType Type) {
+  MangleBuffer Name;
+  getMangledCXXDtorName(Name, D, Type);
+  if (llvm::GlobalValue *V = GetGlobalValue(Name))
+    return V;
+
+  const llvm::FunctionType *FTy =
+    getTypes().GetFunctionType(getTypes().getFunctionInfo(D, Type), false);
+
+  return cast<llvm::Function>(
+                      GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(D, Type)));
+}
+
+void CodeGenModule::getMangledCXXDtorName(MangleBuffer &Name,
+                                          const CXXDestructorDecl *D,
+                                          CXXDtorType Type) {
+  getMangleContext().mangleCXXDtor(D, Type, Name.getBuffer());
+}
+
+static llvm::Value *BuildVirtualCall(CodeGenFunction &CGF, uint64_t VTableIndex, 
+                                     llvm::Value *This, const llvm::Type *Ty) {
+  Ty = Ty->getPointerTo()->getPointerTo()->getPointerTo();
+  
+  llvm::Value *VTable = CGF.Builder.CreateBitCast(This, Ty);
+  VTable = CGF.Builder.CreateLoad(VTable);
+  
+  llvm::Value *VFuncPtr = 
+    CGF.Builder.CreateConstInBoundsGEP1_64(VTable, VTableIndex, "vfn");
+  return CGF.Builder.CreateLoad(VFuncPtr);
+}
+
+llvm::Value *
+CodeGenFunction::BuildVirtualCall(const CXXMethodDecl *MD, llvm::Value *This,
+                                  const llvm::Type *Ty) {
+  MD = MD->getCanonicalDecl();
+  uint64_t VTableIndex = CGM.getVTables().getMethodVTableIndex(MD);
+  
+  return ::BuildVirtualCall(*this, VTableIndex, This, Ty);
+}
+
+llvm::Value *
+CodeGenFunction::BuildVirtualCall(const CXXDestructorDecl *DD, CXXDtorType Type, 
+                                  llvm::Value *&This, const llvm::Type *Ty) {
+  DD = cast<CXXDestructorDecl>(DD->getCanonicalDecl());
+  uint64_t VTableIndex = 
+    CGM.getVTables().getMethodVTableIndex(GlobalDecl(DD, Type));
+
+  return ::BuildVirtualCall(*this, VTableIndex, This, Ty);
+}
diff --git a/lib/CodeGen/CGCXX.h b/lib/CodeGen/CGCXX.h
new file mode 100644
index 0000000..1e6adb0
--- /dev/null
+++ b/lib/CodeGen/CGCXX.h
@@ -0,0 +1,36 @@
+//===----- CGCXX.h - C++ related code CodeGen declarations ------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// These classes wrap the information about a call or function
+// definition used to handle ABI compliancy.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_CODEGEN_CGCXX_H
+#define CLANG_CODEGEN_CGCXX_H
+
+namespace clang {
+
+/// CXXCtorType - C++ constructor types
+enum CXXCtorType {
+    Ctor_Complete,          // Complete object ctor
+    Ctor_Base,              // Base object ctor
+    Ctor_CompleteAllocating // Complete object allocating ctor
+};
+
+/// CXXDtorType - C++ destructor types
+enum CXXDtorType {
+    Dtor_Deleting, // Deleting dtor
+    Dtor_Complete, // Complete object dtor
+    Dtor_Base      // Base object dtor
+};
+
+} // end namespace clang
+
+#endif // CLANG_CODEGEN_CGCXX_H
diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp
new file mode 100644
index 0000000..8b5c3a0
--- /dev/null
+++ b/lib/CodeGen/CGCall.cpp
@@ -0,0 +1,1084 @@
+//===----- CGCall.h - Encapsulate calling convention details ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// These classes wrap the information about a call or function
+// definition used to handle ABI compliancy.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CGCall.h"
+#include "CodeGenFunction.h"
+#include "CodeGenModule.h"
+#include "clang/Basic/TargetInfo.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/CodeGen/CodeGenOptions.h"
+#include "llvm/Attributes.h"
+#include "llvm/Support/CallSite.h"
+#include "llvm/Target/TargetData.h"
+
+#include "ABIInfo.h"
+
+using namespace clang;
+using namespace CodeGen;
+
+/***/
+
+// FIXME: Use iterator and sidestep silly type array creation.
+
+static unsigned ClangCallConvToLLVMCallConv(CallingConv CC) {
+  switch (CC) {
+  default: return llvm::CallingConv::C;
+  case CC_X86StdCall: return llvm::CallingConv::X86_StdCall;
+  case CC_X86FastCall: return llvm::CallingConv::X86_FastCall;
+  }
+}
+
+/// Derives the 'this' type for codegen purposes, i.e. ignoring method
+/// qualification.
+/// FIXME: address space qualification?
+static CanQualType GetThisType(ASTContext &Context, const CXXRecordDecl *RD) {
+  QualType RecTy = Context.getTagDeclType(RD)->getCanonicalTypeInternal();
+  return Context.getPointerType(CanQualType::CreateUnsafe(RecTy));
+}
+
+/// Returns the canonical formal type of the given C++ method.
+static CanQual<FunctionProtoType> GetFormalType(const CXXMethodDecl *MD) {
+  return MD->getType()->getCanonicalTypeUnqualified()
+           .getAs<FunctionProtoType>();
+}
+
+/// Returns the "extra-canonicalized" return type, which discards
+/// qualifiers on the return type.  Codegen doesn't care about them,
+/// and it makes ABI code a little easier to be able to assume that
+/// all parameter and return types are top-level unqualified.
+static CanQualType GetReturnType(QualType RetTy) {
+  return RetTy->getCanonicalTypeUnqualified().getUnqualifiedType();
+}
+
+const CGFunctionInfo &
+CodeGenTypes::getFunctionInfo(CanQual<FunctionNoProtoType> FTNP) {
+  return getFunctionInfo(FTNP->getResultType().getUnqualifiedType(),
+                         llvm::SmallVector<CanQualType, 16>(),
+                         FTNP->getExtInfo());
+}
+
+/// \param Args - contains any initial parameters besides those
+///   in the formal type
+static const CGFunctionInfo &getFunctionInfo(CodeGenTypes &CGT,
+                                  llvm::SmallVectorImpl<CanQualType> &ArgTys,
+                                             CanQual<FunctionProtoType> FTP) {
+  // FIXME: Kill copy.
+  for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i)
+    ArgTys.push_back(FTP->getArgType(i));
+  CanQualType ResTy = FTP->getResultType().getUnqualifiedType();
+  return CGT.getFunctionInfo(ResTy, ArgTys,
+                             FTP->getExtInfo());
+}
+
+const CGFunctionInfo &
+CodeGenTypes::getFunctionInfo(CanQual<FunctionProtoType> FTP) {
+  llvm::SmallVector<CanQualType, 16> ArgTys;
+  return ::getFunctionInfo(*this, ArgTys, FTP);
+}
+
+static CallingConv getCallingConventionForDecl(const Decl *D) {
+  // Set the appropriate calling convention for the Function.
+  if (D->hasAttr<StdCallAttr>())
+    return CC_X86StdCall;
+
+  if (D->hasAttr<FastCallAttr>())
+    return CC_X86FastCall;
+
+  return CC_C;
+}
+
+const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const CXXRecordDecl *RD,
+                                                 const FunctionProtoType *FTP) {
+  llvm::SmallVector<CanQualType, 16> ArgTys;
+
+  // Add the 'this' pointer.
+  ArgTys.push_back(GetThisType(Context, RD));
+
+  return ::getFunctionInfo(*this, ArgTys,
+              FTP->getCanonicalTypeUnqualified().getAs<FunctionProtoType>());
+}
+
+const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const CXXMethodDecl *MD) {
+  llvm::SmallVector<CanQualType, 16> ArgTys;
+
+  // Add the 'this' pointer unless this is a static method.
+  if (MD->isInstance())
+    ArgTys.push_back(GetThisType(Context, MD->getParent()));
+
+  return ::getFunctionInfo(*this, ArgTys, GetFormalType(MD));
+}
+
+const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const CXXConstructorDecl *D, 
+                                                    CXXCtorType Type) {
+  llvm::SmallVector<CanQualType, 16> ArgTys;
+
+  // Add the 'this' pointer.
+  ArgTys.push_back(GetThisType(Context, D->getParent()));
+
+  // Check if we need to add a VTT parameter (which has type void **).
+  if (Type == Ctor_Base && D->getParent()->getNumVBases() != 0)
+    ArgTys.push_back(Context.getPointerType(Context.VoidPtrTy));
+
+  return ::getFunctionInfo(*this, ArgTys, GetFormalType(D));
+}
+
+const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const CXXDestructorDecl *D,
+                                                    CXXDtorType Type) {
+  llvm::SmallVector<CanQualType, 16> ArgTys;
+  
+  // Add the 'this' pointer.
+  ArgTys.push_back(GetThisType(Context, D->getParent()));
+  
+  // Check if we need to add a VTT parameter (which has type void **).
+  if (Type == Dtor_Base && D->getParent()->getNumVBases() != 0)
+    ArgTys.push_back(Context.getPointerType(Context.VoidPtrTy));
+
+  return ::getFunctionInfo(*this, ArgTys, GetFormalType(D));
+}
+
+const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const FunctionDecl *FD) {
+  if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD))
+    if (MD->isInstance())
+      return getFunctionInfo(MD);
+
+  CanQualType FTy = FD->getType()->getCanonicalTypeUnqualified();
+  assert(isa<FunctionType>(FTy));
+  if (isa<FunctionNoProtoType>(FTy))
+    return getFunctionInfo(FTy.getAs<FunctionNoProtoType>());  
+  assert(isa<FunctionProtoType>(FTy));
+  return getFunctionInfo(FTy.getAs<FunctionProtoType>());
+}
+
+const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const ObjCMethodDecl *MD) {
+  llvm::SmallVector<CanQualType, 16> ArgTys;
+  ArgTys.push_back(Context.getCanonicalParamType(MD->getSelfDecl()->getType()));
+  ArgTys.push_back(Context.getCanonicalParamType(Context.getObjCSelType()));
+  // FIXME: Kill copy?
+  for (ObjCMethodDecl::param_iterator i = MD->param_begin(),
+         e = MD->param_end(); i != e; ++i) {
+    ArgTys.push_back(Context.getCanonicalParamType((*i)->getType()));
+  }
+  return getFunctionInfo(GetReturnType(MD->getResultType()),
+                         ArgTys,
+                         FunctionType::ExtInfo(
+                             /*NoReturn*/ false,
+                             /*RegParm*/ 0,
+                             getCallingConventionForDecl(MD)));
+}
+
+const CGFunctionInfo &CodeGenTypes::getFunctionInfo(GlobalDecl GD) {
+  // FIXME: Do we need to handle ObjCMethodDecl?
+  const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl());
+                                              
+  if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(FD))
+    return getFunctionInfo(CD, GD.getCtorType());
+
+  if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(FD))
+    return getFunctionInfo(DD, GD.getDtorType());
+  
+  return getFunctionInfo(FD);
+}
+
+const CGFunctionInfo &CodeGenTypes::getFunctionInfo(QualType ResTy,
+                                                    const CallArgList &Args,
+                                            const FunctionType::ExtInfo &Info) {
+  // FIXME: Kill copy.
+  llvm::SmallVector<CanQualType, 16> ArgTys;
+  for (CallArgList::const_iterator i = Args.begin(), e = Args.end();
+       i != e; ++i)
+    ArgTys.push_back(Context.getCanonicalParamType(i->second));
+  return getFunctionInfo(GetReturnType(ResTy), ArgTys, Info);
+}
+
+const CGFunctionInfo &CodeGenTypes::getFunctionInfo(QualType ResTy,
+                                                    const FunctionArgList &Args,
+                                            const FunctionType::ExtInfo &Info) {
+  // FIXME: Kill copy.
+  llvm::SmallVector<CanQualType, 16> ArgTys;
+  for (FunctionArgList::const_iterator i = Args.begin(), e = Args.end();
+       i != e; ++i)
+    ArgTys.push_back(Context.getCanonicalParamType(i->second));
+  return getFunctionInfo(GetReturnType(ResTy), ArgTys, Info);
+}
+
+const CGFunctionInfo &CodeGenTypes::getFunctionInfo(CanQualType ResTy,
+                           const llvm::SmallVectorImpl<CanQualType> &ArgTys,
+                                            const FunctionType::ExtInfo &Info) {
+#ifndef NDEBUG
+  for (llvm::SmallVectorImpl<CanQualType>::const_iterator
+         I = ArgTys.begin(), E = ArgTys.end(); I != E; ++I)
+    assert(I->isCanonicalAsParam());
+#endif
+
+  unsigned CC = ClangCallConvToLLVMCallConv(Info.getCC());
+
+  // Lookup or create unique function info.
+  llvm::FoldingSetNodeID ID;
+  CGFunctionInfo::Profile(ID, Info, ResTy,
+                          ArgTys.begin(), ArgTys.end());
+
+  void *InsertPos = 0;
+  CGFunctionInfo *FI = FunctionInfos.FindNodeOrInsertPos(ID, InsertPos);
+  if (FI)
+    return *FI;
+
+  // Construct the function info.
+  FI = new CGFunctionInfo(CC, Info.getNoReturn(), Info.getRegParm(), ResTy, ArgTys);
+  FunctionInfos.InsertNode(FI, InsertPos);
+
+  // Compute ABI information.
+  getABIInfo().computeInfo(*FI, getContext(), TheModule.getContext());
+
+  return *FI;
+}
+
+CGFunctionInfo::CGFunctionInfo(unsigned _CallingConvention,
+                               bool _NoReturn,
+                               unsigned _RegParm,
+                               CanQualType ResTy,
+                               const llvm::SmallVectorImpl<CanQualType> &ArgTys)
+  : CallingConvention(_CallingConvention),
+    EffectiveCallingConvention(_CallingConvention),
+    NoReturn(_NoReturn), RegParm(_RegParm)
+{
+  NumArgs = ArgTys.size();
+  Args = new ArgInfo[1 + NumArgs];
+  Args[0].type = ResTy;
+  for (unsigned i = 0; i < NumArgs; ++i)
+    Args[1 + i].type = ArgTys[i];
+}
+
+/***/
+
+void CodeGenTypes::GetExpandedTypes(QualType Ty,
+                                    std::vector<const llvm::Type*> &ArgTys) {
+  const RecordType *RT = Ty->getAsStructureType();
+  assert(RT && "Can only expand structure types.");
+  const RecordDecl *RD = RT->getDecl();
+  assert(!RD->hasFlexibleArrayMember() &&
+         "Cannot expand structure with flexible array.");
+
+  for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
+         i != e; ++i) {
+    const FieldDecl *FD = *i;
+    assert(!FD->isBitField() &&
+           "Cannot expand structure with bit-field members.");
+
+    QualType FT = FD->getType();
+    if (CodeGenFunction::hasAggregateLLVMType(FT)) {
+      GetExpandedTypes(FT, ArgTys);
+    } else {
+      ArgTys.push_back(ConvertType(FT));
+    }
+  }
+}
+
+llvm::Function::arg_iterator
+CodeGenFunction::ExpandTypeFromArgs(QualType Ty, LValue LV,
+                                    llvm::Function::arg_iterator AI) {
+  const RecordType *RT = Ty->getAsStructureType();
+  assert(RT && "Can only expand structure types.");
+
+  RecordDecl *RD = RT->getDecl();
+  assert(LV.isSimple() &&
+         "Unexpected non-simple lvalue during struct expansion.");
+  llvm::Value *Addr = LV.getAddress();
+  for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
+         i != e; ++i) {
+    FieldDecl *FD = *i;
+    QualType FT = FD->getType();
+
+    // FIXME: What are the right qualifiers here?
+    LValue LV = EmitLValueForField(Addr, FD, 0);
+    if (CodeGenFunction::hasAggregateLLVMType(FT)) {
+      AI = ExpandTypeFromArgs(FT, LV, AI);
+    } else {
+      EmitStoreThroughLValue(RValue::get(AI), LV, FT);
+      ++AI;
+    }
+  }
+
+  return AI;
+}
+
+void
+CodeGenFunction::ExpandTypeToArgs(QualType Ty, RValue RV,
+                                  llvm::SmallVector<llvm::Value*, 16> &Args) {
+  const RecordType *RT = Ty->getAsStructureType();
+  assert(RT && "Can only expand structure types.");
+
+  RecordDecl *RD = RT->getDecl();
+  assert(RV.isAggregate() && "Unexpected rvalue during struct expansion");
+  llvm::Value *Addr = RV.getAggregateAddr();
+  for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
+         i != e; ++i) {
+    FieldDecl *FD = *i;
+    QualType FT = FD->getType();
+
+    // FIXME: What are the right qualifiers here?
+    LValue LV = EmitLValueForField(Addr, FD, 0);
+    if (CodeGenFunction::hasAggregateLLVMType(FT)) {
+      ExpandTypeToArgs(FT, RValue::getAggregate(LV.getAddress()), Args);
+    } else {
+      RValue RV = EmitLoadOfLValue(LV, FT);
+      assert(RV.isScalar() &&
+             "Unexpected non-scalar rvalue during struct expansion.");
+      Args.push_back(RV.getScalarVal());
+    }
+  }
+}
+
+/// CreateCoercedLoad - Create a load from \arg SrcPtr interpreted as
+/// a pointer to an object of type \arg Ty.
+///
+/// This safely handles the case when the src type is smaller than the
+/// destination type; in this situation the values of bits which not
+/// present in the src are undefined.
+static llvm::Value *CreateCoercedLoad(llvm::Value *SrcPtr,
+                                      const llvm::Type *Ty,
+                                      CodeGenFunction &CGF) {
+  const llvm::Type *SrcTy =
+    cast<llvm::PointerType>(SrcPtr->getType())->getElementType();
+  uint64_t SrcSize = CGF.CGM.getTargetData().getTypeAllocSize(SrcTy);
+  uint64_t DstSize = CGF.CGM.getTargetData().getTypeAllocSize(Ty);
+
+  // If load is legal, just bitcast the src pointer.
+  if (SrcSize >= DstSize) {
+    // Generally SrcSize is never greater than DstSize, since this means we are
+    // losing bits. However, this can happen in cases where the structure has
+    // additional padding, for example due to a user specified alignment.
+    //
+    // FIXME: Assert that we aren't truncating non-padding bits when have access
+    // to that information.
+    llvm::Value *Casted =
+      CGF.Builder.CreateBitCast(SrcPtr, llvm::PointerType::getUnqual(Ty));
+    llvm::LoadInst *Load = CGF.Builder.CreateLoad(Casted);
+    // FIXME: Use better alignment / avoid requiring aligned load.
+    Load->setAlignment(1);
+    return Load;
+  } else {
+    // Otherwise do coercion through memory. This is stupid, but
+    // simple.
+    llvm::Value *Tmp = CGF.CreateTempAlloca(Ty);
+    llvm::Value *Casted =
+      CGF.Builder.CreateBitCast(Tmp, llvm::PointerType::getUnqual(SrcTy));
+    llvm::StoreInst *Store =
+      CGF.Builder.CreateStore(CGF.Builder.CreateLoad(SrcPtr), Casted);
+    // FIXME: Use better alignment / avoid requiring aligned store.
+    Store->setAlignment(1);
+    return CGF.Builder.CreateLoad(Tmp);
+  }
+}
+
+/// CreateCoercedStore - Create a store to \arg DstPtr from \arg Src,
+/// where the source and destination may have different types.
+///
+/// This safely handles the case when the src type is larger than the
+/// destination type; the upper bits of the src will be lost.
+static void CreateCoercedStore(llvm::Value *Src,
+                               llvm::Value *DstPtr,
+                               bool DstIsVolatile,
+                               CodeGenFunction &CGF) {
+  const llvm::Type *SrcTy = Src->getType();
+  const llvm::Type *DstTy =
+    cast<llvm::PointerType>(DstPtr->getType())->getElementType();
+
+  uint64_t SrcSize = CGF.CGM.getTargetData().getTypeAllocSize(SrcTy);
+  uint64_t DstSize = CGF.CGM.getTargetData().getTypeAllocSize(DstTy);
+
+  // If store is legal, just bitcast the src pointer.
+  if (SrcSize <= DstSize) {
+    llvm::Value *Casted =
+      CGF.Builder.CreateBitCast(DstPtr, llvm::PointerType::getUnqual(SrcTy));
+    // FIXME: Use better alignment / avoid requiring aligned store.
+    CGF.Builder.CreateStore(Src, Casted, DstIsVolatile)->setAlignment(1);
+  } else {
+    // Otherwise do coercion through memory. This is stupid, but
+    // simple.
+
+    // Generally SrcSize is never greater than DstSize, since this means we are
+    // losing bits. However, this can happen in cases where the structure has
+    // additional padding, for example due to a user specified alignment.
+    //
+    // FIXME: Assert that we aren't truncating non-padding bits when have access
+    // to that information.
+    llvm::Value *Tmp = CGF.CreateTempAlloca(SrcTy);
+    CGF.Builder.CreateStore(Src, Tmp);
+    llvm::Value *Casted =
+      CGF.Builder.CreateBitCast(Tmp, llvm::PointerType::getUnqual(DstTy));
+    llvm::LoadInst *Load = CGF.Builder.CreateLoad(Casted);
+    // FIXME: Use better alignment / avoid requiring aligned load.
+    Load->setAlignment(1);
+    CGF.Builder.CreateStore(Load, DstPtr, DstIsVolatile);
+  }
+}
+
+/***/
+
+bool CodeGenModule::ReturnTypeUsesSret(const CGFunctionInfo &FI) {
+  return FI.getReturnInfo().isIndirect();
+}
+
+const llvm::FunctionType *CodeGenTypes::GetFunctionType(GlobalDecl GD) {
+  const CGFunctionInfo &FI = getFunctionInfo(GD);
+  
+  // For definition purposes, don't consider a K&R function variadic.
+  bool Variadic = false;
+  if (const FunctionProtoType *FPT =
+        cast<FunctionDecl>(GD.getDecl())->getType()->getAs<FunctionProtoType>())
+    Variadic = FPT->isVariadic();
+
+  return GetFunctionType(FI, Variadic);
+}
+
+const llvm::FunctionType *
+CodeGenTypes::GetFunctionType(const CGFunctionInfo &FI, bool IsVariadic) {
+  std::vector<const llvm::Type*> ArgTys;
+
+  const llvm::Type *ResultType = 0;
+
+  QualType RetTy = FI.getReturnType();
+  const ABIArgInfo &RetAI = FI.getReturnInfo();
+  switch (RetAI.getKind()) {
+  case ABIArgInfo::Expand:
+    assert(0 && "Invalid ABI kind for return argument");
+
+  case ABIArgInfo::Extend:
+  case ABIArgInfo::Direct:
+    ResultType = ConvertType(RetTy);
+    break;
+
+  case ABIArgInfo::Indirect: {
+    assert(!RetAI.getIndirectAlign() && "Align unused on indirect return.");
+    ResultType = llvm::Type::getVoidTy(getLLVMContext());
+    const llvm::Type *STy = ConvertType(RetTy);
+    ArgTys.push_back(llvm::PointerType::get(STy, RetTy.getAddressSpace()));
+    break;
+  }
+
+  case ABIArgInfo::Ignore:
+    ResultType = llvm::Type::getVoidTy(getLLVMContext());
+    break;
+
+  case ABIArgInfo::Coerce:
+    ResultType = RetAI.getCoerceToType();
+    break;
+  }
+
+  for (CGFunctionInfo::const_arg_iterator it = FI.arg_begin(),
+         ie = FI.arg_end(); it != ie; ++it) {
+    const ABIArgInfo &AI = it->info;
+
+    switch (AI.getKind()) {
+    case ABIArgInfo::Ignore:
+      break;
+
+    case ABIArgInfo::Coerce:
+      ArgTys.push_back(AI.getCoerceToType());
+      break;
+
+    case ABIArgInfo::Indirect: {
+      // indirect arguments are always on the stack, which is addr space #0.
+      const llvm::Type *LTy = ConvertTypeForMem(it->type);
+      ArgTys.push_back(llvm::PointerType::getUnqual(LTy));
+      break;
+    }
+
+    case ABIArgInfo::Extend:
+    case ABIArgInfo::Direct:
+      ArgTys.push_back(ConvertType(it->type));
+      break;
+
+    case ABIArgInfo::Expand:
+      GetExpandedTypes(it->type, ArgTys);
+      break;
+    }
+  }
+
+  return llvm::FunctionType::get(ResultType, ArgTys, IsVariadic);
+}
+
+static bool HasIncompleteReturnTypeOrArgumentTypes(const FunctionProtoType *T) {
+  if (const TagType *TT = T->getResultType()->getAs<TagType>()) {
+    if (!TT->getDecl()->isDefinition())
+      return true;
+  }
+
+  for (unsigned i = 0, e = T->getNumArgs(); i != e; ++i) {
+    if (const TagType *TT = T->getArgType(i)->getAs<TagType>()) {
+      if (!TT->getDecl()->isDefinition())
+        return true;
+    }
+  }
+
+  return false;
+}
+
+const llvm::Type *
+CodeGenTypes::GetFunctionTypeForVTable(const CXXMethodDecl *MD) {
+  const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>();
+  
+  if (!HasIncompleteReturnTypeOrArgumentTypes(FPT))
+    return GetFunctionType(getFunctionInfo(MD), FPT->isVariadic());
+
+  return llvm::OpaqueType::get(getLLVMContext());
+}
+
+void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI,
+                                           const Decl *TargetDecl,
+                                           AttributeListType &PAL, 
+                                           unsigned &CallingConv) {
+  unsigned FuncAttrs = 0;
+  unsigned RetAttrs = 0;
+
+  CallingConv = FI.getEffectiveCallingConvention();
+
+  if (FI.isNoReturn())
+    FuncAttrs |= llvm::Attribute::NoReturn;
+
+  // FIXME: handle sseregparm someday...
+  if (TargetDecl) {
+    if (TargetDecl->hasAttr<NoThrowAttr>())
+      FuncAttrs |= llvm::Attribute::NoUnwind;
+    if (TargetDecl->hasAttr<NoReturnAttr>())
+      FuncAttrs |= llvm::Attribute::NoReturn;
+    if (TargetDecl->hasAttr<ConstAttr>())
+      FuncAttrs |= llvm::Attribute::ReadNone;
+    else if (TargetDecl->hasAttr<PureAttr>())
+      FuncAttrs |= llvm::Attribute::ReadOnly;
+    if (TargetDecl->hasAttr<MallocAttr>())
+      RetAttrs |= llvm::Attribute::NoAlias;
+  }
+
+  if (CodeGenOpts.OptimizeSize)
+    FuncAttrs |= llvm::Attribute::OptimizeForSize;
+  if (CodeGenOpts.DisableRedZone)
+    FuncAttrs |= llvm::Attribute::NoRedZone;
+  if (CodeGenOpts.NoImplicitFloat)
+    FuncAttrs |= llvm::Attribute::NoImplicitFloat;
+
+  QualType RetTy = FI.getReturnType();
+  unsigned Index = 1;
+  const ABIArgInfo &RetAI = FI.getReturnInfo();
+  switch (RetAI.getKind()) {
+  case ABIArgInfo::Extend:
+   if (RetTy->isSignedIntegerType()) {
+     RetAttrs |= llvm::Attribute::SExt;
+   } else if (RetTy->isUnsignedIntegerType()) {
+     RetAttrs |= llvm::Attribute::ZExt;
+   }
+   // FALLTHROUGH
+  case ABIArgInfo::Direct:
+    break;
+
+  case ABIArgInfo::Indirect:
+    PAL.push_back(llvm::AttributeWithIndex::get(Index,
+                                                llvm::Attribute::StructRet));
+    ++Index;
+    // sret disables readnone and readonly
+    FuncAttrs &= ~(llvm::Attribute::ReadOnly |
+                   llvm::Attribute::ReadNone);
+    break;
+
+  case ABIArgInfo::Ignore:
+  case ABIArgInfo::Coerce:
+    break;
+
+  case ABIArgInfo::Expand:
+    assert(0 && "Invalid ABI kind for return argument");
+  }
+
+  if (RetAttrs)
+    PAL.push_back(llvm::AttributeWithIndex::get(0, RetAttrs));
+
+  // FIXME: we need to honour command line settings also...
+  // FIXME: RegParm should be reduced in case of nested functions and/or global
+  // register variable.
+  signed RegParm = FI.getRegParm();
+
+  unsigned PointerWidth = getContext().Target.getPointerWidth(0);
+  for (CGFunctionInfo::const_arg_iterator it = FI.arg_begin(),
+         ie = FI.arg_end(); it != ie; ++it) {
+    QualType ParamType = it->type;
+    const ABIArgInfo &AI = it->info;
+    unsigned Attributes = 0;
+
+    // 'restrict' -> 'noalias' is done in EmitFunctionProlog when we
+    // have the corresponding parameter variable.  It doesn't make
+    // sense to do it here because parameters are so fucked up.
+
+    switch (AI.getKind()) {
+    case ABIArgInfo::Coerce:
+      break;
+
+    case ABIArgInfo::Indirect:
+      if (AI.getIndirectByVal())
+        Attributes |= llvm::Attribute::ByVal;
+
+      Attributes |=
+        llvm::Attribute::constructAlignmentFromInt(AI.getIndirectAlign());
+      // byval disables readnone and readonly.
+      FuncAttrs &= ~(llvm::Attribute::ReadOnly |
+                     llvm::Attribute::ReadNone);
+      break;
+
+    case ABIArgInfo::Extend:
+     if (ParamType->isSignedIntegerType()) {
+       Attributes |= llvm::Attribute::SExt;
+     } else if (ParamType->isUnsignedIntegerType()) {
+       Attributes |= llvm::Attribute::ZExt;
+     }
+     // FALLS THROUGH
+    case ABIArgInfo::Direct:
+      if (RegParm > 0 &&
+          (ParamType->isIntegerType() || ParamType->isPointerType())) {
+        RegParm -=
+          (Context.getTypeSize(ParamType) + PointerWidth - 1) / PointerWidth;
+        if (RegParm >= 0)
+          Attributes |= llvm::Attribute::InReg;
+      }
+      // FIXME: handle sseregparm someday...
+      break;
+
+    case ABIArgInfo::Ignore:
+      // Skip increment, no matching LLVM parameter.
+      continue;
+
+    case ABIArgInfo::Expand: {
+      std::vector<const llvm::Type*> Tys;
+      // FIXME: This is rather inefficient. Do we ever actually need to do
+      // anything here? The result should be just reconstructed on the other
+      // side, so extension should be a non-issue.
+      getTypes().GetExpandedTypes(ParamType, Tys);
+      Index += Tys.size();
+      continue;
+    }
+    }
+
+    if (Attributes)
+      PAL.push_back(llvm::AttributeWithIndex::get(Index, Attributes));
+    ++Index;
+  }
+  if (FuncAttrs)
+    PAL.push_back(llvm::AttributeWithIndex::get(~0, FuncAttrs));
+}
+
+void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,
+                                         llvm::Function *Fn,
+                                         const FunctionArgList &Args) {
+  // If this is an implicit-return-zero function, go ahead and
+  // initialize the return value.  TODO: it might be nice to have
+  // a more general mechanism for this that didn't require synthesized
+  // return statements.
+  if (const FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(CurFuncDecl)) {
+    if (FD->hasImplicitReturnZero()) {
+      QualType RetTy = FD->getResultType().getUnqualifiedType();
+      const llvm::Type* LLVMTy = CGM.getTypes().ConvertType(RetTy);
+      llvm::Constant* Zero = llvm::Constant::getNullValue(LLVMTy);
+      Builder.CreateStore(Zero, ReturnValue);
+    }
+  }
+
+  // FIXME: We no longer need the types from FunctionArgList; lift up and
+  // simplify.
+
+  // Emit allocs for param decls.  Give the LLVM Argument nodes names.
+  llvm::Function::arg_iterator AI = Fn->arg_begin();
+
+  // Name the struct return argument.
+  if (CGM.ReturnTypeUsesSret(FI)) {
+    AI->setName("agg.result");
+    ++AI;
+  }
+
+  assert(FI.arg_size() == Args.size() &&
+         "Mismatch between function signature & arguments.");
+  CGFunctionInfo::const_arg_iterator info_it = FI.arg_begin();
+  for (FunctionArgList::const_iterator i = Args.begin(), e = Args.end();
+       i != e; ++i, ++info_it) {
+    const VarDecl *Arg = i->first;
+    QualType Ty = info_it->type;
+    const ABIArgInfo &ArgI = info_it->info;
+
+    switch (ArgI.getKind()) {
+    case ABIArgInfo::Indirect: {
+      llvm::Value* V = AI;
+      if (hasAggregateLLVMType(Ty)) {
+        // Do nothing, aggregates and complex variables are accessed by
+        // reference.
+      } else {
+        // Load scalar value from indirect argument.
+        V = EmitLoadOfScalar(V, false, Ty);
+        if (!getContext().typesAreCompatible(Ty, Arg->getType())) {
+          // This must be a promotion, for something like
+          // "void a(x) short x; {..."
+          V = EmitScalarConversion(V, Ty, Arg->getType());
+        }
+      }
+      EmitParmDecl(*Arg, V);
+      break;
+    }
+
+    case ABIArgInfo::Extend:
+    case ABIArgInfo::Direct: {
+      assert(AI != Fn->arg_end() && "Argument mismatch!");
+      llvm::Value* V = AI;
+      if (hasAggregateLLVMType(Ty)) {
+        // Create a temporary alloca to hold the argument; the rest of
+        // codegen expects to access aggregates & complex values by
+        // reference.
+        V = CreateMemTemp(Ty);
+        Builder.CreateStore(AI, V);
+      } else {
+        if (Arg->getType().isRestrictQualified())
+          AI->addAttr(llvm::Attribute::NoAlias);
+
+        if (!getContext().typesAreCompatible(Ty, Arg->getType())) {
+          // This must be a promotion, for something like
+          // "void a(x) short x; {..."
+          V = EmitScalarConversion(V, Ty, Arg->getType());
+        }
+      }
+      EmitParmDecl(*Arg, V);
+      break;
+    }
+
+    case ABIArgInfo::Expand: {
+      // If this structure was expanded into multiple arguments then
+      // we need to create a temporary and reconstruct it from the
+      // arguments.
+      llvm::Value *Temp = CreateMemTemp(Ty, Arg->getName() + ".addr");
+      // FIXME: What are the right qualifiers here?
+      llvm::Function::arg_iterator End =
+        ExpandTypeFromArgs(Ty, LValue::MakeAddr(Temp, Qualifiers()), AI);
+      EmitParmDecl(*Arg, Temp);
+
+      // Name the arguments used in expansion and increment AI.
+      unsigned Index = 0;
+      for (; AI != End; ++AI, ++Index)
+        AI->setName(Arg->getName() + "." + llvm::Twine(Index));
+      continue;
+    }
+
+    case ABIArgInfo::Ignore:
+      // Initialize the local variable appropriately.
+      if (hasAggregateLLVMType(Ty)) {
+        EmitParmDecl(*Arg, CreateMemTemp(Ty));
+      } else {
+        EmitParmDecl(*Arg, llvm::UndefValue::get(ConvertType(Arg->getType())));
+      }
+
+      // Skip increment, no matching LLVM parameter.
+      continue;
+
+    case ABIArgInfo::Coerce: {
+      assert(AI != Fn->arg_end() && "Argument mismatch!");
+      // FIXME: This is very wasteful; EmitParmDecl is just going to drop the
+      // result in a new alloca anyway, so we could just store into that
+      // directly if we broke the abstraction down more.
+      llvm::Value *V = CreateMemTemp(Ty, "coerce");
+      CreateCoercedStore(AI, V, /*DestIsVolatile=*/false, *this);
+      // Match to what EmitParmDecl is expecting for this type.
+      if (!CodeGenFunction::hasAggregateLLVMType(Ty)) {
+        V = EmitLoadOfScalar(V, false, Ty);
+        if (!getContext().typesAreCompatible(Ty, Arg->getType())) {
+          // This must be a promotion, for something like
+          // "void a(x) short x; {..."
+          V = EmitScalarConversion(V, Ty, Arg->getType());
+        }
+      }
+      EmitParmDecl(*Arg, V);
+      break;
+    }
+    }
+
+    ++AI;
+  }
+  assert(AI == Fn->arg_end() && "Argument mismatch!");
+}
+
+void CodeGenFunction::EmitFunctionEpilog(const CGFunctionInfo &FI,
+                                         llvm::Value *ReturnValue) {
+  llvm::Value *RV = 0;
+
+  // Functions with no result always return void.
+  if (ReturnValue) {
+    QualType RetTy = FI.getReturnType();
+    const ABIArgInfo &RetAI = FI.getReturnInfo();
+
+    switch (RetAI.getKind()) {
+    case ABIArgInfo::Indirect:
+      if (RetTy->isAnyComplexType()) {
+        ComplexPairTy RT = LoadComplexFromAddr(ReturnValue, false);
+        StoreComplexToAddr(RT, CurFn->arg_begin(), false);
+      } else if (CodeGenFunction::hasAggregateLLVMType(RetTy)) {
+        // Do nothing; aggregrates get evaluated directly into the destination.
+      } else {
+        EmitStoreOfScalar(Builder.CreateLoad(ReturnValue), CurFn->arg_begin(),
+                          false, RetTy);
+      }
+      break;
+
+    case ABIArgInfo::Extend:
+    case ABIArgInfo::Direct:
+      // The internal return value temp always will have
+      // pointer-to-return-type type.
+      RV = Builder.CreateLoad(ReturnValue);
+      break;
+
+    case ABIArgInfo::Ignore:
+      break;
+
+    case ABIArgInfo::Coerce:
+      RV = CreateCoercedLoad(ReturnValue, RetAI.getCoerceToType(), *this);
+      break;
+
+    case ABIArgInfo::Expand:
+      assert(0 && "Invalid ABI kind for return argument");
+    }
+  }
+
+  if (RV) {
+    Builder.CreateRet(RV);
+  } else {
+    Builder.CreateRetVoid();
+  }
+}
+
+RValue CodeGenFunction::EmitCallArg(const Expr *E, QualType ArgType) {
+  if (ArgType->isReferenceType())
+    return EmitReferenceBindingToExpr(E);
+
+  return EmitAnyExprToTemp(E);
+}
+
+RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
+                                 llvm::Value *Callee,
+                                 ReturnValueSlot ReturnValue,
+                                 const CallArgList &CallArgs,
+                                 const Decl *TargetDecl) {
+  // FIXME: We no longer need the types from CallArgs; lift up and simplify.
+  llvm::SmallVector<llvm::Value*, 16> Args;
+
+  // Handle struct-return functions by passing a pointer to the
+  // location that we would like to return into.
+  QualType RetTy = CallInfo.getReturnType();
+  const ABIArgInfo &RetAI = CallInfo.getReturnInfo();
+
+
+  // If the call returns a temporary with struct return, create a temporary
+  // alloca to hold the result, unless one is given to us.
+  if (CGM.ReturnTypeUsesSret(CallInfo)) {
+    llvm::Value *Value = ReturnValue.getValue();
+    if (!Value)
+      Value = CreateMemTemp(RetTy);
+    Args.push_back(Value);
+  }
+
+  assert(CallInfo.arg_size() == CallArgs.size() &&
+         "Mismatch between function signature & arguments.");
+  CGFunctionInfo::const_arg_iterator info_it = CallInfo.arg_begin();
+  for (CallArgList::const_iterator I = CallArgs.begin(), E = CallArgs.end();
+       I != E; ++I, ++info_it) {
+    const ABIArgInfo &ArgInfo = info_it->info;
+    RValue RV = I->first;
+
+    switch (ArgInfo.getKind()) {
+    case ABIArgInfo::Indirect:
+      if (RV.isScalar() || RV.isComplex()) {
+        // Make a temporary alloca to pass the argument.
+        Args.push_back(CreateMemTemp(I->second));
+        if (RV.isScalar())
+          EmitStoreOfScalar(RV.getScalarVal(), Args.back(), false, I->second);
+        else
+          StoreComplexToAddr(RV.getComplexVal(), Args.back(), false);
+      } else {
+        Args.push_back(RV.getAggregateAddr());
+      }
+      break;
+
+    case ABIArgInfo::Extend:
+    case ABIArgInfo::Direct:
+      if (RV.isScalar()) {
+        Args.push_back(RV.getScalarVal());
+      } else if (RV.isComplex()) {
+        llvm::Value *Tmp = llvm::UndefValue::get(ConvertType(I->second));
+        Tmp = Builder.CreateInsertValue(Tmp, RV.getComplexVal().first, 0);
+        Tmp = Builder.CreateInsertValue(Tmp, RV.getComplexVal().second, 1);
+        Args.push_back(Tmp);
+      } else {
+        Args.push_back(Builder.CreateLoad(RV.getAggregateAddr()));
+      }
+      break;
+
+    case ABIArgInfo::Ignore:
+      break;
+
+    case ABIArgInfo::Coerce: {
+      // FIXME: Avoid the conversion through memory if possible.
+      llvm::Value *SrcPtr;
+      if (RV.isScalar()) {
+        SrcPtr = CreateMemTemp(I->second, "coerce");
+        EmitStoreOfScalar(RV.getScalarVal(), SrcPtr, false, I->second);
+      } else if (RV.isComplex()) {
+        SrcPtr = CreateMemTemp(I->second, "coerce");
+        StoreComplexToAddr(RV.getComplexVal(), SrcPtr, false);
+      } else
+        SrcPtr = RV.getAggregateAddr();
+      Args.push_back(CreateCoercedLoad(SrcPtr, ArgInfo.getCoerceToType(),
+                                       *this));
+      break;
+    }
+
+    case ABIArgInfo::Expand:
+      ExpandTypeToArgs(I->second, RV, Args);
+      break;
+    }
+  }
+
+  // If the callee is a bitcast of a function to a varargs pointer to function
+  // type, check to see if we can remove the bitcast.  This handles some cases
+  // with unprototyped functions.
+  if (llvm::ConstantExpr *CE = dyn_cast<llvm::ConstantExpr>(Callee))
+    if (llvm::Function *CalleeF = dyn_cast<llvm::Function>(CE->getOperand(0))) {
+      const llvm::PointerType *CurPT=cast<llvm::PointerType>(Callee->getType());
+      const llvm::FunctionType *CurFT =
+        cast<llvm::FunctionType>(CurPT->getElementType());
+      const llvm::FunctionType *ActualFT = CalleeF->getFunctionType();
+
+      if (CE->getOpcode() == llvm::Instruction::BitCast &&
+          ActualFT->getReturnType() == CurFT->getReturnType() &&
+          ActualFT->getNumParams() == CurFT->getNumParams() &&
+          ActualFT->getNumParams() == Args.size()) {
+        bool ArgsMatch = true;
+        for (unsigned i = 0, e = ActualFT->getNumParams(); i != e; ++i)
+          if (ActualFT->getParamType(i) != CurFT->getParamType(i)) {
+            ArgsMatch = false;
+            break;
+          }
+
+        // Strip the cast if we can get away with it.  This is a nice cleanup,
+        // but also allows us to inline the function at -O0 if it is marked
+        // always_inline.
+        if (ArgsMatch)
+          Callee = CalleeF;
+      }
+    }
+
+
+  llvm::BasicBlock *InvokeDest = getInvokeDest();
+  unsigned CallingConv;
+  CodeGen::AttributeListType AttributeList;
+  CGM.ConstructAttributeList(CallInfo, TargetDecl, AttributeList, CallingConv);
+  llvm::AttrListPtr Attrs = llvm::AttrListPtr::get(AttributeList.begin(),
+                                                   AttributeList.end());
+
+  llvm::CallSite CS;
+  if (!InvokeDest || (Attrs.getFnAttributes() & llvm::Attribute::NoUnwind)) {
+    CS = Builder.CreateCall(Callee, Args.data(), Args.data()+Args.size());
+  } else {
+    llvm::BasicBlock *Cont = createBasicBlock("invoke.cont");
+    CS = Builder.CreateInvoke(Callee, Cont, InvokeDest,
+                              Args.data(), Args.data()+Args.size());
+    EmitBlock(Cont);
+  }
+
+  CS.setAttributes(Attrs);
+  CS.setCallingConv(static_cast<llvm::CallingConv::ID>(CallingConv));
+
+  // If the call doesn't return, finish the basic block and clear the
+  // insertion point; this allows the rest of IRgen to discard
+  // unreachable code.
+  if (CS.doesNotReturn()) {
+    Builder.CreateUnreachable();
+    Builder.ClearInsertionPoint();
+
+    // FIXME: For now, emit a dummy basic block because expr emitters in
+    // generally are not ready to handle emitting expressions at unreachable
+    // points.
+    EnsureInsertPoint();
+
+    // Return a reasonable RValue.
+    return GetUndefRValue(RetTy);
+  }
+
+  llvm::Instruction *CI = CS.getInstruction();
+  if (Builder.isNamePreserving() && !CI->getType()->isVoidTy())
+    CI->setName("call");
+
+  switch (RetAI.getKind()) {
+  case ABIArgInfo::Indirect:
+    if (RetTy->isAnyComplexType())
+      return RValue::getComplex(LoadComplexFromAddr(Args[0], false));
+    if (CodeGenFunction::hasAggregateLLVMType(RetTy))
+      return RValue::getAggregate(Args[0]);
+    return RValue::get(EmitLoadOfScalar(Args[0], false, RetTy));
+
+  case ABIArgInfo::Extend:
+  case ABIArgInfo::Direct:
+    if (RetTy->isAnyComplexType()) {
+      llvm::Value *Real = Builder.CreateExtractValue(CI, 0);
+      llvm::Value *Imag = Builder.CreateExtractValue(CI, 1);
+      return RValue::getComplex(std::make_pair(Real, Imag));
+    }
+    if (CodeGenFunction::hasAggregateLLVMType(RetTy)) {
+      llvm::Value *DestPtr = ReturnValue.getValue();
+      bool DestIsVolatile = ReturnValue.isVolatile();
+
+      if (!DestPtr) {
+        DestPtr = CreateMemTemp(RetTy, "agg.tmp");
+        DestIsVolatile = false;
+      }
+      Builder.CreateStore(CI, DestPtr, DestIsVolatile);
+      return RValue::getAggregate(DestPtr);
+    }
+    return RValue::get(CI);
+
+  case ABIArgInfo::Ignore:
+    // If we are ignoring an argument that had a result, make sure to
+    // construct the appropriate return value for our caller.
+    return GetUndefRValue(RetTy);
+
+  case ABIArgInfo::Coerce: {
+    llvm::Value *DestPtr = ReturnValue.getValue();
+    bool DestIsVolatile = ReturnValue.isVolatile();
+    
+    if (!DestPtr) {
+      DestPtr = CreateMemTemp(RetTy, "coerce");
+      DestIsVolatile = false;
+    }
+    
+    CreateCoercedStore(CI, DestPtr, DestIsVolatile, *this);
+    if (RetTy->isAnyComplexType())
+      return RValue::getComplex(LoadComplexFromAddr(DestPtr, false));
+    if (CodeGenFunction::hasAggregateLLVMType(RetTy))
+      return RValue::getAggregate(DestPtr);
+    return RValue::get(EmitLoadOfScalar(DestPtr, false, RetTy));
+  }
+
+  case ABIArgInfo::Expand:
+    assert(0 && "Invalid ABI kind for return argument");
+  }
+
+  assert(0 && "Unhandled ABIArgInfo::Kind");
+  return RValue::get(0);
+}
+
+/* VarArg handling */
+
+llvm::Value *CodeGenFunction::EmitVAArg(llvm::Value *VAListAddr, QualType Ty) {
+  return CGM.getTypes().getABIInfo().EmitVAArg(VAListAddr, Ty, *this);
+}
diff --git a/lib/CodeGen/CGCall.h b/lib/CodeGen/CGCall.h
new file mode 100644
index 0000000..31c8aac
--- /dev/null
+++ b/lib/CodeGen/CGCall.h
@@ -0,0 +1,166 @@
+//===----- CGCall.h - Encapsulate calling convention details ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// These classes wrap the information about a call or function
+// definition used to handle ABI compliancy.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_CODEGEN_CGCALL_H
+#define CLANG_CODEGEN_CGCALL_H
+
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/Value.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/CanonicalType.h"
+
+#include "CGValue.h"
+
+// FIXME: Restructure so we don't have to expose so much stuff.
+#include "ABIInfo.h"
+
+namespace llvm {
+  struct AttributeWithIndex;
+  class Function;
+  class Type;
+  class Value;
+
+  template<typename T, unsigned> class SmallVector;
+}
+
+namespace clang {
+  class ASTContext;
+  class Decl;
+  class FunctionDecl;
+  class ObjCMethodDecl;
+  class VarDecl;
+
+namespace CodeGen {
+  typedef llvm::SmallVector<llvm::AttributeWithIndex, 8> AttributeListType;
+
+  /// CallArgList - Type for representing both the value and type of
+  /// arguments in a call.
+  typedef llvm::SmallVector<std::pair<RValue, QualType>, 16> CallArgList;
+
+  /// FunctionArgList - Type for representing both the decl and type
+  /// of parameters to a function. The decl must be either a
+  /// ParmVarDecl or ImplicitParamDecl.
+  typedef llvm::SmallVector<std::pair<const VarDecl*, QualType>,
+                            16> FunctionArgList;
+
+  /// CGFunctionInfo - Class to encapsulate the information about a
+  /// function definition.
+  class CGFunctionInfo : public llvm::FoldingSetNode {
+    struct ArgInfo {
+      CanQualType type;
+      ABIArgInfo info;
+    };
+
+    /// The LLVM::CallingConv to use for this function (as specified by the
+    /// user).
+    unsigned CallingConvention;
+
+    /// The LLVM::CallingConv to actually use for this function, which may
+    /// depend on the ABI.
+    unsigned EffectiveCallingConvention;
+
+    /// Whether this function is noreturn.
+    bool NoReturn;
+
+    unsigned NumArgs;
+    ArgInfo *Args;
+
+    /// How many arguments to pass inreg.
+    unsigned RegParm;
+
+  public:
+    typedef const ArgInfo *const_arg_iterator;
+    typedef ArgInfo *arg_iterator;
+
+    CGFunctionInfo(unsigned CallingConvention,
+                   bool NoReturn,
+                   unsigned RegParm,
+                   CanQualType ResTy,
+                   const llvm::SmallVectorImpl<CanQualType> &ArgTys);
+    ~CGFunctionInfo() { delete[] Args; }
+
+    const_arg_iterator arg_begin() const { return Args + 1; }
+    const_arg_iterator arg_end() const { return Args + 1 + NumArgs; }
+    arg_iterator arg_begin() { return Args + 1; }
+    arg_iterator arg_end() { return Args + 1 + NumArgs; }
+
+    unsigned  arg_size() const { return NumArgs; }
+
+    bool isNoReturn() const { return NoReturn; }
+
+    /// getCallingConvention - Return the user specified calling
+    /// convention.
+    unsigned getCallingConvention() const { return CallingConvention; }
+
+    /// getEffectiveCallingConvention - Return the actual calling convention to
+    /// use, which may depend on the ABI.
+    unsigned getEffectiveCallingConvention() const {
+      return EffectiveCallingConvention;
+    }
+    void setEffectiveCallingConvention(unsigned Value) {
+      EffectiveCallingConvention = Value;
+    }
+
+    unsigned getRegParm() const { return RegParm; }
+
+    CanQualType getReturnType() const { return Args[0].type; }
+
+    ABIArgInfo &getReturnInfo() { return Args[0].info; }
+    const ABIArgInfo &getReturnInfo() const { return Args[0].info; }
+
+    void Profile(llvm::FoldingSetNodeID &ID) {
+      ID.AddInteger(getCallingConvention());
+      ID.AddBoolean(NoReturn);
+      ID.AddInteger(RegParm);
+      getReturnType().Profile(ID);
+      for (arg_iterator it = arg_begin(), ie = arg_end(); it != ie; ++it)
+        it->type.Profile(ID);
+    }
+    template<class Iterator>
+    static void Profile(llvm::FoldingSetNodeID &ID,
+                        const FunctionType::ExtInfo &Info,
+                        CanQualType ResTy,
+                        Iterator begin,
+                        Iterator end) {
+      ID.AddInteger(Info.getCC());
+      ID.AddBoolean(Info.getNoReturn());
+      ID.AddInteger(Info.getRegParm());
+      ResTy.Profile(ID);
+      for (; begin != end; ++begin) {
+        CanQualType T = *begin; // force iterator to be over canonical types
+        T.Profile(ID);
+      }
+    }
+  };
+  
+  /// ReturnValueSlot - Contains the address where the return value of a 
+  /// function can be stored, and whether the address is volatile or not.
+  class ReturnValueSlot {
+    llvm::PointerIntPair<llvm::Value *, 1, bool> Value;
+
+  public:
+    ReturnValueSlot() {}
+    ReturnValueSlot(llvm::Value *Value, bool IsVolatile)
+      : Value(Value, IsVolatile) {}
+
+    bool isNull() const { return !getValue(); }
+    
+    bool isVolatile() const { return Value.getInt(); }
+    llvm::Value *getValue() const { return Value.getPointer(); }
+  };
+  
+}  // end namespace CodeGen
+}  // end namespace clang
+
+#endif
diff --git a/lib/CodeGen/CGClass.cpp b/lib/CodeGen/CGClass.cpp
new file mode 100644
index 0000000..bfaa54e
--- /dev/null
+++ b/lib/CodeGen/CGClass.cpp
@@ -0,0 +1,1716 @@
+//===--- CGClass.cpp - Emit LLVM Code for C++ classes ---------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This contains code dealing with C++ code generation of classes
+//
+//===----------------------------------------------------------------------===//
+
+#include "CodeGenFunction.h"
+#include "clang/AST/CXXInheritance.h"
+#include "clang/AST/RecordLayout.h"
+#include "clang/AST/StmtCXX.h"
+
+using namespace clang;
+using namespace CodeGen;
+
+static uint64_t 
+ComputeNonVirtualBaseClassOffset(ASTContext &Context, 
+                                 const CXXRecordDecl *DerivedClass,
+                                 CXXBaseSpecifierArray::iterator Start,
+                                 CXXBaseSpecifierArray::iterator End) {
+  uint64_t Offset = 0;
+  
+  const CXXRecordDecl *RD = DerivedClass;
+  
+  for (CXXBaseSpecifierArray::iterator I = Start; I != End; ++I) {
+    const CXXBaseSpecifier *Base = *I;
+    assert(!Base->isVirtual() && "Should not see virtual bases here!");
+
+    // Get the layout.
+    const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
+    
+    const CXXRecordDecl *BaseDecl = 
+      cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
+    
+    // Add the offset.
+    Offset += Layout.getBaseClassOffset(BaseDecl);
+    
+    RD = BaseDecl;
+  }
+  
+  // FIXME: We should not use / 8 here.
+  return Offset / 8;
+}
+                                 
+static uint64_t 
+ComputeNonVirtualBaseClassOffset(ASTContext &Context,
+                                 const CXXBasePath &Path,
+                                 unsigned Start) {
+  uint64_t Offset = 0;
+
+  for (unsigned i = Start, e = Path.size(); i != e; ++i) {
+    const CXXBasePathElement& Element = Path[i];
+
+    // Get the layout.
+    const ASTRecordLayout &Layout = Context.getASTRecordLayout(Element.Class);
+    
+    const CXXBaseSpecifier *BS = Element.Base;
+    assert(!BS->isVirtual() && "Should not see virtual bases here!");
+    
+    const CXXRecordDecl *Base = 
+      cast<CXXRecordDecl>(BS->getType()->getAs<RecordType>()->getDecl());
+    
+    // Add the offset.
+    Offset += Layout.getBaseClassOffset(Base) / 8;
+  }
+
+  return Offset;
+}
+
+llvm::Constant *
+CodeGenModule::GetNonVirtualBaseClassOffset(const CXXRecordDecl *ClassDecl,
+                                        const CXXBaseSpecifierArray &BasePath) {
+  assert(!BasePath.empty() && "Base path should not be empty!");
+
+  uint64_t Offset = 
+    ComputeNonVirtualBaseClassOffset(getContext(), ClassDecl, 
+                                     BasePath.begin(), BasePath.end());
+  if (!Offset)
+    return 0;
+  
+  const llvm::Type *PtrDiffTy = 
+  Types.ConvertType(getContext().getPointerDiffType());
+  
+  return llvm::ConstantInt::get(PtrDiffTy, Offset);
+}
+
+/// Gets the address of a direct base class within a complete object.
+/// This should only be used for (1) non-virtual bases or (2) virtual bases
+/// when the type is known to be complete (e.g. in complete destructors).
+///
+/// The object pointed to by 'This' is assumed to be non-null.
+llvm::Value *
+CodeGenFunction::GetAddressOfDirectBaseInCompleteClass(llvm::Value *This,
+                                                   const CXXRecordDecl *Derived,
+                                                   const CXXRecordDecl *Base,
+                                                   bool BaseIsVirtual) {
+  // 'this' must be a pointer (in some address space) to Derived.
+  assert(This->getType()->isPointerTy() &&
+         cast<llvm::PointerType>(This->getType())->getElementType()
+           == ConvertType(Derived));
+
+  // Compute the offset of the virtual base.
+  uint64_t Offset;
+  const ASTRecordLayout &Layout = getContext().getASTRecordLayout(Derived);
+  if (BaseIsVirtual)
+    Offset = Layout.getVBaseClassOffset(Base);
+  else
+    Offset = Layout.getBaseClassOffset(Base);
+
+  // Shift and cast down to the base type.
+  // TODO: for complete types, this should be possible with a GEP.
+  llvm::Value *V = This;
+  if (Offset) {
+    const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(getLLVMContext());
+    V = Builder.CreateBitCast(V, Int8PtrTy);
+    V = Builder.CreateConstInBoundsGEP1_64(V, Offset / 8);
+  }
+  V = Builder.CreateBitCast(V, ConvertType(Base)->getPointerTo());
+
+  return V;
+}
+
+static llvm::Value *
+ApplyNonVirtualAndVirtualOffset(CodeGenFunction &CGF, llvm::Value *ThisPtr,
+                                uint64_t NonVirtual, llvm::Value *Virtual) {
+  const llvm::Type *PtrDiffTy = 
+    CGF.ConvertType(CGF.getContext().getPointerDiffType());
+  
+  llvm::Value *NonVirtualOffset = 0;
+  if (NonVirtual)
+    NonVirtualOffset = llvm::ConstantInt::get(PtrDiffTy, NonVirtual);
+  
+  llvm::Value *BaseOffset;
+  if (Virtual) {
+    if (NonVirtualOffset)
+      BaseOffset = CGF.Builder.CreateAdd(Virtual, NonVirtualOffset);
+    else
+      BaseOffset = Virtual;
+  } else
+    BaseOffset = NonVirtualOffset;
+  
+  // Apply the base offset.
+  const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGF.getLLVMContext());
+  ThisPtr = CGF.Builder.CreateBitCast(ThisPtr, Int8PtrTy);
+  ThisPtr = CGF.Builder.CreateGEP(ThisPtr, BaseOffset, "add.ptr");
+
+  return ThisPtr;
+}
+
+llvm::Value *
+CodeGenFunction::GetAddressOfBaseClass(llvm::Value *Value, 
+                                       const CXXRecordDecl *Derived,
+                                       const CXXBaseSpecifierArray &BasePath, 
+                                       bool NullCheckValue) {
+  assert(!BasePath.empty() && "Base path should not be empty!");
+
+  CXXBaseSpecifierArray::iterator Start = BasePath.begin();
+  const CXXRecordDecl *VBase = 0;
+  
+  // Get the virtual base.
+  if ((*Start)->isVirtual()) {
+    VBase = 
+      cast<CXXRecordDecl>((*Start)->getType()->getAs<RecordType>()->getDecl());
+    ++Start;
+  }
+  
+  uint64_t NonVirtualOffset = 
+    ComputeNonVirtualBaseClassOffset(getContext(), VBase ? VBase : Derived,
+                                     Start, BasePath.end());
+
+  // Get the base pointer type.
+  const llvm::Type *BasePtrTy = 
+    ConvertType((BasePath.end()[-1])->getType())->getPointerTo();
+  
+  if (!NonVirtualOffset && !VBase) {
+    // Just cast back.
+    return Builder.CreateBitCast(Value, BasePtrTy);
+  }    
+  
+  llvm::BasicBlock *CastNull = 0;
+  llvm::BasicBlock *CastNotNull = 0;
+  llvm::BasicBlock *CastEnd = 0;
+  
+  if (NullCheckValue) {
+    CastNull = createBasicBlock("cast.null");
+    CastNotNull = createBasicBlock("cast.notnull");
+    CastEnd = createBasicBlock("cast.end");
+    
+    llvm::Value *IsNull = 
+      Builder.CreateICmpEQ(Value,
+                           llvm::Constant::getNullValue(Value->getType()));
+    Builder.CreateCondBr(IsNull, CastNull, CastNotNull);
+    EmitBlock(CastNotNull);
+  }
+
+  llvm::Value *VirtualOffset = 0;
+
+  if (VBase)
+    VirtualOffset = GetVirtualBaseClassOffset(Value, Derived, VBase);
+
+  // Apply the offsets.
+  Value = ApplyNonVirtualAndVirtualOffset(*this, Value, NonVirtualOffset, 
+                                          VirtualOffset);
+  
+  // Cast back.
+  Value = Builder.CreateBitCast(Value, BasePtrTy);
+ 
+  if (NullCheckValue) {
+    Builder.CreateBr(CastEnd);
+    EmitBlock(CastNull);
+    Builder.CreateBr(CastEnd);
+    EmitBlock(CastEnd);
+    
+    llvm::PHINode *PHI = Builder.CreatePHI(Value->getType());
+    PHI->reserveOperandSpace(2);
+    PHI->addIncoming(Value, CastNotNull);
+    PHI->addIncoming(llvm::Constant::getNullValue(Value->getType()), 
+                     CastNull);
+    Value = PHI;
+  }
+  
+  return Value;
+}
+
+llvm::Value *
+CodeGenFunction::OldGetAddressOfBaseClass(llvm::Value *Value,
+                                          const CXXRecordDecl *Class,
+                                          const CXXRecordDecl *BaseClass) {
+  QualType BTy =
+    getContext().getCanonicalType(
+      getContext().getTypeDeclType(BaseClass));
+  const llvm::Type *BasePtrTy = llvm::PointerType::getUnqual(ConvertType(BTy));
+
+  if (Class == BaseClass) {
+    // Just cast back.
+    return Builder.CreateBitCast(Value, BasePtrTy);
+  }
+
+#ifndef NDEBUG
+  CXXBasePaths Paths(/*FindAmbiguities=*/true,
+                     /*RecordPaths=*/true, /*DetectVirtual=*/false);
+#else
+  CXXBasePaths Paths(/*FindAmbiguities=*/false,
+                     /*RecordPaths=*/true, /*DetectVirtual=*/false);
+#endif
+  if (!const_cast<CXXRecordDecl *>(Class)->
+        isDerivedFrom(const_cast<CXXRecordDecl *>(BaseClass), Paths)) {
+    assert(false && "Class must be derived from the passed in base class!");
+    return 0;
+  }
+
+#if 0
+  // FIXME: Re-enable this assert when the underlying bugs have been fixed.
+  assert(!Paths.isAmbiguous(BTy) && "Path is ambiguous");
+#endif
+
+  unsigned Start = 0;
+
+  const CXXBasePath &Path = Paths.front();
+  const CXXRecordDecl *VBase = 0;
+  for (unsigned i = 0, e = Path.size(); i != e; ++i) {
+    const CXXBasePathElement& Element = Path[i];
+    if (Element.Base->isVirtual()) {
+      Start = i+1;
+      QualType VBaseType = Element.Base->getType();
+      VBase = cast<CXXRecordDecl>(VBaseType->getAs<RecordType>()->getDecl());
+    }
+  }
+
+  uint64_t Offset = 
+    ComputeNonVirtualBaseClassOffset(getContext(), Paths.front(), Start);
+  
+  if (!Offset && !VBase) {
+    // Just cast back.
+    return Builder.CreateBitCast(Value, BasePtrTy);
+  }    
+
+  llvm::Value *VirtualOffset = 0;
+
+  if (VBase)
+    VirtualOffset = GetVirtualBaseClassOffset(Value, Class, VBase);
+
+  // Apply the offsets.
+  Value = ApplyNonVirtualAndVirtualOffset(*this, Value, Offset, VirtualOffset);
+  
+  // Cast back.
+  Value = Builder.CreateBitCast(Value, BasePtrTy);
+  return Value;
+}
+
+llvm::Value *
+CodeGenFunction::GetAddressOfDerivedClass(llvm::Value *Value,
+                                          const CXXRecordDecl *Derived,
+                                          const CXXBaseSpecifierArray &BasePath,
+                                          bool NullCheckValue) {
+  assert(!BasePath.empty() && "Base path should not be empty!");
+
+  QualType DerivedTy =
+    getContext().getCanonicalType(getContext().getTagDeclType(Derived));
+  const llvm::Type *DerivedPtrTy = ConvertType(DerivedTy)->getPointerTo();
+  
+  llvm::Value *NonVirtualOffset =
+    CGM.GetNonVirtualBaseClassOffset(Derived, BasePath);
+  
+  if (!NonVirtualOffset) {
+    // No offset, we can just cast back.
+    return Builder.CreateBitCast(Value, DerivedPtrTy);
+  }
+  
+  llvm::BasicBlock *CastNull = 0;
+  llvm::BasicBlock *CastNotNull = 0;
+  llvm::BasicBlock *CastEnd = 0;
+  
+  if (NullCheckValue) {
+    CastNull = createBasicBlock("cast.null");
+    CastNotNull = createBasicBlock("cast.notnull");
+    CastEnd = createBasicBlock("cast.end");
+    
+    llvm::Value *IsNull = 
+    Builder.CreateICmpEQ(Value,
+                         llvm::Constant::getNullValue(Value->getType()));
+    Builder.CreateCondBr(IsNull, CastNull, CastNotNull);
+    EmitBlock(CastNotNull);
+  }
+  
+  // Apply the offset.
+  Value = Builder.CreatePtrToInt(Value, NonVirtualOffset->getType());
+  Value = Builder.CreateSub(Value, NonVirtualOffset);
+  Value = Builder.CreateIntToPtr(Value, DerivedPtrTy);
+
+  // Just cast.
+  Value = Builder.CreateBitCast(Value, DerivedPtrTy);
+
+  if (NullCheckValue) {
+    Builder.CreateBr(CastEnd);
+    EmitBlock(CastNull);
+    Builder.CreateBr(CastEnd);
+    EmitBlock(CastEnd);
+    
+    llvm::PHINode *PHI = Builder.CreatePHI(Value->getType());
+    PHI->reserveOperandSpace(2);
+    PHI->addIncoming(Value, CastNotNull);
+    PHI->addIncoming(llvm::Constant::getNullValue(Value->getType()), 
+                     CastNull);
+    Value = PHI;
+  }
+  
+  return Value;
+}
+
+/// EmitCopyCtorCall - Emit a call to a copy constructor.
+static void
+EmitCopyCtorCall(CodeGenFunction &CGF,
+                 const CXXConstructorDecl *CopyCtor, CXXCtorType CopyCtorType,
+                 llvm::Value *ThisPtr, llvm::Value *VTT, llvm::Value *Src) {
+  llvm::Value *Callee = CGF.CGM.GetAddrOfCXXConstructor(CopyCtor, CopyCtorType);
+
+  CallArgList CallArgs;
+
+  // Push the this ptr.
+  CallArgs.push_back(std::make_pair(RValue::get(ThisPtr),
+                                    CopyCtor->getThisType(CGF.getContext())));
+  
+  // Push the VTT parameter if necessary.
+  if (VTT) {
+    QualType T = CGF.getContext().getPointerType(CGF.getContext().VoidPtrTy);
+    CallArgs.push_back(std::make_pair(RValue::get(VTT), T));
+  }
+ 
+  // Push the Src ptr.
+  CallArgs.push_back(std::make_pair(RValue::get(Src),
+                                    CopyCtor->getParamDecl(0)->getType()));
+
+
+  {
+    CodeGenFunction::CXXTemporariesCleanupScope Scope(CGF);
+
+    // If the copy constructor has default arguments, emit them.
+    for (unsigned I = 1, E = CopyCtor->getNumParams(); I < E; ++I) {
+      const ParmVarDecl *Param = CopyCtor->getParamDecl(I);
+      const Expr *DefaultArgExpr = Param->getDefaultArg();
+
+      assert(DefaultArgExpr && "Ctor parameter must have default arg!");
+
+      QualType ArgType = Param->getType();
+      CallArgs.push_back(std::make_pair(CGF.EmitCallArg(DefaultArgExpr, 
+                                                        ArgType),
+                                        ArgType));
+    }
+
+    const FunctionProtoType *FPT =
+      CopyCtor->getType()->getAs<FunctionProtoType>();
+    CGF.EmitCall(CGF.CGM.getTypes().getFunctionInfo(CallArgs, FPT),
+                 Callee, ReturnValueSlot(), CallArgs, CopyCtor);
+  }
+}
+                             
+/// EmitClassAggrMemberwiseCopy - This routine generates code to copy a class
+/// array of objects from SrcValue to DestValue. Copying can be either a bitwise
+/// copy or via a copy constructor call.
+//  FIXME. Consolidate this with EmitCXXAggrConstructorCall.
+void CodeGenFunction::EmitClassAggrMemberwiseCopy(llvm::Value *Dest,
+                                            llvm::Value *Src,
+                                            const ArrayType *Array,
+                                            const CXXRecordDecl *BaseClassDecl,
+                                            QualType Ty) {
+  const ConstantArrayType *CA = dyn_cast<ConstantArrayType>(Array);
+  assert(CA && "VLA cannot be copied over");
+  bool BitwiseCopy = BaseClassDecl->hasTrivialCopyConstructor();
+
+  // Create a temporary for the loop index and initialize it with 0.
+  llvm::Value *IndexPtr = CreateTempAlloca(llvm::Type::getInt64Ty(VMContext),
+                                           "loop.index");
+  llvm::Value* zeroConstant =
+    llvm::Constant::getNullValue(llvm::Type::getInt64Ty(VMContext));
+  Builder.CreateStore(zeroConstant, IndexPtr);
+  // Start the loop with a block that tests the condition.
+  llvm::BasicBlock *CondBlock = createBasicBlock("for.cond");
+  llvm::BasicBlock *AfterFor = createBasicBlock("for.end");
+
+  EmitBlock(CondBlock);
+
+  llvm::BasicBlock *ForBody = createBasicBlock("for.body");
+  // Generate: if (loop-index < number-of-elements fall to the loop body,
+  // otherwise, go to the block after the for-loop.
+  uint64_t NumElements = getContext().getConstantArrayElementCount(CA);
+  llvm::Value * NumElementsPtr =
+    llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), NumElements);
+  llvm::Value *Counter = Builder.CreateLoad(IndexPtr);
+  llvm::Value *IsLess = Builder.CreateICmpULT(Counter, NumElementsPtr,
+                                              "isless");
+  // If the condition is true, execute the body.
+  Builder.CreateCondBr(IsLess, ForBody, AfterFor);
+
+  EmitBlock(ForBody);
+  llvm::BasicBlock *ContinueBlock = createBasicBlock("for.inc");
+  // Inside the loop body, emit the constructor call on the array element.
+  Counter = Builder.CreateLoad(IndexPtr);
+  Src = Builder.CreateInBoundsGEP(Src, Counter, "srcaddress");
+  Dest = Builder.CreateInBoundsGEP(Dest, Counter, "destaddress");
+  if (BitwiseCopy)
+    EmitAggregateCopy(Dest, Src, Ty);
+  else if (CXXConstructorDecl *BaseCopyCtor =
+           BaseClassDecl->getCopyConstructor(getContext(), 0))
+    EmitCopyCtorCall(*this, BaseCopyCtor, Ctor_Complete, Dest, 0, Src);
+
+  EmitBlock(ContinueBlock);
+
+  // Emit the increment of the loop counter.
+  llvm::Value *NextVal = llvm::ConstantInt::get(Counter->getType(), 1);
+  Counter = Builder.CreateLoad(IndexPtr);
+  NextVal = Builder.CreateAdd(Counter, NextVal, "inc");
+  Builder.CreateStore(NextVal, IndexPtr);
+
+  // Finally, branch back up to the condition for the next iteration.
+  EmitBranch(CondBlock);
+
+  // Emit the fall-through block.
+  EmitBlock(AfterFor, true);
+}
+
+/// EmitClassAggrCopyAssignment - This routine generates code to assign a class
+/// array of objects from SrcValue to DestValue. Assignment can be either a
+/// bitwise assignment or via a copy assignment operator function call.
+/// FIXME. This can be consolidated with EmitClassAggrMemberwiseCopy
+void CodeGenFunction::EmitClassAggrCopyAssignment(llvm::Value *Dest,
+                                            llvm::Value *Src,
+                                            const ArrayType *Array,
+                                            const CXXRecordDecl *BaseClassDecl,
+                                            QualType Ty) {
+  const ConstantArrayType *CA = dyn_cast<ConstantArrayType>(Array);
+  assert(CA && "VLA cannot be asssigned");
+  bool BitwiseAssign = BaseClassDecl->hasTrivialCopyAssignment();
+
+  // Create a temporary for the loop index and initialize it with 0.
+  llvm::Value *IndexPtr = CreateTempAlloca(llvm::Type::getInt64Ty(VMContext),
+                                           "loop.index");
+  llvm::Value* zeroConstant =
+  llvm::Constant::getNullValue(llvm::Type::getInt64Ty(VMContext));
+  Builder.CreateStore(zeroConstant, IndexPtr);
+  // Start the loop with a block that tests the condition.
+  llvm::BasicBlock *CondBlock = createBasicBlock("for.cond");
+  llvm::BasicBlock *AfterFor = createBasicBlock("for.end");
+
+  EmitBlock(CondBlock);
+
+  llvm::BasicBlock *ForBody = createBasicBlock("for.body");
+  // Generate: if (loop-index < number-of-elements fall to the loop body,
+  // otherwise, go to the block after the for-loop.
+  uint64_t NumElements = getContext().getConstantArrayElementCount(CA);
+  llvm::Value * NumElementsPtr =
+  llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), NumElements);
+  llvm::Value *Counter = Builder.CreateLoad(IndexPtr);
+  llvm::Value *IsLess = Builder.CreateICmpULT(Counter, NumElementsPtr,
+                                              "isless");
+  // If the condition is true, execute the body.
+  Builder.CreateCondBr(IsLess, ForBody, AfterFor);
+
+  EmitBlock(ForBody);
+  llvm::BasicBlock *ContinueBlock = createBasicBlock("for.inc");
+  // Inside the loop body, emit the assignment operator call on array element.
+  Counter = Builder.CreateLoad(IndexPtr);
+  Src = Builder.CreateInBoundsGEP(Src, Counter, "srcaddress");
+  Dest = Builder.CreateInBoundsGEP(Dest, Counter, "destaddress");
+  const CXXMethodDecl *MD = 0;
+  if (BitwiseAssign)
+    EmitAggregateCopy(Dest, Src, Ty);
+  else {
+    BaseClassDecl->hasConstCopyAssignment(getContext(), MD);
+    assert(MD && "EmitClassAggrCopyAssignment - No user assign");
+    const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>();
+    const llvm::Type *LTy =
+    CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD),
+                                   FPT->isVariadic());
+    llvm::Constant *Callee = CGM.GetAddrOfFunction(MD, LTy);
+
+    CallArgList CallArgs;
+    // Push the this (Dest) ptr.
+    CallArgs.push_back(std::make_pair(RValue::get(Dest),
+                                      MD->getThisType(getContext())));
+
+    // Push the Src ptr.
+    QualType SrcTy = MD->getParamDecl(0)->getType();
+    RValue SrcValue = SrcTy->isReferenceType() ? RValue::get(Src) :
+                                                 RValue::getAggregate(Src);
+    CallArgs.push_back(std::make_pair(SrcValue, SrcTy));
+    EmitCall(CGM.getTypes().getFunctionInfo(CallArgs, FPT),
+             Callee, ReturnValueSlot(), CallArgs, MD);
+  }
+  EmitBlock(ContinueBlock);
+
+  // Emit the increment of the loop counter.
+  llvm::Value *NextVal = llvm::ConstantInt::get(Counter->getType(), 1);
+  Counter = Builder.CreateLoad(IndexPtr);
+  NextVal = Builder.CreateAdd(Counter, NextVal, "inc");
+  Builder.CreateStore(NextVal, IndexPtr);
+
+  // Finally, branch back up to the condition for the next iteration.
+  EmitBranch(CondBlock);
+
+  // Emit the fall-through block.
+  EmitBlock(AfterFor, true);
+}
+
+/// GetVTTParameter - Return the VTT parameter that should be passed to a
+/// base constructor/destructor with virtual bases.
+static llvm::Value *GetVTTParameter(CodeGenFunction &CGF, GlobalDecl GD) {
+  if (!CodeGenVTables::needsVTTParameter(GD)) {
+    // This constructor/destructor does not need a VTT parameter.
+    return 0;
+  }
+  
+  const CXXRecordDecl *RD = cast<CXXMethodDecl>(CGF.CurFuncDecl)->getParent();
+  const CXXRecordDecl *Base = cast<CXXMethodDecl>(GD.getDecl())->getParent();
+
+  llvm::Value *VTT;
+
+  uint64_t SubVTTIndex;
+
+  // If the record matches the base, this is the complete ctor/dtor
+  // variant calling the base variant in a class with virtual bases.
+  if (RD == Base) {
+    assert(!CodeGenVTables::needsVTTParameter(CGF.CurGD) &&
+           "doing no-op VTT offset in base dtor/ctor?");
+    SubVTTIndex = 0;
+  } else {
+    SubVTTIndex = CGF.CGM.getVTables().getSubVTTIndex(RD, Base);
+    assert(SubVTTIndex != 0 && "Sub-VTT index must be greater than zero!");
+  }
+  
+  if (CodeGenVTables::needsVTTParameter(CGF.CurGD)) {
+    // A VTT parameter was passed to the constructor, use it.
+    VTT = CGF.LoadCXXVTT();
+    VTT = CGF.Builder.CreateConstInBoundsGEP1_64(VTT, SubVTTIndex);
+  } else {
+    // We're the complete constructor, so get the VTT by name.
+    VTT = CGF.CGM.getVTables().getVTT(RD);
+    VTT = CGF.Builder.CreateConstInBoundsGEP2_64(VTT, 0, SubVTTIndex);
+  }
+
+  return VTT;
+}
+
+                                    
+/// EmitClassMemberwiseCopy - This routine generates code to copy a class
+/// object from SrcValue to DestValue. Copying can be either a bitwise copy
+/// or via a copy constructor call.
+void CodeGenFunction::EmitClassMemberwiseCopy(
+                        llvm::Value *Dest, llvm::Value *Src,
+                        const CXXRecordDecl *ClassDecl,
+                        const CXXRecordDecl *BaseClassDecl, QualType Ty) {
+  CXXCtorType CtorType = Ctor_Complete;
+  
+  if (ClassDecl) {
+    Dest = OldGetAddressOfBaseClass(Dest, ClassDecl, BaseClassDecl);
+    Src = OldGetAddressOfBaseClass(Src, ClassDecl, BaseClassDecl);
+
+    // We want to call the base constructor.
+    CtorType = Ctor_Base;
+  }
+  if (BaseClassDecl->hasTrivialCopyConstructor()) {
+    EmitAggregateCopy(Dest, Src, Ty);
+    return;
+  }
+
+  CXXConstructorDecl *BaseCopyCtor =
+    BaseClassDecl->getCopyConstructor(getContext(), 0);
+  if (!BaseCopyCtor)
+    return;
+
+  llvm::Value *VTT = GetVTTParameter(*this, GlobalDecl(BaseCopyCtor, CtorType));
+  EmitCopyCtorCall(*this, BaseCopyCtor, CtorType, Dest, VTT, Src);
+}
+
+/// EmitClassCopyAssignment - This routine generates code to copy assign a class
+/// object from SrcValue to DestValue. Assignment can be either a bitwise
+/// assignment of via an assignment operator call.
+// FIXME. Consolidate this with EmitClassMemberwiseCopy as they share a lot.
+void CodeGenFunction::EmitClassCopyAssignment(
+                                        llvm::Value *Dest, llvm::Value *Src,
+                                        const CXXRecordDecl *ClassDecl,
+                                        const CXXRecordDecl *BaseClassDecl,
+                                        QualType Ty) {
+  if (ClassDecl) {
+    Dest = OldGetAddressOfBaseClass(Dest, ClassDecl, BaseClassDecl);
+    Src = OldGetAddressOfBaseClass(Src, ClassDecl, BaseClassDecl);
+  }
+  if (BaseClassDecl->hasTrivialCopyAssignment()) {
+    EmitAggregateCopy(Dest, Src, Ty);
+    return;
+  }
+
+  const CXXMethodDecl *MD = 0;
+  BaseClassDecl->hasConstCopyAssignment(getContext(), MD);
+  assert(MD && "EmitClassCopyAssignment - missing copy assign");
+
+  const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>();
+  const llvm::Type *LTy =
+    CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD),
+                                   FPT->isVariadic());
+  llvm::Constant *Callee = CGM.GetAddrOfFunction(MD, LTy);
+
+  CallArgList CallArgs;
+  // Push the this (Dest) ptr.
+  CallArgs.push_back(std::make_pair(RValue::get(Dest),
+                                    MD->getThisType(getContext())));
+
+  // Push the Src ptr.
+  QualType SrcTy = MD->getParamDecl(0)->getType();
+  RValue SrcValue = SrcTy->isReferenceType() ? RValue::get(Src) :
+                                               RValue::getAggregate(Src);
+  CallArgs.push_back(std::make_pair(SrcValue, SrcTy));
+  EmitCall(CGM.getTypes().getFunctionInfo(CallArgs, FPT),
+           Callee, ReturnValueSlot(), CallArgs, MD);
+}
+
+/// SynthesizeCXXCopyConstructor - This routine implicitly defines body of a
+/// copy constructor, in accordance with section 12.8 (p7 and p8) of C++03
+/// The implicitly-defined copy constructor for class X performs a memberwise
+/// copy of its subobjects. The order of copying is the same as the order of
+/// initialization of bases and members in a user-defined constructor
+/// Each subobject is copied in the manner appropriate to its type:
+///  if the subobject is of class type, the copy constructor for the class is
+///  used;
+///  if the subobject is an array, each element is copied, in the manner
+///  appropriate to the element type;
+///  if the subobject is of scalar type, the built-in assignment operator is
+///  used.
+/// Virtual base class subobjects shall be copied only once by the
+/// implicitly-defined copy constructor
+
+void 
+CodeGenFunction::SynthesizeCXXCopyConstructor(const FunctionArgList &Args) {
+  const CXXConstructorDecl *Ctor = cast<CXXConstructorDecl>(CurGD.getDecl());
+  const CXXRecordDecl *ClassDecl = Ctor->getParent();
+  assert(!ClassDecl->hasUserDeclaredCopyConstructor() &&
+      "SynthesizeCXXCopyConstructor - copy constructor has definition already");
+  assert(!Ctor->isTrivial() && "shouldn't need to generate trivial ctor");
+
+  llvm::Value *ThisPtr = LoadCXXThis();
+  llvm::Value *SrcPtr = Builder.CreateLoad(GetAddrOfLocalVar(Args[1].first));
+
+  for (CXXRecordDecl::base_class_const_iterator Base = ClassDecl->bases_begin();
+       Base != ClassDecl->bases_end(); ++Base) {
+    // FIXME. copy constrution of virtual base NYI
+    if (Base->isVirtual())
+      continue;
+
+    CXXRecordDecl *BaseClassDecl
+      = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
+    EmitClassMemberwiseCopy(ThisPtr, SrcPtr, ClassDecl, BaseClassDecl,
+                            Base->getType());
+  }
+
+  for (CXXRecordDecl::field_iterator I = ClassDecl->field_begin(),
+       E = ClassDecl->field_end(); I != E; ++I) {
+    const FieldDecl *Field = *I;
+    
+    QualType FieldType = getContext().getCanonicalType(Field->getType());
+    const ConstantArrayType *Array =
+      getContext().getAsConstantArrayType(FieldType);
+    if (Array)
+      FieldType = getContext().getBaseElementType(FieldType);
+
+    if (const RecordType *FieldClassType = FieldType->getAs<RecordType>()) {
+      CXXRecordDecl *FieldClassDecl
+        = cast<CXXRecordDecl>(FieldClassType->getDecl());
+      LValue LHS = EmitLValueForField(ThisPtr, Field, 0);
+      LValue RHS = EmitLValueForField(SrcPtr, Field, 0);
+      if (Array) {
+        const llvm::Type *BasePtr = ConvertType(FieldType)->getPointerTo();
+        llvm::Value *DestBaseAddrPtr =
+          Builder.CreateBitCast(LHS.getAddress(), BasePtr);
+        llvm::Value *SrcBaseAddrPtr =
+          Builder.CreateBitCast(RHS.getAddress(), BasePtr);
+        EmitClassAggrMemberwiseCopy(DestBaseAddrPtr, SrcBaseAddrPtr, Array,
+                                    FieldClassDecl, FieldType);
+      }
+      else
+        EmitClassMemberwiseCopy(LHS.getAddress(), RHS.getAddress(),
+                                0 /*ClassDecl*/, FieldClassDecl, FieldType);
+      continue;
+    }
+    
+    // Do a built-in assignment of scalar data members.
+    LValue LHS = EmitLValueForFieldInitialization(ThisPtr, Field, 0);
+    LValue RHS = EmitLValueForFieldInitialization(SrcPtr, Field, 0);
+
+    if (!hasAggregateLLVMType(Field->getType())) {
+      RValue RVRHS = EmitLoadOfLValue(RHS, Field->getType());
+      EmitStoreThroughLValue(RVRHS, LHS, Field->getType());
+    } else if (Field->getType()->isAnyComplexType()) {
+      ComplexPairTy Pair = LoadComplexFromAddr(RHS.getAddress(),
+                                               RHS.isVolatileQualified());
+      StoreComplexToAddr(Pair, LHS.getAddress(), LHS.isVolatileQualified());
+    } else {
+      EmitAggregateCopy(LHS.getAddress(), RHS.getAddress(), Field->getType());
+    }
+  }
+
+  InitializeVTablePointers(ClassDecl);
+}
+
+/// SynthesizeCXXCopyAssignment - Implicitly define copy assignment operator.
+/// Before the implicitly-declared copy assignment operator for a class is
+/// implicitly defined, all implicitly- declared copy assignment operators for
+/// its direct base classes and its nonstatic data members shall have been
+/// implicitly defined. [12.8-p12]
+/// The implicitly-defined copy assignment operator for class X performs
+/// memberwise assignment of its subob- jects. The direct base classes of X are
+/// assigned first, in the order of their declaration in
+/// the base-specifier-list, and then the immediate nonstatic data members of X
+/// are assigned, in the order in which they were declared in the class
+/// definition.Each subobject is assigned in the manner appropriate to its type:
+///   if the subobject is of class type, the copy assignment operator for the
+///   class is used (as if by explicit qualification; that is, ignoring any
+///   possible virtual overriding functions in more derived classes);
+///
+///   if the subobject is an array, each element is assigned, in the manner
+///   appropriate to the element type;
+///
+///   if the subobject is of scalar type, the built-in assignment operator is
+///   used.
+void CodeGenFunction::SynthesizeCXXCopyAssignment(const FunctionArgList &Args) {
+  const CXXMethodDecl *MD = cast<CXXMethodDecl>(CurGD.getDecl());
+  const CXXRecordDecl *ClassDecl = MD->getParent();
+  assert(!ClassDecl->hasUserDeclaredCopyAssignment() &&
+         "SynthesizeCXXCopyAssignment - copy assignment has user declaration");
+
+  llvm::Value *ThisPtr = LoadCXXThis();
+  llvm::Value *SrcPtr = 
+    Builder.CreateLoad(GetAddrOfLocalVar(Args[1].first));
+
+  for (CXXRecordDecl::base_class_const_iterator Base = ClassDecl->bases_begin();
+       Base != ClassDecl->bases_end(); ++Base) {
+    // FIXME. copy assignment of virtual base NYI
+    if (Base->isVirtual())
+      continue;
+
+    CXXRecordDecl *BaseClassDecl
+      = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
+    EmitClassCopyAssignment(ThisPtr, SrcPtr, ClassDecl, BaseClassDecl,
+                            Base->getType());
+  }
+
+  for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
+       FieldEnd = ClassDecl->field_end();
+       Field != FieldEnd; ++Field) {
+    QualType FieldType = getContext().getCanonicalType((*Field)->getType());
+    const ConstantArrayType *Array =
+      getContext().getAsConstantArrayType(FieldType);
+    if (Array)
+      FieldType = getContext().getBaseElementType(FieldType);
+
+    if (const RecordType *FieldClassType = FieldType->getAs<RecordType>()) {
+      CXXRecordDecl *FieldClassDecl
+      = cast<CXXRecordDecl>(FieldClassType->getDecl());
+      LValue LHS = EmitLValueForField(ThisPtr, *Field, 0);
+      LValue RHS = EmitLValueForField(SrcPtr, *Field, 0);
+      if (Array) {
+        const llvm::Type *BasePtr = ConvertType(FieldType);
+        BasePtr = llvm::PointerType::getUnqual(BasePtr);
+        llvm::Value *DestBaseAddrPtr =
+          Builder.CreateBitCast(LHS.getAddress(), BasePtr);
+        llvm::Value *SrcBaseAddrPtr =
+          Builder.CreateBitCast(RHS.getAddress(), BasePtr);
+        EmitClassAggrCopyAssignment(DestBaseAddrPtr, SrcBaseAddrPtr, Array,
+                                    FieldClassDecl, FieldType);
+      }
+      else
+        EmitClassCopyAssignment(LHS.getAddress(), RHS.getAddress(),
+                               0 /*ClassDecl*/, FieldClassDecl, FieldType);
+      continue;
+    }
+    // Do a built-in assignment of scalar data members.
+    LValue LHS = EmitLValueForField(ThisPtr, *Field, 0);
+    LValue RHS = EmitLValueForField(SrcPtr, *Field, 0);
+    if (!hasAggregateLLVMType(Field->getType())) {
+      RValue RVRHS = EmitLoadOfLValue(RHS, Field->getType());
+      EmitStoreThroughLValue(RVRHS, LHS, Field->getType());
+    } else if (Field->getType()->isAnyComplexType()) {
+      ComplexPairTy Pair = LoadComplexFromAddr(RHS.getAddress(),
+                                               RHS.isVolatileQualified());
+      StoreComplexToAddr(Pair, LHS.getAddress(), LHS.isVolatileQualified());
+    } else {
+      EmitAggregateCopy(LHS.getAddress(), RHS.getAddress(), Field->getType());
+    }
+  }
+
+  // return *this;
+  Builder.CreateStore(ThisPtr, ReturnValue);
+}
+
+static void EmitBaseInitializer(CodeGenFunction &CGF, 
+                                const CXXRecordDecl *ClassDecl,
+                                CXXBaseOrMemberInitializer *BaseInit,
+                                CXXCtorType CtorType) {
+  assert(BaseInit->isBaseInitializer() &&
+         "Must have base initializer!");
+
+  llvm::Value *ThisPtr = CGF.LoadCXXThis();
+  
+  const Type *BaseType = BaseInit->getBaseClass();
+  CXXRecordDecl *BaseClassDecl =
+    cast<CXXRecordDecl>(BaseType->getAs<RecordType>()->getDecl());
+
+  bool isBaseVirtual = BaseInit->isBaseVirtual();
+
+  // The base constructor doesn't construct virtual bases.
+  if (CtorType == Ctor_Base && isBaseVirtual)
+    return;
+
+  // We can pretend to be a complete class because it only matters for
+  // virtual bases, and we only do virtual bases for complete ctors.
+  llvm::Value *V = 
+    CGF.GetAddressOfDirectBaseInCompleteClass(ThisPtr, ClassDecl,
+                                              BaseClassDecl, 
+                                              BaseInit->isBaseVirtual());
+
+  CGF.EmitAggExpr(BaseInit->getInit(), V, false, false, true);
+  
+  if (CGF.Exceptions && !BaseClassDecl->hasTrivialDestructor()) {
+    // FIXME: Is this OK for C++0x delegating constructors?
+    CodeGenFunction::EHCleanupBlock Cleanup(CGF);
+
+    CXXDestructorDecl *DD = BaseClassDecl->getDestructor(CGF.getContext());
+    CGF.EmitCXXDestructorCall(DD, Dtor_Base, V);
+  }
+}
+
+static void EmitMemberInitializer(CodeGenFunction &CGF,
+                                  const CXXRecordDecl *ClassDecl,
+                                  CXXBaseOrMemberInitializer *MemberInit) {
+  assert(MemberInit->isMemberInitializer() &&
+         "Must have member initializer!");
+  
+  // non-static data member initializers.
+  FieldDecl *Field = MemberInit->getMember();
+  QualType FieldType = CGF.getContext().getCanonicalType(Field->getType());
+
+  llvm::Value *ThisPtr = CGF.LoadCXXThis();
+  LValue LHS = CGF.EmitLValueForFieldInitialization(ThisPtr, Field, 0);
+  
+  // If we are initializing an anonymous union field, drill down to the field.
+  if (MemberInit->getAnonUnionMember()) {
+    Field = MemberInit->getAnonUnionMember();
+    LHS = CGF.EmitLValueForField(LHS.getAddress(), Field, 0);
+    FieldType = Field->getType();
+  }
+
+  // FIXME: If there's no initializer and the CXXBaseOrMemberInitializer
+  // was implicitly generated, we shouldn't be zeroing memory.
+  RValue RHS;
+  if (FieldType->isReferenceType()) {
+    RHS = CGF.EmitReferenceBindingToExpr(MemberInit->getInit(),
+                                         /*IsInitializer=*/true);
+    CGF.EmitStoreThroughLValue(RHS, LHS, FieldType);
+  } else if (FieldType->isArrayType() && !MemberInit->getInit()) {
+    CGF.EmitMemSetToZero(LHS.getAddress(), Field->getType());
+  } else if (!CGF.hasAggregateLLVMType(Field->getType())) {
+    RHS = RValue::get(CGF.EmitScalarExpr(MemberInit->getInit(), true));
+    CGF.EmitStoreThroughLValue(RHS, LHS, FieldType);
+  } else if (MemberInit->getInit()->getType()->isAnyComplexType()) {
+    CGF.EmitComplexExprIntoAddr(MemberInit->getInit(), LHS.getAddress(),
+                                LHS.isVolatileQualified());
+  } else {
+    CGF.EmitAggExpr(MemberInit->getInit(), LHS.getAddress(), 
+                    LHS.isVolatileQualified(), false, true);
+    
+    if (!CGF.Exceptions)
+      return;
+
+    const RecordType *RT = FieldType->getAs<RecordType>();
+    if (!RT)
+      return;
+    
+    CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
+    if (!RD->hasTrivialDestructor()) {
+      // FIXME: Is this OK for C++0x delegating constructors?
+      CodeGenFunction::EHCleanupBlock Cleanup(CGF);
+      
+      llvm::Value *ThisPtr = CGF.LoadCXXThis();
+      LValue LHS = CGF.EmitLValueForField(ThisPtr, Field, 0);
+
+      CXXDestructorDecl *DD = RD->getDestructor(CGF.getContext());
+      CGF.EmitCXXDestructorCall(DD, Dtor_Complete, LHS.getAddress());
+    }
+  }
+}
+
+/// Checks whether the given constructor is a valid subject for the
+/// complete-to-base constructor delegation optimization, i.e.
+/// emitting the complete constructor as a simple call to the base
+/// constructor.
+static bool IsConstructorDelegationValid(const CXXConstructorDecl *Ctor) {
+
+  // Currently we disable the optimization for classes with virtual
+  // bases because (1) the addresses of parameter variables need to be
+  // consistent across all initializers but (2) the delegate function
+  // call necessarily creates a second copy of the parameter variable.
+  //
+  // The limiting example (purely theoretical AFAIK):
+  //   struct A { A(int &c) { c++; } };
+  //   struct B : virtual A {
+  //     B(int count) : A(count) { printf("%d\n", count); }
+  //   };
+  // ...although even this example could in principle be emitted as a
+  // delegation since the address of the parameter doesn't escape.
+  if (Ctor->getParent()->getNumVBases()) {
+    // TODO: white-list trivial vbase initializers.  This case wouldn't
+    // be subject to the restrictions below.
+
+    // TODO: white-list cases where:
+    //  - there are no non-reference parameters to the constructor
+    //  - the initializers don't access any non-reference parameters
+    //  - the initializers don't take the address of non-reference
+    //    parameters
+    //  - etc.
+    // If we ever add any of the above cases, remember that:
+    //  - function-try-blocks will always blacklist this optimization
+    //  - we need to perform the constructor prologue and cleanup in
+    //    EmitConstructorBody.
+
+    return false;
+  }
+
+  // We also disable the optimization for variadic functions because
+  // it's impossible to "re-pass" varargs.
+  if (Ctor->getType()->getAs<FunctionProtoType>()->isVariadic())
+    return false;
+
+  return true;
+}
+
+/// EmitConstructorBody - Emits the body of the current constructor.
+void CodeGenFunction::EmitConstructorBody(FunctionArgList &Args) {
+  const CXXConstructorDecl *Ctor = cast<CXXConstructorDecl>(CurGD.getDecl());
+  CXXCtorType CtorType = CurGD.getCtorType();
+
+  // Before we go any further, try the complete->base constructor
+  // delegation optimization.
+  if (CtorType == Ctor_Complete && IsConstructorDelegationValid(Ctor)) {
+    EmitDelegateCXXConstructorCall(Ctor, Ctor_Base, Args);
+    return;
+  }
+
+  Stmt *Body = Ctor->getBody();
+
+  // Enter the function-try-block before the constructor prologue if
+  // applicable.
+  CXXTryStmtInfo TryInfo;
+  bool IsTryBody = (Body && isa<CXXTryStmt>(Body));
+
+  if (IsTryBody)
+    TryInfo = EnterCXXTryStmt(*cast<CXXTryStmt>(Body));
+
+  unsigned CleanupStackSize = CleanupEntries.size();
+
+  // Emit the constructor prologue, i.e. the base and member
+  // initializers.
+  EmitCtorPrologue(Ctor, CtorType);
+
+  // Emit the body of the statement.
+  if (IsTryBody)
+    EmitStmt(cast<CXXTryStmt>(Body)->getTryBlock());
+  else if (Body)
+    EmitStmt(Body);
+  else {
+    assert(Ctor->isImplicit() && "bodyless ctor not implicit");
+    if (!Ctor->isDefaultConstructor()) {
+      assert(Ctor->isCopyConstructor());
+      SynthesizeCXXCopyConstructor(Args);
+    }
+  }
+
+  // Emit any cleanup blocks associated with the member or base
+  // initializers, which includes (along the exceptional path) the
+  // destructors for those members and bases that were fully
+  // constructed.
+  EmitCleanupBlocks(CleanupStackSize);
+
+  if (IsTryBody)
+    ExitCXXTryStmt(*cast<CXXTryStmt>(Body), TryInfo);
+}
+
+/// EmitCtorPrologue - This routine generates necessary code to initialize
+/// base classes and non-static data members belonging to this constructor.
+void CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD,
+                                       CXXCtorType CtorType) {
+  const CXXRecordDecl *ClassDecl = CD->getParent();
+
+  llvm::SmallVector<CXXBaseOrMemberInitializer *, 8> MemberInitializers;
+  
+  for (CXXConstructorDecl::init_const_iterator B = CD->init_begin(),
+       E = CD->init_end();
+       B != E; ++B) {
+    CXXBaseOrMemberInitializer *Member = (*B);
+    
+    assert(LiveTemporaries.empty() &&
+           "Should not have any live temporaries at initializer start!");
+
+    if (Member->isBaseInitializer())
+      EmitBaseInitializer(*this, ClassDecl, Member, CtorType);
+    else
+      MemberInitializers.push_back(Member);
+  }
+
+  InitializeVTablePointers(ClassDecl);
+
+  for (unsigned I = 0, E = MemberInitializers.size(); I != E; ++I) {
+    assert(LiveTemporaries.empty() &&
+           "Should not have any live temporaries at initializer start!");
+    
+    EmitMemberInitializer(*this, ClassDecl, MemberInitializers[I]);
+  }
+}
+
+/// EmitDestructorBody - Emits the body of the current destructor.
+void CodeGenFunction::EmitDestructorBody(FunctionArgList &Args) {
+  const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(CurGD.getDecl());
+  CXXDtorType DtorType = CurGD.getDtorType();
+
+  Stmt *Body = Dtor->getBody();
+
+  // If the body is a function-try-block, enter the try before
+  // anything else --- unless we're in a deleting destructor, in which
+  // case we're just going to call the complete destructor and then
+  // call operator delete() on the way out.
+  CXXTryStmtInfo TryInfo;
+  bool isTryBody = (DtorType != Dtor_Deleting &&
+                    Body && isa<CXXTryStmt>(Body));
+  if (isTryBody)
+    TryInfo = EnterCXXTryStmt(*cast<CXXTryStmt>(Body));
+
+  llvm::BasicBlock *DtorEpilogue = createBasicBlock("dtor.epilogue");
+  PushCleanupBlock(DtorEpilogue);
+
+  bool SkipBody = false; // should get jump-threaded
+
+  // If this is the deleting variant, just invoke the complete
+  // variant, then call the appropriate operator delete() on the way
+  // out.
+  if (DtorType == Dtor_Deleting) {
+    EmitCXXDestructorCall(Dtor, Dtor_Complete, LoadCXXThis());
+    SkipBody = true;
+
+  // If this is the complete variant, just invoke the base variant;
+  // the epilogue will destruct the virtual bases.  But we can't do
+  // this optimization if the body is a function-try-block, because
+  // we'd introduce *two* handler blocks.
+  } else if (!isTryBody && DtorType == Dtor_Complete) {
+    EmitCXXDestructorCall(Dtor, Dtor_Base, LoadCXXThis());
+    SkipBody = true;
+      
+  // Otherwise, we're in the base variant, so we need to ensure the
+  // vtable ptrs are right before emitting the body.
+  } else {
+    InitializeVTablePointers(Dtor->getParent());
+  }
+
+  // Emit the body of the statement.
+  if (SkipBody)
+    (void) 0;
+  else if (isTryBody)
+    EmitStmt(cast<CXXTryStmt>(Body)->getTryBlock());
+  else if (Body)
+    EmitStmt(Body);
+  else {
+    assert(Dtor->isImplicit() && "bodyless dtor not implicit");
+    // nothing to do besides what's in the epilogue
+  }
+
+  // Jump to the cleanup block.
+  CleanupBlockInfo Info = PopCleanupBlock();
+  assert(Info.CleanupBlock == DtorEpilogue && "Block mismatch!");
+  EmitBlock(DtorEpilogue);
+
+  // Emit the destructor epilogue now.  If this is a complete
+  // destructor with a function-try-block, perform the base epilogue
+  // as well.
+  if (isTryBody && DtorType == Dtor_Complete)
+    EmitDtorEpilogue(Dtor, Dtor_Base);
+  EmitDtorEpilogue(Dtor, DtorType);
+
+  // Link up the cleanup information.
+  if (Info.SwitchBlock)
+    EmitBlock(Info.SwitchBlock);
+  if (Info.EndBlock)
+    EmitBlock(Info.EndBlock);
+
+  // Exit the try if applicable.
+  if (isTryBody)
+    ExitCXXTryStmt(*cast<CXXTryStmt>(Body), TryInfo);
+}
+
+/// EmitDtorEpilogue - Emit all code that comes at the end of class's
+/// destructor. This is to call destructors on members and base classes
+/// in reverse order of their construction.
+void CodeGenFunction::EmitDtorEpilogue(const CXXDestructorDecl *DD,
+                                       CXXDtorType DtorType) {
+  assert(!DD->isTrivial() &&
+         "Should not emit dtor epilogue for trivial dtor!");
+
+  const CXXRecordDecl *ClassDecl = DD->getParent();
+
+  // In a deleting destructor, we've already called the complete
+  // destructor as a subroutine, so we just have to delete the
+  // appropriate value.
+  if (DtorType == Dtor_Deleting) {
+    assert(DD->getOperatorDelete() && 
+           "operator delete missing - EmitDtorEpilogue");
+    EmitDeleteCall(DD->getOperatorDelete(), LoadCXXThis(),
+                   getContext().getTagDeclType(ClassDecl));
+    return;
+  }
+
+  // For complete destructors, we've already called the base
+  // destructor (in GenerateBody), so we just need to destruct all the
+  // virtual bases.
+  if (DtorType == Dtor_Complete) {
+    // Handle virtual bases.
+    for (CXXRecordDecl::reverse_base_class_const_iterator I = 
+           ClassDecl->vbases_rbegin(), E = ClassDecl->vbases_rend();
+              I != E; ++I) {
+      const CXXBaseSpecifier &Base = *I;
+      CXXRecordDecl *BaseClassDecl
+        = cast<CXXRecordDecl>(Base.getType()->getAs<RecordType>()->getDecl());
+    
+      // Ignore trivial destructors.
+      if (BaseClassDecl->hasTrivialDestructor())
+        continue;
+      const CXXDestructorDecl *D = BaseClassDecl->getDestructor(getContext());
+      llvm::Value *V = 
+        GetAddressOfDirectBaseInCompleteClass(LoadCXXThis(),
+                                              ClassDecl, BaseClassDecl,
+                                              /*BaseIsVirtual=*/true);
+      EmitCXXDestructorCall(D, Dtor_Base, V);
+    }
+    return;
+  }
+
+  assert(DtorType == Dtor_Base);
+
+  // Collect the fields.
+  llvm::SmallVector<const FieldDecl *, 16> FieldDecls;
+  for (CXXRecordDecl::field_iterator I = ClassDecl->field_begin(),
+       E = ClassDecl->field_end(); I != E; ++I) {
+    const FieldDecl *Field = *I;
+    
+    QualType FieldType = getContext().getCanonicalType(Field->getType());
+    FieldType = getContext().getBaseElementType(FieldType);
+    
+    const RecordType *RT = FieldType->getAs<RecordType>();
+    if (!RT)
+      continue;
+    
+    CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl());
+    if (FieldClassDecl->hasTrivialDestructor())
+        continue;
+    
+    FieldDecls.push_back(Field);
+  }
+  
+  // Now destroy the fields.
+  for (size_t i = FieldDecls.size(); i > 0; --i) {
+    const FieldDecl *Field = FieldDecls[i - 1];
+    
+    QualType FieldType = Field->getType();
+    const ConstantArrayType *Array = 
+      getContext().getAsConstantArrayType(FieldType);
+    if (Array)
+      FieldType = getContext().getBaseElementType(FieldType);
+    
+    const RecordType *RT = FieldType->getAs<RecordType>();
+    CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl());
+
+    llvm::Value *ThisPtr = LoadCXXThis();
+
+    LValue LHS = EmitLValueForField(ThisPtr, Field, 
+                                    // FIXME: Qualifiers?
+                                    /*CVRQualifiers=*/0);
+    if (Array) {
+      const llvm::Type *BasePtr = ConvertType(FieldType);
+      BasePtr = llvm::PointerType::getUnqual(BasePtr);
+      llvm::Value *BaseAddrPtr =
+        Builder.CreateBitCast(LHS.getAddress(), BasePtr);
+      EmitCXXAggrDestructorCall(FieldClassDecl->getDestructor(getContext()),
+                                Array, BaseAddrPtr);
+    } else
+      EmitCXXDestructorCall(FieldClassDecl->getDestructor(getContext()),
+                            Dtor_Complete, LHS.getAddress());
+  }
+
+  // Destroy non-virtual bases.
+  for (CXXRecordDecl::reverse_base_class_const_iterator I = 
+        ClassDecl->bases_rbegin(), E = ClassDecl->bases_rend(); I != E; ++I) {
+    const CXXBaseSpecifier &Base = *I;
+    
+    // Ignore virtual bases.
+    if (Base.isVirtual())
+      continue;
+    
+    CXXRecordDecl *BaseClassDecl
+      = cast<CXXRecordDecl>(Base.getType()->getAs<RecordType>()->getDecl());
+    
+    // Ignore trivial destructors.
+    if (BaseClassDecl->hasTrivialDestructor())
+      continue;
+    const CXXDestructorDecl *D = BaseClassDecl->getDestructor(getContext());
+    
+    llvm::Value *V = OldGetAddressOfBaseClass(LoadCXXThis(),
+                                              ClassDecl, BaseClassDecl);
+    EmitCXXDestructorCall(D, Dtor_Base, V);
+  }
+}
+
+/// EmitCXXAggrConstructorCall - This routine essentially creates a (nested)
+/// for-loop to call the default constructor on individual members of the
+/// array. 
+/// 'D' is the default constructor for elements of the array, 'ArrayTy' is the
+/// array type and 'ArrayPtr' points to the beginning fo the array.
+/// It is assumed that all relevant checks have been made by the caller.
+void
+CodeGenFunction::EmitCXXAggrConstructorCall(const CXXConstructorDecl *D,
+                                          const ConstantArrayType *ArrayTy,
+                                          llvm::Value *ArrayPtr,
+                                          CallExpr::const_arg_iterator ArgBeg,
+                                          CallExpr::const_arg_iterator ArgEnd) {
+
+  const llvm::Type *SizeTy = ConvertType(getContext().getSizeType());
+  llvm::Value * NumElements =
+    llvm::ConstantInt::get(SizeTy, 
+                           getContext().getConstantArrayElementCount(ArrayTy));
+
+  EmitCXXAggrConstructorCall(D, NumElements, ArrayPtr, ArgBeg, ArgEnd);
+}
+
+void
+CodeGenFunction::EmitCXXAggrConstructorCall(const CXXConstructorDecl *D,
+                                          llvm::Value *NumElements,
+                                          llvm::Value *ArrayPtr,
+                                          CallExpr::const_arg_iterator ArgBeg,
+                                          CallExpr::const_arg_iterator ArgEnd) {
+  const llvm::Type *SizeTy = ConvertType(getContext().getSizeType());
+
+  // Create a temporary for the loop index and initialize it with 0.
+  llvm::Value *IndexPtr = CreateTempAlloca(SizeTy, "loop.index");
+  llvm::Value *Zero = llvm::Constant::getNullValue(SizeTy);
+  Builder.CreateStore(Zero, IndexPtr);
+
+  // Start the loop with a block that tests the condition.
+  llvm::BasicBlock *CondBlock = createBasicBlock("for.cond");
+  llvm::BasicBlock *AfterFor = createBasicBlock("for.end");
+
+  EmitBlock(CondBlock);
+
+  llvm::BasicBlock *ForBody = createBasicBlock("for.body");
+
+  // Generate: if (loop-index < number-of-elements fall to the loop body,
+  // otherwise, go to the block after the for-loop.
+  llvm::Value *Counter = Builder.CreateLoad(IndexPtr);
+  llvm::Value *IsLess = Builder.CreateICmpULT(Counter, NumElements, "isless");
+  // If the condition is true, execute the body.
+  Builder.CreateCondBr(IsLess, ForBody, AfterFor);
+
+  EmitBlock(ForBody);
+
+  llvm::BasicBlock *ContinueBlock = createBasicBlock("for.inc");
+  // Inside the loop body, emit the constructor call on the array element.
+  Counter = Builder.CreateLoad(IndexPtr);
+  llvm::Value *Address = Builder.CreateInBoundsGEP(ArrayPtr, Counter, 
+                                                   "arrayidx");
+
+  // C++ [class.temporary]p4: 
+  // There are two contexts in which temporaries are destroyed at a different
+  // point than the end of the full-expression. The first context is when a
+  // default constructor is called to initialize an element of an array. 
+  // If the constructor has one or more default arguments, the destruction of 
+  // every temporary created in a default argument expression is sequenced 
+  // before the construction of the next array element, if any.
+  
+  // Keep track of the current number of live temporaries.
+  {
+    CXXTemporariesCleanupScope Scope(*this);
+
+    EmitCXXConstructorCall(D, Ctor_Complete, Address, ArgBeg, ArgEnd);
+  }
+
+  EmitBlock(ContinueBlock);
+
+  // Emit the increment of the loop counter.
+  llvm::Value *NextVal = llvm::ConstantInt::get(SizeTy, 1);
+  Counter = Builder.CreateLoad(IndexPtr);
+  NextVal = Builder.CreateAdd(Counter, NextVal, "inc");
+  Builder.CreateStore(NextVal, IndexPtr);
+
+  // Finally, branch back up to the condition for the next iteration.
+  EmitBranch(CondBlock);
+
+  // Emit the fall-through block.
+  EmitBlock(AfterFor, true);
+}
+
+/// EmitCXXAggrDestructorCall - calls the default destructor on array
+/// elements in reverse order of construction.
+void
+CodeGenFunction::EmitCXXAggrDestructorCall(const CXXDestructorDecl *D,
+                                           const ArrayType *Array,
+                                           llvm::Value *This) {
+  const ConstantArrayType *CA = dyn_cast<ConstantArrayType>(Array);
+  assert(CA && "Do we support VLA for destruction ?");
+  uint64_t ElementCount = getContext().getConstantArrayElementCount(CA);
+  
+  const llvm::Type *SizeLTy = ConvertType(getContext().getSizeType());
+  llvm::Value* ElementCountPtr = llvm::ConstantInt::get(SizeLTy, ElementCount);
+  EmitCXXAggrDestructorCall(D, ElementCountPtr, This);
+}
+
+/// EmitCXXAggrDestructorCall - calls the default destructor on array
+/// elements in reverse order of construction.
+void
+CodeGenFunction::EmitCXXAggrDestructorCall(const CXXDestructorDecl *D,
+                                           llvm::Value *UpperCount,
+                                           llvm::Value *This) {
+  const llvm::Type *SizeLTy = ConvertType(getContext().getSizeType());
+  llvm::Value *One = llvm::ConstantInt::get(SizeLTy, 1);
+  
+  // Create a temporary for the loop index and initialize it with count of
+  // array elements.
+  llvm::Value *IndexPtr = CreateTempAlloca(SizeLTy, "loop.index");
+
+  // Store the number of elements in the index pointer.
+  Builder.CreateStore(UpperCount, IndexPtr);
+
+  // Start the loop with a block that tests the condition.
+  llvm::BasicBlock *CondBlock = createBasicBlock("for.cond");
+  llvm::BasicBlock *AfterFor = createBasicBlock("for.end");
+
+  EmitBlock(CondBlock);
+
+  llvm::BasicBlock *ForBody = createBasicBlock("for.body");
+
+  // Generate: if (loop-index != 0 fall to the loop body,
+  // otherwise, go to the block after the for-loop.
+  llvm::Value* zeroConstant =
+    llvm::Constant::getNullValue(SizeLTy);
+  llvm::Value *Counter = Builder.CreateLoad(IndexPtr);
+  llvm::Value *IsNE = Builder.CreateICmpNE(Counter, zeroConstant,
+                                            "isne");
+  // If the condition is true, execute the body.
+  Builder.CreateCondBr(IsNE, ForBody, AfterFor);
+
+  EmitBlock(ForBody);
+
+  llvm::BasicBlock *ContinueBlock = createBasicBlock("for.inc");
+  // Inside the loop body, emit the constructor call on the array element.
+  Counter = Builder.CreateLoad(IndexPtr);
+  Counter = Builder.CreateSub(Counter, One);
+  llvm::Value *Address = Builder.CreateInBoundsGEP(This, Counter, "arrayidx");
+  EmitCXXDestructorCall(D, Dtor_Complete, Address);
+
+  EmitBlock(ContinueBlock);
+
+  // Emit the decrement of the loop counter.
+  Counter = Builder.CreateLoad(IndexPtr);
+  Counter = Builder.CreateSub(Counter, One, "dec");
+  Builder.CreateStore(Counter, IndexPtr);
+
+  // Finally, branch back up to the condition for the next iteration.
+  EmitBranch(CondBlock);
+
+  // Emit the fall-through block.
+  EmitBlock(AfterFor, true);
+}
+
+/// GenerateCXXAggrDestructorHelper - Generates a helper function which when
+/// invoked, calls the default destructor on array elements in reverse order of
+/// construction.
+llvm::Constant * 
+CodeGenFunction::GenerateCXXAggrDestructorHelper(const CXXDestructorDecl *D,
+                                                 const ArrayType *Array,
+                                                 llvm::Value *This) {
+  FunctionArgList Args;
+  ImplicitParamDecl *Dst =
+    ImplicitParamDecl::Create(getContext(), 0,
+                              SourceLocation(), 0,
+                              getContext().getPointerType(getContext().VoidTy));
+  Args.push_back(std::make_pair(Dst, Dst->getType()));
+  
+  llvm::SmallString<16> Name;
+  llvm::raw_svector_ostream(Name) << "__tcf_" << (++UniqueAggrDestructorCount);
+  QualType R = getContext().VoidTy;
+  const CGFunctionInfo &FI
+      = CGM.getTypes().getFunctionInfo(R, Args, FunctionType::ExtInfo());
+  const llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FI, false);
+  llvm::Function *Fn =
+    llvm::Function::Create(FTy, llvm::GlobalValue::InternalLinkage,
+                           Name.str(),
+                           &CGM.getModule());
+  IdentifierInfo *II = &CGM.getContext().Idents.get(Name.str());
+  FunctionDecl *FD = FunctionDecl::Create(getContext(),
+                                          getContext().getTranslationUnitDecl(),
+                                          SourceLocation(), II, R, 0,
+                                          FunctionDecl::Static,
+                                          FunctionDecl::None,
+                                          false, true);
+  StartFunction(FD, R, Fn, Args, SourceLocation());
+  QualType BaseElementTy = getContext().getBaseElementType(Array);
+  const llvm::Type *BasePtr = ConvertType(BaseElementTy);
+  BasePtr = llvm::PointerType::getUnqual(BasePtr);
+  llvm::Value *BaseAddrPtr = Builder.CreateBitCast(This, BasePtr);
+  EmitCXXAggrDestructorCall(D, Array, BaseAddrPtr);
+  FinishFunction();
+  llvm::Type *Ptr8Ty = llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext),
+                                              0);
+  llvm::Constant *m = llvm::ConstantExpr::getBitCast(Fn, Ptr8Ty);
+  return m;
+}
+
+
+void
+CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D,
+                                        CXXCtorType Type,
+                                        llvm::Value *This,
+                                        CallExpr::const_arg_iterator ArgBeg,
+                                        CallExpr::const_arg_iterator ArgEnd) {
+  if (D->isTrivial()) {
+    if (ArgBeg == ArgEnd) {
+      // Trivial default constructor, no codegen required.
+      assert(D->isDefaultConstructor() &&
+             "trivial 0-arg ctor not a default ctor");
+      return;
+    }
+
+    assert(ArgBeg + 1 == ArgEnd && "unexpected argcount for trivial ctor");
+    assert(D->isCopyConstructor() && "trivial 1-arg ctor not a copy ctor");
+
+    const Expr *E = (*ArgBeg);
+    QualType Ty = E->getType();
+    llvm::Value *Src = EmitLValue(E).getAddress();
+    EmitAggregateCopy(This, Src, Ty);
+    return;
+  }
+
+  llvm::Value *VTT = GetVTTParameter(*this, GlobalDecl(D, Type));
+  llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(D, Type);
+
+  EmitCXXMemberCall(D, Callee, ReturnValueSlot(), This, VTT, ArgBeg, ArgEnd);
+}
+
+void
+CodeGenFunction::EmitDelegateCXXConstructorCall(const CXXConstructorDecl *Ctor,
+                                                CXXCtorType CtorType,
+                                                const FunctionArgList &Args) {
+  CallArgList DelegateArgs;
+
+  FunctionArgList::const_iterator I = Args.begin(), E = Args.end();
+  assert(I != E && "no parameters to constructor");
+
+  // this
+  DelegateArgs.push_back(std::make_pair(RValue::get(LoadCXXThis()),
+                                        I->second));
+  ++I;
+
+  // vtt
+  if (llvm::Value *VTT = GetVTTParameter(*this, GlobalDecl(Ctor, CtorType))) {
+    QualType VoidPP = getContext().getPointerType(getContext().VoidPtrTy);
+    DelegateArgs.push_back(std::make_pair(RValue::get(VTT), VoidPP));
+
+    if (CodeGenVTables::needsVTTParameter(CurGD)) {
+      assert(I != E && "cannot skip vtt parameter, already done with args");
+      assert(I->second == VoidPP && "skipping parameter not of vtt type");
+      ++I;
+    }
+  }
+
+  // Explicit arguments.
+  for (; I != E; ++I) {
+    
+    const VarDecl *Param = I->first;
+    QualType ArgType = Param->getType(); // because we're passing it to itself
+
+    // StartFunction converted the ABI-lowered parameter(s) into a
+    // local alloca.  We need to turn that into an r-value suitable
+    // for EmitCall.
+    llvm::Value *Local = GetAddrOfLocalVar(Param);
+    RValue Arg;
+ 
+    // For the most part, we just need to load the alloca, except:
+    // 1) aggregate r-values are actually pointers to temporaries, and
+    // 2) references to aggregates are pointers directly to the aggregate.
+    // I don't know why references to non-aggregates are different here.
+    if (ArgType->isReferenceType()) {
+      const ReferenceType *RefType = ArgType->getAs<ReferenceType>();
+      if (hasAggregateLLVMType(RefType->getPointeeType()))
+        Arg = RValue::getAggregate(Local);
+      else
+        // Locals which are references to scalars are represented
+        // with allocas holding the pointer.
+        Arg = RValue::get(Builder.CreateLoad(Local));
+    } else {
+      if (hasAggregateLLVMType(ArgType))
+        Arg = RValue::getAggregate(Local);
+      else
+        Arg = RValue::get(EmitLoadOfScalar(Local, false, ArgType));
+    }
+
+    DelegateArgs.push_back(std::make_pair(Arg, ArgType));
+  }
+
+  EmitCall(CGM.getTypes().getFunctionInfo(Ctor, CtorType),
+           CGM.GetAddrOfCXXConstructor(Ctor, CtorType), 
+           ReturnValueSlot(), DelegateArgs, Ctor);
+}
+
+void CodeGenFunction::EmitCXXDestructorCall(const CXXDestructorDecl *DD,
+                                            CXXDtorType Type,
+                                            llvm::Value *This) {
+  llvm::Value *VTT = GetVTTParameter(*this, GlobalDecl(DD, Type));
+  llvm::Value *Callee = CGM.GetAddrOfCXXDestructor(DD, Type);
+  
+  EmitCXXMemberCall(DD, Callee, ReturnValueSlot(), This, VTT, 0, 0);
+}
+
+llvm::Value *
+CodeGenFunction::GetVirtualBaseClassOffset(llvm::Value *This,
+                                           const CXXRecordDecl *ClassDecl,
+                                           const CXXRecordDecl *BaseClassDecl) {
+  const llvm::Type *Int8PtrTy = 
+    llvm::Type::getInt8Ty(VMContext)->getPointerTo();
+
+  llvm::Value *VTablePtr = Builder.CreateBitCast(This, 
+                                                 Int8PtrTy->getPointerTo());
+  VTablePtr = Builder.CreateLoad(VTablePtr, "vtable");
+
+  int64_t VBaseOffsetOffset = 
+    CGM.getVTables().getVirtualBaseOffsetOffset(ClassDecl, BaseClassDecl);
+  
+  llvm::Value *VBaseOffsetPtr = 
+    Builder.CreateConstGEP1_64(VTablePtr, VBaseOffsetOffset, "vbase.offset.ptr");
+  const llvm::Type *PtrDiffTy = 
+    ConvertType(getContext().getPointerDiffType());
+  
+  VBaseOffsetPtr = Builder.CreateBitCast(VBaseOffsetPtr, 
+                                         PtrDiffTy->getPointerTo());
+                                         
+  llvm::Value *VBaseOffset = Builder.CreateLoad(VBaseOffsetPtr, "vbase.offset");
+  
+  return VBaseOffset;
+}
+
+void
+CodeGenFunction::InitializeVTablePointer(BaseSubobject Base, 
+                                         const CXXRecordDecl *NearestVBase,
+                                         llvm::Constant *VTable,
+                                         const CXXRecordDecl *VTableClass) {
+  const CXXRecordDecl *RD = Base.getBase();
+
+  // Compute the address point.
+  llvm::Value *VTableAddressPoint;
+
+  // Check if we need to use a vtable from the VTT.
+  if (CodeGenVTables::needsVTTParameter(CurGD) &&
+      (RD->getNumVBases() || NearestVBase)) {
+    // Get the secondary vpointer index.
+    uint64_t VirtualPointerIndex = 
+     CGM.getVTables().getSecondaryVirtualPointerIndex(VTableClass, Base);
+    
+    /// Load the VTT.
+    llvm::Value *VTT = LoadCXXVTT();
+    if (VirtualPointerIndex)
+      VTT = Builder.CreateConstInBoundsGEP1_64(VTT, VirtualPointerIndex);
+
+    // And load the address point from the VTT.
+    VTableAddressPoint = Builder.CreateLoad(VTT);
+  } else {
+    uint64_t AddressPoint = CGM.getVTables().getAddressPoint(Base, VTableClass);
+    VTableAddressPoint =
+      Builder.CreateConstInBoundsGEP2_64(VTable, 0, AddressPoint);
+  }
+
+  // Compute where to store the address point.
+  llvm::Value *VTableField;
+  
+  if (CodeGenVTables::needsVTTParameter(CurGD) && NearestVBase) {
+    // We need to use the virtual base offset offset because the virtual base
+    // might have a different offset in the most derived class.
+    VTableField = OldGetAddressOfBaseClass(LoadCXXThis(), VTableClass, RD);
+  } else {
+    const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
+
+    VTableField = Builder.CreateBitCast(LoadCXXThis(), Int8PtrTy);
+    VTableField = 
+      Builder.CreateConstInBoundsGEP1_64(VTableField, Base.getBaseOffset() / 8);  
+  }
+
+  // Finally, store the address point.
+  const llvm::Type *AddressPointPtrTy =
+    VTableAddressPoint->getType()->getPointerTo();
+  VTableField = Builder.CreateBitCast(VTableField, AddressPointPtrTy);
+  Builder.CreateStore(VTableAddressPoint, VTableField);
+}
+
+void
+CodeGenFunction::InitializeVTablePointers(BaseSubobject Base, 
+                                          const CXXRecordDecl *NearestVBase,
+                                          bool BaseIsNonVirtualPrimaryBase,
+                                          llvm::Constant *VTable,
+                                          const CXXRecordDecl *VTableClass,
+                                          VisitedVirtualBasesSetTy& VBases) {
+  // If this base is a non-virtual primary base the address point has already
+  // been set.
+  if (!BaseIsNonVirtualPrimaryBase) {
+    // Initialize the vtable pointer for this base.
+    InitializeVTablePointer(Base, NearestVBase, VTable, VTableClass);
+  }
+  
+  const CXXRecordDecl *RD = Base.getBase();
+
+  // Traverse bases.
+  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 
+       E = RD->bases_end(); I != E; ++I) {
+    CXXRecordDecl *BaseDecl
+      = cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+
+    // Ignore classes without a vtable.
+    if (!BaseDecl->isDynamicClass())
+      continue;
+
+    uint64_t BaseOffset;
+    bool BaseDeclIsNonVirtualPrimaryBase;
+
+    if (I->isVirtual()) {
+      // Check if we've visited this virtual base before.
+      if (!VBases.insert(BaseDecl))
+        continue;
+
+      const ASTRecordLayout &Layout = 
+        getContext().getASTRecordLayout(VTableClass);
+
+      BaseOffset = Layout.getVBaseClassOffset(BaseDecl);
+      BaseDeclIsNonVirtualPrimaryBase = false;
+    } else {
+      const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD);
+
+      BaseOffset = Base.getBaseOffset() + Layout.getBaseClassOffset(BaseDecl);
+      BaseDeclIsNonVirtualPrimaryBase = Layout.getPrimaryBase() == BaseDecl;
+    }
+    
+    InitializeVTablePointers(BaseSubobject(BaseDecl, BaseOffset), 
+                             I->isVirtual() ? BaseDecl : NearestVBase,
+                             BaseDeclIsNonVirtualPrimaryBase, 
+                             VTable, VTableClass, VBases);
+  }
+}
+
+void CodeGenFunction::InitializeVTablePointers(const CXXRecordDecl *RD) {
+  // Ignore classes without a vtable.
+  if (!RD->isDynamicClass())
+    return;
+
+  // Get the VTable.
+  llvm::Constant *VTable = CGM.getVTables().GetAddrOfVTable(RD);
+
+  // Initialize the vtable pointers for this class and all of its bases.
+  VisitedVirtualBasesSetTy VBases;
+  InitializeVTablePointers(BaseSubobject(RD, 0), /*NearestVBase=*/0, 
+                           /*BaseIsNonVirtualPrimaryBase=*/false, 
+                           VTable, RD, VBases);
+}
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp
new file mode 100644
index 0000000..4991c0f
--- /dev/null
+++ b/lib/CodeGen/CGDebugInfo.cpp
@@ -0,0 +1,1665 @@
+//===--- CGDebugInfo.cpp - Emit Debug Information for a Module ------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This coordinates the debug information generation while generating code.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CGDebugInfo.h"
+#include "CodeGenFunction.h"
+#include "CodeGenModule.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/RecordLayout.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/Version.h"
+#include "clang/CodeGen/CodeGenOptions.h"
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/Instructions.h"
+#include "llvm/Intrinsics.h"
+#include "llvm/Module.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Dwarf.h"
+#include "llvm/System/Path.h"
+#include "llvm/Target/TargetMachine.h"
+using namespace clang;
+using namespace clang::CodeGen;
+
+CGDebugInfo::CGDebugInfo(CodeGenModule &CGM)
+  : CGM(CGM), DebugFactory(CGM.getModule()),
+    FwdDeclCount(0), BlockLiteralGenericSet(false) {
+  CreateCompileUnit();
+}
+
+CGDebugInfo::~CGDebugInfo() {
+  assert(RegionStack.empty() && "Region stack mismatch, stack not empty!");
+}
+
+void CGDebugInfo::setLocation(SourceLocation Loc) {
+  if (Loc.isValid())
+    CurLoc = CGM.getContext().getSourceManager().getInstantiationLoc(Loc);
+}
+
+/// getContextDescriptor - Get context info for the decl.
+llvm::DIDescriptor CGDebugInfo::getContextDescriptor(const Decl *Context,
+                                              llvm::DIDescriptor &CompileUnit) {
+  if (!Context)
+    return CompileUnit;
+
+  llvm::DenseMap<const Decl *, llvm::WeakVH>::iterator
+    I = RegionMap.find(Context);
+  if (I != RegionMap.end())
+    return llvm::DIDescriptor(dyn_cast_or_null<llvm::MDNode>(I->second));
+
+  // Check namespace.
+  if (const NamespaceDecl *NSDecl = dyn_cast<NamespaceDecl>(Context))
+    return llvm::DIDescriptor(getOrCreateNameSpace(NSDecl, CompileUnit));
+  
+  return CompileUnit;
+}
+
+/// getFunctionName - Get function name for the given FunctionDecl. If the
+/// name is constructred on demand (e.g. C++ destructor) then the name
+/// is stored on the side.
+llvm::StringRef CGDebugInfo::getFunctionName(const FunctionDecl *FD) {
+  assert (FD && "Invalid FunctionDecl!");
+  IdentifierInfo *FII = FD->getIdentifier();
+  if (FII)
+    return FII->getName();
+
+  // Otherwise construct human readable name for debug info.
+  std::string NS = FD->getNameAsString();
+
+  // Copy this name on the side and use its reference.
+  char *StrPtr = DebugInfoNames.Allocate<char>(NS.length());
+  memcpy(StrPtr, NS.data(), NS.length());
+  return llvm::StringRef(StrPtr, NS.length());
+}
+
+/// getOrCreateFile - Get the file debug info descriptor for the input location.
+llvm::DIFile CGDebugInfo::getOrCreateFile(SourceLocation Loc) {
+  if (!Loc.isValid())
+    // If Location is not valid then use main input file.
+    return DebugFactory.CreateFile(TheCU.getFilename(), TheCU.getDirectory(),
+                                   TheCU);
+  SourceManager &SM = CGM.getContext().getSourceManager();
+  PresumedLoc PLoc = SM.getPresumedLoc(Loc);
+
+  // Cache the results.
+  const char *fname = PLoc.getFilename();
+  llvm::DenseMap<const char *, llvm::WeakVH>::iterator it =
+    DIFileCache.find(fname);
+
+  if (it != DIFileCache.end()) {
+    // Verify that the information still exists.
+    if (&*it->second)
+      return llvm::DIFile(cast<llvm::MDNode>(it->second));
+  }
+
+  // FIXME: We shouldn't even need to call 'makeAbsolute()' in the cases
+  // where we can consult the FileEntry.
+  llvm::sys::Path AbsFileName(PLoc.getFilename());
+  AbsFileName.makeAbsolute();
+
+  llvm::DIFile F = DebugFactory.CreateFile(AbsFileName.getLast(),
+                                           AbsFileName.getDirname(), TheCU);
+
+  DIFileCache[fname] = F.getNode();
+  return F;
+
+}
+/// CreateCompileUnit - Create new compile unit.
+void CGDebugInfo::CreateCompileUnit() {
+
+  // Get absolute path name.
+  SourceManager &SM = CGM.getContext().getSourceManager();
+  std::string MainFileName = CGM.getCodeGenOpts().MainFileName;
+  if (MainFileName.empty())
+    MainFileName = "<unknown>";
+
+  llvm::sys::Path AbsFileName(MainFileName);
+  AbsFileName.makeAbsolute();
+
+  // The main file name provided via the "-main-file-name" option contains just
+  // the file name itself with no path information. This file name may have had
+  // a relative path, so we look into the actual file entry for the main
+  // file to determine the real absolute path for the file.
+  std::string MainFileDir;
+  if (const FileEntry *MainFile = SM.getFileEntryForID(SM.getMainFileID()))
+    MainFileDir = MainFile->getDir()->getName();
+  else
+    MainFileDir = AbsFileName.getDirname();
+
+  unsigned LangTag;
+  const LangOptions &LO = CGM.getLangOptions();
+  if (LO.CPlusPlus) {
+    if (LO.ObjC1)
+      LangTag = llvm::dwarf::DW_LANG_ObjC_plus_plus;
+    else
+      LangTag = llvm::dwarf::DW_LANG_C_plus_plus;
+  } else if (LO.ObjC1) {
+    LangTag = llvm::dwarf::DW_LANG_ObjC;
+  } else if (LO.C99) {
+    LangTag = llvm::dwarf::DW_LANG_C99;
+  } else {
+    LangTag = llvm::dwarf::DW_LANG_C89;
+  }
+
+  const char *Producer =
+#ifdef CLANG_VENDOR
+    CLANG_VENDOR
+#endif
+    "clang " CLANG_VERSION_STRING;
+
+  // Figure out which version of the ObjC runtime we have.
+  unsigned RuntimeVers = 0;
+  if (LO.ObjC1)
+    RuntimeVers = LO.ObjCNonFragileABI ? 2 : 1;
+
+  // Create new compile unit.
+  TheCU = DebugFactory.CreateCompileUnit(
+    LangTag, AbsFileName.getLast(), MainFileDir, Producer, true,
+    LO.Optimize, CGM.getCodeGenOpts().DwarfDebugFlags, RuntimeVers);
+}
+
+/// CreateType - Get the Basic type from the cache or create a new
+/// one if necessary.
+llvm::DIType CGDebugInfo::CreateType(const BuiltinType *BT,
+                                     llvm::DIFile Unit) {
+  unsigned Encoding = 0;
+  switch (BT->getKind()) {
+  default:
+  case BuiltinType::Void:
+    return llvm::DIType();
+  case BuiltinType::UChar:
+  case BuiltinType::Char_U: Encoding = llvm::dwarf::DW_ATE_unsigned_char; break;
+  case BuiltinType::Char_S:
+  case BuiltinType::SChar: Encoding = llvm::dwarf::DW_ATE_signed_char; break;
+  case BuiltinType::UShort:
+  case BuiltinType::UInt:
+  case BuiltinType::ULong:
+  case BuiltinType::ULongLong: Encoding = llvm::dwarf::DW_ATE_unsigned; break;
+  case BuiltinType::Short:
+  case BuiltinType::Int:
+  case BuiltinType::Long:
+  case BuiltinType::LongLong:  Encoding = llvm::dwarf::DW_ATE_signed; break;
+  case BuiltinType::Bool:      Encoding = llvm::dwarf::DW_ATE_boolean; break;
+  case BuiltinType::Float:
+  case BuiltinType::LongDouble:
+  case BuiltinType::Double:    Encoding = llvm::dwarf::DW_ATE_float; break;
+  }
+  // Bit size, align and offset of the type.
+  uint64_t Size = CGM.getContext().getTypeSize(BT);
+  uint64_t Align = CGM.getContext().getTypeAlign(BT);
+  uint64_t Offset = 0;
+
+  llvm::DIType DbgTy = 
+    DebugFactory.CreateBasicType(Unit,
+                                 BT->getName(CGM.getContext().getLangOptions()),
+                                 Unit, 0, Size, Align,
+                                 Offset, /*flags*/ 0, Encoding);
+  return DbgTy;
+}
+
+llvm::DIType CGDebugInfo::CreateType(const ComplexType *Ty,
+                                     llvm::DIFile Unit) {
+  // Bit size, align and offset of the type.
+  unsigned Encoding = llvm::dwarf::DW_ATE_complex_float;
+  if (Ty->isComplexIntegerType())
+    Encoding = llvm::dwarf::DW_ATE_lo_user;
+
+  uint64_t Size = CGM.getContext().getTypeSize(Ty);
+  uint64_t Align = CGM.getContext().getTypeAlign(Ty);
+  uint64_t Offset = 0;
+
+  llvm::DIType DbgTy = 
+    DebugFactory.CreateBasicType(Unit, "complex",
+                                 Unit, 0, Size, Align,
+                                 Offset, /*flags*/ 0, Encoding);
+  return DbgTy;
+}
+
+/// CreateCVRType - Get the qualified type from the cache or create
+/// a new one if necessary.
+llvm::DIType CGDebugInfo::CreateQualifiedType(QualType Ty, llvm::DIFile Unit) {
+  QualifierCollector Qc;
+  const Type *T = Qc.strip(Ty);
+
+  // Ignore these qualifiers for now.
+  Qc.removeObjCGCAttr();
+  Qc.removeAddressSpace();
+
+  // We will create one Derived type for one qualifier and recurse to handle any
+  // additional ones.
+  unsigned Tag;
+  if (Qc.hasConst()) {
+    Tag = llvm::dwarf::DW_TAG_const_type;
+    Qc.removeConst();
+  } else if (Qc.hasVolatile()) {
+    Tag = llvm::dwarf::DW_TAG_volatile_type;
+    Qc.removeVolatile();
+  } else if (Qc.hasRestrict()) {
+    Tag = llvm::dwarf::DW_TAG_restrict_type;
+    Qc.removeRestrict();
+  } else {
+    assert(Qc.empty() && "Unknown type qualifier for debug info");
+    return getOrCreateType(QualType(T, 0), Unit);
+  }
+
+  llvm::DIType FromTy = getOrCreateType(Qc.apply(T), Unit);
+
+  // No need to fill in the Name, Line, Size, Alignment, Offset in case of
+  // CVR derived types.
+  llvm::DIType DbgTy =
+    DebugFactory.CreateDerivedType(Tag, Unit, "", Unit,
+                                   0, 0, 0, 0, 0, FromTy);
+  return DbgTy;
+}
+
+llvm::DIType CGDebugInfo::CreateType(const ObjCObjectPointerType *Ty,
+                                     llvm::DIFile Unit) {
+  llvm::DIType DbgTy =
+    CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty, 
+                          Ty->getPointeeType(), Unit);
+  return DbgTy;
+}
+
+llvm::DIType CGDebugInfo::CreateType(const PointerType *Ty,
+                                     llvm::DIFile Unit) {
+  return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty, 
+                               Ty->getPointeeType(), Unit);
+}
+
+llvm::DIType CGDebugInfo::CreatePointerLikeType(unsigned Tag,
+                                                const Type *Ty, 
+                                                QualType PointeeTy,
+                                                llvm::DIFile Unit) {
+  llvm::DIType EltTy = getOrCreateType(PointeeTy, Unit);
+
+  // Bit size, align and offset of the type.
+  
+  // Size is always the size of a pointer. We can't use getTypeSize here
+  // because that does not return the correct value for references.
+  uint64_t Size = 
+    CGM.getContext().Target.getPointerWidth(PointeeTy.getAddressSpace());
+  uint64_t Align = CGM.getContext().getTypeAlign(Ty);
+
+  return
+    DebugFactory.CreateDerivedType(Tag, Unit, "", Unit,
+                                   0, Size, Align, 0, 0, EltTy);
+  
+}
+
+llvm::DIType CGDebugInfo::CreateType(const BlockPointerType *Ty,
+                                     llvm::DIFile Unit) {
+  if (BlockLiteralGenericSet)
+    return BlockLiteralGeneric;
+
+  unsigned Tag = llvm::dwarf::DW_TAG_structure_type;
+
+  llvm::SmallVector<llvm::DIDescriptor, 5> EltTys;
+
+  llvm::DIType FieldTy;
+
+  QualType FType;
+  uint64_t FieldSize, FieldOffset;
+  unsigned FieldAlign;
+
+  llvm::DIArray Elements;
+  llvm::DIType EltTy, DescTy;
+
+  FieldOffset = 0;
+  FType = CGM.getContext().UnsignedLongTy;
+  EltTys.push_back(CreateMemberType(Unit, FType, "reserved", &FieldOffset));
+  EltTys.push_back(CreateMemberType(Unit, FType, "Size", &FieldOffset));
+
+  Elements = DebugFactory.GetOrCreateArray(EltTys.data(), EltTys.size());
+  EltTys.clear();
+
+  unsigned Flags = llvm::DIType::FlagAppleBlock;
+
+  EltTy = DebugFactory.CreateCompositeType(Tag, Unit, "__block_descriptor",
+                                           Unit, 0, FieldOffset, 0, 0, Flags,
+                                           llvm::DIType(), Elements);
+
+  // Bit size, align and offset of the type.
+  uint64_t Size = CGM.getContext().getTypeSize(Ty);
+  uint64_t Align = CGM.getContext().getTypeAlign(Ty);
+
+  DescTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_pointer_type,
+                                          Unit, "", Unit,
+                                          0, Size, Align, 0, 0, EltTy);
+
+  FieldOffset = 0;
+  FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
+  EltTys.push_back(CreateMemberType(Unit, FType, "__isa", &FieldOffset));
+  FType = CGM.getContext().IntTy;
+  EltTys.push_back(CreateMemberType(Unit, FType, "__flags", &FieldOffset));
+  EltTys.push_back(CreateMemberType(Unit, FType, "__reserved", &FieldOffset));
+  FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
+  EltTys.push_back(CreateMemberType(Unit, FType, "__FuncPtr", &FieldOffset));
+
+  FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
+  FieldTy = DescTy;
+  FieldSize = CGM.getContext().getTypeSize(Ty);
+  FieldAlign = CGM.getContext().getTypeAlign(Ty);
+  FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
+                                           "__descriptor", Unit,
+                                           0, FieldSize, FieldAlign,
+                                           FieldOffset, 0, FieldTy);
+  EltTys.push_back(FieldTy);
+
+  FieldOffset += FieldSize;
+  Elements = DebugFactory.GetOrCreateArray(EltTys.data(), EltTys.size());
+
+  EltTy = DebugFactory.CreateCompositeType(Tag, Unit, "__block_literal_generic",
+                                           Unit, 0, FieldOffset, 0, 0, Flags,
+                                           llvm::DIType(), Elements);
+
+  BlockLiteralGenericSet = true;
+  BlockLiteralGeneric
+    = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_pointer_type, Unit,
+                                     "", Unit,
+                                     0, Size, Align, 0, 0, EltTy);
+  return BlockLiteralGeneric;
+}
+
+llvm::DIType CGDebugInfo::CreateType(const TypedefType *Ty,
+                                     llvm::DIFile Unit) {
+  // Typedefs are derived from some other type.  If we have a typedef of a
+  // typedef, make sure to emit the whole chain.
+  llvm::DIType Src = getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit);
+
+  // We don't set size information, but do specify where the typedef was
+  // declared.
+  SourceManager &SM = CGM.getContext().getSourceManager();
+  PresumedLoc PLoc = SM.getPresumedLoc(Ty->getDecl()->getLocation());
+  unsigned Line = PLoc.isInvalid() ? 0 : PLoc.getLine();
+
+  llvm::DIDescriptor TyContext 
+    = getContextDescriptor(dyn_cast<Decl>(Ty->getDecl()->getDeclContext()),
+                           Unit);
+  llvm::DIType DbgTy = 
+    DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_typedef, 
+                                   TyContext,
+                                   Ty->getDecl()->getName(), Unit,
+                                   Line, 0, 0, 0, 0, Src);
+  return DbgTy;
+}
+
+llvm::DIType CGDebugInfo::CreateType(const FunctionType *Ty,
+                                     llvm::DIFile Unit) {
+  llvm::SmallVector<llvm::DIDescriptor, 16> EltTys;
+
+  // Add the result type at least.
+  EltTys.push_back(getOrCreateType(Ty->getResultType(), Unit));
+
+  // Set up remainder of arguments if there is a prototype.
+  // FIXME: IF NOT, HOW IS THIS REPRESENTED?  llvm-gcc doesn't represent '...'!
+  if (const FunctionProtoType *FTP = dyn_cast<FunctionProtoType>(Ty)) {
+    for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i)
+      EltTys.push_back(getOrCreateType(FTP->getArgType(i), Unit));
+  } else {
+    // FIXME: Handle () case in C.  llvm-gcc doesn't do it either.
+  }
+
+  llvm::DIArray EltTypeArray =
+    DebugFactory.GetOrCreateArray(EltTys.data(), EltTys.size());
+
+  llvm::DIType DbgTy =
+    DebugFactory.CreateCompositeType(llvm::dwarf::DW_TAG_subroutine_type,
+                                     Unit, "", Unit,
+                                     0, 0, 0, 0, 0,
+                                     llvm::DIType(), EltTypeArray);
+  return DbgTy;
+}
+
+/// CollectRecordFields - A helper function to collect debug info for
+/// record fields. This is used while creating debug info entry for a Record.
+void CGDebugInfo::
+CollectRecordFields(const RecordDecl *RD, llvm::DIFile Unit,
+                    llvm::SmallVectorImpl<llvm::DIDescriptor> &EltTys) {
+  unsigned FieldNo = 0;
+  SourceManager &SM = CGM.getContext().getSourceManager();
+  const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
+  for (RecordDecl::field_iterator I = RD->field_begin(),
+                                  E = RD->field_end();
+       I != E; ++I, ++FieldNo) {
+    FieldDecl *Field = *I;
+    llvm::DIType FieldTy = getOrCreateType(Field->getType(), Unit);
+
+    llvm::StringRef FieldName = Field->getName();
+
+    // Ignore unnamed fields. Do not ignore unnamed records.
+    if (FieldName.empty() && !isa<RecordType>(Field->getType()))
+      continue;
+
+    // Get the location for the field.
+    SourceLocation FieldDefLoc = Field->getLocation();
+    PresumedLoc PLoc = SM.getPresumedLoc(FieldDefLoc);
+    llvm::DIFile FieldDefUnit;
+    unsigned FieldLine = 0;
+
+    if (!PLoc.isInvalid()) {
+      FieldDefUnit = getOrCreateFile(FieldDefLoc);
+      FieldLine = PLoc.getLine();
+    }
+
+    QualType FType = Field->getType();
+    uint64_t FieldSize = 0;
+    unsigned FieldAlign = 0;
+    if (!FType->isIncompleteArrayType()) {
+
+      // Bit size, align and offset of the type.
+      FieldSize = CGM.getContext().getTypeSize(FType);
+      Expr *BitWidth = Field->getBitWidth();
+      if (BitWidth)
+        FieldSize = BitWidth->EvaluateAsInt(CGM.getContext()).getZExtValue();
+
+      FieldAlign =  CGM.getContext().getTypeAlign(FType);
+    }
+
+    uint64_t FieldOffset = RL.getFieldOffset(FieldNo);
+
+    unsigned Flags = 0;
+    AccessSpecifier Access = I->getAccess();
+    if (Access == clang::AS_private)
+      Flags |= llvm::DIType::FlagPrivate;
+    else if (Access == clang::AS_protected)
+      Flags |= llvm::DIType::FlagProtected;
+
+    // Create a DW_TAG_member node to remember the offset of this field in the
+    // struct.  FIXME: This is an absolutely insane way to capture this
+    // information.  When we gut debug info, this should be fixed.
+    FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
+                                             FieldName, FieldDefUnit,
+                                             FieldLine, FieldSize, FieldAlign,
+                                             FieldOffset, Flags, FieldTy);
+    EltTys.push_back(FieldTy);
+  }
+}
+
+/// getOrCreateMethodType - CXXMethodDecl's type is a FunctionType. This
+/// function type is not updated to include implicit "this" pointer. Use this
+/// routine to get a method type which includes "this" pointer.
+llvm::DIType
+CGDebugInfo::getOrCreateMethodType(const CXXMethodDecl *Method,
+                                   llvm::DIFile Unit) {
+  llvm::DIType FnTy = getOrCreateType(Method->getType(), Unit);
+  
+  // Static methods do not need "this" pointer argument.
+  if (Method->isStatic())
+    return FnTy;
+
+  // Add "this" pointer.
+
+  llvm::DIArray Args = llvm::DICompositeType(FnTy.getNode()).getTypeArray();
+  assert (Args.getNumElements() && "Invalid number of arguments!");
+
+  llvm::SmallVector<llvm::DIDescriptor, 16> Elts;
+
+  // First element is always return type. For 'void' functions it is NULL.
+  Elts.push_back(Args.getElement(0));
+
+  // "this" pointer is always first argument.
+  ASTContext &Context = CGM.getContext();
+  QualType ThisPtr = 
+    Context.getPointerType(Context.getTagDeclType(Method->getParent()));
+  llvm::DIType ThisPtrType = 
+    DebugFactory.CreateArtificialType(getOrCreateType(ThisPtr, Unit));
+  TypeCache[ThisPtr.getAsOpaquePtr()] = ThisPtrType.getNode();  
+  Elts.push_back(ThisPtrType);
+
+  // Copy rest of the arguments.
+  for (unsigned i = 1, e = Args.getNumElements(); i != e; ++i)
+    Elts.push_back(Args.getElement(i));
+
+  llvm::DIArray EltTypeArray =
+    DebugFactory.GetOrCreateArray(Elts.data(), Elts.size());
+
+  return
+    DebugFactory.CreateCompositeType(llvm::dwarf::DW_TAG_subroutine_type,
+                                     Unit, "", Unit,
+                                     0, 0, 0, 0, 0,
+                                     llvm::DIType(), EltTypeArray);
+}
+
+/// CreateCXXMemberFunction - A helper function to create a DISubprogram for
+/// a single member function GlobalDecl.
+llvm::DISubprogram
+CGDebugInfo::CreateCXXMemberFunction(const CXXMethodDecl *Method,
+                                     llvm::DIFile Unit,
+                                     llvm::DICompositeType &RecordTy) {
+  bool IsCtorOrDtor = 
+    isa<CXXConstructorDecl>(Method) || isa<CXXDestructorDecl>(Method);
+  
+  llvm::StringRef MethodName = getFunctionName(Method);
+  llvm::DIType MethodTy = getOrCreateMethodType(Method, Unit);
+  
+  // Since a single ctor/dtor corresponds to multiple functions, it doesn't
+  // make sense to give a single ctor/dtor a linkage name.
+  MangleBuffer MethodLinkageName;
+  if (!IsCtorOrDtor)
+    CGM.getMangledName(MethodLinkageName, Method);
+
+  SourceManager &SM = CGM.getContext().getSourceManager();
+
+  // Get the location for the method.
+  SourceLocation MethodDefLoc = Method->getLocation();
+  PresumedLoc PLoc = SM.getPresumedLoc(MethodDefLoc);
+  llvm::DIFile MethodDefUnit;
+  unsigned MethodLine = 0;
+
+  if (!PLoc.isInvalid()) {
+    MethodDefUnit = getOrCreateFile(MethodDefLoc);
+    MethodLine = PLoc.getLine();
+  }
+
+  // Collect virtual method info.
+  llvm::DIType ContainingType;
+  unsigned Virtuality = 0; 
+  unsigned VIndex = 0;
+  
+  if (Method->isVirtual()) {
+    if (Method->isPure())
+      Virtuality = llvm::dwarf::DW_VIRTUALITY_pure_virtual;
+    else
+      Virtuality = llvm::dwarf::DW_VIRTUALITY_virtual;
+    
+    // It doesn't make sense to give a virtual destructor a vtable index,
+    // since a single destructor has two entries in the vtable.
+    if (!isa<CXXDestructorDecl>(Method))
+      VIndex = CGM.getVTables().getMethodVTableIndex(Method);
+    ContainingType = RecordTy;
+  }
+
+  llvm::DISubprogram SP =
+    DebugFactory.CreateSubprogram(RecordTy , MethodName, MethodName, 
+                                  MethodLinkageName,
+                                  MethodDefUnit, MethodLine,
+                                  MethodTy, /*isLocalToUnit=*/false, 
+                                  Method->isThisDeclarationADefinition(),
+                                  Virtuality, VIndex, ContainingType);
+  
+  // Don't cache ctors or dtors since we have to emit multiple functions for
+  // a single ctor or dtor.
+  if (!IsCtorOrDtor && Method->isThisDeclarationADefinition())
+    SPCache[Method] = llvm::WeakVH(SP.getNode());
+
+  return SP;
+}
+
+/// CollectCXXMemberFunctions - A helper function to collect debug info for
+/// C++ member functions.This is used while creating debug info entry for 
+/// a Record.
+void CGDebugInfo::
+CollectCXXMemberFunctions(const CXXRecordDecl *RD, llvm::DIFile Unit,
+                          llvm::SmallVectorImpl<llvm::DIDescriptor> &EltTys,
+                          llvm::DICompositeType &RecordTy) {
+  for(CXXRecordDecl::method_iterator I = RD->method_begin(),
+        E = RD->method_end(); I != E; ++I) {
+    const CXXMethodDecl *Method = *I;
+    
+    if (Method->isImplicit() && !Method->isUsed())
+      continue;
+
+    EltTys.push_back(CreateCXXMemberFunction(Method, Unit, RecordTy));
+  }
+}                                 
+
+/// CollectCXXBases - A helper function to collect debug info for
+/// C++ base classes. This is used while creating debug info entry for 
+/// a Record.
+void CGDebugInfo::
+CollectCXXBases(const CXXRecordDecl *RD, llvm::DIFile Unit,
+                llvm::SmallVectorImpl<llvm::DIDescriptor> &EltTys,
+                llvm::DICompositeType &RecordTy) {
+
+  const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
+  for (CXXRecordDecl::base_class_const_iterator BI = RD->bases_begin(),
+         BE = RD->bases_end(); BI != BE; ++BI) {
+    unsigned BFlags = 0;
+    uint64_t BaseOffset;
+    
+    const CXXRecordDecl *Base =
+      cast<CXXRecordDecl>(BI->getType()->getAs<RecordType>()->getDecl());
+    
+    if (BI->isVirtual()) {
+      // virtual base offset offset is -ve. The code generator emits dwarf
+      // expression where it expects +ve number.
+      BaseOffset = 0 - CGM.getVTables().getVirtualBaseOffsetOffset(RD, Base);
+      BFlags = llvm::DIType::FlagVirtual;
+    } else
+      BaseOffset = RL.getBaseClassOffset(Base);
+    
+    AccessSpecifier Access = BI->getAccessSpecifier();
+    if (Access == clang::AS_private)
+      BFlags |= llvm::DIType::FlagPrivate;
+    else if (Access == clang::AS_protected)
+      BFlags |= llvm::DIType::FlagProtected;
+    
+    llvm::DIType DTy =
+      DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_inheritance,
+                                     RecordTy, llvm::StringRef(), 
+                                     Unit, 0, 0, 0,
+                                     BaseOffset, BFlags,
+                                     getOrCreateType(BI->getType(),
+                                                     Unit));
+    EltTys.push_back(DTy);
+  }
+}
+
+/// getOrCreateVTablePtrType - Return debug info descriptor for vtable.
+llvm::DIType CGDebugInfo::getOrCreateVTablePtrType(llvm::DIFile Unit) {
+  if (VTablePtrType.isValid())
+    return VTablePtrType;
+
+  ASTContext &Context = CGM.getContext();
+
+  /* Function type */
+  llvm::DIDescriptor STy = getOrCreateType(Context.IntTy, Unit);
+  llvm::DIArray SElements = DebugFactory.GetOrCreateArray(&STy, 1);
+  llvm::DIType SubTy =
+    DebugFactory.CreateCompositeType(llvm::dwarf::DW_TAG_subroutine_type,
+                                     Unit, "", Unit,
+                                     0, 0, 0, 0, 0, llvm::DIType(), SElements);
+
+  unsigned Size = Context.getTypeSize(Context.VoidPtrTy);
+  llvm::DIType vtbl_ptr_type 
+    = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_pointer_type,
+                                     Unit, "__vtbl_ptr_type", Unit,
+                                     0, Size, 0, 0, 0, SubTy);
+
+  VTablePtrType = 
+    DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_pointer_type,
+                                   Unit, "", Unit,
+                                   0, Size, 0, 0, 0, vtbl_ptr_type);
+  return VTablePtrType;
+}
+
+/// getVTableName - Get vtable name for the given Class.
+llvm::StringRef CGDebugInfo::getVTableName(const CXXRecordDecl *RD) {
+  // Otherwise construct gdb compatible name name.
+  std::string Name = "_vptr$" + RD->getNameAsString();
+
+  // Copy this name on the side and use its reference.
+  char *StrPtr = DebugInfoNames.Allocate<char>(Name.length());
+  memcpy(StrPtr, Name.data(), Name.length());
+  return llvm::StringRef(StrPtr, Name.length());
+}
+
+
+/// CollectVTableInfo - If the C++ class has vtable info then insert appropriate
+/// debug info entry in EltTys vector.
+void CGDebugInfo::
+CollectVTableInfo(const CXXRecordDecl *RD, llvm::DIFile Unit,
+                  llvm::SmallVectorImpl<llvm::DIDescriptor> &EltTys) {
+  const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
+
+  // If there is a primary base then it will hold vtable info.
+  if (RL.getPrimaryBase())
+    return;
+
+  // If this class is not dynamic then there is not any vtable info to collect.
+  if (!RD->isDynamicClass())
+    return;
+
+  unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
+  llvm::DIType VPTR
+    = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
+                                     getVTableName(RD), Unit,
+                                     0, Size, 0, 0, 0, 
+                                     getOrCreateVTablePtrType(Unit));
+  EltTys.push_back(VPTR);
+}
+
+/// CreateType - get structure or union type.
+llvm::DIType CGDebugInfo::CreateType(const RecordType *Ty,
+                                     llvm::DIFile Unit) {
+  RecordDecl *RD = Ty->getDecl();
+
+  unsigned Tag;
+  if (RD->isStruct())
+    Tag = llvm::dwarf::DW_TAG_structure_type;
+  else if (RD->isUnion())
+    Tag = llvm::dwarf::DW_TAG_union_type;
+  else {
+    assert(RD->isClass() && "Unknown RecordType!");
+    Tag = llvm::dwarf::DW_TAG_class_type;
+  }
+
+  SourceManager &SM = CGM.getContext().getSourceManager();
+
+  // Get overall information about the record type for the debug info.
+  PresumedLoc PLoc = SM.getPresumedLoc(RD->getLocation());
+  llvm::DIFile DefUnit;
+  unsigned Line = 0;
+  if (!PLoc.isInvalid()) {
+    DefUnit = getOrCreateFile(RD->getLocation());
+    Line = PLoc.getLine();
+  }
+
+  // Records and classes and unions can all be recursive.  To handle them, we
+  // first generate a debug descriptor for the struct as a forward declaration.
+  // Then (if it is a definition) we go through and get debug info for all of
+  // its members.  Finally, we create a descriptor for the complete type (which
+  // may refer to the forward decl if the struct is recursive) and replace all
+  // uses of the forward declaration with the final definition.
+
+  // A RD->getName() is not unique. However, the debug info descriptors 
+  // are uniqued so use type name to ensure uniquness.
+  llvm::SmallString<128> FwdDeclName;
+  llvm::raw_svector_ostream(FwdDeclName) << "fwd.type." << FwdDeclCount++;
+  llvm::DIDescriptor FDContext = 
+    getContextDescriptor(dyn_cast<Decl>(RD->getDeclContext()), Unit);
+  llvm::DICompositeType FwdDecl =
+    DebugFactory.CreateCompositeType(Tag, FDContext, FwdDeclName,
+                                     DefUnit, Line, 0, 0, 0, 0,
+                                     llvm::DIType(), llvm::DIArray());
+
+  // If this is just a forward declaration, return it.
+  if (!RD->getDefinition())
+    return FwdDecl;
+
+  llvm::TrackingVH<llvm::MDNode> FwdDeclNode = FwdDecl.getNode();
+  // Otherwise, insert it into the TypeCache so that recursive uses will find
+  // it.
+  TypeCache[QualType(Ty, 0).getAsOpaquePtr()] = FwdDecl.getNode();
+  // Push the struct on region stack.
+  RegionStack.push_back(FwdDecl.getNode());
+  RegionMap[Ty->getDecl()] = llvm::WeakVH(FwdDecl.getNode());
+
+  // Convert all the elements.
+  llvm::SmallVector<llvm::DIDescriptor, 16> EltTys;
+
+  const CXXRecordDecl *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
+  if (CXXDecl) {
+    CollectCXXBases(CXXDecl, Unit, EltTys, FwdDecl);
+    CollectVTableInfo(CXXDecl, Unit, EltTys);
+  }
+  CollectRecordFields(RD, Unit, EltTys);
+  llvm::MDNode *ContainingType = NULL;
+  if (CXXDecl) {
+    CollectCXXMemberFunctions(CXXDecl, Unit, EltTys, FwdDecl);
+
+    // A class's primary base or the class itself contains the vtable.
+    const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
+    if (const CXXRecordDecl *PBase = RL.getPrimaryBase())
+      ContainingType = 
+        getOrCreateType(QualType(PBase->getTypeForDecl(), 0), Unit).getNode();
+    else if (CXXDecl->isDynamicClass()) 
+      ContainingType = FwdDecl.getNode();
+  }
+
+  llvm::DIArray Elements =
+    DebugFactory.GetOrCreateArray(EltTys.data(), EltTys.size());
+
+  // Bit size, align and offset of the type.
+  uint64_t Size = CGM.getContext().getTypeSize(Ty);
+  uint64_t Align = CGM.getContext().getTypeAlign(Ty);
+
+  RegionStack.pop_back();
+  llvm::DenseMap<const Decl *, llvm::WeakVH>::iterator RI = 
+    RegionMap.find(Ty->getDecl());
+  if (RI != RegionMap.end())
+    RegionMap.erase(RI);
+
+  llvm::DIDescriptor RDContext =  
+    getContextDescriptor(dyn_cast<Decl>(RD->getDeclContext()), Unit);
+  llvm::DICompositeType RealDecl =
+    DebugFactory.CreateCompositeType(Tag, RDContext,
+                                     RD->getName(),
+                                     DefUnit, Line, Size, Align, 0, 0, 
+                                     llvm::DIType(), Elements, 
+                                     0, ContainingType);
+
+  // Now that we have a real decl for the struct, replace anything using the
+  // old decl with the new one.  This will recursively update the debug info.
+  llvm::DIDerivedType(FwdDeclNode).replaceAllUsesWith(RealDecl);
+  RegionMap[RD] = llvm::WeakVH(RealDecl.getNode());
+  return RealDecl;
+}
+
+/// CreateType - get objective-c interface type.
+llvm::DIType CGDebugInfo::CreateType(const ObjCInterfaceType *Ty,
+                                     llvm::DIFile Unit) {
+  ObjCInterfaceDecl *ID = Ty->getDecl();
+
+  unsigned Tag = llvm::dwarf::DW_TAG_structure_type;
+  SourceManager &SM = CGM.getContext().getSourceManager();
+
+  // Get overall information about the record type for the debug info.
+  llvm::DIFile DefUnit = getOrCreateFile(ID->getLocation());
+  PresumedLoc PLoc = SM.getPresumedLoc(ID->getLocation());
+  unsigned Line = PLoc.isInvalid() ? 0 : PLoc.getLine();
+
+
+  unsigned RuntimeLang = TheCU.getLanguage();
+
+  // To handle recursive interface, we
+  // first generate a debug descriptor for the struct as a forward declaration.
+  // Then (if it is a definition) we go through and get debug info for all of
+  // its members.  Finally, we create a descriptor for the complete type (which
+  // may refer to the forward decl if the struct is recursive) and replace all
+  // uses of the forward declaration with the final definition.
+  llvm::DICompositeType FwdDecl =
+    DebugFactory.CreateCompositeType(Tag, Unit, ID->getName(),
+                                     DefUnit, Line, 0, 0, 0, 0,
+                                     llvm::DIType(), llvm::DIArray(),
+                                     RuntimeLang);
+
+  // If this is just a forward declaration, return it.
+  if (ID->isForwardDecl())
+    return FwdDecl;
+
+  llvm::TrackingVH<llvm::MDNode> FwdDeclNode = FwdDecl.getNode();
+  // Otherwise, insert it into the TypeCache so that recursive uses will find
+  // it.
+  TypeCache[QualType(Ty, 0).getAsOpaquePtr()] = FwdDecl.getNode();
+  // Push the struct on region stack.
+  RegionStack.push_back(FwdDecl.getNode());
+  RegionMap[Ty->getDecl()] = llvm::WeakVH(FwdDecl.getNode());
+
+  // Convert all the elements.
+  llvm::SmallVector<llvm::DIDescriptor, 16> EltTys;
+
+  ObjCInterfaceDecl *SClass = ID->getSuperClass();
+  if (SClass) {
+    llvm::DIType SClassTy =
+      getOrCreateType(CGM.getContext().getObjCInterfaceType(SClass), Unit);
+    llvm::DIType InhTag =
+      DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_inheritance,
+                                     Unit, "", Unit, 0, 0, 0,
+                                     0 /* offset */, 0, SClassTy);
+    EltTys.push_back(InhTag);
+  }
+
+  const ASTRecordLayout &RL = CGM.getContext().getASTObjCInterfaceLayout(ID);
+
+  unsigned FieldNo = 0;
+  for (ObjCInterfaceDecl::ivar_iterator I = ID->ivar_begin(),
+         E = ID->ivar_end();  I != E; ++I, ++FieldNo) {
+    ObjCIvarDecl *Field = *I;
+    llvm::DIType FieldTy = getOrCreateType(Field->getType(), Unit);
+
+    llvm::StringRef FieldName = Field->getName();
+
+    // Ignore unnamed fields.
+    if (FieldName.empty())
+      continue;
+
+    // Get the location for the field.
+    SourceLocation FieldDefLoc = Field->getLocation();
+    llvm::DIFile FieldDefUnit = getOrCreateFile(FieldDefLoc);
+    PresumedLoc PLoc = SM.getPresumedLoc(FieldDefLoc);
+    unsigned FieldLine = PLoc.isInvalid() ? 0 : PLoc.getLine();
+
+
+    QualType FType = Field->getType();
+    uint64_t FieldSize = 0;
+    unsigned FieldAlign = 0;
+
+    if (!FType->isIncompleteArrayType()) {
+
+      // Bit size, align and offset of the type.
+      FieldSize = CGM.getContext().getTypeSize(FType);
+      Expr *BitWidth = Field->getBitWidth();
+      if (BitWidth)
+        FieldSize = BitWidth->EvaluateAsInt(CGM.getContext()).getZExtValue();
+
+      FieldAlign =  CGM.getContext().getTypeAlign(FType);
+    }
+
+    uint64_t FieldOffset = RL.getFieldOffset(FieldNo);
+
+    unsigned Flags = 0;
+    if (Field->getAccessControl() == ObjCIvarDecl::Protected)
+      Flags = llvm::DIType::FlagProtected;
+    else if (Field->getAccessControl() == ObjCIvarDecl::Private)
+      Flags = llvm::DIType::FlagPrivate;
+
+    // Create a DW_TAG_member node to remember the offset of this field in the
+    // struct.  FIXME: This is an absolutely insane way to capture this
+    // information.  When we gut debug info, this should be fixed.
+    FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
+                                             FieldName, FieldDefUnit,
+                                             FieldLine, FieldSize, FieldAlign,
+                                             FieldOffset, Flags, FieldTy);
+    EltTys.push_back(FieldTy);
+  }
+
+  llvm::DIArray Elements =
+    DebugFactory.GetOrCreateArray(EltTys.data(), EltTys.size());
+
+  RegionStack.pop_back();
+  llvm::DenseMap<const Decl *, llvm::WeakVH>::iterator RI = 
+    RegionMap.find(Ty->getDecl());
+  if (RI != RegionMap.end())
+    RegionMap.erase(RI);
+
+  // Bit size, align and offset of the type.
+  uint64_t Size = CGM.getContext().getTypeSize(Ty);
+  uint64_t Align = CGM.getContext().getTypeAlign(Ty);
+
+  llvm::DICompositeType RealDecl =
+    DebugFactory.CreateCompositeType(Tag, Unit, ID->getName(), DefUnit,
+                                     Line, Size, Align, 0, 0, llvm::DIType(), 
+                                     Elements, RuntimeLang);
+
+  // Now that we have a real decl for the struct, replace anything using the
+  // old decl with the new one.  This will recursively update the debug info.
+  llvm::DIDerivedType(FwdDeclNode).replaceAllUsesWith(RealDecl);
+  RegionMap[ID] = llvm::WeakVH(RealDecl.getNode());
+
+  return RealDecl;
+}
+
+llvm::DIType CGDebugInfo::CreateType(const EnumType *Ty,
+                                     llvm::DIFile Unit) {
+  EnumDecl *ED = Ty->getDecl();
+
+  llvm::SmallVector<llvm::DIDescriptor, 32> Enumerators;
+
+  // Create DIEnumerator elements for each enumerator.
+  for (EnumDecl::enumerator_iterator
+         Enum = ED->enumerator_begin(), EnumEnd = ED->enumerator_end();
+       Enum != EnumEnd; ++Enum) {
+    Enumerators.push_back(DebugFactory.CreateEnumerator(Enum->getName(),
+                                            Enum->getInitVal().getZExtValue()));
+  }
+
+  // Return a CompositeType for the enum itself.
+  llvm::DIArray EltArray =
+    DebugFactory.GetOrCreateArray(Enumerators.data(), Enumerators.size());
+
+  SourceLocation DefLoc = ED->getLocation();
+  llvm::DIFile DefUnit = getOrCreateFile(DefLoc);
+  SourceManager &SM = CGM.getContext().getSourceManager();
+  PresumedLoc PLoc = SM.getPresumedLoc(DefLoc);
+  unsigned Line = PLoc.isInvalid() ? 0 : PLoc.getLine();
+
+
+  // Size and align of the type.
+  uint64_t Size = 0;
+  unsigned Align = 0;
+  if (!Ty->isIncompleteType()) {
+    Size = CGM.getContext().getTypeSize(Ty);
+    Align = CGM.getContext().getTypeAlign(Ty);
+  }
+
+  llvm::DIType DbgTy = 
+    DebugFactory.CreateCompositeType(llvm::dwarf::DW_TAG_enumeration_type,
+                                     Unit, ED->getName(), DefUnit, Line,
+                                     Size, Align, 0, 0,
+                                     llvm::DIType(), EltArray);
+  return DbgTy;
+}
+
+llvm::DIType CGDebugInfo::CreateType(const TagType *Ty,
+                                     llvm::DIFile Unit) {
+  if (const RecordType *RT = dyn_cast<RecordType>(Ty))
+    return CreateType(RT, Unit);
+  else if (const EnumType *ET = dyn_cast<EnumType>(Ty))
+    return CreateType(ET, Unit);
+
+  return llvm::DIType();
+}
+
+llvm::DIType CGDebugInfo::CreateType(const VectorType *Ty,
+				     llvm::DIFile Unit) {
+  llvm::DIType ElementTy = getOrCreateType(Ty->getElementType(), Unit);
+  uint64_t NumElems = Ty->getNumElements();
+  if (NumElems > 0)
+    --NumElems;
+
+  llvm::DIDescriptor Subscript = DebugFactory.GetOrCreateSubrange(0, NumElems);
+  llvm::DIArray SubscriptArray = DebugFactory.GetOrCreateArray(&Subscript, 1);
+
+  uint64_t Size = CGM.getContext().getTypeSize(Ty);
+  uint64_t Align = CGM.getContext().getTypeAlign(Ty);
+
+  return
+    DebugFactory.CreateCompositeType(llvm::dwarf::DW_TAG_vector_type,
+                                     Unit, "", Unit,
+                                     0, Size, Align, 0, 0,
+				     ElementTy,  SubscriptArray);
+}
+
+llvm::DIType CGDebugInfo::CreateType(const ArrayType *Ty,
+                                     llvm::DIFile Unit) {
+  uint64_t Size;
+  uint64_t Align;
+
+
+  // FIXME: make getTypeAlign() aware of VLAs and incomplete array types
+  if (const VariableArrayType *VAT = dyn_cast<VariableArrayType>(Ty)) {
+    Size = 0;
+    Align =
+      CGM.getContext().getTypeAlign(CGM.getContext().getBaseElementType(VAT));
+  } else if (Ty->isIncompleteArrayType()) {
+    Size = 0;
+    Align = CGM.getContext().getTypeAlign(Ty->getElementType());
+  } else {
+    // Size and align of the whole array, not the element type.
+    Size = CGM.getContext().getTypeSize(Ty);
+    Align = CGM.getContext().getTypeAlign(Ty);
+  }
+
+  // Add the dimensions of the array.  FIXME: This loses CV qualifiers from
+  // interior arrays, do we care?  Why aren't nested arrays represented the
+  // obvious/recursive way?
+  llvm::SmallVector<llvm::DIDescriptor, 8> Subscripts;
+  QualType EltTy(Ty, 0);
+  while ((Ty = dyn_cast<ArrayType>(EltTy))) {
+    uint64_t Upper = 0;
+    if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(Ty))
+      if (CAT->getSize().getZExtValue())
+        Upper = CAT->getSize().getZExtValue() - 1;
+    // FIXME: Verify this is right for VLAs.
+    Subscripts.push_back(DebugFactory.GetOrCreateSubrange(0, Upper));
+    EltTy = Ty->getElementType();
+  }
+
+  llvm::DIArray SubscriptArray =
+    DebugFactory.GetOrCreateArray(Subscripts.data(), Subscripts.size());
+
+  llvm::DIType DbgTy = 
+    DebugFactory.CreateCompositeType(llvm::dwarf::DW_TAG_array_type,
+                                     Unit, "", Unit,
+                                     0, Size, Align, 0, 0,
+                                     getOrCreateType(EltTy, Unit),
+                                     SubscriptArray);
+  return DbgTy;
+}
+
+llvm::DIType CGDebugInfo::CreateType(const LValueReferenceType *Ty, 
+                                     llvm::DIFile Unit) {
+  return CreatePointerLikeType(llvm::dwarf::DW_TAG_reference_type, 
+                               Ty, Ty->getPointeeType(), Unit);
+}
+
+llvm::DIType CGDebugInfo::CreateType(const MemberPointerType *Ty, 
+                                     llvm::DIFile U) {
+  QualType PointerDiffTy = CGM.getContext().getPointerDiffType();
+  llvm::DIType PointerDiffDITy = getOrCreateType(PointerDiffTy, U);
+  
+  if (!Ty->getPointeeType()->isFunctionType()) {
+    // We have a data member pointer type.
+    return PointerDiffDITy;
+  }
+  
+  // We have a member function pointer type. Treat it as a struct with two
+  // ptrdiff_t members.
+  std::pair<uint64_t, unsigned> Info = CGM.getContext().getTypeInfo(Ty);
+
+  uint64_t FieldOffset = 0;
+  llvm::DIDescriptor ElementTypes[2];
+  
+  // FIXME: This should probably be a function type instead.
+  ElementTypes[0] =
+    DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, U,
+                                   "ptr", U, 0,
+                                   Info.first, Info.second, FieldOffset, 0,
+                                   PointerDiffDITy);
+  FieldOffset += Info.first;
+  
+  ElementTypes[1] =
+    DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, U,
+                                   "ptr", U, 0,
+                                   Info.first, Info.second, FieldOffset, 0,
+                                   PointerDiffDITy);
+  
+  llvm::DIArray Elements = 
+    DebugFactory.GetOrCreateArray(&ElementTypes[0],
+                                  llvm::array_lengthof(ElementTypes));
+
+  return DebugFactory.CreateCompositeType(llvm::dwarf::DW_TAG_structure_type, 
+                                          U, llvm::StringRef("test"), 
+                                          U, 0, FieldOffset, 
+                                          0, 0, 0, llvm::DIType(), Elements);
+}
+
+static QualType UnwrapTypeForDebugInfo(QualType T) {
+  do {
+    QualType LastT = T;
+    switch (T->getTypeClass()) {
+    default:
+      return T;
+    case Type::TemplateSpecialization:
+      T = cast<TemplateSpecializationType>(T)->desugar();
+      break;
+    case Type::TypeOfExpr: {
+      TypeOfExprType *Ty = cast<TypeOfExprType>(T);
+      T = Ty->getUnderlyingExpr()->getType();
+      break;
+    }
+    case Type::TypeOf:
+      T = cast<TypeOfType>(T)->getUnderlyingType();
+      break;
+    case Type::Decltype:
+      T = cast<DecltypeType>(T)->getUnderlyingType();
+      break;
+    case Type::QualifiedName:
+      T = cast<QualifiedNameType>(T)->getNamedType();
+      break;
+    case Type::SubstTemplateTypeParm:
+      T = cast<SubstTemplateTypeParmType>(T)->getReplacementType();
+      break;
+    case Type::Elaborated:
+      T = cast<ElaboratedType>(T)->getUnderlyingType();
+      break;
+    }
+    
+    assert(T != LastT && "Type unwrapping failed to unwrap!");
+    if (T == LastT)
+      return T;
+  } while (true);
+  
+  return T;
+}
+
+/// getOrCreateType - Get the type from the cache or create a new
+/// one if necessary.
+llvm::DIType CGDebugInfo::getOrCreateType(QualType Ty,
+                                          llvm::DIFile Unit) {
+  if (Ty.isNull())
+    return llvm::DIType();
+
+  // Unwrap the type as needed for debug information.
+  Ty = UnwrapTypeForDebugInfo(Ty);
+  
+  // Check for existing entry.
+  llvm::DenseMap<void *, llvm::WeakVH>::iterator it =
+    TypeCache.find(Ty.getAsOpaquePtr());
+  if (it != TypeCache.end()) {
+    // Verify that the debug info still exists.
+    if (&*it->second)
+      return llvm::DIType(cast<llvm::MDNode>(it->second));
+  }
+
+  // Otherwise create the type.
+  llvm::DIType Res = CreateTypeNode(Ty, Unit);
+
+  // And update the type cache.
+  TypeCache[Ty.getAsOpaquePtr()] = Res.getNode();  
+  return Res;
+}
+
+/// CreateTypeNode - Create a new debug type node.
+llvm::DIType CGDebugInfo::CreateTypeNode(QualType Ty,
+                                         llvm::DIFile Unit) {
+  // Handle qualifiers, which recursively handles what they refer to.
+  if (Ty.hasLocalQualifiers())
+    return CreateQualifiedType(Ty, Unit);
+
+  const char *Diag = 0;
+  
+  // Work out details of type.
+  switch (Ty->getTypeClass()) {
+#define TYPE(Class, Base)
+#define ABSTRACT_TYPE(Class, Base)
+#define NON_CANONICAL_TYPE(Class, Base)
+#define DEPENDENT_TYPE(Class, Base) case Type::Class:
+#include "clang/AST/TypeNodes.def"
+    assert(false && "Dependent types cannot show up in debug information");
+
+  // FIXME: Handle these.
+  case Type::ExtVector:
+    return llvm::DIType();
+
+  case Type::Vector:
+    return CreateType(cast<VectorType>(Ty), Unit);
+  case Type::ObjCObjectPointer:
+    return CreateType(cast<ObjCObjectPointerType>(Ty), Unit);
+  case Type::ObjCInterface:
+    return CreateType(cast<ObjCInterfaceType>(Ty), Unit);
+  case Type::Builtin: return CreateType(cast<BuiltinType>(Ty), Unit);
+  case Type::Complex: return CreateType(cast<ComplexType>(Ty), Unit);
+  case Type::Pointer: return CreateType(cast<PointerType>(Ty), Unit);
+  case Type::BlockPointer:
+    return CreateType(cast<BlockPointerType>(Ty), Unit);
+  case Type::Typedef: return CreateType(cast<TypedefType>(Ty), Unit);
+  case Type::Record:
+  case Type::Enum:
+    return CreateType(cast<TagType>(Ty), Unit);
+  case Type::FunctionProto:
+  case Type::FunctionNoProto:
+    return CreateType(cast<FunctionType>(Ty), Unit);
+  case Type::ConstantArray:
+  case Type::VariableArray:
+  case Type::IncompleteArray:
+    return CreateType(cast<ArrayType>(Ty), Unit);
+
+  case Type::LValueReference:
+    return CreateType(cast<LValueReferenceType>(Ty), Unit);
+
+  case Type::MemberPointer:
+    return CreateType(cast<MemberPointerType>(Ty), Unit);
+
+  case Type::TemplateSpecialization:
+  case Type::Elaborated:
+  case Type::QualifiedName:
+  case Type::SubstTemplateTypeParm:
+  case Type::TypeOfExpr:
+  case Type::TypeOf:
+  case Type::Decltype:
+    llvm_unreachable("type should have been unwrapped!");
+    return llvm::DIType();
+      
+  case Type::RValueReference:
+    // FIXME: Implement!
+    Diag = "rvalue references";
+    break;
+  }
+  
+  assert(Diag && "Fall through without a diagnostic?");
+  unsigned DiagID = CGM.getDiags().getCustomDiagID(Diagnostic::Error,
+                               "debug information for %0 is not yet supported");
+  CGM.getDiags().Report(FullSourceLoc(), DiagID)
+    << Diag;
+  return llvm::DIType();
+}
+
+/// CreateMemberType - Create new member and increase Offset by FType's size.
+llvm::DIType CGDebugInfo::CreateMemberType(llvm::DIFile Unit, QualType FType,
+                                           llvm::StringRef Name,
+                                           uint64_t *Offset) {
+  llvm::DIType FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
+  uint64_t FieldSize = CGM.getContext().getTypeSize(FType);
+  unsigned FieldAlign = CGM.getContext().getTypeAlign(FType);
+  llvm::DIType Ty = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member,
+                                                   Unit, Name, Unit, 0,
+                                                   FieldSize, FieldAlign,
+                                                   *Offset, 0, FieldTy);
+  *Offset += FieldSize;
+  return Ty;
+}
+
+/// EmitFunctionStart - Constructs the debug code for entering a function -
+/// "llvm.dbg.func.start.".
+void CGDebugInfo::EmitFunctionStart(GlobalDecl GD, QualType FnType,
+                                    llvm::Function *Fn,
+                                    CGBuilderTy &Builder) {
+
+  llvm::StringRef Name;
+  MangleBuffer LinkageName;
+
+  const Decl *D = GD.getDecl();
+  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+    // If there is a DISubprogram for  this function available then use it.
+    llvm::DenseMap<const FunctionDecl *, llvm::WeakVH>::iterator
+      FI = SPCache.find(FD);
+    if (FI != SPCache.end()) {
+      llvm::DIDescriptor SP(dyn_cast_or_null<llvm::MDNode>(FI->second));
+      if (SP.isSubprogram() && llvm::DISubprogram(SP.getNode()).isDefinition()) {
+        RegionStack.push_back(SP.getNode());
+        RegionMap[D] = llvm::WeakVH(SP.getNode());
+        return;
+      }
+    }
+    Name = getFunctionName(FD);
+    // Use mangled name as linkage name for c/c++ functions.
+    CGM.getMangledName(LinkageName, GD);
+  } else {
+    // Use llvm function name as linkage name.
+    Name = Fn->getName();
+    LinkageName.setString(Name);
+  }
+  if (!Name.empty() && Name[0] == '\01')
+    Name = Name.substr(1);
+
+  // It is expected that CurLoc is set before using EmitFunctionStart.
+  // Usually, CurLoc points to the left bracket location of compound
+  // statement representing function body.
+  llvm::DIFile Unit = getOrCreateFile(CurLoc);
+  SourceManager &SM = CGM.getContext().getSourceManager();
+  unsigned LineNo = SM.getPresumedLoc(CurLoc).getLine();
+
+  llvm::DISubprogram SP =
+    DebugFactory.CreateSubprogram(Unit, Name, Name, LinkageName, Unit, LineNo,
+                                  getOrCreateType(FnType, Unit),
+                                  Fn->hasInternalLinkage(), true/*definition*/);
+
+  // Push function on region stack.
+  RegionStack.push_back(SP.getNode());
+  RegionMap[D] = llvm::WeakVH(SP.getNode());
+}
+
+
+void CGDebugInfo::EmitStopPoint(llvm::Function *Fn, CGBuilderTy &Builder) {
+  if (CurLoc.isInvalid() || CurLoc.isMacroID()) return;
+
+  // Don't bother if things are the same as last time.
+  SourceManager &SM = CGM.getContext().getSourceManager();
+  if (CurLoc == PrevLoc
+       || (SM.getInstantiationLineNumber(CurLoc) ==
+           SM.getInstantiationLineNumber(PrevLoc)
+           && SM.isFromSameFile(CurLoc, PrevLoc)))
+    // New Builder may not be in sync with CGDebugInfo.
+    if (!Builder.getCurrentDebugLocation().isUnknown())
+      return;
+
+  // Update last state.
+  PrevLoc = CurLoc;
+
+  // Get the appropriate compile unit.
+  llvm::DIFile Unit = getOrCreateFile(CurLoc);
+  PresumedLoc PLoc = SM.getPresumedLoc(CurLoc);
+
+  llvm::MDNode *Scope = RegionStack.back();
+  Builder.SetCurrentDebugLocation(llvm::DebugLoc::get(PLoc.getLine(),
+                                                      PLoc.getColumn(),
+                                                      Scope));
+}
+
+/// EmitRegionStart- Constructs the debug code for entering a declarative
+/// region - "llvm.dbg.region.start.".
+void CGDebugInfo::EmitRegionStart(llvm::Function *Fn, CGBuilderTy &Builder) {
+  SourceManager &SM = CGM.getContext().getSourceManager();
+  PresumedLoc PLoc = SM.getPresumedLoc(CurLoc);
+  llvm::DIDescriptor D =
+    DebugFactory.CreateLexicalBlock(RegionStack.empty() ? 
+                                    llvm::DIDescriptor() : 
+                                    llvm::DIDescriptor(RegionStack.back()),
+                                    PLoc.getLine(), PLoc.getColumn());
+  RegionStack.push_back(D.getNode());
+}
+
+/// EmitRegionEnd - Constructs the debug code for exiting a declarative
+/// region - "llvm.dbg.region.end."
+void CGDebugInfo::EmitRegionEnd(llvm::Function *Fn, CGBuilderTy &Builder) {
+  assert(!RegionStack.empty() && "Region stack mismatch, stack empty!");
+
+  // Provide an region stop point.
+  EmitStopPoint(Fn, Builder);
+
+  RegionStack.pop_back();
+}
+
+// EmitTypeForVarWithBlocksAttr - Build up structure info for the byref.  
+// See BuildByRefType.
+llvm::DIType CGDebugInfo::EmitTypeForVarWithBlocksAttr(const ValueDecl *VD,
+                                                       uint64_t *XOffset) {
+
+  llvm::SmallVector<llvm::DIDescriptor, 5> EltTys;
+
+  QualType FType;
+  uint64_t FieldSize, FieldOffset;
+  unsigned FieldAlign;
+  
+  llvm::DIFile Unit = getOrCreateFile(VD->getLocation());
+  QualType Type = VD->getType();  
+
+  FieldOffset = 0;
+  FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
+  EltTys.push_back(CreateMemberType(Unit, FType, "__isa", &FieldOffset));
+  EltTys.push_back(CreateMemberType(Unit, FType, "__forwarding", &FieldOffset));
+  FType = CGM.getContext().IntTy;
+  EltTys.push_back(CreateMemberType(Unit, FType, "__flags", &FieldOffset));
+  EltTys.push_back(CreateMemberType(Unit, FType, "__size", &FieldOffset));
+
+  bool HasCopyAndDispose = CGM.BlockRequiresCopying(Type);
+  if (HasCopyAndDispose) {
+    FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
+    EltTys.push_back(CreateMemberType(Unit, FType, "__copy_helper",
+                                      &FieldOffset));
+    EltTys.push_back(CreateMemberType(Unit, FType, "__destroy_helper",
+                                      &FieldOffset));
+  }
+  
+  CharUnits Align = CGM.getContext().getDeclAlign(VD);
+  if (Align > CharUnits::fromQuantity(
+        CGM.getContext().Target.getPointerAlign(0) / 8)) {
+    unsigned AlignedOffsetInBytes
+      = llvm::RoundUpToAlignment(FieldOffset/8, Align.getQuantity());
+    unsigned NumPaddingBytes
+      = AlignedOffsetInBytes - FieldOffset/8;
+    
+    if (NumPaddingBytes > 0) {
+      llvm::APInt pad(32, NumPaddingBytes);
+      FType = CGM.getContext().getConstantArrayType(CGM.getContext().CharTy,
+                                                    pad, ArrayType::Normal, 0);
+      EltTys.push_back(CreateMemberType(Unit, FType, "", &FieldOffset));
+    }
+  }
+  
+  FType = Type;
+  llvm::DIType FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
+  FieldSize = CGM.getContext().getTypeSize(FType);
+  FieldAlign = Align.getQuantity()*8;
+
+  *XOffset = FieldOffset;  
+  FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
+                                           VD->getName(), Unit,
+                                           0, FieldSize, FieldAlign,
+                                           FieldOffset, 0, FieldTy);
+  EltTys.push_back(FieldTy);
+  FieldOffset += FieldSize;
+  
+  llvm::DIArray Elements = 
+    DebugFactory.GetOrCreateArray(EltTys.data(), EltTys.size());
+  
+  unsigned Flags = llvm::DIType::FlagBlockByrefStruct;
+  
+  return DebugFactory.CreateCompositeType(llvm::dwarf::DW_TAG_structure_type, 
+                                          Unit, "", Unit,
+                                          0, FieldOffset, 0, 0, Flags,
+                                          llvm::DIType(), Elements);
+  
+}
+/// EmitDeclare - Emit local variable declaration debug info.
+void CGDebugInfo::EmitDeclare(const VarDecl *VD, unsigned Tag,
+                              llvm::Value *Storage, CGBuilderTy &Builder) {
+  assert(!RegionStack.empty() && "Region stack mismatch, stack empty!");
+
+  llvm::DIFile Unit = getOrCreateFile(VD->getLocation());
+  llvm::DIType Ty;
+  uint64_t XOffset = 0;
+  if (VD->hasAttr<BlocksAttr>())
+    Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset);
+  else 
+    Ty = getOrCreateType(VD->getType(), Unit);
+
+  // Get location information.
+  SourceManager &SM = CGM.getContext().getSourceManager();
+  PresumedLoc PLoc = SM.getPresumedLoc(VD->getLocation());
+  unsigned Line = 0;
+  unsigned Column = 0;
+  if (PLoc.isInvalid())
+    PLoc = SM.getPresumedLoc(CurLoc);
+  if (PLoc.isValid()) {
+    Line = PLoc.getLine();
+    Column = PLoc.getColumn();
+    Unit = getOrCreateFile(CurLoc);
+  } else {
+    Unit = llvm::DIFile();
+  }
+
+  // Create the descriptor for the variable.
+  llvm::DIVariable D =
+    DebugFactory.CreateVariable(Tag, llvm::DIDescriptor(RegionStack.back()),
+                                VD->getName(),
+                                Unit, Line, Ty);
+  // Insert an llvm.dbg.declare into the current block.
+  llvm::Instruction *Call =
+    DebugFactory.InsertDeclare(Storage, D, Builder.GetInsertBlock());
+
+  llvm::MDNode *Scope = RegionStack.back();
+  Call->setDebugLoc(llvm::DebugLoc::get(Line, Column, Scope));
+}
+
+/// EmitDeclare - Emit local variable declaration debug info.
+void CGDebugInfo::EmitDeclare(const BlockDeclRefExpr *BDRE, unsigned Tag,
+                              llvm::Value *Storage, CGBuilderTy &Builder,
+                              CodeGenFunction *CGF) {
+  const ValueDecl *VD = BDRE->getDecl();
+  assert(!RegionStack.empty() && "Region stack mismatch, stack empty!");
+
+  if (Builder.GetInsertBlock() == 0)
+    return;
+
+  uint64_t XOffset = 0;
+  llvm::DIFile Unit = getOrCreateFile(VD->getLocation());
+  llvm::DIType Ty;
+  if (VD->hasAttr<BlocksAttr>())
+    Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset);
+  else 
+    Ty = getOrCreateType(VD->getType(), Unit);
+
+  // Get location information.
+  SourceManager &SM = CGM.getContext().getSourceManager();
+  PresumedLoc PLoc = SM.getPresumedLoc(VD->getLocation());
+  unsigned Line = 0;
+  if (!PLoc.isInvalid())
+    Line = PLoc.getLine();
+  else
+    Unit = llvm::DIFile();
+
+  CharUnits offset = CGF->BlockDecls[VD];
+  llvm::SmallVector<llvm::Value *, 9> addr;
+  const llvm::Type *Int64Ty = llvm::Type::getInt64Ty(CGM.getLLVMContext());
+  addr.push_back(llvm::ConstantInt::get(Int64Ty, llvm::DIFactory::OpDeref));
+  addr.push_back(llvm::ConstantInt::get(Int64Ty, llvm::DIFactory::OpPlus));
+  addr.push_back(llvm::ConstantInt::get(Int64Ty, offset.getQuantity()));
+  if (BDRE->isByRef()) {
+    addr.push_back(llvm::ConstantInt::get(Int64Ty, llvm::DIFactory::OpDeref));
+    addr.push_back(llvm::ConstantInt::get(Int64Ty, llvm::DIFactory::OpPlus));
+    // offset of __forwarding field
+    offset = CharUnits::fromQuantity(CGF->LLVMPointerWidth/8);
+    addr.push_back(llvm::ConstantInt::get(Int64Ty, offset.getQuantity()));
+    addr.push_back(llvm::ConstantInt::get(Int64Ty, llvm::DIFactory::OpDeref));
+    addr.push_back(llvm::ConstantInt::get(Int64Ty, llvm::DIFactory::OpPlus));
+    // offset of x field
+    offset = CharUnits::fromQuantity(XOffset/8);
+    addr.push_back(llvm::ConstantInt::get(Int64Ty, offset.getQuantity()));
+  }
+
+  // Create the descriptor for the variable.
+  llvm::DIVariable D =
+    DebugFactory.CreateComplexVariable(Tag,
+                                       llvm::DIDescriptor(RegionStack.back()),
+                                       VD->getName(), Unit, Line, Ty,
+                                       addr);
+  // Insert an llvm.dbg.declare into the current block.
+  llvm::Instruction *Call = 
+    DebugFactory.InsertDeclare(Storage, D, Builder.GetInsertBlock());
+  
+  llvm::MDNode *Scope = RegionStack.back();
+  Call->setDebugLoc(llvm::DebugLoc::get(Line, PLoc.getColumn(), Scope));
+}
+
+void CGDebugInfo::EmitDeclareOfAutoVariable(const VarDecl *VD,
+                                            llvm::Value *Storage,
+                                            CGBuilderTy &Builder) {
+  EmitDeclare(VD, llvm::dwarf::DW_TAG_auto_variable, Storage, Builder);
+}
+
+void CGDebugInfo::EmitDeclareOfBlockDeclRefVariable(
+  const BlockDeclRefExpr *BDRE, llvm::Value *Storage, CGBuilderTy &Builder,
+  CodeGenFunction *CGF) {
+  EmitDeclare(BDRE, llvm::dwarf::DW_TAG_auto_variable, Storage, Builder, CGF);
+}
+
+/// EmitDeclareOfArgVariable - Emit call to llvm.dbg.declare for an argument
+/// variable declaration.
+void CGDebugInfo::EmitDeclareOfArgVariable(const VarDecl *VD, llvm::Value *AI,
+                                           CGBuilderTy &Builder) {
+  EmitDeclare(VD, llvm::dwarf::DW_TAG_arg_variable, AI, Builder);
+}
+
+
+
+/// EmitGlobalVariable - Emit information about a global variable.
+void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var,
+                                     const VarDecl *D) {
+  
+  // Create global variable debug descriptor.
+  llvm::DIFile Unit = getOrCreateFile(D->getLocation());
+  SourceManager &SM = CGM.getContext().getSourceManager();
+  PresumedLoc PLoc = SM.getPresumedLoc(D->getLocation());
+  unsigned LineNo = PLoc.isInvalid() ? 0 : PLoc.getLine();
+
+  QualType T = D->getType();
+  if (T->isIncompleteArrayType()) {
+
+    // CodeGen turns int[] into int[1] so we'll do the same here.
+    llvm::APSInt ConstVal(32);
+
+    ConstVal = 1;
+    QualType ET = CGM.getContext().getAsArrayType(T)->getElementType();
+
+    T = CGM.getContext().getConstantArrayType(ET, ConstVal,
+                                           ArrayType::Normal, 0);
+  }
+  llvm::StringRef DeclName = Var->getName();
+  llvm::DIDescriptor DContext = 
+    getContextDescriptor(dyn_cast<Decl>(D->getDeclContext()), Unit);
+  DebugFactory.CreateGlobalVariable(DContext, DeclName,
+                                    DeclName, llvm::StringRef(), Unit, LineNo,
+                                    getOrCreateType(T, Unit),
+                                    Var->hasInternalLinkage(),
+                                    true/*definition*/, Var);
+}
+
+/// EmitGlobalVariable - Emit information about an objective-c interface.
+void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var,
+                                     ObjCInterfaceDecl *ID) {
+  // Create global variable debug descriptor.
+  llvm::DIFile Unit = getOrCreateFile(ID->getLocation());
+  SourceManager &SM = CGM.getContext().getSourceManager();
+  PresumedLoc PLoc = SM.getPresumedLoc(ID->getLocation());
+  unsigned LineNo = PLoc.isInvalid() ? 0 : PLoc.getLine();
+
+  llvm::StringRef Name = ID->getName();
+
+  QualType T = CGM.getContext().getObjCInterfaceType(ID);
+  if (T->isIncompleteArrayType()) {
+
+    // CodeGen turns int[] into int[1] so we'll do the same here.
+    llvm::APSInt ConstVal(32);
+
+    ConstVal = 1;
+    QualType ET = CGM.getContext().getAsArrayType(T)->getElementType();
+
+    T = CGM.getContext().getConstantArrayType(ET, ConstVal,
+                                           ArrayType::Normal, 0);
+  }
+
+  DebugFactory.CreateGlobalVariable(Unit, Name, Name, Name, Unit, LineNo,
+                                    getOrCreateType(T, Unit),
+                                    Var->hasInternalLinkage(),
+                                    true/*definition*/, Var);
+}
+
+/// getOrCreateNamesSpace - Return namespace descriptor for the given
+/// namespace decl.
+llvm::DINameSpace 
+CGDebugInfo::getOrCreateNameSpace(const NamespaceDecl *NSDecl, 
+                                  llvm::DIDescriptor Unit) {
+  llvm::DenseMap<const NamespaceDecl *, llvm::WeakVH>::iterator I = 
+    NameSpaceCache.find(NSDecl);
+  if (I != NameSpaceCache.end())
+    return llvm::DINameSpace(cast<llvm::MDNode>(I->second));
+  
+  SourceManager &SM = CGM.getContext().getSourceManager();
+  PresumedLoc PLoc = SM.getPresumedLoc(NSDecl->getLocation());
+  unsigned LineNo = PLoc.isInvalid() ? 0 : PLoc.getLine();
+
+  llvm::DIDescriptor Context = 
+    getContextDescriptor(dyn_cast<Decl>(NSDecl->getDeclContext()), Unit);
+  llvm::DINameSpace NS =
+    DebugFactory.CreateNameSpace(Context, NSDecl->getName(), 
+	llvm::DIFile(Unit.getNode()), LineNo);
+  NameSpaceCache[NSDecl] = llvm::WeakVH(NS.getNode());
+  return NS;
+}
diff --git a/lib/CodeGen/CGDebugInfo.h b/lib/CodeGen/CGDebugInfo.h
new file mode 100644
index 0000000..c16379a
--- /dev/null
+++ b/lib/CodeGen/CGDebugInfo.h
@@ -0,0 +1,216 @@
+//===--- CGDebugInfo.h - DebugInfo for LLVM CodeGen -------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This is the source level debug info generator for llvm translation.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_CODEGEN_CGDEBUGINFO_H
+#define CLANG_CODEGEN_CGDEBUGINFO_H
+
+#include "clang/AST/Type.h"
+#include "clang/AST/Expr.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/Analysis/DebugInfo.h"
+#include "llvm/Support/ValueHandle.h"
+#include "llvm/Support/Allocator.h"
+
+#include "CGBuilder.h"
+
+namespace llvm {
+  class MDNode;
+}
+
+namespace clang {
+  class VarDecl;
+  class ObjCInterfaceDecl;
+
+namespace CodeGen {
+  class CodeGenModule;
+  class CodeGenFunction;
+  class GlobalDecl;
+
+/// CGDebugInfo - This class gathers all debug information during compilation
+/// and is responsible for emitting to llvm globals or pass directly to
+/// the backend.
+class CGDebugInfo {
+  CodeGenModule &CGM;
+  llvm::DIFactory DebugFactory;
+  llvm::DICompileUnit TheCU;
+  SourceLocation CurLoc, PrevLoc;
+  llvm::DIType VTablePtrType;
+  /// FwdDeclCount - This counter is used to ensure unique names for forward
+  /// record decls.
+  unsigned FwdDeclCount;
+  
+  /// TypeCache - Cache of previously constructed Types.
+  llvm::DenseMap<void *, llvm::WeakVH> TypeCache;
+
+  bool BlockLiteralGenericSet;
+  llvm::DIType BlockLiteralGeneric;
+
+  std::vector<llvm::TrackingVH<llvm::MDNode> > RegionStack;
+  llvm::DenseMap<const Decl *, llvm::WeakVH> RegionMap;
+
+  /// DebugInfoNames - This is a storage for names that are
+  /// constructed on demand. For example, C++ destructors, C++ operators etc..
+  llvm::BumpPtrAllocator DebugInfoNames;
+
+  llvm::DenseMap<const char *, llvm::WeakVH> DIFileCache;
+  llvm::DenseMap<const FunctionDecl *, llvm::WeakVH> SPCache;
+  llvm::DenseMap<const NamespaceDecl *, llvm::WeakVH> NameSpaceCache;
+
+  /// Helper functions for getOrCreateType.
+  llvm::DIType CreateType(const BuiltinType *Ty, llvm::DIFile F);
+  llvm::DIType CreateType(const ComplexType *Ty, llvm::DIFile F);
+  llvm::DIType CreateQualifiedType(QualType Ty, llvm::DIFile F);
+  llvm::DIType CreateType(const TypedefType *Ty, llvm::DIFile F);
+  llvm::DIType CreateType(const ObjCObjectPointerType *Ty,
+                          llvm::DIFile F);
+  llvm::DIType CreateType(const PointerType *Ty, llvm::DIFile F);
+  llvm::DIType CreateType(const BlockPointerType *Ty, llvm::DIFile F);
+  llvm::DIType CreateType(const FunctionType *Ty, llvm::DIFile F);
+  llvm::DIType CreateType(const TagType *Ty, llvm::DIFile F);
+  llvm::DIType CreateType(const RecordType *Ty, llvm::DIFile F);
+  llvm::DIType CreateType(const ObjCInterfaceType *Ty, llvm::DIFile F);
+  llvm::DIType CreateType(const EnumType *Ty, llvm::DIFile F);
+  llvm::DIType CreateType(const VectorType *Ty, llvm::DIFile F);
+  llvm::DIType CreateType(const ArrayType *Ty, llvm::DIFile F);
+  llvm::DIType CreateType(const LValueReferenceType *Ty, llvm::DIFile F);
+  llvm::DIType CreateType(const MemberPointerType *Ty, llvm::DIFile F);
+  llvm::DIType getOrCreateMethodType(const CXXMethodDecl *Method,
+                                     llvm::DIFile F);
+  llvm::DIType getOrCreateVTablePtrType(llvm::DIFile F);
+  llvm::DINameSpace getOrCreateNameSpace(const NamespaceDecl *N, 
+                                         llvm::DIDescriptor Unit);
+
+  llvm::DIType CreatePointerLikeType(unsigned Tag,
+                                     const Type *Ty, QualType PointeeTy,
+                                     llvm::DIFile F);
+  
+  llvm::DISubprogram CreateCXXMemberFunction(const CXXMethodDecl *Method,
+                                             llvm::DIFile F,
+                                             llvm::DICompositeType &RecordTy);
+  
+  void CollectCXXMemberFunctions(const CXXRecordDecl *Decl,
+                                 llvm::DIFile F,
+                                 llvm::SmallVectorImpl<llvm::DIDescriptor> &E,
+                                 llvm::DICompositeType &T);
+  void CollectCXXBases(const CXXRecordDecl *Decl,
+                       llvm::DIFile F,
+                       llvm::SmallVectorImpl<llvm::DIDescriptor> &EltTys,
+                       llvm::DICompositeType &RecordTy);
+
+
+  void CollectRecordFields(const RecordDecl *Decl, llvm::DIFile F,
+                           llvm::SmallVectorImpl<llvm::DIDescriptor> &E);
+
+  void CollectVTableInfo(const CXXRecordDecl *Decl,
+                         llvm::DIFile F,
+                         llvm::SmallVectorImpl<llvm::DIDescriptor> &EltTys);
+
+public:
+  CGDebugInfo(CodeGenModule &CGM);
+  ~CGDebugInfo();
+
+  /// setLocation - Update the current source location. If \arg loc is
+  /// invalid it is ignored.
+  void setLocation(SourceLocation Loc);
+
+  /// EmitStopPoint - Emit a call to llvm.dbg.stoppoint to indicate a change of
+  /// source line.
+  void EmitStopPoint(llvm::Function *Fn, CGBuilderTy &Builder);
+
+  /// EmitFunctionStart - Emit a call to llvm.dbg.function.start to indicate
+  /// start of a new function.
+  void EmitFunctionStart(GlobalDecl GD, QualType FnType,
+                         llvm::Function *Fn, CGBuilderTy &Builder);
+
+  /// EmitRegionStart - Emit a call to llvm.dbg.region.start to indicate start
+  /// of a new block.
+  void EmitRegionStart(llvm::Function *Fn, CGBuilderTy &Builder);
+
+  /// EmitRegionEnd - Emit call to llvm.dbg.region.end to indicate end of a
+  /// block.
+  void EmitRegionEnd(llvm::Function *Fn, CGBuilderTy &Builder);
+
+  /// EmitDeclareOfAutoVariable - Emit call to llvm.dbg.declare for an automatic
+  /// variable declaration.
+  void EmitDeclareOfAutoVariable(const VarDecl *Decl, llvm::Value *AI,
+                                 CGBuilderTy &Builder);
+
+  /// EmitDeclareOfBlockDeclRefVariable - Emit call to llvm.dbg.declare for an
+  /// imported variable declaration in a block.
+  void EmitDeclareOfBlockDeclRefVariable(const BlockDeclRefExpr *BDRE,
+                                         llvm::Value *AI,
+                                         CGBuilderTy &Builder,
+                                         CodeGenFunction *CGF);
+
+  /// EmitDeclareOfArgVariable - Emit call to llvm.dbg.declare for an argument
+  /// variable declaration.
+  void EmitDeclareOfArgVariable(const VarDecl *Decl, llvm::Value *AI,
+                                CGBuilderTy &Builder);
+
+  /// EmitGlobalVariable - Emit information about a global variable.
+  void EmitGlobalVariable(llvm::GlobalVariable *GV, const VarDecl *Decl);
+
+  /// EmitGlobalVariable - Emit information about an objective-c interface.
+  void EmitGlobalVariable(llvm::GlobalVariable *GV, ObjCInterfaceDecl *Decl);
+
+private:
+  /// EmitDeclare - Emit call to llvm.dbg.declare for a variable declaration.
+  void EmitDeclare(const VarDecl *decl, unsigned Tag, llvm::Value *AI,
+                   CGBuilderTy &Builder);
+
+  /// EmitDeclare - Emit call to llvm.dbg.declare for a variable declaration.
+  void EmitDeclare(const BlockDeclRefExpr *BDRE, unsigned Tag, llvm::Value *AI,
+                   CGBuilderTy &Builder, CodeGenFunction *CGF);
+
+  // EmitTypeForVarWithBlocksAttr - Build up structure info for the byref.  
+  // See BuildByRefType.
+  llvm::DIType EmitTypeForVarWithBlocksAttr(const ValueDecl *VD, 
+                                            uint64_t *OffSet);
+
+  /// getContextDescriptor - Get context info for the decl.
+  llvm::DIDescriptor getContextDescriptor(const Decl *Decl,
+                                          llvm::DIDescriptor &CU);
+
+  /// CreateCompileUnit - Create new compile unit.
+  void CreateCompileUnit();
+
+  /// getOrCreateFile - Get the file debug info descriptor for the input 
+  /// location.
+  llvm::DIFile getOrCreateFile(SourceLocation Loc);
+
+  /// getOrCreateType - Get the type from the cache or create a new type if
+  /// necessary.
+  llvm::DIType getOrCreateType(QualType Ty, llvm::DIFile F);
+
+  /// CreateTypeNode - Create type metadata for a source language type.
+  llvm::DIType CreateTypeNode(QualType Ty, llvm::DIFile F);
+
+  /// CreateMemberType - Create new member and increase Offset by FType's size.
+  llvm::DIType CreateMemberType(llvm::DIFile Unit, QualType FType,
+                                llvm::StringRef Name, uint64_t *Offset);
+
+  /// getFunctionName - Get function name for the given FunctionDecl. If the
+  /// name is constructred on demand (e.g. C++ destructor) then the name
+  /// is stored on the side.
+  llvm::StringRef getFunctionName(const FunctionDecl *FD);
+
+  /// getVTableName - Get vtable name for the given Class.
+  llvm::StringRef getVTableName(const CXXRecordDecl *Decl);
+
+};
+} // namespace CodeGen
+} // namespace clang
+
+
+#endif
diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp
new file mode 100644
index 0000000..331ae7a
--- /dev/null
+++ b/lib/CodeGen/CGDecl.cpp
@@ -0,0 +1,777 @@
+//===--- CGDecl.cpp - Emit LLVM Code for declarations ---------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This contains code to emit Decl nodes as LLVM code.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CGDebugInfo.h"
+#include "CodeGenFunction.h"
+#include "CodeGenModule.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/CharUnits.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/TargetInfo.h"
+#include "clang/CodeGen/CodeGenOptions.h"
+#include "llvm/GlobalVariable.h"
+#include "llvm/Intrinsics.h"
+#include "llvm/Target/TargetData.h"
+#include "llvm/Type.h"
+using namespace clang;
+using namespace CodeGen;
+
+
+void CodeGenFunction::EmitDecl(const Decl &D) {
+  switch (D.getKind()) {
+  case Decl::TranslationUnit:
+  case Decl::Namespace:
+  case Decl::UnresolvedUsingTypename:
+  case Decl::ClassTemplateSpecialization:
+  case Decl::ClassTemplatePartialSpecialization:
+  case Decl::TemplateTypeParm:
+  case Decl::UnresolvedUsingValue:
+    case Decl::NonTypeTemplateParm:
+  case Decl::CXXMethod:
+  case Decl::CXXConstructor:
+  case Decl::CXXDestructor:
+  case Decl::CXXConversion:
+  case Decl::Field:
+  case Decl::ObjCIvar:
+  case Decl::ObjCAtDefsField:      
+  case Decl::ParmVar:
+  case Decl::ImplicitParam:
+  case Decl::ClassTemplate:
+  case Decl::FunctionTemplate:
+  case Decl::TemplateTemplateParm:
+  case Decl::ObjCMethod:
+  case Decl::ObjCCategory:
+  case Decl::ObjCProtocol:
+  case Decl::ObjCInterface:
+  case Decl::ObjCCategoryImpl:
+  case Decl::ObjCImplementation:
+  case Decl::ObjCProperty:
+  case Decl::ObjCCompatibleAlias:
+  case Decl::LinkageSpec:
+  case Decl::ObjCPropertyImpl:
+  case Decl::ObjCClass:
+  case Decl::ObjCForwardProtocol:
+  case Decl::FileScopeAsm:
+  case Decl::Friend:
+  case Decl::FriendTemplate:
+  case Decl::Block:
+    
+    assert(0 && "Declaration not should not be in declstmts!");
+  case Decl::Function:  // void X();
+  case Decl::Record:    // struct/union/class X;
+  case Decl::Enum:      // enum X;
+  case Decl::EnumConstant: // enum ? { X = ? }
+  case Decl::CXXRecord: // struct/union/class X; [C++]
+  case Decl::Using:          // using X; [C++]
+  case Decl::UsingShadow:
+  case Decl::UsingDirective: // using namespace X; [C++]
+  case Decl::NamespaceAlias:
+  case Decl::StaticAssert: // static_assert(X, ""); [C++0x]
+    // None of these decls require codegen support.
+    return;
+
+  case Decl::Var: {
+    const VarDecl &VD = cast<VarDecl>(D);
+    assert(VD.isBlockVarDecl() &&
+           "Should not see file-scope variables inside a function!");
+    return EmitBlockVarDecl(VD);
+  }
+
+  case Decl::Typedef: {   // typedef int X;
+    const TypedefDecl &TD = cast<TypedefDecl>(D);
+    QualType Ty = TD.getUnderlyingType();
+
+    if (Ty->isVariablyModifiedType())
+      EmitVLASize(Ty);
+  }
+  }
+}
+
+/// EmitBlockVarDecl - This method handles emission of any variable declaration
+/// inside a function, including static vars etc.
+void CodeGenFunction::EmitBlockVarDecl(const VarDecl &D) {
+  if (D.hasAttr<AsmLabelAttr>())
+    CGM.ErrorUnsupported(&D, "__asm__");
+
+  switch (D.getStorageClass()) {
+  case VarDecl::None:
+  case VarDecl::Auto:
+  case VarDecl::Register:
+    return EmitLocalBlockVarDecl(D);
+  case VarDecl::Static: {
+    llvm::GlobalValue::LinkageTypes Linkage = 
+      llvm::GlobalValue::InternalLinkage;
+
+    // If this is a static declaration inside an inline function, it must have
+    // weak linkage so that the linker will merge multiple definitions of it.
+    if (getContext().getLangOptions().CPlusPlus) {
+      if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CurFuncDecl)) {
+        if (FD->isInlined())
+          Linkage = llvm::GlobalValue::WeakAnyLinkage;
+      }
+    }
+    
+    return EmitStaticBlockVarDecl(D, Linkage);
+  }
+  case VarDecl::Extern:
+  case VarDecl::PrivateExtern:
+    // Don't emit it now, allow it to be emitted lazily on its first use.
+    return;
+  }
+
+  assert(0 && "Unknown storage class");
+}
+
+static std::string GetStaticDeclName(CodeGenFunction &CGF, const VarDecl &D,
+                                     const char *Separator) {
+  CodeGenModule &CGM = CGF.CGM;
+  if (CGF.getContext().getLangOptions().CPlusPlus) {
+    MangleBuffer Name;
+    CGM.getMangledName(Name, &D);
+    return Name.getString().str();
+  }
+  
+  std::string ContextName;
+  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CGF.CurFuncDecl)) {
+    MangleBuffer Name;
+    CGM.getMangledName(Name, FD);
+    ContextName = Name.getString().str();
+  } else if (isa<ObjCMethodDecl>(CGF.CurFuncDecl))
+    ContextName = CGF.CurFn->getName();
+  else
+    // FIXME: What about in a block??
+    assert(0 && "Unknown context for block var decl");
+  
+  return ContextName + Separator + D.getNameAsString();
+}
+
+llvm::GlobalVariable *
+CodeGenFunction::CreateStaticBlockVarDecl(const VarDecl &D,
+                                          const char *Separator,
+                                      llvm::GlobalValue::LinkageTypes Linkage) {
+  QualType Ty = D.getType();
+  assert(Ty->isConstantSizeType() && "VLAs can't be static");
+
+  std::string Name = GetStaticDeclName(*this, D, Separator);
+
+  const llvm::Type *LTy = CGM.getTypes().ConvertTypeForMem(Ty);
+  llvm::GlobalVariable *GV =
+    new llvm::GlobalVariable(CGM.getModule(), LTy,
+                             Ty.isConstant(getContext()), Linkage,
+                             CGM.EmitNullConstant(D.getType()), Name, 0,
+                             D.isThreadSpecified(), Ty.getAddressSpace());
+  GV->setAlignment(getContext().getDeclAlign(&D).getQuantity());
+  return GV;
+}
+
+/// AddInitializerToGlobalBlockVarDecl - Add the initializer for 'D' to the
+/// global variable that has already been created for it.  If the initializer
+/// has a different type than GV does, this may free GV and return a different
+/// one.  Otherwise it just returns GV.
+llvm::GlobalVariable *
+CodeGenFunction::AddInitializerToGlobalBlockVarDecl(const VarDecl &D,
+                                                    llvm::GlobalVariable *GV) {
+  llvm::Constant *Init = CGM.EmitConstantExpr(D.getInit(), D.getType(), this);
+  
+  // If constant emission failed, then this should be a C++ static
+  // initializer.
+  if (!Init) {
+    if (!getContext().getLangOptions().CPlusPlus)
+      CGM.ErrorUnsupported(D.getInit(), "constant l-value expression");
+    else {
+      // Since we have a static initializer, this global variable can't 
+      // be constant.
+      GV->setConstant(false);
+      
+      EmitStaticCXXBlockVarDeclInit(D, GV);
+    }
+    return GV;
+  }
+  
+  // The initializer may differ in type from the global. Rewrite
+  // the global to match the initializer.  (We have to do this
+  // because some types, like unions, can't be completely represented
+  // in the LLVM type system.)
+  if (GV->getType() != Init->getType()) {
+    llvm::GlobalVariable *OldGV = GV;
+    
+    GV = new llvm::GlobalVariable(CGM.getModule(), Init->getType(),
+                                  OldGV->isConstant(),
+                                  OldGV->getLinkage(), Init, "",
+                                  0, D.isThreadSpecified(),
+                                  D.getType().getAddressSpace());
+    
+    // Steal the name of the old global
+    GV->takeName(OldGV);
+    
+    // Replace all uses of the old global with the new global
+    llvm::Constant *NewPtrForOldDecl =
+    llvm::ConstantExpr::getBitCast(GV, OldGV->getType());
+    OldGV->replaceAllUsesWith(NewPtrForOldDecl);
+    
+    // Erase the old global, since it is no longer used.
+    OldGV->eraseFromParent();
+  }
+  
+  GV->setInitializer(Init);
+  return GV;
+}
+
+void CodeGenFunction::EmitStaticBlockVarDecl(const VarDecl &D,
+                                      llvm::GlobalValue::LinkageTypes Linkage) {
+  llvm::Value *&DMEntry = LocalDeclMap[&D];
+  assert(DMEntry == 0 && "Decl already exists in localdeclmap!");
+
+  llvm::GlobalVariable *GV = CreateStaticBlockVarDecl(D, ".", Linkage);
+
+  // Store into LocalDeclMap before generating initializer to handle
+  // circular references.
+  DMEntry = GV;
+  if (getContext().getLangOptions().CPlusPlus)
+    CGM.setStaticLocalDeclAddress(&D, GV);
+
+  // Make sure to evaluate VLA bounds now so that we have them for later.
+  //
+  // FIXME: Can this happen?
+  if (D.getType()->isVariablyModifiedType())
+    EmitVLASize(D.getType());
+
+  // If this value has an initializer, emit it.
+  if (D.getInit())
+    GV = AddInitializerToGlobalBlockVarDecl(D, GV);
+
+  GV->setAlignment(getContext().getDeclAlign(&D).getQuantity());
+
+  // FIXME: Merge attribute handling.
+  if (const AnnotateAttr *AA = D.getAttr<AnnotateAttr>()) {
+    SourceManager &SM = CGM.getContext().getSourceManager();
+    llvm::Constant *Ann =
+      CGM.EmitAnnotateAttr(GV, AA,
+                           SM.getInstantiationLineNumber(D.getLocation()));
+    CGM.AddAnnotation(Ann);
+  }
+
+  if (const SectionAttr *SA = D.getAttr<SectionAttr>())
+    GV->setSection(SA->getName());
+
+  if (D.hasAttr<UsedAttr>())
+    CGM.AddUsedGlobal(GV);
+
+  // We may have to cast the constant because of the initializer
+  // mismatch above.
+  //
+  // FIXME: It is really dangerous to store this in the map; if anyone
+  // RAUW's the GV uses of this constant will be invalid.
+  const llvm::Type *LTy = CGM.getTypes().ConvertTypeForMem(D.getType());
+  const llvm::Type *LPtrTy =
+    llvm::PointerType::get(LTy, D.getType().getAddressSpace());
+  DMEntry = llvm::ConstantExpr::getBitCast(GV, LPtrTy);
+
+  // Emit global variable debug descriptor for static vars.
+  CGDebugInfo *DI = getDebugInfo();
+  if (DI) {
+    DI->setLocation(D.getLocation());
+    DI->EmitGlobalVariable(static_cast<llvm::GlobalVariable *>(GV), &D);
+  }
+}
+
+unsigned CodeGenFunction::getByRefValueLLVMField(const ValueDecl *VD) const {
+  assert(ByRefValueInfo.count(VD) && "Did not find value!");
+  
+  return ByRefValueInfo.find(VD)->second.second;
+}
+
+/// BuildByRefType - This routine changes a __block variable declared as T x
+///   into:
+///
+///      struct {
+///        void *__isa;
+///        void *__forwarding;
+///        int32_t __flags;
+///        int32_t __size;
+///        void *__copy_helper;       // only if needed
+///        void *__destroy_helper;    // only if needed
+///        char padding[X];           // only if needed
+///        T x;
+///      } x
+///
+const llvm::Type *CodeGenFunction::BuildByRefType(const ValueDecl *D) {
+  std::pair<const llvm::Type *, unsigned> &Info = ByRefValueInfo[D];
+  if (Info.first)
+    return Info.first;
+  
+  QualType Ty = D->getType();
+
+  std::vector<const llvm::Type *> Types;
+  
+  const llvm::PointerType *Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext);
+
+  llvm::PATypeHolder ByRefTypeHolder = llvm::OpaqueType::get(VMContext);
+  
+  // void *__isa;
+  Types.push_back(Int8PtrTy);
+  
+  // void *__forwarding;
+  Types.push_back(llvm::PointerType::getUnqual(ByRefTypeHolder));
+  
+  // int32_t __flags;
+  Types.push_back(llvm::Type::getInt32Ty(VMContext));
+    
+  // int32_t __size;
+  Types.push_back(llvm::Type::getInt32Ty(VMContext));
+
+  bool HasCopyAndDispose = BlockRequiresCopying(Ty);
+  if (HasCopyAndDispose) {
+    /// void *__copy_helper;
+    Types.push_back(Int8PtrTy);
+    
+    /// void *__destroy_helper;
+    Types.push_back(Int8PtrTy);
+  }
+
+  bool Packed = false;
+  CharUnits Align = getContext().getDeclAlign(D);
+  if (Align > CharUnits::fromQuantity(Target.getPointerAlign(0) / 8)) {
+    // We have to insert padding.
+    
+    // The struct above has 2 32-bit integers.
+    unsigned CurrentOffsetInBytes = 4 * 2;
+    
+    // And either 2 or 4 pointers.
+    CurrentOffsetInBytes += (HasCopyAndDispose ? 4 : 2) *
+      CGM.getTargetData().getTypeAllocSize(Int8PtrTy);
+    
+    // Align the offset.
+    unsigned AlignedOffsetInBytes = 
+      llvm::RoundUpToAlignment(CurrentOffsetInBytes, Align.getQuantity());
+    
+    unsigned NumPaddingBytes = AlignedOffsetInBytes - CurrentOffsetInBytes;
+    if (NumPaddingBytes > 0) {
+      const llvm::Type *Ty = llvm::Type::getInt8Ty(VMContext);
+      // FIXME: We need a sema error for alignment larger than the minimum of
+      // the maximal stack alignmint and the alignment of malloc on the system.
+      if (NumPaddingBytes > 1)
+        Ty = llvm::ArrayType::get(Ty, NumPaddingBytes);
+    
+      Types.push_back(Ty);
+
+      // We want a packed struct.
+      Packed = true;
+    }
+  }
+
+  // T x;
+  Types.push_back(ConvertType(Ty));
+  
+  const llvm::Type *T = llvm::StructType::get(VMContext, Types, Packed);
+  
+  cast<llvm::OpaqueType>(ByRefTypeHolder.get())->refineAbstractTypeTo(T);
+  CGM.getModule().addTypeName("struct.__block_byref_" + D->getNameAsString(), 
+                              ByRefTypeHolder.get());
+  
+  Info.first = ByRefTypeHolder.get();
+  
+  Info.second = Types.size() - 1;
+  
+  return Info.first;
+}
+
+/// EmitLocalBlockVarDecl - Emit code and set up an entry in LocalDeclMap for a
+/// variable declaration with auto, register, or no storage class specifier.
+/// These turn into simple stack objects, or GlobalValues depending on target.
+void CodeGenFunction::EmitLocalBlockVarDecl(const VarDecl &D) {
+  QualType Ty = D.getType();
+  bool isByRef = D.hasAttr<BlocksAttr>();
+  bool needsDispose = false;
+  CharUnits Align = CharUnits::Zero();
+  bool IsSimpleConstantInitializer = false;
+
+  llvm::Value *DeclPtr;
+  if (Ty->isConstantSizeType()) {
+    if (!Target.useGlobalsForAutomaticVariables()) {
+      
+      // If this value is an array or struct, is POD, and if the initializer is
+      // a staticly determinable constant, try to optimize it.
+      if (D.getInit() && !isByRef &&
+          (Ty->isArrayType() || Ty->isRecordType()) &&
+          Ty->isPODType() &&
+          D.getInit()->isConstantInitializer(getContext())) {
+        // If this variable is marked 'const', emit the value as a global.
+        if (CGM.getCodeGenOpts().MergeAllConstants &&
+            Ty.isConstant(getContext())) {
+          EmitStaticBlockVarDecl(D, llvm::GlobalValue::InternalLinkage);
+          return;
+        }
+        
+        IsSimpleConstantInitializer = true;
+      }
+      
+      // A normal fixed sized variable becomes an alloca in the entry block.
+      const llvm::Type *LTy = ConvertTypeForMem(Ty);
+      if (isByRef)
+        LTy = BuildByRefType(&D);
+      llvm::AllocaInst *Alloc = CreateTempAlloca(LTy);
+      Alloc->setName(D.getNameAsString());
+
+      Align = getContext().getDeclAlign(&D);
+      if (isByRef)
+        Align = std::max(Align, 
+            CharUnits::fromQuantity(Target.getPointerAlign(0) / 8));
+      Alloc->setAlignment(Align.getQuantity());
+      DeclPtr = Alloc;
+    } else {
+      // Targets that don't support recursion emit locals as globals.
+      const char *Class =
+        D.getStorageClass() == VarDecl::Register ? ".reg." : ".auto.";
+      DeclPtr = CreateStaticBlockVarDecl(D, Class,
+                                         llvm::GlobalValue
+                                         ::InternalLinkage);
+    }
+
+    // FIXME: Can this happen?
+    if (Ty->isVariablyModifiedType())
+      EmitVLASize(Ty);
+  } else {
+    EnsureInsertPoint();
+
+    if (!DidCallStackSave) {
+      // Save the stack.
+      const llvm::Type *LTy = llvm::Type::getInt8PtrTy(VMContext);
+      llvm::Value *Stack = CreateTempAlloca(LTy, "saved_stack");
+
+      llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::stacksave);
+      llvm::Value *V = Builder.CreateCall(F);
+
+      Builder.CreateStore(V, Stack);
+
+      DidCallStackSave = true;
+
+      {
+        // Push a cleanup block and restore the stack there.
+        DelayedCleanupBlock scope(*this);
+
+        V = Builder.CreateLoad(Stack, "tmp");
+        llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::stackrestore);
+        Builder.CreateCall(F, V);
+      }
+    }
+
+    // Get the element type.
+    const llvm::Type *LElemTy = ConvertTypeForMem(Ty);
+    const llvm::Type *LElemPtrTy =
+      llvm::PointerType::get(LElemTy, D.getType().getAddressSpace());
+
+    llvm::Value *VLASize = EmitVLASize(Ty);
+
+    // Downcast the VLA size expression
+    VLASize = Builder.CreateIntCast(VLASize, llvm::Type::getInt32Ty(VMContext),
+                                    false, "tmp");
+
+    // Allocate memory for the array.
+    llvm::AllocaInst *VLA = 
+      Builder.CreateAlloca(llvm::Type::getInt8Ty(VMContext), VLASize, "vla");
+    VLA->setAlignment(getContext().getDeclAlign(&D).getQuantity());
+
+    DeclPtr = Builder.CreateBitCast(VLA, LElemPtrTy, "tmp");
+  }
+
+  llvm::Value *&DMEntry = LocalDeclMap[&D];
+  assert(DMEntry == 0 && "Decl already exists in localdeclmap!");
+  DMEntry = DeclPtr;
+
+  // Emit debug info for local var declaration.
+  if (CGDebugInfo *DI = getDebugInfo()) {
+    assert(HaveInsertPoint() && "Unexpected unreachable point!");
+
+    DI->setLocation(D.getLocation());
+    if (Target.useGlobalsForAutomaticVariables()) {
+      DI->EmitGlobalVariable(static_cast<llvm::GlobalVariable *>(DeclPtr), &D);
+    } else
+      DI->EmitDeclareOfAutoVariable(&D, DeclPtr, Builder);
+  }
+
+  // If this local has an initializer, emit it now.
+  const Expr *Init = D.getInit();
+
+  // If we are at an unreachable point, we don't need to emit the initializer
+  // unless it contains a label.
+  if (!HaveInsertPoint()) {
+    if (!ContainsLabel(Init))
+      Init = 0;
+    else
+      EnsureInsertPoint();
+  }
+
+  if (isByRef) {
+    const llvm::PointerType *PtrToInt8Ty = llvm::Type::getInt8PtrTy(VMContext);
+
+    EnsureInsertPoint();
+    llvm::Value *isa_field = Builder.CreateStructGEP(DeclPtr, 0);
+    llvm::Value *forwarding_field = Builder.CreateStructGEP(DeclPtr, 1);
+    llvm::Value *flags_field = Builder.CreateStructGEP(DeclPtr, 2);
+    llvm::Value *size_field = Builder.CreateStructGEP(DeclPtr, 3);
+    llvm::Value *V;
+    int flag = 0;
+    int flags = 0;
+
+    needsDispose = true;
+
+    if (Ty->isBlockPointerType()) {
+      flag |= BLOCK_FIELD_IS_BLOCK;
+      flags |= BLOCK_HAS_COPY_DISPOSE;
+    } else if (BlockRequiresCopying(Ty)) {
+      flag |= BLOCK_FIELD_IS_OBJECT;
+      flags |= BLOCK_HAS_COPY_DISPOSE;
+    }
+
+    // FIXME: Someone double check this.
+    if (Ty.isObjCGCWeak())
+      flag |= BLOCK_FIELD_IS_WEAK;
+
+    int isa = 0;
+    if (flag&BLOCK_FIELD_IS_WEAK)
+      isa = 1;
+    V = llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), isa);
+    V = Builder.CreateIntToPtr(V, PtrToInt8Ty, "isa");
+    Builder.CreateStore(V, isa_field);
+
+    Builder.CreateStore(DeclPtr, forwarding_field);
+
+    V = llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), flags);
+    Builder.CreateStore(V, flags_field);
+
+    const llvm::Type *V1;
+    V1 = cast<llvm::PointerType>(DeclPtr->getType())->getElementType();
+    V = llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext),
+                               CGM.GetTargetTypeStoreSize(V1).getQuantity());
+    Builder.CreateStore(V, size_field);
+
+    if (flags & BLOCK_HAS_COPY_DISPOSE) {
+      BlockHasCopyDispose = true;
+      llvm::Value *copy_helper = Builder.CreateStructGEP(DeclPtr, 4);
+      Builder.CreateStore(BuildbyrefCopyHelper(DeclPtr->getType(), flag, 
+                                               Align.getQuantity()),
+                          copy_helper);
+
+      llvm::Value *destroy_helper = Builder.CreateStructGEP(DeclPtr, 5);
+      Builder.CreateStore(BuildbyrefDestroyHelper(DeclPtr->getType(), flag,
+                                                  Align.getQuantity()),
+                          destroy_helper);
+    }
+  }
+
+  if (Init) {
+    llvm::Value *Loc = DeclPtr;
+    if (isByRef)
+      Loc = Builder.CreateStructGEP(DeclPtr, getByRefValueLLVMField(&D), 
+                                    D.getNameAsString());
+    
+    bool isVolatile =
+    getContext().getCanonicalType(D.getType()).isVolatileQualified();
+    
+    // If the initializer was a simple constant initializer, we can optimize it
+    // in various ways.
+    if (IsSimpleConstantInitializer) {
+      llvm::Constant *Init = CGM.EmitConstantExpr(D.getInit(),D.getType(),this);
+      assert(Init != 0 && "Wasn't a simple constant init?");
+      
+      llvm::Value *AlignVal = 
+      llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 
+                             Align.getQuantity());
+      const llvm::Type *IntPtr =
+      llvm::IntegerType::get(VMContext, LLVMPointerWidth);
+      llvm::Value *SizeVal =
+      llvm::ConstantInt::get(IntPtr, 
+                             getContext().getTypeSizeInChars(Ty).getQuantity());
+      
+      const llvm::Type *BP = llvm::Type::getInt8PtrTy(VMContext);
+      if (Loc->getType() != BP)
+        Loc = Builder.CreateBitCast(Loc, BP, "tmp");
+      
+      llvm::Value *NotVolatile =
+        llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), 0);
+
+      // If the initializer is all zeros, codegen with memset.
+      if (isa<llvm::ConstantAggregateZero>(Init)) {
+        llvm::Value *Zero =
+          llvm::ConstantInt::get(llvm::Type::getInt8Ty(VMContext), 0);
+        Builder.CreateCall5(CGM.getMemSetFn(Loc->getType(), SizeVal->getType()),
+                            Loc, Zero, SizeVal, AlignVal, NotVolatile);
+      } else {
+        // Otherwise, create a temporary global with the initializer then 
+        // memcpy from the global to the alloca.
+        std::string Name = GetStaticDeclName(*this, D, ".");
+        llvm::GlobalVariable *GV =
+        new llvm::GlobalVariable(CGM.getModule(), Init->getType(), true,
+                                 llvm::GlobalValue::InternalLinkage,
+                                 Init, Name, 0, false, 0);
+        GV->setAlignment(Align.getQuantity());
+        
+        llvm::Value *SrcPtr = GV;
+        if (SrcPtr->getType() != BP)
+          SrcPtr = Builder.CreateBitCast(SrcPtr, BP, "tmp");
+
+        Builder.CreateCall5(CGM.getMemCpyFn(Loc->getType(), SrcPtr->getType(),
+                                            SizeVal->getType()),
+                            Loc, SrcPtr, SizeVal, AlignVal, NotVolatile);
+      }
+    } else if (Ty->isReferenceType()) {
+      RValue RV = EmitReferenceBindingToExpr(Init, /*IsInitializer=*/true);
+      EmitStoreOfScalar(RV.getScalarVal(), Loc, false, Ty);
+    } else if (!hasAggregateLLVMType(Init->getType())) {
+      llvm::Value *V = EmitScalarExpr(Init);
+      EmitStoreOfScalar(V, Loc, isVolatile, D.getType());
+    } else if (Init->getType()->isAnyComplexType()) {
+      EmitComplexExprIntoAddr(Init, Loc, isVolatile);
+    } else {
+      EmitAggExpr(Init, Loc, isVolatile);
+    }
+  }
+  
+  // Handle CXX destruction of variables.
+  QualType DtorTy(Ty);
+  while (const ArrayType *Array = getContext().getAsArrayType(DtorTy))
+    DtorTy = getContext().getBaseElementType(Array);
+  if (const RecordType *RT = DtorTy->getAs<RecordType>())
+    if (CXXRecordDecl *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
+      if (!ClassDecl->hasTrivialDestructor()) {
+        const CXXDestructorDecl *D = ClassDecl->getDestructor(getContext());
+        assert(D && "EmitLocalBlockVarDecl - destructor is nul");
+        
+        if (const ConstantArrayType *Array = 
+              getContext().getAsConstantArrayType(Ty)) {
+          {
+            DelayedCleanupBlock Scope(*this);
+            QualType BaseElementTy = getContext().getBaseElementType(Array);
+            const llvm::Type *BasePtr = ConvertType(BaseElementTy);
+            BasePtr = llvm::PointerType::getUnqual(BasePtr);
+            llvm::Value *BaseAddrPtr =
+              Builder.CreateBitCast(DeclPtr, BasePtr);
+            EmitCXXAggrDestructorCall(D, Array, BaseAddrPtr);
+          
+            // Make sure to jump to the exit block.
+            EmitBranch(Scope.getCleanupExitBlock());
+          }
+          if (Exceptions) {
+            EHCleanupBlock Cleanup(*this);
+            QualType BaseElementTy = getContext().getBaseElementType(Array);
+            const llvm::Type *BasePtr = ConvertType(BaseElementTy);
+            BasePtr = llvm::PointerType::getUnqual(BasePtr);
+            llvm::Value *BaseAddrPtr =
+              Builder.CreateBitCast(DeclPtr, BasePtr);
+            EmitCXXAggrDestructorCall(D, Array, BaseAddrPtr);
+          }
+        } else {
+          {
+            DelayedCleanupBlock Scope(*this);
+            EmitCXXDestructorCall(D, Dtor_Complete, DeclPtr);
+
+            // Make sure to jump to the exit block.
+            EmitBranch(Scope.getCleanupExitBlock());
+          }
+          if (Exceptions) {
+            EHCleanupBlock Cleanup(*this);
+            EmitCXXDestructorCall(D, Dtor_Complete, DeclPtr);
+          }
+        }
+      }
+  }
+
+  // Handle the cleanup attribute
+  if (const CleanupAttr *CA = D.getAttr<CleanupAttr>()) {
+    const FunctionDecl *FD = CA->getFunctionDecl();
+
+    llvm::Constant* F = CGM.GetAddrOfFunction(FD);
+    assert(F && "Could not find function!");
+
+    const CGFunctionInfo &Info = CGM.getTypes().getFunctionInfo(FD);
+
+    // In some cases, the type of the function argument will be different from
+    // the type of the pointer. An example of this is
+    // void f(void* arg);
+    // __attribute__((cleanup(f))) void *g;
+    //
+    // To fix this we insert a bitcast here.
+    QualType ArgTy = Info.arg_begin()->type;
+    {
+      DelayedCleanupBlock scope(*this);
+
+      CallArgList Args;
+      Args.push_back(std::make_pair(RValue::get(Builder.CreateBitCast(DeclPtr,
+                                                           ConvertType(ArgTy))),
+                                    getContext().getPointerType(D.getType())));
+      EmitCall(Info, F, ReturnValueSlot(), Args);
+    }
+    if (Exceptions) {
+      EHCleanupBlock Cleanup(*this);
+
+      CallArgList Args;
+      Args.push_back(std::make_pair(RValue::get(Builder.CreateBitCast(DeclPtr,
+                                                           ConvertType(ArgTy))),
+                                    getContext().getPointerType(D.getType())));
+      EmitCall(Info, F, ReturnValueSlot(), Args);
+    }
+  }
+
+  if (needsDispose && CGM.getLangOptions().getGCMode() != LangOptions::GCOnly) {
+    {
+      DelayedCleanupBlock scope(*this);
+      llvm::Value *V = Builder.CreateStructGEP(DeclPtr, 1, "forwarding");
+      V = Builder.CreateLoad(V);
+      BuildBlockRelease(V);
+    }
+    // FIXME: Turn this on and audit the codegen
+    if (0 && Exceptions) {
+      EHCleanupBlock Cleanup(*this);
+      llvm::Value *V = Builder.CreateStructGEP(DeclPtr, 1, "forwarding");
+      V = Builder.CreateLoad(V);
+      BuildBlockRelease(V);
+    }
+  }
+}
+
+/// Emit an alloca (or GlobalValue depending on target)
+/// for the specified parameter and set up LocalDeclMap.
+void CodeGenFunction::EmitParmDecl(const VarDecl &D, llvm::Value *Arg) {
+  // FIXME: Why isn't ImplicitParamDecl a ParmVarDecl?
+  assert((isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D)) &&
+         "Invalid argument to EmitParmDecl");
+  QualType Ty = D.getType();
+  CanQualType CTy = getContext().getCanonicalType(Ty);
+
+  llvm::Value *DeclPtr;
+  // If this is an aggregate or variable sized value, reuse the input pointer.
+  if (!Ty->isConstantSizeType() ||
+      CodeGenFunction::hasAggregateLLVMType(Ty)) {
+    DeclPtr = Arg;
+  } else {
+    // Otherwise, create a temporary to hold the value.
+    DeclPtr = CreateMemTemp(Ty, D.getName() + ".addr");
+
+    // Store the initial value into the alloca.
+    EmitStoreOfScalar(Arg, DeclPtr, CTy.isVolatileQualified(), Ty);
+  }
+  Arg->setName(D.getName());
+
+  llvm::Value *&DMEntry = LocalDeclMap[&D];
+  assert(DMEntry == 0 && "Decl already exists in localdeclmap!");
+  DMEntry = DeclPtr;
+
+  // Emit debug info for param declaration.
+  if (CGDebugInfo *DI = getDebugInfo()) {
+    DI->setLocation(D.getLocation());
+    DI->EmitDeclareOfArgVariable(&D, DeclPtr, Builder);
+  }
+}
diff --git a/lib/CodeGen/CGDeclCXX.cpp b/lib/CodeGen/CGDeclCXX.cpp
new file mode 100644
index 0000000..f6c805f
--- /dev/null
+++ b/lib/CodeGen/CGDeclCXX.cpp
@@ -0,0 +1,350 @@
+//===--- CGDeclCXX.cpp - Emit LLVM Code for C++ declarations --------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This contains code dealing with code generation of C++ declarations
+//
+//===----------------------------------------------------------------------===//
+
+#include "CodeGenFunction.h"
+#include "clang/CodeGen/CodeGenOptions.h"
+using namespace clang;
+using namespace CodeGen;
+
+static void EmitDeclInit(CodeGenFunction &CGF, const VarDecl &D,
+                         llvm::Constant *DeclPtr) {
+  assert(D.hasGlobalStorage() && "VarDecl must have global storage!");
+  assert(!D.getType()->isReferenceType() && 
+         "Should not call EmitDeclInit on a reference!");
+  
+  CodeGenModule &CGM = CGF.CGM;
+  ASTContext &Context = CGF.getContext();
+    
+  const Expr *Init = D.getInit();
+  QualType T = D.getType();
+  bool isVolatile = Context.getCanonicalType(T).isVolatileQualified();
+
+  if (!CGF.hasAggregateLLVMType(T)) {
+    llvm::Value *V = CGF.EmitScalarExpr(Init);
+    CGF.EmitStoreOfScalar(V, DeclPtr, isVolatile, T);
+  } else if (T->isAnyComplexType()) {
+    CGF.EmitComplexExprIntoAddr(Init, DeclPtr, isVolatile);
+  } else {
+    CGF.EmitAggExpr(Init, DeclPtr, isVolatile);
+    
+    // Avoid generating destructor(s) for initialized objects. 
+    if (!isa<CXXConstructExpr>(Init))
+      return;
+    
+    const ConstantArrayType *Array = Context.getAsConstantArrayType(T);
+    if (Array)
+      T = Context.getBaseElementType(Array);
+    
+    const RecordType *RT = T->getAs<RecordType>();
+    if (!RT)
+      return;
+    
+    CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
+    if (RD->hasTrivialDestructor())
+      return;
+    
+    CXXDestructorDecl *Dtor = RD->getDestructor(Context);
+    
+    llvm::Constant *DtorFn;
+    if (Array) {
+      DtorFn = 
+        CodeGenFunction(CGM).GenerateCXXAggrDestructorHelper(Dtor, 
+                                                             Array, 
+                                                             DeclPtr);
+      const llvm::Type *Int8PtrTy =
+        llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
+      DeclPtr = llvm::Constant::getNullValue(Int8PtrTy);
+     } else
+      DtorFn = CGM.GetAddrOfCXXDestructor(Dtor, Dtor_Complete);
+
+    CGF.EmitCXXGlobalDtorRegistration(DtorFn, DeclPtr);
+  }
+}
+
+void CodeGenFunction::EmitCXXGlobalVarDeclInit(const VarDecl &D,
+                                               llvm::Constant *DeclPtr) {
+
+  const Expr *Init = D.getInit();
+  QualType T = D.getType();
+
+  if (!T->isReferenceType()) {
+    EmitDeclInit(*this, D, DeclPtr);
+    return;
+  }
+  if (Init->isLvalue(getContext()) == Expr::LV_Valid) {
+    RValue RV = EmitReferenceBindingToExpr(Init, /*IsInitializer=*/true);
+    EmitStoreOfScalar(RV.getScalarVal(), DeclPtr, false, T);
+    return;
+  }
+  ErrorUnsupported(Init, 
+                   "global variable that binds reference to a non-lvalue");
+}
+
+void
+CodeGenFunction::EmitCXXGlobalDtorRegistration(llvm::Constant *DtorFn,
+                                               llvm::Constant *DeclPtr) {
+  // Generate a global destructor entry if not using __cxa_atexit.
+  if (!CGM.getCodeGenOpts().CXAAtExit) {
+    CGM.AddCXXDtorEntry(DtorFn, DeclPtr);
+    return;
+  }
+
+  const llvm::Type *Int8PtrTy = 
+    llvm::Type::getInt8Ty(VMContext)->getPointerTo();
+
+  std::vector<const llvm::Type *> Params;
+  Params.push_back(Int8PtrTy);
+
+  // Get the destructor function type
+  const llvm::Type *DtorFnTy =
+    llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), Params, false);
+  DtorFnTy = llvm::PointerType::getUnqual(DtorFnTy);
+
+  Params.clear();
+  Params.push_back(DtorFnTy);
+  Params.push_back(Int8PtrTy);
+  Params.push_back(Int8PtrTy);
+
+  // Get the __cxa_atexit function type
+  // extern "C" int __cxa_atexit ( void (*f)(void *), void *p, void *d );
+  const llvm::FunctionType *AtExitFnTy =
+    llvm::FunctionType::get(ConvertType(getContext().IntTy), Params, false);
+
+  llvm::Constant *AtExitFn = CGM.CreateRuntimeFunction(AtExitFnTy,
+                                                       "__cxa_atexit");
+
+  llvm::Constant *Handle = CGM.CreateRuntimeVariable(Int8PtrTy,
+                                                     "__dso_handle");
+  llvm::Value *Args[3] = { llvm::ConstantExpr::getBitCast(DtorFn, DtorFnTy),
+                           llvm::ConstantExpr::getBitCast(DeclPtr, Int8PtrTy),
+                           llvm::ConstantExpr::getBitCast(Handle, Int8PtrTy) };
+  Builder.CreateCall(AtExitFn, &Args[0], llvm::array_endof(Args));
+}
+
+void
+CodeGenModule::EmitCXXGlobalVarDeclInitFunc(const VarDecl *D) {
+  const llvm::FunctionType *FTy
+    = llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
+                              false);
+
+  // Create a variable initialization function.
+  llvm::Function *Fn =
+    llvm::Function::Create(FTy, llvm::GlobalValue::InternalLinkage,
+                           "__cxx_global_var_init", &TheModule);
+
+  CodeGenFunction(*this).GenerateCXXGlobalVarDeclInitFunc(Fn, D);
+
+  CXXGlobalInits.push_back(Fn);
+}
+
+void
+CodeGenModule::EmitCXXGlobalInitFunc() {
+  if (CXXGlobalInits.empty())
+    return;
+
+  const llvm::FunctionType *FTy
+    = llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
+                              false);
+
+  // Create our global initialization function.
+  llvm::Function *Fn =
+    llvm::Function::Create(FTy, llvm::GlobalValue::InternalLinkage,
+                           "_GLOBAL__I_a", &TheModule);
+
+  CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn,
+                                                   &CXXGlobalInits[0],
+                                                   CXXGlobalInits.size());
+  AddGlobalCtor(Fn);
+}
+
+void CodeGenModule::AddCXXDtorEntry(llvm::Constant *DtorFn,
+                                    llvm::Constant *Object) {
+  CXXGlobalDtors.push_back(std::make_pair(DtorFn, Object));
+}
+
+void CodeGenModule::EmitCXXGlobalDtorFunc() {
+  if (CXXGlobalDtors.empty())
+    return;
+
+  const llvm::FunctionType *FTy
+    = llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
+                              false);
+
+  // Create our global destructor function.
+  llvm::Function *Fn =
+    llvm::Function::Create(FTy, llvm::GlobalValue::InternalLinkage,
+                           "_GLOBAL__D_a", &TheModule);
+
+  CodeGenFunction(*this).GenerateCXXGlobalDtorFunc(Fn, CXXGlobalDtors);
+  AddGlobalDtor(Fn);
+}
+
+void CodeGenFunction::GenerateCXXGlobalVarDeclInitFunc(llvm::Function *Fn,
+                                                       const VarDecl *D) {
+  StartFunction(GlobalDecl(), getContext().VoidTy, Fn, FunctionArgList(),
+                SourceLocation());
+
+  llvm::Constant *DeclPtr = CGM.GetAddrOfGlobalVar(D);
+  EmitCXXGlobalVarDeclInit(*D, DeclPtr);
+
+  FinishFunction();
+}
+
+void CodeGenFunction::GenerateCXXGlobalInitFunc(llvm::Function *Fn,
+                                                llvm::Constant **Decls,
+                                                unsigned NumDecls) {
+  StartFunction(GlobalDecl(), getContext().VoidTy, Fn, FunctionArgList(),
+                SourceLocation());
+
+  for (unsigned i = 0; i != NumDecls; ++i)
+    Builder.CreateCall(Decls[i]);
+
+  FinishFunction();
+}
+
+void CodeGenFunction::GenerateCXXGlobalDtorFunc(llvm::Function *Fn,
+                const std::vector<std::pair<llvm::Constant*, llvm::Constant*> >
+                                                &DtorsAndObjects) {
+  StartFunction(GlobalDecl(), getContext().VoidTy, Fn, FunctionArgList(),
+                SourceLocation());
+
+  // Emit the dtors, in reverse order from construction.
+  for (unsigned i = 0, e = DtorsAndObjects.size(); i != e; ++i) {
+    llvm::Constant *Callee = DtorsAndObjects[e - i - 1].first;
+    llvm::CallInst *CI = Builder.CreateCall(Callee,
+                                            DtorsAndObjects[e - i - 1].second);
+    // Make sure the call and the callee agree on calling convention.
+    if (llvm::Function *F = dyn_cast<llvm::Function>(Callee))
+      CI->setCallingConv(F->getCallingConv());
+  }
+
+  FinishFunction();
+}
+
+static llvm::Constant *getGuardAcquireFn(CodeGenFunction &CGF) {
+  // int __cxa_guard_acquire(__int64_t *guard_object);
+  
+  const llvm::Type *Int64PtrTy = 
+    llvm::Type::getInt64PtrTy(CGF.getLLVMContext());
+  
+  std::vector<const llvm::Type*> Args(1, Int64PtrTy);
+  
+  const llvm::FunctionType *FTy =
+    llvm::FunctionType::get(CGF.ConvertType(CGF.getContext().IntTy),
+                            Args, /*isVarArg=*/false);
+  
+  return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_guard_acquire");
+}
+
+static llvm::Constant *getGuardReleaseFn(CodeGenFunction &CGF) {
+  // void __cxa_guard_release(__int64_t *guard_object);
+  
+  const llvm::Type *Int64PtrTy = 
+    llvm::Type::getInt64PtrTy(CGF.getLLVMContext());
+  
+  std::vector<const llvm::Type*> Args(1, Int64PtrTy);
+  
+  const llvm::FunctionType *FTy =
+  llvm::FunctionType::get(llvm::Type::getVoidTy(CGF.getLLVMContext()),
+                          Args, /*isVarArg=*/false);
+  
+  return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_guard_release");
+}
+
+static llvm::Constant *getGuardAbortFn(CodeGenFunction &CGF) {
+  // void __cxa_guard_abort(__int64_t *guard_object);
+  
+  const llvm::Type *Int64PtrTy = 
+    llvm::Type::getInt64PtrTy(CGF.getLLVMContext());
+  
+  std::vector<const llvm::Type*> Args(1, Int64PtrTy);
+  
+  const llvm::FunctionType *FTy =
+  llvm::FunctionType::get(llvm::Type::getVoidTy(CGF.getLLVMContext()),
+                          Args, /*isVarArg=*/false);
+  
+  return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_guard_abort");
+}
+
+void
+CodeGenFunction::EmitStaticCXXBlockVarDeclInit(const VarDecl &D,
+                                               llvm::GlobalVariable *GV) {
+  bool ThreadsafeStatics = getContext().getLangOptions().ThreadsafeStatics;
+  
+  llvm::SmallString<256> GuardVName;
+  CGM.getMangleContext().mangleGuardVariable(&D, GuardVName);
+
+  // Create the guard variable.
+  const llvm::Type *Int64Ty = llvm::Type::getInt64Ty(VMContext);
+  llvm::GlobalValue *GuardVariable =
+    new llvm::GlobalVariable(CGM.getModule(), Int64Ty,
+                             false, GV->getLinkage(),
+                             llvm::Constant::getNullValue(Int64Ty),
+                             GuardVName.str());
+
+  // Load the first byte of the guard variable.
+  const llvm::Type *PtrTy
+    = llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext), 0);
+  llvm::Value *V = 
+    Builder.CreateLoad(Builder.CreateBitCast(GuardVariable, PtrTy), "tmp");
+
+  llvm::BasicBlock *InitCheckBlock = createBasicBlock("init.check");
+  llvm::BasicBlock *EndBlock = createBasicBlock("init.end");
+
+  // Check if the first byte of the guard variable is zero.
+  Builder.CreateCondBr(Builder.CreateIsNull(V, "tobool"), 
+                       InitCheckBlock, EndBlock);
+
+  EmitBlock(InitCheckBlock);
+
+  if (ThreadsafeStatics) {
+    // Call __cxa_guard_acquire.
+    V = Builder.CreateCall(getGuardAcquireFn(*this), GuardVariable);
+               
+    llvm::BasicBlock *InitBlock = createBasicBlock("init");
+  
+    Builder.CreateCondBr(Builder.CreateIsNotNull(V, "tobool"),
+                         InitBlock, EndBlock);
+  
+    EmitBlock(InitBlock);
+
+    if (Exceptions) {
+      EHCleanupBlock Cleanup(*this);
+    
+      // Call __cxa_guard_abort.
+      Builder.CreateCall(getGuardAbortFn(*this), GuardVariable);
+    }
+  }
+
+  if (D.getType()->isReferenceType()) {
+    QualType T = D.getType();
+    // We don't want to pass true for IsInitializer here, because a static
+    // reference to a temporary does not extend its lifetime.
+    RValue RV = EmitReferenceBindingToExpr(D.getInit(),
+                                           /*IsInitializer=*/false);
+    EmitStoreOfScalar(RV.getScalarVal(), GV, /*Volatile=*/false, T);
+
+  } else
+    EmitDeclInit(*this, D, GV);
+
+  if (ThreadsafeStatics) {
+    // Call __cxa_guard_release.
+    Builder.CreateCall(getGuardReleaseFn(*this), GuardVariable);
+  } else {
+    llvm::Value *One = 
+      llvm::ConstantInt::get(llvm::Type::getInt8Ty(VMContext), 1);
+    Builder.CreateStore(One, Builder.CreateBitCast(GuardVariable, PtrTy));
+  }
+
+  EmitBlock(EndBlock);
+}
diff --git a/lib/CodeGen/CGException.cpp b/lib/CodeGen/CGException.cpp
new file mode 100644
index 0000000..405df40
--- /dev/null
+++ b/lib/CodeGen/CGException.cpp
@@ -0,0 +1,746 @@
+//===--- CGException.cpp - Emit LLVM Code for C++ exceptions --------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This contains code dealing with C++ exception related code generation.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/StmtCXX.h"
+
+#include "llvm/Intrinsics.h"
+
+#include "CodeGenFunction.h"
+using namespace clang;
+using namespace CodeGen;
+
+static llvm::Constant *getAllocateExceptionFn(CodeGenFunction &CGF) {
+  // void *__cxa_allocate_exception(size_t thrown_size);
+  const llvm::Type *SizeTy = CGF.ConvertType(CGF.getContext().getSizeType());
+  std::vector<const llvm::Type*> Args(1, SizeTy);
+
+  const llvm::FunctionType *FTy =
+  llvm::FunctionType::get(llvm::Type::getInt8PtrTy(CGF.getLLVMContext()),
+                          Args, false);
+
+  return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_allocate_exception");
+}
+
+static llvm::Constant *getFreeExceptionFn(CodeGenFunction &CGF) {
+  // void __cxa_free_exception(void *thrown_exception);
+  const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGF.getLLVMContext());
+  std::vector<const llvm::Type*> Args(1, Int8PtrTy);
+
+  const llvm::FunctionType *FTy =
+  llvm::FunctionType::get(llvm::Type::getVoidTy(CGF.getLLVMContext()),
+                          Args, false);
+
+  return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_free_exception");
+}
+
+static llvm::Constant *getThrowFn(CodeGenFunction &CGF) {
+  // void __cxa_throw(void *thrown_exception, std::type_info *tinfo,
+  //                  void (*dest) (void *));
+
+  const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGF.getLLVMContext());
+  std::vector<const llvm::Type*> Args(3, Int8PtrTy);
+
+  const llvm::FunctionType *FTy =
+    llvm::FunctionType::get(llvm::Type::getVoidTy(CGF.getLLVMContext()),
+                            Args, false);
+
+  return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_throw");
+}
+
+static llvm::Constant *getReThrowFn(CodeGenFunction &CGF) {
+  // void __cxa_rethrow();
+
+  const llvm::FunctionType *FTy =
+    llvm::FunctionType::get(llvm::Type::getVoidTy(CGF.getLLVMContext()), false);
+
+  return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_rethrow");
+}
+
+static llvm::Constant *getBeginCatchFn(CodeGenFunction &CGF) {
+  // void* __cxa_begin_catch();
+
+  const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGF.getLLVMContext());
+  std::vector<const llvm::Type*> Args(1, Int8PtrTy);
+
+  const llvm::FunctionType *FTy =
+    llvm::FunctionType::get(Int8PtrTy, Args, false);
+
+  return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_begin_catch");
+}
+
+static llvm::Constant *getEndCatchFn(CodeGenFunction &CGF) {
+  // void __cxa_end_catch();
+
+  const llvm::FunctionType *FTy =
+    llvm::FunctionType::get(llvm::Type::getVoidTy(CGF.getLLVMContext()), false);
+
+  return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_end_catch");
+}
+
+static llvm::Constant *getUnexpectedFn(CodeGenFunction &CGF) {
+  // void __cxa_call_unexepcted(void *thrown_exception);
+
+  const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGF.getLLVMContext());
+  std::vector<const llvm::Type*> Args(1, Int8PtrTy);
+
+  const llvm::FunctionType *FTy =
+    llvm::FunctionType::get(llvm::Type::getVoidTy(CGF.getLLVMContext()),
+                            Args, false);
+
+  return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_call_unexpected");
+}
+
+static llvm::Constant *getUnwindResumeOrRethrowFn(CodeGenFunction &CGF) {
+  const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGF.getLLVMContext());
+  std::vector<const llvm::Type*> Args(1, Int8PtrTy);
+
+  const llvm::FunctionType *FTy =
+    llvm::FunctionType::get(llvm::Type::getVoidTy(CGF.getLLVMContext()), Args,
+                            false);
+
+  if (CGF.CGM.getLangOptions().SjLjExceptions)
+    return CGF.CGM.CreateRuntimeFunction(FTy, "_Unwind_SjLj_Resume");
+  return CGF.CGM.CreateRuntimeFunction(FTy, "_Unwind_Resume_or_Rethrow");
+}
+
+static llvm::Constant *getTerminateFn(CodeGenFunction &CGF) {
+  // void __terminate();
+
+  const llvm::FunctionType *FTy =
+    llvm::FunctionType::get(llvm::Type::getVoidTy(CGF.getLLVMContext()), false);
+
+  return CGF.CGM.CreateRuntimeFunction(FTy, "_ZSt9terminatev");
+}
+
+// Emits an exception expression into the given location.  This
+// differs from EmitAnyExprToMem only in that, if a final copy-ctor
+// call is required, an exception within that copy ctor causes
+// std::terminate to be invoked.
+static void EmitAnyExprToExn(CodeGenFunction &CGF, const Expr *E, 
+                             llvm::Value *ExnLoc) {
+  // We want to release the allocated exception object if this
+  // expression throws.  We do this by pushing an EH-only cleanup
+  // block which, furthermore, deactivates itself after the expression
+  // is complete.
+  llvm::AllocaInst *ShouldFreeVar =
+    CGF.CreateTempAlloca(llvm::Type::getInt1Ty(CGF.getLLVMContext()),
+                         "should-free-exnobj.var");
+  CGF.InitTempAlloca(ShouldFreeVar,
+                     llvm::ConstantInt::getFalse(CGF.getLLVMContext()));
+
+  // A variable holding the exception pointer.  This is necessary
+  // because the throw expression does not necessarily dominate the
+  // cleanup, for example if it appears in a conditional expression.
+  llvm::AllocaInst *ExnLocVar =
+    CGF.CreateTempAlloca(ExnLoc->getType(), "exnobj.var");
+
+  llvm::BasicBlock *SavedInvokeDest = CGF.getInvokeDest();
+  {
+    CodeGenFunction::EHCleanupBlock Cleanup(CGF);
+    llvm::BasicBlock *FreeBB = CGF.createBasicBlock("free-exnobj");
+    llvm::BasicBlock *DoneBB = CGF.createBasicBlock("free-exnobj.done");
+
+    llvm::Value *ShouldFree = CGF.Builder.CreateLoad(ShouldFreeVar,
+                                                     "should-free-exnobj");
+    CGF.Builder.CreateCondBr(ShouldFree, FreeBB, DoneBB);
+    CGF.EmitBlock(FreeBB);
+    llvm::Value *ExnLocLocal = CGF.Builder.CreateLoad(ExnLocVar, "exnobj");
+    CGF.Builder.CreateCall(getFreeExceptionFn(CGF), ExnLocLocal);
+    CGF.EmitBlock(DoneBB);
+  }
+  llvm::BasicBlock *Cleanup = CGF.getInvokeDest();
+
+  CGF.Builder.CreateStore(ExnLoc, ExnLocVar);
+  CGF.Builder.CreateStore(llvm::ConstantInt::getTrue(CGF.getLLVMContext()),
+                          ShouldFreeVar);
+
+  // __cxa_allocate_exception returns a void*;  we need to cast this
+  // to the appropriate type for the object.
+  const llvm::Type *Ty = CGF.ConvertType(E->getType())->getPointerTo();
+  llvm::Value *TypedExnLoc = CGF.Builder.CreateBitCast(ExnLoc, Ty);
+
+  // FIXME: this isn't quite right!  If there's a final unelided call
+  // to a copy constructor, then according to [except.terminate]p1 we
+  // must call std::terminate() if that constructor throws, because
+  // technically that copy occurs after the exception expression is
+  // evaluated but before the exception is caught.  But the best way
+  // to handle that is to teach EmitAggExpr to do the final copy
+  // differently if it can't be elided.
+  CGF.EmitAnyExprToMem(E, TypedExnLoc, /*Volatile*/ false);
+
+  CGF.Builder.CreateStore(llvm::ConstantInt::getFalse(CGF.getLLVMContext()),
+                          ShouldFreeVar);
+
+  // Pop the cleanup block if it's still the top of the cleanup stack.
+  // Otherwise, temporaries have been created and our cleanup will get
+  // properly removed in time.
+  // TODO: this is not very resilient.
+  if (CGF.getInvokeDest() == Cleanup)
+    CGF.setInvokeDest(SavedInvokeDest);
+}
+
+// CopyObject - Utility to copy an object.  Calls copy constructor as necessary.
+// N is casted to the right type.
+static void CopyObject(CodeGenFunction &CGF, QualType ObjectType,
+                       bool WasPointer, bool WasPointerReference,
+                       llvm::Value *E, llvm::Value *N) {
+  // Store the throw exception in the exception object.
+  if (WasPointer || !CGF.hasAggregateLLVMType(ObjectType)) {
+    llvm::Value *Value = E;
+    if (!WasPointer)
+      Value = CGF.Builder.CreateLoad(Value);
+    const llvm::Type *ValuePtrTy = Value->getType()->getPointerTo(0);
+    if (WasPointerReference) {
+      llvm::Value *Tmp = CGF.CreateTempAlloca(Value->getType(), "catch.param");
+      CGF.Builder.CreateStore(Value, Tmp);
+      Value = Tmp;
+      ValuePtrTy = Value->getType()->getPointerTo(0);
+    }
+    N = CGF.Builder.CreateBitCast(N, ValuePtrTy);
+    CGF.Builder.CreateStore(Value, N);
+  } else {
+    const llvm::Type *Ty = CGF.ConvertType(ObjectType)->getPointerTo(0);
+    const CXXRecordDecl *RD;
+    RD = cast<CXXRecordDecl>(ObjectType->getAs<RecordType>()->getDecl());
+    llvm::Value *This = CGF.Builder.CreateBitCast(N, Ty);
+    if (RD->hasTrivialCopyConstructor()) {
+      CGF.EmitAggregateCopy(This, E, ObjectType);
+    } else if (CXXConstructorDecl *CopyCtor
+               = RD->getCopyConstructor(CGF.getContext(), 0)) {
+      llvm::Value *Src = E;
+
+      // Stolen from EmitClassAggrMemberwiseCopy
+      llvm::Value *Callee = CGF.CGM.GetAddrOfCXXConstructor(CopyCtor,
+                                                            Ctor_Complete);
+      CallArgList CallArgs;
+      CallArgs.push_back(std::make_pair(RValue::get(This),
+                                      CopyCtor->getThisType(CGF.getContext())));
+
+      // Push the Src ptr.
+      CallArgs.push_back(std::make_pair(RValue::get(Src),
+                                        CopyCtor->getParamDecl(0)->getType()));
+
+      const FunctionProtoType *FPT
+        = CopyCtor->getType()->getAs<FunctionProtoType>();
+      CGF.EmitCall(CGF.CGM.getTypes().getFunctionInfo(CallArgs, FPT),
+                   Callee, ReturnValueSlot(), CallArgs, CopyCtor);
+    } else
+      llvm_unreachable("uncopyable object");
+  }
+}
+
+void CodeGenFunction::EmitCXXThrowExpr(const CXXThrowExpr *E) {
+  if (!E->getSubExpr()) {
+    if (getInvokeDest()) {
+      llvm::BasicBlock *Cont = createBasicBlock("invoke.cont");
+      Builder.CreateInvoke(getReThrowFn(*this), Cont, getInvokeDest())
+        ->setDoesNotReturn();
+      EmitBlock(Cont);
+    } else
+      Builder.CreateCall(getReThrowFn(*this))->setDoesNotReturn();
+    Builder.CreateUnreachable();
+
+    // Clear the insertion point to indicate we are in unreachable code.
+    Builder.ClearInsertionPoint();
+    return;
+  }
+
+  QualType ThrowType = E->getSubExpr()->getType();
+
+  // Now allocate the exception object.
+  const llvm::Type *SizeTy = ConvertType(getContext().getSizeType());
+  uint64_t TypeSize = getContext().getTypeSizeInChars(ThrowType).getQuantity();
+
+  llvm::Constant *AllocExceptionFn = getAllocateExceptionFn(*this);
+  llvm::Value *ExceptionPtr =
+    Builder.CreateCall(AllocExceptionFn,
+                       llvm::ConstantInt::get(SizeTy, TypeSize),
+                       "exception");
+  
+  EmitAnyExprToExn(*this, E->getSubExpr(), ExceptionPtr);
+
+  // Now throw the exception.
+  const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(getLLVMContext());
+  llvm::Constant *TypeInfo = CGM.GetAddrOfRTTIDescriptor(ThrowType);
+
+  // The address of the destructor.  If the exception type has a
+  // trivial destructor (or isn't a record), we just pass null.
+  llvm::Constant *Dtor = 0;
+  if (const RecordType *RecordTy = ThrowType->getAs<RecordType>()) {
+    CXXRecordDecl *Record = cast<CXXRecordDecl>(RecordTy->getDecl());
+    if (!Record->hasTrivialDestructor()) {
+      CXXDestructorDecl *DtorD = Record->getDestructor(getContext());
+      Dtor = CGM.GetAddrOfCXXDestructor(DtorD, Dtor_Complete);
+      Dtor = llvm::ConstantExpr::getBitCast(Dtor, Int8PtrTy);
+    }
+  }
+  if (!Dtor) Dtor = llvm::Constant::getNullValue(Int8PtrTy);
+
+  if (getInvokeDest()) {
+    llvm::BasicBlock *Cont = createBasicBlock("invoke.cont");
+    llvm::InvokeInst *ThrowCall =
+      Builder.CreateInvoke3(getThrowFn(*this), Cont, getInvokeDest(),
+                            ExceptionPtr, TypeInfo, Dtor);
+    ThrowCall->setDoesNotReturn();
+    EmitBlock(Cont);
+  } else {
+    llvm::CallInst *ThrowCall =
+      Builder.CreateCall3(getThrowFn(*this), ExceptionPtr, TypeInfo, Dtor);
+    ThrowCall->setDoesNotReturn();
+  }
+  Builder.CreateUnreachable();
+
+  // Clear the insertion point to indicate we are in unreachable code.
+  Builder.ClearInsertionPoint();
+
+  // FIXME: For now, emit a dummy basic block because expr emitters in generally
+  // are not ready to handle emitting expressions at unreachable points.
+  EnsureInsertPoint();
+}
+
+void CodeGenFunction::EmitStartEHSpec(const Decl *D) {
+  if (!Exceptions)
+    return;
+  
+  const FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(D);
+  if (FD == 0)
+    return;
+  const FunctionProtoType *Proto = FD->getType()->getAs<FunctionProtoType>();
+  if (Proto == 0)
+    return;
+
+  assert(!Proto->hasAnyExceptionSpec() && "function with parameter pack");
+
+  if (!Proto->hasExceptionSpec())
+    return;
+
+  llvm::Constant *Personality =
+    CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::getInt32Ty
+                                                      (VMContext),
+                                                      true),
+                              "__gxx_personality_v0");
+  Personality = llvm::ConstantExpr::getBitCast(Personality, PtrToInt8Ty);
+  llvm::Value *llvm_eh_exception =
+    CGM.getIntrinsic(llvm::Intrinsic::eh_exception);
+  llvm::Value *llvm_eh_selector =
+    CGM.getIntrinsic(llvm::Intrinsic::eh_selector);
+  const llvm::IntegerType *Int8Ty;
+  const llvm::PointerType *PtrToInt8Ty;
+  Int8Ty = llvm::Type::getInt8Ty(VMContext);
+  // C string type.  Used in lots of places.
+  PtrToInt8Ty = llvm::PointerType::getUnqual(Int8Ty);
+  llvm::Constant *Null = llvm::ConstantPointerNull::get(PtrToInt8Ty);
+  llvm::SmallVector<llvm::Value*, 8> SelectorArgs;
+
+  llvm::BasicBlock *PrevLandingPad = getInvokeDest();
+  llvm::BasicBlock *EHSpecHandler = createBasicBlock("ehspec.handler");
+  llvm::BasicBlock *Match = createBasicBlock("match");
+  llvm::BasicBlock *Unwind = 0;
+
+  assert(PrevLandingPad == 0 && "EHSpec has invoke context");
+  (void)PrevLandingPad;
+
+  llvm::BasicBlock *Cont = createBasicBlock("cont");
+
+  EmitBranchThroughCleanup(Cont);
+
+  // Emit the statements in the try {} block
+  setInvokeDest(EHSpecHandler);
+
+  EmitBlock(EHSpecHandler);
+  // Exception object
+  llvm::Value *Exc = Builder.CreateCall(llvm_eh_exception, "exc");
+  llvm::Value *RethrowPtr = CreateTempAlloca(Exc->getType(), "_rethrow");
+
+  SelectorArgs.push_back(Exc);
+  SelectorArgs.push_back(Personality);
+  SelectorArgs.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext),
+                                                Proto->getNumExceptions()+1));
+
+  for (unsigned i = 0; i < Proto->getNumExceptions(); ++i) {
+    QualType Ty = Proto->getExceptionType(i);
+    QualType ExceptType
+      = Ty.getNonReferenceType().getUnqualifiedType();
+    llvm::Value *EHType = CGM.GetAddrOfRTTIDescriptor(ExceptType);
+    SelectorArgs.push_back(EHType);
+  }
+  if (Proto->getNumExceptions())
+    SelectorArgs.push_back(Null);
+
+  // Find which handler was matched.
+  llvm::Value *Selector
+    = Builder.CreateCall(llvm_eh_selector, SelectorArgs.begin(),
+                         SelectorArgs.end(), "selector");
+  if (Proto->getNumExceptions()) {
+    Unwind = createBasicBlock("Unwind");
+
+    Builder.CreateStore(Exc, RethrowPtr);
+    Builder.CreateCondBr(Builder.CreateICmpSLT(Selector,
+                                               llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext),
+                                                                      0)),
+                         Match, Unwind);
+
+    EmitBlock(Match);
+  }
+  Builder.CreateCall(getUnexpectedFn(*this), Exc)->setDoesNotReturn();
+  Builder.CreateUnreachable();
+
+  if (Proto->getNumExceptions()) {
+    EmitBlock(Unwind);
+    Builder.CreateCall(getUnwindResumeOrRethrowFn(*this),
+                       Builder.CreateLoad(RethrowPtr));
+    Builder.CreateUnreachable();
+  }
+
+  EmitBlock(Cont);
+}
+
+void CodeGenFunction::EmitEndEHSpec(const Decl *D) {
+  if (!Exceptions)
+    return;
+  
+  const FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(D);
+  if (FD == 0)
+    return;
+  const FunctionProtoType *Proto = FD->getType()->getAs<FunctionProtoType>();
+  if (Proto == 0)
+    return;
+
+  if (!Proto->hasExceptionSpec())
+    return;
+
+  setInvokeDest(0);
+}
+
+void CodeGenFunction::EmitCXXTryStmt(const CXXTryStmt &S) {
+  CXXTryStmtInfo Info = EnterCXXTryStmt(S);
+  EmitStmt(S.getTryBlock());
+  ExitCXXTryStmt(S, Info);
+}
+
+CodeGenFunction::CXXTryStmtInfo
+CodeGenFunction::EnterCXXTryStmt(const CXXTryStmt &S) {
+  CXXTryStmtInfo Info;
+  Info.SavedLandingPad = getInvokeDest();
+  Info.HandlerBlock = createBasicBlock("try.handler");
+  Info.FinallyBlock = createBasicBlock("finally");
+
+  PushCleanupBlock(Info.FinallyBlock);
+  setInvokeDest(Info.HandlerBlock);
+
+  return Info;
+}
+
+void CodeGenFunction::ExitCXXTryStmt(const CXXTryStmt &S,
+                                     CXXTryStmtInfo TryInfo) {
+  // Pointer to the personality function
+  llvm::Constant *Personality =
+    CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::getInt32Ty
+                                                      (VMContext),
+                                                      true),
+                              "__gxx_personality_v0");
+  Personality = llvm::ConstantExpr::getBitCast(Personality, PtrToInt8Ty);
+  llvm::Value *llvm_eh_exception =
+    CGM.getIntrinsic(llvm::Intrinsic::eh_exception);
+  llvm::Value *llvm_eh_selector =
+    CGM.getIntrinsic(llvm::Intrinsic::eh_selector);
+
+  llvm::BasicBlock *PrevLandingPad = TryInfo.SavedLandingPad;
+  llvm::BasicBlock *TryHandler = TryInfo.HandlerBlock;
+  llvm::BasicBlock *FinallyBlock = TryInfo.FinallyBlock;
+  llvm::BasicBlock *FinallyRethrow = createBasicBlock("finally.throw");
+  llvm::BasicBlock *FinallyEnd = createBasicBlock("finally.end");
+
+  // Jump to end if there is no exception
+  EmitBranchThroughCleanup(FinallyEnd);
+
+  llvm::BasicBlock *TerminateHandler = getTerminateHandler();
+
+  // Emit the handlers
+  EmitBlock(TryHandler);
+
+  const llvm::IntegerType *Int8Ty;
+  const llvm::PointerType *PtrToInt8Ty;
+  Int8Ty = llvm::Type::getInt8Ty(VMContext);
+  // C string type.  Used in lots of places.
+  PtrToInt8Ty = llvm::PointerType::getUnqual(Int8Ty);
+  llvm::Constant *Null = llvm::ConstantPointerNull::get(PtrToInt8Ty);
+  llvm::SmallVector<llvm::Value*, 8> SelectorArgs;
+  llvm::Value *llvm_eh_typeid_for =
+    CGM.getIntrinsic(llvm::Intrinsic::eh_typeid_for);
+  // Exception object
+  llvm::Value *Exc = Builder.CreateCall(llvm_eh_exception, "exc");
+  llvm::Value *RethrowPtr = CreateTempAlloca(Exc->getType(), "_rethrow");
+
+  SelectorArgs.push_back(Exc);
+  SelectorArgs.push_back(Personality);
+
+  bool HasCatchAll = false;
+  for (unsigned i = 0; i<S.getNumHandlers(); ++i) {
+    const CXXCatchStmt *C = S.getHandler(i);
+    VarDecl *CatchParam = C->getExceptionDecl();
+    if (CatchParam) {
+      // C++ [except.handle]p3 indicates that top-level cv-qualifiers
+      // are ignored.
+      QualType CaughtType = C->getCaughtType().getNonReferenceType();
+      llvm::Value *EHTypeInfo
+        = CGM.GetAddrOfRTTIDescriptor(CaughtType.getUnqualifiedType());
+      SelectorArgs.push_back(EHTypeInfo);
+    } else {
+      // null indicates catch all
+      SelectorArgs.push_back(Null);
+      HasCatchAll = true;
+    }
+  }
+
+  // We use a cleanup unless there was already a catch all.
+  if (!HasCatchAll) {
+    SelectorArgs.push_back(Null);
+  }
+
+  // Find which handler was matched.
+  llvm::Value *Selector
+    = Builder.CreateCall(llvm_eh_selector, SelectorArgs.begin(),
+                         SelectorArgs.end(), "selector");
+  for (unsigned i = 0; i<S.getNumHandlers(); ++i) {
+    const CXXCatchStmt *C = S.getHandler(i);
+    VarDecl *CatchParam = C->getExceptionDecl();
+    Stmt *CatchBody = C->getHandlerBlock();
+
+    llvm::BasicBlock *Next = 0;
+
+    if (SelectorArgs[i+2] != Null) {
+      llvm::BasicBlock *Match = createBasicBlock("match");
+      Next = createBasicBlock("catch.next");
+      const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(getLLVMContext());
+      llvm::Value *Id
+        = Builder.CreateCall(llvm_eh_typeid_for,
+                             Builder.CreateBitCast(SelectorArgs[i+2],
+                                                   Int8PtrTy));
+      Builder.CreateCondBr(Builder.CreateICmpEQ(Selector, Id),
+                           Match, Next);
+      EmitBlock(Match);
+    }
+
+    llvm::BasicBlock *MatchEnd = createBasicBlock("match.end");
+    llvm::BasicBlock *MatchHandler = createBasicBlock("match.handler");
+
+    PushCleanupBlock(MatchEnd);
+    setInvokeDest(MatchHandler);
+
+    llvm::Value *ExcObject = Builder.CreateCall(getBeginCatchFn(*this), Exc);
+
+    {
+      CleanupScope CatchScope(*this);
+      // Bind the catch parameter if it exists.
+      if (CatchParam) {
+        QualType CatchType = CatchParam->getType().getNonReferenceType();
+        setInvokeDest(TerminateHandler);
+        bool WasPointer = true;
+        bool WasPointerReference = false;
+        CatchType = CGM.getContext().getCanonicalType(CatchType);
+        if (CatchType.getTypePtr()->isPointerType()) {
+          if (isa<ReferenceType>(CatchParam->getType()))
+            WasPointerReference = true;
+        } else {
+          if (!isa<ReferenceType>(CatchParam->getType()))
+            WasPointer = false;
+          CatchType = getContext().getPointerType(CatchType);
+        }
+        ExcObject = Builder.CreateBitCast(ExcObject, ConvertType(CatchType));
+        EmitLocalBlockVarDecl(*CatchParam);
+        // FIXME: we need to do this sooner so that the EH region for the
+        // cleanup doesn't start until after the ctor completes, use a decl
+        // init?
+        CopyObject(*this, CatchParam->getType().getNonReferenceType(),
+                   WasPointer, WasPointerReference, ExcObject,
+                   GetAddrOfLocalVar(CatchParam));
+        setInvokeDest(MatchHandler);
+      }
+
+      EmitStmt(CatchBody);
+    }
+
+    EmitBranchThroughCleanup(FinallyEnd);
+
+    EmitBlock(MatchHandler);
+
+    llvm::Value *Exc = Builder.CreateCall(llvm_eh_exception, "exc");
+    // We are required to emit this call to satisfy LLVM, even
+    // though we don't use the result.
+    llvm::Value *Args[] = {
+      Exc, Personality,
+      llvm::ConstantInt::getNullValue(llvm::Type::getInt32Ty(VMContext))
+    };
+    Builder.CreateCall(llvm_eh_selector, &Args[0], llvm::array_endof(Args));
+    Builder.CreateStore(Exc, RethrowPtr);
+    EmitBranchThroughCleanup(FinallyRethrow);
+
+    CodeGenFunction::CleanupBlockInfo Info = PopCleanupBlock();
+
+    EmitBlock(MatchEnd);
+
+    llvm::BasicBlock *Cont = createBasicBlock("invoke.cont");
+    Builder.CreateInvoke(getEndCatchFn(*this),
+                         Cont, TerminateHandler,
+                         &Args[0], &Args[0]);
+    EmitBlock(Cont);
+    if (Info.SwitchBlock)
+      EmitBlock(Info.SwitchBlock);
+    if (Info.EndBlock)
+      EmitBlock(Info.EndBlock);
+
+    Exc = Builder.CreateCall(llvm_eh_exception, "exc");
+    Builder.CreateStore(Exc, RethrowPtr);
+    EmitBranchThroughCleanup(FinallyRethrow);
+
+    if (Next)
+      EmitBlock(Next);
+  }
+  if (!HasCatchAll) {
+    Builder.CreateStore(Exc, RethrowPtr);
+    EmitBranchThroughCleanup(FinallyRethrow);
+  }
+
+  CodeGenFunction::CleanupBlockInfo Info = PopCleanupBlock();
+
+  setInvokeDest(PrevLandingPad);
+
+  EmitBlock(FinallyBlock);
+
+  if (Info.SwitchBlock)
+    EmitBlock(Info.SwitchBlock);
+  if (Info.EndBlock)
+    EmitBlock(Info.EndBlock);
+
+  // Branch around the rethrow code.
+  EmitBranch(FinallyEnd);
+
+  EmitBlock(FinallyRethrow);
+  // FIXME: Eventually we can chain the handlers together and just do a call
+  // here.
+  if (getInvokeDest()) {
+    llvm::BasicBlock *Cont = createBasicBlock("invoke.cont");
+    Builder.CreateInvoke(getUnwindResumeOrRethrowFn(*this), Cont,
+                         getInvokeDest(),
+                         Builder.CreateLoad(RethrowPtr));
+    EmitBlock(Cont);
+  } else
+    Builder.CreateCall(getUnwindResumeOrRethrowFn(*this),
+                       Builder.CreateLoad(RethrowPtr));
+
+  Builder.CreateUnreachable();
+
+  EmitBlock(FinallyEnd);
+}
+
+CodeGenFunction::EHCleanupBlock::~EHCleanupBlock() {
+  CGF.setInvokeDest(PreviousInvokeDest);
+
+  llvm::BasicBlock *EndOfCleanup = CGF.Builder.GetInsertBlock();
+
+  // Jump to the beginning of the cleanup.
+  CGF.Builder.SetInsertPoint(CleanupHandler, CleanupHandler->begin());
+ 
+  // The libstdc++ personality function.
+  // TODO: generalize to work with other libraries.
+  llvm::Constant *Personality =
+    CGF.CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::getInt32Ty
+                                                          (CGF.VMContext),
+                                                          true),
+                                  "__gxx_personality_v0");
+  Personality = llvm::ConstantExpr::getBitCast(Personality, CGF.PtrToInt8Ty);
+
+  // %exception = call i8* @llvm.eh.exception()
+  //   Magic intrinsic which tells gives us a handle to the caught
+  //   exception.
+  llvm::Value *llvm_eh_exception =
+    CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_exception);
+  llvm::Value *Exc = CGF.Builder.CreateCall(llvm_eh_exception, "exc");
+
+  llvm::Constant *Null = llvm::ConstantPointerNull::get(CGF.PtrToInt8Ty);
+
+  // %ignored = call i32 @llvm.eh.selector(i8* %exception,
+  //                                       i8* @__gxx_personality_v0,
+  //                                       i8* null)
+  //   Magic intrinsic which tells LLVM that this invoke landing pad is
+  //   just a cleanup block.
+  llvm::Value *Args[] = { Exc, Personality, Null };
+  llvm::Value *llvm_eh_selector =
+    CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_selector);
+  CGF.Builder.CreateCall(llvm_eh_selector, &Args[0], llvm::array_endof(Args));
+
+  // And then we fall through into the code that the user put there.
+  // Jump back to the end of the cleanup.
+  CGF.Builder.SetInsertPoint(EndOfCleanup);
+
+  // Rethrow the exception.
+  if (CGF.getInvokeDest()) {
+    llvm::BasicBlock *Cont = CGF.createBasicBlock("invoke.cont");
+    CGF.Builder.CreateInvoke(getUnwindResumeOrRethrowFn(CGF), Cont,
+                             CGF.getInvokeDest(), Exc);
+    CGF.EmitBlock(Cont);
+  } else
+    CGF.Builder.CreateCall(getUnwindResumeOrRethrowFn(CGF), Exc);
+  CGF.Builder.CreateUnreachable();
+
+  // Resume inserting where we started, but put the new cleanup
+  // handler in place.
+  CGF.Builder.SetInsertPoint(PreviousInsertionBlock);
+  if (CGF.Exceptions)
+    CGF.setInvokeDest(CleanupHandler);
+}
+
+llvm::BasicBlock *CodeGenFunction::getTerminateHandler() {
+  if (TerminateHandler)
+    return TerminateHandler;
+
+  // We don't want to change anything at the current location, so
+  // save it aside and clear the insert point.
+  llvm::BasicBlock *SavedInsertBlock = Builder.GetInsertBlock();
+  llvm::BasicBlock::iterator SavedInsertPoint = Builder.GetInsertPoint();
+  Builder.ClearInsertionPoint();
+
+  llvm::Constant *Personality =
+    CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::getInt32Ty
+                                                      (VMContext),
+                                                      true),
+                              "__gxx_personality_v0");
+  Personality = llvm::ConstantExpr::getBitCast(Personality, PtrToInt8Ty);
+  llvm::Value *llvm_eh_exception =
+    CGM.getIntrinsic(llvm::Intrinsic::eh_exception);
+  llvm::Value *llvm_eh_selector =
+    CGM.getIntrinsic(llvm::Intrinsic::eh_selector);
+
+  // Set up terminate handler
+  TerminateHandler = createBasicBlock("terminate.handler");
+  EmitBlock(TerminateHandler);
+  llvm::Value *Exc = Builder.CreateCall(llvm_eh_exception, "exc");
+  // We are required to emit this call to satisfy LLVM, even
+  // though we don't use the result.
+  llvm::Value *Args[] = {
+    Exc, Personality,
+    llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 1)
+  };
+  Builder.CreateCall(llvm_eh_selector, &Args[0], llvm::array_endof(Args));
+  llvm::CallInst *TerminateCall =
+    Builder.CreateCall(getTerminateFn(*this));
+  TerminateCall->setDoesNotReturn();
+  TerminateCall->setDoesNotThrow();
+  Builder.CreateUnreachable();
+
+  // Restore the saved insertion state.
+  Builder.SetInsertPoint(SavedInsertBlock, SavedInsertPoint);
+
+  return TerminateHandler;
+}
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
new file mode 100644
index 0000000..5c9374d
--- /dev/null
+++ b/lib/CodeGen/CGExpr.cpp
@@ -0,0 +1,1950 @@
+//===--- CGExpr.cpp - Emit LLVM Code from Expressions ---------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This contains code to emit Expr nodes as LLVM code.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CodeGenFunction.h"
+#include "CodeGenModule.h"
+#include "CGCall.h"
+#include "CGRecordLayout.h"
+#include "CGObjCRuntime.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclObjC.h"
+#include "llvm/Intrinsics.h"
+#include "clang/CodeGen/CodeGenOptions.h"
+#include "llvm/Target/TargetData.h"
+using namespace clang;
+using namespace CodeGen;
+
+//===--------------------------------------------------------------------===//
+//                        Miscellaneous Helper Methods
+//===--------------------------------------------------------------------===//
+
+/// CreateTempAlloca - This creates a alloca and inserts it into the entry
+/// block.
+llvm::AllocaInst *CodeGenFunction::CreateTempAlloca(const llvm::Type *Ty,
+                                                    const llvm::Twine &Name) {
+  if (!Builder.isNamePreserving())
+    return new llvm::AllocaInst(Ty, 0, "", AllocaInsertPt);
+  return new llvm::AllocaInst(Ty, 0, Name, AllocaInsertPt);
+}
+
+void CodeGenFunction::InitTempAlloca(llvm::AllocaInst *Var,
+                                     llvm::Value *Init) {
+  llvm::StoreInst *Store = new llvm::StoreInst(Init, Var);
+  llvm::BasicBlock *Block = AllocaInsertPt->getParent();
+  Block->getInstList().insertAfter(&*AllocaInsertPt, Store);
+}
+
+llvm::Value *CodeGenFunction::CreateIRTemp(QualType Ty,
+                                           const llvm::Twine &Name) {
+  llvm::AllocaInst *Alloc = CreateTempAlloca(ConvertType(Ty), Name);
+  // FIXME: Should we prefer the preferred type alignment here?
+  CharUnits Align = getContext().getTypeAlignInChars(Ty);
+  Alloc->setAlignment(Align.getQuantity());
+  return Alloc;
+}
+
+llvm::Value *CodeGenFunction::CreateMemTemp(QualType Ty,
+                                            const llvm::Twine &Name) {
+  llvm::AllocaInst *Alloc = CreateTempAlloca(ConvertTypeForMem(Ty), Name);
+  // FIXME: Should we prefer the preferred type alignment here?
+  CharUnits Align = getContext().getTypeAlignInChars(Ty);
+  Alloc->setAlignment(Align.getQuantity());
+  return Alloc;
+}
+
+/// EvaluateExprAsBool - Perform the usual unary conversions on the specified
+/// expression and compare the result against zero, returning an Int1Ty value.
+llvm::Value *CodeGenFunction::EvaluateExprAsBool(const Expr *E) {
+  QualType BoolTy = getContext().BoolTy;
+  if (E->getType()->isMemberFunctionPointerType()) {
+    LValue LV = EmitAggExprToLValue(E);
+
+    // Get the pointer.
+    llvm::Value *FuncPtr = Builder.CreateStructGEP(LV.getAddress(), 0,
+                                                   "src.ptr");
+    FuncPtr = Builder.CreateLoad(FuncPtr);
+
+    llvm::Value *IsNotNull = 
+      Builder.CreateICmpNE(FuncPtr,
+                            llvm::Constant::getNullValue(FuncPtr->getType()),
+                            "tobool");
+
+    return IsNotNull;
+  }
+  if (!E->getType()->isAnyComplexType())
+    return EmitScalarConversion(EmitScalarExpr(E), E->getType(), BoolTy);
+
+  return EmitComplexToScalarConversion(EmitComplexExpr(E), E->getType(),BoolTy);
+}
+
+/// EmitAnyExpr - Emit code to compute the specified expression which can have
+/// any type.  The result is returned as an RValue struct.  If this is an
+/// aggregate expression, the aggloc/agglocvolatile arguments indicate where the
+/// result should be returned.
+RValue CodeGenFunction::EmitAnyExpr(const Expr *E, llvm::Value *AggLoc,
+                                    bool IsAggLocVolatile, bool IgnoreResult,
+                                    bool IsInitializer) {
+  if (!hasAggregateLLVMType(E->getType()))
+    return RValue::get(EmitScalarExpr(E, IgnoreResult));
+  else if (E->getType()->isAnyComplexType())
+    return RValue::getComplex(EmitComplexExpr(E, false, false,
+                                              IgnoreResult, IgnoreResult));
+
+  EmitAggExpr(E, AggLoc, IsAggLocVolatile, IgnoreResult, IsInitializer);
+  return RValue::getAggregate(AggLoc, IsAggLocVolatile);
+}
+
+/// EmitAnyExprToTemp - Similary to EmitAnyExpr(), however, the result will
+/// always be accessible even if no aggregate location is provided.
+RValue CodeGenFunction::EmitAnyExprToTemp(const Expr *E,
+                                          bool IsAggLocVolatile,
+                                          bool IsInitializer) {
+  llvm::Value *AggLoc = 0;
+
+  if (hasAggregateLLVMType(E->getType()) &&
+      !E->getType()->isAnyComplexType())
+    AggLoc = CreateMemTemp(E->getType(), "agg.tmp");
+  return EmitAnyExpr(E, AggLoc, IsAggLocVolatile, /*IgnoreResult=*/false,
+                     IsInitializer);
+}
+
+/// EmitAnyExprToMem - Evaluate an expression into a given memory
+/// location.
+void CodeGenFunction::EmitAnyExprToMem(const Expr *E,
+                                       llvm::Value *Location,
+                                       bool IsLocationVolatile,
+                                       bool IsInit) {
+  if (E->getType()->isComplexType())
+    EmitComplexExprIntoAddr(E, Location, IsLocationVolatile);
+  else if (hasAggregateLLVMType(E->getType()))
+    EmitAggExpr(E, Location, IsLocationVolatile, /*Ignore*/ false, IsInit);
+  else {
+    RValue RV = RValue::get(EmitScalarExpr(E, /*Ignore*/ false));
+    LValue LV = LValue::MakeAddr(Location, MakeQualifiers(E->getType()));
+    EmitStoreThroughLValue(RV, LV, E->getType());
+  }
+}
+
+RValue CodeGenFunction::EmitReferenceBindingToExpr(const Expr* E,
+                                                   bool IsInitializer) {
+  bool ShouldDestroyTemporaries = false;
+  unsigned OldNumLiveTemporaries = 0;
+
+  if (const CXXDefaultArgExpr *DAE = dyn_cast<CXXDefaultArgExpr>(E))
+    E = DAE->getExpr();
+
+  if (const CXXExprWithTemporaries *TE = dyn_cast<CXXExprWithTemporaries>(E)) {
+    ShouldDestroyTemporaries = true;
+    
+    // Keep track of the current cleanup stack depth.
+    OldNumLiveTemporaries = LiveTemporaries.size();
+    
+    E = TE->getSubExpr();
+  }
+  
+  RValue Val;
+  if (E->isLvalue(getContext()) == Expr::LV_Valid) {
+    // Emit the expr as an lvalue.
+    LValue LV = EmitLValue(E);
+    if (LV.isSimple()) {
+      if (ShouldDestroyTemporaries) {
+        // Pop temporaries.
+        while (LiveTemporaries.size() > OldNumLiveTemporaries)
+          PopCXXTemporary();
+      }
+      
+      return RValue::get(LV.getAddress());
+    }
+    
+    Val = EmitLoadOfLValue(LV, E->getType());
+    
+    if (ShouldDestroyTemporaries) {
+      // Pop temporaries.
+      while (LiveTemporaries.size() > OldNumLiveTemporaries)
+        PopCXXTemporary();
+    }      
+  } else {
+    const CXXBaseSpecifierArray *BasePath = 0;
+    const CXXRecordDecl *DerivedClassDecl = 0;
+    
+    if (const CastExpr *CE = 
+          dyn_cast<CastExpr>(E->IgnoreParenNoopCasts(getContext()))) {
+      if (CE->getCastKind() == CastExpr::CK_DerivedToBase) {
+        E = CE->getSubExpr();
+
+        BasePath = &CE->getBasePath();
+        DerivedClassDecl = 
+          cast<CXXRecordDecl>(E->getType()->getAs<RecordType>()->getDecl());
+      }
+    }
+      
+    Val = EmitAnyExprToTemp(E, /*IsAggLocVolatile=*/false,
+                            IsInitializer);
+
+    if (ShouldDestroyTemporaries) {
+      // Pop temporaries.
+      while (LiveTemporaries.size() > OldNumLiveTemporaries)
+        PopCXXTemporary();
+    }      
+    
+    if (IsInitializer) {
+      // We might have to destroy the temporary variable.
+      if (const RecordType *RT = E->getType()->getAs<RecordType>()) {
+        if (CXXRecordDecl *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
+          if (!ClassDecl->hasTrivialDestructor()) {
+            const CXXDestructorDecl *Dtor =
+              ClassDecl->getDestructor(getContext());
+
+            {
+              DelayedCleanupBlock Scope(*this);
+              EmitCXXDestructorCall(Dtor, Dtor_Complete,
+                                    Val.getAggregateAddr());
+              
+              // Make sure to jump to the exit block.
+              EmitBranch(Scope.getCleanupExitBlock());
+            }
+            if (Exceptions) {
+              EHCleanupBlock Cleanup(*this);
+              EmitCXXDestructorCall(Dtor, Dtor_Complete,
+                                    Val.getAggregateAddr());
+            }
+          }
+        }
+      }
+    }
+    
+    // Check if need to perform the derived-to-base cast.
+    if (BasePath) {
+      llvm::Value *Derived = Val.getAggregateAddr();
+      llvm::Value *Base = 
+        GetAddressOfBaseClass(Derived, DerivedClassDecl, *BasePath, 
+                              /*NullCheckValue=*/false);
+      return RValue::get(Base);
+    }
+  }
+
+  if (Val.isAggregate()) {
+    Val = RValue::get(Val.getAggregateAddr());
+  } else {
+    // Create a temporary variable that we can bind the reference to.
+    llvm::Value *Temp = CreateMemTemp(E->getType(), "reftmp");
+    if (Val.isScalar())
+      EmitStoreOfScalar(Val.getScalarVal(), Temp, false, E->getType());
+    else
+      StoreComplexToAddr(Val.getComplexVal(), Temp, false);
+    Val = RValue::get(Temp);
+  }
+
+  return Val;
+}
+
+
+/// getAccessedFieldNo - Given an encoded value and a result number, return the
+/// input field number being accessed.
+unsigned CodeGenFunction::getAccessedFieldNo(unsigned Idx,
+                                             const llvm::Constant *Elts) {
+  if (isa<llvm::ConstantAggregateZero>(Elts))
+    return 0;
+
+  return cast<llvm::ConstantInt>(Elts->getOperand(Idx))->getZExtValue();
+}
+
+void CodeGenFunction::EmitCheck(llvm::Value *Address, unsigned Size) {
+  if (!CatchUndefined)
+    return;
+
+  const llvm::Type *Size_tTy
+    = llvm::IntegerType::get(VMContext, LLVMPointerWidth);
+  Address = Builder.CreateBitCast(Address, PtrToInt8Ty);
+
+  llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::objectsize, &Size_tTy, 1);
+  const llvm::IntegerType *Int1Ty = llvm::IntegerType::get(VMContext, 1);
+
+  // In time, people may want to control this and use a 1 here.
+  llvm::Value *Arg = llvm::ConstantInt::get(Int1Ty, 0);
+  llvm::Value *C = Builder.CreateCall2(F, Address, Arg);
+  llvm::BasicBlock *Cont = createBasicBlock();
+  llvm::BasicBlock *Check = createBasicBlock();
+  llvm::Value *NegativeOne = llvm::ConstantInt::get(Size_tTy, -1ULL);
+  Builder.CreateCondBr(Builder.CreateICmpEQ(C, NegativeOne), Cont, Check);
+    
+  EmitBlock(Check);
+  Builder.CreateCondBr(Builder.CreateICmpUGE(C,
+                                        llvm::ConstantInt::get(Size_tTy, Size)),
+                       Cont, getTrapBB());
+  EmitBlock(Cont);
+}
+
+
+llvm::Value *CodeGenFunction::
+EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
+                        bool isInc, bool isPre) {
+  QualType ValTy = E->getSubExpr()->getType();
+  llvm::Value *InVal = EmitLoadOfLValue(LV, ValTy).getScalarVal();
+  
+  int AmountVal = isInc ? 1 : -1;
+  
+  if (ValTy->isPointerType() &&
+      ValTy->getAs<PointerType>()->isVariableArrayType()) {
+    // The amount of the addition/subtraction needs to account for the VLA size
+    ErrorUnsupported(E, "VLA pointer inc/dec");
+  }
+  
+  llvm::Value *NextVal;
+  if (const llvm::PointerType *PT =
+      dyn_cast<llvm::PointerType>(InVal->getType())) {
+    llvm::Constant *Inc =
+    llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), AmountVal);
+    if (!isa<llvm::FunctionType>(PT->getElementType())) {
+      QualType PTEE = ValTy->getPointeeType();
+      if (const ObjCInterfaceType *OIT =
+          dyn_cast<ObjCInterfaceType>(PTEE)) {
+        // Handle interface types, which are not represented with a concrete
+        // type.
+        int size = getContext().getTypeSize(OIT) / 8;
+        if (!isInc)
+          size = -size;
+        Inc = llvm::ConstantInt::get(Inc->getType(), size);
+        const llvm::Type *i8Ty = llvm::Type::getInt8PtrTy(VMContext);
+        InVal = Builder.CreateBitCast(InVal, i8Ty);
+        NextVal = Builder.CreateGEP(InVal, Inc, "add.ptr");
+        llvm::Value *lhs = LV.getAddress();
+        lhs = Builder.CreateBitCast(lhs, llvm::PointerType::getUnqual(i8Ty));
+        LV = LValue::MakeAddr(lhs, MakeQualifiers(ValTy));
+      } else
+        NextVal = Builder.CreateInBoundsGEP(InVal, Inc, "ptrincdec");
+    } else {
+      const llvm::Type *i8Ty = llvm::Type::getInt8PtrTy(VMContext);
+      NextVal = Builder.CreateBitCast(InVal, i8Ty, "tmp");
+      NextVal = Builder.CreateGEP(NextVal, Inc, "ptrincdec");
+      NextVal = Builder.CreateBitCast(NextVal, InVal->getType());
+    }
+  } else if (InVal->getType() == llvm::Type::getInt1Ty(VMContext) && isInc) {
+    // Bool++ is an interesting case, due to promotion rules, we get:
+    // Bool++ -> Bool = Bool+1 -> Bool = (int)Bool+1 ->
+    // Bool = ((int)Bool+1) != 0
+    // An interesting aspect of this is that increment is always true.
+    // Decrement does not have this property.
+    NextVal = llvm::ConstantInt::getTrue(VMContext);
+  } else if (isa<llvm::IntegerType>(InVal->getType())) {
+    NextVal = llvm::ConstantInt::get(InVal->getType(), AmountVal);
+    
+    // Signed integer overflow is undefined behavior.
+    if (ValTy->isSignedIntegerType())
+      NextVal = Builder.CreateNSWAdd(InVal, NextVal, isInc ? "inc" : "dec");
+    else
+      NextVal = Builder.CreateAdd(InVal, NextVal, isInc ? "inc" : "dec");
+  } else {
+    // Add the inc/dec to the real part.
+    if (InVal->getType()->isFloatTy())
+      NextVal =
+      llvm::ConstantFP::get(VMContext,
+                            llvm::APFloat(static_cast<float>(AmountVal)));
+    else if (InVal->getType()->isDoubleTy())
+      NextVal =
+      llvm::ConstantFP::get(VMContext,
+                            llvm::APFloat(static_cast<double>(AmountVal)));
+    else {
+      llvm::APFloat F(static_cast<float>(AmountVal));
+      bool ignored;
+      F.convert(Target.getLongDoubleFormat(), llvm::APFloat::rmTowardZero,
+                &ignored);
+      NextVal = llvm::ConstantFP::get(VMContext, F);
+    }
+    NextVal = Builder.CreateFAdd(InVal, NextVal, isInc ? "inc" : "dec");
+  }
+  
+  // Store the updated result through the lvalue.
+  if (LV.isBitField())
+    EmitStoreThroughBitfieldLValue(RValue::get(NextVal), LV, ValTy, &NextVal);
+  else
+    EmitStoreThroughLValue(RValue::get(NextVal), LV, ValTy);
+  
+  // If this is a postinc, return the value read from memory, otherwise use the
+  // updated value.
+  return isPre ? NextVal : InVal;
+}
+
+
+CodeGenFunction::ComplexPairTy CodeGenFunction::
+EmitComplexPrePostIncDec(const UnaryOperator *E, LValue LV,
+                         bool isInc, bool isPre) {
+  ComplexPairTy InVal = LoadComplexFromAddr(LV.getAddress(),
+                                            LV.isVolatileQualified());
+  
+  llvm::Value *NextVal;
+  if (isa<llvm::IntegerType>(InVal.first->getType())) {
+    uint64_t AmountVal = isInc ? 1 : -1;
+    NextVal = llvm::ConstantInt::get(InVal.first->getType(), AmountVal, true);
+    
+    // Add the inc/dec to the real part.
+    NextVal = Builder.CreateAdd(InVal.first, NextVal, isInc ? "inc" : "dec");
+  } else {
+    QualType ElemTy = E->getType()->getAs<ComplexType>()->getElementType();
+    llvm::APFloat FVal(getContext().getFloatTypeSemantics(ElemTy), 1);
+    if (!isInc)
+      FVal.changeSign();
+    NextVal = llvm::ConstantFP::get(getLLVMContext(), FVal);
+    
+    // Add the inc/dec to the real part.
+    NextVal = Builder.CreateFAdd(InVal.first, NextVal, isInc ? "inc" : "dec");
+  }
+  
+  ComplexPairTy IncVal(NextVal, InVal.second);
+  
+  // Store the updated result through the lvalue.
+  StoreComplexToAddr(IncVal, LV.getAddress(), LV.isVolatileQualified());
+  
+  // If this is a postinc, return the value read from memory, otherwise use the
+  // updated value.
+  return isPre ? IncVal : InVal;
+}
+
+
+//===----------------------------------------------------------------------===//
+//                         LValue Expression Emission
+//===----------------------------------------------------------------------===//
+
+RValue CodeGenFunction::GetUndefRValue(QualType Ty) {
+  if (Ty->isVoidType())
+    return RValue::get(0);
+  
+  if (const ComplexType *CTy = Ty->getAs<ComplexType>()) {
+    const llvm::Type *EltTy = ConvertType(CTy->getElementType());
+    llvm::Value *U = llvm::UndefValue::get(EltTy);
+    return RValue::getComplex(std::make_pair(U, U));
+  }
+  
+  if (hasAggregateLLVMType(Ty)) {
+    const llvm::Type *LTy = llvm::PointerType::getUnqual(ConvertType(Ty));
+    return RValue::getAggregate(llvm::UndefValue::get(LTy));
+  }
+  
+  return RValue::get(llvm::UndefValue::get(ConvertType(Ty)));
+}
+
+RValue CodeGenFunction::EmitUnsupportedRValue(const Expr *E,
+                                              const char *Name) {
+  ErrorUnsupported(E, Name);
+  return GetUndefRValue(E->getType());
+}
+
+LValue CodeGenFunction::EmitUnsupportedLValue(const Expr *E,
+                                              const char *Name) {
+  ErrorUnsupported(E, Name);
+  llvm::Type *Ty = llvm::PointerType::getUnqual(ConvertType(E->getType()));
+  return LValue::MakeAddr(llvm::UndefValue::get(Ty),
+                          MakeQualifiers(E->getType()));
+}
+
+LValue CodeGenFunction::EmitCheckedLValue(const Expr *E) {
+  LValue LV = EmitLValue(E);
+  if (!isa<DeclRefExpr>(E) && !LV.isBitField() && LV.isSimple())
+    EmitCheck(LV.getAddress(), getContext().getTypeSize(E->getType()) / 8);
+  return LV;
+}
+
+/// EmitLValue - Emit code to compute a designator that specifies the location
+/// of the expression.
+///
+/// This can return one of two things: a simple address or a bitfield reference.
+/// In either case, the LLVM Value* in the LValue structure is guaranteed to be
+/// an LLVM pointer type.
+///
+/// If this returns a bitfield reference, nothing about the pointee type of the
+/// LLVM value is known: For example, it may not be a pointer to an integer.
+///
+/// If this returns a normal address, and if the lvalue's C type is fixed size,
+/// this method guarantees that the returned pointer type will point to an LLVM
+/// type of the same size of the lvalue's type.  If the lvalue has a variable
+/// length type, this is not possible.
+///
+LValue CodeGenFunction::EmitLValue(const Expr *E) {
+  switch (E->getStmtClass()) {
+  default: return EmitUnsupportedLValue(E, "l-value expression");
+
+  case Expr::ObjCIsaExprClass:
+    return EmitObjCIsaExpr(cast<ObjCIsaExpr>(E));
+  case Expr::BinaryOperatorClass:
+    return EmitBinaryOperatorLValue(cast<BinaryOperator>(E));
+  case Expr::CompoundAssignOperatorClass:
+    return EmitCompoundAssignOperatorLValue(cast<CompoundAssignOperator>(E));
+  case Expr::CallExprClass:
+  case Expr::CXXMemberCallExprClass:
+  case Expr::CXXOperatorCallExprClass:
+    return EmitCallExprLValue(cast<CallExpr>(E));
+  case Expr::VAArgExprClass:
+    return EmitVAArgExprLValue(cast<VAArgExpr>(E));
+  case Expr::DeclRefExprClass:
+    return EmitDeclRefLValue(cast<DeclRefExpr>(E));
+  case Expr::ParenExprClass:return EmitLValue(cast<ParenExpr>(E)->getSubExpr());
+  case Expr::PredefinedExprClass:
+    return EmitPredefinedLValue(cast<PredefinedExpr>(E));
+  case Expr::StringLiteralClass:
+    return EmitStringLiteralLValue(cast<StringLiteral>(E));
+  case Expr::ObjCEncodeExprClass:
+    return EmitObjCEncodeExprLValue(cast<ObjCEncodeExpr>(E));
+
+  case Expr::BlockDeclRefExprClass:
+    return EmitBlockDeclRefLValue(cast<BlockDeclRefExpr>(E));
+
+  case Expr::CXXTemporaryObjectExprClass:
+  case Expr::CXXConstructExprClass:
+    return EmitCXXConstructLValue(cast<CXXConstructExpr>(E));
+  case Expr::CXXBindTemporaryExprClass:
+    return EmitCXXBindTemporaryLValue(cast<CXXBindTemporaryExpr>(E));
+  case Expr::CXXExprWithTemporariesClass:
+    return EmitCXXExprWithTemporariesLValue(cast<CXXExprWithTemporaries>(E));
+  case Expr::CXXZeroInitValueExprClass:
+    return EmitNullInitializationLValue(cast<CXXZeroInitValueExpr>(E));
+  case Expr::CXXDefaultArgExprClass:
+    return EmitLValue(cast<CXXDefaultArgExpr>(E)->getExpr());
+  case Expr::CXXTypeidExprClass:
+    return EmitCXXTypeidLValue(cast<CXXTypeidExpr>(E));
+
+  case Expr::ObjCMessageExprClass:
+    return EmitObjCMessageExprLValue(cast<ObjCMessageExpr>(E));
+  case Expr::ObjCIvarRefExprClass:
+    return EmitObjCIvarRefLValue(cast<ObjCIvarRefExpr>(E));
+  case Expr::ObjCPropertyRefExprClass:
+    return EmitObjCPropertyRefLValue(cast<ObjCPropertyRefExpr>(E));
+  case Expr::ObjCImplicitSetterGetterRefExprClass:
+    return EmitObjCKVCRefLValue(cast<ObjCImplicitSetterGetterRefExpr>(E));
+  case Expr::ObjCSuperExprClass:
+    return EmitObjCSuperExprLValue(cast<ObjCSuperExpr>(E));
+
+  case Expr::StmtExprClass:
+    return EmitStmtExprLValue(cast<StmtExpr>(E));
+  case Expr::UnaryOperatorClass:
+    return EmitUnaryOpLValue(cast<UnaryOperator>(E));
+  case Expr::ArraySubscriptExprClass:
+    return EmitArraySubscriptExpr(cast<ArraySubscriptExpr>(E));
+  case Expr::ExtVectorElementExprClass:
+    return EmitExtVectorElementExpr(cast<ExtVectorElementExpr>(E));
+  case Expr::MemberExprClass:
+    return EmitMemberExpr(cast<MemberExpr>(E));
+  case Expr::CompoundLiteralExprClass:
+    return EmitCompoundLiteralLValue(cast<CompoundLiteralExpr>(E));
+  case Expr::ConditionalOperatorClass:
+    return EmitConditionalOperatorLValue(cast<ConditionalOperator>(E));
+  case Expr::ChooseExprClass:
+    return EmitLValue(cast<ChooseExpr>(E)->getChosenSubExpr(getContext()));
+  case Expr::ImplicitCastExprClass:
+  case Expr::CStyleCastExprClass:
+  case Expr::CXXFunctionalCastExprClass:
+  case Expr::CXXStaticCastExprClass:
+  case Expr::CXXDynamicCastExprClass:
+  case Expr::CXXReinterpretCastExprClass:
+  case Expr::CXXConstCastExprClass:
+    return EmitCastLValue(cast<CastExpr>(E));
+  }
+}
+
+llvm::Value *CodeGenFunction::EmitLoadOfScalar(llvm::Value *Addr, bool Volatile,
+                                               QualType Ty) {
+  llvm::LoadInst *Load = Builder.CreateLoad(Addr, "tmp");
+  if (Volatile)
+    Load->setVolatile(true);
+
+  // Bool can have different representation in memory than in registers.
+  llvm::Value *V = Load;
+  if (Ty->isBooleanType())
+    if (V->getType() != llvm::Type::getInt1Ty(VMContext))
+      V = Builder.CreateTrunc(V, llvm::Type::getInt1Ty(VMContext), "tobool");
+
+  return V;
+}
+
+void CodeGenFunction::EmitStoreOfScalar(llvm::Value *Value, llvm::Value *Addr,
+                                        bool Volatile, QualType Ty) {
+
+  if (Ty->isBooleanType()) {
+    // Bool can have different representation in memory than in registers.
+    const llvm::PointerType *DstPtr = cast<llvm::PointerType>(Addr->getType());
+    Value = Builder.CreateIntCast(Value, DstPtr->getElementType(), false);
+  }
+  Builder.CreateStore(Value, Addr, Volatile);
+}
+
+/// EmitLoadOfLValue - Given an expression that represents a value lvalue, this
+/// method emits the address of the lvalue, then loads the result as an rvalue,
+/// returning the rvalue.
+RValue CodeGenFunction::EmitLoadOfLValue(LValue LV, QualType ExprType) {
+  if (LV.isObjCWeak()) {
+    // load of a __weak object.
+    llvm::Value *AddrWeakObj = LV.getAddress();
+    return RValue::get(CGM.getObjCRuntime().EmitObjCWeakRead(*this,
+                                                             AddrWeakObj));
+  }
+
+  if (LV.isSimple()) {
+    llvm::Value *Ptr = LV.getAddress();
+    const llvm::Type *EltTy =
+      cast<llvm::PointerType>(Ptr->getType())->getElementType();
+
+    // Simple scalar l-value.
+    //
+    // FIXME: We shouldn't have to use isSingleValueType here.
+    if (EltTy->isSingleValueType())
+      return RValue::get(EmitLoadOfScalar(Ptr, LV.isVolatileQualified(),
+                                          ExprType));
+
+    assert(ExprType->isFunctionType() && "Unknown scalar value");
+    return RValue::get(Ptr);
+  }
+
+  if (LV.isVectorElt()) {
+    llvm::Value *Vec = Builder.CreateLoad(LV.getVectorAddr(),
+                                          LV.isVolatileQualified(), "tmp");
+    return RValue::get(Builder.CreateExtractElement(Vec, LV.getVectorIdx(),
+                                                    "vecext"));
+  }
+
+  // If this is a reference to a subset of the elements of a vector, either
+  // shuffle the input or extract/insert them as appropriate.
+  if (LV.isExtVectorElt())
+    return EmitLoadOfExtVectorElementLValue(LV, ExprType);
+
+  if (LV.isBitField())
+    return EmitLoadOfBitfieldLValue(LV, ExprType);
+
+  if (LV.isPropertyRef())
+    return EmitLoadOfPropertyRefLValue(LV, ExprType);
+
+  assert(LV.isKVCRef() && "Unknown LValue type!");
+  return EmitLoadOfKVCRefLValue(LV, ExprType);
+}
+
+RValue CodeGenFunction::EmitLoadOfBitfieldLValue(LValue LV,
+                                                 QualType ExprType) {
+  const CGBitFieldInfo &Info = LV.getBitFieldInfo();
+
+  // Get the output type.
+  const llvm::Type *ResLTy = ConvertType(ExprType);
+  unsigned ResSizeInBits = CGM.getTargetData().getTypeSizeInBits(ResLTy);
+
+  // Compute the result as an OR of all of the individual component accesses.
+  llvm::Value *Res = 0;
+  for (unsigned i = 0, e = Info.getNumComponents(); i != e; ++i) {
+    const CGBitFieldInfo::AccessInfo &AI = Info.getComponent(i);
+
+    // Get the field pointer.
+    llvm::Value *Ptr = LV.getBitFieldBaseAddr();
+
+    // Only offset by the field index if used, so that incoming values are not
+    // required to be structures.
+    if (AI.FieldIndex)
+      Ptr = Builder.CreateStructGEP(Ptr, AI.FieldIndex, "bf.field");
+
+    // Offset by the byte offset, if used.
+    if (AI.FieldByteOffset) {
+      const llvm::Type *i8PTy = llvm::Type::getInt8PtrTy(VMContext);
+      Ptr = Builder.CreateBitCast(Ptr, i8PTy);
+      Ptr = Builder.CreateConstGEP1_32(Ptr, AI.FieldByteOffset,"bf.field.offs");
+    }
+
+    // Cast to the access type.
+    const llvm::Type *PTy = llvm::Type::getIntNPtrTy(VMContext, AI.AccessWidth,
+                                                    ExprType.getAddressSpace());
+    Ptr = Builder.CreateBitCast(Ptr, PTy);
+
+    // Perform the load.
+    llvm::LoadInst *Load = Builder.CreateLoad(Ptr, LV.isVolatileQualified());
+    if (AI.AccessAlignment)
+      Load->setAlignment(AI.AccessAlignment);
+
+    // Shift out unused low bits and mask out unused high bits.
+    llvm::Value *Val = Load;
+    if (AI.FieldBitStart)
+      Val = Builder.CreateLShr(Load, AI.FieldBitStart);
+    Val = Builder.CreateAnd(Val, llvm::APInt::getLowBitsSet(AI.AccessWidth,
+                                                            AI.TargetBitWidth),
+                            "bf.clear");
+
+    // Extend or truncate to the target size.
+    if (AI.AccessWidth < ResSizeInBits)
+      Val = Builder.CreateZExt(Val, ResLTy);
+    else if (AI.AccessWidth > ResSizeInBits)
+      Val = Builder.CreateTrunc(Val, ResLTy);
+
+    // Shift into place, and OR into the result.
+    if (AI.TargetBitOffset)
+      Val = Builder.CreateShl(Val, AI.TargetBitOffset);
+    Res = Res ? Builder.CreateOr(Res, Val) : Val;
+  }
+
+  // If the bit-field is signed, perform the sign-extension.
+  //
+  // FIXME: This can easily be folded into the load of the high bits, which
+  // could also eliminate the mask of high bits in some situations.
+  if (Info.isSigned()) {
+    unsigned ExtraBits = ResSizeInBits - Info.getSize();
+    if (ExtraBits)
+      Res = Builder.CreateAShr(Builder.CreateShl(Res, ExtraBits),
+                               ExtraBits, "bf.val.sext");
+  }
+
+  return RValue::get(Res);
+}
+
+RValue CodeGenFunction::EmitLoadOfPropertyRefLValue(LValue LV,
+                                                    QualType ExprType) {
+  return EmitObjCPropertyGet(LV.getPropertyRefExpr());
+}
+
+RValue CodeGenFunction::EmitLoadOfKVCRefLValue(LValue LV,
+                                               QualType ExprType) {
+  return EmitObjCPropertyGet(LV.getKVCRefExpr());
+}
+
+// If this is a reference to a subset of the elements of a vector, create an
+// appropriate shufflevector.
+RValue CodeGenFunction::EmitLoadOfExtVectorElementLValue(LValue LV,
+                                                         QualType ExprType) {
+  llvm::Value *Vec = Builder.CreateLoad(LV.getExtVectorAddr(),
+                                        LV.isVolatileQualified(), "tmp");
+
+  const llvm::Constant *Elts = LV.getExtVectorElts();
+
+  // If the result of the expression is a non-vector type, we must be extracting
+  // a single element.  Just codegen as an extractelement.
+  const VectorType *ExprVT = ExprType->getAs<VectorType>();
+  if (!ExprVT) {
+    unsigned InIdx = getAccessedFieldNo(0, Elts);
+    llvm::Value *Elt = llvm::ConstantInt::get(
+                                      llvm::Type::getInt32Ty(VMContext), InIdx);
+    return RValue::get(Builder.CreateExtractElement(Vec, Elt, "tmp"));
+  }
+
+  // Always use shuffle vector to try to retain the original program structure
+  unsigned NumResultElts = ExprVT->getNumElements();
+
+  llvm::SmallVector<llvm::Constant*, 4> Mask;
+  for (unsigned i = 0; i != NumResultElts; ++i) {
+    unsigned InIdx = getAccessedFieldNo(i, Elts);
+    Mask.push_back(llvm::ConstantInt::get(
+                                     llvm::Type::getInt32Ty(VMContext), InIdx));
+  }
+
+  llvm::Value *MaskV = llvm::ConstantVector::get(&Mask[0], Mask.size());
+  Vec = Builder.CreateShuffleVector(Vec,
+                                    llvm::UndefValue::get(Vec->getType()),
+                                    MaskV, "tmp");
+  return RValue::get(Vec);
+}
+
+
+
+/// EmitStoreThroughLValue - Store the specified rvalue into the specified
+/// lvalue, where both are guaranteed to the have the same type, and that type
+/// is 'Ty'.
+void CodeGenFunction::EmitStoreThroughLValue(RValue Src, LValue Dst,
+                                             QualType Ty) {
+  if (!Dst.isSimple()) {
+    if (Dst.isVectorElt()) {
+      // Read/modify/write the vector, inserting the new element.
+      llvm::Value *Vec = Builder.CreateLoad(Dst.getVectorAddr(),
+                                            Dst.isVolatileQualified(), "tmp");
+      Vec = Builder.CreateInsertElement(Vec, Src.getScalarVal(),
+                                        Dst.getVectorIdx(), "vecins");
+      Builder.CreateStore(Vec, Dst.getVectorAddr(),Dst.isVolatileQualified());
+      return;
+    }
+
+    // If this is an update of extended vector elements, insert them as
+    // appropriate.
+    if (Dst.isExtVectorElt())
+      return EmitStoreThroughExtVectorComponentLValue(Src, Dst, Ty);
+
+    if (Dst.isBitField())
+      return EmitStoreThroughBitfieldLValue(Src, Dst, Ty);
+
+    if (Dst.isPropertyRef())
+      return EmitStoreThroughPropertyRefLValue(Src, Dst, Ty);
+
+    assert(Dst.isKVCRef() && "Unknown LValue type");
+    return EmitStoreThroughKVCRefLValue(Src, Dst, Ty);
+  }
+
+  if (Dst.isObjCWeak() && !Dst.isNonGC()) {
+    // load of a __weak object.
+    llvm::Value *LvalueDst = Dst.getAddress();
+    llvm::Value *src = Src.getScalarVal();
+     CGM.getObjCRuntime().EmitObjCWeakAssign(*this, src, LvalueDst);
+    return;
+  }
+
+  if (Dst.isObjCStrong() && !Dst.isNonGC()) {
+    // load of a __strong object.
+    llvm::Value *LvalueDst = Dst.getAddress();
+    llvm::Value *src = Src.getScalarVal();
+    if (Dst.isObjCIvar()) {
+      assert(Dst.getBaseIvarExp() && "BaseIvarExp is NULL");
+      const llvm::Type *ResultType = ConvertType(getContext().LongTy);
+      llvm::Value *RHS = EmitScalarExpr(Dst.getBaseIvarExp());
+      llvm::Value *dst = RHS;
+      RHS = Builder.CreatePtrToInt(RHS, ResultType, "sub.ptr.rhs.cast");
+      llvm::Value *LHS = 
+        Builder.CreatePtrToInt(LvalueDst, ResultType, "sub.ptr.lhs.cast");
+      llvm::Value *BytesBetween = Builder.CreateSub(LHS, RHS, "ivar.offset");
+      CGM.getObjCRuntime().EmitObjCIvarAssign(*this, src, dst,
+                                              BytesBetween);
+    } else if (Dst.isGlobalObjCRef())
+      CGM.getObjCRuntime().EmitObjCGlobalAssign(*this, src, LvalueDst);
+    else
+      CGM.getObjCRuntime().EmitObjCStrongCastAssign(*this, src, LvalueDst);
+    return;
+  }
+
+  assert(Src.isScalar() && "Can't emit an agg store with this method");
+  EmitStoreOfScalar(Src.getScalarVal(), Dst.getAddress(),
+                    Dst.isVolatileQualified(), Ty);
+}
+
+void CodeGenFunction::EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst,
+                                                     QualType Ty,
+                                                     llvm::Value **Result) {
+  const CGBitFieldInfo &Info = Dst.getBitFieldInfo();
+
+  // Get the output type.
+  const llvm::Type *ResLTy = ConvertTypeForMem(Ty);
+  unsigned ResSizeInBits = CGM.getTargetData().getTypeSizeInBits(ResLTy);
+
+  // Get the source value, truncated to the width of the bit-field.
+  llvm::Value *SrcVal = Src.getScalarVal();
+
+  if (Ty->isBooleanType())
+    SrcVal = Builder.CreateIntCast(SrcVal, ResLTy, /*IsSigned=*/false);
+
+  SrcVal = Builder.CreateAnd(SrcVal, llvm::APInt::getLowBitsSet(ResSizeInBits,
+                                                                Info.getSize()),
+                             "bf.value");
+
+  // Return the new value of the bit-field, if requested.
+  if (Result) {
+    // Cast back to the proper type for result.
+    const llvm::Type *SrcTy = Src.getScalarVal()->getType();
+    llvm::Value *ReloadVal = Builder.CreateIntCast(SrcVal, SrcTy, false,
+                                                   "bf.reload.val");
+
+    // Sign extend if necessary.
+    if (Info.isSigned()) {
+      unsigned ExtraBits = ResSizeInBits - Info.getSize();
+      if (ExtraBits)
+        ReloadVal = Builder.CreateAShr(Builder.CreateShl(ReloadVal, ExtraBits),
+                                       ExtraBits, "bf.reload.sext");
+    }
+
+    *Result = ReloadVal;
+  }
+
+  // Iterate over the components, writing each piece to memory.
+  for (unsigned i = 0, e = Info.getNumComponents(); i != e; ++i) {
+    const CGBitFieldInfo::AccessInfo &AI = Info.getComponent(i);
+
+    // Get the field pointer.
+    llvm::Value *Ptr = Dst.getBitFieldBaseAddr();
+
+    // Only offset by the field index if used, so that incoming values are not
+    // required to be structures.
+    if (AI.FieldIndex)
+      Ptr = Builder.CreateStructGEP(Ptr, AI.FieldIndex, "bf.field");
+
+    // Offset by the byte offset, if used.
+    if (AI.FieldByteOffset) {
+      const llvm::Type *i8PTy = llvm::Type::getInt8PtrTy(VMContext);
+      Ptr = Builder.CreateBitCast(Ptr, i8PTy);
+      Ptr = Builder.CreateConstGEP1_32(Ptr, AI.FieldByteOffset,"bf.field.offs");
+    }
+
+    // Cast to the access type.
+    const llvm::Type *PTy = llvm::Type::getIntNPtrTy(VMContext, AI.AccessWidth,
+                                                     Ty.getAddressSpace());
+    Ptr = Builder.CreateBitCast(Ptr, PTy);
+
+    // Extract the piece of the bit-field value to write in this access, limited
+    // to the values that are part of this access.
+    llvm::Value *Val = SrcVal;
+    if (AI.TargetBitOffset)
+      Val = Builder.CreateLShr(Val, AI.TargetBitOffset);
+    Val = Builder.CreateAnd(Val, llvm::APInt::getLowBitsSet(ResSizeInBits,
+                                                            AI.TargetBitWidth));
+
+    // Extend or truncate to the access size.
+    const llvm::Type *AccessLTy =
+      llvm::Type::getIntNTy(VMContext, AI.AccessWidth);
+    if (ResSizeInBits < AI.AccessWidth)
+      Val = Builder.CreateZExt(Val, AccessLTy);
+    else if (ResSizeInBits > AI.AccessWidth)
+      Val = Builder.CreateTrunc(Val, AccessLTy);
+
+    // Shift into the position in memory.
+    if (AI.FieldBitStart)
+      Val = Builder.CreateShl(Val, AI.FieldBitStart);
+
+    // If necessary, load and OR in bits that are outside of the bit-field.
+    if (AI.TargetBitWidth != AI.AccessWidth) {
+      llvm::LoadInst *Load = Builder.CreateLoad(Ptr, Dst.isVolatileQualified());
+      if (AI.AccessAlignment)
+        Load->setAlignment(AI.AccessAlignment);
+
+      // Compute the mask for zeroing the bits that are part of the bit-field.
+      llvm::APInt InvMask =
+        ~llvm::APInt::getBitsSet(AI.AccessWidth, AI.FieldBitStart,
+                                 AI.FieldBitStart + AI.TargetBitWidth);
+
+      // Apply the mask and OR in to the value to write.
+      Val = Builder.CreateOr(Builder.CreateAnd(Load, InvMask), Val);
+    }
+
+    // Write the value.
+    llvm::StoreInst *Store = Builder.CreateStore(Val, Ptr,
+                                                 Dst.isVolatileQualified());
+    if (AI.AccessAlignment)
+      Store->setAlignment(AI.AccessAlignment);
+  }
+}
+
+void CodeGenFunction::EmitStoreThroughPropertyRefLValue(RValue Src,
+                                                        LValue Dst,
+                                                        QualType Ty) {
+  EmitObjCPropertySet(Dst.getPropertyRefExpr(), Src);
+}
+
+void CodeGenFunction::EmitStoreThroughKVCRefLValue(RValue Src,
+                                                   LValue Dst,
+                                                   QualType Ty) {
+  EmitObjCPropertySet(Dst.getKVCRefExpr(), Src);
+}
+
+void CodeGenFunction::EmitStoreThroughExtVectorComponentLValue(RValue Src,
+                                                               LValue Dst,
+                                                               QualType Ty) {
+  // This access turns into a read/modify/write of the vector.  Load the input
+  // value now.
+  llvm::Value *Vec = Builder.CreateLoad(Dst.getExtVectorAddr(),
+                                        Dst.isVolatileQualified(), "tmp");
+  const llvm::Constant *Elts = Dst.getExtVectorElts();
+
+  llvm::Value *SrcVal = Src.getScalarVal();
+
+  if (const VectorType *VTy = Ty->getAs<VectorType>()) {
+    unsigned NumSrcElts = VTy->getNumElements();
+    unsigned NumDstElts =
+       cast<llvm::VectorType>(Vec->getType())->getNumElements();
+    if (NumDstElts == NumSrcElts) {
+      // Use shuffle vector is the src and destination are the same number of
+      // elements and restore the vector mask since it is on the side it will be
+      // stored.
+      llvm::SmallVector<llvm::Constant*, 4> Mask(NumDstElts);
+      for (unsigned i = 0; i != NumSrcElts; ++i) {
+        unsigned InIdx = getAccessedFieldNo(i, Elts);
+        Mask[InIdx] = llvm::ConstantInt::get(
+                                          llvm::Type::getInt32Ty(VMContext), i);
+      }
+
+      llvm::Value *MaskV = llvm::ConstantVector::get(&Mask[0], Mask.size());
+      Vec = Builder.CreateShuffleVector(SrcVal,
+                                        llvm::UndefValue::get(Vec->getType()),
+                                        MaskV, "tmp");
+    } else if (NumDstElts > NumSrcElts) {
+      // Extended the source vector to the same length and then shuffle it
+      // into the destination.
+      // FIXME: since we're shuffling with undef, can we just use the indices
+      //        into that?  This could be simpler.
+      llvm::SmallVector<llvm::Constant*, 4> ExtMask;
+      const llvm::Type *Int32Ty = llvm::Type::getInt32Ty(VMContext);
+      unsigned i;
+      for (i = 0; i != NumSrcElts; ++i)
+        ExtMask.push_back(llvm::ConstantInt::get(Int32Ty, i));
+      for (; i != NumDstElts; ++i)
+        ExtMask.push_back(llvm::UndefValue::get(Int32Ty));
+      llvm::Value *ExtMaskV = llvm::ConstantVector::get(&ExtMask[0],
+                                                        ExtMask.size());
+      llvm::Value *ExtSrcVal =
+        Builder.CreateShuffleVector(SrcVal,
+                                    llvm::UndefValue::get(SrcVal->getType()),
+                                    ExtMaskV, "tmp");
+      // build identity
+      llvm::SmallVector<llvm::Constant*, 4> Mask;
+      for (unsigned i = 0; i != NumDstElts; ++i)
+        Mask.push_back(llvm::ConstantInt::get(Int32Ty, i));
+
+      // modify when what gets shuffled in
+      for (unsigned i = 0; i != NumSrcElts; ++i) {
+        unsigned Idx = getAccessedFieldNo(i, Elts);
+        Mask[Idx] = llvm::ConstantInt::get(Int32Ty, i+NumDstElts);
+      }
+      llvm::Value *MaskV = llvm::ConstantVector::get(&Mask[0], Mask.size());
+      Vec = Builder.CreateShuffleVector(Vec, ExtSrcVal, MaskV, "tmp");
+    } else {
+      // We should never shorten the vector
+      assert(0 && "unexpected shorten vector length");
+    }
+  } else {
+    // If the Src is a scalar (not a vector) it must be updating one element.
+    unsigned InIdx = getAccessedFieldNo(0, Elts);
+    const llvm::Type *Int32Ty = llvm::Type::getInt32Ty(VMContext);
+    llvm::Value *Elt = llvm::ConstantInt::get(Int32Ty, InIdx);
+    Vec = Builder.CreateInsertElement(Vec, SrcVal, Elt, "tmp");
+  }
+
+  Builder.CreateStore(Vec, Dst.getExtVectorAddr(), Dst.isVolatileQualified());
+}
+
+// setObjCGCLValueClass - sets class of he lvalue for the purpose of
+// generating write-barries API. It is currently a global, ivar,
+// or neither.
+static void setObjCGCLValueClass(const ASTContext &Ctx, const Expr *E,
+                                 LValue &LV) {
+  if (Ctx.getLangOptions().getGCMode() == LangOptions::NonGC)
+    return;
+  
+  if (isa<ObjCIvarRefExpr>(E)) {
+    LV.SetObjCIvar(LV, true);
+    ObjCIvarRefExpr *Exp = cast<ObjCIvarRefExpr>(const_cast<Expr*>(E));
+    LV.setBaseIvarExp(Exp->getBase());
+    LV.SetObjCArray(LV, E->getType()->isArrayType());
+    return;
+  }
+  
+  if (const DeclRefExpr *Exp = dyn_cast<DeclRefExpr>(E)) {
+    if (const VarDecl *VD = dyn_cast<VarDecl>(Exp->getDecl())) {
+      if ((VD->isBlockVarDecl() && !VD->hasLocalStorage()) ||
+          VD->isFileVarDecl())
+        LV.SetGlobalObjCRef(LV, true);
+    }
+    LV.SetObjCArray(LV, E->getType()->isArrayType());
+    return;
+  }
+  
+  if (const UnaryOperator *Exp = dyn_cast<UnaryOperator>(E)) {
+    setObjCGCLValueClass(Ctx, Exp->getSubExpr(), LV);
+    return;
+  }
+  
+  if (const ParenExpr *Exp = dyn_cast<ParenExpr>(E)) {
+    setObjCGCLValueClass(Ctx, Exp->getSubExpr(), LV);
+    if (LV.isObjCIvar()) {
+      // If cast is to a structure pointer, follow gcc's behavior and make it
+      // a non-ivar write-barrier.
+      QualType ExpTy = E->getType();
+      if (ExpTy->isPointerType())
+        ExpTy = ExpTy->getAs<PointerType>()->getPointeeType();
+      if (ExpTy->isRecordType())
+        LV.SetObjCIvar(LV, false); 
+    }
+    return;
+  }
+  if (const ImplicitCastExpr *Exp = dyn_cast<ImplicitCastExpr>(E)) {
+    setObjCGCLValueClass(Ctx, Exp->getSubExpr(), LV);
+    return;
+  }
+  
+  if (const CStyleCastExpr *Exp = dyn_cast<CStyleCastExpr>(E)) {
+    setObjCGCLValueClass(Ctx, Exp->getSubExpr(), LV);
+    return;
+  }
+  
+  if (const ArraySubscriptExpr *Exp = dyn_cast<ArraySubscriptExpr>(E)) {
+    setObjCGCLValueClass(Ctx, Exp->getBase(), LV);
+    if (LV.isObjCIvar() && !LV.isObjCArray()) 
+      // Using array syntax to assigning to what an ivar points to is not 
+      // same as assigning to the ivar itself. {id *Names;} Names[i] = 0;
+      LV.SetObjCIvar(LV, false); 
+    else if (LV.isGlobalObjCRef() && !LV.isObjCArray())
+      // Using array syntax to assigning to what global points to is not 
+      // same as assigning to the global itself. {id *G;} G[i] = 0;
+      LV.SetGlobalObjCRef(LV, false);
+    return;
+  }
+  
+  if (const MemberExpr *Exp = dyn_cast<MemberExpr>(E)) {
+    setObjCGCLValueClass(Ctx, Exp->getBase(), LV);
+    // We don't know if member is an 'ivar', but this flag is looked at
+    // only in the context of LV.isObjCIvar().
+    LV.SetObjCArray(LV, E->getType()->isArrayType());
+    return;
+  }
+}
+
+static LValue EmitGlobalVarDeclLValue(CodeGenFunction &CGF,
+                                      const Expr *E, const VarDecl *VD) {
+  assert((VD->hasExternalStorage() || VD->isFileVarDecl()) &&
+         "Var decl must have external storage or be a file var decl!");
+
+  llvm::Value *V = CGF.CGM.GetAddrOfGlobalVar(VD);
+  if (VD->getType()->isReferenceType())
+    V = CGF.Builder.CreateLoad(V, "tmp");
+  LValue LV = LValue::MakeAddr(V, CGF.MakeQualifiers(E->getType()));
+  setObjCGCLValueClass(CGF.getContext(), E, LV);
+  return LV;
+}
+
+static LValue EmitFunctionDeclLValue(CodeGenFunction &CGF,
+                                      const Expr *E, const FunctionDecl *FD) {
+  llvm::Value* V = CGF.CGM.GetAddrOfFunction(FD);
+  if (!FD->hasPrototype()) {
+    if (const FunctionProtoType *Proto =
+            FD->getType()->getAs<FunctionProtoType>()) {
+      // Ugly case: for a K&R-style definition, the type of the definition
+      // isn't the same as the type of a use.  Correct for this with a
+      // bitcast.
+      QualType NoProtoType =
+          CGF.getContext().getFunctionNoProtoType(Proto->getResultType());
+      NoProtoType = CGF.getContext().getPointerType(NoProtoType);
+      V = CGF.Builder.CreateBitCast(V, CGF.ConvertType(NoProtoType), "tmp");
+    }
+  }
+  return LValue::MakeAddr(V, CGF.MakeQualifiers(E->getType()));
+}
+
+LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
+  const NamedDecl *ND = E->getDecl();
+
+  if (ND->hasAttr<WeakRefAttr>()) {
+    const ValueDecl* VD = cast<ValueDecl>(ND);
+    llvm::Constant *Aliasee = CGM.GetWeakRefReference(VD);
+
+    Qualifiers Quals = MakeQualifiers(E->getType());
+    LValue LV = LValue::MakeAddr(Aliasee, Quals);
+
+    return LV;
+  }
+
+  if (const VarDecl *VD = dyn_cast<VarDecl>(ND)) {
+    
+    // Check if this is a global variable.
+    if (VD->hasExternalStorage() || VD->isFileVarDecl()) 
+      return EmitGlobalVarDeclLValue(*this, E, VD);
+
+    bool NonGCable = VD->hasLocalStorage() && !VD->hasAttr<BlocksAttr>();
+
+    llvm::Value *V = LocalDeclMap[VD];
+    if (!V && getContext().getLangOptions().CPlusPlus &&
+        VD->isStaticLocal()) 
+      V = CGM.getStaticLocalDeclAddress(VD);
+    assert(V && "DeclRefExpr not entered in LocalDeclMap?");
+
+    Qualifiers Quals = MakeQualifiers(E->getType());
+    // local variables do not get their gc attribute set.
+    // local static?
+    if (NonGCable) Quals.removeObjCGCAttr();
+
+    if (VD->hasAttr<BlocksAttr>()) {
+      V = Builder.CreateStructGEP(V, 1, "forwarding");
+      V = Builder.CreateLoad(V);
+      V = Builder.CreateStructGEP(V, getByRefValueLLVMField(VD),
+                                  VD->getNameAsString());
+    }
+    if (VD->getType()->isReferenceType())
+      V = Builder.CreateLoad(V, "tmp");
+    LValue LV = LValue::MakeAddr(V, Quals);
+    LValue::SetObjCNonGC(LV, NonGCable);
+    setObjCGCLValueClass(getContext(), E, LV);
+    return LV;
+  }
+  
+  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND))
+    return EmitFunctionDeclLValue(*this, E, FD);
+  
+  // FIXME: the qualifier check does not seem sufficient here
+  if (E->getQualifier()) {
+    const FieldDecl *FD = cast<FieldDecl>(ND);
+    llvm::Value *V = CGM.EmitPointerToDataMember(FD);
+
+    return LValue::MakeAddr(V, MakeQualifiers(FD->getType()));
+  }
+  
+  assert(false && "Unhandled DeclRefExpr");
+  
+  // an invalid LValue, but the assert will
+  // ensure that this point is never reached.
+  return LValue();
+}
+
+LValue CodeGenFunction::EmitBlockDeclRefLValue(const BlockDeclRefExpr *E) {
+  return LValue::MakeAddr(GetAddrOfBlockDecl(E), MakeQualifiers(E->getType()));
+}
+
+LValue CodeGenFunction::EmitUnaryOpLValue(const UnaryOperator *E) {
+  // __extension__ doesn't affect lvalue-ness.
+  if (E->getOpcode() == UnaryOperator::Extension)
+    return EmitLValue(E->getSubExpr());
+
+  QualType ExprTy = getContext().getCanonicalType(E->getSubExpr()->getType());
+  switch (E->getOpcode()) {
+  default: assert(0 && "Unknown unary operator lvalue!");
+  case UnaryOperator::Deref: {
+    QualType T = E->getSubExpr()->getType()->getPointeeType();
+    assert(!T.isNull() && "CodeGenFunction::EmitUnaryOpLValue: Illegal type");
+
+    Qualifiers Quals = MakeQualifiers(T);
+    Quals.setAddressSpace(ExprTy.getAddressSpace());
+
+    LValue LV = LValue::MakeAddr(EmitScalarExpr(E->getSubExpr()), Quals);
+    // We should not generate __weak write barrier on indirect reference
+    // of a pointer to object; as in void foo (__weak id *param); *param = 0;
+    // But, we continue to generate __strong write barrier on indirect write
+    // into a pointer to object.
+    if (getContext().getLangOptions().ObjC1 &&
+        getContext().getLangOptions().getGCMode() != LangOptions::NonGC &&
+        LV.isObjCWeak())
+      LValue::SetObjCNonGC(LV, !E->isOBJCGCCandidate(getContext()));
+    return LV;
+  }
+  case UnaryOperator::Real:
+  case UnaryOperator::Imag: {
+    LValue LV = EmitLValue(E->getSubExpr());
+    unsigned Idx = E->getOpcode() == UnaryOperator::Imag;
+    return LValue::MakeAddr(Builder.CreateStructGEP(LV.getAddress(),
+                                                    Idx, "idx"),
+                            MakeQualifiers(ExprTy));
+  }
+  case UnaryOperator::PreInc:
+  case UnaryOperator::PreDec: {
+    LValue LV = EmitLValue(E->getSubExpr());
+    bool isInc = E->getOpcode() == UnaryOperator::PreInc;
+    
+    if (E->getType()->isAnyComplexType())
+      EmitComplexPrePostIncDec(E, LV, isInc, true/*isPre*/);
+    else
+      EmitScalarPrePostIncDec(E, LV, isInc, true/*isPre*/);
+    return LV;
+  }
+  }
+}
+
+LValue CodeGenFunction::EmitStringLiteralLValue(const StringLiteral *E) {
+  return LValue::MakeAddr(CGM.GetAddrOfConstantStringFromLiteral(E),
+                          Qualifiers());
+}
+
+LValue CodeGenFunction::EmitObjCEncodeExprLValue(const ObjCEncodeExpr *E) {
+  return LValue::MakeAddr(CGM.GetAddrOfConstantStringFromObjCEncode(E),
+                          Qualifiers());
+}
+
+
+LValue CodeGenFunction::EmitPredefinedFunctionName(unsigned Type) {
+  std::string GlobalVarName;
+
+  switch (Type) {
+  default: assert(0 && "Invalid type");
+  case PredefinedExpr::Func:
+    GlobalVarName = "__func__.";
+    break;
+  case PredefinedExpr::Function:
+    GlobalVarName = "__FUNCTION__.";
+    break;
+  case PredefinedExpr::PrettyFunction:
+    GlobalVarName = "__PRETTY_FUNCTION__.";
+    break;
+  }
+
+  llvm::StringRef FnName = CurFn->getName();
+  if (FnName.startswith("\01"))
+    FnName = FnName.substr(1);
+  GlobalVarName += FnName;
+
+  std::string FunctionName =
+    PredefinedExpr::ComputeName((PredefinedExpr::IdentType)Type, CurCodeDecl);
+
+  llvm::Constant *C =
+    CGM.GetAddrOfConstantCString(FunctionName, GlobalVarName.c_str());
+  return LValue::MakeAddr(C, Qualifiers());
+}
+
+LValue CodeGenFunction::EmitPredefinedLValue(const PredefinedExpr *E) {
+  switch (E->getIdentType()) {
+  default:
+    return EmitUnsupportedLValue(E, "predefined expression");
+  case PredefinedExpr::Func:
+  case PredefinedExpr::Function:
+  case PredefinedExpr::PrettyFunction:
+    return EmitPredefinedFunctionName(E->getIdentType());
+  }
+}
+
+llvm::BasicBlock *CodeGenFunction::getTrapBB() {
+  const CodeGenOptions &GCO = CGM.getCodeGenOpts();
+
+  // If we are not optimzing, don't collapse all calls to trap in the function
+  // to the same call, that way, in the debugger they can see which operation
+  // did in fact fail.  If we are optimizing, we collpase all call to trap down
+  // to just one per function to save on codesize.
+  if (GCO.OptimizationLevel
+      && TrapBB)
+    return TrapBB;
+
+  llvm::BasicBlock *Cont = 0;
+  if (HaveInsertPoint()) {
+    Cont = createBasicBlock("cont");
+    EmitBranch(Cont);
+  }
+  TrapBB = createBasicBlock("trap");
+  EmitBlock(TrapBB);
+
+  llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::trap, 0, 0);
+  llvm::CallInst *TrapCall = Builder.CreateCall(F);
+  TrapCall->setDoesNotReturn();
+  TrapCall->setDoesNotThrow();
+  Builder.CreateUnreachable();
+
+  if (Cont)
+    EmitBlock(Cont);
+  return TrapBB;
+}
+
+LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E) {
+  // The index must always be an integer, which is not an aggregate.  Emit it.
+  llvm::Value *Idx = EmitScalarExpr(E->getIdx());
+  QualType IdxTy  = E->getIdx()->getType();
+  bool IdxSigned = IdxTy->isSignedIntegerType();
+
+  // If the base is a vector type, then we are forming a vector element lvalue
+  // with this subscript.
+  if (E->getBase()->getType()->isVectorType()) {
+    // Emit the vector as an lvalue to get its address.
+    LValue LHS = EmitLValue(E->getBase());
+    assert(LHS.isSimple() && "Can only subscript lvalue vectors here!");
+    Idx = Builder.CreateIntCast(Idx,
+                          llvm::Type::getInt32Ty(VMContext), IdxSigned, "vidx");
+    return LValue::MakeVectorElt(LHS.getAddress(), Idx,
+                                 E->getBase()->getType().getCVRQualifiers());
+  }
+
+  // The base must be a pointer, which is not an aggregate.  Emit it.
+  llvm::Value *Base = EmitScalarExpr(E->getBase());
+
+  // Extend or truncate the index type to 32 or 64-bits.
+  unsigned IdxBitwidth = cast<llvm::IntegerType>(Idx->getType())->getBitWidth();
+  if (IdxBitwidth != LLVMPointerWidth)
+    Idx = Builder.CreateIntCast(Idx,
+                            llvm::IntegerType::get(VMContext, LLVMPointerWidth),
+                                IdxSigned, "idxprom");
+
+  // FIXME: As llvm implements the object size checking, this can come out.
+  if (CatchUndefined) {
+    if (const ImplicitCastExpr *ICE=dyn_cast<ImplicitCastExpr>(E->getBase())) {
+      if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(ICE->getSubExpr())) {
+        if (ICE->getCastKind() == CastExpr::CK_ArrayToPointerDecay) {
+          if (const ConstantArrayType *CAT
+              = getContext().getAsConstantArrayType(DRE->getType())) {
+            llvm::APInt Size = CAT->getSize();
+            llvm::BasicBlock *Cont = createBasicBlock("cont");
+            Builder.CreateCondBr(Builder.CreateICmpULE(Idx,
+                                  llvm::ConstantInt::get(Idx->getType(), Size)),
+                                 Cont, getTrapBB());
+            EmitBlock(Cont);
+          }
+        }
+      }
+    }
+  }
+
+  // We know that the pointer points to a type of the correct size, unless the
+  // size is a VLA or Objective-C interface.
+  llvm::Value *Address = 0;
+  if (const VariableArrayType *VAT =
+        getContext().getAsVariableArrayType(E->getType())) {
+    llvm::Value *VLASize = GetVLASize(VAT);
+
+    Idx = Builder.CreateMul(Idx, VLASize);
+
+    QualType BaseType = getContext().getBaseElementType(VAT);
+
+    CharUnits BaseTypeSize = getContext().getTypeSizeInChars(BaseType);
+    Idx = Builder.CreateUDiv(Idx,
+                             llvm::ConstantInt::get(Idx->getType(),
+                                 BaseTypeSize.getQuantity()));
+    Address = Builder.CreateInBoundsGEP(Base, Idx, "arrayidx");
+  } else if (const ObjCInterfaceType *OIT =
+             dyn_cast<ObjCInterfaceType>(E->getType())) {
+    llvm::Value *InterfaceSize =
+      llvm::ConstantInt::get(Idx->getType(),
+          getContext().getTypeSizeInChars(OIT).getQuantity());
+
+    Idx = Builder.CreateMul(Idx, InterfaceSize);
+
+    const llvm::Type *i8PTy = llvm::Type::getInt8PtrTy(VMContext);
+    Address = Builder.CreateGEP(Builder.CreateBitCast(Base, i8PTy),
+                                Idx, "arrayidx");
+    Address = Builder.CreateBitCast(Address, Base->getType());
+  } else {
+    Address = Builder.CreateInBoundsGEP(Base, Idx, "arrayidx");
+  }
+
+  QualType T = E->getBase()->getType()->getPointeeType();
+  assert(!T.isNull() &&
+         "CodeGenFunction::EmitArraySubscriptExpr(): Illegal base type");
+
+  Qualifiers Quals = MakeQualifiers(T);
+  Quals.setAddressSpace(E->getBase()->getType().getAddressSpace());
+
+  LValue LV = LValue::MakeAddr(Address, Quals);
+  if (getContext().getLangOptions().ObjC1 &&
+      getContext().getLangOptions().getGCMode() != LangOptions::NonGC) {
+    LValue::SetObjCNonGC(LV, !E->isOBJCGCCandidate(getContext()));
+    setObjCGCLValueClass(getContext(), E, LV);
+  }
+  return LV;
+}
+
+static
+llvm::Constant *GenerateConstantVector(llvm::LLVMContext &VMContext,
+                                       llvm::SmallVector<unsigned, 4> &Elts) {
+  llvm::SmallVector<llvm::Constant*, 4> CElts;
+
+  for (unsigned i = 0, e = Elts.size(); i != e; ++i)
+    CElts.push_back(llvm::ConstantInt::get(
+                                   llvm::Type::getInt32Ty(VMContext), Elts[i]));
+
+  return llvm::ConstantVector::get(&CElts[0], CElts.size());
+}
+
+LValue CodeGenFunction::
+EmitExtVectorElementExpr(const ExtVectorElementExpr *E) {
+  const llvm::Type *Int32Ty = llvm::Type::getInt32Ty(VMContext);
+
+  // Emit the base vector as an l-value.
+  LValue Base;
+
+  // ExtVectorElementExpr's base can either be a vector or pointer to vector.
+  if (E->isArrow()) {
+    // If it is a pointer to a vector, emit the address and form an lvalue with
+    // it.
+    llvm::Value *Ptr = EmitScalarExpr(E->getBase());
+    const PointerType *PT = E->getBase()->getType()->getAs<PointerType>();
+    Qualifiers Quals = MakeQualifiers(PT->getPointeeType());
+    Quals.removeObjCGCAttr();
+    Base = LValue::MakeAddr(Ptr, Quals);
+  } else if (E->getBase()->isLvalue(getContext()) == Expr::LV_Valid) {
+    // Otherwise, if the base is an lvalue ( as in the case of foo.x.x),
+    // emit the base as an lvalue.
+    assert(E->getBase()->getType()->isVectorType());
+    Base = EmitLValue(E->getBase());
+  } else {
+    // Otherwise, the base is a normal rvalue (as in (V+V).x), emit it as such.
+    assert(E->getBase()->getType()->getAs<VectorType>() &&
+           "Result must be a vector");
+    llvm::Value *Vec = EmitScalarExpr(E->getBase());
+    
+    // Store the vector to memory (because LValue wants an address).
+    llvm::Value *VecMem = CreateMemTemp(E->getBase()->getType());
+    Builder.CreateStore(Vec, VecMem);
+    Base = LValue::MakeAddr(VecMem, Qualifiers());
+  }
+  
+  // Encode the element access list into a vector of unsigned indices.
+  llvm::SmallVector<unsigned, 4> Indices;
+  E->getEncodedElementAccess(Indices);
+
+  if (Base.isSimple()) {
+    llvm::Constant *CV = GenerateConstantVector(VMContext, Indices);
+    return LValue::MakeExtVectorElt(Base.getAddress(), CV,
+                                    Base.getVRQualifiers());
+  }
+  assert(Base.isExtVectorElt() && "Can only subscript lvalue vec elts here!");
+
+  llvm::Constant *BaseElts = Base.getExtVectorElts();
+  llvm::SmallVector<llvm::Constant *, 4> CElts;
+
+  for (unsigned i = 0, e = Indices.size(); i != e; ++i) {
+    if (isa<llvm::ConstantAggregateZero>(BaseElts))
+      CElts.push_back(llvm::ConstantInt::get(Int32Ty, 0));
+    else
+      CElts.push_back(cast<llvm::Constant>(BaseElts->getOperand(Indices[i])));
+  }
+  llvm::Constant *CV = llvm::ConstantVector::get(&CElts[0], CElts.size());
+  return LValue::MakeExtVectorElt(Base.getExtVectorAddr(), CV,
+                                  Base.getVRQualifiers());
+}
+
+LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) {
+  bool isNonGC = false;
+  Expr *BaseExpr = E->getBase();
+  llvm::Value *BaseValue = NULL;
+  Qualifiers BaseQuals;
+
+  // If this is s.x, emit s as an lvalue.  If it is s->x, emit s as a scalar.
+  if (E->isArrow()) {
+    BaseValue = EmitScalarExpr(BaseExpr);
+    const PointerType *PTy =
+      BaseExpr->getType()->getAs<PointerType>();
+    BaseQuals = PTy->getPointeeType().getQualifiers();
+  } else if (isa<ObjCPropertyRefExpr>(BaseExpr->IgnoreParens()) ||
+             isa<ObjCImplicitSetterGetterRefExpr>(
+               BaseExpr->IgnoreParens())) {
+    RValue RV = EmitObjCPropertyGet(BaseExpr);
+    BaseValue = RV.getAggregateAddr();
+    BaseQuals = BaseExpr->getType().getQualifiers();
+  } else {
+    LValue BaseLV = EmitLValue(BaseExpr);
+    if (BaseLV.isNonGC())
+      isNonGC = true;
+    // FIXME: this isn't right for bitfields.
+    BaseValue = BaseLV.getAddress();
+    QualType BaseTy = BaseExpr->getType();
+    BaseQuals = BaseTy.getQualifiers();
+  }
+
+  NamedDecl *ND = E->getMemberDecl();
+  if (FieldDecl *Field = dyn_cast<FieldDecl>(ND)) {
+    LValue LV = EmitLValueForField(BaseValue, Field, 
+                                   BaseQuals.getCVRQualifiers());
+    LValue::SetObjCNonGC(LV, isNonGC);
+    setObjCGCLValueClass(getContext(), E, LV);
+    return LV;
+  }
+  
+  if (VarDecl *VD = dyn_cast<VarDecl>(ND))
+    return EmitGlobalVarDeclLValue(*this, E, VD);
+
+  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND))
+    return EmitFunctionDeclLValue(*this, E, FD);
+
+  assert(false && "Unhandled member declaration!");
+  return LValue();
+}
+
+LValue CodeGenFunction::EmitLValueForBitfield(llvm::Value* BaseValue,
+                                              const FieldDecl* Field,
+                                              unsigned CVRQualifiers) {
+  const CGRecordLayout &RL =
+    CGM.getTypes().getCGRecordLayout(Field->getParent());
+  const CGBitFieldInfo &Info = RL.getBitFieldInfo(Field);
+  return LValue::MakeBitfield(BaseValue, Info,
+                             Field->getType().getCVRQualifiers()|CVRQualifiers);
+}
+
+LValue CodeGenFunction::EmitLValueForField(llvm::Value* BaseValue,
+                                           const FieldDecl* Field,
+                                           unsigned CVRQualifiers) {
+  if (Field->isBitField())
+    return EmitLValueForBitfield(BaseValue, Field, CVRQualifiers);
+
+  const CGRecordLayout &RL =
+    CGM.getTypes().getCGRecordLayout(Field->getParent());
+  unsigned idx = RL.getLLVMFieldNo(Field);
+  llvm::Value *V = Builder.CreateStructGEP(BaseValue, idx, "tmp");
+
+  // Match union field type.
+  if (Field->getParent()->isUnion()) {
+    const llvm::Type *FieldTy =
+      CGM.getTypes().ConvertTypeForMem(Field->getType());
+    const llvm::PointerType * BaseTy =
+      cast<llvm::PointerType>(BaseValue->getType());
+    unsigned AS = BaseTy->getAddressSpace();
+    V = Builder.CreateBitCast(V,
+                              llvm::PointerType::get(FieldTy, AS),
+                              "tmp");
+  }
+  if (Field->getType()->isReferenceType())
+    V = Builder.CreateLoad(V, "tmp");
+
+  Qualifiers Quals = MakeQualifiers(Field->getType());
+  Quals.addCVRQualifiers(CVRQualifiers);
+  // __weak attribute on a field is ignored.
+  if (Quals.getObjCGCAttr() == Qualifiers::Weak)
+    Quals.removeObjCGCAttr();
+  
+  return LValue::MakeAddr(V, Quals);
+}
+
+LValue 
+CodeGenFunction::EmitLValueForFieldInitialization(llvm::Value* BaseValue, 
+                                                  const FieldDecl* Field,
+                                                  unsigned CVRQualifiers) {
+  QualType FieldType = Field->getType();
+  
+  if (!FieldType->isReferenceType())
+    return EmitLValueForField(BaseValue, Field, CVRQualifiers);
+
+  const CGRecordLayout &RL =
+    CGM.getTypes().getCGRecordLayout(Field->getParent());
+  unsigned idx = RL.getLLVMFieldNo(Field);
+  llvm::Value *V = Builder.CreateStructGEP(BaseValue, idx, "tmp");
+
+  assert(!FieldType.getObjCGCAttr() && "fields cannot have GC attrs");
+
+  return LValue::MakeAddr(V, MakeQualifiers(FieldType));
+}
+
+LValue CodeGenFunction::EmitCompoundLiteralLValue(const CompoundLiteralExpr* E){
+  llvm::Value *DeclPtr = CreateMemTemp(E->getType(), ".compoundliteral");
+  const Expr* InitExpr = E->getInitializer();
+  LValue Result = LValue::MakeAddr(DeclPtr, MakeQualifiers(E->getType()));
+
+  EmitAnyExprToMem(InitExpr, DeclPtr, /*Volatile*/ false);
+
+  return Result;
+}
+
+LValue 
+CodeGenFunction::EmitConditionalOperatorLValue(const ConditionalOperator* E) {
+  if (E->isLvalue(getContext()) == Expr::LV_Valid) {
+    if (int Cond = ConstantFoldsToSimpleInteger(E->getCond())) {
+      Expr *Live = Cond == 1 ? E->getLHS() : E->getRHS();
+      if (Live)
+        return EmitLValue(Live);
+    }
+
+    if (!E->getLHS())
+      return EmitUnsupportedLValue(E, "conditional operator with missing LHS");
+
+    llvm::BasicBlock *LHSBlock = createBasicBlock("cond.true");
+    llvm::BasicBlock *RHSBlock = createBasicBlock("cond.false");
+    llvm::BasicBlock *ContBlock = createBasicBlock("cond.end");
+    
+    EmitBranchOnBoolExpr(E->getCond(), LHSBlock, RHSBlock);
+    
+    // Any temporaries created here are conditional.
+    BeginConditionalBranch();
+    EmitBlock(LHSBlock);
+    LValue LHS = EmitLValue(E->getLHS());
+    EndConditionalBranch();
+    
+    if (!LHS.isSimple())
+      return EmitUnsupportedLValue(E, "conditional operator");
+
+    // FIXME: We shouldn't need an alloca for this.
+    llvm::Value *Temp = CreateTempAlloca(LHS.getAddress()->getType(),"condtmp");
+    Builder.CreateStore(LHS.getAddress(), Temp);
+    EmitBranch(ContBlock);
+    
+    // Any temporaries created here are conditional.
+    BeginConditionalBranch();
+    EmitBlock(RHSBlock);
+    LValue RHS = EmitLValue(E->getRHS());
+    EndConditionalBranch();
+    if (!RHS.isSimple())
+      return EmitUnsupportedLValue(E, "conditional operator");
+
+    Builder.CreateStore(RHS.getAddress(), Temp);
+    EmitBranch(ContBlock);
+
+    EmitBlock(ContBlock);
+    
+    Temp = Builder.CreateLoad(Temp, "lv");
+    return LValue::MakeAddr(Temp, MakeQualifiers(E->getType()));
+  }
+  
+  // ?: here should be an aggregate.
+  assert((hasAggregateLLVMType(E->getType()) &&
+          !E->getType()->isAnyComplexType()) &&
+         "Unexpected conditional operator!");
+
+  return EmitAggExprToLValue(E);
+}
+
+/// EmitCastLValue - Casts are never lvalues unless that cast is a dynamic_cast.
+/// If the cast is a dynamic_cast, we can have the usual lvalue result,
+/// otherwise if a cast is needed by the code generator in an lvalue context,
+/// then it must mean that we need the address of an aggregate in order to
+/// access one of its fields.  This can happen for all the reasons that casts
+/// are permitted with aggregate result, including noop aggregate casts, and
+/// cast from scalar to union.
+LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) {
+  switch (E->getCastKind()) {
+  default:
+    return EmitUnsupportedLValue(E, "unexpected cast lvalue");
+
+  case CastExpr::CK_Dynamic: {
+    LValue LV = EmitLValue(E->getSubExpr());
+    llvm::Value *V = LV.getAddress();
+    const CXXDynamicCastExpr *DCE = cast<CXXDynamicCastExpr>(E);
+    return LValue::MakeAddr(EmitDynamicCast(V, DCE),
+                            MakeQualifiers(E->getType()));
+  }
+
+  case CastExpr::CK_NoOp:
+  case CastExpr::CK_ConstructorConversion:
+  case CastExpr::CK_UserDefinedConversion:
+  case CastExpr::CK_AnyPointerToObjCPointerCast:
+    return EmitLValue(E->getSubExpr());
+  
+  case CastExpr::CK_UncheckedDerivedToBase:
+  case CastExpr::CK_DerivedToBase: {
+    const RecordType *DerivedClassTy = 
+      E->getSubExpr()->getType()->getAs<RecordType>();
+    CXXRecordDecl *DerivedClassDecl = 
+      cast<CXXRecordDecl>(DerivedClassTy->getDecl());
+    
+    LValue LV = EmitLValue(E->getSubExpr());
+    
+    // Perform the derived-to-base conversion
+    llvm::Value *Base = 
+      GetAddressOfBaseClass(LV.getAddress(), DerivedClassDecl, 
+                            E->getBasePath(), /*NullCheckValue=*/false);
+    
+    return LValue::MakeAddr(Base, MakeQualifiers(E->getType()));
+  }
+  case CastExpr::CK_ToUnion:
+    return EmitAggExprToLValue(E);
+  case CastExpr::CK_BaseToDerived: {
+    const RecordType *DerivedClassTy = E->getType()->getAs<RecordType>();
+    CXXRecordDecl *DerivedClassDecl = 
+      cast<CXXRecordDecl>(DerivedClassTy->getDecl());
+    
+    LValue LV = EmitLValue(E->getSubExpr());
+    
+    // Perform the base-to-derived conversion
+    llvm::Value *Derived = 
+      GetAddressOfDerivedClass(LV.getAddress(), DerivedClassDecl, 
+                               E->getBasePath(),/*NullCheckValue=*/false);
+    
+    return LValue::MakeAddr(Derived, MakeQualifiers(E->getType()));
+  }
+  case CastExpr::CK_BitCast: {
+    // This must be a reinterpret_cast (or c-style equivalent).
+    const ExplicitCastExpr *CE = cast<ExplicitCastExpr>(E);
+    
+    LValue LV = EmitLValue(E->getSubExpr());
+    llvm::Value *V = Builder.CreateBitCast(LV.getAddress(),
+                                           ConvertType(CE->getTypeAsWritten()));
+    return LValue::MakeAddr(V, MakeQualifiers(E->getType()));
+  }
+  }
+}
+
+LValue CodeGenFunction::EmitNullInitializationLValue(
+                                              const CXXZeroInitValueExpr *E) {
+  QualType Ty = E->getType();
+  LValue LV = LValue::MakeAddr(CreateMemTemp(Ty), MakeQualifiers(Ty));
+  EmitMemSetToZero(LV.getAddress(), Ty);
+  return LV;
+}
+
+//===--------------------------------------------------------------------===//
+//                             Expression Emission
+//===--------------------------------------------------------------------===//
+
+
+RValue CodeGenFunction::EmitCallExpr(const CallExpr *E, 
+                                     ReturnValueSlot ReturnValue) {
+  // Builtins never have block type.
+  if (E->getCallee()->getType()->isBlockPointerType())
+    return EmitBlockCallExpr(E, ReturnValue);
+
+  if (const CXXMemberCallExpr *CE = dyn_cast<CXXMemberCallExpr>(E))
+    return EmitCXXMemberCallExpr(CE, ReturnValue);
+
+  const Decl *TargetDecl = 0;
+  if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E->getCallee())) {
+    if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CE->getSubExpr())) {
+      TargetDecl = DRE->getDecl();
+      if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(TargetDecl))
+        if (unsigned builtinID = FD->getBuiltinID())
+          return EmitBuiltinExpr(FD, builtinID, E);
+    }
+  }
+
+  if (const CXXOperatorCallExpr *CE = dyn_cast<CXXOperatorCallExpr>(E))
+    if (const CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(TargetDecl))
+      return EmitCXXOperatorMemberCallExpr(CE, MD, ReturnValue);
+
+  if (isa<CXXPseudoDestructorExpr>(E->getCallee()->IgnoreParens())) {
+    // C++ [expr.pseudo]p1:
+    //   The result shall only be used as the operand for the function call
+    //   operator (), and the result of such a call has type void. The only
+    //   effect is the evaluation of the postfix-expression before the dot or
+    //   arrow.
+    EmitScalarExpr(E->getCallee());
+    return RValue::get(0);
+  }
+
+  llvm::Value *Callee = EmitScalarExpr(E->getCallee());
+  return EmitCall(E->getCallee()->getType(), Callee, ReturnValue,
+                  E->arg_begin(), E->arg_end(), TargetDecl);
+}
+
+LValue CodeGenFunction::EmitBinaryOperatorLValue(const BinaryOperator *E) {
+  // Comma expressions just emit their LHS then their RHS as an l-value.
+  if (E->getOpcode() == BinaryOperator::Comma) {
+    EmitAnyExpr(E->getLHS());
+    EnsureInsertPoint();
+    return EmitLValue(E->getRHS());
+  }
+
+  if (E->getOpcode() == BinaryOperator::PtrMemD ||
+      E->getOpcode() == BinaryOperator::PtrMemI)
+    return EmitPointerToDataMemberBinaryExpr(E);
+  
+  // Can only get l-value for binary operator expressions which are a
+  // simple assignment of aggregate type.
+  if (E->getOpcode() != BinaryOperator::Assign)
+    return EmitUnsupportedLValue(E, "binary l-value expression");
+
+  if (!hasAggregateLLVMType(E->getType())) {
+    // Emit the LHS as an l-value.
+    LValue LV = EmitLValue(E->getLHS());
+    
+    llvm::Value *RHS = EmitScalarExpr(E->getRHS());
+    EmitStoreOfScalar(RHS, LV.getAddress(), LV.isVolatileQualified(), 
+                      E->getType());
+    return LV;
+  }
+  
+  return EmitAggExprToLValue(E);
+}
+
+LValue CodeGenFunction::EmitCallExprLValue(const CallExpr *E) {
+  RValue RV = EmitCallExpr(E);
+
+  if (!RV.isScalar())
+    return LValue::MakeAddr(RV.getAggregateAddr(),MakeQualifiers(E->getType()));
+    
+  assert(E->getCallReturnType()->isReferenceType() &&
+         "Can't have a scalar return unless the return type is a "
+         "reference type!");
+
+  return LValue::MakeAddr(RV.getScalarVal(), MakeQualifiers(E->getType()));
+}
+
+LValue CodeGenFunction::EmitVAArgExprLValue(const VAArgExpr *E) {
+  // FIXME: This shouldn't require another copy.
+  return EmitAggExprToLValue(E);
+}
+
+LValue CodeGenFunction::EmitCXXConstructLValue(const CXXConstructExpr *E) {
+  llvm::Value *Temp = CreateMemTemp(E->getType(), "tmp");
+  EmitCXXConstructExpr(Temp, E);
+  return LValue::MakeAddr(Temp, MakeQualifiers(E->getType()));
+}
+
+LValue
+CodeGenFunction::EmitCXXTypeidLValue(const CXXTypeidExpr *E) {
+  llvm::Value *Temp = EmitCXXTypeidExpr(E);
+  return LValue::MakeAddr(Temp, MakeQualifiers(E->getType()));
+}
+
+LValue
+CodeGenFunction::EmitCXXBindTemporaryLValue(const CXXBindTemporaryExpr *E) {
+  LValue LV = EmitLValue(E->getSubExpr());
+  PushCXXTemporary(E->getTemporary(), LV.getAddress());
+  return LV;
+}
+
+LValue CodeGenFunction::EmitObjCMessageExprLValue(const ObjCMessageExpr *E) {
+  // Can only get l-value for message expression returning aggregate type
+  RValue RV = EmitObjCMessageExpr(E);
+  // FIXME: can this be volatile?
+  return LValue::MakeAddr(RV.getAggregateAddr(), MakeQualifiers(E->getType()));
+}
+
+llvm::Value *CodeGenFunction::EmitIvarOffset(const ObjCInterfaceDecl *Interface,
+                                             const ObjCIvarDecl *Ivar) {
+  return CGM.getObjCRuntime().EmitIvarOffset(*this, Interface, Ivar);
+}
+
+LValue CodeGenFunction::EmitLValueForIvar(QualType ObjectTy,
+                                          llvm::Value *BaseValue,
+                                          const ObjCIvarDecl *Ivar,
+                                          unsigned CVRQualifiers) {
+  return CGM.getObjCRuntime().EmitObjCValueForIvar(*this, ObjectTy, BaseValue,
+                                                   Ivar, CVRQualifiers);
+}
+
+LValue CodeGenFunction::EmitObjCIvarRefLValue(const ObjCIvarRefExpr *E) {
+  // FIXME: A lot of the code below could be shared with EmitMemberExpr.
+  llvm::Value *BaseValue = 0;
+  const Expr *BaseExpr = E->getBase();
+  Qualifiers BaseQuals;
+  QualType ObjectTy;
+  if (E->isArrow()) {
+    BaseValue = EmitScalarExpr(BaseExpr);
+    ObjectTy = BaseExpr->getType()->getPointeeType();
+    BaseQuals = ObjectTy.getQualifiers();
+  } else {
+    LValue BaseLV = EmitLValue(BaseExpr);
+    // FIXME: this isn't right for bitfields.
+    BaseValue = BaseLV.getAddress();
+    ObjectTy = BaseExpr->getType();
+    BaseQuals = ObjectTy.getQualifiers();
+  }
+
+  LValue LV = 
+    EmitLValueForIvar(ObjectTy, BaseValue, E->getDecl(),
+                      BaseQuals.getCVRQualifiers());
+  setObjCGCLValueClass(getContext(), E, LV);
+  return LV;
+}
+
+LValue
+CodeGenFunction::EmitObjCPropertyRefLValue(const ObjCPropertyRefExpr *E) {
+  // This is a special l-value that just issues sends when we load or store
+  // through it.
+  return LValue::MakePropertyRef(E, E->getType().getCVRQualifiers());
+}
+
+LValue CodeGenFunction::EmitObjCKVCRefLValue(
+                                const ObjCImplicitSetterGetterRefExpr *E) {
+  // This is a special l-value that just issues sends when we load or store
+  // through it.
+  return LValue::MakeKVCRef(E, E->getType().getCVRQualifiers());
+}
+
+LValue CodeGenFunction::EmitObjCSuperExprLValue(const ObjCSuperExpr *E) {
+  return EmitUnsupportedLValue(E, "use of super");
+}
+
+LValue CodeGenFunction::EmitStmtExprLValue(const StmtExpr *E) {
+  // Can only get l-value for message expression returning aggregate type
+  RValue RV = EmitAnyExprToTemp(E);
+  return LValue::MakeAddr(RV.getAggregateAddr(), MakeQualifiers(E->getType()));
+}
+
+RValue CodeGenFunction::EmitCall(QualType CalleeType, llvm::Value *Callee,
+                                 ReturnValueSlot ReturnValue,
+                                 CallExpr::const_arg_iterator ArgBeg,
+                                 CallExpr::const_arg_iterator ArgEnd,
+                                 const Decl *TargetDecl) {
+  // Get the actual function type. The callee type will always be a pointer to
+  // function type or a block pointer type.
+  assert(CalleeType->isFunctionPointerType() &&
+         "Call must have function pointer type!");
+
+  CalleeType = getContext().getCanonicalType(CalleeType);
+
+  const FunctionType *FnType
+    = cast<FunctionType>(cast<PointerType>(CalleeType)->getPointeeType());
+  QualType ResultType = FnType->getResultType();
+
+  CallArgList Args;
+  EmitCallArgs(Args, dyn_cast<FunctionProtoType>(FnType), ArgBeg, ArgEnd);
+
+  return EmitCall(CGM.getTypes().getFunctionInfo(Args, FnType),
+                  Callee, ReturnValue, Args, TargetDecl);
+}
+
+LValue CodeGenFunction::
+EmitPointerToDataMemberBinaryExpr(const BinaryOperator *E) {
+  llvm::Value *BaseV;
+  if (E->getOpcode() == BinaryOperator::PtrMemI)
+    BaseV = EmitScalarExpr(E->getLHS());
+  else
+    BaseV = EmitLValue(E->getLHS()).getAddress();
+  const llvm::Type *i8Ty = llvm::Type::getInt8PtrTy(getLLVMContext());
+  BaseV = Builder.CreateBitCast(BaseV, i8Ty);
+  llvm::Value *OffsetV = EmitScalarExpr(E->getRHS());
+  llvm::Value *AddV = Builder.CreateInBoundsGEP(BaseV, OffsetV, "add.ptr");
+
+  QualType Ty = E->getRHS()->getType();
+  Ty = Ty->getAs<MemberPointerType>()->getPointeeType();
+  
+  const llvm::Type *PType = ConvertType(getContext().getPointerType(Ty));
+  AddV = Builder.CreateBitCast(AddV, PType);
+  return LValue::MakeAddr(AddV, MakeQualifiers(Ty));
+}
+
diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp
new file mode 100644
index 0000000..84841bf
--- /dev/null
+++ b/lib/CodeGen/CGExprAgg.cpp
@@ -0,0 +1,797 @@
+//===--- CGExprAgg.cpp - Emit LLVM Code from Aggregate Expressions --------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This contains code to emit Aggregate Expr nodes as LLVM code.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CodeGenFunction.h"
+#include "CodeGenModule.h"
+#include "CGObjCRuntime.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/StmtVisitor.h"
+#include "llvm/Constants.h"
+#include "llvm/Function.h"
+#include "llvm/GlobalVariable.h"
+#include "llvm/Intrinsics.h"
+using namespace clang;
+using namespace CodeGen;
+
+//===----------------------------------------------------------------------===//
+//                        Aggregate Expression Emitter
+//===----------------------------------------------------------------------===//
+
+namespace  {
+class AggExprEmitter : public StmtVisitor<AggExprEmitter> {
+  CodeGenFunction &CGF;
+  CGBuilderTy &Builder;
+  llvm::Value *DestPtr;
+  bool VolatileDest;
+  bool IgnoreResult;
+  bool IsInitializer;
+  bool RequiresGCollection;
+public:
+  AggExprEmitter(CodeGenFunction &cgf, llvm::Value *destPtr, bool v,
+                 bool ignore, bool isinit, bool requiresGCollection)
+    : CGF(cgf), Builder(CGF.Builder),
+      DestPtr(destPtr), VolatileDest(v), IgnoreResult(ignore),
+      IsInitializer(isinit), RequiresGCollection(requiresGCollection) {
+  }
+
+  //===--------------------------------------------------------------------===//
+  //                               Utilities
+  //===--------------------------------------------------------------------===//
+
+  /// EmitAggLoadOfLValue - Given an expression with aggregate type that
+  /// represents a value lvalue, this method emits the address of the lvalue,
+  /// then loads the result into DestPtr.
+  void EmitAggLoadOfLValue(const Expr *E);
+
+  /// EmitFinalDestCopy - Perform the final copy to DestPtr, if desired.
+  void EmitFinalDestCopy(const Expr *E, LValue Src, bool Ignore = false);
+  void EmitFinalDestCopy(const Expr *E, RValue Src, bool Ignore = false);
+
+  //===--------------------------------------------------------------------===//
+  //                            Visitor Methods
+  //===--------------------------------------------------------------------===//
+
+  void VisitStmt(Stmt *S) {
+    CGF.ErrorUnsupported(S, "aggregate expression");
+  }
+  void VisitParenExpr(ParenExpr *PE) { Visit(PE->getSubExpr()); }
+  void VisitUnaryExtension(UnaryOperator *E) { Visit(E->getSubExpr()); }
+
+  // l-values.
+  void VisitDeclRefExpr(DeclRefExpr *DRE) { EmitAggLoadOfLValue(DRE); }
+  void VisitMemberExpr(MemberExpr *ME) { EmitAggLoadOfLValue(ME); }
+  void VisitUnaryDeref(UnaryOperator *E) { EmitAggLoadOfLValue(E); }
+  void VisitStringLiteral(StringLiteral *E) { EmitAggLoadOfLValue(E); }
+  void VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
+    EmitAggLoadOfLValue(E);
+  }
+  void VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
+    EmitAggLoadOfLValue(E);
+  }
+  void VisitBlockDeclRefExpr(const BlockDeclRefExpr *E) {
+    EmitAggLoadOfLValue(E);
+  }
+  void VisitPredefinedExpr(const PredefinedExpr *E) {
+    EmitAggLoadOfLValue(E);
+  }
+
+  // Operators.
+  void VisitCastExpr(CastExpr *E);
+  void VisitCallExpr(const CallExpr *E);
+  void VisitStmtExpr(const StmtExpr *E);
+  void VisitBinaryOperator(const BinaryOperator *BO);
+  void VisitPointerToDataMemberBinaryOperator(const BinaryOperator *BO);
+  void VisitBinAssign(const BinaryOperator *E);
+  void VisitBinComma(const BinaryOperator *E);
+  void VisitUnaryAddrOf(const UnaryOperator *E);
+
+  void VisitObjCMessageExpr(ObjCMessageExpr *E);
+  void VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
+    EmitAggLoadOfLValue(E);
+  }
+  void VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E);
+  void VisitObjCImplicitSetterGetterRefExpr(ObjCImplicitSetterGetterRefExpr *E);
+
+  void VisitConditionalOperator(const ConditionalOperator *CO);
+  void VisitChooseExpr(const ChooseExpr *CE);
+  void VisitInitListExpr(InitListExpr *E);
+  void VisitImplicitValueInitExpr(ImplicitValueInitExpr *E);
+  void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) {
+    Visit(DAE->getExpr());
+  }
+  void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E);
+  void VisitCXXConstructExpr(const CXXConstructExpr *E);
+  void VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E);
+  void VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E);
+  void VisitCXXTypeidExpr(CXXTypeidExpr *E) { EmitAggLoadOfLValue(E); }
+
+  void VisitVAArgExpr(VAArgExpr *E);
+
+  void EmitInitializationToLValue(Expr *E, LValue Address, QualType T);
+  void EmitNullInitializationToLValue(LValue Address, QualType T);
+  //  case Expr::ChooseExprClass:
+  void VisitCXXThrowExpr(const CXXThrowExpr *E) { CGF.EmitCXXThrowExpr(E); }
+};
+}  // end anonymous namespace.
+
+//===----------------------------------------------------------------------===//
+//                                Utilities
+//===----------------------------------------------------------------------===//
+
+/// EmitAggLoadOfLValue - Given an expression with aggregate type that
+/// represents a value lvalue, this method emits the address of the lvalue,
+/// then loads the result into DestPtr.
+void AggExprEmitter::EmitAggLoadOfLValue(const Expr *E) {
+  LValue LV = CGF.EmitLValue(E);
+  EmitFinalDestCopy(E, LV);
+}
+
+/// EmitFinalDestCopy - Perform the final copy to DestPtr, if desired.
+void AggExprEmitter::EmitFinalDestCopy(const Expr *E, RValue Src, bool Ignore) {
+  assert(Src.isAggregate() && "value must be aggregate value!");
+
+  // If the result is ignored, don't copy from the value.
+  if (DestPtr == 0) {
+    if (!Src.isVolatileQualified() || (IgnoreResult && Ignore))
+      return;
+    // If the source is volatile, we must read from it; to do that, we need
+    // some place to put it.
+    DestPtr = CGF.CreateMemTemp(E->getType(), "agg.tmp");
+  }
+
+  if (RequiresGCollection) {
+    CGF.CGM.getObjCRuntime().EmitGCMemmoveCollectable(CGF,
+                                              DestPtr, Src.getAggregateAddr(),
+                                              E->getType());
+    return;
+  }
+  // If the result of the assignment is used, copy the LHS there also.
+  // FIXME: Pass VolatileDest as well.  I think we also need to merge volatile
+  // from the source as well, as we can't eliminate it if either operand
+  // is volatile, unless copy has volatile for both source and destination..
+  CGF.EmitAggregateCopy(DestPtr, Src.getAggregateAddr(), E->getType(),
+                        VolatileDest|Src.isVolatileQualified());
+}
+
+/// EmitFinalDestCopy - Perform the final copy to DestPtr, if desired.
+void AggExprEmitter::EmitFinalDestCopy(const Expr *E, LValue Src, bool Ignore) {
+  assert(Src.isSimple() && "Can't have aggregate bitfield, vector, etc");
+
+  EmitFinalDestCopy(E, RValue::getAggregate(Src.getAddress(),
+                                            Src.isVolatileQualified()),
+                    Ignore);
+}
+
+//===----------------------------------------------------------------------===//
+//                            Visitor Methods
+//===----------------------------------------------------------------------===//
+
+void AggExprEmitter::VisitCastExpr(CastExpr *E) {
+  if (!DestPtr) {
+    Visit(E->getSubExpr());
+    return;
+  }
+
+  switch (E->getCastKind()) {
+  default: assert(0 && "Unhandled cast kind!");
+
+  case CastExpr::CK_ToUnion: {
+    // GCC union extension
+    QualType PtrTy =
+    CGF.getContext().getPointerType(E->getSubExpr()->getType());
+    llvm::Value *CastPtr = Builder.CreateBitCast(DestPtr,
+                                                 CGF.ConvertType(PtrTy));
+    EmitInitializationToLValue(E->getSubExpr(),
+                               LValue::MakeAddr(CastPtr, Qualifiers()), 
+                               E->getSubExpr()->getType());
+    break;
+  }
+
+  // FIXME: Remove the CK_Unknown check here.
+  case CastExpr::CK_Unknown:
+  case CastExpr::CK_NoOp:
+  case CastExpr::CK_UserDefinedConversion:
+  case CastExpr::CK_ConstructorConversion:
+    assert(CGF.getContext().hasSameUnqualifiedType(E->getSubExpr()->getType(),
+                                                   E->getType()) &&
+           "Implicit cast types must be compatible");
+    Visit(E->getSubExpr());
+    break;
+
+  case CastExpr::CK_NullToMemberPointer: {
+    // If the subexpression's type is the C++0x nullptr_t, emit the
+    // subexpression, which may have side effects.
+    if (E->getSubExpr()->getType()->isNullPtrType())
+      Visit(E->getSubExpr());
+
+    const llvm::Type *PtrDiffTy = 
+      CGF.ConvertType(CGF.getContext().getPointerDiffType());
+
+    llvm::Value *NullValue = llvm::Constant::getNullValue(PtrDiffTy);
+    llvm::Value *Ptr = Builder.CreateStructGEP(DestPtr, 0, "ptr");
+    Builder.CreateStore(NullValue, Ptr, VolatileDest);
+    
+    llvm::Value *Adj = Builder.CreateStructGEP(DestPtr, 1, "adj");
+    Builder.CreateStore(NullValue, Adj, VolatileDest);
+
+    break;
+  }
+      
+  case CastExpr::CK_BitCast: {
+    // This must be a member function pointer cast.
+    Visit(E->getSubExpr());
+    break;
+  }
+
+  case CastExpr::CK_DerivedToBaseMemberPointer:
+  case CastExpr::CK_BaseToDerivedMemberPointer: {
+    QualType SrcType = E->getSubExpr()->getType();
+    
+    llvm::Value *Src = CGF.CreateMemTemp(SrcType, "tmp");
+    CGF.EmitAggExpr(E->getSubExpr(), Src, SrcType.isVolatileQualified());
+    
+    llvm::Value *SrcPtr = Builder.CreateStructGEP(Src, 0, "src.ptr");
+    SrcPtr = Builder.CreateLoad(SrcPtr);
+    
+    llvm::Value *SrcAdj = Builder.CreateStructGEP(Src, 1, "src.adj");
+    SrcAdj = Builder.CreateLoad(SrcAdj);
+    
+    llvm::Value *DstPtr = Builder.CreateStructGEP(DestPtr, 0, "dst.ptr");
+    Builder.CreateStore(SrcPtr, DstPtr, VolatileDest);
+    
+    llvm::Value *DstAdj = Builder.CreateStructGEP(DestPtr, 1, "dst.adj");
+    
+    // Now See if we need to update the adjustment.
+    const CXXRecordDecl *BaseDecl = 
+      cast<CXXRecordDecl>(SrcType->getAs<MemberPointerType>()->
+                          getClass()->getAs<RecordType>()->getDecl());
+    const CXXRecordDecl *DerivedDecl = 
+      cast<CXXRecordDecl>(E->getType()->getAs<MemberPointerType>()->
+                          getClass()->getAs<RecordType>()->getDecl());
+    if (E->getCastKind() == CastExpr::CK_DerivedToBaseMemberPointer)
+      std::swap(DerivedDecl, BaseDecl);
+
+    if (llvm::Constant *Adj = 
+          CGF.CGM.GetNonVirtualBaseClassOffset(DerivedDecl, E->getBasePath())) {
+      if (E->getCastKind() == CastExpr::CK_DerivedToBaseMemberPointer)
+        SrcAdj = Builder.CreateSub(SrcAdj, Adj, "adj");
+      else
+        SrcAdj = Builder.CreateAdd(SrcAdj, Adj, "adj");
+    }
+    
+    Builder.CreateStore(SrcAdj, DstAdj, VolatileDest);
+    break;
+  }
+  }
+}
+
+void AggExprEmitter::VisitCallExpr(const CallExpr *E) {
+  if (E->getCallReturnType()->isReferenceType()) {
+    EmitAggLoadOfLValue(E);
+    return;
+  }
+
+  // If the struct doesn't require GC, we can just pass the destination
+  // directly to EmitCall.
+  if (!RequiresGCollection) {
+    CGF.EmitCallExpr(E, ReturnValueSlot(DestPtr, VolatileDest));
+    return;
+  }
+  
+  RValue RV = CGF.EmitCallExpr(E);
+  EmitFinalDestCopy(E, RV);
+}
+
+void AggExprEmitter::VisitObjCMessageExpr(ObjCMessageExpr *E) {
+  RValue RV = CGF.EmitObjCMessageExpr(E);
+  EmitFinalDestCopy(E, RV);
+}
+
+void AggExprEmitter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
+  RValue RV = CGF.EmitObjCPropertyGet(E);
+  EmitFinalDestCopy(E, RV);
+}
+
+void AggExprEmitter::VisitObjCImplicitSetterGetterRefExpr(
+                                   ObjCImplicitSetterGetterRefExpr *E) {
+  RValue RV = CGF.EmitObjCPropertyGet(E);
+  EmitFinalDestCopy(E, RV);
+}
+
+void AggExprEmitter::VisitBinComma(const BinaryOperator *E) {
+  CGF.EmitAnyExpr(E->getLHS(), 0, false, true);
+  CGF.EmitAggExpr(E->getRHS(), DestPtr, VolatileDest,
+                  /*IgnoreResult=*/false, IsInitializer);
+}
+
+void AggExprEmitter::VisitUnaryAddrOf(const UnaryOperator *E) {
+  // We have a member function pointer.
+  const MemberPointerType *MPT = E->getType()->getAs<MemberPointerType>();
+  (void) MPT;
+  assert(MPT->getPointeeType()->isFunctionProtoType() &&
+         "Unexpected member pointer type!");
+  
+  const DeclRefExpr *DRE = cast<DeclRefExpr>(E->getSubExpr());
+  const CXXMethodDecl *MD = 
+    cast<CXXMethodDecl>(DRE->getDecl())->getCanonicalDecl();
+
+  const llvm::Type *PtrDiffTy = 
+    CGF.ConvertType(CGF.getContext().getPointerDiffType());
+
+  llvm::Value *DstPtr = Builder.CreateStructGEP(DestPtr, 0, "dst.ptr");
+  llvm::Value *FuncPtr;
+  
+  if (MD->isVirtual()) {
+    int64_t Index = CGF.CGM.getVTables().getMethodVTableIndex(MD);
+    
+    // Itanium C++ ABI 2.3:
+    //   For a non-virtual function, this field is a simple function pointer. 
+    //   For a virtual function, it is 1 plus the virtual table offset 
+    //   (in bytes) of the function, represented as a ptrdiff_t. 
+    FuncPtr = llvm::ConstantInt::get(PtrDiffTy, (Index * 8) + 1);
+  } else {
+    const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>();
+    const llvm::Type *Ty =
+      CGF.CGM.getTypes().GetFunctionType(CGF.CGM.getTypes().getFunctionInfo(MD),
+                                         FPT->isVariadic());
+    llvm::Constant *Fn = CGF.CGM.GetAddrOfFunction(MD, Ty);
+    FuncPtr = llvm::ConstantExpr::getPtrToInt(Fn, PtrDiffTy);
+  }
+  Builder.CreateStore(FuncPtr, DstPtr, VolatileDest);
+
+  llvm::Value *AdjPtr = Builder.CreateStructGEP(DestPtr, 1, "dst.adj");
+  
+  // The adjustment will always be 0.
+  Builder.CreateStore(llvm::ConstantInt::get(PtrDiffTy, 0), AdjPtr,
+                      VolatileDest);
+}
+
+void AggExprEmitter::VisitStmtExpr(const StmtExpr *E) {
+  CGF.EmitCompoundStmt(*E->getSubStmt(), true, DestPtr, VolatileDest);
+}
+
+void AggExprEmitter::VisitBinaryOperator(const BinaryOperator *E) {
+  if (E->getOpcode() == BinaryOperator::PtrMemD ||
+      E->getOpcode() == BinaryOperator::PtrMemI)
+    VisitPointerToDataMemberBinaryOperator(E);
+  else
+    CGF.ErrorUnsupported(E, "aggregate binary expression");
+}
+
+void AggExprEmitter::VisitPointerToDataMemberBinaryOperator(
+                                                    const BinaryOperator *E) {
+  LValue LV = CGF.EmitPointerToDataMemberBinaryExpr(E);
+  EmitFinalDestCopy(E, LV);
+}
+
+void AggExprEmitter::VisitBinAssign(const BinaryOperator *E) {
+  // For an assignment to work, the value on the right has
+  // to be compatible with the value on the left.
+  assert(CGF.getContext().hasSameUnqualifiedType(E->getLHS()->getType(),
+                                                 E->getRHS()->getType())
+         && "Invalid assignment");
+  LValue LHS = CGF.EmitLValue(E->getLHS());
+
+  // We have to special case property setters, otherwise we must have
+  // a simple lvalue (no aggregates inside vectors, bitfields).
+  if (LHS.isPropertyRef()) {
+    llvm::Value *AggLoc = DestPtr;
+    if (!AggLoc)
+      AggLoc = CGF.CreateMemTemp(E->getRHS()->getType());
+    CGF.EmitAggExpr(E->getRHS(), AggLoc, VolatileDest);
+    CGF.EmitObjCPropertySet(LHS.getPropertyRefExpr(),
+                            RValue::getAggregate(AggLoc, VolatileDest));
+  } else if (LHS.isKVCRef()) {
+    llvm::Value *AggLoc = DestPtr;
+    if (!AggLoc)
+      AggLoc = CGF.CreateMemTemp(E->getRHS()->getType());
+    CGF.EmitAggExpr(E->getRHS(), AggLoc, VolatileDest);
+    CGF.EmitObjCPropertySet(LHS.getKVCRefExpr(),
+                            RValue::getAggregate(AggLoc, VolatileDest));
+  } else {
+    bool RequiresGCollection = false;
+    if (CGF.getContext().getLangOptions().NeXTRuntime) {
+      QualType LHSTy = E->getLHS()->getType();
+      if (const RecordType *FDTTy = LHSTy.getTypePtr()->getAs<RecordType>())
+        RequiresGCollection = FDTTy->getDecl()->hasObjectMember();
+    }
+    // Codegen the RHS so that it stores directly into the LHS.
+    CGF.EmitAggExpr(E->getRHS(), LHS.getAddress(), LHS.isVolatileQualified(),
+                    false, false, RequiresGCollection);
+    EmitFinalDestCopy(E, LHS, true);
+  }
+}
+
+void AggExprEmitter::VisitConditionalOperator(const ConditionalOperator *E) {
+  if (!E->getLHS()) {
+    CGF.ErrorUnsupported(E, "conditional operator with missing LHS");
+    return;
+  }
+
+  llvm::BasicBlock *LHSBlock = CGF.createBasicBlock("cond.true");
+  llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("cond.false");
+  llvm::BasicBlock *ContBlock = CGF.createBasicBlock("cond.end");
+
+  CGF.EmitBranchOnBoolExpr(E->getCond(), LHSBlock, RHSBlock);
+
+  CGF.BeginConditionalBranch();
+  CGF.EmitBlock(LHSBlock);
+
+  // Handle the GNU extension for missing LHS.
+  assert(E->getLHS() && "Must have LHS for aggregate value");
+
+  Visit(E->getLHS());
+  CGF.EndConditionalBranch();
+  CGF.EmitBranch(ContBlock);
+
+  CGF.BeginConditionalBranch();
+  CGF.EmitBlock(RHSBlock);
+
+  Visit(E->getRHS());
+  CGF.EndConditionalBranch();
+  CGF.EmitBranch(ContBlock);
+
+  CGF.EmitBlock(ContBlock);
+}
+
+void AggExprEmitter::VisitChooseExpr(const ChooseExpr *CE) {
+  Visit(CE->getChosenSubExpr(CGF.getContext()));
+}
+
+void AggExprEmitter::VisitVAArgExpr(VAArgExpr *VE) {
+  llvm::Value *ArgValue = CGF.EmitVAListRef(VE->getSubExpr());
+  llvm::Value *ArgPtr = CGF.EmitVAArg(ArgValue, VE->getType());
+
+  if (!ArgPtr) {
+    CGF.ErrorUnsupported(VE, "aggregate va_arg expression");
+    return;
+  }
+
+  EmitFinalDestCopy(VE, LValue::MakeAddr(ArgPtr, Qualifiers()));
+}
+
+void AggExprEmitter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
+  llvm::Value *Val = DestPtr;
+
+  if (!Val) {
+    // Create a temporary variable.
+    Val = CGF.CreateMemTemp(E->getType(), "tmp");
+
+    // FIXME: volatile
+    CGF.EmitAggExpr(E->getSubExpr(), Val, false);
+  } else
+    Visit(E->getSubExpr());
+
+  // Don't make this a live temporary if we're emitting an initializer expr.
+  if (!IsInitializer)
+    CGF.PushCXXTemporary(E->getTemporary(), Val);
+}
+
+void
+AggExprEmitter::VisitCXXConstructExpr(const CXXConstructExpr *E) {
+  llvm::Value *Val = DestPtr;
+
+  if (!Val) {
+    // Create a temporary variable.
+    Val = CGF.CreateMemTemp(E->getType(), "tmp");
+  }
+
+  if (E->requiresZeroInitialization())
+    EmitNullInitializationToLValue(LValue::MakeAddr(Val, 
+                                                    // FIXME: Qualifiers()?
+                                                 E->getType().getQualifiers()),
+                                   E->getType());
+
+  CGF.EmitCXXConstructExpr(Val, E);
+}
+
+void AggExprEmitter::VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E) {
+  llvm::Value *Val = DestPtr;
+
+  CGF.EmitCXXExprWithTemporaries(E, Val, VolatileDest, IsInitializer);
+}
+
+void AggExprEmitter::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) {
+  llvm::Value *Val = DestPtr;
+
+  if (!Val) {
+    // Create a temporary variable.
+    Val = CGF.CreateMemTemp(E->getType(), "tmp");
+  }
+  LValue LV = LValue::MakeAddr(Val, Qualifiers());
+  EmitNullInitializationToLValue(LV, E->getType());
+}
+
+void AggExprEmitter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) {
+  llvm::Value *Val = DestPtr;
+
+  if (!Val) {
+    // Create a temporary variable.
+    Val = CGF.CreateMemTemp(E->getType(), "tmp");
+  }
+  LValue LV = LValue::MakeAddr(Val, Qualifiers());
+  EmitNullInitializationToLValue(LV, E->getType());
+}
+
+void 
+AggExprEmitter::EmitInitializationToLValue(Expr* E, LValue LV, QualType T) {
+  // FIXME: Ignore result?
+  // FIXME: Are initializers affected by volatile?
+  if (isa<ImplicitValueInitExpr>(E)) {
+    EmitNullInitializationToLValue(LV, T);
+  } else if (T->isReferenceType()) {
+    RValue RV = CGF.EmitReferenceBindingToExpr(E, /*IsInitializer=*/false);
+    CGF.EmitStoreThroughLValue(RV, LV, T);
+  } else if (T->isAnyComplexType()) {
+    CGF.EmitComplexExprIntoAddr(E, LV.getAddress(), false);
+  } else if (CGF.hasAggregateLLVMType(T)) {
+    CGF.EmitAnyExpr(E, LV.getAddress(), false);
+  } else {
+    CGF.EmitStoreThroughLValue(CGF.EmitAnyExpr(E), LV, T);
+  }
+}
+
+void AggExprEmitter::EmitNullInitializationToLValue(LValue LV, QualType T) {
+  if (!CGF.hasAggregateLLVMType(T)) {
+    // For non-aggregates, we can store zero
+    llvm::Value *Null = llvm::Constant::getNullValue(CGF.ConvertType(T));
+    CGF.EmitStoreThroughLValue(RValue::get(Null), LV, T);
+  } else {
+    // Otherwise, just memset the whole thing to zero.  This is legal
+    // because in LLVM, all default initializers are guaranteed to have a
+    // bit pattern of all zeros.
+    // FIXME: That isn't true for member pointers!
+    // There's a potential optimization opportunity in combining
+    // memsets; that would be easy for arrays, but relatively
+    // difficult for structures with the current code.
+    CGF.EmitMemSetToZero(LV.getAddress(), T);
+  }
+}
+
+void AggExprEmitter::VisitInitListExpr(InitListExpr *E) {
+#if 0
+  // FIXME: Assess perf here?  Figure out what cases are worth optimizing here
+  // (Length of globals? Chunks of zeroed-out space?).
+  //
+  // If we can, prefer a copy from a global; this is a lot less code for long
+  // globals, and it's easier for the current optimizers to analyze.
+  if (llvm::Constant* C = CGF.CGM.EmitConstantExpr(E, E->getType(), &CGF)) {
+    llvm::GlobalVariable* GV =
+    new llvm::GlobalVariable(CGF.CGM.getModule(), C->getType(), true,
+                             llvm::GlobalValue::InternalLinkage, C, "");
+    EmitFinalDestCopy(E, LValue::MakeAddr(GV, Qualifiers()));
+    return;
+  }
+#endif
+  if (E->hadArrayRangeDesignator()) {
+    CGF.ErrorUnsupported(E, "GNU array range designator extension");
+  }
+
+  // Handle initialization of an array.
+  if (E->getType()->isArrayType()) {
+    const llvm::PointerType *APType =
+      cast<llvm::PointerType>(DestPtr->getType());
+    const llvm::ArrayType *AType =
+      cast<llvm::ArrayType>(APType->getElementType());
+
+    uint64_t NumInitElements = E->getNumInits();
+
+    if (E->getNumInits() > 0) {
+      QualType T1 = E->getType();
+      QualType T2 = E->getInit(0)->getType();
+      if (CGF.getContext().hasSameUnqualifiedType(T1, T2)) {
+        EmitAggLoadOfLValue(E->getInit(0));
+        return;
+      }
+    }
+
+    uint64_t NumArrayElements = AType->getNumElements();
+    QualType ElementType = CGF.getContext().getCanonicalType(E->getType());
+    ElementType = CGF.getContext().getAsArrayType(ElementType)->getElementType();
+
+    // FIXME: were we intentionally ignoring address spaces and GC attributes?
+    Qualifiers Quals = CGF.MakeQualifiers(ElementType);
+
+    for (uint64_t i = 0; i != NumArrayElements; ++i) {
+      llvm::Value *NextVal = Builder.CreateStructGEP(DestPtr, i, ".array");
+      if (i < NumInitElements)
+        EmitInitializationToLValue(E->getInit(i),
+                                   LValue::MakeAddr(NextVal, Quals), 
+                                   ElementType);
+      else
+        EmitNullInitializationToLValue(LValue::MakeAddr(NextVal, Quals),
+                                       ElementType);
+    }
+    return;
+  }
+
+  assert(E->getType()->isRecordType() && "Only support structs/unions here!");
+
+  // Do struct initialization; this code just sets each individual member
+  // to the approprate value.  This makes bitfield support automatic;
+  // the disadvantage is that the generated code is more difficult for
+  // the optimizer, especially with bitfields.
+  unsigned NumInitElements = E->getNumInits();
+  RecordDecl *SD = E->getType()->getAs<RecordType>()->getDecl();
+  unsigned CurInitVal = 0;
+
+  if (E->getType()->isUnionType()) {
+    // Only initialize one field of a union. The field itself is
+    // specified by the initializer list.
+    if (!E->getInitializedFieldInUnion()) {
+      // Empty union; we have nothing to do.
+
+#ifndef NDEBUG
+      // Make sure that it's really an empty and not a failure of
+      // semantic analysis.
+      for (RecordDecl::field_iterator Field = SD->field_begin(),
+                                   FieldEnd = SD->field_end();
+           Field != FieldEnd; ++Field)
+        assert(Field->isUnnamedBitfield() && "Only unnamed bitfields allowed");
+#endif
+      return;
+    }
+
+    // FIXME: volatility
+    FieldDecl *Field = E->getInitializedFieldInUnion();
+    LValue FieldLoc = CGF.EmitLValueForFieldInitialization(DestPtr, Field, 0);
+
+    if (NumInitElements) {
+      // Store the initializer into the field
+      EmitInitializationToLValue(E->getInit(0), FieldLoc, Field->getType());
+    } else {
+      // Default-initialize to null
+      EmitNullInitializationToLValue(FieldLoc, Field->getType());
+    }
+
+    return;
+  }
+  
+  // If we're initializing the whole aggregate, just do it in place.
+  // FIXME: This is a hack around an AST bug (PR6537).
+  if (NumInitElements == 1 && E->getType() == E->getInit(0)->getType()) {
+    EmitInitializationToLValue(E->getInit(0),
+                               LValue::MakeAddr(DestPtr, Qualifiers()),
+                               E->getType());
+    return;
+  }
+  
+
+  // Here we iterate over the fields; this makes it simpler to both
+  // default-initialize fields and skip over unnamed fields.
+  for (RecordDecl::field_iterator Field = SD->field_begin(),
+                               FieldEnd = SD->field_end();
+       Field != FieldEnd; ++Field) {
+    // We're done once we hit the flexible array member
+    if (Field->getType()->isIncompleteArrayType())
+      break;
+
+    if (Field->isUnnamedBitfield())
+      continue;
+
+    // FIXME: volatility
+    LValue FieldLoc = CGF.EmitLValueForFieldInitialization(DestPtr, *Field, 0);
+    // We never generate write-barries for initialized fields.
+    LValue::SetObjCNonGC(FieldLoc, true);
+    if (CurInitVal < NumInitElements) {
+      // Store the initializer into the field.
+      EmitInitializationToLValue(E->getInit(CurInitVal++), FieldLoc,
+                                 Field->getType());
+    } else {
+      // We're out of initalizers; default-initialize to null
+      EmitNullInitializationToLValue(FieldLoc, Field->getType());
+    }
+  }
+}
+
+//===----------------------------------------------------------------------===//
+//                        Entry Points into this File
+//===----------------------------------------------------------------------===//
+
+/// EmitAggExpr - Emit the computation of the specified expression of aggregate
+/// type.  The result is computed into DestPtr.  Note that if DestPtr is null,
+/// the value of the aggregate expression is not needed.  If VolatileDest is
+/// true, DestPtr cannot be 0.
+//
+// FIXME: Take Qualifiers object.
+void CodeGenFunction::EmitAggExpr(const Expr *E, llvm::Value *DestPtr,
+                                  bool VolatileDest, bool IgnoreResult,
+                                  bool IsInitializer,
+                                  bool RequiresGCollection) {
+  assert(E && hasAggregateLLVMType(E->getType()) &&
+         "Invalid aggregate expression to emit");
+  assert ((DestPtr != 0 || VolatileDest == false)
+          && "volatile aggregate can't be 0");
+
+  AggExprEmitter(*this, DestPtr, VolatileDest, IgnoreResult, IsInitializer,
+                 RequiresGCollection)
+    .Visit(const_cast<Expr*>(E));
+}
+
+LValue CodeGenFunction::EmitAggExprToLValue(const Expr *E) {
+  assert(hasAggregateLLVMType(E->getType()) && "Invalid argument!");
+  Qualifiers Q = MakeQualifiers(E->getType());
+  llvm::Value *Temp = CreateMemTemp(E->getType());
+  EmitAggExpr(E, Temp, Q.hasVolatile());
+  return LValue::MakeAddr(Temp, Q);
+}
+
+void CodeGenFunction::EmitAggregateClear(llvm::Value *DestPtr, QualType Ty) {
+  assert(!Ty->isAnyComplexType() && "Shouldn't happen for complex");
+
+  EmitMemSetToZero(DestPtr, Ty);
+}
+
+void CodeGenFunction::EmitAggregateCopy(llvm::Value *DestPtr,
+                                        llvm::Value *SrcPtr, QualType Ty,
+                                        bool isVolatile) {
+  assert(!Ty->isAnyComplexType() && "Shouldn't happen for complex");
+
+  // Aggregate assignment turns into llvm.memcpy.  This is almost valid per
+  // C99 6.5.16.1p3, which states "If the value being stored in an object is
+  // read from another object that overlaps in anyway the storage of the first
+  // object, then the overlap shall be exact and the two objects shall have
+  // qualified or unqualified versions of a compatible type."
+  //
+  // memcpy is not defined if the source and destination pointers are exactly
+  // equal, but other compilers do this optimization, and almost every memcpy
+  // implementation handles this case safely.  If there is a libc that does not
+  // safely handle this, we can add a target hook.
+  const llvm::Type *BP = llvm::Type::getInt8PtrTy(VMContext);
+  if (DestPtr->getType() != BP)
+    DestPtr = Builder.CreateBitCast(DestPtr, BP, "tmp");
+  if (SrcPtr->getType() != BP)
+    SrcPtr = Builder.CreateBitCast(SrcPtr, BP, "tmp");
+
+  // Get size and alignment info for this aggregate.
+  std::pair<uint64_t, unsigned> TypeInfo = getContext().getTypeInfo(Ty);
+
+  // FIXME: Handle variable sized types.
+  const llvm::Type *IntPtr =
+          llvm::IntegerType::get(VMContext, LLVMPointerWidth);
+
+  // FIXME: If we have a volatile struct, the optimizer can remove what might
+  // appear to be `extra' memory ops:
+  //
+  // volatile struct { int i; } a, b;
+  //
+  // int main() {
+  //   a = b;
+  //   a = b;
+  // }
+  //
+  // we need to use a different call here.  We use isVolatile to indicate when
+  // either the source or the destination is volatile.
+  const llvm::Type *I1Ty = llvm::Type::getInt1Ty(VMContext);
+  const llvm::Type *I8Ty = llvm::Type::getInt8Ty(VMContext);
+  const llvm::Type *I32Ty = llvm::Type::getInt32Ty(VMContext);
+
+  const llvm::PointerType *DPT = cast<llvm::PointerType>(DestPtr->getType());
+  const llvm::Type *DBP = llvm::PointerType::get(I8Ty, DPT->getAddressSpace());
+  if (DestPtr->getType() != DBP)
+    DestPtr = Builder.CreateBitCast(DestPtr, DBP, "tmp");
+
+  const llvm::PointerType *SPT = cast<llvm::PointerType>(SrcPtr->getType());
+  const llvm::Type *SBP = llvm::PointerType::get(I8Ty, SPT->getAddressSpace());
+  if (SrcPtr->getType() != SBP)
+    SrcPtr = Builder.CreateBitCast(SrcPtr, SBP, "tmp");
+
+  Builder.CreateCall5(CGM.getMemCpyFn(DestPtr->getType(), SrcPtr->getType(),
+                                      IntPtr),
+                      DestPtr, SrcPtr,
+                      // TypeInfo.first describes size in bits.
+                      llvm::ConstantInt::get(IntPtr, TypeInfo.first/8),
+                      llvm::ConstantInt::get(I32Ty,  TypeInfo.second/8),
+                      llvm::ConstantInt::get(I1Ty,  isVolatile));
+}
diff --git a/lib/CodeGen/CGExprCXX.cpp b/lib/CodeGen/CGExprCXX.cpp
new file mode 100644
index 0000000..934d2db
--- /dev/null
+++ b/lib/CodeGen/CGExprCXX.cpp
@@ -0,0 +1,940 @@
+//===--- CGExprCXX.cpp - Emit LLVM Code for C++ expressions ---------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This contains code dealing with code generation of C++ expressions
+//
+//===----------------------------------------------------------------------===//
+
+#include "CodeGenFunction.h"
+using namespace clang;
+using namespace CodeGen;
+
+RValue CodeGenFunction::EmitCXXMemberCall(const CXXMethodDecl *MD,
+                                          llvm::Value *Callee,
+                                          ReturnValueSlot ReturnValue,
+                                          llvm::Value *This,
+                                          llvm::Value *VTT,
+                                          CallExpr::const_arg_iterator ArgBeg,
+                                          CallExpr::const_arg_iterator ArgEnd) {
+  assert(MD->isInstance() &&
+         "Trying to emit a member call expr on a static method!");
+
+  const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>();
+
+  CallArgList Args;
+
+  // Push the this ptr.
+  Args.push_back(std::make_pair(RValue::get(This),
+                                MD->getThisType(getContext())));
+
+  // If there is a VTT parameter, emit it.
+  if (VTT) {
+    QualType T = getContext().getPointerType(getContext().VoidPtrTy);
+    Args.push_back(std::make_pair(RValue::get(VTT), T));
+  }
+  
+  // And the rest of the call args
+  EmitCallArgs(Args, FPT, ArgBeg, ArgEnd);
+
+  QualType ResultType = FPT->getResultType();
+  return EmitCall(CGM.getTypes().getFunctionInfo(ResultType, Args,
+                                                 FPT->getExtInfo()),
+                  Callee, ReturnValue, Args, MD);
+}
+
+/// canDevirtualizeMemberFunctionCalls - Checks whether virtual calls on given
+/// expr can be devirtualized.
+static bool canDevirtualizeMemberFunctionCalls(const Expr *Base) {
+  if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Base)) {
+    if (const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl())) {
+      // This is a record decl. We know the type and can devirtualize it.
+      return VD->getType()->isRecordType();
+    }
+    
+    return false;
+  }
+  
+  // We can always devirtualize calls on temporary object expressions.
+  if (isa<CXXConstructExpr>(Base))
+    return true;
+  
+  // And calls on bound temporaries.
+  if (isa<CXXBindTemporaryExpr>(Base))
+    return true;
+  
+  // Check if this is a call expr that returns a record type.
+  if (const CallExpr *CE = dyn_cast<CallExpr>(Base))
+    return CE->getCallReturnType()->isRecordType();
+  
+  // We can't devirtualize the call.
+  return false;
+}
+
+RValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE,
+                                              ReturnValueSlot ReturnValue) {
+  if (isa<BinaryOperator>(CE->getCallee()->IgnoreParens())) 
+    return EmitCXXMemberPointerCallExpr(CE, ReturnValue);
+      
+  const MemberExpr *ME = cast<MemberExpr>(CE->getCallee()->IgnoreParens());
+  const CXXMethodDecl *MD = cast<CXXMethodDecl>(ME->getMemberDecl());
+
+  if (MD->isStatic()) {
+    // The method is static, emit it as we would a regular call.
+    llvm::Value *Callee = CGM.GetAddrOfFunction(MD);
+    return EmitCall(getContext().getPointerType(MD->getType()), Callee,
+                    ReturnValue, CE->arg_begin(), CE->arg_end());
+  }
+  
+  const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>();
+
+  const llvm::Type *Ty =
+    CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD),
+                                   FPT->isVariadic());
+  llvm::Value *This;
+
+  if (ME->isArrow())
+    This = EmitScalarExpr(ME->getBase());
+  else {
+    LValue BaseLV = EmitLValue(ME->getBase());
+    This = BaseLV.getAddress();
+  }
+
+  if (MD->isCopyAssignment() && MD->isTrivial()) {
+    // We don't like to generate the trivial copy assignment operator when
+    // it isn't necessary; just produce the proper effect here.
+    llvm::Value *RHS = EmitLValue(*CE->arg_begin()).getAddress();
+    EmitAggregateCopy(This, RHS, CE->getType());
+    return RValue::get(This);
+  }
+
+  // C++ [class.virtual]p12:
+  //   Explicit qualification with the scope operator (5.1) suppresses the
+  //   virtual call mechanism.
+  //
+  // We also don't emit a virtual call if the base expression has a record type
+  // because then we know what the type is.
+  llvm::Value *Callee;
+  if (const CXXDestructorDecl *Destructor
+             = dyn_cast<CXXDestructorDecl>(MD)) {
+    if (Destructor->isTrivial())
+      return RValue::get(0);
+    if (MD->isVirtual() && !ME->hasQualifier() && 
+        !canDevirtualizeMemberFunctionCalls(ME->getBase())) {
+      Callee = BuildVirtualCall(Destructor, Dtor_Complete, This, Ty); 
+    } else {
+      Callee = CGM.GetAddrOfFunction(GlobalDecl(Destructor, Dtor_Complete), Ty);
+    }
+  } else if (MD->isVirtual() && !ME->hasQualifier() && 
+             !canDevirtualizeMemberFunctionCalls(ME->getBase())) {
+    Callee = BuildVirtualCall(MD, This, Ty); 
+  } else {
+    Callee = CGM.GetAddrOfFunction(MD, Ty);
+  }
+
+  return EmitCXXMemberCall(MD, Callee, ReturnValue, This, /*VTT=*/0,
+                           CE->arg_begin(), CE->arg_end());
+}
+
+RValue
+CodeGenFunction::EmitCXXMemberPointerCallExpr(const CXXMemberCallExpr *E,
+                                              ReturnValueSlot ReturnValue) {
+  const BinaryOperator *BO =
+      cast<BinaryOperator>(E->getCallee()->IgnoreParens());
+  const Expr *BaseExpr = BO->getLHS();
+  const Expr *MemFnExpr = BO->getRHS();
+  
+  const MemberPointerType *MPT = 
+    MemFnExpr->getType()->getAs<MemberPointerType>();
+  const FunctionProtoType *FPT = 
+    MPT->getPointeeType()->getAs<FunctionProtoType>();
+  const CXXRecordDecl *RD = 
+    cast<CXXRecordDecl>(MPT->getClass()->getAs<RecordType>()->getDecl());
+
+  const llvm::FunctionType *FTy = 
+    CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(RD, FPT),
+                                   FPT->isVariadic());
+
+  const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext);
+
+  // Get the member function pointer.
+  llvm::Value *MemFnPtr = CreateMemTemp(MemFnExpr->getType(), "mem.fn");
+  EmitAggExpr(MemFnExpr, MemFnPtr, /*VolatileDest=*/false);
+
+  // Emit the 'this' pointer.
+  llvm::Value *This;
+  
+  if (BO->getOpcode() == BinaryOperator::PtrMemI)
+    This = EmitScalarExpr(BaseExpr);
+  else 
+    This = EmitLValue(BaseExpr).getAddress();
+  
+  // Adjust it.
+  llvm::Value *Adj = Builder.CreateStructGEP(MemFnPtr, 1);
+  Adj = Builder.CreateLoad(Adj, "mem.fn.adj");
+  
+  llvm::Value *Ptr = Builder.CreateBitCast(This, Int8PtrTy, "ptr");
+  Ptr = Builder.CreateGEP(Ptr, Adj, "adj");
+  
+  This = Builder.CreateBitCast(Ptr, This->getType(), "this");
+  
+  llvm::Value *FnPtr = Builder.CreateStructGEP(MemFnPtr, 0, "mem.fn.ptr");
+  
+  const llvm::Type *PtrDiffTy = ConvertType(getContext().getPointerDiffType());
+
+  llvm::Value *FnAsInt = Builder.CreateLoad(FnPtr, "fn");
+  
+  // If the LSB in the function pointer is 1, the function pointer points to
+  // a virtual function.
+  llvm::Value *IsVirtual 
+    = Builder.CreateAnd(FnAsInt, llvm::ConstantInt::get(PtrDiffTy, 1),
+                        "and");
+  
+  IsVirtual = Builder.CreateTrunc(IsVirtual,
+                                  llvm::Type::getInt1Ty(VMContext));
+  
+  llvm::BasicBlock *FnVirtual = createBasicBlock("fn.virtual");
+  llvm::BasicBlock *FnNonVirtual = createBasicBlock("fn.nonvirtual");
+  llvm::BasicBlock *FnEnd = createBasicBlock("fn.end");
+  
+  Builder.CreateCondBr(IsVirtual, FnVirtual, FnNonVirtual);
+  EmitBlock(FnVirtual);
+  
+  const llvm::Type *VTableTy = 
+    FTy->getPointerTo()->getPointerTo();
+
+  llvm::Value *VTable = Builder.CreateBitCast(This, VTableTy->getPointerTo());
+  VTable = Builder.CreateLoad(VTable);
+  
+  VTable = Builder.CreateBitCast(VTable, Int8PtrTy);
+  llvm::Value *VTableOffset = 
+    Builder.CreateSub(FnAsInt, llvm::ConstantInt::get(PtrDiffTy, 1));
+  
+  VTable = Builder.CreateGEP(VTable, VTableOffset, "fn");
+  VTable = Builder.CreateBitCast(VTable, VTableTy);
+  
+  llvm::Value *VirtualFn = Builder.CreateLoad(VTable, "virtualfn");
+  
+  EmitBranch(FnEnd);
+  EmitBlock(FnNonVirtual);
+  
+  // If the function is not virtual, just load the pointer.
+  llvm::Value *NonVirtualFn = Builder.CreateLoad(FnPtr, "fn");
+  NonVirtualFn = Builder.CreateIntToPtr(NonVirtualFn, FTy->getPointerTo());
+  
+  EmitBlock(FnEnd);
+
+  llvm::PHINode *Callee = Builder.CreatePHI(FTy->getPointerTo());
+  Callee->reserveOperandSpace(2);
+  Callee->addIncoming(VirtualFn, FnVirtual);
+  Callee->addIncoming(NonVirtualFn, FnNonVirtual);
+
+  CallArgList Args;
+
+  QualType ThisType = 
+    getContext().getPointerType(getContext().getTagDeclType(RD));
+
+  // Push the this ptr.
+  Args.push_back(std::make_pair(RValue::get(This), ThisType));
+  
+  // And the rest of the call args
+  EmitCallArgs(Args, FPT, E->arg_begin(), E->arg_end());
+  const FunctionType *BO_FPT = BO->getType()->getAs<FunctionProtoType>();
+  return EmitCall(CGM.getTypes().getFunctionInfo(Args, BO_FPT), Callee, 
+                  ReturnValue, Args);
+}
+
+RValue
+CodeGenFunction::EmitCXXOperatorMemberCallExpr(const CXXOperatorCallExpr *E,
+                                               const CXXMethodDecl *MD,
+                                               ReturnValueSlot ReturnValue) {
+  assert(MD->isInstance() &&
+         "Trying to emit a member call expr on a static method!");
+
+  if (MD->isCopyAssignment()) {
+    const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(MD->getDeclContext());
+    if (ClassDecl->hasTrivialCopyAssignment()) {
+      assert(!ClassDecl->hasUserDeclaredCopyAssignment() &&
+             "EmitCXXOperatorMemberCallExpr - user declared copy assignment");
+      llvm::Value *This = EmitLValue(E->getArg(0)).getAddress();
+      llvm::Value *Src = EmitLValue(E->getArg(1)).getAddress();
+      QualType Ty = E->getType();
+      EmitAggregateCopy(This, Src, Ty);
+      return RValue::get(This);
+    }
+  }
+
+  const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>();
+  const llvm::Type *Ty =
+    CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD),
+                                   FPT->isVariadic());
+
+  llvm::Value *This = EmitLValue(E->getArg(0)).getAddress();
+
+  llvm::Value *Callee;
+  if (MD->isVirtual() && !canDevirtualizeMemberFunctionCalls(E->getArg(0)))
+    Callee = BuildVirtualCall(MD, This, Ty);
+  else
+    Callee = CGM.GetAddrOfFunction(MD, Ty);
+
+  return EmitCXXMemberCall(MD, Callee, ReturnValue, This, /*VTT=*/0,
+                           E->arg_begin() + 1, E->arg_end());
+}
+
+void
+CodeGenFunction::EmitCXXConstructExpr(llvm::Value *Dest,
+                                      const CXXConstructExpr *E) {
+  assert(Dest && "Must have a destination!");
+  const CXXConstructorDecl *CD = E->getConstructor();
+  const ConstantArrayType *Array =
+  getContext().getAsConstantArrayType(E->getType());
+  // For a copy constructor, even if it is trivial, must fall thru so
+  // its argument is code-gen'ed.
+  if (!CD->isCopyConstructor()) {
+    QualType InitType = E->getType();
+    if (Array)
+      InitType = getContext().getBaseElementType(Array);
+    const CXXRecordDecl *RD =
+    cast<CXXRecordDecl>(InitType->getAs<RecordType>()->getDecl());
+    if (RD->hasTrivialConstructor())
+      return;
+  }
+  // Code gen optimization to eliminate copy constructor and return
+  // its first argument instead.
+  if (getContext().getLangOptions().ElideConstructors && E->isElidable()) {
+    const Expr *Arg = E->getArg(0)->getTemporaryObject();
+    EmitAggExpr(Arg, Dest, false);
+    return;
+  }
+  if (Array) {
+    QualType BaseElementTy = getContext().getBaseElementType(Array);
+    const llvm::Type *BasePtr = ConvertType(BaseElementTy);
+    BasePtr = llvm::PointerType::getUnqual(BasePtr);
+    llvm::Value *BaseAddrPtr =
+    Builder.CreateBitCast(Dest, BasePtr);
+    
+    EmitCXXAggrConstructorCall(CD, Array, BaseAddrPtr, 
+                               E->arg_begin(), E->arg_end());
+  }
+  else
+    // Call the constructor.
+    EmitCXXConstructorCall(CD, 
+                           E->isBaseInitialization()? Ctor_Base : Ctor_Complete, 
+                           Dest,
+                           E->arg_begin(), E->arg_end());
+}
+
+static CharUnits CalculateCookiePadding(ASTContext &Ctx, QualType ElementType) {
+  const RecordType *RT = ElementType->getAs<RecordType>();
+  if (!RT)
+    return CharUnits::Zero();
+  
+  const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());
+  if (!RD)
+    return CharUnits::Zero();
+  
+  // Check if the class has a trivial destructor.
+  if (RD->hasTrivialDestructor()) {
+    // Check if the usual deallocation function takes two arguments.
+    const CXXMethodDecl *UsualDeallocationFunction = 0;
+    
+    DeclarationName OpName =
+      Ctx.DeclarationNames.getCXXOperatorName(OO_Array_Delete);
+    DeclContext::lookup_const_iterator Op, OpEnd;
+    for (llvm::tie(Op, OpEnd) = RD->lookup(OpName);
+         Op != OpEnd; ++Op) {
+      const CXXMethodDecl *Delete = cast<CXXMethodDecl>(*Op);
+
+      if (Delete->isUsualDeallocationFunction()) {
+        UsualDeallocationFunction = Delete;
+        break;
+      }
+    }
+    
+    // No usual deallocation function, we don't need a cookie.
+    if (!UsualDeallocationFunction)
+      return CharUnits::Zero();
+    
+    // The usual deallocation function doesn't take a size_t argument, so we
+    // don't need a cookie.
+    if (UsualDeallocationFunction->getNumParams() == 1)
+      return CharUnits::Zero();
+        
+    assert(UsualDeallocationFunction->getNumParams() == 2 && 
+           "Unexpected deallocation function type!");
+  }  
+  
+  // Padding is the maximum of sizeof(size_t) and alignof(ElementType)
+  return std::max(Ctx.getTypeSizeInChars(Ctx.getSizeType()),
+                  Ctx.getTypeAlignInChars(ElementType));
+}
+
+static CharUnits CalculateCookiePadding(ASTContext &Ctx, const CXXNewExpr *E) {
+  if (!E->isArray())
+    return CharUnits::Zero();
+
+  // No cookie is required if the new operator being used is 
+  // ::operator new[](size_t, void*).
+  const FunctionDecl *OperatorNew = E->getOperatorNew();
+  if (OperatorNew->getDeclContext()->getLookupContext()->isFileContext()) {
+    if (OperatorNew->getNumParams() == 2) {
+      CanQualType ParamType = 
+        Ctx.getCanonicalType(OperatorNew->getParamDecl(1)->getType());
+      
+      if (ParamType == Ctx.VoidPtrTy)
+        return CharUnits::Zero();
+    }
+  }
+      
+  return CalculateCookiePadding(Ctx, E->getAllocatedType());
+}
+
+static llvm::Value *EmitCXXNewAllocSize(ASTContext &Context,
+                                        CodeGenFunction &CGF, 
+                                        const CXXNewExpr *E,
+                                        llvm::Value *& NumElements) {
+  QualType Type = E->getAllocatedType();
+  CharUnits TypeSize = CGF.getContext().getTypeSizeInChars(Type);
+  const llvm::Type *SizeTy = CGF.ConvertType(CGF.getContext().getSizeType());
+  
+  if (!E->isArray())
+    return llvm::ConstantInt::get(SizeTy, TypeSize.getQuantity());
+
+  CharUnits CookiePadding = CalculateCookiePadding(CGF.getContext(), E);
+  
+  Expr::EvalResult Result;
+  if (E->getArraySize()->Evaluate(Result, CGF.getContext()) &&
+      !Result.HasSideEffects && Result.Val.isInt()) {
+
+    CharUnits AllocSize = 
+      Result.Val.getInt().getZExtValue() * TypeSize + CookiePadding;
+    
+    NumElements = 
+      llvm::ConstantInt::get(SizeTy, Result.Val.getInt().getZExtValue());
+    while (const ArrayType *AType = Context.getAsArrayType(Type)) {
+      const llvm::ArrayType *llvmAType =
+        cast<llvm::ArrayType>(CGF.ConvertType(Type));
+      NumElements =
+        CGF.Builder.CreateMul(NumElements, 
+                              llvm::ConstantInt::get(
+                                        SizeTy, llvmAType->getNumElements()));
+      Type = AType->getElementType();
+    }
+    
+    return llvm::ConstantInt::get(SizeTy, AllocSize.getQuantity());
+  }
+  
+  // Emit the array size expression.
+  NumElements = CGF.EmitScalarExpr(E->getArraySize());
+  
+  // Multiply with the type size.
+  llvm::Value *V = 
+    CGF.Builder.CreateMul(NumElements, 
+                          llvm::ConstantInt::get(SizeTy, 
+                                                 TypeSize.getQuantity()));
+  
+  while (const ArrayType *AType = Context.getAsArrayType(Type)) {
+    const llvm::ArrayType *llvmAType =
+      cast<llvm::ArrayType>(CGF.ConvertType(Type));
+    NumElements =
+      CGF.Builder.CreateMul(NumElements, 
+                            llvm::ConstantInt::get(
+                                          SizeTy, llvmAType->getNumElements()));
+    Type = AType->getElementType();
+  }
+
+  // And add the cookie padding if necessary.
+  if (!CookiePadding.isZero())
+    V = CGF.Builder.CreateAdd(V, 
+        llvm::ConstantInt::get(SizeTy, CookiePadding.getQuantity()));
+  
+  return V;
+}
+
+static void EmitNewInitializer(CodeGenFunction &CGF, const CXXNewExpr *E,
+                               llvm::Value *NewPtr,
+                               llvm::Value *NumElements) {
+  if (E->isArray()) {
+    if (CXXConstructorDecl *Ctor = E->getConstructor())
+      CGF.EmitCXXAggrConstructorCall(Ctor, NumElements, NewPtr, 
+                                     E->constructor_arg_begin(), 
+                                     E->constructor_arg_end());
+    return;
+  }
+  
+  QualType AllocType = E->getAllocatedType();
+
+  if (CXXConstructorDecl *Ctor = E->getConstructor()) {
+    CGF.EmitCXXConstructorCall(Ctor, Ctor_Complete, NewPtr,
+                               E->constructor_arg_begin(),
+                               E->constructor_arg_end());
+
+    return;
+  }
+    
+  // We have a POD type.
+  if (E->getNumConstructorArgs() == 0)
+    return;
+
+  assert(E->getNumConstructorArgs() == 1 &&
+         "Can only have one argument to initializer of POD type.");
+      
+  const Expr *Init = E->getConstructorArg(0);
+    
+  if (!CGF.hasAggregateLLVMType(AllocType)) 
+    CGF.EmitStoreOfScalar(CGF.EmitScalarExpr(Init), NewPtr,
+                          AllocType.isVolatileQualified(), AllocType);
+  else if (AllocType->isAnyComplexType())
+    CGF.EmitComplexExprIntoAddr(Init, NewPtr, 
+                                AllocType.isVolatileQualified());
+  else
+    CGF.EmitAggExpr(Init, NewPtr, AllocType.isVolatileQualified());
+}
+
+llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) {
+  QualType AllocType = E->getAllocatedType();
+  FunctionDecl *NewFD = E->getOperatorNew();
+  const FunctionProtoType *NewFTy = NewFD->getType()->getAs<FunctionProtoType>();
+
+  CallArgList NewArgs;
+
+  // The allocation size is the first argument.
+  QualType SizeTy = getContext().getSizeType();
+
+  llvm::Value *NumElements = 0;
+  llvm::Value *AllocSize = EmitCXXNewAllocSize(getContext(),
+                                               *this, E, NumElements);
+  
+  NewArgs.push_back(std::make_pair(RValue::get(AllocSize), SizeTy));
+
+  // Emit the rest of the arguments.
+  // FIXME: Ideally, this should just use EmitCallArgs.
+  CXXNewExpr::const_arg_iterator NewArg = E->placement_arg_begin();
+
+  // First, use the types from the function type.
+  // We start at 1 here because the first argument (the allocation size)
+  // has already been emitted.
+  for (unsigned i = 1, e = NewFTy->getNumArgs(); i != e; ++i, ++NewArg) {
+    QualType ArgType = NewFTy->getArgType(i);
+
+    assert(getContext().getCanonicalType(ArgType.getNonReferenceType()).
+           getTypePtr() ==
+           getContext().getCanonicalType(NewArg->getType()).getTypePtr() &&
+           "type mismatch in call argument!");
+
+    NewArgs.push_back(std::make_pair(EmitCallArg(*NewArg, ArgType),
+                                     ArgType));
+
+  }
+
+  // Either we've emitted all the call args, or we have a call to a
+  // variadic function.
+  assert((NewArg == E->placement_arg_end() || NewFTy->isVariadic()) &&
+         "Extra arguments in non-variadic function!");
+
+  // If we still have any arguments, emit them using the type of the argument.
+  for (CXXNewExpr::const_arg_iterator NewArgEnd = E->placement_arg_end();
+       NewArg != NewArgEnd; ++NewArg) {
+    QualType ArgType = NewArg->getType();
+    NewArgs.push_back(std::make_pair(EmitCallArg(*NewArg, ArgType),
+                                     ArgType));
+  }
+
+  // Emit the call to new.
+  RValue RV =
+    EmitCall(CGM.getTypes().getFunctionInfo(NewArgs, NewFTy),
+             CGM.GetAddrOfFunction(NewFD), ReturnValueSlot(), NewArgs, NewFD);
+
+  // If an allocation function is declared with an empty exception specification
+  // it returns null to indicate failure to allocate storage. [expr.new]p13.
+  // (We don't need to check for null when there's no new initializer and
+  // we're allocating a POD type).
+  bool NullCheckResult = NewFTy->hasEmptyExceptionSpec() &&
+    !(AllocType->isPODType() && !E->hasInitializer());
+
+  llvm::BasicBlock *NewNull = 0;
+  llvm::BasicBlock *NewNotNull = 0;
+  llvm::BasicBlock *NewEnd = 0;
+
+  llvm::Value *NewPtr = RV.getScalarVal();
+
+  if (NullCheckResult) {
+    NewNull = createBasicBlock("new.null");
+    NewNotNull = createBasicBlock("new.notnull");
+    NewEnd = createBasicBlock("new.end");
+
+    llvm::Value *IsNull =
+      Builder.CreateICmpEQ(NewPtr,
+                           llvm::Constant::getNullValue(NewPtr->getType()),
+                           "isnull");
+
+    Builder.CreateCondBr(IsNull, NewNull, NewNotNull);
+    EmitBlock(NewNotNull);
+  }
+  
+  CharUnits CookiePadding = CalculateCookiePadding(getContext(), E);
+  if (!CookiePadding.isZero()) {
+    CharUnits CookieOffset = 
+      CookiePadding - getContext().getTypeSizeInChars(SizeTy);
+    
+    llvm::Value *NumElementsPtr = 
+      Builder.CreateConstInBoundsGEP1_64(NewPtr, CookieOffset.getQuantity());
+    
+    NumElementsPtr = Builder.CreateBitCast(NumElementsPtr, 
+                                           ConvertType(SizeTy)->getPointerTo());
+    Builder.CreateStore(NumElements, NumElementsPtr);
+
+    // Now add the padding to the new ptr.
+    NewPtr = Builder.CreateConstInBoundsGEP1_64(NewPtr, 
+                                                CookiePadding.getQuantity());
+  }
+  
+  if (AllocType->isArrayType()) {
+    while (const ArrayType *AType = getContext().getAsArrayType(AllocType))
+      AllocType = AType->getElementType();
+    NewPtr = 
+      Builder.CreateBitCast(NewPtr, 
+                          ConvertType(getContext().getPointerType(AllocType)));
+    EmitNewInitializer(*this, E, NewPtr, NumElements);
+    NewPtr = Builder.CreateBitCast(NewPtr, ConvertType(E->getType()));
+  }
+  else {
+    NewPtr = Builder.CreateBitCast(NewPtr, ConvertType(E->getType()));
+    EmitNewInitializer(*this, E, NewPtr, NumElements);
+  }
+  
+  if (NullCheckResult) {
+    Builder.CreateBr(NewEnd);
+    NewNotNull = Builder.GetInsertBlock();
+    EmitBlock(NewNull);
+    Builder.CreateBr(NewEnd);
+    EmitBlock(NewEnd);
+
+    llvm::PHINode *PHI = Builder.CreatePHI(NewPtr->getType());
+    PHI->reserveOperandSpace(2);
+    PHI->addIncoming(NewPtr, NewNotNull);
+    PHI->addIncoming(llvm::Constant::getNullValue(NewPtr->getType()), NewNull);
+
+    NewPtr = PHI;
+  }
+
+  return NewPtr;
+}
+
+static std::pair<llvm::Value *, llvm::Value *>
+GetAllocatedObjectPtrAndNumElements(CodeGenFunction &CGF,
+                                    llvm::Value *Ptr, QualType DeleteTy) {
+  QualType SizeTy = CGF.getContext().getSizeType();
+  const llvm::Type *SizeLTy = CGF.ConvertType(SizeTy);
+  
+  CharUnits DeleteTypeAlign = CGF.getContext().getTypeAlignInChars(DeleteTy);
+  CharUnits CookiePadding = 
+    std::max(CGF.getContext().getTypeSizeInChars(SizeTy),
+             DeleteTypeAlign);
+  assert(!CookiePadding.isZero() && "CookiePadding should not be 0.");
+
+  const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGF.getLLVMContext());
+  CharUnits CookieOffset = 
+    CookiePadding - CGF.getContext().getTypeSizeInChars(SizeTy);
+
+  llvm::Value *AllocatedObjectPtr = CGF.Builder.CreateBitCast(Ptr, Int8PtrTy);
+  AllocatedObjectPtr = 
+    CGF.Builder.CreateConstInBoundsGEP1_64(AllocatedObjectPtr,
+                                           -CookiePadding.getQuantity());
+
+  llvm::Value *NumElementsPtr =
+    CGF.Builder.CreateConstInBoundsGEP1_64(AllocatedObjectPtr, 
+                                           CookieOffset.getQuantity());
+  NumElementsPtr = 
+    CGF.Builder.CreateBitCast(NumElementsPtr, SizeLTy->getPointerTo());
+  
+  llvm::Value *NumElements = CGF.Builder.CreateLoad(NumElementsPtr);
+  NumElements = 
+    CGF.Builder.CreateIntCast(NumElements, SizeLTy, /*isSigned=*/false);
+  
+  return std::make_pair(AllocatedObjectPtr, NumElements);
+}
+
+void CodeGenFunction::EmitDeleteCall(const FunctionDecl *DeleteFD,
+                                     llvm::Value *Ptr,
+                                     QualType DeleteTy) {
+  const FunctionProtoType *DeleteFTy =
+    DeleteFD->getType()->getAs<FunctionProtoType>();
+
+  CallArgList DeleteArgs;
+
+  // Check if we need to pass the size to the delete operator.
+  llvm::Value *Size = 0;
+  QualType SizeTy;
+  if (DeleteFTy->getNumArgs() == 2) {
+    SizeTy = DeleteFTy->getArgType(1);
+    CharUnits DeleteTypeSize = getContext().getTypeSizeInChars(DeleteTy);
+    Size = llvm::ConstantInt::get(ConvertType(SizeTy), 
+                                  DeleteTypeSize.getQuantity());
+  }
+  
+  if (DeleteFD->getOverloadedOperator() == OO_Array_Delete &&
+      !CalculateCookiePadding(getContext(), DeleteTy).isZero()) {
+    // We need to get the number of elements in the array from the cookie.
+    llvm::Value *AllocatedObjectPtr;
+    llvm::Value *NumElements;
+    llvm::tie(AllocatedObjectPtr, NumElements) =
+      GetAllocatedObjectPtrAndNumElements(*this, Ptr, DeleteTy);
+    
+    // Multiply the size with the number of elements.
+    if (Size)
+      Size = Builder.CreateMul(NumElements, Size);
+    
+    Ptr = AllocatedObjectPtr;
+  }
+  
+  QualType ArgTy = DeleteFTy->getArgType(0);
+  llvm::Value *DeletePtr = Builder.CreateBitCast(Ptr, ConvertType(ArgTy));
+  DeleteArgs.push_back(std::make_pair(RValue::get(DeletePtr), ArgTy));
+
+  if (Size)
+    DeleteArgs.push_back(std::make_pair(RValue::get(Size), SizeTy));
+
+  // Emit the call to delete.
+  EmitCall(CGM.getTypes().getFunctionInfo(DeleteArgs, DeleteFTy),
+           CGM.GetAddrOfFunction(DeleteFD), ReturnValueSlot(), 
+           DeleteArgs, DeleteFD);
+}
+
+void CodeGenFunction::EmitCXXDeleteExpr(const CXXDeleteExpr *E) {
+  
+  // Get at the argument before we performed the implicit conversion
+  // to void*.
+  const Expr *Arg = E->getArgument();
+  while (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Arg)) {
+    if (ICE->getCastKind() != CastExpr::CK_UserDefinedConversion &&
+        ICE->getType()->isVoidPointerType())
+      Arg = ICE->getSubExpr();
+    else
+      break;
+  }
+  
+  QualType DeleteTy = Arg->getType()->getAs<PointerType>()->getPointeeType();
+
+  llvm::Value *Ptr = EmitScalarExpr(Arg);
+
+  // Null check the pointer.
+  llvm::BasicBlock *DeleteNotNull = createBasicBlock("delete.notnull");
+  llvm::BasicBlock *DeleteEnd = createBasicBlock("delete.end");
+
+  llvm::Value *IsNull =
+    Builder.CreateICmpEQ(Ptr, llvm::Constant::getNullValue(Ptr->getType()),
+                         "isnull");
+
+  Builder.CreateCondBr(IsNull, DeleteEnd, DeleteNotNull);
+  EmitBlock(DeleteNotNull);
+  
+  bool ShouldCallDelete = true;
+  
+  // Call the destructor if necessary.
+  if (const RecordType *RT = DeleteTy->getAs<RecordType>()) {
+    if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
+      if (!RD->hasTrivialDestructor()) {
+        const CXXDestructorDecl *Dtor = RD->getDestructor(getContext());
+        if (E->isArrayForm()) {
+          llvm::Value *AllocatedObjectPtr;
+          llvm::Value *NumElements;
+          llvm::tie(AllocatedObjectPtr, NumElements) =
+            GetAllocatedObjectPtrAndNumElements(*this, Ptr, DeleteTy);
+          
+          EmitCXXAggrDestructorCall(Dtor, NumElements, Ptr);
+        } else if (Dtor->isVirtual()) {
+          const llvm::Type *Ty =
+            CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(Dtor),
+                                           /*isVariadic=*/false);
+          
+          llvm::Value *Callee = BuildVirtualCall(Dtor, Dtor_Deleting, Ptr, Ty);
+          EmitCXXMemberCall(Dtor, Callee, ReturnValueSlot(), Ptr, /*VTT=*/0,
+                            0, 0);
+
+          // The dtor took care of deleting the object.
+          ShouldCallDelete = false;
+        } else 
+          EmitCXXDestructorCall(Dtor, Dtor_Complete, Ptr);
+      }
+    }
+  }
+
+  if (ShouldCallDelete)
+    EmitDeleteCall(E->getOperatorDelete(), Ptr, DeleteTy);
+
+  EmitBlock(DeleteEnd);
+}
+
+llvm::Value * CodeGenFunction::EmitCXXTypeidExpr(const CXXTypeidExpr *E) {
+  QualType Ty = E->getType();
+  const llvm::Type *LTy = ConvertType(Ty)->getPointerTo();
+  
+  if (E->isTypeOperand()) {
+    llvm::Constant *TypeInfo = 
+      CGM.GetAddrOfRTTIDescriptor(E->getTypeOperand());
+    return Builder.CreateBitCast(TypeInfo, LTy);
+  }
+  
+  Expr *subE = E->getExprOperand();
+  Ty = subE->getType();
+  CanQualType CanTy = CGM.getContext().getCanonicalType(Ty);
+  Ty = CanTy.getUnqualifiedType().getNonReferenceType();
+  if (const RecordType *RT = Ty->getAs<RecordType>()) {
+    const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
+    if (RD->isPolymorphic()) {
+      // FIXME: if subE is an lvalue do
+      LValue Obj = EmitLValue(subE);
+      llvm::Value *This = Obj.getAddress();
+      LTy = LTy->getPointerTo()->getPointerTo();
+      llvm::Value *V = Builder.CreateBitCast(This, LTy);
+      // We need to do a zero check for *p, unless it has NonNullAttr.
+      // FIXME: PointerType->hasAttr<NonNullAttr>()
+      bool CanBeZero = false;
+      if (UnaryOperator *UO = dyn_cast<UnaryOperator>(subE->IgnoreParens()))
+        if (UO->getOpcode() == UnaryOperator::Deref)
+          CanBeZero = true;
+      if (CanBeZero) {
+        llvm::BasicBlock *NonZeroBlock = createBasicBlock();
+        llvm::BasicBlock *ZeroBlock = createBasicBlock();
+        
+        llvm::Value *Zero = llvm::Constant::getNullValue(LTy);
+        Builder.CreateCondBr(Builder.CreateICmpNE(V, Zero),
+                             NonZeroBlock, ZeroBlock);
+        EmitBlock(ZeroBlock);
+        /// Call __cxa_bad_typeid
+        const llvm::Type *ResultType = llvm::Type::getVoidTy(VMContext);
+        const llvm::FunctionType *FTy;
+        FTy = llvm::FunctionType::get(ResultType, false);
+        llvm::Value *F = CGM.CreateRuntimeFunction(FTy, "__cxa_bad_typeid");
+        Builder.CreateCall(F)->setDoesNotReturn();
+        Builder.CreateUnreachable();
+        EmitBlock(NonZeroBlock);
+      }
+      V = Builder.CreateLoad(V, "vtable");
+      V = Builder.CreateConstInBoundsGEP1_64(V, -1ULL);
+      V = Builder.CreateLoad(V);
+      return V;
+    }
+  }
+  return Builder.CreateBitCast(CGM.GetAddrOfRTTIDescriptor(Ty), LTy);
+}
+
+llvm::Value *CodeGenFunction::EmitDynamicCast(llvm::Value *V,
+                                              const CXXDynamicCastExpr *DCE) {
+  QualType SrcTy = DCE->getSubExpr()->getType();
+  QualType DestTy = DCE->getTypeAsWritten();
+  QualType InnerType = DestTy->getPointeeType();
+  
+  const llvm::Type *LTy = ConvertType(DCE->getType());
+
+  bool CanBeZero = false;
+  bool ToVoid = false;
+  bool ThrowOnBad = false;
+  if (DestTy->isPointerType()) {
+    // FIXME: if PointerType->hasAttr<NonNullAttr>(), we don't set this
+    CanBeZero = true;
+    if (InnerType->isVoidType())
+      ToVoid = true;
+  } else {
+    LTy = LTy->getPointerTo();
+    ThrowOnBad = true;
+  }
+
+  if (SrcTy->isPointerType() || SrcTy->isReferenceType())
+    SrcTy = SrcTy->getPointeeType();
+  SrcTy = SrcTy.getUnqualifiedType();
+
+  if (DestTy->isPointerType() || DestTy->isReferenceType())
+    DestTy = DestTy->getPointeeType();
+  DestTy = DestTy.getUnqualifiedType();
+
+  llvm::BasicBlock *ContBlock = createBasicBlock();
+  llvm::BasicBlock *NullBlock = 0;
+  llvm::BasicBlock *NonZeroBlock = 0;
+  if (CanBeZero) {
+    NonZeroBlock = createBasicBlock();
+    NullBlock = createBasicBlock();
+    Builder.CreateCondBr(Builder.CreateIsNotNull(V), NonZeroBlock, NullBlock);
+    EmitBlock(NonZeroBlock);
+  }
+
+  llvm::BasicBlock *BadCastBlock = 0;
+
+  const llvm::Type *PtrDiffTy = ConvertType(getContext().getPointerDiffType());
+
+  // See if this is a dynamic_cast(void*)
+  if (ToVoid) {
+    llvm::Value *This = V;
+    V = Builder.CreateBitCast(This, PtrDiffTy->getPointerTo()->getPointerTo());
+    V = Builder.CreateLoad(V, "vtable");
+    V = Builder.CreateConstInBoundsGEP1_64(V, -2ULL);
+    V = Builder.CreateLoad(V, "offset to top");
+    This = Builder.CreateBitCast(This, llvm::Type::getInt8PtrTy(VMContext));
+    V = Builder.CreateInBoundsGEP(This, V);
+    V = Builder.CreateBitCast(V, LTy);
+  } else {
+    /// Call __dynamic_cast
+    const llvm::Type *ResultType = llvm::Type::getInt8PtrTy(VMContext);
+    const llvm::FunctionType *FTy;
+    std::vector<const llvm::Type*> ArgTys;
+    const llvm::Type *PtrToInt8Ty
+      = llvm::Type::getInt8Ty(VMContext)->getPointerTo();
+    ArgTys.push_back(PtrToInt8Ty);
+    ArgTys.push_back(PtrToInt8Ty);
+    ArgTys.push_back(PtrToInt8Ty);
+    ArgTys.push_back(PtrDiffTy);
+    FTy = llvm::FunctionType::get(ResultType, ArgTys, false);
+
+    // FIXME: Calculate better hint.
+    llvm::Value *hint = llvm::ConstantInt::get(PtrDiffTy, -1ULL);
+    
+    assert(SrcTy->isRecordType() && "Src type must be record type!");
+    assert(DestTy->isRecordType() && "Dest type must be record type!");
+    
+    llvm::Value *SrcArg
+      = CGM.GetAddrOfRTTIDescriptor(SrcTy.getUnqualifiedType());
+    llvm::Value *DestArg
+      = CGM.GetAddrOfRTTIDescriptor(DestTy.getUnqualifiedType());
+    
+    V = Builder.CreateBitCast(V, PtrToInt8Ty);
+    V = Builder.CreateCall4(CGM.CreateRuntimeFunction(FTy, "__dynamic_cast"),
+                            V, SrcArg, DestArg, hint);
+    V = Builder.CreateBitCast(V, LTy);
+
+    if (ThrowOnBad) {
+      BadCastBlock = createBasicBlock();
+
+      Builder.CreateCondBr(Builder.CreateIsNotNull(V), ContBlock, BadCastBlock);
+      EmitBlock(BadCastBlock);
+      /// Call __cxa_bad_cast
+      ResultType = llvm::Type::getVoidTy(VMContext);
+      const llvm::FunctionType *FBadTy;
+      FBadTy = llvm::FunctionType::get(ResultType, false);
+      llvm::Value *F = CGM.CreateRuntimeFunction(FBadTy, "__cxa_bad_cast");
+      Builder.CreateCall(F)->setDoesNotReturn();
+      Builder.CreateUnreachable();
+    }
+  }
+  
+  if (CanBeZero) {
+    Builder.CreateBr(ContBlock);
+    EmitBlock(NullBlock);
+    Builder.CreateBr(ContBlock);
+  }
+  EmitBlock(ContBlock);
+  if (CanBeZero) {
+    llvm::PHINode *PHI = Builder.CreatePHI(LTy);
+    PHI->reserveOperandSpace(2);
+    PHI->addIncoming(V, NonZeroBlock);
+    PHI->addIncoming(llvm::Constant::getNullValue(LTy), NullBlock);
+    V = PHI;
+  }
+
+  return V;
+}
diff --git a/lib/CodeGen/CGExprComplex.cpp b/lib/CodeGen/CGExprComplex.cpp
new file mode 100644
index 0000000..0a0c914
--- /dev/null
+++ b/lib/CodeGen/CGExprComplex.cpp
@@ -0,0 +1,742 @@
+//===--- CGExprComplex.cpp - Emit LLVM Code for Complex Exprs -------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This contains code to emit Expr nodes with complex types as LLVM code.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CodeGenFunction.h"
+#include "CodeGenModule.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/StmtVisitor.h"
+#include "llvm/Constants.h"
+#include "llvm/Function.h"
+#include "llvm/ADT/SmallString.h"
+using namespace clang;
+using namespace CodeGen;
+
+//===----------------------------------------------------------------------===//
+//                        Complex Expression Emitter
+//===----------------------------------------------------------------------===//
+
+typedef CodeGenFunction::ComplexPairTy ComplexPairTy;
+
+namespace  {
+class ComplexExprEmitter
+  : public StmtVisitor<ComplexExprEmitter, ComplexPairTy> {
+  CodeGenFunction &CGF;
+  CGBuilderTy &Builder;
+  // True is we should ignore the value of a
+  bool IgnoreReal;
+  bool IgnoreImag;
+  // True if we should ignore the value of a=b
+  bool IgnoreRealAssign;
+  bool IgnoreImagAssign;
+public:
+  ComplexExprEmitter(CodeGenFunction &cgf, bool ir=false, bool ii=false,
+                     bool irn=false, bool iin=false)
+    : CGF(cgf), Builder(CGF.Builder), IgnoreReal(ir), IgnoreImag(ii),
+    IgnoreRealAssign(irn), IgnoreImagAssign(iin) {
+  }
+
+
+  //===--------------------------------------------------------------------===//
+  //                               Utilities
+  //===--------------------------------------------------------------------===//
+
+  bool TestAndClearIgnoreReal() {
+    bool I = IgnoreReal;
+    IgnoreReal = false;
+    return I;
+  }
+  bool TestAndClearIgnoreImag() {
+    bool I = IgnoreImag;
+    IgnoreImag = false;
+    return I;
+  }
+  bool TestAndClearIgnoreRealAssign() {
+    bool I = IgnoreRealAssign;
+    IgnoreRealAssign = false;
+    return I;
+  }
+  bool TestAndClearIgnoreImagAssign() {
+    bool I = IgnoreImagAssign;
+    IgnoreImagAssign = false;
+    return I;
+  }
+
+  /// EmitLoadOfLValue - Given an expression with complex type that represents a
+  /// value l-value, this method emits the address of the l-value, then loads
+  /// and returns the result.
+  ComplexPairTy EmitLoadOfLValue(const Expr *E) {
+    LValue LV = CGF.EmitLValue(E);
+    if (LV.isSimple())
+      return EmitLoadOfComplex(LV.getAddress(), LV.isVolatileQualified());
+
+    if (LV.isPropertyRef())
+      return CGF.EmitObjCPropertyGet(LV.getPropertyRefExpr()).getComplexVal();
+
+    assert(LV.isKVCRef() && "Unknown LValue type!");
+    return CGF.EmitObjCPropertyGet(LV.getKVCRefExpr()).getComplexVal();
+  }
+
+  /// EmitLoadOfComplex - Given a pointer to a complex value, emit code to load
+  /// the real and imaginary pieces.
+  ComplexPairTy EmitLoadOfComplex(llvm::Value *SrcPtr, bool isVolatile);
+
+  /// EmitStoreOfComplex - Store the specified real/imag parts into the
+  /// specified value pointer.
+  void EmitStoreOfComplex(ComplexPairTy Val, llvm::Value *ResPtr, bool isVol);
+
+  /// EmitComplexToComplexCast - Emit a cast from complex value Val to DestType.
+  ComplexPairTy EmitComplexToComplexCast(ComplexPairTy Val, QualType SrcType,
+                                         QualType DestType);
+
+  //===--------------------------------------------------------------------===//
+  //                            Visitor Methods
+  //===--------------------------------------------------------------------===//
+
+  ComplexPairTy VisitStmt(Stmt *S) {
+    S->dump(CGF.getContext().getSourceManager());
+    assert(0 && "Stmt can't have complex result type!");
+    return ComplexPairTy();
+  }
+  ComplexPairTy VisitExpr(Expr *S);
+  ComplexPairTy VisitParenExpr(ParenExpr *PE) { return Visit(PE->getSubExpr());}
+  ComplexPairTy VisitImaginaryLiteral(const ImaginaryLiteral *IL);
+
+  // l-values.
+  ComplexPairTy VisitDeclRefExpr(const Expr *E) { return EmitLoadOfLValue(E); }
+  ComplexPairTy VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
+    return EmitLoadOfLValue(E);
+  }
+  ComplexPairTy VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
+    return EmitLoadOfLValue(E);
+  }
+  ComplexPairTy VisitObjCImplicitSetterGetterRefExpr(
+                               ObjCImplicitSetterGetterRefExpr *E) {
+    return EmitLoadOfLValue(E);
+  }
+  ComplexPairTy VisitObjCMessageExpr(ObjCMessageExpr *E) {
+    return CGF.EmitObjCMessageExpr(E).getComplexVal();
+  }
+  ComplexPairTy VisitArraySubscriptExpr(Expr *E) { return EmitLoadOfLValue(E); }
+  ComplexPairTy VisitMemberExpr(const Expr *E) { return EmitLoadOfLValue(E); }
+
+  // FIXME: CompoundLiteralExpr
+
+  ComplexPairTy EmitCast(Expr *Op, QualType DestTy);
+  ComplexPairTy VisitImplicitCastExpr(ImplicitCastExpr *E) {
+    // Unlike for scalars, we don't have to worry about function->ptr demotion
+    // here.
+    return EmitCast(E->getSubExpr(), E->getType());
+  }
+  ComplexPairTy VisitCastExpr(CastExpr *E) {
+    return EmitCast(E->getSubExpr(), E->getType());
+  }
+  ComplexPairTy VisitCallExpr(const CallExpr *E);
+  ComplexPairTy VisitStmtExpr(const StmtExpr *E);
+
+  // Operators.
+  ComplexPairTy VisitPrePostIncDec(const UnaryOperator *E,
+                                   bool isInc, bool isPre) {
+    LValue LV = CGF.EmitLValue(E->getSubExpr());
+    return CGF.EmitComplexPrePostIncDec(E, LV, isInc, isPre);
+  }
+  ComplexPairTy VisitUnaryPostDec(const UnaryOperator *E) {
+    return VisitPrePostIncDec(E, false, false);
+  }
+  ComplexPairTy VisitUnaryPostInc(const UnaryOperator *E) {
+    return VisitPrePostIncDec(E, true, false);
+  }
+  ComplexPairTy VisitUnaryPreDec(const UnaryOperator *E) {
+    return VisitPrePostIncDec(E, false, true);
+  }
+  ComplexPairTy VisitUnaryPreInc(const UnaryOperator *E) {
+    return VisitPrePostIncDec(E, true, true);
+  }
+  ComplexPairTy VisitUnaryDeref(const Expr *E) { return EmitLoadOfLValue(E); }
+  ComplexPairTy VisitUnaryPlus     (const UnaryOperator *E) {
+    TestAndClearIgnoreReal();
+    TestAndClearIgnoreImag();
+    TestAndClearIgnoreRealAssign();
+    TestAndClearIgnoreImagAssign();
+    return Visit(E->getSubExpr());
+  }
+  ComplexPairTy VisitUnaryMinus    (const UnaryOperator *E);
+  ComplexPairTy VisitUnaryNot      (const UnaryOperator *E);
+  // LNot,Real,Imag never return complex.
+  ComplexPairTy VisitUnaryExtension(const UnaryOperator *E) {
+    return Visit(E->getSubExpr());
+  }
+  ComplexPairTy VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) {
+    return Visit(DAE->getExpr());
+  }
+  ComplexPairTy VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E) {
+    return CGF.EmitCXXExprWithTemporaries(E).getComplexVal();
+  }
+  ComplexPairTy VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) {
+    assert(E->getType()->isAnyComplexType() && "Expected complex type!");
+    QualType Elem = E->getType()->getAs<ComplexType>()->getElementType();
+    llvm::Constant *Null = llvm::Constant::getNullValue(CGF.ConvertType(Elem));
+    return ComplexPairTy(Null, Null);
+  }
+  ComplexPairTy VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) {
+    assert(E->getType()->isAnyComplexType() && "Expected complex type!");
+    QualType Elem = E->getType()->getAs<ComplexType>()->getElementType();
+    llvm::Constant *Null =
+                       llvm::Constant::getNullValue(CGF.ConvertType(Elem));
+    return ComplexPairTy(Null, Null);
+  }
+
+  struct BinOpInfo {
+    ComplexPairTy LHS;
+    ComplexPairTy RHS;
+    QualType Ty;  // Computation Type.
+  };
+
+  BinOpInfo EmitBinOps(const BinaryOperator *E);
+  ComplexPairTy EmitCompoundAssign(const CompoundAssignOperator *E,
+                                   ComplexPairTy (ComplexExprEmitter::*Func)
+                                   (const BinOpInfo &));
+
+  ComplexPairTy EmitBinAdd(const BinOpInfo &Op);
+  ComplexPairTy EmitBinSub(const BinOpInfo &Op);
+  ComplexPairTy EmitBinMul(const BinOpInfo &Op);
+  ComplexPairTy EmitBinDiv(const BinOpInfo &Op);
+
+  ComplexPairTy VisitBinMul(const BinaryOperator *E) {
+    return EmitBinMul(EmitBinOps(E));
+  }
+  ComplexPairTy VisitBinAdd(const BinaryOperator *E) {
+    return EmitBinAdd(EmitBinOps(E));
+  }
+  ComplexPairTy VisitBinSub(const BinaryOperator *E) {
+    return EmitBinSub(EmitBinOps(E));
+  }
+  ComplexPairTy VisitBinDiv(const BinaryOperator *E) {
+    return EmitBinDiv(EmitBinOps(E));
+  }
+
+  // Compound assignments.
+  ComplexPairTy VisitBinAddAssign(const CompoundAssignOperator *E) {
+    return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinAdd);
+  }
+  ComplexPairTy VisitBinSubAssign(const CompoundAssignOperator *E) {
+    return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinSub);
+  }
+  ComplexPairTy VisitBinMulAssign(const CompoundAssignOperator *E) {
+    return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinMul);
+  }
+  ComplexPairTy VisitBinDivAssign(const CompoundAssignOperator *E) {
+    return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinDiv);
+  }
+
+  // GCC rejects rem/and/or/xor for integer complex.
+  // Logical and/or always return int, never complex.
+
+  // No comparisons produce a complex result.
+  ComplexPairTy VisitBinAssign     (const BinaryOperator *E);
+  ComplexPairTy VisitBinComma      (const BinaryOperator *E);
+
+
+  ComplexPairTy VisitConditionalOperator(const ConditionalOperator *CO);
+  ComplexPairTy VisitChooseExpr(ChooseExpr *CE);
+
+  ComplexPairTy VisitInitListExpr(InitListExpr *E);
+
+  ComplexPairTy VisitVAArgExpr(VAArgExpr *E);
+};
+}  // end anonymous namespace.
+
+//===----------------------------------------------------------------------===//
+//                                Utilities
+//===----------------------------------------------------------------------===//
+
+/// EmitLoadOfComplex - Given an RValue reference for a complex, emit code to
+/// load the real and imaginary pieces, returning them as Real/Imag.
+ComplexPairTy ComplexExprEmitter::EmitLoadOfComplex(llvm::Value *SrcPtr,
+                                                    bool isVolatile) {
+  llvm::Value *Real=0, *Imag=0;
+
+  if (!IgnoreReal) {
+    llvm::Value *RealP = Builder.CreateStructGEP(SrcPtr, 0,
+                                                 SrcPtr->getName() + ".realp");
+    Real = Builder.CreateLoad(RealP, isVolatile, SrcPtr->getName() + ".real");
+  }
+
+  if (!IgnoreImag) {
+    llvm::Value *ImagP = Builder.CreateStructGEP(SrcPtr, 1,
+                                                 SrcPtr->getName() + ".imagp");
+    Imag = Builder.CreateLoad(ImagP, isVolatile, SrcPtr->getName() + ".imag");
+  }
+  return ComplexPairTy(Real, Imag);
+}
+
+/// EmitStoreOfComplex - Store the specified real/imag parts into the
+/// specified value pointer.
+void ComplexExprEmitter::EmitStoreOfComplex(ComplexPairTy Val, llvm::Value *Ptr,
+                                            bool isVolatile) {
+  llvm::Value *RealPtr = Builder.CreateStructGEP(Ptr, 0, "real");
+  llvm::Value *ImagPtr = Builder.CreateStructGEP(Ptr, 1, "imag");
+
+  Builder.CreateStore(Val.first, RealPtr, isVolatile);
+  Builder.CreateStore(Val.second, ImagPtr, isVolatile);
+}
+
+
+
+//===----------------------------------------------------------------------===//
+//                            Visitor Methods
+//===----------------------------------------------------------------------===//
+
+ComplexPairTy ComplexExprEmitter::VisitExpr(Expr *E) {
+  CGF.ErrorUnsupported(E, "complex expression");
+  const llvm::Type *EltTy =
+    CGF.ConvertType(E->getType()->getAs<ComplexType>()->getElementType());
+  llvm::Value *U = llvm::UndefValue::get(EltTy);
+  return ComplexPairTy(U, U);
+}
+
+ComplexPairTy ComplexExprEmitter::
+VisitImaginaryLiteral(const ImaginaryLiteral *IL) {
+  llvm::Value *Imag = CGF.EmitScalarExpr(IL->getSubExpr());
+  return
+        ComplexPairTy(llvm::Constant::getNullValue(Imag->getType()), Imag);
+}
+
+
+ComplexPairTy ComplexExprEmitter::VisitCallExpr(const CallExpr *E) {
+  if (E->getCallReturnType()->isReferenceType())
+    return EmitLoadOfLValue(E);
+
+  return CGF.EmitCallExpr(E).getComplexVal();
+}
+
+ComplexPairTy ComplexExprEmitter::VisitStmtExpr(const StmtExpr *E) {
+  return CGF.EmitCompoundStmt(*E->getSubStmt(), true).getComplexVal();
+}
+
+/// EmitComplexToComplexCast - Emit a cast from complex value Val to DestType.
+ComplexPairTy ComplexExprEmitter::EmitComplexToComplexCast(ComplexPairTy Val,
+                                                           QualType SrcType,
+                                                           QualType DestType) {
+  // Get the src/dest element type.
+  SrcType = SrcType->getAs<ComplexType>()->getElementType();
+  DestType = DestType->getAs<ComplexType>()->getElementType();
+
+  // C99 6.3.1.6: When a value of complex type is converted to another
+  // complex type, both the real and imaginary parts follow the conversion
+  // rules for the corresponding real types.
+  Val.first = CGF.EmitScalarConversion(Val.first, SrcType, DestType);
+  Val.second = CGF.EmitScalarConversion(Val.second, SrcType, DestType);
+  return Val;
+}
+
+ComplexPairTy ComplexExprEmitter::EmitCast(Expr *Op, QualType DestTy) {
+  // Two cases here: cast from (complex to complex) and (scalar to complex).
+  if (Op->getType()->isAnyComplexType())
+    return EmitComplexToComplexCast(Visit(Op), Op->getType(), DestTy);
+
+  // C99 6.3.1.7: When a value of real type is converted to a complex type, the
+  // real part of the complex result value is determined by the rules of
+  // conversion to the corresponding real type and the imaginary part of the
+  // complex result value is a positive zero or an unsigned zero.
+  llvm::Value *Elt = CGF.EmitScalarExpr(Op);
+
+  // Convert the input element to the element type of the complex.
+  DestTy = DestTy->getAs<ComplexType>()->getElementType();
+  Elt = CGF.EmitScalarConversion(Elt, Op->getType(), DestTy);
+
+  // Return (realval, 0).
+  return ComplexPairTy(Elt, llvm::Constant::getNullValue(Elt->getType()));
+}
+
+ComplexPairTy ComplexExprEmitter::VisitUnaryMinus(const UnaryOperator *E) {
+  TestAndClearIgnoreReal();
+  TestAndClearIgnoreImag();
+  TestAndClearIgnoreRealAssign();
+  TestAndClearIgnoreImagAssign();
+  ComplexPairTy Op = Visit(E->getSubExpr());
+
+  llvm::Value *ResR, *ResI;
+  if (Op.first->getType()->isFloatingPointTy()) {
+    ResR = Builder.CreateFNeg(Op.first,  "neg.r");
+    ResI = Builder.CreateFNeg(Op.second, "neg.i");
+  } else {
+    ResR = Builder.CreateNeg(Op.first,  "neg.r");
+    ResI = Builder.CreateNeg(Op.second, "neg.i");
+  }
+  return ComplexPairTy(ResR, ResI);
+}
+
+ComplexPairTy ComplexExprEmitter::VisitUnaryNot(const UnaryOperator *E) {
+  TestAndClearIgnoreReal();
+  TestAndClearIgnoreImag();
+  TestAndClearIgnoreRealAssign();
+  TestAndClearIgnoreImagAssign();
+  // ~(a+ib) = a + i*-b
+  ComplexPairTy Op = Visit(E->getSubExpr());
+  llvm::Value *ResI;
+  if (Op.second->getType()->isFloatingPointTy())
+    ResI = Builder.CreateFNeg(Op.second, "conj.i");
+  else
+    ResI = Builder.CreateNeg(Op.second, "conj.i");
+
+  return ComplexPairTy(Op.first, ResI);
+}
+
+ComplexPairTy ComplexExprEmitter::EmitBinAdd(const BinOpInfo &Op) {
+  llvm::Value *ResR, *ResI;
+
+  if (Op.LHS.first->getType()->isFloatingPointTy()) {
+    ResR = Builder.CreateFAdd(Op.LHS.first,  Op.RHS.first,  "add.r");
+    ResI = Builder.CreateFAdd(Op.LHS.second, Op.RHS.second, "add.i");
+  } else {
+    ResR = Builder.CreateAdd(Op.LHS.first,  Op.RHS.first,  "add.r");
+    ResI = Builder.CreateAdd(Op.LHS.second, Op.RHS.second, "add.i");
+  }
+  return ComplexPairTy(ResR, ResI);
+}
+
+ComplexPairTy ComplexExprEmitter::EmitBinSub(const BinOpInfo &Op) {
+  llvm::Value *ResR, *ResI;
+  if (Op.LHS.first->getType()->isFloatingPointTy()) {
+    ResR = Builder.CreateFSub(Op.LHS.first,  Op.RHS.first,  "sub.r");
+    ResI = Builder.CreateFSub(Op.LHS.second, Op.RHS.second, "sub.i");
+  } else {
+    ResR = Builder.CreateSub(Op.LHS.first,  Op.RHS.first,  "sub.r");
+    ResI = Builder.CreateSub(Op.LHS.second, Op.RHS.second, "sub.i");
+  }
+  return ComplexPairTy(ResR, ResI);
+}
+
+
+ComplexPairTy ComplexExprEmitter::EmitBinMul(const BinOpInfo &Op) {
+  using llvm::Value;
+  Value *ResR, *ResI;
+
+  if (Op.LHS.first->getType()->isFloatingPointTy()) {
+    Value *ResRl = Builder.CreateFMul(Op.LHS.first, Op.RHS.first, "mul.rl");
+    Value *ResRr = Builder.CreateFMul(Op.LHS.second, Op.RHS.second,"mul.rr");
+    ResR  = Builder.CreateFSub(ResRl, ResRr, "mul.r");
+
+    Value *ResIl = Builder.CreateFMul(Op.LHS.second, Op.RHS.first, "mul.il");
+    Value *ResIr = Builder.CreateFMul(Op.LHS.first, Op.RHS.second, "mul.ir");
+    ResI  = Builder.CreateFAdd(ResIl, ResIr, "mul.i");
+  } else {
+    Value *ResRl = Builder.CreateMul(Op.LHS.first, Op.RHS.first, "mul.rl");
+    Value *ResRr = Builder.CreateMul(Op.LHS.second, Op.RHS.second,"mul.rr");
+    ResR  = Builder.CreateSub(ResRl, ResRr, "mul.r");
+
+    Value *ResIl = Builder.CreateMul(Op.LHS.second, Op.RHS.first, "mul.il");
+    Value *ResIr = Builder.CreateMul(Op.LHS.first, Op.RHS.second, "mul.ir");
+    ResI  = Builder.CreateAdd(ResIl, ResIr, "mul.i");
+  }
+  return ComplexPairTy(ResR, ResI);
+}
+
+ComplexPairTy ComplexExprEmitter::EmitBinDiv(const BinOpInfo &Op) {
+  llvm::Value *LHSr = Op.LHS.first, *LHSi = Op.LHS.second;
+  llvm::Value *RHSr = Op.RHS.first, *RHSi = Op.RHS.second;
+
+
+  llvm::Value *DSTr, *DSTi;
+  if (Op.LHS.first->getType()->isFloatingPointTy()) {
+    // (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd))
+    llvm::Value *Tmp1 = Builder.CreateFMul(LHSr, RHSr, "tmp"); // a*c
+    llvm::Value *Tmp2 = Builder.CreateFMul(LHSi, RHSi, "tmp"); // b*d
+    llvm::Value *Tmp3 = Builder.CreateFAdd(Tmp1, Tmp2, "tmp"); // ac+bd
+
+    llvm::Value *Tmp4 = Builder.CreateFMul(RHSr, RHSr, "tmp"); // c*c
+    llvm::Value *Tmp5 = Builder.CreateFMul(RHSi, RHSi, "tmp"); // d*d
+    llvm::Value *Tmp6 = Builder.CreateFAdd(Tmp4, Tmp5, "tmp"); // cc+dd
+
+    llvm::Value *Tmp7 = Builder.CreateFMul(LHSi, RHSr, "tmp"); // b*c
+    llvm::Value *Tmp8 = Builder.CreateFMul(LHSr, RHSi, "tmp"); // a*d
+    llvm::Value *Tmp9 = Builder.CreateFSub(Tmp7, Tmp8, "tmp"); // bc-ad
+
+    DSTr = Builder.CreateFDiv(Tmp3, Tmp6, "tmp");
+    DSTi = Builder.CreateFDiv(Tmp9, Tmp6, "tmp");
+  } else {
+    // (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd))
+    llvm::Value *Tmp1 = Builder.CreateMul(LHSr, RHSr, "tmp"); // a*c
+    llvm::Value *Tmp2 = Builder.CreateMul(LHSi, RHSi, "tmp"); // b*d
+    llvm::Value *Tmp3 = Builder.CreateAdd(Tmp1, Tmp2, "tmp"); // ac+bd
+
+    llvm::Value *Tmp4 = Builder.CreateMul(RHSr, RHSr, "tmp"); // c*c
+    llvm::Value *Tmp5 = Builder.CreateMul(RHSi, RHSi, "tmp"); // d*d
+    llvm::Value *Tmp6 = Builder.CreateAdd(Tmp4, Tmp5, "tmp"); // cc+dd
+
+    llvm::Value *Tmp7 = Builder.CreateMul(LHSi, RHSr, "tmp"); // b*c
+    llvm::Value *Tmp8 = Builder.CreateMul(LHSr, RHSi, "tmp"); // a*d
+    llvm::Value *Tmp9 = Builder.CreateSub(Tmp7, Tmp8, "tmp"); // bc-ad
+
+    if (Op.Ty->getAs<ComplexType>()->getElementType()->isUnsignedIntegerType()) {
+      DSTr = Builder.CreateUDiv(Tmp3, Tmp6, "tmp");
+      DSTi = Builder.CreateUDiv(Tmp9, Tmp6, "tmp");
+    } else {
+      DSTr = Builder.CreateSDiv(Tmp3, Tmp6, "tmp");
+      DSTi = Builder.CreateSDiv(Tmp9, Tmp6, "tmp");
+    }
+  }
+
+  return ComplexPairTy(DSTr, DSTi);
+}
+
+ComplexExprEmitter::BinOpInfo
+ComplexExprEmitter::EmitBinOps(const BinaryOperator *E) {
+  TestAndClearIgnoreReal();
+  TestAndClearIgnoreImag();
+  TestAndClearIgnoreRealAssign();
+  TestAndClearIgnoreImagAssign();
+  BinOpInfo Ops;
+  Ops.LHS = Visit(E->getLHS());
+  Ops.RHS = Visit(E->getRHS());
+  Ops.Ty = E->getType();
+  return Ops;
+}
+
+
+// Compound assignments.
+ComplexPairTy ComplexExprEmitter::
+EmitCompoundAssign(const CompoundAssignOperator *E,
+                   ComplexPairTy (ComplexExprEmitter::*Func)(const BinOpInfo&)){
+  TestAndClearIgnoreReal();
+  TestAndClearIgnoreImag();
+  bool ignreal = TestAndClearIgnoreRealAssign();
+  bool ignimag = TestAndClearIgnoreImagAssign();
+  QualType LHSTy = E->getLHS()->getType(), RHSTy = E->getRHS()->getType();
+
+  BinOpInfo OpInfo;
+
+  // Load the RHS and LHS operands.
+  // __block variables need to have the rhs evaluated first, plus this should
+  // improve codegen a little.  It is possible for the RHS to be complex or
+  // scalar.
+  OpInfo.Ty = E->getComputationResultType();
+  OpInfo.RHS = EmitCast(E->getRHS(), OpInfo.Ty);
+  
+  LValue LHSLV = CGF.EmitLValue(E->getLHS());
+  // We know the LHS is a complex lvalue.
+  ComplexPairTy LHSComplexPair;
+  if (LHSLV.isPropertyRef())
+    LHSComplexPair = 
+      CGF.EmitObjCPropertyGet(LHSLV.getPropertyRefExpr()).getComplexVal();
+  else if (LHSLV.isKVCRef())
+    LHSComplexPair = 
+      CGF.EmitObjCPropertyGet(LHSLV.getKVCRefExpr()).getComplexVal();
+  else
+    LHSComplexPair = EmitLoadOfComplex(LHSLV.getAddress(), 
+                                       LHSLV.isVolatileQualified());
+  
+  OpInfo.LHS=EmitComplexToComplexCast(LHSComplexPair, LHSTy, OpInfo.Ty);
+
+  // Expand the binary operator.
+  ComplexPairTy Result = (this->*Func)(OpInfo);
+
+  // Truncate the result back to the LHS type.
+  Result = EmitComplexToComplexCast(Result, OpInfo.Ty, LHSTy);
+
+  // Store the result value into the LHS lvalue.
+  if (LHSLV.isPropertyRef())
+    CGF.EmitObjCPropertySet(LHSLV.getPropertyRefExpr(), 
+                            RValue::getComplex(Result));
+  else if (LHSLV.isKVCRef())
+    CGF.EmitObjCPropertySet(LHSLV.getKVCRefExpr(), RValue::getComplex(Result));
+  else
+    EmitStoreOfComplex(Result, LHSLV.getAddress(), LHSLV.isVolatileQualified());
+  // And now return the LHS
+  IgnoreReal = ignreal;
+  IgnoreImag = ignimag;
+  IgnoreRealAssign = ignreal;
+  IgnoreImagAssign = ignimag;
+  if (LHSLV.isPropertyRef())
+    return CGF.EmitObjCPropertyGet(LHSLV.getPropertyRefExpr()).getComplexVal();
+  else if (LHSLV.isKVCRef())
+    return CGF.EmitObjCPropertyGet(LHSLV.getKVCRefExpr()).getComplexVal();
+  return EmitLoadOfComplex(LHSLV.getAddress(), LHSLV.isVolatileQualified());
+}
+
+ComplexPairTy ComplexExprEmitter::VisitBinAssign(const BinaryOperator *E) {
+  TestAndClearIgnoreReal();
+  TestAndClearIgnoreImag();
+  bool ignreal = TestAndClearIgnoreRealAssign();
+  bool ignimag = TestAndClearIgnoreImagAssign();
+  assert(CGF.getContext().getCanonicalType(E->getLHS()->getType()) ==
+         CGF.getContext().getCanonicalType(E->getRHS()->getType()) &&
+         "Invalid assignment");
+  // Emit the RHS.
+  ComplexPairTy Val = Visit(E->getRHS());
+
+  // Compute the address to store into.
+  LValue LHS = CGF.EmitLValue(E->getLHS());
+
+  // Store into it, if simple.
+  if (LHS.isSimple()) {
+    EmitStoreOfComplex(Val, LHS.getAddress(), LHS.isVolatileQualified());
+
+    // And now return the LHS
+    IgnoreReal = ignreal;
+    IgnoreImag = ignimag;
+    IgnoreRealAssign = ignreal;
+    IgnoreImagAssign = ignimag;
+    return EmitLoadOfComplex(LHS.getAddress(), LHS.isVolatileQualified());
+  }
+
+  // Otherwise we must have a property setter (no complex vector/bitfields).
+  if (LHS.isPropertyRef())
+    CGF.EmitObjCPropertySet(LHS.getPropertyRefExpr(), RValue::getComplex(Val));
+  else
+    CGF.EmitObjCPropertySet(LHS.getKVCRefExpr(), RValue::getComplex(Val));
+
+  // There is no reload after a store through a method, but we need to restore
+  // the Ignore* flags.
+  IgnoreReal = ignreal;
+  IgnoreImag = ignimag;
+  IgnoreRealAssign = ignreal;
+  IgnoreImagAssign = ignimag;
+  return Val;
+}
+
+ComplexPairTy ComplexExprEmitter::VisitBinComma(const BinaryOperator *E) {
+  CGF.EmitStmt(E->getLHS());
+  CGF.EnsureInsertPoint();
+  return Visit(E->getRHS());
+}
+
+ComplexPairTy ComplexExprEmitter::
+VisitConditionalOperator(const ConditionalOperator *E) {
+  if (!E->getLHS()) {
+    CGF.ErrorUnsupported(E, "conditional operator with missing LHS");
+    const llvm::Type *EltTy =
+      CGF.ConvertType(E->getType()->getAs<ComplexType>()->getElementType());
+    llvm::Value *U = llvm::UndefValue::get(EltTy);
+    return ComplexPairTy(U, U);
+  }
+
+  TestAndClearIgnoreReal();
+  TestAndClearIgnoreImag();
+  TestAndClearIgnoreRealAssign();
+  TestAndClearIgnoreImagAssign();
+  llvm::BasicBlock *LHSBlock = CGF.createBasicBlock("cond.true");
+  llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("cond.false");
+  llvm::BasicBlock *ContBlock = CGF.createBasicBlock("cond.end");
+
+  CGF.EmitBranchOnBoolExpr(E->getCond(), LHSBlock, RHSBlock);
+
+  CGF.EmitBlock(LHSBlock);
+
+  // Handle the GNU extension for missing LHS.
+  assert(E->getLHS() && "Must have LHS for complex value");
+
+  ComplexPairTy LHS = Visit(E->getLHS());
+  LHSBlock = Builder.GetInsertBlock();
+  CGF.EmitBranch(ContBlock);
+
+  CGF.EmitBlock(RHSBlock);
+
+  ComplexPairTy RHS = Visit(E->getRHS());
+  RHSBlock = Builder.GetInsertBlock();
+  CGF.EmitBranch(ContBlock);
+
+  CGF.EmitBlock(ContBlock);
+
+  // Create a PHI node for the real part.
+  llvm::PHINode *RealPN = Builder.CreatePHI(LHS.first->getType(), "cond.r");
+  RealPN->reserveOperandSpace(2);
+  RealPN->addIncoming(LHS.first, LHSBlock);
+  RealPN->addIncoming(RHS.first, RHSBlock);
+
+  // Create a PHI node for the imaginary part.
+  llvm::PHINode *ImagPN = Builder.CreatePHI(LHS.first->getType(), "cond.i");
+  ImagPN->reserveOperandSpace(2);
+  ImagPN->addIncoming(LHS.second, LHSBlock);
+  ImagPN->addIncoming(RHS.second, RHSBlock);
+
+  return ComplexPairTy(RealPN, ImagPN);
+}
+
+ComplexPairTy ComplexExprEmitter::VisitChooseExpr(ChooseExpr *E) {
+  return Visit(E->getChosenSubExpr(CGF.getContext()));
+}
+
+ComplexPairTy ComplexExprEmitter::VisitInitListExpr(InitListExpr *E) {
+    bool Ignore = TestAndClearIgnoreReal();
+    (void)Ignore;
+    assert (Ignore == false && "init list ignored");
+    Ignore = TestAndClearIgnoreImag();
+    (void)Ignore;
+    assert (Ignore == false && "init list ignored");
+  if (E->getNumInits())
+    return Visit(E->getInit(0));
+
+  // Empty init list intializes to null
+  QualType Ty = E->getType()->getAs<ComplexType>()->getElementType();
+  const llvm::Type* LTy = CGF.ConvertType(Ty);
+  llvm::Value* zeroConstant = llvm::Constant::getNullValue(LTy);
+  return ComplexPairTy(zeroConstant, zeroConstant);
+}
+
+ComplexPairTy ComplexExprEmitter::VisitVAArgExpr(VAArgExpr *E) {
+  llvm::Value *ArgValue = CGF.EmitVAListRef(E->getSubExpr());
+  llvm::Value *ArgPtr = CGF.EmitVAArg(ArgValue, E->getType());
+
+  if (!ArgPtr) {
+    CGF.ErrorUnsupported(E, "complex va_arg expression");
+    const llvm::Type *EltTy =
+      CGF.ConvertType(E->getType()->getAs<ComplexType>()->getElementType());
+    llvm::Value *U = llvm::UndefValue::get(EltTy);
+    return ComplexPairTy(U, U);
+  }
+
+  // FIXME Volatility.
+  return EmitLoadOfComplex(ArgPtr, false);
+}
+
+//===----------------------------------------------------------------------===//
+//                         Entry Point into this File
+//===----------------------------------------------------------------------===//
+
+/// EmitComplexExpr - Emit the computation of the specified expression of
+/// complex type, ignoring the result.
+ComplexPairTy CodeGenFunction::EmitComplexExpr(const Expr *E, bool IgnoreReal,
+                                               bool IgnoreImag, bool IgnoreRealAssign, bool IgnoreImagAssign) {
+  assert(E && E->getType()->isAnyComplexType() &&
+         "Invalid complex expression to emit");
+
+  return ComplexExprEmitter(*this, IgnoreReal, IgnoreImag, IgnoreRealAssign,
+                            IgnoreImagAssign)
+    .Visit(const_cast<Expr*>(E));
+}
+
+/// EmitComplexExprIntoAddr - Emit the computation of the specified expression
+/// of complex type, storing into the specified Value*.
+void CodeGenFunction::EmitComplexExprIntoAddr(const Expr *E,
+                                              llvm::Value *DestAddr,
+                                              bool DestIsVolatile) {
+  assert(E && E->getType()->isAnyComplexType() &&
+         "Invalid complex expression to emit");
+  ComplexExprEmitter Emitter(*this);
+  ComplexPairTy Val = Emitter.Visit(const_cast<Expr*>(E));
+  Emitter.EmitStoreOfComplex(Val, DestAddr, DestIsVolatile);
+}
+
+/// StoreComplexToAddr - Store a complex number into the specified address.
+void CodeGenFunction::StoreComplexToAddr(ComplexPairTy V,
+                                         llvm::Value *DestAddr,
+                                         bool DestIsVolatile) {
+  ComplexExprEmitter(*this).EmitStoreOfComplex(V, DestAddr, DestIsVolatile);
+}
+
+/// LoadComplexFromAddr - Load a complex number from the specified address.
+ComplexPairTy CodeGenFunction::LoadComplexFromAddr(llvm::Value *SrcAddr,
+                                                   bool SrcIsVolatile) {
+  return ComplexExprEmitter(*this).EmitLoadOfComplex(SrcAddr, SrcIsVolatile);
+}
diff --git a/lib/CodeGen/CGExprConstant.cpp b/lib/CodeGen/CGExprConstant.cpp
new file mode 100644
index 0000000..ab0805e
--- /dev/null
+++ b/lib/CodeGen/CGExprConstant.cpp
@@ -0,0 +1,1087 @@
+//===--- CGExprConstant.cpp - Emit LLVM Code from Constant Expressions ----===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This contains code to emit Constant Expr nodes as LLVM code.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CodeGenFunction.h"
+#include "CodeGenModule.h"
+#include "CGObjCRuntime.h"
+#include "CGRecordLayout.h"
+#include "clang/AST/APValue.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/RecordLayout.h"
+#include "clang/AST/StmtVisitor.h"
+#include "clang/Basic/Builtins.h"
+#include "llvm/Constants.h"
+#include "llvm/Function.h"
+#include "llvm/GlobalVariable.h"
+#include "llvm/Target/TargetData.h"
+using namespace clang;
+using namespace CodeGen;
+
+//===----------------------------------------------------------------------===//
+//                            ConstStructBuilder
+//===----------------------------------------------------------------------===//
+
+namespace {
+class ConstStructBuilder {
+  CodeGenModule &CGM;
+  CodeGenFunction *CGF;
+
+  bool Packed;
+  unsigned NextFieldOffsetInBytes;
+  unsigned LLVMStructAlignment;
+  std::vector<llvm::Constant *> Elements;
+public:
+  static llvm::Constant *BuildStruct(CodeGenModule &CGM, CodeGenFunction *CGF,
+                                     InitListExpr *ILE);
+  
+private:  
+  ConstStructBuilder(CodeGenModule &CGM, CodeGenFunction *CGF)
+    : CGM(CGM), CGF(CGF), Packed(false), NextFieldOffsetInBytes(0),
+    LLVMStructAlignment(1) { }
+
+  bool AppendField(const FieldDecl *Field, uint64_t FieldOffset,
+                   llvm::Constant *InitExpr);
+
+  bool AppendBitField(const FieldDecl *Field, uint64_t FieldOffset,
+                      llvm::Constant *InitExpr);
+
+  void AppendPadding(uint64_t NumBytes);
+
+  void AppendTailPadding(uint64_t RecordSize);
+
+  void ConvertStructToPacked();
+                              
+  bool Build(InitListExpr *ILE);
+
+  unsigned getAlignment(const llvm::Constant *C) const {
+    if (Packed)  return 1;
+    return CGM.getTargetData().getABITypeAlignment(C->getType());
+  }
+
+  uint64_t getSizeInBytes(const llvm::Constant *C) const {
+    return CGM.getTargetData().getTypeAllocSize(C->getType());
+  }
+};
+
+bool ConstStructBuilder::
+AppendField(const FieldDecl *Field, uint64_t FieldOffset,
+            llvm::Constant *InitCst) {
+  uint64_t FieldOffsetInBytes = FieldOffset / 8;
+
+  assert(NextFieldOffsetInBytes <= FieldOffsetInBytes
+         && "Field offset mismatch!");
+
+  // Emit the field.
+  if (!InitCst)
+    return false;
+
+  unsigned FieldAlignment = getAlignment(InitCst);
+
+  // Round up the field offset to the alignment of the field type.
+  uint64_t AlignedNextFieldOffsetInBytes =
+    llvm::RoundUpToAlignment(NextFieldOffsetInBytes, FieldAlignment);
+
+  if (AlignedNextFieldOffsetInBytes > FieldOffsetInBytes) {
+    assert(!Packed && "Alignment is wrong even with a packed struct!");
+
+    // Convert the struct to a packed struct.
+    ConvertStructToPacked();
+    
+    AlignedNextFieldOffsetInBytes = NextFieldOffsetInBytes;
+  }
+
+  if (AlignedNextFieldOffsetInBytes < FieldOffsetInBytes) {
+    // We need to append padding.
+    AppendPadding(FieldOffsetInBytes - NextFieldOffsetInBytes);
+
+    assert(NextFieldOffsetInBytes == FieldOffsetInBytes &&
+           "Did not add enough padding!");
+
+    AlignedNextFieldOffsetInBytes = NextFieldOffsetInBytes;
+  }
+
+  // Add the field.
+  Elements.push_back(InitCst);
+  NextFieldOffsetInBytes = AlignedNextFieldOffsetInBytes +
+                             getSizeInBytes(InitCst);
+  
+  if (Packed)
+    assert(LLVMStructAlignment == 1 && "Packed struct not byte-aligned!");
+  else
+    LLVMStructAlignment = std::max(LLVMStructAlignment, FieldAlignment);
+
+  return true;
+}
+
+bool ConstStructBuilder::
+  AppendBitField(const FieldDecl *Field, uint64_t FieldOffset,
+                 llvm::Constant *InitCst) {
+  llvm::ConstantInt *CI = cast_or_null<llvm::ConstantInt>(InitCst);
+  // FIXME: Can this ever happen?
+  if (!CI)
+    return false;
+
+  if (FieldOffset > NextFieldOffsetInBytes * 8) {
+    // We need to add padding.
+    uint64_t NumBytes =
+      llvm::RoundUpToAlignment(FieldOffset -
+                               NextFieldOffsetInBytes * 8, 8) / 8;
+
+    AppendPadding(NumBytes);
+  }
+
+  uint64_t FieldSize =
+    Field->getBitWidth()->EvaluateAsInt(CGM.getContext()).getZExtValue();
+
+  llvm::APInt FieldValue = CI->getValue();
+
+  // Promote the size of FieldValue if necessary
+  // FIXME: This should never occur, but currently it can because initializer
+  // constants are cast to bool, and because clang is not enforcing bitfield
+  // width limits.
+  if (FieldSize > FieldValue.getBitWidth())
+    FieldValue.zext(FieldSize);
+
+  // Truncate the size of FieldValue to the bit field size.
+  if (FieldSize < FieldValue.getBitWidth())
+    FieldValue.trunc(FieldSize);
+
+  if (FieldOffset < NextFieldOffsetInBytes * 8) {
+    // Either part of the field or the entire field can go into the previous
+    // byte.
+    assert(!Elements.empty() && "Elements can't be empty!");
+
+    unsigned BitsInPreviousByte =
+      NextFieldOffsetInBytes * 8 - FieldOffset;
+
+    bool FitsCompletelyInPreviousByte =
+      BitsInPreviousByte >= FieldValue.getBitWidth();
+
+    llvm::APInt Tmp = FieldValue;
+
+    if (!FitsCompletelyInPreviousByte) {
+      unsigned NewFieldWidth = FieldSize - BitsInPreviousByte;
+
+      if (CGM.getTargetData().isBigEndian()) {
+        Tmp = Tmp.lshr(NewFieldWidth);
+        Tmp.trunc(BitsInPreviousByte);
+
+        // We want the remaining high bits.
+        FieldValue.trunc(NewFieldWidth);
+      } else {
+        Tmp.trunc(BitsInPreviousByte);
+
+        // We want the remaining low bits.
+        FieldValue = FieldValue.lshr(BitsInPreviousByte);
+        FieldValue.trunc(NewFieldWidth);
+      }
+    }
+
+    Tmp.zext(8);
+    if (CGM.getTargetData().isBigEndian()) {
+      if (FitsCompletelyInPreviousByte)
+        Tmp = Tmp.shl(BitsInPreviousByte - FieldValue.getBitWidth());
+    } else {
+      Tmp = Tmp.shl(8 - BitsInPreviousByte);
+    }
+
+    // Or in the bits that go into the previous byte.
+    if (llvm::ConstantInt *Val = dyn_cast<llvm::ConstantInt>(Elements.back()))
+      Tmp |= Val->getValue();
+    else
+      assert(isa<llvm::UndefValue>(Elements.back()));
+
+    Elements.back() = llvm::ConstantInt::get(CGM.getLLVMContext(), Tmp);
+
+    if (FitsCompletelyInPreviousByte)
+      return true;
+  }
+
+  while (FieldValue.getBitWidth() > 8) {
+    llvm::APInt Tmp;
+
+    if (CGM.getTargetData().isBigEndian()) {
+      // We want the high bits.
+      Tmp = FieldValue;
+      Tmp = Tmp.lshr(Tmp.getBitWidth() - 8);
+      Tmp.trunc(8);
+    } else {
+      // We want the low bits.
+      Tmp = FieldValue;
+      Tmp.trunc(8);
+
+      FieldValue = FieldValue.lshr(8);
+    }
+
+    Elements.push_back(llvm::ConstantInt::get(CGM.getLLVMContext(), Tmp));
+    NextFieldOffsetInBytes++;
+
+    FieldValue.trunc(FieldValue.getBitWidth() - 8);
+  }
+
+  assert(FieldValue.getBitWidth() > 0 &&
+         "Should have at least one bit left!");
+  assert(FieldValue.getBitWidth() <= 8 &&
+         "Should not have more than a byte left!");
+
+  if (FieldValue.getBitWidth() < 8) {
+    if (CGM.getTargetData().isBigEndian()) {
+      unsigned BitWidth = FieldValue.getBitWidth();
+
+      FieldValue.zext(8);
+      FieldValue = FieldValue << (8 - BitWidth);
+    } else
+      FieldValue.zext(8);
+  }
+
+  // Append the last element.
+  Elements.push_back(llvm::ConstantInt::get(CGM.getLLVMContext(),
+                                            FieldValue));
+  NextFieldOffsetInBytes++;
+  return true;
+}
+
+void ConstStructBuilder::AppendPadding(uint64_t NumBytes) {
+  if (!NumBytes)
+    return;
+
+  const llvm::Type *Ty = llvm::Type::getInt8Ty(CGM.getLLVMContext());
+  if (NumBytes > 1)
+    Ty = llvm::ArrayType::get(Ty, NumBytes);
+
+  llvm::Constant *C = llvm::UndefValue::get(Ty);
+  Elements.push_back(C);
+  assert(getAlignment(C) == 1 && "Padding must have 1 byte alignment!");
+
+  NextFieldOffsetInBytes += getSizeInBytes(C);
+}
+
+void ConstStructBuilder::AppendTailPadding(uint64_t RecordSize) {
+  assert(RecordSize % 8 == 0 && "Invalid record size!");
+
+  uint64_t RecordSizeInBytes = RecordSize / 8;
+  assert(NextFieldOffsetInBytes <= RecordSizeInBytes && "Size mismatch!");
+
+  unsigned NumPadBytes = RecordSizeInBytes - NextFieldOffsetInBytes;
+  AppendPadding(NumPadBytes);
+}
+
+void ConstStructBuilder::ConvertStructToPacked() {
+  std::vector<llvm::Constant *> PackedElements;
+  uint64_t ElementOffsetInBytes = 0;
+
+  for (unsigned i = 0, e = Elements.size(); i != e; ++i) {
+    llvm::Constant *C = Elements[i];
+
+    unsigned ElementAlign =
+      CGM.getTargetData().getABITypeAlignment(C->getType());
+    uint64_t AlignedElementOffsetInBytes =
+      llvm::RoundUpToAlignment(ElementOffsetInBytes, ElementAlign);
+
+    if (AlignedElementOffsetInBytes > ElementOffsetInBytes) {
+      // We need some padding.
+      uint64_t NumBytes =
+        AlignedElementOffsetInBytes - ElementOffsetInBytes;
+
+      const llvm::Type *Ty = llvm::Type::getInt8Ty(CGM.getLLVMContext());
+      if (NumBytes > 1)
+        Ty = llvm::ArrayType::get(Ty, NumBytes);
+
+      llvm::Constant *Padding = llvm::UndefValue::get(Ty);
+      PackedElements.push_back(Padding);
+      ElementOffsetInBytes += getSizeInBytes(Padding);
+    }
+
+    PackedElements.push_back(C);
+    ElementOffsetInBytes += getSizeInBytes(C);
+  }
+
+  assert(ElementOffsetInBytes == NextFieldOffsetInBytes &&
+         "Packing the struct changed its size!");
+
+  Elements = PackedElements;
+  LLVMStructAlignment = 1;
+  Packed = true;
+}
+                            
+bool ConstStructBuilder::Build(InitListExpr *ILE) {
+  RecordDecl *RD = ILE->getType()->getAs<RecordType>()->getDecl();
+  const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
+
+  unsigned FieldNo = 0;
+  unsigned ElementNo = 0;
+  for (RecordDecl::field_iterator Field = RD->field_begin(),
+       FieldEnd = RD->field_end(); Field != FieldEnd; ++Field, ++FieldNo) {
+    
+    // If this is a union, skip all the fields that aren't being initialized.
+    if (RD->isUnion() && ILE->getInitializedFieldInUnion() != *Field)
+      continue;
+
+    // Don't emit anonymous bitfields, they just affect layout.
+    if (Field->isBitField() && !Field->getIdentifier())
+      continue;
+
+    // Get the initializer.  A struct can include fields without initializers,
+    // we just use explicit null values for them.
+    llvm::Constant *EltInit;
+    if (ElementNo < ILE->getNumInits())
+      EltInit = CGM.EmitConstantExpr(ILE->getInit(ElementNo++),
+                                     Field->getType(), CGF);
+    else
+      EltInit = CGM.EmitNullConstant(Field->getType());
+    
+    if (!Field->isBitField()) {
+      // Handle non-bitfield members.
+      if (!AppendField(*Field, Layout.getFieldOffset(FieldNo), EltInit))
+        return false;
+    } else {
+      // Otherwise we have a bitfield.
+      if (!AppendBitField(*Field, Layout.getFieldOffset(FieldNo), EltInit))
+        return false;
+    }
+  }
+
+  uint64_t LayoutSizeInBytes = Layout.getSize() / 8;
+
+  if (NextFieldOffsetInBytes > LayoutSizeInBytes) {
+    // If the struct is bigger than the size of the record type,
+    // we must have a flexible array member at the end.
+    assert(RD->hasFlexibleArrayMember() &&
+           "Must have flexible array member if struct is bigger than type!");
+    
+    // No tail padding is necessary.
+    return true;
+  }
+
+  uint64_t LLVMSizeInBytes = llvm::RoundUpToAlignment(NextFieldOffsetInBytes, 
+                                                      LLVMStructAlignment);
+
+  // Check if we need to convert the struct to a packed struct.
+  if (NextFieldOffsetInBytes <= LayoutSizeInBytes && 
+      LLVMSizeInBytes > LayoutSizeInBytes) {
+    assert(!Packed && "Size mismatch!");
+    
+    ConvertStructToPacked();
+    assert(NextFieldOffsetInBytes <= LayoutSizeInBytes &&
+           "Converting to packed did not help!");
+  }
+
+  // Append tail padding if necessary.
+  AppendTailPadding(Layout.getSize());
+
+  assert(Layout.getSize() / 8 == NextFieldOffsetInBytes &&
+         "Tail padding mismatch!");
+
+  return true;
+}
+  
+llvm::Constant *ConstStructBuilder::
+  BuildStruct(CodeGenModule &CGM, CodeGenFunction *CGF, InitListExpr *ILE) {
+  ConstStructBuilder Builder(CGM, CGF);
+  
+  if (!Builder.Build(ILE))
+    return 0;
+  
+  llvm::Constant *Result =
+  llvm::ConstantStruct::get(CGM.getLLVMContext(),
+                            Builder.Elements, Builder.Packed);
+  
+  assert(llvm::RoundUpToAlignment(Builder.NextFieldOffsetInBytes,
+                                  Builder.getAlignment(Result)) ==
+         Builder.getSizeInBytes(Result) && "Size mismatch!");
+  
+  return Result;
+}
+
+  
+//===----------------------------------------------------------------------===//
+//                             ConstExprEmitter
+//===----------------------------------------------------------------------===//
+  
+class ConstExprEmitter :
+  public StmtVisitor<ConstExprEmitter, llvm::Constant*> {
+  CodeGenModule &CGM;
+  CodeGenFunction *CGF;
+  llvm::LLVMContext &VMContext;
+public:
+  ConstExprEmitter(CodeGenModule &cgm, CodeGenFunction *cgf)
+    : CGM(cgm), CGF(cgf), VMContext(cgm.getLLVMContext()) {
+  }
+
+  //===--------------------------------------------------------------------===//
+  //                            Visitor Methods
+  //===--------------------------------------------------------------------===//
+
+  llvm::Constant *VisitStmt(Stmt *S) {
+    return 0;
+  }
+
+  llvm::Constant *VisitParenExpr(ParenExpr *PE) {
+    return Visit(PE->getSubExpr());
+  }
+
+  llvm::Constant *VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
+    return Visit(E->getInitializer());
+  }
+    
+  llvm::Constant *EmitMemberFunctionPointer(CXXMethodDecl *MD) {
+    assert(MD->isInstance() && "Member function must not be static!");
+    
+    MD = MD->getCanonicalDecl();
+
+    const llvm::Type *PtrDiffTy = 
+      CGM.getTypes().ConvertType(CGM.getContext().getPointerDiffType());
+    
+    llvm::Constant *Values[2];
+    
+    // Get the function pointer (or index if this is a virtual function).
+    if (MD->isVirtual()) {
+      uint64_t Index = CGM.getVTables().getMethodVTableIndex(MD);
+
+      // Itanium C++ ABI 2.3:
+      //   For a non-virtual function, this field is a simple function pointer. 
+      //   For a virtual function, it is 1 plus the virtual table offset 
+      //   (in bytes) of the function, represented as a ptrdiff_t. 
+      Values[0] = llvm::ConstantInt::get(PtrDiffTy, (Index * 8) + 1);
+    } else {
+      const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>();
+      const llvm::Type *Ty =
+        CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD),
+                                       FPT->isVariadic());
+
+      llvm::Constant *FuncPtr = CGM.GetAddrOfFunction(MD, Ty);
+      Values[0] = llvm::ConstantExpr::getPtrToInt(FuncPtr, PtrDiffTy);
+    } 
+    
+    // The adjustment will always be 0.
+    Values[1] = llvm::ConstantInt::get(PtrDiffTy, 0);
+    
+    return llvm::ConstantStruct::get(CGM.getLLVMContext(),
+                                     Values, 2, /*Packed=*/false);
+  }
+
+  llvm::Constant *VisitUnaryAddrOf(UnaryOperator *E) {
+    if (const MemberPointerType *MPT = 
+        E->getType()->getAs<MemberPointerType>()) {
+      QualType T = MPT->getPointeeType();
+      DeclRefExpr *DRE = cast<DeclRefExpr>(E->getSubExpr());
+
+      NamedDecl *ND = DRE->getDecl();
+      if (T->isFunctionProtoType())
+        return EmitMemberFunctionPointer(cast<CXXMethodDecl>(ND));
+      
+      // We have a pointer to data member.
+      return CGM.EmitPointerToDataMember(cast<FieldDecl>(ND));
+    }
+
+    return 0;
+  }
+    
+  llvm::Constant *VisitBinSub(BinaryOperator *E) {
+    // This must be a pointer/pointer subtraction.  This only happens for
+    // address of label.
+    if (!isa<AddrLabelExpr>(E->getLHS()->IgnoreParenNoopCasts(CGM.getContext())) ||
+       !isa<AddrLabelExpr>(E->getRHS()->IgnoreParenNoopCasts(CGM.getContext())))
+      return 0;
+    
+    llvm::Constant *LHS = CGM.EmitConstantExpr(E->getLHS(),
+                                               E->getLHS()->getType(), CGF);
+    llvm::Constant *RHS = CGM.EmitConstantExpr(E->getRHS(),
+                                               E->getRHS()->getType(), CGF);
+
+    const llvm::Type *ResultType = ConvertType(E->getType());
+    LHS = llvm::ConstantExpr::getPtrToInt(LHS, ResultType);
+    RHS = llvm::ConstantExpr::getPtrToInt(RHS, ResultType);
+        
+    // No need to divide by element size, since addr of label is always void*,
+    // which has size 1 in GNUish.
+    return llvm::ConstantExpr::getSub(LHS, RHS);
+  }
+    
+  llvm::Constant *VisitCastExpr(CastExpr* E) {
+    switch (E->getCastKind()) {
+    case CastExpr::CK_ToUnion: {
+      // GCC cast to union extension
+      assert(E->getType()->isUnionType() &&
+             "Destination type is not union type!");
+      const llvm::Type *Ty = ConvertType(E->getType());
+      Expr *SubExpr = E->getSubExpr();
+
+      llvm::Constant *C =
+        CGM.EmitConstantExpr(SubExpr, SubExpr->getType(), CGF);
+      if (!C)
+        return 0;
+
+      // Build a struct with the union sub-element as the first member,
+      // and padded to the appropriate size
+      std::vector<llvm::Constant*> Elts;
+      std::vector<const llvm::Type*> Types;
+      Elts.push_back(C);
+      Types.push_back(C->getType());
+      unsigned CurSize = CGM.getTargetData().getTypeAllocSize(C->getType());
+      unsigned TotalSize = CGM.getTargetData().getTypeAllocSize(Ty);
+
+      assert(CurSize <= TotalSize && "Union size mismatch!");
+      if (unsigned NumPadBytes = TotalSize - CurSize) {
+        const llvm::Type *Ty = llvm::Type::getInt8Ty(VMContext);
+        if (NumPadBytes > 1)
+          Ty = llvm::ArrayType::get(Ty, NumPadBytes);
+
+        Elts.push_back(llvm::UndefValue::get(Ty));
+        Types.push_back(Ty);
+      }
+
+      llvm::StructType* STy =
+        llvm::StructType::get(C->getType()->getContext(), Types, false);
+      return llvm::ConstantStruct::get(STy, Elts);
+    }
+    case CastExpr::CK_NullToMemberPointer:
+      return CGM.EmitNullConstant(E->getType());
+      
+    case CastExpr::CK_BaseToDerivedMemberPointer: {
+      Expr *SubExpr = E->getSubExpr();
+
+      const MemberPointerType *SrcTy = 
+        SubExpr->getType()->getAs<MemberPointerType>();
+      const MemberPointerType *DestTy = 
+        E->getType()->getAs<MemberPointerType>();
+      
+      const CXXRecordDecl *DerivedClass =
+        cast<CXXRecordDecl>(cast<RecordType>(DestTy->getClass())->getDecl());
+
+      if (SrcTy->getPointeeType()->isFunctionProtoType()) {
+        llvm::Constant *C = 
+          CGM.EmitConstantExpr(SubExpr, SubExpr->getType(), CGF);
+        if (!C)
+          return 0;
+        
+        llvm::ConstantStruct *CS = cast<llvm::ConstantStruct>(C);
+        
+        // Check if we need to update the adjustment.
+        if (llvm::Constant *Offset = 
+            CGM.GetNonVirtualBaseClassOffset(DerivedClass, E->getBasePath())) {
+          llvm::Constant *Values[2];
+        
+          Values[0] = CS->getOperand(0);
+          Values[1] = llvm::ConstantExpr::getAdd(CS->getOperand(1), Offset);
+          return llvm::ConstantStruct::get(CGM.getLLVMContext(), Values, 2, 
+                                           /*Packed=*/false);
+        }
+        
+        return CS;
+      }          
+    }
+
+    case CastExpr::CK_BitCast: 
+      // This must be a member function pointer cast.
+      return Visit(E->getSubExpr());
+
+    default: {
+      // FIXME: This should be handled by the CK_NoOp cast kind.
+      // Explicit and implicit no-op casts
+      QualType Ty = E->getType(), SubTy = E->getSubExpr()->getType();
+      if (CGM.getContext().hasSameUnqualifiedType(Ty, SubTy))
+        return Visit(E->getSubExpr());
+
+      // Handle integer->integer casts for address-of-label differences.
+      if (Ty->isIntegerType() && SubTy->isIntegerType() &&
+          CGF) {
+        llvm::Value *Src = Visit(E->getSubExpr());
+        if (Src == 0) return 0;
+        
+        // Use EmitScalarConversion to perform the conversion.
+        return cast<llvm::Constant>(CGF->EmitScalarConversion(Src, SubTy, Ty));
+      }
+      
+      return 0;
+    }
+    }
+  }
+
+  llvm::Constant *VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) {
+    return Visit(DAE->getExpr());
+  }
+
+  llvm::Constant *EmitArrayInitialization(InitListExpr *ILE) {
+    unsigned NumInitElements = ILE->getNumInits();
+    if (NumInitElements == 1 &&
+        (isa<StringLiteral>(ILE->getInit(0)) ||
+         isa<ObjCEncodeExpr>(ILE->getInit(0))))
+      return Visit(ILE->getInit(0));
+
+    std::vector<llvm::Constant*> Elts;
+    const llvm::ArrayType *AType =
+        cast<llvm::ArrayType>(ConvertType(ILE->getType()));
+    const llvm::Type *ElemTy = AType->getElementType();
+    unsigned NumElements = AType->getNumElements();
+
+    // Initialising an array requires us to automatically
+    // initialise any elements that have not been initialised explicitly
+    unsigned NumInitableElts = std::min(NumInitElements, NumElements);
+
+    // Copy initializer elements.
+    unsigned i = 0;
+    bool RewriteType = false;
+    for (; i < NumInitableElts; ++i) {
+      Expr *Init = ILE->getInit(i);
+      llvm::Constant *C = CGM.EmitConstantExpr(Init, Init->getType(), CGF);
+      if (!C)
+        return 0;
+      RewriteType |= (C->getType() != ElemTy);
+      Elts.push_back(C);
+    }
+
+    // Initialize remaining array elements.
+    // FIXME: This doesn't handle member pointers correctly!
+    for (; i < NumElements; ++i)
+      Elts.push_back(llvm::Constant::getNullValue(ElemTy));
+
+    if (RewriteType) {
+      // FIXME: Try to avoid packing the array
+      std::vector<const llvm::Type*> Types;
+      for (unsigned i = 0; i < Elts.size(); ++i)
+        Types.push_back(Elts[i]->getType());
+      const llvm::StructType *SType = llvm::StructType::get(AType->getContext(),
+                                                            Types, true);
+      return llvm::ConstantStruct::get(SType, Elts);
+    }
+
+    return llvm::ConstantArray::get(AType, Elts);
+  }
+
+  llvm::Constant *EmitStructInitialization(InitListExpr *ILE) {
+    return ConstStructBuilder::BuildStruct(CGM, CGF, ILE);
+  }
+
+  llvm::Constant *EmitUnionInitialization(InitListExpr *ILE) {
+    return ConstStructBuilder::BuildStruct(CGM, CGF, ILE);
+  }
+
+  llvm::Constant *VisitImplicitValueInitExpr(ImplicitValueInitExpr* E) {
+    return CGM.EmitNullConstant(E->getType());
+  }
+
+  llvm::Constant *VisitInitListExpr(InitListExpr *ILE) {
+    if (ILE->getType()->isScalarType()) {
+      // We have a scalar in braces. Just use the first element.
+      if (ILE->getNumInits() > 0) {
+        Expr *Init = ILE->getInit(0);
+        return CGM.EmitConstantExpr(Init, Init->getType(), CGF);
+      }
+      return CGM.EmitNullConstant(ILE->getType());
+    }
+
+    if (ILE->getType()->isArrayType())
+      return EmitArrayInitialization(ILE);
+
+    if (ILE->getType()->isRecordType())
+      return EmitStructInitialization(ILE);
+
+    if (ILE->getType()->isUnionType())
+      return EmitUnionInitialization(ILE);
+
+    // If ILE was a constant vector, we would have handled it already.
+    if (ILE->getType()->isVectorType())
+      return 0;
+
+    assert(0 && "Unable to handle InitListExpr");
+    // Get rid of control reaches end of void function warning.
+    // Not reached.
+    return 0;
+  }
+
+  llvm::Constant *VisitCXXConstructExpr(CXXConstructExpr *E) {
+    if (!E->getConstructor()->isTrivial())
+      return 0;
+
+    QualType Ty = E->getType();
+
+    // FIXME: We should not have to call getBaseElementType here.
+    const RecordType *RT = 
+      CGM.getContext().getBaseElementType(Ty)->getAs<RecordType>();
+    const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
+    
+    // If the class doesn't have a trivial destructor, we can't emit it as a
+    // constant expr.
+    if (!RD->hasTrivialDestructor())
+      return 0;
+    
+    // Only copy and default constructors can be trivial.
+
+
+    if (E->getNumArgs()) {
+      assert(E->getNumArgs() == 1 && "trivial ctor with > 1 argument");
+      assert(E->getConstructor()->isCopyConstructor() &&
+             "trivial ctor has argument but isn't a copy ctor");
+
+      Expr *Arg = E->getArg(0);
+      assert(CGM.getContext().hasSameUnqualifiedType(Ty, Arg->getType()) &&
+             "argument to copy ctor is of wrong type");
+
+      return Visit(Arg);
+    }
+
+    return CGM.EmitNullConstant(Ty);
+  }
+
+  llvm::Constant *VisitStringLiteral(StringLiteral *E) {
+    assert(!E->getType()->isPointerType() && "Strings are always arrays");
+
+    // This must be a string initializing an array in a static initializer.
+    // Don't emit it as the address of the string, emit the string data itself
+    // as an inline array.
+    return llvm::ConstantArray::get(VMContext,
+                                    CGM.GetStringForStringLiteral(E), false);
+  }
+
+  llvm::Constant *VisitObjCEncodeExpr(ObjCEncodeExpr *E) {
+    // This must be an @encode initializing an array in a static initializer.
+    // Don't emit it as the address of the string, emit the string data itself
+    // as an inline array.
+    std::string Str;
+    CGM.getContext().getObjCEncodingForType(E->getEncodedType(), Str);
+    const ConstantArrayType *CAT = cast<ConstantArrayType>(E->getType());
+
+    // Resize the string to the right size, adding zeros at the end, or
+    // truncating as needed.
+    Str.resize(CAT->getSize().getZExtValue(), '\0');
+    return llvm::ConstantArray::get(VMContext, Str, false);
+  }
+
+  llvm::Constant *VisitUnaryExtension(const UnaryOperator *E) {
+    return Visit(E->getSubExpr());
+  }
+
+  // Utility methods
+  const llvm::Type *ConvertType(QualType T) {
+    return CGM.getTypes().ConvertType(T);
+  }
+
+public:
+  llvm::Constant *EmitLValue(Expr *E) {
+    switch (E->getStmtClass()) {
+    default: break;
+    case Expr::CompoundLiteralExprClass: {
+      // Note that due to the nature of compound literals, this is guaranteed
+      // to be the only use of the variable, so we just generate it here.
+      CompoundLiteralExpr *CLE = cast<CompoundLiteralExpr>(E);
+      llvm::Constant* C = Visit(CLE->getInitializer());
+      // FIXME: "Leaked" on failure.
+      if (C)
+        C = new llvm::GlobalVariable(CGM.getModule(), C->getType(),
+                                     E->getType().isConstant(CGM.getContext()),
+                                     llvm::GlobalValue::InternalLinkage,
+                                     C, ".compoundliteral", 0, false,
+                                     E->getType().getAddressSpace());
+      return C;
+    }
+    case Expr::DeclRefExprClass: {
+      ValueDecl *Decl = cast<DeclRefExpr>(E)->getDecl();
+      if (Decl->hasAttr<WeakRefAttr>())
+	return CGM.GetWeakRefReference(Decl);
+      if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(Decl))
+        return CGM.GetAddrOfFunction(FD);
+      if (const VarDecl* VD = dyn_cast<VarDecl>(Decl)) {
+        // We can never refer to a variable with local storage.
+        if (!VD->hasLocalStorage()) {
+          if (VD->isFileVarDecl() || VD->hasExternalStorage())
+            return CGM.GetAddrOfGlobalVar(VD);
+          else if (VD->isBlockVarDecl()) {
+            assert(CGF && "Can't access static local vars without CGF");
+            return CGF->GetAddrOfStaticLocalVar(VD);
+          }
+        }
+      }
+      break;
+    }
+    case Expr::StringLiteralClass:
+      return CGM.GetAddrOfConstantStringFromLiteral(cast<StringLiteral>(E));
+    case Expr::ObjCEncodeExprClass:
+      return CGM.GetAddrOfConstantStringFromObjCEncode(cast<ObjCEncodeExpr>(E));
+    case Expr::ObjCStringLiteralClass: {
+      ObjCStringLiteral* SL = cast<ObjCStringLiteral>(E);
+      llvm::Constant *C =
+          CGM.getObjCRuntime().GenerateConstantString(SL->getString());
+      return llvm::ConstantExpr::getBitCast(C, ConvertType(E->getType()));
+    }
+    case Expr::PredefinedExprClass: {
+      unsigned Type = cast<PredefinedExpr>(E)->getIdentType();
+      if (CGF) {
+        LValue Res = CGF->EmitPredefinedFunctionName(Type);
+        return cast<llvm::Constant>(Res.getAddress());
+      } else if (Type == PredefinedExpr::PrettyFunction) {
+        return CGM.GetAddrOfConstantCString("top level", ".tmp");
+      }
+
+      return CGM.GetAddrOfConstantCString("", ".tmp");
+    }
+    case Expr::AddrLabelExprClass: {
+      assert(CGF && "Invalid address of label expression outside function.");
+      llvm::Constant *Ptr =
+        CGF->GetAddrOfLabel(cast<AddrLabelExpr>(E)->getLabel());
+      return llvm::ConstantExpr::getBitCast(Ptr, ConvertType(E->getType()));
+    }
+    case Expr::CallExprClass: {
+      CallExpr* CE = cast<CallExpr>(E);
+      unsigned builtin = CE->isBuiltinCall(CGM.getContext());
+      if (builtin !=
+            Builtin::BI__builtin___CFStringMakeConstantString &&
+          builtin !=
+            Builtin::BI__builtin___NSStringMakeConstantString)
+        break;
+      const Expr *Arg = CE->getArg(0)->IgnoreParenCasts();
+      const StringLiteral *Literal = cast<StringLiteral>(Arg);
+      if (builtin ==
+            Builtin::BI__builtin___NSStringMakeConstantString) {
+        return CGM.getObjCRuntime().GenerateConstantString(Literal);
+      }
+      // FIXME: need to deal with UCN conversion issues.
+      return CGM.GetAddrOfConstantCFString(Literal);
+    }
+    case Expr::BlockExprClass: {
+      std::string FunctionName;
+      if (CGF)
+        FunctionName = CGF->CurFn->getName();
+      else
+        FunctionName = "global";
+
+      return CGM.GetAddrOfGlobalBlock(cast<BlockExpr>(E), FunctionName.c_str());
+    }
+    }
+
+    return 0;
+  }
+};
+
+}  // end anonymous namespace.
+
+llvm::Constant *CodeGenModule::EmitConstantExpr(const Expr *E,
+                                                QualType DestType,
+                                                CodeGenFunction *CGF) {
+  Expr::EvalResult Result;
+
+  bool Success = false;
+
+  if (DestType->isReferenceType())
+    Success = E->EvaluateAsLValue(Result, Context);
+  else
+    Success = E->Evaluate(Result, Context);
+
+  if (Success && !Result.HasSideEffects) {
+    switch (Result.Val.getKind()) {
+    case APValue::Uninitialized:
+      assert(0 && "Constant expressions should be initialized.");
+      return 0;
+    case APValue::LValue: {
+      const llvm::Type *DestTy = getTypes().ConvertTypeForMem(DestType);
+      llvm::Constant *Offset =
+        llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext),
+                               Result.Val.getLValueOffset().getQuantity());
+
+      llvm::Constant *C;
+      if (const Expr *LVBase = Result.Val.getLValueBase()) {
+        C = ConstExprEmitter(*this, CGF).EmitLValue(const_cast<Expr*>(LVBase));
+
+        // Apply offset if necessary.
+        if (!Offset->isNullValue()) {
+          const llvm::Type *Type = llvm::Type::getInt8PtrTy(VMContext);
+          llvm::Constant *Casted = llvm::ConstantExpr::getBitCast(C, Type);
+          Casted = llvm::ConstantExpr::getGetElementPtr(Casted, &Offset, 1);
+          C = llvm::ConstantExpr::getBitCast(Casted, C->getType());
+        }
+
+        // Convert to the appropriate type; this could be an lvalue for
+        // an integer.
+        if (isa<llvm::PointerType>(DestTy))
+          return llvm::ConstantExpr::getBitCast(C, DestTy);
+
+        return llvm::ConstantExpr::getPtrToInt(C, DestTy);
+      } else {
+        C = Offset;
+
+        // Convert to the appropriate type; this could be an lvalue for
+        // an integer.
+        if (isa<llvm::PointerType>(DestTy))
+          return llvm::ConstantExpr::getIntToPtr(C, DestTy);
+
+        // If the types don't match this should only be a truncate.
+        if (C->getType() != DestTy)
+          return llvm::ConstantExpr::getTrunc(C, DestTy);
+
+        return C;
+      }
+    }
+    case APValue::Int: {
+      llvm::Constant *C = llvm::ConstantInt::get(VMContext,
+                                                 Result.Val.getInt());
+
+      if (C->getType() == llvm::Type::getInt1Ty(VMContext)) {
+        const llvm::Type *BoolTy = getTypes().ConvertTypeForMem(E->getType());
+        C = llvm::ConstantExpr::getZExt(C, BoolTy);
+      }
+      return C;
+    }
+    case APValue::ComplexInt: {
+      llvm::Constant *Complex[2];
+
+      Complex[0] = llvm::ConstantInt::get(VMContext,
+                                          Result.Val.getComplexIntReal());
+      Complex[1] = llvm::ConstantInt::get(VMContext,
+                                          Result.Val.getComplexIntImag());
+
+      // FIXME: the target may want to specify that this is packed.
+      return llvm::ConstantStruct::get(VMContext, Complex, 2, false);
+    }
+    case APValue::Float:
+      return llvm::ConstantFP::get(VMContext, Result.Val.getFloat());
+    case APValue::ComplexFloat: {
+      llvm::Constant *Complex[2];
+
+      Complex[0] = llvm::ConstantFP::get(VMContext,
+                                         Result.Val.getComplexFloatReal());
+      Complex[1] = llvm::ConstantFP::get(VMContext,
+                                         Result.Val.getComplexFloatImag());
+
+      // FIXME: the target may want to specify that this is packed.
+      return llvm::ConstantStruct::get(VMContext, Complex, 2, false);
+    }
+    case APValue::Vector: {
+      llvm::SmallVector<llvm::Constant *, 4> Inits;
+      unsigned NumElts = Result.Val.getVectorLength();
+
+      for (unsigned i = 0; i != NumElts; ++i) {
+        APValue &Elt = Result.Val.getVectorElt(i);
+        if (Elt.isInt())
+          Inits.push_back(llvm::ConstantInt::get(VMContext, Elt.getInt()));
+        else
+          Inits.push_back(llvm::ConstantFP::get(VMContext, Elt.getFloat()));
+      }
+      return llvm::ConstantVector::get(&Inits[0], Inits.size());
+    }
+    }
+  }
+
+  llvm::Constant* C = ConstExprEmitter(*this, CGF).Visit(const_cast<Expr*>(E));
+  if (C && C->getType() == llvm::Type::getInt1Ty(VMContext)) {
+    const llvm::Type *BoolTy = getTypes().ConvertTypeForMem(E->getType());
+    C = llvm::ConstantExpr::getZExt(C, BoolTy);
+  }
+  return C;
+}
+
+static bool containsPointerToDataMember(CodeGenTypes &Types, QualType T) {
+  // No need to check for member pointers when not compiling C++.
+  if (!Types.getContext().getLangOptions().CPlusPlus)
+    return false;
+  
+  T = Types.getContext().getBaseElementType(T);
+  
+  if (const RecordType *RT = T->getAs<RecordType>()) {
+    const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
+    
+    // FIXME: It would be better if there was a way to explicitly compute the
+    // record layout instead of converting to a type.
+    Types.ConvertTagDeclType(RD);
+    
+    const CGRecordLayout &Layout = Types.getCGRecordLayout(RD);
+    return Layout.containsPointerToDataMember();
+  }
+    
+  if (const MemberPointerType *MPT = T->getAs<MemberPointerType>())
+    return !MPT->getPointeeType()->isFunctionType();
+  
+  return false;
+}
+
+llvm::Constant *CodeGenModule::EmitNullConstant(QualType T) {
+  if (!containsPointerToDataMember(getTypes(), T))
+    return llvm::Constant::getNullValue(getTypes().ConvertTypeForMem(T));
+    
+  if (const ConstantArrayType *CAT = Context.getAsConstantArrayType(T)) {
+
+    QualType ElementTy = CAT->getElementType();
+
+    llvm::Constant *Element = EmitNullConstant(ElementTy);
+    unsigned NumElements = CAT->getSize().getZExtValue();
+    std::vector<llvm::Constant *> Array(NumElements);
+    for (unsigned i = 0; i != NumElements; ++i)
+      Array[i] = Element;
+
+    const llvm::ArrayType *ATy =
+      cast<llvm::ArrayType>(getTypes().ConvertTypeForMem(T));
+    return llvm::ConstantArray::get(ATy, Array);
+  }
+
+  if (const RecordType *RT = T->getAs<RecordType>()) {
+    const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
+    assert(!RD->getNumBases() && 
+           "FIXME: Handle zero-initializing structs with bases and "
+           "pointers to data members.");
+    const llvm::StructType *STy =
+      cast<llvm::StructType>(getTypes().ConvertTypeForMem(T));
+    unsigned NumElements = STy->getNumElements();
+    std::vector<llvm::Constant *> Elements(NumElements);
+
+    for (RecordDecl::field_iterator I = RD->field_begin(),
+         E = RD->field_end(); I != E; ++I) {
+      const FieldDecl *FD = *I;
+      
+      const CGRecordLayout &RL =
+        getTypes().getCGRecordLayout(FD->getParent());
+      unsigned FieldNo = RL.getLLVMFieldNo(FD);
+      Elements[FieldNo] = EmitNullConstant(FD->getType());
+    }
+    
+    // Now go through all other fields and zero them out.
+    for (unsigned i = 0; i != NumElements; ++i) {
+      if (!Elements[i])
+        Elements[i] = llvm::Constant::getNullValue(STy->getElementType(i));
+    }
+    
+    return llvm::ConstantStruct::get(STy, Elements);
+  }
+
+  assert(!T->getAs<MemberPointerType>()->getPointeeType()->isFunctionType() &&
+         "Should only see pointers to data members here!");
+  
+  // Itanium C++ ABI 2.3:
+  //   A NULL pointer is represented as -1.
+  return llvm::ConstantInt::get(getTypes().ConvertTypeForMem(T), -1ULL, 
+                                /*isSigned=*/true);
+}
+
+llvm::Constant *
+CodeGenModule::EmitPointerToDataMember(const FieldDecl *FD) {
+
+  // Itanium C++ ABI 2.3:
+  //   A pointer to data member is an offset from the base address of the class
+  //   object containing it, represented as a ptrdiff_t
+
+  const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(FD->getParent());
+  QualType ClassType = 
+    getContext().getTypeDeclType(const_cast<CXXRecordDecl *>(ClassDecl));
+  
+  const llvm::StructType *ClassLTy =
+    cast<llvm::StructType>(getTypes().ConvertType(ClassType));
+
+  const CGRecordLayout &RL =
+    getTypes().getCGRecordLayout(FD->getParent());
+  unsigned FieldNo = RL.getLLVMFieldNo(FD);
+  uint64_t Offset = 
+    getTargetData().getStructLayout(ClassLTy)->getElementOffset(FieldNo);
+
+  const llvm::Type *PtrDiffTy = 
+    getTypes().ConvertType(getContext().getPointerDiffType());
+
+  return llvm::ConstantInt::get(PtrDiffTy, Offset);
+}
diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp
new file mode 100644
index 0000000..842590b
--- /dev/null
+++ b/lib/CodeGen/CGExprScalar.cpp
@@ -0,0 +1,1975 @@
+//===--- CGExprScalar.cpp - Emit LLVM Code for Scalar Exprs ---------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This contains code to emit Expr nodes with scalar LLVM types as LLVM code.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CodeGenFunction.h"
+#include "CGObjCRuntime.h"
+#include "CodeGenModule.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/RecordLayout.h"
+#include "clang/AST/StmtVisitor.h"
+#include "clang/Basic/TargetInfo.h"
+#include "llvm/Constants.h"
+#include "llvm/Function.h"
+#include "llvm/GlobalVariable.h"
+#include "llvm/Intrinsics.h"
+#include "llvm/Module.h"
+#include "llvm/Support/CFG.h"
+#include "llvm/Target/TargetData.h"
+#include <cstdarg>
+
+using namespace clang;
+using namespace CodeGen;
+using llvm::Value;
+
+//===----------------------------------------------------------------------===//
+//                         Scalar Expression Emitter
+//===----------------------------------------------------------------------===//
+
+struct BinOpInfo {
+  Value *LHS;
+  Value *RHS;
+  QualType Ty;  // Computation Type.
+  const BinaryOperator *E;
+};
+
+namespace {
+class ScalarExprEmitter
+  : public StmtVisitor<ScalarExprEmitter, Value*> {
+  CodeGenFunction &CGF;
+  CGBuilderTy &Builder;
+  bool IgnoreResultAssign;
+  llvm::LLVMContext &VMContext;
+public:
+
+  ScalarExprEmitter(CodeGenFunction &cgf, bool ira=false)
+    : CGF(cgf), Builder(CGF.Builder), IgnoreResultAssign(ira),
+      VMContext(cgf.getLLVMContext()) {
+  }
+
+  //===--------------------------------------------------------------------===//
+  //                               Utilities
+  //===--------------------------------------------------------------------===//
+
+  bool TestAndClearIgnoreResultAssign() {
+    bool I = IgnoreResultAssign;
+    IgnoreResultAssign = false;
+    return I;
+  }
+
+  const llvm::Type *ConvertType(QualType T) { return CGF.ConvertType(T); }
+  LValue EmitLValue(const Expr *E) { return CGF.EmitLValue(E); }
+  LValue EmitCheckedLValue(const Expr *E) { return CGF.EmitCheckedLValue(E); }
+
+  Value *EmitLoadOfLValue(LValue LV, QualType T) {
+    return CGF.EmitLoadOfLValue(LV, T).getScalarVal();
+  }
+
+  /// EmitLoadOfLValue - Given an expression with complex type that represents a
+  /// value l-value, this method emits the address of the l-value, then loads
+  /// and returns the result.
+  Value *EmitLoadOfLValue(const Expr *E) {
+    return EmitLoadOfLValue(EmitCheckedLValue(E), E->getType());
+  }
+
+  /// EmitConversionToBool - Convert the specified expression value to a
+  /// boolean (i1) truth value.  This is equivalent to "Val != 0".
+  Value *EmitConversionToBool(Value *Src, QualType DstTy);
+
+  /// EmitScalarConversion - Emit a conversion from the specified type to the
+  /// specified destination type, both of which are LLVM scalar types.
+  Value *EmitScalarConversion(Value *Src, QualType SrcTy, QualType DstTy);
+
+  /// EmitComplexToScalarConversion - Emit a conversion from the specified
+  /// complex type to the specified destination type, where the destination type
+  /// is an LLVM scalar type.
+  Value *EmitComplexToScalarConversion(CodeGenFunction::ComplexPairTy Src,
+                                       QualType SrcTy, QualType DstTy);
+
+  //===--------------------------------------------------------------------===//
+  //                            Visitor Methods
+  //===--------------------------------------------------------------------===//
+
+  Value *VisitStmt(Stmt *S) {
+    S->dump(CGF.getContext().getSourceManager());
+    assert(0 && "Stmt can't have complex result type!");
+    return 0;
+  }
+  Value *VisitExpr(Expr *S);
+  
+  Value *VisitParenExpr(ParenExpr *PE) { return Visit(PE->getSubExpr()); }
+
+  // Leaves.
+  Value *VisitIntegerLiteral(const IntegerLiteral *E) {
+    return llvm::ConstantInt::get(VMContext, E->getValue());
+  }
+  Value *VisitFloatingLiteral(const FloatingLiteral *E) {
+    return llvm::ConstantFP::get(VMContext, E->getValue());
+  }
+  Value *VisitCharacterLiteral(const CharacterLiteral *E) {
+    return llvm::ConstantInt::get(ConvertType(E->getType()), E->getValue());
+  }
+  Value *VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E) {
+    return llvm::ConstantInt::get(ConvertType(E->getType()), E->getValue());
+  }
+  Value *VisitCXXZeroInitValueExpr(const CXXZeroInitValueExpr *E) {
+    return llvm::Constant::getNullValue(ConvertType(E->getType()));
+  }
+  Value *VisitGNUNullExpr(const GNUNullExpr *E) {
+    return llvm::Constant::getNullValue(ConvertType(E->getType()));
+  }
+  Value *VisitTypesCompatibleExpr(const TypesCompatibleExpr *E) {
+    return llvm::ConstantInt::get(ConvertType(E->getType()),
+                                  CGF.getContext().typesAreCompatible(
+                                    E->getArgType1(), E->getArgType2()));
+  }
+  Value *VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr *E);
+  Value *VisitAddrLabelExpr(const AddrLabelExpr *E) {
+    llvm::Value *V = CGF.GetAddrOfLabel(E->getLabel());
+    return Builder.CreateBitCast(V, ConvertType(E->getType()));
+  }
+
+  // l-values.
+  Value *VisitDeclRefExpr(DeclRefExpr *E) {
+    Expr::EvalResult Result;
+    if (E->Evaluate(Result, CGF.getContext()) && Result.Val.isInt()) {
+      assert(!Result.HasSideEffects && "Constant declref with side-effect?!");
+      return llvm::ConstantInt::get(VMContext, Result.Val.getInt());
+    }
+    return EmitLoadOfLValue(E);
+  }
+  Value *VisitObjCSelectorExpr(ObjCSelectorExpr *E) {
+    return CGF.EmitObjCSelectorExpr(E);
+  }
+  Value *VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
+    return CGF.EmitObjCProtocolExpr(E);
+  }
+  Value *VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
+    return EmitLoadOfLValue(E);
+  }
+  Value *VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
+    return EmitLoadOfLValue(E);
+  }
+  Value *VisitObjCImplicitSetterGetterRefExpr(
+                        ObjCImplicitSetterGetterRefExpr *E) {
+    return EmitLoadOfLValue(E);
+  }
+  Value *VisitObjCMessageExpr(ObjCMessageExpr *E) {
+    return CGF.EmitObjCMessageExpr(E).getScalarVal();
+  }
+
+  Value *VisitObjCIsaExpr(ObjCIsaExpr *E) {
+    LValue LV = CGF.EmitObjCIsaExpr(E);
+    Value *V = CGF.EmitLoadOfLValue(LV, E->getType()).getScalarVal();
+    return V;
+  }
+
+  Value *VisitArraySubscriptExpr(ArraySubscriptExpr *E);
+  Value *VisitShuffleVectorExpr(ShuffleVectorExpr *E);
+  Value *VisitMemberExpr(MemberExpr *E);
+  Value *VisitExtVectorElementExpr(Expr *E) { return EmitLoadOfLValue(E); }
+  Value *VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
+    return EmitLoadOfLValue(E);
+  }
+
+  Value *VisitInitListExpr(InitListExpr *E);
+
+  Value *VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E) {
+    return llvm::Constant::getNullValue(ConvertType(E->getType()));
+  }
+  Value *VisitCastExpr(CastExpr *E) {
+    // Make sure to evaluate VLA bounds now so that we have them for later.
+    if (E->getType()->isVariablyModifiedType())
+      CGF.EmitVLASize(E->getType());
+
+    return EmitCastExpr(E);
+  }
+  Value *EmitCastExpr(CastExpr *E);
+
+  Value *VisitCallExpr(const CallExpr *E) {
+    if (E->getCallReturnType()->isReferenceType())
+      return EmitLoadOfLValue(E);
+
+    return CGF.EmitCallExpr(E).getScalarVal();
+  }
+
+  Value *VisitStmtExpr(const StmtExpr *E);
+
+  Value *VisitBlockDeclRefExpr(const BlockDeclRefExpr *E);
+
+  // Unary Operators.
+  Value *VisitPrePostIncDec(const UnaryOperator *E, bool isInc, bool isPre) {
+    LValue LV = EmitLValue(E->getSubExpr());
+    return CGF.EmitScalarPrePostIncDec(E, LV, isInc, isPre);
+  }
+  Value *VisitUnaryPostDec(const UnaryOperator *E) {
+    return VisitPrePostIncDec(E, false, false);
+  }
+  Value *VisitUnaryPostInc(const UnaryOperator *E) {
+    return VisitPrePostIncDec(E, true, false);
+  }
+  Value *VisitUnaryPreDec(const UnaryOperator *E) {
+    return VisitPrePostIncDec(E, false, true);
+  }
+  Value *VisitUnaryPreInc(const UnaryOperator *E) {
+    return VisitPrePostIncDec(E, true, true);
+  }
+  Value *VisitUnaryAddrOf(const UnaryOperator *E) {
+    return EmitLValue(E->getSubExpr()).getAddress();
+  }
+  Value *VisitUnaryDeref(const Expr *E) { return EmitLoadOfLValue(E); }
+  Value *VisitUnaryPlus(const UnaryOperator *E) {
+    // This differs from gcc, though, most likely due to a bug in gcc.
+    TestAndClearIgnoreResultAssign();
+    return Visit(E->getSubExpr());
+  }
+  Value *VisitUnaryMinus    (const UnaryOperator *E);
+  Value *VisitUnaryNot      (const UnaryOperator *E);
+  Value *VisitUnaryLNot     (const UnaryOperator *E);
+  Value *VisitUnaryReal     (const UnaryOperator *E);
+  Value *VisitUnaryImag     (const UnaryOperator *E);
+  Value *VisitUnaryExtension(const UnaryOperator *E) {
+    return Visit(E->getSubExpr());
+  }
+  Value *VisitUnaryOffsetOf(const UnaryOperator *E);
+
+  // C++
+  Value *VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) {
+    return Visit(DAE->getExpr());
+  }
+  Value *VisitCXXThisExpr(CXXThisExpr *TE) {
+    return CGF.LoadCXXThis();
+  }
+
+  Value *VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E) {
+    return CGF.EmitCXXExprWithTemporaries(E).getScalarVal();
+  }
+  Value *VisitCXXNewExpr(const CXXNewExpr *E) {
+    return CGF.EmitCXXNewExpr(E);
+  }
+  Value *VisitCXXDeleteExpr(const CXXDeleteExpr *E) {
+    CGF.EmitCXXDeleteExpr(E);
+    return 0;
+  }
+  Value *VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E) {
+    return llvm::ConstantInt::get(Builder.getInt1Ty(),
+                                  E->EvaluateTrait(CGF.getContext()));
+  }
+
+  Value *VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E) {
+    // C++ [expr.pseudo]p1:
+    //   The result shall only be used as the operand for the function call
+    //   operator (), and the result of such a call has type void. The only
+    //   effect is the evaluation of the postfix-expression before the dot or
+    //   arrow.
+    CGF.EmitScalarExpr(E->getBase());
+    return 0;
+  }
+
+  Value *VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr *E) {
+    return llvm::Constant::getNullValue(ConvertType(E->getType()));
+  }
+
+  Value *VisitCXXThrowExpr(const CXXThrowExpr *E) {
+    CGF.EmitCXXThrowExpr(E);
+    return 0;
+  }
+
+  // Binary Operators.
+  Value *EmitMul(const BinOpInfo &Ops) {
+    if (CGF.getContext().getLangOptions().OverflowChecking
+        && Ops.Ty->isSignedIntegerType())
+      return EmitOverflowCheckedBinOp(Ops);
+    if (Ops.LHS->getType()->isFPOrFPVectorTy())
+      return Builder.CreateFMul(Ops.LHS, Ops.RHS, "mul");
+    return Builder.CreateMul(Ops.LHS, Ops.RHS, "mul");
+  }
+  /// Create a binary op that checks for overflow.
+  /// Currently only supports +, - and *.
+  Value *EmitOverflowCheckedBinOp(const BinOpInfo &Ops);
+  Value *EmitDiv(const BinOpInfo &Ops);
+  Value *EmitRem(const BinOpInfo &Ops);
+  Value *EmitAdd(const BinOpInfo &Ops);
+  Value *EmitSub(const BinOpInfo &Ops);
+  Value *EmitShl(const BinOpInfo &Ops);
+  Value *EmitShr(const BinOpInfo &Ops);
+  Value *EmitAnd(const BinOpInfo &Ops) {
+    return Builder.CreateAnd(Ops.LHS, Ops.RHS, "and");
+  }
+  Value *EmitXor(const BinOpInfo &Ops) {
+    return Builder.CreateXor(Ops.LHS, Ops.RHS, "xor");
+  }
+  Value *EmitOr (const BinOpInfo &Ops) {
+    return Builder.CreateOr(Ops.LHS, Ops.RHS, "or");
+  }
+
+  BinOpInfo EmitBinOps(const BinaryOperator *E);
+  LValue EmitCompoundAssignLValue(const CompoundAssignOperator *E,
+                            Value *(ScalarExprEmitter::*F)(const BinOpInfo &),
+                                  Value *&BitFieldResult);
+
+  Value *EmitCompoundAssign(const CompoundAssignOperator *E,
+                            Value *(ScalarExprEmitter::*F)(const BinOpInfo &));
+
+  // Binary operators and binary compound assignment operators.
+#define HANDLEBINOP(OP) \
+  Value *VisitBin ## OP(const BinaryOperator *E) {                         \
+    return Emit ## OP(EmitBinOps(E));                                      \
+  }                                                                        \
+  Value *VisitBin ## OP ## Assign(const CompoundAssignOperator *E) {       \
+    return EmitCompoundAssign(E, &ScalarExprEmitter::Emit ## OP);          \
+  }
+  HANDLEBINOP(Mul)
+  HANDLEBINOP(Div)
+  HANDLEBINOP(Rem)
+  HANDLEBINOP(Add)
+  HANDLEBINOP(Sub)
+  HANDLEBINOP(Shl)
+  HANDLEBINOP(Shr)
+  HANDLEBINOP(And)
+  HANDLEBINOP(Xor)
+  HANDLEBINOP(Or)
+#undef HANDLEBINOP
+
+  // Comparisons.
+  Value *EmitCompare(const BinaryOperator *E, unsigned UICmpOpc,
+                     unsigned SICmpOpc, unsigned FCmpOpc);
+#define VISITCOMP(CODE, UI, SI, FP) \
+    Value *VisitBin##CODE(const BinaryOperator *E) { \
+      return EmitCompare(E, llvm::ICmpInst::UI, llvm::ICmpInst::SI, \
+                         llvm::FCmpInst::FP); }
+  VISITCOMP(LT, ICMP_ULT, ICMP_SLT, FCMP_OLT)
+  VISITCOMP(GT, ICMP_UGT, ICMP_SGT, FCMP_OGT)
+  VISITCOMP(LE, ICMP_ULE, ICMP_SLE, FCMP_OLE)
+  VISITCOMP(GE, ICMP_UGE, ICMP_SGE, FCMP_OGE)
+  VISITCOMP(EQ, ICMP_EQ , ICMP_EQ , FCMP_OEQ)
+  VISITCOMP(NE, ICMP_NE , ICMP_NE , FCMP_UNE)
+#undef VISITCOMP
+
+  Value *VisitBinAssign     (const BinaryOperator *E);
+
+  Value *VisitBinLAnd       (const BinaryOperator *E);
+  Value *VisitBinLOr        (const BinaryOperator *E);
+  Value *VisitBinComma      (const BinaryOperator *E);
+
+  Value *VisitBinPtrMemD(const Expr *E) { return EmitLoadOfLValue(E); }
+  Value *VisitBinPtrMemI(const Expr *E) { return EmitLoadOfLValue(E); }
+
+  // Other Operators.
+  Value *VisitBlockExpr(const BlockExpr *BE);
+  Value *VisitConditionalOperator(const ConditionalOperator *CO);
+  Value *VisitChooseExpr(ChooseExpr *CE);
+  Value *VisitVAArgExpr(VAArgExpr *VE);
+  Value *VisitObjCStringLiteral(const ObjCStringLiteral *E) {
+    return CGF.EmitObjCStringLiteral(E);
+  }
+};
+}  // end anonymous namespace.
+
+//===----------------------------------------------------------------------===//
+//                                Utilities
+//===----------------------------------------------------------------------===//
+
+/// EmitConversionToBool - Convert the specified expression value to a
+/// boolean (i1) truth value.  This is equivalent to "Val != 0".
+Value *ScalarExprEmitter::EmitConversionToBool(Value *Src, QualType SrcType) {
+  assert(SrcType.isCanonical() && "EmitScalarConversion strips typedefs");
+
+  if (SrcType->isRealFloatingType()) {
+    // Compare against 0.0 for fp scalars.
+    llvm::Value *Zero = llvm::Constant::getNullValue(Src->getType());
+    return Builder.CreateFCmpUNE(Src, Zero, "tobool");
+  }
+
+  if (SrcType->isMemberPointerType()) {
+    // Compare against -1.
+    llvm::Value *NegativeOne = llvm::Constant::getAllOnesValue(Src->getType());
+    return Builder.CreateICmpNE(Src, NegativeOne, "tobool");
+  }
+
+  assert((SrcType->isIntegerType() || isa<llvm::PointerType>(Src->getType())) &&
+         "Unknown scalar type to convert");
+
+  // Because of the type rules of C, we often end up computing a logical value,
+  // then zero extending it to int, then wanting it as a logical value again.
+  // Optimize this common case.
+  if (llvm::ZExtInst *ZI = dyn_cast<llvm::ZExtInst>(Src)) {
+    if (ZI->getOperand(0)->getType() ==
+        llvm::Type::getInt1Ty(CGF.getLLVMContext())) {
+      Value *Result = ZI->getOperand(0);
+      // If there aren't any more uses, zap the instruction to save space.
+      // Note that there can be more uses, for example if this
+      // is the result of an assignment.
+      if (ZI->use_empty())
+        ZI->eraseFromParent();
+      return Result;
+    }
+  }
+
+  // Compare against an integer or pointer null.
+  llvm::Value *Zero = llvm::Constant::getNullValue(Src->getType());
+  return Builder.CreateICmpNE(Src, Zero, "tobool");
+}
+
+/// EmitScalarConversion - Emit a conversion from the specified type to the
+/// specified destination type, both of which are LLVM scalar types.
+Value *ScalarExprEmitter::EmitScalarConversion(Value *Src, QualType SrcType,
+                                               QualType DstType) {
+  SrcType = CGF.getContext().getCanonicalType(SrcType);
+  DstType = CGF.getContext().getCanonicalType(DstType);
+  if (SrcType == DstType) return Src;
+
+  if (DstType->isVoidType()) return 0;
+
+  llvm::LLVMContext &VMContext = CGF.getLLVMContext();
+
+  // Handle conversions to bool first, they are special: comparisons against 0.
+  if (DstType->isBooleanType())
+    return EmitConversionToBool(Src, SrcType);
+
+  const llvm::Type *DstTy = ConvertType(DstType);
+
+  // Ignore conversions like int -> uint.
+  if (Src->getType() == DstTy)
+    return Src;
+
+  // Handle pointer conversions next: pointers can only be converted to/from
+  // other pointers and integers. Check for pointer types in terms of LLVM, as
+  // some native types (like Obj-C id) may map to a pointer type.
+  if (isa<llvm::PointerType>(DstTy)) {
+    // The source value may be an integer, or a pointer.
+    if (isa<llvm::PointerType>(Src->getType()))
+      return Builder.CreateBitCast(Src, DstTy, "conv");
+
+    assert(SrcType->isIntegerType() && "Not ptr->ptr or int->ptr conversion?");
+    // First, convert to the correct width so that we control the kind of
+    // extension.
+    const llvm::Type *MiddleTy =
+          llvm::IntegerType::get(VMContext, CGF.LLVMPointerWidth);
+    bool InputSigned = SrcType->isSignedIntegerType();
+    llvm::Value* IntResult =
+        Builder.CreateIntCast(Src, MiddleTy, InputSigned, "conv");
+    // Then, cast to pointer.
+    return Builder.CreateIntToPtr(IntResult, DstTy, "conv");
+  }
+
+  if (isa<llvm::PointerType>(Src->getType())) {
+    // Must be an ptr to int cast.
+    assert(isa<llvm::IntegerType>(DstTy) && "not ptr->int?");
+    return Builder.CreatePtrToInt(Src, DstTy, "conv");
+  }
+
+  // A scalar can be splatted to an extended vector of the same element type
+  if (DstType->isExtVectorType() && !SrcType->isVectorType()) {
+    // Cast the scalar to element type
+    QualType EltTy = DstType->getAs<ExtVectorType>()->getElementType();
+    llvm::Value *Elt = EmitScalarConversion(Src, SrcType, EltTy);
+
+    // Insert the element in element zero of an undef vector
+    llvm::Value *UnV = llvm::UndefValue::get(DstTy);
+    llvm::Value *Idx =
+        llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 0);
+    UnV = Builder.CreateInsertElement(UnV, Elt, Idx, "tmp");
+
+    // Splat the element across to all elements
+    llvm::SmallVector<llvm::Constant*, 16> Args;
+    unsigned NumElements = cast<llvm::VectorType>(DstTy)->getNumElements();
+    for (unsigned i = 0; i < NumElements; i++)
+      Args.push_back(llvm::ConstantInt::get(
+                                        llvm::Type::getInt32Ty(VMContext), 0));
+
+    llvm::Constant *Mask = llvm::ConstantVector::get(&Args[0], NumElements);
+    llvm::Value *Yay = Builder.CreateShuffleVector(UnV, UnV, Mask, "splat");
+    return Yay;
+  }
+
+  // Allow bitcast from vector to integer/fp of the same size.
+  if (isa<llvm::VectorType>(Src->getType()) ||
+      isa<llvm::VectorType>(DstTy))
+    return Builder.CreateBitCast(Src, DstTy, "conv");
+
+  // Finally, we have the arithmetic types: real int/float.
+  if (isa<llvm::IntegerType>(Src->getType())) {
+    bool InputSigned = SrcType->isSignedIntegerType();
+    if (isa<llvm::IntegerType>(DstTy))
+      return Builder.CreateIntCast(Src, DstTy, InputSigned, "conv");
+    else if (InputSigned)
+      return Builder.CreateSIToFP(Src, DstTy, "conv");
+    else
+      return Builder.CreateUIToFP(Src, DstTy, "conv");
+  }
+
+  assert(Src->getType()->isFloatingPointTy() && "Unknown real conversion");
+  if (isa<llvm::IntegerType>(DstTy)) {
+    if (DstType->isSignedIntegerType())
+      return Builder.CreateFPToSI(Src, DstTy, "conv");
+    else
+      return Builder.CreateFPToUI(Src, DstTy, "conv");
+  }
+
+  assert(DstTy->isFloatingPointTy() && "Unknown real conversion");
+  if (DstTy->getTypeID() < Src->getType()->getTypeID())
+    return Builder.CreateFPTrunc(Src, DstTy, "conv");
+  else
+    return Builder.CreateFPExt(Src, DstTy, "conv");
+}
+
+/// EmitComplexToScalarConversion - Emit a conversion from the specified complex
+/// type to the specified destination type, where the destination type is an
+/// LLVM scalar type.
+Value *ScalarExprEmitter::
+EmitComplexToScalarConversion(CodeGenFunction::ComplexPairTy Src,
+                              QualType SrcTy, QualType DstTy) {
+  // Get the source element type.
+  SrcTy = SrcTy->getAs<ComplexType>()->getElementType();
+
+  // Handle conversions to bool first, they are special: comparisons against 0.
+  if (DstTy->isBooleanType()) {
+    //  Complex != 0  -> (Real != 0) | (Imag != 0)
+    Src.first  = EmitScalarConversion(Src.first, SrcTy, DstTy);
+    Src.second = EmitScalarConversion(Src.second, SrcTy, DstTy);
+    return Builder.CreateOr(Src.first, Src.second, "tobool");
+  }
+
+  // C99 6.3.1.7p2: "When a value of complex type is converted to a real type,
+  // the imaginary part of the complex value is discarded and the value of the
+  // real part is converted according to the conversion rules for the
+  // corresponding real type.
+  return EmitScalarConversion(Src.first, SrcTy, DstTy);
+}
+
+
+//===----------------------------------------------------------------------===//
+//                            Visitor Methods
+//===----------------------------------------------------------------------===//
+
+Value *ScalarExprEmitter::VisitExpr(Expr *E) {
+  CGF.ErrorUnsupported(E, "scalar expression");
+  if (E->getType()->isVoidType())
+    return 0;
+  return llvm::UndefValue::get(CGF.ConvertType(E->getType()));
+}
+
+Value *ScalarExprEmitter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
+  llvm::SmallVector<llvm::Constant*, 32> indices;
+  for (unsigned i = 2; i < E->getNumSubExprs(); i++) {
+    indices.push_back(cast<llvm::Constant>(CGF.EmitScalarExpr(E->getExpr(i))));
+  }
+  Value* V1 = CGF.EmitScalarExpr(E->getExpr(0));
+  Value* V2 = CGF.EmitScalarExpr(E->getExpr(1));
+  Value* SV = llvm::ConstantVector::get(indices.begin(), indices.size());
+  return Builder.CreateShuffleVector(V1, V2, SV, "shuffle");
+}
+Value *ScalarExprEmitter::VisitMemberExpr(MemberExpr *E) {
+  Expr::EvalResult Result;
+  if (E->Evaluate(Result, CGF.getContext()) && Result.Val.isInt()) {
+    if (E->isArrow())
+      CGF.EmitScalarExpr(E->getBase());
+    else
+      EmitLValue(E->getBase());
+    return llvm::ConstantInt::get(VMContext, Result.Val.getInt());
+  }
+  return EmitLoadOfLValue(E);
+}
+
+Value *ScalarExprEmitter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
+  TestAndClearIgnoreResultAssign();
+
+  // Emit subscript expressions in rvalue context's.  For most cases, this just
+  // loads the lvalue formed by the subscript expr.  However, we have to be
+  // careful, because the base of a vector subscript is occasionally an rvalue,
+  // so we can't get it as an lvalue.
+  if (!E->getBase()->getType()->isVectorType())
+    return EmitLoadOfLValue(E);
+
+  // Handle the vector case.  The base must be a vector, the index must be an
+  // integer value.
+  Value *Base = Visit(E->getBase());
+  Value *Idx  = Visit(E->getIdx());
+  bool IdxSigned = E->getIdx()->getType()->isSignedIntegerType();
+  Idx = Builder.CreateIntCast(Idx,
+                              llvm::Type::getInt32Ty(CGF.getLLVMContext()),
+                              IdxSigned,
+                              "vecidxcast");
+  return Builder.CreateExtractElement(Base, Idx, "vecext");
+}
+
+static llvm::Constant *getMaskElt(llvm::ShuffleVectorInst *SVI, unsigned Idx,
+                                  unsigned Off, const llvm::Type *I32Ty) {
+  int MV = SVI->getMaskValue(Idx);
+  if (MV == -1) 
+    return llvm::UndefValue::get(I32Ty);
+  return llvm::ConstantInt::get(I32Ty, Off+MV);
+}
+
+Value *ScalarExprEmitter::VisitInitListExpr(InitListExpr *E) {
+  bool Ignore = TestAndClearIgnoreResultAssign();
+  (void)Ignore;
+  assert (Ignore == false && "init list ignored");
+  unsigned NumInitElements = E->getNumInits();
+  
+  if (E->hadArrayRangeDesignator())
+    CGF.ErrorUnsupported(E, "GNU array range designator extension");
+  
+  const llvm::VectorType *VType =
+    dyn_cast<llvm::VectorType>(ConvertType(E->getType()));
+  
+  // We have a scalar in braces. Just use the first element.
+  if (!VType)
+    return Visit(E->getInit(0));
+  
+  unsigned ResElts = VType->getNumElements();
+  const llvm::Type *I32Ty = llvm::Type::getInt32Ty(CGF.getLLVMContext());
+  
+  // Loop over initializers collecting the Value for each, and remembering 
+  // whether the source was swizzle (ExtVectorElementExpr).  This will allow
+  // us to fold the shuffle for the swizzle into the shuffle for the vector
+  // initializer, since LLVM optimizers generally do not want to touch
+  // shuffles.
+  unsigned CurIdx = 0;
+  bool VIsUndefShuffle = false;
+  llvm::Value *V = llvm::UndefValue::get(VType);
+  for (unsigned i = 0; i != NumInitElements; ++i) {
+    Expr *IE = E->getInit(i);
+    Value *Init = Visit(IE);
+    llvm::SmallVector<llvm::Constant*, 16> Args;
+    
+    const llvm::VectorType *VVT = dyn_cast<llvm::VectorType>(Init->getType());
+    
+    // Handle scalar elements.  If the scalar initializer is actually one
+    // element of a different vector of the same width, use shuffle instead of 
+    // extract+insert.
+    if (!VVT) {
+      if (isa<ExtVectorElementExpr>(IE)) {
+        llvm::ExtractElementInst *EI = cast<llvm::ExtractElementInst>(Init);
+
+        if (EI->getVectorOperandType()->getNumElements() == ResElts) {
+          llvm::ConstantInt *C = cast<llvm::ConstantInt>(EI->getIndexOperand());
+          Value *LHS = 0, *RHS = 0;
+          if (CurIdx == 0) {
+            // insert into undef -> shuffle (src, undef)
+            Args.push_back(C);
+            for (unsigned j = 1; j != ResElts; ++j)
+              Args.push_back(llvm::UndefValue::get(I32Ty));
+
+            LHS = EI->getVectorOperand();
+            RHS = V;
+            VIsUndefShuffle = true;
+          } else if (VIsUndefShuffle) {
+            // insert into undefshuffle && size match -> shuffle (v, src)
+            llvm::ShuffleVectorInst *SVV = cast<llvm::ShuffleVectorInst>(V);
+            for (unsigned j = 0; j != CurIdx; ++j)
+              Args.push_back(getMaskElt(SVV, j, 0, I32Ty));
+            Args.push_back(llvm::ConstantInt::get(I32Ty, 
+                                                  ResElts + C->getZExtValue()));
+            for (unsigned j = CurIdx + 1; j != ResElts; ++j)
+              Args.push_back(llvm::UndefValue::get(I32Ty));
+            
+            LHS = cast<llvm::ShuffleVectorInst>(V)->getOperand(0);
+            RHS = EI->getVectorOperand();
+            VIsUndefShuffle = false;
+          }
+          if (!Args.empty()) {
+            llvm::Constant *Mask = llvm::ConstantVector::get(&Args[0], ResElts);
+            V = Builder.CreateShuffleVector(LHS, RHS, Mask);
+            ++CurIdx;
+            continue;
+          }
+        }
+      }
+      Value *Idx = llvm::ConstantInt::get(I32Ty, CurIdx);
+      V = Builder.CreateInsertElement(V, Init, Idx, "vecinit");
+      VIsUndefShuffle = false;
+      ++CurIdx;
+      continue;
+    }
+    
+    unsigned InitElts = VVT->getNumElements();
+
+    // If the initializer is an ExtVecEltExpr (a swizzle), and the swizzle's 
+    // input is the same width as the vector being constructed, generate an
+    // optimized shuffle of the swizzle input into the result.
+    unsigned Offset = (CurIdx == 0) ? 0 : ResElts;
+    if (isa<ExtVectorElementExpr>(IE)) {
+      llvm::ShuffleVectorInst *SVI = cast<llvm::ShuffleVectorInst>(Init);
+      Value *SVOp = SVI->getOperand(0);
+      const llvm::VectorType *OpTy = cast<llvm::VectorType>(SVOp->getType());
+      
+      if (OpTy->getNumElements() == ResElts) {
+        for (unsigned j = 0; j != CurIdx; ++j) {
+          // If the current vector initializer is a shuffle with undef, merge
+          // this shuffle directly into it.
+          if (VIsUndefShuffle) {
+            Args.push_back(getMaskElt(cast<llvm::ShuffleVectorInst>(V), j, 0,
+                                      I32Ty));
+          } else {
+            Args.push_back(llvm::ConstantInt::get(I32Ty, j));
+          }
+        }
+        for (unsigned j = 0, je = InitElts; j != je; ++j)
+          Args.push_back(getMaskElt(SVI, j, Offset, I32Ty));
+        for (unsigned j = CurIdx + InitElts; j != ResElts; ++j)
+          Args.push_back(llvm::UndefValue::get(I32Ty));
+
+        if (VIsUndefShuffle)
+          V = cast<llvm::ShuffleVectorInst>(V)->getOperand(0);
+
+        Init = SVOp;
+      }
+    }
+
+    // Extend init to result vector length, and then shuffle its contribution
+    // to the vector initializer into V.
+    if (Args.empty()) {
+      for (unsigned j = 0; j != InitElts; ++j)
+        Args.push_back(llvm::ConstantInt::get(I32Ty, j));
+      for (unsigned j = InitElts; j != ResElts; ++j)
+        Args.push_back(llvm::UndefValue::get(I32Ty));
+      llvm::Constant *Mask = llvm::ConstantVector::get(&Args[0], ResElts);
+      Init = Builder.CreateShuffleVector(Init, llvm::UndefValue::get(VVT),
+                                         Mask, "vext");
+
+      Args.clear();
+      for (unsigned j = 0; j != CurIdx; ++j)
+        Args.push_back(llvm::ConstantInt::get(I32Ty, j));
+      for (unsigned j = 0; j != InitElts; ++j)
+        Args.push_back(llvm::ConstantInt::get(I32Ty, j+Offset));
+      for (unsigned j = CurIdx + InitElts; j != ResElts; ++j)
+        Args.push_back(llvm::UndefValue::get(I32Ty));
+    }
+
+    // If V is undef, make sure it ends up on the RHS of the shuffle to aid
+    // merging subsequent shuffles into this one.
+    if (CurIdx == 0)
+      std::swap(V, Init);
+    llvm::Constant *Mask = llvm::ConstantVector::get(&Args[0], ResElts);
+    V = Builder.CreateShuffleVector(V, Init, Mask, "vecinit");
+    VIsUndefShuffle = isa<llvm::UndefValue>(Init);
+    CurIdx += InitElts;
+  }
+  
+  // FIXME: evaluate codegen vs. shuffling against constant null vector.
+  // Emit remaining default initializers.
+  const llvm::Type *EltTy = VType->getElementType();
+  
+  // Emit remaining default initializers
+  for (/* Do not initialize i*/; CurIdx < ResElts; ++CurIdx) {
+    Value *Idx = llvm::ConstantInt::get(I32Ty, CurIdx);
+    llvm::Value *Init = llvm::Constant::getNullValue(EltTy);
+    V = Builder.CreateInsertElement(V, Init, Idx, "vecinit");
+  }
+  return V;
+}
+
+static bool ShouldNullCheckClassCastValue(const CastExpr *CE) {
+  const Expr *E = CE->getSubExpr();
+
+  if (CE->getCastKind() == CastExpr::CK_UncheckedDerivedToBase)
+    return false;
+  
+  if (isa<CXXThisExpr>(E)) {
+    // We always assume that 'this' is never null.
+    return false;
+  }
+  
+  if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(CE)) {
+    // And that lvalue casts are never null.
+    if (ICE->isLvalueCast())
+      return false;
+  }
+
+  return true;
+}
+
+// VisitCastExpr - Emit code for an explicit or implicit cast.  Implicit casts
+// have to handle a more broad range of conversions than explicit casts, as they
+// handle things like function to ptr-to-function decay etc.
+Value *ScalarExprEmitter::EmitCastExpr(CastExpr *CE) {
+  Expr *E = CE->getSubExpr();
+  QualType DestTy = CE->getType();
+  CastExpr::CastKind Kind = CE->getCastKind();
+  
+  if (!DestTy->isVoidType())
+    TestAndClearIgnoreResultAssign();
+
+  // Since almost all cast kinds apply to scalars, this switch doesn't have
+  // a default case, so the compiler will warn on a missing case.  The cases
+  // are in the same order as in the CastKind enum.
+  switch (Kind) {
+  case CastExpr::CK_Unknown:
+    // FIXME: All casts should have a known kind!
+    //assert(0 && "Unknown cast kind!");
+    break;
+
+  case CastExpr::CK_AnyPointerToObjCPointerCast:
+  case CastExpr::CK_AnyPointerToBlockPointerCast:
+  case CastExpr::CK_BitCast: {
+    Value *Src = Visit(const_cast<Expr*>(E));
+    return Builder.CreateBitCast(Src, ConvertType(DestTy));
+  }
+  case CastExpr::CK_NoOp:
+  case CastExpr::CK_UserDefinedConversion:
+    return Visit(const_cast<Expr*>(E));
+
+  case CastExpr::CK_BaseToDerived: {
+    const CXXRecordDecl *DerivedClassDecl = 
+      DestTy->getCXXRecordDeclForPointerType();
+    
+    return CGF.GetAddressOfDerivedClass(Visit(E), DerivedClassDecl, 
+                                        CE->getBasePath(), 
+                                        ShouldNullCheckClassCastValue(CE));
+  }
+  case CastExpr::CK_UncheckedDerivedToBase:
+  case CastExpr::CK_DerivedToBase: {
+    const RecordType *DerivedClassTy = 
+      E->getType()->getAs<PointerType>()->getPointeeType()->getAs<RecordType>();
+    CXXRecordDecl *DerivedClassDecl = 
+      cast<CXXRecordDecl>(DerivedClassTy->getDecl());
+
+    return CGF.GetAddressOfBaseClass(Visit(E), DerivedClassDecl, 
+                                     CE->getBasePath(),
+                                     ShouldNullCheckClassCastValue(CE));
+  }
+  case CastExpr::CK_Dynamic: {
+    Value *V = Visit(const_cast<Expr*>(E));
+    const CXXDynamicCastExpr *DCE = cast<CXXDynamicCastExpr>(CE);
+    return CGF.EmitDynamicCast(V, DCE);
+  }
+  case CastExpr::CK_ToUnion:
+    assert(0 && "Should be unreachable!");
+    break;
+
+  case CastExpr::CK_ArrayToPointerDecay: {
+    assert(E->getType()->isArrayType() &&
+           "Array to pointer decay must have array source type!");
+
+    Value *V = EmitLValue(E).getAddress();  // Bitfields can't be arrays.
+
+    // Note that VLA pointers are always decayed, so we don't need to do
+    // anything here.
+    if (!E->getType()->isVariableArrayType()) {
+      assert(isa<llvm::PointerType>(V->getType()) && "Expected pointer");
+      assert(isa<llvm::ArrayType>(cast<llvm::PointerType>(V->getType())
+                                 ->getElementType()) &&
+             "Expected pointer to array");
+      V = Builder.CreateStructGEP(V, 0, "arraydecay");
+    }
+
+    return V;
+  }
+  case CastExpr::CK_FunctionToPointerDecay:
+    return EmitLValue(E).getAddress();
+
+  case CastExpr::CK_NullToMemberPointer:
+    return CGF.CGM.EmitNullConstant(DestTy);
+
+  case CastExpr::CK_BaseToDerivedMemberPointer:
+  case CastExpr::CK_DerivedToBaseMemberPointer: {
+    Value *Src = Visit(E);
+
+    // See if we need to adjust the pointer.
+    const CXXRecordDecl *BaseDecl = 
+      cast<CXXRecordDecl>(E->getType()->getAs<MemberPointerType>()->
+                          getClass()->getAs<RecordType>()->getDecl());
+    const CXXRecordDecl *DerivedDecl = 
+      cast<CXXRecordDecl>(CE->getType()->getAs<MemberPointerType>()->
+                          getClass()->getAs<RecordType>()->getDecl());
+    if (CE->getCastKind() == CastExpr::CK_DerivedToBaseMemberPointer)
+      std::swap(DerivedDecl, BaseDecl);
+
+    if (llvm::Constant *Adj = 
+          CGF.CGM.GetNonVirtualBaseClassOffset(DerivedDecl, 
+                                               CE->getBasePath())) {
+      if (CE->getCastKind() == CastExpr::CK_DerivedToBaseMemberPointer)
+        Src = Builder.CreateSub(Src, Adj, "adj");
+      else
+        Src = Builder.CreateAdd(Src, Adj, "adj");
+    }
+    return Src;
+  }
+
+  case CastExpr::CK_ConstructorConversion:
+    assert(0 && "Should be unreachable!");
+    break;
+
+  case CastExpr::CK_IntegralToPointer: {
+    Value *Src = Visit(const_cast<Expr*>(E));
+    
+    // First, convert to the correct width so that we control the kind of
+    // extension.
+    const llvm::Type *MiddleTy =
+      llvm::IntegerType::get(VMContext, CGF.LLVMPointerWidth);
+    bool InputSigned = E->getType()->isSignedIntegerType();
+    llvm::Value* IntResult =
+      Builder.CreateIntCast(Src, MiddleTy, InputSigned, "conv");
+    
+    return Builder.CreateIntToPtr(IntResult, ConvertType(DestTy));
+  }
+  case CastExpr::CK_PointerToIntegral: {
+    Value *Src = Visit(const_cast<Expr*>(E));
+    return Builder.CreatePtrToInt(Src, ConvertType(DestTy));
+  }
+  case CastExpr::CK_ToVoid: {
+    CGF.EmitAnyExpr(E, 0, false, true);
+    return 0;
+  }
+  case CastExpr::CK_VectorSplat: {
+    const llvm::Type *DstTy = ConvertType(DestTy);
+    Value *Elt = Visit(const_cast<Expr*>(E));
+
+    // Insert the element in element zero of an undef vector
+    llvm::Value *UnV = llvm::UndefValue::get(DstTy);
+    llvm::Value *Idx =
+        llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 0);
+    UnV = Builder.CreateInsertElement(UnV, Elt, Idx, "tmp");
+
+    // Splat the element across to all elements
+    llvm::SmallVector<llvm::Constant*, 16> Args;
+    unsigned NumElements = cast<llvm::VectorType>(DstTy)->getNumElements();
+    for (unsigned i = 0; i < NumElements; i++)
+      Args.push_back(llvm::ConstantInt::get(
+                                        llvm::Type::getInt32Ty(VMContext), 0));
+
+    llvm::Constant *Mask = llvm::ConstantVector::get(&Args[0], NumElements);
+    llvm::Value *Yay = Builder.CreateShuffleVector(UnV, UnV, Mask, "splat");
+    return Yay;
+  }
+  case CastExpr::CK_IntegralCast:
+  case CastExpr::CK_IntegralToFloating:
+  case CastExpr::CK_FloatingToIntegral:
+  case CastExpr::CK_FloatingCast:
+    return EmitScalarConversion(Visit(E), E->getType(), DestTy);
+
+  case CastExpr::CK_MemberPointerToBoolean:
+    return CGF.EvaluateExprAsBool(E);
+  }
+
+  // Handle cases where the source is an non-complex type.
+
+  if (!CGF.hasAggregateLLVMType(E->getType())) {
+    Value *Src = Visit(const_cast<Expr*>(E));
+
+    // Use EmitScalarConversion to perform the conversion.
+    return EmitScalarConversion(Src, E->getType(), DestTy);
+  }
+
+  if (E->getType()->isAnyComplexType()) {
+    // Handle cases where the source is a complex type.
+    bool IgnoreImag = true;
+    bool IgnoreImagAssign = true;
+    bool IgnoreReal = IgnoreResultAssign;
+    bool IgnoreRealAssign = IgnoreResultAssign;
+    if (DestTy->isBooleanType())
+      IgnoreImagAssign = IgnoreImag = false;
+    else if (DestTy->isVoidType()) {
+      IgnoreReal = IgnoreImag = false;
+      IgnoreRealAssign = IgnoreImagAssign = true;
+    }
+    CodeGenFunction::ComplexPairTy V
+      = CGF.EmitComplexExpr(E, IgnoreReal, IgnoreImag, IgnoreRealAssign,
+                            IgnoreImagAssign);
+    return EmitComplexToScalarConversion(V, E->getType(), DestTy);
+  }
+
+  // Okay, this is a cast from an aggregate.  It must be a cast to void.  Just
+  // evaluate the result and return.
+  CGF.EmitAggExpr(E, 0, false, true);
+  return 0;
+}
+
+Value *ScalarExprEmitter::VisitStmtExpr(const StmtExpr *E) {
+  return CGF.EmitCompoundStmt(*E->getSubStmt(),
+                              !E->getType()->isVoidType()).getScalarVal();
+}
+
+Value *ScalarExprEmitter::VisitBlockDeclRefExpr(const BlockDeclRefExpr *E) {
+  llvm::Value *V = CGF.GetAddrOfBlockDecl(E);
+  if (E->getType().isObjCGCWeak())
+    return CGF.CGM.getObjCRuntime().EmitObjCWeakRead(CGF, V);
+  return Builder.CreateLoad(V, "tmp");
+}
+
+//===----------------------------------------------------------------------===//
+//                             Unary Operators
+//===----------------------------------------------------------------------===//
+
+Value *ScalarExprEmitter::VisitUnaryMinus(const UnaryOperator *E) {
+  TestAndClearIgnoreResultAssign();
+  Value *Op = Visit(E->getSubExpr());
+  if (Op->getType()->isFPOrFPVectorTy())
+    return Builder.CreateFNeg(Op, "neg");
+  return Builder.CreateNeg(Op, "neg");
+}
+
+Value *ScalarExprEmitter::VisitUnaryNot(const UnaryOperator *E) {
+  TestAndClearIgnoreResultAssign();
+  Value *Op = Visit(E->getSubExpr());
+  return Builder.CreateNot(Op, "neg");
+}
+
+Value *ScalarExprEmitter::VisitUnaryLNot(const UnaryOperator *E) {
+  // Compare operand to zero.
+  Value *BoolVal = CGF.EvaluateExprAsBool(E->getSubExpr());
+
+  // Invert value.
+  // TODO: Could dynamically modify easy computations here.  For example, if
+  // the operand is an icmp ne, turn into icmp eq.
+  BoolVal = Builder.CreateNot(BoolVal, "lnot");
+
+  // ZExt result to the expr type.
+  return Builder.CreateZExt(BoolVal, ConvertType(E->getType()), "lnot.ext");
+}
+
+/// VisitSizeOfAlignOfExpr - Return the size or alignment of the type of
+/// argument of the sizeof expression as an integer.
+Value *
+ScalarExprEmitter::VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr *E) {
+  QualType TypeToSize = E->getTypeOfArgument();
+  if (E->isSizeOf()) {
+    if (const VariableArrayType *VAT =
+          CGF.getContext().getAsVariableArrayType(TypeToSize)) {
+      if (E->isArgumentType()) {
+        // sizeof(type) - make sure to emit the VLA size.
+        CGF.EmitVLASize(TypeToSize);
+      } else {
+        // C99 6.5.3.4p2: If the argument is an expression of type
+        // VLA, it is evaluated.
+        CGF.EmitAnyExpr(E->getArgumentExpr());
+      }
+
+      return CGF.GetVLASize(VAT);
+    }
+  }
+
+  // If this isn't sizeof(vla), the result must be constant; use the constant
+  // folding logic so we don't have to duplicate it here.
+  Expr::EvalResult Result;
+  E->Evaluate(Result, CGF.getContext());
+  return llvm::ConstantInt::get(VMContext, Result.Val.getInt());
+}
+
+Value *ScalarExprEmitter::VisitUnaryReal(const UnaryOperator *E) {
+  Expr *Op = E->getSubExpr();
+  if (Op->getType()->isAnyComplexType())
+    return CGF.EmitComplexExpr(Op, false, true, false, true).first;
+  return Visit(Op);
+}
+Value *ScalarExprEmitter::VisitUnaryImag(const UnaryOperator *E) {
+  Expr *Op = E->getSubExpr();
+  if (Op->getType()->isAnyComplexType())
+    return CGF.EmitComplexExpr(Op, true, false, true, false).second;
+
+  // __imag on a scalar returns zero.  Emit the subexpr to ensure side
+  // effects are evaluated, but not the actual value.
+  if (E->isLvalue(CGF.getContext()) == Expr::LV_Valid)
+    CGF.EmitLValue(Op);
+  else
+    CGF.EmitScalarExpr(Op, true);
+  return llvm::Constant::getNullValue(ConvertType(E->getType()));
+}
+
+Value *ScalarExprEmitter::VisitUnaryOffsetOf(const UnaryOperator *E) {
+  Value* ResultAsPtr = EmitLValue(E->getSubExpr()).getAddress();
+  const llvm::Type* ResultType = ConvertType(E->getType());
+  return Builder.CreatePtrToInt(ResultAsPtr, ResultType, "offsetof");
+}
+
+//===----------------------------------------------------------------------===//
+//                           Binary Operators
+//===----------------------------------------------------------------------===//
+
+BinOpInfo ScalarExprEmitter::EmitBinOps(const BinaryOperator *E) {
+  TestAndClearIgnoreResultAssign();
+  BinOpInfo Result;
+  Result.LHS = Visit(E->getLHS());
+  Result.RHS = Visit(E->getRHS());
+  Result.Ty  = E->getType();
+  Result.E = E;
+  return Result;
+}
+
+LValue ScalarExprEmitter::EmitCompoundAssignLValue(
+                                              const CompoundAssignOperator *E,
+                        Value *(ScalarExprEmitter::*Func)(const BinOpInfo &),
+                                                   Value *&BitFieldResult) {
+  QualType LHSTy = E->getLHS()->getType();
+  BitFieldResult = 0;
+  BinOpInfo OpInfo;
+  
+  if (E->getComputationResultType()->isAnyComplexType()) {
+    // This needs to go through the complex expression emitter, but it's a tad
+    // complicated to do that... I'm leaving it out for now.  (Note that we do
+    // actually need the imaginary part of the RHS for multiplication and
+    // division.)
+    CGF.ErrorUnsupported(E, "complex compound assignment");
+    llvm::UndefValue::get(CGF.ConvertType(E->getType()));
+    return LValue();
+  }
+  
+  // Emit the RHS first.  __block variables need to have the rhs evaluated
+  // first, plus this should improve codegen a little.
+  OpInfo.RHS = Visit(E->getRHS());
+  OpInfo.Ty = E->getComputationResultType();
+  OpInfo.E = E;
+  // Load/convert the LHS.
+  LValue LHSLV = EmitCheckedLValue(E->getLHS());
+  OpInfo.LHS = EmitLoadOfLValue(LHSLV, LHSTy);
+  OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy,
+                                    E->getComputationLHSType());
+  
+  // Expand the binary operator.
+  Value *Result = (this->*Func)(OpInfo);
+  
+  // Convert the result back to the LHS type.
+  Result = EmitScalarConversion(Result, E->getComputationResultType(), LHSTy);
+  
+  // Store the result value into the LHS lvalue. Bit-fields are handled
+  // specially because the result is altered by the store, i.e., [C99 6.5.16p1]
+  // 'An assignment expression has the value of the left operand after the
+  // assignment...'.
+  if (LHSLV.isBitField()) {
+    if (!LHSLV.isVolatileQualified()) {
+      CGF.EmitStoreThroughBitfieldLValue(RValue::get(Result), LHSLV, LHSTy,
+                                         &Result);
+      BitFieldResult = Result;
+      return LHSLV;
+    } else
+      CGF.EmitStoreThroughBitfieldLValue(RValue::get(Result), LHSLV, LHSTy);
+  } else
+    CGF.EmitStoreThroughLValue(RValue::get(Result), LHSLV, LHSTy);
+  return LHSLV;
+}
+
+Value *ScalarExprEmitter::EmitCompoundAssign(const CompoundAssignOperator *E,
+                      Value *(ScalarExprEmitter::*Func)(const BinOpInfo &)) {
+  bool Ignore = TestAndClearIgnoreResultAssign();
+  Value *BitFieldResult;
+  LValue LHSLV = EmitCompoundAssignLValue(E, Func, BitFieldResult);
+  if (BitFieldResult)
+    return BitFieldResult;
+  
+  if (Ignore)
+    return 0;
+  return EmitLoadOfLValue(LHSLV, E->getType());
+}
+
+
+Value *ScalarExprEmitter::EmitDiv(const BinOpInfo &Ops) {
+  if (Ops.LHS->getType()->isFPOrFPVectorTy())
+    return Builder.CreateFDiv(Ops.LHS, Ops.RHS, "div");
+  else if (Ops.Ty->isUnsignedIntegerType())
+    return Builder.CreateUDiv(Ops.LHS, Ops.RHS, "div");
+  else
+    return Builder.CreateSDiv(Ops.LHS, Ops.RHS, "div");
+}
+
+Value *ScalarExprEmitter::EmitRem(const BinOpInfo &Ops) {
+  // Rem in C can't be a floating point type: C99 6.5.5p2.
+  if (Ops.Ty->isUnsignedIntegerType())
+    return Builder.CreateURem(Ops.LHS, Ops.RHS, "rem");
+  else
+    return Builder.CreateSRem(Ops.LHS, Ops.RHS, "rem");
+}
+
+Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(const BinOpInfo &Ops) {
+  unsigned IID;
+  unsigned OpID = 0;
+
+  switch (Ops.E->getOpcode()) {
+  case BinaryOperator::Add:
+  case BinaryOperator::AddAssign:
+    OpID = 1;
+    IID = llvm::Intrinsic::sadd_with_overflow;
+    break;
+  case BinaryOperator::Sub:
+  case BinaryOperator::SubAssign:
+    OpID = 2;
+    IID = llvm::Intrinsic::ssub_with_overflow;
+    break;
+  case BinaryOperator::Mul:
+  case BinaryOperator::MulAssign:
+    OpID = 3;
+    IID = llvm::Intrinsic::smul_with_overflow;
+    break;
+  default:
+    assert(false && "Unsupported operation for overflow detection");
+    IID = 0;
+  }
+  OpID <<= 1;
+  OpID |= 1;
+
+  const llvm::Type *opTy = CGF.CGM.getTypes().ConvertType(Ops.Ty);
+
+  llvm::Function *intrinsic = CGF.CGM.getIntrinsic(IID, &opTy, 1);
+
+  Value *resultAndOverflow = Builder.CreateCall2(intrinsic, Ops.LHS, Ops.RHS);
+  Value *result = Builder.CreateExtractValue(resultAndOverflow, 0);
+  Value *overflow = Builder.CreateExtractValue(resultAndOverflow, 1);
+
+  // Branch in case of overflow.
+  llvm::BasicBlock *initialBB = Builder.GetInsertBlock();
+  llvm::BasicBlock *overflowBB =
+    CGF.createBasicBlock("overflow", CGF.CurFn);
+  llvm::BasicBlock *continueBB =
+    CGF.createBasicBlock("overflow.continue", CGF.CurFn);
+
+  Builder.CreateCondBr(overflow, overflowBB, continueBB);
+
+  // Handle overflow
+
+  Builder.SetInsertPoint(overflowBB);
+
+  // Handler is:
+  // long long *__overflow_handler)(long long a, long long b, char op,
+  // char width)
+  std::vector<const llvm::Type*> handerArgTypes;
+  handerArgTypes.push_back(llvm::Type::getInt64Ty(VMContext));
+  handerArgTypes.push_back(llvm::Type::getInt64Ty(VMContext));
+  handerArgTypes.push_back(llvm::Type::getInt8Ty(VMContext));
+  handerArgTypes.push_back(llvm::Type::getInt8Ty(VMContext));
+  llvm::FunctionType *handlerTy = llvm::FunctionType::get(
+      llvm::Type::getInt64Ty(VMContext), handerArgTypes, false);
+  llvm::Value *handlerFunction =
+    CGF.CGM.getModule().getOrInsertGlobal("__overflow_handler",
+        llvm::PointerType::getUnqual(handlerTy));
+  handlerFunction = Builder.CreateLoad(handlerFunction);
+
+  llvm::Value *handlerResult = Builder.CreateCall4(handlerFunction,
+      Builder.CreateSExt(Ops.LHS, llvm::Type::getInt64Ty(VMContext)),
+      Builder.CreateSExt(Ops.RHS, llvm::Type::getInt64Ty(VMContext)),
+      llvm::ConstantInt::get(llvm::Type::getInt8Ty(VMContext), OpID),
+      llvm::ConstantInt::get(llvm::Type::getInt8Ty(VMContext),
+        cast<llvm::IntegerType>(opTy)->getBitWidth()));
+
+  handlerResult = Builder.CreateTrunc(handlerResult, opTy);
+
+  Builder.CreateBr(continueBB);
+
+  // Set up the continuation
+  Builder.SetInsertPoint(continueBB);
+  // Get the correct result
+  llvm::PHINode *phi = Builder.CreatePHI(opTy);
+  phi->reserveOperandSpace(2);
+  phi->addIncoming(result, initialBB);
+  phi->addIncoming(handlerResult, overflowBB);
+
+  return phi;
+}
+
+Value *ScalarExprEmitter::EmitAdd(const BinOpInfo &Ops) {
+  if (!Ops.Ty->isAnyPointerType()) {
+    if (CGF.getContext().getLangOptions().OverflowChecking &&
+        Ops.Ty->isSignedIntegerType())
+      return EmitOverflowCheckedBinOp(Ops);
+
+    if (Ops.LHS->getType()->isFPOrFPVectorTy())
+      return Builder.CreateFAdd(Ops.LHS, Ops.RHS, "add");
+
+    // Signed integer overflow is undefined behavior.
+    if (Ops.Ty->isSignedIntegerType())
+      return Builder.CreateNSWAdd(Ops.LHS, Ops.RHS, "add");
+
+    return Builder.CreateAdd(Ops.LHS, Ops.RHS, "add");
+  }
+
+  if (Ops.Ty->isPointerType() &&
+      Ops.Ty->getAs<PointerType>()->isVariableArrayType()) {
+    // The amount of the addition needs to account for the VLA size
+    CGF.ErrorUnsupported(Ops.E, "VLA pointer addition");
+  }
+  Value *Ptr, *Idx;
+  Expr *IdxExp;
+  const PointerType *PT = Ops.E->getLHS()->getType()->getAs<PointerType>();
+  const ObjCObjectPointerType *OPT =
+    Ops.E->getLHS()->getType()->getAs<ObjCObjectPointerType>();
+  if (PT || OPT) {
+    Ptr = Ops.LHS;
+    Idx = Ops.RHS;
+    IdxExp = Ops.E->getRHS();
+  } else {  // int + pointer
+    PT = Ops.E->getRHS()->getType()->getAs<PointerType>();
+    OPT = Ops.E->getRHS()->getType()->getAs<ObjCObjectPointerType>();
+    assert((PT || OPT) && "Invalid add expr");
+    Ptr = Ops.RHS;
+    Idx = Ops.LHS;
+    IdxExp = Ops.E->getLHS();
+  }
+
+  unsigned Width = cast<llvm::IntegerType>(Idx->getType())->getBitWidth();
+  if (Width < CGF.LLVMPointerWidth) {
+    // Zero or sign extend the pointer value based on whether the index is
+    // signed or not.
+    const llvm::Type *IdxType =
+        llvm::IntegerType::get(VMContext, CGF.LLVMPointerWidth);
+    if (IdxExp->getType()->isSignedIntegerType())
+      Idx = Builder.CreateSExt(Idx, IdxType, "idx.ext");
+    else
+      Idx = Builder.CreateZExt(Idx, IdxType, "idx.ext");
+  }
+  const QualType ElementType = PT ? PT->getPointeeType() : OPT->getPointeeType();
+  // Handle interface types, which are not represented with a concrete type.
+  if (const ObjCInterfaceType *OIT = dyn_cast<ObjCInterfaceType>(ElementType)) {
+    llvm::Value *InterfaceSize =
+      llvm::ConstantInt::get(Idx->getType(),
+          CGF.getContext().getTypeSizeInChars(OIT).getQuantity());
+    Idx = Builder.CreateMul(Idx, InterfaceSize);
+    const llvm::Type *i8Ty = llvm::Type::getInt8PtrTy(VMContext);
+    Value *Casted = Builder.CreateBitCast(Ptr, i8Ty);
+    Value *Res = Builder.CreateGEP(Casted, Idx, "add.ptr");
+    return Builder.CreateBitCast(Res, Ptr->getType());
+  }
+
+  // Explicitly handle GNU void* and function pointer arithmetic extensions. The
+  // GNU void* casts amount to no-ops since our void* type is i8*, but this is
+  // future proof.
+  if (ElementType->isVoidType() || ElementType->isFunctionType()) {
+    const llvm::Type *i8Ty = llvm::Type::getInt8PtrTy(VMContext);
+    Value *Casted = Builder.CreateBitCast(Ptr, i8Ty);
+    Value *Res = Builder.CreateGEP(Casted, Idx, "add.ptr");
+    return Builder.CreateBitCast(Res, Ptr->getType());
+  }
+
+  return Builder.CreateInBoundsGEP(Ptr, Idx, "add.ptr");
+}
+
+Value *ScalarExprEmitter::EmitSub(const BinOpInfo &Ops) {
+  if (!isa<llvm::PointerType>(Ops.LHS->getType())) {
+    if (CGF.getContext().getLangOptions().OverflowChecking
+        && Ops.Ty->isSignedIntegerType())
+      return EmitOverflowCheckedBinOp(Ops);
+
+    if (Ops.LHS->getType()->isFPOrFPVectorTy())
+      return Builder.CreateFSub(Ops.LHS, Ops.RHS, "sub");
+
+    // Signed integer overflow is undefined behavior.
+    if (Ops.Ty->isSignedIntegerType())
+      return Builder.CreateNSWSub(Ops.LHS, Ops.RHS, "sub");
+
+    return Builder.CreateSub(Ops.LHS, Ops.RHS, "sub");
+  }
+
+  if (Ops.E->getLHS()->getType()->isPointerType() &&
+      Ops.E->getLHS()->getType()->getAs<PointerType>()->isVariableArrayType()) {
+    // The amount of the addition needs to account for the VLA size for
+    // ptr-int
+    // The amount of the division needs to account for the VLA size for
+    // ptr-ptr.
+    CGF.ErrorUnsupported(Ops.E, "VLA pointer subtraction");
+  }
+
+  const QualType LHSType = Ops.E->getLHS()->getType();
+  const QualType LHSElementType = LHSType->getPointeeType();
+  if (!isa<llvm::PointerType>(Ops.RHS->getType())) {
+    // pointer - int
+    Value *Idx = Ops.RHS;
+    unsigned Width = cast<llvm::IntegerType>(Idx->getType())->getBitWidth();
+    if (Width < CGF.LLVMPointerWidth) {
+      // Zero or sign extend the pointer value based on whether the index is
+      // signed or not.
+      const llvm::Type *IdxType =
+          llvm::IntegerType::get(VMContext, CGF.LLVMPointerWidth);
+      if (Ops.E->getRHS()->getType()->isSignedIntegerType())
+        Idx = Builder.CreateSExt(Idx, IdxType, "idx.ext");
+      else
+        Idx = Builder.CreateZExt(Idx, IdxType, "idx.ext");
+    }
+    Idx = Builder.CreateNeg(Idx, "sub.ptr.neg");
+
+    // Handle interface types, which are not represented with a concrete type.
+    if (const ObjCInterfaceType *OIT =
+        dyn_cast<ObjCInterfaceType>(LHSElementType)) {
+      llvm::Value *InterfaceSize =
+        llvm::ConstantInt::get(Idx->getType(),
+                               CGF.getContext().
+                                 getTypeSizeInChars(OIT).getQuantity());
+      Idx = Builder.CreateMul(Idx, InterfaceSize);
+      const llvm::Type *i8Ty = llvm::Type::getInt8PtrTy(VMContext);
+      Value *LHSCasted = Builder.CreateBitCast(Ops.LHS, i8Ty);
+      Value *Res = Builder.CreateGEP(LHSCasted, Idx, "add.ptr");
+      return Builder.CreateBitCast(Res, Ops.LHS->getType());
+    }
+
+    // Explicitly handle GNU void* and function pointer arithmetic
+    // extensions. The GNU void* casts amount to no-ops since our void* type is
+    // i8*, but this is future proof.
+    if (LHSElementType->isVoidType() || LHSElementType->isFunctionType()) {
+      const llvm::Type *i8Ty = llvm::Type::getInt8PtrTy(VMContext);
+      Value *LHSCasted = Builder.CreateBitCast(Ops.LHS, i8Ty);
+      Value *Res = Builder.CreateGEP(LHSCasted, Idx, "sub.ptr");
+      return Builder.CreateBitCast(Res, Ops.LHS->getType());
+    }
+
+    return Builder.CreateInBoundsGEP(Ops.LHS, Idx, "sub.ptr");
+  } else {
+    // pointer - pointer
+    Value *LHS = Ops.LHS;
+    Value *RHS = Ops.RHS;
+
+    CharUnits ElementSize;
+
+    // Handle GCC extension for pointer arithmetic on void* and function pointer
+    // types.
+    if (LHSElementType->isVoidType() || LHSElementType->isFunctionType()) {
+      ElementSize = CharUnits::One();
+    } else {
+      ElementSize = CGF.getContext().getTypeSizeInChars(LHSElementType);
+    }
+
+    const llvm::Type *ResultType = ConvertType(Ops.Ty);
+    LHS = Builder.CreatePtrToInt(LHS, ResultType, "sub.ptr.lhs.cast");
+    RHS = Builder.CreatePtrToInt(RHS, ResultType, "sub.ptr.rhs.cast");
+    Value *BytesBetween = Builder.CreateSub(LHS, RHS, "sub.ptr.sub");
+
+    // Optimize out the shift for element size of 1.
+    if (ElementSize.isOne())
+      return BytesBetween;
+
+    // Otherwise, do a full sdiv. This uses the "exact" form of sdiv, since
+    // pointer difference in C is only defined in the case where both operands
+    // are pointing to elements of an array.
+    Value *BytesPerElt = 
+        llvm::ConstantInt::get(ResultType, ElementSize.getQuantity());
+    return Builder.CreateExactSDiv(BytesBetween, BytesPerElt, "sub.ptr.div");
+  }
+}
+
+Value *ScalarExprEmitter::EmitShl(const BinOpInfo &Ops) {
+  // LLVM requires the LHS and RHS to be the same type: promote or truncate the
+  // RHS to the same size as the LHS.
+  Value *RHS = Ops.RHS;
+  if (Ops.LHS->getType() != RHS->getType())
+    RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(), false, "sh_prom");
+
+  if (CGF.CatchUndefined 
+      && isa<llvm::IntegerType>(Ops.LHS->getType())) {
+    unsigned Width = cast<llvm::IntegerType>(Ops.LHS->getType())->getBitWidth();
+    llvm::BasicBlock *Cont = CGF.createBasicBlock("cont");
+    CGF.Builder.CreateCondBr(Builder.CreateICmpULT(RHS,
+                                 llvm::ConstantInt::get(RHS->getType(), Width)),
+                             Cont, CGF.getTrapBB());
+    CGF.EmitBlock(Cont);
+  }
+
+  return Builder.CreateShl(Ops.LHS, RHS, "shl");
+}
+
+Value *ScalarExprEmitter::EmitShr(const BinOpInfo &Ops) {
+  // LLVM requires the LHS and RHS to be the same type: promote or truncate the
+  // RHS to the same size as the LHS.
+  Value *RHS = Ops.RHS;
+  if (Ops.LHS->getType() != RHS->getType())
+    RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(), false, "sh_prom");
+
+  if (CGF.CatchUndefined 
+      && isa<llvm::IntegerType>(Ops.LHS->getType())) {
+    unsigned Width = cast<llvm::IntegerType>(Ops.LHS->getType())->getBitWidth();
+    llvm::BasicBlock *Cont = CGF.createBasicBlock("cont");
+    CGF.Builder.CreateCondBr(Builder.CreateICmpULT(RHS,
+                                 llvm::ConstantInt::get(RHS->getType(), Width)),
+                             Cont, CGF.getTrapBB());
+    CGF.EmitBlock(Cont);
+  }
+
+  if (Ops.Ty->isUnsignedIntegerType())
+    return Builder.CreateLShr(Ops.LHS, RHS, "shr");
+  return Builder.CreateAShr(Ops.LHS, RHS, "shr");
+}
+
+Value *ScalarExprEmitter::EmitCompare(const BinaryOperator *E,unsigned UICmpOpc,
+                                      unsigned SICmpOpc, unsigned FCmpOpc) {
+  TestAndClearIgnoreResultAssign();
+  Value *Result;
+  QualType LHSTy = E->getLHS()->getType();
+  if (LHSTy->isMemberFunctionPointerType()) {
+    Value *LHSPtr = CGF.EmitAnyExprToTemp(E->getLHS()).getAggregateAddr();
+    Value *RHSPtr = CGF.EmitAnyExprToTemp(E->getRHS()).getAggregateAddr();
+    llvm::Value *LHSFunc = Builder.CreateStructGEP(LHSPtr, 0);
+    LHSFunc = Builder.CreateLoad(LHSFunc);
+    llvm::Value *RHSFunc = Builder.CreateStructGEP(RHSPtr, 0);
+    RHSFunc = Builder.CreateLoad(RHSFunc);
+    Value *ResultF = Builder.CreateICmp((llvm::ICmpInst::Predicate)UICmpOpc,
+                                        LHSFunc, RHSFunc, "cmp.func");
+    Value *NullPtr = llvm::Constant::getNullValue(LHSFunc->getType());
+    Value *ResultNull = Builder.CreateICmp((llvm::ICmpInst::Predicate)UICmpOpc,
+                                           LHSFunc, NullPtr, "cmp.null");
+    llvm::Value *LHSAdj = Builder.CreateStructGEP(LHSPtr, 1);
+    LHSAdj = Builder.CreateLoad(LHSAdj);
+    llvm::Value *RHSAdj = Builder.CreateStructGEP(RHSPtr, 1);
+    RHSAdj = Builder.CreateLoad(RHSAdj);
+    Value *ResultA = Builder.CreateICmp((llvm::ICmpInst::Predicate)UICmpOpc,
+                                        LHSAdj, RHSAdj, "cmp.adj");
+    if (E->getOpcode() == BinaryOperator::EQ) {
+      Result = Builder.CreateOr(ResultNull, ResultA, "or.na");
+      Result = Builder.CreateAnd(Result, ResultF, "and.f");
+    } else {
+      assert(E->getOpcode() == BinaryOperator::NE &&
+             "Member pointer comparison other than == or != ?");
+      Result = Builder.CreateAnd(ResultNull, ResultA, "and.na");
+      Result = Builder.CreateOr(Result, ResultF, "or.f");
+    }
+  } else if (!LHSTy->isAnyComplexType()) {
+    Value *LHS = Visit(E->getLHS());
+    Value *RHS = Visit(E->getRHS());
+
+    if (LHS->getType()->isFPOrFPVectorTy()) {
+      Result = Builder.CreateFCmp((llvm::CmpInst::Predicate)FCmpOpc,
+                                  LHS, RHS, "cmp");
+    } else if (LHSTy->isSignedIntegerType()) {
+      Result = Builder.CreateICmp((llvm::ICmpInst::Predicate)SICmpOpc,
+                                  LHS, RHS, "cmp");
+    } else {
+      // Unsigned integers and pointers.
+      Result = Builder.CreateICmp((llvm::ICmpInst::Predicate)UICmpOpc,
+                                  LHS, RHS, "cmp");
+    }
+
+    // If this is a vector comparison, sign extend the result to the appropriate
+    // vector integer type and return it (don't convert to bool).
+    if (LHSTy->isVectorType())
+      return Builder.CreateSExt(Result, ConvertType(E->getType()), "sext");
+
+  } else {
+    // Complex Comparison: can only be an equality comparison.
+    CodeGenFunction::ComplexPairTy LHS = CGF.EmitComplexExpr(E->getLHS());
+    CodeGenFunction::ComplexPairTy RHS = CGF.EmitComplexExpr(E->getRHS());
+
+    QualType CETy = LHSTy->getAs<ComplexType>()->getElementType();
+
+    Value *ResultR, *ResultI;
+    if (CETy->isRealFloatingType()) {
+      ResultR = Builder.CreateFCmp((llvm::FCmpInst::Predicate)FCmpOpc,
+                                   LHS.first, RHS.first, "cmp.r");
+      ResultI = Builder.CreateFCmp((llvm::FCmpInst::Predicate)FCmpOpc,
+                                   LHS.second, RHS.second, "cmp.i");
+    } else {
+      // Complex comparisons can only be equality comparisons.  As such, signed
+      // and unsigned opcodes are the same.
+      ResultR = Builder.CreateICmp((llvm::ICmpInst::Predicate)UICmpOpc,
+                                   LHS.first, RHS.first, "cmp.r");
+      ResultI = Builder.CreateICmp((llvm::ICmpInst::Predicate)UICmpOpc,
+                                   LHS.second, RHS.second, "cmp.i");
+    }
+
+    if (E->getOpcode() == BinaryOperator::EQ) {
+      Result = Builder.CreateAnd(ResultR, ResultI, "and.ri");
+    } else {
+      assert(E->getOpcode() == BinaryOperator::NE &&
+             "Complex comparison other than == or != ?");
+      Result = Builder.CreateOr(ResultR, ResultI, "or.ri");
+    }
+  }
+
+  return EmitScalarConversion(Result, CGF.getContext().BoolTy, E->getType());
+}
+
+Value *ScalarExprEmitter::VisitBinAssign(const BinaryOperator *E) {
+  bool Ignore = TestAndClearIgnoreResultAssign();
+
+  // __block variables need to have the rhs evaluated first, plus this should
+  // improve codegen just a little.
+  Value *RHS = Visit(E->getRHS());
+  LValue LHS = EmitCheckedLValue(E->getLHS());
+
+  // Store the value into the LHS.  Bit-fields are handled specially
+  // because the result is altered by the store, i.e., [C99 6.5.16p1]
+  // 'An assignment expression has the value of the left operand after
+  // the assignment...'.
+  if (LHS.isBitField()) {
+    if (!LHS.isVolatileQualified()) {
+      CGF.EmitStoreThroughBitfieldLValue(RValue::get(RHS), LHS, E->getType(),
+                                         &RHS);
+      return RHS;
+    } else
+      CGF.EmitStoreThroughBitfieldLValue(RValue::get(RHS), LHS, E->getType());
+  } else
+    CGF.EmitStoreThroughLValue(RValue::get(RHS), LHS, E->getType());
+  if (Ignore)
+    return 0;
+  return EmitLoadOfLValue(LHS, E->getType());
+}
+
+Value *ScalarExprEmitter::VisitBinLAnd(const BinaryOperator *E) {
+  const llvm::Type *ResTy = ConvertType(E->getType());
+  
+  // If we have 0 && RHS, see if we can elide RHS, if so, just return 0.
+  // If we have 1 && X, just emit X without inserting the control flow.
+  if (int Cond = CGF.ConstantFoldsToSimpleInteger(E->getLHS())) {
+    if (Cond == 1) { // If we have 1 && X, just emit X.
+      Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS());
+      // ZExt result to int or bool.
+      return Builder.CreateZExtOrBitCast(RHSCond, ResTy, "land.ext");
+    }
+
+    // 0 && RHS: If it is safe, just elide the RHS, and return 0/false.
+    if (!CGF.ContainsLabel(E->getRHS()))
+      return llvm::Constant::getNullValue(ResTy);
+  }
+
+  llvm::BasicBlock *ContBlock = CGF.createBasicBlock("land.end");
+  llvm::BasicBlock *RHSBlock  = CGF.createBasicBlock("land.rhs");
+
+  // Branch on the LHS first.  If it is false, go to the failure (cont) block.
+  CGF.EmitBranchOnBoolExpr(E->getLHS(), RHSBlock, ContBlock);
+
+  // Any edges into the ContBlock are now from an (indeterminate number of)
+  // edges from this first condition.  All of these values will be false.  Start
+  // setting up the PHI node in the Cont Block for this.
+  llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext),
+                                            "", ContBlock);
+  PN->reserveOperandSpace(2);  // Normal case, two inputs.
+  for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
+       PI != PE; ++PI)
+    PN->addIncoming(llvm::ConstantInt::getFalse(VMContext), *PI);
+
+  CGF.BeginConditionalBranch();
+  CGF.EmitBlock(RHSBlock);
+  Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS());
+  CGF.EndConditionalBranch();
+
+  // Reaquire the RHS block, as there may be subblocks inserted.
+  RHSBlock = Builder.GetInsertBlock();
+
+  // Emit an unconditional branch from this block to ContBlock.  Insert an entry
+  // into the phi node for the edge with the value of RHSCond.
+  CGF.EmitBlock(ContBlock);
+  PN->addIncoming(RHSCond, RHSBlock);
+
+  // ZExt result to int.
+  return Builder.CreateZExtOrBitCast(PN, ResTy, "land.ext");
+}
+
+Value *ScalarExprEmitter::VisitBinLOr(const BinaryOperator *E) {
+  const llvm::Type *ResTy = ConvertType(E->getType());
+  
+  // If we have 1 || RHS, see if we can elide RHS, if so, just return 1.
+  // If we have 0 || X, just emit X without inserting the control flow.
+  if (int Cond = CGF.ConstantFoldsToSimpleInteger(E->getLHS())) {
+    if (Cond == -1) { // If we have 0 || X, just emit X.
+      Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS());
+      // ZExt result to int or bool.
+      return Builder.CreateZExtOrBitCast(RHSCond, ResTy, "lor.ext");
+    }
+
+    // 1 || RHS: If it is safe, just elide the RHS, and return 1/true.
+    if (!CGF.ContainsLabel(E->getRHS()))
+      return llvm::ConstantInt::get(ResTy, 1);
+  }
+
+  llvm::BasicBlock *ContBlock = CGF.createBasicBlock("lor.end");
+  llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("lor.rhs");
+
+  // Branch on the LHS first.  If it is true, go to the success (cont) block.
+  CGF.EmitBranchOnBoolExpr(E->getLHS(), ContBlock, RHSBlock);
+
+  // Any edges into the ContBlock are now from an (indeterminate number of)
+  // edges from this first condition.  All of these values will be true.  Start
+  // setting up the PHI node in the Cont Block for this.
+  llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext),
+                                            "", ContBlock);
+  PN->reserveOperandSpace(2);  // Normal case, two inputs.
+  for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
+       PI != PE; ++PI)
+    PN->addIncoming(llvm::ConstantInt::getTrue(VMContext), *PI);
+
+  CGF.BeginConditionalBranch();
+
+  // Emit the RHS condition as a bool value.
+  CGF.EmitBlock(RHSBlock);
+  Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS());
+
+  CGF.EndConditionalBranch();
+
+  // Reaquire the RHS block, as there may be subblocks inserted.
+  RHSBlock = Builder.GetInsertBlock();
+
+  // Emit an unconditional branch from this block to ContBlock.  Insert an entry
+  // into the phi node for the edge with the value of RHSCond.
+  CGF.EmitBlock(ContBlock);
+  PN->addIncoming(RHSCond, RHSBlock);
+
+  // ZExt result to int.
+  return Builder.CreateZExtOrBitCast(PN, ResTy, "lor.ext");
+}
+
+Value *ScalarExprEmitter::VisitBinComma(const BinaryOperator *E) {
+  CGF.EmitStmt(E->getLHS());
+  CGF.EnsureInsertPoint();
+  return Visit(E->getRHS());
+}
+
+//===----------------------------------------------------------------------===//
+//                             Other Operators
+//===----------------------------------------------------------------------===//
+
+/// isCheapEnoughToEvaluateUnconditionally - Return true if the specified
+/// expression is cheap enough and side-effect-free enough to evaluate
+/// unconditionally instead of conditionally.  This is used to convert control
+/// flow into selects in some cases.
+static bool isCheapEnoughToEvaluateUnconditionally(const Expr *E,
+                                                   CodeGenFunction &CGF) {
+  if (const ParenExpr *PE = dyn_cast<ParenExpr>(E))
+    return isCheapEnoughToEvaluateUnconditionally(PE->getSubExpr(), CGF);
+
+  // TODO: Allow anything we can constant fold to an integer or fp constant.
+  if (isa<IntegerLiteral>(E) || isa<CharacterLiteral>(E) ||
+      isa<FloatingLiteral>(E))
+    return true;
+
+  // Non-volatile automatic variables too, to get "cond ? X : Y" where
+  // X and Y are local variables.
+  if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
+    if (const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl()))
+      if (VD->hasLocalStorage() && !(CGF.getContext()
+                                     .getCanonicalType(VD->getType())
+                                     .isVolatileQualified()))
+        return true;
+
+  return false;
+}
+
+
+Value *ScalarExprEmitter::
+VisitConditionalOperator(const ConditionalOperator *E) {
+  TestAndClearIgnoreResultAssign();
+  // If the condition constant folds and can be elided, try to avoid emitting
+  // the condition and the dead arm.
+  if (int Cond = CGF.ConstantFoldsToSimpleInteger(E->getCond())){
+    Expr *Live = E->getLHS(), *Dead = E->getRHS();
+    if (Cond == -1)
+      std::swap(Live, Dead);
+
+    // If the dead side doesn't have labels we need, and if the Live side isn't
+    // the gnu missing ?: extension (which we could handle, but don't bother
+    // to), just emit the Live part.
+    if ((!Dead || !CGF.ContainsLabel(Dead)) &&  // No labels in dead part
+        Live)                                   // Live part isn't missing.
+      return Visit(Live);
+  }
+
+
+  // If this is a really simple expression (like x ? 4 : 5), emit this as a
+  // select instead of as control flow.  We can only do this if it is cheap and
+  // safe to evaluate the LHS and RHS unconditionally.
+  if (E->getLHS() && isCheapEnoughToEvaluateUnconditionally(E->getLHS(),
+                                                            CGF) &&
+      isCheapEnoughToEvaluateUnconditionally(E->getRHS(), CGF)) {
+    llvm::Value *CondV = CGF.EvaluateExprAsBool(E->getCond());
+    llvm::Value *LHS = Visit(E->getLHS());
+    llvm::Value *RHS = Visit(E->getRHS());
+    return Builder.CreateSelect(CondV, LHS, RHS, "cond");
+  }
+
+
+  llvm::BasicBlock *LHSBlock = CGF.createBasicBlock("cond.true");
+  llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("cond.false");
+  llvm::BasicBlock *ContBlock = CGF.createBasicBlock("cond.end");
+  Value *CondVal = 0;
+
+  // If we don't have the GNU missing condition extension, emit a branch on bool
+  // the normal way.
+  if (E->getLHS()) {
+    // Otherwise, just use EmitBranchOnBoolExpr to get small and simple code for
+    // the branch on bool.
+    CGF.EmitBranchOnBoolExpr(E->getCond(), LHSBlock, RHSBlock);
+  } else {
+    // Otherwise, for the ?: extension, evaluate the conditional and then
+    // convert it to bool the hard way.  We do this explicitly because we need
+    // the unconverted value for the missing middle value of the ?:.
+    CondVal = CGF.EmitScalarExpr(E->getCond());
+
+    // In some cases, EmitScalarConversion will delete the "CondVal" expression
+    // if there are no extra uses (an optimization).  Inhibit this by making an
+    // extra dead use, because we're going to add a use of CondVal later.  We
+    // don't use the builder for this, because we don't want it to get optimized
+    // away.  This leaves dead code, but the ?: extension isn't common.
+    new llvm::BitCastInst(CondVal, CondVal->getType(), "dummy?:holder",
+                          Builder.GetInsertBlock());
+
+    Value *CondBoolVal =
+      CGF.EmitScalarConversion(CondVal, E->getCond()->getType(),
+                               CGF.getContext().BoolTy);
+    Builder.CreateCondBr(CondBoolVal, LHSBlock, RHSBlock);
+  }
+
+  CGF.BeginConditionalBranch();
+  CGF.EmitBlock(LHSBlock);
+
+  // Handle the GNU extension for missing LHS.
+  Value *LHS;
+  if (E->getLHS())
+    LHS = Visit(E->getLHS());
+  else    // Perform promotions, to handle cases like "short ?: int"
+    LHS = EmitScalarConversion(CondVal, E->getCond()->getType(), E->getType());
+
+  CGF.EndConditionalBranch();
+  LHSBlock = Builder.GetInsertBlock();
+  CGF.EmitBranch(ContBlock);
+
+  CGF.BeginConditionalBranch();
+  CGF.EmitBlock(RHSBlock);
+
+  Value *RHS = Visit(E->getRHS());
+  CGF.EndConditionalBranch();
+  RHSBlock = Builder.GetInsertBlock();
+  CGF.EmitBranch(ContBlock);
+
+  CGF.EmitBlock(ContBlock);
+
+  // If the LHS or RHS is a throw expression, it will be legitimately null.
+  if (!LHS)
+    return RHS;
+  if (!RHS)
+    return LHS;
+
+  // Create a PHI node for the real part.
+  llvm::PHINode *PN = Builder.CreatePHI(LHS->getType(), "cond");
+  PN->reserveOperandSpace(2);
+  PN->addIncoming(LHS, LHSBlock);
+  PN->addIncoming(RHS, RHSBlock);
+  return PN;
+}
+
+Value *ScalarExprEmitter::VisitChooseExpr(ChooseExpr *E) {
+  return Visit(E->getChosenSubExpr(CGF.getContext()));
+}
+
+Value *ScalarExprEmitter::VisitVAArgExpr(VAArgExpr *VE) {
+  llvm::Value *ArgValue = CGF.EmitVAListRef(VE->getSubExpr());
+  llvm::Value *ArgPtr = CGF.EmitVAArg(ArgValue, VE->getType());
+
+  // If EmitVAArg fails, we fall back to the LLVM instruction.
+  if (!ArgPtr)
+    return Builder.CreateVAArg(ArgValue, ConvertType(VE->getType()));
+
+  // FIXME Volatility.
+  return Builder.CreateLoad(ArgPtr);
+}
+
+Value *ScalarExprEmitter::VisitBlockExpr(const BlockExpr *BE) {
+  return CGF.BuildBlockLiteralTmp(BE);
+}
+
+//===----------------------------------------------------------------------===//
+//                         Entry Point into this File
+//===----------------------------------------------------------------------===//
+
+/// EmitScalarExpr - Emit the computation of the specified expression of scalar
+/// type, ignoring the result.
+Value *CodeGenFunction::EmitScalarExpr(const Expr *E, bool IgnoreResultAssign) {
+  assert(E && !hasAggregateLLVMType(E->getType()) &&
+         "Invalid scalar expression to emit");
+
+  return ScalarExprEmitter(*this, IgnoreResultAssign)
+    .Visit(const_cast<Expr*>(E));
+}
+
+/// EmitScalarConversion - Emit a conversion from the specified type to the
+/// specified destination type, both of which are LLVM scalar types.
+Value *CodeGenFunction::EmitScalarConversion(Value *Src, QualType SrcTy,
+                                             QualType DstTy) {
+  assert(!hasAggregateLLVMType(SrcTy) && !hasAggregateLLVMType(DstTy) &&
+         "Invalid scalar expression to emit");
+  return ScalarExprEmitter(*this).EmitScalarConversion(Src, SrcTy, DstTy);
+}
+
+/// EmitComplexToScalarConversion - Emit a conversion from the specified complex
+/// type to the specified destination type, where the destination type is an
+/// LLVM scalar type.
+Value *CodeGenFunction::EmitComplexToScalarConversion(ComplexPairTy Src,
+                                                      QualType SrcTy,
+                                                      QualType DstTy) {
+  assert(SrcTy->isAnyComplexType() && !hasAggregateLLVMType(DstTy) &&
+         "Invalid complex -> scalar conversion");
+  return ScalarExprEmitter(*this).EmitComplexToScalarConversion(Src, SrcTy,
+                                                                DstTy);
+}
+
+LValue CodeGenFunction::EmitObjCIsaExpr(const ObjCIsaExpr *E) {
+  llvm::Value *V;
+  // object->isa or (*object).isa
+  // Generate code as for: *(Class*)object
+  // build Class* type
+  const llvm::Type *ClassPtrTy = ConvertType(E->getType());
+
+  Expr *BaseExpr = E->getBase();
+  if (BaseExpr->isLvalue(getContext()) != Expr::LV_Valid) {
+    V = CreateTempAlloca(ClassPtrTy, "resval");
+    llvm::Value *Src = EmitScalarExpr(BaseExpr);
+    Builder.CreateStore(Src, V);
+    LValue LV = LValue::MakeAddr(V, MakeQualifiers(E->getType()));
+    V = ScalarExprEmitter(*this).EmitLoadOfLValue(LV, E->getType());
+  }
+  else {
+      if (E->isArrow())
+        V = ScalarExprEmitter(*this).EmitLoadOfLValue(BaseExpr);
+      else
+        V  = EmitLValue(BaseExpr).getAddress();
+  }
+  
+  // build Class* type
+  ClassPtrTy = ClassPtrTy->getPointerTo();
+  V = Builder.CreateBitCast(V, ClassPtrTy);
+  LValue LV = LValue::MakeAddr(V, MakeQualifiers(E->getType()));
+  return LV;
+}
+
+
+LValue CodeGenFunction::EmitCompoundAssignOperatorLValue(
+                                            const CompoundAssignOperator *E) {
+  ScalarExprEmitter Scalar(*this);
+  Value *BitFieldResult = 0;
+  switch (E->getOpcode()) {
+#define COMPOUND_OP(Op)                                                       \
+    case BinaryOperator::Op##Assign:                                          \
+      return Scalar.EmitCompoundAssignLValue(E, &ScalarExprEmitter::Emit##Op, \
+                                             BitFieldResult)
+  COMPOUND_OP(Mul);
+  COMPOUND_OP(Div);
+  COMPOUND_OP(Rem);
+  COMPOUND_OP(Add);
+  COMPOUND_OP(Sub);
+  COMPOUND_OP(Shl);
+  COMPOUND_OP(Shr);
+  COMPOUND_OP(And);
+  COMPOUND_OP(Xor);
+  COMPOUND_OP(Or);
+#undef COMPOUND_OP
+      
+  case BinaryOperator::PtrMemD:
+  case BinaryOperator::PtrMemI:
+  case BinaryOperator::Mul:
+  case BinaryOperator::Div:
+  case BinaryOperator::Rem:
+  case BinaryOperator::Add:
+  case BinaryOperator::Sub:
+  case BinaryOperator::Shl:
+  case BinaryOperator::Shr:
+  case BinaryOperator::LT:
+  case BinaryOperator::GT:
+  case BinaryOperator::LE:
+  case BinaryOperator::GE:
+  case BinaryOperator::EQ:
+  case BinaryOperator::NE:
+  case BinaryOperator::And:
+  case BinaryOperator::Xor:
+  case BinaryOperator::Or:
+  case BinaryOperator::LAnd:
+  case BinaryOperator::LOr:
+  case BinaryOperator::Assign:
+  case BinaryOperator::Comma:
+    assert(false && "Not valid compound assignment operators");
+    break;
+  }
+   
+  llvm_unreachable("Unhandled compound assignment operator");
+}
diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp
new file mode 100644
index 0000000..1ff30f2
--- /dev/null
+++ b/lib/CodeGen/CGObjC.cpp
@@ -0,0 +1,755 @@
+//===---- CGBuiltin.cpp - Emit LLVM Code for builtins ---------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This contains code to emit Objective-C code as LLVM code.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CGObjCRuntime.h"
+#include "CodeGenFunction.h"
+#include "CodeGenModule.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/StmtObjC.h"
+#include "clang/Basic/Diagnostic.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Target/TargetData.h"
+using namespace clang;
+using namespace CodeGen;
+
+/// Emits an instance of NSConstantString representing the object.
+llvm::Value *CodeGenFunction::EmitObjCStringLiteral(const ObjCStringLiteral *E)
+{
+  llvm::Constant *C = 
+      CGM.getObjCRuntime().GenerateConstantString(E->getString());
+  // FIXME: This bitcast should just be made an invariant on the Runtime.
+  return llvm::ConstantExpr::getBitCast(C, ConvertType(E->getType()));
+}
+
+/// Emit a selector.
+llvm::Value *CodeGenFunction::EmitObjCSelectorExpr(const ObjCSelectorExpr *E) {
+  // Untyped selector.
+  // Note that this implementation allows for non-constant strings to be passed
+  // as arguments to @selector().  Currently, the only thing preventing this
+  // behaviour is the type checking in the front end.
+  return CGM.getObjCRuntime().GetSelector(Builder, E->getSelector());
+}
+
+llvm::Value *CodeGenFunction::EmitObjCProtocolExpr(const ObjCProtocolExpr *E) {
+  // FIXME: This should pass the Decl not the name.
+  return CGM.getObjCRuntime().GenerateProtocolRef(Builder, E->getProtocol());
+}
+
+
+RValue CodeGenFunction::EmitObjCMessageExpr(const ObjCMessageExpr *E) {
+  // Only the lookup mechanism and first two arguments of the method
+  // implementation vary between runtimes.  We can get the receiver and
+  // arguments in generic code.
+
+  CGObjCRuntime &Runtime = CGM.getObjCRuntime();
+  bool isSuperMessage = false;
+  bool isClassMessage = false;
+  // Find the receiver
+  llvm::Value *Receiver = 0;
+  switch (E->getReceiverKind()) {
+  case ObjCMessageExpr::Instance:
+    Receiver = EmitScalarExpr(E->getInstanceReceiver());
+    break;
+
+  case ObjCMessageExpr::Class: {
+    const ObjCInterfaceType *IFace
+      = E->getClassReceiver()->getAs<ObjCInterfaceType>();
+    assert(IFace && "Invalid Objective-C class message send");
+    Receiver = Runtime.GetClass(Builder, IFace->getDecl());
+    isClassMessage = true;
+    break;
+  }
+
+  case ObjCMessageExpr::SuperInstance:
+    Receiver = LoadObjCSelf();
+    isSuperMessage = true;
+    break;
+
+  case ObjCMessageExpr::SuperClass:
+    Receiver = LoadObjCSelf();
+    isSuperMessage = true;
+    isClassMessage = true;
+    break;
+  }
+
+  CallArgList Args;
+  EmitCallArgs(Args, E->getMethodDecl(), E->arg_begin(), E->arg_end());
+
+  if (isSuperMessage) {
+    // super is only valid in an Objective-C method
+    const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl);
+    bool isCategoryImpl = isa<ObjCCategoryImplDecl>(OMD->getDeclContext());
+    return Runtime.GenerateMessageSendSuper(*this, E->getType(),
+                                            E->getSelector(),
+                                            OMD->getClassInterface(),
+                                            isCategoryImpl,
+                                            Receiver,
+                                            isClassMessage,
+                                            Args,
+                                            E->getMethodDecl());
+  }
+
+  return Runtime.GenerateMessageSend(*this, E->getType(), E->getSelector(),
+                                     Receiver, isClassMessage, Args,
+                                     E->getMethodDecl());
+}
+
+/// StartObjCMethod - Begin emission of an ObjCMethod. This generates
+/// the LLVM function and sets the other context used by
+/// CodeGenFunction.
+void CodeGenFunction::StartObjCMethod(const ObjCMethodDecl *OMD,
+                                      const ObjCContainerDecl *CD) {
+  FunctionArgList Args;
+  // Check if we should generate debug info for this method.
+  if (CGM.getDebugInfo() && !OMD->hasAttr<NoDebugAttr>())
+    DebugInfo = CGM.getDebugInfo();
+
+  llvm::Function *Fn = CGM.getObjCRuntime().GenerateMethod(OMD, CD);
+
+  const CGFunctionInfo &FI = CGM.getTypes().getFunctionInfo(OMD);
+  CGM.SetInternalFunctionAttributes(OMD, Fn, FI);
+
+  Args.push_back(std::make_pair(OMD->getSelfDecl(),
+                                OMD->getSelfDecl()->getType()));
+  Args.push_back(std::make_pair(OMD->getCmdDecl(),
+                                OMD->getCmdDecl()->getType()));
+
+  for (ObjCMethodDecl::param_iterator PI = OMD->param_begin(),
+       E = OMD->param_end(); PI != E; ++PI)
+    Args.push_back(std::make_pair(*PI, (*PI)->getType()));
+
+  StartFunction(OMD, OMD->getResultType(), Fn, Args, OMD->getLocStart());
+}
+
+/// Generate an Objective-C method.  An Objective-C method is a C function with
+/// its pointer, name, and types registered in the class struture.
+void CodeGenFunction::GenerateObjCMethod(const ObjCMethodDecl *OMD) {
+  StartObjCMethod(OMD, OMD->getClassInterface());
+  EmitStmt(OMD->getBody());
+  FinishFunction(OMD->getBodyRBrace());
+}
+
+// FIXME: I wasn't sure about the synthesis approach. If we end up generating an
+// AST for the whole body we can just fall back to having a GenerateFunction
+// which takes the body Stmt.
+
+/// GenerateObjCGetter - Generate an Objective-C property getter
+/// function. The given Decl must be an ObjCImplementationDecl. @synthesize
+/// is illegal within a category.
+void CodeGenFunction::GenerateObjCGetter(ObjCImplementationDecl *IMP,
+                                         const ObjCPropertyImplDecl *PID) {
+  ObjCIvarDecl *Ivar = PID->getPropertyIvarDecl();
+  const ObjCPropertyDecl *PD = PID->getPropertyDecl();
+  bool IsAtomic =
+    !(PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_nonatomic);
+  ObjCMethodDecl *OMD = PD->getGetterMethodDecl();
+  assert(OMD && "Invalid call to generate getter (empty method)");
+  // FIXME: This is rather murky, we create this here since they will not have
+  // been created by Sema for us.
+  OMD->createImplicitParams(getContext(), IMP->getClassInterface());
+  StartObjCMethod(OMD, IMP->getClassInterface());
+  
+  // Determine if we should use an objc_getProperty call for
+  // this. Non-atomic properties are directly evaluated.
+  // atomic 'copy' and 'retain' properties are also directly
+  // evaluated in gc-only mode.
+  if (CGM.getLangOptions().getGCMode() != LangOptions::GCOnly &&
+      IsAtomic &&
+      (PD->getSetterKind() == ObjCPropertyDecl::Copy ||
+       PD->getSetterKind() == ObjCPropertyDecl::Retain)) {
+    llvm::Value *GetPropertyFn =
+      CGM.getObjCRuntime().GetPropertyGetFunction();
+
+    if (!GetPropertyFn) {
+      CGM.ErrorUnsupported(PID, "Obj-C getter requiring atomic copy");
+      FinishFunction();
+      return;
+    }
+
+    // Return (ivar-type) objc_getProperty((id) self, _cmd, offset, true).
+    // FIXME: Can't this be simpler? This might even be worse than the
+    // corresponding gcc code.
+    CodeGenTypes &Types = CGM.getTypes();
+    ValueDecl *Cmd = OMD->getCmdDecl();
+    llvm::Value *CmdVal = Builder.CreateLoad(LocalDeclMap[Cmd], "cmd");
+    QualType IdTy = getContext().getObjCIdType();
+    llvm::Value *SelfAsId =
+      Builder.CreateBitCast(LoadObjCSelf(), Types.ConvertType(IdTy));
+    llvm::Value *Offset = EmitIvarOffset(IMP->getClassInterface(), Ivar);
+    llvm::Value *True =
+      llvm::ConstantInt::get(Types.ConvertType(getContext().BoolTy), 1);
+    CallArgList Args;
+    Args.push_back(std::make_pair(RValue::get(SelfAsId), IdTy));
+    Args.push_back(std::make_pair(RValue::get(CmdVal), Cmd->getType()));
+    Args.push_back(std::make_pair(RValue::get(Offset), getContext().LongTy));
+    Args.push_back(std::make_pair(RValue::get(True), getContext().BoolTy));
+    // FIXME: We shouldn't need to get the function info here, the
+    // runtime already should have computed it to build the function.
+    RValue RV = EmitCall(Types.getFunctionInfo(PD->getType(), Args,
+                                               FunctionType::ExtInfo()),
+                         GetPropertyFn, ReturnValueSlot(), Args);
+    // We need to fix the type here. Ivars with copy & retain are
+    // always objects so we don't need to worry about complex or
+    // aggregates.
+    RV = RValue::get(Builder.CreateBitCast(RV.getScalarVal(),
+                                           Types.ConvertType(PD->getType())));
+    EmitReturnOfRValue(RV, PD->getType());
+  } else {
+    LValue LV = EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(), Ivar, 0);
+    if (Ivar->getType()->isAnyComplexType()) {
+      ComplexPairTy Pair = LoadComplexFromAddr(LV.getAddress(),
+                                               LV.isVolatileQualified());
+      StoreComplexToAddr(Pair, ReturnValue, LV.isVolatileQualified());
+    }
+    else if (hasAggregateLLVMType(Ivar->getType())) {
+      bool IsStrong = false;
+      if ((IsAtomic || (IsStrong = IvarTypeWithAggrGCObjects(Ivar->getType())))
+          && CurFnInfo->getReturnInfo().getKind() == ABIArgInfo::Indirect
+          && CGM.getObjCRuntime().GetCopyStructFunction()) {
+        llvm::Value *GetCopyStructFn =
+          CGM.getObjCRuntime().GetCopyStructFunction();
+        CodeGenTypes &Types = CGM.getTypes();
+        // objc_copyStruct (ReturnValue, &structIvar, 
+        //                  sizeof (Type of Ivar), isAtomic, false);
+        CallArgList Args;
+        RValue RV = RValue::get(Builder.CreateBitCast(ReturnValue,
+                                    Types.ConvertType(getContext().VoidPtrTy)));
+        Args.push_back(std::make_pair(RV, getContext().VoidPtrTy));
+        RV = RValue::get(Builder.CreateBitCast(LV.getAddress(),
+                                    Types.ConvertType(getContext().VoidPtrTy)));
+        Args.push_back(std::make_pair(RV, getContext().VoidPtrTy));
+        // sizeof (Type of Ivar)
+        uint64_t Size =  getContext().getTypeSize(Ivar->getType()) / 8;
+        llvm::Value *SizeVal =
+          llvm::ConstantInt::get(Types.ConvertType(getContext().LongTy), Size);
+        Args.push_back(std::make_pair(RValue::get(SizeVal),
+                                      getContext().LongTy));
+        llvm::Value *isAtomic =
+          llvm::ConstantInt::get(Types.ConvertType(getContext().BoolTy), 
+                                 IsAtomic ? 1 : 0);
+        Args.push_back(std::make_pair(RValue::get(isAtomic), 
+                                      getContext().BoolTy));
+        llvm::Value *hasStrong =
+          llvm::ConstantInt::get(Types.ConvertType(getContext().BoolTy), 
+                                 IsStrong ? 1 : 0);
+        Args.push_back(std::make_pair(RValue::get(hasStrong), 
+                                      getContext().BoolTy));
+        EmitCall(Types.getFunctionInfo(getContext().VoidTy, Args,
+                                       FunctionType::ExtInfo()),
+                 GetCopyStructFn, ReturnValueSlot(), Args);
+      }
+      else
+        EmitAggregateCopy(ReturnValue, LV.getAddress(), Ivar->getType());
+    } else {
+      CodeGenTypes &Types = CGM.getTypes();
+      RValue RV = EmitLoadOfLValue(LV, Ivar->getType());
+      RV = RValue::get(Builder.CreateBitCast(RV.getScalarVal(),
+                       Types.ConvertType(PD->getType())));
+      EmitReturnOfRValue(RV, PD->getType());
+    }
+  }
+
+  FinishFunction();
+}
+
+/// GenerateObjCSetter - Generate an Objective-C property setter
+/// function. The given Decl must be an ObjCImplementationDecl. @synthesize
+/// is illegal within a category.
+void CodeGenFunction::GenerateObjCSetter(ObjCImplementationDecl *IMP,
+                                         const ObjCPropertyImplDecl *PID) {
+  ObjCIvarDecl *Ivar = PID->getPropertyIvarDecl();
+  const ObjCPropertyDecl *PD = PID->getPropertyDecl();
+  ObjCMethodDecl *OMD = PD->getSetterMethodDecl();
+  assert(OMD && "Invalid call to generate setter (empty method)");
+  // FIXME: This is rather murky, we create this here since they will not have
+  // been created by Sema for us.
+  OMD->createImplicitParams(getContext(), IMP->getClassInterface());
+  StartObjCMethod(OMD, IMP->getClassInterface());
+
+  bool IsCopy = PD->getSetterKind() == ObjCPropertyDecl::Copy;
+  bool IsAtomic =
+    !(PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_nonatomic);
+
+  // Determine if we should use an objc_setProperty call for
+  // this. Properties with 'copy' semantics always use it, as do
+  // non-atomic properties with 'release' semantics as long as we are
+  // not in gc-only mode.
+  if (IsCopy ||
+      (CGM.getLangOptions().getGCMode() != LangOptions::GCOnly &&
+       PD->getSetterKind() == ObjCPropertyDecl::Retain)) {
+    llvm::Value *SetPropertyFn =
+      CGM.getObjCRuntime().GetPropertySetFunction();
+
+    if (!SetPropertyFn) {
+      CGM.ErrorUnsupported(PID, "Obj-C getter requiring atomic copy");
+      FinishFunction();
+      return;
+    }
+
+    // Emit objc_setProperty((id) self, _cmd, offset, arg,
+    //                       <is-atomic>, <is-copy>).
+    // FIXME: Can't this be simpler? This might even be worse than the
+    // corresponding gcc code.
+    CodeGenTypes &Types = CGM.getTypes();
+    ValueDecl *Cmd = OMD->getCmdDecl();
+    llvm::Value *CmdVal = Builder.CreateLoad(LocalDeclMap[Cmd], "cmd");
+    QualType IdTy = getContext().getObjCIdType();
+    llvm::Value *SelfAsId =
+      Builder.CreateBitCast(LoadObjCSelf(), Types.ConvertType(IdTy));
+    llvm::Value *Offset = EmitIvarOffset(IMP->getClassInterface(), Ivar);
+    llvm::Value *Arg = LocalDeclMap[*OMD->param_begin()];
+    llvm::Value *ArgAsId =
+      Builder.CreateBitCast(Builder.CreateLoad(Arg, "arg"),
+                            Types.ConvertType(IdTy));
+    llvm::Value *True =
+      llvm::ConstantInt::get(Types.ConvertType(getContext().BoolTy), 1);
+    llvm::Value *False =
+      llvm::ConstantInt::get(Types.ConvertType(getContext().BoolTy), 0);
+    CallArgList Args;
+    Args.push_back(std::make_pair(RValue::get(SelfAsId), IdTy));
+    Args.push_back(std::make_pair(RValue::get(CmdVal), Cmd->getType()));
+    Args.push_back(std::make_pair(RValue::get(Offset), getContext().LongTy));
+    Args.push_back(std::make_pair(RValue::get(ArgAsId), IdTy));
+    Args.push_back(std::make_pair(RValue::get(IsAtomic ? True : False),
+                                  getContext().BoolTy));
+    Args.push_back(std::make_pair(RValue::get(IsCopy ? True : False),
+                                  getContext().BoolTy));
+    // FIXME: We shouldn't need to get the function info here, the runtime
+    // already should have computed it to build the function.
+    EmitCall(Types.getFunctionInfo(getContext().VoidTy, Args,
+                                   FunctionType::ExtInfo()),
+             SetPropertyFn,
+             ReturnValueSlot(), Args);
+  } else if (IsAtomic && hasAggregateLLVMType(Ivar->getType()) &&
+             !Ivar->getType()->isAnyComplexType() &&
+             IndirectObjCSetterArg(*CurFnInfo)
+             && CGM.getObjCRuntime().GetCopyStructFunction()) {
+    // objc_copyStruct (&structIvar, &Arg, 
+    //                  sizeof (struct something), true, false);
+    llvm::Value *GetCopyStructFn =
+      CGM.getObjCRuntime().GetCopyStructFunction();
+    CodeGenTypes &Types = CGM.getTypes();
+    CallArgList Args;
+    LValue LV = EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(), Ivar, 0);
+    RValue RV = RValue::get(Builder.CreateBitCast(LV.getAddress(),
+                                    Types.ConvertType(getContext().VoidPtrTy)));
+    Args.push_back(std::make_pair(RV, getContext().VoidPtrTy));
+    llvm::Value *Arg = LocalDeclMap[*OMD->param_begin()];
+    llvm::Value *ArgAsPtrTy =
+      Builder.CreateBitCast(Arg,
+                            Types.ConvertType(getContext().VoidPtrTy));
+    RV = RValue::get(ArgAsPtrTy);
+    Args.push_back(std::make_pair(RV, getContext().VoidPtrTy));
+    // sizeof (Type of Ivar)
+    uint64_t Size =  getContext().getTypeSize(Ivar->getType()) / 8;
+    llvm::Value *SizeVal =
+      llvm::ConstantInt::get(Types.ConvertType(getContext().LongTy), Size);
+    Args.push_back(std::make_pair(RValue::get(SizeVal),
+                                  getContext().LongTy));
+    llvm::Value *True =
+      llvm::ConstantInt::get(Types.ConvertType(getContext().BoolTy), 1);
+    Args.push_back(std::make_pair(RValue::get(True), getContext().BoolTy));
+    llvm::Value *False =
+      llvm::ConstantInt::get(Types.ConvertType(getContext().BoolTy), 0);
+    Args.push_back(std::make_pair(RValue::get(False), getContext().BoolTy));
+    EmitCall(Types.getFunctionInfo(getContext().VoidTy, Args,
+                                   FunctionType::ExtInfo()),
+             GetCopyStructFn, ReturnValueSlot(), Args);
+  } else {
+    // FIXME: Find a clean way to avoid AST node creation.
+    SourceLocation Loc = PD->getLocation();
+    ValueDecl *Self = OMD->getSelfDecl();
+    ObjCIvarDecl *Ivar = PID->getPropertyIvarDecl();
+    DeclRefExpr Base(Self, Self->getType(), Loc);
+    ParmVarDecl *ArgDecl = *OMD->param_begin();
+    DeclRefExpr Arg(ArgDecl, ArgDecl->getType(), Loc);
+    ObjCIvarRefExpr IvarRef(Ivar, Ivar->getType(), Loc, &Base, true, true);
+    
+    // The property type can differ from the ivar type in some situations with
+    // Objective-C pointer types, we can always bit cast the RHS in these cases.
+    if (getContext().getCanonicalType(Ivar->getType()) !=
+        getContext().getCanonicalType(ArgDecl->getType())) {
+      ImplicitCastExpr ArgCasted(Ivar->getType(), CastExpr::CK_BitCast, &Arg,
+                                 CXXBaseSpecifierArray(), false);
+      BinaryOperator Assign(&IvarRef, &ArgCasted, BinaryOperator::Assign,
+                            Ivar->getType(), Loc);
+      EmitStmt(&Assign);
+    } else {
+      BinaryOperator Assign(&IvarRef, &Arg, BinaryOperator::Assign,
+                            Ivar->getType(), Loc);
+      EmitStmt(&Assign);
+    }
+  }
+
+  FinishFunction();
+}
+
+bool CodeGenFunction::IndirectObjCSetterArg(const CGFunctionInfo &FI) {
+  CGFunctionInfo::const_arg_iterator it = FI.arg_begin();
+  it++; it++;
+  const ABIArgInfo &AI = it->info;
+  // FIXME. Is this sufficient check?
+  return (AI.getKind() == ABIArgInfo::Indirect);
+}
+
+bool CodeGenFunction::IvarTypeWithAggrGCObjects(QualType Ty) {
+  if (CGM.getLangOptions().getGCMode() == LangOptions::NonGC)
+    return false;
+  if (const RecordType *FDTTy = Ty.getTypePtr()->getAs<RecordType>())
+    return FDTTy->getDecl()->hasObjectMember();
+  return false;
+}
+
+llvm::Value *CodeGenFunction::LoadObjCSelf() {
+  const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl);
+  // See if we need to lazily forward self inside a block literal.
+  BlockForwardSelf();
+  return Builder.CreateLoad(LocalDeclMap[OMD->getSelfDecl()], "self");
+}
+
+QualType CodeGenFunction::TypeOfSelfObject() {
+  const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl);
+  ImplicitParamDecl *selfDecl = OMD->getSelfDecl();
+  const ObjCObjectPointerType *PTy = cast<ObjCObjectPointerType>(
+    getContext().getCanonicalType(selfDecl->getType()));
+  return PTy->getPointeeType();
+}
+
+RValue CodeGenFunction::EmitObjCSuperPropertyGet(const Expr *Exp,
+                                                 const Selector &S) {
+  llvm::Value *Receiver = LoadObjCSelf();
+  const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl);
+  bool isClassMessage = OMD->isClassMethod();
+  bool isCategoryImpl = isa<ObjCCategoryImplDecl>(OMD->getDeclContext());
+  return CGM.getObjCRuntime().GenerateMessageSendSuper(*this,
+                                                       Exp->getType(),
+                                                       S,
+                                                       OMD->getClassInterface(),
+                                                       isCategoryImpl,
+                                                       Receiver,
+                                                       isClassMessage,
+                                                       CallArgList());
+
+}
+
+RValue CodeGenFunction::EmitObjCPropertyGet(const Expr *Exp) {
+  Exp = Exp->IgnoreParens();
+  // FIXME: Split it into two separate routines.
+  if (const ObjCPropertyRefExpr *E = dyn_cast<ObjCPropertyRefExpr>(Exp)) {
+    Selector S = E->getProperty()->getGetterName();
+    if (isa<ObjCSuperExpr>(E->getBase()))
+      return EmitObjCSuperPropertyGet(E, S);
+    return CGM.getObjCRuntime().
+             GenerateMessageSend(*this, Exp->getType(), S,
+                                 EmitScalarExpr(E->getBase()),
+                                 false, CallArgList());
+  } else {
+    const ObjCImplicitSetterGetterRefExpr *KE =
+      cast<ObjCImplicitSetterGetterRefExpr>(Exp);
+    Selector S = KE->getGetterMethod()->getSelector();
+    llvm::Value *Receiver;
+    if (KE->getInterfaceDecl()) {
+      const ObjCInterfaceDecl *OID = KE->getInterfaceDecl();
+      Receiver = CGM.getObjCRuntime().GetClass(Builder, OID);
+    } else if (isa<ObjCSuperExpr>(KE->getBase()))
+      return EmitObjCSuperPropertyGet(KE, S);
+    else
+      Receiver = EmitScalarExpr(KE->getBase());
+    return CGM.getObjCRuntime().
+             GenerateMessageSend(*this, Exp->getType(), S,
+                                 Receiver,
+                                 KE->getInterfaceDecl() != 0, CallArgList());
+  }
+}
+
+void CodeGenFunction::EmitObjCSuperPropertySet(const Expr *Exp,
+                                               const Selector &S,
+                                               RValue Src) {
+  CallArgList Args;
+  llvm::Value *Receiver = LoadObjCSelf();
+  const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl);
+  bool isClassMessage = OMD->isClassMethod();
+  bool isCategoryImpl = isa<ObjCCategoryImplDecl>(OMD->getDeclContext());
+  Args.push_back(std::make_pair(Src, Exp->getType()));
+  CGM.getObjCRuntime().GenerateMessageSendSuper(*this,
+                                                Exp->getType(),
+                                                S,
+                                                OMD->getClassInterface(),
+                                                isCategoryImpl,
+                                                Receiver,
+                                                isClassMessage,
+                                                Args);
+  return;
+}
+
+void CodeGenFunction::EmitObjCPropertySet(const Expr *Exp,
+                                          RValue Src) {
+  // FIXME: Split it into two separate routines.
+  if (const ObjCPropertyRefExpr *E = dyn_cast<ObjCPropertyRefExpr>(Exp)) {
+    Selector S = E->getProperty()->getSetterName();
+    if (isa<ObjCSuperExpr>(E->getBase())) {
+      EmitObjCSuperPropertySet(E, S, Src);
+      return;
+    }
+    CallArgList Args;
+    Args.push_back(std::make_pair(Src, E->getType()));
+    CGM.getObjCRuntime().GenerateMessageSend(*this, getContext().VoidTy, S,
+                                             EmitScalarExpr(E->getBase()),
+                                             false, Args);
+  } else if (const ObjCImplicitSetterGetterRefExpr *E =
+               dyn_cast<ObjCImplicitSetterGetterRefExpr>(Exp)) {
+    Selector S = E->getSetterMethod()->getSelector();
+    CallArgList Args;
+    llvm::Value *Receiver;
+    if (E->getInterfaceDecl()) {
+      const ObjCInterfaceDecl *OID = E->getInterfaceDecl();
+      Receiver = CGM.getObjCRuntime().GetClass(Builder, OID);
+    } else if (isa<ObjCSuperExpr>(E->getBase())) {
+      EmitObjCSuperPropertySet(E, S, Src);
+      return;
+    } else
+      Receiver = EmitScalarExpr(E->getBase());
+    Args.push_back(std::make_pair(Src, E->getType()));
+    CGM.getObjCRuntime().GenerateMessageSend(*this, getContext().VoidTy, S,
+                                             Receiver,
+                                             E->getInterfaceDecl() != 0, Args);
+  } else
+    assert (0 && "bad expression node in EmitObjCPropertySet");
+}
+
+void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S){
+  llvm::Constant *EnumerationMutationFn =
+    CGM.getObjCRuntime().EnumerationMutationFunction();
+  llvm::Value *DeclAddress;
+  QualType ElementTy;
+
+  if (!EnumerationMutationFn) {
+    CGM.ErrorUnsupported(&S, "Obj-C fast enumeration for this runtime");
+    return;
+  }
+
+  if (const DeclStmt *SD = dyn_cast<DeclStmt>(S.getElement())) {
+    EmitStmt(SD);
+    assert(HaveInsertPoint() && "DeclStmt destroyed insert point!");
+    const Decl* D = SD->getSingleDecl();
+    ElementTy = cast<ValueDecl>(D)->getType();
+    DeclAddress = LocalDeclMap[D];
+  } else {
+    ElementTy = cast<Expr>(S.getElement())->getType();
+    DeclAddress = 0;
+  }
+
+  // Fast enumeration state.
+  QualType StateTy = getContext().getObjCFastEnumerationStateType();
+  llvm::Value *StatePtr = CreateMemTemp(StateTy, "state.ptr");
+  EmitMemSetToZero(StatePtr, StateTy);
+
+  // Number of elements in the items array.
+  static const unsigned NumItems = 16;
+
+  // Get selector
+  IdentifierInfo *II[] = {
+    &CGM.getContext().Idents.get("countByEnumeratingWithState"),
+    &CGM.getContext().Idents.get("objects"),
+    &CGM.getContext().Idents.get("count")
+  };
+  Selector FastEnumSel =
+    CGM.getContext().Selectors.getSelector(llvm::array_lengthof(II), &II[0]);
+
+  QualType ItemsTy =
+    getContext().getConstantArrayType(getContext().getObjCIdType(),
+                                      llvm::APInt(32, NumItems),
+                                      ArrayType::Normal, 0);
+  llvm::Value *ItemsPtr = CreateMemTemp(ItemsTy, "items.ptr");
+
+  llvm::Value *Collection = EmitScalarExpr(S.getCollection());
+
+  CallArgList Args;
+  Args.push_back(std::make_pair(RValue::get(StatePtr),
+                                getContext().getPointerType(StateTy)));
+
+  Args.push_back(std::make_pair(RValue::get(ItemsPtr),
+                                getContext().getPointerType(ItemsTy)));
+
+  const llvm::Type *UnsignedLongLTy = ConvertType(getContext().UnsignedLongTy);
+  llvm::Constant *Count = llvm::ConstantInt::get(UnsignedLongLTy, NumItems);
+  Args.push_back(std::make_pair(RValue::get(Count),
+                                getContext().UnsignedLongTy));
+
+  RValue CountRV =
+    CGM.getObjCRuntime().GenerateMessageSend(*this,
+                                             getContext().UnsignedLongTy,
+                                             FastEnumSel,
+                                             Collection, false, Args);
+
+  llvm::Value *LimitPtr = CreateMemTemp(getContext().UnsignedLongTy,
+                                        "limit.ptr");
+  Builder.CreateStore(CountRV.getScalarVal(), LimitPtr);
+
+  llvm::BasicBlock *NoElements = createBasicBlock("noelements");
+  llvm::BasicBlock *SetStartMutations = createBasicBlock("setstartmutations");
+
+  llvm::Value *Limit = Builder.CreateLoad(LimitPtr);
+  llvm::Value *Zero = llvm::Constant::getNullValue(UnsignedLongLTy);
+
+  llvm::Value *IsZero = Builder.CreateICmpEQ(Limit, Zero, "iszero");
+  Builder.CreateCondBr(IsZero, NoElements, SetStartMutations);
+
+  EmitBlock(SetStartMutations);
+
+  llvm::Value *StartMutationsPtr = CreateMemTemp(getContext().UnsignedLongTy);
+
+  llvm::Value *StateMutationsPtrPtr =
+    Builder.CreateStructGEP(StatePtr, 2, "mutationsptr.ptr");
+  llvm::Value *StateMutationsPtr = Builder.CreateLoad(StateMutationsPtrPtr,
+                                                      "mutationsptr");
+
+  llvm::Value *StateMutations = Builder.CreateLoad(StateMutationsPtr,
+                                                   "mutations");
+
+  Builder.CreateStore(StateMutations, StartMutationsPtr);
+
+  llvm::BasicBlock *LoopStart = createBasicBlock("loopstart");
+  EmitBlock(LoopStart);
+
+  llvm::Value *CounterPtr = CreateMemTemp(getContext().UnsignedLongTy,
+                                       "counter.ptr");
+  Builder.CreateStore(Zero, CounterPtr);
+
+  llvm::BasicBlock *LoopBody = createBasicBlock("loopbody");
+  EmitBlock(LoopBody);
+
+  StateMutationsPtr = Builder.CreateLoad(StateMutationsPtrPtr, "mutationsptr");
+  StateMutations = Builder.CreateLoad(StateMutationsPtr, "statemutations");
+
+  llvm::Value *StartMutations = Builder.CreateLoad(StartMutationsPtr,
+                                                   "mutations");
+  llvm::Value *MutationsEqual = Builder.CreateICmpEQ(StateMutations,
+                                                     StartMutations,
+                                                     "tobool");
+
+
+  llvm::BasicBlock *WasMutated = createBasicBlock("wasmutated");
+  llvm::BasicBlock *WasNotMutated = createBasicBlock("wasnotmutated");
+
+  Builder.CreateCondBr(MutationsEqual, WasNotMutated, WasMutated);
+
+  EmitBlock(WasMutated);
+  llvm::Value *V =
+    Builder.CreateBitCast(Collection,
+                          ConvertType(getContext().getObjCIdType()),
+                          "tmp");
+  CallArgList Args2;
+  Args2.push_back(std::make_pair(RValue::get(V),
+                                getContext().getObjCIdType()));
+  // FIXME: We shouldn't need to get the function info here, the runtime already
+  // should have computed it to build the function.
+  EmitCall(CGM.getTypes().getFunctionInfo(getContext().VoidTy, Args2,
+                                          FunctionType::ExtInfo()),
+           EnumerationMutationFn, ReturnValueSlot(), Args2);
+
+  EmitBlock(WasNotMutated);
+
+  llvm::Value *StateItemsPtr =
+    Builder.CreateStructGEP(StatePtr, 1, "stateitems.ptr");
+
+  llvm::Value *Counter = Builder.CreateLoad(CounterPtr, "counter");
+
+  llvm::Value *EnumStateItems = Builder.CreateLoad(StateItemsPtr,
+                                                   "stateitems");
+
+  llvm::Value *CurrentItemPtr =
+    Builder.CreateGEP(EnumStateItems, Counter, "currentitem.ptr");
+
+  llvm::Value *CurrentItem = Builder.CreateLoad(CurrentItemPtr, "currentitem");
+
+  // Cast the item to the right type.
+  CurrentItem = Builder.CreateBitCast(CurrentItem,
+                                      ConvertType(ElementTy), "tmp");
+
+  if (!DeclAddress) {
+    LValue LV = EmitLValue(cast<Expr>(S.getElement()));
+
+    // Set the value to null.
+    Builder.CreateStore(CurrentItem, LV.getAddress());
+  } else
+    Builder.CreateStore(CurrentItem, DeclAddress);
+
+  // Increment the counter.
+  Counter = Builder.CreateAdd(Counter,
+                              llvm::ConstantInt::get(UnsignedLongLTy, 1));
+  Builder.CreateStore(Counter, CounterPtr);
+
+  llvm::BasicBlock *LoopEnd = createBasicBlock("loopend");
+  llvm::BasicBlock *AfterBody = createBasicBlock("afterbody");
+
+  BreakContinueStack.push_back(BreakContinue(LoopEnd, AfterBody));
+
+  EmitStmt(S.getBody());
+
+  BreakContinueStack.pop_back();
+
+  EmitBlock(AfterBody);
+
+  llvm::BasicBlock *FetchMore = createBasicBlock("fetchmore");
+
+  Counter = Builder.CreateLoad(CounterPtr);
+  Limit = Builder.CreateLoad(LimitPtr);
+  llvm::Value *IsLess = Builder.CreateICmpULT(Counter, Limit, "isless");
+  Builder.CreateCondBr(IsLess, LoopBody, FetchMore);
+
+  // Fetch more elements.
+  EmitBlock(FetchMore);
+
+  CountRV =
+    CGM.getObjCRuntime().GenerateMessageSend(*this,
+                                             getContext().UnsignedLongTy,
+                                             FastEnumSel,
+                                             Collection, false, Args);
+  Builder.CreateStore(CountRV.getScalarVal(), LimitPtr);
+  Limit = Builder.CreateLoad(LimitPtr);
+
+  IsZero = Builder.CreateICmpEQ(Limit, Zero, "iszero");
+  Builder.CreateCondBr(IsZero, NoElements, LoopStart);
+
+  // No more elements.
+  EmitBlock(NoElements);
+
+  if (!DeclAddress) {
+    // If the element was not a declaration, set it to be null.
+
+    LValue LV = EmitLValue(cast<Expr>(S.getElement()));
+
+    // Set the value to null.
+    Builder.CreateStore(llvm::Constant::getNullValue(ConvertType(ElementTy)),
+                        LV.getAddress());
+  }
+
+  EmitBlock(LoopEnd);
+}
+
+void CodeGenFunction::EmitObjCAtTryStmt(const ObjCAtTryStmt &S) {
+  CGM.getObjCRuntime().EmitTryOrSynchronizedStmt(*this, S);
+}
+
+void CodeGenFunction::EmitObjCAtThrowStmt(const ObjCAtThrowStmt &S) {
+  CGM.getObjCRuntime().EmitThrowStmt(*this, S);
+}
+
+void CodeGenFunction::EmitObjCAtSynchronizedStmt(
+                                              const ObjCAtSynchronizedStmt &S) {
+  CGM.getObjCRuntime().EmitTryOrSynchronizedStmt(*this, S);
+}
+
+CGObjCRuntime::~CGObjCRuntime() {}
diff --git a/lib/CodeGen/CGObjCGNU.cpp b/lib/CodeGen/CGObjCGNU.cpp
new file mode 100644
index 0000000..e8ade2a
--- /dev/null
+++ b/lib/CodeGen/CGObjCGNU.cpp
@@ -0,0 +1,2131 @@
+//===------- CGObjCGNU.cpp - Emit LLVM Code from ASTs for a Module --------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This provides Objective-C code generation targetting the GNU runtime.  The
+// class in this file generates structures used by the GNU Objective-C runtime
+// library.  These structures are defined in objc/objc.h and objc/objc-api.h in
+// the GNU runtime distribution.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CGObjCRuntime.h"
+#include "CodeGenModule.h"
+#include "CodeGenFunction.h"
+
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/RecordLayout.h"
+#include "clang/AST/StmtObjC.h"
+
+#include "llvm/Intrinsics.h"
+#include "llvm/Module.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Target/TargetData.h"
+
+#include <map>
+
+
+using namespace clang;
+using namespace CodeGen;
+using llvm::dyn_cast;
+
+// The version of the runtime that this class targets.  Must match the version
+// in the runtime.
+static const int RuntimeVersion = 8;
+static const int NonFragileRuntimeVersion = 9;
+static const int ProtocolVersion = 2;
+static const int NonFragileProtocolVersion = 3;
+
+namespace {
+class CGObjCGNU : public CodeGen::CGObjCRuntime {
+private:
+  CodeGen::CodeGenModule &CGM;
+  llvm::Module &TheModule;
+  const llvm::PointerType *SelectorTy;
+  const llvm::IntegerType *Int8Ty;
+  const llvm::PointerType *PtrToInt8Ty;
+  const llvm::FunctionType *IMPTy;
+  const llvm::PointerType *IdTy;
+  const llvm::PointerType *PtrToIdTy;
+  CanQualType ASTIdTy;
+  const llvm::IntegerType *IntTy;
+  const llvm::PointerType *PtrTy;
+  const llvm::IntegerType *LongTy;
+  const llvm::PointerType *PtrToIntTy;
+  llvm::GlobalAlias *ClassPtrAlias;
+  llvm::GlobalAlias *MetaClassPtrAlias;
+  std::vector<llvm::Constant*> Classes;
+  std::vector<llvm::Constant*> Categories;
+  std::vector<llvm::Constant*> ConstantStrings;
+  llvm::StringMap<llvm::Constant*> ObjCStrings;
+  llvm::Function *LoadFunction;
+  llvm::StringMap<llvm::Constant*> ExistingProtocols;
+  typedef std::pair<std::string, std::string> TypedSelector;
+  std::map<TypedSelector, llvm::GlobalAlias*> TypedSelectors;
+  llvm::StringMap<llvm::GlobalAlias*> UntypedSelectors;
+  // Selectors that we don't emit in GC mode
+  Selector RetainSel, ReleaseSel, AutoreleaseSel;
+  // Functions used for GC.
+  llvm::Constant *IvarAssignFn, *StrongCastAssignFn, *MemMoveFn, *WeakReadFn, 
+    *WeakAssignFn, *GlobalAssignFn;
+  // Some zeros used for GEPs in lots of places.
+  llvm::Constant *Zeros[2];
+  llvm::Constant *NULLPtr;
+  llvm::LLVMContext &VMContext;
+private:
+  llvm::Constant *GenerateIvarList(
+      const llvm::SmallVectorImpl<llvm::Constant *>  &IvarNames,
+      const llvm::SmallVectorImpl<llvm::Constant *>  &IvarTypes,
+      const llvm::SmallVectorImpl<llvm::Constant *>  &IvarOffsets);
+  llvm::Constant *GenerateMethodList(const std::string &ClassName,
+      const std::string &CategoryName,
+      const llvm::SmallVectorImpl<Selector>  &MethodSels,
+      const llvm::SmallVectorImpl<llvm::Constant *>  &MethodTypes,
+      bool isClassMethodList);
+  llvm::Constant *GenerateEmptyProtocol(const std::string &ProtocolName);
+  llvm::Constant *GeneratePropertyList(const ObjCImplementationDecl *OID,
+        llvm::SmallVectorImpl<Selector> &InstanceMethodSels,
+        llvm::SmallVectorImpl<llvm::Constant*> &InstanceMethodTypes);
+  llvm::Constant *GenerateProtocolList(
+      const llvm::SmallVectorImpl<std::string> &Protocols);
+  // To ensure that all protocols are seen by the runtime, we add a category on
+  // a class defined in the runtime, declaring no methods, but adopting the
+  // protocols.
+  void GenerateProtocolHolderCategory(void);
+  llvm::Constant *GenerateClassStructure(
+      llvm::Constant *MetaClass,
+      llvm::Constant *SuperClass,
+      unsigned info,
+      const char *Name,
+      llvm::Constant *Version,
+      llvm::Constant *InstanceSize,
+      llvm::Constant *IVars,
+      llvm::Constant *Methods,
+      llvm::Constant *Protocols,
+      llvm::Constant *IvarOffsets,
+      llvm::Constant *Properties);
+  llvm::Constant *GenerateProtocolMethodList(
+      const llvm::SmallVectorImpl<llvm::Constant *>  &MethodNames,
+      const llvm::SmallVectorImpl<llvm::Constant *>  &MethodTypes);
+  llvm::Constant *MakeConstantString(const std::string &Str, const std::string
+      &Name="");
+  llvm::Constant *ExportUniqueString(const std::string &Str, const std::string
+          prefix);
+  llvm::Constant *MakeGlobal(const llvm::StructType *Ty,
+    std::vector<llvm::Constant*> &V, llvm::StringRef Name="",
+    llvm::GlobalValue::LinkageTypes linkage=llvm::GlobalValue::InternalLinkage);
+  llvm::Constant *MakeGlobal(const llvm::ArrayType *Ty,
+    std::vector<llvm::Constant*> &V, llvm::StringRef Name="",
+    llvm::GlobalValue::LinkageTypes linkage=llvm::GlobalValue::InternalLinkage);
+  llvm::GlobalVariable *ObjCIvarOffsetVariable(const ObjCInterfaceDecl *ID,
+      const ObjCIvarDecl *Ivar);
+  void EmitClassRef(const std::string &className);
+  llvm::Value* EnforceType(CGBuilderTy B, llvm::Value *V, const llvm::Type *Ty){
+    if (V->getType() == Ty) return V;
+    return B.CreateBitCast(V, Ty);
+  }
+public:
+  CGObjCGNU(CodeGen::CodeGenModule &cgm);
+  virtual llvm::Constant *GenerateConstantString(const StringLiteral *);
+  virtual CodeGen::RValue
+  GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
+                      QualType ResultType,
+                      Selector Sel,
+                      llvm::Value *Receiver,
+                      bool IsClassMessage,
+                      const CallArgList &CallArgs,
+                      const ObjCMethodDecl *Method);
+  virtual CodeGen::RValue
+  GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
+                           QualType ResultType,
+                           Selector Sel,
+                           const ObjCInterfaceDecl *Class,
+                           bool isCategoryImpl,
+                           llvm::Value *Receiver,
+                           bool IsClassMessage,
+                           const CallArgList &CallArgs,
+                           const ObjCMethodDecl *Method);
+  virtual llvm::Value *GetClass(CGBuilderTy &Builder,
+                                const ObjCInterfaceDecl *OID);
+  virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel);
+  virtual llvm::Value *GetSelector(CGBuilderTy &Builder, const ObjCMethodDecl
+      *Method);
+
+  virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD,
+                                         const ObjCContainerDecl *CD);
+  virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD);
+  virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl);
+  virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder,
+                                           const ObjCProtocolDecl *PD);
+  virtual void GenerateProtocol(const ObjCProtocolDecl *PD);
+  virtual llvm::Function *ModuleInitFunction();
+  virtual llvm::Function *GetPropertyGetFunction();
+  virtual llvm::Function *GetPropertySetFunction();
+  virtual llvm::Function *GetCopyStructFunction();
+  virtual llvm::Constant *EnumerationMutationFunction();
+
+  virtual void EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
+                                         const Stmt &S);
+  virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
+                             const ObjCAtThrowStmt &S);
+  virtual llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
+                                         llvm::Value *AddrWeakObj);
+  virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
+                                  llvm::Value *src, llvm::Value *dst);
+  virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
+                                    llvm::Value *src, llvm::Value *dest);
+  virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
+                                    llvm::Value *src, llvm::Value *dest,
+                                    llvm::Value *ivarOffset);
+  virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
+                                        llvm::Value *src, llvm::Value *dest);
+  virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
+                                        llvm::Value *DestPtr,
+                                        llvm::Value *SrcPtr,
+                                        QualType Ty);
+  virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
+                                      QualType ObjectTy,
+                                      llvm::Value *BaseValue,
+                                      const ObjCIvarDecl *Ivar,
+                                      unsigned CVRQualifiers);
+  virtual llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
+                                      const ObjCInterfaceDecl *Interface,
+                                      const ObjCIvarDecl *Ivar);
+};
+} // end anonymous namespace
+
+
+/// Emits a reference to a dummy variable which is emitted with each class.
+/// This ensures that a linker error will be generated when trying to link
+/// together modules where a referenced class is not defined.
+void CGObjCGNU::EmitClassRef(const std::string &className) {
+  std::string symbolRef = "__objc_class_ref_" + className;
+  // Don't emit two copies of the same symbol
+  if (TheModule.getGlobalVariable(symbolRef))
+    return;
+  std::string symbolName = "__objc_class_name_" + className;
+  llvm::GlobalVariable *ClassSymbol = TheModule.getGlobalVariable(symbolName);
+  if (!ClassSymbol) {
+    ClassSymbol = new llvm::GlobalVariable(TheModule, LongTy, false,
+        llvm::GlobalValue::ExternalLinkage, 0, symbolName);
+  }
+  new llvm::GlobalVariable(TheModule, ClassSymbol->getType(), true,
+    llvm::GlobalValue::WeakAnyLinkage, ClassSymbol, symbolRef);
+}
+
+static std::string SymbolNameForClass(const std::string &ClassName) {
+  return "_OBJC_CLASS_" + ClassName;
+}
+
+static std::string SymbolNameForMethod(const std::string &ClassName, const
+  std::string &CategoryName, const std::string &MethodName, bool isClassMethod)
+{
+  std::string MethodNameColonStripped = MethodName;
+  std::replace(MethodNameColonStripped.begin(), MethodNameColonStripped.end(),
+      ':', '_');
+  return std::string(isClassMethod ? "_c_" : "_i_") + ClassName + "_" +
+    CategoryName + "_" + MethodNameColonStripped;
+}
+
+CGObjCGNU::CGObjCGNU(CodeGen::CodeGenModule &cgm)
+  : CGM(cgm), TheModule(CGM.getModule()), ClassPtrAlias(0),
+    MetaClassPtrAlias(0), VMContext(cgm.getLLVMContext()) {
+  IntTy = cast<llvm::IntegerType>(
+      CGM.getTypes().ConvertType(CGM.getContext().IntTy));
+  LongTy = cast<llvm::IntegerType>(
+      CGM.getTypes().ConvertType(CGM.getContext().LongTy));
+
+  Int8Ty = llvm::Type::getInt8Ty(VMContext);
+  // C string type.  Used in lots of places.
+  PtrToInt8Ty = llvm::PointerType::getUnqual(Int8Ty);
+
+  Zeros[0] = llvm::ConstantInt::get(LongTy, 0);
+  Zeros[1] = Zeros[0];
+  NULLPtr = llvm::ConstantPointerNull::get(PtrToInt8Ty);
+  // Get the selector Type.
+  QualType selTy = CGM.getContext().getObjCSelType();
+  if (QualType() == selTy) {
+    SelectorTy = PtrToInt8Ty;
+  } else {
+    SelectorTy = cast<llvm::PointerType>(CGM.getTypes().ConvertType(selTy));
+  }
+
+  PtrToIntTy = llvm::PointerType::getUnqual(IntTy);
+  PtrTy = PtrToInt8Ty;
+
+  // Object type
+  ASTIdTy = CGM.getContext().getCanonicalType(CGM.getContext().getObjCIdType());
+  if (QualType() == ASTIdTy) {
+    IdTy = PtrToInt8Ty;
+  } else {
+    IdTy = cast<llvm::PointerType>(CGM.getTypes().ConvertType(ASTIdTy));
+  }
+  PtrToIdTy = llvm::PointerType::getUnqual(IdTy);
+
+  // IMP type
+  std::vector<const llvm::Type*> IMPArgs;
+  IMPArgs.push_back(IdTy);
+  IMPArgs.push_back(SelectorTy);
+  IMPTy = llvm::FunctionType::get(IdTy, IMPArgs, true);
+
+  if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC) {
+    // Get selectors needed in GC mode
+    RetainSel = GetNullarySelector("retain", CGM.getContext());
+    ReleaseSel = GetNullarySelector("release", CGM.getContext());
+    AutoreleaseSel = GetNullarySelector("autorelease", CGM.getContext());
+
+    // Get functions needed in GC mode
+
+    // id objc_assign_ivar(id, id, ptrdiff_t);
+    std::vector<const llvm::Type*> Args(1, IdTy);
+    Args.push_back(PtrToIdTy);
+    // FIXME: ptrdiff_t
+    Args.push_back(LongTy);
+    llvm::FunctionType *FTy = llvm::FunctionType::get(IdTy, Args, false);
+    IvarAssignFn = CGM.CreateRuntimeFunction(FTy, "objc_assign_ivar");
+    // id objc_assign_strongCast (id, id*)
+    Args.pop_back();
+    FTy = llvm::FunctionType::get(IdTy, Args, false);
+    StrongCastAssignFn = 
+        CGM.CreateRuntimeFunction(FTy, "objc_assign_strongCast");
+    // id objc_assign_global(id, id*);
+    FTy = llvm::FunctionType::get(IdTy, Args, false);
+    GlobalAssignFn = CGM.CreateRuntimeFunction(FTy, "objc_assign_global");
+    // id objc_assign_weak(id, id*);
+    FTy = llvm::FunctionType::get(IdTy, Args, false);
+    WeakAssignFn = CGM.CreateRuntimeFunction(FTy, "objc_assign_weak");
+    // id objc_read_weak(id*);
+    Args.clear();
+    Args.push_back(PtrToIdTy);
+    FTy = llvm::FunctionType::get(IdTy, Args, false);
+    WeakReadFn = CGM.CreateRuntimeFunction(FTy, "objc_read_weak");
+    // void *objc_memmove_collectable(void*, void *, size_t);
+    Args.clear();
+    Args.push_back(PtrToInt8Ty);
+    Args.push_back(PtrToInt8Ty);
+    // FIXME: size_t
+    Args.push_back(LongTy);
+    FTy = llvm::FunctionType::get(IdTy, Args, false);
+    MemMoveFn = CGM.CreateRuntimeFunction(FTy, "objc_memmove_collectable");
+  }
+}
+
+// This has to perform the lookup every time, since posing and related
+// techniques can modify the name -> class mapping.
+llvm::Value *CGObjCGNU::GetClass(CGBuilderTy &Builder,
+                                 const ObjCInterfaceDecl *OID) {
+  llvm::Value *ClassName = CGM.GetAddrOfConstantCString(OID->getNameAsString());
+  // With the incompatible ABI, this will need to be replaced with a direct
+  // reference to the class symbol.  For the compatible nonfragile ABI we are
+  // still performing this lookup at run time but emitting the symbol for the
+  // class externally so that we can make the switch later.
+  EmitClassRef(OID->getNameAsString());
+  ClassName = Builder.CreateStructGEP(ClassName, 0);
+
+  std::vector<const llvm::Type*> Params(1, PtrToInt8Ty);
+  llvm::Constant *ClassLookupFn =
+    CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy,
+                                                      Params,
+                                                      true),
+                              "objc_lookup_class");
+  return Builder.CreateCall(ClassLookupFn, ClassName);
+}
+
+llvm::Value *CGObjCGNU::GetSelector(CGBuilderTy &Builder, Selector Sel) {
+  llvm::GlobalAlias *&US = UntypedSelectors[Sel.getAsString()];
+  if (US == 0)
+    US = new llvm::GlobalAlias(llvm::PointerType::getUnqual(SelectorTy),
+                               llvm::GlobalValue::PrivateLinkage,
+                               ".objc_untyped_selector_alias"+Sel.getAsString(),
+                               NULL, &TheModule);
+
+  return Builder.CreateLoad(US);
+}
+
+llvm::Value *CGObjCGNU::GetSelector(CGBuilderTy &Builder, const ObjCMethodDecl
+    *Method) {
+
+  std::string SelName = Method->getSelector().getAsString();
+  std::string SelTypes;
+  CGM.getContext().getObjCEncodingForMethodDecl(Method, SelTypes);
+  // Typed selectors
+  TypedSelector Selector = TypedSelector(SelName,
+          SelTypes);
+
+  // If it's already cached, return it.
+  if (TypedSelectors[Selector]) {
+    return Builder.CreateLoad(TypedSelectors[Selector]);
+  }
+
+  // If it isn't, cache it.
+  llvm::GlobalAlias *Sel = new llvm::GlobalAlias(
+          llvm::PointerType::getUnqual(SelectorTy),
+          llvm::GlobalValue::PrivateLinkage, ".objc_selector_alias" + SelName,
+          NULL, &TheModule);
+  TypedSelectors[Selector] = Sel;
+
+  return Builder.CreateLoad(Sel);
+}
+
+llvm::Constant *CGObjCGNU::MakeConstantString(const std::string &Str,
+                                              const std::string &Name) {
+  llvm::Constant *ConstStr = CGM.GetAddrOfConstantCString(Str, Name.c_str());
+  return llvm::ConstantExpr::getGetElementPtr(ConstStr, Zeros, 2);
+}
+llvm::Constant *CGObjCGNU::ExportUniqueString(const std::string &Str,
+        const std::string prefix) {
+  std::string name = prefix + Str;
+  llvm::Constant *ConstStr = TheModule.getGlobalVariable(name);
+  if (!ConstStr) {
+    llvm::Constant *value = llvm::ConstantArray::get(VMContext, Str, true);
+    ConstStr = new llvm::GlobalVariable(TheModule, value->getType(), true,
+            llvm::GlobalValue::LinkOnceODRLinkage, value, prefix + Str);
+  }
+  return llvm::ConstantExpr::getGetElementPtr(ConstStr, Zeros, 2);
+}
+
+llvm::Constant *CGObjCGNU::MakeGlobal(const llvm::StructType *Ty,
+    std::vector<llvm::Constant*> &V, llvm::StringRef Name,
+    llvm::GlobalValue::LinkageTypes linkage) {
+  llvm::Constant *C = llvm::ConstantStruct::get(Ty, V);
+  return new llvm::GlobalVariable(TheModule, Ty, false,
+      llvm::GlobalValue::InternalLinkage, C, Name);
+}
+
+llvm::Constant *CGObjCGNU::MakeGlobal(const llvm::ArrayType *Ty,
+    std::vector<llvm::Constant*> &V, llvm::StringRef Name,
+    llvm::GlobalValue::LinkageTypes linkage) {
+  llvm::Constant *C = llvm::ConstantArray::get(Ty, V);
+  return new llvm::GlobalVariable(TheModule, Ty, false,
+                                  llvm::GlobalValue::InternalLinkage, C, Name);
+}
+
+/// Generate an NSConstantString object.
+llvm::Constant *CGObjCGNU::GenerateConstantString(const StringLiteral *SL) {
+
+  std::string Str(SL->getStrData(), SL->getByteLength());
+
+  // Look for an existing one
+  llvm::StringMap<llvm::Constant*>::iterator old = ObjCStrings.find(Str);
+  if (old != ObjCStrings.end())
+    return old->getValue();
+
+  std::vector<llvm::Constant*> Ivars;
+  Ivars.push_back(NULLPtr);
+  Ivars.push_back(MakeConstantString(Str));
+  Ivars.push_back(llvm::ConstantInt::get(IntTy, Str.size()));
+  llvm::Constant *ObjCStr = MakeGlobal(
+    llvm::StructType::get(VMContext, PtrToInt8Ty, PtrToInt8Ty, IntTy, NULL),
+    Ivars, ".objc_str");
+  ObjCStr = llvm::ConstantExpr::getBitCast(ObjCStr, PtrToInt8Ty);
+  ObjCStrings[Str] = ObjCStr;
+  ConstantStrings.push_back(ObjCStr);
+  return ObjCStr;
+}
+
+///Generates a message send where the super is the receiver.  This is a message
+///send to self with special delivery semantics indicating which class's method
+///should be called.
+CodeGen::RValue
+CGObjCGNU::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
+                                    QualType ResultType,
+                                    Selector Sel,
+                                    const ObjCInterfaceDecl *Class,
+                                    bool isCategoryImpl,
+                                    llvm::Value *Receiver,
+                                    bool IsClassMessage,
+                                    const CallArgList &CallArgs,
+                                    const ObjCMethodDecl *Method) {
+  if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC) {
+    if (Sel == RetainSel || Sel == AutoreleaseSel) {
+      return RValue::get(Receiver);
+    }
+    if (Sel == ReleaseSel) {
+      return RValue::get(0);
+    }
+  }
+  llvm::Value *cmd = GetSelector(CGF.Builder, Sel);
+
+  CallArgList ActualArgs;
+
+  ActualArgs.push_back(
+      std::make_pair(RValue::get(CGF.Builder.CreateBitCast(Receiver, IdTy)),
+      ASTIdTy));
+  ActualArgs.push_back(std::make_pair(RValue::get(cmd),
+                                      CGF.getContext().getObjCSelType()));
+  ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end());
+
+  CodeGenTypes &Types = CGM.getTypes();
+  const CGFunctionInfo &FnInfo = Types.getFunctionInfo(ResultType, ActualArgs,
+                                                       FunctionType::ExtInfo());
+  const llvm::FunctionType *impType =
+    Types.GetFunctionType(FnInfo, Method ? Method->isVariadic() : false);
+
+  llvm::Value *ReceiverClass = 0;
+  if (isCategoryImpl) {
+    llvm::Constant *classLookupFunction = 0;
+    std::vector<const llvm::Type*> Params;
+    Params.push_back(PtrTy);
+    if (IsClassMessage)  {
+      classLookupFunction = CGM.CreateRuntimeFunction(llvm::FunctionType::get(
+            IdTy, Params, true), "objc_get_meta_class");
+    } else {
+      classLookupFunction = CGM.CreateRuntimeFunction(llvm::FunctionType::get(
+            IdTy, Params, true), "objc_get_class");
+    }
+    ReceiverClass = CGF.Builder.CreateCall(classLookupFunction,
+        MakeConstantString(Class->getNameAsString()));
+  } else {
+    // Set up global aliases for the metaclass or class pointer if they do not
+    // already exist.  These will are forward-references which will be set to
+    // pointers to the class and metaclass structure created for the runtime
+    // load function.  To send a message to super, we look up the value of the
+    // super_class pointer from either the class or metaclass structure.
+    if (IsClassMessage)  {
+      if (!MetaClassPtrAlias) {
+        MetaClassPtrAlias = new llvm::GlobalAlias(IdTy,
+            llvm::GlobalValue::InternalLinkage, ".objc_metaclass_ref" +
+            Class->getNameAsString(), NULL, &TheModule);
+      }
+      ReceiverClass = MetaClassPtrAlias;
+    } else {
+      if (!ClassPtrAlias) {
+        ClassPtrAlias = new llvm::GlobalAlias(IdTy,
+            llvm::GlobalValue::InternalLinkage, ".objc_class_ref" +
+            Class->getNameAsString(), NULL, &TheModule);
+      }
+      ReceiverClass = ClassPtrAlias;
+    }
+  }
+  // Cast the pointer to a simplified version of the class structure
+  ReceiverClass = CGF.Builder.CreateBitCast(ReceiverClass,
+      llvm::PointerType::getUnqual(
+        llvm::StructType::get(VMContext, IdTy, IdTy, NULL)));
+  // Get the superclass pointer
+  ReceiverClass = CGF.Builder.CreateStructGEP(ReceiverClass, 1);
+  // Load the superclass pointer
+  ReceiverClass = CGF.Builder.CreateLoad(ReceiverClass);
+  // Construct the structure used to look up the IMP
+  llvm::StructType *ObjCSuperTy = llvm::StructType::get(VMContext,
+      Receiver->getType(), IdTy, NULL);
+  llvm::Value *ObjCSuper = CGF.Builder.CreateAlloca(ObjCSuperTy);
+
+  CGF.Builder.CreateStore(Receiver, CGF.Builder.CreateStructGEP(ObjCSuper, 0));
+  CGF.Builder.CreateStore(ReceiverClass,
+      CGF.Builder.CreateStructGEP(ObjCSuper, 1));
+
+  // Get the IMP
+  std::vector<const llvm::Type*> Params;
+  Params.push_back(llvm::PointerType::getUnqual(ObjCSuperTy));
+  Params.push_back(SelectorTy);
+  llvm::Constant *lookupFunction =
+    CGM.CreateRuntimeFunction(llvm::FunctionType::get(
+          llvm::PointerType::getUnqual(impType), Params, true),
+        "objc_msg_lookup_super");
+
+  llvm::Value *lookupArgs[] = {ObjCSuper, cmd};
+  llvm::Value *imp = CGF.Builder.CreateCall(lookupFunction, lookupArgs,
+      lookupArgs+2);
+
+  return CGF.EmitCall(FnInfo, imp, ReturnValueSlot(), ActualArgs);
+}
+
+/// Generate code for a message send expression.
+CodeGen::RValue
+CGObjCGNU::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
+                               QualType ResultType,
+                               Selector Sel,
+                               llvm::Value *Receiver,
+                               bool IsClassMessage,
+                               const CallArgList &CallArgs,
+                               const ObjCMethodDecl *Method) {
+  if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC) {
+    if (Sel == RetainSel || Sel == AutoreleaseSel) {
+      return RValue::get(Receiver);
+    }
+    if (Sel == ReleaseSel) {
+      return RValue::get(0);
+    }
+  }
+  CGBuilderTy &Builder = CGF.Builder;
+  IdTy = cast<llvm::PointerType>(CGM.getTypes().ConvertType(ASTIdTy));
+  llvm::Value *cmd;
+  if (Method)
+    cmd = GetSelector(Builder, Method);
+  else
+    cmd = GetSelector(Builder, Sel);
+  CallArgList ActualArgs;
+
+  Receiver = Builder.CreateBitCast(Receiver, IdTy);
+  ActualArgs.push_back(
+    std::make_pair(RValue::get(Receiver), ASTIdTy));
+  ActualArgs.push_back(std::make_pair(RValue::get(cmd),
+                                      CGF.getContext().getObjCSelType()));
+  ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end());
+
+  CodeGenTypes &Types = CGM.getTypes();
+  const CGFunctionInfo &FnInfo = Types.getFunctionInfo(ResultType, ActualArgs,
+                                                       FunctionType::ExtInfo());
+  const llvm::FunctionType *impType =
+    Types.GetFunctionType(FnInfo, Method ? Method->isVariadic() : false);
+
+  llvm::Value *imp;
+  // For sender-aware dispatch, we pass the sender as the third argument to a
+  // lookup function.  When sending messages from C code, the sender is nil.
+  // objc_msg_lookup_sender(id *receiver, SEL selector, id sender);
+  if (CGM.getContext().getLangOptions().ObjCNonFragileABI) {
+
+    std::vector<const llvm::Type*> Params;
+    llvm::Value *ReceiverPtr = CGF.CreateTempAlloca(Receiver->getType());
+    Builder.CreateStore(Receiver, ReceiverPtr);
+    Params.push_back(ReceiverPtr->getType());
+    Params.push_back(SelectorTy);
+    llvm::Value *self;
+
+    if (isa<ObjCMethodDecl>(CGF.CurFuncDecl)) {
+      self = CGF.LoadObjCSelf();
+    } else {
+      self = llvm::ConstantPointerNull::get(IdTy);
+    }
+
+    Params.push_back(self->getType());
+
+    // The lookup function returns a slot, which can be safely cached.
+    llvm::Type *SlotTy = llvm::StructType::get(VMContext, PtrTy, PtrTy, PtrTy,
+            IntTy, llvm::PointerType::getUnqual(impType), NULL);
+    llvm::Constant *lookupFunction =
+      CGM.CreateRuntimeFunction(llvm::FunctionType::get(
+          llvm::PointerType::getUnqual(SlotTy), Params, true),
+        "objc_msg_lookup_sender");
+
+    // The lookup function is guaranteed not to capture the receiver pointer.
+    if (llvm::Function *LookupFn = dyn_cast<llvm::Function>(lookupFunction)) {
+      LookupFn->setDoesNotCapture(1);
+    }
+
+    llvm::Value *slot =
+        Builder.CreateCall3(lookupFunction, ReceiverPtr, cmd, self);
+    imp = Builder.CreateLoad(Builder.CreateStructGEP(slot, 4));
+    // The lookup function may have changed the receiver, so make sure we use
+    // the new one.
+    ActualArgs[0] =
+        std::make_pair(RValue::get(Builder.CreateLoad(ReceiverPtr)), ASTIdTy);
+  } else {
+    std::vector<const llvm::Type*> Params;
+    Params.push_back(Receiver->getType());
+    Params.push_back(SelectorTy);
+    llvm::Constant *lookupFunction =
+    CGM.CreateRuntimeFunction(llvm::FunctionType::get(
+        llvm::PointerType::getUnqual(impType), Params, true),
+      "objc_msg_lookup");
+
+    imp = Builder.CreateCall2(lookupFunction, Receiver, cmd);
+  }
+
+  return CGF.EmitCall(FnInfo, imp, ReturnValueSlot(), ActualArgs);
+}
+
+/// Generates a MethodList.  Used in construction of a objc_class and
+/// objc_category structures.
+llvm::Constant *CGObjCGNU::GenerateMethodList(const std::string &ClassName,
+                                              const std::string &CategoryName,
+    const llvm::SmallVectorImpl<Selector> &MethodSels,
+    const llvm::SmallVectorImpl<llvm::Constant *> &MethodTypes,
+    bool isClassMethodList) {
+  if (MethodSels.empty())
+    return NULLPtr;
+  // Get the method structure type.
+  llvm::StructType *ObjCMethodTy = llvm::StructType::get(VMContext,
+    PtrToInt8Ty, // Really a selector, but the runtime creates it us.
+    PtrToInt8Ty, // Method types
+    llvm::PointerType::getUnqual(IMPTy), //Method pointer
+    NULL);
+  std::vector<llvm::Constant*> Methods;
+  std::vector<llvm::Constant*> Elements;
+  for (unsigned int i = 0, e = MethodTypes.size(); i < e; ++i) {
+    Elements.clear();
+    if (llvm::Constant *Method =
+      TheModule.getFunction(SymbolNameForMethod(ClassName, CategoryName,
+                                                MethodSels[i].getAsString(),
+                                                isClassMethodList))) {
+      llvm::Constant *C = MakeConstantString(MethodSels[i].getAsString());
+      Elements.push_back(C);
+      Elements.push_back(MethodTypes[i]);
+      Method = llvm::ConstantExpr::getBitCast(Method,
+          llvm::PointerType::getUnqual(IMPTy));
+      Elements.push_back(Method);
+      Methods.push_back(llvm::ConstantStruct::get(ObjCMethodTy, Elements));
+    }
+  }
+
+  // Array of method structures
+  llvm::ArrayType *ObjCMethodArrayTy = llvm::ArrayType::get(ObjCMethodTy,
+                                                            Methods.size());
+  llvm::Constant *MethodArray = llvm::ConstantArray::get(ObjCMethodArrayTy,
+                                                         Methods);
+
+  // Structure containing list pointer, array and array count
+  llvm::SmallVector<const llvm::Type*, 16> ObjCMethodListFields;
+  llvm::PATypeHolder OpaqueNextTy = llvm::OpaqueType::get(VMContext);
+  llvm::Type *NextPtrTy = llvm::PointerType::getUnqual(OpaqueNextTy);
+  llvm::StructType *ObjCMethodListTy = llvm::StructType::get(VMContext,
+      NextPtrTy,
+      IntTy,
+      ObjCMethodArrayTy,
+      NULL);
+  // Refine next pointer type to concrete type
+  llvm::cast<llvm::OpaqueType>(
+      OpaqueNextTy.get())->refineAbstractTypeTo(ObjCMethodListTy);
+  ObjCMethodListTy = llvm::cast<llvm::StructType>(OpaqueNextTy.get());
+
+  Methods.clear();
+  Methods.push_back(llvm::ConstantPointerNull::get(
+        llvm::PointerType::getUnqual(ObjCMethodListTy)));
+  Methods.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext),
+        MethodTypes.size()));
+  Methods.push_back(MethodArray);
+
+  // Create an instance of the structure
+  return MakeGlobal(ObjCMethodListTy, Methods, ".objc_method_list");
+}
+
+/// Generates an IvarList.  Used in construction of a objc_class.
+llvm::Constant *CGObjCGNU::GenerateIvarList(
+    const llvm::SmallVectorImpl<llvm::Constant *>  &IvarNames,
+    const llvm::SmallVectorImpl<llvm::Constant *>  &IvarTypes,
+    const llvm::SmallVectorImpl<llvm::Constant *>  &IvarOffsets) {
+  if (IvarNames.size() == 0)
+    return NULLPtr;
+  // Get the method structure type.
+  llvm::StructType *ObjCIvarTy = llvm::StructType::get(VMContext,
+    PtrToInt8Ty,
+    PtrToInt8Ty,
+    IntTy,
+    NULL);
+  std::vector<llvm::Constant*> Ivars;
+  std::vector<llvm::Constant*> Elements;
+  for (unsigned int i = 0, e = IvarNames.size() ; i < e ; i++) {
+    Elements.clear();
+    Elements.push_back(IvarNames[i]);
+    Elements.push_back(IvarTypes[i]);
+    Elements.push_back(IvarOffsets[i]);
+    Ivars.push_back(llvm::ConstantStruct::get(ObjCIvarTy, Elements));
+  }
+
+  // Array of method structures
+  llvm::ArrayType *ObjCIvarArrayTy = llvm::ArrayType::get(ObjCIvarTy,
+      IvarNames.size());
+
+
+  Elements.clear();
+  Elements.push_back(llvm::ConstantInt::get(IntTy, (int)IvarNames.size()));
+  Elements.push_back(llvm::ConstantArray::get(ObjCIvarArrayTy, Ivars));
+  // Structure containing array and array count
+  llvm::StructType *ObjCIvarListTy = llvm::StructType::get(VMContext, IntTy,
+    ObjCIvarArrayTy,
+    NULL);
+
+  // Create an instance of the structure
+  return MakeGlobal(ObjCIvarListTy, Elements, ".objc_ivar_list");
+}
+
+/// Generate a class structure
+llvm::Constant *CGObjCGNU::GenerateClassStructure(
+    llvm::Constant *MetaClass,
+    llvm::Constant *SuperClass,
+    unsigned info,
+    const char *Name,
+    llvm::Constant *Version,
+    llvm::Constant *InstanceSize,
+    llvm::Constant *IVars,
+    llvm::Constant *Methods,
+    llvm::Constant *Protocols,
+    llvm::Constant *IvarOffsets,
+    llvm::Constant *Properties) {
+  // Set up the class structure
+  // Note:  Several of these are char*s when they should be ids.  This is
+  // because the runtime performs this translation on load.
+  //
+  // Fields marked New ABI are part of the GNUstep runtime.  We emit them
+  // anyway; the classes will still work with the GNU runtime, they will just
+  // be ignored.
+  llvm::StructType *ClassTy = llvm::StructType::get(VMContext,
+      PtrToInt8Ty,        // class_pointer
+      PtrToInt8Ty,        // super_class
+      PtrToInt8Ty,        // name
+      LongTy,             // version
+      LongTy,             // info
+      LongTy,             // instance_size
+      IVars->getType(),   // ivars
+      Methods->getType(), // methods
+      // These are all filled in by the runtime, so we pretend
+      PtrTy,              // dtable
+      PtrTy,              // subclass_list
+      PtrTy,              // sibling_class
+      PtrTy,              // protocols
+      PtrTy,              // gc_object_type
+      // New ABI:
+      LongTy,                 // abi_version
+      IvarOffsets->getType(), // ivar_offsets
+      Properties->getType(),  // properties
+      NULL);
+  llvm::Constant *Zero = llvm::ConstantInt::get(LongTy, 0);
+  // Fill in the structure
+  std::vector<llvm::Constant*> Elements;
+  Elements.push_back(llvm::ConstantExpr::getBitCast(MetaClass, PtrToInt8Ty));
+  Elements.push_back(SuperClass);
+  Elements.push_back(MakeConstantString(Name, ".class_name"));
+  Elements.push_back(Zero);
+  Elements.push_back(llvm::ConstantInt::get(LongTy, info));
+  Elements.push_back(InstanceSize);
+  Elements.push_back(IVars);
+  Elements.push_back(Methods);
+  Elements.push_back(NULLPtr);
+  Elements.push_back(NULLPtr);
+  Elements.push_back(NULLPtr);
+  Elements.push_back(llvm::ConstantExpr::getBitCast(Protocols, PtrTy));
+  Elements.push_back(NULLPtr);
+  Elements.push_back(Zero);
+  Elements.push_back(IvarOffsets);
+  Elements.push_back(Properties);
+  // Create an instance of the structure
+  // This is now an externally visible symbol, so that we can speed up class
+  // messages in the next ABI.
+  return MakeGlobal(ClassTy, Elements, SymbolNameForClass(Name),
+         llvm::GlobalValue::ExternalLinkage);
+}
+
+llvm::Constant *CGObjCGNU::GenerateProtocolMethodList(
+    const llvm::SmallVectorImpl<llvm::Constant *>  &MethodNames,
+    const llvm::SmallVectorImpl<llvm::Constant *>  &MethodTypes) {
+  // Get the method structure type.
+  llvm::StructType *ObjCMethodDescTy = llvm::StructType::get(VMContext,
+    PtrToInt8Ty, // Really a selector, but the runtime does the casting for us.
+    PtrToInt8Ty,
+    NULL);
+  std::vector<llvm::Constant*> Methods;
+  std::vector<llvm::Constant*> Elements;
+  for (unsigned int i = 0, e = MethodTypes.size() ; i < e ; i++) {
+    Elements.clear();
+    Elements.push_back(MethodNames[i]);
+    Elements.push_back(MethodTypes[i]);
+    Methods.push_back(llvm::ConstantStruct::get(ObjCMethodDescTy, Elements));
+  }
+  llvm::ArrayType *ObjCMethodArrayTy = llvm::ArrayType::get(ObjCMethodDescTy,
+      MethodNames.size());
+  llvm::Constant *Array = llvm::ConstantArray::get(ObjCMethodArrayTy,
+                                                   Methods);
+  llvm::StructType *ObjCMethodDescListTy = llvm::StructType::get(VMContext,
+      IntTy, ObjCMethodArrayTy, NULL);
+  Methods.clear();
+  Methods.push_back(llvm::ConstantInt::get(IntTy, MethodNames.size()));
+  Methods.push_back(Array);
+  return MakeGlobal(ObjCMethodDescListTy, Methods, ".objc_method_list");
+}
+
+// Create the protocol list structure used in classes, categories and so on
+llvm::Constant *CGObjCGNU::GenerateProtocolList(
+    const llvm::SmallVectorImpl<std::string> &Protocols) {
+  llvm::ArrayType *ProtocolArrayTy = llvm::ArrayType::get(PtrToInt8Ty,
+      Protocols.size());
+  llvm::StructType *ProtocolListTy = llvm::StructType::get(VMContext,
+      PtrTy, //Should be a recurisve pointer, but it's always NULL here.
+      LongTy,//FIXME: Should be size_t
+      ProtocolArrayTy,
+      NULL);
+  std::vector<llvm::Constant*> Elements;
+  for (const std::string *iter = Protocols.begin(), *endIter = Protocols.end();
+      iter != endIter ; iter++) {
+    llvm::Constant *protocol = 0;
+    llvm::StringMap<llvm::Constant*>::iterator value =
+      ExistingProtocols.find(*iter);
+    if (value == ExistingProtocols.end()) {
+      protocol = GenerateEmptyProtocol(*iter);
+    } else {
+      protocol = value->getValue();
+    }
+    llvm::Constant *Ptr = llvm::ConstantExpr::getBitCast(protocol,
+                                                           PtrToInt8Ty);
+    Elements.push_back(Ptr);
+  }
+  llvm::Constant * ProtocolArray = llvm::ConstantArray::get(ProtocolArrayTy,
+      Elements);
+  Elements.clear();
+  Elements.push_back(NULLPtr);
+  Elements.push_back(llvm::ConstantInt::get(LongTy, Protocols.size()));
+  Elements.push_back(ProtocolArray);
+  return MakeGlobal(ProtocolListTy, Elements, ".objc_protocol_list");
+}
+
+llvm::Value *CGObjCGNU::GenerateProtocolRef(CGBuilderTy &Builder,
+                                            const ObjCProtocolDecl *PD) {
+  llvm::Value *protocol = ExistingProtocols[PD->getNameAsString()];
+  const llvm::Type *T =
+    CGM.getTypes().ConvertType(CGM.getContext().getObjCProtoType());
+  return Builder.CreateBitCast(protocol, llvm::PointerType::getUnqual(T));
+}
+
+llvm::Constant *CGObjCGNU::GenerateEmptyProtocol(
+  const std::string &ProtocolName) {
+  llvm::SmallVector<std::string, 0> EmptyStringVector;
+  llvm::SmallVector<llvm::Constant*, 0> EmptyConstantVector;
+
+  llvm::Constant *ProtocolList = GenerateProtocolList(EmptyStringVector);
+  llvm::Constant *MethodList =
+    GenerateProtocolMethodList(EmptyConstantVector, EmptyConstantVector);
+  // Protocols are objects containing lists of the methods implemented and
+  // protocols adopted.
+  llvm::StructType *ProtocolTy = llvm::StructType::get(VMContext, IdTy,
+      PtrToInt8Ty,
+      ProtocolList->getType(),
+      MethodList->getType(),
+      MethodList->getType(),
+      MethodList->getType(),
+      MethodList->getType(),
+      NULL);
+  std::vector<llvm::Constant*> Elements;
+  // The isa pointer must be set to a magic number so the runtime knows it's
+  // the correct layout.
+  int Version = CGM.getContext().getLangOptions().ObjCNonFragileABI ?
+      NonFragileProtocolVersion : ProtocolVersion;
+  Elements.push_back(llvm::ConstantExpr::getIntToPtr(
+        llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), Version), IdTy));
+  Elements.push_back(MakeConstantString(ProtocolName, ".objc_protocol_name"));
+  Elements.push_back(ProtocolList);
+  Elements.push_back(MethodList);
+  Elements.push_back(MethodList);
+  Elements.push_back(MethodList);
+  Elements.push_back(MethodList);
+  return MakeGlobal(ProtocolTy, Elements, ".objc_protocol");
+}
+
+void CGObjCGNU::GenerateProtocol(const ObjCProtocolDecl *PD) {
+  ASTContext &Context = CGM.getContext();
+  std::string ProtocolName = PD->getNameAsString();
+  llvm::SmallVector<std::string, 16> Protocols;
+  for (ObjCProtocolDecl::protocol_iterator PI = PD->protocol_begin(),
+       E = PD->protocol_end(); PI != E; ++PI)
+    Protocols.push_back((*PI)->getNameAsString());
+  llvm::SmallVector<llvm::Constant*, 16> InstanceMethodNames;
+  llvm::SmallVector<llvm::Constant*, 16> InstanceMethodTypes;
+  llvm::SmallVector<llvm::Constant*, 16> OptionalInstanceMethodNames;
+  llvm::SmallVector<llvm::Constant*, 16> OptionalInstanceMethodTypes;
+  for (ObjCProtocolDecl::instmeth_iterator iter = PD->instmeth_begin(),
+       E = PD->instmeth_end(); iter != E; iter++) {
+    std::string TypeStr;
+    Context.getObjCEncodingForMethodDecl(*iter, TypeStr);
+    if ((*iter)->getImplementationControl() == ObjCMethodDecl::Optional) {
+      InstanceMethodNames.push_back(
+          MakeConstantString((*iter)->getSelector().getAsString()));
+      InstanceMethodTypes.push_back(MakeConstantString(TypeStr));
+    } else {
+      OptionalInstanceMethodNames.push_back(
+          MakeConstantString((*iter)->getSelector().getAsString()));
+      OptionalInstanceMethodTypes.push_back(MakeConstantString(TypeStr));
+    }
+  }
+  // Collect information about class methods:
+  llvm::SmallVector<llvm::Constant*, 16> ClassMethodNames;
+  llvm::SmallVector<llvm::Constant*, 16> ClassMethodTypes;
+  llvm::SmallVector<llvm::Constant*, 16> OptionalClassMethodNames;
+  llvm::SmallVector<llvm::Constant*, 16> OptionalClassMethodTypes;
+  for (ObjCProtocolDecl::classmeth_iterator
+         iter = PD->classmeth_begin(), endIter = PD->classmeth_end();
+       iter != endIter ; iter++) {
+    std::string TypeStr;
+    Context.getObjCEncodingForMethodDecl((*iter),TypeStr);
+    if ((*iter)->getImplementationControl() == ObjCMethodDecl::Optional) {
+      ClassMethodNames.push_back(
+          MakeConstantString((*iter)->getSelector().getAsString()));
+      ClassMethodTypes.push_back(MakeConstantString(TypeStr));
+    } else {
+      OptionalClassMethodNames.push_back(
+          MakeConstantString((*iter)->getSelector().getAsString()));
+      OptionalClassMethodTypes.push_back(MakeConstantString(TypeStr));
+    }
+  }
+
+  llvm::Constant *ProtocolList = GenerateProtocolList(Protocols);
+  llvm::Constant *InstanceMethodList =
+    GenerateProtocolMethodList(InstanceMethodNames, InstanceMethodTypes);
+  llvm::Constant *ClassMethodList =
+    GenerateProtocolMethodList(ClassMethodNames, ClassMethodTypes);
+  llvm::Constant *OptionalInstanceMethodList =
+    GenerateProtocolMethodList(OptionalInstanceMethodNames,
+            OptionalInstanceMethodTypes);
+  llvm::Constant *OptionalClassMethodList =
+    GenerateProtocolMethodList(OptionalClassMethodNames,
+            OptionalClassMethodTypes);
+
+  // Property metadata: name, attributes, isSynthesized, setter name, setter
+  // types, getter name, getter types.
+  // The isSynthesized value is always set to 0 in a protocol.  It exists to
+  // simplify the runtime library by allowing it to use the same data
+  // structures for protocol metadata everywhere.
+  llvm::StructType *PropertyMetadataTy = llvm::StructType::get(VMContext,
+          PtrToInt8Ty, Int8Ty, Int8Ty, PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty,
+          PtrToInt8Ty, NULL);
+  std::vector<llvm::Constant*> Properties;
+  std::vector<llvm::Constant*> OptionalProperties;
+
+  // Add all of the property methods need adding to the method list and to the
+  // property metadata list.
+  for (ObjCContainerDecl::prop_iterator
+         iter = PD->prop_begin(), endIter = PD->prop_end();
+       iter != endIter ; iter++) {
+    std::vector<llvm::Constant*> Fields;
+    ObjCPropertyDecl *property = (*iter);
+
+    Fields.push_back(MakeConstantString(property->getNameAsString()));
+    Fields.push_back(llvm::ConstantInt::get(Int8Ty,
+                property->getPropertyAttributes()));
+    Fields.push_back(llvm::ConstantInt::get(Int8Ty, 0));
+    if (ObjCMethodDecl *getter = property->getGetterMethodDecl()) {
+      std::string TypeStr;
+      Context.getObjCEncodingForMethodDecl(getter,TypeStr);
+      llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);
+      InstanceMethodTypes.push_back(TypeEncoding);
+      Fields.push_back(MakeConstantString(getter->getSelector().getAsString()));
+      Fields.push_back(TypeEncoding);
+    } else {
+      Fields.push_back(NULLPtr);
+      Fields.push_back(NULLPtr);
+    }
+    if (ObjCMethodDecl *setter = property->getSetterMethodDecl()) {
+      std::string TypeStr;
+      Context.getObjCEncodingForMethodDecl(setter,TypeStr);
+      llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);
+      InstanceMethodTypes.push_back(TypeEncoding);
+      Fields.push_back(MakeConstantString(setter->getSelector().getAsString()));
+      Fields.push_back(TypeEncoding);
+    } else {
+      Fields.push_back(NULLPtr);
+      Fields.push_back(NULLPtr);
+    }
+    if (property->getPropertyImplementation() == ObjCPropertyDecl::Optional) {
+      OptionalProperties.push_back(llvm::ConstantStruct::get(PropertyMetadataTy, Fields));
+    } else {
+      Properties.push_back(llvm::ConstantStruct::get(PropertyMetadataTy, Fields));
+    }
+  }
+  llvm::Constant *PropertyArray = llvm::ConstantArray::get(
+      llvm::ArrayType::get(PropertyMetadataTy, Properties.size()), Properties);
+  llvm::Constant* PropertyListInitFields[] =
+    {llvm::ConstantInt::get(IntTy, Properties.size()), NULLPtr, PropertyArray};
+
+  llvm::Constant *PropertyListInit =
+      llvm::ConstantStruct::get(VMContext, PropertyListInitFields, 3, false);
+  llvm::Constant *PropertyList = new llvm::GlobalVariable(TheModule,
+      PropertyListInit->getType(), false, llvm::GlobalValue::InternalLinkage,
+      PropertyListInit, ".objc_property_list");
+
+  llvm::Constant *OptionalPropertyArray =
+      llvm::ConstantArray::get(llvm::ArrayType::get(PropertyMetadataTy,
+          OptionalProperties.size()) , OptionalProperties);
+  llvm::Constant* OptionalPropertyListInitFields[] = {
+      llvm::ConstantInt::get(IntTy, OptionalProperties.size()), NULLPtr,
+      OptionalPropertyArray };
+
+  llvm::Constant *OptionalPropertyListInit =
+      llvm::ConstantStruct::get(VMContext, OptionalPropertyListInitFields, 3, false);
+  llvm::Constant *OptionalPropertyList = new llvm::GlobalVariable(TheModule,
+          OptionalPropertyListInit->getType(), false,
+          llvm::GlobalValue::InternalLinkage, OptionalPropertyListInit,
+          ".objc_property_list");
+
+  // Protocols are objects containing lists of the methods implemented and
+  // protocols adopted.
+  llvm::StructType *ProtocolTy = llvm::StructType::get(VMContext, IdTy,
+      PtrToInt8Ty,
+      ProtocolList->getType(),
+      InstanceMethodList->getType(),
+      ClassMethodList->getType(),
+      OptionalInstanceMethodList->getType(),
+      OptionalClassMethodList->getType(),
+      PropertyList->getType(),
+      OptionalPropertyList->getType(),
+      NULL);
+  std::vector<llvm::Constant*> Elements;
+  // The isa pointer must be set to a magic number so the runtime knows it's
+  // the correct layout.
+  int Version = CGM.getContext().getLangOptions().ObjCNonFragileABI ?
+      NonFragileProtocolVersion : ProtocolVersion;
+  Elements.push_back(llvm::ConstantExpr::getIntToPtr(
+        llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), Version), IdTy));
+  Elements.push_back(MakeConstantString(ProtocolName, ".objc_protocol_name"));
+  Elements.push_back(ProtocolList);
+  Elements.push_back(InstanceMethodList);
+  Elements.push_back(ClassMethodList);
+  Elements.push_back(OptionalInstanceMethodList);
+  Elements.push_back(OptionalClassMethodList);
+  Elements.push_back(PropertyList);
+  Elements.push_back(OptionalPropertyList);
+  ExistingProtocols[ProtocolName] =
+    llvm::ConstantExpr::getBitCast(MakeGlobal(ProtocolTy, Elements,
+          ".objc_protocol"), IdTy);
+}
+void CGObjCGNU::GenerateProtocolHolderCategory(void) {
+  // Collect information about instance methods
+  llvm::SmallVector<Selector, 1> MethodSels;
+  llvm::SmallVector<llvm::Constant*, 1> MethodTypes;
+
+  std::vector<llvm::Constant*> Elements;
+  const std::string ClassName = "__ObjC_Protocol_Holder_Ugly_Hack";
+  const std::string CategoryName = "AnotherHack";
+  Elements.push_back(MakeConstantString(CategoryName));
+  Elements.push_back(MakeConstantString(ClassName));
+  // Instance method list
+  Elements.push_back(llvm::ConstantExpr::getBitCast(GenerateMethodList(
+          ClassName, CategoryName, MethodSels, MethodTypes, false), PtrTy));
+  // Class method list
+  Elements.push_back(llvm::ConstantExpr::getBitCast(GenerateMethodList(
+          ClassName, CategoryName, MethodSels, MethodTypes, true), PtrTy));
+  // Protocol list
+  llvm::ArrayType *ProtocolArrayTy = llvm::ArrayType::get(PtrTy,
+      ExistingProtocols.size());
+  llvm::StructType *ProtocolListTy = llvm::StructType::get(VMContext,
+      PtrTy, //Should be a recurisve pointer, but it's always NULL here.
+      LongTy,//FIXME: Should be size_t
+      ProtocolArrayTy,
+      NULL);
+  std::vector<llvm::Constant*> ProtocolElements;
+  for (llvm::StringMapIterator<llvm::Constant*> iter =
+       ExistingProtocols.begin(), endIter = ExistingProtocols.end();
+       iter != endIter ; iter++) {
+    llvm::Constant *Ptr = llvm::ConstantExpr::getBitCast(iter->getValue(),
+            PtrTy);
+    ProtocolElements.push_back(Ptr);
+  }
+  llvm::Constant * ProtocolArray = llvm::ConstantArray::get(ProtocolArrayTy,
+      ProtocolElements);
+  ProtocolElements.clear();
+  ProtocolElements.push_back(NULLPtr);
+  ProtocolElements.push_back(llvm::ConstantInt::get(LongTy,
+              ExistingProtocols.size()));
+  ProtocolElements.push_back(ProtocolArray);
+  Elements.push_back(llvm::ConstantExpr::getBitCast(MakeGlobal(ProtocolListTy,
+                  ProtocolElements, ".objc_protocol_list"), PtrTy));
+  Categories.push_back(llvm::ConstantExpr::getBitCast(
+        MakeGlobal(llvm::StructType::get(VMContext, PtrToInt8Ty, PtrToInt8Ty,
+            PtrTy, PtrTy, PtrTy, NULL), Elements), PtrTy));
+}
+
+void CGObjCGNU::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
+  std::string ClassName = OCD->getClassInterface()->getNameAsString();
+  std::string CategoryName = OCD->getNameAsString();
+  // Collect information about instance methods
+  llvm::SmallVector<Selector, 16> InstanceMethodSels;
+  llvm::SmallVector<llvm::Constant*, 16> InstanceMethodTypes;
+  for (ObjCCategoryImplDecl::instmeth_iterator
+         iter = OCD->instmeth_begin(), endIter = OCD->instmeth_end();
+       iter != endIter ; iter++) {
+    InstanceMethodSels.push_back((*iter)->getSelector());
+    std::string TypeStr;
+    CGM.getContext().getObjCEncodingForMethodDecl(*iter,TypeStr);
+    InstanceMethodTypes.push_back(MakeConstantString(TypeStr));
+  }
+
+  // Collect information about class methods
+  llvm::SmallVector<Selector, 16> ClassMethodSels;
+  llvm::SmallVector<llvm::Constant*, 16> ClassMethodTypes;
+  for (ObjCCategoryImplDecl::classmeth_iterator
+         iter = OCD->classmeth_begin(), endIter = OCD->classmeth_end();
+       iter != endIter ; iter++) {
+    ClassMethodSels.push_back((*iter)->getSelector());
+    std::string TypeStr;
+    CGM.getContext().getObjCEncodingForMethodDecl(*iter,TypeStr);
+    ClassMethodTypes.push_back(MakeConstantString(TypeStr));
+  }
+
+  // Collect the names of referenced protocols
+  llvm::SmallVector<std::string, 16> Protocols;
+  const ObjCCategoryDecl *CatDecl = OCD->getCategoryDecl();
+  const ObjCList<ObjCProtocolDecl> &Protos = CatDecl->getReferencedProtocols();
+  for (ObjCList<ObjCProtocolDecl>::iterator I = Protos.begin(),
+       E = Protos.end(); I != E; ++I)
+    Protocols.push_back((*I)->getNameAsString());
+
+  std::vector<llvm::Constant*> Elements;
+  Elements.push_back(MakeConstantString(CategoryName));
+  Elements.push_back(MakeConstantString(ClassName));
+  // Instance method list
+  Elements.push_back(llvm::ConstantExpr::getBitCast(GenerateMethodList(
+          ClassName, CategoryName, InstanceMethodSels, InstanceMethodTypes,
+          false), PtrTy));
+  // Class method list
+  Elements.push_back(llvm::ConstantExpr::getBitCast(GenerateMethodList(
+          ClassName, CategoryName, ClassMethodSels, ClassMethodTypes, true),
+        PtrTy));
+  // Protocol list
+  Elements.push_back(llvm::ConstantExpr::getBitCast(
+        GenerateProtocolList(Protocols), PtrTy));
+  Categories.push_back(llvm::ConstantExpr::getBitCast(
+        MakeGlobal(llvm::StructType::get(VMContext, PtrToInt8Ty, PtrToInt8Ty,
+            PtrTy, PtrTy, PtrTy, NULL), Elements), PtrTy));
+}
+
+llvm::Constant *CGObjCGNU::GeneratePropertyList(const ObjCImplementationDecl *OID,
+        llvm::SmallVectorImpl<Selector> &InstanceMethodSels,
+        llvm::SmallVectorImpl<llvm::Constant*> &InstanceMethodTypes) {
+  ASTContext &Context = CGM.getContext();
+  //
+  // Property metadata: name, attributes, isSynthesized, setter name, setter
+  // types, getter name, getter types.
+  llvm::StructType *PropertyMetadataTy = llvm::StructType::get(VMContext,
+          PtrToInt8Ty, Int8Ty, Int8Ty, PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty,
+          PtrToInt8Ty, NULL);
+  std::vector<llvm::Constant*> Properties;
+
+
+  // Add all of the property methods need adding to the method list and to the
+  // property metadata list.
+  for (ObjCImplDecl::propimpl_iterator
+         iter = OID->propimpl_begin(), endIter = OID->propimpl_end();
+       iter != endIter ; iter++) {
+    std::vector<llvm::Constant*> Fields;
+    ObjCPropertyDecl *property = (*iter)->getPropertyDecl();
+    ObjCPropertyImplDecl *propertyImpl = *iter;
+    bool isSynthesized = (propertyImpl->getPropertyImplementation() == 
+        ObjCPropertyImplDecl::Synthesize);
+
+    Fields.push_back(MakeConstantString(property->getNameAsString()));
+    Fields.push_back(llvm::ConstantInt::get(Int8Ty,
+                property->getPropertyAttributes()));
+    Fields.push_back(llvm::ConstantInt::get(Int8Ty, isSynthesized));
+    if (ObjCMethodDecl *getter = property->getGetterMethodDecl()) {
+      std::string TypeStr;
+      Context.getObjCEncodingForMethodDecl(getter,TypeStr);
+      llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);
+      if (isSynthesized) {
+        InstanceMethodTypes.push_back(TypeEncoding);
+        InstanceMethodSels.push_back(getter->getSelector());
+      }
+      Fields.push_back(MakeConstantString(getter->getSelector().getAsString()));
+      Fields.push_back(TypeEncoding);
+    } else {
+      Fields.push_back(NULLPtr);
+      Fields.push_back(NULLPtr);
+    }
+    if (ObjCMethodDecl *setter = property->getSetterMethodDecl()) {
+      std::string TypeStr;
+      Context.getObjCEncodingForMethodDecl(setter,TypeStr);
+      llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);
+      if (isSynthesized) {
+        InstanceMethodTypes.push_back(TypeEncoding);
+        InstanceMethodSels.push_back(setter->getSelector());
+      }
+      Fields.push_back(MakeConstantString(setter->getSelector().getAsString()));
+      Fields.push_back(TypeEncoding);
+    } else {
+      Fields.push_back(NULLPtr);
+      Fields.push_back(NULLPtr);
+    }
+    Properties.push_back(llvm::ConstantStruct::get(PropertyMetadataTy, Fields));
+  }
+  llvm::ArrayType *PropertyArrayTy =
+      llvm::ArrayType::get(PropertyMetadataTy, Properties.size());
+  llvm::Constant *PropertyArray = llvm::ConstantArray::get(PropertyArrayTy,
+          Properties);
+  llvm::Constant* PropertyListInitFields[] =
+    {llvm::ConstantInt::get(IntTy, Properties.size()), NULLPtr, PropertyArray};
+
+  llvm::Constant *PropertyListInit =
+      llvm::ConstantStruct::get(VMContext, PropertyListInitFields, 3, false);
+  return new llvm::GlobalVariable(TheModule, PropertyListInit->getType(), false,
+          llvm::GlobalValue::InternalLinkage, PropertyListInit,
+          ".objc_property_list");
+}
+
+void CGObjCGNU::GenerateClass(const ObjCImplementationDecl *OID) {
+  ASTContext &Context = CGM.getContext();
+
+  // Get the superclass name.
+  const ObjCInterfaceDecl * SuperClassDecl =
+    OID->getClassInterface()->getSuperClass();
+  std::string SuperClassName;
+  if (SuperClassDecl) {
+    SuperClassName = SuperClassDecl->getNameAsString();
+    EmitClassRef(SuperClassName);
+  }
+
+  // Get the class name
+  ObjCInterfaceDecl *ClassDecl =
+    const_cast<ObjCInterfaceDecl *>(OID->getClassInterface());
+  std::string ClassName = ClassDecl->getNameAsString();
+  // Emit the symbol that is used to generate linker errors if this class is
+  // referenced in other modules but not declared.
+  std::string classSymbolName = "__objc_class_name_" + ClassName;
+  if (llvm::GlobalVariable *symbol =
+      TheModule.getGlobalVariable(classSymbolName)) {
+    symbol->setInitializer(llvm::ConstantInt::get(LongTy, 0));
+  } else {
+    new llvm::GlobalVariable(TheModule, LongTy, false,
+    llvm::GlobalValue::ExternalLinkage, llvm::ConstantInt::get(LongTy, 0),
+    classSymbolName);
+  }
+
+  // Get the size of instances.
+  int instanceSize = Context.getASTObjCImplementationLayout(OID).getSize() / 8;
+
+  // Collect information about instance variables.
+  llvm::SmallVector<llvm::Constant*, 16> IvarNames;
+  llvm::SmallVector<llvm::Constant*, 16> IvarTypes;
+  llvm::SmallVector<llvm::Constant*, 16> IvarOffsets;
+
+  std::vector<llvm::Constant*> IvarOffsetValues;
+
+  int superInstanceSize = !SuperClassDecl ? 0 :
+    Context.getASTObjCInterfaceLayout(SuperClassDecl).getSize() / 8;
+  // For non-fragile ivars, set the instance size to 0 - {the size of just this
+  // class}.  The runtime will then set this to the correct value on load.
+  if (CGM.getContext().getLangOptions().ObjCNonFragileABI) {
+    instanceSize = 0 - (instanceSize - superInstanceSize);
+  }
+
+  // Collect declared and synthesized ivars.
+  llvm::SmallVector<ObjCIvarDecl*, 16> OIvars;
+  CGM.getContext().ShallowCollectObjCIvars(ClassDecl, OIvars);
+
+  for (unsigned i = 0, e = OIvars.size(); i != e; ++i) {
+      ObjCIvarDecl *IVD = OIvars[i];
+      // Store the name
+      IvarNames.push_back(MakeConstantString(IVD->getNameAsString()));
+      // Get the type encoding for this ivar
+      std::string TypeStr;
+      Context.getObjCEncodingForType(IVD->getType(), TypeStr);
+      IvarTypes.push_back(MakeConstantString(TypeStr));
+      // Get the offset
+      uint64_t BaseOffset = ComputeIvarBaseOffset(CGM, OID, IVD);
+      uint64_t Offset = BaseOffset;
+      if (CGM.getContext().getLangOptions().ObjCNonFragileABI) {
+        Offset = BaseOffset - superInstanceSize;
+      }
+      IvarOffsets.push_back(
+          llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), Offset));
+      IvarOffsetValues.push_back(new llvm::GlobalVariable(TheModule, IntTy,
+          false, llvm::GlobalValue::ExternalLinkage,
+          llvm::ConstantInt::get(IntTy, BaseOffset),
+          "__objc_ivar_offset_value_" + ClassName +"." +
+          IVD->getNameAsString()));
+  }
+  llvm::Constant *IvarOffsetArrayInit =
+      llvm::ConstantArray::get(llvm::ArrayType::get(PtrToIntTy,
+                  IvarOffsetValues.size()), IvarOffsetValues);
+  llvm::GlobalVariable *IvarOffsetArray = new llvm::GlobalVariable(TheModule,
+          IvarOffsetArrayInit->getType(), false,
+          llvm::GlobalValue::InternalLinkage, IvarOffsetArrayInit,
+          ".ivar.offsets");
+
+  // Collect information about instance methods
+  llvm::SmallVector<Selector, 16> InstanceMethodSels;
+  llvm::SmallVector<llvm::Constant*, 16> InstanceMethodTypes;
+  for (ObjCImplementationDecl::instmeth_iterator
+         iter = OID->instmeth_begin(), endIter = OID->instmeth_end();
+       iter != endIter ; iter++) {
+    InstanceMethodSels.push_back((*iter)->getSelector());
+    std::string TypeStr;
+    Context.getObjCEncodingForMethodDecl((*iter),TypeStr);
+    InstanceMethodTypes.push_back(MakeConstantString(TypeStr));
+  }
+
+  llvm::Constant *Properties = GeneratePropertyList(OID, InstanceMethodSels,
+          InstanceMethodTypes);
+
+
+  // Collect information about class methods
+  llvm::SmallVector<Selector, 16> ClassMethodSels;
+  llvm::SmallVector<llvm::Constant*, 16> ClassMethodTypes;
+  for (ObjCImplementationDecl::classmeth_iterator
+         iter = OID->classmeth_begin(), endIter = OID->classmeth_end();
+       iter != endIter ; iter++) {
+    ClassMethodSels.push_back((*iter)->getSelector());
+    std::string TypeStr;
+    Context.getObjCEncodingForMethodDecl((*iter),TypeStr);
+    ClassMethodTypes.push_back(MakeConstantString(TypeStr));
+  }
+  // Collect the names of referenced protocols
+  llvm::SmallVector<std::string, 16> Protocols;
+  const ObjCList<ObjCProtocolDecl> &Protos =ClassDecl->getReferencedProtocols();
+  for (ObjCList<ObjCProtocolDecl>::iterator I = Protos.begin(),
+       E = Protos.end(); I != E; ++I)
+    Protocols.push_back((*I)->getNameAsString());
+
+
+
+  // Get the superclass pointer.
+  llvm::Constant *SuperClass;
+  if (!SuperClassName.empty()) {
+    SuperClass = MakeConstantString(SuperClassName, ".super_class_name");
+  } else {
+    SuperClass = llvm::ConstantPointerNull::get(PtrToInt8Ty);
+  }
+  // Empty vector used to construct empty method lists
+  llvm::SmallVector<llvm::Constant*, 1>  empty;
+  // Generate the method and instance variable lists
+  llvm::Constant *MethodList = GenerateMethodList(ClassName, "",
+      InstanceMethodSels, InstanceMethodTypes, false);
+  llvm::Constant *ClassMethodList = GenerateMethodList(ClassName, "",
+      ClassMethodSels, ClassMethodTypes, true);
+  llvm::Constant *IvarList = GenerateIvarList(IvarNames, IvarTypes,
+      IvarOffsets);
+  // Irrespective of whether we are compiling for a fragile or non-fragile ABI,
+  // we emit a symbol containing the offset for each ivar in the class.  This
+  // allows code compiled for the non-Fragile ABI to inherit from code compiled
+  // for the legacy ABI, without causing problems.  The converse is also
+  // possible, but causes all ivar accesses to be fragile.
+  int i = 0;
+  // Offset pointer for getting at the correct field in the ivar list when
+  // setting up the alias.  These are: The base address for the global, the
+  // ivar array (second field), the ivar in this list (set for each ivar), and
+  // the offset (third field in ivar structure)
+  const llvm::Type *IndexTy = llvm::Type::getInt32Ty(VMContext);
+  llvm::Constant *offsetPointerIndexes[] = {Zeros[0],
+      llvm::ConstantInt::get(IndexTy, 1), 0,
+      llvm::ConstantInt::get(IndexTy, 2) };
+
+  for (ObjCInterfaceDecl::ivar_iterator iter = ClassDecl->ivar_begin(),
+      endIter = ClassDecl->ivar_end() ; iter != endIter ; iter++) {
+      const std::string Name = "__objc_ivar_offset_" + ClassName + '.'
+          +(*iter)->getNameAsString();
+      offsetPointerIndexes[2] = llvm::ConstantInt::get(IndexTy, i++);
+      // Get the correct ivar field
+      llvm::Constant *offsetValue = llvm::ConstantExpr::getGetElementPtr(
+              IvarList, offsetPointerIndexes, 4);
+      // Get the existing alias, if one exists.
+      llvm::GlobalVariable *offset = TheModule.getNamedGlobal(Name);
+      if (offset) {
+          offset->setInitializer(offsetValue);
+          // If this is the real definition, change its linkage type so that
+          // different modules will use this one, rather than their private
+          // copy.
+          offset->setLinkage(llvm::GlobalValue::ExternalLinkage);
+      } else {
+          // Add a new alias if there isn't one already.
+          offset = new llvm::GlobalVariable(TheModule, offsetValue->getType(),
+                  false, llvm::GlobalValue::ExternalLinkage, offsetValue, Name);
+      }
+  }
+  //Generate metaclass for class methods
+  llvm::Constant *MetaClassStruct = GenerateClassStructure(NULLPtr,
+      NULLPtr, 0x12L, ClassName.c_str(), 0, Zeros[0], GenerateIvarList(
+        empty, empty, empty), ClassMethodList, NULLPtr, NULLPtr, NULLPtr);
+
+  // Generate the class structure
+  llvm::Constant *ClassStruct =
+    GenerateClassStructure(MetaClassStruct, SuperClass, 0x11L,
+                           ClassName.c_str(), 0,
+      llvm::ConstantInt::get(LongTy, instanceSize), IvarList,
+      MethodList, GenerateProtocolList(Protocols), IvarOffsetArray,
+      Properties);
+
+  // Resolve the class aliases, if they exist.
+  if (ClassPtrAlias) {
+    ClassPtrAlias->setAliasee(
+        llvm::ConstantExpr::getBitCast(ClassStruct, IdTy));
+    ClassPtrAlias = 0;
+  }
+  if (MetaClassPtrAlias) {
+    MetaClassPtrAlias->setAliasee(
+        llvm::ConstantExpr::getBitCast(MetaClassStruct, IdTy));
+    MetaClassPtrAlias = 0;
+  }
+
+  // Add class structure to list to be added to the symtab later
+  ClassStruct = llvm::ConstantExpr::getBitCast(ClassStruct, PtrToInt8Ty);
+  Classes.push_back(ClassStruct);
+}
+
+
+llvm::Function *CGObjCGNU::ModuleInitFunction() {
+  // Only emit an ObjC load function if no Objective-C stuff has been called
+  if (Classes.empty() && Categories.empty() && ConstantStrings.empty() &&
+      ExistingProtocols.empty() && TypedSelectors.empty() &&
+      UntypedSelectors.empty())
+    return NULL;
+
+  // Add all referenced protocols to a category.
+  GenerateProtocolHolderCategory();
+
+  const llvm::StructType *SelStructTy = dyn_cast<llvm::StructType>(
+          SelectorTy->getElementType());
+  const llvm::Type *SelStructPtrTy = SelectorTy;
+  bool isSelOpaque = false;
+  if (SelStructTy == 0) {
+    SelStructTy = llvm::StructType::get(VMContext, PtrToInt8Ty,
+                                        PtrToInt8Ty, NULL);
+    SelStructPtrTy = llvm::PointerType::getUnqual(SelStructTy);
+    isSelOpaque = true;
+  }
+
+  // Name the ObjC types to make the IR a bit easier to read
+  TheModule.addTypeName(".objc_selector", SelStructPtrTy);
+  TheModule.addTypeName(".objc_id", IdTy);
+  TheModule.addTypeName(".objc_imp", IMPTy);
+
+  std::vector<llvm::Constant*> Elements;
+  llvm::Constant *Statics = NULLPtr;
+  // Generate statics list:
+  if (ConstantStrings.size()) {
+    llvm::ArrayType *StaticsArrayTy = llvm::ArrayType::get(PtrToInt8Ty,
+        ConstantStrings.size() + 1);
+    ConstantStrings.push_back(NULLPtr);
+
+    llvm::StringRef StringClass = CGM.getLangOptions().ObjCConstantStringClass;
+    if (StringClass.empty()) StringClass = "NXConstantString";
+    Elements.push_back(MakeConstantString(StringClass,
+                ".objc_static_class_name"));
+    Elements.push_back(llvm::ConstantArray::get(StaticsArrayTy,
+       ConstantStrings));
+    llvm::StructType *StaticsListTy =
+      llvm::StructType::get(VMContext, PtrToInt8Ty, StaticsArrayTy, NULL);
+    llvm::Type *StaticsListPtrTy =
+      llvm::PointerType::getUnqual(StaticsListTy);
+    Statics = MakeGlobal(StaticsListTy, Elements, ".objc_statics");
+    llvm::ArrayType *StaticsListArrayTy =
+      llvm::ArrayType::get(StaticsListPtrTy, 2);
+    Elements.clear();
+    Elements.push_back(Statics);
+    Elements.push_back(llvm::Constant::getNullValue(StaticsListPtrTy));
+    Statics = MakeGlobal(StaticsListArrayTy, Elements, ".objc_statics_ptr");
+    Statics = llvm::ConstantExpr::getBitCast(Statics, PtrTy);
+  }
+  // Array of classes, categories, and constant objects
+  llvm::ArrayType *ClassListTy = llvm::ArrayType::get(PtrToInt8Ty,
+      Classes.size() + Categories.size()  + 2);
+  llvm::StructType *SymTabTy = llvm::StructType::get(VMContext,
+                                                     LongTy, SelStructPtrTy,
+                                                     llvm::Type::getInt16Ty(VMContext),
+                                                     llvm::Type::getInt16Ty(VMContext),
+                                                     ClassListTy, NULL);
+
+  Elements.clear();
+  // Pointer to an array of selectors used in this module.
+  std::vector<llvm::Constant*> Selectors;
+  for (std::map<TypedSelector, llvm::GlobalAlias*>::iterator
+     iter = TypedSelectors.begin(), iterEnd = TypedSelectors.end();
+     iter != iterEnd ; ++iter) {
+    Elements.push_back(ExportUniqueString(iter->first.first, ".objc_sel_name"));
+    Elements.push_back(MakeConstantString(iter->first.second,
+                                          ".objc_sel_types"));
+    Selectors.push_back(llvm::ConstantStruct::get(SelStructTy, Elements));
+    Elements.clear();
+  }
+  for (llvm::StringMap<llvm::GlobalAlias*>::iterator
+      iter = UntypedSelectors.begin(), iterEnd = UntypedSelectors.end();
+      iter != iterEnd; ++iter) {
+    Elements.push_back(
+        ExportUniqueString(iter->getKeyData(), ".objc_sel_name"));
+    Elements.push_back(NULLPtr);
+    Selectors.push_back(llvm::ConstantStruct::get(SelStructTy, Elements));
+    Elements.clear();
+  }
+  Elements.push_back(NULLPtr);
+  Elements.push_back(NULLPtr);
+  Selectors.push_back(llvm::ConstantStruct::get(SelStructTy, Elements));
+  Elements.clear();
+  // Number of static selectors
+  Elements.push_back(llvm::ConstantInt::get(LongTy, Selectors.size() ));
+  llvm::Constant *SelectorList = MakeGlobal(
+          llvm::ArrayType::get(SelStructTy, Selectors.size()), Selectors,
+          ".objc_selector_list");
+  Elements.push_back(llvm::ConstantExpr::getBitCast(SelectorList,
+    SelStructPtrTy));
+
+  // Now that all of the static selectors exist, create pointers to them.
+  int index = 0;
+  for (std::map<TypedSelector, llvm::GlobalAlias*>::iterator
+     iter=TypedSelectors.begin(), iterEnd =TypedSelectors.end();
+     iter != iterEnd; ++iter) {
+    llvm::Constant *Idxs[] = {Zeros[0],
+      llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), index++), Zeros[0]};
+    llvm::Constant *SelPtr = new llvm::GlobalVariable(TheModule, SelStructPtrTy,
+        true, llvm::GlobalValue::InternalLinkage,
+        llvm::ConstantExpr::getGetElementPtr(SelectorList, Idxs, 2),
+        ".objc_sel_ptr");
+    // If selectors are defined as an opaque type, cast the pointer to this
+    // type.
+    if (isSelOpaque) {
+      SelPtr = llvm::ConstantExpr::getBitCast(SelPtr,
+        llvm::PointerType::getUnqual(SelectorTy));
+    }
+    (*iter).second->setAliasee(SelPtr);
+  }
+  for (llvm::StringMap<llvm::GlobalAlias*>::iterator
+      iter=UntypedSelectors.begin(), iterEnd = UntypedSelectors.end();
+      iter != iterEnd; iter++) {
+    llvm::Constant *Idxs[] = {Zeros[0],
+      llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), index++), Zeros[0]};
+    llvm::Constant *SelPtr = new llvm::GlobalVariable
+      (TheModule, SelStructPtrTy,
+       true, llvm::GlobalValue::InternalLinkage,
+       llvm::ConstantExpr::getGetElementPtr(SelectorList, Idxs, 2),
+       ".objc_sel_ptr");
+    // If selectors are defined as an opaque type, cast the pointer to this
+    // type.
+    if (isSelOpaque) {
+      SelPtr = llvm::ConstantExpr::getBitCast(SelPtr,
+        llvm::PointerType::getUnqual(SelectorTy));
+    }
+    (*iter).second->setAliasee(SelPtr);
+  }
+  // Number of classes defined.
+  Elements.push_back(llvm::ConstantInt::get(llvm::Type::getInt16Ty(VMContext),
+        Classes.size()));
+  // Number of categories defined
+  Elements.push_back(llvm::ConstantInt::get(llvm::Type::getInt16Ty(VMContext),
+        Categories.size()));
+  // Create an array of classes, then categories, then static object instances
+  Classes.insert(Classes.end(), Categories.begin(), Categories.end());
+  //  NULL-terminated list of static object instances (mainly constant strings)
+  Classes.push_back(Statics);
+  Classes.push_back(NULLPtr);
+  llvm::Constant *ClassList = llvm::ConstantArray::get(ClassListTy, Classes);
+  Elements.push_back(ClassList);
+  // Construct the symbol table
+  llvm::Constant *SymTab= MakeGlobal(SymTabTy, Elements);
+
+  // The symbol table is contained in a module which has some version-checking
+  // constants
+  llvm::StructType * ModuleTy = llvm::StructType::get(VMContext, LongTy, LongTy,
+      PtrToInt8Ty, llvm::PointerType::getUnqual(SymTabTy), NULL);
+  Elements.clear();
+  // Runtime version used for compatibility checking.
+  if (CGM.getContext().getLangOptions().ObjCNonFragileABI) {
+    Elements.push_back(llvm::ConstantInt::get(LongTy,
+        NonFragileRuntimeVersion));
+  } else {
+    Elements.push_back(llvm::ConstantInt::get(LongTy, RuntimeVersion));
+  }
+  // sizeof(ModuleTy)
+  llvm::TargetData td(&TheModule);
+  Elements.push_back(llvm::ConstantInt::get(LongTy,
+                     td.getTypeSizeInBits(ModuleTy)/8));
+  //FIXME: Should be the path to the file where this module was declared
+  Elements.push_back(NULLPtr);
+  Elements.push_back(SymTab);
+  llvm::Value *Module = MakeGlobal(ModuleTy, Elements);
+
+  // Create the load function calling the runtime entry point with the module
+  // structure
+  llvm::Function * LoadFunction = llvm::Function::Create(
+      llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), false),
+      llvm::GlobalValue::InternalLinkage, ".objc_load_function",
+      &TheModule);
+  llvm::BasicBlock *EntryBB =
+      llvm::BasicBlock::Create(VMContext, "entry", LoadFunction);
+  CGBuilderTy Builder(VMContext);
+  Builder.SetInsertPoint(EntryBB);
+
+  std::vector<const llvm::Type*> Params(1,
+      llvm::PointerType::getUnqual(ModuleTy));
+  llvm::Value *Register = CGM.CreateRuntimeFunction(llvm::FunctionType::get(
+        llvm::Type::getVoidTy(VMContext), Params, true), "__objc_exec_class");
+  Builder.CreateCall(Register, Module);
+  Builder.CreateRetVoid();
+
+  return LoadFunction;
+}
+
+llvm::Function *CGObjCGNU::GenerateMethod(const ObjCMethodDecl *OMD,
+                                          const ObjCContainerDecl *CD) {
+  const ObjCCategoryImplDecl *OCD =
+    dyn_cast<ObjCCategoryImplDecl>(OMD->getDeclContext());
+  std::string CategoryName = OCD ? OCD->getNameAsString() : "";
+  std::string ClassName = CD->getName();
+  std::string MethodName = OMD->getSelector().getAsString();
+  bool isClassMethod = !OMD->isInstanceMethod();
+
+  CodeGenTypes &Types = CGM.getTypes();
+  const llvm::FunctionType *MethodTy =
+    Types.GetFunctionType(Types.getFunctionInfo(OMD), OMD->isVariadic());
+  std::string FunctionName = SymbolNameForMethod(ClassName, CategoryName,
+      MethodName, isClassMethod);
+
+  llvm::Function *Method
+    = llvm::Function::Create(MethodTy,
+                             llvm::GlobalValue::InternalLinkage,
+                             FunctionName,
+                             &TheModule);
+  return Method;
+}
+
+llvm::Function *CGObjCGNU::GetPropertyGetFunction() {
+  std::vector<const llvm::Type*> Params;
+  const llvm::Type *BoolTy =
+    CGM.getTypes().ConvertType(CGM.getContext().BoolTy);
+  Params.push_back(IdTy);
+  Params.push_back(SelectorTy);
+  Params.push_back(IntTy);
+  Params.push_back(BoolTy);
+  // void objc_getProperty (id, SEL, int, bool)
+  const llvm::FunctionType *FTy =
+    llvm::FunctionType::get(IdTy, Params, false);
+  return cast<llvm::Function>(CGM.CreateRuntimeFunction(FTy,
+                                                        "objc_getProperty"));
+}
+
+llvm::Function *CGObjCGNU::GetPropertySetFunction() {
+  std::vector<const llvm::Type*> Params;
+  const llvm::Type *BoolTy =
+    CGM.getTypes().ConvertType(CGM.getContext().BoolTy);
+  Params.push_back(IdTy);
+  Params.push_back(SelectorTy);
+  Params.push_back(IntTy);
+  Params.push_back(IdTy);
+  Params.push_back(BoolTy);
+  Params.push_back(BoolTy);
+  // void objc_setProperty (id, SEL, int, id, bool, bool)
+  const llvm::FunctionType *FTy =
+    llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), Params, false);
+  return cast<llvm::Function>(CGM.CreateRuntimeFunction(FTy,
+                                                        "objc_setProperty"));
+}
+
+// FIXME. Implement this.
+llvm::Function *CGObjCGNU::GetCopyStructFunction() {
+  return 0;
+}
+
+llvm::Constant *CGObjCGNU::EnumerationMutationFunction() {
+  CodeGen::CodeGenTypes &Types = CGM.getTypes();
+  ASTContext &Ctx = CGM.getContext();
+  // void objc_enumerationMutation (id)
+  llvm::SmallVector<CanQualType,1> Params;
+  Params.push_back(ASTIdTy);
+  const llvm::FunctionType *FTy =
+    Types.GetFunctionType(Types.getFunctionInfo(Ctx.VoidTy, Params,
+                                              FunctionType::ExtInfo()), false);
+  return CGM.CreateRuntimeFunction(FTy, "objc_enumerationMutation");
+}
+
+void CGObjCGNU::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
+                                          const Stmt &S) {
+  // Pointer to the personality function
+  llvm::Constant *Personality =
+    CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::getInt32Ty(VMContext),
+          true),
+        "__gnu_objc_personality_v0");
+  Personality = llvm::ConstantExpr::getBitCast(Personality, PtrTy);
+  std::vector<const llvm::Type*> Params;
+  Params.push_back(PtrTy);
+  llvm::Value *RethrowFn =
+    CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
+          Params, false), "_Unwind_Resume");
+
+  bool isTry = isa<ObjCAtTryStmt>(S);
+  llvm::BasicBlock *TryBlock = CGF.createBasicBlock("try");
+  llvm::BasicBlock *PrevLandingPad = CGF.getInvokeDest();
+  llvm::BasicBlock *TryHandler = CGF.createBasicBlock("try.handler");
+  llvm::BasicBlock *CatchInCatch = CGF.createBasicBlock("catch.rethrow");
+  llvm::BasicBlock *FinallyBlock = CGF.createBasicBlock("finally");
+  llvm::BasicBlock *FinallyRethrow = CGF.createBasicBlock("finally.throw");
+  llvm::BasicBlock *FinallyEnd = CGF.createBasicBlock("finally.end");
+
+  // @synchronized()
+  if (!isTry) {
+    std::vector<const llvm::Type*> Args(1, IdTy);
+    llvm::FunctionType *FTy =
+      llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), Args, false);
+    llvm::Value *SyncEnter = CGM.CreateRuntimeFunction(FTy, "objc_sync_enter");
+    llvm::Value *SyncArg =
+      CGF.EmitScalarExpr(cast<ObjCAtSynchronizedStmt>(S).getSynchExpr());
+    SyncArg = CGF.Builder.CreateBitCast(SyncArg, IdTy);
+    CGF.Builder.CreateCall(SyncEnter, SyncArg);
+  }
+
+
+  // Push an EH context entry, used for handling rethrows and jumps
+  // through finally.
+  CGF.PushCleanupBlock(FinallyBlock);
+
+  // Emit the statements in the @try {} block
+  CGF.setInvokeDest(TryHandler);
+
+  CGF.EmitBlock(TryBlock);
+  CGF.EmitStmt(isTry ? cast<ObjCAtTryStmt>(S).getTryBody()
+                     : cast<ObjCAtSynchronizedStmt>(S).getSynchBody());
+
+  // Jump to @finally if there is no exception
+  CGF.EmitBranchThroughCleanup(FinallyEnd);
+
+  // Emit the handlers
+  CGF.EmitBlock(TryHandler);
+
+  // Get the correct versions of the exception handling intrinsics
+  llvm::Value *llvm_eh_exception =
+    CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_exception);
+  llvm::Value *llvm_eh_selector =
+    CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_selector);
+  llvm::Value *llvm_eh_typeid_for =
+    CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_typeid_for);
+
+  // Exception object
+  llvm::Value *Exc = CGF.Builder.CreateCall(llvm_eh_exception, "exc");
+  llvm::Value *RethrowPtr = CGF.CreateTempAlloca(Exc->getType(), "_rethrow");
+
+  llvm::SmallVector<llvm::Value*, 8> ESelArgs;
+  llvm::SmallVector<std::pair<const VarDecl*, const Stmt*>, 8> Handlers;
+
+  ESelArgs.push_back(Exc);
+  ESelArgs.push_back(Personality);
+
+  bool HasCatchAll = false;
+  // Only @try blocks are allowed @catch blocks, but both can have @finally
+  if (isTry) {
+    if (cast<ObjCAtTryStmt>(S).getNumCatchStmts()) {
+      const ObjCAtTryStmt &AtTry = cast<ObjCAtTryStmt>(S);
+      CGF.setInvokeDest(CatchInCatch);
+
+      for (unsigned I = 0, N = AtTry.getNumCatchStmts(); I != N; ++I) {
+        const ObjCAtCatchStmt *CatchStmt = AtTry.getCatchStmt(I);
+        const VarDecl *CatchDecl = CatchStmt->getCatchParamDecl();
+        Handlers.push_back(std::make_pair(CatchDecl,
+                                          CatchStmt->getCatchBody()));
+
+        // @catch() and @catch(id) both catch any ObjC exception
+        if (!CatchDecl || CatchDecl->getType()->isObjCIdType()
+            || CatchDecl->getType()->isObjCQualifiedIdType()) {
+          // Use i8* null here to signal this is a catch all, not a cleanup.
+          ESelArgs.push_back(NULLPtr);
+          HasCatchAll = true;
+          // No further catches after this one will ever by reached
+          break;
+        }
+
+        // All other types should be Objective-C interface pointer types.
+        const ObjCObjectPointerType *OPT =
+          CatchDecl->getType()->getAs<ObjCObjectPointerType>();
+        assert(OPT && "Invalid @catch type.");
+        const ObjCInterfaceType *IT =
+          OPT->getPointeeType()->getAs<ObjCInterfaceType>();
+        assert(IT && "Invalid @catch type.");
+        llvm::Value *EHType =
+          MakeConstantString(IT->getDecl()->getNameAsString());
+        ESelArgs.push_back(EHType);
+      }
+    }
+  }
+
+  // We use a cleanup unless there was already a catch all.
+  if (!HasCatchAll) {
+    ESelArgs.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 0));
+    Handlers.push_back(std::make_pair((const ParmVarDecl*) 0, (const Stmt*) 0));
+  }
+
+  // Find which handler was matched.
+  llvm::Value *ESelector = CGF.Builder.CreateCall(llvm_eh_selector,
+      ESelArgs.begin(), ESelArgs.end(), "selector");
+
+  for (unsigned i = 0, e = Handlers.size(); i != e; ++i) {
+    const VarDecl *CatchParam = Handlers[i].first;
+    const Stmt *CatchBody = Handlers[i].second;
+
+    llvm::BasicBlock *Next = 0;
+
+    // The last handler always matches.
+    if (i + 1 != e) {
+      assert(CatchParam && "Only last handler can be a catch all.");
+
+      // Test whether this block matches the type for the selector and branch
+      // to Match if it does, or to the next BB if it doesn't.
+      llvm::BasicBlock *Match = CGF.createBasicBlock("match");
+      Next = CGF.createBasicBlock("catch.next");
+      llvm::Value *Id = CGF.Builder.CreateCall(llvm_eh_typeid_for,
+          CGF.Builder.CreateBitCast(ESelArgs[i+2], PtrTy));
+      CGF.Builder.CreateCondBr(CGF.Builder.CreateICmpEQ(ESelector, Id), Match,
+          Next);
+
+      CGF.EmitBlock(Match);
+    }
+
+    if (CatchBody) {
+      llvm::Value *ExcObject = CGF.Builder.CreateBitCast(Exc,
+          CGF.ConvertType(CatchParam->getType()));
+
+      // Bind the catch parameter if it exists.
+      if (CatchParam) {
+        // CatchParam is a ParmVarDecl because of the grammar
+        // construction used to handle this, but for codegen purposes
+        // we treat this as a local decl.
+        CGF.EmitLocalBlockVarDecl(*CatchParam);
+        CGF.Builder.CreateStore(ExcObject, CGF.GetAddrOfLocalVar(CatchParam));
+      }
+
+      CGF.ObjCEHValueStack.push_back(ExcObject);
+      CGF.EmitStmt(CatchBody);
+      CGF.ObjCEHValueStack.pop_back();
+
+      CGF.EmitBranchThroughCleanup(FinallyEnd);
+
+      if (Next)
+        CGF.EmitBlock(Next);
+    } else {
+      assert(!Next && "catchup should be last handler.");
+
+      CGF.Builder.CreateStore(Exc, RethrowPtr);
+      CGF.EmitBranchThroughCleanup(FinallyRethrow);
+    }
+  }
+  // The @finally block is a secondary landing pad for any exceptions thrown in
+  // @catch() blocks
+  CGF.EmitBlock(CatchInCatch);
+  Exc = CGF.Builder.CreateCall(llvm_eh_exception, "exc");
+  ESelArgs.clear();
+  ESelArgs.push_back(Exc);
+  ESelArgs.push_back(Personality);
+  // If there is a @catch or @finally clause in outside of this one then we
+  // need to make sure that we catch and rethrow it.  
+  if (PrevLandingPad) {
+    ESelArgs.push_back(NULLPtr);
+  } else {
+    ESelArgs.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 0));
+  }
+  CGF.Builder.CreateCall(llvm_eh_selector, ESelArgs.begin(), ESelArgs.end(),
+      "selector");
+  CGF.Builder.CreateCall(llvm_eh_typeid_for,
+      CGF.Builder.CreateIntToPtr(ESelArgs[2], PtrTy));
+  CGF.Builder.CreateStore(Exc, RethrowPtr);
+  CGF.EmitBranchThroughCleanup(FinallyRethrow);
+
+  CodeGenFunction::CleanupBlockInfo Info = CGF.PopCleanupBlock();
+
+  CGF.setInvokeDest(PrevLandingPad);
+
+  CGF.EmitBlock(FinallyBlock);
+
+
+  if (isTry) {
+    if (const ObjCAtFinallyStmt* FinallyStmt =
+        cast<ObjCAtTryStmt>(S).getFinallyStmt())
+      CGF.EmitStmt(FinallyStmt->getFinallyBody());
+  } else {
+    // Emit 'objc_sync_exit(expr)' as finally's sole statement for
+    // @synchronized.
+    std::vector<const llvm::Type*> Args(1, IdTy);
+    llvm::FunctionType *FTy =
+      llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), Args, false);
+    llvm::Value *SyncExit = CGM.CreateRuntimeFunction(FTy, "objc_sync_exit");
+    llvm::Value *SyncArg =
+      CGF.EmitScalarExpr(cast<ObjCAtSynchronizedStmt>(S).getSynchExpr());
+    SyncArg = CGF.Builder.CreateBitCast(SyncArg, IdTy);
+    CGF.Builder.CreateCall(SyncExit, SyncArg);
+  }
+
+  if (Info.SwitchBlock)
+    CGF.EmitBlock(Info.SwitchBlock);
+  if (Info.EndBlock)
+    CGF.EmitBlock(Info.EndBlock);
+
+  // Branch around the rethrow code.
+  CGF.EmitBranch(FinallyEnd);
+
+  CGF.EmitBlock(FinallyRethrow);
+
+  llvm::Value *ExceptionObject = CGF.Builder.CreateLoad(RethrowPtr);
+  llvm::BasicBlock *UnwindBB = CGF.getInvokeDest();
+  if (!UnwindBB) {
+    CGF.Builder.CreateCall(RethrowFn, ExceptionObject);
+    // Exception always thrown, next instruction is never reached.
+    CGF.Builder.CreateUnreachable();
+  } else {
+    // If there is a @catch block outside this scope, we invoke instead of
+    // calling because we may return to this function.  This is very slow, but
+    // some people still do it.  It would be nice to add an optimised path for
+    // this.
+    CGF.Builder.CreateInvoke(RethrowFn, UnwindBB, UnwindBB, &ExceptionObject,
+        &ExceptionObject+1);
+  }
+
+  CGF.EmitBlock(FinallyEnd);
+}
+
+void CGObjCGNU::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
+                              const ObjCAtThrowStmt &S) {
+  llvm::Value *ExceptionAsObject;
+
+  std::vector<const llvm::Type*> Args(1, IdTy);
+  llvm::FunctionType *FTy =
+    llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), Args, false);
+  llvm::Value *ThrowFn =
+    CGM.CreateRuntimeFunction(FTy, "objc_exception_throw");
+
+  if (const Expr *ThrowExpr = S.getThrowExpr()) {
+    llvm::Value *Exception = CGF.EmitScalarExpr(ThrowExpr);
+    ExceptionAsObject = Exception;
+  } else {
+    assert((!CGF.ObjCEHValueStack.empty() && CGF.ObjCEHValueStack.back()) &&
+           "Unexpected rethrow outside @catch block.");
+    ExceptionAsObject = CGF.ObjCEHValueStack.back();
+  }
+  ExceptionAsObject =
+      CGF.Builder.CreateBitCast(ExceptionAsObject, IdTy, "tmp");
+
+  // Note: This may have to be an invoke, if we want to support constructs like:
+  // @try {
+  //  @throw(obj);
+  // }
+  // @catch(id) ...
+  //
+  // This is effectively turning @throw into an incredibly-expensive goto, but
+  // it may happen as a result of inlining followed by missed optimizations, or
+  // as a result of stupidity.
+  llvm::BasicBlock *UnwindBB = CGF.getInvokeDest();
+  if (!UnwindBB) {
+    CGF.Builder.CreateCall(ThrowFn, ExceptionAsObject);
+    CGF.Builder.CreateUnreachable();
+  } else {
+    CGF.Builder.CreateInvoke(ThrowFn, UnwindBB, UnwindBB, &ExceptionAsObject,
+        &ExceptionAsObject+1);
+  }
+  // Clear the insertion point to indicate we are in unreachable code.
+  CGF.Builder.ClearInsertionPoint();
+}
+
+llvm::Value * CGObjCGNU::EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
+                                          llvm::Value *AddrWeakObj) {
+  CGBuilderTy B = CGF.Builder;
+  AddrWeakObj = EnforceType(B, AddrWeakObj, IdTy);
+  return B.CreateCall(WeakReadFn, AddrWeakObj);
+}
+
+void CGObjCGNU::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
+                                   llvm::Value *src, llvm::Value *dst) {
+  CGBuilderTy B = CGF.Builder;
+  src = EnforceType(B, src, IdTy);
+  dst = EnforceType(B, dst, PtrToIdTy);
+  B.CreateCall2(WeakAssignFn, src, dst);
+}
+
+void CGObjCGNU::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
+                                     llvm::Value *src, llvm::Value *dst) {
+  CGBuilderTy B = CGF.Builder;
+  src = EnforceType(B, src, IdTy);
+  dst = EnforceType(B, dst, PtrToIdTy);
+  B.CreateCall2(GlobalAssignFn, src, dst);
+}
+
+void CGObjCGNU::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
+                                   llvm::Value *src, llvm::Value *dst,
+                                   llvm::Value *ivarOffset) {
+  CGBuilderTy B = CGF.Builder;
+  src = EnforceType(B, src, IdTy);
+  dst = EnforceType(B, dst, PtrToIdTy);
+  B.CreateCall3(IvarAssignFn, src, dst, ivarOffset);
+}
+
+void CGObjCGNU::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
+                                         llvm::Value *src, llvm::Value *dst) {
+  CGBuilderTy B = CGF.Builder;
+  src = EnforceType(B, src, IdTy);
+  dst = EnforceType(B, dst, PtrToIdTy);
+  B.CreateCall2(StrongCastAssignFn, src, dst);
+}
+
+void CGObjCGNU::EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
+                                         llvm::Value *DestPtr,
+                                         llvm::Value *SrcPtr,
+                                         QualType Ty) {
+  CGBuilderTy B = CGF.Builder;
+  DestPtr = EnforceType(B, DestPtr, IdTy);
+  SrcPtr = EnforceType(B, SrcPtr, PtrToIdTy);
+
+  std::pair<uint64_t, unsigned> TypeInfo = CGM.getContext().getTypeInfo(Ty);
+  unsigned long size = TypeInfo.first/8;
+  // FIXME: size_t
+  llvm::Value *N = llvm::ConstantInt::get(LongTy, size);
+
+  B.CreateCall3(MemMoveFn, DestPtr, SrcPtr, N);
+}
+
+llvm::GlobalVariable *CGObjCGNU::ObjCIvarOffsetVariable(
+                              const ObjCInterfaceDecl *ID,
+                              const ObjCIvarDecl *Ivar) {
+  const std::string Name = "__objc_ivar_offset_" + ID->getNameAsString()
+    + '.' + Ivar->getNameAsString();
+  // Emit the variable and initialize it with what we think the correct value
+  // is.  This allows code compiled with non-fragile ivars to work correctly
+  // when linked against code which isn't (most of the time).
+  llvm::GlobalVariable *IvarOffsetPointer = TheModule.getNamedGlobal(Name);
+  if (!IvarOffsetPointer) {
+    uint64_t Offset;
+    if (ObjCImplementationDecl *OID =
+            CGM.getContext().getObjCImplementation(
+              const_cast<ObjCInterfaceDecl *>(ID)))
+      Offset = ComputeIvarBaseOffset(CGM, OID, Ivar);
+    else
+      Offset = ComputeIvarBaseOffset(CGM, ID, Ivar);
+
+    llvm::ConstantInt *OffsetGuess =
+      llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), Offset, "ivar");
+    // Don't emit the guess in non-PIC code because the linker will not be able
+    // to replace it with the real version for a library.  In non-PIC code you
+    // must compile with the fragile ABI if you want to use ivars from a
+    // GCC-compiled class.
+    if (CGM.getLangOptions().PICLevel) {
+      llvm::GlobalVariable *IvarOffsetGV = new llvm::GlobalVariable(TheModule,
+            llvm::Type::getInt32Ty(VMContext), false,
+            llvm::GlobalValue::PrivateLinkage, OffsetGuess, Name+".guess");
+      IvarOffsetPointer = new llvm::GlobalVariable(TheModule,
+            IvarOffsetGV->getType(), false, llvm::GlobalValue::LinkOnceAnyLinkage,
+            IvarOffsetGV, Name);
+    } else {
+      IvarOffsetPointer = new llvm::GlobalVariable(TheModule,
+              llvm::Type::getInt32PtrTy(VMContext), false,
+              llvm::GlobalValue::ExternalLinkage, 0, Name);
+    }
+  }
+  return IvarOffsetPointer;
+}
+
+LValue CGObjCGNU::EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
+                                       QualType ObjectTy,
+                                       llvm::Value *BaseValue,
+                                       const ObjCIvarDecl *Ivar,
+                                       unsigned CVRQualifiers) {
+  const ObjCInterfaceDecl *ID = ObjectTy->getAs<ObjCInterfaceType>()->getDecl();
+  return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
+                                  EmitIvarOffset(CGF, ID, Ivar));
+}
+
+static const ObjCInterfaceDecl *FindIvarInterface(ASTContext &Context,
+                                                  const ObjCInterfaceDecl *OID,
+                                                  const ObjCIvarDecl *OIVD) {
+  llvm::SmallVector<ObjCIvarDecl*, 16> Ivars;
+  Context.ShallowCollectObjCIvars(OID, Ivars);
+  for (unsigned k = 0, e = Ivars.size(); k != e; ++k) {
+    if (OIVD == Ivars[k])
+      return OID;
+  }
+
+  // Otherwise check in the super class.
+  if (const ObjCInterfaceDecl *Super = OID->getSuperClass())
+    return FindIvarInterface(Context, Super, OIVD);
+
+  return 0;
+}
+
+llvm::Value *CGObjCGNU::EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
+                         const ObjCInterfaceDecl *Interface,
+                         const ObjCIvarDecl *Ivar) {
+  if (CGM.getLangOptions().ObjCNonFragileABI) {
+    Interface = FindIvarInterface(CGM.getContext(), Interface, Ivar);
+    return CGF.Builder.CreateLoad(CGF.Builder.CreateLoad(
+                ObjCIvarOffsetVariable(Interface, Ivar), false, "ivar"));
+  }
+  uint64_t Offset = ComputeIvarBaseOffset(CGF.CGM, Interface, Ivar);
+  return llvm::ConstantInt::get(LongTy, Offset, "ivar");
+}
+
+CodeGen::CGObjCRuntime *
+CodeGen::CreateGNUObjCRuntime(CodeGen::CodeGenModule &CGM) {
+  return new CGObjCGNU(CGM);
+}
diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp
new file mode 100644
index 0000000..3905bd4
--- /dev/null
+++ b/lib/CodeGen/CGObjCMac.cpp
@@ -0,0 +1,5886 @@
+//===------- CGObjCMac.cpp - Interface to Apple Objective-C Runtime -------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This provides Objective-C code generation targetting the Apple runtime.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CGObjCRuntime.h"
+
+#include "CGRecordLayout.h"
+#include "CodeGenModule.h"
+#include "CodeGenFunction.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/RecordLayout.h"
+#include "clang/AST/StmtObjC.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/CodeGen/CodeGenOptions.h"
+
+#include "llvm/Intrinsics.h"
+#include "llvm/LLVMContext.h"
+#include "llvm/Module.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Target/TargetData.h"
+#include <cstdio>
+
+using namespace clang;
+using namespace CodeGen;
+
+// Common CGObjCRuntime functions, these don't belong here, but they
+// don't belong in CGObjCRuntime either so we will live with it for
+// now.
+
+static uint64_t LookupFieldBitOffset(CodeGen::CodeGenModule &CGM,
+                                     const ObjCInterfaceDecl *OID,
+                                     const ObjCImplementationDecl *ID,
+                                     const ObjCIvarDecl *Ivar) {
+  const ObjCInterfaceDecl *Container = Ivar->getContainingInterface();
+
+  // FIXME: We should eliminate the need to have ObjCImplementationDecl passed
+  // in here; it should never be necessary because that should be the lexical
+  // decl context for the ivar.
+
+  // If we know have an implementation (and the ivar is in it) then
+  // look up in the implementation layout.
+  const ASTRecordLayout *RL;
+  if (ID && ID->getClassInterface() == Container)
+    RL = &CGM.getContext().getASTObjCImplementationLayout(ID);
+  else
+    RL = &CGM.getContext().getASTObjCInterfaceLayout(Container);
+
+  // Compute field index.
+  //
+  // FIXME: The index here is closely tied to how ASTContext::getObjCLayout is
+  // implemented. This should be fixed to get the information from the layout
+  // directly.
+  unsigned Index = 0;
+  llvm::SmallVector<ObjCIvarDecl*, 16> Ivars;
+  CGM.getContext().ShallowCollectObjCIvars(Container, Ivars);
+  for (unsigned k = 0, e = Ivars.size(); k != e; ++k) {
+    if (Ivar == Ivars[k])
+      break;
+    ++Index;
+  }
+  assert(Index != Ivars.size() && "Ivar is not inside container!");
+
+  return RL->getFieldOffset(Index);
+}
+
+uint64_t CGObjCRuntime::ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM,
+                                              const ObjCInterfaceDecl *OID,
+                                              const ObjCIvarDecl *Ivar) {
+  return LookupFieldBitOffset(CGM, OID, 0, Ivar) / 8;
+}
+
+uint64_t CGObjCRuntime::ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM,
+                                              const ObjCImplementationDecl *OID,
+                                              const ObjCIvarDecl *Ivar) {
+  return LookupFieldBitOffset(CGM, OID->getClassInterface(), OID, Ivar) / 8;
+}
+
+LValue CGObjCRuntime::EmitValueForIvarAtOffset(CodeGen::CodeGenFunction &CGF,
+                                               const ObjCInterfaceDecl *OID,
+                                               llvm::Value *BaseValue,
+                                               const ObjCIvarDecl *Ivar,
+                                               unsigned CVRQualifiers,
+                                               llvm::Value *Offset) {
+  // Compute (type*) ( (char *) BaseValue + Offset)
+  const llvm::Type *I8Ptr = llvm::Type::getInt8PtrTy(CGF.getLLVMContext());
+  QualType IvarTy = Ivar->getType();
+  const llvm::Type *LTy = CGF.CGM.getTypes().ConvertTypeForMem(IvarTy);
+  llvm::Value *V = CGF.Builder.CreateBitCast(BaseValue, I8Ptr);
+  V = CGF.Builder.CreateGEP(V, Offset, "add.ptr");
+  V = CGF.Builder.CreateBitCast(V, llvm::PointerType::getUnqual(LTy));
+
+  Qualifiers Quals = CGF.MakeQualifiers(IvarTy);
+  Quals.addCVRQualifiers(CVRQualifiers);
+
+  if (!Ivar->isBitField())
+    return LValue::MakeAddr(V, Quals);
+
+  // We need to compute the bit offset for the bit-field, the offset is to the
+  // byte. Note, there is a subtle invariant here: we can only call this routine
+  // on non-synthesized ivars but we may be called for synthesized ivars.
+  // However, a synthesized ivar can never be a bit-field, so this is safe.
+  uint64_t BitOffset = LookupFieldBitOffset(CGF.CGM, OID, 0, Ivar) % 8;
+  uint64_t BitFieldSize =
+    Ivar->getBitWidth()->EvaluateAsInt(CGF.getContext()).getZExtValue();
+
+  // Allocate a new CGBitFieldInfo object to describe this access.
+  //
+  // FIXME: This is incredibly wasteful, these should be uniqued or part of some
+  // layout object. However, this is blocked on other cleanups to the
+  // Objective-C code, so for now we just live with allocating a bunch of these
+  // objects.
+
+  // We always construct a single, possibly unaligned, access for this case.
+  CGBitFieldInfo::AccessInfo AI;
+  AI.FieldIndex = 0;
+  AI.FieldByteOffset = 0;
+  AI.FieldBitStart = BitOffset;
+  AI.AccessWidth = CGF.CGM.getContext().getTypeSize(IvarTy);
+  AI.AccessAlignment = 0;
+  AI.TargetBitOffset = 0;
+  AI.TargetBitWidth = BitFieldSize;
+
+  CGBitFieldInfo *Info =
+    new (CGF.CGM.getContext()) CGBitFieldInfo(BitFieldSize, 1, &AI,
+                                              IvarTy->isSignedIntegerType());
+
+  // FIXME: We need to set a very conservative alignment on this, or make sure
+  // that the runtime is doing the right thing.
+  return LValue::MakeBitfield(V, *Info, Quals.getCVRQualifiers());
+}
+
+///
+
+namespace {
+
+typedef std::vector<llvm::Constant*> ConstantVector;
+
+// FIXME: We should find a nicer way to make the labels for metadata, string
+// concatenation is lame.
+
+class ObjCCommonTypesHelper {
+protected:
+  llvm::LLVMContext &VMContext;
+
+private:
+  llvm::Constant *getMessageSendFn() const {
+    // id objc_msgSend (id, SEL, ...)
+    std::vector<const llvm::Type*> Params;
+    Params.push_back(ObjectPtrTy);
+    Params.push_back(SelectorPtrTy);
+    return
+      CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
+                                                        Params, true),
+                                "objc_msgSend");
+  }
+
+  llvm::Constant *getMessageSendStretFn() const {
+    // id objc_msgSend_stret (id, SEL, ...)
+    std::vector<const llvm::Type*> Params;
+    Params.push_back(ObjectPtrTy);
+    Params.push_back(SelectorPtrTy);
+    return
+      CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
+                                                        Params, true),
+                                "objc_msgSend_stret");
+
+  }
+
+  llvm::Constant *getMessageSendFpretFn() const {
+    // FIXME: This should be long double on x86_64?
+    // [double | long double] objc_msgSend_fpret(id self, SEL op, ...)
+    std::vector<const llvm::Type*> Params;
+    Params.push_back(ObjectPtrTy);
+    Params.push_back(SelectorPtrTy);
+    return
+      CGM.CreateRuntimeFunction(llvm::FunctionType::get(
+                                             llvm::Type::getDoubleTy(VMContext),
+                                                        Params,
+                                                        true),
+                                "objc_msgSend_fpret");
+
+  }
+
+  llvm::Constant *getMessageSendSuperFn() const {
+    // id objc_msgSendSuper(struct objc_super *super, SEL op, ...)
+    const char *SuperName = "objc_msgSendSuper";
+    std::vector<const llvm::Type*> Params;
+    Params.push_back(SuperPtrTy);
+    Params.push_back(SelectorPtrTy);
+    return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
+                                                             Params, true),
+                                     SuperName);
+  }
+
+  llvm::Constant *getMessageSendSuperFn2() const {
+    // id objc_msgSendSuper2(struct objc_super *super, SEL op, ...)
+    const char *SuperName = "objc_msgSendSuper2";
+    std::vector<const llvm::Type*> Params;
+    Params.push_back(SuperPtrTy);
+    Params.push_back(SelectorPtrTy);
+    return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
+                                                             Params, true),
+                                     SuperName);
+  }
+
+  llvm::Constant *getMessageSendSuperStretFn() const {
+    // void objc_msgSendSuper_stret(void * stretAddr, struct objc_super *super,
+    //                              SEL op, ...)
+    std::vector<const llvm::Type*> Params;
+    Params.push_back(Int8PtrTy);
+    Params.push_back(SuperPtrTy);
+    Params.push_back(SelectorPtrTy);
+    return CGM.CreateRuntimeFunction(
+      llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
+                              Params, true),
+      "objc_msgSendSuper_stret");
+  }
+
+  llvm::Constant *getMessageSendSuperStretFn2() const {
+    // void objc_msgSendSuper2_stret(void * stretAddr, struct objc_super *super,
+    //                               SEL op, ...)
+    std::vector<const llvm::Type*> Params;
+    Params.push_back(Int8PtrTy);
+    Params.push_back(SuperPtrTy);
+    Params.push_back(SelectorPtrTy);
+    return CGM.CreateRuntimeFunction(
+      llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
+                              Params, true),
+      "objc_msgSendSuper2_stret");
+  }
+
+  llvm::Constant *getMessageSendSuperFpretFn() const {
+    // There is no objc_msgSendSuper_fpret? How can that work?
+    return getMessageSendSuperFn();
+  }
+
+  llvm::Constant *getMessageSendSuperFpretFn2() const {
+    // There is no objc_msgSendSuper_fpret? How can that work?
+    return getMessageSendSuperFn2();
+  }
+
+protected:
+  CodeGen::CodeGenModule &CGM;
+
+public:
+  const llvm::Type *ShortTy, *IntTy, *LongTy, *LongLongTy;
+  const llvm::Type *Int8PtrTy;
+
+  /// ObjectPtrTy - LLVM type for object handles (typeof(id))
+  const llvm::Type *ObjectPtrTy;
+
+  /// PtrObjectPtrTy - LLVM type for id *
+  const llvm::Type *PtrObjectPtrTy;
+
+  /// SelectorPtrTy - LLVM type for selector handles (typeof(SEL))
+  const llvm::Type *SelectorPtrTy;
+  /// ProtocolPtrTy - LLVM type for external protocol handles
+  /// (typeof(Protocol))
+  const llvm::Type *ExternalProtocolPtrTy;
+
+  // SuperCTy - clang type for struct objc_super.
+  QualType SuperCTy;
+  // SuperPtrCTy - clang type for struct objc_super *.
+  QualType SuperPtrCTy;
+
+  /// SuperTy - LLVM type for struct objc_super.
+  const llvm::StructType *SuperTy;
+  /// SuperPtrTy - LLVM type for struct objc_super *.
+  const llvm::Type *SuperPtrTy;
+
+  /// PropertyTy - LLVM type for struct objc_property (struct _prop_t
+  /// in GCC parlance).
+  const llvm::StructType *PropertyTy;
+
+  /// PropertyListTy - LLVM type for struct objc_property_list
+  /// (_prop_list_t in GCC parlance).
+  const llvm::StructType *PropertyListTy;
+  /// PropertyListPtrTy - LLVM type for struct objc_property_list*.
+  const llvm::Type *PropertyListPtrTy;
+
+  // MethodTy - LLVM type for struct objc_method.
+  const llvm::StructType *MethodTy;
+
+  /// CacheTy - LLVM type for struct objc_cache.
+  const llvm::Type *CacheTy;
+  /// CachePtrTy - LLVM type for struct objc_cache *.
+  const llvm::Type *CachePtrTy;
+
+  llvm::Constant *getGetPropertyFn() {
+    CodeGen::CodeGenTypes &Types = CGM.getTypes();
+    ASTContext &Ctx = CGM.getContext();
+    // id objc_getProperty (id, SEL, ptrdiff_t, bool)
+    llvm::SmallVector<CanQualType,4> Params;
+    CanQualType IdType = Ctx.getCanonicalParamType(Ctx.getObjCIdType());
+    CanQualType SelType = Ctx.getCanonicalParamType(Ctx.getObjCSelType());
+    Params.push_back(IdType);
+    Params.push_back(SelType);
+    Params.push_back(Ctx.LongTy);
+    Params.push_back(Ctx.BoolTy);
+    const llvm::FunctionType *FTy =
+      Types.GetFunctionType(Types.getFunctionInfo(IdType, Params,
+                                                  FunctionType::ExtInfo()),
+                            false);
+    return CGM.CreateRuntimeFunction(FTy, "objc_getProperty");
+  }
+
+  llvm::Constant *getSetPropertyFn() {
+    CodeGen::CodeGenTypes &Types = CGM.getTypes();
+    ASTContext &Ctx = CGM.getContext();
+    // void objc_setProperty (id, SEL, ptrdiff_t, id, bool, bool)
+    llvm::SmallVector<CanQualType,6> Params;
+    CanQualType IdType = Ctx.getCanonicalParamType(Ctx.getObjCIdType());
+    CanQualType SelType = Ctx.getCanonicalParamType(Ctx.getObjCSelType());
+    Params.push_back(IdType);
+    Params.push_back(SelType);
+    Params.push_back(Ctx.LongTy);
+    Params.push_back(IdType);
+    Params.push_back(Ctx.BoolTy);
+    Params.push_back(Ctx.BoolTy);
+    const llvm::FunctionType *FTy =
+      Types.GetFunctionType(Types.getFunctionInfo(Ctx.VoidTy, Params,
+                                                  FunctionType::ExtInfo()),
+                            false);
+    return CGM.CreateRuntimeFunction(FTy, "objc_setProperty");
+  }
+
+  
+  llvm::Constant *getCopyStructFn() {
+    CodeGen::CodeGenTypes &Types = CGM.getTypes();
+    ASTContext &Ctx = CGM.getContext();
+    // void objc_copyStruct (void *, const void *, size_t, bool, bool)
+    llvm::SmallVector<CanQualType,5> Params;
+    Params.push_back(Ctx.VoidPtrTy);
+    Params.push_back(Ctx.VoidPtrTy);
+    Params.push_back(Ctx.LongTy);
+    Params.push_back(Ctx.BoolTy);
+    Params.push_back(Ctx.BoolTy);
+    const llvm::FunctionType *FTy =
+      Types.GetFunctionType(Types.getFunctionInfo(Ctx.VoidTy, Params,
+                                                  FunctionType::ExtInfo()),
+                            false);
+    return CGM.CreateRuntimeFunction(FTy, "objc_copyStruct");
+  }
+  
+  llvm::Constant *getEnumerationMutationFn() {
+    CodeGen::CodeGenTypes &Types = CGM.getTypes();
+    ASTContext &Ctx = CGM.getContext();
+    // void objc_enumerationMutation (id)
+    llvm::SmallVector<CanQualType,1> Params;
+    Params.push_back(Ctx.getCanonicalParamType(Ctx.getObjCIdType()));
+    const llvm::FunctionType *FTy =
+      Types.GetFunctionType(Types.getFunctionInfo(Ctx.VoidTy, Params,
+                                                  FunctionType::ExtInfo()),
+                            false);
+    return CGM.CreateRuntimeFunction(FTy, "objc_enumerationMutation");
+  }
+
+  /// GcReadWeakFn -- LLVM objc_read_weak (id *src) function.
+  llvm::Constant *getGcReadWeakFn() {
+    // id objc_read_weak (id *)
+    std::vector<const llvm::Type*> Args;
+    Args.push_back(ObjectPtrTy->getPointerTo());
+    llvm::FunctionType *FTy =
+      llvm::FunctionType::get(ObjectPtrTy, Args, false);
+    return CGM.CreateRuntimeFunction(FTy, "objc_read_weak");
+  }
+
+  /// GcAssignWeakFn -- LLVM objc_assign_weak function.
+  llvm::Constant *getGcAssignWeakFn() {
+    // id objc_assign_weak (id, id *)
+    std::vector<const llvm::Type*> Args(1, ObjectPtrTy);
+    Args.push_back(ObjectPtrTy->getPointerTo());
+    llvm::FunctionType *FTy =
+      llvm::FunctionType::get(ObjectPtrTy, Args, false);
+    return CGM.CreateRuntimeFunction(FTy, "objc_assign_weak");
+  }
+
+  /// GcAssignGlobalFn -- LLVM objc_assign_global function.
+  llvm::Constant *getGcAssignGlobalFn() {
+    // id objc_assign_global(id, id *)
+    std::vector<const llvm::Type*> Args(1, ObjectPtrTy);
+    Args.push_back(ObjectPtrTy->getPointerTo());
+    llvm::FunctionType *FTy =
+      llvm::FunctionType::get(ObjectPtrTy, Args, false);
+    return CGM.CreateRuntimeFunction(FTy, "objc_assign_global");
+  }
+
+  /// GcAssignIvarFn -- LLVM objc_assign_ivar function.
+  llvm::Constant *getGcAssignIvarFn() {
+    // id objc_assign_ivar(id, id *, ptrdiff_t)
+    std::vector<const llvm::Type*> Args(1, ObjectPtrTy);
+    Args.push_back(ObjectPtrTy->getPointerTo());
+    Args.push_back(LongTy);
+    llvm::FunctionType *FTy =
+      llvm::FunctionType::get(ObjectPtrTy, Args, false);
+    return CGM.CreateRuntimeFunction(FTy, "objc_assign_ivar");
+  }
+
+  /// GcMemmoveCollectableFn -- LLVM objc_memmove_collectable function.
+  llvm::Constant *GcMemmoveCollectableFn() {
+    // void *objc_memmove_collectable(void *dst, const void *src, size_t size)
+    std::vector<const llvm::Type*> Args(1, Int8PtrTy);
+    Args.push_back(Int8PtrTy);
+    Args.push_back(LongTy);
+    llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, Args, false);
+    return CGM.CreateRuntimeFunction(FTy, "objc_memmove_collectable");
+  }
+
+  /// GcAssignStrongCastFn -- LLVM objc_assign_strongCast function.
+  llvm::Constant *getGcAssignStrongCastFn() {
+    // id objc_assign_global(id, id *)
+    std::vector<const llvm::Type*> Args(1, ObjectPtrTy);
+    Args.push_back(ObjectPtrTy->getPointerTo());
+    llvm::FunctionType *FTy =
+      llvm::FunctionType::get(ObjectPtrTy, Args, false);
+    return CGM.CreateRuntimeFunction(FTy, "objc_assign_strongCast");
+  }
+
+  /// ExceptionThrowFn - LLVM objc_exception_throw function.
+  llvm::Constant *getExceptionThrowFn() {
+    // void objc_exception_throw(id)
+    std::vector<const llvm::Type*> Args(1, ObjectPtrTy);
+    llvm::FunctionType *FTy =
+      llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), Args, false);
+    return CGM.CreateRuntimeFunction(FTy, "objc_exception_throw");
+  }
+
+  /// SyncEnterFn - LLVM object_sync_enter function.
+  llvm::Constant *getSyncEnterFn() {
+    // void objc_sync_enter (id)
+    std::vector<const llvm::Type*> Args(1, ObjectPtrTy);
+    llvm::FunctionType *FTy =
+      llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), Args, false);
+    return CGM.CreateRuntimeFunction(FTy, "objc_sync_enter");
+  }
+
+  /// SyncExitFn - LLVM object_sync_exit function.
+  llvm::Constant *getSyncExitFn() {
+    // void objc_sync_exit (id)
+    std::vector<const llvm::Type*> Args(1, ObjectPtrTy);
+    llvm::FunctionType *FTy =
+      llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), Args, false);
+    return CGM.CreateRuntimeFunction(FTy, "objc_sync_exit");
+  }
+
+  llvm::Constant *getSendFn(bool IsSuper) const {
+    return IsSuper ? getMessageSendSuperFn() : getMessageSendFn();
+  }
+
+  llvm::Constant *getSendFn2(bool IsSuper) const {
+    return IsSuper ? getMessageSendSuperFn2() : getMessageSendFn();
+  }
+
+  llvm::Constant *getSendStretFn(bool IsSuper) const {
+    return IsSuper ? getMessageSendSuperStretFn() : getMessageSendStretFn();
+  }
+
+  llvm::Constant *getSendStretFn2(bool IsSuper) const {
+    return IsSuper ? getMessageSendSuperStretFn2() : getMessageSendStretFn();
+  }
+
+  llvm::Constant *getSendFpretFn(bool IsSuper) const {
+    return IsSuper ? getMessageSendSuperFpretFn() : getMessageSendFpretFn();
+  }
+
+  llvm::Constant *getSendFpretFn2(bool IsSuper) const {
+    return IsSuper ? getMessageSendSuperFpretFn2() : getMessageSendFpretFn();
+  }
+
+  ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm);
+  ~ObjCCommonTypesHelper(){}
+};
+
+/// ObjCTypesHelper - Helper class that encapsulates lazy
+/// construction of varies types used during ObjC generation.
+class ObjCTypesHelper : public ObjCCommonTypesHelper {
+public:
+  /// SymtabTy - LLVM type for struct objc_symtab.
+  const llvm::StructType *SymtabTy;
+  /// SymtabPtrTy - LLVM type for struct objc_symtab *.
+  const llvm::Type *SymtabPtrTy;
+  /// ModuleTy - LLVM type for struct objc_module.
+  const llvm::StructType *ModuleTy;
+
+  /// ProtocolTy - LLVM type for struct objc_protocol.
+  const llvm::StructType *ProtocolTy;
+  /// ProtocolPtrTy - LLVM type for struct objc_protocol *.
+  const llvm::Type *ProtocolPtrTy;
+  /// ProtocolExtensionTy - LLVM type for struct
+  /// objc_protocol_extension.
+  const llvm::StructType *ProtocolExtensionTy;
+  /// ProtocolExtensionTy - LLVM type for struct
+  /// objc_protocol_extension *.
+  const llvm::Type *ProtocolExtensionPtrTy;
+  /// MethodDescriptionTy - LLVM type for struct
+  /// objc_method_description.
+  const llvm::StructType *MethodDescriptionTy;
+  /// MethodDescriptionListTy - LLVM type for struct
+  /// objc_method_description_list.
+  const llvm::StructType *MethodDescriptionListTy;
+  /// MethodDescriptionListPtrTy - LLVM type for struct
+  /// objc_method_description_list *.
+  const llvm::Type *MethodDescriptionListPtrTy;
+  /// ProtocolListTy - LLVM type for struct objc_property_list.
+  const llvm::Type *ProtocolListTy;
+  /// ProtocolListPtrTy - LLVM type for struct objc_property_list*.
+  const llvm::Type *ProtocolListPtrTy;
+  /// CategoryTy - LLVM type for struct objc_category.
+  const llvm::StructType *CategoryTy;
+  /// ClassTy - LLVM type for struct objc_class.
+  const llvm::StructType *ClassTy;
+  /// ClassPtrTy - LLVM type for struct objc_class *.
+  const llvm::Type *ClassPtrTy;
+  /// ClassExtensionTy - LLVM type for struct objc_class_ext.
+  const llvm::StructType *ClassExtensionTy;
+  /// ClassExtensionPtrTy - LLVM type for struct objc_class_ext *.
+  const llvm::Type *ClassExtensionPtrTy;
+  // IvarTy - LLVM type for struct objc_ivar.
+  const llvm::StructType *IvarTy;
+  /// IvarListTy - LLVM type for struct objc_ivar_list.
+  const llvm::Type *IvarListTy;
+  /// IvarListPtrTy - LLVM type for struct objc_ivar_list *.
+  const llvm::Type *IvarListPtrTy;
+  /// MethodListTy - LLVM type for struct objc_method_list.
+  const llvm::Type *MethodListTy;
+  /// MethodListPtrTy - LLVM type for struct objc_method_list *.
+  const llvm::Type *MethodListPtrTy;
+
+  /// ExceptionDataTy - LLVM type for struct _objc_exception_data.
+  const llvm::Type *ExceptionDataTy;
+
+  /// ExceptionTryEnterFn - LLVM objc_exception_try_enter function.
+  llvm::Constant *getExceptionTryEnterFn() {
+    std::vector<const llvm::Type*> Params;
+    Params.push_back(llvm::PointerType::getUnqual(ExceptionDataTy));
+    return CGM.CreateRuntimeFunction(
+      llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
+                              Params, false),
+      "objc_exception_try_enter");
+  }
+
+  /// ExceptionTryExitFn - LLVM objc_exception_try_exit function.
+  llvm::Constant *getExceptionTryExitFn() {
+    std::vector<const llvm::Type*> Params;
+    Params.push_back(llvm::PointerType::getUnqual(ExceptionDataTy));
+    return CGM.CreateRuntimeFunction(
+      llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
+                              Params, false),
+      "objc_exception_try_exit");
+  }
+
+  /// ExceptionExtractFn - LLVM objc_exception_extract function.
+  llvm::Constant *getExceptionExtractFn() {
+    std::vector<const llvm::Type*> Params;
+    Params.push_back(llvm::PointerType::getUnqual(ExceptionDataTy));
+    return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
+                                                             Params, false),
+                                     "objc_exception_extract");
+
+  }
+
+  /// ExceptionMatchFn - LLVM objc_exception_match function.
+  llvm::Constant *getExceptionMatchFn() {
+    std::vector<const llvm::Type*> Params;
+    Params.push_back(ClassPtrTy);
+    Params.push_back(ObjectPtrTy);
+    return CGM.CreateRuntimeFunction(
+      llvm::FunctionType::get(llvm::Type::getInt32Ty(VMContext),
+                              Params, false),
+      "objc_exception_match");
+
+  }
+
+  /// SetJmpFn - LLVM _setjmp function.
+  llvm::Constant *getSetJmpFn() {
+    std::vector<const llvm::Type*> Params;
+    Params.push_back(llvm::Type::getInt32PtrTy(VMContext));
+    return
+      CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::getInt32Ty(VMContext),
+                                                        Params, false),
+                                "_setjmp");
+
+  }
+
+public:
+  ObjCTypesHelper(CodeGen::CodeGenModule &cgm);
+  ~ObjCTypesHelper() {}
+};
+
+/// ObjCNonFragileABITypesHelper - will have all types needed by objective-c's
+/// modern abi
+class ObjCNonFragileABITypesHelper : public ObjCCommonTypesHelper {
+public:
+
+  // MethodListnfABITy - LLVM for struct _method_list_t
+  const llvm::StructType *MethodListnfABITy;
+
+  // MethodListnfABIPtrTy - LLVM for struct _method_list_t*
+  const llvm::Type *MethodListnfABIPtrTy;
+
+  // ProtocolnfABITy = LLVM for struct _protocol_t
+  const llvm::StructType *ProtocolnfABITy;
+
+  // ProtocolnfABIPtrTy = LLVM for struct _protocol_t*
+  const llvm::Type *ProtocolnfABIPtrTy;
+
+  // ProtocolListnfABITy - LLVM for struct _objc_protocol_list
+  const llvm::StructType *ProtocolListnfABITy;
+
+  // ProtocolListnfABIPtrTy - LLVM for struct _objc_protocol_list*
+  const llvm::Type *ProtocolListnfABIPtrTy;
+
+  // ClassnfABITy - LLVM for struct _class_t
+  const llvm::StructType *ClassnfABITy;
+
+  // ClassnfABIPtrTy - LLVM for struct _class_t*
+  const llvm::Type *ClassnfABIPtrTy;
+
+  // IvarnfABITy - LLVM for struct _ivar_t
+  const llvm::StructType *IvarnfABITy;
+
+  // IvarListnfABITy - LLVM for struct _ivar_list_t
+  const llvm::StructType *IvarListnfABITy;
+
+  // IvarListnfABIPtrTy = LLVM for struct _ivar_list_t*
+  const llvm::Type *IvarListnfABIPtrTy;
+
+  // ClassRonfABITy - LLVM for struct _class_ro_t
+  const llvm::StructType *ClassRonfABITy;
+
+  // ImpnfABITy - LLVM for id (*)(id, SEL, ...)
+  const llvm::Type *ImpnfABITy;
+
+  // CategorynfABITy - LLVM for struct _category_t
+  const llvm::StructType *CategorynfABITy;
+
+  // New types for nonfragile abi messaging.
+
+  // MessageRefTy - LLVM for:
+  // struct _message_ref_t {
+  //   IMP messenger;
+  //   SEL name;
+  // };
+  const llvm::StructType *MessageRefTy;
+  // MessageRefCTy - clang type for struct _message_ref_t
+  QualType MessageRefCTy;
+
+  // MessageRefPtrTy - LLVM for struct _message_ref_t*
+  const llvm::Type *MessageRefPtrTy;
+  // MessageRefCPtrTy - clang type for struct _message_ref_t*
+  QualType MessageRefCPtrTy;
+
+  // MessengerTy - Type of the messenger (shown as IMP above)
+  const llvm::FunctionType *MessengerTy;
+
+  // SuperMessageRefTy - LLVM for:
+  // struct _super_message_ref_t {
+  //   SUPER_IMP messenger;
+  //   SEL name;
+  // };
+  const llvm::StructType *SuperMessageRefTy;
+
+  // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t*
+  const llvm::Type *SuperMessageRefPtrTy;
+
+  llvm::Constant *getMessageSendFixupFn() {
+    // id objc_msgSend_fixup(id, struct message_ref_t*, ...)
+    std::vector<const llvm::Type*> Params;
+    Params.push_back(ObjectPtrTy);
+    Params.push_back(MessageRefPtrTy);
+    return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
+                                                             Params, true),
+                                     "objc_msgSend_fixup");
+  }
+
+  llvm::Constant *getMessageSendFpretFixupFn() {
+    // id objc_msgSend_fpret_fixup(id, struct message_ref_t*, ...)
+    std::vector<const llvm::Type*> Params;
+    Params.push_back(ObjectPtrTy);
+    Params.push_back(MessageRefPtrTy);
+    return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
+                                                             Params, true),
+                                     "objc_msgSend_fpret_fixup");
+  }
+
+  llvm::Constant *getMessageSendStretFixupFn() {
+    // id objc_msgSend_stret_fixup(id, struct message_ref_t*, ...)
+    std::vector<const llvm::Type*> Params;
+    Params.push_back(ObjectPtrTy);
+    Params.push_back(MessageRefPtrTy);
+    return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
+                                                             Params, true),
+                                     "objc_msgSend_stret_fixup");
+  }
+
+  llvm::Constant *getMessageSendIdFixupFn() {
+    // id objc_msgSendId_fixup(id, struct message_ref_t*, ...)
+    std::vector<const llvm::Type*> Params;
+    Params.push_back(ObjectPtrTy);
+    Params.push_back(MessageRefPtrTy);
+    return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
+                                                             Params, true),
+                                     "objc_msgSendId_fixup");
+  }
+
+  llvm::Constant *getMessageSendIdStretFixupFn() {
+    // id objc_msgSendId_stret_fixup(id, struct message_ref_t*, ...)
+    std::vector<const llvm::Type*> Params;
+    Params.push_back(ObjectPtrTy);
+    Params.push_back(MessageRefPtrTy);
+    return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
+                                                             Params, true),
+                                     "objc_msgSendId_stret_fixup");
+  }
+  llvm::Constant *getMessageSendSuper2FixupFn() {
+    // id objc_msgSendSuper2_fixup (struct objc_super *,
+    //                              struct _super_message_ref_t*, ...)
+    std::vector<const llvm::Type*> Params;
+    Params.push_back(SuperPtrTy);
+    Params.push_back(SuperMessageRefPtrTy);
+    return  CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
+                                                              Params, true),
+                                      "objc_msgSendSuper2_fixup");
+  }
+
+  llvm::Constant *getMessageSendSuper2StretFixupFn() {
+    // id objc_msgSendSuper2_stret_fixup(struct objc_super *,
+    //                                   struct _super_message_ref_t*, ...)
+    std::vector<const llvm::Type*> Params;
+    Params.push_back(SuperPtrTy);
+    Params.push_back(SuperMessageRefPtrTy);
+    return  CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
+                                                              Params, true),
+                                      "objc_msgSendSuper2_stret_fixup");
+  }
+
+
+
+  /// EHPersonalityPtr - LLVM value for an i8* to the Objective-C
+  /// exception personality function.
+  llvm::Value *getEHPersonalityPtr() {
+    llvm::Constant *Personality =
+      CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::getInt32Ty(VMContext),
+                                                        true),
+                                "__objc_personality_v0");
+    return llvm::ConstantExpr::getBitCast(Personality, Int8PtrTy);
+  }
+
+  llvm::Constant *getUnwindResumeOrRethrowFn() {
+    std::vector<const llvm::Type*> Params;
+    Params.push_back(Int8PtrTy);
+    return CGM.CreateRuntimeFunction(
+      llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
+                              Params, false),
+      (CGM.getLangOptions().SjLjExceptions ? "_Unwind_SjLj_Resume" :
+       "_Unwind_Resume_or_Rethrow"));
+  }
+
+  llvm::Constant *getObjCEndCatchFn() {
+    return CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
+                                                             false),
+                                     "objc_end_catch");
+
+  }
+
+  llvm::Constant *getObjCBeginCatchFn() {
+    std::vector<const llvm::Type*> Params;
+    Params.push_back(Int8PtrTy);
+    return CGM.CreateRuntimeFunction(llvm::FunctionType::get(Int8PtrTy,
+                                                             Params, false),
+                                     "objc_begin_catch");
+  }
+
+  const llvm::StructType *EHTypeTy;
+  const llvm::Type *EHTypePtrTy;
+
+  ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm);
+  ~ObjCNonFragileABITypesHelper(){}
+};
+
+class CGObjCCommonMac : public CodeGen::CGObjCRuntime {
+public:
+  // FIXME - accessibility
+  class GC_IVAR {
+  public:
+    unsigned ivar_bytepos;
+    unsigned ivar_size;
+    GC_IVAR(unsigned bytepos = 0, unsigned size = 0)
+      : ivar_bytepos(bytepos), ivar_size(size) {}
+
+    // Allow sorting based on byte pos.
+    bool operator<(const GC_IVAR &b) const {
+      return ivar_bytepos < b.ivar_bytepos;
+    }
+  };
+
+  class SKIP_SCAN {
+  public:
+    unsigned skip;
+    unsigned scan;
+    SKIP_SCAN(unsigned _skip = 0, unsigned _scan = 0)
+      : skip(_skip), scan(_scan) {}
+  };
+
+protected:
+  CodeGen::CodeGenModule &CGM;
+  llvm::LLVMContext &VMContext;
+  // FIXME! May not be needing this after all.
+  unsigned ObjCABI;
+
+  // gc ivar layout bitmap calculation helper caches.
+  llvm::SmallVector<GC_IVAR, 16> SkipIvars;
+  llvm::SmallVector<GC_IVAR, 16> IvarsInfo;
+
+  /// LazySymbols - Symbols to generate a lazy reference for. See
+  /// DefinedSymbols and FinishModule().
+  llvm::SetVector<IdentifierInfo*> LazySymbols;
+
+  /// DefinedSymbols - External symbols which are defined by this
+  /// module. The symbols in this list and LazySymbols are used to add
+  /// special linker symbols which ensure that Objective-C modules are
+  /// linked properly.
+  llvm::SetVector<IdentifierInfo*> DefinedSymbols;
+
+  /// ClassNames - uniqued class names.
+  llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassNames;
+
+  /// MethodVarNames - uniqued method variable names.
+  llvm::DenseMap<Selector, llvm::GlobalVariable*> MethodVarNames;
+
+  /// MethodVarTypes - uniqued method type signatures. We have to use
+  /// a StringMap here because have no other unique reference.
+  llvm::StringMap<llvm::GlobalVariable*> MethodVarTypes;
+
+  /// MethodDefinitions - map of methods which have been defined in
+  /// this translation unit.
+  llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*> MethodDefinitions;
+
+  /// PropertyNames - uniqued method variable names.
+  llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> PropertyNames;
+
+  /// ClassReferences - uniqued class references.
+  llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassReferences;
+
+  /// SelectorReferences - uniqued selector references.
+  llvm::DenseMap<Selector, llvm::GlobalVariable*> SelectorReferences;
+
+  /// Protocols - Protocols for which an objc_protocol structure has
+  /// been emitted. Forward declarations are handled by creating an
+  /// empty structure whose initializer is filled in when/if defined.
+  llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> Protocols;
+
+  /// DefinedProtocols - Protocols which have actually been
+  /// defined. We should not need this, see FIXME in GenerateProtocol.
+  llvm::DenseSet<IdentifierInfo*> DefinedProtocols;
+
+  /// DefinedClasses - List of defined classes.
+  std::vector<llvm::GlobalValue*> DefinedClasses;
+
+  /// DefinedNonLazyClasses - List of defined "non-lazy" classes.
+  std::vector<llvm::GlobalValue*> DefinedNonLazyClasses;
+
+  /// DefinedCategories - List of defined categories.
+  std::vector<llvm::GlobalValue*> DefinedCategories;
+
+  /// DefinedNonLazyCategories - List of defined "non-lazy" categories.
+  std::vector<llvm::GlobalValue*> DefinedNonLazyCategories;
+
+  /// GetNameForMethod - Return a name for the given method.
+  /// \param[out] NameOut - The return value.
+  void GetNameForMethod(const ObjCMethodDecl *OMD,
+                        const ObjCContainerDecl *CD,
+                        llvm::SmallVectorImpl<char> &NameOut);
+
+  /// GetMethodVarName - Return a unique constant for the given
+  /// selector's name. The return value has type char *.
+  llvm::Constant *GetMethodVarName(Selector Sel);
+  llvm::Constant *GetMethodVarName(IdentifierInfo *Ident);
+  llvm::Constant *GetMethodVarName(const std::string &Name);
+
+  /// GetMethodVarType - Return a unique constant for the given
+  /// selector's name. The return value has type char *.
+
+  // FIXME: This is a horrible name.
+  llvm::Constant *GetMethodVarType(const ObjCMethodDecl *D);
+  llvm::Constant *GetMethodVarType(const FieldDecl *D);
+
+  /// GetPropertyName - Return a unique constant for the given
+  /// name. The return value has type char *.
+  llvm::Constant *GetPropertyName(IdentifierInfo *Ident);
+
+  // FIXME: This can be dropped once string functions are unified.
+  llvm::Constant *GetPropertyTypeString(const ObjCPropertyDecl *PD,
+                                        const Decl *Container);
+
+  /// GetClassName - Return a unique constant for the given selector's
+  /// name. The return value has type char *.
+  llvm::Constant *GetClassName(IdentifierInfo *Ident);
+
+  /// BuildIvarLayout - Builds ivar layout bitmap for the class
+  /// implementation for the __strong or __weak case.
+  ///
+  llvm::Constant *BuildIvarLayout(const ObjCImplementationDecl *OI,
+                                  bool ForStrongLayout);
+
+  void BuildAggrIvarRecordLayout(const RecordType *RT,
+                                 unsigned int BytePos, bool ForStrongLayout,
+                                 bool &HasUnion);
+  void BuildAggrIvarLayout(const ObjCImplementationDecl *OI,
+                           const llvm::StructLayout *Layout,
+                           const RecordDecl *RD,
+                           const llvm::SmallVectorImpl<FieldDecl*> &RecFields,
+                           unsigned int BytePos, bool ForStrongLayout,
+                           bool &HasUnion);
+
+  /// GetIvarLayoutName - Returns a unique constant for the given
+  /// ivar layout bitmap.
+  llvm::Constant *GetIvarLayoutName(IdentifierInfo *Ident,
+                                    const ObjCCommonTypesHelper &ObjCTypes);
+
+  /// EmitPropertyList - Emit the given property list. The return
+  /// value has type PropertyListPtrTy.
+  llvm::Constant *EmitPropertyList(llvm::Twine Name,
+                                   const Decl *Container,
+                                   const ObjCContainerDecl *OCD,
+                                   const ObjCCommonTypesHelper &ObjCTypes);
+
+  /// PushProtocolProperties - Push protocol's property on the input stack.
+  void PushProtocolProperties(llvm::SmallPtrSet<const IdentifierInfo*, 16> &PropertySet,
+                              std::vector<llvm::Constant*> &Properties,
+                                   const Decl *Container,
+                                   const ObjCProtocolDecl *PROTO,
+                                   const ObjCCommonTypesHelper &ObjCTypes);
+
+  /// GetProtocolRef - Return a reference to the internal protocol
+  /// description, creating an empty one if it has not been
+  /// defined. The return value has type ProtocolPtrTy.
+  llvm::Constant *GetProtocolRef(const ObjCProtocolDecl *PD);
+
+  /// CreateMetadataVar - Create a global variable with internal
+  /// linkage for use by the Objective-C runtime.
+  ///
+  /// This is a convenience wrapper which not only creates the
+  /// variable, but also sets the section and alignment and adds the
+  /// global to the "llvm.used" list.
+  ///
+  /// \param Name - The variable name.
+  /// \param Init - The variable initializer; this is also used to
+  /// define the type of the variable.
+  /// \param Section - The section the variable should go into, or 0.
+  /// \param Align - The alignment for the variable, or 0.
+  /// \param AddToUsed - Whether the variable should be added to
+  /// "llvm.used".
+  llvm::GlobalVariable *CreateMetadataVar(llvm::Twine Name,
+                                          llvm::Constant *Init,
+                                          const char *Section,
+                                          unsigned Align,
+                                          bool AddToUsed);
+
+  CodeGen::RValue EmitLegacyMessageSend(CodeGen::CodeGenFunction &CGF,
+                                        QualType ResultType,
+                                        llvm::Value *Sel,
+                                        llvm::Value *Arg0,
+                                        QualType Arg0Ty,
+                                        bool IsSuper,
+                                        const CallArgList &CallArgs,
+                                        const ObjCMethodDecl *OMD,
+                                        const ObjCCommonTypesHelper &ObjCTypes);
+
+  /// EmitImageInfo - Emit the image info marker used to encode some module
+  /// level information.
+  void EmitImageInfo();
+
+public:
+  CGObjCCommonMac(CodeGen::CodeGenModule &cgm) :
+    CGM(cgm), VMContext(cgm.getLLVMContext()) { }
+
+  virtual llvm::Constant *GenerateConstantString(const StringLiteral *SL);
+
+  virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD,
+                                         const ObjCContainerDecl *CD=0);
+
+  virtual void GenerateProtocol(const ObjCProtocolDecl *PD);
+
+  /// GetOrEmitProtocol - Get the protocol object for the given
+  /// declaration, emitting it if necessary. The return value has type
+  /// ProtocolPtrTy.
+  virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD)=0;
+
+  /// GetOrEmitProtocolRef - Get a forward reference to the protocol
+  /// object for the given declaration, emitting it if needed. These
+  /// forward references will be filled in with empty bodies if no
+  /// definition is seen. The return value has type ProtocolPtrTy.
+  virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD)=0;
+};
+
+class CGObjCMac : public CGObjCCommonMac {
+private:
+  ObjCTypesHelper ObjCTypes;
+
+  /// EmitModuleInfo - Another marker encoding module level
+  /// information.
+  void EmitModuleInfo();
+
+  /// EmitModuleSymols - Emit module symbols, the list of defined
+  /// classes and categories. The result has type SymtabPtrTy.
+  llvm::Constant *EmitModuleSymbols();
+
+  /// FinishModule - Write out global data structures at the end of
+  /// processing a translation unit.
+  void FinishModule();
+
+  /// EmitClassExtension - Generate the class extension structure used
+  /// to store the weak ivar layout and properties. The return value
+  /// has type ClassExtensionPtrTy.
+  llvm::Constant *EmitClassExtension(const ObjCImplementationDecl *ID);
+
+  /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
+  /// for the given class.
+  llvm::Value *EmitClassRef(CGBuilderTy &Builder,
+                            const ObjCInterfaceDecl *ID);
+  
+  /// EmitSuperClassRef - Emits reference to class's main metadata class.
+  llvm::Value *EmitSuperClassRef(const ObjCInterfaceDecl *ID);
+
+  CodeGen::RValue EmitMessageSend(CodeGen::CodeGenFunction &CGF,
+                                  QualType ResultType,
+                                  Selector Sel,
+                                  llvm::Value *Arg0,
+                                  QualType Arg0Ty,
+                                  bool IsSuper,
+                                  const CallArgList &CallArgs);
+
+  /// EmitIvarList - Emit the ivar list for the given
+  /// implementation. If ForClass is true the list of class ivars
+  /// (i.e. metaclass ivars) is emitted, otherwise the list of
+  /// interface ivars will be emitted. The return value has type
+  /// IvarListPtrTy.
+  llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID,
+                               bool ForClass);
+
+  /// EmitMetaClass - Emit a forward reference to the class structure
+  /// for the metaclass of the given interface. The return value has
+  /// type ClassPtrTy.
+  llvm::Constant *EmitMetaClassRef(const ObjCInterfaceDecl *ID);
+
+  /// EmitMetaClass - Emit a class structure for the metaclass of the
+  /// given implementation. The return value has type ClassPtrTy.
+  llvm::Constant *EmitMetaClass(const ObjCImplementationDecl *ID,
+                                llvm::Constant *Protocols,
+                                const ConstantVector &Methods);
+
+  llvm::Constant *GetMethodConstant(const ObjCMethodDecl *MD);
+
+  llvm::Constant *GetMethodDescriptionConstant(const ObjCMethodDecl *MD);
+
+  /// EmitMethodList - Emit the method list for the given
+  /// implementation. The return value has type MethodListPtrTy.
+  llvm::Constant *EmitMethodList(llvm::Twine Name,
+                                 const char *Section,
+                                 const ConstantVector &Methods);
+
+  /// EmitMethodDescList - Emit a method description list for a list of
+  /// method declarations.
+  ///  - TypeName: The name for the type containing the methods.
+  ///  - IsProtocol: True iff these methods are for a protocol.
+  ///  - ClassMethds: True iff these are class methods.
+  ///  - Required: When true, only "required" methods are
+  ///    listed. Similarly, when false only "optional" methods are
+  ///    listed. For classes this should always be true.
+  ///  - begin, end: The method list to output.
+  ///
+  /// The return value has type MethodDescriptionListPtrTy.
+  llvm::Constant *EmitMethodDescList(llvm::Twine Name,
+                                     const char *Section,
+                                     const ConstantVector &Methods);
+
+  /// GetOrEmitProtocol - Get the protocol object for the given
+  /// declaration, emitting it if necessary. The return value has type
+  /// ProtocolPtrTy.
+  virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD);
+
+  /// GetOrEmitProtocolRef - Get a forward reference to the protocol
+  /// object for the given declaration, emitting it if needed. These
+  /// forward references will be filled in with empty bodies if no
+  /// definition is seen. The return value has type ProtocolPtrTy.
+  virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD);
+
+  /// EmitProtocolExtension - Generate the protocol extension
+  /// structure used to store optional instance and class methods, and
+  /// protocol properties. The return value has type
+  /// ProtocolExtensionPtrTy.
+  llvm::Constant *
+  EmitProtocolExtension(const ObjCProtocolDecl *PD,
+                        const ConstantVector &OptInstanceMethods,
+                        const ConstantVector &OptClassMethods);
+
+  /// EmitProtocolList - Generate the list of referenced
+  /// protocols. The return value has type ProtocolListPtrTy.
+  llvm::Constant *EmitProtocolList(llvm::Twine Name,
+                                   ObjCProtocolDecl::protocol_iterator begin,
+                                   ObjCProtocolDecl::protocol_iterator end);
+
+  /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy,
+  /// for the given selector.
+  llvm::Value *EmitSelector(CGBuilderTy &Builder, Selector Sel);
+
+public:
+  CGObjCMac(CodeGen::CodeGenModule &cgm);
+
+  virtual llvm::Function *ModuleInitFunction();
+
+  virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
+                                              QualType ResultType,
+                                              Selector Sel,
+                                              llvm::Value *Receiver,
+                                              bool IsClassMessage,
+                                              const CallArgList &CallArgs,
+                                              const ObjCMethodDecl *Method);
+
+  virtual CodeGen::RValue
+  GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
+                           QualType ResultType,
+                           Selector Sel,
+                           const ObjCInterfaceDecl *Class,
+                           bool isCategoryImpl,
+                           llvm::Value *Receiver,
+                           bool IsClassMessage,
+                           const CallArgList &CallArgs,
+                           const ObjCMethodDecl *Method);
+
+  virtual llvm::Value *GetClass(CGBuilderTy &Builder,
+                                const ObjCInterfaceDecl *ID);
+
+  virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel);
+
+  /// The NeXT/Apple runtimes do not support typed selectors; just emit an
+  /// untyped one.
+  virtual llvm::Value *GetSelector(CGBuilderTy &Builder,
+                                   const ObjCMethodDecl *Method);
+
+  virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD);
+
+  virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl);
+
+  virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder,
+                                           const ObjCProtocolDecl *PD);
+
+  virtual llvm::Constant *GetPropertyGetFunction();
+  virtual llvm::Constant *GetPropertySetFunction();
+  virtual llvm::Constant *GetCopyStructFunction();
+  virtual llvm::Constant *EnumerationMutationFunction();
+
+  virtual void EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
+                                         const Stmt &S);
+  virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
+                             const ObjCAtThrowStmt &S);
+  virtual llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
+                                         llvm::Value *AddrWeakObj);
+  virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
+                                  llvm::Value *src, llvm::Value *dst);
+  virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
+                                    llvm::Value *src, llvm::Value *dest);
+  virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
+                                  llvm::Value *src, llvm::Value *dest,
+                                  llvm::Value *ivarOffset);
+  virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
+                                        llvm::Value *src, llvm::Value *dest);
+  virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
+                                        llvm::Value *dest, llvm::Value *src,
+                                        QualType Ty);
+
+  virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
+                                      QualType ObjectTy,
+                                      llvm::Value *BaseValue,
+                                      const ObjCIvarDecl *Ivar,
+                                      unsigned CVRQualifiers);
+  virtual llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
+                                      const ObjCInterfaceDecl *Interface,
+                                      const ObjCIvarDecl *Ivar);
+};
+
+class CGObjCNonFragileABIMac : public CGObjCCommonMac {
+private:
+  ObjCNonFragileABITypesHelper ObjCTypes;
+  llvm::GlobalVariable* ObjCEmptyCacheVar;
+  llvm::GlobalVariable* ObjCEmptyVtableVar;
+
+  /// SuperClassReferences - uniqued super class references.
+  llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> SuperClassReferences;
+
+  /// MetaClassReferences - uniqued meta class references.
+  llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> MetaClassReferences;
+
+  /// EHTypeReferences - uniqued class ehtype references.
+  llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> EHTypeReferences;
+
+  /// NonLegacyDispatchMethods - List of methods for which we do *not* generate
+  /// legacy messaging dispatch.
+  llvm::DenseSet<Selector> NonLegacyDispatchMethods;
+
+  /// DefinedMetaClasses - List of defined meta-classes.
+  std::vector<llvm::GlobalValue*> DefinedMetaClasses;
+  
+  /// LegacyDispatchedSelector - Returns true if SEL is not in the list of
+  /// NonLegacyDispatchMethods; false otherwise.
+  bool LegacyDispatchedSelector(Selector Sel);
+
+  /// FinishNonFragileABIModule - Write out global data structures at the end of
+  /// processing a translation unit.
+  void FinishNonFragileABIModule();
+
+  /// AddModuleClassList - Add the given list of class pointers to the
+  /// module with the provided symbol and section names.
+  void AddModuleClassList(const std::vector<llvm::GlobalValue*> &Container,
+                          const char *SymbolName,
+                          const char *SectionName);
+
+  llvm::GlobalVariable * BuildClassRoTInitializer(unsigned flags,
+                                              unsigned InstanceStart,
+                                              unsigned InstanceSize,
+                                              const ObjCImplementationDecl *ID);
+  llvm::GlobalVariable * BuildClassMetaData(std::string &ClassName,
+                                            llvm::Constant *IsAGV,
+                                            llvm::Constant *SuperClassGV,
+                                            llvm::Constant *ClassRoGV,
+                                            bool HiddenVisibility);
+
+  llvm::Constant *GetMethodConstant(const ObjCMethodDecl *MD);
+
+  llvm::Constant *GetMethodDescriptionConstant(const ObjCMethodDecl *MD);
+
+  /// EmitMethodList - Emit the method list for the given
+  /// implementation. The return value has type MethodListnfABITy.
+  llvm::Constant *EmitMethodList(llvm::Twine Name,
+                                 const char *Section,
+                                 const ConstantVector &Methods);
+  /// EmitIvarList - Emit the ivar list for the given
+  /// implementation. If ForClass is true the list of class ivars
+  /// (i.e. metaclass ivars) is emitted, otherwise the list of
+  /// interface ivars will be emitted. The return value has type
+  /// IvarListnfABIPtrTy.
+  llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID);
+
+  llvm::Constant *EmitIvarOffsetVar(const ObjCInterfaceDecl *ID,
+                                    const ObjCIvarDecl *Ivar,
+                                    unsigned long int offset);
+
+  /// GetOrEmitProtocol - Get the protocol object for the given
+  /// declaration, emitting it if necessary. The return value has type
+  /// ProtocolPtrTy.
+  virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD);
+
+  /// GetOrEmitProtocolRef - Get a forward reference to the protocol
+  /// object for the given declaration, emitting it if needed. These
+  /// forward references will be filled in with empty bodies if no
+  /// definition is seen. The return value has type ProtocolPtrTy.
+  virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD);
+
+  /// EmitProtocolList - Generate the list of referenced
+  /// protocols. The return value has type ProtocolListPtrTy.
+  llvm::Constant *EmitProtocolList(llvm::Twine Name,
+                                   ObjCProtocolDecl::protocol_iterator begin,
+                                   ObjCProtocolDecl::protocol_iterator end);
+
+  CodeGen::RValue EmitMessageSend(CodeGen::CodeGenFunction &CGF,
+                                  QualType ResultType,
+                                  Selector Sel,
+                                  llvm::Value *Receiver,
+                                  QualType Arg0Ty,
+                                  bool IsSuper,
+                                  const CallArgList &CallArgs);
+
+  /// GetClassGlobal - Return the global variable for the Objective-C
+  /// class of the given name.
+  llvm::GlobalVariable *GetClassGlobal(const std::string &Name);
+
+  /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
+  /// for the given class reference.
+  llvm::Value *EmitClassRef(CGBuilderTy &Builder,
+                            const ObjCInterfaceDecl *ID);
+
+  /// EmitSuperClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
+  /// for the given super class reference.
+  llvm::Value *EmitSuperClassRef(CGBuilderTy &Builder,
+                                 const ObjCInterfaceDecl *ID);
+
+  /// EmitMetaClassRef - Return a Value * of the address of _class_t
+  /// meta-data
+  llvm::Value *EmitMetaClassRef(CGBuilderTy &Builder,
+                                const ObjCInterfaceDecl *ID);
+
+  /// ObjCIvarOffsetVariable - Returns the ivar offset variable for
+  /// the given ivar.
+  ///
+  llvm::GlobalVariable * ObjCIvarOffsetVariable(
+    const ObjCInterfaceDecl *ID,
+    const ObjCIvarDecl *Ivar);
+
+  /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy,
+  /// for the given selector.
+  llvm::Value *EmitSelector(CGBuilderTy &Builder, Selector Sel);
+
+  /// GetInterfaceEHType - Get the cached ehtype for the given Objective-C
+  /// interface. The return value has type EHTypePtrTy.
+  llvm::Value *GetInterfaceEHType(const ObjCInterfaceDecl *ID,
+                                  bool ForDefinition);
+
+  const char *getMetaclassSymbolPrefix() const {
+    return "OBJC_METACLASS_$_";
+  }
+
+  const char *getClassSymbolPrefix() const {
+    return "OBJC_CLASS_$_";
+  }
+
+  void GetClassSizeInfo(const ObjCImplementationDecl *OID,
+                        uint32_t &InstanceStart,
+                        uint32_t &InstanceSize);
+
+  // Shamelessly stolen from Analysis/CFRefCount.cpp
+  Selector GetNullarySelector(const char* name) const {
+    IdentifierInfo* II = &CGM.getContext().Idents.get(name);
+    return CGM.getContext().Selectors.getSelector(0, &II);
+  }
+
+  Selector GetUnarySelector(const char* name) const {
+    IdentifierInfo* II = &CGM.getContext().Idents.get(name);
+    return CGM.getContext().Selectors.getSelector(1, &II);
+  }
+
+  /// ImplementationIsNonLazy - Check whether the given category or
+  /// class implementation is "non-lazy".
+  bool ImplementationIsNonLazy(const ObjCImplDecl *OD) const;
+
+public:
+  CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm);
+  // FIXME. All stubs for now!
+  virtual llvm::Function *ModuleInitFunction();
+
+  virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
+                                              QualType ResultType,
+                                              Selector Sel,
+                                              llvm::Value *Receiver,
+                                              bool IsClassMessage,
+                                              const CallArgList &CallArgs,
+                                              const ObjCMethodDecl *Method);
+
+  virtual CodeGen::RValue
+  GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
+                           QualType ResultType,
+                           Selector Sel,
+                           const ObjCInterfaceDecl *Class,
+                           bool isCategoryImpl,
+                           llvm::Value *Receiver,
+                           bool IsClassMessage,
+                           const CallArgList &CallArgs,
+                           const ObjCMethodDecl *Method);
+
+  virtual llvm::Value *GetClass(CGBuilderTy &Builder,
+                                const ObjCInterfaceDecl *ID);
+
+  virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel)
+    { return EmitSelector(Builder, Sel); }
+
+  /// The NeXT/Apple runtimes do not support typed selectors; just emit an
+  /// untyped one.
+  virtual llvm::Value *GetSelector(CGBuilderTy &Builder,
+                                   const ObjCMethodDecl *Method)
+    { return EmitSelector(Builder, Method->getSelector()); }
+
+  virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD);
+
+  virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl);
+  virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder,
+                                           const ObjCProtocolDecl *PD);
+
+  virtual llvm::Constant *GetPropertyGetFunction() {
+    return ObjCTypes.getGetPropertyFn();
+  }
+  virtual llvm::Constant *GetPropertySetFunction() {
+    return ObjCTypes.getSetPropertyFn();
+  }
+  
+  virtual llvm::Constant *GetCopyStructFunction() {
+    return ObjCTypes.getCopyStructFn();
+  }
+  
+  virtual llvm::Constant *EnumerationMutationFunction() {
+    return ObjCTypes.getEnumerationMutationFn();
+  }
+
+  virtual void EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
+                                         const Stmt &S);
+  virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
+                             const ObjCAtThrowStmt &S);
+  virtual llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
+                                         llvm::Value *AddrWeakObj);
+  virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
+                                  llvm::Value *src, llvm::Value *dst);
+  virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
+                                    llvm::Value *src, llvm::Value *dest);
+  virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
+                                  llvm::Value *src, llvm::Value *dest,
+                                  llvm::Value *ivarOffset);
+  virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
+                                        llvm::Value *src, llvm::Value *dest);
+  virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
+                                        llvm::Value *dest, llvm::Value *src,
+                                        QualType Ty);
+  virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
+                                      QualType ObjectTy,
+                                      llvm::Value *BaseValue,
+                                      const ObjCIvarDecl *Ivar,
+                                      unsigned CVRQualifiers);
+  virtual llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
+                                      const ObjCInterfaceDecl *Interface,
+                                      const ObjCIvarDecl *Ivar);
+};
+
+} // end anonymous namespace
+
+/* *** Helper Functions *** */
+
+/// getConstantGEP() - Help routine to construct simple GEPs.
+static llvm::Constant *getConstantGEP(llvm::LLVMContext &VMContext,
+                                      llvm::Constant *C,
+                                      unsigned idx0,
+                                      unsigned idx1) {
+  llvm::Value *Idxs[] = {
+    llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx0),
+    llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx1)
+  };
+  return llvm::ConstantExpr::getGetElementPtr(C, Idxs, 2);
+}
+
+/// hasObjCExceptionAttribute - Return true if this class or any super
+/// class has the __objc_exception__ attribute.
+static bool hasObjCExceptionAttribute(ASTContext &Context,
+                                      const ObjCInterfaceDecl *OID) {
+  if (OID->hasAttr<ObjCExceptionAttr>())
+    return true;
+  if (const ObjCInterfaceDecl *Super = OID->getSuperClass())
+    return hasObjCExceptionAttribute(Context, Super);
+  return false;
+}
+
+/* *** CGObjCMac Public Interface *** */
+
+CGObjCMac::CGObjCMac(CodeGen::CodeGenModule &cgm) : CGObjCCommonMac(cgm),
+                                                    ObjCTypes(cgm) {
+  ObjCABI = 1;
+  EmitImageInfo();
+}
+
+/// GetClass - Return a reference to the class for the given interface
+/// decl.
+llvm::Value *CGObjCMac::GetClass(CGBuilderTy &Builder,
+                                 const ObjCInterfaceDecl *ID) {
+  return EmitClassRef(Builder, ID);
+}
+
+/// GetSelector - Return the pointer to the unique'd string for this selector.
+llvm::Value *CGObjCMac::GetSelector(CGBuilderTy &Builder, Selector Sel) {
+  return EmitSelector(Builder, Sel);
+}
+llvm::Value *CGObjCMac::GetSelector(CGBuilderTy &Builder, const ObjCMethodDecl
+                                    *Method) {
+  return EmitSelector(Builder, Method->getSelector());
+}
+
+/// Generate a constant CFString object.
+/*
+  struct __builtin_CFString {
+  const int *isa; // point to __CFConstantStringClassReference
+  int flags;
+  const char *str;
+  long length;
+  };
+*/
+
+/// or Generate a constant NSString object.
+/*
+   struct __builtin_NSString {
+     const int *isa; // point to __NSConstantStringClassReference
+     const char *str;
+     unsigned int length;
+   };
+*/
+
+llvm::Constant *CGObjCCommonMac::GenerateConstantString(
+  const StringLiteral *SL) {
+  return (CGM.getLangOptions().NoConstantCFStrings == 0 ? 
+          CGM.GetAddrOfConstantCFString(SL) :
+          CGM.GetAddrOfConstantNSString(SL));
+}
+
+/// Generates a message send where the super is the receiver.  This is
+/// a message send to self with special delivery semantics indicating
+/// which class's method should be called.
+CodeGen::RValue
+CGObjCMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
+                                    QualType ResultType,
+                                    Selector Sel,
+                                    const ObjCInterfaceDecl *Class,
+                                    bool isCategoryImpl,
+                                    llvm::Value *Receiver,
+                                    bool IsClassMessage,
+                                    const CodeGen::CallArgList &CallArgs,
+                                    const ObjCMethodDecl *Method) {
+  // Create and init a super structure; this is a (receiver, class)
+  // pair we will pass to objc_msgSendSuper.
+  llvm::Value *ObjCSuper =
+    CGF.Builder.CreateAlloca(ObjCTypes.SuperTy, 0, "objc_super");
+  llvm::Value *ReceiverAsObject =
+    CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);
+  CGF.Builder.CreateStore(ReceiverAsObject,
+                          CGF.Builder.CreateStructGEP(ObjCSuper, 0));
+
+  // If this is a class message the metaclass is passed as the target.
+  llvm::Value *Target;
+  if (IsClassMessage) {
+    if (isCategoryImpl) {
+      // Message sent to 'super' in a class method defined in a category
+      // implementation requires an odd treatment.
+      // If we are in a class method, we must retrieve the
+      // _metaclass_ for the current class, pointed at by
+      // the class's "isa" pointer.  The following assumes that
+      // isa" is the first ivar in a class (which it must be).
+      Target = EmitClassRef(CGF.Builder, Class->getSuperClass());
+      Target = CGF.Builder.CreateStructGEP(Target, 0);
+      Target = CGF.Builder.CreateLoad(Target);
+    } else {
+      llvm::Value *MetaClassPtr = EmitMetaClassRef(Class);
+      llvm::Value *SuperPtr = CGF.Builder.CreateStructGEP(MetaClassPtr, 1);
+      llvm::Value *Super = CGF.Builder.CreateLoad(SuperPtr);
+      Target = Super;
+    }
+  } 
+  else if (isCategoryImpl)
+    Target = EmitClassRef(CGF.Builder, Class->getSuperClass());
+  else {
+    llvm::Value *ClassPtr = EmitSuperClassRef(Class);
+    ClassPtr = CGF.Builder.CreateStructGEP(ClassPtr, 1);
+    Target = CGF.Builder.CreateLoad(ClassPtr);
+  }
+  // FIXME: We shouldn't need to do this cast, rectify the ASTContext and
+  // ObjCTypes types.
+  const llvm::Type *ClassTy =
+    CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType());
+  Target = CGF.Builder.CreateBitCast(Target, ClassTy);
+  CGF.Builder.CreateStore(Target,
+                          CGF.Builder.CreateStructGEP(ObjCSuper, 1));
+  return EmitLegacyMessageSend(CGF, ResultType,
+                               EmitSelector(CGF.Builder, Sel),
+                               ObjCSuper, ObjCTypes.SuperPtrCTy,
+                               true, CallArgs, Method, ObjCTypes);
+}
+
+/// Generate code for a message send expression.
+CodeGen::RValue CGObjCMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
+                                               QualType ResultType,
+                                               Selector Sel,
+                                               llvm::Value *Receiver,
+                                               bool IsClassMessage,
+                                               const CallArgList &CallArgs,
+                                               const ObjCMethodDecl *Method) {
+  return EmitLegacyMessageSend(CGF, ResultType,
+                               EmitSelector(CGF.Builder, Sel),
+                               Receiver, CGF.getContext().getObjCIdType(),
+                               false, CallArgs, Method, ObjCTypes);
+}
+
+CodeGen::RValue
+CGObjCCommonMac::EmitLegacyMessageSend(CodeGen::CodeGenFunction &CGF,
+                                       QualType ResultType,
+                                       llvm::Value *Sel,
+                                       llvm::Value *Arg0,
+                                       QualType Arg0Ty,
+                                       bool IsSuper,
+                                       const CallArgList &CallArgs,
+                                       const ObjCMethodDecl *Method,
+                                       const ObjCCommonTypesHelper &ObjCTypes) {
+  CallArgList ActualArgs;
+  if (!IsSuper)
+    Arg0 = CGF.Builder.CreateBitCast(Arg0, ObjCTypes.ObjectPtrTy, "tmp");
+  ActualArgs.push_back(std::make_pair(RValue::get(Arg0), Arg0Ty));
+  ActualArgs.push_back(std::make_pair(RValue::get(Sel),
+                                      CGF.getContext().getObjCSelType()));
+  ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end());
+
+  CodeGenTypes &Types = CGM.getTypes();
+  const CGFunctionInfo &FnInfo = Types.getFunctionInfo(ResultType, ActualArgs,
+                                                       FunctionType::ExtInfo());
+  const llvm::FunctionType *FTy =
+    Types.GetFunctionType(FnInfo, Method ? Method->isVariadic() : false);
+
+  llvm::Constant *Fn = NULL;
+  if (CGM.ReturnTypeUsesSret(FnInfo)) {
+    Fn = (ObjCABI == 2) ?  ObjCTypes.getSendStretFn2(IsSuper)
+      : ObjCTypes.getSendStretFn(IsSuper);
+  } else if (ResultType->isFloatingType()) {
+    if (ObjCABI == 2) {
+      if (const BuiltinType *BT = ResultType->getAs<BuiltinType>()) {
+        BuiltinType::Kind k = BT->getKind();
+        Fn = (k == BuiltinType::LongDouble) ? ObjCTypes.getSendFpretFn2(IsSuper)
+          : ObjCTypes.getSendFn2(IsSuper);
+      } else {
+        Fn = ObjCTypes.getSendFn2(IsSuper);
+      }
+    } else
+      // FIXME. This currently matches gcc's API for x86-32. May need to change
+      // for others if we have their API.
+      Fn = ObjCTypes.getSendFpretFn(IsSuper);
+  } else {
+    Fn = (ObjCABI == 2) ? ObjCTypes.getSendFn2(IsSuper)
+      : ObjCTypes.getSendFn(IsSuper);
+  }
+  assert(Fn && "EmitLegacyMessageSend - unknown API");
+  Fn = llvm::ConstantExpr::getBitCast(Fn,
+                                      llvm::PointerType::getUnqual(FTy));
+  return CGF.EmitCall(FnInfo, Fn, ReturnValueSlot(), ActualArgs);
+}
+
+llvm::Value *CGObjCMac::GenerateProtocolRef(CGBuilderTy &Builder,
+                                            const ObjCProtocolDecl *PD) {
+  // FIXME: I don't understand why gcc generates this, or where it is
+  // resolved. Investigate. Its also wasteful to look this up over and over.
+  LazySymbols.insert(&CGM.getContext().Idents.get("Protocol"));
+
+  return llvm::ConstantExpr::getBitCast(GetProtocolRef(PD),
+                                        ObjCTypes.ExternalProtocolPtrTy);
+}
+
+void CGObjCCommonMac::GenerateProtocol(const ObjCProtocolDecl *PD) {
+  // FIXME: We shouldn't need this, the protocol decl should contain enough
+  // information to tell us whether this was a declaration or a definition.
+  DefinedProtocols.insert(PD->getIdentifier());
+
+  // If we have generated a forward reference to this protocol, emit
+  // it now. Otherwise do nothing, the protocol objects are lazily
+  // emitted.
+  if (Protocols.count(PD->getIdentifier()))
+    GetOrEmitProtocol(PD);
+}
+
+llvm::Constant *CGObjCCommonMac::GetProtocolRef(const ObjCProtocolDecl *PD) {
+  if (DefinedProtocols.count(PD->getIdentifier()))
+    return GetOrEmitProtocol(PD);
+  return GetOrEmitProtocolRef(PD);
+}
+
+/*
+// APPLE LOCAL radar 4585769 - Objective-C 1.0 extensions
+struct _objc_protocol {
+struct _objc_protocol_extension *isa;
+char *protocol_name;
+struct _objc_protocol_list *protocol_list;
+struct _objc__method_prototype_list *instance_methods;
+struct _objc__method_prototype_list *class_methods
+};
+
+See EmitProtocolExtension().
+*/
+llvm::Constant *CGObjCMac::GetOrEmitProtocol(const ObjCProtocolDecl *PD) {
+  llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
+
+  // Early exit if a defining object has already been generated.
+  if (Entry && Entry->hasInitializer())
+    return Entry;
+
+  // FIXME: I don't understand why gcc generates this, or where it is
+  // resolved. Investigate. Its also wasteful to look this up over and over.
+  LazySymbols.insert(&CGM.getContext().Idents.get("Protocol"));
+
+  // Construct method lists.
+  std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
+  std::vector<llvm::Constant*> OptInstanceMethods, OptClassMethods;
+  for (ObjCProtocolDecl::instmeth_iterator
+         i = PD->instmeth_begin(), e = PD->instmeth_end(); i != e; ++i) {
+    ObjCMethodDecl *MD = *i;
+    llvm::Constant *C = GetMethodDescriptionConstant(MD);
+    if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
+      OptInstanceMethods.push_back(C);
+    } else {
+      InstanceMethods.push_back(C);
+    }
+  }
+
+  for (ObjCProtocolDecl::classmeth_iterator
+         i = PD->classmeth_begin(), e = PD->classmeth_end(); i != e; ++i) {
+    ObjCMethodDecl *MD = *i;
+    llvm::Constant *C = GetMethodDescriptionConstant(MD);
+    if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
+      OptClassMethods.push_back(C);
+    } else {
+      ClassMethods.push_back(C);
+    }
+  }
+
+  std::vector<llvm::Constant*> Values(5);
+  Values[0] = EmitProtocolExtension(PD, OptInstanceMethods, OptClassMethods);
+  Values[1] = GetClassName(PD->getIdentifier());
+  Values[2] =
+    EmitProtocolList("\01L_OBJC_PROTOCOL_REFS_" + PD->getName(),
+                     PD->protocol_begin(),
+                     PD->protocol_end());
+  Values[3] =
+    EmitMethodDescList("\01L_OBJC_PROTOCOL_INSTANCE_METHODS_" + PD->getName(),
+                       "__OBJC,__cat_inst_meth,regular,no_dead_strip",
+                       InstanceMethods);
+  Values[4] =
+    EmitMethodDescList("\01L_OBJC_PROTOCOL_CLASS_METHODS_" + PD->getName(),
+                       "__OBJC,__cat_cls_meth,regular,no_dead_strip",
+                       ClassMethods);
+  llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
+                                                   Values);
+
+  if (Entry) {
+    // Already created, fix the linkage and update the initializer.
+    Entry->setLinkage(llvm::GlobalValue::InternalLinkage);
+    Entry->setInitializer(Init);
+  } else {
+    Entry =
+      new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolTy, false,
+                               llvm::GlobalValue::InternalLinkage,
+                               Init,
+                               "\01L_OBJC_PROTOCOL_" + PD->getName());
+    Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
+    // FIXME: Is this necessary? Why only for protocol?
+    Entry->setAlignment(4);
+  }
+  CGM.AddUsedGlobal(Entry);
+
+  return Entry;
+}
+
+llvm::Constant *CGObjCMac::GetOrEmitProtocolRef(const ObjCProtocolDecl *PD) {
+  llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
+
+  if (!Entry) {
+    // We use the initializer as a marker of whether this is a forward
+    // reference or not. At module finalization we add the empty
+    // contents for protocols which were referenced but never defined.
+    Entry =
+      new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolTy, false,
+                               llvm::GlobalValue::ExternalLinkage,
+                               0,
+                               "\01L_OBJC_PROTOCOL_" + PD->getName());
+    Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
+    // FIXME: Is this necessary? Why only for protocol?
+    Entry->setAlignment(4);
+  }
+
+  return Entry;
+}
+
+/*
+  struct _objc_protocol_extension {
+  uint32_t size;
+  struct objc_method_description_list *optional_instance_methods;
+  struct objc_method_description_list *optional_class_methods;
+  struct objc_property_list *instance_properties;
+  };
+*/
+llvm::Constant *
+CGObjCMac::EmitProtocolExtension(const ObjCProtocolDecl *PD,
+                                 const ConstantVector &OptInstanceMethods,
+                                 const ConstantVector &OptClassMethods) {
+  uint64_t Size =
+    CGM.getTargetData().getTypeAllocSize(ObjCTypes.ProtocolExtensionTy);
+  std::vector<llvm::Constant*> Values(4);
+  Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
+  Values[1] =
+    EmitMethodDescList("\01L_OBJC_PROTOCOL_INSTANCE_METHODS_OPT_"
+                       + PD->getName(),
+                       "__OBJC,__cat_inst_meth,regular,no_dead_strip",
+                       OptInstanceMethods);
+  Values[2] =
+    EmitMethodDescList("\01L_OBJC_PROTOCOL_CLASS_METHODS_OPT_" + PD->getName(),
+                       "__OBJC,__cat_cls_meth,regular,no_dead_strip",
+                       OptClassMethods);
+  Values[3] = EmitPropertyList("\01L_OBJC_$_PROP_PROTO_LIST_" + PD->getName(),
+                               0, PD, ObjCTypes);
+
+  // Return null if no extension bits are used.
+  if (Values[1]->isNullValue() && Values[2]->isNullValue() &&
+      Values[3]->isNullValue())
+    return llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
+
+  llvm::Constant *Init =
+    llvm::ConstantStruct::get(ObjCTypes.ProtocolExtensionTy, Values);
+
+  // No special section, but goes in llvm.used
+  return CreateMetadataVar("\01L_OBJC_PROTOCOLEXT_" + PD->getName(),
+                           Init,
+                           0, 0, true);
+}
+
+/*
+  struct objc_protocol_list {
+  struct objc_protocol_list *next;
+  long count;
+  Protocol *list[];
+  };
+*/
+llvm::Constant *
+CGObjCMac::EmitProtocolList(llvm::Twine Name,
+                            ObjCProtocolDecl::protocol_iterator begin,
+                            ObjCProtocolDecl::protocol_iterator end) {
+  std::vector<llvm::Constant*> ProtocolRefs;
+
+  for (; begin != end; ++begin)
+    ProtocolRefs.push_back(GetProtocolRef(*begin));
+
+  // Just return null for empty protocol lists
+  if (ProtocolRefs.empty())
+    return llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
+
+  // This list is null terminated.
+  ProtocolRefs.push_back(llvm::Constant::getNullValue(ObjCTypes.ProtocolPtrTy));
+
+  std::vector<llvm::Constant*> Values(3);
+  // This field is only used by the runtime.
+  Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
+  Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy,
+                                     ProtocolRefs.size() - 1);
+  Values[2] =
+    llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.ProtocolPtrTy,
+                                                  ProtocolRefs.size()),
+                             ProtocolRefs);
+
+  llvm::Constant *Init = llvm::ConstantStruct::get(VMContext, Values, false);
+  llvm::GlobalVariable *GV =
+    CreateMetadataVar(Name, Init, "__OBJC,__cat_cls_meth,regular,no_dead_strip",
+                      4, false);
+  return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListPtrTy);
+}
+
+void CGObjCCommonMac::PushProtocolProperties(llvm::SmallPtrSet<const IdentifierInfo*, 16> &PropertySet,
+                                   std::vector<llvm::Constant*> &Properties,
+                                   const Decl *Container,
+                                   const ObjCProtocolDecl *PROTO,
+                                   const ObjCCommonTypesHelper &ObjCTypes) {
+  std::vector<llvm::Constant*> Prop(2);
+  for (ObjCProtocolDecl::protocol_iterator P = PROTO->protocol_begin(),
+         E = PROTO->protocol_end(); P != E; ++P) 
+    PushProtocolProperties(PropertySet, Properties, Container, (*P), ObjCTypes);
+  for (ObjCContainerDecl::prop_iterator I = PROTO->prop_begin(),
+       E = PROTO->prop_end(); I != E; ++I) {
+    const ObjCPropertyDecl *PD = *I;
+    if (!PropertySet.insert(PD->getIdentifier()))
+      continue;
+    Prop[0] = GetPropertyName(PD->getIdentifier());
+    Prop[1] = GetPropertyTypeString(PD, Container);
+    Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy, Prop));
+  }
+}
+
+/*
+  struct _objc_property {
+  const char * const name;
+  const char * const attributes;
+  };
+
+  struct _objc_property_list {
+  uint32_t entsize; // sizeof (struct _objc_property)
+  uint32_t prop_count;
+  struct _objc_property[prop_count];
+  };
+*/
+llvm::Constant *CGObjCCommonMac::EmitPropertyList(llvm::Twine Name,
+                                       const Decl *Container,
+                                       const ObjCContainerDecl *OCD,
+                                       const ObjCCommonTypesHelper &ObjCTypes) {
+  std::vector<llvm::Constant*> Properties, Prop(2);
+  llvm::SmallPtrSet<const IdentifierInfo*, 16> PropertySet;
+  for (ObjCContainerDecl::prop_iterator I = OCD->prop_begin(),
+         E = OCD->prop_end(); I != E; ++I) {
+    const ObjCPropertyDecl *PD = *I;
+    PropertySet.insert(PD->getIdentifier());
+    Prop[0] = GetPropertyName(PD->getIdentifier());
+    Prop[1] = GetPropertyTypeString(PD, Container);
+    Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy,
+                                                   Prop));
+  }
+  if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(OCD))
+    for (ObjCInterfaceDecl::protocol_iterator P = OID->protocol_begin(),
+         E = OID->protocol_end(); P != E; ++P)
+      PushProtocolProperties(PropertySet, Properties, Container, (*P), ObjCTypes);
+
+  // Return null for empty list.
+  if (Properties.empty())
+    return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
+
+  unsigned PropertySize =
+    CGM.getTargetData().getTypeAllocSize(ObjCTypes.PropertyTy);
+  std::vector<llvm::Constant*> Values(3);
+  Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, PropertySize);
+  Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Properties.size());
+  llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.PropertyTy,
+                                             Properties.size());
+  Values[2] = llvm::ConstantArray::get(AT, Properties);
+  llvm::Constant *Init = llvm::ConstantStruct::get(VMContext, Values, false);
+
+  llvm::GlobalVariable *GV =
+    CreateMetadataVar(Name, Init,
+                      (ObjCABI == 2) ? "__DATA, __objc_const" :
+                      "__OBJC,__property,regular,no_dead_strip",
+                      (ObjCABI == 2) ? 8 : 4,
+                      true);
+  return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.PropertyListPtrTy);
+}
+
+/*
+  struct objc_method_description_list {
+  int count;
+  struct objc_method_description list[];
+  };
+*/
+llvm::Constant *
+CGObjCMac::GetMethodDescriptionConstant(const ObjCMethodDecl *MD) {
+  std::vector<llvm::Constant*> Desc(2);
+  Desc[0] =
+    llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
+                                   ObjCTypes.SelectorPtrTy);
+  Desc[1] = GetMethodVarType(MD);
+  return llvm::ConstantStruct::get(ObjCTypes.MethodDescriptionTy,
+                                   Desc);
+}
+
+llvm::Constant *CGObjCMac::EmitMethodDescList(llvm::Twine Name,
+                                              const char *Section,
+                                              const ConstantVector &Methods) {
+  // Return null for empty list.
+  if (Methods.empty())
+    return llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
+
+  std::vector<llvm::Constant*> Values(2);
+  Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
+  llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodDescriptionTy,
+                                             Methods.size());
+  Values[1] = llvm::ConstantArray::get(AT, Methods);
+  llvm::Constant *Init = llvm::ConstantStruct::get(VMContext, Values, false);
+
+  llvm::GlobalVariable *GV = CreateMetadataVar(Name, Init, Section, 4, true);
+  return llvm::ConstantExpr::getBitCast(GV,
+                                        ObjCTypes.MethodDescriptionListPtrTy);
+}
+
+/*
+  struct _objc_category {
+  char *category_name;
+  char *class_name;
+  struct _objc_method_list *instance_methods;
+  struct _objc_method_list *class_methods;
+  struct _objc_protocol_list *protocols;
+  uint32_t size; // <rdar://4585769>
+  struct _objc_property_list *instance_properties;
+  };
+*/
+void CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
+  unsigned Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.CategoryTy);
+
+  // FIXME: This is poor design, the OCD should have a pointer to the category
+  // decl. Additionally, note that Category can be null for the @implementation
+  // w/o an @interface case. Sema should just create one for us as it does for
+  // @implementation so everyone else can live life under a clear blue sky.
+  const ObjCInterfaceDecl *Interface = OCD->getClassInterface();
+  const ObjCCategoryDecl *Category =
+    Interface->FindCategoryDeclaration(OCD->getIdentifier());
+
+  llvm::SmallString<256> ExtName;
+  llvm::raw_svector_ostream(ExtName) << Interface->getName() << '_'
+                                     << OCD->getName();
+
+  std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
+  for (ObjCCategoryImplDecl::instmeth_iterator
+         i = OCD->instmeth_begin(), e = OCD->instmeth_end(); i != e; ++i) {
+    // Instance methods should always be defined.
+    InstanceMethods.push_back(GetMethodConstant(*i));
+  }
+  for (ObjCCategoryImplDecl::classmeth_iterator
+         i = OCD->classmeth_begin(), e = OCD->classmeth_end(); i != e; ++i) {
+    // Class methods should always be defined.
+    ClassMethods.push_back(GetMethodConstant(*i));
+  }
+
+  std::vector<llvm::Constant*> Values(7);
+  Values[0] = GetClassName(OCD->getIdentifier());
+  Values[1] = GetClassName(Interface->getIdentifier());
+  LazySymbols.insert(Interface->getIdentifier());
+  Values[2] =
+    EmitMethodList("\01L_OBJC_CATEGORY_INSTANCE_METHODS_" + ExtName.str(),
+                   "__OBJC,__cat_inst_meth,regular,no_dead_strip",
+                   InstanceMethods);
+  Values[3] =
+    EmitMethodList("\01L_OBJC_CATEGORY_CLASS_METHODS_" + ExtName.str(),
+                   "__OBJC,__cat_cls_meth,regular,no_dead_strip",
+                   ClassMethods);
+  if (Category) {
+    Values[4] =
+      EmitProtocolList("\01L_OBJC_CATEGORY_PROTOCOLS_" + ExtName.str(),
+                       Category->protocol_begin(),
+                       Category->protocol_end());
+  } else {
+    Values[4] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
+  }
+  Values[5] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
+
+  // If there is no category @interface then there can be no properties.
+  if (Category) {
+    Values[6] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ExtName.str(),
+                                 OCD, Category, ObjCTypes);
+  } else {
+    Values[6] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
+  }
+
+  llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.CategoryTy,
+                                                   Values);
+
+  llvm::GlobalVariable *GV =
+    CreateMetadataVar("\01L_OBJC_CATEGORY_" + ExtName.str(), Init,
+                      "__OBJC,__category,regular,no_dead_strip",
+                      4, true);
+  DefinedCategories.push_back(GV);
+}
+
+// FIXME: Get from somewhere?
+enum ClassFlags {
+  eClassFlags_Factory              = 0x00001,
+  eClassFlags_Meta                 = 0x00002,
+  // <rdr://5142207>
+  eClassFlags_HasCXXStructors      = 0x02000,
+  eClassFlags_Hidden               = 0x20000,
+  eClassFlags_ABI2_Hidden          = 0x00010,
+  eClassFlags_ABI2_HasCXXStructors = 0x00004   // <rdr://4923634>
+};
+
+/*
+  struct _objc_class {
+  Class isa;
+  Class super_class;
+  const char *name;
+  long version;
+  long info;
+  long instance_size;
+  struct _objc_ivar_list *ivars;
+  struct _objc_method_list *methods;
+  struct _objc_cache *cache;
+  struct _objc_protocol_list *protocols;
+  // Objective-C 1.0 extensions (<rdr://4585769>)
+  const char *ivar_layout;
+  struct _objc_class_ext *ext;
+  };
+
+  See EmitClassExtension();
+*/
+void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) {
+  DefinedSymbols.insert(ID->getIdentifier());
+
+  std::string ClassName = ID->getNameAsString();
+  // FIXME: Gross
+  ObjCInterfaceDecl *Interface =
+    const_cast<ObjCInterfaceDecl*>(ID->getClassInterface());
+  llvm::Constant *Protocols =
+    EmitProtocolList("\01L_OBJC_CLASS_PROTOCOLS_" + ID->getName(),
+                     Interface->protocol_begin(),
+                     Interface->protocol_end());
+  unsigned Flags = eClassFlags_Factory;
+  unsigned Size =
+    CGM.getContext().getASTObjCImplementationLayout(ID).getSize() / 8;
+
+  // FIXME: Set CXX-structors flag.
+  if (CGM.getDeclVisibilityMode(ID->getClassInterface()) == LangOptions::Hidden)
+    Flags |= eClassFlags_Hidden;
+
+  std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
+  for (ObjCImplementationDecl::instmeth_iterator
+         i = ID->instmeth_begin(), e = ID->instmeth_end(); i != e; ++i) {
+    // Instance methods should always be defined.
+    InstanceMethods.push_back(GetMethodConstant(*i));
+  }
+  for (ObjCImplementationDecl::classmeth_iterator
+         i = ID->classmeth_begin(), e = ID->classmeth_end(); i != e; ++i) {
+    // Class methods should always be defined.
+    ClassMethods.push_back(GetMethodConstant(*i));
+  }
+
+  for (ObjCImplementationDecl::propimpl_iterator
+         i = ID->propimpl_begin(), e = ID->propimpl_end(); i != e; ++i) {
+    ObjCPropertyImplDecl *PID = *i;
+
+    if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) {
+      ObjCPropertyDecl *PD = PID->getPropertyDecl();
+
+      if (ObjCMethodDecl *MD = PD->getGetterMethodDecl())
+        if (llvm::Constant *C = GetMethodConstant(MD))
+          InstanceMethods.push_back(C);
+      if (ObjCMethodDecl *MD = PD->getSetterMethodDecl())
+        if (llvm::Constant *C = GetMethodConstant(MD))
+          InstanceMethods.push_back(C);
+    }
+  }
+
+  std::vector<llvm::Constant*> Values(12);
+  Values[ 0] = EmitMetaClass(ID, Protocols, ClassMethods);
+  if (ObjCInterfaceDecl *Super = Interface->getSuperClass()) {
+    // Record a reference to the super class.
+    LazySymbols.insert(Super->getIdentifier());
+
+    Values[ 1] =
+      llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()),
+                                     ObjCTypes.ClassPtrTy);
+  } else {
+    Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
+  }
+  Values[ 2] = GetClassName(ID->getIdentifier());
+  // Version is always 0.
+  Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
+  Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
+  Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
+  Values[ 6] = EmitIvarList(ID, false);
+  Values[ 7] =
+    EmitMethodList("\01L_OBJC_INSTANCE_METHODS_" + ID->getName(),
+                   "__OBJC,__inst_meth,regular,no_dead_strip",
+                   InstanceMethods);
+  // cache is always NULL.
+  Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
+  Values[ 9] = Protocols;
+  Values[10] = BuildIvarLayout(ID, true);
+  Values[11] = EmitClassExtension(ID);
+  llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
+                                                   Values);
+  std::string Name("\01L_OBJC_CLASS_");
+  Name += ClassName;
+  const char *Section = "__OBJC,__class,regular,no_dead_strip";
+  // Check for a forward reference.
+  llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
+  if (GV) {
+    assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
+           "Forward metaclass reference has incorrect type.");
+    GV->setLinkage(llvm::GlobalValue::InternalLinkage);
+    GV->setInitializer(Init);
+    GV->setSection(Section);
+    GV->setAlignment(4);
+    CGM.AddUsedGlobal(GV);
+  } 
+  else
+    GV = CreateMetadataVar(Name, Init, Section, 4, true);
+  DefinedClasses.push_back(GV);
+}
+
+llvm::Constant *CGObjCMac::EmitMetaClass(const ObjCImplementationDecl *ID,
+                                         llvm::Constant *Protocols,
+                                         const ConstantVector &Methods) {
+  unsigned Flags = eClassFlags_Meta;
+  unsigned Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.ClassTy);
+
+  if (CGM.getDeclVisibilityMode(ID->getClassInterface()) == LangOptions::Hidden)
+    Flags |= eClassFlags_Hidden;
+
+  std::vector<llvm::Constant*> Values(12);
+  // The isa for the metaclass is the root of the hierarchy.
+  const ObjCInterfaceDecl *Root = ID->getClassInterface();
+  while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
+    Root = Super;
+  Values[ 0] =
+    llvm::ConstantExpr::getBitCast(GetClassName(Root->getIdentifier()),
+                                   ObjCTypes.ClassPtrTy);
+  // The super class for the metaclass is emitted as the name of the
+  // super class. The runtime fixes this up to point to the
+  // *metaclass* for the super class.
+  if (ObjCInterfaceDecl *Super = ID->getClassInterface()->getSuperClass()) {
+    Values[ 1] =
+      llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()),
+                                     ObjCTypes.ClassPtrTy);
+  } else {
+    Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
+  }
+  Values[ 2] = GetClassName(ID->getIdentifier());
+  // Version is always 0.
+  Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
+  Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
+  Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
+  Values[ 6] = EmitIvarList(ID, true);
+  Values[ 7] =
+    EmitMethodList("\01L_OBJC_CLASS_METHODS_" + ID->getNameAsString(),
+                   "__OBJC,__cls_meth,regular,no_dead_strip",
+                   Methods);
+  // cache is always NULL.
+  Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
+  Values[ 9] = Protocols;
+  // ivar_layout for metaclass is always NULL.
+  Values[10] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
+  // The class extension is always unused for metaclasses.
+  Values[11] = llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
+  llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
+                                                   Values);
+
+  std::string Name("\01L_OBJC_METACLASS_");
+  Name += ID->getNameAsCString();
+
+  // Check for a forward reference.
+  llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
+  if (GV) {
+    assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
+           "Forward metaclass reference has incorrect type.");
+    GV->setLinkage(llvm::GlobalValue::InternalLinkage);
+    GV->setInitializer(Init);
+  } else {
+    GV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false,
+                                  llvm::GlobalValue::InternalLinkage,
+                                  Init, Name);
+  }
+  GV->setSection("__OBJC,__meta_class,regular,no_dead_strip");
+  GV->setAlignment(4);
+  CGM.AddUsedGlobal(GV);
+
+  return GV;
+}
+
+llvm::Constant *CGObjCMac::EmitMetaClassRef(const ObjCInterfaceDecl *ID) {
+  std::string Name = "\01L_OBJC_METACLASS_" + ID->getNameAsString();
+
+  // FIXME: Should we look these up somewhere other than the module. Its a bit
+  // silly since we only generate these while processing an implementation, so
+  // exactly one pointer would work if know when we entered/exitted an
+  // implementation block.
+
+  // Check for an existing forward reference.
+  // Previously, metaclass with internal linkage may have been defined.
+  // pass 'true' as 2nd argument so it is returned.
+  if (llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name,
+                                                                   true)) {
+    assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
+           "Forward metaclass reference has incorrect type.");
+    return GV;
+  } else {
+    // Generate as an external reference to keep a consistent
+    // module. This will be patched up when we emit the metaclass.
+    return new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false,
+                                    llvm::GlobalValue::ExternalLinkage,
+                                    0,
+                                    Name);
+  }
+}
+
+llvm::Value *CGObjCMac::EmitSuperClassRef(const ObjCInterfaceDecl *ID) {
+  std::string Name = "\01L_OBJC_CLASS_" + ID->getNameAsString();
+  
+  if (llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name,
+                                                                   true)) {
+    assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
+           "Forward class metadata reference has incorrect type.");
+    return GV;
+  } else {
+    return new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false,
+                                    llvm::GlobalValue::ExternalLinkage,
+                                    0,
+                                    Name);
+  }
+}
+
+/*
+  struct objc_class_ext {
+  uint32_t size;
+  const char *weak_ivar_layout;
+  struct _objc_property_list *properties;
+  };
+*/
+llvm::Constant *
+CGObjCMac::EmitClassExtension(const ObjCImplementationDecl *ID) {
+  uint64_t Size =
+    CGM.getTargetData().getTypeAllocSize(ObjCTypes.ClassExtensionTy);
+
+  std::vector<llvm::Constant*> Values(3);
+  Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
+  Values[1] = BuildIvarLayout(ID, false);
+  Values[2] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ID->getName(),
+                               ID, ID->getClassInterface(), ObjCTypes);
+
+  // Return null if no extension bits are used.
+  if (Values[1]->isNullValue() && Values[2]->isNullValue())
+    return llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
+
+  llvm::Constant *Init =
+    llvm::ConstantStruct::get(ObjCTypes.ClassExtensionTy, Values);
+  return CreateMetadataVar("\01L_OBJC_CLASSEXT_" + ID->getName(),
+                           Init, "__OBJC,__class_ext,regular,no_dead_strip",
+                           4, true);
+}
+
+/*
+  struct objc_ivar {
+  char *ivar_name;
+  char *ivar_type;
+  int ivar_offset;
+  };
+
+  struct objc_ivar_list {
+  int ivar_count;
+  struct objc_ivar list[count];
+  };
+*/
+llvm::Constant *CGObjCMac::EmitIvarList(const ObjCImplementationDecl *ID,
+                                        bool ForClass) {
+  std::vector<llvm::Constant*> Ivars, Ivar(3);
+
+  // When emitting the root class GCC emits ivar entries for the
+  // actual class structure. It is not clear if we need to follow this
+  // behavior; for now lets try and get away with not doing it. If so,
+  // the cleanest solution would be to make up an ObjCInterfaceDecl
+  // for the class.
+  if (ForClass)
+    return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
+
+  ObjCInterfaceDecl *OID =
+    const_cast<ObjCInterfaceDecl*>(ID->getClassInterface());
+
+  llvm::SmallVector<ObjCIvarDecl*, 16> OIvars;
+  CGM.getContext().ShallowCollectObjCIvars(OID, OIvars);
+
+  for (unsigned i = 0, e = OIvars.size(); i != e; ++i) {
+    ObjCIvarDecl *IVD = OIvars[i];
+    // Ignore unnamed bit-fields.
+    if (!IVD->getDeclName())
+      continue;
+    Ivar[0] = GetMethodVarName(IVD->getIdentifier());
+    Ivar[1] = GetMethodVarType(IVD);
+    Ivar[2] = llvm::ConstantInt::get(ObjCTypes.IntTy,
+                                     ComputeIvarBaseOffset(CGM, OID, IVD));
+    Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarTy, Ivar));
+  }
+
+  // Return null for empty list.
+  if (Ivars.empty())
+    return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
+
+  std::vector<llvm::Constant*> Values(2);
+  Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size());
+  llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarTy,
+                                             Ivars.size());
+  Values[1] = llvm::ConstantArray::get(AT, Ivars);
+  llvm::Constant *Init = llvm::ConstantStruct::get(VMContext, Values, false);
+
+  llvm::GlobalVariable *GV;
+  if (ForClass)
+    GV = CreateMetadataVar("\01L_OBJC_CLASS_VARIABLES_" + ID->getName(),
+                           Init, "__OBJC,__class_vars,regular,no_dead_strip",
+                           4, true);
+  else
+    GV = CreateMetadataVar("\01L_OBJC_INSTANCE_VARIABLES_" + ID->getName(),
+                           Init, "__OBJC,__instance_vars,regular,no_dead_strip",
+                           4, true);
+  return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.IvarListPtrTy);
+}
+
+/*
+  struct objc_method {
+  SEL method_name;
+  char *method_types;
+  void *method;
+  };
+
+  struct objc_method_list {
+  struct objc_method_list *obsolete;
+  int count;
+  struct objc_method methods_list[count];
+  };
+*/
+
+/// GetMethodConstant - Return a struct objc_method constant for the
+/// given method if it has been defined. The result is null if the
+/// method has not been defined. The return value has type MethodPtrTy.
+llvm::Constant *CGObjCMac::GetMethodConstant(const ObjCMethodDecl *MD) {
+  // FIXME: Use DenseMap::lookup
+  llvm::Function *Fn = MethodDefinitions[MD];
+  if (!Fn)
+    return 0;
+
+  std::vector<llvm::Constant*> Method(3);
+  Method[0] =
+    llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
+                                   ObjCTypes.SelectorPtrTy);
+  Method[1] = GetMethodVarType(MD);
+  Method[2] = llvm::ConstantExpr::getBitCast(Fn, ObjCTypes.Int8PtrTy);
+  return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Method);
+}
+
+llvm::Constant *CGObjCMac::EmitMethodList(llvm::Twine Name,
+                                          const char *Section,
+                                          const ConstantVector &Methods) {
+  // Return null for empty list.
+  if (Methods.empty())
+    return llvm::Constant::getNullValue(ObjCTypes.MethodListPtrTy);
+
+  std::vector<llvm::Constant*> Values(3);
+  Values[0] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
+  Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
+  llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy,
+                                             Methods.size());
+  Values[2] = llvm::ConstantArray::get(AT, Methods);
+  llvm::Constant *Init = llvm::ConstantStruct::get(VMContext, Values, false);
+
+  llvm::GlobalVariable *GV = CreateMetadataVar(Name, Init, Section, 4, true);
+  return llvm::ConstantExpr::getBitCast(GV,
+                                        ObjCTypes.MethodListPtrTy);
+}
+
+llvm::Function *CGObjCCommonMac::GenerateMethod(const ObjCMethodDecl *OMD,
+                                                const ObjCContainerDecl *CD) {
+  llvm::SmallString<256> Name;
+  GetNameForMethod(OMD, CD, Name);
+
+  CodeGenTypes &Types = CGM.getTypes();
+  const llvm::FunctionType *MethodTy =
+    Types.GetFunctionType(Types.getFunctionInfo(OMD), OMD->isVariadic());
+  llvm::Function *Method =
+    llvm::Function::Create(MethodTy,
+                           llvm::GlobalValue::InternalLinkage,
+                           Name.str(),
+                           &CGM.getModule());
+  MethodDefinitions.insert(std::make_pair(OMD, Method));
+
+  return Method;
+}
+
+llvm::GlobalVariable *
+CGObjCCommonMac::CreateMetadataVar(llvm::Twine Name,
+                                   llvm::Constant *Init,
+                                   const char *Section,
+                                   unsigned Align,
+                                   bool AddToUsed) {
+  const llvm::Type *Ty = Init->getType();
+  llvm::GlobalVariable *GV =
+    new llvm::GlobalVariable(CGM.getModule(), Ty, false,
+                             llvm::GlobalValue::InternalLinkage, Init, Name);
+  if (Section)
+    GV->setSection(Section);
+  if (Align)
+    GV->setAlignment(Align);
+  if (AddToUsed)
+    CGM.AddUsedGlobal(GV);
+  return GV;
+}
+
+llvm::Function *CGObjCMac::ModuleInitFunction() {
+  // Abuse this interface function as a place to finalize.
+  FinishModule();
+  return NULL;
+}
+
+llvm::Constant *CGObjCMac::GetPropertyGetFunction() {
+  return ObjCTypes.getGetPropertyFn();
+}
+
+llvm::Constant *CGObjCMac::GetPropertySetFunction() {
+  return ObjCTypes.getSetPropertyFn();
+}
+
+llvm::Constant *CGObjCMac::GetCopyStructFunction() {
+  return ObjCTypes.getCopyStructFn();
+}
+
+llvm::Constant *CGObjCMac::EnumerationMutationFunction() {
+  return ObjCTypes.getEnumerationMutationFn();
+}
+
+/*
+
+  Objective-C setjmp-longjmp (sjlj) Exception Handling
+  --
+
+  The basic framework for a @try-catch-finally is as follows:
+  {
+  objc_exception_data d;
+  id _rethrow = null;
+  bool _call_try_exit = true;
+
+  objc_exception_try_enter(&d);
+  if (!setjmp(d.jmp_buf)) {
+  ... try body ...
+  } else {
+  // exception path
+  id _caught = objc_exception_extract(&d);
+
+  // enter new try scope for handlers
+  if (!setjmp(d.jmp_buf)) {
+  ... match exception and execute catch blocks ...
+
+  // fell off end, rethrow.
+  _rethrow = _caught;
+  ... jump-through-finally to finally_rethrow ...
+  } else {
+  // exception in catch block
+  _rethrow = objc_exception_extract(&d);
+  _call_try_exit = false;
+  ... jump-through-finally to finally_rethrow ...
+  }
+  }
+  ... jump-through-finally to finally_end ...
+
+  finally:
+  if (_call_try_exit)
+  objc_exception_try_exit(&d);
+
+  ... finally block ....
+  ... dispatch to finally destination ...
+
+  finally_rethrow:
+  objc_exception_throw(_rethrow);
+
+  finally_end:
+  }
+
+  This framework differs slightly from the one gcc uses, in that gcc
+  uses _rethrow to determine if objc_exception_try_exit should be called
+  and if the object should be rethrown. This breaks in the face of
+  throwing nil and introduces unnecessary branches.
+
+  We specialize this framework for a few particular circumstances:
+
+  - If there are no catch blocks, then we avoid emitting the second
+  exception handling context.
+
+  - If there is a catch-all catch block (i.e. @catch(...) or @catch(id
+  e)) we avoid emitting the code to rethrow an uncaught exception.
+
+  - FIXME: If there is no @finally block we can do a few more
+  simplifications.
+
+  Rethrows and Jumps-Through-Finally
+  --
+
+  Support for implicit rethrows and jumping through the finally block is
+  handled by storing the current exception-handling context in
+  ObjCEHStack.
+
+  In order to implement proper @finally semantics, we support one basic
+  mechanism for jumping through the finally block to an arbitrary
+  destination. Constructs which generate exits from a @try or @catch
+  block use this mechanism to implement the proper semantics by chaining
+  jumps, as necessary.
+
+  This mechanism works like the one used for indirect goto: we
+  arbitrarily assign an ID to each destination and store the ID for the
+  destination in a variable prior to entering the finally block. At the
+  end of the finally block we simply create a switch to the proper
+  destination.
+
+  Code gen for @synchronized(expr) stmt;
+  Effectively generating code for:
+  objc_sync_enter(expr);
+  @try stmt @finally { objc_sync_exit(expr); }
+*/
+
+void CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
+                                          const Stmt &S) {
+  bool isTry = isa<ObjCAtTryStmt>(S);
+  // Create various blocks we refer to for handling @finally.
+  llvm::BasicBlock *FinallyBlock = CGF.createBasicBlock("finally");
+  llvm::BasicBlock *FinallyExit = CGF.createBasicBlock("finally.exit");
+  llvm::BasicBlock *FinallyNoExit = CGF.createBasicBlock("finally.noexit");
+  llvm::BasicBlock *FinallyRethrow = CGF.createBasicBlock("finally.throw");
+  llvm::BasicBlock *FinallyEnd = CGF.createBasicBlock("finally.end");
+
+  // For @synchronized, call objc_sync_enter(sync.expr). The
+  // evaluation of the expression must occur before we enter the
+  // @synchronized. We can safely avoid a temp here because jumps into
+  // @synchronized are illegal & this will dominate uses.
+  llvm::Value *SyncArg = 0;
+  if (!isTry) {
+    SyncArg =
+      CGF.EmitScalarExpr(cast<ObjCAtSynchronizedStmt>(S).getSynchExpr());
+    SyncArg = CGF.Builder.CreateBitCast(SyncArg, ObjCTypes.ObjectPtrTy);
+    CGF.Builder.CreateCall(ObjCTypes.getSyncEnterFn(), SyncArg);
+  }
+
+  // Push an EH context entry, used for handling rethrows and jumps
+  // through finally.
+  CGF.PushCleanupBlock(FinallyBlock);
+
+  if (CGF.ObjCEHValueStack.empty())
+    CGF.ObjCEHValueStack.push_back(0);
+  // If This is a nested @try, caught exception is that of enclosing @try.
+  else
+    CGF.ObjCEHValueStack.push_back(CGF.ObjCEHValueStack.back());
+  // Allocate memory for the exception data and rethrow pointer.
+  llvm::Value *ExceptionData = CGF.CreateTempAlloca(ObjCTypes.ExceptionDataTy,
+                                                    "exceptiondata.ptr");
+  llvm::Value *RethrowPtr = CGF.CreateTempAlloca(ObjCTypes.ObjectPtrTy,
+                                                 "_rethrow");
+  llvm::Value *CallTryExitPtr = CGF.CreateTempAlloca(
+                                               llvm::Type::getInt1Ty(VMContext),
+                                                     "_call_try_exit");
+  CGF.Builder.CreateStore(llvm::ConstantInt::getTrue(VMContext),
+                          CallTryExitPtr);
+
+  // Enter a new try block and call setjmp.
+  CGF.Builder.CreateCall(ObjCTypes.getExceptionTryEnterFn(), ExceptionData);
+  llvm::Value *JmpBufPtr = CGF.Builder.CreateStructGEP(ExceptionData, 0,
+                                                       "jmpbufarray");
+  JmpBufPtr = CGF.Builder.CreateStructGEP(JmpBufPtr, 0, "tmp");
+  llvm::Value *SetJmpResult = CGF.Builder.CreateCall(ObjCTypes.getSetJmpFn(),
+                                                     JmpBufPtr, "result");
+
+  llvm::BasicBlock *TryBlock = CGF.createBasicBlock("try");
+  llvm::BasicBlock *TryHandler = CGF.createBasicBlock("try.handler");
+  CGF.Builder.CreateCondBr(CGF.Builder.CreateIsNotNull(SetJmpResult, "threw"),
+                           TryHandler, TryBlock);
+
+  // Emit the @try block.
+  CGF.EmitBlock(TryBlock);
+  CGF.EmitStmt(isTry ? cast<ObjCAtTryStmt>(S).getTryBody()
+               : cast<ObjCAtSynchronizedStmt>(S).getSynchBody());
+  CGF.EmitBranchThroughCleanup(FinallyEnd);
+
+  // Emit the "exception in @try" block.
+  CGF.EmitBlock(TryHandler);
+
+  // Retrieve the exception object.  We may emit multiple blocks but
+  // nothing can cross this so the value is already in SSA form.
+  llvm::Value *Caught =
+    CGF.Builder.CreateCall(ObjCTypes.getExceptionExtractFn(),
+                           ExceptionData, "caught");
+  CGF.ObjCEHValueStack.back() = Caught;
+  if (!isTry) {
+    CGF.Builder.CreateStore(Caught, RethrowPtr);
+    CGF.Builder.CreateStore(llvm::ConstantInt::getFalse(VMContext),
+                            CallTryExitPtr);
+    CGF.EmitBranchThroughCleanup(FinallyRethrow);
+  } else if (cast<ObjCAtTryStmt>(S).getNumCatchStmts()) {
+    const ObjCAtTryStmt* AtTryStmt = cast<ObjCAtTryStmt>(&S);
+    
+    // Enter a new exception try block (in case a @catch block throws
+    // an exception).
+    CGF.Builder.CreateCall(ObjCTypes.getExceptionTryEnterFn(), ExceptionData);
+
+    llvm::Value *SetJmpResult = CGF.Builder.CreateCall(ObjCTypes.getSetJmpFn(),
+                                                       JmpBufPtr, "result");
+    llvm::Value *Threw = CGF.Builder.CreateIsNotNull(SetJmpResult, "threw");
+
+    llvm::BasicBlock *CatchBlock = CGF.createBasicBlock("catch");
+    llvm::BasicBlock *CatchHandler = CGF.createBasicBlock("catch.handler");
+    CGF.Builder.CreateCondBr(Threw, CatchHandler, CatchBlock);
+
+    CGF.EmitBlock(CatchBlock);
+
+    // Handle catch list. As a special case we check if everything is
+    // matched and avoid generating code for falling off the end if
+    // so.
+    bool AllMatched = false;
+    for (unsigned I = 0, N = AtTryStmt->getNumCatchStmts(); I != N; ++I) {
+      const ObjCAtCatchStmt *CatchStmt = AtTryStmt->getCatchStmt(I);
+      llvm::BasicBlock *NextCatchBlock = CGF.createBasicBlock("catch");
+
+      const VarDecl *CatchParam = CatchStmt->getCatchParamDecl();
+      const ObjCObjectPointerType *OPT = 0;
+
+      // catch(...) always matches.
+      if (!CatchParam) {
+        AllMatched = true;
+      } else {
+        OPT = CatchParam->getType()->getAs<ObjCObjectPointerType>();
+
+        // catch(id e) always matches.
+        // FIXME: For the time being we also match id<X>; this should
+        // be rejected by Sema instead.
+        if (OPT && (OPT->isObjCIdType() || OPT->isObjCQualifiedIdType()))
+          AllMatched = true;
+      }
+
+      if (AllMatched) {
+        if (CatchParam) {
+          CGF.EmitLocalBlockVarDecl(*CatchParam);
+          assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?");
+          CGF.Builder.CreateStore(Caught, CGF.GetAddrOfLocalVar(CatchParam));
+        }
+
+        CGF.EmitStmt(CatchStmt->getCatchBody());
+        CGF.EmitBranchThroughCleanup(FinallyEnd);
+        break;
+      }
+
+      assert(OPT && "Unexpected non-object pointer type in @catch");
+      QualType T = OPT->getPointeeType();
+      const ObjCInterfaceType *ObjCType = T->getAs<ObjCInterfaceType>();
+      assert(ObjCType && "Catch parameter must have Objective-C type!");
+
+      // Check if the @catch block matches the exception object.
+      llvm::Value *Class = EmitClassRef(CGF.Builder, ObjCType->getDecl());
+
+      llvm::Value *Match =
+        CGF.Builder.CreateCall2(ObjCTypes.getExceptionMatchFn(),
+                                Class, Caught, "match");
+
+      llvm::BasicBlock *MatchedBlock = CGF.createBasicBlock("matched");
+
+      CGF.Builder.CreateCondBr(CGF.Builder.CreateIsNotNull(Match, "matched"),
+                               MatchedBlock, NextCatchBlock);
+
+      // Emit the @catch block.
+      CGF.EmitBlock(MatchedBlock);
+      CGF.EmitLocalBlockVarDecl(*CatchParam);
+      assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?");
+
+      llvm::Value *Tmp =
+        CGF.Builder.CreateBitCast(Caught,
+                                  CGF.ConvertType(CatchParam->getType()),
+                                  "tmp");
+      CGF.Builder.CreateStore(Tmp, CGF.GetAddrOfLocalVar(CatchParam));
+
+      CGF.EmitStmt(CatchStmt->getCatchBody());
+      CGF.EmitBranchThroughCleanup(FinallyEnd);
+
+      CGF.EmitBlock(NextCatchBlock);
+    }
+
+    if (!AllMatched) {
+      // None of the handlers caught the exception, so store it to be
+      // rethrown at the end of the @finally block.
+      CGF.Builder.CreateStore(Caught, RethrowPtr);
+      CGF.EmitBranchThroughCleanup(FinallyRethrow);
+    }
+
+    // Emit the exception handler for the @catch blocks.
+    CGF.EmitBlock(CatchHandler);
+    CGF.Builder.CreateStore(
+      CGF.Builder.CreateCall(ObjCTypes.getExceptionExtractFn(),
+                             ExceptionData),
+      RethrowPtr);
+    CGF.Builder.CreateStore(llvm::ConstantInt::getFalse(VMContext),
+                            CallTryExitPtr);
+    CGF.EmitBranchThroughCleanup(FinallyRethrow);
+  } else {
+    CGF.Builder.CreateStore(Caught, RethrowPtr);
+    CGF.Builder.CreateStore(llvm::ConstantInt::getFalse(VMContext),
+                            CallTryExitPtr);
+    CGF.EmitBranchThroughCleanup(FinallyRethrow);
+  }
+
+  // Pop the exception-handling stack entry. It is important to do
+  // this now, because the code in the @finally block is not in this
+  // context.
+  CodeGenFunction::CleanupBlockInfo Info = CGF.PopCleanupBlock();
+
+  CGF.ObjCEHValueStack.pop_back();
+
+  // Emit the @finally block.
+  CGF.EmitBlock(FinallyBlock);
+  llvm::Value* CallTryExit = CGF.Builder.CreateLoad(CallTryExitPtr, "tmp");
+
+  CGF.Builder.CreateCondBr(CallTryExit, FinallyExit, FinallyNoExit);
+
+  CGF.EmitBlock(FinallyExit);
+  CGF.Builder.CreateCall(ObjCTypes.getExceptionTryExitFn(), ExceptionData);
+
+  CGF.EmitBlock(FinallyNoExit);
+  if (isTry) {
+    if (const ObjCAtFinallyStmt* FinallyStmt =
+        cast<ObjCAtTryStmt>(S).getFinallyStmt())
+      CGF.EmitStmt(FinallyStmt->getFinallyBody());
+  } else {
+    // Emit objc_sync_exit(expr); as finally's sole statement for
+    // @synchronized.
+    CGF.Builder.CreateCall(ObjCTypes.getSyncExitFn(), SyncArg);
+  }
+
+  // Emit the switch block
+  if (Info.SwitchBlock)
+    CGF.EmitBlock(Info.SwitchBlock);
+  if (Info.EndBlock)
+    CGF.EmitBlock(Info.EndBlock);
+
+  CGF.EmitBlock(FinallyRethrow);
+  CGF.Builder.CreateCall(ObjCTypes.getExceptionThrowFn(),
+                         CGF.Builder.CreateLoad(RethrowPtr));
+  CGF.Builder.CreateUnreachable();
+
+  CGF.EmitBlock(FinallyEnd);
+}
+
+void CGObjCMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
+                              const ObjCAtThrowStmt &S) {
+  llvm::Value *ExceptionAsObject;
+
+  if (const Expr *ThrowExpr = S.getThrowExpr()) {
+    llvm::Value *Exception = CGF.EmitScalarExpr(ThrowExpr);
+    ExceptionAsObject =
+      CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy, "tmp");
+  } else {
+    assert((!CGF.ObjCEHValueStack.empty() && CGF.ObjCEHValueStack.back()) &&
+           "Unexpected rethrow outside @catch block.");
+    ExceptionAsObject = CGF.ObjCEHValueStack.back();
+  }
+
+  CGF.Builder.CreateCall(ObjCTypes.getExceptionThrowFn(), ExceptionAsObject);
+  CGF.Builder.CreateUnreachable();
+
+  // Clear the insertion point to indicate we are in unreachable code.
+  CGF.Builder.ClearInsertionPoint();
+}
+
+/// EmitObjCWeakRead - Code gen for loading value of a __weak
+/// object: objc_read_weak (id *src)
+///
+llvm::Value * CGObjCMac::EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
+                                          llvm::Value *AddrWeakObj) {
+  const llvm::Type* DestTy =
+    cast<llvm::PointerType>(AddrWeakObj->getType())->getElementType();
+  AddrWeakObj = CGF.Builder.CreateBitCast(AddrWeakObj,
+                                          ObjCTypes.PtrObjectPtrTy);
+  llvm::Value *read_weak = CGF.Builder.CreateCall(ObjCTypes.getGcReadWeakFn(),
+                                                  AddrWeakObj, "weakread");
+  read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy);
+  return read_weak;
+}
+
+/// EmitObjCWeakAssign - Code gen for assigning to a __weak object.
+/// objc_assign_weak (id src, id *dst)
+///
+void CGObjCMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
+                                   llvm::Value *src, llvm::Value *dst) {
+  const llvm::Type * SrcTy = src->getType();
+  if (!isa<llvm::PointerType>(SrcTy)) {
+    unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
+    assert(Size <= 8 && "does not support size > 8");
+    src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
+      : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
+    src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
+  }
+  src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
+  dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
+  CGF.Builder.CreateCall2(ObjCTypes.getGcAssignWeakFn(),
+                          src, dst, "weakassign");
+  return;
+}
+
+/// EmitObjCGlobalAssign - Code gen for assigning to a __strong object.
+/// objc_assign_global (id src, id *dst)
+///
+void CGObjCMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
+                                     llvm::Value *src, llvm::Value *dst) {
+  const llvm::Type * SrcTy = src->getType();
+  if (!isa<llvm::PointerType>(SrcTy)) {
+    unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
+    assert(Size <= 8 && "does not support size > 8");
+    src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
+      : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
+    src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
+  }
+  src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
+  dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
+  CGF.Builder.CreateCall2(ObjCTypes.getGcAssignGlobalFn(),
+                          src, dst, "globalassign");
+  return;
+}
+
+/// EmitObjCIvarAssign - Code gen for assigning to a __strong object.
+/// objc_assign_ivar (id src, id *dst, ptrdiff_t ivaroffset)
+///
+void CGObjCMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
+                                   llvm::Value *src, llvm::Value *dst,
+                                   llvm::Value *ivarOffset) {
+  assert(ivarOffset && "EmitObjCIvarAssign - ivarOffset is NULL");
+  const llvm::Type * SrcTy = src->getType();
+  if (!isa<llvm::PointerType>(SrcTy)) {
+    unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
+    assert(Size <= 8 && "does not support size > 8");
+    src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
+      : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
+    src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
+  }
+  src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
+  dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
+  CGF.Builder.CreateCall3(ObjCTypes.getGcAssignIvarFn(),
+                          src, dst, ivarOffset);
+  return;
+}
+
+/// EmitObjCStrongCastAssign - Code gen for assigning to a __strong cast object.
+/// objc_assign_strongCast (id src, id *dst)
+///
+void CGObjCMac::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
+                                         llvm::Value *src, llvm::Value *dst) {
+  const llvm::Type * SrcTy = src->getType();
+  if (!isa<llvm::PointerType>(SrcTy)) {
+    unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
+    assert(Size <= 8 && "does not support size > 8");
+    src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
+      : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
+    src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
+  }
+  src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
+  dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
+  CGF.Builder.CreateCall2(ObjCTypes.getGcAssignStrongCastFn(),
+                          src, dst, "weakassign");
+  return;
+}
+
+void CGObjCMac::EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
+                                         llvm::Value *DestPtr,
+                                         llvm::Value *SrcPtr,
+                                         QualType Ty) {
+  // Get size info for this aggregate.
+  std::pair<uint64_t, unsigned> TypeInfo = CGM.getContext().getTypeInfo(Ty);
+  unsigned long size = TypeInfo.first/8;
+  SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy);
+  DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy);
+  llvm::Value *N = llvm::ConstantInt::get(ObjCTypes.LongTy, size);
+  CGF.Builder.CreateCall3(ObjCTypes.GcMemmoveCollectableFn(),
+                          DestPtr, SrcPtr, N);
+  return;
+}
+
+/// EmitObjCValueForIvar - Code Gen for ivar reference.
+///
+LValue CGObjCMac::EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
+                                       QualType ObjectTy,
+                                       llvm::Value *BaseValue,
+                                       const ObjCIvarDecl *Ivar,
+                                       unsigned CVRQualifiers) {
+  const ObjCInterfaceDecl *ID = ObjectTy->getAs<ObjCInterfaceType>()->getDecl();
+  return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
+                                  EmitIvarOffset(CGF, ID, Ivar));
+}
+
+llvm::Value *CGObjCMac::EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
+                                       const ObjCInterfaceDecl *Interface,
+                                       const ObjCIvarDecl *Ivar) {
+  uint64_t Offset = ComputeIvarBaseOffset(CGM, Interface, Ivar);
+  return llvm::ConstantInt::get(
+    CGM.getTypes().ConvertType(CGM.getContext().LongTy),
+    Offset);
+}
+
+/* *** Private Interface *** */
+
+/// EmitImageInfo - Emit the image info marker used to encode some module
+/// level information.
+///
+/// See: <rdr://4810609&4810587&4810587>
+/// struct IMAGE_INFO {
+///   unsigned version;
+///   unsigned flags;
+/// };
+enum ImageInfoFlags {
+  eImageInfo_FixAndContinue      = (1 << 0),
+  eImageInfo_GarbageCollected    = (1 << 1),
+  eImageInfo_GCOnly              = (1 << 2),
+  eImageInfo_OptimizedByDyld     = (1 << 3), // FIXME: When is this set.
+
+  // A flag indicating that the module has no instances of a @synthesize of a
+  // superclass variable. <rdar://problem/6803242>
+  eImageInfo_CorrectedSynthesize = (1 << 4)
+};
+
+void CGObjCCommonMac::EmitImageInfo() {
+  unsigned version = 0; // Version is unused?
+  unsigned flags = 0;
+
+  // FIXME: Fix and continue?
+  if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC)
+    flags |= eImageInfo_GarbageCollected;
+  if (CGM.getLangOptions().getGCMode() == LangOptions::GCOnly)
+    flags |= eImageInfo_GCOnly;
+
+  // We never allow @synthesize of a superclass property.
+  flags |= eImageInfo_CorrectedSynthesize;
+
+  // Emitted as int[2];
+  llvm::Constant *values[2] = {
+    llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), version),
+    llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), flags)
+  };
+  llvm::ArrayType *AT = llvm::ArrayType::get(llvm::Type::getInt32Ty(VMContext), 2);
+
+  const char *Section;
+  if (ObjCABI == 1)
+    Section = "__OBJC, __image_info,regular";
+  else
+    Section = "__DATA, __objc_imageinfo, regular, no_dead_strip";
+  llvm::GlobalVariable *GV =
+    CreateMetadataVar("\01L_OBJC_IMAGE_INFO",
+                      llvm::ConstantArray::get(AT, values, 2),
+                      Section,
+                      0,
+                      true);
+  GV->setConstant(true);
+}
+
+
+// struct objc_module {
+//   unsigned long version;
+//   unsigned long size;
+//   const char *name;
+//   Symtab symtab;
+// };
+
+// FIXME: Get from somewhere
+static const int ModuleVersion = 7;
+
+void CGObjCMac::EmitModuleInfo() {
+  uint64_t Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.ModuleTy);
+
+  std::vector<llvm::Constant*> Values(4);
+  Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, ModuleVersion);
+  Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
+  // This used to be the filename, now it is unused. <rdr://4327263>
+  Values[2] = GetClassName(&CGM.getContext().Idents.get(""));
+  Values[3] = EmitModuleSymbols();
+  CreateMetadataVar("\01L_OBJC_MODULES",
+                    llvm::ConstantStruct::get(ObjCTypes.ModuleTy, Values),
+                    "__OBJC,__module_info,regular,no_dead_strip",
+                    4, true);
+}
+
+llvm::Constant *CGObjCMac::EmitModuleSymbols() {
+  unsigned NumClasses = DefinedClasses.size();
+  unsigned NumCategories = DefinedCategories.size();
+
+  // Return null if no symbols were defined.
+  if (!NumClasses && !NumCategories)
+    return llvm::Constant::getNullValue(ObjCTypes.SymtabPtrTy);
+
+  std::vector<llvm::Constant*> Values(5);
+  Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
+  Values[1] = llvm::Constant::getNullValue(ObjCTypes.SelectorPtrTy);
+  Values[2] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumClasses);
+  Values[3] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumCategories);
+
+  // The runtime expects exactly the list of defined classes followed
+  // by the list of defined categories, in a single array.
+  std::vector<llvm::Constant*> Symbols(NumClasses + NumCategories);
+  for (unsigned i=0; i<NumClasses; i++)
+    Symbols[i] = llvm::ConstantExpr::getBitCast(DefinedClasses[i],
+                                                ObjCTypes.Int8PtrTy);
+  for (unsigned i=0; i<NumCategories; i++)
+    Symbols[NumClasses + i] =
+      llvm::ConstantExpr::getBitCast(DefinedCategories[i],
+                                     ObjCTypes.Int8PtrTy);
+
+  Values[4] =
+    llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
+                                                  NumClasses + NumCategories),
+                             Symbols);
+
+  llvm::Constant *Init = llvm::ConstantStruct::get(VMContext, Values, false);
+
+  llvm::GlobalVariable *GV =
+    CreateMetadataVar("\01L_OBJC_SYMBOLS", Init,
+                      "__OBJC,__symbols,regular,no_dead_strip",
+                      4, true);
+  return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.SymtabPtrTy);
+}
+
+llvm::Value *CGObjCMac::EmitClassRef(CGBuilderTy &Builder,
+                                     const ObjCInterfaceDecl *ID) {
+  LazySymbols.insert(ID->getIdentifier());
+
+  llvm::GlobalVariable *&Entry = ClassReferences[ID->getIdentifier()];
+
+  if (!Entry) {
+    llvm::Constant *Casted =
+      llvm::ConstantExpr::getBitCast(GetClassName(ID->getIdentifier()),
+                                     ObjCTypes.ClassPtrTy);
+    Entry =
+      CreateMetadataVar("\01L_OBJC_CLASS_REFERENCES_", Casted,
+                        "__OBJC,__cls_refs,literal_pointers,no_dead_strip",
+                        4, true);
+  }
+
+  return Builder.CreateLoad(Entry, "tmp");
+}
+
+llvm::Value *CGObjCMac::EmitSelector(CGBuilderTy &Builder, Selector Sel) {
+  llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
+
+  if (!Entry) {
+    llvm::Constant *Casted =
+      llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
+                                     ObjCTypes.SelectorPtrTy);
+    Entry =
+      CreateMetadataVar("\01L_OBJC_SELECTOR_REFERENCES_", Casted,
+                        "__OBJC,__message_refs,literal_pointers,no_dead_strip",
+                        4, true);
+  }
+
+  return Builder.CreateLoad(Entry, "tmp");
+}
+
+llvm::Constant *CGObjCCommonMac::GetClassName(IdentifierInfo *Ident) {
+  llvm::GlobalVariable *&Entry = ClassNames[Ident];
+
+  if (!Entry)
+    Entry = CreateMetadataVar("\01L_OBJC_CLASS_NAME_",
+                          llvm::ConstantArray::get(VMContext,
+                                                   Ident->getNameStart()),
+                              "__TEXT,__cstring,cstring_literals",
+                              1, true);
+
+  return getConstantGEP(VMContext, Entry, 0, 0);
+}
+
+/// GetIvarLayoutName - Returns a unique constant for the given
+/// ivar layout bitmap.
+llvm::Constant *CGObjCCommonMac::GetIvarLayoutName(IdentifierInfo *Ident,
+                                       const ObjCCommonTypesHelper &ObjCTypes) {
+  return llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
+}
+
+static Qualifiers::GC GetGCAttrTypeForType(ASTContext &Ctx, QualType FQT) {
+  if (FQT.isObjCGCStrong())
+    return Qualifiers::Strong;
+
+  if (FQT.isObjCGCWeak())
+    return Qualifiers::Weak;
+
+  if (FQT->isObjCObjectPointerType() || FQT->isBlockPointerType())
+    return Qualifiers::Strong;
+
+  if (const PointerType *PT = FQT->getAs<PointerType>())
+    return GetGCAttrTypeForType(Ctx, PT->getPointeeType());
+
+  return Qualifiers::GCNone;
+}
+
+void CGObjCCommonMac::BuildAggrIvarRecordLayout(const RecordType *RT,
+                                                unsigned int BytePos,
+                                                bool ForStrongLayout,
+                                                bool &HasUnion) {
+  const RecordDecl *RD = RT->getDecl();
+  // FIXME - Use iterator.
+  llvm::SmallVector<FieldDecl*, 16> Fields(RD->field_begin(), RD->field_end());
+  const llvm::Type *Ty = CGM.getTypes().ConvertType(QualType(RT, 0));
+  const llvm::StructLayout *RecLayout =
+    CGM.getTargetData().getStructLayout(cast<llvm::StructType>(Ty));
+
+  BuildAggrIvarLayout(0, RecLayout, RD, Fields, BytePos,
+                      ForStrongLayout, HasUnion);
+}
+
+void CGObjCCommonMac::BuildAggrIvarLayout(const ObjCImplementationDecl *OI,
+                             const llvm::StructLayout *Layout,
+                             const RecordDecl *RD,
+                             const llvm::SmallVectorImpl<FieldDecl*> &RecFields,
+                             unsigned int BytePos, bool ForStrongLayout,
+                             bool &HasUnion) {
+  bool IsUnion = (RD && RD->isUnion());
+  uint64_t MaxUnionIvarSize = 0;
+  uint64_t MaxSkippedUnionIvarSize = 0;
+  FieldDecl *MaxField = 0;
+  FieldDecl *MaxSkippedField = 0;
+  FieldDecl *LastFieldBitfield = 0;
+  uint64_t MaxFieldOffset = 0;
+  uint64_t MaxSkippedFieldOffset = 0;
+  uint64_t LastBitfieldOffset = 0;
+
+  if (RecFields.empty())
+    return;
+  unsigned WordSizeInBits = CGM.getContext().Target.getPointerWidth(0);
+  unsigned ByteSizeInBits = CGM.getContext().Target.getCharWidth();
+
+  for (unsigned i = 0, e = RecFields.size(); i != e; ++i) {
+    FieldDecl *Field = RecFields[i];
+    uint64_t FieldOffset;
+    if (RD) {
+      // Note that 'i' here is actually the field index inside RD of Field,
+      // although this dependency is hidden.
+      const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
+      FieldOffset = RL.getFieldOffset(i) / 8;
+    } else
+      FieldOffset = ComputeIvarBaseOffset(CGM, OI, cast<ObjCIvarDecl>(Field));
+
+    // Skip over unnamed or bitfields
+    if (!Field->getIdentifier() || Field->isBitField()) {
+      LastFieldBitfield = Field;
+      LastBitfieldOffset = FieldOffset;
+      continue;
+    }
+
+    LastFieldBitfield = 0;
+    QualType FQT = Field->getType();
+    if (FQT->isRecordType() || FQT->isUnionType()) {
+      if (FQT->isUnionType())
+        HasUnion = true;
+
+      BuildAggrIvarRecordLayout(FQT->getAs<RecordType>(),
+                                BytePos + FieldOffset,
+                                ForStrongLayout, HasUnion);
+      continue;
+    }
+
+    if (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) {
+      const ConstantArrayType *CArray =
+        dyn_cast_or_null<ConstantArrayType>(Array);
+      uint64_t ElCount = CArray->getSize().getZExtValue();
+      assert(CArray && "only array with known element size is supported");
+      FQT = CArray->getElementType();
+      while (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) {
+        const ConstantArrayType *CArray =
+          dyn_cast_or_null<ConstantArrayType>(Array);
+        ElCount *= CArray->getSize().getZExtValue();
+        FQT = CArray->getElementType();
+      }
+
+      assert(!FQT->isUnionType() &&
+             "layout for array of unions not supported");
+      if (FQT->isRecordType()) {
+        int OldIndex = IvarsInfo.size() - 1;
+        int OldSkIndex = SkipIvars.size() -1;
+
+        const RecordType *RT = FQT->getAs<RecordType>();
+        BuildAggrIvarRecordLayout(RT, BytePos + FieldOffset,
+                                  ForStrongLayout, HasUnion);
+
+        // Replicate layout information for each array element. Note that
+        // one element is already done.
+        uint64_t ElIx = 1;
+        for (int FirstIndex = IvarsInfo.size() - 1,
+               FirstSkIndex = SkipIvars.size() - 1 ;ElIx < ElCount; ElIx++) {
+          uint64_t Size = CGM.getContext().getTypeSize(RT)/ByteSizeInBits;
+          for (int i = OldIndex+1; i <= FirstIndex; ++i)
+            IvarsInfo.push_back(GC_IVAR(IvarsInfo[i].ivar_bytepos + Size*ElIx,
+                                        IvarsInfo[i].ivar_size));
+          for (int i = OldSkIndex+1; i <= FirstSkIndex; ++i)
+            SkipIvars.push_back(GC_IVAR(SkipIvars[i].ivar_bytepos + Size*ElIx,
+                                        SkipIvars[i].ivar_size));
+        }
+        continue;
+      }
+    }
+    // At this point, we are done with Record/Union and array there of.
+    // For other arrays we are down to its element type.
+    Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), FQT);
+
+    unsigned FieldSize = CGM.getContext().getTypeSize(Field->getType());
+    if ((ForStrongLayout && GCAttr == Qualifiers::Strong)
+        || (!ForStrongLayout && GCAttr == Qualifiers::Weak)) {
+      if (IsUnion) {
+        uint64_t UnionIvarSize = FieldSize / WordSizeInBits;
+        if (UnionIvarSize > MaxUnionIvarSize) {
+          MaxUnionIvarSize = UnionIvarSize;
+          MaxField = Field;
+          MaxFieldOffset = FieldOffset;
+        }
+      } else {
+        IvarsInfo.push_back(GC_IVAR(BytePos + FieldOffset,
+                                    FieldSize / WordSizeInBits));
+      }
+    } else if ((ForStrongLayout &&
+                (GCAttr == Qualifiers::GCNone || GCAttr == Qualifiers::Weak))
+               || (!ForStrongLayout && GCAttr != Qualifiers::Weak)) {
+      if (IsUnion) {
+        // FIXME: Why the asymmetry? We divide by word size in bits on other
+        // side.
+        uint64_t UnionIvarSize = FieldSize;
+        if (UnionIvarSize > MaxSkippedUnionIvarSize) {
+          MaxSkippedUnionIvarSize = UnionIvarSize;
+          MaxSkippedField = Field;
+          MaxSkippedFieldOffset = FieldOffset;
+        }
+      } else {
+        // FIXME: Why the asymmetry, we divide by byte size in bits here?
+        SkipIvars.push_back(GC_IVAR(BytePos + FieldOffset,
+                                    FieldSize / ByteSizeInBits));
+      }
+    }
+  }
+
+  if (LastFieldBitfield) {
+    // Last field was a bitfield. Must update skip info.
+    Expr *BitWidth = LastFieldBitfield->getBitWidth();
+    uint64_t BitFieldSize =
+      BitWidth->EvaluateAsInt(CGM.getContext()).getZExtValue();
+    GC_IVAR skivar;
+    skivar.ivar_bytepos = BytePos + LastBitfieldOffset;
+    skivar.ivar_size = (BitFieldSize / ByteSizeInBits)
+      + ((BitFieldSize % ByteSizeInBits) != 0);
+    SkipIvars.push_back(skivar);
+  }
+
+  if (MaxField)
+    IvarsInfo.push_back(GC_IVAR(BytePos + MaxFieldOffset,
+                                MaxUnionIvarSize));
+  if (MaxSkippedField)
+    SkipIvars.push_back(GC_IVAR(BytePos + MaxSkippedFieldOffset,
+                                MaxSkippedUnionIvarSize));
+}
+
+/// BuildIvarLayout - Builds ivar layout bitmap for the class
+/// implementation for the __strong or __weak case.
+/// The layout map displays which words in ivar list must be skipped
+/// and which must be scanned by GC (see below). String is built of bytes.
+/// Each byte is divided up in two nibbles (4-bit each). Left nibble is count
+/// of words to skip and right nibble is count of words to scan. So, each
+/// nibble represents up to 15 workds to skip or scan. Skipping the rest is
+/// represented by a 0x00 byte which also ends the string.
+/// 1. when ForStrongLayout is true, following ivars are scanned:
+/// - id, Class
+/// - object *
+/// - __strong anything
+///
+/// 2. When ForStrongLayout is false, following ivars are scanned:
+/// - __weak anything
+///
+llvm::Constant *CGObjCCommonMac::BuildIvarLayout(
+  const ObjCImplementationDecl *OMD,
+  bool ForStrongLayout) {
+  bool hasUnion = false;
+
+  unsigned int WordsToScan, WordsToSkip;
+  const llvm::Type *PtrTy = llvm::Type::getInt8PtrTy(VMContext);
+  if (CGM.getLangOptions().getGCMode() == LangOptions::NonGC)
+    return llvm::Constant::getNullValue(PtrTy);
+
+  llvm::SmallVector<FieldDecl*, 32> RecFields;
+  const ObjCInterfaceDecl *OI = OMD->getClassInterface();
+  CGM.getContext().CollectObjCIvars(OI, RecFields);
+
+  // Add this implementations synthesized ivars.
+  llvm::SmallVector<ObjCIvarDecl*, 16> Ivars;
+  CGM.getContext().CollectNonClassIvars(OI, Ivars);
+  for (unsigned k = 0, e = Ivars.size(); k != e; ++k)
+    RecFields.push_back(cast<FieldDecl>(Ivars[k]));
+
+  if (RecFields.empty())
+    return llvm::Constant::getNullValue(PtrTy);
+
+  SkipIvars.clear();
+  IvarsInfo.clear();
+
+  BuildAggrIvarLayout(OMD, 0, 0, RecFields, 0, ForStrongLayout, hasUnion);
+  if (IvarsInfo.empty())
+    return llvm::Constant::getNullValue(PtrTy);
+
+  // Sort on byte position in case we encounterred a union nested in
+  // the ivar list.
+  if (hasUnion && !IvarsInfo.empty())
+    std::sort(IvarsInfo.begin(), IvarsInfo.end());
+  if (hasUnion && !SkipIvars.empty())
+    std::sort(SkipIvars.begin(), SkipIvars.end());
+
+  // Build the string of skip/scan nibbles
+  llvm::SmallVector<SKIP_SCAN, 32> SkipScanIvars;
+  unsigned int WordSize =
+    CGM.getTypes().getTargetData().getTypeAllocSize(PtrTy);
+  if (IvarsInfo[0].ivar_bytepos == 0) {
+    WordsToSkip = 0;
+    WordsToScan = IvarsInfo[0].ivar_size;
+  } else {
+    WordsToSkip = IvarsInfo[0].ivar_bytepos/WordSize;
+    WordsToScan = IvarsInfo[0].ivar_size;
+  }
+  for (unsigned int i=1, Last=IvarsInfo.size(); i != Last; i++) {
+    unsigned int TailPrevGCObjC =
+      IvarsInfo[i-1].ivar_bytepos + IvarsInfo[i-1].ivar_size * WordSize;
+    if (IvarsInfo[i].ivar_bytepos == TailPrevGCObjC) {
+      // consecutive 'scanned' object pointers.
+      WordsToScan += IvarsInfo[i].ivar_size;
+    } else {
+      // Skip over 'gc'able object pointer which lay over each other.
+      if (TailPrevGCObjC > IvarsInfo[i].ivar_bytepos)
+        continue;
+      // Must skip over 1 or more words. We save current skip/scan values
+      //  and start a new pair.
+      SKIP_SCAN SkScan;
+      SkScan.skip = WordsToSkip;
+      SkScan.scan = WordsToScan;
+      SkipScanIvars.push_back(SkScan);
+
+      // Skip the hole.
+      SkScan.skip = (IvarsInfo[i].ivar_bytepos - TailPrevGCObjC) / WordSize;
+      SkScan.scan = 0;
+      SkipScanIvars.push_back(SkScan);
+      WordsToSkip = 0;
+      WordsToScan = IvarsInfo[i].ivar_size;
+    }
+  }
+  if (WordsToScan > 0) {
+    SKIP_SCAN SkScan;
+    SkScan.skip = WordsToSkip;
+    SkScan.scan = WordsToScan;
+    SkipScanIvars.push_back(SkScan);
+  }
+
+  if (!SkipIvars.empty()) {
+    unsigned int LastIndex = SkipIvars.size()-1;
+    int LastByteSkipped =
+      SkipIvars[LastIndex].ivar_bytepos + SkipIvars[LastIndex].ivar_size;
+    LastIndex = IvarsInfo.size()-1;
+    int LastByteScanned =
+      IvarsInfo[LastIndex].ivar_bytepos +
+      IvarsInfo[LastIndex].ivar_size * WordSize;
+    // Compute number of bytes to skip at the tail end of the last ivar scanned.
+    if (LastByteSkipped > LastByteScanned) {
+      unsigned int TotalWords = (LastByteSkipped + (WordSize -1)) / WordSize;
+      SKIP_SCAN SkScan;
+      SkScan.skip = TotalWords - (LastByteScanned/WordSize);
+      SkScan.scan = 0;
+      SkipScanIvars.push_back(SkScan);
+    }
+  }
+  // Mini optimization of nibbles such that an 0xM0 followed by 0x0N is produced
+  // as 0xMN.
+  int SkipScan = SkipScanIvars.size()-1;
+  for (int i = 0; i <= SkipScan; i++) {
+    if ((i < SkipScan) && SkipScanIvars[i].skip && SkipScanIvars[i].scan == 0
+        && SkipScanIvars[i+1].skip == 0 && SkipScanIvars[i+1].scan) {
+      // 0xM0 followed by 0x0N detected.
+      SkipScanIvars[i].scan = SkipScanIvars[i+1].scan;
+      for (int j = i+1; j < SkipScan; j++)
+        SkipScanIvars[j] = SkipScanIvars[j+1];
+      --SkipScan;
+    }
+  }
+
+  // Generate the string.
+  std::string BitMap;
+  for (int i = 0; i <= SkipScan; i++) {
+    unsigned char byte;
+    unsigned int skip_small = SkipScanIvars[i].skip % 0xf;
+    unsigned int scan_small = SkipScanIvars[i].scan % 0xf;
+    unsigned int skip_big  = SkipScanIvars[i].skip / 0xf;
+    unsigned int scan_big  = SkipScanIvars[i].scan / 0xf;
+
+    // first skip big.
+    for (unsigned int ix = 0; ix < skip_big; ix++)
+      BitMap += (unsigned char)(0xf0);
+
+    // next (skip small, scan)
+    if (skip_small) {
+      byte = skip_small << 4;
+      if (scan_big > 0) {
+        byte |= 0xf;
+        --scan_big;
+      } else if (scan_small) {
+        byte |= scan_small;
+        scan_small = 0;
+      }
+      BitMap += byte;
+    }
+    // next scan big
+    for (unsigned int ix = 0; ix < scan_big; ix++)
+      BitMap += (unsigned char)(0x0f);
+    // last scan small
+    if (scan_small) {
+      byte = scan_small;
+      BitMap += byte;
+    }
+  }
+  // null terminate string.
+  unsigned char zero = 0;
+  BitMap += zero;
+
+  if (CGM.getLangOptions().ObjCGCBitmapPrint) {
+    printf("\n%s ivar layout for class '%s': ",
+           ForStrongLayout ? "strong" : "weak",
+           OMD->getClassInterface()->getNameAsCString());
+    const unsigned char *s = (unsigned char*)BitMap.c_str();
+    for (unsigned i = 0; i < BitMap.size(); i++)
+      if (!(s[i] & 0xf0))
+        printf("0x0%x%s", s[i], s[i] != 0 ? ", " : "");
+      else
+        printf("0x%x%s",  s[i], s[i] != 0 ? ", " : "");
+    printf("\n");
+  }
+  llvm::GlobalVariable * Entry =
+    CreateMetadataVar("\01L_OBJC_CLASS_NAME_",
+                      llvm::ConstantArray::get(VMContext, BitMap.c_str()),
+                      "__TEXT,__cstring,cstring_literals",
+                      1, true);
+  return getConstantGEP(VMContext, Entry, 0, 0);
+}
+
+llvm::Constant *CGObjCCommonMac::GetMethodVarName(Selector Sel) {
+  llvm::GlobalVariable *&Entry = MethodVarNames[Sel];
+
+  // FIXME: Avoid std::string copying.
+  if (!Entry)
+    Entry = CreateMetadataVar("\01L_OBJC_METH_VAR_NAME_",
+                        llvm::ConstantArray::get(VMContext, Sel.getAsString()),
+                              "__TEXT,__cstring,cstring_literals",
+                              1, true);
+
+  return getConstantGEP(VMContext, Entry, 0, 0);
+}
+
+// FIXME: Merge into a single cstring creation function.
+llvm::Constant *CGObjCCommonMac::GetMethodVarName(IdentifierInfo *ID) {
+  return GetMethodVarName(CGM.getContext().Selectors.getNullarySelector(ID));
+}
+
+// FIXME: Merge into a single cstring creation function.
+llvm::Constant *CGObjCCommonMac::GetMethodVarName(const std::string &Name) {
+  return GetMethodVarName(&CGM.getContext().Idents.get(Name));
+}
+
+llvm::Constant *CGObjCCommonMac::GetMethodVarType(const FieldDecl *Field) {
+  std::string TypeStr;
+  CGM.getContext().getObjCEncodingForType(Field->getType(), TypeStr, Field);
+
+  llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
+
+  if (!Entry)
+    Entry = CreateMetadataVar("\01L_OBJC_METH_VAR_TYPE_",
+                              llvm::ConstantArray::get(VMContext, TypeStr),
+                              "__TEXT,__cstring,cstring_literals",
+                              1, true);
+
+  return getConstantGEP(VMContext, Entry, 0, 0);
+}
+
+llvm::Constant *CGObjCCommonMac::GetMethodVarType(const ObjCMethodDecl *D) {
+  std::string TypeStr;
+  CGM.getContext().getObjCEncodingForMethodDecl(const_cast<ObjCMethodDecl*>(D),
+                                                TypeStr);
+
+  llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
+
+  if (!Entry)
+    Entry = CreateMetadataVar("\01L_OBJC_METH_VAR_TYPE_",
+                              llvm::ConstantArray::get(VMContext, TypeStr),
+                              "__TEXT,__cstring,cstring_literals",
+                              1, true);
+
+  return getConstantGEP(VMContext, Entry, 0, 0);
+}
+
+// FIXME: Merge into a single cstring creation function.
+llvm::Constant *CGObjCCommonMac::GetPropertyName(IdentifierInfo *Ident) {
+  llvm::GlobalVariable *&Entry = PropertyNames[Ident];
+
+  if (!Entry)
+    Entry = CreateMetadataVar("\01L_OBJC_PROP_NAME_ATTR_",
+                          llvm::ConstantArray::get(VMContext,
+                                                   Ident->getNameStart()),
+                              "__TEXT,__cstring,cstring_literals",
+                              1, true);
+
+  return getConstantGEP(VMContext, Entry, 0, 0);
+}
+
+// FIXME: Merge into a single cstring creation function.
+// FIXME: This Decl should be more precise.
+llvm::Constant *
+CGObjCCommonMac::GetPropertyTypeString(const ObjCPropertyDecl *PD,
+                                       const Decl *Container) {
+  std::string TypeStr;
+  CGM.getContext().getObjCEncodingForPropertyDecl(PD, Container, TypeStr);
+  return GetPropertyName(&CGM.getContext().Idents.get(TypeStr));
+}
+
+void CGObjCCommonMac::GetNameForMethod(const ObjCMethodDecl *D,
+                                       const ObjCContainerDecl *CD,
+                                       llvm::SmallVectorImpl<char> &Name) {
+  llvm::raw_svector_ostream OS(Name);
+  assert (CD && "Missing container decl in GetNameForMethod");
+  OS << '\01' << (D->isInstanceMethod() ? '-' : '+')
+     << '[' << CD->getName();
+  if (const ObjCCategoryImplDecl *CID =
+      dyn_cast<ObjCCategoryImplDecl>(D->getDeclContext()))
+    OS << '(' << CID << ')';
+  OS << ' ' << D->getSelector().getAsString() << ']';
+}
+
+void CGObjCMac::FinishModule() {
+  EmitModuleInfo();
+
+  // Emit the dummy bodies for any protocols which were referenced but
+  // never defined.
+  for (llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*>::iterator
+         I = Protocols.begin(), e = Protocols.end(); I != e; ++I) {
+    if (I->second->hasInitializer())
+      continue;
+
+    std::vector<llvm::Constant*> Values(5);
+    Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
+    Values[1] = GetClassName(I->first);
+    Values[2] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
+    Values[3] = Values[4] =
+      llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
+    I->second->setLinkage(llvm::GlobalValue::InternalLinkage);
+    I->second->setInitializer(llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
+                                                        Values));
+    CGM.AddUsedGlobal(I->second);
+  }
+
+  // Add assembler directives to add lazy undefined symbol references
+  // for classes which are referenced but not defined. This is
+  // important for correct linker interaction.
+  //
+  // FIXME: It would be nice if we had an LLVM construct for this.
+  if (!LazySymbols.empty() || !DefinedSymbols.empty()) {
+    llvm::SmallString<256> Asm;
+    Asm += CGM.getModule().getModuleInlineAsm();
+    if (!Asm.empty() && Asm.back() != '\n')
+      Asm += '\n';
+
+    llvm::raw_svector_ostream OS(Asm);
+    for (llvm::SetVector<IdentifierInfo*>::iterator I = DefinedSymbols.begin(),
+           e = DefinedSymbols.end(); I != e; ++I)
+      OS << "\t.objc_class_name_" << (*I)->getName() << "=0\n"
+         << "\t.globl .objc_class_name_" << (*I)->getName() << "\n";
+    for (llvm::SetVector<IdentifierInfo*>::iterator I = LazySymbols.begin(),
+         e = LazySymbols.end(); I != e; ++I)
+      OS << "\t.lazy_reference .objc_class_name_" << (*I)->getName() << "\n";
+    
+    CGM.getModule().setModuleInlineAsm(OS.str());
+  }
+}
+
+CGObjCNonFragileABIMac::CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm)
+  : CGObjCCommonMac(cgm),
+    ObjCTypes(cgm) {
+  ObjCEmptyCacheVar = ObjCEmptyVtableVar = NULL;
+  ObjCABI = 2;
+}
+
+/* *** */
+
+ObjCCommonTypesHelper::ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm)
+  : VMContext(cgm.getLLVMContext()), CGM(cgm) {
+  CodeGen::CodeGenTypes &Types = CGM.getTypes();
+  ASTContext &Ctx = CGM.getContext();
+
+  ShortTy = Types.ConvertType(Ctx.ShortTy);
+  IntTy = Types.ConvertType(Ctx.IntTy);
+  LongTy = Types.ConvertType(Ctx.LongTy);
+  LongLongTy = Types.ConvertType(Ctx.LongLongTy);
+  Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext);
+
+  ObjectPtrTy = Types.ConvertType(Ctx.getObjCIdType());
+  PtrObjectPtrTy = llvm::PointerType::getUnqual(ObjectPtrTy);
+  SelectorPtrTy = Types.ConvertType(Ctx.getObjCSelType());
+
+  // FIXME: It would be nice to unify this with the opaque type, so that the IR
+  // comes out a bit cleaner.
+  const llvm::Type *T = Types.ConvertType(Ctx.getObjCProtoType());
+  ExternalProtocolPtrTy = llvm::PointerType::getUnqual(T);
+
+  // I'm not sure I like this. The implicit coordination is a bit
+  // gross. We should solve this in a reasonable fashion because this
+  // is a pretty common task (match some runtime data structure with
+  // an LLVM data structure).
+
+  // FIXME: This is leaked.
+  // FIXME: Merge with rewriter code?
+
+  // struct _objc_super {
+  //   id self;
+  //   Class cls;
+  // }
+  RecordDecl *RD = RecordDecl::Create(Ctx, TagDecl::TK_struct, 0,
+                                      SourceLocation(),
+                                      &Ctx.Idents.get("_objc_super"));
+  RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), 0,
+                                Ctx.getObjCIdType(), 0, 0, false));
+  RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), 0,
+                                Ctx.getObjCClassType(), 0, 0, false));
+  RD->completeDefinition();
+
+  SuperCTy = Ctx.getTagDeclType(RD);
+  SuperPtrCTy = Ctx.getPointerType(SuperCTy);
+
+  SuperTy = cast<llvm::StructType>(Types.ConvertType(SuperCTy));
+  SuperPtrTy = llvm::PointerType::getUnqual(SuperTy);
+
+  // struct _prop_t {
+  //   char *name;
+  //   char *attributes;
+  // }
+  PropertyTy = llvm::StructType::get(VMContext, Int8PtrTy, Int8PtrTy, NULL);
+  CGM.getModule().addTypeName("struct._prop_t",
+                              PropertyTy);
+
+  // struct _prop_list_t {
+  //   uint32_t entsize;      // sizeof(struct _prop_t)
+  //   uint32_t count_of_properties;
+  //   struct _prop_t prop_list[count_of_properties];
+  // }
+  PropertyListTy = llvm::StructType::get(VMContext, IntTy,
+                                         IntTy,
+                                         llvm::ArrayType::get(PropertyTy, 0),
+                                         NULL);
+  CGM.getModule().addTypeName("struct._prop_list_t",
+                              PropertyListTy);
+  // struct _prop_list_t *
+  PropertyListPtrTy = llvm::PointerType::getUnqual(PropertyListTy);
+
+  // struct _objc_method {
+  //   SEL _cmd;
+  //   char *method_type;
+  //   char *_imp;
+  // }
+  MethodTy = llvm::StructType::get(VMContext, SelectorPtrTy,
+                                   Int8PtrTy,
+                                   Int8PtrTy,
+                                   NULL);
+  CGM.getModule().addTypeName("struct._objc_method", MethodTy);
+
+  // struct _objc_cache *
+  CacheTy = llvm::OpaqueType::get(VMContext);
+  CGM.getModule().addTypeName("struct._objc_cache", CacheTy);
+  CachePtrTy = llvm::PointerType::getUnqual(CacheTy);
+}
+
+ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
+  : ObjCCommonTypesHelper(cgm) {
+  // struct _objc_method_description {
+  //   SEL name;
+  //   char *types;
+  // }
+  MethodDescriptionTy =
+    llvm::StructType::get(VMContext, SelectorPtrTy,
+                          Int8PtrTy,
+                          NULL);
+  CGM.getModule().addTypeName("struct._objc_method_description",
+                              MethodDescriptionTy);
+
+  // struct _objc_method_description_list {
+  //   int count;
+  //   struct _objc_method_description[1];
+  // }
+  MethodDescriptionListTy =
+    llvm::StructType::get(VMContext, IntTy,
+                          llvm::ArrayType::get(MethodDescriptionTy, 0),
+                          NULL);
+  CGM.getModule().addTypeName("struct._objc_method_description_list",
+                              MethodDescriptionListTy);
+
+  // struct _objc_method_description_list *
+  MethodDescriptionListPtrTy =
+    llvm::PointerType::getUnqual(MethodDescriptionListTy);
+
+  // Protocol description structures
+
+  // struct _objc_protocol_extension {
+  //   uint32_t size;  // sizeof(struct _objc_protocol_extension)
+  //   struct _objc_method_description_list *optional_instance_methods;
+  //   struct _objc_method_description_list *optional_class_methods;
+  //   struct _objc_property_list *instance_properties;
+  // }
+  ProtocolExtensionTy =
+    llvm::StructType::get(VMContext, IntTy,
+                          MethodDescriptionListPtrTy,
+                          MethodDescriptionListPtrTy,
+                          PropertyListPtrTy,
+                          NULL);
+  CGM.getModule().addTypeName("struct._objc_protocol_extension",
+                              ProtocolExtensionTy);
+
+  // struct _objc_protocol_extension *
+  ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(ProtocolExtensionTy);
+
+  // Handle recursive construction of Protocol and ProtocolList types
+
+  llvm::PATypeHolder ProtocolTyHolder = llvm::OpaqueType::get(VMContext);
+  llvm::PATypeHolder ProtocolListTyHolder = llvm::OpaqueType::get(VMContext);
+
+  const llvm::Type *T =
+    llvm::StructType::get(VMContext,
+                          llvm::PointerType::getUnqual(ProtocolListTyHolder),
+                          LongTy,
+                          llvm::ArrayType::get(ProtocolTyHolder, 0),
+                          NULL);
+  cast<llvm::OpaqueType>(ProtocolListTyHolder.get())->refineAbstractTypeTo(T);
+
+  // struct _objc_protocol {
+  //   struct _objc_protocol_extension *isa;
+  //   char *protocol_name;
+  //   struct _objc_protocol **_objc_protocol_list;
+  //   struct _objc_method_description_list *instance_methods;
+  //   struct _objc_method_description_list *class_methods;
+  // }
+  T = llvm::StructType::get(VMContext, ProtocolExtensionPtrTy,
+                            Int8PtrTy,
+                            llvm::PointerType::getUnqual(ProtocolListTyHolder),
+                            MethodDescriptionListPtrTy,
+                            MethodDescriptionListPtrTy,
+                            NULL);
+  cast<llvm::OpaqueType>(ProtocolTyHolder.get())->refineAbstractTypeTo(T);
+
+  ProtocolListTy = cast<llvm::StructType>(ProtocolListTyHolder.get());
+  CGM.getModule().addTypeName("struct._objc_protocol_list",
+                              ProtocolListTy);
+  // struct _objc_protocol_list *
+  ProtocolListPtrTy = llvm::PointerType::getUnqual(ProtocolListTy);
+
+  ProtocolTy = cast<llvm::StructType>(ProtocolTyHolder.get());
+  CGM.getModule().addTypeName("struct._objc_protocol", ProtocolTy);
+  ProtocolPtrTy = llvm::PointerType::getUnqual(ProtocolTy);
+
+  // Class description structures
+
+  // struct _objc_ivar {
+  //   char *ivar_name;
+  //   char *ivar_type;
+  //   int  ivar_offset;
+  // }
+  IvarTy = llvm::StructType::get(VMContext, Int8PtrTy,
+                                 Int8PtrTy,
+                                 IntTy,
+                                 NULL);
+  CGM.getModule().addTypeName("struct._objc_ivar", IvarTy);
+
+  // struct _objc_ivar_list *
+  IvarListTy = llvm::OpaqueType::get(VMContext);
+  CGM.getModule().addTypeName("struct._objc_ivar_list", IvarListTy);
+  IvarListPtrTy = llvm::PointerType::getUnqual(IvarListTy);
+
+  // struct _objc_method_list *
+  MethodListTy = llvm::OpaqueType::get(VMContext);
+  CGM.getModule().addTypeName("struct._objc_method_list", MethodListTy);
+  MethodListPtrTy = llvm::PointerType::getUnqual(MethodListTy);
+
+  // struct _objc_class_extension *
+  ClassExtensionTy =
+    llvm::StructType::get(VMContext, IntTy,
+                          Int8PtrTy,
+                          PropertyListPtrTy,
+                          NULL);
+  CGM.getModule().addTypeName("struct._objc_class_extension", ClassExtensionTy);
+  ClassExtensionPtrTy = llvm::PointerType::getUnqual(ClassExtensionTy);
+
+  llvm::PATypeHolder ClassTyHolder = llvm::OpaqueType::get(VMContext);
+
+  // struct _objc_class {
+  //   Class isa;
+  //   Class super_class;
+  //   char *name;
+  //   long version;
+  //   long info;
+  //   long instance_size;
+  //   struct _objc_ivar_list *ivars;
+  //   struct _objc_method_list *methods;
+  //   struct _objc_cache *cache;
+  //   struct _objc_protocol_list *protocols;
+  //   char *ivar_layout;
+  //   struct _objc_class_ext *ext;
+  // };
+  T = llvm::StructType::get(VMContext,
+                            llvm::PointerType::getUnqual(ClassTyHolder),
+                            llvm::PointerType::getUnqual(ClassTyHolder),
+                            Int8PtrTy,
+                            LongTy,
+                            LongTy,
+                            LongTy,
+                            IvarListPtrTy,
+                            MethodListPtrTy,
+                            CachePtrTy,
+                            ProtocolListPtrTy,
+                            Int8PtrTy,
+                            ClassExtensionPtrTy,
+                            NULL);
+  cast<llvm::OpaqueType>(ClassTyHolder.get())->refineAbstractTypeTo(T);
+
+  ClassTy = cast<llvm::StructType>(ClassTyHolder.get());
+  CGM.getModule().addTypeName("struct._objc_class", ClassTy);
+  ClassPtrTy = llvm::PointerType::getUnqual(ClassTy);
+
+  // struct _objc_category {
+  //   char *category_name;
+  //   char *class_name;
+  //   struct _objc_method_list *instance_method;
+  //   struct _objc_method_list *class_method;
+  //   uint32_t size;  // sizeof(struct _objc_category)
+  //   struct _objc_property_list *instance_properties;// category's @property
+  // }
+  CategoryTy = llvm::StructType::get(VMContext, Int8PtrTy,
+                                     Int8PtrTy,
+                                     MethodListPtrTy,
+                                     MethodListPtrTy,
+                                     ProtocolListPtrTy,
+                                     IntTy,
+                                     PropertyListPtrTy,
+                                     NULL);
+  CGM.getModule().addTypeName("struct._objc_category", CategoryTy);
+
+  // Global metadata structures
+
+  // struct _objc_symtab {
+  //   long sel_ref_cnt;
+  //   SEL *refs;
+  //   short cls_def_cnt;
+  //   short cat_def_cnt;
+  //   char *defs[cls_def_cnt + cat_def_cnt];
+  // }
+  SymtabTy = llvm::StructType::get(VMContext, LongTy,
+                                   SelectorPtrTy,
+                                   ShortTy,
+                                   ShortTy,
+                                   llvm::ArrayType::get(Int8PtrTy, 0),
+                                   NULL);
+  CGM.getModule().addTypeName("struct._objc_symtab", SymtabTy);
+  SymtabPtrTy = llvm::PointerType::getUnqual(SymtabTy);
+
+  // struct _objc_module {
+  //   long version;
+  //   long size;   // sizeof(struct _objc_module)
+  //   char *name;
+  //   struct _objc_symtab* symtab;
+  //  }
+  ModuleTy =
+    llvm::StructType::get(VMContext, LongTy,
+                          LongTy,
+                          Int8PtrTy,
+                          SymtabPtrTy,
+                          NULL);
+  CGM.getModule().addTypeName("struct._objc_module", ModuleTy);
+
+
+  // FIXME: This is the size of the setjmp buffer and should be target
+  // specific. 18 is what's used on 32-bit X86.
+  uint64_t SetJmpBufferSize = 18;
+
+  // Exceptions
+  const llvm::Type *StackPtrTy = llvm::ArrayType::get(
+    llvm::Type::getInt8PtrTy(VMContext), 4);
+
+  ExceptionDataTy =
+    llvm::StructType::get(VMContext, llvm::ArrayType::get(llvm::Type::getInt32Ty(VMContext),
+                                                          SetJmpBufferSize),
+                          StackPtrTy, NULL);
+  CGM.getModule().addTypeName("struct._objc_exception_data",
+                              ExceptionDataTy);
+
+}
+
+ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm)
+  : ObjCCommonTypesHelper(cgm) {
+  // struct _method_list_t {
+  //   uint32_t entsize;  // sizeof(struct _objc_method)
+  //   uint32_t method_count;
+  //   struct _objc_method method_list[method_count];
+  // }
+  MethodListnfABITy = llvm::StructType::get(VMContext, IntTy,
+                                            IntTy,
+                                            llvm::ArrayType::get(MethodTy, 0),
+                                            NULL);
+  CGM.getModule().addTypeName("struct.__method_list_t",
+                              MethodListnfABITy);
+  // struct method_list_t *
+  MethodListnfABIPtrTy = llvm::PointerType::getUnqual(MethodListnfABITy);
+
+  // struct _protocol_t {
+  //   id isa;  // NULL
+  //   const char * const protocol_name;
+  //   const struct _protocol_list_t * protocol_list; // super protocols
+  //   const struct method_list_t * const instance_methods;
+  //   const struct method_list_t * const class_methods;
+  //   const struct method_list_t *optionalInstanceMethods;
+  //   const struct method_list_t *optionalClassMethods;
+  //   const struct _prop_list_t * properties;
+  //   const uint32_t size;  // sizeof(struct _protocol_t)
+  //   const uint32_t flags;  // = 0
+  // }
+
+  // Holder for struct _protocol_list_t *
+  llvm::PATypeHolder ProtocolListTyHolder = llvm::OpaqueType::get(VMContext);
+
+  ProtocolnfABITy = llvm::StructType::get(VMContext, ObjectPtrTy,
+                                          Int8PtrTy,
+                                          llvm::PointerType::getUnqual(
+                                            ProtocolListTyHolder),
+                                          MethodListnfABIPtrTy,
+                                          MethodListnfABIPtrTy,
+                                          MethodListnfABIPtrTy,
+                                          MethodListnfABIPtrTy,
+                                          PropertyListPtrTy,
+                                          IntTy,
+                                          IntTy,
+                                          NULL);
+  CGM.getModule().addTypeName("struct._protocol_t",
+                              ProtocolnfABITy);
+
+  // struct _protocol_t*
+  ProtocolnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolnfABITy);
+
+  // struct _protocol_list_t {
+  //   long protocol_count;   // Note, this is 32/64 bit
+  //   struct _protocol_t *[protocol_count];
+  // }
+  ProtocolListnfABITy = llvm::StructType::get(VMContext, LongTy,
+                                              llvm::ArrayType::get(
+                                                ProtocolnfABIPtrTy, 0),
+                                              NULL);
+  CGM.getModule().addTypeName("struct._objc_protocol_list",
+                              ProtocolListnfABITy);
+  cast<llvm::OpaqueType>(ProtocolListTyHolder.get())->refineAbstractTypeTo(
+    ProtocolListnfABITy);
+
+  // struct _objc_protocol_list*
+  ProtocolListnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolListnfABITy);
+
+  // struct _ivar_t {
+  //   unsigned long int *offset;  // pointer to ivar offset location
+  //   char *name;
+  //   char *type;
+  //   uint32_t alignment;
+  //   uint32_t size;
+  // }
+  IvarnfABITy = llvm::StructType::get(VMContext,
+                                      llvm::PointerType::getUnqual(LongTy),
+                                      Int8PtrTy,
+                                      Int8PtrTy,
+                                      IntTy,
+                                      IntTy,
+                                      NULL);
+  CGM.getModule().addTypeName("struct._ivar_t", IvarnfABITy);
+
+  // struct _ivar_list_t {
+  //   uint32 entsize;  // sizeof(struct _ivar_t)
+  //   uint32 count;
+  //   struct _iver_t list[count];
+  // }
+  IvarListnfABITy = llvm::StructType::get(VMContext, IntTy,
+                                          IntTy,
+                                          llvm::ArrayType::get(
+                                            IvarnfABITy, 0),
+                                          NULL);
+  CGM.getModule().addTypeName("struct._ivar_list_t", IvarListnfABITy);
+
+  IvarListnfABIPtrTy = llvm::PointerType::getUnqual(IvarListnfABITy);
+
+  // struct _class_ro_t {
+  //   uint32_t const flags;
+  //   uint32_t const instanceStart;
+  //   uint32_t const instanceSize;
+  //   uint32_t const reserved;  // only when building for 64bit targets
+  //   const uint8_t * const ivarLayout;
+  //   const char *const name;
+  //   const struct _method_list_t * const baseMethods;
+  //   const struct _objc_protocol_list *const baseProtocols;
+  //   const struct _ivar_list_t *const ivars;
+  //   const uint8_t * const weakIvarLayout;
+  //   const struct _prop_list_t * const properties;
+  // }
+
+  // FIXME. Add 'reserved' field in 64bit abi mode!
+  ClassRonfABITy = llvm::StructType::get(VMContext, IntTy,
+                                         IntTy,
+                                         IntTy,
+                                         Int8PtrTy,
+                                         Int8PtrTy,
+                                         MethodListnfABIPtrTy,
+                                         ProtocolListnfABIPtrTy,
+                                         IvarListnfABIPtrTy,
+                                         Int8PtrTy,
+                                         PropertyListPtrTy,
+                                         NULL);
+  CGM.getModule().addTypeName("struct._class_ro_t",
+                              ClassRonfABITy);
+
+  // ImpnfABITy - LLVM for id (*)(id, SEL, ...)
+  std::vector<const llvm::Type*> Params;
+  Params.push_back(ObjectPtrTy);
+  Params.push_back(SelectorPtrTy);
+  ImpnfABITy = llvm::PointerType::getUnqual(
+    llvm::FunctionType::get(ObjectPtrTy, Params, false));
+
+  // struct _class_t {
+  //   struct _class_t *isa;
+  //   struct _class_t * const superclass;
+  //   void *cache;
+  //   IMP *vtable;
+  //   struct class_ro_t *ro;
+  // }
+
+  llvm::PATypeHolder ClassTyHolder = llvm::OpaqueType::get(VMContext);
+  ClassnfABITy =
+    llvm::StructType::get(VMContext,
+                          llvm::PointerType::getUnqual(ClassTyHolder),
+                          llvm::PointerType::getUnqual(ClassTyHolder),
+                          CachePtrTy,
+                          llvm::PointerType::getUnqual(ImpnfABITy),
+                          llvm::PointerType::getUnqual(ClassRonfABITy),
+                          NULL);
+  CGM.getModule().addTypeName("struct._class_t", ClassnfABITy);
+
+  cast<llvm::OpaqueType>(ClassTyHolder.get())->refineAbstractTypeTo(
+    ClassnfABITy);
+
+  // LLVM for struct _class_t *
+  ClassnfABIPtrTy = llvm::PointerType::getUnqual(ClassnfABITy);
+
+  // struct _category_t {
+  //   const char * const name;
+  //   struct _class_t *const cls;
+  //   const struct _method_list_t * const instance_methods;
+  //   const struct _method_list_t * const class_methods;
+  //   const struct _protocol_list_t * const protocols;
+  //   const struct _prop_list_t * const properties;
+  // }
+  CategorynfABITy = llvm::StructType::get(VMContext, Int8PtrTy,
+                                          ClassnfABIPtrTy,
+                                          MethodListnfABIPtrTy,
+                                          MethodListnfABIPtrTy,
+                                          ProtocolListnfABIPtrTy,
+                                          PropertyListPtrTy,
+                                          NULL);
+  CGM.getModule().addTypeName("struct._category_t", CategorynfABITy);
+
+  // New types for nonfragile abi messaging.
+  CodeGen::CodeGenTypes &Types = CGM.getTypes();
+  ASTContext &Ctx = CGM.getContext();
+
+  // MessageRefTy - LLVM for:
+  // struct _message_ref_t {
+  //   IMP messenger;
+  //   SEL name;
+  // };
+
+  // First the clang type for struct _message_ref_t
+  RecordDecl *RD = RecordDecl::Create(Ctx, TagDecl::TK_struct, 0,
+                                      SourceLocation(),
+                                      &Ctx.Idents.get("_message_ref_t"));
+  RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), 0,
+                                Ctx.VoidPtrTy, 0, 0, false));
+  RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), 0,
+                                Ctx.getObjCSelType(), 0, 0, false));
+  RD->completeDefinition();
+
+  MessageRefCTy = Ctx.getTagDeclType(RD);
+  MessageRefCPtrTy = Ctx.getPointerType(MessageRefCTy);
+  MessageRefTy = cast<llvm::StructType>(Types.ConvertType(MessageRefCTy));
+
+  // MessageRefPtrTy - LLVM for struct _message_ref_t*
+  MessageRefPtrTy = llvm::PointerType::getUnqual(MessageRefTy);
+
+  // SuperMessageRefTy - LLVM for:
+  // struct _super_message_ref_t {
+  //   SUPER_IMP messenger;
+  //   SEL name;
+  // };
+  SuperMessageRefTy = llvm::StructType::get(VMContext, ImpnfABITy,
+                                            SelectorPtrTy,
+                                            NULL);
+  CGM.getModule().addTypeName("struct._super_message_ref_t", SuperMessageRefTy);
+
+  // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t*
+  SuperMessageRefPtrTy = llvm::PointerType::getUnqual(SuperMessageRefTy);
+
+
+  // struct objc_typeinfo {
+  //   const void** vtable; // objc_ehtype_vtable + 2
+  //   const char*  name;    // c++ typeinfo string
+  //   Class        cls;
+  // };
+  EHTypeTy = llvm::StructType::get(VMContext,
+                                   llvm::PointerType::getUnqual(Int8PtrTy),
+                                   Int8PtrTy,
+                                   ClassnfABIPtrTy,
+                                   NULL);
+  CGM.getModule().addTypeName("struct._objc_typeinfo", EHTypeTy);
+  EHTypePtrTy = llvm::PointerType::getUnqual(EHTypeTy);
+}
+
+llvm::Function *CGObjCNonFragileABIMac::ModuleInitFunction() {
+  FinishNonFragileABIModule();
+
+  return NULL;
+}
+
+void CGObjCNonFragileABIMac::AddModuleClassList(const
+                                                std::vector<llvm::GlobalValue*>
+                                                &Container,
+                                                const char *SymbolName,
+                                                const char *SectionName) {
+  unsigned NumClasses = Container.size();
+
+  if (!NumClasses)
+    return;
+
+  std::vector<llvm::Constant*> Symbols(NumClasses);
+  for (unsigned i=0; i<NumClasses; i++)
+    Symbols[i] = llvm::ConstantExpr::getBitCast(Container[i],
+                                                ObjCTypes.Int8PtrTy);
+  llvm::Constant* Init =
+    llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
+                                                  NumClasses),
+                             Symbols);
+
+  llvm::GlobalVariable *GV =
+    new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
+                             llvm::GlobalValue::InternalLinkage,
+                             Init,
+                             SymbolName);
+  GV->setAlignment(CGM.getTargetData().getABITypeAlignment(Init->getType()));
+  GV->setSection(SectionName);
+  CGM.AddUsedGlobal(GV);
+}
+
+void CGObjCNonFragileABIMac::FinishNonFragileABIModule() {
+  // nonfragile abi has no module definition.
+
+  // Build list of all implemented class addresses in array
+  // L_OBJC_LABEL_CLASS_$.
+  AddModuleClassList(DefinedClasses,
+                     "\01L_OBJC_LABEL_CLASS_$",
+                     "__DATA, __objc_classlist, regular, no_dead_strip");
+  
+  for (unsigned i = 0; i < DefinedClasses.size(); i++) {
+    llvm::GlobalValue *IMPLGV = DefinedClasses[i];
+    if (IMPLGV->getLinkage() != llvm::GlobalValue::ExternalWeakLinkage)
+      continue;
+    IMPLGV->setLinkage(llvm::GlobalValue::ExternalLinkage);
+  }
+  
+  for (unsigned i = 0; i < DefinedMetaClasses.size(); i++) {
+    llvm::GlobalValue *IMPLGV = DefinedMetaClasses[i];
+    if (IMPLGV->getLinkage() != llvm::GlobalValue::ExternalWeakLinkage)
+      continue;
+    IMPLGV->setLinkage(llvm::GlobalValue::ExternalLinkage);
+  }    
+  
+  AddModuleClassList(DefinedNonLazyClasses,
+                     "\01L_OBJC_LABEL_NONLAZY_CLASS_$",
+                     "__DATA, __objc_nlclslist, regular, no_dead_strip");
+
+  // Build list of all implemented category addresses in array
+  // L_OBJC_LABEL_CATEGORY_$.
+  AddModuleClassList(DefinedCategories,
+                     "\01L_OBJC_LABEL_CATEGORY_$",
+                     "__DATA, __objc_catlist, regular, no_dead_strip");
+  AddModuleClassList(DefinedNonLazyCategories,
+                     "\01L_OBJC_LABEL_NONLAZY_CATEGORY_$",
+                     "__DATA, __objc_nlcatlist, regular, no_dead_strip");
+
+  EmitImageInfo();
+}
+
+/// LegacyDispatchedSelector - Returns true if SEL is not in the list of
+/// NonLegacyDispatchMethods; false otherwise. What this means is that
+/// except for the 19 selectors in the list, we generate 32bit-style
+/// message dispatch call for all the rest.
+///
+bool CGObjCNonFragileABIMac::LegacyDispatchedSelector(Selector Sel) {
+  switch (CGM.getCodeGenOpts().getObjCDispatchMethod()) {
+  default:
+    assert(0 && "Invalid dispatch method!");
+  case CodeGenOptions::Legacy:
+    return true;
+  case CodeGenOptions::NonLegacy:
+    return false;
+  case CodeGenOptions::Mixed:
+    break;
+  }
+
+  // If so, see whether this selector is in the white-list of things which must
+  // use the new dispatch convention. We lazily build a dense set for this.
+  if (NonLegacyDispatchMethods.empty()) {
+    NonLegacyDispatchMethods.insert(GetNullarySelector("alloc"));
+    NonLegacyDispatchMethods.insert(GetNullarySelector("class"));
+    NonLegacyDispatchMethods.insert(GetNullarySelector("self"));
+    NonLegacyDispatchMethods.insert(GetNullarySelector("isFlipped"));
+    NonLegacyDispatchMethods.insert(GetNullarySelector("length"));
+    NonLegacyDispatchMethods.insert(GetNullarySelector("count"));
+    NonLegacyDispatchMethods.insert(GetNullarySelector("retain"));
+    NonLegacyDispatchMethods.insert(GetNullarySelector("release"));
+    NonLegacyDispatchMethods.insert(GetNullarySelector("autorelease"));
+    NonLegacyDispatchMethods.insert(GetNullarySelector("hash"));
+
+    NonLegacyDispatchMethods.insert(GetUnarySelector("allocWithZone"));
+    NonLegacyDispatchMethods.insert(GetUnarySelector("isKindOfClass"));
+    NonLegacyDispatchMethods.insert(GetUnarySelector("respondsToSelector"));
+    NonLegacyDispatchMethods.insert(GetUnarySelector("objectForKey"));
+    NonLegacyDispatchMethods.insert(GetUnarySelector("objectAtIndex"));
+    NonLegacyDispatchMethods.insert(GetUnarySelector("isEqualToString"));
+    NonLegacyDispatchMethods.insert(GetUnarySelector("isEqual"));
+    NonLegacyDispatchMethods.insert(GetUnarySelector("addObject"));
+    // "countByEnumeratingWithState:objects:count"
+    IdentifierInfo *KeyIdents[] = {
+      &CGM.getContext().Idents.get("countByEnumeratingWithState"),
+      &CGM.getContext().Idents.get("objects"),
+      &CGM.getContext().Idents.get("count")
+    };
+    NonLegacyDispatchMethods.insert(
+      CGM.getContext().Selectors.getSelector(3, KeyIdents));
+  }
+
+  return (NonLegacyDispatchMethods.count(Sel) == 0);
+}
+
+// Metadata flags
+enum MetaDataDlags {
+  CLS = 0x0,
+  CLS_META = 0x1,
+  CLS_ROOT = 0x2,
+  OBJC2_CLS_HIDDEN = 0x10,
+  CLS_EXCEPTION = 0x20
+};
+/// BuildClassRoTInitializer - generate meta-data for:
+/// struct _class_ro_t {
+///   uint32_t const flags;
+///   uint32_t const instanceStart;
+///   uint32_t const instanceSize;
+///   uint32_t const reserved;  // only when building for 64bit targets
+///   const uint8_t * const ivarLayout;
+///   const char *const name;
+///   const struct _method_list_t * const baseMethods;
+///   const struct _protocol_list_t *const baseProtocols;
+///   const struct _ivar_list_t *const ivars;
+///   const uint8_t * const weakIvarLayout;
+///   const struct _prop_list_t * const properties;
+/// }
+///
+llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassRoTInitializer(
+  unsigned flags,
+  unsigned InstanceStart,
+  unsigned InstanceSize,
+  const ObjCImplementationDecl *ID) {
+  std::string ClassName = ID->getNameAsString();
+  std::vector<llvm::Constant*> Values(10); // 11 for 64bit targets!
+  Values[ 0] = llvm::ConstantInt::get(ObjCTypes.IntTy, flags);
+  Values[ 1] = llvm::ConstantInt::get(ObjCTypes.IntTy, InstanceStart);
+  Values[ 2] = llvm::ConstantInt::get(ObjCTypes.IntTy, InstanceSize);
+  // FIXME. For 64bit targets add 0 here.
+  Values[ 3] = (flags & CLS_META) ? GetIvarLayoutName(0, ObjCTypes)
+    : BuildIvarLayout(ID, true);
+  Values[ 4] = GetClassName(ID->getIdentifier());
+  // const struct _method_list_t * const baseMethods;
+  std::vector<llvm::Constant*> Methods;
+  std::string MethodListName("\01l_OBJC_$_");
+  if (flags & CLS_META) {
+    MethodListName += "CLASS_METHODS_" + ID->getNameAsString();
+    for (ObjCImplementationDecl::classmeth_iterator
+           i = ID->classmeth_begin(), e = ID->classmeth_end(); i != e; ++i) {
+      // Class methods should always be defined.
+      Methods.push_back(GetMethodConstant(*i));
+    }
+  } else {
+    MethodListName += "INSTANCE_METHODS_" + ID->getNameAsString();
+    for (ObjCImplementationDecl::instmeth_iterator
+           i = ID->instmeth_begin(), e = ID->instmeth_end(); i != e; ++i) {
+      // Instance methods should always be defined.
+      Methods.push_back(GetMethodConstant(*i));
+    }
+    for (ObjCImplementationDecl::propimpl_iterator
+           i = ID->propimpl_begin(), e = ID->propimpl_end(); i != e; ++i) {
+      ObjCPropertyImplDecl *PID = *i;
+
+      if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize){
+        ObjCPropertyDecl *PD = PID->getPropertyDecl();
+
+        if (ObjCMethodDecl *MD = PD->getGetterMethodDecl())
+          if (llvm::Constant *C = GetMethodConstant(MD))
+            Methods.push_back(C);
+        if (ObjCMethodDecl *MD = PD->getSetterMethodDecl())
+          if (llvm::Constant *C = GetMethodConstant(MD))
+            Methods.push_back(C);
+      }
+    }
+  }
+  Values[ 5] = EmitMethodList(MethodListName,
+                              "__DATA, __objc_const", Methods);
+
+  const ObjCInterfaceDecl *OID = ID->getClassInterface();
+  assert(OID && "CGObjCNonFragileABIMac::BuildClassRoTInitializer");
+  Values[ 6] = EmitProtocolList("\01l_OBJC_CLASS_PROTOCOLS_$_"
+                                + OID->getName(),
+                                OID->protocol_begin(),
+                                OID->protocol_end());
+
+  if (flags & CLS_META)
+    Values[ 7] = llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy);
+  else
+    Values[ 7] = EmitIvarList(ID);
+  Values[ 8] = (flags & CLS_META) ? GetIvarLayoutName(0, ObjCTypes)
+    : BuildIvarLayout(ID, false);
+  if (flags & CLS_META)
+    Values[ 9] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
+  else
+    Values[ 9] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ID->getName(),
+                                  ID, ID->getClassInterface(), ObjCTypes);
+  llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassRonfABITy,
+                                                   Values);
+  llvm::GlobalVariable *CLASS_RO_GV =
+    new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassRonfABITy, false,
+                             llvm::GlobalValue::InternalLinkage,
+                             Init,
+                             (flags & CLS_META) ?
+                             std::string("\01l_OBJC_METACLASS_RO_$_")+ClassName :
+                             std::string("\01l_OBJC_CLASS_RO_$_")+ClassName);
+  CLASS_RO_GV->setAlignment(
+    CGM.getTargetData().getABITypeAlignment(ObjCTypes.ClassRonfABITy));
+  CLASS_RO_GV->setSection("__DATA, __objc_const");
+  return CLASS_RO_GV;
+
+}
+
+/// BuildClassMetaData - This routine defines that to-level meta-data
+/// for the given ClassName for:
+/// struct _class_t {
+///   struct _class_t *isa;
+///   struct _class_t * const superclass;
+///   void *cache;
+///   IMP *vtable;
+///   struct class_ro_t *ro;
+/// }
+///
+llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassMetaData(
+  std::string &ClassName,
+  llvm::Constant *IsAGV,
+  llvm::Constant *SuperClassGV,
+  llvm::Constant *ClassRoGV,
+  bool HiddenVisibility) {
+  std::vector<llvm::Constant*> Values(5);
+  Values[0] = IsAGV;
+  Values[1] = SuperClassGV;
+  if (!Values[1])
+    Values[1] = llvm::Constant::getNullValue(ObjCTypes.ClassnfABIPtrTy);
+  Values[2] = ObjCEmptyCacheVar;  // &ObjCEmptyCacheVar
+  Values[3] = ObjCEmptyVtableVar; // &ObjCEmptyVtableVar
+  Values[4] = ClassRoGV;                 // &CLASS_RO_GV
+  llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassnfABITy,
+                                                   Values);
+  llvm::GlobalVariable *GV = GetClassGlobal(ClassName);
+  GV->setInitializer(Init);
+  GV->setSection("__DATA, __objc_data");
+  GV->setAlignment(
+    CGM.getTargetData().getABITypeAlignment(ObjCTypes.ClassnfABITy));
+  if (HiddenVisibility)
+    GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
+  return GV;
+}
+
+bool
+CGObjCNonFragileABIMac::ImplementationIsNonLazy(const ObjCImplDecl *OD) const {
+  return OD->getClassMethod(GetNullarySelector("load")) != 0;
+}
+
+void CGObjCNonFragileABIMac::GetClassSizeInfo(const ObjCImplementationDecl *OID,
+                                              uint32_t &InstanceStart,
+                                              uint32_t &InstanceSize) {
+  const ASTRecordLayout &RL =
+    CGM.getContext().getASTObjCImplementationLayout(OID);
+
+  // InstanceSize is really instance end.
+  InstanceSize = llvm::RoundUpToAlignment(RL.getDataSize(), 8) / 8;
+
+  // If there are no fields, the start is the same as the end.
+  if (!RL.getFieldCount())
+    InstanceStart = InstanceSize;
+  else
+    InstanceStart = RL.getFieldOffset(0) / 8;
+}
+
+void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) {
+  std::string ClassName = ID->getNameAsString();
+  if (!ObjCEmptyCacheVar) {
+    ObjCEmptyCacheVar = new llvm::GlobalVariable(
+      CGM.getModule(),
+      ObjCTypes.CacheTy,
+      false,
+      llvm::GlobalValue::ExternalLinkage,
+      0,
+      "_objc_empty_cache");
+
+    ObjCEmptyVtableVar = new llvm::GlobalVariable(
+      CGM.getModule(),
+      ObjCTypes.ImpnfABITy,
+      false,
+      llvm::GlobalValue::ExternalLinkage,
+      0,
+      "_objc_empty_vtable");
+  }
+  assert(ID->getClassInterface() &&
+         "CGObjCNonFragileABIMac::GenerateClass - class is 0");
+  // FIXME: Is this correct (that meta class size is never computed)?
+  uint32_t InstanceStart =
+    CGM.getTargetData().getTypeAllocSize(ObjCTypes.ClassnfABITy);
+  uint32_t InstanceSize = InstanceStart;
+  uint32_t flags = CLS_META;
+  std::string ObjCMetaClassName(getMetaclassSymbolPrefix());
+  std::string ObjCClassName(getClassSymbolPrefix());
+
+  llvm::GlobalVariable *SuperClassGV, *IsAGV;
+
+  bool classIsHidden =
+    CGM.getDeclVisibilityMode(ID->getClassInterface()) == LangOptions::Hidden;
+  if (classIsHidden)
+    flags |= OBJC2_CLS_HIDDEN;
+  if (!ID->getClassInterface()->getSuperClass()) {
+    // class is root
+    flags |= CLS_ROOT;
+    SuperClassGV = GetClassGlobal(ObjCClassName + ClassName);
+    IsAGV = GetClassGlobal(ObjCMetaClassName + ClassName);
+  } else {
+    // Has a root. Current class is not a root.
+    const ObjCInterfaceDecl *Root = ID->getClassInterface();
+    while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
+      Root = Super;
+    IsAGV = GetClassGlobal(ObjCMetaClassName + Root->getNameAsString());
+    if (Root->hasAttr<WeakImportAttr>())
+      IsAGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
+    // work on super class metadata symbol.
+    std::string SuperClassName =
+      ObjCMetaClassName + 
+        ID->getClassInterface()->getSuperClass()->getNameAsString();
+    SuperClassGV = GetClassGlobal(SuperClassName);
+    if (ID->getClassInterface()->getSuperClass()->hasAttr<WeakImportAttr>())
+      SuperClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
+  }
+  llvm::GlobalVariable *CLASS_RO_GV = BuildClassRoTInitializer(flags,
+                                                               InstanceStart,
+                                                               InstanceSize,ID);
+  std::string TClassName = ObjCMetaClassName + ClassName;
+  llvm::GlobalVariable *MetaTClass =
+    BuildClassMetaData(TClassName, IsAGV, SuperClassGV, CLASS_RO_GV,
+                       classIsHidden);
+  DefinedMetaClasses.push_back(MetaTClass);
+
+  // Metadata for the class
+  flags = CLS;
+  if (classIsHidden)
+    flags |= OBJC2_CLS_HIDDEN;
+
+  if (hasObjCExceptionAttribute(CGM.getContext(), ID->getClassInterface()))
+    flags |= CLS_EXCEPTION;
+
+  if (!ID->getClassInterface()->getSuperClass()) {
+    flags |= CLS_ROOT;
+    SuperClassGV = 0;
+  } else {
+    // Has a root. Current class is not a root.
+    std::string RootClassName =
+      ID->getClassInterface()->getSuperClass()->getNameAsString();
+    SuperClassGV = GetClassGlobal(ObjCClassName + RootClassName);
+    if (ID->getClassInterface()->getSuperClass()->hasAttr<WeakImportAttr>())
+      SuperClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
+  }
+  GetClassSizeInfo(ID, InstanceStart, InstanceSize);
+  CLASS_RO_GV = BuildClassRoTInitializer(flags,
+                                         InstanceStart,
+                                         InstanceSize,
+                                         ID);
+
+  TClassName = ObjCClassName + ClassName;
+  llvm::GlobalVariable *ClassMD =
+    BuildClassMetaData(TClassName, MetaTClass, SuperClassGV, CLASS_RO_GV,
+                       classIsHidden);
+  DefinedClasses.push_back(ClassMD);
+
+  // Determine if this class is also "non-lazy".
+  if (ImplementationIsNonLazy(ID))
+    DefinedNonLazyClasses.push_back(ClassMD);
+
+  // Force the definition of the EHType if necessary.
+  if (flags & CLS_EXCEPTION)
+    GetInterfaceEHType(ID->getClassInterface(), true);
+}
+
+/// GenerateProtocolRef - This routine is called to generate code for
+/// a protocol reference expression; as in:
+/// @code
+///   @protocol(Proto1);
+/// @endcode
+/// It generates a weak reference to l_OBJC_PROTOCOL_REFERENCE_$_Proto1
+/// which will hold address of the protocol meta-data.
+///
+llvm::Value *CGObjCNonFragileABIMac::GenerateProtocolRef(CGBuilderTy &Builder,
+                                                         const ObjCProtocolDecl *PD) {
+
+  // This routine is called for @protocol only. So, we must build definition
+  // of protocol's meta-data (not a reference to it!)
+  //
+  llvm::Constant *Init =
+    llvm::ConstantExpr::getBitCast(GetOrEmitProtocol(PD),
+                                   ObjCTypes.ExternalProtocolPtrTy);
+
+  std::string ProtocolName("\01l_OBJC_PROTOCOL_REFERENCE_$_");
+  ProtocolName += PD->getNameAsCString();
+
+  llvm::GlobalVariable *PTGV = CGM.getModule().getGlobalVariable(ProtocolName);
+  if (PTGV)
+    return Builder.CreateLoad(PTGV, "tmp");
+  PTGV = new llvm::GlobalVariable(
+    CGM.getModule(),
+    Init->getType(), false,
+    llvm::GlobalValue::WeakAnyLinkage,
+    Init,
+    ProtocolName);
+  PTGV->setSection("__DATA, __objc_protorefs, coalesced, no_dead_strip");
+  PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
+  CGM.AddUsedGlobal(PTGV);
+  return Builder.CreateLoad(PTGV, "tmp");
+}
+
+/// GenerateCategory - Build metadata for a category implementation.
+/// struct _category_t {
+///   const char * const name;
+///   struct _class_t *const cls;
+///   const struct _method_list_t * const instance_methods;
+///   const struct _method_list_t * const class_methods;
+///   const struct _protocol_list_t * const protocols;
+///   const struct _prop_list_t * const properties;
+/// }
+///
+void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
+  const ObjCInterfaceDecl *Interface = OCD->getClassInterface();
+  const char *Prefix = "\01l_OBJC_$_CATEGORY_";
+  std::string ExtCatName(Prefix + Interface->getNameAsString()+
+                         "_$_" + OCD->getNameAsString());
+  std::string ExtClassName(getClassSymbolPrefix() +
+                           Interface->getNameAsString());
+
+  std::vector<llvm::Constant*> Values(6);
+  Values[0] = GetClassName(OCD->getIdentifier());
+  // meta-class entry symbol
+  llvm::GlobalVariable *ClassGV = GetClassGlobal(ExtClassName);
+  if (Interface->hasAttr<WeakImportAttr>())
+    ClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
+  
+  Values[1] = ClassGV;
+  std::vector<llvm::Constant*> Methods;
+  std::string MethodListName(Prefix);
+  MethodListName += "INSTANCE_METHODS_" + Interface->getNameAsString() +
+    "_$_" + OCD->getNameAsString();
+
+  for (ObjCCategoryImplDecl::instmeth_iterator
+         i = OCD->instmeth_begin(), e = OCD->instmeth_end(); i != e; ++i) {
+    // Instance methods should always be defined.
+    Methods.push_back(GetMethodConstant(*i));
+  }
+
+  Values[2] = EmitMethodList(MethodListName,
+                             "__DATA, __objc_const",
+                             Methods);
+
+  MethodListName = Prefix;
+  MethodListName += "CLASS_METHODS_" + Interface->getNameAsString() + "_$_" +
+    OCD->getNameAsString();
+  Methods.clear();
+  for (ObjCCategoryImplDecl::classmeth_iterator
+         i = OCD->classmeth_begin(), e = OCD->classmeth_end(); i != e; ++i) {
+    // Class methods should always be defined.
+    Methods.push_back(GetMethodConstant(*i));
+  }
+
+  Values[3] = EmitMethodList(MethodListName,
+                             "__DATA, __objc_const",
+                             Methods);
+  const ObjCCategoryDecl *Category =
+    Interface->FindCategoryDeclaration(OCD->getIdentifier());
+  if (Category) {
+    llvm::SmallString<256> ExtName;
+    llvm::raw_svector_ostream(ExtName) << Interface->getName() << "_$_"
+                                       << OCD->getName();
+    Values[4] = EmitProtocolList("\01l_OBJC_CATEGORY_PROTOCOLS_$_"
+                                 + Interface->getName() + "_$_"
+                                 + Category->getName(),
+                                 Category->protocol_begin(),
+                                 Category->protocol_end());
+    Values[5] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ExtName.str(),
+                                 OCD, Category, ObjCTypes);
+  } else {
+    Values[4] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);
+    Values[5] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
+  }
+
+  llvm::Constant *Init =
+    llvm::ConstantStruct::get(ObjCTypes.CategorynfABITy,
+                              Values);
+  llvm::GlobalVariable *GCATV
+    = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.CategorynfABITy,
+                               false,
+                               llvm::GlobalValue::InternalLinkage,
+                               Init,
+                               ExtCatName);
+  GCATV->setAlignment(
+    CGM.getTargetData().getABITypeAlignment(ObjCTypes.CategorynfABITy));
+  GCATV->setSection("__DATA, __objc_const");
+  CGM.AddUsedGlobal(GCATV);
+  DefinedCategories.push_back(GCATV);
+
+  // Determine if this category is also "non-lazy".
+  if (ImplementationIsNonLazy(OCD))
+    DefinedNonLazyCategories.push_back(GCATV);
+}
+
+/// GetMethodConstant - Return a struct objc_method constant for the
+/// given method if it has been defined. The result is null if the
+/// method has not been defined. The return value has type MethodPtrTy.
+llvm::Constant *CGObjCNonFragileABIMac::GetMethodConstant(
+  const ObjCMethodDecl *MD) {
+  // FIXME: Use DenseMap::lookup
+  llvm::Function *Fn = MethodDefinitions[MD];
+  if (!Fn)
+    return 0;
+
+  std::vector<llvm::Constant*> Method(3);
+  Method[0] =
+    llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
+                                   ObjCTypes.SelectorPtrTy);
+  Method[1] = GetMethodVarType(MD);
+  Method[2] = llvm::ConstantExpr::getBitCast(Fn, ObjCTypes.Int8PtrTy);
+  return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Method);
+}
+
+/// EmitMethodList - Build meta-data for method declarations
+/// struct _method_list_t {
+///   uint32_t entsize;  // sizeof(struct _objc_method)
+///   uint32_t method_count;
+///   struct _objc_method method_list[method_count];
+/// }
+///
+llvm::Constant *CGObjCNonFragileABIMac::EmitMethodList(llvm::Twine Name,
+                                                       const char *Section,
+                                                const ConstantVector &Methods) {
+  // Return null for empty list.
+  if (Methods.empty())
+    return llvm::Constant::getNullValue(ObjCTypes.MethodListnfABIPtrTy);
+
+  std::vector<llvm::Constant*> Values(3);
+  // sizeof(struct _objc_method)
+  unsigned Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.MethodTy);
+  Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
+  // method_count
+  Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
+  llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy,
+                                             Methods.size());
+  Values[2] = llvm::ConstantArray::get(AT, Methods);
+  llvm::Constant *Init = llvm::ConstantStruct::get(VMContext, Values, false);
+
+  llvm::GlobalVariable *GV =
+    new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
+                             llvm::GlobalValue::InternalLinkage,
+                             Init,
+                             Name);
+  GV->setAlignment(
+    CGM.getTargetData().getABITypeAlignment(Init->getType()));
+  GV->setSection(Section);
+  CGM.AddUsedGlobal(GV);
+  return llvm::ConstantExpr::getBitCast(GV,
+                                        ObjCTypes.MethodListnfABIPtrTy);
+}
+
+/// ObjCIvarOffsetVariable - Returns the ivar offset variable for
+/// the given ivar.
+llvm::GlobalVariable *
+CGObjCNonFragileABIMac::ObjCIvarOffsetVariable(const ObjCInterfaceDecl *ID,
+                                               const ObjCIvarDecl *Ivar) {
+  const ObjCInterfaceDecl *Container = Ivar->getContainingInterface();
+  std::string Name = "OBJC_IVAR_$_" + Container->getNameAsString() +
+    '.' + Ivar->getNameAsString();
+  llvm::GlobalVariable *IvarOffsetGV =
+    CGM.getModule().getGlobalVariable(Name);
+  if (!IvarOffsetGV)
+    IvarOffsetGV =
+      new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.LongTy,
+                               false,
+                               llvm::GlobalValue::ExternalLinkage,
+                               0,
+                               Name);
+  return IvarOffsetGV;
+}
+
+llvm::Constant *
+CGObjCNonFragileABIMac::EmitIvarOffsetVar(const ObjCInterfaceDecl *ID,
+                                          const ObjCIvarDecl *Ivar,
+                                          unsigned long int Offset) {
+  llvm::GlobalVariable *IvarOffsetGV = ObjCIvarOffsetVariable(ID, Ivar);
+  IvarOffsetGV->setInitializer(llvm::ConstantInt::get(ObjCTypes.LongTy,
+                                                      Offset));
+  IvarOffsetGV->setAlignment(
+    CGM.getTargetData().getABITypeAlignment(ObjCTypes.LongTy));
+
+  // FIXME: This matches gcc, but shouldn't the visibility be set on the use as
+  // well (i.e., in ObjCIvarOffsetVariable).
+  if (Ivar->getAccessControl() == ObjCIvarDecl::Private ||
+      Ivar->getAccessControl() == ObjCIvarDecl::Package ||
+      CGM.getDeclVisibilityMode(ID) == LangOptions::Hidden)
+    IvarOffsetGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
+  else
+    IvarOffsetGV->setVisibility(llvm::GlobalValue::DefaultVisibility);
+  IvarOffsetGV->setSection("__DATA, __objc_const");
+  return IvarOffsetGV;
+}
+
+/// EmitIvarList - Emit the ivar list for the given
+/// implementation. The return value has type
+/// IvarListnfABIPtrTy.
+///  struct _ivar_t {
+///   unsigned long int *offset;  // pointer to ivar offset location
+///   char *name;
+///   char *type;
+///   uint32_t alignment;
+///   uint32_t size;
+/// }
+/// struct _ivar_list_t {
+///   uint32 entsize;  // sizeof(struct _ivar_t)
+///   uint32 count;
+///   struct _iver_t list[count];
+/// }
+///
+
+llvm::Constant *CGObjCNonFragileABIMac::EmitIvarList(
+  const ObjCImplementationDecl *ID) {
+
+  std::vector<llvm::Constant*> Ivars, Ivar(5);
+
+  const ObjCInterfaceDecl *OID = ID->getClassInterface();
+  assert(OID && "CGObjCNonFragileABIMac::EmitIvarList - null interface");
+
+  // FIXME. Consolidate this with similar code in GenerateClass.
+
+  // Collect declared and synthesized ivars in a small vector.
+  llvm::SmallVector<ObjCIvarDecl*, 16> OIvars;
+  CGM.getContext().ShallowCollectObjCIvars(OID, OIvars);
+
+  for (unsigned i = 0, e = OIvars.size(); i != e; ++i) {
+    ObjCIvarDecl *IVD = OIvars[i];
+    // Ignore unnamed bit-fields.
+    if (!IVD->getDeclName())
+      continue;
+    Ivar[0] = EmitIvarOffsetVar(ID->getClassInterface(), IVD,
+                                ComputeIvarBaseOffset(CGM, ID, IVD));
+    Ivar[1] = GetMethodVarName(IVD->getIdentifier());
+    Ivar[2] = GetMethodVarType(IVD);
+    const llvm::Type *FieldTy =
+      CGM.getTypes().ConvertTypeForMem(IVD->getType());
+    unsigned Size = CGM.getTargetData().getTypeAllocSize(FieldTy);
+    unsigned Align = CGM.getContext().getPreferredTypeAlign(
+      IVD->getType().getTypePtr()) >> 3;
+    Align = llvm::Log2_32(Align);
+    Ivar[3] = llvm::ConstantInt::get(ObjCTypes.IntTy, Align);
+    // NOTE. Size of a bitfield does not match gcc's, because of the
+    // way bitfields are treated special in each. But I am told that
+    // 'size' for bitfield ivars is ignored by the runtime so it does
+    // not matter.  If it matters, there is enough info to get the
+    // bitfield right!
+    Ivar[4] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
+    Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarnfABITy, Ivar));
+  }
+  // Return null for empty list.
+  if (Ivars.empty())
+    return llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy);
+  std::vector<llvm::Constant*> Values(3);
+  unsigned Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.IvarnfABITy);
+  Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
+  Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size());
+  llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarnfABITy,
+                                             Ivars.size());
+  Values[2] = llvm::ConstantArray::get(AT, Ivars);
+  llvm::Constant *Init = llvm::ConstantStruct::get(VMContext, Values, false);
+  const char *Prefix = "\01l_OBJC_$_INSTANCE_VARIABLES_";
+  llvm::GlobalVariable *GV =
+    new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
+                             llvm::GlobalValue::InternalLinkage,
+                             Init,
+                             Prefix + OID->getName());
+  GV->setAlignment(
+    CGM.getTargetData().getABITypeAlignment(Init->getType()));
+  GV->setSection("__DATA, __objc_const");
+
+  CGM.AddUsedGlobal(GV);
+  return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.IvarListnfABIPtrTy);
+}
+
+llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocolRef(
+  const ObjCProtocolDecl *PD) {
+  llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
+
+  if (!Entry) {
+    // We use the initializer as a marker of whether this is a forward
+    // reference or not. At module finalization we add the empty
+    // contents for protocols which were referenced but never defined.
+    Entry =
+      new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy, false,
+                               llvm::GlobalValue::ExternalLinkage,
+                               0,
+                               "\01l_OBJC_PROTOCOL_$_" + PD->getName());
+    Entry->setSection("__DATA,__datacoal_nt,coalesced");
+  }
+
+  return Entry;
+}
+
+/// GetOrEmitProtocol - Generate the protocol meta-data:
+/// @code
+/// struct _protocol_t {
+///   id isa;  // NULL
+///   const char * const protocol_name;
+///   const struct _protocol_list_t * protocol_list; // super protocols
+///   const struct method_list_t * const instance_methods;
+///   const struct method_list_t * const class_methods;
+///   const struct method_list_t *optionalInstanceMethods;
+///   const struct method_list_t *optionalClassMethods;
+///   const struct _prop_list_t * properties;
+///   const uint32_t size;  // sizeof(struct _protocol_t)
+///   const uint32_t flags;  // = 0
+/// }
+/// @endcode
+///
+
+llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol(
+  const ObjCProtocolDecl *PD) {
+  llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
+
+  // Early exit if a defining object has already been generated.
+  if (Entry && Entry->hasInitializer())
+    return Entry;
+
+  // Construct method lists.
+  std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
+  std::vector<llvm::Constant*> OptInstanceMethods, OptClassMethods;
+  for (ObjCProtocolDecl::instmeth_iterator
+         i = PD->instmeth_begin(), e = PD->instmeth_end(); i != e; ++i) {
+    ObjCMethodDecl *MD = *i;
+    llvm::Constant *C = GetMethodDescriptionConstant(MD);
+    if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
+      OptInstanceMethods.push_back(C);
+    } else {
+      InstanceMethods.push_back(C);
+    }
+  }
+
+  for (ObjCProtocolDecl::classmeth_iterator
+         i = PD->classmeth_begin(), e = PD->classmeth_end(); i != e; ++i) {
+    ObjCMethodDecl *MD = *i;
+    llvm::Constant *C = GetMethodDescriptionConstant(MD);
+    if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
+      OptClassMethods.push_back(C);
+    } else {
+      ClassMethods.push_back(C);
+    }
+  }
+
+  std::vector<llvm::Constant*> Values(10);
+  // isa is NULL
+  Values[0] = llvm::Constant::getNullValue(ObjCTypes.ObjectPtrTy);
+  Values[1] = GetClassName(PD->getIdentifier());
+  Values[2] = EmitProtocolList("\01l_OBJC_$_PROTOCOL_REFS_" + PD->getName(),
+                               PD->protocol_begin(),
+                               PD->protocol_end());
+
+  Values[3] = EmitMethodList("\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_"
+                             + PD->getName(),
+                             "__DATA, __objc_const",
+                             InstanceMethods);
+  Values[4] = EmitMethodList("\01l_OBJC_$_PROTOCOL_CLASS_METHODS_"
+                             + PD->getName(),
+                             "__DATA, __objc_const",
+                             ClassMethods);
+  Values[5] = EmitMethodList("\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_OPT_"
+                             + PD->getName(),
+                             "__DATA, __objc_const",
+                             OptInstanceMethods);
+  Values[6] = EmitMethodList("\01l_OBJC_$_PROTOCOL_CLASS_METHODS_OPT_"
+                             + PD->getName(),
+                             "__DATA, __objc_const",
+                             OptClassMethods);
+  Values[7] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + PD->getName(),
+                               0, PD, ObjCTypes);
+  uint32_t Size =
+    CGM.getTargetData().getTypeAllocSize(ObjCTypes.ProtocolnfABITy);
+  Values[8] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
+  Values[9] = llvm::Constant::getNullValue(ObjCTypes.IntTy);
+  llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolnfABITy,
+                                                   Values);
+
+  if (Entry) {
+    // Already created, fix the linkage and update the initializer.
+    Entry->setLinkage(llvm::GlobalValue::WeakAnyLinkage);
+    Entry->setInitializer(Init);
+  } else {
+    Entry =
+      new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy,
+                               false, llvm::GlobalValue::WeakAnyLinkage, Init,
+                               "\01l_OBJC_PROTOCOL_$_" + PD->getName());
+    Entry->setAlignment(
+      CGM.getTargetData().getABITypeAlignment(ObjCTypes.ProtocolnfABITy));
+    Entry->setSection("__DATA,__datacoal_nt,coalesced");
+  }
+  Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
+  CGM.AddUsedGlobal(Entry);
+
+  // Use this protocol meta-data to build protocol list table in section
+  // __DATA, __objc_protolist
+  llvm::GlobalVariable *PTGV =
+    new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABIPtrTy,
+                             false, llvm::GlobalValue::WeakAnyLinkage, Entry,
+                             "\01l_OBJC_LABEL_PROTOCOL_$_" + PD->getName());
+  PTGV->setAlignment(
+    CGM.getTargetData().getABITypeAlignment(ObjCTypes.ProtocolnfABIPtrTy));
+  PTGV->setSection("__DATA, __objc_protolist, coalesced, no_dead_strip");
+  PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
+  CGM.AddUsedGlobal(PTGV);
+  return Entry;
+}
+
+/// EmitProtocolList - Generate protocol list meta-data:
+/// @code
+/// struct _protocol_list_t {
+///   long protocol_count;   // Note, this is 32/64 bit
+///   struct _protocol_t[protocol_count];
+/// }
+/// @endcode
+///
+llvm::Constant *
+CGObjCNonFragileABIMac::EmitProtocolList(llvm::Twine Name,
+                                      ObjCProtocolDecl::protocol_iterator begin,
+                                      ObjCProtocolDecl::protocol_iterator end) {
+  std::vector<llvm::Constant*> ProtocolRefs;
+
+  // Just return null for empty protocol lists
+  if (begin == end)
+    return llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);
+
+  // FIXME: We shouldn't need to do this lookup here, should we?
+  llvm::SmallString<256> TmpName;
+  Name.toVector(TmpName);
+  llvm::GlobalVariable *GV =
+    CGM.getModule().getGlobalVariable(TmpName.str(), true);
+  if (GV)
+    return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListnfABIPtrTy);
+
+  for (; begin != end; ++begin)
+    ProtocolRefs.push_back(GetProtocolRef(*begin));  // Implemented???
+
+  // This list is null terminated.
+  ProtocolRefs.push_back(llvm::Constant::getNullValue(
+                           ObjCTypes.ProtocolnfABIPtrTy));
+
+  std::vector<llvm::Constant*> Values(2);
+  Values[0] =
+    llvm::ConstantInt::get(ObjCTypes.LongTy, ProtocolRefs.size() - 1);
+  Values[1] =
+    llvm::ConstantArray::get(
+      llvm::ArrayType::get(ObjCTypes.ProtocolnfABIPtrTy,
+                           ProtocolRefs.size()),
+      ProtocolRefs);
+
+  llvm::Constant *Init = llvm::ConstantStruct::get(VMContext, Values, false);
+  GV = new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
+                                llvm::GlobalValue::InternalLinkage,
+                                Init,
+                                Name);
+  GV->setSection("__DATA, __objc_const");
+  GV->setAlignment(
+    CGM.getTargetData().getABITypeAlignment(Init->getType()));
+  CGM.AddUsedGlobal(GV);
+  return llvm::ConstantExpr::getBitCast(GV,
+                                        ObjCTypes.ProtocolListnfABIPtrTy);
+}
+
+/// GetMethodDescriptionConstant - This routine build following meta-data:
+/// struct _objc_method {
+///   SEL _cmd;
+///   char *method_type;
+///   char *_imp;
+/// }
+
+llvm::Constant *
+CGObjCNonFragileABIMac::GetMethodDescriptionConstant(const ObjCMethodDecl *MD) {
+  std::vector<llvm::Constant*> Desc(3);
+  Desc[0] =
+    llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
+                                   ObjCTypes.SelectorPtrTy);
+  Desc[1] = GetMethodVarType(MD);
+  // Protocol methods have no implementation. So, this entry is always NULL.
+  Desc[2] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
+  return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Desc);
+}
+
+/// EmitObjCValueForIvar - Code Gen for nonfragile ivar reference.
+/// This code gen. amounts to generating code for:
+/// @code
+/// (type *)((char *)base + _OBJC_IVAR_$_.ivar;
+/// @encode
+///
+LValue CGObjCNonFragileABIMac::EmitObjCValueForIvar(
+  CodeGen::CodeGenFunction &CGF,
+  QualType ObjectTy,
+  llvm::Value *BaseValue,
+  const ObjCIvarDecl *Ivar,
+  unsigned CVRQualifiers) {
+  const ObjCInterfaceDecl *ID = ObjectTy->getAs<ObjCInterfaceType>()->getDecl();
+  return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
+                                  EmitIvarOffset(CGF, ID, Ivar));
+}
+
+llvm::Value *CGObjCNonFragileABIMac::EmitIvarOffset(
+  CodeGen::CodeGenFunction &CGF,
+  const ObjCInterfaceDecl *Interface,
+  const ObjCIvarDecl *Ivar) {
+  return CGF.Builder.CreateLoad(ObjCIvarOffsetVariable(Interface, Ivar),"ivar");
+}
+
+CodeGen::RValue CGObjCNonFragileABIMac::EmitMessageSend(
+  CodeGen::CodeGenFunction &CGF,
+  QualType ResultType,
+  Selector Sel,
+  llvm::Value *Receiver,
+  QualType Arg0Ty,
+  bool IsSuper,
+  const CallArgList &CallArgs) {
+  // FIXME. Even though IsSuper is passes. This function doese not handle calls
+  // to 'super' receivers.
+  CodeGenTypes &Types = CGM.getTypes();
+  llvm::Value *Arg0 = Receiver;
+  if (!IsSuper)
+    Arg0 = CGF.Builder.CreateBitCast(Arg0, ObjCTypes.ObjectPtrTy, "tmp");
+
+  // Find the message function name.
+  // FIXME. This is too much work to get the ABI-specific result type needed to
+  // find the message name.
+  const CGFunctionInfo &FnInfo
+      = Types.getFunctionInfo(ResultType, CallArgList(),
+                              FunctionType::ExtInfo());
+  llvm::Constant *Fn = 0;
+  std::string Name("\01l_");
+  if (CGM.ReturnTypeUsesSret(FnInfo)) {
+#if 0
+    // unlike what is documented. gcc never generates this API!!
+    if (Receiver->getType() == ObjCTypes.ObjectPtrTy) {
+      Fn = ObjCTypes.getMessageSendIdStretFixupFn();
+      // FIXME. Is there a better way of getting these names.
+      // They are available in RuntimeFunctions vector pair.
+      Name += "objc_msgSendId_stret_fixup";
+    } else
+#endif
+      if (IsSuper) {
+        Fn = ObjCTypes.getMessageSendSuper2StretFixupFn();
+        Name += "objc_msgSendSuper2_stret_fixup";
+      } else {
+        Fn = ObjCTypes.getMessageSendStretFixupFn();
+        Name += "objc_msgSend_stret_fixup";
+      }
+  } else if (!IsSuper && ResultType->isFloatingType()) {
+    if (ResultType->isSpecificBuiltinType(BuiltinType::LongDouble)) {
+      Fn = ObjCTypes.getMessageSendFpretFixupFn();
+      Name += "objc_msgSend_fpret_fixup";
+    } else {
+      Fn = ObjCTypes.getMessageSendFixupFn();
+      Name += "objc_msgSend_fixup";
+    }
+  } else {
+#if 0
+// unlike what is documented. gcc never generates this API!!
+    if (Receiver->getType() == ObjCTypes.ObjectPtrTy) {
+      Fn = ObjCTypes.getMessageSendIdFixupFn();
+      Name += "objc_msgSendId_fixup";
+    } else
+#endif
+      if (IsSuper) {
+        Fn = ObjCTypes.getMessageSendSuper2FixupFn();
+        Name += "objc_msgSendSuper2_fixup";
+      } else {
+        Fn = ObjCTypes.getMessageSendFixupFn();
+        Name += "objc_msgSend_fixup";
+      }
+  }
+  assert(Fn && "CGObjCNonFragileABIMac::EmitMessageSend");
+  Name += '_';
+  std::string SelName(Sel.getAsString());
+  // Replace all ':' in selector name with '_'  ouch!
+  for (unsigned i = 0; i < SelName.size(); i++)
+    if (SelName[i] == ':')
+      SelName[i] = '_';
+  Name += SelName;
+  llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
+  if (!GV) {
+    // Build message ref table entry.
+    std::vector<llvm::Constant*> Values(2);
+    Values[0] = Fn;
+    Values[1] = GetMethodVarName(Sel);
+    llvm::Constant *Init = llvm::ConstantStruct::get(VMContext, Values, false);
+    GV =  new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
+                                   llvm::GlobalValue::WeakAnyLinkage,
+                                   Init,
+                                   Name);
+    GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
+    GV->setAlignment(16);
+    GV->setSection("__DATA, __objc_msgrefs, coalesced");
+  }
+  llvm::Value *Arg1 = CGF.Builder.CreateBitCast(GV, ObjCTypes.MessageRefPtrTy);
+
+  CallArgList ActualArgs;
+  ActualArgs.push_back(std::make_pair(RValue::get(Arg0), Arg0Ty));
+  ActualArgs.push_back(std::make_pair(RValue::get(Arg1),
+                                      ObjCTypes.MessageRefCPtrTy));
+  ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end());
+  const CGFunctionInfo &FnInfo1 = Types.getFunctionInfo(ResultType, ActualArgs,
+                                                      FunctionType::ExtInfo());
+  llvm::Value *Callee = CGF.Builder.CreateStructGEP(Arg1, 0);
+  Callee = CGF.Builder.CreateLoad(Callee);
+  const llvm::FunctionType *FTy = Types.GetFunctionType(FnInfo1, true);
+  Callee = CGF.Builder.CreateBitCast(Callee,
+                                     llvm::PointerType::getUnqual(FTy));
+  return CGF.EmitCall(FnInfo1, Callee, ReturnValueSlot(), ActualArgs);
+}
+
+/// Generate code for a message send expression in the nonfragile abi.
+CodeGen::RValue
+CGObjCNonFragileABIMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
+                                            QualType ResultType,
+                                            Selector Sel,
+                                            llvm::Value *Receiver,
+                                            bool IsClassMessage,
+                                            const CallArgList &CallArgs,
+                                            const ObjCMethodDecl *Method) {
+  return LegacyDispatchedSelector(Sel)
+    ? EmitLegacyMessageSend(CGF, ResultType, EmitSelector(CGF.Builder, Sel),
+                            Receiver, CGF.getContext().getObjCIdType(),
+                            false, CallArgs, Method, ObjCTypes)
+    : EmitMessageSend(CGF, ResultType, Sel,
+                      Receiver, CGF.getContext().getObjCIdType(),
+                      false, CallArgs);
+}
+
+llvm::GlobalVariable *
+CGObjCNonFragileABIMac::GetClassGlobal(const std::string &Name) {
+  llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
+
+  if (!GV) {
+    GV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABITy,
+                                  false, llvm::GlobalValue::ExternalLinkage,
+                                  0, Name);
+  }
+
+  return GV;
+}
+
+llvm::Value *CGObjCNonFragileABIMac::EmitClassRef(CGBuilderTy &Builder,
+                                                  const ObjCInterfaceDecl *ID) {
+  llvm::GlobalVariable *&Entry = ClassReferences[ID->getIdentifier()];
+
+  if (!Entry) {
+    std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString());
+    llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName);
+    Entry =
+      new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy,
+                               false, llvm::GlobalValue::InternalLinkage,
+                               ClassGV,
+                               "\01L_OBJC_CLASSLIST_REFERENCES_$_");
+    Entry->setAlignment(
+      CGM.getTargetData().getABITypeAlignment(
+        ObjCTypes.ClassnfABIPtrTy));
+    Entry->setSection("__DATA, __objc_classrefs, regular, no_dead_strip");
+    CGM.AddUsedGlobal(Entry);
+  }
+
+  return Builder.CreateLoad(Entry, "tmp");
+}
+
+llvm::Value *
+CGObjCNonFragileABIMac::EmitSuperClassRef(CGBuilderTy &Builder,
+                                          const ObjCInterfaceDecl *ID) {
+  llvm::GlobalVariable *&Entry = SuperClassReferences[ID->getIdentifier()];
+
+  if (!Entry) {
+    std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString());
+    llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName);
+    Entry =
+      new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy,
+                               false, llvm::GlobalValue::InternalLinkage,
+                               ClassGV,
+                               "\01L_OBJC_CLASSLIST_SUP_REFS_$_");
+    Entry->setAlignment(
+      CGM.getTargetData().getABITypeAlignment(
+        ObjCTypes.ClassnfABIPtrTy));
+    Entry->setSection("__DATA, __objc_superrefs, regular, no_dead_strip");
+    CGM.AddUsedGlobal(Entry);
+  }
+
+  return Builder.CreateLoad(Entry, "tmp");
+}
+
+/// EmitMetaClassRef - Return a Value * of the address of _class_t
+/// meta-data
+///
+llvm::Value *CGObjCNonFragileABIMac::EmitMetaClassRef(CGBuilderTy &Builder,
+                                                      const ObjCInterfaceDecl *ID) {
+  llvm::GlobalVariable * &Entry = MetaClassReferences[ID->getIdentifier()];
+  if (Entry)
+    return Builder.CreateLoad(Entry, "tmp");
+
+  std::string MetaClassName(getMetaclassSymbolPrefix() + ID->getNameAsString());
+  llvm::GlobalVariable *MetaClassGV = GetClassGlobal(MetaClassName);
+  Entry =
+    new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy, false,
+                             llvm::GlobalValue::InternalLinkage,
+                             MetaClassGV,
+                             "\01L_OBJC_CLASSLIST_SUP_REFS_$_");
+  Entry->setAlignment(
+    CGM.getTargetData().getABITypeAlignment(
+      ObjCTypes.ClassnfABIPtrTy));
+
+  Entry->setSection("__DATA, __objc_superrefs, regular, no_dead_strip");
+  CGM.AddUsedGlobal(Entry);
+
+  return Builder.CreateLoad(Entry, "tmp");
+}
+
+/// GetClass - Return a reference to the class for the given interface
+/// decl.
+llvm::Value *CGObjCNonFragileABIMac::GetClass(CGBuilderTy &Builder,
+                                              const ObjCInterfaceDecl *ID) {
+  if (ID->hasAttr<WeakImportAttr>()) {
+    std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString());
+    llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName);
+    ClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
+  }
+  
+  return EmitClassRef(Builder, ID);
+}
+
+/// Generates a message send where the super is the receiver.  This is
+/// a message send to self with special delivery semantics indicating
+/// which class's method should be called.
+CodeGen::RValue
+CGObjCNonFragileABIMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
+                                                 QualType ResultType,
+                                                 Selector Sel,
+                                                 const ObjCInterfaceDecl *Class,
+                                                 bool isCategoryImpl,
+                                                 llvm::Value *Receiver,
+                                                 bool IsClassMessage,
+                                                 const CodeGen::CallArgList &CallArgs,
+                                                 const ObjCMethodDecl *Method) {
+  // ...
+  // Create and init a super structure; this is a (receiver, class)
+  // pair we will pass to objc_msgSendSuper.
+  llvm::Value *ObjCSuper =
+    CGF.Builder.CreateAlloca(ObjCTypes.SuperTy, 0, "objc_super");
+
+  llvm::Value *ReceiverAsObject =
+    CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);
+  CGF.Builder.CreateStore(ReceiverAsObject,
+                          CGF.Builder.CreateStructGEP(ObjCSuper, 0));
+
+  // If this is a class message the metaclass is passed as the target.
+  llvm::Value *Target;
+  if (IsClassMessage) {
+    if (isCategoryImpl) {
+      // Message sent to "super' in a class method defined in
+      // a category implementation.
+      Target = EmitClassRef(CGF.Builder, Class);
+      Target = CGF.Builder.CreateStructGEP(Target, 0);
+      Target = CGF.Builder.CreateLoad(Target);
+    } else
+      Target = EmitMetaClassRef(CGF.Builder, Class);
+  } else
+    Target = EmitSuperClassRef(CGF.Builder, Class);
+
+  // FIXME: We shouldn't need to do this cast, rectify the ASTContext and
+  // ObjCTypes types.
+  const llvm::Type *ClassTy =
+    CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType());
+  Target = CGF.Builder.CreateBitCast(Target, ClassTy);
+  CGF.Builder.CreateStore(Target,
+                          CGF.Builder.CreateStructGEP(ObjCSuper, 1));
+
+  return (LegacyDispatchedSelector(Sel))
+    ? EmitLegacyMessageSend(CGF, ResultType,EmitSelector(CGF.Builder, Sel),
+                            ObjCSuper, ObjCTypes.SuperPtrCTy,
+                            true, CallArgs, Method, ObjCTypes)
+    : EmitMessageSend(CGF, ResultType, Sel,
+                      ObjCSuper, ObjCTypes.SuperPtrCTy,
+                      true, CallArgs);
+}
+
+llvm::Value *CGObjCNonFragileABIMac::EmitSelector(CGBuilderTy &Builder,
+                                                  Selector Sel) {
+  llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
+
+  if (!Entry) {
+    llvm::Constant *Casted =
+      llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
+                                     ObjCTypes.SelectorPtrTy);
+    Entry =
+      new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.SelectorPtrTy, false,
+                               llvm::GlobalValue::InternalLinkage,
+                               Casted, "\01L_OBJC_SELECTOR_REFERENCES_");
+    Entry->setSection("__DATA, __objc_selrefs, literal_pointers, no_dead_strip");
+    CGM.AddUsedGlobal(Entry);
+  }
+
+  return Builder.CreateLoad(Entry, "tmp");
+}
+/// EmitObjCIvarAssign - Code gen for assigning to a __strong object.
+/// objc_assign_ivar (id src, id *dst, ptrdiff_t)
+///
+void CGObjCNonFragileABIMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
+                                                llvm::Value *src,
+                                                llvm::Value *dst,
+                                                llvm::Value *ivarOffset) {
+  const llvm::Type * SrcTy = src->getType();
+  if (!isa<llvm::PointerType>(SrcTy)) {
+    unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
+    assert(Size <= 8 && "does not support size > 8");
+    src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
+           : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
+    src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
+  }
+  src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
+  dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
+  CGF.Builder.CreateCall3(ObjCTypes.getGcAssignIvarFn(),
+                          src, dst, ivarOffset);
+  return;
+}
+
+/// EmitObjCStrongCastAssign - Code gen for assigning to a __strong cast object.
+/// objc_assign_strongCast (id src, id *dst)
+///
+void CGObjCNonFragileABIMac::EmitObjCStrongCastAssign(
+  CodeGen::CodeGenFunction &CGF,
+  llvm::Value *src, llvm::Value *dst) {
+  const llvm::Type * SrcTy = src->getType();
+  if (!isa<llvm::PointerType>(SrcTy)) {
+    unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
+    assert(Size <= 8 && "does not support size > 8");
+    src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
+           : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
+    src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
+  }
+  src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
+  dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
+  CGF.Builder.CreateCall2(ObjCTypes.getGcAssignStrongCastFn(),
+                          src, dst, "weakassign");
+  return;
+}
+
+void CGObjCNonFragileABIMac::EmitGCMemmoveCollectable(
+  CodeGen::CodeGenFunction &CGF,
+  llvm::Value *DestPtr,
+  llvm::Value *SrcPtr,
+  QualType Ty) {
+  // Get size info for this aggregate.
+  std::pair<uint64_t, unsigned> TypeInfo = CGM.getContext().getTypeInfo(Ty);
+  unsigned long size = TypeInfo.first/8;
+  SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy);
+  DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy);
+  llvm::Value *N = llvm::ConstantInt::get(ObjCTypes.LongTy, size);
+  CGF.Builder.CreateCall3(ObjCTypes.GcMemmoveCollectableFn(),
+                          DestPtr, SrcPtr, N);
+  return;
+}
+
+/// EmitObjCWeakRead - Code gen for loading value of a __weak
+/// object: objc_read_weak (id *src)
+///
+llvm::Value * CGObjCNonFragileABIMac::EmitObjCWeakRead(
+  CodeGen::CodeGenFunction &CGF,
+  llvm::Value *AddrWeakObj) {
+  const llvm::Type* DestTy =
+    cast<llvm::PointerType>(AddrWeakObj->getType())->getElementType();
+  AddrWeakObj = CGF.Builder.CreateBitCast(AddrWeakObj, ObjCTypes.PtrObjectPtrTy);
+  llvm::Value *read_weak = CGF.Builder.CreateCall(ObjCTypes.getGcReadWeakFn(),
+                                                  AddrWeakObj, "weakread");
+  read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy);
+  return read_weak;
+}
+
+/// EmitObjCWeakAssign - Code gen for assigning to a __weak object.
+/// objc_assign_weak (id src, id *dst)
+///
+void CGObjCNonFragileABIMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
+                                                llvm::Value *src, llvm::Value *dst) {
+  const llvm::Type * SrcTy = src->getType();
+  if (!isa<llvm::PointerType>(SrcTy)) {
+    unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
+    assert(Size <= 8 && "does not support size > 8");
+    src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
+           : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
+    src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
+  }
+  src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
+  dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
+  CGF.Builder.CreateCall2(ObjCTypes.getGcAssignWeakFn(),
+                          src, dst, "weakassign");
+  return;
+}
+
+/// EmitObjCGlobalAssign - Code gen for assigning to a __strong object.
+/// objc_assign_global (id src, id *dst)
+///
+void CGObjCNonFragileABIMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
+                                                  llvm::Value *src, llvm::Value *dst) {
+  const llvm::Type * SrcTy = src->getType();
+  if (!isa<llvm::PointerType>(SrcTy)) {
+    unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
+    assert(Size <= 8 && "does not support size > 8");
+    src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
+           : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
+    src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
+  }
+  src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
+  dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
+  CGF.Builder.CreateCall2(ObjCTypes.getGcAssignGlobalFn(),
+                          src, dst, "globalassign");
+  return;
+}
+
+void
+CGObjCNonFragileABIMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
+                                                  const Stmt &S) {
+  bool isTry = isa<ObjCAtTryStmt>(S);
+  llvm::BasicBlock *TryBlock = CGF.createBasicBlock("try");
+  llvm::BasicBlock *PrevLandingPad = CGF.getInvokeDest();
+  llvm::BasicBlock *TryHandler = CGF.createBasicBlock("try.handler");
+  llvm::BasicBlock *FinallyBlock = CGF.createBasicBlock("finally");
+  llvm::BasicBlock *FinallyRethrow = CGF.createBasicBlock("finally.throw");
+  llvm::BasicBlock *FinallyEnd = CGF.createBasicBlock("finally.end");
+
+  // For @synchronized, call objc_sync_enter(sync.expr). The
+  // evaluation of the expression must occur before we enter the
+  // @synchronized. We can safely avoid a temp here because jumps into
+  // @synchronized are illegal & this will dominate uses.
+  llvm::Value *SyncArg = 0;
+  if (!isTry) {
+    SyncArg =
+      CGF.EmitScalarExpr(cast<ObjCAtSynchronizedStmt>(S).getSynchExpr());
+    SyncArg = CGF.Builder.CreateBitCast(SyncArg, ObjCTypes.ObjectPtrTy);
+    CGF.Builder.CreateCall(ObjCTypes.getSyncEnterFn(), SyncArg);
+  }
+
+  // Push an EH context entry, used for handling rethrows and jumps
+  // through finally.
+  CGF.PushCleanupBlock(FinallyBlock);
+
+  CGF.setInvokeDest(TryHandler);
+
+  CGF.EmitBlock(TryBlock);
+  CGF.EmitStmt(isTry ? cast<ObjCAtTryStmt>(S).getTryBody()
+               : cast<ObjCAtSynchronizedStmt>(S).getSynchBody());
+  CGF.EmitBranchThroughCleanup(FinallyEnd);
+
+  // Emit the exception handler.
+
+  CGF.EmitBlock(TryHandler);
+
+  llvm::Value *llvm_eh_exception =
+    CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_exception);
+  llvm::Value *llvm_eh_selector =
+    CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_selector);
+  llvm::Value *llvm_eh_typeid_for =
+    CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_typeid_for);
+  llvm::Value *Exc = CGF.Builder.CreateCall(llvm_eh_exception, "exc");
+  llvm::Value *RethrowPtr = CGF.CreateTempAlloca(Exc->getType(), "_rethrow");
+
+  llvm::SmallVector<llvm::Value*, 8> SelectorArgs;
+  SelectorArgs.push_back(Exc);
+  SelectorArgs.push_back(ObjCTypes.getEHPersonalityPtr());
+
+  // Construct the lists of (type, catch body) to handle.
+  llvm::SmallVector<std::pair<const VarDecl*, const Stmt*>, 8> Handlers;
+  bool HasCatchAll = false;
+  if (isTry) {
+    const ObjCAtTryStmt &AtTry = cast<ObjCAtTryStmt>(S);
+    for (unsigned I = 0, N = AtTry.getNumCatchStmts(); I != N; ++I) {
+      const ObjCAtCatchStmt *CatchStmt = AtTry.getCatchStmt(I);
+      const VarDecl *CatchDecl = CatchStmt->getCatchParamDecl();
+      Handlers.push_back(std::make_pair(CatchDecl, CatchStmt->getCatchBody()));
+
+      // catch(...) always matches.
+      if (!CatchDecl) {
+        // Use i8* null here to signal this is a catch all, not a cleanup.
+        llvm::Value *Null = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
+        SelectorArgs.push_back(Null);
+        HasCatchAll = true;
+        break;
+      }
+
+      if (CatchDecl->getType()->isObjCIdType() ||
+          CatchDecl->getType()->isObjCQualifiedIdType()) {
+        llvm::Value *IDEHType =
+          CGM.getModule().getGlobalVariable("OBJC_EHTYPE_id");
+        if (!IDEHType)
+          IDEHType =
+            new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy,
+                                     false,
+                                     llvm::GlobalValue::ExternalLinkage,
+                                     0, "OBJC_EHTYPE_id");
+        SelectorArgs.push_back(IDEHType);
+      } else {
+        // All other types should be Objective-C interface pointer types.
+        const ObjCObjectPointerType *PT =
+          CatchDecl->getType()->getAs<ObjCObjectPointerType>();
+        assert(PT && "Invalid @catch type.");
+        const ObjCInterfaceType *IT = PT->getInterfaceType();
+        assert(IT && "Invalid @catch type.");
+        llvm::Value *EHType = GetInterfaceEHType(IT->getDecl(), false);
+        SelectorArgs.push_back(EHType);
+      }
+    }
+  }
+
+  // We use a cleanup unless there was already a catch all.
+  if (!HasCatchAll) {
+    // Even though this is a cleanup, treat it as a catch all to avoid the C++
+    // personality behavior of terminating the process if only cleanups are
+    // found in the exception handling stack.
+    SelectorArgs.push_back(llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy));
+    Handlers.push_back(std::make_pair((const ParmVarDecl*) 0, (const Stmt*) 0));
+  }
+
+  llvm::Value *Selector =
+    CGF.Builder.CreateCall(llvm_eh_selector,
+                           SelectorArgs.begin(), SelectorArgs.end(),
+                           "selector");
+  for (unsigned i = 0, e = Handlers.size(); i != e; ++i) {
+    const VarDecl *CatchParam = Handlers[i].first;
+    const Stmt *CatchBody = Handlers[i].second;
+
+    llvm::BasicBlock *Next = 0;
+
+    // The last handler always matches.
+    if (i + 1 != e) {
+      assert(CatchParam && "Only last handler can be a catch all.");
+
+      llvm::BasicBlock *Match = CGF.createBasicBlock("match");
+      Next = CGF.createBasicBlock("catch.next");
+      llvm::Value *Id =
+        CGF.Builder.CreateCall(llvm_eh_typeid_for,
+                               CGF.Builder.CreateBitCast(SelectorArgs[i+2],
+                                                         ObjCTypes.Int8PtrTy));
+      CGF.Builder.CreateCondBr(CGF.Builder.CreateICmpEQ(Selector, Id),
+                               Match, Next);
+
+      CGF.EmitBlock(Match);
+    }
+
+    if (CatchBody) {
+      llvm::BasicBlock *MatchEnd = CGF.createBasicBlock("match.end");
+
+      // Cleanups must call objc_end_catch.
+      CGF.PushCleanupBlock(MatchEnd);
+
+      llvm::Value *ExcObject =
+        CGF.Builder.CreateCall(ObjCTypes.getObjCBeginCatchFn(), Exc);
+
+      // Bind the catch parameter if it exists.
+      if (CatchParam) {
+        ExcObject =
+          CGF.Builder.CreateBitCast(ExcObject,
+                                    CGF.ConvertType(CatchParam->getType()));
+        // CatchParam is a ParmVarDecl because of the grammar
+        // construction used to handle this, but for codegen purposes
+        // we treat this as a local decl.
+        CGF.EmitLocalBlockVarDecl(*CatchParam);
+        CGF.Builder.CreateStore(ExcObject, CGF.GetAddrOfLocalVar(CatchParam));
+      }
+
+      // Exceptions inside the catch block must be rethrown. We set a special
+      // purpose invoke destination for this which just collects the thrown
+      // exception and overwrites the object in RethrowPtr, branches through the
+      // match.end to make sure we call objc_end_catch, before branching to the
+      // rethrow handler.
+      llvm::BasicBlock *MatchHandler = CGF.createBasicBlock("match.handler");
+      CGF.setInvokeDest(MatchHandler);
+      CGF.ObjCEHValueStack.push_back(ExcObject);
+      CGF.EmitStmt(CatchBody);
+      CGF.ObjCEHValueStack.pop_back();
+      CGF.setInvokeDest(0);
+
+      CGF.EmitBranchThroughCleanup(FinallyEnd);
+
+      // Don't emit the extra match handler if there we no unprotected calls in
+      // the catch block.
+      if (MatchHandler->use_empty()) {
+        delete MatchHandler;
+      } else {
+        CGF.EmitBlock(MatchHandler);
+        llvm::Value *Exc = CGF.Builder.CreateCall(llvm_eh_exception, "exc");
+        // We are required to emit this call to satisfy LLVM, even
+        // though we don't use the result.
+        CGF.Builder.CreateCall3(llvm_eh_selector,
+                                Exc, ObjCTypes.getEHPersonalityPtr(),
+                                llvm::ConstantInt::get(
+                                  llvm::Type::getInt32Ty(VMContext), 0),
+                               "unused_eh_selector");
+        CGF.Builder.CreateStore(Exc, RethrowPtr);
+        CGF.EmitBranchThroughCleanup(FinallyRethrow);
+      }
+
+      CodeGenFunction::CleanupBlockInfo Info = CGF.PopCleanupBlock();
+
+      CGF.EmitBlock(MatchEnd);
+
+      // Unfortunately, we also have to generate another EH frame here
+      // in case this throws.
+      llvm::BasicBlock *MatchEndHandler =
+        CGF.createBasicBlock("match.end.handler");
+      llvm::BasicBlock *Cont = CGF.createBasicBlock("invoke.cont");
+      CGF.Builder.CreateInvoke(ObjCTypes.getObjCEndCatchFn(),
+                               Cont, MatchEndHandler);
+
+      CGF.EmitBlock(Cont);
+      if (Info.SwitchBlock)
+        CGF.EmitBlock(Info.SwitchBlock);
+      if (Info.EndBlock)
+        CGF.EmitBlock(Info.EndBlock);
+
+      CGF.EmitBlock(MatchEndHandler);
+      llvm::Value *Exc = CGF.Builder.CreateCall(llvm_eh_exception, "exc");
+      // We are required to emit this call to satisfy LLVM, even
+      // though we don't use the result.
+      CGF.Builder.CreateCall3(llvm_eh_selector,
+                              Exc, ObjCTypes.getEHPersonalityPtr(),
+                              llvm::ConstantInt::get(
+                                llvm::Type::getInt32Ty(VMContext), 0),
+                              "unused_eh_selector");
+      CGF.Builder.CreateStore(Exc, RethrowPtr);
+      CGF.EmitBranchThroughCleanup(FinallyRethrow);
+
+      if (Next)
+        CGF.EmitBlock(Next);
+    } else {
+      assert(!Next && "catchup should be last handler.");
+
+      CGF.Builder.CreateStore(Exc, RethrowPtr);
+      CGF.EmitBranchThroughCleanup(FinallyRethrow);
+    }
+  }
+
+  // Pop the cleanup entry, the @finally is outside this cleanup
+  // scope.
+  CodeGenFunction::CleanupBlockInfo Info = CGF.PopCleanupBlock();
+  CGF.setInvokeDest(PrevLandingPad);
+
+  CGF.EmitBlock(FinallyBlock);
+
+  if (isTry) {
+    if (const ObjCAtFinallyStmt* FinallyStmt =
+        cast<ObjCAtTryStmt>(S).getFinallyStmt())
+      CGF.EmitStmt(FinallyStmt->getFinallyBody());
+  } else {
+    // Emit 'objc_sync_exit(expr)' as finally's sole statement for
+    // @synchronized.
+    CGF.Builder.CreateCall(ObjCTypes.getSyncExitFn(), SyncArg);
+  }
+
+  if (Info.SwitchBlock)
+    CGF.EmitBlock(Info.SwitchBlock);
+  if (Info.EndBlock)
+    CGF.EmitBlock(Info.EndBlock);
+
+  // Branch around the rethrow code.
+  CGF.EmitBranch(FinallyEnd);
+
+  // Generate the rethrow code, taking care to use an invoke if we are in a
+  // nested exception scope.
+  CGF.EmitBlock(FinallyRethrow);
+  if (PrevLandingPad) {
+    llvm::BasicBlock *Cont = CGF.createBasicBlock("invoke.cont");
+    CGF.Builder.CreateInvoke(ObjCTypes.getUnwindResumeOrRethrowFn(),
+                             Cont, PrevLandingPad,
+                             CGF.Builder.CreateLoad(RethrowPtr));
+    CGF.EmitBlock(Cont);
+  } else {
+    CGF.Builder.CreateCall(ObjCTypes.getUnwindResumeOrRethrowFn(),
+                           CGF.Builder.CreateLoad(RethrowPtr));
+  }
+  CGF.Builder.CreateUnreachable();
+
+  CGF.EmitBlock(FinallyEnd);
+}
+
+/// EmitThrowStmt - Generate code for a throw statement.
+void CGObjCNonFragileABIMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
+                                           const ObjCAtThrowStmt &S) {
+  llvm::Value *Exception;
+  if (const Expr *ThrowExpr = S.getThrowExpr()) {
+    Exception = CGF.EmitScalarExpr(ThrowExpr);
+  } else {
+    assert((!CGF.ObjCEHValueStack.empty() && CGF.ObjCEHValueStack.back()) &&
+           "Unexpected rethrow outside @catch block.");
+    Exception = CGF.ObjCEHValueStack.back();
+  }
+
+  llvm::Value *ExceptionAsObject =
+    CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy, "tmp");
+  llvm::BasicBlock *InvokeDest = CGF.getInvokeDest();
+  if (InvokeDest) {
+    llvm::BasicBlock *Cont = CGF.createBasicBlock("invoke.cont");
+    CGF.Builder.CreateInvoke(ObjCTypes.getExceptionThrowFn(),
+                             Cont, InvokeDest,
+                             &ExceptionAsObject, &ExceptionAsObject + 1);
+    CGF.EmitBlock(Cont);
+  } else
+    CGF.Builder.CreateCall(ObjCTypes.getExceptionThrowFn(), ExceptionAsObject);
+  CGF.Builder.CreateUnreachable();
+
+  // Clear the insertion point to indicate we are in unreachable code.
+  CGF.Builder.ClearInsertionPoint();
+}
+
+llvm::Value *
+CGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceDecl *ID,
+                                           bool ForDefinition) {
+  llvm::GlobalVariable * &Entry = EHTypeReferences[ID->getIdentifier()];
+
+  // If we don't need a definition, return the entry if found or check
+  // if we use an external reference.
+  if (!ForDefinition) {
+    if (Entry)
+      return Entry;
+
+    // If this type (or a super class) has the __objc_exception__
+    // attribute, emit an external reference.
+    if (hasObjCExceptionAttribute(CGM.getContext(), ID))
+      return Entry =
+        new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false,
+                                 llvm::GlobalValue::ExternalLinkage,
+                                 0,
+                                 ("OBJC_EHTYPE_$_" +
+                                  ID->getIdentifier()->getName()));
+  }
+
+  // Otherwise we need to either make a new entry or fill in the
+  // initializer.
+  assert((!Entry || !Entry->hasInitializer()) && "Duplicate EHType definition");
+  std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString());
+  std::string VTableName = "objc_ehtype_vtable";
+  llvm::GlobalVariable *VTableGV =
+    CGM.getModule().getGlobalVariable(VTableName);
+  if (!VTableGV)
+    VTableGV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.Int8PtrTy,
+                                        false,
+                                        llvm::GlobalValue::ExternalLinkage,
+                                        0, VTableName);
+
+  llvm::Value *VTableIdx = llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 2);
+
+  std::vector<llvm::Constant*> Values(3);
+  Values[0] = llvm::ConstantExpr::getGetElementPtr(VTableGV, &VTableIdx, 1);
+  Values[1] = GetClassName(ID->getIdentifier());
+  Values[2] = GetClassGlobal(ClassName);
+  llvm::Constant *Init =
+    llvm::ConstantStruct::get(ObjCTypes.EHTypeTy, Values);
+
+  if (Entry) {
+    Entry->setInitializer(Init);
+  } else {
+    Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false,
+                                     llvm::GlobalValue::WeakAnyLinkage,
+                                     Init,
+                                     ("OBJC_EHTYPE_$_" +
+                                      ID->getIdentifier()->getName()));
+  }
+
+  if (CGM.getLangOptions().getVisibilityMode() == LangOptions::Hidden)
+    Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
+  Entry->setAlignment(CGM.getTargetData().getABITypeAlignment(
+      ObjCTypes.EHTypeTy));
+
+  if (ForDefinition) {
+    Entry->setSection("__DATA,__objc_const");
+    Entry->setLinkage(llvm::GlobalValue::ExternalLinkage);
+  } else {
+    Entry->setSection("__DATA,__datacoal_nt,coalesced");
+  }
+
+  return Entry;
+}
+
+/* *** */
+
+CodeGen::CGObjCRuntime *
+CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) {
+  return new CGObjCMac(CGM);
+}
+
+CodeGen::CGObjCRuntime *
+CodeGen::CreateMacNonFragileABIObjCRuntime(CodeGen::CodeGenModule &CGM) {
+  return new CGObjCNonFragileABIMac(CGM);
+}
diff --git a/lib/CodeGen/CGObjCRuntime.h b/lib/CodeGen/CGObjCRuntime.h
new file mode 100644
index 0000000..64e6808
--- /dev/null
+++ b/lib/CodeGen/CGObjCRuntime.h
@@ -0,0 +1,219 @@
+//===----- CGObjCRuntime.h - Interface to ObjC Runtimes ---------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This provides an abstract class for Objective-C code generation.  Concrete
+// subclasses of this implement code generation for specific Objective-C
+// runtime libraries.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_CODEGEN_OBCJRUNTIME_H
+#define CLANG_CODEGEN_OBCJRUNTIME_H
+#include "clang/Basic/IdentifierTable.h" // Selector
+#include "clang/AST/DeclObjC.h"
+#include <string>
+
+#include "CGBuilder.h"
+#include "CGCall.h"
+#include "CGValue.h"
+
+namespace llvm {
+  class Constant;
+  class Function;
+  class Module;
+  class StructLayout;
+  class StructType;
+  class Type;
+  class Value;
+}
+
+namespace clang {
+namespace CodeGen {
+  class CodeGenFunction;
+}
+
+  class FieldDecl;
+  class ObjCAtTryStmt;
+  class ObjCAtThrowStmt;
+  class ObjCAtSynchronizedStmt;
+  class ObjCContainerDecl;
+  class ObjCCategoryImplDecl;
+  class ObjCImplementationDecl;
+  class ObjCInterfaceDecl;
+  class ObjCMessageExpr;
+  class ObjCMethodDecl;
+  class ObjCProtocolDecl;
+  class Selector;
+  class ObjCIvarDecl;
+  class ObjCStringLiteral;
+
+namespace CodeGen {
+  class CodeGenModule;
+
+// FIXME: Several methods should be pure virtual but aren't to avoid the
+// partially-implemented subclass breaking.
+
+/// Implements runtime-specific code generation functions.
+class CGObjCRuntime {
+protected:
+  // Utility functions for unified ivar access. These need to
+  // eventually be folded into other places (the structure layout
+  // code).
+
+  /// Compute an offset to the given ivar, suitable for passing to
+  /// EmitValueForIvarAtOffset.  Note that the correct handling of
+  /// bit-fields is carefully coordinated by these two, use caution!
+  ///
+  /// The latter overload is suitable for computing the offset of a
+  /// sythesized ivar.
+  uint64_t ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM,
+                                 const ObjCInterfaceDecl *OID,
+                                 const ObjCIvarDecl *Ivar);
+  uint64_t ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM,
+                                 const ObjCImplementationDecl *OID,
+                                 const ObjCIvarDecl *Ivar);
+
+  LValue EmitValueForIvarAtOffset(CodeGen::CodeGenFunction &CGF,
+                                  const ObjCInterfaceDecl *OID,
+                                  llvm::Value *BaseValue,
+                                  const ObjCIvarDecl *Ivar,
+                                  unsigned CVRQualifiers,
+                                  llvm::Value *Offset);
+
+public:
+  virtual ~CGObjCRuntime();
+
+  /// Generate the function required to register all Objective-C components in
+  /// this compilation unit with the runtime library.
+  virtual llvm::Function *ModuleInitFunction() = 0;
+
+  /// Get a selector for the specified name and type values. The
+  /// return value should have the LLVM type for pointer-to
+  /// ASTContext::getObjCSelType().
+  virtual llvm::Value *GetSelector(CGBuilderTy &Builder,
+                                   Selector Sel) = 0;
+
+  /// Get a typed selector.
+  virtual llvm::Value *GetSelector(CGBuilderTy &Builder,
+                                   const ObjCMethodDecl *Method) = 0;
+
+  /// Generate a constant string object.
+  virtual llvm::Constant *GenerateConstantString(const StringLiteral *) = 0;
+
+  /// Generate a category.  A category contains a list of methods (and
+  /// accompanying metadata) and a list of protocols.
+  virtual void GenerateCategory(const ObjCCategoryImplDecl *OCD) = 0;
+
+  /// Generate a class stucture for this class.
+  virtual void GenerateClass(const ObjCImplementationDecl *OID) = 0;
+
+  /// Generate an Objective-C message send operation.
+  ///
+  /// \param Method - The method being called, this may be null if synthesizing
+  /// a property setter or getter.
+  virtual CodeGen::RValue
+  GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
+                      QualType ResultType,
+                      Selector Sel,
+                      llvm::Value *Receiver,
+                      bool IsClassMessage,
+                      const CallArgList &CallArgs,
+                      const ObjCMethodDecl *Method = 0) = 0;
+
+  /// Generate an Objective-C message send operation to the super
+  /// class initiated in a method for Class and with the given Self
+  /// object.
+  ///
+  /// \param Method - The method being called, this may be null if synthesizing
+  /// a property setter or getter.
+  virtual CodeGen::RValue
+  GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
+                           QualType ResultType,
+                           Selector Sel,
+                           const ObjCInterfaceDecl *Class,
+                           bool isCategoryImpl,
+                           llvm::Value *Self,
+                           bool IsClassMessage,
+                           const CallArgList &CallArgs,
+                           const ObjCMethodDecl *Method = 0) = 0;
+
+  /// Emit the code to return the named protocol as an object, as in a
+  /// @protocol expression.
+  virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder,
+                                           const ObjCProtocolDecl *OPD) = 0;
+
+  /// Generate the named protocol.  Protocols contain method metadata but no
+  /// implementations.
+  virtual void GenerateProtocol(const ObjCProtocolDecl *OPD) = 0;
+
+  /// Generate a function preamble for a method with the specified
+  /// types.
+
+  // FIXME: Current this just generates the Function definition, but really this
+  // should also be generating the loads of the parameters, as the runtime
+  // should have full control over how parameters are passed.
+  virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD,
+                                         const ObjCContainerDecl *CD) = 0;
+
+  /// Return the runtime function for getting properties.
+  virtual llvm::Constant *GetPropertyGetFunction() = 0;
+
+  /// Return the runtime function for setting properties.
+  virtual llvm::Constant *GetPropertySetFunction() = 0;
+
+  // API for atomic copying of qualified aggregates in setter/getter.
+  virtual llvm::Constant *GetCopyStructFunction() = 0;
+  
+  /// GetClass - Return a reference to the class for the given
+  /// interface decl.
+  virtual llvm::Value *GetClass(CGBuilderTy &Builder,
+                                const ObjCInterfaceDecl *OID) = 0;
+
+  /// EnumerationMutationFunction - Return the function that's called by the
+  /// compiler when a mutation is detected during foreach iteration.
+  virtual llvm::Constant *EnumerationMutationFunction() = 0;
+
+  virtual void EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
+                                         const Stmt &S) = 0;
+  virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
+                             const ObjCAtThrowStmt &S) = 0;
+  virtual llvm::Value *EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
+                                        llvm::Value *AddrWeakObj) = 0;
+  virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
+                                  llvm::Value *src, llvm::Value *dest) = 0;
+  virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
+                                    llvm::Value *src, llvm::Value *dest) = 0;
+  virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
+                                  llvm::Value *src, llvm::Value *dest,
+                                  llvm::Value *ivarOffset) = 0;
+  virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
+                                        llvm::Value *src, llvm::Value *dest) = 0;
+
+  virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
+                                      QualType ObjectTy,
+                                      llvm::Value *BaseValue,
+                                      const ObjCIvarDecl *Ivar,
+                                      unsigned CVRQualifiers) = 0;
+  virtual llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
+                                      const ObjCInterfaceDecl *Interface,
+                                      const ObjCIvarDecl *Ivar) = 0;
+  virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
+                                        llvm::Value *DestPtr,
+                                        llvm::Value *SrcPtr,
+                                        QualType Ty) = 0;
+};
+
+/// Creates an instance of an Objective-C runtime class.
+//TODO: This should include some way of selecting which runtime to target.
+CGObjCRuntime *CreateGNUObjCRuntime(CodeGenModule &CGM);
+CGObjCRuntime *CreateMacObjCRuntime(CodeGenModule &CGM);
+CGObjCRuntime *CreateMacNonFragileABIObjCRuntime(CodeGenModule &CGM);
+}
+}
+#endif
diff --git a/lib/CodeGen/CGRTTI.cpp b/lib/CodeGen/CGRTTI.cpp
new file mode 100644
index 0000000..5e3801d
--- /dev/null
+++ b/lib/CodeGen/CGRTTI.cpp
@@ -0,0 +1,815 @@
+//===--- CGCXXRTTI.cpp - Emit LLVM Code for C++ RTTI descriptors ----------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This contains code dealing with C++ code generation of RTTI descriptors.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/Type.h"
+#include "clang/AST/RecordLayout.h"
+#include "CodeGenModule.h"
+using namespace clang;
+using namespace CodeGen;
+
+namespace {
+class RTTIBuilder {
+  CodeGenModule &CGM;  // Per-module state.
+  llvm::LLVMContext &VMContext;
+  
+  const llvm::Type *Int8PtrTy;
+  
+  /// Fields - The fields of the RTTI descriptor currently being built.
+  llvm::SmallVector<llvm::Constant *, 16> Fields;
+
+  /// GetAddrOfExternalRTTIDescriptor - Returns the constant for the RTTI 
+  /// descriptor of the given type.
+  llvm::Constant *GetAddrOfExternalRTTIDescriptor(QualType Ty);
+  
+  /// BuildVTablePointer - Build the vtable pointer for the given type.
+  void BuildVTablePointer(const Type *Ty);
+  
+  /// BuildSIClassTypeInfo - Build an abi::__si_class_type_info, used for single
+  /// inheritance, according to the Itanium C++ ABI, 2.9.5p6b.
+  void BuildSIClassTypeInfo(const CXXRecordDecl *RD);
+  
+  /// BuildVMIClassTypeInfo - Build an abi::__vmi_class_type_info, used for
+  /// classes with bases that do not satisfy the abi::__si_class_type_info 
+  /// constraints, according ti the Itanium C++ ABI, 2.9.5p5c.
+  void BuildVMIClassTypeInfo(const CXXRecordDecl *RD);
+  
+  /// BuildPointerTypeInfo - Build an abi::__pointer_type_info struct, used
+  /// for pointer types.
+  void BuildPointerTypeInfo(const PointerType *Ty);
+  
+  /// BuildPointerToMemberTypeInfo - Build an abi::__pointer_to_member_type_info 
+  /// struct, used for member pointer types.
+  void BuildPointerToMemberTypeInfo(const MemberPointerType *Ty);
+  
+public:
+  RTTIBuilder(CodeGenModule &cgm)
+    : CGM(cgm), VMContext(cgm.getModule().getContext()),
+      Int8PtrTy(llvm::Type::getInt8PtrTy(VMContext)) { }
+
+  llvm::Constant *BuildName(QualType Ty, bool Hidden, 
+                            llvm::GlobalVariable::LinkageTypes Linkage) {
+    llvm::SmallString<256> OutName;
+    CGM.getMangleContext().mangleCXXRTTIName(Ty, OutName);
+    llvm::StringRef Name = OutName.str();
+
+    llvm::GlobalVariable *OGV = CGM.getModule().getNamedGlobal(Name);
+    if (OGV && !OGV->isDeclaration())
+      return llvm::ConstantExpr::getBitCast(OGV, Int8PtrTy);
+
+    llvm::Constant *C = llvm::ConstantArray::get(VMContext, Name.substr(4));
+
+    llvm::GlobalVariable *GV = 
+      new llvm::GlobalVariable(CGM.getModule(), C->getType(), true, Linkage,
+                               C, Name);
+    if (OGV) {
+      GV->takeName(OGV);
+      llvm::Constant *NewPtr = llvm::ConstantExpr::getBitCast(GV,
+                                                              OGV->getType());
+      OGV->replaceAllUsesWith(NewPtr);
+      OGV->eraseFromParent();
+    }
+    if (Hidden)
+      GV->setVisibility(llvm::GlobalVariable::HiddenVisibility);
+    return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
+  }
+
+  // FIXME: unify with DecideExtern
+  bool DecideHidden(QualType Ty) {
+    // For this type, see if all components are never hidden.
+    if (const MemberPointerType *MPT = Ty->getAs<MemberPointerType>())
+      return (DecideHidden(MPT->getPointeeType())
+              && DecideHidden(QualType(MPT->getClass(), 0)));
+    if (const PointerType *PT = Ty->getAs<PointerType>())
+      return DecideHidden(PT->getPointeeType());
+    if (const FunctionType *FT = Ty->getAs<FunctionType>()) {
+      if (DecideHidden(FT->getResultType()) == false)
+        return false;
+      if (const FunctionProtoType *FPT = Ty->getAs<FunctionProtoType>()) {
+        for (unsigned i = 0; i <FPT->getNumArgs(); ++i)
+          if (DecideHidden(FPT->getArgType(i)) == false)
+            return false;
+        for (unsigned i = 0; i <FPT->getNumExceptions(); ++i)
+          if (DecideHidden(FPT->getExceptionType(i)) == false)
+            return false;
+        return true;
+      }
+    }
+    if (const RecordType *RT = Ty->getAs<RecordType>())
+      if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()))
+        return CGM.getDeclVisibilityMode(RD) == LangOptions::Hidden;
+    return false;
+  }
+  
+  // Pointer type info flags.
+  enum {
+    /// PTI_Const - Type has const qualifier.
+    PTI_Const = 0x1,
+    
+    /// PTI_Volatile - Type has volatile qualifier.
+    PTI_Volatile = 0x2,
+    
+    /// PTI_Restrict - Type has restrict qualifier.
+    PTI_Restrict = 0x4,
+    
+    /// PTI_Incomplete - Type is incomplete.
+    PTI_Incomplete = 0x8,
+    
+    /// PTI_ContainingClassIncomplete - Containing class is incomplete.
+    /// (in pointer to member).
+    PTI_ContainingClassIncomplete = 0x10
+  };
+  
+  // VMI type info flags.
+  enum {
+    /// VMI_NonDiamondRepeat - Class has non-diamond repeated inheritance.
+    VMI_NonDiamondRepeat = 0x1,
+    
+    /// VMI_DiamondShaped - Class is diamond shaped.
+    VMI_DiamondShaped = 0x2
+  };
+  
+  // Base class type info flags.
+  enum {
+    /// BCTI_Virtual - Base class is virtual.
+    BCTI_Virtual = 0x1,
+    
+    /// BCTI_Public - Base class is public.
+    BCTI_Public = 0x2
+  };
+  
+  /// BuildTypeInfo - Build the RTTI type info struct for the given type.
+  llvm::Constant *BuildTypeInfo(QualType Ty, bool Force = false);
+};
+}
+
+llvm::Constant *RTTIBuilder::GetAddrOfExternalRTTIDescriptor(QualType Ty) {
+  // Mangle the RTTI name.
+  llvm::SmallString<256> OutName;
+  CGM.getMangleContext().mangleCXXRTTI(Ty, OutName);
+  llvm::StringRef Name = OutName.str();
+
+  // Look for an existing global.
+  llvm::GlobalVariable *GV = CGM.getModule().getNamedGlobal(Name);
+  
+  if (!GV) {
+    // Create a new global variable.
+    GV = new llvm::GlobalVariable(CGM.getModule(), Int8PtrTy, /*Constant=*/true,
+                                  llvm::GlobalValue::ExternalLinkage, 0, Name);
+  }
+  
+  return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
+}
+
+/// TypeInfoIsInStandardLibrary - Given a builtin type, returns whether the type
+/// info for that type is defined in the standard library.
+static bool TypeInfoIsInStandardLibrary(const BuiltinType *Ty) {
+  // Itanium C++ ABI 2.9.2:
+  //   Basic type information (e.g. for "int", "bool", etc.) will be kept in
+  //   the run-time support library. Specifically, the run-time support
+  //   library should contain type_info objects for the types X, X* and 
+  //   X const*, for every X in: void, bool, wchar_t, char, unsigned char, 
+  //   signed char, short, unsigned short, int, unsigned int, long, 
+  //   unsigned long, long long, unsigned long long, float, double, long double, 
+  //   char16_t, char32_t, and the IEEE 754r decimal and half-precision 
+  //   floating point types.
+  switch (Ty->getKind()) {
+    case BuiltinType::Void:
+    case BuiltinType::Bool:
+    case BuiltinType::WChar:
+    case BuiltinType::Char_U:
+    case BuiltinType::Char_S:
+    case BuiltinType::UChar:
+    case BuiltinType::SChar:
+    case BuiltinType::Short:
+    case BuiltinType::UShort:
+    case BuiltinType::Int:
+    case BuiltinType::UInt:
+    case BuiltinType::Long:
+    case BuiltinType::ULong:
+    case BuiltinType::LongLong:
+    case BuiltinType::ULongLong:
+    case BuiltinType::Float:
+    case BuiltinType::Double:
+    case BuiltinType::LongDouble:
+    case BuiltinType::Char16:
+    case BuiltinType::Char32:
+    case BuiltinType::Int128:
+    case BuiltinType::UInt128:
+      return true;
+      
+    case BuiltinType::Overload:
+    case BuiltinType::Dependent:
+    case BuiltinType::UndeducedAuto:
+      assert(false && "Should not see this type here!");
+      
+    case BuiltinType::NullPtr:
+      assert(false && "FIXME: nullptr_t is not handled!");
+
+    case BuiltinType::ObjCId:
+    case BuiltinType::ObjCClass:
+    case BuiltinType::ObjCSel:
+      assert(false && "FIXME: Objective-C types are unsupported!");
+  }
+  
+  // Silent gcc.
+  return false;
+}
+
+static bool TypeInfoIsInStandardLibrary(const PointerType *PointerTy) {
+  QualType PointeeTy = PointerTy->getPointeeType();
+  const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(PointeeTy);
+  if (!BuiltinTy)
+    return false;
+    
+  // Check the qualifiers.
+  Qualifiers Quals = PointeeTy.getQualifiers();
+  Quals.removeConst();
+    
+  if (!Quals.empty())
+    return false;
+    
+  return TypeInfoIsInStandardLibrary(BuiltinTy);
+}
+
+/// ShouldUseExternalRTTIDescriptor - Returns whether the type information for
+/// the given type exists somewhere else, and that we should not emit the typ
+/// information in this translation unit.
+bool ShouldUseExternalRTTIDescriptor(QualType Ty) {
+  // Type info for builtin types is defined in the standard library.
+  if (const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(Ty))
+    return TypeInfoIsInStandardLibrary(BuiltinTy);
+  
+  // Type info for some pointer types to builtin types is defined in the
+  // standard library.
+  if (const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
+    return TypeInfoIsInStandardLibrary(PointerTy);
+
+  if (const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
+    const CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl());
+    if (!RD->hasDefinition())
+      return false;
+
+    if (!RD->isDynamicClass())
+      return false;
+
+    // Get the key function.
+    const CXXMethodDecl *KeyFunction = RD->getASTContext().getKeyFunction(RD);
+    if (KeyFunction && !KeyFunction->getBody()) {
+      // The class has a key function, but it is not defined in this translation
+      // unit, so we should use the external descriptor for it.
+      return true;
+    }
+  }
+  
+  return false;
+}
+
+/// IsIncompleteClassType - Returns whether the given record type is incomplete.
+static bool IsIncompleteClassType(const RecordType *RecordTy) {
+  return !RecordTy->getDecl()->isDefinition();
+}  
+
+/// ContainsIncompleteClassType - Returns whether the given type contains an
+/// incomplete class type. This is true if
+///
+///   * The given type is an incomplete class type.
+///   * The given type is a pointer type whose pointee type contains an 
+///     incomplete class type.
+///   * The given type is a member pointer type whose class is an incomplete
+///     class type.
+///   * The given type is a member pointer type whoise pointee type contains an
+///     incomplete class type.
+/// is an indirect or direct pointer to an incomplete class type.
+static bool ContainsIncompleteClassType(QualType Ty) {
+  if (const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
+    if (IsIncompleteClassType(RecordTy))
+      return true;
+  }
+  
+  if (const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
+    return ContainsIncompleteClassType(PointerTy->getPointeeType());
+  
+  if (const MemberPointerType *MemberPointerTy = 
+      dyn_cast<MemberPointerType>(Ty)) {
+    // Check if the class type is incomplete.
+    const RecordType *ClassType = cast<RecordType>(MemberPointerTy->getClass());
+    if (IsIncompleteClassType(ClassType))
+      return true;
+    
+    return ContainsIncompleteClassType(MemberPointerTy->getPointeeType());
+  }
+  
+  return false;
+}
+
+/// getTypeInfoLinkage - Return the linkage that the type info and type info
+/// name constants should have for the given type.
+static llvm::GlobalVariable::LinkageTypes getTypeInfoLinkage(QualType Ty) {
+  // Itanium C++ ABI 2.9.5p7:
+  //   In addition, it and all of the intermediate abi::__pointer_type_info 
+  //   structs in the chain down to the abi::__class_type_info for the
+  //   incomplete class type must be prevented from resolving to the 
+  //   corresponding type_info structs for the complete class type, possibly
+  //   by making them local static objects. Finally, a dummy class RTTI is
+  //   generated for the incomplete type that will not resolve to the final 
+  //   complete class RTTI (because the latter need not exist), possibly by 
+  //   making it a local static object.
+  if (ContainsIncompleteClassType(Ty))
+    return llvm::GlobalValue::InternalLinkage;
+  
+  switch (Ty->getLinkage()) {
+  case NoLinkage:
+  case InternalLinkage:
+  case UniqueExternalLinkage:
+    return llvm::GlobalValue::InternalLinkage;
+
+  case ExternalLinkage:
+    if (const RecordType *Record = dyn_cast<RecordType>(Ty)) {
+      const CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getDecl());
+      if (RD->isDynamicClass())
+        return CodeGenModule::getVTableLinkage(RD);
+    }
+
+    return llvm::GlobalValue::WeakODRLinkage;
+  }
+
+  return llvm::GlobalValue::WeakODRLinkage;
+}
+
+// CanUseSingleInheritance - Return whether the given record decl has a "single, 
+// public, non-virtual base at offset zero (i.e. the derived class is dynamic 
+// iff the base is)", according to Itanium C++ ABI, 2.95p6b.
+static bool CanUseSingleInheritance(const CXXRecordDecl *RD) {
+  // Check the number of bases.
+  if (RD->getNumBases() != 1)
+    return false;
+  
+  // Get the base.
+  CXXRecordDecl::base_class_const_iterator Base = RD->bases_begin();
+  
+  // Check that the base is not virtual.
+  if (Base->isVirtual())
+    return false;
+  
+  // Check that the base is public.
+  if (Base->getAccessSpecifier() != AS_public)
+    return false;
+  
+  // Check that the class is dynamic iff the base is.
+  const CXXRecordDecl *BaseDecl = 
+    cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
+  if (!BaseDecl->isEmpty() && 
+      BaseDecl->isDynamicClass() != RD->isDynamicClass())
+    return false;
+  
+  return true;
+}
+
+void RTTIBuilder::BuildVTablePointer(const Type *Ty) {
+  const char *VTableName;
+
+  switch (Ty->getTypeClass()) {
+  default: assert(0 && "Unhandled type!");
+
+  case Type::Builtin:
+  // GCC treats vector types as fundamental types.
+  case Type::Vector:
+  case Type::ExtVector:
+    // abi::__fundamental_type_info.
+    VTableName = "_ZTVN10__cxxabiv123__fundamental_type_infoE";
+    break;
+
+  case Type::ConstantArray:
+  case Type::IncompleteArray:
+    // abi::__array_type_info.
+    VTableName = "_ZTVN10__cxxabiv117__array_type_infoE";
+    break;
+
+  case Type::FunctionNoProto:
+  case Type::FunctionProto:
+    // abi::__function_type_info.
+    VTableName = "_ZTVN10__cxxabiv120__function_type_infoE";
+    break;
+
+  case Type::Enum:
+    // abi::__enum_type_info.
+    VTableName = "_ZTVN10__cxxabiv116__enum_type_infoE";
+    break;
+      
+  case Type::Record: {
+    const CXXRecordDecl *RD = 
+      cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl());
+    
+    if (!RD->hasDefinition() || !RD->getNumBases()) {
+      // abi::__class_type_info.
+      VTableName = "_ZTVN10__cxxabiv117__class_type_infoE";
+    } else if (CanUseSingleInheritance(RD)) {
+      // abi::__si_class_type_info.
+      VTableName = "_ZTVN10__cxxabiv120__si_class_type_infoE";
+    } else {
+      // abi::__vmi_class_type_info.
+      VTableName = "_ZTVN10__cxxabiv121__vmi_class_type_infoE";
+    }
+    
+    break;
+  }
+
+  case Type::Pointer:
+    // abi::__pointer_type_info.
+    VTableName = "_ZTVN10__cxxabiv119__pointer_type_infoE";
+    break;
+
+  case Type::MemberPointer:
+    // abi::__pointer_to_member_type_info.
+    VTableName = "_ZTVN10__cxxabiv129__pointer_to_member_type_infoE";
+    break;
+  }
+
+  llvm::Constant *VTable = 
+    CGM.getModule().getOrInsertGlobal(VTableName, Int8PtrTy);
+    
+  const llvm::Type *PtrDiffTy = 
+    CGM.getTypes().ConvertType(CGM.getContext().getPointerDiffType());
+
+  // The vtable address point is 2.
+  llvm::Constant *Two = llvm::ConstantInt::get(PtrDiffTy, 2);
+  VTable = llvm::ConstantExpr::getInBoundsGetElementPtr(VTable, &Two, 1);
+  VTable = llvm::ConstantExpr::getBitCast(VTable, Int8PtrTy);
+
+  Fields.push_back(VTable);
+}
+
+llvm::Constant *RTTIBuilder::BuildTypeInfo(QualType Ty, bool Force) {
+  // We want to operate on the canonical type.
+  Ty = CGM.getContext().getCanonicalType(Ty);
+
+  // Check if we've already emitted an RTTI descriptor for this type.
+  llvm::SmallString<256> OutName;
+  CGM.getMangleContext().mangleCXXRTTI(Ty, OutName);
+  llvm::StringRef Name = OutName.str();
+  
+  llvm::GlobalVariable *OldGV = CGM.getModule().getNamedGlobal(Name);
+  if (OldGV && !OldGV->isDeclaration())
+    return llvm::ConstantExpr::getBitCast(OldGV, Int8PtrTy);
+  
+  // Check if there is already an external RTTI descriptor for this type.
+  if (!Force && ShouldUseExternalRTTIDescriptor(Ty))
+    return GetAddrOfExternalRTTIDescriptor(Ty);
+
+  llvm::GlobalVariable::LinkageTypes Linkage = getTypeInfoLinkage(Ty);
+
+  // Add the vtable pointer.
+  BuildVTablePointer(cast<Type>(Ty));
+  
+  // And the name.
+  Fields.push_back(BuildName(Ty, DecideHidden(Ty), Linkage));
+  
+  switch (Ty->getTypeClass()) {
+  default: assert(false && "Unhandled type class!");
+
+  // GCC treats vector types as fundamental types.
+  case Type::Builtin:
+  case Type::Vector:
+  case Type::ExtVector:
+    // Itanium C++ ABI 2.9.5p4:
+    // abi::__fundamental_type_info adds no data members to std::type_info.
+    break;
+      
+  case Type::ConstantArray:
+  case Type::IncompleteArray:
+    // Itanium C++ ABI 2.9.5p5:
+    // abi::__array_type_info adds no data members to std::type_info.
+    break;
+
+  case Type::FunctionNoProto:
+  case Type::FunctionProto:
+    // Itanium C++ ABI 2.9.5p5:
+    // abi::__function_type_info adds no data members to std::type_info.
+    break;
+
+  case Type::Enum:
+    // Itanium C++ ABI 2.9.5p5:
+    // abi::__enum_type_info adds no data members to std::type_info.
+    break;
+
+  case Type::Record: {
+    const CXXRecordDecl *RD = 
+      cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl());
+    if (!RD->hasDefinition() || !RD->getNumBases()) {
+      // We don't need to emit any fields.
+      break;
+    }
+    
+    if (CanUseSingleInheritance(RD))
+      BuildSIClassTypeInfo(RD);
+    else 
+      BuildVMIClassTypeInfo(RD);
+
+    break;
+  }
+      
+  case Type::Pointer:
+    BuildPointerTypeInfo(cast<PointerType>(Ty));
+    break;
+  
+  case Type::MemberPointer:
+    BuildPointerToMemberTypeInfo(cast<MemberPointerType>(Ty));
+    break;
+  }
+
+  llvm::Constant *Init = 
+    llvm::ConstantStruct::get(VMContext, &Fields[0], Fields.size(), 
+                              /*Packed=*/false);
+
+  llvm::GlobalVariable *GV = 
+    new llvm::GlobalVariable(CGM.getModule(), Init->getType(), 
+                             /*Constant=*/true, Linkage, Init, Name);
+  
+  // If there's already an old global variable, replace it with the new one.
+  if (OldGV) {
+    GV->takeName(OldGV);
+    llvm::Constant *NewPtr = 
+      llvm::ConstantExpr::getBitCast(GV, OldGV->getType());
+    OldGV->replaceAllUsesWith(NewPtr);
+    OldGV->eraseFromParent();
+  }
+    
+  return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
+}
+
+/// ComputeQualifierFlags - Compute the pointer type info flags from the
+/// given qualifier.
+static unsigned ComputeQualifierFlags(Qualifiers Quals) {
+  unsigned Flags = 0;
+
+  if (Quals.hasConst())
+    Flags |= RTTIBuilder::PTI_Const;
+  if (Quals.hasVolatile())
+    Flags |= RTTIBuilder::PTI_Volatile;
+  if (Quals.hasRestrict())
+    Flags |= RTTIBuilder::PTI_Restrict;
+
+  return Flags;
+}
+
+/// BuildSIClassTypeInfo - Build an abi::__si_class_type_info, used for single
+/// inheritance, according to the Itanium C++ ABI, 2.95p6b.
+void RTTIBuilder::BuildSIClassTypeInfo(const CXXRecordDecl *RD) {
+  // Itanium C++ ABI 2.9.5p6b:
+  // It adds to abi::__class_type_info a single member pointing to the 
+  // type_info structure for the base type,
+  llvm::Constant *BaseTypeInfo = 
+    RTTIBuilder(CGM).BuildTypeInfo(RD->bases_begin()->getType());
+  Fields.push_back(BaseTypeInfo);
+}
+
+/// SeenBases - Contains virtual and non-virtual bases seen when traversing
+/// a class hierarchy.
+struct SeenBases {
+  llvm::SmallPtrSet<const CXXRecordDecl *, 16> NonVirtualBases;
+  llvm::SmallPtrSet<const CXXRecordDecl *, 16> VirtualBases;
+};
+
+/// ComputeVMIClassTypeInfoFlags - Compute the value of the flags member in
+/// abi::__vmi_class_type_info.
+///
+static unsigned ComputeVMIClassTypeInfoFlags(const CXXBaseSpecifier *Base, 
+                                             SeenBases &Bases) {
+  
+  unsigned Flags = 0;
+  
+  const CXXRecordDecl *BaseDecl = 
+    cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
+  
+  if (Base->isVirtual()) {
+    if (Bases.VirtualBases.count(BaseDecl)) {
+      // If this virtual base has been seen before, then the class is diamond
+      // shaped.
+      Flags |= RTTIBuilder::VMI_DiamondShaped;
+    } else {
+      if (Bases.NonVirtualBases.count(BaseDecl))
+        Flags |= RTTIBuilder::VMI_NonDiamondRepeat;
+
+      // Mark the virtual base as seen.
+      Bases.VirtualBases.insert(BaseDecl);
+    }
+  } else {
+    if (Bases.NonVirtualBases.count(BaseDecl)) {
+      // If this non-virtual base has been seen before, then the class has non-
+      // diamond shaped repeated inheritance.
+      Flags |= RTTIBuilder::VMI_NonDiamondRepeat;
+    } else {
+      if (Bases.VirtualBases.count(BaseDecl))
+        Flags |= RTTIBuilder::VMI_NonDiamondRepeat;
+        
+      // Mark the non-virtual base as seen.
+      Bases.NonVirtualBases.insert(BaseDecl);
+    }
+  }
+
+  // Walk all bases.
+  for (CXXRecordDecl::base_class_const_iterator I = BaseDecl->bases_begin(),
+       E = BaseDecl->bases_end(); I != E; ++I) 
+    Flags |= ComputeVMIClassTypeInfoFlags(I, Bases);
+  
+  return Flags;
+}
+
+static unsigned ComputeVMIClassTypeInfoFlags(const CXXRecordDecl *RD) {
+  unsigned Flags = 0;
+  SeenBases Bases;
+  
+  // Walk all bases.
+  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
+       E = RD->bases_end(); I != E; ++I) 
+    Flags |= ComputeVMIClassTypeInfoFlags(I, Bases);
+  
+  return Flags;
+}
+
+/// BuildVMIClassTypeInfo - Build an abi::__vmi_class_type_info, used for
+/// classes with bases that do not satisfy the abi::__si_class_type_info 
+/// constraints, according ti the Itanium C++ ABI, 2.9.5p5c.
+void RTTIBuilder::BuildVMIClassTypeInfo(const CXXRecordDecl *RD) {
+  const llvm::Type *UnsignedIntLTy = 
+    CGM.getTypes().ConvertType(CGM.getContext().UnsignedIntTy);
+  
+  // Itanium C++ ABI 2.9.5p6c:
+  //   __flags is a word with flags describing details about the class 
+  //   structure, which may be referenced by using the __flags_masks 
+  //   enumeration. These flags refer to both direct and indirect bases. 
+  unsigned Flags = ComputeVMIClassTypeInfoFlags(RD);
+  Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
+
+  // Itanium C++ ABI 2.9.5p6c:
+  //   __base_count is a word with the number of direct proper base class 
+  //   descriptions that follow.
+  Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, RD->getNumBases()));
+  
+  if (!RD->getNumBases())
+    return;
+  
+  const llvm::Type *LongLTy = 
+    CGM.getTypes().ConvertType(CGM.getContext().LongTy);
+
+  // Now add the base class descriptions.
+  
+  // Itanium C++ ABI 2.9.5p6c:
+  //   __base_info[] is an array of base class descriptions -- one for every 
+  //   direct proper base. Each description is of the type:
+  //
+  //   struct abi::__base_class_type_info {
+	//   public:
+  //     const __class_type_info *__base_type;
+  //     long __offset_flags;
+  //
+  //     enum __offset_flags_masks {
+  //       __virtual_mask = 0x1,
+  //       __public_mask = 0x2,
+  //       __offset_shift = 8
+  //     };
+  //   };
+  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
+       E = RD->bases_end(); I != E; ++I) {
+    const CXXBaseSpecifier *Base = I;
+
+    // The __base_type member points to the RTTI for the base type.
+    Fields.push_back(RTTIBuilder(CGM).BuildTypeInfo(Base->getType()));
+
+    const CXXRecordDecl *BaseDecl = 
+      cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
+
+    int64_t OffsetFlags = 0;
+    
+    // All but the lower 8 bits of __offset_flags are a signed offset. 
+    // For a non-virtual base, this is the offset in the object of the base
+    // subobject. For a virtual base, this is the offset in the virtual table of
+    // the virtual base offset for the virtual base referenced (negative).
+    if (Base->isVirtual())
+      OffsetFlags = CGM.getVTables().getVirtualBaseOffsetOffset(RD, BaseDecl);
+    else {
+      const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
+      OffsetFlags = Layout.getBaseClassOffset(BaseDecl) / 8;
+    };
+    
+    OffsetFlags <<= 8;
+    
+    // The low-order byte of __offset_flags contains flags, as given by the 
+    // masks from the enumeration __offset_flags_masks.
+    if (Base->isVirtual())
+      OffsetFlags |= BCTI_Virtual;
+    if (Base->getAccessSpecifier() == AS_public)
+      OffsetFlags |= BCTI_Public;
+
+    Fields.push_back(llvm::ConstantInt::get(LongLTy, OffsetFlags));
+  }
+}
+
+/// BuildPointerTypeInfo - Build an abi::__pointer_type_info struct,
+/// used for pointer types.
+void RTTIBuilder::BuildPointerTypeInfo(const PointerType *Ty) {
+  QualType PointeeTy = Ty->getPointeeType();
+  
+  // Itanium C++ ABI 2.9.5p7:
+  //   __flags is a flag word describing the cv-qualification and other 
+  //   attributes of the type pointed to
+  unsigned Flags = ComputeQualifierFlags(PointeeTy.getQualifiers());
+
+  // Itanium C++ ABI 2.9.5p7:
+  //   When the abi::__pbase_type_info is for a direct or indirect pointer to an
+  //   incomplete class type, the incomplete target type flag is set. 
+  if (ContainsIncompleteClassType(PointeeTy))
+    Flags |= PTI_Incomplete;
+
+  const llvm::Type *UnsignedIntLTy = 
+    CGM.getTypes().ConvertType(CGM.getContext().UnsignedIntTy);
+  Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
+  
+  // Itanium C++ ABI 2.9.5p7:
+  //  __pointee is a pointer to the std::type_info derivation for the 
+  //  unqualified type being pointed to.
+  llvm::Constant *PointeeTypeInfo = 
+    RTTIBuilder(CGM).BuildTypeInfo(PointeeTy.getUnqualifiedType());
+  Fields.push_back(PointeeTypeInfo);
+}
+
+/// BuildPointerToMemberTypeInfo - Build an abi::__pointer_to_member_type_info 
+/// struct, used for member pointer types.
+void RTTIBuilder::BuildPointerToMemberTypeInfo(const MemberPointerType *Ty) {
+  QualType PointeeTy = Ty->getPointeeType();
+  
+  // Itanium C++ ABI 2.9.5p7:
+  //   __flags is a flag word describing the cv-qualification and other 
+  //   attributes of the type pointed to.
+  unsigned Flags = ComputeQualifierFlags(PointeeTy.getQualifiers());
+
+  const RecordType *ClassType = cast<RecordType>(Ty->getClass());
+
+  // Itanium C++ ABI 2.9.5p7:
+  //   When the abi::__pbase_type_info is for a direct or indirect pointer to an
+  //   incomplete class type, the incomplete target type flag is set. 
+  if (ContainsIncompleteClassType(PointeeTy))
+    Flags |= PTI_Incomplete;
+
+  if (IsIncompleteClassType(ClassType))
+    Flags |= PTI_ContainingClassIncomplete;
+  
+  const llvm::Type *UnsignedIntLTy = 
+    CGM.getTypes().ConvertType(CGM.getContext().UnsignedIntTy);
+  Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
+  
+  // Itanium C++ ABI 2.9.5p7:
+  //   __pointee is a pointer to the std::type_info derivation for the 
+  //   unqualified type being pointed to.
+  llvm::Constant *PointeeTypeInfo = 
+    RTTIBuilder(CGM).BuildTypeInfo(PointeeTy.getUnqualifiedType());
+  Fields.push_back(PointeeTypeInfo);
+
+  // Itanium C++ ABI 2.9.5p9:
+  //   __context is a pointer to an abi::__class_type_info corresponding to the
+  //   class type containing the member pointed to 
+  //   (e.g., the "A" in "int A::*").
+  Fields.push_back(RTTIBuilder(CGM).BuildTypeInfo(QualType(ClassType, 0)));
+}
+
+llvm::Constant *CodeGenModule::GetAddrOfRTTIDescriptor(QualType Ty) {
+  if (!getContext().getLangOptions().RTTI) {
+    const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext);
+    return llvm::Constant::getNullValue(Int8PtrTy);
+  }
+  
+  return RTTIBuilder(*this).BuildTypeInfo(Ty);
+}
+
+void CodeGenModule::EmitFundamentalRTTIDescriptor(QualType Type) {
+  QualType PointerType = Context.getPointerType(Type);
+  QualType PointerTypeConst = Context.getPointerType(Type.withConst());
+  RTTIBuilder(*this).BuildTypeInfo(Type, true);
+  RTTIBuilder(*this).BuildTypeInfo(PointerType, true);
+  RTTIBuilder(*this).BuildTypeInfo(PointerTypeConst, true);
+}
+
+void CodeGenModule::EmitFundamentalRTTIDescriptors() {
+  QualType FundamentalTypes[] = { Context.VoidTy, Context.Char32Ty,
+                                  Context.Char16Ty, Context.UnsignedLongLongTy,
+                                  Context.LongLongTy, Context.WCharTy,
+                                  Context.UnsignedShortTy, Context.ShortTy,
+                                  Context.UnsignedLongTy, Context.LongTy,
+                                  Context.UnsignedIntTy, Context.IntTy,
+                                  Context.UnsignedCharTy, Context.FloatTy,
+                                  Context.LongDoubleTy, Context.DoubleTy,
+                                  Context.CharTy, Context.BoolTy,
+                                  Context.SignedCharTy };
+  for (unsigned i = 0; i < sizeof(FundamentalTypes)/sizeof(QualType); ++i)
+    EmitFundamentalRTTIDescriptor(FundamentalTypes[i]);
+}
diff --git a/lib/CodeGen/CGRecordLayout.h b/lib/CodeGen/CGRecordLayout.h
new file mode 100644
index 0000000..56211b1
--- /dev/null
+++ b/lib/CodeGen/CGRecordLayout.h
@@ -0,0 +1,213 @@
+//===--- CGRecordLayout.h - LLVM Record Layout Information ------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_CODEGEN_CGRECORDLAYOUT_H
+#define CLANG_CODEGEN_CGRECORDLAYOUT_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "clang/AST/Decl.h"
+namespace llvm {
+  class raw_ostream;
+  class Type;
+}
+
+namespace clang {
+namespace CodeGen {
+
+/// \brief Helper object for describing how to generate the code for access to a
+/// bit-field.
+///
+/// This structure is intended to describe the "policy" of how the bit-field
+/// should be accessed, which may be target, language, or ABI dependent.
+class CGBitFieldInfo {
+public:
+  /// Descriptor for a single component of a bit-field access. The entire
+  /// bit-field is constituted of a bitwise OR of all of the individual
+  /// components.
+  ///
+  /// Each component describes an accessed value, which is how the component
+  /// should be transferred to/from memory, and a target placement, which is how
+  /// that component fits into the constituted bit-field. The pseudo-IR for a
+  /// load is:
+  ///
+  ///   %0 = gep %base, 0, FieldIndex
+  ///   %1 = gep (i8*) %0, FieldByteOffset
+  ///   %2 = (i(AccessWidth) *) %1
+  ///   %3 = load %2, align AccessAlignment
+  ///   %4 = shr %3, FieldBitStart
+  ///
+  /// and the composed bit-field is formed as the boolean OR of all accesses,
+  /// masked to TargetBitWidth bits and shifted to TargetBitOffset.
+  struct AccessInfo {
+    /// Offset of the field to load in the LLVM structure, if any.
+    unsigned FieldIndex;
+
+    /// Byte offset from the field address, if any. This should generally be
+    /// unused as the cleanest IR comes from having a well-constructed LLVM type
+    /// with proper GEP instructions, but sometimes its use is required, for
+    /// example if an access is intended to straddle an LLVM field boundary.
+    unsigned FieldByteOffset;
+
+    /// Bit offset in the accessed value to use. The width is implied by \see
+    /// TargetBitWidth.
+    unsigned FieldBitStart;
+
+    /// Bit width of the memory access to perform.
+    unsigned AccessWidth;
+
+    /// The alignment of the memory access, or 0 if the default alignment should
+    /// be used.
+    //
+    // FIXME: Remove use of 0 to encode default, instead have IRgen do the right
+    // thing when it generates the code, if avoiding align directives is
+    // desired.
+    unsigned AccessAlignment;
+
+    /// Offset for the target value.
+    unsigned TargetBitOffset;
+
+    /// Number of bits in the access that are destined for the bit-field.
+    unsigned TargetBitWidth;
+  };
+
+private:
+  /// The components to use to access the bit-field. We may need up to three
+  /// separate components to support up to i64 bit-field access (4 + 2 + 1 byte
+  /// accesses).
+  //
+  // FIXME: De-hardcode this, just allocate following the struct.
+  AccessInfo Components[3];
+
+  /// The total size of the bit-field, in bits.
+  unsigned Size;
+
+  /// The number of access components to use.
+  unsigned NumComponents;
+
+  /// Whether the bit-field is signed.
+  bool IsSigned : 1;
+
+public:
+  CGBitFieldInfo(unsigned Size, unsigned NumComponents, AccessInfo *_Components,
+                 bool IsSigned) : Size(Size), NumComponents(NumComponents),
+                                  IsSigned(IsSigned) {
+    assert(NumComponents <= 3 && "invalid number of components!");
+    for (unsigned i = 0; i != NumComponents; ++i)
+      Components[i] = _Components[i];
+
+    // Check some invariants.
+    unsigned AccessedSize = 0;
+    for (unsigned i = 0, e = getNumComponents(); i != e; ++i) {
+      const AccessInfo &AI = getComponent(i);
+      AccessedSize += AI.TargetBitWidth;
+
+      // We shouldn't try to load 0 bits.
+      assert(AI.TargetBitWidth > 0);
+
+      // We can't load more bits than we accessed.
+      assert(AI.FieldBitStart + AI.TargetBitWidth <= AI.AccessWidth);
+
+      // We shouldn't put any bits outside the result size.
+      assert(AI.TargetBitWidth + AI.TargetBitOffset <= Size);
+    }
+
+    // Check that the total number of target bits matches the total bit-field
+    // size.
+    assert(AccessedSize == Size && "Total size does not match accessed size!");
+  }
+
+public:
+  /// \brief Check whether this bit-field access is (i.e., should be sign
+  /// extended on loads).
+  bool isSigned() const { return IsSigned; }
+
+  /// \brief Get the size of the bit-field, in bits.
+  unsigned getSize() const { return Size; }
+
+  /// @name Component Access
+  /// @{
+
+  unsigned getNumComponents() const { return NumComponents; }
+
+  const AccessInfo &getComponent(unsigned Index) const {
+    assert(Index < getNumComponents() && "Invalid access!");
+    return Components[Index];
+  }
+
+  /// @}
+
+  void print(llvm::raw_ostream &OS) const;
+  void dump() const;
+};
+
+/// CGRecordLayout - This class handles struct and union layout info while
+/// lowering AST types to LLVM types.
+///
+/// These layout objects are only created on demand as IR generation requires.
+class CGRecordLayout {
+  friend class CodeGenTypes;
+
+  CGRecordLayout(const CGRecordLayout&); // DO NOT IMPLEMENT
+  void operator=(const CGRecordLayout&); // DO NOT IMPLEMENT
+
+private:
+  /// The LLVMType corresponding to this record layout.
+  const llvm::Type *LLVMType;
+
+  /// Map from (non-bit-field) struct field to the corresponding llvm struct
+  /// type field no. This info is populated by record builder.
+  llvm::DenseMap<const FieldDecl *, unsigned> FieldInfo;
+
+  /// Map from (bit-field) struct field to the corresponding llvm struct type
+  /// field no. This info is populated by record builder.
+  llvm::DenseMap<const FieldDecl *, CGBitFieldInfo> BitFields;
+
+  /// Whether one of the fields in this record layout is a pointer to data
+  /// member, or a struct that contains pointer to data member.
+  bool ContainsPointerToDataMember : 1;
+
+public:
+  CGRecordLayout(const llvm::Type *T, bool ContainsPointerToDataMember)
+    : LLVMType(T), ContainsPointerToDataMember(ContainsPointerToDataMember) {}
+
+  /// \brief Return the LLVM type associated with this record.
+  const llvm::Type *getLLVMType() const {
+    return LLVMType;
+  }
+
+  /// \brief Check whether this struct contains pointers to data members.
+  bool containsPointerToDataMember() const {
+    return ContainsPointerToDataMember;
+  }
+
+  /// \brief Return the BitFieldInfo that corresponds to the field FD.
+  unsigned getLLVMFieldNo(const FieldDecl *FD) const {
+    assert(!FD->isBitField() && "Invalid call for bit-field decl!");
+    assert(FieldInfo.count(FD) && "Invalid field for record!");
+    return FieldInfo.lookup(FD);
+  }
+
+  /// \brief Return llvm::StructType element number that corresponds to the
+  /// field FD.
+  const CGBitFieldInfo &getBitFieldInfo(const FieldDecl *FD) const {
+    assert(FD->isBitField() && "Invalid call for non bit-field decl!");
+    llvm::DenseMap<const FieldDecl *, CGBitFieldInfo>::const_iterator
+      it = BitFields.find(FD);
+    assert(it != BitFields.end()  && "Unable to find bitfield info");
+    return it->second;
+  }
+
+  void print(llvm::raw_ostream &OS) const;
+  void dump() const;
+};
+
+}  // end namespace CodeGen
+}  // end namespace clang
+
+#endif
diff --git a/lib/CodeGen/CGRecordLayoutBuilder.cpp b/lib/CodeGen/CGRecordLayoutBuilder.cpp
new file mode 100644
index 0000000..6302cf8
--- /dev/null
+++ b/lib/CodeGen/CGRecordLayoutBuilder.cpp
@@ -0,0 +1,712 @@
+//===--- CGRecordLayoutBuilder.cpp - CGRecordLayout builder  ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Builder implementation for CGRecordLayout objects.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CGRecordLayout.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Attr.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/RecordLayout.h"
+#include "CodeGenTypes.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/Type.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Target/TargetData.h"
+using namespace clang;
+using namespace CodeGen;
+
+namespace clang {
+namespace CodeGen {
+
+class CGRecordLayoutBuilder {
+public:
+  /// FieldTypes - Holds the LLVM types that the struct is created from.
+  std::vector<const llvm::Type *> FieldTypes;
+
+  /// LLVMFieldInfo - Holds a field and its corresponding LLVM field number.
+  typedef std::pair<const FieldDecl *, unsigned> LLVMFieldInfo;
+  llvm::SmallVector<LLVMFieldInfo, 16> LLVMFields;
+
+  /// LLVMBitFieldInfo - Holds location and size information about a bit field.
+  typedef std::pair<const FieldDecl *, CGBitFieldInfo> LLVMBitFieldInfo;
+  llvm::SmallVector<LLVMBitFieldInfo, 16> LLVMBitFields;
+
+  /// ContainsPointerToDataMember - Whether one of the fields in this record
+  /// layout is a pointer to data member, or a struct that contains pointer to
+  /// data member.
+  bool ContainsPointerToDataMember;
+
+  /// Packed - Whether the resulting LLVM struct will be packed or not.
+  bool Packed;
+
+private:
+  CodeGenTypes &Types;
+
+  /// Alignment - Contains the alignment of the RecordDecl.
+  //
+  // FIXME: This is not needed and should be removed.
+  unsigned Alignment;
+
+  /// AlignmentAsLLVMStruct - Will contain the maximum alignment of all the
+  /// LLVM types.
+  unsigned AlignmentAsLLVMStruct;
+
+  /// BitsAvailableInLastField - If a bit field spans only part of a LLVM field,
+  /// this will have the number of bits still available in the field.
+  char BitsAvailableInLastField;
+
+  /// NextFieldOffsetInBytes - Holds the next field offset in bytes.
+  uint64_t NextFieldOffsetInBytes;
+
+  /// LayoutUnionField - Will layout a field in an union and return the type
+  /// that the field will have.
+  const llvm::Type *LayoutUnionField(const FieldDecl *Field,
+                                     const ASTRecordLayout &Layout);
+  
+  /// LayoutUnion - Will layout a union RecordDecl.
+  void LayoutUnion(const RecordDecl *D);
+
+  /// LayoutField - try to layout all fields in the record decl.
+  /// Returns false if the operation failed because the struct is not packed.
+  bool LayoutFields(const RecordDecl *D);
+
+  /// LayoutBases - layout the bases and vtable pointer of a record decl.
+  void LayoutBases(const CXXRecordDecl *RD, const ASTRecordLayout &Layout);
+
+  /// LayoutField - layout a single field. Returns false if the operation failed
+  /// because the current struct is not packed.
+  bool LayoutField(const FieldDecl *D, uint64_t FieldOffset);
+
+  /// LayoutBitField - layout a single bit field.
+  void LayoutBitField(const FieldDecl *D, uint64_t FieldOffset);
+
+  /// AppendField - Appends a field with the given offset and type.
+  void AppendField(uint64_t FieldOffsetInBytes, const llvm::Type *FieldTy);
+
+  /// AppendPadding - Appends enough padding bytes so that the total
+  /// struct size is a multiple of the field alignment.
+  void AppendPadding(uint64_t FieldOffsetInBytes, unsigned FieldAlignment);
+
+  /// AppendBytes - Append a given number of bytes to the record.
+  void AppendBytes(uint64_t NumBytes);
+
+  /// AppendTailPadding - Append enough tail padding so that the type will have
+  /// the passed size.
+  void AppendTailPadding(uint64_t RecordSize);
+
+  unsigned getTypeAlignment(const llvm::Type *Ty) const;
+
+  /// CheckForPointerToDataMember - Check if the given type contains a pointer
+  /// to data member.
+  void CheckForPointerToDataMember(QualType T);
+
+public:
+  CGRecordLayoutBuilder(CodeGenTypes &Types)
+    : ContainsPointerToDataMember(false), Packed(false), Types(Types),
+      Alignment(0), AlignmentAsLLVMStruct(1),
+      BitsAvailableInLastField(0), NextFieldOffsetInBytes(0) { }
+
+  /// Layout - Will layout a RecordDecl.
+  void Layout(const RecordDecl *D);
+};
+
+}
+}
+
+void CGRecordLayoutBuilder::Layout(const RecordDecl *D) {
+  Alignment = Types.getContext().getASTRecordLayout(D).getAlignment() / 8;
+  Packed = D->hasAttr<PackedAttr>();
+
+  if (D->isUnion()) {
+    LayoutUnion(D);
+    return;
+  }
+
+  if (LayoutFields(D))
+    return;
+
+  // We weren't able to layout the struct. Try again with a packed struct
+  Packed = true;
+  AlignmentAsLLVMStruct = 1;
+  NextFieldOffsetInBytes = 0;
+  FieldTypes.clear();
+  LLVMFields.clear();
+  LLVMBitFields.clear();
+
+  LayoutFields(D);
+}
+
+static CGBitFieldInfo ComputeBitFieldInfo(CodeGenTypes &Types,
+                                          const FieldDecl *FD,
+                                          uint64_t FieldOffset,
+                                          uint64_t FieldSize) {
+  const RecordDecl *RD = FD->getParent();
+  const ASTRecordLayout &RL = Types.getContext().getASTRecordLayout(RD);
+  uint64_t ContainingTypeSizeInBits = RL.getSize();
+  unsigned ContainingTypeAlign = RL.getAlignment();
+
+  const llvm::Type *Ty = Types.ConvertTypeForMemRecursive(FD->getType());
+  uint64_t TypeSizeInBytes = Types.getTargetData().getTypeAllocSize(Ty);
+  uint64_t TypeSizeInBits = TypeSizeInBytes * 8;
+
+  bool IsSigned = FD->getType()->isSignedIntegerType();
+
+  if (FieldSize > TypeSizeInBits) {
+    // We have a wide bit-field. The extra bits are only used for padding, so
+    // if we have a bitfield of type T, with size N:
+    //
+    // T t : N;
+    //
+    // We can just assume that it's:
+    //
+    // T t : sizeof(T);
+    //
+    FieldSize = TypeSizeInBits;
+  }
+
+  // Compute the access components. The policy we use is to start by attempting
+  // to access using the width of the bit-field type itself and to always access
+  // at aligned indices of that type. If such an access would fail because it
+  // extends past the bound of the type, then we reduce size to the next smaller
+  // power of two and retry. The current algorithm assumes pow2 sized types,
+  // although this is easy to fix.
+  //
+  // FIXME: This algorithm is wrong on big-endian systems, I think.
+  assert(llvm::isPowerOf2_32(TypeSizeInBits) && "Unexpected type size!");
+  CGBitFieldInfo::AccessInfo Components[3];
+  unsigned NumComponents = 0;
+  unsigned AccessedTargetBits = 0;       // The tumber of target bits accessed.
+  unsigned AccessWidth = TypeSizeInBits; // The current access width to attempt.
+
+  // Round down from the field offset to find the first access position that is
+  // at an aligned offset of the initial access type.
+  uint64_t AccessStart = FieldOffset - (FieldOffset % AccessWidth);
+
+  // Adjust initial access size to fit within record.
+  while (AccessWidth > 8 &&
+         AccessStart + AccessWidth > ContainingTypeSizeInBits) {
+    AccessWidth >>= 1;
+    AccessStart = FieldOffset - (FieldOffset % AccessWidth);
+  }
+
+  while (AccessedTargetBits < FieldSize) {
+    // Check that we can access using a type of this size, without reading off
+    // the end of the structure. This can occur with packed structures and
+    // -fno-bitfield-type-align, for example.
+    if (AccessStart + AccessWidth > ContainingTypeSizeInBits) {
+      // If so, reduce access size to the next smaller power-of-two and retry.
+      AccessWidth >>= 1;
+      assert(AccessWidth >= 8 && "Cannot access under byte size!");
+      continue;
+    }
+
+    // Otherwise, add an access component.
+
+    // First, compute the bits inside this access which are part of the
+    // target. We are reading bits [AccessStart, AccessStart + AccessWidth); the
+    // intersection with [FieldOffset, FieldOffset + FieldSize) gives the bits
+    // in the target that we are reading.
+    assert(FieldOffset < AccessStart + AccessWidth && "Invalid access start!");
+    assert(AccessStart < FieldOffset + FieldSize && "Invalid access start!");
+    uint64_t AccessBitsInFieldStart = std::max(AccessStart, FieldOffset);
+    uint64_t AccessBitsInFieldSize =
+      std::min(AccessWidth + AccessStart,
+               FieldOffset + FieldSize) - AccessBitsInFieldStart;
+
+    assert(NumComponents < 3 && "Unexpected number of components!");
+    CGBitFieldInfo::AccessInfo &AI = Components[NumComponents++];
+    AI.FieldIndex = 0;
+    // FIXME: We still follow the old access pattern of only using the field
+    // byte offset. We should switch this once we fix the struct layout to be
+    // pretty.
+    AI.FieldByteOffset = AccessStart / 8;
+    AI.FieldBitStart = AccessBitsInFieldStart - AccessStart;
+    AI.AccessWidth = AccessWidth;
+    AI.AccessAlignment = llvm::MinAlign(ContainingTypeAlign, AccessStart) / 8;
+    AI.TargetBitOffset = AccessedTargetBits;
+    AI.TargetBitWidth = AccessBitsInFieldSize;
+
+    AccessStart += AccessWidth;
+    AccessedTargetBits += AI.TargetBitWidth;
+  }
+
+  assert(AccessedTargetBits == FieldSize && "Invalid bit-field access!");
+  return CGBitFieldInfo(FieldSize, NumComponents, Components, IsSigned);
+}
+
+void CGRecordLayoutBuilder::LayoutBitField(const FieldDecl *D,
+                                           uint64_t FieldOffset) {
+  uint64_t FieldSize =
+    D->getBitWidth()->EvaluateAsInt(Types.getContext()).getZExtValue();
+
+  if (FieldSize == 0)
+    return;
+
+  uint64_t NextFieldOffset = NextFieldOffsetInBytes * 8;
+  unsigned NumBytesToAppend;
+
+  if (FieldOffset < NextFieldOffset) {
+    assert(BitsAvailableInLastField && "Bitfield size mismatch!");
+    assert(NextFieldOffsetInBytes && "Must have laid out at least one byte!");
+
+    // The bitfield begins in the previous bit-field.
+    NumBytesToAppend =
+      llvm::RoundUpToAlignment(FieldSize - BitsAvailableInLastField, 8) / 8;
+  } else {
+    assert(FieldOffset % 8 == 0 && "Field offset not aligned correctly");
+
+    // Append padding if necessary.
+    AppendBytes((FieldOffset - NextFieldOffset) / 8);
+
+    NumBytesToAppend =
+      llvm::RoundUpToAlignment(FieldSize, 8) / 8;
+
+    assert(NumBytesToAppend && "No bytes to append!");
+  }
+
+  // Add the bit field info.
+  LLVMBitFields.push_back(
+    LLVMBitFieldInfo(D, ComputeBitFieldInfo(Types, D, FieldOffset, FieldSize)));
+
+  AppendBytes(NumBytesToAppend);
+
+  BitsAvailableInLastField =
+    NextFieldOffsetInBytes * 8 - (FieldOffset + FieldSize);
+}
+
+bool CGRecordLayoutBuilder::LayoutField(const FieldDecl *D,
+                                        uint64_t FieldOffset) {
+  // If the field is packed, then we need a packed struct.
+  if (!Packed && D->hasAttr<PackedAttr>())
+    return false;
+
+  if (D->isBitField()) {
+    // We must use packed structs for unnamed bit fields since they
+    // don't affect the struct alignment.
+    if (!Packed && !D->getDeclName())
+      return false;
+
+    LayoutBitField(D, FieldOffset);
+    return true;
+  }
+
+  // Check if we have a pointer to data member in this field.
+  CheckForPointerToDataMember(D->getType());
+
+  assert(FieldOffset % 8 == 0 && "FieldOffset is not on a byte boundary!");
+  uint64_t FieldOffsetInBytes = FieldOffset / 8;
+
+  const llvm::Type *Ty = Types.ConvertTypeForMemRecursive(D->getType());
+  unsigned TypeAlignment = getTypeAlignment(Ty);
+
+  // If the type alignment is larger then the struct alignment, we must use
+  // a packed struct.
+  if (TypeAlignment > Alignment) {
+    assert(!Packed && "Alignment is wrong even with packed struct!");
+    return false;
+  }
+
+  if (const RecordType *RT = D->getType()->getAs<RecordType>()) {
+    const RecordDecl *RD = cast<RecordDecl>(RT->getDecl());
+    if (const PragmaPackAttr *PPA = RD->getAttr<PragmaPackAttr>()) {
+      if (PPA->getAlignment() != TypeAlignment * 8 && !Packed)
+        return false;
+    }
+  }
+
+  // Round up the field offset to the alignment of the field type.
+  uint64_t AlignedNextFieldOffsetInBytes =
+    llvm::RoundUpToAlignment(NextFieldOffsetInBytes, TypeAlignment);
+
+  if (FieldOffsetInBytes < AlignedNextFieldOffsetInBytes) {
+    assert(!Packed && "Could not place field even with packed struct!");
+    return false;
+  }
+
+  if (AlignedNextFieldOffsetInBytes < FieldOffsetInBytes) {
+    // Even with alignment, the field offset is not at the right place,
+    // insert padding.
+    uint64_t PaddingInBytes = FieldOffsetInBytes - NextFieldOffsetInBytes;
+
+    AppendBytes(PaddingInBytes);
+  }
+
+  // Now append the field.
+  LLVMFields.push_back(LLVMFieldInfo(D, FieldTypes.size()));
+  AppendField(FieldOffsetInBytes, Ty);
+
+  return true;
+}
+
+const llvm::Type *
+CGRecordLayoutBuilder::LayoutUnionField(const FieldDecl *Field,
+                                        const ASTRecordLayout &Layout) {
+  if (Field->isBitField()) {
+    uint64_t FieldSize =
+      Field->getBitWidth()->EvaluateAsInt(Types.getContext()).getZExtValue();
+
+    // Ignore zero sized bit fields.
+    if (FieldSize == 0)
+      return 0;
+
+    const llvm::Type *FieldTy = llvm::Type::getInt8Ty(Types.getLLVMContext());
+    unsigned NumBytesToAppend =
+      llvm::RoundUpToAlignment(FieldSize, 8) / 8;
+
+    if (NumBytesToAppend > 1)
+      FieldTy = llvm::ArrayType::get(FieldTy, NumBytesToAppend);
+
+    // Add the bit field info.
+    LLVMBitFields.push_back(
+      LLVMBitFieldInfo(Field, ComputeBitFieldInfo(Types, Field, 0, FieldSize)));
+    return FieldTy;
+  }
+
+  // This is a regular union field.
+  LLVMFields.push_back(LLVMFieldInfo(Field, 0));
+  return Types.ConvertTypeForMemRecursive(Field->getType());
+}
+
+void CGRecordLayoutBuilder::LayoutUnion(const RecordDecl *D) {
+  assert(D->isUnion() && "Can't call LayoutUnion on a non-union record!");
+
+  const ASTRecordLayout &Layout = Types.getContext().getASTRecordLayout(D);
+
+  const llvm::Type *Ty = 0;
+  uint64_t Size = 0;
+  unsigned Align = 0;
+
+  bool HasOnlyZeroSizedBitFields = true;
+
+  unsigned FieldNo = 0;
+  for (RecordDecl::field_iterator Field = D->field_begin(),
+       FieldEnd = D->field_end(); Field != FieldEnd; ++Field, ++FieldNo) {
+    assert(Layout.getFieldOffset(FieldNo) == 0 &&
+          "Union field offset did not start at the beginning of record!");
+    const llvm::Type *FieldTy = LayoutUnionField(*Field, Layout);
+
+    if (!FieldTy)
+      continue;
+
+    HasOnlyZeroSizedBitFields = false;
+
+    unsigned FieldAlign = Types.getTargetData().getABITypeAlignment(FieldTy);
+    uint64_t FieldSize = Types.getTargetData().getTypeAllocSize(FieldTy);
+
+    if (FieldAlign < Align)
+      continue;
+
+    if (FieldAlign > Align || FieldSize > Size) {
+      Ty = FieldTy;
+      Align = FieldAlign;
+      Size = FieldSize;
+    }
+  }
+
+  // Now add our field.
+  if (Ty) {
+    AppendField(0, Ty);
+
+    if (getTypeAlignment(Ty) > Layout.getAlignment() / 8) {
+      // We need a packed struct.
+      Packed = true;
+      Align = 1;
+    }
+  }
+  if (!Align) {
+    assert(HasOnlyZeroSizedBitFields &&
+           "0-align record did not have all zero-sized bit-fields!");
+    Align = 1;
+  }
+
+  // Append tail padding.
+  if (Layout.getSize() / 8 > Size)
+    AppendPadding(Layout.getSize() / 8, Align);
+}
+
+void CGRecordLayoutBuilder::LayoutBases(const CXXRecordDecl *RD,
+                                        const ASTRecordLayout &Layout) {
+  // Check if we need to add a vtable pointer.
+  if (RD->isDynamicClass() && !Layout.getPrimaryBase()) {
+    const llvm::Type *Int8PtrTy =
+      llvm::Type::getInt8PtrTy(Types.getLLVMContext());
+
+    assert(NextFieldOffsetInBytes == 0 &&
+           "VTable pointer must come first!");
+    AppendField(NextFieldOffsetInBytes, Int8PtrTy->getPointerTo());
+  }
+}
+
+bool CGRecordLayoutBuilder::LayoutFields(const RecordDecl *D) {
+  assert(!D->isUnion() && "Can't call LayoutFields on a union!");
+  assert(Alignment && "Did not set alignment!");
+
+  const ASTRecordLayout &Layout = Types.getContext().getASTRecordLayout(D);
+
+  if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
+    LayoutBases(RD, Layout);
+
+  unsigned FieldNo = 0;
+
+  for (RecordDecl::field_iterator Field = D->field_begin(),
+       FieldEnd = D->field_end(); Field != FieldEnd; ++Field, ++FieldNo) {
+    if (!LayoutField(*Field, Layout.getFieldOffset(FieldNo))) {
+      assert(!Packed &&
+             "Could not layout fields even with a packed LLVM struct!");
+      return false;
+    }
+  }
+
+  // Append tail padding if necessary.
+  AppendTailPadding(Layout.getSize());
+
+  return true;
+}
+
+void CGRecordLayoutBuilder::AppendTailPadding(uint64_t RecordSize) {
+  assert(RecordSize % 8 == 0 && "Invalid record size!");
+
+  uint64_t RecordSizeInBytes = RecordSize / 8;
+  assert(NextFieldOffsetInBytes <= RecordSizeInBytes && "Size mismatch!");
+
+  uint64_t AlignedNextFieldOffset =
+    llvm::RoundUpToAlignment(NextFieldOffsetInBytes, AlignmentAsLLVMStruct);
+
+  if (AlignedNextFieldOffset == RecordSizeInBytes) {
+    // We don't need any padding.
+    return;
+  }
+
+  unsigned NumPadBytes = RecordSizeInBytes - NextFieldOffsetInBytes;
+  AppendBytes(NumPadBytes);
+}
+
+void CGRecordLayoutBuilder::AppendField(uint64_t FieldOffsetInBytes,
+                                        const llvm::Type *FieldTy) {
+  AlignmentAsLLVMStruct = std::max(AlignmentAsLLVMStruct,
+                                   getTypeAlignment(FieldTy));
+
+  uint64_t FieldSizeInBytes = Types.getTargetData().getTypeAllocSize(FieldTy);
+
+  FieldTypes.push_back(FieldTy);
+
+  NextFieldOffsetInBytes = FieldOffsetInBytes + FieldSizeInBytes;
+  BitsAvailableInLastField = 0;
+}
+
+void CGRecordLayoutBuilder::AppendPadding(uint64_t FieldOffsetInBytes,
+                                          unsigned FieldAlignment) {
+  assert(NextFieldOffsetInBytes <= FieldOffsetInBytes &&
+         "Incorrect field layout!");
+
+  // Round up the field offset to the alignment of the field type.
+  uint64_t AlignedNextFieldOffsetInBytes =
+    llvm::RoundUpToAlignment(NextFieldOffsetInBytes, FieldAlignment);
+
+  if (AlignedNextFieldOffsetInBytes < FieldOffsetInBytes) {
+    // Even with alignment, the field offset is not at the right place,
+    // insert padding.
+    uint64_t PaddingInBytes = FieldOffsetInBytes - NextFieldOffsetInBytes;
+
+    AppendBytes(PaddingInBytes);
+  }
+}
+
+void CGRecordLayoutBuilder::AppendBytes(uint64_t NumBytes) {
+  if (NumBytes == 0)
+    return;
+
+  const llvm::Type *Ty = llvm::Type::getInt8Ty(Types.getLLVMContext());
+  if (NumBytes > 1)
+    Ty = llvm::ArrayType::get(Ty, NumBytes);
+
+  // Append the padding field
+  AppendField(NextFieldOffsetInBytes, Ty);
+}
+
+unsigned CGRecordLayoutBuilder::getTypeAlignment(const llvm::Type *Ty) const {
+  if (Packed)
+    return 1;
+
+  return Types.getTargetData().getABITypeAlignment(Ty);
+}
+
+void CGRecordLayoutBuilder::CheckForPointerToDataMember(QualType T) {
+  // This record already contains a member pointer.
+  if (ContainsPointerToDataMember)
+    return;
+
+  // Can only have member pointers if we're compiling C++.
+  if (!Types.getContext().getLangOptions().CPlusPlus)
+    return;
+
+  T = Types.getContext().getBaseElementType(T);
+
+  if (const MemberPointerType *MPT = T->getAs<MemberPointerType>()) {
+    if (!MPT->getPointeeType()->isFunctionType()) {
+      // We have a pointer to data member.
+      ContainsPointerToDataMember = true;
+    }
+  } else if (const RecordType *RT = T->getAs<RecordType>()) {
+    const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
+
+    // FIXME: It would be better if there was a way to explicitly compute the
+    // record layout instead of converting to a type.
+    Types.ConvertTagDeclType(RD);
+
+    const CGRecordLayout &Layout = Types.getCGRecordLayout(RD);
+
+    if (Layout.containsPointerToDataMember())
+      ContainsPointerToDataMember = true;
+  }
+}
+
+CGRecordLayout *CodeGenTypes::ComputeRecordLayout(const RecordDecl *D) {
+  CGRecordLayoutBuilder Builder(*this);
+
+  Builder.Layout(D);
+
+  const llvm::Type *Ty = llvm::StructType::get(getLLVMContext(),
+                                               Builder.FieldTypes,
+                                               Builder.Packed);
+
+  CGRecordLayout *RL =
+    new CGRecordLayout(Ty, Builder.ContainsPointerToDataMember);
+
+  // Add all the field numbers.
+  for (unsigned i = 0, e = Builder.LLVMFields.size(); i != e; ++i)
+    RL->FieldInfo.insert(Builder.LLVMFields[i]);
+
+  // Add bitfield info.
+  for (unsigned i = 0, e = Builder.LLVMBitFields.size(); i != e; ++i)
+    RL->BitFields.insert(Builder.LLVMBitFields[i]);
+
+  // Dump the layout, if requested.
+  if (getContext().getLangOptions().DumpRecordLayouts) {
+    llvm::errs() << "\n*** Dumping IRgen Record Layout\n";
+    llvm::errs() << "Record: ";
+    D->dump();
+    llvm::errs() << "\nLayout: ";
+    RL->dump();
+  }
+
+#ifndef NDEBUG
+  // Verify that the computed LLVM struct size matches the AST layout size.
+  uint64_t TypeSizeInBits = getContext().getASTRecordLayout(D).getSize();
+  assert(TypeSizeInBits == getTargetData().getTypeAllocSizeInBits(Ty) &&
+         "Type size mismatch!");
+
+  // Verify that the LLVM and AST field offsets agree.
+  const llvm::StructType *ST =
+    dyn_cast<llvm::StructType>(RL->getLLVMType());
+  const llvm::StructLayout *SL = getTargetData().getStructLayout(ST);
+
+  const ASTRecordLayout &AST_RL = getContext().getASTRecordLayout(D);
+  RecordDecl::field_iterator it = D->field_begin();
+  for (unsigned i = 0, e = AST_RL.getFieldCount(); i != e; ++i, ++it) {
+    const FieldDecl *FD = *it;
+
+    // For non-bit-fields, just check that the LLVM struct offset matches the
+    // AST offset.
+    if (!FD->isBitField()) {
+      unsigned FieldNo = RL->getLLVMFieldNo(FD);
+      assert(AST_RL.getFieldOffset(i) == SL->getElementOffsetInBits(FieldNo) &&
+             "Invalid field offset!");
+      continue;
+    }
+
+    // Ignore unnamed bit-fields.
+    if (!FD->getDeclName())
+      continue;
+
+    const CGBitFieldInfo &Info = RL->getBitFieldInfo(FD);
+    for (unsigned i = 0, e = Info.getNumComponents(); i != e; ++i) {
+      const CGBitFieldInfo::AccessInfo &AI = Info.getComponent(i);
+
+      // Verify that every component access is within the structure.
+      uint64_t FieldOffset = SL->getElementOffsetInBits(AI.FieldIndex);
+      uint64_t AccessBitOffset = FieldOffset + AI.FieldByteOffset * 8;
+      assert(AccessBitOffset + AI.AccessWidth <= TypeSizeInBits &&
+             "Invalid bit-field access (out of range)!");
+    }
+  }
+#endif
+
+  return RL;
+}
+
+void CGRecordLayout::print(llvm::raw_ostream &OS) const {
+  OS << "<CGRecordLayout\n";
+  OS << "  LLVMType:" << *LLVMType << "\n";
+  OS << "  ContainsPointerToDataMember:" << ContainsPointerToDataMember << "\n";
+  OS << "  BitFields:[\n";
+
+  // Print bit-field infos in declaration order.
+  std::vector<std::pair<unsigned, const CGBitFieldInfo*> > BFIs;
+  for (llvm::DenseMap<const FieldDecl*, CGBitFieldInfo>::const_iterator
+         it = BitFields.begin(), ie = BitFields.end();
+       it != ie; ++it) {
+    const RecordDecl *RD = it->first->getParent();
+    unsigned Index = 0;
+    for (RecordDecl::field_iterator
+           it2 = RD->field_begin(); *it2 != it->first; ++it2)
+      ++Index;
+    BFIs.push_back(std::make_pair(Index, &it->second));
+  }
+  llvm::array_pod_sort(BFIs.begin(), BFIs.end());
+  for (unsigned i = 0, e = BFIs.size(); i != e; ++i) {
+    OS.indent(4);
+    BFIs[i].second->print(OS);
+    OS << "\n";
+  }
+
+  OS << "]>\n";
+}
+
+void CGRecordLayout::dump() const {
+  print(llvm::errs());
+}
+
+void CGBitFieldInfo::print(llvm::raw_ostream &OS) const {
+  OS << "<CGBitFieldInfo";
+  OS << " Size:" << Size;
+  OS << " IsSigned:" << IsSigned << "\n";
+
+  OS.indent(4 + strlen("<CGBitFieldInfo"));
+  OS << " NumComponents:" << getNumComponents();
+  OS << " Components: [";
+  if (getNumComponents()) {
+    OS << "\n";
+    for (unsigned i = 0, e = getNumComponents(); i != e; ++i) {
+      const AccessInfo &AI = getComponent(i);
+      OS.indent(8);
+      OS << "<AccessInfo"
+         << " FieldIndex:" << AI.FieldIndex
+         << " FieldByteOffset:" << AI.FieldByteOffset
+         << " FieldBitStart:" << AI.FieldBitStart
+         << " AccessWidth:" << AI.AccessWidth << "\n";
+      OS.indent(8 + strlen("<AccessInfo"));
+      OS << " AccessAlignment:" << AI.AccessAlignment
+         << " TargetBitOffset:" << AI.TargetBitOffset
+         << " TargetBitWidth:" << AI.TargetBitWidth
+         << ">\n";
+    }
+    OS.indent(4);
+  }
+  OS << "]>";
+}
+
+void CGBitFieldInfo::dump() const {
+  print(llvm::errs());
+}
diff --git a/lib/CodeGen/CGStmt.cpp b/lib/CodeGen/CGStmt.cpp
new file mode 100644
index 0000000..a914c80
--- /dev/null
+++ b/lib/CodeGen/CGStmt.cpp
@@ -0,0 +1,1162 @@
+//===--- CGStmt.cpp - Emit LLVM Code from Statements ----------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This contains code to emit Stmt nodes as LLVM code.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CGDebugInfo.h"
+#include "CodeGenModule.h"
+#include "CodeGenFunction.h"
+#include "clang/AST/StmtVisitor.h"
+#include "clang/Basic/PrettyStackTrace.h"
+#include "clang/Basic/TargetInfo.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/InlineAsm.h"
+#include "llvm/Intrinsics.h"
+#include "llvm/Target/TargetData.h"
+using namespace clang;
+using namespace CodeGen;
+
+//===----------------------------------------------------------------------===//
+//                              Statement Emission
+//===----------------------------------------------------------------------===//
+
+void CodeGenFunction::EmitStopPoint(const Stmt *S) {
+  if (CGDebugInfo *DI = getDebugInfo()) {
+    DI->setLocation(S->getLocStart());
+    DI->EmitStopPoint(CurFn, Builder);
+  }
+}
+
+void CodeGenFunction::EmitStmt(const Stmt *S) {
+  assert(S && "Null statement?");
+
+  // Check if we can handle this without bothering to generate an
+  // insert point or debug info.
+  if (EmitSimpleStmt(S))
+    return;
+
+  // Check if we are generating unreachable code.
+  if (!HaveInsertPoint()) {
+    // If so, and the statement doesn't contain a label, then we do not need to
+    // generate actual code. This is safe because (1) the current point is
+    // unreachable, so we don't need to execute the code, and (2) we've already
+    // handled the statements which update internal data structures (like the
+    // local variable map) which could be used by subsequent statements.
+    if (!ContainsLabel(S)) {
+      // Verify that any decl statements were handled as simple, they may be in
+      // scope of subsequent reachable statements.
+      assert(!isa<DeclStmt>(*S) && "Unexpected DeclStmt!");
+      return;
+    }
+
+    // Otherwise, make a new block to hold the code.
+    EnsureInsertPoint();
+  }
+
+  // Generate a stoppoint if we are emitting debug info.
+  EmitStopPoint(S);
+
+  switch (S->getStmtClass()) {
+  default:
+    // Must be an expression in a stmt context.  Emit the value (to get
+    // side-effects) and ignore the result.
+    if (!isa<Expr>(S))
+      ErrorUnsupported(S, "statement");
+
+    EmitAnyExpr(cast<Expr>(S), 0, false, true);
+
+    // Expression emitters don't handle unreachable blocks yet, so look for one
+    // explicitly here. This handles the common case of a call to a noreturn
+    // function.
+    if (llvm::BasicBlock *CurBB = Builder.GetInsertBlock()) {
+      if (CurBB->empty() && CurBB->use_empty()) {
+        CurBB->eraseFromParent();
+        Builder.ClearInsertionPoint();
+      }
+    }
+    break;
+  case Stmt::IndirectGotoStmtClass:
+    EmitIndirectGotoStmt(cast<IndirectGotoStmt>(*S)); break;
+
+  case Stmt::IfStmtClass:       EmitIfStmt(cast<IfStmt>(*S));             break;
+  case Stmt::WhileStmtClass:    EmitWhileStmt(cast<WhileStmt>(*S));       break;
+  case Stmt::DoStmtClass:       EmitDoStmt(cast<DoStmt>(*S));             break;
+  case Stmt::ForStmtClass:      EmitForStmt(cast<ForStmt>(*S));           break;
+
+  case Stmt::ReturnStmtClass:   EmitReturnStmt(cast<ReturnStmt>(*S));     break;
+
+  case Stmt::SwitchStmtClass:   EmitSwitchStmt(cast<SwitchStmt>(*S));     break;
+  case Stmt::AsmStmtClass:      EmitAsmStmt(cast<AsmStmt>(*S));           break;
+
+  case Stmt::ObjCAtTryStmtClass:
+    EmitObjCAtTryStmt(cast<ObjCAtTryStmt>(*S));
+    break;
+  case Stmt::ObjCAtCatchStmtClass:
+    assert(0 && "@catch statements should be handled by EmitObjCAtTryStmt");
+    break;
+  case Stmt::ObjCAtFinallyStmtClass:
+    assert(0 && "@finally statements should be handled by EmitObjCAtTryStmt");
+    break;
+  case Stmt::ObjCAtThrowStmtClass:
+    EmitObjCAtThrowStmt(cast<ObjCAtThrowStmt>(*S));
+    break;
+  case Stmt::ObjCAtSynchronizedStmtClass:
+    EmitObjCAtSynchronizedStmt(cast<ObjCAtSynchronizedStmt>(*S));
+    break;
+  case Stmt::ObjCForCollectionStmtClass:
+    EmitObjCForCollectionStmt(cast<ObjCForCollectionStmt>(*S));
+    break;
+      
+  case Stmt::CXXTryStmtClass:
+    EmitCXXTryStmt(cast<CXXTryStmt>(*S));
+    break;
+  }
+}
+
+bool CodeGenFunction::EmitSimpleStmt(const Stmt *S) {
+  switch (S->getStmtClass()) {
+  default: return false;
+  case Stmt::NullStmtClass: break;
+  case Stmt::CompoundStmtClass: EmitCompoundStmt(cast<CompoundStmt>(*S)); break;
+  case Stmt::DeclStmtClass:     EmitDeclStmt(cast<DeclStmt>(*S));         break;
+  case Stmt::LabelStmtClass:    EmitLabelStmt(cast<LabelStmt>(*S));       break;
+  case Stmt::GotoStmtClass:     EmitGotoStmt(cast<GotoStmt>(*S));         break;
+  case Stmt::BreakStmtClass:    EmitBreakStmt(cast<BreakStmt>(*S));       break;
+  case Stmt::ContinueStmtClass: EmitContinueStmt(cast<ContinueStmt>(*S)); break;
+  case Stmt::DefaultStmtClass:  EmitDefaultStmt(cast<DefaultStmt>(*S));   break;
+  case Stmt::CaseStmtClass:     EmitCaseStmt(cast<CaseStmt>(*S));         break;
+  }
+
+  return true;
+}
+
+/// EmitCompoundStmt - Emit a compound statement {..} node.  If GetLast is true,
+/// this captures the expression result of the last sub-statement and returns it
+/// (for use by the statement expression extension).
+RValue CodeGenFunction::EmitCompoundStmt(const CompoundStmt &S, bool GetLast,
+                                         llvm::Value *AggLoc, bool isAggVol) {
+  PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),S.getLBracLoc(),
+                             "LLVM IR generation of compound statement ('{}')");
+
+  CGDebugInfo *DI = getDebugInfo();
+  if (DI) {
+    DI->setLocation(S.getLBracLoc());
+    DI->EmitRegionStart(CurFn, Builder);
+  }
+
+  // Keep track of the current cleanup stack depth.
+  CleanupScope Scope(*this);
+
+  for (CompoundStmt::const_body_iterator I = S.body_begin(),
+       E = S.body_end()-GetLast; I != E; ++I)
+    EmitStmt(*I);
+
+  if (DI) {
+    DI->setLocation(S.getRBracLoc());
+    DI->EmitRegionEnd(CurFn, Builder);
+  }
+
+  RValue RV;
+  if (!GetLast)
+    RV = RValue::get(0);
+  else {
+    // We have to special case labels here.  They are statements, but when put
+    // at the end of a statement expression, they yield the value of their
+    // subexpression.  Handle this by walking through all labels we encounter,
+    // emitting them before we evaluate the subexpr.
+    const Stmt *LastStmt = S.body_back();
+    while (const LabelStmt *LS = dyn_cast<LabelStmt>(LastStmt)) {
+      EmitLabel(*LS);
+      LastStmt = LS->getSubStmt();
+    }
+
+    EnsureInsertPoint();
+
+    RV = EmitAnyExpr(cast<Expr>(LastStmt), AggLoc);
+  }
+
+  return RV;
+}
+
+void CodeGenFunction::SimplifyForwardingBlocks(llvm::BasicBlock *BB) {
+  llvm::BranchInst *BI = dyn_cast<llvm::BranchInst>(BB->getTerminator());
+
+  // If there is a cleanup stack, then we it isn't worth trying to
+  // simplify this block (we would need to remove it from the scope map
+  // and cleanup entry).
+  if (!CleanupEntries.empty())
+    return;
+
+  // Can only simplify direct branches.
+  if (!BI || !BI->isUnconditional())
+    return;
+
+  BB->replaceAllUsesWith(BI->getSuccessor(0));
+  BI->eraseFromParent();
+  BB->eraseFromParent();
+}
+
+void CodeGenFunction::EmitBlock(llvm::BasicBlock *BB, bool IsFinished) {
+  llvm::BasicBlock *CurBB = Builder.GetInsertBlock();
+
+  // Fall out of the current block (if necessary).
+  EmitBranch(BB);
+
+  if (IsFinished && BB->use_empty()) {
+    delete BB;
+    return;
+  }
+
+  // If necessary, associate the block with the cleanup stack size.
+  if (!CleanupEntries.empty()) {
+    // Check if the basic block has already been inserted.
+    BlockScopeMap::iterator I = BlockScopes.find(BB);
+    if (I != BlockScopes.end()) {
+      assert(I->second == CleanupEntries.size() - 1);
+    } else {
+      BlockScopes[BB] = CleanupEntries.size() - 1;
+      CleanupEntries.back().Blocks.push_back(BB);
+    }
+  }
+
+  // Place the block after the current block, if possible, or else at
+  // the end of the function.
+  if (CurBB && CurBB->getParent())
+    CurFn->getBasicBlockList().insertAfter(CurBB, BB);
+  else
+    CurFn->getBasicBlockList().push_back(BB);
+  Builder.SetInsertPoint(BB);
+}
+
+void CodeGenFunction::EmitBranch(llvm::BasicBlock *Target) {
+  // Emit a branch from the current block to the target one if this
+  // was a real block.  If this was just a fall-through block after a
+  // terminator, don't emit it.
+  llvm::BasicBlock *CurBB = Builder.GetInsertBlock();
+
+  if (!CurBB || CurBB->getTerminator()) {
+    // If there is no insert point or the previous block is already
+    // terminated, don't touch it.
+  } else {
+    // Otherwise, create a fall-through branch.
+    Builder.CreateBr(Target);
+  }
+
+  Builder.ClearInsertionPoint();
+}
+
+void CodeGenFunction::EmitLabel(const LabelStmt &S) {
+  EmitBlock(getBasicBlockForLabel(&S));
+}
+
+
+void CodeGenFunction::EmitLabelStmt(const LabelStmt &S) {
+  EmitLabel(S);
+  EmitStmt(S.getSubStmt());
+}
+
+void CodeGenFunction::EmitGotoStmt(const GotoStmt &S) {
+  // If this code is reachable then emit a stop point (if generating
+  // debug info). We have to do this ourselves because we are on the
+  // "simple" statement path.
+  if (HaveInsertPoint())
+    EmitStopPoint(&S);
+
+  EmitBranchThroughCleanup(getBasicBlockForLabel(S.getLabel()));
+}
+
+
+void CodeGenFunction::EmitIndirectGotoStmt(const IndirectGotoStmt &S) {
+  // Ensure that we have an i8* for our PHI node.
+  llvm::Value *V = Builder.CreateBitCast(EmitScalarExpr(S.getTarget()),
+                                         llvm::Type::getInt8PtrTy(VMContext),
+                                          "addr");
+  llvm::BasicBlock *CurBB = Builder.GetInsertBlock();
+  
+
+  // Get the basic block for the indirect goto.
+  llvm::BasicBlock *IndGotoBB = GetIndirectGotoBlock();
+  
+  // The first instruction in the block has to be the PHI for the switch dest,
+  // add an entry for this branch.
+  cast<llvm::PHINode>(IndGotoBB->begin())->addIncoming(V, CurBB);
+  
+  EmitBranch(IndGotoBB);
+}
+
+void CodeGenFunction::EmitIfStmt(const IfStmt &S) {
+  // C99 6.8.4.1: The first substatement is executed if the expression compares
+  // unequal to 0.  The condition must be a scalar type.
+  CleanupScope ConditionScope(*this);
+
+  if (S.getConditionVariable())
+    EmitLocalBlockVarDecl(*S.getConditionVariable());
+
+  // If the condition constant folds and can be elided, try to avoid emitting
+  // the condition and the dead arm of the if/else.
+  if (int Cond = ConstantFoldsToSimpleInteger(S.getCond())) {
+    // Figure out which block (then or else) is executed.
+    const Stmt *Executed = S.getThen(), *Skipped  = S.getElse();
+    if (Cond == -1)  // Condition false?
+      std::swap(Executed, Skipped);
+
+    // If the skipped block has no labels in it, just emit the executed block.
+    // This avoids emitting dead code and simplifies the CFG substantially.
+    if (!ContainsLabel(Skipped)) {
+      if (Executed) {
+        CleanupScope ExecutedScope(*this);
+        EmitStmt(Executed);
+      }
+      return;
+    }
+  }
+
+  // Otherwise, the condition did not fold, or we couldn't elide it.  Just emit
+  // the conditional branch.
+  llvm::BasicBlock *ThenBlock = createBasicBlock("if.then");
+  llvm::BasicBlock *ContBlock = createBasicBlock("if.end");
+  llvm::BasicBlock *ElseBlock = ContBlock;
+  if (S.getElse())
+    ElseBlock = createBasicBlock("if.else");
+  EmitBranchOnBoolExpr(S.getCond(), ThenBlock, ElseBlock);
+
+  // Emit the 'then' code.
+  EmitBlock(ThenBlock); 
+  {
+    CleanupScope ThenScope(*this);
+    EmitStmt(S.getThen());
+  }
+  EmitBranch(ContBlock);
+
+  // Emit the 'else' code if present.
+  if (const Stmt *Else = S.getElse()) {
+    EmitBlock(ElseBlock);
+    {
+      CleanupScope ElseScope(*this);
+      EmitStmt(Else);
+    }
+    EmitBranch(ContBlock);
+  }
+
+  // Emit the continuation block for code after the if.
+  EmitBlock(ContBlock, true);
+}
+
+void CodeGenFunction::EmitWhileStmt(const WhileStmt &S) {
+  // Emit the header for the loop, insert it, which will create an uncond br to
+  // it.
+  llvm::BasicBlock *LoopHeader = createBasicBlock("while.cond");
+  EmitBlock(LoopHeader);
+
+  // Create an exit block for when the condition fails, create a block for the
+  // body of the loop.
+  llvm::BasicBlock *ExitBlock = createBasicBlock("while.end");
+  llvm::BasicBlock *LoopBody  = createBasicBlock("while.body");
+  llvm::BasicBlock *CleanupBlock = 0;
+  llvm::BasicBlock *EffectiveExitBlock = ExitBlock;
+
+  // Store the blocks to use for break and continue.
+  BreakContinueStack.push_back(BreakContinue(ExitBlock, LoopHeader));
+
+  // C++ [stmt.while]p2:
+  //   When the condition of a while statement is a declaration, the
+  //   scope of the variable that is declared extends from its point
+  //   of declaration (3.3.2) to the end of the while statement.
+  //   [...]
+  //   The object created in a condition is destroyed and created
+  //   with each iteration of the loop.
+  CleanupScope ConditionScope(*this);
+
+  if (S.getConditionVariable()) {
+    EmitLocalBlockVarDecl(*S.getConditionVariable());
+
+    // If this condition variable requires cleanups, create a basic
+    // block to handle those cleanups.
+    if (ConditionScope.requiresCleanups()) {
+      CleanupBlock = createBasicBlock("while.cleanup");
+      EffectiveExitBlock = CleanupBlock;
+    }
+  }
+  
+  // Evaluate the conditional in the while header.  C99 6.8.5.1: The
+  // evaluation of the controlling expression takes place before each
+  // execution of the loop body.
+  llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond());
+   
+  // while(1) is common, avoid extra exit blocks.  Be sure
+  // to correctly handle break/continue though.
+  bool EmitBoolCondBranch = true;
+  if (llvm::ConstantInt *C = dyn_cast<llvm::ConstantInt>(BoolCondVal))
+    if (C->isOne())
+      EmitBoolCondBranch = false;
+
+  // As long as the condition is true, go to the loop body.
+  if (EmitBoolCondBranch)
+    Builder.CreateCondBr(BoolCondVal, LoopBody, EffectiveExitBlock);
+ 
+  // Emit the loop body.
+  {
+    CleanupScope BodyScope(*this);
+    EmitBlock(LoopBody);
+    EmitStmt(S.getBody());
+  }
+
+  BreakContinueStack.pop_back();
+
+  if (CleanupBlock) {
+    // If we have a cleanup block, jump there to perform cleanups
+    // before looping.
+    EmitBranch(CleanupBlock);
+
+    // Emit the cleanup block, performing cleanups for the condition
+    // and then jumping to either the loop header or the exit block.
+    EmitBlock(CleanupBlock);
+    ConditionScope.ForceCleanup();
+    Builder.CreateCondBr(BoolCondVal, LoopHeader, ExitBlock);
+  } else {
+    // Cycle to the condition.
+    EmitBranch(LoopHeader);
+  }
+
+  // Emit the exit block.
+  EmitBlock(ExitBlock, true);
+
+
+  // The LoopHeader typically is just a branch if we skipped emitting
+  // a branch, try to erase it.
+  if (!EmitBoolCondBranch && !CleanupBlock)
+    SimplifyForwardingBlocks(LoopHeader);
+}
+
+void CodeGenFunction::EmitDoStmt(const DoStmt &S) {
+  // Emit the body for the loop, insert it, which will create an uncond br to
+  // it.
+  llvm::BasicBlock *LoopBody = createBasicBlock("do.body");
+  llvm::BasicBlock *AfterDo = createBasicBlock("do.end");
+  EmitBlock(LoopBody);
+
+  llvm::BasicBlock *DoCond = createBasicBlock("do.cond");
+
+  // Store the blocks to use for break and continue.
+  BreakContinueStack.push_back(BreakContinue(AfterDo, DoCond));
+
+  // Emit the body of the loop into the block.
+  EmitStmt(S.getBody());
+
+  BreakContinueStack.pop_back();
+
+  EmitBlock(DoCond);
+
+  // C99 6.8.5.2: "The evaluation of the controlling expression takes place
+  // after each execution of the loop body."
+
+  // Evaluate the conditional in the while header.
+  // C99 6.8.5p2/p4: The first substatement is executed if the expression
+  // compares unequal to 0.  The condition must be a scalar type.
+  llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond());
+
+  // "do {} while (0)" is common in macros, avoid extra blocks.  Be sure
+  // to correctly handle break/continue though.
+  bool EmitBoolCondBranch = true;
+  if (llvm::ConstantInt *C = dyn_cast<llvm::ConstantInt>(BoolCondVal))
+    if (C->isZero())
+      EmitBoolCondBranch = false;
+
+  // As long as the condition is true, iterate the loop.
+  if (EmitBoolCondBranch)
+    Builder.CreateCondBr(BoolCondVal, LoopBody, AfterDo);
+
+  // Emit the exit block.
+  EmitBlock(AfterDo);
+
+  // The DoCond block typically is just a branch if we skipped
+  // emitting a branch, try to erase it.
+  if (!EmitBoolCondBranch)
+    SimplifyForwardingBlocks(DoCond);
+}
+
+void CodeGenFunction::EmitForStmt(const ForStmt &S) {
+  // FIXME: What do we do if the increment (f.e.) contains a stmt expression,
+  // which contains a continue/break?
+  CleanupScope ForScope(*this);
+
+  // Evaluate the first part before the loop.
+  if (S.getInit())
+    EmitStmt(S.getInit());
+
+  // Start the loop with a block that tests the condition.
+  llvm::BasicBlock *CondBlock = createBasicBlock("for.cond");
+  llvm::BasicBlock *AfterFor = createBasicBlock("for.end");
+  llvm::BasicBlock *IncBlock = 0;
+  llvm::BasicBlock *CondCleanup = 0;
+  llvm::BasicBlock *EffectiveExitBlock = AfterFor;
+  EmitBlock(CondBlock);
+
+  // Create a cleanup scope for the condition variable cleanups.
+  CleanupScope ConditionScope(*this);
+  
+  llvm::Value *BoolCondVal = 0;
+  if (S.getCond()) {
+    // If the for statement has a condition scope, emit the local variable
+    // declaration.
+    if (S.getConditionVariable()) {
+      EmitLocalBlockVarDecl(*S.getConditionVariable());
+      
+      if (ConditionScope.requiresCleanups()) {
+        CondCleanup = createBasicBlock("for.cond.cleanup");
+        EffectiveExitBlock = CondCleanup;
+      }
+    }
+    
+    // As long as the condition is true, iterate the loop.
+    llvm::BasicBlock *ForBody = createBasicBlock("for.body");
+
+    // C99 6.8.5p2/p4: The first substatement is executed if the expression
+    // compares unequal to 0.  The condition must be a scalar type.
+    BoolCondVal = EvaluateExprAsBool(S.getCond());
+    Builder.CreateCondBr(BoolCondVal, ForBody, EffectiveExitBlock);
+
+    EmitBlock(ForBody);
+  } else {
+    // Treat it as a non-zero constant.  Don't even create a new block for the
+    // body, just fall into it.
+  }
+
+  // If the for loop doesn't have an increment we can just use the
+  // condition as the continue block.
+  llvm::BasicBlock *ContinueBlock;
+  if (S.getInc())
+    ContinueBlock = IncBlock = createBasicBlock("for.inc");
+  else
+    ContinueBlock = CondBlock;
+
+  // Store the blocks to use for break and continue.
+  BreakContinueStack.push_back(BreakContinue(AfterFor, ContinueBlock));
+
+  // If the condition is true, execute the body of the for stmt.
+  CGDebugInfo *DI = getDebugInfo();
+  if (DI) {
+    DI->setLocation(S.getSourceRange().getBegin());
+    DI->EmitRegionStart(CurFn, Builder);
+  }
+
+  {
+    // Create a separate cleanup scope for the body, in case it is not
+    // a compound statement.
+    CleanupScope BodyScope(*this);
+    EmitStmt(S.getBody());
+  }
+
+  BreakContinueStack.pop_back();
+
+  // If there is an increment, emit it next.
+  if (S.getInc()) {
+    EmitBlock(IncBlock);
+    EmitStmt(S.getInc());
+  }
+
+  // Finally, branch back up to the condition for the next iteration.
+  if (CondCleanup) {
+    // Branch to the cleanup block.
+    EmitBranch(CondCleanup);
+
+    // Emit the cleanup block, which branches back to the loop body or
+    // outside of the for statement once it is done.
+    EmitBlock(CondCleanup);
+    ConditionScope.ForceCleanup();
+    Builder.CreateCondBr(BoolCondVal, CondBlock, AfterFor);
+  } else
+    EmitBranch(CondBlock);
+  if (DI) {
+    DI->setLocation(S.getSourceRange().getEnd());
+    DI->EmitRegionEnd(CurFn, Builder);
+  }
+
+  // Emit the fall-through block.
+  EmitBlock(AfterFor, true);
+}
+
+void CodeGenFunction::EmitReturnOfRValue(RValue RV, QualType Ty) {
+  if (RV.isScalar()) {
+    Builder.CreateStore(RV.getScalarVal(), ReturnValue);
+  } else if (RV.isAggregate()) {
+    EmitAggregateCopy(ReturnValue, RV.getAggregateAddr(), Ty);
+  } else {
+    StoreComplexToAddr(RV.getComplexVal(), ReturnValue, false);
+  }
+  EmitBranchThroughCleanup(ReturnBlock);
+}
+
+/// EmitReturnStmt - Note that due to GCC extensions, this can have an operand
+/// if the function returns void, or may be missing one if the function returns
+/// non-void.  Fun stuff :).
+void CodeGenFunction::EmitReturnStmt(const ReturnStmt &S) {
+  // Emit the result value, even if unused, to evalute the side effects.
+  const Expr *RV = S.getRetValue();
+
+  // FIXME: Clean this up by using an LValue for ReturnTemp,
+  // EmitStoreThroughLValue, and EmitAnyExpr.
+  if (!ReturnValue) {
+    // Make sure not to return anything, but evaluate the expression
+    // for side effects.
+    if (RV)
+      EmitAnyExpr(RV);
+  } else if (RV == 0) {
+    // Do nothing (return value is left uninitialized)
+  } else if (FnRetTy->isReferenceType()) {
+    // If this function returns a reference, take the address of the expression
+    // rather than the value.
+    RValue Result = EmitReferenceBindingToExpr(RV, false);
+    Builder.CreateStore(Result.getScalarVal(), ReturnValue);
+  } else if (!hasAggregateLLVMType(RV->getType())) {
+    Builder.CreateStore(EmitScalarExpr(RV), ReturnValue);
+  } else if (RV->getType()->isAnyComplexType()) {
+    EmitComplexExprIntoAddr(RV, ReturnValue, false);
+  } else {
+    EmitAggExpr(RV, ReturnValue, false);
+  }
+
+  EmitBranchThroughCleanup(ReturnBlock);
+}
+
+void CodeGenFunction::EmitDeclStmt(const DeclStmt &S) {
+  // As long as debug info is modeled with instructions, we have to ensure we
+  // have a place to insert here and write the stop point here.
+  if (getDebugInfo()) {
+    EnsureInsertPoint();
+    EmitStopPoint(&S);
+  }
+
+  for (DeclStmt::const_decl_iterator I = S.decl_begin(), E = S.decl_end();
+       I != E; ++I)
+    EmitDecl(**I);
+}
+
+void CodeGenFunction::EmitBreakStmt(const BreakStmt &S) {
+  assert(!BreakContinueStack.empty() && "break stmt not in a loop or switch!");
+
+  // If this code is reachable then emit a stop point (if generating
+  // debug info). We have to do this ourselves because we are on the
+  // "simple" statement path.
+  if (HaveInsertPoint())
+    EmitStopPoint(&S);
+
+  llvm::BasicBlock *Block = BreakContinueStack.back().BreakBlock;
+  EmitBranchThroughCleanup(Block);
+}
+
+void CodeGenFunction::EmitContinueStmt(const ContinueStmt &S) {
+  assert(!BreakContinueStack.empty() && "continue stmt not in a loop!");
+
+  // If this code is reachable then emit a stop point (if generating
+  // debug info). We have to do this ourselves because we are on the
+  // "simple" statement path.
+  if (HaveInsertPoint())
+    EmitStopPoint(&S);
+
+  llvm::BasicBlock *Block = BreakContinueStack.back().ContinueBlock;
+  EmitBranchThroughCleanup(Block);
+}
+
+/// EmitCaseStmtRange - If case statement range is not too big then
+/// add multiple cases to switch instruction, one for each value within
+/// the range. If range is too big then emit "if" condition check.
+void CodeGenFunction::EmitCaseStmtRange(const CaseStmt &S) {
+  assert(S.getRHS() && "Expected RHS value in CaseStmt");
+
+  llvm::APSInt LHS = S.getLHS()->EvaluateAsInt(getContext());
+  llvm::APSInt RHS = S.getRHS()->EvaluateAsInt(getContext());
+
+  // Emit the code for this case. We do this first to make sure it is
+  // properly chained from our predecessor before generating the
+  // switch machinery to enter this block.
+  EmitBlock(createBasicBlock("sw.bb"));
+  llvm::BasicBlock *CaseDest = Builder.GetInsertBlock();
+  EmitStmt(S.getSubStmt());
+
+  // If range is empty, do nothing.
+  if (LHS.isSigned() ? RHS.slt(LHS) : RHS.ult(LHS))
+    return;
+
+  llvm::APInt Range = RHS - LHS;
+  // FIXME: parameters such as this should not be hardcoded.
+  if (Range.ult(llvm::APInt(Range.getBitWidth(), 64))) {
+    // Range is small enough to add multiple switch instruction cases.
+    for (unsigned i = 0, e = Range.getZExtValue() + 1; i != e; ++i) {
+      SwitchInsn->addCase(llvm::ConstantInt::get(VMContext, LHS), CaseDest);
+      LHS++;
+    }
+    return;
+  }
+
+  // The range is too big. Emit "if" condition into a new block,
+  // making sure to save and restore the current insertion point.
+  llvm::BasicBlock *RestoreBB = Builder.GetInsertBlock();
+
+  // Push this test onto the chain of range checks (which terminates
+  // in the default basic block). The switch's default will be changed
+  // to the top of this chain after switch emission is complete.
+  llvm::BasicBlock *FalseDest = CaseRangeBlock;
+  CaseRangeBlock = createBasicBlock("sw.caserange");
+
+  CurFn->getBasicBlockList().push_back(CaseRangeBlock);
+  Builder.SetInsertPoint(CaseRangeBlock);
+
+  // Emit range check.
+  llvm::Value *Diff =
+    Builder.CreateSub(SwitchInsn->getCondition(),
+                      llvm::ConstantInt::get(VMContext, LHS),  "tmp");
+  llvm::Value *Cond =
+    Builder.CreateICmpULE(Diff,
+                          llvm::ConstantInt::get(VMContext, Range), "tmp");
+  Builder.CreateCondBr(Cond, CaseDest, FalseDest);
+
+  // Restore the appropriate insertion point.
+  if (RestoreBB)
+    Builder.SetInsertPoint(RestoreBB);
+  else
+    Builder.ClearInsertionPoint();
+}
+
+void CodeGenFunction::EmitCaseStmt(const CaseStmt &S) {
+  if (S.getRHS()) {
+    EmitCaseStmtRange(S);
+    return;
+  }
+
+  EmitBlock(createBasicBlock("sw.bb"));
+  llvm::BasicBlock *CaseDest = Builder.GetInsertBlock();
+  llvm::APSInt CaseVal = S.getLHS()->EvaluateAsInt(getContext());
+  SwitchInsn->addCase(llvm::ConstantInt::get(VMContext, CaseVal), CaseDest);
+
+  // Recursively emitting the statement is acceptable, but is not wonderful for
+  // code where we have many case statements nested together, i.e.:
+  //  case 1:
+  //    case 2:
+  //      case 3: etc.
+  // Handling this recursively will create a new block for each case statement
+  // that falls through to the next case which is IR intensive.  It also causes
+  // deep recursion which can run into stack depth limitations.  Handle
+  // sequential non-range case statements specially.
+  const CaseStmt *CurCase = &S;
+  const CaseStmt *NextCase = dyn_cast<CaseStmt>(S.getSubStmt());
+
+  // Otherwise, iteratively add consequtive cases to this switch stmt.
+  while (NextCase && NextCase->getRHS() == 0) {
+    CurCase = NextCase;
+    CaseVal = CurCase->getLHS()->EvaluateAsInt(getContext());
+    SwitchInsn->addCase(llvm::ConstantInt::get(VMContext, CaseVal), CaseDest);
+
+    NextCase = dyn_cast<CaseStmt>(CurCase->getSubStmt());
+  }
+
+  // Normal default recursion for non-cases.
+  EmitStmt(CurCase->getSubStmt());
+}
+
+void CodeGenFunction::EmitDefaultStmt(const DefaultStmt &S) {
+  llvm::BasicBlock *DefaultBlock = SwitchInsn->getDefaultDest();
+  assert(DefaultBlock->empty() &&
+         "EmitDefaultStmt: Default block already defined?");
+  EmitBlock(DefaultBlock);
+  EmitStmt(S.getSubStmt());
+}
+
+void CodeGenFunction::EmitSwitchStmt(const SwitchStmt &S) {
+  CleanupScope ConditionScope(*this);
+
+  if (S.getConditionVariable())
+    EmitLocalBlockVarDecl(*S.getConditionVariable());
+
+  llvm::Value *CondV = EmitScalarExpr(S.getCond());
+
+  // Handle nested switch statements.
+  llvm::SwitchInst *SavedSwitchInsn = SwitchInsn;
+  llvm::BasicBlock *SavedCRBlock = CaseRangeBlock;
+
+  // Create basic block to hold stuff that comes after switch
+  // statement. We also need to create a default block now so that
+  // explicit case ranges tests can have a place to jump to on
+  // failure.
+  llvm::BasicBlock *NextBlock = createBasicBlock("sw.epilog");
+  llvm::BasicBlock *DefaultBlock = createBasicBlock("sw.default");
+  SwitchInsn = Builder.CreateSwitch(CondV, DefaultBlock);
+  CaseRangeBlock = DefaultBlock;
+
+  // Clear the insertion point to indicate we are in unreachable code.
+  Builder.ClearInsertionPoint();
+
+  // All break statements jump to NextBlock. If BreakContinueStack is non empty
+  // then reuse last ContinueBlock.
+  llvm::BasicBlock *ContinueBlock = 0;
+  if (!BreakContinueStack.empty())
+    ContinueBlock = BreakContinueStack.back().ContinueBlock;
+
+  // Ensure any vlas created between there and here, are undone
+  BreakContinueStack.push_back(BreakContinue(NextBlock, ContinueBlock));
+
+  // Emit switch body.
+  EmitStmt(S.getBody());
+
+  BreakContinueStack.pop_back();
+
+  // Update the default block in case explicit case range tests have
+  // been chained on top.
+  SwitchInsn->setSuccessor(0, CaseRangeBlock);
+
+  // If a default was never emitted then reroute any jumps to it and
+  // discard.
+  if (!DefaultBlock->getParent()) {
+    DefaultBlock->replaceAllUsesWith(NextBlock);
+    delete DefaultBlock;
+  }
+
+  // Emit continuation.
+  EmitBlock(NextBlock, true);
+
+  SwitchInsn = SavedSwitchInsn;
+  CaseRangeBlock = SavedCRBlock;
+}
+
+static std::string
+SimplifyConstraint(const char *Constraint, const TargetInfo &Target,
+                 llvm::SmallVectorImpl<TargetInfo::ConstraintInfo> *OutCons=0) {
+  std::string Result;
+
+  while (*Constraint) {
+    switch (*Constraint) {
+    default:
+      Result += Target.convertConstraint(*Constraint);
+      break;
+    // Ignore these
+    case '*':
+    case '?':
+    case '!':
+      break;
+    case 'g':
+      Result += "imr";
+      break;
+    case '[': {
+      assert(OutCons &&
+             "Must pass output names to constraints with a symbolic name");
+      unsigned Index;
+      bool result = Target.resolveSymbolicName(Constraint,
+                                               &(*OutCons)[0],
+                                               OutCons->size(), Index);
+      assert(result && "Could not resolve symbolic name"); result=result;
+      Result += llvm::utostr(Index);
+      break;
+    }
+    }
+
+    Constraint++;
+  }
+
+  return Result;
+}
+
+llvm::Value* CodeGenFunction::EmitAsmInput(const AsmStmt &S,
+                                         const TargetInfo::ConstraintInfo &Info,
+                                           const Expr *InputExpr,
+                                           std::string &ConstraintStr) {
+  llvm::Value *Arg;
+  if (Info.allowsRegister() || !Info.allowsMemory()) {
+    if (!CodeGenFunction::hasAggregateLLVMType(InputExpr->getType())) {
+      Arg = EmitScalarExpr(InputExpr);
+    } else {
+      InputExpr = InputExpr->IgnoreParenNoopCasts(getContext());
+      LValue Dest = EmitLValue(InputExpr);
+
+      const llvm::Type *Ty = ConvertType(InputExpr->getType());
+      uint64_t Size = CGM.getTargetData().getTypeSizeInBits(Ty);
+      if (Size <= 64 && llvm::isPowerOf2_64(Size)) {
+        Ty = llvm::IntegerType::get(VMContext, Size);
+        Ty = llvm::PointerType::getUnqual(Ty);
+
+        Arg = Builder.CreateLoad(Builder.CreateBitCast(Dest.getAddress(), Ty));
+      } else {
+        Arg = Dest.getAddress();
+        ConstraintStr += '*';
+      }
+    }
+  } else {
+    InputExpr = InputExpr->IgnoreParenNoopCasts(getContext());
+    LValue Dest = EmitLValue(InputExpr);
+    Arg = Dest.getAddress();
+    ConstraintStr += '*';
+  }
+
+  return Arg;
+}
+
+void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {
+  // Analyze the asm string to decompose it into its pieces.  We know that Sema
+  // has already done this, so it is guaranteed to be successful.
+  llvm::SmallVector<AsmStmt::AsmStringPiece, 4> Pieces;
+  unsigned DiagOffs;
+  S.AnalyzeAsmString(Pieces, getContext(), DiagOffs);
+
+  // Assemble the pieces into the final asm string.
+  std::string AsmString;
+  for (unsigned i = 0, e = Pieces.size(); i != e; ++i) {
+    if (Pieces[i].isString())
+      AsmString += Pieces[i].getString();
+    else if (Pieces[i].getModifier() == '\0')
+      AsmString += '$' + llvm::utostr(Pieces[i].getOperandNo());
+    else
+      AsmString += "${" + llvm::utostr(Pieces[i].getOperandNo()) + ':' +
+                   Pieces[i].getModifier() + '}';
+  }
+
+  // Get all the output and input constraints together.
+  llvm::SmallVector<TargetInfo::ConstraintInfo, 4> OutputConstraintInfos;
+  llvm::SmallVector<TargetInfo::ConstraintInfo, 4> InputConstraintInfos;
+
+  for (unsigned i = 0, e = S.getNumOutputs(); i != e; i++) {
+    TargetInfo::ConstraintInfo Info(S.getOutputConstraint(i),
+                                    S.getOutputName(i));
+    bool IsValid = Target.validateOutputConstraint(Info); (void)IsValid;
+    assert(IsValid && "Failed to parse output constraint"); 
+    OutputConstraintInfos.push_back(Info);
+  }
+
+  for (unsigned i = 0, e = S.getNumInputs(); i != e; i++) {
+    TargetInfo::ConstraintInfo Info(S.getInputConstraint(i),
+                                    S.getInputName(i));
+    bool IsValid = Target.validateInputConstraint(OutputConstraintInfos.data(),
+                                                  S.getNumOutputs(), Info);
+    assert(IsValid && "Failed to parse input constraint"); (void)IsValid;
+    InputConstraintInfos.push_back(Info);
+  }
+
+  std::string Constraints;
+
+  std::vector<LValue> ResultRegDests;
+  std::vector<QualType> ResultRegQualTys;
+  std::vector<const llvm::Type *> ResultRegTypes;
+  std::vector<const llvm::Type *> ResultTruncRegTypes;
+  std::vector<const llvm::Type*> ArgTypes;
+  std::vector<llvm::Value*> Args;
+
+  // Keep track of inout constraints.
+  std::string InOutConstraints;
+  std::vector<llvm::Value*> InOutArgs;
+  std::vector<const llvm::Type*> InOutArgTypes;
+
+  for (unsigned i = 0, e = S.getNumOutputs(); i != e; i++) {
+    TargetInfo::ConstraintInfo &Info = OutputConstraintInfos[i];
+
+    // Simplify the output constraint.
+    std::string OutputConstraint(S.getOutputConstraint(i));
+    OutputConstraint = SimplifyConstraint(OutputConstraint.c_str() + 1, Target);
+
+    const Expr *OutExpr = S.getOutputExpr(i);
+    OutExpr = OutExpr->IgnoreParenNoopCasts(getContext());
+
+    LValue Dest = EmitLValue(OutExpr);
+    if (!Constraints.empty())
+      Constraints += ',';
+
+    // If this is a register output, then make the inline asm return it
+    // by-value.  If this is a memory result, return the value by-reference.
+    if (!Info.allowsMemory() && !hasAggregateLLVMType(OutExpr->getType())) {
+      Constraints += "=" + OutputConstraint;
+      ResultRegQualTys.push_back(OutExpr->getType());
+      ResultRegDests.push_back(Dest);
+      ResultRegTypes.push_back(ConvertTypeForMem(OutExpr->getType()));
+      ResultTruncRegTypes.push_back(ResultRegTypes.back());
+
+      // If this output is tied to an input, and if the input is larger, then
+      // we need to set the actual result type of the inline asm node to be the
+      // same as the input type.
+      if (Info.hasMatchingInput()) {
+        unsigned InputNo;
+        for (InputNo = 0; InputNo != S.getNumInputs(); ++InputNo) {
+          TargetInfo::ConstraintInfo &Input = InputConstraintInfos[InputNo];
+          if (Input.hasTiedOperand() && Input.getTiedOperand() == i)
+            break;
+        }
+        assert(InputNo != S.getNumInputs() && "Didn't find matching input!");
+
+        QualType InputTy = S.getInputExpr(InputNo)->getType();
+        QualType OutputType = OutExpr->getType();
+
+        uint64_t InputSize = getContext().getTypeSize(InputTy);
+        if (getContext().getTypeSize(OutputType) < InputSize) {
+          // Form the asm to return the value as a larger integer or fp type.
+          ResultRegTypes.back() = ConvertType(InputTy);
+        }
+      }
+    } else {
+      ArgTypes.push_back(Dest.getAddress()->getType());
+      Args.push_back(Dest.getAddress());
+      Constraints += "=*";
+      Constraints += OutputConstraint;
+    }
+
+    if (Info.isReadWrite()) {
+      InOutConstraints += ',';
+
+      const Expr *InputExpr = S.getOutputExpr(i);
+      llvm::Value *Arg = EmitAsmInput(S, Info, InputExpr, InOutConstraints);
+
+      if (Info.allowsRegister())
+        InOutConstraints += llvm::utostr(i);
+      else
+        InOutConstraints += OutputConstraint;
+
+      InOutArgTypes.push_back(Arg->getType());
+      InOutArgs.push_back(Arg);
+    }
+  }
+
+  unsigned NumConstraints = S.getNumOutputs() + S.getNumInputs();
+
+  for (unsigned i = 0, e = S.getNumInputs(); i != e; i++) {
+    const Expr *InputExpr = S.getInputExpr(i);
+
+    TargetInfo::ConstraintInfo &Info = InputConstraintInfos[i];
+
+    if (!Constraints.empty())
+      Constraints += ',';
+
+    // Simplify the input constraint.
+    std::string InputConstraint(S.getInputConstraint(i));
+    InputConstraint = SimplifyConstraint(InputConstraint.c_str(), Target,
+                                         &OutputConstraintInfos);
+
+    llvm::Value *Arg = EmitAsmInput(S, Info, InputExpr, Constraints);
+
+    // If this input argument is tied to a larger output result, extend the
+    // input to be the same size as the output.  The LLVM backend wants to see
+    // the input and output of a matching constraint be the same size.  Note
+    // that GCC does not define what the top bits are here.  We use zext because
+    // that is usually cheaper, but LLVM IR should really get an anyext someday.
+    if (Info.hasTiedOperand()) {
+      unsigned Output = Info.getTiedOperand();
+      QualType OutputType = S.getOutputExpr(Output)->getType();
+      QualType InputTy = InputExpr->getType();
+
+      if (getContext().getTypeSize(OutputType) >
+          getContext().getTypeSize(InputTy)) {
+        // Use ptrtoint as appropriate so that we can do our extension.
+        if (isa<llvm::PointerType>(Arg->getType()))
+          Arg = Builder.CreatePtrToInt(Arg,
+                           llvm::IntegerType::get(VMContext, LLVMPointerWidth));
+        const llvm::Type *OutputTy = ConvertType(OutputType);
+        if (isa<llvm::IntegerType>(OutputTy))
+          Arg = Builder.CreateZExt(Arg, OutputTy);
+        else
+          Arg = Builder.CreateFPExt(Arg, OutputTy);
+      }
+    }
+
+
+    ArgTypes.push_back(Arg->getType());
+    Args.push_back(Arg);
+    Constraints += InputConstraint;
+  }
+
+  // Append the "input" part of inout constraints last.
+  for (unsigned i = 0, e = InOutArgs.size(); i != e; i++) {
+    ArgTypes.push_back(InOutArgTypes[i]);
+    Args.push_back(InOutArgs[i]);
+  }
+  Constraints += InOutConstraints;
+
+  // Clobbers
+  for (unsigned i = 0, e = S.getNumClobbers(); i != e; i++) {
+    llvm::StringRef Clobber = S.getClobber(i)->getString();
+
+    Clobber = Target.getNormalizedGCCRegisterName(Clobber);
+
+    if (i != 0 || NumConstraints != 0)
+      Constraints += ',';
+
+    Constraints += "~{";
+    Constraints += Clobber;
+    Constraints += '}';
+  }
+
+  // Add machine specific clobbers
+  std::string MachineClobbers = Target.getClobbers();
+  if (!MachineClobbers.empty()) {
+    if (!Constraints.empty())
+      Constraints += ',';
+    Constraints += MachineClobbers;
+  }
+
+  const llvm::Type *ResultType;
+  if (ResultRegTypes.empty())
+    ResultType = llvm::Type::getVoidTy(VMContext);
+  else if (ResultRegTypes.size() == 1)
+    ResultType = ResultRegTypes[0];
+  else
+    ResultType = llvm::StructType::get(VMContext, ResultRegTypes);
+
+  const llvm::FunctionType *FTy =
+    llvm::FunctionType::get(ResultType, ArgTypes, false);
+
+  llvm::InlineAsm *IA =
+    llvm::InlineAsm::get(FTy, AsmString, Constraints,
+                         S.isVolatile() || S.getNumOutputs() == 0);
+  llvm::CallInst *Result = Builder.CreateCall(IA, Args.begin(), Args.end());
+  Result->addAttribute(~0, llvm::Attribute::NoUnwind);
+
+  // Slap the source location of the inline asm into a !srcloc metadata on the
+  // call.
+  unsigned LocID = S.getAsmString()->getLocStart().getRawEncoding();
+  llvm::Value *LocIDC =
+    llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), LocID);
+  Result->setMetadata("srcloc", llvm::MDNode::get(VMContext, &LocIDC, 1));
+
+  // Extract all of the register value results from the asm.
+  std::vector<llvm::Value*> RegResults;
+  if (ResultRegTypes.size() == 1) {
+    RegResults.push_back(Result);
+  } else {
+    for (unsigned i = 0, e = ResultRegTypes.size(); i != e; ++i) {
+      llvm::Value *Tmp = Builder.CreateExtractValue(Result, i, "asmresult");
+      RegResults.push_back(Tmp);
+    }
+  }
+
+  for (unsigned i = 0, e = RegResults.size(); i != e; ++i) {
+    llvm::Value *Tmp = RegResults[i];
+
+    // If the result type of the LLVM IR asm doesn't match the result type of
+    // the expression, do the conversion.
+    if (ResultRegTypes[i] != ResultTruncRegTypes[i]) {
+      const llvm::Type *TruncTy = ResultTruncRegTypes[i];
+      
+      // Truncate the integer result to the right size, note that TruncTy can be
+      // a pointer.
+      if (TruncTy->isFloatingPointTy())
+        Tmp = Builder.CreateFPTrunc(Tmp, TruncTy);
+      else if (TruncTy->isPointerTy() && Tmp->getType()->isIntegerTy()) {
+        uint64_t ResSize = CGM.getTargetData().getTypeSizeInBits(TruncTy);
+        Tmp = Builder.CreateTrunc(Tmp, llvm::IntegerType::get(VMContext,
+                                                            (unsigned)ResSize));
+        Tmp = Builder.CreateIntToPtr(Tmp, TruncTy);
+      } else if (Tmp->getType()->isPointerTy() && TruncTy->isIntegerTy()) {
+        uint64_t TmpSize =CGM.getTargetData().getTypeSizeInBits(Tmp->getType());
+        Tmp = Builder.CreatePtrToInt(Tmp, llvm::IntegerType::get(VMContext,
+                                                            (unsigned)TmpSize));
+        Tmp = Builder.CreateTrunc(Tmp, TruncTy);
+      } else if (TruncTy->isIntegerTy()) {
+        Tmp = Builder.CreateTrunc(Tmp, TruncTy);
+      }
+    }
+
+    EmitStoreThroughLValue(RValue::get(Tmp), ResultRegDests[i],
+                           ResultRegQualTys[i]);
+  }
+}
diff --git a/lib/CodeGen/CGTemporaries.cpp b/lib/CodeGen/CGTemporaries.cpp
new file mode 100644
index 0000000..d6d3be5
--- /dev/null
+++ b/lib/CodeGen/CGTemporaries.cpp
@@ -0,0 +1,159 @@
+//===--- CGTemporaries.cpp - Emit LLVM Code for C++ temporaries -----------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This contains code dealing with C++ code generation of temporaries
+//
+//===----------------------------------------------------------------------===//
+
+#include "CodeGenFunction.h"
+using namespace clang;
+using namespace CodeGen;
+
+void CodeGenFunction::PushCXXTemporary(const CXXTemporary *Temporary,
+                                       llvm::Value *Ptr) {
+  assert((LiveTemporaries.empty() ||
+          LiveTemporaries.back().ThisPtr != Ptr ||
+          ConditionalBranchLevel) &&
+         "Pushed the same temporary twice; AST is likely wrong");
+  llvm::BasicBlock *DtorBlock = createBasicBlock("temp.dtor");
+
+  llvm::AllocaInst *CondPtr = 0;
+
+  // Check if temporaries need to be conditional. If so, we'll create a
+  // condition boolean, initialize it to 0 and
+  if (ConditionalBranchLevel != 0) {
+    CondPtr = CreateTempAlloca(llvm::Type::getInt1Ty(VMContext), "cond");
+
+    // Initialize it to false. This initialization takes place right after
+    // the alloca insert point.
+    InitTempAlloca(CondPtr, llvm::ConstantInt::getFalse(VMContext));
+
+    // Now set it to true.
+    Builder.CreateStore(llvm::ConstantInt::getTrue(VMContext), CondPtr);
+  }
+
+  LiveTemporaries.push_back(CXXLiveTemporaryInfo(Temporary, Ptr, DtorBlock,
+                                                 CondPtr));
+
+  PushCleanupBlock(DtorBlock);
+
+  if (Exceptions) {
+    const CXXLiveTemporaryInfo& Info = LiveTemporaries.back();
+    llvm::BasicBlock *CondEnd = 0;
+    
+    EHCleanupBlock Cleanup(*this);
+
+    // If this is a conditional temporary, we need to check the condition
+    // boolean and only call the destructor if it's true.
+    if (Info.CondPtr) {
+      llvm::BasicBlock *CondBlock = createBasicBlock("cond.dtor.call");
+      CondEnd = createBasicBlock("cond.dtor.end");
+
+      llvm::Value *Cond = Builder.CreateLoad(Info.CondPtr);
+      Builder.CreateCondBr(Cond, CondBlock, CondEnd);
+      EmitBlock(CondBlock);
+    }
+
+    EmitCXXDestructorCall(Info.Temporary->getDestructor(),
+                          Dtor_Complete, Info.ThisPtr);
+
+    if (CondEnd) {
+      // Reset the condition. to false.
+      Builder.CreateStore(llvm::ConstantInt::getFalse(VMContext), Info.CondPtr);
+      EmitBlock(CondEnd);
+    }
+  }
+}
+
+void CodeGenFunction::PopCXXTemporary() {
+  const CXXLiveTemporaryInfo& Info = LiveTemporaries.back();
+
+  CleanupBlockInfo CleanupInfo = PopCleanupBlock();
+  assert(CleanupInfo.CleanupBlock == Info.DtorBlock &&
+         "Cleanup block mismatch!");
+  assert(!CleanupInfo.SwitchBlock &&
+         "Should not have a switch block for temporary cleanup!");
+  assert(!CleanupInfo.EndBlock &&
+         "Should not have an end block for temporary cleanup!");
+
+  llvm::BasicBlock *CurBB = Builder.GetInsertBlock();
+  if (CurBB && !CurBB->getTerminator() &&
+      Info.DtorBlock->getNumUses() == 0) {
+    CurBB->getInstList().splice(CurBB->end(), Info.DtorBlock->getInstList());
+    delete Info.DtorBlock;
+  } else
+    EmitBlock(Info.DtorBlock);
+
+  llvm::BasicBlock *CondEnd = 0;
+
+  // If this is a conditional temporary, we need to check the condition
+  // boolean and only call the destructor if it's true.
+  if (Info.CondPtr) {
+    llvm::BasicBlock *CondBlock = createBasicBlock("cond.dtor.call");
+    CondEnd = createBasicBlock("cond.dtor.end");
+
+    llvm::Value *Cond = Builder.CreateLoad(Info.CondPtr);
+    Builder.CreateCondBr(Cond, CondBlock, CondEnd);
+    EmitBlock(CondBlock);
+  }
+
+  EmitCXXDestructorCall(Info.Temporary->getDestructor(),
+                        Dtor_Complete, Info.ThisPtr);
+
+  if (CondEnd) {
+    // Reset the condition. to false.
+    Builder.CreateStore(llvm::ConstantInt::getFalse(VMContext), Info.CondPtr);
+    EmitBlock(CondEnd);
+  }
+
+  LiveTemporaries.pop_back();
+}
+
+RValue
+CodeGenFunction::EmitCXXExprWithTemporaries(const CXXExprWithTemporaries *E,
+                                            llvm::Value *AggLoc,
+                                            bool IsAggLocVolatile,
+                                            bool IsInitializer) {
+  // Keep track of the current cleanup stack depth.
+  size_t CleanupStackDepth = CleanupEntries.size();
+  (void) CleanupStackDepth;
+
+  RValue RV;
+  
+  {
+    CXXTemporariesCleanupScope Scope(*this);
+
+    RV = EmitAnyExpr(E->getSubExpr(), AggLoc, IsAggLocVolatile,
+                     /*IgnoreResult=*/false, IsInitializer);
+  }
+  assert(CleanupEntries.size() == CleanupStackDepth &&
+         "Cleanup size mismatch!");
+
+  return RV;
+}
+
+LValue CodeGenFunction::EmitCXXExprWithTemporariesLValue(
+                                              const CXXExprWithTemporaries *E) {
+  // Keep track of the current cleanup stack depth.
+  size_t CleanupStackDepth = CleanupEntries.size();
+  (void) CleanupStackDepth;
+
+  unsigned OldNumLiveTemporaries = LiveTemporaries.size();
+
+  LValue LV = EmitLValue(E->getSubExpr());
+
+  // Pop temporaries.
+  while (LiveTemporaries.size() > OldNumLiveTemporaries)
+    PopCXXTemporary();
+
+  assert(CleanupEntries.size() == CleanupStackDepth &&
+         "Cleanup size mismatch!");
+
+  return LV;
+}
diff --git a/lib/CodeGen/CGVTT.cpp b/lib/CodeGen/CGVTT.cpp
new file mode 100644
index 0000000..68bb655
--- /dev/null
+++ b/lib/CodeGen/CGVTT.cpp
@@ -0,0 +1,488 @@
+//===--- CGVTT.cpp - Emit LLVM Code for C++ VTTs --------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This contains code dealing with C++ code generation of VTTs (vtable tables).
+//
+//===----------------------------------------------------------------------===//
+
+#include "CodeGenModule.h"
+#include "clang/AST/RecordLayout.h"
+using namespace clang;
+using namespace CodeGen;
+
+#define D1(x)
+
+namespace {
+
+/// VTT builder - Class for building VTT layout information.
+class VTTBuilder {
+  
+  CodeGenModule &CGM;
+
+  /// MostDerivedClass - The most derived class for which we're building this
+  /// vtable.
+  const CXXRecordDecl *MostDerivedClass;
+
+  typedef llvm::SmallVector<llvm::Constant *, 64> VTTComponentsVectorTy;
+  
+  /// VTTComponents - The VTT components.
+  VTTComponentsVectorTy VTTComponents;
+  
+  /// MostDerivedClassLayout - the AST record layout of the most derived class.
+  const ASTRecordLayout &MostDerivedClassLayout;
+
+  typedef llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBasesSetTy;
+
+  typedef llvm::DenseMap<BaseSubobject, uint64_t> AddressPointsMapTy;
+
+  /// SubVTTIndicies - The sub-VTT indices for the bases of the most derived
+  /// class.
+  llvm::DenseMap<const CXXRecordDecl *, uint64_t> SubVTTIndicies;
+
+  /// SecondaryVirtualPointerIndices - The secondary virtual pointer indices of
+  /// all subobjects of the most derived class.
+  llvm::DenseMap<BaseSubobject, uint64_t> SecondaryVirtualPointerIndices;
+
+  /// GenerateDefinition - Whether the VTT builder should generate LLVM IR for
+  /// the VTT.
+  bool GenerateDefinition;
+  
+  /// GetAddrOfVTable - Returns the address of the vtable for the base class in
+  /// the given vtable class.
+  ///
+  /// \param AddressPoints - If the returned vtable is a construction vtable,
+  /// this will hold the address points for it.
+  llvm::Constant *GetAddrOfVTable(BaseSubobject Base, bool BaseIsVirtual,
+                                  AddressPointsMapTy& AddressPoints);
+
+  /// AddVTablePointer - Add a vtable pointer to the VTT currently being built.
+  ///
+  /// \param AddressPoints - If the vtable is a construction vtable, this has
+  /// the address points for it.
+  void AddVTablePointer(BaseSubobject Base, llvm::Constant *VTable,
+                        const CXXRecordDecl *VTableClass,
+                        const AddressPointsMapTy& AddressPoints);
+                        
+  /// LayoutSecondaryVTTs - Lay out the secondary VTTs of the given base 
+  /// subobject.
+  void LayoutSecondaryVTTs(BaseSubobject Base);
+  
+  /// LayoutSecondaryVirtualPointers - Lay out the secondary virtual pointers
+  /// for the given base subobject.
+  ///
+  /// \param BaseIsMorallyVirtual whether the base subobject is a virtual base
+  /// or a direct or indirect base of a virtual base.
+  ///
+  /// \param AddressPoints - If the vtable is a construction vtable, this has
+  /// the address points for it.
+  void LayoutSecondaryVirtualPointers(BaseSubobject Base, 
+                                      bool BaseIsMorallyVirtual,
+                                      llvm::Constant *VTable,
+                                      const CXXRecordDecl *VTableClass,
+                                      const AddressPointsMapTy& AddressPoints,
+                                      VisitedVirtualBasesSetTy &VBases);
+  
+  /// LayoutSecondaryVirtualPointers - Lay out the secondary virtual pointers
+  /// for the given base subobject.
+  ///
+  /// \param AddressPoints - If the vtable is a construction vtable, this has
+  /// the address points for it.
+  void LayoutSecondaryVirtualPointers(BaseSubobject Base, 
+                                      llvm::Constant *VTable,
+                                      const AddressPointsMapTy& AddressPoints);
+
+  /// LayoutVirtualVTTs - Lay out the VTTs for the virtual base classes of the
+  /// given record decl.
+  void LayoutVirtualVTTs(const CXXRecordDecl *RD,
+                         VisitedVirtualBasesSetTy &VBases);
+  
+  /// LayoutVTT - Will lay out the VTT for the given subobject, including any
+  /// secondary VTTs, secondary virtual pointers and virtual VTTs.
+  void LayoutVTT(BaseSubobject Base, bool BaseIsVirtual);
+  
+public:
+  VTTBuilder(CodeGenModule &CGM, const CXXRecordDecl *MostDerivedClass,
+             bool GenerateDefinition);
+
+  // getVTTComponents - Returns a reference to the VTT components.
+  const VTTComponentsVectorTy &getVTTComponents() const {
+    return VTTComponents;
+  }
+  
+  /// getSubVTTIndicies - Returns a reference to the sub-VTT indices.
+  const llvm::DenseMap<const CXXRecordDecl *, uint64_t> &
+  getSubVTTIndicies() const {
+    return SubVTTIndicies;
+  }
+  
+  /// getSecondaryVirtualPointerIndices - Returns a reference to the secondary
+  /// virtual pointer indices.
+  const llvm::DenseMap<BaseSubobject, uint64_t> &
+  getSecondaryVirtualPointerIndices() const {
+    return SecondaryVirtualPointerIndices;
+  }
+
+};
+
+VTTBuilder::VTTBuilder(CodeGenModule &CGM,
+                       const CXXRecordDecl *MostDerivedClass,
+                       bool GenerateDefinition)
+  : CGM(CGM), MostDerivedClass(MostDerivedClass), 
+  MostDerivedClassLayout(CGM.getContext().getASTRecordLayout(MostDerivedClass)),
+  GenerateDefinition(GenerateDefinition) {
+    
+  // Lay out this VTT.
+  LayoutVTT(BaseSubobject(MostDerivedClass, 0), /*BaseIsVirtual=*/false);
+}
+
+llvm::Constant *
+VTTBuilder::GetAddrOfVTable(BaseSubobject Base, bool BaseIsVirtual, 
+                            AddressPointsMapTy& AddressPoints) {
+  if (!GenerateDefinition)
+    return 0;
+  
+  if (Base.getBase() == MostDerivedClass) {
+    assert(Base.getBaseOffset() == 0 &&
+           "Most derived class vtable must have a zero offset!");
+    // This is a regular vtable.
+    return CGM.getVTables().GetAddrOfVTable(MostDerivedClass);
+  }
+  
+  return CGM.getVTables().GenerateConstructionVTable(MostDerivedClass, 
+                                                     Base, BaseIsVirtual,
+                                                     AddressPoints);
+}
+
+void VTTBuilder::AddVTablePointer(BaseSubobject Base, llvm::Constant *VTable,
+                                  const CXXRecordDecl *VTableClass,
+                                  const AddressPointsMapTy& AddressPoints) {
+  // Store the vtable pointer index if we're generating the primary VTT.
+  if (VTableClass == MostDerivedClass) {
+    assert(!SecondaryVirtualPointerIndices.count(Base) &&
+           "A virtual pointer index already exists for this base subobject!");
+    SecondaryVirtualPointerIndices[Base] = VTTComponents.size();
+  }
+
+  if (!GenerateDefinition) {
+    VTTComponents.push_back(0);
+    return;
+  }
+
+  uint64_t AddressPoint;
+  if (VTableClass != MostDerivedClass) {
+    // The vtable is a construction vtable, look in the construction vtable
+    // address points.
+    AddressPoint = AddressPoints.lookup(Base);
+    assert(AddressPoint != 0 && "Did not find ctor vtable address point!");
+  } else {
+    // Just get the address point for the regular vtable.
+    AddressPoint = CGM.getVTables().getAddressPoint(Base, VTableClass);
+    assert(AddressPoint != 0 && "Did not find vtable address point!");
+  }
+
+  if (!AddressPoint) AddressPoint = 0;
+  
+  llvm::Value *Idxs[] = {
+    llvm::ConstantInt::get(llvm::Type::getInt64Ty(CGM.getLLVMContext()), 0),
+    llvm::ConstantInt::get(llvm::Type::getInt64Ty(CGM.getLLVMContext()), 
+                           AddressPoint)
+  };
+  
+  llvm::Constant *Init = 
+    llvm::ConstantExpr::getInBoundsGetElementPtr(VTable, Idxs, 2);
+  
+  const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
+  Init = llvm::ConstantExpr::getBitCast(Init, Int8PtrTy);
+  
+  VTTComponents.push_back(Init);
+}
+
+void VTTBuilder::LayoutSecondaryVTTs(BaseSubobject Base) {
+  const CXXRecordDecl *RD = Base.getBase();
+
+  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
+       E = RD->bases_end(); I != E; ++I) {
+    
+    // Don't layout virtual bases.
+    if (I->isVirtual())
+        continue;
+
+    const CXXRecordDecl *BaseDecl =
+      cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+
+    const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
+    uint64_t BaseOffset = Base.getBaseOffset() + 
+      Layout.getBaseClassOffset(BaseDecl);
+   
+    // Layout the VTT for this base.
+    LayoutVTT(BaseSubobject(BaseDecl, BaseOffset), /*BaseIsVirtual=*/false);
+  }
+}
+
+void
+VTTBuilder::LayoutSecondaryVirtualPointers(BaseSubobject Base, 
+                                        bool BaseIsMorallyVirtual,
+                                        llvm::Constant *VTable,
+                                        const CXXRecordDecl *VTableClass,
+                                        const AddressPointsMapTy& AddressPoints,
+                                        VisitedVirtualBasesSetTy &VBases) {
+  const CXXRecordDecl *RD = Base.getBase();
+  
+  // We're not interested in bases that don't have virtual bases, and not
+  // morally virtual bases.
+  if (!RD->getNumVBases() && !BaseIsMorallyVirtual)
+    return;
+
+  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
+       E = RD->bases_end(); I != E; ++I) {
+    const CXXRecordDecl *BaseDecl =
+      cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+
+    // Itanium C++ ABI 2.6.2:
+    //   Secondary virtual pointers are present for all bases with either
+    //   virtual bases or virtual function declarations overridden along a 
+    //   virtual path.
+    //
+    // If the base class is not dynamic, we don't want to add it, nor any
+    // of its base classes.
+    if (!BaseDecl->isDynamicClass())
+      continue;
+    
+    bool BaseDeclIsMorallyVirtual = BaseIsMorallyVirtual;
+    bool BaseDeclIsNonVirtualPrimaryBase = false;
+    uint64_t BaseOffset;
+    if (I->isVirtual()) {
+      // Ignore virtual bases that we've already visited.
+      if (!VBases.insert(BaseDecl))
+        continue;
+      
+      BaseOffset = MostDerivedClassLayout.getVBaseClassOffset(BaseDecl);
+      BaseDeclIsMorallyVirtual = true;
+    } else {
+      const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
+      
+      BaseOffset = Base.getBaseOffset() + Layout.getBaseClassOffset(BaseDecl);
+      
+      if (!Layout.getPrimaryBaseWasVirtual() &&
+          Layout.getPrimaryBase() == BaseDecl)
+        BaseDeclIsNonVirtualPrimaryBase = true;
+    }
+
+    // Itanium C++ ABI 2.6.2:
+    //   Secondary virtual pointers: for each base class X which (a) has virtual
+    //   bases or is reachable along a virtual path from D, and (b) is not a
+    //   non-virtual primary base, the address of the virtual table for X-in-D
+    //   or an appropriate construction virtual table.
+    if (!BaseDeclIsNonVirtualPrimaryBase &&
+        (BaseDecl->getNumVBases() || BaseDeclIsMorallyVirtual)) {
+      // Add the vtable pointer.
+      AddVTablePointer(BaseSubobject(BaseDecl, BaseOffset), VTable, VTableClass, 
+                       AddressPoints);
+    }
+
+    // And lay out the secondary virtual pointers for the base class.
+    LayoutSecondaryVirtualPointers(BaseSubobject(BaseDecl, BaseOffset),
+                                   BaseDeclIsMorallyVirtual, VTable, 
+                                   VTableClass, AddressPoints, VBases);
+  }
+}
+
+void 
+VTTBuilder::LayoutSecondaryVirtualPointers(BaseSubobject Base, 
+                                      llvm::Constant *VTable,
+                                      const AddressPointsMapTy& AddressPoints) {
+  VisitedVirtualBasesSetTy VBases;
+  LayoutSecondaryVirtualPointers(Base, /*BaseIsMorallyVirtual=*/false,
+                                 VTable, Base.getBase(), AddressPoints, VBases);
+}
+
+void VTTBuilder::LayoutVirtualVTTs(const CXXRecordDecl *RD,
+                                   VisitedVirtualBasesSetTy &VBases) {
+  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
+       E = RD->bases_end(); I != E; ++I) {
+    const CXXRecordDecl *BaseDecl = 
+      cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+    
+    // Check if this is a virtual base.
+    if (I->isVirtual()) {
+      // Check if we've seen this base before.
+      if (!VBases.insert(BaseDecl))
+        continue;
+    
+      uint64_t BaseOffset = 
+        MostDerivedClassLayout.getVBaseClassOffset(BaseDecl);
+      
+      LayoutVTT(BaseSubobject(BaseDecl, BaseOffset), /*BaseIsVirtual=*/true);
+    }
+    
+    // We only need to layout virtual VTTs for this base if it actually has
+    // virtual bases.
+    if (BaseDecl->getNumVBases())
+      LayoutVirtualVTTs(BaseDecl, VBases);
+  }
+}
+
+void VTTBuilder::LayoutVTT(BaseSubobject Base, bool BaseIsVirtual) {
+  const CXXRecordDecl *RD = Base.getBase();
+
+  // Itanium C++ ABI 2.6.2:
+  //   An array of virtual table addresses, called the VTT, is declared for 
+  //   each class type that has indirect or direct virtual base classes.
+  if (RD->getNumVBases() == 0)
+    return;
+
+  bool IsPrimaryVTT = Base.getBase() == MostDerivedClass;
+
+  if (!IsPrimaryVTT) {
+    // Remember the sub-VTT index.
+    SubVTTIndicies[RD] = VTTComponents.size();
+  }
+
+  AddressPointsMapTy AddressPoints;
+  llvm::Constant *VTable = GetAddrOfVTable(Base, BaseIsVirtual, AddressPoints);
+
+  // Add the primary vtable pointer.
+  AddVTablePointer(Base, VTable, RD, AddressPoints);
+
+  // Add the secondary VTTs.
+  LayoutSecondaryVTTs(Base);
+  
+  // Add the secondary virtual pointers.
+  LayoutSecondaryVirtualPointers(Base, VTable, AddressPoints);
+  
+  // If this is the primary VTT, we want to lay out virtual VTTs as well.
+  if (IsPrimaryVTT) {
+    VisitedVirtualBasesSetTy VBases;
+    LayoutVirtualVTTs(Base.getBase(), VBases);
+  }
+}
+  
+}
+
+llvm::GlobalVariable *
+CodeGenVTables::GenerateVTT(llvm::GlobalVariable::LinkageTypes Linkage,
+                            bool GenerateDefinition,
+                            const CXXRecordDecl *RD) {
+  // Only classes that have virtual bases need a VTT.
+  if (RD->getNumVBases() == 0)
+    return 0;
+
+  llvm::SmallString<256> OutName;
+  CGM.getMangleContext().mangleCXXVTT(RD, OutName);
+  llvm::StringRef Name = OutName.str();
+
+  D1(printf("vtt %s\n", RD->getNameAsCString()));
+
+  llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
+  if (GV == 0 || GV->isDeclaration()) {
+    const llvm::Type *Int8PtrTy = 
+      llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
+
+    VTTBuilder Builder(CGM, RD, GenerateDefinition);
+
+    const llvm::ArrayType *Type = 
+      llvm::ArrayType::get(Int8PtrTy, Builder.getVTTComponents().size());
+
+    llvm::Constant *Init = 0;
+    if (GenerateDefinition)
+      Init = llvm::ConstantArray::get(Type, Builder.getVTTComponents().data(),
+                                      Builder.getVTTComponents().size());
+
+    llvm::GlobalVariable *OldGV = GV;
+    GV = new llvm::GlobalVariable(CGM.getModule(), Type, /*isConstant=*/true, 
+                                  Linkage, Init, Name);
+    CGM.setGlobalVisibility(GV, RD);
+    
+    if (OldGV) {
+      GV->takeName(OldGV);
+      llvm::Constant *NewPtr = 
+        llvm::ConstantExpr::getBitCast(GV, OldGV->getType());
+      OldGV->replaceAllUsesWith(NewPtr);
+      OldGV->eraseFromParent();
+    }
+  }
+  
+  return GV;
+}
+
+llvm::GlobalVariable *CodeGenVTables::getVTT(const CXXRecordDecl *RD) {
+  return GenerateVTT(llvm::GlobalValue::ExternalLinkage, 
+                     /*GenerateDefinition=*/false, RD);
+}
+
+bool CodeGenVTables::needsVTTParameter(GlobalDecl GD) {
+  const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
+  
+  // We don't have any virtual bases, just return early.
+  if (!MD->getParent()->getNumVBases())
+    return false;
+  
+  // Check if we have a base constructor.
+  if (isa<CXXConstructorDecl>(MD) && GD.getCtorType() == Ctor_Base)
+    return true;
+
+  // Check if we have a base destructor.
+  if (isa<CXXDestructorDecl>(MD) && GD.getDtorType() == Dtor_Base)
+    return true;
+  
+  return false;
+}
+
+uint64_t CodeGenVTables::getSubVTTIndex(const CXXRecordDecl *RD, 
+                                        const CXXRecordDecl *Base) {
+  ClassPairTy ClassPair(RD, Base);
+
+  SubVTTIndiciesMapTy::iterator I = SubVTTIndicies.find(ClassPair);
+  if (I != SubVTTIndicies.end())
+    return I->second;
+  
+  VTTBuilder Builder(CGM, RD, /*GenerateDefinition=*/false);
+
+  for (llvm::DenseMap<const CXXRecordDecl *, uint64_t>::const_iterator I =
+       Builder.getSubVTTIndicies().begin(), 
+       E = Builder.getSubVTTIndicies().end(); I != E; ++I) {
+    // Insert all indices.
+    ClassPairTy ClassPair(RD, I->first);
+    
+    SubVTTIndicies.insert(std::make_pair(ClassPair, I->second));
+  }
+    
+  I = SubVTTIndicies.find(ClassPair);
+  assert(I != SubVTTIndicies.end() && "Did not find index!");
+  
+  return I->second;
+}
+
+uint64_t 
+CodeGenVTables::getSecondaryVirtualPointerIndex(const CXXRecordDecl *RD,
+                                                BaseSubobject Base) {
+  SecondaryVirtualPointerIndicesMapTy::iterator I =
+    SecondaryVirtualPointerIndices.find(std::make_pair(RD, Base));
+
+  if (I != SecondaryVirtualPointerIndices.end())
+    return I->second;
+
+  VTTBuilder Builder(CGM, RD, /*GenerateDefinition=*/false);
+
+  // Insert all secondary vpointer indices.
+  for (llvm::DenseMap<BaseSubobject, uint64_t>::const_iterator I = 
+       Builder.getSecondaryVirtualPointerIndices().begin(),
+       E = Builder.getSecondaryVirtualPointerIndices().end(); I != E; ++I) {
+    std::pair<const CXXRecordDecl *, BaseSubobject> Pair =
+      std::make_pair(RD, I->first);
+    
+    SecondaryVirtualPointerIndices.insert(std::make_pair(Pair, I->second));
+  }
+
+  I = SecondaryVirtualPointerIndices.find(std::make_pair(RD, Base));
+  assert(I != SecondaryVirtualPointerIndices.end() && "Did not find index!");
+  
+  return I->second;
+}
+
diff --git a/lib/CodeGen/CGVTables.cpp b/lib/CodeGen/CGVTables.cpp
new file mode 100644
index 0000000..159753a
--- /dev/null
+++ b/lib/CodeGen/CGVTables.cpp
@@ -0,0 +1,3167 @@
+//===--- CGVTables.cpp - Emit LLVM Code for C++ vtables -------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This contains code dealing with C++ code generation of virtual tables.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CodeGenModule.h"
+#include "CodeGenFunction.h"
+#include "clang/AST/CXXInheritance.h"
+#include "clang/AST/RecordLayout.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/SetVector.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Format.h"
+#include <algorithm>
+#include <cstdio>
+
+using namespace clang;
+using namespace CodeGen;
+
+namespace {
+
+/// BaseOffset - Represents an offset from a derived class to a direct or
+/// indirect base class.
+struct BaseOffset {
+  /// DerivedClass - The derived class.
+  const CXXRecordDecl *DerivedClass;
+  
+  /// VirtualBase - If the path from the derived class to the base class
+  /// involves a virtual base class, this holds its declaration.
+  const CXXRecordDecl *VirtualBase;
+
+  /// NonVirtualOffset - The offset from the derived class to the base class.
+  /// (Or the offset from the virtual base class to the base class, if the 
+  /// path from the derived class to the base class involves a virtual base
+  /// class.
+  int64_t NonVirtualOffset;
+  
+  BaseOffset() : DerivedClass(0), VirtualBase(0), NonVirtualOffset(0) { }
+  BaseOffset(const CXXRecordDecl *DerivedClass,
+             const CXXRecordDecl *VirtualBase, int64_t NonVirtualOffset)
+    : DerivedClass(DerivedClass), VirtualBase(VirtualBase), 
+    NonVirtualOffset(NonVirtualOffset) { }
+
+  bool isEmpty() const { return !NonVirtualOffset && !VirtualBase; }
+};
+
+/// FinalOverriders - Contains the final overrider member functions for all
+/// member functions in the base subobjects of a class.
+class FinalOverriders {
+public:
+  /// OverriderInfo - Information about a final overrider.
+  struct OverriderInfo {
+    /// Method - The method decl of the overrider.
+    const CXXMethodDecl *Method;
+
+    /// Offset - the base offset of the overrider in the layout class.
+    uint64_t Offset;
+    
+    OverriderInfo() : Method(0), Offset(0) { }
+  };
+
+private:
+  /// MostDerivedClass - The most derived class for which the final overriders
+  /// are stored.
+  const CXXRecordDecl *MostDerivedClass;
+  
+  /// MostDerivedClassOffset - If we're building final overriders for a 
+  /// construction vtable, this holds the offset from the layout class to the
+  /// most derived class.
+  const uint64_t MostDerivedClassOffset;
+
+  /// LayoutClass - The class we're using for layout information. Will be 
+  /// different than the most derived class if the final overriders are for a
+  /// construction vtable.  
+  const CXXRecordDecl *LayoutClass;  
+
+  ASTContext &Context;
+  
+  /// MostDerivedClassLayout - the AST record layout of the most derived class.
+  const ASTRecordLayout &MostDerivedClassLayout;
+
+  /// BaseSubobjectMethodPairTy - Uniquely identifies a member function
+  /// in a base subobject.
+  typedef std::pair<BaseSubobject, const CXXMethodDecl *>
+    BaseSubobjectMethodPairTy;
+  
+  typedef llvm::DenseMap<BaseSubobjectMethodPairTy,
+                         OverriderInfo> OverridersMapTy;
+  
+  /// OverridersMap - The final overriders for all virtual member functions of 
+  /// all the base subobjects of the most derived class.
+  OverridersMapTy OverridersMap;
+  
+  /// VisitedVirtualBases - A set of all the visited virtual bases, used to
+  /// avoid visiting virtual bases more than once.
+  llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBases;
+
+  typedef llvm::DenseMap<BaseSubobjectMethodPairTy, BaseOffset>
+    AdjustmentOffsetsMapTy;
+
+  /// ReturnAdjustments - Holds return adjustments for all the overriders that 
+  /// need to perform return value adjustments.
+  AdjustmentOffsetsMapTy ReturnAdjustments;
+
+  // FIXME: We might be able to get away with making this a SmallSet.
+  typedef llvm::SmallSetVector<uint64_t, 2> OffsetSetVectorTy;
+  
+  /// SubobjectOffsetsMapTy - This map is used for keeping track of all the
+  /// base subobject offsets that a single class declaration might refer to.
+  ///
+  /// For example, in:
+  ///
+  /// struct A { virtual void f(); };
+  /// struct B1 : A { };
+  /// struct B2 : A { };
+  /// struct C : B1, B2 { virtual void f(); };
+  ///
+  /// when we determine that C::f() overrides A::f(), we need to update the
+  /// overriders map for both A-in-B1 and A-in-B2 and the subobject offsets map
+  /// will have the subobject offsets for both A copies.
+  typedef llvm::DenseMap<const CXXRecordDecl *, OffsetSetVectorTy>
+    SubobjectOffsetsMapTy;
+  
+  /// ComputeFinalOverriders - Compute the final overriders for a given base
+  /// subobject (and all its direct and indirect bases).
+  void ComputeFinalOverriders(BaseSubobject Base,
+                              bool BaseSubobjectIsVisitedVBase,
+                              uint64_t OffsetInLayoutClass,
+                              SubobjectOffsetsMapTy &Offsets);
+  
+  /// AddOverriders - Add the final overriders for this base subobject to the
+  /// map of final overriders.  
+  void AddOverriders(BaseSubobject Base, uint64_t OffsetInLayoutClass,
+                     SubobjectOffsetsMapTy &Offsets);
+
+  /// PropagateOverrider - Propagate the NewMD overrider to all the functions 
+  /// that OldMD overrides. For example, if we have:
+  ///
+  /// struct A { virtual void f(); };
+  /// struct B : A { virtual void f(); };
+  /// struct C : B { virtual void f(); };
+  ///
+  /// and we want to override B::f with C::f, we also need to override A::f with
+  /// C::f.
+  void PropagateOverrider(const CXXMethodDecl *OldMD,
+                          BaseSubobject NewBase,
+                          uint64_t OverriderOffsetInLayoutClass,
+                          const CXXMethodDecl *NewMD,
+                          SubobjectOffsetsMapTy &Offsets);
+  
+  static void MergeSubobjectOffsets(const SubobjectOffsetsMapTy &NewOffsets,
+                                    SubobjectOffsetsMapTy &Offsets);
+
+public:
+  FinalOverriders(const CXXRecordDecl *MostDerivedClass,
+                  uint64_t MostDerivedClassOffset,
+                  const CXXRecordDecl *LayoutClass);
+
+  /// getOverrider - Get the final overrider for the given method declaration in
+  /// the given base subobject.
+  OverriderInfo getOverrider(BaseSubobject Base,
+                             const CXXMethodDecl *MD) const {
+    assert(OverridersMap.count(std::make_pair(Base, MD)) && 
+           "Did not find overrider!");
+    
+    return OverridersMap.lookup(std::make_pair(Base, MD));
+  }
+  
+  /// getReturnAdjustmentOffset - Get the return adjustment offset for the
+  /// method decl in the given base subobject. Returns an empty base offset if
+  /// no adjustment is needed.
+  BaseOffset getReturnAdjustmentOffset(BaseSubobject Base,
+                                       const CXXMethodDecl *MD) const {
+    return ReturnAdjustments.lookup(std::make_pair(Base, MD));
+  }
+
+  /// dump - dump the final overriders.
+  void dump() {
+    assert(VisitedVirtualBases.empty() &&
+           "Visited virtual bases aren't empty!");
+    dump(llvm::errs(), BaseSubobject(MostDerivedClass, 0)); 
+    VisitedVirtualBases.clear();
+  }
+  
+  /// dump - dump the final overriders for a base subobject, and all its direct
+  /// and indirect base subobjects.
+  void dump(llvm::raw_ostream &Out, BaseSubobject Base);
+};
+
+#define DUMP_OVERRIDERS 0
+
+FinalOverriders::FinalOverriders(const CXXRecordDecl *MostDerivedClass,
+                                 uint64_t MostDerivedClassOffset,
+                                 const CXXRecordDecl *LayoutClass)
+  : MostDerivedClass(MostDerivedClass), 
+  MostDerivedClassOffset(MostDerivedClassOffset), LayoutClass(LayoutClass),
+  Context(MostDerivedClass->getASTContext()),
+  MostDerivedClassLayout(Context.getASTRecordLayout(MostDerivedClass)) {
+    
+  // Compute the final overriders.
+  SubobjectOffsetsMapTy Offsets;
+  ComputeFinalOverriders(BaseSubobject(MostDerivedClass, 0), 
+                         /*BaseSubobjectIsVisitedVBase=*/false, 
+                         MostDerivedClassOffset, Offsets);
+  VisitedVirtualBases.clear();
+
+#if DUMP_OVERRIDERS
+  // And dump them (for now).
+  dump();
+    
+  // Also dump the base offsets (for now).
+  for (SubobjectOffsetsMapTy::const_iterator I = Offsets.begin(),
+       E = Offsets.end(); I != E; ++I) {
+    const OffsetSetVectorTy& OffsetSetVector = I->second;
+
+    llvm::errs() << "Base offsets for ";
+    llvm::errs() << I->first->getQualifiedNameAsString() << '\n';
+
+    for (unsigned I = 0, E = OffsetSetVector.size(); I != E; ++I)
+      llvm::errs() << "  " << I << " - " << OffsetSetVector[I] / 8 << '\n';
+  }
+#endif
+}
+
+void FinalOverriders::AddOverriders(BaseSubobject Base,
+                                    uint64_t OffsetInLayoutClass,
+                                    SubobjectOffsetsMapTy &Offsets) {
+  const CXXRecordDecl *RD = Base.getBase();
+
+  for (CXXRecordDecl::method_iterator I = RD->method_begin(), 
+       E = RD->method_end(); I != E; ++I) {
+    const CXXMethodDecl *MD = *I;
+    
+    if (!MD->isVirtual())
+      continue;
+
+    // First, propagate the overrider.
+    PropagateOverrider(MD, Base, OffsetInLayoutClass, MD, Offsets);
+
+    // Add the overrider as the final overrider of itself.
+    OverriderInfo& Overrider = OverridersMap[std::make_pair(Base, MD)];
+    assert(!Overrider.Method && "Overrider should not exist yet!");
+
+    Overrider.Offset = OffsetInLayoutClass;
+    Overrider.Method = MD;
+  }
+}
+
+static BaseOffset ComputeBaseOffset(ASTContext &Context, 
+                                    const CXXRecordDecl *DerivedRD,
+                                    const CXXBasePath &Path) {
+  int64_t NonVirtualOffset = 0;
+
+  unsigned NonVirtualStart = 0;
+  const CXXRecordDecl *VirtualBase = 0;
+  
+  // First, look for the virtual base class.
+  for (unsigned I = 0, E = Path.size(); I != E; ++I) {
+    const CXXBasePathElement &Element = Path[I];
+    
+    if (Element.Base->isVirtual()) {
+      // FIXME: Can we break when we find the first virtual base?
+      // (If we can't, can't we just iterate over the path in reverse order?)
+      NonVirtualStart = I + 1;
+      QualType VBaseType = Element.Base->getType();
+      VirtualBase = 
+        cast<CXXRecordDecl>(VBaseType->getAs<RecordType>()->getDecl());
+    }
+  }
+  
+  // Now compute the non-virtual offset.
+  for (unsigned I = NonVirtualStart, E = Path.size(); I != E; ++I) {
+    const CXXBasePathElement &Element = Path[I];
+    
+    // Check the base class offset.
+    const ASTRecordLayout &Layout = Context.getASTRecordLayout(Element.Class);
+
+    const RecordType *BaseType = Element.Base->getType()->getAs<RecordType>();
+    const CXXRecordDecl *Base = cast<CXXRecordDecl>(BaseType->getDecl());
+
+    NonVirtualOffset += Layout.getBaseClassOffset(Base);
+  }
+  
+  // FIXME: This should probably use CharUnits or something. Maybe we should
+  // even change the base offsets in ASTRecordLayout to be specified in 
+  // CharUnits.
+  return BaseOffset(DerivedRD, VirtualBase, NonVirtualOffset / 8);
+  
+}
+
+static BaseOffset ComputeBaseOffset(ASTContext &Context, 
+                                    const CXXRecordDecl *BaseRD,
+                                    const CXXRecordDecl *DerivedRD) {
+  CXXBasePaths Paths(/*FindAmbiguities=*/false,
+                     /*RecordPaths=*/true, /*DetectVirtual=*/false);
+  
+  if (!const_cast<CXXRecordDecl *>(DerivedRD)->
+      isDerivedFrom(const_cast<CXXRecordDecl *>(BaseRD), Paths)) {
+    assert(false && "Class must be derived from the passed in base class!");
+    return BaseOffset();
+  }
+
+  return ComputeBaseOffset(Context, DerivedRD, Paths.front());
+}
+
+static BaseOffset
+ComputeReturnAdjustmentBaseOffset(ASTContext &Context, 
+                                  const CXXMethodDecl *DerivedMD,
+                                  const CXXMethodDecl *BaseMD) {
+  const FunctionType *BaseFT = BaseMD->getType()->getAs<FunctionType>();
+  const FunctionType *DerivedFT = DerivedMD->getType()->getAs<FunctionType>();
+  
+  // Canonicalize the return types.
+  CanQualType CanDerivedReturnType = 
+    Context.getCanonicalType(DerivedFT->getResultType());
+  CanQualType CanBaseReturnType = 
+    Context.getCanonicalType(BaseFT->getResultType());
+  
+  assert(CanDerivedReturnType->getTypeClass() == 
+         CanBaseReturnType->getTypeClass() && 
+         "Types must have same type class!");
+  
+  if (CanDerivedReturnType == CanBaseReturnType) {
+    // No adjustment needed.
+    return BaseOffset();
+  }
+  
+  if (isa<ReferenceType>(CanDerivedReturnType)) {
+    CanDerivedReturnType = 
+      CanDerivedReturnType->getAs<ReferenceType>()->getPointeeType();
+    CanBaseReturnType = 
+      CanBaseReturnType->getAs<ReferenceType>()->getPointeeType();
+  } else if (isa<PointerType>(CanDerivedReturnType)) {
+    CanDerivedReturnType = 
+      CanDerivedReturnType->getAs<PointerType>()->getPointeeType();
+    CanBaseReturnType = 
+      CanBaseReturnType->getAs<PointerType>()->getPointeeType();
+  } else {
+    assert(false && "Unexpected return type!");
+  }
+  
+  // We need to compare unqualified types here; consider
+  //   const T *Base::foo();
+  //   T *Derived::foo();
+  if (CanDerivedReturnType.getUnqualifiedType() == 
+      CanBaseReturnType.getUnqualifiedType()) {
+    // No adjustment needed.
+    return BaseOffset();
+  }
+  
+  const CXXRecordDecl *DerivedRD = 
+    cast<CXXRecordDecl>(cast<RecordType>(CanDerivedReturnType)->getDecl());
+  
+  const CXXRecordDecl *BaseRD = 
+    cast<CXXRecordDecl>(cast<RecordType>(CanBaseReturnType)->getDecl());
+
+  return ComputeBaseOffset(Context, BaseRD, DerivedRD);
+}
+
+void FinalOverriders::PropagateOverrider(const CXXMethodDecl *OldMD,
+                                         BaseSubobject NewBase,
+                                         uint64_t OverriderOffsetInLayoutClass,
+                                         const CXXMethodDecl *NewMD,
+                                         SubobjectOffsetsMapTy &Offsets) {
+  for (CXXMethodDecl::method_iterator I = OldMD->begin_overridden_methods(),
+       E = OldMD->end_overridden_methods(); I != E; ++I) {
+    const CXXMethodDecl *OverriddenMD = *I;
+    const CXXRecordDecl *OverriddenRD = OverriddenMD->getParent();
+
+    // We want to override OverriddenMD in all subobjects, for example:
+    //
+    /// struct A { virtual void f(); };
+    /// struct B1 : A { };
+    /// struct B2 : A { };
+    /// struct C : B1, B2 { virtual void f(); };
+    ///
+    /// When overriding A::f with C::f we need to do so in both A subobjects.
+    const OffsetSetVectorTy &OffsetVector = Offsets[OverriddenRD];
+    
+    // Go through all the subobjects.
+    for (unsigned I = 0, E = OffsetVector.size(); I != E; ++I) {
+      uint64_t Offset = OffsetVector[I];
+
+      BaseSubobject OverriddenSubobject = BaseSubobject(OverriddenRD, Offset);
+      BaseSubobjectMethodPairTy SubobjectAndMethod =
+        std::make_pair(OverriddenSubobject, OverriddenMD);
+      
+      OverriderInfo &Overrider = OverridersMap[SubobjectAndMethod];
+
+      assert(Overrider.Method && "Did not find existing overrider!");
+
+      // Check if we need return adjustments or base adjustments.
+      // (We don't want to do this for pure virtual member functions).
+      if (!NewMD->isPure()) {
+        // Get the return adjustment base offset.
+        BaseOffset ReturnBaseOffset =
+          ComputeReturnAdjustmentBaseOffset(Context, NewMD, OverriddenMD);
+
+        if (!ReturnBaseOffset.isEmpty()) {
+          // Store the return adjustment base offset.
+          ReturnAdjustments[SubobjectAndMethod] = ReturnBaseOffset;
+        }
+      }
+
+      // Set the new overrider.
+      Overrider.Offset = OverriderOffsetInLayoutClass;
+      Overrider.Method = NewMD;
+      
+      // And propagate it further.
+      PropagateOverrider(OverriddenMD, NewBase, OverriderOffsetInLayoutClass,
+                         NewMD, Offsets);
+    }
+  }
+}
+
+void 
+FinalOverriders::MergeSubobjectOffsets(const SubobjectOffsetsMapTy &NewOffsets,
+                                       SubobjectOffsetsMapTy &Offsets) {
+  // Iterate over the new offsets.
+  for (SubobjectOffsetsMapTy::const_iterator I = NewOffsets.begin(),
+       E = NewOffsets.end(); I != E; ++I) {
+    const CXXRecordDecl *NewRD = I->first;
+    const OffsetSetVectorTy& NewOffsetVector = I->second;
+    
+    OffsetSetVectorTy &OffsetVector = Offsets[NewRD];
+    
+    // Merge the new offsets set vector into the old.
+    OffsetVector.insert(NewOffsetVector.begin(), NewOffsetVector.end());
+  }
+}
+
+void FinalOverriders::ComputeFinalOverriders(BaseSubobject Base,
+                                             bool BaseSubobjectIsVisitedVBase,
+                                             uint64_t OffsetInLayoutClass,
+                                             SubobjectOffsetsMapTy &Offsets) {
+  const CXXRecordDecl *RD = Base.getBase();
+  const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
+  
+  SubobjectOffsetsMapTy NewOffsets;
+  
+  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
+       E = RD->bases_end(); I != E; ++I) {
+    const CXXRecordDecl *BaseDecl = 
+      cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+    
+    // Ignore bases that don't have any virtual member functions.
+    if (!BaseDecl->isPolymorphic())
+      continue;
+    
+    bool IsVisitedVirtualBase = BaseSubobjectIsVisitedVBase;
+    uint64_t BaseOffset;
+    uint64_t BaseOffsetInLayoutClass;
+    if (I->isVirtual()) {
+      if (!VisitedVirtualBases.insert(BaseDecl))
+        IsVisitedVirtualBase = true;
+      BaseOffset = MostDerivedClassLayout.getVBaseClassOffset(BaseDecl);
+      
+      const ASTRecordLayout &LayoutClassLayout =
+        Context.getASTRecordLayout(LayoutClass);
+      BaseOffsetInLayoutClass = 
+        LayoutClassLayout.getVBaseClassOffset(BaseDecl);
+    } else {
+      BaseOffset = Layout.getBaseClassOffset(BaseDecl) + Base.getBaseOffset();
+      BaseOffsetInLayoutClass = Layout.getBaseClassOffset(BaseDecl) +
+        OffsetInLayoutClass;
+    }
+    
+    // Compute the final overriders for this base.
+    // We always want to compute the final overriders, even if the base is a
+    // visited virtual base. Consider:
+    //
+    // struct A {
+    //   virtual void f();
+    //   virtual void g();
+    // };
+    //  
+    // struct B : virtual A {
+    //   void f();
+    // };
+    //
+    // struct C : virtual A {
+    //   void g ();
+    // };
+    //
+    // struct D : B, C { };
+    //
+    // Here, we still want to compute the overriders for A as a base of C, 
+    // because otherwise we'll miss that C::g overrides A::f.
+    ComputeFinalOverriders(BaseSubobject(BaseDecl, BaseOffset), 
+                           IsVisitedVirtualBase, BaseOffsetInLayoutClass, 
+                           NewOffsets);
+  }
+
+  /// Now add the overriders for this particular subobject.
+  /// (We don't want to do this more than once for a virtual base).
+  if (!BaseSubobjectIsVisitedVBase)
+    AddOverriders(Base, OffsetInLayoutClass, NewOffsets);
+  
+  // And merge the newly discovered subobject offsets.
+  MergeSubobjectOffsets(NewOffsets, Offsets);
+
+  /// Finally, add the offset for our own subobject.
+  Offsets[RD].insert(Base.getBaseOffset());
+}
+
+void FinalOverriders::dump(llvm::raw_ostream &Out, BaseSubobject Base) {
+  const CXXRecordDecl *RD = Base.getBase();
+  const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
+
+  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
+       E = RD->bases_end(); I != E; ++I) {
+    const CXXRecordDecl *BaseDecl = 
+      cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+    
+    // Ignore bases that don't have any virtual member functions.
+    if (!BaseDecl->isPolymorphic())
+      continue;
+
+    uint64_t BaseOffset;
+    if (I->isVirtual()) {
+      if (!VisitedVirtualBases.insert(BaseDecl)) {
+        // We've visited this base before.
+        continue;
+      }
+      
+      BaseOffset = MostDerivedClassLayout.getVBaseClassOffset(BaseDecl);
+    } else {
+      BaseOffset = Layout.getBaseClassOffset(BaseDecl) + 
+        Base.getBaseOffset();
+    }
+
+    dump(Out, BaseSubobject(BaseDecl, BaseOffset));
+  }
+
+  Out << "Final overriders for (" << RD->getQualifiedNameAsString() << ", ";
+  Out << Base.getBaseOffset() / 8 << ")\n";
+
+  // Now dump the overriders for this base subobject.
+  for (CXXRecordDecl::method_iterator I = RD->method_begin(), 
+       E = RD->method_end(); I != E; ++I) {
+    const CXXMethodDecl *MD = *I;
+
+    if (!MD->isVirtual())
+      continue;
+  
+    OverriderInfo Overrider = getOverrider(Base, MD);
+
+    Out << "  " << MD->getQualifiedNameAsString() << " - (";
+    Out << Overrider.Method->getQualifiedNameAsString();
+    Out << ", " << ", " << Overrider.Offset / 8 << ')';
+
+    AdjustmentOffsetsMapTy::const_iterator AI =
+      ReturnAdjustments.find(std::make_pair(Base, MD));
+    if (AI != ReturnAdjustments.end()) {
+      const BaseOffset &Offset = AI->second;
+
+      Out << " [ret-adj: ";
+      if (Offset.VirtualBase)
+        Out << Offset.VirtualBase->getQualifiedNameAsString() << " vbase, ";
+             
+      Out << Offset.NonVirtualOffset << " nv]";
+    }
+    
+    Out << "\n";
+  }  
+}
+
+/// VTableComponent - Represents a single component in a vtable.
+class VTableComponent {
+public:
+  enum Kind {
+    CK_VCallOffset,
+    CK_VBaseOffset,
+    CK_OffsetToTop,
+    CK_RTTI,
+    CK_FunctionPointer,
+    
+    /// CK_CompleteDtorPointer - A pointer to the complete destructor.
+    CK_CompleteDtorPointer,
+    
+    /// CK_DeletingDtorPointer - A pointer to the deleting destructor.
+    CK_DeletingDtorPointer,
+    
+    /// CK_UnusedFunctionPointer - In some cases, a vtable function pointer
+    /// will end up never being called. Such vtable function pointers are
+    /// represented as a CK_UnusedFunctionPointer. 
+    CK_UnusedFunctionPointer
+  };
+
+  static VTableComponent MakeVCallOffset(int64_t Offset) {
+    return VTableComponent(CK_VCallOffset, Offset);
+  }
+
+  static VTableComponent MakeVBaseOffset(int64_t Offset) {
+    return VTableComponent(CK_VBaseOffset, Offset);
+  }
+
+  static VTableComponent MakeOffsetToTop(int64_t Offset) {
+    return VTableComponent(CK_OffsetToTop, Offset);
+  }
+  
+  static VTableComponent MakeRTTI(const CXXRecordDecl *RD) {
+    return VTableComponent(CK_RTTI, reinterpret_cast<uintptr_t>(RD));
+  }
+
+  static VTableComponent MakeFunction(const CXXMethodDecl *MD) {
+    assert(!isa<CXXDestructorDecl>(MD) && 
+           "Don't use MakeFunction with destructors!");
+
+    return VTableComponent(CK_FunctionPointer, 
+                           reinterpret_cast<uintptr_t>(MD));
+  }
+  
+  static VTableComponent MakeCompleteDtor(const CXXDestructorDecl *DD) {
+    return VTableComponent(CK_CompleteDtorPointer,
+                           reinterpret_cast<uintptr_t>(DD));
+  }
+
+  static VTableComponent MakeDeletingDtor(const CXXDestructorDecl *DD) {
+    return VTableComponent(CK_DeletingDtorPointer, 
+                           reinterpret_cast<uintptr_t>(DD));
+  }
+
+  static VTableComponent MakeUnusedFunction(const CXXMethodDecl *MD) {
+    assert(!isa<CXXDestructorDecl>(MD) && 
+           "Don't use MakeUnusedFunction with destructors!");
+    return VTableComponent(CK_UnusedFunctionPointer,
+                           reinterpret_cast<uintptr_t>(MD));                           
+  }
+
+  static VTableComponent getFromOpaqueInteger(uint64_t I) {
+    return VTableComponent(I);
+  }
+
+  /// getKind - Get the kind of this vtable component.
+  Kind getKind() const {
+    return (Kind)(Value & 0x7);
+  }
+
+  int64_t getVCallOffset() const {
+    assert(getKind() == CK_VCallOffset && "Invalid component kind!");
+    
+    return getOffset();
+  }
+
+  int64_t getVBaseOffset() const {
+    assert(getKind() == CK_VBaseOffset && "Invalid component kind!");
+    
+    return getOffset();
+  }
+
+  int64_t getOffsetToTop() const {
+    assert(getKind() == CK_OffsetToTop && "Invalid component kind!");
+    
+    return getOffset();
+  }
+  
+  const CXXRecordDecl *getRTTIDecl() const {
+    assert(getKind() == CK_RTTI && "Invalid component kind!");
+    
+    return reinterpret_cast<CXXRecordDecl *>(getPointer());
+  }
+  
+  const CXXMethodDecl *getFunctionDecl() const {
+    assert(getKind() == CK_FunctionPointer);
+    
+    return reinterpret_cast<CXXMethodDecl *>(getPointer());
+  }
+
+  const CXXDestructorDecl *getDestructorDecl() const {
+    assert((getKind() == CK_CompleteDtorPointer ||
+            getKind() == CK_DeletingDtorPointer) && "Invalid component kind!");
+    
+    return reinterpret_cast<CXXDestructorDecl *>(getPointer());
+  }
+
+  const CXXMethodDecl *getUnusedFunctionDecl() const {
+    assert(getKind() == CK_UnusedFunctionPointer);
+    
+    return reinterpret_cast<CXXMethodDecl *>(getPointer());
+  }
+  
+private:
+  VTableComponent(Kind ComponentKind, int64_t Offset) {
+    assert((ComponentKind == CK_VCallOffset || 
+            ComponentKind == CK_VBaseOffset ||
+            ComponentKind == CK_OffsetToTop) && "Invalid component kind!");
+    assert(Offset <= ((1LL << 56) - 1) && "Offset is too big!");
+    
+    Value = ((Offset << 3) | ComponentKind);
+  }
+
+  VTableComponent(Kind ComponentKind, uintptr_t Ptr) {
+    assert((ComponentKind == CK_RTTI || 
+            ComponentKind == CK_FunctionPointer ||
+            ComponentKind == CK_CompleteDtorPointer ||
+            ComponentKind == CK_DeletingDtorPointer ||
+            ComponentKind == CK_UnusedFunctionPointer) &&
+            "Invalid component kind!");
+    
+    assert((Ptr & 7) == 0 && "Pointer not sufficiently aligned!");
+    
+    Value = Ptr | ComponentKind;
+  }
+  
+  int64_t getOffset() const {
+    assert((getKind() == CK_VCallOffset || getKind() == CK_VBaseOffset ||
+            getKind() == CK_OffsetToTop) && "Invalid component kind!");
+    
+    return Value >> 3;
+  }
+
+  uintptr_t getPointer() const {
+    assert((getKind() == CK_RTTI || 
+            getKind() == CK_FunctionPointer ||
+            getKind() == CK_CompleteDtorPointer ||
+            getKind() == CK_DeletingDtorPointer ||
+            getKind() == CK_UnusedFunctionPointer) &&
+           "Invalid component kind!");
+    
+    return static_cast<uintptr_t>(Value & ~7ULL);
+  }
+  
+  explicit VTableComponent(uint64_t Value)
+    : Value(Value) { }
+
+  /// The kind is stored in the lower 3 bits of the value. For offsets, we
+  /// make use of the facts that classes can't be larger than 2^55 bytes,
+  /// so we store the offset in the lower part of the 61 bytes that remain.
+  /// (The reason that we're not simply using a PointerIntPair here is that we
+  /// need the offsets to be 64-bit, even when on a 32-bit machine).
+  int64_t Value;
+};
+
+/// VCallOffsetMap - Keeps track of vcall offsets when building a vtable.
+struct VCallOffsetMap {
+  
+  typedef std::pair<const CXXMethodDecl *, int64_t> MethodAndOffsetPairTy;
+  
+  /// Offsets - Keeps track of methods and their offsets.
+  // FIXME: This should be a real map and not a vector.
+  llvm::SmallVector<MethodAndOffsetPairTy, 16> Offsets;
+
+  /// MethodsCanShareVCallOffset - Returns whether two virtual member functions
+  /// can share the same vcall offset.
+  static bool MethodsCanShareVCallOffset(const CXXMethodDecl *LHS,
+                                         const CXXMethodDecl *RHS);
+
+public:
+  /// AddVCallOffset - Adds a vcall offset to the map. Returns true if the
+  /// add was successful, or false if there was already a member function with
+  /// the same signature in the map.
+  bool AddVCallOffset(const CXXMethodDecl *MD, int64_t OffsetOffset);
+  
+  /// getVCallOffsetOffset - Returns the vcall offset offset (relative to the
+  /// vtable address point) for the given virtual member function.
+  int64_t getVCallOffsetOffset(const CXXMethodDecl *MD);
+  
+  // empty - Return whether the offset map is empty or not.
+  bool empty() const { return Offsets.empty(); }
+};
+
+static bool HasSameVirtualSignature(const CXXMethodDecl *LHS,
+                                    const CXXMethodDecl *RHS) {
+  ASTContext &C = LHS->getASTContext(); // TODO: thread this down
+  CanQual<FunctionProtoType>
+    LT = C.getCanonicalType(LHS->getType()).getAs<FunctionProtoType>(),
+    RT = C.getCanonicalType(RHS->getType()).getAs<FunctionProtoType>();
+
+  // Fast-path matches in the canonical types.
+  if (LT == RT) return true;
+
+  // Force the signatures to match.  We can't rely on the overrides
+  // list here because there isn't necessarily an inheritance
+  // relationship between the two methods.
+  if (LT.getQualifiers() != RT.getQualifiers() ||
+      LT->getNumArgs() != RT->getNumArgs())
+    return false;
+  for (unsigned I = 0, E = LT->getNumArgs(); I != E; ++I)
+    if (LT->getArgType(I) != RT->getArgType(I))
+      return false;
+  return true;
+}
+
+bool VCallOffsetMap::MethodsCanShareVCallOffset(const CXXMethodDecl *LHS,
+                                                const CXXMethodDecl *RHS) {
+  assert(LHS->isVirtual() && "LHS must be virtual!");
+  assert(RHS->isVirtual() && "LHS must be virtual!");
+  
+  // A destructor can share a vcall offset with another destructor.
+  if (isa<CXXDestructorDecl>(LHS))
+    return isa<CXXDestructorDecl>(RHS);
+
+  // FIXME: We need to check more things here.
+  
+  // The methods must have the same name.
+  DeclarationName LHSName = LHS->getDeclName();
+  DeclarationName RHSName = RHS->getDeclName();
+  if (LHSName != RHSName)
+    return false;
+
+  // And the same signatures.
+  return HasSameVirtualSignature(LHS, RHS);
+}
+
+bool VCallOffsetMap::AddVCallOffset(const CXXMethodDecl *MD, 
+                                    int64_t OffsetOffset) {
+  // Check if we can reuse an offset.
+  for (unsigned I = 0, E = Offsets.size(); I != E; ++I) {
+    if (MethodsCanShareVCallOffset(Offsets[I].first, MD))
+      return false;
+  }
+  
+  // Add the offset.
+  Offsets.push_back(MethodAndOffsetPairTy(MD, OffsetOffset));
+  return true;
+}
+
+int64_t VCallOffsetMap::getVCallOffsetOffset(const CXXMethodDecl *MD) {
+  // Look for an offset.
+  for (unsigned I = 0, E = Offsets.size(); I != E; ++I) {
+    if (MethodsCanShareVCallOffset(Offsets[I].first, MD))
+      return Offsets[I].second;
+  }
+  
+  assert(false && "Should always find a vcall offset offset!");
+  return 0;
+}
+
+/// VCallAndVBaseOffsetBuilder - Class for building vcall and vbase offsets.
+class VCallAndVBaseOffsetBuilder {
+public:
+  typedef llvm::DenseMap<const CXXRecordDecl *, int64_t> 
+    VBaseOffsetOffsetsMapTy;
+
+private:
+  /// MostDerivedClass - The most derived class for which we're building vcall
+  /// and vbase offsets.
+  const CXXRecordDecl *MostDerivedClass;
+  
+  /// LayoutClass - The class we're using for layout information. Will be 
+  /// different than the most derived class if we're building a construction
+  /// vtable.
+  const CXXRecordDecl *LayoutClass;
+  
+  /// Context - The ASTContext which we will use for layout information.
+  ASTContext &Context;
+
+  /// Components - vcall and vbase offset components
+  typedef llvm::SmallVector<VTableComponent, 64> VTableComponentVectorTy;
+  VTableComponentVectorTy Components;
+  
+  /// VisitedVirtualBases - Visited virtual bases.
+  llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBases;
+  
+  /// VCallOffsets - Keeps track of vcall offsets.
+  VCallOffsetMap VCallOffsets;
+
+
+  /// VBaseOffsetOffsets - Contains the offsets of the virtual base offsets,
+  /// relative to the address point.
+  VBaseOffsetOffsetsMapTy VBaseOffsetOffsets;
+  
+  /// FinalOverriders - The final overriders of the most derived class.
+  /// (Can be null when we're not building a vtable of the most derived class).
+  const FinalOverriders *Overriders;
+
+  /// AddVCallAndVBaseOffsets - Add vcall offsets and vbase offsets for the
+  /// given base subobject.
+  void AddVCallAndVBaseOffsets(BaseSubobject Base, bool BaseIsVirtual,
+                               uint64_t RealBaseOffset);
+  
+  /// AddVCallOffsets - Add vcall offsets for the given base subobject.
+  void AddVCallOffsets(BaseSubobject Base, uint64_t VBaseOffset);
+  
+  /// AddVBaseOffsets - Add vbase offsets for the given class.
+  void AddVBaseOffsets(const CXXRecordDecl *Base, uint64_t OffsetInLayoutClass);
+  
+  /// getCurrentOffsetOffset - Get the current vcall or vbase offset offset in
+  /// bytes, relative to the vtable address point.
+  int64_t getCurrentOffsetOffset() const;
+  
+public:
+  VCallAndVBaseOffsetBuilder(const CXXRecordDecl *MostDerivedClass,
+                             const CXXRecordDecl *LayoutClass,
+                             const FinalOverriders *Overriders,
+                             BaseSubobject Base, bool BaseIsVirtual,
+                             uint64_t OffsetInLayoutClass)
+    : MostDerivedClass(MostDerivedClass), LayoutClass(LayoutClass), 
+    Context(MostDerivedClass->getASTContext()), Overriders(Overriders) {
+      
+    // Add vcall and vbase offsets.
+    AddVCallAndVBaseOffsets(Base, BaseIsVirtual, OffsetInLayoutClass);
+  }
+  
+  /// Methods for iterating over the components.
+  typedef VTableComponentVectorTy::const_reverse_iterator const_iterator;
+  const_iterator components_begin() const { return Components.rbegin(); }
+  const_iterator components_end() const { return Components.rend(); }
+  
+  const VCallOffsetMap &getVCallOffsets() const { return VCallOffsets; }
+  const VBaseOffsetOffsetsMapTy &getVBaseOffsetOffsets() const {
+    return VBaseOffsetOffsets;
+  }
+};
+  
+void 
+VCallAndVBaseOffsetBuilder::AddVCallAndVBaseOffsets(BaseSubobject Base,
+                                                    bool BaseIsVirtual,
+                                                    uint64_t RealBaseOffset) {
+  const ASTRecordLayout &Layout = Context.getASTRecordLayout(Base.getBase());
+  
+  // Itanium C++ ABI 2.5.2:
+  //   ..in classes sharing a virtual table with a primary base class, the vcall
+  //   and vbase offsets added by the derived class all come before the vcall
+  //   and vbase offsets required by the base class, so that the latter may be
+  //   laid out as required by the base class without regard to additions from
+  //   the derived class(es).
+
+  // (Since we're emitting the vcall and vbase offsets in reverse order, we'll
+  // emit them for the primary base first).
+  if (const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase()) {
+    bool PrimaryBaseIsVirtual = Layout.getPrimaryBaseWasVirtual();
+
+    uint64_t PrimaryBaseOffset;
+    
+    // Get the base offset of the primary base.
+    if (PrimaryBaseIsVirtual) {
+      assert(Layout.getVBaseClassOffset(PrimaryBase) == 0 &&
+             "Primary vbase should have a zero offset!");
+      
+      const ASTRecordLayout &MostDerivedClassLayout =
+        Context.getASTRecordLayout(MostDerivedClass);
+      
+      PrimaryBaseOffset = 
+        MostDerivedClassLayout.getVBaseClassOffset(PrimaryBase);
+    } else {
+      assert(Layout.getBaseClassOffset(PrimaryBase) == 0 &&
+             "Primary base should have a zero offset!");
+
+      PrimaryBaseOffset = Base.getBaseOffset();
+    }
+
+    AddVCallAndVBaseOffsets(BaseSubobject(PrimaryBase, PrimaryBaseOffset),
+                            PrimaryBaseIsVirtual, RealBaseOffset);
+  }
+
+  AddVBaseOffsets(Base.getBase(), RealBaseOffset);
+
+  // We only want to add vcall offsets for virtual bases.
+  if (BaseIsVirtual)
+    AddVCallOffsets(Base, RealBaseOffset);
+}
+
+int64_t VCallAndVBaseOffsetBuilder::getCurrentOffsetOffset() const {
+  // OffsetIndex is the index of this vcall or vbase offset, relative to the 
+  // vtable address point. (We subtract 3 to account for the information just
+  // above the address point, the RTTI info, the offset to top, and the
+  // vcall offset itself).
+  int64_t OffsetIndex = -(int64_t)(3 + Components.size());
+    
+  // FIXME: We shouldn't use / 8 here.
+  int64_t OffsetOffset = OffsetIndex * 
+    (int64_t)Context.Target.getPointerWidth(0) / 8;
+
+  return OffsetOffset;
+}
+
+void VCallAndVBaseOffsetBuilder::AddVCallOffsets(BaseSubobject Base, 
+                                                 uint64_t VBaseOffset) {
+  const CXXRecordDecl *RD = Base.getBase();
+  const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
+
+  const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
+
+  // Handle the primary base first.
+  // We only want to add vcall offsets if the base is non-virtual; a virtual
+  // primary base will have its vcall and vbase offsets emitted already.
+  if (PrimaryBase && !Layout.getPrimaryBaseWasVirtual()) {
+    // Get the base offset of the primary base.
+    assert(Layout.getBaseClassOffset(PrimaryBase) == 0 &&
+           "Primary base should have a zero offset!");
+
+    AddVCallOffsets(BaseSubobject(PrimaryBase, Base.getBaseOffset()),
+                    VBaseOffset);
+  }
+  
+  // Add the vcall offsets.
+  for (CXXRecordDecl::method_iterator I = RD->method_begin(),
+       E = RD->method_end(); I != E; ++I) {
+    const CXXMethodDecl *MD = *I;
+    
+    if (!MD->isVirtual())
+      continue;
+
+    int64_t OffsetOffset = getCurrentOffsetOffset();
+    
+    // Don't add a vcall offset if we already have one for this member function
+    // signature.
+    if (!VCallOffsets.AddVCallOffset(MD, OffsetOffset))
+      continue;
+
+    int64_t Offset = 0;
+
+    if (Overriders) {
+      // Get the final overrider.
+      FinalOverriders::OverriderInfo Overrider = 
+        Overriders->getOverrider(Base, MD);
+      
+      /// The vcall offset is the offset from the virtual base to the object 
+      /// where the function was overridden.
+      // FIXME: We should not use / 8 here.
+      Offset = (int64_t)(Overrider.Offset - VBaseOffset) / 8;
+    }
+    
+    Components.push_back(VTableComponent::MakeVCallOffset(Offset));
+  }
+
+  // And iterate over all non-virtual bases (ignoring the primary base).
+  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
+       E = RD->bases_end(); I != E; ++I) {
+  
+    if (I->isVirtual())
+      continue;
+
+    const CXXRecordDecl *BaseDecl =
+      cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+    if (BaseDecl == PrimaryBase)
+      continue;
+
+    // Get the base offset of this base.
+    uint64_t BaseOffset = Base.getBaseOffset() + 
+      Layout.getBaseClassOffset(BaseDecl);
+    
+    AddVCallOffsets(BaseSubobject(BaseDecl, BaseOffset), VBaseOffset);
+  }
+}
+
+void VCallAndVBaseOffsetBuilder::AddVBaseOffsets(const CXXRecordDecl *RD,
+                                                 uint64_t OffsetInLayoutClass) {
+  const ASTRecordLayout &LayoutClassLayout = 
+    Context.getASTRecordLayout(LayoutClass);
+
+  // Add vbase offsets.
+  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
+       E = RD->bases_end(); I != E; ++I) {
+    const CXXRecordDecl *BaseDecl =
+      cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+
+    // Check if this is a virtual base that we haven't visited before.
+    if (I->isVirtual() && VisitedVirtualBases.insert(BaseDecl)) {
+      // FIXME: We shouldn't use / 8 here.
+      int64_t Offset = 
+        (int64_t)(LayoutClassLayout.getVBaseClassOffset(BaseDecl) - 
+                  OffsetInLayoutClass) / 8;
+
+      // Add the vbase offset offset.
+      assert(!VBaseOffsetOffsets.count(BaseDecl) &&
+             "vbase offset offset already exists!");
+
+      int64_t VBaseOffsetOffset = getCurrentOffsetOffset();
+      VBaseOffsetOffsets.insert(std::make_pair(BaseDecl, VBaseOffsetOffset));
+
+      Components.push_back(VTableComponent::MakeVBaseOffset(Offset));
+    }
+
+    // Check the base class looking for more vbase offsets.
+    AddVBaseOffsets(BaseDecl, OffsetInLayoutClass);
+  }
+}
+
+/// VTableBuilder - Class for building vtable layout information.
+class VTableBuilder {
+public:
+  /// PrimaryBasesSetVectorTy - A set vector of direct and indirect 
+  /// primary bases.
+  typedef llvm::SmallSetVector<const CXXRecordDecl *, 8> 
+    PrimaryBasesSetVectorTy;
+  
+  typedef llvm::DenseMap<const CXXRecordDecl *, int64_t> 
+    VBaseOffsetOffsetsMapTy;
+  
+  typedef llvm::DenseMap<BaseSubobject, uint64_t> 
+    AddressPointsMapTy;
+
+private:
+  /// VTables - Global vtable information.
+  CodeGenVTables &VTables;
+  
+  /// MostDerivedClass - The most derived class for which we're building this
+  /// vtable.
+  const CXXRecordDecl *MostDerivedClass;
+
+  /// MostDerivedClassOffset - If we're building a construction vtable, this
+  /// holds the offset from the layout class to the most derived class.
+  const uint64_t MostDerivedClassOffset;
+  
+  /// MostDerivedClassIsVirtual - Whether the most derived class is a virtual 
+  /// base. (This only makes sense when building a construction vtable).
+  bool MostDerivedClassIsVirtual;
+  
+  /// LayoutClass - The class we're using for layout information. Will be 
+  /// different than the most derived class if we're building a construction
+  /// vtable.
+  const CXXRecordDecl *LayoutClass;
+  
+  /// Context - The ASTContext which we will use for layout information.
+  ASTContext &Context;
+  
+  /// FinalOverriders - The final overriders of the most derived class.
+  const FinalOverriders Overriders;
+
+  /// VCallOffsetsForVBases - Keeps track of vcall offsets for the virtual
+  /// bases in this vtable.
+  llvm::DenseMap<const CXXRecordDecl *, VCallOffsetMap> VCallOffsetsForVBases;
+
+  /// VBaseOffsetOffsets - Contains the offsets of the virtual base offsets for
+  /// the most derived class.
+  VBaseOffsetOffsetsMapTy VBaseOffsetOffsets;
+  
+  /// Components - The components of the vtable being built.
+  llvm::SmallVector<VTableComponent, 64> Components;
+
+  /// AddressPoints - Address points for the vtable being built.
+  AddressPointsMapTy AddressPoints;
+
+  /// MethodInfo - Contains information about a method in a vtable.
+  /// (Used for computing 'this' pointer adjustment thunks.
+  struct MethodInfo {
+    /// BaseOffset - The base offset of this method.
+    const uint64_t BaseOffset;
+    
+    /// BaseOffsetInLayoutClass - The base offset in the layout class of this
+    /// method.
+    const uint64_t BaseOffsetInLayoutClass;
+    
+    /// VTableIndex - The index in the vtable that this method has.
+    /// (For destructors, this is the index of the complete destructor).
+    const uint64_t VTableIndex;
+    
+    MethodInfo(uint64_t BaseOffset, uint64_t BaseOffsetInLayoutClass, 
+               uint64_t VTableIndex)
+      : BaseOffset(BaseOffset), 
+      BaseOffsetInLayoutClass(BaseOffsetInLayoutClass),
+      VTableIndex(VTableIndex) { }
+    
+    MethodInfo() : BaseOffset(0), BaseOffsetInLayoutClass(0), VTableIndex(0) { }
+  };
+  
+  typedef llvm::DenseMap<const CXXMethodDecl *, MethodInfo> MethodInfoMapTy;
+  
+  /// MethodInfoMap - The information for all methods in the vtable we're
+  /// currently building.
+  MethodInfoMapTy MethodInfoMap;
+  
+  typedef llvm::DenseMap<uint64_t, ThunkInfo> VTableThunksMapTy;
+  
+  /// VTableThunks - The thunks by vtable index in the vtable currently being 
+  /// built.
+  VTableThunksMapTy VTableThunks;
+
+  typedef llvm::SmallVector<ThunkInfo, 1> ThunkInfoVectorTy;
+  typedef llvm::DenseMap<const CXXMethodDecl *, ThunkInfoVectorTy> ThunksMapTy;
+  
+  /// Thunks - A map that contains all the thunks needed for all methods in the
+  /// most derived class for which the vtable is currently being built.
+  ThunksMapTy Thunks;
+  
+  /// AddThunk - Add a thunk for the given method.
+  void AddThunk(const CXXMethodDecl *MD, const ThunkInfo &Thunk);
+  
+  /// ComputeThisAdjustments - Compute the 'this' pointer adjustments for the
+  /// part of the vtable we're currently building.
+  void ComputeThisAdjustments();
+  
+  typedef llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBasesSetTy;
+
+  /// PrimaryVirtualBases - All known virtual bases who are a primary base of
+  /// some other base.
+  VisitedVirtualBasesSetTy PrimaryVirtualBases;
+
+  /// ComputeReturnAdjustment - Compute the return adjustment given a return
+  /// adjustment base offset.
+  ReturnAdjustment ComputeReturnAdjustment(BaseOffset Offset);
+  
+  /// ComputeThisAdjustmentBaseOffset - Compute the base offset for adjusting
+  /// the 'this' pointer from the base subobject to the derived subobject.
+  BaseOffset ComputeThisAdjustmentBaseOffset(BaseSubobject Base,
+                                             BaseSubobject Derived) const;
+
+  /// ComputeThisAdjustment - Compute the 'this' pointer adjustment for the
+  /// given virtual member function, its offset in the layout class and its
+  /// final overrider.
+  ThisAdjustment 
+  ComputeThisAdjustment(const CXXMethodDecl *MD, 
+                        uint64_t BaseOffsetInLayoutClass,
+                        FinalOverriders::OverriderInfo Overrider);
+
+  /// AddMethod - Add a single virtual member function to the vtable
+  /// components vector.
+  void AddMethod(const CXXMethodDecl *MD, ReturnAdjustment ReturnAdjustment);
+
+  /// IsOverriderUsed - Returns whether the overrider will ever be used in this
+  /// part of the vtable. 
+  ///
+  /// Itanium C++ ABI 2.5.2:
+  ///
+  ///   struct A { virtual void f(); };
+  ///   struct B : virtual public A { int i; };
+  ///   struct C : virtual public A { int j; };
+  ///   struct D : public B, public C {};
+  ///
+  ///   When B and C are declared, A is a primary base in each case, so although
+  ///   vcall offsets are allocated in the A-in-B and A-in-C vtables, no this
+  ///   adjustment is required and no thunk is generated. However, inside D
+  ///   objects, A is no longer a primary base of C, so if we allowed calls to
+  ///   C::f() to use the copy of A's vtable in the C subobject, we would need
+  ///   to adjust this from C* to B::A*, which would require a third-party 
+  ///   thunk. Since we require that a call to C::f() first convert to A*, 
+  ///   C-in-D's copy of A's vtable is never referenced, so this is not 
+  ///   necessary.
+  bool IsOverriderUsed(const CXXMethodDecl *Overrider,
+                       uint64_t BaseOffsetInLayoutClass,
+                       const CXXRecordDecl *FirstBaseInPrimaryBaseChain,
+                       uint64_t FirstBaseOffsetInLayoutClass) const;
+
+  
+  /// AddMethods - Add the methods of this base subobject and all its
+  /// primary bases to the vtable components vector.
+  void AddMethods(BaseSubobject Base, uint64_t BaseOffsetInLayoutClass,                  
+                  const CXXRecordDecl *FirstBaseInPrimaryBaseChain,
+                  uint64_t FirstBaseOffsetInLayoutClass,
+                  PrimaryBasesSetVectorTy &PrimaryBases);
+
+  // LayoutVTable - Layout the vtable for the given base class, including its
+  // secondary vtables and any vtables for virtual bases.
+  void LayoutVTable();
+
+  /// LayoutPrimaryAndSecondaryVTables - Layout the primary vtable for the
+  /// given base subobject, as well as all its secondary vtables.
+  ///
+  /// \param BaseIsMorallyVirtual whether the base subobject is a virtual base
+  /// or a direct or indirect base of a virtual base.
+  ///
+  /// \param BaseIsVirtualInLayoutClass - Whether the base subobject is virtual
+  /// in the layout class. 
+  void LayoutPrimaryAndSecondaryVTables(BaseSubobject Base,
+                                        bool BaseIsMorallyVirtual,
+                                        bool BaseIsVirtualInLayoutClass,
+                                        uint64_t OffsetInLayoutClass);
+  
+  /// LayoutSecondaryVTables - Layout the secondary vtables for the given base
+  /// subobject.
+  ///
+  /// \param BaseIsMorallyVirtual whether the base subobject is a virtual base
+  /// or a direct or indirect base of a virtual base.
+  void LayoutSecondaryVTables(BaseSubobject Base, bool BaseIsMorallyVirtual,
+                              uint64_t OffsetInLayoutClass);
+
+  /// DeterminePrimaryVirtualBases - Determine the primary virtual bases in this
+  /// class hierarchy.
+  void DeterminePrimaryVirtualBases(const CXXRecordDecl *RD, 
+                                    uint64_t OffsetInLayoutClass,
+                                    VisitedVirtualBasesSetTy &VBases);
+
+  /// LayoutVTablesForVirtualBases - Layout vtables for all virtual bases of the
+  /// given base (excluding any primary bases).
+  void LayoutVTablesForVirtualBases(const CXXRecordDecl *RD, 
+                                    VisitedVirtualBasesSetTy &VBases);
+
+  /// isBuildingConstructionVTable - Return whether this vtable builder is
+  /// building a construction vtable.
+  bool isBuildingConstructorVTable() const { 
+    return MostDerivedClass != LayoutClass;
+  }
+
+public:
+  VTableBuilder(CodeGenVTables &VTables, const CXXRecordDecl *MostDerivedClass,
+                uint64_t MostDerivedClassOffset, bool MostDerivedClassIsVirtual,
+                const CXXRecordDecl *LayoutClass)
+    : VTables(VTables), MostDerivedClass(MostDerivedClass),
+    MostDerivedClassOffset(MostDerivedClassOffset), 
+    MostDerivedClassIsVirtual(MostDerivedClassIsVirtual), 
+    LayoutClass(LayoutClass), Context(MostDerivedClass->getASTContext()), 
+    Overriders(MostDerivedClass, MostDerivedClassOffset, LayoutClass) {
+
+    LayoutVTable();
+  }
+
+  ThunksMapTy::const_iterator thunks_begin() const {
+    return Thunks.begin();
+  }
+
+  ThunksMapTy::const_iterator thunks_end() const {
+    return Thunks.end();
+  }
+
+  const VBaseOffsetOffsetsMapTy &getVBaseOffsetOffsets() const {
+    return VBaseOffsetOffsets;
+  }
+
+  /// getNumVTableComponents - Return the number of components in the vtable
+  /// currently built.
+  uint64_t getNumVTableComponents() const {
+    return Components.size();
+  }
+
+  const uint64_t *vtable_components_data_begin() const {
+    return reinterpret_cast<const uint64_t *>(Components.begin());
+  }
+  
+  const uint64_t *vtable_components_data_end() const {
+    return reinterpret_cast<const uint64_t *>(Components.end());
+  }
+  
+  AddressPointsMapTy::const_iterator address_points_begin() const {
+    return AddressPoints.begin();
+  }
+
+  AddressPointsMapTy::const_iterator address_points_end() const {
+    return AddressPoints.end();
+  }
+
+  VTableThunksMapTy::const_iterator vtable_thunks_begin() const {
+    return VTableThunks.begin();
+  }
+
+  VTableThunksMapTy::const_iterator vtable_thunks_end() const {
+    return VTableThunks.end();
+  }
+
+  /// dumpLayout - Dump the vtable layout.
+  void dumpLayout(llvm::raw_ostream&);
+};
+
+void VTableBuilder::AddThunk(const CXXMethodDecl *MD, const ThunkInfo &Thunk) {
+  assert(!isBuildingConstructorVTable() && 
+         "Can't add thunks for construction vtable");
+
+  llvm::SmallVector<ThunkInfo, 1> &ThunksVector = Thunks[MD];
+  
+  // Check if we have this thunk already.
+  if (std::find(ThunksVector.begin(), ThunksVector.end(), Thunk) != 
+      ThunksVector.end())
+    return;
+  
+  ThunksVector.push_back(Thunk);
+}
+
+typedef llvm::SmallPtrSet<const CXXMethodDecl *, 8> OverriddenMethodsSetTy;
+
+/// ComputeAllOverriddenMethods - Given a method decl, will return a set of all
+/// the overridden methods that the function decl overrides.
+static void 
+ComputeAllOverriddenMethods(const CXXMethodDecl *MD,
+                            OverriddenMethodsSetTy& OverriddenMethods) {
+  assert(MD->isVirtual() && "Method is not virtual!");
+
+  for (CXXMethodDecl::method_iterator I = MD->begin_overridden_methods(),
+       E = MD->end_overridden_methods(); I != E; ++I) {
+    const CXXMethodDecl *OverriddenMD = *I;
+    
+    OverriddenMethods.insert(OverriddenMD);
+    
+    ComputeAllOverriddenMethods(OverriddenMD, OverriddenMethods);
+  }
+}
+
+void VTableBuilder::ComputeThisAdjustments() {
+  // Now go through the method info map and see if any of the methods need
+  // 'this' pointer adjustments.
+  for (MethodInfoMapTy::const_iterator I = MethodInfoMap.begin(),
+       E = MethodInfoMap.end(); I != E; ++I) {
+    const CXXMethodDecl *MD = I->first;
+    const MethodInfo &MethodInfo = I->second;
+
+    // Ignore adjustments for unused function pointers.
+    uint64_t VTableIndex = MethodInfo.VTableIndex;
+    if (Components[VTableIndex].getKind() == 
+        VTableComponent::CK_UnusedFunctionPointer)
+      continue;
+    
+    // Get the final overrider for this method.
+    FinalOverriders::OverriderInfo Overrider =
+      Overriders.getOverrider(BaseSubobject(MD->getParent(), 
+                                            MethodInfo.BaseOffset), MD);
+    
+    // Check if we need an adjustment at all.
+    if (MethodInfo.BaseOffsetInLayoutClass == Overrider.Offset) {
+      // When a return thunk is needed by a derived class that overrides a
+      // virtual base, gcc uses a virtual 'this' adjustment as well. 
+      // While the thunk itself might be needed by vtables in subclasses or
+      // in construction vtables, there doesn't seem to be a reason for using
+      // the thunk in this vtable. Still, we do so to match gcc.
+      if (VTableThunks.lookup(VTableIndex).Return.isEmpty())
+        continue;
+    }
+
+    ThisAdjustment ThisAdjustment =
+      ComputeThisAdjustment(MD, MethodInfo.BaseOffsetInLayoutClass, Overrider);
+
+    if (ThisAdjustment.isEmpty())
+      continue;
+
+    // Add it.
+    VTableThunks[VTableIndex].This = ThisAdjustment;
+
+    if (isa<CXXDestructorDecl>(MD)) {
+      // Add an adjustment for the deleting destructor as well.
+      VTableThunks[VTableIndex + 1].This = ThisAdjustment;
+    }
+  }
+
+  /// Clear the method info map.
+  MethodInfoMap.clear();
+  
+  if (isBuildingConstructorVTable()) {
+    // We don't need to store thunk information for construction vtables.
+    return;
+  }
+
+  for (VTableThunksMapTy::const_iterator I = VTableThunks.begin(),
+       E = VTableThunks.end(); I != E; ++I) {
+    const VTableComponent &Component = Components[I->first];
+    const ThunkInfo &Thunk = I->second;
+    const CXXMethodDecl *MD;
+    
+    switch (Component.getKind()) {
+    default:
+      llvm_unreachable("Unexpected vtable component kind!");
+    case VTableComponent::CK_FunctionPointer:
+      MD = Component.getFunctionDecl();
+      break;
+    case VTableComponent::CK_CompleteDtorPointer:
+      MD = Component.getDestructorDecl();
+      break;
+    case VTableComponent::CK_DeletingDtorPointer:
+      // We've already added the thunk when we saw the complete dtor pointer.
+      continue;
+    }
+
+    if (MD->getParent() == MostDerivedClass)
+      AddThunk(MD, Thunk);
+  }
+}
+
+ReturnAdjustment VTableBuilder::ComputeReturnAdjustment(BaseOffset Offset) {
+  ReturnAdjustment Adjustment;
+  
+  if (!Offset.isEmpty()) {
+    if (Offset.VirtualBase) {
+      // Get the virtual base offset offset.
+      if (Offset.DerivedClass == MostDerivedClass) {
+        // We can get the offset offset directly from our map.
+        Adjustment.VBaseOffsetOffset = 
+          VBaseOffsetOffsets.lookup(Offset.VirtualBase);
+      } else {
+        Adjustment.VBaseOffsetOffset = 
+          VTables.getVirtualBaseOffsetOffset(Offset.DerivedClass,
+                                             Offset.VirtualBase);
+      }
+    }
+
+    Adjustment.NonVirtual = Offset.NonVirtualOffset;
+  }
+  
+  return Adjustment;
+}
+
+BaseOffset
+VTableBuilder::ComputeThisAdjustmentBaseOffset(BaseSubobject Base,
+                                               BaseSubobject Derived) const {
+  const CXXRecordDecl *BaseRD = Base.getBase();
+  const CXXRecordDecl *DerivedRD = Derived.getBase();
+  
+  CXXBasePaths Paths(/*FindAmbiguities=*/true,
+                     /*RecordPaths=*/true, /*DetectVirtual=*/true);
+
+  if (!const_cast<CXXRecordDecl *>(DerivedRD)->
+      isDerivedFrom(const_cast<CXXRecordDecl *>(BaseRD), Paths)) {
+    assert(false && "Class must be derived from the passed in base class!");
+    return BaseOffset();
+  }
+
+  // We have to go through all the paths, and see which one leads us to the
+  // right base subobject.
+  for (CXXBasePaths::const_paths_iterator I = Paths.begin(), E = Paths.end();
+       I != E; ++I) {
+    BaseOffset Offset = ComputeBaseOffset(Context, DerivedRD, *I);
+    
+    // FIXME: Should not use * 8 here.
+    uint64_t OffsetToBaseSubobject = Offset.NonVirtualOffset * 8;
+    
+    if (Offset.VirtualBase) {
+      // If we have a virtual base class, the non-virtual offset is relative
+      // to the virtual base class offset.
+      const ASTRecordLayout &LayoutClassLayout =
+        Context.getASTRecordLayout(LayoutClass);
+      
+      /// Get the virtual base offset, relative to the most derived class 
+      /// layout.
+      OffsetToBaseSubobject += 
+        LayoutClassLayout.getVBaseClassOffset(Offset.VirtualBase);
+    } else {
+      // Otherwise, the non-virtual offset is relative to the derived class 
+      // offset.
+      OffsetToBaseSubobject += Derived.getBaseOffset();
+    }
+    
+    // Check if this path gives us the right base subobject.
+    if (OffsetToBaseSubobject == Base.getBaseOffset()) {
+      // Since we're going from the base class _to_ the derived class, we'll
+      // invert the non-virtual offset here.
+      Offset.NonVirtualOffset = -Offset.NonVirtualOffset;
+      return Offset;
+    }      
+  }
+  
+  return BaseOffset();
+}
+  
+ThisAdjustment 
+VTableBuilder::ComputeThisAdjustment(const CXXMethodDecl *MD, 
+                                     uint64_t BaseOffsetInLayoutClass,
+                                     FinalOverriders::OverriderInfo Overrider) {
+  // Ignore adjustments for pure virtual member functions.
+  if (Overrider.Method->isPure())
+    return ThisAdjustment();
+  
+  BaseSubobject OverriddenBaseSubobject(MD->getParent(),
+                                        BaseOffsetInLayoutClass);
+  
+  BaseSubobject OverriderBaseSubobject(Overrider.Method->getParent(),
+                                       Overrider.Offset);
+  
+  // Compute the adjustment offset.
+  BaseOffset Offset = ComputeThisAdjustmentBaseOffset(OverriddenBaseSubobject,
+                                                      OverriderBaseSubobject);
+  if (Offset.isEmpty())
+    return ThisAdjustment();
+
+  ThisAdjustment Adjustment;
+  
+  if (Offset.VirtualBase) {
+    // Get the vcall offset map for this virtual base.
+    VCallOffsetMap &VCallOffsets = VCallOffsetsForVBases[Offset.VirtualBase];
+
+    if (VCallOffsets.empty()) {
+      // We don't have vcall offsets for this virtual base, go ahead and
+      // build them.
+      VCallAndVBaseOffsetBuilder Builder(MostDerivedClass, MostDerivedClass,
+                                         /*FinalOverriders=*/0,
+                                         BaseSubobject(Offset.VirtualBase, 0),                                           
+                                         /*BaseIsVirtual=*/true,
+                                         /*OffsetInLayoutClass=*/0);
+        
+      VCallOffsets = Builder.getVCallOffsets();
+    }
+      
+    Adjustment.VCallOffsetOffset = VCallOffsets.getVCallOffsetOffset(MD);
+  }
+
+  // Set the non-virtual part of the adjustment.
+  Adjustment.NonVirtual = Offset.NonVirtualOffset;
+  
+  return Adjustment;
+}
+  
+void 
+VTableBuilder::AddMethod(const CXXMethodDecl *MD,
+                         ReturnAdjustment ReturnAdjustment) {
+  if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {
+    assert(ReturnAdjustment.isEmpty() && 
+           "Destructor can't have return adjustment!");
+
+    // Add both the complete destructor and the deleting destructor.
+    Components.push_back(VTableComponent::MakeCompleteDtor(DD));
+    Components.push_back(VTableComponent::MakeDeletingDtor(DD));
+  } else {
+    // Add the return adjustment if necessary.
+    if (!ReturnAdjustment.isEmpty())
+      VTableThunks[Components.size()].Return = ReturnAdjustment;
+
+    // Add the function.
+    Components.push_back(VTableComponent::MakeFunction(MD));
+  }
+}
+
+/// OverridesIndirectMethodInBase - Return whether the given member function
+/// overrides any methods in the set of given bases. 
+/// Unlike OverridesMethodInBase, this checks "overriders of overriders".
+/// For example, if we have:
+///
+/// struct A { virtual void f(); }
+/// struct B : A { virtual void f(); }
+/// struct C : B { virtual void f(); }
+///
+/// OverridesIndirectMethodInBase will return true if given C::f as the method 
+/// and { A } as the set of bases.
+static bool
+OverridesIndirectMethodInBases(const CXXMethodDecl *MD,
+                               VTableBuilder::PrimaryBasesSetVectorTy &Bases) {
+  if (Bases.count(MD->getParent()))
+    return true;
+  
+  for (CXXMethodDecl::method_iterator I = MD->begin_overridden_methods(),
+       E = MD->end_overridden_methods(); I != E; ++I) {
+    const CXXMethodDecl *OverriddenMD = *I;
+    
+    // Check "indirect overriders".
+    if (OverridesIndirectMethodInBases(OverriddenMD, Bases))
+      return true;
+  }
+   
+  return false;
+}
+
+bool 
+VTableBuilder::IsOverriderUsed(const CXXMethodDecl *Overrider,
+                               uint64_t BaseOffsetInLayoutClass,
+                               const CXXRecordDecl *FirstBaseInPrimaryBaseChain,
+                               uint64_t FirstBaseOffsetInLayoutClass) const {
+  // If the base and the first base in the primary base chain have the same
+  // offsets, then this overrider will be used.
+  if (BaseOffsetInLayoutClass == FirstBaseOffsetInLayoutClass)
+   return true;
+
+  // We know now that Base (or a direct or indirect base of it) is a primary
+  // base in part of the class hierarchy, but not a primary base in the most 
+  // derived class.
+  
+  // If the overrider is the first base in the primary base chain, we know
+  // that the overrider will be used.
+  if (Overrider->getParent() == FirstBaseInPrimaryBaseChain)
+    return true;
+  
+  VTableBuilder::PrimaryBasesSetVectorTy PrimaryBases;
+
+  const CXXRecordDecl *RD = FirstBaseInPrimaryBaseChain;
+  PrimaryBases.insert(RD);
+
+  // Now traverse the base chain, starting with the first base, until we find
+  // the base that is no longer a primary base.
+  while (true) {
+    const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
+    const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
+    
+    if (!PrimaryBase)
+      break;
+    
+    if (Layout.getPrimaryBaseWasVirtual()) {
+      assert(Layout.getVBaseClassOffset(PrimaryBase) == 0 && 
+             "Primary base should always be at offset 0!");
+
+      const ASTRecordLayout &LayoutClassLayout =
+        Context.getASTRecordLayout(LayoutClass);
+
+      // Now check if this is the primary base that is not a primary base in the
+      // most derived class.
+      if (LayoutClassLayout.getVBaseClassOffset(PrimaryBase) !=
+          FirstBaseOffsetInLayoutClass) {
+        // We found it, stop walking the chain.
+        break;
+      }
+    } else {
+      assert(Layout.getBaseClassOffset(PrimaryBase) == 0 && 
+             "Primary base should always be at offset 0!");
+    }
+    
+    if (!PrimaryBases.insert(PrimaryBase))
+      assert(false && "Found a duplicate primary base!");
+
+    RD = PrimaryBase;
+  }
+  
+  // If the final overrider is an override of one of the primary bases,
+  // then we know that it will be used.
+  return OverridesIndirectMethodInBases(Overrider, PrimaryBases);
+}
+
+/// FindNearestOverriddenMethod - Given a method, returns the overridden method
+/// from the nearest base. Returns null if no method was found.
+static const CXXMethodDecl * 
+FindNearestOverriddenMethod(const CXXMethodDecl *MD,
+                            VTableBuilder::PrimaryBasesSetVectorTy &Bases) {
+  OverriddenMethodsSetTy OverriddenMethods;
+  ComputeAllOverriddenMethods(MD, OverriddenMethods);
+  
+  for (int I = Bases.size(), E = 0; I != E; --I) {
+    const CXXRecordDecl *PrimaryBase = Bases[I - 1];
+
+    // Now check the overriden methods.
+    for (OverriddenMethodsSetTy::const_iterator I = OverriddenMethods.begin(),
+         E = OverriddenMethods.end(); I != E; ++I) {
+      const CXXMethodDecl *OverriddenMD = *I;
+      
+      // We found our overridden method.
+      if (OverriddenMD->getParent() == PrimaryBase)
+        return OverriddenMD;
+    }
+  }
+  
+  return 0;
+}  
+
+void
+VTableBuilder::AddMethods(BaseSubobject Base, uint64_t BaseOffsetInLayoutClass,                  
+                          const CXXRecordDecl *FirstBaseInPrimaryBaseChain,
+                          uint64_t FirstBaseOffsetInLayoutClass,
+                          PrimaryBasesSetVectorTy &PrimaryBases) {
+  const CXXRecordDecl *RD = Base.getBase();
+  const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
+
+  if (const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase()) {
+    uint64_t PrimaryBaseOffset;
+    uint64_t PrimaryBaseOffsetInLayoutClass;
+    if (Layout.getPrimaryBaseWasVirtual()) {
+      assert(Layout.getVBaseClassOffset(PrimaryBase) == 0 &&
+             "Primary vbase should have a zero offset!");
+      
+      const ASTRecordLayout &MostDerivedClassLayout =
+        Context.getASTRecordLayout(MostDerivedClass);
+      
+      PrimaryBaseOffset = 
+        MostDerivedClassLayout.getVBaseClassOffset(PrimaryBase);
+      
+      const ASTRecordLayout &LayoutClassLayout =
+        Context.getASTRecordLayout(LayoutClass);
+
+      PrimaryBaseOffsetInLayoutClass =
+        LayoutClassLayout.getVBaseClassOffset(PrimaryBase);
+    } else {
+      assert(Layout.getBaseClassOffset(PrimaryBase) == 0 &&
+             "Primary base should have a zero offset!");
+
+      PrimaryBaseOffset = Base.getBaseOffset();
+      PrimaryBaseOffsetInLayoutClass = BaseOffsetInLayoutClass;
+    }
+
+    AddMethods(BaseSubobject(PrimaryBase, PrimaryBaseOffset),
+               PrimaryBaseOffsetInLayoutClass, FirstBaseInPrimaryBaseChain, 
+               FirstBaseOffsetInLayoutClass, PrimaryBases);
+    
+    if (!PrimaryBases.insert(PrimaryBase))
+      assert(false && "Found a duplicate primary base!");
+  }
+
+  // Now go through all virtual member functions and add them.
+  for (CXXRecordDecl::method_iterator I = RD->method_begin(),
+       E = RD->method_end(); I != E; ++I) {
+    const CXXMethodDecl *MD = *I;
+  
+    if (!MD->isVirtual())
+      continue;
+
+    // Get the final overrider.
+    FinalOverriders::OverriderInfo Overrider = 
+      Overriders.getOverrider(Base, MD);
+
+    // Check if this virtual member function overrides a method in a primary
+    // base. If this is the case, and the return type doesn't require adjustment
+    // then we can just use the member function from the primary base.
+    if (const CXXMethodDecl *OverriddenMD = 
+          FindNearestOverriddenMethod(MD, PrimaryBases)) {
+      if (ComputeReturnAdjustmentBaseOffset(Context, MD, 
+                                            OverriddenMD).isEmpty()) {
+        // Replace the method info of the overridden method with our own
+        // method.
+        assert(MethodInfoMap.count(OverriddenMD) && 
+               "Did not find the overridden method!");
+        MethodInfo &OverriddenMethodInfo = MethodInfoMap[OverriddenMD];
+        
+        MethodInfo MethodInfo(Base.getBaseOffset(), 
+                              BaseOffsetInLayoutClass,
+                              OverriddenMethodInfo.VTableIndex);
+
+        assert(!MethodInfoMap.count(MD) &&
+               "Should not have method info for this method yet!");
+        
+        MethodInfoMap.insert(std::make_pair(MD, MethodInfo));
+        MethodInfoMap.erase(OverriddenMD);
+        
+        // If the overridden method exists in a virtual base class or a direct
+        // or indirect base class of a virtual base class, we need to emit a
+        // thunk if we ever have a class hierarchy where the base class is not
+        // a primary base in the complete object.
+        if (!isBuildingConstructorVTable() && OverriddenMD != MD) {
+          // Compute the this adjustment.
+          ThisAdjustment ThisAdjustment =
+            ComputeThisAdjustment(OverriddenMD, BaseOffsetInLayoutClass,
+                                  Overrider);
+
+          if (ThisAdjustment.VCallOffsetOffset &&
+              Overrider.Method->getParent() == MostDerivedClass) {
+            // This is a virtual thunk for the most derived class, add it.
+            AddThunk(Overrider.Method, 
+                     ThunkInfo(ThisAdjustment, ReturnAdjustment()));
+          }
+        }
+
+        continue;
+      }
+    }
+
+    // Insert the method info for this method.
+    MethodInfo MethodInfo(Base.getBaseOffset(), BaseOffsetInLayoutClass,
+                          Components.size());
+
+    assert(!MethodInfoMap.count(MD) &&
+           "Should not have method info for this method yet!");
+    MethodInfoMap.insert(std::make_pair(MD, MethodInfo));
+
+    // Check if this overrider is going to be used.
+    const CXXMethodDecl *OverriderMD = Overrider.Method;
+    if (!IsOverriderUsed(OverriderMD, BaseOffsetInLayoutClass,
+                         FirstBaseInPrimaryBaseChain, 
+                         FirstBaseOffsetInLayoutClass)) {
+      Components.push_back(VTableComponent::MakeUnusedFunction(OverriderMD));
+      continue;
+    }
+    
+    // Check if this overrider needs a return adjustment.
+    BaseOffset ReturnAdjustmentOffset = 
+      Overriders.getReturnAdjustmentOffset(Base, MD);
+
+    ReturnAdjustment ReturnAdjustment = 
+      ComputeReturnAdjustment(ReturnAdjustmentOffset);
+    
+    AddMethod(Overrider.Method, ReturnAdjustment);
+  }
+}
+
+void VTableBuilder::LayoutVTable() {
+  LayoutPrimaryAndSecondaryVTables(BaseSubobject(MostDerivedClass, 0),
+                                   /*BaseIsMorallyVirtual=*/false,
+                                   MostDerivedClassIsVirtual,
+                                   MostDerivedClassOffset);
+  
+  VisitedVirtualBasesSetTy VBases;
+  
+  // Determine the primary virtual bases.
+  DeterminePrimaryVirtualBases(MostDerivedClass, MostDerivedClassOffset,
+                               VBases);
+  VBases.clear();
+  
+  LayoutVTablesForVirtualBases(MostDerivedClass, VBases);
+}
+  
+void
+VTableBuilder::LayoutPrimaryAndSecondaryVTables(BaseSubobject Base,
+                                                bool BaseIsMorallyVirtual,
+                                                bool BaseIsVirtualInLayoutClass,
+                                                uint64_t OffsetInLayoutClass) {
+  assert(Base.getBase()->isDynamicClass() && "class does not have a vtable!");
+
+  // Add vcall and vbase offsets for this vtable.
+  VCallAndVBaseOffsetBuilder Builder(MostDerivedClass, LayoutClass, &Overriders,
+                                     Base, BaseIsVirtualInLayoutClass, 
+                                     OffsetInLayoutClass);
+  Components.append(Builder.components_begin(), Builder.components_end());
+  
+  // Check if we need to add these vcall offsets.
+  if (BaseIsVirtualInLayoutClass && !Builder.getVCallOffsets().empty()) {
+    VCallOffsetMap &VCallOffsets = VCallOffsetsForVBases[Base.getBase()];
+    
+    if (VCallOffsets.empty())
+      VCallOffsets = Builder.getVCallOffsets();
+  }
+
+  // If we're laying out the most derived class we want to keep track of the
+  // virtual base class offset offsets.
+  if (Base.getBase() == MostDerivedClass)
+    VBaseOffsetOffsets = Builder.getVBaseOffsetOffsets();
+
+  // Add the offset to top.
+  // FIXME: We should not use / 8 here.
+  int64_t OffsetToTop = -(int64_t)(OffsetInLayoutClass -
+                                   MostDerivedClassOffset) / 8;
+  Components.push_back(VTableComponent::MakeOffsetToTop(OffsetToTop));
+  
+  // Next, add the RTTI.
+  Components.push_back(VTableComponent::MakeRTTI(MostDerivedClass));
+  
+  uint64_t AddressPoint = Components.size();
+
+  // Now go through all virtual member functions and add them.
+  PrimaryBasesSetVectorTy PrimaryBases;
+  AddMethods(Base, OffsetInLayoutClass, Base.getBase(), OffsetInLayoutClass, 
+             PrimaryBases);
+
+  // Compute 'this' pointer adjustments.
+  ComputeThisAdjustments();
+
+  // Add all address points.
+  const CXXRecordDecl *RD = Base.getBase();
+  while (true) {
+    AddressPoints.insert(std::make_pair(BaseSubobject(RD, OffsetInLayoutClass),
+                                        AddressPoint));
+
+    const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
+    const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
+    
+    if (!PrimaryBase)
+      break;
+    
+    if (Layout.getPrimaryBaseWasVirtual()) {
+      // Check if this virtual primary base is a primary base in the layout
+      // class. If it's not, we don't want to add it.
+      const ASTRecordLayout &LayoutClassLayout =
+        Context.getASTRecordLayout(LayoutClass);
+
+      if (LayoutClassLayout.getVBaseClassOffset(PrimaryBase) !=
+          OffsetInLayoutClass) {
+        // We don't want to add this class (or any of its primary bases).
+        break;
+      }
+    }
+
+    RD = PrimaryBase;
+  }
+
+  // Layout secondary vtables.
+  LayoutSecondaryVTables(Base, BaseIsMorallyVirtual, OffsetInLayoutClass);
+}
+
+void VTableBuilder::LayoutSecondaryVTables(BaseSubobject Base,
+                                           bool BaseIsMorallyVirtual,
+                                           uint64_t OffsetInLayoutClass) {
+  // Itanium C++ ABI 2.5.2:
+  //   Following the primary virtual table of a derived class are secondary 
+  //   virtual tables for each of its proper base classes, except any primary
+  //   base(s) with which it shares its primary virtual table.
+
+  const CXXRecordDecl *RD = Base.getBase();
+  const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
+  const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
+  
+  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
+       E = RD->bases_end(); I != E; ++I) {
+    // Ignore virtual bases, we'll emit them later.
+    if (I->isVirtual())
+      continue;
+    
+    const CXXRecordDecl *BaseDecl = 
+      cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+
+    // Ignore bases that don't have a vtable.
+    if (!BaseDecl->isDynamicClass())
+      continue;
+
+    if (isBuildingConstructorVTable()) {
+      // Itanium C++ ABI 2.6.4:
+      //   Some of the base class subobjects may not need construction virtual
+      //   tables, which will therefore not be present in the construction
+      //   virtual table group, even though the subobject virtual tables are
+      //   present in the main virtual table group for the complete object.
+      if (!BaseIsMorallyVirtual && !BaseDecl->getNumVBases())
+        continue;
+    }
+
+    // Get the base offset of this base.
+    uint64_t RelativeBaseOffset = Layout.getBaseClassOffset(BaseDecl);
+    uint64_t BaseOffset = Base.getBaseOffset() + RelativeBaseOffset;
+    
+    uint64_t BaseOffsetInLayoutClass = OffsetInLayoutClass + RelativeBaseOffset;
+    
+    // Don't emit a secondary vtable for a primary base. We might however want 
+    // to emit secondary vtables for other bases of this base.
+    if (BaseDecl == PrimaryBase) {
+      LayoutSecondaryVTables(BaseSubobject(BaseDecl, BaseOffset),
+                             BaseIsMorallyVirtual, BaseOffsetInLayoutClass);
+      continue;
+    }
+
+    // Layout the primary vtable (and any secondary vtables) for this base.
+    LayoutPrimaryAndSecondaryVTables(BaseSubobject(BaseDecl, BaseOffset),
+                                     BaseIsMorallyVirtual,
+                                     /*BaseIsVirtualInLayoutClass=*/false,
+                                     BaseOffsetInLayoutClass);
+  }
+}
+
+void
+VTableBuilder::DeterminePrimaryVirtualBases(const CXXRecordDecl *RD,
+                                            uint64_t OffsetInLayoutClass,
+                                            VisitedVirtualBasesSetTy &VBases) {
+  const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
+  
+  // Check if this base has a primary base.
+  if (const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase()) {
+
+    // Check if it's virtual.
+    if (Layout.getPrimaryBaseWasVirtual()) {
+      bool IsPrimaryVirtualBase = true;
+
+      if (isBuildingConstructorVTable()) {
+        // Check if the base is actually a primary base in the class we use for
+        // layout.
+        const ASTRecordLayout &LayoutClassLayout =
+          Context.getASTRecordLayout(LayoutClass);
+
+        uint64_t PrimaryBaseOffsetInLayoutClass =
+          LayoutClassLayout.getVBaseClassOffset(PrimaryBase);
+        
+        // We know that the base is not a primary base in the layout class if 
+        // the base offsets are different.
+        if (PrimaryBaseOffsetInLayoutClass != OffsetInLayoutClass)
+          IsPrimaryVirtualBase = false;
+      }
+        
+      if (IsPrimaryVirtualBase)
+        PrimaryVirtualBases.insert(PrimaryBase);
+    }
+  }
+
+  // Traverse bases, looking for more primary virtual bases.
+  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
+       E = RD->bases_end(); I != E; ++I) {
+    const CXXRecordDecl *BaseDecl = 
+      cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+
+    uint64_t BaseOffsetInLayoutClass;
+    
+    if (I->isVirtual()) {
+      if (!VBases.insert(BaseDecl))
+        continue;
+      
+      const ASTRecordLayout &LayoutClassLayout =
+        Context.getASTRecordLayout(LayoutClass);
+
+      BaseOffsetInLayoutClass = LayoutClassLayout.getVBaseClassOffset(BaseDecl);
+    } else {
+      BaseOffsetInLayoutClass = 
+        OffsetInLayoutClass + Layout.getBaseClassOffset(BaseDecl);
+    }
+
+    DeterminePrimaryVirtualBases(BaseDecl, BaseOffsetInLayoutClass, VBases);
+  }
+}
+
+void
+VTableBuilder::LayoutVTablesForVirtualBases(const CXXRecordDecl *RD, 
+                                            VisitedVirtualBasesSetTy &VBases) {
+  // Itanium C++ ABI 2.5.2:
+  //   Then come the virtual base virtual tables, also in inheritance graph
+  //   order, and again excluding primary bases (which share virtual tables with
+  //   the classes for which they are primary).
+  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
+       E = RD->bases_end(); I != E; ++I) {
+    const CXXRecordDecl *BaseDecl = 
+      cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+
+    // Check if this base needs a vtable. (If it's virtual, not a primary base
+    // of some other class, and we haven't visited it before).
+    if (I->isVirtual() && BaseDecl->isDynamicClass() && 
+        !PrimaryVirtualBases.count(BaseDecl) && VBases.insert(BaseDecl)) {
+      const ASTRecordLayout &MostDerivedClassLayout =
+        Context.getASTRecordLayout(MostDerivedClass);
+      uint64_t BaseOffset = 
+        MostDerivedClassLayout.getVBaseClassOffset(BaseDecl);
+      
+      const ASTRecordLayout &LayoutClassLayout =
+        Context.getASTRecordLayout(LayoutClass);
+      uint64_t BaseOffsetInLayoutClass = 
+        LayoutClassLayout.getVBaseClassOffset(BaseDecl);
+
+      LayoutPrimaryAndSecondaryVTables(BaseSubobject(BaseDecl, BaseOffset),
+                                       /*BaseIsMorallyVirtual=*/true,
+                                       /*BaseIsVirtualInLayoutClass=*/true,
+                                       BaseOffsetInLayoutClass);
+    }
+    
+    // We only need to check the base for virtual base vtables if it actually
+    // has virtual bases.
+    if (BaseDecl->getNumVBases())
+      LayoutVTablesForVirtualBases(BaseDecl, VBases);
+  }
+}
+
+/// dumpLayout - Dump the vtable layout.
+void VTableBuilder::dumpLayout(llvm::raw_ostream& Out) {
+
+  if (isBuildingConstructorVTable()) {
+    Out << "Construction vtable for ('";
+    Out << MostDerivedClass->getQualifiedNameAsString() << "', ";
+    // FIXME: Don't use / 8 .
+    Out << MostDerivedClassOffset / 8 << ") in '";
+    Out << LayoutClass->getQualifiedNameAsString();
+  } else {
+    Out << "Vtable for '";
+    Out << MostDerivedClass->getQualifiedNameAsString();
+  }
+  Out << "' (" << Components.size() << " entries).\n";
+
+  // Iterate through the address points and insert them into a new map where
+  // they are keyed by the index and not the base object.
+  // Since an address point can be shared by multiple subobjects, we use an
+  // STL multimap.
+  std::multimap<uint64_t, BaseSubobject> AddressPointsByIndex;
+  for (AddressPointsMapTy::const_iterator I = AddressPoints.begin(), 
+       E = AddressPoints.end(); I != E; ++I) {
+    const BaseSubobject& Base = I->first;
+    uint64_t Index = I->second;
+    
+    AddressPointsByIndex.insert(std::make_pair(Index, Base));
+  }
+  
+  for (unsigned I = 0, E = Components.size(); I != E; ++I) {
+    uint64_t Index = I;
+
+    Out << llvm::format("%4d | ", I);
+
+    const VTableComponent &Component = Components[I];
+
+    // Dump the component.
+    switch (Component.getKind()) {
+
+    case VTableComponent::CK_VCallOffset:
+      Out << "vcall_offset (" << Component.getVCallOffset() << ")";
+      break;
+
+    case VTableComponent::CK_VBaseOffset:
+      Out << "vbase_offset (" << Component.getVBaseOffset() << ")";
+      break;
+
+    case VTableComponent::CK_OffsetToTop:
+      Out << "offset_to_top (" << Component.getOffsetToTop() << ")";
+      break;
+    
+    case VTableComponent::CK_RTTI:
+      Out << Component.getRTTIDecl()->getQualifiedNameAsString() << " RTTI";
+      break;
+    
+    case VTableComponent::CK_FunctionPointer: {
+      const CXXMethodDecl *MD = Component.getFunctionDecl();
+
+      std::string Str = 
+        PredefinedExpr::ComputeName(PredefinedExpr::PrettyFunctionNoVirtual, 
+                                    MD);
+      Out << Str;
+      if (MD->isPure())
+        Out << " [pure]";
+
+      ThunkInfo Thunk = VTableThunks.lookup(I);
+      if (!Thunk.isEmpty()) {
+        // If this function pointer has a return adjustment, dump it.
+        if (!Thunk.Return.isEmpty()) {
+          Out << "\n       [return adjustment: ";
+          Out << Thunk.Return.NonVirtual << " non-virtual";
+          
+          if (Thunk.Return.VBaseOffsetOffset) {
+            Out << ", " << Thunk.Return.VBaseOffsetOffset;
+            Out << " vbase offset offset";
+          }
+
+          Out << ']';
+        }
+
+        // If this function pointer has a 'this' pointer adjustment, dump it.
+        if (!Thunk.This.isEmpty()) {
+          Out << "\n       [this adjustment: ";
+          Out << Thunk.This.NonVirtual << " non-virtual";
+          
+          if (Thunk.This.VCallOffsetOffset) {
+            Out << ", " << Thunk.This.VCallOffsetOffset;
+            Out << " vcall offset offset";
+          }
+
+          Out << ']';
+        }          
+      }
+
+      break;
+    }
+
+    case VTableComponent::CK_CompleteDtorPointer: 
+    case VTableComponent::CK_DeletingDtorPointer: {
+      bool IsComplete = 
+        Component.getKind() == VTableComponent::CK_CompleteDtorPointer;
+      
+      const CXXDestructorDecl *DD = Component.getDestructorDecl();
+      
+      Out << DD->getQualifiedNameAsString();
+      if (IsComplete)
+        Out << "() [complete]";
+      else
+        Out << "() [deleting]";
+
+      if (DD->isPure())
+        Out << " [pure]";
+
+      ThunkInfo Thunk = VTableThunks.lookup(I);
+      if (!Thunk.isEmpty()) {
+        // If this destructor has a 'this' pointer adjustment, dump it.
+        if (!Thunk.This.isEmpty()) {
+          Out << "\n       [this adjustment: ";
+          Out << Thunk.This.NonVirtual << " non-virtual";
+          
+          if (Thunk.This.VCallOffsetOffset) {
+            Out << ", " << Thunk.This.VCallOffsetOffset;
+            Out << " vcall offset offset";
+          }
+          
+          Out << ']';
+        }          
+      }        
+
+      break;
+    }
+
+    case VTableComponent::CK_UnusedFunctionPointer: {
+      const CXXMethodDecl *MD = Component.getUnusedFunctionDecl();
+
+      std::string Str = 
+        PredefinedExpr::ComputeName(PredefinedExpr::PrettyFunctionNoVirtual, 
+                                    MD);
+      Out << "[unused] " << Str;
+      if (MD->isPure())
+        Out << " [pure]";
+    }
+
+    }
+
+    Out << '\n';
+    
+    // Dump the next address point.
+    uint64_t NextIndex = Index + 1;
+    if (AddressPointsByIndex.count(NextIndex)) {
+      if (AddressPointsByIndex.count(NextIndex) == 1) {
+        const BaseSubobject &Base = 
+          AddressPointsByIndex.find(NextIndex)->second;
+        
+        // FIXME: Instead of dividing by 8, we should be using CharUnits.
+        Out << "       -- (" << Base.getBase()->getQualifiedNameAsString();
+        Out << ", " << Base.getBaseOffset() / 8 << ") vtable address --\n";
+      } else {
+        uint64_t BaseOffset = 
+          AddressPointsByIndex.lower_bound(NextIndex)->second.getBaseOffset();
+        
+        // We store the class names in a set to get a stable order.
+        std::set<std::string> ClassNames;
+        for (std::multimap<uint64_t, BaseSubobject>::const_iterator I =
+             AddressPointsByIndex.lower_bound(NextIndex), E =
+             AddressPointsByIndex.upper_bound(NextIndex); I != E; ++I) {
+          assert(I->second.getBaseOffset() == BaseOffset &&
+                 "Invalid base offset!");
+          const CXXRecordDecl *RD = I->second.getBase();
+          ClassNames.insert(RD->getQualifiedNameAsString());
+        }
+        
+        for (std::set<std::string>::const_iterator I = ClassNames.begin(),
+             E = ClassNames.end(); I != E; ++I) {
+          // FIXME: Instead of dividing by 8, we should be using CharUnits.
+          Out << "       -- (" << *I;
+          Out << ", " << BaseOffset / 8 << ") vtable address --\n";
+        }
+      }
+    }
+  }
+
+  Out << '\n';
+  
+  if (isBuildingConstructorVTable())
+    return;
+  
+  if (MostDerivedClass->getNumVBases()) {
+    // We store the virtual base class names and their offsets in a map to get
+    // a stable order.
+
+    std::map<std::string, int64_t> ClassNamesAndOffsets;
+    for (VBaseOffsetOffsetsMapTy::const_iterator I = VBaseOffsetOffsets.begin(),
+         E = VBaseOffsetOffsets.end(); I != E; ++I) {
+      std::string ClassName = I->first->getQualifiedNameAsString();
+      int64_t OffsetOffset = I->second;
+      ClassNamesAndOffsets.insert(std::make_pair(ClassName, OffsetOffset));
+    }
+    
+    Out << "Virtual base offset offsets for '";
+    Out << MostDerivedClass->getQualifiedNameAsString() << "' (";
+    Out << ClassNamesAndOffsets.size();
+    Out << (ClassNamesAndOffsets.size() == 1 ? " entry" : " entries") << ").\n";
+
+    for (std::map<std::string, int64_t>::const_iterator I =
+         ClassNamesAndOffsets.begin(), E = ClassNamesAndOffsets.end(); 
+         I != E; ++I)
+      Out << "   " << I->first << " | " << I->second << '\n';
+
+    Out << "\n";
+  }
+  
+  if (!Thunks.empty()) {
+    // We store the method names in a map to get a stable order.
+    std::map<std::string, const CXXMethodDecl *> MethodNamesAndDecls;
+    
+    for (ThunksMapTy::const_iterator I = Thunks.begin(), E = Thunks.end();
+         I != E; ++I) {
+      const CXXMethodDecl *MD = I->first;
+      std::string MethodName = 
+        PredefinedExpr::ComputeName(PredefinedExpr::PrettyFunctionNoVirtual,
+                                    MD);
+      
+      MethodNamesAndDecls.insert(std::make_pair(MethodName, MD));
+    }
+
+    for (std::map<std::string, const CXXMethodDecl *>::const_iterator I =
+         MethodNamesAndDecls.begin(), E = MethodNamesAndDecls.end(); 
+         I != E; ++I) {
+      const std::string &MethodName = I->first;
+      const CXXMethodDecl *MD = I->second;
+
+      ThunkInfoVectorTy ThunksVector = Thunks[MD];
+      std::sort(ThunksVector.begin(), ThunksVector.end());
+
+      Out << "Thunks for '" << MethodName << "' (" << ThunksVector.size();
+      Out << (ThunksVector.size() == 1 ? " entry" : " entries") << ").\n";
+      
+      for (unsigned I = 0, E = ThunksVector.size(); I != E; ++I) {
+        const ThunkInfo &Thunk = ThunksVector[I];
+
+        Out << llvm::format("%4d | ", I);
+        
+        // If this function pointer has a return pointer adjustment, dump it.
+        if (!Thunk.Return.isEmpty()) {
+          Out << "return adjustment: " << Thunk.This.NonVirtual;
+          Out << " non-virtual";
+          if (Thunk.Return.VBaseOffsetOffset) {
+            Out << ", " << Thunk.Return.VBaseOffsetOffset;
+            Out << " vbase offset offset";
+          }
+
+          if (!Thunk.This.isEmpty())
+            Out << "\n       ";
+        }
+
+        // If this function pointer has a 'this' pointer adjustment, dump it.
+        if (!Thunk.This.isEmpty()) {
+          Out << "this adjustment: ";
+          Out << Thunk.This.NonVirtual << " non-virtual";
+          
+          if (Thunk.This.VCallOffsetOffset) {
+            Out << ", " << Thunk.This.VCallOffsetOffset;
+            Out << " vcall offset offset";
+          }
+        }
+        
+        Out << '\n';
+      }
+      
+      Out << '\n';
+
+    }
+  }
+}
+  
+}
+
+void CodeGenVTables::ComputeMethodVTableIndices(const CXXRecordDecl *RD) {
+  
+  // Itanium C++ ABI 2.5.2:
+  //   The order of the virtual function pointers in a virtual table is the 
+  //   order of declaration of the corresponding member functions in the class.
+  //
+  //   There is an entry for any virtual function declared in a class, 
+  //   whether it is a new function or overrides a base class function, 
+  //   unless it overrides a function from the primary base, and conversion
+  //   between their return types does not require an adjustment. 
+
+  int64_t CurrentIndex = 0;
+  
+  const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
+  const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
+  
+  if (PrimaryBase) {
+    assert(PrimaryBase->isDefinition() && 
+           "Should have the definition decl of the primary base!");
+
+    // Since the record decl shares its vtable pointer with the primary base
+    // we need to start counting at the end of the primary base's vtable.
+    CurrentIndex = getNumVirtualFunctionPointers(PrimaryBase);
+  }
+
+  // Collect all the primary bases, so we can check whether methods override
+  // a method from the base.
+  VTableBuilder::PrimaryBasesSetVectorTy PrimaryBases;
+  for (ASTRecordLayout::primary_base_info_iterator
+       I = Layout.primary_base_begin(), E = Layout.primary_base_end();
+       I != E; ++I)
+    PrimaryBases.insert((*I).getBase());
+
+  const CXXDestructorDecl *ImplicitVirtualDtor = 0;
+  
+  for (CXXRecordDecl::method_iterator i = RD->method_begin(),
+       e = RD->method_end(); i != e; ++i) {
+    const CXXMethodDecl *MD = *i;
+
+    // We only want virtual methods.
+    if (!MD->isVirtual())
+      continue;
+
+    // Check if this method overrides a method in the primary base.
+    if (const CXXMethodDecl *OverriddenMD = 
+          FindNearestOverriddenMethod(MD, PrimaryBases)) {
+      // Check if converting from the return type of the method to the 
+      // return type of the overridden method requires conversion.
+      if (ComputeReturnAdjustmentBaseOffset(CGM.getContext(), MD, 
+                                            OverriddenMD).isEmpty()) {
+        // This index is shared between the index in the vtable of the primary
+        // base class.
+        if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {
+          const CXXDestructorDecl *OverriddenDD = 
+            cast<CXXDestructorDecl>(OverriddenMD);
+          
+          // Add both the complete and deleting entries.
+          MethodVTableIndices[GlobalDecl(DD, Dtor_Complete)] = 
+            getMethodVTableIndex(GlobalDecl(OverriddenDD, Dtor_Complete));
+          MethodVTableIndices[GlobalDecl(DD, Dtor_Deleting)] = 
+            getMethodVTableIndex(GlobalDecl(OverriddenDD, Dtor_Deleting));
+        } else {
+          MethodVTableIndices[MD] = getMethodVTableIndex(OverriddenMD);
+        }
+        
+        // We don't need to add an entry for this method.
+        continue;
+      }
+    }
+    
+    if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {
+      if (MD->isImplicit()) {
+        assert(!ImplicitVirtualDtor && 
+               "Did already see an implicit virtual dtor!");
+        ImplicitVirtualDtor = DD;
+        continue;
+      } 
+
+      // Add the complete dtor.
+      MethodVTableIndices[GlobalDecl(DD, Dtor_Complete)] = CurrentIndex++;
+      
+      // Add the deleting dtor.
+      MethodVTableIndices[GlobalDecl(DD, Dtor_Deleting)] = CurrentIndex++;
+    } else {
+      // Add the entry.
+      MethodVTableIndices[MD] = CurrentIndex++;
+    }
+  }
+
+  if (ImplicitVirtualDtor) {
+    // Itanium C++ ABI 2.5.2:
+    //   If a class has an implicitly-defined virtual destructor, 
+    //   its entries come after the declared virtual function pointers.
+
+    // Add the complete dtor.
+    MethodVTableIndices[GlobalDecl(ImplicitVirtualDtor, Dtor_Complete)] = 
+      CurrentIndex++;
+    
+    // Add the deleting dtor.
+    MethodVTableIndices[GlobalDecl(ImplicitVirtualDtor, Dtor_Deleting)] = 
+      CurrentIndex++;
+  }
+  
+  NumVirtualFunctionPointers[RD] = CurrentIndex;
+}
+
+uint64_t CodeGenVTables::getNumVirtualFunctionPointers(const CXXRecordDecl *RD) {
+  llvm::DenseMap<const CXXRecordDecl *, uint64_t>::iterator I = 
+    NumVirtualFunctionPointers.find(RD);
+  if (I != NumVirtualFunctionPointers.end())
+    return I->second;
+
+  ComputeMethodVTableIndices(RD);
+
+  I = NumVirtualFunctionPointers.find(RD);
+  assert(I != NumVirtualFunctionPointers.end() && "Did not find entry!");
+  return I->second;
+}
+      
+uint64_t CodeGenVTables::getMethodVTableIndex(GlobalDecl GD) {
+  MethodVTableIndicesTy::iterator I = MethodVTableIndices.find(GD);
+  if (I != MethodVTableIndices.end())
+    return I->second;
+  
+  const CXXRecordDecl *RD = cast<CXXMethodDecl>(GD.getDecl())->getParent();
+
+  ComputeMethodVTableIndices(RD);
+
+  I = MethodVTableIndices.find(GD);
+  assert(I != MethodVTableIndices.end() && "Did not find index!");
+  return I->second;
+}
+
+int64_t CodeGenVTables::getVirtualBaseOffsetOffset(const CXXRecordDecl *RD, 
+                                                   const CXXRecordDecl *VBase) {
+  ClassPairTy ClassPair(RD, VBase);
+  
+  VirtualBaseClassOffsetOffsetsMapTy::iterator I = 
+    VirtualBaseClassOffsetOffsets.find(ClassPair);
+  if (I != VirtualBaseClassOffsetOffsets.end())
+    return I->second;
+  
+  VCallAndVBaseOffsetBuilder Builder(RD, RD, /*FinalOverriders=*/0,
+                                     BaseSubobject(RD, 0),                                           
+                                     /*BaseIsVirtual=*/false,
+                                     /*OffsetInLayoutClass=*/0);
+
+  for (VCallAndVBaseOffsetBuilder::VBaseOffsetOffsetsMapTy::const_iterator I =
+       Builder.getVBaseOffsetOffsets().begin(), 
+       E = Builder.getVBaseOffsetOffsets().end(); I != E; ++I) {
+    // Insert all types.
+    ClassPairTy ClassPair(RD, I->first);
+    
+    VirtualBaseClassOffsetOffsets.insert(std::make_pair(ClassPair, I->second));
+  }
+  
+  I = VirtualBaseClassOffsetOffsets.find(ClassPair);
+  assert(I != VirtualBaseClassOffsetOffsets.end() && "Did not find index!");
+  
+  return I->second;
+}
+
+uint64_t
+CodeGenVTables::getAddressPoint(BaseSubobject Base, const CXXRecordDecl *RD) {
+  assert(AddressPoints.count(std::make_pair(RD, Base)) &&
+         "Did not find address point!");
+
+  uint64_t AddressPoint = AddressPoints.lookup(std::make_pair(RD, Base));
+  assert(AddressPoint && "Address point must not be zero!");
+
+  return AddressPoint;
+}
+
+llvm::Constant *CodeGenModule::GetAddrOfThunk(GlobalDecl GD, 
+                                              const ThunkInfo &Thunk) {
+  const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
+
+  // Compute the mangled name.
+  llvm::SmallString<256> Name;
+  if (const CXXDestructorDecl* DD = dyn_cast<CXXDestructorDecl>(MD))
+    getMangleContext().mangleCXXDtorThunk(DD, GD.getDtorType(), Thunk.This,
+                                          Name);
+  else
+    getMangleContext().mangleThunk(MD, Thunk, Name);
+  
+  const llvm::Type *Ty = getTypes().GetFunctionTypeForVTable(MD);
+  return GetOrCreateLLVMFunction(Name, Ty, GlobalDecl());
+}
+
+static llvm::Value *PerformTypeAdjustment(CodeGenFunction &CGF,
+                                          llvm::Value *Ptr,
+                                          int64_t NonVirtualAdjustment,
+                                          int64_t VirtualAdjustment) {
+  if (!NonVirtualAdjustment && !VirtualAdjustment)
+    return Ptr;
+
+  const llvm::Type *Int8PtrTy = 
+    llvm::Type::getInt8PtrTy(CGF.getLLVMContext());
+  
+  llvm::Value *V = CGF.Builder.CreateBitCast(Ptr, Int8PtrTy);
+
+  if (NonVirtualAdjustment) {
+    // Do the non-virtual adjustment.
+    V = CGF.Builder.CreateConstInBoundsGEP1_64(V, NonVirtualAdjustment);
+  }
+
+  if (VirtualAdjustment) {
+    const llvm::Type *PtrDiffTy = 
+      CGF.ConvertType(CGF.getContext().getPointerDiffType());
+
+    // Do the virtual adjustment.
+    llvm::Value *VTablePtrPtr = 
+      CGF.Builder.CreateBitCast(V, Int8PtrTy->getPointerTo());
+    
+    llvm::Value *VTablePtr = CGF.Builder.CreateLoad(VTablePtrPtr);
+  
+    llvm::Value *OffsetPtr =
+      CGF.Builder.CreateConstInBoundsGEP1_64(VTablePtr, VirtualAdjustment);
+    
+    OffsetPtr = CGF.Builder.CreateBitCast(OffsetPtr, PtrDiffTy->getPointerTo());
+    
+    // Load the adjustment offset from the vtable.
+    llvm::Value *Offset = CGF.Builder.CreateLoad(OffsetPtr);
+    
+    // Adjust our pointer.
+    V = CGF.Builder.CreateInBoundsGEP(V, Offset);
+  }
+
+  // Cast back to the original type.
+  return CGF.Builder.CreateBitCast(V, Ptr->getType());
+}
+
+void CodeGenFunction::GenerateThunk(llvm::Function *Fn, GlobalDecl GD,
+                                    const ThunkInfo &Thunk) {
+  const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
+  const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>();
+  QualType ResultType = FPT->getResultType();
+  QualType ThisType = MD->getThisType(getContext());
+
+  FunctionArgList FunctionArgs;
+
+  // FIXME: It would be nice if more of this code could be shared with 
+  // CodeGenFunction::GenerateCode.
+
+  // Create the implicit 'this' parameter declaration.
+  CXXThisDecl = ImplicitParamDecl::Create(getContext(), 0,
+                                          MD->getLocation(),
+                                          &getContext().Idents.get("this"),
+                                          ThisType);
+
+  // Add the 'this' parameter.
+  FunctionArgs.push_back(std::make_pair(CXXThisDecl, CXXThisDecl->getType()));
+
+  // Add the rest of the parameters.
+  for (FunctionDecl::param_const_iterator I = MD->param_begin(),
+       E = MD->param_end(); I != E; ++I) {
+    ParmVarDecl *Param = *I;
+    
+    FunctionArgs.push_back(std::make_pair(Param, Param->getType()));
+  }
+  
+  StartFunction(GlobalDecl(), ResultType, Fn, FunctionArgs, SourceLocation());
+
+  // Adjust the 'this' pointer if necessary.
+  llvm::Value *AdjustedThisPtr = 
+    PerformTypeAdjustment(*this, LoadCXXThis(), 
+                          Thunk.This.NonVirtual, 
+                          Thunk.This.VCallOffsetOffset);
+  
+  CallArgList CallArgs;
+  
+  // Add our adjusted 'this' pointer.
+  CallArgs.push_back(std::make_pair(RValue::get(AdjustedThisPtr), ThisType));
+
+  // Add the rest of the parameters.
+  for (FunctionDecl::param_const_iterator I = MD->param_begin(),
+       E = MD->param_end(); I != E; ++I) {
+    ParmVarDecl *Param = *I;
+    QualType ArgType = Param->getType();
+    
+    // FIXME: Declaring a DeclRefExpr on the stack is kinda icky.
+    DeclRefExpr ArgExpr(Param, ArgType.getNonReferenceType(), SourceLocation());
+    CallArgs.push_back(std::make_pair(EmitCallArg(&ArgExpr, ArgType), ArgType));
+  }
+
+  // Get our callee.
+  const llvm::Type *Ty =
+    CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD),
+                                   FPT->isVariadic());
+  llvm::Value *Callee = CGM.GetAddrOfFunction(GD, Ty);
+
+  const CGFunctionInfo &FnInfo = 
+    CGM.getTypes().getFunctionInfo(ResultType, CallArgs,
+                                   FPT->getExtInfo());
+  
+  // Now emit our call.
+  RValue RV = EmitCall(FnInfo, Callee, ReturnValueSlot(), CallArgs, MD);
+  
+  if (!Thunk.Return.isEmpty()) {
+    // Emit the return adjustment.
+    bool NullCheckValue = !ResultType->isReferenceType();
+    
+    llvm::BasicBlock *AdjustNull = 0;
+    llvm::BasicBlock *AdjustNotNull = 0;
+    llvm::BasicBlock *AdjustEnd = 0;
+    
+    llvm::Value *ReturnValue = RV.getScalarVal();
+
+    if (NullCheckValue) {
+      AdjustNull = createBasicBlock("adjust.null");
+      AdjustNotNull = createBasicBlock("adjust.notnull");
+      AdjustEnd = createBasicBlock("adjust.end");
+    
+      llvm::Value *IsNull = Builder.CreateIsNull(ReturnValue);
+      Builder.CreateCondBr(IsNull, AdjustNull, AdjustNotNull);
+      EmitBlock(AdjustNotNull);
+    }
+    
+    ReturnValue = PerformTypeAdjustment(*this, ReturnValue, 
+                                        Thunk.Return.NonVirtual, 
+                                        Thunk.Return.VBaseOffsetOffset);
+    
+    if (NullCheckValue) {
+      Builder.CreateBr(AdjustEnd);
+      EmitBlock(AdjustNull);
+      Builder.CreateBr(AdjustEnd);
+      EmitBlock(AdjustEnd);
+    
+      llvm::PHINode *PHI = Builder.CreatePHI(ReturnValue->getType());
+      PHI->reserveOperandSpace(2);
+      PHI->addIncoming(ReturnValue, AdjustNotNull);
+      PHI->addIncoming(llvm::Constant::getNullValue(ReturnValue->getType()), 
+                       AdjustNull);
+      ReturnValue = PHI;
+    }
+    
+    RV = RValue::get(ReturnValue);
+  }
+
+  if (!ResultType->isVoidType())
+    EmitReturnOfRValue(RV, ResultType);
+
+  FinishFunction();
+
+  // Destroy the 'this' declaration.
+  CXXThisDecl->Destroy(getContext());
+  
+  // Set the right linkage.
+  Fn->setLinkage(CGM.getFunctionLinkage(MD));
+  
+  // Set the right visibility.
+  CGM.setGlobalVisibility(Fn, MD);
+}
+
+void CodeGenVTables::EmitThunk(GlobalDecl GD, const ThunkInfo &Thunk)
+{
+  llvm::Constant *Entry = CGM.GetAddrOfThunk(GD, Thunk);
+  const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
+  
+  // Strip off a bitcast if we got one back.
+  if (llvm::ConstantExpr *CE = dyn_cast<llvm::ConstantExpr>(Entry)) {
+    assert(CE->getOpcode() == llvm::Instruction::BitCast);
+    Entry = CE->getOperand(0);
+  }
+  
+  // There's already a declaration with the same name, check if it has the same
+  // type or if we need to replace it.
+  if (cast<llvm::GlobalValue>(Entry)->getType()->getElementType() != 
+      CGM.getTypes().GetFunctionTypeForVTable(MD)) {
+    llvm::GlobalValue *OldThunkFn = cast<llvm::GlobalValue>(Entry);
+    
+    // If the types mismatch then we have to rewrite the definition.
+    assert(OldThunkFn->isDeclaration() &&
+           "Shouldn't replace non-declaration");
+
+    // Remove the name from the old thunk function and get a new thunk.
+    OldThunkFn->setName(llvm::StringRef());
+    Entry = CGM.GetAddrOfThunk(GD, Thunk);
+    
+    // If needed, replace the old thunk with a bitcast.
+    if (!OldThunkFn->use_empty()) {
+      llvm::Constant *NewPtrForOldDecl =
+        llvm::ConstantExpr::getBitCast(Entry, OldThunkFn->getType());
+      OldThunkFn->replaceAllUsesWith(NewPtrForOldDecl);
+    }
+    
+    // Remove the old thunk.
+    OldThunkFn->eraseFromParent();
+  }
+
+  // Actually generate the thunk body.
+  llvm::Function *ThunkFn = cast<llvm::Function>(Entry);
+  CodeGenFunction(CGM).GenerateThunk(ThunkFn, GD, Thunk);
+}
+
+void CodeGenVTables::EmitThunks(GlobalDecl GD)
+{
+  const CXXMethodDecl *MD = 
+    cast<CXXMethodDecl>(GD.getDecl())->getCanonicalDecl();
+
+  // We don't need to generate thunks for the base destructor.
+  if (isa<CXXDestructorDecl>(MD) && GD.getDtorType() == Dtor_Base)
+    return;
+
+  const CXXRecordDecl *RD = MD->getParent();
+  
+  // Compute VTable related info for this class.
+  ComputeVTableRelatedInformation(RD);
+  
+  ThunksMapTy::const_iterator I = Thunks.find(MD);
+  if (I == Thunks.end()) {
+    // We did not find a thunk for this method.
+    return;
+  }
+
+  const ThunkInfoVectorTy &ThunkInfoVector = I->second;
+  for (unsigned I = 0, E = ThunkInfoVector.size(); I != E; ++I)
+    EmitThunk(GD, ThunkInfoVector[I]);
+}
+
+void CodeGenVTables::ComputeVTableRelatedInformation(const CXXRecordDecl *RD) {
+  uint64_t *&LayoutData = VTableLayoutMap[RD];
+  
+  // Check if we've computed this information before.
+  if (LayoutData)
+    return;
+      
+  VTableBuilder Builder(*this, RD, 0, /*MostDerivedClassIsVirtual=*/0, RD);
+
+  // Add the VTable layout.
+  uint64_t NumVTableComponents = Builder.getNumVTableComponents();
+  LayoutData = new uint64_t[NumVTableComponents + 1];
+
+  // Store the number of components.
+  LayoutData[0] = NumVTableComponents;
+
+  // Store the components.
+  std::copy(Builder.vtable_components_data_begin(),
+            Builder.vtable_components_data_end(),
+            &LayoutData[1]);
+
+  // Add the known thunks.
+  Thunks.insert(Builder.thunks_begin(), Builder.thunks_end());
+  
+  // Add the thunks needed in this vtable.
+  assert(!VTableThunksMap.count(RD) && 
+         "Thunks already exists for this vtable!");
+
+  VTableThunksTy &VTableThunks = VTableThunksMap[RD];
+  VTableThunks.append(Builder.vtable_thunks_begin(),
+                      Builder.vtable_thunks_end());
+  
+  // Sort them.
+  std::sort(VTableThunks.begin(), VTableThunks.end());
+  
+  // Add the address points.
+  for (VTableBuilder::AddressPointsMapTy::const_iterator I =
+       Builder.address_points_begin(), E = Builder.address_points_end();
+       I != E; ++I) {
+    
+    uint64_t &AddressPoint = AddressPoints[std::make_pair(RD, I->first)];
+    
+    // Check if we already have the address points for this base.
+    assert(!AddressPoint && "Address point already exists for this base!");
+    
+    AddressPoint = I->second;
+  }
+  
+  // If we don't have the vbase information for this class, insert it.
+  // getVirtualBaseOffsetOffset will compute it separately without computing
+  // the rest of the vtable related information.
+  if (!RD->getNumVBases())
+    return;
+  
+  const RecordType *VBaseRT = 
+    RD->vbases_begin()->getType()->getAs<RecordType>();
+  const CXXRecordDecl *VBase = cast<CXXRecordDecl>(VBaseRT->getDecl());
+  
+  if (VirtualBaseClassOffsetOffsets.count(std::make_pair(RD, VBase)))
+    return;
+  
+  for (VTableBuilder::VBaseOffsetOffsetsMapTy::const_iterator I =
+       Builder.getVBaseOffsetOffsets().begin(), 
+       E = Builder.getVBaseOffsetOffsets().end(); I != E; ++I) {
+    // Insert all types.
+    ClassPairTy ClassPair(RD, I->first);
+    
+    VirtualBaseClassOffsetOffsets.insert(std::make_pair(ClassPair, I->second));
+  }
+}
+
+llvm::Constant *
+CodeGenVTables::CreateVTableInitializer(const CXXRecordDecl *RD,
+                                        const uint64_t *Components, 
+                                        unsigned NumComponents,
+                                        const VTableThunksTy &VTableThunks) {
+  llvm::SmallVector<llvm::Constant *, 64> Inits;
+
+  const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
+  
+  const llvm::Type *PtrDiffTy = 
+    CGM.getTypes().ConvertType(CGM.getContext().getPointerDiffType());
+
+  QualType ClassType = CGM.getContext().getTagDeclType(RD);
+  llvm::Constant *RTTI = CGM.GetAddrOfRTTIDescriptor(ClassType);
+  
+  unsigned NextVTableThunkIndex = 0;
+  
+  llvm::Constant* PureVirtualFn = 0;
+
+  for (unsigned I = 0; I != NumComponents; ++I) {
+    VTableComponent Component = 
+      VTableComponent::getFromOpaqueInteger(Components[I]);
+
+    llvm::Constant *Init = 0;
+
+    switch (Component.getKind()) {
+    case VTableComponent::CK_VCallOffset:
+      Init = llvm::ConstantInt::get(PtrDiffTy, Component.getVCallOffset());
+      Init = llvm::ConstantExpr::getIntToPtr(Init, Int8PtrTy);
+      break;
+    case VTableComponent::CK_VBaseOffset:
+      Init = llvm::ConstantInt::get(PtrDiffTy, Component.getVBaseOffset());
+      Init = llvm::ConstantExpr::getIntToPtr(Init, Int8PtrTy);
+      break;
+    case VTableComponent::CK_OffsetToTop:
+      Init = llvm::ConstantInt::get(PtrDiffTy, Component.getOffsetToTop());
+      Init = llvm::ConstantExpr::getIntToPtr(Init, Int8PtrTy);
+      break;
+    case VTableComponent::CK_RTTI:
+      Init = llvm::ConstantExpr::getBitCast(RTTI, Int8PtrTy);
+      break;
+    case VTableComponent::CK_FunctionPointer:
+    case VTableComponent::CK_CompleteDtorPointer:
+    case VTableComponent::CK_DeletingDtorPointer: {
+      GlobalDecl GD;
+      
+      // Get the right global decl.
+      switch (Component.getKind()) {
+      default:
+        llvm_unreachable("Unexpected vtable component kind");
+      case VTableComponent::CK_FunctionPointer:
+        GD = Component.getFunctionDecl();
+        break;
+      case VTableComponent::CK_CompleteDtorPointer:
+        GD = GlobalDecl(Component.getDestructorDecl(), Dtor_Complete);
+        break;
+      case VTableComponent::CK_DeletingDtorPointer:
+        GD = GlobalDecl(Component.getDestructorDecl(), Dtor_Deleting);
+        break;
+      }
+
+      if (cast<CXXMethodDecl>(GD.getDecl())->isPure()) {
+        // We have a pure virtual member function.
+        if (!PureVirtualFn) {
+          const llvm::FunctionType *Ty = 
+            llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.getLLVMContext()), 
+                                    /*isVarArg=*/false);
+          PureVirtualFn = 
+            CGM.CreateRuntimeFunction(Ty, "__cxa_pure_virtual");
+          PureVirtualFn = llvm::ConstantExpr::getBitCast(PureVirtualFn, 
+                                                         Int8PtrTy);
+        }
+        
+        Init = PureVirtualFn;
+      } else {
+        // Check if we should use a thunk.
+        if (NextVTableThunkIndex < VTableThunks.size() &&
+            VTableThunks[NextVTableThunkIndex].first == I) {
+          const ThunkInfo &Thunk = VTableThunks[NextVTableThunkIndex].second;
+        
+          Init = CGM.GetAddrOfThunk(GD, Thunk);
+        
+          NextVTableThunkIndex++;
+        } else {
+          const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
+          const llvm::Type *Ty = CGM.getTypes().GetFunctionTypeForVTable(MD);
+        
+          Init = CGM.GetAddrOfFunction(GD, Ty);
+        }
+
+        Init = llvm::ConstantExpr::getBitCast(Init, Int8PtrTy);
+      }
+      break;
+    }
+
+    case VTableComponent::CK_UnusedFunctionPointer:
+      Init = llvm::ConstantExpr::getNullValue(Int8PtrTy);
+      break;
+    };
+    
+    Inits.push_back(Init);
+  }
+  
+  llvm::ArrayType *ArrayType = llvm::ArrayType::get(Int8PtrTy, NumComponents);
+  return llvm::ConstantArray::get(ArrayType, Inits.data(), Inits.size());
+}
+
+/// GetGlobalVariable - Will return a global variable of the given type. 
+/// If a variable with a different type already exists then a new variable
+/// with the right type will be created.
+/// FIXME: We should move this to CodeGenModule and rename it to something 
+/// better and then use it in CGVTT and CGRTTI. 
+static llvm::GlobalVariable *
+GetGlobalVariable(llvm::Module &Module, llvm::StringRef Name,
+                  const llvm::Type *Ty,
+                  llvm::GlobalValue::LinkageTypes Linkage) {
+
+  llvm::GlobalVariable *GV = Module.getNamedGlobal(Name);
+  llvm::GlobalVariable *OldGV = 0;
+  
+  if (GV) {
+    // Check if the variable has the right type.
+    if (GV->getType()->getElementType() == Ty)
+      return GV;
+
+    assert(GV->isDeclaration() && "Declaration has wrong type!");
+    
+    OldGV = GV;
+  }
+  
+  // Create a new variable.
+  GV = new llvm::GlobalVariable(Module, Ty, /*isConstant=*/true,
+                                Linkage, 0, Name);
+  
+  if (OldGV) {
+    // Replace occurrences of the old variable if needed.
+    GV->takeName(OldGV);
+   
+    if (!OldGV->use_empty()) {
+      llvm::Constant *NewPtrForOldDecl =
+        llvm::ConstantExpr::getBitCast(GV, OldGV->getType());
+      OldGV->replaceAllUsesWith(NewPtrForOldDecl);
+    }
+
+    OldGV->eraseFromParent();
+  }
+  
+  return GV;
+}
+
+llvm::GlobalVariable *CodeGenVTables::GetAddrOfVTable(const CXXRecordDecl *RD) {
+  llvm::SmallString<256> OutName;
+  CGM.getMangleContext().mangleCXXVTable(RD, OutName);
+  llvm::StringRef Name = OutName.str();
+
+  ComputeVTableRelatedInformation(RD);
+  
+  const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
+  llvm::ArrayType *ArrayType = 
+    llvm::ArrayType::get(Int8PtrTy, getNumVTableComponents(RD));
+
+  return GetGlobalVariable(CGM.getModule(), Name, ArrayType, 
+                           llvm::GlobalValue::ExternalLinkage);
+}
+
+void
+CodeGenVTables::EmitVTableDefinition(llvm::GlobalVariable *VTable,
+                                     llvm::GlobalVariable::LinkageTypes Linkage,
+                                     const CXXRecordDecl *RD) {
+  // Dump the vtable layout if necessary.
+  if (CGM.getLangOptions().DumpVTableLayouts) {
+    VTableBuilder Builder(*this, RD, 0, /*MostDerivedClassIsVirtual=*/0, RD);
+
+    Builder.dumpLayout(llvm::errs());
+  }
+
+  assert(VTableThunksMap.count(RD) && 
+         "No thunk status for this record decl!");
+  
+  const VTableThunksTy& Thunks = VTableThunksMap[RD];
+  
+  // Create and set the initializer.
+  llvm::Constant *Init = 
+    CreateVTableInitializer(RD, getVTableComponentsData(RD),
+                            getNumVTableComponents(RD), Thunks);
+  VTable->setInitializer(Init);
+  
+  // Set the correct linkage.
+  VTable->setLinkage(Linkage);
+}
+
+llvm::GlobalVariable *
+CodeGenVTables::GenerateConstructionVTable(const CXXRecordDecl *RD, 
+                                      const BaseSubobject &Base, 
+                                      bool BaseIsVirtual, 
+                                      VTableAddressPointsMapTy& AddressPoints) {
+  VTableBuilder Builder(*this, Base.getBase(), Base.getBaseOffset(), 
+                        /*MostDerivedClassIsVirtual=*/BaseIsVirtual, RD);
+
+  // Dump the vtable layout if necessary.
+  if (CGM.getLangOptions().DumpVTableLayouts)
+    Builder.dumpLayout(llvm::errs());
+
+  // Add the address points.
+  AddressPoints.insert(Builder.address_points_begin(),
+                       Builder.address_points_end());
+
+  // Get the mangled construction vtable name.
+  llvm::SmallString<256> OutName;
+  CGM.getMangleContext().mangleCXXCtorVTable(RD, Base.getBaseOffset() / 8, 
+                                             Base.getBase(), OutName);
+  llvm::StringRef Name = OutName.str();
+
+  const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
+  llvm::ArrayType *ArrayType = 
+    llvm::ArrayType::get(Int8PtrTy, Builder.getNumVTableComponents());
+
+  // Create the variable that will hold the construction vtable.
+  llvm::GlobalVariable *VTable = 
+    GetGlobalVariable(CGM.getModule(), Name, ArrayType, 
+                      llvm::GlobalValue::InternalLinkage);
+
+  // Add the thunks.
+  VTableThunksTy VTableThunks;
+  VTableThunks.append(Builder.vtable_thunks_begin(),
+                      Builder.vtable_thunks_end());
+
+  // Sort them.
+  std::sort(VTableThunks.begin(), VTableThunks.end());
+
+  // Create and set the initializer.
+  llvm::Constant *Init = 
+    CreateVTableInitializer(Base.getBase(), 
+                            Builder.vtable_components_data_begin(), 
+                            Builder.getNumVTableComponents(), VTableThunks);
+  VTable->setInitializer(Init);
+  
+  return VTable;
+}
+
+void 
+CodeGenVTables::GenerateClassData(llvm::GlobalVariable::LinkageTypes Linkage,
+                                  const CXXRecordDecl *RD) {
+  llvm::GlobalVariable *&VTable = VTables[RD];
+  if (VTable) {
+    assert(VTable->getInitializer() && "VTable doesn't have a definition!");
+    return;
+  }
+
+  VTable = GetAddrOfVTable(RD);
+  EmitVTableDefinition(VTable, Linkage, RD);
+
+  GenerateVTT(Linkage, /*GenerateDefinition=*/true, RD);
+
+  // If this is the magic class __cxxabiv1::__fundamental_type_info,
+  // we will emit the typeinfo for the fundamental types. This is the
+  // same behaviour as GCC.
+  const DeclContext *DC = RD->getDeclContext();
+  if (RD->getIdentifier() &&
+      RD->getIdentifier()->isStr("__fundamental_type_info") &&
+      isa<NamespaceDecl>(DC) &&
+      cast<NamespaceDecl>(DC)->getIdentifier() &&
+      cast<NamespaceDecl>(DC)->getIdentifier()->isStr("__cxxabiv1") &&
+      DC->getParent()->isTranslationUnit())
+    CGM.EmitFundamentalRTTIDescriptors();
+}
+
+void CodeGenVTables::EmitVTableRelatedData(GlobalDecl GD) {
+  const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
+  const CXXRecordDecl *RD = MD->getParent();
+
+  // If the class doesn't have a vtable we don't need to emit one.
+  if (!RD->isDynamicClass())
+    return;
+  
+  // Check if we need to emit thunks for this function.
+  if (MD->isVirtual())
+    EmitThunks(GD);
+
+  // Get the key function.
+  const CXXMethodDecl *KeyFunction = CGM.getContext().getKeyFunction(RD);
+  
+  TemplateSpecializationKind RDKind = RD->getTemplateSpecializationKind();
+  TemplateSpecializationKind MDKind = MD->getTemplateSpecializationKind();
+
+  if (KeyFunction) {
+    // We don't have the right key function.
+    if (KeyFunction->getCanonicalDecl() != MD->getCanonicalDecl())
+      return;
+  } else {
+    // If we have no key funcion and this is a explicit instantiation declaration,
+    // we will produce a vtable at the explicit instantiation. We don't need one
+    // here.
+    if (RDKind == clang::TSK_ExplicitInstantiationDeclaration)
+      return;
+
+    // If this is an explicit instantiation of a method, we don't need a vtable.
+    // Since we have no key function, we will emit the vtable when we see
+    // a use, and just defining a function is not an use.
+    if (RDKind == TSK_ImplicitInstantiation &&
+        MDKind == TSK_ExplicitInstantiationDefinition)
+      return;
+  }
+
+  if (VTables.count(RD))
+    return;
+
+  if (RDKind == TSK_ImplicitInstantiation)
+    CGM.DeferredVTables.push_back(RD);
+  else
+    GenerateClassData(CGM.getVTableLinkage(RD), RD);
+}
diff --git a/lib/CodeGen/CGVTables.h b/lib/CodeGen/CGVTables.h
new file mode 100644
index 0000000..bc113ec
--- /dev/null
+++ b/lib/CodeGen/CGVTables.h
@@ -0,0 +1,370 @@
+//===--- CGVTables.h - Emit LLVM Code for C++ vtables ---------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This contains code dealing with C++ code generation of virtual tables.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_CODEGEN_CGVTABLE_H
+#define CLANG_CODEGEN_CGVTABLE_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/GlobalVariable.h"
+#include "GlobalDecl.h"
+
+namespace clang {
+  class CXXRecordDecl;
+
+namespace CodeGen {
+  class CodeGenModule;
+
+/// ReturnAdjustment - A return adjustment.
+struct ReturnAdjustment {
+  /// NonVirtual - The non-virtual adjustment from the derived object to its
+  /// nearest virtual base.
+  int64_t NonVirtual;
+  
+  /// VBaseOffsetOffset - The offset (in bytes), relative to the address point 
+  /// of the virtual base class offset.
+  int64_t VBaseOffsetOffset;
+  
+  ReturnAdjustment() : NonVirtual(0), VBaseOffsetOffset(0) { }
+  
+  bool isEmpty() const { return !NonVirtual && !VBaseOffsetOffset; }
+
+  friend bool operator==(const ReturnAdjustment &LHS, 
+                         const ReturnAdjustment &RHS) {
+    return LHS.NonVirtual == RHS.NonVirtual && 
+      LHS.VBaseOffsetOffset == RHS.VBaseOffsetOffset;
+  }
+
+  friend bool operator<(const ReturnAdjustment &LHS,
+                        const ReturnAdjustment &RHS) {
+    if (LHS.NonVirtual < RHS.NonVirtual)
+      return true;
+    
+    return LHS.NonVirtual == RHS.NonVirtual && 
+      LHS.VBaseOffsetOffset < RHS.VBaseOffsetOffset;
+  }
+};
+  
+/// ThisAdjustment - A 'this' pointer adjustment.
+struct ThisAdjustment {
+  /// NonVirtual - The non-virtual adjustment from the derived object to its
+  /// nearest virtual base.
+  int64_t NonVirtual;
+
+  /// VCallOffsetOffset - The offset (in bytes), relative to the address point,
+  /// of the virtual call offset.
+  int64_t VCallOffsetOffset;
+  
+  ThisAdjustment() : NonVirtual(0), VCallOffsetOffset(0) { }
+
+  bool isEmpty() const { return !NonVirtual && !VCallOffsetOffset; }
+
+  friend bool operator==(const ThisAdjustment &LHS, 
+                         const ThisAdjustment &RHS) {
+    return LHS.NonVirtual == RHS.NonVirtual && 
+      LHS.VCallOffsetOffset == RHS.VCallOffsetOffset;
+  }
+  
+  friend bool operator<(const ThisAdjustment &LHS,
+                        const ThisAdjustment &RHS) {
+    if (LHS.NonVirtual < RHS.NonVirtual)
+      return true;
+    
+    return LHS.NonVirtual == RHS.NonVirtual && 
+      LHS.VCallOffsetOffset < RHS.VCallOffsetOffset;
+  }
+};
+
+/// ThunkInfo - The 'this' pointer adjustment as well as an optional return
+/// adjustment for a thunk.
+struct ThunkInfo {
+  /// This - The 'this' pointer adjustment.
+  ThisAdjustment This;
+    
+  /// Return - The return adjustment.
+  ReturnAdjustment Return;
+
+  ThunkInfo() { }
+
+  ThunkInfo(const ThisAdjustment &This, const ReturnAdjustment &Return)
+    : This(This), Return(Return) { }
+
+  friend bool operator==(const ThunkInfo &LHS, const ThunkInfo &RHS) {
+    return LHS.This == RHS.This && LHS.Return == RHS.Return;
+  }
+
+  friend bool operator<(const ThunkInfo &LHS, const ThunkInfo &RHS) {
+    if (LHS.This < RHS.This)
+      return true;
+      
+    return LHS.This == RHS.This && LHS.Return < RHS.Return;
+  }
+
+  bool isEmpty() const { return This.isEmpty() && Return.isEmpty(); }
+};  
+
+// BaseSubobject - Uniquely identifies a direct or indirect base class. 
+// Stores both the base class decl and the offset from the most derived class to
+// the base class.
+class BaseSubobject {
+  /// Base - The base class declaration.
+  const CXXRecordDecl *Base;
+  
+  /// BaseOffset - The offset from the most derived class to the base class.
+  uint64_t BaseOffset;
+  
+public:
+  BaseSubobject(const CXXRecordDecl *Base, uint64_t BaseOffset)
+    : Base(Base), BaseOffset(BaseOffset) { }
+  
+  /// getBase - Returns the base class declaration.
+  const CXXRecordDecl *getBase() const { return Base; }
+
+  /// getBaseOffset - Returns the base class offset.
+  uint64_t getBaseOffset() const { return BaseOffset; }
+
+  friend bool operator==(const BaseSubobject &LHS, const BaseSubobject &RHS) {
+    return LHS.Base == RHS.Base && LHS.BaseOffset == RHS.BaseOffset;
+ }
+};
+
+} // end namespace CodeGen
+} // end namespace clang
+
+namespace llvm {
+
+template<> struct DenseMapInfo<clang::CodeGen::BaseSubobject> {
+  static clang::CodeGen::BaseSubobject getEmptyKey() {
+    return clang::CodeGen::BaseSubobject(
+      DenseMapInfo<const clang::CXXRecordDecl *>::getEmptyKey(),
+      DenseMapInfo<uint64_t>::getEmptyKey());
+  }
+
+  static clang::CodeGen::BaseSubobject getTombstoneKey() {
+    return clang::CodeGen::BaseSubobject(
+      DenseMapInfo<const clang::CXXRecordDecl *>::getTombstoneKey(),
+      DenseMapInfo<uint64_t>::getTombstoneKey());
+  }
+
+  static unsigned getHashValue(const clang::CodeGen::BaseSubobject &Base) {
+    return 
+      DenseMapInfo<const clang::CXXRecordDecl *>::getHashValue(Base.getBase()) ^
+      DenseMapInfo<uint64_t>::getHashValue(Base.getBaseOffset());
+  }
+
+  static bool isEqual(const clang::CodeGen::BaseSubobject &LHS, 
+                      const clang::CodeGen::BaseSubobject &RHS) {
+    return LHS == RHS;
+  }
+};
+
+// It's OK to treat BaseSubobject as a POD type.
+template <> struct isPodLike<clang::CodeGen::BaseSubobject> {
+  static const bool value = true;
+};
+
+}
+
+namespace clang {
+namespace CodeGen {
+
+class CodeGenVTables {
+  CodeGenModule &CGM;
+
+  /// MethodVTableIndices - Contains the index (relative to the vtable address
+  /// point) where the function pointer for a virtual function is stored.
+  typedef llvm::DenseMap<GlobalDecl, int64_t> MethodVTableIndicesTy;
+  MethodVTableIndicesTy MethodVTableIndices;
+
+  typedef std::pair<const CXXRecordDecl *,
+                    const CXXRecordDecl *> ClassPairTy;
+
+  /// VirtualBaseClassOffsetOffsets - Contains the vtable offset (relative to 
+  /// the address point) in bytes where the offsets for virtual bases of a class
+  /// are stored.
+  typedef llvm::DenseMap<ClassPairTy, int64_t> 
+    VirtualBaseClassOffsetOffsetsMapTy;
+  VirtualBaseClassOffsetOffsetsMapTy VirtualBaseClassOffsetOffsets;
+
+  /// VTables - All the vtables which have been defined.
+  llvm::DenseMap<const CXXRecordDecl *, llvm::GlobalVariable *> VTables;
+  
+  /// NumVirtualFunctionPointers - Contains the number of virtual function 
+  /// pointers in the vtable for a given record decl.
+  llvm::DenseMap<const CXXRecordDecl *, uint64_t> NumVirtualFunctionPointers;
+
+  typedef llvm::SmallVector<ThunkInfo, 1> ThunkInfoVectorTy;
+  typedef llvm::DenseMap<const CXXMethodDecl *, ThunkInfoVectorTy> ThunksMapTy;
+  
+  /// Thunks - Contains all thunks that a given method decl will need.
+  ThunksMapTy Thunks;
+  
+  typedef llvm::DenseMap<const CXXRecordDecl *, uint64_t *> VTableLayoutMapTy;
+  
+  /// VTableLayoutMap - Stores the vtable layout for all record decls.
+  /// The layout is stored as an array of 64-bit integers, where the first
+  /// integer is the number of vtable entries in the layout, and the subsequent
+  /// integers are the vtable components.
+  VTableLayoutMapTy VTableLayoutMap;
+
+  typedef llvm::DenseMap<std::pair<const CXXRecordDecl *, 
+                                   BaseSubobject>, uint64_t> AddressPointsMapTy;
+  
+  /// Address points - Address points for all vtables.
+  AddressPointsMapTy AddressPoints;
+
+  /// VTableAddressPointsMapTy - Address points for a single vtable.
+  typedef llvm::DenseMap<BaseSubobject, uint64_t> VTableAddressPointsMapTy;
+
+  typedef llvm::SmallVector<std::pair<uint64_t, ThunkInfo>, 1> 
+    VTableThunksTy;
+  
+  typedef llvm::DenseMap<const CXXRecordDecl *, VTableThunksTy>
+    VTableThunksMapTy;
+  
+  /// VTableThunksMap - Contains thunks needed by vtables.
+  VTableThunksMapTy VTableThunksMap;
+  
+  uint64_t getNumVTableComponents(const CXXRecordDecl *RD) const {
+    assert(VTableLayoutMap.count(RD) && "No vtable layout for this class!");
+    
+    return VTableLayoutMap.lookup(RD)[0];
+  }
+
+  const uint64_t *getVTableComponentsData(const CXXRecordDecl *RD) const {
+    assert(VTableLayoutMap.count(RD) && "No vtable layout for this class!");
+
+    uint64_t *Components = VTableLayoutMap.lookup(RD);
+    return &Components[1];
+  }
+
+  typedef llvm::DenseMap<ClassPairTy, uint64_t> SubVTTIndiciesMapTy;
+  
+  /// SubVTTIndicies - Contains indices into the various sub-VTTs.
+  SubVTTIndiciesMapTy SubVTTIndicies;
+
+   
+  typedef llvm::DenseMap<std::pair<const CXXRecordDecl *, 
+                                   BaseSubobject>, uint64_t>
+    SecondaryVirtualPointerIndicesMapTy;
+
+  /// SecondaryVirtualPointerIndices - Contains the secondary virtual pointer
+  /// indices.
+  SecondaryVirtualPointerIndicesMapTy SecondaryVirtualPointerIndices;
+
+  /// getNumVirtualFunctionPointers - Return the number of virtual function
+  /// pointers in the vtable for a given record decl.
+  uint64_t getNumVirtualFunctionPointers(const CXXRecordDecl *RD);
+  
+  void ComputeMethodVTableIndices(const CXXRecordDecl *RD);
+
+  llvm::GlobalVariable *GenerateVTT(llvm::GlobalVariable::LinkageTypes Linkage,
+                                    bool GenerateDefinition,
+                                    const CXXRecordDecl *RD);
+
+  /// EmitThunk - Emit a single thunk.
+  void EmitThunk(GlobalDecl GD, const ThunkInfo &Thunk);
+  
+  /// EmitThunks - Emit the associated thunks for the given global decl.
+  void EmitThunks(GlobalDecl GD);
+  
+  /// ComputeVTableRelatedInformation - Compute and store all vtable related
+  /// information (vtable layout, vbase offset offsets, thunks etc) for the
+  /// given record decl.
+  void ComputeVTableRelatedInformation(const CXXRecordDecl *RD);
+
+  /// CreateVTableInitializer - Create a vtable initializer for the given record
+  /// decl.
+  /// \param Components - The vtable components; this is really an array of
+  /// VTableComponents.
+  llvm::Constant *CreateVTableInitializer(const CXXRecordDecl *RD,
+                                          const uint64_t *Components, 
+                                          unsigned NumComponents,
+                                          const VTableThunksTy &VTableThunks);
+
+public:
+  CodeGenVTables(CodeGenModule &CGM)
+    : CGM(CGM) { }
+
+  // isKeyFunctionInAnotherTU - True if this record has a key function and it is
+  // in another translation unit.
+  static bool isKeyFunctionInAnotherTU(ASTContext &Context,
+				       const CXXRecordDecl *RD) {
+    assert (RD->isDynamicClass() && "Non dynamic classes have no key.");
+    const CXXMethodDecl *KeyFunction = Context.getKeyFunction(RD);
+    return KeyFunction && !KeyFunction->getBody();
+  }
+
+  /// needsVTTParameter - Return whether the given global decl needs a VTT
+  /// parameter, which it does if it's a base constructor or destructor with
+  /// virtual bases.
+  static bool needsVTTParameter(GlobalDecl GD);
+
+  /// getSubVTTIndex - Return the index of the sub-VTT for the base class of the
+  /// given record decl.
+  uint64_t getSubVTTIndex(const CXXRecordDecl *RD, const CXXRecordDecl *Base);
+  
+  /// getSecondaryVirtualPointerIndex - Return the index in the VTT where the
+  /// virtual pointer for the given subobject is located.
+  uint64_t getSecondaryVirtualPointerIndex(const CXXRecordDecl *RD,
+                                           BaseSubobject Base);
+
+  /// getMethodVTableIndex - Return the index (relative to the vtable address
+  /// point) where the function pointer for the given virtual function is
+  /// stored.
+  uint64_t getMethodVTableIndex(GlobalDecl GD);
+
+  /// getVirtualBaseOffsetOffset - Return the offset in bytes (relative to the
+  /// vtable address point) where the offset of the virtual base that contains 
+  /// the given base is stored, otherwise, if no virtual base contains the given
+  /// class, return 0.  Base must be a virtual base class or an unambigious
+  /// base.
+  int64_t getVirtualBaseOffsetOffset(const CXXRecordDecl *RD,
+                                     const CXXRecordDecl *VBase);
+
+  /// getAddressPoint - Get the address point of the given subobject in the
+  /// class decl.
+  uint64_t getAddressPoint(BaseSubobject Base, const CXXRecordDecl *RD);
+  
+  /// GetAddrOfVTable - Get the address of the vtable for the given record decl.
+  llvm::GlobalVariable *GetAddrOfVTable(const CXXRecordDecl *RD);
+
+  /// EmitVTableDefinition - Emit the definition of the given vtable.
+  void EmitVTableDefinition(llvm::GlobalVariable *VTable,
+                            llvm::GlobalVariable::LinkageTypes Linkage,
+                            const CXXRecordDecl *RD);
+  
+  /// GenerateConstructionVTable - Generate a construction vtable for the given 
+  /// base subobject.
+  llvm::GlobalVariable *
+  GenerateConstructionVTable(const CXXRecordDecl *RD, const BaseSubobject &Base, 
+                             bool BaseIsVirtual, 
+                             VTableAddressPointsMapTy& AddressPoints);
+  
+  llvm::GlobalVariable *getVTT(const CXXRecordDecl *RD);
+  
+  // EmitVTableRelatedData - Will emit any thunks that the global decl might
+  // have, as well as the vtable itself if the global decl is the key function.
+  void EmitVTableRelatedData(GlobalDecl GD);
+
+  /// GenerateClassData - Generate all the class data required to be generated
+  /// upon definition of a KeyFunction.  This includes the vtable, the
+  /// rtti data structure and the VTT.
+  ///
+  /// \param Linkage - The desired linkage of the vtable, the RTTI and the VTT.
+  void GenerateClassData(llvm::GlobalVariable::LinkageTypes Linkage,
+                         const CXXRecordDecl *RD);
+};
+
+} // end namespace CodeGen
+} // end namespace clang
+#endif
diff --git a/lib/CodeGen/CGValue.h b/lib/CodeGen/CGValue.h
new file mode 100644
index 0000000..e7343e2
--- /dev/null
+++ b/lib/CodeGen/CGValue.h
@@ -0,0 +1,313 @@
+//===-- CGValue.h - LLVM CodeGen wrappers for llvm::Value* ------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// These classes implement wrappers around llvm::Value in order to
+// fully represent the range of values for C L- and R- values.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_CODEGEN_CGVALUE_H
+#define CLANG_CODEGEN_CGVALUE_H
+
+#include "clang/AST/Type.h"
+
+namespace llvm {
+  class Constant;
+  class Value;
+}
+
+namespace clang {
+  class ObjCPropertyRefExpr;
+  class ObjCImplicitSetterGetterRefExpr;
+
+namespace CodeGen {
+  class CGBitFieldInfo;
+
+/// RValue - This trivial value class is used to represent the result of an
+/// expression that is evaluated.  It can be one of three things: either a
+/// simple LLVM SSA value, a pair of SSA values for complex numbers, or the
+/// address of an aggregate value in memory.
+class RValue {
+  llvm::Value *V1, *V2;
+  // TODO: Encode this into the low bit of pointer for more efficient
+  // return-by-value.
+  enum { Scalar, Complex, Aggregate } Flavor;
+
+  bool Volatile:1;
+public:
+
+  bool isScalar() const { return Flavor == Scalar; }
+  bool isComplex() const { return Flavor == Complex; }
+  bool isAggregate() const { return Flavor == Aggregate; }
+
+  bool isVolatileQualified() const { return Volatile; }
+
+  /// getScalarVal() - Return the Value* of this scalar value.
+  llvm::Value *getScalarVal() const {
+    assert(isScalar() && "Not a scalar!");
+    return V1;
+  }
+
+  /// getComplexVal - Return the real/imag components of this complex value.
+  ///
+  std::pair<llvm::Value *, llvm::Value *> getComplexVal() const {
+    return std::pair<llvm::Value *, llvm::Value *>(V1, V2);
+  }
+
+  /// getAggregateAddr() - Return the Value* of the address of the aggregate.
+  llvm::Value *getAggregateAddr() const {
+    assert(isAggregate() && "Not an aggregate!");
+    return V1;
+  }
+
+  static RValue get(llvm::Value *V) {
+    RValue ER;
+    ER.V1 = V;
+    ER.Flavor = Scalar;
+    ER.Volatile = false;
+    return ER;
+  }
+  static RValue getComplex(llvm::Value *V1, llvm::Value *V2) {
+    RValue ER;
+    ER.V1 = V1;
+    ER.V2 = V2;
+    ER.Flavor = Complex;
+    ER.Volatile = false;
+    return ER;
+  }
+  static RValue getComplex(const std::pair<llvm::Value *, llvm::Value *> &C) {
+    RValue ER;
+    ER.V1 = C.first;
+    ER.V2 = C.second;
+    ER.Flavor = Complex;
+    ER.Volatile = false;
+    return ER;
+  }
+  // FIXME: Aggregate rvalues need to retain information about whether they are
+  // volatile or not.  Remove default to find all places that probably get this
+  // wrong.
+  static RValue getAggregate(llvm::Value *V, bool Vol = false) {
+    RValue ER;
+    ER.V1 = V;
+    ER.Flavor = Aggregate;
+    ER.Volatile = Vol;
+    return ER;
+  }
+};
+
+
+/// LValue - This represents an lvalue references.  Because C/C++ allow
+/// bitfields, this is not a simple LLVM pointer, it may be a pointer plus a
+/// bitrange.
+class LValue {
+  // FIXME: alignment?
+
+  enum {
+    Simple,       // This is a normal l-value, use getAddress().
+    VectorElt,    // This is a vector element l-value (V[i]), use getVector*
+    BitField,     // This is a bitfield l-value, use getBitfield*.
+    ExtVectorElt, // This is an extended vector subset, use getExtVectorComp
+    PropertyRef,  // This is an Objective-C property reference, use
+                  // getPropertyRefExpr
+    KVCRef        // This is an objective-c 'implicit' property ref,
+                  // use getKVCRefExpr
+  } LVType;
+
+  llvm::Value *V;
+
+  union {
+    // Index into a vector subscript: V[i]
+    llvm::Value *VectorIdx;
+
+    // ExtVector element subset: V.xyx
+    llvm::Constant *VectorElts;
+
+    // BitField start bit and size
+    const CGBitFieldInfo *BitFieldInfo;
+
+    // Obj-C property reference expression
+    const ObjCPropertyRefExpr *PropertyRefExpr;
+
+    // ObjC 'implicit' property reference expression
+    const ObjCImplicitSetterGetterRefExpr *KVCRefExpr;
+  };
+
+  // 'const' is unused here
+  Qualifiers Quals;
+
+  // objective-c's ivar
+  bool Ivar:1;
+  
+  // objective-c's ivar is an array
+  bool ObjIsArray:1;
+
+  // LValue is non-gc'able for any reason, including being a parameter or local
+  // variable.
+  bool NonGC: 1;
+
+  // Lvalue is a global reference of an objective-c object
+  bool GlobalObjCRef : 1;
+
+  Expr *BaseIvarExp;
+private:
+  void SetQualifiers(Qualifiers Quals) {
+    this->Quals = Quals;
+    
+    // FIXME: Convenient place to set objc flags to 0. This should really be
+    // done in a user-defined constructor instead.
+    this->Ivar = this->ObjIsArray = this->NonGC = this->GlobalObjCRef = false;
+    this->BaseIvarExp = 0;
+  }
+
+public:
+  bool isSimple() const { return LVType == Simple; }
+  bool isVectorElt() const { return LVType == VectorElt; }
+  bool isBitField() const { return LVType == BitField; }
+  bool isExtVectorElt() const { return LVType == ExtVectorElt; }
+  bool isPropertyRef() const { return LVType == PropertyRef; }
+  bool isKVCRef() const { return LVType == KVCRef; }
+
+  bool isVolatileQualified() const { return Quals.hasVolatile(); }
+  bool isRestrictQualified() const { return Quals.hasRestrict(); }
+  unsigned getVRQualifiers() const {
+    return Quals.getCVRQualifiers() & ~Qualifiers::Const;
+  }
+
+  bool isObjCIvar() const { return Ivar; }
+  bool isObjCArray() const { return ObjIsArray; }
+  bool isNonGC () const { return NonGC; }
+  bool isGlobalObjCRef() const { return GlobalObjCRef; }
+  bool isObjCWeak() const { return Quals.getObjCGCAttr() == Qualifiers::Weak; }
+  bool isObjCStrong() const { return Quals.getObjCGCAttr() == Qualifiers::Strong; }
+  
+  Expr *getBaseIvarExp() const { return BaseIvarExp; }
+  void setBaseIvarExp(Expr *V) { BaseIvarExp = V; }
+
+  unsigned getAddressSpace() const { return Quals.getAddressSpace(); }
+
+  static void SetObjCIvar(LValue& R, bool iValue) {
+    R.Ivar = iValue;
+  }
+  static void SetObjCArray(LValue& R, bool iValue) {
+    R.ObjIsArray = iValue;
+  }
+  static void SetGlobalObjCRef(LValue& R, bool iValue) {
+    R.GlobalObjCRef = iValue;
+  }
+
+  static void SetObjCNonGC(LValue& R, bool iValue) {
+    R.NonGC = iValue;
+  }
+
+  // simple lvalue
+  llvm::Value *getAddress() const { assert(isSimple()); return V; }
+
+  // vector elt lvalue
+  llvm::Value *getVectorAddr() const { assert(isVectorElt()); return V; }
+  llvm::Value *getVectorIdx() const { assert(isVectorElt()); return VectorIdx; }
+
+  // extended vector elements.
+  llvm::Value *getExtVectorAddr() const { assert(isExtVectorElt()); return V; }
+  llvm::Constant *getExtVectorElts() const {
+    assert(isExtVectorElt());
+    return VectorElts;
+  }
+
+  // bitfield lvalue
+  llvm::Value *getBitFieldBaseAddr() const {
+    assert(isBitField());
+    return V;
+  }
+  const CGBitFieldInfo &getBitFieldInfo() const {
+    assert(isBitField());
+    return *BitFieldInfo;
+  }
+
+  // property ref lvalue
+  const ObjCPropertyRefExpr *getPropertyRefExpr() const {
+    assert(isPropertyRef());
+    return PropertyRefExpr;
+  }
+
+  // 'implicit' property ref lvalue
+  const ObjCImplicitSetterGetterRefExpr *getKVCRefExpr() const {
+    assert(isKVCRef());
+    return KVCRefExpr;
+  }
+
+  static LValue MakeAddr(llvm::Value *V, Qualifiers Quals) {
+    LValue R;
+    R.LVType = Simple;
+    R.V = V;
+    R.SetQualifiers(Quals);
+    return R;
+  }
+
+  static LValue MakeVectorElt(llvm::Value *Vec, llvm::Value *Idx,
+                              unsigned CVR) {
+    LValue R;
+    R.LVType = VectorElt;
+    R.V = Vec;
+    R.VectorIdx = Idx;
+    R.SetQualifiers(Qualifiers::fromCVRMask(CVR));
+    return R;
+  }
+
+  static LValue MakeExtVectorElt(llvm::Value *Vec, llvm::Constant *Elts,
+                                 unsigned CVR) {
+    LValue R;
+    R.LVType = ExtVectorElt;
+    R.V = Vec;
+    R.VectorElts = Elts;
+    R.SetQualifiers(Qualifiers::fromCVRMask(CVR));
+    return R;
+  }
+
+  /// \brief Create a new object to represent a bit-field access.
+  ///
+  /// \param BaseValue - The base address of the structure containing the
+  /// bit-field.
+  /// \param Info - The information describing how to perform the bit-field
+  /// access.
+  static LValue MakeBitfield(llvm::Value *BaseValue, const CGBitFieldInfo &Info,
+                             unsigned CVR) {
+    LValue R;
+    R.LVType = BitField;
+    R.V = BaseValue;
+    R.BitFieldInfo = &Info;
+    R.SetQualifiers(Qualifiers::fromCVRMask(CVR));
+    return R;
+  }
+
+  // FIXME: It is probably bad that we aren't emitting the target when we build
+  // the lvalue. However, this complicates the code a bit, and I haven't figured
+  // out how to make it go wrong yet.
+  static LValue MakePropertyRef(const ObjCPropertyRefExpr *E,
+                                unsigned CVR) {
+    LValue R;
+    R.LVType = PropertyRef;
+    R.PropertyRefExpr = E;
+    R.SetQualifiers(Qualifiers::fromCVRMask(CVR));
+    return R;
+  }
+
+  static LValue MakeKVCRef(const ObjCImplicitSetterGetterRefExpr *E,
+                           unsigned CVR) {
+    LValue R;
+    R.LVType = KVCRef;
+    R.KVCRefExpr = E;
+    R.SetQualifiers(Qualifiers::fromCVRMask(CVR));
+    return R;
+  }
+};
+
+}  // end namespace CodeGen
+}  // end namespace clang
+
+#endif
diff --git a/lib/CodeGen/CMakeLists.txt b/lib/CodeGen/CMakeLists.txt
new file mode 100644
index 0000000..dfd2a39
--- /dev/null
+++ b/lib/CodeGen/CMakeLists.txt
@@ -0,0 +1,34 @@
+set(LLVM_NO_RTTI 1)
+
+add_clang_library(clangCodeGen
+  CGBlocks.cpp
+  CGBuiltin.cpp
+  CGCall.cpp
+  CGClass.cpp
+  CGCXX.cpp
+  CGDebugInfo.cpp
+  CGDecl.cpp
+  CGDeclCXX.cpp
+  CGException.cpp
+  CGExpr.cpp
+  CGExprAgg.cpp
+  CGExprComplex.cpp
+  CGExprConstant.cpp
+  CGExprCXX.cpp
+  CGExprScalar.cpp
+  CGObjC.cpp
+  CGObjCGNU.cpp
+  CGObjCMac.cpp
+  CGRecordLayoutBuilder.cpp
+  CGRTTI.cpp
+  CGStmt.cpp
+  CGTemporaries.cpp
+  CGVTables.cpp
+  CGVTT.cpp
+  CodeGenFunction.cpp
+  CodeGenModule.cpp
+  CodeGenTypes.cpp
+  Mangle.cpp
+  ModuleBuilder.cpp
+  TargetInfo.cpp
+  )
diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp
new file mode 100644
index 0000000..110a8dc
--- /dev/null
+++ b/lib/CodeGen/CodeGenFunction.cpp
@@ -0,0 +1,814 @@
+//===--- CodeGenFunction.cpp - Emit LLVM Code from ASTs for a Function ----===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This coordinates the per-function state used while generating code.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CodeGenFunction.h"
+#include "CodeGenModule.h"
+#include "CGDebugInfo.h"
+#include "clang/Basic/TargetInfo.h"
+#include "clang/AST/APValue.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/StmtCXX.h"
+#include "llvm/Target/TargetData.h"
+using namespace clang;
+using namespace CodeGen;
+
+CodeGenFunction::CodeGenFunction(CodeGenModule &cgm)
+  : BlockFunction(cgm, *this, Builder), CGM(cgm),
+    Target(CGM.getContext().Target),
+    Builder(cgm.getModule().getContext()),
+    DebugInfo(0), IndirectBranch(0),
+    SwitchInsn(0), CaseRangeBlock(0), InvokeDest(0),
+    CXXThisDecl(0), CXXThisValue(0), CXXVTTDecl(0), CXXVTTValue(0),
+    ConditionalBranchLevel(0), TerminateHandler(0), TrapBB(0),
+    UniqueAggrDestructorCount(0) {
+  LLVMIntTy = ConvertType(getContext().IntTy);
+  LLVMPointerWidth = Target.getPointerWidth(0);
+  Exceptions = getContext().getLangOptions().Exceptions;
+  CatchUndefined = getContext().getLangOptions().CatchUndefined;
+}
+
+ASTContext &CodeGenFunction::getContext() const {
+  return CGM.getContext();
+}
+
+
+llvm::BasicBlock *CodeGenFunction::getBasicBlockForLabel(const LabelStmt *S) {
+  llvm::BasicBlock *&BB = LabelMap[S];
+  if (BB) return BB;
+
+  // Create, but don't insert, the new block.
+  return BB = createBasicBlock(S->getName());
+}
+
+llvm::Value *CodeGenFunction::GetAddrOfLocalVar(const VarDecl *VD) {
+  llvm::Value *Res = LocalDeclMap[VD];
+  assert(Res && "Invalid argument to GetAddrOfLocalVar(), no decl!");
+  return Res;
+}
+
+llvm::Constant *
+CodeGenFunction::GetAddrOfStaticLocalVar(const VarDecl *BVD) {
+  return cast<llvm::Constant>(GetAddrOfLocalVar(BVD));
+}
+
+const llvm::Type *CodeGenFunction::ConvertTypeForMem(QualType T) {
+  return CGM.getTypes().ConvertTypeForMem(T);
+}
+
+const llvm::Type *CodeGenFunction::ConvertType(QualType T) {
+  return CGM.getTypes().ConvertType(T);
+}
+
+bool CodeGenFunction::hasAggregateLLVMType(QualType T) {
+  return T->isRecordType() || T->isArrayType() || T->isAnyComplexType() ||
+    T->isMemberFunctionPointerType();
+}
+
+void CodeGenFunction::EmitReturnBlock() {
+  // For cleanliness, we try to avoid emitting the return block for
+  // simple cases.
+  llvm::BasicBlock *CurBB = Builder.GetInsertBlock();
+
+  if (CurBB) {
+    assert(!CurBB->getTerminator() && "Unexpected terminated block.");
+
+    // We have a valid insert point, reuse it if it is empty or there are no
+    // explicit jumps to the return block.
+    if (CurBB->empty() || ReturnBlock->use_empty()) {
+      ReturnBlock->replaceAllUsesWith(CurBB);
+      delete ReturnBlock;
+    } else
+      EmitBlock(ReturnBlock);
+    return;
+  }
+
+  // Otherwise, if the return block is the target of a single direct
+  // branch then we can just put the code in that block instead. This
+  // cleans up functions which started with a unified return block.
+  if (ReturnBlock->hasOneUse()) {
+    llvm::BranchInst *BI =
+      dyn_cast<llvm::BranchInst>(*ReturnBlock->use_begin());
+    if (BI && BI->isUnconditional() && BI->getSuccessor(0) == ReturnBlock) {
+      // Reset insertion point and delete the branch.
+      Builder.SetInsertPoint(BI->getParent());
+      BI->eraseFromParent();
+      delete ReturnBlock;
+      return;
+    }
+  }
+
+  // FIXME: We are at an unreachable point, there is no reason to emit the block
+  // unless it has uses. However, we still need a place to put the debug
+  // region.end for now.
+
+  EmitBlock(ReturnBlock);
+}
+
+void CodeGenFunction::FinishFunction(SourceLocation EndLoc) {
+  assert(BreakContinueStack.empty() &&
+         "mismatched push/pop in break/continue stack!");
+  assert(BlockScopes.empty() &&
+         "did not remove all blocks from block scope map!");
+  assert(CleanupEntries.empty() &&
+         "mismatched push/pop in cleanup stack!");
+
+  // Emit function epilog (to return).
+  EmitReturnBlock();
+
+  // Emit debug descriptor for function end.
+  if (CGDebugInfo *DI = getDebugInfo()) {
+    DI->setLocation(EndLoc);
+    DI->EmitRegionEnd(CurFn, Builder);
+  }
+
+  EmitFunctionEpilog(*CurFnInfo, ReturnValue);
+  EmitEndEHSpec(CurCodeDecl);
+
+  // If someone did an indirect goto, emit the indirect goto block at the end of
+  // the function.
+  if (IndirectBranch) {
+    EmitBlock(IndirectBranch->getParent());
+    Builder.ClearInsertionPoint();
+  }
+  
+  // Remove the AllocaInsertPt instruction, which is just a convenience for us.
+  llvm::Instruction *Ptr = AllocaInsertPt;
+  AllocaInsertPt = 0;
+  Ptr->eraseFromParent();
+  
+  // If someone took the address of a label but never did an indirect goto, we
+  // made a zero entry PHI node, which is illegal, zap it now.
+  if (IndirectBranch) {
+    llvm::PHINode *PN = cast<llvm::PHINode>(IndirectBranch->getAddress());
+    if (PN->getNumIncomingValues() == 0) {
+      PN->replaceAllUsesWith(llvm::UndefValue::get(PN->getType()));
+      PN->eraseFromParent();
+    }
+  }
+}
+
+void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
+                                    llvm::Function *Fn,
+                                    const FunctionArgList &Args,
+                                    SourceLocation StartLoc) {
+  const Decl *D = GD.getDecl();
+  
+  DidCallStackSave = false;
+  CurCodeDecl = CurFuncDecl = D;
+  FnRetTy = RetTy;
+  CurFn = Fn;
+  assert(CurFn->isDeclaration() && "Function already has body?");
+
+  // Pass inline keyword to optimizer if it appears explicitly on any
+  // declaration.
+  if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
+    for (FunctionDecl::redecl_iterator RI = FD->redecls_begin(),
+           RE = FD->redecls_end(); RI != RE; ++RI)
+      if (RI->isInlineSpecified()) {
+        Fn->addFnAttr(llvm::Attribute::InlineHint);
+        break;
+      }
+
+  llvm::BasicBlock *EntryBB = createBasicBlock("entry", CurFn);
+
+  // Create a marker to make it easy to insert allocas into the entryblock
+  // later.  Don't create this with the builder, because we don't want it
+  // folded.
+  llvm::Value *Undef = llvm::UndefValue::get(llvm::Type::getInt32Ty(VMContext));
+  AllocaInsertPt = new llvm::BitCastInst(Undef,
+                                         llvm::Type::getInt32Ty(VMContext), "",
+                                         EntryBB);
+  if (Builder.isNamePreserving())
+    AllocaInsertPt->setName("allocapt");
+
+  ReturnBlock = createBasicBlock("return");
+
+  Builder.SetInsertPoint(EntryBB);
+
+  QualType FnType = getContext().getFunctionType(RetTy, 0, 0, false, 0,
+                                                 false, false, 0, 0,
+                                                 /*FIXME?*/
+                                                 FunctionType::ExtInfo());
+
+  // Emit subprogram debug descriptor.
+  if (CGDebugInfo *DI = getDebugInfo()) {
+    DI->setLocation(StartLoc);
+    DI->EmitFunctionStart(GD, FnType, CurFn, Builder);
+  }
+
+  // FIXME: Leaked.
+  // CC info is ignored, hopefully?
+  CurFnInfo = &CGM.getTypes().getFunctionInfo(FnRetTy, Args,
+                                              FunctionType::ExtInfo());
+
+  if (RetTy->isVoidType()) {
+    // Void type; nothing to return.
+    ReturnValue = 0;
+  } else if (CurFnInfo->getReturnInfo().getKind() == ABIArgInfo::Indirect &&
+             hasAggregateLLVMType(CurFnInfo->getReturnType())) {
+    // Indirect aggregate return; emit returned value directly into sret slot.
+    // This reduces code size, and affects correctness in C++.
+    ReturnValue = CurFn->arg_begin();
+  } else {
+    ReturnValue = CreateIRTemp(RetTy, "retval");
+  }
+
+  EmitStartEHSpec(CurCodeDecl);
+  EmitFunctionProlog(*CurFnInfo, CurFn, Args);
+
+  if (CXXThisDecl)
+    CXXThisValue = Builder.CreateLoad(LocalDeclMap[CXXThisDecl], "this");
+  if (CXXVTTDecl)
+    CXXVTTValue = Builder.CreateLoad(LocalDeclMap[CXXVTTDecl], "vtt");
+
+  // If any of the arguments have a variably modified type, make sure to
+  // emit the type size.
+  for (FunctionArgList::const_iterator i = Args.begin(), e = Args.end();
+       i != e; ++i) {
+    QualType Ty = i->second;
+
+    if (Ty->isVariablyModifiedType())
+      EmitVLASize(Ty);
+  }
+}
+
+void CodeGenFunction::EmitFunctionBody(FunctionArgList &Args) {
+  const FunctionDecl *FD = cast<FunctionDecl>(CurGD.getDecl());
+
+  Stmt *Body = FD->getBody();
+  if (Body)
+    EmitStmt(Body);
+  else {
+    assert(FD->isImplicit() && "non-implicit function def has no body");
+    assert(FD->isCopyAssignment() && "implicit function not copy assignment");
+    SynthesizeCXXCopyAssignment(Args);
+  }
+}
+
+void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn) {
+  const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl());
+  
+  // Check if we should generate debug info for this function.
+  if (CGM.getDebugInfo() && !FD->hasAttr<NoDebugAttr>())
+    DebugInfo = CGM.getDebugInfo();
+
+  FunctionArgList Args;
+
+  CurGD = GD;
+  if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
+    if (MD->isInstance()) {
+      // Create the implicit 'this' decl.
+      // FIXME: I'm not entirely sure I like using a fake decl just for code
+      // generation. Maybe we can come up with a better way?
+      CXXThisDecl = ImplicitParamDecl::Create(getContext(), 0,
+                                              FD->getLocation(),
+                                              &getContext().Idents.get("this"),
+                                              MD->getThisType(getContext()));
+      Args.push_back(std::make_pair(CXXThisDecl, CXXThisDecl->getType()));
+      
+      // Check if we need a VTT parameter as well.
+      if (CodeGenVTables::needsVTTParameter(GD)) {
+        // FIXME: The comment about using a fake decl above applies here too.
+        QualType T = getContext().getPointerType(getContext().VoidPtrTy);
+        CXXVTTDecl = 
+          ImplicitParamDecl::Create(getContext(), 0, FD->getLocation(),
+                                    &getContext().Idents.get("vtt"), T);
+        Args.push_back(std::make_pair(CXXVTTDecl, CXXVTTDecl->getType()));
+      }
+    }
+  }
+
+  if (FD->getNumParams()) {
+    const FunctionProtoType* FProto = FD->getType()->getAs<FunctionProtoType>();
+    assert(FProto && "Function def must have prototype!");
+
+    for (unsigned i = 0, e = FD->getNumParams(); i != e; ++i)
+      Args.push_back(std::make_pair(FD->getParamDecl(i),
+                                    FProto->getArgType(i)));
+  }
+
+  SourceRange BodyRange;
+  if (Stmt *Body = FD->getBody()) BodyRange = Body->getSourceRange();
+
+  // Emit the standard function prologue.
+  StartFunction(GD, FD->getResultType(), Fn, Args, BodyRange.getBegin());
+
+  // Generate the body of the function.
+  if (isa<CXXDestructorDecl>(FD))
+    EmitDestructorBody(Args);
+  else if (isa<CXXConstructorDecl>(FD))
+    EmitConstructorBody(Args);
+  else
+    EmitFunctionBody(Args);
+
+  // Emit the standard function epilogue.
+  FinishFunction(BodyRange.getEnd());
+
+  // Destroy the 'this' declaration.
+  if (CXXThisDecl)
+    CXXThisDecl->Destroy(getContext());
+  
+  // Destroy the VTT declaration.
+  if (CXXVTTDecl)
+    CXXVTTDecl->Destroy(getContext());
+}
+
+/// ContainsLabel - Return true if the statement contains a label in it.  If
+/// this statement is not executed normally, it not containing a label means
+/// that we can just remove the code.
+bool CodeGenFunction::ContainsLabel(const Stmt *S, bool IgnoreCaseStmts) {
+  // Null statement, not a label!
+  if (S == 0) return false;
+
+  // If this is a label, we have to emit the code, consider something like:
+  // if (0) {  ...  foo:  bar(); }  goto foo;
+  if (isa<LabelStmt>(S))
+    return true;
+
+  // If this is a case/default statement, and we haven't seen a switch, we have
+  // to emit the code.
+  if (isa<SwitchCase>(S) && !IgnoreCaseStmts)
+    return true;
+
+  // If this is a switch statement, we want to ignore cases below it.
+  if (isa<SwitchStmt>(S))
+    IgnoreCaseStmts = true;
+
+  // Scan subexpressions for verboten labels.
+  for (Stmt::const_child_iterator I = S->child_begin(), E = S->child_end();
+       I != E; ++I)
+    if (ContainsLabel(*I, IgnoreCaseStmts))
+      return true;
+
+  return false;
+}
+
+
+/// ConstantFoldsToSimpleInteger - If the sepcified expression does not fold to
+/// a constant, or if it does but contains a label, return 0.  If it constant
+/// folds to 'true' and does not contain a label, return 1, if it constant folds
+/// to 'false' and does not contain a label, return -1.
+int CodeGenFunction::ConstantFoldsToSimpleInteger(const Expr *Cond) {
+  // FIXME: Rename and handle conversion of other evaluatable things
+  // to bool.
+  Expr::EvalResult Result;
+  if (!Cond->Evaluate(Result, getContext()) || !Result.Val.isInt() ||
+      Result.HasSideEffects)
+    return 0;  // Not foldable, not integer or not fully evaluatable.
+
+  if (CodeGenFunction::ContainsLabel(Cond))
+    return 0;  // Contains a label.
+
+  return Result.Val.getInt().getBoolValue() ? 1 : -1;
+}
+
+
+/// EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g. for an if
+/// statement) to the specified blocks.  Based on the condition, this might try
+/// to simplify the codegen of the conditional based on the branch.
+///
+void CodeGenFunction::EmitBranchOnBoolExpr(const Expr *Cond,
+                                           llvm::BasicBlock *TrueBlock,
+                                           llvm::BasicBlock *FalseBlock) {
+  if (const ParenExpr *PE = dyn_cast<ParenExpr>(Cond))
+    return EmitBranchOnBoolExpr(PE->getSubExpr(), TrueBlock, FalseBlock);
+
+  if (const BinaryOperator *CondBOp = dyn_cast<BinaryOperator>(Cond)) {
+    // Handle X && Y in a condition.
+    if (CondBOp->getOpcode() == BinaryOperator::LAnd) {
+      // If we have "1 && X", simplify the code.  "0 && X" would have constant
+      // folded if the case was simple enough.
+      if (ConstantFoldsToSimpleInteger(CondBOp->getLHS()) == 1) {
+        // br(1 && X) -> br(X).
+        return EmitBranchOnBoolExpr(CondBOp->getRHS(), TrueBlock, FalseBlock);
+      }
+
+      // If we have "X && 1", simplify the code to use an uncond branch.
+      // "X && 0" would have been constant folded to 0.
+      if (ConstantFoldsToSimpleInteger(CondBOp->getRHS()) == 1) {
+        // br(X && 1) -> br(X).
+        return EmitBranchOnBoolExpr(CondBOp->getLHS(), TrueBlock, FalseBlock);
+      }
+
+      // Emit the LHS as a conditional.  If the LHS conditional is false, we
+      // want to jump to the FalseBlock.
+      llvm::BasicBlock *LHSTrue = createBasicBlock("land.lhs.true");
+      EmitBranchOnBoolExpr(CondBOp->getLHS(), LHSTrue, FalseBlock);
+      EmitBlock(LHSTrue);
+
+      // Any temporaries created here are conditional.
+      BeginConditionalBranch();
+      EmitBranchOnBoolExpr(CondBOp->getRHS(), TrueBlock, FalseBlock);
+      EndConditionalBranch();
+
+      return;
+    } else if (CondBOp->getOpcode() == BinaryOperator::LOr) {
+      // If we have "0 || X", simplify the code.  "1 || X" would have constant
+      // folded if the case was simple enough.
+      if (ConstantFoldsToSimpleInteger(CondBOp->getLHS()) == -1) {
+        // br(0 || X) -> br(X).
+        return EmitBranchOnBoolExpr(CondBOp->getRHS(), TrueBlock, FalseBlock);
+      }
+
+      // If we have "X || 0", simplify the code to use an uncond branch.
+      // "X || 1" would have been constant folded to 1.
+      if (ConstantFoldsToSimpleInteger(CondBOp->getRHS()) == -1) {
+        // br(X || 0) -> br(X).
+        return EmitBranchOnBoolExpr(CondBOp->getLHS(), TrueBlock, FalseBlock);
+      }
+
+      // Emit the LHS as a conditional.  If the LHS conditional is true, we
+      // want to jump to the TrueBlock.
+      llvm::BasicBlock *LHSFalse = createBasicBlock("lor.lhs.false");
+      EmitBranchOnBoolExpr(CondBOp->getLHS(), TrueBlock, LHSFalse);
+      EmitBlock(LHSFalse);
+
+      // Any temporaries created here are conditional.
+      BeginConditionalBranch();
+      EmitBranchOnBoolExpr(CondBOp->getRHS(), TrueBlock, FalseBlock);
+      EndConditionalBranch();
+
+      return;
+    }
+  }
+
+  if (const UnaryOperator *CondUOp = dyn_cast<UnaryOperator>(Cond)) {
+    // br(!x, t, f) -> br(x, f, t)
+    if (CondUOp->getOpcode() == UnaryOperator::LNot)
+      return EmitBranchOnBoolExpr(CondUOp->getSubExpr(), FalseBlock, TrueBlock);
+  }
+
+  if (const ConditionalOperator *CondOp = dyn_cast<ConditionalOperator>(Cond)) {
+    // Handle ?: operator.
+
+    // Just ignore GNU ?: extension.
+    if (CondOp->getLHS()) {
+      // br(c ? x : y, t, f) -> br(c, br(x, t, f), br(y, t, f))
+      llvm::BasicBlock *LHSBlock = createBasicBlock("cond.true");
+      llvm::BasicBlock *RHSBlock = createBasicBlock("cond.false");
+      EmitBranchOnBoolExpr(CondOp->getCond(), LHSBlock, RHSBlock);
+      EmitBlock(LHSBlock);
+      EmitBranchOnBoolExpr(CondOp->getLHS(), TrueBlock, FalseBlock);
+      EmitBlock(RHSBlock);
+      EmitBranchOnBoolExpr(CondOp->getRHS(), TrueBlock, FalseBlock);
+      return;
+    }
+  }
+
+  // Emit the code with the fully general case.
+  llvm::Value *CondV = EvaluateExprAsBool(Cond);
+  Builder.CreateCondBr(CondV, TrueBlock, FalseBlock);
+}
+
+/// ErrorUnsupported - Print out an error that codegen doesn't support the
+/// specified stmt yet.
+void CodeGenFunction::ErrorUnsupported(const Stmt *S, const char *Type,
+                                       bool OmitOnError) {
+  CGM.ErrorUnsupported(S, Type, OmitOnError);
+}
+
+void CodeGenFunction::EmitMemSetToZero(llvm::Value *DestPtr, QualType Ty) {
+  const llvm::Type *BP = llvm::Type::getInt8PtrTy(VMContext);
+  if (DestPtr->getType() != BP)
+    DestPtr = Builder.CreateBitCast(DestPtr, BP, "tmp");
+
+  // Get size and alignment info for this aggregate.
+  std::pair<uint64_t, unsigned> TypeInfo = getContext().getTypeInfo(Ty);
+
+  // Don't bother emitting a zero-byte memset.
+  if (TypeInfo.first == 0)
+    return;
+
+  // FIXME: Handle variable sized types.
+  const llvm::Type *IntPtr = llvm::IntegerType::get(VMContext,
+                                                    LLVMPointerWidth);
+
+  Builder.CreateCall5(CGM.getMemSetFn(BP, IntPtr), DestPtr,
+                 llvm::Constant::getNullValue(llvm::Type::getInt8Ty(VMContext)),
+                      // TypeInfo.first describes size in bits.
+                      llvm::ConstantInt::get(IntPtr, TypeInfo.first/8),
+                      llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext),
+                                             TypeInfo.second/8),
+                      llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext),
+                                             0));
+}
+
+llvm::BlockAddress *CodeGenFunction::GetAddrOfLabel(const LabelStmt *L) {
+  // Make sure that there is a block for the indirect goto.
+  if (IndirectBranch == 0)
+    GetIndirectGotoBlock();
+  
+  llvm::BasicBlock *BB = getBasicBlockForLabel(L);
+  
+  // Make sure the indirect branch includes all of the address-taken blocks.
+  IndirectBranch->addDestination(BB);
+  return llvm::BlockAddress::get(CurFn, BB);
+}
+
+llvm::BasicBlock *CodeGenFunction::GetIndirectGotoBlock() {
+  // If we already made the indirect branch for indirect goto, return its block.
+  if (IndirectBranch) return IndirectBranch->getParent();
+  
+  CGBuilderTy TmpBuilder(createBasicBlock("indirectgoto"));
+  
+  const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext);
+
+  // Create the PHI node that indirect gotos will add entries to.
+  llvm::Value *DestVal = TmpBuilder.CreatePHI(Int8PtrTy, "indirect.goto.dest");
+  
+  // Create the indirect branch instruction.
+  IndirectBranch = TmpBuilder.CreateIndirectBr(DestVal);
+  return IndirectBranch->getParent();
+}
+
+llvm::Value *CodeGenFunction::GetVLASize(const VariableArrayType *VAT) {
+  llvm::Value *&SizeEntry = VLASizeMap[VAT->getSizeExpr()];
+
+  assert(SizeEntry && "Did not emit size for type");
+  return SizeEntry;
+}
+
+llvm::Value *CodeGenFunction::EmitVLASize(QualType Ty) {
+  assert(Ty->isVariablyModifiedType() &&
+         "Must pass variably modified type to EmitVLASizes!");
+
+  EnsureInsertPoint();
+
+  if (const VariableArrayType *VAT = getContext().getAsVariableArrayType(Ty)) {
+    llvm::Value *&SizeEntry = VLASizeMap[VAT->getSizeExpr()];
+
+    if (!SizeEntry) {
+      const llvm::Type *SizeTy = ConvertType(getContext().getSizeType());
+
+      // Get the element size;
+      QualType ElemTy = VAT->getElementType();
+      llvm::Value *ElemSize;
+      if (ElemTy->isVariableArrayType())
+        ElemSize = EmitVLASize(ElemTy);
+      else
+        ElemSize = llvm::ConstantInt::get(SizeTy,
+            getContext().getTypeSizeInChars(ElemTy).getQuantity());
+
+      llvm::Value *NumElements = EmitScalarExpr(VAT->getSizeExpr());
+      NumElements = Builder.CreateIntCast(NumElements, SizeTy, false, "tmp");
+
+      SizeEntry = Builder.CreateMul(ElemSize, NumElements);
+    }
+
+    return SizeEntry;
+  }
+
+  if (const ArrayType *AT = dyn_cast<ArrayType>(Ty)) {
+    EmitVLASize(AT->getElementType());
+    return 0;
+  }
+
+  const PointerType *PT = Ty->getAs<PointerType>();
+  assert(PT && "unknown VM type!");
+  EmitVLASize(PT->getPointeeType());
+  return 0;
+}
+
+llvm::Value* CodeGenFunction::EmitVAListRef(const Expr* E) {
+  if (CGM.getContext().getBuiltinVaListType()->isArrayType()) {
+    return EmitScalarExpr(E);
+  }
+  return EmitLValue(E).getAddress();
+}
+
+void CodeGenFunction::PushCleanupBlock(llvm::BasicBlock *CleanupEntryBlock,
+                                       llvm::BasicBlock *CleanupExitBlock,
+                                       llvm::BasicBlock *PreviousInvokeDest,
+                                       bool EHOnly) {
+  CleanupEntries.push_back(CleanupEntry(CleanupEntryBlock, CleanupExitBlock,
+                                        PreviousInvokeDest, EHOnly));
+}
+
+void CodeGenFunction::EmitCleanupBlocks(size_t OldCleanupStackSize) {
+  assert(CleanupEntries.size() >= OldCleanupStackSize &&
+         "Cleanup stack mismatch!");
+
+  while (CleanupEntries.size() > OldCleanupStackSize)
+    EmitCleanupBlock();
+}
+
+CodeGenFunction::CleanupBlockInfo CodeGenFunction::PopCleanupBlock() {
+  CleanupEntry &CE = CleanupEntries.back();
+
+  llvm::BasicBlock *CleanupEntryBlock = CE.CleanupEntryBlock;
+
+  std::vector<llvm::BasicBlock *> Blocks;
+  std::swap(Blocks, CE.Blocks);
+
+  std::vector<llvm::BranchInst *> BranchFixups;
+  std::swap(BranchFixups, CE.BranchFixups);
+
+  bool EHOnly = CE.EHOnly;
+
+  setInvokeDest(CE.PreviousInvokeDest);
+
+  CleanupEntries.pop_back();
+
+  // Check if any branch fixups pointed to the scope we just popped. If so,
+  // we can remove them.
+  for (size_t i = 0, e = BranchFixups.size(); i != e; ++i) {
+    llvm::BasicBlock *Dest = BranchFixups[i]->getSuccessor(0);
+    BlockScopeMap::iterator I = BlockScopes.find(Dest);
+
+    if (I == BlockScopes.end())
+      continue;
+
+    assert(I->second <= CleanupEntries.size() && "Invalid branch fixup!");
+
+    if (I->second == CleanupEntries.size()) {
+      // We don't need to do this branch fixup.
+      BranchFixups[i] = BranchFixups.back();
+      BranchFixups.pop_back();
+      i--;
+      e--;
+      continue;
+    }
+  }
+
+  llvm::BasicBlock *SwitchBlock = CE.CleanupExitBlock;
+  llvm::BasicBlock *EndBlock = 0;
+  if (!BranchFixups.empty()) {
+    if (!SwitchBlock)
+      SwitchBlock = createBasicBlock("cleanup.switch");
+    EndBlock = createBasicBlock("cleanup.end");
+
+    llvm::BasicBlock *CurBB = Builder.GetInsertBlock();
+
+    Builder.SetInsertPoint(SwitchBlock);
+
+    llvm::Value *DestCodePtr
+      = CreateTempAlloca(llvm::Type::getInt32Ty(VMContext),
+                         "cleanup.dst");
+    llvm::Value *DestCode = Builder.CreateLoad(DestCodePtr, "tmp");
+
+    // Create a switch instruction to determine where to jump next.
+    llvm::SwitchInst *SI = Builder.CreateSwitch(DestCode, EndBlock,
+                                                BranchFixups.size());
+
+    // Restore the current basic block (if any)
+    if (CurBB) {
+      Builder.SetInsertPoint(CurBB);
+
+      // If we had a current basic block, we also need to emit an instruction
+      // to initialize the cleanup destination.
+      Builder.CreateStore(llvm::Constant::getNullValue(llvm::Type::getInt32Ty(VMContext)),
+                          DestCodePtr);
+    } else
+      Builder.ClearInsertionPoint();
+
+    for (size_t i = 0, e = BranchFixups.size(); i != e; ++i) {
+      llvm::BranchInst *BI = BranchFixups[i];
+      llvm::BasicBlock *Dest = BI->getSuccessor(0);
+
+      // Fixup the branch instruction to point to the cleanup block.
+      BI->setSuccessor(0, CleanupEntryBlock);
+
+      if (CleanupEntries.empty()) {
+        llvm::ConstantInt *ID;
+
+        // Check if we already have a destination for this block.
+        if (Dest == SI->getDefaultDest())
+          ID = llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 0);
+        else {
+          ID = SI->findCaseDest(Dest);
+          if (!ID) {
+            // No code found, get a new unique one by using the number of
+            // switch successors.
+            ID = llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext),
+                                        SI->getNumSuccessors());
+            SI->addCase(ID, Dest);
+          }
+        }
+
+        // Store the jump destination before the branch instruction.
+        new llvm::StoreInst(ID, DestCodePtr, BI);
+      } else {
+        // We need to jump through another cleanup block. Create a pad block
+        // with a branch instruction that jumps to the final destination and add
+        // it as a branch fixup to the current cleanup scope.
+
+        // Create the pad block.
+        llvm::BasicBlock *CleanupPad = createBasicBlock("cleanup.pad", CurFn);
+
+        // Create a unique case ID.
+        llvm::ConstantInt *ID
+          = llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext),
+                                   SI->getNumSuccessors());
+
+        // Store the jump destination before the branch instruction.
+        new llvm::StoreInst(ID, DestCodePtr, BI);
+
+        // Add it as the destination.
+        SI->addCase(ID, CleanupPad);
+
+        // Create the branch to the final destination.
+        llvm::BranchInst *BI = llvm::BranchInst::Create(Dest);
+        CleanupPad->getInstList().push_back(BI);
+
+        // And add it as a branch fixup.
+        CleanupEntries.back().BranchFixups.push_back(BI);
+      }
+    }
+  }
+
+  // Remove all blocks from the block scope map.
+  for (size_t i = 0, e = Blocks.size(); i != e; ++i) {
+    assert(BlockScopes.count(Blocks[i]) &&
+           "Did not find block in scope map!");
+
+    BlockScopes.erase(Blocks[i]);
+  }
+
+  return CleanupBlockInfo(CleanupEntryBlock, SwitchBlock, EndBlock, EHOnly);
+}
+
+void CodeGenFunction::EmitCleanupBlock() {
+  CleanupBlockInfo Info = PopCleanupBlock();
+
+  if (Info.EHOnly) {
+    // FIXME: Add this to the exceptional edge
+    if (Info.CleanupBlock->getNumUses() == 0)
+      delete Info.CleanupBlock;
+    return;
+  }
+
+  //  Scrub debug location info.
+  for (llvm::BasicBlock::iterator LBI = Info.CleanupBlock->begin(),
+         LBE = Info.CleanupBlock->end(); LBI != LBE; ++LBI)
+    Builder.SetInstDebugLocation(LBI);
+
+  llvm::BasicBlock *CurBB = Builder.GetInsertBlock();
+  if (CurBB && !CurBB->getTerminator() &&
+      Info.CleanupBlock->getNumUses() == 0) {
+    CurBB->getInstList().splice(CurBB->end(), Info.CleanupBlock->getInstList());
+    delete Info.CleanupBlock;
+  } else
+    EmitBlock(Info.CleanupBlock);
+
+  if (Info.SwitchBlock)
+    EmitBlock(Info.SwitchBlock);
+  if (Info.EndBlock)
+    EmitBlock(Info.EndBlock);
+}
+
+void CodeGenFunction::AddBranchFixup(llvm::BranchInst *BI) {
+  assert(!CleanupEntries.empty() &&
+         "Trying to add branch fixup without cleanup block!");
+
+  // FIXME: We could be more clever here and check if there's already a branch
+  // fixup for this destination and recycle it.
+  CleanupEntries.back().BranchFixups.push_back(BI);
+}
+
+void CodeGenFunction::EmitBranchThroughCleanup(llvm::BasicBlock *Dest) {
+  if (!HaveInsertPoint())
+    return;
+
+  llvm::BranchInst* BI = Builder.CreateBr(Dest);
+
+  Builder.ClearInsertionPoint();
+
+  // The stack is empty, no need to do any cleanup.
+  if (CleanupEntries.empty())
+    return;
+
+  if (!Dest->getParent()) {
+    // We are trying to branch to a block that hasn't been inserted yet.
+    AddBranchFixup(BI);
+    return;
+  }
+
+  BlockScopeMap::iterator I = BlockScopes.find(Dest);
+  if (I == BlockScopes.end()) {
+    // We are trying to jump to a block that is outside of any cleanup scope.
+    AddBranchFixup(BI);
+    return;
+  }
+
+  assert(I->second < CleanupEntries.size() &&
+         "Trying to branch into cleanup region");
+
+  if (I->second == CleanupEntries.size() - 1) {
+    // We have a branch to a block in the same scope.
+    return;
+  }
+
+  AddBranchFixup(BI);
+}
diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h
new file mode 100644
index 0000000..e4e98ef
--- /dev/null
+++ b/lib/CodeGen/CodeGenFunction.h
@@ -0,0 +1,1394 @@
+//===-- CodeGenFunction.h - Per-Function state for LLVM CodeGen -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This is the internal per-function state used for llvm translation.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_CODEGEN_CODEGENFUNCTION_H
+#define CLANG_CODEGEN_CODEGENFUNCTION_H
+
+#include "clang/AST/Type.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/ExprObjC.h"
+#include "clang/AST/CharUnits.h"
+#include "clang/Basic/TargetInfo.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/ValueHandle.h"
+#include "CodeGenModule.h"
+#include "CGBlocks.h"
+#include "CGBuilder.h"
+#include "CGCall.h"
+#include "CGCXX.h"
+#include "CGValue.h"
+
+namespace llvm {
+  class BasicBlock;
+  class LLVMContext;
+  class Module;
+  class SwitchInst;
+  class Twine;
+  class Value;
+}
+
+namespace clang {
+  class ASTContext;
+  class CXXDestructorDecl;
+  class CXXTryStmt;
+  class Decl;
+  class EnumConstantDecl;
+  class FunctionDecl;
+  class FunctionProtoType;
+  class LabelStmt;
+  class ObjCContainerDecl;
+  class ObjCInterfaceDecl;
+  class ObjCIvarDecl;
+  class ObjCMethodDecl;
+  class ObjCImplementationDecl;
+  class ObjCPropertyImplDecl;
+  class TargetInfo;
+  class TargetCodeGenInfo;
+  class VarDecl;
+  class ObjCForCollectionStmt;
+  class ObjCAtTryStmt;
+  class ObjCAtThrowStmt;
+  class ObjCAtSynchronizedStmt;
+
+namespace CodeGen {
+  class CodeGenTypes;
+  class CGDebugInfo;
+  class CGFunctionInfo;
+  class CGRecordLayout;
+
+/// CodeGenFunction - This class organizes the per-function state that is used
+/// while generating LLVM code.
+class CodeGenFunction : public BlockFunction {
+  CodeGenFunction(const CodeGenFunction&); // DO NOT IMPLEMENT
+  void operator=(const CodeGenFunction&);  // DO NOT IMPLEMENT
+public:
+  CodeGenModule &CGM;  // Per-module state.
+  const TargetInfo &Target;
+
+  typedef std::pair<llvm::Value *, llvm::Value *> ComplexPairTy;
+  CGBuilderTy Builder;
+
+  /// CurFuncDecl - Holds the Decl for the current function or ObjC method.
+  /// This excludes BlockDecls.
+  const Decl *CurFuncDecl;
+  /// CurCodeDecl - This is the inner-most code context, which includes blocks.
+  const Decl *CurCodeDecl;
+  const CGFunctionInfo *CurFnInfo;
+  QualType FnRetTy;
+  llvm::Function *CurFn;
+
+  /// CurGD - The GlobalDecl for the current function being compiled.
+  GlobalDecl CurGD;
+
+  /// ReturnBlock - Unified return block.
+  llvm::BasicBlock *ReturnBlock;
+  /// ReturnValue - The temporary alloca to hold the return value. This is null
+  /// iff the function has no return value.
+  llvm::Value *ReturnValue;
+
+  /// AllocaInsertPoint - This is an instruction in the entry block before which
+  /// we prefer to insert allocas.
+  llvm::AssertingVH<llvm::Instruction> AllocaInsertPt;
+
+  const llvm::Type *LLVMIntTy;
+  uint32_t LLVMPointerWidth;
+
+  bool Exceptions;
+  bool CatchUndefined;
+public:
+  /// ObjCEHValueStack - Stack of Objective-C exception values, used for
+  /// rethrows.
+  llvm::SmallVector<llvm::Value*, 8> ObjCEHValueStack;
+
+  /// PushCleanupBlock - Push a new cleanup entry on the stack and set the
+  /// passed in block as the cleanup block.
+  void PushCleanupBlock(llvm::BasicBlock *CleanupEntryBlock,
+                        llvm::BasicBlock *CleanupExitBlock,
+                        llvm::BasicBlock *PreviousInvokeDest,
+                        bool EHOnly = false);
+  void PushCleanupBlock(llvm::BasicBlock *CleanupEntryBlock) {
+    PushCleanupBlock(CleanupEntryBlock, 0, getInvokeDest(), false);
+  }
+
+  /// CleanupBlockInfo - A struct representing a popped cleanup block.
+  struct CleanupBlockInfo {
+    /// CleanupEntryBlock - the cleanup entry block
+    llvm::BasicBlock *CleanupBlock;
+
+    /// SwitchBlock - the block (if any) containing the switch instruction used
+    /// for jumping to the final destination.
+    llvm::BasicBlock *SwitchBlock;
+
+    /// EndBlock - the default destination for the switch instruction.
+    llvm::BasicBlock *EndBlock;
+
+    /// EHOnly - True iff this cleanup should only be performed on the
+    /// exceptional edge.
+    bool EHOnly;
+
+    CleanupBlockInfo(llvm::BasicBlock *cb, llvm::BasicBlock *sb,
+                     llvm::BasicBlock *eb, bool ehonly = false)
+      : CleanupBlock(cb), SwitchBlock(sb), EndBlock(eb), EHOnly(ehonly) {}
+  };
+
+  /// EHCleanupBlock - RAII object that will create a cleanup block for the
+  /// exceptional edge and set the insert point to that block.  When destroyed,
+  /// it creates the cleanup edge and sets the insert point to the previous
+  /// block.
+  class EHCleanupBlock {
+    CodeGenFunction& CGF;
+    llvm::BasicBlock *PreviousInsertionBlock;
+    llvm::BasicBlock *CleanupHandler;
+    llvm::BasicBlock *PreviousInvokeDest;
+  public:
+    EHCleanupBlock(CodeGenFunction &cgf) 
+      : CGF(cgf),
+        PreviousInsertionBlock(CGF.Builder.GetInsertBlock()),
+        CleanupHandler(CGF.createBasicBlock("ehcleanup", CGF.CurFn)),
+        PreviousInvokeDest(CGF.getInvokeDest()) {
+      llvm::BasicBlock *TerminateHandler = CGF.getTerminateHandler();
+      CGF.Builder.SetInsertPoint(CleanupHandler);
+      CGF.setInvokeDest(TerminateHandler);
+    }
+    ~EHCleanupBlock();
+  };
+
+  /// PopCleanupBlock - Will pop the cleanup entry on the stack, process all
+  /// branch fixups and return a block info struct with the switch block and end
+  /// block.  This will also reset the invoke handler to the previous value
+  /// from when the cleanup block was created.
+  CleanupBlockInfo PopCleanupBlock();
+
+  /// DelayedCleanupBlock - RAII object that will create a cleanup block and set
+  /// the insert point to that block. When destructed, it sets the insert point
+  /// to the previous block and pushes a new cleanup entry on the stack.
+  class DelayedCleanupBlock {
+    CodeGenFunction& CGF;
+    llvm::BasicBlock *CurBB;
+    llvm::BasicBlock *CleanupEntryBB;
+    llvm::BasicBlock *CleanupExitBB;
+    llvm::BasicBlock *CurInvokeDest;
+    bool EHOnly;
+    
+  public:
+    DelayedCleanupBlock(CodeGenFunction &cgf, bool ehonly = false)
+      : CGF(cgf), CurBB(CGF.Builder.GetInsertBlock()),
+        CleanupEntryBB(CGF.createBasicBlock("cleanup")),
+        CleanupExitBB(0),
+        CurInvokeDest(CGF.getInvokeDest()),
+        EHOnly(ehonly) {
+      CGF.Builder.SetInsertPoint(CleanupEntryBB);
+    }
+
+    llvm::BasicBlock *getCleanupExitBlock() {
+      if (!CleanupExitBB)
+        CleanupExitBB = CGF.createBasicBlock("cleanup.exit");
+      return CleanupExitBB;
+    }
+    
+    ~DelayedCleanupBlock() {
+      CGF.PushCleanupBlock(CleanupEntryBB, CleanupExitBB, CurInvokeDest,
+                           EHOnly);
+      // FIXME: This is silly, move this into the builder.
+      if (CurBB)
+        CGF.Builder.SetInsertPoint(CurBB);
+      else
+        CGF.Builder.ClearInsertionPoint();
+    }
+  };
+
+  /// \brief Enters a new scope for capturing cleanups, all of which will be
+  /// executed once the scope is exited.
+  class CleanupScope {
+    CodeGenFunction& CGF;
+    size_t CleanupStackDepth;
+    bool OldDidCallStackSave;
+    bool PerformCleanup;
+
+    CleanupScope(const CleanupScope &); // DO NOT IMPLEMENT
+    CleanupScope &operator=(const CleanupScope &); // DO NOT IMPLEMENT
+
+  public:
+    /// \brief Enter a new cleanup scope.
+    explicit CleanupScope(CodeGenFunction &CGF) 
+      : CGF(CGF), PerformCleanup(true) 
+    {
+      CleanupStackDepth = CGF.CleanupEntries.size();
+      OldDidCallStackSave = CGF.DidCallStackSave;
+    }
+
+    /// \brief Exit this cleanup scope, emitting any accumulated
+    /// cleanups.
+    ~CleanupScope() {
+      if (PerformCleanup) {
+        CGF.DidCallStackSave = OldDidCallStackSave;
+        CGF.EmitCleanupBlocks(CleanupStackDepth);
+      }
+    }
+
+    /// \brief Determine whether this scope requires any cleanups.
+    bool requiresCleanups() const {
+      return CGF.CleanupEntries.size() > CleanupStackDepth;
+    }
+
+    /// \brief Force the emission of cleanups now, instead of waiting
+    /// until this object is destroyed.
+    void ForceCleanup() {
+      assert(PerformCleanup && "Already forced cleanup");
+      CGF.DidCallStackSave = OldDidCallStackSave;
+      CGF.EmitCleanupBlocks(CleanupStackDepth);
+      PerformCleanup = false;
+    }
+  };
+
+  /// CXXTemporariesCleanupScope - Enters a new scope for catching live
+  /// temporaries, all of which will be popped once the scope is exited.
+  class CXXTemporariesCleanupScope {
+    CodeGenFunction &CGF;
+    size_t NumLiveTemporaries;
+    
+    // DO NOT IMPLEMENT
+    CXXTemporariesCleanupScope(const CXXTemporariesCleanupScope &); 
+    CXXTemporariesCleanupScope &operator=(const CXXTemporariesCleanupScope &);
+    
+  public:
+    explicit CXXTemporariesCleanupScope(CodeGenFunction &CGF)
+      : CGF(CGF), NumLiveTemporaries(CGF.LiveTemporaries.size()) { }
+    
+    ~CXXTemporariesCleanupScope() {
+      while (CGF.LiveTemporaries.size() > NumLiveTemporaries)
+        CGF.PopCXXTemporary();
+    }
+  };
+
+
+  /// EmitCleanupBlocks - Takes the old cleanup stack size and emits the cleanup
+  /// blocks that have been added.
+  void EmitCleanupBlocks(size_t OldCleanupStackSize);
+
+  /// EmitBranchThroughCleanup - Emit a branch from the current insert block
+  /// through the cleanup handling code (if any) and then on to \arg Dest.
+  ///
+  /// FIXME: Maybe this should really be in EmitBranch? Don't we always want
+  /// this behavior for branches?
+  void EmitBranchThroughCleanup(llvm::BasicBlock *Dest);
+
+  /// BeginConditionalBranch - Should be called before a conditional part of an
+  /// expression is emitted. For example, before the RHS of the expression below
+  /// is emitted:
+  ///
+  /// b && f(T());
+  ///
+  /// This is used to make sure that any temporaries created in the conditional
+  /// branch are only destroyed if the branch is taken.
+  void BeginConditionalBranch() {
+    ++ConditionalBranchLevel;
+  }
+
+  /// EndConditionalBranch - Should be called after a conditional part of an
+  /// expression has been emitted.
+  void EndConditionalBranch() {
+    assert(ConditionalBranchLevel != 0 &&
+           "Conditional branch mismatch!");
+    
+    --ConditionalBranchLevel;
+  }
+
+private:
+  CGDebugInfo *DebugInfo;
+
+  /// IndirectBranch - The first time an indirect goto is seen we create a block
+  /// with an indirect branch.  Every time we see the address of a label taken,
+  /// we add the label to the indirect goto.  Every subsequent indirect goto is
+  /// codegen'd as a jump to the IndirectBranch's basic block.
+  llvm::IndirectBrInst *IndirectBranch;
+
+  /// LocalDeclMap - This keeps track of the LLVM allocas or globals for local C
+  /// decls.
+  llvm::DenseMap<const Decl*, llvm::Value*> LocalDeclMap;
+
+  /// LabelMap - This keeps track of the LLVM basic block for each C label.
+  llvm::DenseMap<const LabelStmt*, llvm::BasicBlock*> LabelMap;
+
+  // BreakContinueStack - This keeps track of where break and continue
+  // statements should jump to.
+  struct BreakContinue {
+    BreakContinue(llvm::BasicBlock *bb, llvm::BasicBlock *cb)
+      : BreakBlock(bb), ContinueBlock(cb) {}
+
+    llvm::BasicBlock *BreakBlock;
+    llvm::BasicBlock *ContinueBlock;
+  };
+  llvm::SmallVector<BreakContinue, 8> BreakContinueStack;
+
+  /// SwitchInsn - This is nearest current switch instruction. It is null if if
+  /// current context is not in a switch.
+  llvm::SwitchInst *SwitchInsn;
+
+  /// CaseRangeBlock - This block holds if condition check for last case
+  /// statement range in current switch instruction.
+  llvm::BasicBlock *CaseRangeBlock;
+
+  /// InvokeDest - This is the nearest exception target for calls
+  /// which can unwind, when exceptions are being used.
+  llvm::BasicBlock *InvokeDest;
+
+  // VLASizeMap - This keeps track of the associated size for each VLA type.
+  // We track this by the size expression rather than the type itself because
+  // in certain situations, like a const qualifier applied to an VLA typedef,
+  // multiple VLA types can share the same size expression.
+  // FIXME: Maybe this could be a stack of maps that is pushed/popped as we
+  // enter/leave scopes.
+  llvm::DenseMap<const Expr*, llvm::Value*> VLASizeMap;
+
+  /// DidCallStackSave - Whether llvm.stacksave has been called. Used to avoid
+  /// calling llvm.stacksave for multiple VLAs in the same scope.
+  bool DidCallStackSave;
+
+  struct CleanupEntry {
+    /// CleanupEntryBlock - The block of code that does the actual cleanup.
+    llvm::BasicBlock *CleanupEntryBlock;
+
+    /// CleanupExitBlock - The cleanup exit block.
+    llvm::BasicBlock *CleanupExitBlock;
+    
+    /// Blocks - Basic blocks that were emitted in the current cleanup scope.
+    std::vector<llvm::BasicBlock *> Blocks;
+
+    /// BranchFixups - Branch instructions to basic blocks that haven't been
+    /// inserted into the current function yet.
+    std::vector<llvm::BranchInst *> BranchFixups;
+
+    /// PreviousInvokeDest - The invoke handler from the start of the cleanup
+    /// region.
+    llvm::BasicBlock *PreviousInvokeDest;
+
+    /// EHOnly - Perform this only on the exceptional edge, not the main edge.
+    bool EHOnly;
+
+    explicit CleanupEntry(llvm::BasicBlock *CleanupEntryBlock,
+                          llvm::BasicBlock *CleanupExitBlock,
+                          llvm::BasicBlock *PreviousInvokeDest,
+                          bool ehonly)
+      : CleanupEntryBlock(CleanupEntryBlock),
+        CleanupExitBlock(CleanupExitBlock),
+        PreviousInvokeDest(PreviousInvokeDest),
+        EHOnly(ehonly) {}
+  };
+
+  /// CleanupEntries - Stack of cleanup entries.
+  llvm::SmallVector<CleanupEntry, 8> CleanupEntries;
+
+  typedef llvm::DenseMap<llvm::BasicBlock*, size_t> BlockScopeMap;
+
+  /// BlockScopes - Map of which "cleanup scope" scope basic blocks have.
+  BlockScopeMap BlockScopes;
+
+  /// CXXThisDecl - When generating code for a C++ member function,
+  /// this will hold the implicit 'this' declaration.
+  ImplicitParamDecl *CXXThisDecl;
+  llvm::Value *CXXThisValue;
+
+  /// CXXVTTDecl - When generating code for a base object constructor or
+  /// base object destructor with virtual bases, this will hold the implicit
+  /// VTT parameter.
+  ImplicitParamDecl *CXXVTTDecl;
+  llvm::Value *CXXVTTValue;
+  
+  /// CXXLiveTemporaryInfo - Holds information about a live C++ temporary.
+  struct CXXLiveTemporaryInfo {
+    /// Temporary - The live temporary.
+    const CXXTemporary *Temporary;
+
+    /// ThisPtr - The pointer to the temporary.
+    llvm::Value *ThisPtr;
+
+    /// DtorBlock - The destructor block.
+    llvm::BasicBlock *DtorBlock;
+
+    /// CondPtr - If this is a conditional temporary, this is the pointer to the
+    /// condition variable that states whether the destructor should be called
+    /// or not.
+    llvm::Value *CondPtr;
+
+    CXXLiveTemporaryInfo(const CXXTemporary *temporary,
+                         llvm::Value *thisptr, llvm::BasicBlock *dtorblock,
+                         llvm::Value *condptr)
+      : Temporary(temporary), ThisPtr(thisptr), DtorBlock(dtorblock),
+      CondPtr(condptr) { }
+  };
+
+  llvm::SmallVector<CXXLiveTemporaryInfo, 4> LiveTemporaries;
+
+  /// ConditionalBranchLevel - Contains the nesting level of the current
+  /// conditional branch. This is used so that we know if a temporary should be
+  /// destroyed conditionally.
+  unsigned ConditionalBranchLevel;
+
+
+  /// ByrefValueInfoMap - For each __block variable, contains a pair of the LLVM
+  /// type as well as the field number that contains the actual data.
+  llvm::DenseMap<const ValueDecl *, std::pair<const llvm::Type *, 
+                                              unsigned> > ByRefValueInfo;
+  
+  /// getByrefValueFieldNumber - Given a declaration, returns the LLVM field
+  /// number that holds the value.
+  unsigned getByRefValueLLVMField(const ValueDecl *VD) const;
+
+  llvm::BasicBlock *TerminateHandler;
+  llvm::BasicBlock *TrapBB;
+
+  int UniqueAggrDestructorCount;
+public:
+  CodeGenFunction(CodeGenModule &cgm);
+
+  ASTContext &getContext() const;
+  CGDebugInfo *getDebugInfo() { return DebugInfo; }
+
+  llvm::BasicBlock *getInvokeDest() { return InvokeDest; }
+  void setInvokeDest(llvm::BasicBlock *B) { InvokeDest = B; }
+
+  llvm::LLVMContext &getLLVMContext() { return VMContext; }
+
+  //===--------------------------------------------------------------------===//
+  //                                  Objective-C
+  //===--------------------------------------------------------------------===//
+
+  void GenerateObjCMethod(const ObjCMethodDecl *OMD);
+
+  void StartObjCMethod(const ObjCMethodDecl *MD,
+                       const ObjCContainerDecl *CD);
+
+  /// GenerateObjCGetter - Synthesize an Objective-C property getter function.
+  void GenerateObjCGetter(ObjCImplementationDecl *IMP,
+                          const ObjCPropertyImplDecl *PID);
+
+  /// GenerateObjCSetter - Synthesize an Objective-C property setter function
+  /// for the given property.
+  void GenerateObjCSetter(ObjCImplementationDecl *IMP,
+                          const ObjCPropertyImplDecl *PID);
+  bool IndirectObjCSetterArg(const CGFunctionInfo &FI);
+  bool IvarTypeWithAggrGCObjects(QualType Ty);
+
+  //===--------------------------------------------------------------------===//
+  //                                  Block Bits
+  //===--------------------------------------------------------------------===//
+
+  llvm::Value *BuildBlockLiteralTmp(const BlockExpr *);
+  llvm::Constant *BuildDescriptorBlockDecl(const BlockExpr *,
+                                           bool BlockHasCopyDispose,
+                                           CharUnits Size,
+                                           const llvm::StructType *,
+                                           std::vector<HelperInfo> *);
+
+  llvm::Function *GenerateBlockFunction(const BlockExpr *BExpr,
+                                        const BlockInfo& Info,
+                                        const Decl *OuterFuncDecl,
+                                  llvm::DenseMap<const Decl*, llvm::Value*> ldm,
+                                        CharUnits &Size, CharUnits &Align,
+                      llvm::SmallVector<const Expr *, 8> &subBlockDeclRefDecls,
+                                        bool &subBlockHasCopyDispose);
+
+  void BlockForwardSelf();
+  llvm::Value *LoadBlockStruct();
+
+  CharUnits AllocateBlockDecl(const BlockDeclRefExpr *E);
+  llvm::Value *GetAddrOfBlockDecl(const BlockDeclRefExpr *E);
+  const llvm::Type *BuildByRefType(const ValueDecl *D);
+
+  void GenerateCode(GlobalDecl GD, llvm::Function *Fn);
+  void StartFunction(GlobalDecl GD, QualType RetTy,
+                     llvm::Function *Fn,
+                     const FunctionArgList &Args,
+                     SourceLocation StartLoc);
+
+  void EmitConstructorBody(FunctionArgList &Args);
+  void EmitDestructorBody(FunctionArgList &Args);
+  void EmitFunctionBody(FunctionArgList &Args);
+
+  /// EmitReturnBlock - Emit the unified return block, trying to avoid its
+  /// emission when possible.
+  void EmitReturnBlock();
+
+  /// FinishFunction - Complete IR generation of the current function. It is
+  /// legal to call this function even if there is no current insertion point.
+  void FinishFunction(SourceLocation EndLoc=SourceLocation());
+
+  /// GenerateThunk - Generate a thunk for the given method.
+  void GenerateThunk(llvm::Function *Fn, GlobalDecl GD, const ThunkInfo &Thunk);
+  
+  void EmitCtorPrologue(const CXXConstructorDecl *CD, CXXCtorType Type);
+
+  /// InitializeVTablePointer - Initialize the vtable pointer of the given
+  /// subobject.
+  ///
+  void InitializeVTablePointer(BaseSubobject Base, 
+                               const CXXRecordDecl *NearestVBase,
+                               llvm::Constant *VTable,
+                               const CXXRecordDecl *VTableClass);
+
+  typedef llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBasesSetTy;
+  void InitializeVTablePointers(BaseSubobject Base, 
+                                const CXXRecordDecl *NearestVBase,
+                                bool BaseIsNonVirtualPrimaryBase,
+                                llvm::Constant *VTable,
+                                const CXXRecordDecl *VTableClass,
+                                VisitedVirtualBasesSetTy& VBases);
+
+  void InitializeVTablePointers(const CXXRecordDecl *ClassDecl);
+
+
+  void SynthesizeCXXCopyConstructor(const FunctionArgList &Args);
+  void SynthesizeCXXCopyAssignment(const FunctionArgList &Args);
+
+  /// EmitDtorEpilogue - Emit all code that comes at the end of class's
+  /// destructor. This is to call destructors on members and base classes in
+  /// reverse order of their construction.
+  void EmitDtorEpilogue(const CXXDestructorDecl *Dtor,
+                        CXXDtorType Type);
+
+  /// EmitFunctionProlog - Emit the target specific LLVM code to load the
+  /// arguments for the given function. This is also responsible for naming the
+  /// LLVM function arguments.
+  void EmitFunctionProlog(const CGFunctionInfo &FI,
+                          llvm::Function *Fn,
+                          const FunctionArgList &Args);
+
+  /// EmitFunctionEpilog - Emit the target specific LLVM code to return the
+  /// given temporary.
+  void EmitFunctionEpilog(const CGFunctionInfo &FI, llvm::Value *ReturnValue);
+
+  /// EmitStartEHSpec - Emit the start of the exception spec.
+  void EmitStartEHSpec(const Decl *D);
+
+  /// EmitEndEHSpec - Emit the end of the exception spec.
+  void EmitEndEHSpec(const Decl *D);
+
+  /// getTerminateHandler - Return a handler that just calls terminate.
+  llvm::BasicBlock *getTerminateHandler();
+
+  const llvm::Type *ConvertTypeForMem(QualType T);
+  const llvm::Type *ConvertType(QualType T);
+  const llvm::Type *ConvertType(const TypeDecl *T) {
+    return ConvertType(getContext().getTypeDeclType(T));
+  }
+
+  /// LoadObjCSelf - Load the value of self. This function is only valid while
+  /// generating code for an Objective-C method.
+  llvm::Value *LoadObjCSelf();
+
+  /// TypeOfSelfObject - Return type of object that this self represents.
+  QualType TypeOfSelfObject();
+
+  /// hasAggregateLLVMType - Return true if the specified AST type will map into
+  /// an aggregate LLVM type or is void.
+  static bool hasAggregateLLVMType(QualType T);
+
+  /// createBasicBlock - Create an LLVM basic block.
+  llvm::BasicBlock *createBasicBlock(const char *Name="",
+                                     llvm::Function *Parent=0,
+                                     llvm::BasicBlock *InsertBefore=0) {
+#ifdef NDEBUG
+    return llvm::BasicBlock::Create(VMContext, "", Parent, InsertBefore);
+#else
+    return llvm::BasicBlock::Create(VMContext, Name, Parent, InsertBefore);
+#endif
+  }
+
+  /// getBasicBlockForLabel - Return the LLVM basicblock that the specified
+  /// label maps to.
+  llvm::BasicBlock *getBasicBlockForLabel(const LabelStmt *S);
+
+  /// SimplifyForwardingBlocks - If the given basic block is only a branch to
+  /// another basic block, simplify it. This assumes that no other code could
+  /// potentially reference the basic block.
+  void SimplifyForwardingBlocks(llvm::BasicBlock *BB);
+
+  /// EmitBlock - Emit the given block \arg BB and set it as the insert point,
+  /// adding a fall-through branch from the current insert block if
+  /// necessary. It is legal to call this function even if there is no current
+  /// insertion point.
+  ///
+  /// IsFinished - If true, indicates that the caller has finished emitting
+  /// branches to the given block and does not expect to emit code into it. This
+  /// means the block can be ignored if it is unreachable.
+  void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false);
+
+  /// EmitBranch - Emit a branch to the specified basic block from the current
+  /// insert block, taking care to avoid creation of branches from dummy
+  /// blocks. It is legal to call this function even if there is no current
+  /// insertion point.
+  ///
+  /// This function clears the current insertion point. The caller should follow
+  /// calls to this function with calls to Emit*Block prior to generation new
+  /// code.
+  void EmitBranch(llvm::BasicBlock *Block);
+
+  /// HaveInsertPoint - True if an insertion point is defined. If not, this
+  /// indicates that the current code being emitted is unreachable.
+  bool HaveInsertPoint() const {
+    return Builder.GetInsertBlock() != 0;
+  }
+
+  /// EnsureInsertPoint - Ensure that an insertion point is defined so that
+  /// emitted IR has a place to go. Note that by definition, if this function
+  /// creates a block then that block is unreachable; callers may do better to
+  /// detect when no insertion point is defined and simply skip IR generation.
+  void EnsureInsertPoint() {
+    if (!HaveInsertPoint())
+      EmitBlock(createBasicBlock());
+  }
+
+  /// ErrorUnsupported - Print out an error that codegen doesn't support the
+  /// specified stmt yet.
+  void ErrorUnsupported(const Stmt *S, const char *Type,
+                        bool OmitOnError=false);
+
+  //===--------------------------------------------------------------------===//
+  //                                  Helpers
+  //===--------------------------------------------------------------------===//
+
+  Qualifiers MakeQualifiers(QualType T) {
+    Qualifiers Quals = getContext().getCanonicalType(T).getQualifiers();
+    Quals.setObjCGCAttr(getContext().getObjCGCAttrKind(T));
+    return Quals;
+  }
+
+  /// CreateTempAlloca - This creates a alloca and inserts it into the entry
+  /// block. The caller is responsible for setting an appropriate alignment on
+  /// the alloca.
+  llvm::AllocaInst *CreateTempAlloca(const llvm::Type *Ty,
+                                     const llvm::Twine &Name = "tmp");
+
+  /// InitTempAlloca - Provide an initial value for the given alloca.
+  void InitTempAlloca(llvm::AllocaInst *Alloca, llvm::Value *Value);
+
+  /// CreateIRTemp - Create a temporary IR object of the given type, with
+  /// appropriate alignment. This routine should only be used when an temporary
+  /// value needs to be stored into an alloca (for example, to avoid explicit
+  /// PHI construction), but the type is the IR type, not the type appropriate
+  /// for storing in memory.
+  llvm::Value *CreateIRTemp(QualType T, const llvm::Twine &Name = "tmp");
+
+  /// CreateMemTemp - Create a temporary memory object of the given type, with
+  /// appropriate alignment.
+  llvm::Value *CreateMemTemp(QualType T, const llvm::Twine &Name = "tmp");
+
+  /// EvaluateExprAsBool - Perform the usual unary conversions on the specified
+  /// expression and compare the result against zero, returning an Int1Ty value.
+  llvm::Value *EvaluateExprAsBool(const Expr *E);
+
+  /// EmitAnyExpr - Emit code to compute the specified expression which can have
+  /// any type.  The result is returned as an RValue struct.  If this is an
+  /// aggregate expression, the aggloc/agglocvolatile arguments indicate where
+  /// the result should be returned.
+  ///
+  /// \param IgnoreResult - True if the resulting value isn't used.
+  RValue EmitAnyExpr(const Expr *E, llvm::Value *AggLoc = 0,
+                     bool IsAggLocVolatile = false, bool IgnoreResult = false,
+                     bool IsInitializer = false);
+
+  // EmitVAListRef - Emit a "reference" to a va_list; this is either the address
+  // or the value of the expression, depending on how va_list is defined.
+  llvm::Value *EmitVAListRef(const Expr *E);
+
+  /// EmitAnyExprToTemp - Similary to EmitAnyExpr(), however, the result will
+  /// always be accessible even if no aggregate location is provided.
+  RValue EmitAnyExprToTemp(const Expr *E, bool IsAggLocVolatile = false,
+                           bool IsInitializer = false);
+
+  /// EmitsAnyExprToMem - Emits the code necessary to evaluate an
+  /// arbitrary expression into the given memory location.
+  void EmitAnyExprToMem(const Expr *E, llvm::Value *Location,
+                        bool IsLocationVolatile = false,
+                        bool IsInitializer = false);
+
+  /// EmitAggregateCopy - Emit an aggrate copy.
+  ///
+  /// \param isVolatile - True iff either the source or the destination is
+  /// volatile.
+  void EmitAggregateCopy(llvm::Value *DestPtr, llvm::Value *SrcPtr,
+                         QualType EltTy, bool isVolatile=false);
+
+  void EmitAggregateClear(llvm::Value *DestPtr, QualType Ty);
+
+  /// StartBlock - Start new block named N. If insert block is a dummy block
+  /// then reuse it.
+  void StartBlock(const char *N);
+
+  /// GetAddrOfStaticLocalVar - Return the address of a static local variable.
+  llvm::Constant *GetAddrOfStaticLocalVar(const VarDecl *BVD);
+
+  /// GetAddrOfLocalVar - Return the address of a local variable.
+  llvm::Value *GetAddrOfLocalVar(const VarDecl *VD);
+
+  /// getAccessedFieldNo - Given an encoded value and a result number, return
+  /// the input field number being accessed.
+  static unsigned getAccessedFieldNo(unsigned Idx, const llvm::Constant *Elts);
+
+  llvm::BlockAddress *GetAddrOfLabel(const LabelStmt *L);
+  llvm::BasicBlock *GetIndirectGotoBlock();
+
+  /// EmitMemSetToZero - Generate code to memset a value of the given type to 0.
+  void EmitMemSetToZero(llvm::Value *DestPtr, QualType Ty);
+
+  // EmitVAArg - Generate code to get an argument from the passed in pointer
+  // and update it accordingly. The return value is a pointer to the argument.
+  // FIXME: We should be able to get rid of this method and use the va_arg
+  // instruction in LLVM instead once it works well enough.
+  llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty);
+
+  /// EmitVLASize - Generate code for any VLA size expressions that might occur
+  /// in a variably modified type. If Ty is a VLA, will return the value that
+  /// corresponds to the size in bytes of the VLA type. Will return 0 otherwise.
+  ///
+  /// This function can be called with a null (unreachable) insert point.
+  llvm::Value *EmitVLASize(QualType Ty);
+
+  // GetVLASize - Returns an LLVM value that corresponds to the size in bytes
+  // of a variable length array type.
+  llvm::Value *GetVLASize(const VariableArrayType *);
+
+  /// LoadCXXThis - Load the value of 'this'. This function is only valid while
+  /// generating code for an C++ member function.
+  llvm::Value *LoadCXXThis() {
+    assert(CXXThisValue && "no 'this' value for this function");
+    return CXXThisValue;
+  }
+
+  /// LoadCXXVTT - Load the VTT parameter to base constructors/destructors have
+  /// virtual bases.
+  llvm::Value *LoadCXXVTT() {
+    assert(CXXVTTValue && "no VTT value for this function");
+    return CXXVTTValue;
+  }
+
+  /// GetAddressOfBaseOfCompleteClass - Convert the given pointer to a
+  /// complete class to the given direct base.
+  llvm::Value *
+  GetAddressOfDirectBaseInCompleteClass(llvm::Value *Value,
+                                        const CXXRecordDecl *Derived,
+                                        const CXXRecordDecl *Base,
+                                        bool BaseIsVirtual);
+
+  llvm::Value *OldGetAddressOfBaseClass(llvm::Value *Value,
+                                        const CXXRecordDecl *ClassDecl,
+                                        const CXXRecordDecl *BaseClassDecl);
+
+  /// GetAddressOfBaseClass - This function will add the necessary delta to the
+  /// load of 'this' and returns address of the base class.
+  llvm::Value *GetAddressOfBaseClass(llvm::Value *Value, 
+                                     const CXXRecordDecl *Derived,
+                                     const CXXBaseSpecifierArray &BasePath, 
+                                     bool NullCheckValue);
+
+  llvm::Value *GetAddressOfDerivedClass(llvm::Value *Value,
+                                        const CXXRecordDecl *Derived,
+                                        const CXXBaseSpecifierArray &BasePath,
+                                        bool NullCheckValue);
+
+  llvm::Value *GetVirtualBaseClassOffset(llvm::Value *This,
+                                         const CXXRecordDecl *ClassDecl,
+                                         const CXXRecordDecl *BaseClassDecl);
+    
+  void EmitClassAggrMemberwiseCopy(llvm::Value *DestValue,
+                                   llvm::Value *SrcValue,
+                                   const ArrayType *Array,
+                                   const CXXRecordDecl *BaseClassDecl,
+                                   QualType Ty);
+
+  void EmitClassAggrCopyAssignment(llvm::Value *DestValue,
+                                   llvm::Value *SrcValue,
+                                   const ArrayType *Array,
+                                   const CXXRecordDecl *BaseClassDecl,
+                                   QualType Ty);
+
+  void EmitClassMemberwiseCopy(llvm::Value *DestValue, llvm::Value *SrcValue,
+                               const CXXRecordDecl *ClassDecl,
+                               const CXXRecordDecl *BaseClassDecl,
+                               QualType Ty);
+
+  void EmitClassCopyAssignment(llvm::Value *DestValue, llvm::Value *SrcValue,
+                               const CXXRecordDecl *ClassDecl,
+                               const CXXRecordDecl *BaseClassDecl,
+                               QualType Ty);
+
+  void EmitDelegateCXXConstructorCall(const CXXConstructorDecl *Ctor,
+                                      CXXCtorType CtorType,
+                                      const FunctionArgList &Args);
+  void EmitCXXConstructorCall(const CXXConstructorDecl *D, CXXCtorType Type,
+                              llvm::Value *This,
+                              CallExpr::const_arg_iterator ArgBeg,
+                              CallExpr::const_arg_iterator ArgEnd);
+
+  void EmitCXXAggrConstructorCall(const CXXConstructorDecl *D,
+                                  const ConstantArrayType *ArrayTy,
+                                  llvm::Value *ArrayPtr,
+                                  CallExpr::const_arg_iterator ArgBeg,
+                                  CallExpr::const_arg_iterator ArgEnd);
+  
+  void EmitCXXAggrConstructorCall(const CXXConstructorDecl *D,
+                                  llvm::Value *NumElements,
+                                  llvm::Value *ArrayPtr,
+                                  CallExpr::const_arg_iterator ArgBeg,
+                                  CallExpr::const_arg_iterator ArgEnd);
+
+  void EmitCXXAggrDestructorCall(const CXXDestructorDecl *D,
+                                 const ArrayType *Array,
+                                 llvm::Value *This);
+
+  void EmitCXXAggrDestructorCall(const CXXDestructorDecl *D,
+                                 llvm::Value *NumElements,
+                                 llvm::Value *This);
+
+  llvm::Constant *GenerateCXXAggrDestructorHelper(const CXXDestructorDecl *D,
+                                                const ArrayType *Array,
+                                                llvm::Value *This);
+
+  void EmitCXXDestructorCall(const CXXDestructorDecl *D, CXXDtorType Type,
+                             llvm::Value *This);
+
+  void PushCXXTemporary(const CXXTemporary *Temporary, llvm::Value *Ptr);
+  void PopCXXTemporary();
+
+  llvm::Value *EmitCXXNewExpr(const CXXNewExpr *E);
+  void EmitCXXDeleteExpr(const CXXDeleteExpr *E);
+
+  void EmitDeleteCall(const FunctionDecl *DeleteFD, llvm::Value *Ptr,
+                      QualType DeleteTy);
+
+  llvm::Value* EmitCXXTypeidExpr(const CXXTypeidExpr *E);
+  llvm::Value *EmitDynamicCast(llvm::Value *V, const CXXDynamicCastExpr *DCE);
+
+  void EmitCheck(llvm::Value *, unsigned Size);
+
+  llvm::Value *EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
+                                       bool isInc, bool isPre);
+  ComplexPairTy EmitComplexPrePostIncDec(const UnaryOperator *E, LValue LV,
+                                         bool isInc, bool isPre);
+  //===--------------------------------------------------------------------===//
+  //                            Declaration Emission
+  //===--------------------------------------------------------------------===//
+
+  /// EmitDecl - Emit a declaration.
+  ///
+  /// This function can be called with a null (unreachable) insert point.
+  void EmitDecl(const Decl &D);
+
+  /// EmitBlockVarDecl - Emit a block variable declaration.
+  ///
+  /// This function can be called with a null (unreachable) insert point.
+  void EmitBlockVarDecl(const VarDecl &D);
+
+  /// EmitLocalBlockVarDecl - Emit a local block variable declaration.
+  ///
+  /// This function can be called with a null (unreachable) insert point.
+  void EmitLocalBlockVarDecl(const VarDecl &D);
+
+  void EmitStaticBlockVarDecl(const VarDecl &D,
+                              llvm::GlobalValue::LinkageTypes Linkage);
+
+  /// EmitParmDecl - Emit a ParmVarDecl or an ImplicitParamDecl.
+  void EmitParmDecl(const VarDecl &D, llvm::Value *Arg);
+
+  //===--------------------------------------------------------------------===//
+  //                             Statement Emission
+  //===--------------------------------------------------------------------===//
+
+  /// EmitStopPoint - Emit a debug stoppoint if we are emitting debug info.
+  void EmitStopPoint(const Stmt *S);
+
+  /// EmitStmt - Emit the code for the statement \arg S. It is legal to call
+  /// this function even if there is no current insertion point.
+  ///
+  /// This function may clear the current insertion point; callers should use
+  /// EnsureInsertPoint if they wish to subsequently generate code without first
+  /// calling EmitBlock, EmitBranch, or EmitStmt.
+  void EmitStmt(const Stmt *S);
+
+  /// EmitSimpleStmt - Try to emit a "simple" statement which does not
+  /// necessarily require an insertion point or debug information; typically
+  /// because the statement amounts to a jump or a container of other
+  /// statements.
+  ///
+  /// \return True if the statement was handled.
+  bool EmitSimpleStmt(const Stmt *S);
+
+  RValue EmitCompoundStmt(const CompoundStmt &S, bool GetLast = false,
+                          llvm::Value *AggLoc = 0, bool isAggVol = false);
+
+  /// EmitLabel - Emit the block for the given label. It is legal to call this
+  /// function even if there is no current insertion point.
+  void EmitLabel(const LabelStmt &S); // helper for EmitLabelStmt.
+
+  void EmitLabelStmt(const LabelStmt &S);
+  void EmitGotoStmt(const GotoStmt &S);
+  void EmitIndirectGotoStmt(const IndirectGotoStmt &S);
+  void EmitIfStmt(const IfStmt &S);
+  void EmitWhileStmt(const WhileStmt &S);
+  void EmitDoStmt(const DoStmt &S);
+  void EmitForStmt(const ForStmt &S);
+  void EmitReturnStmt(const ReturnStmt &S);
+  void EmitDeclStmt(const DeclStmt &S);
+  void EmitBreakStmt(const BreakStmt &S);
+  void EmitContinueStmt(const ContinueStmt &S);
+  void EmitSwitchStmt(const SwitchStmt &S);
+  void EmitDefaultStmt(const DefaultStmt &S);
+  void EmitCaseStmt(const CaseStmt &S);
+  void EmitCaseStmtRange(const CaseStmt &S);
+  void EmitAsmStmt(const AsmStmt &S);
+
+  void EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S);
+  void EmitObjCAtTryStmt(const ObjCAtTryStmt &S);
+  void EmitObjCAtThrowStmt(const ObjCAtThrowStmt &S);
+  void EmitObjCAtSynchronizedStmt(const ObjCAtSynchronizedStmt &S);
+
+  struct CXXTryStmtInfo {
+    llvm::BasicBlock *SavedLandingPad;
+    llvm::BasicBlock *HandlerBlock;
+    llvm::BasicBlock *FinallyBlock;
+  };
+  CXXTryStmtInfo EnterCXXTryStmt(const CXXTryStmt &S);
+  void ExitCXXTryStmt(const CXXTryStmt &S, CXXTryStmtInfo Info);
+
+  void EmitCXXTryStmt(const CXXTryStmt &S);
+  
+  //===--------------------------------------------------------------------===//
+  //                         LValue Expression Emission
+  //===--------------------------------------------------------------------===//
+
+  /// GetUndefRValue - Get an appropriate 'undef' rvalue for the given type.
+  RValue GetUndefRValue(QualType Ty);
+
+  /// EmitUnsupportedRValue - Emit a dummy r-value using the type of E
+  /// and issue an ErrorUnsupported style diagnostic (using the
+  /// provided Name).
+  RValue EmitUnsupportedRValue(const Expr *E,
+                               const char *Name);
+
+  /// EmitUnsupportedLValue - Emit a dummy l-value using the type of E and issue
+  /// an ErrorUnsupported style diagnostic (using the provided Name).
+  LValue EmitUnsupportedLValue(const Expr *E,
+                               const char *Name);
+
+  /// EmitLValue - Emit code to compute a designator that specifies the location
+  /// of the expression.
+  ///
+  /// This can return one of two things: a simple address or a bitfield
+  /// reference.  In either case, the LLVM Value* in the LValue structure is
+  /// guaranteed to be an LLVM pointer type.
+  ///
+  /// If this returns a bitfield reference, nothing about the pointee type of
+  /// the LLVM value is known: For example, it may not be a pointer to an
+  /// integer.
+  ///
+  /// If this returns a normal address, and if the lvalue's C type is fixed
+  /// size, this method guarantees that the returned pointer type will point to
+  /// an LLVM type of the same size of the lvalue's type.  If the lvalue has a
+  /// variable length type, this is not possible.
+  ///
+  LValue EmitLValue(const Expr *E);
+
+  /// EmitCheckedLValue - Same as EmitLValue but additionally we generate
+  /// checking code to guard against undefined behavior.  This is only
+  /// suitable when we know that the address will be used to access the
+  /// object.
+  LValue EmitCheckedLValue(const Expr *E);
+
+  /// EmitLoadOfScalar - Load a scalar value from an address, taking
+  /// care to appropriately convert from the memory representation to
+  /// the LLVM value representation.
+  llvm::Value *EmitLoadOfScalar(llvm::Value *Addr, bool Volatile,
+                                QualType Ty);
+
+  /// EmitStoreOfScalar - Store a scalar value to an address, taking
+  /// care to appropriately convert from the memory representation to
+  /// the LLVM value representation.
+  void EmitStoreOfScalar(llvm::Value *Value, llvm::Value *Addr,
+                         bool Volatile, QualType Ty);
+
+  /// EmitLoadOfLValue - Given an expression that represents a value lvalue,
+  /// this method emits the address of the lvalue, then loads the result as an
+  /// rvalue, returning the rvalue.
+  RValue EmitLoadOfLValue(LValue V, QualType LVType);
+  RValue EmitLoadOfExtVectorElementLValue(LValue V, QualType LVType);
+  RValue EmitLoadOfBitfieldLValue(LValue LV, QualType ExprType);
+  RValue EmitLoadOfPropertyRefLValue(LValue LV, QualType ExprType);
+  RValue EmitLoadOfKVCRefLValue(LValue LV, QualType ExprType);
+
+
+  /// EmitStoreThroughLValue - Store the specified rvalue into the specified
+  /// lvalue, where both are guaranteed to the have the same type, and that type
+  /// is 'Ty'.
+  void EmitStoreThroughLValue(RValue Src, LValue Dst, QualType Ty);
+  void EmitStoreThroughExtVectorComponentLValue(RValue Src, LValue Dst,
+                                                QualType Ty);
+  void EmitStoreThroughPropertyRefLValue(RValue Src, LValue Dst, QualType Ty);
+  void EmitStoreThroughKVCRefLValue(RValue Src, LValue Dst, QualType Ty);
+
+  /// EmitStoreThroughLValue - Store Src into Dst with same constraints as
+  /// EmitStoreThroughLValue.
+  ///
+  /// \param Result [out] - If non-null, this will be set to a Value* for the
+  /// bit-field contents after the store, appropriate for use as the result of
+  /// an assignment to the bit-field.
+  void EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst, QualType Ty,
+                                      llvm::Value **Result=0);
+
+  // Note: only availabe for agg return types
+  LValue EmitBinaryOperatorLValue(const BinaryOperator *E);
+  LValue EmitCompoundAssignOperatorLValue(const CompoundAssignOperator *E);
+  // Note: only available for agg return types
+  LValue EmitCallExprLValue(const CallExpr *E);
+  // Note: only available for agg return types
+  LValue EmitVAArgExprLValue(const VAArgExpr *E);
+  LValue EmitDeclRefLValue(const DeclRefExpr *E);
+  LValue EmitStringLiteralLValue(const StringLiteral *E);
+  LValue EmitObjCEncodeExprLValue(const ObjCEncodeExpr *E);
+  LValue EmitPredefinedFunctionName(unsigned Type);
+  LValue EmitPredefinedLValue(const PredefinedExpr *E);
+  LValue EmitUnaryOpLValue(const UnaryOperator *E);
+  LValue EmitArraySubscriptExpr(const ArraySubscriptExpr *E);
+  LValue EmitExtVectorElementExpr(const ExtVectorElementExpr *E);
+  LValue EmitMemberExpr(const MemberExpr *E);
+  LValue EmitObjCIsaExpr(const ObjCIsaExpr *E);
+  LValue EmitCompoundLiteralLValue(const CompoundLiteralExpr *E);
+  LValue EmitConditionalOperatorLValue(const ConditionalOperator *E);
+  LValue EmitCastLValue(const CastExpr *E);
+  LValue EmitNullInitializationLValue(const CXXZeroInitValueExpr *E);
+  
+  llvm::Value *EmitIvarOffset(const ObjCInterfaceDecl *Interface,
+                              const ObjCIvarDecl *Ivar);
+  LValue EmitLValueForField(llvm::Value* Base, const FieldDecl* Field,
+                            unsigned CVRQualifiers);
+  
+  /// EmitLValueForFieldInitialization - Like EmitLValueForField, except that
+  /// if the Field is a reference, this will return the address of the reference
+  /// and not the address of the value stored in the reference.
+  LValue EmitLValueForFieldInitialization(llvm::Value* Base, 
+                                          const FieldDecl* Field,
+                                          unsigned CVRQualifiers);
+  
+  LValue EmitLValueForIvar(QualType ObjectTy,
+                           llvm::Value* Base, const ObjCIvarDecl *Ivar,
+                           unsigned CVRQualifiers);
+
+  LValue EmitLValueForBitfield(llvm::Value* Base, const FieldDecl* Field,
+                                unsigned CVRQualifiers);
+
+  LValue EmitBlockDeclRefLValue(const BlockDeclRefExpr *E);
+
+  LValue EmitCXXConstructLValue(const CXXConstructExpr *E);
+  LValue EmitCXXBindTemporaryLValue(const CXXBindTemporaryExpr *E);
+  LValue EmitCXXExprWithTemporariesLValue(const CXXExprWithTemporaries *E);
+  LValue EmitCXXTypeidLValue(const CXXTypeidExpr *E);
+  
+  LValue EmitObjCMessageExprLValue(const ObjCMessageExpr *E);
+  LValue EmitObjCIvarRefLValue(const ObjCIvarRefExpr *E);
+  LValue EmitObjCPropertyRefLValue(const ObjCPropertyRefExpr *E);
+  LValue EmitObjCKVCRefLValue(const ObjCImplicitSetterGetterRefExpr *E);
+  LValue EmitObjCSuperExprLValue(const ObjCSuperExpr *E);
+  LValue EmitStmtExprLValue(const StmtExpr *E);
+  LValue EmitPointerToDataMemberBinaryExpr(const BinaryOperator *E);
+  
+  //===--------------------------------------------------------------------===//
+  //                         Scalar Expression Emission
+  //===--------------------------------------------------------------------===//
+
+  /// EmitCall - Generate a call of the given function, expecting the given
+  /// result type, and using the given argument list which specifies both the
+  /// LLVM arguments and the types they were derived from.
+  ///
+  /// \param TargetDecl - If given, the decl of the function in a direct call;
+  /// used to set attributes on the call (noreturn, etc.).
+  RValue EmitCall(const CGFunctionInfo &FnInfo,
+                  llvm::Value *Callee,
+                  ReturnValueSlot ReturnValue,
+                  const CallArgList &Args,
+                  const Decl *TargetDecl = 0);
+
+  RValue EmitCall(QualType FnType, llvm::Value *Callee,
+                  ReturnValueSlot ReturnValue,
+                  CallExpr::const_arg_iterator ArgBeg,
+                  CallExpr::const_arg_iterator ArgEnd,
+                  const Decl *TargetDecl = 0);
+  RValue EmitCallExpr(const CallExpr *E, 
+                      ReturnValueSlot ReturnValue = ReturnValueSlot());
+
+  llvm::Value *BuildVirtualCall(const CXXMethodDecl *MD, llvm::Value *This,
+                                const llvm::Type *Ty);
+  llvm::Value *BuildVirtualCall(const CXXDestructorDecl *DD, CXXDtorType Type, 
+                                llvm::Value *&This, const llvm::Type *Ty);
+
+  RValue EmitCXXMemberCall(const CXXMethodDecl *MD,
+                           llvm::Value *Callee,
+                           ReturnValueSlot ReturnValue,
+                           llvm::Value *This,
+                           llvm::Value *VTT,
+                           CallExpr::const_arg_iterator ArgBeg,
+                           CallExpr::const_arg_iterator ArgEnd);
+  RValue EmitCXXMemberCallExpr(const CXXMemberCallExpr *E,
+                               ReturnValueSlot ReturnValue);
+  RValue EmitCXXMemberPointerCallExpr(const CXXMemberCallExpr *E,
+                                      ReturnValueSlot ReturnValue);
+
+  RValue EmitCXXOperatorMemberCallExpr(const CXXOperatorCallExpr *E,
+                                       const CXXMethodDecl *MD,
+                                       ReturnValueSlot ReturnValue);
+
+  
+  RValue EmitBuiltinExpr(const FunctionDecl *FD,
+                         unsigned BuiltinID, const CallExpr *E);
+
+  RValue EmitBlockCallExpr(const CallExpr *E, ReturnValueSlot ReturnValue);
+
+  /// EmitTargetBuiltinExpr - Emit the given builtin call. Returns 0 if the call
+  /// is unhandled by the current target.
+  llvm::Value *EmitTargetBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
+
+  llvm::Value *EmitARMBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
+  llvm::Value *EmitX86BuiltinExpr(unsigned BuiltinID, const CallExpr *E);
+  llvm::Value *EmitPPCBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
+
+  llvm::Value *EmitObjCProtocolExpr(const ObjCProtocolExpr *E);
+  llvm::Value *EmitObjCStringLiteral(const ObjCStringLiteral *E);
+  llvm::Value *EmitObjCSelectorExpr(const ObjCSelectorExpr *E);
+  RValue EmitObjCMessageExpr(const ObjCMessageExpr *E);
+  RValue EmitObjCPropertyGet(const Expr *E);
+  RValue EmitObjCSuperPropertyGet(const Expr *Exp, const Selector &S);
+  void EmitObjCPropertySet(const Expr *E, RValue Src);
+  void EmitObjCSuperPropertySet(const Expr *E, const Selector &S, RValue Src);
+
+
+  /// EmitReferenceBindingToExpr - Emits a reference binding to the passed in
+  /// expression. Will emit a temporary variable if E is not an LValue.
+  RValue EmitReferenceBindingToExpr(const Expr* E, bool IsInitializer = false);
+
+  //===--------------------------------------------------------------------===//
+  //                           Expression Emission
+  //===--------------------------------------------------------------------===//
+
+  // Expressions are broken into three classes: scalar, complex, aggregate.
+
+  /// EmitScalarExpr - Emit the computation of the specified expression of LLVM
+  /// scalar type, returning the result.
+  llvm::Value *EmitScalarExpr(const Expr *E , bool IgnoreResultAssign = false);
+
+  /// EmitScalarConversion - Emit a conversion from the specified type to the
+  /// specified destination type, both of which are LLVM scalar types.
+  llvm::Value *EmitScalarConversion(llvm::Value *Src, QualType SrcTy,
+                                    QualType DstTy);
+
+  /// EmitComplexToScalarConversion - Emit a conversion from the specified
+  /// complex type to the specified destination type, where the destination type
+  /// is an LLVM scalar type.
+  llvm::Value *EmitComplexToScalarConversion(ComplexPairTy Src, QualType SrcTy,
+                                             QualType DstTy);
+
+
+  /// EmitAggExpr - Emit the computation of the specified expression of
+  /// aggregate type.  The result is computed into DestPtr.  Note that if
+  /// DestPtr is null, the value of the aggregate expression is not needed.
+  void EmitAggExpr(const Expr *E, llvm::Value *DestPtr, bool VolatileDest,
+                   bool IgnoreResult = false, bool IsInitializer = false,
+                   bool RequiresGCollection = false);
+
+  /// EmitAggExprToLValue - Emit the computation of the specified expression of
+  /// aggregate type into a temporary LValue.
+  LValue EmitAggExprToLValue(const Expr *E);
+
+  /// EmitGCMemmoveCollectable - Emit special API for structs with object
+  /// pointers.
+  void EmitGCMemmoveCollectable(llvm::Value *DestPtr, llvm::Value *SrcPtr,
+                                QualType Ty);
+
+  /// EmitComplexExpr - Emit the computation of the specified expression of
+  /// complex type, returning the result.
+  ComplexPairTy EmitComplexExpr(const Expr *E, bool IgnoreReal = false,
+                                bool IgnoreImag = false,
+                                bool IgnoreRealAssign = false,
+                                bool IgnoreImagAssign = false);
+
+  /// EmitComplexExprIntoAddr - Emit the computation of the specified expression
+  /// of complex type, storing into the specified Value*.
+  void EmitComplexExprIntoAddr(const Expr *E, llvm::Value *DestAddr,
+                               bool DestIsVolatile);
+
+  /// StoreComplexToAddr - Store a complex number into the specified address.
+  void StoreComplexToAddr(ComplexPairTy V, llvm::Value *DestAddr,
+                          bool DestIsVolatile);
+  /// LoadComplexFromAddr - Load a complex number from the specified address.
+  ComplexPairTy LoadComplexFromAddr(llvm::Value *SrcAddr, bool SrcIsVolatile);
+
+  /// CreateStaticBlockVarDecl - Create a zero-initialized LLVM global for a
+  /// static block var decl.
+  llvm::GlobalVariable *CreateStaticBlockVarDecl(const VarDecl &D,
+                                                 const char *Separator,
+                                       llvm::GlobalValue::LinkageTypes Linkage);
+  
+  /// AddInitializerToGlobalBlockVarDecl - Add the initializer for 'D' to the
+  /// global variable that has already been created for it.  If the initializer
+  /// has a different type than GV does, this may free GV and return a different
+  /// one.  Otherwise it just returns GV.
+  llvm::GlobalVariable *
+  AddInitializerToGlobalBlockVarDecl(const VarDecl &D,
+                                     llvm::GlobalVariable *GV);
+  
+
+  /// EmitStaticCXXBlockVarDeclInit - Create the initializer for a C++ runtime
+  /// initialized static block var decl.
+  void EmitStaticCXXBlockVarDeclInit(const VarDecl &D,
+                                     llvm::GlobalVariable *GV);
+
+  /// EmitCXXGlobalVarDeclInit - Create the initializer for a C++
+  /// variable with global storage.
+  void EmitCXXGlobalVarDeclInit(const VarDecl &D, llvm::Constant *DeclPtr);
+
+  /// EmitCXXGlobalDtorRegistration - Emits a call to register the global ptr
+  /// with the C++ runtime so that its destructor will be called at exit.
+  void EmitCXXGlobalDtorRegistration(llvm::Constant *DtorFn,
+                                     llvm::Constant *DeclPtr);
+
+  /// GenerateCXXGlobalInitFunc - Generates code for initializing global
+  /// variables.
+  void GenerateCXXGlobalInitFunc(llvm::Function *Fn,
+                                 llvm::Constant **Decls,
+                                 unsigned NumDecls);
+
+  /// GenerateCXXGlobalDtorFunc - Generates code for destroying global
+  /// variables.
+  void GenerateCXXGlobalDtorFunc(llvm::Function *Fn,
+                                 const std::vector<std::pair<llvm::Constant*,
+                                   llvm::Constant*> > &DtorsAndObjects);
+
+  void GenerateCXXGlobalVarDeclInitFunc(llvm::Function *Fn, const VarDecl *D);
+
+  void EmitCXXConstructExpr(llvm::Value *Dest, const CXXConstructExpr *E);
+
+  RValue EmitCXXExprWithTemporaries(const CXXExprWithTemporaries *E,
+                                    llvm::Value *AggLoc = 0,
+                                    bool IsAggLocVolatile = false,
+                                    bool IsInitializer = false);
+
+  void EmitCXXThrowExpr(const CXXThrowExpr *E);
+
+  //===--------------------------------------------------------------------===//
+  //                             Internal Helpers
+  //===--------------------------------------------------------------------===//
+
+  /// ContainsLabel - Return true if the statement contains a label in it.  If
+  /// this statement is not executed normally, it not containing a label means
+  /// that we can just remove the code.
+  static bool ContainsLabel(const Stmt *S, bool IgnoreCaseStmts = false);
+
+  /// ConstantFoldsToSimpleInteger - If the specified expression does not fold
+  /// to a constant, or if it does but contains a label, return 0.  If it
+  /// constant folds to 'true' and does not contain a label, return 1, if it
+  /// constant folds to 'false' and does not contain a label, return -1.
+  int ConstantFoldsToSimpleInteger(const Expr *Cond);
+
+  /// EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g. for an
+  /// if statement) to the specified blocks.  Based on the condition, this might
+  /// try to simplify the codegen of the conditional based on the branch.
+  void EmitBranchOnBoolExpr(const Expr *Cond, llvm::BasicBlock *TrueBlock,
+                            llvm::BasicBlock *FalseBlock);
+
+  /// getTrapBB - Create a basic block that will call the trap intrinsic.  We'll
+  /// generate a branch around the created basic block as necessary.
+  llvm::BasicBlock* getTrapBB();
+  
+  /// EmitCallArg - Emit a single call argument.
+  RValue EmitCallArg(const Expr *E, QualType ArgType);
+
+private:
+
+  void EmitReturnOfRValue(RValue RV, QualType Ty);
+
+  /// ExpandTypeFromArgs - Reconstruct a structure of type \arg Ty
+  /// from function arguments into \arg Dst. See ABIArgInfo::Expand.
+  ///
+  /// \param AI - The first function argument of the expansion.
+  /// \return The argument following the last expanded function
+  /// argument.
+  llvm::Function::arg_iterator
+  ExpandTypeFromArgs(QualType Ty, LValue Dst,
+                     llvm::Function::arg_iterator AI);
+
+  /// ExpandTypeToArgs - Expand an RValue \arg Src, with the LLVM type for \arg
+  /// Ty, into individual arguments on the provided vector \arg Args. See
+  /// ABIArgInfo::Expand.
+  void ExpandTypeToArgs(QualType Ty, RValue Src,
+                        llvm::SmallVector<llvm::Value*, 16> &Args);
+
+  llvm::Value* EmitAsmInput(const AsmStmt &S,
+                            const TargetInfo::ConstraintInfo &Info,
+                            const Expr *InputExpr, std::string &ConstraintStr);
+
+  /// EmitCleanupBlock - emits a single cleanup block.
+  void EmitCleanupBlock();
+
+  /// AddBranchFixup - adds a branch instruction to the list of fixups for the
+  /// current cleanup scope.
+  void AddBranchFixup(llvm::BranchInst *BI);
+
+  /// EmitCallArgs - Emit call arguments for a function.
+  /// The CallArgTypeInfo parameter is used for iterating over the known
+  /// argument types of the function being called.
+  template<typename T>
+  void EmitCallArgs(CallArgList& Args, const T* CallArgTypeInfo,
+                    CallExpr::const_arg_iterator ArgBeg,
+                    CallExpr::const_arg_iterator ArgEnd) {
+      CallExpr::const_arg_iterator Arg = ArgBeg;
+
+    // First, use the argument types that the type info knows about
+    if (CallArgTypeInfo) {
+      for (typename T::arg_type_iterator I = CallArgTypeInfo->arg_type_begin(),
+           E = CallArgTypeInfo->arg_type_end(); I != E; ++I, ++Arg) {
+        assert(Arg != ArgEnd && "Running over edge of argument list!");
+        QualType ArgType = *I;
+
+        assert(getContext().getCanonicalType(ArgType.getNonReferenceType()).
+               getTypePtr() ==
+               getContext().getCanonicalType(Arg->getType()).getTypePtr() &&
+               "type mismatch in call argument!");
+
+        Args.push_back(std::make_pair(EmitCallArg(*Arg, ArgType),
+                                      ArgType));
+      }
+
+      // Either we've emitted all the call args, or we have a call to a
+      // variadic function.
+      assert((Arg == ArgEnd || CallArgTypeInfo->isVariadic()) &&
+             "Extra arguments in non-variadic function!");
+
+    }
+
+    // If we still have any arguments, emit them using the type of the argument.
+    for (; Arg != ArgEnd; ++Arg) {
+      QualType ArgType = Arg->getType();
+      Args.push_back(std::make_pair(EmitCallArg(*Arg, ArgType),
+                                    ArgType));
+    }
+  }
+
+  const TargetCodeGenInfo &getTargetHooks() const {
+    return CGM.getTargetCodeGenInfo();
+  }
+};
+
+
+}  // end namespace CodeGen
+}  // end namespace clang
+
+#endif
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
new file mode 100644
index 0000000..599df96
--- /dev/null
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -0,0 +1,1944 @@
+//===--- CodeGenModule.cpp - Emit LLVM Code from ASTs for a Module --------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This coordinates the per-module state used while generating code.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CodeGenModule.h"
+#include "CGDebugInfo.h"
+#include "CodeGenFunction.h"
+#include "CGCall.h"
+#include "CGObjCRuntime.h"
+#include "Mangle.h"
+#include "TargetInfo.h"
+#include "clang/CodeGen/CodeGenOptions.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/CharUnits.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/RecordLayout.h"
+#include "clang/Basic/Builtins.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/TargetInfo.h"
+#include "clang/Basic/ConvertUTF.h"
+#include "llvm/CallingConv.h"
+#include "llvm/Module.h"
+#include "llvm/Intrinsics.h"
+#include "llvm/LLVMContext.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Target/TargetData.h"
+#include "llvm/Support/CallSite.h"
+#include "llvm/Support/ErrorHandling.h"
+using namespace clang;
+using namespace CodeGen;
+
+
+CodeGenModule::CodeGenModule(ASTContext &C, const CodeGenOptions &CGO,
+                             llvm::Module &M, const llvm::TargetData &TD,
+                             Diagnostic &diags)
+  : BlockModule(C, M, TD, Types, *this), Context(C),
+    Features(C.getLangOptions()), CodeGenOpts(CGO), TheModule(M),
+    TheTargetData(TD), TheTargetCodeGenInfo(0), Diags(diags),
+    Types(C, M, TD, getTargetCodeGenInfo().getABIInfo()),
+    MangleCtx(C, diags), VTables(*this), Runtime(0),
+    CFConstantStringClassRef(0),
+    NSConstantStringClassRef(0),
+    VMContext(M.getContext()) {
+
+  if (!Features.ObjC1)
+    Runtime = 0;
+  else if (!Features.NeXTRuntime)
+    Runtime = CreateGNUObjCRuntime(*this);
+  else if (Features.ObjCNonFragileABI)
+    Runtime = CreateMacNonFragileABIObjCRuntime(*this);
+  else
+    Runtime = CreateMacObjCRuntime(*this);
+
+  // If debug info generation is enabled, create the CGDebugInfo object.
+  DebugInfo = CodeGenOpts.DebugInfo ? new CGDebugInfo(*this) : 0;
+}
+
+CodeGenModule::~CodeGenModule() {
+  delete Runtime;
+  delete DebugInfo;
+}
+
+void CodeGenModule::createObjCRuntime() {
+  if (!Features.NeXTRuntime)
+    Runtime = CreateGNUObjCRuntime(*this);
+  else if (Features.ObjCNonFragileABI)
+    Runtime = CreateMacNonFragileABIObjCRuntime(*this);
+  else
+    Runtime = CreateMacObjCRuntime(*this);
+}
+
+void CodeGenModule::Release() {
+  EmitDeferred();
+  EmitCXXGlobalInitFunc();
+  EmitCXXGlobalDtorFunc();
+  if (Runtime)
+    if (llvm::Function *ObjCInitFunction = Runtime->ModuleInitFunction())
+      AddGlobalCtor(ObjCInitFunction);
+  EmitCtorList(GlobalCtors, "llvm.global_ctors");
+  EmitCtorList(GlobalDtors, "llvm.global_dtors");
+  EmitAnnotations();
+  EmitLLVMUsed();
+}
+
+bool CodeGenModule::isTargetDarwin() const {
+  return getContext().Target.getTriple().getOS() == llvm::Triple::Darwin;
+}
+
+/// ErrorUnsupported - Print out an error that codegen doesn't support the
+/// specified stmt yet.
+void CodeGenModule::ErrorUnsupported(const Stmt *S, const char *Type,
+                                     bool OmitOnError) {
+  if (OmitOnError && getDiags().hasErrorOccurred())
+    return;
+  unsigned DiagID = getDiags().getCustomDiagID(Diagnostic::Error,
+                                               "cannot compile this %0 yet");
+  std::string Msg = Type;
+  getDiags().Report(Context.getFullLoc(S->getLocStart()), DiagID)
+    << Msg << S->getSourceRange();
+}
+
+/// ErrorUnsupported - Print out an error that codegen doesn't support the
+/// specified decl yet.
+void CodeGenModule::ErrorUnsupported(const Decl *D, const char *Type,
+                                     bool OmitOnError) {
+  if (OmitOnError && getDiags().hasErrorOccurred())
+    return;
+  unsigned DiagID = getDiags().getCustomDiagID(Diagnostic::Error,
+                                               "cannot compile this %0 yet");
+  std::string Msg = Type;
+  getDiags().Report(Context.getFullLoc(D->getLocation()), DiagID) << Msg;
+}
+
+LangOptions::VisibilityMode
+CodeGenModule::getDeclVisibilityMode(const Decl *D) const {
+  if (const VarDecl *VD = dyn_cast<VarDecl>(D))
+    if (VD->getStorageClass() == VarDecl::PrivateExtern)
+      return LangOptions::Hidden;
+
+  if (const VisibilityAttr *attr = D->getAttr<VisibilityAttr>()) {
+    switch (attr->getVisibility()) {
+    default: assert(0 && "Unknown visibility!");
+    case VisibilityAttr::DefaultVisibility:
+      return LangOptions::Default;
+    case VisibilityAttr::HiddenVisibility:
+      return LangOptions::Hidden;
+    case VisibilityAttr::ProtectedVisibility:
+      return LangOptions::Protected;
+    }
+  }
+
+  // This decl should have the same visibility as its parent.
+  if (const DeclContext *DC = D->getDeclContext()) 
+    return getDeclVisibilityMode(cast<Decl>(DC));
+
+  return getLangOptions().getVisibilityMode();
+}
+
+void CodeGenModule::setGlobalVisibility(llvm::GlobalValue *GV,
+                                        const Decl *D) const {
+  // Internal definitions always have default visibility.
+  if (GV->hasLocalLinkage()) {
+    GV->setVisibility(llvm::GlobalValue::DefaultVisibility);
+    return;
+  }
+
+  switch (getDeclVisibilityMode(D)) {
+  default: assert(0 && "Unknown visibility!");
+  case LangOptions::Default:
+    return GV->setVisibility(llvm::GlobalValue::DefaultVisibility);
+  case LangOptions::Hidden:
+    return GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
+  case LangOptions::Protected:
+    return GV->setVisibility(llvm::GlobalValue::ProtectedVisibility);
+  }
+}
+
+void CodeGenModule::getMangledName(MangleBuffer &Buffer, GlobalDecl GD) {
+  const NamedDecl *ND = cast<NamedDecl>(GD.getDecl());
+
+  if (const CXXConstructorDecl *D = dyn_cast<CXXConstructorDecl>(ND))
+    return getMangledCXXCtorName(Buffer, D, GD.getCtorType());
+  if (const CXXDestructorDecl *D = dyn_cast<CXXDestructorDecl>(ND))
+    return getMangledCXXDtorName(Buffer, D, GD.getDtorType());
+
+  return getMangledName(Buffer, ND);
+}
+
+/// \brief Retrieves the mangled name for the given declaration.
+///
+/// If the given declaration requires a mangled name, returns an
+/// const char* containing the mangled name.  Otherwise, returns
+/// the unmangled name.
+///
+void CodeGenModule::getMangledName(MangleBuffer &Buffer,
+                                   const NamedDecl *ND) {
+  if (!getMangleContext().shouldMangleDeclName(ND)) {
+    assert(ND->getIdentifier() && "Attempt to mangle unnamed decl.");
+    Buffer.setString(ND->getNameAsCString());
+    return;
+  }
+
+  getMangleContext().mangleName(ND, Buffer.getBuffer());
+}
+
+llvm::GlobalValue *CodeGenModule::GetGlobalValue(llvm::StringRef Name) {
+  return getModule().getNamedValue(Name);
+}
+
+/// AddGlobalCtor - Add a function to the list that will be called before
+/// main() runs.
+void CodeGenModule::AddGlobalCtor(llvm::Function * Ctor, int Priority) {
+  // FIXME: Type coercion of void()* types.
+  GlobalCtors.push_back(std::make_pair(Ctor, Priority));
+}
+
+/// AddGlobalDtor - Add a function to the list that will be called
+/// when the module is unloaded.
+void CodeGenModule::AddGlobalDtor(llvm::Function * Dtor, int Priority) {
+  // FIXME: Type coercion of void()* types.
+  GlobalDtors.push_back(std::make_pair(Dtor, Priority));
+}
+
+void CodeGenModule::EmitCtorList(const CtorList &Fns, const char *GlobalName) {
+  // Ctor function type is void()*.
+  llvm::FunctionType* CtorFTy =
+    llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
+                            std::vector<const llvm::Type*>(),
+                            false);
+  llvm::Type *CtorPFTy = llvm::PointerType::getUnqual(CtorFTy);
+
+  // Get the type of a ctor entry, { i32, void ()* }.
+  llvm::StructType* CtorStructTy =
+    llvm::StructType::get(VMContext, llvm::Type::getInt32Ty(VMContext),
+                          llvm::PointerType::getUnqual(CtorFTy), NULL);
+
+  // Construct the constructor and destructor arrays.
+  std::vector<llvm::Constant*> Ctors;
+  for (CtorList::const_iterator I = Fns.begin(), E = Fns.end(); I != E; ++I) {
+    std::vector<llvm::Constant*> S;
+    S.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext),
+                I->second, false));
+    S.push_back(llvm::ConstantExpr::getBitCast(I->first, CtorPFTy));
+    Ctors.push_back(llvm::ConstantStruct::get(CtorStructTy, S));
+  }
+
+  if (!Ctors.empty()) {
+    llvm::ArrayType *AT = llvm::ArrayType::get(CtorStructTy, Ctors.size());
+    new llvm::GlobalVariable(TheModule, AT, false,
+                             llvm::GlobalValue::AppendingLinkage,
+                             llvm::ConstantArray::get(AT, Ctors),
+                             GlobalName);
+  }
+}
+
+void CodeGenModule::EmitAnnotations() {
+  if (Annotations.empty())
+    return;
+
+  // Create a new global variable for the ConstantStruct in the Module.
+  llvm::Constant *Array =
+  llvm::ConstantArray::get(llvm::ArrayType::get(Annotations[0]->getType(),
+                                                Annotations.size()),
+                           Annotations);
+  llvm::GlobalValue *gv =
+  new llvm::GlobalVariable(TheModule, Array->getType(), false,
+                           llvm::GlobalValue::AppendingLinkage, Array,
+                           "llvm.global.annotations");
+  gv->setSection("llvm.metadata");
+}
+
+static CodeGenModule::GVALinkage
+GetLinkageForFunction(ASTContext &Context, const FunctionDecl *FD,
+                      const LangOptions &Features) {
+  CodeGenModule::GVALinkage External = CodeGenModule::GVA_StrongExternal;
+
+  Linkage L = FD->getLinkage();
+  if (L == ExternalLinkage && Context.getLangOptions().CPlusPlus &&
+      FD->getType()->getLinkage() == UniqueExternalLinkage)
+    L = UniqueExternalLinkage;
+  
+  switch (L) {
+  case NoLinkage:
+  case InternalLinkage:
+  case UniqueExternalLinkage:
+    return CodeGenModule::GVA_Internal;
+    
+  case ExternalLinkage:
+    switch (FD->getTemplateSpecializationKind()) {
+    case TSK_Undeclared:
+    case TSK_ExplicitSpecialization:
+      External = CodeGenModule::GVA_StrongExternal;
+      break;
+
+    case TSK_ExplicitInstantiationDefinition:
+      return CodeGenModule::GVA_ExplicitTemplateInstantiation;
+
+    case TSK_ExplicitInstantiationDeclaration:
+    case TSK_ImplicitInstantiation:
+      External = CodeGenModule::GVA_TemplateInstantiation;
+      break;
+    }
+  }
+
+  if (!FD->isInlined())
+    return External;
+    
+  if (!Features.CPlusPlus || FD->hasAttr<GNUInlineAttr>()) {
+    // GNU or C99 inline semantics. Determine whether this symbol should be
+    // externally visible.
+    if (FD->isInlineDefinitionExternallyVisible())
+      return External;
+
+    // C99 inline semantics, where the symbol is not externally visible.
+    return CodeGenModule::GVA_C99Inline;
+  }
+
+  // C++0x [temp.explicit]p9:
+  //   [ Note: The intent is that an inline function that is the subject of 
+  //   an explicit instantiation declaration will still be implicitly 
+  //   instantiated when used so that the body can be considered for 
+  //   inlining, but that no out-of-line copy of the inline function would be
+  //   generated in the translation unit. -- end note ]
+  if (FD->getTemplateSpecializationKind() 
+                                       == TSK_ExplicitInstantiationDeclaration)
+    return CodeGenModule::GVA_C99Inline;
+
+  // If this is a virtual method and its class has a key method in another
+  // translation unit, we know that this method will be present in that
+  // translation unit. In this translation unit we will use this method
+  // only for inlining and analysis. This is the semantics of c99 inline.
+  if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
+    const CXXRecordDecl *RD = MD->getParent();
+    if (MD->isVirtual() &&
+	CodeGenVTables::isKeyFunctionInAnotherTU(Context, RD))
+      return CodeGenModule::GVA_C99Inline;
+  }  
+
+  return CodeGenModule::GVA_CXXInline;
+}
+
+llvm::GlobalValue::LinkageTypes
+CodeGenModule::getFunctionLinkage(const FunctionDecl *D) {
+  GVALinkage Linkage = GetLinkageForFunction(getContext(), D, Features);
+
+  if (Linkage == GVA_Internal) {
+    return llvm::Function::InternalLinkage;
+  } else if (D->hasAttr<DLLExportAttr>()) {
+    return llvm::Function::DLLExportLinkage;
+  } else if (D->hasAttr<WeakAttr>()) {
+    return llvm::Function::WeakAnyLinkage;
+  } else if (Linkage == GVA_C99Inline) {
+    // In C99 mode, 'inline' functions are guaranteed to have a strong
+    // definition somewhere else, so we can use available_externally linkage.
+    return llvm::Function::AvailableExternallyLinkage;
+  } else if (Linkage == GVA_CXXInline || Linkage == GVA_TemplateInstantiation) {
+    // In C++, the compiler has to emit a definition in every translation unit
+    // that references the function.  We should use linkonce_odr because
+    // a) if all references in this translation unit are optimized away, we
+    // don't need to codegen it.  b) if the function persists, it needs to be
+    // merged with other definitions. c) C++ has the ODR, so we know the
+    // definition is dependable.
+    return llvm::Function::LinkOnceODRLinkage;
+  } else if (Linkage == GVA_ExplicitTemplateInstantiation) {
+    // An explicit instantiation of a template has weak linkage, since
+    // explicit instantiations can occur in multiple translation units
+    // and must all be equivalent. However, we are not allowed to
+    // throw away these explicit instantiations.
+    return llvm::Function::WeakODRLinkage;
+  } else {
+    assert(Linkage == GVA_StrongExternal);
+    // Otherwise, we have strong external linkage.
+    return llvm::Function::ExternalLinkage;
+  }
+}
+
+
+/// SetFunctionDefinitionAttributes - Set attributes for a global.
+///
+/// FIXME: This is currently only done for aliases and functions, but not for
+/// variables (these details are set in EmitGlobalVarDefinition for variables).
+void CodeGenModule::SetFunctionDefinitionAttributes(const FunctionDecl *D,
+                                                    llvm::GlobalValue *GV) {
+  GV->setLinkage(getFunctionLinkage(D));
+  SetCommonAttributes(D, GV);
+}
+
+void CodeGenModule::SetLLVMFunctionAttributes(const Decl *D,
+                                              const CGFunctionInfo &Info,
+                                              llvm::Function *F) {
+  unsigned CallingConv;
+  AttributeListType AttributeList;
+  ConstructAttributeList(Info, D, AttributeList, CallingConv);
+  F->setAttributes(llvm::AttrListPtr::get(AttributeList.begin(),
+                                          AttributeList.size()));
+  F->setCallingConv(static_cast<llvm::CallingConv::ID>(CallingConv));
+}
+
+void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,
+                                                           llvm::Function *F) {
+  if (!Features.Exceptions && !Features.ObjCNonFragileABI)
+    F->addFnAttr(llvm::Attribute::NoUnwind);
+
+  if (D->hasAttr<AlwaysInlineAttr>())
+    F->addFnAttr(llvm::Attribute::AlwaysInline);
+
+  if (D->hasAttr<NoInlineAttr>())
+    F->addFnAttr(llvm::Attribute::NoInline);
+
+  if (Features.getStackProtectorMode() == LangOptions::SSPOn)
+    F->addFnAttr(llvm::Attribute::StackProtect);
+  else if (Features.getStackProtectorMode() == LangOptions::SSPReq)
+    F->addFnAttr(llvm::Attribute::StackProtectReq);
+  
+  if (const AlignedAttr *AA = D->getAttr<AlignedAttr>()) {
+    unsigned width = Context.Target.getCharWidth();
+    F->setAlignment(AA->getAlignment() / width);
+    while ((AA = AA->getNext<AlignedAttr>()))
+      F->setAlignment(std::max(F->getAlignment(), AA->getAlignment() / width));
+  }
+  // C++ ABI requires 2-byte alignment for member functions.
+  if (F->getAlignment() < 2 && isa<CXXMethodDecl>(D))
+    F->setAlignment(2);
+}
+
+void CodeGenModule::SetCommonAttributes(const Decl *D,
+                                        llvm::GlobalValue *GV) {
+  setGlobalVisibility(GV, D);
+
+  if (D->hasAttr<UsedAttr>())
+    AddUsedGlobal(GV);
+
+  if (const SectionAttr *SA = D->getAttr<SectionAttr>())
+    GV->setSection(SA->getName());
+
+  getTargetCodeGenInfo().SetTargetAttributes(D, GV, *this);
+}
+
+void CodeGenModule::SetInternalFunctionAttributes(const Decl *D,
+                                                  llvm::Function *F,
+                                                  const CGFunctionInfo &FI) {
+  SetLLVMFunctionAttributes(D, FI, F);
+  SetLLVMFunctionAttributesForDefinition(D, F);
+
+  F->setLinkage(llvm::Function::InternalLinkage);
+
+  SetCommonAttributes(D, F);
+}
+
+void CodeGenModule::SetFunctionAttributes(GlobalDecl GD,
+                                          llvm::Function *F,
+                                          bool IsIncompleteFunction) {
+  const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl());
+
+  if (!IsIncompleteFunction)
+    SetLLVMFunctionAttributes(FD, getTypes().getFunctionInfo(GD), F);
+
+  // Only a few attributes are set on declarations; these may later be
+  // overridden by a definition.
+
+  if (FD->hasAttr<DLLImportAttr>()) {
+    F->setLinkage(llvm::Function::DLLImportLinkage);
+  } else if (FD->hasAttr<WeakAttr>() ||
+             FD->hasAttr<WeakImportAttr>()) {
+    // "extern_weak" is overloaded in LLVM; we probably should have
+    // separate linkage types for this.
+    F->setLinkage(llvm::Function::ExternalWeakLinkage);
+  } else {
+    F->setLinkage(llvm::Function::ExternalLinkage);
+  }
+
+  if (const SectionAttr *SA = FD->getAttr<SectionAttr>())
+    F->setSection(SA->getName());
+}
+
+void CodeGenModule::AddUsedGlobal(llvm::GlobalValue *GV) {
+  assert(!GV->isDeclaration() &&
+         "Only globals with definition can force usage.");
+  LLVMUsed.push_back(GV);
+}
+
+void CodeGenModule::EmitLLVMUsed() {
+  // Don't create llvm.used if there is no need.
+  if (LLVMUsed.empty())
+    return;
+
+  const llvm::Type *i8PTy = llvm::Type::getInt8PtrTy(VMContext);
+
+  // Convert LLVMUsed to what ConstantArray needs.
+  std::vector<llvm::Constant*> UsedArray;
+  UsedArray.resize(LLVMUsed.size());
+  for (unsigned i = 0, e = LLVMUsed.size(); i != e; ++i) {
+    UsedArray[i] =
+     llvm::ConstantExpr::getBitCast(cast<llvm::Constant>(&*LLVMUsed[i]),
+                                      i8PTy);
+  }
+
+  if (UsedArray.empty())
+    return;
+  llvm::ArrayType *ATy = llvm::ArrayType::get(i8PTy, UsedArray.size());
+
+  llvm::GlobalVariable *GV =
+    new llvm::GlobalVariable(getModule(), ATy, false,
+                             llvm::GlobalValue::AppendingLinkage,
+                             llvm::ConstantArray::get(ATy, UsedArray),
+                             "llvm.used");
+
+  GV->setSection("llvm.metadata");
+}
+
+void CodeGenModule::EmitDeferred() {
+  // Emit code for any potentially referenced deferred decls.  Since a
+  // previously unused static decl may become used during the generation of code
+  // for a static function, iterate until no  changes are made.
+
+  while (!DeferredDeclsToEmit.empty() || !DeferredVTables.empty()) {
+    if (!DeferredVTables.empty()) {
+      const CXXRecordDecl *RD = DeferredVTables.back();
+      DeferredVTables.pop_back();
+      getVTables().GenerateClassData(getVTableLinkage(RD), RD);
+      continue;
+    }
+
+    GlobalDecl D = DeferredDeclsToEmit.back();
+    DeferredDeclsToEmit.pop_back();
+
+    // Look it up to see if it was defined with a stronger definition (e.g. an
+    // extern inline function with a strong function redefinition).  If so,
+    // just ignore the deferred decl.
+    MangleBuffer Name;
+    getMangledName(Name, D);
+    llvm::GlobalValue *CGRef = GetGlobalValue(Name);
+    assert(CGRef && "Deferred decl wasn't referenced?");
+
+    if (!CGRef->isDeclaration())
+      continue;
+
+    // Otherwise, emit the definition and move on to the next one.
+    EmitGlobalDefinition(D);
+  }
+}
+
+/// EmitAnnotateAttr - Generate the llvm::ConstantStruct which contains the
+/// annotation information for a given GlobalValue.  The annotation struct is
+/// {i8 *, i8 *, i8 *, i32}.  The first field is a constant expression, the
+/// GlobalValue being annotated.  The second field is the constant string
+/// created from the AnnotateAttr's annotation.  The third field is a constant
+/// string containing the name of the translation unit.  The fourth field is
+/// the line number in the file of the annotated value declaration.
+///
+/// FIXME: this does not unique the annotation string constants, as llvm-gcc
+///        appears to.
+///
+llvm::Constant *CodeGenModule::EmitAnnotateAttr(llvm::GlobalValue *GV,
+                                                const AnnotateAttr *AA,
+                                                unsigned LineNo) {
+  llvm::Module *M = &getModule();
+
+  // get [N x i8] constants for the annotation string, and the filename string
+  // which are the 2nd and 3rd elements of the global annotation structure.
+  const llvm::Type *SBP = llvm::Type::getInt8PtrTy(VMContext);
+  llvm::Constant *anno = llvm::ConstantArray::get(VMContext,
+                                                  AA->getAnnotation(), true);
+  llvm::Constant *unit = llvm::ConstantArray::get(VMContext,
+                                                  M->getModuleIdentifier(),
+                                                  true);
+
+  // Get the two global values corresponding to the ConstantArrays we just
+  // created to hold the bytes of the strings.
+  llvm::GlobalValue *annoGV =
+    new llvm::GlobalVariable(*M, anno->getType(), false,
+                             llvm::GlobalValue::PrivateLinkage, anno,
+                             GV->getName());
+  // translation unit name string, emitted into the llvm.metadata section.
+  llvm::GlobalValue *unitGV =
+    new llvm::GlobalVariable(*M, unit->getType(), false,
+                             llvm::GlobalValue::PrivateLinkage, unit,
+                             ".str");
+
+  // Create the ConstantStruct for the global annotation.
+  llvm::Constant *Fields[4] = {
+    llvm::ConstantExpr::getBitCast(GV, SBP),
+    llvm::ConstantExpr::getBitCast(annoGV, SBP),
+    llvm::ConstantExpr::getBitCast(unitGV, SBP),
+    llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), LineNo)
+  };
+  return llvm::ConstantStruct::get(VMContext, Fields, 4, false);
+}
+
+bool CodeGenModule::MayDeferGeneration(const ValueDecl *Global) {
+  // Never defer when EmitAllDecls is specified or the decl has
+  // attribute used.
+  if (Features.EmitAllDecls || Global->hasAttr<UsedAttr>())
+    return false;
+
+  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(Global)) {
+    // Constructors and destructors should never be deferred.
+    if (FD->hasAttr<ConstructorAttr>() ||
+        FD->hasAttr<DestructorAttr>())
+      return false;
+
+    // The key function for a class must never be deferred.
+    if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Global)) {
+      const CXXRecordDecl *RD = MD->getParent();
+      if (MD->isOutOfLine() && RD->isDynamicClass()) {
+        const CXXMethodDecl *KeyFunction = getContext().getKeyFunction(RD);
+        if (KeyFunction && 
+            KeyFunction->getCanonicalDecl() == MD->getCanonicalDecl())
+          return false;
+      }
+    }
+
+    GVALinkage Linkage = GetLinkageForFunction(getContext(), FD, Features);
+
+    // static, static inline, always_inline, and extern inline functions can
+    // always be deferred.  Normal inline functions can be deferred in C99/C++.
+    // Implicit template instantiations can also be deferred in C++.
+    if (Linkage == GVA_Internal || Linkage == GVA_C99Inline ||
+        Linkage == GVA_CXXInline || Linkage == GVA_TemplateInstantiation)
+      return true;
+    return false;
+  }
+
+  const VarDecl *VD = cast<VarDecl>(Global);
+  assert(VD->isFileVarDecl() && "Invalid decl");
+
+  // We never want to defer structs that have non-trivial constructors or 
+  // destructors.
+  
+  // FIXME: Handle references.
+  if (const RecordType *RT = VD->getType()->getAs<RecordType>()) {
+    if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
+      if (!RD->hasTrivialConstructor() || !RD->hasTrivialDestructor())
+        return false;
+    }
+  }
+      
+  // Static data may be deferred, but out-of-line static data members
+  // cannot be.
+  Linkage L = VD->getLinkage();
+  if (L == ExternalLinkage && getContext().getLangOptions().CPlusPlus &&
+      VD->getType()->getLinkage() == UniqueExternalLinkage)
+    L = UniqueExternalLinkage;
+
+  switch (L) {
+  case NoLinkage:
+  case InternalLinkage:
+  case UniqueExternalLinkage:
+    // Initializer has side effects?
+    if (VD->getInit() && VD->getInit()->HasSideEffects(Context))
+      return false;
+    return !(VD->isStaticDataMember() && VD->isOutOfLine());
+
+  case ExternalLinkage:
+    break;
+  }
+
+  return false;
+}
+
+llvm::Constant *CodeGenModule::GetWeakRefReference(const ValueDecl *VD) {
+  const AliasAttr *AA = VD->getAttr<AliasAttr>();
+  assert(AA && "No alias?");
+
+  const llvm::Type *DeclTy = getTypes().ConvertTypeForMem(VD->getType());
+
+  // See if there is already something with the target's name in the module.
+  llvm::GlobalValue *Entry = GetGlobalValue(AA->getAliasee());
+
+  llvm::Constant *Aliasee;
+  if (isa<llvm::FunctionType>(DeclTy))
+    Aliasee = GetOrCreateLLVMFunction(AA->getAliasee(), DeclTy, GlobalDecl());
+  else
+    Aliasee = GetOrCreateLLVMGlobal(AA->getAliasee(),
+                                    llvm::PointerType::getUnqual(DeclTy), 0);
+  if (!Entry) {
+    llvm::GlobalValue* F = cast<llvm::GlobalValue>(Aliasee);
+    F->setLinkage(llvm::Function::ExternalWeakLinkage);    
+    WeakRefReferences.insert(F);
+  }
+
+  return Aliasee;
+}
+
+void CodeGenModule::EmitGlobal(GlobalDecl GD) {
+  const ValueDecl *Global = cast<ValueDecl>(GD.getDecl());
+
+  // Weak references don't produce any output by themselves.
+  if (Global->hasAttr<WeakRefAttr>())
+    return;
+
+  // If this is an alias definition (which otherwise looks like a declaration)
+  // emit it now.
+  if (Global->hasAttr<AliasAttr>())
+    return EmitAliasDefinition(GD);
+
+  // Ignore declarations, they will be emitted on their first use.
+  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(Global)) {
+    // Forward declarations are emitted lazily on first use.
+    if (!FD->isThisDeclarationADefinition())
+      return;
+  } else {
+    const VarDecl *VD = cast<VarDecl>(Global);
+    assert(VD->isFileVarDecl() && "Cannot emit local var decl as global.");
+
+    if (VD->isThisDeclarationADefinition() != VarDecl::Definition)
+      return;
+  }
+
+  // Defer code generation when possible if this is a static definition, inline
+  // function etc.  These we only want to emit if they are used.
+  if (!MayDeferGeneration(Global)) {
+    // Emit the definition if it can't be deferred.
+    EmitGlobalDefinition(GD);
+    return;
+  }
+  
+  // If the value has already been used, add it directly to the
+  // DeferredDeclsToEmit list.
+  MangleBuffer MangledName;
+  getMangledName(MangledName, GD);
+  if (GetGlobalValue(MangledName))
+    DeferredDeclsToEmit.push_back(GD);
+  else {
+    // Otherwise, remember that we saw a deferred decl with this name.  The
+    // first use of the mangled name will cause it to move into
+    // DeferredDeclsToEmit.
+    DeferredDecls[MangledName] = GD;
+  }
+}
+
+void CodeGenModule::EmitGlobalDefinition(GlobalDecl GD) {
+  const ValueDecl *D = cast<ValueDecl>(GD.getDecl());
+
+  PrettyStackTraceDecl CrashInfo(const_cast<ValueDecl *>(D), D->getLocation(), 
+                                 Context.getSourceManager(),
+                                 "Generating code for declaration");
+  
+  if (isa<CXXMethodDecl>(D))
+    getVTables().EmitVTableRelatedData(GD);
+
+  if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(D))
+    return EmitCXXConstructor(CD, GD.getCtorType());
+  
+  if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(D))
+    return EmitCXXDestructor(DD, GD.getDtorType());
+
+  if (isa<FunctionDecl>(D))
+    return EmitGlobalFunctionDefinition(GD);
+  
+  if (const VarDecl *VD = dyn_cast<VarDecl>(D))
+    return EmitGlobalVarDefinition(VD);
+  
+  assert(0 && "Invalid argument to EmitGlobalDefinition()");
+}
+
+/// GetOrCreateLLVMFunction - If the specified mangled name is not in the
+/// module, create and return an llvm Function with the specified type. If there
+/// is something in the module with the specified name, return it potentially
+/// bitcasted to the right type.
+///
+/// If D is non-null, it specifies a decl that correspond to this.  This is used
+/// to set the attributes on the function when it is first created.
+llvm::Constant *
+CodeGenModule::GetOrCreateLLVMFunction(llvm::StringRef MangledName,
+                                       const llvm::Type *Ty,
+                                       GlobalDecl D) {
+  // Lookup the entry, lazily creating it if necessary.
+  llvm::GlobalValue *Entry = GetGlobalValue(MangledName);
+  if (Entry) {
+    if (WeakRefReferences.count(Entry)) {
+      const FunctionDecl *FD = cast_or_null<FunctionDecl>(D.getDecl());
+      if (FD && !FD->hasAttr<WeakAttr>())
+        Entry->setLinkage(llvm::Function::ExternalLinkage);
+
+      WeakRefReferences.erase(Entry);
+    }
+
+    if (Entry->getType()->getElementType() == Ty)
+      return Entry;
+
+    // Make sure the result is of the correct type.
+    const llvm::Type *PTy = llvm::PointerType::getUnqual(Ty);
+    return llvm::ConstantExpr::getBitCast(Entry, PTy);
+  }
+
+  // This function doesn't have a complete type (for example, the return
+  // type is an incomplete struct). Use a fake type instead, and make
+  // sure not to try to set attributes.
+  bool IsIncompleteFunction = false;
+  if (!isa<llvm::FunctionType>(Ty)) {
+    Ty = llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
+                                 std::vector<const llvm::Type*>(), false);
+    IsIncompleteFunction = true;
+  }
+  llvm::Function *F = llvm::Function::Create(cast<llvm::FunctionType>(Ty),
+                                             llvm::Function::ExternalLinkage,
+                                             MangledName, &getModule());
+  assert(F->getName() == MangledName && "name was uniqued!");
+  if (D.getDecl())
+    SetFunctionAttributes(D, F, IsIncompleteFunction);
+
+  // This is the first use or definition of a mangled name.  If there is a
+  // deferred decl with this name, remember that we need to emit it at the end
+  // of the file.
+  llvm::StringMap<GlobalDecl>::iterator DDI = DeferredDecls.find(MangledName);
+  if (DDI != DeferredDecls.end()) {
+    // Move the potentially referenced deferred decl to the DeferredDeclsToEmit
+    // list, and remove it from DeferredDecls (since we don't need it anymore).
+    DeferredDeclsToEmit.push_back(DDI->second);
+    DeferredDecls.erase(DDI);
+  } else if (const FunctionDecl *FD = cast_or_null<FunctionDecl>(D.getDecl())) {
+    // If this the first reference to a C++ inline function in a class, queue up
+    // the deferred function body for emission.  These are not seen as
+    // top-level declarations.
+    if (FD->isThisDeclarationADefinition() && MayDeferGeneration(FD))
+      DeferredDeclsToEmit.push_back(D);
+    // A called constructor which has no definition or declaration need be
+    // synthesized.
+    else if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(FD)) {
+      if (CD->isImplicit()) {
+        assert(CD->isUsed() && "Sema doesn't consider constructor as used.");
+        DeferredDeclsToEmit.push_back(D);
+      }
+    } else if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(FD)) {
+      if (DD->isImplicit()) {
+        assert(DD->isUsed() && "Sema doesn't consider destructor as used.");
+        DeferredDeclsToEmit.push_back(D);
+      }
+    } else if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
+      if (MD->isCopyAssignment() && MD->isImplicit()) {
+        assert(MD->isUsed() && "Sema doesn't consider CopyAssignment as used.");
+        DeferredDeclsToEmit.push_back(D);
+      }
+    }
+  }
+
+  return F;
+}
+
+/// GetAddrOfFunction - Return the address of the given function.  If Ty is
+/// non-null, then this function will use the specified type if it has to
+/// create it (this occurs when we see a definition of the function).
+llvm::Constant *CodeGenModule::GetAddrOfFunction(GlobalDecl GD,
+                                                 const llvm::Type *Ty) {
+  // If there was no specific requested type, just convert it now.
+  if (!Ty)
+    Ty = getTypes().ConvertType(cast<ValueDecl>(GD.getDecl())->getType());
+  MangleBuffer MangledName;
+  getMangledName(MangledName, GD);
+  return GetOrCreateLLVMFunction(MangledName, Ty, GD);
+}
+
+/// CreateRuntimeFunction - Create a new runtime function with the specified
+/// type and name.
+llvm::Constant *
+CodeGenModule::CreateRuntimeFunction(const llvm::FunctionType *FTy,
+                                     llvm::StringRef Name) {
+  return GetOrCreateLLVMFunction(Name, FTy, GlobalDecl());
+}
+
+static bool DeclIsConstantGlobal(ASTContext &Context, const VarDecl *D) {
+  if (!D->getType().isConstant(Context) && !D->getType()->isReferenceType())
+    return false;
+  if (Context.getLangOptions().CPlusPlus &&
+      Context.getBaseElementType(D->getType())->getAs<RecordType>()) {
+    // FIXME: We should do something fancier here!
+    return false;
+  }
+  return true;
+}
+
+/// GetOrCreateLLVMGlobal - If the specified mangled name is not in the module,
+/// create and return an llvm GlobalVariable with the specified type.  If there
+/// is something in the module with the specified name, return it potentially
+/// bitcasted to the right type.
+///
+/// If D is non-null, it specifies a decl that correspond to this.  This is used
+/// to set the attributes on the global when it is first created.
+llvm::Constant *
+CodeGenModule::GetOrCreateLLVMGlobal(llvm::StringRef MangledName,
+                                     const llvm::PointerType *Ty,
+                                     const VarDecl *D) {
+  // Lookup the entry, lazily creating it if necessary.
+  llvm::GlobalValue *Entry = GetGlobalValue(MangledName);
+  if (Entry) {
+    if (WeakRefReferences.count(Entry)) {
+      if (D && !D->hasAttr<WeakAttr>())
+        Entry->setLinkage(llvm::Function::ExternalLinkage);
+
+      WeakRefReferences.erase(Entry);
+    }
+
+    if (Entry->getType() == Ty)
+      return Entry;
+
+    // Make sure the result is of the correct type.
+    return llvm::ConstantExpr::getBitCast(Entry, Ty);
+  }
+
+  // This is the first use or definition of a mangled name.  If there is a
+  // deferred decl with this name, remember that we need to emit it at the end
+  // of the file.
+  llvm::StringMap<GlobalDecl>::iterator DDI = DeferredDecls.find(MangledName);
+  if (DDI != DeferredDecls.end()) {
+    // Move the potentially referenced deferred decl to the DeferredDeclsToEmit
+    // list, and remove it from DeferredDecls (since we don't need it anymore).
+    DeferredDeclsToEmit.push_back(DDI->second);
+    DeferredDecls.erase(DDI);
+  }
+
+  llvm::GlobalVariable *GV =
+    new llvm::GlobalVariable(getModule(), Ty->getElementType(), false,
+                             llvm::GlobalValue::ExternalLinkage,
+                             0, MangledName, 0,
+                             false, Ty->getAddressSpace());
+
+  // Handle things which are present even on external declarations.
+  if (D) {
+    // FIXME: This code is overly simple and should be merged with other global
+    // handling.
+    GV->setConstant(DeclIsConstantGlobal(Context, D));
+
+    // FIXME: Merge with other attribute handling code.
+    if (D->getStorageClass() == VarDecl::PrivateExtern)
+      GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
+
+    if (D->hasAttr<WeakAttr>() ||
+        D->hasAttr<WeakImportAttr>())
+      GV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
+
+    GV->setThreadLocal(D->isThreadSpecified());
+  }
+
+  return GV;
+}
+
+
+/// GetAddrOfGlobalVar - Return the llvm::Constant for the address of the
+/// given global variable.  If Ty is non-null and if the global doesn't exist,
+/// then it will be greated with the specified type instead of whatever the
+/// normal requested type would be.
+llvm::Constant *CodeGenModule::GetAddrOfGlobalVar(const VarDecl *D,
+                                                  const llvm::Type *Ty) {
+  assert(D->hasGlobalStorage() && "Not a global variable");
+  QualType ASTTy = D->getType();
+  if (Ty == 0)
+    Ty = getTypes().ConvertTypeForMem(ASTTy);
+
+  const llvm::PointerType *PTy =
+    llvm::PointerType::get(Ty, ASTTy.getAddressSpace());
+
+  MangleBuffer MangledName;
+  getMangledName(MangledName, D);
+  return GetOrCreateLLVMGlobal(MangledName, PTy, D);
+}
+
+/// CreateRuntimeVariable - Create a new runtime global variable with the
+/// specified type and name.
+llvm::Constant *
+CodeGenModule::CreateRuntimeVariable(const llvm::Type *Ty,
+                                     llvm::StringRef Name) {
+  return GetOrCreateLLVMGlobal(Name, llvm::PointerType::getUnqual(Ty), 0);
+}
+
+void CodeGenModule::EmitTentativeDefinition(const VarDecl *D) {
+  assert(!D->getInit() && "Cannot emit definite definitions here!");
+
+  if (MayDeferGeneration(D)) {
+    // If we have not seen a reference to this variable yet, place it
+    // into the deferred declarations table to be emitted if needed
+    // later.
+    MangleBuffer MangledName;
+    getMangledName(MangledName, D);
+    if (!GetGlobalValue(MangledName)) {
+      DeferredDecls[MangledName] = D;
+      return;
+    }
+  }
+
+  // The tentative definition is the only definition.
+  EmitGlobalVarDefinition(D);
+}
+
+llvm::GlobalVariable::LinkageTypes 
+CodeGenModule::getVTableLinkage(const CXXRecordDecl *RD) {
+  if (RD->isInAnonymousNamespace() || !RD->hasLinkage())
+    return llvm::GlobalVariable::InternalLinkage;
+
+  if (const CXXMethodDecl *KeyFunction
+                                    = RD->getASTContext().getKeyFunction(RD)) {
+    // If this class has a key function, use that to determine the linkage of
+    // the vtable.
+    const FunctionDecl *Def = 0;
+    if (KeyFunction->getBody(Def))
+      KeyFunction = cast<CXXMethodDecl>(Def);
+    
+    switch (KeyFunction->getTemplateSpecializationKind()) {
+      case TSK_Undeclared:
+      case TSK_ExplicitSpecialization:
+        if (KeyFunction->isInlined())
+          return llvm::GlobalVariable::WeakODRLinkage;
+        
+        return llvm::GlobalVariable::ExternalLinkage;
+        
+      case TSK_ImplicitInstantiation:
+      case TSK_ExplicitInstantiationDefinition:
+        return llvm::GlobalVariable::WeakODRLinkage;
+        
+      case TSK_ExplicitInstantiationDeclaration:
+        // FIXME: Use available_externally linkage. However, this currently
+        // breaks LLVM's build due to undefined symbols.
+        //      return llvm::GlobalVariable::AvailableExternallyLinkage;
+        return llvm::GlobalVariable::WeakODRLinkage;
+    }
+  }
+  
+  switch (RD->getTemplateSpecializationKind()) {
+  case TSK_Undeclared:
+  case TSK_ExplicitSpecialization:
+  case TSK_ImplicitInstantiation:
+  case TSK_ExplicitInstantiationDefinition:
+    return llvm::GlobalVariable::WeakODRLinkage;
+    
+  case TSK_ExplicitInstantiationDeclaration:
+    // FIXME: Use available_externally linkage. However, this currently
+    // breaks LLVM's build due to undefined symbols.
+    //   return llvm::GlobalVariable::AvailableExternallyLinkage;
+    return llvm::GlobalVariable::WeakODRLinkage;
+  }
+  
+  // Silence GCC warning.
+  return llvm::GlobalVariable::WeakODRLinkage;
+}
+
+static CodeGenModule::GVALinkage
+GetLinkageForVariable(ASTContext &Context, const VarDecl *VD) {
+  // If this is a static data member, compute the kind of template
+  // specialization. Otherwise, this variable is not part of a
+  // template.
+  TemplateSpecializationKind TSK = TSK_Undeclared;
+  if (VD->isStaticDataMember())
+    TSK = VD->getTemplateSpecializationKind();
+
+  Linkage L = VD->getLinkage();
+  if (L == ExternalLinkage && Context.getLangOptions().CPlusPlus &&
+      VD->getType()->getLinkage() == UniqueExternalLinkage)
+    L = UniqueExternalLinkage;
+
+  switch (L) {
+  case NoLinkage:
+  case InternalLinkage:
+  case UniqueExternalLinkage:
+    return CodeGenModule::GVA_Internal;
+
+  case ExternalLinkage:
+    switch (TSK) {
+    case TSK_Undeclared:
+    case TSK_ExplicitSpecialization:
+      return CodeGenModule::GVA_StrongExternal;
+
+    case TSK_ExplicitInstantiationDeclaration:
+      llvm_unreachable("Variable should not be instantiated");
+      // Fall through to treat this like any other instantiation.
+        
+    case TSK_ExplicitInstantiationDefinition:
+      return CodeGenModule::GVA_ExplicitTemplateInstantiation;
+
+    case TSK_ImplicitInstantiation:
+      return CodeGenModule::GVA_TemplateInstantiation;      
+    }
+  }
+
+  return CodeGenModule::GVA_StrongExternal;
+}
+
+CharUnits CodeGenModule::GetTargetTypeStoreSize(const llvm::Type *Ty) const {
+    return CharUnits::fromQuantity(
+      TheTargetData.getTypeStoreSizeInBits(Ty) / Context.getCharWidth());
+}
+
+void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) {
+  llvm::Constant *Init = 0;
+  QualType ASTTy = D->getType();
+  bool NonConstInit = false;
+
+  const Expr *InitExpr = D->getAnyInitializer();
+  
+  if (!InitExpr) {
+    // This is a tentative definition; tentative definitions are
+    // implicitly initialized with { 0 }.
+    //
+    // Note that tentative definitions are only emitted at the end of
+    // a translation unit, so they should never have incomplete
+    // type. In addition, EmitTentativeDefinition makes sure that we
+    // never attempt to emit a tentative definition if a real one
+    // exists. A use may still exists, however, so we still may need
+    // to do a RAUW.
+    assert(!ASTTy->isIncompleteType() && "Unexpected incomplete type");
+    Init = EmitNullConstant(D->getType());
+  } else {
+    Init = EmitConstantExpr(InitExpr, D->getType());
+
+    if (!Init) {
+      QualType T = InitExpr->getType();
+      if (getLangOptions().CPlusPlus) {
+        EmitCXXGlobalVarDeclInitFunc(D);
+        Init = EmitNullConstant(T);
+        NonConstInit = true;
+      } else {
+        ErrorUnsupported(D, "static initializer");
+        Init = llvm::UndefValue::get(getTypes().ConvertType(T));
+      }
+    }
+  }
+
+  const llvm::Type* InitType = Init->getType();
+  llvm::Constant *Entry = GetAddrOfGlobalVar(D, InitType);
+
+  // Strip off a bitcast if we got one back.
+  if (llvm::ConstantExpr *CE = dyn_cast<llvm::ConstantExpr>(Entry)) {
+    assert(CE->getOpcode() == llvm::Instruction::BitCast ||
+           // all zero index gep.
+           CE->getOpcode() == llvm::Instruction::GetElementPtr);
+    Entry = CE->getOperand(0);
+  }
+
+  // Entry is now either a Function or GlobalVariable.
+  llvm::GlobalVariable *GV = dyn_cast<llvm::GlobalVariable>(Entry);
+
+  // We have a definition after a declaration with the wrong type.
+  // We must make a new GlobalVariable* and update everything that used OldGV
+  // (a declaration or tentative definition) with the new GlobalVariable*
+  // (which will be a definition).
+  //
+  // This happens if there is a prototype for a global (e.g.
+  // "extern int x[];") and then a definition of a different type (e.g.
+  // "int x[10];"). This also happens when an initializer has a different type
+  // from the type of the global (this happens with unions).
+  if (GV == 0 ||
+      GV->getType()->getElementType() != InitType ||
+      GV->getType()->getAddressSpace() != ASTTy.getAddressSpace()) {
+
+    // Move the old entry aside so that we'll create a new one.
+    Entry->setName(llvm::StringRef());
+
+    // Make a new global with the correct type, this is now guaranteed to work.
+    GV = cast<llvm::GlobalVariable>(GetAddrOfGlobalVar(D, InitType));
+
+    // Replace all uses of the old global with the new global
+    llvm::Constant *NewPtrForOldDecl =
+        llvm::ConstantExpr::getBitCast(GV, Entry->getType());
+    Entry->replaceAllUsesWith(NewPtrForOldDecl);
+
+    // Erase the old global, since it is no longer used.
+    cast<llvm::GlobalValue>(Entry)->eraseFromParent();
+  }
+
+  if (const AnnotateAttr *AA = D->getAttr<AnnotateAttr>()) {
+    SourceManager &SM = Context.getSourceManager();
+    AddAnnotation(EmitAnnotateAttr(GV, AA,
+                              SM.getInstantiationLineNumber(D->getLocation())));
+  }
+
+  GV->setInitializer(Init);
+
+  // If it is safe to mark the global 'constant', do so now.
+  GV->setConstant(false);
+  if (!NonConstInit && DeclIsConstantGlobal(Context, D))
+    GV->setConstant(true);
+
+  GV->setAlignment(getContext().getDeclAlign(D).getQuantity());
+
+  // Set the llvm linkage type as appropriate.
+  GVALinkage Linkage = GetLinkageForVariable(getContext(), D);
+  if (Linkage == GVA_Internal)
+    GV->setLinkage(llvm::Function::InternalLinkage);
+  else if (D->hasAttr<DLLImportAttr>())
+    GV->setLinkage(llvm::Function::DLLImportLinkage);
+  else if (D->hasAttr<DLLExportAttr>())
+    GV->setLinkage(llvm::Function::DLLExportLinkage);
+  else if (D->hasAttr<WeakAttr>()) {
+    if (GV->isConstant())
+      GV->setLinkage(llvm::GlobalVariable::WeakODRLinkage);
+    else
+      GV->setLinkage(llvm::GlobalVariable::WeakAnyLinkage);
+  } else if (Linkage == GVA_TemplateInstantiation ||
+             Linkage == GVA_ExplicitTemplateInstantiation)
+    // FIXME: It seems like we can provide more specific linkage here
+    // (LinkOnceODR, WeakODR).
+    GV->setLinkage(llvm::GlobalVariable::WeakAnyLinkage);   
+  else if (!getLangOptions().CPlusPlus && !CodeGenOpts.NoCommon &&
+           !D->hasExternalStorage() && !D->getInit() &&
+           !D->getAttr<SectionAttr>()) {
+    GV->setLinkage(llvm::GlobalVariable::CommonLinkage);
+    // common vars aren't constant even if declared const.
+    GV->setConstant(false);
+  } else
+    GV->setLinkage(llvm::GlobalVariable::ExternalLinkage);
+
+  SetCommonAttributes(D, GV);
+
+  // Emit global variable debug information.
+  if (CGDebugInfo *DI = getDebugInfo()) {
+    DI->setLocation(D->getLocation());
+    DI->EmitGlobalVariable(GV, D);
+  }
+}
+
+/// ReplaceUsesOfNonProtoTypeWithRealFunction - This function is called when we
+/// implement a function with no prototype, e.g. "int foo() {}".  If there are
+/// existing call uses of the old function in the module, this adjusts them to
+/// call the new function directly.
+///
+/// This is not just a cleanup: the always_inline pass requires direct calls to
+/// functions to be able to inline them.  If there is a bitcast in the way, it
+/// won't inline them.  Instcombine normally deletes these calls, but it isn't
+/// run at -O0.
+static void ReplaceUsesOfNonProtoTypeWithRealFunction(llvm::GlobalValue *Old,
+                                                      llvm::Function *NewFn) {
+  // If we're redefining a global as a function, don't transform it.
+  llvm::Function *OldFn = dyn_cast<llvm::Function>(Old);
+  if (OldFn == 0) return;
+
+  const llvm::Type *NewRetTy = NewFn->getReturnType();
+  llvm::SmallVector<llvm::Value*, 4> ArgList;
+
+  for (llvm::Value::use_iterator UI = OldFn->use_begin(), E = OldFn->use_end();
+       UI != E; ) {
+    // TODO: Do invokes ever occur in C code?  If so, we should handle them too.
+    llvm::Value::use_iterator I = UI++; // Increment before the CI is erased.
+    llvm::CallInst *CI = dyn_cast<llvm::CallInst>(*I);
+    llvm::CallSite CS(CI);
+    if (!CI || !CS.isCallee(I)) continue;
+
+    // If the return types don't match exactly, and if the call isn't dead, then
+    // we can't transform this call.
+    if (CI->getType() != NewRetTy && !CI->use_empty())
+      continue;
+
+    // If the function was passed too few arguments, don't transform.  If extra
+    // arguments were passed, we silently drop them.  If any of the types
+    // mismatch, we don't transform.
+    unsigned ArgNo = 0;
+    bool DontTransform = false;
+    for (llvm::Function::arg_iterator AI = NewFn->arg_begin(),
+         E = NewFn->arg_end(); AI != E; ++AI, ++ArgNo) {
+      if (CS.arg_size() == ArgNo ||
+          CS.getArgument(ArgNo)->getType() != AI->getType()) {
+        DontTransform = true;
+        break;
+      }
+    }
+    if (DontTransform)
+      continue;
+
+    // Okay, we can transform this.  Create the new call instruction and copy
+    // over the required information.
+    ArgList.append(CS.arg_begin(), CS.arg_begin() + ArgNo);
+    llvm::CallInst *NewCall = llvm::CallInst::Create(NewFn, ArgList.begin(),
+                                                     ArgList.end(), "", CI);
+    ArgList.clear();
+    if (!NewCall->getType()->isVoidTy())
+      NewCall->takeName(CI);
+    NewCall->setAttributes(CI->getAttributes());
+    NewCall->setCallingConv(CI->getCallingConv());
+
+    // Finally, remove the old call, replacing any uses with the new one.
+    if (!CI->use_empty())
+      CI->replaceAllUsesWith(NewCall);
+
+    // Copy debug location attached to CI.
+    if (!CI->getDebugLoc().isUnknown())
+      NewCall->setDebugLoc(CI->getDebugLoc());
+    CI->eraseFromParent();
+  }
+}
+
+
+void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD) {
+  const FunctionDecl *D = cast<FunctionDecl>(GD.getDecl());
+  const llvm::FunctionType *Ty = getTypes().GetFunctionType(GD);
+  getMangleContext().mangleInitDiscriminator();
+  // Get or create the prototype for the function.
+  llvm::Constant *Entry = GetAddrOfFunction(GD, Ty);
+
+  // Strip off a bitcast if we got one back.
+  if (llvm::ConstantExpr *CE = dyn_cast<llvm::ConstantExpr>(Entry)) {
+    assert(CE->getOpcode() == llvm::Instruction::BitCast);
+    Entry = CE->getOperand(0);
+  }
+
+
+  if (cast<llvm::GlobalValue>(Entry)->getType()->getElementType() != Ty) {
+    llvm::GlobalValue *OldFn = cast<llvm::GlobalValue>(Entry);
+
+    // If the types mismatch then we have to rewrite the definition.
+    assert(OldFn->isDeclaration() &&
+           "Shouldn't replace non-declaration");
+
+    // F is the Function* for the one with the wrong type, we must make a new
+    // Function* and update everything that used F (a declaration) with the new
+    // Function* (which will be a definition).
+    //
+    // This happens if there is a prototype for a function
+    // (e.g. "int f()") and then a definition of a different type
+    // (e.g. "int f(int x)").  Move the old function aside so that it
+    // doesn't interfere with GetAddrOfFunction.
+    OldFn->setName(llvm::StringRef());
+    llvm::Function *NewFn = cast<llvm::Function>(GetAddrOfFunction(GD, Ty));
+
+    // If this is an implementation of a function without a prototype, try to
+    // replace any existing uses of the function (which may be calls) with uses
+    // of the new function
+    if (D->getType()->isFunctionNoProtoType()) {
+      ReplaceUsesOfNonProtoTypeWithRealFunction(OldFn, NewFn);
+      OldFn->removeDeadConstantUsers();
+    }
+
+    // Replace uses of F with the Function we will endow with a body.
+    if (!Entry->use_empty()) {
+      llvm::Constant *NewPtrForOldDecl =
+        llvm::ConstantExpr::getBitCast(NewFn, Entry->getType());
+      Entry->replaceAllUsesWith(NewPtrForOldDecl);
+    }
+
+    // Ok, delete the old function now, which is dead.
+    OldFn->eraseFromParent();
+
+    Entry = NewFn;
+  }
+
+  llvm::Function *Fn = cast<llvm::Function>(Entry);
+
+  CodeGenFunction(*this).GenerateCode(D, Fn);
+
+  SetFunctionDefinitionAttributes(D, Fn);
+  SetLLVMFunctionAttributesForDefinition(D, Fn);
+
+  if (const ConstructorAttr *CA = D->getAttr<ConstructorAttr>())
+    AddGlobalCtor(Fn, CA->getPriority());
+  if (const DestructorAttr *DA = D->getAttr<DestructorAttr>())
+    AddGlobalDtor(Fn, DA->getPriority());
+}
+
+void CodeGenModule::EmitAliasDefinition(GlobalDecl GD) {
+  const ValueDecl *D = cast<ValueDecl>(GD.getDecl());
+  const AliasAttr *AA = D->getAttr<AliasAttr>();
+  assert(AA && "Not an alias?");
+
+  MangleBuffer MangledName;
+  getMangledName(MangledName, GD);
+
+  // If there is a definition in the module, then it wins over the alias.
+  // This is dubious, but allow it to be safe.  Just ignore the alias.
+  llvm::GlobalValue *Entry = GetGlobalValue(MangledName);
+  if (Entry && !Entry->isDeclaration())
+    return;
+
+  const llvm::Type *DeclTy = getTypes().ConvertTypeForMem(D->getType());
+
+  // Create a reference to the named value.  This ensures that it is emitted
+  // if a deferred decl.
+  llvm::Constant *Aliasee;
+  if (isa<llvm::FunctionType>(DeclTy))
+    Aliasee = GetOrCreateLLVMFunction(AA->getAliasee(), DeclTy, GlobalDecl());
+  else
+    Aliasee = GetOrCreateLLVMGlobal(AA->getAliasee(),
+                                    llvm::PointerType::getUnqual(DeclTy), 0);
+
+  // Create the new alias itself, but don't set a name yet.
+  llvm::GlobalValue *GA =
+    new llvm::GlobalAlias(Aliasee->getType(),
+                          llvm::Function::ExternalLinkage,
+                          "", Aliasee, &getModule());
+
+  if (Entry) {
+    assert(Entry->isDeclaration());
+
+    // If there is a declaration in the module, then we had an extern followed
+    // by the alias, as in:
+    //   extern int test6();
+    //   ...
+    //   int test6() __attribute__((alias("test7")));
+    //
+    // Remove it and replace uses of it with the alias.
+    GA->takeName(Entry);
+
+    Entry->replaceAllUsesWith(llvm::ConstantExpr::getBitCast(GA,
+                                                          Entry->getType()));
+    Entry->eraseFromParent();
+  } else {
+    GA->setName(MangledName.getString());
+  }
+
+  // Set attributes which are particular to an alias; this is a
+  // specialization of the attributes which may be set on a global
+  // variable/function.
+  if (D->hasAttr<DLLExportAttr>()) {
+    if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+      // The dllexport attribute is ignored for undefined symbols.
+      if (FD->getBody())
+        GA->setLinkage(llvm::Function::DLLExportLinkage);
+    } else {
+      GA->setLinkage(llvm::Function::DLLExportLinkage);
+    }
+  } else if (D->hasAttr<WeakAttr>() ||
+             D->hasAttr<WeakRefAttr>() ||
+             D->hasAttr<WeakImportAttr>()) {
+    GA->setLinkage(llvm::Function::WeakAnyLinkage);
+  }
+
+  SetCommonAttributes(D, GA);
+}
+
+/// getBuiltinLibFunction - Given a builtin id for a function like
+/// "__builtin_fabsf", return a Function* for "fabsf".
+llvm::Value *CodeGenModule::getBuiltinLibFunction(const FunctionDecl *FD,
+                                                  unsigned BuiltinID) {
+  assert((Context.BuiltinInfo.isLibFunction(BuiltinID) ||
+          Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID)) &&
+         "isn't a lib fn");
+
+  // Get the name, skip over the __builtin_ prefix (if necessary).
+  const char *Name = Context.BuiltinInfo.GetName(BuiltinID);
+  if (Context.BuiltinInfo.isLibFunction(BuiltinID))
+    Name += 10;
+
+  const llvm::FunctionType *Ty =
+    cast<llvm::FunctionType>(getTypes().ConvertType(FD->getType()));
+
+  return GetOrCreateLLVMFunction(Name, Ty, GlobalDecl(FD));
+}
+
+llvm::Function *CodeGenModule::getIntrinsic(unsigned IID,const llvm::Type **Tys,
+                                            unsigned NumTys) {
+  return llvm::Intrinsic::getDeclaration(&getModule(),
+                                         (llvm::Intrinsic::ID)IID, Tys, NumTys);
+}
+
+
+llvm::Function *CodeGenModule::getMemCpyFn(const llvm::Type *DestType,
+                                           const llvm::Type *SrcType,
+                                           const llvm::Type *SizeType) {
+  const llvm::Type *ArgTypes[3] = {DestType, SrcType, SizeType };
+  return getIntrinsic(llvm::Intrinsic::memcpy, ArgTypes, 3);
+}
+
+llvm::Function *CodeGenModule::getMemMoveFn(const llvm::Type *DestType,
+                                            const llvm::Type *SrcType,
+                                            const llvm::Type *SizeType) {
+  const llvm::Type *ArgTypes[3] = {DestType, SrcType, SizeType };
+  return getIntrinsic(llvm::Intrinsic::memmove, ArgTypes, 3);
+}
+
+llvm::Function *CodeGenModule::getMemSetFn(const llvm::Type *DestType,
+                                           const llvm::Type *SizeType) {
+  const llvm::Type *ArgTypes[2] = { DestType, SizeType };
+  return getIntrinsic(llvm::Intrinsic::memset, ArgTypes, 2);
+}
+
+static llvm::StringMapEntry<llvm::Constant*> &
+GetConstantCFStringEntry(llvm::StringMap<llvm::Constant*> &Map,
+                         const StringLiteral *Literal,
+                         bool TargetIsLSB,
+                         bool &IsUTF16,
+                         unsigned &StringLength) {
+  unsigned NumBytes = Literal->getByteLength();
+
+  // Check for simple case.
+  if (!Literal->containsNonAsciiOrNull()) {
+    StringLength = NumBytes;
+    return Map.GetOrCreateValue(llvm::StringRef(Literal->getStrData(),
+                                                StringLength));
+  }
+
+  // Otherwise, convert the UTF8 literals into a byte string.
+  llvm::SmallVector<UTF16, 128> ToBuf(NumBytes);
+  const UTF8 *FromPtr = (UTF8 *)Literal->getStrData();
+  UTF16 *ToPtr = &ToBuf[0];
+
+  ConversionResult Result = ConvertUTF8toUTF16(&FromPtr, FromPtr + NumBytes,
+                                               &ToPtr, ToPtr + NumBytes,
+                                               strictConversion);
+
+  // Check for conversion failure.
+  if (Result != conversionOK) {
+    // FIXME: Have Sema::CheckObjCString() validate the UTF-8 string and remove
+    // this duplicate code.
+    assert(Result == sourceIllegal && "UTF-8 to UTF-16 conversion failed");
+    StringLength = NumBytes;
+    return Map.GetOrCreateValue(llvm::StringRef(Literal->getStrData(),
+                                                StringLength));
+  }
+
+  // ConvertUTF8toUTF16 returns the length in ToPtr.
+  StringLength = ToPtr - &ToBuf[0];
+
+  // Render the UTF-16 string into a byte array and convert to the target byte
+  // order.
+  //
+  // FIXME: This isn't something we should need to do here.
+  llvm::SmallString<128> AsBytes;
+  AsBytes.reserve(StringLength * 2);
+  for (unsigned i = 0; i != StringLength; ++i) {
+    unsigned short Val = ToBuf[i];
+    if (TargetIsLSB) {
+      AsBytes.push_back(Val & 0xFF);
+      AsBytes.push_back(Val >> 8);
+    } else {
+      AsBytes.push_back(Val >> 8);
+      AsBytes.push_back(Val & 0xFF);
+    }
+  }
+  // Append one extra null character, the second is automatically added by our
+  // caller.
+  AsBytes.push_back(0);
+
+  IsUTF16 = true;
+  return Map.GetOrCreateValue(llvm::StringRef(AsBytes.data(), AsBytes.size()));
+}
+
+llvm::Constant *
+CodeGenModule::GetAddrOfConstantCFString(const StringLiteral *Literal) {
+  unsigned StringLength = 0;
+  bool isUTF16 = false;
+  llvm::StringMapEntry<llvm::Constant*> &Entry =
+    GetConstantCFStringEntry(CFConstantStringMap, Literal,
+                             getTargetData().isLittleEndian(),
+                             isUTF16, StringLength);
+
+  if (llvm::Constant *C = Entry.getValue())
+    return C;
+
+  llvm::Constant *Zero =
+      llvm::Constant::getNullValue(llvm::Type::getInt32Ty(VMContext));
+  llvm::Constant *Zeros[] = { Zero, Zero };
+
+  // If we don't already have it, get __CFConstantStringClassReference.
+  if (!CFConstantStringClassRef) {
+    const llvm::Type *Ty = getTypes().ConvertType(getContext().IntTy);
+    Ty = llvm::ArrayType::get(Ty, 0);
+    llvm::Constant *GV = CreateRuntimeVariable(Ty,
+                                           "__CFConstantStringClassReference");
+    // Decay array -> ptr
+    CFConstantStringClassRef =
+      llvm::ConstantExpr::getGetElementPtr(GV, Zeros, 2);
+  }
+
+  QualType CFTy = getContext().getCFConstantStringType();
+
+  const llvm::StructType *STy =
+    cast<llvm::StructType>(getTypes().ConvertType(CFTy));
+
+  std::vector<llvm::Constant*> Fields(4);
+
+  // Class pointer.
+  Fields[0] = CFConstantStringClassRef;
+
+  // Flags.
+  const llvm::Type *Ty = getTypes().ConvertType(getContext().UnsignedIntTy);
+  Fields[1] = isUTF16 ? llvm::ConstantInt::get(Ty, 0x07d0) :
+    llvm::ConstantInt::get(Ty, 0x07C8);
+
+  // String pointer.
+  llvm::Constant *C = llvm::ConstantArray::get(VMContext, Entry.getKey().str());
+
+  llvm::GlobalValue::LinkageTypes Linkage;
+  bool isConstant;
+  if (isUTF16) {
+    // FIXME: why do utf strings get "_" labels instead of "L" labels?
+    Linkage = llvm::GlobalValue::InternalLinkage;
+    // Note: -fwritable-strings doesn't make unicode CFStrings writable, but
+    // does make plain ascii ones writable.
+    isConstant = true;
+  } else {
+    Linkage = llvm::GlobalValue::PrivateLinkage;
+    isConstant = !Features.WritableStrings;
+  }
+  
+  llvm::GlobalVariable *GV =
+    new llvm::GlobalVariable(getModule(), C->getType(), isConstant, Linkage, C,
+                             ".str");
+  if (isUTF16) {
+    CharUnits Align = getContext().getTypeAlignInChars(getContext().ShortTy);
+    GV->setAlignment(Align.getQuantity());
+  }
+  Fields[2] = llvm::ConstantExpr::getGetElementPtr(GV, Zeros, 2);
+
+  // String length.
+  Ty = getTypes().ConvertType(getContext().LongTy);
+  Fields[3] = llvm::ConstantInt::get(Ty, StringLength);
+
+  // The struct.
+  C = llvm::ConstantStruct::get(STy, Fields);
+  GV = new llvm::GlobalVariable(getModule(), C->getType(), true,
+                                llvm::GlobalVariable::PrivateLinkage, C,
+                                "_unnamed_cfstring_");
+  if (const char *Sect = getContext().Target.getCFStringSection())
+    GV->setSection(Sect);
+  Entry.setValue(GV);
+
+  return GV;
+}
+
+llvm::Constant *
+CodeGenModule::GetAddrOfConstantNSString(const StringLiteral *Literal) {
+  unsigned StringLength = 0;
+  bool isUTF16 = false;
+  llvm::StringMapEntry<llvm::Constant*> &Entry =
+    GetConstantCFStringEntry(CFConstantStringMap, Literal,
+                             getTargetData().isLittleEndian(),
+                             isUTF16, StringLength);
+  
+  if (llvm::Constant *C = Entry.getValue())
+    return C;
+  
+  llvm::Constant *Zero =
+  llvm::Constant::getNullValue(llvm::Type::getInt32Ty(VMContext));
+  llvm::Constant *Zeros[] = { Zero, Zero };
+  
+  // If we don't already have it, get _NSConstantStringClassReference.
+  if (!NSConstantStringClassRef) {
+    const llvm::Type *Ty = getTypes().ConvertType(getContext().IntTy);
+    Ty = llvm::ArrayType::get(Ty, 0);
+    llvm::Constant *GV = CreateRuntimeVariable(Ty, 
+                                        Features.ObjCNonFragileABI ?
+                                        "OBJC_CLASS_$_NSConstantString" :
+                                        "_NSConstantStringClassReference");
+    // Decay array -> ptr
+    NSConstantStringClassRef = 
+      llvm::ConstantExpr::getGetElementPtr(GV, Zeros, 2);
+  }
+  
+  QualType NSTy = getContext().getNSConstantStringType();
+  
+  const llvm::StructType *STy =
+  cast<llvm::StructType>(getTypes().ConvertType(NSTy));
+  
+  std::vector<llvm::Constant*> Fields(3);
+  
+  // Class pointer.
+  Fields[0] = NSConstantStringClassRef;
+  
+  // String pointer.
+  llvm::Constant *C = llvm::ConstantArray::get(VMContext, Entry.getKey().str());
+  
+  llvm::GlobalValue::LinkageTypes Linkage;
+  bool isConstant;
+  if (isUTF16) {
+    // FIXME: why do utf strings get "_" labels instead of "L" labels?
+    Linkage = llvm::GlobalValue::InternalLinkage;
+    // Note: -fwritable-strings doesn't make unicode NSStrings writable, but
+    // does make plain ascii ones writable.
+    isConstant = true;
+  } else {
+    Linkage = llvm::GlobalValue::PrivateLinkage;
+    isConstant = !Features.WritableStrings;
+  }
+  
+  llvm::GlobalVariable *GV =
+  new llvm::GlobalVariable(getModule(), C->getType(), isConstant, Linkage, C,
+                           ".str");
+  if (isUTF16) {
+    CharUnits Align = getContext().getTypeAlignInChars(getContext().ShortTy);
+    GV->setAlignment(Align.getQuantity());
+  }
+  Fields[1] = llvm::ConstantExpr::getGetElementPtr(GV, Zeros, 2);
+  
+  // String length.
+  const llvm::Type *Ty = getTypes().ConvertType(getContext().UnsignedIntTy);
+  Fields[2] = llvm::ConstantInt::get(Ty, StringLength);
+  
+  // The struct.
+  C = llvm::ConstantStruct::get(STy, Fields);
+  GV = new llvm::GlobalVariable(getModule(), C->getType(), true,
+                                llvm::GlobalVariable::PrivateLinkage, C,
+                                "_unnamed_nsstring_");
+  // FIXME. Fix section.
+  if (const char *Sect = 
+        Features.ObjCNonFragileABI 
+          ? getContext().Target.getNSStringNonFragileABISection() 
+          : getContext().Target.getNSStringSection())
+    GV->setSection(Sect);
+  Entry.setValue(GV);
+  
+  return GV;
+}
+
+/// GetStringForStringLiteral - Return the appropriate bytes for a
+/// string literal, properly padded to match the literal type.
+std::string CodeGenModule::GetStringForStringLiteral(const StringLiteral *E) {
+  const char *StrData = E->getStrData();
+  unsigned Len = E->getByteLength();
+
+  const ConstantArrayType *CAT =
+    getContext().getAsConstantArrayType(E->getType());
+  assert(CAT && "String isn't pointer or array!");
+
+  // Resize the string to the right size.
+  std::string Str(StrData, StrData+Len);
+  uint64_t RealLen = CAT->getSize().getZExtValue();
+
+  if (E->isWide())
+    RealLen *= getContext().Target.getWCharWidth()/8;
+
+  Str.resize(RealLen, '\0');
+
+  return Str;
+}
+
+/// GetAddrOfConstantStringFromLiteral - Return a pointer to a
+/// constant array for the given string literal.
+llvm::Constant *
+CodeGenModule::GetAddrOfConstantStringFromLiteral(const StringLiteral *S) {
+  // FIXME: This can be more efficient.
+  // FIXME: We shouldn't need to bitcast the constant in the wide string case.
+  llvm::Constant *C = GetAddrOfConstantString(GetStringForStringLiteral(S));
+  if (S->isWide()) {
+    llvm::Type *DestTy =
+        llvm::PointerType::getUnqual(getTypes().ConvertType(S->getType()));
+    C = llvm::ConstantExpr::getBitCast(C, DestTy);
+  }
+  return C;
+}
+
+/// GetAddrOfConstantStringFromObjCEncode - Return a pointer to a constant
+/// array for the given ObjCEncodeExpr node.
+llvm::Constant *
+CodeGenModule::GetAddrOfConstantStringFromObjCEncode(const ObjCEncodeExpr *E) {
+  std::string Str;
+  getContext().getObjCEncodingForType(E->getEncodedType(), Str);
+
+  return GetAddrOfConstantCString(Str);
+}
+
+
+/// GenerateWritableString -- Creates storage for a string literal.
+static llvm::Constant *GenerateStringLiteral(const std::string &str,
+                                             bool constant,
+                                             CodeGenModule &CGM,
+                                             const char *GlobalName) {
+  // Create Constant for this string literal. Don't add a '\0'.
+  llvm::Constant *C =
+      llvm::ConstantArray::get(CGM.getLLVMContext(), str, false);
+
+  // Create a global variable for this string
+  return new llvm::GlobalVariable(CGM.getModule(), C->getType(), constant,
+                                  llvm::GlobalValue::PrivateLinkage,
+                                  C, GlobalName);
+}
+
+/// GetAddrOfConstantString - Returns a pointer to a character array
+/// containing the literal. This contents are exactly that of the
+/// given string, i.e. it will not be null terminated automatically;
+/// see GetAddrOfConstantCString. Note that whether the result is
+/// actually a pointer to an LLVM constant depends on
+/// Feature.WriteableStrings.
+///
+/// The result has pointer to array type.
+llvm::Constant *CodeGenModule::GetAddrOfConstantString(const std::string &str,
+                                                       const char *GlobalName) {
+  bool IsConstant = !Features.WritableStrings;
+
+  // Get the default prefix if a name wasn't specified.
+  if (!GlobalName)
+    GlobalName = ".str";
+
+  // Don't share any string literals if strings aren't constant.
+  if (!IsConstant)
+    return GenerateStringLiteral(str, false, *this, GlobalName);
+
+  llvm::StringMapEntry<llvm::Constant *> &Entry =
+    ConstantStringMap.GetOrCreateValue(&str[0], &str[str.length()]);
+
+  if (Entry.getValue())
+    return Entry.getValue();
+
+  // Create a global variable for this.
+  llvm::Constant *C = GenerateStringLiteral(str, true, *this, GlobalName);
+  Entry.setValue(C);
+  return C;
+}
+
+/// GetAddrOfConstantCString - Returns a pointer to a character
+/// array containing the literal and a terminating '\-'
+/// character. The result has pointer to array type.
+llvm::Constant *CodeGenModule::GetAddrOfConstantCString(const std::string &str,
+                                                        const char *GlobalName){
+  return GetAddrOfConstantString(str + '\0', GlobalName);
+}
+
+/// EmitObjCPropertyImplementations - Emit information for synthesized
+/// properties for an implementation.
+void CodeGenModule::EmitObjCPropertyImplementations(const
+                                                    ObjCImplementationDecl *D) {
+  for (ObjCImplementationDecl::propimpl_iterator
+         i = D->propimpl_begin(), e = D->propimpl_end(); i != e; ++i) {
+    ObjCPropertyImplDecl *PID = *i;
+
+    // Dynamic is just for type-checking.
+    if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) {
+      ObjCPropertyDecl *PD = PID->getPropertyDecl();
+
+      // Determine which methods need to be implemented, some may have
+      // been overridden. Note that ::isSynthesized is not the method
+      // we want, that just indicates if the decl came from a
+      // property. What we want to know is if the method is defined in
+      // this implementation.
+      if (!D->getInstanceMethod(PD->getGetterName()))
+        CodeGenFunction(*this).GenerateObjCGetter(
+                                 const_cast<ObjCImplementationDecl *>(D), PID);
+      if (!PD->isReadOnly() &&
+          !D->getInstanceMethod(PD->getSetterName()))
+        CodeGenFunction(*this).GenerateObjCSetter(
+                                 const_cast<ObjCImplementationDecl *>(D), PID);
+    }
+  }
+}
+
+/// EmitNamespace - Emit all declarations in a namespace.
+void CodeGenModule::EmitNamespace(const NamespaceDecl *ND) {
+  for (RecordDecl::decl_iterator I = ND->decls_begin(), E = ND->decls_end();
+       I != E; ++I)
+    EmitTopLevelDecl(*I);
+}
+
+// EmitLinkageSpec - Emit all declarations in a linkage spec.
+void CodeGenModule::EmitLinkageSpec(const LinkageSpecDecl *LSD) {
+  if (LSD->getLanguage() != LinkageSpecDecl::lang_c &&
+      LSD->getLanguage() != LinkageSpecDecl::lang_cxx) {
+    ErrorUnsupported(LSD, "linkage spec");
+    return;
+  }
+
+  for (RecordDecl::decl_iterator I = LSD->decls_begin(), E = LSD->decls_end();
+       I != E; ++I)
+    EmitTopLevelDecl(*I);
+}
+
+/// EmitTopLevelDecl - Emit code for a single top level declaration.
+void CodeGenModule::EmitTopLevelDecl(Decl *D) {
+  // If an error has occurred, stop code generation, but continue
+  // parsing and semantic analysis (to ensure all warnings and errors
+  // are emitted).
+  if (Diags.hasErrorOccurred())
+    return;
+
+  // Ignore dependent declarations.
+  if (D->getDeclContext() && D->getDeclContext()->isDependentContext())
+    return;
+
+  switch (D->getKind()) {
+  case Decl::CXXConversion:
+  case Decl::CXXMethod:
+  case Decl::Function:
+    // Skip function templates
+    if (cast<FunctionDecl>(D)->getDescribedFunctionTemplate())
+      return;
+
+    EmitGlobal(cast<FunctionDecl>(D));
+    break;
+      
+  case Decl::Var:
+    EmitGlobal(cast<VarDecl>(D));
+    break;
+
+  // C++ Decls
+  case Decl::Namespace:
+    EmitNamespace(cast<NamespaceDecl>(D));
+    break;
+    // No code generation needed.
+  case Decl::UsingShadow:
+  case Decl::Using:
+  case Decl::UsingDirective:
+  case Decl::ClassTemplate:
+  case Decl::FunctionTemplate:
+  case Decl::NamespaceAlias:
+    break;
+  case Decl::CXXConstructor:
+    // Skip function templates
+    if (cast<FunctionDecl>(D)->getDescribedFunctionTemplate())
+      return;
+      
+    EmitCXXConstructors(cast<CXXConstructorDecl>(D));
+    break;
+  case Decl::CXXDestructor:
+    EmitCXXDestructors(cast<CXXDestructorDecl>(D));
+    break;
+
+  case Decl::StaticAssert:
+    // Nothing to do.
+    break;
+
+  // Objective-C Decls
+
+  // Forward declarations, no (immediate) code generation.
+  case Decl::ObjCClass:
+  case Decl::ObjCForwardProtocol:
+  case Decl::ObjCCategory:
+  case Decl::ObjCInterface:
+    break;
+
+  case Decl::ObjCProtocol:
+    Runtime->GenerateProtocol(cast<ObjCProtocolDecl>(D));
+    break;
+
+  case Decl::ObjCCategoryImpl:
+    // Categories have properties but don't support synthesize so we
+    // can ignore them here.
+    Runtime->GenerateCategory(cast<ObjCCategoryImplDecl>(D));
+    break;
+
+  case Decl::ObjCImplementation: {
+    ObjCImplementationDecl *OMD = cast<ObjCImplementationDecl>(D);
+    EmitObjCPropertyImplementations(OMD);
+    Runtime->GenerateClass(OMD);
+    break;
+  }
+  case Decl::ObjCMethod: {
+    ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(D);
+    // If this is not a prototype, emit the body.
+    if (OMD->getBody())
+      CodeGenFunction(*this).GenerateObjCMethod(OMD);
+    break;
+  }
+  case Decl::ObjCCompatibleAlias:
+    // compatibility-alias is a directive and has no code gen.
+    break;
+
+  case Decl::LinkageSpec:
+    EmitLinkageSpec(cast<LinkageSpecDecl>(D));
+    break;
+
+  case Decl::FileScopeAsm: {
+    FileScopeAsmDecl *AD = cast<FileScopeAsmDecl>(D);
+    llvm::StringRef AsmString = AD->getAsmString()->getString();
+
+    const std::string &S = getModule().getModuleInlineAsm();
+    if (S.empty())
+      getModule().setModuleInlineAsm(AsmString);
+    else
+      getModule().setModuleInlineAsm(S + '\n' + AsmString.str());
+    break;
+  }
+
+  default:
+    // Make sure we handled everything we should, every other kind is a
+    // non-top-level decl.  FIXME: Would be nice to have an isTopLevelDeclKind
+    // function. Need to recode Decl::Kind to do that easily.
+    assert(isa<TypeDecl>(D) && "Unsupported decl kind");
+  }
+}
diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h
new file mode 100644
index 0000000..b0abc49
--- /dev/null
+++ b/lib/CodeGen/CodeGenModule.h
@@ -0,0 +1,553 @@
+//===--- CodeGenModule.h - Per-Module state for LLVM CodeGen ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This is the internal per-translation-unit state used for llvm translation.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_CODEGEN_CODEGENMODULE_H
+#define CLANG_CODEGEN_CODEGENMODULE_H
+
+#include "clang/Basic/LangOptions.h"
+#include "clang/AST/Attr.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclObjC.h"
+#include "CGBlocks.h"
+#include "CGCall.h"
+#include "CGCXX.h"
+#include "CGVTables.h"
+#include "CodeGenTypes.h"
+#include "GlobalDecl.h"
+#include "Mangle.h"
+#include "llvm/Module.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringSet.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/Support/ValueHandle.h"
+
+namespace llvm {
+  class Module;
+  class Constant;
+  class Function;
+  class GlobalValue;
+  class TargetData;
+  class FunctionType;
+  class LLVMContext;
+}
+
+namespace clang {
+  class TargetCodeGenInfo;
+  class ASTContext;
+  class FunctionDecl;
+  class IdentifierInfo;
+  class ObjCMethodDecl;
+  class ObjCImplementationDecl;
+  class ObjCCategoryImplDecl;
+  class ObjCProtocolDecl;
+  class ObjCEncodeExpr;
+  class BlockExpr;
+  class CharUnits;
+  class Decl;
+  class Expr;
+  class Stmt;
+  class StringLiteral;
+  class NamedDecl;
+  class ValueDecl;
+  class VarDecl;
+  class LangOptions;
+  class CodeGenOptions;
+  class Diagnostic;
+  class AnnotateAttr;
+  class CXXDestructorDecl;
+
+namespace CodeGen {
+
+  class CodeGenFunction;
+  class CGDebugInfo;
+  class CGObjCRuntime;
+  class MangleBuffer;
+  
+/// CodeGenModule - This class organizes the cross-function state that is used
+/// while generating LLVM code.
+class CodeGenModule : public BlockModule {
+  CodeGenModule(const CodeGenModule&);  // DO NOT IMPLEMENT
+  void operator=(const CodeGenModule&); // DO NOT IMPLEMENT
+
+  typedef std::vector<std::pair<llvm::Constant*, int> > CtorList;
+
+  ASTContext &Context;
+  const LangOptions &Features;
+  const CodeGenOptions &CodeGenOpts;
+  llvm::Module &TheModule;
+  const llvm::TargetData &TheTargetData;
+  mutable const TargetCodeGenInfo *TheTargetCodeGenInfo;
+  Diagnostic &Diags;
+  CodeGenTypes Types;
+  MangleContext MangleCtx;
+
+  /// VTables - Holds information about C++ vtables.
+  CodeGenVTables VTables;
+  friend class CodeGenVTables;
+
+  CGObjCRuntime* Runtime;
+  CGDebugInfo* DebugInfo;
+
+  // WeakRefReferences - A set of references that have only been seen via
+  // a weakref so far. This is used to remove the weak of the reference if we ever
+  // see a direct reference or a definition.
+  llvm::SmallPtrSet<llvm::GlobalValue*, 10> WeakRefReferences;
+
+  /// DeferredDecls - This contains all the decls which have definitions but
+  /// which are deferred for emission and therefore should only be output if
+  /// they are actually used.  If a decl is in this, then it is known to have
+  /// not been referenced yet.
+  llvm::StringMap<GlobalDecl> DeferredDecls;
+
+  /// DeferredDeclsToEmit - This is a list of deferred decls which we have seen
+  /// that *are* actually referenced.  These get code generated when the module
+  /// is done.
+  std::vector<GlobalDecl> DeferredDeclsToEmit;
+
+  /// LLVMUsed - List of global values which are required to be
+  /// present in the object file; bitcast to i8*. This is used for
+  /// forcing visibility of symbols which may otherwise be optimized
+  /// out.
+  std::vector<llvm::WeakVH> LLVMUsed;
+
+  /// GlobalCtors - Store the list of global constructors and their respective
+  /// priorities to be emitted when the translation unit is complete.
+  CtorList GlobalCtors;
+
+  /// GlobalDtors - Store the list of global destructors and their respective
+  /// priorities to be emitted when the translation unit is complete.
+  CtorList GlobalDtors;
+
+  std::vector<llvm::Constant*> Annotations;
+
+  llvm::StringMap<llvm::Constant*> CFConstantStringMap;
+  llvm::StringMap<llvm::Constant*> ConstantStringMap;
+  llvm::DenseMap<const Decl*, llvm::Value*> StaticLocalDeclMap;
+
+  /// CXXGlobalInits - Global variables with initializers that need to run
+  /// before main.
+  std::vector<llvm::Constant*> CXXGlobalInits;
+
+  /// CXXGlobalDtors - Global destructor functions and arguments that need to
+  /// run on termination.
+  std::vector<std::pair<llvm::Constant*,llvm::Constant*> > CXXGlobalDtors;
+
+  /// CFConstantStringClassRef - Cached reference to the class for constant
+  /// strings. This value has type int * but is actually an Obj-C class pointer.
+  llvm::Constant *CFConstantStringClassRef;
+
+  /// NSConstantStringClassRef - Cached reference to the class for constant
+  /// strings. This value has type int * but is actually an Obj-C class pointer.
+  llvm::Constant *NSConstantStringClassRef;
+
+  /// Lazily create the Objective-C runtime
+  void createObjCRuntime();
+
+  llvm::LLVMContext &VMContext;
+public:
+  CodeGenModule(ASTContext &C, const CodeGenOptions &CodeGenOpts,
+                llvm::Module &M, const llvm::TargetData &TD, Diagnostic &Diags);
+
+  ~CodeGenModule();
+
+  /// Release - Finalize LLVM code generation.
+  void Release();
+
+  /// getObjCRuntime() - Return a reference to the configured
+  /// Objective-C runtime.
+  CGObjCRuntime &getObjCRuntime() {
+    if (!Runtime) createObjCRuntime();
+    return *Runtime;
+  }
+
+  /// hasObjCRuntime() - Return true iff an Objective-C runtime has
+  /// been configured.
+  bool hasObjCRuntime() { return !!Runtime; }
+
+  llvm::Value *getStaticLocalDeclAddress(const VarDecl *VD) {
+    return StaticLocalDeclMap[VD];
+  }
+  void setStaticLocalDeclAddress(const VarDecl *D, 
+                             llvm::GlobalVariable *GV) {
+    StaticLocalDeclMap[D] = GV;
+  }
+
+  CGDebugInfo *getDebugInfo() { return DebugInfo; }
+  ASTContext &getContext() const { return Context; }
+  const CodeGenOptions &getCodeGenOpts() const { return CodeGenOpts; }
+  const LangOptions &getLangOptions() const { return Features; }
+  llvm::Module &getModule() const { return TheModule; }
+  CodeGenTypes &getTypes() { return Types; }
+  MangleContext &getMangleContext() { return MangleCtx; }
+  CodeGenVTables &getVTables() { return VTables; }
+  Diagnostic &getDiags() const { return Diags; }
+  const llvm::TargetData &getTargetData() const { return TheTargetData; }
+  llvm::LLVMContext &getLLVMContext() { return VMContext; }
+  const TargetCodeGenInfo &getTargetCodeGenInfo() const;
+  bool isTargetDarwin() const;
+
+  /// getDeclVisibilityMode - Compute the visibility of the decl \arg D.
+  LangOptions::VisibilityMode getDeclVisibilityMode(const Decl *D) const;
+
+  /// setGlobalVisibility - Set the visibility for the given LLVM
+  /// GlobalValue.
+  void setGlobalVisibility(llvm::GlobalValue *GV, const Decl *D) const;
+
+  llvm::Constant *GetAddrOfGlobal(GlobalDecl GD) {
+    if (isa<CXXConstructorDecl>(GD.getDecl()))
+      return GetAddrOfCXXConstructor(cast<CXXConstructorDecl>(GD.getDecl()),
+                                     GD.getCtorType());
+    else if (isa<CXXDestructorDecl>(GD.getDecl()))
+      return GetAddrOfCXXDestructor(cast<CXXDestructorDecl>(GD.getDecl()),
+                                     GD.getDtorType());
+    else if (isa<FunctionDecl>(GD.getDecl()))
+      return GetAddrOfFunction(GD);
+    else
+      return GetAddrOfGlobalVar(cast<VarDecl>(GD.getDecl()));
+  }
+
+  /// GetAddrOfGlobalVar - Return the llvm::Constant for the address of the
+  /// given global variable.  If Ty is non-null and if the global doesn't exist,
+  /// then it will be greated with the specified type instead of whatever the
+  /// normal requested type would be.
+  llvm::Constant *GetAddrOfGlobalVar(const VarDecl *D,
+                                     const llvm::Type *Ty = 0);
+
+  /// GetAddrOfFunction - Return the address of the given function.  If Ty is
+  /// non-null, then this function will use the specified type if it has to
+  /// create it.
+  llvm::Constant *GetAddrOfFunction(GlobalDecl GD,
+                                    const llvm::Type *Ty = 0);
+
+  /// GetAddrOfRTTIDescriptor - Get the address of the RTTI descriptor 
+  /// for the given type.
+  llvm::Constant *GetAddrOfRTTIDescriptor(QualType Ty);
+
+  /// GetAddrOfThunk - Get the address of the thunk for the given global decl.
+  llvm::Constant *GetAddrOfThunk(GlobalDecl GD, const ThunkInfo &Thunk);
+
+  /// GetWeakRefReference - Get a reference to the target of VD.
+  llvm::Constant *GetWeakRefReference(const ValueDecl *VD);
+
+  /// GetNonVirtualBaseClassOffset - Returns the offset from a derived class to 
+  /// a class. Returns null if the offset is 0. 
+  llvm::Constant *
+  GetNonVirtualBaseClassOffset(const CXXRecordDecl *ClassDecl,
+                               const CXXBaseSpecifierArray &BasePath);
+  
+  /// GetStringForStringLiteral - Return the appropriate bytes for a string
+  /// literal, properly padded to match the literal type. If only the address of
+  /// a constant is needed consider using GetAddrOfConstantStringLiteral.
+  std::string GetStringForStringLiteral(const StringLiteral *E);
+
+  /// GetAddrOfConstantCFString - Return a pointer to a constant CFString object
+  /// for the given string.
+  llvm::Constant *GetAddrOfConstantCFString(const StringLiteral *Literal);
+  
+  /// GetAddrOfConstantNSString - Return a pointer to a constant NSString object
+  /// for the given string.
+  llvm::Constant *GetAddrOfConstantNSString(const StringLiteral *Literal);
+
+  /// GetAddrOfConstantStringFromLiteral - Return a pointer to a constant array
+  /// for the given string literal.
+  llvm::Constant *GetAddrOfConstantStringFromLiteral(const StringLiteral *S);
+
+  /// GetAddrOfConstantStringFromObjCEncode - Return a pointer to a constant
+  /// array for the given ObjCEncodeExpr node.
+  llvm::Constant *GetAddrOfConstantStringFromObjCEncode(const ObjCEncodeExpr *);
+
+  /// GetAddrOfConstantString - Returns a pointer to a character array
+  /// containing the literal. This contents are exactly that of the given
+  /// string, i.e. it will not be null terminated automatically; see
+  /// GetAddrOfConstantCString. Note that whether the result is actually a
+  /// pointer to an LLVM constant depends on Feature.WriteableStrings.
+  ///
+  /// The result has pointer to array type.
+  ///
+  /// \param GlobalName If provided, the name to use for the global
+  /// (if one is created).
+  llvm::Constant *GetAddrOfConstantString(const std::string& str,
+                                          const char *GlobalName=0);
+
+  /// GetAddrOfConstantCString - Returns a pointer to a character array
+  /// containing the literal and a terminating '\0' character. The result has
+  /// pointer to array type.
+  ///
+  /// \param GlobalName If provided, the name to use for the global (if one is
+  /// created).
+  llvm::Constant *GetAddrOfConstantCString(const std::string &str,
+                                           const char *GlobalName=0);
+
+  /// GetAddrOfCXXConstructor - Return the address of the constructor of the
+  /// given type.
+  llvm::GlobalValue *GetAddrOfCXXConstructor(const CXXConstructorDecl *D,
+                                             CXXCtorType Type);
+
+  /// GetAddrOfCXXDestructor - Return the address of the constructor of the
+  /// given type.
+  llvm::GlobalValue *GetAddrOfCXXDestructor(const CXXDestructorDecl *D,
+                                            CXXDtorType Type);
+
+  /// getBuiltinLibFunction - Given a builtin id for a function like
+  /// "__builtin_fabsf", return a Function* for "fabsf".
+  llvm::Value *getBuiltinLibFunction(const FunctionDecl *FD,
+                                     unsigned BuiltinID);
+
+  llvm::Function *getMemCpyFn(const llvm::Type *DestType,
+                              const llvm::Type *SrcType,
+                              const llvm::Type *SizeType);
+
+  llvm::Function *getMemMoveFn(const llvm::Type *DestType,
+                               const llvm::Type *SrcType,
+                               const llvm::Type *SizeType);
+
+  llvm::Function *getMemSetFn(const llvm::Type *DestType,
+                              const llvm::Type *SizeType);
+
+  llvm::Function *getIntrinsic(unsigned IID, const llvm::Type **Tys = 0,
+                               unsigned NumTys = 0);
+
+  /// EmitTopLevelDecl - Emit code for a single top level declaration.
+  void EmitTopLevelDecl(Decl *D);
+
+  /// AddUsedGlobal - Add a global which should be forced to be
+  /// present in the object file; these are emitted to the llvm.used
+  /// metadata global.
+  void AddUsedGlobal(llvm::GlobalValue *GV);
+
+  void AddAnnotation(llvm::Constant *C) { Annotations.push_back(C); }
+
+  /// AddCXXDtorEntry - Add a destructor and object to add to the C++ global
+  /// destructor function.
+  void AddCXXDtorEntry(llvm::Constant *DtorFn, llvm::Constant *Object);
+
+  /// CreateRuntimeFunction - Create a new runtime function with the specified
+  /// type and name.
+  llvm::Constant *CreateRuntimeFunction(const llvm::FunctionType *Ty,
+                                        llvm::StringRef Name);
+  /// CreateRuntimeVariable - Create a new runtime global variable with the
+  /// specified type and name.
+  llvm::Constant *CreateRuntimeVariable(const llvm::Type *Ty,
+                                        llvm::StringRef Name);
+
+  void UpdateCompletedType(const TagDecl *TD) {
+    // Make sure that this type is translated.
+    Types.UpdateCompletedType(TD);
+  }
+
+  /// EmitConstantExpr - Try to emit the given expression as a
+  /// constant; returns 0 if the expression cannot be emitted as a
+  /// constant.
+  llvm::Constant *EmitConstantExpr(const Expr *E, QualType DestType,
+                                   CodeGenFunction *CGF = 0);
+
+  /// EmitNullConstant - Return the result of value-initializing the given
+  /// type, i.e. a null expression of the given type.  This is usually,
+  /// but not always, an LLVM null constant.
+  llvm::Constant *EmitNullConstant(QualType T);
+
+  llvm::Constant *EmitAnnotateAttr(llvm::GlobalValue *GV,
+                                   const AnnotateAttr *AA, unsigned LineNo);
+
+  llvm::Constant *EmitPointerToDataMember(const FieldDecl *FD);
+
+  /// ErrorUnsupported - Print out an error that codegen doesn't support the
+  /// specified stmt yet.
+  /// \param OmitOnError - If true, then this error should only be emitted if no
+  /// other errors have been reported.
+  void ErrorUnsupported(const Stmt *S, const char *Type,
+                        bool OmitOnError=false);
+
+  /// ErrorUnsupported - Print out an error that codegen doesn't support the
+  /// specified decl yet.
+  /// \param OmitOnError - If true, then this error should only be emitted if no
+  /// other errors have been reported.
+  void ErrorUnsupported(const Decl *D, const char *Type,
+                        bool OmitOnError=false);
+
+  /// SetInternalFunctionAttributes - Set the attributes on the LLVM
+  /// function for the given decl and function info. This applies
+  /// attributes necessary for handling the ABI as well as user
+  /// specified attributes like section.
+  void SetInternalFunctionAttributes(const Decl *D, llvm::Function *F,
+                                     const CGFunctionInfo &FI);
+
+  /// SetLLVMFunctionAttributes - Set the LLVM function attributes
+  /// (sext, zext, etc).
+  void SetLLVMFunctionAttributes(const Decl *D,
+                                 const CGFunctionInfo &Info,
+                                 llvm::Function *F);
+
+  /// SetLLVMFunctionAttributesForDefinition - Set the LLVM function attributes
+  /// which only apply to a function definintion.
+  void SetLLVMFunctionAttributesForDefinition(const Decl *D, llvm::Function *F);
+
+  /// ReturnTypeUsesSret - Return true iff the given type uses 'sret' when used
+  /// as a return type.
+  bool ReturnTypeUsesSret(const CGFunctionInfo &FI);
+
+  /// ConstructAttributeList - Get the LLVM attributes and calling convention to
+  /// use for a particular function type.
+  ///
+  /// \param Info - The function type information.
+  /// \param TargetDecl - The decl these attributes are being constructed
+  /// for. If supplied the attributes applied to this decl may contribute to the
+  /// function attributes and calling convention.
+  /// \param PAL [out] - On return, the attribute list to use.
+  /// \param CallingConv [out] - On return, the LLVM calling convention to use.
+  void ConstructAttributeList(const CGFunctionInfo &Info,
+                              const Decl *TargetDecl,
+                              AttributeListType &PAL,
+                              unsigned &CallingConv);
+
+  void getMangledName(MangleBuffer &Buffer, GlobalDecl D);
+  void getMangledName(MangleBuffer &Buffer, const NamedDecl *ND);
+  void getMangledCXXCtorName(MangleBuffer &Buffer,
+                             const CXXConstructorDecl *D,
+                             CXXCtorType Type);
+  void getMangledCXXDtorName(MangleBuffer &Buffer,
+                             const CXXDestructorDecl *D,
+                             CXXDtorType Type);
+
+  void EmitTentativeDefinition(const VarDecl *D);
+
+  enum GVALinkage {
+    GVA_Internal,
+    GVA_C99Inline,
+    GVA_CXXInline,
+    GVA_StrongExternal,
+    GVA_TemplateInstantiation,
+    GVA_ExplicitTemplateInstantiation
+  };
+
+  llvm::GlobalVariable::LinkageTypes
+  getFunctionLinkage(const FunctionDecl *FD);
+
+  /// getVTableLinkage - Return the appropriate linkage for the vtable, VTT,
+  /// and type information of the given class.
+  static llvm::GlobalVariable::LinkageTypes 
+  getVTableLinkage(const CXXRecordDecl *RD);
+
+  /// GetTargetTypeStoreSize - Return the store size, in character units, of
+  /// the given LLVM type.
+  CharUnits GetTargetTypeStoreSize(const llvm::Type *Ty) const;
+
+  std::vector<const CXXRecordDecl*> DeferredVTables;
+
+private:
+  llvm::GlobalValue *GetGlobalValue(llvm::StringRef Ref);
+
+  llvm::Constant *GetOrCreateLLVMFunction(llvm::StringRef MangledName,
+                                          const llvm::Type *Ty,
+                                          GlobalDecl D);
+  llvm::Constant *GetOrCreateLLVMGlobal(llvm::StringRef MangledName,
+                                        const llvm::PointerType *PTy,
+                                        const VarDecl *D);
+
+  /// SetCommonAttributes - Set attributes which are common to any
+  /// form of a global definition (alias, Objective-C method,
+  /// function, global variable).
+  ///
+  /// NOTE: This should only be called for definitions.
+  void SetCommonAttributes(const Decl *D, llvm::GlobalValue *GV);
+
+  /// SetFunctionDefinitionAttributes - Set attributes for a global definition.
+  void SetFunctionDefinitionAttributes(const FunctionDecl *D,
+                                       llvm::GlobalValue *GV);
+
+  /// SetFunctionAttributes - Set function attributes for a function
+  /// declaration.
+  void SetFunctionAttributes(GlobalDecl GD,
+                             llvm::Function *F,
+                             bool IsIncompleteFunction);
+
+  /// EmitGlobal - Emit code for a singal global function or var decl. Forward
+  /// declarations are emitted lazily.
+  void EmitGlobal(GlobalDecl D);
+
+  void EmitGlobalDefinition(GlobalDecl D);
+
+  void EmitGlobalFunctionDefinition(GlobalDecl GD);
+  void EmitGlobalVarDefinition(const VarDecl *D);
+  void EmitAliasDefinition(GlobalDecl GD);
+  void EmitObjCPropertyImplementations(const ObjCImplementationDecl *D);
+
+  // C++ related functions.
+
+  bool TryEmitDefinitionAsAlias(GlobalDecl Alias, GlobalDecl Target);
+  bool TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D);
+
+  void EmitNamespace(const NamespaceDecl *D);
+  void EmitLinkageSpec(const LinkageSpecDecl *D);
+
+  /// EmitCXXConstructors - Emit constructors (base, complete) from a
+  /// C++ constructor Decl.
+  void EmitCXXConstructors(const CXXConstructorDecl *D);
+
+  /// EmitCXXConstructor - Emit a single constructor with the given type from
+  /// a C++ constructor Decl.
+  void EmitCXXConstructor(const CXXConstructorDecl *D, CXXCtorType Type);
+
+  /// EmitCXXDestructors - Emit destructors (base, complete) from a
+  /// C++ destructor Decl.
+  void EmitCXXDestructors(const CXXDestructorDecl *D);
+
+  /// EmitCXXDestructor - Emit a single destructor with the given type from
+  /// a C++ destructor Decl.
+  void EmitCXXDestructor(const CXXDestructorDecl *D, CXXDtorType Type);
+
+  /// EmitCXXGlobalInitFunc - Emit the function that initializes C++ globals.
+  void EmitCXXGlobalInitFunc();
+
+  /// EmitCXXGlobalDtorFunc - Emit the function that destroys C++ globals.
+  void EmitCXXGlobalDtorFunc();
+
+  void EmitCXXGlobalVarDeclInitFunc(const VarDecl *D);
+
+  // FIXME: Hardcoding priority here is gross.
+  void AddGlobalCtor(llvm::Function *Ctor, int Priority=65535);
+  void AddGlobalDtor(llvm::Function *Dtor, int Priority=65535);
+
+  /// EmitCtorList - Generates a global array of functions and priorities using
+  /// the given list and name. This array will have appending linkage and is
+  /// suitable for use as a LLVM constructor or destructor array.
+  void EmitCtorList(const CtorList &Fns, const char *GlobalName);
+
+  void EmitAnnotations(void);
+
+  /// EmitFundamentalRTTIDescriptor - Emit the RTTI descriptors for the
+  /// given type.
+  void EmitFundamentalRTTIDescriptor(QualType Type);
+
+  /// EmitFundamentalRTTIDescriptors - Emit the RTTI descriptors for the
+  /// builtin types.
+  void EmitFundamentalRTTIDescriptors();
+
+  /// EmitDeferred - Emit any needed decls for which code generation
+  /// was deferred.
+  void EmitDeferred(void);
+
+  /// EmitLLVMUsed - Emit the llvm.used metadata used to force
+  /// references to global which may otherwise be optimized out.
+  void EmitLLVMUsed(void);
+
+  /// MayDeferGeneration - Determine if the given decl can be emitted
+  /// lazily; this is only relevant for definitions. The given decl
+  /// must be either a function or var decl.
+  bool MayDeferGeneration(const ValueDecl *D);
+};
+}  // end namespace CodeGen
+}  // end namespace clang
+
+#endif
diff --git a/lib/CodeGen/CodeGenTypes.cpp b/lib/CodeGen/CodeGenTypes.cpp
new file mode 100644
index 0000000..f53dd83
--- /dev/null
+++ b/lib/CodeGen/CodeGenTypes.cpp
@@ -0,0 +1,469 @@
+//===--- CodeGenTypes.cpp - Type translation for LLVM CodeGen -------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This is the code that handles AST -> LLVM type lowering.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CodeGenTypes.h"
+#include "CGCall.h"
+#include "CGRecordLayout.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/RecordLayout.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/Module.h"
+#include "llvm/Target/TargetData.h"
+using namespace clang;
+using namespace CodeGen;
+
+CodeGenTypes::CodeGenTypes(ASTContext &Ctx, llvm::Module& M,
+                           const llvm::TargetData &TD, const ABIInfo &Info)
+  : Context(Ctx), Target(Ctx.Target), TheModule(M), TheTargetData(TD),
+    TheABIInfo(Info) {
+}
+
+CodeGenTypes::~CodeGenTypes() {
+  for (llvm::DenseMap<const Type *, CGRecordLayout *>::iterator
+         I = CGRecordLayouts.begin(), E = CGRecordLayouts.end();
+      I != E; ++I)
+    delete I->second;
+
+  for (llvm::FoldingSet<CGFunctionInfo>::iterator
+       I = FunctionInfos.begin(), E = FunctionInfos.end(); I != E; )
+    delete &*I++;
+}
+
+/// ConvertType - Convert the specified type to its LLVM form.
+const llvm::Type *CodeGenTypes::ConvertType(QualType T) {
+  llvm::PATypeHolder Result = ConvertTypeRecursive(T);
+
+  // Any pointers that were converted defered evaluation of their pointee type,
+  // creating an opaque type instead.  This is in order to avoid problems with
+  // circular types.  Loop through all these defered pointees, if any, and
+  // resolve them now.
+  while (!PointersToResolve.empty()) {
+    std::pair<QualType, llvm::OpaqueType*> P = PointersToResolve.pop_back_val();
+    
+    // We can handle bare pointers here because we know that the only pointers
+    // to the Opaque type are P.second and from other types.  Refining the
+    // opqaue type away will invalidate P.second, but we don't mind :).
+    const llvm::Type *NT = ConvertTypeForMemRecursive(P.first);
+    P.second->refineAbstractTypeTo(NT);
+  }
+
+  return Result;
+}
+
+const llvm::Type *CodeGenTypes::ConvertTypeRecursive(QualType T) {
+  T = Context.getCanonicalType(T);
+
+  // See if type is already cached.
+  llvm::DenseMap<Type *, llvm::PATypeHolder>::iterator
+    I = TypeCache.find(T.getTypePtr());
+  // If type is found in map and this is not a definition for a opaque
+  // place holder type then use it. Otherwise, convert type T.
+  if (I != TypeCache.end())
+    return I->second.get();
+
+  const llvm::Type *ResultType = ConvertNewType(T);
+  TypeCache.insert(std::make_pair(T.getTypePtr(),
+                                  llvm::PATypeHolder(ResultType)));
+  return ResultType;
+}
+
+const llvm::Type *CodeGenTypes::ConvertTypeForMemRecursive(QualType T) {
+  const llvm::Type *ResultType = ConvertTypeRecursive(T);
+  if (ResultType->isIntegerTy(1))
+    return llvm::IntegerType::get(getLLVMContext(),
+                                  (unsigned)Context.getTypeSize(T));
+  // FIXME: Should assert that the llvm type and AST type has the same size.
+  return ResultType;
+}
+
+/// ConvertTypeForMem - Convert type T into a llvm::Type.  This differs from
+/// ConvertType in that it is used to convert to the memory representation for
+/// a type.  For example, the scalar representation for _Bool is i1, but the
+/// memory representation is usually i8 or i32, depending on the target.
+const llvm::Type *CodeGenTypes::ConvertTypeForMem(QualType T) {
+  const llvm::Type *R = ConvertType(T);
+
+  // If this is a non-bool type, don't map it.
+  if (!R->isIntegerTy(1))
+    return R;
+
+  // Otherwise, return an integer of the target-specified size.
+  return llvm::IntegerType::get(getLLVMContext(),
+                                (unsigned)Context.getTypeSize(T));
+
+}
+
+// Code to verify a given function type is complete, i.e. the return type
+// and all of the argument types are complete.
+static const TagType *VerifyFuncTypeComplete(const Type* T) {
+  const FunctionType *FT = cast<FunctionType>(T);
+  if (const TagType* TT = FT->getResultType()->getAs<TagType>())
+    if (!TT->getDecl()->isDefinition())
+      return TT;
+  if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(T))
+    for (unsigned i = 0; i < FPT->getNumArgs(); i++)
+      if (const TagType* TT = FPT->getArgType(i)->getAs<TagType>())
+        if (!TT->getDecl()->isDefinition())
+          return TT;
+  return 0;
+}
+
+/// UpdateCompletedType - When we find the full definition for a TagDecl,
+/// replace the 'opaque' type we previously made for it if applicable.
+void CodeGenTypes::UpdateCompletedType(const TagDecl *TD) {
+  const Type *Key = Context.getTagDeclType(TD).getTypePtr();
+  llvm::DenseMap<const Type*, llvm::PATypeHolder>::iterator TDTI =
+    TagDeclTypes.find(Key);
+  if (TDTI == TagDeclTypes.end()) return;
+
+  // Remember the opaque LLVM type for this tagdecl.
+  llvm::PATypeHolder OpaqueHolder = TDTI->second;
+  assert(isa<llvm::OpaqueType>(OpaqueHolder.get()) &&
+         "Updating compilation of an already non-opaque type?");
+
+  // Remove it from TagDeclTypes so that it will be regenerated.
+  TagDeclTypes.erase(TDTI);
+
+  // Generate the new type.
+  const llvm::Type *NT = ConvertTagDeclType(TD);
+
+  // Refine the old opaque type to its new definition.
+  cast<llvm::OpaqueType>(OpaqueHolder.get())->refineAbstractTypeTo(NT);
+
+  // Since we just completed a tag type, check to see if any function types
+  // were completed along with the tag type.
+  // FIXME: This is very inefficient; if we track which function types depend
+  // on which tag types, though, it should be reasonably efficient.
+  llvm::DenseMap<const Type*, llvm::PATypeHolder>::iterator i;
+  for (i = FunctionTypes.begin(); i != FunctionTypes.end(); ++i) {
+    if (const TagType* TT = VerifyFuncTypeComplete(i->first)) {
+      // This function type still depends on an incomplete tag type; make sure
+      // that tag type has an associated opaque type.
+      ConvertTagDeclType(TT->getDecl());
+    } else {
+      // This function no longer depends on an incomplete tag type; create the
+      // function type, and refine the opaque type to the new function type.
+      llvm::PATypeHolder OpaqueHolder = i->second;
+      const llvm::Type *NFT = ConvertNewType(QualType(i->first, 0));
+      cast<llvm::OpaqueType>(OpaqueHolder.get())->refineAbstractTypeTo(NFT);
+      FunctionTypes.erase(i);
+    }
+  }
+}
+
+static const llvm::Type* getTypeForFormat(llvm::LLVMContext &VMContext,
+                                          const llvm::fltSemantics &format) {
+  if (&format == &llvm::APFloat::IEEEsingle)
+    return llvm::Type::getFloatTy(VMContext);
+  if (&format == &llvm::APFloat::IEEEdouble)
+    return llvm::Type::getDoubleTy(VMContext);
+  if (&format == &llvm::APFloat::IEEEquad)
+    return llvm::Type::getFP128Ty(VMContext);
+  if (&format == &llvm::APFloat::PPCDoubleDouble)
+    return llvm::Type::getPPC_FP128Ty(VMContext);
+  if (&format == &llvm::APFloat::x87DoubleExtended)
+    return llvm::Type::getX86_FP80Ty(VMContext);
+  assert(0 && "Unknown float format!");
+  return 0;
+}
+
+const llvm::Type *CodeGenTypes::ConvertNewType(QualType T) {
+  const clang::Type &Ty = *Context.getCanonicalType(T).getTypePtr();
+
+  switch (Ty.getTypeClass()) {
+#define TYPE(Class, Base)
+#define ABSTRACT_TYPE(Class, Base)
+#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
+#define DEPENDENT_TYPE(Class, Base) case Type::Class:
+#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
+#include "clang/AST/TypeNodes.def"
+    assert(false && "Non-canonical or dependent types aren't possible.");
+    break;
+
+  case Type::Builtin: {
+    switch (cast<BuiltinType>(Ty).getKind()) {
+    case BuiltinType::Void:
+    case BuiltinType::ObjCId:
+    case BuiltinType::ObjCClass:
+    case BuiltinType::ObjCSel:
+      // LLVM void type can only be used as the result of a function call.  Just
+      // map to the same as char.
+      return llvm::IntegerType::get(getLLVMContext(), 8);
+
+    case BuiltinType::Bool:
+      // Note that we always return bool as i1 for use as a scalar type.
+      return llvm::Type::getInt1Ty(getLLVMContext());
+
+    case BuiltinType::Char_S:
+    case BuiltinType::Char_U:
+    case BuiltinType::SChar:
+    case BuiltinType::UChar:
+    case BuiltinType::Short:
+    case BuiltinType::UShort:
+    case BuiltinType::Int:
+    case BuiltinType::UInt:
+    case BuiltinType::Long:
+    case BuiltinType::ULong:
+    case BuiltinType::LongLong:
+    case BuiltinType::ULongLong:
+    case BuiltinType::WChar:
+    case BuiltinType::Char16:
+    case BuiltinType::Char32:
+      return llvm::IntegerType::get(getLLVMContext(),
+        static_cast<unsigned>(Context.getTypeSize(T)));
+
+    case BuiltinType::Float:
+    case BuiltinType::Double:
+    case BuiltinType::LongDouble:
+      return getTypeForFormat(getLLVMContext(),
+                              Context.getFloatTypeSemantics(T));
+
+    case BuiltinType::NullPtr: {
+      // Model std::nullptr_t as i8*
+      const llvm::Type *Ty = llvm::IntegerType::get(getLLVMContext(), 8);
+      return llvm::PointerType::getUnqual(Ty);
+    }
+        
+    case BuiltinType::UInt128:
+    case BuiltinType::Int128:
+      return llvm::IntegerType::get(getLLVMContext(), 128);
+    
+    case BuiltinType::Overload:
+    case BuiltinType::Dependent:
+    case BuiltinType::UndeducedAuto:
+      assert(0 && "Unexpected builtin type!");
+      break;
+    }
+    assert(0 && "Unknown builtin type!");
+    break;
+  }
+  case Type::Complex: {
+    const llvm::Type *EltTy =
+      ConvertTypeRecursive(cast<ComplexType>(Ty).getElementType());
+    return llvm::StructType::get(TheModule.getContext(), EltTy, EltTy, NULL);
+  }
+  case Type::LValueReference:
+  case Type::RValueReference: {
+    const ReferenceType &RTy = cast<ReferenceType>(Ty);
+    QualType ETy = RTy.getPointeeType();
+    llvm::OpaqueType *PointeeType = llvm::OpaqueType::get(getLLVMContext());
+    PointersToResolve.push_back(std::make_pair(ETy, PointeeType));
+    return llvm::PointerType::get(PointeeType, ETy.getAddressSpace());
+  }
+  case Type::Pointer: {
+    const PointerType &PTy = cast<PointerType>(Ty);
+    QualType ETy = PTy.getPointeeType();
+    llvm::OpaqueType *PointeeType = llvm::OpaqueType::get(getLLVMContext());
+    PointersToResolve.push_back(std::make_pair(ETy, PointeeType));
+    return llvm::PointerType::get(PointeeType, ETy.getAddressSpace());
+  }
+
+  case Type::VariableArray: {
+    const VariableArrayType &A = cast<VariableArrayType>(Ty);
+    assert(A.getIndexTypeCVRQualifiers() == 0 &&
+           "FIXME: We only handle trivial array types so far!");
+    // VLAs resolve to the innermost element type; this matches
+    // the return of alloca, and there isn't any obviously better choice.
+    return ConvertTypeForMemRecursive(A.getElementType());
+  }
+  case Type::IncompleteArray: {
+    const IncompleteArrayType &A = cast<IncompleteArrayType>(Ty);
+    assert(A.getIndexTypeCVRQualifiers() == 0 &&
+           "FIXME: We only handle trivial array types so far!");
+    // int X[] -> [0 x int]
+    return llvm::ArrayType::get(ConvertTypeForMemRecursive(A.getElementType()), 0);
+  }
+  case Type::ConstantArray: {
+    const ConstantArrayType &A = cast<ConstantArrayType>(Ty);
+    const llvm::Type *EltTy = ConvertTypeForMemRecursive(A.getElementType());
+    return llvm::ArrayType::get(EltTy, A.getSize().getZExtValue());
+  }
+  case Type::ExtVector:
+  case Type::Vector: {
+    const VectorType &VT = cast<VectorType>(Ty);
+    return llvm::VectorType::get(ConvertTypeRecursive(VT.getElementType()),
+                                 VT.getNumElements());
+  }
+  case Type::FunctionNoProto:
+  case Type::FunctionProto: {
+    // First, check whether we can build the full function type.
+    if (const TagType* TT = VerifyFuncTypeComplete(&Ty)) {
+      // This function's type depends on an incomplete tag type; make sure
+      // we have an opaque type corresponding to the tag type.
+      ConvertTagDeclType(TT->getDecl());
+      // Create an opaque type for this function type, save it, and return it.
+      llvm::Type *ResultType = llvm::OpaqueType::get(getLLVMContext());
+      FunctionTypes.insert(std::make_pair(&Ty, ResultType));
+      return ResultType;
+    }
+    // The function type can be built; call the appropriate routines to
+    // build it.
+    if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(&Ty))
+      return GetFunctionType(getFunctionInfo(
+                CanQual<FunctionProtoType>::CreateUnsafe(QualType(FPT,0))),
+                             FPT->isVariadic());
+
+    const FunctionNoProtoType *FNPT = cast<FunctionNoProtoType>(&Ty);
+    return GetFunctionType(getFunctionInfo(
+                CanQual<FunctionNoProtoType>::CreateUnsafe(QualType(FNPT,0))),
+                           true);
+  }
+
+  case Type::ObjCInterface: {
+    // Objective-C interfaces are always opaque (outside of the
+    // runtime, which can do whatever it likes); we never refine
+    // these.
+    const llvm::Type *&T = InterfaceTypes[cast<ObjCInterfaceType>(&Ty)];
+    if (!T)
+        T = llvm::OpaqueType::get(getLLVMContext());
+    return T;
+  }
+
+  case Type::ObjCObjectPointer: {
+    // Protocol qualifications do not influence the LLVM type, we just return a
+    // pointer to the underlying interface type. We don't need to worry about
+    // recursive conversion.
+    const llvm::Type *T =
+      ConvertTypeRecursive(cast<ObjCObjectPointerType>(Ty).getPointeeType());
+    return llvm::PointerType::getUnqual(T);
+  }
+
+  case Type::Record:
+  case Type::Enum: {
+    const TagDecl *TD = cast<TagType>(Ty).getDecl();
+    const llvm::Type *Res = ConvertTagDeclType(TD);
+
+    std::string TypeName(TD->getKindName());
+    TypeName += '.';
+
+    // Name the codegen type after the typedef name
+    // if there is no tag type name available
+    if (TD->getIdentifier())
+      // FIXME: We should not have to check for a null decl context here.
+      // Right now we do it because the implicit Obj-C decls don't have one.
+      TypeName += TD->getDeclContext() ? TD->getQualifiedNameAsString() :
+        TD->getNameAsString();
+    else if (const TypedefType *TdT = dyn_cast<TypedefType>(T))
+      // FIXME: We should not have to check for a null decl context here.
+      // Right now we do it because the implicit Obj-C decls don't have one.
+      TypeName += TdT->getDecl()->getDeclContext() ? 
+        TdT->getDecl()->getQualifiedNameAsString() :
+        TdT->getDecl()->getNameAsString();
+    else
+      TypeName += "anon";
+
+    TheModule.addTypeName(TypeName, Res);
+    return Res;
+  }
+
+  case Type::BlockPointer: {
+    const QualType FTy = cast<BlockPointerType>(Ty).getPointeeType();
+    llvm::OpaqueType *PointeeType = llvm::OpaqueType::get(getLLVMContext());
+    PointersToResolve.push_back(std::make_pair(FTy, PointeeType));
+    return llvm::PointerType::get(PointeeType, FTy.getAddressSpace());
+  }
+
+  case Type::MemberPointer: {
+    // FIXME: This is ABI dependent. We use the Itanium C++ ABI.
+    // http://www.codesourcery.com/public/cxx-abi/abi.html#member-pointers
+    // If we ever want to support other ABIs this needs to be abstracted.
+
+    QualType ETy = cast<MemberPointerType>(Ty).getPointeeType();
+    const llvm::Type *PtrDiffTy =
+        ConvertTypeRecursive(Context.getPointerDiffType());
+    if (ETy->isFunctionType())
+      return llvm::StructType::get(TheModule.getContext(), PtrDiffTy, PtrDiffTy,
+                                   NULL);
+    return PtrDiffTy;
+  }
+  }
+
+  // FIXME: implement.
+  return llvm::OpaqueType::get(getLLVMContext());
+}
+
+/// ConvertTagDeclType - Lay out a tagged decl type like struct or union or
+/// enum.
+const llvm::Type *CodeGenTypes::ConvertTagDeclType(const TagDecl *TD) {
+  // TagDecl's are not necessarily unique, instead use the (clang)
+  // type connected to the decl.
+  const Type *Key =
+    Context.getTagDeclType(TD).getTypePtr();
+  llvm::DenseMap<const Type*, llvm::PATypeHolder>::iterator TDTI =
+    TagDeclTypes.find(Key);
+
+  // If we've already compiled this tag type, use the previous definition.
+  if (TDTI != TagDeclTypes.end())
+    return TDTI->second;
+
+  // If this is still a forward declaration, just define an opaque
+  // type to use for this tagged decl.
+  if (!TD->isDefinition()) {
+    llvm::Type *ResultType = llvm::OpaqueType::get(getLLVMContext());
+    TagDeclTypes.insert(std::make_pair(Key, ResultType));
+    return ResultType;
+  }
+
+  // Okay, this is a definition of a type.  Compile the implementation now.
+
+  if (TD->isEnum())  // Don't bother storing enums in TagDeclTypes.
+    return ConvertTypeRecursive(cast<EnumDecl>(TD)->getIntegerType());
+
+  // This decl could well be recursive.  In this case, insert an opaque
+  // definition of this type, which the recursive uses will get.  We will then
+  // refine this opaque version later.
+
+  // Create new OpaqueType now for later use in case this is a recursive
+  // type.  This will later be refined to the actual type.
+  llvm::PATypeHolder ResultHolder = llvm::OpaqueType::get(getLLVMContext());
+  TagDeclTypes.insert(std::make_pair(Key, ResultHolder));
+
+  const RecordDecl *RD = cast<const RecordDecl>(TD);
+
+  // Force conversion of non-virtual base classes recursively.
+  if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(TD)) {    
+    for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
+         e = RD->bases_end(); i != e; ++i) {
+      if (!i->isVirtual()) {
+        const CXXRecordDecl *Base =
+          cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
+        ConvertTagDeclType(Base);
+      }
+    }
+  }
+
+  // Layout fields.
+  CGRecordLayout *Layout = ComputeRecordLayout(RD);
+
+  CGRecordLayouts[Key] = Layout;
+  const llvm::Type *ResultType = Layout->getLLVMType();
+
+  // Refine our Opaque type to ResultType.  This can invalidate ResultType, so
+  // make sure to read the result out of the holder.
+  cast<llvm::OpaqueType>(ResultHolder.get())
+    ->refineAbstractTypeTo(ResultType);
+
+  return ResultHolder.get();
+}
+
+/// getCGRecordLayout - Return record layout info for the given llvm::Type.
+const CGRecordLayout &
+CodeGenTypes::getCGRecordLayout(const RecordDecl *TD) const {
+  const Type *Key = Context.getTagDeclType(TD).getTypePtr();
+  const CGRecordLayout *Layout = CGRecordLayouts.lookup(Key);
+  assert(Layout && "Unable to find record layout information for type");
+  return *Layout;
+}
diff --git a/lib/CodeGen/CodeGenTypes.h b/lib/CodeGen/CodeGenTypes.h
new file mode 100644
index 0000000..10e71e2
--- /dev/null
+++ b/lib/CodeGen/CodeGenTypes.h
@@ -0,0 +1,194 @@
+//===--- CodeGenTypes.h - Type translation for LLVM CodeGen -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This is the code that handles AST -> LLVM type lowering.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_CODEGEN_CODEGENTYPES_H
+#define CLANG_CODEGEN_CODEGENTYPES_H
+
+#include "llvm/Module.h"
+#include "llvm/ADT/DenseMap.h"
+#include <vector>
+
+#include "CGCall.h"
+#include "GlobalDecl.h"
+
+namespace llvm {
+  class FunctionType;
+  class Module;
+  class OpaqueType;
+  class PATypeHolder;
+  class TargetData;
+  class Type;
+  class LLVMContext;
+}
+
+namespace clang {
+  class ABIInfo;
+  class ASTContext;
+  template <typename> class CanQual;
+  class CXXConstructorDecl;
+  class CXXDestructorDecl;
+  class CXXMethodDecl;
+  class FieldDecl;
+  class FunctionProtoType;
+  class ObjCInterfaceDecl;
+  class ObjCIvarDecl;
+  class PointerType;
+  class QualType;
+  class RecordDecl;
+  class TagDecl;
+  class TargetInfo;
+  class Type;
+  typedef CanQual<Type> CanQualType;
+
+namespace CodeGen {
+  class CGRecordLayout;
+
+/// CodeGenTypes - This class organizes the cross-module state that is used
+/// while lowering AST types to LLVM types.
+class CodeGenTypes {
+  ASTContext &Context;
+  const TargetInfo &Target;
+  llvm::Module& TheModule;
+  const llvm::TargetData& TheTargetData;
+  const ABIInfo& TheABIInfo;
+
+  llvm::SmallVector<std::pair<QualType,
+                              llvm::OpaqueType *>, 8>  PointersToResolve;
+
+  llvm::DenseMap<const Type*, llvm::PATypeHolder> TagDeclTypes;
+
+  llvm::DenseMap<const Type*, llvm::PATypeHolder> FunctionTypes;
+
+  /// The opaque type map for Objective-C interfaces. All direct
+  /// manipulation is done by the runtime interfaces, which are
+  /// responsible for coercing to the appropriate type; these opaque
+  /// types are never refined.
+  llvm::DenseMap<const ObjCInterfaceType*, const llvm::Type *> InterfaceTypes;
+
+  /// CGRecordLayouts - This maps llvm struct type with corresponding
+  /// record layout info.
+  llvm::DenseMap<const Type*, CGRecordLayout *> CGRecordLayouts;
+
+  /// FunctionInfos - Hold memoized CGFunctionInfo results.
+  llvm::FoldingSet<CGFunctionInfo> FunctionInfos;
+
+private:
+  /// TypeCache - This map keeps cache of llvm::Types (through PATypeHolder)
+  /// and maps llvm::Types to corresponding clang::Type. llvm::PATypeHolder is
+  /// used instead of llvm::Type because it allows us to bypass potential
+  /// dangling type pointers due to type refinement on llvm side.
+  llvm::DenseMap<Type *, llvm::PATypeHolder> TypeCache;
+
+  /// ConvertNewType - Convert type T into a llvm::Type. Do not use this
+  /// method directly because it does not do any type caching. This method
+  /// is available only for ConvertType(). CovertType() is preferred
+  /// interface to convert type T into a llvm::Type.
+  const llvm::Type *ConvertNewType(QualType T);
+public:
+  CodeGenTypes(ASTContext &Ctx, llvm::Module &M, const llvm::TargetData &TD,
+               const ABIInfo &Info);
+  ~CodeGenTypes();
+
+  const llvm::TargetData &getTargetData() const { return TheTargetData; }
+  const TargetInfo &getTarget() const { return Target; }
+  ASTContext &getContext() const { return Context; }
+  const ABIInfo &getABIInfo() const { return TheABIInfo; }
+  llvm::LLVMContext &getLLVMContext() { return TheModule.getContext(); }
+
+  /// ConvertType - Convert type T into a llvm::Type.
+  const llvm::Type *ConvertType(QualType T);
+  const llvm::Type *ConvertTypeRecursive(QualType T);
+
+  /// ConvertTypeForMem - Convert type T into a llvm::Type.  This differs from
+  /// ConvertType in that it is used to convert to the memory representation for
+  /// a type.  For example, the scalar representation for _Bool is i1, but the
+  /// memory representation is usually i8 or i32, depending on the target.
+  const llvm::Type *ConvertTypeForMem(QualType T);
+  const llvm::Type *ConvertTypeForMemRecursive(QualType T);
+
+  /// GetFunctionType - Get the LLVM function type for \arg Info.
+  const llvm::FunctionType *GetFunctionType(const CGFunctionInfo &Info,
+                                            bool IsVariadic);
+
+  const llvm::FunctionType *GetFunctionType(GlobalDecl GD);
+
+
+  /// GetFunctionTypeForVTable - Get the LLVM function type for use in a vtable,
+  /// given a CXXMethodDecl. If the method to has an incomplete return type, 
+  /// and/or incomplete argument types, this will return the opaque type.
+  const llvm::Type *GetFunctionTypeForVTable(const CXXMethodDecl *MD);
+                                                     
+  const CGRecordLayout &getCGRecordLayout(const RecordDecl*) const;
+
+  /// UpdateCompletedType - When we find the full definition for a TagDecl,
+  /// replace the 'opaque' type we previously made for it if applicable.
+  void UpdateCompletedType(const TagDecl *TD);
+
+  /// getFunctionInfo - Get the function info for the specified function decl.
+  const CGFunctionInfo &getFunctionInfo(GlobalDecl GD);
+  
+  const CGFunctionInfo &getFunctionInfo(const FunctionDecl *FD);
+  const CGFunctionInfo &getFunctionInfo(const CXXMethodDecl *MD);
+  const CGFunctionInfo &getFunctionInfo(const ObjCMethodDecl *MD);
+  const CGFunctionInfo &getFunctionInfo(const CXXConstructorDecl *D,
+                                        CXXCtorType Type);
+  const CGFunctionInfo &getFunctionInfo(const CXXDestructorDecl *D,
+                                        CXXDtorType Type);
+
+  const CGFunctionInfo &getFunctionInfo(const CallArgList &Args,
+                                        const FunctionType *Ty) {
+    return getFunctionInfo(Ty->getResultType(), Args,
+                           Ty->getExtInfo());
+  }
+  const CGFunctionInfo &getFunctionInfo(CanQual<FunctionProtoType> Ty);
+  const CGFunctionInfo &getFunctionInfo(CanQual<FunctionNoProtoType> Ty);
+
+  // getFunctionInfo - Get the function info for a member function.
+  const CGFunctionInfo &getFunctionInfo(const CXXRecordDecl *RD,
+                                        const FunctionProtoType *FTP);
+  
+  /// getFunctionInfo - Get the function info for a function described by a
+  /// return type and argument types. If the calling convention is not
+  /// specified, the "C" calling convention will be used.
+  const CGFunctionInfo &getFunctionInfo(QualType ResTy,
+                                        const CallArgList &Args,
+                                        const FunctionType::ExtInfo &Info);
+  const CGFunctionInfo &getFunctionInfo(QualType ResTy,
+                                        const FunctionArgList &Args,
+                                        const FunctionType::ExtInfo &Info);
+
+  /// Retrieves the ABI information for the given function signature.
+  /// 
+  /// \param ArgTys - must all actually be canonical as params
+  const CGFunctionInfo &getFunctionInfo(CanQualType RetTy,
+                               const llvm::SmallVectorImpl<CanQualType> &ArgTys,
+                                        const FunctionType::ExtInfo &Info);
+
+  /// \brief Compute a new LLVM record layout object for the given record.
+  CGRecordLayout *ComputeRecordLayout(const RecordDecl *D);
+
+public:  // These are internal details of CGT that shouldn't be used externally.
+  /// ConvertTagDeclType - Lay out a tagged decl type like struct or union or
+  /// enum.
+  const llvm::Type *ConvertTagDeclType(const TagDecl *TD);
+
+  /// GetExpandedTypes - Expand the type \arg Ty into the LLVM
+  /// argument types it would be passed as on the provided vector \arg
+  /// ArgTys. See ABIArgInfo::Expand.
+  void GetExpandedTypes(QualType Ty, std::vector<const llvm::Type*> &ArgTys);
+};
+
+}  // end namespace CodeGen
+}  // end namespace clang
+
+#endif
diff --git a/lib/CodeGen/GlobalDecl.h b/lib/CodeGen/GlobalDecl.h
new file mode 100644
index 0000000..b8a98d7
--- /dev/null
+++ b/lib/CodeGen/GlobalDecl.h
@@ -0,0 +1,113 @@
+//===--- GlobalDecl.h - Global declaration holder ---------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// A GlobalDecl can hold either a regular variable/function or a C++ ctor/dtor
+// together with its type.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_CODEGEN_GLOBALDECL_H
+#define CLANG_CODEGEN_GLOBALDECL_H
+
+#include "CGCXX.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclObjC.h"
+
+namespace clang {
+
+namespace CodeGen {
+
+/// GlobalDecl - represents a global declaration. This can either be a
+/// CXXConstructorDecl and the constructor type (Base, Complete).
+/// a CXXDestructorDecl and the destructor type (Base, Complete) or
+/// a VarDecl, a FunctionDecl or a BlockDecl.
+class GlobalDecl {
+  llvm::PointerIntPair<const Decl*, 2> Value;
+
+  void Init(const Decl *D) {
+    assert(!isa<CXXConstructorDecl>(D) && "Use other ctor with ctor decls!");
+    assert(!isa<CXXDestructorDecl>(D) && "Use other ctor with dtor decls!");
+
+    Value.setPointer(D);
+  }
+  
+public:
+  GlobalDecl() {}
+
+  GlobalDecl(const VarDecl *D) { Init(D);}
+  GlobalDecl(const FunctionDecl *D) { Init(D); }
+  GlobalDecl(const BlockDecl *D) { Init(D); }
+  GlobalDecl(const ObjCMethodDecl *D) { Init(D); }
+
+  GlobalDecl(const CXXConstructorDecl *D, CXXCtorType Type)
+  : Value(D, Type) {}
+  GlobalDecl(const CXXDestructorDecl *D, CXXDtorType Type)
+  : Value(D, Type) {}
+
+  const Decl *getDecl() const { return Value.getPointer(); }
+
+  CXXCtorType getCtorType() const {
+    assert(isa<CXXConstructorDecl>(getDecl()) && "Decl is not a ctor!");
+    return static_cast<CXXCtorType>(Value.getInt());
+  }
+
+  CXXDtorType getDtorType() const {
+    assert(isa<CXXDestructorDecl>(getDecl()) && "Decl is not a dtor!");
+    return static_cast<CXXDtorType>(Value.getInt());
+  }
+  
+  friend bool operator==(const GlobalDecl &LHS, const GlobalDecl &RHS) {
+    return LHS.Value == RHS.Value;
+  }
+  
+  void *getAsOpaquePtr() const { return Value.getOpaqueValue(); }
+
+  static GlobalDecl getFromOpaquePtr(void *P) {
+    GlobalDecl GD;
+    GD.Value.setFromOpaqueValue(P);
+    return GD;
+  }
+};
+
+} // end namespace CodeGen
+} // end namespace clang
+
+namespace llvm {
+  template<class> struct DenseMapInfo;
+
+  template<> struct DenseMapInfo<clang::CodeGen::GlobalDecl> {
+    static inline clang::CodeGen::GlobalDecl getEmptyKey() {
+      return clang::CodeGen::GlobalDecl();
+    }
+  
+    static inline clang::CodeGen::GlobalDecl getTombstoneKey() {
+      return clang::CodeGen::GlobalDecl::
+        getFromOpaquePtr(reinterpret_cast<void*>(-1));
+    }
+
+    static unsigned getHashValue(clang::CodeGen::GlobalDecl GD) {
+      return DenseMapInfo<void*>::getHashValue(GD.getAsOpaquePtr());
+    }
+    
+    static bool isEqual(clang::CodeGen::GlobalDecl LHS, 
+                        clang::CodeGen::GlobalDecl RHS) {
+      return LHS == RHS;
+    }
+      
+  };
+  
+  // GlobalDecl isn't *technically* a POD type. However, its copy constructor,
+  // copy assignment operator, and destructor are all trivial.
+  template <>
+  struct isPodLike<clang::CodeGen::GlobalDecl> {
+    static const bool value = true;
+  };
+} // end namespace llvm
+
+#endif
diff --git a/lib/CodeGen/Makefile b/lib/CodeGen/Makefile
new file mode 100644
index 0000000..3cea6bb
--- /dev/null
+++ b/lib/CodeGen/Makefile
@@ -0,0 +1,25 @@
+##===- clang/lib/CodeGen/Makefile --------------------------*- Makefile -*-===##
+# 
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+# 
+##===----------------------------------------------------------------------===##
+#
+# This implements the AST -> LLVM code generation library for the 
+# C-Language front-end.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../../../..
+LIBRARYNAME := clangCodeGen
+BUILD_ARCHIVE = 1
+
+CPP.Flags += -I$(PROJ_SRC_DIR)/../../include -I$(PROJ_OBJ_DIR)/../../include
+ifdef CLANG_VENDOR
+CPP.Flags += -DCLANG_VENDOR='"$(CLANG_VENDOR) "'
+endif
+
+include $(LEVEL)/Makefile.common
+
diff --git a/lib/CodeGen/Mangle.cpp b/lib/CodeGen/Mangle.cpp
new file mode 100644
index 0000000..cb32570
--- /dev/null
+++ b/lib/CodeGen/Mangle.cpp
@@ -0,0 +1,2068 @@
+//===--- Mangle.cpp - Mangle C++ Names --------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Implements C++ name mangling according to the Itanium C++ ABI,
+// which is used in GCC 3.2 and newer (and many compilers that are
+// ABI-compatible with GCC):
+//
+//   http://www.codesourcery.com/public/cxx-abi/abi.html
+//
+//===----------------------------------------------------------------------===//
+#include "Mangle.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/Basic/SourceManager.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "CGVTables.h"
+
+#define MANGLE_CHECKER 0
+
+#if MANGLE_CHECKER
+#include <cxxabi.h>
+#endif
+
+using namespace clang;
+using namespace CodeGen;
+
+namespace {
+
+static const DeclContext *GetLocalClassFunctionDeclContext(
+                                                      const DeclContext *DC) {
+  if (isa<CXXRecordDecl>(DC)) {
+    while (!DC->isNamespace() && !DC->isTranslationUnit() &&
+           !isa<FunctionDecl>(DC))
+      DC = DC->getParent();
+    if (isa<FunctionDecl>(DC))
+      return DC;
+  }
+  return 0;
+}
+
+static const CXXMethodDecl *getStructor(const CXXMethodDecl *MD) {
+  assert((isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD)) &&
+         "Passed in decl is not a ctor or dtor!");
+
+  if (const TemplateDecl *TD = MD->getPrimaryTemplate()) {
+    MD = cast<CXXMethodDecl>(TD->getTemplatedDecl());
+
+    assert((isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD)) &&
+           "Templated decl is not a ctor or dtor!");
+  }
+
+  return MD;
+}
+
+static const unsigned UnknownArity = ~0U;
+
+/// CXXNameMangler - Manage the mangling of a single name.
+class CXXNameMangler {
+  MangleContext &Context;
+  llvm::raw_svector_ostream Out;
+
+  const CXXMethodDecl *Structor;
+  unsigned StructorType;
+
+  llvm::DenseMap<uintptr_t, unsigned> Substitutions;
+
+  ASTContext &getASTContext() const { return Context.getASTContext(); }
+
+public:
+  CXXNameMangler(MangleContext &C, llvm::SmallVectorImpl<char> &Res)
+    : Context(C), Out(Res), Structor(0), StructorType(0) { }
+  CXXNameMangler(MangleContext &C, llvm::SmallVectorImpl<char> &Res,
+                 const CXXConstructorDecl *D, CXXCtorType Type)
+    : Context(C), Out(Res), Structor(getStructor(D)), StructorType(Type) { }
+  CXXNameMangler(MangleContext &C, llvm::SmallVectorImpl<char> &Res,
+                 const CXXDestructorDecl *D, CXXDtorType Type)
+    : Context(C), Out(Res), Structor(getStructor(D)), StructorType(Type) { }
+
+#if MANGLE_CHECKER
+  ~CXXNameMangler() {
+    if (Out.str()[0] == '\01')
+      return;
+
+    int status = 0;
+    char *result = abi::__cxa_demangle(Out.str().str().c_str(), 0, 0, &status);
+    assert(status == 0 && "Could not demangle mangled name!");
+    free(result);
+  }
+#endif
+  llvm::raw_svector_ostream &getStream() { return Out; }
+
+  void mangle(const NamedDecl *D, llvm::StringRef Prefix = "_Z");
+  void mangleCallOffset(int64_t NonVirtual, int64_t Virtual);
+  void mangleNumber(int64_t Number);
+  void mangleFunctionEncoding(const FunctionDecl *FD);
+  void mangleName(const NamedDecl *ND);
+  void mangleType(QualType T);
+
+private:
+  bool mangleSubstitution(const NamedDecl *ND);
+  bool mangleSubstitution(QualType T);
+  bool mangleSubstitution(uintptr_t Ptr);
+
+  bool mangleStandardSubstitution(const NamedDecl *ND);
+
+  void addSubstitution(const NamedDecl *ND) {
+    ND = cast<NamedDecl>(ND->getCanonicalDecl());
+
+    addSubstitution(reinterpret_cast<uintptr_t>(ND));
+  }
+  void addSubstitution(QualType T);
+  void addSubstitution(uintptr_t Ptr);
+
+  void mangleUnresolvedScope(NestedNameSpecifier *Qualifier);
+  void mangleUnresolvedName(NestedNameSpecifier *Qualifier,
+                            DeclarationName Name,
+                            unsigned KnownArity = UnknownArity);
+
+  void mangleName(const TemplateDecl *TD,
+                  const TemplateArgument *TemplateArgs,
+                  unsigned NumTemplateArgs);
+  void mangleUnqualifiedName(const NamedDecl *ND) {
+    mangleUnqualifiedName(ND, ND->getDeclName(), UnknownArity);
+  }
+  void mangleUnqualifiedName(const NamedDecl *ND, DeclarationName Name,
+                             unsigned KnownArity);
+  void mangleUnscopedName(const NamedDecl *ND);
+  void mangleUnscopedTemplateName(const TemplateDecl *ND);
+  void mangleSourceName(const IdentifierInfo *II);
+  void mangleLocalName(const NamedDecl *ND);
+  void mangleNestedName(const NamedDecl *ND, const DeclContext *DC,
+                        bool NoFunction=false);
+  void mangleNestedName(const TemplateDecl *TD,
+                        const TemplateArgument *TemplateArgs,
+                        unsigned NumTemplateArgs);
+  void manglePrefix(const DeclContext *DC, bool NoFunction=false);
+  void mangleTemplatePrefix(const TemplateDecl *ND);
+  void mangleTemplatePrefix(TemplateName Template);
+  void mangleOperatorName(OverloadedOperatorKind OO, unsigned Arity);
+  void mangleQualifiers(Qualifiers Quals);
+
+  void mangleObjCMethodName(const ObjCMethodDecl *MD);
+
+  // Declare manglers for every type class.
+#define ABSTRACT_TYPE(CLASS, PARENT)
+#define NON_CANONICAL_TYPE(CLASS, PARENT)
+#define TYPE(CLASS, PARENT) void mangleType(const CLASS##Type *T);
+#include "clang/AST/TypeNodes.def"
+
+  void mangleType(const TagType*);
+  void mangleBareFunctionType(const FunctionType *T,
+                              bool MangleReturnType);
+
+  void mangleIntegerLiteral(QualType T, const llvm::APSInt &Value);
+  void mangleMemberExpr(const Expr *Base, bool IsArrow,
+                        NestedNameSpecifier *Qualifier,
+                        DeclarationName Name,
+                        unsigned KnownArity);
+  void mangleCalledExpression(const Expr *E, unsigned KnownArity);
+  void mangleExpression(const Expr *E);
+  void mangleCXXCtorType(CXXCtorType T);
+  void mangleCXXDtorType(CXXDtorType T);
+
+  void mangleTemplateArgs(TemplateName Template,
+                          const TemplateArgument *TemplateArgs,
+                          unsigned NumTemplateArgs);  
+  void mangleTemplateArgs(const TemplateParameterList &PL,
+                          const TemplateArgument *TemplateArgs,
+                          unsigned NumTemplateArgs);
+  void mangleTemplateArgs(const TemplateParameterList &PL,
+                          const TemplateArgumentList &AL);
+  void mangleTemplateArg(const NamedDecl *P, const TemplateArgument &A);
+
+  void mangleTemplateParameter(unsigned Index);
+};
+}
+
+static bool isInCLinkageSpecification(const Decl *D) {
+  D = D->getCanonicalDecl();
+  for (const DeclContext *DC = D->getDeclContext();
+       !DC->isTranslationUnit(); DC = DC->getParent()) {
+    if (const LinkageSpecDecl *Linkage = dyn_cast<LinkageSpecDecl>(DC))
+      return Linkage->getLanguage() == LinkageSpecDecl::lang_c;
+  }
+
+  return false;
+}
+
+bool MangleContext::shouldMangleDeclName(const NamedDecl *D) {
+  // In C, functions with no attributes never need to be mangled. Fastpath them.
+  if (!getASTContext().getLangOptions().CPlusPlus && !D->hasAttrs())
+    return false;
+
+  // Any decl can be declared with __asm("foo") on it, and this takes precedence
+  // over all other naming in the .o file.
+  if (D->hasAttr<AsmLabelAttr>())
+    return true;
+
+  // Clang's "overloadable" attribute extension to C/C++ implies name mangling
+  // (always) as does passing a C++ member function and a function
+  // whose name is not a simple identifier.
+  const FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
+  if (FD && (FD->hasAttr<OverloadableAttr>() || isa<CXXMethodDecl>(FD) ||
+             !FD->getDeclName().isIdentifier()))
+    return true;
+
+  // Otherwise, no mangling is done outside C++ mode.
+  if (!getASTContext().getLangOptions().CPlusPlus)
+    return false;
+
+  // Variables at global scope with non-internal linkage are not mangled
+  if (!FD) {
+    const DeclContext *DC = D->getDeclContext();
+    // Check for extern variable declared locally.
+    if (isa<FunctionDecl>(DC) && D->hasLinkage())
+      while (!DC->isNamespace() && !DC->isTranslationUnit())
+        DC = DC->getParent();
+    if (DC->isTranslationUnit() && D->getLinkage() != InternalLinkage)
+      return false;
+  }
+
+  // C functions and "main" are not mangled.
+  if ((FD && FD->isMain()) || isInCLinkageSpecification(D))
+    return false;
+
+  return true;
+}
+
+void CXXNameMangler::mangle(const NamedDecl *D, llvm::StringRef Prefix) {
+  // Any decl can be declared with __asm("foo") on it, and this takes precedence
+  // over all other naming in the .o file.
+  if (const AsmLabelAttr *ALA = D->getAttr<AsmLabelAttr>()) {
+    // If we have an asm name, then we use it as the mangling.
+    Out << '\01';  // LLVM IR Marker for __asm("foo")
+    Out << ALA->getLabel();
+    return;
+  }
+
+  // <mangled-name> ::= _Z <encoding>
+  //            ::= <data name>
+  //            ::= <special-name>
+  Out << Prefix;
+  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
+    mangleFunctionEncoding(FD);
+  else if (const VarDecl *VD = dyn_cast<VarDecl>(D))
+    mangleName(VD);
+  else
+    mangleName(cast<FieldDecl>(D));
+}
+
+void CXXNameMangler::mangleFunctionEncoding(const FunctionDecl *FD) {
+  // <encoding> ::= <function name> <bare-function-type>
+  mangleName(FD);
+
+  // Don't mangle in the type if this isn't a decl we should typically mangle.
+  if (!Context.shouldMangleDeclName(FD))
+    return;
+
+  // Whether the mangling of a function type includes the return type depends on
+  // the context and the nature of the function. The rules for deciding whether
+  // the return type is included are:
+  //
+  //   1. Template functions (names or types) have return types encoded, with
+  //   the exceptions listed below.
+  //   2. Function types not appearing as part of a function name mangling,
+  //   e.g. parameters, pointer types, etc., have return type encoded, with the
+  //   exceptions listed below.
+  //   3. Non-template function names do not have return types encoded.
+  //
+  // The exceptions mentioned in (1) and (2) above, for which the return type is
+  // never included, are
+  //   1. Constructors.
+  //   2. Destructors.
+  //   3. Conversion operator functions, e.g. operator int.
+  bool MangleReturnType = false;
+  if (FunctionTemplateDecl *PrimaryTemplate = FD->getPrimaryTemplate()) {
+    if (!(isa<CXXConstructorDecl>(FD) || isa<CXXDestructorDecl>(FD) ||
+          isa<CXXConversionDecl>(FD)))
+      MangleReturnType = true;
+
+    // Mangle the type of the primary template.
+    FD = PrimaryTemplate->getTemplatedDecl();
+  }
+
+  // Do the canonicalization out here because parameter types can
+  // undergo additional canonicalization (e.g. array decay).
+  FunctionType *FT = cast<FunctionType>(Context.getASTContext()
+                                          .getCanonicalType(FD->getType()));
+
+  mangleBareFunctionType(FT, MangleReturnType);
+}
+
+/// isStd - Return whether a given namespace is the 'std' namespace.
+static bool isStd(const NamespaceDecl *NS) {
+  const IdentifierInfo *II = NS->getOriginalNamespace()->getIdentifier();
+  return II && II->isStr("std");
+}
+
+static const DeclContext *IgnoreLinkageSpecDecls(const DeclContext *DC) {
+  while (isa<LinkageSpecDecl>(DC)) {
+    DC = DC->getParent();
+  }
+
+  return DC;
+}
+
+// isStdNamespace - Return whether a given decl context is a toplevel 'std'
+// namespace.
+static bool isStdNamespace(const DeclContext *DC) {
+  if (!DC->isNamespace())
+    return false;
+
+  if (!IgnoreLinkageSpecDecls(DC->getParent())->isTranslationUnit())
+    return false;
+
+  return isStd(cast<NamespaceDecl>(DC));
+}
+
+static const TemplateDecl *
+isTemplate(const NamedDecl *ND, const TemplateArgumentList *&TemplateArgs) {
+  // Check if we have a function template.
+  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)){
+    if (const TemplateDecl *TD = FD->getPrimaryTemplate()) {
+      TemplateArgs = FD->getTemplateSpecializationArgs();
+      return TD;
+    }
+  }
+
+  // Check if we have a class template.
+  if (const ClassTemplateSpecializationDecl *Spec =
+        dyn_cast<ClassTemplateSpecializationDecl>(ND)) {
+    TemplateArgs = &Spec->getTemplateArgs();
+    return Spec->getSpecializedTemplate();
+  }
+
+  return 0;
+}
+
+void CXXNameMangler::mangleName(const NamedDecl *ND) {
+  //  <name> ::= <nested-name>
+  //         ::= <unscoped-name>
+  //         ::= <unscoped-template-name> <template-args>
+  //         ::= <local-name>
+  //
+  const DeclContext *DC = ND->getDeclContext();
+
+  if (GetLocalClassFunctionDeclContext(DC)) {
+    mangleLocalName(ND);
+    return;
+  }
+
+  // If this is an extern variable declared locally, the relevant DeclContext
+  // is that of the containing namespace, or the translation unit.
+  if (isa<FunctionDecl>(DC) && ND->hasLinkage())
+    while (!DC->isNamespace() && !DC->isTranslationUnit())
+      DC = DC->getParent();
+
+  while (isa<LinkageSpecDecl>(DC))
+    DC = DC->getParent();
+
+  if (DC->isTranslationUnit() || isStdNamespace(DC)) {
+    // Check if we have a template.
+    const TemplateArgumentList *TemplateArgs = 0;
+    if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) {
+      mangleUnscopedTemplateName(TD);
+      TemplateParameterList *TemplateParameters = TD->getTemplateParameters();
+      mangleTemplateArgs(*TemplateParameters, *TemplateArgs);
+      return;
+    }
+
+    mangleUnscopedName(ND);
+    return;
+  }
+
+  if (isa<FunctionDecl>(DC) || isa<ObjCMethodDecl>(DC)) {
+    mangleLocalName(ND);
+    return;
+  }
+
+  mangleNestedName(ND, DC);
+}
+void CXXNameMangler::mangleName(const TemplateDecl *TD,
+                                const TemplateArgument *TemplateArgs,
+                                unsigned NumTemplateArgs) {
+  const DeclContext *DC = IgnoreLinkageSpecDecls(TD->getDeclContext());
+
+  if (DC->isTranslationUnit() || isStdNamespace(DC)) {
+    mangleUnscopedTemplateName(TD);
+    TemplateParameterList *TemplateParameters = TD->getTemplateParameters();
+    mangleTemplateArgs(*TemplateParameters, TemplateArgs, NumTemplateArgs);
+  } else {
+    mangleNestedName(TD, TemplateArgs, NumTemplateArgs);
+  }
+}
+
+void CXXNameMangler::mangleUnscopedName(const NamedDecl *ND) {
+  //  <unscoped-name> ::= <unqualified-name>
+  //                  ::= St <unqualified-name>   # ::std::
+  if (isStdNamespace(ND->getDeclContext()))
+    Out << "St";
+
+  mangleUnqualifiedName(ND);
+}
+
+void CXXNameMangler::mangleUnscopedTemplateName(const TemplateDecl *ND) {
+  //     <unscoped-template-name> ::= <unscoped-name>
+  //                              ::= <substitution>
+  if (mangleSubstitution(ND))
+    return;
+
+  // <template-template-param> ::= <template-param>
+  if (const TemplateTemplateParmDecl *TTP
+                                     = dyn_cast<TemplateTemplateParmDecl>(ND)) {
+    mangleTemplateParameter(TTP->getIndex());
+    return;
+  }
+
+  mangleUnscopedName(ND->getTemplatedDecl());
+  addSubstitution(ND);
+}
+
+void CXXNameMangler::mangleNumber(int64_t Number) {
+  //  <number> ::= [n] <non-negative decimal integer>
+  if (Number < 0) {
+    Out << 'n';
+    Number = -Number;
+  }
+
+  Out << Number;
+}
+
+void CXXNameMangler::mangleCallOffset(int64_t NonVirtual, int64_t Virtual) {
+  //  <call-offset>  ::= h <nv-offset> _
+  //                 ::= v <v-offset> _
+  //  <nv-offset>    ::= <offset number>        # non-virtual base override
+  //  <v-offset>     ::= <offset number> _ <virtual offset number>
+  //                      # virtual base override, with vcall offset
+  if (!Virtual) {
+    Out << 'h';
+    mangleNumber(NonVirtual);
+    Out << '_';
+    return;
+  }
+
+  Out << 'v';
+  mangleNumber(NonVirtual);
+  Out << '_';
+  mangleNumber(Virtual);
+  Out << '_';
+}
+
+void CXXNameMangler::mangleUnresolvedScope(NestedNameSpecifier *Qualifier) {
+  Qualifier = getASTContext().getCanonicalNestedNameSpecifier(Qualifier);
+  switch (Qualifier->getKind()) {
+  case NestedNameSpecifier::Global:
+    // nothing
+    break;
+  case NestedNameSpecifier::Namespace:
+    mangleName(Qualifier->getAsNamespace());
+    break;
+  case NestedNameSpecifier::TypeSpec:
+  case NestedNameSpecifier::TypeSpecWithTemplate: {
+    const Type *QTy = Qualifier->getAsType();
+
+    if (const TemplateSpecializationType *TST =
+        dyn_cast<TemplateSpecializationType>(QTy)) {
+      if (!mangleSubstitution(QualType(TST, 0))) {
+        mangleTemplatePrefix(TST->getTemplateName());
+        
+        // FIXME: GCC does not appear to mangle the template arguments when
+        // the template in question is a dependent template name. Should we
+        // emulate that badness?
+        mangleTemplateArgs(TST->getTemplateName(), TST->getArgs(),
+                           TST->getNumArgs());
+        addSubstitution(QualType(TST, 0));
+      }
+    } else {
+      // We use the QualType mangle type variant here because it handles
+      // substitutions.
+      mangleType(QualType(QTy, 0));
+    }
+  }
+    break;
+  case NestedNameSpecifier::Identifier:
+    // Member expressions can have these without prefixes.
+    if (Qualifier->getPrefix())
+      mangleUnresolvedScope(Qualifier->getPrefix());
+    mangleSourceName(Qualifier->getAsIdentifier());
+    break;
+  }
+}
+
+/// Mangles a name which was not resolved to a specific entity.
+void CXXNameMangler::mangleUnresolvedName(NestedNameSpecifier *Qualifier,
+                                          DeclarationName Name,
+                                          unsigned KnownArity) {
+  if (Qualifier)
+    mangleUnresolvedScope(Qualifier);
+  // FIXME: ambiguity of unqualified lookup with ::
+
+  mangleUnqualifiedName(0, Name, KnownArity);
+}
+
+void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,
+                                           DeclarationName Name,
+                                           unsigned KnownArity) {
+  //  <unqualified-name> ::= <operator-name>
+  //                     ::= <ctor-dtor-name>
+  //                     ::= <source-name>
+  switch (Name.getNameKind()) {
+  case DeclarationName::Identifier: {
+    if (const IdentifierInfo *II = Name.getAsIdentifierInfo()) {
+      // We must avoid conflicts between internally- and externally-
+      // linked variable declaration names in the same TU.
+      // This naming convention is the same as that followed by GCC, though it
+      // shouldn't actually matter.
+      if (ND && isa<VarDecl>(ND) && ND->getLinkage() == InternalLinkage &&
+          ND->getDeclContext()->isFileContext())
+        Out << 'L';
+
+      mangleSourceName(II);
+      break;
+    }
+
+    // Otherwise, an anonymous entity.  We must have a declaration.
+    assert(ND && "mangling empty name without declaration");
+
+    if (const NamespaceDecl *NS = dyn_cast<NamespaceDecl>(ND)) {
+      if (NS->isAnonymousNamespace()) {
+        // This is how gcc mangles these names.
+        Out << "12_GLOBAL__N_1";
+        break;
+      }
+    }
+
+    // We must have an anonymous struct.
+    const TagDecl *TD = cast<TagDecl>(ND);
+    if (const TypedefDecl *D = TD->getTypedefForAnonDecl()) {
+      assert(TD->getDeclContext() == D->getDeclContext() &&
+             "Typedef should not be in another decl context!");
+      assert(D->getDeclName().getAsIdentifierInfo() &&
+             "Typedef was not named!");
+      mangleSourceName(D->getDeclName().getAsIdentifierInfo());
+      break;
+    }
+
+    // Get a unique id for the anonymous struct.
+    uint64_t AnonStructId = Context.getAnonymousStructId(TD);
+
+    // Mangle it as a source name in the form
+    // [n] $_<id>
+    // where n is the length of the string.
+    llvm::SmallString<8> Str;
+    Str += "$_";
+    Str += llvm::utostr(AnonStructId);
+
+    Out << Str.size();
+    Out << Str.str();
+    break;
+  }
+
+  case DeclarationName::ObjCZeroArgSelector:
+  case DeclarationName::ObjCOneArgSelector:
+  case DeclarationName::ObjCMultiArgSelector:
+    assert(false && "Can't mangle Objective-C selector names here!");
+    break;
+
+  case DeclarationName::CXXConstructorName:
+    if (ND == Structor)
+      // If the named decl is the C++ constructor we're mangling, use the type
+      // we were given.
+      mangleCXXCtorType(static_cast<CXXCtorType>(StructorType));
+    else
+      // Otherwise, use the complete constructor name. This is relevant if a
+      // class with a constructor is declared within a constructor.
+      mangleCXXCtorType(Ctor_Complete);
+    break;
+
+  case DeclarationName::CXXDestructorName:
+    if (ND == Structor)
+      // If the named decl is the C++ destructor we're mangling, use the type we
+      // were given.
+      mangleCXXDtorType(static_cast<CXXDtorType>(StructorType));
+    else
+      // Otherwise, use the complete destructor name. This is relevant if a
+      // class with a destructor is declared within a destructor.
+      mangleCXXDtorType(Dtor_Complete);
+    break;
+
+  case DeclarationName::CXXConversionFunctionName:
+    // <operator-name> ::= cv <type>    # (cast)
+    Out << "cv";
+    mangleType(Context.getASTContext().getCanonicalType(Name.getCXXNameType()));
+    break;
+
+  case DeclarationName::CXXOperatorName: {
+    unsigned Arity;
+    if (ND) {
+      Arity = cast<FunctionDecl>(ND)->getNumParams();
+
+      // If we have a C++ member function, we need to include the 'this' pointer.
+      // FIXME: This does not make sense for operators that are static, but their
+      // names stay the same regardless of the arity (operator new for instance).
+      if (isa<CXXMethodDecl>(ND))
+        Arity++;
+    } else
+      Arity = KnownArity;
+
+    mangleOperatorName(Name.getCXXOverloadedOperator(), Arity);
+    break;
+  }
+
+  case DeclarationName::CXXLiteralOperatorName:
+    // FIXME: This mangling is not yet official.
+    Out << "li";
+    mangleSourceName(Name.getCXXLiteralIdentifier());
+    break;
+
+  case DeclarationName::CXXUsingDirective:
+    assert(false && "Can't mangle a using directive name!");
+    break;
+  }
+}
+
+void CXXNameMangler::mangleSourceName(const IdentifierInfo *II) {
+  // <source-name> ::= <positive length number> <identifier>
+  // <number> ::= [n] <non-negative decimal integer>
+  // <identifier> ::= <unqualified source code identifier>
+  Out << II->getLength() << II->getName();
+}
+
+void CXXNameMangler::mangleNestedName(const NamedDecl *ND,
+                                      const DeclContext *DC,
+                                      bool NoFunction) {
+  // <nested-name> ::= N [<CV-qualifiers>] <prefix> <unqualified-name> E
+  //               ::= N [<CV-qualifiers>] <template-prefix> <template-args> E
+
+  Out << 'N';
+  if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(ND))
+    mangleQualifiers(Qualifiers::fromCVRMask(Method->getTypeQualifiers()));
+
+  // Check if we have a template.
+  const TemplateArgumentList *TemplateArgs = 0;
+  if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) {
+    mangleTemplatePrefix(TD);
+    TemplateParameterList *TemplateParameters = TD->getTemplateParameters();
+    mangleTemplateArgs(*TemplateParameters, *TemplateArgs);
+  }
+  else {
+    manglePrefix(DC, NoFunction);
+    mangleUnqualifiedName(ND);
+  }
+
+  Out << 'E';
+}
+void CXXNameMangler::mangleNestedName(const TemplateDecl *TD,
+                                      const TemplateArgument *TemplateArgs,
+                                      unsigned NumTemplateArgs) {
+  // <nested-name> ::= N [<CV-qualifiers>] <template-prefix> <template-args> E
+
+  Out << 'N';
+
+  mangleTemplatePrefix(TD);
+  TemplateParameterList *TemplateParameters = TD->getTemplateParameters();
+  mangleTemplateArgs(*TemplateParameters, TemplateArgs, NumTemplateArgs);
+
+  Out << 'E';
+}
+
+void CXXNameMangler::mangleLocalName(const NamedDecl *ND) {
+  // <local-name> := Z <function encoding> E <entity name> [<discriminator>]
+  //              := Z <function encoding> E s [<discriminator>]
+  // <discriminator> := _ <non-negative number>
+  const DeclContext *DC = ND->getDeclContext();
+  Out << 'Z';
+
+  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(DC))
+    mangleObjCMethodName(MD);
+  else if (const DeclContext *CDC = GetLocalClassFunctionDeclContext(DC)) {
+    mangleFunctionEncoding(cast<FunctionDecl>(CDC));
+    Out << 'E';
+    mangleNestedName(ND, DC, true /*NoFunction*/);
+
+    // FIXME. This still does not cover all cases.
+    unsigned disc;
+    if (Context.getNextDiscriminator(ND, disc)) {
+      if (disc < 10)
+        Out << '_' << disc;
+      else
+        Out << "__" << disc << '_';
+    }
+
+    return;
+  }
+  else
+    mangleFunctionEncoding(cast<FunctionDecl>(DC));
+
+  Out << 'E';
+  mangleUnqualifiedName(ND);
+}
+
+void CXXNameMangler::manglePrefix(const DeclContext *DC, bool NoFunction) {
+  //  <prefix> ::= <prefix> <unqualified-name>
+  //           ::= <template-prefix> <template-args>
+  //           ::= <template-param>
+  //           ::= # empty
+  //           ::= <substitution>
+
+  while (isa<LinkageSpecDecl>(DC))
+    DC = DC->getParent();
+
+  if (DC->isTranslationUnit())
+    return;
+
+  if (mangleSubstitution(cast<NamedDecl>(DC)))
+    return;
+
+  // Check if we have a template.
+  const TemplateArgumentList *TemplateArgs = 0;
+  if (const TemplateDecl *TD = isTemplate(cast<NamedDecl>(DC), TemplateArgs)) {
+    mangleTemplatePrefix(TD);
+    TemplateParameterList *TemplateParameters = TD->getTemplateParameters();
+    mangleTemplateArgs(*TemplateParameters, *TemplateArgs);
+  }
+  else if(NoFunction && isa<FunctionDecl>(DC))
+    return;
+  else {
+    manglePrefix(DC->getParent(), NoFunction);
+    mangleUnqualifiedName(cast<NamedDecl>(DC));
+  }
+
+  addSubstitution(cast<NamedDecl>(DC));
+}
+
+void CXXNameMangler::mangleTemplatePrefix(TemplateName Template) {
+  // <template-prefix> ::= <prefix> <template unqualified-name>
+  //                   ::= <template-param>
+  //                   ::= <substitution>
+  if (TemplateDecl *TD = Template.getAsTemplateDecl())
+    return mangleTemplatePrefix(TD);
+
+  if (QualifiedTemplateName *Qualified = Template.getAsQualifiedTemplateName())
+    mangleUnresolvedScope(Qualified->getQualifier());
+  
+  if (OverloadedTemplateStorage *Overloaded
+                                      = Template.getAsOverloadedTemplate()) {
+    mangleUnqualifiedName(0, (*Overloaded->begin())->getDeclName(), 
+                          UnknownArity);
+    return;
+  }
+   
+  DependentTemplateName *Dependent = Template.getAsDependentTemplateName();
+  assert(Dependent && "Unknown template name kind?");
+  mangleUnresolvedScope(Dependent->getQualifier());
+  if (Dependent->isIdentifier())
+    mangleSourceName(Dependent->getIdentifier());
+  else {
+    // FIXME: We can't possibly know the arity of the operator here!
+    Diagnostic &Diags = Context.getDiags();
+    unsigned DiagID = Diags.getCustomDiagID(Diagnostic::Error,
+                                 "cannot mangle dependent operator name");
+    Diags.Report(FullSourceLoc(), DiagID);
+  }
+}
+
+void CXXNameMangler::mangleTemplatePrefix(const TemplateDecl *ND) {
+  // <template-prefix> ::= <prefix> <template unqualified-name>
+  //                   ::= <template-param>
+  //                   ::= <substitution>
+  // <template-template-param> ::= <template-param>
+  //                               <substitution>
+
+  if (mangleSubstitution(ND))
+    return;
+
+  // <template-template-param> ::= <template-param>
+  if (const TemplateTemplateParmDecl *TTP
+                                     = dyn_cast<TemplateTemplateParmDecl>(ND)) {
+    mangleTemplateParameter(TTP->getIndex());
+    return;
+  }
+
+  manglePrefix(ND->getDeclContext());
+  mangleUnqualifiedName(ND->getTemplatedDecl());
+  addSubstitution(ND);
+}
+
+void
+CXXNameMangler::mangleOperatorName(OverloadedOperatorKind OO, unsigned Arity) {
+  switch (OO) {
+  // <operator-name> ::= nw     # new
+  case OO_New: Out << "nw"; break;
+  //              ::= na        # new[]
+  case OO_Array_New: Out << "na"; break;
+  //              ::= dl        # delete
+  case OO_Delete: Out << "dl"; break;
+  //              ::= da        # delete[]
+  case OO_Array_Delete: Out << "da"; break;
+  //              ::= ps        # + (unary)
+  //              ::= pl        # +
+  case OO_Plus:
+    assert((Arity == 1 || Arity == 2) && "Invalid arity!");
+    Out << (Arity == 1? "ps" : "pl"); break;
+  //              ::= ng        # - (unary)
+  //              ::= mi        # -
+  case OO_Minus:
+    assert((Arity == 1 || Arity == 2) && "Invalid arity!");
+    Out << (Arity == 1? "ng" : "mi"); break;
+  //              ::= ad        # & (unary)
+  //              ::= an        # &
+  case OO_Amp:
+    assert((Arity == 1 || Arity == 2) && "Invalid arity!");
+    Out << (Arity == 1? "ad" : "an"); break;
+  //              ::= de        # * (unary)
+  //              ::= ml        # *
+  case OO_Star:
+    assert((Arity == 1 || Arity == 2) && "Invalid arity!");
+    Out << (Arity == 1? "de" : "ml"); break;
+  //              ::= co        # ~
+  case OO_Tilde: Out << "co"; break;
+  //              ::= dv        # /
+  case OO_Slash: Out << "dv"; break;
+  //              ::= rm        # %
+  case OO_Percent: Out << "rm"; break;
+  //              ::= or        # |
+  case OO_Pipe: Out << "or"; break;
+  //              ::= eo        # ^
+  case OO_Caret: Out << "eo"; break;
+  //              ::= aS        # =
+  case OO_Equal: Out << "aS"; break;
+  //              ::= pL        # +=
+  case OO_PlusEqual: Out << "pL"; break;
+  //              ::= mI        # -=
+  case OO_MinusEqual: Out << "mI"; break;
+  //              ::= mL        # *=
+  case OO_StarEqual: Out << "mL"; break;
+  //              ::= dV        # /=
+  case OO_SlashEqual: Out << "dV"; break;
+  //              ::= rM        # %=
+  case OO_PercentEqual: Out << "rM"; break;
+  //              ::= aN        # &=
+  case OO_AmpEqual: Out << "aN"; break;
+  //              ::= oR        # |=
+  case OO_PipeEqual: Out << "oR"; break;
+  //              ::= eO        # ^=
+  case OO_CaretEqual: Out << "eO"; break;
+  //              ::= ls        # <<
+  case OO_LessLess: Out << "ls"; break;
+  //              ::= rs        # >>
+  case OO_GreaterGreater: Out << "rs"; break;
+  //              ::= lS        # <<=
+  case OO_LessLessEqual: Out << "lS"; break;
+  //              ::= rS        # >>=
+  case OO_GreaterGreaterEqual: Out << "rS"; break;
+  //              ::= eq        # ==
+  case OO_EqualEqual: Out << "eq"; break;
+  //              ::= ne        # !=
+  case OO_ExclaimEqual: Out << "ne"; break;
+  //              ::= lt        # <
+  case OO_Less: Out << "lt"; break;
+  //              ::= gt        # >
+  case OO_Greater: Out << "gt"; break;
+  //              ::= le        # <=
+  case OO_LessEqual: Out << "le"; break;
+  //              ::= ge        # >=
+  case OO_GreaterEqual: Out << "ge"; break;
+  //              ::= nt        # !
+  case OO_Exclaim: Out << "nt"; break;
+  //              ::= aa        # &&
+  case OO_AmpAmp: Out << "aa"; break;
+  //              ::= oo        # ||
+  case OO_PipePipe: Out << "oo"; break;
+  //              ::= pp        # ++
+  case OO_PlusPlus: Out << "pp"; break;
+  //              ::= mm        # --
+  case OO_MinusMinus: Out << "mm"; break;
+  //              ::= cm        # ,
+  case OO_Comma: Out << "cm"; break;
+  //              ::= pm        # ->*
+  case OO_ArrowStar: Out << "pm"; break;
+  //              ::= pt        # ->
+  case OO_Arrow: Out << "pt"; break;
+  //              ::= cl        # ()
+  case OO_Call: Out << "cl"; break;
+  //              ::= ix        # []
+  case OO_Subscript: Out << "ix"; break;
+
+  //              ::= qu        # ?
+  // The conditional operator can't be overloaded, but we still handle it when
+  // mangling expressions.
+  case OO_Conditional: Out << "qu"; break;
+
+  case OO_None:
+  case NUM_OVERLOADED_OPERATORS:
+    assert(false && "Not an overloaded operator");
+    break;
+  }
+}
+
+void CXXNameMangler::mangleQualifiers(Qualifiers Quals) {
+  // <CV-qualifiers> ::= [r] [V] [K]    # restrict (C99), volatile, const
+  if (Quals.hasRestrict())
+    Out << 'r';
+  if (Quals.hasVolatile())
+    Out << 'V';
+  if (Quals.hasConst())
+    Out << 'K';
+
+  // FIXME: For now, just drop all extension qualifiers on the floor.
+}
+
+void CXXNameMangler::mangleObjCMethodName(const ObjCMethodDecl *MD) {
+  llvm::SmallString<64> Name;
+  llvm::raw_svector_ostream OS(Name);
+
+  const ObjCContainerDecl *CD =
+    dyn_cast<ObjCContainerDecl>(MD->getDeclContext());
+  assert (CD && "Missing container decl in GetNameForMethod");
+  OS << (MD->isInstanceMethod() ? '-' : '+') << '[' << CD->getName();
+  if (const ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(CD))
+    OS << '(' << CID << ')';
+  OS << ' ' << MD->getSelector().getAsString() << ']';
+
+  Out << OS.str().size() << OS.str();
+}
+
+void CXXNameMangler::mangleType(QualType T) {
+  // Only operate on the canonical type!
+  T = Context.getASTContext().getCanonicalType(T);
+
+  bool IsSubstitutable = T.hasLocalQualifiers() || !isa<BuiltinType>(T);
+  if (IsSubstitutable && mangleSubstitution(T))
+    return;
+
+  if (Qualifiers Quals = T.getLocalQualifiers()) {
+    mangleQualifiers(Quals);
+    // Recurse:  even if the qualified type isn't yet substitutable,
+    // the unqualified type might be.
+    mangleType(T.getLocalUnqualifiedType());
+  } else {
+    switch (T->getTypeClass()) {
+#define ABSTRACT_TYPE(CLASS, PARENT)
+#define NON_CANONICAL_TYPE(CLASS, PARENT) \
+    case Type::CLASS: \
+      llvm_unreachable("can't mangle non-canonical type " #CLASS "Type"); \
+      return;
+#define TYPE(CLASS, PARENT) \
+    case Type::CLASS: \
+      mangleType(static_cast<const CLASS##Type*>(T.getTypePtr())); \
+      break;
+#include "clang/AST/TypeNodes.def"
+    }
+  }
+
+  // Add the substitution.
+  if (IsSubstitutable)
+    addSubstitution(T);
+}
+
+void CXXNameMangler::mangleType(const BuiltinType *T) {
+  //  <type>         ::= <builtin-type>
+  //  <builtin-type> ::= v  # void
+  //                 ::= w  # wchar_t
+  //                 ::= b  # bool
+  //                 ::= c  # char
+  //                 ::= a  # signed char
+  //                 ::= h  # unsigned char
+  //                 ::= s  # short
+  //                 ::= t  # unsigned short
+  //                 ::= i  # int
+  //                 ::= j  # unsigned int
+  //                 ::= l  # long
+  //                 ::= m  # unsigned long
+  //                 ::= x  # long long, __int64
+  //                 ::= y  # unsigned long long, __int64
+  //                 ::= n  # __int128
+  // UNSUPPORTED:    ::= o  # unsigned __int128
+  //                 ::= f  # float
+  //                 ::= d  # double
+  //                 ::= e  # long double, __float80
+  // UNSUPPORTED:    ::= g  # __float128
+  // UNSUPPORTED:    ::= Dd # IEEE 754r decimal floating point (64 bits)
+  // UNSUPPORTED:    ::= De # IEEE 754r decimal floating point (128 bits)
+  // UNSUPPORTED:    ::= Df # IEEE 754r decimal floating point (32 bits)
+  // UNSUPPORTED:    ::= Dh # IEEE 754r half-precision floating point (16 bits)
+  //                 ::= Di # char32_t
+  //                 ::= Ds # char16_t
+  //                 ::= u <source-name>    # vendor extended type
+  // From our point of view, std::nullptr_t is a builtin, but as far as mangling
+  // is concerned, it's a type called std::nullptr_t.
+  switch (T->getKind()) {
+  case BuiltinType::Void: Out << 'v'; break;
+  case BuiltinType::Bool: Out << 'b'; break;
+  case BuiltinType::Char_U: case BuiltinType::Char_S: Out << 'c'; break;
+  case BuiltinType::UChar: Out << 'h'; break;
+  case BuiltinType::UShort: Out << 't'; break;
+  case BuiltinType::UInt: Out << 'j'; break;
+  case BuiltinType::ULong: Out << 'm'; break;
+  case BuiltinType::ULongLong: Out << 'y'; break;
+  case BuiltinType::UInt128: Out << 'o'; break;
+  case BuiltinType::SChar: Out << 'a'; break;
+  case BuiltinType::WChar: Out << 'w'; break;
+  case BuiltinType::Char16: Out << "Ds"; break;
+  case BuiltinType::Char32: Out << "Di"; break;
+  case BuiltinType::Short: Out << 's'; break;
+  case BuiltinType::Int: Out << 'i'; break;
+  case BuiltinType::Long: Out << 'l'; break;
+  case BuiltinType::LongLong: Out << 'x'; break;
+  case BuiltinType::Int128: Out << 'n'; break;
+  case BuiltinType::Float: Out << 'f'; break;
+  case BuiltinType::Double: Out << 'd'; break;
+  case BuiltinType::LongDouble: Out << 'e'; break;
+  case BuiltinType::NullPtr: Out << "St9nullptr_t"; break;
+
+  case BuiltinType::Overload:
+  case BuiltinType::Dependent:
+    assert(false &&
+           "Overloaded and dependent types shouldn't get to name mangling");
+    break;
+  case BuiltinType::UndeducedAuto:
+    assert(0 && "Should not see undeduced auto here");
+    break;
+  case BuiltinType::ObjCId: Out << "11objc_object"; break;
+  case BuiltinType::ObjCClass: Out << "10objc_class"; break;
+  case BuiltinType::ObjCSel: Out << "13objc_selector"; break;
+  }
+}
+
+// <type>          ::= <function-type>
+// <function-type> ::= F [Y] <bare-function-type> E
+void CXXNameMangler::mangleType(const FunctionProtoType *T) {
+  Out << 'F';
+  // FIXME: We don't have enough information in the AST to produce the 'Y'
+  // encoding for extern "C" function types.
+  mangleBareFunctionType(T, /*MangleReturnType=*/true);
+  Out << 'E';
+}
+void CXXNameMangler::mangleType(const FunctionNoProtoType *T) {
+  llvm_unreachable("Can't mangle K&R function prototypes");
+}
+void CXXNameMangler::mangleBareFunctionType(const FunctionType *T,
+                                            bool MangleReturnType) {
+  // We should never be mangling something without a prototype.
+  const FunctionProtoType *Proto = cast<FunctionProtoType>(T);
+
+  // <bare-function-type> ::= <signature type>+
+  if (MangleReturnType)
+    mangleType(Proto->getResultType());
+
+  if (Proto->getNumArgs() == 0) {
+    Out << 'v';
+    return;
+  }
+
+  for (FunctionProtoType::arg_type_iterator Arg = Proto->arg_type_begin(),
+                                         ArgEnd = Proto->arg_type_end();
+       Arg != ArgEnd; ++Arg)
+    mangleType(*Arg);
+
+  // <builtin-type>      ::= z  # ellipsis
+  if (Proto->isVariadic())
+    Out << 'z';
+}
+
+// <type>            ::= <class-enum-type>
+// <class-enum-type> ::= <name>
+void CXXNameMangler::mangleType(const UnresolvedUsingType *T) {
+  mangleName(T->getDecl());
+}
+
+// <type>            ::= <class-enum-type>
+// <class-enum-type> ::= <name>
+void CXXNameMangler::mangleType(const EnumType *T) {
+  mangleType(static_cast<const TagType*>(T));
+}
+void CXXNameMangler::mangleType(const RecordType *T) {
+  mangleType(static_cast<const TagType*>(T));
+}
+void CXXNameMangler::mangleType(const TagType *T) {
+  mangleName(T->getDecl());
+}
+
+// <type>       ::= <array-type>
+// <array-type> ::= A <positive dimension number> _ <element type>
+//              ::= A [<dimension expression>] _ <element type>
+void CXXNameMangler::mangleType(const ConstantArrayType *T) {
+  Out << 'A' << T->getSize() << '_';
+  mangleType(T->getElementType());
+}
+void CXXNameMangler::mangleType(const VariableArrayType *T) {
+  Out << 'A';
+  mangleExpression(T->getSizeExpr());
+  Out << '_';
+  mangleType(T->getElementType());
+}
+void CXXNameMangler::mangleType(const DependentSizedArrayType *T) {
+  Out << 'A';
+  mangleExpression(T->getSizeExpr());
+  Out << '_';
+  mangleType(T->getElementType());
+}
+void CXXNameMangler::mangleType(const IncompleteArrayType *T) {
+  Out << 'A' << '_';
+  mangleType(T->getElementType());
+}
+
+// <type>                   ::= <pointer-to-member-type>
+// <pointer-to-member-type> ::= M <class type> <member type>
+void CXXNameMangler::mangleType(const MemberPointerType *T) {
+  Out << 'M';
+  mangleType(QualType(T->getClass(), 0));
+  QualType PointeeType = T->getPointeeType();
+  if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(PointeeType)) {
+    mangleQualifiers(Qualifiers::fromCVRMask(FPT->getTypeQuals()));
+    mangleType(FPT);
+  } else
+    mangleType(PointeeType);
+}
+
+// <type>           ::= <template-param>
+void CXXNameMangler::mangleType(const TemplateTypeParmType *T) {
+  mangleTemplateParameter(T->getIndex());
+}
+
+// FIXME: <type> ::= <template-template-param> <template-args>
+
+// <type> ::= P <type>   # pointer-to
+void CXXNameMangler::mangleType(const PointerType *T) {
+  Out << 'P';
+  mangleType(T->getPointeeType());
+}
+void CXXNameMangler::mangleType(const ObjCObjectPointerType *T) {
+  Out << 'P';
+  mangleType(T->getPointeeType());
+}
+
+// <type> ::= R <type>   # reference-to
+void CXXNameMangler::mangleType(const LValueReferenceType *T) {
+  Out << 'R';
+  mangleType(T->getPointeeType());
+}
+
+// <type> ::= O <type>   # rvalue reference-to (C++0x)
+void CXXNameMangler::mangleType(const RValueReferenceType *T) {
+  Out << 'O';
+  mangleType(T->getPointeeType());
+}
+
+// <type> ::= C <type>   # complex pair (C 2000)
+void CXXNameMangler::mangleType(const ComplexType *T) {
+  Out << 'C';
+  mangleType(T->getElementType());
+}
+
+// GNU extension: vector types
+// <type>        ::= <vector-type>
+// <vector-type> ::= Dv <positive dimension number> _ <element type>
+//               ::= Dv [<dimension expression>] _ <element type>
+void CXXNameMangler::mangleType(const VectorType *T) {
+  Out << "Dv" << T->getNumElements() << '_';
+  mangleType(T->getElementType());
+}
+void CXXNameMangler::mangleType(const ExtVectorType *T) {
+  mangleType(static_cast<const VectorType*>(T));
+}
+void CXXNameMangler::mangleType(const DependentSizedExtVectorType *T) {
+  Out << "Dv";
+  mangleExpression(T->getSizeExpr());
+  Out << '_';
+  mangleType(T->getElementType());
+}
+
+void CXXNameMangler::mangleType(const ObjCInterfaceType *T) {
+  mangleSourceName(T->getDecl()->getIdentifier());
+}
+
+void CXXNameMangler::mangleType(const BlockPointerType *T) {
+  Out << "U13block_pointer";
+  mangleType(T->getPointeeType());
+}
+
+void CXXNameMangler::mangleType(const InjectedClassNameType *T) {
+  // Mangle injected class name types as if the user had written the
+  // specialization out fully.  It may not actually be possible to see
+  // this mangling, though.
+  mangleType(T->getInjectedSpecializationType());
+}
+
+void CXXNameMangler::mangleType(const TemplateSpecializationType *T) {
+  TemplateDecl *TD = T->getTemplateName().getAsTemplateDecl();
+  assert(TD && "FIXME: Support dependent template names!");
+
+  mangleName(TD, T->getArgs(), T->getNumArgs());
+}
+
+void CXXNameMangler::mangleType(const DependentNameType *T) {
+  // Typename types are always nested
+  Out << 'N';
+  mangleUnresolvedScope(T->getQualifier());
+  mangleSourceName(T->getIdentifier());
+  Out << 'E';
+}
+
+void CXXNameMangler::mangleType(const TypeOfType *T) {
+  // FIXME: this is pretty unsatisfactory, but there isn't an obvious
+  // "extension with parameters" mangling.
+  Out << "u6typeof";
+}
+
+void CXXNameMangler::mangleType(const TypeOfExprType *T) {
+  // FIXME: this is pretty unsatisfactory, but there isn't an obvious
+  // "extension with parameters" mangling.
+  Out << "u6typeof";
+}
+
+void CXXNameMangler::mangleType(const DecltypeType *T) {
+  Expr *E = T->getUnderlyingExpr();
+
+  // type ::= Dt <expression> E  # decltype of an id-expression
+  //                             #   or class member access
+  //      ::= DT <expression> E  # decltype of an expression
+
+  // This purports to be an exhaustive list of id-expressions and
+  // class member accesses.  Note that we do not ignore parentheses;
+  // parentheses change the semantics of decltype for these
+  // expressions (and cause the mangler to use the other form).
+  if (isa<DeclRefExpr>(E) ||
+      isa<MemberExpr>(E) ||
+      isa<UnresolvedLookupExpr>(E) ||
+      isa<DependentScopeDeclRefExpr>(E) ||
+      isa<CXXDependentScopeMemberExpr>(E) ||
+      isa<UnresolvedMemberExpr>(E))
+    Out << "Dt";
+  else
+    Out << "DT";
+  mangleExpression(E);
+  Out << 'E';
+}
+
+void CXXNameMangler::mangleIntegerLiteral(QualType T,
+                                          const llvm::APSInt &Value) {
+  //  <expr-primary> ::= L <type> <value number> E # integer literal
+  Out << 'L';
+
+  mangleType(T);
+  if (T->isBooleanType()) {
+    // Boolean values are encoded as 0/1.
+    Out << (Value.getBoolValue() ? '1' : '0');
+  } else {
+    if (Value.isNegative())
+      Out << 'n';
+    Value.abs().print(Out, false);
+  }
+  Out << 'E';
+
+}
+
+void CXXNameMangler::mangleCalledExpression(const Expr *E, unsigned Arity) {
+  if (E->getType() != getASTContext().OverloadTy)
+    mangleExpression(E);
+  // propagate arity to dependent overloads?
+
+  llvm::PointerIntPair<OverloadExpr*,1> R
+    = OverloadExpr::find(const_cast<Expr*>(E));
+  if (R.getInt())
+    Out << "an"; // &
+  const OverloadExpr *Ovl = R.getPointer();
+  if (const UnresolvedMemberExpr *ME = dyn_cast<UnresolvedMemberExpr>(Ovl)) {
+    mangleMemberExpr(ME->getBase(), ME->isArrow(), ME->getQualifier(),
+                     ME->getMemberName(), Arity);
+    return;
+  }
+
+  mangleUnresolvedName(Ovl->getQualifier(), Ovl->getName(), Arity);
+}
+
+/// Mangles a member expression.  Implicit accesses are not handled,
+/// but that should be okay, because you shouldn't be able to
+/// make an implicit access in a function template declaration.
+void CXXNameMangler::mangleMemberExpr(const Expr *Base,
+                                      bool IsArrow,
+                                      NestedNameSpecifier *Qualifier,
+                                      DeclarationName Member,
+                                      unsigned Arity) {
+  // gcc-4.4 uses 'dt' for dot expressions, which is reasonable.
+  // OTOH, gcc also mangles the name as an expression.
+  Out << (IsArrow ? "pt" : "dt");
+  mangleExpression(Base);
+  mangleUnresolvedName(Qualifier, Member, Arity);
+}
+
+void CXXNameMangler::mangleExpression(const Expr *E) {
+  // <expression> ::= <unary operator-name> <expression>
+  //              ::= <binary operator-name> <expression> <expression>
+  //              ::= <trinary operator-name> <expression> <expression> <expression>
+  //              ::= cl <expression>* E	     # call
+  //              ::= cv <type> expression           # conversion with one argument
+  //              ::= cv <type> _ <expression>* E # conversion with a different number of arguments
+  //              ::= st <type>		             # sizeof (a type)
+  //              ::= at <type>                      # alignof (a type)
+  //              ::= <template-param>
+  //              ::= <function-param>
+  //              ::= sr <type> <unqualified-name>                   # dependent name
+  //              ::= sr <type> <unqualified-name> <template-args>   # dependent template-id
+  //              ::= sZ <template-param>                            # size of a parameter pack
+  //              ::= <expr-primary>
+  // <expr-primary> ::= L <type> <value number> E    # integer literal
+  //                ::= L <type <value float> E      # floating literal
+  //                ::= L <mangled-name> E           # external name
+  switch (E->getStmtClass()) {
+  case Expr::NoStmtClass:
+#define EXPR(Type, Base)
+#define STMT(Type, Base) \
+  case Expr::Type##Class:
+#include "clang/AST/StmtNodes.def"
+    llvm_unreachable("unexpected statement kind");
+    break;
+
+  default: {
+    // As bad as this diagnostic is, it's better than crashing.
+    Diagnostic &Diags = Context.getDiags();
+    unsigned DiagID = Diags.getCustomDiagID(Diagnostic::Error,
+                                     "cannot yet mangle expression type %0");
+    Diags.Report(FullSourceLoc(E->getExprLoc(),
+                               getASTContext().getSourceManager()),
+                 DiagID)
+      << E->getStmtClassName() << E->getSourceRange();
+    break;
+  }
+
+  case Expr::CallExprClass: {
+    const CallExpr *CE = cast<CallExpr>(E);
+    Out << "cl";
+    mangleCalledExpression(CE->getCallee(), CE->getNumArgs());
+    for (unsigned I = 0, N = CE->getNumArgs(); I != N; ++I)
+      mangleExpression(CE->getArg(I));
+    Out << 'E';
+    break;
+  }
+
+  case Expr::MemberExprClass: {
+    const MemberExpr *ME = cast<MemberExpr>(E);
+    mangleMemberExpr(ME->getBase(), ME->isArrow(),
+                     ME->getQualifier(), ME->getMemberDecl()->getDeclName(),
+                     UnknownArity);
+    break;
+  }
+
+  case Expr::UnresolvedMemberExprClass: {
+    const UnresolvedMemberExpr *ME = cast<UnresolvedMemberExpr>(E);
+    mangleMemberExpr(ME->getBase(), ME->isArrow(),
+                     ME->getQualifier(), ME->getMemberName(),
+                     UnknownArity);
+    break;
+  }
+
+  case Expr::CXXDependentScopeMemberExprClass: {
+    const CXXDependentScopeMemberExpr *ME
+      = cast<CXXDependentScopeMemberExpr>(E);
+    mangleMemberExpr(ME->getBase(), ME->isArrow(),
+                     ME->getQualifier(), ME->getMember(),
+                     UnknownArity);
+    break;
+  }
+
+  case Expr::UnresolvedLookupExprClass: {
+    // The ABI doesn't cover how to mangle overload sets, so we mangle
+    // using something as close as possible to the original lookup
+    // expression.
+    const UnresolvedLookupExpr *ULE = cast<UnresolvedLookupExpr>(E);
+    mangleUnresolvedName(ULE->getQualifier(), ULE->getName(), UnknownArity);
+    break;
+  }
+
+  case Expr::CXXUnresolvedConstructExprClass: {
+    const CXXUnresolvedConstructExpr *CE = cast<CXXUnresolvedConstructExpr>(E);
+    unsigned N = CE->arg_size();
+
+    Out << "cv";
+    mangleType(CE->getType());
+    if (N != 1) Out << '_';
+    for (unsigned I = 0; I != N; ++I) mangleExpression(CE->getArg(I));
+    if (N != 1) Out << 'E';
+    break;
+  }
+
+  case Expr::CXXTemporaryObjectExprClass:
+  case Expr::CXXConstructExprClass: {
+    const CXXConstructExpr *CE = cast<CXXConstructExpr>(E);
+    unsigned N = CE->getNumArgs();
+
+    Out << "cv";
+    mangleType(CE->getType());
+    if (N != 1) Out << '_';
+    for (unsigned I = 0; I != N; ++I) mangleExpression(CE->getArg(I));
+    if (N != 1) Out << 'E';
+    break;
+  }
+
+  case Expr::SizeOfAlignOfExprClass: {
+    const SizeOfAlignOfExpr *SAE = cast<SizeOfAlignOfExpr>(E);
+    if (SAE->isSizeOf()) Out << 's';
+    else Out << 'a';
+    if (SAE->isArgumentType()) {
+      Out << 't';
+      mangleType(SAE->getArgumentType());
+    } else {
+      Out << 'z';
+      mangleExpression(SAE->getArgumentExpr());
+    }
+    break;
+  }
+
+  case Expr::UnaryOperatorClass: {
+    const UnaryOperator *UO = cast<UnaryOperator>(E);
+    mangleOperatorName(UnaryOperator::getOverloadedOperator(UO->getOpcode()),
+                       /*Arity=*/1);
+    mangleExpression(UO->getSubExpr());
+    break;
+  }
+
+  case Expr::BinaryOperatorClass: {
+    const BinaryOperator *BO = cast<BinaryOperator>(E);
+    mangleOperatorName(BinaryOperator::getOverloadedOperator(BO->getOpcode()),
+                       /*Arity=*/2);
+    mangleExpression(BO->getLHS());
+    mangleExpression(BO->getRHS());
+    break;
+  }
+
+  case Expr::ConditionalOperatorClass: {
+    const ConditionalOperator *CO = cast<ConditionalOperator>(E);
+    mangleOperatorName(OO_Conditional, /*Arity=*/3);
+    mangleExpression(CO->getCond());
+    mangleExpression(CO->getLHS());
+    mangleExpression(CO->getRHS());
+    break;
+  }
+
+  case Expr::ImplicitCastExprClass: {
+    mangleExpression(cast<ImplicitCastExpr>(E)->getSubExpr());
+    break;
+  }
+
+  case Expr::CStyleCastExprClass:
+  case Expr::CXXStaticCastExprClass:
+  case Expr::CXXDynamicCastExprClass:
+  case Expr::CXXReinterpretCastExprClass:
+  case Expr::CXXConstCastExprClass:
+  case Expr::CXXFunctionalCastExprClass: {
+    const ExplicitCastExpr *ECE = cast<ExplicitCastExpr>(E);
+    Out << "cv";
+    mangleType(ECE->getType());
+    mangleExpression(ECE->getSubExpr());
+    break;
+  }
+
+  case Expr::CXXOperatorCallExprClass: {
+    const CXXOperatorCallExpr *CE = cast<CXXOperatorCallExpr>(E);
+    unsigned NumArgs = CE->getNumArgs();
+    mangleOperatorName(CE->getOperator(), /*Arity=*/NumArgs);
+    // Mangle the arguments.
+    for (unsigned i = 0; i != NumArgs; ++i)
+      mangleExpression(CE->getArg(i));
+    break;
+  }
+
+  case Expr::ParenExprClass:
+    mangleExpression(cast<ParenExpr>(E)->getSubExpr());
+    break;
+
+  case Expr::DeclRefExprClass: {
+    const NamedDecl *D = cast<DeclRefExpr>(E)->getDecl();
+
+    switch (D->getKind()) {
+    default:
+      //  <expr-primary> ::= L <mangled-name> E # external name
+      Out << 'L';
+      mangle(D, "_Z");
+      Out << 'E';
+      break;
+
+    case Decl::NonTypeTemplateParm: {
+      const NonTypeTemplateParmDecl *PD = cast<NonTypeTemplateParmDecl>(D);
+      mangleTemplateParameter(PD->getIndex());
+      break;
+    }
+
+    }
+
+    break;
+  }
+
+  case Expr::DependentScopeDeclRefExprClass: {
+    const DependentScopeDeclRefExpr *DRE = cast<DependentScopeDeclRefExpr>(E);
+    NestedNameSpecifier *NNS = DRE->getQualifier();
+    const Type *QTy = NNS->getAsType();
+
+    // When we're dealing with a nested-name-specifier that has just a
+    // dependent identifier in it, mangle that as a typename.  FIXME:
+    // It isn't clear that we ever actually want to have such a
+    // nested-name-specifier; why not just represent it as a typename type?
+    if (!QTy && NNS->getAsIdentifier() && NNS->getPrefix()) {
+      QTy = getASTContext().getDependentNameType(ETK_Typename,
+                                                 NNS->getPrefix(),
+                                                 NNS->getAsIdentifier())
+              .getTypePtr();
+    }
+    assert(QTy && "Qualifier was not type!");
+
+    // ::= sr <type> <unqualified-name>                   # dependent name
+    Out << "sr";
+    mangleType(QualType(QTy, 0));
+
+    assert(DRE->getDeclName().getNameKind() == DeclarationName::Identifier &&
+           "Unhandled decl name kind!");
+    mangleSourceName(DRE->getDeclName().getAsIdentifierInfo());
+
+    break;
+  }
+
+  case Expr::CXXBindReferenceExprClass:
+    mangleExpression(cast<CXXBindReferenceExpr>(E)->getSubExpr());
+    break;
+
+  case Expr::CXXBindTemporaryExprClass:
+    mangleExpression(cast<CXXBindTemporaryExpr>(E)->getSubExpr());
+    break;
+
+  case Expr::CXXExprWithTemporariesClass:
+    mangleExpression(cast<CXXExprWithTemporaries>(E)->getSubExpr());
+    break;
+
+  case Expr::FloatingLiteralClass: {
+    const FloatingLiteral *FL = cast<FloatingLiteral>(E);
+    Out << 'L';
+    mangleType(FL->getType());
+
+    // TODO: avoid this copy with careful stream management.
+    llvm::SmallString<20> Buffer;
+    FL->getValue().bitcastToAPInt().toString(Buffer, 16, false);
+    Out.write(Buffer.data(), Buffer.size());
+
+    Out << 'E';
+    break;
+  }
+
+  case Expr::CharacterLiteralClass:
+    Out << 'L';
+    mangleType(E->getType());
+    Out << cast<CharacterLiteral>(E)->getValue();
+    Out << 'E';
+    break;
+
+  case Expr::CXXBoolLiteralExprClass:
+    Out << "Lb";
+    Out << (cast<CXXBoolLiteralExpr>(E)->getValue() ? '1' : '0');
+    Out << 'E';
+    break;
+
+  case Expr::IntegerLiteralClass:
+    mangleIntegerLiteral(E->getType(),
+                         llvm::APSInt(cast<IntegerLiteral>(E)->getValue()));
+    break;
+
+  }
+}
+
+// FIXME: <type> ::= G <type>   # imaginary (C 2000)
+// FIXME: <type> ::= U <source-name> <type>     # vendor extended type qualifier
+
+void CXXNameMangler::mangleCXXCtorType(CXXCtorType T) {
+  // <ctor-dtor-name> ::= C1  # complete object constructor
+  //                  ::= C2  # base object constructor
+  //                  ::= C3  # complete object allocating constructor
+  //
+  switch (T) {
+  case Ctor_Complete:
+    Out << "C1";
+    break;
+  case Ctor_Base:
+    Out << "C2";
+    break;
+  case Ctor_CompleteAllocating:
+    Out << "C3";
+    break;
+  }
+}
+
+void CXXNameMangler::mangleCXXDtorType(CXXDtorType T) {
+  // <ctor-dtor-name> ::= D0  # deleting destructor
+  //                  ::= D1  # complete object destructor
+  //                  ::= D2  # base object destructor
+  //
+  switch (T) {
+  case Dtor_Deleting:
+    Out << "D0";
+    break;
+  case Dtor_Complete:
+    Out << "D1";
+    break;
+  case Dtor_Base:
+    Out << "D2";
+    break;
+  }
+}
+
+void CXXNameMangler::mangleTemplateArgs(TemplateName Template,
+                                        const TemplateArgument *TemplateArgs,
+                                        unsigned NumTemplateArgs) {
+  if (TemplateDecl *TD = Template.getAsTemplateDecl())
+    return mangleTemplateArgs(*TD->getTemplateParameters(), TemplateArgs,
+                              NumTemplateArgs);
+  
+  // <template-args> ::= I <template-arg>+ E
+  Out << 'I';
+  for (unsigned i = 0; i != NumTemplateArgs; ++i)
+    mangleTemplateArg(0, TemplateArgs[i]);
+  Out << 'E';
+}
+
+void CXXNameMangler::mangleTemplateArgs(const TemplateParameterList &PL,
+                                        const TemplateArgumentList &AL) {
+  // <template-args> ::= I <template-arg>+ E
+  Out << 'I';
+  for (unsigned i = 0, e = AL.size(); i != e; ++i)
+    mangleTemplateArg(PL.getParam(i), AL[i]);
+  Out << 'E';
+}
+
+void CXXNameMangler::mangleTemplateArgs(const TemplateParameterList &PL,
+                                        const TemplateArgument *TemplateArgs,
+                                        unsigned NumTemplateArgs) {
+  // <template-args> ::= I <template-arg>+ E
+  Out << 'I';
+  for (unsigned i = 0; i != NumTemplateArgs; ++i)
+    mangleTemplateArg(PL.getParam(i), TemplateArgs[i]);
+  Out << 'E';
+}
+
+void CXXNameMangler::mangleTemplateArg(const NamedDecl *P,
+                                       const TemplateArgument &A) {
+  // <template-arg> ::= <type>              # type or template
+  //                ::= X <expression> E    # expression
+  //                ::= <expr-primary>      # simple expressions
+  //                ::= I <template-arg>* E # argument pack
+  //                ::= sp <expression>     # pack expansion of (C++0x)
+  switch (A.getKind()) {
+  default:
+    assert(0 && "Unknown template argument kind!");
+  case TemplateArgument::Type:
+    mangleType(A.getAsType());
+    break;
+  case TemplateArgument::Template:
+    assert(A.getAsTemplate().getAsTemplateDecl() &&
+           "Can't get dependent template names here");
+    mangleName(A.getAsTemplate().getAsTemplateDecl());
+    break;
+  case TemplateArgument::Expression:
+    Out << 'X';
+    mangleExpression(A.getAsExpr());
+    Out << 'E';
+    break;
+  case TemplateArgument::Integral:
+    mangleIntegerLiteral(A.getIntegralType(), *A.getAsIntegral());
+    break;
+  case TemplateArgument::Declaration: {
+    assert(P && "Missing template parameter for declaration argument");
+    //  <expr-primary> ::= L <mangled-name> E # external name
+
+    // Clang produces AST's where pointer-to-member-function expressions
+    // and pointer-to-function expressions are represented as a declaration not
+    // an expression. We compensate for it here to produce the correct mangling.
+    NamedDecl *D = cast<NamedDecl>(A.getAsDecl());
+    const NonTypeTemplateParmDecl *Parameter = cast<NonTypeTemplateParmDecl>(P);
+    bool compensateMangling = D->isCXXClassMember() &&
+      !Parameter->getType()->isReferenceType();
+    if (compensateMangling) {
+      Out << 'X';
+      mangleOperatorName(OO_Amp, 1);
+    }
+
+    Out << 'L';
+    // References to external entities use the mangled name; if the name would
+    // not normally be manged then mangle it as unqualified.
+    //
+    // FIXME: The ABI specifies that external names here should have _Z, but
+    // gcc leaves this off.
+    if (compensateMangling)
+      mangle(D, "_Z");
+    else
+      mangle(D, "Z");
+    Out << 'E';
+
+    if (compensateMangling)
+      Out << 'E';
+
+    break;
+  }
+  }
+}
+
+void CXXNameMangler::mangleTemplateParameter(unsigned Index) {
+  // <template-param> ::= T_    # first template parameter
+  //                  ::= T <parameter-2 non-negative number> _
+  if (Index == 0)
+    Out << "T_";
+  else
+    Out << 'T' << (Index - 1) << '_';
+}
+
+// <substitution> ::= S <seq-id> _
+//                ::= S_
+bool CXXNameMangler::mangleSubstitution(const NamedDecl *ND) {
+  // Try one of the standard substitutions first.
+  if (mangleStandardSubstitution(ND))
+    return true;
+
+  ND = cast<NamedDecl>(ND->getCanonicalDecl());
+  return mangleSubstitution(reinterpret_cast<uintptr_t>(ND));
+}
+
+bool CXXNameMangler::mangleSubstitution(QualType T) {
+  if (!T.getCVRQualifiers()) {
+    if (const RecordType *RT = T->getAs<RecordType>())
+      return mangleSubstitution(RT->getDecl());
+  }
+
+  uintptr_t TypePtr = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
+
+  return mangleSubstitution(TypePtr);
+}
+
+bool CXXNameMangler::mangleSubstitution(uintptr_t Ptr) {
+  llvm::DenseMap<uintptr_t, unsigned>::iterator I = Substitutions.find(Ptr);
+  if (I == Substitutions.end())
+    return false;
+
+  unsigned SeqID = I->second;
+  if (SeqID == 0)
+    Out << "S_";
+  else {
+    SeqID--;
+
+    // <seq-id> is encoded in base-36, using digits and upper case letters.
+    char Buffer[10];
+    char *BufferPtr = llvm::array_endof(Buffer);
+
+    if (SeqID == 0) *--BufferPtr = '0';
+
+    while (SeqID) {
+      assert(BufferPtr > Buffer && "Buffer overflow!");
+
+      unsigned char c = static_cast<unsigned char>(SeqID) % 36;
+
+      *--BufferPtr =  (c < 10 ? '0' + c : 'A' + c - 10);
+      SeqID /= 36;
+    }
+
+    Out << 'S'
+        << llvm::StringRef(BufferPtr, llvm::array_endof(Buffer)-BufferPtr)
+        << '_';
+  }
+
+  return true;
+}
+
+static bool isCharType(QualType T) {
+  if (T.isNull())
+    return false;
+
+  return T->isSpecificBuiltinType(BuiltinType::Char_S) ||
+    T->isSpecificBuiltinType(BuiltinType::Char_U);
+}
+
+/// isCharSpecialization - Returns whether a given type is a template
+/// specialization of a given name with a single argument of type char.
+static bool isCharSpecialization(QualType T, const char *Name) {
+  if (T.isNull())
+    return false;
+
+  const RecordType *RT = T->getAs<RecordType>();
+  if (!RT)
+    return false;
+
+  const ClassTemplateSpecializationDecl *SD =
+    dyn_cast<ClassTemplateSpecializationDecl>(RT->getDecl());
+  if (!SD)
+    return false;
+
+  if (!isStdNamespace(SD->getDeclContext()))
+    return false;
+
+  const TemplateArgumentList &TemplateArgs = SD->getTemplateArgs();
+  if (TemplateArgs.size() != 1)
+    return false;
+
+  if (!isCharType(TemplateArgs[0].getAsType()))
+    return false;
+
+  return SD->getIdentifier()->getName() == Name;
+}
+
+template <std::size_t StrLen>
+bool isStreamCharSpecialization(const ClassTemplateSpecializationDecl *SD,
+                                const char (&Str)[StrLen]) {
+  if (!SD->getIdentifier()->isStr(Str))
+    return false;
+
+  const TemplateArgumentList &TemplateArgs = SD->getTemplateArgs();
+  if (TemplateArgs.size() != 2)
+    return false;
+
+  if (!isCharType(TemplateArgs[0].getAsType()))
+    return false;
+
+  if (!isCharSpecialization(TemplateArgs[1].getAsType(), "char_traits"))
+    return false;
+
+  return true;
+}
+
+bool CXXNameMangler::mangleStandardSubstitution(const NamedDecl *ND) {
+  // <substitution> ::= St # ::std::
+  if (const NamespaceDecl *NS = dyn_cast<NamespaceDecl>(ND)) {
+    if (isStd(NS)) {
+      Out << "St";
+      return true;
+    }
+  }
+
+  if (const ClassTemplateDecl *TD = dyn_cast<ClassTemplateDecl>(ND)) {
+    if (!isStdNamespace(TD->getDeclContext()))
+      return false;
+
+    // <substitution> ::= Sa # ::std::allocator
+    if (TD->getIdentifier()->isStr("allocator")) {
+      Out << "Sa";
+      return true;
+    }
+
+    // <<substitution> ::= Sb # ::std::basic_string
+    if (TD->getIdentifier()->isStr("basic_string")) {
+      Out << "Sb";
+      return true;
+    }
+  }
+
+  if (const ClassTemplateSpecializationDecl *SD =
+        dyn_cast<ClassTemplateSpecializationDecl>(ND)) {
+    if (!isStdNamespace(SD->getDeclContext()))
+      return false;
+
+    //    <substitution> ::= Ss # ::std::basic_string<char,
+    //                            ::std::char_traits<char>,
+    //                            ::std::allocator<char> >
+    if (SD->getIdentifier()->isStr("basic_string")) {
+      const TemplateArgumentList &TemplateArgs = SD->getTemplateArgs();
+
+      if (TemplateArgs.size() != 3)
+        return false;
+
+      if (!isCharType(TemplateArgs[0].getAsType()))
+        return false;
+
+      if (!isCharSpecialization(TemplateArgs[1].getAsType(), "char_traits"))
+        return false;
+
+      if (!isCharSpecialization(TemplateArgs[2].getAsType(), "allocator"))
+        return false;
+
+      Out << "Ss";
+      return true;
+    }
+
+    //    <substitution> ::= Si # ::std::basic_istream<char,
+    //                            ::std::char_traits<char> >
+    if (isStreamCharSpecialization(SD, "basic_istream")) {
+      Out << "Si";
+      return true;
+    }
+
+    //    <substitution> ::= So # ::std::basic_ostream<char,
+    //                            ::std::char_traits<char> >
+    if (isStreamCharSpecialization(SD, "basic_ostream")) {
+      Out << "So";
+      return true;
+    }
+
+    //    <substitution> ::= Sd # ::std::basic_iostream<char,
+    //                            ::std::char_traits<char> >
+    if (isStreamCharSpecialization(SD, "basic_iostream")) {
+      Out << "Sd";
+      return true;
+    }
+  }
+  return false;
+}
+
+void CXXNameMangler::addSubstitution(QualType T) {
+  if (!T.getCVRQualifiers()) {
+    if (const RecordType *RT = T->getAs<RecordType>()) {
+      addSubstitution(RT->getDecl());
+      return;
+    }
+  }
+
+  uintptr_t TypePtr = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
+  addSubstitution(TypePtr);
+}
+
+void CXXNameMangler::addSubstitution(uintptr_t Ptr) {
+  unsigned SeqID = Substitutions.size();
+
+  assert(!Substitutions.count(Ptr) && "Substitution already exists!");
+  Substitutions[Ptr] = SeqID;
+}
+
+//
+
+/// \brief Mangles the name of the declaration D and emits that name to the
+/// given output stream.
+///
+/// If the declaration D requires a mangled name, this routine will emit that
+/// mangled name to \p os and return true. Otherwise, \p os will be unchanged
+/// and this routine will return false. In this case, the caller should just
+/// emit the identifier of the declaration (\c D->getIdentifier()) as its
+/// name.
+void MangleContext::mangleName(const NamedDecl *D,
+                               llvm::SmallVectorImpl<char> &Res) {
+  assert((isa<FunctionDecl>(D) || isa<VarDecl>(D)) &&
+          "Invalid mangleName() call, argument is not a variable or function!");
+  assert(!isa<CXXConstructorDecl>(D) && !isa<CXXDestructorDecl>(D) &&
+         "Invalid mangleName() call on 'structor decl!");
+
+  PrettyStackTraceDecl CrashInfo(D, SourceLocation(),
+                                 getASTContext().getSourceManager(),
+                                 "Mangling declaration");
+
+  CXXNameMangler Mangler(*this, Res);
+  return Mangler.mangle(D);
+}
+
+void MangleContext::mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type,
+                                  llvm::SmallVectorImpl<char> &Res) {
+  CXXNameMangler Mangler(*this, Res, D, Type);
+  Mangler.mangle(D);
+}
+
+void MangleContext::mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type,
+                                  llvm::SmallVectorImpl<char> &Res) {
+  CXXNameMangler Mangler(*this, Res, D, Type);
+  Mangler.mangle(D);
+}
+
+void MangleContext::mangleThunk(const CXXMethodDecl *MD,
+                                const ThunkInfo &Thunk,
+                                llvm::SmallVectorImpl<char> &Res) {
+  //  <special-name> ::= T <call-offset> <base encoding>
+  //                      # base is the nominal target function of thunk
+  //  <special-name> ::= Tc <call-offset> <call-offset> <base encoding>
+  //                      # base is the nominal target function of thunk
+  //                      # first call-offset is 'this' adjustment
+  //                      # second call-offset is result adjustment
+  
+  assert(!isa<CXXDestructorDecl>(MD) &&
+         "Use mangleCXXDtor for destructor decls!");
+  
+  CXXNameMangler Mangler(*this, Res);
+  Mangler.getStream() << "_ZT";
+  if (!Thunk.Return.isEmpty())
+    Mangler.getStream() << 'c';
+  
+  // Mangle the 'this' pointer adjustment.
+  Mangler.mangleCallOffset(Thunk.This.NonVirtual, Thunk.This.VCallOffsetOffset);
+  
+  // Mangle the return pointer adjustment if there is one.
+  if (!Thunk.Return.isEmpty())
+    Mangler.mangleCallOffset(Thunk.Return.NonVirtual,
+                             Thunk.Return.VBaseOffsetOffset);
+  
+  Mangler.mangleFunctionEncoding(MD);
+}
+
+void 
+MangleContext::mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type,
+                                  const ThisAdjustment &ThisAdjustment,
+                                  llvm::SmallVectorImpl<char> &Res) {
+  //  <special-name> ::= T <call-offset> <base encoding>
+  //                      # base is the nominal target function of thunk
+  
+  CXXNameMangler Mangler(*this, Res, DD, Type);
+  Mangler.getStream() << "_ZT";
+
+  // Mangle the 'this' pointer adjustment.
+  Mangler.mangleCallOffset(ThisAdjustment.NonVirtual, 
+                           ThisAdjustment.VCallOffsetOffset);
+
+  Mangler.mangleFunctionEncoding(DD);
+}
+
+/// mangleGuardVariable - Returns the mangled name for a guard variable
+/// for the passed in VarDecl.
+void MangleContext::mangleGuardVariable(const VarDecl *D,
+                                        llvm::SmallVectorImpl<char> &Res) {
+  //  <special-name> ::= GV <object name>       # Guard variable for one-time
+  //                                            # initialization
+  CXXNameMangler Mangler(*this, Res);
+  Mangler.getStream() << "_ZGV";
+  Mangler.mangleName(D);
+}
+
+void MangleContext::mangleCXXVTable(const CXXRecordDecl *RD,
+                                    llvm::SmallVectorImpl<char> &Res) {
+  // <special-name> ::= TV <type>  # virtual table
+  CXXNameMangler Mangler(*this, Res);
+  Mangler.getStream() << "_ZTV";
+  Mangler.mangleName(RD);
+}
+
+void MangleContext::mangleCXXVTT(const CXXRecordDecl *RD,
+                                 llvm::SmallVectorImpl<char> &Res) {
+  // <special-name> ::= TT <type>  # VTT structure
+  CXXNameMangler Mangler(*this, Res);
+  Mangler.getStream() << "_ZTT";
+  Mangler.mangleName(RD);
+}
+
+void MangleContext::mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset,
+                                        const CXXRecordDecl *Type,
+                                        llvm::SmallVectorImpl<char> &Res) {
+  // <special-name> ::= TC <type> <offset number> _ <base type>
+  CXXNameMangler Mangler(*this, Res);
+  Mangler.getStream() << "_ZTC";
+  Mangler.mangleName(RD);
+  Mangler.getStream() << Offset;
+  Mangler.getStream() << '_';
+  Mangler.mangleName(Type);
+}
+
+void MangleContext::mangleCXXRTTI(QualType Ty,
+                                  llvm::SmallVectorImpl<char> &Res) {
+  // <special-name> ::= TI <type>  # typeinfo structure
+  assert(!Ty.hasQualifiers() && "RTTI info cannot have top-level qualifiers");
+  CXXNameMangler Mangler(*this, Res);
+  Mangler.getStream() << "_ZTI";
+  Mangler.mangleType(Ty);
+}
+
+void MangleContext::mangleCXXRTTIName(QualType Ty,
+                                      llvm::SmallVectorImpl<char> &Res) {
+  // <special-name> ::= TS <type>  # typeinfo name (null terminated byte string)
+  CXXNameMangler Mangler(*this, Res);
+  Mangler.getStream() << "_ZTS";
+  Mangler.mangleType(Ty);
+}
diff --git a/lib/CodeGen/Mangle.h b/lib/CodeGen/Mangle.h
new file mode 100644
index 0000000..da3626f
--- /dev/null
+++ b/lib/CodeGen/Mangle.h
@@ -0,0 +1,137 @@
+//===--- Mangle.h - Mangle C++ Names ----------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Implements C++ name mangling according to the Itanium C++ ABI,
+// which is used in GCC 3.2 and newer (and many compilers that are
+// ABI-compatible with GCC):
+//
+//   http://www.codesourcery.com/public/cxx-abi/abi.html
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_CODEGEN_MANGLE_H
+#define LLVM_CLANG_CODEGEN_MANGLE_H
+
+#include "CGCXX.h"
+#include "clang/AST/Type.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/SmallString.h"
+
+namespace clang {
+  class ASTContext;
+  class CXXConstructorDecl;
+  class CXXDestructorDecl;
+  class CXXMethodDecl;
+  class FunctionDecl;
+  class NamedDecl;
+  class VarDecl;
+
+namespace CodeGen {
+  struct ThisAdjustment;
+  struct ThunkInfo;
+
+/// MangleBuffer - a convenient class for storing a name which is
+/// either the result of a mangling or is a constant string with
+/// external memory ownership.
+class MangleBuffer {
+public:
+  void setString(llvm::StringRef Ref) {
+    String = Ref;
+  }
+
+  llvm::SmallVectorImpl<char> &getBuffer() {
+    return Buffer;
+  }
+
+  llvm::StringRef getString() const {
+    if (!String.empty()) return String;
+    return Buffer.str();
+  }
+
+  operator llvm::StringRef() const {
+    return getString();
+  }
+
+private:
+  llvm::StringRef String;
+  llvm::SmallString<256> Buffer;
+};
+   
+/// MangleContext - Context for tracking state which persists across multiple
+/// calls to the C++ name mangler.
+class MangleContext {
+  ASTContext &Context;
+  Diagnostic &Diags;
+
+  llvm::DenseMap<const TagDecl *, uint64_t> AnonStructIds;
+  unsigned Discriminator;
+  llvm::DenseMap<const NamedDecl*, unsigned> Uniquifier;
+  
+public:
+  explicit MangleContext(ASTContext &Context,
+                         Diagnostic &Diags)
+    : Context(Context), Diags(Diags) { }
+
+  ASTContext &getASTContext() const { return Context; }
+
+  Diagnostic &getDiags() const { return Diags; }
+
+  uint64_t getAnonymousStructId(const TagDecl *TD) {
+    std::pair<llvm::DenseMap<const TagDecl *,
+      uint64_t>::iterator, bool> Result =
+      AnonStructIds.insert(std::make_pair(TD, AnonStructIds.size()));
+    return Result.first->second;
+  }
+
+  /// @name Mangler Entry Points
+  /// @{
+
+  bool shouldMangleDeclName(const NamedDecl *D);
+
+  void mangleName(const NamedDecl *D, llvm::SmallVectorImpl<char> &);
+  void mangleThunk(const CXXMethodDecl *MD,
+                   const ThunkInfo &Thunk,
+                   llvm::SmallVectorImpl<char> &);
+  void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type,
+                          const ThisAdjustment &ThisAdjustment,
+                          llvm::SmallVectorImpl<char> &);
+  void mangleGuardVariable(const VarDecl *D, llvm::SmallVectorImpl<char> &);
+  void mangleCXXVTable(const CXXRecordDecl *RD, llvm::SmallVectorImpl<char> &);
+  void mangleCXXVTT(const CXXRecordDecl *RD, llvm::SmallVectorImpl<char> &);
+  void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset,
+                           const CXXRecordDecl *Type,
+                           llvm::SmallVectorImpl<char> &);
+  void mangleCXXRTTI(QualType T, llvm::SmallVectorImpl<char> &);
+  void mangleCXXRTTIName(QualType T, llvm::SmallVectorImpl<char> &);
+  void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type,
+                     llvm::SmallVectorImpl<char> &);
+  void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type,
+                     llvm::SmallVectorImpl<char> &);
+  
+  void mangleInitDiscriminator() {
+    Discriminator = 0;
+  }
+
+  bool getNextDiscriminator(const NamedDecl *ND, unsigned &disc) {
+    unsigned &discriminator = Uniquifier[ND];
+    if (!discriminator)
+      discriminator = ++Discriminator;
+    if (discriminator == 1)
+      return false;
+    disc = discriminator-2;
+    return true;
+  }
+  /// @}
+};
+  
+}
+}
+
+#endif
diff --git a/lib/CodeGen/ModuleBuilder.cpp b/lib/CodeGen/ModuleBuilder.cpp
new file mode 100644
index 0000000..1e1edc1
--- /dev/null
+++ b/lib/CodeGen/ModuleBuilder.cpp
@@ -0,0 +1,100 @@
+//===--- ModuleBuilder.cpp - Emit LLVM Code from ASTs ---------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This builds an AST and converts it to LLVM Code.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/CodeGen/ModuleBuilder.h"
+#include "CodeGenModule.h"
+#include "clang/CodeGen/CodeGenOptions.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/Expr.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/TargetInfo.h"
+#include "llvm/LLVMContext.h"
+#include "llvm/Module.h"
+#include "llvm/Target/TargetData.h"
+#include "llvm/ADT/OwningPtr.h"
+using namespace clang;
+
+namespace {
+  class CodeGeneratorImpl : public CodeGenerator {
+    Diagnostic &Diags;
+    llvm::OwningPtr<const llvm::TargetData> TD;
+    ASTContext *Ctx;
+    const CodeGenOptions CodeGenOpts;  // Intentionally copied in.
+  protected:
+    llvm::OwningPtr<llvm::Module> M;
+    llvm::OwningPtr<CodeGen::CodeGenModule> Builder;
+  public:
+    CodeGeneratorImpl(Diagnostic &diags, const std::string& ModuleName,
+                      const CodeGenOptions &CGO, llvm::LLVMContext& C)
+      : Diags(diags), CodeGenOpts(CGO), M(new llvm::Module(ModuleName, C)) {}
+
+    virtual ~CodeGeneratorImpl() {}
+
+    virtual llvm::Module* GetModule() {
+      return M.get();
+    }
+
+    virtual llvm::Module* ReleaseModule() {
+      return M.take();
+    }
+
+    virtual void Initialize(ASTContext &Context) {
+      Ctx = &Context;
+
+      M->setTargetTriple(Ctx->Target.getTriple().getTriple());
+      M->setDataLayout(Ctx->Target.getTargetDescription());
+      TD.reset(new llvm::TargetData(Ctx->Target.getTargetDescription()));
+      Builder.reset(new CodeGen::CodeGenModule(Context, CodeGenOpts,
+                                               *M, *TD, Diags));
+    }
+
+    virtual void HandleTopLevelDecl(DeclGroupRef DG) {
+      // Make sure to emit all elements of a Decl.
+      for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I)
+        Builder->EmitTopLevelDecl(*I);
+    }
+
+    /// HandleTagDeclDefinition - This callback is invoked each time a TagDecl
+    /// to (e.g. struct, union, enum, class) is completed. This allows the
+    /// client hack on the type, which can occur at any point in the file
+    /// (because these can be defined in declspecs).
+    virtual void HandleTagDeclDefinition(TagDecl *D) {
+      Builder->UpdateCompletedType(D);
+    }
+
+    virtual void HandleTranslationUnit(ASTContext &Ctx) {
+      if (Diags.hasErrorOccurred()) {
+        M.reset();
+        return;
+      }
+
+      if (Builder)
+        Builder->Release();
+    }
+
+    virtual void CompleteTentativeDefinition(VarDecl *D) {
+      if (Diags.hasErrorOccurred())
+        return;
+
+      Builder->EmitTentativeDefinition(D);
+    }
+  };
+}
+
+CodeGenerator *clang::CreateLLVMCodeGen(Diagnostic &Diags,
+                                        const std::string& ModuleName,
+                                        const CodeGenOptions &CGO,
+                                        llvm::LLVMContext& C) {
+  return new CodeGeneratorImpl(Diags, ModuleName, CGO, C);
+}
diff --git a/lib/CodeGen/README.txt b/lib/CodeGen/README.txt
new file mode 100644
index 0000000..e6d6109
--- /dev/null
+++ b/lib/CodeGen/README.txt
@@ -0,0 +1,47 @@
+IRgen optimization opportunities.
+
+//===---------------------------------------------------------------------===//
+
+The common pattern of
+--
+short x; // or char, etc
+(x == 10)
+--
+generates an zext/sext of x which can easily be avoided.
+
+//===---------------------------------------------------------------------===//
+
+Bitfields accesses can be shifted to simplify masking and sign
+extension. For example, if the bitfield width is 8 and it is
+appropriately aligned then is is a lot shorter to just load the char
+directly.
+
+//===---------------------------------------------------------------------===//
+
+It may be worth avoiding creation of alloca's for formal arguments
+for the common situation where the argument is never written to or has
+its address taken. The idea would be to begin generating code by using
+the argument directly and if its address is taken or it is stored to
+then generate the alloca and patch up the existing code.
+
+In theory, the same optimization could be a win for block local
+variables as long as the declaration dominates all statements in the
+block.
+
+NOTE: The main case we care about this for is for -O0 -g compile time
+performance, and in that scenario we will need to emit the alloca
+anyway currently to emit proper debug info. So this is blocked by
+being able to emit debug information which refers to an LLVM
+temporary, not an alloca.
+
+//===---------------------------------------------------------------------===//
+
+We should try and avoid generating basic blocks which only contain
+jumps. At -O0, this penalizes us all the way from IRgen (malloc &
+instruction overhead), all the way down through code generation and
+assembly time.
+
+On 176.gcc:expr.ll, it looks like over 12% of basic blocks are just
+direct branches!
+
+//===---------------------------------------------------------------------===//
diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp
new file mode 100644
index 0000000..e1fdf86
--- /dev/null
+++ b/lib/CodeGen/TargetInfo.cpp
@@ -0,0 +1,2183 @@
+//===---- TargetInfo.cpp - Encapsulate target details -----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// These classes wrap the information about a call or function
+// definition used to handle ABI compliancy.
+//
+//===----------------------------------------------------------------------===//
+
+#include "TargetInfo.h"
+#include "ABIInfo.h"
+#include "CodeGenFunction.h"
+#include "clang/AST/RecordLayout.h"
+#include "llvm/Type.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace clang;
+using namespace CodeGen;
+
+ABIInfo::~ABIInfo() {}
+
+void ABIArgInfo::dump() const {
+  llvm::raw_ostream &OS = llvm::errs();
+  OS << "(ABIArgInfo Kind=";
+  switch (TheKind) {
+  case Direct:
+    OS << "Direct";
+    break;
+  case Extend:
+    OS << "Extend";
+    break;
+  case Ignore:
+    OS << "Ignore";
+    break;
+  case Coerce:
+    OS << "Coerce Type=";
+    getCoerceToType()->print(OS);
+    break;
+  case Indirect:
+    OS << "Indirect Align=" << getIndirectAlign()
+       << " Byal=" << getIndirectByVal();
+    break;
+  case Expand:
+    OS << "Expand";
+    break;
+  }
+  OS << ")\n";
+}
+
+TargetCodeGenInfo::~TargetCodeGenInfo() { delete Info; }
+
+static bool isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays);
+
+/// isEmptyField - Return true iff a the field is "empty", that is it
+/// is an unnamed bit-field or an (array of) empty record(s).
+static bool isEmptyField(ASTContext &Context, const FieldDecl *FD,
+                         bool AllowArrays) {
+  if (FD->isUnnamedBitfield())
+    return true;
+
+  QualType FT = FD->getType();
+
+    // Constant arrays of empty records count as empty, strip them off.
+  if (AllowArrays)
+    while (const ConstantArrayType *AT = Context.getAsConstantArrayType(FT))
+      FT = AT->getElementType();
+
+  return isEmptyRecord(Context, FT, AllowArrays);
+}
+
+/// isEmptyRecord - Return true iff a structure contains only empty
+/// fields. Note that a structure with a flexible array member is not
+/// considered empty.
+static bool isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays) {
+  const RecordType *RT = T->getAs<RecordType>();
+  if (!RT)
+    return 0;
+  const RecordDecl *RD = RT->getDecl();
+  if (RD->hasFlexibleArrayMember())
+    return false;
+  for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
+         i != e; ++i)
+    if (!isEmptyField(Context, *i, AllowArrays))
+      return false;
+  return true;
+}
+
+/// hasNonTrivialDestructorOrCopyConstructor - Determine if a type has either
+/// a non-trivial destructor or a non-trivial copy constructor.
+static bool hasNonTrivialDestructorOrCopyConstructor(const RecordType *RT) {
+  const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());
+  if (!RD)
+    return false;
+  
+  return !RD->hasTrivialDestructor() || !RD->hasTrivialCopyConstructor();
+}
+
+/// isRecordWithNonTrivialDestructorOrCopyConstructor - Determine if a type is
+/// a record type with either a non-trivial destructor or a non-trivial copy
+/// constructor.
+static bool isRecordWithNonTrivialDestructorOrCopyConstructor(QualType T) {
+  const RecordType *RT = T->getAs<RecordType>();
+  if (!RT)
+    return false;
+
+  return hasNonTrivialDestructorOrCopyConstructor(RT);
+}
+
+/// isSingleElementStruct - Determine if a structure is a "single
+/// element struct", i.e. it has exactly one non-empty field or
+/// exactly one field which is itself a single element
+/// struct. Structures with flexible array members are never
+/// considered single element structs.
+///
+/// \return The field declaration for the single non-empty field, if
+/// it exists.
+static const Type *isSingleElementStruct(QualType T, ASTContext &Context) {
+  const RecordType *RT = T->getAsStructureType();
+  if (!RT)
+    return 0;
+
+  const RecordDecl *RD = RT->getDecl();
+  if (RD->hasFlexibleArrayMember())
+    return 0;
+
+  const Type *Found = 0;
+  for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
+         i != e; ++i) {
+    const FieldDecl *FD = *i;
+    QualType FT = FD->getType();
+
+    // Ignore empty fields.
+    if (isEmptyField(Context, FD, true))
+      continue;
+
+    // If we already found an element then this isn't a single-element
+    // struct.
+    if (Found)
+      return 0;
+
+    // Treat single element arrays as the element.
+    while (const ConstantArrayType *AT = Context.getAsConstantArrayType(FT)) {
+      if (AT->getSize().getZExtValue() != 1)
+        break;
+      FT = AT->getElementType();
+    }
+
+    if (!CodeGenFunction::hasAggregateLLVMType(FT)) {
+      Found = FT.getTypePtr();
+    } else {
+      Found = isSingleElementStruct(FT, Context);
+      if (!Found)
+        return 0;
+    }
+  }
+
+  return Found;
+}
+
+static bool is32Or64BitBasicType(QualType Ty, ASTContext &Context) {
+  if (!Ty->getAs<BuiltinType>() && !Ty->isAnyPointerType() &&
+      !Ty->isAnyComplexType() && !Ty->isEnumeralType() &&
+      !Ty->isBlockPointerType())
+    return false;
+
+  uint64_t Size = Context.getTypeSize(Ty);
+  return Size == 32 || Size == 64;
+}
+
+/// canExpandIndirectArgument - Test whether an argument type which is to be
+/// passed indirectly (on the stack) would have the equivalent layout if it was
+/// expanded into separate arguments. If so, we prefer to do the latter to avoid
+/// inhibiting optimizations.
+///
+// FIXME: This predicate is missing many cases, currently it just follows
+// llvm-gcc (checks that all fields are 32-bit or 64-bit primitive types). We
+// should probably make this smarter, or better yet make the LLVM backend
+// capable of handling it.
+static bool canExpandIndirectArgument(QualType Ty, ASTContext &Context) {
+  // We can only expand structure types.
+  const RecordType *RT = Ty->getAs<RecordType>();
+  if (!RT)
+    return false;
+
+  // We can only expand (C) structures.
+  //
+  // FIXME: This needs to be generalized to handle classes as well.
+  const RecordDecl *RD = RT->getDecl();
+  if (!RD->isStruct() || isa<CXXRecordDecl>(RD))
+    return false;
+
+  for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
+         i != e; ++i) {
+    const FieldDecl *FD = *i;
+
+    if (!is32Or64BitBasicType(FD->getType(), Context))
+      return false;
+
+    // FIXME: Reject bit-fields wholesale; there are two problems, we don't know
+    // how to expand them yet, and the predicate for telling if a bitfield still
+    // counts as "basic" is more complicated than what we were doing previously.
+    if (FD->isBitField())
+      return false;
+  }
+
+  return true;
+}
+
+static bool typeContainsSSEVector(const RecordDecl *RD, ASTContext &Context) {
+  for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
+         i != e; ++i) {
+    const FieldDecl *FD = *i;
+
+    if (FD->getType()->isVectorType() &&
+        Context.getTypeSize(FD->getType()) >= 128)
+      return true;
+
+    if (const RecordType* RT = FD->getType()->getAs<RecordType>())
+      if (typeContainsSSEVector(RT->getDecl(), Context))
+        return true;
+  }
+
+  return false;
+}
+
+namespace {
+/// DefaultABIInfo - The default implementation for ABI specific
+/// details. This implementation provides information which results in
+/// self-consistent and sensible LLVM IR generation, but does not
+/// conform to any particular ABI.
+class DefaultABIInfo : public ABIInfo {
+  ABIArgInfo classifyReturnType(QualType RetTy,
+                                ASTContext &Context,
+                                llvm::LLVMContext &VMContext) const;
+
+  ABIArgInfo classifyArgumentType(QualType RetTy,
+                                  ASTContext &Context,
+                                  llvm::LLVMContext &VMContext) const;
+
+  virtual void computeInfo(CGFunctionInfo &FI, ASTContext &Context,
+                           llvm::LLVMContext &VMContext) const {
+    FI.getReturnInfo() = classifyReturnType(FI.getReturnType(), Context,
+                                            VMContext);
+    for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end();
+         it != ie; ++it)
+      it->info = classifyArgumentType(it->type, Context, VMContext);
+  }
+
+  virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
+                                 CodeGenFunction &CGF) const;
+};
+
+class DefaultTargetCodeGenInfo : public TargetCodeGenInfo {
+public:
+  DefaultTargetCodeGenInfo():TargetCodeGenInfo(new DefaultABIInfo()) {}
+};
+
+llvm::Value *DefaultABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
+                                       CodeGenFunction &CGF) const {
+  return 0;
+}
+
+ABIArgInfo DefaultABIInfo::classifyArgumentType(QualType Ty,
+                                                ASTContext &Context,
+                                          llvm::LLVMContext &VMContext) const {
+  if (CodeGenFunction::hasAggregateLLVMType(Ty))
+    return ABIArgInfo::getIndirect(0);
+
+  // Treat an enum type as its underlying type.
+  if (const EnumType *EnumTy = Ty->getAs<EnumType>())
+    Ty = EnumTy->getDecl()->getIntegerType();
+
+  return (Ty->isPromotableIntegerType() ?
+          ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
+}
+
+/// X86_32ABIInfo - The X86-32 ABI information.
+class X86_32ABIInfo : public ABIInfo {
+  ASTContext &Context;
+  bool IsDarwinVectorABI;
+  bool IsSmallStructInRegABI;
+
+  static bool isRegisterSize(unsigned Size) {
+    return (Size == 8 || Size == 16 || Size == 32 || Size == 64);
+  }
+
+  static bool shouldReturnTypeInRegister(QualType Ty, ASTContext &Context);
+
+  /// getIndirectResult - Give a source type \arg Ty, return a suitable result
+  /// such that the argument will be passed in memory.
+  ABIArgInfo getIndirectResult(QualType Ty, ASTContext &Context,
+                               bool ByVal = true) const;
+
+public:
+  ABIArgInfo classifyReturnType(QualType RetTy,
+                                ASTContext &Context,
+                                llvm::LLVMContext &VMContext) const;
+
+  ABIArgInfo classifyArgumentType(QualType RetTy,
+                                  ASTContext &Context,
+                                  llvm::LLVMContext &VMContext) const;
+
+  virtual void computeInfo(CGFunctionInfo &FI, ASTContext &Context,
+                           llvm::LLVMContext &VMContext) const {
+    FI.getReturnInfo() = classifyReturnType(FI.getReturnType(), Context,
+                                            VMContext);
+    for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end();
+         it != ie; ++it)
+      it->info = classifyArgumentType(it->type, Context, VMContext);
+  }
+
+  virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
+                                 CodeGenFunction &CGF) const;
+
+  X86_32ABIInfo(ASTContext &Context, bool d, bool p)
+    : ABIInfo(), Context(Context), IsDarwinVectorABI(d),
+      IsSmallStructInRegABI(p) {}
+};
+
+class X86_32TargetCodeGenInfo : public TargetCodeGenInfo {
+public:
+  X86_32TargetCodeGenInfo(ASTContext &Context, bool d, bool p)
+    :TargetCodeGenInfo(new X86_32ABIInfo(Context, d, p)) {}
+
+  void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
+                           CodeGen::CodeGenModule &CGM) const;
+
+  int getDwarfEHStackPointer(CodeGen::CodeGenModule &CGM) const {
+    // Darwin uses different dwarf register numbers for EH.
+    if (CGM.isTargetDarwin()) return 5;
+
+    return 4;
+  }
+
+  bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
+                               llvm::Value *Address) const;
+};
+
+}
+
+/// shouldReturnTypeInRegister - Determine if the given type should be
+/// passed in a register (for the Darwin ABI).
+bool X86_32ABIInfo::shouldReturnTypeInRegister(QualType Ty,
+                                               ASTContext &Context) {
+  uint64_t Size = Context.getTypeSize(Ty);
+
+  // Type must be register sized.
+  if (!isRegisterSize(Size))
+    return false;
+
+  if (Ty->isVectorType()) {
+    // 64- and 128- bit vectors inside structures are not returned in
+    // registers.
+    if (Size == 64 || Size == 128)
+      return false;
+
+    return true;
+  }
+
+  // If this is a builtin, pointer, enum, or complex type, it is ok.
+  if (Ty->getAs<BuiltinType>() || Ty->isAnyPointerType() || 
+      Ty->isAnyComplexType() || Ty->isEnumeralType() ||
+      Ty->isBlockPointerType())
+    return true;
+
+  // Arrays are treated like records.
+  if (const ConstantArrayType *AT = Context.getAsConstantArrayType(Ty))
+    return shouldReturnTypeInRegister(AT->getElementType(), Context);
+
+  // Otherwise, it must be a record type.
+  const RecordType *RT = Ty->getAs<RecordType>();
+  if (!RT) return false;
+
+  // FIXME: Traverse bases here too.
+
+  // Structure types are passed in register if all fields would be
+  // passed in a register.
+  for (RecordDecl::field_iterator i = RT->getDecl()->field_begin(),
+         e = RT->getDecl()->field_end(); i != e; ++i) {
+    const FieldDecl *FD = *i;
+
+    // Empty fields are ignored.
+    if (isEmptyField(Context, FD, true))
+      continue;
+
+    // Check fields recursively.
+    if (!shouldReturnTypeInRegister(FD->getType(), Context))
+      return false;
+  }
+
+  return true;
+}
+
+ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy,
+                                            ASTContext &Context,
+                                          llvm::LLVMContext &VMContext) const {
+  if (RetTy->isVoidType()) {
+    return ABIArgInfo::getIgnore();
+  } else if (const VectorType *VT = RetTy->getAs<VectorType>()) {
+    // On Darwin, some vectors are returned in registers.
+    if (IsDarwinVectorABI) {
+      uint64_t Size = Context.getTypeSize(RetTy);
+
+      // 128-bit vectors are a special case; they are returned in
+      // registers and we need to make sure to pick a type the LLVM
+      // backend will like.
+      if (Size == 128)
+        return ABIArgInfo::getCoerce(llvm::VectorType::get(
+                  llvm::Type::getInt64Ty(VMContext), 2));
+
+      // Always return in register if it fits in a general purpose
+      // register, or if it is 64 bits and has a single element.
+      if ((Size == 8 || Size == 16 || Size == 32) ||
+          (Size == 64 && VT->getNumElements() == 1))
+        return ABIArgInfo::getCoerce(llvm::IntegerType::get(VMContext, Size));
+
+      return ABIArgInfo::getIndirect(0);
+    }
+
+    return ABIArgInfo::getDirect();
+  } else if (CodeGenFunction::hasAggregateLLVMType(RetTy)) {
+    if (const RecordType *RT = RetTy->getAs<RecordType>()) {
+      // Structures with either a non-trivial destructor or a non-trivial
+      // copy constructor are always indirect.
+      if (hasNonTrivialDestructorOrCopyConstructor(RT))
+        return ABIArgInfo::getIndirect(0, /*ByVal=*/false);
+      
+      // Structures with flexible arrays are always indirect.
+      if (RT->getDecl()->hasFlexibleArrayMember())
+        return ABIArgInfo::getIndirect(0);
+    }
+    
+    // If specified, structs and unions are always indirect.
+    if (!IsSmallStructInRegABI && !RetTy->isAnyComplexType())
+      return ABIArgInfo::getIndirect(0);
+
+    // Classify "single element" structs as their element type.
+    if (const Type *SeltTy = isSingleElementStruct(RetTy, Context)) {
+      if (const BuiltinType *BT = SeltTy->getAs<BuiltinType>()) {
+        if (BT->isIntegerType()) {
+          // We need to use the size of the structure, padding
+          // bit-fields can adjust that to be larger than the single
+          // element type.
+          uint64_t Size = Context.getTypeSize(RetTy);
+          return ABIArgInfo::getCoerce(
+            llvm::IntegerType::get(VMContext, (unsigned) Size));
+        } else if (BT->getKind() == BuiltinType::Float) {
+          assert(Context.getTypeSize(RetTy) == Context.getTypeSize(SeltTy) &&
+                 "Unexpect single element structure size!");
+          return ABIArgInfo::getCoerce(llvm::Type::getFloatTy(VMContext));
+        } else if (BT->getKind() == BuiltinType::Double) {
+          assert(Context.getTypeSize(RetTy) == Context.getTypeSize(SeltTy) &&
+                 "Unexpect single element structure size!");
+          return ABIArgInfo::getCoerce(llvm::Type::getDoubleTy(VMContext));
+        }
+      } else if (SeltTy->isPointerType()) {
+        // FIXME: It would be really nice if this could come out as the proper
+        // pointer type.
+        const llvm::Type *PtrTy = llvm::Type::getInt8PtrTy(VMContext);
+        return ABIArgInfo::getCoerce(PtrTy);
+      } else if (SeltTy->isVectorType()) {
+        // 64- and 128-bit vectors are never returned in a
+        // register when inside a structure.
+        uint64_t Size = Context.getTypeSize(RetTy);
+        if (Size == 64 || Size == 128)
+          return ABIArgInfo::getIndirect(0);
+
+        return classifyReturnType(QualType(SeltTy, 0), Context, VMContext);
+      }
+    }
+
+    // Small structures which are register sized are generally returned
+    // in a register.
+    if (X86_32ABIInfo::shouldReturnTypeInRegister(RetTy, Context)) {
+      uint64_t Size = Context.getTypeSize(RetTy);
+      return ABIArgInfo::getCoerce(llvm::IntegerType::get(VMContext, Size));
+    }
+
+    return ABIArgInfo::getIndirect(0);
+  } else {
+    // Treat an enum type as its underlying type.
+    if (const EnumType *EnumTy = RetTy->getAs<EnumType>())
+      RetTy = EnumTy->getDecl()->getIntegerType();
+
+    return (RetTy->isPromotableIntegerType() ?
+            ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
+  }
+}
+
+ABIArgInfo X86_32ABIInfo::getIndirectResult(QualType Ty,
+                                            ASTContext &Context,
+                                            bool ByVal) const {
+  if (!ByVal)
+    return ABIArgInfo::getIndirect(0, false);
+
+  // Compute the byval alignment. We trust the back-end to honor the
+  // minimum ABI alignment for byval, to make cleaner IR.
+  const unsigned MinABIAlign = 4;
+  unsigned Align = Context.getTypeAlign(Ty) / 8;
+  if (Align > MinABIAlign)
+    return ABIArgInfo::getIndirect(Align);
+  return ABIArgInfo::getIndirect(0);
+}
+
+ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty,
+                                               ASTContext &Context,
+                                           llvm::LLVMContext &VMContext) const {
+  // FIXME: Set alignment on indirect arguments.
+  if (CodeGenFunction::hasAggregateLLVMType(Ty)) {
+    // Structures with flexible arrays are always indirect.
+    if (const RecordType *RT = Ty->getAs<RecordType>()) {
+      // Structures with either a non-trivial destructor or a non-trivial
+      // copy constructor are always indirect.
+      if (hasNonTrivialDestructorOrCopyConstructor(RT))
+        return getIndirectResult(Ty, Context, /*ByVal=*/false);
+
+      if (RT->getDecl()->hasFlexibleArrayMember())
+        return getIndirectResult(Ty, Context);
+    }
+
+    // Ignore empty structs.
+    if (Ty->isStructureType() && Context.getTypeSize(Ty) == 0)
+      return ABIArgInfo::getIgnore();
+
+    // Expand small (<= 128-bit) record types when we know that the stack layout
+    // of those arguments will match the struct. This is important because the
+    // LLVM backend isn't smart enough to remove byval, which inhibits many
+    // optimizations.
+    if (Context.getTypeSize(Ty) <= 4*32 &&
+        canExpandIndirectArgument(Ty, Context))
+      return ABIArgInfo::getExpand();
+
+    return getIndirectResult(Ty, Context);
+  } else {
+    if (const EnumType *EnumTy = Ty->getAs<EnumType>())
+      Ty = EnumTy->getDecl()->getIntegerType();
+
+    return (Ty->isPromotableIntegerType() ?
+            ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
+  }
+}
+
+llvm::Value *X86_32ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
+                                      CodeGenFunction &CGF) const {
+  const llvm::Type *BP = llvm::Type::getInt8PtrTy(CGF.getLLVMContext());
+  const llvm::Type *BPP = llvm::PointerType::getUnqual(BP);
+
+  CGBuilderTy &Builder = CGF.Builder;
+  llvm::Value *VAListAddrAsBPP = Builder.CreateBitCast(VAListAddr, BPP,
+                                                       "ap");
+  llvm::Value *Addr = Builder.CreateLoad(VAListAddrAsBPP, "ap.cur");
+  llvm::Type *PTy =
+    llvm::PointerType::getUnqual(CGF.ConvertType(Ty));
+  llvm::Value *AddrTyped = Builder.CreateBitCast(Addr, PTy);
+
+  uint64_t Offset =
+    llvm::RoundUpToAlignment(CGF.getContext().getTypeSize(Ty) / 8, 4);
+  llvm::Value *NextAddr =
+    Builder.CreateGEP(Addr, llvm::ConstantInt::get(
+                          llvm::Type::getInt32Ty(CGF.getLLVMContext()), Offset),
+                      "ap.next");
+  Builder.CreateStore(NextAddr, VAListAddrAsBPP);
+
+  return AddrTyped;
+}
+
+void X86_32TargetCodeGenInfo::SetTargetAttributes(const Decl *D,
+                                                  llvm::GlobalValue *GV,
+                                            CodeGen::CodeGenModule &CGM) const {
+  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+    if (FD->hasAttr<X86ForceAlignArgPointerAttr>()) {
+      // Get the LLVM function.
+      llvm::Function *Fn = cast<llvm::Function>(GV);
+
+      // Now add the 'alignstack' attribute with a value of 16.
+      Fn->addFnAttr(llvm::Attribute::constructStackAlignmentFromInt(16));
+    }
+  }
+}
+
+bool X86_32TargetCodeGenInfo::initDwarfEHRegSizeTable(
+                                               CodeGen::CodeGenFunction &CGF,
+                                               llvm::Value *Address) const {
+  CodeGen::CGBuilderTy &Builder = CGF.Builder;
+  llvm::LLVMContext &Context = CGF.getLLVMContext();
+
+  const llvm::IntegerType *i8 = llvm::Type::getInt8Ty(Context);
+  llvm::Value *Four8 = llvm::ConstantInt::get(i8, 4);
+    
+  // 0-7 are the eight integer registers;  the order is different
+  //   on Darwin (for EH), but the range is the same.
+  // 8 is %eip.
+  for (unsigned I = 0, E = 9; I != E; ++I) {
+    llvm::Value *Slot = Builder.CreateConstInBoundsGEP1_32(Address, I);
+    Builder.CreateStore(Four8, Slot);
+  }
+
+  if (CGF.CGM.isTargetDarwin()) {
+    // 12-16 are st(0..4).  Not sure why we stop at 4.
+    // These have size 16, which is sizeof(long double) on
+    // platforms with 8-byte alignment for that type.
+    llvm::Value *Sixteen8 = llvm::ConstantInt::get(i8, 16);
+    for (unsigned I = 12, E = 17; I != E; ++I) {
+      llvm::Value *Slot = Builder.CreateConstInBoundsGEP1_32(Address, I);
+      Builder.CreateStore(Sixteen8, Slot);
+    }
+      
+  } else {
+    // 9 is %eflags, which doesn't get a size on Darwin for some
+    // reason.
+    Builder.CreateStore(Four8, Builder.CreateConstInBoundsGEP1_32(Address, 9));
+
+    // 11-16 are st(0..5).  Not sure why we stop at 5.
+    // These have size 12, which is sizeof(long double) on
+    // platforms with 4-byte alignment for that type.
+    llvm::Value *Twelve8 = llvm::ConstantInt::get(i8, 12);
+    for (unsigned I = 11, E = 17; I != E; ++I) {
+      llvm::Value *Slot = Builder.CreateConstInBoundsGEP1_32(Address, I);
+      Builder.CreateStore(Twelve8, Slot);
+    }
+  }      
+
+  return false;
+}
+
+namespace {
+/// X86_64ABIInfo - The X86_64 ABI information.
+class X86_64ABIInfo : public ABIInfo {
+  enum Class {
+    Integer = 0,
+    SSE,
+    SSEUp,
+    X87,
+    X87Up,
+    ComplexX87,
+    NoClass,
+    Memory
+  };
+
+  /// merge - Implement the X86_64 ABI merging algorithm.
+  ///
+  /// Merge an accumulating classification \arg Accum with a field
+  /// classification \arg Field.
+  ///
+  /// \param Accum - The accumulating classification. This should
+  /// always be either NoClass or the result of a previous merge
+  /// call. In addition, this should never be Memory (the caller
+  /// should just return Memory for the aggregate).
+  Class merge(Class Accum, Class Field) const;
+
+  /// classify - Determine the x86_64 register classes in which the
+  /// given type T should be passed.
+  ///
+  /// \param Lo - The classification for the parts of the type
+  /// residing in the low word of the containing object.
+  ///
+  /// \param Hi - The classification for the parts of the type
+  /// residing in the high word of the containing object.
+  ///
+  /// \param OffsetBase - The bit offset of this type in the
+  /// containing object.  Some parameters are classified different
+  /// depending on whether they straddle an eightbyte boundary.
+  ///
+  /// If a word is unused its result will be NoClass; if a type should
+  /// be passed in Memory then at least the classification of \arg Lo
+  /// will be Memory.
+  ///
+  /// The \arg Lo class will be NoClass iff the argument is ignored.
+  ///
+  /// If the \arg Lo class is ComplexX87, then the \arg Hi class will
+  /// also be ComplexX87.
+  void classify(QualType T, ASTContext &Context, uint64_t OffsetBase,
+                Class &Lo, Class &Hi) const;
+
+  /// getCoerceResult - Given a source type \arg Ty and an LLVM type
+  /// to coerce to, chose the best way to pass Ty in the same place
+  /// that \arg CoerceTo would be passed, but while keeping the
+  /// emitted code as simple as possible.
+  ///
+  /// FIXME: Note, this should be cleaned up to just take an enumeration of all
+  /// the ways we might want to pass things, instead of constructing an LLVM
+  /// type. This makes this code more explicit, and it makes it clearer that we
+  /// are also doing this for correctness in the case of passing scalar types.
+  ABIArgInfo getCoerceResult(QualType Ty,
+                             const llvm::Type *CoerceTo,
+                             ASTContext &Context) const;
+
+  /// getIndirectResult - Give a source type \arg Ty, return a suitable result
+  /// such that the argument will be returned in memory.
+  ABIArgInfo getIndirectReturnResult(QualType Ty, ASTContext &Context) const;
+
+  /// getIndirectResult - Give a source type \arg Ty, return a suitable result
+  /// such that the argument will be passed in memory.
+  ABIArgInfo getIndirectResult(QualType Ty, ASTContext &Context) const;
+
+  ABIArgInfo classifyReturnType(QualType RetTy,
+                                ASTContext &Context,
+                                llvm::LLVMContext &VMContext) const;
+
+  ABIArgInfo classifyArgumentType(QualType Ty,
+                                  ASTContext &Context,
+                                  llvm::LLVMContext &VMContext,
+                                  unsigned &neededInt,
+                                  unsigned &neededSSE) const;
+
+public:
+  virtual void computeInfo(CGFunctionInfo &FI, ASTContext &Context,
+                           llvm::LLVMContext &VMContext) const;
+
+  virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
+                                 CodeGenFunction &CGF) const;
+};
+
+class X86_64TargetCodeGenInfo : public TargetCodeGenInfo {
+public:
+  X86_64TargetCodeGenInfo():TargetCodeGenInfo(new X86_64ABIInfo()) {}
+
+  int getDwarfEHStackPointer(CodeGen::CodeGenModule &CGM) const {
+    return 7;
+  }
+
+  bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
+                               llvm::Value *Address) const {
+    CodeGen::CGBuilderTy &Builder = CGF.Builder;
+    llvm::LLVMContext &Context = CGF.getLLVMContext();
+
+    const llvm::IntegerType *i8 = llvm::Type::getInt8Ty(Context);
+    llvm::Value *Eight8 = llvm::ConstantInt::get(i8, 8);
+      
+    // 0-16 are the 16 integer registers.
+    // 17 is %rip.
+    for (unsigned I = 0, E = 17; I != E; ++I) {
+      llvm::Value *Slot = Builder.CreateConstInBoundsGEP1_32(Address, I);
+      Builder.CreateStore(Eight8, Slot);
+    }
+
+    return false;
+  }
+};
+
+}
+
+X86_64ABIInfo::Class X86_64ABIInfo::merge(Class Accum,
+                                          Class Field) const {
+  // AMD64-ABI 3.2.3p2: Rule 4. Each field of an object is
+  // classified recursively so that always two fields are
+  // considered. The resulting class is calculated according to
+  // the classes of the fields in the eightbyte:
+  //
+  // (a) If both classes are equal, this is the resulting class.
+  //
+  // (b) If one of the classes is NO_CLASS, the resulting class is
+  // the other class.
+  //
+  // (c) If one of the classes is MEMORY, the result is the MEMORY
+  // class.
+  //
+  // (d) If one of the classes is INTEGER, the result is the
+  // INTEGER.
+  //
+  // (e) If one of the classes is X87, X87UP, COMPLEX_X87 class,
+  // MEMORY is used as class.
+  //
+  // (f) Otherwise class SSE is used.
+
+  // Accum should never be memory (we should have returned) or
+  // ComplexX87 (because this cannot be passed in a structure).
+  assert((Accum != Memory && Accum != ComplexX87) &&
+         "Invalid accumulated classification during merge.");
+  if (Accum == Field || Field == NoClass)
+    return Accum;
+  else if (Field == Memory)
+    return Memory;
+  else if (Accum == NoClass)
+    return Field;
+  else if (Accum == Integer || Field == Integer)
+    return Integer;
+  else if (Field == X87 || Field == X87Up || Field == ComplexX87 ||
+           Accum == X87 || Accum == X87Up)
+    return Memory;
+  else
+    return SSE;
+}
+
+void X86_64ABIInfo::classify(QualType Ty,
+                             ASTContext &Context,
+                             uint64_t OffsetBase,
+                             Class &Lo, Class &Hi) const {
+  // FIXME: This code can be simplified by introducing a simple value class for
+  // Class pairs with appropriate constructor methods for the various
+  // situations.
+
+  // FIXME: Some of the split computations are wrong; unaligned vectors
+  // shouldn't be passed in registers for example, so there is no chance they
+  // can straddle an eightbyte. Verify & simplify.
+
+  Lo = Hi = NoClass;
+
+  Class &Current = OffsetBase < 64 ? Lo : Hi;
+  Current = Memory;
+
+  if (const BuiltinType *BT = Ty->getAs<BuiltinType>()) {
+    BuiltinType::Kind k = BT->getKind();
+
+    if (k == BuiltinType::Void) {
+      Current = NoClass;
+    } else if (k == BuiltinType::Int128 || k == BuiltinType::UInt128) {
+      Lo = Integer;
+      Hi = Integer;
+    } else if (k >= BuiltinType::Bool && k <= BuiltinType::LongLong) {
+      Current = Integer;
+    } else if (k == BuiltinType::Float || k == BuiltinType::Double) {
+      Current = SSE;
+    } else if (k == BuiltinType::LongDouble) {
+      Lo = X87;
+      Hi = X87Up;
+    }
+    // FIXME: _Decimal32 and _Decimal64 are SSE.
+    // FIXME: _float128 and _Decimal128 are (SSE, SSEUp).
+  } else if (const EnumType *ET = Ty->getAs<EnumType>()) {
+    // Classify the underlying integer type.
+    classify(ET->getDecl()->getIntegerType(), Context, OffsetBase, Lo, Hi);
+  } else if (Ty->hasPointerRepresentation()) {
+    Current = Integer;
+  } else if (const VectorType *VT = Ty->getAs<VectorType>()) {
+    uint64_t Size = Context.getTypeSize(VT);
+    if (Size == 32) {
+      // gcc passes all <4 x char>, <2 x short>, <1 x int>, <1 x
+      // float> as integer.
+      Current = Integer;
+
+      // If this type crosses an eightbyte boundary, it should be
+      // split.
+      uint64_t EB_Real = (OffsetBase) / 64;
+      uint64_t EB_Imag = (OffsetBase + Size - 1) / 64;
+      if (EB_Real != EB_Imag)
+        Hi = Lo;
+    } else if (Size == 64) {
+      // gcc passes <1 x double> in memory. :(
+      if (VT->getElementType()->isSpecificBuiltinType(BuiltinType::Double))
+        return;
+
+      // gcc passes <1 x long long> as INTEGER.
+      if (VT->getElementType()->isSpecificBuiltinType(BuiltinType::LongLong))
+        Current = Integer;
+      else
+        Current = SSE;
+
+      // If this type crosses an eightbyte boundary, it should be
+      // split.
+      if (OffsetBase && OffsetBase != 64)
+        Hi = Lo;
+    } else if (Size == 128) {
+      Lo = SSE;
+      Hi = SSEUp;
+    }
+  } else if (const ComplexType *CT = Ty->getAs<ComplexType>()) {
+    QualType ET = Context.getCanonicalType(CT->getElementType());
+
+    uint64_t Size = Context.getTypeSize(Ty);
+    if (ET->isIntegralType()) {
+      if (Size <= 64)
+        Current = Integer;
+      else if (Size <= 128)
+        Lo = Hi = Integer;
+    } else if (ET == Context.FloatTy)
+      Current = SSE;
+    else if (ET == Context.DoubleTy)
+      Lo = Hi = SSE;
+    else if (ET == Context.LongDoubleTy)
+      Current = ComplexX87;
+
+    // If this complex type crosses an eightbyte boundary then it
+    // should be split.
+    uint64_t EB_Real = (OffsetBase) / 64;
+    uint64_t EB_Imag = (OffsetBase + Context.getTypeSize(ET)) / 64;
+    if (Hi == NoClass && EB_Real != EB_Imag)
+      Hi = Lo;
+  } else if (const ConstantArrayType *AT = Context.getAsConstantArrayType(Ty)) {
+    // Arrays are treated like structures.
+
+    uint64_t Size = Context.getTypeSize(Ty);
+
+    // AMD64-ABI 3.2.3p2: Rule 1. If the size of an object is larger
+    // than two eightbytes, ..., it has class MEMORY.
+    if (Size > 128)
+      return;
+
+    // AMD64-ABI 3.2.3p2: Rule 1. If ..., or it contains unaligned
+    // fields, it has class MEMORY.
+    //
+    // Only need to check alignment of array base.
+    if (OffsetBase % Context.getTypeAlign(AT->getElementType()))
+      return;
+
+    // Otherwise implement simplified merge. We could be smarter about
+    // this, but it isn't worth it and would be harder to verify.
+    Current = NoClass;
+    uint64_t EltSize = Context.getTypeSize(AT->getElementType());
+    uint64_t ArraySize = AT->getSize().getZExtValue();
+    for (uint64_t i=0, Offset=OffsetBase; i<ArraySize; ++i, Offset += EltSize) {
+      Class FieldLo, FieldHi;
+      classify(AT->getElementType(), Context, Offset, FieldLo, FieldHi);
+      Lo = merge(Lo, FieldLo);
+      Hi = merge(Hi, FieldHi);
+      if (Lo == Memory || Hi == Memory)
+        break;
+    }
+
+    // Do post merger cleanup (see below). Only case we worry about is Memory.
+    if (Hi == Memory)
+      Lo = Memory;
+    assert((Hi != SSEUp || Lo == SSE) && "Invalid SSEUp array classification.");
+  } else if (const RecordType *RT = Ty->getAs<RecordType>()) {
+    uint64_t Size = Context.getTypeSize(Ty);
+
+    // AMD64-ABI 3.2.3p2: Rule 1. If the size of an object is larger
+    // than two eightbytes, ..., it has class MEMORY.
+    if (Size > 128)
+      return;
+
+    // AMD64-ABI 3.2.3p2: Rule 2. If a C++ object has either a non-trivial
+    // copy constructor or a non-trivial destructor, it is passed by invisible
+    // reference.
+    if (hasNonTrivialDestructorOrCopyConstructor(RT))
+      return;
+
+    const RecordDecl *RD = RT->getDecl();
+
+    // Assume variable sized types are passed in memory.
+    if (RD->hasFlexibleArrayMember())
+      return;
+
+    const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
+
+    // Reset Lo class, this will be recomputed.
+    Current = NoClass;
+
+    // If this is a C++ record, classify the bases first.
+    if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
+      for (CXXRecordDecl::base_class_const_iterator i = CXXRD->bases_begin(),
+             e = CXXRD->bases_end(); i != e; ++i) {
+        assert(!i->isVirtual() && !i->getType()->isDependentType() &&
+               "Unexpected base class!");
+        const CXXRecordDecl *Base =
+          cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
+
+        // Classify this field.
+        //
+        // AMD64-ABI 3.2.3p2: Rule 3. If the size of the aggregate exceeds a
+        // single eightbyte, each is classified separately. Each eightbyte gets
+        // initialized to class NO_CLASS.
+        Class FieldLo, FieldHi;
+        uint64_t Offset = OffsetBase + Layout.getBaseClassOffset(Base);
+        classify(i->getType(), Context, Offset, FieldLo, FieldHi);
+        Lo = merge(Lo, FieldLo);
+        Hi = merge(Hi, FieldHi);
+        if (Lo == Memory || Hi == Memory)
+          break;
+      }
+
+      // If this record has no fields but isn't empty, classify as INTEGER.
+      if (RD->field_empty() && Size)
+        Current = Integer;
+    }
+
+    // Classify the fields one at a time, merging the results.
+    unsigned idx = 0;
+    for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
+           i != e; ++i, ++idx) {
+      uint64_t Offset = OffsetBase + Layout.getFieldOffset(idx);
+      bool BitField = i->isBitField();
+
+      // AMD64-ABI 3.2.3p2: Rule 1. If ..., or it contains unaligned
+      // fields, it has class MEMORY.
+      //
+      // Note, skip this test for bit-fields, see below.
+      if (!BitField && Offset % Context.getTypeAlign(i->getType())) {
+        Lo = Memory;
+        return;
+      }
+
+      // Classify this field.
+      //
+      // AMD64-ABI 3.2.3p2: Rule 3. If the size of the aggregate
+      // exceeds a single eightbyte, each is classified
+      // separately. Each eightbyte gets initialized to class
+      // NO_CLASS.
+      Class FieldLo, FieldHi;
+
+      // Bit-fields require special handling, they do not force the
+      // structure to be passed in memory even if unaligned, and
+      // therefore they can straddle an eightbyte.
+      if (BitField) {
+        // Ignore padding bit-fields.
+        if (i->isUnnamedBitfield())
+          continue;
+
+        uint64_t Offset = OffsetBase + Layout.getFieldOffset(idx);
+        uint64_t Size = i->getBitWidth()->EvaluateAsInt(Context).getZExtValue();
+
+        uint64_t EB_Lo = Offset / 64;
+        uint64_t EB_Hi = (Offset + Size - 1) / 64;
+        FieldLo = FieldHi = NoClass;
+        if (EB_Lo) {
+          assert(EB_Hi == EB_Lo && "Invalid classification, type > 16 bytes.");
+          FieldLo = NoClass;
+          FieldHi = Integer;
+        } else {
+          FieldLo = Integer;
+          FieldHi = EB_Hi ? Integer : NoClass;
+        }
+      } else
+        classify(i->getType(), Context, Offset, FieldLo, FieldHi);
+      Lo = merge(Lo, FieldLo);
+      Hi = merge(Hi, FieldHi);
+      if (Lo == Memory || Hi == Memory)
+        break;
+    }
+
+    // AMD64-ABI 3.2.3p2: Rule 5. Then a post merger cleanup is done:
+    //
+    // (a) If one of the classes is MEMORY, the whole argument is
+    // passed in memory.
+    //
+    // (b) If SSEUP is not preceeded by SSE, it is converted to SSE.
+
+    // The first of these conditions is guaranteed by how we implement
+    // the merge (just bail).
+    //
+    // The second condition occurs in the case of unions; for example
+    // union { _Complex double; unsigned; }.
+    if (Hi == Memory)
+      Lo = Memory;
+    if (Hi == SSEUp && Lo != SSE)
+      Hi = SSE;
+  }
+}
+
+ABIArgInfo X86_64ABIInfo::getCoerceResult(QualType Ty,
+                                          const llvm::Type *CoerceTo,
+                                          ASTContext &Context) const {
+  if (CoerceTo == llvm::Type::getInt64Ty(CoerceTo->getContext())) {
+    // Integer and pointer types will end up in a general purpose
+    // register.
+
+    // Treat an enum type as its underlying type.
+    if (const EnumType *EnumTy = Ty->getAs<EnumType>())
+      Ty = EnumTy->getDecl()->getIntegerType();
+
+    if (Ty->isIntegralType() || Ty->hasPointerRepresentation())
+      return (Ty->isPromotableIntegerType() ?
+              ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
+  } else if (CoerceTo == llvm::Type::getDoubleTy(CoerceTo->getContext())) {
+    assert(Ty.isCanonical() && "should always have a canonical type here");
+    assert(!Ty.hasQualifiers() && "should never have a qualified type here");
+
+    // Float and double end up in a single SSE reg.
+    if (Ty == Context.FloatTy || Ty == Context.DoubleTy)
+      return ABIArgInfo::getDirect();
+
+  }
+
+  return ABIArgInfo::getCoerce(CoerceTo);
+}
+
+ABIArgInfo X86_64ABIInfo::getIndirectReturnResult(QualType Ty,
+                                                  ASTContext &Context) const {
+  // If this is a scalar LLVM value then assume LLVM will pass it in the right
+  // place naturally.
+  if (!CodeGenFunction::hasAggregateLLVMType(Ty)) {
+    // Treat an enum type as its underlying type.
+    if (const EnumType *EnumTy = Ty->getAs<EnumType>())
+      Ty = EnumTy->getDecl()->getIntegerType();
+
+    return (Ty->isPromotableIntegerType() ?
+            ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
+  }
+
+  return ABIArgInfo::getIndirect(0);
+}
+
+ABIArgInfo X86_64ABIInfo::getIndirectResult(QualType Ty,
+                                            ASTContext &Context) const {
+  // If this is a scalar LLVM value then assume LLVM will pass it in the right
+  // place naturally.
+  if (!CodeGenFunction::hasAggregateLLVMType(Ty)) {
+    // Treat an enum type as its underlying type.
+    if (const EnumType *EnumTy = Ty->getAs<EnumType>())
+      Ty = EnumTy->getDecl()->getIntegerType();
+
+    return (Ty->isPromotableIntegerType() ?
+            ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
+  }
+
+  if (isRecordWithNonTrivialDestructorOrCopyConstructor(Ty))
+    return ABIArgInfo::getIndirect(0, /*ByVal=*/false);
+
+  // Compute the byval alignment. We trust the back-end to honor the
+  // minimum ABI alignment for byval, to make cleaner IR.
+  const unsigned MinABIAlign = 8;
+  unsigned Align = Context.getTypeAlign(Ty) / 8;
+  if (Align > MinABIAlign)
+    return ABIArgInfo::getIndirect(Align);
+  return ABIArgInfo::getIndirect(0);
+}
+
+ABIArgInfo X86_64ABIInfo::classifyReturnType(QualType RetTy,
+                                            ASTContext &Context,
+                                          llvm::LLVMContext &VMContext) const {
+  // AMD64-ABI 3.2.3p4: Rule 1. Classify the return type with the
+  // classification algorithm.
+  X86_64ABIInfo::Class Lo, Hi;
+  classify(RetTy, Context, 0, Lo, Hi);
+
+  // Check some invariants.
+  assert((Hi != Memory || Lo == Memory) && "Invalid memory classification.");
+  assert((Lo != NoClass || Hi == NoClass) && "Invalid null classification.");
+  assert((Hi != SSEUp || Lo == SSE) && "Invalid SSEUp classification.");
+
+  const llvm::Type *ResType = 0;
+  switch (Lo) {
+  case NoClass:
+    return ABIArgInfo::getIgnore();
+
+  case SSEUp:
+  case X87Up:
+    assert(0 && "Invalid classification for lo word.");
+
+    // AMD64-ABI 3.2.3p4: Rule 2. Types of class memory are returned via
+    // hidden argument.
+  case Memory:
+    return getIndirectReturnResult(RetTy, Context);
+
+    // AMD64-ABI 3.2.3p4: Rule 3. If the class is INTEGER, the next
+    // available register of the sequence %rax, %rdx is used.
+  case Integer:
+    ResType = llvm::Type::getInt64Ty(VMContext); break;
+
+    // AMD64-ABI 3.2.3p4: Rule 4. If the class is SSE, the next
+    // available SSE register of the sequence %xmm0, %xmm1 is used.
+  case SSE:
+    ResType = llvm::Type::getDoubleTy(VMContext); break;
+
+    // AMD64-ABI 3.2.3p4: Rule 6. If the class is X87, the value is
+    // returned on the X87 stack in %st0 as 80-bit x87 number.
+  case X87:
+    ResType = llvm::Type::getX86_FP80Ty(VMContext); break;
+
+    // AMD64-ABI 3.2.3p4: Rule 8. If the class is COMPLEX_X87, the real
+    // part of the value is returned in %st0 and the imaginary part in
+    // %st1.
+  case ComplexX87:
+    assert(Hi == ComplexX87 && "Unexpected ComplexX87 classification.");
+    ResType = llvm::StructType::get(VMContext,
+                                    llvm::Type::getX86_FP80Ty(VMContext),
+                                    llvm::Type::getX86_FP80Ty(VMContext),
+                                    NULL);
+    break;
+  }
+
+  switch (Hi) {
+    // Memory was handled previously and X87 should
+    // never occur as a hi class.
+  case Memory:
+  case X87:
+    assert(0 && "Invalid classification for hi word.");
+
+  case ComplexX87: // Previously handled.
+  case NoClass: break;
+
+  case Integer:
+    ResType = llvm::StructType::get(VMContext, ResType,
+                                    llvm::Type::getInt64Ty(VMContext), NULL);
+    break;
+  case SSE:
+    ResType = llvm::StructType::get(VMContext, ResType,
+                                    llvm::Type::getDoubleTy(VMContext), NULL);
+    break;
+
+    // AMD64-ABI 3.2.3p4: Rule 5. If the class is SSEUP, the eightbyte
+    // is passed in the upper half of the last used SSE register.
+    //
+    // SSEUP should always be preceeded by SSE, just widen.
+  case SSEUp:
+    assert(Lo == SSE && "Unexpected SSEUp classification.");
+    ResType = llvm::VectorType::get(llvm::Type::getDoubleTy(VMContext), 2);
+    break;
+
+    // AMD64-ABI 3.2.3p4: Rule 7. If the class is X87UP, the value is
+    // returned together with the previous X87 value in %st0.
+  case X87Up:
+    // If X87Up is preceeded by X87, we don't need to do
+    // anything. However, in some cases with unions it may not be
+    // preceeded by X87. In such situations we follow gcc and pass the
+    // extra bits in an SSE reg.
+    if (Lo != X87)
+      ResType = llvm::StructType::get(VMContext, ResType,
+                                      llvm::Type::getDoubleTy(VMContext), NULL);
+    break;
+  }
+
+  return getCoerceResult(RetTy, ResType, Context);
+}
+
+ABIArgInfo X86_64ABIInfo::classifyArgumentType(QualType Ty, ASTContext &Context,
+                                               llvm::LLVMContext &VMContext,
+                                               unsigned &neededInt,
+                                               unsigned &neededSSE) const {
+  X86_64ABIInfo::Class Lo, Hi;
+  classify(Ty, Context, 0, Lo, Hi);
+
+  // Check some invariants.
+  // FIXME: Enforce these by construction.
+  assert((Hi != Memory || Lo == Memory) && "Invalid memory classification.");
+  assert((Lo != NoClass || Hi == NoClass) && "Invalid null classification.");
+  assert((Hi != SSEUp || Lo == SSE) && "Invalid SSEUp classification.");
+
+  neededInt = 0;
+  neededSSE = 0;
+  const llvm::Type *ResType = 0;
+  switch (Lo) {
+  case NoClass:
+    return ABIArgInfo::getIgnore();
+
+    // AMD64-ABI 3.2.3p3: Rule 1. If the class is MEMORY, pass the argument
+    // on the stack.
+  case Memory:
+
+    // AMD64-ABI 3.2.3p3: Rule 5. If the class is X87, X87UP or
+    // COMPLEX_X87, it is passed in memory.
+  case X87:
+  case ComplexX87:
+    return getIndirectResult(Ty, Context);
+
+  case SSEUp:
+  case X87Up:
+    assert(0 && "Invalid classification for lo word.");
+
+    // AMD64-ABI 3.2.3p3: Rule 2. If the class is INTEGER, the next
+    // available register of the sequence %rdi, %rsi, %rdx, %rcx, %r8
+    // and %r9 is used.
+  case Integer:
+    ++neededInt;
+    ResType = llvm::Type::getInt64Ty(VMContext);
+    break;
+
+    // AMD64-ABI 3.2.3p3: Rule 3. If the class is SSE, the next
+    // available SSE register is used, the registers are taken in the
+    // order from %xmm0 to %xmm7.
+  case SSE:
+    ++neededSSE;
+    ResType = llvm::Type::getDoubleTy(VMContext);
+    break;
+  }
+
+  switch (Hi) {
+    // Memory was handled previously, ComplexX87 and X87 should
+    // never occur as hi classes, and X87Up must be preceed by X87,
+    // which is passed in memory.
+  case Memory:
+  case X87:
+  case ComplexX87:
+    assert(0 && "Invalid classification for hi word.");
+    break;
+
+  case NoClass: break;
+  case Integer:
+    ResType = llvm::StructType::get(VMContext, ResType,
+                                    llvm::Type::getInt64Ty(VMContext), NULL);
+    ++neededInt;
+    break;
+
+    // X87Up generally doesn't occur here (long double is passed in
+    // memory), except in situations involving unions.
+  case X87Up:
+  case SSE:
+    ResType = llvm::StructType::get(VMContext, ResType,
+                                    llvm::Type::getDoubleTy(VMContext), NULL);
+    ++neededSSE;
+    break;
+
+    // AMD64-ABI 3.2.3p3: Rule 4. If the class is SSEUP, the
+    // eightbyte is passed in the upper half of the last used SSE
+    // register.
+  case SSEUp:
+    assert(Lo == SSE && "Unexpected SSEUp classification.");
+    ResType = llvm::VectorType::get(llvm::Type::getDoubleTy(VMContext), 2);
+    break;
+  }
+
+  return getCoerceResult(Ty, ResType, Context);
+}
+
+void X86_64ABIInfo::computeInfo(CGFunctionInfo &FI, ASTContext &Context,
+                                llvm::LLVMContext &VMContext) const {
+  FI.getReturnInfo() = classifyReturnType(FI.getReturnType(),
+                                          Context, VMContext);
+
+  // Keep track of the number of assigned registers.
+  unsigned freeIntRegs = 6, freeSSERegs = 8;
+
+  // If the return value is indirect, then the hidden argument is consuming one
+  // integer register.
+  if (FI.getReturnInfo().isIndirect())
+    --freeIntRegs;
+
+  // AMD64-ABI 3.2.3p3: Once arguments are classified, the registers
+  // get assigned (in left-to-right order) for passing as follows...
+  for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end();
+       it != ie; ++it) {
+    unsigned neededInt, neededSSE;
+    it->info = classifyArgumentType(it->type, Context, VMContext,
+                                    neededInt, neededSSE);
+
+    // AMD64-ABI 3.2.3p3: If there are no registers available for any
+    // eightbyte of an argument, the whole argument is passed on the
+    // stack. If registers have already been assigned for some
+    // eightbytes of such an argument, the assignments get reverted.
+    if (freeIntRegs >= neededInt && freeSSERegs >= neededSSE) {
+      freeIntRegs -= neededInt;
+      freeSSERegs -= neededSSE;
+    } else {
+      it->info = getIndirectResult(it->type, Context);
+    }
+  }
+}
+
+static llvm::Value *EmitVAArgFromMemory(llvm::Value *VAListAddr,
+                                        QualType Ty,
+                                        CodeGenFunction &CGF) {
+  llvm::Value *overflow_arg_area_p =
+    CGF.Builder.CreateStructGEP(VAListAddr, 2, "overflow_arg_area_p");
+  llvm::Value *overflow_arg_area =
+    CGF.Builder.CreateLoad(overflow_arg_area_p, "overflow_arg_area");
+
+  // AMD64-ABI 3.5.7p5: Step 7. Align l->overflow_arg_area upwards to a 16
+  // byte boundary if alignment needed by type exceeds 8 byte boundary.
+  uint64_t Align = CGF.getContext().getTypeAlign(Ty) / 8;
+  if (Align > 8) {
+    // Note that we follow the ABI & gcc here, even though the type
+    // could in theory have an alignment greater than 16. This case
+    // shouldn't ever matter in practice.
+
+    // overflow_arg_area = (overflow_arg_area + 15) & ~15;
+    llvm::Value *Offset =
+      llvm::ConstantInt::get(llvm::Type::getInt32Ty(CGF.getLLVMContext()), 15);
+    overflow_arg_area = CGF.Builder.CreateGEP(overflow_arg_area, Offset);
+    llvm::Value *AsInt = CGF.Builder.CreatePtrToInt(overflow_arg_area,
+                                 llvm::Type::getInt64Ty(CGF.getLLVMContext()));
+    llvm::Value *Mask = llvm::ConstantInt::get(
+        llvm::Type::getInt64Ty(CGF.getLLVMContext()), ~15LL);
+    overflow_arg_area =
+      CGF.Builder.CreateIntToPtr(CGF.Builder.CreateAnd(AsInt, Mask),
+                                 overflow_arg_area->getType(),
+                                 "overflow_arg_area.align");
+  }
+
+  // AMD64-ABI 3.5.7p5: Step 8. Fetch type from l->overflow_arg_area.
+  const llvm::Type *LTy = CGF.ConvertTypeForMem(Ty);
+  llvm::Value *Res =
+    CGF.Builder.CreateBitCast(overflow_arg_area,
+                              llvm::PointerType::getUnqual(LTy));
+
+  // AMD64-ABI 3.5.7p5: Step 9. Set l->overflow_arg_area to:
+  // l->overflow_arg_area + sizeof(type).
+  // AMD64-ABI 3.5.7p5: Step 10. Align l->overflow_arg_area upwards to
+  // an 8 byte boundary.
+
+  uint64_t SizeInBytes = (CGF.getContext().getTypeSize(Ty) + 7) / 8;
+  llvm::Value *Offset =
+      llvm::ConstantInt::get(llvm::Type::getInt32Ty(CGF.getLLVMContext()),
+                                               (SizeInBytes + 7)  & ~7);
+  overflow_arg_area = CGF.Builder.CreateGEP(overflow_arg_area, Offset,
+                                            "overflow_arg_area.next");
+  CGF.Builder.CreateStore(overflow_arg_area, overflow_arg_area_p);
+
+  // AMD64-ABI 3.5.7p5: Step 11. Return the fetched type.
+  return Res;
+}
+
+llvm::Value *X86_64ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
+                                      CodeGenFunction &CGF) const {
+  llvm::LLVMContext &VMContext = CGF.getLLVMContext();
+  const llvm::Type *i32Ty = llvm::Type::getInt32Ty(VMContext);
+  const llvm::Type *DoubleTy = llvm::Type::getDoubleTy(VMContext);
+
+  // Assume that va_list type is correct; should be pointer to LLVM type:
+  // struct {
+  //   i32 gp_offset;
+  //   i32 fp_offset;
+  //   i8* overflow_arg_area;
+  //   i8* reg_save_area;
+  // };
+  unsigned neededInt, neededSSE;
+  
+  Ty = CGF.getContext().getCanonicalType(Ty);
+  ABIArgInfo AI = classifyArgumentType(Ty, CGF.getContext(), VMContext,
+                                       neededInt, neededSSE);
+
+  // AMD64-ABI 3.5.7p5: Step 1. Determine whether type may be passed
+  // in the registers. If not go to step 7.
+  if (!neededInt && !neededSSE)
+    return EmitVAArgFromMemory(VAListAddr, Ty, CGF);
+
+  // AMD64-ABI 3.5.7p5: Step 2. Compute num_gp to hold the number of
+  // general purpose registers needed to pass type and num_fp to hold
+  // the number of floating point registers needed.
+
+  // AMD64-ABI 3.5.7p5: Step 3. Verify whether arguments fit into
+  // registers. In the case: l->gp_offset > 48 - num_gp * 8 or
+  // l->fp_offset > 304 - num_fp * 16 go to step 7.
+  //
+  // NOTE: 304 is a typo, there are (6 * 8 + 8 * 16) = 176 bytes of
+  // register save space).
+
+  llvm::Value *InRegs = 0;
+  llvm::Value *gp_offset_p = 0, *gp_offset = 0;
+  llvm::Value *fp_offset_p = 0, *fp_offset = 0;
+  if (neededInt) {
+    gp_offset_p = CGF.Builder.CreateStructGEP(VAListAddr, 0, "gp_offset_p");
+    gp_offset = CGF.Builder.CreateLoad(gp_offset_p, "gp_offset");
+    InRegs =
+      CGF.Builder.CreateICmpULE(gp_offset,
+                                llvm::ConstantInt::get(i32Ty,
+                                                       48 - neededInt * 8),
+                                "fits_in_gp");
+  }
+
+  if (neededSSE) {
+    fp_offset_p = CGF.Builder.CreateStructGEP(VAListAddr, 1, "fp_offset_p");
+    fp_offset = CGF.Builder.CreateLoad(fp_offset_p, "fp_offset");
+    llvm::Value *FitsInFP =
+      CGF.Builder.CreateICmpULE(fp_offset,
+                                llvm::ConstantInt::get(i32Ty,
+                                                       176 - neededSSE * 16),
+                                "fits_in_fp");
+    InRegs = InRegs ? CGF.Builder.CreateAnd(InRegs, FitsInFP) : FitsInFP;
+  }
+
+  llvm::BasicBlock *InRegBlock = CGF.createBasicBlock("vaarg.in_reg");
+  llvm::BasicBlock *InMemBlock = CGF.createBasicBlock("vaarg.in_mem");
+  llvm::BasicBlock *ContBlock = CGF.createBasicBlock("vaarg.end");
+  CGF.Builder.CreateCondBr(InRegs, InRegBlock, InMemBlock);
+
+  // Emit code to load the value if it was passed in registers.
+
+  CGF.EmitBlock(InRegBlock);
+
+  // AMD64-ABI 3.5.7p5: Step 4. Fetch type from l->reg_save_area with
+  // an offset of l->gp_offset and/or l->fp_offset. This may require
+  // copying to a temporary location in case the parameter is passed
+  // in different register classes or requires an alignment greater
+  // than 8 for general purpose registers and 16 for XMM registers.
+  //
+  // FIXME: This really results in shameful code when we end up needing to
+  // collect arguments from different places; often what should result in a
+  // simple assembling of a structure from scattered addresses has many more
+  // loads than necessary. Can we clean this up?
+  const llvm::Type *LTy = CGF.ConvertTypeForMem(Ty);
+  llvm::Value *RegAddr =
+    CGF.Builder.CreateLoad(CGF.Builder.CreateStructGEP(VAListAddr, 3),
+                           "reg_save_area");
+  if (neededInt && neededSSE) {
+    // FIXME: Cleanup.
+    assert(AI.isCoerce() && "Unexpected ABI info for mixed regs");
+    const llvm::StructType *ST = cast<llvm::StructType>(AI.getCoerceToType());
+    llvm::Value *Tmp = CGF.CreateTempAlloca(ST);
+    assert(ST->getNumElements() == 2 && "Unexpected ABI info for mixed regs");
+    const llvm::Type *TyLo = ST->getElementType(0);
+    const llvm::Type *TyHi = ST->getElementType(1);
+    assert((TyLo->isFloatingPointTy() ^ TyHi->isFloatingPointTy()) &&
+           "Unexpected ABI info for mixed regs");
+    const llvm::Type *PTyLo = llvm::PointerType::getUnqual(TyLo);
+    const llvm::Type *PTyHi = llvm::PointerType::getUnqual(TyHi);
+    llvm::Value *GPAddr = CGF.Builder.CreateGEP(RegAddr, gp_offset);
+    llvm::Value *FPAddr = CGF.Builder.CreateGEP(RegAddr, fp_offset);
+    llvm::Value *RegLoAddr = TyLo->isFloatingPointTy() ? FPAddr : GPAddr;
+    llvm::Value *RegHiAddr = TyLo->isFloatingPointTy() ? GPAddr : FPAddr;
+    llvm::Value *V =
+      CGF.Builder.CreateLoad(CGF.Builder.CreateBitCast(RegLoAddr, PTyLo));
+    CGF.Builder.CreateStore(V, CGF.Builder.CreateStructGEP(Tmp, 0));
+    V = CGF.Builder.CreateLoad(CGF.Builder.CreateBitCast(RegHiAddr, PTyHi));
+    CGF.Builder.CreateStore(V, CGF.Builder.CreateStructGEP(Tmp, 1));
+
+    RegAddr = CGF.Builder.CreateBitCast(Tmp,
+                                        llvm::PointerType::getUnqual(LTy));
+  } else if (neededInt) {
+    RegAddr = CGF.Builder.CreateGEP(RegAddr, gp_offset);
+    RegAddr = CGF.Builder.CreateBitCast(RegAddr,
+                                        llvm::PointerType::getUnqual(LTy));
+  } else {
+    if (neededSSE == 1) {
+      RegAddr = CGF.Builder.CreateGEP(RegAddr, fp_offset);
+      RegAddr = CGF.Builder.CreateBitCast(RegAddr,
+                                          llvm::PointerType::getUnqual(LTy));
+    } else {
+      assert(neededSSE == 2 && "Invalid number of needed registers!");
+      // SSE registers are spaced 16 bytes apart in the register save
+      // area, we need to collect the two eightbytes together.
+      llvm::Value *RegAddrLo = CGF.Builder.CreateGEP(RegAddr, fp_offset);
+      llvm::Value *RegAddrHi =
+        CGF.Builder.CreateGEP(RegAddrLo,
+                            llvm::ConstantInt::get(i32Ty, 16));
+      const llvm::Type *DblPtrTy =
+        llvm::PointerType::getUnqual(DoubleTy);
+      const llvm::StructType *ST = llvm::StructType::get(VMContext, DoubleTy,
+                                                         DoubleTy, NULL);
+      llvm::Value *V, *Tmp = CGF.CreateTempAlloca(ST);
+      V = CGF.Builder.CreateLoad(CGF.Builder.CreateBitCast(RegAddrLo,
+                                                           DblPtrTy));
+      CGF.Builder.CreateStore(V, CGF.Builder.CreateStructGEP(Tmp, 0));
+      V = CGF.Builder.CreateLoad(CGF.Builder.CreateBitCast(RegAddrHi,
+                                                           DblPtrTy));
+      CGF.Builder.CreateStore(V, CGF.Builder.CreateStructGEP(Tmp, 1));
+      RegAddr = CGF.Builder.CreateBitCast(Tmp,
+                                          llvm::PointerType::getUnqual(LTy));
+    }
+  }
+
+  // AMD64-ABI 3.5.7p5: Step 5. Set:
+  // l->gp_offset = l->gp_offset + num_gp * 8
+  // l->fp_offset = l->fp_offset + num_fp * 16.
+  if (neededInt) {
+    llvm::Value *Offset = llvm::ConstantInt::get(i32Ty, neededInt * 8);
+    CGF.Builder.CreateStore(CGF.Builder.CreateAdd(gp_offset, Offset),
+                            gp_offset_p);
+  }
+  if (neededSSE) {
+    llvm::Value *Offset = llvm::ConstantInt::get(i32Ty, neededSSE * 16);
+    CGF.Builder.CreateStore(CGF.Builder.CreateAdd(fp_offset, Offset),
+                            fp_offset_p);
+  }
+  CGF.EmitBranch(ContBlock);
+
+  // Emit code to load the value if it was passed in memory.
+
+  CGF.EmitBlock(InMemBlock);
+  llvm::Value *MemAddr = EmitVAArgFromMemory(VAListAddr, Ty, CGF);
+
+  // Return the appropriate result.
+
+  CGF.EmitBlock(ContBlock);
+  llvm::PHINode *ResAddr = CGF.Builder.CreatePHI(RegAddr->getType(),
+                                                 "vaarg.addr");
+  ResAddr->reserveOperandSpace(2);
+  ResAddr->addIncoming(RegAddr, InRegBlock);
+  ResAddr->addIncoming(MemAddr, InMemBlock);
+
+  return ResAddr;
+}
+
+// PIC16 ABI Implementation
+
+namespace {
+
+class PIC16ABIInfo : public ABIInfo {
+  ABIArgInfo classifyReturnType(QualType RetTy,
+                                ASTContext &Context,
+                                llvm::LLVMContext &VMContext) const;
+
+  ABIArgInfo classifyArgumentType(QualType RetTy,
+                                  ASTContext &Context,
+                                  llvm::LLVMContext &VMContext) const;
+
+  virtual void computeInfo(CGFunctionInfo &FI, ASTContext &Context,
+                           llvm::LLVMContext &VMContext) const {
+    FI.getReturnInfo() = classifyReturnType(FI.getReturnType(), Context,
+                                            VMContext);
+    for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end();
+         it != ie; ++it)
+      it->info = classifyArgumentType(it->type, Context, VMContext);
+  }
+
+  virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
+                                 CodeGenFunction &CGF) const;
+};
+
+class PIC16TargetCodeGenInfo : public TargetCodeGenInfo {
+public:
+  PIC16TargetCodeGenInfo():TargetCodeGenInfo(new PIC16ABIInfo()) {}
+};
+
+}
+
+ABIArgInfo PIC16ABIInfo::classifyReturnType(QualType RetTy,
+                                            ASTContext &Context,
+                                          llvm::LLVMContext &VMContext) const {
+  if (RetTy->isVoidType()) {
+    return ABIArgInfo::getIgnore();
+  } else {
+    return ABIArgInfo::getDirect();
+  }
+}
+
+ABIArgInfo PIC16ABIInfo::classifyArgumentType(QualType Ty,
+                                              ASTContext &Context,
+                                          llvm::LLVMContext &VMContext) const {
+  return ABIArgInfo::getDirect();
+}
+
+llvm::Value *PIC16ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
+                                       CodeGenFunction &CGF) const {
+  const llvm::Type *BP = llvm::Type::getInt8PtrTy(CGF.getLLVMContext());
+  const llvm::Type *BPP = llvm::PointerType::getUnqual(BP);
+
+  CGBuilderTy &Builder = CGF.Builder;
+  llvm::Value *VAListAddrAsBPP = Builder.CreateBitCast(VAListAddr, BPP,
+                                                       "ap");
+  llvm::Value *Addr = Builder.CreateLoad(VAListAddrAsBPP, "ap.cur");
+  llvm::Type *PTy =
+    llvm::PointerType::getUnqual(CGF.ConvertType(Ty));
+  llvm::Value *AddrTyped = Builder.CreateBitCast(Addr, PTy);
+
+  uint64_t Offset = CGF.getContext().getTypeSize(Ty) / 8;
+
+  llvm::Value *NextAddr =
+    Builder.CreateGEP(Addr, llvm::ConstantInt::get(
+                          llvm::Type::getInt32Ty(CGF.getLLVMContext()), Offset),
+                      "ap.next");
+  Builder.CreateStore(NextAddr, VAListAddrAsBPP);
+
+  return AddrTyped;
+}
+
+
+// PowerPC-32
+
+namespace {
+class PPC32TargetCodeGenInfo : public DefaultTargetCodeGenInfo {
+public:
+  int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const {
+    // This is recovered from gcc output.
+    return 1; // r1 is the dedicated stack pointer
+  }
+
+  bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
+                               llvm::Value *Address) const;  
+};
+
+}
+
+bool
+PPC32TargetCodeGenInfo::initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
+                                                llvm::Value *Address) const {
+  // This is calculated from the LLVM and GCC tables and verified
+  // against gcc output.  AFAIK all ABIs use the same encoding.
+
+  CodeGen::CGBuilderTy &Builder = CGF.Builder;
+  llvm::LLVMContext &Context = CGF.getLLVMContext();
+
+  const llvm::IntegerType *i8 = llvm::Type::getInt8Ty(Context);
+  llvm::Value *Four8 = llvm::ConstantInt::get(i8, 4);
+  llvm::Value *Eight8 = llvm::ConstantInt::get(i8, 8);
+  llvm::Value *Sixteen8 = llvm::ConstantInt::get(i8, 16);
+
+  // 0-31: r0-31, the 4-byte general-purpose registers
+  for (unsigned I = 0, E = 32; I != E; ++I) {
+    llvm::Value *Slot = Builder.CreateConstInBoundsGEP1_32(Address, I);
+    Builder.CreateStore(Four8, Slot);
+  }
+
+  // 32-63: fp0-31, the 8-byte floating-point registers
+  for (unsigned I = 32, E = 64; I != E; ++I) {
+    llvm::Value *Slot = Builder.CreateConstInBoundsGEP1_32(Address, I);
+    Builder.CreateStore(Eight8, Slot);
+  }
+
+  // 64-76 are various 4-byte special-purpose registers:
+  // 64: mq
+  // 65: lr
+  // 66: ctr
+  // 67: ap
+  // 68-75 cr0-7
+  // 76: xer
+  for (unsigned I = 64, E = 77; I != E; ++I) {
+    llvm::Value *Slot = Builder.CreateConstInBoundsGEP1_32(Address, I);
+    Builder.CreateStore(Four8, Slot);
+  }
+
+  // 77-108: v0-31, the 16-byte vector registers
+  for (unsigned I = 77, E = 109; I != E; ++I) {
+    llvm::Value *Slot = Builder.CreateConstInBoundsGEP1_32(Address, I);
+    Builder.CreateStore(Sixteen8, Slot);
+  }
+
+  // 109: vrsave
+  // 110: vscr
+  // 111: spe_acc
+  // 112: spefscr
+  // 113: sfp
+  for (unsigned I = 109, E = 114; I != E; ++I) {
+    llvm::Value *Slot = Builder.CreateConstInBoundsGEP1_32(Address, I);
+    Builder.CreateStore(Four8, Slot);
+  }
+
+  return false;  
+}
+
+
+// ARM ABI Implementation
+
+namespace {
+
+class ARMABIInfo : public ABIInfo {
+public:
+  enum ABIKind {
+    APCS = 0,
+    AAPCS = 1,
+    AAPCS_VFP
+  };
+
+private:
+  ABIKind Kind;
+
+public:
+  ARMABIInfo(ABIKind _Kind) : Kind(_Kind) {}
+
+private:
+  ABIKind getABIKind() const { return Kind; }
+
+  ABIArgInfo classifyReturnType(QualType RetTy,
+                                ASTContext &Context,
+                                llvm::LLVMContext &VMCOntext) const;
+
+  ABIArgInfo classifyArgumentType(QualType RetTy,
+                                  ASTContext &Context,
+                                  llvm::LLVMContext &VMContext) const;
+
+  virtual void computeInfo(CGFunctionInfo &FI, ASTContext &Context,
+                           llvm::LLVMContext &VMContext) const;
+
+  virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
+                                 CodeGenFunction &CGF) const;
+};
+
+class ARMTargetCodeGenInfo : public TargetCodeGenInfo {
+public:
+  ARMTargetCodeGenInfo(ARMABIInfo::ABIKind K)
+    :TargetCodeGenInfo(new ARMABIInfo(K)) {}
+
+  int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const {
+    return 13;
+  }
+};
+
+}
+
+void ARMABIInfo::computeInfo(CGFunctionInfo &FI, ASTContext &Context,
+                             llvm::LLVMContext &VMContext) const {
+  FI.getReturnInfo() = classifyReturnType(FI.getReturnType(), Context,
+                                          VMContext);
+  for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end();
+       it != ie; ++it) {
+    it->info = classifyArgumentType(it->type, Context, VMContext);
+  }
+
+  // ARM always overrides the calling convention.
+  switch (getABIKind()) {
+  case APCS:
+    FI.setEffectiveCallingConvention(llvm::CallingConv::ARM_APCS);
+    break;
+
+  case AAPCS:
+    FI.setEffectiveCallingConvention(llvm::CallingConv::ARM_AAPCS);
+    break;
+
+  case AAPCS_VFP:
+    FI.setEffectiveCallingConvention(llvm::CallingConv::ARM_AAPCS_VFP);
+    break;
+  }
+}
+
+ABIArgInfo ARMABIInfo::classifyArgumentType(QualType Ty,
+                                            ASTContext &Context,
+                                          llvm::LLVMContext &VMContext) const {
+  if (!CodeGenFunction::hasAggregateLLVMType(Ty)) {
+    // Treat an enum type as its underlying type.
+    if (const EnumType *EnumTy = Ty->getAs<EnumType>())
+      Ty = EnumTy->getDecl()->getIntegerType();
+
+    return (Ty->isPromotableIntegerType() ?
+            ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
+  }
+
+  // Ignore empty records.
+  if (isEmptyRecord(Context, Ty, true))
+    return ABIArgInfo::getIgnore();
+
+  // FIXME: This is kind of nasty... but there isn't much choice because the ARM
+  // backend doesn't support byval.
+  // FIXME: This doesn't handle alignment > 64 bits.
+  const llvm::Type* ElemTy;
+  unsigned SizeRegs;
+  if (Context.getTypeAlign(Ty) > 32) {
+    ElemTy = llvm::Type::getInt64Ty(VMContext);
+    SizeRegs = (Context.getTypeSize(Ty) + 63) / 64;
+  } else {
+    ElemTy = llvm::Type::getInt32Ty(VMContext);
+    SizeRegs = (Context.getTypeSize(Ty) + 31) / 32;
+  }
+  std::vector<const llvm::Type*> LLVMFields;
+  LLVMFields.push_back(llvm::ArrayType::get(ElemTy, SizeRegs));
+  const llvm::Type* STy = llvm::StructType::get(VMContext, LLVMFields, true);
+  return ABIArgInfo::getCoerce(STy);
+}
+
+static bool isIntegerLikeType(QualType Ty,
+                              ASTContext &Context,
+                              llvm::LLVMContext &VMContext) {
+  // APCS, C Language Calling Conventions, Non-Simple Return Values: A structure
+  // is called integer-like if its size is less than or equal to one word, and
+  // the offset of each of its addressable sub-fields is zero.
+
+  uint64_t Size = Context.getTypeSize(Ty);
+
+  // Check that the type fits in a word.
+  if (Size > 32)
+    return false;
+
+  // FIXME: Handle vector types!
+  if (Ty->isVectorType())
+    return false;
+
+  // Float types are never treated as "integer like".
+  if (Ty->isRealFloatingType())
+    return false;
+
+  // If this is a builtin or pointer type then it is ok.
+  if (Ty->getAs<BuiltinType>() || Ty->isPointerType())
+    return true;
+
+  // Small complex integer types are "integer like".
+  if (const ComplexType *CT = Ty->getAs<ComplexType>())
+    return isIntegerLikeType(CT->getElementType(), Context, VMContext);
+
+  // Single element and zero sized arrays should be allowed, by the definition
+  // above, but they are not.
+
+  // Otherwise, it must be a record type.
+  const RecordType *RT = Ty->getAs<RecordType>();
+  if (!RT) return false;
+
+  // Ignore records with flexible arrays.
+  const RecordDecl *RD = RT->getDecl();
+  if (RD->hasFlexibleArrayMember())
+    return false;
+
+  // Check that all sub-fields are at offset 0, and are themselves "integer
+  // like".
+  const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
+
+  bool HadField = false;
+  unsigned idx = 0;
+  for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
+       i != e; ++i, ++idx) {
+    const FieldDecl *FD = *i;
+
+    // Bit-fields are not addressable, we only need to verify they are "integer
+    // like". We still have to disallow a subsequent non-bitfield, for example:
+    //   struct { int : 0; int x }
+    // is non-integer like according to gcc.
+    if (FD->isBitField()) {
+      if (!RD->isUnion())
+        HadField = true;
+
+      if (!isIntegerLikeType(FD->getType(), Context, VMContext))
+        return false;
+
+      continue;
+    }
+
+    // Check if this field is at offset 0.
+    if (Layout.getFieldOffset(idx) != 0)
+      return false;
+
+    if (!isIntegerLikeType(FD->getType(), Context, VMContext))
+      return false;
+    
+    // Only allow at most one field in a structure. This doesn't match the
+    // wording above, but follows gcc in situations with a field following an
+    // empty structure.
+    if (!RD->isUnion()) {
+      if (HadField)
+        return false;
+
+      HadField = true;
+    }
+  }
+
+  return true;
+}
+
+ABIArgInfo ARMABIInfo::classifyReturnType(QualType RetTy,
+                                          ASTContext &Context,
+                                          llvm::LLVMContext &VMContext) const {
+  if (RetTy->isVoidType())
+    return ABIArgInfo::getIgnore();
+
+  if (!CodeGenFunction::hasAggregateLLVMType(RetTy)) {
+    // Treat an enum type as its underlying type.
+    if (const EnumType *EnumTy = RetTy->getAs<EnumType>())
+      RetTy = EnumTy->getDecl()->getIntegerType();
+
+    return (RetTy->isPromotableIntegerType() ?
+            ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
+  }
+
+  // Are we following APCS?
+  if (getABIKind() == APCS) {
+    if (isEmptyRecord(Context, RetTy, false))
+      return ABIArgInfo::getIgnore();
+
+    // Complex types are all returned as packed integers.
+    //
+    // FIXME: Consider using 2 x vector types if the back end handles them
+    // correctly.
+    if (RetTy->isAnyComplexType())
+      return ABIArgInfo::getCoerce(llvm::IntegerType::get(
+                                     VMContext, Context.getTypeSize(RetTy)));
+
+    // Integer like structures are returned in r0.
+    if (isIntegerLikeType(RetTy, Context, VMContext)) {
+      // Return in the smallest viable integer type.
+      uint64_t Size = Context.getTypeSize(RetTy);
+      if (Size <= 8)
+        return ABIArgInfo::getCoerce(llvm::Type::getInt8Ty(VMContext));
+      if (Size <= 16)
+        return ABIArgInfo::getCoerce(llvm::Type::getInt16Ty(VMContext));
+      return ABIArgInfo::getCoerce(llvm::Type::getInt32Ty(VMContext));
+    }
+
+    // Otherwise return in memory.
+    return ABIArgInfo::getIndirect(0);
+  }
+
+  // Otherwise this is an AAPCS variant.
+
+  if (isEmptyRecord(Context, RetTy, true))
+    return ABIArgInfo::getIgnore();
+
+  // Aggregates <= 4 bytes are returned in r0; other aggregates
+  // are returned indirectly.
+  uint64_t Size = Context.getTypeSize(RetTy);
+  if (Size <= 32) {
+    // Return in the smallest viable integer type.
+    if (Size <= 8)
+      return ABIArgInfo::getCoerce(llvm::Type::getInt8Ty(VMContext));
+    if (Size <= 16)
+      return ABIArgInfo::getCoerce(llvm::Type::getInt16Ty(VMContext));
+    return ABIArgInfo::getCoerce(llvm::Type::getInt32Ty(VMContext));
+  }
+
+  return ABIArgInfo::getIndirect(0);
+}
+
+llvm::Value *ARMABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
+                                      CodeGenFunction &CGF) const {
+  // FIXME: Need to handle alignment
+  const llvm::Type *BP = llvm::Type::getInt8PtrTy(CGF.getLLVMContext());
+  const llvm::Type *BPP = llvm::PointerType::getUnqual(BP);
+
+  CGBuilderTy &Builder = CGF.Builder;
+  llvm::Value *VAListAddrAsBPP = Builder.CreateBitCast(VAListAddr, BPP,
+                                                       "ap");
+  llvm::Value *Addr = Builder.CreateLoad(VAListAddrAsBPP, "ap.cur");
+  llvm::Type *PTy =
+    llvm::PointerType::getUnqual(CGF.ConvertType(Ty));
+  llvm::Value *AddrTyped = Builder.CreateBitCast(Addr, PTy);
+
+  uint64_t Offset =
+    llvm::RoundUpToAlignment(CGF.getContext().getTypeSize(Ty) / 8, 4);
+  llvm::Value *NextAddr =
+    Builder.CreateGEP(Addr, llvm::ConstantInt::get(
+                          llvm::Type::getInt32Ty(CGF.getLLVMContext()), Offset),
+                      "ap.next");
+  Builder.CreateStore(NextAddr, VAListAddrAsBPP);
+
+  return AddrTyped;
+}
+
+ABIArgInfo DefaultABIInfo::classifyReturnType(QualType RetTy,
+                                              ASTContext &Context,
+                                          llvm::LLVMContext &VMContext) const {
+  if (RetTy->isVoidType()) {
+    return ABIArgInfo::getIgnore();
+  } else if (CodeGenFunction::hasAggregateLLVMType(RetTy)) {
+    return ABIArgInfo::getIndirect(0);
+  } else {
+    // Treat an enum type as its underlying type.
+    if (const EnumType *EnumTy = RetTy->getAs<EnumType>())
+      RetTy = EnumTy->getDecl()->getIntegerType();
+
+    return (RetTy->isPromotableIntegerType() ?
+            ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
+  }
+}
+
+// SystemZ ABI Implementation
+
+namespace {
+
+class SystemZABIInfo : public ABIInfo {
+  bool isPromotableIntegerType(QualType Ty) const;
+
+  ABIArgInfo classifyReturnType(QualType RetTy, ASTContext &Context,
+                                llvm::LLVMContext &VMContext) const;
+
+  ABIArgInfo classifyArgumentType(QualType RetTy, ASTContext &Context,
+                                  llvm::LLVMContext &VMContext) const;
+
+  virtual void computeInfo(CGFunctionInfo &FI, ASTContext &Context,
+                          llvm::LLVMContext &VMContext) const {
+    FI.getReturnInfo() = classifyReturnType(FI.getReturnType(),
+                                            Context, VMContext);
+    for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end();
+         it != ie; ++it)
+      it->info = classifyArgumentType(it->type, Context, VMContext);
+  }
+
+  virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
+                                 CodeGenFunction &CGF) const;
+};
+
+class SystemZTargetCodeGenInfo : public TargetCodeGenInfo {
+public:
+  SystemZTargetCodeGenInfo():TargetCodeGenInfo(new SystemZABIInfo()) {}
+};
+
+}
+
+bool SystemZABIInfo::isPromotableIntegerType(QualType Ty) const {
+  // SystemZ ABI requires all 8, 16 and 32 bit quantities to be extended.
+  if (const BuiltinType *BT = Ty->getAs<BuiltinType>())
+    switch (BT->getKind()) {
+    case BuiltinType::Bool:
+    case BuiltinType::Char_S:
+    case BuiltinType::Char_U:
+    case BuiltinType::SChar:
+    case BuiltinType::UChar:
+    case BuiltinType::Short:
+    case BuiltinType::UShort:
+    case BuiltinType::Int:
+    case BuiltinType::UInt:
+      return true;
+    default:
+      return false;
+    }
+  return false;
+}
+
+llvm::Value *SystemZABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
+                                       CodeGenFunction &CGF) const {
+  // FIXME: Implement
+  return 0;
+}
+
+
+ABIArgInfo SystemZABIInfo::classifyReturnType(QualType RetTy,
+                                              ASTContext &Context,
+                                           llvm::LLVMContext &VMContext) const {
+  if (RetTy->isVoidType()) {
+    return ABIArgInfo::getIgnore();
+  } else if (CodeGenFunction::hasAggregateLLVMType(RetTy)) {
+    return ABIArgInfo::getIndirect(0);
+  } else {
+    return (isPromotableIntegerType(RetTy) ?
+            ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
+  }
+}
+
+ABIArgInfo SystemZABIInfo::classifyArgumentType(QualType Ty,
+                                                ASTContext &Context,
+                                           llvm::LLVMContext &VMContext) const {
+  if (CodeGenFunction::hasAggregateLLVMType(Ty)) {
+    return ABIArgInfo::getIndirect(0);
+  } else {
+    return (isPromotableIntegerType(Ty) ?
+            ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
+  }
+}
+
+// MSP430 ABI Implementation
+
+namespace {
+
+class MSP430TargetCodeGenInfo : public TargetCodeGenInfo {
+public:
+  MSP430TargetCodeGenInfo():TargetCodeGenInfo(new DefaultABIInfo()) {}
+  void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
+                           CodeGen::CodeGenModule &M) const;
+};
+
+}
+
+void MSP430TargetCodeGenInfo::SetTargetAttributes(const Decl *D,
+                                                  llvm::GlobalValue *GV,
+                                             CodeGen::CodeGenModule &M) const {
+  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+    if (const MSP430InterruptAttr *attr = FD->getAttr<MSP430InterruptAttr>()) {
+      // Handle 'interrupt' attribute:
+      llvm::Function *F = cast<llvm::Function>(GV);
+
+      // Step 1: Set ISR calling convention.
+      F->setCallingConv(llvm::CallingConv::MSP430_INTR);
+
+      // Step 2: Add attributes goodness.
+      F->addFnAttr(llvm::Attribute::NoInline);
+
+      // Step 3: Emit ISR vector alias.
+      unsigned Num = attr->getNumber() + 0xffe0;
+      new llvm::GlobalAlias(GV->getType(), llvm::Function::ExternalLinkage,
+                            "vector_" +
+                            llvm::LowercaseString(llvm::utohexstr(Num)),
+                            GV, &M.getModule());
+    }
+  }
+}
+
+const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() const {
+  if (TheTargetCodeGenInfo)
+    return *TheTargetCodeGenInfo;
+
+  // For now we just cache the TargetCodeGenInfo in CodeGenModule and don't
+  // free it.
+
+  const llvm::Triple &Triple(getContext().Target.getTriple());
+  switch (Triple.getArch()) {
+  default:
+    return *(TheTargetCodeGenInfo = new DefaultTargetCodeGenInfo);
+
+  case llvm::Triple::arm:
+  case llvm::Triple::thumb:
+    // FIXME: We want to know the float calling convention as well.
+    if (strcmp(getContext().Target.getABI(), "apcs-gnu") == 0)
+      return *(TheTargetCodeGenInfo =
+               new ARMTargetCodeGenInfo(ARMABIInfo::APCS));
+
+    return *(TheTargetCodeGenInfo =
+             new ARMTargetCodeGenInfo(ARMABIInfo::AAPCS));
+
+  case llvm::Triple::pic16:
+    return *(TheTargetCodeGenInfo = new PIC16TargetCodeGenInfo());
+
+  case llvm::Triple::ppc:
+    return *(TheTargetCodeGenInfo = new PPC32TargetCodeGenInfo());
+
+  case llvm::Triple::systemz:
+    return *(TheTargetCodeGenInfo = new SystemZTargetCodeGenInfo());
+
+  case llvm::Triple::msp430:
+    return *(TheTargetCodeGenInfo = new MSP430TargetCodeGenInfo());
+
+  case llvm::Triple::x86:
+    switch (Triple.getOS()) {
+    case llvm::Triple::Darwin:
+      return *(TheTargetCodeGenInfo =
+               new X86_32TargetCodeGenInfo(Context, true, true));
+    case llvm::Triple::Cygwin:
+    case llvm::Triple::MinGW32:
+    case llvm::Triple::MinGW64:
+    case llvm::Triple::AuroraUX:
+    case llvm::Triple::DragonFly:
+    case llvm::Triple::FreeBSD:
+    case llvm::Triple::OpenBSD:
+      return *(TheTargetCodeGenInfo =
+               new X86_32TargetCodeGenInfo(Context, false, true));
+
+    default:
+      return *(TheTargetCodeGenInfo =
+               new X86_32TargetCodeGenInfo(Context, false, false));
+    }
+
+  case llvm::Triple::x86_64:
+    return *(TheTargetCodeGenInfo = new X86_64TargetCodeGenInfo());
+  }
+}
diff --git a/lib/CodeGen/TargetInfo.h b/lib/CodeGen/TargetInfo.h
new file mode 100644
index 0000000..f0a7824
--- /dev/null
+++ b/lib/CodeGen/TargetInfo.h
@@ -0,0 +1,98 @@
+//===---- TargetInfo.h - Encapsulate target details -------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// These classes wrap the information about a call or function
+// definition used to handle ABI compliancy.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_CODEGEN_TARGETINFO_H
+#define CLANG_CODEGEN_TARGETINFO_H
+
+namespace llvm {
+  class GlobalValue;
+  class Value;
+}
+
+namespace clang {
+  class ABIInfo;
+  class Decl;
+
+  namespace CodeGen {
+    class CodeGenModule;
+    class CodeGenFunction;
+  }
+
+  /// TargetCodeGenInfo - This class organizes various target-specific
+  /// codegeneration issues, like target-specific attributes, builtins and so
+  /// on.
+  class TargetCodeGenInfo {
+    ABIInfo *Info;
+  public:
+    // WARNING: Acquires the ownership of ABIInfo.
+    TargetCodeGenInfo(ABIInfo *info = 0):Info(info) { }
+    virtual ~TargetCodeGenInfo();
+
+    /// getABIInfo() - Returns ABI info helper for the target.
+    const ABIInfo& getABIInfo() const { return *Info; }
+
+    /// SetTargetAttributes - Provides a convenient hook to handle extra
+    /// target-specific attributes for the given global.
+    virtual void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
+                                     CodeGen::CodeGenModule &M) const { }
+
+    /// Controls whether __builtin_extend_pointer should sign-extend
+    /// pointers to uint64_t or zero-extend them (the default).  Has
+    /// no effect for targets:
+    ///   - that have 64-bit pointers, or
+    ///   - that cannot address through registers larger than pointers, or
+    ///   - that implicitly ignore/truncate the top bits when addressing
+    ///     through such registers.
+    virtual bool extendPointerWithSExt() const { return false; }
+
+    /// Determines the DWARF register number for the stack pointer, for
+    /// exception-handling purposes.  Implements __builtin_dwarf_sp_column.
+    ///
+    /// Returns -1 if the operation is unsupported by this target.
+    virtual int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const {
+      return -1;
+    }
+
+    /// Initializes the given DWARF EH register-size table, a char*.
+    /// Implements __builtin_init_dwarf_reg_size_table.
+    ///
+    /// Returns true if the operation is unsupported by this target.
+    virtual bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
+                                         llvm::Value *Address) const {
+      return true;
+    }
+
+    /// Performs the code-generation required to convert a return
+    /// address as stored by the system into the actual address of the
+    /// next instruction that will be executed.
+    ///
+    /// Used by __builtin_extract_return_addr().
+    virtual llvm::Value *decodeReturnAddress(CodeGen::CodeGenFunction &CGF,
+                                             llvm::Value *Address) const {
+      return Address;
+    }
+
+    /// Performs the code-generation required to convert the address
+    /// of an instruction into a return address suitable for storage
+    /// by the system in a return slot.
+    ///
+    /// Used by __builtin_frob_return_addr().
+    virtual llvm::Value *encodeReturnAddress(CodeGen::CodeGenFunction &CGF,
+                                             llvm::Value *Address) const {
+      return Address;
+    }
+  };
+}
+
+#endif // CLANG_CODEGEN_TARGETINFO_H
diff --git a/lib/Driver/Action.cpp b/lib/Driver/Action.cpp
new file mode 100644
index 0000000..b9a3306
--- /dev/null
+++ b/lib/Driver/Action.cpp
@@ -0,0 +1,81 @@
+//===--- Action.cpp - Abstract compilation steps ------------------------*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Driver/Action.h"
+
+#include <cassert>
+using namespace clang::driver;
+
+Action::~Action() {
+  if (OwnsInputs) {
+    for (iterator it = begin(), ie = end(); it != ie; ++it)
+      delete *it;
+  }
+}
+
+const char *Action::getClassName(ActionClass AC) {
+  switch (AC) {
+  case InputClass: return "input";
+  case BindArchClass: return "bind-arch";
+  case PreprocessJobClass: return "preprocessor";
+  case PrecompileJobClass: return "precompiler";
+  case AnalyzeJobClass: return "analyzer";
+  case CompileJobClass: return "compiler";
+  case AssembleJobClass: return "assembler";
+  case LinkJobClass: return "linker";
+  case LipoJobClass: return "lipo";
+  }
+
+  assert(0 && "invalid class");
+  return 0;
+}
+
+InputAction::InputAction(const Arg &_Input, types::ID _Type)
+  : Action(InputClass, _Type), Input(_Input) {
+}
+
+BindArchAction::BindArchAction(Action *Input, const char *_ArchName)
+  : Action(BindArchClass, Input, Input->getType()), ArchName(_ArchName) {
+}
+
+JobAction::JobAction(ActionClass Kind, Action *Input, types::ID Type)
+  : Action(Kind, Input, Type) {
+}
+
+JobAction::JobAction(ActionClass Kind, const ActionList &Inputs, types::ID Type)
+  : Action(Kind, Inputs, Type) {
+}
+
+PreprocessJobAction::PreprocessJobAction(Action *Input, types::ID OutputType)
+  : JobAction(PreprocessJobClass, Input, OutputType) {
+}
+
+PrecompileJobAction::PrecompileJobAction(Action *Input, types::ID OutputType)
+  : JobAction(PrecompileJobClass, Input, OutputType) {
+}
+
+AnalyzeJobAction::AnalyzeJobAction(Action *Input, types::ID OutputType)
+  : JobAction(AnalyzeJobClass, Input, OutputType) {
+}
+
+CompileJobAction::CompileJobAction(Action *Input, types::ID OutputType)
+  : JobAction(CompileJobClass, Input, OutputType) {
+}
+
+AssembleJobAction::AssembleJobAction(Action *Input, types::ID OutputType)
+  : JobAction(AssembleJobClass, Input, OutputType) {
+}
+
+LinkJobAction::LinkJobAction(ActionList &Inputs, types::ID Type)
+  : JobAction(LinkJobClass, Inputs, Type) {
+}
+
+LipoJobAction::LipoJobAction(ActionList &Inputs, types::ID Type)
+  : JobAction(LipoJobClass, Inputs, Type) {
+}
diff --git a/lib/Driver/Arg.cpp b/lib/Driver/Arg.cpp
new file mode 100644
index 0000000..7e61a1d
--- /dev/null
+++ b/lib/Driver/Arg.cpp
@@ -0,0 +1,190 @@
+//===--- Arg.cpp - Argument Implementations -----------------------------*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Driver/Arg.h"
+#include "clang/Driver/ArgList.h"
+#include "clang/Driver/Option.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace clang::driver;
+
+Arg::Arg(ArgClass _Kind, const Option *_Opt, unsigned _Index,
+         const Arg *_BaseArg)
+  : Kind(_Kind), Opt(_Opt), BaseArg(_BaseArg), Index(_Index), Claimed(false) {
+}
+
+Arg::~Arg() { }
+
+void Arg::dump() const {
+  llvm::errs() << "<";
+  switch (Kind) {
+  default:
+    assert(0 && "Invalid kind");
+#define P(N) case N: llvm::errs() << #N; break
+    P(FlagClass);
+    P(PositionalClass);
+    P(JoinedClass);
+    P(SeparateClass);
+    P(CommaJoinedClass);
+    P(JoinedAndSeparateClass);
+#undef P
+  }
+
+  llvm::errs() << " Opt:";
+  Opt->dump();
+
+  llvm::errs() << " Index:" << Index;
+
+  if (isa<CommaJoinedArg>(this) || isa<SeparateArg>(this))
+    llvm::errs() << " NumValues:" << getNumValues();
+
+  llvm::errs() << ">\n";
+}
+
+std::string Arg::getAsString(const ArgList &Args) const {
+  std::string Res;
+  llvm::raw_string_ostream OS(Res);
+
+  ArgStringList ASL;
+  render(Args, ASL);
+  for (ArgStringList::iterator
+         it = ASL.begin(), ie = ASL.end(); it != ie; ++it) {
+    if (it != ASL.begin())
+      OS << ' ';
+    OS << *it;
+  }
+
+  return OS.str();
+}
+
+void Arg::renderAsInput(const ArgList &Args, ArgStringList &Output) const {
+  if (!getOption().hasNoOptAsInput()) {
+    render(Args, Output);
+    return;
+  }
+
+  for (unsigned i = 0, e = getNumValues(); i != e; ++i)
+    Output.push_back(getValue(Args, i));
+}
+
+FlagArg::FlagArg(const Option *Opt, unsigned Index, const Arg *BaseArg)
+  : Arg(FlagClass, Opt, Index, BaseArg) {
+}
+
+void FlagArg::render(const ArgList &Args, ArgStringList &Output) const {
+  Output.push_back(Args.getArgString(getIndex()));
+}
+
+const char *FlagArg::getValue(const ArgList &Args, unsigned N) const {
+  assert(0 && "Invalid index.");
+  return 0;
+}
+
+PositionalArg::PositionalArg(const Option *Opt, unsigned Index,
+                             const Arg *BaseArg)
+  : Arg(PositionalClass, Opt, Index, BaseArg) {
+}
+
+void PositionalArg::render(const ArgList &Args, ArgStringList &Output) const {
+  Output.push_back(Args.getArgString(getIndex()));
+}
+
+const char *PositionalArg::getValue(const ArgList &Args, unsigned N) const {
+  assert(N < getNumValues() && "Invalid index.");
+  return Args.getArgString(getIndex());
+}
+
+JoinedArg::JoinedArg(const Option *Opt, unsigned Index, const Arg *BaseArg)
+  : Arg(JoinedClass, Opt, Index, BaseArg) {
+}
+
+void JoinedArg::render(const ArgList &Args, ArgStringList &Output) const {
+  if (getOption().hasForceSeparateRender()) {
+    Output.push_back(getOption().getName());
+    Output.push_back(getValue(Args, 0));
+  } else {
+    Output.push_back(Args.getArgString(getIndex()));
+  }
+}
+
+const char *JoinedArg::getValue(const ArgList &Args, unsigned N) const {
+  assert(N < getNumValues() && "Invalid index.");
+  // FIXME: Avoid strlen.
+  return Args.getArgString(getIndex()) + strlen(getOption().getName());
+}
+
+CommaJoinedArg::CommaJoinedArg(const Option *Opt, unsigned Index,
+                               const char *Str, const Arg *BaseArg)
+  : Arg(CommaJoinedClass, Opt, Index, BaseArg) {
+  const char *Prev = Str;
+  for (;; ++Str) {
+    char c = *Str;
+
+    if (!c) {
+      if (Prev != Str)
+        Values.push_back(std::string(Prev, Str));
+      break;
+    } else if (c == ',') {
+      if (Prev != Str)
+        Values.push_back(std::string(Prev, Str));
+      Prev = Str + 1;
+    }
+  }
+}
+
+void CommaJoinedArg::render(const ArgList &Args, ArgStringList &Output) const {
+  Output.push_back(Args.getArgString(getIndex()));
+}
+
+const char *CommaJoinedArg::getValue(const ArgList &Args, unsigned N) const {
+  assert(N < getNumValues() && "Invalid index.");
+  return Values[N].c_str();
+}
+
+SeparateArg::SeparateArg(const Option *Opt, unsigned Index, unsigned _NumValues,
+                         const Arg *BaseArg)
+  : Arg(SeparateClass, Opt, Index, BaseArg), NumValues(_NumValues) {
+}
+
+void SeparateArg::render(const ArgList &Args, ArgStringList &Output) const {
+  if (getOption().hasForceJoinedRender()) {
+    assert(getNumValues() == 1 && "Cannot force joined render with > 1 args.");
+    Output.push_back(Args.MakeArgString(llvm::StringRef(getOption().getName()) +
+                                        getValue(Args, 0)));
+  } else {
+    Output.push_back(Args.getArgString(getIndex()));
+    for (unsigned i = 0; i < NumValues; ++i)
+      Output.push_back(getValue(Args, i));
+  }
+}
+
+const char *SeparateArg::getValue(const ArgList &Args, unsigned N) const {
+  assert(N < getNumValues() && "Invalid index.");
+  return Args.getArgString(getIndex() + 1 + N);
+}
+
+JoinedAndSeparateArg::JoinedAndSeparateArg(const Option *Opt, unsigned Index,
+                                           const Arg *BaseArg)
+  : Arg(JoinedAndSeparateClass, Opt, Index, BaseArg) {
+}
+
+void JoinedAndSeparateArg::render(const ArgList &Args,
+                                  ArgStringList &Output) const {
+  Output.push_back(Args.getArgString(getIndex()));
+  Output.push_back(Args.getArgString(getIndex() + 1));
+}
+
+const char *JoinedAndSeparateArg::getValue(const ArgList &Args,
+                                           unsigned N) const {
+  assert(N < getNumValues() && "Invalid index.");
+  if (N == 0)
+    return Args.getArgString(getIndex()) + strlen(getOption().getName());
+  return Args.getArgString(getIndex() + 1);
+}
diff --git a/lib/Driver/ArgList.cpp b/lib/Driver/ArgList.cpp
new file mode 100644
index 0000000..95805b0
--- /dev/null
+++ b/lib/Driver/ArgList.cpp
@@ -0,0 +1,247 @@
+//===--- ArgList.cpp - Argument List Management -------------------------*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Driver/ArgList.h"
+#include "clang/Driver/Arg.h"
+#include "clang/Driver/Option.h"
+
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace clang::driver;
+
+void arg_iterator::SkipToNextArg() {
+  for (; Current != Args.end(); ++Current) {
+    // Done if there are no filters.
+    if (!Id0.isValid())
+      break;
+
+    // Otherwise require a match.
+    const Option &O = (*Current)->getOption();
+    if (O.matches(Id0) ||
+        (Id1.isValid() && O.matches(Id1)) ||
+        (Id2.isValid() && O.matches(Id2)))
+      break;
+  }
+}
+
+//
+
+ArgList::ArgList(arglist_type &_Args) : Args(_Args) {
+}
+
+ArgList::~ArgList() {
+}
+
+void ArgList::append(Arg *A) {
+  Args.push_back(A);
+}
+
+Arg *ArgList::getLastArgNoClaim(OptSpecifier Id) const {
+  // FIXME: Make search efficient?
+  for (const_reverse_iterator it = rbegin(), ie = rend(); it != ie; ++it)
+    if ((*it)->getOption().matches(Id))
+      return *it;
+  return 0;
+}
+
+Arg *ArgList::getLastArg(OptSpecifier Id) const {
+  Arg *A = getLastArgNoClaim(Id);
+  if (A)
+    A->claim();
+  return A;
+}
+
+Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1) const {
+  Arg *Res, *A0 = getLastArgNoClaim(Id0), *A1 = getLastArgNoClaim(Id1);
+
+  if (A0 && A1)
+    Res = A0->getIndex() > A1->getIndex() ? A0 : A1;
+  else
+    Res = A0 ? A0 : A1;
+
+  if (Res)
+    Res->claim();
+
+  return Res;
+}
+
+Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1,
+                         OptSpecifier Id2) const {
+  Arg *Res = 0;
+  Arg *A0 = getLastArgNoClaim(Id0);
+  Arg *A1 = getLastArgNoClaim(Id1);
+  Arg *A2 = getLastArgNoClaim(Id2);
+
+  int A0Idx = A0 ? (int) A0->getIndex() : -1;
+  int A1Idx = A1 ? (int) A1->getIndex() : -1;
+  int A2Idx = A2 ? (int) A2->getIndex() : -1;
+
+  if (A0Idx > A1Idx) {
+    if (A0Idx > A2Idx)
+      Res = A0;
+    else if (A2Idx != -1)
+      Res = A2;
+  } else {
+    if (A1Idx > A2Idx)
+      Res = A1;
+    else if (A2Idx != -1)
+      Res = A2;
+  }
+
+  if (Res)
+    Res->claim();
+
+  return Res;
+}
+
+bool ArgList::hasFlag(OptSpecifier Pos, OptSpecifier Neg, bool Default) const {
+  if (Arg *A = getLastArg(Pos, Neg))
+    return A->getOption().matches(Pos);
+  return Default;
+}
+
+void ArgList::AddLastArg(ArgStringList &Output, OptSpecifier Id) const {
+  if (Arg *A = getLastArg(Id)) {
+    A->claim();
+    A->render(*this, Output);
+  }
+}
+
+void ArgList::AddAllArgs(ArgStringList &Output, OptSpecifier Id0,
+                         OptSpecifier Id1, OptSpecifier Id2) const {
+  for (arg_iterator it = filtered_begin(Id0, Id1, Id2),
+         ie = filtered_end(); it != ie; ++it) {
+    it->claim();
+    it->render(*this, Output);
+  }
+}
+
+void ArgList::AddAllArgValues(ArgStringList &Output, OptSpecifier Id0,
+                              OptSpecifier Id1, OptSpecifier Id2) const {
+  for (arg_iterator it = filtered_begin(Id0, Id1, Id2),
+         ie = filtered_end(); it != ie; ++it) {
+    it->claim();
+    for (unsigned i = 0, e = it->getNumValues(); i != e; ++i)
+      Output.push_back(it->getValue(*this, i));
+  }
+}
+
+void ArgList::AddAllArgsTranslated(ArgStringList &Output, OptSpecifier Id0,
+                                   const char *Translation,
+                                   bool Joined) const {
+  for (arg_iterator it = filtered_begin(Id0),
+         ie = filtered_end(); it != ie; ++it) {
+    it->claim();
+
+    if (Joined) {
+      Output.push_back(MakeArgString(llvm::StringRef(Translation) +
+                                     it->getValue(*this, 0)));
+    } else {
+      Output.push_back(Translation);
+      Output.push_back(it->getValue(*this, 0));
+    }
+  }
+}
+
+void ArgList::ClaimAllArgs(OptSpecifier Id0) const {
+  for (arg_iterator it = filtered_begin(Id0),
+         ie = filtered_end(); it != ie; ++it)
+      it->claim();
+}
+
+const char *ArgList::MakeArgString(const llvm::Twine &T) const {
+  llvm::SmallString<256> Str;
+  T.toVector(Str);
+  return MakeArgString(Str.str());
+}
+
+//
+
+InputArgList::InputArgList(const char **ArgBegin, const char **ArgEnd)
+  : ArgList(ActualArgs), NumInputArgStrings(ArgEnd - ArgBegin) {
+  ArgStrings.append(ArgBegin, ArgEnd);
+}
+
+InputArgList::~InputArgList() {
+  // An InputArgList always owns its arguments.
+  for (iterator it = begin(), ie = end(); it != ie; ++it)
+    delete *it;
+}
+
+unsigned InputArgList::MakeIndex(llvm::StringRef String0) const {
+  unsigned Index = ArgStrings.size();
+
+  // Tuck away so we have a reliable const char *.
+  SynthesizedStrings.push_back(String0);
+  ArgStrings.push_back(SynthesizedStrings.back().c_str());
+
+  return Index;
+}
+
+unsigned InputArgList::MakeIndex(llvm::StringRef String0,
+                                 llvm::StringRef String1) const {
+  unsigned Index0 = MakeIndex(String0);
+  unsigned Index1 = MakeIndex(String1);
+  assert(Index0 + 1 == Index1 && "Unexpected non-consecutive indices!");
+  (void) Index1;
+  return Index0;
+}
+
+const char *InputArgList::MakeArgString(llvm::StringRef Str) const {
+  return getArgString(MakeIndex(Str));
+}
+
+//
+
+DerivedArgList::DerivedArgList(InputArgList &_BaseArgs, bool _OnlyProxy)
+  : ArgList(_OnlyProxy ? _BaseArgs.getArgs() : ActualArgs),
+    BaseArgs(_BaseArgs), OnlyProxy(_OnlyProxy) {
+}
+
+DerivedArgList::~DerivedArgList() {
+  // We only own the arguments we explicitly synthesized.
+  for (iterator it = SynthesizedArgs.begin(), ie = SynthesizedArgs.end();
+       it != ie; ++it)
+    delete *it;
+}
+
+const char *DerivedArgList::MakeArgString(llvm::StringRef Str) const {
+  return BaseArgs.MakeArgString(Str);
+}
+
+Arg *DerivedArgList::MakeFlagArg(const Arg *BaseArg, const Option *Opt) const {
+  Arg *A = new FlagArg(Opt, BaseArgs.MakeIndex(Opt->getName()), BaseArg);
+  SynthesizedArgs.push_back(A);
+  return A;
+}
+
+Arg *DerivedArgList::MakePositionalArg(const Arg *BaseArg, const Option *Opt,
+                                       llvm::StringRef Value) const {
+  Arg *A = new PositionalArg(Opt, BaseArgs.MakeIndex(Value), BaseArg);
+  SynthesizedArgs.push_back(A);
+  return A;
+}
+
+Arg *DerivedArgList::MakeSeparateArg(const Arg *BaseArg, const Option *Opt,
+                                     llvm::StringRef Value) const {
+  Arg *A = new SeparateArg(Opt, BaseArgs.MakeIndex(Opt->getName(), Value), 1,
+                           BaseArg);
+  SynthesizedArgs.push_back(A);
+  return A;
+}
+
+Arg *DerivedArgList::MakeJoinedArg(const Arg *BaseArg, const Option *Opt,
+                                   llvm::StringRef Value) const {
+  Arg *A = new JoinedArg(Opt, BaseArgs.MakeIndex(Opt->getName() + Value.str()),
+                         BaseArg);
+  SynthesizedArgs.push_back(A);
+  return A;
+}
diff --git a/lib/Driver/CC1Options.cpp b/lib/Driver/CC1Options.cpp
new file mode 100644
index 0000000..0e98bb9
--- /dev/null
+++ b/lib/Driver/CC1Options.cpp
@@ -0,0 +1,38 @@
+//===--- CC1Options.cpp - Clang CC1 Options Table -----------------------*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Driver/CC1Options.h"
+#include "clang/Driver/Option.h"
+#include "clang/Driver/OptTable.h"
+using namespace clang;
+using namespace clang::driver;
+using namespace clang::driver::options;
+using namespace clang::driver::cc1options;
+
+static const OptTable::Info CC1InfoTable[] = {
+#define OPTION(NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \
+               HELPTEXT, METAVAR)   \
+  { NAME, HELPTEXT, METAVAR, Option::KIND##Class, FLAGS, PARAM, \
+    OPT_##GROUP, OPT_##ALIAS },
+#include "clang/Driver/CC1Options.inc"
+};
+
+namespace {
+
+class CC1OptTable : public OptTable {
+public:
+  CC1OptTable()
+    : OptTable(CC1InfoTable, sizeof(CC1InfoTable) / sizeof(CC1InfoTable[0])) {}
+};
+
+}
+
+OptTable *clang::driver::createCC1OptTable() {
+  return new CC1OptTable();
+}
diff --git a/lib/Driver/CMakeLists.txt b/lib/Driver/CMakeLists.txt
new file mode 100644
index 0000000..7efcd8a
--- /dev/null
+++ b/lib/Driver/CMakeLists.txt
@@ -0,0 +1,23 @@
+set(LLVM_NO_RTTI 1)
+
+add_clang_library(clangDriver
+  Action.cpp
+  Arg.cpp
+  ArgList.cpp
+  CC1Options.cpp
+  Compilation.cpp
+  Driver.cpp
+  DriverOptions.cpp
+  HostInfo.cpp
+  Job.cpp
+  Option.cpp
+  OptTable.cpp
+  Phases.cpp
+  Tool.cpp
+  ToolChain.cpp
+  ToolChains.cpp
+  Tools.cpp
+  Types.cpp
+  )
+
+add_dependencies(clangDriver ClangDiagnosticDriver ClangDriverOptions ClangCC1Options)
diff --git a/lib/Driver/Compilation.cpp b/lib/Driver/Compilation.cpp
new file mode 100644
index 0000000..227f79a
--- /dev/null
+++ b/lib/Driver/Compilation.cpp
@@ -0,0 +1,204 @@
+//===--- Compilation.cpp - Compilation Task Implementation --------------*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Driver/Compilation.h"
+
+#include "clang/Driver/Action.h"
+#include "clang/Driver/ArgList.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/DriverDiagnostic.h"
+#include "clang/Driver/Options.h"
+#include "clang/Driver/ToolChain.h"
+
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/System/Program.h"
+#include <sys/stat.h>
+#include <errno.h>
+using namespace clang::driver;
+
+Compilation::Compilation(const Driver &D,
+                         const ToolChain &_DefaultToolChain,
+                         InputArgList *_Args)
+  : TheDriver(D), DefaultToolChain(_DefaultToolChain), Args(_Args) {
+}
+
+Compilation::~Compilation() {
+  delete Args;
+
+  // Free any derived arg lists.
+  for (llvm::DenseMap<std::pair<const ToolChain*, const char*>,
+                      DerivedArgList*>::iterator it = TCArgs.begin(),
+         ie = TCArgs.end(); it != ie; ++it)
+    delete it->second;
+
+  // Free the actions, if built.
+  for (ActionList::iterator it = Actions.begin(), ie = Actions.end();
+       it != ie; ++it)
+    delete *it;
+}
+
+const DerivedArgList &Compilation::getArgsForToolChain(const ToolChain *TC,
+                                                       const char *BoundArch) {
+  if (!TC)
+    TC = &DefaultToolChain;
+
+  DerivedArgList *&Entry = TCArgs[std::make_pair(TC, BoundArch)];
+  if (!Entry)
+    Entry = TC->TranslateArgs(*Args, BoundArch);
+
+  return *Entry;
+}
+
+void Compilation::PrintJob(llvm::raw_ostream &OS, const Job &J,
+                           const char *Terminator, bool Quote) const {
+  if (const Command *C = dyn_cast<Command>(&J)) {
+    OS << " \"" << C->getExecutable() << '"';
+    for (ArgStringList::const_iterator it = C->getArguments().begin(),
+           ie = C->getArguments().end(); it != ie; ++it) {
+      OS << ' ';
+      if (!Quote) {
+        OS << *it;
+        continue;
+      }
+
+      // Quote the argument and escape shell special characters; this isn't
+      // really complete but is good enough.
+      OS << '"';
+      for (const char *s = *it; *s; ++s) {
+        if (*s == '"' || *s == '\\' || *s == '$')
+          OS << '\\';
+        OS << *s;
+      }
+      OS << '"';
+    }
+    OS << Terminator;
+  } else if (const PipedJob *PJ = dyn_cast<PipedJob>(&J)) {
+    for (PipedJob::const_iterator
+           it = PJ->begin(), ie = PJ->end(); it != ie; ++it)
+      PrintJob(OS, **it, (it + 1 != PJ->end()) ? " |\n" : "\n", Quote);
+  } else {
+    const JobList *Jobs = cast<JobList>(&J);
+    for (JobList::const_iterator
+           it = Jobs->begin(), ie = Jobs->end(); it != ie; ++it)
+      PrintJob(OS, **it, Terminator, Quote);
+  }
+}
+
+bool Compilation::CleanupFileList(const ArgStringList &Files,
+                                  bool IssueErrors) const {
+  bool Success = true;
+
+  for (ArgStringList::const_iterator
+         it = Files.begin(), ie = Files.end(); it != ie; ++it) {
+
+    llvm::sys::Path P(*it);
+    std::string Error;
+
+    if (!P.isRegularFile()) {
+      // If we have a special file in our list, i.e. /dev/null
+      //  then don't call eraseFromDisk() and just continue.
+      continue;
+    }
+
+    if (P.eraseFromDisk(false, &Error)) {
+      // Failure is only failure if the file doesn't exist. There is a
+      // race condition here due to the limited interface of
+      // llvm::sys::Path, we want to know if the removal gave E_NOENT.
+
+      // FIXME: Grumble, P.exists() is broken. PR3837.
+      struct stat buf;
+      if (::stat(P.c_str(), &buf) == 0
+          || errno != ENOENT) {
+        if (IssueErrors)
+          getDriver().Diag(clang::diag::err_drv_unable_to_remove_file)
+            << Error;
+        Success = false;
+      }
+    }
+  }
+
+  return Success;
+}
+
+int Compilation::ExecuteCommand(const Command &C,
+                                const Command *&FailingCommand) const {
+  llvm::sys::Path Prog(C.getExecutable());
+  const char **Argv = new const char*[C.getArguments().size() + 2];
+  Argv[0] = C.getExecutable();
+  std::copy(C.getArguments().begin(), C.getArguments().end(), Argv+1);
+  Argv[C.getArguments().size() + 1] = 0;
+
+  if (getDriver().CCCEcho || getDriver().CCPrintOptions ||
+      getArgs().hasArg(options::OPT_v)) {
+    llvm::raw_ostream *OS = &llvm::errs();
+
+    // Follow gcc implementation of CC_PRINT_OPTIONS; we could also cache the
+    // output stream.
+    if (getDriver().CCPrintOptions && getDriver().CCPrintOptionsFilename) {
+      std::string Error;
+      OS = new llvm::raw_fd_ostream(getDriver().CCPrintOptionsFilename,
+                                    Error,
+                                    llvm::raw_fd_ostream::F_Append);
+      if (!Error.empty()) {
+        getDriver().Diag(clang::diag::err_drv_cc_print_options_failure)
+          << Error;
+        FailingCommand = &C;
+        delete OS;
+        return 1;
+      }
+    }
+
+    if (getDriver().CCPrintOptions)
+      *OS << "[Logging clang options]";
+
+    PrintJob(*OS, C, "\n", /*Quote=*/getDriver().CCPrintOptions);
+
+    if (OS != &llvm::errs())
+      delete OS;
+  }
+
+  std::string Error;
+  int Res =
+    llvm::sys::Program::ExecuteAndWait(Prog, Argv,
+                                       /*env*/0, /*redirects*/0,
+                                       /*secondsToWait*/0, /*memoryLimit*/0,
+                                       &Error);
+  if (!Error.empty()) {
+    assert(Res && "Error string set with 0 result code!");
+    getDriver().Diag(clang::diag::err_drv_command_failure) << Error;
+  }
+
+  if (Res)
+    FailingCommand = &C;
+
+  delete[] Argv;
+  return Res;
+}
+
+int Compilation::ExecuteJob(const Job &J,
+                            const Command *&FailingCommand) const {
+  if (const Command *C = dyn_cast<Command>(&J)) {
+    return ExecuteCommand(*C, FailingCommand);
+  } else if (const PipedJob *PJ = dyn_cast<PipedJob>(&J)) {
+    // Piped commands with a single job are easy.
+    if (PJ->size() == 1)
+      return ExecuteCommand(**PJ->begin(), FailingCommand);
+
+    FailingCommand = *PJ->begin();
+    getDriver().Diag(clang::diag::err_drv_unsupported_opt) << "-pipe";
+    return 1;
+  } else {
+    const JobList *Jobs = cast<JobList>(&J);
+    for (JobList::const_iterator
+           it = Jobs->begin(), ie = Jobs->end(); it != ie; ++it)
+      if (int Res = ExecuteJob(**it, FailingCommand))
+        return Res;
+    return 0;
+  }
+}
diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp
new file mode 100644
index 0000000..7371a93
--- /dev/null
+++ b/lib/Driver/Driver.cpp
@@ -0,0 +1,1266 @@
+//===--- Driver.cpp - Clang GCC Compatible Driver -----------------------*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Driver/Driver.h"
+
+#include "clang/Driver/Action.h"
+#include "clang/Driver/Arg.h"
+#include "clang/Driver/ArgList.h"
+#include "clang/Driver/Compilation.h"
+#include "clang/Driver/DriverDiagnostic.h"
+#include "clang/Driver/HostInfo.h"
+#include "clang/Driver/Job.h"
+#include "clang/Driver/OptTable.h"
+#include "clang/Driver/Option.h"
+#include "clang/Driver/Options.h"
+#include "clang/Driver/Tool.h"
+#include "clang/Driver/ToolChain.h"
+#include "clang/Driver/Types.h"
+
+#include "clang/Basic/Version.h"
+
+#include "llvm/ADT/StringSet.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/Support/PrettyStackTrace.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/System/Path.h"
+#include "llvm/System/Program.h"
+
+#include "InputInfo.h"
+
+#include <map>
+
+using namespace clang::driver;
+using namespace clang;
+
+// Used to set values for "production" clang, for releases.
+// #define USE_PRODUCTION_CLANG
+
+Driver::Driver(llvm::StringRef _Name, llvm::StringRef _Dir,
+               llvm::StringRef _DefaultHostTriple,
+               llvm::StringRef _DefaultImageName,
+               bool IsProduction, bool CXXIsProduction,
+               Diagnostic &_Diags)
+  : Opts(createDriverOptTable()), Diags(_Diags),
+    Name(_Name), Dir(_Dir), DefaultHostTriple(_DefaultHostTriple),
+    DefaultImageName(_DefaultImageName),
+    DriverTitle("clang \"gcc-compatible\" driver"),
+    Host(0),
+    CCCGenericGCCName("gcc"), CCPrintOptionsFilename(0), CCCIsCXX(false),
+    CCCEcho(false), CCCPrintBindings(false), CCPrintOptions(false),
+    CheckInputsExist(true), CCCUseClang(true), CCCUseClangCXX(true),
+    CCCUseClangCPP(true), CCCUsePCH(true), SuppressMissingInputWarning(false) {
+  if (IsProduction) {
+    // In a "production" build, only use clang on architectures we expect to
+    // work, and don't use clang C++.
+    //
+    // During development its more convenient to always have the driver use
+    // clang, but we don't want users to be confused when things don't work, or
+    // to file bugs for things we don't support.
+    CCCClangArchs.insert(llvm::Triple::x86);
+    CCCClangArchs.insert(llvm::Triple::x86_64);
+    CCCClangArchs.insert(llvm::Triple::arm);
+
+    if (!CXXIsProduction)
+      CCCUseClangCXX = false;
+  }
+
+  // Compute the path to the resource directory.
+  llvm::sys::Path P(Dir);
+  P.eraseComponent(); // Remove /bin from foo/bin
+  P.appendComponent("lib");
+  P.appendComponent("clang");
+  P.appendComponent(CLANG_VERSION_STRING);
+  ResourceDir = P.str();
+}
+
+Driver::~Driver() {
+  delete Opts;
+  delete Host;
+}
+
+InputArgList *Driver::ParseArgStrings(const char **ArgBegin,
+                                      const char **ArgEnd) {
+  llvm::PrettyStackTraceString CrashInfo("Command line argument parsing");
+  unsigned MissingArgIndex, MissingArgCount;
+  InputArgList *Args = getOpts().ParseArgs(ArgBegin, ArgEnd,
+                                           MissingArgIndex, MissingArgCount);
+
+  // Check for missing argument error.
+  if (MissingArgCount)
+    Diag(clang::diag::err_drv_missing_argument)
+      << Args->getArgString(MissingArgIndex) << MissingArgCount;
+
+  // Check for unsupported options.
+  for (ArgList::const_iterator it = Args->begin(), ie = Args->end();
+       it != ie; ++it) {
+    Arg *A = *it;
+    if (A->getOption().isUnsupported()) {
+      Diag(clang::diag::err_drv_unsupported_opt) << A->getAsString(*Args);
+      continue;
+    }
+  }
+
+  return Args;
+}
+
+Compilation *Driver::BuildCompilation(int argc, const char **argv) {
+  llvm::PrettyStackTraceString CrashInfo("Compilation construction");
+
+  // FIXME: Handle environment options which effect driver behavior, somewhere
+  // (client?). GCC_EXEC_PREFIX, COMPILER_PATH, LIBRARY_PATH, LPATH,
+  // CC_PRINT_OPTIONS.
+
+  // FIXME: What are we going to do with -V and -b?
+
+  // FIXME: This stuff needs to go into the Compilation, not the driver.
+  bool CCCPrintOptions = false, CCCPrintActions = false;
+
+  const char **Start = argv + 1, **End = argv + argc;
+  const char *HostTriple = DefaultHostTriple.c_str();
+
+  InputArgList *Args = ParseArgStrings(Start, End);
+
+  // -no-canonical-prefixes is used very early in main.
+  Args->ClaimAllArgs(options::OPT_no_canonical_prefixes);
+
+  // Extract -ccc args.
+  //
+  // FIXME: We need to figure out where this behavior should live. Most of it
+  // should be outside in the client; the parts that aren't should have proper
+  // options, either by introducing new ones or by overloading gcc ones like -V
+  // or -b.
+  CCCPrintOptions = Args->hasArg(options::OPT_ccc_print_options);
+  CCCPrintActions = Args->hasArg(options::OPT_ccc_print_phases);
+  CCCPrintBindings = Args->hasArg(options::OPT_ccc_print_bindings);
+  CCCIsCXX = Args->hasArg(options::OPT_ccc_cxx) || CCCIsCXX;
+  CCCEcho = Args->hasArg(options::OPT_ccc_echo);
+  if (const Arg *A = Args->getLastArg(options::OPT_ccc_gcc_name))
+    CCCGenericGCCName = A->getValue(*Args);
+  CCCUseClangCXX = Args->hasFlag(options::OPT_ccc_clang_cxx,
+                                 options::OPT_ccc_no_clang_cxx,
+                                 CCCUseClangCXX);
+  CCCUsePCH = Args->hasFlag(options::OPT_ccc_pch_is_pch,
+                            options::OPT_ccc_pch_is_pth);
+  CCCUseClang = !Args->hasArg(options::OPT_ccc_no_clang);
+  CCCUseClangCPP = !Args->hasArg(options::OPT_ccc_no_clang_cpp);
+  if (const Arg *A = Args->getLastArg(options::OPT_ccc_clang_archs)) {
+    llvm::StringRef Cur = A->getValue(*Args);
+
+    CCCClangArchs.clear();
+    while (!Cur.empty()) {
+      std::pair<llvm::StringRef, llvm::StringRef> Split = Cur.split(',');
+
+      if (!Split.first.empty()) {
+        llvm::Triple::ArchType Arch =
+          llvm::Triple(Split.first, "", "").getArch();
+
+        if (Arch == llvm::Triple::UnknownArch)
+          Diag(clang::diag::err_drv_invalid_arch_name) << Split.first;
+
+        CCCClangArchs.insert(Arch);
+      }
+
+      Cur = Split.second;
+    }
+  }
+  if (const Arg *A = Args->getLastArg(options::OPT_ccc_host_triple))
+    HostTriple = A->getValue(*Args);
+  if (const Arg *A = Args->getLastArg(options::OPT_ccc_install_dir))
+    Dir = A->getValue(*Args);
+  if (const Arg *A = Args->getLastArg(options::OPT_B))
+    PrefixDir = A->getValue(*Args);
+
+  Host = GetHostInfo(HostTriple);
+
+  // The compilation takes ownership of Args.
+  Compilation *C = new Compilation(*this, *Host->CreateToolChain(*Args), Args);
+
+  // FIXME: This behavior shouldn't be here.
+  if (CCCPrintOptions) {
+    PrintOptions(C->getArgs());
+    return C;
+  }
+
+  if (!HandleImmediateArgs(*C))
+    return C;
+
+  // Construct the list of abstract actions to perform for this compilation. We
+  // avoid passing a Compilation here simply to enforce the abstraction that
+  // pipelining is not host or toolchain dependent (other than the driver driver
+  // test).
+  if (Host->useDriverDriver())
+    BuildUniversalActions(C->getArgs(), C->getActions());
+  else
+    BuildActions(C->getArgs(), C->getActions());
+
+  if (CCCPrintActions) {
+    PrintActions(*C);
+    return C;
+  }
+
+  BuildJobs(*C);
+
+  return C;
+}
+
+int Driver::ExecuteCompilation(const Compilation &C) const {
+  // Just print if -### was present.
+  if (C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)) {
+    C.PrintJob(llvm::errs(), C.getJobs(), "\n", true);
+    return 0;
+  }
+
+  // If there were errors building the compilation, quit now.
+  if (getDiags().getNumErrors())
+    return 1;
+
+  const Command *FailingCommand = 0;
+  int Res = C.ExecuteJob(C.getJobs(), FailingCommand);
+
+  // Remove temp files.
+  C.CleanupFileList(C.getTempFiles());
+
+  // If the compilation failed, remove result files as well.
+  if (Res != 0 && !C.getArgs().hasArg(options::OPT_save_temps))
+    C.CleanupFileList(C.getResultFiles(), true);
+
+  // Print extra information about abnormal failures, if possible.
+  if (Res) {
+    // This is ad-hoc, but we don't want to be excessively noisy. If the result
+    // status was 1, assume the command failed normally. In particular, if it
+    // was the compiler then assume it gave a reasonable error code. Failures in
+    // other tools are less common, and they generally have worse diagnostics,
+    // so always print the diagnostic there.
+    const Action &Source = FailingCommand->getSource();
+
+    if (!FailingCommand->getCreator().hasGoodDiagnostics() || Res != 1) {
+      // FIXME: See FIXME above regarding result code interpretation.
+      if (Res < 0)
+        Diag(clang::diag::err_drv_command_signalled)
+          << Source.getClassName() << -Res;
+      else
+        Diag(clang::diag::err_drv_command_failed)
+          << Source.getClassName() << Res;
+    }
+  }
+
+  return Res;
+}
+
+void Driver::PrintOptions(const ArgList &Args) const {
+  unsigned i = 0;
+  for (ArgList::const_iterator it = Args.begin(), ie = Args.end();
+       it != ie; ++it, ++i) {
+    Arg *A = *it;
+    llvm::errs() << "Option " << i << " - "
+                 << "Name: \"" << A->getOption().getName() << "\", "
+                 << "Values: {";
+    for (unsigned j = 0; j < A->getNumValues(); ++j) {
+      if (j)
+        llvm::errs() << ", ";
+      llvm::errs() << '"' << A->getValue(Args, j) << '"';
+    }
+    llvm::errs() << "}\n";
+  }
+}
+
+// FIXME: Move -ccc options to real options in the .td file (or eliminate), and
+// then move to using OptTable::PrintHelp.
+void Driver::PrintHelp(bool ShowHidden) const {
+  getOpts().PrintHelp(llvm::outs(), Name.c_str(), DriverTitle.c_str(),
+                      ShowHidden);
+}
+
+void Driver::PrintVersion(const Compilation &C, llvm::raw_ostream &OS) const {
+  // FIXME: The following handlers should use a callback mechanism, we don't
+  // know what the client would like to do.
+  OS << getClangFullVersion() << '\n';
+  const ToolChain &TC = C.getDefaultToolChain();
+  OS << "Target: " << TC.getTripleString() << '\n';
+
+  // Print the threading model.
+  //
+  // FIXME: Implement correctly.
+  OS << "Thread model: " << "posix" << '\n';
+}
+
+bool Driver::HandleImmediateArgs(const Compilation &C) {
+  // The order these options are handled in in gcc is all over the place, but we
+  // don't expect inconsistencies w.r.t. that to matter in practice.
+
+  if (C.getArgs().hasArg(options::OPT_dumpversion)) {
+    llvm::outs() << CLANG_VERSION_STRING "\n";
+    return false;
+  }
+
+  if (C.getArgs().hasArg(options::OPT__help) ||
+      C.getArgs().hasArg(options::OPT__help_hidden)) {
+    PrintHelp(C.getArgs().hasArg(options::OPT__help_hidden));
+    return false;
+  }
+
+  if (C.getArgs().hasArg(options::OPT__version)) {
+    // Follow gcc behavior and use stdout for --version and stderr for -v.
+    PrintVersion(C, llvm::outs());
+    return false;
+  }
+
+  if (C.getArgs().hasArg(options::OPT_v) ||
+      C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)) {
+    PrintVersion(C, llvm::errs());
+    SuppressMissingInputWarning = true;
+  }
+
+  const ToolChain &TC = C.getDefaultToolChain();
+  if (C.getArgs().hasArg(options::OPT_print_search_dirs)) {
+    llvm::outs() << "programs: =";
+    for (ToolChain::path_list::const_iterator it = TC.getProgramPaths().begin(),
+           ie = TC.getProgramPaths().end(); it != ie; ++it) {
+      if (it != TC.getProgramPaths().begin())
+        llvm::outs() << ':';
+      llvm::outs() << *it;
+    }
+    llvm::outs() << "\n";
+    llvm::outs() << "libraries: =";
+    for (ToolChain::path_list::const_iterator it = TC.getFilePaths().begin(),
+           ie = TC.getFilePaths().end(); it != ie; ++it) {
+      if (it != TC.getFilePaths().begin())
+        llvm::outs() << ':';
+      llvm::outs() << *it;
+    }
+    llvm::outs() << "\n";
+    return false;
+  }
+
+  // FIXME: The following handlers should use a callback mechanism, we don't
+  // know what the client would like to do.
+  if (Arg *A = C.getArgs().getLastArg(options::OPT_print_file_name_EQ)) {
+    llvm::outs() << GetFilePath(A->getValue(C.getArgs()), TC) << "\n";
+    return false;
+  }
+
+  if (Arg *A = C.getArgs().getLastArg(options::OPT_print_prog_name_EQ)) {
+    llvm::outs() << GetProgramPath(A->getValue(C.getArgs()), TC) << "\n";
+    return false;
+  }
+
+  if (C.getArgs().hasArg(options::OPT_print_libgcc_file_name)) {
+    llvm::outs() << GetFilePath("libgcc.a", TC) << "\n";
+    return false;
+  }
+
+  if (C.getArgs().hasArg(options::OPT_print_multi_lib)) {
+    // FIXME: We need tool chain support for this.
+    llvm::outs() << ".;\n";
+
+    switch (C.getDefaultToolChain().getTriple().getArch()) {
+    default:
+      break;
+
+    case llvm::Triple::x86_64:
+      llvm::outs() << "x86_64;@m64" << "\n";
+      break;
+
+    case llvm::Triple::ppc64:
+      llvm::outs() << "ppc64;@m64" << "\n";
+      break;
+    }
+    return false;
+  }
+
+  // FIXME: What is the difference between print-multi-directory and
+  // print-multi-os-directory?
+  if (C.getArgs().hasArg(options::OPT_print_multi_directory) ||
+      C.getArgs().hasArg(options::OPT_print_multi_os_directory)) {
+    switch (C.getDefaultToolChain().getTriple().getArch()) {
+    default:
+    case llvm::Triple::x86:
+    case llvm::Triple::ppc:
+      llvm::outs() << "." << "\n";
+      break;
+
+    case llvm::Triple::x86_64:
+      llvm::outs() << "x86_64" << "\n";
+      break;
+
+    case llvm::Triple::ppc64:
+      llvm::outs() << "ppc64" << "\n";
+      break;
+    }
+    return false;
+  }
+
+  return true;
+}
+
+static unsigned PrintActions1(const Compilation &C, Action *A,
+                              std::map<Action*, unsigned> &Ids) {
+  if (Ids.count(A))
+    return Ids[A];
+
+  std::string str;
+  llvm::raw_string_ostream os(str);
+
+  os << Action::getClassName(A->getKind()) << ", ";
+  if (InputAction *IA = dyn_cast<InputAction>(A)) {
+    os << "\"" << IA->getInputArg().getValue(C.getArgs()) << "\"";
+  } else if (BindArchAction *BIA = dyn_cast<BindArchAction>(A)) {
+    os << '"' << (BIA->getArchName() ? BIA->getArchName() :
+                  C.getDefaultToolChain().getArchName()) << '"'
+       << ", {" << PrintActions1(C, *BIA->begin(), Ids) << "}";
+  } else {
+    os << "{";
+    for (Action::iterator it = A->begin(), ie = A->end(); it != ie;) {
+      os << PrintActions1(C, *it, Ids);
+      ++it;
+      if (it != ie)
+        os << ", ";
+    }
+    os << "}";
+  }
+
+  unsigned Id = Ids.size();
+  Ids[A] = Id;
+  llvm::errs() << Id << ": " << os.str() << ", "
+               << types::getTypeName(A->getType()) << "\n";
+
+  return Id;
+}
+
+void Driver::PrintActions(const Compilation &C) const {
+  std::map<Action*, unsigned> Ids;
+  for (ActionList::const_iterator it = C.getActions().begin(),
+         ie = C.getActions().end(); it != ie; ++it)
+    PrintActions1(C, *it, Ids);
+}
+
+void Driver::BuildUniversalActions(const ArgList &Args,
+                                   ActionList &Actions) const {
+  llvm::PrettyStackTraceString CrashInfo("Building universal build actions");
+  // Collect the list of architectures. Duplicates are allowed, but should only
+  // be handled once (in the order seen).
+  llvm::StringSet<> ArchNames;
+  llvm::SmallVector<const char *, 4> Archs;
+  for (ArgList::const_iterator it = Args.begin(), ie = Args.end();
+       it != ie; ++it) {
+    Arg *A = *it;
+
+    if (A->getOption().matches(options::OPT_arch)) {
+      // Validate the option here; we don't save the type here because its
+      // particular spelling may participate in other driver choices.
+      llvm::Triple::ArchType Arch =
+        llvm::Triple::getArchTypeForDarwinArchName(A->getValue(Args));
+      if (Arch == llvm::Triple::UnknownArch) {
+        Diag(clang::diag::err_drv_invalid_arch_name)
+          << A->getAsString(Args);
+        continue;
+      }
+
+      A->claim();
+      if (ArchNames.insert(A->getValue(Args)))
+        Archs.push_back(A->getValue(Args));
+    }
+  }
+
+  // When there is no explicit arch for this platform, make sure we still bind
+  // the architecture (to the default) so that -Xarch_ is handled correctly.
+  if (!Archs.size())
+    Archs.push_back(0);
+
+  // FIXME: We killed off some others but these aren't yet detected in a
+  // functional manner. If we added information to jobs about which "auxiliary"
+  // files they wrote then we could detect the conflict these cause downstream.
+  if (Archs.size() > 1) {
+    // No recovery needed, the point of this is just to prevent
+    // overwriting the same files.
+    if (const Arg *A = Args.getLastArg(options::OPT_save_temps))
+      Diag(clang::diag::err_drv_invalid_opt_with_multiple_archs)
+        << A->getAsString(Args);
+  }
+
+  ActionList SingleActions;
+  BuildActions(Args, SingleActions);
+
+  // Add in arch binding and lipo (if necessary) for every top level action.
+  for (unsigned i = 0, e = SingleActions.size(); i != e; ++i) {
+    Action *Act = SingleActions[i];
+
+    // Make sure we can lipo this kind of output. If not (and it is an actual
+    // output) then we disallow, since we can't create an output file with the
+    // right name without overwriting it. We could remove this oddity by just
+    // changing the output names to include the arch, which would also fix
+    // -save-temps. Compatibility wins for now.
+
+    if (Archs.size() > 1 && !types::canLipoType(Act->getType()))
+      Diag(clang::diag::err_drv_invalid_output_with_multiple_archs)
+        << types::getTypeName(Act->getType());
+
+    ActionList Inputs;
+    for (unsigned i = 0, e = Archs.size(); i != e; ++i) {
+      Inputs.push_back(new BindArchAction(Act, Archs[i]));
+      if (i != 0)
+        Inputs.back()->setOwnsInputs(false);
+    }
+
+    // Lipo if necessary, we do it this way because we need to set the arch flag
+    // so that -Xarch_ gets overwritten.
+    if (Inputs.size() == 1 || Act->getType() == types::TY_Nothing)
+      Actions.append(Inputs.begin(), Inputs.end());
+    else
+      Actions.push_back(new LipoJobAction(Inputs, Act->getType()));
+  }
+}
+
+void Driver::BuildActions(const ArgList &Args, ActionList &Actions) const {
+  llvm::PrettyStackTraceString CrashInfo("Building compilation actions");
+  // Start by constructing the list of inputs and their types.
+
+  // Track the current user specified (-x) input. We also explicitly track the
+  // argument used to set the type; we only want to claim the type when we
+  // actually use it, so we warn about unused -x arguments.
+  types::ID InputType = types::TY_Nothing;
+  Arg *InputTypeArg = 0;
+
+  llvm::SmallVector<std::pair<types::ID, const Arg*>, 16> Inputs;
+  for (ArgList::const_iterator it = Args.begin(), ie = Args.end();
+       it != ie; ++it) {
+    Arg *A = *it;
+
+    if (isa<InputOption>(A->getOption())) {
+      const char *Value = A->getValue(Args);
+      types::ID Ty = types::TY_INVALID;
+
+      // Infer the input type if necessary.
+      if (InputType == types::TY_Nothing) {
+        // If there was an explicit arg for this, claim it.
+        if (InputTypeArg)
+          InputTypeArg->claim();
+
+        // stdin must be handled specially.
+        if (memcmp(Value, "-", 2) == 0) {
+          // If running with -E, treat as a C input (this changes the builtin
+          // macros, for example). This may be overridden by -ObjC below.
+          //
+          // Otherwise emit an error but still use a valid type to avoid
+          // spurious errors (e.g., no inputs).
+          if (!Args.hasArgNoClaim(options::OPT_E))
+            Diag(clang::diag::err_drv_unknown_stdin_type);
+          Ty = types::TY_C;
+        } else {
+          // Otherwise lookup by extension, and fallback to ObjectType if not
+          // found. We use a host hook here because Darwin at least has its own
+          // idea of what .s is.
+          if (const char *Ext = strrchr(Value, '.'))
+            Ty = Host->lookupTypeForExtension(Ext + 1);
+
+          if (Ty == types::TY_INVALID)
+            Ty = types::TY_Object;
+
+          // If the driver is invoked as C++ compiler (like clang++ or c++) it
+          // should autodetect some input files as C++ for g++ compatibility.
+          if (CCCIsCXX) {
+            types::ID OldTy = Ty;
+            Ty = types::lookupCXXTypeForCType(Ty);
+
+            if (Ty != OldTy)
+              Diag(clang::diag::warn_drv_treating_input_as_cxx)
+                << getTypeName(OldTy) << getTypeName(Ty);
+          }
+        }
+
+        // -ObjC and -ObjC++ override the default language, but only for "source
+        // files". We just treat everything that isn't a linker input as a
+        // source file.
+        //
+        // FIXME: Clean this up if we move the phase sequence into the type.
+        if (Ty != types::TY_Object) {
+          if (Args.hasArg(options::OPT_ObjC))
+            Ty = types::TY_ObjC;
+          else if (Args.hasArg(options::OPT_ObjCXX))
+            Ty = types::TY_ObjCXX;
+        }
+      } else {
+        assert(InputTypeArg && "InputType set w/o InputTypeArg");
+        InputTypeArg->claim();
+        Ty = InputType;
+      }
+
+      // Check that the file exists, if enabled.
+      if (CheckInputsExist && memcmp(Value, "-", 2) != 0 &&
+          !llvm::sys::Path(Value).exists())
+        Diag(clang::diag::err_drv_no_such_file) << A->getValue(Args);
+      else
+        Inputs.push_back(std::make_pair(Ty, A));
+
+    } else if (A->getOption().isLinkerInput()) {
+      // Just treat as object type, we could make a special type for this if
+      // necessary.
+      Inputs.push_back(std::make_pair(types::TY_Object, A));
+
+    } else if (A->getOption().matches(options::OPT_x)) {
+      InputTypeArg = A;
+      InputType = types::lookupTypeForTypeSpecifier(A->getValue(Args));
+
+      // Follow gcc behavior and treat as linker input for invalid -x
+      // options. Its not clear why we shouldn't just revert to unknown; but
+      // this isn't very important, we might as well be bug comatible.
+      if (!InputType) {
+        Diag(clang::diag::err_drv_unknown_language) << A->getValue(Args);
+        InputType = types::TY_Object;
+      }
+    }
+  }
+
+  if (!SuppressMissingInputWarning && Inputs.empty()) {
+    Diag(clang::diag::err_drv_no_input_files);
+    return;
+  }
+
+  // Determine which compilation mode we are in. We look for options which
+  // affect the phase, starting with the earliest phases, and record which
+  // option we used to determine the final phase.
+  Arg *FinalPhaseArg = 0;
+  phases::ID FinalPhase;
+
+  // -{E,M,MM} only run the preprocessor.
+  if ((FinalPhaseArg = Args.getLastArg(options::OPT_E)) ||
+      (FinalPhaseArg = Args.getLastArg(options::OPT_M)) ||
+      (FinalPhaseArg = Args.getLastArg(options::OPT_MM))) {
+    FinalPhase = phases::Preprocess;
+
+    // -{fsyntax-only,-analyze,emit-ast,S} only run up to the compiler.
+  } else if ((FinalPhaseArg = Args.getLastArg(options::OPT_fsyntax_only)) ||
+             (FinalPhaseArg = Args.getLastArg(options::OPT_rewrite_objc)) ||
+             (FinalPhaseArg = Args.getLastArg(options::OPT__analyze,
+                                              options::OPT__analyze_auto)) ||
+             (FinalPhaseArg = Args.getLastArg(options::OPT_emit_ast)) ||
+             (FinalPhaseArg = Args.getLastArg(options::OPT_S))) {
+    FinalPhase = phases::Compile;
+
+    // -c only runs up to the assembler.
+  } else if ((FinalPhaseArg = Args.getLastArg(options::OPT_c))) {
+    FinalPhase = phases::Assemble;
+
+    // Otherwise do everything.
+  } else
+    FinalPhase = phases::Link;
+
+  // Reject -Z* at the top level, these options should never have been exposed
+  // by gcc.
+  if (Arg *A = Args.getLastArg(options::OPT_Z_Joined))
+    Diag(clang::diag::err_drv_use_of_Z_option) << A->getAsString(Args);
+
+  // Construct the actions to perform.
+  ActionList LinkerInputs;
+  for (unsigned i = 0, e = Inputs.size(); i != e; ++i) {
+    types::ID InputType = Inputs[i].first;
+    const Arg *InputArg = Inputs[i].second;
+
+    unsigned NumSteps = types::getNumCompilationPhases(InputType);
+    assert(NumSteps && "Invalid number of steps!");
+
+    // If the first step comes after the final phase we are doing as part of
+    // this compilation, warn the user about it.
+    phases::ID InitialPhase = types::getCompilationPhase(InputType, 0);
+    if (InitialPhase > FinalPhase) {
+      // Claim here to avoid the more general unused warning.
+      InputArg->claim();
+
+      // Special case '-E' warning on a previously preprocessed file to make
+      // more sense.
+      if (InitialPhase == phases::Compile && FinalPhase == phases::Preprocess &&
+          getPreprocessedType(InputType) == types::TY_INVALID)
+        Diag(clang::diag::warn_drv_preprocessed_input_file_unused)
+          << InputArg->getAsString(Args)
+          << FinalPhaseArg->getOption().getName();
+      else
+        Diag(clang::diag::warn_drv_input_file_unused)
+          << InputArg->getAsString(Args)
+          << getPhaseName(InitialPhase)
+          << FinalPhaseArg->getOption().getName();
+      continue;
+    }
+
+    // Build the pipeline for this file.
+    llvm::OwningPtr<Action> Current(new InputAction(*InputArg, InputType));
+    for (unsigned i = 0; i != NumSteps; ++i) {
+      phases::ID Phase = types::getCompilationPhase(InputType, i);
+
+      // We are done if this step is past what the user requested.
+      if (Phase > FinalPhase)
+        break;
+
+      // Queue linker inputs.
+      if (Phase == phases::Link) {
+        assert(i + 1 == NumSteps && "linking must be final compilation step.");
+        LinkerInputs.push_back(Current.take());
+        break;
+      }
+
+      // Some types skip the assembler phase (e.g., llvm-bc), but we can't
+      // encode this in the steps because the intermediate type depends on
+      // arguments. Just special case here.
+      if (Phase == phases::Assemble && Current->getType() != types::TY_PP_Asm)
+        continue;
+
+      // Otherwise construct the appropriate action.
+      Current.reset(ConstructPhaseAction(Args, Phase, Current.take()));
+      if (Current->getType() == types::TY_Nothing)
+        break;
+    }
+
+    // If we ended with something, add to the output list.
+    if (Current)
+      Actions.push_back(Current.take());
+  }
+
+  // Add a link action if necessary.
+  if (!LinkerInputs.empty())
+    Actions.push_back(new LinkJobAction(LinkerInputs, types::TY_Image));
+
+  // If we are linking, claim any options which are obviously only used for
+  // compilation.
+  if (FinalPhase == phases::Link)
+    Args.ClaimAllArgs(options::OPT_CompileOnly_Group);
+}
+
+Action *Driver::ConstructPhaseAction(const ArgList &Args, phases::ID Phase,
+                                     Action *Input) const {
+  llvm::PrettyStackTraceString CrashInfo("Constructing phase actions");
+  // Build the appropriate action.
+  switch (Phase) {
+  case phases::Link: assert(0 && "link action invalid here.");
+  case phases::Preprocess: {
+    types::ID OutputTy;
+    // -{M, MM} alter the output type.
+    if (Args.hasArg(options::OPT_M) || Args.hasArg(options::OPT_MM)) {
+      OutputTy = types::TY_Dependencies;
+    } else {
+      OutputTy = types::getPreprocessedType(Input->getType());
+      assert(OutputTy != types::TY_INVALID &&
+             "Cannot preprocess this input type!");
+    }
+    return new PreprocessJobAction(Input, OutputTy);
+  }
+  case phases::Precompile:
+    return new PrecompileJobAction(Input, types::TY_PCH);
+  case phases::Compile: {
+    bool HasO4 = false;
+    if (const Arg *A = Args.getLastArg(options::OPT_O_Group))
+      HasO4 = A->getOption().matches(options::OPT_O4);
+
+    if (Args.hasArg(options::OPT_fsyntax_only)) {
+      return new CompileJobAction(Input, types::TY_Nothing);
+    } else if (Args.hasArg(options::OPT_rewrite_objc)) {
+      return new CompileJobAction(Input, types::TY_RewrittenObjC);
+    } else if (Args.hasArg(options::OPT__analyze, options::OPT__analyze_auto)) {
+      return new AnalyzeJobAction(Input, types::TY_Plist);
+    } else if (Args.hasArg(options::OPT_emit_ast)) {
+      return new CompileJobAction(Input, types::TY_AST);
+    } else if (Args.hasArg(options::OPT_emit_llvm) ||
+               Args.hasArg(options::OPT_flto) || HasO4) {
+      types::ID Output =
+        Args.hasArg(options::OPT_S) ? types::TY_LLVMAsm : types::TY_LLVMBC;
+      return new CompileJobAction(Input, Output);
+    } else {
+      return new CompileJobAction(Input, types::TY_PP_Asm);
+    }
+  }
+  case phases::Assemble:
+    return new AssembleJobAction(Input, types::TY_Object);
+  }
+
+  assert(0 && "invalid phase in ConstructPhaseAction");
+  return 0;
+}
+
+void Driver::BuildJobs(Compilation &C) const {
+  llvm::PrettyStackTraceString CrashInfo("Building compilation jobs");
+  bool SaveTemps = C.getArgs().hasArg(options::OPT_save_temps);
+  bool UsePipes = C.getArgs().hasArg(options::OPT_pipe);
+
+  // FIXME: Pipes are forcibly disabled until we support executing them.
+  if (!CCCPrintBindings)
+    UsePipes = false;
+
+  // -save-temps inhibits pipes.
+  if (SaveTemps && UsePipes)
+    Diag(clang::diag::warn_drv_pipe_ignored_with_save_temps);
+
+  Arg *FinalOutput = C.getArgs().getLastArg(options::OPT_o);
+
+  // It is an error to provide a -o option if we are making multiple output
+  // files.
+  if (FinalOutput) {
+    unsigned NumOutputs = 0;
+    for (ActionList::const_iterator it = C.getActions().begin(),
+           ie = C.getActions().end(); it != ie; ++it)
+      if ((*it)->getType() != types::TY_Nothing)
+        ++NumOutputs;
+
+    if (NumOutputs > 1) {
+      Diag(clang::diag::err_drv_output_argument_with_multiple_files);
+      FinalOutput = 0;
+    }
+  }
+
+  for (ActionList::const_iterator it = C.getActions().begin(),
+         ie = C.getActions().end(); it != ie; ++it) {
+    Action *A = *it;
+
+    // If we are linking an image for multiple archs then the linker wants
+    // -arch_multiple and -final_output <final image name>. Unfortunately, this
+    // doesn't fit in cleanly because we have to pass this information down.
+    //
+    // FIXME: This is a hack; find a cleaner way to integrate this into the
+    // process.
+    const char *LinkingOutput = 0;
+    if (isa<LipoJobAction>(A)) {
+      if (FinalOutput)
+        LinkingOutput = FinalOutput->getValue(C.getArgs());
+      else
+        LinkingOutput = DefaultImageName.c_str();
+    }
+
+    InputInfo II;
+    BuildJobsForAction(C, A, &C.getDefaultToolChain(),
+                       /*BoundArch*/0,
+                       /*CanAcceptPipe*/ true,
+                       /*AtTopLevel*/ true,
+                       /*LinkingOutput*/ LinkingOutput,
+                       II);
+  }
+
+  // If the user passed -Qunused-arguments or there were errors, don't warn
+  // about any unused arguments.
+  if (Diags.getNumErrors() ||
+      C.getArgs().hasArg(options::OPT_Qunused_arguments))
+    return;
+
+  // Claim -### here.
+  (void) C.getArgs().hasArg(options::OPT__HASH_HASH_HASH);
+
+  for (ArgList::const_iterator it = C.getArgs().begin(), ie = C.getArgs().end();
+       it != ie; ++it) {
+    Arg *A = *it;
+
+    // FIXME: It would be nice to be able to send the argument to the
+    // Diagnostic, so that extra values, position, and so on could be printed.
+    if (!A->isClaimed()) {
+      if (A->getOption().hasNoArgumentUnused())
+        continue;
+
+      // Suppress the warning automatically if this is just a flag, and it is an
+      // instance of an argument we already claimed.
+      const Option &Opt = A->getOption();
+      if (isa<FlagOption>(Opt)) {
+        bool DuplicateClaimed = false;
+
+        for (arg_iterator it = C.getArgs().filtered_begin(&Opt),
+               ie = C.getArgs().filtered_end(); it != ie; ++it) {
+          if ((*it)->isClaimed()) {
+            DuplicateClaimed = true;
+            break;
+          }
+        }
+
+        if (DuplicateClaimed)
+          continue;
+      }
+
+      Diag(clang::diag::warn_drv_unused_argument)
+        << A->getAsString(C.getArgs());
+    }
+  }
+}
+
+static const Tool &SelectToolForJob(Compilation &C, const ToolChain *TC,
+                                    const JobAction *JA,
+                                    const ActionList *&Inputs) {
+  const Tool *ToolForJob = 0;
+
+  // See if we should look for a compiler with an integrated assembler. We match
+  // bottom up, so what we are actually looking for is an assembler job with a
+  // compiler input.
+  if (C.getArgs().hasArg(options::OPT_integrated_as,
+                         options::OPT_no_integrated_as,
+                         TC->IsIntegratedAssemblerDefault()) &&
+      !C.getArgs().hasArg(options::OPT_save_temps) &&
+      isa<AssembleJobAction>(JA) &&
+      Inputs->size() == 1 && isa<CompileJobAction>(*Inputs->begin())) {
+    const Tool &Compiler = TC->SelectTool(C,cast<JobAction>(**Inputs->begin()));
+    if (Compiler.hasIntegratedAssembler()) {
+      Inputs = &(*Inputs)[0]->getInputs();
+      ToolForJob = &Compiler;
+    }
+  }
+
+  // Otherwise use the tool for the current job.
+  if (!ToolForJob)
+    ToolForJob = &TC->SelectTool(C, *JA);
+
+  // See if we should use an integrated preprocessor. We do so when we have
+  // exactly one input, since this is the only use case we care about
+  // (irrelevant since we don't support combine yet).
+  if (Inputs->size() == 1 && isa<PreprocessJobAction>(*Inputs->begin()) &&
+      !C.getArgs().hasArg(options::OPT_no_integrated_cpp) &&
+      !C.getArgs().hasArg(options::OPT_traditional_cpp) &&
+      !C.getArgs().hasArg(options::OPT_save_temps) &&
+      ToolForJob->hasIntegratedCPP())
+    Inputs = &(*Inputs)[0]->getInputs();
+
+  return *ToolForJob;
+}
+
+void Driver::BuildJobsForAction(Compilation &C,
+                                const Action *A,
+                                const ToolChain *TC,
+                                const char *BoundArch,
+                                bool CanAcceptPipe,
+                                bool AtTopLevel,
+                                const char *LinkingOutput,
+                                InputInfo &Result) const {
+  llvm::PrettyStackTraceString CrashInfo("Building compilation jobs");
+
+  bool UsePipes = C.getArgs().hasArg(options::OPT_pipe);
+  // FIXME: Pipes are forcibly disabled until we support executing them.
+  if (!CCCPrintBindings)
+    UsePipes = false;
+
+  if (const InputAction *IA = dyn_cast<InputAction>(A)) {
+    // FIXME: It would be nice to not claim this here; maybe the old scheme of
+    // just using Args was better?
+    const Arg &Input = IA->getInputArg();
+    Input.claim();
+    if (isa<PositionalArg>(Input)) {
+      const char *Name = Input.getValue(C.getArgs());
+      Result = InputInfo(Name, A->getType(), Name);
+    } else
+      Result = InputInfo(&Input, A->getType(), "");
+    return;
+  }
+
+  if (const BindArchAction *BAA = dyn_cast<BindArchAction>(A)) {
+    const ToolChain *TC = &C.getDefaultToolChain();
+
+    std::string Arch;
+    if (BAA->getArchName())
+      TC = Host->CreateToolChain(C.getArgs(), BAA->getArchName());
+
+    BuildJobsForAction(C, *BAA->begin(), TC, BAA->getArchName(),
+                       CanAcceptPipe, AtTopLevel, LinkingOutput, Result);
+    return;
+  }
+
+  const ActionList *Inputs = &A->getInputs();
+
+  const JobAction *JA = cast<JobAction>(A);
+  const Tool &T = SelectToolForJob(C, TC, JA, Inputs);
+
+  // Only use pipes when there is exactly one input.
+  bool TryToUsePipeInput = Inputs->size() == 1 && T.acceptsPipedInput();
+  InputInfoList InputInfos;
+  for (ActionList::const_iterator it = Inputs->begin(), ie = Inputs->end();
+       it != ie; ++it) {
+    InputInfo II;
+    BuildJobsForAction(C, *it, TC, BoundArch, TryToUsePipeInput,
+                       /*AtTopLevel*/false, LinkingOutput, II);
+    InputInfos.push_back(II);
+  }
+
+  // Determine if we should output to a pipe.
+  bool OutputToPipe = false;
+  if (CanAcceptPipe && T.canPipeOutput()) {
+    // Some actions default to writing to a pipe if they are the top level phase
+    // and there was no user override.
+    //
+    // FIXME: Is there a better way to handle this?
+    if (AtTopLevel) {
+      if (isa<PreprocessJobAction>(A) && !C.getArgs().hasArg(options::OPT_o))
+        OutputToPipe = true;
+    } else if (UsePipes)
+      OutputToPipe = true;
+  }
+
+  // Figure out where to put the job (pipes).
+  Job *Dest = &C.getJobs();
+  if (InputInfos[0].isPipe()) {
+    assert(TryToUsePipeInput && "Unrequested pipe!");
+    assert(InputInfos.size() == 1 && "Unexpected pipe with multiple inputs.");
+    Dest = &InputInfos[0].getPipe();
+  }
+
+  // Always use the first input as the base input.
+  const char *BaseInput = InputInfos[0].getBaseInput();
+
+  // Determine the place to write output to (nothing, pipe, or filename) and
+  // where to put the new job.
+  if (JA->getType() == types::TY_Nothing) {
+    Result = InputInfo(A->getType(), BaseInput);
+  } else if (OutputToPipe) {
+    // Append to current piped job or create a new one as appropriate.
+    PipedJob *PJ = dyn_cast<PipedJob>(Dest);
+    if (!PJ) {
+      PJ = new PipedJob();
+      // FIXME: Temporary hack so that -ccc-print-bindings work until we have
+      // pipe support. Please remove later.
+      if (!CCCPrintBindings)
+        cast<JobList>(Dest)->addJob(PJ);
+      Dest = PJ;
+    }
+    Result = InputInfo(PJ, A->getType(), BaseInput);
+  } else {
+    Result = InputInfo(GetNamedOutputPath(C, *JA, BaseInput, AtTopLevel),
+                       A->getType(), BaseInput);
+  }
+
+  if (CCCPrintBindings) {
+    llvm::errs() << "# \"" << T.getToolChain().getTripleString() << '"'
+                 << " - \"" << T.getName() << "\", inputs: [";
+    for (unsigned i = 0, e = InputInfos.size(); i != e; ++i) {
+      llvm::errs() << InputInfos[i].getAsString();
+      if (i + 1 != e)
+        llvm::errs() << ", ";
+    }
+    llvm::errs() << "], output: " << Result.getAsString() << "\n";
+  } else {
+    T.ConstructJob(C, *JA, *Dest, Result, InputInfos,
+                   C.getArgsForToolChain(TC, BoundArch), LinkingOutput);
+  }
+}
+
+const char *Driver::GetNamedOutputPath(Compilation &C,
+                                       const JobAction &JA,
+                                       const char *BaseInput,
+                                       bool AtTopLevel) const {
+  llvm::PrettyStackTraceString CrashInfo("Computing output path");
+  // Output to a user requested destination?
+  if (AtTopLevel) {
+    if (Arg *FinalOutput = C.getArgs().getLastArg(options::OPT_o))
+      return C.addResultFile(FinalOutput->getValue(C.getArgs()));
+  }
+
+  // Output to a temporary file?
+  if (!AtTopLevel && !C.getArgs().hasArg(options::OPT_save_temps)) {
+    std::string TmpName =
+      GetTemporaryPath(types::getTypeTempSuffix(JA.getType()));
+    return C.addTempFile(C.getArgs().MakeArgString(TmpName.c_str()));
+  }
+
+  llvm::sys::Path BasePath(BaseInput);
+  std::string BaseName(BasePath.getLast());
+
+  // Determine what the derived output name should be.
+  const char *NamedOutput;
+  if (JA.getType() == types::TY_Image) {
+    NamedOutput = DefaultImageName.c_str();
+  } else {
+    const char *Suffix = types::getTypeTempSuffix(JA.getType());
+    assert(Suffix && "All types used for output should have a suffix.");
+
+    std::string::size_type End = std::string::npos;
+    if (!types::appendSuffixForType(JA.getType()))
+      End = BaseName.rfind('.');
+    std::string Suffixed(BaseName.substr(0, End));
+    Suffixed += '.';
+    Suffixed += Suffix;
+    NamedOutput = C.getArgs().MakeArgString(Suffixed.c_str());
+  }
+
+  // As an annoying special case, PCH generation doesn't strip the pathname.
+  if (JA.getType() == types::TY_PCH) {
+    BasePath.eraseComponent();
+    if (BasePath.isEmpty())
+      BasePath = NamedOutput;
+    else
+      BasePath.appendComponent(NamedOutput);
+    return C.addResultFile(C.getArgs().MakeArgString(BasePath.c_str()));
+  } else {
+    return C.addResultFile(NamedOutput);
+  }
+}
+
+std::string Driver::GetFilePath(const char *Name, const ToolChain &TC) const {
+  // Respect a limited subset of the '-Bprefix' functionality in GCC by
+  // attempting to use this prefix when lokup up program paths.
+  if (!PrefixDir.empty()) {
+    llvm::sys::Path P(PrefixDir);
+    P.appendComponent(Name);
+    if (P.exists())
+      return P.str();
+  }
+
+  const ToolChain::path_list &List = TC.getFilePaths();
+  for (ToolChain::path_list::const_iterator
+         it = List.begin(), ie = List.end(); it != ie; ++it) {
+    llvm::sys::Path P(*it);
+    P.appendComponent(Name);
+    if (P.exists())
+      return P.str();
+  }
+
+  return Name;
+}
+
+std::string Driver::GetProgramPath(const char *Name, const ToolChain &TC,
+                                   bool WantFile) const {
+  // Respect a limited subset of the '-Bprefix' functionality in GCC by
+  // attempting to use this prefix when lokup up program paths.
+  if (!PrefixDir.empty()) {
+    llvm::sys::Path P(PrefixDir);
+    P.appendComponent(Name);
+    if (WantFile ? P.exists() : P.canExecute())
+      return P.str();
+  }
+
+  const ToolChain::path_list &List = TC.getProgramPaths();
+  for (ToolChain::path_list::const_iterator
+         it = List.begin(), ie = List.end(); it != ie; ++it) {
+    llvm::sys::Path P(*it);
+    P.appendComponent(Name);
+    if (WantFile ? P.exists() : P.canExecute())
+      return P.str();
+  }
+
+  // If all else failed, search the path.
+  llvm::sys::Path P(llvm::sys::Program::FindProgramByName(Name));
+  if (!P.empty())
+    return P.str();
+
+  return Name;
+}
+
+std::string Driver::GetTemporaryPath(const char *Suffix) const {
+  // FIXME: This is lame; sys::Path should provide this function (in particular,
+  // it should know how to find the temporary files dir).
+  std::string Error;
+  const char *TmpDir = ::getenv("TMPDIR");
+  if (!TmpDir)
+    TmpDir = ::getenv("TEMP");
+  if (!TmpDir)
+    TmpDir = ::getenv("TMP");
+  if (!TmpDir)
+    TmpDir = "/tmp";
+  llvm::sys::Path P(TmpDir);
+  P.appendComponent("cc");
+  if (P.makeUnique(false, &Error)) {
+    Diag(clang::diag::err_drv_unable_to_make_temp) << Error;
+    return "";
+  }
+
+  // FIXME: Grumble, makeUnique sometimes leaves the file around!?  PR3837.
+  P.eraseFromDisk(false, 0);
+
+  P.appendSuffix(Suffix);
+  return P.str();
+}
+
+const HostInfo *Driver::GetHostInfo(const char *TripleStr) const {
+  llvm::PrettyStackTraceString CrashInfo("Constructing host");
+  llvm::Triple Triple(TripleStr);
+
+  // TCE is an osless target
+  if (Triple.getArchName() == "tce")
+    return createTCEHostInfo(*this, Triple); 
+
+  switch (Triple.getOS()) {
+  case llvm::Triple::AuroraUX:
+    return createAuroraUXHostInfo(*this, Triple);
+  case llvm::Triple::Darwin:
+    return createDarwinHostInfo(*this, Triple);
+  case llvm::Triple::DragonFly:
+    return createDragonFlyHostInfo(*this, Triple);
+  case llvm::Triple::OpenBSD:
+    return createOpenBSDHostInfo(*this, Triple);
+  case llvm::Triple::FreeBSD:
+    return createFreeBSDHostInfo(*this, Triple);
+  case llvm::Triple::Linux:
+    return createLinuxHostInfo(*this, Triple);
+  default:
+    return createUnknownHostInfo(*this, Triple);
+  }
+}
+
+bool Driver::ShouldUseClangCompiler(const Compilation &C, const JobAction &JA,
+                                    const llvm::Triple &Triple) const {
+  // Check if user requested no clang, or clang doesn't understand this type (we
+  // only handle single inputs for now).
+  if (!CCCUseClang || JA.size() != 1 ||
+      !types::isAcceptedByClang((*JA.begin())->getType()))
+    return false;
+
+  // Otherwise make sure this is an action clang understands.
+  if (isa<PreprocessJobAction>(JA)) {
+    if (!CCCUseClangCPP) {
+      Diag(clang::diag::warn_drv_not_using_clang_cpp);
+      return false;
+    }
+  } else if (!isa<PrecompileJobAction>(JA) && !isa<CompileJobAction>(JA))
+    return false;
+
+  // Use clang for C++?
+  if (!CCCUseClangCXX && types::isCXX((*JA.begin())->getType())) {
+    Diag(clang::diag::warn_drv_not_using_clang_cxx);
+    return false;
+  }
+
+  // Always use clang for precompiling, AST generation, and rewriting,
+  // regardless of archs.
+  if (isa<PrecompileJobAction>(JA) || JA.getType() == types::TY_AST ||
+      JA.getType() == types::TY_RewrittenObjC)
+    return true;
+
+  // Finally, don't use clang if this isn't one of the user specified archs to
+  // build.
+  if (!CCCClangArchs.empty() && !CCCClangArchs.count(Triple.getArch())) {
+    Diag(clang::diag::warn_drv_not_using_clang_arch) << Triple.getArchName();
+    return false;
+  }
+
+  return true;
+}
+
+/// GetReleaseVersion - Parse (([0-9]+)(.([0-9]+)(.([0-9]+)?))?)? and return the
+/// grouped values as integers. Numbers which are not provided are set to 0.
+///
+/// \return True if the entire string was parsed (9.2), or all groups were
+/// parsed (10.3.5extrastuff).
+bool Driver::GetReleaseVersion(const char *Str, unsigned &Major,
+                               unsigned &Minor, unsigned &Micro,
+                               bool &HadExtra) {
+  HadExtra = false;
+
+  Major = Minor = Micro = 0;
+  if (*Str == '\0')
+    return true;
+
+  char *End;
+  Major = (unsigned) strtol(Str, &End, 10);
+  if (*Str != '\0' && *End == '\0')
+    return true;
+  if (*End != '.')
+    return false;
+
+  Str = End+1;
+  Minor = (unsigned) strtol(Str, &End, 10);
+  if (*Str != '\0' && *End == '\0')
+    return true;
+  if (*End != '.')
+    return false;
+
+  Str = End+1;
+  Micro = (unsigned) strtol(Str, &End, 10);
+  if (*Str != '\0' && *End == '\0')
+    return true;
+  if (Str == End)
+    return false;
+  HadExtra = true;
+  return true;
+}
diff --git a/lib/Driver/DriverOptions.cpp b/lib/Driver/DriverOptions.cpp
new file mode 100644
index 0000000..72aaf56
--- /dev/null
+++ b/lib/Driver/DriverOptions.cpp
@@ -0,0 +1,37 @@
+//===--- DriverOptions.cpp - Driver Options Table -----------------------*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Driver/Options.h"
+#include "clang/Driver/OptTable.h"
+#include "clang/Driver/Option.h"
+
+using namespace clang::driver;
+using namespace clang::driver::options;
+
+static const OptTable::Info InfoTable[] = {
+#define OPTION(NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \
+               HELPTEXT, METAVAR)   \
+  { NAME, HELPTEXT, METAVAR, Option::KIND##Class, FLAGS, PARAM, \
+    OPT_##GROUP, OPT_##ALIAS },
+#include "clang/Driver/Options.inc"
+};
+
+namespace {
+
+class DriverOptTable : public OptTable {
+public:
+  DriverOptTable()
+    : OptTable(InfoTable, sizeof(InfoTable) / sizeof(InfoTable[0])) {}
+};
+
+}
+
+OptTable *clang::driver::createDriverOptTable() {
+  return new DriverOptTable();
+}
diff --git a/lib/Driver/HostInfo.cpp b/lib/Driver/HostInfo.cpp
new file mode 100644
index 0000000..d9e2e37
--- /dev/null
+++ b/lib/Driver/HostInfo.cpp
@@ -0,0 +1,590 @@
+//===--- HostInfo.cpp - Host specific information -----------------------*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Driver/HostInfo.h"
+
+#include "clang/Driver/Arg.h"
+#include "clang/Driver/ArgList.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/DriverDiagnostic.h"
+#include "clang/Driver/Option.h"
+#include "clang/Driver/Options.h"
+
+#include "llvm/ADT/StringMap.h"
+#include "llvm/Support/Compiler.h"
+
+#include "ToolChains.h"
+
+#include <cassert>
+
+using namespace clang::driver;
+
+HostInfo::HostInfo(const Driver &D, const llvm::Triple &_Triple)
+  : TheDriver(D), Triple(_Triple) {
+}
+
+HostInfo::~HostInfo() {
+}
+
+namespace {
+
+// Darwin Host Info
+
+/// DarwinHostInfo - Darwin host information implementation.
+class DarwinHostInfo : public HostInfo {
+  /// Darwin version of host.
+  unsigned DarwinVersion[3];
+
+  /// GCC version to use on this host.
+  unsigned GCCVersion[3];
+
+  /// Cache of tool chains we have created.
+  mutable llvm::DenseMap<unsigned, ToolChain*> ToolChains;
+
+public:
+  DarwinHostInfo(const Driver &D, const llvm::Triple &Triple);
+  ~DarwinHostInfo();
+
+  virtual bool useDriverDriver() const;
+
+  virtual types::ID lookupTypeForExtension(const char *Ext) const {
+    types::ID Ty = types::lookupTypeForExtension(Ext);
+
+    // Darwin always preprocesses assembly files (unless -x is used
+    // explicitly).
+    if (Ty == types::TY_PP_Asm)
+      return types::TY_Asm;
+
+    return Ty;
+  }
+
+  virtual ToolChain *CreateToolChain(const ArgList &Args,
+                                     const char *ArchName) const;
+};
+
+DarwinHostInfo::DarwinHostInfo(const Driver &D, const llvm::Triple& Triple)
+  : HostInfo(D, Triple) {
+
+  assert(Triple.getArch() != llvm::Triple::UnknownArch && "Invalid arch!");
+  assert(memcmp(&getOSName()[0], "darwin", 6) == 0 &&
+         "Unknown Darwin platform.");
+  bool HadExtra;
+  if (!Driver::GetReleaseVersion(&getOSName()[6],
+                                 DarwinVersion[0], DarwinVersion[1],
+                                 DarwinVersion[2], HadExtra))
+    D.Diag(clang::diag::err_drv_invalid_darwin_version) << getOSName();
+
+  // We can only call 4.2.1 for now.
+  GCCVersion[0] = 4;
+  GCCVersion[1] = 2;
+  GCCVersion[2] = 1;
+}
+
+DarwinHostInfo::~DarwinHostInfo() {
+  for (llvm::DenseMap<unsigned, ToolChain*>::iterator
+         it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it)
+    delete it->second;
+}
+
+bool DarwinHostInfo::useDriverDriver() const {
+  return true;
+}
+
+ToolChain *DarwinHostInfo::CreateToolChain(const ArgList &Args,
+                                           const char *ArchName) const {
+  llvm::Triple::ArchType Arch;
+
+  if (!ArchName) {
+    // If we aren't looking for a specific arch, infer the default architecture
+    // based on -arch and -m32/-m64 command line options.
+    if (Arg *A = Args.getLastArg(options::OPT_arch)) {
+      // The gcc driver behavior with multiple -arch flags wasn't consistent for
+      // things which rely on a default architecture. We just use the last -arch
+      // to find the default tool chain (assuming it is valid).
+      Arch = llvm::Triple::getArchTypeForDarwinArchName(A->getValue(Args));
+
+      // If it was invalid just use the host, we will reject this command line
+      // later.
+      if (Arch == llvm::Triple::UnknownArch)
+        Arch = getTriple().getArch();
+    } else {
+      // Otherwise default to the arch of the host.
+      Arch = getTriple().getArch();
+    }
+
+    // Honor -m32 and -m64 when finding the default tool chain.
+    //
+    // FIXME: Should this information be in llvm::Triple?
+    if (Arg *A = Args.getLastArg(options::OPT_m32, options::OPT_m64)) {
+      if (A->getOption().matches(options::OPT_m32)) {
+        if (Arch == llvm::Triple::x86_64)
+          Arch = llvm::Triple::x86;
+        if (Arch == llvm::Triple::ppc64)
+          Arch = llvm::Triple::ppc;
+      } else {
+        if (Arch == llvm::Triple::x86)
+          Arch = llvm::Triple::x86_64;
+        if (Arch == llvm::Triple::ppc)
+          Arch = llvm::Triple::ppc64;
+      }
+    }
+  } else
+    Arch = llvm::Triple::getArchTypeForDarwinArchName(ArchName);
+
+  assert(Arch != llvm::Triple::UnknownArch && "Unexpected arch!");
+  ToolChain *&TC = ToolChains[Arch];
+  if (!TC) {
+    llvm::Triple TCTriple(getTriple());
+    TCTriple.setArch(Arch);
+
+    // If we recognized the arch, match it to the toolchains we support.
+    const char *UseNewToolChain = ::getenv("CCC_ENABLE_NEW_DARWIN_TOOLCHAIN");
+    if (UseNewToolChain || 
+        Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb) {
+      TC = new toolchains::DarwinClang(*this, TCTriple, DarwinVersion);
+    } else if (Arch == llvm::Triple::x86 || Arch == llvm::Triple::x86_64) {
+      // We still use the legacy DarwinGCC toolchain on X86.
+      TC = new toolchains::DarwinGCC(*this, TCTriple, DarwinVersion,
+                                     GCCVersion);
+    } else
+      TC = new toolchains::Darwin_Generic_GCC(*this, TCTriple);
+  }
+
+  return TC;
+}
+
+// TCE Host Info
+
+/// TCEHostInfo - TCE host information implementation (see http://tce.cs.tut.fi)
+class TCEHostInfo : public HostInfo {
+
+public:
+  TCEHostInfo(const Driver &D, const llvm::Triple &Triple);
+  ~TCEHostInfo() {}
+
+  virtual bool useDriverDriver() const;
+
+  virtual types::ID lookupTypeForExtension(const char *Ext) const {
+    types::ID Ty = types::lookupTypeForExtension(Ext);
+
+    if (Ty == types::TY_PP_Asm)
+      return types::TY_Asm;
+
+    return Ty;
+  }
+
+  virtual ToolChain *CreateToolChain(const ArgList &Args, 
+                                     const char *ArchName) const;
+};
+
+TCEHostInfo::TCEHostInfo(const Driver &D, const llvm::Triple& Triple)
+  : HostInfo(D, Triple) {
+}
+
+bool TCEHostInfo::useDriverDriver() const { 
+  return false;
+}
+
+ToolChain *TCEHostInfo::CreateToolChain(const ArgList &Args, 
+                                        const char *ArchName) const {
+  llvm::Triple TCTriple(getTriple());
+//  TCTriple.setArchName(ArchName);
+  return new toolchains::TCEToolChain(*this, TCTriple);
+}
+
+
+// Unknown Host Info
+
+/// UnknownHostInfo - Generic host information to use for unknown hosts.
+class UnknownHostInfo : public HostInfo {
+  /// Cache of tool chains we have created.
+  mutable llvm::StringMap<ToolChain*> ToolChains;
+
+public:
+  UnknownHostInfo(const Driver &D, const llvm::Triple& Triple);
+  ~UnknownHostInfo();
+
+  virtual bool useDriverDriver() const;
+
+  virtual types::ID lookupTypeForExtension(const char *Ext) const {
+    return types::lookupTypeForExtension(Ext);
+  }
+
+  virtual ToolChain *CreateToolChain(const ArgList &Args,
+                                     const char *ArchName) const;
+};
+
+UnknownHostInfo::UnknownHostInfo(const Driver &D, const llvm::Triple& Triple)
+  : HostInfo(D, Triple) {
+}
+
+UnknownHostInfo::~UnknownHostInfo() {
+  for (llvm::StringMap<ToolChain*>::iterator
+         it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it)
+    delete it->second;
+}
+
+bool UnknownHostInfo::useDriverDriver() const {
+  return false;
+}
+
+ToolChain *UnknownHostInfo::CreateToolChain(const ArgList &Args,
+                                            const char *ArchName) const {
+  assert(!ArchName &&
+         "Unexpected arch name on platform without driver driver support.");
+
+  // Automatically handle some instances of -m32/-m64 we know about.
+  std::string Arch = getArchName();
+  ArchName = Arch.c_str();
+  if (Arg *A = Args.getLastArg(options::OPT_m32, options::OPT_m64)) {
+    if (Triple.getArch() == llvm::Triple::x86 ||
+        Triple.getArch() == llvm::Triple::x86_64) {
+      ArchName =
+        (A->getOption().matches(options::OPT_m32)) ? "i386" : "x86_64";
+    } else if (Triple.getArch() == llvm::Triple::ppc ||
+               Triple.getArch() == llvm::Triple::ppc64) {
+      ArchName =
+        (A->getOption().matches(options::OPT_m32)) ? "powerpc" : "powerpc64";
+    }
+  }
+
+  ToolChain *&TC = ToolChains[ArchName];
+  if (!TC) {
+    llvm::Triple TCTriple(getTriple());
+    TCTriple.setArchName(ArchName);
+
+    TC = new toolchains::Generic_GCC(*this, TCTriple);
+  }
+
+  return TC;
+}
+
+// OpenBSD Host Info
+
+/// OpenBSDHostInfo -  OpenBSD host information implementation.
+class OpenBSDHostInfo : public HostInfo {
+  /// Cache of tool chains we have created.
+  mutable llvm::StringMap<ToolChain*> ToolChains;
+
+public:
+  OpenBSDHostInfo(const Driver &D, const llvm::Triple& Triple)
+    : HostInfo(D, Triple) {}
+  ~OpenBSDHostInfo();
+
+  virtual bool useDriverDriver() const;
+
+  virtual types::ID lookupTypeForExtension(const char *Ext) const {
+    return types::lookupTypeForExtension(Ext);
+  }
+
+  virtual ToolChain *CreateToolChain(const ArgList &Args,
+                                     const char *ArchName) const;
+};
+
+OpenBSDHostInfo::~OpenBSDHostInfo() {
+  for (llvm::StringMap<ToolChain*>::iterator
+         it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it)
+    delete it->second;
+}
+
+bool OpenBSDHostInfo::useDriverDriver() const {
+  return false;
+}
+
+ToolChain *OpenBSDHostInfo::CreateToolChain(const ArgList &Args,
+                                            const char *ArchName) const {
+  assert(!ArchName &&
+         "Unexpected arch name on platform without driver driver support.");
+
+  std::string Arch = getArchName();
+  ArchName = Arch.c_str();
+
+  ToolChain *&TC = ToolChains[ArchName];
+  if (!TC) {
+    llvm::Triple TCTriple(getTriple());
+    TCTriple.setArchName(ArchName);
+
+    TC = new toolchains::OpenBSD(*this, TCTriple);
+  }
+
+  return TC;
+}
+
+// AuroraUX Host Info
+
+/// AuroraUXHostInfo - AuroraUX host information implementation.
+class AuroraUXHostInfo : public HostInfo {
+  /// Cache of tool chains we have created.
+  mutable llvm::StringMap<ToolChain*> ToolChains;
+
+public:
+  AuroraUXHostInfo(const Driver &D, const llvm::Triple& Triple)
+    : HostInfo(D, Triple) {}
+  ~AuroraUXHostInfo();
+
+  virtual bool useDriverDriver() const;
+
+  virtual types::ID lookupTypeForExtension(const char *Ext) const {
+    return types::lookupTypeForExtension(Ext);
+  }
+
+  virtual ToolChain *CreateToolChain(const ArgList &Args,
+                                     const char *ArchName) const;
+};
+
+AuroraUXHostInfo::~AuroraUXHostInfo() {
+  for (llvm::StringMap<ToolChain*>::iterator
+         it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it)
+    delete it->second;
+}
+
+bool AuroraUXHostInfo::useDriverDriver() const {
+  return false;
+}
+
+ToolChain *AuroraUXHostInfo::CreateToolChain(const ArgList &Args,
+                                             const char *ArchName) const {
+  assert(!ArchName &&
+         "Unexpected arch name on platform without driver driver support.");
+
+  ToolChain *&TC = ToolChains[getArchName()];
+
+  if (!TC) {
+    llvm::Triple TCTriple(getTriple());
+    TCTriple.setArchName(getArchName());
+
+    TC = new toolchains::AuroraUX(*this, TCTriple);
+  }
+
+  return TC;
+}
+
+// FreeBSD Host Info
+
+/// FreeBSDHostInfo -  FreeBSD host information implementation.
+class FreeBSDHostInfo : public HostInfo {
+  /// Cache of tool chains we have created.
+  mutable llvm::StringMap<ToolChain*> ToolChains;
+
+public:
+  FreeBSDHostInfo(const Driver &D, const llvm::Triple& Triple)
+    : HostInfo(D, Triple) {}
+  ~FreeBSDHostInfo();
+
+  virtual bool useDriverDriver() const;
+
+  virtual types::ID lookupTypeForExtension(const char *Ext) const {
+    return types::lookupTypeForExtension(Ext);
+  }
+
+  virtual ToolChain *CreateToolChain(const ArgList &Args,
+                                     const char *ArchName) const;
+};
+
+FreeBSDHostInfo::~FreeBSDHostInfo() {
+  for (llvm::StringMap<ToolChain*>::iterator
+         it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it)
+    delete it->second;
+}
+
+bool FreeBSDHostInfo::useDriverDriver() const {
+  return false;
+}
+
+ToolChain *FreeBSDHostInfo::CreateToolChain(const ArgList &Args,
+                                            const char *ArchName) const {
+  bool Lib32 = false;
+
+  assert(!ArchName &&
+         "Unexpected arch name on platform without driver driver support.");
+
+  // On x86_64 we need to be able to compile 32-bits binaries as well.
+  // Compiling 64-bit binaries on i386 is not supported. We don't have a
+  // lib64.
+  std::string Arch = getArchName();
+  ArchName = Arch.c_str();
+  if (Args.hasArg(options::OPT_m32) && getArchName() == "x86_64") {
+    ArchName = "i386";
+    Lib32 = true;
+  }
+
+  ToolChain *&TC = ToolChains[ArchName];
+  if (!TC) {
+    llvm::Triple TCTriple(getTriple());
+    TCTriple.setArchName(ArchName);
+
+    TC = new toolchains::FreeBSD(*this, TCTriple, Lib32);
+  }
+
+  return TC;
+}
+
+// DragonFly Host Info
+
+/// DragonFlyHostInfo -  DragonFly host information implementation.
+class DragonFlyHostInfo : public HostInfo {
+  /// Cache of tool chains we have created.
+  mutable llvm::StringMap<ToolChain*> ToolChains;
+
+public:
+  DragonFlyHostInfo(const Driver &D, const llvm::Triple& Triple)
+    : HostInfo(D, Triple) {}
+  ~DragonFlyHostInfo();
+
+  virtual bool useDriverDriver() const;
+
+  virtual types::ID lookupTypeForExtension(const char *Ext) const {
+    return types::lookupTypeForExtension(Ext);
+  }
+
+  virtual ToolChain *CreateToolChain(const ArgList &Args,
+                                     const char *ArchName) const;
+};
+
+DragonFlyHostInfo::~DragonFlyHostInfo() {
+  for (llvm::StringMap<ToolChain*>::iterator
+         it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it)
+    delete it->second;
+}
+
+bool DragonFlyHostInfo::useDriverDriver() const {
+  return false;
+}
+
+ToolChain *DragonFlyHostInfo::CreateToolChain(const ArgList &Args,
+                                              const char *ArchName) const {
+  assert(!ArchName &&
+         "Unexpected arch name on platform without driver driver support.");
+
+  ToolChain *&TC = ToolChains[getArchName()];
+
+  if (!TC) {
+    llvm::Triple TCTriple(getTriple());
+    TCTriple.setArchName(getArchName());
+
+    TC = new toolchains::DragonFly(*this, TCTriple);
+  }
+
+  return TC;
+}
+
+// Linux Host Info
+
+/// LinuxHostInfo -  Linux host information implementation.
+class LinuxHostInfo : public HostInfo {
+  /// Cache of tool chains we have created.
+  mutable llvm::StringMap<ToolChain*> ToolChains;
+
+public:
+  LinuxHostInfo(const Driver &D, const llvm::Triple& Triple)
+    : HostInfo(D, Triple) {}
+  ~LinuxHostInfo();
+
+  virtual bool useDriverDriver() const;
+
+  virtual types::ID lookupTypeForExtension(const char *Ext) const {
+    return types::lookupTypeForExtension(Ext);
+  }
+
+  virtual ToolChain *CreateToolChain(const ArgList &Args,
+                                     const char *ArchName) const;
+};
+
+LinuxHostInfo::~LinuxHostInfo() {
+  for (llvm::StringMap<ToolChain*>::iterator
+         it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it)
+    delete it->second;
+}
+
+bool LinuxHostInfo::useDriverDriver() const {
+  return false;
+}
+
+ToolChain *LinuxHostInfo::CreateToolChain(const ArgList &Args,
+                                          const char *ArchName) const {
+
+  assert(!ArchName &&
+         "Unexpected arch name on platform without driver driver support.");
+
+  // Automatically handle some instances of -m32/-m64 we know about.
+  std::string Arch = getArchName();
+  ArchName = Arch.c_str();
+  if (Arg *A = Args.getLastArg(options::OPT_m32, options::OPT_m64)) {
+    if (Triple.getArch() == llvm::Triple::x86 ||
+        Triple.getArch() == llvm::Triple::x86_64) {
+      ArchName =
+        (A->getOption().matches(options::OPT_m32)) ? "i386" : "x86_64";
+    } else if (Triple.getArch() == llvm::Triple::ppc ||
+               Triple.getArch() == llvm::Triple::ppc64) {
+      ArchName =
+        (A->getOption().matches(options::OPT_m32)) ? "powerpc" : "powerpc64";
+    }
+  }
+
+  ToolChain *&TC = ToolChains[ArchName];
+
+  if (!TC) {
+    llvm::Triple TCTriple(getTriple());
+    TCTriple.setArchName(ArchName);
+
+    TC = new toolchains::Linux(*this, TCTriple);
+  }
+
+  return TC;
+}
+
+}
+
+const HostInfo *
+clang::driver::createAuroraUXHostInfo(const Driver &D,
+                                      const llvm::Triple& Triple){
+  return new AuroraUXHostInfo(D, Triple);
+}
+
+const HostInfo *
+clang::driver::createDarwinHostInfo(const Driver &D,
+                                    const llvm::Triple& Triple){
+  return new DarwinHostInfo(D, Triple);
+}
+
+const HostInfo *
+clang::driver::createOpenBSDHostInfo(const Driver &D,
+                                     const llvm::Triple& Triple) {
+  return new OpenBSDHostInfo(D, Triple);
+}
+
+const HostInfo *
+clang::driver::createFreeBSDHostInfo(const Driver &D,
+                                     const llvm::Triple& Triple) {
+  return new FreeBSDHostInfo(D, Triple);
+}
+
+const HostInfo *
+clang::driver::createDragonFlyHostInfo(const Driver &D,
+                                       const llvm::Triple& Triple) {
+  return new DragonFlyHostInfo(D, Triple);
+}
+
+const HostInfo *
+clang::driver::createLinuxHostInfo(const Driver &D,
+                                   const llvm::Triple& Triple) {
+  return new LinuxHostInfo(D, Triple);
+}
+
+const HostInfo *
+clang::driver::createTCEHostInfo(const Driver &D,
+                                   const llvm::Triple& Triple) {
+  return new TCEHostInfo(D, Triple);
+}
+
+const HostInfo *
+clang::driver::createUnknownHostInfo(const Driver &D,
+                                     const llvm::Triple& Triple) {
+  return new UnknownHostInfo(D, Triple);
+}
diff --git a/lib/Driver/InputInfo.h b/lib/Driver/InputInfo.h
new file mode 100644
index 0000000..c657bef
--- /dev/null
+++ b/lib/Driver/InputInfo.h
@@ -0,0 +1,101 @@
+//===--- InputInfo.h - Input Source & Type Information ----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_LIB_DRIVER_INPUTINFO_H_
+#define CLANG_LIB_DRIVER_INPUTINFO_H_
+
+#include "clang/Driver/Types.h"
+
+#include <cassert>
+#include <string>
+
+namespace clang {
+namespace driver {
+  class PipedJob;
+
+/// InputInfo - Wrapper for information about an input source.
+class InputInfo {
+  // FIXME: The distinction between filenames and inputarg here is
+  // gross; we should probably drop the idea of a "linker
+  // input". Doing so means tweaking pipelining to still create link
+  // steps when it sees linker inputs (but not treat them as
+  // arguments), and making sure that arguments get rendered
+  // correctly.
+  enum Class {
+    Nothing,
+    Filename,
+    InputArg,
+    Pipe
+  };
+
+  union {
+    const char *Filename;
+    const Arg *InputArg;
+    PipedJob *Pipe;
+  } Data;
+  Class Kind;
+  types::ID Type;
+  const char *BaseInput;
+
+public:
+  InputInfo() {}
+  InputInfo(types::ID _Type, const char *_BaseInput)
+    : Kind(Nothing), Type(_Type), BaseInput(_BaseInput) {
+  }
+  InputInfo(const char *_Filename, types::ID _Type, const char *_BaseInput)
+    : Kind(Filename), Type(_Type), BaseInput(_BaseInput) {
+    Data.Filename = _Filename;
+  }
+  InputInfo(const Arg *_InputArg, types::ID _Type, const char *_BaseInput)
+    : Kind(InputArg), Type(_Type), BaseInput(_BaseInput) {
+    Data.InputArg = _InputArg;
+  }
+  InputInfo(PipedJob *_Pipe, types::ID _Type, const char *_BaseInput)
+    : Kind(Pipe), Type(_Type), BaseInput(_BaseInput) {
+    Data.Pipe = _Pipe;
+  }
+
+  bool isNothing() const { return Kind == Nothing; }
+  bool isFilename() const { return Kind == Filename; }
+  bool isInputArg() const { return Kind == InputArg; }
+  bool isPipe() const { return Kind == Pipe; }
+  types::ID getType() const { return Type; }
+  const char *getBaseInput() const { return BaseInput; }
+
+  const char *getFilename() const {
+    assert(isFilename() && "Invalid accessor.");
+    return Data.Filename;
+  }
+  const Arg &getInputArg() const {
+    assert(isInputArg() && "Invalid accessor.");
+    return *Data.InputArg;
+  }
+  PipedJob &getPipe() const {
+    assert(isPipe() && "Invalid accessor.");
+    return *Data.Pipe;
+  }
+
+  /// getAsString - Return a string name for this input, for
+  /// debugging.
+  std::string getAsString() const {
+    if (isPipe())
+      return "(pipe)";
+    else if (isFilename())
+      return std::string("\"") + getFilename() + '"';
+    else if (isInputArg())
+      return "(input arg)";
+    else
+      return "(nothing)";
+  }
+};
+
+} // end namespace driver
+} // end namespace clang
+
+#endif
diff --git a/lib/Driver/Job.cpp b/lib/Driver/Job.cpp
new file mode 100644
index 0000000..bfeb41a
--- /dev/null
+++ b/lib/Driver/Job.cpp
@@ -0,0 +1,44 @@
+//===--- Job.cpp - Command to Execute -----------------------------------*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Driver/Job.h"
+
+#include <cassert>
+using namespace clang::driver;
+
+Job::~Job() {}
+
+Command::Command(const Action &_Source, const Tool &_Creator,
+                 const char *_Executable, const ArgStringList &_Arguments)
+  : Job(CommandClass), Source(_Source), Creator(_Creator),
+    Executable(_Executable), Arguments(_Arguments)
+{
+}
+
+PipedJob::PipedJob() : Job(PipedJobClass) {}
+
+PipedJob::~PipedJob() {
+  for (iterator it = begin(), ie = end(); it != ie; ++it)
+    delete *it;
+}
+
+JobList::JobList() : Job(JobListClass) {}
+
+JobList::~JobList() {
+  for (iterator it = begin(), ie = end(); it != ie; ++it)
+    delete *it;
+}
+
+void Job::addCommand(Command *C) {
+  if (PipedJob *PJ = dyn_cast<PipedJob>(this))
+    PJ->addCommand(C);
+  else
+    cast<JobList>(this)->addJob(C);
+}
+
diff --git a/lib/Driver/Makefile b/lib/Driver/Makefile
new file mode 100644
index 0000000..371bda7
--- /dev/null
+++ b/lib/Driver/Makefile
@@ -0,0 +1,16 @@
+##===- clang/lib/Driver/Makefile ---------------------------*- Makefile -*-===##
+# 
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+# 
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../../../..
+LIBRARYNAME := clangDriver
+BUILD_ARCHIVE = 1
+
+CPPFLAGS += -I$(PROJ_SRC_DIR)/../../include -I$(PROJ_OBJ_DIR)/../../include
+
+include $(LEVEL)/Makefile.common
diff --git a/lib/Driver/OptTable.cpp b/lib/Driver/OptTable.cpp
new file mode 100644
index 0000000..de1e459
--- /dev/null
+++ b/lib/Driver/OptTable.cpp
@@ -0,0 +1,379 @@
+//===--- OptTable.cpp - Option Table Implementation ---------------------*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Driver/OptTable.h"
+#include "clang/Driver/Arg.h"
+#include "clang/Driver/ArgList.h"
+#include "clang/Driver/Option.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <cassert>
+#include <map>
+using namespace clang::driver;
+using namespace clang::driver::options;
+
+// Ordering on Info. The ordering is *almost* lexicographic, with two
+// exceptions. First, '\0' comes at the end of the alphabet instead of
+// the beginning (thus options preceed any other options which prefix
+// them). Second, for options with the same name, the less permissive
+// version should come first; a Flag option should preceed a Joined
+// option, for example.
+
+static int StrCmpOptionName(const char *A, const char *B) {
+  char a = *A, b = *B;
+  while (a == b) {
+    if (a == '\0')
+      return 0;
+
+    a = *++A;
+    b = *++B;
+  }
+
+  if (a == '\0') // A is a prefix of B.
+    return 1;
+  if (b == '\0') // B is a prefix of A.
+    return -1;
+
+  // Otherwise lexicographic.
+  return (a < b) ? -1 : 1;
+}
+
+namespace clang {
+namespace driver {
+static inline bool operator<(const OptTable::Info &A, const OptTable::Info &B) {
+  if (&A == &B)
+    return false;
+
+  if (int N = StrCmpOptionName(A.Name, B.Name))
+    return N == -1;
+
+  // Names are the same, check that classes are in order; exactly one
+  // should be joined, and it should succeed the other.
+  assert(((A.Kind == Option::JoinedClass) ^ (B.Kind == Option::JoinedClass)) &&
+         "Unexpected classes for options with same name.");
+  return B.Kind == Option::JoinedClass;
+}
+
+// Support lower_bound between info and an option name.
+static inline bool operator<(const OptTable::Info &I, const char *Name) {
+  return StrCmpOptionName(I.Name, Name) == -1;
+}
+static inline bool operator<(const char *Name, const OptTable::Info &I) {
+  return StrCmpOptionName(Name, I.Name) == -1;
+}
+}
+}
+
+//
+
+OptSpecifier::OptSpecifier(const Option *Opt) : ID(Opt->getID()) {}
+
+//
+
+OptTable::OptTable(const Info *_OptionInfos, unsigned _NumOptionInfos)
+  : OptionInfos(_OptionInfos), NumOptionInfos(_NumOptionInfos),
+    Options(new Option*[NumOptionInfos]),
+    TheInputOption(0), TheUnknownOption(0), FirstSearchableIndex(0)
+{
+  // Explicitly zero initialize the error to work around a bug in array
+  // value-initialization on MinGW with gcc 4.3.5.
+  memset(Options, 0, sizeof(*Options) * NumOptionInfos);
+
+  // Find start of normal options.
+  for (unsigned i = 0, e = getNumOptions(); i != e; ++i) {
+    unsigned Kind = getInfo(i + 1).Kind;
+    if (Kind == Option::InputClass) {
+      assert(!TheInputOption && "Cannot have multiple input options!");
+      TheInputOption = getOption(i + 1);
+    } else if (Kind == Option::UnknownClass) {
+      assert(!TheUnknownOption && "Cannot have multiple input options!");
+      TheUnknownOption = getOption(i + 1);
+    } else if (Kind != Option::GroupClass) {
+      FirstSearchableIndex = i;
+      break;
+    }
+  }
+  assert(FirstSearchableIndex != 0 && "No searchable options?");
+
+#ifndef NDEBUG
+  // Check that everything after the first searchable option is a
+  // regular option class.
+  for (unsigned i = FirstSearchableIndex, e = getNumOptions(); i != e; ++i) {
+    Option::OptionClass Kind = (Option::OptionClass) getInfo(i + 1).Kind;
+    assert((Kind != Option::InputClass && Kind != Option::UnknownClass &&
+            Kind != Option::GroupClass) &&
+           "Special options should be defined first!");
+  }
+
+  // Check that options are in order.
+  for (unsigned i = FirstSearchableIndex+1, e = getNumOptions(); i != e; ++i) {
+    if (!(getInfo(i) < getInfo(i + 1))) {
+      getOption(i)->dump();
+      getOption(i + 1)->dump();
+      assert(0 && "Options are not in order!");
+    }
+  }
+#endif
+}
+
+OptTable::~OptTable() {
+  for (unsigned i = 0, e = getNumOptions(); i != e; ++i)
+    delete Options[i];
+  delete[] Options;
+}
+
+Option *OptTable::CreateOption(unsigned id) const {
+  const Info &info = getInfo(id);
+  const OptionGroup *Group =
+    cast_or_null<OptionGroup>(getOption(info.GroupID));
+  const Option *Alias = getOption(info.AliasID);
+
+  Option *Opt = 0;
+  switch (info.Kind) {
+  case Option::InputClass:
+    Opt = new InputOption(id); break;
+  case Option::UnknownClass:
+    Opt = new UnknownOption(id); break;
+  case Option::GroupClass:
+    Opt = new OptionGroup(id, info.Name, Group); break;
+  case Option::FlagClass:
+    Opt = new FlagOption(id, info.Name, Group, Alias); break;
+  case Option::JoinedClass:
+    Opt = new JoinedOption(id, info.Name, Group, Alias); break;
+  case Option::SeparateClass:
+    Opt = new SeparateOption(id, info.Name, Group, Alias); break;
+  case Option::CommaJoinedClass:
+    Opt = new CommaJoinedOption(id, info.Name, Group, Alias); break;
+  case Option::MultiArgClass:
+    Opt = new MultiArgOption(id, info.Name, Group, Alias, info.Param); break;
+  case Option::JoinedOrSeparateClass:
+    Opt = new JoinedOrSeparateOption(id, info.Name, Group, Alias); break;
+  case Option::JoinedAndSeparateClass:
+    Opt = new JoinedAndSeparateOption(id, info.Name, Group, Alias); break;
+  }
+
+  if (info.Flags & DriverOption)
+    Opt->setDriverOption(true);
+  if (info.Flags & LinkerInput)
+    Opt->setLinkerInput(true);
+  if (info.Flags & NoArgumentUnused)
+    Opt->setNoArgumentUnused(true);
+  if (info.Flags & RenderAsInput)
+    Opt->setNoOptAsInput(true);
+  if (info.Flags & RenderJoined) {
+    assert((info.Kind == Option::JoinedOrSeparateClass ||
+            info.Kind == Option::SeparateClass) && "Invalid option.");
+    Opt->setForceJoinedRender(true);
+  }
+  if (info.Flags & RenderSeparate) {
+    assert((info.Kind == Option::JoinedOrSeparateClass ||
+            info.Kind == Option::JoinedClass) && "Invalid option.");
+    Opt->setForceSeparateRender(true);
+  }
+  if (info.Flags & Unsupported)
+    Opt->setUnsupported(true);
+
+  return Opt;
+}
+
+Arg *OptTable::ParseOneArg(const InputArgList &Args, unsigned &Index) const {
+  unsigned Prev = Index;
+  const char *Str = Args.getArgString(Index);
+
+  // Anything that doesn't start with '-' is an input, as is '-' itself.
+  if (Str[0] != '-' || Str[1] == '\0')
+    return new PositionalArg(TheInputOption, Index++);
+
+  const Info *Start = OptionInfos + FirstSearchableIndex;
+  const Info *End = OptionInfos + getNumOptions();
+
+  // Search for the first next option which could be a prefix.
+  Start = std::lower_bound(Start, End, Str);
+
+  // Options are stored in sorted order, with '\0' at the end of the
+  // alphabet. Since the only options which can accept a string must
+  // prefix it, we iteratively search for the next option which could
+  // be a prefix.
+  //
+  // FIXME: This is searching much more than necessary, but I am
+  // blanking on the simplest way to make it fast. We can solve this
+  // problem when we move to TableGen.
+  for (; Start != End; ++Start) {
+    // Scan for first option which is a proper prefix.
+    for (; Start != End; ++Start)
+      if (memcmp(Str, Start->Name, strlen(Start->Name)) == 0)
+        break;
+    if (Start == End)
+      break;
+
+    // See if this option matches.
+    if (Arg *A = getOption(Start - OptionInfos + 1)->accept(Args, Index))
+      return A;
+
+    // Otherwise, see if this argument was missing values.
+    if (Prev != Index)
+      return 0;
+  }
+
+  return new PositionalArg(TheUnknownOption, Index++);
+}
+
+InputArgList *OptTable::ParseArgs(const char **ArgBegin, const char **ArgEnd,
+                                  unsigned &MissingArgIndex,
+                                  unsigned &MissingArgCount) const {
+  InputArgList *Args = new InputArgList(ArgBegin, ArgEnd);
+
+  // FIXME: Handle '@' args (or at least error on them).
+
+  MissingArgIndex = MissingArgCount = 0;
+  unsigned Index = 0, End = ArgEnd - ArgBegin;
+  while (Index < End) {
+    // Ignore empty arguments (other things may still take them as arguments).
+    if (Args->getArgString(Index)[0] == '\0') {
+      ++Index;
+      continue;
+    }
+
+    unsigned Prev = Index;
+    Arg *A = ParseOneArg(*Args, Index);
+    assert(Index > Prev && "Parser failed to consume argument.");
+
+    // Check for missing argument error.
+    if (!A) {
+      assert(Index >= End && "Unexpected parser error.");
+      assert(Index - Prev - 1 && "No missing arguments!");
+      MissingArgIndex = Prev;
+      MissingArgCount = Index - Prev - 1;
+      break;
+    }
+
+    Args->append(A);
+  }
+
+  return Args;
+}
+
+static std::string getOptionHelpName(const OptTable &Opts, OptSpecifier Id) {
+  std::string Name = Opts.getOptionName(Id);
+
+  // Add metavar, if used.
+  switch (Opts.getOptionKind(Id)) {
+  case Option::GroupClass: case Option::InputClass: case Option::UnknownClass:
+    assert(0 && "Invalid option with help text.");
+
+  case Option::MultiArgClass: case Option::JoinedAndSeparateClass:
+    assert(0 && "Cannot print metavar for this kind of option.");
+
+  case Option::FlagClass:
+    break;
+
+  case Option::SeparateClass: case Option::JoinedOrSeparateClass:
+    Name += ' ';
+    // FALLTHROUGH
+  case Option::JoinedClass: case Option::CommaJoinedClass:
+    if (const char *MetaVarName = Opts.getOptionMetaVar(Id))
+      Name += MetaVarName;
+    else
+      Name += "<value>";
+    break;
+  }
+
+  return Name;
+}
+
+static void PrintHelpOptionList(llvm::raw_ostream &OS, llvm::StringRef Title,
+                                std::vector<std::pair<std::string,
+                                const char*> > &OptionHelp) {
+  OS << Title << ":\n";
+
+  // Find the maximum option length.
+  unsigned OptionFieldWidth = 0;
+  for (unsigned i = 0, e = OptionHelp.size(); i != e; ++i) {
+    // Skip titles.
+    if (!OptionHelp[i].second)
+      continue;
+
+    // Limit the amount of padding we are willing to give up for alignment.
+    unsigned Length = OptionHelp[i].first.size();
+    if (Length <= 23)
+      OptionFieldWidth = std::max(OptionFieldWidth, Length);
+  }
+
+  const unsigned InitialPad = 2;
+  for (unsigned i = 0, e = OptionHelp.size(); i != e; ++i) {
+    const std::string &Option = OptionHelp[i].first;
+    int Pad = OptionFieldWidth - int(Option.size());
+    OS.indent(InitialPad) << Option;
+
+    // Break on long option names.
+    if (Pad < 0) {
+      OS << "\n";
+      Pad = OptionFieldWidth + InitialPad;
+    }
+    OS.indent(Pad + 1) << OptionHelp[i].second << '\n';
+  }
+}
+
+static const char *getOptionHelpGroup(const OptTable &Opts, OptSpecifier Id) {
+  unsigned GroupID = Opts.getOptionGroupID(Id);
+
+  // If not in a group, return the default help group.
+  if (!GroupID)
+    return "OPTIONS";
+
+  // Abuse the help text of the option groups to store the "help group"
+  // name.
+  //
+  // FIXME: Split out option groups.
+  if (const char *GroupHelp = Opts.getOptionHelpText(GroupID))
+    return GroupHelp;
+
+  // Otherwise keep looking.
+  return getOptionHelpGroup(Opts, GroupID);
+}
+
+void OptTable::PrintHelp(llvm::raw_ostream &OS, const char *Name,
+                         const char *Title, bool ShowHidden) const {
+  OS << "OVERVIEW: " << Title << "\n";
+  OS << '\n';
+  OS << "USAGE: " << Name << " [options] <inputs>\n";
+  OS << '\n';
+
+  // Render help text into a map of group-name to a list of (option, help)
+  // pairs.
+  typedef std::map<std::string,
+                 std::vector<std::pair<std::string, const char*> > > helpmap_ty;
+  helpmap_ty GroupedOptionHelp;
+
+  for (unsigned i = 0, e = getNumOptions(); i != e; ++i) {
+    unsigned Id = i + 1;
+
+    // FIXME: Split out option groups.
+    if (getOptionKind(Id) == Option::GroupClass)
+      continue;
+
+    if (!ShowHidden && isOptionHelpHidden(Id))
+      continue;
+
+    if (const char *Text = getOptionHelpText(Id)) {
+      const char *HelpGroup = getOptionHelpGroup(*this, Id);
+      const std::string &OptName = getOptionHelpName(*this, Id);
+      GroupedOptionHelp[HelpGroup].push_back(std::make_pair(OptName, Text));
+    }
+  }
+
+  for (helpmap_ty::iterator it = GroupedOptionHelp .begin(),
+         ie = GroupedOptionHelp.end(); it != ie; ++it) {
+    if (it != GroupedOptionHelp .begin())
+      OS << "\n";
+    PrintHelpOptionList(OS, it->first, it->second);
+  }
+
+  OS.flush();
+}
diff --git a/lib/Driver/Option.cpp b/lib/Driver/Option.cpp
new file mode 100644
index 0000000..17d00f5
--- /dev/null
+++ b/lib/Driver/Option.cpp
@@ -0,0 +1,232 @@
+//===--- Option.cpp - Abstract Driver Options ---------------------------*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Driver/Option.h"
+
+#include "clang/Driver/Arg.h"
+#include "clang/Driver/ArgList.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cassert>
+#include <algorithm>
+using namespace clang::driver;
+
+Option::Option(OptionClass _Kind, OptSpecifier _ID, const char *_Name,
+               const OptionGroup *_Group, const Option *_Alias)
+  : Kind(_Kind), ID(_ID.getID()), Name(_Name), Group(_Group), Alias(_Alias),
+    Unsupported(false), LinkerInput(false), NoOptAsInput(false),
+    ForceSeparateRender(false), ForceJoinedRender(false),
+    DriverOption(false), NoArgumentUnused(false) {
+
+  // Multi-level aliases are not supported, and alias options cannot
+  // have groups. This just simplifies option tracking, it is not an
+  // inherent limitation.
+  assert((!Alias || (!Alias->Alias && !Group)) &&
+         "Multi-level aliases and aliases with groups are unsupported.");
+}
+
+Option::~Option() {
+}
+
+void Option::dump() const {
+  llvm::errs() << "<";
+  switch (Kind) {
+  default:
+    assert(0 && "Invalid kind");
+#define P(N) case N: llvm::errs() << #N; break
+    P(GroupClass);
+    P(InputClass);
+    P(UnknownClass);
+    P(FlagClass);
+    P(JoinedClass);
+    P(SeparateClass);
+    P(CommaJoinedClass);
+    P(MultiArgClass);
+    P(JoinedOrSeparateClass);
+    P(JoinedAndSeparateClass);
+#undef P
+  }
+
+  llvm::errs() << " Name:\"" << Name << '"';
+
+  if (Group) {
+    llvm::errs() << " Group:";
+    Group->dump();
+  }
+
+  if (Alias) {
+    llvm::errs() << " Alias:";
+    Alias->dump();
+  }
+
+  if (const MultiArgOption *MOA = dyn_cast<MultiArgOption>(this))
+    llvm::errs() << " NumArgs:" << MOA->getNumArgs();
+
+  llvm::errs() << ">\n";
+}
+
+bool Option::matches(OptSpecifier Opt) const {
+  // Aliases are never considered in matching, look through them.
+  if (Alias)
+    return Alias->matches(Opt);
+
+  // Check exact match.
+  if (ID == Opt)
+    return true;
+
+  if (Group)
+    return Group->matches(Opt);
+  return false;
+}
+
+OptionGroup::OptionGroup(OptSpecifier ID, const char *Name,
+                         const OptionGroup *Group)
+  : Option(Option::GroupClass, ID, Name, Group, 0) {
+}
+
+Arg *OptionGroup::accept(const InputArgList &Args, unsigned &Index) const {
+  assert(0 && "accept() should never be called on an OptionGroup");
+  return 0;
+}
+
+InputOption::InputOption(OptSpecifier ID)
+  : Option(Option::InputClass, ID, "<input>", 0, 0) {
+}
+
+Arg *InputOption::accept(const InputArgList &Args, unsigned &Index) const {
+  assert(0 && "accept() should never be called on an InputOption");
+  return 0;
+}
+
+UnknownOption::UnknownOption(OptSpecifier ID)
+  : Option(Option::UnknownClass, ID, "<unknown>", 0, 0) {
+}
+
+Arg *UnknownOption::accept(const InputArgList &Args, unsigned &Index) const {
+  assert(0 && "accept() should never be called on an UnknownOption");
+  return 0;
+}
+
+FlagOption::FlagOption(OptSpecifier ID, const char *Name,
+                       const OptionGroup *Group, const Option *Alias)
+  : Option(Option::FlagClass, ID, Name, Group, Alias) {
+}
+
+Arg *FlagOption::accept(const InputArgList &Args, unsigned &Index) const {
+  // Matches iff this is an exact match.
+  // FIXME: Avoid strlen.
+  if (strlen(getName()) != strlen(Args.getArgString(Index)))
+    return 0;
+
+  return new FlagArg(this, Index++);
+}
+
+JoinedOption::JoinedOption(OptSpecifier ID, const char *Name,
+                           const OptionGroup *Group, const Option *Alias)
+  : Option(Option::JoinedClass, ID, Name, Group, Alias) {
+}
+
+Arg *JoinedOption::accept(const InputArgList &Args, unsigned &Index) const {
+  // Always matches.
+  return new JoinedArg(this, Index++);
+}
+
+CommaJoinedOption::CommaJoinedOption(OptSpecifier ID, const char *Name,
+                                     const OptionGroup *Group,
+                                     const Option *Alias)
+  : Option(Option::CommaJoinedClass, ID, Name, Group, Alias) {
+}
+
+Arg *CommaJoinedOption::accept(const InputArgList &Args,
+                               unsigned &Index) const {
+  // Always matches. We count the commas now so we can answer
+  // getNumValues easily.
+
+  // Get the suffix string.
+  // FIXME: Avoid strlen, and move to helper method?
+  const char *Suffix = Args.getArgString(Index) + strlen(getName());
+  return new CommaJoinedArg(this, Index++, Suffix);
+}
+
+SeparateOption::SeparateOption(OptSpecifier ID, const char *Name,
+                               const OptionGroup *Group, const Option *Alias)
+  : Option(Option::SeparateClass, ID, Name, Group, Alias) {
+}
+
+Arg *SeparateOption::accept(const InputArgList &Args, unsigned &Index) const {
+  // Matches iff this is an exact match.
+  // FIXME: Avoid strlen.
+  if (strlen(getName()) != strlen(Args.getArgString(Index)))
+    return 0;
+
+  Index += 2;
+  if (Index > Args.getNumInputArgStrings())
+    return 0;
+
+  return new SeparateArg(this, Index - 2, 1);
+}
+
+MultiArgOption::MultiArgOption(OptSpecifier ID, const char *Name,
+                               const OptionGroup *Group, const Option *Alias,
+                               unsigned _NumArgs)
+  : Option(Option::MultiArgClass, ID, Name, Group, Alias), NumArgs(_NumArgs) {
+  assert(NumArgs > 1  && "Invalid MultiArgOption!");
+}
+
+Arg *MultiArgOption::accept(const InputArgList &Args, unsigned &Index) const {
+  // Matches iff this is an exact match.
+  // FIXME: Avoid strlen.
+  if (strlen(getName()) != strlen(Args.getArgString(Index)))
+    return 0;
+
+  Index += 1 + NumArgs;
+  if (Index > Args.getNumInputArgStrings())
+    return 0;
+
+  return new SeparateArg(this, Index - 1 - NumArgs, NumArgs);
+}
+
+JoinedOrSeparateOption::JoinedOrSeparateOption(OptSpecifier ID, const char *Name,
+                                               const OptionGroup *Group,
+                                               const Option *Alias)
+  : Option(Option::JoinedOrSeparateClass, ID, Name, Group, Alias) {
+}
+
+Arg *JoinedOrSeparateOption::accept(const InputArgList &Args,
+                                    unsigned &Index) const {
+  // If this is not an exact match, it is a joined arg.
+  // FIXME: Avoid strlen.
+  if (strlen(getName()) != strlen(Args.getArgString(Index)))
+    return new JoinedArg(this, Index++);
+
+  // Otherwise it must be separate.
+  Index += 2;
+  if (Index > Args.getNumInputArgStrings())
+    return 0;
+
+  return new SeparateArg(this, Index - 2, 1);
+}
+
+JoinedAndSeparateOption::JoinedAndSeparateOption(OptSpecifier ID,
+                                                 const char *Name,
+                                                 const OptionGroup *Group,
+                                                 const Option *Alias)
+  : Option(Option::JoinedAndSeparateClass, ID, Name, Group, Alias) {
+}
+
+Arg *JoinedAndSeparateOption::accept(const InputArgList &Args,
+                                     unsigned &Index) const {
+  // Always matches.
+
+  Index += 2;
+  if (Index > Args.getNumInputArgStrings())
+    return 0;
+
+  return new JoinedAndSeparateArg(this, Index - 2);
+}
+
diff --git a/lib/Driver/Phases.cpp b/lib/Driver/Phases.cpp
new file mode 100644
index 0000000..df4cdee
--- /dev/null
+++ b/lib/Driver/Phases.cpp
@@ -0,0 +1,27 @@
+//===--- Phases.cpp - Transformations on Driver Types -------------------*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Driver/Phases.h"
+
+#include <cassert>
+
+using namespace clang::driver;
+
+const char *phases::getPhaseName(ID Id) {
+  switch (Id) {
+  case Preprocess: return "preprocessor";
+  case Precompile: return "precompiler";
+  case Compile: return "compiler";
+  case Assemble: return "assembler";
+  case Link: return "linker";
+  }
+
+  assert(0 && "Invalid phase id.");
+  return 0;
+}
diff --git a/lib/Driver/Tool.cpp b/lib/Driver/Tool.cpp
new file mode 100644
index 0000000..781e0a7
--- /dev/null
+++ b/lib/Driver/Tool.cpp
@@ -0,0 +1,19 @@
+//===--- Tool.cpp - Compilation Tools -----------------------------------*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Driver/Tool.h"
+
+using namespace clang::driver;
+
+Tool::Tool(const char *_Name, const ToolChain &TC) : Name(_Name),
+                                                     TheToolChain(TC) {
+}
+
+Tool::~Tool() {
+}
diff --git a/lib/Driver/ToolChain.cpp b/lib/Driver/ToolChain.cpp
new file mode 100644
index 0000000..9b6264a
--- /dev/null
+++ b/lib/Driver/ToolChain.cpp
@@ -0,0 +1,39 @@
+//===--- ToolChain.cpp - Collections of tools for one platform ----------*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Driver/ToolChain.h"
+
+#include "clang/Driver/Action.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/HostInfo.h"
+
+using namespace clang::driver;
+
+ToolChain::ToolChain(const HostInfo &_Host, const llvm::Triple &_Triple)
+  : Host(_Host), Triple(_Triple) {
+}
+
+ToolChain::~ToolChain() {
+}
+
+const Driver &ToolChain::getDriver() const {
+ return Host.getDriver();
+}
+
+std::string ToolChain::GetFilePath(const Compilation &C,
+                                   const char *Name) const {
+  return Host.getDriver().GetFilePath(Name, *this);
+
+}
+
+std::string ToolChain::GetProgramPath(const Compilation &C,
+                                      const char *Name,
+                                      bool WantFile) const {
+  return Host.getDriver().GetProgramPath(Name, *this, WantFile);
+}
diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp
new file mode 100644
index 0000000..1cd8ee1
--- /dev/null
+++ b/lib/Driver/ToolChains.cpp
@@ -0,0 +1,973 @@
+//===--- ToolChains.cpp - ToolChain Implementations ---------------------*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ToolChains.h"
+
+#include "clang/Driver/Arg.h"
+#include "clang/Driver/ArgList.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/DriverDiagnostic.h"
+#include "clang/Driver/HostInfo.h"
+#include "clang/Driver/OptTable.h"
+#include "clang/Driver/Option.h"
+#include "clang/Driver/Options.h"
+
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/System/Path.h"
+
+#include <cstdlib> // ::getenv
+
+using namespace clang::driver;
+using namespace clang::driver::toolchains;
+
+/// Darwin - Darwin tool chain for i386 and x86_64.
+
+Darwin::Darwin(const HostInfo &Host, const llvm::Triple& Triple,
+               const unsigned (&_DarwinVersion)[3])
+  : ToolChain(Host, Triple), TargetInitialized(false)
+{
+  llvm::raw_string_ostream(MacosxVersionMin)
+    << "10." << std::max(0, (int)_DarwinVersion[0] - 4) << '.'
+    << _DarwinVersion[1];
+}
+
+// FIXME: Can we tablegen this?
+static const char *GetArmArchForMArch(llvm::StringRef Value) {
+  if (Value == "armv6k")
+    return "armv6";
+
+  if (Value == "armv5tej")
+    return "armv5";
+
+  if (Value == "xscale")
+    return "xscale";
+
+  if (Value == "armv4t")
+    return "armv4t";
+
+  if (Value == "armv7" || Value == "armv7-a" || Value == "armv7-r" ||
+      Value == "armv7-m" || Value == "armv7a" || Value == "armv7r" ||
+      Value == "armv7m")
+    return "armv7";
+
+  return 0;
+}
+
+// FIXME: Can we tablegen this?
+static const char *GetArmArchForMCpu(llvm::StringRef Value) {
+  if (Value == "arm10tdmi" || Value == "arm1020t" || Value == "arm9e" ||
+      Value == "arm946e-s" || Value == "arm966e-s" ||
+      Value == "arm968e-s" || Value == "arm10e" ||
+      Value == "arm1020e" || Value == "arm1022e" || Value == "arm926ej-s" ||
+      Value == "arm1026ej-s")
+    return "armv5";
+
+  if (Value == "xscale")
+    return "xscale";
+
+  if (Value == "arm1136j-s" || Value == "arm1136jf-s" ||
+      Value == "arm1176jz-s" || Value == "arm1176jzf-s")
+    return "armv6";
+
+  if (Value == "cortex-a8" || Value == "cortex-r4" || Value == "cortex-m3")
+    return "armv7";
+
+  return 0;
+}
+
+llvm::StringRef Darwin::getDarwinArchName(const ArgList &Args) const {
+  switch (getTriple().getArch()) {
+  default:
+    return getArchName();
+
+  case llvm::Triple::arm: {
+    if (const Arg *A = Args.getLastArg(options::OPT_march_EQ))
+      if (const char *Arch = GetArmArchForMArch(A->getValue(Args)))
+        return Arch;
+
+    if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
+      if (const char *Arch = GetArmArchForMCpu(A->getValue(Args)))
+        return Arch;
+
+    return "arm";
+  }
+  }
+}
+
+DarwinGCC::DarwinGCC(const HostInfo &Host, const llvm::Triple& Triple,
+                     const unsigned (&DarwinVersion)[3],
+                     const unsigned (&_GCCVersion)[3])
+  : Darwin(Host, Triple, DarwinVersion)
+{
+  GCCVersion[0] = _GCCVersion[0];
+  GCCVersion[1] = _GCCVersion[1];
+  GCCVersion[2] = _GCCVersion[2];
+
+  // Set up the tool chain paths to match gcc.
+  ToolChainDir = "i686-apple-darwin";
+  ToolChainDir += llvm::utostr(DarwinVersion[0]);
+  ToolChainDir += "/";
+  ToolChainDir += llvm::utostr(GCCVersion[0]);
+  ToolChainDir += '.';
+  ToolChainDir += llvm::utostr(GCCVersion[1]);
+  ToolChainDir += '.';
+  ToolChainDir += llvm::utostr(GCCVersion[2]);
+
+  // Try the next major version if that tool chain dir is invalid.
+  std::string Tmp = "/usr/lib/gcc/" + ToolChainDir;
+  if (!llvm::sys::Path(Tmp).exists()) {
+    std::string Next = "i686-apple-darwin";
+    Next += llvm::utostr(DarwinVersion[0] + 1);
+    Next += "/";
+    Next += llvm::utostr(GCCVersion[0]);
+    Next += '.';
+    Next += llvm::utostr(GCCVersion[1]);
+    Next += '.';
+    Next += llvm::utostr(GCCVersion[2]);
+
+    // Use that if it exists, otherwise hope the user isn't linking.
+    //
+    // FIXME: Drop dependency on gcc's tool chain.
+    Tmp = "/usr/lib/gcc/" + Next;
+    if (llvm::sys::Path(Tmp).exists())
+      ToolChainDir = Next;
+  }
+
+  std::string Path;
+  if (getArchName() == "x86_64") {
+    Path = getDriver().Dir;
+    Path += "/../lib/gcc/";
+    Path += ToolChainDir;
+    Path += "/x86_64";
+    getFilePaths().push_back(Path);
+
+    Path = "/usr/lib/gcc/";
+    Path += ToolChainDir;
+    Path += "/x86_64";
+    getFilePaths().push_back(Path);
+  }
+
+  Path = getDriver().Dir;
+  Path += "/../lib/gcc/";
+  Path += ToolChainDir;
+  getFilePaths().push_back(Path);
+
+  Path = "/usr/lib/gcc/";
+  Path += ToolChainDir;
+  getFilePaths().push_back(Path);
+
+  Path = getDriver().Dir;
+  Path += "/../libexec/gcc/";
+  Path += ToolChainDir;
+  getProgramPaths().push_back(Path);
+
+  Path = "/usr/libexec/gcc/";
+  Path += ToolChainDir;
+  getProgramPaths().push_back(Path);
+
+  getProgramPaths().push_back(getDriver().Dir);
+}
+
+Darwin::~Darwin() {
+  // Free tool implementations.
+  for (llvm::DenseMap<unsigned, Tool*>::iterator
+         it = Tools.begin(), ie = Tools.end(); it != ie; ++it)
+    delete it->second;
+}
+
+Tool &Darwin::SelectTool(const Compilation &C, const JobAction &JA) const {
+  Action::ActionClass Key;
+  if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
+    Key = Action::AnalyzeJobClass;
+  else
+    Key = JA.getKind();
+
+  Tool *&T = Tools[Key];
+  if (!T) {
+    switch (Key) {
+    case Action::InputClass:
+    case Action::BindArchClass:
+      assert(0 && "Invalid tool kind.");
+    case Action::PreprocessJobClass:
+      T = new tools::darwin::Preprocess(*this); break;
+    case Action::AnalyzeJobClass:
+      T = new tools::Clang(*this); break;
+    case Action::PrecompileJobClass:
+    case Action::CompileJobClass:
+      T = new tools::darwin::Compile(*this); break;
+    case Action::AssembleJobClass:
+      T = new tools::darwin::Assemble(*this); break;
+    case Action::LinkJobClass:
+      T = new tools::darwin::Link(*this); break;
+    case Action::LipoJobClass:
+      T = new tools::darwin::Lipo(*this); break;
+    }
+  }
+
+  return *T;
+}
+
+void DarwinGCC::AddLinkSearchPathArgs(const ArgList &Args,
+                                      ArgStringList &CmdArgs) const {
+  std::string Tmp;
+
+  // FIXME: Derive these correctly.
+  if (getArchName() == "x86_64") {
+    CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc/" + ToolChainDir +
+                                         "/x86_64"));
+    // Intentionally duplicated for (temporary) gcc bug compatibility.
+    CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc/" + ToolChainDir +
+                                         "/x86_64"));
+  }
+  
+  CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/" + ToolChainDir));
+
+  Tmp = getDriver().Dir + "/../lib/gcc/" + ToolChainDir;
+  if (llvm::sys::Path(Tmp).exists())
+    CmdArgs.push_back(Args.MakeArgString("-L" + Tmp));
+  Tmp = getDriver().Dir + "/../lib/gcc";
+  if (llvm::sys::Path(Tmp).exists())
+    CmdArgs.push_back(Args.MakeArgString("-L" + Tmp));
+  CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc/" + ToolChainDir));
+  // Intentionally duplicated for (temporary) gcc bug compatibility.
+  CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc/" + ToolChainDir));
+  Tmp = getDriver().Dir + "/../lib/" + ToolChainDir;
+  if (llvm::sys::Path(Tmp).exists())
+    CmdArgs.push_back(Args.MakeArgString("-L" + Tmp));
+  Tmp = getDriver().Dir + "/../lib";
+  if (llvm::sys::Path(Tmp).exists())
+    CmdArgs.push_back(Args.MakeArgString("-L" + Tmp));
+  CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc/" + ToolChainDir +
+                                       "/../../../" + ToolChainDir));
+  CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc/" + ToolChainDir +
+                                       "/../../.."));
+}
+
+void DarwinGCC::AddLinkRuntimeLibArgs(const ArgList &Args,
+                                      ArgStringList &CmdArgs) const {
+  // Note that this routine is only used for targetting OS X.
+
+  // Derived from libgcc and lib specs but refactored.
+  if (Args.hasArg(options::OPT_static)) {
+    CmdArgs.push_back("-lgcc_static");
+  } else {
+    if (Args.hasArg(options::OPT_static_libgcc)) {
+      CmdArgs.push_back("-lgcc_eh");
+    } else if (Args.hasArg(options::OPT_miphoneos_version_min_EQ)) {
+      // Derived from darwin_iphoneos_libgcc spec.
+      if (isTargetIPhoneOS()) {
+        CmdArgs.push_back("-lgcc_s.1");
+      } else {
+        CmdArgs.push_back("-lgcc_s.10.5");
+      }
+    } else if (Args.hasArg(options::OPT_shared_libgcc) ||
+               Args.hasFlag(options::OPT_fexceptions,
+                            options::OPT_fno_exceptions) ||
+               Args.hasArg(options::OPT_fgnu_runtime)) {
+      // FIXME: This is probably broken on 10.3?
+      if (isMacosxVersionLT(10, 5))
+        CmdArgs.push_back("-lgcc_s.10.4");
+      else if (isMacosxVersionLT(10, 6))
+        CmdArgs.push_back("-lgcc_s.10.5");
+    } else {
+      if (isMacosxVersionLT(10, 3, 9))
+        ; // Do nothing.
+      else if (isMacosxVersionLT(10, 5))
+        CmdArgs.push_back("-lgcc_s.10.4");
+      else if (isMacosxVersionLT(10, 6))
+        CmdArgs.push_back("-lgcc_s.10.5");
+    }
+
+    if (isTargetIPhoneOS() || isMacosxVersionLT(10, 6)) {
+      CmdArgs.push_back("-lgcc");
+      CmdArgs.push_back("-lSystem");
+    } else {
+      CmdArgs.push_back("-lSystem");
+      CmdArgs.push_back("-lgcc");
+    }
+  }
+}
+
+DarwinClang::DarwinClang(const HostInfo &Host, const llvm::Triple& Triple,
+                         const unsigned (&DarwinVersion)[3])
+  : Darwin(Host, Triple, DarwinVersion)
+{
+  // We expect 'as', 'ld', etc. to be adjacent to our install dir.
+  getProgramPaths().push_back(getDriver().Dir);
+}
+
+void DarwinClang::AddLinkSearchPathArgs(const ArgList &Args,
+                                       ArgStringList &CmdArgs) const {
+  // The Clang toolchain uses explicit paths for internal libraries.
+}
+
+void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args,
+                                        ArgStringList &CmdArgs) const {
+  // Darwin doesn't support real static executables, don't link any runtime
+  // libraries with -static.
+  if (Args.hasArg(options::OPT_static))
+    return;
+
+  // Reject -static-libgcc for now, we can deal with this when and if someone
+  // cares. This is useful in situations where someone wants to statically link
+  // something like libstdc++, and needs its runtime support routines.
+  if (const Arg *A = Args.getLastArg(options::OPT_static_libgcc)) {
+    getDriver().Diag(clang::diag::err_drv_unsupported_opt)
+      << A->getAsString(Args);
+    return;
+  }
+
+  // Otherwise link libSystem, then the dynamic runtime library, and finally any
+  // target specific static runtime library.
+  CmdArgs.push_back("-lSystem");
+
+  // Select the dynamic runtime library and the target specific static library.
+  const char *DarwinStaticLib = 0;
+  if (isTargetIPhoneOS()) {
+    CmdArgs.push_back("-lgcc_s.1");
+
+    // We may need some static functions for armv6/thumb which are required to
+    // be in the same linkage unit as their caller.
+    if (getDarwinArchName(Args) == "armv6")
+      DarwinStaticLib = "libclang_rt.armv6.a";
+  } else {
+    // The dynamic runtime library was merged with libSystem for 10.6 and
+    // beyond; only 10.4 and 10.5 need an additional runtime library.
+    if (isMacosxVersionLT(10, 5))
+      CmdArgs.push_back("-lgcc_s.10.4");
+    else if (isMacosxVersionLT(10, 6))
+      CmdArgs.push_back("-lgcc_s.10.5");
+
+    // For OS X, we only need a static runtime library when targetting 10.4, to
+    // provide versions of the static functions which were omitted from
+    // 10.4.dylib.
+    if (isMacosxVersionLT(10, 5))
+      DarwinStaticLib = "libclang_rt.10.4.a";
+  }
+
+  /// Add the target specific static library, if needed.
+  if (DarwinStaticLib) {
+    llvm::sys::Path P(getDriver().ResourceDir);
+    P.appendComponent("lib");
+    P.appendComponent("darwin");
+    P.appendComponent(DarwinStaticLib);
+
+    // For now, allow missing resource libraries to support developers who may
+    // not have compiler-rt checked out or integrated into their build.
+    if (!P.exists())
+      getDriver().Diag(clang::diag::warn_drv_missing_resource_library)
+        << P.str();
+    else
+      CmdArgs.push_back(Args.MakeArgString(P.str()));
+  }
+}
+
+DerivedArgList *Darwin::TranslateArgs(InputArgList &Args,
+                                      const char *BoundArch) const {
+  DerivedArgList *DAL = new DerivedArgList(Args, false);
+  const OptTable &Opts = getDriver().getOpts();
+
+  // FIXME: We really want to get out of the tool chain level argument
+  // translation business, as it makes the driver functionality much
+  // more opaque. For now, we follow gcc closely solely for the
+  // purpose of easily achieving feature parity & testability. Once we
+  // have something that works, we should reevaluate each translation
+  // and try to push it down into tool specific logic.
+
+  Arg *OSXVersion = Args.getLastArg(options::OPT_mmacosx_version_min_EQ);
+  Arg *iPhoneVersion = Args.getLastArg(options::OPT_miphoneos_version_min_EQ);
+  if (OSXVersion && iPhoneVersion) {
+    getDriver().Diag(clang::diag::err_drv_argument_not_allowed_with)
+          << OSXVersion->getAsString(Args)
+          << iPhoneVersion->getAsString(Args);
+    iPhoneVersion = 0;
+  } else if (!OSXVersion && !iPhoneVersion) {
+    // If neither OS X nor iPhoneOS targets were specified, check for
+    // environment defines.
+    const char *OSXTarget = ::getenv("MACOSX_DEPLOYMENT_TARGET");
+    const char *iPhoneOSTarget = ::getenv("IPHONEOS_DEPLOYMENT_TARGET");
+
+    // Ignore empty strings.
+    if (OSXTarget && OSXTarget[0] == '\0')
+      OSXTarget = 0;
+    if (iPhoneOSTarget && iPhoneOSTarget[0] == '\0')
+      iPhoneOSTarget = 0;
+
+    // Diagnose conflicting deployment targets, and choose default platform
+    // based on the tool chain.
+    //
+    // FIXME: Don't hardcode default here.
+    if (OSXTarget && iPhoneOSTarget) {
+      // FIXME: We should see if we can get away with warning or erroring on
+      // this. Perhaps put under -pedantic?
+      if (getTriple().getArch() == llvm::Triple::arm ||
+          getTriple().getArch() == llvm::Triple::thumb)
+        OSXTarget = 0;
+      else
+        iPhoneOSTarget = 0;
+    }
+
+    if (OSXTarget) {
+      const Option *O = Opts.getOption(options::OPT_mmacosx_version_min_EQ);
+      OSXVersion = DAL->MakeJoinedArg(0, O, OSXTarget);
+      DAL->append(OSXVersion);
+    } else if (iPhoneOSTarget) {
+      const Option *O = Opts.getOption(options::OPT_miphoneos_version_min_EQ);
+      iPhoneVersion = DAL->MakeJoinedArg(0, O, iPhoneOSTarget);
+      DAL->append(iPhoneVersion);
+    } else {
+      // Otherwise, choose a default platform based on the tool chain.
+      //
+      // FIXME: Don't hardcode default here.
+      if (getTriple().getArch() == llvm::Triple::arm ||
+          getTriple().getArch() == llvm::Triple::thumb) {
+        const Option *O = Opts.getOption(options::OPT_miphoneos_version_min_EQ);
+        iPhoneVersion = DAL->MakeJoinedArg(0, O, "3.0");
+        DAL->append(iPhoneVersion);
+      } else {
+        const Option *O = Opts.getOption(options::OPT_mmacosx_version_min_EQ);
+        OSXVersion = DAL->MakeJoinedArg(0, O, MacosxVersionMin);
+        DAL->append(OSXVersion);
+      }
+    }
+  }
+
+  // Set the tool chain target information.
+  unsigned Major, Minor, Micro;
+  bool HadExtra;
+  if (OSXVersion) {
+    assert(!iPhoneVersion && "Unknown target platform!");
+    if (!Driver::GetReleaseVersion(OSXVersion->getValue(Args), Major, Minor,
+                                   Micro, HadExtra) || HadExtra ||
+        Major != 10 || Minor >= 10 || Micro >= 10)
+      getDriver().Diag(clang::diag::err_drv_invalid_version_number)
+        << OSXVersion->getAsString(Args);
+  } else {
+    assert(iPhoneVersion && "Unknown target platform!");
+    if (!Driver::GetReleaseVersion(iPhoneVersion->getValue(Args), Major, Minor,
+                                   Micro, HadExtra) || HadExtra ||
+        Major >= 10 || Minor >= 100 || Micro >= 100)
+      getDriver().Diag(clang::diag::err_drv_invalid_version_number)
+        << iPhoneVersion->getAsString(Args);
+  }
+  setTarget(iPhoneVersion, Major, Minor, Micro);
+
+  for (ArgList::iterator it = Args.begin(), ie = Args.end(); it != ie; ++it) {
+    Arg *A = *it;
+
+    if (A->getOption().matches(options::OPT_Xarch__)) {
+      // FIXME: Canonicalize name.
+      if (getArchName() != A->getValue(Args, 0))
+        continue;
+
+      // FIXME: The arg is leaked here, and we should have a nicer
+      // interface for this.
+      unsigned Prev, Index = Prev = A->getIndex() + 1;
+      Arg *XarchArg = Opts.ParseOneArg(Args, Index);
+
+      // If the argument parsing failed or more than one argument was
+      // consumed, the -Xarch_ argument's parameter tried to consume
+      // extra arguments. Emit an error and ignore.
+      //
+      // We also want to disallow any options which would alter the
+      // driver behavior; that isn't going to work in our model. We
+      // use isDriverOption() as an approximation, although things
+      // like -O4 are going to slip through.
+      if (!XarchArg || Index > Prev + 1 ||
+          XarchArg->getOption().isDriverOption()) {
+       getDriver().Diag(clang::diag::err_drv_invalid_Xarch_argument)
+          << A->getAsString(Args);
+        continue;
+      }
+
+      XarchArg->setBaseArg(A);
+      A = XarchArg;
+    }
+
+    // Sob. These is strictly gcc compatible for the time being. Apple
+    // gcc translates options twice, which means that self-expanding
+    // options add duplicates.
+    switch ((options::ID) A->getOption().getID()) {
+    default:
+      DAL->append(A);
+      break;
+
+    case options::OPT_mkernel:
+    case options::OPT_fapple_kext:
+      DAL->append(A);
+      DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_static)));
+      DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_static)));
+      break;
+
+    case options::OPT_dependency_file:
+      DAL->append(DAL->MakeSeparateArg(A, Opts.getOption(options::OPT_MF),
+                                       A->getValue(Args)));
+      break;
+
+    case options::OPT_gfull:
+      DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_g_Flag)));
+      DAL->append(DAL->MakeFlagArg(A,
+             Opts.getOption(options::OPT_fno_eliminate_unused_debug_symbols)));
+      break;
+
+    case options::OPT_gused:
+      DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_g_Flag)));
+      DAL->append(DAL->MakeFlagArg(A,
+             Opts.getOption(options::OPT_feliminate_unused_debug_symbols)));
+      break;
+
+    case options::OPT_fterminated_vtables:
+    case options::OPT_findirect_virtual_calls:
+      DAL->append(DAL->MakeFlagArg(A,
+                                   Opts.getOption(options::OPT_fapple_kext)));
+      DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_static)));
+      break;
+
+    case options::OPT_shared:
+      DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_dynamiclib)));
+      break;
+
+    case options::OPT_fconstant_cfstrings:
+      DAL->append(DAL->MakeFlagArg(A,
+                             Opts.getOption(options::OPT_mconstant_cfstrings)));
+      break;
+
+    case options::OPT_fno_constant_cfstrings:
+      DAL->append(DAL->MakeFlagArg(A,
+                          Opts.getOption(options::OPT_mno_constant_cfstrings)));
+      break;
+
+    case options::OPT_Wnonportable_cfstrings:
+      DAL->append(DAL->MakeFlagArg(A,
+                     Opts.getOption(options::OPT_mwarn_nonportable_cfstrings)));
+      break;
+
+    case options::OPT_Wno_nonportable_cfstrings:
+      DAL->append(DAL->MakeFlagArg(A,
+                  Opts.getOption(options::OPT_mno_warn_nonportable_cfstrings)));
+      break;
+
+    case options::OPT_fpascal_strings:
+      DAL->append(DAL->MakeFlagArg(A,
+                                 Opts.getOption(options::OPT_mpascal_strings)));
+      break;
+
+    case options::OPT_fno_pascal_strings:
+      DAL->append(DAL->MakeFlagArg(A,
+                              Opts.getOption(options::OPT_mno_pascal_strings)));
+      break;
+    }
+  }
+
+  if (getTriple().getArch() == llvm::Triple::x86 ||
+      getTriple().getArch() == llvm::Triple::x86_64)
+    if (!Args.hasArgNoClaim(options::OPT_mtune_EQ))
+      DAL->append(DAL->MakeJoinedArg(0, Opts.getOption(options::OPT_mtune_EQ),
+                                     "core2"));
+
+  // Add the arch options based on the particular spelling of -arch, to match
+  // how the driver driver works.
+  if (BoundArch) {
+    llvm::StringRef Name = BoundArch;
+    const Option *MCpu = Opts.getOption(options::OPT_mcpu_EQ);
+    const Option *MArch = Opts.getOption(options::OPT_march_EQ);
+
+    // This code must be kept in sync with LLVM's getArchTypeForDarwinArch,
+    // which defines the list of which architectures we accept.
+    if (Name == "ppc")
+      ;
+    else if (Name == "ppc601")
+      DAL->append(DAL->MakeJoinedArg(0, MCpu, "601"));
+    else if (Name == "ppc603")
+      DAL->append(DAL->MakeJoinedArg(0, MCpu, "603"));
+    else if (Name == "ppc604")
+      DAL->append(DAL->MakeJoinedArg(0, MCpu, "604"));
+    else if (Name == "ppc604e")
+      DAL->append(DAL->MakeJoinedArg(0, MCpu, "604e"));
+    else if (Name == "ppc750")
+      DAL->append(DAL->MakeJoinedArg(0, MCpu, "750"));
+    else if (Name == "ppc7400")
+      DAL->append(DAL->MakeJoinedArg(0, MCpu, "7400"));
+    else if (Name == "ppc7450")
+      DAL->append(DAL->MakeJoinedArg(0, MCpu, "7450"));
+    else if (Name == "ppc970")
+      DAL->append(DAL->MakeJoinedArg(0, MCpu, "970"));
+
+    else if (Name == "ppc64")
+      DAL->append(DAL->MakeFlagArg(0, Opts.getOption(options::OPT_m64)));
+
+    else if (Name == "i386")
+      ;
+    else if (Name == "i486")
+      DAL->append(DAL->MakeJoinedArg(0, MArch, "i486"));
+    else if (Name == "i586")
+      DAL->append(DAL->MakeJoinedArg(0, MArch, "i586"));
+    else if (Name == "i686")
+      DAL->append(DAL->MakeJoinedArg(0, MArch, "i686"));
+    else if (Name == "pentium")
+      DAL->append(DAL->MakeJoinedArg(0, MArch, "pentium"));
+    else if (Name == "pentium2")
+      DAL->append(DAL->MakeJoinedArg(0, MArch, "pentium2"));
+    else if (Name == "pentpro")
+      DAL->append(DAL->MakeJoinedArg(0, MArch, "pentiumpro"));
+    else if (Name == "pentIIm3")
+      DAL->append(DAL->MakeJoinedArg(0, MArch, "pentium2"));
+
+    else if (Name == "x86_64")
+      DAL->append(DAL->MakeFlagArg(0, Opts.getOption(options::OPT_m64)));
+
+    else if (Name == "arm")
+      DAL->append(DAL->MakeJoinedArg(0, MArch, "armv4t"));
+    else if (Name == "armv4t")
+      DAL->append(DAL->MakeJoinedArg(0, MArch, "armv4t"));
+    else if (Name == "armv5")
+      DAL->append(DAL->MakeJoinedArg(0, MArch, "armv5tej"));
+    else if (Name == "xscale")
+      DAL->append(DAL->MakeJoinedArg(0, MArch, "xscale"));
+    else if (Name == "armv6")
+      DAL->append(DAL->MakeJoinedArg(0, MArch, "armv6k"));
+    else if (Name == "armv7")
+      DAL->append(DAL->MakeJoinedArg(0, MArch, "armv7a"));
+
+    else
+      llvm_unreachable("invalid Darwin arch");
+  }
+
+  return DAL;
+}
+
+bool Darwin::IsUnwindTablesDefault() const {
+  // FIXME: Gross; we should probably have some separate target
+  // definition, possibly even reusing the one in clang.
+  return getArchName() == "x86_64";
+}
+
+bool Darwin::UseDwarfDebugFlags() const {
+  if (const char *S = ::getenv("RC_DEBUG_OPTIONS"))
+    return S[0] != '\0';
+  return false;
+}
+
+bool Darwin::UseSjLjExceptions() const {
+  // Darwin uses SjLj exceptions on ARM.
+  return (getTriple().getArch() == llvm::Triple::arm ||
+          getTriple().getArch() == llvm::Triple::thumb);
+}
+
+const char *Darwin::GetDefaultRelocationModel() const {
+  return "pic";
+}
+
+const char *Darwin::GetForcedPicModel() const {
+  if (getArchName() == "x86_64")
+    return "pic";
+  return 0;
+}
+
+bool Darwin::SupportsObjCGC() const {
+  // Garbage collection is supported everywhere except on iPhone OS.
+  return !isTargetIPhoneOS();
+}
+
+/// Generic_GCC - A tool chain using the 'gcc' command to perform
+/// all subcommands; this relies on gcc translating the majority of
+/// command line options.
+
+Generic_GCC::Generic_GCC(const HostInfo &Host, const llvm::Triple& Triple)
+  : ToolChain(Host, Triple) {
+  getProgramPaths().push_back(getDriver().Dir);
+}
+
+Generic_GCC::~Generic_GCC() {
+  // Free tool implementations.
+  for (llvm::DenseMap<unsigned, Tool*>::iterator
+         it = Tools.begin(), ie = Tools.end(); it != ie; ++it)
+    delete it->second;
+}
+
+Tool &Generic_GCC::SelectTool(const Compilation &C,
+                              const JobAction &JA) const {
+  Action::ActionClass Key;
+  if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
+    Key = Action::AnalyzeJobClass;
+  else
+    Key = JA.getKind();
+
+  Tool *&T = Tools[Key];
+  if (!T) {
+    switch (Key) {
+    case Action::InputClass:
+    case Action::BindArchClass:
+      assert(0 && "Invalid tool kind.");
+    case Action::PreprocessJobClass:
+      T = new tools::gcc::Preprocess(*this); break;
+    case Action::PrecompileJobClass:
+      T = new tools::gcc::Precompile(*this); break;
+    case Action::AnalyzeJobClass:
+      T = new tools::Clang(*this); break;
+    case Action::CompileJobClass:
+      T = new tools::gcc::Compile(*this); break;
+    case Action::AssembleJobClass:
+      T = new tools::gcc::Assemble(*this); break;
+    case Action::LinkJobClass:
+      T = new tools::gcc::Link(*this); break;
+
+      // This is a bit ungeneric, but the only platform using a driver
+      // driver is Darwin.
+    case Action::LipoJobClass:
+      T = new tools::darwin::Lipo(*this); break;
+    }
+  }
+
+  return *T;
+}
+
+bool Generic_GCC::IsUnwindTablesDefault() const {
+  // FIXME: Gross; we should probably have some separate target
+  // definition, possibly even reusing the one in clang.
+  return getArchName() == "x86_64";
+}
+
+const char *Generic_GCC::GetDefaultRelocationModel() const {
+  return "static";
+}
+
+const char *Generic_GCC::GetForcedPicModel() const {
+  return 0;
+}
+
+DerivedArgList *Generic_GCC::TranslateArgs(InputArgList &Args,
+                                           const char *BoundArch) const {
+  return new DerivedArgList(Args, true);
+}
+
+
+/// TCEToolChain - A tool chain using the llvm bitcode tools to perform
+/// all subcommands. See http://tce.cs.tut.fi for our peculiar target.
+/// Currently does not support anything else but compilation.
+
+TCEToolChain::TCEToolChain(const HostInfo &Host, const llvm::Triple& Triple)
+  : ToolChain(Host, Triple) {
+  // Path mangling to find libexec
+  std::string Path(getDriver().Dir);
+
+  Path += "/../libexec";
+  getProgramPaths().push_back(Path);
+}
+
+TCEToolChain::~TCEToolChain() {
+  for (llvm::DenseMap<unsigned, Tool*>::iterator
+           it = Tools.begin(), ie = Tools.end(); it != ie; ++it)
+      delete it->second;
+}
+
+bool TCEToolChain::IsMathErrnoDefault() const { 
+  return true; 
+}
+
+bool TCEToolChain::IsUnwindTablesDefault() const {
+  return false;
+}
+
+const char *TCEToolChain::GetDefaultRelocationModel() const {
+  return "static";
+}
+
+const char *TCEToolChain::GetForcedPicModel() const {
+  return 0;
+}
+
+Tool &TCEToolChain::SelectTool(const Compilation &C, 
+                            const JobAction &JA) const {
+  Action::ActionClass Key;
+  Key = Action::AnalyzeJobClass;
+
+  Tool *&T = Tools[Key];
+  if (!T) {
+    switch (Key) {
+    case Action::PreprocessJobClass:
+      T = new tools::gcc::Preprocess(*this); break;
+    case Action::AnalyzeJobClass:
+      T = new tools::Clang(*this); break;
+    default:
+     assert(false && "Unsupported action for TCE target.");
+    }
+  }
+  return *T;
+}
+
+DerivedArgList *TCEToolChain::TranslateArgs(InputArgList &Args,
+                                            const char *BoundArch) const {
+  return new DerivedArgList(Args, true);
+}
+
+/// OpenBSD - OpenBSD tool chain which can call as(1) and ld(1) directly.
+
+OpenBSD::OpenBSD(const HostInfo &Host, const llvm::Triple& Triple)
+  : Generic_GCC(Host, Triple) {
+  getFilePaths().push_back(getDriver().Dir + "/../lib");
+  getFilePaths().push_back("/usr/lib");
+}
+
+Tool &OpenBSD::SelectTool(const Compilation &C, const JobAction &JA) const {
+  Action::ActionClass Key;
+  if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
+    Key = Action::AnalyzeJobClass;
+  else
+    Key = JA.getKind();
+
+  Tool *&T = Tools[Key];
+  if (!T) {
+    switch (Key) {
+    case Action::AssembleJobClass:
+      T = new tools::openbsd::Assemble(*this); break;
+    case Action::LinkJobClass:
+      T = new tools::openbsd::Link(*this); break;
+    default:
+      T = &Generic_GCC::SelectTool(C, JA);
+    }
+  }
+
+  return *T;
+}
+
+/// FreeBSD - FreeBSD tool chain which can call as(1) and ld(1) directly.
+
+FreeBSD::FreeBSD(const HostInfo &Host, const llvm::Triple& Triple, bool Lib32)
+  : Generic_GCC(Host, Triple) {
+  if (Lib32) {
+    getFilePaths().push_back(getDriver().Dir + "/../lib32");
+    getFilePaths().push_back("/usr/lib32");
+  } else {
+    getFilePaths().push_back(getDriver().Dir + "/../lib");
+    getFilePaths().push_back("/usr/lib");
+  }
+}
+
+Tool &FreeBSD::SelectTool(const Compilation &C, const JobAction &JA) const {
+  Action::ActionClass Key;
+  if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
+    Key = Action::AnalyzeJobClass;
+  else
+    Key = JA.getKind();
+
+  Tool *&T = Tools[Key];
+  if (!T) {
+    switch (Key) {
+    case Action::AssembleJobClass:
+      T = new tools::freebsd::Assemble(*this); break;
+    case Action::LinkJobClass:
+      T = new tools::freebsd::Link(*this); break;
+    default:
+      T = &Generic_GCC::SelectTool(C, JA);
+    }
+  }
+
+  return *T;
+}
+
+/// AuroraUX - AuroraUX tool chain which can call as(1) and ld(1) directly.
+
+AuroraUX::AuroraUX(const HostInfo &Host, const llvm::Triple& Triple)
+  : Generic_GCC(Host, Triple) {
+
+  getProgramPaths().push_back(getDriver().Dir);
+
+  getFilePaths().push_back(getDriver().Dir + "/../lib");
+  getFilePaths().push_back("/usr/lib");
+  getFilePaths().push_back("/usr/sfw/lib");
+  getFilePaths().push_back("/opt/gcc4/lib");
+  getFilePaths().push_back("/opt/gcc4/lib/gcc/i386-pc-solaris2.11/4.2.4");
+
+}
+
+Tool &AuroraUX::SelectTool(const Compilation &C, const JobAction &JA) const {
+  Action::ActionClass Key;
+  if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
+    Key = Action::AnalyzeJobClass;
+  else
+    Key = JA.getKind();
+
+  Tool *&T = Tools[Key];
+  if (!T) {
+    switch (Key) {
+    case Action::AssembleJobClass:
+      T = new tools::auroraux::Assemble(*this); break;
+    case Action::LinkJobClass:
+      T = new tools::auroraux::Link(*this); break;
+    default:
+      T = &Generic_GCC::SelectTool(C, JA);
+    }
+  }
+
+  return *T;
+}
+
+
+/// Linux toolchain (very bare-bones at the moment).
+
+Linux::Linux(const HostInfo &Host, const llvm::Triple& Triple)
+  : Generic_GCC(Host, Triple) {
+  getFilePaths().push_back(getDriver().Dir + "/../lib/clang/1.0/");
+  getFilePaths().push_back("/lib/");
+  getFilePaths().push_back("/usr/lib/");
+
+  // Depending on the Linux distribution, any combination of lib{,32,64} is
+  // possible. E.g. Debian uses lib and lib32 for mixed i386/x86-64 systems,
+  // openSUSE uses lib and lib64 for the same purpose.
+  getFilePaths().push_back("/lib32/");
+  getFilePaths().push_back("/usr/lib32/");
+  getFilePaths().push_back("/lib64/");
+  getFilePaths().push_back("/usr/lib64/");
+
+  // FIXME: Figure out some way to get gcc's libdir
+  // (e.g. /usr/lib/gcc/i486-linux-gnu/4.3/ for Ubuntu 32-bit); we need
+  // crtbegin.o/crtend.o/etc., and want static versions of various
+  // libraries. If we had our own crtbegin.o/crtend.o/etc, we could probably
+  // get away with using shared versions in /usr/lib, though.
+  // We could fall back to the approach we used for includes (a massive
+  // list), but that's messy at best.
+}
+
+/// DragonFly - DragonFly tool chain which can call as(1) and ld(1) directly.
+
+DragonFly::DragonFly(const HostInfo &Host, const llvm::Triple& Triple)
+  : Generic_GCC(Host, Triple) {
+
+  // Path mangling to find libexec
+  getProgramPaths().push_back(getDriver().Dir);
+
+  getFilePaths().push_back(getDriver().Dir + "/../lib");
+  getFilePaths().push_back("/usr/lib");
+  getFilePaths().push_back("/usr/lib/gcc41");
+}
+
+Tool &DragonFly::SelectTool(const Compilation &C, const JobAction &JA) const {
+  Action::ActionClass Key;
+  if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
+    Key = Action::AnalyzeJobClass;
+  else
+    Key = JA.getKind();
+
+  Tool *&T = Tools[Key];
+  if (!T) {
+    switch (Key) {
+    case Action::AssembleJobClass:
+      T = new tools::dragonfly::Assemble(*this); break;
+    case Action::LinkJobClass:
+      T = new tools::dragonfly::Link(*this); break;
+    default:
+      T = &Generic_GCC::SelectTool(C, JA);
+    }
+  }
+
+  return *T;
+}
diff --git a/lib/Driver/ToolChains.h b/lib/Driver/ToolChains.h
new file mode 100644
index 0000000..9acc950
--- /dev/null
+++ b/lib/Driver/ToolChains.h
@@ -0,0 +1,305 @@
+//===--- ToolChains.h - ToolChain Implementations ---------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_LIB_DRIVER_TOOLCHAINS_H_
+#define CLANG_LIB_DRIVER_TOOLCHAINS_H_
+
+#include "clang/Driver/Action.h"
+#include "clang/Driver/ToolChain.h"
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/Support/Compiler.h"
+
+#include "Tools.h"
+
+namespace clang {
+namespace driver {
+namespace toolchains {
+
+/// Generic_GCC - A tool chain using the 'gcc' command to perform
+/// all subcommands; this relies on gcc translating the majority of
+/// command line options.
+class VISIBILITY_HIDDEN Generic_GCC : public ToolChain {
+protected:
+  mutable llvm::DenseMap<unsigned, Tool*> Tools;
+
+public:
+  Generic_GCC(const HostInfo &Host, const llvm::Triple& Triple);
+  ~Generic_GCC();
+
+  virtual DerivedArgList *TranslateArgs(InputArgList &Args,
+                                        const char *BoundArch) const;
+
+  virtual Tool &SelectTool(const Compilation &C, const JobAction &JA) const;
+
+  virtual bool IsUnwindTablesDefault() const;
+  virtual const char *GetDefaultRelocationModel() const;
+  virtual const char *GetForcedPicModel() const;
+};
+
+/// Darwin - The base Darwin tool chain.
+class VISIBILITY_HIDDEN Darwin : public ToolChain {
+  mutable llvm::DenseMap<unsigned, Tool*> Tools;
+
+  /// Whether the information on the target has been initialized.
+  //
+  // FIXME: This should be eliminated. What we want to do is make this part of
+  // the "default target for arguments" selection process, once we get out of
+  // the argument translation business.
+  mutable bool TargetInitialized;
+
+  /// Whether we are targetting iPhoneOS target.
+  mutable bool TargetIsIPhoneOS;
+  
+  /// The OS version we are targetting.
+  mutable unsigned TargetVersion[3];
+
+  /// The default macosx-version-min of this tool chain; empty until
+  /// initialized.
+  std::string MacosxVersionMin;
+
+public:
+  Darwin(const HostInfo &Host, const llvm::Triple& Triple,
+         const unsigned (&DarwinVersion)[3]);
+  ~Darwin();
+
+  /// @name Darwin Specific Toolchain API
+  /// {
+
+  // FIXME: Eliminate these ...Target functions and derive separate tool chains
+  // for these targets and put version in constructor.
+  void setTarget(bool isIPhoneOS, unsigned Major, unsigned Minor,
+                 unsigned Micro) const {
+    // FIXME: For now, allow reinitialization as long as values don't
+    // change. This will go away when we move away from argument translation.
+    if (TargetInitialized && TargetIsIPhoneOS == isIPhoneOS &&
+        TargetVersion[0] == Major && TargetVersion[1] == Minor &&
+        TargetVersion[2] == Micro)
+      return;
+
+    assert(!TargetInitialized && "Target already initialized!");
+    TargetInitialized = true;
+    TargetIsIPhoneOS = isIPhoneOS;
+    TargetVersion[0] = Major;
+    TargetVersion[1] = Minor;
+    TargetVersion[2] = Micro;
+  }
+
+  bool isTargetIPhoneOS() const {
+    assert(TargetInitialized && "Target not initialized!");
+    return TargetIsIPhoneOS;
+  }
+
+  bool isTargetInitialized() const { return TargetInitialized; }
+
+  void getTargetVersion(unsigned (&Res)[3]) const {
+    assert(TargetInitialized && "Target not initialized!");
+    Res[0] = TargetVersion[0];
+    Res[1] = TargetVersion[1];
+    Res[2] = TargetVersion[2];
+  }
+
+  /// getDarwinArchName - Get the "Darwin" arch name for a particular compiler
+  /// invocation. For example, Darwin treats different ARM variations as
+  /// distinct architectures.
+  llvm::StringRef getDarwinArchName(const ArgList &Args) const;
+
+  static bool isVersionLT(unsigned (&A)[3], unsigned (&B)[3]) {
+    for (unsigned i=0; i < 3; ++i) {
+      if (A[i] > B[i]) return false;
+      if (A[i] < B[i]) return true;
+    }
+    return false;
+  }
+
+  bool isIPhoneOSVersionLT(unsigned V0, unsigned V1=0, unsigned V2=0) const {
+    assert(isTargetIPhoneOS() && "Unexpected call for OS X target!");
+    unsigned B[3] = { V0, V1, V2 };
+    return isVersionLT(TargetVersion, B);
+  }
+
+  bool isMacosxVersionLT(unsigned V0, unsigned V1=0, unsigned V2=0) const {
+    assert(!isTargetIPhoneOS() && "Unexpected call for iPhoneOS target!");
+    unsigned B[3] = { V0, V1, V2 };
+    return isVersionLT(TargetVersion, B);
+  }
+
+  /// AddLinkSearchPathArgs - Add the linker search paths to \arg CmdArgs.
+  ///
+  /// \param Args - The input argument list.
+  /// \param CmdArgs [out] - The command argument list to append the paths
+  /// (prefixed by -L) to.
+  virtual void AddLinkSearchPathArgs(const ArgList &Args,
+                                     ArgStringList &CmdArgs) const = 0;
+
+  /// AddLinkRuntimeLibArgs - Add the linker arguments to link the compiler
+  /// runtime library.
+  virtual void AddLinkRuntimeLibArgs(const ArgList &Args,
+                                     ArgStringList &CmdArgs) const = 0;
+
+  /// }
+  /// @name ToolChain Implementation
+  /// {
+
+  virtual DerivedArgList *TranslateArgs(InputArgList &Args,
+                                        const char *BoundArch) const;
+
+  virtual Tool &SelectTool(const Compilation &C, const JobAction &JA) const;
+
+  virtual bool IsBlocksDefault() const {
+    // Blocks default to on for OS X 10.6 and iPhoneOS 3.0 and beyond.
+    if (isTargetIPhoneOS())
+      return !isIPhoneOSVersionLT(3);
+    else
+      return !isMacosxVersionLT(10, 6);
+  }
+  virtual bool IsObjCNonFragileABIDefault() const {
+    // Non-fragile ABI is default for everything but i386.
+    return getTriple().getArch() != llvm::Triple::x86;
+  }
+  virtual bool IsObjCLegacyDispatchDefault() const {
+    // This is only used with the non-fragile ABI.
+
+    // Legacy dispatch is used everywhere except on x86_64.
+    return getTriple().getArch() != llvm::Triple::x86_64;
+  }
+  virtual bool UseObjCMixedDispatch() const {
+    // This is only used with the non-fragile ABI and non-legacy dispatch.
+
+    // Mixed dispatch is used everywhere except OS X before 10.6.
+    return !(!isTargetIPhoneOS() && isMacosxVersionLT(10, 6));
+  }
+  virtual bool IsUnwindTablesDefault() const;
+  virtual unsigned GetDefaultStackProtectorLevel() const {
+    // Stack protectors default to on for 10.6 and beyond.
+    return !isTargetIPhoneOS() && !isMacosxVersionLT(10, 6);
+  }
+  virtual const char *GetDefaultRelocationModel() const;
+  virtual const char *GetForcedPicModel() const;
+
+  virtual bool SupportsObjCGC() const;
+
+  virtual bool UseDwarfDebugFlags() const;
+
+  virtual bool UseSjLjExceptions() const;
+
+  /// }
+};
+
+/// DarwinClang - The Darwin toolchain used by Clang.
+class VISIBILITY_HIDDEN DarwinClang : public Darwin {
+public:
+  DarwinClang(const HostInfo &Host, const llvm::Triple& Triple,
+              const unsigned (&DarwinVersion)[3]);
+
+  /// @name Darwin ToolChain Implementation
+  /// {
+
+  virtual void AddLinkSearchPathArgs(const ArgList &Args,
+                                    ArgStringList &CmdArgs) const;
+
+  virtual void AddLinkRuntimeLibArgs(const ArgList &Args,
+                                     ArgStringList &CmdArgs) const;
+
+  /// }
+};
+
+/// DarwinGCC - The Darwin toolchain used by GCC.
+class VISIBILITY_HIDDEN DarwinGCC : public Darwin {
+  /// GCC version to use.
+  unsigned GCCVersion[3];
+
+  /// The directory suffix for this tool chain.
+  std::string ToolChainDir;
+
+public:
+  DarwinGCC(const HostInfo &Host, const llvm::Triple& Triple,
+            const unsigned (&DarwinVersion)[3],
+            const unsigned (&GCCVersion)[3]);
+
+  /// @name Darwin ToolChain Implementation
+  /// {
+
+  virtual void AddLinkSearchPathArgs(const ArgList &Args,
+                                    ArgStringList &CmdArgs) const;
+
+  virtual void AddLinkRuntimeLibArgs(const ArgList &Args,
+                                     ArgStringList &CmdArgs) const;
+
+  /// }
+};
+
+/// Darwin_Generic_GCC - Generic Darwin tool chain using gcc.
+class VISIBILITY_HIDDEN Darwin_Generic_GCC : public Generic_GCC {
+public:
+  Darwin_Generic_GCC(const HostInfo &Host, const llvm::Triple& Triple)
+    : Generic_GCC(Host, Triple) {}
+
+  virtual const char *GetDefaultRelocationModel() const { return "pic"; }
+};
+
+class VISIBILITY_HIDDEN AuroraUX : public Generic_GCC {
+public:
+  AuroraUX(const HostInfo &Host, const llvm::Triple& Triple);
+
+  virtual Tool &SelectTool(const Compilation &C, const JobAction &JA) const;
+};
+
+class VISIBILITY_HIDDEN OpenBSD : public Generic_GCC {
+public:
+  OpenBSD(const HostInfo &Host, const llvm::Triple& Triple);
+
+  virtual Tool &SelectTool(const Compilation &C, const JobAction &JA) const;
+};
+
+class VISIBILITY_HIDDEN FreeBSD : public Generic_GCC {
+public:
+  FreeBSD(const HostInfo &Host, const llvm::Triple& Triple, bool Lib32);
+
+  virtual Tool &SelectTool(const Compilation &C, const JobAction &JA) const;
+};
+
+class VISIBILITY_HIDDEN DragonFly : public Generic_GCC {
+public:
+  DragonFly(const HostInfo &Host, const llvm::Triple& Triple);
+
+  virtual Tool &SelectTool(const Compilation &C, const JobAction &JA) const;
+};
+
+class VISIBILITY_HIDDEN Linux : public Generic_GCC {
+public:
+  Linux(const HostInfo &Host, const llvm::Triple& Triple);
+};
+
+
+/// TCEToolChain - A tool chain using the llvm bitcode tools to perform
+/// all subcommands. See http://tce.cs.tut.fi for our peculiar target.
+class VISIBILITY_HIDDEN TCEToolChain : public ToolChain {
+public:
+  TCEToolChain(const HostInfo &Host, const llvm::Triple& Triple);
+  ~TCEToolChain();
+
+  virtual DerivedArgList *TranslateArgs(InputArgList &Args,
+                                        const char *BoundArch) const;
+  virtual Tool &SelectTool(const Compilation &C, const JobAction &JA) const;
+  bool IsMathErrnoDefault() const;
+  bool IsUnwindTablesDefault() const;
+  const char* GetDefaultRelocationModel() const;
+  const char* GetForcedPicModel() const;
+
+private:
+  mutable llvm::DenseMap<unsigned, Tool*> Tools;
+
+};
+
+} // end namespace toolchains
+} // end namespace driver
+} // end namespace clang
+
+#endif
diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp
new file mode 100644
index 0000000..8ad04aa
--- /dev/null
+++ b/lib/Driver/Tools.cpp
@@ -0,0 +1,3051 @@
+//===--- Tools.cpp - Tools Implementations ------------------------------*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Tools.h"
+
+#include "clang/Driver/Action.h"
+#include "clang/Driver/Arg.h"
+#include "clang/Driver/ArgList.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/DriverDiagnostic.h"
+#include "clang/Driver/Compilation.h"
+#include "clang/Driver/Job.h"
+#include "clang/Driver/HostInfo.h"
+#include "clang/Driver/Option.h"
+#include "clang/Driver/Options.h"
+#include "clang/Driver/ToolChain.h"
+#include "clang/Driver/Util.h"
+
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/System/Host.h"
+#include "llvm/System/Process.h"
+
+#include "InputInfo.h"
+#include "ToolChains.h"
+
+using namespace clang::driver;
+using namespace clang::driver::tools;
+
+/// CheckPreprocessingOptions - Perform some validation of preprocessing
+/// arguments that is shared with gcc.
+static void CheckPreprocessingOptions(const Driver &D, const ArgList &Args) {
+  if (Arg *A = Args.getLastArg(options::OPT_C, options::OPT_CC))
+    if (!Args.hasArg(options::OPT_E))
+      D.Diag(clang::diag::err_drv_argument_only_allowed_with)
+        << A->getAsString(Args) << "-E";
+}
+
+/// CheckCodeGenerationOptions - Perform some validation of code generation
+/// arguments that is shared with gcc.
+static void CheckCodeGenerationOptions(const Driver &D, const ArgList &Args) {
+  // In gcc, only ARM checks this, but it seems reasonable to check universally.
+  if (Args.hasArg(options::OPT_static))
+    if (const Arg *A = Args.getLastArg(options::OPT_dynamic,
+                                       options::OPT_mdynamic_no_pic))
+      D.Diag(clang::diag::err_drv_argument_not_allowed_with)
+        << A->getAsString(Args) << "-static";
+}
+
+// Quote target names for inclusion in GNU Make dependency files.
+// Only the characters '$', '#', ' ', '\t' are quoted.
+static void QuoteTarget(llvm::StringRef Target,
+                        llvm::SmallVectorImpl<char> &Res) {
+  for (unsigned i = 0, e = Target.size(); i != e; ++i) {
+    switch (Target[i]) {
+    case ' ':
+    case '\t':
+      // Escape the preceding backslashes
+      for (int j = i - 1; j >= 0 && Target[j] == '\\'; --j)
+        Res.push_back('\\');
+
+      // Escape the space/tab
+      Res.push_back('\\');
+      break;
+    case '$':
+      Res.push_back('$');
+      break;
+    case '#':
+      Res.push_back('\\');
+      break;
+    default:
+      break;
+    }
+
+    Res.push_back(Target[i]);
+  }
+}
+
+void Clang::AddPreprocessingOptions(const Driver &D,
+                                    const ArgList &Args,
+                                    ArgStringList &CmdArgs,
+                                    const InputInfo &Output,
+                                    const InputInfoList &Inputs) const {
+  Arg *A;
+
+  CheckPreprocessingOptions(D, Args);
+
+  Args.AddLastArg(CmdArgs, options::OPT_C);
+  Args.AddLastArg(CmdArgs, options::OPT_CC);
+
+  // Handle dependency file generation.
+  if ((A = Args.getLastArg(options::OPT_M)) ||
+      (A = Args.getLastArg(options::OPT_MM)) ||
+      (A = Args.getLastArg(options::OPT_MD)) ||
+      (A = Args.getLastArg(options::OPT_MMD))) {
+    // Determine the output location.
+    const char *DepFile;
+    if (Output.getType() == types::TY_Dependencies) {
+      if (Output.isPipe())
+        DepFile = "-";
+      else
+        DepFile = Output.getFilename();
+    } else if (Arg *MF = Args.getLastArg(options::OPT_MF)) {
+      DepFile = MF->getValue(Args);
+    } else if (A->getOption().matches(options::OPT_M) ||
+               A->getOption().matches(options::OPT_MM)) {
+      DepFile = "-";
+    } else {
+      DepFile = darwin::CC1::getDependencyFileName(Args, Inputs);
+    }
+    CmdArgs.push_back("-dependency-file");
+    CmdArgs.push_back(DepFile);
+
+    // Add a default target if one wasn't specified.
+    if (!Args.hasArg(options::OPT_MT) && !Args.hasArg(options::OPT_MQ)) {
+      const char *DepTarget;
+
+      // If user provided -o, that is the dependency target, except
+      // when we are only generating a dependency file.
+      Arg *OutputOpt = Args.getLastArg(options::OPT_o);
+      if (OutputOpt && Output.getType() != types::TY_Dependencies) {
+        DepTarget = OutputOpt->getValue(Args);
+      } else {
+        // Otherwise derive from the base input.
+        //
+        // FIXME: This should use the computed output file location.
+        llvm::sys::Path P(Inputs[0].getBaseInput());
+
+        P.eraseSuffix();
+        P.appendSuffix("o");
+        DepTarget = Args.MakeArgString(P.getLast());
+      }
+
+      CmdArgs.push_back("-MT");
+      llvm::SmallString<128> Quoted;
+      QuoteTarget(DepTarget, Quoted);
+      CmdArgs.push_back(Args.MakeArgString(Quoted));
+    }
+
+    if (A->getOption().matches(options::OPT_M) ||
+        A->getOption().matches(options::OPT_MD))
+      CmdArgs.push_back("-sys-header-deps");
+  }
+
+  Args.AddLastArg(CmdArgs, options::OPT_MP);
+
+  // Convert all -MQ <target> args to -MT <quoted target>
+  for (arg_iterator it = Args.filtered_begin(options::OPT_MT,
+                                             options::OPT_MQ),
+         ie = Args.filtered_end(); it != ie; ++it) {
+
+    it->claim();
+
+    if (it->getOption().matches(options::OPT_MQ)) {
+      CmdArgs.push_back("-MT");
+      llvm::SmallString<128> Quoted;
+      QuoteTarget(it->getValue(Args), Quoted);
+      CmdArgs.push_back(Args.MakeArgString(Quoted));
+
+    // -MT flag - no change
+    } else {
+      it->render(Args, CmdArgs);
+    }
+  }
+
+  // Add -i* options, and automatically translate to
+  // -include-pch/-include-pth for transparent PCH support. It's
+  // wonky, but we include looking for .gch so we can support seamless
+  // replacement into a build system already set up to be generating
+  // .gch files.
+  for (arg_iterator it = Args.filtered_begin(options::OPT_clang_i_Group),
+         ie = Args.filtered_end(); it != ie; ++it) {
+    const Arg *A = it;
+
+    if (A->getOption().matches(options::OPT_include)) {
+      // Use PCH if the user requested it, except for C++ (for now).
+      bool UsePCH = D.CCCUsePCH;
+      if (types::isCXX(Inputs[0].getType()))
+        UsePCH = false;
+
+      bool FoundPTH = false;
+      bool FoundPCH = false;
+      llvm::sys::Path P(A->getValue(Args));
+      if (UsePCH) {
+        P.appendSuffix("pch");
+        if (P.exists())
+          FoundPCH = true;
+        else
+          P.eraseSuffix();
+      }
+
+      if (!FoundPCH) {
+        P.appendSuffix("pth");
+        if (P.exists())
+          FoundPTH = true;
+        else
+          P.eraseSuffix();
+      }
+
+      if (!FoundPCH && !FoundPTH) {
+        P.appendSuffix("gch");
+        if (P.exists()) {
+          FoundPCH = UsePCH;
+          FoundPTH = !UsePCH;
+        }
+        else
+          P.eraseSuffix();
+      }
+
+      if (FoundPCH || FoundPTH) {
+        A->claim();
+        if (UsePCH)
+          CmdArgs.push_back("-include-pch");
+        else
+          CmdArgs.push_back("-include-pth");
+        CmdArgs.push_back(Args.MakeArgString(P.str()));
+        continue;
+      }
+    }
+
+    // Not translated, render as usual.
+    A->claim();
+    A->render(Args, CmdArgs);
+  }
+
+  Args.AddAllArgs(CmdArgs, options::OPT_D, options::OPT_U);
+  Args.AddAllArgs(CmdArgs, options::OPT_I_Group, options::OPT_F);
+
+  // Add -Wp, and -Xassembler if using the preprocessor.
+
+  // FIXME: There is a very unfortunate problem here, some troubled
+  // souls abuse -Wp, to pass preprocessor options in gcc syntax. To
+  // really support that we would have to parse and then translate
+  // those options. :(
+  Args.AddAllArgValues(CmdArgs, options::OPT_Wp_COMMA,
+                       options::OPT_Xpreprocessor);
+
+  // -I- is a deprecated GCC feature, reject it.
+  if (Arg *A = Args.getLastArg(options::OPT_I_))
+    D.Diag(clang::diag::err_drv_I_dash_not_supported) << A->getAsString(Args);
+}
+
+/// getARMTargetCPU - Get the (LLVM) name of the ARM cpu we are targetting.
+//
+// FIXME: tblgen this.
+static const char *getARMTargetCPU(const ArgList &Args) {
+  // FIXME: Warn on inconsistent use of -mcpu and -march.
+
+  // If we have -mcpu=, use that.
+  if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
+    return A->getValue(Args);
+
+  // Otherwise, if we have -march= choose the base CPU for that arch.
+  if (Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
+    llvm::StringRef MArch = A->getValue(Args);
+
+    if (MArch == "armv2" || MArch == "armv2a")
+      return "arm2";
+    if (MArch == "armv3")
+      return "arm6";
+    if (MArch == "armv3m")
+      return "arm7m";
+    if (MArch == "armv4" || MArch == "armv4t")
+      return "arm7tdmi";
+    if (MArch == "armv5" || MArch == "armv5t")
+      return "arm10tdmi";
+    if (MArch == "armv5e" || MArch == "armv5te")
+      return "arm1026ejs";
+    if (MArch == "armv5tej")
+      return "arm926ej-s";
+    if (MArch == "armv6" || MArch == "armv6k")
+      return "arm1136jf-s";
+    if (MArch == "armv6j")
+      return "arm1136j-s";
+    if (MArch == "armv6z" || MArch == "armv6zk")
+      return "arm1176jzf-s";
+    if (MArch == "armv6t2")
+      return "arm1156t2-s";
+    if (MArch == "armv7" || MArch == "armv7a" || MArch == "armv7-a")
+      return "cortex-a8";
+    if (MArch == "armv7r" || MArch == "armv7-r")
+      return "cortex-r4";
+    if (MArch == "armv7m" || MArch == "armv7-m")
+      return "cortex-m3";
+    if (MArch == "ep9312")
+      return "ep9312";
+    if (MArch == "iwmmxt")
+      return "iwmmxt";
+    if (MArch == "xscale")
+      return "xscale";
+  }
+
+  // Otherwise return the most base CPU LLVM supports.
+  return "arm7tdmi";
+}
+
+/// getLLVMArchSuffixForARM - Get the LLVM arch name to use for a particular
+/// CPU.
+//
+// FIXME: This is redundant with -mcpu, why does LLVM use this.
+// FIXME: tblgen this, or kill it!
+static const char *getLLVMArchSuffixForARM(llvm::StringRef CPU) {
+  if (CPU == "arm7tdmi" || CPU == "arm7tdmi-s" || CPU == "arm710t" ||
+      CPU == "arm720t" || CPU == "arm9" || CPU == "arm9tdmi" ||
+      CPU == "arm920" || CPU == "arm920t" || CPU == "arm922t" ||
+      CPU == "arm940t" || CPU == "ep9312")
+    return "v4t";
+
+  if (CPU == "arm10tdmi" || CPU == "arm1020t")
+    return "v5";
+
+  if (CPU == "arm9e" || CPU == "arm926ej-s" || CPU == "arm946e-s" ||
+      CPU == "arm966e-s" || CPU == "arm968e-s" || CPU == "arm10e" ||
+      CPU == "arm1020e" || CPU == "arm1022e" || CPU == "xscale" ||
+      CPU == "iwmmxt")
+    return "v5e";
+
+  if (CPU == "arm1136j-s" || CPU == "arm1136jf-s" || CPU == "arm1176jz-s" ||
+      CPU == "arm1176jzf-s" || CPU == "mpcorenovfp" || CPU == "mpcore")
+    return "v6";
+
+  if (CPU == "arm1156t2-s" || CPU == "arm1156t2f-s")
+    return "v6t2";
+
+  if (CPU == "cortex-a8" || CPU == "cortex-a9")
+    return "v7";
+
+  return "";
+}
+
+/// getLLVMTriple - Get the LLVM triple to use for a particular toolchain, which
+/// may depend on command line arguments.
+static std::string getLLVMTriple(const ToolChain &TC, const ArgList &Args) {
+  switch (TC.getTriple().getArch()) {
+  default:
+    return TC.getTripleString();
+
+  case llvm::Triple::arm:
+  case llvm::Triple::thumb: {
+    // FIXME: Factor into subclasses.
+    llvm::Triple Triple = TC.getTriple();
+
+    // Thumb2 is the default for V7 on Darwin.
+    //
+    // FIXME: Thumb should just be another -target-feaure, not in the triple.
+    llvm::StringRef Suffix = getLLVMArchSuffixForARM(getARMTargetCPU(Args));
+    bool ThumbDefault =
+      (Suffix == "v7" && TC.getTriple().getOS() == llvm::Triple::Darwin);
+    std::string ArchName = "arm";
+    if (Args.hasFlag(options::OPT_mthumb, options::OPT_mno_thumb, ThumbDefault))
+      ArchName = "thumb";
+    Triple.setArchName(ArchName + Suffix.str());
+
+    return Triple.getTriple();
+  }
+  }
+}
+
+// FIXME: Move to target hook.
+static bool isSignedCharDefault(const llvm::Triple &Triple) {
+  switch (Triple.getArch()) {
+  default:
+    return true;
+
+  case llvm::Triple::ppc:
+  case llvm::Triple::ppc64:
+    if (Triple.getOS() == llvm::Triple::Darwin)
+      return true;
+    return false;
+
+  case llvm::Triple::systemz:
+    return false;
+  }
+}
+
+void Clang::AddARMTargetArgs(const ArgList &Args,
+                             ArgStringList &CmdArgs) const {
+  const Driver &D = getToolChain().getDriver();
+
+  // Select the ABI to use.
+  //
+  // FIXME: Support -meabi.
+  const char *ABIName = 0;
+  if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) {
+    ABIName = A->getValue(Args);
+  } else {
+    // Select the default based on the platform.
+    switch (getToolChain().getTriple().getOS()) {
+      // FIXME: Is this right for non-Darwin and non-Linux?
+    default:
+      ABIName = "aapcs";
+      break;
+
+    case llvm::Triple::Darwin:
+      ABIName = "apcs-gnu";
+      break;
+
+    case llvm::Triple::Linux:
+      ABIName = "aapcs-linux";
+      break;
+    }
+  }
+  CmdArgs.push_back("-target-abi");
+  CmdArgs.push_back(ABIName);
+
+  // Set the CPU based on -march= and -mcpu=.
+  CmdArgs.push_back("-target-cpu");
+  CmdArgs.push_back(getARMTargetCPU(Args));
+
+  // Select the float ABI as determined by -msoft-float, -mhard-float, and
+  // -mfloat-abi=.
+  llvm::StringRef FloatABI;
+  if (Arg *A = Args.getLastArg(options::OPT_msoft_float,
+                               options::OPT_mhard_float,
+                               options::OPT_mfloat_abi_EQ)) {
+    if (A->getOption().matches(options::OPT_msoft_float))
+      FloatABI = "soft";
+    else if (A->getOption().matches(options::OPT_mhard_float))
+      FloatABI = "hard";
+    else {
+      FloatABI = A->getValue(Args);
+      if (FloatABI != "soft" && FloatABI != "softfp" && FloatABI != "hard") {
+        D.Diag(clang::diag::err_drv_invalid_mfloat_abi)
+          << A->getAsString(Args);
+        FloatABI = "soft";
+      }
+    }
+  }
+
+  // If unspecified, choose the default based on the platform.
+  if (FloatABI.empty()) {
+    // FIXME: This is wrong for non-Darwin, we don't have a mechanism yet for
+    // distinguishing things like linux-eabi vs linux-elf.
+    switch (getToolChain().getTriple().getOS()) {
+    case llvm::Triple::Darwin: {
+      // Darwin defaults to "softfp" for v6 and v7.
+      //
+      // FIXME: Factor out an ARM class so we can cache the arch somewhere.
+      llvm::StringRef ArchName = getLLVMArchSuffixForARM(getARMTargetCPU(Args));
+      if (ArchName.startswith("v6") || ArchName.startswith("v7"))
+        FloatABI = "softfp";
+      else
+        FloatABI = "soft";
+      break;
+    }
+
+    default:
+      // Assume "soft", but warn the user we are guessing.
+      FloatABI = "soft";
+      D.Diag(clang::diag::warn_drv_assuming_mfloat_abi_is) << "soft";
+      break;
+    }
+  }
+
+  if (FloatABI == "soft") {
+    // Floating point operations and argument passing are soft.
+    //
+    // FIXME: This changes CPP defines, we need -target-soft-float.
+    CmdArgs.push_back("-msoft-float");
+    CmdArgs.push_back("-mfloat-abi");
+    CmdArgs.push_back("soft");
+  } else if (FloatABI == "softfp") {
+    // Floating point operations are hard, but argument passing is soft.
+    CmdArgs.push_back("-mfloat-abi");
+    CmdArgs.push_back("soft");
+  } else {
+    // Floating point operations and argument passing are hard.
+    assert(FloatABI == "hard" && "Invalid float abi!");
+    CmdArgs.push_back("-mfloat-abi");
+    CmdArgs.push_back("hard");
+  }
+
+  // Set appropriate target features for floating point mode.
+  //
+  // FIXME: Note, this is a hack, the LLVM backend doesn't actually use these
+  // yet (it uses the -mfloat-abi and -msoft-float options above), and it is
+  // stripped out by the ARM target.
+
+  // Use software floating point operations?
+  if (FloatABI == "soft") {
+    CmdArgs.push_back("-target-feature");
+    CmdArgs.push_back("+soft-float");
+  }
+
+  // Use software floating point argument passing?
+  if (FloatABI != "hard") {
+    CmdArgs.push_back("-target-feature");
+    CmdArgs.push_back("+soft-float-abi");
+  }
+
+  // Honor -mfpu=.
+  //
+  // FIXME: Centralize feature selection, defaulting shouldn't be also in the
+  // frontend target.
+  if (const Arg *A = Args.getLastArg(options::OPT_mfpu_EQ)) {
+    llvm::StringRef FPU = A->getValue(Args);
+
+    // Set the target features based on the FPU.
+    if (FPU == "fpa" || FPU == "fpe2" || FPU == "fpe3" || FPU == "maverick") {
+      // Disable any default FPU support.
+      CmdArgs.push_back("-target-feature");
+      CmdArgs.push_back("-vfp2");
+      CmdArgs.push_back("-target-feature");
+      CmdArgs.push_back("-vfp3");
+      CmdArgs.push_back("-target-feature");
+      CmdArgs.push_back("-neon");
+    } else if (FPU == "vfp") {
+      CmdArgs.push_back("-target-feature");
+      CmdArgs.push_back("+vfp2");
+    } else if (FPU == "vfp3") {
+      CmdArgs.push_back("-target-feature");
+      CmdArgs.push_back("+vfp3");
+    } else if (FPU == "neon") {
+      CmdArgs.push_back("-target-feature");
+      CmdArgs.push_back("+neon");
+    } else
+      D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);
+  }
+}
+
+void Clang::AddMIPSTargetArgs(const ArgList &Args,
+                             ArgStringList &CmdArgs) const {
+  const Driver &D = getToolChain().getDriver();
+
+  // Select the ABI to use.
+  const char *ABIName = 0;
+  if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) {
+    ABIName = A->getValue(Args);
+  } else {
+    ABIName = "o32";
+  }
+
+  CmdArgs.push_back("-target-abi");
+  CmdArgs.push_back(ABIName);
+
+  if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
+    llvm::StringRef MArch = A->getValue(Args);
+    CmdArgs.push_back("-target-cpu");
+
+    if ((MArch == "r2000") || (MArch == "r3000"))
+      CmdArgs.push_back("mips1");
+    else if (MArch == "r6000")
+      CmdArgs.push_back("mips2");
+    else
+      CmdArgs.push_back(MArch.str().c_str());
+  }
+
+  // Select the float ABI as determined by -msoft-float, -mhard-float, and
+  llvm::StringRef FloatABI;
+  if (Arg *A = Args.getLastArg(options::OPT_msoft_float,
+                               options::OPT_mhard_float)) {
+    if (A->getOption().matches(options::OPT_msoft_float))
+      FloatABI = "soft";
+    else if (A->getOption().matches(options::OPT_mhard_float))
+      FloatABI = "hard";
+  }
+
+  // If unspecified, choose the default based on the platform.
+  if (FloatABI.empty()) {
+    // Assume "soft", but warn the user we are guessing.
+    FloatABI = "soft";
+    D.Diag(clang::diag::warn_drv_assuming_mfloat_abi_is) << "soft";
+  }
+
+  if (FloatABI == "soft") {
+    // Floating point operations and argument passing are soft.
+    //
+    // FIXME: This changes CPP defines, we need -target-soft-float.
+    CmdArgs.push_back("-msoft-float");
+  } else {
+    assert(FloatABI == "hard" && "Invalid float abi!");
+    CmdArgs.push_back("-mhard-float");
+  }
+}
+
+void Clang::AddX86TargetArgs(const ArgList &Args,
+                             ArgStringList &CmdArgs) const {
+  if (!Args.hasFlag(options::OPT_mred_zone,
+                    options::OPT_mno_red_zone,
+                    true) ||
+      Args.hasArg(options::OPT_mkernel) ||
+      Args.hasArg(options::OPT_fapple_kext))
+    CmdArgs.push_back("-disable-red-zone");
+
+  if (Args.hasFlag(options::OPT_msoft_float,
+                   options::OPT_mno_soft_float,
+                   false))
+    CmdArgs.push_back("-no-implicit-float");
+
+  const char *CPUName = 0;
+  if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
+    if (llvm::StringRef(A->getValue(Args)) == "native") {
+      // FIXME: Reject attempts to use -march=native unless the target matches
+      // the host.
+      //
+      // FIXME: We should also incorporate the detected target features for use
+      // with -native.
+      std::string CPU = llvm::sys::getHostCPUName();
+      if (!CPU.empty())
+        CPUName = Args.MakeArgString(CPU);
+    } else
+      CPUName = A->getValue(Args);
+  }
+
+  // Select the default CPU if none was given (or detection failed).
+  if (!CPUName) {
+    // FIXME: Need target hooks.
+    if (getToolChain().getOS().startswith("darwin")) {
+      if (getToolChain().getArchName() == "x86_64")
+        CPUName = "core2";
+      else if (getToolChain().getArchName() == "i386")
+        CPUName = "yonah";
+    } else if (getToolChain().getOS().startswith("haiku"))  {
+      if (getToolChain().getArchName() == "x86_64")
+        CPUName = "x86-64";
+      else if (getToolChain().getArchName() == "i386")
+        CPUName = "i586";
+    } else {
+      if (getToolChain().getArchName() == "x86_64")
+        CPUName = "x86-64";
+      else if (getToolChain().getArchName() == "i386")
+        CPUName = "pentium4";
+    }
+  }
+
+  if (CPUName) {
+    CmdArgs.push_back("-target-cpu");
+    CmdArgs.push_back(CPUName);
+  }
+
+  for (arg_iterator it = Args.filtered_begin(options::OPT_m_x86_Features_Group),
+         ie = Args.filtered_end(); it != ie; ++it) {
+    llvm::StringRef Name = it->getOption().getName();
+    it->claim();
+
+    // Skip over "-m".
+    assert(Name.startswith("-m") && "Invalid feature name.");
+    Name = Name.substr(2);
+
+    bool IsNegative = Name.startswith("no-");
+    if (IsNegative)
+      Name = Name.substr(3);
+
+    CmdArgs.push_back("-target-feature");
+    CmdArgs.push_back(Args.MakeArgString((IsNegative ? "-" : "+") + Name));
+  }
+}
+
+static bool needsExceptions(const ArgList &Args,  types::ID InputType,
+                            const llvm::Triple &Triple) {
+  if (Arg *A = Args.getLastArg(options::OPT_fexceptions,
+                               options::OPT_fno_exceptions)) {
+    if (A->getOption().matches(options::OPT_fexceptions))
+      return true;
+    else
+      return false;
+  }
+  switch (InputType) {
+  case types::TY_CXX: case types::TY_CXXHeader:
+  case types::TY_PP_CXX: case types::TY_PP_CXXHeader:
+  case types::TY_ObjCXX: case types::TY_ObjCXXHeader:
+  case types::TY_PP_ObjCXX: case types::TY_PP_ObjCXXHeader:
+    return true;
+
+  case types::TY_ObjC: case types::TY_ObjCHeader:
+  case types::TY_PP_ObjC: case types::TY_PP_ObjCHeader:
+    if (Args.hasArg(options::OPT_fobjc_nonfragile_abi))
+      return true;
+    if (Triple.getOS() != llvm::Triple::Darwin)
+      return false;
+    return (Triple.getDarwinMajorNumber() >= 9 &&
+            Triple.getArch() == llvm::Triple::x86_64);
+
+  default:
+    return false;
+  }
+}
+
+/// getEffectiveClangTriple - Get the "effective" target triple, which is the
+/// triple for the target but with the OS version potentially modified for
+/// Darwin's -mmacosx-version-min.
+static std::string getEffectiveClangTriple(const Driver &D,
+                                           const ToolChain &TC,
+                                           const ArgList &Args) {
+  llvm::Triple Triple(getLLVMTriple(TC, Args));
+
+  // Handle -mmacosx-version-min and -miphoneos-version-min.
+  if (Triple.getOS() != llvm::Triple::Darwin) {
+    // Diagnose use of -mmacosx-version-min and -miphoneos-version-min on
+    // non-Darwin.
+    if (Arg *A = Args.getLastArg(options::OPT_mmacosx_version_min_EQ,
+                                 options::OPT_miphoneos_version_min_EQ))
+      D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);
+  } else {
+    const toolchains::Darwin &DarwinTC(
+      reinterpret_cast<const toolchains::Darwin&>(TC));
+
+    // If the target isn't initialized (e.g., an unknown Darwin platform, return
+    // the default triple).
+    if (!DarwinTC.isTargetInitialized())
+      return Triple.getTriple();
+    
+    unsigned Version[3];
+    DarwinTC.getTargetVersion(Version);
+
+    // Mangle the target version into the OS triple component.  For historical
+    // reasons that make little sense, the version passed here is the "darwin"
+    // version, which drops the 10 and offsets by 4. See inverse code when
+    // setting the OS version preprocessor define.
+    if (!DarwinTC.isTargetIPhoneOS()) {
+      Version[0] = Version[1] + 4;
+      Version[1] = Version[2];
+      Version[2] = 0;
+    } else {
+      // Use the environment to communicate that we are targetting iPhoneOS.
+      Triple.setEnvironmentName("iphoneos");
+    }
+
+    llvm::SmallString<16> Str;
+    llvm::raw_svector_ostream(Str) << "darwin" << Version[0]
+                                   << "." << Version[1] << "." << Version[2];
+    Triple.setOSName(Str.str());
+  }
+
+  return Triple.getTriple();
+}
+
+void Clang::ConstructJob(Compilation &C, const JobAction &JA,
+                         Job &Dest,
+                         const InputInfo &Output,
+                         const InputInfoList &Inputs,
+                         const ArgList &Args,
+                         const char *LinkingOutput) const {
+  bool KernelOrKext = Args.hasArg(options::OPT_mkernel,
+                                  options::OPT_fapple_kext);
+  const Driver &D = getToolChain().getDriver();
+  ArgStringList CmdArgs;
+
+  assert(Inputs.size() == 1 && "Unable to handle multiple inputs.");
+
+  // Invoke ourselves in -cc1 mode.
+  //
+  // FIXME: Implement custom jobs for internal actions.
+  CmdArgs.push_back("-cc1");
+
+  // Add the "effective" target triple.
+  CmdArgs.push_back("-triple");
+  std::string TripleStr = getEffectiveClangTriple(D, getToolChain(), Args);
+  CmdArgs.push_back(Args.MakeArgString(TripleStr));
+
+  // Select the appropriate action.
+  if (isa<AnalyzeJobAction>(JA)) {
+    assert(JA.getType() == types::TY_Plist && "Invalid output type.");
+    CmdArgs.push_back("-analyze");
+  } else if (isa<PreprocessJobAction>(JA)) {
+    if (Output.getType() == types::TY_Dependencies)
+      CmdArgs.push_back("-Eonly");
+    else
+      CmdArgs.push_back("-E");
+  } else if (isa<AssembleJobAction>(JA)) {
+    CmdArgs.push_back("-emit-obj");
+  } else if (isa<PrecompileJobAction>(JA)) {
+    // Use PCH if the user requested it, except for C++ (for now).
+    bool UsePCH = D.CCCUsePCH;
+    if (types::isCXX(Inputs[0].getType()))
+      UsePCH = false;
+
+    if (UsePCH)
+      CmdArgs.push_back("-emit-pch");
+    else
+      CmdArgs.push_back("-emit-pth");
+  } else {
+    assert(isa<CompileJobAction>(JA) && "Invalid action for clang tool.");
+
+    if (JA.getType() == types::TY_Nothing) {
+      CmdArgs.push_back("-fsyntax-only");
+    } else if (JA.getType() == types::TY_LLVMAsm) {
+      CmdArgs.push_back("-emit-llvm");
+    } else if (JA.getType() == types::TY_LLVMBC) {
+      CmdArgs.push_back("-emit-llvm-bc");
+    } else if (JA.getType() == types::TY_PP_Asm) {
+      CmdArgs.push_back("-S");
+    } else if (JA.getType() == types::TY_AST) {
+      CmdArgs.push_back("-emit-pch");
+    } else if (JA.getType() == types::TY_RewrittenObjC) {
+      CmdArgs.push_back("-rewrite-objc");
+    } else {
+      assert(JA.getType() == types::TY_PP_Asm &&
+             "Unexpected output type!");
+    }
+  }
+
+  // The make clang go fast button.
+  CmdArgs.push_back("-disable-free");
+
+  // Disable the verification pass in -asserts builds.
+#ifdef NDEBUG
+  CmdArgs.push_back("-disable-llvm-verifier");
+#endif
+
+  // Set the main file name, so that debug info works even with
+  // -save-temps.
+  CmdArgs.push_back("-main-file-name");
+  CmdArgs.push_back(darwin::CC1::getBaseInputName(Args, Inputs));
+
+  // Some flags which affect the language (via preprocessor
+  // defines). See darwin::CC1::AddCPPArgs.
+  if (Args.hasArg(options::OPT_static))
+    CmdArgs.push_back("-static-define");
+
+  if (isa<AnalyzeJobAction>(JA)) {
+    // Enable region store model by default.
+    CmdArgs.push_back("-analyzer-store=region");
+
+    // Treat blocks as analysis entry points.
+    CmdArgs.push_back("-analyzer-opt-analyze-nested-blocks");
+
+    // Add default argument set.
+    if (!Args.hasArg(options::OPT__analyzer_no_default_checks)) {
+      CmdArgs.push_back("-analyzer-check-dead-stores");
+      CmdArgs.push_back("-analyzer-check-security-syntactic");
+      CmdArgs.push_back("-analyzer-check-objc-mem");
+      CmdArgs.push_back("-analyzer-eagerly-assume");
+      CmdArgs.push_back("-analyzer-check-objc-methodsigs");
+      // Do not enable the missing -dealloc check.
+      // '-analyzer-check-objc-missing-dealloc',
+      CmdArgs.push_back("-analyzer-check-objc-unused-ivars");
+    }
+
+    // Set the output format. The default is plist, for (lame) historical
+    // reasons.
+    CmdArgs.push_back("-analyzer-output");
+    if (Arg *A = Args.getLastArg(options::OPT__analyzer_output))
+      CmdArgs.push_back(A->getValue(Args));
+    else
+      CmdArgs.push_back("plist");
+
+    // Disable the presentation of standard compiler warnings when
+    // using --analyze.  We only want to show static analyzer diagnostics
+    // or frontend errors.
+    CmdArgs.push_back("-w");
+
+    // Add -Xanalyzer arguments when running as analyzer.
+    Args.AddAllArgValues(CmdArgs, options::OPT_Xanalyzer);
+  }
+
+  CheckCodeGenerationOptions(D, Args);
+
+  // Perform argument translation for LLVM backend. This
+  // takes some care in reconciling with llvm-gcc. The
+  // issue is that llvm-gcc translates these options based on
+  // the values in cc1, whereas we are processing based on
+  // the driver arguments.
+
+  // This comes from the default translation the driver + cc1
+  // would do to enable flag_pic.
+  //
+  // FIXME: Centralize this code.
+  bool PICEnabled = (Args.hasArg(options::OPT_fPIC) ||
+                     Args.hasArg(options::OPT_fpic) ||
+                     Args.hasArg(options::OPT_fPIE) ||
+                     Args.hasArg(options::OPT_fpie));
+  bool PICDisabled = (Args.hasArg(options::OPT_mkernel) ||
+                      Args.hasArg(options::OPT_static));
+  const char *Model = getToolChain().GetForcedPicModel();
+  if (!Model) {
+    if (Args.hasArg(options::OPT_mdynamic_no_pic))
+      Model = "dynamic-no-pic";
+    else if (PICDisabled)
+      Model = "static";
+    else if (PICEnabled)
+      Model = "pic";
+    else
+      Model = getToolChain().GetDefaultRelocationModel();
+  }
+  if (llvm::StringRef(Model) != "pic") {
+    CmdArgs.push_back("-mrelocation-model");
+    CmdArgs.push_back(Model);
+  }
+
+  // Infer the __PIC__ value.
+  //
+  // FIXME:  This isn't quite right on Darwin, which always sets
+  // __PIC__=2.
+  if (strcmp(Model, "pic") == 0 || strcmp(Model, "dynamic-no-pic") == 0) {
+    CmdArgs.push_back("-pic-level");
+    CmdArgs.push_back(Args.hasArg(options::OPT_fPIC) ? "2" : "1");
+  }
+  if (!Args.hasFlag(options::OPT_fmerge_all_constants,
+                    options::OPT_fno_merge_all_constants))
+    CmdArgs.push_back("-no-merge-all-constants");
+
+  // LLVM Code Generator Options.
+
+  // FIXME: Set --enable-unsafe-fp-math.
+  if (Args.hasFlag(options::OPT_fno_omit_frame_pointer,
+                   options::OPT_fomit_frame_pointer))
+    CmdArgs.push_back("-mdisable-fp-elim");
+  if (!Args.hasFlag(options::OPT_fzero_initialized_in_bss,
+                    options::OPT_fno_zero_initialized_in_bss))
+    CmdArgs.push_back("-mno-zero-initialized-in-bss");
+  if (Args.hasArg(options::OPT_dA) || Args.hasArg(options::OPT_fverbose_asm))
+    CmdArgs.push_back("-masm-verbose");
+  if (Args.hasArg(options::OPT_fdebug_pass_structure)) {
+    CmdArgs.push_back("-mdebug-pass");
+    CmdArgs.push_back("Structure");
+  }
+  if (Args.hasArg(options::OPT_fdebug_pass_arguments)) {
+    CmdArgs.push_back("-mdebug-pass");
+    CmdArgs.push_back("Arguments");
+  }
+
+  // Enable -mconstructor-aliases except on darwin, where we have to
+  // work around a linker bug;  see <rdar://problem/7651567>.
+  if (getToolChain().getTriple().getOS() != llvm::Triple::Darwin)
+    CmdArgs.push_back("-mconstructor-aliases");
+
+  // This is a coarse approximation of what llvm-gcc actually does, both
+  // -fasynchronous-unwind-tables and -fnon-call-exceptions interact in more
+  // complicated ways.
+  bool AsynchronousUnwindTables =
+    Args.hasFlag(options::OPT_fasynchronous_unwind_tables,
+                 options::OPT_fno_asynchronous_unwind_tables,
+                 getToolChain().IsUnwindTablesDefault() &&
+                 !KernelOrKext);
+  if (Args.hasFlag(options::OPT_funwind_tables, options::OPT_fno_unwind_tables,
+                   AsynchronousUnwindTables))
+    CmdArgs.push_back("-munwind-tables");
+
+  if (Arg *A = Args.getLastArg(options::OPT_flimited_precision_EQ)) {
+    CmdArgs.push_back("-mlimit-float-precision");
+    CmdArgs.push_back(A->getValue(Args));
+  }
+
+  // FIXME: Handle -mtune=.
+  (void) Args.hasArg(options::OPT_mtune_EQ);
+
+  if (Arg *A = Args.getLastArg(options::OPT_mcmodel_EQ)) {
+    CmdArgs.push_back("-mcode-model");
+    CmdArgs.push_back(A->getValue(Args));
+  }
+
+  // Add target specific cpu and features flags.
+  switch(getToolChain().getTriple().getArch()) {
+  default:
+    break;
+
+  case llvm::Triple::arm:
+  case llvm::Triple::thumb:
+    AddARMTargetArgs(Args, CmdArgs);
+    break;
+
+  case llvm::Triple::mips:
+  case llvm::Triple::mipsel:
+    AddMIPSTargetArgs(Args, CmdArgs);
+    break;
+
+  case llvm::Triple::x86:
+  case llvm::Triple::x86_64:
+    AddX86TargetArgs(Args, CmdArgs);
+    break;
+  }
+
+  // -fno-math-errno is default.
+  if (Args.hasFlag(options::OPT_fmath_errno,
+                   options::OPT_fno_math_errno,
+                   false))
+    CmdArgs.push_back("-fmath-errno");
+
+  Arg *Unsupported;
+  if ((Unsupported = Args.getLastArg(options::OPT_MG)) ||
+      (Unsupported = Args.getLastArg(options::OPT_iframework)) ||
+      (Unsupported = Args.getLastArg(options::OPT_fshort_enums)))
+    D.Diag(clang::diag::err_drv_clang_unsupported)
+      << Unsupported->getOption().getName();
+
+  Args.AddAllArgs(CmdArgs, options::OPT_v);
+  Args.AddLastArg(CmdArgs, options::OPT_P);
+  Args.AddLastArg(CmdArgs, options::OPT_print_ivar_layout);
+
+  // Special case debug options to only pass -g to clang. This is
+  // wrong.
+  Args.ClaimAllArgs(options::OPT_g_Group);
+  Arg *Garg = Args.getLastArg(options::OPT_g_Group);
+  if (Garg && Garg != Args.getLastArg(options::OPT_g0))
+    CmdArgs.push_back("-g");
+
+  Args.AddLastArg(CmdArgs, options::OPT_nostdinc);
+  Args.AddLastArg(CmdArgs, options::OPT_nostdincxx);
+  Args.AddLastArg(CmdArgs, options::OPT_nobuiltininc);
+
+  // Pass the path to compiler resource files.
+  CmdArgs.push_back("-resource-dir");
+  CmdArgs.push_back(D.ResourceDir.c_str());
+
+  // Add preprocessing options like -I, -D, etc. if we are using the
+  // preprocessor.
+  //
+  // FIXME: Support -fpreprocessed
+  types::ID InputType = Inputs[0].getType();
+  if (types::getPreprocessedType(InputType) != types::TY_INVALID)
+    AddPreprocessingOptions(D, Args, CmdArgs, Output, Inputs);
+
+  // Manually translate -O to -O2 and -O4 to -O3; let clang reject
+  // others.
+  if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
+    if (A->getOption().matches(options::OPT_O4))
+      CmdArgs.push_back("-O3");
+    else if (A->getValue(Args)[0] == '\0')
+      CmdArgs.push_back("-O2");
+    else
+      A->render(Args, CmdArgs);
+  }
+
+  Args.AddAllArgs(CmdArgs, options::OPT_W_Group);
+  Args.AddLastArg(CmdArgs, options::OPT_pedantic);
+  Args.AddLastArg(CmdArgs, options::OPT_pedantic_errors);
+  Args.AddLastArg(CmdArgs, options::OPT_w);
+
+  // Handle -{std, ansi, trigraphs} -- take the last of -{std, ansi}
+  // (-ansi is equivalent to -std=c89).
+  //
+  // If a std is supplied, only add -trigraphs if it follows the
+  // option.
+  if (Arg *Std = Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi)) {
+    if (Std->getOption().matches(options::OPT_ansi))
+      if (types::isCXX(InputType))
+        CmdArgs.push_back("-std=c++98");
+      else
+        CmdArgs.push_back("-std=c89");
+    else
+      Std->render(Args, CmdArgs);
+
+    if (Arg *A = Args.getLastArg(options::OPT_trigraphs))
+      if (A->getIndex() > Std->getIndex())
+        A->render(Args, CmdArgs);
+  } else {
+    // Honor -std-default.
+    //
+    // FIXME: Clang doesn't correctly handle -std= when the input language
+    // doesn't match. For the time being just ignore this for C++ inputs;
+    // eventually we want to do all the standard defaulting here instead of
+    // splitting it between the driver and clang -cc1.
+    if (!types::isCXX(InputType))
+        Args.AddAllArgsTranslated(CmdArgs, options::OPT_std_default_EQ,
+                                  "-std=", /*Joined=*/true);
+    Args.AddLastArg(CmdArgs, options::OPT_trigraphs);
+  }
+
+  if (Arg *A = Args.getLastArg(options::OPT_ftemplate_depth_)) {
+    CmdArgs.push_back("-ftemplate-depth");
+    CmdArgs.push_back(A->getValue(Args));
+  }
+
+  if (Args.hasArg(options::OPT__relocatable_pch))
+    CmdArgs.push_back("-relocatable-pch");
+
+  if (Arg *A = Args.getLastArg(options::OPT_fconstant_string_class_EQ)) {
+    CmdArgs.push_back("-fconstant-string-class");
+    CmdArgs.push_back(A->getValue(Args));
+  }
+
+  if (Arg *A = Args.getLastArg(options::OPT_ftabstop_EQ)) {
+    CmdArgs.push_back("-ftabstop");
+    CmdArgs.push_back(A->getValue(Args));
+  }
+
+  CmdArgs.push_back("-ferror-limit");
+  if (Arg *A = Args.getLastArg(options::OPT_ferror_limit_EQ))
+    CmdArgs.push_back(A->getValue(Args));
+  else
+    CmdArgs.push_back("19");
+
+  CmdArgs.push_back("-ftemplate-backtrace-limit");
+  if (Arg *A = Args.getLastArg(options::OPT_ftemplate_backtrace_limit_EQ))
+    CmdArgs.push_back(A->getValue(Args));
+  else
+    CmdArgs.push_back("10");
+  
+  // Pass -fmessage-length=.
+  CmdArgs.push_back("-fmessage-length");
+  if (Arg *A = Args.getLastArg(options::OPT_fmessage_length_EQ)) {
+    CmdArgs.push_back(A->getValue(Args));
+  } else {
+    // If -fmessage-length=N was not specified, determine whether this is a
+    // terminal and, if so, implicitly define -fmessage-length appropriately.
+    unsigned N = llvm::sys::Process::StandardErrColumns();
+    CmdArgs.push_back(Args.MakeArgString(llvm::Twine(N)));
+  }
+
+  if (const Arg *A = Args.getLastArg(options::OPT_fvisibility_EQ)) {
+    CmdArgs.push_back("-fvisibility");
+    CmdArgs.push_back(A->getValue(Args));
+  }
+
+  // -fhosted is default.
+  if (KernelOrKext || Args.hasFlag(options::OPT_ffreestanding,
+                                   options::OPT_fhosted,
+                                   false))
+    CmdArgs.push_back("-ffreestanding");
+
+  // Forward -f (flag) options which we can pass directly.
+  Args.AddLastArg(CmdArgs, options::OPT_fcatch_undefined_behavior);
+  Args.AddLastArg(CmdArgs, options::OPT_femit_all_decls);
+  Args.AddLastArg(CmdArgs, options::OPT_fheinous_gnu_extensions);
+
+  // -flax-vector-conversions is default.
+  if (!Args.hasFlag(options::OPT_flax_vector_conversions,
+                    options::OPT_fno_lax_vector_conversions))
+    CmdArgs.push_back("-fno-lax-vector-conversions");
+
+  // Handle -fobjc-gc and -fobjc-gc-only. They are exclusive, and -fobjc-gc-only
+  // takes precedence.
+  const Arg *GCArg = Args.getLastArg(options::OPT_fobjc_gc_only);
+  if (!GCArg)
+    GCArg = Args.getLastArg(options::OPT_fobjc_gc);
+  if (GCArg) {
+    if (getToolChain().SupportsObjCGC()) {
+      GCArg->render(Args, CmdArgs);
+    } else {
+      // FIXME: We should move this to a hard error.
+      D.Diag(clang::diag::warn_drv_objc_gc_unsupported)
+        << GCArg->getAsString(Args);
+    }
+  }
+
+  Args.AddLastArg(CmdArgs, options::OPT_fno_caret_diagnostics);
+  Args.AddLastArg(CmdArgs, options::OPT_fno_show_column);
+  Args.AddLastArg(CmdArgs, options::OPT_fobjc_sender_dependent_dispatch);
+  Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_print_source_range_info);
+  Args.AddLastArg(CmdArgs, options::OPT_ftime_report);
+  Args.AddLastArg(CmdArgs, options::OPT_ftrapv);
+  Args.AddLastArg(CmdArgs, options::OPT_fwritable_strings);
+
+  Args.AddLastArg(CmdArgs, options::OPT_pthread);
+
+  // -stack-protector=0 is default.
+  unsigned StackProtectorLevel = 0;
+  if (Arg *A = Args.getLastArg(options::OPT_fno_stack_protector,
+                               options::OPT_fstack_protector_all,
+                               options::OPT_fstack_protector)) {
+    if (A->getOption().matches(options::OPT_fstack_protector))
+      StackProtectorLevel = 1;
+    else if (A->getOption().matches(options::OPT_fstack_protector_all))
+      StackProtectorLevel = 2;
+  } else
+    StackProtectorLevel = getToolChain().GetDefaultStackProtectorLevel();
+  if (StackProtectorLevel) {
+    CmdArgs.push_back("-stack-protector");
+    CmdArgs.push_back(Args.MakeArgString(llvm::Twine(StackProtectorLevel)));
+  }
+
+  // Forward -f options with positive and negative forms; we translate
+  // these by hand.
+
+  // -fbuiltin is default.
+  if (!Args.hasFlag(options::OPT_fbuiltin, options::OPT_fno_builtin))
+    CmdArgs.push_back("-fno-builtin");
+
+  if (!Args.hasFlag(options::OPT_fassume_sane_operator_new,
+                    options::OPT_fno_assume_sane_operator_new))
+    CmdArgs.push_back("-fno-assume-sane-operator-new");
+
+  // -fblocks=0 is default.
+  if (Args.hasFlag(options::OPT_fblocks, options::OPT_fno_blocks,
+                   getToolChain().IsBlocksDefault())) {
+    CmdArgs.push_back("-fblocks");
+  }
+
+  // -faccess-control is default.
+  if (Args.hasFlag(options::OPT_fno_access_control,
+                   options::OPT_faccess_control,
+                   false))
+    CmdArgs.push_back("-fno-access-control");
+
+  // -fexceptions=0 is default.
+  if (needsExceptions(Args, InputType, getToolChain().getTriple()))
+    CmdArgs.push_back("-fexceptions");
+
+  if (getToolChain().UseSjLjExceptions())
+    CmdArgs.push_back("-fsjlj-exceptions");
+
+  // -frtti is default.
+  if (KernelOrKext ||
+      !Args.hasFlag(options::OPT_frtti, options::OPT_fno_rtti))
+    CmdArgs.push_back("-fno-rtti");
+
+  // -fsigned-char is default.
+  if (!Args.hasFlag(options::OPT_fsigned_char, options::OPT_funsigned_char,
+                    isSignedCharDefault(getToolChain().getTriple())))
+    CmdArgs.push_back("-fno-signed-char");
+
+  // -fthreadsafe-static is default.
+  if (!Args.hasFlag(options::OPT_fthreadsafe_statics, 
+                    options::OPT_fno_threadsafe_statics))
+    CmdArgs.push_back("-fno-threadsafe-statics");
+
+  // -fuse-cxa-atexit is default.
+  if (KernelOrKext || !Args.hasFlag(options::OPT_fuse_cxa_atexit,
+                                    options::OPT_fno_use_cxa_atexit))
+    CmdArgs.push_back("-fno-use-cxa-atexit");
+
+  // -fms-extensions=0 is default.
+  if (Args.hasFlag(options::OPT_fms_extensions, options::OPT_fno_ms_extensions,
+                   getToolChain().getTriple().getOS() == llvm::Triple::Win32))
+    CmdArgs.push_back("-fms-extensions");
+
+  // -fgnu-keywords default varies depending on language; only pass if
+  // specified.
+  if (Arg *A = Args.getLastArg(options::OPT_fgnu_keywords,
+                               options::OPT_fno_gnu_keywords))
+    A->render(Args, CmdArgs);
+
+  // -fnext-runtime is default.
+  if (!Args.hasFlag(options::OPT_fnext_runtime, options::OPT_fgnu_runtime,
+                    getToolChain().getTriple().getOS() == llvm::Triple::Darwin))
+    CmdArgs.push_back("-fgnu-runtime");
+
+  // -fobjc-nonfragile-abi=0 is default.
+  if (types::isObjC(InputType)) {
+    if (Args.hasArg(options::OPT_fobjc_nonfragile_abi) ||
+        getToolChain().IsObjCNonFragileABIDefault()) {
+      CmdArgs.push_back("-fobjc-nonfragile-abi");
+
+      // -fobjc-dispatch-method is only relevant with the nonfragile-abi, and
+      // legacy is the default.
+      if (!Args.hasFlag(options::OPT_fobjc_legacy_dispatch,
+                        options::OPT_fno_objc_legacy_dispatch,
+                        getToolChain().IsObjCLegacyDispatchDefault())) {
+        if (getToolChain().UseObjCMixedDispatch())
+          CmdArgs.push_back("-fobjc-dispatch-method=mixed");
+        else
+          CmdArgs.push_back("-fobjc-dispatch-method=non-legacy");
+      }
+    }
+  }
+
+  if (!Args.hasFlag(options::OPT_fassume_sane_operator_new,
+                    options::OPT_fno_assume_sane_operator_new))
+    CmdArgs.push_back("-fno-assume-sane-operator-new");
+
+  // -fshort-wchar default varies depending on platform; only
+  // pass if specified.
+  if (Arg *A = Args.getLastArg(options::OPT_fshort_wchar)) {
+    if (A->getOption().matches(options::OPT_fshort_wchar))
+      CmdArgs.push_back("-fshort-wchar");
+  }
+
+  // -fno-pascal-strings is default, only pass non-default. If the tool chain
+  // happened to translate to -mpascal-strings, we want to back translate here.
+  //
+  // FIXME: This is gross; that translation should be pulled from the
+  // tool chain.
+  if (Args.hasFlag(options::OPT_fpascal_strings,
+                   options::OPT_fno_pascal_strings,
+                   false) ||
+      Args.hasFlag(options::OPT_mpascal_strings,
+                   options::OPT_mno_pascal_strings,
+                   false))
+    CmdArgs.push_back("-fpascal-strings");
+
+  // -fcommon is default, only pass non-default.
+  if (!Args.hasFlag(options::OPT_fcommon, options::OPT_fno_common))
+    CmdArgs.push_back("-fno-common");
+
+  // -fsigned-bitfields is default, and clang doesn't yet support
+  // --funsigned-bitfields.
+  if (!Args.hasFlag(options::OPT_fsigned_bitfields,
+                    options::OPT_funsigned_bitfields))
+    D.Diag(clang::diag::warn_drv_clang_unsupported)
+      << Args.getLastArg(options::OPT_funsigned_bitfields)->getAsString(Args);
+
+  // -fdiagnostics-fixit-info is default, only pass non-default.
+  if (!Args.hasFlag(options::OPT_fdiagnostics_fixit_info,
+                    options::OPT_fno_diagnostics_fixit_info))
+    CmdArgs.push_back("-fno-diagnostics-fixit-info");
+
+  Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_binary);
+
+  // Enable -fdiagnostics-show-option by default.
+  if (Args.hasFlag(options::OPT_fdiagnostics_show_option,
+                   options::OPT_fno_diagnostics_show_option))
+    CmdArgs.push_back("-fdiagnostics-show-option");
+
+  // Color diagnostics are the default, unless the terminal doesn't support
+  // them.
+  if (Args.hasFlag(options::OPT_fcolor_diagnostics,
+                   options::OPT_fno_color_diagnostics) &&
+      llvm::sys::Process::StandardErrHasColors())
+    CmdArgs.push_back("-fcolor-diagnostics");
+
+  if (!Args.hasFlag(options::OPT_fshow_source_location,
+                    options::OPT_fno_show_source_location))
+    CmdArgs.push_back("-fno-show-source-location");
+
+  // -fdollars-in-identifiers default varies depending on platform and
+  // language; only pass if specified.
+  if (Arg *A = Args.getLastArg(options::OPT_fdollars_in_identifiers,
+                               options::OPT_fno_dollars_in_identifiers)) {
+    if (A->getOption().matches(options::OPT_fdollars_in_identifiers))
+      CmdArgs.push_back("-fdollars-in-identifiers");
+    else
+      CmdArgs.push_back("-fno-dollars-in-identifiers");
+  }
+
+  // -funit-at-a-time is default, and we don't support -fno-unit-at-a-time for
+  // practical purposes.
+  if (Arg *A = Args.getLastArg(options::OPT_funit_at_a_time,
+                               options::OPT_fno_unit_at_a_time)) {
+    if (A->getOption().matches(options::OPT_fno_unit_at_a_time))
+      D.Diag(clang::diag::warn_drv_clang_unsupported) << A->getAsString(Args);
+  }
+
+  // Default to -fno-builtin-str{cat,cpy} on Darwin for ARM.
+  //
+  // FIXME: This is disabled until clang -cc1 supports -fno-builtin-foo. PR4941.
+#if 0
+  if (getToolChain().getTriple().getOS() == llvm::Triple::Darwin &&
+      (getToolChain().getTriple().getArch() == llvm::Triple::arm ||
+       getToolChain().getTriple().getArch() == llvm::Triple::thumb)) {
+    if (!Args.hasArg(options::OPT_fbuiltin_strcat))
+      CmdArgs.push_back("-fno-builtin-strcat");
+    if (!Args.hasArg(options::OPT_fbuiltin_strcpy))
+      CmdArgs.push_back("-fno-builtin-strcpy");
+  }
+#endif
+
+  if (Arg *A = Args.getLastArg(options::OPT_traditional,
+                               options::OPT_traditional_cpp))
+    D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);
+
+  Args.AddLastArg(CmdArgs, options::OPT_dM);
+  Args.AddLastArg(CmdArgs, options::OPT_dD);
+
+  // Forward -Xclang arguments to -cc1, and -mllvm arguments to the LLVM option
+  // parser.
+  Args.AddAllArgValues(CmdArgs, options::OPT_Xclang);
+  for (arg_iterator it = Args.filtered_begin(options::OPT_mllvm),
+         ie = Args.filtered_end(); it != ie; ++it) {
+    it->claim();
+
+    // We translate this by hand to the -cc1 argument, since nightly test uses
+    // it and developers have been trained to spell it with -mllvm.
+    if (llvm::StringRef(it->getValue(Args, 0)) == "-disable-llvm-optzns")
+      CmdArgs.push_back("-disable-llvm-optzns");
+    else
+      it->render(Args, CmdArgs);
+  }
+
+  if (Output.getType() == types::TY_Dependencies) {
+    // Handled with other dependency code.
+  } else if (Output.isPipe()) {
+    CmdArgs.push_back("-o");
+    CmdArgs.push_back("-");
+  } else if (Output.isFilename()) {
+    CmdArgs.push_back("-o");
+    CmdArgs.push_back(Output.getFilename());
+  } else {
+    assert(Output.isNothing() && "Invalid output.");
+  }
+
+  for (InputInfoList::const_iterator
+         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
+    const InputInfo &II = *it;
+    CmdArgs.push_back("-x");
+    CmdArgs.push_back(types::getTypeName(II.getType()));
+    if (II.isPipe())
+      CmdArgs.push_back("-");
+    else if (II.isFilename())
+      CmdArgs.push_back(II.getFilename());
+    else
+      II.getInputArg().renderAsInput(Args, CmdArgs);
+  }
+
+  Args.AddAllArgs(CmdArgs, options::OPT_undef);
+
+  const char *Exec =
+    Args.MakeArgString(getToolChain().GetProgramPath(C, "clang"));
+
+  // Optionally embed the -cc1 level arguments into the debug info, for build
+  // analysis.
+  if (getToolChain().UseDwarfDebugFlags()) {
+    llvm::SmallString<256> Flags;
+    Flags += Exec;
+    for (unsigned i = 0, e = CmdArgs.size(); i != e; ++i) {
+      Flags += " ";
+      Flags += CmdArgs[i];
+    }
+    CmdArgs.push_back("-dwarf-debug-flags");
+    CmdArgs.push_back(Args.MakeArgString(Flags.str()));
+  }
+
+  Dest.addCommand(new Command(JA, *this, Exec, CmdArgs));
+
+  // Explicitly warn that these options are unsupported, even though
+  // we are allowing compilation to continue.
+  for (arg_iterator it = Args.filtered_begin(options::OPT_pg),
+         ie = Args.filtered_end(); it != ie; ++it) {
+    it->claim();
+    D.Diag(clang::diag::warn_drv_clang_unsupported) << it->getAsString(Args);
+  }
+
+  // Claim some arguments which clang supports automatically.
+
+  // -fpch-preprocess is used with gcc to add a special marker in the output to
+  // include the PCH file. Clang's PTH solution is completely transparent, so we
+  // do not need to deal with it at all.
+  Args.ClaimAllArgs(options::OPT_fpch_preprocess);
+
+  // Claim some arguments which clang doesn't support, but we don't
+  // care to warn the user about.
+  Args.ClaimAllArgs(options::OPT_clang_ignored_f_Group);
+  Args.ClaimAllArgs(options::OPT_clang_ignored_m_Group);
+}
+
+void gcc::Common::ConstructJob(Compilation &C, const JobAction &JA,
+                               Job &Dest,
+                               const InputInfo &Output,
+                               const InputInfoList &Inputs,
+                               const ArgList &Args,
+                               const char *LinkingOutput) const {
+  const Driver &D = getToolChain().getDriver();
+  ArgStringList CmdArgs;
+
+  for (ArgList::const_iterator
+         it = Args.begin(), ie = Args.end(); it != ie; ++it) {
+    Arg *A = *it;
+    if (A->getOption().hasForwardToGCC()) {
+      // It is unfortunate that we have to claim here, as this means
+      // we will basically never report anything interesting for
+      // platforms using a generic gcc, even if we are just using gcc
+      // to get to the assembler.
+      A->claim();
+      A->render(Args, CmdArgs);
+    }
+  }
+
+  RenderExtraToolArgs(JA, CmdArgs);
+
+  // If using a driver driver, force the arch.
+  const std::string &Arch = getToolChain().getArchName();
+  if (getToolChain().getTriple().getOS() == llvm::Triple::Darwin) {
+    CmdArgs.push_back("-arch");
+
+    // FIXME: Remove these special cases.
+    if (Arch == "powerpc")
+      CmdArgs.push_back("ppc");
+    else if (Arch == "powerpc64")
+      CmdArgs.push_back("ppc64");
+    else
+      CmdArgs.push_back(Args.MakeArgString(Arch));
+  }
+
+  // Try to force gcc to match the tool chain we want, if we recognize
+  // the arch.
+  //
+  // FIXME: The triple class should directly provide the information we want
+  // here.
+  if (Arch == "i386" || Arch == "powerpc")
+    CmdArgs.push_back("-m32");
+  else if (Arch == "x86_64" || Arch == "powerpc64")
+    CmdArgs.push_back("-m64");
+
+  if (Output.isPipe()) {
+    CmdArgs.push_back("-o");
+    CmdArgs.push_back("-");
+  } else if (Output.isFilename()) {
+    CmdArgs.push_back("-o");
+    CmdArgs.push_back(Output.getFilename());
+  } else {
+    assert(Output.isNothing() && "Unexpected output");
+    CmdArgs.push_back("-fsyntax-only");
+  }
+
+
+  // Only pass -x if gcc will understand it; otherwise hope gcc
+  // understands the suffix correctly. The main use case this would go
+  // wrong in is for linker inputs if they happened to have an odd
+  // suffix; really the only way to get this to happen is a command
+  // like '-x foobar a.c' which will treat a.c like a linker input.
+  //
+  // FIXME: For the linker case specifically, can we safely convert
+  // inputs into '-Wl,' options?
+  for (InputInfoList::const_iterator
+         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
+    const InputInfo &II = *it;
+
+    // Don't try to pass LLVM or AST inputs to a generic gcc.
+    if (II.getType() == types::TY_LLVMBC)
+      D.Diag(clang::diag::err_drv_no_linker_llvm_support)
+        << getToolChain().getTripleString();
+    else if (II.getType() == types::TY_AST)
+      D.Diag(clang::diag::err_drv_no_ast_support)
+        << getToolChain().getTripleString();
+
+    if (types::canTypeBeUserSpecified(II.getType())) {
+      CmdArgs.push_back("-x");
+      CmdArgs.push_back(types::getTypeName(II.getType()));
+    }
+
+    if (II.isPipe())
+      CmdArgs.push_back("-");
+    else if (II.isFilename())
+      CmdArgs.push_back(II.getFilename());
+    else
+      // Don't render as input, we need gcc to do the translations.
+      II.getInputArg().render(Args, CmdArgs);
+  }
+
+  const char *GCCName = getToolChain().getDriver().CCCGenericGCCName.c_str();
+  const char *Exec =
+    Args.MakeArgString(getToolChain().GetProgramPath(C, GCCName));
+  Dest.addCommand(new Command(JA, *this, Exec, CmdArgs));
+}
+
+void gcc::Preprocess::RenderExtraToolArgs(const JobAction &JA,
+                                          ArgStringList &CmdArgs) const {
+  CmdArgs.push_back("-E");
+}
+
+void gcc::Precompile::RenderExtraToolArgs(const JobAction &JA,
+                                          ArgStringList &CmdArgs) const {
+  // The type is good enough.
+}
+
+void gcc::Compile::RenderExtraToolArgs(const JobAction &JA,
+                                       ArgStringList &CmdArgs) const {
+  const Driver &D = getToolChain().getDriver();
+
+  // If -flto, etc. are present then make sure not to force assembly output.
+  if (JA.getType() == types::TY_LLVMBC)
+    CmdArgs.push_back("-c");
+  else {
+    if (JA.getType() != types::TY_PP_Asm)
+      D.Diag(clang::diag::err_drv_invalid_gcc_output_type)
+        << getTypeName(JA.getType());
+      
+    CmdArgs.push_back("-S");
+  }
+}
+
+void gcc::Assemble::RenderExtraToolArgs(const JobAction &JA,
+                                        ArgStringList &CmdArgs) const {
+  CmdArgs.push_back("-c");
+}
+
+void gcc::Link::RenderExtraToolArgs(const JobAction &JA,
+                                    ArgStringList &CmdArgs) const {
+  // The types are (hopefully) good enough.
+}
+
+const char *darwin::CC1::getCC1Name(types::ID Type) const {
+  switch (Type) {
+  default:
+    assert(0 && "Unexpected type for Darwin CC1 tool.");
+  case types::TY_Asm:
+  case types::TY_C: case types::TY_CHeader:
+  case types::TY_PP_C: case types::TY_PP_CHeader:
+    return "cc1";
+  case types::TY_ObjC: case types::TY_ObjCHeader:
+  case types::TY_PP_ObjC: case types::TY_PP_ObjCHeader:
+    return "cc1obj";
+  case types::TY_CXX: case types::TY_CXXHeader:
+  case types::TY_PP_CXX: case types::TY_PP_CXXHeader:
+    return "cc1plus";
+  case types::TY_ObjCXX: case types::TY_ObjCXXHeader:
+  case types::TY_PP_ObjCXX: case types::TY_PP_ObjCXXHeader:
+    return "cc1objplus";
+  }
+}
+
+const char *darwin::CC1::getBaseInputName(const ArgList &Args,
+                                          const InputInfoList &Inputs) {
+  llvm::sys::Path P(Inputs[0].getBaseInput());
+  return Args.MakeArgString(P.getLast());
+}
+
+const char *darwin::CC1::getBaseInputStem(const ArgList &Args,
+                                          const InputInfoList &Inputs) {
+  const char *Str = getBaseInputName(Args, Inputs);
+
+  if (const char *End = strchr(Str, '.'))
+    return Args.MakeArgString(std::string(Str, End));
+
+  return Str;
+}
+
+const char *
+darwin::CC1::getDependencyFileName(const ArgList &Args,
+                                   const InputInfoList &Inputs) {
+  // FIXME: Think about this more.
+  std::string Res;
+
+  if (Arg *OutputOpt = Args.getLastArg(options::OPT_o)) {
+    std::string Str(OutputOpt->getValue(Args));
+
+    Res = Str.substr(0, Str.rfind('.'));
+  } else
+    Res = darwin::CC1::getBaseInputStem(Args, Inputs);
+
+  return Args.MakeArgString(Res + ".d");
+}
+
+void darwin::CC1::AddCC1Args(const ArgList &Args,
+                             ArgStringList &CmdArgs) const {
+  const Driver &D = getToolChain().getDriver();
+
+  CheckCodeGenerationOptions(D, Args);
+
+  // Derived from cc1 spec.
+  if (!Args.hasArg(options::OPT_mkernel) && !Args.hasArg(options::OPT_static) &&
+      !Args.hasArg(options::OPT_mdynamic_no_pic))
+    CmdArgs.push_back("-fPIC");
+
+  if (getToolChain().getTriple().getArch() == llvm::Triple::arm ||
+      getToolChain().getTriple().getArch() == llvm::Triple::thumb) {
+    if (!Args.hasArg(options::OPT_fbuiltin_strcat))
+      CmdArgs.push_back("-fno-builtin-strcat");
+    if (!Args.hasArg(options::OPT_fbuiltin_strcpy))
+      CmdArgs.push_back("-fno-builtin-strcpy");
+  }
+
+  // gcc has some code here to deal with when no -mmacosx-version-min
+  // and no -miphoneos-version-min is present, but this never happens
+  // due to tool chain specific argument translation.
+
+  if (Args.hasArg(options::OPT_g_Flag) &&
+      !Args.hasArg(options::OPT_fno_eliminate_unused_debug_symbols))
+    CmdArgs.push_back("-feliminate-unused-debug-symbols");
+}
+
+void darwin::CC1::AddCC1OptionsArgs(const ArgList &Args, ArgStringList &CmdArgs,
+                                    const InputInfoList &Inputs,
+                                    const ArgStringList &OutputArgs) const {
+  const Driver &D = getToolChain().getDriver();
+
+  // Derived from cc1_options spec.
+  if (Args.hasArg(options::OPT_fast) ||
+      Args.hasArg(options::OPT_fastf) ||
+      Args.hasArg(options::OPT_fastcp))
+    CmdArgs.push_back("-O3");
+
+  if (Arg *A = Args.getLastArg(options::OPT_pg))
+    if (Args.hasArg(options::OPT_fomit_frame_pointer))
+      D.Diag(clang::diag::err_drv_argument_not_allowed_with)
+        << A->getAsString(Args) << "-fomit-frame-pointer";
+
+  AddCC1Args(Args, CmdArgs);
+
+  if (!Args.hasArg(options::OPT_Q))
+    CmdArgs.push_back("-quiet");
+
+  CmdArgs.push_back("-dumpbase");
+  CmdArgs.push_back(darwin::CC1::getBaseInputName(Args, Inputs));
+
+  Args.AddAllArgs(CmdArgs, options::OPT_d_Group);
+
+  Args.AddAllArgs(CmdArgs, options::OPT_m_Group);
+  Args.AddAllArgs(CmdArgs, options::OPT_a_Group);
+
+  // FIXME: The goal is to use the user provided -o if that is our
+  // final output, otherwise to drive from the original input
+  // name. Find a clean way to go about this.
+  if ((Args.hasArg(options::OPT_c) || Args.hasArg(options::OPT_S)) &&
+      Args.hasArg(options::OPT_o)) {
+    Arg *OutputOpt = Args.getLastArg(options::OPT_o);
+    CmdArgs.push_back("-auxbase-strip");
+    CmdArgs.push_back(OutputOpt->getValue(Args));
+  } else {
+    CmdArgs.push_back("-auxbase");
+    CmdArgs.push_back(darwin::CC1::getBaseInputStem(Args, Inputs));
+  }
+
+  Args.AddAllArgs(CmdArgs, options::OPT_g_Group);
+
+  Args.AddAllArgs(CmdArgs, options::OPT_O);
+  // FIXME: -Wall is getting some special treatment. Investigate.
+  Args.AddAllArgs(CmdArgs, options::OPT_W_Group, options::OPT_pedantic_Group);
+  Args.AddLastArg(CmdArgs, options::OPT_w);
+  Args.AddAllArgs(CmdArgs, options::OPT_std_EQ, options::OPT_ansi,
+                  options::OPT_trigraphs);
+  if (!Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi)) {
+    // Honor -std-default.
+    Args.AddAllArgsTranslated(CmdArgs, options::OPT_std_default_EQ,
+                              "-std=", /*Joined=*/true);
+  }
+
+  if (Args.hasArg(options::OPT_v))
+    CmdArgs.push_back("-version");
+  if (Args.hasArg(options::OPT_pg))
+    CmdArgs.push_back("-p");
+  Args.AddLastArg(CmdArgs, options::OPT_p);
+
+  // The driver treats -fsyntax-only specially.
+  if (getToolChain().getTriple().getArch() == llvm::Triple::arm ||
+      getToolChain().getTriple().getArch() == llvm::Triple::thumb) {
+    // Removes -fbuiltin-str{cat,cpy}; these aren't recognized by cc1 but are
+    // used to inhibit the default -fno-builtin-str{cat,cpy}.
+    //
+    // FIXME: Should we grow a better way to deal with "removing" args?
+    for (arg_iterator it = Args.filtered_begin(options::OPT_f_Group,
+                                               options::OPT_fsyntax_only),
+           ie = Args.filtered_end(); it != ie; ++it) {
+      if (!it->getOption().matches(options::OPT_fbuiltin_strcat) &&
+          !it->getOption().matches(options::OPT_fbuiltin_strcpy)) {
+        it->claim();
+        it->render(Args, CmdArgs);
+      }
+    }
+  } else
+    Args.AddAllArgs(CmdArgs, options::OPT_f_Group, options::OPT_fsyntax_only);
+
+  Args.AddAllArgs(CmdArgs, options::OPT_undef);
+  if (Args.hasArg(options::OPT_Qn))
+    CmdArgs.push_back("-fno-ident");
+
+  // FIXME: This isn't correct.
+  //Args.AddLastArg(CmdArgs, options::OPT__help)
+  //Args.AddLastArg(CmdArgs, options::OPT__targetHelp)
+
+  CmdArgs.append(OutputArgs.begin(), OutputArgs.end());
+
+  // FIXME: Still don't get what is happening here. Investigate.
+  Args.AddAllArgs(CmdArgs, options::OPT__param);
+
+  if (Args.hasArg(options::OPT_fmudflap) ||
+      Args.hasArg(options::OPT_fmudflapth)) {
+    CmdArgs.push_back("-fno-builtin");
+    CmdArgs.push_back("-fno-merge-constants");
+  }
+
+  if (Args.hasArg(options::OPT_coverage)) {
+    CmdArgs.push_back("-fprofile-arcs");
+    CmdArgs.push_back("-ftest-coverage");
+  }
+
+  if (types::isCXX(Inputs[0].getType()))
+    CmdArgs.push_back("-D__private_extern__=extern");
+}
+
+void darwin::CC1::AddCPPOptionsArgs(const ArgList &Args, ArgStringList &CmdArgs,
+                                    const InputInfoList &Inputs,
+                                    const ArgStringList &OutputArgs) const {
+  // Derived from cpp_options
+  AddCPPUniqueOptionsArgs(Args, CmdArgs, Inputs);
+
+  CmdArgs.append(OutputArgs.begin(), OutputArgs.end());
+
+  AddCC1Args(Args, CmdArgs);
+
+  // NOTE: The code below has some commonality with cpp_options, but
+  // in classic gcc style ends up sending things in different
+  // orders. This may be a good merge candidate once we drop pedantic
+  // compatibility.
+
+  Args.AddAllArgs(CmdArgs, options::OPT_m_Group);
+  Args.AddAllArgs(CmdArgs, options::OPT_std_EQ, options::OPT_ansi,
+                  options::OPT_trigraphs);
+  if (!Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi)) {
+    // Honor -std-default.
+    Args.AddAllArgsTranslated(CmdArgs, options::OPT_std_default_EQ,
+                              "-std=", /*Joined=*/true);
+  }
+  Args.AddAllArgs(CmdArgs, options::OPT_W_Group, options::OPT_pedantic_Group);
+  Args.AddLastArg(CmdArgs, options::OPT_w);
+
+  // The driver treats -fsyntax-only specially.
+  Args.AddAllArgs(CmdArgs, options::OPT_f_Group, options::OPT_fsyntax_only);
+
+  if (Args.hasArg(options::OPT_g_Group) && !Args.hasArg(options::OPT_g0) &&
+      !Args.hasArg(options::OPT_fno_working_directory))
+    CmdArgs.push_back("-fworking-directory");
+
+  Args.AddAllArgs(CmdArgs, options::OPT_O);
+  Args.AddAllArgs(CmdArgs, options::OPT_undef);
+  if (Args.hasArg(options::OPT_save_temps))
+    CmdArgs.push_back("-fpch-preprocess");
+}
+
+void darwin::CC1::AddCPPUniqueOptionsArgs(const ArgList &Args,
+                                          ArgStringList &CmdArgs,
+                                          const InputInfoList &Inputs) const {
+  const Driver &D = getToolChain().getDriver();
+
+  CheckPreprocessingOptions(D, Args);
+
+  // Derived from cpp_unique_options.
+  // -{C,CC} only with -E is checked in CheckPreprocessingOptions().
+  Args.AddLastArg(CmdArgs, options::OPT_C);
+  Args.AddLastArg(CmdArgs, options::OPT_CC);
+  if (!Args.hasArg(options::OPT_Q))
+    CmdArgs.push_back("-quiet");
+  Args.AddAllArgs(CmdArgs, options::OPT_nostdinc);
+  Args.AddAllArgs(CmdArgs, options::OPT_nostdincxx);
+  Args.AddLastArg(CmdArgs, options::OPT_v);
+  Args.AddAllArgs(CmdArgs, options::OPT_I_Group, options::OPT_F);
+  Args.AddLastArg(CmdArgs, options::OPT_P);
+
+  // FIXME: Handle %I properly.
+  if (getToolChain().getArchName() == "x86_64") {
+    CmdArgs.push_back("-imultilib");
+    CmdArgs.push_back("x86_64");
+  }
+
+  if (Args.hasArg(options::OPT_MD)) {
+    CmdArgs.push_back("-MD");
+    CmdArgs.push_back(darwin::CC1::getDependencyFileName(Args, Inputs));
+  }
+
+  if (Args.hasArg(options::OPT_MMD)) {
+    CmdArgs.push_back("-MMD");
+    CmdArgs.push_back(darwin::CC1::getDependencyFileName(Args, Inputs));
+  }
+
+  Args.AddLastArg(CmdArgs, options::OPT_M);
+  Args.AddLastArg(CmdArgs, options::OPT_MM);
+  Args.AddAllArgs(CmdArgs, options::OPT_MF);
+  Args.AddLastArg(CmdArgs, options::OPT_MG);
+  Args.AddLastArg(CmdArgs, options::OPT_MP);
+  Args.AddAllArgs(CmdArgs, options::OPT_MQ);
+  Args.AddAllArgs(CmdArgs, options::OPT_MT);
+  if (!Args.hasArg(options::OPT_M) && !Args.hasArg(options::OPT_MM) &&
+      (Args.hasArg(options::OPT_MD) || Args.hasArg(options::OPT_MMD))) {
+    if (Arg *OutputOpt = Args.getLastArg(options::OPT_o)) {
+      CmdArgs.push_back("-MQ");
+      CmdArgs.push_back(OutputOpt->getValue(Args));
+    }
+  }
+
+  Args.AddLastArg(CmdArgs, options::OPT_remap);
+  if (Args.hasArg(options::OPT_g3))
+    CmdArgs.push_back("-dD");
+  Args.AddLastArg(CmdArgs, options::OPT_H);
+
+  AddCPPArgs(Args, CmdArgs);
+
+  Args.AddAllArgs(CmdArgs, options::OPT_D, options::OPT_U, options::OPT_A);
+  Args.AddAllArgs(CmdArgs, options::OPT_i_Group);
+
+  for (InputInfoList::const_iterator
+         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
+    const InputInfo &II = *it;
+
+    if (II.isPipe())
+      CmdArgs.push_back("-");
+    else
+      CmdArgs.push_back(II.getFilename());
+  }
+
+  Args.AddAllArgValues(CmdArgs, options::OPT_Wp_COMMA,
+                       options::OPT_Xpreprocessor);
+
+  if (Args.hasArg(options::OPT_fmudflap)) {
+    CmdArgs.push_back("-D_MUDFLAP");
+    CmdArgs.push_back("-include");
+    CmdArgs.push_back("mf-runtime.h");
+  }
+
+  if (Args.hasArg(options::OPT_fmudflapth)) {
+    CmdArgs.push_back("-D_MUDFLAP");
+    CmdArgs.push_back("-D_MUDFLAPTH");
+    CmdArgs.push_back("-include");
+    CmdArgs.push_back("mf-runtime.h");
+  }
+}
+
+void darwin::CC1::AddCPPArgs(const ArgList &Args,
+                             ArgStringList &CmdArgs) const {
+  // Derived from cpp spec.
+
+  if (Args.hasArg(options::OPT_static)) {
+    // The gcc spec is broken here, it refers to dynamic but
+    // that has been translated. Start by being bug compatible.
+
+    // if (!Args.hasArg(arglist.parser.dynamicOption))
+    CmdArgs.push_back("-D__STATIC__");
+  } else
+    CmdArgs.push_back("-D__DYNAMIC__");
+
+  if (Args.hasArg(options::OPT_pthread))
+    CmdArgs.push_back("-D_REENTRANT");
+}
+
+void darwin::Preprocess::ConstructJob(Compilation &C, const JobAction &JA,
+                                      Job &Dest, const InputInfo &Output,
+                                      const InputInfoList &Inputs,
+                                      const ArgList &Args,
+                                      const char *LinkingOutput) const {
+  ArgStringList CmdArgs;
+
+  assert(Inputs.size() == 1 && "Unexpected number of inputs!");
+
+  CmdArgs.push_back("-E");
+
+  if (Args.hasArg(options::OPT_traditional) ||
+      Args.hasArg(options::OPT_traditional_cpp))
+    CmdArgs.push_back("-traditional-cpp");
+
+  ArgStringList OutputArgs;
+  if (Output.isFilename()) {
+    OutputArgs.push_back("-o");
+    OutputArgs.push_back(Output.getFilename());
+  } else {
+    assert(Output.isPipe() && "Unexpected CC1 output.");
+  }
+
+  if (Args.hasArg(options::OPT_E)) {
+    AddCPPOptionsArgs(Args, CmdArgs, Inputs, OutputArgs);
+  } else {
+    AddCPPOptionsArgs(Args, CmdArgs, Inputs, ArgStringList());
+    CmdArgs.append(OutputArgs.begin(), OutputArgs.end());
+  }
+
+  Args.AddAllArgs(CmdArgs, options::OPT_d_Group);
+
+  const char *CC1Name = getCC1Name(Inputs[0].getType());
+  const char *Exec =
+    Args.MakeArgString(getToolChain().GetProgramPath(C, CC1Name));
+  Dest.addCommand(new Command(JA, *this, Exec, CmdArgs));
+}
+
+void darwin::Compile::ConstructJob(Compilation &C, const JobAction &JA,
+                                   Job &Dest, const InputInfo &Output,
+                                   const InputInfoList &Inputs,
+                                   const ArgList &Args,
+                                   const char *LinkingOutput) const {
+  const Driver &D = getToolChain().getDriver();
+  ArgStringList CmdArgs;
+
+  assert(Inputs.size() == 1 && "Unexpected number of inputs!");
+
+  types::ID InputType = Inputs[0].getType();
+  const Arg *A;
+  if ((A = Args.getLastArg(options::OPT_traditional)))
+    D.Diag(clang::diag::err_drv_argument_only_allowed_with)
+      << A->getAsString(Args) << "-E";
+
+  if (Output.getType() == types::TY_LLVMAsm)
+    CmdArgs.push_back("-emit-llvm");
+  else if (Output.getType() == types::TY_LLVMBC)
+    CmdArgs.push_back("-emit-llvm-bc");
+  else if (Output.getType() == types::TY_AST)
+    D.Diag(clang::diag::err_drv_no_ast_support)
+      << getToolChain().getTripleString();
+  else if (JA.getType() != types::TY_PP_Asm &&
+           JA.getType() != types::TY_PCH)
+    D.Diag(clang::diag::err_drv_invalid_gcc_output_type)
+      << getTypeName(JA.getType());
+
+  ArgStringList OutputArgs;
+  if (Output.getType() != types::TY_PCH) {
+    OutputArgs.push_back("-o");
+    if (Output.isPipe())
+      OutputArgs.push_back("-");
+    else if (Output.isNothing())
+      OutputArgs.push_back("/dev/null");
+    else
+      OutputArgs.push_back(Output.getFilename());
+  }
+
+  // There is no need for this level of compatibility, but it makes
+  // diffing easier.
+  bool OutputArgsEarly = (Args.hasArg(options::OPT_fsyntax_only) ||
+                          Args.hasArg(options::OPT_S));
+
+  if (types::getPreprocessedType(InputType) != types::TY_INVALID) {
+    AddCPPUniqueOptionsArgs(Args, CmdArgs, Inputs);
+    if (OutputArgsEarly) {
+      AddCC1OptionsArgs(Args, CmdArgs, Inputs, OutputArgs);
+    } else {
+      AddCC1OptionsArgs(Args, CmdArgs, Inputs, ArgStringList());
+      CmdArgs.append(OutputArgs.begin(), OutputArgs.end());
+    }
+  } else {
+    CmdArgs.push_back("-fpreprocessed");
+
+    for (InputInfoList::const_iterator
+           it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
+      const InputInfo &II = *it;
+
+      // Reject AST inputs.
+      if (II.getType() == types::TY_AST) {
+        D.Diag(clang::diag::err_drv_no_ast_support)
+          << getToolChain().getTripleString();
+        return;
+      }
+
+      if (II.isPipe())
+        CmdArgs.push_back("-");
+      else
+        CmdArgs.push_back(II.getFilename());
+    }
+
+    if (OutputArgsEarly) {
+      AddCC1OptionsArgs(Args, CmdArgs, Inputs, OutputArgs);
+    } else {
+      AddCC1OptionsArgs(Args, CmdArgs, Inputs, ArgStringList());
+      CmdArgs.append(OutputArgs.begin(), OutputArgs.end());
+    }
+  }
+
+  if (Output.getType() == types::TY_PCH) {
+    assert(Output.isFilename() && "Invalid PCH output.");
+
+    CmdArgs.push_back("-o");
+    // NOTE: gcc uses a temp .s file for this, but there doesn't seem
+    // to be a good reason.
+    CmdArgs.push_back("/dev/null");
+
+    CmdArgs.push_back("--output-pch=");
+    CmdArgs.push_back(Output.getFilename());
+  }
+
+  const char *CC1Name = getCC1Name(Inputs[0].getType());
+  const char *Exec =
+    Args.MakeArgString(getToolChain().GetProgramPath(C, CC1Name));
+  Dest.addCommand(new Command(JA, *this, Exec, CmdArgs));
+}
+
+void darwin::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
+                                    Job &Dest, const InputInfo &Output,
+                                    const InputInfoList &Inputs,
+                                    const ArgList &Args,
+                                    const char *LinkingOutput) const {
+  ArgStringList CmdArgs;
+
+  assert(Inputs.size() == 1 && "Unexpected number of inputs.");
+  const InputInfo &Input = Inputs[0];
+
+  // Bit of a hack, this is only used for original inputs.
+  //
+  // FIXME: This is broken for preprocessed .s inputs.
+  if (Input.isFilename() &&
+      strcmp(Input.getFilename(), Input.getBaseInput()) == 0) {
+    if (Args.hasArg(options::OPT_gstabs))
+      CmdArgs.push_back("--gstabs");
+    else if (Args.hasArg(options::OPT_g_Group))
+      CmdArgs.push_back("--gdwarf2");
+  }
+
+  // Derived from asm spec.
+  AddDarwinArch(Args, CmdArgs);
+
+  if (!getDarwinToolChain().isTargetIPhoneOS() ||
+      Args.hasArg(options::OPT_force__cpusubtype__ALL))
+    CmdArgs.push_back("-force_cpusubtype_ALL");
+
+  if (getToolChain().getTriple().getArch() != llvm::Triple::x86_64 &&
+      (Args.hasArg(options::OPT_mkernel) ||
+       Args.hasArg(options::OPT_static) ||
+       Args.hasArg(options::OPT_fapple_kext)))
+    CmdArgs.push_back("-static");
+
+  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
+                       options::OPT_Xassembler);
+
+  assert(Output.isFilename() && "Unexpected lipo output.");
+  CmdArgs.push_back("-o");
+  CmdArgs.push_back(Output.getFilename());
+
+  if (Input.isPipe()) {
+    CmdArgs.push_back("-");
+  } else {
+    assert(Input.isFilename() && "Invalid input.");
+    CmdArgs.push_back(Input.getFilename());
+  }
+
+  // asm_final spec is empty.
+
+  const char *Exec =
+    Args.MakeArgString(getToolChain().GetProgramPath(C, "as"));
+  Dest.addCommand(new Command(JA, *this, Exec, CmdArgs));
+}
+
+/// Helper routine for seeing if we should use dsymutil; this is a
+/// gcc compatible hack, we should remove it and use the input
+/// type information.
+static bool isSourceSuffix(const char *Str) {
+  // match: 'C', 'CPP', 'c', 'cc', 'cp', 'c++', 'cpp', 'cxx', 'm',
+  // 'mm'.
+  return llvm::StringSwitch<bool>(Str)
+           .Case("C", true)
+           .Case("c", true)
+           .Case("m", true)
+           .Case("cc", true)
+           .Case("cp", true)
+           .Case("mm", true)
+           .Case("CPP", true)
+           .Case("c++", true)
+           .Case("cpp", true)
+           .Case("cxx", true)
+           .Default(false);
+}
+
+void darwin::DarwinTool::AddDarwinArch(const ArgList &Args,
+                                       ArgStringList &CmdArgs) const {
+  llvm::StringRef ArchName = getDarwinToolChain().getDarwinArchName(Args);
+
+  // Derived from darwin_arch spec.
+  CmdArgs.push_back("-arch");
+  CmdArgs.push_back(Args.MakeArgString(ArchName));
+
+  // FIXME: Is this needed anymore?
+  if (ArchName == "arm")
+    CmdArgs.push_back("-force_cpusubtype_ALL");
+}
+
+void darwin::Link::AddLinkArgs(const ArgList &Args,
+                               ArgStringList &CmdArgs) const {
+  const Driver &D = getToolChain().getDriver();
+
+  // Derived from the "link" spec.
+  Args.AddAllArgs(CmdArgs, options::OPT_static);
+  if (!Args.hasArg(options::OPT_static))
+    CmdArgs.push_back("-dynamic");
+  if (Args.hasArg(options::OPT_fgnu_runtime)) {
+    // FIXME: gcc replaces -lobjc in forward args with -lobjc-gnu
+    // here. How do we wish to handle such things?
+  }
+
+  if (!Args.hasArg(options::OPT_dynamiclib)) {
+    AddDarwinArch(Args, CmdArgs);
+    // FIXME: Why do this only on this path?
+    Args.AddLastArg(CmdArgs, options::OPT_force__cpusubtype__ALL);
+
+    Args.AddLastArg(CmdArgs, options::OPT_bundle);
+    Args.AddAllArgs(CmdArgs, options::OPT_bundle__loader);
+    Args.AddAllArgs(CmdArgs, options::OPT_client__name);
+
+    Arg *A;
+    if ((A = Args.getLastArg(options::OPT_compatibility__version)) ||
+        (A = Args.getLastArg(options::OPT_current__version)) ||
+        (A = Args.getLastArg(options::OPT_install__name)))
+      D.Diag(clang::diag::err_drv_argument_only_allowed_with)
+        << A->getAsString(Args) << "-dynamiclib";
+
+    Args.AddLastArg(CmdArgs, options::OPT_force__flat__namespace);
+    Args.AddLastArg(CmdArgs, options::OPT_keep__private__externs);
+    Args.AddLastArg(CmdArgs, options::OPT_private__bundle);
+  } else {
+    CmdArgs.push_back("-dylib");
+
+    Arg *A;
+    if ((A = Args.getLastArg(options::OPT_bundle)) ||
+        (A = Args.getLastArg(options::OPT_bundle__loader)) ||
+        (A = Args.getLastArg(options::OPT_client__name)) ||
+        (A = Args.getLastArg(options::OPT_force__flat__namespace)) ||
+        (A = Args.getLastArg(options::OPT_keep__private__externs)) ||
+        (A = Args.getLastArg(options::OPT_private__bundle)))
+      D.Diag(clang::diag::err_drv_argument_not_allowed_with)
+        << A->getAsString(Args) << "-dynamiclib";
+
+    Args.AddAllArgsTranslated(CmdArgs, options::OPT_compatibility__version,
+                              "-dylib_compatibility_version");
+    Args.AddAllArgsTranslated(CmdArgs, options::OPT_current__version,
+                              "-dylib_current_version");
+
+    AddDarwinArch(Args, CmdArgs);
+
+    Args.AddAllArgsTranslated(CmdArgs, options::OPT_install__name,
+                              "-dylib_install_name");
+  }
+
+  Args.AddLastArg(CmdArgs, options::OPT_all__load);
+  Args.AddAllArgs(CmdArgs, options::OPT_allowable__client);
+  Args.AddLastArg(CmdArgs, options::OPT_bind__at__load);
+  if (getDarwinToolChain().isTargetIPhoneOS())
+    Args.AddLastArg(CmdArgs, options::OPT_arch__errors__fatal);
+  Args.AddLastArg(CmdArgs, options::OPT_dead__strip);
+  Args.AddLastArg(CmdArgs, options::OPT_no__dead__strip__inits__and__terms);
+  Args.AddAllArgs(CmdArgs, options::OPT_dylib__file);
+  Args.AddLastArg(CmdArgs, options::OPT_dynamic);
+  Args.AddAllArgs(CmdArgs, options::OPT_exported__symbols__list);
+  Args.AddLastArg(CmdArgs, options::OPT_flat__namespace);
+  Args.AddAllArgs(CmdArgs, options::OPT_headerpad__max__install__names);
+  Args.AddAllArgs(CmdArgs, options::OPT_image__base);
+  Args.AddAllArgs(CmdArgs, options::OPT_init);
+
+  // Adding all arguments doesn't make sense here but this is what gcc does. One
+  // of this should always be present thanks to argument translation.
+  assert((Args.hasArg(options::OPT_mmacosx_version_min_EQ) ||
+          Args.hasArg(options::OPT_miphoneos_version_min_EQ)) &&
+         "Missing version argument (lost in translation)?");
+  Args.AddAllArgsTranslated(CmdArgs, options::OPT_mmacosx_version_min_EQ,
+                            "-macosx_version_min");
+  Args.AddAllArgsTranslated(CmdArgs, options::OPT_miphoneos_version_min_EQ,
+                            "-iphoneos_version_min");
+  Args.AddLastArg(CmdArgs, options::OPT_nomultidefs);
+  Args.AddLastArg(CmdArgs, options::OPT_multi__module);
+  Args.AddLastArg(CmdArgs, options::OPT_single__module);
+  Args.AddAllArgs(CmdArgs, options::OPT_multiply__defined);
+  Args.AddAllArgs(CmdArgs, options::OPT_multiply__defined__unused);
+
+  if (Args.hasArg(options::OPT_fpie))
+    CmdArgs.push_back("-pie");
+
+  Args.AddLastArg(CmdArgs, options::OPT_prebind);
+  Args.AddLastArg(CmdArgs, options::OPT_noprebind);
+  Args.AddLastArg(CmdArgs, options::OPT_nofixprebinding);
+  Args.AddLastArg(CmdArgs, options::OPT_prebind__all__twolevel__modules);
+  Args.AddLastArg(CmdArgs, options::OPT_read__only__relocs);
+  Args.AddAllArgs(CmdArgs, options::OPT_sectcreate);
+  Args.AddAllArgs(CmdArgs, options::OPT_sectorder);
+  Args.AddAllArgs(CmdArgs, options::OPT_seg1addr);
+  Args.AddAllArgs(CmdArgs, options::OPT_segprot);
+  Args.AddAllArgs(CmdArgs, options::OPT_segaddr);
+  Args.AddAllArgs(CmdArgs, options::OPT_segs__read__only__addr);
+  Args.AddAllArgs(CmdArgs, options::OPT_segs__read__write__addr);
+  Args.AddAllArgs(CmdArgs, options::OPT_seg__addr__table);
+  Args.AddAllArgs(CmdArgs, options::OPT_seg__addr__table__filename);
+  Args.AddAllArgs(CmdArgs, options::OPT_sub__library);
+  Args.AddAllArgs(CmdArgs, options::OPT_sub__umbrella);
+
+  Args.AddAllArgsTranslated(CmdArgs, options::OPT_isysroot, "-syslibroot");
+  if (getDarwinToolChain().isTargetIPhoneOS()) {
+    if (!Args.hasArg(options::OPT_isysroot)) {
+      CmdArgs.push_back("-syslibroot");
+      CmdArgs.push_back("/Developer/SDKs/Extra");
+    }
+  }
+
+  Args.AddLastArg(CmdArgs, options::OPT_twolevel__namespace);
+  Args.AddLastArg(CmdArgs, options::OPT_twolevel__namespace__hints);
+  Args.AddAllArgs(CmdArgs, options::OPT_umbrella);
+  Args.AddAllArgs(CmdArgs, options::OPT_undefined);
+  Args.AddAllArgs(CmdArgs, options::OPT_unexported__symbols__list);
+  Args.AddAllArgs(CmdArgs, options::OPT_weak__reference__mismatches);
+  Args.AddLastArg(CmdArgs, options::OPT_X_Flag);
+  Args.AddAllArgs(CmdArgs, options::OPT_y);
+  Args.AddLastArg(CmdArgs, options::OPT_w);
+  Args.AddAllArgs(CmdArgs, options::OPT_pagezero__size);
+  Args.AddAllArgs(CmdArgs, options::OPT_segs__read__);
+  Args.AddLastArg(CmdArgs, options::OPT_seglinkedit);
+  Args.AddLastArg(CmdArgs, options::OPT_noseglinkedit);
+  Args.AddAllArgs(CmdArgs, options::OPT_sectalign);
+  Args.AddAllArgs(CmdArgs, options::OPT_sectobjectsymbols);
+  Args.AddAllArgs(CmdArgs, options::OPT_segcreate);
+  Args.AddLastArg(CmdArgs, options::OPT_whyload);
+  Args.AddLastArg(CmdArgs, options::OPT_whatsloaded);
+  Args.AddAllArgs(CmdArgs, options::OPT_dylinker__install__name);
+  Args.AddLastArg(CmdArgs, options::OPT_dylinker);
+  Args.AddLastArg(CmdArgs, options::OPT_Mach);
+}
+
+void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA,
+                                Job &Dest, const InputInfo &Output,
+                                const InputInfoList &Inputs,
+                                const ArgList &Args,
+                                const char *LinkingOutput) const {
+  assert(Output.getType() == types::TY_Image && "Invalid linker output type.");
+
+  // The logic here is derived from gcc's behavior; most of which
+  // comes from specs (starting with link_command). Consult gcc for
+  // more information.
+  ArgStringList CmdArgs;
+
+  // I'm not sure why this particular decomposition exists in gcc, but
+  // we follow suite for ease of comparison.
+  AddLinkArgs(Args, CmdArgs);
+
+  Args.AddAllArgs(CmdArgs, options::OPT_d_Flag);
+  Args.AddAllArgs(CmdArgs, options::OPT_s);
+  Args.AddAllArgs(CmdArgs, options::OPT_t);
+  Args.AddAllArgs(CmdArgs, options::OPT_Z_Flag);
+  Args.AddAllArgs(CmdArgs, options::OPT_u_Group);
+  Args.AddAllArgs(CmdArgs, options::OPT_A);
+  Args.AddLastArg(CmdArgs, options::OPT_e);
+  Args.AddAllArgs(CmdArgs, options::OPT_m_Separate);
+  Args.AddAllArgs(CmdArgs, options::OPT_r);
+
+  CmdArgs.push_back("-o");
+  CmdArgs.push_back(Output.getFilename());
+
+  if (!Args.hasArg(options::OPT_A) &&
+      !Args.hasArg(options::OPT_nostdlib) &&
+      !Args.hasArg(options::OPT_nostartfiles)) {
+    // Derived from startfile spec.
+    if (Args.hasArg(options::OPT_dynamiclib)) {
+      // Derived from darwin_dylib1 spec.
+      if (getDarwinToolChain().isTargetIPhoneOS()) {
+        if (getDarwinToolChain().isIPhoneOSVersionLT(3, 1))
+          CmdArgs.push_back("-ldylib1.o");
+      } else {
+        if (getDarwinToolChain().isMacosxVersionLT(10, 5))
+          CmdArgs.push_back("-ldylib1.o");
+        else if (getDarwinToolChain().isMacosxVersionLT(10, 6))
+          CmdArgs.push_back("-ldylib1.10.5.o");
+      }
+    } else {
+      if (Args.hasArg(options::OPT_bundle)) {
+        if (!Args.hasArg(options::OPT_static)) {
+          // Derived from darwin_bundle1 spec.
+          if (getDarwinToolChain().isTargetIPhoneOS()) {
+            if (getDarwinToolChain().isIPhoneOSVersionLT(3, 1))
+              CmdArgs.push_back("-lbundle1.o");
+          } else {
+            if (getDarwinToolChain().isMacosxVersionLT(10, 6))
+              CmdArgs.push_back("-lbundle1.o");
+          }
+        }
+      } else {
+        if (Args.hasArg(options::OPT_pg)) {
+          if (Args.hasArg(options::OPT_static) ||
+              Args.hasArg(options::OPT_object) ||
+              Args.hasArg(options::OPT_preload)) {
+            CmdArgs.push_back("-lgcrt0.o");
+          } else {
+            CmdArgs.push_back("-lgcrt1.o");
+
+            // darwin_crt2 spec is empty.
+          }
+        } else {
+          if (Args.hasArg(options::OPT_static) ||
+              Args.hasArg(options::OPT_object) ||
+              Args.hasArg(options::OPT_preload)) {
+            CmdArgs.push_back("-lcrt0.o");
+          } else {
+            // Derived from darwin_crt1 spec.
+            if (getDarwinToolChain().isTargetIPhoneOS()) {
+              if (getDarwinToolChain().isIPhoneOSVersionLT(3, 1))
+                CmdArgs.push_back("-lcrt1.o");
+              else
+                CmdArgs.push_back("-lcrt1.3.1.o");
+            } else {
+              if (getDarwinToolChain().isMacosxVersionLT(10, 5))
+                CmdArgs.push_back("-lcrt1.o");
+              else if (getDarwinToolChain().isMacosxVersionLT(10, 6))
+                CmdArgs.push_back("-lcrt1.10.5.o");
+              else
+                CmdArgs.push_back("-lcrt1.10.6.o");
+
+              // darwin_crt2 spec is empty.
+            }
+          }
+        }
+      }
+    }
+
+    if (!getDarwinToolChain().isTargetIPhoneOS() &&
+        Args.hasArg(options::OPT_shared_libgcc) &&
+        getDarwinToolChain().isMacosxVersionLT(10, 5)) {
+      const char *Str =
+        Args.MakeArgString(getToolChain().GetFilePath(C, "crt3.o"));
+      CmdArgs.push_back(Str);
+    }
+  }
+
+  Args.AddAllArgs(CmdArgs, options::OPT_L);
+
+  if (Args.hasArg(options::OPT_fopenmp))
+    // This is more complicated in gcc...
+    CmdArgs.push_back("-lgomp");
+
+  getDarwinToolChain().AddLinkSearchPathArgs(Args, CmdArgs);
+
+  for (InputInfoList::const_iterator
+         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
+    const InputInfo &II = *it;
+    if (II.isFilename())
+      CmdArgs.push_back(II.getFilename());
+    else
+      II.getInputArg().renderAsInput(Args, CmdArgs);
+  }
+
+  if (LinkingOutput) {
+    CmdArgs.push_back("-arch_multiple");
+    CmdArgs.push_back("-final_output");
+    CmdArgs.push_back(LinkingOutput);
+  }
+
+  if (Args.hasArg(options::OPT_fprofile_arcs) ||
+      Args.hasArg(options::OPT_fprofile_generate) ||
+      Args.hasArg(options::OPT_fcreate_profile) ||
+      Args.hasArg(options::OPT_coverage))
+    CmdArgs.push_back("-lgcov");
+
+  if (Args.hasArg(options::OPT_fnested_functions))
+    CmdArgs.push_back("-allow_stack_execute");
+
+  if (!Args.hasArg(options::OPT_nostdlib) &&
+      !Args.hasArg(options::OPT_nodefaultlibs)) {
+    // FIXME: g++ is more complicated here, it tries to put -lstdc++
+    // before -lm, for example.
+    if (getToolChain().getDriver().CCCIsCXX)
+      CmdArgs.push_back("-lstdc++");
+
+    // link_ssp spec is empty.
+
+    // Let the tool chain choose which runtime library to link.
+    getDarwinToolChain().AddLinkRuntimeLibArgs(Args, CmdArgs);
+  }
+
+  if (!Args.hasArg(options::OPT_A) &&
+      !Args.hasArg(options::OPT_nostdlib) &&
+      !Args.hasArg(options::OPT_nostartfiles)) {
+    // endfile_spec is empty.
+  }
+
+  Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
+  Args.AddAllArgs(CmdArgs, options::OPT_F);
+
+  const char *Exec =
+    Args.MakeArgString(getToolChain().GetProgramPath(C, "ld"));
+  Dest.addCommand(new Command(JA, *this, Exec, CmdArgs));
+
+  // Find the first non-empty base input (we want to ignore linker
+  // inputs).
+  const char *BaseInput = "";
+  for (unsigned i = 0, e = Inputs.size(); i != e; ++i) {
+    if (Inputs[i].getBaseInput()[0] != '\0') {
+      BaseInput = Inputs[i].getBaseInput();
+      break;
+    }
+  }
+
+  // Run dsymutil if we are making an executable in a single step.
+  //
+  // FIXME: Currently we don't want to do this when we are part of a
+  // universal build step, as this would end up creating stray temp
+  // files.
+  if (!LinkingOutput &&
+      Args.getLastArg(options::OPT_g_Group) &&
+      !Args.getLastArg(options::OPT_gstabs) &&
+      !Args.getLastArg(options::OPT_g0)) {
+    // FIXME: This is gross, but matches gcc. The test only considers
+    // the suffix (not the -x type), and then only of the first
+    // source input. Awesome.
+    const char *Suffix = strrchr(BaseInput, '.');
+    if (Suffix && isSourceSuffix(Suffix + 1)) {
+      const char *Exec =
+        Args.MakeArgString(getToolChain().GetProgramPath(C, "dsymutil"));
+      ArgStringList CmdArgs;
+      CmdArgs.push_back(Output.getFilename());
+      C.getJobs().addCommand(new Command(JA, *this, Exec, CmdArgs));
+    }
+  }
+}
+
+void darwin::Lipo::ConstructJob(Compilation &C, const JobAction &JA,
+                                Job &Dest, const InputInfo &Output,
+                                const InputInfoList &Inputs,
+                                const ArgList &Args,
+                                const char *LinkingOutput) const {
+  ArgStringList CmdArgs;
+
+  CmdArgs.push_back("-create");
+  assert(Output.isFilename() && "Unexpected lipo output.");
+
+  CmdArgs.push_back("-output");
+  CmdArgs.push_back(Output.getFilename());
+
+  for (InputInfoList::const_iterator
+         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
+    const InputInfo &II = *it;
+    assert(II.isFilename() && "Unexpected lipo input.");
+    CmdArgs.push_back(II.getFilename());
+  }
+  const char *Exec =
+    Args.MakeArgString(getToolChain().GetProgramPath(C, "lipo"));
+  Dest.addCommand(new Command(JA, *this, Exec, CmdArgs));
+}
+
+void auroraux::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
+                                      Job &Dest, const InputInfo &Output,
+                                      const InputInfoList &Inputs,
+                                      const ArgList &Args,
+                                      const char *LinkingOutput) const {
+  ArgStringList CmdArgs;
+
+  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
+                       options::OPT_Xassembler);
+
+  CmdArgs.push_back("-o");
+  if (Output.isPipe())
+    CmdArgs.push_back("-");
+  else
+    CmdArgs.push_back(Output.getFilename());
+
+  for (InputInfoList::const_iterator
+         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
+    const InputInfo &II = *it;
+    if (II.isPipe())
+      CmdArgs.push_back("-");
+    else
+      CmdArgs.push_back(II.getFilename());
+  }
+
+  const char *Exec =
+    Args.MakeArgString(getToolChain().GetProgramPath(C, "gas"));
+  Dest.addCommand(new Command(JA, *this, Exec, CmdArgs));
+}
+
+void auroraux::Link::ConstructJob(Compilation &C, const JobAction &JA,
+                                  Job &Dest, const InputInfo &Output,
+                                  const InputInfoList &Inputs,
+                                  const ArgList &Args,
+                                  const char *LinkingOutput) const {
+  const Driver &D = getToolChain().getDriver();
+  ArgStringList CmdArgs;
+
+  if ((!Args.hasArg(options::OPT_nostdlib)) &&
+      (!Args.hasArg(options::OPT_shared))) {
+    CmdArgs.push_back("-e");
+    CmdArgs.push_back("_start");
+  }
+
+  if (Args.hasArg(options::OPT_static)) {
+    CmdArgs.push_back("-Bstatic");
+    CmdArgs.push_back("-dn");
+  } else {
+//    CmdArgs.push_back("--eh-frame-hdr");
+    CmdArgs.push_back("-Bdynamic");
+    if (Args.hasArg(options::OPT_shared)) {
+      CmdArgs.push_back("-shared");
+    } else {
+      CmdArgs.push_back("--dynamic-linker");
+      CmdArgs.push_back("/lib/ld.so.1"); // 64Bit Path /lib/amd64/ld.so.1
+    }
+  }
+
+  if (Output.isPipe()) {
+    CmdArgs.push_back("-o");
+    CmdArgs.push_back("-");
+  } else if (Output.isFilename()) {
+    CmdArgs.push_back("-o");
+    CmdArgs.push_back(Output.getFilename());
+  } else {
+    assert(Output.isNothing() && "Invalid output.");
+  }
+
+  if (!Args.hasArg(options::OPT_nostdlib) &&
+      !Args.hasArg(options::OPT_nostartfiles)) {
+    if (!Args.hasArg(options::OPT_shared)) {
+      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crt1.o")));
+      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crti.o")));
+      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtbegin.o")));
+    } else {
+      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crti.o")));
+    }
+    CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtn.o")));
+  }
+
+  CmdArgs.push_back(Args.MakeArgString("-L/opt/gcc4/lib/gcc/"
+                                       + getToolChain().getTripleString()
+                                       + "/4.2.4"));
+
+  Args.AddAllArgs(CmdArgs, options::OPT_L);
+  Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
+  Args.AddAllArgs(CmdArgs, options::OPT_e);
+
+  for (InputInfoList::const_iterator
+         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
+    const InputInfo &II = *it;
+
+    // Don't try to pass LLVM inputs to a generic gcc.
+    if (II.getType() == types::TY_LLVMBC)
+      D.Diag(clang::diag::err_drv_no_linker_llvm_support)
+        << getToolChain().getTripleString();
+
+    if (II.isPipe())
+      CmdArgs.push_back("-");
+    else if (II.isFilename())
+      CmdArgs.push_back(II.getFilename());
+    else
+      II.getInputArg().renderAsInput(Args, CmdArgs);
+  }
+
+  if (!Args.hasArg(options::OPT_nostdlib) &&
+      !Args.hasArg(options::OPT_nodefaultlibs)) {
+    // FIXME: For some reason GCC passes -lgcc before adding
+    // the default system libraries. Just mimic this for now.
+    CmdArgs.push_back("-lgcc");
+
+    if (Args.hasArg(options::OPT_pthread))
+      CmdArgs.push_back("-pthread");
+    if (!Args.hasArg(options::OPT_shared))
+      CmdArgs.push_back("-lc");
+    CmdArgs.push_back("-lgcc");
+  }
+
+  if (!Args.hasArg(options::OPT_nostdlib) &&
+      !Args.hasArg(options::OPT_nostartfiles)) {
+    if (!Args.hasArg(options::OPT_shared))
+      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtend.o")));
+//    else
+//      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtendS.o")));
+  }
+
+  const char *Exec =
+    Args.MakeArgString(getToolChain().GetProgramPath(C, "ld"));
+  Dest.addCommand(new Command(JA, *this, Exec, CmdArgs));
+}
+
+void openbsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
+                                     Job &Dest, const InputInfo &Output,
+                                     const InputInfoList &Inputs,
+                                     const ArgList &Args,
+                                     const char *LinkingOutput) const {
+  ArgStringList CmdArgs;
+
+  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
+                       options::OPT_Xassembler);
+
+  CmdArgs.push_back("-o");
+  if (Output.isPipe())
+    CmdArgs.push_back("-");
+  else
+    CmdArgs.push_back(Output.getFilename());
+
+  for (InputInfoList::const_iterator
+         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
+    const InputInfo &II = *it;
+    if (II.isPipe())
+      CmdArgs.push_back("-");
+    else
+      CmdArgs.push_back(II.getFilename());
+  }
+
+  const char *Exec =
+    Args.MakeArgString(getToolChain().GetProgramPath(C, "as"));
+  Dest.addCommand(new Command(JA, *this, Exec, CmdArgs));
+}
+
+void openbsd::Link::ConstructJob(Compilation &C, const JobAction &JA,
+                                 Job &Dest, const InputInfo &Output,
+                                 const InputInfoList &Inputs,
+                                 const ArgList &Args,
+                                 const char *LinkingOutput) const {
+  const Driver &D = getToolChain().getDriver();
+  ArgStringList CmdArgs;
+
+  if ((!Args.hasArg(options::OPT_nostdlib)) &&
+      (!Args.hasArg(options::OPT_shared))) {
+    CmdArgs.push_back("-e");
+    CmdArgs.push_back("__start");
+  }
+
+  if (Args.hasArg(options::OPT_static)) {
+    CmdArgs.push_back("-Bstatic");
+  } else {
+    CmdArgs.push_back("--eh-frame-hdr");
+    CmdArgs.push_back("-Bdynamic");
+    if (Args.hasArg(options::OPT_shared)) {
+      CmdArgs.push_back("-shared");
+    } else {
+      CmdArgs.push_back("-dynamic-linker");
+      CmdArgs.push_back("/usr/libexec/ld.so");
+    }
+  }
+
+  if (Output.isPipe()) {
+    CmdArgs.push_back("-o");
+    CmdArgs.push_back("-");
+  } else if (Output.isFilename()) {
+    CmdArgs.push_back("-o");
+    CmdArgs.push_back(Output.getFilename());
+  } else {
+    assert(Output.isNothing() && "Invalid output.");
+  }
+
+  if (!Args.hasArg(options::OPT_nostdlib) &&
+      !Args.hasArg(options::OPT_nostartfiles)) {
+    if (!Args.hasArg(options::OPT_shared)) {
+      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crt0.o")));
+      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtbegin.o")));
+    } else {
+      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtbeginS.o")));
+    }
+  }
+
+  std::string Triple = getToolChain().getTripleString();
+  if (Triple.substr(0, 6) == "x86_64")
+    Triple.replace(0, 6, "amd64");
+  CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc-lib/" + Triple +
+                                       "/3.3.5"));
+
+  Args.AddAllArgs(CmdArgs, options::OPT_L);
+  Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
+  Args.AddAllArgs(CmdArgs, options::OPT_e);
+
+  for (InputInfoList::const_iterator
+         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
+    const InputInfo &II = *it;
+
+    // Don't try to pass LLVM inputs to a generic gcc.
+    if (II.getType() == types::TY_LLVMBC)
+      D.Diag(clang::diag::err_drv_no_linker_llvm_support)
+        << getToolChain().getTripleString();
+
+    if (II.isPipe())
+      CmdArgs.push_back("-");
+    else if (II.isFilename())
+      CmdArgs.push_back(II.getFilename());
+    else
+      II.getInputArg().renderAsInput(Args, CmdArgs);
+  }
+
+  if (!Args.hasArg(options::OPT_nostdlib) &&
+      !Args.hasArg(options::OPT_nodefaultlibs)) {
+    // FIXME: For some reason GCC passes -lgcc before adding
+    // the default system libraries. Just mimic this for now.
+    CmdArgs.push_back("-lgcc");
+
+    if (Args.hasArg(options::OPT_pthread))
+      CmdArgs.push_back("-pthread");
+    if (!Args.hasArg(options::OPT_shared))
+      CmdArgs.push_back("-lc");
+    CmdArgs.push_back("-lgcc");
+  }
+
+  if (!Args.hasArg(options::OPT_nostdlib) &&
+      !Args.hasArg(options::OPT_nostartfiles)) {
+    if (!Args.hasArg(options::OPT_shared))
+      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtend.o")));
+    else
+      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtendS.o")));
+  }
+
+  const char *Exec =
+    Args.MakeArgString(getToolChain().GetProgramPath(C, "ld"));
+  Dest.addCommand(new Command(JA, *this, Exec, CmdArgs));
+}
+
+void freebsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
+                                     Job &Dest, const InputInfo &Output,
+                                     const InputInfoList &Inputs,
+                                     const ArgList &Args,
+                                     const char *LinkingOutput) const {
+  ArgStringList CmdArgs;
+
+  // When building 32-bit code on FreeBSD/amd64, we have to explicitly
+  // instruct as in the base system to assemble 32-bit code.
+  if (getToolChain().getArchName() == "i386")
+    CmdArgs.push_back("--32");
+
+  
+  // Set byte order explicitly
+  if (getToolChain().getArchName() == "mips")
+    CmdArgs.push_back("-EB");
+  else if (getToolChain().getArchName() == "mipsel")
+    CmdArgs.push_back("-EL");
+
+  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
+                       options::OPT_Xassembler);
+
+  CmdArgs.push_back("-o");
+  if (Output.isPipe())
+    CmdArgs.push_back("-");
+  else
+    CmdArgs.push_back(Output.getFilename());
+
+  for (InputInfoList::const_iterator
+         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
+    const InputInfo &II = *it;
+    if (II.isPipe())
+      CmdArgs.push_back("-");
+    else
+      CmdArgs.push_back(II.getFilename());
+  }
+
+  const char *Exec =
+    Args.MakeArgString(getToolChain().GetProgramPath(C, "as"));
+  Dest.addCommand(new Command(JA, *this, Exec, CmdArgs));
+}
+
+void freebsd::Link::ConstructJob(Compilation &C, const JobAction &JA,
+                                 Job &Dest, const InputInfo &Output,
+                                 const InputInfoList &Inputs,
+                                 const ArgList &Args,
+                                 const char *LinkingOutput) const {
+  const Driver &D = getToolChain().getDriver();
+  ArgStringList CmdArgs;
+
+  if (Args.hasArg(options::OPT_static)) {
+    CmdArgs.push_back("-Bstatic");
+  } else {
+    CmdArgs.push_back("--eh-frame-hdr");
+    if (Args.hasArg(options::OPT_shared)) {
+      CmdArgs.push_back("-Bshareable");
+    } else {
+      CmdArgs.push_back("-dynamic-linker");
+      CmdArgs.push_back("/libexec/ld-elf.so.1");
+    }
+  }
+
+  // When building 32-bit code on FreeBSD/amd64, we have to explicitly
+  // instruct ld in the base system to link 32-bit code.
+  if (getToolChain().getArchName() == "i386") {
+    CmdArgs.push_back("-m");
+    CmdArgs.push_back("elf_i386_fbsd");
+  }
+
+  if (Output.isPipe()) {
+    CmdArgs.push_back("-o");
+    CmdArgs.push_back("-");
+  } else if (Output.isFilename()) {
+    CmdArgs.push_back("-o");
+    CmdArgs.push_back(Output.getFilename());
+  } else {
+    assert(Output.isNothing() && "Invalid output.");
+  }
+
+  if (!Args.hasArg(options::OPT_nostdlib) &&
+      !Args.hasArg(options::OPT_nostartfiles)) {
+    if (!Args.hasArg(options::OPT_shared)) {
+      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crt1.o")));
+      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crti.o")));
+      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtbegin.o")));
+    } else {
+      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crti.o")));
+      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtbeginS.o")));
+    }
+  }
+
+  Args.AddAllArgs(CmdArgs, options::OPT_L);
+  Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
+  Args.AddAllArgs(CmdArgs, options::OPT_e);
+
+  for (InputInfoList::const_iterator
+         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
+    const InputInfo &II = *it;
+
+    // Don't try to pass LLVM inputs to a generic gcc.
+    if (II.getType() == types::TY_LLVMBC)
+      D.Diag(clang::diag::err_drv_no_linker_llvm_support)
+        << getToolChain().getTripleString();
+
+    if (II.isPipe())
+      CmdArgs.push_back("-");
+    else if (II.isFilename())
+      CmdArgs.push_back(II.getFilename());
+    else
+      II.getInputArg().renderAsInput(Args, CmdArgs);
+  }
+
+  if (!Args.hasArg(options::OPT_nostdlib) &&
+      !Args.hasArg(options::OPT_nodefaultlibs)) {
+    if (D.CCCIsCXX) {
+      CmdArgs.push_back("-lstdc++");
+      CmdArgs.push_back("-lm");
+    }
+    // FIXME: For some reason GCC passes -lgcc and -lgcc_s before adding
+    // the default system libraries. Just mimic this for now.
+    CmdArgs.push_back("-lgcc");
+    if (Args.hasArg(options::OPT_static)) {
+      CmdArgs.push_back("-lgcc_eh");
+    } else {
+      CmdArgs.push_back("--as-needed");
+      CmdArgs.push_back("-lgcc_s");
+      CmdArgs.push_back("--no-as-needed");
+    }
+
+    if (Args.hasArg(options::OPT_pthread))
+      CmdArgs.push_back("-lpthread");
+    CmdArgs.push_back("-lc");
+
+    CmdArgs.push_back("-lgcc");
+    if (Args.hasArg(options::OPT_static)) {
+      CmdArgs.push_back("-lgcc_eh");
+    } else {
+      CmdArgs.push_back("--as-needed");
+      CmdArgs.push_back("-lgcc_s");
+      CmdArgs.push_back("--no-as-needed");
+    }
+  }
+
+  if (!Args.hasArg(options::OPT_nostdlib) &&
+      !Args.hasArg(options::OPT_nostartfiles)) {
+    if (!Args.hasArg(options::OPT_shared))
+      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtend.o")));
+    else
+      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtendS.o")));
+    CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtn.o")));
+  }
+
+  const char *Exec =
+    Args.MakeArgString(getToolChain().GetProgramPath(C, "ld"));
+  Dest.addCommand(new Command(JA, *this, Exec, CmdArgs));
+}
+
+/// DragonFly Tools
+
+// For now, DragonFly Assemble does just about the same as for
+// FreeBSD, but this may change soon.
+void dragonfly::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
+                                       Job &Dest, const InputInfo &Output,
+                                       const InputInfoList &Inputs,
+                                       const ArgList &Args,
+                                       const char *LinkingOutput) const {
+  ArgStringList CmdArgs;
+
+  // When building 32-bit code on DragonFly/pc64, we have to explicitly
+  // instruct as in the base system to assemble 32-bit code.
+  if (getToolChain().getArchName() == "i386")
+    CmdArgs.push_back("--32");
+
+  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
+                       options::OPT_Xassembler);
+
+  CmdArgs.push_back("-o");
+  if (Output.isPipe())
+    CmdArgs.push_back("-");
+  else
+    CmdArgs.push_back(Output.getFilename());
+
+  for (InputInfoList::const_iterator
+         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
+    const InputInfo &II = *it;
+    if (II.isPipe())
+      CmdArgs.push_back("-");
+    else
+      CmdArgs.push_back(II.getFilename());
+  }
+
+  const char *Exec =
+    Args.MakeArgString(getToolChain().GetProgramPath(C, "as"));
+  Dest.addCommand(new Command(JA, *this, Exec, CmdArgs));
+}
+
+void dragonfly::Link::ConstructJob(Compilation &C, const JobAction &JA,
+                                 Job &Dest, const InputInfo &Output,
+                                 const InputInfoList &Inputs,
+                                 const ArgList &Args,
+                                 const char *LinkingOutput) const {
+  const Driver &D = getToolChain().getDriver();
+  ArgStringList CmdArgs;
+
+  if (Args.hasArg(options::OPT_static)) {
+    CmdArgs.push_back("-Bstatic");
+  } else {
+    if (Args.hasArg(options::OPT_shared))
+      CmdArgs.push_back("-Bshareable");
+    else {
+      CmdArgs.push_back("-dynamic-linker");
+      CmdArgs.push_back("/usr/libexec/ld-elf.so.2");
+    }
+  }
+
+  // When building 32-bit code on DragonFly/pc64, we have to explicitly
+  // instruct ld in the base system to link 32-bit code.
+  if (getToolChain().getArchName() == "i386") {
+    CmdArgs.push_back("-m");
+    CmdArgs.push_back("elf_i386");
+  }
+
+  if (Output.isPipe()) {
+    CmdArgs.push_back("-o");
+    CmdArgs.push_back("-");
+  } else if (Output.isFilename()) {
+    CmdArgs.push_back("-o");
+    CmdArgs.push_back(Output.getFilename());
+  } else {
+    assert(Output.isNothing() && "Invalid output.");
+  }
+
+  if (!Args.hasArg(options::OPT_nostdlib) &&
+      !Args.hasArg(options::OPT_nostartfiles)) {
+    if (!Args.hasArg(options::OPT_shared)) {
+      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crt1.o")));
+      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crti.o")));
+      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtbegin.o")));
+    } else {
+      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crti.o")));
+      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtbeginS.o")));
+    }
+  }
+
+  Args.AddAllArgs(CmdArgs, options::OPT_L);
+  Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
+  Args.AddAllArgs(CmdArgs, options::OPT_e);
+
+  for (InputInfoList::const_iterator
+         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
+    const InputInfo &II = *it;
+
+    // Don't try to pass LLVM inputs to a generic gcc.
+    if (II.getType() == types::TY_LLVMBC)
+      D.Diag(clang::diag::err_drv_no_linker_llvm_support)
+        << getToolChain().getTripleString();
+
+    if (II.isPipe())
+      CmdArgs.push_back("-");
+    else if (II.isFilename())
+      CmdArgs.push_back(II.getFilename());
+    else
+      II.getInputArg().renderAsInput(Args, CmdArgs);
+  }
+
+  if (!Args.hasArg(options::OPT_nostdlib) &&
+      !Args.hasArg(options::OPT_nodefaultlibs)) {
+    // FIXME: GCC passes on -lgcc, -lgcc_pic and a whole lot of
+    //         rpaths
+    CmdArgs.push_back("-L/usr/lib/gcc41");
+
+    if (!Args.hasArg(options::OPT_static)) {
+      CmdArgs.push_back("-rpath");
+      CmdArgs.push_back("/usr/lib/gcc41");
+
+      CmdArgs.push_back("-rpath-link");
+      CmdArgs.push_back("/usr/lib/gcc41");
+
+      CmdArgs.push_back("-rpath");
+      CmdArgs.push_back("/usr/lib");
+
+      CmdArgs.push_back("-rpath-link");
+      CmdArgs.push_back("/usr/lib");
+    }
+
+    if (Args.hasArg(options::OPT_shared)) {
+      CmdArgs.push_back("-lgcc_pic");
+    } else {
+      CmdArgs.push_back("-lgcc");
+    }
+
+
+    if (Args.hasArg(options::OPT_pthread))
+      CmdArgs.push_back("-lpthread");
+
+    if (!Args.hasArg(options::OPT_nolibc)) {
+      CmdArgs.push_back("-lc");
+    }
+
+    if (Args.hasArg(options::OPT_shared)) {
+      CmdArgs.push_back("-lgcc_pic");
+    } else {
+      CmdArgs.push_back("-lgcc");
+    }
+  }
+
+  if (!Args.hasArg(options::OPT_nostdlib) &&
+      !Args.hasArg(options::OPT_nostartfiles)) {
+    if (!Args.hasArg(options::OPT_shared))
+      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtend.o")));
+    else
+      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtendS.o")));
+    CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtn.o")));
+  }
+
+  const char *Exec =
+    Args.MakeArgString(getToolChain().GetProgramPath(C, "ld"));
+  Dest.addCommand(new Command(JA, *this, Exec, CmdArgs));
+}
diff --git a/lib/Driver/Tools.h b/lib/Driver/Tools.h
new file mode 100644
index 0000000..091fec3
--- /dev/null
+++ b/lib/Driver/Tools.h
@@ -0,0 +1,402 @@
+//===--- Tools.h - Tool Implementations -------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_LIB_DRIVER_TOOLS_H_
+#define CLANG_LIB_DRIVER_TOOLS_H_
+
+#include "clang/Driver/Tool.h"
+#include "clang/Driver/Types.h"
+#include "clang/Driver/Util.h"
+
+#include "llvm/Support/Compiler.h"
+
+namespace clang {
+namespace driver {
+  class Driver;
+
+namespace toolchains {
+  class Darwin;
+}
+
+namespace tools {
+
+  class VISIBILITY_HIDDEN Clang : public Tool {
+    void AddPreprocessingOptions(const Driver &D,
+                                 const ArgList &Args,
+                                 ArgStringList &CmdArgs,
+                                 const InputInfo &Output,
+                                 const InputInfoList &Inputs) const;
+
+    void AddARMTargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const;
+    void AddMIPSTargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const;
+    void AddX86TargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const;
+
+  public:
+    Clang(const ToolChain &TC) : Tool("clang", TC) {}
+
+    virtual bool acceptsPipedInput() const { return true; }
+    virtual bool canPipeOutput() const { return true; }
+    virtual bool hasGoodDiagnostics() const { return true; }
+    virtual bool hasIntegratedAssembler() const { return true; }
+    virtual bool hasIntegratedCPP() const { return true; }
+
+    virtual void ConstructJob(Compilation &C, const JobAction &JA,
+                              Job &Dest,
+                              const InputInfo &Output,
+                              const InputInfoList &Inputs,
+                              const ArgList &TCArgs,
+                              const char *LinkingOutput) const;
+  };
+
+  /// gcc - Generic GCC tool implementations.
+namespace gcc {
+  class VISIBILITY_HIDDEN Common : public Tool {
+  public:
+    Common(const char *Name, const ToolChain &TC) : Tool(Name, TC) {}
+
+    virtual void ConstructJob(Compilation &C, const JobAction &JA,
+                              Job &Dest,
+                              const InputInfo &Output,
+                              const InputInfoList &Inputs,
+                              const ArgList &TCArgs,
+                              const char *LinkingOutput) const;
+
+    /// RenderExtraToolArgs - Render any arguments necessary to force
+    /// the particular tool mode.
+    virtual void RenderExtraToolArgs(const JobAction &JA,
+                                     ArgStringList &CmdArgs) const = 0;
+  };
+
+
+  class VISIBILITY_HIDDEN Preprocess : public Common {
+  public:
+    Preprocess(const ToolChain &TC) : Common("gcc::Preprocess", TC) {}
+
+    virtual bool acceptsPipedInput() const { return true; }
+    virtual bool canPipeOutput() const { return true; }
+    virtual bool hasGoodDiagnostics() const { return true; }
+    virtual bool hasIntegratedCPP() const { return false; }
+
+    virtual void RenderExtraToolArgs(const JobAction &JA,
+                                     ArgStringList &CmdArgs) const;
+  };
+
+  class VISIBILITY_HIDDEN Precompile : public Common  {
+  public:
+    Precompile(const ToolChain &TC) : Common("gcc::Precompile", TC) {}
+
+    virtual bool acceptsPipedInput() const { return true; }
+    virtual bool canPipeOutput() const { return false; }
+    virtual bool hasGoodDiagnostics() const { return true; }
+    virtual bool hasIntegratedCPP() const { return true; }
+
+    virtual void RenderExtraToolArgs(const JobAction &JA,
+                                     ArgStringList &CmdArgs) const;
+  };
+
+  class VISIBILITY_HIDDEN Compile : public Common  {
+  public:
+    Compile(const ToolChain &TC) : Common("gcc::Compile", TC) {}
+
+    virtual bool acceptsPipedInput() const { return true; }
+    virtual bool canPipeOutput() const { return true; }
+    virtual bool hasGoodDiagnostics() const { return true; }
+    virtual bool hasIntegratedCPP() const { return true; }
+
+    virtual void RenderExtraToolArgs(const JobAction &JA,
+                                     ArgStringList &CmdArgs) const;
+  };
+
+  class VISIBILITY_HIDDEN Assemble : public Common  {
+  public:
+    Assemble(const ToolChain &TC) : Common("gcc::Assemble", TC) {}
+
+    virtual bool acceptsPipedInput() const { return true; }
+    virtual bool canPipeOutput() const { return false; }
+    virtual bool hasIntegratedCPP() const { return false; }
+
+    virtual void RenderExtraToolArgs(const JobAction &JA,
+                                     ArgStringList &CmdArgs) const;
+  };
+
+  class VISIBILITY_HIDDEN Link : public Common  {
+  public:
+    Link(const ToolChain &TC) : Common("gcc::Link", TC) {}
+
+    virtual bool acceptsPipedInput() const { return false; }
+    virtual bool canPipeOutput() const { return false; }
+    virtual bool hasIntegratedCPP() const { return false; }
+
+    virtual void RenderExtraToolArgs(const JobAction &JA,
+                                     ArgStringList &CmdArgs) const;
+  };
+} // end namespace gcc
+
+namespace darwin {
+  class VISIBILITY_HIDDEN DarwinTool : public Tool {
+  protected:
+    void AddDarwinArch(const ArgList &Args, ArgStringList &CmdArgs) const;
+
+    const toolchains::Darwin &getDarwinToolChain() const {
+      return reinterpret_cast<const toolchains::Darwin&>(getToolChain());
+    }
+
+  public:
+    DarwinTool(const char *Name, const ToolChain &TC) : Tool(Name, TC) {}
+  };
+
+  class VISIBILITY_HIDDEN CC1 : public DarwinTool  {
+  public:
+    static const char *getBaseInputName(const ArgList &Args,
+                                 const InputInfoList &Input);
+    static const char *getBaseInputStem(const ArgList &Args,
+                                 const InputInfoList &Input);
+    static const char *getDependencyFileName(const ArgList &Args,
+                                             const InputInfoList &Inputs);
+
+  protected:
+    const char *getCC1Name(types::ID Type) const;
+
+    void AddCC1Args(const ArgList &Args, ArgStringList &CmdArgs) const;
+    void AddCC1OptionsArgs(const ArgList &Args, ArgStringList &CmdArgs,
+                           const InputInfoList &Inputs,
+                           const ArgStringList &OutputArgs) const;
+    void AddCPPOptionsArgs(const ArgList &Args, ArgStringList &CmdArgs,
+                           const InputInfoList &Inputs,
+                           const ArgStringList &OutputArgs) const;
+    void AddCPPUniqueOptionsArgs(const ArgList &Args,
+                                 ArgStringList &CmdArgs,
+                                 const InputInfoList &Inputs) const;
+    void AddCPPArgs(const ArgList &Args, ArgStringList &CmdArgs) const;
+
+  public:
+    CC1(const char *Name, const ToolChain &TC) : DarwinTool(Name, TC) {}
+
+    virtual bool acceptsPipedInput() const { return true; }
+    virtual bool canPipeOutput() const { return true; }
+    virtual bool hasGoodDiagnostics() const { return true; }
+    virtual bool hasIntegratedCPP() const { return true; }
+  };
+
+  class VISIBILITY_HIDDEN Preprocess : public CC1  {
+  public:
+    Preprocess(const ToolChain &TC) : CC1("darwin::Preprocess", TC) {}
+
+    virtual void ConstructJob(Compilation &C, const JobAction &JA,
+                              Job &Dest,
+                              const InputInfo &Output,
+                              const InputInfoList &Inputs,
+                              const ArgList &TCArgs,
+                              const char *LinkingOutput) const;
+  };
+
+  class VISIBILITY_HIDDEN Compile : public CC1  {
+  public:
+    Compile(const ToolChain &TC) : CC1("darwin::Compile", TC) {}
+
+    virtual void ConstructJob(Compilation &C, const JobAction &JA,
+                              Job &Dest,
+                              const InputInfo &Output,
+                              const InputInfoList &Inputs,
+                              const ArgList &TCArgs,
+                              const char *LinkingOutput) const;
+  };
+
+  class VISIBILITY_HIDDEN Assemble : public DarwinTool  {
+  public:
+    Assemble(const ToolChain &TC) : DarwinTool("darwin::Assemble", TC) {}
+
+    virtual bool acceptsPipedInput() const { return true; }
+    virtual bool canPipeOutput() const { return false; }
+    virtual bool hasIntegratedCPP() const { return false; }
+
+    virtual void ConstructJob(Compilation &C, const JobAction &JA,
+                              Job &Dest,
+                              const InputInfo &Output,
+                              const InputInfoList &Inputs,
+                              const ArgList &TCArgs,
+                              const char *LinkingOutput) const;
+  };
+
+  class VISIBILITY_HIDDEN Link : public DarwinTool  {
+    void AddLinkArgs(const ArgList &Args, ArgStringList &CmdArgs) const;
+
+  public:
+    Link(const ToolChain &TC) : DarwinTool("darwin::Link", TC) {}
+
+    virtual bool acceptsPipedInput() const { return false; }
+    virtual bool canPipeOutput() const { return false; }
+    virtual bool hasIntegratedCPP() const { return false; }
+
+    virtual void ConstructJob(Compilation &C, const JobAction &JA,
+                              Job &Dest,
+                              const InputInfo &Output,
+                              const InputInfoList &Inputs,
+                              const ArgList &TCArgs,
+                              const char *LinkingOutput) const;
+  };
+
+  class VISIBILITY_HIDDEN Lipo : public DarwinTool  {
+  public:
+    Lipo(const ToolChain &TC) : DarwinTool("darwin::Lipo", TC) {}
+
+    virtual bool acceptsPipedInput() const { return false; }
+    virtual bool canPipeOutput() const { return false; }
+    virtual bool hasIntegratedCPP() const { return false; }
+
+    virtual void ConstructJob(Compilation &C, const JobAction &JA,
+                              Job &Dest,
+                              const InputInfo &Output,
+                              const InputInfoList &Inputs,
+                              const ArgList &TCArgs,
+                              const char *LinkingOutput) const;
+  };
+}
+
+  /// openbsd -- Directly call GNU Binutils assembler and linker
+namespace openbsd {
+  class VISIBILITY_HIDDEN Assemble : public Tool  {
+  public:
+    Assemble(const ToolChain &TC) : Tool("openbsd::Assemble", TC) {}
+
+    virtual bool acceptsPipedInput() const { return true; }
+    virtual bool canPipeOutput() const { return true; }
+    virtual bool hasIntegratedCPP() const { return false; }
+
+    virtual void ConstructJob(Compilation &C, const JobAction &JA,
+                              Job &Dest,
+                              const InputInfo &Output,
+                              const InputInfoList &Inputs,
+                              const ArgList &TCArgs,
+                              const char *LinkingOutput) const;
+  };
+  class VISIBILITY_HIDDEN Link : public Tool  {
+  public:
+    Link(const ToolChain &TC) : Tool("openbsd::Link", TC) {}
+
+    virtual bool acceptsPipedInput() const { return true; }
+    virtual bool canPipeOutput() const { return true; }
+    virtual bool hasIntegratedCPP() const { return false; }
+
+    virtual void ConstructJob(Compilation &C, const JobAction &JA,
+                              Job &Dest,
+                              const InputInfo &Output,
+                              const InputInfoList &Inputs,
+                              const ArgList &TCArgs,
+                              const char *LinkingOutput) const;
+  };
+} // end namespace openbsd
+
+  /// freebsd -- Directly call GNU Binutils assembler and linker
+namespace freebsd {
+  class VISIBILITY_HIDDEN Assemble : public Tool  {
+  public:
+    Assemble(const ToolChain &TC) : Tool("freebsd::Assemble", TC) {}
+
+    virtual bool acceptsPipedInput() const { return true; }
+    virtual bool canPipeOutput() const { return true; }
+    virtual bool hasIntegratedCPP() const { return false; }
+
+    virtual void ConstructJob(Compilation &C, const JobAction &JA,
+                              Job &Dest,
+                              const InputInfo &Output,
+                              const InputInfoList &Inputs,
+                              const ArgList &TCArgs,
+                              const char *LinkingOutput) const;
+  };
+  class VISIBILITY_HIDDEN Link : public Tool  {
+  public:
+    Link(const ToolChain &TC) : Tool("freebsd::Link", TC) {}
+
+    virtual bool acceptsPipedInput() const { return true; }
+    virtual bool canPipeOutput() const { return true; }
+    virtual bool hasIntegratedCPP() const { return false; }
+
+    virtual void ConstructJob(Compilation &C, const JobAction &JA,
+                              Job &Dest,
+                              const InputInfo &Output,
+                              const InputInfoList &Inputs,
+                              const ArgList &TCArgs,
+                              const char *LinkingOutput) const;
+  };
+} // end namespace freebsd
+
+  /// auroraux -- Directly call GNU Binutils assembler and linker
+namespace auroraux {
+  class VISIBILITY_HIDDEN Assemble : public Tool  {
+  public:
+    Assemble(const ToolChain &TC) : Tool("auroraux::Assemble", TC) {}
+
+    virtual bool acceptsPipedInput() const { return true; }
+    virtual bool canPipeOutput() const { return true; }
+    virtual bool hasIntegratedCPP() const { return false; }
+
+    virtual void ConstructJob(Compilation &C, const JobAction &JA,
+                              Job &Dest,
+                              const InputInfo &Output,
+                              const InputInfoList &Inputs,
+                              const ArgList &TCArgs,
+                              const char *LinkingOutput) const;
+  };
+  class VISIBILITY_HIDDEN Link : public Tool  {
+  public:
+    Link(const ToolChain &TC) : Tool("auroraux::Link", TC) {}
+
+    virtual bool acceptsPipedInput() const { return true; }
+    virtual bool canPipeOutput() const { return true; }
+    virtual bool hasIntegratedCPP() const { return false; }
+
+    virtual void ConstructJob(Compilation &C, const JobAction &JA,
+                              Job &Dest,
+                              const InputInfo &Output,
+                              const InputInfoList &Inputs,
+                              const ArgList &TCArgs,
+                              const char *LinkingOutput) const;
+  };
+} // end namespace auroraux
+
+  /// dragonfly -- Directly call GNU Binutils assembler and linker
+namespace dragonfly {
+  class VISIBILITY_HIDDEN Assemble : public Tool  {
+  public:
+    Assemble(const ToolChain &TC) : Tool("dragonfly::Assemble", TC) {}
+
+    virtual bool acceptsPipedInput() const { return true; }
+    virtual bool canPipeOutput() const { return true; }
+    virtual bool hasIntegratedCPP() const { return false; }
+
+    virtual void ConstructJob(Compilation &C, const JobAction &JA,
+                              Job &Dest,
+                              const InputInfo &Output,
+                              const InputInfoList &Inputs,
+                              const ArgList &TCArgs,
+                              const char *LinkingOutput) const;
+  };
+  class VISIBILITY_HIDDEN Link : public Tool  {
+  public:
+    Link(const ToolChain &TC) : Tool("dragonfly::Link", TC) {}
+
+    virtual bool acceptsPipedInput() const { return true; }
+    virtual bool canPipeOutput() const { return true; }
+    virtual bool hasIntegratedCPP() const { return false; }
+
+    virtual void ConstructJob(Compilation &C, const JobAction &JA,
+                              Job &Dest,
+                              const InputInfo &Output,
+                              const InputInfoList &Inputs,
+                              const ArgList &TCArgs,
+                              const char *LinkingOutput) const;
+  };
+} // end namespace dragonfly
+
+} // end namespace toolchains
+} // end namespace driver
+} // end namespace clang
+
+#endif // CLANG_LIB_DRIVER_TOOLS_H_
diff --git a/lib/Driver/Types.cpp b/lib/Driver/Types.cpp
new file mode 100644
index 0000000..8857fb1
--- /dev/null
+++ b/lib/Driver/Types.cpp
@@ -0,0 +1,231 @@
+//===--- Types.cpp - Driver input & temporary type information ----------*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Driver/Types.h"
+
+#include "llvm/ADT/StringSwitch.h"
+#include <string.h>
+#include <cassert>
+
+using namespace clang::driver;
+using namespace clang::driver::types;
+
+struct TypeInfo {
+  const char *Name;
+  const char *Flags;
+  const char *TempSuffix;
+  ID PreprocessedType;
+};
+
+static const TypeInfo TypeInfos[] = {
+#define TYPE(NAME, ID, PP_TYPE, TEMP_SUFFIX, FLAGS) \
+  { NAME, FLAGS, TEMP_SUFFIX, TY_##PP_TYPE, },
+#include "clang/Driver/Types.def"
+#undef TYPE
+};
+static const unsigned numTypes = sizeof(TypeInfos) / sizeof(TypeInfos[0]);
+
+static const TypeInfo &getInfo(unsigned id) {
+  assert(id > 0 && id - 1 < numTypes && "Invalid Type ID.");
+  return TypeInfos[id - 1];
+}
+
+const char *types::getTypeName(ID Id) {
+  return getInfo(Id).Name;
+}
+
+types::ID types::getPreprocessedType(ID Id) {
+  return getInfo(Id).PreprocessedType;
+}
+
+const char *types::getTypeTempSuffix(ID Id) {
+  return getInfo(Id).TempSuffix;
+}
+
+bool types::onlyAssembleType(ID Id) {
+  return strchr(getInfo(Id).Flags, 'a');
+}
+
+bool types::onlyPrecompileType(ID Id) {
+  return strchr(getInfo(Id).Flags, 'p');
+}
+
+bool types::canTypeBeUserSpecified(ID Id) {
+  return strchr(getInfo(Id).Flags, 'u');
+}
+
+bool types::appendSuffixForType(ID Id) {
+  return strchr(getInfo(Id).Flags, 'A');
+}
+
+bool types::canLipoType(ID Id) {
+  return (Id == TY_Nothing ||
+          Id == TY_Image ||
+          Id == TY_Object);
+}
+
+bool types::isAcceptedByClang(ID Id) {
+  switch (Id) {
+  default:
+    return false;
+
+  case TY_Asm:
+  case TY_C: case TY_PP_C:
+  case TY_CL:
+  case TY_ObjC: case TY_PP_ObjC:
+  case TY_CXX: case TY_PP_CXX:
+  case TY_ObjCXX: case TY_PP_ObjCXX:
+  case TY_CHeader: case TY_PP_CHeader:
+  case TY_ObjCHeader: case TY_PP_ObjCHeader:
+  case TY_CXXHeader: case TY_PP_CXXHeader:
+  case TY_ObjCXXHeader: case TY_PP_ObjCXXHeader:
+  case TY_AST:
+    return true;
+  }
+}
+
+bool types::isObjC(ID Id) {
+  switch (Id) {
+  default:
+    return false;
+
+  case TY_ObjC: case TY_PP_ObjC:
+  case TY_ObjCXX: case TY_PP_ObjCXX:
+  case TY_ObjCHeader: case TY_PP_ObjCHeader:
+  case TY_ObjCXXHeader: case TY_PP_ObjCXXHeader:
+    return true;
+  }
+}
+
+bool types::isCXX(ID Id) {
+  switch (Id) {
+  default:
+    return false;
+
+  case TY_CXX: case TY_PP_CXX:
+  case TY_ObjCXX: case TY_PP_ObjCXX:
+  case TY_CXXHeader: case TY_PP_CXXHeader:
+  case TY_ObjCXXHeader: case TY_PP_ObjCXXHeader:
+    return true;
+  }
+}
+
+types::ID types::lookupTypeForExtension(const char *Ext) {
+  return llvm::StringSwitch<types::ID>(Ext)
+           .Case("c", TY_C)
+           .Case("i", TY_PP_C)
+           .Case("m", TY_ObjC)
+           .Case("M", TY_ObjCXX)
+           .Case("h", TY_CHeader)
+           .Case("C", TY_CXX)
+           .Case("H", TY_CXXHeader)
+           .Case("f", TY_PP_Fortran)
+           .Case("F", TY_Fortran)
+           .Case("s", TY_PP_Asm)
+           .Case("S", TY_Asm)
+           .Case("ii", TY_PP_CXX)
+           .Case("mi", TY_PP_ObjC)
+           .Case("mm", TY_ObjCXX)
+           .Case("cc", TY_CXX)
+           .Case("CC", TY_CXX)
+           .Case("cl", TY_CL)
+           .Case("cp", TY_CXX)
+           .Case("hh", TY_CXXHeader)
+           .Case("hpp", TY_CXXHeader)
+           .Case("ads", TY_Ada)
+           .Case("adb", TY_Ada)
+           .Case("ast", TY_AST)
+           .Case("cxx", TY_CXX)
+           .Case("cpp", TY_CXX)
+           .Case("CPP", TY_CXX)
+           .Case("CXX", TY_CXX)
+           .Case("for", TY_PP_Fortran)
+           .Case("FOR", TY_PP_Fortran)
+           .Case("fpp", TY_Fortran)
+           .Case("FPP", TY_Fortran)
+           .Case("f90", TY_PP_Fortran)
+           .Case("f95", TY_PP_Fortran)
+           .Case("F90", TY_Fortran)
+           .Case("F95", TY_Fortran)
+           .Case("mii", TY_PP_ObjCXX)
+           .Default(TY_INVALID);
+}
+
+types::ID types::lookupTypeForTypeSpecifier(const char *Name) {
+  unsigned N = strlen(Name);
+
+  for (unsigned i=0; i<numTypes; ++i) {
+    types::ID Id = (types::ID) (i + 1);
+    if (canTypeBeUserSpecified(Id) &&
+        memcmp(Name, getInfo(Id).Name, N + 1) == 0)
+      return Id;
+  }
+
+  return TY_INVALID;
+}
+
+// FIXME: Why don't we just put this list in the defs file, eh.
+
+unsigned types::getNumCompilationPhases(ID Id) {
+  if (Id == TY_Object)
+    return 1;
+
+  unsigned N = 0;
+  if (getPreprocessedType(Id) != TY_INVALID)
+    N += 1;
+
+  if (onlyAssembleType(Id))
+    return N + 2; // assemble, link
+  if (onlyPrecompileType(Id))
+    return N + 1; // precompile
+
+  return N + 3; // compile, assemble, link
+}
+
+phases::ID types::getCompilationPhase(ID Id, unsigned N) {
+  assert(N < getNumCompilationPhases(Id) && "Invalid index.");
+
+  if (Id == TY_Object)
+    return phases::Link;
+
+  if (getPreprocessedType(Id) != TY_INVALID) {
+    if (N == 0)
+      return phases::Preprocess;
+    --N;
+  }
+
+  if (onlyAssembleType(Id))
+    return N == 0 ? phases::Assemble : phases::Link;
+
+  if (onlyPrecompileType(Id))
+    return phases::Precompile;
+
+  if (N == 0)
+    return phases::Compile;
+  if (N == 1)
+    return phases::Assemble;
+
+  return phases::Link;
+}
+
+ID types::lookupCXXTypeForCType(ID Id) {
+  switch (Id) {
+  default:
+    return Id;
+    
+  case types::TY_C:
+    return types::TY_CXX;
+  case types::TY_PP_C:
+    return types::TY_PP_CXX;
+  case types::TY_CHeader:
+    return types::TY_CXXHeader;
+  case types::TY_PP_CHeader:
+    return types::TY_PP_CXXHeader;
+  }
+}
diff --git a/lib/Frontend/ASTConsumers.cpp b/lib/Frontend/ASTConsumers.cpp
new file mode 100644
index 0000000..7b8ebf9
--- /dev/null
+++ b/lib/Frontend/ASTConsumers.cpp
@@ -0,0 +1,464 @@
+//===--- ASTConsumers.cpp - ASTConsumer implementations -------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// AST Consumer Implementations.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/ASTConsumers.h"
+#include "clang/Frontend/DocumentXML.h"
+#include "clang/Frontend/PathDiagnosticClients.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/AST/AST.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/RecordLayout.h"
+#include "clang/AST/PrettyPrinter.h"
+#include "clang/CodeGen/ModuleBuilder.h"
+#include "llvm/Module.h"
+#include "llvm/Support/Timer.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/System/Path.h"
+using namespace clang;
+
+//===----------------------------------------------------------------------===//
+/// ASTPrinter - Pretty-printer and dumper of ASTs
+
+namespace {
+  class ASTPrinter : public ASTConsumer {
+    llvm::raw_ostream &Out;
+    bool Dump;
+
+  public:
+    ASTPrinter(llvm::raw_ostream* o = NULL, bool Dump = false)
+      : Out(o? *o : llvm::errs()), Dump(Dump) { }
+
+    virtual void HandleTranslationUnit(ASTContext &Context) {
+      PrintingPolicy Policy = Context.PrintingPolicy;
+      Policy.Dump = Dump;
+      Context.getTranslationUnitDecl()->print(Out, Policy);
+    }
+  };
+} // end anonymous namespace
+
+ASTConsumer *clang::CreateASTPrinter(llvm::raw_ostream* out) {
+  return new ASTPrinter(out);
+}
+
+//===----------------------------------------------------------------------===//
+/// ASTPrinterXML - XML-printer of ASTs
+
+namespace {
+  class ASTPrinterXML : public ASTConsumer {
+    DocumentXML         Doc;
+
+  public:
+    ASTPrinterXML(llvm::raw_ostream& o) : Doc("CLANG_XML", o) {}
+
+    void Initialize(ASTContext &Context) {
+      Doc.initialize(Context);
+    }
+
+    virtual void HandleTranslationUnit(ASTContext &Ctx) {
+      Doc.addSubNode("TranslationUnit");
+      for (DeclContext::decl_iterator
+             D = Ctx.getTranslationUnitDecl()->decls_begin(),
+             DEnd = Ctx.getTranslationUnitDecl()->decls_end();
+           D != DEnd;
+           ++D)
+        Doc.PrintDecl(*D);
+      Doc.toParent();
+      Doc.finalize();
+    }
+  };
+} // end anonymous namespace
+
+
+ASTConsumer *clang::CreateASTPrinterXML(llvm::raw_ostream* out) {
+  return new ASTPrinterXML(out ? *out : llvm::outs());
+}
+
+ASTConsumer *clang::CreateASTDumper() {
+  return new ASTPrinter(0, true);
+}
+
+//===----------------------------------------------------------------------===//
+/// ASTViewer - AST Visualization
+
+namespace {
+  class ASTViewer : public ASTConsumer {
+    ASTContext *Context;
+  public:
+    void Initialize(ASTContext &Context) {
+      this->Context = &Context;
+    }
+
+    virtual void HandleTopLevelDecl(DeclGroupRef D) {
+      for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I)
+        HandleTopLevelSingleDecl(*I);
+    }
+
+    void HandleTopLevelSingleDecl(Decl *D);
+  };
+}
+
+void ASTViewer::HandleTopLevelSingleDecl(Decl *D) {
+  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+    FD->print(llvm::errs());
+
+    if (Stmt *Body = FD->getBody()) {
+      llvm::errs() << '\n';
+      Body->viewAST();
+      llvm::errs() << '\n';
+    }
+    return;
+  }
+
+  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
+    MD->print(llvm::errs());
+
+    if (MD->getBody()) {
+      llvm::errs() << '\n';
+      MD->getBody()->viewAST();
+      llvm::errs() << '\n';
+    }
+  }
+}
+
+
+ASTConsumer *clang::CreateASTViewer() { return new ASTViewer(); }
+
+//===----------------------------------------------------------------------===//
+/// DeclContextPrinter - Decl and DeclContext Visualization
+
+namespace {
+
+class DeclContextPrinter : public ASTConsumer {
+  llvm::raw_ostream& Out;
+public:
+  DeclContextPrinter() : Out(llvm::errs()) {}
+
+  void HandleTranslationUnit(ASTContext &C) {
+    PrintDeclContext(C.getTranslationUnitDecl(), 4);
+  }
+
+  void PrintDeclContext(const DeclContext* DC, unsigned Indentation);
+};
+}  // end anonymous namespace
+
+void DeclContextPrinter::PrintDeclContext(const DeclContext* DC,
+                                          unsigned Indentation) {
+  // Print DeclContext name.
+  switch (DC->getDeclKind()) {
+  case Decl::TranslationUnit:
+    Out << "[translation unit] " << DC;
+    break;
+  case Decl::Namespace: {
+    Out << "[namespace] ";
+    const NamespaceDecl* ND = cast<NamespaceDecl>(DC);
+    Out << ND;
+    break;
+  }
+  case Decl::Enum: {
+    const EnumDecl* ED = cast<EnumDecl>(DC);
+    if (ED->isDefinition())
+      Out << "[enum] ";
+    else
+      Out << "<enum> ";
+    Out << ED;
+    break;
+  }
+  case Decl::Record: {
+    const RecordDecl* RD = cast<RecordDecl>(DC);
+    if (RD->isDefinition())
+      Out << "[struct] ";
+    else
+      Out << "<struct> ";
+    Out << RD;
+    break;
+  }
+  case Decl::CXXRecord: {
+    const CXXRecordDecl* RD = cast<CXXRecordDecl>(DC);
+    if (RD->isDefinition())
+      Out << "[class] ";
+    else
+      Out << "<class> ";
+    Out << RD << ' ' << DC;
+    break;
+  }
+  case Decl::ObjCMethod:
+    Out << "[objc method]";
+    break;
+  case Decl::ObjCInterface:
+    Out << "[objc interface]";
+    break;
+  case Decl::ObjCCategory:
+    Out << "[objc category]";
+    break;
+  case Decl::ObjCProtocol:
+    Out << "[objc protocol]";
+    break;
+  case Decl::ObjCImplementation:
+    Out << "[objc implementation]";
+    break;
+  case Decl::ObjCCategoryImpl:
+    Out << "[objc categoryimpl]";
+    break;
+  case Decl::LinkageSpec:
+    Out << "[linkage spec]";
+    break;
+  case Decl::Block:
+    Out << "[block]";
+    break;
+  case Decl::Function: {
+    const FunctionDecl* FD = cast<FunctionDecl>(DC);
+    if (FD->isThisDeclarationADefinition())
+      Out << "[function] ";
+    else
+      Out << "<function> ";
+    Out << FD;
+    // Print the parameters.
+    Out << "(";
+    bool PrintComma = false;
+    for (FunctionDecl::param_const_iterator I = FD->param_begin(),
+           E = FD->param_end(); I != E; ++I) {
+      if (PrintComma)
+        Out << ", ";
+      else
+        PrintComma = true;
+      Out << *I;
+    }
+    Out << ")";
+    break;
+  }
+  case Decl::CXXMethod: {
+    const CXXMethodDecl* D = cast<CXXMethodDecl>(DC);
+    if (D->isOutOfLine())
+      Out << "[c++ method] ";
+    else if (D->isImplicit())
+      Out << "(c++ method) ";
+    else
+      Out << "<c++ method> ";
+    Out << D;
+    // Print the parameters.
+    Out << "(";
+    bool PrintComma = false;
+    for (FunctionDecl::param_const_iterator I = D->param_begin(),
+           E = D->param_end(); I != E; ++I) {
+      if (PrintComma)
+        Out << ", ";
+      else
+        PrintComma = true;
+      Out << *I;
+    }
+    Out << ")";
+
+    // Check the semantic DeclContext.
+    const DeclContext* SemaDC = D->getDeclContext();
+    const DeclContext* LexicalDC = D->getLexicalDeclContext();
+    if (SemaDC != LexicalDC)
+      Out << " [[" << SemaDC << "]]";
+
+    break;
+  }
+  case Decl::CXXConstructor: {
+    const CXXConstructorDecl* D = cast<CXXConstructorDecl>(DC);
+    if (D->isOutOfLine())
+      Out << "[c++ ctor] ";
+    else if (D->isImplicit())
+      Out << "(c++ ctor) ";
+    else
+      Out << "<c++ ctor> ";
+    Out << D;
+    // Print the parameters.
+    Out << "(";
+    bool PrintComma = false;
+    for (FunctionDecl::param_const_iterator I = D->param_begin(),
+           E = D->param_end(); I != E; ++I) {
+      if (PrintComma)
+        Out << ", ";
+      else
+        PrintComma = true;
+      Out << *I;
+    }
+    Out << ")";
+
+    // Check the semantic DC.
+    const DeclContext* SemaDC = D->getDeclContext();
+    const DeclContext* LexicalDC = D->getLexicalDeclContext();
+    if (SemaDC != LexicalDC)
+      Out << " [[" << SemaDC << "]]";
+    break;
+  }
+  case Decl::CXXDestructor: {
+    const CXXDestructorDecl* D = cast<CXXDestructorDecl>(DC);
+    if (D->isOutOfLine())
+      Out << "[c++ dtor] ";
+    else if (D->isImplicit())
+      Out << "(c++ dtor) ";
+    else
+      Out << "<c++ dtor> ";
+    Out << D;
+    // Check the semantic DC.
+    const DeclContext* SemaDC = D->getDeclContext();
+    const DeclContext* LexicalDC = D->getLexicalDeclContext();
+    if (SemaDC != LexicalDC)
+      Out << " [[" << SemaDC << "]]";
+    break;
+  }
+  case Decl::CXXConversion: {
+    const CXXConversionDecl* D = cast<CXXConversionDecl>(DC);
+    if (D->isOutOfLine())
+      Out << "[c++ conversion] ";
+    else if (D->isImplicit())
+      Out << "(c++ conversion) ";
+    else
+      Out << "<c++ conversion> ";
+    Out << D;
+    // Check the semantic DC.
+    const DeclContext* SemaDC = D->getDeclContext();
+    const DeclContext* LexicalDC = D->getLexicalDeclContext();
+    if (SemaDC != LexicalDC)
+      Out << " [[" << SemaDC << "]]";
+    break;
+  }
+
+  default:
+    assert(0 && "a decl that inherits DeclContext isn't handled");
+  }
+
+  Out << "\n";
+
+  // Print decls in the DeclContext.
+  for (DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
+       I != E; ++I) {
+    for (unsigned i = 0; i < Indentation; ++i)
+      Out << "  ";
+
+    Decl::Kind DK = I->getKind();
+    switch (DK) {
+    case Decl::Namespace:
+    case Decl::Enum:
+    case Decl::Record:
+    case Decl::CXXRecord:
+    case Decl::ObjCMethod:
+    case Decl::ObjCInterface:
+    case Decl::ObjCCategory:
+    case Decl::ObjCProtocol:
+    case Decl::ObjCImplementation:
+    case Decl::ObjCCategoryImpl:
+    case Decl::LinkageSpec:
+    case Decl::Block:
+    case Decl::Function:
+    case Decl::CXXMethod:
+    case Decl::CXXConstructor:
+    case Decl::CXXDestructor:
+    case Decl::CXXConversion:
+    {
+      DeclContext* DC = cast<DeclContext>(*I);
+      PrintDeclContext(DC, Indentation+2);
+      break;
+    }
+    case Decl::Field: {
+      FieldDecl* FD = cast<FieldDecl>(*I);
+      Out << "<field> " << FD << '\n';
+      break;
+    }
+    case Decl::Typedef: {
+      TypedefDecl* TD = cast<TypedefDecl>(*I);
+      Out << "<typedef> " << TD << '\n';
+      break;
+    }
+    case Decl::EnumConstant: {
+      EnumConstantDecl* ECD = cast<EnumConstantDecl>(*I);
+      Out << "<enum constant> " << ECD << '\n';
+      break;
+    }
+    case Decl::Var: {
+      VarDecl* VD = cast<VarDecl>(*I);
+      Out << "<var> " << VD << '\n';
+      break;
+    }
+    case Decl::ImplicitParam: {
+      ImplicitParamDecl* IPD = cast<ImplicitParamDecl>(*I);
+      Out << "<implicit parameter> " << IPD << '\n';
+      break;
+    }
+    case Decl::ParmVar: {
+      ParmVarDecl* PVD = cast<ParmVarDecl>(*I);
+      Out << "<parameter> " << PVD << '\n';
+      break;
+    }
+    case Decl::ObjCProperty: {
+      ObjCPropertyDecl* OPD = cast<ObjCPropertyDecl>(*I);
+      Out << "<objc property> " << OPD << '\n';
+      break;
+    }
+    case Decl::FunctionTemplate: {
+      FunctionTemplateDecl* FTD = cast<FunctionTemplateDecl>(*I);
+      Out << "<function template> " << FTD << '\n';
+      break;
+    }
+    case Decl::FileScopeAsm: {
+      Out << "<file-scope asm>\n";
+      break;
+    }
+    case Decl::UsingDirective: {
+      Out << "<using directive>\n";
+      break;
+    }
+    case Decl::NamespaceAlias: {
+      NamespaceAliasDecl* NAD = cast<NamespaceAliasDecl>(*I);
+      Out << "<namespace alias> " << NAD << '\n';
+      break;
+    }
+    case Decl::ClassTemplate: {
+      ClassTemplateDecl *CTD = cast<ClassTemplateDecl>(*I);
+      Out << "<class template> " << CTD << '\n';
+      break;
+    }
+    default:
+      Out << "DeclKind: " << DK << '"' << *I << "\"\n";
+      assert(0 && "decl unhandled");
+    }
+  }
+}
+ASTConsumer *clang::CreateDeclContextPrinter() {
+  return new DeclContextPrinter();
+}
+
+//===----------------------------------------------------------------------===//
+/// InheritanceViewer - C++ Inheritance Visualization
+
+namespace {
+class InheritanceViewer : public ASTConsumer {
+  const std::string clsname;
+public:
+  InheritanceViewer(const std::string& cname) : clsname(cname) {}
+
+  void HandleTranslationUnit(ASTContext &C) {
+    for (ASTContext::type_iterator I=C.types_begin(),E=C.types_end(); I!=E; ++I)
+      if (RecordType *T = dyn_cast<RecordType>(*I)) {
+        if (CXXRecordDecl *D = dyn_cast<CXXRecordDecl>(T->getDecl())) {
+          // FIXME: This lookup needs to be generalized to handle namespaces and
+          // (when we support them) templates.
+          if (D->getNameAsString() == clsname) {
+            D->viewInheritance(C);
+          }
+        }
+      }
+  }
+};
+}
+
+ASTConsumer *clang::CreateInheritanceViewer(const std::string& clsname) {
+  return new InheritanceViewer(clsname);
+}
diff --git a/lib/Frontend/ASTMerge.cpp b/lib/Frontend/ASTMerge.cpp
new file mode 100644
index 0000000..b0faf0a
--- /dev/null
+++ b/lib/Frontend/ASTMerge.cpp
@@ -0,0 +1,104 @@
+//===-- ASTMerge.cpp - AST Merging Frontent Action --------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "clang/Frontend/ASTUnit.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Frontend/FrontendActions.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTDiagnostic.h"
+#include "clang/AST/ASTImporter.h"
+#include "clang/Basic/Diagnostic.h"
+
+using namespace clang;
+
+ASTConsumer *ASTMergeAction::CreateASTConsumer(CompilerInstance &CI,
+                                               llvm::StringRef InFile) {
+  return AdaptedAction->CreateASTConsumer(CI, InFile);
+}
+
+bool ASTMergeAction::BeginSourceFileAction(CompilerInstance &CI,
+                                           llvm::StringRef Filename) {
+  // FIXME: This is a hack. We need a better way to communicate the
+  // AST file, compiler instance, and file name than member variables
+  // of FrontendAction.
+  AdaptedAction->setCurrentFile(getCurrentFile(), takeCurrentASTUnit());
+  AdaptedAction->setCompilerInstance(&CI);
+  return AdaptedAction->BeginSourceFileAction(CI, Filename);
+}
+
+void ASTMergeAction::ExecuteAction() {
+  CompilerInstance &CI = getCompilerInstance();
+  CI.getDiagnostics().getClient()->BeginSourceFile(
+                                         CI.getASTContext().getLangOptions());
+  CI.getDiagnostics().SetArgToStringFn(&FormatASTNodeDiagnosticArgument,
+                                       &CI.getASTContext());
+  llvm::IntrusiveRefCntPtr<Diagnostic> Diags(&CI.getDiagnostics());
+  for (unsigned I = 0, N = ASTFiles.size(); I != N; ++I) {
+    ASTUnit *Unit = ASTUnit::LoadFromPCHFile(ASTFiles[I], Diags, false);
+    if (!Unit)
+      continue;
+
+    ASTImporter Importer(CI.getDiagnostics(),
+                         CI.getASTContext(), 
+                         CI.getFileManager(),
+                         Unit->getASTContext(), 
+                         Unit->getFileManager());
+
+    TranslationUnitDecl *TU = Unit->getASTContext().getTranslationUnitDecl();
+    for (DeclContext::decl_iterator D = TU->decls_begin(), 
+                                 DEnd = TU->decls_end();
+         D != DEnd; ++D) {
+      // Don't re-import __va_list_tag, __builtin_va_list.
+      if (NamedDecl *ND = dyn_cast<NamedDecl>(*D))
+        if (IdentifierInfo *II = ND->getIdentifier())
+          if (II->isStr("__va_list_tag") || II->isStr("__builtin_va_list"))
+            continue;
+      
+      Importer.Import(*D);
+    }
+
+    delete Unit;
+  }
+
+  AdaptedAction->ExecuteAction();
+  CI.getDiagnostics().getClient()->EndSourceFile();
+}
+
+void ASTMergeAction::EndSourceFileAction() {
+  return AdaptedAction->EndSourceFileAction();
+}
+
+ASTMergeAction::ASTMergeAction(FrontendAction *AdaptedAction,
+                               std::string *ASTFiles, unsigned NumASTFiles)
+  : AdaptedAction(AdaptedAction), ASTFiles(ASTFiles, ASTFiles + NumASTFiles) {
+  assert(AdaptedAction && "ASTMergeAction needs an action to adapt");
+}
+
+ASTMergeAction::~ASTMergeAction() { 
+  delete AdaptedAction;
+}
+
+bool ASTMergeAction::usesPreprocessorOnly() const {
+  return AdaptedAction->usesPreprocessorOnly();
+}
+
+bool ASTMergeAction::usesCompleteTranslationUnit() {
+  return AdaptedAction->usesCompleteTranslationUnit();
+}
+
+bool ASTMergeAction::hasPCHSupport() const {
+  return AdaptedAction->hasPCHSupport();
+}
+
+bool ASTMergeAction::hasASTSupport() const {
+  return AdaptedAction->hasASTSupport();
+}
+
+bool ASTMergeAction::hasCodeCompletionSupport() const {
+  return AdaptedAction->hasCodeCompletionSupport();
+}
diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp
new file mode 100644
index 0000000..0f7dca2
--- /dev/null
+++ b/lib/Frontend/ASTUnit.cpp
@@ -0,0 +1,451 @@
+//===--- ASTUnit.cpp - ASTUnit utility ------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// ASTUnit Implementation.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/ASTUnit.h"
+#include "clang/Frontend/PCHReader.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/DeclVisitor.h"
+#include "clang/AST/StmtVisitor.h"
+#include "clang/Driver/Compilation.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/Job.h"
+#include "clang/Driver/Tool.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Frontend/FrontendActions.h"
+#include "clang/Frontend/FrontendDiagnostic.h"
+#include "clang/Frontend/FrontendOptions.h"
+#include "clang/Lex/HeaderSearch.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Basic/TargetOptions.h"
+#include "clang/Basic/TargetInfo.h"
+#include "clang/Basic/Diagnostic.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/System/Host.h"
+#include "llvm/System/Path.h"
+using namespace clang;
+
+ASTUnit::ASTUnit(bool _MainFileIsAST)
+  : MainFileIsAST(_MainFileIsAST), ConcurrencyCheckValue(CheckUnlocked) { }
+
+ASTUnit::~ASTUnit() {
+  ConcurrencyCheckValue = CheckLocked;
+  for (unsigned I = 0, N = TemporaryFiles.size(); I != N; ++I)
+    TemporaryFiles[I].eraseFromDisk();
+}
+
+namespace {
+
+/// \brief Gathers information from PCHReader that will be used to initialize
+/// a Preprocessor.
+class PCHInfoCollector : public PCHReaderListener {
+  LangOptions &LangOpt;
+  HeaderSearch &HSI;
+  std::string &TargetTriple;
+  std::string &Predefines;
+  unsigned &Counter;
+
+  unsigned NumHeaderInfos;
+
+public:
+  PCHInfoCollector(LangOptions &LangOpt, HeaderSearch &HSI,
+                   std::string &TargetTriple, std::string &Predefines,
+                   unsigned &Counter)
+    : LangOpt(LangOpt), HSI(HSI), TargetTriple(TargetTriple),
+      Predefines(Predefines), Counter(Counter), NumHeaderInfos(0) {}
+
+  virtual bool ReadLanguageOptions(const LangOptions &LangOpts) {
+    LangOpt = LangOpts;
+    return false;
+  }
+
+  virtual bool ReadTargetTriple(llvm::StringRef Triple) {
+    TargetTriple = Triple;
+    return false;
+  }
+
+  virtual bool ReadPredefinesBuffer(llvm::StringRef PCHPredef,
+                                    FileID PCHBufferID,
+                                    llvm::StringRef OriginalFileName,
+                                    std::string &SuggestedPredefines) {
+    Predefines = PCHPredef;
+    return false;
+  }
+
+  virtual void ReadHeaderFileInfo(const HeaderFileInfo &HFI, unsigned ID) {
+    HSI.setHeaderFileInfoForUID(HFI, NumHeaderInfos++);
+  }
+
+  virtual void ReadCounter(unsigned Value) {
+    Counter = Value;
+  }
+};
+
+class StoredDiagnosticClient : public DiagnosticClient {
+  llvm::SmallVectorImpl<StoredDiagnostic> &StoredDiags;
+  
+public:
+  explicit StoredDiagnosticClient(
+                          llvm::SmallVectorImpl<StoredDiagnostic> &StoredDiags)
+    : StoredDiags(StoredDiags) { }
+  
+  virtual void HandleDiagnostic(Diagnostic::Level Level,
+                                const DiagnosticInfo &Info);
+};
+
+/// \brief RAII object that optionally captures diagnostics, if
+/// there is no diagnostic client to capture them already.
+class CaptureDroppedDiagnostics {
+  Diagnostic &Diags;
+  StoredDiagnosticClient Client;
+  DiagnosticClient *PreviousClient;
+
+public:
+  CaptureDroppedDiagnostics(bool RequestCapture, Diagnostic &Diags, 
+                           llvm::SmallVectorImpl<StoredDiagnostic> &StoredDiags)
+    : Diags(Diags), Client(StoredDiags), PreviousClient(Diags.getClient()) 
+  {
+    if (RequestCapture || Diags.getClient() == 0)
+      Diags.setClient(&Client);
+  }
+
+  ~CaptureDroppedDiagnostics() {
+    Diags.setClient(PreviousClient);
+  }
+};
+
+} // anonymous namespace
+
+void StoredDiagnosticClient::HandleDiagnostic(Diagnostic::Level Level,
+                                              const DiagnosticInfo &Info) {
+  StoredDiags.push_back(StoredDiagnostic(Level, Info));
+}
+
+const std::string &ASTUnit::getOriginalSourceFileName() {
+  return OriginalSourceFile;
+}
+
+const std::string &ASTUnit::getPCHFileName() {
+  assert(isMainFileAST() && "Not an ASTUnit from a PCH file!");
+  return static_cast<PCHReader *>(Ctx->getExternalSource())->getFileName();
+}
+
+ASTUnit *ASTUnit::LoadFromPCHFile(const std::string &Filename,
+                                  llvm::IntrusiveRefCntPtr<Diagnostic> Diags,
+                                  bool OnlyLocalDecls,
+                                  RemappedFile *RemappedFiles,
+                                  unsigned NumRemappedFiles,
+                                  bool CaptureDiagnostics) {
+  llvm::OwningPtr<ASTUnit> AST(new ASTUnit(true));
+  
+  if (!Diags.getPtr()) {
+    // No diagnostics engine was provided, so create our own diagnostics object
+    // with the default options.
+    DiagnosticOptions DiagOpts;
+    Diags = CompilerInstance::createDiagnostics(DiagOpts, 0, 0);
+  }
+  
+  AST->OnlyLocalDecls = OnlyLocalDecls;
+  AST->Diagnostics = Diags;
+  AST->FileMgr.reset(new FileManager);
+  AST->SourceMgr.reset(new SourceManager(AST->getDiagnostics()));
+  AST->HeaderInfo.reset(new HeaderSearch(AST->getFileManager()));
+
+  // If requested, capture diagnostics in the ASTUnit.
+  CaptureDroppedDiagnostics Capture(CaptureDiagnostics, AST->getDiagnostics(),
+                                    AST->StoredDiagnostics);
+
+  for (unsigned I = 0; I != NumRemappedFiles; ++I) {
+    // Create the file entry for the file that we're mapping from.
+    const FileEntry *FromFile
+      = AST->getFileManager().getVirtualFile(RemappedFiles[I].first,
+                                    RemappedFiles[I].second->getBufferSize(),
+                                             0);
+    if (!FromFile) {
+      AST->getDiagnostics().Report(diag::err_fe_remap_missing_from_file)
+        << RemappedFiles[I].first;
+      delete RemappedFiles[I].second;
+      continue;
+    }
+    
+    // Override the contents of the "from" file with the contents of
+    // the "to" file.
+    AST->getSourceManager().overrideFileContents(FromFile, 
+                                                 RemappedFiles[I].second);    
+  }
+  
+  // Gather Info for preprocessor construction later on.
+
+  LangOptions LangInfo;
+  HeaderSearch &HeaderInfo = *AST->HeaderInfo.get();
+  std::string TargetTriple;
+  std::string Predefines;
+  unsigned Counter;
+
+  llvm::OwningPtr<PCHReader> Reader;
+  llvm::OwningPtr<ExternalASTSource> Source;
+
+  Reader.reset(new PCHReader(AST->getSourceManager(), AST->getFileManager(),
+                             AST->getDiagnostics()));
+  Reader->setListener(new PCHInfoCollector(LangInfo, HeaderInfo, TargetTriple,
+                                           Predefines, Counter));
+
+  switch (Reader->ReadPCH(Filename)) {
+  case PCHReader::Success:
+    break;
+
+  case PCHReader::Failure:
+  case PCHReader::IgnorePCH:
+    AST->getDiagnostics().Report(diag::err_fe_unable_to_load_pch);
+    return NULL;
+  }
+
+  AST->OriginalSourceFile = Reader->getOriginalSourceFile();
+
+  // PCH loaded successfully. Now create the preprocessor.
+
+  // Get information about the target being compiled for.
+  //
+  // FIXME: This is broken, we should store the TargetOptions in the PCH.
+  TargetOptions TargetOpts;
+  TargetOpts.ABI = "";
+  TargetOpts.CPU = "";
+  TargetOpts.Features.clear();
+  TargetOpts.Triple = TargetTriple;
+  AST->Target.reset(TargetInfo::CreateTargetInfo(AST->getDiagnostics(),
+                                                 TargetOpts));
+  AST->PP.reset(new Preprocessor(AST->getDiagnostics(), LangInfo, 
+                                 *AST->Target.get(),
+                                 AST->getSourceManager(), HeaderInfo));
+  Preprocessor &PP = *AST->PP.get();
+
+  PP.setPredefines(Reader->getSuggestedPredefines());
+  PP.setCounterValue(Counter);
+  Reader->setPreprocessor(PP);
+
+  // Create and initialize the ASTContext.
+
+  AST->Ctx.reset(new ASTContext(LangInfo,
+                                AST->getSourceManager(),
+                                *AST->Target.get(),
+                                PP.getIdentifierTable(),
+                                PP.getSelectorTable(),
+                                PP.getBuiltinInfo(),
+                                /* FreeMemory = */ false,
+                                /* size_reserve = */0));
+  ASTContext &Context = *AST->Ctx.get();
+
+  Reader->InitializeContext(Context);
+
+  // Attach the PCH reader to the AST context as an external AST
+  // source, so that declarations will be deserialized from the
+  // PCH file as needed.
+  Source.reset(Reader.take());
+  Context.setExternalSource(Source);
+
+  return AST.take();
+}
+
+namespace {
+
+class TopLevelDeclTrackerConsumer : public ASTConsumer {
+  ASTUnit &Unit;
+
+public:
+  TopLevelDeclTrackerConsumer(ASTUnit &_Unit) : Unit(_Unit) {}
+
+  void HandleTopLevelDecl(DeclGroupRef D) {
+    for (DeclGroupRef::iterator it = D.begin(), ie = D.end(); it != ie; ++it)
+      Unit.getTopLevelDecls().push_back(*it);
+  }
+};
+
+class TopLevelDeclTrackerAction : public ASTFrontendAction {
+public:
+  ASTUnit &Unit;
+
+  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                         llvm::StringRef InFile) {
+    return new TopLevelDeclTrackerConsumer(Unit);
+  }
+
+public:
+  TopLevelDeclTrackerAction(ASTUnit &_Unit) : Unit(_Unit) {}
+
+  virtual bool hasCodeCompletionSupport() const { return false; }
+};
+
+}
+
+ASTUnit *ASTUnit::LoadFromCompilerInvocation(CompilerInvocation *CI,
+                                   llvm::IntrusiveRefCntPtr<Diagnostic> Diags,
+                                             bool OnlyLocalDecls,
+                                             bool CaptureDiagnostics) {
+  // Create the compiler instance to use for building the AST.
+  CompilerInstance Clang;
+  llvm::OwningPtr<ASTUnit> AST;
+  llvm::OwningPtr<TopLevelDeclTrackerAction> Act;
+
+  if (!Diags.getPtr()) {
+    // No diagnostics engine was provided, so create our own diagnostics object
+    // with the default options.
+    DiagnosticOptions DiagOpts;
+    Diags = CompilerInstance::createDiagnostics(DiagOpts, 0, 0);
+  }
+  
+  Clang.setInvocation(CI);
+
+  Clang.setDiagnostics(Diags.getPtr());
+  Clang.setDiagnosticClient(Diags->getClient());
+
+  // Create the target instance.
+  Clang.setTarget(TargetInfo::CreateTargetInfo(Clang.getDiagnostics(),
+                                               Clang.getTargetOpts()));
+  if (!Clang.hasTarget()) {
+    Clang.takeDiagnosticClient();
+    return 0;
+  }
+
+  // Inform the target of the language options.
+  //
+  // FIXME: We shouldn't need to do this, the target should be immutable once
+  // created. This complexity should be lifted elsewhere.
+  Clang.getTarget().setForcedLangOptions(Clang.getLangOpts());
+
+  assert(Clang.getFrontendOpts().Inputs.size() == 1 &&
+         "Invocation must have exactly one source file!");
+  assert(Clang.getFrontendOpts().Inputs[0].first != FrontendOptions::IK_AST &&
+         "FIXME: AST inputs not yet supported here!");
+
+  // Create the AST unit.
+  AST.reset(new ASTUnit(false));
+  AST->Diagnostics = Diags;
+  AST->FileMgr.reset(new FileManager);
+  AST->SourceMgr.reset(new SourceManager(AST->getDiagnostics()));
+  AST->OnlyLocalDecls = OnlyLocalDecls;
+  AST->OriginalSourceFile = Clang.getFrontendOpts().Inputs[0].second;
+
+  // Capture any diagnostics that would otherwise be dropped.
+  CaptureDroppedDiagnostics Capture(CaptureDiagnostics, 
+                                    Clang.getDiagnostics(),
+                                    AST->StoredDiagnostics);
+
+  // Create a file manager object to provide access to and cache the filesystem.
+  Clang.setFileManager(&AST->getFileManager());
+
+  // Create the source manager.
+  Clang.setSourceManager(&AST->getSourceManager());
+
+  // Create the preprocessor.
+  Clang.createPreprocessor();
+
+  Act.reset(new TopLevelDeclTrackerAction(*AST));
+  if (!Act->BeginSourceFile(Clang, Clang.getFrontendOpts().Inputs[0].second,
+                           /*IsAST=*/false))
+    goto error;
+
+  Act->Execute();
+
+  // Steal the created target, context, and preprocessor, and take back the
+  // source and file managers.
+  AST->Ctx.reset(Clang.takeASTContext());
+  AST->PP.reset(Clang.takePreprocessor());
+  Clang.takeSourceManager();
+  Clang.takeFileManager();
+  AST->Target.reset(Clang.takeTarget());
+
+  Act->EndSourceFile();
+
+  Clang.takeDiagnosticClient();
+  Clang.takeInvocation();
+
+  AST->Invocation.reset(Clang.takeInvocation());
+  return AST.take();
+
+error:
+  Clang.takeSourceManager();
+  Clang.takeFileManager();
+  Clang.takeDiagnosticClient();
+  return 0;
+}
+
+ASTUnit *ASTUnit::LoadFromCommandLine(const char **ArgBegin,
+                                      const char **ArgEnd,
+                                    llvm::IntrusiveRefCntPtr<Diagnostic> Diags,
+                                      llvm::StringRef ResourceFilesPath,
+                                      bool OnlyLocalDecls,
+                                      RemappedFile *RemappedFiles,
+                                      unsigned NumRemappedFiles,
+                                      bool CaptureDiagnostics) {
+  if (!Diags.getPtr()) {
+    // No diagnostics engine was provided, so create our own diagnostics object
+    // with the default options.
+    DiagnosticOptions DiagOpts;
+    Diags = CompilerInstance::createDiagnostics(DiagOpts, 0, 0);
+  }
+  
+  llvm::SmallVector<const char *, 16> Args;
+  Args.push_back("<clang>"); // FIXME: Remove dummy argument.
+  Args.insert(Args.end(), ArgBegin, ArgEnd);
+
+  // FIXME: Find a cleaner way to force the driver into restricted modes. We
+  // also want to force it to use clang.
+  Args.push_back("-fsyntax-only");
+
+  // FIXME: We shouldn't have to pass in the path info.
+  driver::Driver TheDriver("clang", "/", llvm::sys::getHostTriple(),
+                           "a.out", false, false, *Diags);
+
+  // Don't check that inputs exist, they have been remapped.
+  TheDriver.setCheckInputsExist(false);
+
+  llvm::OwningPtr<driver::Compilation> C(
+    TheDriver.BuildCompilation(Args.size(), Args.data()));
+
+  // We expect to get back exactly one command job, if we didn't something
+  // failed.
+  const driver::JobList &Jobs = C->getJobs();
+  if (Jobs.size() != 1 || !isa<driver::Command>(Jobs.begin())) {
+    llvm::SmallString<256> Msg;
+    llvm::raw_svector_ostream OS(Msg);
+    C->PrintJob(OS, C->getJobs(), "; ", true);
+    Diags->Report(diag::err_fe_expected_compiler_job) << OS.str();
+    return 0;
+  }
+
+  const driver::Command *Cmd = cast<driver::Command>(*Jobs.begin());
+  if (llvm::StringRef(Cmd->getCreator().getName()) != "clang") {
+    Diags->Report(diag::err_fe_expected_clang_command);
+    return 0;
+  }
+
+  const driver::ArgStringList &CCArgs = Cmd->getArguments();
+  llvm::OwningPtr<CompilerInvocation> CI(new CompilerInvocation);
+  CompilerInvocation::CreateFromArgs(*CI,
+                                     const_cast<const char **>(CCArgs.data()),
+                                     const_cast<const char **>(CCArgs.data()) +
+                                       CCArgs.size(),
+                                     *Diags);
+
+  // Override any files that need remapping
+  for (unsigned I = 0; I != NumRemappedFiles; ++I)
+    CI->getPreprocessorOpts().addRemappedFile(RemappedFiles[I].first,
+                                              RemappedFiles[I].second);
+  
+  // Override the resources path.
+  CI->getHeaderSearchOpts().ResourceDir = ResourceFilesPath;
+
+  CI->getFrontendOpts().DisableFree = true;
+  return LoadFromCompilerInvocation(CI.take(), Diags, OnlyLocalDecls,
+                                    CaptureDiagnostics);
+}
diff --git a/lib/Frontend/AnalysisConsumer.cpp b/lib/Frontend/AnalysisConsumer.cpp
new file mode 100644
index 0000000..d55fbc1
--- /dev/null
+++ b/lib/Frontend/AnalysisConsumer.cpp
@@ -0,0 +1,661 @@
+//===--- AnalysisConsumer.cpp - ASTConsumer for running Analyses ----------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// "Meta" ASTConsumer for running different source analyses.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/AnalysisConsumer.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/ParentMap.h"
+#include "clang/Analysis/Analyses/LiveVariables.h"
+#include "clang/Analysis/Analyses/UninitializedValues.h"
+#include "clang/Analysis/CFG.h"
+#include "clang/Checker/Checkers/LocalCheckers.h"
+#include "clang/Checker/ManagerRegistry.h"
+#include "clang/Checker/BugReporter/PathDiagnostic.h"
+#include "clang/Checker/PathSensitive/AnalysisManager.h"
+#include "clang/Checker/BugReporter/BugReporter.h"
+#include "clang/Checker/PathSensitive/GRExprEngine.h"
+#include "clang/Checker/PathSensitive/GRTransferFuncs.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Frontend/PathDiagnosticClients.h"
+#include "clang/Lex/Preprocessor.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/System/Path.h"
+#include "llvm/System/Program.h"
+#include "llvm/ADT/OwningPtr.h"
+
+using namespace clang;
+
+static ExplodedNode::Auditor* CreateUbiViz();
+
+//===----------------------------------------------------------------------===//
+// Basic type definitions.
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Special PathDiagnosticClients.
+//===----------------------------------------------------------------------===//
+
+static PathDiagnosticClient*
+CreatePlistHTMLDiagnosticClient(const std::string& prefix,
+                                const Preprocessor &PP) {
+  llvm::sys::Path F(prefix);
+  PathDiagnosticClient *PD = CreateHTMLDiagnosticClient(F.getDirname(), PP);
+  return CreatePlistDiagnosticClient(prefix, PP, PD);
+}
+
+//===----------------------------------------------------------------------===//
+// AnalysisConsumer declaration.
+//===----------------------------------------------------------------------===//
+
+namespace {
+
+ class AnalysisConsumer : public ASTConsumer {
+ public:
+  typedef void (*CodeAction)(AnalysisConsumer &C, AnalysisManager &M, Decl *D);
+  typedef void (*TUAction)(AnalysisConsumer &C, AnalysisManager &M,
+                           TranslationUnitDecl &TU);
+
+ private:
+  typedef std::vector<CodeAction> Actions;
+  typedef std::vector<TUAction> TUActions;
+
+  Actions FunctionActions;
+  Actions ObjCMethodActions;
+  Actions ObjCImplementationActions;
+  TUActions TranslationUnitActions;
+
+public:
+  ASTContext* Ctx;
+  const Preprocessor &PP;
+  const std::string OutDir;
+  AnalyzerOptions Opts;
+  bool declDisplayed;
+
+
+  // PD is owned by AnalysisManager.
+  PathDiagnosticClient *PD;
+
+  StoreManagerCreator CreateStoreMgr;
+  ConstraintManagerCreator CreateConstraintMgr;
+
+  llvm::OwningPtr<AnalysisManager> Mgr;
+
+  AnalysisConsumer(const Preprocessor& pp,
+                   const std::string& outdir,
+                   const AnalyzerOptions& opts)
+    : Ctx(0), PP(pp), OutDir(outdir),
+      Opts(opts), declDisplayed(false), PD(0) {
+    DigestAnalyzerOptions();
+  }
+
+  void DigestAnalyzerOptions() {
+    // Create the PathDiagnosticClient.
+    if (!OutDir.empty()) {
+      switch (Opts.AnalysisDiagOpt) {
+      default:
+#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN, AUTOCREATE) \
+        case PD_##NAME: PD = CREATEFN(OutDir, PP); break;
+#include "clang/Frontend/Analyses.def"
+      }
+    }
+
+    // Create the analyzer component creators.
+    if (ManagerRegistry::StoreMgrCreator != 0) {
+      CreateStoreMgr = ManagerRegistry::StoreMgrCreator;
+    }
+    else {
+      switch (Opts.AnalysisStoreOpt) {
+      default:
+        assert(0 && "Unknown store manager.");
+#define ANALYSIS_STORE(NAME, CMDFLAG, DESC, CREATEFN)           \
+        case NAME##Model: CreateStoreMgr = CREATEFN; break;
+#include "clang/Frontend/Analyses.def"
+      }
+    }
+
+    if (ManagerRegistry::ConstraintMgrCreator != 0)
+      CreateConstraintMgr = ManagerRegistry::ConstraintMgrCreator;
+    else {
+      switch (Opts.AnalysisConstraintsOpt) {
+      default:
+        assert(0 && "Unknown store manager.");
+#define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATEFN)     \
+        case NAME##Model: CreateConstraintMgr = CREATEFN; break;
+#include "clang/Frontend/Analyses.def"
+      }
+    }
+  }
+
+  void DisplayFunction(const Decl *D) {
+    if (!Opts.AnalyzerDisplayProgress || declDisplayed)
+      return;
+
+    declDisplayed = true;
+    SourceManager &SM = Mgr->getASTContext().getSourceManager();
+    PresumedLoc Loc = SM.getPresumedLoc(D->getLocation());
+    llvm::errs() << "ANALYZE: " << Loc.getFilename();
+
+    if (isa<FunctionDecl>(D) || isa<ObjCMethodDecl>(D)) {
+      const NamedDecl *ND = cast<NamedDecl>(D);
+      llvm::errs() << ' ' << ND << '\n';
+    }
+    else if (isa<BlockDecl>(D)) {
+      llvm::errs() << ' ' << "block(line:" << Loc.getLine() << ",col:"
+                   << Loc.getColumn() << '\n';
+    }
+  }
+
+  void addCodeAction(CodeAction action) {
+    FunctionActions.push_back(action);
+    ObjCMethodActions.push_back(action);
+  }
+
+  void addObjCImplementationAction(CodeAction action) {
+    ObjCImplementationActions.push_back(action);
+  }
+
+  void addTranslationUnitAction(TUAction action) {
+    TranslationUnitActions.push_back(action);
+  }
+
+  virtual void Initialize(ASTContext &Context) {
+    Ctx = &Context;
+    Mgr.reset(new AnalysisManager(*Ctx, PP.getDiagnostics(),
+                                  PP.getLangOptions(), PD,
+                                  CreateStoreMgr, CreateConstraintMgr,
+                                  Opts.MaxNodes,
+                                  Opts.VisualizeEGDot, Opts.VisualizeEGUbi,
+                                  Opts.PurgeDead, Opts.EagerlyAssume,
+                                  Opts.TrimGraph));
+  }
+
+  virtual void HandleTopLevelDecl(DeclGroupRef D) {
+    declDisplayed = false;
+    for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I)
+      HandleTopLevelSingleDecl(*I);
+  }
+
+  void HandleTopLevelSingleDecl(Decl *D);
+  virtual void HandleTranslationUnit(ASTContext &C);
+
+  void HandleCode(Decl* D, Stmt* Body, Actions& actions);
+};
+} // end anonymous namespace
+
+namespace llvm {
+  template <> struct FoldingSetTrait<AnalysisConsumer::CodeAction> {
+    static inline void Profile(AnalysisConsumer::CodeAction X,
+                               FoldingSetNodeID& ID) {
+      ID.AddPointer(reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(X)));
+    }
+  };
+}
+
+//===----------------------------------------------------------------------===//
+// AnalysisConsumer implementation.
+//===----------------------------------------------------------------------===//
+
+void AnalysisConsumer::HandleTopLevelSingleDecl(Decl *D) {
+  switch (D->getKind()) {
+  case Decl::CXXConstructor:
+  case Decl::CXXDestructor:
+  case Decl::CXXConversion:
+  case Decl::CXXMethod:
+  case Decl::Function: {
+    FunctionDecl* FD = cast<FunctionDecl>(D);
+    if (!Opts.AnalyzeSpecificFunction.empty() &&
+        FD->getDeclName().getAsString() != Opts.AnalyzeSpecificFunction)
+        break;
+
+    if (Stmt *Body = FD->getBody())
+      HandleCode(FD, Body, FunctionActions);
+    break;
+  }
+
+  case Decl::ObjCMethod: {
+    ObjCMethodDecl* MD = cast<ObjCMethodDecl>(D);
+
+    if (!Opts.AnalyzeSpecificFunction.empty() &&
+        Opts.AnalyzeSpecificFunction != MD->getSelector().getAsString())
+      return;
+
+    if (Stmt* Body = MD->getBody())
+      HandleCode(MD, Body, ObjCMethodActions);
+    break;
+  }
+
+  default:
+    break;
+  }
+}
+
+void AnalysisConsumer::HandleTranslationUnit(ASTContext &C) {
+
+  TranslationUnitDecl *TU = C.getTranslationUnitDecl();
+
+  for (TUActions::iterator I = TranslationUnitActions.begin(),
+                           E = TranslationUnitActions.end(); I != E; ++I) {
+    (*I)(*this, *Mgr, *TU);
+  }
+
+  if (!ObjCImplementationActions.empty()) {
+    for (DeclContext::decl_iterator I = TU->decls_begin(),
+                                    E = TU->decls_end();
+         I != E; ++I)
+      if (ObjCImplementationDecl* ID = dyn_cast<ObjCImplementationDecl>(*I))
+        HandleCode(ID, 0, ObjCImplementationActions);
+  }
+
+  // Explicitly destroy the PathDiagnosticClient.  This will flush its output.
+  // FIXME: This should be replaced with something that doesn't rely on
+  // side-effects in PathDiagnosticClient's destructor. This is required when
+  // used with option -disable-free.
+  Mgr.reset(NULL);
+}
+
+static void FindBlocks(DeclContext *D, llvm::SmallVectorImpl<Decl*> &WL) {
+  if (BlockDecl *BD = dyn_cast<BlockDecl>(D))
+    WL.push_back(BD);
+
+  for (DeclContext::decl_iterator I = D->decls_begin(), E = D->decls_end();
+       I!=E; ++I)
+    if (DeclContext *DC = dyn_cast<DeclContext>(*I))
+      FindBlocks(DC, WL);
+}
+
+void AnalysisConsumer::HandleCode(Decl *D, Stmt* Body, Actions& actions) {
+
+  // Don't run the actions if an error has occured with parsing the file.
+  if (PP.getDiagnostics().hasErrorOccurred())
+    return;
+
+  // Don't run the actions on declarations in header files unless
+  // otherwise specified.
+  if (!Opts.AnalyzeAll &&
+      !Ctx->getSourceManager().isFromMainFile(D->getLocation()))
+    return;
+
+  // Clear the AnalysisManager of old AnalysisContexts.
+  Mgr->ClearContexts();
+
+  // Dispatch on the actions.
+  llvm::SmallVector<Decl*, 10> WL;
+  WL.push_back(D);
+
+  if (Body && Opts.AnalyzeNestedBlocks)
+    FindBlocks(cast<DeclContext>(D), WL);
+
+  for (Actions::iterator I = actions.begin(), E = actions.end(); I != E; ++I)
+    for (llvm::SmallVectorImpl<Decl*>::iterator WI=WL.begin(), WE=WL.end();
+         WI != WE; ++WI)
+      (*I)(*this, *Mgr, *WI);
+}
+
+//===----------------------------------------------------------------------===//
+// Analyses
+//===----------------------------------------------------------------------===//
+
+static void ActionWarnDeadStores(AnalysisConsumer &C, AnalysisManager& mgr,
+                                 Decl *D) {
+  if (LiveVariables *L = mgr.getLiveVariables(D)) {
+    C.DisplayFunction(D);
+    BugReporter BR(mgr);
+    CheckDeadStores(*mgr.getCFG(D), *L, mgr.getParentMap(D), BR);
+  }
+}
+
+static void ActionWarnUninitVals(AnalysisConsumer &C, AnalysisManager& mgr,
+                                 Decl *D) {
+  if (CFG* c = mgr.getCFG(D)) {
+    C.DisplayFunction(D);
+    CheckUninitializedValues(*c, mgr.getASTContext(), mgr.getDiagnostic());
+  }
+}
+
+
+static void ActionGRExprEngine(AnalysisConsumer &C, AnalysisManager& mgr,
+                               Decl *D,
+                               GRTransferFuncs* tf) {
+
+  llvm::OwningPtr<GRTransferFuncs> TF(tf);
+
+  // Display progress.
+  C.DisplayFunction(D);
+
+  // Construct the analysis engine.  We first query for the LiveVariables
+  // information to see if the CFG is valid.
+  // FIXME: Inter-procedural analysis will need to handle invalid CFGs.
+  if (!mgr.getLiveVariables(D))
+    return;
+
+  GRExprEngine Eng(mgr, TF.take());
+
+  if (C.Opts.EnableExperimentalInternalChecks)
+    RegisterExperimentalInternalChecks(Eng);
+
+  RegisterAppleChecks(Eng, *D);
+
+  if (C.Opts.EnableExperimentalChecks)
+    RegisterExperimentalChecks(Eng);
+
+  // Set the graph auditor.
+  llvm::OwningPtr<ExplodedNode::Auditor> Auditor;
+  if (mgr.shouldVisualizeUbigraph()) {
+    Auditor.reset(CreateUbiViz());
+    ExplodedNode::SetAuditor(Auditor.get());
+  }
+
+  // Execute the worklist algorithm.
+  Eng.ExecuteWorkList(mgr.getStackFrame(D), mgr.getMaxNodes());
+
+  // Release the auditor (if any) so that it doesn't monitor the graph
+  // created BugReporter.
+  ExplodedNode::SetAuditor(0);
+
+  // Visualize the exploded graph.
+  if (mgr.shouldVisualizeGraphviz())
+    Eng.ViewGraph(mgr.shouldTrimGraph());
+
+  // Display warnings.
+  Eng.getBugReporter().FlushReports();
+}
+
+static void ActionObjCMemCheckerAux(AnalysisConsumer &C, AnalysisManager& mgr,
+                                  Decl *D, bool GCEnabled) {
+
+  GRTransferFuncs* TF = MakeCFRefCountTF(mgr.getASTContext(),
+                                         GCEnabled,
+                                         mgr.getLangOptions());
+
+  ActionGRExprEngine(C, mgr, D, TF);
+}
+
+static void ActionObjCMemChecker(AnalysisConsumer &C, AnalysisManager& mgr,
+                               Decl *D) {
+
+ switch (mgr.getLangOptions().getGCMode()) {
+ default:
+   assert (false && "Invalid GC mode.");
+ case LangOptions::NonGC:
+   ActionObjCMemCheckerAux(C, mgr, D, false);
+   break;
+
+ case LangOptions::GCOnly:
+   ActionObjCMemCheckerAux(C, mgr, D, true);
+   break;
+
+ case LangOptions::HybridGC:
+   ActionObjCMemCheckerAux(C, mgr, D, false);
+   ActionObjCMemCheckerAux(C, mgr, D, true);
+   break;
+ }
+}
+
+static void ActionDisplayLiveVariables(AnalysisConsumer &C,
+                                       AnalysisManager& mgr, Decl *D) {
+  if (LiveVariables* L = mgr.getLiveVariables(D)) {
+    C.DisplayFunction(D);
+    L->dumpBlockLiveness(mgr.getSourceManager());
+  }
+}
+
+static void ActionCFGDump(AnalysisConsumer &C, AnalysisManager& mgr, Decl *D) {
+  if (CFG *cfg = mgr.getCFG(D)) {
+    C.DisplayFunction(D);
+    cfg->dump(mgr.getLangOptions());
+  }
+}
+
+static void ActionCFGView(AnalysisConsumer &C, AnalysisManager& mgr, Decl *D) {
+  if (CFG *cfg = mgr.getCFG(D)) {
+    C.DisplayFunction(D);
+    cfg->viewCFG(mgr.getLangOptions());
+  }
+}
+
+static void ActionSecuritySyntacticChecks(AnalysisConsumer &C,
+                                          AnalysisManager &mgr, Decl *D) {
+  C.DisplayFunction(D);
+  BugReporter BR(mgr);
+  CheckSecuritySyntaxOnly(D, BR);
+}
+
+static void ActionLLVMConventionChecker(AnalysisConsumer &C,
+                                        AnalysisManager &mgr,
+                                        TranslationUnitDecl &TU) {
+  BugReporter BR(mgr);
+  CheckLLVMConventions(TU, BR);
+}
+
+static void ActionWarnObjCDealloc(AnalysisConsumer &C, AnalysisManager& mgr,
+                                  Decl *D) {
+  if (mgr.getLangOptions().getGCMode() == LangOptions::GCOnly)
+    return;
+
+  C.DisplayFunction(D);
+  BugReporter BR(mgr);
+  CheckObjCDealloc(cast<ObjCImplementationDecl>(D), mgr.getLangOptions(), BR);
+}
+
+static void ActionWarnObjCUnusedIvars(AnalysisConsumer &C, AnalysisManager& mgr,
+                                      Decl *D) {
+  C.DisplayFunction(D);
+  BugReporter BR(mgr);
+  CheckObjCUnusedIvar(cast<ObjCImplementationDecl>(D), BR);
+}
+
+static void ActionWarnObjCMethSigs(AnalysisConsumer &C, AnalysisManager& mgr,
+                                   Decl *D) {
+  C.DisplayFunction(D);
+  BugReporter BR(mgr);
+  CheckObjCInstMethSignature(cast<ObjCImplementationDecl>(D), BR);
+}
+
+static void ActionWarnSizeofPointer(AnalysisConsumer &C, AnalysisManager &mgr,
+                                    Decl *D) {
+  C.DisplayFunction(D);
+  BugReporter BR(mgr);
+  CheckSizeofPointer(D, BR);
+}
+
+static void ActionInlineCall(AnalysisConsumer &C, AnalysisManager &mgr,
+                             TranslationUnitDecl &TU) {
+
+  // Find the entry function definition (if any).
+  FunctionDecl *D = 0;
+
+  // Must specify an entry function.
+  if (!C.Opts.AnalyzeSpecificFunction.empty()) {
+    for (DeclContext::decl_iterator I=TU.decls_begin(), E=TU.decls_end();
+         I != E; ++I) {
+      if (FunctionDecl *fd = dyn_cast<FunctionDecl>(*I))
+        if (fd->isThisDeclarationADefinition() &&
+            fd->getNameAsString() == C.Opts.AnalyzeSpecificFunction) {
+          D = fd;
+          break;
+        }
+    }
+  }
+
+  if (!D)
+    return;
+
+
+  // FIXME: This is largely copy of ActionGRExprEngine. Needs cleanup.
+  // Display progress.
+  C.DisplayFunction(D);
+
+  // FIXME: Make a fake transfer function. The GRTransferFunc interface
+  // eventually will be removed.
+  GRExprEngine Eng(mgr, new GRTransferFuncs());
+
+  if (C.Opts.EnableExperimentalInternalChecks)
+    RegisterExperimentalInternalChecks(Eng);
+
+  RegisterAppleChecks(Eng, *D);
+
+  if (C.Opts.EnableExperimentalChecks)
+    RegisterExperimentalChecks(Eng);
+
+  // Register call inliner as the last checker.
+  RegisterCallInliner(Eng);
+
+  // Execute the worklist algorithm.
+  Eng.ExecuteWorkList(mgr.getStackFrame(D));
+
+  // Visualize the exploded graph.
+  if (mgr.shouldVisualizeGraphviz())
+    Eng.ViewGraph(mgr.shouldTrimGraph());
+
+  // Display warnings.
+  Eng.getBugReporter().FlushReports();
+}
+
+//===----------------------------------------------------------------------===//
+// AnalysisConsumer creation.
+//===----------------------------------------------------------------------===//
+
+ASTConsumer* clang::CreateAnalysisConsumer(const Preprocessor& pp,
+                                           const std::string& OutDir,
+                                           const AnalyzerOptions& Opts) {
+  llvm::OwningPtr<AnalysisConsumer> C(new AnalysisConsumer(pp, OutDir, Opts));
+
+  for (unsigned i = 0; i < Opts.AnalysisList.size(); ++i)
+    switch (Opts.AnalysisList[i]) {
+#define ANALYSIS(NAME, CMD, DESC, SCOPE)\
+    case NAME:\
+      C->add ## SCOPE ## Action(&Action ## NAME);\
+      break;
+#include "clang/Frontend/Analyses.def"
+    default: break;
+    }
+
+  // Last, disable the effects of '-Werror' when using the AnalysisConsumer.
+  pp.getDiagnostics().setWarningsAsErrors(false);
+
+  return C.take();
+}
+
+//===----------------------------------------------------------------------===//
+// Ubigraph Visualization.  FIXME: Move to separate file.
+//===----------------------------------------------------------------------===//
+
+namespace {
+
+class UbigraphViz : public ExplodedNode::Auditor {
+  llvm::OwningPtr<llvm::raw_ostream> Out;
+  llvm::sys::Path Dir, Filename;
+  unsigned Cntr;
+
+  typedef llvm::DenseMap<void*,unsigned> VMap;
+  VMap M;
+
+public:
+  UbigraphViz(llvm::raw_ostream* out, llvm::sys::Path& dir,
+              llvm::sys::Path& filename);
+
+  ~UbigraphViz();
+
+  virtual void AddEdge(ExplodedNode* Src, ExplodedNode* Dst);
+};
+
+} // end anonymous namespace
+
+static ExplodedNode::Auditor* CreateUbiViz() {
+  std::string ErrMsg;
+
+  llvm::sys::Path Dir = llvm::sys::Path::GetTemporaryDirectory(&ErrMsg);
+  if (!ErrMsg.empty())
+    return 0;
+
+  llvm::sys::Path Filename = Dir;
+  Filename.appendComponent("llvm_ubi");
+  Filename.makeUnique(true,&ErrMsg);
+
+  if (!ErrMsg.empty())
+    return 0;
+
+  llvm::errs() << "Writing '" << Filename.str() << "'.\n";
+
+  llvm::OwningPtr<llvm::raw_fd_ostream> Stream;
+  Stream.reset(new llvm::raw_fd_ostream(Filename.c_str(), ErrMsg));
+
+  if (!ErrMsg.empty())
+    return 0;
+
+  return new UbigraphViz(Stream.take(), Dir, Filename);
+}
+
+void UbigraphViz::AddEdge(ExplodedNode* Src, ExplodedNode* Dst) {
+
+  assert (Src != Dst && "Self-edges are not allowed.");
+
+  // Lookup the Src.  If it is a new node, it's a root.
+  VMap::iterator SrcI= M.find(Src);
+  unsigned SrcID;
+
+  if (SrcI == M.end()) {
+    M[Src] = SrcID = Cntr++;
+    *Out << "('vertex', " << SrcID << ", ('color','#00ff00'))\n";
+  }
+  else
+    SrcID = SrcI->second;
+
+  // Lookup the Dst.
+  VMap::iterator DstI= M.find(Dst);
+  unsigned DstID;
+
+  if (DstI == M.end()) {
+    M[Dst] = DstID = Cntr++;
+    *Out << "('vertex', " << DstID << ")\n";
+  }
+  else {
+    // We have hit DstID before.  Change its style to reflect a cache hit.
+    DstID = DstI->second;
+    *Out << "('change_vertex_style', " << DstID << ", 1)\n";
+  }
+
+  // Add the edge.
+  *Out << "('edge', " << SrcID << ", " << DstID
+       << ", ('arrow','true'), ('oriented', 'true'))\n";
+}
+
+UbigraphViz::UbigraphViz(llvm::raw_ostream* out, llvm::sys::Path& dir,
+                         llvm::sys::Path& filename)
+  : Out(out), Dir(dir), Filename(filename), Cntr(0) {
+
+  *Out << "('vertex_style_attribute', 0, ('shape', 'icosahedron'))\n";
+  *Out << "('vertex_style', 1, 0, ('shape', 'sphere'), ('color', '#ffcc66'),"
+          " ('size', '1.5'))\n";
+}
+
+UbigraphViz::~UbigraphViz() {
+  Out.reset(0);
+  llvm::errs() << "Running 'ubiviz' program... ";
+  std::string ErrMsg;
+  llvm::sys::Path Ubiviz = llvm::sys::Program::FindProgramByName("ubiviz");
+  std::vector<const char*> args;
+  args.push_back(Ubiviz.c_str());
+  args.push_back(Filename.c_str());
+  args.push_back(0);
+
+  if (llvm::sys::Program::ExecuteAndWait(Ubiviz, &args[0],0,0,0,0,&ErrMsg)) {
+    llvm::errs() << "Error viewing graph: " << ErrMsg << "\n";
+  }
+
+  // Delete the directory.
+  Dir.eraseFromDisk(true);
+}
diff --git a/lib/Frontend/CMakeLists.txt b/lib/Frontend/CMakeLists.txt
new file mode 100644
index 0000000..b69ad97
--- /dev/null
+++ b/lib/Frontend/CMakeLists.txt
@@ -0,0 +1,57 @@
+set(LLVM_NO_RTTI 1)
+
+add_clang_library(clangFrontend
+  ASTConsumers.cpp
+  ASTMerge.cpp
+  ASTUnit.cpp
+  AnalysisConsumer.cpp
+  CacheTokens.cpp
+  CodeGenAction.cpp
+  CompilerInstance.cpp
+  CompilerInvocation.cpp
+  DeclXML.cpp
+  DependencyFile.cpp
+  DiagChecker.cpp
+  DocumentXML.cpp
+  FixItRewriter.cpp
+  FrontendAction.cpp
+  FrontendActions.cpp
+  FrontendOptions.cpp
+  GeneratePCH.cpp
+  HTMLDiagnostics.cpp
+  HTMLPrint.cpp
+  InitHeaderSearch.cpp
+  InitPreprocessor.cpp
+  LangStandards.cpp
+  PCHReader.cpp
+  PCHReaderDecl.cpp
+  PCHReaderStmt.cpp
+  PCHWriter.cpp
+  PCHWriterDecl.cpp
+  PCHWriterStmt.cpp
+  PlistDiagnostics.cpp
+  PrintParserCallbacks.cpp
+  PrintPreprocessedOutput.cpp
+  RewriteMacros.cpp
+  RewriteObjC.cpp
+  RewriteTest.cpp
+  StmtXML.cpp
+  TextDiagnosticBuffer.cpp
+  TextDiagnosticPrinter.cpp
+  TypeXML.cpp
+  VerifyDiagnosticsClient.cpp
+  Warnings.cpp
+  )
+
+IF(MSVC)
+  get_target_property(NON_ANSI_COMPILE_FLAGS clangFrontend COMPILE_FLAGS)
+  string(REPLACE /Za
+    "" NON_ANSI_COMPILE_FLAGS
+    ${NON_ANSI_COMPILE_FLAGS})
+  set_target_properties(clangFrontend PROPERTIES COMPILE_FLAGS ${NON_ANSI_COMPILE_FLAGS})
+ENDIF(MSVC)
+
+add_dependencies(clangFrontend 
+  ClangDiagnosticFrontend 
+  ClangDiagnosticLex
+  ClangDiagnosticSema)
diff --git a/lib/Frontend/CacheTokens.cpp b/lib/Frontend/CacheTokens.cpp
new file mode 100644
index 0000000..a5fcebe
--- /dev/null
+++ b/lib/Frontend/CacheTokens.cpp
@@ -0,0 +1,649 @@
+//===--- CacheTokens.cpp - Caching of lexer tokens for PTH support --------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This provides a possible implementation of PTH support for Clang that is
+// based on caching lexed tokens and identifiers.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/Utils.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/OnDiskHashTable.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Lex/Preprocessor.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/System/Path.h"
+
+// FIXME: put this somewhere else?
+#ifndef S_ISDIR
+#define S_ISDIR(x) (((x)&_S_IFDIR)!=0)
+#endif
+
+using namespace clang;
+using namespace clang::io;
+
+//===----------------------------------------------------------------------===//
+// PTH-specific stuff.
+//===----------------------------------------------------------------------===//
+
+namespace {
+class PTHEntry {
+  Offset TokenData, PPCondData;
+
+public:
+  PTHEntry() {}
+
+  PTHEntry(Offset td, Offset ppcd)
+    : TokenData(td), PPCondData(ppcd) {}
+
+  Offset getTokenOffset() const { return TokenData; }
+  Offset getPPCondTableOffset() const { return PPCondData; }
+};
+
+
+class PTHEntryKeyVariant {
+  union { const FileEntry* FE; const char* Path; };
+  enum { IsFE = 0x1, IsDE = 0x2, IsNoExist = 0x0 } Kind;
+  struct stat *StatBuf;
+public:
+  PTHEntryKeyVariant(const FileEntry *fe)
+    : FE(fe), Kind(IsFE), StatBuf(0) {}
+
+  PTHEntryKeyVariant(struct stat* statbuf, const char* path)
+    : Path(path), Kind(IsDE), StatBuf(new struct stat(*statbuf)) {}
+
+  explicit PTHEntryKeyVariant(const char* path)
+    : Path(path), Kind(IsNoExist), StatBuf(0) {}
+
+  bool isFile() const { return Kind == IsFE; }
+
+  llvm::StringRef getString() const {
+    return Kind == IsFE ? FE->getName() : Path;
+  }
+
+  unsigned getKind() const { return (unsigned) Kind; }
+
+  void EmitData(llvm::raw_ostream& Out) {
+    switch (Kind) {
+    case IsFE:
+      // Emit stat information.
+      ::Emit32(Out, FE->getInode());
+      ::Emit32(Out, FE->getDevice());
+      ::Emit16(Out, FE->getFileMode());
+      ::Emit64(Out, FE->getModificationTime());
+      ::Emit64(Out, FE->getSize());
+      break;
+    case IsDE:
+      // Emit stat information.
+      ::Emit32(Out, (uint32_t) StatBuf->st_ino);
+      ::Emit32(Out, (uint32_t) StatBuf->st_dev);
+      ::Emit16(Out, (uint16_t) StatBuf->st_mode);
+      ::Emit64(Out, (uint64_t) StatBuf->st_mtime);
+      ::Emit64(Out, (uint64_t) StatBuf->st_size);
+      delete StatBuf;
+      break;
+    default:
+      break;
+    }
+  }
+
+  unsigned getRepresentationLength() const {
+    return Kind == IsNoExist ? 0 : 4 + 4 + 2 + 8 + 8;
+  }
+};
+
+class FileEntryPTHEntryInfo {
+public:
+  typedef PTHEntryKeyVariant key_type;
+  typedef key_type key_type_ref;
+
+  typedef PTHEntry data_type;
+  typedef const PTHEntry& data_type_ref;
+
+  static unsigned ComputeHash(PTHEntryKeyVariant V) {
+    return llvm::HashString(V.getString());
+  }
+
+  static std::pair<unsigned,unsigned>
+  EmitKeyDataLength(llvm::raw_ostream& Out, PTHEntryKeyVariant V,
+                    const PTHEntry& E) {
+
+    unsigned n = V.getString().size() + 1 + 1;
+    ::Emit16(Out, n);
+
+    unsigned m = V.getRepresentationLength() + (V.isFile() ? 4 + 4 : 0);
+    ::Emit8(Out, m);
+
+    return std::make_pair(n, m);
+  }
+
+  static void EmitKey(llvm::raw_ostream& Out, PTHEntryKeyVariant V, unsigned n){
+    // Emit the entry kind.
+    ::Emit8(Out, (unsigned) V.getKind());
+    // Emit the string.
+    Out.write(V.getString().data(), n - 1);
+  }
+
+  static void EmitData(llvm::raw_ostream& Out, PTHEntryKeyVariant V,
+                       const PTHEntry& E, unsigned) {
+
+
+    // For file entries emit the offsets into the PTH file for token data
+    // and the preprocessor blocks table.
+    if (V.isFile()) {
+      ::Emit32(Out, E.getTokenOffset());
+      ::Emit32(Out, E.getPPCondTableOffset());
+    }
+
+    // Emit any other data associated with the key (i.e., stat information).
+    V.EmitData(Out);
+  }
+};
+
+class OffsetOpt {
+  bool valid;
+  Offset off;
+public:
+  OffsetOpt() : valid(false) {}
+  bool hasOffset() const { return valid; }
+  Offset getOffset() const { assert(valid); return off; }
+  void setOffset(Offset o) { off = o; valid = true; }
+};
+} // end anonymous namespace
+
+typedef OnDiskChainedHashTableGenerator<FileEntryPTHEntryInfo> PTHMap;
+
+namespace {
+class PTHWriter {
+  typedef llvm::DenseMap<const IdentifierInfo*,uint32_t> IDMap;
+  typedef llvm::StringMap<OffsetOpt, llvm::BumpPtrAllocator> CachedStrsTy;
+
+  IDMap IM;
+  llvm::raw_fd_ostream& Out;
+  Preprocessor& PP;
+  uint32_t idcount;
+  PTHMap PM;
+  CachedStrsTy CachedStrs;
+  Offset CurStrOffset;
+  std::vector<llvm::StringMapEntry<OffsetOpt>*> StrEntries;
+
+  //// Get the persistent id for the given IdentifierInfo*.
+  uint32_t ResolveID(const IdentifierInfo* II);
+
+  /// Emit a token to the PTH file.
+  void EmitToken(const Token& T);
+
+  void Emit8(uint32_t V) { ::Emit8(Out, V); }
+
+  void Emit16(uint32_t V) { ::Emit16(Out, V); }
+
+  void Emit24(uint32_t V) { ::Emit24(Out, V); }
+
+  void Emit32(uint32_t V) { ::Emit32(Out, V); }
+
+  void EmitBuf(const char *Ptr, unsigned NumBytes) {
+    Out.write(Ptr, NumBytes);
+  }
+
+  void EmitString(llvm::StringRef V) {
+    ::Emit16(Out, V.size());
+    EmitBuf(V.data(), V.size());
+  }
+
+  /// EmitIdentifierTable - Emits two tables to the PTH file.  The first is
+  ///  a hashtable mapping from identifier strings to persistent IDs.
+  ///  The second is a straight table mapping from persistent IDs to string data
+  ///  (the keys of the first table).
+  std::pair<Offset, Offset> EmitIdentifierTable();
+
+  /// EmitFileTable - Emit a table mapping from file name strings to PTH
+  /// token data.
+  Offset EmitFileTable() { return PM.Emit(Out); }
+
+  PTHEntry LexTokens(Lexer& L);
+  Offset EmitCachedSpellings();
+
+public:
+  PTHWriter(llvm::raw_fd_ostream& out, Preprocessor& pp)
+    : Out(out), PP(pp), idcount(0), CurStrOffset(0) {}
+
+  PTHMap &getPM() { return PM; }
+  void GeneratePTH(const std::string &MainFile);
+};
+} // end anonymous namespace
+
+uint32_t PTHWriter::ResolveID(const IdentifierInfo* II) {
+  // Null IdentifierInfo's map to the persistent ID 0.
+  if (!II)
+    return 0;
+
+  IDMap::iterator I = IM.find(II);
+  if (I != IM.end())
+    return I->second; // We've already added 1.
+
+  IM[II] = ++idcount; // Pre-increment since '0' is reserved for NULL.
+  return idcount;
+}
+
+void PTHWriter::EmitToken(const Token& T) {
+  // Emit the token kind, flags, and length.
+  Emit32(((uint32_t) T.getKind()) | ((((uint32_t) T.getFlags())) << 8)|
+         (((uint32_t) T.getLength()) << 16));
+
+  if (!T.isLiteral()) {
+    Emit32(ResolveID(T.getIdentifierInfo()));
+  } else {
+    // We cache *un-cleaned* spellings. This gives us 100% fidelity with the
+    // source code.
+    const char* s = T.getLiteralData();
+    unsigned len = T.getLength();
+
+    // Get the string entry.
+    llvm::StringMapEntry<OffsetOpt> *E = &CachedStrs.GetOrCreateValue(s, s+len);
+
+    // If this is a new string entry, bump the PTH offset.
+    if (!E->getValue().hasOffset()) {
+      E->getValue().setOffset(CurStrOffset);
+      StrEntries.push_back(E);
+      CurStrOffset += len + 1;
+    }
+
+    // Emit the relative offset into the PTH file for the spelling string.
+    Emit32(E->getValue().getOffset());
+  }
+
+  // Emit the offset into the original source file of this token so that we
+  // can reconstruct its SourceLocation.
+  Emit32(PP.getSourceManager().getFileOffset(T.getLocation()));
+}
+
+PTHEntry PTHWriter::LexTokens(Lexer& L) {
+  // Pad 0's so that we emit tokens to a 4-byte alignment.
+  // This speed up reading them back in.
+  Pad(Out, 4);
+  Offset TokenOff = (Offset) Out.tell();
+
+  // Keep track of matching '#if' ... '#endif'.
+  typedef std::vector<std::pair<Offset, unsigned> > PPCondTable;
+  PPCondTable PPCond;
+  std::vector<unsigned> PPStartCond;
+  bool ParsingPreprocessorDirective = false;
+  Token Tok;
+
+  do {
+    L.LexFromRawLexer(Tok);
+  NextToken:
+
+    if ((Tok.isAtStartOfLine() || Tok.is(tok::eof)) &&
+        ParsingPreprocessorDirective) {
+      // Insert an eom token into the token cache.  It has the same
+      // position as the next token that is not on the same line as the
+      // preprocessor directive.  Observe that we continue processing
+      // 'Tok' when we exit this branch.
+      Token Tmp = Tok;
+      Tmp.setKind(tok::eom);
+      Tmp.clearFlag(Token::StartOfLine);
+      Tmp.setIdentifierInfo(0);
+      EmitToken(Tmp);
+      ParsingPreprocessorDirective = false;
+    }
+
+    if (Tok.is(tok::identifier)) {
+      PP.LookUpIdentifierInfo(Tok);
+      EmitToken(Tok);
+      continue;
+    }
+
+    if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
+      // Special processing for #include.  Store the '#' token and lex
+      // the next token.
+      assert(!ParsingPreprocessorDirective);
+      Offset HashOff = (Offset) Out.tell();
+      EmitToken(Tok);
+
+      // Get the next token.
+      L.LexFromRawLexer(Tok);
+
+      // If we see the start of line, then we had a null directive "#".
+      if (Tok.isAtStartOfLine())
+        goto NextToken;
+
+      // Did we see 'include'/'import'/'include_next'?
+      if (Tok.isNot(tok::identifier)) {
+        EmitToken(Tok);
+        continue;
+      }
+
+      IdentifierInfo* II = PP.LookUpIdentifierInfo(Tok);
+      tok::PPKeywordKind K = II->getPPKeywordID();
+
+      ParsingPreprocessorDirective = true;
+
+      switch (K) {
+      case tok::pp_not_keyword:
+        // Invalid directives "#foo" can occur in #if 0 blocks etc, just pass
+        // them through.
+      default:
+        break;
+
+      case tok::pp_include:
+      case tok::pp_import:
+      case tok::pp_include_next: {
+        // Save the 'include' token.
+        EmitToken(Tok);
+        // Lex the next token as an include string.
+        L.setParsingPreprocessorDirective(true);
+        L.LexIncludeFilename(Tok);
+        L.setParsingPreprocessorDirective(false);
+        assert(!Tok.isAtStartOfLine());
+        if (Tok.is(tok::identifier))
+          PP.LookUpIdentifierInfo(Tok);
+
+        break;
+      }
+      case tok::pp_if:
+      case tok::pp_ifdef:
+      case tok::pp_ifndef: {
+        // Add an entry for '#if' and friends.  We initially set the target
+        // index to 0.  This will get backpatched when we hit #endif.
+        PPStartCond.push_back(PPCond.size());
+        PPCond.push_back(std::make_pair(HashOff, 0U));
+        break;
+      }
+      case tok::pp_endif: {
+        // Add an entry for '#endif'.  We set the target table index to itself.
+        // This will later be set to zero when emitting to the PTH file.  We
+        // use 0 for uninitialized indices because that is easier to debug.
+        unsigned index = PPCond.size();
+        // Backpatch the opening '#if' entry.
+        assert(!PPStartCond.empty());
+        assert(PPCond.size() > PPStartCond.back());
+        assert(PPCond[PPStartCond.back()].second == 0);
+        PPCond[PPStartCond.back()].second = index;
+        PPStartCond.pop_back();
+        // Add the new entry to PPCond.
+        PPCond.push_back(std::make_pair(HashOff, index));
+        EmitToken(Tok);
+
+        // Some files have gibberish on the same line as '#endif'.
+        // Discard these tokens.
+        do
+          L.LexFromRawLexer(Tok);
+        while (Tok.isNot(tok::eof) && !Tok.isAtStartOfLine());
+        // We have the next token in hand.
+        // Don't immediately lex the next one.
+        goto NextToken;
+      }
+      case tok::pp_elif:
+      case tok::pp_else: {
+        // Add an entry for #elif or #else.
+        // This serves as both a closing and opening of a conditional block.
+        // This means that its entry will get backpatched later.
+        unsigned index = PPCond.size();
+        // Backpatch the previous '#if' entry.
+        assert(!PPStartCond.empty());
+        assert(PPCond.size() > PPStartCond.back());
+        assert(PPCond[PPStartCond.back()].second == 0);
+        PPCond[PPStartCond.back()].second = index;
+        PPStartCond.pop_back();
+        // Now add '#elif' as a new block opening.
+        PPCond.push_back(std::make_pair(HashOff, 0U));
+        PPStartCond.push_back(index);
+        break;
+      }
+      }
+    }
+
+    EmitToken(Tok);
+  }
+  while (Tok.isNot(tok::eof));
+
+  assert(PPStartCond.empty() && "Error: imblanced preprocessor conditionals.");
+
+  // Next write out PPCond.
+  Offset PPCondOff = (Offset) Out.tell();
+
+  // Write out the size of PPCond so that clients can identifer empty tables.
+  Emit32(PPCond.size());
+
+  for (unsigned i = 0, e = PPCond.size(); i!=e; ++i) {
+    Emit32(PPCond[i].first - TokenOff);
+    uint32_t x = PPCond[i].second;
+    assert(x != 0 && "PPCond entry not backpatched.");
+    // Emit zero for #endifs.  This allows us to do checking when
+    // we read the PTH file back in.
+    Emit32(x == i ? 0 : x);
+  }
+
+  return PTHEntry(TokenOff, PPCondOff);
+}
+
+Offset PTHWriter::EmitCachedSpellings() {
+  // Write each cached strings to the PTH file.
+  Offset SpellingsOff = Out.tell();
+
+  for (std::vector<llvm::StringMapEntry<OffsetOpt>*>::iterator
+       I = StrEntries.begin(), E = StrEntries.end(); I!=E; ++I)
+    EmitBuf((*I)->getKeyData(), (*I)->getKeyLength()+1 /*nul included*/);
+
+  return SpellingsOff;
+}
+
+void PTHWriter::GeneratePTH(const std::string &MainFile) {
+  // Generate the prologue.
+  Out << "cfe-pth";
+  Emit32(PTHManager::Version);
+
+  // Leave 4 words for the prologue.
+  Offset PrologueOffset = Out.tell();
+  for (unsigned i = 0; i < 4; ++i)
+    Emit32(0);
+
+  // Write the name of the MainFile.
+  if (!MainFile.empty()) {
+    EmitString(MainFile);
+  } else {
+    // String with 0 bytes.
+    Emit16(0);
+  }
+  Emit8(0);
+
+  // Iterate over all the files in SourceManager.  Create a lexer
+  // for each file and cache the tokens.
+  SourceManager &SM = PP.getSourceManager();
+  const LangOptions &LOpts = PP.getLangOptions();
+
+  for (SourceManager::fileinfo_iterator I = SM.fileinfo_begin(),
+       E = SM.fileinfo_end(); I != E; ++I) {
+    const SrcMgr::ContentCache &C = *I->second;
+    const FileEntry *FE = C.Entry;
+
+    // FIXME: Handle files with non-absolute paths.
+    llvm::sys::Path P(FE->getName());
+    if (!P.isAbsolute())
+      continue;
+
+    const llvm::MemoryBuffer *B = C.getBuffer(PP.getDiagnostics(), SM);
+    if (!B) continue;
+
+    FileID FID = SM.createFileID(FE, SourceLocation(), SrcMgr::C_User);
+    const llvm::MemoryBuffer *FromFile = SM.getBuffer(FID);
+    Lexer L(FID, FromFile, SM, LOpts);
+    PM.insert(FE, LexTokens(L));
+  }
+
+  // Write out the identifier table.
+  const std::pair<Offset,Offset> &IdTableOff = EmitIdentifierTable();
+
+  // Write out the cached strings table.
+  Offset SpellingOff = EmitCachedSpellings();
+
+  // Write out the file table.
+  Offset FileTableOff = EmitFileTable();
+
+  // Finally, write the prologue.
+  Out.seek(PrologueOffset);
+  Emit32(IdTableOff.first);
+  Emit32(IdTableOff.second);
+  Emit32(FileTableOff);
+  Emit32(SpellingOff);
+}
+
+namespace {
+/// StatListener - A simple "interpose" object used to monitor stat calls
+/// invoked by FileManager while processing the original sources used
+/// as input to PTH generation.  StatListener populates the PTHWriter's
+/// file map with stat information for directories as well as negative stats.
+/// Stat information for files are populated elsewhere.
+class StatListener : public StatSysCallCache {
+  PTHMap &PM;
+public:
+  StatListener(PTHMap &pm) : PM(pm) {}
+  ~StatListener() {}
+
+  int stat(const char *path, struct stat *buf) {
+    int result = StatSysCallCache::stat(path, buf);
+
+    if (result != 0) // Failed 'stat'.
+      PM.insert(PTHEntryKeyVariant(path), PTHEntry());
+    else if (S_ISDIR(buf->st_mode)) {
+      // Only cache directories with absolute paths.
+      if (!llvm::sys::Path(path).isAbsolute())
+        return result;
+
+      PM.insert(PTHEntryKeyVariant(buf, path), PTHEntry());
+    }
+
+    return result;
+  }
+};
+} // end anonymous namespace
+
+
+void clang::CacheTokens(Preprocessor &PP, llvm::raw_fd_ostream* OS) {
+  // Get the name of the main file.
+  const SourceManager &SrcMgr = PP.getSourceManager();
+  const FileEntry *MainFile = SrcMgr.getFileEntryForID(SrcMgr.getMainFileID());
+  llvm::sys::Path MainFilePath(MainFile->getName());
+
+  MainFilePath.makeAbsolute();
+
+  // Create the PTHWriter.
+  PTHWriter PW(*OS, PP);
+
+  // Install the 'stat' system call listener in the FileManager.
+  StatListener *StatCache = new StatListener(PW.getPM());
+  PP.getFileManager().addStatCache(StatCache, /*AtBeginning=*/true);
+
+  // Lex through the entire file.  This will populate SourceManager with
+  // all of the header information.
+  Token Tok;
+  PP.EnterMainSourceFile();
+  do { PP.Lex(Tok); } while (Tok.isNot(tok::eof));
+
+  // Generate the PTH file.
+  PP.getFileManager().removeStatCache(StatCache);
+  PW.GeneratePTH(MainFilePath.str());
+}
+
+//===----------------------------------------------------------------------===//
+
+namespace {
+class PTHIdKey {
+public:
+  const IdentifierInfo* II;
+  uint32_t FileOffset;
+};
+
+class PTHIdentifierTableTrait {
+public:
+  typedef PTHIdKey* key_type;
+  typedef key_type  key_type_ref;
+
+  typedef uint32_t  data_type;
+  typedef data_type data_type_ref;
+
+  static unsigned ComputeHash(PTHIdKey* key) {
+    return llvm::HashString(key->II->getName());
+  }
+
+  static std::pair<unsigned,unsigned>
+  EmitKeyDataLength(llvm::raw_ostream& Out, const PTHIdKey* key, uint32_t) {
+    unsigned n = key->II->getLength() + 1;
+    ::Emit16(Out, n);
+    return std::make_pair(n, sizeof(uint32_t));
+  }
+
+  static void EmitKey(llvm::raw_ostream& Out, PTHIdKey* key, unsigned n) {
+    // Record the location of the key data.  This is used when generating
+    // the mapping from persistent IDs to strings.
+    key->FileOffset = Out.tell();
+    Out.write(key->II->getNameStart(), n);
+  }
+
+  static void EmitData(llvm::raw_ostream& Out, PTHIdKey*, uint32_t pID,
+                       unsigned) {
+    ::Emit32(Out, pID);
+  }
+};
+} // end anonymous namespace
+
+/// EmitIdentifierTable - Emits two tables to the PTH file.  The first is
+///  a hashtable mapping from identifier strings to persistent IDs.  The second
+///  is a straight table mapping from persistent IDs to string data (the
+///  keys of the first table).
+///
+std::pair<Offset,Offset> PTHWriter::EmitIdentifierTable() {
+  // Build two maps:
+  //  (1) an inverse map from persistent IDs -> (IdentifierInfo*,Offset)
+  //  (2) a map from (IdentifierInfo*, Offset)* -> persistent IDs
+
+  // Note that we use 'calloc', so all the bytes are 0.
+  PTHIdKey *IIDMap = (PTHIdKey*)calloc(idcount, sizeof(PTHIdKey));
+
+  // Create the hashtable.
+  OnDiskChainedHashTableGenerator<PTHIdentifierTableTrait> IIOffMap;
+
+  // Generate mapping from persistent IDs -> IdentifierInfo*.
+  for (IDMap::iterator I = IM.begin(), E = IM.end(); I != E; ++I) {
+    // Decrement by 1 because we are using a vector for the lookup and
+    // 0 is reserved for NULL.
+    assert(I->second > 0);
+    assert(I->second-1 < idcount);
+    unsigned idx = I->second-1;
+
+    // Store the mapping from persistent ID to IdentifierInfo*
+    IIDMap[idx].II = I->first;
+
+    // Store the reverse mapping in a hashtable.
+    IIOffMap.insert(&IIDMap[idx], I->second);
+  }
+
+  // Write out the inverse map first.  This causes the PCIDKey entries to
+  // record PTH file offsets for the string data.  This is used to write
+  // the second table.
+  Offset StringTableOffset = IIOffMap.Emit(Out);
+
+  // Now emit the table mapping from persistent IDs to PTH file offsets.
+  Offset IDOff = Out.tell();
+  Emit32(idcount);  // Emit the number of identifiers.
+  for (unsigned i = 0 ; i < idcount; ++i)
+    Emit32(IIDMap[i].FileOffset);
+
+  // Finally, release the inverse map.
+  free(IIDMap);
+
+  return std::make_pair(IDOff, StringTableOffset);
+}
diff --git a/lib/Frontend/CodeGenAction.cpp b/lib/Frontend/CodeGenAction.cpp
new file mode 100644
index 0000000..80b0038
--- /dev/null
+++ b/lib/Frontend/CodeGenAction.cpp
@@ -0,0 +1,590 @@
+//===--- CodeGenAction.cpp - LLVM Code Generation Frontend Action ---------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/CodeGenAction.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/TargetInfo.h"
+#include "clang/Basic/TargetOptions.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclGroup.h"
+#include "clang/CodeGen/CodeGenOptions.h"
+#include "clang/CodeGen/ModuleBuilder.h"
+#include "clang/Frontend/ASTConsumers.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Frontend/FrontendDiagnostic.h"
+#include "llvm/LLVMContext.h"
+#include "llvm/Module.h"
+#include "llvm/PassManager.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/Assembly/PrintModulePass.h"
+#include "llvm/Analysis/CallGraph.h"
+#include "llvm/Analysis/Verifier.h"
+#include "llvm/Bitcode/ReaderWriter.h"
+#include "llvm/CodeGen/RegAllocRegistry.h"
+#include "llvm/CodeGen/SchedulerRegistry.h"
+#include "llvm/Support/FormattedStream.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/StandardPasses.h"
+#include "llvm/Support/Timer.h"
+#include "llvm/Target/SubtargetFeature.h"
+#include "llvm/Target/TargetData.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetOptions.h"
+#include "llvm/Target/TargetRegistry.h"
+using namespace clang;
+using namespace llvm;
+
+namespace {
+  enum BackendAction {
+    Backend_EmitAssembly,  ///< Emit native assembly files
+    Backend_EmitBC,        ///< Emit LLVM bitcode files
+    Backend_EmitLL,        ///< Emit human-readable LLVM assembly
+    Backend_EmitNothing,   ///< Don't emit anything (benchmarking mode)
+    Backend_EmitObj        ///< Emit native object files
+  };
+
+  class BackendConsumer : public ASTConsumer {
+    Diagnostic &Diags;
+    BackendAction Action;
+    const CodeGenOptions &CodeGenOpts;
+    const LangOptions &LangOpts;
+    const TargetOptions &TargetOpts;
+    llvm::raw_ostream *AsmOutStream;
+    llvm::formatted_raw_ostream FormattedOutStream;
+    ASTContext *Context;
+
+    Timer LLVMIRGeneration;
+    Timer CodeGenerationTime;
+
+    llvm::OwningPtr<CodeGenerator> Gen;
+
+    llvm::OwningPtr<llvm::Module> TheModule;
+    llvm::TargetData *TheTargetData;
+
+    mutable FunctionPassManager *CodeGenPasses;
+    mutable PassManager *PerModulePasses;
+    mutable FunctionPassManager *PerFunctionPasses;
+
+    FunctionPassManager *getCodeGenPasses() const;
+    PassManager *getPerModulePasses() const;
+    FunctionPassManager *getPerFunctionPasses() const;
+
+    void CreatePasses();
+
+    /// AddEmitPasses - Add passes necessary to emit assembly or LLVM IR.
+    ///
+    /// \return True on success.
+    bool AddEmitPasses();
+
+    void EmitAssembly();
+
+  public:
+    BackendConsumer(BackendAction action, Diagnostic &_Diags,
+                    const LangOptions &langopts, const CodeGenOptions &compopts,
+                    const TargetOptions &targetopts, bool TimePasses,
+                    const std::string &infile, llvm::raw_ostream *OS,
+                    LLVMContext &C) :
+      Diags(_Diags),
+      Action(action),
+      CodeGenOpts(compopts),
+      LangOpts(langopts),
+      TargetOpts(targetopts),
+      AsmOutStream(OS),
+      LLVMIRGeneration("LLVM IR Generation Time"),
+      CodeGenerationTime("Code Generation Time"),
+      Gen(CreateLLVMCodeGen(Diags, infile, compopts, C)),
+      TheTargetData(0),
+      CodeGenPasses(0), PerModulePasses(0), PerFunctionPasses(0) {
+
+      if (AsmOutStream)
+        FormattedOutStream.setStream(*AsmOutStream,
+                                     formatted_raw_ostream::PRESERVE_STREAM);
+
+      llvm::TimePassesIsEnabled = TimePasses;
+    }
+
+    ~BackendConsumer() {
+      delete TheTargetData;
+      delete CodeGenPasses;
+      delete PerModulePasses;
+      delete PerFunctionPasses;
+    }
+
+    llvm::Module *takeModule() { return TheModule.take(); }
+
+    virtual void Initialize(ASTContext &Ctx) {
+      Context = &Ctx;
+
+      if (llvm::TimePassesIsEnabled)
+        LLVMIRGeneration.startTimer();
+
+      Gen->Initialize(Ctx);
+
+      TheModule.reset(Gen->GetModule());
+      TheTargetData = new llvm::TargetData(Ctx.Target.getTargetDescription());
+
+      if (llvm::TimePassesIsEnabled)
+        LLVMIRGeneration.stopTimer();
+    }
+
+    virtual void HandleTopLevelDecl(DeclGroupRef D) {
+      PrettyStackTraceDecl CrashInfo(*D.begin(), SourceLocation(),
+                                     Context->getSourceManager(),
+                                     "LLVM IR generation of declaration");
+
+      if (llvm::TimePassesIsEnabled)
+        LLVMIRGeneration.startTimer();
+
+      Gen->HandleTopLevelDecl(D);
+
+      if (llvm::TimePassesIsEnabled)
+        LLVMIRGeneration.stopTimer();
+    }
+
+    virtual void HandleTranslationUnit(ASTContext &C) {
+      {
+        PrettyStackTraceString CrashInfo("Per-file LLVM IR generation");
+        if (llvm::TimePassesIsEnabled)
+          LLVMIRGeneration.startTimer();
+
+        Gen->HandleTranslationUnit(C);
+
+        if (llvm::TimePassesIsEnabled)
+          LLVMIRGeneration.stopTimer();
+      }
+
+      // EmitAssembly times and registers crash info itself.
+      EmitAssembly();
+
+      // Force a flush here in case we never get released.
+      if (AsmOutStream)
+        FormattedOutStream.flush();
+    }
+
+    virtual void HandleTagDeclDefinition(TagDecl *D) {
+      PrettyStackTraceDecl CrashInfo(D, SourceLocation(),
+                                     Context->getSourceManager(),
+                                     "LLVM IR generation of declaration");
+      Gen->HandleTagDeclDefinition(D);
+    }
+
+    virtual void CompleteTentativeDefinition(VarDecl *D) {
+      Gen->CompleteTentativeDefinition(D);
+    }
+    
+    static void InlineAsmDiagHandler(const llvm::SMDiagnostic &SM,void *Context,
+                                     unsigned LocCookie) {
+      SourceLocation Loc = SourceLocation::getFromRawEncoding(LocCookie);
+      ((BackendConsumer*)Context)->InlineAsmDiagHandler2(SM, Loc);
+    }
+    
+    void InlineAsmDiagHandler2(const llvm::SMDiagnostic &,
+                               SourceLocation LocCookie);
+  };
+}
+
+FunctionPassManager *BackendConsumer::getCodeGenPasses() const {
+  if (!CodeGenPasses) {
+    CodeGenPasses = new FunctionPassManager(&*TheModule);
+    CodeGenPasses->add(new TargetData(*TheTargetData));
+  }
+
+  return CodeGenPasses;
+}
+
+PassManager *BackendConsumer::getPerModulePasses() const {
+  if (!PerModulePasses) {
+    PerModulePasses = new PassManager();
+    PerModulePasses->add(new TargetData(*TheTargetData));
+  }
+
+  return PerModulePasses;
+}
+
+FunctionPassManager *BackendConsumer::getPerFunctionPasses() const {
+  if (!PerFunctionPasses) {
+    PerFunctionPasses = new FunctionPassManager(&*TheModule);
+    PerFunctionPasses->add(new TargetData(*TheTargetData));
+  }
+
+  return PerFunctionPasses;
+}
+
+bool BackendConsumer::AddEmitPasses() {
+  if (Action == Backend_EmitNothing)
+    return true;
+
+  if (Action == Backend_EmitBC) {
+    getPerModulePasses()->add(createBitcodeWriterPass(FormattedOutStream));
+    return true;
+  }
+  
+  if (Action == Backend_EmitLL) {
+    getPerModulePasses()->add(createPrintModulePass(&FormattedOutStream));
+    return true;
+  }
+  
+  bool Fast = CodeGenOpts.OptimizationLevel == 0;
+
+  // Create the TargetMachine for generating code.
+  std::string Error;
+  std::string Triple = TheModule->getTargetTriple();
+  const llvm::Target *TheTarget = TargetRegistry::lookupTarget(Triple, Error);
+  if (!TheTarget) {
+    Diags.Report(diag::err_fe_unable_to_create_target) << Error;
+    return false;
+  }
+
+  // FIXME: Expose these capabilities via actual APIs!!!! Aside from just
+  // being gross, this is also totally broken if we ever care about
+  // concurrency.
+  llvm::NoFramePointerElim = CodeGenOpts.DisableFPElim;
+  if (CodeGenOpts.FloatABI == "soft")
+    llvm::FloatABIType = llvm::FloatABI::Soft;
+  else if (CodeGenOpts.FloatABI == "hard")
+    llvm::FloatABIType = llvm::FloatABI::Hard;
+  else {
+    assert(CodeGenOpts.FloatABI.empty() && "Invalid float abi!");
+    llvm::FloatABIType = llvm::FloatABI::Default;
+  }
+  NoZerosInBSS = CodeGenOpts.NoZeroInitializedInBSS;
+  llvm::UseSoftFloat = CodeGenOpts.SoftFloat;
+  UnwindTablesMandatory = CodeGenOpts.UnwindTables;
+
+  TargetMachine::setAsmVerbosityDefault(CodeGenOpts.AsmVerbose);
+
+  TargetMachine::setFunctionSections(CodeGenOpts.FunctionSections);
+  TargetMachine::setDataSections    (CodeGenOpts.DataSections);
+
+  // FIXME: Parse this earlier.
+  if (CodeGenOpts.RelocationModel == "static") {
+    TargetMachine::setRelocationModel(llvm::Reloc::Static);
+  } else if (CodeGenOpts.RelocationModel == "pic") {
+    TargetMachine::setRelocationModel(llvm::Reloc::PIC_);
+  } else {
+    assert(CodeGenOpts.RelocationModel == "dynamic-no-pic" &&
+           "Invalid PIC model!");
+    TargetMachine::setRelocationModel(llvm::Reloc::DynamicNoPIC);
+  }
+  // FIXME: Parse this earlier.
+  if (CodeGenOpts.CodeModel == "small") {
+    TargetMachine::setCodeModel(llvm::CodeModel::Small);
+  } else if (CodeGenOpts.CodeModel == "kernel") {
+    TargetMachine::setCodeModel(llvm::CodeModel::Kernel);
+  } else if (CodeGenOpts.CodeModel == "medium") {
+    TargetMachine::setCodeModel(llvm::CodeModel::Medium);
+  } else if (CodeGenOpts.CodeModel == "large") {
+    TargetMachine::setCodeModel(llvm::CodeModel::Large);
+  } else {
+    assert(CodeGenOpts.CodeModel.empty() && "Invalid code model!");
+    TargetMachine::setCodeModel(llvm::CodeModel::Default);
+  }
+
+  std::vector<const char *> BackendArgs;
+  BackendArgs.push_back("clang"); // Fake program name.
+  if (!CodeGenOpts.DebugPass.empty()) {
+    BackendArgs.push_back("-debug-pass");
+    BackendArgs.push_back(CodeGenOpts.DebugPass.c_str());
+  }
+  if (!CodeGenOpts.LimitFloatPrecision.empty()) {
+    BackendArgs.push_back("-limit-float-precision");
+    BackendArgs.push_back(CodeGenOpts.LimitFloatPrecision.c_str());
+  }
+  if (llvm::TimePassesIsEnabled)
+    BackendArgs.push_back("-time-passes");
+  BackendArgs.push_back(0);
+  llvm::cl::ParseCommandLineOptions(BackendArgs.size() - 1,
+                                    const_cast<char **>(&BackendArgs[0]));
+
+  std::string FeaturesStr;
+  if (TargetOpts.CPU.size() || TargetOpts.Features.size()) {
+    SubtargetFeatures Features;
+    Features.setCPU(TargetOpts.CPU);
+    for (std::vector<std::string>::const_iterator
+           it = TargetOpts.Features.begin(),
+           ie = TargetOpts.Features.end(); it != ie; ++it)
+      Features.AddFeature(*it);
+    FeaturesStr = Features.getString();
+  }
+  TargetMachine *TM = TheTarget->createTargetMachine(Triple, FeaturesStr);
+
+  // Set register scheduler & allocation policy.
+  RegisterScheduler::setDefault(createDefaultScheduler);
+  RegisterRegAlloc::setDefault(Fast ? createLocalRegisterAllocator :
+                               createLinearScanRegisterAllocator);
+
+  // From llvm-gcc:
+  // If there are passes we have to run on the entire module, we do codegen
+  // as a separate "pass" after that happens.
+  // FIXME: This is disabled right now until bugs can be worked out.  Reenable
+  // this for fast -O0 compiles!
+  FunctionPassManager *PM = getCodeGenPasses();
+  CodeGenOpt::Level OptLevel = CodeGenOpt::Default;
+
+  switch (CodeGenOpts.OptimizationLevel) {
+  default: break;
+  case 0: OptLevel = CodeGenOpt::None; break;
+  case 3: OptLevel = CodeGenOpt::Aggressive; break;
+  }
+
+  // Request that addPassesToEmitFile run the Verifier after running
+  // passes which modify the IR.
+#ifndef NDEBUG
+  bool DisableVerify = false;
+#else
+  bool DisableVerify = true;
+#endif
+
+  // Normal mode, emit a .s or .o file by running the code generator. Note,
+  // this also adds codegenerator level optimization passes.
+  TargetMachine::CodeGenFileType CGFT = TargetMachine::CGFT_AssemblyFile;
+  if (Action == Backend_EmitObj)
+    CGFT = TargetMachine::CGFT_ObjectFile;
+  if (TM->addPassesToEmitFile(*PM, FormattedOutStream, CGFT, OptLevel,
+                              DisableVerify)) {
+    Diags.Report(diag::err_fe_unable_to_interface_with_target);
+    return false;
+  }
+
+  return true;
+}
+
+void BackendConsumer::CreatePasses() {
+  unsigned OptLevel = CodeGenOpts.OptimizationLevel;
+  CodeGenOptions::InliningMethod Inlining = CodeGenOpts.Inlining;
+
+  // Handle disabling of LLVM optimization, where we want to preserve the
+  // internal module before any optimization.
+  if (CodeGenOpts.DisableLLVMOpts) {
+    OptLevel = 0;
+    Inlining = CodeGenOpts.NoInlining;
+  }
+
+  // In -O0 if checking is disabled, we don't even have per-function passes.
+  if (CodeGenOpts.VerifyModule)
+    getPerFunctionPasses()->add(createVerifierPass());
+
+  // Assume that standard function passes aren't run for -O0.
+  if (OptLevel > 0)
+    llvm::createStandardFunctionPasses(getPerFunctionPasses(), OptLevel);
+
+  llvm::Pass *InliningPass = 0;
+  switch (Inlining) {
+  case CodeGenOptions::NoInlining: break;
+  case CodeGenOptions::NormalInlining: {
+    // Set the inline threshold following llvm-gcc.
+    //
+    // FIXME: Derive these constants in a principled fashion.
+    unsigned Threshold = 225;
+    if (CodeGenOpts.OptimizeSize)
+      Threshold = 75;
+    else if (OptLevel > 2)
+      Threshold = 275;
+    InliningPass = createFunctionInliningPass(Threshold);
+    break;
+  }
+  case CodeGenOptions::OnlyAlwaysInlining:
+    InliningPass = createAlwaysInlinerPass();         // Respect always_inline
+    break;
+  }
+
+  // For now we always create per module passes.
+  PassManager *PM = getPerModulePasses();
+  llvm::createStandardModulePasses(PM, OptLevel, CodeGenOpts.OptimizeSize,
+                                   CodeGenOpts.UnitAtATime,
+                                   CodeGenOpts.UnrollLoops,
+                                   /*SimplifyLibCalls=*/!LangOpts.NoBuiltin,
+                                   /*HaveExceptions=*/true,
+                                   InliningPass);
+}
+
+/// EmitAssembly - Handle interaction with LLVM backend to generate
+/// actual machine code.
+void BackendConsumer::EmitAssembly() {
+  // Silently ignore if we weren't initialized for some reason.
+  if (!TheModule || !TheTargetData)
+    return;
+
+  TimeRegion Region(llvm::TimePassesIsEnabled ? &CodeGenerationTime : 0);
+
+  // Make sure IR generation is happy with the module. This is
+  // released by the module provider.
+  Module *M = Gen->ReleaseModule();
+  if (!M) {
+    // The module has been released by IR gen on failures, do not
+    // double free.
+    TheModule.take();
+    return;
+  }
+
+  assert(TheModule.get() == M &&
+         "Unexpected module change during IR generation");
+
+  CreatePasses();
+  if (!AddEmitPasses())
+    return;
+
+  // Run passes. For now we do all passes at once, but eventually we
+  // would like to have the option of streaming code generation.
+
+  if (PerFunctionPasses) {
+    PrettyStackTraceString CrashInfo("Per-function optimization");
+
+    PerFunctionPasses->doInitialization();
+    for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
+      if (!I->isDeclaration())
+        PerFunctionPasses->run(*I);
+    PerFunctionPasses->doFinalization();
+  }
+
+  if (PerModulePasses) {
+    PrettyStackTraceString CrashInfo("Per-module optimization passes");
+    PerModulePasses->run(*M);
+  }
+
+  if (CodeGenPasses) {
+    PrettyStackTraceString CrashInfo("Code generation");
+    
+    // Install an inline asm handler so that diagnostics get printed through our
+    // diagnostics hooks.
+    LLVMContext &Ctx = TheModule->getContext();
+    void *OldHandler = Ctx.getInlineAsmDiagnosticHandler();
+    void *OldContext = Ctx.getInlineAsmDiagnosticContext();
+    Ctx.setInlineAsmDiagnosticHandler((void*)(intptr_t)InlineAsmDiagHandler,
+                                      this);
+    
+    CodeGenPasses->doInitialization();
+    for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
+      if (!I->isDeclaration())
+        CodeGenPasses->run(*I);
+    CodeGenPasses->doFinalization();
+    
+    Ctx.setInlineAsmDiagnosticHandler(OldHandler, OldContext);
+  }
+}
+
+/// ConvertBackendLocation - Convert a location in a temporary llvm::SourceMgr
+/// buffer to be a valid FullSourceLoc.
+static FullSourceLoc ConvertBackendLocation(const llvm::SMDiagnostic &D,
+                                            SourceManager &CSM) {
+  // Get both the clang and llvm source managers.  The location is relative to
+  // a memory buffer that the LLVM Source Manager is handling, we need to add
+  // a copy to the Clang source manager. 
+  const llvm::SourceMgr &LSM = *D.getSourceMgr();
+  
+  // We need to copy the underlying LLVM memory buffer because llvm::SourceMgr
+  // already owns its one and clang::SourceManager wants to own its one.
+  const MemoryBuffer *LBuf =
+  LSM.getMemoryBuffer(LSM.FindBufferContainingLoc(D.getLoc()));
+  
+  // Create the copy and transfer ownership to clang::SourceManager.
+  llvm::MemoryBuffer *CBuf =
+  llvm::MemoryBuffer::getMemBufferCopy(LBuf->getBuffer(),
+                                       LBuf->getBufferIdentifier());
+  FileID FID = CSM.createFileIDForMemBuffer(CBuf);
+  
+  // Translate the offset into the file.
+  unsigned Offset = D.getLoc().getPointer()  - LBuf->getBufferStart();
+  SourceLocation NewLoc = 
+  CSM.getLocForStartOfFile(FID).getFileLocWithOffset(Offset);
+  return FullSourceLoc(NewLoc, CSM);
+}
+
+
+/// InlineAsmDiagHandler2 - This function is invoked when the backend hits an
+/// error parsing inline asm.  The SMDiagnostic indicates the error relative to
+/// the temporary memory buffer that the inline asm parser has set up.  
+void BackendConsumer::InlineAsmDiagHandler2(const llvm::SMDiagnostic &D,
+                                            SourceLocation LocCookie) {
+  // There are a couple of different kinds of errors we could get here.  First,
+  // we re-format the SMDiagnostic in terms of a clang diagnostic.
+  
+  // Strip "error: " off the start of the message string.
+  llvm::StringRef Message = D.getMessage();
+  if (Message.startswith("error: "))
+    Message = Message.substr(7);
+
+  // There are two cases: the SMDiagnostic could have a inline asm source
+  // location or it might not.  If it does, translate the location.
+  FullSourceLoc Loc;
+  if (D.getLoc() != SMLoc())
+    Loc = ConvertBackendLocation(D, Context->getSourceManager());
+  Diags.Report(Loc, diag::err_fe_inline_asm).AddString(Message);
+  
+  // This could be a problem with no clang-level source location information.
+  // In this case, LocCookie is invalid.  If there is source level information,
+  // print an "generated from" note.
+  if (LocCookie.isValid())
+    Diags.Report(FullSourceLoc(LocCookie, Context->getSourceManager()),
+                 diag::note_fe_inline_asm_here);
+}
+
+//
+
+CodeGenAction::CodeGenAction(unsigned _Act) : Act(_Act) {}
+
+CodeGenAction::~CodeGenAction() {}
+
+void CodeGenAction::EndSourceFileAction() {
+  // If the consumer creation failed, do nothing.
+  if (!getCompilerInstance().hasASTConsumer())
+    return;
+
+  // Steal the module from the consumer.
+  BackendConsumer *Consumer = static_cast<BackendConsumer*>(
+    &getCompilerInstance().getASTConsumer());
+
+  TheModule.reset(Consumer->takeModule());
+}
+
+llvm::Module *CodeGenAction::takeModule() {
+  return TheModule.take();
+}
+
+ASTConsumer *CodeGenAction::CreateASTConsumer(CompilerInstance &CI,
+                                              llvm::StringRef InFile) {
+  BackendAction BA = static_cast<BackendAction>(Act);
+  llvm::OwningPtr<llvm::raw_ostream> OS;
+  switch (BA) {
+  case Backend_EmitAssembly:
+    OS.reset(CI.createDefaultOutputFile(false, InFile, "s"));
+    break;
+  case Backend_EmitLL:
+    OS.reset(CI.createDefaultOutputFile(false, InFile, "ll"));
+    break;
+  case Backend_EmitBC:
+    OS.reset(CI.createDefaultOutputFile(true, InFile, "bc"));
+    break;
+  case Backend_EmitNothing:
+    break;
+  case Backend_EmitObj:
+    OS.reset(CI.createDefaultOutputFile(true, InFile, "o"));
+    break;
+  }
+  if (BA != Backend_EmitNothing && !OS)
+    return 0;
+
+  return new BackendConsumer(BA, CI.getDiagnostics(), CI.getLangOpts(),
+                             CI.getCodeGenOpts(), CI.getTargetOpts(),
+                             CI.getFrontendOpts().ShowTimers, InFile, OS.take(),
+                             CI.getLLVMContext());
+}
+
+EmitAssemblyAction::EmitAssemblyAction()
+  : CodeGenAction(Backend_EmitAssembly) {}
+
+EmitBCAction::EmitBCAction() : CodeGenAction(Backend_EmitBC) {}
+
+EmitLLVMAction::EmitLLVMAction() : CodeGenAction(Backend_EmitLL) {}
+
+EmitLLVMOnlyAction::EmitLLVMOnlyAction() : CodeGenAction(Backend_EmitNothing) {}
+
+EmitObjAction::EmitObjAction() : CodeGenAction(Backend_EmitObj) {}
diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp
new file mode 100644
index 0000000..5ed9c40
--- /dev/null
+++ b/lib/Frontend/CompilerInstance.cpp
@@ -0,0 +1,547 @@
+//===--- CompilerInstance.cpp ---------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/TargetInfo.h"
+#include "clang/Basic/Version.h"
+#include "clang/Lex/HeaderSearch.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Lex/PTHManager.h"
+#include "clang/Frontend/ChainedDiagnosticClient.h"
+#include "clang/Frontend/FrontendAction.h"
+#include "clang/Frontend/PCHReader.h"
+#include "clang/Frontend/FrontendDiagnostic.h"
+#include "clang/Frontend/TextDiagnosticPrinter.h"
+#include "clang/Frontend/VerifyDiagnosticsClient.h"
+#include "clang/Frontend/Utils.h"
+#include "clang/Sema/CodeCompleteConsumer.h"
+#include "llvm/LLVMContext.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/Support/Timer.h"
+#include "llvm/System/Host.h"
+#include "llvm/System/Path.h"
+#include "llvm/System/Program.h"
+using namespace clang;
+
+CompilerInstance::CompilerInstance()
+  : Invocation(new CompilerInvocation()) {
+}
+
+CompilerInstance::~CompilerInstance() {
+}
+
+void CompilerInstance::setLLVMContext(llvm::LLVMContext *Value) {
+  LLVMContext.reset(Value);
+}
+
+void CompilerInstance::setInvocation(CompilerInvocation *Value) {
+  Invocation.reset(Value);
+}
+
+void CompilerInstance::setDiagnostics(Diagnostic *Value) {
+  Diagnostics = Value;
+}
+
+void CompilerInstance::setDiagnosticClient(DiagnosticClient *Value) {
+  DiagClient.reset(Value);
+}
+
+void CompilerInstance::setTarget(TargetInfo *Value) {
+  Target.reset(Value);
+}
+
+void CompilerInstance::setFileManager(FileManager *Value) {
+  FileMgr.reset(Value);
+}
+
+void CompilerInstance::setSourceManager(SourceManager *Value) {
+  SourceMgr.reset(Value);
+}
+
+void CompilerInstance::setPreprocessor(Preprocessor *Value) {
+  PP.reset(Value);
+}
+
+void CompilerInstance::setASTContext(ASTContext *Value) {
+  Context.reset(Value);
+}
+
+void CompilerInstance::setASTConsumer(ASTConsumer *Value) {
+  Consumer.reset(Value);
+}
+
+void CompilerInstance::setCodeCompletionConsumer(CodeCompleteConsumer *Value) {
+  CompletionConsumer.reset(Value);
+}
+
+// Diagnostics
+namespace {
+  class BinaryDiagnosticSerializer : public DiagnosticClient {
+    llvm::raw_ostream &OS;
+    SourceManager *SourceMgr;
+  public:
+    explicit BinaryDiagnosticSerializer(llvm::raw_ostream &OS)
+      : OS(OS), SourceMgr(0) { }
+
+    virtual void HandleDiagnostic(Diagnostic::Level DiagLevel,
+                                  const DiagnosticInfo &Info);
+  };
+}
+
+void BinaryDiagnosticSerializer::HandleDiagnostic(Diagnostic::Level DiagLevel,
+                                                  const DiagnosticInfo &Info) {
+  StoredDiagnostic(DiagLevel, Info).Serialize(OS);
+}
+
+static void SetUpBuildDumpLog(const DiagnosticOptions &DiagOpts,
+                              unsigned argc, char **argv,
+                              Diagnostic &Diags) {
+  std::string ErrorInfo;
+  llvm::OwningPtr<llvm::raw_ostream> OS(
+    new llvm::raw_fd_ostream(DiagOpts.DumpBuildInformation.c_str(), ErrorInfo));
+  if (!ErrorInfo.empty()) {
+    Diags.Report(diag::err_fe_unable_to_open_logfile)
+                 << DiagOpts.DumpBuildInformation << ErrorInfo;
+    return;
+  }
+
+  (*OS) << "clang -cc1 command line arguments: ";
+  for (unsigned i = 0; i != argc; ++i)
+    (*OS) << argv[i] << ' ';
+  (*OS) << '\n';
+
+  // Chain in a diagnostic client which will log the diagnostics.
+  DiagnosticClient *Logger =
+    new TextDiagnosticPrinter(*OS.take(), DiagOpts, /*OwnsOutputStream=*/true);
+  Diags.setClient(new ChainedDiagnosticClient(Diags.getClient(), Logger));
+}
+
+void CompilerInstance::createDiagnostics(int Argc, char **Argv) {
+  Diagnostics = createDiagnostics(getDiagnosticOpts(), Argc, Argv);
+
+  if (Diagnostics)
+    DiagClient.reset(Diagnostics->getClient());
+}
+
+llvm::IntrusiveRefCntPtr<Diagnostic> 
+CompilerInstance::createDiagnostics(const DiagnosticOptions &Opts,
+                                    int Argc, char **Argv) {
+  llvm::IntrusiveRefCntPtr<Diagnostic> Diags(new Diagnostic());
+
+  // Create the diagnostic client for reporting errors or for
+  // implementing -verify.
+  llvm::OwningPtr<DiagnosticClient> DiagClient;
+  if (Opts.BinaryOutput) {
+    if (llvm::sys::Program::ChangeStderrToBinary()) {
+      // We weren't able to set standard error to binary, which is a
+      // bit of a problem. So, just create a text diagnostic printer
+      // to complain about this problem, and pretend that the user
+      // didn't try to use binary output.
+      DiagClient.reset(new TextDiagnosticPrinter(llvm::errs(), Opts));
+      Diags->setClient(DiagClient.take());
+      Diags->Report(diag::err_fe_stderr_binary);
+      return Diags;
+    } else {
+      DiagClient.reset(new BinaryDiagnosticSerializer(llvm::errs()));
+    }
+  } else {
+    DiagClient.reset(new TextDiagnosticPrinter(llvm::errs(), Opts));
+  }
+
+  // Chain in -verify checker, if requested.
+  if (Opts.VerifyDiagnostics)
+    DiagClient.reset(new VerifyDiagnosticsClient(*Diags, DiagClient.take()));
+
+  Diags->setClient(DiagClient.take());
+  if (!Opts.DumpBuildInformation.empty())
+    SetUpBuildDumpLog(Opts, Argc, Argv, *Diags);
+
+  // Configure our handling of diagnostics.
+  ProcessWarningOptions(*Diags, Opts);
+
+  return Diags;
+}
+
+// File Manager
+
+void CompilerInstance::createFileManager() {
+  FileMgr.reset(new FileManager());
+}
+
+// Source Manager
+
+void CompilerInstance::createSourceManager() {
+  SourceMgr.reset(new SourceManager(getDiagnostics()));
+}
+
+// Preprocessor
+
+void CompilerInstance::createPreprocessor() {
+  PP.reset(createPreprocessor(getDiagnostics(), getLangOpts(),
+                              getPreprocessorOpts(), getHeaderSearchOpts(),
+                              getDependencyOutputOpts(), getTarget(),
+                              getFrontendOpts(), getSourceManager(),
+                              getFileManager()));
+}
+
+Preprocessor *
+CompilerInstance::createPreprocessor(Diagnostic &Diags,
+                                     const LangOptions &LangInfo,
+                                     const PreprocessorOptions &PPOpts,
+                                     const HeaderSearchOptions &HSOpts,
+                                     const DependencyOutputOptions &DepOpts,
+                                     const TargetInfo &Target,
+                                     const FrontendOptions &FEOpts,
+                                     SourceManager &SourceMgr,
+                                     FileManager &FileMgr) {
+  // Create a PTH manager if we are using some form of a token cache.
+  PTHManager *PTHMgr = 0;
+  if (!PPOpts.TokenCache.empty())
+    PTHMgr = PTHManager::Create(PPOpts.TokenCache, Diags);
+
+  // Create the Preprocessor.
+  HeaderSearch *HeaderInfo = new HeaderSearch(FileMgr);
+  Preprocessor *PP = new Preprocessor(Diags, LangInfo, Target,
+                                      SourceMgr, *HeaderInfo, PTHMgr,
+                                      /*OwnsHeaderSearch=*/true);
+
+  // Note that this is different then passing PTHMgr to Preprocessor's ctor.
+  // That argument is used as the IdentifierInfoLookup argument to
+  // IdentifierTable's ctor.
+  if (PTHMgr) {
+    PTHMgr->setPreprocessor(PP);
+    PP->setPTHManager(PTHMgr);
+  }
+
+  if (PPOpts.DetailedRecord)
+    PP->createPreprocessingRecord();
+  
+  InitializePreprocessor(*PP, PPOpts, HSOpts, FEOpts);
+
+  // Handle generating dependencies, if requested.
+  if (!DepOpts.OutputFile.empty())
+    AttachDependencyFileGen(*PP, DepOpts);
+
+  return PP;
+}
+
+// ASTContext
+
+void CompilerInstance::createASTContext() {
+  Preprocessor &PP = getPreprocessor();
+  Context.reset(new ASTContext(getLangOpts(), PP.getSourceManager(),
+                               getTarget(), PP.getIdentifierTable(),
+                               PP.getSelectorTable(), PP.getBuiltinInfo(),
+                               /*FreeMemory=*/ !getFrontendOpts().DisableFree,
+                               /*size_reserve=*/ 0));
+}
+
+// ExternalASTSource
+
+void CompilerInstance::createPCHExternalASTSource(llvm::StringRef Path) {
+  llvm::OwningPtr<ExternalASTSource> Source;
+  Source.reset(createPCHExternalASTSource(Path, getHeaderSearchOpts().Sysroot,
+                                          getPreprocessor(), getASTContext()));
+  getASTContext().setExternalSource(Source);
+}
+
+ExternalASTSource *
+CompilerInstance::createPCHExternalASTSource(llvm::StringRef Path,
+                                             const std::string &Sysroot,
+                                             Preprocessor &PP,
+                                             ASTContext &Context) {
+  llvm::OwningPtr<PCHReader> Reader;
+  Reader.reset(new PCHReader(PP, &Context,
+                             Sysroot.empty() ? 0 : Sysroot.c_str()));
+
+  switch (Reader->ReadPCH(Path)) {
+  case PCHReader::Success:
+    // Set the predefines buffer as suggested by the PCH reader. Typically, the
+    // predefines buffer will be empty.
+    PP.setPredefines(Reader->getSuggestedPredefines());
+    return Reader.take();
+
+  case PCHReader::Failure:
+    // Unrecoverable failure: don't even try to process the input file.
+    break;
+
+  case PCHReader::IgnorePCH:
+    // No suitable PCH file could be found. Return an error.
+    break;
+  }
+
+  return 0;
+}
+
+// Code Completion
+
+void CompilerInstance::createCodeCompletionConsumer() {
+  const ParsedSourceLocation &Loc = getFrontendOpts().CodeCompletionAt;
+  CompletionConsumer.reset(
+    createCodeCompletionConsumer(getPreprocessor(),
+                                 Loc.FileName, Loc.Line, Loc.Column,
+                                 getFrontendOpts().DebugCodeCompletionPrinter,
+                                 getFrontendOpts().ShowMacrosInCodeCompletion,
+                                 llvm::outs()));
+  if (!CompletionConsumer)
+    return;
+
+  if (CompletionConsumer->isOutputBinary() &&
+      llvm::sys::Program::ChangeStdoutToBinary()) {
+    getPreprocessor().getDiagnostics().Report(diag::err_fe_stdout_binary);
+    CompletionConsumer.reset();
+  }
+}
+
+void CompilerInstance::createFrontendTimer() {
+  FrontendTimer.reset(new llvm::Timer("Clang front-end timer"));
+}
+
+CodeCompleteConsumer *
+CompilerInstance::createCodeCompletionConsumer(Preprocessor &PP,
+                                               const std::string &Filename,
+                                               unsigned Line,
+                                               unsigned Column,
+                                               bool UseDebugPrinter,
+                                               bool ShowMacros,
+                                               llvm::raw_ostream &OS) {
+  // Tell the source manager to chop off the given file at a specific
+  // line and column.
+  const FileEntry *Entry = PP.getFileManager().getFile(Filename);
+  if (!Entry) {
+    PP.getDiagnostics().Report(diag::err_fe_invalid_code_complete_file)
+      << Filename;
+    return 0;
+  }
+
+  // Truncate the named file at the given line/column.
+  PP.SetCodeCompletionPoint(Entry, Line, Column);
+
+  // Set up the creation routine for code-completion.
+  if (UseDebugPrinter)
+    return new PrintingCodeCompleteConsumer(ShowMacros, OS);
+  else
+    return new CIndexCodeCompleteConsumer(ShowMacros, OS);
+}
+
+// Output Files
+
+void CompilerInstance::addOutputFile(llvm::StringRef Path,
+                                     llvm::raw_ostream *OS) {
+  assert(OS && "Attempt to add empty stream to output list!");
+  OutputFiles.push_back(std::make_pair(Path, OS));
+}
+
+void CompilerInstance::clearOutputFiles(bool EraseFiles) {
+  for (std::list< std::pair<std::string, llvm::raw_ostream*> >::iterator
+         it = OutputFiles.begin(), ie = OutputFiles.end(); it != ie; ++it) {
+    delete it->second;
+    if (EraseFiles && !it->first.empty())
+      llvm::sys::Path(it->first).eraseFromDisk();
+  }
+  OutputFiles.clear();
+}
+
+llvm::raw_fd_ostream *
+CompilerInstance::createDefaultOutputFile(bool Binary,
+                                          llvm::StringRef InFile,
+                                          llvm::StringRef Extension) {
+  return createOutputFile(getFrontendOpts().OutputFile, Binary,
+                          InFile, Extension);
+}
+
+llvm::raw_fd_ostream *
+CompilerInstance::createOutputFile(llvm::StringRef OutputPath,
+                                   bool Binary,
+                                   llvm::StringRef InFile,
+                                   llvm::StringRef Extension) {
+  std::string Error, OutputPathName;
+  llvm::raw_fd_ostream *OS = createOutputFile(OutputPath, Error, Binary,
+                                              InFile, Extension,
+                                              &OutputPathName);
+  if (!OS) {
+    getDiagnostics().Report(diag::err_fe_unable_to_open_output)
+      << OutputPath << Error;
+    return 0;
+  }
+
+  // Add the output file -- but don't try to remove "-", since this means we are
+  // using stdin.
+  addOutputFile((OutputPathName != "-") ? OutputPathName : "", OS);
+
+  return OS;
+}
+
+llvm::raw_fd_ostream *
+CompilerInstance::createOutputFile(llvm::StringRef OutputPath,
+                                   std::string &Error,
+                                   bool Binary,
+                                   llvm::StringRef InFile,
+                                   llvm::StringRef Extension,
+                                   std::string *ResultPathName) {
+  std::string OutFile;
+  if (!OutputPath.empty()) {
+    OutFile = OutputPath;
+  } else if (InFile == "-") {
+    OutFile = "-";
+  } else if (!Extension.empty()) {
+    llvm::sys::Path Path(InFile);
+    Path.eraseSuffix();
+    Path.appendSuffix(Extension);
+    OutFile = Path.str();
+  } else {
+    OutFile = "-";
+  }
+
+  llvm::OwningPtr<llvm::raw_fd_ostream> OS(
+    new llvm::raw_fd_ostream(OutFile.c_str(), Error,
+                             (Binary ? llvm::raw_fd_ostream::F_Binary : 0)));
+  if (!Error.empty())
+    return 0;
+
+  if (ResultPathName)
+    *ResultPathName = OutFile;
+
+  return OS.take();
+}
+
+// Initialization Utilities
+
+bool CompilerInstance::InitializeSourceManager(llvm::StringRef InputFile) {
+  return InitializeSourceManager(InputFile, getDiagnostics(), getFileManager(),
+                                 getSourceManager(), getFrontendOpts());
+}
+
+bool CompilerInstance::InitializeSourceManager(llvm::StringRef InputFile,
+                                               Diagnostic &Diags,
+                                               FileManager &FileMgr,
+                                               SourceManager &SourceMgr,
+                                               const FrontendOptions &Opts) {
+  // Figure out where to get and map in the main file.
+  if (InputFile != "-") {
+    const FileEntry *File = FileMgr.getFile(InputFile);
+    if (File) SourceMgr.createMainFileID(File, SourceLocation());
+    if (SourceMgr.getMainFileID().isInvalid()) {
+      Diags.Report(diag::err_fe_error_reading) << InputFile;
+      return false;
+    }
+  } else {
+    llvm::MemoryBuffer *SB = llvm::MemoryBuffer::getSTDIN();
+    SourceMgr.createMainFileIDForMemBuffer(SB);
+    if (SourceMgr.getMainFileID().isInvalid()) {
+      Diags.Report(diag::err_fe_error_reading_stdin);
+      return false;
+    }
+  }
+
+  return true;
+}
+
+// High-Level Operations
+
+bool CompilerInstance::ExecuteAction(FrontendAction &Act) {
+  assert(hasDiagnostics() && "Diagnostics engine is not initialized!");
+  assert(!getFrontendOpts().ShowHelp && "Client must handle '-help'!");
+  assert(!getFrontendOpts().ShowVersion && "Client must handle '-version'!");
+
+  // FIXME: Take this as an argument, once all the APIs we used have moved to
+  // taking it as an input instead of hard-coding llvm::errs.
+  llvm::raw_ostream &OS = llvm::errs();
+
+  // Create the target instance.
+  setTarget(TargetInfo::CreateTargetInfo(getDiagnostics(), getTargetOpts()));
+  if (!hasTarget())
+    return false;
+
+  // Inform the target of the language options.
+  //
+  // FIXME: We shouldn't need to do this, the target should be immutable once
+  // created. This complexity should be lifted elsewhere.
+  getTarget().setForcedLangOptions(getLangOpts());
+
+  // Validate/process some options.
+  if (getHeaderSearchOpts().Verbose)
+    OS << "clang -cc1 version " CLANG_VERSION_STRING
+       << " based upon " << PACKAGE_STRING
+       << " hosted on " << llvm::sys::getHostTriple() << "\n";
+
+  if (getFrontendOpts().ShowTimers)
+    createFrontendTimer();
+
+  if (getFrontendOpts().ShowStats)
+    llvm::EnableStatistics();
+    
+  for (unsigned i = 0, e = getFrontendOpts().Inputs.size(); i != e; ++i) {
+    const std::string &InFile = getFrontendOpts().Inputs[i].second;
+
+    // If we aren't using an AST file, setup the file and source managers and
+    // the preprocessor.
+    bool IsAST = getFrontendOpts().Inputs[i].first == FrontendOptions::IK_AST;
+    if (!IsAST) {
+      if (!i) {
+        // Create a file manager object to provide access to and cache the
+        // filesystem.
+        createFileManager();
+
+        // Create the source manager.
+        createSourceManager();
+      } else {
+        // Reset the ID tables if we are reusing the SourceManager.
+        getSourceManager().clearIDTables();
+      }
+
+      // Create the preprocessor.
+      createPreprocessor();
+    }
+
+    if (Act.BeginSourceFile(*this, InFile, IsAST)) {
+      Act.Execute();
+      Act.EndSourceFile();
+    }
+  }
+
+  if (getDiagnosticOpts().ShowCarets) {
+    unsigned NumWarnings = getDiagnostics().getNumWarnings();
+    unsigned NumErrors = getDiagnostics().getNumErrors() - 
+                               getDiagnostics().getNumErrorsSuppressed();
+    
+    if (NumWarnings)
+      OS << NumWarnings << " warning" << (NumWarnings == 1 ? "" : "s");
+    if (NumWarnings && NumErrors)
+      OS << " and ";
+    if (NumErrors)
+      OS << NumErrors << " error" << (NumErrors == 1 ? "" : "s");
+    if (NumWarnings || NumErrors)
+      OS << " generated.\n";
+  }
+
+  if (getFrontendOpts().ShowStats) {
+    getFileManager().PrintStats();
+    OS << "\n";
+  }
+
+  // Return the appropriate status when verifying diagnostics.
+  //
+  // FIXME: If we could make getNumErrors() do the right thing, we wouldn't need
+  // this.
+  if (getDiagnosticOpts().VerifyDiagnostics)
+    return !static_cast<VerifyDiagnosticsClient&>(
+      getDiagnosticClient()).HadErrors();
+
+  return !getDiagnostics().getNumErrors();
+}
+
+
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
new file mode 100644
index 0000000..68842a4
--- /dev/null
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -0,0 +1,1395 @@
+//===--- CompilerInvocation.cpp -------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/CompilerInvocation.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/Version.h"
+#include "clang/Driver/Arg.h"
+#include "clang/Driver/ArgList.h"
+#include "clang/Driver/CC1Options.h"
+#include "clang/Driver/DriverDiagnostic.h"
+#include "clang/Driver/OptTable.h"
+#include "clang/Driver/Option.h"
+#include "clang/Frontend/CompilerInvocation.h"
+#include "clang/Frontend/LangStandard.h"
+#include "clang/Frontend/PCHReader.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/System/Host.h"
+#include "llvm/System/Path.h"
+using namespace clang;
+
+static const char *getAnalysisName(Analyses Kind) {
+  switch (Kind) {
+  default:
+    llvm_unreachable("Unknown analysis kind!");
+#define ANALYSIS(NAME, CMDFLAG, DESC, SCOPE)\
+  case NAME: return "-" CMDFLAG;
+#include "clang/Frontend/Analyses.def"
+  }
+}
+
+static const char *getAnalysisStoreName(AnalysisStores Kind) {
+  switch (Kind) {
+  default:
+    llvm_unreachable("Unknown analysis store!");
+#define ANALYSIS_STORE(NAME, CMDFLAG, DESC, CREATFN) \
+  case NAME##Model: return CMDFLAG;
+#include "clang/Frontend/Analyses.def"
+  }
+}
+
+static const char *getAnalysisConstraintName(AnalysisConstraints Kind) {
+  switch (Kind) {
+  default:
+    llvm_unreachable("Unknown analysis constraints!");
+#define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATFN) \
+  case NAME##Model: return CMDFLAG;
+#include "clang/Frontend/Analyses.def"
+  }
+}
+
+static const char *getAnalysisDiagClientName(AnalysisDiagClients Kind) {
+  switch (Kind) {
+  default:
+    llvm_unreachable("Unknown analysis client!");
+#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN, AUTOCREATE) \
+  case PD_##NAME: return CMDFLAG;
+#include "clang/Frontend/Analyses.def"
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// Serialization (to args)
+//===----------------------------------------------------------------------===//
+
+static void AnalyzerOptsToArgs(const AnalyzerOptions &Opts,
+                               std::vector<std::string> &Res) {
+  for (unsigned i = 0, e = Opts.AnalysisList.size(); i != e; ++i)
+    Res.push_back(getAnalysisName(Opts.AnalysisList[i]));
+  if (Opts.AnalysisStoreOpt != BasicStoreModel) {
+    Res.push_back("-analyzer-store");
+    Res.push_back(getAnalysisStoreName(Opts.AnalysisStoreOpt));
+  }
+  if (Opts.AnalysisConstraintsOpt != RangeConstraintsModel) {
+    Res.push_back("-analyzer-constraints");
+    Res.push_back(getAnalysisConstraintName(Opts.AnalysisConstraintsOpt));
+  }
+  if (Opts.AnalysisDiagOpt != PD_HTML) {
+    Res.push_back("-analyzer-output");
+    Res.push_back(getAnalysisDiagClientName(Opts.AnalysisDiagOpt));
+  }
+  if (!Opts.AnalyzeSpecificFunction.empty()) {
+    Res.push_back("-analyze-function");
+    Res.push_back(Opts.AnalyzeSpecificFunction);
+  }
+  if (Opts.AnalyzeAll)
+    Res.push_back("-analyzer-opt-analyze-headers");
+  if (Opts.AnalyzerDisplayProgress)
+    Res.push_back("-analyzer-display-progress");
+  if (Opts.AnalyzeNestedBlocks)
+    Res.push_back("-analyzer-opt-analyze-nested-blocks");
+  if (Opts.EagerlyAssume)
+    Res.push_back("-analyzer-eagerly-assume");
+  if (!Opts.PurgeDead)
+    Res.push_back("-analyzer-no-purge-dead");
+  if (Opts.TrimGraph)
+    Res.push_back("-trim-egraph");
+  if (Opts.VisualizeEGDot)
+    Res.push_back("-analyzer-viz-egraph-graphviz");
+  if (Opts.VisualizeEGDot)
+    Res.push_back("-analyzer-viz-egraph-ubigraph");
+  if (Opts.EnableExperimentalChecks)
+    Res.push_back("-analyzer-experimental-checks");
+  if (Opts.EnableExperimentalInternalChecks)
+    Res.push_back("-analyzer-experimental-internal-checks");
+}
+
+static void CodeGenOptsToArgs(const CodeGenOptions &Opts,
+                              std::vector<std::string> &Res) {
+  if (Opts.DebugInfo)
+    Res.push_back("-g");
+  if (Opts.DisableLLVMOpts)
+    Res.push_back("-disable-llvm-optzns");
+  if (Opts.DisableRedZone)
+    Res.push_back("-disable-red-zone");
+  if (!Opts.DwarfDebugFlags.empty()) {
+    Res.push_back("-dwarf-debug-flags");
+    Res.push_back(Opts.DwarfDebugFlags);
+  }
+  if (!Opts.MergeAllConstants)
+    Res.push_back("-fno-merge-all-constants");
+  if (Opts.NoCommon)
+    Res.push_back("-fno-common");
+  if (Opts.NoImplicitFloat)
+    Res.push_back("-no-implicit-float");
+  if (Opts.OptimizeSize) {
+    assert(Opts.OptimizationLevel == 2 && "Invalid options!");
+    Res.push_back("-Os");
+  } else if (Opts.OptimizationLevel != 0)
+    Res.push_back("-O" + llvm::utostr(Opts.OptimizationLevel));
+  if (!Opts.MainFileName.empty()) {
+    Res.push_back("-main-file-name");
+    Res.push_back(Opts.MainFileName);
+  }
+  // SimplifyLibCalls is only derived.
+  // TimePasses is only derived.
+  // UnitAtATime is unused.
+  // UnrollLoops is only derived.
+  // VerifyModule is only derived.
+  // Inlining is only derived.
+
+  if (Opts.DataSections)
+    Res.push_back("-fdata-sections");
+  if (Opts.FunctionSections)
+    Res.push_back("-ffunction-sections");
+  if (Opts.AsmVerbose)
+    Res.push_back("-masm-verbose");
+  if (!Opts.CodeModel.empty()) {
+    Res.push_back("-mcode-model");
+    Res.push_back(Opts.CodeModel);
+  }
+  if (!Opts.CXAAtExit)
+    Res.push_back("-fno-use-cxa-atexit");
+  if (Opts.CXXCtorDtorAliases)
+    Res.push_back("-mconstructor-aliases");
+  if (!Opts.DebugPass.empty()) {
+    Res.push_back("-mdebug-pass");
+    Res.push_back(Opts.DebugPass);
+  }
+  if (Opts.DisableFPElim)
+    Res.push_back("-mdisable-fp-elim");
+  if (!Opts.FloatABI.empty()) {
+    Res.push_back("-mfloat-abi");
+    Res.push_back(Opts.FloatABI);
+  }
+  if (!Opts.LimitFloatPrecision.empty()) {
+    Res.push_back("-mlimit-float-precision");
+    Res.push_back(Opts.LimitFloatPrecision);
+  }
+  if (Opts.NoZeroInitializedInBSS)
+    Res.push_back("-mno-zero-initialized-bss");
+  switch (Opts.getObjCDispatchMethod()) {
+  case CodeGenOptions::Legacy:
+    break;
+  case CodeGenOptions::Mixed:
+    Res.push_back("-fobjc-dispatch-method=mixed");
+    break;
+  case CodeGenOptions::NonLegacy:
+    Res.push_back("-fobjc-dispatch-method=non-legacy");
+    break;
+  }
+  if (Opts.SoftFloat)
+    Res.push_back("-msoft-float");
+  if (Opts.UnwindTables)
+    Res.push_back("-munwind-tables");
+  if (Opts.RelocationModel != "pic") {
+    Res.push_back("-mrelocation-model");
+    Res.push_back(Opts.RelocationModel);
+  }
+  if (!Opts.VerifyModule)
+    Res.push_back("-disable-llvm-verifier");
+}
+
+static void DependencyOutputOptsToArgs(const DependencyOutputOptions &Opts,
+                                       std::vector<std::string> &Res) {
+  if (Opts.IncludeSystemHeaders)
+    Res.push_back("-sys-header-deps");
+  if (Opts.UsePhonyTargets)
+    Res.push_back("-MP");
+  if (!Opts.OutputFile.empty()) {
+    Res.push_back("-dependency-file");
+    Res.push_back(Opts.OutputFile);
+  }
+  for (unsigned i = 0, e = Opts.Targets.size(); i != e; ++i) {
+    Res.push_back("-MT");
+    Res.push_back(Opts.Targets[i]);
+  }
+}
+
+static void DiagnosticOptsToArgs(const DiagnosticOptions &Opts,
+                                 std::vector<std::string> &Res) {
+  if (Opts.IgnoreWarnings)
+    Res.push_back("-w");
+  if (Opts.NoRewriteMacros)
+    Res.push_back("-Wno-rewrite-macros");
+  if (Opts.Pedantic)
+    Res.push_back("-pedantic");
+  if (Opts.PedanticErrors)
+    Res.push_back("-pedantic-errors");
+  if (!Opts.ShowColumn)
+    Res.push_back("-fno-show-column");
+  if (!Opts.ShowLocation)
+    Res.push_back("-fno-show-source-location");
+  if (!Opts.ShowCarets)
+    Res.push_back("-fno-caret-diagnostics");
+  if (!Opts.ShowFixits)
+    Res.push_back("-fno-diagnostics-fixit-info");
+  if (Opts.ShowSourceRanges)
+    Res.push_back("-fdiagnostics-print-source-range-info");
+  if (Opts.ShowColors)
+    Res.push_back("-fcolor-diagnostics");
+  if (Opts.VerifyDiagnostics)
+    Res.push_back("-verify");
+  if (Opts.BinaryOutput)
+    Res.push_back("-fdiagnostics-binary");
+  if (Opts.ShowOptionNames)
+    Res.push_back("-fdiagnostics-show-option");
+  if (Opts.ErrorLimit) {
+    Res.push_back("-ferror-limit");
+    Res.push_back(llvm::utostr(Opts.ErrorLimit));
+  }
+  if (Opts.TemplateBacktraceLimit != 10) {
+    Res.push_back("-ftemplate-backtrace-limit");
+    Res.push_back(llvm::utostr(Opts.TemplateBacktraceLimit));
+  }
+
+  if (Opts.TabStop != DiagnosticOptions::DefaultTabStop) {
+    Res.push_back("-ftabstop");
+    Res.push_back(llvm::utostr(Opts.TabStop));
+  }
+  if (Opts.MessageLength) {
+    Res.push_back("-fmessage-length");
+    Res.push_back(llvm::utostr(Opts.MessageLength));
+  }
+  if (!Opts.DumpBuildInformation.empty()) {
+    Res.push_back("-dump-build-information");
+    Res.push_back(Opts.DumpBuildInformation);
+  }
+  for (unsigned i = 0, e = Opts.Warnings.size(); i != e; ++i)
+    Res.push_back("-W" + Opts.Warnings[i]);
+}
+
+static const char *getInputKindName(FrontendOptions::InputKind Kind) {
+  switch (Kind) {
+  case FrontendOptions::IK_None:              break;
+  case FrontendOptions::IK_AST:               return "ast";
+  case FrontendOptions::IK_Asm:               return "assembler-with-cpp";
+  case FrontendOptions::IK_C:                 return "c";
+  case FrontendOptions::IK_CXX:               return "c++";
+  case FrontendOptions::IK_ObjC:              return "objective-c";
+  case FrontendOptions::IK_ObjCXX:            return "objective-c++";
+  case FrontendOptions::IK_OpenCL:            return "cl";
+  case FrontendOptions::IK_PreprocessedC:     return "cpp-output";
+  case FrontendOptions::IK_PreprocessedCXX:   return "c++-cpp-output";
+  case FrontendOptions::IK_PreprocessedObjC:  return "objective-c-cpp-output";
+  case FrontendOptions::IK_PreprocessedObjCXX:return "objective-c++-cpp-output";
+  }
+
+  llvm_unreachable("Unexpected language kind!");
+  return 0;
+}
+
+static const char *getActionName(frontend::ActionKind Kind) {
+  switch (Kind) {
+  case frontend::PluginAction:
+  case frontend::InheritanceView:
+    llvm_unreachable("Invalid kind!");
+
+  case frontend::ASTDump:                return "-ast-dump";
+  case frontend::ASTPrint:               return "-ast-print";
+  case frontend::ASTPrintXML:            return "-ast-print-xml";
+  case frontend::ASTView:                return "-ast-view";
+  case frontend::DumpRawTokens:          return "-dump-raw-tokens";
+  case frontend::DumpTokens:             return "-dump-tokens";
+  case frontend::EmitAssembly:           return "-S";
+  case frontend::EmitBC:                 return "-emit-llvm-bc";
+  case frontend::EmitHTML:               return "-emit-html";
+  case frontend::EmitLLVM:               return "-emit-llvm";
+  case frontend::EmitLLVMOnly:           return "-emit-llvm-only";
+  case frontend::EmitObj:                return "-emit-obj";
+  case frontend::FixIt:                  return "-fixit";
+  case frontend::GeneratePCH:            return "-emit-pch";
+  case frontend::GeneratePTH:            return "-emit-pth";
+  case frontend::InitOnly:               return "-init-only";
+  case frontend::ParseNoop:              return "-parse-noop";
+  case frontend::ParsePrintCallbacks:    return "-parse-print-callbacks";
+  case frontend::ParseSyntaxOnly:        return "-fsyntax-only";
+  case frontend::PrintDeclContext:       return "-print-decl-contexts";
+  case frontend::PrintPreprocessedInput: return "-E";
+  case frontend::RewriteMacros:          return "-rewrite-macros";
+  case frontend::RewriteObjC:            return "-rewrite-objc";
+  case frontend::RewriteTest:            return "-rewrite-test";
+  case frontend::RunAnalysis:            return "-analyze";
+  case frontend::RunPreprocessorOnly:    return "-Eonly";
+  }
+
+  llvm_unreachable("Unexpected language kind!");
+  return 0;
+}
+
+static void FrontendOptsToArgs(const FrontendOptions &Opts,
+                               std::vector<std::string> &Res) {
+  if (!Opts.DebugCodeCompletionPrinter)
+    Res.push_back("-no-code-completion-debug-printer");
+  if (Opts.DisableFree)
+    Res.push_back("-disable-free");
+  if (Opts.RelocatablePCH)
+    Res.push_back("-relocatable-pch");
+  if (Opts.ShowHelp)
+    Res.push_back("-help");
+  if (Opts.ShowMacrosInCodeCompletion)
+    Res.push_back("-code-completion-macros");
+  if (Opts.ShowStats)
+    Res.push_back("-print-stats");
+  if (Opts.ShowTimers)
+    Res.push_back("-ftime-report");
+  if (Opts.ShowVersion)
+    Res.push_back("-version");
+
+  bool NeedLang = false;
+  for (unsigned i = 0, e = Opts.Inputs.size(); i != e; ++i)
+    if (FrontendOptions::getInputKindForExtension(Opts.Inputs[i].second) !=
+        Opts.Inputs[i].first)
+      NeedLang = true;
+  if (NeedLang) {
+    Res.push_back("-x");
+    Res.push_back(getInputKindName(Opts.Inputs[0].first));
+  }
+  for (unsigned i = 0, e = Opts.Inputs.size(); i != e; ++i) {
+    assert((!NeedLang || Opts.Inputs[i].first == Opts.Inputs[0].first) &&
+           "Unable to represent this input vector!");
+    Res.push_back(Opts.Inputs[i].second);
+  }
+
+  if (!Opts.OutputFile.empty()) {
+    Res.push_back("-o");
+    Res.push_back(Opts.OutputFile);
+  }
+  if (!Opts.ViewClassInheritance.empty()) {
+    Res.push_back("-cxx-inheritance-view");
+    Res.push_back(Opts.ViewClassInheritance);
+  }
+  if (!Opts.CodeCompletionAt.FileName.empty()) {
+    Res.push_back("-code-completion-at");
+    Res.push_back(Opts.CodeCompletionAt.FileName + ":" +
+                  llvm::utostr(Opts.CodeCompletionAt.Line) + ":" +
+                  llvm::utostr(Opts.CodeCompletionAt.Column));
+  }
+  if (Opts.ProgramAction != frontend::InheritanceView &&
+      Opts.ProgramAction != frontend::PluginAction)
+    Res.push_back(getActionName(Opts.ProgramAction));
+  if (!Opts.ActionName.empty()) {
+    Res.push_back("-plugin");
+    Res.push_back(Opts.ActionName);
+  }
+  for (unsigned i = 0, e = Opts.Plugins.size(); i != e; ++i) {
+    Res.push_back("-load");
+    Res.push_back(Opts.Plugins[i]);
+  }
+  for (unsigned i = 0, e = Opts.ASTMergeFiles.size(); i != e; ++i) {
+    Res.push_back("-ast-merge");
+    Res.push_back(Opts.ASTMergeFiles[i]);
+  }
+  for (unsigned i = 0, e = Opts.LLVMArgs.size(); i != e; ++i) {
+    Res.push_back("-mllvm");
+    Res.push_back(Opts.LLVMArgs[i]);
+  }
+}
+
+static void HeaderSearchOptsToArgs(const HeaderSearchOptions &Opts,
+                                   std::vector<std::string> &Res) {
+  if (Opts.Sysroot != "/") {
+    Res.push_back("-isysroot");
+    Res.push_back(Opts.Sysroot);
+  }
+
+  /// User specified include entries.
+  for (unsigned i = 0, e = Opts.UserEntries.size(); i != e; ++i) {
+    const HeaderSearchOptions::Entry &E = Opts.UserEntries[i];
+    if (E.IsFramework && (E.Group != frontend::Angled || !E.IsUserSupplied))
+      llvm::report_fatal_error("Invalid option set!");
+    if (E.IsUserSupplied) {
+      if (E.Group == frontend::After) {
+        Res.push_back("-idirafter");
+      } else if (E.Group == frontend::Quoted) {
+        Res.push_back("-iquote");
+      } else if (E.Group == frontend::System) {
+        Res.push_back("-isystem");
+      } else {
+        assert(E.Group == frontend::Angled && "Invalid group!");
+        Res.push_back(E.IsFramework ? "-F" : "-I");
+      }
+    } else {
+      if (E.Group != frontend::Angled && E.Group != frontend::System)
+        llvm::report_fatal_error("Invalid option set!");
+      Res.push_back(E.Group == frontend::Angled ? "-iwithprefixbefore" :
+                    "-iwithprefix");
+    }
+    Res.push_back(E.Path);
+  }
+
+  if (!Opts.EnvIncPath.empty()) {
+    // FIXME: Provide an option for this, and move env detection to driver.
+    llvm::report_fatal_error("Not yet implemented!");
+  }
+  if (!Opts.CEnvIncPath.empty()) {
+    // FIXME: Provide an option for this, and move env detection to driver.
+    llvm::report_fatal_error("Not yet implemented!");
+  }
+  if (!Opts.ObjCEnvIncPath.empty()) {
+    // FIXME: Provide an option for this, and move env detection to driver.
+    llvm::report_fatal_error("Not yet implemented!");
+  }
+  if (!Opts.CXXEnvIncPath.empty()) {
+    // FIXME: Provide an option for this, and move env detection to driver.
+    llvm::report_fatal_error("Not yet implemented!");
+  }
+  if (!Opts.ObjCXXEnvIncPath.empty()) {
+    // FIXME: Provide an option for this, and move env detection to driver.
+    llvm::report_fatal_error("Not yet implemented!");
+  }
+  if (!Opts.ResourceDir.empty()) {
+    Res.push_back("-resource-dir");
+    Res.push_back(Opts.ResourceDir);
+  }
+  if (!Opts.UseStandardIncludes)
+    Res.push_back("-nostdinc");
+  if (!Opts.UseStandardCXXIncludes)
+    Res.push_back("-nostdinc++");
+  if (Opts.Verbose)
+    Res.push_back("-v");
+}
+
+static void LangOptsToArgs(const LangOptions &Opts,
+                           std::vector<std::string> &Res) {
+  LangOptions DefaultLangOpts;
+
+  // FIXME: Need to set -std to get all the implicit options.
+
+  // FIXME: We want to only pass options relative to the defaults, which
+  // requires constructing a target. :(
+  //
+  // It would be better to push the all target specific choices into the driver,
+  // so that everything below that was more uniform.
+
+  if (Opts.Trigraphs)
+    Res.push_back("-trigraphs");
+  // Implicit based on the input kind:
+  //   AsmPreprocessor, CPlusPlus, ObjC1, ObjC2, OpenCL
+  // Implicit based on the input language standard:
+  //   BCPLComment, C99, CPlusPlus0x, Digraphs, GNUInline, ImplicitInt, GNUMode
+  if (Opts.DollarIdents)
+    Res.push_back("-fdollars-in-identifiers");
+  if (Opts.GNUMode && !Opts.GNUKeywords)
+    Res.push_back("-fno-gnu-keywords");
+  if (!Opts.GNUMode && Opts.GNUKeywords)
+    Res.push_back("-fgnu-keywords");
+  if (Opts.Microsoft)
+    Res.push_back("-fms-extensions");
+  if (Opts.ObjCNonFragileABI)
+    Res.push_back("-fobjc-nonfragile-abi");
+  if (Opts.ObjCNonFragileABI2)
+    Res.push_back("-fobjc-nonfragile-abi2");
+  // NoInline is implicit.
+  if (!Opts.CXXOperatorNames)
+    Res.push_back("-fno-operator-names");
+  if (Opts.PascalStrings)
+    Res.push_back("-fpascal-strings");
+  if (Opts.CatchUndefined)
+    Res.push_back("-fcatch-undefined-behavior");
+  if (Opts.WritableStrings)
+    Res.push_back("-fwritable-strings");
+  if (Opts.ConstStrings)
+    Res.push_back("-Wwrite-strings");
+  if (!Opts.LaxVectorConversions)
+    Res.push_back("-fno-lax-vector-conversions");
+  if (Opts.AltiVec)
+    Res.push_back("-faltivec");
+  if (Opts.Exceptions)
+    Res.push_back("-fexceptions");
+  if (Opts.SjLjExceptions)
+    Res.push_back("-fsjlj-exceptions");
+  if (!Opts.RTTI)
+    Res.push_back("-fno-rtti");
+  if (!Opts.NeXTRuntime)
+    Res.push_back("-fgnu-runtime");
+  if (Opts.Freestanding)
+    Res.push_back("-ffreestanding");
+  if (Opts.NoBuiltin)
+    Res.push_back("-fno-builtin");
+  if (!Opts.AssumeSaneOperatorNew)
+    Res.push_back("-fno-assume-sane-operator-new");
+  if (!Opts.ThreadsafeStatics)
+    Res.push_back("-fno-threadsafe-statics");
+  if (Opts.POSIXThreads)
+    Res.push_back("-pthread");
+  if (Opts.Blocks)
+    Res.push_back("-fblocks");
+  if (Opts.EmitAllDecls)
+    Res.push_back("-femit-all-decls");
+  if (Opts.MathErrno)
+    Res.push_back("-fmath-errno");
+  if (Opts.OverflowChecking)
+    Res.push_back("-ftrapv");
+  if (Opts.HeinousExtensions)
+    Res.push_back("-fheinous-gnu-extensions");
+  // Optimize is implicit.
+  // OptimizeSize is implicit.
+  if (Opts.Static)
+    Res.push_back("-static-define");
+  if (Opts.DumpRecordLayouts)
+    Res.push_back("-fdump-record-layouts");
+  if (Opts.DumpVTableLayouts)
+    Res.push_back("-fdump-vtable-layouts");
+  if (Opts.NoBitFieldTypeAlign)
+    Res.push_back("-fno-bitfield-type-alignment");
+  if (Opts.SjLjExceptions)
+    Res.push_back("-fsjlj-exceptions");
+  if (Opts.PICLevel) {
+    Res.push_back("-pic-level");
+    Res.push_back(llvm::utostr(Opts.PICLevel));
+  }
+  if (Opts.ObjCGCBitmapPrint)
+    Res.push_back("-print-ivar-layout");
+  if (Opts.NoConstantCFStrings)
+    Res.push_back("-fno-constant-cfstrings");
+  if (!Opts.AccessControl)
+    Res.push_back("-fno-access-control");
+  if (!Opts.CharIsSigned)
+    Res.push_back("-fno-signed-char");
+  if (Opts.ShortWChar)
+    Res.push_back("-fshort-wchar");
+  if (!Opts.ElideConstructors)
+    Res.push_back("-fno-elide-constructors");
+  if (Opts.getGCMode() != LangOptions::NonGC) {
+    if (Opts.getGCMode() == LangOptions::HybridGC) {
+      Res.push_back("-fobjc-gc");
+    } else {
+      assert(Opts.getGCMode() == LangOptions::GCOnly && "Invalid GC mode!");
+      Res.push_back("-fobjc-gc-only");
+    }
+  }
+  if (Opts.getVisibilityMode() != LangOptions::Default) {
+    Res.push_back("-fvisibility");
+    if (Opts.getVisibilityMode() == LangOptions::Hidden) {
+      Res.push_back("hidden");
+    } else {
+      assert(Opts.getVisibilityMode() == LangOptions::Protected &&
+             "Invalid visibility!");
+      Res.push_back("protected");
+    }
+  }
+  if (Opts.getStackProtectorMode() != 0) {
+    Res.push_back("-stack-protector");
+    Res.push_back(llvm::utostr(Opts.getStackProtectorMode()));
+  }
+  if (Opts.InstantiationDepth != DefaultLangOpts.InstantiationDepth) {
+    Res.push_back("-ftemplate-depth");
+    Res.push_back(llvm::utostr(Opts.InstantiationDepth));
+  }
+  if (!Opts.ObjCConstantStringClass.empty()) {
+    Res.push_back("-fconstant-string-class");
+    Res.push_back(Opts.ObjCConstantStringClass);
+  }
+}
+
+static void PreprocessorOptsToArgs(const PreprocessorOptions &Opts,
+                                   std::vector<std::string> &Res) {
+  for (unsigned i = 0, e = Opts.Macros.size(); i != e; ++i)
+    Res.push_back(std::string(Opts.Macros[i].second ? "-U" : "-D") +
+                  Opts.Macros[i].first);
+  for (unsigned i = 0, e = Opts.Includes.size(); i != e; ++i) {
+    // FIXME: We need to avoid reincluding the implicit PCH and PTH includes.
+    Res.push_back("-include");
+    Res.push_back(Opts.Includes[i]);
+  }
+  for (unsigned i = 0, e = Opts.MacroIncludes.size(); i != e; ++i) {
+    Res.push_back("-imacros");
+    Res.push_back(Opts.MacroIncludes[i]);
+  }
+  if (!Opts.UsePredefines)
+    Res.push_back("-undef");
+  if (Opts.DetailedRecord)
+    Res.push_back("-detailed-preprocessing-record");
+  if (!Opts.ImplicitPCHInclude.empty()) {
+    Res.push_back("-include-pch");
+    Res.push_back(Opts.ImplicitPCHInclude);
+  }
+  if (!Opts.ImplicitPTHInclude.empty()) {
+    Res.push_back("-include-pth");
+    Res.push_back(Opts.ImplicitPTHInclude);
+  }
+  if (!Opts.TokenCache.empty()) {
+    if (Opts.ImplicitPTHInclude.empty()) {
+      Res.push_back("-token-cache");
+      Res.push_back(Opts.TokenCache);
+    } else
+      assert(Opts.ImplicitPTHInclude == Opts.TokenCache &&
+             "Unsupported option combination!");
+  }
+  for (unsigned i = 0, e = Opts.RemappedFiles.size(); i != e; ++i) {
+    Res.push_back("-remap-file");
+    Res.push_back(Opts.RemappedFiles[i].first + ";" +
+                  Opts.RemappedFiles[i].second);
+  }
+}
+
+static void PreprocessorOutputOptsToArgs(const PreprocessorOutputOptions &Opts,
+                                         std::vector<std::string> &Res) {
+  if (!Opts.ShowCPP && !Opts.ShowMacros)
+    llvm::report_fatal_error("Invalid option combination!");
+
+  if (Opts.ShowCPP && Opts.ShowMacros)
+    Res.push_back("-dD");
+  else if (!Opts.ShowCPP && Opts.ShowMacros)
+    Res.push_back("-dM");
+
+  if (!Opts.ShowLineMarkers)
+    Res.push_back("-P");
+  if (Opts.ShowComments)
+    Res.push_back("-C");
+  if (Opts.ShowMacroComments)
+    Res.push_back("-CC");
+}
+
+static void TargetOptsToArgs(const TargetOptions &Opts,
+                             std::vector<std::string> &Res) {
+  Res.push_back("-triple");
+  Res.push_back(Opts.Triple);
+  if (!Opts.CPU.empty()) {
+    Res.push_back("-target-cpu");
+    Res.push_back(Opts.CPU);
+  }
+  if (!Opts.ABI.empty()) {
+    Res.push_back("-target-abi");
+    Res.push_back(Opts.ABI);
+  }
+  for (unsigned i = 0, e = Opts.Features.size(); i != e; ++i) {
+    Res.push_back("-target-feature");
+    Res.push_back(Opts.Features[i]);
+  }
+}
+
+void CompilerInvocation::toArgs(std::vector<std::string> &Res) {
+  AnalyzerOptsToArgs(getAnalyzerOpts(), Res);
+  CodeGenOptsToArgs(getCodeGenOpts(), Res);
+  DependencyOutputOptsToArgs(getDependencyOutputOpts(), Res);
+  DiagnosticOptsToArgs(getDiagnosticOpts(), Res);
+  FrontendOptsToArgs(getFrontendOpts(), Res);
+  HeaderSearchOptsToArgs(getHeaderSearchOpts(), Res);
+  LangOptsToArgs(getLangOpts(), Res);
+  PreprocessorOptsToArgs(getPreprocessorOpts(), Res);
+  PreprocessorOutputOptsToArgs(getPreprocessorOutputOpts(), Res);
+  TargetOptsToArgs(getTargetOpts(), Res);
+}
+
+//===----------------------------------------------------------------------===//
+// Deserialization (to args)
+//===----------------------------------------------------------------------===//
+
+using namespace clang::driver;
+using namespace clang::driver::cc1options;
+
+static llvm::StringRef getLastArgValue(ArgList &Args, cc1options::ID ID,
+                                       llvm::StringRef Default = "") {
+  if (Arg *A = Args.getLastArg(ID))
+    return A->getValue(Args);
+  return Default;
+}
+
+static int getLastArgIntValue(ArgList &Args, cc1options::ID ID,
+                              int Default, Diagnostic &Diags) {
+  Arg *A = Args.getLastArg(ID);
+  if (!A)
+    return Default;
+
+  int Res = Default;
+  if (llvm::StringRef(A->getValue(Args)).getAsInteger(10, Res))
+    Diags.Report(diag::err_drv_invalid_int_value)
+        << A->getAsString(Args) << A->getValue(Args);
+
+  return Res;
+}
+
+static std::vector<std::string>
+getAllArgValues(ArgList &Args, cc1options::ID ID) {
+  llvm::SmallVector<const char *, 16> Values;
+  Args.AddAllArgValues(Values, ID);
+  return std::vector<std::string>(Values.begin(), Values.end());
+}
+
+//
+
+static void ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args,
+                              Diagnostic &Diags) {
+  using namespace cc1options;
+
+  Opts.AnalysisList.clear();
+#define ANALYSIS(NAME, CMDFLAG, DESC, SCOPE) \
+  if (Args.hasArg(OPT_analysis_##NAME)) Opts.AnalysisList.push_back(NAME);
+#include "clang/Frontend/Analyses.def"
+
+  if (Arg *A = Args.getLastArg(OPT_analyzer_store)) {
+    llvm::StringRef Name = A->getValue(Args);
+    AnalysisStores Value = llvm::StringSwitch<AnalysisStores>(Name)
+#define ANALYSIS_STORE(NAME, CMDFLAG, DESC, CREATFN) \
+      .Case(CMDFLAG, NAME##Model)
+#include "clang/Frontend/Analyses.def"
+      .Default(NumStores);
+    // FIXME: Error handling.
+    if (Value == NumStores)
+      Diags.Report(diag::err_drv_invalid_value)
+        << Args.getLastArg(OPT_O)->getAsString(Args) << Name;
+    else
+      Opts.AnalysisStoreOpt = Value;
+  }
+
+  if (Arg *A = Args.getLastArg(OPT_analyzer_constraints)) {
+    llvm::StringRef Name = A->getValue(Args);
+    AnalysisConstraints Value = llvm::StringSwitch<AnalysisConstraints>(Name)
+#define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATFN) \
+      .Case(CMDFLAG, NAME##Model)
+#include "clang/Frontend/Analyses.def"
+      .Default(NumConstraints);
+    // FIXME: Error handling.
+    if (Value == NumConstraints)
+      Diags.Report(diag::err_drv_invalid_value)
+        << Args.getLastArg(OPT_O)->getAsString(Args) << Name;
+    else
+      Opts.AnalysisConstraintsOpt = Value;
+  }
+
+  if (Arg *A = Args.getLastArg(OPT_analyzer_output)) {
+    llvm::StringRef Name = A->getValue(Args);
+    AnalysisDiagClients Value = llvm::StringSwitch<AnalysisDiagClients>(Name)
+#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN, AUTOCREAT) \
+      .Case(CMDFLAG, PD_##NAME)
+#include "clang/Frontend/Analyses.def"
+      .Default(NUM_ANALYSIS_DIAG_CLIENTS);
+    // FIXME: Error handling.
+    if (Value == NUM_ANALYSIS_DIAG_CLIENTS)
+      Diags.Report(diag::err_drv_invalid_value)
+        << Args.getLastArg(OPT_O)->getAsString(Args) << Name;
+    else
+      Opts.AnalysisDiagOpt = Value;
+  }
+
+  Opts.VisualizeEGDot = Args.hasArg(OPT_analyzer_viz_egraph_graphviz);
+  Opts.VisualizeEGUbi = Args.hasArg(OPT_analyzer_viz_egraph_ubigraph);
+  Opts.AnalyzeAll = Args.hasArg(OPT_analyzer_opt_analyze_headers);
+  Opts.AnalyzerDisplayProgress = Args.hasArg(OPT_analyzer_display_progress);
+  Opts.AnalyzeNestedBlocks =
+    Args.hasArg(OPT_analyzer_opt_analyze_nested_blocks);
+  Opts.PurgeDead = !Args.hasArg(OPT_analyzer_no_purge_dead);
+  Opts.EagerlyAssume = Args.hasArg(OPT_analyzer_eagerly_assume);
+  Opts.AnalyzeSpecificFunction = getLastArgValue(Args, OPT_analyze_function);
+  Opts.EnableExperimentalChecks = Args.hasArg(OPT_analyzer_experimental_checks);
+  Opts.EnableExperimentalInternalChecks =
+    Args.hasArg(OPT_analyzer_experimental_internal_checks);
+  Opts.TrimGraph = Args.hasArg(OPT_trim_egraph);
+  Opts.MaxNodes = getLastArgIntValue(Args, OPT_analyzer_max_nodes,150000,Diags);
+}
+
+static void ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args,
+                             Diagnostic &Diags) {
+  using namespace cc1options;
+  // -Os implies -O2
+  if (Args.hasArg(OPT_Os))
+    Opts.OptimizationLevel = 2;
+  else {
+    Opts.OptimizationLevel = getLastArgIntValue(Args, OPT_O, 0, Diags);
+    if (Opts.OptimizationLevel > 3) {
+      Diags.Report(diag::err_drv_invalid_value)
+        << Args.getLastArg(OPT_O)->getAsString(Args) << Opts.OptimizationLevel;
+      Opts.OptimizationLevel = 3;
+    }
+  }
+
+  // We must always run at least the always inlining pass.
+  Opts.Inlining = (Opts.OptimizationLevel > 1) ? CodeGenOptions::NormalInlining
+    : CodeGenOptions::OnlyAlwaysInlining;
+
+  Opts.DebugInfo = Args.hasArg(OPT_g);
+  Opts.DisableLLVMOpts = Args.hasArg(OPT_disable_llvm_optzns);
+  Opts.DisableRedZone = Args.hasArg(OPT_disable_red_zone);
+  Opts.DwarfDebugFlags = getLastArgValue(Args, OPT_dwarf_debug_flags);
+  Opts.MergeAllConstants = !Args.hasArg(OPT_fno_merge_all_constants);
+  Opts.NoCommon = Args.hasArg(OPT_fno_common);
+  Opts.NoImplicitFloat = Args.hasArg(OPT_no_implicit_float);
+  Opts.OptimizeSize = Args.hasArg(OPT_Os);
+  Opts.UnrollLoops = (Opts.OptimizationLevel > 1 && !Opts.OptimizeSize);
+
+  Opts.AsmVerbose = Args.hasArg(OPT_masm_verbose);
+  Opts.CXAAtExit = !Args.hasArg(OPT_fno_use_cxa_atexit);
+  Opts.CXXCtorDtorAliases = Args.hasArg(OPT_mconstructor_aliases);
+  Opts.CodeModel = getLastArgValue(Args, OPT_mcode_model);
+  Opts.DebugPass = getLastArgValue(Args, OPT_mdebug_pass);
+  Opts.DisableFPElim = Args.hasArg(OPT_mdisable_fp_elim);
+  Opts.FloatABI = getLastArgValue(Args, OPT_mfloat_abi);
+  Opts.LimitFloatPrecision = getLastArgValue(Args, OPT_mlimit_float_precision);
+  Opts.NoZeroInitializedInBSS = Args.hasArg(OPT_mno_zero_initialized_in_bss);
+  Opts.SoftFloat = Args.hasArg(OPT_msoft_float);
+  Opts.UnwindTables = Args.hasArg(OPT_munwind_tables);
+  Opts.RelocationModel = getLastArgValue(Args, OPT_mrelocation_model, "pic");
+
+  Opts.FunctionSections = Args.hasArg(OPT_ffunction_sections);
+  Opts.DataSections = Args.hasArg(OPT_fdata_sections);
+
+  Opts.MainFileName = getLastArgValue(Args, OPT_main_file_name);
+  Opts.VerifyModule = !Args.hasArg(OPT_disable_llvm_verifier);
+
+  if (Arg *A = Args.getLastArg(OPT_fobjc_dispatch_method_EQ)) {
+    llvm::StringRef Name = A->getValue(Args);
+    unsigned Method = llvm::StringSwitch<unsigned>(Name)
+      .Case("legacy", CodeGenOptions::Legacy)
+      .Case("non-legacy", CodeGenOptions::NonLegacy)
+      .Case("mixed", CodeGenOptions::Mixed)
+      .Default(~0U);
+    if (Method == ~0U)
+      Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Name;
+    else
+      Opts.ObjCDispatchMethod = Method;
+  }
+}
+
+static void ParseDependencyOutputArgs(DependencyOutputOptions &Opts,
+                                      ArgList &Args) {
+  using namespace cc1options;
+  Opts.OutputFile = getLastArgValue(Args, OPT_dependency_file);
+  Opts.Targets = getAllArgValues(Args, OPT_MT);
+  Opts.IncludeSystemHeaders = Args.hasArg(OPT_sys_header_deps);
+  Opts.UsePhonyTargets = Args.hasArg(OPT_MP);
+}
+
+static void ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args,
+                                Diagnostic &Diags) {
+  using namespace cc1options;
+  Opts.IgnoreWarnings = Args.hasArg(OPT_w);
+  Opts.NoRewriteMacros = Args.hasArg(OPT_Wno_rewrite_macros);
+  Opts.Pedantic = Args.hasArg(OPT_pedantic);
+  Opts.PedanticErrors = Args.hasArg(OPT_pedantic_errors);
+  Opts.ShowCarets = !Args.hasArg(OPT_fno_caret_diagnostics);
+  Opts.ShowColors = Args.hasArg(OPT_fcolor_diagnostics);
+  Opts.ShowColumn = !Args.hasArg(OPT_fno_show_column);
+  Opts.ShowFixits = !Args.hasArg(OPT_fno_diagnostics_fixit_info);
+  Opts.ShowLocation = !Args.hasArg(OPT_fno_show_source_location);
+  Opts.ShowOptionNames = Args.hasArg(OPT_fdiagnostics_show_option);
+  Opts.ShowSourceRanges = Args.hasArg(OPT_fdiagnostics_print_source_range_info);
+  Opts.VerifyDiagnostics = Args.hasArg(OPT_verify);
+  Opts.BinaryOutput = Args.hasArg(OPT_fdiagnostics_binary);
+  Opts.ErrorLimit = getLastArgIntValue(Args, OPT_ferror_limit, 0, Diags);
+  Opts.TemplateBacktraceLimit
+    = getLastArgIntValue(Args, OPT_ftemplate_backtrace_limit, 0, Diags);
+  Opts.TabStop = getLastArgIntValue(Args, OPT_ftabstop,
+                                    DiagnosticOptions::DefaultTabStop, Diags);
+  if (Opts.TabStop == 0 || Opts.TabStop > DiagnosticOptions::MaxTabStop) {
+    Diags.Report(diag::warn_ignoring_ftabstop_value)
+      << Opts.TabStop << DiagnosticOptions::DefaultTabStop;
+    Opts.TabStop = DiagnosticOptions::DefaultTabStop;
+  }
+  Opts.MessageLength = getLastArgIntValue(Args, OPT_fmessage_length, 0, Diags);
+  Opts.DumpBuildInformation = getLastArgValue(Args, OPT_dump_build_information);
+  Opts.Warnings = getAllArgValues(Args, OPT_W);
+}
+
+static FrontendOptions::InputKind
+ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, Diagnostic &Diags) {
+  using namespace cc1options;
+  Opts.ProgramAction = frontend::ParseSyntaxOnly;
+  if (const Arg *A = Args.getLastArg(OPT_Action_Group)) {
+    switch (A->getOption().getID()) {
+    default:
+      assert(0 && "Invalid option in group!");
+    case OPT_ast_dump:
+      Opts.ProgramAction = frontend::ASTDump; break;
+    case OPT_ast_print:
+      Opts.ProgramAction = frontend::ASTPrint; break;
+    case OPT_ast_print_xml:
+      Opts.ProgramAction = frontend::ASTPrintXML; break;
+    case OPT_ast_view:
+      Opts.ProgramAction = frontend::ASTView; break;
+    case OPT_dump_raw_tokens:
+      Opts.ProgramAction = frontend::DumpRawTokens; break;
+    case OPT_dump_tokens:
+      Opts.ProgramAction = frontend::DumpTokens; break;
+    case OPT_S:
+      Opts.ProgramAction = frontend::EmitAssembly; break;
+    case OPT_emit_llvm_bc:
+      Opts.ProgramAction = frontend::EmitBC; break;
+    case OPT_emit_html:
+      Opts.ProgramAction = frontend::EmitHTML; break;
+    case OPT_emit_llvm:
+      Opts.ProgramAction = frontend::EmitLLVM; break;
+    case OPT_emit_llvm_only:
+      Opts.ProgramAction = frontend::EmitLLVMOnly; break;
+    case OPT_emit_obj:
+      Opts.ProgramAction = frontend::EmitObj; break;
+    case OPT_fixit_EQ:
+      Opts.FixItSuffix = A->getValue(Args);
+      // fall-through!
+    case OPT_fixit:
+      Opts.ProgramAction = frontend::FixIt; break;
+    case OPT_emit_pch:
+      Opts.ProgramAction = frontend::GeneratePCH; break;
+    case OPT_emit_pth:
+      Opts.ProgramAction = frontend::GeneratePTH; break;
+    case OPT_init_only:
+      Opts.ProgramAction = frontend::InitOnly; break;
+    case OPT_parse_noop:
+      Opts.ProgramAction = frontend::ParseNoop; break;
+    case OPT_parse_print_callbacks:
+      Opts.ProgramAction = frontend::ParsePrintCallbacks; break;
+    case OPT_fsyntax_only:
+      Opts.ProgramAction = frontend::ParseSyntaxOnly; break;
+    case OPT_print_decl_contexts:
+      Opts.ProgramAction = frontend::PrintDeclContext; break;
+    case OPT_E:
+      Opts.ProgramAction = frontend::PrintPreprocessedInput; break;
+    case OPT_rewrite_macros:
+      Opts.ProgramAction = frontend::RewriteMacros; break;
+    case OPT_rewrite_objc:
+      Opts.ProgramAction = frontend::RewriteObjC; break;
+    case OPT_rewrite_test:
+      Opts.ProgramAction = frontend::RewriteTest; break;
+    case OPT_analyze:
+      Opts.ProgramAction = frontend::RunAnalysis; break;
+    case OPT_Eonly:
+      Opts.ProgramAction = frontend::RunPreprocessorOnly; break;
+    }
+  }
+  if (const Arg *A = Args.getLastArg(OPT_plugin)) {
+    Opts.ProgramAction = frontend::PluginAction;
+    Opts.ActionName = A->getValue(Args);
+  }
+
+  if (const Arg *A = Args.getLastArg(OPT_code_completion_at)) {
+    Opts.CodeCompletionAt =
+      ParsedSourceLocation::FromString(A->getValue(Args));
+    if (Opts.CodeCompletionAt.FileName.empty())
+      Diags.Report(diag::err_drv_invalid_value)
+        << A->getAsString(Args) << A->getValue(Args);
+  }
+  Opts.DebugCodeCompletionPrinter =
+    !Args.hasArg(OPT_no_code_completion_debug_printer);
+  Opts.DisableFree = Args.hasArg(OPT_disable_free);
+
+  Opts.OutputFile = getLastArgValue(Args, OPT_o);
+  Opts.Plugins = getAllArgValues(Args, OPT_load);
+  Opts.RelocatablePCH = Args.hasArg(OPT_relocatable_pch);
+  Opts.ShowHelp = Args.hasArg(OPT_help);
+  Opts.ShowMacrosInCodeCompletion = Args.hasArg(OPT_code_completion_macros);
+  Opts.ShowStats = Args.hasArg(OPT_print_stats);
+  Opts.ShowTimers = Args.hasArg(OPT_ftime_report);
+  Opts.ShowVersion = Args.hasArg(OPT_version);
+  Opts.ViewClassInheritance = getLastArgValue(Args, OPT_cxx_inheritance_view);
+  Opts.ASTMergeFiles = getAllArgValues(Args, OPT_ast_merge);
+  Opts.LLVMArgs = getAllArgValues(Args, OPT_mllvm);
+
+  FrontendOptions::InputKind DashX = FrontendOptions::IK_None;
+  if (const Arg *A = Args.getLastArg(OPT_x)) {
+    DashX = llvm::StringSwitch<FrontendOptions::InputKind>(A->getValue(Args))
+      .Case("c", FrontendOptions::IK_C)
+      .Case("cl", FrontendOptions::IK_OpenCL)
+      .Case("c", FrontendOptions::IK_C)
+      .Case("cl", FrontendOptions::IK_OpenCL)
+      .Case("c++", FrontendOptions::IK_CXX)
+      .Case("objective-c", FrontendOptions::IK_ObjC)
+      .Case("objective-c++", FrontendOptions::IK_ObjCXX)
+      .Case("cpp-output", FrontendOptions::IK_PreprocessedC)
+      .Case("assembler-with-cpp", FrontendOptions::IK_Asm)
+      .Case("c++-cpp-output", FrontendOptions::IK_PreprocessedCXX)
+      .Case("objective-c-cpp-output", FrontendOptions::IK_PreprocessedObjC)
+      .Case("objective-c++-cpp-output", FrontendOptions::IK_PreprocessedObjCXX)
+      .Case("c-header", FrontendOptions::IK_C)
+      .Case("objective-c-header", FrontendOptions::IK_ObjC)
+      .Case("c++-header", FrontendOptions::IK_CXX)
+      .Case("objective-c++-header", FrontendOptions::IK_ObjCXX)
+      .Case("ast", FrontendOptions::IK_AST)
+      .Default(FrontendOptions::IK_None);
+    if (DashX == FrontendOptions::IK_None)
+      Diags.Report(diag::err_drv_invalid_value)
+        << A->getAsString(Args) << A->getValue(Args);
+  }
+
+  // '-' is the default input if none is given.
+  std::vector<std::string> Inputs = getAllArgValues(Args, OPT_INPUT);
+  Opts.Inputs.clear();
+  if (Inputs.empty())
+    Inputs.push_back("-");
+  for (unsigned i = 0, e = Inputs.size(); i != e; ++i) {
+    FrontendOptions::InputKind IK = DashX;
+    if (IK == FrontendOptions::IK_None) {
+      IK = FrontendOptions::getInputKindForExtension(
+        llvm::StringRef(Inputs[i]).rsplit('.').second);
+      // FIXME: Remove this hack.
+      if (i == 0)
+        DashX = IK;
+    }
+    Opts.Inputs.push_back(std::make_pair(IK, Inputs[i]));
+  }
+
+  return DashX;
+}
+
+std::string CompilerInvocation::GetResourcesPath(const char *Argv0,
+                                                 void *MainAddr) {
+  llvm::sys::Path P = llvm::sys::Path::GetMainExecutable(Argv0, MainAddr);
+
+  if (!P.isEmpty()) {
+    P.eraseComponent();  // Remove /clang from foo/bin/clang
+    P.eraseComponent();  // Remove /bin   from foo/bin
+
+    // Get foo/lib/clang/<version>/include
+    P.appendComponent("lib");
+    P.appendComponent("clang");
+    P.appendComponent(CLANG_VERSION_STRING);
+  }
+
+  return P.str();
+}
+
+static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args) {
+  using namespace cc1options;
+  Opts.Sysroot = getLastArgValue(Args, OPT_isysroot, "/");
+  Opts.Verbose = Args.hasArg(OPT_v);
+  Opts.UseBuiltinIncludes = !Args.hasArg(OPT_nobuiltininc);
+  Opts.UseStandardIncludes = !Args.hasArg(OPT_nostdinc);
+  Opts.UseStandardCXXIncludes = !Args.hasArg(OPT_nostdincxx);
+  Opts.ResourceDir = getLastArgValue(Args, OPT_resource_dir);
+
+  // Add -I... and -F... options in order.
+  for (arg_iterator it = Args.filtered_begin(OPT_I, OPT_F),
+         ie = Args.filtered_end(); it != ie; ++it)
+    Opts.AddPath(it->getValue(Args), frontend::Angled, true,
+                 /*IsFramework=*/ it->getOption().matches(OPT_F));
+
+  // Add -iprefix/-iwith-prefix/-iwithprefixbefore options.
+  llvm::StringRef Prefix = ""; // FIXME: This isn't the correct default prefix.
+  for (arg_iterator it = Args.filtered_begin(OPT_iprefix, OPT_iwithprefix,
+                                             OPT_iwithprefixbefore),
+         ie = Args.filtered_end(); it != ie; ++it) {
+    if (it->getOption().matches(OPT_iprefix))
+      Prefix = it->getValue(Args);
+    else if (it->getOption().matches(OPT_iwithprefix))
+      Opts.AddPath(Prefix.str() + it->getValue(Args),
+                   frontend::System, false, false);
+    else
+      Opts.AddPath(Prefix.str() + it->getValue(Args),
+                   frontend::Angled, false, false);
+  }
+
+  for (arg_iterator it = Args.filtered_begin(OPT_idirafter),
+         ie = Args.filtered_end(); it != ie; ++it)
+    Opts.AddPath(it->getValue(Args), frontend::After, true, false);
+  for (arg_iterator it = Args.filtered_begin(OPT_iquote),
+         ie = Args.filtered_end(); it != ie; ++it)
+    Opts.AddPath(it->getValue(Args), frontend::Quoted, true, false);
+  for (arg_iterator it = Args.filtered_begin(OPT_isystem),
+         ie = Args.filtered_end(); it != ie; ++it)
+    Opts.AddPath(it->getValue(Args), frontend::System, true, false);
+
+  // FIXME: Need options for the various environment variables!
+}
+
+static void ParseLangArgs(LangOptions &Opts, ArgList &Args,
+                          FrontendOptions::InputKind IK,
+                          Diagnostic &Diags) {
+  // FIXME: Cleanup per-file based stuff.
+
+  // Set some properties which depend soley on the input kind; it would be nice
+  // to move these to the language standard, and have the driver resolve the
+  // input kind + language standard.
+  if (IK == FrontendOptions::IK_Asm) {
+    Opts.AsmPreprocessor = 1;
+  } else if (IK == FrontendOptions::IK_ObjC ||
+             IK == FrontendOptions::IK_ObjCXX ||
+             IK == FrontendOptions::IK_PreprocessedObjC ||
+             IK == FrontendOptions::IK_PreprocessedObjCXX) {
+    Opts.ObjC1 = Opts.ObjC2 = 1;
+  }
+
+  LangStandard::Kind LangStd = LangStandard::lang_unspecified;
+  if (const Arg *A = Args.getLastArg(OPT_std_EQ)) {
+    LangStd = llvm::StringSwitch<LangStandard::Kind>(A->getValue(Args))
+#define LANGSTANDARD(id, name, desc, features) \
+      .Case(name, LangStandard::lang_##id)
+#include "clang/Frontend/LangStandards.def"
+      .Default(LangStandard::lang_unspecified);
+    if (LangStd == LangStandard::lang_unspecified)
+      Diags.Report(diag::err_drv_invalid_value)
+        << A->getAsString(Args) << A->getValue(Args);
+  }
+
+  if (LangStd == LangStandard::lang_unspecified) {
+    // Based on the base language, pick one.
+    switch (IK) {
+    case FrontendOptions::IK_None:
+    case FrontendOptions::IK_AST:
+      assert(0 && "Invalid input kind!");
+    case FrontendOptions::IK_OpenCL:
+      LangStd = LangStandard::lang_opencl;
+      break;
+    case FrontendOptions::IK_Asm:
+    case FrontendOptions::IK_C:
+    case FrontendOptions::IK_PreprocessedC:
+    case FrontendOptions::IK_ObjC:
+    case FrontendOptions::IK_PreprocessedObjC:
+      LangStd = LangStandard::lang_gnu99;
+      break;
+    case FrontendOptions::IK_CXX:
+    case FrontendOptions::IK_PreprocessedCXX:
+    case FrontendOptions::IK_ObjCXX:
+    case FrontendOptions::IK_PreprocessedObjCXX:
+      LangStd = LangStandard::lang_gnucxx98;
+      break;
+    }
+  }
+
+  const LangStandard &Std = LangStandard::getLangStandardForKind(LangStd);
+  Opts.BCPLComment = Std.hasBCPLComments();
+  Opts.C99 = Std.isC99();
+  Opts.CPlusPlus = Std.isCPlusPlus();
+  Opts.CPlusPlus0x = Std.isCPlusPlus0x();
+  Opts.Digraphs = Std.hasDigraphs();
+  Opts.GNUMode = Std.isGNUMode();
+  Opts.GNUInline = !Std.isC99();
+  Opts.HexFloats = Std.hasHexFloats();
+  Opts.ImplicitInt = Std.hasImplicitInt();
+
+  // OpenCL has some additional defaults.
+  if (LangStd == LangStandard::lang_opencl) {
+    Opts.OpenCL = 1;
+    Opts.AltiVec = 1;
+    Opts.CXXOperatorNames = 1;
+    Opts.LaxVectorConversions = 1;
+  }
+
+  // OpenCL and C++ both have bool, true, false keywords.
+  Opts.Bool = Opts.OpenCL || Opts.CPlusPlus;
+
+  // We abuse '-f[no-]gnu-keywords' to force overriding all GNU-extension
+  // keywords. This behavior is provided by GCC's poorly named '-fasm' flag,
+  // while a subset (the non-C++ GNU keywords) is provided by GCC's
+  // '-fgnu-keywords'. Clang conflates the two for simplicity under the single
+  // name, as it doesn't seem a useful distinction.
+  Opts.GNUKeywords = Args.hasFlag(OPT_fgnu_keywords, OPT_fno_gnu_keywords,
+                                  Opts.GNUMode);
+
+  if (Opts.CPlusPlus)
+    Opts.CXXOperatorNames = !Args.hasArg(OPT_fno_operator_names);
+
+  if (Args.hasArg(OPT_fobjc_gc_only))
+    Opts.setGCMode(LangOptions::GCOnly);
+  else if (Args.hasArg(OPT_fobjc_gc))
+    Opts.setGCMode(LangOptions::HybridGC);
+
+  if (Args.hasArg(OPT_print_ivar_layout))
+    Opts.ObjCGCBitmapPrint = 1;
+  if (Args.hasArg(OPT_fno_constant_cfstrings))
+    Opts.NoConstantCFStrings = 1;
+
+  if (Args.hasArg(OPT_faltivec))
+    Opts.AltiVec = 1;
+
+  if (Args.hasArg(OPT_pthread))
+    Opts.POSIXThreads = 1;
+
+  llvm::StringRef Vis = getLastArgValue(Args, OPT_fvisibility,
+                                        "default");
+  if (Vis == "default")
+    Opts.setVisibilityMode(LangOptions::Default);
+  else if (Vis == "hidden")
+    Opts.setVisibilityMode(LangOptions::Hidden);
+  else if (Vis == "protected")
+    Opts.setVisibilityMode(LangOptions::Protected);
+  else
+    Diags.Report(diag::err_drv_invalid_value)
+      << Args.getLastArg(OPT_fvisibility)->getAsString(Args) << Vis;
+
+  Opts.OverflowChecking = Args.hasArg(OPT_ftrapv);
+
+  // Mimicing gcc's behavior, trigraphs are only enabled if -trigraphs
+  // is specified, or -std is set to a conforming mode.
+  Opts.Trigraphs = !Opts.GNUMode;
+  if (Args.hasArg(OPT_trigraphs))
+    Opts.Trigraphs = 1;
+
+  Opts.DollarIdents = Args.hasFlag(OPT_fdollars_in_identifiers,
+                                   OPT_fno_dollars_in_identifiers,
+                                   !Opts.AsmPreprocessor);
+  Opts.PascalStrings = Args.hasArg(OPT_fpascal_strings);
+  Opts.Microsoft = Args.hasArg(OPT_fms_extensions);
+  Opts.WritableStrings = Args.hasArg(OPT_fwritable_strings);
+  Opts.ConstStrings = Args.hasArg(OPT_Wwrite_strings);
+  if (Args.hasArg(OPT_fno_lax_vector_conversions))
+    Opts.LaxVectorConversions = 0;
+  if (Args.hasArg(OPT_fno_threadsafe_statics))
+    Opts.ThreadsafeStatics = 0;
+  Opts.Exceptions = Args.hasArg(OPT_fexceptions);
+  Opts.RTTI = !Args.hasArg(OPT_fno_rtti);
+  Opts.Blocks = Args.hasArg(OPT_fblocks);
+  Opts.CharIsSigned = !Args.hasArg(OPT_fno_signed_char);
+  Opts.ShortWChar = Args.hasArg(OPT_fshort_wchar);
+  Opts.Freestanding = Args.hasArg(OPT_ffreestanding);
+  Opts.NoBuiltin = Args.hasArg(OPT_fno_builtin) || Opts.Freestanding;
+  Opts.AssumeSaneOperatorNew = !Args.hasArg(OPT_fno_assume_sane_operator_new);
+  Opts.HeinousExtensions = Args.hasArg(OPT_fheinous_gnu_extensions);
+  Opts.AccessControl = !Args.hasArg(OPT_fno_access_control);
+  Opts.ElideConstructors = !Args.hasArg(OPT_fno_elide_constructors);
+  Opts.MathErrno = Args.hasArg(OPT_fmath_errno);
+  Opts.InstantiationDepth = getLastArgIntValue(Args, OPT_ftemplate_depth, 99,
+                                               Diags);
+  Opts.NeXTRuntime = !Args.hasArg(OPT_fgnu_runtime);
+  Opts.ObjCConstantStringClass = getLastArgValue(Args,
+                                                 OPT_fconstant_string_class);
+  Opts.ObjCNonFragileABI = Args.hasArg(OPT_fobjc_nonfragile_abi);
+  Opts.ObjCNonFragileABI2 = Args.hasArg(OPT_fobjc_nonfragile_abi2);
+  if (Opts.ObjCNonFragileABI2)
+    Opts.ObjCNonFragileABI = true;
+  Opts.CatchUndefined = Args.hasArg(OPT_fcatch_undefined_behavior);
+  Opts.EmitAllDecls = Args.hasArg(OPT_femit_all_decls);
+  Opts.PICLevel = getLastArgIntValue(Args, OPT_pic_level, 0, Diags);
+  Opts.SjLjExceptions = Args.hasArg(OPT_fsjlj_exceptions);
+  Opts.Static = Args.hasArg(OPT_static_define);
+  Opts.DumpRecordLayouts = Args.hasArg(OPT_fdump_record_layouts);
+  Opts.DumpVTableLayouts = Args.hasArg(OPT_fdump_vtable_layouts);
+  Opts.NoBitFieldTypeAlign = Args.hasArg(OPT_fno_bitfield_type_align);
+  Opts.OptimizeSize = 0;
+
+  // FIXME: Eliminate this dependency.
+  unsigned Opt =
+    Args.hasArg(OPT_Os) ? 2 : getLastArgIntValue(Args, OPT_O, 0, Diags);
+  Opts.Optimize = Opt != 0;
+
+  // This is the __NO_INLINE__ define, which just depends on things like the
+  // optimization level and -fno-inline, not actually whether the backend has
+  // inlining enabled.
+  //
+  // FIXME: This is affected by other options (-fno-inline).
+  Opts.NoInline = !Opt;
+
+  unsigned SSP = getLastArgIntValue(Args, OPT_stack_protector, 0, Diags);
+  switch (SSP) {
+  default:
+    Diags.Report(diag::err_drv_invalid_value)
+      << Args.getLastArg(OPT_stack_protector)->getAsString(Args) << SSP;
+    break;
+  case 0: Opts.setStackProtectorMode(LangOptions::SSPOff); break;
+  case 1: Opts.setStackProtectorMode(LangOptions::SSPOn);  break;
+  case 2: Opts.setStackProtectorMode(LangOptions::SSPReq); break;
+  }
+}
+
+static void ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args,
+                                  Diagnostic &Diags) {
+  using namespace cc1options;
+  Opts.ImplicitPCHInclude = getLastArgValue(Args, OPT_include_pch);
+  Opts.ImplicitPTHInclude = getLastArgValue(Args, OPT_include_pth);
+  if (const Arg *A = Args.getLastArg(OPT_token_cache))
+      Opts.TokenCache = A->getValue(Args);
+  else
+    Opts.TokenCache = Opts.ImplicitPTHInclude;
+  Opts.UsePredefines = !Args.hasArg(OPT_undef);
+  Opts.DetailedRecord = Args.hasArg(OPT_detailed_preprocessing_record);
+  // Add macros from the command line.
+  for (arg_iterator it = Args.filtered_begin(OPT_D, OPT_U),
+         ie = Args.filtered_end(); it != ie; ++it) {
+    if (it->getOption().matches(OPT_D))
+      Opts.addMacroDef(it->getValue(Args));
+    else
+      Opts.addMacroUndef(it->getValue(Args));
+  }
+
+  Opts.MacroIncludes = getAllArgValues(Args, OPT_imacros);
+
+  // Add the ordered list of -includes.
+  for (arg_iterator it = Args.filtered_begin(OPT_include, OPT_include_pch,
+                                             OPT_include_pth),
+         ie = Args.filtered_end(); it != ie; ++it) {
+    // PCH is handled specially, we need to extra the original include path.
+    if (it->getOption().matches(OPT_include_pch)) {
+      std::string OriginalFile =
+        PCHReader::getOriginalSourceFile(it->getValue(Args), Diags);
+      if (OriginalFile.empty())
+        continue;
+
+      Opts.Includes.push_back(OriginalFile);
+    } else
+      Opts.Includes.push_back(it->getValue(Args));
+  }
+
+  // Include 'altivec.h' if -faltivec option present
+  if (Args.hasArg(OPT_faltivec))
+    Opts.Includes.push_back("altivec.h");
+
+  for (arg_iterator it = Args.filtered_begin(OPT_remap_file),
+         ie = Args.filtered_end(); it != ie; ++it) {
+    std::pair<llvm::StringRef,llvm::StringRef> Split =
+      llvm::StringRef(it->getValue(Args)).split(';');
+
+    if (Split.second.empty()) {
+      Diags.Report(diag::err_drv_invalid_remap_file) << it->getAsString(Args);
+      continue;
+    }
+
+    Opts.addRemappedFile(Split.first, Split.second);
+  }
+}
+
+static void ParsePreprocessorOutputArgs(PreprocessorOutputOptions &Opts,
+                                        ArgList &Args) {
+  using namespace cc1options;
+  Opts.ShowCPP = !Args.hasArg(OPT_dM);
+  Opts.ShowMacros = Args.hasArg(OPT_dM) || Args.hasArg(OPT_dD);
+  Opts.ShowLineMarkers = !Args.hasArg(OPT_P);
+  Opts.ShowComments = Args.hasArg(OPT_C);
+  Opts.ShowMacroComments = Args.hasArg(OPT_CC);
+}
+
+static void ParseTargetArgs(TargetOptions &Opts, ArgList &Args) {
+  using namespace cc1options;
+  Opts.ABI = getLastArgValue(Args, OPT_target_abi);
+  Opts.CPU = getLastArgValue(Args, OPT_target_cpu);
+  Opts.Triple = getLastArgValue(Args, OPT_triple);
+  Opts.Features = getAllArgValues(Args, OPT_target_feature);
+
+  // Use the host triple if unspecified.
+  if (Opts.Triple.empty())
+    Opts.Triple = llvm::sys::getHostTriple();
+}
+
+//
+
+void CompilerInvocation::CreateFromArgs(CompilerInvocation &Res,
+                                        const char **ArgBegin,
+                                        const char **ArgEnd,
+                                        Diagnostic &Diags) {
+  // Parse the arguments.
+  llvm::OwningPtr<OptTable> Opts(createCC1OptTable());
+  unsigned MissingArgIndex, MissingArgCount;
+  llvm::OwningPtr<InputArgList> Args(
+    Opts->ParseArgs(ArgBegin, ArgEnd,MissingArgIndex, MissingArgCount));
+
+  // Check for missing argument error.
+  if (MissingArgCount)
+    Diags.Report(diag::err_drv_missing_argument)
+      << Args->getArgString(MissingArgIndex) << MissingArgCount;
+
+  // Issue errors on unknown arguments.
+  for (arg_iterator it = Args->filtered_begin(OPT_UNKNOWN),
+         ie = Args->filtered_end(); it != ie; ++it)
+    Diags.Report(diag::err_drv_unknown_argument) << it->getAsString(*Args);
+
+  ParseAnalyzerArgs(Res.getAnalyzerOpts(), *Args, Diags);
+  ParseCodeGenArgs(Res.getCodeGenOpts(), *Args, Diags);
+  ParseDependencyOutputArgs(Res.getDependencyOutputOpts(), *Args);
+  ParseDiagnosticArgs(Res.getDiagnosticOpts(), *Args, Diags);
+  FrontendOptions::InputKind DashX =
+    ParseFrontendArgs(Res.getFrontendOpts(), *Args, Diags);
+  ParseHeaderSearchArgs(Res.getHeaderSearchOpts(), *Args);
+  if (DashX != FrontendOptions::IK_AST)
+    ParseLangArgs(Res.getLangOpts(), *Args, DashX, Diags);
+  ParsePreprocessorArgs(Res.getPreprocessorOpts(), *Args, Diags);
+  ParsePreprocessorOutputArgs(Res.getPreprocessorOutputOpts(), *Args);
+  ParseTargetArgs(Res.getTargetOpts(), *Args);
+}
diff --git a/lib/Frontend/DeclXML.cpp b/lib/Frontend/DeclXML.cpp
new file mode 100644
index 0000000..8750b1e
--- /dev/null
+++ b/lib/Frontend/DeclXML.cpp
@@ -0,0 +1,149 @@
+//===--- DeclXML.cpp - XML implementation for Decl ASTs -------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the XML document class, which provides the means to
+// dump out the AST in a XML form that exposes type details and other fields.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/DocumentXML.h"
+#include "clang/AST/DeclVisitor.h"
+#include "clang/AST/Expr.h"
+
+namespace clang {
+
+//---------------------------------------------------------
+class DocumentXML::DeclPrinter : public DeclVisitor<DocumentXML::DeclPrinter> {
+  DocumentXML& Doc;
+
+  void addSubNodes(FunctionDecl* FD) {
+    for (unsigned i = 0, e = FD->getNumParams(); i != e; ++i) {
+      Visit(FD->getParamDecl(i));
+      Doc.toParent();
+    }
+  }
+
+  void addFunctionBody(FunctionDecl* FD) {
+    if (FD->isThisDeclarationADefinition()) {
+      Doc.addSubNode("Body");
+      Doc.PrintStmt(FD->getBody());
+      Doc.toParent();
+    }
+  }
+
+  void addSubNodes(RecordDecl* RD) {
+    for (RecordDecl::field_iterator i = RD->field_begin(),
+                                    e = RD->field_end(); i != e; ++i) {
+      Visit(*i);
+      Doc.toParent();
+    }
+  }
+
+  void addSubNodes(CXXRecordDecl* RD) {
+    addSubNodes(cast<RecordDecl>(RD));
+    for (CXXRecordDecl::method_iterator i = RD->method_begin(),
+                                        e = RD->method_end(); i != e; ++i) {
+      Visit(*i);
+      Doc.toParent();
+    }
+  }
+
+  void addSubNodes(EnumDecl* ED) {
+    for (EnumDecl::enumerator_iterator i = ED->enumerator_begin(),
+                                       e = ED->enumerator_end(); i != e; ++i) {
+      Visit(*i);
+      Doc.toParent();
+    }
+  }
+
+  void addSubNodes(EnumConstantDecl* ECD) {
+    if (ECD->getInitExpr())
+      Doc.PrintStmt(ECD->getInitExpr());
+  }
+
+  void addSubNodes(FieldDecl* FdD)  {
+    if (FdD->isBitField())
+      Doc.PrintStmt(FdD->getBitWidth());
+  }
+
+  void addSubNodes(VarDecl* V) {
+    if (V->getInit())
+      Doc.PrintStmt(V->getInit());
+  }
+
+  void addSubNodes(ParmVarDecl* argDecl) {
+    if (argDecl->getDefaultArg())
+      Doc.PrintStmt(argDecl->getDefaultArg());
+  }
+
+  void addSpecialAttribute(const char* pName, EnumDecl* ED) {
+    const QualType& enumType = ED->getIntegerType();
+    if (!enumType.isNull())
+      Doc.addAttribute(pName, enumType);
+  }
+
+  void addIdAttribute(LinkageSpecDecl* ED) {
+    Doc.addAttribute("id", ED);
+  }
+
+  void addIdAttribute(NamedDecl* ND) {
+    Doc.addAttribute("id", ND);
+  }
+
+public:
+  DeclPrinter(DocumentXML& doc) : Doc(doc) {}
+
+#define NODE_XML( CLASS, NAME )          \
+  void Visit##CLASS(CLASS* T)            \
+  {                                      \
+    Doc.addSubNode(NAME);
+
+#define ID_ATTRIBUTE_XML                  addIdAttribute(T);
+#define ATTRIBUTE_XML( FN, NAME )         Doc.addAttribute(NAME, T->FN);
+#define ATTRIBUTE_OPT_XML( FN, NAME )     Doc.addAttributeOptional(NAME, T->FN);
+#define ATTRIBUTE_FILE_LOCATION_XML       Doc.addLocation(T->getLocation());
+#define ATTRIBUTE_SPECIAL_XML( FN, NAME ) addSpecialAttribute(NAME, T);
+
+#define ATTRIBUTE_ENUM_XML( FN, NAME )  \
+  {                                     \
+    const char* pAttributeName = NAME;  \
+    const bool optional = false;             \
+    switch (T->FN) {                    \
+    default: assert(0 && "unknown enum value");
+
+#define ATTRIBUTE_ENUM_OPT_XML( FN, NAME )  \
+  {                                     \
+    const char* pAttributeName = NAME;  \
+    const bool optional = true;              \
+    switch (T->FN) {                    \
+    default: assert(0 && "unknown enum value");
+
+#define ENUM_XML( VALUE, NAME )         case VALUE: if ((!optional) || NAME[0]) Doc.addAttribute(pAttributeName, NAME); break;
+#define END_ENUM_XML                    } }
+#define END_NODE_XML                    }
+
+#define SUB_NODE_XML( CLASS )           addSubNodes(T);
+#define SUB_NODE_SEQUENCE_XML( CLASS )  addSubNodes(T);
+#define SUB_NODE_OPT_XML( CLASS )       addSubNodes(T);
+
+#define SUB_NODE_FN_BODY_XML            addFunctionBody(T);
+
+#include "clang/Frontend/DeclXML.def"
+};
+
+
+//---------------------------------------------------------
+void DocumentXML::writeDeclToXML(Decl *D) {
+  DeclPrinter(*this).Visit(D);
+  toParent();
+}
+
+//---------------------------------------------------------
+} // NS clang
+
diff --git a/lib/Frontend/DependencyFile.cpp b/lib/Frontend/DependencyFile.cpp
new file mode 100644
index 0000000..14aee35
--- /dev/null
+++ b/lib/Frontend/DependencyFile.cpp
@@ -0,0 +1,174 @@
+//===--- DependencyFile.cpp - Generate dependency file --------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This code generates dependency files.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/Utils.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Frontend/DependencyOutputOptions.h"
+#include "clang/Frontend/FrontendDiagnostic.h"
+#include "clang/Lex/DirectoryLookup.h"
+#include "clang/Lex/PPCallbacks.h"
+#include "clang/Lex/Preprocessor.h"
+#include "llvm/ADT/StringSet.h"
+#include "llvm/Support/raw_ostream.h"
+#include <string>
+
+using namespace clang;
+
+namespace {
+class DependencyFileCallback : public PPCallbacks {
+  std::vector<std::string> Files;
+  llvm::StringSet<> FilesSet;
+  const Preprocessor *PP;
+  std::vector<std::string> Targets;
+  llvm::raw_ostream *OS;
+  bool IncludeSystemHeaders;
+  bool PhonyTarget;
+private:
+  bool FileMatchesDepCriteria(const char *Filename,
+                              SrcMgr::CharacteristicKind FileType);
+  void OutputDependencyFile();
+
+public:
+  DependencyFileCallback(const Preprocessor *_PP,
+                         llvm::raw_ostream *_OS,
+                         const DependencyOutputOptions &Opts)
+    : PP(_PP), Targets(Opts.Targets), OS(_OS),
+      IncludeSystemHeaders(Opts.IncludeSystemHeaders),
+      PhonyTarget(Opts.UsePhonyTargets) {}
+
+  virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,
+                           SrcMgr::CharacteristicKind FileType);
+
+  virtual void EndOfMainFile() {
+    OutputDependencyFile();
+    OS->flush();
+    delete OS;
+    OS = 0;
+  }
+};
+}
+
+void clang::AttachDependencyFileGen(Preprocessor &PP,
+                                    const DependencyOutputOptions &Opts) {
+  if (Opts.Targets.empty()) {
+    PP.getDiagnostics().Report(diag::err_fe_dependency_file_requires_MT);
+    return;
+  }
+
+  std::string Err;
+  llvm::raw_ostream *OS(new llvm::raw_fd_ostream(Opts.OutputFile.c_str(), Err));
+  if (!Err.empty()) {
+    PP.getDiagnostics().Report(diag::err_fe_error_opening)
+      << Opts.OutputFile << Err;
+    return;
+  }
+
+  PP.addPPCallbacks(new DependencyFileCallback(&PP, OS, Opts));
+}
+
+/// FileMatchesDepCriteria - Determine whether the given Filename should be
+/// considered as a dependency.
+bool DependencyFileCallback::FileMatchesDepCriteria(const char *Filename,
+                                          SrcMgr::CharacteristicKind FileType) {
+  if (strcmp("<built-in>", Filename) == 0)
+    return false;
+
+  if (IncludeSystemHeaders)
+    return true;
+
+  return FileType == SrcMgr::C_User;
+}
+
+void DependencyFileCallback::FileChanged(SourceLocation Loc,
+                                         FileChangeReason Reason,
+                                         SrcMgr::CharacteristicKind FileType) {
+  if (Reason != PPCallbacks::EnterFile)
+    return;
+
+  // Dependency generation really does want to go all the way to the
+  // file entry for a source location to find out what is depended on.
+  // We do not want #line markers to affect dependency generation!
+  SourceManager &SM = PP->getSourceManager();
+
+  const FileEntry *FE =
+    SM.getFileEntryForID(SM.getFileID(SM.getInstantiationLoc(Loc)));
+  if (FE == 0) return;
+
+  const char *Filename = FE->getName();
+  if (!FileMatchesDepCriteria(Filename, FileType))
+    return;
+
+  // Remove leading "./"
+  if (Filename[0] == '.' && Filename[1] == '/')
+    Filename = &Filename[2];
+
+  if (FilesSet.insert(Filename))
+    Files.push_back(Filename);
+}
+
+void DependencyFileCallback::OutputDependencyFile() {
+  // Write out the dependency targets, trying to avoid overly long
+  // lines when possible. We try our best to emit exactly the same
+  // dependency file as GCC (4.2), assuming the included files are the
+  // same.
+  const unsigned MaxColumns = 75;
+  unsigned Columns = 0;
+
+  for (std::vector<std::string>::iterator
+         I = Targets.begin(), E = Targets.end(); I != E; ++I) {
+    unsigned N = I->length();
+    if (Columns == 0) {
+      Columns += N;
+      *OS << *I;
+    } else if (Columns + N + 2 > MaxColumns) {
+      Columns = N + 2;
+      *OS << " \\\n  " << *I;
+    } else {
+      Columns += N + 1;
+      *OS << ' ' << *I;
+    }
+  }
+
+  *OS << ':';
+  Columns += 1;
+
+  // Now add each dependency in the order it was seen, but avoiding
+  // duplicates.
+  for (std::vector<std::string>::iterator I = Files.begin(),
+         E = Files.end(); I != E; ++I) {
+    // Start a new line if this would exceed the column limit. Make
+    // sure to leave space for a trailing " \" in case we need to
+    // break the line on the next iteration.
+    unsigned N = I->length();
+    if (Columns + (N + 1) + 2 > MaxColumns) {
+      *OS << " \\\n ";
+      Columns = 2;
+    }
+    *OS << ' ' << *I;
+    Columns += N + 1;
+  }
+  *OS << '\n';
+
+  // Create phony targets if requested.
+  if (PhonyTarget) {
+    // Skip the first entry, this is always the input file itself.
+    for (std::vector<std::string>::iterator I = Files.begin() + 1,
+           E = Files.end(); I != E; ++I) {
+      *OS << '\n';
+      *OS << *I << ":\n";
+    }
+  }
+}
+
diff --git a/lib/Frontend/DiagChecker.cpp b/lib/Frontend/DiagChecker.cpp
new file mode 100644
index 0000000..a50cc99
--- /dev/null
+++ b/lib/Frontend/DiagChecker.cpp
@@ -0,0 +1,301 @@
+//===--- DiagChecker.cpp - Diagnostic Checking Functions ------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Process the input files and check that the diagnostic messages are expected.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/Utils.h"
+#include "clang/Frontend/TextDiagnosticBuffer.h"
+#include "clang/Sema/ParseAST.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Lex/Preprocessor.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace clang;
+
+typedef TextDiagnosticBuffer::DiagList DiagList;
+typedef TextDiagnosticBuffer::const_iterator const_diag_iterator;
+
+static void EmitError(Preprocessor &PP, SourceLocation Pos, const char *String){
+  unsigned ID = PP.getDiagnostics().getCustomDiagID(Diagnostic::Error, String);
+  PP.Diag(Pos, ID);
+}
+
+
+// USING THE DIAGNOSTIC CHECKER:
+//
+// Indicating that a line expects an error or a warning is simple. Put a comment
+// on the line that has the diagnostic, use "expected-{error,warning}" to tag
+// if it's an expected error or warning, and place the expected text between {{
+// and }} markers. The full text doesn't have to be included, only enough to
+// ensure that the correct diagnostic was emitted.
+//
+// Here's an example:
+//
+//   int A = B; // expected-error {{use of undeclared identifier 'B'}}
+//
+// You can place as many diagnostics on one line as you wish. To make the code
+// more readable, you can use slash-newline to separate out the diagnostics.
+//
+// The simple syntax above allows each specification to match exactly one error.
+// You can use the extended syntax to customize this. The extended syntax is
+// "expected-<type> <n> {{diag text}}", where <type> is one of "error",
+// "warning" or "note", and <n> is a positive integer. This allows the
+// diagnostic to appear as many times as specified. Example:
+//
+//   void f(); // expected-note 2 {{previous declaration is here}}
+//
+
+/// FindDiagnostics - Go through the comment and see if it indicates expected
+/// diagnostics. If so, then put them in a diagnostic list.
+///
+static void FindDiagnostics(const char *CommentStart, unsigned CommentLen,
+                            DiagList &ExpectedDiags,
+                            Preprocessor &PP, SourceLocation Pos,
+                            const char *ExpectedStr) {
+  const char *CommentEnd = CommentStart+CommentLen;
+  unsigned ExpectedStrLen = strlen(ExpectedStr);
+
+  // Find all expected-foo diagnostics in the string and add them to
+  // ExpectedDiags.
+  while (CommentStart != CommentEnd) {
+    CommentStart = std::find(CommentStart, CommentEnd, 'e');
+    if (unsigned(CommentEnd-CommentStart) < ExpectedStrLen) return;
+
+    // If this isn't expected-foo, ignore it.
+    if (memcmp(CommentStart, ExpectedStr, ExpectedStrLen)) {
+      ++CommentStart;
+      continue;
+    }
+
+    CommentStart += ExpectedStrLen;
+
+    // Skip whitespace.
+    while (CommentStart != CommentEnd &&
+           isspace(CommentStart[0]))
+      ++CommentStart;
+
+    // Default, if we find the '{' now, is 1 time.
+    int Times = 1;
+    int Temp = 0;
+    // In extended syntax, there could be a digit now.
+    while (CommentStart != CommentEnd &&
+           CommentStart[0] >= '0' && CommentStart[0] <= '9') {
+      Temp *= 10;
+      Temp += CommentStart[0] - '0';
+      ++CommentStart;
+    }
+    if (Temp > 0)
+      Times = Temp;
+
+    // Skip whitespace again.
+    while (CommentStart != CommentEnd &&
+           isspace(CommentStart[0]))
+      ++CommentStart;
+
+    // We should have a {{ now.
+    if (CommentEnd-CommentStart < 2 ||
+        CommentStart[0] != '{' || CommentStart[1] != '{') {
+      if (std::find(CommentStart, CommentEnd, '{') != CommentEnd)
+        EmitError(PP, Pos, "bogus characters before '{{' in expected string");
+      else
+        EmitError(PP, Pos, "cannot find start ('{{') of expected string");
+      return;
+    }
+    CommentStart += 2;
+
+    // Find the }}.
+    const char *ExpectedEnd = CommentStart;
+    while (1) {
+      ExpectedEnd = std::find(ExpectedEnd, CommentEnd, '}');
+      if (CommentEnd-ExpectedEnd < 2) {
+        EmitError(PP, Pos, "cannot find end ('}}') of expected string");
+        return;
+      }
+
+      if (ExpectedEnd[1] == '}')
+        break;
+
+      ++ExpectedEnd;  // Skip over singular }'s
+    }
+
+    std::string Msg(CommentStart, ExpectedEnd);
+    std::string::size_type FindPos;
+    while ((FindPos = Msg.find("\\n")) != std::string::npos)
+      Msg.replace(FindPos, 2, "\n");
+    // Add is possibly multiple times.
+    for (int i = 0; i < Times; ++i)
+      ExpectedDiags.push_back(std::make_pair(Pos, Msg));
+
+    CommentStart = ExpectedEnd;
+  }
+}
+
+/// FindExpectedDiags - Lex the main source file to find all of the
+//   expected errors and warnings.
+static void FindExpectedDiags(Preprocessor &PP,
+                              DiagList &ExpectedErrors,
+                              DiagList &ExpectedWarnings,
+                              DiagList &ExpectedNotes) {
+  // Create a raw lexer to pull all the comments out of the main file.  We don't
+  // want to look in #include'd headers for expected-error strings.
+  FileID FID = PP.getSourceManager().getMainFileID();
+
+  // Create a lexer to lex all the tokens of the main file in raw mode.
+  const llvm::MemoryBuffer *FromFile = PP.getSourceManager().getBuffer(FID);
+  Lexer RawLex(FID, FromFile, PP.getSourceManager(), PP.getLangOptions());
+
+  // Return comments as tokens, this is how we find expected diagnostics.
+  RawLex.SetCommentRetentionState(true);
+
+  Token Tok;
+  Tok.setKind(tok::comment);
+  while (Tok.isNot(tok::eof)) {
+    RawLex.Lex(Tok);
+    if (!Tok.is(tok::comment)) continue;
+
+    std::string Comment = PP.getSpelling(Tok);
+    if (Comment.empty()) continue;
+
+
+    // Find all expected errors.
+    FindDiagnostics(&Comment[0], Comment.size(), ExpectedErrors, PP,
+                    Tok.getLocation(), "expected-error");
+
+    // Find all expected warnings.
+    FindDiagnostics(&Comment[0], Comment.size(), ExpectedWarnings, PP,
+                    Tok.getLocation(), "expected-warning");
+
+    // Find all expected notes.
+    FindDiagnostics(&Comment[0], Comment.size(), ExpectedNotes, PP,
+                    Tok.getLocation(), "expected-note");
+  };
+}
+
+/// PrintProblem - This takes a diagnostic map of the delta between expected and
+/// seen diagnostics. If there's anything in it, then something unexpected
+/// happened. Print the map out in a nice format and return "true". If the map
+/// is empty and we're not going to print things, then return "false".
+///
+static bool PrintProblem(SourceManager &SourceMgr,
+                         const_diag_iterator diag_begin,
+                         const_diag_iterator diag_end,
+                         const char *Msg) {
+  if (diag_begin == diag_end) return false;
+
+  llvm::errs() << Msg << "\n";
+  for (const_diag_iterator I = diag_begin, E = diag_end; I != E; ++I)
+    llvm::errs() << "  Line " << SourceMgr.getInstantiationLineNumber(I->first)
+                 << " " << I->second << "\n";
+
+  return true;
+}
+
+/// CompareDiagLists - Compare two diagnostic lists and return the difference
+/// between them.
+///
+static bool CompareDiagLists(SourceManager &SourceMgr,
+                             const_diag_iterator d1_begin,
+                             const_diag_iterator d1_end,
+                             const_diag_iterator d2_begin,
+                             const_diag_iterator d2_end,
+                             const char *MsgLeftOnly,
+                             const char *MsgRightOnly) {
+  DiagList LeftOnly;
+  DiagList Left(d1_begin, d1_end);
+  DiagList Right(d2_begin, d2_end);
+
+  for (const_diag_iterator I = Left.begin(), E = Left.end(); I != E; ++I) {
+    unsigned LineNo1 = SourceMgr.getInstantiationLineNumber(I->first);
+    const std::string &Diag1 = I->second;
+
+    DiagList::iterator II, IE;
+    for (II = Right.begin(), IE = Right.end(); II != IE; ++II) {
+      unsigned LineNo2 = SourceMgr.getInstantiationLineNumber(II->first);
+      if (LineNo1 != LineNo2) continue;
+
+      const std::string &Diag2 = II->second;
+      if (Diag2.find(Diag1) != std::string::npos ||
+          Diag1.find(Diag2) != std::string::npos) {
+        break;
+      }
+    }
+    if (II == IE) {
+      // Not found.
+      LeftOnly.push_back(*I);
+    } else {
+      // Found. The same cannot be found twice.
+      Right.erase(II);
+    }
+  }
+  // Now all that's left in Right are those that were not matched.
+
+  return PrintProblem(SourceMgr, LeftOnly.begin(), LeftOnly.end(), MsgLeftOnly)
+       | PrintProblem(SourceMgr, Right.begin(), Right.end(), MsgRightOnly);
+}
+
+/// CheckResults - This compares the expected results to those that
+/// were actually reported. It emits any discrepencies. Return "true" if there
+/// were problems. Return "false" otherwise.
+///
+static bool CheckResults(Preprocessor &PP,
+                         const DiagList &ExpectedErrors,
+                         const DiagList &ExpectedWarnings,
+                         const DiagList &ExpectedNotes) {
+  const DiagnosticClient *DiagClient = PP.getDiagnostics().getClient();
+  assert(DiagClient != 0 &&
+      "DiagChecker requires a valid TextDiagnosticBuffer");
+  const TextDiagnosticBuffer &Diags =
+    static_cast<const TextDiagnosticBuffer&>(*DiagClient);
+  SourceManager &SourceMgr = PP.getSourceManager();
+
+  // We want to capture the delta between what was expected and what was
+  // seen.
+  //
+  //   Expected \ Seen - set expected but not seen
+  //   Seen \ Expected - set seen but not expected
+  bool HadProblem = false;
+
+  // See if there are error mismatches.
+  HadProblem |= CompareDiagLists(SourceMgr,
+                                 ExpectedErrors.begin(), ExpectedErrors.end(),
+                                 Diags.err_begin(), Diags.err_end(),
+                                 "Errors expected but not seen:",
+                                 "Errors seen but not expected:");
+
+  // See if there are warning mismatches.
+  HadProblem |= CompareDiagLists(SourceMgr,
+                                 ExpectedWarnings.begin(),
+                                 ExpectedWarnings.end(),
+                                 Diags.warn_begin(), Diags.warn_end(),
+                                 "Warnings expected but not seen:",
+                                 "Warnings seen but not expected:");
+
+  // See if there are note mismatches.
+  HadProblem |= CompareDiagLists(SourceMgr,
+                                 ExpectedNotes.begin(),
+                                 ExpectedNotes.end(),
+                                 Diags.note_begin(), Diags.note_end(),
+                                 "Notes expected but not seen:",
+                                 "Notes seen but not expected:");
+
+  return HadProblem;
+}
+
+
+/// CheckDiagnostics - Gather the expected diagnostics and check them.
+bool clang::CheckDiagnostics(Preprocessor &PP) {
+  // Gather the set of expected diagnostics.
+  DiagList ExpectedErrors, ExpectedWarnings, ExpectedNotes;
+  FindExpectedDiags(PP, ExpectedErrors, ExpectedWarnings, ExpectedNotes);
+
+  // Check that the expected diagnostics occurred.
+  return CheckResults(PP, ExpectedErrors, ExpectedWarnings, ExpectedNotes);
+}
diff --git a/lib/Frontend/DocumentXML.cpp b/lib/Frontend/DocumentXML.cpp
new file mode 100644
index 0000000..0263c30
--- /dev/null
+++ b/lib/Frontend/DocumentXML.cpp
@@ -0,0 +1,338 @@
+//===--- DocumentXML.cpp - XML document for ASTs --------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the XML document class, which provides the means to
+// dump out the AST in a XML form that exposes type details and other fields.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/DocumentXML.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/Basic/SourceManager.h"
+#include "llvm/ADT/StringExtras.h"
+
+namespace clang {
+
+//---------------------------------------------------------
+DocumentXML::DocumentXML(const std::string& rootName, llvm::raw_ostream& out) :
+  Out(out),
+  Ctx(0),
+  HasCurrentNodeSubNodes(false) {
+  NodeStack.push(rootName);
+  Out << "<?xml version=\"1.0\"?>\n<" << rootName;
+}
+
+//---------------------------------------------------------
+DocumentXML& DocumentXML::addSubNode(const std::string& name) {
+  if (!HasCurrentNodeSubNodes)
+    Out << ">\n";
+  NodeStack.push(name);
+  HasCurrentNodeSubNodes = false;
+  Indent();
+  Out << "<" << NodeStack.top();
+  return *this;
+}
+
+//---------------------------------------------------------
+void DocumentXML::Indent() {
+  for (size_t i = 0, e = (NodeStack.size() - 1) * 2; i < e; ++i)
+    Out << ' ';
+}
+
+//---------------------------------------------------------
+DocumentXML& DocumentXML::toParent() {
+  assert(NodeStack.size() > 1 && "too much backtracking");
+
+  if (HasCurrentNodeSubNodes) {
+    Indent();
+    Out << "</" << NodeStack.top() << ">\n";
+  } else
+    Out << "/>\n";
+  NodeStack.pop();
+  HasCurrentNodeSubNodes = true;
+  return *this;
+}
+
+//---------------------------------------------------------
+namespace {
+
+enum tIdType { ID_NORMAL, ID_FILE, ID_LABEL, ID_LAST };
+
+unsigned getNewId(tIdType idType) {
+  static unsigned int idCounts[ID_LAST] = { 0 };
+  return ++idCounts[idType];
+}
+
+//---------------------------------------------------------
+inline std::string getPrefixedId(unsigned uId, tIdType idType) {
+  static const char idPrefix[ID_LAST] = { '_', 'f', 'l' };
+  char buffer[20];
+  char* BufPtr = llvm::utohex_buffer(uId, buffer + 20);
+  *--BufPtr = idPrefix[idType];
+  return BufPtr;
+}
+
+//---------------------------------------------------------
+template<class T, class V>
+bool addToMap(T& idMap, const V& value, tIdType idType = ID_NORMAL) {
+  typename T::iterator i = idMap.find(value);
+  bool toAdd = i == idMap.end();
+  if (toAdd)
+    idMap.insert(typename T::value_type(value, getNewId(idType)));
+  return toAdd;
+}
+
+} // anon NS
+
+
+//---------------------------------------------------------
+std::string DocumentXML::escapeString(const char* pStr,
+                                      std::string::size_type len) {
+  std::string value;
+  value.reserve(len + 1);
+  char buffer[16];
+  for (unsigned i = 0; i < len; ++i) {
+    switch (char C = pStr[i]) {
+    default:
+      if (isprint(C))
+        value += C;
+      else {
+        sprintf(buffer, "\\%03o", C);
+        value += buffer;
+      }
+      break;
+
+    case '\n': value += "\\n"; break;
+    case '\t': value += "\\t"; break;
+    case '\a': value += "\\a"; break;
+    case '\b': value += "\\b"; break;
+    case '\r': value += "\\r"; break;
+
+    case '&': value += "&amp;"; break;
+    case '<': value += "&lt;"; break;
+    case '>': value += "&gt;"; break;
+    case '"': value += "&quot;"; break;
+    case '\'':  value += "&apos;"; break;
+
+    }
+  }
+  return value;
+}
+
+//---------------------------------------------------------
+void DocumentXML::finalize() {
+  assert(NodeStack.size() == 1 && "not completely backtracked");
+
+  addSubNode("ReferenceSection");
+  addSubNode("Types");
+
+  for (XML::IdMap<QualType>::iterator i = Types.begin(), e = Types.end();
+       i != e; ++i) {
+    if (i->first.hasLocalQualifiers()) {
+      writeTypeToXML(i->first);
+      addAttribute("id", getPrefixedId(i->second, ID_NORMAL));
+      toParent();
+    }
+  }
+
+  for (XML::IdMap<const Type*>::iterator i = BasicTypes.begin(),
+         e = BasicTypes.end(); i != e; ++i) {
+    writeTypeToXML(i->first);
+    addAttribute("id", getPrefixedId(i->second, ID_NORMAL));
+    toParent();
+  }
+
+
+  toParent().addSubNode("Contexts");
+
+  for (XML::IdMap<const DeclContext*>::iterator i = Contexts.begin(),
+         e = Contexts.end(); i != e; ++i) {
+    addSubNode(i->first->getDeclKindName());
+    addAttribute("id", getPrefixedId(i->second, ID_NORMAL));
+    if (const NamedDecl *ND = dyn_cast<NamedDecl>(i->first))
+      addAttribute("name", ND->getNameAsString());
+    if (const TagDecl *TD = dyn_cast<TagDecl>(i->first))
+      addAttribute("type", getPrefixedId(BasicTypes[TD->getTypeForDecl()], ID_NORMAL));
+    else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(i->first))
+      addAttribute("type", getPrefixedId(BasicTypes[FD->getType()->getAs<FunctionType>()], ID_NORMAL));
+
+    if (const DeclContext* parent = i->first->getParent())
+      addAttribute("context", parent);
+    toParent();
+  }
+
+  toParent().addSubNode("Files");
+
+  for (XML::IdMap<std::string>::iterator i = SourceFiles.begin(),
+         e = SourceFiles.end(); i != e; ++i) {
+    addSubNode("File");
+    addAttribute("id", getPrefixedId(i->second, ID_FILE));
+    addAttribute("name", escapeString(i->first.c_str(), i->first.size()));
+    toParent();
+  }
+
+  toParent().toParent();
+
+  // write the root closing node (which has always subnodes)
+  Out << "</" << NodeStack.top() << ">\n";
+}
+
+//---------------------------------------------------------
+void DocumentXML::addAttribute(const char* pAttributeName,
+                               const QualType& pType) {
+  addTypeRecursively(pType);
+  addAttribute(pAttributeName, getPrefixedId(Types[pType], ID_NORMAL));
+}
+
+//---------------------------------------------------------
+void DocumentXML::addPtrAttribute(const char* pAttributeName,
+                                  const Type* pType) {
+  addTypeRecursively(pType);
+  addAttribute(pAttributeName, getPrefixedId(BasicTypes[pType], ID_NORMAL));
+}
+
+//---------------------------------------------------------
+void DocumentXML::addTypeRecursively(const QualType& pType)
+{
+  if (addToMap(Types, pType))
+  {
+    addTypeRecursively(pType.getTypePtr());
+    // beautifier: a non-qualified type shall be transparent
+    if (!pType.hasLocalQualifiers())
+    {
+      Types[pType] = BasicTypes[pType.getTypePtr()];
+    }
+  }
+}
+
+//---------------------------------------------------------
+void DocumentXML::addTypeRecursively(const Type* pType)
+{
+  if (addToMap(BasicTypes, pType))
+  {
+    addParentTypes(pType);
+/*
+    // FIXME: doesn't work in the immediate streaming approach
+    if (const VariableArrayType *VAT = dyn_cast<VariableArrayType>(pType))
+    {
+      addSubNode("VariableArraySizeExpression");
+      PrintStmt(VAT->getSizeExpr());
+      toParent();
+    }
+*/
+  }
+}
+
+//---------------------------------------------------------
+void DocumentXML::addPtrAttribute(const char* pName, const DeclContext* DC)
+{
+  addContextsRecursively(DC);
+  addAttribute(pName, getPrefixedId(Contexts[DC], ID_NORMAL));
+}
+
+//---------------------------------------------------------
+void DocumentXML::addPtrAttribute(const char* pAttributeName, const NamedDecl* D)
+{
+  if (const DeclContext* DC = dyn_cast<DeclContext>(D))
+  {
+    addContextsRecursively(DC);
+    addAttribute(pAttributeName, getPrefixedId(Contexts[DC], ID_NORMAL));
+  }
+  else
+  {
+    addToMap(Decls, D);
+    addAttribute(pAttributeName, getPrefixedId(Decls[D], ID_NORMAL));
+  }
+}
+
+//---------------------------------------------------------
+void DocumentXML::addPtrAttribute(const char* pName, const NamespaceDecl* D)
+{
+  addPtrAttribute(pName, static_cast<const DeclContext*>(D));
+}
+
+//---------------------------------------------------------
+void DocumentXML::addContextsRecursively(const DeclContext *DC)
+{
+  if (DC != 0 && addToMap(Contexts, DC))
+  {
+    addContextsRecursively(DC->getParent());
+  }
+}
+
+//---------------------------------------------------------
+void DocumentXML::addSourceFileAttribute(const std::string& fileName)
+{
+  addToMap(SourceFiles, fileName, ID_FILE);
+  addAttribute("file", getPrefixedId(SourceFiles[fileName], ID_FILE));
+}
+
+
+//---------------------------------------------------------
+void DocumentXML::addPtrAttribute(const char* pName, const LabelStmt* L)
+{
+  addToMap(Labels, L, ID_LABEL);
+  addAttribute(pName, getPrefixedId(Labels[L], ID_LABEL));
+}
+
+
+//---------------------------------------------------------
+PresumedLoc DocumentXML::addLocation(const SourceLocation& Loc)
+{
+  SourceManager& SM = Ctx->getSourceManager();
+  SourceLocation SpellingLoc = SM.getSpellingLoc(Loc);
+  PresumedLoc PLoc;
+  if (!SpellingLoc.isInvalid())
+  {
+    PLoc = SM.getPresumedLoc(SpellingLoc);
+    addSourceFileAttribute(PLoc.getFilename());
+    addAttribute("line", PLoc.getLine());
+    addAttribute("col", PLoc.getColumn());
+  }
+  // else there is no error in some cases (eg. CXXThisExpr)
+  return PLoc;
+}
+
+//---------------------------------------------------------
+void DocumentXML::addLocationRange(const SourceRange& R)
+{
+  PresumedLoc PStartLoc = addLocation(R.getBegin());
+  if (R.getBegin() != R.getEnd())
+  {
+    SourceManager& SM = Ctx->getSourceManager();
+    SourceLocation SpellingLoc = SM.getSpellingLoc(R.getEnd());
+    if (!SpellingLoc.isInvalid())
+    {
+      PresumedLoc PLoc = SM.getPresumedLoc(SpellingLoc);
+      if (PStartLoc.isInvalid() ||
+          strcmp(PLoc.getFilename(), PStartLoc.getFilename()) != 0) {
+        addToMap(SourceFiles, PLoc.getFilename(), ID_FILE);
+        addAttribute("endfile", PLoc.getFilename());
+        addAttribute("endline", PLoc.getLine());
+        addAttribute("endcol", PLoc.getColumn());
+      } else if (PLoc.getLine() != PStartLoc.getLine()) {
+        addAttribute("endline", PLoc.getLine());
+        addAttribute("endcol", PLoc.getColumn());
+      } else {
+        addAttribute("endcol", PLoc.getColumn());
+      }
+    }
+  }
+}
+
+//---------------------------------------------------------
+void DocumentXML::PrintDecl(Decl *D)
+{
+  writeDeclToXML(D);
+}
+
+//---------------------------------------------------------
+} // NS clang
+
diff --git a/lib/Frontend/FixItRewriter.cpp b/lib/Frontend/FixItRewriter.cpp
new file mode 100644
index 0000000..7c9a566
--- /dev/null
+++ b/lib/Frontend/FixItRewriter.cpp
@@ -0,0 +1,167 @@
+//===--- FixItRewriter.cpp - Fix-It Rewriter Diagnostic Client --*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This is a diagnostic client adaptor that performs rewrites as
+// suggested by code modification hints attached to diagnostics. It
+// then forwards any diagnostics to the adapted diagnostic client.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/FixItRewriter.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Frontend/FrontendDiagnostic.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/System/Path.h"
+#include "llvm/ADT/OwningPtr.h"
+#include <cstdio>
+
+using namespace clang;
+
+FixItRewriter::FixItRewriter(Diagnostic &Diags, SourceManager &SourceMgr,
+                             const LangOptions &LangOpts,
+                             FixItPathRewriter *PathRewriter)
+  : Diags(Diags),
+    Rewrite(SourceMgr, LangOpts),
+    PathRewriter(PathRewriter),
+    NumFailures(0) {
+  Client = Diags.getClient();
+  Diags.setClient(this);
+}
+
+FixItRewriter::~FixItRewriter() {
+  Diags.setClient(Client);
+}
+
+bool FixItRewriter::WriteFixedFile(FileID ID, llvm::raw_ostream &OS) {
+  const RewriteBuffer *RewriteBuf = Rewrite.getRewriteBufferFor(ID);
+  if (!RewriteBuf) return true;
+  RewriteBuf->write(OS);
+  OS.flush();
+  return false;
+}
+
+bool FixItRewriter::WriteFixedFiles() {
+  if (NumFailures > 0) {
+    Diag(FullSourceLoc(), diag::warn_fixit_no_changes);
+    return true;
+  }
+
+  for (iterator I = buffer_begin(), E = buffer_end(); I != E; ++I) {
+    const FileEntry *Entry = Rewrite.getSourceMgr().getFileEntryForID(I->first);
+    std::string Filename = Entry->getName();
+    if (PathRewriter)
+      Filename = PathRewriter->RewriteFilename(Filename);
+    std::string Err;
+    llvm::raw_fd_ostream OS(Filename.c_str(), Err,
+                            llvm::raw_fd_ostream::F_Binary);
+    if (!Err.empty()) {
+      Diags.Report(clang::diag::err_fe_unable_to_open_output)
+          << Filename << Err;
+      continue;
+    }
+    RewriteBuffer &RewriteBuf = I->second;
+    RewriteBuf.write(OS);
+    OS.flush();
+  }
+
+  return false;
+}
+
+bool FixItRewriter::IncludeInDiagnosticCounts() const {
+  return Client ? Client->IncludeInDiagnosticCounts() : true;
+}
+
+void FixItRewriter::HandleDiagnostic(Diagnostic::Level DiagLevel,
+                                     const DiagnosticInfo &Info) {
+  Client->HandleDiagnostic(DiagLevel, Info);
+
+  // Skip over any diagnostics that are ignored or notes.
+  if (DiagLevel <= Diagnostic::Note)
+    return;
+
+  // Make sure that we can perform all of the modifications we
+  // in this diagnostic.
+  bool CanRewrite = Info.getNumFixItHints() > 0;
+  for (unsigned Idx = 0, Last = Info.getNumFixItHints();
+       Idx < Last; ++Idx) {
+    const FixItHint &Hint = Info.getFixItHint(Idx);
+    if (Hint.RemoveRange.isValid() &&
+        Rewrite.getRangeSize(Hint.RemoveRange) == -1) {
+      CanRewrite = false;
+      break;
+    }
+
+    if (Hint.InsertionLoc.isValid() &&
+        !Rewrite.isRewritable(Hint.InsertionLoc)) {
+      CanRewrite = false;
+      break;
+    }
+  }
+
+  if (!CanRewrite) {
+    if (Info.getNumFixItHints() > 0)
+      Diag(Info.getLocation(), diag::note_fixit_in_macro);
+
+    // If this was an error, refuse to perform any rewriting.
+    if (DiagLevel == Diagnostic::Error || DiagLevel == Diagnostic::Fatal) {
+      if (++NumFailures == 1)
+        Diag(Info.getLocation(), diag::note_fixit_unfixed_error);
+    }
+    return;
+  }
+
+  bool Failed = false;
+  for (unsigned Idx = 0, Last = Info.getNumFixItHints();
+       Idx < Last; ++Idx) {
+    const FixItHint &Hint = Info.getFixItHint(Idx);
+    if (!Hint.RemoveRange.isValid()) {
+      // We're adding code.
+      if (Rewrite.InsertTextBefore(Hint.InsertionLoc, Hint.CodeToInsert))
+        Failed = true;
+      continue;
+    }
+
+    if (Hint.CodeToInsert.empty()) {
+      // We're removing code.
+      if (Rewrite.RemoveText(Hint.RemoveRange.getBegin(),
+                             Rewrite.getRangeSize(Hint.RemoveRange)))
+        Failed = true;
+      continue;
+    }
+
+    // We're replacing code.
+    if (Rewrite.ReplaceText(Hint.RemoveRange.getBegin(),
+                            Rewrite.getRangeSize(Hint.RemoveRange),
+                            Hint.CodeToInsert))
+      Failed = true;
+  }
+
+  if (Failed) {
+    ++NumFailures;
+    Diag(Info.getLocation(), diag::note_fixit_failed);
+    return;
+  }
+
+  Diag(Info.getLocation(), diag::note_fixit_applied);
+}
+
+/// \brief Emit a diagnostic via the adapted diagnostic client.
+void FixItRewriter::Diag(FullSourceLoc Loc, unsigned DiagID) {
+  // When producing this diagnostic, we temporarily bypass ourselves,
+  // clear out any current diagnostic, and let the downstream client
+  // format the diagnostic.
+  Diags.setClient(Client);
+  Diags.Clear();
+  Diags.Report(Loc, DiagID);
+  Diags.setClient(this);
+}
+
+FixItPathRewriter::~FixItPathRewriter() {}
diff --git a/lib/Frontend/FrontendAction.cpp b/lib/Frontend/FrontendAction.cpp
new file mode 100644
index 0000000..87fc122
--- /dev/null
+++ b/lib/Frontend/FrontendAction.cpp
@@ -0,0 +1,231 @@
+//===--- FrontendAction.cpp -----------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/FrontendAction.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/Lex/HeaderSearch.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Frontend/ASTUnit.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Frontend/FrontendDiagnostic.h"
+#include "clang/Sema/ParseAST.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Timer.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace clang;
+
+FrontendAction::FrontendAction() : Instance(0) {}
+
+FrontendAction::~FrontendAction() {}
+
+void FrontendAction::setCurrentFile(llvm::StringRef Value, ASTUnit *AST) {
+  CurrentFile = Value;
+  CurrentASTUnit.reset(AST);
+}
+
+bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
+                                     llvm::StringRef Filename,
+                                     bool IsAST) {
+  assert(!Instance && "Already processing a source file!");
+  assert(!Filename.empty() && "Unexpected empty filename!");
+  setCurrentFile(Filename);
+  setCompilerInstance(&CI);
+
+  // AST files follow a very different path, since they share objects via the
+  // AST unit.
+  if (IsAST) {
+    assert(!usesPreprocessorOnly() &&
+           "Attempt to pass AST file to preprocessor only action!");
+    assert(hasASTSupport() && "This action does not have AST support!");
+
+    llvm::IntrusiveRefCntPtr<Diagnostic> Diags(&CI.getDiagnostics());
+    std::string Error;
+    ASTUnit *AST = ASTUnit::LoadFromPCHFile(Filename, Diags);
+    if (!AST)
+      goto failure;
+
+    setCurrentFile(Filename, AST);
+
+    // Set the shared objects, these are reset when we finish processing the
+    // file, otherwise the CompilerInstance will happily destroy them.
+    CI.setFileManager(&AST->getFileManager());
+    CI.setSourceManager(&AST->getSourceManager());
+    CI.setPreprocessor(&AST->getPreprocessor());
+    CI.setASTContext(&AST->getASTContext());
+
+    // Initialize the action.
+    if (!BeginSourceFileAction(CI, Filename))
+      goto failure;
+
+    /// Create the AST consumer.
+    CI.setASTConsumer(CreateASTConsumer(CI, Filename));
+    if (!CI.hasASTConsumer())
+      goto failure;
+
+    return true;
+  }
+
+  // Inform the diagnostic client we are processing a source file.
+  CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(),
+                                           &CI.getPreprocessor());
+
+  // Initialize the action.
+  if (!BeginSourceFileAction(CI, Filename))
+    goto failure;
+
+  /// Create the AST context and consumer unless this is a preprocessor only
+  /// action.
+  if (!usesPreprocessorOnly()) {
+    CI.createASTContext();
+    CI.setASTConsumer(CreateASTConsumer(CI, Filename));
+    if (!CI.hasASTConsumer())
+      goto failure;
+
+    /// Use PCH?
+    if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) {
+      assert(hasPCHSupport() && "This action does not have PCH support!");
+      CI.createPCHExternalASTSource(
+        CI.getPreprocessorOpts().ImplicitPCHInclude);
+      if (!CI.getASTContext().getExternalSource())
+        goto failure;
+    }
+  }
+
+  // Initialize builtin info as long as we aren't using an external AST
+  // source.
+  if (!CI.hasASTContext() || !CI.getASTContext().getExternalSource()) {
+    Preprocessor &PP = CI.getPreprocessor();
+    PP.getBuiltinInfo().InitializeBuiltins(PP.getIdentifierTable(),
+                                           PP.getLangOptions().NoBuiltin);
+  }
+
+  return true;
+
+  // If we failed, reset state since the client will not end up calling the
+  // matching EndSourceFile().
+  failure:
+  if (isCurrentFileAST()) {
+    CI.takeASTContext();
+    CI.takePreprocessor();
+    CI.takeSourceManager();
+    CI.takeFileManager();
+  }
+
+  CI.getDiagnosticClient().EndSourceFile();
+  setCurrentFile("");
+  setCompilerInstance(0);
+  return false;
+}
+
+void FrontendAction::Execute() {
+  CompilerInstance &CI = getCompilerInstance();
+
+  // Initialize the main file entry. This needs to be delayed until after PCH
+  // has loaded.
+  if (isCurrentFileAST()) {
+    // Set the main file ID to an empty file.
+    //
+    // FIXME: We probably shouldn't need this, but for now this is the
+    // simplest way to reuse the logic in ParseAST.
+    const char *EmptyStr = "";
+    llvm::MemoryBuffer *SB =
+      llvm::MemoryBuffer::getMemBuffer(EmptyStr, "<dummy input>");
+    CI.getSourceManager().createMainFileIDForMemBuffer(SB);
+  } else {
+    if (!CI.InitializeSourceManager(getCurrentFile()))
+      return;
+  }
+
+  if (CI.hasFrontendTimer()) {
+    llvm::TimeRegion Timer(CI.getFrontendTimer());
+    ExecuteAction();
+  }
+  else ExecuteAction();
+}
+
+void FrontendAction::EndSourceFile() {
+  CompilerInstance &CI = getCompilerInstance();
+
+  // Finalize the action.
+  EndSourceFileAction();
+
+  // Release the consumer and the AST, in that order since the consumer may
+  // perform actions in its destructor which require the context.
+  //
+  // FIXME: There is more per-file stuff we could just drop here?
+  if (CI.getFrontendOpts().DisableFree) {
+    CI.takeASTConsumer();
+    if (!isCurrentFileAST())
+      CI.takeASTContext();
+  } else {
+    CI.setASTConsumer(0);
+    if (!isCurrentFileAST())
+      CI.setASTContext(0);
+  }
+
+  // Inform the preprocessor we are done.
+  if (CI.hasPreprocessor())
+    CI.getPreprocessor().EndSourceFile();
+
+  if (CI.getFrontendOpts().ShowStats) {
+    llvm::errs() << "\nSTATISTICS FOR '" << getCurrentFile() << "':\n";
+    CI.getPreprocessor().PrintStats();
+    CI.getPreprocessor().getIdentifierTable().PrintStats();
+    CI.getPreprocessor().getHeaderSearchInfo().PrintStats();
+    CI.getSourceManager().PrintStats();
+    llvm::errs() << "\n";
+  }
+
+  // Cleanup the output streams, and erase the output files if we encountered
+  // an error.
+  CI.clearOutputFiles(/*EraseFiles=*/CI.getDiagnostics().getNumErrors());
+
+  // Inform the diagnostic client we are done with this source file.
+  CI.getDiagnosticClient().EndSourceFile();
+
+  if (isCurrentFileAST()) {
+    CI.takeASTContext();
+    CI.takePreprocessor();
+    CI.takeSourceManager();
+    CI.takeFileManager();
+  }
+
+  setCompilerInstance(0);
+  setCurrentFile("");
+}
+
+//===----------------------------------------------------------------------===//
+// Utility Actions
+//===----------------------------------------------------------------------===//
+
+void ASTFrontendAction::ExecuteAction() {
+  CompilerInstance &CI = getCompilerInstance();
+
+  // FIXME: Move the truncation aspect of this into Sema, we delayed this till
+  // here so the source manager would be initialized.
+  if (hasCodeCompletionSupport() &&
+      !CI.getFrontendOpts().CodeCompletionAt.FileName.empty())
+    CI.createCodeCompletionConsumer();
+
+  // Use a code completion consumer?
+  CodeCompleteConsumer *CompletionConsumer = 0;
+  if (CI.hasCodeCompletionConsumer())
+    CompletionConsumer = &CI.getCodeCompletionConsumer();
+
+  ParseAST(CI.getPreprocessor(), &CI.getASTConsumer(), CI.getASTContext(),
+           CI.getFrontendOpts().ShowStats,
+           usesCompleteTranslationUnit(), CompletionConsumer);
+}
+
+ASTConsumer *
+PreprocessorFrontendAction::CreateASTConsumer(CompilerInstance &CI,
+                                              llvm::StringRef InFile) {
+  llvm_unreachable("Invalid CreateASTConsumer on preprocessor action!");
+}
diff --git a/lib/Frontend/FrontendActions.cpp b/lib/Frontend/FrontendActions.cpp
new file mode 100644
index 0000000..6cd960b
--- /dev/null
+++ b/lib/Frontend/FrontendActions.cpp
@@ -0,0 +1,272 @@
+//===--- FrontendActions.cpp ----------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/FrontendActions.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Parse/Parser.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Frontend/AnalysisConsumer.h"
+#include "clang/Frontend/ASTConsumers.h"
+#include "clang/Frontend/ASTUnit.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Frontend/FixItRewriter.h"
+#include "clang/Frontend/FrontendDiagnostic.h"
+#include "clang/Frontend/Utils.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace clang;
+
+//===----------------------------------------------------------------------===//
+// Custom Actions
+//===----------------------------------------------------------------------===//
+
+ASTConsumer *InitOnlyAction::CreateASTConsumer(CompilerInstance &CI,
+                                               llvm::StringRef InFile) {
+  return new ASTConsumer();
+}
+
+void InitOnlyAction::ExecuteAction() {
+}
+
+//===----------------------------------------------------------------------===//
+// AST Consumer Actions
+//===----------------------------------------------------------------------===//
+
+ASTConsumer *AnalysisAction::CreateASTConsumer(CompilerInstance &CI,
+                                               llvm::StringRef InFile) {
+  return CreateAnalysisConsumer(CI.getPreprocessor(),
+                                CI.getFrontendOpts().OutputFile,
+                                CI.getAnalyzerOpts());
+}
+
+ASTConsumer *ASTPrintAction::CreateASTConsumer(CompilerInstance &CI,
+                                               llvm::StringRef InFile) {
+  if (llvm::raw_ostream *OS = CI.createDefaultOutputFile(false, InFile))
+    return CreateASTPrinter(OS);
+  return 0;
+}
+
+ASTConsumer *ASTPrintXMLAction::CreateASTConsumer(CompilerInstance &CI,
+                                                  llvm::StringRef InFile) {
+  if (llvm::raw_ostream *OS = CI.createDefaultOutputFile(false, InFile, "xml"))
+    return CreateASTPrinterXML(OS);
+  return 0;
+}
+
+ASTConsumer *ASTDumpAction::CreateASTConsumer(CompilerInstance &CI,
+                                              llvm::StringRef InFile) {
+  return CreateASTDumper();
+}
+
+ASTConsumer *ASTViewAction::CreateASTConsumer(CompilerInstance &CI,
+                                              llvm::StringRef InFile) {
+  return CreateASTViewer();
+}
+
+ASTConsumer *DeclContextPrintAction::CreateASTConsumer(CompilerInstance &CI,
+                                                       llvm::StringRef InFile) {
+  return CreateDeclContextPrinter();
+}
+
+ASTConsumer *GeneratePCHAction::CreateASTConsumer(CompilerInstance &CI,
+                                                  llvm::StringRef InFile) {
+  const std::string &Sysroot = CI.getHeaderSearchOpts().Sysroot;
+  if (CI.getFrontendOpts().RelocatablePCH &&
+      Sysroot.empty()) {
+    CI.getDiagnostics().Report(diag::err_relocatable_without_without_isysroot);
+    return 0;
+  }
+
+  llvm::raw_ostream *OS = CI.createDefaultOutputFile(true, InFile);
+  if (!OS)
+    return 0;
+
+  if (CI.getFrontendOpts().RelocatablePCH)
+    return CreatePCHGenerator(CI.getPreprocessor(), OS, Sysroot.c_str());
+
+  return CreatePCHGenerator(CI.getPreprocessor(), OS);
+}
+
+ASTConsumer *HTMLPrintAction::CreateASTConsumer(CompilerInstance &CI,
+                                                llvm::StringRef InFile) {
+  if (llvm::raw_ostream *OS = CI.createDefaultOutputFile(false, InFile))
+    return CreateHTMLPrinter(OS, CI.getPreprocessor());
+  return 0;
+}
+
+ASTConsumer *InheritanceViewAction::CreateASTConsumer(CompilerInstance &CI,
+                                                      llvm::StringRef InFile) {
+  return CreateInheritanceViewer(CI.getFrontendOpts().ViewClassInheritance);
+}
+
+FixItAction::FixItAction() {}
+FixItAction::~FixItAction() {}
+
+ASTConsumer *FixItAction::CreateASTConsumer(CompilerInstance &CI,
+                                            llvm::StringRef InFile) {
+  return new ASTConsumer();
+}
+
+class FixItActionSuffixInserter : public FixItPathRewriter {
+  std::string NewSuffix;
+
+public:
+  explicit FixItActionSuffixInserter(std::string NewSuffix)
+    : NewSuffix(NewSuffix) {}
+
+  std::string RewriteFilename(const std::string &Filename) {
+    llvm::sys::Path Path(Filename);
+    std::string Suffix = Path.getSuffix();
+    Path.eraseSuffix();
+    Path.appendSuffix(NewSuffix + "." + Suffix);
+    return Path.c_str();
+  }
+};
+
+bool FixItAction::BeginSourceFileAction(CompilerInstance &CI,
+                                        llvm::StringRef Filename) {
+  const FrontendOptions &FEOpts = getCompilerInstance().getFrontendOpts();
+  if (!FEOpts.FixItSuffix.empty()) {
+    PathRewriter.reset(new FixItActionSuffixInserter(FEOpts.FixItSuffix));
+  } else {
+    PathRewriter.reset();
+  }
+  Rewriter.reset(new FixItRewriter(CI.getDiagnostics(), CI.getSourceManager(),
+                                   CI.getLangOpts(), PathRewriter.get()));
+  return true;
+}
+
+void FixItAction::EndSourceFileAction() {
+  // Otherwise rewrite all files.
+  Rewriter->WriteFixedFiles();
+}
+
+ASTConsumer *RewriteObjCAction::CreateASTConsumer(CompilerInstance &CI,
+                                                  llvm::StringRef InFile) {
+  if (llvm::raw_ostream *OS = CI.createDefaultOutputFile(false, InFile, "cpp"))
+    return CreateObjCRewriter(InFile, OS,
+                              CI.getDiagnostics(), CI.getLangOpts(),
+                              CI.getDiagnosticOpts().NoRewriteMacros);
+  return 0;
+}
+
+ASTConsumer *SyntaxOnlyAction::CreateASTConsumer(CompilerInstance &CI,
+                                                 llvm::StringRef InFile) {
+  return new ASTConsumer();
+}
+
+//===----------------------------------------------------------------------===//
+// Preprocessor Actions
+//===----------------------------------------------------------------------===//
+
+void DumpRawTokensAction::ExecuteAction() {
+  Preprocessor &PP = getCompilerInstance().getPreprocessor();
+  SourceManager &SM = PP.getSourceManager();
+
+  // Start lexing the specified input file.
+  const llvm::MemoryBuffer *FromFile = SM.getBuffer(SM.getMainFileID());
+  Lexer RawLex(SM.getMainFileID(), FromFile, SM, PP.getLangOptions());
+  RawLex.SetKeepWhitespaceMode(true);
+
+  Token RawTok;
+  RawLex.LexFromRawLexer(RawTok);
+  while (RawTok.isNot(tok::eof)) {
+    PP.DumpToken(RawTok, true);
+    llvm::errs() << "\n";
+    RawLex.LexFromRawLexer(RawTok);
+  }
+}
+
+void DumpTokensAction::ExecuteAction() {
+  Preprocessor &PP = getCompilerInstance().getPreprocessor();
+  // Start preprocessing the specified input file.
+  Token Tok;
+  PP.EnterMainSourceFile();
+  do {
+    PP.Lex(Tok);
+    PP.DumpToken(Tok, true);
+    llvm::errs() << "\n";
+  } while (Tok.isNot(tok::eof));
+}
+
+void GeneratePTHAction::ExecuteAction() {
+  CompilerInstance &CI = getCompilerInstance();
+  if (CI.getFrontendOpts().OutputFile.empty() ||
+      CI.getFrontendOpts().OutputFile == "-") {
+    // FIXME: Don't fail this way.
+    // FIXME: Verify that we can actually seek in the given file.
+    llvm::report_fatal_error("PTH requires a seekable file for output!");
+  }
+  llvm::raw_fd_ostream *OS =
+    CI.createDefaultOutputFile(true, getCurrentFile());
+  if (!OS) return;
+
+  CacheTokens(CI.getPreprocessor(), OS);
+}
+
+void ParseOnlyAction::ExecuteAction() {
+  Preprocessor &PP = getCompilerInstance().getPreprocessor();
+  llvm::OwningPtr<Action> PA(new MinimalAction(PP));
+
+  Parser P(PP, *PA);
+  PP.EnterMainSourceFile();
+  P.ParseTranslationUnit();
+}
+
+void PreprocessOnlyAction::ExecuteAction() {
+  Preprocessor &PP = getCompilerInstance().getPreprocessor();
+
+  Token Tok;
+  // Start parsing the specified input file.
+  PP.EnterMainSourceFile();
+  do {
+    PP.Lex(Tok);
+  } while (Tok.isNot(tok::eof));
+}
+
+void PrintParseAction::ExecuteAction() {
+  CompilerInstance &CI = getCompilerInstance();
+  Preprocessor &PP = getCompilerInstance().getPreprocessor();
+  llvm::raw_ostream *OS = CI.createDefaultOutputFile(false, getCurrentFile());
+  if (!OS) return;
+
+  llvm::OwningPtr<Action> PA(CreatePrintParserActionsAction(PP, OS));
+
+  Parser P(PP, *PA);
+  PP.EnterMainSourceFile();
+  P.ParseTranslationUnit();
+}
+
+void PrintPreprocessedAction::ExecuteAction() {
+  CompilerInstance &CI = getCompilerInstance();
+  // Output file needs to be set to 'Binary', to avoid converting Unix style
+  // line feeds (<LF>) to Microsoft style line feeds (<CR><LF>).
+  llvm::raw_ostream *OS = CI.createDefaultOutputFile(true, getCurrentFile());
+  if (!OS) return;
+
+  DoPrintPreprocessedInput(CI.getPreprocessor(), OS,
+                           CI.getPreprocessorOutputOpts());
+}
+
+void RewriteMacrosAction::ExecuteAction() {
+  CompilerInstance &CI = getCompilerInstance();
+  llvm::raw_ostream *OS = CI.createDefaultOutputFile(true, getCurrentFile());
+  if (!OS) return;
+
+  RewriteMacrosInInput(CI.getPreprocessor(), OS);
+}
+
+void RewriteTestAction::ExecuteAction() {
+  CompilerInstance &CI = getCompilerInstance();
+  llvm::raw_ostream *OS = CI.createDefaultOutputFile(false, getCurrentFile());
+  if (!OS) return;
+
+  DoRewriteTest(CI.getPreprocessor(), OS);
+}
diff --git a/lib/Frontend/FrontendOptions.cpp b/lib/Frontend/FrontendOptions.cpp
new file mode 100644
index 0000000..bd91638
--- /dev/null
+++ b/lib/Frontend/FrontendOptions.cpp
@@ -0,0 +1,31 @@
+//===--- FrontendOptions.cpp ----------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/FrontendOptions.h"
+#include "llvm/ADT/StringSwitch.h"
+using namespace clang;
+
+FrontendOptions::InputKind
+FrontendOptions::getInputKindForExtension(llvm::StringRef Extension) {
+  return llvm::StringSwitch<InputKind>(Extension)
+    .Case("ast", IK_AST)
+    .Case("c", IK_C)
+    .Cases("S", "s", IK_Asm)
+    .Case("i", IK_PreprocessedC)
+    .Case("ii", IK_PreprocessedCXX)
+    .Case("m", IK_ObjC)
+    .Case("mi", IK_PreprocessedObjC)
+    .Cases("mm", "M", IK_ObjCXX)
+    .Case("mii", IK_PreprocessedObjCXX)
+    .Case("C", IK_CXX)
+    .Cases("C", "cc", "cp", IK_CXX)
+    .Cases("cpp", "CPP", "c++", "cxx", "hpp", IK_CXX)
+    .Case("cl", IK_OpenCL)
+    .Default(IK_C);
+}
diff --git a/lib/Frontend/GeneratePCH.cpp b/lib/Frontend/GeneratePCH.cpp
new file mode 100644
index 0000000..6251bac
--- /dev/null
+++ b/lib/Frontend/GeneratePCH.cpp
@@ -0,0 +1,80 @@
+//===--- GeneratePCH.cpp - AST Consumer for PCH Generation ------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the CreatePCHGenerate function, which creates an
+//  ASTConsume that generates a PCH file.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/ASTConsumers.h"
+#include "clang/Frontend/PCHWriter.h"
+#include "clang/Sema/SemaConsumer.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Basic/FileManager.h"
+#include "llvm/Bitcode/BitstreamWriter.h"
+#include "llvm/Support/raw_ostream.h"
+#include <string>
+
+using namespace clang;
+
+namespace {
+  class PCHGenerator : public SemaConsumer {
+    const Preprocessor &PP;
+    const char *isysroot;
+    llvm::raw_ostream *Out;
+    Sema *SemaPtr;
+    MemorizeStatCalls *StatCalls; // owned by the FileManager
+
+  public:
+    explicit PCHGenerator(const Preprocessor &PP,
+                          const char *isysroot,
+                          llvm::raw_ostream *Out);
+    virtual void InitializeSema(Sema &S) { SemaPtr = &S; }
+    virtual void HandleTranslationUnit(ASTContext &Ctx);
+  };
+}
+
+PCHGenerator::PCHGenerator(const Preprocessor &PP,
+                           const char *isysroot,
+                           llvm::raw_ostream *OS)
+  : PP(PP), isysroot(isysroot), Out(OS), SemaPtr(0), StatCalls(0) {
+
+  // Install a stat() listener to keep track of all of the stat()
+  // calls.
+  StatCalls = new MemorizeStatCalls;
+  PP.getFileManager().addStatCache(StatCalls, /*AtBeginning=*/true);
+}
+
+void PCHGenerator::HandleTranslationUnit(ASTContext &Ctx) {
+  if (PP.getDiagnostics().hasErrorOccurred())
+    return;
+
+  // Write the PCH contents into a buffer
+  std::vector<unsigned char> Buffer;
+  llvm::BitstreamWriter Stream(Buffer);
+  PCHWriter Writer(Stream);
+
+  // Emit the PCH file
+  assert(SemaPtr && "No Sema?");
+  Writer.WritePCH(*SemaPtr, StatCalls, isysroot);
+
+  // Write the generated bitstream to "Out".
+  Out->write((char *)&Buffer.front(), Buffer.size());
+
+  // Make sure it hits disk now.
+  Out->flush();
+}
+
+ASTConsumer *clang::CreatePCHGenerator(const Preprocessor &PP,
+                                       llvm::raw_ostream *OS,
+                                       const char *isysroot) {
+  return new PCHGenerator(PP, isysroot, OS);
+}
diff --git a/lib/Frontend/HTMLDiagnostics.cpp b/lib/Frontend/HTMLDiagnostics.cpp
new file mode 100644
index 0000000..022a34d
--- /dev/null
+++ b/lib/Frontend/HTMLDiagnostics.cpp
@@ -0,0 +1,577 @@
+//===--- HTMLDiagnostics.cpp - HTML Diagnostics for Paths ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the HTMLDiagnostics object.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/PathDiagnosticClients.h"
+#include "clang/Checker/BugReporter/PathDiagnostic.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Rewrite/Rewriter.h"
+#include "clang/Rewrite/HTMLRewrite.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Lex/Preprocessor.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/System/Path.h"
+
+using namespace clang;
+
+//===----------------------------------------------------------------------===//
+// Boilerplate.
+//===----------------------------------------------------------------------===//
+
+namespace {
+
+class HTMLDiagnostics : public PathDiagnosticClient {
+  llvm::sys::Path Directory, FilePrefix;
+  bool createdDir, noDir;
+  const Preprocessor &PP;
+  std::vector<const PathDiagnostic*> BatchedDiags;
+public:
+  HTMLDiagnostics(const std::string& prefix, const Preprocessor &pp);
+
+  virtual ~HTMLDiagnostics() { FlushDiagnostics(NULL); }
+
+  virtual void FlushDiagnostics(llvm::SmallVectorImpl<std::string> *FilesMade);
+
+  virtual void HandlePathDiagnostic(const PathDiagnostic* D);
+
+  virtual llvm::StringRef getName() const {
+    return "HTMLDiagnostics";
+  }
+
+  unsigned ProcessMacroPiece(llvm::raw_ostream& os,
+                             const PathDiagnosticMacroPiece& P,
+                             unsigned num);
+
+  void HandlePiece(Rewriter& R, FileID BugFileID,
+                   const PathDiagnosticPiece& P, unsigned num, unsigned max);
+
+  void HighlightRange(Rewriter& R, FileID BugFileID, SourceRange Range,
+                      const char *HighlightStart = "<span class=\"mrange\">",
+                      const char *HighlightEnd = "</span>");
+
+  void ReportDiag(const PathDiagnostic& D,
+                  llvm::SmallVectorImpl<std::string> *FilesMade);
+};
+
+} // end anonymous namespace
+
+HTMLDiagnostics::HTMLDiagnostics(const std::string& prefix,
+                                 const Preprocessor &pp)
+  : Directory(prefix), FilePrefix(prefix), createdDir(false), noDir(false),
+    PP(pp) {
+  // All html files begin with "report"
+  FilePrefix.appendComponent("report");
+}
+
+PathDiagnosticClient*
+clang::CreateHTMLDiagnosticClient(const std::string& prefix,
+                                  const Preprocessor &PP) {
+  return new HTMLDiagnostics(prefix, PP);
+}
+
+//===----------------------------------------------------------------------===//
+// Report processing.
+//===----------------------------------------------------------------------===//
+
+void HTMLDiagnostics::HandlePathDiagnostic(const PathDiagnostic* D) {
+  if (!D)
+    return;
+
+  if (D->empty()) {
+    delete D;
+    return;
+  }
+
+  const_cast<PathDiagnostic*>(D)->flattenLocations();
+  BatchedDiags.push_back(D);
+}
+
+void
+HTMLDiagnostics::FlushDiagnostics(llvm::SmallVectorImpl<std::string> *FilesMade)
+{
+  while (!BatchedDiags.empty()) {
+    const PathDiagnostic* D = BatchedDiags.back();
+    BatchedDiags.pop_back();
+    ReportDiag(*D, FilesMade);
+    delete D;
+  }
+
+  BatchedDiags.clear();
+}
+
+void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D,
+                                 llvm::SmallVectorImpl<std::string> *FilesMade){
+  // Create the HTML directory if it is missing.
+  if (!createdDir) {
+    createdDir = true;
+    std::string ErrorMsg;
+    Directory.createDirectoryOnDisk(true, &ErrorMsg);
+
+    if (!Directory.isDirectory()) {
+      llvm::errs() << "warning: could not create directory '"
+                   << Directory.str() << "'\n"
+                   << "reason: " << ErrorMsg << '\n';
+
+      noDir = true;
+
+      return;
+    }
+  }
+
+  if (noDir)
+    return;
+
+  const SourceManager &SMgr = D.begin()->getLocation().getManager();
+  FileID FID;
+
+  // Verify that the entire path is from the same FileID.
+  for (PathDiagnostic::const_iterator I = D.begin(), E = D.end(); I != E; ++I) {
+    FullSourceLoc L = I->getLocation().asLocation().getInstantiationLoc();
+
+    if (FID.isInvalid()) {
+      FID = SMgr.getFileID(L);
+    } else if (SMgr.getFileID(L) != FID)
+      return; // FIXME: Emit a warning?
+
+    // Check the source ranges.
+    for (PathDiagnosticPiece::range_iterator RI=I->ranges_begin(),
+                                             RE=I->ranges_end(); RI!=RE; ++RI) {
+
+      SourceLocation L = SMgr.getInstantiationLoc(RI->getBegin());
+
+      if (!L.isFileID() || SMgr.getFileID(L) != FID)
+        return; // FIXME: Emit a warning?
+
+      L = SMgr.getInstantiationLoc(RI->getEnd());
+
+      if (!L.isFileID() || SMgr.getFileID(L) != FID)
+        return; // FIXME: Emit a warning?
+    }
+  }
+
+  if (FID.isInvalid())
+    return; // FIXME: Emit a warning?
+
+  // Create a new rewriter to generate HTML.
+  Rewriter R(const_cast<SourceManager&>(SMgr), PP.getLangOptions());
+
+  // Process the path.
+  unsigned n = D.size();
+  unsigned max = n;
+
+  for (PathDiagnostic::const_reverse_iterator I=D.rbegin(), E=D.rend();
+        I!=E; ++I, --n)
+    HandlePiece(R, FID, *I, n, max);
+
+  // Add line numbers, header, footer, etc.
+
+  // unsigned FID = R.getSourceMgr().getMainFileID();
+  html::EscapeText(R, FID);
+  html::AddLineNumbers(R, FID);
+
+  // If we have a preprocessor, relex the file and syntax highlight.
+  // We might not have a preprocessor if we come from a deserialized AST file,
+  // for example.
+
+  html::SyntaxHighlight(R, FID, PP);
+  html::HighlightMacros(R, FID, PP);
+
+  // Get the full directory name of the analyzed file.
+
+  const FileEntry* Entry = SMgr.getFileEntryForID(FID);
+
+  // This is a cludge; basically we want to append either the full
+  // working directory if we have no directory information.  This is
+  // a work in progress.
+
+  std::string DirName = "";
+
+  if (!llvm::sys::Path(Entry->getName()).isAbsolute()) {
+    llvm::sys::Path P = llvm::sys::Path::GetCurrentDirectory();
+    DirName = P.str() + "/";
+  }
+
+  // Add the name of the file as an <h1> tag.
+
+  {
+    std::string s;
+    llvm::raw_string_ostream os(s);
+
+    os << "<!-- REPORTHEADER -->\n"
+      << "<h3>Bug Summary</h3>\n<table class=\"simpletable\">\n"
+          "<tr><td class=\"rowname\">File:</td><td>"
+      << html::EscapeText(DirName)
+      << html::EscapeText(Entry->getName())
+      << "</td></tr>\n<tr><td class=\"rowname\">Location:</td><td>"
+         "<a href=\"#EndPath\">line "
+      << (*D.rbegin()).getLocation().asLocation().getInstantiationLineNumber()
+      << ", column "
+      << (*D.rbegin()).getLocation().asLocation().getInstantiationColumnNumber()
+      << "</a></td></tr>\n"
+         "<tr><td class=\"rowname\">Description:</td><td>"
+      << D.getDescription() << "</td></tr>\n";
+
+    // Output any other meta data.
+
+    for (PathDiagnostic::meta_iterator I=D.meta_begin(), E=D.meta_end();
+         I!=E; ++I) {
+      os << "<tr><td></td><td>" << html::EscapeText(*I) << "</td></tr>\n";
+    }
+
+    os << "</table>\n<!-- REPORTSUMMARYEXTRA -->\n"
+          "<h3>Annotated Source Code</h3>\n";
+
+    R.InsertTextBefore(SMgr.getLocForStartOfFile(FID), os.str());
+  }
+
+  // Embed meta-data tags.
+  {
+    std::string s;
+    llvm::raw_string_ostream os(s);
+
+    const std::string& BugDesc = D.getDescription();
+    if (!BugDesc.empty())
+      os << "\n<!-- BUGDESC " << BugDesc << " -->\n";
+
+    const std::string& BugType = D.getBugType();
+    if (!BugType.empty())
+      os << "\n<!-- BUGTYPE " << BugType << " -->\n";
+
+    const std::string& BugCategory = D.getCategory();
+    if (!BugCategory.empty())
+      os << "\n<!-- BUGCATEGORY " << BugCategory << " -->\n";
+
+    os << "\n<!-- BUGFILE " << DirName << Entry->getName() << " -->\n";
+
+    os << "\n<!-- BUGLINE "
+       << D.back()->getLocation().asLocation().getInstantiationLineNumber()
+       << " -->\n";
+
+    os << "\n<!-- BUGPATHLENGTH " << D.size() << " -->\n";
+
+    // Mark the end of the tags.
+    os << "\n<!-- BUGMETAEND -->\n";
+
+    // Insert the text.
+    R.InsertTextBefore(SMgr.getLocForStartOfFile(FID), os.str());
+  }
+
+  // Add CSS, header, and footer.
+
+  html::AddHeaderFooterInternalBuiltinCSS(R, FID, Entry->getName());
+
+  // Get the rewrite buffer.
+  const RewriteBuffer *Buf = R.getRewriteBufferFor(FID);
+
+  if (!Buf) {
+    llvm::errs() << "warning: no diagnostics generated for main file.\n";
+    return;
+  }
+
+  // Create a path for the target HTML file.
+  llvm::sys::Path F(FilePrefix);
+  F.makeUnique(false, NULL);
+
+  // Rename the file with an HTML extension.
+  llvm::sys::Path H(F);
+  H.appendSuffix("html");
+  F.renamePathOnDisk(H, NULL);
+
+  std::string ErrorMsg;
+  llvm::raw_fd_ostream os(H.c_str(), ErrorMsg);
+
+  if (!ErrorMsg.empty()) {
+    (llvm::errs() << "warning: could not create file '" << F.str()
+                  << "'\n").flush();
+    return;
+  }
+
+  if (FilesMade)
+    FilesMade->push_back(H.getLast());
+
+  // Emit the HTML to disk.
+  for (RewriteBuffer::iterator I = Buf->begin(), E = Buf->end(); I!=E; ++I)
+      os << *I;
+}
+
+void HTMLDiagnostics::HandlePiece(Rewriter& R, FileID BugFileID,
+                                  const PathDiagnosticPiece& P,
+                                  unsigned num, unsigned max) {
+
+  // For now, just draw a box above the line in question, and emit the
+  // warning.
+  FullSourceLoc Pos = P.getLocation().asLocation();
+
+  if (!Pos.isValid())
+    return;
+
+  SourceManager &SM = R.getSourceMgr();
+  assert(&Pos.getManager() == &SM && "SourceManagers are different!");
+  std::pair<FileID, unsigned> LPosInfo = SM.getDecomposedInstantiationLoc(Pos);
+
+  if (LPosInfo.first != BugFileID)
+    return;
+
+  const llvm::MemoryBuffer *Buf = SM.getBuffer(LPosInfo.first);
+  const char* FileStart = Buf->getBufferStart();
+
+  // Compute the column number.  Rewind from the current position to the start
+  // of the line.
+  unsigned ColNo = SM.getColumnNumber(LPosInfo.first, LPosInfo.second);
+  const char *TokInstantiationPtr =Pos.getInstantiationLoc().getCharacterData();
+  const char *LineStart = TokInstantiationPtr-ColNo;
+
+  // Compute LineEnd.
+  const char *LineEnd = TokInstantiationPtr;
+  const char* FileEnd = Buf->getBufferEnd();
+  while (*LineEnd != '\n' && LineEnd != FileEnd)
+    ++LineEnd;
+
+  // Compute the margin offset by counting tabs and non-tabs.
+  unsigned PosNo = 0;
+  for (const char* c = LineStart; c != TokInstantiationPtr; ++c)
+    PosNo += *c == '\t' ? 8 : 1;
+
+  // Create the html for the message.
+
+  const char *Kind = 0;
+  switch (P.getKind()) {
+  case PathDiagnosticPiece::Event:  Kind = "Event"; break;
+  case PathDiagnosticPiece::ControlFlow: Kind = "Control"; break;
+    // Setting Kind to "Control" is intentional.
+  case PathDiagnosticPiece::Macro: Kind = "Control"; break;
+  }
+
+  std::string sbuf;
+  llvm::raw_string_ostream os(sbuf);
+
+  os << "\n<tr><td class=\"num\"></td><td class=\"line\"><div id=\"";
+
+  if (num == max)
+    os << "EndPath";
+  else
+    os << "Path" << num;
+
+  os << "\" class=\"msg";
+  if (Kind)
+    os << " msg" << Kind;
+  os << "\" style=\"margin-left:" << PosNo << "ex";
+
+  // Output a maximum size.
+  if (!isa<PathDiagnosticMacroPiece>(P)) {
+    // Get the string and determining its maximum substring.
+    const std::string& Msg = P.getString();
+    unsigned max_token = 0;
+    unsigned cnt = 0;
+    unsigned len = Msg.size();
+
+    for (std::string::const_iterator I=Msg.begin(), E=Msg.end(); I!=E; ++I)
+      switch (*I) {
+      default:
+        ++cnt;
+        continue;
+      case ' ':
+      case '\t':
+      case '\n':
+        if (cnt > max_token) max_token = cnt;
+        cnt = 0;
+      }
+
+    if (cnt > max_token)
+      max_token = cnt;
+
+    // Determine the approximate size of the message bubble in em.
+    unsigned em;
+    const unsigned max_line = 120;
+
+    if (max_token >= max_line)
+      em = max_token / 2;
+    else {
+      unsigned characters = max_line;
+      unsigned lines = len / max_line;
+
+      if (lines > 0) {
+        for (; characters > max_token; --characters)
+          if (len / characters > lines) {
+            ++characters;
+            break;
+          }
+      }
+
+      em = characters / 2;
+    }
+
+    if (em < max_line/2)
+      os << "; max-width:" << em << "em";
+  }
+  else
+    os << "; max-width:100em";
+
+  os << "\">";
+
+  if (max > 1) {
+    os << "<table class=\"msgT\"><tr><td valign=\"top\">";
+    os << "<div class=\"PathIndex";
+    if (Kind) os << " PathIndex" << Kind;
+    os << "\">" << num << "</div>";
+    os << "</td><td>";
+  }
+
+  if (const PathDiagnosticMacroPiece *MP =
+        dyn_cast<PathDiagnosticMacroPiece>(&P)) {
+
+    os << "Within the expansion of the macro '";
+
+    // Get the name of the macro by relexing it.
+    {
+      FullSourceLoc L = MP->getLocation().asLocation().getInstantiationLoc();
+      assert(L.isFileID());
+      llvm::StringRef BufferInfo = L.getBufferData();
+      const char* MacroName = L.getDecomposedLoc().second + BufferInfo.data();
+      Lexer rawLexer(L, PP.getLangOptions(), BufferInfo.begin(),
+                     MacroName, BufferInfo.end());
+
+      Token TheTok;
+      rawLexer.LexFromRawLexer(TheTok);
+      for (unsigned i = 0, n = TheTok.getLength(); i < n; ++i)
+        os << MacroName[i];
+    }
+
+    os << "':\n";
+
+    if (max > 1)
+      os << "</td></tr></table>";
+
+    // Within a macro piece.  Write out each event.
+    ProcessMacroPiece(os, *MP, 0);
+  }
+  else {
+    os << html::EscapeText(P.getString());
+
+    if (max > 1)
+      os << "</td></tr></table>";
+  }
+
+  os << "</div></td></tr>";
+
+  // Insert the new html.
+  unsigned DisplayPos = LineEnd - FileStart;
+  SourceLocation Loc =
+    SM.getLocForStartOfFile(LPosInfo.first).getFileLocWithOffset(DisplayPos);
+
+  R.InsertTextBefore(Loc, os.str());
+
+  // Now highlight the ranges.
+  for (const SourceRange *I = P.ranges_begin(), *E = P.ranges_end();
+        I != E; ++I)
+    HighlightRange(R, LPosInfo.first, *I);
+
+#if 0
+  // If there is a code insertion hint, insert that code.
+  // FIXME: This code is disabled because it seems to mangle the HTML
+  // output. I'm leaving it here because it's generally the right idea,
+  // but needs some help from someone more familiar with the rewriter.
+  for (const FixItHint *Hint = P.fixit_begin(), *HintEnd = P.fixit_end();
+       Hint != HintEnd; ++Hint) {
+    if (Hint->RemoveRange.isValid()) {
+      HighlightRange(R, LPosInfo.first, Hint->RemoveRange,
+                     "<span class=\"CodeRemovalHint\">", "</span>");
+    }
+    if (Hint->InsertionLoc.isValid()) {
+      std::string EscapedCode = html::EscapeText(Hint->CodeToInsert, true);
+      EscapedCode = "<span class=\"CodeInsertionHint\">" + EscapedCode
+        + "</span>";
+      R.InsertTextBefore(Hint->InsertionLoc, EscapedCode);
+    }
+  }
+#endif
+}
+
+static void EmitAlphaCounter(llvm::raw_ostream& os, unsigned n) {
+  unsigned x = n % ('z' - 'a');
+  n /= 'z' - 'a';
+
+  if (n > 0)
+    EmitAlphaCounter(os, n);
+
+  os << char('a' + x);
+}
+
+unsigned HTMLDiagnostics::ProcessMacroPiece(llvm::raw_ostream& os,
+                                            const PathDiagnosticMacroPiece& P,
+                                            unsigned num) {
+
+  for (PathDiagnosticMacroPiece::const_iterator I=P.begin(), E=P.end();
+        I!=E; ++I) {
+
+    if (const PathDiagnosticMacroPiece *MP =
+          dyn_cast<PathDiagnosticMacroPiece>(*I)) {
+      num = ProcessMacroPiece(os, *MP, num);
+      continue;
+    }
+
+    if (PathDiagnosticEventPiece *EP = dyn_cast<PathDiagnosticEventPiece>(*I)) {
+      os << "<div class=\"msg msgEvent\" style=\"width:94%; "
+            "margin-left:5px\">"
+            "<table class=\"msgT\"><tr>"
+            "<td valign=\"top\"><div class=\"PathIndex PathIndexEvent\">";
+      EmitAlphaCounter(os, num++);
+      os << "</div></td><td valign=\"top\">"
+         << html::EscapeText(EP->getString())
+         << "</td></tr></table></div>\n";
+    }
+  }
+
+  return num;
+}
+
+void HTMLDiagnostics::HighlightRange(Rewriter& R, FileID BugFileID,
+                                     SourceRange Range,
+                                     const char *HighlightStart,
+                                     const char *HighlightEnd) {
+  SourceManager &SM = R.getSourceMgr();
+  const LangOptions &LangOpts = R.getLangOpts();
+
+  SourceLocation InstantiationStart = SM.getInstantiationLoc(Range.getBegin());
+  unsigned StartLineNo = SM.getInstantiationLineNumber(InstantiationStart);
+
+  SourceLocation InstantiationEnd = SM.getInstantiationLoc(Range.getEnd());
+  unsigned EndLineNo = SM.getInstantiationLineNumber(InstantiationEnd);
+
+  if (EndLineNo < StartLineNo)
+    return;
+
+  if (SM.getFileID(InstantiationStart) != BugFileID ||
+      SM.getFileID(InstantiationEnd) != BugFileID)
+    return;
+
+  // Compute the column number of the end.
+  unsigned EndColNo = SM.getInstantiationColumnNumber(InstantiationEnd);
+  unsigned OldEndColNo = EndColNo;
+
+  if (EndColNo) {
+    // Add in the length of the token, so that we cover multi-char tokens.
+    EndColNo += Lexer::MeasureTokenLength(Range.getEnd(), SM, LangOpts)-1;
+  }
+
+  // Highlight the range.  Make the span tag the outermost tag for the
+  // selected range.
+
+  SourceLocation E =
+    InstantiationEnd.getFileLocWithOffset(EndColNo - OldEndColNo);
+
+  html::HighlightRange(R, InstantiationStart, E, HighlightStart, HighlightEnd);
+}
diff --git a/lib/Frontend/HTMLPrint.cpp b/lib/Frontend/HTMLPrint.cpp
new file mode 100644
index 0000000..9ea8cb3
--- /dev/null
+++ b/lib/Frontend/HTMLPrint.cpp
@@ -0,0 +1,94 @@
+//===--- HTMLPrint.cpp - Source code -> HTML pretty-printing --------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Pretty-printing of source code to HTML.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/ASTConsumers.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Rewrite/HTMLRewrite.h"
+#include "clang/Rewrite/Rewriter.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace clang;
+
+//===----------------------------------------------------------------------===//
+// Functional HTML pretty-printing.
+//===----------------------------------------------------------------------===//
+
+namespace {
+  class HTMLPrinter : public ASTConsumer {
+    Rewriter R;
+    llvm::raw_ostream *Out;
+    Preprocessor &PP;
+    bool SyntaxHighlight, HighlightMacros;
+
+  public:
+    HTMLPrinter(llvm::raw_ostream *OS, Preprocessor &pp,
+                bool _SyntaxHighlight, bool _HighlightMacros)
+      : Out(OS), PP(pp), SyntaxHighlight(_SyntaxHighlight),
+        HighlightMacros(_HighlightMacros) {}
+
+    void Initialize(ASTContext &context);
+    void HandleTranslationUnit(ASTContext &Ctx);
+  };
+}
+
+ASTConsumer* clang::CreateHTMLPrinter(llvm::raw_ostream *OS,
+                                      Preprocessor &PP,
+                                      bool SyntaxHighlight,
+                                      bool HighlightMacros) {
+  return new HTMLPrinter(OS, PP, SyntaxHighlight, HighlightMacros);
+}
+
+void HTMLPrinter::Initialize(ASTContext &context) {
+  R.setSourceMgr(context.getSourceManager(), context.getLangOptions());
+}
+
+void HTMLPrinter::HandleTranslationUnit(ASTContext &Ctx) {
+  if (PP.getDiagnostics().hasErrorOccurred())
+    return;
+
+  // Format the file.
+  FileID FID = R.getSourceMgr().getMainFileID();
+  const FileEntry* Entry = R.getSourceMgr().getFileEntryForID(FID);
+  const char* Name;
+  // In some cases, in particular the case where the input is from stdin,
+  // there is no entry.  Fall back to the memory buffer for a name in those
+  // cases.
+  if (Entry)
+    Name = Entry->getName();
+  else
+    Name = R.getSourceMgr().getBuffer(FID)->getBufferIdentifier();
+
+  html::AddLineNumbers(R, FID);
+  html::AddHeaderFooterInternalBuiltinCSS(R, FID, Name);
+
+  // If we have a preprocessor, relex the file and syntax highlight.
+  // We might not have a preprocessor if we come from a deserialized AST file,
+  // for example.
+
+  if (SyntaxHighlight) html::SyntaxHighlight(R, FID, PP);
+  if (HighlightMacros) html::HighlightMacros(R, FID, PP);
+  html::EscapeText(R, FID, false, true);
+
+  // Emit the HTML.
+  const RewriteBuffer &RewriteBuf = R.getEditBuffer(FID);
+  char *Buffer = (char*)malloc(RewriteBuf.size());
+  std::copy(RewriteBuf.begin(), RewriteBuf.end(), Buffer);
+  Out->write(Buffer, RewriteBuf.size());
+  free(Buffer);
+}
diff --git a/lib/Frontend/InitHeaderSearch.cpp b/lib/Frontend/InitHeaderSearch.cpp
new file mode 100644
index 0000000..12a4d4d
--- /dev/null
+++ b/lib/Frontend/InitHeaderSearch.cpp
@@ -0,0 +1,829 @@
+//===--- InitHeaderSearch.cpp - Initialize header search paths ----------*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the InitHeaderSearch class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/Utils.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Frontend/HeaderSearchOptions.h"
+#include "clang/Lex/HeaderSearch.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/System/Path.h"
+#include "llvm/Config/config.h"
+#ifdef _MSC_VER
+  #define WIN32_LEAN_AND_MEAN 1
+  #include <windows.h>
+#endif
+using namespace clang;
+using namespace clang::frontend;
+
+namespace {
+
+/// InitHeaderSearch - This class makes it easier to set the search paths of
+///  a HeaderSearch object. InitHeaderSearch stores several search path lists
+///  internally, which can be sent to a HeaderSearch object in one swoop.
+class InitHeaderSearch {
+  std::vector<DirectoryLookup> IncludeGroup[4];
+  HeaderSearch& Headers;
+  bool Verbose;
+  std::string isysroot;
+
+public:
+
+  InitHeaderSearch(HeaderSearch &HS,
+      bool verbose = false, const std::string &iSysroot = "")
+    : Headers(HS), Verbose(verbose), isysroot(iSysroot) {}
+
+  /// AddPath - Add the specified path to the specified group list.
+  void AddPath(const llvm::Twine &Path, IncludeDirGroup Group,
+               bool isCXXAware, bool isUserSupplied,
+               bool isFramework, bool IgnoreSysRoot = false);
+
+  /// AddGnuCPlusPlusIncludePaths - Add the necessary paths to suport a gnu
+  ///  libstdc++.
+  void AddGnuCPlusPlusIncludePaths(llvm::StringRef Base,
+                                   llvm::StringRef ArchDir,
+                                   llvm::StringRef Dir32,
+                                   llvm::StringRef Dir64,
+                                   const llvm::Triple &triple);
+
+  /// AddMinGWCPlusPlusIncludePaths - Add the necessary paths to suport a MinGW
+  ///  libstdc++.
+  void AddMinGWCPlusPlusIncludePaths(llvm::StringRef Base,
+                                     llvm::StringRef Arch,
+                                     llvm::StringRef Version);
+
+  /// AddDelimitedPaths - Add a list of paths delimited by the system PATH
+  /// separator. The processing follows that of the CPATH variable for gcc.
+  void AddDelimitedPaths(llvm::StringRef String);
+
+  // AddDefaultCIncludePaths - Add paths that should always be searched.
+  void AddDefaultCIncludePaths(const llvm::Triple &triple);
+
+  // AddDefaultCPlusPlusIncludePaths -  Add paths that should be searched when
+  //  compiling c++.
+  void AddDefaultCPlusPlusIncludePaths(const llvm::Triple &triple);
+
+  /// AddDefaultSystemIncludePaths - Adds the default system include paths so
+  ///  that e.g. stdio.h is found.
+  void AddDefaultSystemIncludePaths(const LangOptions &Lang,
+                                    const llvm::Triple &triple,
+                                    bool UseStandardCXXIncludes);
+
+  /// Realize - Merges all search path lists into one list and send it to
+  /// HeaderSearch.
+  void Realize();
+};
+
+}
+
+void InitHeaderSearch::AddPath(const llvm::Twine &Path,
+                               IncludeDirGroup Group, bool isCXXAware,
+                               bool isUserSupplied, bool isFramework,
+                               bool IgnoreSysRoot) {
+  assert(!Path.isTriviallyEmpty() && "can't handle empty path here");
+  FileManager &FM = Headers.getFileMgr();
+
+  // Compute the actual path, taking into consideration -isysroot.
+  llvm::SmallString<256> MappedPathStr;
+  llvm::raw_svector_ostream MappedPath(MappedPathStr);
+
+  // Handle isysroot.
+  if (Group == System && !IgnoreSysRoot) {
+    // FIXME: Portability.  This should be a sys::Path interface, this doesn't
+    // handle things like C:\ right, nor win32 \\network\device\blah.
+    if (isysroot.size() != 1 || isysroot[0] != '/') // Add isysroot if present.
+      MappedPath << isysroot;
+  }
+
+  Path.print(MappedPath);
+
+  // Compute the DirectoryLookup type.
+  SrcMgr::CharacteristicKind Type;
+  if (Group == Quoted || Group == Angled)
+    Type = SrcMgr::C_User;
+  else if (isCXXAware)
+    Type = SrcMgr::C_System;
+  else
+    Type = SrcMgr::C_ExternCSystem;
+
+
+  // If the directory exists, add it.
+  if (const DirectoryEntry *DE = FM.getDirectory(MappedPath.str())) {
+    IncludeGroup[Group].push_back(DirectoryLookup(DE, Type, isUserSupplied,
+                                                  isFramework));
+    return;
+  }
+
+  // Check to see if this is an apple-style headermap (which are not allowed to
+  // be frameworks).
+  if (!isFramework) {
+    if (const FileEntry *FE = FM.getFile(MappedPath.str())) {
+      if (const HeaderMap *HM = Headers.CreateHeaderMap(FE)) {
+        // It is a headermap, add it to the search path.
+        IncludeGroup[Group].push_back(DirectoryLookup(HM, Type,isUserSupplied));
+        return;
+      }
+    }
+  }
+
+  if (Verbose)
+    llvm::errs() << "ignoring nonexistent directory \""
+                 << MappedPath.str() << "\"\n";
+}
+
+
+void InitHeaderSearch::AddDelimitedPaths(llvm::StringRef at) {
+  if (at.empty()) // Empty string should not add '.' path.
+    return;
+
+  llvm::StringRef::size_type delim;
+  while ((delim = at.find(llvm::sys::PathSeparator)) != llvm::StringRef::npos) {
+    if (delim == 0)
+      AddPath(".", Angled, false, true, false);
+    else
+      AddPath(at.substr(0, delim), Angled, false, true, false);
+    at = at.substr(delim + 1);
+  }
+
+  if (at.empty())
+    AddPath(".", Angled, false, true, false);
+  else
+    AddPath(at, Angled, false, true, false);
+}
+
+void InitHeaderSearch::AddGnuCPlusPlusIncludePaths(llvm::StringRef Base,
+                                                   llvm::StringRef ArchDir,
+                                                   llvm::StringRef Dir32,
+                                                   llvm::StringRef Dir64,
+                                                   const llvm::Triple &triple) {
+  // Add the base dir
+  AddPath(Base, System, true, false, false);
+
+  // Add the multilib dirs
+  llvm::Triple::ArchType arch = triple.getArch();
+  bool is64bit = arch == llvm::Triple::ppc64 || arch == llvm::Triple::x86_64;
+  if (is64bit)
+    AddPath(Base + "/" + ArchDir + "/" + Dir64, System, true, false, false);
+  else
+    AddPath(Base + "/" + ArchDir + "/" + Dir32, System, true, false, false);
+
+  // Add the backward dir
+  AddPath(Base + "/backward", System, true, false, false);
+}
+
+void InitHeaderSearch::AddMinGWCPlusPlusIncludePaths(llvm::StringRef Base,
+                                                     llvm::StringRef Arch,
+                                                     llvm::StringRef Version) {
+  AddPath(Base + "/" + Arch + "/" + Version + "/include",
+          System, true, false, false);
+  AddPath(Base + "/" + Arch + "/" + Version + "/include/c++",
+          System, true, false, false);
+  AddPath(Base + "/" + Arch + "/" + Version + "/include/c++/backward",
+          System, true, false, false);
+}
+
+  // FIXME: This probably should goto to some platform utils place.
+#ifdef _MSC_VER
+
+  // Read registry string.
+  // This also supports a means to look for high-versioned keys by use
+  // of a $VERSION placeholder in the key path.
+  // $VERSION in the key path is a placeholder for the version number,
+  // causing the highest value path to be searched for and used.
+  // I.e. "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\$VERSION".
+  // There can be additional characters in the component.  Only the numberic
+  // characters are compared.
+static bool getSystemRegistryString(const char *keyPath, const char *valueName,
+                                    char *value, size_t maxLength) {
+  HKEY hRootKey = NULL;
+  HKEY hKey = NULL;
+  const char* subKey = NULL;
+  DWORD valueType;
+  DWORD valueSize = maxLength - 1;
+  long lResult;
+  bool returnValue = false;
+  if (strncmp(keyPath, "HKEY_CLASSES_ROOT\\", 18) == 0) {
+    hRootKey = HKEY_CLASSES_ROOT;
+    subKey = keyPath + 18;
+  }
+  else if (strncmp(keyPath, "HKEY_USERS\\", 11) == 0) {
+    hRootKey = HKEY_USERS;
+    subKey = keyPath + 11;
+  }
+  else if (strncmp(keyPath, "HKEY_LOCAL_MACHINE\\", 19) == 0) {
+    hRootKey = HKEY_LOCAL_MACHINE;
+    subKey = keyPath + 19;
+  }
+  else if (strncmp(keyPath, "HKEY_CURRENT_USER\\", 18) == 0) {
+    hRootKey = HKEY_CURRENT_USER;
+    subKey = keyPath + 18;
+  }
+  else
+    return(false);
+  const char *placeHolder = strstr(subKey, "$VERSION");
+  char bestName[256];
+  bestName[0] = '\0';
+  // If we have a $VERSION placeholder, do the highest-version search.
+  if (placeHolder) {
+    const char *keyEnd = placeHolder - 1;
+    const char *nextKey = placeHolder;
+    // Find end of previous key.
+    while ((keyEnd > subKey) && (*keyEnd != '\\'))
+      keyEnd--;
+    // Find end of key containing $VERSION.
+    while (*nextKey && (*nextKey != '\\'))
+      nextKey++;
+    size_t partialKeyLength = keyEnd - subKey;
+    char partialKey[256];
+    if (partialKeyLength > sizeof(partialKey))
+      partialKeyLength = sizeof(partialKey);
+    strncpy(partialKey, subKey, partialKeyLength);
+    partialKey[partialKeyLength] = '\0';
+    HKEY hTopKey = NULL;
+    lResult = RegOpenKeyEx(hRootKey, partialKey, 0, KEY_READ, &hTopKey);
+    if (lResult == ERROR_SUCCESS) {
+      char keyName[256];
+      int bestIndex = -1;
+      double bestValue = 0.0;
+      DWORD index, size = sizeof(keyName) - 1;
+      for (index = 0; RegEnumKeyEx(hTopKey, index, keyName, &size, NULL,
+          NULL, NULL, NULL) == ERROR_SUCCESS; index++) {
+        const char *sp = keyName;
+        while (*sp && !isdigit(*sp))
+          sp++;
+        if (!*sp)
+          continue;
+        const char *ep = sp + 1;
+        while (*ep && (isdigit(*ep) || (*ep == '.')))
+          ep++;
+        char numBuf[32];
+        strncpy(numBuf, sp, sizeof(numBuf) - 1);
+        numBuf[sizeof(numBuf) - 1] = '\0';
+        double value = strtod(numBuf, NULL);
+        if (value > bestValue) {
+          bestIndex = (int)index;
+          bestValue = value;
+          strcpy(bestName, keyName);
+        }
+        size = sizeof(keyName) - 1;
+      }
+      // If we found the highest versioned key, open the key and get the value.
+      if (bestIndex != -1) {
+        // Append rest of key.
+        strncat(bestName, nextKey, sizeof(bestName) - 1);
+        bestName[sizeof(bestName) - 1] = '\0';
+        // Open the chosen key path remainder.
+        lResult = RegOpenKeyEx(hTopKey, bestName, 0, KEY_READ, &hKey);
+        if (lResult == ERROR_SUCCESS) {
+          lResult = RegQueryValueEx(hKey, valueName, NULL, &valueType,
+            (LPBYTE)value, &valueSize);
+          if (lResult == ERROR_SUCCESS)
+            returnValue = true;
+          RegCloseKey(hKey);
+        }
+      }
+      RegCloseKey(hTopKey);
+    }
+  }
+  else {
+    lResult = RegOpenKeyEx(hRootKey, subKey, 0, KEY_READ, &hKey);
+    if (lResult == ERROR_SUCCESS) {
+      lResult = RegQueryValueEx(hKey, valueName, NULL, &valueType,
+        (LPBYTE)value, &valueSize);
+      if (lResult == ERROR_SUCCESS)
+        returnValue = true;
+      RegCloseKey(hKey);
+    }
+  }
+  return(returnValue);
+}
+#else // _MSC_VER
+  // Read registry string.
+static bool getSystemRegistryString(const char*, const char*, char*, size_t) {
+  return(false);
+}
+#endif // _MSC_VER
+
+  // Get Visual Studio installation directory.
+static bool getVisualStudioDir(std::string &path) {
+  char vsIDEInstallDir[256];
+  // Try the Windows registry first.
+  bool hasVCDir = getSystemRegistryString(
+    "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\$VERSION",
+    "InstallDir", vsIDEInstallDir, sizeof(vsIDEInstallDir) - 1);
+    // If we have both vc80 and vc90, pick version we were compiled with. 
+  if (hasVCDir && vsIDEInstallDir[0]) {
+    char *p = (char*)strstr(vsIDEInstallDir, "\\Common7\\IDE");
+    if (p)
+      *p = '\0';
+    path = vsIDEInstallDir;
+    return(true);
+  }
+  else {
+    // Try the environment.
+    const char* vs90comntools = getenv("VS90COMNTOOLS");
+    const char* vs80comntools = getenv("VS80COMNTOOLS");
+    const char* vscomntools = NULL;
+      // If we have both vc80 and vc90, pick version we were compiled with. 
+    if (vs90comntools && vs80comntools) {
+      #if (_MSC_VER >= 1500)  // VC90
+          vscomntools = vs90comntools;
+      #elif (_MSC_VER == 1400) // VC80
+          vscomntools = vs80comntools;
+      #else
+          vscomntools = vs90comntools;
+      #endif
+    }
+    else if (vs90comntools)
+      vscomntools = vs90comntools;
+    else if (vs80comntools)
+      vscomntools = vs80comntools;
+    if (vscomntools && *vscomntools) {
+      char *p = const_cast<char *>(strstr(vscomntools, "\\Common7\\Tools"));
+      if (p)
+        *p = '\0';
+      path = vscomntools;
+      return(true);
+    }
+    else
+      return(false);
+  }
+  return(false);
+}
+
+  // Get Windows SDK installation directory.
+static bool getWindowsSDKDir(std::string &path) {
+  char windowsSDKInstallDir[256];
+  // Try the Windows registry.
+  bool hasSDKDir = getSystemRegistryString(
+   "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\$VERSION",
+    "InstallationFolder", windowsSDKInstallDir, sizeof(windowsSDKInstallDir) - 1);
+    // If we have both vc80 and vc90, pick version we were compiled with. 
+  if (hasSDKDir && windowsSDKInstallDir[0]) {
+    path = windowsSDKInstallDir;
+    return(true);
+  }
+  return(false);
+}
+
+void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple) {
+  // FIXME: temporary hack: hard-coded paths.
+  llvm::StringRef CIncludeDirs(C_INCLUDE_DIRS);
+  if (CIncludeDirs != "") {
+    llvm::SmallVector<llvm::StringRef, 5> dirs;
+    CIncludeDirs.split(dirs, ":");
+    for (llvm::SmallVectorImpl<llvm::StringRef>::iterator i = dirs.begin();
+         i != dirs.end();
+         ++i) 
+      AddPath(*i, System, false, false, false);
+    return;
+  }
+  llvm::Triple::OSType os = triple.getOS();
+  switch (os) {
+  case llvm::Triple::Win32:
+    {
+      std::string VSDir;
+      std::string WindowsSDKDir;
+      if (getVisualStudioDir(VSDir)) {
+        AddPath(VSDir + "\\VC\\include", System, false, false, false);
+        if (getWindowsSDKDir(WindowsSDKDir))
+          AddPath(WindowsSDKDir, System, false, false, false);
+        else
+          AddPath(VSDir + "\\VC\\PlatformSDK\\Include",
+            System, false, false, false);
+      }
+      else {
+          // Default install paths.
+        AddPath("C:/Program Files/Microsoft Visual Studio 9.0/VC/include",
+          System, false, false, false);
+        AddPath(
+        "C:/Program Files/Microsoft Visual Studio 9.0/VC/PlatformSDK/Include",
+          System, false, false, false);
+        AddPath("C:/Program Files/Microsoft Visual Studio 8/VC/include",
+          System, false, false, false);
+        AddPath(
+        "C:/Program Files/Microsoft Visual Studio 8/VC/PlatformSDK/Include",
+          System, false, false, false);
+          // For some clang developers.
+        AddPath("G:/Program Files/Microsoft Visual Studio 9.0/VC/include",
+          System, false, false, false);
+        AddPath(
+        "G:/Program Files/Microsoft Visual Studio 9.0/VC/PlatformSDK/Include",
+          System, false, false, false);
+      }
+    }
+    break;
+  case llvm::Triple::Haiku:
+    AddPath("/boot/common/include", System, true, false, false);
+    AddPath("/boot/develop/headers/os", System, true, false, false);
+    AddPath("/boot/develop/headers/os/app", System, true, false, false);
+    AddPath("/boot/develop/headers/os/arch", System, true, false, false);
+    AddPath("/boot/develop/headers/os/device", System, true, false, false);
+    AddPath("/boot/develop/headers/os/drivers", System, true, false, false);
+    AddPath("/boot/develop/headers/os/game", System, true, false, false); 
+    AddPath("/boot/develop/headers/os/interface", System, true, false, false);
+    AddPath("/boot/develop/headers/os/kernel", System, true, false, false);
+    AddPath("/boot/develop/headers/os/locale", System, true, false, false);
+    AddPath("/boot/develop/headers/os/mail", System, true, false, false);
+    AddPath("/boot/develop/headers/os/media", System, true, false, false);
+    AddPath("/boot/develop/headers/os/midi", System, true, false, false);
+    AddPath("/boot/develop/headers/os/midi2", System, true, false, false);
+    AddPath("/boot/develop/headers/os/net", System, true, false, false);
+    AddPath("/boot/develop/headers/os/storage", System, true, false, false);
+    AddPath("/boot/develop/headers/os/support", System, true, false, false);
+    AddPath("/boot/develop/headers/os/translation",
+      System, true, false, false);
+    AddPath("/boot/develop/headers/os/add-ons/graphics", 
+      System, true, false, false);
+    AddPath("/boot/develop/headers/os/add-ons/input_server", 
+      System, true, false, false);
+    AddPath("/boot/develop/headers/os/add-ons/screen_saver", 
+      System, true, false, false);
+    AddPath("/boot/develop/headers/os/add-ons/tracker", 
+      System, true, false, false);
+    AddPath("/boot/develop/headers/os/be_apps/Deskbar",
+      System, true, false, false);
+    AddPath("/boot/develop/headers/os/be_apps/NetPositive",
+      System, true, false, false);
+    AddPath("/boot/develop/headers/os/be_apps/Tracker",
+      System, true, false, false);
+    AddPath("/boot/develop/headers/cpp", System, true, false, false);
+    AddPath("/boot/develop/headers/cpp/i586-pc-haiku", 
+      System, true, false, false);
+    AddPath("/boot/develop/headers/3rdparty", System, true, false, false);
+    AddPath("/boot/develop/headers/bsd", System, true, false, false);
+    AddPath("/boot/develop/headers/glibc", System, true, false, false);
+    AddPath("/boot/develop/headers/posix", System, true, false, false);
+    AddPath("/boot/develop/headers",  System, true, false, false);
+  	break;
+  case llvm::Triple::MinGW64:
+  case llvm::Triple::MinGW32:
+    AddPath("c:/mingw/include", System, true, false, false);
+    break;
+  default:
+    break;
+  }
+
+  AddPath("/usr/local/include", System, true, false, false);
+  AddPath("/usr/include", System, false, false, false);
+}
+
+void InitHeaderSearch::AddDefaultCPlusPlusIncludePaths(const llvm::Triple &triple) {
+  llvm::Triple::OSType os = triple.getOS();
+  llvm::StringRef CxxIncludeRoot(CXX_INCLUDE_ROOT);
+  if (CxxIncludeRoot != "") {
+    llvm::StringRef CxxIncludeArch(CXX_INCLUDE_ARCH);
+    if (CxxIncludeArch == "")
+      AddGnuCPlusPlusIncludePaths(CxxIncludeRoot, triple.str().c_str(),
+                                  CXX_INCLUDE_32BIT_DIR, CXX_INCLUDE_64BIT_DIR, triple);
+    else
+      AddGnuCPlusPlusIncludePaths(CxxIncludeRoot, CXX_INCLUDE_ARCH,
+                                  CXX_INCLUDE_32BIT_DIR, CXX_INCLUDE_64BIT_DIR, triple);
+    return;
+  }
+  // FIXME: temporary hack: hard-coded paths.
+  switch (os) {
+  case llvm::Triple::Cygwin:
+    AddPath("/lib/gcc/i686-pc-cygwin/3.4.4/include",
+        System, true, false, false);
+    AddPath("/lib/gcc/i686-pc-cygwin/3.4.4/include/c++",
+        System, true, false, false);
+    break;
+  case llvm::Triple::MinGW64:
+    // Try gcc 4.4.0
+    AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw64", "4.4.0");
+    // Try gcc 4.3.0
+    AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw64", "4.3.0");
+    // Fall through.
+  case llvm::Triple::MinGW32:
+    // Try gcc 4.4.0
+    AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.4.0");
+    // Try gcc 4.3.0
+    AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.3.0");
+    break;
+  case llvm::Triple::Darwin:
+    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2.1",
+                                "i686-apple-darwin10", "", "x86_64", triple);
+    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.0.0",
+                                "i686-apple-darwin8", "", "", triple);
+    break;
+  case llvm::Triple::DragonFly:
+    AddPath("/usr/include/c++/4.1", System, true, false, false);
+    break;
+  case llvm::Triple::Linux:
+    // Exherbo (2010-01-25)
+    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.3",
+                                "x86_64-pc-linux-gnu", "32", "", triple);
+    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.3",
+                                "i686-pc-linux-gnu", "", "", triple);
+    // Debian sid
+    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4",
+                                "x86_64-linux-gnu", "32", "", triple);
+    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4",
+                                "i486-linux-gnu", "64", "", triple);
+    // Ubuntu 7.10 - Gutsy Gibbon
+    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.1.3",
+                                "i486-linux-gnu", "", "", triple);
+    // Ubuntu 9.04
+    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3.3",
+                                "x86_64-linux-gnu","32", "", triple);
+    // Ubuntu 9.10
+    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.1",
+                                "x86_64-linux-gnu", "32", "", triple);
+    // Fedora 8
+    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.1.2",
+                                "i386-redhat-linux", "", "", triple);
+    // Fedora 9
+    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3.0",
+                                "i386-redhat-linux", "", "", triple);
+    // Fedora 10
+    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3.2",
+                                "i386-redhat-linux","", "", triple);
+
+    // Fedora 10 x86_64
+    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3.2",
+                                "x86_64-redhat-linux", "32", "", triple);
+
+    // Fedora 11
+    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.1",
+                                "i586-redhat-linux","", "", triple);
+
+    // Fedora 11 x86_64
+    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.1",
+                                "x86_64-redhat-linux", "32", "", triple);
+
+    // Fedora 12
+    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.2",
+                                "i686-redhat-linux","", "", triple);
+
+    // Fedora 12 x86_64
+    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.2",
+                                "x86_64-redhat-linux", "32", "", triple);
+
+    // Fedora 12 (February-2010+)
+    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.3",
+                                "i686-redhat-linux","", "", triple);
+
+    // Fedora 12 (February-2010+) x86_64
+    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.3",
+                                "x86_64-redhat-linux", "32", "", triple);
+
+    // openSUSE 11.1 32 bit
+    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3",
+                                "i586-suse-linux", "", "", triple);
+    // openSUSE 11.1 64 bit
+    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3",
+                                "x86_64-suse-linux", "32", "", triple);
+    // openSUSE 11.2
+    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4",
+                                "i586-suse-linux", "", "", triple);
+    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4",
+                                "x86_64-suse-linux", "", "", triple);
+    // Arch Linux 2008-06-24
+    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3.1",
+                                "i686-pc-linux-gnu", "", "", triple);
+    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3.1",
+                                "x86_64-unknown-linux-gnu", "", "", triple);
+    // Gentoo x86 2009.1 stable
+    AddGnuCPlusPlusIncludePaths(
+      "/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4",
+      "i686-pc-linux-gnu", "", "", triple);
+    // Gentoo x86 2009.0 stable
+    AddGnuCPlusPlusIncludePaths(
+      "/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/include/g++-v4",
+      "i686-pc-linux-gnu", "", "", triple);
+    // Gentoo x86 2008.0 stable
+    AddGnuCPlusPlusIncludePaths(
+      "/usr/lib/gcc/i686-pc-linux-gnu/4.1.2/include/g++-v4",
+      "i686-pc-linux-gnu", "", "", triple);
+    // Ubuntu 8.10
+    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3",
+                                "i486-pc-linux-gnu", "", "", triple);
+    // Ubuntu 9.04
+    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3",
+                                "i486-linux-gnu","", "", triple);
+    // Gentoo amd64 stable
+    AddGnuCPlusPlusIncludePaths(
+        "/usr/lib/gcc/x86_64-pc-linux-gnu/4.1.2/include/g++-v4",
+        "i686-pc-linux-gnu", "", "", triple);
+        
+    // Gentoo amd64 gcc 4.3.2
+    AddGnuCPlusPlusIncludePaths(
+        "/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.2/include/g++-v4",
+        "x86_64-pc-linux-gnu", "", "", triple);
+        
+    // Gentoo amd64 gcc 4.4.3
+    AddGnuCPlusPlusIncludePaths(
+        "/usr/lib/gcc/x86_64-pc-linux-gnu/4.4.3/include/g++-v4",
+        "x86_64-pc-linux-gnu", "32", "", triple);
+    
+    break;
+  case llvm::Triple::FreeBSD:
+    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2", "", "", "", triple);
+    break;
+  case llvm::Triple::Solaris:
+    // Solaris - Fall though..
+  case llvm::Triple::AuroraUX:
+    // AuroraUX
+    AddGnuCPlusPlusIncludePaths("/opt/gcc4/include/c++/4.2.4",
+                                "i386-pc-solaris2.11", "", "", triple);
+    break;
+  default:
+    break;
+  }
+}
+
+void InitHeaderSearch::AddDefaultSystemIncludePaths(const LangOptions &Lang,
+                                                    const llvm::Triple &triple,
+                                                  bool UseStandardCXXIncludes) {
+  if (Lang.CPlusPlus && UseStandardCXXIncludes)
+    AddDefaultCPlusPlusIncludePaths(triple);
+
+  AddDefaultCIncludePaths(triple);
+
+  // Add the default framework include paths on Darwin.
+  if (triple.getOS() == llvm::Triple::Darwin) {
+    AddPath("/System/Library/Frameworks", System, true, false, true);
+    AddPath("/Library/Frameworks", System, true, false, true);
+  }
+}
+
+/// RemoveDuplicates - If there are duplicate directory entries in the specified
+/// search list, remove the later (dead) ones.
+static void RemoveDuplicates(std::vector<DirectoryLookup> &SearchList,
+                             bool Verbose) {
+  llvm::SmallPtrSet<const DirectoryEntry *, 8> SeenDirs;
+  llvm::SmallPtrSet<const DirectoryEntry *, 8> SeenFrameworkDirs;
+  llvm::SmallPtrSet<const HeaderMap *, 8> SeenHeaderMaps;
+  for (unsigned i = 0; i != SearchList.size(); ++i) {
+    unsigned DirToRemove = i;
+
+    const DirectoryLookup &CurEntry = SearchList[i];
+
+    if (CurEntry.isNormalDir()) {
+      // If this isn't the first time we've seen this dir, remove it.
+      if (SeenDirs.insert(CurEntry.getDir()))
+        continue;
+    } else if (CurEntry.isFramework()) {
+      // If this isn't the first time we've seen this framework dir, remove it.
+      if (SeenFrameworkDirs.insert(CurEntry.getFrameworkDir()))
+        continue;
+    } else {
+      assert(CurEntry.isHeaderMap() && "Not a headermap or normal dir?");
+      // If this isn't the first time we've seen this headermap, remove it.
+      if (SeenHeaderMaps.insert(CurEntry.getHeaderMap()))
+        continue;
+    }
+
+    // If we have a normal #include dir/framework/headermap that is shadowed
+    // later in the chain by a system include location, we actually want to
+    // ignore the user's request and drop the user dir... keeping the system
+    // dir.  This is weird, but required to emulate GCC's search path correctly.
+    //
+    // Since dupes of system dirs are rare, just rescan to find the original
+    // that we're nuking instead of using a DenseMap.
+    if (CurEntry.getDirCharacteristic() != SrcMgr::C_User) {
+      // Find the dir that this is the same of.
+      unsigned FirstDir;
+      for (FirstDir = 0; ; ++FirstDir) {
+        assert(FirstDir != i && "Didn't find dupe?");
+
+        const DirectoryLookup &SearchEntry = SearchList[FirstDir];
+
+        // If these are different lookup types, then they can't be the dupe.
+        if (SearchEntry.getLookupType() != CurEntry.getLookupType())
+          continue;
+
+        bool isSame;
+        if (CurEntry.isNormalDir())
+          isSame = SearchEntry.getDir() == CurEntry.getDir();
+        else if (CurEntry.isFramework())
+          isSame = SearchEntry.getFrameworkDir() == CurEntry.getFrameworkDir();
+        else {
+          assert(CurEntry.isHeaderMap() && "Not a headermap or normal dir?");
+          isSame = SearchEntry.getHeaderMap() == CurEntry.getHeaderMap();
+        }
+
+        if (isSame)
+          break;
+      }
+
+      // If the first dir in the search path is a non-system dir, zap it
+      // instead of the system one.
+      if (SearchList[FirstDir].getDirCharacteristic() == SrcMgr::C_User)
+        DirToRemove = FirstDir;
+    }
+
+    if (Verbose) {
+      llvm::errs() << "ignoring duplicate directory \""
+                   << CurEntry.getName() << "\"\n";
+      if (DirToRemove != i)
+        llvm::errs() << "  as it is a non-system directory that duplicates "
+                     << "a system directory\n";
+    }
+
+    // This is reached if the current entry is a duplicate.  Remove the
+    // DirToRemove (usually the current dir).
+    SearchList.erase(SearchList.begin()+DirToRemove);
+    --i;
+  }
+}
+
+
+void InitHeaderSearch::Realize() {
+  // Concatenate ANGLE+SYSTEM+AFTER chains together into SearchList.
+  std::vector<DirectoryLookup> SearchList;
+  SearchList = IncludeGroup[Angled];
+  SearchList.insert(SearchList.end(), IncludeGroup[System].begin(),
+                    IncludeGroup[System].end());
+  SearchList.insert(SearchList.end(), IncludeGroup[After].begin(),
+                    IncludeGroup[After].end());
+  RemoveDuplicates(SearchList, Verbose);
+  RemoveDuplicates(IncludeGroup[Quoted], Verbose);
+
+  // Prepend QUOTED list on the search list.
+  SearchList.insert(SearchList.begin(), IncludeGroup[Quoted].begin(),
+                    IncludeGroup[Quoted].end());
+
+
+  bool DontSearchCurDir = false;  // TODO: set to true if -I- is set?
+  Headers.SetSearchPaths(SearchList, IncludeGroup[Quoted].size(),
+                         DontSearchCurDir);
+
+  // If verbose, print the list of directories that will be searched.
+  if (Verbose) {
+    llvm::errs() << "#include \"...\" search starts here:\n";
+    unsigned QuotedIdx = IncludeGroup[Quoted].size();
+    for (unsigned i = 0, e = SearchList.size(); i != e; ++i) {
+      if (i == QuotedIdx)
+        llvm::errs() << "#include <...> search starts here:\n";
+      const char *Name = SearchList[i].getName();
+      const char *Suffix;
+      if (SearchList[i].isNormalDir())
+        Suffix = "";
+      else if (SearchList[i].isFramework())
+        Suffix = " (framework directory)";
+      else {
+        assert(SearchList[i].isHeaderMap() && "Unknown DirectoryLookup");
+        Suffix = " (headermap)";
+      }
+      llvm::errs() << " " << Name << Suffix << "\n";
+    }
+    llvm::errs() << "End of search list.\n";
+  }
+}
+
+void clang::ApplyHeaderSearchOptions(HeaderSearch &HS,
+                                     const HeaderSearchOptions &HSOpts,
+                                     const LangOptions &Lang,
+                                     const llvm::Triple &Triple) {
+  InitHeaderSearch Init(HS, HSOpts.Verbose, HSOpts.Sysroot);
+
+  // Add the user defined entries.
+  for (unsigned i = 0, e = HSOpts.UserEntries.size(); i != e; ++i) {
+    const HeaderSearchOptions::Entry &E = HSOpts.UserEntries[i];
+    Init.AddPath(E.Path, E.Group, false, E.IsUserSupplied, E.IsFramework,
+                 false);
+  }
+
+  // Add entries from CPATH and friends.
+  Init.AddDelimitedPaths(HSOpts.EnvIncPath);
+  if (Lang.CPlusPlus && Lang.ObjC1)
+    Init.AddDelimitedPaths(HSOpts.ObjCXXEnvIncPath);
+  else if (Lang.CPlusPlus)
+    Init.AddDelimitedPaths(HSOpts.CXXEnvIncPath);
+  else if (Lang.ObjC1)
+    Init.AddDelimitedPaths(HSOpts.ObjCEnvIncPath);
+  else
+    Init.AddDelimitedPaths(HSOpts.CEnvIncPath);
+
+  if (HSOpts.UseBuiltinIncludes) {
+    // Ignore the sys root, we *always* look for clang headers relative to
+    // supplied path.
+    llvm::sys::Path P(HSOpts.ResourceDir);
+    P.appendComponent("include");
+    Init.AddPath(P.str(), System, false, false, false, /*IgnoreSysRoot=*/ true);
+  }
+
+  if (HSOpts.UseStandardIncludes)
+    Init.AddDefaultSystemIncludePaths(Lang, Triple, 
+                                      HSOpts.UseStandardCXXIncludes);
+
+  Init.Realize();
+}
diff --git a/lib/Frontend/InitPreprocessor.cpp b/lib/Frontend/InitPreprocessor.cpp
new file mode 100644
index 0000000..e035afd
--- /dev/null
+++ b/lib/Frontend/InitPreprocessor.cpp
@@ -0,0 +1,554 @@
+//===--- InitPreprocessor.cpp - PP initialization code. ---------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the clang::InitializePreprocessor function.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/Utils.h"
+#include "clang/Basic/MacroBuilder.h"
+#include "clang/Basic/TargetInfo.h"
+#include "clang/Frontend/FrontendDiagnostic.h"
+#include "clang/Frontend/FrontendOptions.h"
+#include "clang/Frontend/PreprocessorOptions.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/SourceManager.h"
+#include "llvm/ADT/APFloat.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/System/Path.h"
+using namespace clang;
+
+// Append a #define line to Buf for Macro.  Macro should be of the form XXX,
+// in which case we emit "#define XXX 1" or "XXX=Y z W" in which case we emit
+// "#define XXX Y z W".  To get a #define with no value, use "XXX=".
+static void DefineBuiltinMacro(MacroBuilder &Builder, llvm::StringRef Macro,
+                               Diagnostic &Diags) {
+  std::pair<llvm::StringRef, llvm::StringRef> MacroPair = Macro.split('=');
+  llvm::StringRef MacroName = MacroPair.first;
+  llvm::StringRef MacroBody = MacroPair.second;
+  if (MacroName.size() != Macro.size()) {
+    // Per GCC -D semantics, the macro ends at \n if it exists.
+    llvm::StringRef::size_type End = MacroBody.find_first_of("\n\r");
+    if (End != llvm::StringRef::npos)
+      Diags.Report(diag::warn_fe_macro_contains_embedded_newline)
+        << MacroName;
+    Builder.defineMacro(MacroName, MacroBody.substr(0, End));
+  } else {
+    // Push "macroname 1".
+    Builder.defineMacro(Macro);
+  }
+}
+
+std::string clang::NormalizeDashIncludePath(llvm::StringRef File) {
+  // Implicit include paths should be resolved relative to the current
+  // working directory first, and then use the regular header search
+  // mechanism. The proper way to handle this is to have the
+  // predefines buffer located at the current working directory, but
+  // it has not file entry. For now, workaround this by using an
+  // absolute path if we find the file here, and otherwise letting
+  // header search handle it.
+  llvm::sys::Path Path(File);
+  Path.makeAbsolute();
+  if (!Path.exists())
+    Path = File;
+
+  return Lexer::Stringify(Path.str());
+}
+
+/// AddImplicitInclude - Add an implicit #include of the specified file to the
+/// predefines buffer.
+static void AddImplicitInclude(MacroBuilder &Builder, llvm::StringRef File) {
+  Builder.append("#include \"" +
+                 llvm::Twine(NormalizeDashIncludePath(File)) + "\"");
+}
+
+static void AddImplicitIncludeMacros(MacroBuilder &Builder,
+                                     llvm::StringRef File) {
+  Builder.append("#__include_macros \"" +
+                 llvm::Twine(NormalizeDashIncludePath(File)) + "\"");
+  // Marker token to stop the __include_macros fetch loop.
+  Builder.append("##"); // ##?
+}
+
+/// AddImplicitIncludePTH - Add an implicit #include using the original file
+///  used to generate a PTH cache.
+static void AddImplicitIncludePTH(MacroBuilder &Builder, Preprocessor &PP,
+                                  llvm::StringRef ImplicitIncludePTH) {
+  PTHManager *P = PP.getPTHManager();
+  assert(P && "No PTHManager.");
+  const char *OriginalFile = P->getOriginalSourceFile();
+
+  if (!OriginalFile) {
+    PP.getDiagnostics().Report(diag::err_fe_pth_file_has_no_source_header)
+      << ImplicitIncludePTH;
+    return;
+  }
+
+  AddImplicitInclude(Builder, OriginalFile);
+}
+
+/// PickFP - This is used to pick a value based on the FP semantics of the
+/// specified FP model.
+template <typename T>
+static T PickFP(const llvm::fltSemantics *Sem, T IEEESingleVal,
+                T IEEEDoubleVal, T X87DoubleExtendedVal, T PPCDoubleDoubleVal,
+                T IEEEQuadVal) {
+  if (Sem == (const llvm::fltSemantics*)&llvm::APFloat::IEEEsingle)
+    return IEEESingleVal;
+  if (Sem == (const llvm::fltSemantics*)&llvm::APFloat::IEEEdouble)
+    return IEEEDoubleVal;
+  if (Sem == (const llvm::fltSemantics*)&llvm::APFloat::x87DoubleExtended)
+    return X87DoubleExtendedVal;
+  if (Sem == (const llvm::fltSemantics*)&llvm::APFloat::PPCDoubleDouble)
+    return PPCDoubleDoubleVal;
+  assert(Sem == (const llvm::fltSemantics*)&llvm::APFloat::IEEEquad);
+  return IEEEQuadVal;
+}
+
+static void DefineFloatMacros(MacroBuilder &Builder, llvm::StringRef Prefix,
+                              const llvm::fltSemantics *Sem) {
+  const char *DenormMin, *Epsilon, *Max, *Min;
+  DenormMin = PickFP(Sem, "1.40129846e-45F", "4.9406564584124654e-324",
+                     "3.64519953188247460253e-4951L",
+                     "4.94065645841246544176568792868221e-324L",
+                     "6.47517511943802511092443895822764655e-4966L");
+  int Digits = PickFP(Sem, 6, 15, 18, 31, 33);
+  Epsilon = PickFP(Sem, "1.19209290e-7F", "2.2204460492503131e-16",
+                   "1.08420217248550443401e-19L",
+                   "4.94065645841246544176568792868221e-324L",
+                   "1.92592994438723585305597794258492732e-34L");
+  int MantissaDigits = PickFP(Sem, 24, 53, 64, 106, 113);
+  int Min10Exp = PickFP(Sem, -37, -307, -4931, -291, -4931);
+  int Max10Exp = PickFP(Sem, 38, 308, 4932, 308, 4932);
+  int MinExp = PickFP(Sem, -125, -1021, -16381, -968, -16381);
+  int MaxExp = PickFP(Sem, 128, 1024, 16384, 1024, 16384);
+  Min = PickFP(Sem, "1.17549435e-38F", "2.2250738585072014e-308",
+               "3.36210314311209350626e-4932L",
+               "2.00416836000897277799610805135016e-292L",
+               "3.36210314311209350626267781732175260e-4932L");
+  Max = PickFP(Sem, "3.40282347e+38F", "1.7976931348623157e+308",
+               "1.18973149535723176502e+4932L",
+               "1.79769313486231580793728971405301e+308L",
+               "1.18973149535723176508575932662800702e+4932L");
+
+  llvm::SmallString<32> DefPrefix;
+  DefPrefix = "__";
+  DefPrefix += Prefix;
+  DefPrefix += "_";
+
+  Builder.defineMacro(DefPrefix + "DENORM_MIN__", DenormMin);
+  Builder.defineMacro(DefPrefix + "HAS_DENORM__");
+  Builder.defineMacro(DefPrefix + "DIG__", llvm::Twine(Digits));
+  Builder.defineMacro(DefPrefix + "EPSILON__", llvm::Twine(Epsilon));
+  Builder.defineMacro(DefPrefix + "HAS_INFINITY__");
+  Builder.defineMacro(DefPrefix + "HAS_QUIET_NAN__");
+  Builder.defineMacro(DefPrefix + "MANT_DIG__", llvm::Twine(MantissaDigits));
+
+  Builder.defineMacro(DefPrefix + "MAX_10_EXP__", llvm::Twine(Max10Exp));
+  Builder.defineMacro(DefPrefix + "MAX_EXP__", llvm::Twine(MaxExp));
+  Builder.defineMacro(DefPrefix + "MAX__", llvm::Twine(Max));
+
+  Builder.defineMacro(DefPrefix + "MIN_10_EXP__","("+llvm::Twine(Min10Exp)+")");
+  Builder.defineMacro(DefPrefix + "MIN_EXP__", "("+llvm::Twine(MinExp)+")");
+  Builder.defineMacro(DefPrefix + "MIN__", llvm::Twine(Min));
+}
+
+
+/// DefineTypeSize - Emit a macro to the predefines buffer that declares a macro
+/// named MacroName with the max value for a type with width 'TypeWidth' a
+/// signedness of 'isSigned' and with a value suffix of 'ValSuffix' (e.g. LL).
+static void DefineTypeSize(llvm::StringRef MacroName, unsigned TypeWidth,
+                           llvm::StringRef ValSuffix, bool isSigned,
+                           MacroBuilder& Builder) {
+  long long MaxVal;
+  if (isSigned)
+    MaxVal = (1LL << (TypeWidth - 1)) - 1;
+  else
+    MaxVal = ~0LL >> (64-TypeWidth);
+
+  Builder.defineMacro(MacroName, llvm::Twine(MaxVal) + ValSuffix);
+}
+
+/// DefineTypeSize - An overloaded helper that uses TargetInfo to determine
+/// the width, suffix, and signedness of the given type
+static void DefineTypeSize(llvm::StringRef MacroName, TargetInfo::IntType Ty,
+                           const TargetInfo &TI, MacroBuilder &Builder) {
+  DefineTypeSize(MacroName, TI.getTypeWidth(Ty), TI.getTypeConstantSuffix(Ty), 
+                 TI.isTypeSigned(Ty), Builder);
+}
+
+static void DefineType(const llvm::Twine &MacroName, TargetInfo::IntType Ty,
+                       MacroBuilder &Builder) {
+  Builder.defineMacro(MacroName, TargetInfo::getTypeName(Ty));
+}
+
+static void DefineTypeWidth(llvm::StringRef MacroName, TargetInfo::IntType Ty,
+                            const TargetInfo &TI, MacroBuilder &Builder) {
+  Builder.defineMacro(MacroName, llvm::Twine(TI.getTypeWidth(Ty)));
+}
+
+static void DefineExactWidthIntType(TargetInfo::IntType Ty, 
+                               const TargetInfo &TI, MacroBuilder &Builder) {
+  int TypeWidth = TI.getTypeWidth(Ty);
+  DefineType("__INT" + llvm::Twine(TypeWidth) + "_TYPE__", Ty, Builder);
+
+  llvm::StringRef ConstSuffix(TargetInfo::getTypeConstantSuffix(Ty));
+  if (!ConstSuffix.empty())
+    Builder.defineMacro("__INT" + llvm::Twine(TypeWidth) + "_C_SUFFIX__",
+                        ConstSuffix);
+}
+
+static void InitializePredefinedMacros(const TargetInfo &TI,
+                                       const LangOptions &LangOpts,
+                                       const FrontendOptions &FEOpts,
+                                       MacroBuilder &Builder) {
+  // Compiler version introspection macros.
+  Builder.defineMacro("__llvm__");  // LLVM Backend
+  Builder.defineMacro("__clang__"); // Clang Frontend
+
+  // Currently claim to be compatible with GCC 4.2.1-5621.
+  Builder.defineMacro("__GNUC_MINOR__", "2");
+  Builder.defineMacro("__GNUC_PATCHLEVEL__", "1");
+  Builder.defineMacro("__GNUC__", "4");
+  Builder.defineMacro("__GXX_ABI_VERSION", "1002");
+  Builder.defineMacro("__VERSION__", "\"4.2.1 Compatible Clang Compiler\"");
+
+  // Initialize language-specific preprocessor defines.
+
+  // These should all be defined in the preprocessor according to the
+  // current language configuration.
+  if (!LangOpts.Microsoft)
+    Builder.defineMacro("__STDC__");
+  if (LangOpts.AsmPreprocessor)
+    Builder.defineMacro("__ASSEMBLER__");
+
+  if (!LangOpts.CPlusPlus) {
+    if (LangOpts.C99)
+      Builder.defineMacro("__STDC_VERSION__", "199901L");
+    else if (!LangOpts.GNUMode && LangOpts.Digraphs)
+      Builder.defineMacro("__STDC_VERSION__", "199409L");
+  }
+
+  // Standard conforming mode?
+  if (!LangOpts.GNUMode)
+    Builder.defineMacro("__STRICT_ANSI__");
+
+  if (LangOpts.CPlusPlus0x)
+    Builder.defineMacro("__GXX_EXPERIMENTAL_CXX0X__");
+
+  if (LangOpts.Freestanding)
+    Builder.defineMacro("__STDC_HOSTED__", "0");
+  else
+    Builder.defineMacro("__STDC_HOSTED__");
+
+  if (LangOpts.ObjC1) {
+    Builder.defineMacro("__OBJC__");
+    if (LangOpts.ObjCNonFragileABI) {
+      Builder.defineMacro("__OBJC2__");
+      Builder.defineMacro("OBJC_ZEROCOST_EXCEPTIONS");
+    }
+
+    if (LangOpts.getGCMode() != LangOptions::NonGC)
+      Builder.defineMacro("__OBJC_GC__");
+
+    if (LangOpts.NeXTRuntime)
+      Builder.defineMacro("__NEXT_RUNTIME__");
+  }
+
+  // darwin_constant_cfstrings controls this. This is also dependent
+  // on other things like the runtime I believe.  This is set even for C code.
+  Builder.defineMacro("__CONSTANT_CFSTRINGS__");
+
+  if (LangOpts.ObjC2)
+    Builder.defineMacro("OBJC_NEW_PROPERTIES");
+
+  if (LangOpts.PascalStrings)
+    Builder.defineMacro("__PASCAL_STRINGS__");
+
+  if (LangOpts.Blocks) {
+    Builder.defineMacro("__block", "__attribute__((__blocks__(byref)))");
+    Builder.defineMacro("__BLOCKS__");
+  }
+
+  if (LangOpts.Exceptions)
+    Builder.defineMacro("__EXCEPTIONS");
+  if (LangOpts.SjLjExceptions)
+    Builder.defineMacro("__USING_SJLJ_EXCEPTIONS__");
+
+  if (LangOpts.CPlusPlus) {
+    Builder.defineMacro("__DEPRECATED");
+    Builder.defineMacro("__GNUG__", "4");
+    Builder.defineMacro("__GXX_WEAK__");
+    if (LangOpts.GNUMode)
+      Builder.defineMacro("__cplusplus");
+    else
+      // C++ [cpp.predefined]p1:
+      //   The name_ _cplusplusis defined to the value199711Lwhen compiling a
+      //   C++ translation unit.
+      Builder.defineMacro("__cplusplus", "199711L");
+    Builder.defineMacro("__private_extern__", "extern");
+  }
+
+  if (LangOpts.Microsoft) {
+    // Filter out some microsoft extensions when trying to parse in ms-compat
+    // mode.
+    Builder.defineMacro("__int8", "__INT8_TYPE__");
+    Builder.defineMacro("__int16", "__INT16_TYPE__");
+    Builder.defineMacro("__int32", "__INT32_TYPE__");
+    Builder.defineMacro("__int64", "__INT64_TYPE__");
+    // Both __PRETTY_FUNCTION__ and __FUNCTION__ are GCC extensions, however
+    // VC++ appears to only like __FUNCTION__.
+    Builder.defineMacro("__PRETTY_FUNCTION__", "__FUNCTION__");
+    // Work around some issues with Visual C++ headerws.
+    if (LangOpts.CPlusPlus) {
+      // Since we define wchar_t in C++ mode.
+      Builder.defineMacro("_WCHAR_T_DEFINED");
+      Builder.defineMacro("_NATIVE_WCHAR_T_DEFINED");
+      // FIXME:  This should be temporary until we have a __pragma
+      // solution, to avoid some errors flagged in VC++ headers.
+      Builder.defineMacro("_CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES", "0");
+    }
+  }
+
+  if (LangOpts.Optimize)
+    Builder.defineMacro("__OPTIMIZE__");
+  if (LangOpts.OptimizeSize)
+    Builder.defineMacro("__OPTIMIZE_SIZE__");
+
+  // Initialize target-specific preprocessor defines.
+
+  // Define type sizing macros based on the target properties.
+  assert(TI.getCharWidth() == 8 && "Only support 8-bit char so far");
+  Builder.defineMacro("__CHAR_BIT__", "8");
+
+  DefineTypeSize("__SCHAR_MAX__", TI.getCharWidth(), "", true, Builder);
+  DefineTypeSize("__SHRT_MAX__", TargetInfo::SignedShort, TI, Builder);
+  DefineTypeSize("__INT_MAX__", TargetInfo::SignedInt, TI, Builder);
+  DefineTypeSize("__LONG_MAX__", TargetInfo::SignedLong, TI, Builder);
+  DefineTypeSize("__LONG_LONG_MAX__", TargetInfo::SignedLongLong, TI, Builder);
+  DefineTypeSize("__WCHAR_MAX__", TI.getWCharType(), TI, Builder);
+  DefineTypeSize("__INTMAX_MAX__", TI.getIntMaxType(), TI, Builder);
+
+  DefineType("__INTMAX_TYPE__", TI.getIntMaxType(), Builder);
+  DefineType("__UINTMAX_TYPE__", TI.getUIntMaxType(), Builder);
+  DefineTypeWidth("__INTMAX_WIDTH__",  TI.getIntMaxType(), TI, Builder);
+  DefineType("__PTRDIFF_TYPE__", TI.getPtrDiffType(0), Builder);
+  DefineTypeWidth("__PTRDIFF_WIDTH__", TI.getPtrDiffType(0), TI, Builder);
+  DefineType("__INTPTR_TYPE__", TI.getIntPtrType(), Builder);
+  DefineTypeWidth("__INTPTR_WIDTH__", TI.getIntPtrType(), TI, Builder);
+  DefineType("__SIZE_TYPE__", TI.getSizeType(), Builder);
+  DefineTypeWidth("__SIZE_WIDTH__", TI.getSizeType(), TI, Builder);
+  DefineType("__WCHAR_TYPE__", TI.getWCharType(), Builder);
+  DefineTypeWidth("__WCHAR_WIDTH__", TI.getWCharType(), TI, Builder);
+  DefineType("__WINT_TYPE__", TI.getWIntType(), Builder);
+  DefineTypeWidth("__WINT_WIDTH__", TI.getWIntType(), TI, Builder);
+  DefineTypeWidth("__SIG_ATOMIC_WIDTH__", TI.getSigAtomicType(), TI, Builder);
+
+  DefineFloatMacros(Builder, "FLT", &TI.getFloatFormat());
+  DefineFloatMacros(Builder, "DBL", &TI.getDoubleFormat());
+  DefineFloatMacros(Builder, "LDBL", &TI.getLongDoubleFormat());
+
+  // Define a __POINTER_WIDTH__ macro for stdint.h.
+  Builder.defineMacro("__POINTER_WIDTH__",
+                      llvm::Twine((int)TI.getPointerWidth(0)));
+
+  if (!LangOpts.CharIsSigned)
+    Builder.defineMacro("__CHAR_UNSIGNED__");
+
+  // Define exact-width integer types for stdint.h
+  Builder.defineMacro("__INT" + llvm::Twine(TI.getCharWidth()) + "_TYPE__",
+                      "char");
+
+  if (TI.getShortWidth() > TI.getCharWidth())
+    DefineExactWidthIntType(TargetInfo::SignedShort, TI, Builder);
+
+  if (TI.getIntWidth() > TI.getShortWidth())
+    DefineExactWidthIntType(TargetInfo::SignedInt, TI, Builder);
+
+  if (TI.getLongWidth() > TI.getIntWidth())
+    DefineExactWidthIntType(TargetInfo::SignedLong, TI, Builder);
+
+  if (TI.getLongLongWidth() > TI.getLongWidth())
+    DefineExactWidthIntType(TargetInfo::SignedLongLong, TI, Builder);
+
+  // Add __builtin_va_list typedef.
+  Builder.append(TI.getVAListDeclaration());
+
+  if (const char *Prefix = TI.getUserLabelPrefix())
+    Builder.defineMacro("__USER_LABEL_PREFIX__", Prefix);
+
+  // Build configuration options.  FIXME: these should be controlled by
+  // command line options or something.
+  Builder.defineMacro("__FINITE_MATH_ONLY__", "0");
+
+  if (LangOpts.GNUInline)
+    Builder.defineMacro("__GNUC_GNU_INLINE__");
+  else
+    Builder.defineMacro("__GNUC_STDC_INLINE__");
+
+  if (LangOpts.NoInline)
+    Builder.defineMacro("__NO_INLINE__");
+
+  if (unsigned PICLevel = LangOpts.PICLevel) {
+    Builder.defineMacro("__PIC__", llvm::Twine(PICLevel));
+    Builder.defineMacro("__pic__", llvm::Twine(PICLevel));
+  }
+
+  // Macros to control C99 numerics and <float.h>
+  Builder.defineMacro("__FLT_EVAL_METHOD__", "0");
+  Builder.defineMacro("__FLT_RADIX__", "2");
+  int Dig = PickFP(&TI.getLongDoubleFormat(), -1/*FIXME*/, 17, 21, 33, 36);
+  Builder.defineMacro("__DECIMAL_DIG__", llvm::Twine(Dig));
+
+  if (LangOpts.getStackProtectorMode() == LangOptions::SSPOn)
+    Builder.defineMacro("__SSP__");
+  else if (LangOpts.getStackProtectorMode() == LangOptions::SSPReq)
+    Builder.defineMacro("__SSP_ALL__", "2");
+
+  if (FEOpts.ProgramAction == frontend::RewriteObjC)
+    Builder.defineMacro("__weak", "__attribute__((objc_gc(weak)))");
+  // Get other target #defines.
+  TI.getTargetDefines(LangOpts, Builder);
+}
+
+// Initialize the remapping of files to alternative contents, e.g.,
+// those specified through other files.
+static void InitializeFileRemapping(Diagnostic &Diags,
+                                    SourceManager &SourceMgr,
+                                    FileManager &FileMgr,
+                                    const PreprocessorOptions &InitOpts) {
+  // Remap files in the source manager (with buffers).
+  for (PreprocessorOptions::remapped_file_buffer_iterator
+         Remap = InitOpts.remapped_file_buffer_begin(),
+         RemapEnd = InitOpts.remapped_file_buffer_end();
+       Remap != RemapEnd;
+       ++Remap) {
+    // Create the file entry for the file that we're mapping from.
+    const FileEntry *FromFile = FileMgr.getVirtualFile(Remap->first,
+                                                Remap->second->getBufferSize(),
+                                                       0);
+    if (!FromFile) {
+      Diags.Report(diag::err_fe_remap_missing_from_file)
+        << Remap->first;
+      delete Remap->second;
+      continue;
+    }
+
+    // Override the contents of the "from" file with the contents of
+    // the "to" file.
+    SourceMgr.overrideFileContents(FromFile, Remap->second);
+  }
+
+  // Remap files in the source manager (with other files).
+  for (PreprocessorOptions::remapped_file_iterator
+       Remap = InitOpts.remapped_file_begin(),
+       RemapEnd = InitOpts.remapped_file_end();
+       Remap != RemapEnd;
+       ++Remap) {
+    // Find the file that we're mapping to.
+    const FileEntry *ToFile = FileMgr.getFile(Remap->second);
+    if (!ToFile) {
+      Diags.Report(diag::err_fe_remap_missing_to_file)
+      << Remap->first << Remap->second;
+      continue;
+    }
+    
+    // Create the file entry for the file that we're mapping from.
+    const FileEntry *FromFile = FileMgr.getVirtualFile(Remap->first,
+                                                       ToFile->getSize(),
+                                                       0);
+    if (!FromFile) {
+      Diags.Report(diag::err_fe_remap_missing_from_file)
+      << Remap->first;
+      continue;
+    }
+    
+    // Load the contents of the file we're mapping to.
+    std::string ErrorStr;
+    const llvm::MemoryBuffer *Buffer
+    = llvm::MemoryBuffer::getFile(ToFile->getName(), &ErrorStr);
+    if (!Buffer) {
+      Diags.Report(diag::err_fe_error_opening)
+        << Remap->second << ErrorStr;
+      continue;
+    }
+    
+    // Override the contents of the "from" file with the contents of
+    // the "to" file.
+    SourceMgr.overrideFileContents(FromFile, Buffer);
+  }
+}
+
+/// InitializePreprocessor - Initialize the preprocessor getting it and the
+/// environment ready to process a single file. This returns true on error.
+///
+void clang::InitializePreprocessor(Preprocessor &PP,
+                                   const PreprocessorOptions &InitOpts,
+                                   const HeaderSearchOptions &HSOpts,
+                                   const FrontendOptions &FEOpts) {
+  std::string PredefineBuffer;
+  PredefineBuffer.reserve(4080);
+  llvm::raw_string_ostream Predefines(PredefineBuffer);
+  MacroBuilder Builder(Predefines);
+
+  InitializeFileRemapping(PP.getDiagnostics(), PP.getSourceManager(),
+                          PP.getFileManager(), InitOpts);
+
+  // Emit line markers for various builtin sections of the file.  We don't do
+  // this in asm preprocessor mode, because "# 4" is not a line marker directive
+  // in this mode.
+  if (!PP.getLangOptions().AsmPreprocessor)
+    Builder.append("# 1 \"<built-in>\" 3");
+
+  // Install things like __POWERPC__, __GNUC__, etc into the macro table.
+  if (InitOpts.UsePredefines)
+    InitializePredefinedMacros(PP.getTargetInfo(), PP.getLangOptions(),
+                               FEOpts, Builder);
+
+  // Add on the predefines from the driver.  Wrap in a #line directive to report
+  // that they come from the command line.
+  if (!PP.getLangOptions().AsmPreprocessor)
+    Builder.append("# 1 \"<command line>\" 1");
+
+  // Process #define's and #undef's in the order they are given.
+  for (unsigned i = 0, e = InitOpts.Macros.size(); i != e; ++i) {
+    if (InitOpts.Macros[i].second)  // isUndef
+      Builder.undefineMacro(InitOpts.Macros[i].first);
+    else
+      DefineBuiltinMacro(Builder, InitOpts.Macros[i].first,
+                         PP.getDiagnostics());
+  }
+
+  // If -imacros are specified, include them now.  These are processed before
+  // any -include directives.
+  for (unsigned i = 0, e = InitOpts.MacroIncludes.size(); i != e; ++i)
+    AddImplicitIncludeMacros(Builder, InitOpts.MacroIncludes[i]);
+
+  // Process -include directives.
+  for (unsigned i = 0, e = InitOpts.Includes.size(); i != e; ++i) {
+    const std::string &Path = InitOpts.Includes[i];
+    if (Path == InitOpts.ImplicitPTHInclude)
+      AddImplicitIncludePTH(Builder, PP, Path);
+    else
+      AddImplicitInclude(Builder, Path);
+  }
+
+  // Exit the command line and go back to <built-in> (2 is LC_LEAVE).
+  if (!PP.getLangOptions().AsmPreprocessor)
+    Builder.append("# 1 \"<built-in>\" 2");
+
+  // Copy PredefinedBuffer into the Preprocessor.
+  PP.setPredefines(Predefines.str());
+
+  // Initialize the header search object.
+  ApplyHeaderSearchOptions(PP.getHeaderSearchInfo(), HSOpts,
+                           PP.getLangOptions(),
+                           PP.getTargetInfo().getTriple());
+}
diff --git a/lib/Frontend/LangStandards.cpp b/lib/Frontend/LangStandards.cpp
new file mode 100644
index 0000000..af1721d
--- /dev/null
+++ b/lib/Frontend/LangStandards.cpp
@@ -0,0 +1,44 @@
+//===--- LangStandards.cpp - Language Standard Definitions ----------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/LangStandard.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Support/ErrorHandling.h"
+using namespace clang;
+using namespace clang::frontend;
+
+#define LANGSTANDARD(id, name, desc, features) \
+  static const LangStandard Lang_##id = { name, desc, features };
+#include "clang/Frontend/LangStandards.def"
+
+const LangStandard &LangStandard::getLangStandardForKind(Kind K) {
+  switch (K) {
+  default:
+    llvm_unreachable("Invalid language kind!");
+  case lang_unspecified:
+    llvm::report_fatal_error("getLangStandardForKind() on unspecified kind");
+#define LANGSTANDARD(id, name, desc, features) \
+    case lang_##id: return Lang_##id;
+#include "clang/Frontend/LangStandards.def"
+  }
+}
+
+const LangStandard *LangStandard::getLangStandardForName(llvm::StringRef Name) {
+  Kind K = llvm::StringSwitch<Kind>(Name)
+#define LANGSTANDARD(id, name, desc, features) \
+    .Case(name, lang_##id)
+#include "clang/Frontend/LangStandards.def"
+    .Default(lang_unspecified);
+  if (K == lang_unspecified)
+    return 0;
+
+  return &getLangStandardForKind(K);
+}
+
+
diff --git a/lib/Frontend/Makefile b/lib/Frontend/Makefile
new file mode 100644
index 0000000..9e1a864
--- /dev/null
+++ b/lib/Frontend/Makefile
@@ -0,0 +1,17 @@
+##===- clang/lib/Frontend/Makefile -------------------------*- Makefile -*-===##
+# 
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+# 
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../../../..
+LIBRARYNAME := clangFrontend
+BUILD_ARCHIVE = 1
+
+CPP.Flags += -I$(PROJ_SRC_DIR)/../../include -I$(PROJ_OBJ_DIR)/../../include
+
+include $(LEVEL)/Makefile.common
+
diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp
new file mode 100644
index 0000000..ae57ce5
--- /dev/null
+++ b/lib/Frontend/PCHReader.cpp
@@ -0,0 +1,3045 @@
+//===--- PCHReader.cpp - Precompiled Headers Reader -------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the PCHReader class, which reads a precompiled header.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/PCHReader.h"
+#include "clang/Frontend/FrontendDiagnostic.h"
+#include "clang/Frontend/Utils.h"
+#include "../Sema/Sema.h" // FIXME: move Sema headers elsewhere
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/TypeLocVisitor.h"
+#include "clang/Lex/MacroInfo.h"
+#include "clang/Lex/PreprocessingRecord.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Lex/HeaderSearch.h"
+#include "clang/Basic/OnDiskHashTable.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/SourceManagerInternals.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/TargetInfo.h"
+#include "clang/Basic/Version.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Bitcode/BitstreamReader.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/System/Path.h"
+#include <algorithm>
+#include <iterator>
+#include <cstdio>
+#include <sys/stat.h>
+using namespace clang;
+
+//===----------------------------------------------------------------------===//
+// PCH reader validator implementation
+//===----------------------------------------------------------------------===//
+
+PCHReaderListener::~PCHReaderListener() {}
+
+bool
+PCHValidator::ReadLanguageOptions(const LangOptions &LangOpts) {
+  const LangOptions &PPLangOpts = PP.getLangOptions();
+#define PARSE_LANGOPT_BENIGN(Option)
+#define PARSE_LANGOPT_IMPORTANT(Option, DiagID)                    \
+  if (PPLangOpts.Option != LangOpts.Option) {                      \
+    Reader.Diag(DiagID) << LangOpts.Option << PPLangOpts.Option;   \
+    return true;                                                   \
+  }
+
+  PARSE_LANGOPT_BENIGN(Trigraphs);
+  PARSE_LANGOPT_BENIGN(BCPLComment);
+  PARSE_LANGOPT_BENIGN(DollarIdents);
+  PARSE_LANGOPT_BENIGN(AsmPreprocessor);
+  PARSE_LANGOPT_IMPORTANT(GNUMode, diag::warn_pch_gnu_extensions);
+  PARSE_LANGOPT_IMPORTANT(GNUKeywords, diag::warn_pch_gnu_keywords);
+  PARSE_LANGOPT_BENIGN(ImplicitInt);
+  PARSE_LANGOPT_BENIGN(Digraphs);
+  PARSE_LANGOPT_BENIGN(HexFloats);
+  PARSE_LANGOPT_IMPORTANT(C99, diag::warn_pch_c99);
+  PARSE_LANGOPT_IMPORTANT(Microsoft, diag::warn_pch_microsoft_extensions);
+  PARSE_LANGOPT_IMPORTANT(CPlusPlus, diag::warn_pch_cplusplus);
+  PARSE_LANGOPT_IMPORTANT(CPlusPlus0x, diag::warn_pch_cplusplus0x);
+  PARSE_LANGOPT_BENIGN(CXXOperatorName);
+  PARSE_LANGOPT_IMPORTANT(ObjC1, diag::warn_pch_objective_c);
+  PARSE_LANGOPT_IMPORTANT(ObjC2, diag::warn_pch_objective_c2);
+  PARSE_LANGOPT_IMPORTANT(ObjCNonFragileABI, diag::warn_pch_nonfragile_abi);
+  PARSE_LANGOPT_IMPORTANT(ObjCNonFragileABI2, diag::warn_pch_nonfragile_abi2);
+  PARSE_LANGOPT_IMPORTANT(NoConstantCFStrings, 
+                          diag::warn_pch_no_constant_cfstrings);
+  PARSE_LANGOPT_BENIGN(PascalStrings);
+  PARSE_LANGOPT_BENIGN(WritableStrings);
+  PARSE_LANGOPT_IMPORTANT(LaxVectorConversions,
+                          diag::warn_pch_lax_vector_conversions);
+  PARSE_LANGOPT_IMPORTANT(AltiVec, diag::warn_pch_altivec);
+  PARSE_LANGOPT_IMPORTANT(Exceptions, diag::warn_pch_exceptions);
+  PARSE_LANGOPT_IMPORTANT(SjLjExceptions, diag::warn_pch_sjlj_exceptions);
+  PARSE_LANGOPT_IMPORTANT(NeXTRuntime, diag::warn_pch_objc_runtime);
+  PARSE_LANGOPT_IMPORTANT(Freestanding, diag::warn_pch_freestanding);
+  PARSE_LANGOPT_IMPORTANT(NoBuiltin, diag::warn_pch_builtins);
+  PARSE_LANGOPT_IMPORTANT(ThreadsafeStatics,
+                          diag::warn_pch_thread_safe_statics);
+  PARSE_LANGOPT_IMPORTANT(POSIXThreads, diag::warn_pch_posix_threads);
+  PARSE_LANGOPT_IMPORTANT(Blocks, diag::warn_pch_blocks);
+  PARSE_LANGOPT_BENIGN(EmitAllDecls);
+  PARSE_LANGOPT_IMPORTANT(MathErrno, diag::warn_pch_math_errno);
+  PARSE_LANGOPT_IMPORTANT(OverflowChecking, diag::warn_pch_overflow_checking);
+  PARSE_LANGOPT_IMPORTANT(HeinousExtensions,
+                          diag::warn_pch_heinous_extensions);
+  // FIXME: Most of the options below are benign if the macro wasn't
+  // used. Unfortunately, this means that a PCH compiled without
+  // optimization can't be used with optimization turned on, even
+  // though the only thing that changes is whether __OPTIMIZE__ was
+  // defined... but if __OPTIMIZE__ never showed up in the header, it
+  // doesn't matter. We could consider making this some special kind
+  // of check.
+  PARSE_LANGOPT_IMPORTANT(Optimize, diag::warn_pch_optimize);
+  PARSE_LANGOPT_IMPORTANT(OptimizeSize, diag::warn_pch_optimize_size);
+  PARSE_LANGOPT_IMPORTANT(Static, diag::warn_pch_static);
+  PARSE_LANGOPT_IMPORTANT(PICLevel, diag::warn_pch_pic_level);
+  PARSE_LANGOPT_IMPORTANT(GNUInline, diag::warn_pch_gnu_inline);
+  PARSE_LANGOPT_IMPORTANT(NoInline, diag::warn_pch_no_inline);
+  PARSE_LANGOPT_IMPORTANT(AccessControl, diag::warn_pch_access_control);
+  PARSE_LANGOPT_IMPORTANT(CharIsSigned, diag::warn_pch_char_signed);
+  PARSE_LANGOPT_IMPORTANT(ShortWChar, diag::warn_pch_short_wchar);
+  if ((PPLangOpts.getGCMode() != 0) != (LangOpts.getGCMode() != 0)) {
+    Reader.Diag(diag::warn_pch_gc_mode)
+      << LangOpts.getGCMode() << PPLangOpts.getGCMode();
+    return true;
+  }
+  PARSE_LANGOPT_BENIGN(getVisibilityMode());
+  PARSE_LANGOPT_IMPORTANT(getStackProtectorMode(),
+                          diag::warn_pch_stack_protector);
+  PARSE_LANGOPT_BENIGN(InstantiationDepth);
+  PARSE_LANGOPT_IMPORTANT(OpenCL, diag::warn_pch_opencl);
+  PARSE_LANGOPT_BENIGN(CatchUndefined);
+  PARSE_LANGOPT_IMPORTANT(ElideConstructors, diag::warn_pch_elide_constructors);
+#undef PARSE_LANGOPT_IMPORTANT
+#undef PARSE_LANGOPT_BENIGN
+
+  return false;
+}
+
+bool PCHValidator::ReadTargetTriple(llvm::StringRef Triple) {
+  if (Triple == PP.getTargetInfo().getTriple().str())
+    return false;
+
+  Reader.Diag(diag::warn_pch_target_triple)
+    << Triple << PP.getTargetInfo().getTriple().str();
+  return true;
+}
+
+bool PCHValidator::ReadPredefinesBuffer(llvm::StringRef PCHPredef,
+                                        FileID PCHBufferID,
+                                        llvm::StringRef OriginalFileName,
+                                        std::string &SuggestedPredefines) {
+  // We are in the context of an implicit include, so the predefines buffer will
+  // have a #include entry for the PCH file itself (as normalized by the
+  // preprocessor initialization). Find it and skip over it in the checking
+  // below.
+  llvm::SmallString<256> PCHInclude;
+  PCHInclude += "#include \"";
+  PCHInclude += NormalizeDashIncludePath(OriginalFileName);
+  PCHInclude += "\"\n";
+  std::pair<llvm::StringRef,llvm::StringRef> Split =
+    llvm::StringRef(PP.getPredefines()).split(PCHInclude.str());
+  llvm::StringRef Left =  Split.first, Right = Split.second;
+  if (Left == PP.getPredefines()) {
+    Error("Missing PCH include entry!");
+    return true;
+  }
+
+  // If the predefines is equal to the joined left and right halves, we're done!
+  if (Left.size() + Right.size() == PCHPredef.size() &&
+      PCHPredef.startswith(Left) && PCHPredef.endswith(Right))
+    return false;
+
+  SourceManager &SourceMgr = PP.getSourceManager();
+
+  // The predefines buffers are different. Determine what the differences are,
+  // and whether they require us to reject the PCH file.
+  llvm::SmallVector<llvm::StringRef, 8> PCHLines;
+  PCHPredef.split(PCHLines, "\n", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
+
+  llvm::SmallVector<llvm::StringRef, 8> CmdLineLines;
+  Left.split(CmdLineLines, "\n", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
+  Right.split(CmdLineLines, "\n", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
+
+  // Sort both sets of predefined buffer lines, since we allow some extra
+  // definitions and they may appear at any point in the output.
+  std::sort(CmdLineLines.begin(), CmdLineLines.end());
+  std::sort(PCHLines.begin(), PCHLines.end());
+
+  // Determine which predefines that were used to build the PCH file are missing
+  // from the command line.
+  std::vector<llvm::StringRef> MissingPredefines;
+  std::set_difference(PCHLines.begin(), PCHLines.end(),
+                      CmdLineLines.begin(), CmdLineLines.end(),
+                      std::back_inserter(MissingPredefines));
+
+  bool MissingDefines = false;
+  bool ConflictingDefines = false;
+  for (unsigned I = 0, N = MissingPredefines.size(); I != N; ++I) {
+    llvm::StringRef Missing = MissingPredefines[I];
+    if (!Missing.startswith("#define ")) {
+      Reader.Diag(diag::warn_pch_compiler_options_mismatch);
+      return true;
+    }
+
+    // This is a macro definition. Determine the name of the macro we're
+    // defining.
+    std::string::size_type StartOfMacroName = strlen("#define ");
+    std::string::size_type EndOfMacroName
+      = Missing.find_first_of("( \n\r", StartOfMacroName);
+    assert(EndOfMacroName != std::string::npos &&
+           "Couldn't find the end of the macro name");
+    llvm::StringRef MacroName = Missing.slice(StartOfMacroName, EndOfMacroName);
+
+    // Determine whether this macro was given a different definition on the
+    // command line.
+    std::string MacroDefStart = "#define " + MacroName.str();
+    std::string::size_type MacroDefLen = MacroDefStart.size();
+    llvm::SmallVector<llvm::StringRef, 8>::iterator ConflictPos
+      = std::lower_bound(CmdLineLines.begin(), CmdLineLines.end(),
+                         MacroDefStart);
+    for (; ConflictPos != CmdLineLines.end(); ++ConflictPos) {
+      if (!ConflictPos->startswith(MacroDefStart)) {
+        // Different macro; we're done.
+        ConflictPos = CmdLineLines.end();
+        break;
+      }
+
+      assert(ConflictPos->size() > MacroDefLen &&
+             "Invalid #define in predefines buffer?");
+      if ((*ConflictPos)[MacroDefLen] != ' ' &&
+          (*ConflictPos)[MacroDefLen] != '(')
+        continue; // Longer macro name; keep trying.
+
+      // We found a conflicting macro definition.
+      break;
+    }
+
+    if (ConflictPos != CmdLineLines.end()) {
+      Reader.Diag(diag::warn_cmdline_conflicting_macro_def)
+          << MacroName;
+
+      // Show the definition of this macro within the PCH file.
+      llvm::StringRef::size_type Offset = PCHPredef.find(Missing);
+      assert(Offset != llvm::StringRef::npos && "Unable to find macro!");
+      SourceLocation PCHMissingLoc = SourceMgr.getLocForStartOfFile(PCHBufferID)
+        .getFileLocWithOffset(Offset);
+      Reader.Diag(PCHMissingLoc, diag::note_pch_macro_defined_as) << MacroName;
+
+      ConflictingDefines = true;
+      continue;
+    }
+
+    // If the macro doesn't conflict, then we'll just pick up the macro
+    // definition from the PCH file. Warn the user that they made a mistake.
+    if (ConflictingDefines)
+      continue; // Don't complain if there are already conflicting defs
+
+    if (!MissingDefines) {
+      Reader.Diag(diag::warn_cmdline_missing_macro_defs);
+      MissingDefines = true;
+    }
+
+    // Show the definition of this macro within the PCH file.
+    llvm::StringRef::size_type Offset = PCHPredef.find(Missing);
+    assert(Offset != llvm::StringRef::npos && "Unable to find macro!");
+    SourceLocation PCHMissingLoc = SourceMgr.getLocForStartOfFile(PCHBufferID)
+      .getFileLocWithOffset(Offset);
+    Reader.Diag(PCHMissingLoc, diag::note_using_macro_def_from_pch);
+  }
+
+  if (ConflictingDefines)
+    return true;
+
+  // Determine what predefines were introduced based on command-line
+  // parameters that were not present when building the PCH
+  // file. Extra #defines are okay, so long as the identifiers being
+  // defined were not used within the precompiled header.
+  std::vector<llvm::StringRef> ExtraPredefines;
+  std::set_difference(CmdLineLines.begin(), CmdLineLines.end(),
+                      PCHLines.begin(), PCHLines.end(),
+                      std::back_inserter(ExtraPredefines));
+  for (unsigned I = 0, N = ExtraPredefines.size(); I != N; ++I) {
+    llvm::StringRef &Extra = ExtraPredefines[I];
+    if (!Extra.startswith("#define ")) {
+      Reader.Diag(diag::warn_pch_compiler_options_mismatch);
+      return true;
+    }
+
+    // This is an extra macro definition. Determine the name of the
+    // macro we're defining.
+    std::string::size_type StartOfMacroName = strlen("#define ");
+    std::string::size_type EndOfMacroName
+      = Extra.find_first_of("( \n\r", StartOfMacroName);
+    assert(EndOfMacroName != std::string::npos &&
+           "Couldn't find the end of the macro name");
+    llvm::StringRef MacroName = Extra.slice(StartOfMacroName, EndOfMacroName);
+
+    // Check whether this name was used somewhere in the PCH file. If
+    // so, defining it as a macro could change behavior, so we reject
+    // the PCH file.
+    if (IdentifierInfo *II = Reader.get(MacroName)) {
+      Reader.Diag(diag::warn_macro_name_used_in_pch) << II;
+      return true;
+    }
+
+    // Add this definition to the suggested predefines buffer.
+    SuggestedPredefines += Extra;
+    SuggestedPredefines += '\n';
+  }
+
+  // If we get here, it's because the predefines buffer had compatible
+  // contents. Accept the PCH file.
+  return false;
+}
+
+void PCHValidator::ReadHeaderFileInfo(const HeaderFileInfo &HFI,
+                                      unsigned ID) {
+  PP.getHeaderSearchInfo().setHeaderFileInfoForUID(HFI, ID);
+  ++NumHeaderInfos;
+}
+
+void PCHValidator::ReadCounter(unsigned Value) {
+  PP.setCounterValue(Value);
+}
+
+//===----------------------------------------------------------------------===//
+// PCH reader implementation
+//===----------------------------------------------------------------------===//
+
+PCHReader::PCHReader(Preprocessor &PP, ASTContext *Context,
+                     const char *isysroot)
+  : Listener(new PCHValidator(PP, *this)), SourceMgr(PP.getSourceManager()),
+    FileMgr(PP.getFileManager()), Diags(PP.getDiagnostics()),
+    SemaObj(0), PP(&PP), Context(Context), StatCache(0), Consumer(0),
+    IdentifierTableData(0), IdentifierLookupTable(0),
+    IdentifierOffsets(0),
+    MethodPoolLookupTable(0), MethodPoolLookupTableData(0),
+    TotalSelectorsInMethodPool(0), SelectorOffsets(0),
+    TotalNumSelectors(0), MacroDefinitionOffsets(0), 
+    NumPreallocatedPreprocessingEntities(0),  
+    isysroot(isysroot), NumStatHits(0), NumStatMisses(0),
+    NumSLocEntriesRead(0), NumStatementsRead(0),
+    NumMacrosRead(0), NumMethodPoolSelectorsRead(0), NumMethodPoolMisses(0),
+    NumLexicalDeclContextsRead(0), NumVisibleDeclContextsRead(0),
+    CurrentlyLoadingTypeOrDecl(0) {
+  RelocatablePCH = false;
+}
+
+PCHReader::PCHReader(SourceManager &SourceMgr, FileManager &FileMgr,
+                     Diagnostic &Diags, const char *isysroot)
+  : SourceMgr(SourceMgr), FileMgr(FileMgr), Diags(Diags),
+    SemaObj(0), PP(0), Context(0), StatCache(0), Consumer(0),
+    IdentifierTableData(0), IdentifierLookupTable(0),
+    IdentifierOffsets(0),
+    MethodPoolLookupTable(0), MethodPoolLookupTableData(0),
+    TotalSelectorsInMethodPool(0), SelectorOffsets(0),
+    TotalNumSelectors(0), MacroDefinitionOffsets(0), 
+    NumPreallocatedPreprocessingEntities(0),  
+    isysroot(isysroot), NumStatHits(0), NumStatMisses(0),
+    NumSLocEntriesRead(0), NumStatementsRead(0),
+    NumMacrosRead(0), NumMethodPoolSelectorsRead(0), NumMethodPoolMisses(0),
+    NumLexicalDeclContextsRead(0), NumVisibleDeclContextsRead(0),
+    CurrentlyLoadingTypeOrDecl(0) {
+  RelocatablePCH = false;
+}
+
+PCHReader::~PCHReader() {}
+
+Expr *PCHReader::ReadDeclExpr() {
+  return dyn_cast_or_null<Expr>(ReadStmt(DeclsCursor));
+}
+
+Expr *PCHReader::ReadTypeExpr() {
+  return dyn_cast_or_null<Expr>(ReadStmt(DeclsCursor));
+}
+
+
+namespace {
+class PCHMethodPoolLookupTrait {
+  PCHReader &Reader;
+
+public:
+  typedef std::pair<ObjCMethodList, ObjCMethodList> data_type;
+
+  typedef Selector external_key_type;
+  typedef external_key_type internal_key_type;
+
+  explicit PCHMethodPoolLookupTrait(PCHReader &Reader) : Reader(Reader) { }
+
+  static bool EqualKey(const internal_key_type& a,
+                       const internal_key_type& b) {
+    return a == b;
+  }
+
+  static unsigned ComputeHash(Selector Sel) {
+    unsigned N = Sel.getNumArgs();
+    if (N == 0)
+      ++N;
+    unsigned R = 5381;
+    for (unsigned I = 0; I != N; ++I)
+      if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(I))
+        R = llvm::HashString(II->getName(), R);
+    return R;
+  }
+
+  // This hopefully will just get inlined and removed by the optimizer.
+  static const internal_key_type&
+  GetInternalKey(const external_key_type& x) { return x; }
+
+  static std::pair<unsigned, unsigned>
+  ReadKeyDataLength(const unsigned char*& d) {
+    using namespace clang::io;
+    unsigned KeyLen = ReadUnalignedLE16(d);
+    unsigned DataLen = ReadUnalignedLE16(d);
+    return std::make_pair(KeyLen, DataLen);
+  }
+
+  internal_key_type ReadKey(const unsigned char* d, unsigned) {
+    using namespace clang::io;
+    SelectorTable &SelTable = Reader.getContext()->Selectors;
+    unsigned N = ReadUnalignedLE16(d);
+    IdentifierInfo *FirstII
+      = Reader.DecodeIdentifierInfo(ReadUnalignedLE32(d));
+    if (N == 0)
+      return SelTable.getNullarySelector(FirstII);
+    else if (N == 1)
+      return SelTable.getUnarySelector(FirstII);
+
+    llvm::SmallVector<IdentifierInfo *, 16> Args;
+    Args.push_back(FirstII);
+    for (unsigned I = 1; I != N; ++I)
+      Args.push_back(Reader.DecodeIdentifierInfo(ReadUnalignedLE32(d)));
+
+    return SelTable.getSelector(N, Args.data());
+  }
+
+  data_type ReadData(Selector, const unsigned char* d, unsigned DataLen) {
+    using namespace clang::io;
+    unsigned NumInstanceMethods = ReadUnalignedLE16(d);
+    unsigned NumFactoryMethods = ReadUnalignedLE16(d);
+
+    data_type Result;
+
+    // Load instance methods
+    ObjCMethodList *Prev = 0;
+    for (unsigned I = 0; I != NumInstanceMethods; ++I) {
+      ObjCMethodDecl *Method
+        = cast<ObjCMethodDecl>(Reader.GetDecl(ReadUnalignedLE32(d)));
+      if (!Result.first.Method) {
+        // This is the first method, which is the easy case.
+        Result.first.Method = Method;
+        Prev = &Result.first;
+        continue;
+      }
+
+      ObjCMethodList *Mem =
+        Reader.getSema()->BumpAlloc.Allocate<ObjCMethodList>();
+      Prev->Next = new (Mem) ObjCMethodList(Method, 0);
+      Prev = Prev->Next;
+    }
+
+    // Load factory methods
+    Prev = 0;
+    for (unsigned I = 0; I != NumFactoryMethods; ++I) {
+      ObjCMethodDecl *Method
+        = cast<ObjCMethodDecl>(Reader.GetDecl(ReadUnalignedLE32(d)));
+      if (!Result.second.Method) {
+        // This is the first method, which is the easy case.
+        Result.second.Method = Method;
+        Prev = &Result.second;
+        continue;
+      }
+
+      ObjCMethodList *Mem =
+        Reader.getSema()->BumpAlloc.Allocate<ObjCMethodList>();
+      Prev->Next = new (Mem) ObjCMethodList(Method, 0);
+      Prev = Prev->Next;
+    }
+
+    return Result;
+  }
+};
+
+} // end anonymous namespace
+
+/// \brief The on-disk hash table used for the global method pool.
+typedef OnDiskChainedHashTable<PCHMethodPoolLookupTrait>
+  PCHMethodPoolLookupTable;
+
+namespace {
+class PCHIdentifierLookupTrait {
+  PCHReader &Reader;
+
+  // If we know the IdentifierInfo in advance, it is here and we will
+  // not build a new one. Used when deserializing information about an
+  // identifier that was constructed before the PCH file was read.
+  IdentifierInfo *KnownII;
+
+public:
+  typedef IdentifierInfo * data_type;
+
+  typedef const std::pair<const char*, unsigned> external_key_type;
+
+  typedef external_key_type internal_key_type;
+
+  explicit PCHIdentifierLookupTrait(PCHReader &Reader, IdentifierInfo *II = 0)
+    : Reader(Reader), KnownII(II) { }
+
+  static bool EqualKey(const internal_key_type& a,
+                       const internal_key_type& b) {
+    return (a.second == b.second) ? memcmp(a.first, b.first, a.second) == 0
+                                  : false;
+  }
+
+  static unsigned ComputeHash(const internal_key_type& a) {
+    return llvm::HashString(llvm::StringRef(a.first, a.second));
+  }
+
+  // This hopefully will just get inlined and removed by the optimizer.
+  static const internal_key_type&
+  GetInternalKey(const external_key_type& x) { return x; }
+
+  static std::pair<unsigned, unsigned>
+  ReadKeyDataLength(const unsigned char*& d) {
+    using namespace clang::io;
+    unsigned DataLen = ReadUnalignedLE16(d);
+    unsigned KeyLen = ReadUnalignedLE16(d);
+    return std::make_pair(KeyLen, DataLen);
+  }
+
+  static std::pair<const char*, unsigned>
+  ReadKey(const unsigned char* d, unsigned n) {
+    assert(n >= 2 && d[n-1] == '\0');
+    return std::make_pair((const char*) d, n-1);
+  }
+
+  IdentifierInfo *ReadData(const internal_key_type& k,
+                           const unsigned char* d,
+                           unsigned DataLen) {
+    using namespace clang::io;
+    pch::IdentID ID = ReadUnalignedLE32(d);
+    bool IsInteresting = ID & 0x01;
+
+    // Wipe out the "is interesting" bit.
+    ID = ID >> 1;
+
+    if (!IsInteresting) {
+      // For unintersting identifiers, just build the IdentifierInfo
+      // and associate it with the persistent ID.
+      IdentifierInfo *II = KnownII;
+      if (!II)
+        II = &Reader.getIdentifierTable().CreateIdentifierInfo(
+                                                 k.first, k.first + k.second);
+      Reader.SetIdentifierInfo(ID, II);
+      return II;
+    }
+
+    unsigned Bits = ReadUnalignedLE16(d);
+    bool CPlusPlusOperatorKeyword = Bits & 0x01;
+    Bits >>= 1;
+    bool Poisoned = Bits & 0x01;
+    Bits >>= 1;
+    bool ExtensionToken = Bits & 0x01;
+    Bits >>= 1;
+    bool hasMacroDefinition = Bits & 0x01;
+    Bits >>= 1;
+    unsigned ObjCOrBuiltinID = Bits & 0x3FF;
+    Bits >>= 10;
+
+    assert(Bits == 0 && "Extra bits in the identifier?");
+    DataLen -= 6;
+
+    // Build the IdentifierInfo itself and link the identifier ID with
+    // the new IdentifierInfo.
+    IdentifierInfo *II = KnownII;
+    if (!II)
+      II = &Reader.getIdentifierTable().CreateIdentifierInfo(
+                                                 k.first, k.first + k.second);
+    Reader.SetIdentifierInfo(ID, II);
+
+    // Set or check the various bits in the IdentifierInfo structure.
+    // FIXME: Load token IDs lazily, too?
+    II->setObjCOrBuiltinID(ObjCOrBuiltinID);
+    assert(II->isExtensionToken() == ExtensionToken &&
+           "Incorrect extension token flag");
+    (void)ExtensionToken;
+    II->setIsPoisoned(Poisoned);
+    assert(II->isCPlusPlusOperatorKeyword() == CPlusPlusOperatorKeyword &&
+           "Incorrect C++ operator keyword flag");
+    (void)CPlusPlusOperatorKeyword;
+
+    // If this identifier is a macro, deserialize the macro
+    // definition.
+    if (hasMacroDefinition) {
+      uint32_t Offset = ReadUnalignedLE32(d);
+      Reader.ReadMacroRecord(Offset);
+      DataLen -= 4;
+    }
+
+    // Read all of the declarations visible at global scope with this
+    // name.
+    if (Reader.getContext() == 0) return II;
+    if (DataLen > 0) {
+      llvm::SmallVector<uint32_t, 4> DeclIDs;
+      for (; DataLen > 0; DataLen -= 4)
+        DeclIDs.push_back(ReadUnalignedLE32(d));
+      Reader.SetGloballyVisibleDecls(II, DeclIDs);
+    }
+
+    return II;
+  }
+};
+
+} // end anonymous namespace
+
+/// \brief The on-disk hash table used to contain information about
+/// all of the identifiers in the program.
+typedef OnDiskChainedHashTable<PCHIdentifierLookupTrait>
+  PCHIdentifierLookupTable;
+
+void PCHReader::Error(const char *Msg) {
+  Diag(diag::err_fe_pch_malformed) << Msg;
+}
+
+/// \brief Check the contents of the predefines buffer against the
+/// contents of the predefines buffer used to build the PCH file.
+///
+/// The contents of the two predefines buffers should be the same. If
+/// not, then some command-line option changed the preprocessor state
+/// and we must reject the PCH file.
+///
+/// \param PCHPredef The start of the predefines buffer in the PCH
+/// file.
+///
+/// \param PCHPredefLen The length of the predefines buffer in the PCH
+/// file.
+///
+/// \param PCHBufferID The FileID for the PCH predefines buffer.
+///
+/// \returns true if there was a mismatch (in which case the PCH file
+/// should be ignored), or false otherwise.
+bool PCHReader::CheckPredefinesBuffer(llvm::StringRef PCHPredef,
+                                      FileID PCHBufferID) {
+  if (Listener)
+    return Listener->ReadPredefinesBuffer(PCHPredef, PCHBufferID,
+                                          ActualOriginalFileName,
+                                          SuggestedPredefines);
+  return false;
+}
+
+//===----------------------------------------------------------------------===//
+// Source Manager Deserialization
+//===----------------------------------------------------------------------===//
+
+/// \brief Read the line table in the source manager block.
+/// \returns true if ther was an error.
+bool PCHReader::ParseLineTable(llvm::SmallVectorImpl<uint64_t> &Record) {
+  unsigned Idx = 0;
+  LineTableInfo &LineTable = SourceMgr.getLineTable();
+
+  // Parse the file names
+  std::map<int, int> FileIDs;
+  for (int I = 0, N = Record[Idx++]; I != N; ++I) {
+    // Extract the file name
+    unsigned FilenameLen = Record[Idx++];
+    std::string Filename(&Record[Idx], &Record[Idx] + FilenameLen);
+    Idx += FilenameLen;
+    MaybeAddSystemRootToFilename(Filename);
+    FileIDs[I] = LineTable.getLineTableFilenameID(Filename.c_str(),
+                                                  Filename.size());
+  }
+
+  // Parse the line entries
+  std::vector<LineEntry> Entries;
+  while (Idx < Record.size()) {
+    int FID = FileIDs[Record[Idx++]];
+
+    // Extract the line entries
+    unsigned NumEntries = Record[Idx++];
+    Entries.clear();
+    Entries.reserve(NumEntries);
+    for (unsigned I = 0; I != NumEntries; ++I) {
+      unsigned FileOffset = Record[Idx++];
+      unsigned LineNo = Record[Idx++];
+      int FilenameID = Record[Idx++];
+      SrcMgr::CharacteristicKind FileKind
+        = (SrcMgr::CharacteristicKind)Record[Idx++];
+      unsigned IncludeOffset = Record[Idx++];
+      Entries.push_back(LineEntry::get(FileOffset, LineNo, FilenameID,
+                                       FileKind, IncludeOffset));
+    }
+    LineTable.AddEntry(FID, Entries);
+  }
+
+  return false;
+}
+
+namespace {
+
+class PCHStatData {
+public:
+  const bool hasStat;
+  const ino_t ino;
+  const dev_t dev;
+  const mode_t mode;
+  const time_t mtime;
+  const off_t size;
+
+  PCHStatData(ino_t i, dev_t d, mode_t mo, time_t m, off_t s)
+  : hasStat(true), ino(i), dev(d), mode(mo), mtime(m), size(s) {}
+
+  PCHStatData()
+    : hasStat(false), ino(0), dev(0), mode(0), mtime(0), size(0) {}
+};
+
+class PCHStatLookupTrait {
+ public:
+  typedef const char *external_key_type;
+  typedef const char *internal_key_type;
+
+  typedef PCHStatData data_type;
+
+  static unsigned ComputeHash(const char *path) {
+    return llvm::HashString(path);
+  }
+
+  static internal_key_type GetInternalKey(const char *path) { return path; }
+
+  static bool EqualKey(internal_key_type a, internal_key_type b) {
+    return strcmp(a, b) == 0;
+  }
+
+  static std::pair<unsigned, unsigned>
+  ReadKeyDataLength(const unsigned char*& d) {
+    unsigned KeyLen = (unsigned) clang::io::ReadUnalignedLE16(d);
+    unsigned DataLen = (unsigned) *d++;
+    return std::make_pair(KeyLen + 1, DataLen);
+  }
+
+  static internal_key_type ReadKey(const unsigned char *d, unsigned) {
+    return (const char *)d;
+  }
+
+  static data_type ReadData(const internal_key_type, const unsigned char *d,
+                            unsigned /*DataLen*/) {
+    using namespace clang::io;
+
+    if (*d++ == 1)
+      return data_type();
+
+    ino_t ino = (ino_t) ReadUnalignedLE32(d);
+    dev_t dev = (dev_t) ReadUnalignedLE32(d);
+    mode_t mode = (mode_t) ReadUnalignedLE16(d);
+    time_t mtime = (time_t) ReadUnalignedLE64(d);
+    off_t size = (off_t) ReadUnalignedLE64(d);
+    return data_type(ino, dev, mode, mtime, size);
+  }
+};
+
+/// \brief stat() cache for precompiled headers.
+///
+/// This cache is very similar to the stat cache used by pretokenized
+/// headers.
+class PCHStatCache : public StatSysCallCache {
+  typedef OnDiskChainedHashTable<PCHStatLookupTrait> CacheTy;
+  CacheTy *Cache;
+
+  unsigned &NumStatHits, &NumStatMisses;
+public:
+  PCHStatCache(const unsigned char *Buckets,
+               const unsigned char *Base,
+               unsigned &NumStatHits,
+               unsigned &NumStatMisses)
+    : Cache(0), NumStatHits(NumStatHits), NumStatMisses(NumStatMisses) {
+    Cache = CacheTy::Create(Buckets, Base);
+  }
+
+  ~PCHStatCache() { delete Cache; }
+
+  int stat(const char *path, struct stat *buf) {
+    // Do the lookup for the file's data in the PCH file.
+    CacheTy::iterator I = Cache->find(path);
+
+    // If we don't get a hit in the PCH file just forward to 'stat'.
+    if (I == Cache->end()) {
+      ++NumStatMisses;
+      return StatSysCallCache::stat(path, buf);
+    }
+
+    ++NumStatHits;
+    PCHStatData Data = *I;
+
+    if (!Data.hasStat)
+      return 1;
+
+    buf->st_ino = Data.ino;
+    buf->st_dev = Data.dev;
+    buf->st_mtime = Data.mtime;
+    buf->st_mode = Data.mode;
+    buf->st_size = Data.size;
+    return 0;
+  }
+};
+} // end anonymous namespace
+
+
+/// \brief Read the source manager block
+PCHReader::PCHReadResult PCHReader::ReadSourceManagerBlock() {
+  using namespace SrcMgr;
+
+  // Set the source-location entry cursor to the current position in
+  // the stream. This cursor will be used to read the contents of the
+  // source manager block initially, and then lazily read
+  // source-location entries as needed.
+  SLocEntryCursor = Stream;
+
+  // The stream itself is going to skip over the source manager block.
+  if (Stream.SkipBlock()) {
+    Error("malformed block record in PCH file");
+    return Failure;
+  }
+
+  // Enter the source manager block.
+  if (SLocEntryCursor.EnterSubBlock(pch::SOURCE_MANAGER_BLOCK_ID)) {
+    Error("malformed source manager block record in PCH file");
+    return Failure;
+  }
+
+  RecordData Record;
+  while (true) {
+    unsigned Code = SLocEntryCursor.ReadCode();
+    if (Code == llvm::bitc::END_BLOCK) {
+      if (SLocEntryCursor.ReadBlockEnd()) {
+        Error("error at end of Source Manager block in PCH file");
+        return Failure;
+      }
+      return Success;
+    }
+
+    if (Code == llvm::bitc::ENTER_SUBBLOCK) {
+      // No known subblocks, always skip them.
+      SLocEntryCursor.ReadSubBlockID();
+      if (SLocEntryCursor.SkipBlock()) {
+        Error("malformed block record in PCH file");
+        return Failure;
+      }
+      continue;
+    }
+
+    if (Code == llvm::bitc::DEFINE_ABBREV) {
+      SLocEntryCursor.ReadAbbrevRecord();
+      continue;
+    }
+
+    // Read a record.
+    const char *BlobStart;
+    unsigned BlobLen;
+    Record.clear();
+    switch (SLocEntryCursor.ReadRecord(Code, Record, &BlobStart, &BlobLen)) {
+    default:  // Default behavior: ignore.
+      break;
+
+    case pch::SM_LINE_TABLE:
+      if (ParseLineTable(Record))
+        return Failure;
+      break;
+
+    case pch::SM_SLOC_FILE_ENTRY:
+    case pch::SM_SLOC_BUFFER_ENTRY:
+    case pch::SM_SLOC_INSTANTIATION_ENTRY:
+      // Once we hit one of the source location entries, we're done.
+      return Success;
+    }
+  }
+}
+
+/// \brief Read in the source location entry with the given ID.
+PCHReader::PCHReadResult PCHReader::ReadSLocEntryRecord(unsigned ID) {
+  if (ID == 0)
+    return Success;
+
+  if (ID > TotalNumSLocEntries) {
+    Error("source location entry ID out-of-range for PCH file");
+    return Failure;
+  }
+
+  ++NumSLocEntriesRead;
+  SLocEntryCursor.JumpToBit(SLocOffsets[ID - 1]);
+  unsigned Code = SLocEntryCursor.ReadCode();
+  if (Code == llvm::bitc::END_BLOCK ||
+      Code == llvm::bitc::ENTER_SUBBLOCK ||
+      Code == llvm::bitc::DEFINE_ABBREV) {
+    Error("incorrectly-formatted source location entry in PCH file");
+    return Failure;
+  }
+
+  RecordData Record;
+  const char *BlobStart;
+  unsigned BlobLen;
+  switch (SLocEntryCursor.ReadRecord(Code, Record, &BlobStart, &BlobLen)) {
+  default:
+    Error("incorrectly-formatted source location entry in PCH file");
+    return Failure;
+
+  case pch::SM_SLOC_FILE_ENTRY: {
+    std::string Filename(BlobStart, BlobStart + BlobLen);
+    MaybeAddSystemRootToFilename(Filename);
+    const FileEntry *File = FileMgr.getFile(Filename);
+    if (File == 0) {
+      std::string ErrorStr = "could not find file '";
+      ErrorStr += Filename;
+      ErrorStr += "' referenced by PCH file";
+      Error(ErrorStr.c_str());
+      return Failure;
+    }
+
+    if (Record.size() < 10) {
+      Error("source location entry is incorrect");
+      return Failure;
+    }
+
+    if ((off_t)Record[4] != File->getSize()
+#if !defined(LLVM_ON_WIN32)
+        // In our regression testing, the Windows file system seems to
+        // have inconsistent modification times that sometimes
+        // erroneously trigger this error-handling path.
+        || (time_t)Record[5] != File->getModificationTime()
+#endif
+        ) {
+      Diag(diag::err_fe_pch_file_modified)
+        << Filename;
+      return Failure;
+    }
+
+    FileID FID = SourceMgr.createFileID(File,
+                                SourceLocation::getFromRawEncoding(Record[1]),
+                                       (SrcMgr::CharacteristicKind)Record[2],
+                                        ID, Record[0]);
+    if (Record[3])
+      const_cast<SrcMgr::FileInfo&>(SourceMgr.getSLocEntry(FID).getFile())
+        .setHasLineDirectives();
+
+    // Reconstruct header-search information for this file.
+    HeaderFileInfo HFI;
+    HFI.isImport = Record[6];
+    HFI.DirInfo = Record[7];
+    HFI.NumIncludes = Record[8];
+    HFI.ControllingMacroID = Record[9];
+    if (Listener)
+      Listener->ReadHeaderFileInfo(HFI, File->getUID());
+    break;
+  }
+
+  case pch::SM_SLOC_BUFFER_ENTRY: {
+    const char *Name = BlobStart;
+    unsigned Offset = Record[0];
+    unsigned Code = SLocEntryCursor.ReadCode();
+    Record.clear();
+    unsigned RecCode
+      = SLocEntryCursor.ReadRecord(Code, Record, &BlobStart, &BlobLen);
+
+    if (RecCode != pch::SM_SLOC_BUFFER_BLOB) {
+      Error("PCH record has invalid code");
+      return Failure;
+    }
+
+    llvm::MemoryBuffer *Buffer
+    = llvm::MemoryBuffer::getMemBuffer(llvm::StringRef(BlobStart, BlobLen - 1),
+                                       Name);
+    FileID BufferID = SourceMgr.createFileIDForMemBuffer(Buffer, ID, Offset);
+
+    if (strcmp(Name, "<built-in>") == 0) {
+      PCHPredefinesBufferID = BufferID;
+      PCHPredefines = BlobStart;
+      PCHPredefinesLen = BlobLen - 1;
+    }
+
+    break;
+  }
+
+  case pch::SM_SLOC_INSTANTIATION_ENTRY: {
+    SourceLocation SpellingLoc
+      = SourceLocation::getFromRawEncoding(Record[1]);
+    SourceMgr.createInstantiationLoc(SpellingLoc,
+                              SourceLocation::getFromRawEncoding(Record[2]),
+                              SourceLocation::getFromRawEncoding(Record[3]),
+                                     Record[4],
+                                     ID,
+                                     Record[0]);
+    break;
+  }
+  }
+
+  return Success;
+}
+
+/// ReadBlockAbbrevs - Enter a subblock of the specified BlockID with the
+/// specified cursor.  Read the abbreviations that are at the top of the block
+/// and then leave the cursor pointing into the block.
+bool PCHReader::ReadBlockAbbrevs(llvm::BitstreamCursor &Cursor,
+                                 unsigned BlockID) {
+  if (Cursor.EnterSubBlock(BlockID)) {
+    Error("malformed block record in PCH file");
+    return Failure;
+  }
+
+  while (true) {
+    unsigned Code = Cursor.ReadCode();
+
+    // We expect all abbrevs to be at the start of the block.
+    if (Code != llvm::bitc::DEFINE_ABBREV)
+      return false;
+    Cursor.ReadAbbrevRecord();
+  }
+}
+
+void PCHReader::ReadMacroRecord(uint64_t Offset) {
+  assert(PP && "Forgot to set Preprocessor ?");
+
+  // Keep track of where we are in the stream, then jump back there
+  // after reading this macro.
+  SavedStreamPosition SavedPosition(Stream);
+
+  Stream.JumpToBit(Offset);
+  RecordData Record;
+  llvm::SmallVector<IdentifierInfo*, 16> MacroArgs;
+  MacroInfo *Macro = 0;
+
+  while (true) {
+    unsigned Code = Stream.ReadCode();
+    switch (Code) {
+    case llvm::bitc::END_BLOCK:
+      return;
+
+    case llvm::bitc::ENTER_SUBBLOCK:
+      // No known subblocks, always skip them.
+      Stream.ReadSubBlockID();
+      if (Stream.SkipBlock()) {
+        Error("malformed block record in PCH file");
+        return;
+      }
+      continue;
+
+    case llvm::bitc::DEFINE_ABBREV:
+      Stream.ReadAbbrevRecord();
+      continue;
+    default: break;
+    }
+
+    // Read a record.
+    Record.clear();
+    pch::PreprocessorRecordTypes RecType =
+      (pch::PreprocessorRecordTypes)Stream.ReadRecord(Code, Record);
+    switch (RecType) {
+    case pch::PP_MACRO_OBJECT_LIKE:
+    case pch::PP_MACRO_FUNCTION_LIKE: {
+      // If we already have a macro, that means that we've hit the end
+      // of the definition of the macro we were looking for. We're
+      // done.
+      if (Macro)
+        return;
+
+      IdentifierInfo *II = DecodeIdentifierInfo(Record[0]);
+      if (II == 0) {
+        Error("macro must have a name in PCH file");
+        return;
+      }
+      SourceLocation Loc = SourceLocation::getFromRawEncoding(Record[1]);
+      bool isUsed = Record[2];
+
+      MacroInfo *MI = PP->AllocateMacroInfo(Loc);
+      MI->setIsUsed(isUsed);
+
+      unsigned NextIndex = 3;
+      if (RecType == pch::PP_MACRO_FUNCTION_LIKE) {
+        // Decode function-like macro info.
+        bool isC99VarArgs = Record[3];
+        bool isGNUVarArgs = Record[4];
+        MacroArgs.clear();
+        unsigned NumArgs = Record[5];
+        NextIndex = 6 + NumArgs;
+        for (unsigned i = 0; i != NumArgs; ++i)
+          MacroArgs.push_back(DecodeIdentifierInfo(Record[6+i]));
+
+        // Install function-like macro info.
+        MI->setIsFunctionLike();
+        if (isC99VarArgs) MI->setIsC99Varargs();
+        if (isGNUVarArgs) MI->setIsGNUVarargs();
+        MI->setArgumentList(MacroArgs.data(), MacroArgs.size(),
+                            PP->getPreprocessorAllocator());
+      }
+
+      // Finally, install the macro.
+      PP->setMacroInfo(II, MI);
+
+      // Remember that we saw this macro last so that we add the tokens that
+      // form its body to it.
+      Macro = MI;
+      
+      if (NextIndex + 1 == Record.size() && PP->getPreprocessingRecord()) {
+        // We have a macro definition. Load it now.
+        PP->getPreprocessingRecord()->RegisterMacroDefinition(Macro,
+                                        getMacroDefinition(Record[NextIndex]));
+      }
+      
+      ++NumMacrosRead;
+      break;
+    }
+
+    case pch::PP_TOKEN: {
+      // If we see a TOKEN before a PP_MACRO_*, then the file is
+      // erroneous, just pretend we didn't see this.
+      if (Macro == 0) break;
+
+      Token Tok;
+      Tok.startToken();
+      Tok.setLocation(SourceLocation::getFromRawEncoding(Record[0]));
+      Tok.setLength(Record[1]);
+      if (IdentifierInfo *II = DecodeIdentifierInfo(Record[2]))
+        Tok.setIdentifierInfo(II);
+      Tok.setKind((tok::TokenKind)Record[3]);
+      Tok.setFlag((Token::TokenFlags)Record[4]);
+      Macro->AddTokenToBody(Tok);
+      break;
+    }
+        
+    case pch::PP_MACRO_INSTANTIATION: {
+      // If we already have a macro, that means that we've hit the end
+      // of the definition of the macro we were looking for. We're
+      // done.
+      if (Macro)
+        return;
+      
+      if (!PP->getPreprocessingRecord()) {
+        Error("missing preprocessing record in PCH file");
+        return;
+      }
+        
+      PreprocessingRecord &PPRec = *PP->getPreprocessingRecord();
+      if (PPRec.getPreprocessedEntity(Record[0]))
+        return;
+
+      MacroInstantiation *MI
+        = new (PPRec) MacroInstantiation(DecodeIdentifierInfo(Record[3]),
+                               SourceRange(
+                                 SourceLocation::getFromRawEncoding(Record[1]),
+                                 SourceLocation::getFromRawEncoding(Record[2])),
+                                         getMacroDefinition(Record[4]));
+      PPRec.SetPreallocatedEntity(Record[0], MI);
+      return;
+    }
+
+    case pch::PP_MACRO_DEFINITION: {
+      // If we already have a macro, that means that we've hit the end
+      // of the definition of the macro we were looking for. We're
+      // done.
+      if (Macro)
+        return;
+      
+      if (!PP->getPreprocessingRecord()) {
+        Error("missing preprocessing record in PCH file");
+        return;
+      }
+      
+      PreprocessingRecord &PPRec = *PP->getPreprocessingRecord();
+      if (PPRec.getPreprocessedEntity(Record[0]))
+        return;
+        
+      if (Record[1] >= MacroDefinitionsLoaded.size()) {
+        Error("out-of-bounds macro definition record");
+        return;
+      }
+
+      MacroDefinition *MD
+        = new (PPRec) MacroDefinition(DecodeIdentifierInfo(Record[4]),
+                                SourceLocation::getFromRawEncoding(Record[5]),
+                              SourceRange(
+                                SourceLocation::getFromRawEncoding(Record[2]),
+                                SourceLocation::getFromRawEncoding(Record[3])));
+      PPRec.SetPreallocatedEntity(Record[0], MD);
+      MacroDefinitionsLoaded[Record[1]] = MD;
+      return;
+    }
+  }
+  }
+}
+
+void PCHReader::ReadDefinedMacros() {
+  // If there was no preprocessor block, do nothing.
+  if (!MacroCursor.getBitStreamReader())
+    return;
+
+  llvm::BitstreamCursor Cursor = MacroCursor;
+  if (Cursor.EnterSubBlock(pch::PREPROCESSOR_BLOCK_ID)) {
+    Error("malformed preprocessor block record in PCH file");
+    return;
+  }
+
+  RecordData Record;
+  while (true) {
+    unsigned Code = Cursor.ReadCode();
+    if (Code == llvm::bitc::END_BLOCK) {
+      if (Cursor.ReadBlockEnd())
+        Error("error at end of preprocessor block in PCH file");
+      return;
+    }
+
+    if (Code == llvm::bitc::ENTER_SUBBLOCK) {
+      // No known subblocks, always skip them.
+      Cursor.ReadSubBlockID();
+      if (Cursor.SkipBlock()) {
+        Error("malformed block record in PCH file");
+        return;
+      }
+      continue;
+    }
+
+    if (Code == llvm::bitc::DEFINE_ABBREV) {
+      Cursor.ReadAbbrevRecord();
+      continue;
+    }
+
+    // Read a record.
+    const char *BlobStart;
+    unsigned BlobLen;
+    Record.clear();
+    switch (Cursor.ReadRecord(Code, Record, &BlobStart, &BlobLen)) {
+    default:  // Default behavior: ignore.
+      break;
+
+    case pch::PP_MACRO_OBJECT_LIKE:
+    case pch::PP_MACRO_FUNCTION_LIKE:
+      DecodeIdentifierInfo(Record[0]);
+      break;
+
+    case pch::PP_TOKEN:
+      // Ignore tokens.
+      break;
+        
+    case pch::PP_MACRO_INSTANTIATION:
+    case pch::PP_MACRO_DEFINITION:
+      // Read the macro record.
+      ReadMacroRecord(Cursor.GetCurrentBitNo());
+      break;
+    }
+  }
+}
+
+MacroDefinition *PCHReader::getMacroDefinition(pch::IdentID ID) {
+  if (ID == 0 || ID >= MacroDefinitionsLoaded.size())
+    return 0;
+  
+  if (!MacroDefinitionsLoaded[ID])
+    ReadMacroRecord(MacroDefinitionOffsets[ID]);
+    
+  return MacroDefinitionsLoaded[ID];
+}
+
+/// \brief If we are loading a relocatable PCH file, and the filename is
+/// not an absolute path, add the system root to the beginning of the file
+/// name.
+void PCHReader::MaybeAddSystemRootToFilename(std::string &Filename) {
+  // If this is not a relocatable PCH file, there's nothing to do.
+  if (!RelocatablePCH)
+    return;
+
+  if (Filename.empty() || llvm::sys::Path(Filename).isAbsolute())
+    return;
+
+  if (isysroot == 0) {
+    // If no system root was given, default to '/'
+    Filename.insert(Filename.begin(), '/');
+    return;
+  }
+
+  unsigned Length = strlen(isysroot);
+  if (isysroot[Length - 1] != '/')
+    Filename.insert(Filename.begin(), '/');
+
+  Filename.insert(Filename.begin(), isysroot, isysroot + Length);
+}
+
+PCHReader::PCHReadResult
+PCHReader::ReadPCHBlock() {
+  if (Stream.EnterSubBlock(pch::PCH_BLOCK_ID)) {
+    Error("malformed block record in PCH file");
+    return Failure;
+  }
+
+  // Read all of the records and blocks for the PCH file.
+  RecordData Record;
+  while (!Stream.AtEndOfStream()) {
+    unsigned Code = Stream.ReadCode();
+    if (Code == llvm::bitc::END_BLOCK) {
+      if (Stream.ReadBlockEnd()) {
+        Error("error at end of module block in PCH file");
+        return Failure;
+      }
+
+      return Success;
+    }
+
+    if (Code == llvm::bitc::ENTER_SUBBLOCK) {
+      switch (Stream.ReadSubBlockID()) {
+      case pch::DECLTYPES_BLOCK_ID:
+        // We lazily load the decls block, but we want to set up the
+        // DeclsCursor cursor to point into it.  Clone our current bitcode
+        // cursor to it, enter the block and read the abbrevs in that block.
+        // With the main cursor, we just skip over it.
+        DeclsCursor = Stream;
+        if (Stream.SkipBlock() ||  // Skip with the main cursor.
+            // Read the abbrevs.
+            ReadBlockAbbrevs(DeclsCursor, pch::DECLTYPES_BLOCK_ID)) {
+          Error("malformed block record in PCH file");
+          return Failure;
+        }
+        break;
+
+      case pch::PREPROCESSOR_BLOCK_ID:
+        MacroCursor = Stream;
+        if (PP)
+          PP->setExternalSource(this);
+
+        if (Stream.SkipBlock()) {
+          Error("malformed block record in PCH file");
+          return Failure;
+        }
+        break;
+
+      case pch::SOURCE_MANAGER_BLOCK_ID:
+        switch (ReadSourceManagerBlock()) {
+        case Success:
+          break;
+
+        case Failure:
+          Error("malformed source manager block in PCH file");
+          return Failure;
+
+        case IgnorePCH:
+          return IgnorePCH;
+        }
+        break;
+      }
+      continue;
+    }
+
+    if (Code == llvm::bitc::DEFINE_ABBREV) {
+      Stream.ReadAbbrevRecord();
+      continue;
+    }
+
+    // Read and process a record.
+    Record.clear();
+    const char *BlobStart = 0;
+    unsigned BlobLen = 0;
+    switch ((pch::PCHRecordTypes)Stream.ReadRecord(Code, Record,
+                                                   &BlobStart, &BlobLen)) {
+    default:  // Default behavior: ignore.
+      break;
+
+    case pch::TYPE_OFFSET:
+      if (!TypesLoaded.empty()) {
+        Error("duplicate TYPE_OFFSET record in PCH file");
+        return Failure;
+      }
+      TypeOffsets = (const uint32_t *)BlobStart;
+      TypesLoaded.resize(Record[0]);
+      break;
+
+    case pch::DECL_OFFSET:
+      if (!DeclsLoaded.empty()) {
+        Error("duplicate DECL_OFFSET record in PCH file");
+        return Failure;
+      }
+      DeclOffsets = (const uint32_t *)BlobStart;
+      DeclsLoaded.resize(Record[0]);
+      break;
+
+    case pch::LANGUAGE_OPTIONS:
+      if (ParseLanguageOptions(Record))
+        return IgnorePCH;
+      break;
+
+    case pch::METADATA: {
+      if (Record[0] != pch::VERSION_MAJOR) {
+        Diag(Record[0] < pch::VERSION_MAJOR? diag::warn_pch_version_too_old
+                                           : diag::warn_pch_version_too_new);
+        return IgnorePCH;
+      }
+
+      RelocatablePCH = Record[4];
+      if (Listener) {
+        std::string TargetTriple(BlobStart, BlobLen);
+        if (Listener->ReadTargetTriple(TargetTriple))
+          return IgnorePCH;
+      }
+      break;
+    }
+
+    case pch::IDENTIFIER_TABLE:
+      IdentifierTableData = BlobStart;
+      if (Record[0]) {
+        IdentifierLookupTable
+          = PCHIdentifierLookupTable::Create(
+                        (const unsigned char *)IdentifierTableData + Record[0],
+                        (const unsigned char *)IdentifierTableData,
+                        PCHIdentifierLookupTrait(*this));
+        if (PP)
+          PP->getIdentifierTable().setExternalIdentifierLookup(this);
+      }
+      break;
+
+    case pch::IDENTIFIER_OFFSET:
+      if (!IdentifiersLoaded.empty()) {
+        Error("duplicate IDENTIFIER_OFFSET record in PCH file");
+        return Failure;
+      }
+      IdentifierOffsets = (const uint32_t *)BlobStart;
+      IdentifiersLoaded.resize(Record[0]);
+      if (PP)
+        PP->getHeaderSearchInfo().SetExternalLookup(this);
+      break;
+
+    case pch::EXTERNAL_DEFINITIONS:
+      if (!ExternalDefinitions.empty()) {
+        Error("duplicate EXTERNAL_DEFINITIONS record in PCH file");
+        return Failure;
+      }
+      ExternalDefinitions.swap(Record);
+      break;
+
+    case pch::SPECIAL_TYPES:
+      SpecialTypes.swap(Record);
+      break;
+
+    case pch::STATISTICS:
+      TotalNumStatements = Record[0];
+      TotalNumMacros = Record[1];
+      TotalLexicalDeclContexts = Record[2];
+      TotalVisibleDeclContexts = Record[3];
+      break;
+
+    case pch::TENTATIVE_DEFINITIONS:
+      if (!TentativeDefinitions.empty()) {
+        Error("duplicate TENTATIVE_DEFINITIONS record in PCH file");
+        return Failure;
+      }
+      TentativeDefinitions.swap(Record);
+      break;
+
+    case pch::UNUSED_STATIC_FUNCS:
+      if (!UnusedStaticFuncs.empty()) {
+        Error("duplicate UNUSED_STATIC_FUNCS record in PCH file");
+        return Failure;
+      }
+      UnusedStaticFuncs.swap(Record);
+      break;
+
+    case pch::LOCALLY_SCOPED_EXTERNAL_DECLS:
+      if (!LocallyScopedExternalDecls.empty()) {
+        Error("duplicate LOCALLY_SCOPED_EXTERNAL_DECLS record in PCH file");
+        return Failure;
+      }
+      LocallyScopedExternalDecls.swap(Record);
+      break;
+
+    case pch::SELECTOR_OFFSETS:
+      SelectorOffsets = (const uint32_t *)BlobStart;
+      TotalNumSelectors = Record[0];
+      SelectorsLoaded.resize(TotalNumSelectors);
+      break;
+
+    case pch::METHOD_POOL:
+      MethodPoolLookupTableData = (const unsigned char *)BlobStart;
+      if (Record[0])
+        MethodPoolLookupTable
+          = PCHMethodPoolLookupTable::Create(
+                        MethodPoolLookupTableData + Record[0],
+                        MethodPoolLookupTableData,
+                        PCHMethodPoolLookupTrait(*this));
+      TotalSelectorsInMethodPool = Record[1];
+      break;
+
+    case pch::PP_COUNTER_VALUE:
+      if (!Record.empty() && Listener)
+        Listener->ReadCounter(Record[0]);
+      break;
+
+    case pch::SOURCE_LOCATION_OFFSETS:
+      SLocOffsets = (const uint32_t *)BlobStart;
+      TotalNumSLocEntries = Record[0];
+      SourceMgr.PreallocateSLocEntries(this, TotalNumSLocEntries, Record[1]);
+      break;
+
+    case pch::SOURCE_LOCATION_PRELOADS:
+      for (unsigned I = 0, N = Record.size(); I != N; ++I) {
+        PCHReadResult Result = ReadSLocEntryRecord(Record[I]);
+        if (Result != Success)
+          return Result;
+      }
+      break;
+
+    case pch::STAT_CACHE: {
+      PCHStatCache *MyStatCache =
+        new PCHStatCache((const unsigned char *)BlobStart + Record[0],
+                         (const unsigned char *)BlobStart,
+                         NumStatHits, NumStatMisses);
+      FileMgr.addStatCache(MyStatCache);
+      StatCache = MyStatCache;
+      break;
+    }
+
+    case pch::EXT_VECTOR_DECLS:
+      if (!ExtVectorDecls.empty()) {
+        Error("duplicate EXT_VECTOR_DECLS record in PCH file");
+        return Failure;
+      }
+      ExtVectorDecls.swap(Record);
+      break;
+
+    case pch::ORIGINAL_FILE_NAME:
+      ActualOriginalFileName.assign(BlobStart, BlobLen);
+      OriginalFileName = ActualOriginalFileName;
+      MaybeAddSystemRootToFilename(OriginalFileName);
+      break;
+
+    case pch::VERSION_CONTROL_BRANCH_REVISION: {
+      const std::string &CurBranch = getClangFullRepositoryVersion();
+      llvm::StringRef PCHBranch(BlobStart, BlobLen);
+      if (llvm::StringRef(CurBranch) != PCHBranch) {
+        Diag(diag::warn_pch_different_branch) << PCHBranch << CurBranch;
+        return IgnorePCH;
+      }
+      break;
+    }
+        
+    case pch::MACRO_DEFINITION_OFFSETS:
+      MacroDefinitionOffsets = (const uint32_t *)BlobStart;
+      if (PP) {
+        if (!PP->getPreprocessingRecord())
+          PP->createPreprocessingRecord();
+        PP->getPreprocessingRecord()->SetExternalSource(*this, Record[0]);
+      } else {
+        NumPreallocatedPreprocessingEntities = Record[0];
+      }
+       
+      MacroDefinitionsLoaded.resize(Record[1]);
+      break;
+    }
+  }
+  Error("premature end of bitstream in PCH file");
+  return Failure;
+}
+
+PCHReader::PCHReadResult PCHReader::ReadPCH(const std::string &FileName) {
+  // Set the PCH file name.
+  this->FileName = FileName;
+
+  // Open the PCH file.
+  //
+  // FIXME: This shouldn't be here, we should just take a raw_ostream.
+  std::string ErrStr;
+  Buffer.reset(llvm::MemoryBuffer::getFileOrSTDIN(FileName, &ErrStr));
+  if (!Buffer) {
+    Error(ErrStr.c_str());
+    return IgnorePCH;
+  }
+
+  // Initialize the stream
+  StreamFile.init((const unsigned char *)Buffer->getBufferStart(),
+                  (const unsigned char *)Buffer->getBufferEnd());
+  Stream.init(StreamFile);
+
+  // Sniff for the signature.
+  if (Stream.Read(8) != 'C' ||
+      Stream.Read(8) != 'P' ||
+      Stream.Read(8) != 'C' ||
+      Stream.Read(8) != 'H') {
+    Diag(diag::err_not_a_pch_file) << FileName;
+    return Failure;
+  }
+
+  while (!Stream.AtEndOfStream()) {
+    unsigned Code = Stream.ReadCode();
+
+    if (Code != llvm::bitc::ENTER_SUBBLOCK) {
+      Error("invalid record at top-level of PCH file");
+      return Failure;
+    }
+
+    unsigned BlockID = Stream.ReadSubBlockID();
+
+    // We only know the PCH subblock ID.
+    switch (BlockID) {
+    case llvm::bitc::BLOCKINFO_BLOCK_ID:
+      if (Stream.ReadBlockInfoBlock()) {
+        Error("malformed BlockInfoBlock in PCH file");
+        return Failure;
+      }
+      break;
+    case pch::PCH_BLOCK_ID:
+      switch (ReadPCHBlock()) {
+      case Success:
+        break;
+
+      case Failure:
+        return Failure;
+
+      case IgnorePCH:
+        // FIXME: We could consider reading through to the end of this
+        // PCH block, skipping subblocks, to see if there are other
+        // PCH blocks elsewhere.
+
+        // Clear out any preallocated source location entries, so that
+        // the source manager does not try to resolve them later.
+        SourceMgr.ClearPreallocatedSLocEntries();
+
+        // Remove the stat cache.
+        if (StatCache)
+          FileMgr.removeStatCache((PCHStatCache*)StatCache);
+
+        return IgnorePCH;
+      }
+      break;
+    default:
+      if (Stream.SkipBlock()) {
+        Error("malformed block record in PCH file");
+        return Failure;
+      }
+      break;
+    }
+  }
+
+  // Check the predefines buffer.
+  if (CheckPredefinesBuffer(llvm::StringRef(PCHPredefines, PCHPredefinesLen),
+                            PCHPredefinesBufferID))
+    return IgnorePCH;
+
+  if (PP) {
+    // Initialization of keywords and pragmas occurs before the
+    // PCH file is read, so there may be some identifiers that were
+    // loaded into the IdentifierTable before we intercepted the
+    // creation of identifiers. Iterate through the list of known
+    // identifiers and determine whether we have to establish
+    // preprocessor definitions or top-level identifier declaration
+    // chains for those identifiers.
+    //
+    // We copy the IdentifierInfo pointers to a small vector first,
+    // since de-serializing declarations or macro definitions can add
+    // new entries into the identifier table, invalidating the
+    // iterators.
+    llvm::SmallVector<IdentifierInfo *, 128> Identifiers;
+    for (IdentifierTable::iterator Id = PP->getIdentifierTable().begin(),
+                                IdEnd = PP->getIdentifierTable().end();
+         Id != IdEnd; ++Id)
+      Identifiers.push_back(Id->second);
+    PCHIdentifierLookupTable *IdTable
+      = (PCHIdentifierLookupTable *)IdentifierLookupTable;
+    for (unsigned I = 0, N = Identifiers.size(); I != N; ++I) {
+      IdentifierInfo *II = Identifiers[I];
+      // Look in the on-disk hash table for an entry for
+      PCHIdentifierLookupTrait Info(*this, II);
+      std::pair<const char*, unsigned> Key(II->getNameStart(), II->getLength());
+      PCHIdentifierLookupTable::iterator Pos = IdTable->find(Key, &Info);
+      if (Pos == IdTable->end())
+        continue;
+
+      // Dereferencing the iterator has the effect of populating the
+      // IdentifierInfo node with the various declarations it needs.
+      (void)*Pos;
+    }
+  }
+
+  if (Context)
+    InitializeContext(*Context);
+
+  return Success;
+}
+
+void PCHReader::setPreprocessor(Preprocessor &pp) {
+  PP = &pp;
+  
+  if (NumPreallocatedPreprocessingEntities) {
+    if (!PP->getPreprocessingRecord())
+      PP->createPreprocessingRecord();
+    PP->getPreprocessingRecord()->SetExternalSource(*this, 
+                                          NumPreallocatedPreprocessingEntities);
+    NumPreallocatedPreprocessingEntities = 0;
+  }
+}
+
+void PCHReader::InitializeContext(ASTContext &Ctx) {
+  Context = &Ctx;
+  assert(Context && "Passed null context!");
+
+  assert(PP && "Forgot to set Preprocessor ?");
+  PP->getIdentifierTable().setExternalIdentifierLookup(this);
+  PP->getHeaderSearchInfo().SetExternalLookup(this);
+  PP->setExternalSource(this);
+
+  // Load the translation unit declaration
+  ReadDeclRecord(DeclOffsets[0], 0);
+
+  // Load the special types.
+  Context->setBuiltinVaListType(
+    GetType(SpecialTypes[pch::SPECIAL_TYPE_BUILTIN_VA_LIST]));
+  if (unsigned Id = SpecialTypes[pch::SPECIAL_TYPE_OBJC_ID])
+    Context->setObjCIdType(GetType(Id));
+  if (unsigned Sel = SpecialTypes[pch::SPECIAL_TYPE_OBJC_SELECTOR])
+    Context->setObjCSelType(GetType(Sel));
+  if (unsigned Proto = SpecialTypes[pch::SPECIAL_TYPE_OBJC_PROTOCOL])
+    Context->setObjCProtoType(GetType(Proto));
+  if (unsigned Class = SpecialTypes[pch::SPECIAL_TYPE_OBJC_CLASS])
+    Context->setObjCClassType(GetType(Class));
+
+  if (unsigned String = SpecialTypes[pch::SPECIAL_TYPE_CF_CONSTANT_STRING])
+    Context->setCFConstantStringType(GetType(String));
+  if (unsigned FastEnum
+        = SpecialTypes[pch::SPECIAL_TYPE_OBJC_FAST_ENUMERATION_STATE])
+    Context->setObjCFastEnumerationStateType(GetType(FastEnum));
+  if (unsigned File = SpecialTypes[pch::SPECIAL_TYPE_FILE]) {
+    QualType FileType = GetType(File);
+    if (FileType.isNull()) {
+      Error("FILE type is NULL");
+      return;
+    }
+    if (const TypedefType *Typedef = FileType->getAs<TypedefType>())
+      Context->setFILEDecl(Typedef->getDecl());
+    else {
+      const TagType *Tag = FileType->getAs<TagType>();
+      if (!Tag) {
+        Error("Invalid FILE type in PCH file");
+        return;
+      }
+      Context->setFILEDecl(Tag->getDecl());
+    }
+  }
+  if (unsigned Jmp_buf = SpecialTypes[pch::SPECIAL_TYPE_jmp_buf]) {
+    QualType Jmp_bufType = GetType(Jmp_buf);
+    if (Jmp_bufType.isNull()) {
+      Error("jmp_bug type is NULL");
+      return;
+    }
+    if (const TypedefType *Typedef = Jmp_bufType->getAs<TypedefType>())
+      Context->setjmp_bufDecl(Typedef->getDecl());
+    else {
+      const TagType *Tag = Jmp_bufType->getAs<TagType>();
+      if (!Tag) {
+        Error("Invalid jmp_bug type in PCH file");
+        return;
+      }
+      Context->setjmp_bufDecl(Tag->getDecl());
+    }
+  }
+  if (unsigned Sigjmp_buf = SpecialTypes[pch::SPECIAL_TYPE_sigjmp_buf]) {
+    QualType Sigjmp_bufType = GetType(Sigjmp_buf);
+    if (Sigjmp_bufType.isNull()) {
+      Error("sigjmp_buf type is NULL");
+      return;
+    }
+    if (const TypedefType *Typedef = Sigjmp_bufType->getAs<TypedefType>())
+      Context->setsigjmp_bufDecl(Typedef->getDecl());
+    else {
+      const TagType *Tag = Sigjmp_bufType->getAs<TagType>();
+      assert(Tag && "Invalid sigjmp_buf type in PCH file");
+      Context->setsigjmp_bufDecl(Tag->getDecl());
+    }
+  }
+  if (unsigned ObjCIdRedef
+        = SpecialTypes[pch::SPECIAL_TYPE_OBJC_ID_REDEFINITION])
+    Context->ObjCIdRedefinitionType = GetType(ObjCIdRedef);
+  if (unsigned ObjCClassRedef
+      = SpecialTypes[pch::SPECIAL_TYPE_OBJC_CLASS_REDEFINITION])
+    Context->ObjCClassRedefinitionType = GetType(ObjCClassRedef);
+  if (unsigned String = SpecialTypes[pch::SPECIAL_TYPE_BLOCK_DESCRIPTOR])
+    Context->setBlockDescriptorType(GetType(String));
+  if (unsigned String
+      = SpecialTypes[pch::SPECIAL_TYPE_BLOCK_EXTENDED_DESCRIPTOR])
+    Context->setBlockDescriptorExtendedType(GetType(String));
+  if (unsigned ObjCSelRedef
+      = SpecialTypes[pch::SPECIAL_TYPE_OBJC_SEL_REDEFINITION])
+    Context->ObjCSelRedefinitionType = GetType(ObjCSelRedef);
+  if (unsigned String = SpecialTypes[pch::SPECIAL_TYPE_NS_CONSTANT_STRING])
+    Context->setNSConstantStringType(GetType(String));
+}
+
+/// \brief Retrieve the name of the original source file name
+/// directly from the PCH file, without actually loading the PCH
+/// file.
+std::string PCHReader::getOriginalSourceFile(const std::string &PCHFileName,
+                                             Diagnostic &Diags) {
+  // Open the PCH file.
+  std::string ErrStr;
+  llvm::OwningPtr<llvm::MemoryBuffer> Buffer;
+  Buffer.reset(llvm::MemoryBuffer::getFile(PCHFileName.c_str(), &ErrStr));
+  if (!Buffer) {
+    Diags.Report(diag::err_fe_unable_to_read_pch_file) << ErrStr;
+    return std::string();
+  }
+
+  // Initialize the stream
+  llvm::BitstreamReader StreamFile;
+  llvm::BitstreamCursor Stream;
+  StreamFile.init((const unsigned char *)Buffer->getBufferStart(),
+                  (const unsigned char *)Buffer->getBufferEnd());
+  Stream.init(StreamFile);
+
+  // Sniff for the signature.
+  if (Stream.Read(8) != 'C' ||
+      Stream.Read(8) != 'P' ||
+      Stream.Read(8) != 'C' ||
+      Stream.Read(8) != 'H') {
+    Diags.Report(diag::err_fe_not_a_pch_file) << PCHFileName;
+    return std::string();
+  }
+
+  RecordData Record;
+  while (!Stream.AtEndOfStream()) {
+    unsigned Code = Stream.ReadCode();
+
+    if (Code == llvm::bitc::ENTER_SUBBLOCK) {
+      unsigned BlockID = Stream.ReadSubBlockID();
+
+      // We only know the PCH subblock ID.
+      switch (BlockID) {
+      case pch::PCH_BLOCK_ID:
+        if (Stream.EnterSubBlock(pch::PCH_BLOCK_ID)) {
+          Diags.Report(diag::err_fe_pch_malformed_block) << PCHFileName;
+          return std::string();
+        }
+        break;
+
+      default:
+        if (Stream.SkipBlock()) {
+          Diags.Report(diag::err_fe_pch_malformed_block) << PCHFileName;
+          return std::string();
+        }
+        break;
+      }
+      continue;
+    }
+
+    if (Code == llvm::bitc::END_BLOCK) {
+      if (Stream.ReadBlockEnd()) {
+        Diags.Report(diag::err_fe_pch_error_at_end_block) << PCHFileName;
+        return std::string();
+      }
+      continue;
+    }
+
+    if (Code == llvm::bitc::DEFINE_ABBREV) {
+      Stream.ReadAbbrevRecord();
+      continue;
+    }
+
+    Record.clear();
+    const char *BlobStart = 0;
+    unsigned BlobLen = 0;
+    if (Stream.ReadRecord(Code, Record, &BlobStart, &BlobLen)
+          == pch::ORIGINAL_FILE_NAME)
+      return std::string(BlobStart, BlobLen);
+  }
+
+  return std::string();
+}
+
+/// \brief Parse the record that corresponds to a LangOptions data
+/// structure.
+///
+/// This routine compares the language options used to generate the
+/// PCH file against the language options set for the current
+/// compilation. For each option, we classify differences between the
+/// two compiler states as either "benign" or "important". Benign
+/// differences don't matter, and we accept them without complaint
+/// (and without modifying the language options). Differences between
+/// the states for important options cause the PCH file to be
+/// unusable, so we emit a warning and return true to indicate that
+/// there was an error.
+///
+/// \returns true if the PCH file is unacceptable, false otherwise.
+bool PCHReader::ParseLanguageOptions(
+                             const llvm::SmallVectorImpl<uint64_t> &Record) {
+  if (Listener) {
+    LangOptions LangOpts;
+
+  #define PARSE_LANGOPT(Option)                  \
+      LangOpts.Option = Record[Idx];             \
+      ++Idx
+
+    unsigned Idx = 0;
+    PARSE_LANGOPT(Trigraphs);
+    PARSE_LANGOPT(BCPLComment);
+    PARSE_LANGOPT(DollarIdents);
+    PARSE_LANGOPT(AsmPreprocessor);
+    PARSE_LANGOPT(GNUMode);
+    PARSE_LANGOPT(GNUKeywords);
+    PARSE_LANGOPT(ImplicitInt);
+    PARSE_LANGOPT(Digraphs);
+    PARSE_LANGOPT(HexFloats);
+    PARSE_LANGOPT(C99);
+    PARSE_LANGOPT(Microsoft);
+    PARSE_LANGOPT(CPlusPlus);
+    PARSE_LANGOPT(CPlusPlus0x);
+    PARSE_LANGOPT(CXXOperatorNames);
+    PARSE_LANGOPT(ObjC1);
+    PARSE_LANGOPT(ObjC2);
+    PARSE_LANGOPT(ObjCNonFragileABI);
+    PARSE_LANGOPT(ObjCNonFragileABI2);
+    PARSE_LANGOPT(NoConstantCFStrings);
+    PARSE_LANGOPT(PascalStrings);
+    PARSE_LANGOPT(WritableStrings);
+    PARSE_LANGOPT(LaxVectorConversions);
+    PARSE_LANGOPT(AltiVec);
+    PARSE_LANGOPT(Exceptions);
+    PARSE_LANGOPT(SjLjExceptions);
+    PARSE_LANGOPT(NeXTRuntime);
+    PARSE_LANGOPT(Freestanding);
+    PARSE_LANGOPT(NoBuiltin);
+    PARSE_LANGOPT(ThreadsafeStatics);
+    PARSE_LANGOPT(POSIXThreads);
+    PARSE_LANGOPT(Blocks);
+    PARSE_LANGOPT(EmitAllDecls);
+    PARSE_LANGOPT(MathErrno);
+    PARSE_LANGOPT(OverflowChecking);
+    PARSE_LANGOPT(HeinousExtensions);
+    PARSE_LANGOPT(Optimize);
+    PARSE_LANGOPT(OptimizeSize);
+    PARSE_LANGOPT(Static);
+    PARSE_LANGOPT(PICLevel);
+    PARSE_LANGOPT(GNUInline);
+    PARSE_LANGOPT(NoInline);
+    PARSE_LANGOPT(AccessControl);
+    PARSE_LANGOPT(CharIsSigned);
+    PARSE_LANGOPT(ShortWChar);
+    LangOpts.setGCMode((LangOptions::GCMode)Record[Idx]);
+    ++Idx;
+    LangOpts.setVisibilityMode((LangOptions::VisibilityMode)Record[Idx]);
+    ++Idx;
+    LangOpts.setStackProtectorMode((LangOptions::StackProtectorMode)
+                                   Record[Idx]);
+    ++Idx;
+    PARSE_LANGOPT(InstantiationDepth);
+    PARSE_LANGOPT(OpenCL);
+    PARSE_LANGOPT(CatchUndefined);
+    // FIXME: Missing ElideConstructors?!
+  #undef PARSE_LANGOPT
+
+    return Listener->ReadLanguageOptions(LangOpts);
+  }
+
+  return false;
+}
+
+void PCHReader::ReadPreprocessedEntities() {
+  ReadDefinedMacros();
+}
+
+/// \brief Read and return the type at the given offset.
+///
+/// This routine actually reads the record corresponding to the type
+/// at the given offset in the bitstream. It is a helper routine for
+/// GetType, which deals with reading type IDs.
+QualType PCHReader::ReadTypeRecord(uint64_t Offset) {
+  // Keep track of where we are in the stream, then jump back there
+  // after reading this type.
+  SavedStreamPosition SavedPosition(DeclsCursor);
+
+  // Note that we are loading a type record.
+  LoadingTypeOrDecl Loading(*this);
+
+  DeclsCursor.JumpToBit(Offset);
+  RecordData Record;
+  unsigned Code = DeclsCursor.ReadCode();
+  switch ((pch::TypeCode)DeclsCursor.ReadRecord(Code, Record)) {
+  case pch::TYPE_EXT_QUAL: {
+    if (Record.size() != 2) {
+      Error("Incorrect encoding of extended qualifier type");
+      return QualType();
+    }
+    QualType Base = GetType(Record[0]);
+    Qualifiers Quals = Qualifiers::fromOpaqueValue(Record[1]);
+    return Context->getQualifiedType(Base, Quals);
+  }
+
+  case pch::TYPE_COMPLEX: {
+    if (Record.size() != 1) {
+      Error("Incorrect encoding of complex type");
+      return QualType();
+    }
+    QualType ElemType = GetType(Record[0]);
+    return Context->getComplexType(ElemType);
+  }
+
+  case pch::TYPE_POINTER: {
+    if (Record.size() != 1) {
+      Error("Incorrect encoding of pointer type");
+      return QualType();
+    }
+    QualType PointeeType = GetType(Record[0]);
+    return Context->getPointerType(PointeeType);
+  }
+
+  case pch::TYPE_BLOCK_POINTER: {
+    if (Record.size() != 1) {
+      Error("Incorrect encoding of block pointer type");
+      return QualType();
+    }
+    QualType PointeeType = GetType(Record[0]);
+    return Context->getBlockPointerType(PointeeType);
+  }
+
+  case pch::TYPE_LVALUE_REFERENCE: {
+    if (Record.size() != 1) {
+      Error("Incorrect encoding of lvalue reference type");
+      return QualType();
+    }
+    QualType PointeeType = GetType(Record[0]);
+    return Context->getLValueReferenceType(PointeeType);
+  }
+
+  case pch::TYPE_RVALUE_REFERENCE: {
+    if (Record.size() != 1) {
+      Error("Incorrect encoding of rvalue reference type");
+      return QualType();
+    }
+    QualType PointeeType = GetType(Record[0]);
+    return Context->getRValueReferenceType(PointeeType);
+  }
+
+  case pch::TYPE_MEMBER_POINTER: {
+    if (Record.size() != 1) {
+      Error("Incorrect encoding of member pointer type");
+      return QualType();
+    }
+    QualType PointeeType = GetType(Record[0]);
+    QualType ClassType = GetType(Record[1]);
+    return Context->getMemberPointerType(PointeeType, ClassType.getTypePtr());
+  }
+
+  case pch::TYPE_CONSTANT_ARRAY: {
+    QualType ElementType = GetType(Record[0]);
+    ArrayType::ArraySizeModifier ASM = (ArrayType::ArraySizeModifier)Record[1];
+    unsigned IndexTypeQuals = Record[2];
+    unsigned Idx = 3;
+    llvm::APInt Size = ReadAPInt(Record, Idx);
+    return Context->getConstantArrayType(ElementType, Size,
+                                         ASM, IndexTypeQuals);
+  }
+
+  case pch::TYPE_INCOMPLETE_ARRAY: {
+    QualType ElementType = GetType(Record[0]);
+    ArrayType::ArraySizeModifier ASM = (ArrayType::ArraySizeModifier)Record[1];
+    unsigned IndexTypeQuals = Record[2];
+    return Context->getIncompleteArrayType(ElementType, ASM, IndexTypeQuals);
+  }
+
+  case pch::TYPE_VARIABLE_ARRAY: {
+    QualType ElementType = GetType(Record[0]);
+    ArrayType::ArraySizeModifier ASM = (ArrayType::ArraySizeModifier)Record[1];
+    unsigned IndexTypeQuals = Record[2];
+    SourceLocation LBLoc = SourceLocation::getFromRawEncoding(Record[3]);
+    SourceLocation RBLoc = SourceLocation::getFromRawEncoding(Record[4]);
+    return Context->getVariableArrayType(ElementType, ReadTypeExpr(),
+                                         ASM, IndexTypeQuals,
+                                         SourceRange(LBLoc, RBLoc));
+  }
+
+  case pch::TYPE_VECTOR: {
+    if (Record.size() != 4) {
+      Error("incorrect encoding of vector type in PCH file");
+      return QualType();
+    }
+
+    QualType ElementType = GetType(Record[0]);
+    unsigned NumElements = Record[1];
+    bool AltiVec = Record[2];
+    bool Pixel = Record[3];
+    return Context->getVectorType(ElementType, NumElements, AltiVec, Pixel);
+  }
+
+  case pch::TYPE_EXT_VECTOR: {
+    if (Record.size() != 4) {
+      Error("incorrect encoding of extended vector type in PCH file");
+      return QualType();
+    }
+
+    QualType ElementType = GetType(Record[0]);
+    unsigned NumElements = Record[1];
+    return Context->getExtVectorType(ElementType, NumElements);
+  }
+
+  case pch::TYPE_FUNCTION_NO_PROTO: {
+    if (Record.size() != 4) {
+      Error("incorrect encoding of no-proto function type");
+      return QualType();
+    }
+    QualType ResultType = GetType(Record[0]);
+    FunctionType::ExtInfo Info(Record[1], Record[2], (CallingConv)Record[3]);
+    return Context->getFunctionNoProtoType(ResultType, Info);
+  }
+
+  case pch::TYPE_FUNCTION_PROTO: {
+    QualType ResultType = GetType(Record[0]);
+    bool NoReturn = Record[1];
+    unsigned RegParm = Record[2];
+    CallingConv CallConv = (CallingConv)Record[3];
+    unsigned Idx = 4;
+    unsigned NumParams = Record[Idx++];
+    llvm::SmallVector<QualType, 16> ParamTypes;
+    for (unsigned I = 0; I != NumParams; ++I)
+      ParamTypes.push_back(GetType(Record[Idx++]));
+    bool isVariadic = Record[Idx++];
+    unsigned Quals = Record[Idx++];
+    bool hasExceptionSpec = Record[Idx++];
+    bool hasAnyExceptionSpec = Record[Idx++];
+    unsigned NumExceptions = Record[Idx++];
+    llvm::SmallVector<QualType, 2> Exceptions;
+    for (unsigned I = 0; I != NumExceptions; ++I)
+      Exceptions.push_back(GetType(Record[Idx++]));
+    return Context->getFunctionType(ResultType, ParamTypes.data(), NumParams,
+                                    isVariadic, Quals, hasExceptionSpec,
+                                    hasAnyExceptionSpec, NumExceptions,
+                                    Exceptions.data(),
+                                    FunctionType::ExtInfo(NoReturn, RegParm,
+                                                          CallConv));
+  }
+
+  case pch::TYPE_UNRESOLVED_USING:
+    return Context->getTypeDeclType(
+             cast<UnresolvedUsingTypenameDecl>(GetDecl(Record[0])));
+
+  case pch::TYPE_TYPEDEF:
+    if (Record.size() != 1) {
+      Error("incorrect encoding of typedef type");
+      return QualType();
+    }
+    return Context->getTypeDeclType(cast<TypedefDecl>(GetDecl(Record[0])));
+
+  case pch::TYPE_TYPEOF_EXPR:
+    return Context->getTypeOfExprType(ReadTypeExpr());
+
+  case pch::TYPE_TYPEOF: {
+    if (Record.size() != 1) {
+      Error("incorrect encoding of typeof(type) in PCH file");
+      return QualType();
+    }
+    QualType UnderlyingType = GetType(Record[0]);
+    return Context->getTypeOfType(UnderlyingType);
+  }
+
+  case pch::TYPE_DECLTYPE:
+    return Context->getDecltypeType(ReadTypeExpr());
+
+  case pch::TYPE_RECORD:
+    if (Record.size() != 1) {
+      Error("incorrect encoding of record type");
+      return QualType();
+    }
+    return Context->getTypeDeclType(cast<RecordDecl>(GetDecl(Record[0])));
+
+  case pch::TYPE_ENUM:
+    if (Record.size() != 1) {
+      Error("incorrect encoding of enum type");
+      return QualType();
+    }
+    return Context->getTypeDeclType(cast<EnumDecl>(GetDecl(Record[0])));
+
+  case pch::TYPE_ELABORATED: {
+    if (Record.size() != 2) {
+      Error("incorrect encoding of elaborated type");
+      return QualType();
+    }
+    unsigned Tag = Record[1];
+    return Context->getElaboratedType(GetType(Record[0]),
+                                      (ElaboratedType::TagKind) Tag);
+  }
+
+  case pch::TYPE_OBJC_INTERFACE: {
+    unsigned Idx = 0;
+    ObjCInterfaceDecl *ItfD = cast<ObjCInterfaceDecl>(GetDecl(Record[Idx++]));
+    unsigned NumProtos = Record[Idx++];
+    llvm::SmallVector<ObjCProtocolDecl*, 4> Protos;
+    for (unsigned I = 0; I != NumProtos; ++I)
+      Protos.push_back(cast<ObjCProtocolDecl>(GetDecl(Record[Idx++])));
+    return Context->getObjCInterfaceType(ItfD, Protos.data(), NumProtos);
+  }
+
+  case pch::TYPE_OBJC_OBJECT_POINTER: {
+    unsigned Idx = 0;
+    QualType OIT = GetType(Record[Idx++]);
+    unsigned NumProtos = Record[Idx++];
+    llvm::SmallVector<ObjCProtocolDecl*, 4> Protos;
+    for (unsigned I = 0; I != NumProtos; ++I)
+      Protos.push_back(cast<ObjCProtocolDecl>(GetDecl(Record[Idx++])));
+    return Context->getObjCObjectPointerType(OIT, Protos.data(), NumProtos);
+  }
+
+  case pch::TYPE_SUBST_TEMPLATE_TYPE_PARM: {
+    unsigned Idx = 0;
+    QualType Parm = GetType(Record[Idx++]);
+    QualType Replacement = GetType(Record[Idx++]);
+    return
+      Context->getSubstTemplateTypeParmType(cast<TemplateTypeParmType>(Parm),
+                                            Replacement);
+  }
+
+  case pch::TYPE_INJECTED_CLASS_NAME: {
+    CXXRecordDecl *D = cast<CXXRecordDecl>(GetDecl(Record[0]));
+    QualType TST = GetType(Record[1]); // probably derivable
+    return Context->getInjectedClassNameType(D, TST);
+  }
+  }
+  // Suppress a GCC warning
+  return QualType();
+}
+
+namespace {
+
+class TypeLocReader : public TypeLocVisitor<TypeLocReader> {
+  PCHReader &Reader;
+  const PCHReader::RecordData &Record;
+  unsigned &Idx;
+
+public:
+  TypeLocReader(PCHReader &Reader, const PCHReader::RecordData &Record,
+                unsigned &Idx)
+    : Reader(Reader), Record(Record), Idx(Idx) { }
+
+  // We want compile-time assurance that we've enumerated all of
+  // these, so unfortunately we have to declare them first, then
+  // define them out-of-line.
+#define ABSTRACT_TYPELOC(CLASS, PARENT)
+#define TYPELOC(CLASS, PARENT) \
+  void Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc);
+#include "clang/AST/TypeLocNodes.def"
+
+  void VisitFunctionTypeLoc(FunctionTypeLoc);
+  void VisitArrayTypeLoc(ArrayTypeLoc);
+};
+
+}
+
+void TypeLocReader::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
+  // nothing to do
+}
+void TypeLocReader::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
+  TL.setBuiltinLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  if (TL.needsExtraLocalData()) {
+    TL.setWrittenTypeSpec(static_cast<DeclSpec::TST>(Record[Idx++]));
+    TL.setWrittenSignSpec(static_cast<DeclSpec::TSS>(Record[Idx++]));
+    TL.setWrittenWidthSpec(static_cast<DeclSpec::TSW>(Record[Idx++]));
+    TL.setModeAttr(Record[Idx++]);
+  }
+}
+void TypeLocReader::VisitComplexTypeLoc(ComplexTypeLoc TL) {
+  TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+void TypeLocReader::VisitPointerTypeLoc(PointerTypeLoc TL) {
+  TL.setStarLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+void TypeLocReader::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
+  TL.setCaretLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+void TypeLocReader::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
+  TL.setAmpLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+void TypeLocReader::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
+  TL.setAmpAmpLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+void TypeLocReader::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
+  TL.setStarLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+void TypeLocReader::VisitArrayTypeLoc(ArrayTypeLoc TL) {
+  TL.setLBracketLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  TL.setRBracketLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  if (Record[Idx++])
+    TL.setSizeExpr(Reader.ReadDeclExpr());
+  else
+    TL.setSizeExpr(0);
+}
+void TypeLocReader::VisitConstantArrayTypeLoc(ConstantArrayTypeLoc TL) {
+  VisitArrayTypeLoc(TL);
+}
+void TypeLocReader::VisitIncompleteArrayTypeLoc(IncompleteArrayTypeLoc TL) {
+  VisitArrayTypeLoc(TL);
+}
+void TypeLocReader::VisitVariableArrayTypeLoc(VariableArrayTypeLoc TL) {
+  VisitArrayTypeLoc(TL);
+}
+void TypeLocReader::VisitDependentSizedArrayTypeLoc(
+                                            DependentSizedArrayTypeLoc TL) {
+  VisitArrayTypeLoc(TL);
+}
+void TypeLocReader::VisitDependentSizedExtVectorTypeLoc(
+                                        DependentSizedExtVectorTypeLoc TL) {
+  TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+void TypeLocReader::VisitVectorTypeLoc(VectorTypeLoc TL) {
+  TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+void TypeLocReader::VisitExtVectorTypeLoc(ExtVectorTypeLoc TL) {
+  TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+void TypeLocReader::VisitFunctionTypeLoc(FunctionTypeLoc TL) {
+  TL.setLParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  TL.setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) {
+    TL.setArg(i, cast_or_null<ParmVarDecl>(Reader.GetDecl(Record[Idx++])));
+  }
+}
+void TypeLocReader::VisitFunctionProtoTypeLoc(FunctionProtoTypeLoc TL) {
+  VisitFunctionTypeLoc(TL);
+}
+void TypeLocReader::VisitFunctionNoProtoTypeLoc(FunctionNoProtoTypeLoc TL) {
+  VisitFunctionTypeLoc(TL);
+}
+void TypeLocReader::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
+  TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+void TypeLocReader::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
+  TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+void TypeLocReader::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
+  TL.setTypeofLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  TL.setLParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  TL.setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+void TypeLocReader::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
+  TL.setTypeofLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  TL.setLParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  TL.setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  TL.setUnderlyingTInfo(Reader.GetTypeSourceInfo(Record, Idx));
+}
+void TypeLocReader::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
+  TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+void TypeLocReader::VisitRecordTypeLoc(RecordTypeLoc TL) {
+  TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+void TypeLocReader::VisitEnumTypeLoc(EnumTypeLoc TL) {
+  TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+void TypeLocReader::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
+  TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+void TypeLocReader::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
+  TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+void TypeLocReader::VisitSubstTemplateTypeParmTypeLoc(
+                                            SubstTemplateTypeParmTypeLoc TL) {
+  TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+void TypeLocReader::VisitTemplateSpecializationTypeLoc(
+                                           TemplateSpecializationTypeLoc TL) {
+  TL.setTemplateNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  TL.setLAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  TL.setRAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i)
+    TL.setArgLocInfo(i,
+        Reader.GetTemplateArgumentLocInfo(TL.getTypePtr()->getArg(i).getKind(),
+                                          Record, Idx));
+}
+void TypeLocReader::VisitQualifiedNameTypeLoc(QualifiedNameTypeLoc TL) {
+  TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+void TypeLocReader::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
+  TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+void TypeLocReader::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
+  TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+void TypeLocReader::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
+  TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  TL.setLAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  TL.setRAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i)
+    TL.setProtocolLoc(i, SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+void TypeLocReader::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
+  TL.setStarLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  TL.setLAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  TL.setRAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  TL.setHasBaseTypeAsWritten(Record[Idx++]);
+  TL.setHasProtocolsAsWritten(Record[Idx++]);
+  if (TL.hasProtocolsAsWritten())
+    for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i)
+      TL.setProtocolLoc(i, SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+
+TypeSourceInfo *PCHReader::GetTypeSourceInfo(const RecordData &Record,
+                                             unsigned &Idx) {
+  QualType InfoTy = GetType(Record[Idx++]);
+  if (InfoTy.isNull())
+    return 0;
+
+  TypeSourceInfo *TInfo = getContext()->CreateTypeSourceInfo(InfoTy);
+  TypeLocReader TLR(*this, Record, Idx);
+  for (TypeLoc TL = TInfo->getTypeLoc(); !TL.isNull(); TL = TL.getNextTypeLoc())
+    TLR.Visit(TL);
+  return TInfo;
+}
+
+QualType PCHReader::GetType(pch::TypeID ID) {
+  unsigned FastQuals = ID & Qualifiers::FastMask;
+  unsigned Index = ID >> Qualifiers::FastWidth;
+
+  if (Index < pch::NUM_PREDEF_TYPE_IDS) {
+    QualType T;
+    switch ((pch::PredefinedTypeIDs)Index) {
+    case pch::PREDEF_TYPE_NULL_ID: return QualType();
+    case pch::PREDEF_TYPE_VOID_ID: T = Context->VoidTy; break;
+    case pch::PREDEF_TYPE_BOOL_ID: T = Context->BoolTy; break;
+
+    case pch::PREDEF_TYPE_CHAR_U_ID:
+    case pch::PREDEF_TYPE_CHAR_S_ID:
+      // FIXME: Check that the signedness of CharTy is correct!
+      T = Context->CharTy;
+      break;
+
+    case pch::PREDEF_TYPE_UCHAR_ID:      T = Context->UnsignedCharTy;     break;
+    case pch::PREDEF_TYPE_USHORT_ID:     T = Context->UnsignedShortTy;    break;
+    case pch::PREDEF_TYPE_UINT_ID:       T = Context->UnsignedIntTy;      break;
+    case pch::PREDEF_TYPE_ULONG_ID:      T = Context->UnsignedLongTy;     break;
+    case pch::PREDEF_TYPE_ULONGLONG_ID:  T = Context->UnsignedLongLongTy; break;
+    case pch::PREDEF_TYPE_UINT128_ID:    T = Context->UnsignedInt128Ty;   break;
+    case pch::PREDEF_TYPE_SCHAR_ID:      T = Context->SignedCharTy;       break;
+    case pch::PREDEF_TYPE_WCHAR_ID:      T = Context->WCharTy;            break;
+    case pch::PREDEF_TYPE_SHORT_ID:      T = Context->ShortTy;            break;
+    case pch::PREDEF_TYPE_INT_ID:        T = Context->IntTy;              break;
+    case pch::PREDEF_TYPE_LONG_ID:       T = Context->LongTy;             break;
+    case pch::PREDEF_TYPE_LONGLONG_ID:   T = Context->LongLongTy;         break;
+    case pch::PREDEF_TYPE_INT128_ID:     T = Context->Int128Ty;           break;
+    case pch::PREDEF_TYPE_FLOAT_ID:      T = Context->FloatTy;            break;
+    case pch::PREDEF_TYPE_DOUBLE_ID:     T = Context->DoubleTy;           break;
+    case pch::PREDEF_TYPE_LONGDOUBLE_ID: T = Context->LongDoubleTy;       break;
+    case pch::PREDEF_TYPE_OVERLOAD_ID:   T = Context->OverloadTy;         break;
+    case pch::PREDEF_TYPE_DEPENDENT_ID:  T = Context->DependentTy;        break;
+    case pch::PREDEF_TYPE_NULLPTR_ID:    T = Context->NullPtrTy;          break;
+    case pch::PREDEF_TYPE_CHAR16_ID:     T = Context->Char16Ty;           break;
+    case pch::PREDEF_TYPE_CHAR32_ID:     T = Context->Char32Ty;           break;
+    case pch::PREDEF_TYPE_OBJC_ID:       T = Context->ObjCBuiltinIdTy;    break;
+    case pch::PREDEF_TYPE_OBJC_CLASS:    T = Context->ObjCBuiltinClassTy; break;
+    case pch::PREDEF_TYPE_OBJC_SEL:      T = Context->ObjCBuiltinSelTy;   break;
+    }
+
+    assert(!T.isNull() && "Unknown predefined type");
+    return T.withFastQualifiers(FastQuals);
+  }
+
+  Index -= pch::NUM_PREDEF_TYPE_IDS;
+  //assert(Index < TypesLoaded.size() && "Type index out-of-range");
+  if (TypesLoaded[Index].isNull())
+    TypesLoaded[Index] = ReadTypeRecord(TypeOffsets[Index]);
+
+  return TypesLoaded[Index].withFastQualifiers(FastQuals);
+}
+
+TemplateArgumentLocInfo
+PCHReader::GetTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind,
+                                      const RecordData &Record,
+                                      unsigned &Index) {
+  switch (Kind) {
+  case TemplateArgument::Expression:
+    return ReadDeclExpr();
+  case TemplateArgument::Type:
+    return GetTypeSourceInfo(Record, Index);
+  case TemplateArgument::Template: {
+    SourceLocation
+      QualStart = SourceLocation::getFromRawEncoding(Record[Index++]),
+      QualEnd = SourceLocation::getFromRawEncoding(Record[Index++]),
+      TemplateNameLoc = SourceLocation::getFromRawEncoding(Record[Index++]);
+    return TemplateArgumentLocInfo(SourceRange(QualStart, QualEnd),
+                                   TemplateNameLoc);
+  }
+  case TemplateArgument::Null:
+  case TemplateArgument::Integral:
+  case TemplateArgument::Declaration:
+  case TemplateArgument::Pack:
+    return TemplateArgumentLocInfo();
+  }
+  llvm_unreachable("unexpected template argument loc");
+  return TemplateArgumentLocInfo();
+}
+
+Decl *PCHReader::GetDecl(pch::DeclID ID) {
+  if (ID == 0)
+    return 0;
+
+  if (ID > DeclsLoaded.size()) {
+    Error("declaration ID out-of-range for PCH file");
+    return 0;
+  }
+
+  unsigned Index = ID - 1;
+  if (!DeclsLoaded[Index])
+    ReadDeclRecord(DeclOffsets[Index], Index);
+
+  return DeclsLoaded[Index];
+}
+
+/// \brief Resolve the offset of a statement into a statement.
+///
+/// This operation will read a new statement from the external
+/// source each time it is called, and is meant to be used via a
+/// LazyOffsetPtr (which is used by Decls for the body of functions, etc).
+Stmt *PCHReader::GetDeclStmt(uint64_t Offset) {
+  // Since we know tha this statement is part of a decl, make sure to use the
+  // decl cursor to read it.
+  DeclsCursor.JumpToBit(Offset);
+  return ReadStmt(DeclsCursor);
+}
+
+bool PCHReader::ReadDeclsLexicallyInContext(DeclContext *DC,
+                                  llvm::SmallVectorImpl<pch::DeclID> &Decls) {
+  assert(DC->hasExternalLexicalStorage() &&
+         "DeclContext has no lexical decls in storage");
+
+  uint64_t Offset = DeclContextOffsets[DC].first;
+  if (Offset == 0) {
+    Error("DeclContext has no lexical decls in storage");
+    return true;
+  }
+
+  // Keep track of where we are in the stream, then jump back there
+  // after reading this context.
+  SavedStreamPosition SavedPosition(DeclsCursor);
+
+  // Load the record containing all of the declarations lexically in
+  // this context.
+  DeclsCursor.JumpToBit(Offset);
+  RecordData Record;
+  unsigned Code = DeclsCursor.ReadCode();
+  unsigned RecCode = DeclsCursor.ReadRecord(Code, Record);
+  if (RecCode != pch::DECL_CONTEXT_LEXICAL) {
+    Error("Expected lexical block");
+    return true;
+  }
+
+  // Load all of the declaration IDs
+  Decls.clear();
+  Decls.insert(Decls.end(), Record.begin(), Record.end());
+  ++NumLexicalDeclContextsRead;
+  return false;
+}
+
+bool PCHReader::ReadDeclsVisibleInContext(DeclContext *DC,
+                           llvm::SmallVectorImpl<VisibleDeclaration> &Decls) {
+  assert(DC->hasExternalVisibleStorage() &&
+         "DeclContext has no visible decls in storage");
+  uint64_t Offset = DeclContextOffsets[DC].second;
+  if (Offset == 0) {
+    Error("DeclContext has no visible decls in storage");
+    return true;
+  }
+
+  // Keep track of where we are in the stream, then jump back there
+  // after reading this context.
+  SavedStreamPosition SavedPosition(DeclsCursor);
+
+  // Load the record containing all of the declarations visible in
+  // this context.
+  DeclsCursor.JumpToBit(Offset);
+  RecordData Record;
+  unsigned Code = DeclsCursor.ReadCode();
+  unsigned RecCode = DeclsCursor.ReadRecord(Code, Record);
+  if (RecCode != pch::DECL_CONTEXT_VISIBLE) {
+    Error("Expected visible block");
+    return true;
+  }
+
+  if (Record.size() == 0)
+    return false;
+
+  Decls.clear();
+
+  unsigned Idx = 0;
+  while (Idx < Record.size()) {
+    Decls.push_back(VisibleDeclaration());
+    Decls.back().Name = ReadDeclarationName(Record, Idx);
+
+    unsigned Size = Record[Idx++];
+    llvm::SmallVector<unsigned, 4> &LoadedDecls = Decls.back().Declarations;
+    LoadedDecls.reserve(Size);
+    for (unsigned I = 0; I < Size; ++I)
+      LoadedDecls.push_back(Record[Idx++]);
+  }
+
+  ++NumVisibleDeclContextsRead;
+  return false;
+}
+
+void PCHReader::StartTranslationUnit(ASTConsumer *Consumer) {
+  this->Consumer = Consumer;
+
+  if (!Consumer)
+    return;
+
+  for (unsigned I = 0, N = ExternalDefinitions.size(); I != N; ++I) {
+    // Force deserialization of this decl, which will cause it to be passed to
+    // the consumer (or queued).
+    GetDecl(ExternalDefinitions[I]);
+  }
+
+  for (unsigned I = 0, N = InterestingDecls.size(); I != N; ++I) {
+    DeclGroupRef DG(InterestingDecls[I]);
+    Consumer->HandleTopLevelDecl(DG);
+  }
+}
+
+void PCHReader::PrintStats() {
+  std::fprintf(stderr, "*** PCH Statistics:\n");
+
+  unsigned NumTypesLoaded
+    = TypesLoaded.size() - std::count(TypesLoaded.begin(), TypesLoaded.end(),
+                                      QualType());
+  unsigned NumDeclsLoaded
+    = DeclsLoaded.size() - std::count(DeclsLoaded.begin(), DeclsLoaded.end(),
+                                      (Decl *)0);
+  unsigned NumIdentifiersLoaded
+    = IdentifiersLoaded.size() - std::count(IdentifiersLoaded.begin(),
+                                            IdentifiersLoaded.end(),
+                                            (IdentifierInfo *)0);
+  unsigned NumSelectorsLoaded
+    = SelectorsLoaded.size() - std::count(SelectorsLoaded.begin(),
+                                          SelectorsLoaded.end(),
+                                          Selector());
+
+  std::fprintf(stderr, "  %u stat cache hits\n", NumStatHits);
+  std::fprintf(stderr, "  %u stat cache misses\n", NumStatMisses);
+  if (TotalNumSLocEntries)
+    std::fprintf(stderr, "  %u/%u source location entries read (%f%%)\n",
+                 NumSLocEntriesRead, TotalNumSLocEntries,
+                 ((float)NumSLocEntriesRead/TotalNumSLocEntries * 100));
+  if (!TypesLoaded.empty())
+    std::fprintf(stderr, "  %u/%u types read (%f%%)\n",
+                 NumTypesLoaded, (unsigned)TypesLoaded.size(),
+                 ((float)NumTypesLoaded/TypesLoaded.size() * 100));
+  if (!DeclsLoaded.empty())
+    std::fprintf(stderr, "  %u/%u declarations read (%f%%)\n",
+                 NumDeclsLoaded, (unsigned)DeclsLoaded.size(),
+                 ((float)NumDeclsLoaded/DeclsLoaded.size() * 100));
+  if (!IdentifiersLoaded.empty())
+    std::fprintf(stderr, "  %u/%u identifiers read (%f%%)\n",
+                 NumIdentifiersLoaded, (unsigned)IdentifiersLoaded.size(),
+                 ((float)NumIdentifiersLoaded/IdentifiersLoaded.size() * 100));
+  if (TotalNumSelectors)
+    std::fprintf(stderr, "  %u/%u selectors read (%f%%)\n",
+                 NumSelectorsLoaded, TotalNumSelectors,
+                 ((float)NumSelectorsLoaded/TotalNumSelectors * 100));
+  if (TotalNumStatements)
+    std::fprintf(stderr, "  %u/%u statements read (%f%%)\n",
+                 NumStatementsRead, TotalNumStatements,
+                 ((float)NumStatementsRead/TotalNumStatements * 100));
+  if (TotalNumMacros)
+    std::fprintf(stderr, "  %u/%u macros read (%f%%)\n",
+                 NumMacrosRead, TotalNumMacros,
+                 ((float)NumMacrosRead/TotalNumMacros * 100));
+  if (TotalLexicalDeclContexts)
+    std::fprintf(stderr, "  %u/%u lexical declcontexts read (%f%%)\n",
+                 NumLexicalDeclContextsRead, TotalLexicalDeclContexts,
+                 ((float)NumLexicalDeclContextsRead/TotalLexicalDeclContexts
+                  * 100));
+  if (TotalVisibleDeclContexts)
+    std::fprintf(stderr, "  %u/%u visible declcontexts read (%f%%)\n",
+                 NumVisibleDeclContextsRead, TotalVisibleDeclContexts,
+                 ((float)NumVisibleDeclContextsRead/TotalVisibleDeclContexts
+                  * 100));
+  if (TotalSelectorsInMethodPool) {
+    std::fprintf(stderr, "  %u/%u method pool entries read (%f%%)\n",
+                 NumMethodPoolSelectorsRead, TotalSelectorsInMethodPool,
+                 ((float)NumMethodPoolSelectorsRead/TotalSelectorsInMethodPool
+                  * 100));
+    std::fprintf(stderr, "  %u method pool misses\n", NumMethodPoolMisses);
+  }
+  std::fprintf(stderr, "\n");
+}
+
+void PCHReader::InitializeSema(Sema &S) {
+  SemaObj = &S;
+  S.ExternalSource = this;
+
+  // Makes sure any declarations that were deserialized "too early"
+  // still get added to the identifier's declaration chains.
+  for (unsigned I = 0, N = PreloadedDecls.size(); I != N; ++I) {
+    SemaObj->TUScope->AddDecl(Action::DeclPtrTy::make(PreloadedDecls[I]));
+    SemaObj->IdResolver.AddDecl(PreloadedDecls[I]);
+  }
+  PreloadedDecls.clear();
+
+  // If there were any tentative definitions, deserialize them and add
+  // them to Sema's list of tentative definitions.
+  for (unsigned I = 0, N = TentativeDefinitions.size(); I != N; ++I) {
+    VarDecl *Var = cast<VarDecl>(GetDecl(TentativeDefinitions[I]));
+    SemaObj->TentativeDefinitions.push_back(Var);
+  }
+
+  // If there were any unused static functions, deserialize them and add to
+  // Sema's list of unused static functions.
+  for (unsigned I = 0, N = UnusedStaticFuncs.size(); I != N; ++I) {
+    FunctionDecl *FD = cast<FunctionDecl>(GetDecl(UnusedStaticFuncs[I]));
+    SemaObj->UnusedStaticFuncs.push_back(FD);
+  }
+
+  // If there were any locally-scoped external declarations,
+  // deserialize them and add them to Sema's table of locally-scoped
+  // external declarations.
+  for (unsigned I = 0, N = LocallyScopedExternalDecls.size(); I != N; ++I) {
+    NamedDecl *D = cast<NamedDecl>(GetDecl(LocallyScopedExternalDecls[I]));
+    SemaObj->LocallyScopedExternalDecls[D->getDeclName()] = D;
+  }
+
+  // If there were any ext_vector type declarations, deserialize them
+  // and add them to Sema's vector of such declarations.
+  for (unsigned I = 0, N = ExtVectorDecls.size(); I != N; ++I)
+    SemaObj->ExtVectorDecls.push_back(
+                               cast<TypedefDecl>(GetDecl(ExtVectorDecls[I])));
+}
+
+IdentifierInfo* PCHReader::get(const char *NameStart, const char *NameEnd) {
+  // Try to find this name within our on-disk hash table
+  PCHIdentifierLookupTable *IdTable
+    = (PCHIdentifierLookupTable *)IdentifierLookupTable;
+  std::pair<const char*, unsigned> Key(NameStart, NameEnd - NameStart);
+  PCHIdentifierLookupTable::iterator Pos = IdTable->find(Key);
+  if (Pos == IdTable->end())
+    return 0;
+
+  // Dereferencing the iterator has the effect of building the
+  // IdentifierInfo node and populating it with the various
+  // declarations it needs.
+  return *Pos;
+}
+
+std::pair<ObjCMethodList, ObjCMethodList>
+PCHReader::ReadMethodPool(Selector Sel) {
+  if (!MethodPoolLookupTable)
+    return std::pair<ObjCMethodList, ObjCMethodList>();
+
+  // Try to find this selector within our on-disk hash table.
+  PCHMethodPoolLookupTable *PoolTable
+    = (PCHMethodPoolLookupTable*)MethodPoolLookupTable;
+  PCHMethodPoolLookupTable::iterator Pos = PoolTable->find(Sel);
+  if (Pos == PoolTable->end()) {
+    ++NumMethodPoolMisses;
+    return std::pair<ObjCMethodList, ObjCMethodList>();;
+  }
+
+  ++NumMethodPoolSelectorsRead;
+  return *Pos;
+}
+
+void PCHReader::SetIdentifierInfo(unsigned ID, IdentifierInfo *II) {
+  assert(ID && "Non-zero identifier ID required");
+  assert(ID <= IdentifiersLoaded.size() && "identifier ID out of range");
+  IdentifiersLoaded[ID - 1] = II;
+}
+
+/// \brief Set the globally-visible declarations associated with the given
+/// identifier.
+///
+/// If the PCH reader is currently in a state where the given declaration IDs
+/// cannot safely be resolved, they are queued until it is safe to resolve
+/// them.
+///
+/// \param II an IdentifierInfo that refers to one or more globally-visible
+/// declarations.
+///
+/// \param DeclIDs the set of declaration IDs with the name @p II that are
+/// visible at global scope.
+///
+/// \param Nonrecursive should be true to indicate that the caller knows that
+/// this call is non-recursive, and therefore the globally-visible declarations
+/// will not be placed onto the pending queue.
+void
+PCHReader::SetGloballyVisibleDecls(IdentifierInfo *II,
+                              const llvm::SmallVectorImpl<uint32_t> &DeclIDs,
+                                   bool Nonrecursive) {
+  if (CurrentlyLoadingTypeOrDecl && !Nonrecursive) {
+    PendingIdentifierInfos.push_back(PendingIdentifierInfo());
+    PendingIdentifierInfo &PII = PendingIdentifierInfos.back();
+    PII.II = II;
+    for (unsigned I = 0, N = DeclIDs.size(); I != N; ++I)
+      PII.DeclIDs.push_back(DeclIDs[I]);
+    return;
+  }
+
+  for (unsigned I = 0, N = DeclIDs.size(); I != N; ++I) {
+    NamedDecl *D = cast<NamedDecl>(GetDecl(DeclIDs[I]));
+    if (SemaObj) {
+      // Introduce this declaration into the translation-unit scope
+      // and add it to the declaration chain for this identifier, so
+      // that (unqualified) name lookup will find it.
+      SemaObj->TUScope->AddDecl(Action::DeclPtrTy::make(D));
+      SemaObj->IdResolver.AddDeclToIdentifierChain(II, D);
+    } else {
+      // Queue this declaration so that it will be added to the
+      // translation unit scope and identifier's declaration chain
+      // once a Sema object is known.
+      PreloadedDecls.push_back(D);
+    }
+  }
+}
+
+IdentifierInfo *PCHReader::DecodeIdentifierInfo(unsigned ID) {
+  if (ID == 0)
+    return 0;
+
+  if (!IdentifierTableData || IdentifiersLoaded.empty()) {
+    Error("no identifier table in PCH file");
+    return 0;
+  }
+
+  assert(PP && "Forgot to set Preprocessor ?");
+  if (!IdentifiersLoaded[ID - 1]) {
+    uint32_t Offset = IdentifierOffsets[ID - 1];
+    const char *Str = IdentifierTableData + Offset;
+
+    // All of the strings in the PCH file are preceded by a 16-bit
+    // length. Extract that 16-bit length to avoid having to execute
+    // strlen().
+    // NOTE: 'StrLenPtr' is an 'unsigned char*' so that we load bytes as
+    //  unsigned integers.  This is important to avoid integer overflow when
+    //  we cast them to 'unsigned'.
+    const unsigned char *StrLenPtr = (const unsigned char*) Str - 2;
+    unsigned StrLen = (((unsigned) StrLenPtr[0])
+                       | (((unsigned) StrLenPtr[1]) << 8)) - 1;
+    IdentifiersLoaded[ID - 1]
+      = &PP->getIdentifierTable().get(Str, StrLen);
+  }
+
+  return IdentifiersLoaded[ID - 1];
+}
+
+void PCHReader::ReadSLocEntry(unsigned ID) {
+  ReadSLocEntryRecord(ID);
+}
+
+Selector PCHReader::DecodeSelector(unsigned ID) {
+  if (ID == 0)
+    return Selector();
+
+  if (!MethodPoolLookupTableData)
+    return Selector();
+
+  if (ID > TotalNumSelectors) {
+    Error("selector ID out of range in PCH file");
+    return Selector();
+  }
+
+  unsigned Index = ID - 1;
+  if (SelectorsLoaded[Index].getAsOpaquePtr() == 0) {
+    // Load this selector from the selector table.
+    // FIXME: endianness portability issues with SelectorOffsets table
+    PCHMethodPoolLookupTrait Trait(*this);
+    SelectorsLoaded[Index]
+      = Trait.ReadKey(MethodPoolLookupTableData + SelectorOffsets[Index], 0);
+  }
+
+  return SelectorsLoaded[Index];
+}
+
+Selector PCHReader::GetSelector(uint32_t ID) { 
+  return DecodeSelector(ID);
+}
+
+uint32_t PCHReader::GetNumKnownSelectors() {
+  return TotalNumSelectors + 1;
+}
+
+DeclarationName
+PCHReader::ReadDeclarationName(const RecordData &Record, unsigned &Idx) {
+  DeclarationName::NameKind Kind = (DeclarationName::NameKind)Record[Idx++];
+  switch (Kind) {
+  case DeclarationName::Identifier:
+    return DeclarationName(GetIdentifierInfo(Record, Idx));
+
+  case DeclarationName::ObjCZeroArgSelector:
+  case DeclarationName::ObjCOneArgSelector:
+  case DeclarationName::ObjCMultiArgSelector:
+    return DeclarationName(GetSelector(Record, Idx));
+
+  case DeclarationName::CXXConstructorName:
+    return Context->DeclarationNames.getCXXConstructorName(
+                          Context->getCanonicalType(GetType(Record[Idx++])));
+
+  case DeclarationName::CXXDestructorName:
+    return Context->DeclarationNames.getCXXDestructorName(
+                          Context->getCanonicalType(GetType(Record[Idx++])));
+
+  case DeclarationName::CXXConversionFunctionName:
+    return Context->DeclarationNames.getCXXConversionFunctionName(
+                          Context->getCanonicalType(GetType(Record[Idx++])));
+
+  case DeclarationName::CXXOperatorName:
+    return Context->DeclarationNames.getCXXOperatorName(
+                                       (OverloadedOperatorKind)Record[Idx++]);
+
+  case DeclarationName::CXXLiteralOperatorName:
+    return Context->DeclarationNames.getCXXLiteralOperatorName(
+                                       GetIdentifierInfo(Record, Idx));
+
+  case DeclarationName::CXXUsingDirective:
+    return DeclarationName::getUsingDirectiveName();
+  }
+
+  // Required to silence GCC warning
+  return DeclarationName();
+}
+
+/// \brief Read an integral value
+llvm::APInt PCHReader::ReadAPInt(const RecordData &Record, unsigned &Idx) {
+  unsigned BitWidth = Record[Idx++];
+  unsigned NumWords = llvm::APInt::getNumWords(BitWidth);
+  llvm::APInt Result(BitWidth, NumWords, &Record[Idx]);
+  Idx += NumWords;
+  return Result;
+}
+
+/// \brief Read a signed integral value
+llvm::APSInt PCHReader::ReadAPSInt(const RecordData &Record, unsigned &Idx) {
+  bool isUnsigned = Record[Idx++];
+  return llvm::APSInt(ReadAPInt(Record, Idx), isUnsigned);
+}
+
+/// \brief Read a floating-point value
+llvm::APFloat PCHReader::ReadAPFloat(const RecordData &Record, unsigned &Idx) {
+  return llvm::APFloat(ReadAPInt(Record, Idx));
+}
+
+// \brief Read a string
+std::string PCHReader::ReadString(const RecordData &Record, unsigned &Idx) {
+  unsigned Len = Record[Idx++];
+  std::string Result(Record.data() + Idx, Record.data() + Idx + Len);
+  Idx += Len;
+  return Result;
+}
+
+DiagnosticBuilder PCHReader::Diag(unsigned DiagID) {
+  return Diag(SourceLocation(), DiagID);
+}
+
+DiagnosticBuilder PCHReader::Diag(SourceLocation Loc, unsigned DiagID) {
+  return Diags.Report(FullSourceLoc(Loc, SourceMgr), DiagID);
+}
+
+/// \brief Retrieve the identifier table associated with the
+/// preprocessor.
+IdentifierTable &PCHReader::getIdentifierTable() {
+  assert(PP && "Forgot to set Preprocessor ?");
+  return PP->getIdentifierTable();
+}
+
+/// \brief Record that the given ID maps to the given switch-case
+/// statement.
+void PCHReader::RecordSwitchCaseID(SwitchCase *SC, unsigned ID) {
+  assert(SwitchCaseStmts[ID] == 0 && "Already have a SwitchCase with this ID");
+  SwitchCaseStmts[ID] = SC;
+}
+
+/// \brief Retrieve the switch-case statement with the given ID.
+SwitchCase *PCHReader::getSwitchCaseWithID(unsigned ID) {
+  assert(SwitchCaseStmts[ID] != 0 && "No SwitchCase with this ID");
+  return SwitchCaseStmts[ID];
+}
+
+/// \brief Record that the given label statement has been
+/// deserialized and has the given ID.
+void PCHReader::RecordLabelStmt(LabelStmt *S, unsigned ID) {
+  assert(LabelStmts.find(ID) == LabelStmts.end() &&
+         "Deserialized label twice");
+  LabelStmts[ID] = S;
+
+  // If we've already seen any goto statements that point to this
+  // label, resolve them now.
+  typedef std::multimap<unsigned, GotoStmt *>::iterator GotoIter;
+  std::pair<GotoIter, GotoIter> Gotos = UnresolvedGotoStmts.equal_range(ID);
+  for (GotoIter Goto = Gotos.first; Goto != Gotos.second; ++Goto)
+    Goto->second->setLabel(S);
+  UnresolvedGotoStmts.erase(Gotos.first, Gotos.second);
+
+  // If we've already seen any address-label statements that point to
+  // this label, resolve them now.
+  typedef std::multimap<unsigned, AddrLabelExpr *>::iterator AddrLabelIter;
+  std::pair<AddrLabelIter, AddrLabelIter> AddrLabels
+    = UnresolvedAddrLabelExprs.equal_range(ID);
+  for (AddrLabelIter AddrLabel = AddrLabels.first;
+       AddrLabel != AddrLabels.second; ++AddrLabel)
+    AddrLabel->second->setLabel(S);
+  UnresolvedAddrLabelExprs.erase(AddrLabels.first, AddrLabels.second);
+}
+
+/// \brief Set the label of the given statement to the label
+/// identified by ID.
+///
+/// Depending on the order in which the label and other statements
+/// referencing that label occur, this operation may complete
+/// immediately (updating the statement) or it may queue the
+/// statement to be back-patched later.
+void PCHReader::SetLabelOf(GotoStmt *S, unsigned ID) {
+  std::map<unsigned, LabelStmt *>::iterator Label = LabelStmts.find(ID);
+  if (Label != LabelStmts.end()) {
+    // We've already seen this label, so set the label of the goto and
+    // we're done.
+    S->setLabel(Label->second);
+  } else {
+    // We haven't seen this label yet, so add this goto to the set of
+    // unresolved goto statements.
+    UnresolvedGotoStmts.insert(std::make_pair(ID, S));
+  }
+}
+
+/// \brief Set the label of the given expression to the label
+/// identified by ID.
+///
+/// Depending on the order in which the label and other statements
+/// referencing that label occur, this operation may complete
+/// immediately (updating the statement) or it may queue the
+/// statement to be back-patched later.
+void PCHReader::SetLabelOf(AddrLabelExpr *S, unsigned ID) {
+  std::map<unsigned, LabelStmt *>::iterator Label = LabelStmts.find(ID);
+  if (Label != LabelStmts.end()) {
+    // We've already seen this label, so set the label of the
+    // label-address expression and we're done.
+    S->setLabel(Label->second);
+  } else {
+    // We haven't seen this label yet, so add this label-address
+    // expression to the set of unresolved label-address expressions.
+    UnresolvedAddrLabelExprs.insert(std::make_pair(ID, S));
+  }
+}
+
+
+PCHReader::LoadingTypeOrDecl::LoadingTypeOrDecl(PCHReader &Reader)
+  : Reader(Reader), Parent(Reader.CurrentlyLoadingTypeOrDecl) {
+  Reader.CurrentlyLoadingTypeOrDecl = this;
+}
+
+PCHReader::LoadingTypeOrDecl::~LoadingTypeOrDecl() {
+  if (!Parent) {
+    // If any identifiers with corresponding top-level declarations have
+    // been loaded, load those declarations now.
+    while (!Reader.PendingIdentifierInfos.empty()) {
+      Reader.SetGloballyVisibleDecls(Reader.PendingIdentifierInfos.front().II,
+                                 Reader.PendingIdentifierInfos.front().DeclIDs,
+                                     true);
+      Reader.PendingIdentifierInfos.pop_front();
+    }
+  }
+
+  Reader.CurrentlyLoadingTypeOrDecl = Parent;
+}
diff --git a/lib/Frontend/PCHReaderDecl.cpp b/lib/Frontend/PCHReaderDecl.cpp
new file mode 100644
index 0000000..53647ba
--- /dev/null
+++ b/lib/Frontend/PCHReaderDecl.cpp
@@ -0,0 +1,808 @@
+//===--- PCHReaderDecl.cpp - Decl Deserialization ---------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the PCHReader::ReadDeclRecord method, which is the
+// entrypoint for loading a decl.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/PCHReader.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclVisitor.h"
+#include "clang/AST/DeclGroup.h"
+#include "clang/AST/Expr.h"
+using namespace clang;
+
+
+//===----------------------------------------------------------------------===//
+// Declaration deserialization
+//===----------------------------------------------------------------------===//
+
+namespace {
+  class PCHDeclReader : public DeclVisitor<PCHDeclReader, void> {
+    PCHReader &Reader;
+    const PCHReader::RecordData &Record;
+    unsigned &Idx;
+
+  public:
+    PCHDeclReader(PCHReader &Reader, const PCHReader::RecordData &Record,
+                  unsigned &Idx)
+      : Reader(Reader), Record(Record), Idx(Idx) { }
+
+    void VisitDecl(Decl *D);
+    void VisitTranslationUnitDecl(TranslationUnitDecl *TU);
+    void VisitNamedDecl(NamedDecl *ND);
+    void VisitNamespaceDecl(NamespaceDecl *D);
+    void VisitTypeDecl(TypeDecl *TD);
+    void VisitTypedefDecl(TypedefDecl *TD);
+    void VisitTagDecl(TagDecl *TD);
+    void VisitEnumDecl(EnumDecl *ED);
+    void VisitRecordDecl(RecordDecl *RD);
+    void VisitValueDecl(ValueDecl *VD);
+    void VisitEnumConstantDecl(EnumConstantDecl *ECD);
+    void VisitDeclaratorDecl(DeclaratorDecl *DD);
+    void VisitFunctionDecl(FunctionDecl *FD);
+    void VisitFieldDecl(FieldDecl *FD);
+    void VisitVarDecl(VarDecl *VD);
+    void VisitImplicitParamDecl(ImplicitParamDecl *PD);
+    void VisitParmVarDecl(ParmVarDecl *PD);
+    void VisitFileScopeAsmDecl(FileScopeAsmDecl *AD);
+    void VisitBlockDecl(BlockDecl *BD);
+    std::pair<uint64_t, uint64_t> VisitDeclContext(DeclContext *DC);
+    void VisitObjCMethodDecl(ObjCMethodDecl *D);
+    void VisitObjCContainerDecl(ObjCContainerDecl *D);
+    void VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
+    void VisitObjCIvarDecl(ObjCIvarDecl *D);
+    void VisitObjCProtocolDecl(ObjCProtocolDecl *D);
+    void VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl *D);
+    void VisitObjCClassDecl(ObjCClassDecl *D);
+    void VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D);
+    void VisitObjCCategoryDecl(ObjCCategoryDecl *D);
+    void VisitObjCImplDecl(ObjCImplDecl *D);
+    void VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D);
+    void VisitObjCImplementationDecl(ObjCImplementationDecl *D);
+    void VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *D);
+    void VisitObjCPropertyDecl(ObjCPropertyDecl *D);
+    void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D);
+  };
+}
+
+void PCHDeclReader::VisitDecl(Decl *D) {
+  D->setDeclContext(cast_or_null<DeclContext>(Reader.GetDecl(Record[Idx++])));
+  D->setLexicalDeclContext(
+                     cast_or_null<DeclContext>(Reader.GetDecl(Record[Idx++])));
+  D->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  D->setInvalidDecl(Record[Idx++]);
+  if (Record[Idx++])
+    D->addAttr(Reader.ReadAttributes());
+  D->setImplicit(Record[Idx++]);
+  D->setUsed(Record[Idx++]);
+  D->setAccess((AccessSpecifier)Record[Idx++]);
+  D->setPCHLevel(Record[Idx++] + 1);
+}
+
+void PCHDeclReader::VisitTranslationUnitDecl(TranslationUnitDecl *TU) {
+  VisitDecl(TU);
+}
+
+void PCHDeclReader::VisitNamedDecl(NamedDecl *ND) {
+  VisitDecl(ND);
+  ND->setDeclName(Reader.ReadDeclarationName(Record, Idx));
+}
+
+void PCHDeclReader::VisitNamespaceDecl(NamespaceDecl *D) {
+  VisitNamedDecl(D);
+  D->setLBracLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  D->setRBracLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  D->setNextNamespace(
+                    cast_or_null<NamespaceDecl>(Reader.GetDecl(Record[Idx++])));
+  D->setOriginalNamespace(
+                    cast_or_null<NamespaceDecl>(Reader.GetDecl(Record[Idx++])));
+  D->setAnonymousNamespace(
+                    cast_or_null<NamespaceDecl>(Reader.GetDecl(Record[Idx++])));
+}
+
+void PCHDeclReader::VisitTypeDecl(TypeDecl *TD) {
+  VisitNamedDecl(TD);
+  TD->setTypeForDecl(Reader.GetType(Record[Idx++]).getTypePtr());
+}
+
+void PCHDeclReader::VisitTypedefDecl(TypedefDecl *TD) {
+  // Note that we cannot use VisitTypeDecl here, because we need to
+  // set the underlying type of the typedef *before* we try to read
+  // the type associated with the TypedefDecl.
+  VisitNamedDecl(TD);
+  uint64_t TypeData = Record[Idx++];
+  TD->setTypeSourceInfo(Reader.GetTypeSourceInfo(Record, Idx));
+  TD->setTypeForDecl(Reader.GetType(TypeData).getTypePtr());
+}
+
+void PCHDeclReader::VisitTagDecl(TagDecl *TD) {
+  VisitTypeDecl(TD);
+  TD->setPreviousDeclaration(
+                        cast_or_null<TagDecl>(Reader.GetDecl(Record[Idx++])));
+  TD->setTagKind((TagDecl::TagKind)Record[Idx++]);
+  TD->setDefinition(Record[Idx++]);
+  TD->setEmbeddedInDeclarator(Record[Idx++]);
+  TD->setRBraceLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  TD->setTagKeywordLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  // FIXME: maybe read optional qualifier and its range.
+  TD->setTypedefForAnonDecl(
+                    cast_or_null<TypedefDecl>(Reader.GetDecl(Record[Idx++])));
+}
+
+void PCHDeclReader::VisitEnumDecl(EnumDecl *ED) {
+  VisitTagDecl(ED);
+  ED->setIntegerType(Reader.GetType(Record[Idx++]));
+  ED->setPromotionType(Reader.GetType(Record[Idx++]));
+  // FIXME: C++ InstantiatedFrom
+}
+
+void PCHDeclReader::VisitRecordDecl(RecordDecl *RD) {
+  VisitTagDecl(RD);
+  RD->setHasFlexibleArrayMember(Record[Idx++]);
+  RD->setAnonymousStructOrUnion(Record[Idx++]);
+  RD->setHasObjectMember(Record[Idx++]);
+}
+
+void PCHDeclReader::VisitValueDecl(ValueDecl *VD) {
+  VisitNamedDecl(VD);
+  VD->setType(Reader.GetType(Record[Idx++]));
+}
+
+void PCHDeclReader::VisitEnumConstantDecl(EnumConstantDecl *ECD) {
+  VisitValueDecl(ECD);
+  if (Record[Idx++])
+    ECD->setInitExpr(Reader.ReadDeclExpr());
+  ECD->setInitVal(Reader.ReadAPSInt(Record, Idx));
+}
+
+void PCHDeclReader::VisitDeclaratorDecl(DeclaratorDecl *DD) {
+  VisitValueDecl(DD);
+  TypeSourceInfo *TInfo = Reader.GetTypeSourceInfo(Record, Idx);
+  if (TInfo)
+    DD->setTypeSourceInfo(TInfo);
+  // FIXME: read optional qualifier and its range.
+}
+
+void PCHDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
+  VisitDeclaratorDecl(FD);
+  if (Record[Idx++])
+    FD->setLazyBody(Reader.getDeclsCursor().GetCurrentBitNo());
+  FD->setPreviousDeclaration(
+                   cast_or_null<FunctionDecl>(Reader.GetDecl(Record[Idx++])));
+  FD->setStorageClass((FunctionDecl::StorageClass)Record[Idx++]);
+  FD->setStorageClassAsWritten((FunctionDecl::StorageClass)Record[Idx++]);
+  FD->setInlineSpecified(Record[Idx++]);
+  FD->setVirtualAsWritten(Record[Idx++]);
+  FD->setPure(Record[Idx++]);
+  FD->setHasInheritedPrototype(Record[Idx++]);
+  FD->setHasWrittenPrototype(Record[Idx++]);
+  FD->setDeleted(Record[Idx++]);
+  FD->setTrivial(Record[Idx++]);
+  FD->setCopyAssignment(Record[Idx++]);
+  FD->setHasImplicitReturnZero(Record[Idx++]);
+  FD->setLocEnd(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  // FIXME: C++ TemplateOrInstantiation
+  unsigned NumParams = Record[Idx++];
+  llvm::SmallVector<ParmVarDecl *, 16> Params;
+  Params.reserve(NumParams);
+  for (unsigned I = 0; I != NumParams; ++I)
+    Params.push_back(cast<ParmVarDecl>(Reader.GetDecl(Record[Idx++])));
+  FD->setParams(Params.data(), NumParams);
+
+  // FIXME: order this properly w.r.t. friendness
+  // FIXME: this same thing needs to happen for function templates
+  if (FD->isOverloadedOperator() && !FD->getDeclContext()->isRecord())
+    FD->setNonMemberOperator();
+}
+
+void PCHDeclReader::VisitObjCMethodDecl(ObjCMethodDecl *MD) {
+  VisitNamedDecl(MD);
+  if (Record[Idx++]) {
+    // In practice, this won't be executed (since method definitions
+    // don't occur in header files).
+    MD->setBody(Reader.ReadDeclStmt());
+    MD->setSelfDecl(cast<ImplicitParamDecl>(Reader.GetDecl(Record[Idx++])));
+    MD->setCmdDecl(cast<ImplicitParamDecl>(Reader.GetDecl(Record[Idx++])));
+  }
+  MD->setInstanceMethod(Record[Idx++]);
+  MD->setVariadic(Record[Idx++]);
+  MD->setSynthesized(Record[Idx++]);
+  MD->setDeclImplementation((ObjCMethodDecl::ImplementationControl)Record[Idx++]);
+  MD->setObjCDeclQualifier((Decl::ObjCDeclQualifier)Record[Idx++]);
+  MD->setNumSelectorArgs(unsigned(Record[Idx++]));
+  MD->setResultType(Reader.GetType(Record[Idx++]));
+  MD->setResultTypeSourceInfo(Reader.GetTypeSourceInfo(Record, Idx));
+  MD->setEndLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  unsigned NumParams = Record[Idx++];
+  llvm::SmallVector<ParmVarDecl *, 16> Params;
+  Params.reserve(NumParams);
+  for (unsigned I = 0; I != NumParams; ++I)
+    Params.push_back(cast<ParmVarDecl>(Reader.GetDecl(Record[Idx++])));
+  MD->setMethodParams(*Reader.getContext(), Params.data(), NumParams,
+                      NumParams);
+}
+
+void PCHDeclReader::VisitObjCContainerDecl(ObjCContainerDecl *CD) {
+  VisitNamedDecl(CD);
+  SourceLocation A = SourceLocation::getFromRawEncoding(Record[Idx++]);
+  SourceLocation B = SourceLocation::getFromRawEncoding(Record[Idx++]);
+  CD->setAtEndRange(SourceRange(A, B));
+}
+
+void PCHDeclReader::VisitObjCInterfaceDecl(ObjCInterfaceDecl *ID) {
+  VisitObjCContainerDecl(ID);
+  ID->setTypeForDecl(Reader.GetType(Record[Idx++]).getTypePtr());
+  ID->setSuperClass(cast_or_null<ObjCInterfaceDecl>
+                       (Reader.GetDecl(Record[Idx++])));
+  unsigned NumProtocols = Record[Idx++];
+  llvm::SmallVector<ObjCProtocolDecl *, 16> Protocols;
+  Protocols.reserve(NumProtocols);
+  for (unsigned I = 0; I != NumProtocols; ++I)
+    Protocols.push_back(cast<ObjCProtocolDecl>(Reader.GetDecl(Record[Idx++])));
+  llvm::SmallVector<SourceLocation, 16> ProtoLocs;
+  ProtoLocs.reserve(NumProtocols);
+  for (unsigned I = 0; I != NumProtocols; ++I)
+    ProtoLocs.push_back(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  ID->setProtocolList(Protocols.data(), NumProtocols, ProtoLocs.data(),
+                      *Reader.getContext());
+  unsigned NumIvars = Record[Idx++];
+  llvm::SmallVector<ObjCIvarDecl *, 16> IVars;
+  IVars.reserve(NumIvars);
+  for (unsigned I = 0; I != NumIvars; ++I)
+    IVars.push_back(cast<ObjCIvarDecl>(Reader.GetDecl(Record[Idx++])));
+  ID->setCategoryList(
+               cast_or_null<ObjCCategoryDecl>(Reader.GetDecl(Record[Idx++])));
+  ID->setForwardDecl(Record[Idx++]);
+  ID->setImplicitInterfaceDecl(Record[Idx++]);
+  ID->setClassLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  ID->setSuperClassLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  ID->setLocEnd(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+
+void PCHDeclReader::VisitObjCIvarDecl(ObjCIvarDecl *IVD) {
+  VisitFieldDecl(IVD);
+  IVD->setAccessControl((ObjCIvarDecl::AccessControl)Record[Idx++]);
+}
+
+void PCHDeclReader::VisitObjCProtocolDecl(ObjCProtocolDecl *PD) {
+  VisitObjCContainerDecl(PD);
+  PD->setForwardDecl(Record[Idx++]);
+  PD->setLocEnd(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  unsigned NumProtoRefs = Record[Idx++];
+  llvm::SmallVector<ObjCProtocolDecl *, 16> ProtoRefs;
+  ProtoRefs.reserve(NumProtoRefs);
+  for (unsigned I = 0; I != NumProtoRefs; ++I)
+    ProtoRefs.push_back(cast<ObjCProtocolDecl>(Reader.GetDecl(Record[Idx++])));
+  llvm::SmallVector<SourceLocation, 16> ProtoLocs;
+  ProtoLocs.reserve(NumProtoRefs);
+  for (unsigned I = 0; I != NumProtoRefs; ++I)
+    ProtoLocs.push_back(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  PD->setProtocolList(ProtoRefs.data(), NumProtoRefs, ProtoLocs.data(),
+                      *Reader.getContext());
+}
+
+void PCHDeclReader::VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl *FD) {
+  VisitFieldDecl(FD);
+}
+
+void PCHDeclReader::VisitObjCClassDecl(ObjCClassDecl *CD) {
+  VisitDecl(CD);
+  unsigned NumClassRefs = Record[Idx++];
+  llvm::SmallVector<ObjCInterfaceDecl *, 16> ClassRefs;
+  ClassRefs.reserve(NumClassRefs);
+  for (unsigned I = 0; I != NumClassRefs; ++I)
+    ClassRefs.push_back(cast<ObjCInterfaceDecl>(Reader.GetDecl(Record[Idx++])));
+  llvm::SmallVector<SourceLocation, 16> SLocs;
+  SLocs.reserve(NumClassRefs);
+  for (unsigned I = 0; I != NumClassRefs; ++I)
+    SLocs.push_back(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  CD->setClassList(*Reader.getContext(), ClassRefs.data(), SLocs.data(),
+                   NumClassRefs);
+}
+
+void PCHDeclReader::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *FPD) {
+  VisitDecl(FPD);
+  unsigned NumProtoRefs = Record[Idx++];
+  llvm::SmallVector<ObjCProtocolDecl *, 16> ProtoRefs;
+  ProtoRefs.reserve(NumProtoRefs);
+  for (unsigned I = 0; I != NumProtoRefs; ++I)
+    ProtoRefs.push_back(cast<ObjCProtocolDecl>(Reader.GetDecl(Record[Idx++])));
+  llvm::SmallVector<SourceLocation, 16> ProtoLocs;
+  ProtoLocs.reserve(NumProtoRefs);
+  for (unsigned I = 0; I != NumProtoRefs; ++I)
+    ProtoLocs.push_back(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  FPD->setProtocolList(ProtoRefs.data(), NumProtoRefs, ProtoLocs.data(),
+                       *Reader.getContext());
+}
+
+void PCHDeclReader::VisitObjCCategoryDecl(ObjCCategoryDecl *CD) {
+  VisitObjCContainerDecl(CD);
+  CD->setClassInterface(cast<ObjCInterfaceDecl>(Reader.GetDecl(Record[Idx++])));
+  unsigned NumProtoRefs = Record[Idx++];
+  llvm::SmallVector<ObjCProtocolDecl *, 16> ProtoRefs;
+  ProtoRefs.reserve(NumProtoRefs);
+  for (unsigned I = 0; I != NumProtoRefs; ++I)
+    ProtoRefs.push_back(cast<ObjCProtocolDecl>(Reader.GetDecl(Record[Idx++])));
+  llvm::SmallVector<SourceLocation, 16> ProtoLocs;
+  ProtoLocs.reserve(NumProtoRefs);
+  for (unsigned I = 0; I != NumProtoRefs; ++I)
+    ProtoLocs.push_back(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  CD->setProtocolList(ProtoRefs.data(), NumProtoRefs, ProtoLocs.data(),
+                      *Reader.getContext());
+  CD->setNextClassCategory(cast_or_null<ObjCCategoryDecl>(Reader.GetDecl(Record[Idx++])));
+  CD->setAtLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  CD->setCategoryNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+
+void PCHDeclReader::VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *CAD) {
+  VisitNamedDecl(CAD);
+  CAD->setClassInterface(cast<ObjCInterfaceDecl>(Reader.GetDecl(Record[Idx++])));
+}
+
+void PCHDeclReader::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
+  VisitNamedDecl(D);
+  D->setAtLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  D->setType(Reader.GetType(Record[Idx++]));
+  // FIXME: stable encoding
+  D->setPropertyAttributes(
+                      (ObjCPropertyDecl::PropertyAttributeKind)Record[Idx++]);
+  // FIXME: stable encoding
+  D->setPropertyImplementation(
+                            (ObjCPropertyDecl::PropertyControl)Record[Idx++]);
+  D->setGetterName(Reader.ReadDeclarationName(Record, Idx).getObjCSelector());
+  D->setSetterName(Reader.ReadDeclarationName(Record, Idx).getObjCSelector());
+  D->setGetterMethodDecl(
+                 cast_or_null<ObjCMethodDecl>(Reader.GetDecl(Record[Idx++])));
+  D->setSetterMethodDecl(
+                 cast_or_null<ObjCMethodDecl>(Reader.GetDecl(Record[Idx++])));
+  D->setPropertyIvarDecl(
+                   cast_or_null<ObjCIvarDecl>(Reader.GetDecl(Record[Idx++])));
+}
+
+void PCHDeclReader::VisitObjCImplDecl(ObjCImplDecl *D) {
+  VisitObjCContainerDecl(D);
+  D->setClassInterface(
+              cast_or_null<ObjCInterfaceDecl>(Reader.GetDecl(Record[Idx++])));
+}
+
+void PCHDeclReader::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
+  VisitObjCImplDecl(D);
+  D->setIdentifier(Reader.GetIdentifierInfo(Record, Idx));
+}
+
+void PCHDeclReader::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
+  VisitObjCImplDecl(D);
+  D->setSuperClass(
+              cast_or_null<ObjCInterfaceDecl>(Reader.GetDecl(Record[Idx++])));
+}
+
+
+void PCHDeclReader::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
+  VisitDecl(D);
+  D->setAtLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  D->setPropertyDecl(
+               cast_or_null<ObjCPropertyDecl>(Reader.GetDecl(Record[Idx++])));
+  D->setPropertyIvarDecl(
+                   cast_or_null<ObjCIvarDecl>(Reader.GetDecl(Record[Idx++])));
+}
+
+void PCHDeclReader::VisitFieldDecl(FieldDecl *FD) {
+  VisitDeclaratorDecl(FD);
+  FD->setMutable(Record[Idx++]);
+  if (Record[Idx++])
+    FD->setBitWidth(Reader.ReadDeclExpr());
+}
+
+void PCHDeclReader::VisitVarDecl(VarDecl *VD) {
+  VisitDeclaratorDecl(VD);
+  VD->setStorageClass((VarDecl::StorageClass)Record[Idx++]);
+  VD->setStorageClassAsWritten((VarDecl::StorageClass)Record[Idx++]);
+  VD->setThreadSpecified(Record[Idx++]);
+  VD->setCXXDirectInitializer(Record[Idx++]);
+  VD->setDeclaredInCondition(Record[Idx++]);
+  VD->setPreviousDeclaration(
+                         cast_or_null<VarDecl>(Reader.GetDecl(Record[Idx++])));
+  if (Record[Idx++])
+    VD->setInit(Reader.ReadDeclExpr());
+}
+
+void PCHDeclReader::VisitImplicitParamDecl(ImplicitParamDecl *PD) {
+  VisitVarDecl(PD);
+}
+
+void PCHDeclReader::VisitParmVarDecl(ParmVarDecl *PD) {
+  VisitVarDecl(PD);
+  PD->setObjCDeclQualifier((Decl::ObjCDeclQualifier)Record[Idx++]);
+  PD->setHasInheritedDefaultArg(Record[Idx++]);
+}
+
+void PCHDeclReader::VisitFileScopeAsmDecl(FileScopeAsmDecl *AD) {
+  VisitDecl(AD);
+  AD->setAsmString(cast<StringLiteral>(Reader.ReadDeclExpr()));
+}
+
+void PCHDeclReader::VisitBlockDecl(BlockDecl *BD) {
+  VisitDecl(BD);
+  BD->setBody(cast_or_null<CompoundStmt>(Reader.ReadDeclStmt()));
+  unsigned NumParams = Record[Idx++];
+  llvm::SmallVector<ParmVarDecl *, 16> Params;
+  Params.reserve(NumParams);
+  for (unsigned I = 0; I != NumParams; ++I)
+    Params.push_back(cast<ParmVarDecl>(Reader.GetDecl(Record[Idx++])));
+  BD->setParams(Params.data(), NumParams);
+}
+
+std::pair<uint64_t, uint64_t>
+PCHDeclReader::VisitDeclContext(DeclContext *DC) {
+  uint64_t LexicalOffset = Record[Idx++];
+  uint64_t VisibleOffset = Record[Idx++];
+  return std::make_pair(LexicalOffset, VisibleOffset);
+}
+
+//===----------------------------------------------------------------------===//
+// Attribute Reading
+//===----------------------------------------------------------------------===//
+
+/// \brief Reads attributes from the current stream position.
+Attr *PCHReader::ReadAttributes() {
+  unsigned Code = DeclsCursor.ReadCode();
+  assert(Code == llvm::bitc::UNABBREV_RECORD &&
+         "Expected unabbreviated record"); (void)Code;
+
+  RecordData Record;
+  unsigned Idx = 0;
+  unsigned RecCode = DeclsCursor.ReadRecord(Code, Record);
+  assert(RecCode == pch::DECL_ATTR && "Expected attribute record");
+  (void)RecCode;
+
+#define SIMPLE_ATTR(Name)                       \
+ case Attr::Name:                               \
+   New = ::new (*Context) Name##Attr();         \
+   break
+
+#define STRING_ATTR(Name)                                       \
+ case Attr::Name:                                               \
+   New = ::new (*Context) Name##Attr(*Context, ReadString(Record, Idx));  \
+   break
+
+#define UNSIGNED_ATTR(Name)                             \
+ case Attr::Name:                                       \
+   New = ::new (*Context) Name##Attr(Record[Idx++]);    \
+   break
+
+  Attr *Attrs = 0;
+  while (Idx < Record.size()) {
+    Attr *New = 0;
+    Attr::Kind Kind = (Attr::Kind)Record[Idx++];
+    bool IsInherited = Record[Idx++];
+
+    switch (Kind) {
+    default:
+      assert(0 && "Unknown attribute!");
+      break;
+    STRING_ATTR(Alias);
+    UNSIGNED_ATTR(Aligned);
+    SIMPLE_ATTR(AlwaysInline);
+    SIMPLE_ATTR(AnalyzerNoReturn);
+    STRING_ATTR(Annotate);
+    STRING_ATTR(AsmLabel);
+    SIMPLE_ATTR(BaseCheck);
+
+    case Attr::Blocks:
+      New = ::new (*Context) BlocksAttr(
+                                  (BlocksAttr::BlocksAttrTypes)Record[Idx++]);
+      break;
+
+    SIMPLE_ATTR(CDecl);
+
+    case Attr::Cleanup:
+      New = ::new (*Context) CleanupAttr(
+                                  cast<FunctionDecl>(GetDecl(Record[Idx++])));
+      break;
+
+    SIMPLE_ATTR(Const);
+    UNSIGNED_ATTR(Constructor);
+    SIMPLE_ATTR(DLLExport);
+    SIMPLE_ATTR(DLLImport);
+    SIMPLE_ATTR(Deprecated);
+    UNSIGNED_ATTR(Destructor);
+    SIMPLE_ATTR(FastCall);
+    SIMPLE_ATTR(Final);
+
+    case Attr::Format: {
+      std::string Type = ReadString(Record, Idx);
+      unsigned FormatIdx = Record[Idx++];
+      unsigned FirstArg = Record[Idx++];
+      New = ::new (*Context) FormatAttr(*Context, Type, FormatIdx, FirstArg);
+      break;
+    }
+
+    case Attr::FormatArg: {
+      unsigned FormatIdx = Record[Idx++];
+      New = ::new (*Context) FormatArgAttr(FormatIdx);
+      break;
+    }
+
+    case Attr::Sentinel: {
+      int sentinel = Record[Idx++];
+      int nullPos = Record[Idx++];
+      New = ::new (*Context) SentinelAttr(sentinel, nullPos);
+      break;
+    }
+
+    SIMPLE_ATTR(GNUInline);
+    SIMPLE_ATTR(Hiding);
+
+    case Attr::IBActionKind:
+      New = ::new (*Context) IBActionAttr();
+      break;
+
+    case Attr::IBOutletKind:
+      New = ::new (*Context) IBOutletAttr();
+      break;
+
+    SIMPLE_ATTR(Malloc);
+    SIMPLE_ATTR(NoDebug);
+    SIMPLE_ATTR(NoInline);
+    SIMPLE_ATTR(NoReturn);
+    SIMPLE_ATTR(NoThrow);
+
+    case Attr::NonNull: {
+      unsigned Size = Record[Idx++];
+      llvm::SmallVector<unsigned, 16> ArgNums;
+      ArgNums.insert(ArgNums.end(), &Record[Idx], &Record[Idx] + Size);
+      Idx += Size;
+      New = ::new (*Context) NonNullAttr(*Context, ArgNums.data(), Size);
+      break;
+    }
+
+    case Attr::ReqdWorkGroupSize: {
+      unsigned X = Record[Idx++];
+      unsigned Y = Record[Idx++];
+      unsigned Z = Record[Idx++];
+      New = ::new (*Context) ReqdWorkGroupSizeAttr(X, Y, Z);
+      break;
+    }
+
+    SIMPLE_ATTR(ObjCException);
+    SIMPLE_ATTR(ObjCNSObject);
+    SIMPLE_ATTR(CFReturnsNotRetained);
+    SIMPLE_ATTR(CFReturnsRetained);
+    SIMPLE_ATTR(NSReturnsNotRetained);
+    SIMPLE_ATTR(NSReturnsRetained);
+    SIMPLE_ATTR(Overloadable);
+    SIMPLE_ATTR(Override);
+    SIMPLE_ATTR(Packed);
+    UNSIGNED_ATTR(PragmaPack);
+    SIMPLE_ATTR(Pure);
+    UNSIGNED_ATTR(Regparm);
+    STRING_ATTR(Section);
+    SIMPLE_ATTR(StdCall);
+    SIMPLE_ATTR(TransparentUnion);
+    SIMPLE_ATTR(Unavailable);
+    SIMPLE_ATTR(Unused);
+    SIMPLE_ATTR(Used);
+
+    case Attr::Visibility:
+      New = ::new (*Context) VisibilityAttr(
+                              (VisibilityAttr::VisibilityTypes)Record[Idx++]);
+      break;
+
+    SIMPLE_ATTR(WarnUnusedResult);
+    SIMPLE_ATTR(Weak);
+    SIMPLE_ATTR(WeakRef);
+    SIMPLE_ATTR(WeakImport);
+    }
+
+    assert(New && "Unable to decode attribute?");
+    New->setInherited(IsInherited);
+    New->setNext(Attrs);
+    Attrs = New;
+  }
+#undef UNSIGNED_ATTR
+#undef STRING_ATTR
+#undef SIMPLE_ATTR
+
+  // The list of attributes was built backwards. Reverse the list
+  // before returning it.
+  Attr *PrevAttr = 0, *NextAttr = 0;
+  while (Attrs) {
+    NextAttr = Attrs->getNext();
+    Attrs->setNext(PrevAttr);
+    PrevAttr = Attrs;
+    Attrs = NextAttr;
+  }
+
+  return PrevAttr;
+}
+
+//===----------------------------------------------------------------------===//
+// PCHReader Implementation
+//===----------------------------------------------------------------------===//
+
+/// \brief Note that we have loaded the declaration with the given
+/// Index.
+///
+/// This routine notes that this declaration has already been loaded,
+/// so that future GetDecl calls will return this declaration rather
+/// than trying to load a new declaration.
+inline void PCHReader::LoadedDecl(unsigned Index, Decl *D) {
+  assert(!DeclsLoaded[Index] && "Decl loaded twice?");
+  DeclsLoaded[Index] = D;
+}
+
+
+/// \brief Determine whether the consumer will be interested in seeing
+/// this declaration (via HandleTopLevelDecl).
+///
+/// This routine should return true for anything that might affect
+/// code generation, e.g., inline function definitions, Objective-C
+/// declarations with metadata, etc.
+static bool isConsumerInterestedIn(Decl *D) {
+  if (isa<FileScopeAsmDecl>(D))
+    return true;
+  if (VarDecl *Var = dyn_cast<VarDecl>(D))
+    return Var->isFileVarDecl() && Var->getInit();
+  if (FunctionDecl *Func = dyn_cast<FunctionDecl>(D))
+    return Func->isThisDeclarationADefinition();
+  return isa<ObjCProtocolDecl>(D);
+}
+
+/// \brief Read the declaration at the given offset from the PCH file.
+Decl *PCHReader::ReadDeclRecord(uint64_t Offset, unsigned Index) {
+  // Keep track of where we are in the stream, then jump back there
+  // after reading this declaration.
+  SavedStreamPosition SavedPosition(DeclsCursor);
+
+  // Note that we are loading a declaration record.
+  LoadingTypeOrDecl Loading(*this);
+
+  DeclsCursor.JumpToBit(Offset);
+  RecordData Record;
+  unsigned Code = DeclsCursor.ReadCode();
+  unsigned Idx = 0;
+  PCHDeclReader Reader(*this, Record, Idx);
+
+  Decl *D = 0;
+  switch ((pch::DeclCode)DeclsCursor.ReadRecord(Code, Record)) {
+  case pch::DECL_ATTR:
+  case pch::DECL_CONTEXT_LEXICAL:
+  case pch::DECL_CONTEXT_VISIBLE:
+    assert(false && "Record cannot be de-serialized with ReadDeclRecord");
+    break;
+  case pch::DECL_TRANSLATION_UNIT:
+    assert(Index == 0 && "Translation unit must be at index 0");
+    D = Context->getTranslationUnitDecl();
+    break;
+  case pch::DECL_TYPEDEF:
+    D = TypedefDecl::Create(*Context, 0, SourceLocation(), 0, 0);
+    break;
+  case pch::DECL_ENUM:
+    D = EnumDecl::Create(*Context, 0, SourceLocation(), 0, SourceLocation(), 0);
+    break;
+  case pch::DECL_RECORD:
+    D = RecordDecl::Create(*Context, TagDecl::TK_struct, 0, SourceLocation(),
+                           0, SourceLocation(), 0);
+    break;
+  case pch::DECL_ENUM_CONSTANT:
+    D = EnumConstantDecl::Create(*Context, 0, SourceLocation(), 0, QualType(),
+                                 0, llvm::APSInt());
+    break;
+  case pch::DECL_FUNCTION:
+    D = FunctionDecl::Create(*Context, 0, SourceLocation(), DeclarationName(),
+                             QualType(), 0);
+    break;
+  case pch::DECL_OBJC_METHOD:
+    D = ObjCMethodDecl::Create(*Context, SourceLocation(), SourceLocation(),
+                               Selector(), QualType(), 0, 0);
+    break;
+  case pch::DECL_OBJC_INTERFACE:
+    D = ObjCInterfaceDecl::Create(*Context, 0, SourceLocation(), 0);
+    break;
+  case pch::DECL_OBJC_IVAR:
+    D = ObjCIvarDecl::Create(*Context, 0, SourceLocation(), 0, QualType(), 0,
+                             ObjCIvarDecl::None);
+    break;
+  case pch::DECL_OBJC_PROTOCOL:
+    D = ObjCProtocolDecl::Create(*Context, 0, SourceLocation(), 0);
+    break;
+  case pch::DECL_OBJC_AT_DEFS_FIELD:
+    D = ObjCAtDefsFieldDecl::Create(*Context, 0, SourceLocation(), 0,
+                                    QualType(), 0);
+    break;
+  case pch::DECL_OBJC_CLASS:
+    D = ObjCClassDecl::Create(*Context, 0, SourceLocation());
+    break;
+  case pch::DECL_OBJC_FORWARD_PROTOCOL:
+    D = ObjCForwardProtocolDecl::Create(*Context, 0, SourceLocation());
+    break;
+  case pch::DECL_OBJC_CATEGORY:
+    D = ObjCCategoryDecl::Create(*Context, 0, SourceLocation(), 
+                                 SourceLocation(), SourceLocation(), 0);
+    break;
+  case pch::DECL_OBJC_CATEGORY_IMPL:
+    D = ObjCCategoryImplDecl::Create(*Context, 0, SourceLocation(), 0, 0);
+    break;
+  case pch::DECL_OBJC_IMPLEMENTATION:
+    D = ObjCImplementationDecl::Create(*Context, 0, SourceLocation(), 0, 0);
+    break;
+  case pch::DECL_OBJC_COMPATIBLE_ALIAS:
+    D = ObjCCompatibleAliasDecl::Create(*Context, 0, SourceLocation(), 0, 0);
+    break;
+  case pch::DECL_OBJC_PROPERTY:
+    D = ObjCPropertyDecl::Create(*Context, 0, SourceLocation(), 0, SourceLocation(),
+                                 QualType());
+    break;
+  case pch::DECL_OBJC_PROPERTY_IMPL:
+    D = ObjCPropertyImplDecl::Create(*Context, 0, SourceLocation(),
+                                     SourceLocation(), 0,
+                                     ObjCPropertyImplDecl::Dynamic, 0);
+    break;
+  case pch::DECL_FIELD:
+    D = FieldDecl::Create(*Context, 0, SourceLocation(), 0, QualType(), 0, 0,
+                          false);
+    break;
+  case pch::DECL_VAR:
+    D = VarDecl::Create(*Context, 0, SourceLocation(), 0, QualType(), 0,
+                        VarDecl::None, VarDecl::None);
+    break;
+
+  case pch::DECL_IMPLICIT_PARAM:
+    D = ImplicitParamDecl::Create(*Context, 0, SourceLocation(), 0, QualType());
+    break;
+
+  case pch::DECL_PARM_VAR:
+    D = ParmVarDecl::Create(*Context, 0, SourceLocation(), 0, QualType(), 0,
+                            VarDecl::None, VarDecl::None, 0);
+    break;
+  case pch::DECL_FILE_SCOPE_ASM:
+    D = FileScopeAsmDecl::Create(*Context, 0, SourceLocation(), 0);
+    break;
+  case pch::DECL_BLOCK:
+    D = BlockDecl::Create(*Context, 0, SourceLocation());
+    break;
+      
+  case pch::DECL_NAMESPACE:
+    D = NamespaceDecl::Create(*Context, 0, SourceLocation(), 0);
+    break;
+  }
+
+  assert(D && "Unknown declaration reading PCH file");
+  LoadedDecl(Index, D);
+  Reader.Visit(D);
+
+  // If this declaration is also a declaration context, get the
+  // offsets for its tables of lexical and visible declarations.
+  if (DeclContext *DC = dyn_cast<DeclContext>(D)) {
+    std::pair<uint64_t, uint64_t> Offsets = Reader.VisitDeclContext(DC);
+    if (Offsets.first || Offsets.second) {
+      DC->setHasExternalLexicalStorage(Offsets.first != 0);
+      DC->setHasExternalVisibleStorage(Offsets.second != 0);
+      DeclContextOffsets[DC] = Offsets;
+    }
+  }
+  assert(Idx == Record.size());
+
+  // If we have deserialized a declaration that has a definition the
+  // AST consumer might need to know about, notify the consumer
+  // about that definition now or queue it for later.
+  if (isConsumerInterestedIn(D)) {
+    if (Consumer) {
+      DeclGroupRef DG(D);
+      Consumer->HandleTopLevelDecl(DG);
+    } else {
+      InterestingDecls.push_back(D);
+    }
+  }
+
+  return D;
+}
diff --git a/lib/Frontend/PCHReaderStmt.cpp b/lib/Frontend/PCHReaderStmt.cpp
new file mode 100644
index 0000000..5e08be1
--- /dev/null
+++ b/lib/Frontend/PCHReaderStmt.cpp
@@ -0,0 +1,1311 @@
+//===--- PCHReaderStmt.cpp - Stmt/Expr Deserialization ----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Statement/expression deserialization.  This implements the
+// PCHReader::ReadStmt method.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/PCHReader.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/StmtVisitor.h"
+using namespace clang;
+
+namespace {
+  class PCHStmtReader : public StmtVisitor<PCHStmtReader, unsigned> {
+    PCHReader &Reader;
+    const PCHReader::RecordData &Record;
+    unsigned &Idx;
+    llvm::SmallVectorImpl<Stmt *> &StmtStack;
+
+  public:
+    PCHStmtReader(PCHReader &Reader, const PCHReader::RecordData &Record,
+                  unsigned &Idx, llvm::SmallVectorImpl<Stmt *> &StmtStack)
+      : Reader(Reader), Record(Record), Idx(Idx), StmtStack(StmtStack) { }
+
+    /// \brief The number of record fields required for the Stmt class
+    /// itself.
+    static const unsigned NumStmtFields = 0;
+
+    /// \brief The number of record fields required for the Expr class
+    /// itself.
+    static const unsigned NumExprFields = NumStmtFields + 3;
+
+    // Each of the Visit* functions reads in part of the expression
+    // from the given record and the current expression stack, then
+    // return the total number of operands that it read from the
+    // expression stack.
+
+    unsigned VisitStmt(Stmt *S);
+    unsigned VisitNullStmt(NullStmt *S);
+    unsigned VisitCompoundStmt(CompoundStmt *S);
+    unsigned VisitSwitchCase(SwitchCase *S);
+    unsigned VisitCaseStmt(CaseStmt *S);
+    unsigned VisitDefaultStmt(DefaultStmt *S);
+    unsigned VisitLabelStmt(LabelStmt *S);
+    unsigned VisitIfStmt(IfStmt *S);
+    unsigned VisitSwitchStmt(SwitchStmt *S);
+    unsigned VisitWhileStmt(WhileStmt *S);
+    unsigned VisitDoStmt(DoStmt *S);
+    unsigned VisitForStmt(ForStmt *S);
+    unsigned VisitGotoStmt(GotoStmt *S);
+    unsigned VisitIndirectGotoStmt(IndirectGotoStmt *S);
+    unsigned VisitContinueStmt(ContinueStmt *S);
+    unsigned VisitBreakStmt(BreakStmt *S);
+    unsigned VisitReturnStmt(ReturnStmt *S);
+    unsigned VisitDeclStmt(DeclStmt *S);
+    unsigned VisitAsmStmt(AsmStmt *S);
+    unsigned VisitExpr(Expr *E);
+    unsigned VisitPredefinedExpr(PredefinedExpr *E);
+    unsigned VisitDeclRefExpr(DeclRefExpr *E);
+    unsigned VisitIntegerLiteral(IntegerLiteral *E);
+    unsigned VisitFloatingLiteral(FloatingLiteral *E);
+    unsigned VisitImaginaryLiteral(ImaginaryLiteral *E);
+    unsigned VisitStringLiteral(StringLiteral *E);
+    unsigned VisitCharacterLiteral(CharacterLiteral *E);
+    unsigned VisitParenExpr(ParenExpr *E);
+    unsigned VisitUnaryOperator(UnaryOperator *E);
+    unsigned VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E);
+    unsigned VisitArraySubscriptExpr(ArraySubscriptExpr *E);
+    unsigned VisitCallExpr(CallExpr *E);
+    unsigned VisitMemberExpr(MemberExpr *E);
+    unsigned VisitCastExpr(CastExpr *E);
+    unsigned VisitBinaryOperator(BinaryOperator *E);
+    unsigned VisitCompoundAssignOperator(CompoundAssignOperator *E);
+    unsigned VisitConditionalOperator(ConditionalOperator *E);
+    unsigned VisitImplicitCastExpr(ImplicitCastExpr *E);
+    unsigned VisitExplicitCastExpr(ExplicitCastExpr *E);
+    unsigned VisitCStyleCastExpr(CStyleCastExpr *E);
+    unsigned VisitCompoundLiteralExpr(CompoundLiteralExpr *E);
+    unsigned VisitExtVectorElementExpr(ExtVectorElementExpr *E);
+    unsigned VisitInitListExpr(InitListExpr *E);
+    unsigned VisitDesignatedInitExpr(DesignatedInitExpr *E);
+    unsigned VisitImplicitValueInitExpr(ImplicitValueInitExpr *E);
+    unsigned VisitVAArgExpr(VAArgExpr *E);
+    unsigned VisitAddrLabelExpr(AddrLabelExpr *E);
+    unsigned VisitStmtExpr(StmtExpr *E);
+    unsigned VisitTypesCompatibleExpr(TypesCompatibleExpr *E);
+    unsigned VisitChooseExpr(ChooseExpr *E);
+    unsigned VisitGNUNullExpr(GNUNullExpr *E);
+    unsigned VisitShuffleVectorExpr(ShuffleVectorExpr *E);
+    unsigned VisitBlockExpr(BlockExpr *E);
+    unsigned VisitBlockDeclRefExpr(BlockDeclRefExpr *E);
+    unsigned VisitObjCStringLiteral(ObjCStringLiteral *E);
+    unsigned VisitObjCEncodeExpr(ObjCEncodeExpr *E);
+    unsigned VisitObjCSelectorExpr(ObjCSelectorExpr *E);
+    unsigned VisitObjCProtocolExpr(ObjCProtocolExpr *E);
+    unsigned VisitObjCIvarRefExpr(ObjCIvarRefExpr *E);
+    unsigned VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E);
+    unsigned VisitObjCImplicitSetterGetterRefExpr(
+                            ObjCImplicitSetterGetterRefExpr *E);
+    unsigned VisitObjCMessageExpr(ObjCMessageExpr *E);
+    unsigned VisitObjCSuperExpr(ObjCSuperExpr *E);
+    unsigned VisitObjCIsaExpr(ObjCIsaExpr *E);
+
+    unsigned VisitObjCForCollectionStmt(ObjCForCollectionStmt *);
+    unsigned VisitObjCAtCatchStmt(ObjCAtCatchStmt *);
+    unsigned VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *);
+    unsigned VisitObjCAtTryStmt(ObjCAtTryStmt *);
+    unsigned VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *);
+    unsigned VisitObjCAtThrowStmt(ObjCAtThrowStmt *);
+
+    unsigned VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E);
+    unsigned VisitCXXConstructExpr(CXXConstructExpr *E);
+    unsigned VisitCXXNamedCastExpr(CXXNamedCastExpr *E);
+    unsigned VisitCXXStaticCastExpr(CXXStaticCastExpr *E);
+    unsigned VisitCXXDynamicCastExpr(CXXDynamicCastExpr *E);
+    unsigned VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *E);
+    unsigned VisitCXXConstCastExpr(CXXConstCastExpr *E);
+    unsigned VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E);
+    unsigned VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E);
+    unsigned VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E);
+  };
+}
+
+unsigned PCHStmtReader::VisitStmt(Stmt *S) {
+  assert(Idx == NumStmtFields && "Incorrect statement field count");
+  return 0;
+}
+
+unsigned PCHStmtReader::VisitNullStmt(NullStmt *S) {
+  VisitStmt(S);
+  S->setSemiLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  return 0;
+}
+
+unsigned PCHStmtReader::VisitCompoundStmt(CompoundStmt *S) {
+  VisitStmt(S);
+  unsigned NumStmts = Record[Idx++];
+  S->setStmts(*Reader.getContext(),
+              StmtStack.data() + StmtStack.size() - NumStmts, NumStmts);
+  S->setLBracLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  S->setRBracLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  return NumStmts;
+}
+
+unsigned PCHStmtReader::VisitSwitchCase(SwitchCase *S) {
+  VisitStmt(S);
+  Reader.RecordSwitchCaseID(S, Record[Idx++]);
+  return 0;
+}
+
+unsigned PCHStmtReader::VisitCaseStmt(CaseStmt *S) {
+  VisitSwitchCase(S);
+  S->setLHS(cast<Expr>(StmtStack[StmtStack.size() - 3]));
+  S->setRHS(cast_or_null<Expr>(StmtStack[StmtStack.size() - 2]));
+  S->setSubStmt(StmtStack.back());
+  S->setCaseLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  S->setEllipsisLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  S->setColonLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  return 3;
+}
+
+unsigned PCHStmtReader::VisitDefaultStmt(DefaultStmt *S) {
+  VisitSwitchCase(S);
+  S->setSubStmt(StmtStack.back());
+  S->setDefaultLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  S->setColonLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  return 1;
+}
+
+unsigned PCHStmtReader::VisitLabelStmt(LabelStmt *S) {
+  VisitStmt(S);
+  S->setID(Reader.GetIdentifierInfo(Record, Idx));
+  S->setSubStmt(StmtStack.back());
+  S->setIdentLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  Reader.RecordLabelStmt(S, Record[Idx++]);
+  return 1;
+}
+
+unsigned PCHStmtReader::VisitIfStmt(IfStmt *S) {
+  VisitStmt(S);
+  S->setConditionVariable(cast_or_null<VarDecl>(Reader.GetDecl(Record[Idx++])));
+  S->setCond(cast<Expr>(StmtStack[StmtStack.size() - 3]));
+  S->setThen(StmtStack[StmtStack.size() - 2]);
+  S->setElse(StmtStack[StmtStack.size() - 1]);
+  S->setIfLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  S->setElseLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  return 3;
+}
+
+unsigned PCHStmtReader::VisitSwitchStmt(SwitchStmt *S) {
+  VisitStmt(S);
+  S->setConditionVariable(cast_or_null<VarDecl>(Reader.GetDecl(Record[Idx++])));
+  S->setCond(cast<Expr>(StmtStack[StmtStack.size() - 2]));
+  S->setBody(StmtStack.back());
+  S->setSwitchLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  SwitchCase *PrevSC = 0;
+  for (unsigned N = Record.size(); Idx != N; ++Idx) {
+    SwitchCase *SC = Reader.getSwitchCaseWithID(Record[Idx]);
+    if (PrevSC)
+      PrevSC->setNextSwitchCase(SC);
+    else
+      S->setSwitchCaseList(SC);
+
+    // Retain this SwitchCase, since SwitchStmt::addSwitchCase() would
+    // normally retain it (but we aren't calling addSwitchCase).
+    SC->Retain();
+    PrevSC = SC;
+  }
+  return 2;
+}
+
+unsigned PCHStmtReader::VisitWhileStmt(WhileStmt *S) {
+  VisitStmt(S);
+  S->setConditionVariable(cast_or_null<VarDecl>(Reader.GetDecl(Record[Idx++])));
+  S->setCond(cast_or_null<Expr>(StmtStack[StmtStack.size() - 2]));
+  S->setBody(StmtStack.back());
+  S->setWhileLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  return 2;
+}
+
+unsigned PCHStmtReader::VisitDoStmt(DoStmt *S) {
+  VisitStmt(S);
+  S->setCond(cast_or_null<Expr>(StmtStack[StmtStack.size() - 2]));
+  S->setBody(StmtStack.back());
+  S->setDoLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  S->setWhileLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  S->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  return 2;
+}
+
+unsigned PCHStmtReader::VisitForStmt(ForStmt *S) {
+  VisitStmt(S);
+  S->setInit(StmtStack[StmtStack.size() - 4]);
+  S->setCond(cast_or_null<Expr>(StmtStack[StmtStack.size() - 3]));
+  S->setConditionVariable(cast_or_null<VarDecl>(Reader.GetDecl(Record[Idx++])));
+  S->setInc(cast_or_null<Expr>(StmtStack[StmtStack.size() - 2]));
+  S->setBody(StmtStack.back());
+  S->setForLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  S->setLParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  S->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  return 4;
+}
+
+unsigned PCHStmtReader::VisitGotoStmt(GotoStmt *S) {
+  VisitStmt(S);
+  Reader.SetLabelOf(S, Record[Idx++]);
+  S->setGotoLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  S->setLabelLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  return 0;
+}
+
+unsigned PCHStmtReader::VisitIndirectGotoStmt(IndirectGotoStmt *S) {
+  VisitStmt(S);
+  S->setGotoLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  S->setStarLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  S->setTarget(cast_or_null<Expr>(StmtStack.back()));
+  return 1;
+}
+
+unsigned PCHStmtReader::VisitContinueStmt(ContinueStmt *S) {
+  VisitStmt(S);
+  S->setContinueLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  return 0;
+}
+
+unsigned PCHStmtReader::VisitBreakStmt(BreakStmt *S) {
+  VisitStmt(S);
+  S->setBreakLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  return 0;
+}
+
+unsigned PCHStmtReader::VisitReturnStmt(ReturnStmt *S) {
+  VisitStmt(S);
+  S->setRetValue(cast_or_null<Expr>(StmtStack.back()));
+  S->setReturnLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  return 1;
+}
+
+unsigned PCHStmtReader::VisitDeclStmt(DeclStmt *S) {
+  VisitStmt(S);
+  S->setStartLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  S->setEndLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+
+  if (Idx + 1 == Record.size()) {
+    // Single declaration
+    S->setDeclGroup(DeclGroupRef(Reader.GetDecl(Record[Idx++])));
+  } else {
+    llvm::SmallVector<Decl *, 16> Decls;
+    Decls.reserve(Record.size() - Idx);
+    for (unsigned N = Record.size(); Idx != N; ++Idx)
+      Decls.push_back(Reader.GetDecl(Record[Idx]));
+    S->setDeclGroup(DeclGroupRef(DeclGroup::Create(*Reader.getContext(),
+                                                   Decls.data(),
+                                                   Decls.size())));
+  }
+  return 0;
+}
+
+unsigned PCHStmtReader::VisitAsmStmt(AsmStmt *S) {
+  VisitStmt(S);
+  unsigned NumOutputs = Record[Idx++];
+  unsigned NumInputs = Record[Idx++];
+  unsigned NumClobbers = Record[Idx++];
+  S->setAsmLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  S->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  S->setVolatile(Record[Idx++]);
+  S->setSimple(Record[Idx++]);
+  S->setMSAsm(Record[Idx++]);
+
+  unsigned StackIdx
+    = StmtStack.size() - (NumOutputs*2 + NumInputs*2 + NumClobbers + 1);
+  S->setAsmString(cast_or_null<StringLiteral>(StmtStack[StackIdx++]));
+
+  // Outputs and inputs
+  llvm::SmallVector<IdentifierInfo *, 16> Names;
+  llvm::SmallVector<StringLiteral*, 16> Constraints;
+  llvm::SmallVector<Stmt*, 16> Exprs;
+  for (unsigned I = 0, N = NumOutputs + NumInputs; I != N; ++I) {
+    Names.push_back(Reader.GetIdentifierInfo(Record, Idx));
+    Constraints.push_back(cast_or_null<StringLiteral>(StmtStack[StackIdx++]));
+    Exprs.push_back(StmtStack[StackIdx++]);
+  }
+
+  // Constraints
+  llvm::SmallVector<StringLiteral*, 16> Clobbers;
+  for (unsigned I = 0; I != NumClobbers; ++I)
+    Clobbers.push_back(cast_or_null<StringLiteral>(StmtStack[StackIdx++]));
+
+  S->setOutputsAndInputsAndClobbers(*Reader.getContext(),
+                                    Names.data(), Constraints.data(), 
+                                    Exprs.data(), NumOutputs, NumInputs, 
+                                    Clobbers.data(), NumClobbers);
+
+  assert(StackIdx == StmtStack.size() && "Error deserializing AsmStmt");
+  return NumOutputs*2 + NumInputs*2 + NumClobbers + 1;
+}
+
+unsigned PCHStmtReader::VisitExpr(Expr *E) {
+  VisitStmt(E);
+  E->setType(Reader.GetType(Record[Idx++]));
+  E->setTypeDependent(Record[Idx++]);
+  E->setValueDependent(Record[Idx++]);
+  assert(Idx == NumExprFields && "Incorrect expression field count");
+  return 0;
+}
+
+unsigned PCHStmtReader::VisitPredefinedExpr(PredefinedExpr *E) {
+  VisitExpr(E);
+  E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setIdentType((PredefinedExpr::IdentType)Record[Idx++]);
+  return 0;
+}
+
+unsigned PCHStmtReader::VisitDeclRefExpr(DeclRefExpr *E) {
+  VisitExpr(E);
+  E->setDecl(cast<ValueDecl>(Reader.GetDecl(Record[Idx++])));
+  E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  // FIXME: read qualifier
+  // FIXME: read explicit template arguments
+  return 0;
+}
+
+unsigned PCHStmtReader::VisitIntegerLiteral(IntegerLiteral *E) {
+  VisitExpr(E);
+  E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setValue(Reader.ReadAPInt(Record, Idx));
+  return 0;
+}
+
+unsigned PCHStmtReader::VisitFloatingLiteral(FloatingLiteral *E) {
+  VisitExpr(E);
+  E->setValue(Reader.ReadAPFloat(Record, Idx));
+  E->setExact(Record[Idx++]);
+  E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  return 0;
+}
+
+unsigned PCHStmtReader::VisitImaginaryLiteral(ImaginaryLiteral *E) {
+  VisitExpr(E);
+  E->setSubExpr(cast<Expr>(StmtStack.back()));
+  return 1;
+}
+
+unsigned PCHStmtReader::VisitStringLiteral(StringLiteral *E) {
+  VisitExpr(E);
+  unsigned Len = Record[Idx++];
+  assert(Record[Idx] == E->getNumConcatenated() &&
+         "Wrong number of concatenated tokens!");
+  ++Idx;
+  E->setWide(Record[Idx++]);
+
+  // Read string data
+  llvm::SmallString<16> Str(&Record[Idx], &Record[Idx] + Len);
+  E->setString(*Reader.getContext(), Str.str());
+  Idx += Len;
+
+  // Read source locations
+  for (unsigned I = 0, N = E->getNumConcatenated(); I != N; ++I)
+    E->setStrTokenLoc(I, SourceLocation::getFromRawEncoding(Record[Idx++]));
+
+  return 0;
+}
+
+unsigned PCHStmtReader::VisitCharacterLiteral(CharacterLiteral *E) {
+  VisitExpr(E);
+  E->setValue(Record[Idx++]);
+  E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setWide(Record[Idx++]);
+  return 0;
+}
+
+unsigned PCHStmtReader::VisitParenExpr(ParenExpr *E) {
+  VisitExpr(E);
+  E->setLParen(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setRParen(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setSubExpr(cast<Expr>(StmtStack.back()));
+  return 1;
+}
+
+unsigned PCHStmtReader::VisitUnaryOperator(UnaryOperator *E) {
+  VisitExpr(E);
+  E->setSubExpr(cast<Expr>(StmtStack.back()));
+  E->setOpcode((UnaryOperator::Opcode)Record[Idx++]);
+  E->setOperatorLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  return 1;
+}
+
+unsigned PCHStmtReader::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) {
+  VisitExpr(E);
+  E->setSizeof(Record[Idx++]);
+  if (Record[Idx] == 0) {
+    E->setArgument(cast<Expr>(StmtStack.back()));
+    ++Idx;
+  } else {
+    E->setArgument(Reader.GetTypeSourceInfo(Record, Idx));
+  }
+  E->setOperatorLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  return E->isArgumentType()? 0 : 1;
+}
+
+unsigned PCHStmtReader::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
+  VisitExpr(E);
+  E->setLHS(cast<Expr>(StmtStack[StmtStack.size() - 2]));
+  E->setRHS(cast<Expr>(StmtStack[StmtStack.size() - 1]));
+  E->setRBracketLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  return 2;
+}
+
+unsigned PCHStmtReader::VisitCallExpr(CallExpr *E) {
+  VisitExpr(E);
+  E->setNumArgs(*Reader.getContext(), Record[Idx++]);
+  E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setCallee(cast<Expr>(StmtStack[StmtStack.size() - E->getNumArgs() - 1]));
+  for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
+    E->setArg(I, cast<Expr>(StmtStack[StmtStack.size() - N + I]));
+  return E->getNumArgs() + 1;
+}
+
+unsigned PCHStmtReader::VisitMemberExpr(MemberExpr *E) {
+  VisitExpr(E);
+  E->setBase(cast<Expr>(StmtStack.back()));
+  E->setMemberDecl(cast<ValueDecl>(Reader.GetDecl(Record[Idx++])));
+  E->setMemberLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setArrow(Record[Idx++]);
+  return 1;
+}
+
+unsigned PCHStmtReader::VisitObjCIsaExpr(ObjCIsaExpr *E) {
+  VisitExpr(E);
+  E->setBase(cast<Expr>(StmtStack.back()));
+  E->setIsaMemberLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setArrow(Record[Idx++]);
+  return 1;
+}
+
+unsigned PCHStmtReader::VisitCastExpr(CastExpr *E) {
+  VisitExpr(E);
+  E->setSubExpr(cast<Expr>(StmtStack.back()));
+  E->setCastKind((CastExpr::CastKind)Record[Idx++]);
+
+  return 1;
+}
+
+unsigned PCHStmtReader::VisitBinaryOperator(BinaryOperator *E) {
+  VisitExpr(E);
+  E->setLHS(cast<Expr>(StmtStack.end()[-2]));
+  E->setRHS(cast<Expr>(StmtStack.end()[-1]));
+  E->setOpcode((BinaryOperator::Opcode)Record[Idx++]);
+  E->setOperatorLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  return 2;
+}
+
+unsigned PCHStmtReader::VisitCompoundAssignOperator(CompoundAssignOperator *E) {
+  VisitBinaryOperator(E);
+  E->setComputationLHSType(Reader.GetType(Record[Idx++]));
+  E->setComputationResultType(Reader.GetType(Record[Idx++]));
+  return 2;
+}
+
+unsigned PCHStmtReader::VisitConditionalOperator(ConditionalOperator *E) {
+  VisitExpr(E);
+  E->setCond(cast<Expr>(StmtStack[StmtStack.size() - 3]));
+  E->setLHS(cast_or_null<Expr>(StmtStack[StmtStack.size() - 2]));
+  E->setRHS(cast_or_null<Expr>(StmtStack[StmtStack.size() - 1]));
+  E->setQuestionLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setColonLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  return 3;
+}
+
+unsigned PCHStmtReader::VisitImplicitCastExpr(ImplicitCastExpr *E) {
+  VisitCastExpr(E);
+  E->setLvalueCast(Record[Idx++]);
+  return 1;
+}
+
+unsigned PCHStmtReader::VisitExplicitCastExpr(ExplicitCastExpr *E) {
+  VisitCastExpr(E);
+  E->setTypeInfoAsWritten(Reader.GetTypeSourceInfo(Record, Idx));
+  return 1;
+}
+
+unsigned PCHStmtReader::VisitCStyleCastExpr(CStyleCastExpr *E) {
+  VisitExplicitCastExpr(E);
+  E->setLParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  return 1;
+}
+
+unsigned PCHStmtReader::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
+  VisitExpr(E);
+  E->setLParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setTypeSourceInfo(Reader.GetTypeSourceInfo(Record, Idx));
+  E->setInitializer(cast<Expr>(StmtStack.back()));
+  E->setFileScope(Record[Idx++]);
+  return 1;
+}
+
+unsigned PCHStmtReader::VisitExtVectorElementExpr(ExtVectorElementExpr *E) {
+  VisitExpr(E);
+  E->setBase(cast<Expr>(StmtStack.back()));
+  E->setAccessor(Reader.GetIdentifierInfo(Record, Idx));
+  E->setAccessorLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  return 1;
+}
+
+unsigned PCHStmtReader::VisitInitListExpr(InitListExpr *E) {
+  VisitExpr(E);
+  unsigned NumInits = Record[Idx++];
+  E->reserveInits(*Reader.getContext(), NumInits);
+  for (unsigned I = 0; I != NumInits; ++I)
+    E->updateInit(*Reader.getContext(), I,
+                  cast<Expr>(StmtStack[StmtStack.size() - NumInits - 1 + I]));
+  E->setSyntacticForm(cast_or_null<InitListExpr>(StmtStack.back()));
+  E->setLBraceLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setRBraceLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setInitializedFieldInUnion(
+                      cast_or_null<FieldDecl>(Reader.GetDecl(Record[Idx++])));
+  E->sawArrayRangeDesignator(Record[Idx++]);
+  return NumInits + 1;
+}
+
+unsigned PCHStmtReader::VisitDesignatedInitExpr(DesignatedInitExpr *E) {
+  typedef DesignatedInitExpr::Designator Designator;
+
+  VisitExpr(E);
+  unsigned NumSubExprs = Record[Idx++];
+  assert(NumSubExprs == E->getNumSubExprs() && "Wrong number of subexprs");
+  for (unsigned I = 0; I != NumSubExprs; ++I)
+    E->setSubExpr(I, cast<Expr>(StmtStack[StmtStack.size() - NumSubExprs + I]));
+  E->setEqualOrColonLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setGNUSyntax(Record[Idx++]);
+
+  llvm::SmallVector<Designator, 4> Designators;
+  while (Idx < Record.size()) {
+    switch ((pch::DesignatorTypes)Record[Idx++]) {
+    case pch::DESIG_FIELD_DECL: {
+      FieldDecl *Field = cast<FieldDecl>(Reader.GetDecl(Record[Idx++]));
+      SourceLocation DotLoc
+        = SourceLocation::getFromRawEncoding(Record[Idx++]);
+      SourceLocation FieldLoc
+        = SourceLocation::getFromRawEncoding(Record[Idx++]);
+      Designators.push_back(Designator(Field->getIdentifier(), DotLoc,
+                                       FieldLoc));
+      Designators.back().setField(Field);
+      break;
+    }
+
+    case pch::DESIG_FIELD_NAME: {
+      const IdentifierInfo *Name = Reader.GetIdentifierInfo(Record, Idx);
+      SourceLocation DotLoc
+        = SourceLocation::getFromRawEncoding(Record[Idx++]);
+      SourceLocation FieldLoc
+        = SourceLocation::getFromRawEncoding(Record[Idx++]);
+      Designators.push_back(Designator(Name, DotLoc, FieldLoc));
+      break;
+    }
+
+    case pch::DESIG_ARRAY: {
+      unsigned Index = Record[Idx++];
+      SourceLocation LBracketLoc
+        = SourceLocation::getFromRawEncoding(Record[Idx++]);
+      SourceLocation RBracketLoc
+        = SourceLocation::getFromRawEncoding(Record[Idx++]);
+      Designators.push_back(Designator(Index, LBracketLoc, RBracketLoc));
+      break;
+    }
+
+    case pch::DESIG_ARRAY_RANGE: {
+      unsigned Index = Record[Idx++];
+      SourceLocation LBracketLoc
+        = SourceLocation::getFromRawEncoding(Record[Idx++]);
+      SourceLocation EllipsisLoc
+        = SourceLocation::getFromRawEncoding(Record[Idx++]);
+      SourceLocation RBracketLoc
+        = SourceLocation::getFromRawEncoding(Record[Idx++]);
+      Designators.push_back(Designator(Index, LBracketLoc, EllipsisLoc,
+                                       RBracketLoc));
+      break;
+    }
+    }
+  }
+  E->setDesignators(*Reader.getContext(), 
+                    Designators.data(), Designators.size());
+
+  return NumSubExprs;
+}
+
+unsigned PCHStmtReader::VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) {
+  VisitExpr(E);
+  return 0;
+}
+
+unsigned PCHStmtReader::VisitVAArgExpr(VAArgExpr *E) {
+  VisitExpr(E);
+  E->setSubExpr(cast<Expr>(StmtStack.back()));
+  E->setBuiltinLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  return 1;
+}
+
+unsigned PCHStmtReader::VisitAddrLabelExpr(AddrLabelExpr *E) {
+  VisitExpr(E);
+  E->setAmpAmpLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setLabelLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  Reader.SetLabelOf(E, Record[Idx++]);
+  return 0;
+}
+
+unsigned PCHStmtReader::VisitStmtExpr(StmtExpr *E) {
+  VisitExpr(E);
+  E->setLParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setSubStmt(cast_or_null<CompoundStmt>(StmtStack.back()));
+  return 1;
+}
+
+unsigned PCHStmtReader::VisitTypesCompatibleExpr(TypesCompatibleExpr *E) {
+  VisitExpr(E);
+  E->setArgType1(Reader.GetType(Record[Idx++]));
+  E->setArgType2(Reader.GetType(Record[Idx++]));
+  E->setBuiltinLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  return 0;
+}
+
+unsigned PCHStmtReader::VisitChooseExpr(ChooseExpr *E) {
+  VisitExpr(E);
+  E->setCond(cast<Expr>(StmtStack[StmtStack.size() - 3]));
+  E->setLHS(cast_or_null<Expr>(StmtStack[StmtStack.size() - 2]));
+  E->setRHS(cast_or_null<Expr>(StmtStack[StmtStack.size() - 1]));
+  E->setBuiltinLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  return 3;
+}
+
+unsigned PCHStmtReader::VisitGNUNullExpr(GNUNullExpr *E) {
+  VisitExpr(E);
+  E->setTokenLocation(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  return 0;
+}
+
+unsigned PCHStmtReader::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
+  VisitExpr(E);
+  unsigned NumExprs = Record[Idx++];
+  E->setExprs(*Reader.getContext(),
+              (Expr **)&StmtStack[StmtStack.size() - NumExprs], NumExprs);
+  E->setBuiltinLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  return NumExprs;
+}
+
+unsigned PCHStmtReader::VisitBlockExpr(BlockExpr *E) {
+  VisitExpr(E);
+  E->setBlockDecl(cast_or_null<BlockDecl>(Reader.GetDecl(Record[Idx++])));
+  E->setHasBlockDeclRefExprs(Record[Idx++]);
+  return 0;
+}
+
+unsigned PCHStmtReader::VisitBlockDeclRefExpr(BlockDeclRefExpr *E) {
+  VisitExpr(E);
+  E->setDecl(cast<ValueDecl>(Reader.GetDecl(Record[Idx++])));
+  E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setByRef(Record[Idx++]);
+  E->setConstQualAdded(Record[Idx++]);
+  return 0;
+}
+
+//===----------------------------------------------------------------------===//
+// Objective-C Expressions and Statements
+
+unsigned PCHStmtReader::VisitObjCStringLiteral(ObjCStringLiteral *E) {
+  VisitExpr(E);
+  E->setString(cast<StringLiteral>(StmtStack.back()));
+  E->setAtLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  return 1;
+}
+
+unsigned PCHStmtReader::VisitObjCEncodeExpr(ObjCEncodeExpr *E) {
+  VisitExpr(E);
+  E->setEncodedTypeSourceInfo(Reader.GetTypeSourceInfo(Record, Idx));
+  E->setAtLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  return 0;
+}
+
+unsigned PCHStmtReader::VisitObjCSelectorExpr(ObjCSelectorExpr *E) {
+  VisitExpr(E);
+  E->setSelector(Reader.GetSelector(Record, Idx));
+  E->setAtLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  return 0;
+}
+
+unsigned PCHStmtReader::VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
+  VisitExpr(E);
+  E->setProtocol(cast<ObjCProtocolDecl>(Reader.GetDecl(Record[Idx++])));
+  E->setAtLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  return 0;
+}
+
+unsigned PCHStmtReader::VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
+  VisitExpr(E);
+  E->setDecl(cast<ObjCIvarDecl>(Reader.GetDecl(Record[Idx++])));
+  E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setBase(cast<Expr>(StmtStack.back()));
+  E->setIsArrow(Record[Idx++]);
+  E->setIsFreeIvar(Record[Idx++]);
+  return 1;
+}
+
+unsigned PCHStmtReader::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
+  VisitExpr(E);
+  E->setProperty(cast<ObjCPropertyDecl>(Reader.GetDecl(Record[Idx++])));
+  E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setBase(cast<Expr>(StmtStack.back()));
+  return 1;
+}
+
+unsigned PCHStmtReader::VisitObjCImplicitSetterGetterRefExpr(
+                                      ObjCImplicitSetterGetterRefExpr *E) {
+  VisitExpr(E);
+  E->setGetterMethod(
+                 cast_or_null<ObjCMethodDecl>(Reader.GetDecl(Record[Idx++])));
+  E->setSetterMethod(
+                 cast_or_null<ObjCMethodDecl>(Reader.GetDecl(Record[Idx++])));
+  E->setInterfaceDecl(
+              cast_or_null<ObjCInterfaceDecl>(Reader.GetDecl(Record[Idx++])));
+  E->setBase(cast_or_null<Expr>(StmtStack.back()));
+  E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setClassLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  return 1;
+}
+
+unsigned PCHStmtReader::VisitObjCMessageExpr(ObjCMessageExpr *E) {
+  VisitExpr(E);
+  assert(Record[Idx] == E->getNumArgs());
+  ++Idx;
+  ObjCMessageExpr::ReceiverKind Kind
+    = static_cast<ObjCMessageExpr::ReceiverKind>(Record[Idx++]);
+  switch (Kind) {
+  case ObjCMessageExpr::Instance:
+    E->setInstanceReceiver(
+         cast_or_null<Expr>(StmtStack[StmtStack.size() - E->getNumArgs() - 1]));
+    break;
+
+  case ObjCMessageExpr::Class:
+    E->setClassReceiver(Reader.GetTypeSourceInfo(Record, Idx));
+    break;
+
+  case ObjCMessageExpr::SuperClass:
+  case ObjCMessageExpr::SuperInstance: {
+    QualType T = Reader.GetType(Record[Idx++]);
+    SourceLocation SuperLoc = SourceLocation::getFromRawEncoding(Record[Idx++]);
+    E->setSuper(SuperLoc, T, Kind == ObjCMessageExpr::SuperInstance);
+    break;
+  }
+  }
+
+  assert(Kind == E->getReceiverKind());
+
+  if (Record[Idx++])
+    E->setMethodDecl(cast_or_null<ObjCMethodDecl>(Reader.GetDecl(Record[Idx++])));
+  else
+    E->setSelector(Reader.GetSelector(Record, Idx));
+
+  E->setLeftLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setRightLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+
+  for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
+    E->setArg(I, cast<Expr>(StmtStack[StmtStack.size() - N + I]));
+  return E->getNumArgs() + (Kind == ObjCMessageExpr::Instance);
+}
+
+unsigned PCHStmtReader::VisitObjCSuperExpr(ObjCSuperExpr *E) {
+  VisitExpr(E);
+  E->setLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  return 0;
+}
+
+unsigned PCHStmtReader::VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) {
+  VisitStmt(S);
+  S->setElement(cast_or_null<Stmt>(StmtStack[StmtStack.size() - 3]));
+  S->setCollection(cast_or_null<Expr>(StmtStack[StmtStack.size() - 2]));
+  S->setBody(cast_or_null<Stmt>(StmtStack[StmtStack.size() - 1]));
+  S->setForLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  S->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  return 3;
+}
+
+unsigned PCHStmtReader::VisitObjCAtCatchStmt(ObjCAtCatchStmt *S) {
+  VisitStmt(S);
+  S->setCatchBody(cast_or_null<Stmt>(StmtStack.back()));
+  S->setCatchParamDecl(cast_or_null<VarDecl>(Reader.GetDecl(Record[Idx++])));
+  S->setAtCatchLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  S->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  return 1;
+}
+
+unsigned PCHStmtReader::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
+  VisitStmt(S);
+  S->setFinallyBody(StmtStack.back());
+  S->setAtFinallyLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  return 1;
+}
+
+unsigned PCHStmtReader::VisitObjCAtTryStmt(ObjCAtTryStmt *S) {
+  VisitStmt(S);
+  assert(Record[Idx] == S->getNumCatchStmts());
+  ++Idx;
+  bool HasFinally = Record[Idx++];
+  for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I) {
+    unsigned Offset = StmtStack.size() - N - HasFinally + I;
+    S->setCatchStmt(I, cast_or_null<ObjCAtCatchStmt>(StmtStack[Offset]));
+  }
+
+  unsigned TryOffset
+    = StmtStack.size() - S->getNumCatchStmts() - HasFinally - 1;
+  S->setTryBody(cast_or_null<Stmt>(StmtStack[TryOffset]));
+  if (HasFinally)
+    S->setFinallyStmt(cast_or_null<Stmt>(StmtStack[StmtStack.size() - 1]));
+  S->setAtTryLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  return 1 + S->getNumCatchStmts() + HasFinally;
+}
+
+unsigned PCHStmtReader::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *S) {
+  VisitStmt(S);
+  S->setSynchExpr(cast_or_null<Stmt>(StmtStack[StmtStack.size() - 2]));
+  S->setSynchBody(cast_or_null<Stmt>(StmtStack[StmtStack.size() - 1]));
+  S->setAtSynchronizedLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  return 2;
+}
+
+unsigned PCHStmtReader::VisitObjCAtThrowStmt(ObjCAtThrowStmt *S) {
+  VisitStmt(S);
+  S->setThrowExpr(StmtStack.back());
+  S->setThrowLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  return 1;
+}
+
+//===----------------------------------------------------------------------===//
+// C++ Expressions and Statements
+
+unsigned PCHStmtReader::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
+  unsigned num = VisitCallExpr(E);
+  E->setOperator((OverloadedOperatorKind)Record[Idx++]);
+  return num;
+}
+
+unsigned PCHStmtReader::VisitCXXConstructExpr(CXXConstructExpr *E) {
+  VisitExpr(E);
+  E->setConstructor(cast<CXXConstructorDecl>(Reader.GetDecl(Record[Idx++])));
+  E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setElidable(Record[Idx++]);  
+  E->setRequiresZeroInitialization(Record[Idx++]);
+  for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
+    E->setArg(I, cast<Expr>(StmtStack[StmtStack.size() - N + I]));
+  return E->getNumArgs();
+}
+
+unsigned PCHStmtReader::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) {
+  unsigned num = VisitExplicitCastExpr(E);
+  E->setOperatorLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  return num;
+}
+
+unsigned PCHStmtReader::VisitCXXStaticCastExpr(CXXStaticCastExpr *E) {
+  return VisitCXXNamedCastExpr(E);
+}
+
+unsigned PCHStmtReader::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
+  return VisitCXXNamedCastExpr(E);
+}
+
+unsigned PCHStmtReader::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *E) {
+  return VisitCXXNamedCastExpr(E);
+}
+
+unsigned PCHStmtReader::VisitCXXConstCastExpr(CXXConstCastExpr *E) {
+  return VisitCXXNamedCastExpr(E);
+}
+
+unsigned PCHStmtReader::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E) {
+  unsigned num = VisitExplicitCastExpr(E);
+  E->setTypeBeginLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  return num;
+}
+
+unsigned PCHStmtReader::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
+  VisitExpr(E);
+  E->setValue(Record[Idx++]);
+  E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  return 0;
+}
+
+unsigned PCHStmtReader::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E) {
+  VisitExpr(E);
+  E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  return 0;
+}
+
+// Within the bitstream, expressions are stored in Reverse Polish
+// Notation, with each of the subexpressions preceding the
+// expression they are stored in. To evaluate expressions, we
+// continue reading expressions and placing them on the stack, with
+// expressions having operands removing those operands from the
+// stack. Evaluation terminates when we see a STMT_STOP record, and
+// the single remaining expression on the stack is our result.
+Stmt *PCHReader::ReadStmt(llvm::BitstreamCursor &Cursor) {
+  RecordData Record;
+  unsigned Idx;
+  llvm::SmallVector<Stmt *, 16> StmtStack;
+  PCHStmtReader Reader(*this, Record, Idx, StmtStack);
+  Stmt::EmptyShell Empty;
+
+  while (true) {
+    unsigned Code = Cursor.ReadCode();
+    if (Code == llvm::bitc::END_BLOCK) {
+      if (Cursor.ReadBlockEnd()) {
+        Error("error at end of block in PCH file");
+        return 0;
+      }
+      break;
+    }
+
+    if (Code == llvm::bitc::ENTER_SUBBLOCK) {
+      // No known subblocks, always skip them.
+      Cursor.ReadSubBlockID();
+      if (Cursor.SkipBlock()) {
+        Error("malformed block record in PCH file");
+        return 0;
+      }
+      continue;
+    }
+
+    if (Code == llvm::bitc::DEFINE_ABBREV) {
+      Cursor.ReadAbbrevRecord();
+      continue;
+    }
+
+    Stmt *S = 0;
+    Idx = 0;
+    Record.clear();
+    bool Finished = false;
+    switch ((pch::StmtCode)Cursor.ReadRecord(Code, Record)) {
+    case pch::STMT_STOP:
+      Finished = true;
+      break;
+
+    case pch::STMT_NULL_PTR:
+      S = 0;
+      break;
+
+    case pch::STMT_NULL:
+      S = new (Context) NullStmt(Empty);
+      break;
+
+    case pch::STMT_COMPOUND:
+      S = new (Context) CompoundStmt(Empty);
+      break;
+
+    case pch::STMT_CASE:
+      S = new (Context) CaseStmt(Empty);
+      break;
+
+    case pch::STMT_DEFAULT:
+      S = new (Context) DefaultStmt(Empty);
+      break;
+
+    case pch::STMT_LABEL:
+      S = new (Context) LabelStmt(Empty);
+      break;
+
+    case pch::STMT_IF:
+      S = new (Context) IfStmt(Empty);
+      break;
+
+    case pch::STMT_SWITCH:
+      S = new (Context) SwitchStmt(Empty);
+      break;
+
+    case pch::STMT_WHILE:
+      S = new (Context) WhileStmt(Empty);
+      break;
+
+    case pch::STMT_DO:
+      S = new (Context) DoStmt(Empty);
+      break;
+
+    case pch::STMT_FOR:
+      S = new (Context) ForStmt(Empty);
+      break;
+
+    case pch::STMT_GOTO:
+      S = new (Context) GotoStmt(Empty);
+      break;
+
+    case pch::STMT_INDIRECT_GOTO:
+      S = new (Context) IndirectGotoStmt(Empty);
+      break;
+
+    case pch::STMT_CONTINUE:
+      S = new (Context) ContinueStmt(Empty);
+      break;
+
+    case pch::STMT_BREAK:
+      S = new (Context) BreakStmt(Empty);
+      break;
+
+    case pch::STMT_RETURN:
+      S = new (Context) ReturnStmt(Empty);
+      break;
+
+    case pch::STMT_DECL:
+      S = new (Context) DeclStmt(Empty);
+      break;
+
+    case pch::STMT_ASM:
+      S = new (Context) AsmStmt(Empty);
+      break;
+
+    case pch::EXPR_PREDEFINED:
+      S = new (Context) PredefinedExpr(Empty);
+      break;
+
+    case pch::EXPR_DECL_REF:
+      S = new (Context) DeclRefExpr(Empty);
+      break;
+
+    case pch::EXPR_INTEGER_LITERAL:
+      S = new (Context) IntegerLiteral(Empty);
+      break;
+
+    case pch::EXPR_FLOATING_LITERAL:
+      S = new (Context) FloatingLiteral(Empty);
+      break;
+
+    case pch::EXPR_IMAGINARY_LITERAL:
+      S = new (Context) ImaginaryLiteral(Empty);
+      break;
+
+    case pch::EXPR_STRING_LITERAL:
+      S = StringLiteral::CreateEmpty(*Context,
+                                     Record[PCHStmtReader::NumExprFields + 1]);
+      break;
+
+    case pch::EXPR_CHARACTER_LITERAL:
+      S = new (Context) CharacterLiteral(Empty);
+      break;
+
+    case pch::EXPR_PAREN:
+      S = new (Context) ParenExpr(Empty);
+      break;
+
+    case pch::EXPR_UNARY_OPERATOR:
+      S = new (Context) UnaryOperator(Empty);
+      break;
+
+    case pch::EXPR_SIZEOF_ALIGN_OF:
+      S = new (Context) SizeOfAlignOfExpr(Empty);
+      break;
+
+    case pch::EXPR_ARRAY_SUBSCRIPT:
+      S = new (Context) ArraySubscriptExpr(Empty);
+      break;
+
+    case pch::EXPR_CALL:
+      S = new (Context) CallExpr(*Context, Stmt::CallExprClass, Empty);
+      break;
+
+    case pch::EXPR_MEMBER:
+      S = new (Context) MemberExpr(Empty);
+      break;
+
+    case pch::EXPR_BINARY_OPERATOR:
+      S = new (Context) BinaryOperator(Empty);
+      break;
+
+    case pch::EXPR_COMPOUND_ASSIGN_OPERATOR:
+      S = new (Context) CompoundAssignOperator(Empty);
+      break;
+
+    case pch::EXPR_CONDITIONAL_OPERATOR:
+      S = new (Context) ConditionalOperator(Empty);
+      break;
+
+    case pch::EXPR_IMPLICIT_CAST:
+      S = new (Context) ImplicitCastExpr(Empty);
+      break;
+
+    case pch::EXPR_CSTYLE_CAST:
+      S = new (Context) CStyleCastExpr(Empty);
+      break;
+
+    case pch::EXPR_COMPOUND_LITERAL:
+      S = new (Context) CompoundLiteralExpr(Empty);
+      break;
+
+    case pch::EXPR_EXT_VECTOR_ELEMENT:
+      S = new (Context) ExtVectorElementExpr(Empty);
+      break;
+
+    case pch::EXPR_INIT_LIST:
+      S = new (Context) InitListExpr(*getContext(), Empty);
+      break;
+
+    case pch::EXPR_DESIGNATED_INIT:
+      S = DesignatedInitExpr::CreateEmpty(*Context,
+                                     Record[PCHStmtReader::NumExprFields] - 1);
+
+      break;
+
+    case pch::EXPR_IMPLICIT_VALUE_INIT:
+      S = new (Context) ImplicitValueInitExpr(Empty);
+      break;
+
+    case pch::EXPR_VA_ARG:
+      S = new (Context) VAArgExpr(Empty);
+      break;
+
+    case pch::EXPR_ADDR_LABEL:
+      S = new (Context) AddrLabelExpr(Empty);
+      break;
+
+    case pch::EXPR_STMT:
+      S = new (Context) StmtExpr(Empty);
+      break;
+
+    case pch::EXPR_TYPES_COMPATIBLE:
+      S = new (Context) TypesCompatibleExpr(Empty);
+      break;
+
+    case pch::EXPR_CHOOSE:
+      S = new (Context) ChooseExpr(Empty);
+      break;
+
+    case pch::EXPR_GNU_NULL:
+      S = new (Context) GNUNullExpr(Empty);
+      break;
+
+    case pch::EXPR_SHUFFLE_VECTOR:
+      S = new (Context) ShuffleVectorExpr(Empty);
+      break;
+
+    case pch::EXPR_BLOCK:
+      S = new (Context) BlockExpr(Empty);
+      break;
+
+    case pch::EXPR_BLOCK_DECL_REF:
+      S = new (Context) BlockDeclRefExpr(Empty);
+      break;
+
+    case pch::EXPR_OBJC_STRING_LITERAL:
+      S = new (Context) ObjCStringLiteral(Empty);
+      break;
+    case pch::EXPR_OBJC_ENCODE:
+      S = new (Context) ObjCEncodeExpr(Empty);
+      break;
+    case pch::EXPR_OBJC_SELECTOR_EXPR:
+      S = new (Context) ObjCSelectorExpr(Empty);
+      break;
+    case pch::EXPR_OBJC_PROTOCOL_EXPR:
+      S = new (Context) ObjCProtocolExpr(Empty);
+      break;
+    case pch::EXPR_OBJC_IVAR_REF_EXPR:
+      S = new (Context) ObjCIvarRefExpr(Empty);
+      break;
+    case pch::EXPR_OBJC_PROPERTY_REF_EXPR:
+      S = new (Context) ObjCPropertyRefExpr(Empty);
+      break;
+    case pch::EXPR_OBJC_KVC_REF_EXPR:
+      S = new (Context) ObjCImplicitSetterGetterRefExpr(Empty);
+      break;
+    case pch::EXPR_OBJC_MESSAGE_EXPR:
+      S = ObjCMessageExpr::CreateEmpty(*Context,
+                                     Record[PCHStmtReader::NumExprFields]);
+      break;
+    case pch::EXPR_OBJC_SUPER_EXPR:
+      S = new (Context) ObjCSuperExpr(Empty);
+      break;
+    case pch::EXPR_OBJC_ISA:
+      S = new (Context) ObjCIsaExpr(Empty);
+      break;
+    case pch::STMT_OBJC_FOR_COLLECTION:
+      S = new (Context) ObjCForCollectionStmt(Empty);
+      break;
+    case pch::STMT_OBJC_CATCH:
+      S = new (Context) ObjCAtCatchStmt(Empty);
+      break;
+    case pch::STMT_OBJC_FINALLY:
+      S = new (Context) ObjCAtFinallyStmt(Empty);
+      break;
+    case pch::STMT_OBJC_AT_TRY:
+      S = ObjCAtTryStmt::CreateEmpty(*Context, 
+                                     Record[PCHStmtReader::NumStmtFields],
+                                     Record[PCHStmtReader::NumStmtFields + 1]);
+      break;
+    case pch::STMT_OBJC_AT_SYNCHRONIZED:
+      S = new (Context) ObjCAtSynchronizedStmt(Empty);
+      break;
+    case pch::STMT_OBJC_AT_THROW:
+      S = new (Context) ObjCAtThrowStmt(Empty);
+      break;
+
+    case pch::EXPR_CXX_OPERATOR_CALL:
+      S = new (Context) CXXOperatorCallExpr(*Context, Empty);
+      break;
+        
+    case pch::EXPR_CXX_CONSTRUCT:
+      S = new (Context) CXXConstructExpr(Empty, *Context,
+                                      Record[PCHStmtReader::NumExprFields + 2]);
+      break;
+
+    case pch::EXPR_CXX_STATIC_CAST:
+      S = new (Context) CXXStaticCastExpr(Empty);
+      break;
+
+    case pch::EXPR_CXX_DYNAMIC_CAST:
+      S = new (Context) CXXDynamicCastExpr(Empty);
+      break;
+
+    case pch::EXPR_CXX_REINTERPRET_CAST:
+      S = new (Context) CXXReinterpretCastExpr(Empty);
+      break;
+
+    case pch::EXPR_CXX_CONST_CAST:
+      S = new (Context) CXXConstCastExpr(Empty);
+      break;
+
+    case pch::EXPR_CXX_FUNCTIONAL_CAST:
+      S = new (Context) CXXFunctionalCastExpr(Empty);
+      break;
+
+    case pch::EXPR_CXX_BOOL_LITERAL:
+      S = new (Context) CXXBoolLiteralExpr(Empty);
+      break;
+
+    case pch::EXPR_CXX_NULL_PTR_LITERAL:
+      S = new (Context) CXXNullPtrLiteralExpr(Empty);
+      break;
+    }
+
+    // We hit a STMT_STOP, so we're done with this expression.
+    if (Finished)
+      break;
+
+    ++NumStatementsRead;
+
+    if (S) {
+      unsigned NumSubStmts = Reader.Visit(S);
+      while (NumSubStmts > 0) {
+        StmtStack.pop_back();
+        --NumSubStmts;
+      }
+    }
+
+    assert(Idx == Record.size() && "Invalid deserialization of statement");
+    StmtStack.push_back(S);
+  }
+  assert(StmtStack.size() == 1 && "Extra expressions on stack!");
+  return StmtStack.back();
+}
diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp
new file mode 100644
index 0000000..e56dd31
--- /dev/null
+++ b/lib/Frontend/PCHWriter.cpp
@@ -0,0 +1,2409 @@
+//===--- PCHWriter.cpp - Precompiled Headers Writer -----------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the PCHWriter class, which writes a precompiled header.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/PCHWriter.h"
+#include "../Sema/Sema.h" // FIXME: move header into include/clang/Sema
+#include "../Sema/IdentifierResolver.h" // FIXME: move header
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclContextInternals.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/TypeLocVisitor.h"
+#include "clang/Lex/MacroInfo.h"
+#include "clang/Lex/PreprocessingRecord.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Lex/HeaderSearch.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/OnDiskHashTable.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/SourceManagerInternals.h"
+#include "clang/Basic/TargetInfo.h"
+#include "clang/Basic/Version.h"
+#include "llvm/ADT/APFloat.h"
+#include "llvm/ADT/APInt.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Bitcode/BitstreamWriter.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/System/Path.h"
+#include <cstdio>
+using namespace clang;
+
+//===----------------------------------------------------------------------===//
+// Type serialization
+//===----------------------------------------------------------------------===//
+
+namespace {
+  class PCHTypeWriter {
+    PCHWriter &Writer;
+    PCHWriter::RecordData &Record;
+
+  public:
+    /// \brief Type code that corresponds to the record generated.
+    pch::TypeCode Code;
+
+    PCHTypeWriter(PCHWriter &Writer, PCHWriter::RecordData &Record)
+      : Writer(Writer), Record(Record), Code(pch::TYPE_EXT_QUAL) { }
+
+    void VisitArrayType(const ArrayType *T);
+    void VisitFunctionType(const FunctionType *T);
+    void VisitTagType(const TagType *T);
+
+#define TYPE(Class, Base) void Visit##Class##Type(const Class##Type *T);
+#define ABSTRACT_TYPE(Class, Base)
+#define DEPENDENT_TYPE(Class, Base)
+#include "clang/AST/TypeNodes.def"
+    void VisitInjectedClassNameType(const InjectedClassNameType *T);
+  };
+}
+
+void PCHTypeWriter::VisitBuiltinType(const BuiltinType *T) {
+  assert(false && "Built-in types are never serialized");
+}
+
+void PCHTypeWriter::VisitComplexType(const ComplexType *T) {
+  Writer.AddTypeRef(T->getElementType(), Record);
+  Code = pch::TYPE_COMPLEX;
+}
+
+void PCHTypeWriter::VisitPointerType(const PointerType *T) {
+  Writer.AddTypeRef(T->getPointeeType(), Record);
+  Code = pch::TYPE_POINTER;
+}
+
+void PCHTypeWriter::VisitBlockPointerType(const BlockPointerType *T) {
+  Writer.AddTypeRef(T->getPointeeType(), Record);
+  Code = pch::TYPE_BLOCK_POINTER;
+}
+
+void PCHTypeWriter::VisitLValueReferenceType(const LValueReferenceType *T) {
+  Writer.AddTypeRef(T->getPointeeType(), Record);
+  Code = pch::TYPE_LVALUE_REFERENCE;
+}
+
+void PCHTypeWriter::VisitRValueReferenceType(const RValueReferenceType *T) {
+  Writer.AddTypeRef(T->getPointeeType(), Record);
+  Code = pch::TYPE_RVALUE_REFERENCE;
+}
+
+void PCHTypeWriter::VisitMemberPointerType(const MemberPointerType *T) {
+  Writer.AddTypeRef(T->getPointeeType(), Record);
+  Writer.AddTypeRef(QualType(T->getClass(), 0), Record);
+  Code = pch::TYPE_MEMBER_POINTER;
+}
+
+void PCHTypeWriter::VisitArrayType(const ArrayType *T) {
+  Writer.AddTypeRef(T->getElementType(), Record);
+  Record.push_back(T->getSizeModifier()); // FIXME: stable values
+  Record.push_back(T->getIndexTypeCVRQualifiers()); // FIXME: stable values
+}
+
+void PCHTypeWriter::VisitConstantArrayType(const ConstantArrayType *T) {
+  VisitArrayType(T);
+  Writer.AddAPInt(T->getSize(), Record);
+  Code = pch::TYPE_CONSTANT_ARRAY;
+}
+
+void PCHTypeWriter::VisitIncompleteArrayType(const IncompleteArrayType *T) {
+  VisitArrayType(T);
+  Code = pch::TYPE_INCOMPLETE_ARRAY;
+}
+
+void PCHTypeWriter::VisitVariableArrayType(const VariableArrayType *T) {
+  VisitArrayType(T);
+  Writer.AddSourceLocation(T->getLBracketLoc(), Record);
+  Writer.AddSourceLocation(T->getRBracketLoc(), Record);
+  Writer.AddStmt(T->getSizeExpr());
+  Code = pch::TYPE_VARIABLE_ARRAY;
+}
+
+void PCHTypeWriter::VisitVectorType(const VectorType *T) {
+  Writer.AddTypeRef(T->getElementType(), Record);
+  Record.push_back(T->getNumElements());
+  Record.push_back(T->isAltiVec());
+  Record.push_back(T->isPixel());
+  Code = pch::TYPE_VECTOR;
+}
+
+void PCHTypeWriter::VisitExtVectorType(const ExtVectorType *T) {
+  VisitVectorType(T);
+  Code = pch::TYPE_EXT_VECTOR;
+}
+
+void PCHTypeWriter::VisitFunctionType(const FunctionType *T) {
+  Writer.AddTypeRef(T->getResultType(), Record);
+  FunctionType::ExtInfo C = T->getExtInfo();
+  Record.push_back(C.getNoReturn());
+  Record.push_back(C.getRegParm());
+  // FIXME: need to stabilize encoding of calling convention...
+  Record.push_back(C.getCC());
+}
+
+void PCHTypeWriter::VisitFunctionNoProtoType(const FunctionNoProtoType *T) {
+  VisitFunctionType(T);
+  Code = pch::TYPE_FUNCTION_NO_PROTO;
+}
+
+void PCHTypeWriter::VisitFunctionProtoType(const FunctionProtoType *T) {
+  VisitFunctionType(T);
+  Record.push_back(T->getNumArgs());
+  for (unsigned I = 0, N = T->getNumArgs(); I != N; ++I)
+    Writer.AddTypeRef(T->getArgType(I), Record);
+  Record.push_back(T->isVariadic());
+  Record.push_back(T->getTypeQuals());
+  Record.push_back(T->hasExceptionSpec());
+  Record.push_back(T->hasAnyExceptionSpec());
+  Record.push_back(T->getNumExceptions());
+  for (unsigned I = 0, N = T->getNumExceptions(); I != N; ++I)
+    Writer.AddTypeRef(T->getExceptionType(I), Record);
+  Code = pch::TYPE_FUNCTION_PROTO;
+}
+
+#if 0
+// For when we want it....
+void PCHTypeWriter::VisitUnresolvedUsingType(const UnresolvedUsingType *T) {
+  Writer.AddDeclRef(T->getDecl(), Record);
+  Code = pch::TYPE_UNRESOLVED_USING;
+}
+#endif
+
+void PCHTypeWriter::VisitTypedefType(const TypedefType *T) {
+  Writer.AddDeclRef(T->getDecl(), Record);
+  Code = pch::TYPE_TYPEDEF;
+}
+
+void PCHTypeWriter::VisitTypeOfExprType(const TypeOfExprType *T) {
+  Writer.AddStmt(T->getUnderlyingExpr());
+  Code = pch::TYPE_TYPEOF_EXPR;
+}
+
+void PCHTypeWriter::VisitTypeOfType(const TypeOfType *T) {
+  Writer.AddTypeRef(T->getUnderlyingType(), Record);
+  Code = pch::TYPE_TYPEOF;
+}
+
+void PCHTypeWriter::VisitDecltypeType(const DecltypeType *T) {
+  Writer.AddStmt(T->getUnderlyingExpr());
+  Code = pch::TYPE_DECLTYPE;
+}
+
+void PCHTypeWriter::VisitTagType(const TagType *T) {
+  Writer.AddDeclRef(T->getDecl(), Record);
+  assert(!T->isBeingDefined() &&
+         "Cannot serialize in the middle of a type definition");
+}
+
+void PCHTypeWriter::VisitRecordType(const RecordType *T) {
+  VisitTagType(T);
+  Code = pch::TYPE_RECORD;
+}
+
+void PCHTypeWriter::VisitEnumType(const EnumType *T) {
+  VisitTagType(T);
+  Code = pch::TYPE_ENUM;
+}
+
+void PCHTypeWriter::VisitElaboratedType(const ElaboratedType *T) {
+  Writer.AddTypeRef(T->getUnderlyingType(), Record);
+  Record.push_back(T->getTagKind());
+  Code = pch::TYPE_ELABORATED;
+}
+
+void
+PCHTypeWriter::VisitSubstTemplateTypeParmType(
+                                        const SubstTemplateTypeParmType *T) {
+  Writer.AddTypeRef(QualType(T->getReplacedParameter(), 0), Record);
+  Writer.AddTypeRef(T->getReplacementType(), Record);
+  Code = pch::TYPE_SUBST_TEMPLATE_TYPE_PARM;
+}
+
+void
+PCHTypeWriter::VisitTemplateSpecializationType(
+                                       const TemplateSpecializationType *T) {
+  // FIXME: Serialize this type (C++ only)
+  assert(false && "Cannot serialize template specialization types");
+}
+
+void PCHTypeWriter::VisitQualifiedNameType(const QualifiedNameType *T) {
+  // FIXME: Serialize this type (C++ only)
+  assert(false && "Cannot serialize qualified name types");
+}
+
+void PCHTypeWriter::VisitInjectedClassNameType(const InjectedClassNameType *T) {
+  Writer.AddDeclRef(T->getDecl(), Record);
+  Writer.AddTypeRef(T->getInjectedSpecializationType(), Record);
+  Code = pch::TYPE_INJECTED_CLASS_NAME;
+}
+
+void PCHTypeWriter::VisitObjCInterfaceType(const ObjCInterfaceType *T) {
+  Writer.AddDeclRef(T->getDecl(), Record);
+  Record.push_back(T->getNumProtocols());
+  for (ObjCInterfaceType::qual_iterator I = T->qual_begin(),
+       E = T->qual_end(); I != E; ++I)
+    Writer.AddDeclRef(*I, Record);
+  Code = pch::TYPE_OBJC_INTERFACE;
+}
+
+void
+PCHTypeWriter::VisitObjCObjectPointerType(const ObjCObjectPointerType *T) {
+  Writer.AddTypeRef(T->getPointeeType(), Record);
+  Record.push_back(T->getNumProtocols());
+  for (ObjCInterfaceType::qual_iterator I = T->qual_begin(),
+       E = T->qual_end(); I != E; ++I)
+    Writer.AddDeclRef(*I, Record);
+  Code = pch::TYPE_OBJC_OBJECT_POINTER;
+}
+
+namespace {
+
+class TypeLocWriter : public TypeLocVisitor<TypeLocWriter> {
+  PCHWriter &Writer;
+  PCHWriter::RecordData &Record;
+
+public:
+  TypeLocWriter(PCHWriter &Writer, PCHWriter::RecordData &Record)
+    : Writer(Writer), Record(Record) { }
+
+#define ABSTRACT_TYPELOC(CLASS, PARENT)
+#define TYPELOC(CLASS, PARENT) \
+    void Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc);
+#include "clang/AST/TypeLocNodes.def"
+
+  void VisitArrayTypeLoc(ArrayTypeLoc TyLoc);
+  void VisitFunctionTypeLoc(FunctionTypeLoc TyLoc);
+};
+
+}
+
+void TypeLocWriter::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
+  // nothing to do
+}
+void TypeLocWriter::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
+  Writer.AddSourceLocation(TL.getBuiltinLoc(), Record);
+  if (TL.needsExtraLocalData()) {
+    Record.push_back(TL.getWrittenTypeSpec());
+    Record.push_back(TL.getWrittenSignSpec());
+    Record.push_back(TL.getWrittenWidthSpec());
+    Record.push_back(TL.hasModeAttr());
+  }
+}
+void TypeLocWriter::VisitComplexTypeLoc(ComplexTypeLoc TL) {
+  Writer.AddSourceLocation(TL.getNameLoc(), Record);
+}
+void TypeLocWriter::VisitPointerTypeLoc(PointerTypeLoc TL) {
+  Writer.AddSourceLocation(TL.getStarLoc(), Record);
+}
+void TypeLocWriter::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
+  Writer.AddSourceLocation(TL.getCaretLoc(), Record);
+}
+void TypeLocWriter::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
+  Writer.AddSourceLocation(TL.getAmpLoc(), Record);
+}
+void TypeLocWriter::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
+  Writer.AddSourceLocation(TL.getAmpAmpLoc(), Record);
+}
+void TypeLocWriter::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
+  Writer.AddSourceLocation(TL.getStarLoc(), Record);
+}
+void TypeLocWriter::VisitArrayTypeLoc(ArrayTypeLoc TL) {
+  Writer.AddSourceLocation(TL.getLBracketLoc(), Record);
+  Writer.AddSourceLocation(TL.getRBracketLoc(), Record);
+  Record.push_back(TL.getSizeExpr() ? 1 : 0);
+  if (TL.getSizeExpr())
+    Writer.AddStmt(TL.getSizeExpr());
+}
+void TypeLocWriter::VisitConstantArrayTypeLoc(ConstantArrayTypeLoc TL) {
+  VisitArrayTypeLoc(TL);
+}
+void TypeLocWriter::VisitIncompleteArrayTypeLoc(IncompleteArrayTypeLoc TL) {
+  VisitArrayTypeLoc(TL);
+}
+void TypeLocWriter::VisitVariableArrayTypeLoc(VariableArrayTypeLoc TL) {
+  VisitArrayTypeLoc(TL);
+}
+void TypeLocWriter::VisitDependentSizedArrayTypeLoc(
+                                            DependentSizedArrayTypeLoc TL) {
+  VisitArrayTypeLoc(TL);
+}
+void TypeLocWriter::VisitDependentSizedExtVectorTypeLoc(
+                                        DependentSizedExtVectorTypeLoc TL) {
+  Writer.AddSourceLocation(TL.getNameLoc(), Record);
+}
+void TypeLocWriter::VisitVectorTypeLoc(VectorTypeLoc TL) {
+  Writer.AddSourceLocation(TL.getNameLoc(), Record);
+}
+void TypeLocWriter::VisitExtVectorTypeLoc(ExtVectorTypeLoc TL) {
+  Writer.AddSourceLocation(TL.getNameLoc(), Record);
+}
+void TypeLocWriter::VisitFunctionTypeLoc(FunctionTypeLoc TL) {
+  Writer.AddSourceLocation(TL.getLParenLoc(), Record);
+  Writer.AddSourceLocation(TL.getRParenLoc(), Record);
+  for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i)
+    Writer.AddDeclRef(TL.getArg(i), Record);
+}
+void TypeLocWriter::VisitFunctionProtoTypeLoc(FunctionProtoTypeLoc TL) {
+  VisitFunctionTypeLoc(TL);
+}
+void TypeLocWriter::VisitFunctionNoProtoTypeLoc(FunctionNoProtoTypeLoc TL) {
+  VisitFunctionTypeLoc(TL);
+}
+void TypeLocWriter::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
+  Writer.AddSourceLocation(TL.getNameLoc(), Record);
+}
+void TypeLocWriter::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
+  Writer.AddSourceLocation(TL.getNameLoc(), Record);
+}
+void TypeLocWriter::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
+  Writer.AddSourceLocation(TL.getTypeofLoc(), Record);
+  Writer.AddSourceLocation(TL.getLParenLoc(), Record);
+  Writer.AddSourceLocation(TL.getRParenLoc(), Record);
+}
+void TypeLocWriter::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
+  Writer.AddSourceLocation(TL.getTypeofLoc(), Record);
+  Writer.AddSourceLocation(TL.getLParenLoc(), Record);
+  Writer.AddSourceLocation(TL.getRParenLoc(), Record);
+  Writer.AddTypeSourceInfo(TL.getUnderlyingTInfo(), Record);
+}
+void TypeLocWriter::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
+  Writer.AddSourceLocation(TL.getNameLoc(), Record);
+}
+void TypeLocWriter::VisitRecordTypeLoc(RecordTypeLoc TL) {
+  Writer.AddSourceLocation(TL.getNameLoc(), Record);
+}
+void TypeLocWriter::VisitEnumTypeLoc(EnumTypeLoc TL) {
+  Writer.AddSourceLocation(TL.getNameLoc(), Record);
+}
+void TypeLocWriter::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
+  Writer.AddSourceLocation(TL.getNameLoc(), Record);
+}
+void TypeLocWriter::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
+  Writer.AddSourceLocation(TL.getNameLoc(), Record);
+}
+void TypeLocWriter::VisitSubstTemplateTypeParmTypeLoc(
+                                            SubstTemplateTypeParmTypeLoc TL) {
+  Writer.AddSourceLocation(TL.getNameLoc(), Record);
+}
+void TypeLocWriter::VisitTemplateSpecializationTypeLoc(
+                                           TemplateSpecializationTypeLoc TL) {
+  Writer.AddSourceLocation(TL.getTemplateNameLoc(), Record);
+  Writer.AddSourceLocation(TL.getLAngleLoc(), Record);
+  Writer.AddSourceLocation(TL.getRAngleLoc(), Record);
+  for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i)
+    Writer.AddTemplateArgumentLoc(TL.getArgLoc(i), Record);
+}
+void TypeLocWriter::VisitQualifiedNameTypeLoc(QualifiedNameTypeLoc TL) {
+  Writer.AddSourceLocation(TL.getNameLoc(), Record);
+}
+void TypeLocWriter::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
+  Writer.AddSourceLocation(TL.getNameLoc(), Record);
+}
+void TypeLocWriter::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
+  Writer.AddSourceLocation(TL.getNameLoc(), Record);
+}
+void TypeLocWriter::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
+  Writer.AddSourceLocation(TL.getNameLoc(), Record);
+  Writer.AddSourceLocation(TL.getLAngleLoc(), Record);
+  Writer.AddSourceLocation(TL.getRAngleLoc(), Record);
+  for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i)
+    Writer.AddSourceLocation(TL.getProtocolLoc(i), Record);
+}
+void TypeLocWriter::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
+  Writer.AddSourceLocation(TL.getStarLoc(), Record);
+  Writer.AddSourceLocation(TL.getLAngleLoc(), Record);
+  Writer.AddSourceLocation(TL.getRAngleLoc(), Record);
+  Record.push_back(TL.hasBaseTypeAsWritten());
+  Record.push_back(TL.hasProtocolsAsWritten());
+  if (TL.hasProtocolsAsWritten())
+    for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i)
+      Writer.AddSourceLocation(TL.getProtocolLoc(i), Record);
+}
+
+//===----------------------------------------------------------------------===//
+// PCHWriter Implementation
+//===----------------------------------------------------------------------===//
+
+static void EmitBlockID(unsigned ID, const char *Name,
+                        llvm::BitstreamWriter &Stream,
+                        PCHWriter::RecordData &Record) {
+  Record.clear();
+  Record.push_back(ID);
+  Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_SETBID, Record);
+
+  // Emit the block name if present.
+  if (Name == 0 || Name[0] == 0) return;
+  Record.clear();
+  while (*Name)
+    Record.push_back(*Name++);
+  Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_BLOCKNAME, Record);
+}
+
+static void EmitRecordID(unsigned ID, const char *Name,
+                         llvm::BitstreamWriter &Stream,
+                         PCHWriter::RecordData &Record) {
+  Record.clear();
+  Record.push_back(ID);
+  while (*Name)
+    Record.push_back(*Name++);
+  Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_SETRECORDNAME, Record);
+}
+
+static void AddStmtsExprs(llvm::BitstreamWriter &Stream,
+                          PCHWriter::RecordData &Record) {
+#define RECORD(X) EmitRecordID(pch::X, #X, Stream, Record)
+  RECORD(STMT_STOP);
+  RECORD(STMT_NULL_PTR);
+  RECORD(STMT_NULL);
+  RECORD(STMT_COMPOUND);
+  RECORD(STMT_CASE);
+  RECORD(STMT_DEFAULT);
+  RECORD(STMT_LABEL);
+  RECORD(STMT_IF);
+  RECORD(STMT_SWITCH);
+  RECORD(STMT_WHILE);
+  RECORD(STMT_DO);
+  RECORD(STMT_FOR);
+  RECORD(STMT_GOTO);
+  RECORD(STMT_INDIRECT_GOTO);
+  RECORD(STMT_CONTINUE);
+  RECORD(STMT_BREAK);
+  RECORD(STMT_RETURN);
+  RECORD(STMT_DECL);
+  RECORD(STMT_ASM);
+  RECORD(EXPR_PREDEFINED);
+  RECORD(EXPR_DECL_REF);
+  RECORD(EXPR_INTEGER_LITERAL);
+  RECORD(EXPR_FLOATING_LITERAL);
+  RECORD(EXPR_IMAGINARY_LITERAL);
+  RECORD(EXPR_STRING_LITERAL);
+  RECORD(EXPR_CHARACTER_LITERAL);
+  RECORD(EXPR_PAREN);
+  RECORD(EXPR_UNARY_OPERATOR);
+  RECORD(EXPR_SIZEOF_ALIGN_OF);
+  RECORD(EXPR_ARRAY_SUBSCRIPT);
+  RECORD(EXPR_CALL);
+  RECORD(EXPR_MEMBER);
+  RECORD(EXPR_BINARY_OPERATOR);
+  RECORD(EXPR_COMPOUND_ASSIGN_OPERATOR);
+  RECORD(EXPR_CONDITIONAL_OPERATOR);
+  RECORD(EXPR_IMPLICIT_CAST);
+  RECORD(EXPR_CSTYLE_CAST);
+  RECORD(EXPR_COMPOUND_LITERAL);
+  RECORD(EXPR_EXT_VECTOR_ELEMENT);
+  RECORD(EXPR_INIT_LIST);
+  RECORD(EXPR_DESIGNATED_INIT);
+  RECORD(EXPR_IMPLICIT_VALUE_INIT);
+  RECORD(EXPR_VA_ARG);
+  RECORD(EXPR_ADDR_LABEL);
+  RECORD(EXPR_STMT);
+  RECORD(EXPR_TYPES_COMPATIBLE);
+  RECORD(EXPR_CHOOSE);
+  RECORD(EXPR_GNU_NULL);
+  RECORD(EXPR_SHUFFLE_VECTOR);
+  RECORD(EXPR_BLOCK);
+  RECORD(EXPR_BLOCK_DECL_REF);
+  RECORD(EXPR_OBJC_STRING_LITERAL);
+  RECORD(EXPR_OBJC_ENCODE);
+  RECORD(EXPR_OBJC_SELECTOR_EXPR);
+  RECORD(EXPR_OBJC_PROTOCOL_EXPR);
+  RECORD(EXPR_OBJC_IVAR_REF_EXPR);
+  RECORD(EXPR_OBJC_PROPERTY_REF_EXPR);
+  RECORD(EXPR_OBJC_KVC_REF_EXPR);
+  RECORD(EXPR_OBJC_MESSAGE_EXPR);
+  RECORD(EXPR_OBJC_SUPER_EXPR);
+  RECORD(STMT_OBJC_FOR_COLLECTION);
+  RECORD(STMT_OBJC_CATCH);
+  RECORD(STMT_OBJC_FINALLY);
+  RECORD(STMT_OBJC_AT_TRY);
+  RECORD(STMT_OBJC_AT_SYNCHRONIZED);
+  RECORD(STMT_OBJC_AT_THROW);
+  RECORD(EXPR_CXX_OPERATOR_CALL);
+  RECORD(EXPR_CXX_CONSTRUCT);
+  RECORD(EXPR_CXX_STATIC_CAST);
+  RECORD(EXPR_CXX_DYNAMIC_CAST);
+  RECORD(EXPR_CXX_REINTERPRET_CAST);
+  RECORD(EXPR_CXX_CONST_CAST);
+  RECORD(EXPR_CXX_FUNCTIONAL_CAST);
+  RECORD(EXPR_CXX_BOOL_LITERAL);
+  RECORD(EXPR_CXX_NULL_PTR_LITERAL);
+#undef RECORD
+}
+
+void PCHWriter::WriteBlockInfoBlock() {
+  RecordData Record;
+  Stream.EnterSubblock(llvm::bitc::BLOCKINFO_BLOCK_ID, 3);
+
+#define BLOCK(X) EmitBlockID(pch::X ## _ID, #X, Stream, Record)
+#define RECORD(X) EmitRecordID(pch::X, #X, Stream, Record)
+
+  // PCH Top-Level Block.
+  BLOCK(PCH_BLOCK);
+  RECORD(ORIGINAL_FILE_NAME);
+  RECORD(TYPE_OFFSET);
+  RECORD(DECL_OFFSET);
+  RECORD(LANGUAGE_OPTIONS);
+  RECORD(METADATA);
+  RECORD(IDENTIFIER_OFFSET);
+  RECORD(IDENTIFIER_TABLE);
+  RECORD(EXTERNAL_DEFINITIONS);
+  RECORD(SPECIAL_TYPES);
+  RECORD(STATISTICS);
+  RECORD(TENTATIVE_DEFINITIONS);
+  RECORD(UNUSED_STATIC_FUNCS);
+  RECORD(LOCALLY_SCOPED_EXTERNAL_DECLS);
+  RECORD(SELECTOR_OFFSETS);
+  RECORD(METHOD_POOL);
+  RECORD(PP_COUNTER_VALUE);
+  RECORD(SOURCE_LOCATION_OFFSETS);
+  RECORD(SOURCE_LOCATION_PRELOADS);
+  RECORD(STAT_CACHE);
+  RECORD(EXT_VECTOR_DECLS);
+  RECORD(VERSION_CONTROL_BRANCH_REVISION);
+  RECORD(UNUSED_STATIC_FUNCS);
+  RECORD(MACRO_DEFINITION_OFFSETS);
+  
+  // SourceManager Block.
+  BLOCK(SOURCE_MANAGER_BLOCK);
+  RECORD(SM_SLOC_FILE_ENTRY);
+  RECORD(SM_SLOC_BUFFER_ENTRY);
+  RECORD(SM_SLOC_BUFFER_BLOB);
+  RECORD(SM_SLOC_INSTANTIATION_ENTRY);
+  RECORD(SM_LINE_TABLE);
+
+  // Preprocessor Block.
+  BLOCK(PREPROCESSOR_BLOCK);
+  RECORD(PP_MACRO_OBJECT_LIKE);
+  RECORD(PP_MACRO_FUNCTION_LIKE);
+  RECORD(PP_TOKEN);
+  RECORD(PP_MACRO_INSTANTIATION);
+  RECORD(PP_MACRO_DEFINITION);
+  
+  // Decls and Types block.
+  BLOCK(DECLTYPES_BLOCK);
+  RECORD(TYPE_EXT_QUAL);
+  RECORD(TYPE_COMPLEX);
+  RECORD(TYPE_POINTER);
+  RECORD(TYPE_BLOCK_POINTER);
+  RECORD(TYPE_LVALUE_REFERENCE);
+  RECORD(TYPE_RVALUE_REFERENCE);
+  RECORD(TYPE_MEMBER_POINTER);
+  RECORD(TYPE_CONSTANT_ARRAY);
+  RECORD(TYPE_INCOMPLETE_ARRAY);
+  RECORD(TYPE_VARIABLE_ARRAY);
+  RECORD(TYPE_VECTOR);
+  RECORD(TYPE_EXT_VECTOR);
+  RECORD(TYPE_FUNCTION_PROTO);
+  RECORD(TYPE_FUNCTION_NO_PROTO);
+  RECORD(TYPE_TYPEDEF);
+  RECORD(TYPE_TYPEOF_EXPR);
+  RECORD(TYPE_TYPEOF);
+  RECORD(TYPE_RECORD);
+  RECORD(TYPE_ENUM);
+  RECORD(TYPE_OBJC_INTERFACE);
+  RECORD(TYPE_OBJC_OBJECT_POINTER);
+  RECORD(DECL_ATTR);
+  RECORD(DECL_TRANSLATION_UNIT);
+  RECORD(DECL_TYPEDEF);
+  RECORD(DECL_ENUM);
+  RECORD(DECL_RECORD);
+  RECORD(DECL_ENUM_CONSTANT);
+  RECORD(DECL_FUNCTION);
+  RECORD(DECL_OBJC_METHOD);
+  RECORD(DECL_OBJC_INTERFACE);
+  RECORD(DECL_OBJC_PROTOCOL);
+  RECORD(DECL_OBJC_IVAR);
+  RECORD(DECL_OBJC_AT_DEFS_FIELD);
+  RECORD(DECL_OBJC_CLASS);
+  RECORD(DECL_OBJC_FORWARD_PROTOCOL);
+  RECORD(DECL_OBJC_CATEGORY);
+  RECORD(DECL_OBJC_CATEGORY_IMPL);
+  RECORD(DECL_OBJC_IMPLEMENTATION);
+  RECORD(DECL_OBJC_COMPATIBLE_ALIAS);
+  RECORD(DECL_OBJC_PROPERTY);
+  RECORD(DECL_OBJC_PROPERTY_IMPL);
+  RECORD(DECL_FIELD);
+  RECORD(DECL_VAR);
+  RECORD(DECL_IMPLICIT_PARAM);
+  RECORD(DECL_PARM_VAR);
+  RECORD(DECL_FILE_SCOPE_ASM);
+  RECORD(DECL_BLOCK);
+  RECORD(DECL_CONTEXT_LEXICAL);
+  RECORD(DECL_CONTEXT_VISIBLE);
+  // Statements and Exprs can occur in the Decls and Types block.
+  AddStmtsExprs(Stream, Record);
+#undef RECORD
+#undef BLOCK
+  Stream.ExitBlock();
+}
+
+/// \brief Adjusts the given filename to only write out the portion of the
+/// filename that is not part of the system root directory.
+///
+/// \param Filename the file name to adjust.
+///
+/// \param isysroot When non-NULL, the PCH file is a relocatable PCH file and
+/// the returned filename will be adjusted by this system root.
+///
+/// \returns either the original filename (if it needs no adjustment) or the
+/// adjusted filename (which points into the @p Filename parameter).
+static const char *
+adjustFilenameForRelocatablePCH(const char *Filename, const char *isysroot) {
+  assert(Filename && "No file name to adjust?");
+
+  if (!isysroot)
+    return Filename;
+
+  // Verify that the filename and the system root have the same prefix.
+  unsigned Pos = 0;
+  for (; Filename[Pos] && isysroot[Pos]; ++Pos)
+    if (Filename[Pos] != isysroot[Pos])
+      return Filename; // Prefixes don't match.
+
+  // We hit the end of the filename before we hit the end of the system root.
+  if (!Filename[Pos])
+    return Filename;
+
+  // If the file name has a '/' at the current position, skip over the '/'.
+  // We distinguish sysroot-based includes from absolute includes by the
+  // absence of '/' at the beginning of sysroot-based includes.
+  if (Filename[Pos] == '/')
+    ++Pos;
+
+  return Filename + Pos;
+}
+
+/// \brief Write the PCH metadata (e.g., i686-apple-darwin9).
+void PCHWriter::WriteMetadata(ASTContext &Context, const char *isysroot) {
+  using namespace llvm;
+
+  // Metadata
+  const TargetInfo &Target = Context.Target;
+  BitCodeAbbrev *MetaAbbrev = new BitCodeAbbrev();
+  MetaAbbrev->Add(BitCodeAbbrevOp(pch::METADATA));
+  MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // PCH major
+  MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // PCH minor
+  MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // Clang major
+  MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // Clang minor
+  MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Relocatable
+  MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Target triple
+  unsigned MetaAbbrevCode = Stream.EmitAbbrev(MetaAbbrev);
+
+  RecordData Record;
+  Record.push_back(pch::METADATA);
+  Record.push_back(pch::VERSION_MAJOR);
+  Record.push_back(pch::VERSION_MINOR);
+  Record.push_back(CLANG_VERSION_MAJOR);
+  Record.push_back(CLANG_VERSION_MINOR);
+  Record.push_back(isysroot != 0);
+  const std::string &TripleStr = Target.getTriple().getTriple();
+  Stream.EmitRecordWithBlob(MetaAbbrevCode, Record, TripleStr);
+
+  // Original file name
+  SourceManager &SM = Context.getSourceManager();
+  if (const FileEntry *MainFile = SM.getFileEntryForID(SM.getMainFileID())) {
+    BitCodeAbbrev *FileAbbrev = new BitCodeAbbrev();
+    FileAbbrev->Add(BitCodeAbbrevOp(pch::ORIGINAL_FILE_NAME));
+    FileAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // File name
+    unsigned FileAbbrevCode = Stream.EmitAbbrev(FileAbbrev);
+
+    llvm::sys::Path MainFilePath(MainFile->getName());
+
+    MainFilePath.makeAbsolute();
+
+    const char *MainFileNameStr = MainFilePath.c_str();
+    MainFileNameStr = adjustFilenameForRelocatablePCH(MainFileNameStr,
+                                                      isysroot);
+    RecordData Record;
+    Record.push_back(pch::ORIGINAL_FILE_NAME);
+    Stream.EmitRecordWithBlob(FileAbbrevCode, Record, MainFileNameStr);
+  }
+
+  // Repository branch/version information.
+  BitCodeAbbrev *RepoAbbrev = new BitCodeAbbrev();
+  RepoAbbrev->Add(BitCodeAbbrevOp(pch::VERSION_CONTROL_BRANCH_REVISION));
+  RepoAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // SVN branch/tag
+  unsigned RepoAbbrevCode = Stream.EmitAbbrev(RepoAbbrev);
+  Record.clear();
+  Record.push_back(pch::VERSION_CONTROL_BRANCH_REVISION);
+  Stream.EmitRecordWithBlob(RepoAbbrevCode, Record,
+                            getClangFullRepositoryVersion());
+}
+
+/// \brief Write the LangOptions structure.
+void PCHWriter::WriteLanguageOptions(const LangOptions &LangOpts) {
+  RecordData Record;
+  Record.push_back(LangOpts.Trigraphs);
+  Record.push_back(LangOpts.BCPLComment);  // BCPL-style '//' comments.
+  Record.push_back(LangOpts.DollarIdents);  // '$' allowed in identifiers.
+  Record.push_back(LangOpts.AsmPreprocessor);  // Preprocessor in asm mode.
+  Record.push_back(LangOpts.GNUMode);  // True in gnu99 mode false in c99 mode (etc)
+  Record.push_back(LangOpts.GNUKeywords);  // Allow GNU-extension keywords
+  Record.push_back(LangOpts.ImplicitInt);  // C89 implicit 'int'.
+  Record.push_back(LangOpts.Digraphs);  // C94, C99 and C++
+  Record.push_back(LangOpts.HexFloats);  // C99 Hexadecimal float constants.
+  Record.push_back(LangOpts.C99);  // C99 Support
+  Record.push_back(LangOpts.Microsoft);  // Microsoft extensions.
+  Record.push_back(LangOpts.CPlusPlus);  // C++ Support
+  Record.push_back(LangOpts.CPlusPlus0x);  // C++0x Support
+  Record.push_back(LangOpts.CXXOperatorNames);  // Treat C++ operator names as keywords.
+
+  Record.push_back(LangOpts.ObjC1);  // Objective-C 1 support enabled.
+  Record.push_back(LangOpts.ObjC2);  // Objective-C 2 support enabled.
+  Record.push_back(LangOpts.ObjCNonFragileABI);  // Objective-C
+                                                 // modern abi enabled.
+  Record.push_back(LangOpts.ObjCNonFragileABI2); // Objective-C enhanced
+                                                 // modern abi enabled.
+  Record.push_back(LangOpts.NoConstantCFStrings); // non cfstring generation enabled..
+
+  Record.push_back(LangOpts.PascalStrings);  // Allow Pascal strings
+  Record.push_back(LangOpts.WritableStrings);  // Allow writable strings
+  Record.push_back(LangOpts.LaxVectorConversions);
+  Record.push_back(LangOpts.AltiVec);
+  Record.push_back(LangOpts.Exceptions);  // Support exception handling.
+  Record.push_back(LangOpts.SjLjExceptions);
+
+  Record.push_back(LangOpts.NeXTRuntime); // Use NeXT runtime.
+  Record.push_back(LangOpts.Freestanding); // Freestanding implementation
+  Record.push_back(LangOpts.NoBuiltin); // Do not use builtin functions (-fno-builtin)
+
+  // Whether static initializers are protected by locks.
+  Record.push_back(LangOpts.ThreadsafeStatics);
+  Record.push_back(LangOpts.POSIXThreads);
+  Record.push_back(LangOpts.Blocks); // block extension to C
+  Record.push_back(LangOpts.EmitAllDecls); // Emit all declarations, even if
+                                  // they are unused.
+  Record.push_back(LangOpts.MathErrno); // Math functions must respect errno
+                                  // (modulo the platform support).
+
+  Record.push_back(LangOpts.OverflowChecking); // Extension to call a handler function when
+                                  // signed integer arithmetic overflows.
+
+  Record.push_back(LangOpts.HeinousExtensions); // Extensions that we really don't like and
+                                  // may be ripped out at any time.
+
+  Record.push_back(LangOpts.Optimize); // Whether __OPTIMIZE__ should be defined.
+  Record.push_back(LangOpts.OptimizeSize); // Whether __OPTIMIZE_SIZE__ should be
+                                  // defined.
+  Record.push_back(LangOpts.Static); // Should __STATIC__ be defined (as
+                                  // opposed to __DYNAMIC__).
+  Record.push_back(LangOpts.PICLevel); // The value for __PIC__, if non-zero.
+
+  Record.push_back(LangOpts.GNUInline); // Should GNU inline semantics be
+                                  // used (instead of C99 semantics).
+  Record.push_back(LangOpts.NoInline); // Should __NO_INLINE__ be defined.
+  Record.push_back(LangOpts.AccessControl); // Whether C++ access control should
+                                            // be enabled.
+  Record.push_back(LangOpts.CharIsSigned); // Whether char is a signed or
+                                           // unsigned type
+  Record.push_back(LangOpts.ShortWChar);  // force wchar_t to be unsigned short
+  Record.push_back(LangOpts.getGCMode());
+  Record.push_back(LangOpts.getVisibilityMode());
+  Record.push_back(LangOpts.getStackProtectorMode());
+  Record.push_back(LangOpts.InstantiationDepth);
+  Record.push_back(LangOpts.OpenCL);
+  Record.push_back(LangOpts.CatchUndefined);
+  Record.push_back(LangOpts.ElideConstructors);
+  Stream.EmitRecord(pch::LANGUAGE_OPTIONS, Record);
+}
+
+//===----------------------------------------------------------------------===//
+// stat cache Serialization
+//===----------------------------------------------------------------------===//
+
+namespace {
+// Trait used for the on-disk hash table of stat cache results.
+class PCHStatCacheTrait {
+public:
+  typedef const char * key_type;
+  typedef key_type key_type_ref;
+
+  typedef std::pair<int, struct stat> data_type;
+  typedef const data_type& data_type_ref;
+
+  static unsigned ComputeHash(const char *path) {
+    return llvm::HashString(path);
+  }
+
+  std::pair<unsigned,unsigned>
+    EmitKeyDataLength(llvm::raw_ostream& Out, const char *path,
+                      data_type_ref Data) {
+    unsigned StrLen = strlen(path);
+    clang::io::Emit16(Out, StrLen);
+    unsigned DataLen = 1; // result value
+    if (Data.first == 0)
+      DataLen += 4 + 4 + 2 + 8 + 8;
+    clang::io::Emit8(Out, DataLen);
+    return std::make_pair(StrLen + 1, DataLen);
+  }
+
+  void EmitKey(llvm::raw_ostream& Out, const char *path, unsigned KeyLen) {
+    Out.write(path, KeyLen);
+  }
+
+  void EmitData(llvm::raw_ostream& Out, key_type_ref,
+                data_type_ref Data, unsigned DataLen) {
+    using namespace clang::io;
+    uint64_t Start = Out.tell(); (void)Start;
+
+    // Result of stat()
+    Emit8(Out, Data.first? 1 : 0);
+
+    if (Data.first == 0) {
+      Emit32(Out, (uint32_t) Data.second.st_ino);
+      Emit32(Out, (uint32_t) Data.second.st_dev);
+      Emit16(Out, (uint16_t) Data.second.st_mode);
+      Emit64(Out, (uint64_t) Data.second.st_mtime);
+      Emit64(Out, (uint64_t) Data.second.st_size);
+    }
+
+    assert(Out.tell() - Start == DataLen && "Wrong data length");
+  }
+};
+} // end anonymous namespace
+
+/// \brief Write the stat() system call cache to the PCH file.
+void PCHWriter::WriteStatCache(MemorizeStatCalls &StatCalls,
+                               const char *isysroot) {
+  // Build the on-disk hash table containing information about every
+  // stat() call.
+  OnDiskChainedHashTableGenerator<PCHStatCacheTrait> Generator;
+  unsigned NumStatEntries = 0;
+  for (MemorizeStatCalls::iterator Stat = StatCalls.begin(),
+                                StatEnd = StatCalls.end();
+       Stat != StatEnd; ++Stat, ++NumStatEntries) {
+    const char *Filename = Stat->first();
+    Filename = adjustFilenameForRelocatablePCH(Filename, isysroot);
+    Generator.insert(Filename, Stat->second);
+  }
+
+  // Create the on-disk hash table in a buffer.
+  llvm::SmallString<4096> StatCacheData;
+  uint32_t BucketOffset;
+  {
+    llvm::raw_svector_ostream Out(StatCacheData);
+    // Make sure that no bucket is at offset 0
+    clang::io::Emit32(Out, 0);
+    BucketOffset = Generator.Emit(Out);
+  }
+
+  // Create a blob abbreviation
+  using namespace llvm;
+  BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
+  Abbrev->Add(BitCodeAbbrevOp(pch::STAT_CACHE));
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
+  unsigned StatCacheAbbrev = Stream.EmitAbbrev(Abbrev);
+
+  // Write the stat cache
+  RecordData Record;
+  Record.push_back(pch::STAT_CACHE);
+  Record.push_back(BucketOffset);
+  Record.push_back(NumStatEntries);
+  Stream.EmitRecordWithBlob(StatCacheAbbrev, Record, StatCacheData.str());
+}
+
+//===----------------------------------------------------------------------===//
+// Source Manager Serialization
+//===----------------------------------------------------------------------===//
+
+/// \brief Create an abbreviation for the SLocEntry that refers to a
+/// file.
+static unsigned CreateSLocFileAbbrev(llvm::BitstreamWriter &Stream) {
+  using namespace llvm;
+  BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
+  Abbrev->Add(BitCodeAbbrevOp(pch::SM_SLOC_FILE_ENTRY));
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Offset
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Include location
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // Characteristic
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Line directives
+  // FileEntry fields.
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 12)); // Size
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 32)); // Modification time
+  // HeaderFileInfo fields.
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isImport
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // DirInfo
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // NumIncludes
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // ControllingMacro
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // File name
+  return Stream.EmitAbbrev(Abbrev);
+}
+
+/// \brief Create an abbreviation for the SLocEntry that refers to a
+/// buffer.
+static unsigned CreateSLocBufferAbbrev(llvm::BitstreamWriter &Stream) {
+  using namespace llvm;
+  BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
+  Abbrev->Add(BitCodeAbbrevOp(pch::SM_SLOC_BUFFER_ENTRY));
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Offset
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Include location
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // Characteristic
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Line directives
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Buffer name blob
+  return Stream.EmitAbbrev(Abbrev);
+}
+
+/// \brief Create an abbreviation for the SLocEntry that refers to a
+/// buffer's blob.
+static unsigned CreateSLocBufferBlobAbbrev(llvm::BitstreamWriter &Stream) {
+  using namespace llvm;
+  BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
+  Abbrev->Add(BitCodeAbbrevOp(pch::SM_SLOC_BUFFER_BLOB));
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Blob
+  return Stream.EmitAbbrev(Abbrev);
+}
+
+/// \brief Create an abbreviation for the SLocEntry that refers to an
+/// buffer.
+static unsigned CreateSLocInstantiationAbbrev(llvm::BitstreamWriter &Stream) {
+  using namespace llvm;
+  BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
+  Abbrev->Add(BitCodeAbbrevOp(pch::SM_SLOC_INSTANTIATION_ENTRY));
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Offset
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Spelling location
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Start location
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // End location
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Token length
+  return Stream.EmitAbbrev(Abbrev);
+}
+
+/// \brief Writes the block containing the serialized form of the
+/// source manager.
+///
+/// TODO: We should probably use an on-disk hash table (stored in a
+/// blob), indexed based on the file name, so that we only create
+/// entries for files that we actually need. In the common case (no
+/// errors), we probably won't have to create file entries for any of
+/// the files in the AST.
+void PCHWriter::WriteSourceManagerBlock(SourceManager &SourceMgr,
+                                        const Preprocessor &PP,
+                                        const char *isysroot) {
+  RecordData Record;
+
+  // Enter the source manager block.
+  Stream.EnterSubblock(pch::SOURCE_MANAGER_BLOCK_ID, 3);
+
+  // Abbreviations for the various kinds of source-location entries.
+  unsigned SLocFileAbbrv = CreateSLocFileAbbrev(Stream);
+  unsigned SLocBufferAbbrv = CreateSLocBufferAbbrev(Stream);
+  unsigned SLocBufferBlobAbbrv = CreateSLocBufferBlobAbbrev(Stream);
+  unsigned SLocInstantiationAbbrv = CreateSLocInstantiationAbbrev(Stream);
+
+  // Write the line table.
+  if (SourceMgr.hasLineTable()) {
+    LineTableInfo &LineTable = SourceMgr.getLineTable();
+
+    // Emit the file names
+    Record.push_back(LineTable.getNumFilenames());
+    for (unsigned I = 0, N = LineTable.getNumFilenames(); I != N; ++I) {
+      // Emit the file name
+      const char *Filename = LineTable.getFilename(I);
+      Filename = adjustFilenameForRelocatablePCH(Filename, isysroot);
+      unsigned FilenameLen = Filename? strlen(Filename) : 0;
+      Record.push_back(FilenameLen);
+      if (FilenameLen)
+        Record.insert(Record.end(), Filename, Filename + FilenameLen);
+    }
+
+    // Emit the line entries
+    for (LineTableInfo::iterator L = LineTable.begin(), LEnd = LineTable.end();
+         L != LEnd; ++L) {
+      // Emit the file ID
+      Record.push_back(L->first);
+
+      // Emit the line entries
+      Record.push_back(L->second.size());
+      for (std::vector<LineEntry>::iterator LE = L->second.begin(),
+                                         LEEnd = L->second.end();
+           LE != LEEnd; ++LE) {
+        Record.push_back(LE->FileOffset);
+        Record.push_back(LE->LineNo);
+        Record.push_back(LE->FilenameID);
+        Record.push_back((unsigned)LE->FileKind);
+        Record.push_back(LE->IncludeOffset);
+      }
+    }
+    Stream.EmitRecord(pch::SM_LINE_TABLE, Record);
+  }
+
+  // Write out the source location entry table. We skip the first
+  // entry, which is always the same dummy entry.
+  std::vector<uint32_t> SLocEntryOffsets;
+  RecordData PreloadSLocs;
+  SLocEntryOffsets.reserve(SourceMgr.sloc_entry_size() - 1);
+  for (unsigned I = 1, N = SourceMgr.sloc_entry_size(); I != N; ++I) {
+    // Get this source location entry.
+    const SrcMgr::SLocEntry *SLoc = &SourceMgr.getSLocEntry(I);
+
+    // Record the offset of this source-location entry.
+    SLocEntryOffsets.push_back(Stream.GetCurrentBitNo());
+
+    // Figure out which record code to use.
+    unsigned Code;
+    if (SLoc->isFile()) {
+      if (SLoc->getFile().getContentCache()->Entry)
+        Code = pch::SM_SLOC_FILE_ENTRY;
+      else
+        Code = pch::SM_SLOC_BUFFER_ENTRY;
+    } else
+      Code = pch::SM_SLOC_INSTANTIATION_ENTRY;
+    Record.clear();
+    Record.push_back(Code);
+
+    Record.push_back(SLoc->getOffset());
+    if (SLoc->isFile()) {
+      const SrcMgr::FileInfo &File = SLoc->getFile();
+      Record.push_back(File.getIncludeLoc().getRawEncoding());
+      Record.push_back(File.getFileCharacteristic()); // FIXME: stable encoding
+      Record.push_back(File.hasLineDirectives());
+
+      const SrcMgr::ContentCache *Content = File.getContentCache();
+      if (Content->Entry) {
+        // The source location entry is a file. The blob associated
+        // with this entry is the file name.
+
+        // Emit size/modification time for this file.
+        Record.push_back(Content->Entry->getSize());
+        Record.push_back(Content->Entry->getModificationTime());
+
+        // Emit header-search information associated with this file.
+        HeaderFileInfo HFI;
+        HeaderSearch &HS = PP.getHeaderSearchInfo();
+        if (Content->Entry->getUID() < HS.header_file_size())
+          HFI = HS.header_file_begin()[Content->Entry->getUID()];
+        Record.push_back(HFI.isImport);
+        Record.push_back(HFI.DirInfo);
+        Record.push_back(HFI.NumIncludes);
+        AddIdentifierRef(HFI.ControllingMacro, Record);
+
+        // Turn the file name into an absolute path, if it isn't already.
+        const char *Filename = Content->Entry->getName();
+        llvm::sys::Path FilePath(Filename, strlen(Filename));
+        FilePath.makeAbsolute();
+        Filename = FilePath.c_str();
+
+        Filename = adjustFilenameForRelocatablePCH(Filename, isysroot);
+        Stream.EmitRecordWithBlob(SLocFileAbbrv, Record, Filename);
+
+        // FIXME: For now, preload all file source locations, so that
+        // we get the appropriate File entries in the reader. This is
+        // a temporary measure.
+        PreloadSLocs.push_back(SLocEntryOffsets.size());
+      } else {
+        // The source location entry is a buffer. The blob associated
+        // with this entry contains the contents of the buffer.
+
+        // We add one to the size so that we capture the trailing NULL
+        // that is required by llvm::MemoryBuffer::getMemBuffer (on
+        // the reader side).
+        const llvm::MemoryBuffer *Buffer
+          = Content->getBuffer(PP.getDiagnostics(), PP.getSourceManager());
+        const char *Name = Buffer->getBufferIdentifier();
+        Stream.EmitRecordWithBlob(SLocBufferAbbrv, Record,
+                                  llvm::StringRef(Name, strlen(Name) + 1));
+        Record.clear();
+        Record.push_back(pch::SM_SLOC_BUFFER_BLOB);
+        Stream.EmitRecordWithBlob(SLocBufferBlobAbbrv, Record,
+                                  llvm::StringRef(Buffer->getBufferStart(),
+                                                  Buffer->getBufferSize() + 1));
+
+        if (strcmp(Name, "<built-in>") == 0)
+          PreloadSLocs.push_back(SLocEntryOffsets.size());
+      }
+    } else {
+      // The source location entry is an instantiation.
+      const SrcMgr::InstantiationInfo &Inst = SLoc->getInstantiation();
+      Record.push_back(Inst.getSpellingLoc().getRawEncoding());
+      Record.push_back(Inst.getInstantiationLocStart().getRawEncoding());
+      Record.push_back(Inst.getInstantiationLocEnd().getRawEncoding());
+
+      // Compute the token length for this macro expansion.
+      unsigned NextOffset = SourceMgr.getNextOffset();
+      if (I + 1 != N)
+        NextOffset = SourceMgr.getSLocEntry(I + 1).getOffset();
+      Record.push_back(NextOffset - SLoc->getOffset() - 1);
+      Stream.EmitRecordWithAbbrev(SLocInstantiationAbbrv, Record);
+    }
+  }
+
+  Stream.ExitBlock();
+
+  if (SLocEntryOffsets.empty())
+    return;
+
+  // Write the source-location offsets table into the PCH block. This
+  // table is used for lazily loading source-location information.
+  using namespace llvm;
+  BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
+  Abbrev->Add(BitCodeAbbrevOp(pch::SOURCE_LOCATION_OFFSETS));
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 16)); // # of slocs
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 16)); // next offset
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // offsets
+  unsigned SLocOffsetsAbbrev = Stream.EmitAbbrev(Abbrev);
+
+  Record.clear();
+  Record.push_back(pch::SOURCE_LOCATION_OFFSETS);
+  Record.push_back(SLocEntryOffsets.size());
+  Record.push_back(SourceMgr.getNextOffset());
+  Stream.EmitRecordWithBlob(SLocOffsetsAbbrev, Record,
+                            (const char *)&SLocEntryOffsets.front(),
+                           SLocEntryOffsets.size()*sizeof(SLocEntryOffsets[0]));
+
+  // Write the source location entry preloads array, telling the PCH
+  // reader which source locations entries it should load eagerly.
+  Stream.EmitRecord(pch::SOURCE_LOCATION_PRELOADS, PreloadSLocs);
+}
+
+//===----------------------------------------------------------------------===//
+// Preprocessor Serialization
+//===----------------------------------------------------------------------===//
+
+/// \brief Writes the block containing the serialized form of the
+/// preprocessor.
+///
+void PCHWriter::WritePreprocessor(const Preprocessor &PP) {
+  RecordData Record;
+
+  // If the preprocessor __COUNTER__ value has been bumped, remember it.
+  if (PP.getCounterValue() != 0) {
+    Record.push_back(PP.getCounterValue());
+    Stream.EmitRecord(pch::PP_COUNTER_VALUE, Record);
+    Record.clear();
+  }
+
+  // Enter the preprocessor block.
+  Stream.EnterSubblock(pch::PREPROCESSOR_BLOCK_ID, 2);
+
+  // If the PCH file contains __DATE__ or __TIME__ emit a warning about this.
+  // FIXME: use diagnostics subsystem for localization etc.
+  if (PP.SawDateOrTime())
+    fprintf(stderr, "warning: precompiled header used __DATE__ or __TIME__.\n");
+
+  // Loop over all the macro definitions that are live at the end of the file,
+  // emitting each to the PP section.
+  PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
+  for (Preprocessor::macro_iterator I = PP.macro_begin(), E = PP.macro_end();
+       I != E; ++I) {
+    // FIXME: This emits macros in hash table order, we should do it in a stable
+    // order so that output is reproducible.
+    MacroInfo *MI = I->second;
+
+    // Don't emit builtin macros like __LINE__ to the PCH file unless they have
+    // been redefined by the header (in which case they are not isBuiltinMacro).
+    if (MI->isBuiltinMacro())
+      continue;
+
+    AddIdentifierRef(I->first, Record);
+    MacroOffsets[I->first] = Stream.GetCurrentBitNo();
+    Record.push_back(MI->getDefinitionLoc().getRawEncoding());
+    Record.push_back(MI->isUsed());
+
+    unsigned Code;
+    if (MI->isObjectLike()) {
+      Code = pch::PP_MACRO_OBJECT_LIKE;
+    } else {
+      Code = pch::PP_MACRO_FUNCTION_LIKE;
+
+      Record.push_back(MI->isC99Varargs());
+      Record.push_back(MI->isGNUVarargs());
+      Record.push_back(MI->getNumArgs());
+      for (MacroInfo::arg_iterator I = MI->arg_begin(), E = MI->arg_end();
+           I != E; ++I)
+        AddIdentifierRef(*I, Record);
+    }
+    
+    // If we have a detailed preprocessing record, record the macro definition
+    // ID that corresponds to this macro.
+    if (PPRec)
+      Record.push_back(getMacroDefinitionID(PPRec->findMacroDefinition(MI)));
+    
+    Stream.EmitRecord(Code, Record);
+    Record.clear();
+
+    // Emit the tokens array.
+    for (unsigned TokNo = 0, e = MI->getNumTokens(); TokNo != e; ++TokNo) {
+      // Note that we know that the preprocessor does not have any annotation
+      // tokens in it because they are created by the parser, and thus can't be
+      // in a macro definition.
+      const Token &Tok = MI->getReplacementToken(TokNo);
+
+      Record.push_back(Tok.getLocation().getRawEncoding());
+      Record.push_back(Tok.getLength());
+
+      // FIXME: When reading literal tokens, reconstruct the literal pointer if
+      // it is needed.
+      AddIdentifierRef(Tok.getIdentifierInfo(), Record);
+
+      // FIXME: Should translate token kind to a stable encoding.
+      Record.push_back(Tok.getKind());
+      // FIXME: Should translate token flags to a stable encoding.
+      Record.push_back(Tok.getFlags());
+
+      Stream.EmitRecord(pch::PP_TOKEN, Record);
+      Record.clear();
+    }
+    ++NumMacros;
+  }
+  
+  // If the preprocessor has a preprocessing record, emit it.
+  unsigned NumPreprocessingRecords = 0;
+  if (PPRec) {
+    for (PreprocessingRecord::iterator E = PPRec->begin(), EEnd = PPRec->end();
+         E != EEnd; ++E) {
+      Record.clear();
+      
+      if (MacroInstantiation *MI = dyn_cast<MacroInstantiation>(*E)) {
+        Record.push_back(NumPreprocessingRecords++);
+        AddSourceLocation(MI->getSourceRange().getBegin(), Record);
+        AddSourceLocation(MI->getSourceRange().getEnd(), Record);
+        AddIdentifierRef(MI->getName(), Record);
+        Record.push_back(getMacroDefinitionID(MI->getDefinition()));
+        Stream.EmitRecord(pch::PP_MACRO_INSTANTIATION, Record);
+        continue;
+      }
+      
+      if (MacroDefinition *MD = dyn_cast<MacroDefinition>(*E)) {
+        // Record this macro definition's location.
+        pch::IdentID ID = getMacroDefinitionID(MD);
+        if (ID != MacroDefinitionOffsets.size()) {
+          if (ID > MacroDefinitionOffsets.size())
+            MacroDefinitionOffsets.resize(ID + 1);
+          
+          MacroDefinitionOffsets[ID] = Stream.GetCurrentBitNo();            
+        } else
+          MacroDefinitionOffsets.push_back(Stream.GetCurrentBitNo());
+        
+        Record.push_back(NumPreprocessingRecords++);
+        Record.push_back(ID);
+        AddSourceLocation(MD->getSourceRange().getBegin(), Record);
+        AddSourceLocation(MD->getSourceRange().getEnd(), Record);
+        AddIdentifierRef(MD->getName(), Record);
+        AddSourceLocation(MD->getLocation(), Record);
+        Stream.EmitRecord(pch::PP_MACRO_DEFINITION, Record);
+        continue;
+      }
+    }
+  }
+  
+  Stream.ExitBlock();
+  
+  // Write the offsets table for the preprocessing record.
+  if (NumPreprocessingRecords > 0) {
+    // Write the offsets table for identifier IDs.
+    using namespace llvm;
+    BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
+    Abbrev->Add(BitCodeAbbrevOp(pch::MACRO_DEFINITION_OFFSETS));
+    Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of records
+    Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of macro defs
+    Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
+    unsigned MacroDefOffsetAbbrev = Stream.EmitAbbrev(Abbrev);
+    
+    Record.clear();
+    Record.push_back(pch::MACRO_DEFINITION_OFFSETS);
+    Record.push_back(NumPreprocessingRecords);
+    Record.push_back(MacroDefinitionOffsets.size());
+    Stream.EmitRecordWithBlob(MacroDefOffsetAbbrev, Record,
+                              (const char *)&MacroDefinitionOffsets.front(),
+                              MacroDefinitionOffsets.size() * sizeof(uint32_t));
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// Type Serialization
+//===----------------------------------------------------------------------===//
+
+/// \brief Write the representation of a type to the PCH stream.
+void PCHWriter::WriteType(QualType T) {
+  pch::TypeID &ID = TypeIDs[T];
+  if (ID == 0) // we haven't seen this type before.
+    ID = NextTypeID++;
+
+  // Record the offset for this type.
+  if (TypeOffsets.size() == ID - pch::NUM_PREDEF_TYPE_IDS)
+    TypeOffsets.push_back(Stream.GetCurrentBitNo());
+  else if (TypeOffsets.size() < ID - pch::NUM_PREDEF_TYPE_IDS) {
+    TypeOffsets.resize(ID + 1 - pch::NUM_PREDEF_TYPE_IDS);
+    TypeOffsets[ID - pch::NUM_PREDEF_TYPE_IDS] = Stream.GetCurrentBitNo();
+  }
+
+  RecordData Record;
+
+  // Emit the type's representation.
+  PCHTypeWriter W(*this, Record);
+
+  if (T.hasLocalNonFastQualifiers()) {
+    Qualifiers Qs = T.getLocalQualifiers();
+    AddTypeRef(T.getLocalUnqualifiedType(), Record);
+    Record.push_back(Qs.getAsOpaqueValue());
+    W.Code = pch::TYPE_EXT_QUAL;
+  } else {
+    switch (T->getTypeClass()) {
+      // For all of the concrete, non-dependent types, call the
+      // appropriate visitor function.
+#define TYPE(Class, Base) \
+    case Type::Class: W.Visit##Class##Type(cast<Class##Type>(T)); break;
+#define ABSTRACT_TYPE(Class, Base)
+#define DEPENDENT_TYPE(Class, Base)
+#include "clang/AST/TypeNodes.def"
+
+      // For all of the dependent type nodes (which only occur in C++
+      // templates), produce an error.
+#define TYPE(Class, Base)
+#define DEPENDENT_TYPE(Class, Base) case Type::Class:
+#include "clang/AST/TypeNodes.def"
+      assert(false && "Cannot serialize dependent type nodes");
+      break;
+    }
+  }
+
+  // Emit the serialized record.
+  Stream.EmitRecord(W.Code, Record);
+
+  // Flush any expressions that were written as part of this type.
+  FlushStmts();
+}
+
+//===----------------------------------------------------------------------===//
+// Declaration Serialization
+//===----------------------------------------------------------------------===//
+
+/// \brief Write the block containing all of the declaration IDs
+/// lexically declared within the given DeclContext.
+///
+/// \returns the offset of the DECL_CONTEXT_LEXICAL block within the
+/// bistream, or 0 if no block was written.
+uint64_t PCHWriter::WriteDeclContextLexicalBlock(ASTContext &Context,
+                                                 DeclContext *DC) {
+  if (DC->decls_empty())
+    return 0;
+
+  uint64_t Offset = Stream.GetCurrentBitNo();
+  RecordData Record;
+  for (DeclContext::decl_iterator D = DC->decls_begin(), DEnd = DC->decls_end();
+         D != DEnd; ++D)
+    AddDeclRef(*D, Record);
+
+  ++NumLexicalDeclContexts;
+  Stream.EmitRecord(pch::DECL_CONTEXT_LEXICAL, Record);
+  return Offset;
+}
+
+/// \brief Write the block containing all of the declaration IDs
+/// visible from the given DeclContext.
+///
+/// \returns the offset of the DECL_CONTEXT_VISIBLE block within the
+/// bistream, or 0 if no block was written.
+uint64_t PCHWriter::WriteDeclContextVisibleBlock(ASTContext &Context,
+                                                 DeclContext *DC) {
+  if (DC->getPrimaryContext() != DC)
+    return 0;
+
+  // Since there is no name lookup into functions or methods, and we
+  // perform name lookup for the translation unit via the
+  // IdentifierInfo chains, don't bother to build a
+  // visible-declarations table for these entities.
+  if (DC->isFunctionOrMethod() || DC->isTranslationUnit())
+    return 0;
+
+  // Force the DeclContext to build a its name-lookup table.
+  DC->lookup(DeclarationName());
+
+  // Serialize the contents of the mapping used for lookup. Note that,
+  // although we have two very different code paths, the serialized
+  // representation is the same for both cases: a declaration name,
+  // followed by a size, followed by references to the visible
+  // declarations that have that name.
+  uint64_t Offset = Stream.GetCurrentBitNo();
+  RecordData Record;
+  StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(DC->getLookupPtr());
+  if (!Map)
+    return 0;
+
+  for (StoredDeclsMap::iterator D = Map->begin(), DEnd = Map->end();
+       D != DEnd; ++D) {
+    AddDeclarationName(D->first, Record);
+    DeclContext::lookup_result Result = D->second.getLookupResult(Context);
+    Record.push_back(Result.second - Result.first);
+    for (; Result.first != Result.second; ++Result.first)
+      AddDeclRef(*Result.first, Record);
+  }
+
+  if (Record.size() == 0)
+    return 0;
+
+  Stream.EmitRecord(pch::DECL_CONTEXT_VISIBLE, Record);
+  ++NumVisibleDeclContexts;
+  return Offset;
+}
+
+//===----------------------------------------------------------------------===//
+// Global Method Pool and Selector Serialization
+//===----------------------------------------------------------------------===//
+
+namespace {
+// Trait used for the on-disk hash table used in the method pool.
+class PCHMethodPoolTrait {
+  PCHWriter &Writer;
+
+public:
+  typedef Selector key_type;
+  typedef key_type key_type_ref;
+
+  typedef std::pair<ObjCMethodList, ObjCMethodList> data_type;
+  typedef const data_type& data_type_ref;
+
+  explicit PCHMethodPoolTrait(PCHWriter &Writer) : Writer(Writer) { }
+
+  static unsigned ComputeHash(Selector Sel) {
+    unsigned N = Sel.getNumArgs();
+    if (N == 0)
+      ++N;
+    unsigned R = 5381;
+    for (unsigned I = 0; I != N; ++I)
+      if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(I))
+        R = llvm::HashString(II->getName(), R);
+    return R;
+  }
+
+  std::pair<unsigned,unsigned>
+    EmitKeyDataLength(llvm::raw_ostream& Out, Selector Sel,
+                      data_type_ref Methods) {
+    unsigned KeyLen = 2 + (Sel.getNumArgs()? Sel.getNumArgs() * 4 : 4);
+    clang::io::Emit16(Out, KeyLen);
+    unsigned DataLen = 2 + 2; // 2 bytes for each of the method counts
+    for (const ObjCMethodList *Method = &Methods.first; Method;
+         Method = Method->Next)
+      if (Method->Method)
+        DataLen += 4;
+    for (const ObjCMethodList *Method = &Methods.second; Method;
+         Method = Method->Next)
+      if (Method->Method)
+        DataLen += 4;
+    clang::io::Emit16(Out, DataLen);
+    return std::make_pair(KeyLen, DataLen);
+  }
+
+  void EmitKey(llvm::raw_ostream& Out, Selector Sel, unsigned) {
+    uint64_t Start = Out.tell();
+    assert((Start >> 32) == 0 && "Selector key offset too large");
+    Writer.SetSelectorOffset(Sel, Start);
+    unsigned N = Sel.getNumArgs();
+    clang::io::Emit16(Out, N);
+    if (N == 0)
+      N = 1;
+    for (unsigned I = 0; I != N; ++I)
+      clang::io::Emit32(Out,
+                    Writer.getIdentifierRef(Sel.getIdentifierInfoForSlot(I)));
+  }
+
+  void EmitData(llvm::raw_ostream& Out, key_type_ref,
+                data_type_ref Methods, unsigned DataLen) {
+    uint64_t Start = Out.tell(); (void)Start;
+    unsigned NumInstanceMethods = 0;
+    for (const ObjCMethodList *Method = &Methods.first; Method;
+         Method = Method->Next)
+      if (Method->Method)
+        ++NumInstanceMethods;
+
+    unsigned NumFactoryMethods = 0;
+    for (const ObjCMethodList *Method = &Methods.second; Method;
+         Method = Method->Next)
+      if (Method->Method)
+        ++NumFactoryMethods;
+
+    clang::io::Emit16(Out, NumInstanceMethods);
+    clang::io::Emit16(Out, NumFactoryMethods);
+    for (const ObjCMethodList *Method = &Methods.first; Method;
+         Method = Method->Next)
+      if (Method->Method)
+        clang::io::Emit32(Out, Writer.getDeclID(Method->Method));
+    for (const ObjCMethodList *Method = &Methods.second; Method;
+         Method = Method->Next)
+      if (Method->Method)
+        clang::io::Emit32(Out, Writer.getDeclID(Method->Method));
+
+    assert(Out.tell() - Start == DataLen && "Data length is wrong");
+  }
+};
+} // end anonymous namespace
+
+/// \brief Write the method pool into the PCH file.
+///
+/// The method pool contains both instance and factory methods, stored
+/// in an on-disk hash table indexed by the selector.
+void PCHWriter::WriteMethodPool(Sema &SemaRef) {
+  using namespace llvm;
+
+  // Create and write out the blob that contains the instance and
+  // factor method pools.
+  bool Empty = true;
+  {
+    OnDiskChainedHashTableGenerator<PCHMethodPoolTrait> Generator;
+
+    // Create the on-disk hash table representation. Start by
+    // iterating through the instance method pool.
+    PCHMethodPoolTrait::key_type Key;
+    unsigned NumSelectorsInMethodPool = 0;
+    for (llvm::DenseMap<Selector, ObjCMethodList>::iterator
+           Instance = SemaRef.InstanceMethodPool.begin(),
+           InstanceEnd = SemaRef.InstanceMethodPool.end();
+         Instance != InstanceEnd; ++Instance) {
+      // Check whether there is a factory method with the same
+      // selector.
+      llvm::DenseMap<Selector, ObjCMethodList>::iterator Factory
+        = SemaRef.FactoryMethodPool.find(Instance->first);
+
+      if (Factory == SemaRef.FactoryMethodPool.end())
+        Generator.insert(Instance->first,
+                         std::make_pair(Instance->second,
+                                        ObjCMethodList()));
+      else
+        Generator.insert(Instance->first,
+                         std::make_pair(Instance->second, Factory->second));
+
+      ++NumSelectorsInMethodPool;
+      Empty = false;
+    }
+
+    // Now iterate through the factory method pool, to pick up any
+    // selectors that weren't already in the instance method pool.
+    for (llvm::DenseMap<Selector, ObjCMethodList>::iterator
+           Factory = SemaRef.FactoryMethodPool.begin(),
+           FactoryEnd = SemaRef.FactoryMethodPool.end();
+         Factory != FactoryEnd; ++Factory) {
+      // Check whether there is an instance method with the same
+      // selector. If so, there is no work to do here.
+      llvm::DenseMap<Selector, ObjCMethodList>::iterator Instance
+        = SemaRef.InstanceMethodPool.find(Factory->first);
+
+      if (Instance == SemaRef.InstanceMethodPool.end()) {
+        Generator.insert(Factory->first,
+                         std::make_pair(ObjCMethodList(), Factory->second));
+        ++NumSelectorsInMethodPool;
+      }
+
+      Empty = false;
+    }
+
+    if (Empty && SelectorOffsets.empty())
+      return;
+
+    // Create the on-disk hash table in a buffer.
+    llvm::SmallString<4096> MethodPool;
+    uint32_t BucketOffset;
+    SelectorOffsets.resize(SelVector.size());
+    {
+      PCHMethodPoolTrait Trait(*this);
+      llvm::raw_svector_ostream Out(MethodPool);
+      // Make sure that no bucket is at offset 0
+      clang::io::Emit32(Out, 0);
+      BucketOffset = Generator.Emit(Out, Trait);
+
+      // For every selector that we have seen but which was not
+      // written into the hash table, write the selector itself and
+      // record it's offset.
+      for (unsigned I = 0, N = SelVector.size(); I != N; ++I)
+        if (SelectorOffsets[I] == 0)
+          Trait.EmitKey(Out, SelVector[I], 0);
+    }
+
+    // Create a blob abbreviation
+    BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
+    Abbrev->Add(BitCodeAbbrevOp(pch::METHOD_POOL));
+    Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
+    Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
+    Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
+    unsigned MethodPoolAbbrev = Stream.EmitAbbrev(Abbrev);
+
+    // Write the method pool
+    RecordData Record;
+    Record.push_back(pch::METHOD_POOL);
+    Record.push_back(BucketOffset);
+    Record.push_back(NumSelectorsInMethodPool);
+    Stream.EmitRecordWithBlob(MethodPoolAbbrev, Record, MethodPool.str());
+
+    // Create a blob abbreviation for the selector table offsets.
+    Abbrev = new BitCodeAbbrev();
+    Abbrev->Add(BitCodeAbbrevOp(pch::SELECTOR_OFFSETS));
+    Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // index
+    Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
+    unsigned SelectorOffsetAbbrev = Stream.EmitAbbrev(Abbrev);
+
+    // Write the selector offsets table.
+    Record.clear();
+    Record.push_back(pch::SELECTOR_OFFSETS);
+    Record.push_back(SelectorOffsets.size());
+    Stream.EmitRecordWithBlob(SelectorOffsetAbbrev, Record,
+                              (const char *)&SelectorOffsets.front(),
+                              SelectorOffsets.size() * 4);
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// Identifier Table Serialization
+//===----------------------------------------------------------------------===//
+
+namespace {
+class PCHIdentifierTableTrait {
+  PCHWriter &Writer;
+  Preprocessor &PP;
+
+  /// \brief Determines whether this is an "interesting" identifier
+  /// that needs a full IdentifierInfo structure written into the hash
+  /// table.
+  static bool isInterestingIdentifier(const IdentifierInfo *II) {
+    return II->isPoisoned() ||
+      II->isExtensionToken() ||
+      II->hasMacroDefinition() ||
+      II->getObjCOrBuiltinID() ||
+      II->getFETokenInfo<void>();
+  }
+
+public:
+  typedef const IdentifierInfo* key_type;
+  typedef key_type  key_type_ref;
+
+  typedef pch::IdentID data_type;
+  typedef data_type data_type_ref;
+
+  PCHIdentifierTableTrait(PCHWriter &Writer, Preprocessor &PP)
+    : Writer(Writer), PP(PP) { }
+
+  static unsigned ComputeHash(const IdentifierInfo* II) {
+    return llvm::HashString(II->getName());
+  }
+
+  std::pair<unsigned,unsigned>
+    EmitKeyDataLength(llvm::raw_ostream& Out, const IdentifierInfo* II,
+                      pch::IdentID ID) {
+    unsigned KeyLen = II->getLength() + 1;
+    unsigned DataLen = 4; // 4 bytes for the persistent ID << 1
+    if (isInterestingIdentifier(II)) {
+      DataLen += 2; // 2 bytes for builtin ID, flags
+      if (II->hasMacroDefinition() &&
+          !PP.getMacroInfo(const_cast<IdentifierInfo *>(II))->isBuiltinMacro())
+        DataLen += 4;
+      for (IdentifierResolver::iterator D = IdentifierResolver::begin(II),
+                                     DEnd = IdentifierResolver::end();
+           D != DEnd; ++D)
+        DataLen += sizeof(pch::DeclID);
+    }
+    clang::io::Emit16(Out, DataLen);
+    // We emit the key length after the data length so that every
+    // string is preceded by a 16-bit length. This matches the PTH
+    // format for storing identifiers.
+    clang::io::Emit16(Out, KeyLen);
+    return std::make_pair(KeyLen, DataLen);
+  }
+
+  void EmitKey(llvm::raw_ostream& Out, const IdentifierInfo* II,
+               unsigned KeyLen) {
+    // Record the location of the key data.  This is used when generating
+    // the mapping from persistent IDs to strings.
+    Writer.SetIdentifierOffset(II, Out.tell());
+    Out.write(II->getNameStart(), KeyLen);
+  }
+
+  void EmitData(llvm::raw_ostream& Out, const IdentifierInfo* II,
+                pch::IdentID ID, unsigned) {
+    if (!isInterestingIdentifier(II)) {
+      clang::io::Emit32(Out, ID << 1);
+      return;
+    }
+
+    clang::io::Emit32(Out, (ID << 1) | 0x01);
+    uint32_t Bits = 0;
+    bool hasMacroDefinition =
+      II->hasMacroDefinition() &&
+      !PP.getMacroInfo(const_cast<IdentifierInfo *>(II))->isBuiltinMacro();
+    Bits = (uint32_t)II->getObjCOrBuiltinID();
+    Bits = (Bits << 1) | unsigned(hasMacroDefinition);
+    Bits = (Bits << 1) | unsigned(II->isExtensionToken());
+    Bits = (Bits << 1) | unsigned(II->isPoisoned());
+    Bits = (Bits << 1) | unsigned(II->isCPlusPlusOperatorKeyword());
+    clang::io::Emit16(Out, Bits);
+
+    if (hasMacroDefinition)
+      clang::io::Emit32(Out, Writer.getMacroOffset(II));
+
+    // Emit the declaration IDs in reverse order, because the
+    // IdentifierResolver provides the declarations as they would be
+    // visible (e.g., the function "stat" would come before the struct
+    // "stat"), but IdentifierResolver::AddDeclToIdentifierChain()
+    // adds declarations to the end of the list (so we need to see the
+    // struct "status" before the function "status").
+    llvm::SmallVector<Decl *, 16> Decls(IdentifierResolver::begin(II),
+                                        IdentifierResolver::end());
+    for (llvm::SmallVector<Decl *, 16>::reverse_iterator D = Decls.rbegin(),
+                                                      DEnd = Decls.rend();
+         D != DEnd; ++D)
+      clang::io::Emit32(Out, Writer.getDeclID(*D));
+  }
+};
+} // end anonymous namespace
+
+/// \brief Write the identifier table into the PCH file.
+///
+/// The identifier table consists of a blob containing string data
+/// (the actual identifiers themselves) and a separate "offsets" index
+/// that maps identifier IDs to locations within the blob.
+void PCHWriter::WriteIdentifierTable(Preprocessor &PP) {
+  using namespace llvm;
+
+  // Create and write out the blob that contains the identifier
+  // strings.
+  {
+    OnDiskChainedHashTableGenerator<PCHIdentifierTableTrait> Generator;
+
+    // Look for any identifiers that were named while processing the
+    // headers, but are otherwise not needed. We add these to the hash
+    // table to enable checking of the predefines buffer in the case
+    // where the user adds new macro definitions when building the PCH
+    // file.
+    for (IdentifierTable::iterator ID = PP.getIdentifierTable().begin(),
+                                IDEnd = PP.getIdentifierTable().end();
+         ID != IDEnd; ++ID)
+      getIdentifierRef(ID->second);
+
+    // Create the on-disk hash table representation.
+    IdentifierOffsets.resize(IdentifierIDs.size());
+    for (llvm::DenseMap<const IdentifierInfo *, pch::IdentID>::iterator
+           ID = IdentifierIDs.begin(), IDEnd = IdentifierIDs.end();
+         ID != IDEnd; ++ID) {
+      assert(ID->first && "NULL identifier in identifier table");
+      Generator.insert(ID->first, ID->second);
+    }
+
+    // Create the on-disk hash table in a buffer.
+    llvm::SmallString<4096> IdentifierTable;
+    uint32_t BucketOffset;
+    {
+      PCHIdentifierTableTrait Trait(*this, PP);
+      llvm::raw_svector_ostream Out(IdentifierTable);
+      // Make sure that no bucket is at offset 0
+      clang::io::Emit32(Out, 0);
+      BucketOffset = Generator.Emit(Out, Trait);
+    }
+
+    // Create a blob abbreviation
+    BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
+    Abbrev->Add(BitCodeAbbrevOp(pch::IDENTIFIER_TABLE));
+    Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
+    Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
+    unsigned IDTableAbbrev = Stream.EmitAbbrev(Abbrev);
+
+    // Write the identifier table
+    RecordData Record;
+    Record.push_back(pch::IDENTIFIER_TABLE);
+    Record.push_back(BucketOffset);
+    Stream.EmitRecordWithBlob(IDTableAbbrev, Record, IdentifierTable.str());
+  }
+
+  // Write the offsets table for identifier IDs.
+  BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
+  Abbrev->Add(BitCodeAbbrevOp(pch::IDENTIFIER_OFFSET));
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of identifiers
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
+  unsigned IdentifierOffsetAbbrev = Stream.EmitAbbrev(Abbrev);
+
+  RecordData Record;
+  Record.push_back(pch::IDENTIFIER_OFFSET);
+  Record.push_back(IdentifierOffsets.size());
+  Stream.EmitRecordWithBlob(IdentifierOffsetAbbrev, Record,
+                            (const char *)&IdentifierOffsets.front(),
+                            IdentifierOffsets.size() * sizeof(uint32_t));
+}
+
+//===----------------------------------------------------------------------===//
+// General Serialization Routines
+//===----------------------------------------------------------------------===//
+
+/// \brief Write a record containing the given attributes.
+void PCHWriter::WriteAttributeRecord(const Attr *Attr) {
+  RecordData Record;
+  for (; Attr; Attr = Attr->getNext()) {
+    Record.push_back(Attr->getKind()); // FIXME: stable encoding, target attrs
+    Record.push_back(Attr->isInherited());
+    switch (Attr->getKind()) {
+    default:
+      assert(0 && "Does not support PCH writing for this attribute yet!");
+      break;
+    case Attr::Alias:
+      AddString(cast<AliasAttr>(Attr)->getAliasee(), Record);
+      break;
+
+    case Attr::Aligned:
+      Record.push_back(cast<AlignedAttr>(Attr)->getAlignment());
+      break;
+
+    case Attr::AlwaysInline:
+      break;
+
+    case Attr::AnalyzerNoReturn:
+      break;
+
+    case Attr::Annotate:
+      AddString(cast<AnnotateAttr>(Attr)->getAnnotation(), Record);
+      break;
+
+    case Attr::AsmLabel:
+      AddString(cast<AsmLabelAttr>(Attr)->getLabel(), Record);
+      break;
+
+    case Attr::BaseCheck:
+      break;
+
+    case Attr::Blocks:
+      Record.push_back(cast<BlocksAttr>(Attr)->getType()); // FIXME: stable
+      break;
+
+    case Attr::CDecl:
+      break;
+
+    case Attr::Cleanup:
+      AddDeclRef(cast<CleanupAttr>(Attr)->getFunctionDecl(), Record);
+      break;
+
+    case Attr::Const:
+      break;
+
+    case Attr::Constructor:
+      Record.push_back(cast<ConstructorAttr>(Attr)->getPriority());
+      break;
+
+    case Attr::DLLExport:
+    case Attr::DLLImport:
+    case Attr::Deprecated:
+      break;
+
+    case Attr::Destructor:
+      Record.push_back(cast<DestructorAttr>(Attr)->getPriority());
+      break;
+
+    case Attr::FastCall:
+    case Attr::Final:
+      break;
+
+    case Attr::Format: {
+      const FormatAttr *Format = cast<FormatAttr>(Attr);
+      AddString(Format->getType(), Record);
+      Record.push_back(Format->getFormatIdx());
+      Record.push_back(Format->getFirstArg());
+      break;
+    }
+
+    case Attr::FormatArg: {
+      const FormatArgAttr *Format = cast<FormatArgAttr>(Attr);
+      Record.push_back(Format->getFormatIdx());
+      break;
+    }
+
+    case Attr::Sentinel : {
+      const SentinelAttr *Sentinel = cast<SentinelAttr>(Attr);
+      Record.push_back(Sentinel->getSentinel());
+      Record.push_back(Sentinel->getNullPos());
+      break;
+    }
+
+    case Attr::GNUInline:
+    case Attr::Hiding:
+    case Attr::IBActionKind:
+    case Attr::IBOutletKind:
+    case Attr::Malloc:
+    case Attr::NoDebug:
+    case Attr::NoInline:
+    case Attr::NoReturn:
+    case Attr::NoThrow:
+      break;
+
+    case Attr::NonNull: {
+      const NonNullAttr *NonNull = cast<NonNullAttr>(Attr);
+      Record.push_back(NonNull->size());
+      Record.insert(Record.end(), NonNull->begin(), NonNull->end());
+      break;
+    }
+
+    case Attr::CFReturnsNotRetained:
+    case Attr::CFReturnsRetained:
+    case Attr::NSReturnsNotRetained:
+    case Attr::NSReturnsRetained:
+    case Attr::ObjCException:
+    case Attr::ObjCNSObject:
+    case Attr::Overloadable:
+    case Attr::Override:
+      break;
+
+    case Attr::PragmaPack:
+      Record.push_back(cast<PragmaPackAttr>(Attr)->getAlignment());
+      break;
+
+    case Attr::Packed:
+      break;
+
+    case Attr::Pure:
+      break;
+
+    case Attr::Regparm:
+      Record.push_back(cast<RegparmAttr>(Attr)->getNumParams());
+      break;
+
+    case Attr::ReqdWorkGroupSize:
+      Record.push_back(cast<ReqdWorkGroupSizeAttr>(Attr)->getXDim());
+      Record.push_back(cast<ReqdWorkGroupSizeAttr>(Attr)->getYDim());
+      Record.push_back(cast<ReqdWorkGroupSizeAttr>(Attr)->getZDim());
+      break;
+
+    case Attr::Section:
+      AddString(cast<SectionAttr>(Attr)->getName(), Record);
+      break;
+
+    case Attr::StdCall:
+    case Attr::TransparentUnion:
+    case Attr::Unavailable:
+    case Attr::Unused:
+    case Attr::Used:
+      break;
+
+    case Attr::Visibility:
+      // FIXME: stable encoding
+      Record.push_back(cast<VisibilityAttr>(Attr)->getVisibility());
+      break;
+
+    case Attr::WarnUnusedResult:
+    case Attr::Weak:
+    case Attr::WeakRef:
+    case Attr::WeakImport:
+      break;
+    }
+  }
+
+  Stream.EmitRecord(pch::DECL_ATTR, Record);
+}
+
+void PCHWriter::AddString(const std::string &Str, RecordData &Record) {
+  Record.push_back(Str.size());
+  Record.insert(Record.end(), Str.begin(), Str.end());
+}
+
+/// \brief Note that the identifier II occurs at the given offset
+/// within the identifier table.
+void PCHWriter::SetIdentifierOffset(const IdentifierInfo *II, uint32_t Offset) {
+  IdentifierOffsets[IdentifierIDs[II] - 1] = Offset;
+}
+
+/// \brief Note that the selector Sel occurs at the given offset
+/// within the method pool/selector table.
+void PCHWriter::SetSelectorOffset(Selector Sel, uint32_t Offset) {
+  unsigned ID = SelectorIDs[Sel];
+  assert(ID && "Unknown selector");
+  SelectorOffsets[ID - 1] = Offset;
+}
+
+PCHWriter::PCHWriter(llvm::BitstreamWriter &Stream)
+  : Stream(Stream), NextTypeID(pch::NUM_PREDEF_TYPE_IDS),
+    NumStatements(0), NumMacros(0), NumLexicalDeclContexts(0),
+    NumVisibleDeclContexts(0) { }
+
+void PCHWriter::WritePCH(Sema &SemaRef, MemorizeStatCalls *StatCalls,
+                         const char *isysroot) {
+  using namespace llvm;
+
+  ASTContext &Context = SemaRef.Context;
+  Preprocessor &PP = SemaRef.PP;
+
+  // Emit the file header.
+  Stream.Emit((unsigned)'C', 8);
+  Stream.Emit((unsigned)'P', 8);
+  Stream.Emit((unsigned)'C', 8);
+  Stream.Emit((unsigned)'H', 8);
+
+  WriteBlockInfoBlock();
+
+  // The translation unit is the first declaration we'll emit.
+  DeclIDs[Context.getTranslationUnitDecl()] = 1;
+  DeclTypesToEmit.push(Context.getTranslationUnitDecl());
+
+  // Make sure that we emit IdentifierInfos (and any attached
+  // declarations) for builtins.
+  {
+    IdentifierTable &Table = PP.getIdentifierTable();
+    llvm::SmallVector<const char *, 32> BuiltinNames;
+    Context.BuiltinInfo.GetBuiltinNames(BuiltinNames,
+                                        Context.getLangOptions().NoBuiltin);
+    for (unsigned I = 0, N = BuiltinNames.size(); I != N; ++I)
+      getIdentifierRef(&Table.get(BuiltinNames[I]));
+  }
+
+  // Build a record containing all of the tentative definitions in this file, in
+  // TentativeDefinitions order.  Generally, this record will be empty for
+  // headers.
+  RecordData TentativeDefinitions;
+  for (unsigned i = 0, e = SemaRef.TentativeDefinitions.size(); i != e; ++i) {
+    AddDeclRef(SemaRef.TentativeDefinitions[i], TentativeDefinitions);
+  }
+
+  // Build a record containing all of the static unused functions in this file.
+  RecordData UnusedStaticFuncs;
+  for (unsigned i=0, e = SemaRef.UnusedStaticFuncs.size(); i !=e; ++i)
+    AddDeclRef(SemaRef.UnusedStaticFuncs[i], UnusedStaticFuncs);
+
+  // Build a record containing all of the locally-scoped external
+  // declarations in this header file. Generally, this record will be
+  // empty.
+  RecordData LocallyScopedExternalDecls;
+  // FIXME: This is filling in the PCH file in densemap order which is
+  // nondeterminstic!
+  for (llvm::DenseMap<DeclarationName, NamedDecl *>::iterator
+         TD = SemaRef.LocallyScopedExternalDecls.begin(),
+         TDEnd = SemaRef.LocallyScopedExternalDecls.end();
+       TD != TDEnd; ++TD)
+    AddDeclRef(TD->second, LocallyScopedExternalDecls);
+
+  // Build a record containing all of the ext_vector declarations.
+  RecordData ExtVectorDecls;
+  for (unsigned I = 0, N = SemaRef.ExtVectorDecls.size(); I != N; ++I)
+    AddDeclRef(SemaRef.ExtVectorDecls[I], ExtVectorDecls);
+
+  // Write the remaining PCH contents.
+  RecordData Record;
+  Stream.EnterSubblock(pch::PCH_BLOCK_ID, 5);
+  WriteMetadata(Context, isysroot);
+  WriteLanguageOptions(Context.getLangOptions());
+  if (StatCalls && !isysroot)
+    WriteStatCache(*StatCalls, isysroot);
+  WriteSourceManagerBlock(Context.getSourceManager(), PP, isysroot);
+  // Write the record of special types.
+  Record.clear();
+
+  AddTypeRef(Context.getBuiltinVaListType(), Record);
+  AddTypeRef(Context.getObjCIdType(), Record);
+  AddTypeRef(Context.getObjCSelType(), Record);
+  AddTypeRef(Context.getObjCProtoType(), Record);
+  AddTypeRef(Context.getObjCClassType(), Record);
+  AddTypeRef(Context.getRawCFConstantStringType(), Record);
+  AddTypeRef(Context.getRawObjCFastEnumerationStateType(), Record);
+  AddTypeRef(Context.getFILEType(), Record);
+  AddTypeRef(Context.getjmp_bufType(), Record);
+  AddTypeRef(Context.getsigjmp_bufType(), Record);
+  AddTypeRef(Context.ObjCIdRedefinitionType, Record);
+  AddTypeRef(Context.ObjCClassRedefinitionType, Record);
+  AddTypeRef(Context.getRawBlockdescriptorType(), Record);
+  AddTypeRef(Context.getRawBlockdescriptorExtendedType(), Record);
+  AddTypeRef(Context.ObjCSelRedefinitionType, Record);
+  AddTypeRef(Context.getRawNSConstantStringType(), Record);
+  Stream.EmitRecord(pch::SPECIAL_TYPES, Record);
+
+  // Keep writing types and declarations until all types and
+  // declarations have been written.
+  Stream.EnterSubblock(pch::DECLTYPES_BLOCK_ID, 3);
+  WriteDeclsBlockAbbrevs();
+  while (!DeclTypesToEmit.empty()) {
+    DeclOrType DOT = DeclTypesToEmit.front();
+    DeclTypesToEmit.pop();
+    if (DOT.isType())
+      WriteType(DOT.getType());
+    else
+      WriteDecl(Context, DOT.getDecl());
+  }
+  Stream.ExitBlock();
+
+  WritePreprocessor(PP);
+  WriteMethodPool(SemaRef);
+  WriteIdentifierTable(PP);
+
+  // Write the type offsets array
+  BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
+  Abbrev->Add(BitCodeAbbrevOp(pch::TYPE_OFFSET));
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of types
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // types block
+  unsigned TypeOffsetAbbrev = Stream.EmitAbbrev(Abbrev);
+  Record.clear();
+  Record.push_back(pch::TYPE_OFFSET);
+  Record.push_back(TypeOffsets.size());
+  Stream.EmitRecordWithBlob(TypeOffsetAbbrev, Record,
+                            (const char *)&TypeOffsets.front(),
+                            TypeOffsets.size() * sizeof(TypeOffsets[0]));
+
+  // Write the declaration offsets array
+  Abbrev = new BitCodeAbbrev();
+  Abbrev->Add(BitCodeAbbrevOp(pch::DECL_OFFSET));
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of declarations
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // declarations block
+  unsigned DeclOffsetAbbrev = Stream.EmitAbbrev(Abbrev);
+  Record.clear();
+  Record.push_back(pch::DECL_OFFSET);
+  Record.push_back(DeclOffsets.size());
+  Stream.EmitRecordWithBlob(DeclOffsetAbbrev, Record,
+                            (const char *)&DeclOffsets.front(),
+                            DeclOffsets.size() * sizeof(DeclOffsets[0]));
+
+  // Write the record containing external, unnamed definitions.
+  if (!ExternalDefinitions.empty())
+    Stream.EmitRecord(pch::EXTERNAL_DEFINITIONS, ExternalDefinitions);
+
+  // Write the record containing tentative definitions.
+  if (!TentativeDefinitions.empty())
+    Stream.EmitRecord(pch::TENTATIVE_DEFINITIONS, TentativeDefinitions);
+
+  // Write the record containing unused static functions.
+  if (!UnusedStaticFuncs.empty())
+    Stream.EmitRecord(pch::UNUSED_STATIC_FUNCS, UnusedStaticFuncs);
+
+  // Write the record containing locally-scoped external definitions.
+  if (!LocallyScopedExternalDecls.empty())
+    Stream.EmitRecord(pch::LOCALLY_SCOPED_EXTERNAL_DECLS,
+                      LocallyScopedExternalDecls);
+
+  // Write the record containing ext_vector type names.
+  if (!ExtVectorDecls.empty())
+    Stream.EmitRecord(pch::EXT_VECTOR_DECLS, ExtVectorDecls);
+
+  // Some simple statistics
+  Record.clear();
+  Record.push_back(NumStatements);
+  Record.push_back(NumMacros);
+  Record.push_back(NumLexicalDeclContexts);
+  Record.push_back(NumVisibleDeclContexts);
+  Stream.EmitRecord(pch::STATISTICS, Record);
+  Stream.ExitBlock();
+}
+
+void PCHWriter::AddSourceLocation(SourceLocation Loc, RecordData &Record) {
+  Record.push_back(Loc.getRawEncoding());
+}
+
+void PCHWriter::AddAPInt(const llvm::APInt &Value, RecordData &Record) {
+  Record.push_back(Value.getBitWidth());
+  unsigned N = Value.getNumWords();
+  const uint64_t* Words = Value.getRawData();
+  for (unsigned I = 0; I != N; ++I)
+    Record.push_back(Words[I]);
+}
+
+void PCHWriter::AddAPSInt(const llvm::APSInt &Value, RecordData &Record) {
+  Record.push_back(Value.isUnsigned());
+  AddAPInt(Value, Record);
+}
+
+void PCHWriter::AddAPFloat(const llvm::APFloat &Value, RecordData &Record) {
+  AddAPInt(Value.bitcastToAPInt(), Record);
+}
+
+void PCHWriter::AddIdentifierRef(const IdentifierInfo *II, RecordData &Record) {
+  Record.push_back(getIdentifierRef(II));
+}
+
+pch::IdentID PCHWriter::getIdentifierRef(const IdentifierInfo *II) {
+  if (II == 0)
+    return 0;
+
+  pch::IdentID &ID = IdentifierIDs[II];
+  if (ID == 0)
+    ID = IdentifierIDs.size();
+  return ID;
+}
+
+pch::IdentID PCHWriter::getMacroDefinitionID(MacroDefinition *MD) {
+  if (MD == 0)
+    return 0;
+  
+  pch::IdentID &ID = MacroDefinitions[MD];
+  if (ID == 0)
+    ID = MacroDefinitions.size();
+  return ID;
+}
+
+void PCHWriter::AddSelectorRef(const Selector SelRef, RecordData &Record) {
+  if (SelRef.getAsOpaquePtr() == 0) {
+    Record.push_back(0);
+    return;
+  }
+
+  pch::SelectorID &SID = SelectorIDs[SelRef];
+  if (SID == 0) {
+    SID = SelectorIDs.size();
+    SelVector.push_back(SelRef);
+  }
+  Record.push_back(SID);
+}
+
+void PCHWriter::AddTemplateArgumentLoc(const TemplateArgumentLoc &Arg,
+                                       RecordData &Record) {
+  switch (Arg.getArgument().getKind()) {
+  case TemplateArgument::Expression:
+    AddStmt(Arg.getLocInfo().getAsExpr());
+    break;
+  case TemplateArgument::Type:
+    AddTypeSourceInfo(Arg.getLocInfo().getAsTypeSourceInfo(), Record);
+    break;
+  case TemplateArgument::Template:
+    Record.push_back(
+                   Arg.getTemplateQualifierRange().getBegin().getRawEncoding());
+    Record.push_back(Arg.getTemplateQualifierRange().getEnd().getRawEncoding());
+    Record.push_back(Arg.getTemplateNameLoc().getRawEncoding());
+    break;
+  case TemplateArgument::Null:
+  case TemplateArgument::Integral:
+  case TemplateArgument::Declaration:
+  case TemplateArgument::Pack:
+    break;
+  }
+}
+
+void PCHWriter::AddTypeSourceInfo(TypeSourceInfo *TInfo, RecordData &Record) {
+  if (TInfo == 0) {
+    AddTypeRef(QualType(), Record);
+    return;
+  }
+
+  AddTypeRef(TInfo->getType(), Record);
+  TypeLocWriter TLW(*this, Record);
+  for (TypeLoc TL = TInfo->getTypeLoc(); !TL.isNull(); TL = TL.getNextTypeLoc())
+    TLW.Visit(TL);
+}
+
+void PCHWriter::AddTypeRef(QualType T, RecordData &Record) {
+  if (T.isNull()) {
+    Record.push_back(pch::PREDEF_TYPE_NULL_ID);
+    return;
+  }
+
+  unsigned FastQuals = T.getLocalFastQualifiers();
+  T.removeFastQualifiers();
+
+  if (T.hasLocalNonFastQualifiers()) {
+    pch::TypeID &ID = TypeIDs[T];
+    if (ID == 0) {
+      // We haven't seen these qualifiers applied to this type before.
+      // Assign it a new ID.  This is the only time we enqueue a
+      // qualified type, and it has no CV qualifiers.
+      ID = NextTypeID++;
+      DeclTypesToEmit.push(T);
+    }
+
+    // Encode the type qualifiers in the type reference.
+    Record.push_back((ID << Qualifiers::FastWidth) | FastQuals);
+    return;
+  }
+
+  assert(!T.hasLocalQualifiers());
+
+  if (const BuiltinType *BT = dyn_cast<BuiltinType>(T.getTypePtr())) {
+    pch::TypeID ID = 0;
+    switch (BT->getKind()) {
+    case BuiltinType::Void:       ID = pch::PREDEF_TYPE_VOID_ID;       break;
+    case BuiltinType::Bool:       ID = pch::PREDEF_TYPE_BOOL_ID;       break;
+    case BuiltinType::Char_U:     ID = pch::PREDEF_TYPE_CHAR_U_ID;     break;
+    case BuiltinType::UChar:      ID = pch::PREDEF_TYPE_UCHAR_ID;      break;
+    case BuiltinType::UShort:     ID = pch::PREDEF_TYPE_USHORT_ID;     break;
+    case BuiltinType::UInt:       ID = pch::PREDEF_TYPE_UINT_ID;       break;
+    case BuiltinType::ULong:      ID = pch::PREDEF_TYPE_ULONG_ID;      break;
+    case BuiltinType::ULongLong:  ID = pch::PREDEF_TYPE_ULONGLONG_ID;  break;
+    case BuiltinType::UInt128:    ID = pch::PREDEF_TYPE_UINT128_ID;    break;
+    case BuiltinType::Char_S:     ID = pch::PREDEF_TYPE_CHAR_S_ID;     break;
+    case BuiltinType::SChar:      ID = pch::PREDEF_TYPE_SCHAR_ID;      break;
+    case BuiltinType::WChar:      ID = pch::PREDEF_TYPE_WCHAR_ID;      break;
+    case BuiltinType::Short:      ID = pch::PREDEF_TYPE_SHORT_ID;      break;
+    case BuiltinType::Int:        ID = pch::PREDEF_TYPE_INT_ID;        break;
+    case BuiltinType::Long:       ID = pch::PREDEF_TYPE_LONG_ID;       break;
+    case BuiltinType::LongLong:   ID = pch::PREDEF_TYPE_LONGLONG_ID;   break;
+    case BuiltinType::Int128:     ID = pch::PREDEF_TYPE_INT128_ID;     break;
+    case BuiltinType::Float:      ID = pch::PREDEF_TYPE_FLOAT_ID;      break;
+    case BuiltinType::Double:     ID = pch::PREDEF_TYPE_DOUBLE_ID;     break;
+    case BuiltinType::LongDouble: ID = pch::PREDEF_TYPE_LONGDOUBLE_ID; break;
+    case BuiltinType::NullPtr:    ID = pch::PREDEF_TYPE_NULLPTR_ID;    break;
+    case BuiltinType::Char16:     ID = pch::PREDEF_TYPE_CHAR16_ID;     break;
+    case BuiltinType::Char32:     ID = pch::PREDEF_TYPE_CHAR32_ID;     break;
+    case BuiltinType::Overload:   ID = pch::PREDEF_TYPE_OVERLOAD_ID;   break;
+    case BuiltinType::Dependent:  ID = pch::PREDEF_TYPE_DEPENDENT_ID;  break;
+    case BuiltinType::ObjCId:     ID = pch::PREDEF_TYPE_OBJC_ID;       break;
+    case BuiltinType::ObjCClass:  ID = pch::PREDEF_TYPE_OBJC_CLASS;    break;
+    case BuiltinType::ObjCSel:    ID = pch::PREDEF_TYPE_OBJC_SEL;      break;
+    case BuiltinType::UndeducedAuto:
+      assert(0 && "Should not see undeduced auto here");
+      break;
+    }
+
+    Record.push_back((ID << Qualifiers::FastWidth) | FastQuals);
+    return;
+  }
+
+  pch::TypeID &ID = TypeIDs[T];
+  if (ID == 0) {
+    // We haven't seen this type before. Assign it a new ID and put it
+    // into the queue of types to emit.
+    ID = NextTypeID++;
+    DeclTypesToEmit.push(T);
+  }
+
+  // Encode the type qualifiers in the type reference.
+  Record.push_back((ID << Qualifiers::FastWidth) | FastQuals);
+}
+
+void PCHWriter::AddDeclRef(const Decl *D, RecordData &Record) {
+  if (D == 0) {
+    Record.push_back(0);
+    return;
+  }
+
+  pch::DeclID &ID = DeclIDs[D];
+  if (ID == 0) {
+    // We haven't seen this declaration before. Give it a new ID and
+    // enqueue it in the list of declarations to emit.
+    ID = DeclIDs.size();
+    DeclTypesToEmit.push(const_cast<Decl *>(D));
+  }
+
+  Record.push_back(ID);
+}
+
+pch::DeclID PCHWriter::getDeclID(const Decl *D) {
+  if (D == 0)
+    return 0;
+
+  assert(DeclIDs.find(D) != DeclIDs.end() && "Declaration not emitted!");
+  return DeclIDs[D];
+}
+
+void PCHWriter::AddDeclarationName(DeclarationName Name, RecordData &Record) {
+  // FIXME: Emit a stable enum for NameKind.  0 = Identifier etc.
+  Record.push_back(Name.getNameKind());
+  switch (Name.getNameKind()) {
+  case DeclarationName::Identifier:
+    AddIdentifierRef(Name.getAsIdentifierInfo(), Record);
+    break;
+
+  case DeclarationName::ObjCZeroArgSelector:
+  case DeclarationName::ObjCOneArgSelector:
+  case DeclarationName::ObjCMultiArgSelector:
+    AddSelectorRef(Name.getObjCSelector(), Record);
+    break;
+
+  case DeclarationName::CXXConstructorName:
+  case DeclarationName::CXXDestructorName:
+  case DeclarationName::CXXConversionFunctionName:
+    AddTypeRef(Name.getCXXNameType(), Record);
+    break;
+
+  case DeclarationName::CXXOperatorName:
+    Record.push_back(Name.getCXXOverloadedOperator());
+    break;
+
+  case DeclarationName::CXXLiteralOperatorName:
+    AddIdentifierRef(Name.getCXXLiteralIdentifier(), Record);
+    break;
+
+  case DeclarationName::CXXUsingDirective:
+    // No extra data to emit
+    break;
+  }
+}
diff --git a/lib/Frontend/PCHWriterDecl.cpp b/lib/Frontend/PCHWriterDecl.cpp
new file mode 100644
index 0000000..6b4ba67
--- /dev/null
+++ b/lib/Frontend/PCHWriterDecl.cpp
@@ -0,0 +1,632 @@
+//===--- PCHWriterDecl.cpp - Declaration Serialization --------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements serialization for Declarations.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/PCHWriter.h"
+#include "clang/AST/DeclVisitor.h"
+#include "clang/AST/Expr.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Bitcode/BitstreamWriter.h"
+#include "llvm/Support/ErrorHandling.h"
+using namespace clang;
+
+//===----------------------------------------------------------------------===//
+// Declaration serialization
+//===----------------------------------------------------------------------===//
+
+namespace {
+  class PCHDeclWriter : public DeclVisitor<PCHDeclWriter, void> {
+
+    PCHWriter &Writer;
+    ASTContext &Context;
+    PCHWriter::RecordData &Record;
+
+  public:
+    pch::DeclCode Code;
+    unsigned AbbrevToUse;
+
+    PCHDeclWriter(PCHWriter &Writer, ASTContext &Context,
+                  PCHWriter::RecordData &Record)
+      : Writer(Writer), Context(Context), Record(Record) {
+    }
+
+    void VisitDecl(Decl *D);
+    void VisitTranslationUnitDecl(TranslationUnitDecl *D);
+    void VisitNamedDecl(NamedDecl *D);
+    void VisitNamespaceDecl(NamespaceDecl *D);
+    void VisitTypeDecl(TypeDecl *D);
+    void VisitTypedefDecl(TypedefDecl *D);
+    void VisitTagDecl(TagDecl *D);
+    void VisitEnumDecl(EnumDecl *D);
+    void VisitRecordDecl(RecordDecl *D);
+    void VisitValueDecl(ValueDecl *D);
+    void VisitEnumConstantDecl(EnumConstantDecl *D);
+    void VisitDeclaratorDecl(DeclaratorDecl *D);
+    void VisitFunctionDecl(FunctionDecl *D);
+    void VisitFieldDecl(FieldDecl *D);
+    void VisitVarDecl(VarDecl *D);
+    void VisitImplicitParamDecl(ImplicitParamDecl *D);
+    void VisitParmVarDecl(ParmVarDecl *D);
+    void VisitFileScopeAsmDecl(FileScopeAsmDecl *D);
+    void VisitBlockDecl(BlockDecl *D);
+    void VisitDeclContext(DeclContext *DC, uint64_t LexicalOffset,
+                          uint64_t VisibleOffset);
+    void VisitObjCMethodDecl(ObjCMethodDecl *D);
+    void VisitObjCContainerDecl(ObjCContainerDecl *D);
+    void VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
+    void VisitObjCIvarDecl(ObjCIvarDecl *D);
+    void VisitObjCProtocolDecl(ObjCProtocolDecl *D);
+    void VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl *D);
+    void VisitObjCClassDecl(ObjCClassDecl *D);
+    void VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D);
+    void VisitObjCCategoryDecl(ObjCCategoryDecl *D);
+    void VisitObjCImplDecl(ObjCImplDecl *D);
+    void VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D);
+    void VisitObjCImplementationDecl(ObjCImplementationDecl *D);
+    void VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *D);
+    void VisitObjCPropertyDecl(ObjCPropertyDecl *D);
+    void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D);
+  };
+}
+
+void PCHDeclWriter::VisitDecl(Decl *D) {
+  Writer.AddDeclRef(cast_or_null<Decl>(D->getDeclContext()), Record);
+  Writer.AddDeclRef(cast_or_null<Decl>(D->getLexicalDeclContext()), Record);
+  Writer.AddSourceLocation(D->getLocation(), Record);
+  Record.push_back(D->isInvalidDecl());
+  Record.push_back(D->hasAttrs());
+  Record.push_back(D->isImplicit());
+  Record.push_back(D->isUsed());
+  Record.push_back(D->getAccess());
+  Record.push_back(D->getPCHLevel());
+}
+
+void PCHDeclWriter::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
+  VisitDecl(D);
+  Code = pch::DECL_TRANSLATION_UNIT;
+}
+
+void PCHDeclWriter::VisitNamedDecl(NamedDecl *D) {
+  VisitDecl(D);
+  Writer.AddDeclarationName(D->getDeclName(), Record);
+}
+
+void PCHDeclWriter::VisitNamespaceDecl(NamespaceDecl *D) {
+  VisitNamedDecl(D);
+  Writer.AddSourceLocation(D->getLBracLoc(), Record);
+  Writer.AddSourceLocation(D->getRBracLoc(), Record);
+  Writer.AddDeclRef(D->getNextNamespace(), Record);
+  Writer.AddDeclRef(D->getOriginalNamespace(), Record);
+  Writer.AddDeclRef(D->getAnonymousNamespace(), Record);
+  Code = pch::DECL_NAMESPACE;
+}
+
+void PCHDeclWriter::VisitTypeDecl(TypeDecl *D) {
+  VisitNamedDecl(D);
+  Writer.AddTypeRef(QualType(D->getTypeForDecl(), 0), Record);
+}
+
+void PCHDeclWriter::VisitTypedefDecl(TypedefDecl *D) {
+  VisitTypeDecl(D);
+  Writer.AddTypeSourceInfo(D->getTypeSourceInfo(), Record);
+  Code = pch::DECL_TYPEDEF;
+}
+
+void PCHDeclWriter::VisitTagDecl(TagDecl *D) {
+  VisitTypeDecl(D);
+  Writer.AddDeclRef(D->getPreviousDeclaration(), Record);
+  Record.push_back((unsigned)D->getTagKind()); // FIXME: stable encoding
+  Record.push_back(D->isDefinition());
+  Record.push_back(D->isEmbeddedInDeclarator());
+  Writer.AddSourceLocation(D->getRBraceLoc(), Record);
+  Writer.AddSourceLocation(D->getTagKeywordLoc(), Record);
+  // FIXME: maybe write optional qualifier and its range.
+  Writer.AddDeclRef(D->getTypedefForAnonDecl(), Record);
+}
+
+void PCHDeclWriter::VisitEnumDecl(EnumDecl *D) {
+  VisitTagDecl(D);
+  Writer.AddTypeRef(D->getIntegerType(), Record);
+  Writer.AddTypeRef(D->getPromotionType(), Record);
+  // FIXME: C++ InstantiatedFrom
+  Code = pch::DECL_ENUM;
+}
+
+void PCHDeclWriter::VisitRecordDecl(RecordDecl *D) {
+  VisitTagDecl(D);
+  Record.push_back(D->hasFlexibleArrayMember());
+  Record.push_back(D->isAnonymousStructOrUnion());
+  Record.push_back(D->hasObjectMember());
+  Code = pch::DECL_RECORD;
+}
+
+void PCHDeclWriter::VisitValueDecl(ValueDecl *D) {
+  VisitNamedDecl(D);
+  Writer.AddTypeRef(D->getType(), Record);
+}
+
+void PCHDeclWriter::VisitEnumConstantDecl(EnumConstantDecl *D) {
+  VisitValueDecl(D);
+  Record.push_back(D->getInitExpr()? 1 : 0);
+  if (D->getInitExpr())
+    Writer.AddStmt(D->getInitExpr());
+  Writer.AddAPSInt(D->getInitVal(), Record);
+  Code = pch::DECL_ENUM_CONSTANT;
+}
+
+void PCHDeclWriter::VisitDeclaratorDecl(DeclaratorDecl *D) {
+  VisitValueDecl(D);
+  Writer.AddTypeSourceInfo(D->getTypeSourceInfo(), Record);
+  // FIXME: write optional qualifier and its range.
+}
+
+void PCHDeclWriter::VisitFunctionDecl(FunctionDecl *D) {
+  VisitDeclaratorDecl(D);
+  Record.push_back(D->isThisDeclarationADefinition());
+  if (D->isThisDeclarationADefinition())
+    Writer.AddStmt(D->getBody());
+  Writer.AddDeclRef(D->getPreviousDeclaration(), Record);
+  Record.push_back(D->getStorageClass()); // FIXME: stable encoding
+  Record.push_back(D->getStorageClassAsWritten());
+  Record.push_back(D->isInlineSpecified());
+  Record.push_back(D->isVirtualAsWritten());
+  Record.push_back(D->isPure());
+  Record.push_back(D->hasInheritedPrototype());
+  Record.push_back(D->hasWrittenPrototype());
+  Record.push_back(D->isDeleted());
+  Record.push_back(D->isTrivial());
+  Record.push_back(D->isCopyAssignment());
+  Record.push_back(D->hasImplicitReturnZero());
+  Writer.AddSourceLocation(D->getLocEnd(), Record);
+  // FIXME: C++ TemplateOrInstantiation
+  Record.push_back(D->param_size());
+  for (FunctionDecl::param_iterator P = D->param_begin(), PEnd = D->param_end();
+       P != PEnd; ++P)
+    Writer.AddDeclRef(*P, Record);
+  Code = pch::DECL_FUNCTION;
+}
+
+void PCHDeclWriter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
+  VisitNamedDecl(D);
+  // FIXME: convert to LazyStmtPtr?
+  // Unlike C/C++, method bodies will never be in header files.
+  Record.push_back(D->getBody() != 0);
+  if (D->getBody() != 0) {
+    Writer.AddStmt(D->getBody());
+    Writer.AddDeclRef(D->getSelfDecl(), Record);
+    Writer.AddDeclRef(D->getCmdDecl(), Record);
+  }
+  Record.push_back(D->isInstanceMethod());
+  Record.push_back(D->isVariadic());
+  Record.push_back(D->isSynthesized());
+  // FIXME: stable encoding for @required/@optional
+  Record.push_back(D->getImplementationControl());
+  // FIXME: stable encoding for in/out/inout/bycopy/byref/oneway
+  Record.push_back(D->getObjCDeclQualifier());
+  Record.push_back(D->getNumSelectorArgs());
+  Writer.AddTypeRef(D->getResultType(), Record);
+  Writer.AddTypeSourceInfo(D->getResultTypeSourceInfo(), Record);
+  Writer.AddSourceLocation(D->getLocEnd(), Record);
+  Record.push_back(D->param_size());
+  for (ObjCMethodDecl::param_iterator P = D->param_begin(),
+                                   PEnd = D->param_end(); P != PEnd; ++P)
+    Writer.AddDeclRef(*P, Record);
+  Code = pch::DECL_OBJC_METHOD;
+}
+
+void PCHDeclWriter::VisitObjCContainerDecl(ObjCContainerDecl *D) {
+  VisitNamedDecl(D);
+  SourceRange R = D->getAtEndRange();
+  Writer.AddSourceLocation(R.getBegin(), Record);
+  Writer.AddSourceLocation(R.getEnd(), Record);
+  // Abstract class (no need to define a stable pch::DECL code).
+}
+
+void PCHDeclWriter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
+  VisitObjCContainerDecl(D);
+  Writer.AddTypeRef(QualType(D->getTypeForDecl(), 0), Record);
+  Writer.AddDeclRef(D->getSuperClass(), Record);
+  Record.push_back(D->protocol_size());
+  for (ObjCInterfaceDecl::protocol_iterator P = D->protocol_begin(),
+         PEnd = D->protocol_end();
+       P != PEnd; ++P)
+    Writer.AddDeclRef(*P, Record);
+  for (ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin(),
+         PLEnd = D->protocol_loc_end();
+       PL != PLEnd; ++PL)
+    Writer.AddSourceLocation(*PL, Record);
+  Record.push_back(D->ivar_size());
+  for (ObjCInterfaceDecl::ivar_iterator I = D->ivar_begin(),
+                                     IEnd = D->ivar_end(); I != IEnd; ++I)
+    Writer.AddDeclRef(*I, Record);
+  Writer.AddDeclRef(D->getCategoryList(), Record);
+  Record.push_back(D->isForwardDecl());
+  Record.push_back(D->isImplicitInterfaceDecl());
+  Writer.AddSourceLocation(D->getClassLoc(), Record);
+  Writer.AddSourceLocation(D->getSuperClassLoc(), Record);
+  Writer.AddSourceLocation(D->getLocEnd(), Record);
+  Code = pch::DECL_OBJC_INTERFACE;
+}
+
+void PCHDeclWriter::VisitObjCIvarDecl(ObjCIvarDecl *D) {
+  VisitFieldDecl(D);
+  // FIXME: stable encoding for @public/@private/@protected/@package
+  Record.push_back(D->getAccessControl());
+  Code = pch::DECL_OBJC_IVAR;
+}
+
+void PCHDeclWriter::VisitObjCProtocolDecl(ObjCProtocolDecl *D) {
+  VisitObjCContainerDecl(D);
+  Record.push_back(D->isForwardDecl());
+  Writer.AddSourceLocation(D->getLocEnd(), Record);
+  Record.push_back(D->protocol_size());
+  for (ObjCProtocolDecl::protocol_iterator
+       I = D->protocol_begin(), IEnd = D->protocol_end(); I != IEnd; ++I)
+    Writer.AddDeclRef(*I, Record);
+  for (ObjCProtocolDecl::protocol_loc_iterator PL = D->protocol_loc_begin(),
+         PLEnd = D->protocol_loc_end();
+       PL != PLEnd; ++PL)
+    Writer.AddSourceLocation(*PL, Record);
+  Code = pch::DECL_OBJC_PROTOCOL;
+}
+
+void PCHDeclWriter::VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl *D) {
+  VisitFieldDecl(D);
+  Code = pch::DECL_OBJC_AT_DEFS_FIELD;
+}
+
+void PCHDeclWriter::VisitObjCClassDecl(ObjCClassDecl *D) {
+  VisitDecl(D);
+  Record.push_back(D->size());
+  for (ObjCClassDecl::iterator I = D->begin(), IEnd = D->end(); I != IEnd; ++I)
+    Writer.AddDeclRef(I->getInterface(), Record);
+  for (ObjCClassDecl::iterator I = D->begin(), IEnd = D->end(); I != IEnd; ++I)
+    Writer.AddSourceLocation(I->getLocation(), Record);
+  Code = pch::DECL_OBJC_CLASS;
+}
+
+void PCHDeclWriter::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D) {
+  VisitDecl(D);
+  Record.push_back(D->protocol_size());
+  for (ObjCForwardProtocolDecl::protocol_iterator
+       I = D->protocol_begin(), IEnd = D->protocol_end(); I != IEnd; ++I)
+    Writer.AddDeclRef(*I, Record);
+  for (ObjCForwardProtocolDecl::protocol_loc_iterator 
+         PL = D->protocol_loc_begin(), PLEnd = D->protocol_loc_end();
+       PL != PLEnd; ++PL)
+    Writer.AddSourceLocation(*PL, Record);
+  Code = pch::DECL_OBJC_FORWARD_PROTOCOL;
+}
+
+void PCHDeclWriter::VisitObjCCategoryDecl(ObjCCategoryDecl *D) {
+  VisitObjCContainerDecl(D);
+  Writer.AddDeclRef(D->getClassInterface(), Record);
+  Record.push_back(D->protocol_size());
+  for (ObjCCategoryDecl::protocol_iterator
+       I = D->protocol_begin(), IEnd = D->protocol_end(); I != IEnd; ++I)
+    Writer.AddDeclRef(*I, Record);
+  for (ObjCCategoryDecl::protocol_loc_iterator 
+         PL = D->protocol_loc_begin(), PLEnd = D->protocol_loc_end();
+       PL != PLEnd; ++PL)
+    Writer.AddSourceLocation(*PL, Record);
+  Writer.AddDeclRef(D->getNextClassCategory(), Record);
+  Writer.AddSourceLocation(D->getAtLoc(), Record);
+  Writer.AddSourceLocation(D->getCategoryNameLoc(), Record);
+  Code = pch::DECL_OBJC_CATEGORY;
+}
+
+void PCHDeclWriter::VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *D) {
+  VisitNamedDecl(D);
+  Writer.AddDeclRef(D->getClassInterface(), Record);
+  Code = pch::DECL_OBJC_COMPATIBLE_ALIAS;
+}
+
+void PCHDeclWriter::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
+  VisitNamedDecl(D);
+  Writer.AddSourceLocation(D->getAtLoc(), Record);
+  Writer.AddTypeRef(D->getType(), Record);
+  // FIXME: stable encoding
+  Record.push_back((unsigned)D->getPropertyAttributes());
+  // FIXME: stable encoding
+  Record.push_back((unsigned)D->getPropertyImplementation());
+  Writer.AddDeclarationName(D->getGetterName(), Record);
+  Writer.AddDeclarationName(D->getSetterName(), Record);
+  Writer.AddDeclRef(D->getGetterMethodDecl(), Record);
+  Writer.AddDeclRef(D->getSetterMethodDecl(), Record);
+  Writer.AddDeclRef(D->getPropertyIvarDecl(), Record);
+  Code = pch::DECL_OBJC_PROPERTY;
+}
+
+void PCHDeclWriter::VisitObjCImplDecl(ObjCImplDecl *D) {
+  VisitObjCContainerDecl(D);
+  Writer.AddDeclRef(D->getClassInterface(), Record);
+  // Abstract class (no need to define a stable pch::DECL code).
+}
+
+void PCHDeclWriter::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
+  VisitObjCImplDecl(D);
+  Writer.AddIdentifierRef(D->getIdentifier(), Record);
+  Code = pch::DECL_OBJC_CATEGORY_IMPL;
+}
+
+void PCHDeclWriter::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
+  VisitObjCImplDecl(D);
+  Writer.AddDeclRef(D->getSuperClass(), Record);
+  Code = pch::DECL_OBJC_IMPLEMENTATION;
+}
+
+void PCHDeclWriter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
+  VisitDecl(D);
+  Writer.AddSourceLocation(D->getLocStart(), Record);
+  Writer.AddDeclRef(D->getPropertyDecl(), Record);
+  Writer.AddDeclRef(D->getPropertyIvarDecl(), Record);
+  Code = pch::DECL_OBJC_PROPERTY_IMPL;
+}
+
+void PCHDeclWriter::VisitFieldDecl(FieldDecl *D) {
+  VisitDeclaratorDecl(D);
+  Record.push_back(D->isMutable());
+  Record.push_back(D->getBitWidth()? 1 : 0);
+  if (D->getBitWidth())
+    Writer.AddStmt(D->getBitWidth());
+  Code = pch::DECL_FIELD;
+}
+
+void PCHDeclWriter::VisitVarDecl(VarDecl *D) {
+  VisitDeclaratorDecl(D);
+  Record.push_back(D->getStorageClass()); // FIXME: stable encoding
+  Record.push_back(D->getStorageClassAsWritten());
+  Record.push_back(D->isThreadSpecified());
+  Record.push_back(D->hasCXXDirectInitializer());
+  Record.push_back(D->isDeclaredInCondition());
+  Writer.AddDeclRef(D->getPreviousDeclaration(), Record);
+  Record.push_back(D->getInit()? 1 : 0);
+  if (D->getInit())
+    Writer.AddStmt(D->getInit());
+  Code = pch::DECL_VAR;
+}
+
+void PCHDeclWriter::VisitImplicitParamDecl(ImplicitParamDecl *D) {
+  VisitVarDecl(D);
+  Code = pch::DECL_IMPLICIT_PARAM;
+}
+
+void PCHDeclWriter::VisitParmVarDecl(ParmVarDecl *D) {
+  VisitVarDecl(D);
+  Record.push_back(D->getObjCDeclQualifier()); // FIXME: stable encoding
+  Record.push_back(D->hasInheritedDefaultArg());
+  Code = pch::DECL_PARM_VAR;
+
+
+  // If the assumptions about the DECL_PARM_VAR abbrev are true, use it.  Here
+  // we dynamically check for the properties that we optimize for, but don't
+  // know are true of all PARM_VAR_DECLs.
+  if (!D->getTypeSourceInfo() &&
+      !D->hasAttrs() &&
+      !D->isImplicit() &&
+      !D->isUsed() &&
+      D->getAccess() == AS_none &&
+      D->getPCHLevel() == 0 &&
+      D->getStorageClass() == 0 &&
+      !D->hasCXXDirectInitializer() && // Can params have this ever?
+      D->getObjCDeclQualifier() == 0 &&
+      !D->hasInheritedDefaultArg())
+    AbbrevToUse = Writer.getParmVarDeclAbbrev();
+
+  // Check things we know are true of *every* PARM_VAR_DECL, which is more than
+  // just us assuming it.
+  assert(!D->isInvalidDecl() && "Shouldn't emit invalid decls");
+  assert(!D->isThreadSpecified() && "PARM_VAR_DECL can't be __thread");
+  assert(D->getAccess() == AS_none && "PARM_VAR_DECL can't be public/private");
+  assert(!D->isDeclaredInCondition() && "PARM_VAR_DECL can't be in condition");
+  assert(D->getPreviousDeclaration() == 0 && "PARM_VAR_DECL can't be redecl");
+  assert(D->getInit() == 0 && "PARM_VAR_DECL never has init");
+}
+
+void PCHDeclWriter::VisitFileScopeAsmDecl(FileScopeAsmDecl *D) {
+  VisitDecl(D);
+  Writer.AddStmt(D->getAsmString());
+  Code = pch::DECL_FILE_SCOPE_ASM;
+}
+
+void PCHDeclWriter::VisitBlockDecl(BlockDecl *D) {
+  VisitDecl(D);
+  Writer.AddStmt(D->getBody());
+  Record.push_back(D->param_size());
+  for (FunctionDecl::param_iterator P = D->param_begin(), PEnd = D->param_end();
+       P != PEnd; ++P)
+    Writer.AddDeclRef(*P, Record);
+  Code = pch::DECL_BLOCK;
+}
+
+/// \brief Emit the DeclContext part of a declaration context decl.
+///
+/// \param LexicalOffset the offset at which the DECL_CONTEXT_LEXICAL
+/// block for this declaration context is stored. May be 0 to indicate
+/// that there are no declarations stored within this context.
+///
+/// \param VisibleOffset the offset at which the DECL_CONTEXT_VISIBLE
+/// block for this declaration context is stored. May be 0 to indicate
+/// that there are no declarations visible from this context. Note
+/// that this value will not be emitted for non-primary declaration
+/// contexts.
+void PCHDeclWriter::VisitDeclContext(DeclContext *DC, uint64_t LexicalOffset,
+                                     uint64_t VisibleOffset) {
+  Record.push_back(LexicalOffset);
+  Record.push_back(VisibleOffset);
+}
+
+
+//===----------------------------------------------------------------------===//
+// PCHWriter Implementation
+//===----------------------------------------------------------------------===//
+
+void PCHWriter::WriteDeclsBlockAbbrevs() {
+  using namespace llvm;
+  // Abbreviation for DECL_PARM_VAR.
+  BitCodeAbbrev *Abv = new BitCodeAbbrev();
+  Abv->Add(BitCodeAbbrevOp(pch::DECL_PARM_VAR));
+
+  // Decl
+  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
+  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalDeclContext
+  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Location
+  Abv->Add(BitCodeAbbrevOp(0));                       // isInvalidDecl (!?)
+  Abv->Add(BitCodeAbbrevOp(0));                       // HasAttrs
+  Abv->Add(BitCodeAbbrevOp(0));                       // isImplicit
+  Abv->Add(BitCodeAbbrevOp(0));                       // isUsed
+  Abv->Add(BitCodeAbbrevOp(AS_none));                 // C++ AccessSpecifier
+  Abv->Add(BitCodeAbbrevOp(0));                       // PCH level
+
+  // NamedDecl
+  Abv->Add(BitCodeAbbrevOp(0));                       // NameKind = Identifier
+  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name
+  // ValueDecl
+  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
+  // DeclaratorDecl
+  Abv->Add(BitCodeAbbrevOp(pch::PREDEF_TYPE_NULL_ID)); // InfoType
+  // VarDecl
+  Abv->Add(BitCodeAbbrevOp(0));                       // StorageClass
+  Abv->Add(BitCodeAbbrevOp(0));                       // StorageClassAsWritten
+  Abv->Add(BitCodeAbbrevOp(0));                       // isThreadSpecified
+  Abv->Add(BitCodeAbbrevOp(0));                       // hasCXXDirectInitializer
+  Abv->Add(BitCodeAbbrevOp(0));                       // isDeclaredInCondition
+  Abv->Add(BitCodeAbbrevOp(0));                       // PrevDecl
+  Abv->Add(BitCodeAbbrevOp(0));                       // HasInit
+  // ParmVarDecl
+  Abv->Add(BitCodeAbbrevOp(0));                       // ObjCDeclQualifier
+  Abv->Add(BitCodeAbbrevOp(0));                       // HasInheritedDefaultArg
+
+  ParmVarDeclAbbrev = Stream.EmitAbbrev(Abv);
+}
+
+/// isRequiredDecl - Check if this is a "required" Decl, which must be seen by
+/// consumers of the AST.
+///
+/// Such decls will always be deserialized from the PCH file, so we would like
+/// this to be as restrictive as possible. Currently the predicate is driven by
+/// code generation requirements, if other clients have a different notion of
+/// what is "required" then we may have to consider an alternate scheme where
+/// clients can iterate over the top-level decls and get information on them,
+/// without necessary deserializing them. We could explicitly require such
+/// clients to use a separate API call to "realize" the decl. This should be
+/// relatively painless since they would presumably only do it for top-level
+/// decls.
+//
+// FIXME: This predicate is essentially IRgen's predicate to determine whether a
+// declaration can be deferred. Merge them somehow.
+static bool isRequiredDecl(const Decl *D, ASTContext &Context) {
+  // File scoped assembly must be seen.
+  if (isa<FileScopeAsmDecl>(D))
+    return true;
+
+  // Otherwise if this isn't a function or a file scoped variable it doesn't
+  // need to be seen.
+  if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
+    if (!VD->isFileVarDecl())
+      return false;
+  } else if (!isa<FunctionDecl>(D))
+    return false;
+
+  // Aliases and used decls must be seen.
+  if (D->hasAttr<AliasAttr>() || D->hasAttr<UsedAttr>())
+    return true;
+
+  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+    // Forward declarations don't need to be seen.
+    if (!FD->isThisDeclarationADefinition())
+      return false;
+
+    // Constructors and destructors must be seen.
+    if (FD->hasAttr<ConstructorAttr>() || FD->hasAttr<DestructorAttr>())
+      return true;
+
+    // Otherwise, this is required unless it is static.
+    //
+    // FIXME: Inlines.
+    return FD->getStorageClass() != FunctionDecl::Static;
+  } else {
+    const VarDecl *VD = cast<VarDecl>(D);
+
+    // In C++, this doesn't need to be seen if it is marked "extern".
+    if (Context.getLangOptions().CPlusPlus && !VD->getInit() &&
+        (VD->getStorageClass() == VarDecl::Extern ||
+         VD->isExternC()))
+      return false;
+
+    // In C, this doesn't need to be seen unless it is a definition.
+    if (!Context.getLangOptions().CPlusPlus && !VD->getInit())
+      return false;
+
+    // Otherwise, this is required unless it is static.
+    return VD->getStorageClass() != VarDecl::Static;
+  }
+}
+
+void PCHWriter::WriteDecl(ASTContext &Context, Decl *D) {
+  RecordData Record;
+  PCHDeclWriter W(*this, Context, Record);
+
+  // If this declaration is also a DeclContext, write blocks for the
+  // declarations that lexically stored inside its context and those
+  // declarations that are visible from its context. These blocks
+  // are written before the declaration itself so that we can put
+  // their offsets into the record for the declaration.
+  uint64_t LexicalOffset = 0;
+  uint64_t VisibleOffset = 0;
+  DeclContext *DC = dyn_cast<DeclContext>(D);
+  if (DC) {
+    LexicalOffset = WriteDeclContextLexicalBlock(Context, DC);
+    VisibleOffset = WriteDeclContextVisibleBlock(Context, DC);
+  }
+
+  // Determine the ID for this declaration
+  pch::DeclID &ID = DeclIDs[D];
+  if (ID == 0)
+    ID = DeclIDs.size();
+
+  unsigned Index = ID - 1;
+
+  // Record the offset for this declaration
+  if (DeclOffsets.size() == Index)
+    DeclOffsets.push_back(Stream.GetCurrentBitNo());
+  else if (DeclOffsets.size() < Index) {
+    DeclOffsets.resize(Index+1);
+    DeclOffsets[Index] = Stream.GetCurrentBitNo();
+  }
+
+  // Build and emit a record for this declaration
+  Record.clear();
+  W.Code = (pch::DeclCode)0;
+  W.AbbrevToUse = 0;
+  W.Visit(D);
+  if (DC) W.VisitDeclContext(DC, LexicalOffset, VisibleOffset);
+
+  if (!W.Code)
+    llvm::report_fatal_error(llvm::StringRef("unexpected declaration kind '") +
+                            D->getDeclKindName() + "'");
+  Stream.EmitRecord(W.Code, Record, W.AbbrevToUse);
+
+  // If the declaration had any attributes, write them now.
+  if (D->hasAttrs())
+    WriteAttributeRecord(D->getAttrs());
+
+  // Flush any expressions that were written as part of this declaration.
+  FlushStmts();
+
+  // Note "external" declarations so that we can add them to a record in the
+  // PCH file later.
+  //
+  // FIXME: This should be renamed, the predicate is much more complicated.
+  if (isRequiredDecl(D, Context))
+    ExternalDefinitions.push_back(Index + 1);
+}
diff --git a/lib/Frontend/PCHWriterStmt.cpp b/lib/Frontend/PCHWriterStmt.cpp
new file mode 100644
index 0000000..a0ea5c9
--- /dev/null
+++ b/lib/Frontend/PCHWriterStmt.cpp
@@ -0,0 +1,952 @@
+//===--- PCHWriterStmt.cpp - Statement and Expression Serialization -------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements serialization for Statements and Expressions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/PCHWriter.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/StmtVisitor.h"
+#include "llvm/Bitcode/BitstreamWriter.h"
+using namespace clang;
+
+//===----------------------------------------------------------------------===//
+// Statement/expression serialization
+//===----------------------------------------------------------------------===//
+
+namespace {
+  class PCHStmtWriter : public StmtVisitor<PCHStmtWriter, void> {
+    PCHWriter &Writer;
+    PCHWriter::RecordData &Record;
+
+  public:
+    pch::StmtCode Code;
+
+    PCHStmtWriter(PCHWriter &Writer, PCHWriter::RecordData &Record)
+      : Writer(Writer), Record(Record) { }
+
+    void VisitStmt(Stmt *S);
+    void VisitNullStmt(NullStmt *S);
+    void VisitCompoundStmt(CompoundStmt *S);
+    void VisitSwitchCase(SwitchCase *S);
+    void VisitCaseStmt(CaseStmt *S);
+    void VisitDefaultStmt(DefaultStmt *S);
+    void VisitLabelStmt(LabelStmt *S);
+    void VisitIfStmt(IfStmt *S);
+    void VisitSwitchStmt(SwitchStmt *S);
+    void VisitWhileStmt(WhileStmt *S);
+    void VisitDoStmt(DoStmt *S);
+    void VisitForStmt(ForStmt *S);
+    void VisitGotoStmt(GotoStmt *S);
+    void VisitIndirectGotoStmt(IndirectGotoStmt *S);
+    void VisitContinueStmt(ContinueStmt *S);
+    void VisitBreakStmt(BreakStmt *S);
+    void VisitReturnStmt(ReturnStmt *S);
+    void VisitDeclStmt(DeclStmt *S);
+    void VisitAsmStmt(AsmStmt *S);
+    void VisitExpr(Expr *E);
+    void VisitPredefinedExpr(PredefinedExpr *E);
+    void VisitDeclRefExpr(DeclRefExpr *E);
+    void VisitIntegerLiteral(IntegerLiteral *E);
+    void VisitFloatingLiteral(FloatingLiteral *E);
+    void VisitImaginaryLiteral(ImaginaryLiteral *E);
+    void VisitStringLiteral(StringLiteral *E);
+    void VisitCharacterLiteral(CharacterLiteral *E);
+    void VisitParenExpr(ParenExpr *E);
+    void VisitUnaryOperator(UnaryOperator *E);
+    void VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E);
+    void VisitArraySubscriptExpr(ArraySubscriptExpr *E);
+    void VisitCallExpr(CallExpr *E);
+    void VisitMemberExpr(MemberExpr *E);
+    void VisitCastExpr(CastExpr *E);
+    void VisitBinaryOperator(BinaryOperator *E);
+    void VisitCompoundAssignOperator(CompoundAssignOperator *E);
+    void VisitConditionalOperator(ConditionalOperator *E);
+    void VisitImplicitCastExpr(ImplicitCastExpr *E);
+    void VisitExplicitCastExpr(ExplicitCastExpr *E);
+    void VisitCStyleCastExpr(CStyleCastExpr *E);
+    void VisitCompoundLiteralExpr(CompoundLiteralExpr *E);
+    void VisitExtVectorElementExpr(ExtVectorElementExpr *E);
+    void VisitInitListExpr(InitListExpr *E);
+    void VisitDesignatedInitExpr(DesignatedInitExpr *E);
+    void VisitImplicitValueInitExpr(ImplicitValueInitExpr *E);
+    void VisitVAArgExpr(VAArgExpr *E);
+    void VisitAddrLabelExpr(AddrLabelExpr *E);
+    void VisitStmtExpr(StmtExpr *E);
+    void VisitTypesCompatibleExpr(TypesCompatibleExpr *E);
+    void VisitChooseExpr(ChooseExpr *E);
+    void VisitGNUNullExpr(GNUNullExpr *E);
+    void VisitShuffleVectorExpr(ShuffleVectorExpr *E);
+    void VisitBlockExpr(BlockExpr *E);
+    void VisitBlockDeclRefExpr(BlockDeclRefExpr *E);
+
+    // Objective-C Expressions
+    void VisitObjCStringLiteral(ObjCStringLiteral *E);
+    void VisitObjCEncodeExpr(ObjCEncodeExpr *E);
+    void VisitObjCSelectorExpr(ObjCSelectorExpr *E);
+    void VisitObjCProtocolExpr(ObjCProtocolExpr *E);
+    void VisitObjCIvarRefExpr(ObjCIvarRefExpr *E);
+    void VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E);
+    void VisitObjCImplicitSetterGetterRefExpr(
+                        ObjCImplicitSetterGetterRefExpr *E);
+    void VisitObjCMessageExpr(ObjCMessageExpr *E);
+    void VisitObjCSuperExpr(ObjCSuperExpr *E);
+    void VisitObjCIsaExpr(ObjCIsaExpr *E);
+
+    // Objective-C Statements
+    void VisitObjCForCollectionStmt(ObjCForCollectionStmt *);
+    void VisitObjCAtCatchStmt(ObjCAtCatchStmt *);
+    void VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *);
+    void VisitObjCAtTryStmt(ObjCAtTryStmt *);
+    void VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *);
+    void VisitObjCAtThrowStmt(ObjCAtThrowStmt *);
+
+    // C++ Statements
+    void VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E);
+    void VisitCXXConstructExpr(CXXConstructExpr *E);
+    void VisitCXXNamedCastExpr(CXXNamedCastExpr *E);
+    void VisitCXXStaticCastExpr(CXXStaticCastExpr *E);
+    void VisitCXXDynamicCastExpr(CXXDynamicCastExpr *E);
+    void VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *E);
+    void VisitCXXConstCastExpr(CXXConstCastExpr *E);
+    void VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E);
+    void VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E);
+    void VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E);
+  };
+}
+
+void PCHStmtWriter::VisitStmt(Stmt *S) {
+}
+
+void PCHStmtWriter::VisitNullStmt(NullStmt *S) {
+  VisitStmt(S);
+  Writer.AddSourceLocation(S->getSemiLoc(), Record);
+  Code = pch::STMT_NULL;
+}
+
+void PCHStmtWriter::VisitCompoundStmt(CompoundStmt *S) {
+  VisitStmt(S);
+  Record.push_back(S->size());
+  for (CompoundStmt::body_iterator CS = S->body_begin(), CSEnd = S->body_end();
+       CS != CSEnd; ++CS)
+    Writer.WriteSubStmt(*CS);
+  Writer.AddSourceLocation(S->getLBracLoc(), Record);
+  Writer.AddSourceLocation(S->getRBracLoc(), Record);
+  Code = pch::STMT_COMPOUND;
+}
+
+void PCHStmtWriter::VisitSwitchCase(SwitchCase *S) {
+  VisitStmt(S);
+  Record.push_back(Writer.RecordSwitchCaseID(S));
+}
+
+void PCHStmtWriter::VisitCaseStmt(CaseStmt *S) {
+  VisitSwitchCase(S);
+  Writer.WriteSubStmt(S->getLHS());
+  Writer.WriteSubStmt(S->getRHS());
+  Writer.WriteSubStmt(S->getSubStmt());
+  Writer.AddSourceLocation(S->getCaseLoc(), Record);
+  Writer.AddSourceLocation(S->getEllipsisLoc(), Record);
+  Writer.AddSourceLocation(S->getColonLoc(), Record);
+  Code = pch::STMT_CASE;
+}
+
+void PCHStmtWriter::VisitDefaultStmt(DefaultStmt *S) {
+  VisitSwitchCase(S);
+  Writer.WriteSubStmt(S->getSubStmt());
+  Writer.AddSourceLocation(S->getDefaultLoc(), Record);
+  Writer.AddSourceLocation(S->getColonLoc(), Record);
+  Code = pch::STMT_DEFAULT;
+}
+
+void PCHStmtWriter::VisitLabelStmt(LabelStmt *S) {
+  VisitStmt(S);
+  Writer.AddIdentifierRef(S->getID(), Record);
+  Writer.WriteSubStmt(S->getSubStmt());
+  Writer.AddSourceLocation(S->getIdentLoc(), Record);
+  Record.push_back(Writer.GetLabelID(S));
+  Code = pch::STMT_LABEL;
+}
+
+void PCHStmtWriter::VisitIfStmt(IfStmt *S) {
+  VisitStmt(S);
+  Writer.AddDeclRef(S->getConditionVariable(), Record);
+  Writer.WriteSubStmt(S->getCond());
+  Writer.WriteSubStmt(S->getThen());
+  Writer.WriteSubStmt(S->getElse());
+  Writer.AddSourceLocation(S->getIfLoc(), Record);
+  Writer.AddSourceLocation(S->getElseLoc(), Record);
+  Code = pch::STMT_IF;
+}
+
+void PCHStmtWriter::VisitSwitchStmt(SwitchStmt *S) {
+  VisitStmt(S);
+  Writer.AddDeclRef(S->getConditionVariable(), Record);
+  Writer.WriteSubStmt(S->getCond());
+  Writer.WriteSubStmt(S->getBody());
+  Writer.AddSourceLocation(S->getSwitchLoc(), Record);
+  for (SwitchCase *SC = S->getSwitchCaseList(); SC;
+       SC = SC->getNextSwitchCase())
+    Record.push_back(Writer.getSwitchCaseID(SC));
+  Code = pch::STMT_SWITCH;
+}
+
+void PCHStmtWriter::VisitWhileStmt(WhileStmt *S) {
+  VisitStmt(S);
+  Writer.AddDeclRef(S->getConditionVariable(), Record);
+  Writer.WriteSubStmt(S->getCond());
+  Writer.WriteSubStmt(S->getBody());
+  Writer.AddSourceLocation(S->getWhileLoc(), Record);
+  Code = pch::STMT_WHILE;
+}
+
+void PCHStmtWriter::VisitDoStmt(DoStmt *S) {
+  VisitStmt(S);
+  Writer.WriteSubStmt(S->getCond());
+  Writer.WriteSubStmt(S->getBody());
+  Writer.AddSourceLocation(S->getDoLoc(), Record);
+  Writer.AddSourceLocation(S->getWhileLoc(), Record);
+  Writer.AddSourceLocation(S->getRParenLoc(), Record);
+  Code = pch::STMT_DO;
+}
+
+void PCHStmtWriter::VisitForStmt(ForStmt *S) {
+  VisitStmt(S);
+  Writer.WriteSubStmt(S->getInit());
+  Writer.WriteSubStmt(S->getCond());
+  Writer.AddDeclRef(S->getConditionVariable(), Record);
+  Writer.WriteSubStmt(S->getInc());
+  Writer.WriteSubStmt(S->getBody());
+  Writer.AddSourceLocation(S->getForLoc(), Record);
+  Writer.AddSourceLocation(S->getLParenLoc(), Record);
+  Writer.AddSourceLocation(S->getRParenLoc(), Record);
+  Code = pch::STMT_FOR;
+}
+
+void PCHStmtWriter::VisitGotoStmt(GotoStmt *S) {
+  VisitStmt(S);
+  Record.push_back(Writer.GetLabelID(S->getLabel()));
+  Writer.AddSourceLocation(S->getGotoLoc(), Record);
+  Writer.AddSourceLocation(S->getLabelLoc(), Record);
+  Code = pch::STMT_GOTO;
+}
+
+void PCHStmtWriter::VisitIndirectGotoStmt(IndirectGotoStmt *S) {
+  VisitStmt(S);
+  Writer.AddSourceLocation(S->getGotoLoc(), Record);
+  Writer.AddSourceLocation(S->getStarLoc(), Record);
+  Writer.WriteSubStmt(S->getTarget());
+  Code = pch::STMT_INDIRECT_GOTO;
+}
+
+void PCHStmtWriter::VisitContinueStmt(ContinueStmt *S) {
+  VisitStmt(S);
+  Writer.AddSourceLocation(S->getContinueLoc(), Record);
+  Code = pch::STMT_CONTINUE;
+}
+
+void PCHStmtWriter::VisitBreakStmt(BreakStmt *S) {
+  VisitStmt(S);
+  Writer.AddSourceLocation(S->getBreakLoc(), Record);
+  Code = pch::STMT_BREAK;
+}
+
+void PCHStmtWriter::VisitReturnStmt(ReturnStmt *S) {
+  VisitStmt(S);
+  Writer.WriteSubStmt(S->getRetValue());
+  Writer.AddSourceLocation(S->getReturnLoc(), Record);
+  Code = pch::STMT_RETURN;
+}
+
+void PCHStmtWriter::VisitDeclStmt(DeclStmt *S) {
+  VisitStmt(S);
+  Writer.AddSourceLocation(S->getStartLoc(), Record);
+  Writer.AddSourceLocation(S->getEndLoc(), Record);
+  DeclGroupRef DG = S->getDeclGroup();
+  for (DeclGroupRef::iterator D = DG.begin(), DEnd = DG.end(); D != DEnd; ++D)
+    Writer.AddDeclRef(*D, Record);
+  Code = pch::STMT_DECL;
+}
+
+void PCHStmtWriter::VisitAsmStmt(AsmStmt *S) {
+  VisitStmt(S);
+  Record.push_back(S->getNumOutputs());
+  Record.push_back(S->getNumInputs());
+  Record.push_back(S->getNumClobbers());
+  Writer.AddSourceLocation(S->getAsmLoc(), Record);
+  Writer.AddSourceLocation(S->getRParenLoc(), Record);
+  Record.push_back(S->isVolatile());
+  Record.push_back(S->isSimple());
+  Record.push_back(S->isMSAsm());
+  Writer.WriteSubStmt(S->getAsmString());
+
+  // Outputs
+  for (unsigned I = 0, N = S->getNumOutputs(); I != N; ++I) {      
+    Writer.AddIdentifierRef(S->getOutputIdentifier(I), Record);
+    Writer.WriteSubStmt(S->getOutputConstraintLiteral(I));
+    Writer.WriteSubStmt(S->getOutputExpr(I));
+  }
+
+  // Inputs
+  for (unsigned I = 0, N = S->getNumInputs(); I != N; ++I) {
+    Writer.AddIdentifierRef(S->getInputIdentifier(I), Record);
+    Writer.WriteSubStmt(S->getInputConstraintLiteral(I));
+    Writer.WriteSubStmt(S->getInputExpr(I));
+  }
+
+  // Clobbers
+  for (unsigned I = 0, N = S->getNumClobbers(); I != N; ++I)
+    Writer.WriteSubStmt(S->getClobber(I));
+
+  Code = pch::STMT_ASM;
+}
+
+void PCHStmtWriter::VisitExpr(Expr *E) {
+  VisitStmt(E);
+  Writer.AddTypeRef(E->getType(), Record);
+  Record.push_back(E->isTypeDependent());
+  Record.push_back(E->isValueDependent());
+}
+
+void PCHStmtWriter::VisitPredefinedExpr(PredefinedExpr *E) {
+  VisitExpr(E);
+  Writer.AddSourceLocation(E->getLocation(), Record);
+  Record.push_back(E->getIdentType()); // FIXME: stable encoding
+  Code = pch::EXPR_PREDEFINED;
+}
+
+void PCHStmtWriter::VisitDeclRefExpr(DeclRefExpr *E) {
+  VisitExpr(E);
+  Writer.AddDeclRef(E->getDecl(), Record);
+  Writer.AddSourceLocation(E->getLocation(), Record);
+  // FIXME: write qualifier
+  // FIXME: write explicit template arguments
+  Code = pch::EXPR_DECL_REF;
+}
+
+void PCHStmtWriter::VisitIntegerLiteral(IntegerLiteral *E) {
+  VisitExpr(E);
+  Writer.AddSourceLocation(E->getLocation(), Record);
+  Writer.AddAPInt(E->getValue(), Record);
+  Code = pch::EXPR_INTEGER_LITERAL;
+}
+
+void PCHStmtWriter::VisitFloatingLiteral(FloatingLiteral *E) {
+  VisitExpr(E);
+  Writer.AddAPFloat(E->getValue(), Record);
+  Record.push_back(E->isExact());
+  Writer.AddSourceLocation(E->getLocation(), Record);
+  Code = pch::EXPR_FLOATING_LITERAL;
+}
+
+void PCHStmtWriter::VisitImaginaryLiteral(ImaginaryLiteral *E) {
+  VisitExpr(E);
+  Writer.WriteSubStmt(E->getSubExpr());
+  Code = pch::EXPR_IMAGINARY_LITERAL;
+}
+
+void PCHStmtWriter::VisitStringLiteral(StringLiteral *E) {
+  VisitExpr(E);
+  Record.push_back(E->getByteLength());
+  Record.push_back(E->getNumConcatenated());
+  Record.push_back(E->isWide());
+  // FIXME: String data should be stored as a blob at the end of the
+  // StringLiteral. However, we can't do so now because we have no
+  // provision for coping with abbreviations when we're jumping around
+  // the PCH file during deserialization.
+  Record.insert(Record.end(),
+                E->getStrData(), E->getStrData() + E->getByteLength());
+  for (unsigned I = 0, N = E->getNumConcatenated(); I != N; ++I)
+    Writer.AddSourceLocation(E->getStrTokenLoc(I), Record);
+  Code = pch::EXPR_STRING_LITERAL;
+}
+
+void PCHStmtWriter::VisitCharacterLiteral(CharacterLiteral *E) {
+  VisitExpr(E);
+  Record.push_back(E->getValue());
+  Writer.AddSourceLocation(E->getLocation(), Record);
+  Record.push_back(E->isWide());
+  Code = pch::EXPR_CHARACTER_LITERAL;
+}
+
+void PCHStmtWriter::VisitParenExpr(ParenExpr *E) {
+  VisitExpr(E);
+  Writer.AddSourceLocation(E->getLParen(), Record);
+  Writer.AddSourceLocation(E->getRParen(), Record);
+  Writer.WriteSubStmt(E->getSubExpr());
+  Code = pch::EXPR_PAREN;
+}
+
+void PCHStmtWriter::VisitUnaryOperator(UnaryOperator *E) {
+  VisitExpr(E);
+  Writer.WriteSubStmt(E->getSubExpr());
+  Record.push_back(E->getOpcode()); // FIXME: stable encoding
+  Writer.AddSourceLocation(E->getOperatorLoc(), Record);
+  Code = pch::EXPR_UNARY_OPERATOR;
+}
+
+void PCHStmtWriter::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) {
+  VisitExpr(E);
+  Record.push_back(E->isSizeOf());
+  if (E->isArgumentType())
+    Writer.AddTypeSourceInfo(E->getArgumentTypeInfo(), Record);
+  else {
+    Record.push_back(0);
+    Writer.WriteSubStmt(E->getArgumentExpr());
+  }
+  Writer.AddSourceLocation(E->getOperatorLoc(), Record);
+  Writer.AddSourceLocation(E->getRParenLoc(), Record);
+  Code = pch::EXPR_SIZEOF_ALIGN_OF;
+}
+
+void PCHStmtWriter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
+  VisitExpr(E);
+  Writer.WriteSubStmt(E->getLHS());
+  Writer.WriteSubStmt(E->getRHS());
+  Writer.AddSourceLocation(E->getRBracketLoc(), Record);
+  Code = pch::EXPR_ARRAY_SUBSCRIPT;
+}
+
+void PCHStmtWriter::VisitCallExpr(CallExpr *E) {
+  VisitExpr(E);
+  Record.push_back(E->getNumArgs());
+  Writer.AddSourceLocation(E->getRParenLoc(), Record);
+  Writer.WriteSubStmt(E->getCallee());
+  for (CallExpr::arg_iterator Arg = E->arg_begin(), ArgEnd = E->arg_end();
+       Arg != ArgEnd; ++Arg)
+    Writer.WriteSubStmt(*Arg);
+  Code = pch::EXPR_CALL;
+}
+
+void PCHStmtWriter::VisitMemberExpr(MemberExpr *E) {
+  VisitExpr(E);
+  Writer.WriteSubStmt(E->getBase());
+  Writer.AddDeclRef(E->getMemberDecl(), Record);
+  Writer.AddSourceLocation(E->getMemberLoc(), Record);
+  Record.push_back(E->isArrow());
+  // FIXME: C++ nested-name-specifier
+  // FIXME: C++ template argument list
+  Code = pch::EXPR_MEMBER;
+}
+
+void PCHStmtWriter::VisitObjCIsaExpr(ObjCIsaExpr *E) {
+  VisitExpr(E);
+  Writer.WriteSubStmt(E->getBase());
+  Writer.AddSourceLocation(E->getIsaMemberLoc(), Record);
+  Record.push_back(E->isArrow());
+  Code = pch::EXPR_OBJC_ISA;
+}
+
+void PCHStmtWriter::VisitCastExpr(CastExpr *E) {
+  VisitExpr(E);
+  Writer.WriteSubStmt(E->getSubExpr());
+  Record.push_back(E->getCastKind()); // FIXME: stable encoding
+}
+
+void PCHStmtWriter::VisitBinaryOperator(BinaryOperator *E) {
+  VisitExpr(E);
+  Writer.WriteSubStmt(E->getLHS());
+  Writer.WriteSubStmt(E->getRHS());
+  Record.push_back(E->getOpcode()); // FIXME: stable encoding
+  Writer.AddSourceLocation(E->getOperatorLoc(), Record);
+  Code = pch::EXPR_BINARY_OPERATOR;
+}
+
+void PCHStmtWriter::VisitCompoundAssignOperator(CompoundAssignOperator *E) {
+  VisitBinaryOperator(E);
+  Writer.AddTypeRef(E->getComputationLHSType(), Record);
+  Writer.AddTypeRef(E->getComputationResultType(), Record);
+  Code = pch::EXPR_COMPOUND_ASSIGN_OPERATOR;
+}
+
+void PCHStmtWriter::VisitConditionalOperator(ConditionalOperator *E) {
+  VisitExpr(E);
+  Writer.WriteSubStmt(E->getCond());
+  Writer.WriteSubStmt(E->getLHS());
+  Writer.WriteSubStmt(E->getRHS());
+  Writer.AddSourceLocation(E->getQuestionLoc(), Record);
+  Writer.AddSourceLocation(E->getColonLoc(), Record);
+  Code = pch::EXPR_CONDITIONAL_OPERATOR;
+}
+
+void PCHStmtWriter::VisitImplicitCastExpr(ImplicitCastExpr *E) {
+  VisitCastExpr(E);
+  Record.push_back(E->isLvalueCast());
+  Code = pch::EXPR_IMPLICIT_CAST;
+}
+
+void PCHStmtWriter::VisitExplicitCastExpr(ExplicitCastExpr *E) {
+  VisitCastExpr(E);
+  Writer.AddTypeSourceInfo(E->getTypeInfoAsWritten(), Record);
+}
+
+void PCHStmtWriter::VisitCStyleCastExpr(CStyleCastExpr *E) {
+  VisitExplicitCastExpr(E);
+  Writer.AddSourceLocation(E->getLParenLoc(), Record);
+  Writer.AddSourceLocation(E->getRParenLoc(), Record);
+  Code = pch::EXPR_CSTYLE_CAST;
+}
+
+void PCHStmtWriter::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
+  VisitExpr(E);
+  Writer.AddSourceLocation(E->getLParenLoc(), Record);
+  Writer.AddTypeSourceInfo(E->getTypeSourceInfo(), Record);
+  Writer.WriteSubStmt(E->getInitializer());
+  Record.push_back(E->isFileScope());
+  Code = pch::EXPR_COMPOUND_LITERAL;
+}
+
+void PCHStmtWriter::VisitExtVectorElementExpr(ExtVectorElementExpr *E) {
+  VisitExpr(E);
+  Writer.WriteSubStmt(E->getBase());
+  Writer.AddIdentifierRef(&E->getAccessor(), Record);
+  Writer.AddSourceLocation(E->getAccessorLoc(), Record);
+  Code = pch::EXPR_EXT_VECTOR_ELEMENT;
+}
+
+void PCHStmtWriter::VisitInitListExpr(InitListExpr *E) {
+  VisitExpr(E);
+  Record.push_back(E->getNumInits());
+  for (unsigned I = 0, N = E->getNumInits(); I != N; ++I)
+    Writer.WriteSubStmt(E->getInit(I));
+  Writer.WriteSubStmt(E->getSyntacticForm());
+  Writer.AddSourceLocation(E->getLBraceLoc(), Record);
+  Writer.AddSourceLocation(E->getRBraceLoc(), Record);
+  Writer.AddDeclRef(E->getInitializedFieldInUnion(), Record);
+  Record.push_back(E->hadArrayRangeDesignator());
+  Code = pch::EXPR_INIT_LIST;
+}
+
+void PCHStmtWriter::VisitDesignatedInitExpr(DesignatedInitExpr *E) {
+  VisitExpr(E);
+  Record.push_back(E->getNumSubExprs());
+  for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I)
+    Writer.WriteSubStmt(E->getSubExpr(I));
+  Writer.AddSourceLocation(E->getEqualOrColonLoc(), Record);
+  Record.push_back(E->usesGNUSyntax());
+  for (DesignatedInitExpr::designators_iterator D = E->designators_begin(),
+                                             DEnd = E->designators_end();
+       D != DEnd; ++D) {
+    if (D->isFieldDesignator()) {
+      if (FieldDecl *Field = D->getField()) {
+        Record.push_back(pch::DESIG_FIELD_DECL);
+        Writer.AddDeclRef(Field, Record);
+      } else {
+        Record.push_back(pch::DESIG_FIELD_NAME);
+        Writer.AddIdentifierRef(D->getFieldName(), Record);
+      }
+      Writer.AddSourceLocation(D->getDotLoc(), Record);
+      Writer.AddSourceLocation(D->getFieldLoc(), Record);
+    } else if (D->isArrayDesignator()) {
+      Record.push_back(pch::DESIG_ARRAY);
+      Record.push_back(D->getFirstExprIndex());
+      Writer.AddSourceLocation(D->getLBracketLoc(), Record);
+      Writer.AddSourceLocation(D->getRBracketLoc(), Record);
+    } else {
+      assert(D->isArrayRangeDesignator() && "Unknown designator");
+      Record.push_back(pch::DESIG_ARRAY_RANGE);
+      Record.push_back(D->getFirstExprIndex());
+      Writer.AddSourceLocation(D->getLBracketLoc(), Record);
+      Writer.AddSourceLocation(D->getEllipsisLoc(), Record);
+      Writer.AddSourceLocation(D->getRBracketLoc(), Record);
+    }
+  }
+  Code = pch::EXPR_DESIGNATED_INIT;
+}
+
+void PCHStmtWriter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) {
+  VisitExpr(E);
+  Code = pch::EXPR_IMPLICIT_VALUE_INIT;
+}
+
+void PCHStmtWriter::VisitVAArgExpr(VAArgExpr *E) {
+  VisitExpr(E);
+  Writer.WriteSubStmt(E->getSubExpr());
+  Writer.AddSourceLocation(E->getBuiltinLoc(), Record);
+  Writer.AddSourceLocation(E->getRParenLoc(), Record);
+  Code = pch::EXPR_VA_ARG;
+}
+
+void PCHStmtWriter::VisitAddrLabelExpr(AddrLabelExpr *E) {
+  VisitExpr(E);
+  Writer.AddSourceLocation(E->getAmpAmpLoc(), Record);
+  Writer.AddSourceLocation(E->getLabelLoc(), Record);
+  Record.push_back(Writer.GetLabelID(E->getLabel()));
+  Code = pch::EXPR_ADDR_LABEL;
+}
+
+void PCHStmtWriter::VisitStmtExpr(StmtExpr *E) {
+  VisitExpr(E);
+  Writer.WriteSubStmt(E->getSubStmt());
+  Writer.AddSourceLocation(E->getLParenLoc(), Record);
+  Writer.AddSourceLocation(E->getRParenLoc(), Record);
+  Code = pch::EXPR_STMT;
+}
+
+void PCHStmtWriter::VisitTypesCompatibleExpr(TypesCompatibleExpr *E) {
+  VisitExpr(E);
+  Writer.AddTypeRef(E->getArgType1(), Record);
+  Writer.AddTypeRef(E->getArgType2(), Record);
+  Writer.AddSourceLocation(E->getBuiltinLoc(), Record);
+  Writer.AddSourceLocation(E->getRParenLoc(), Record);
+  Code = pch::EXPR_TYPES_COMPATIBLE;
+}
+
+void PCHStmtWriter::VisitChooseExpr(ChooseExpr *E) {
+  VisitExpr(E);
+  Writer.WriteSubStmt(E->getCond());
+  Writer.WriteSubStmt(E->getLHS());
+  Writer.WriteSubStmt(E->getRHS());
+  Writer.AddSourceLocation(E->getBuiltinLoc(), Record);
+  Writer.AddSourceLocation(E->getRParenLoc(), Record);
+  Code = pch::EXPR_CHOOSE;
+}
+
+void PCHStmtWriter::VisitGNUNullExpr(GNUNullExpr *E) {
+  VisitExpr(E);
+  Writer.AddSourceLocation(E->getTokenLocation(), Record);
+  Code = pch::EXPR_GNU_NULL;
+}
+
+void PCHStmtWriter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
+  VisitExpr(E);
+  Record.push_back(E->getNumSubExprs());
+  for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I)
+    Writer.WriteSubStmt(E->getExpr(I));
+  Writer.AddSourceLocation(E->getBuiltinLoc(), Record);
+  Writer.AddSourceLocation(E->getRParenLoc(), Record);
+  Code = pch::EXPR_SHUFFLE_VECTOR;
+}
+
+void PCHStmtWriter::VisitBlockExpr(BlockExpr *E) {
+  VisitExpr(E);
+  Writer.AddDeclRef(E->getBlockDecl(), Record);
+  Record.push_back(E->hasBlockDeclRefExprs());
+  Code = pch::EXPR_BLOCK;
+}
+
+void PCHStmtWriter::VisitBlockDeclRefExpr(BlockDeclRefExpr *E) {
+  VisitExpr(E);
+  Writer.AddDeclRef(E->getDecl(), Record);
+  Writer.AddSourceLocation(E->getLocation(), Record);
+  Record.push_back(E->isByRef());
+  Record.push_back(E->isConstQualAdded());
+  Code = pch::EXPR_BLOCK_DECL_REF;
+}
+
+//===----------------------------------------------------------------------===//
+// Objective-C Expressions and Statements.
+//===----------------------------------------------------------------------===//
+
+void PCHStmtWriter::VisitObjCStringLiteral(ObjCStringLiteral *E) {
+  VisitExpr(E);
+  Writer.WriteSubStmt(E->getString());
+  Writer.AddSourceLocation(E->getAtLoc(), Record);
+  Code = pch::EXPR_OBJC_STRING_LITERAL;
+}
+
+void PCHStmtWriter::VisitObjCEncodeExpr(ObjCEncodeExpr *E) {
+  VisitExpr(E);
+  Writer.AddTypeSourceInfo(E->getEncodedTypeSourceInfo(), Record);
+  Writer.AddSourceLocation(E->getAtLoc(), Record);
+  Writer.AddSourceLocation(E->getRParenLoc(), Record);
+  Code = pch::EXPR_OBJC_ENCODE;
+}
+
+void PCHStmtWriter::VisitObjCSelectorExpr(ObjCSelectorExpr *E) {
+  VisitExpr(E);
+  Writer.AddSelectorRef(E->getSelector(), Record);
+  Writer.AddSourceLocation(E->getAtLoc(), Record);
+  Writer.AddSourceLocation(E->getRParenLoc(), Record);
+  Code = pch::EXPR_OBJC_SELECTOR_EXPR;
+}
+
+void PCHStmtWriter::VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
+  VisitExpr(E);
+  Writer.AddDeclRef(E->getProtocol(), Record);
+  Writer.AddSourceLocation(E->getAtLoc(), Record);
+  Writer.AddSourceLocation(E->getRParenLoc(), Record);
+  Code = pch::EXPR_OBJC_PROTOCOL_EXPR;
+}
+
+void PCHStmtWriter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
+  VisitExpr(E);
+  Writer.AddDeclRef(E->getDecl(), Record);
+  Writer.AddSourceLocation(E->getLocation(), Record);
+  Writer.WriteSubStmt(E->getBase());
+  Record.push_back(E->isArrow());
+  Record.push_back(E->isFreeIvar());
+  Code = pch::EXPR_OBJC_IVAR_REF_EXPR;
+}
+
+void PCHStmtWriter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
+  VisitExpr(E);
+  Writer.AddDeclRef(E->getProperty(), Record);
+  Writer.AddSourceLocation(E->getLocation(), Record);
+  Writer.WriteSubStmt(E->getBase());
+  Code = pch::EXPR_OBJC_PROPERTY_REF_EXPR;
+}
+
+void PCHStmtWriter::VisitObjCImplicitSetterGetterRefExpr(
+                                  ObjCImplicitSetterGetterRefExpr *E) {
+  VisitExpr(E);
+  Writer.AddDeclRef(E->getGetterMethod(), Record);
+  Writer.AddDeclRef(E->getSetterMethod(), Record);
+
+  // NOTE: InterfaceDecl and Base are mutually exclusive.
+  Writer.AddDeclRef(E->getInterfaceDecl(), Record);
+  Writer.WriteSubStmt(E->getBase());
+  Writer.AddSourceLocation(E->getLocation(), Record);
+  Writer.AddSourceLocation(E->getClassLoc(), Record);
+  Code = pch::EXPR_OBJC_KVC_REF_EXPR;
+}
+
+void PCHStmtWriter::VisitObjCMessageExpr(ObjCMessageExpr *E) {
+  VisitExpr(E);
+  Record.push_back(E->getNumArgs());
+  Record.push_back((unsigned)E->getReceiverKind()); // FIXME: stable encoding
+  switch (E->getReceiverKind()) {
+  case ObjCMessageExpr::Instance:
+    Writer.WriteSubStmt(E->getInstanceReceiver());
+    break;
+
+  case ObjCMessageExpr::Class:
+    Writer.AddTypeSourceInfo(E->getClassReceiverTypeInfo(), Record);
+    break;
+
+  case ObjCMessageExpr::SuperClass:
+  case ObjCMessageExpr::SuperInstance:
+    Writer.AddTypeRef(E->getSuperType(), Record);
+    Writer.AddSourceLocation(E->getSuperLoc(), Record);
+    break;
+  }
+
+  if (E->getMethodDecl()) {
+    Record.push_back(1);
+    Writer.AddDeclRef(E->getMethodDecl(), Record);
+  } else {
+    Record.push_back(0);
+    Writer.AddSelectorRef(E->getSelector(), Record);    
+  }
+    
+  Writer.AddSourceLocation(E->getLeftLoc(), Record);
+  Writer.AddSourceLocation(E->getRightLoc(), Record);
+
+  for (CallExpr::arg_iterator Arg = E->arg_begin(), ArgEnd = E->arg_end();
+       Arg != ArgEnd; ++Arg)
+    Writer.WriteSubStmt(*Arg);
+  Code = pch::EXPR_OBJC_MESSAGE_EXPR;
+}
+
+void PCHStmtWriter::VisitObjCSuperExpr(ObjCSuperExpr *E) {
+  VisitExpr(E);
+  Writer.AddSourceLocation(E->getLoc(), Record);
+  Code = pch::EXPR_OBJC_SUPER_EXPR;
+}
+
+void PCHStmtWriter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) {
+  VisitStmt(S);
+  Writer.WriteSubStmt(S->getElement());
+  Writer.WriteSubStmt(S->getCollection());
+  Writer.WriteSubStmt(S->getBody());
+  Writer.AddSourceLocation(S->getForLoc(), Record);
+  Writer.AddSourceLocation(S->getRParenLoc(), Record);
+  Code = pch::STMT_OBJC_FOR_COLLECTION;
+}
+
+void PCHStmtWriter::VisitObjCAtCatchStmt(ObjCAtCatchStmt *S) {
+  Writer.WriteSubStmt(S->getCatchBody());
+  Writer.AddDeclRef(S->getCatchParamDecl(), Record);
+  Writer.AddSourceLocation(S->getAtCatchLoc(), Record);
+  Writer.AddSourceLocation(S->getRParenLoc(), Record);
+  Code = pch::STMT_OBJC_CATCH;
+}
+
+void PCHStmtWriter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
+  Writer.WriteSubStmt(S->getFinallyBody());
+  Writer.AddSourceLocation(S->getAtFinallyLoc(), Record);
+  Code = pch::STMT_OBJC_FINALLY;
+}
+
+void PCHStmtWriter::VisitObjCAtTryStmt(ObjCAtTryStmt *S) {
+  Record.push_back(S->getNumCatchStmts());
+  Record.push_back(S->getFinallyStmt() != 0);
+  Writer.WriteSubStmt(S->getTryBody());
+  for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I)
+    Writer.WriteSubStmt(S->getCatchStmt(I));
+  if (S->getFinallyStmt())
+    Writer.WriteSubStmt(S->getFinallyStmt());
+  Writer.AddSourceLocation(S->getAtTryLoc(), Record);
+  Code = pch::STMT_OBJC_AT_TRY;
+}
+
+void PCHStmtWriter::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *S) {
+  Writer.WriteSubStmt(S->getSynchExpr());
+  Writer.WriteSubStmt(S->getSynchBody());
+  Writer.AddSourceLocation(S->getAtSynchronizedLoc(), Record);
+  Code = pch::STMT_OBJC_AT_SYNCHRONIZED;
+}
+
+void PCHStmtWriter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *S) {
+  Writer.WriteSubStmt(S->getThrowExpr());
+  Writer.AddSourceLocation(S->getThrowLoc(), Record);
+  Code = pch::STMT_OBJC_AT_THROW;
+}
+
+//===----------------------------------------------------------------------===//
+// C++ Expressions and Statements.
+//===----------------------------------------------------------------------===//
+
+void PCHStmtWriter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
+  VisitCallExpr(E);
+  Record.push_back(E->getOperator());
+  Code = pch::EXPR_CXX_OPERATOR_CALL;
+}
+
+void PCHStmtWriter::VisitCXXConstructExpr(CXXConstructExpr *E) {
+  VisitExpr(E);
+  Writer.AddDeclRef(E->getConstructor(), Record);
+  Writer.AddSourceLocation(E->getLocation(), Record);
+  Record.push_back(E->isElidable());
+  Record.push_back(E->requiresZeroInitialization());
+  Record.push_back(E->getNumArgs());
+  for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
+    Writer.WriteSubStmt(E->getArg(I));
+  Code = pch::EXPR_CXX_CONSTRUCT;
+}
+
+void PCHStmtWriter::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) {
+  VisitExplicitCastExpr(E);
+  Writer.AddSourceLocation(E->getOperatorLoc(), Record);
+}
+
+void PCHStmtWriter::VisitCXXStaticCastExpr(CXXStaticCastExpr *E) {
+  VisitCXXNamedCastExpr(E);
+  Code = pch::EXPR_CXX_STATIC_CAST;
+}
+
+void PCHStmtWriter::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
+  VisitCXXNamedCastExpr(E);
+  Code = pch::EXPR_CXX_DYNAMIC_CAST;
+}
+
+void PCHStmtWriter::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *E) {
+  VisitCXXNamedCastExpr(E);
+  Code = pch::EXPR_CXX_REINTERPRET_CAST;
+}
+
+void PCHStmtWriter::VisitCXXConstCastExpr(CXXConstCastExpr *E) {
+  VisitCXXNamedCastExpr(E);
+  Code = pch::EXPR_CXX_CONST_CAST;
+}
+
+void PCHStmtWriter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E) {
+  VisitExplicitCastExpr(E);
+  Writer.AddSourceLocation(E->getTypeBeginLoc(), Record);
+  Writer.AddSourceLocation(E->getRParenLoc(), Record);
+  Code = pch::EXPR_CXX_FUNCTIONAL_CAST;
+}
+
+void PCHStmtWriter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
+  VisitExpr(E);
+  Record.push_back(E->getValue());
+  Writer.AddSourceLocation(E->getLocation(), Record);
+  Code = pch::EXPR_CXX_BOOL_LITERAL;
+}
+
+void PCHStmtWriter::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E) {
+  VisitExpr(E);
+  Writer.AddSourceLocation(E->getLocation(), Record);
+  Code = pch::EXPR_CXX_NULL_PTR_LITERAL;
+}
+
+//===----------------------------------------------------------------------===//
+// PCHWriter Implementation
+//===----------------------------------------------------------------------===//
+
+unsigned PCHWriter::RecordSwitchCaseID(SwitchCase *S) {
+  assert(SwitchCaseIDs.find(S) == SwitchCaseIDs.end() &&
+         "SwitchCase recorded twice");
+  unsigned NextID = SwitchCaseIDs.size();
+  SwitchCaseIDs[S] = NextID;
+  return NextID;
+}
+
+unsigned PCHWriter::getSwitchCaseID(SwitchCase *S) {
+  assert(SwitchCaseIDs.find(S) != SwitchCaseIDs.end() &&
+         "SwitchCase hasn't been seen yet");
+  return SwitchCaseIDs[S];
+}
+
+/// \brief Retrieve the ID for the given label statement, which may
+/// or may not have been emitted yet.
+unsigned PCHWriter::GetLabelID(LabelStmt *S) {
+  std::map<LabelStmt *, unsigned>::iterator Pos = LabelIDs.find(S);
+  if (Pos != LabelIDs.end())
+    return Pos->second;
+
+  unsigned NextID = LabelIDs.size();
+  LabelIDs[S] = NextID;
+  return NextID;
+}
+
+/// \brief Write the given substatement or subexpression to the
+/// bitstream.
+void PCHWriter::WriteSubStmt(Stmt *S) {
+  RecordData Record;
+  PCHStmtWriter Writer(*this, Record);
+  ++NumStatements;
+
+  if (!S) {
+    Stream.EmitRecord(pch::STMT_NULL_PTR, Record);
+    return;
+  }
+
+  Writer.Code = pch::STMT_NULL_PTR;
+  Writer.Visit(S);
+  assert(Writer.Code != pch::STMT_NULL_PTR &&
+         "Unhandled expression writing PCH file");
+  Stream.EmitRecord(Writer.Code, Record);
+}
+
+/// \brief Flush all of the statements that have been added to the
+/// queue via AddStmt().
+void PCHWriter::FlushStmts() {
+  RecordData Record;
+  PCHStmtWriter Writer(*this, Record);
+
+  for (unsigned I = 0, N = StmtsToEmit.size(); I != N; ++I) {
+    ++NumStatements;
+    Stmt *S = StmtsToEmit[I];
+
+    if (!S) {
+      Stream.EmitRecord(pch::STMT_NULL_PTR, Record);
+      continue;
+    }
+
+    Writer.Code = pch::STMT_NULL_PTR;
+    Writer.Visit(S);
+    assert(Writer.Code != pch::STMT_NULL_PTR &&
+           "Unhandled expression writing PCH file");
+    Stream.EmitRecord(Writer.Code, Record);
+
+    assert(N == StmtsToEmit.size() &&
+           "Substatement writen via AddStmt rather than WriteSubStmt!");
+
+    // Note that we are at the end of a full expression. Any
+    // expression records that follow this one are part of a different
+    // expression.
+    Record.clear();
+    Stream.EmitRecord(pch::STMT_STOP, Record);
+  }
+
+  StmtsToEmit.clear();
+}
diff --git a/lib/Frontend/PlistDiagnostics.cpp b/lib/Frontend/PlistDiagnostics.cpp
new file mode 100644
index 0000000..5706a07
--- /dev/null
+++ b/lib/Frontend/PlistDiagnostics.cpp
@@ -0,0 +1,471 @@
+//===--- PlistDiagnostics.cpp - Plist Diagnostics for Paths -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the PlistDiagnostics object.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/PathDiagnosticClients.h"
+#include "clang/Checker/BugReporter/PathDiagnostic.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Lex/Preprocessor.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVector.h"
+using namespace clang;
+using llvm::cast;
+
+typedef llvm::DenseMap<FileID, unsigned> FIDMap;
+
+namespace clang {
+  class Preprocessor;
+}
+
+namespace {
+struct CompareDiagnostics {
+  // Compare if 'X' is "<" than 'Y'.
+  bool operator()(const PathDiagnostic *X, const PathDiagnostic *Y) const {
+    // First compare by location
+    const FullSourceLoc &XLoc = X->getLocation().asLocation();
+    const FullSourceLoc &YLoc = Y->getLocation().asLocation();
+    if (XLoc < YLoc)
+      return true;
+    if (XLoc != YLoc)
+      return false;
+    
+    // Next, compare by bug type.
+    llvm::StringRef XBugType = X->getBugType();
+    llvm::StringRef YBugType = Y->getBugType();
+    if (XBugType < YBugType)
+      return true;
+    if (XBugType != YBugType)
+      return false;
+    
+    // Next, compare by bug description.
+    llvm::StringRef XDesc = X->getDescription();
+    llvm::StringRef YDesc = Y->getDescription();
+    if (XDesc < YDesc)
+      return true;
+    if (XDesc != YDesc)
+      return false;
+    
+    // FIXME: Further refine by comparing PathDiagnosticPieces?
+    return false;    
+  }  
+};  
+}
+
+namespace {
+  class PlistDiagnostics : public PathDiagnosticClient {
+    std::vector<const PathDiagnostic*> BatchedDiags;
+    const std::string OutputFile;
+    const LangOptions &LangOpts;
+    llvm::OwningPtr<PathDiagnosticClient> SubPD;
+    bool flushed;
+  public:
+    PlistDiagnostics(const std::string& prefix, const LangOptions &LangOpts,
+                     PathDiagnosticClient *subPD);
+
+    ~PlistDiagnostics() { FlushDiagnostics(NULL); }
+
+    void FlushDiagnostics(llvm::SmallVectorImpl<std::string> *FilesMade);
+    
+    void HandlePathDiagnostic(const PathDiagnostic* D);
+    
+    virtual llvm::StringRef getName() const {
+      return "PlistDiagnostics";
+    }
+
+    PathGenerationScheme getGenerationScheme() const;
+    bool supportsLogicalOpControlFlow() const { return true; }
+    bool supportsAllBlockEdges() const { return true; }
+    virtual bool useVerboseDescription() const { return false; }
+  };
+} // end anonymous namespace
+
+PlistDiagnostics::PlistDiagnostics(const std::string& output,
+                                   const LangOptions &LO,
+                                   PathDiagnosticClient *subPD)
+  : OutputFile(output), LangOpts(LO), SubPD(subPD), flushed(false) {}
+
+PathDiagnosticClient*
+clang::CreatePlistDiagnosticClient(const std::string& s, const Preprocessor &PP,
+                                   PathDiagnosticClient *subPD) {
+  return new PlistDiagnostics(s, PP.getLangOptions(), subPD);
+}
+
+PathDiagnosticClient::PathGenerationScheme
+PlistDiagnostics::getGenerationScheme() const {
+  if (const PathDiagnosticClient *PD = SubPD.get())
+    return PD->getGenerationScheme();
+
+  return Extensive;
+}
+
+static void AddFID(FIDMap &FIDs, llvm::SmallVectorImpl<FileID> &V,
+                   const SourceManager* SM, SourceLocation L) {
+
+  FileID FID = SM->getFileID(SM->getInstantiationLoc(L));
+  FIDMap::iterator I = FIDs.find(FID);
+  if (I != FIDs.end()) return;
+  FIDs[FID] = V.size();
+  V.push_back(FID);
+}
+
+static unsigned GetFID(const FIDMap& FIDs, const SourceManager &SM,
+                       SourceLocation L) {
+  FileID FID = SM.getFileID(SM.getInstantiationLoc(L));
+  FIDMap::const_iterator I = FIDs.find(FID);
+  assert(I != FIDs.end());
+  return I->second;
+}
+
+static llvm::raw_ostream& Indent(llvm::raw_ostream& o, const unsigned indent) {
+  for (unsigned i = 0; i < indent; ++i) o << ' ';
+  return o;
+}
+
+static void EmitLocation(llvm::raw_ostream& o, const SourceManager &SM,
+                         const LangOptions &LangOpts,
+                         SourceLocation L, const FIDMap &FM,
+                         unsigned indent, bool extend = false) {
+
+  FullSourceLoc Loc(SM.getInstantiationLoc(L), const_cast<SourceManager&>(SM));
+
+  // Add in the length of the token, so that we cover multi-char tokens.
+  unsigned offset =
+    extend ? Lexer::MeasureTokenLength(Loc, SM, LangOpts) - 1 : 0;
+
+  Indent(o, indent) << "<dict>\n";
+  Indent(o, indent) << " <key>line</key><integer>"
+                    << Loc.getInstantiationLineNumber() << "</integer>\n";
+  Indent(o, indent) << " <key>col</key><integer>"
+                    << Loc.getInstantiationColumnNumber() + offset << "</integer>\n";
+  Indent(o, indent) << " <key>file</key><integer>"
+                    << GetFID(FM, SM, Loc) << "</integer>\n";
+  Indent(o, indent) << "</dict>\n";
+}
+
+static void EmitLocation(llvm::raw_ostream& o, const SourceManager &SM,
+                         const LangOptions &LangOpts,
+                         const PathDiagnosticLocation &L, const FIDMap& FM,
+                         unsigned indent, bool extend = false) {
+  EmitLocation(o, SM, LangOpts, L.asLocation(), FM, indent, extend);
+}
+
+static void EmitRange(llvm::raw_ostream& o, const SourceManager &SM,
+                      const LangOptions &LangOpts,
+                      PathDiagnosticRange R, const FIDMap &FM,
+                      unsigned indent) {
+  Indent(o, indent) << "<array>\n";
+  EmitLocation(o, SM, LangOpts, R.getBegin(), FM, indent+1);
+  EmitLocation(o, SM, LangOpts, R.getEnd(), FM, indent+1, !R.isPoint);
+  Indent(o, indent) << "</array>\n";
+}
+
+static llvm::raw_ostream& EmitString(llvm::raw_ostream& o,
+                                     const std::string& s) {
+  o << "<string>";
+  for (std::string::const_iterator I=s.begin(), E=s.end(); I!=E; ++I) {
+    char c = *I;
+    switch (c) {
+    default:   o << c; break;
+    case '&':  o << "&amp;"; break;
+    case '<':  o << "&lt;"; break;
+    case '>':  o << "&gt;"; break;
+    case '\'': o << "&apos;"; break;
+    case '\"': o << "&quot;"; break;
+    }
+  }
+  o << "</string>";
+  return o;
+}
+
+static void ReportControlFlow(llvm::raw_ostream& o,
+                              const PathDiagnosticControlFlowPiece& P,
+                              const FIDMap& FM,
+                              const SourceManager &SM,
+                              const LangOptions &LangOpts,
+                              unsigned indent) {
+
+  Indent(o, indent) << "<dict>\n";
+  ++indent;
+
+  Indent(o, indent) << "<key>kind</key><string>control</string>\n";
+
+  // Emit edges.
+  Indent(o, indent) << "<key>edges</key>\n";
+  ++indent;
+  Indent(o, indent) << "<array>\n";
+  ++indent;
+  for (PathDiagnosticControlFlowPiece::const_iterator I=P.begin(), E=P.end();
+       I!=E; ++I) {
+    Indent(o, indent) << "<dict>\n";
+    ++indent;
+    Indent(o, indent) << "<key>start</key>\n";
+    EmitRange(o, SM, LangOpts, I->getStart().asRange(), FM, indent+1);
+    Indent(o, indent) << "<key>end</key>\n";
+    EmitRange(o, SM, LangOpts, I->getEnd().asRange(), FM, indent+1);
+    --indent;
+    Indent(o, indent) << "</dict>\n";
+  }
+  --indent;
+  Indent(o, indent) << "</array>\n";
+  --indent;
+
+  // Output any helper text.
+  const std::string& s = P.getString();
+  if (!s.empty()) {
+    Indent(o, indent) << "<key>alternate</key>";
+    EmitString(o, s) << '\n';
+  }
+
+  --indent;
+  Indent(o, indent) << "</dict>\n";
+}
+
+static void ReportEvent(llvm::raw_ostream& o, const PathDiagnosticPiece& P,
+                        const FIDMap& FM,
+                        const SourceManager &SM,
+                        const LangOptions &LangOpts,
+                        unsigned indent) {
+
+  Indent(o, indent) << "<dict>\n";
+  ++indent;
+
+  Indent(o, indent) << "<key>kind</key><string>event</string>\n";
+
+  // Output the location.
+  FullSourceLoc L = P.getLocation().asLocation();
+
+  Indent(o, indent) << "<key>location</key>\n";
+  EmitLocation(o, SM, LangOpts, L, FM, indent);
+
+  // Output the ranges (if any).
+  PathDiagnosticPiece::range_iterator RI = P.ranges_begin(),
+  RE = P.ranges_end();
+
+  if (RI != RE) {
+    Indent(o, indent) << "<key>ranges</key>\n";
+    Indent(o, indent) << "<array>\n";
+    ++indent;
+    for (; RI != RE; ++RI)
+      EmitRange(o, SM, LangOpts, *RI, FM, indent+1);
+    --indent;
+    Indent(o, indent) << "</array>\n";
+  }
+
+  // Output the text.
+  assert(!P.getString().empty());
+  Indent(o, indent) << "<key>extended_message</key>\n";
+  Indent(o, indent);
+  EmitString(o, P.getString()) << '\n';
+
+  // Output the short text.
+  // FIXME: Really use a short string.
+  Indent(o, indent) << "<key>message</key>\n";
+  EmitString(o, P.getString()) << '\n';
+
+  // Finish up.
+  --indent;
+  Indent(o, indent); o << "</dict>\n";
+}
+
+static void ReportMacro(llvm::raw_ostream& o,
+                        const PathDiagnosticMacroPiece& P,
+                        const FIDMap& FM, const SourceManager &SM,
+                        const LangOptions &LangOpts,
+                        unsigned indent) {
+
+  for (PathDiagnosticMacroPiece::const_iterator I=P.begin(), E=P.end();
+       I!=E; ++I) {
+
+    switch ((*I)->getKind()) {
+    default:
+      break;
+    case PathDiagnosticPiece::Event:
+      ReportEvent(o, cast<PathDiagnosticEventPiece>(**I), FM, SM, LangOpts,
+                  indent);
+      break;
+    case PathDiagnosticPiece::Macro:
+      ReportMacro(o, cast<PathDiagnosticMacroPiece>(**I), FM, SM, LangOpts,
+                  indent);
+      break;
+    }
+  }
+}
+
+static void ReportDiag(llvm::raw_ostream& o, const PathDiagnosticPiece& P,
+                       const FIDMap& FM, const SourceManager &SM,
+                       const LangOptions &LangOpts) {
+
+  unsigned indent = 4;
+
+  switch (P.getKind()) {
+  case PathDiagnosticPiece::ControlFlow:
+    ReportControlFlow(o, cast<PathDiagnosticControlFlowPiece>(P), FM, SM,
+                      LangOpts, indent);
+    break;
+  case PathDiagnosticPiece::Event:
+    ReportEvent(o, cast<PathDiagnosticEventPiece>(P), FM, SM, LangOpts,
+                indent);
+    break;
+  case PathDiagnosticPiece::Macro:
+    ReportMacro(o, cast<PathDiagnosticMacroPiece>(P), FM, SM, LangOpts,
+                indent);
+    break;
+  }
+}
+
+void PlistDiagnostics::HandlePathDiagnostic(const PathDiagnostic* D) {
+  if (!D)
+    return;
+
+  if (D->empty()) {
+    delete D;
+    return;
+  }
+
+  // We need to flatten the locations (convert Stmt* to locations) because
+  // the referenced statements may be freed by the time the diagnostics
+  // are emitted.
+  const_cast<PathDiagnostic*>(D)->flattenLocations();
+  BatchedDiags.push_back(D);
+}
+
+void PlistDiagnostics::FlushDiagnostics(llvm::SmallVectorImpl<std::string>
+                                        *FilesMade) {
+  
+  if (flushed)
+    return;
+  
+  flushed = true;
+  
+  // Sort the diagnostics so that they are always emitted in a deterministic
+  // order.
+  if (!BatchedDiags.empty())
+    std::sort(BatchedDiags.begin(), BatchedDiags.end(), CompareDiagnostics()); 
+
+  // Build up a set of FIDs that we use by scanning the locations and
+  // ranges of the diagnostics.
+  FIDMap FM;
+  llvm::SmallVector<FileID, 10> Fids;
+  const SourceManager* SM = 0;
+
+  if (!BatchedDiags.empty())
+    SM = &(*BatchedDiags.begin())->begin()->getLocation().getManager();
+
+  for (std::vector<const PathDiagnostic*>::iterator DI = BatchedDiags.begin(),
+       DE = BatchedDiags.end(); DI != DE; ++DI) {
+
+    const PathDiagnostic *D = *DI;
+
+    for (PathDiagnostic::const_iterator I=D->begin(), E=D->end(); I!=E; ++I) {
+      AddFID(FM, Fids, SM, I->getLocation().asLocation());
+
+      for (PathDiagnosticPiece::range_iterator RI=I->ranges_begin(),
+           RE=I->ranges_end(); RI!=RE; ++RI) {
+        AddFID(FM, Fids, SM, RI->getBegin());
+        AddFID(FM, Fids, SM, RI->getEnd());
+      }
+    }
+  }
+
+  // Open the file.
+  std::string ErrMsg;
+  llvm::raw_fd_ostream o(OutputFile.c_str(), ErrMsg);
+  if (!ErrMsg.empty()) {
+    llvm::errs() << "warning: could not creat file: " << OutputFile << '\n';
+    return;
+  }
+
+  // Write the plist header.
+  o << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+  "<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" "
+  "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
+  "<plist version=\"1.0\">\n";
+
+  // Write the root object: a <dict> containing...
+  //  - "files", an <array> mapping from FIDs to file names
+  //  - "diagnostics", an <array> containing the path diagnostics
+  o << "<dict>\n"
+       " <key>files</key>\n"
+       " <array>\n";
+
+  for (llvm::SmallVectorImpl<FileID>::iterator I=Fids.begin(), E=Fids.end();
+       I!=E; ++I) {
+    o << "  ";
+    EmitString(o, SM->getFileEntryForID(*I)->getName()) << '\n';
+  }
+
+  o << " </array>\n"
+       " <key>diagnostics</key>\n"
+       " <array>\n";
+
+  for (std::vector<const PathDiagnostic*>::iterator DI=BatchedDiags.begin(),
+       DE = BatchedDiags.end(); DI!=DE; ++DI) {
+
+    o << "  <dict>\n"
+         "   <key>path</key>\n";
+
+    const PathDiagnostic *D = *DI;
+    // Create an owning smart pointer for 'D' just so that we auto-free it
+    // when we exit this method.
+    llvm::OwningPtr<PathDiagnostic> OwnedD(const_cast<PathDiagnostic*>(D));
+
+    o << "   <array>\n";
+
+    for (PathDiagnostic::const_iterator I=D->begin(), E=D->end(); I != E; ++I)
+      ReportDiag(o, *I, FM, *SM, LangOpts);
+
+    o << "   </array>\n";
+
+    // Output the bug type and bug category.
+    o << "   <key>description</key>";
+    EmitString(o, D->getDescription()) << '\n';
+    o << "   <key>category</key>";
+    EmitString(o, D->getCategory()) << '\n';
+    o << "   <key>type</key>";
+    EmitString(o, D->getBugType()) << '\n';
+
+    // Output the location of the bug.
+    o << "  <key>location</key>\n";
+    EmitLocation(o, *SM, LangOpts, D->getLocation(), FM, 2);
+
+    // Output the diagnostic to the sub-diagnostic client, if any.
+    if (SubPD) {
+      SubPD->HandlePathDiagnostic(OwnedD.take());
+      llvm::SmallVector<std::string, 1> SubFilesMade;
+      SubPD->FlushDiagnostics(SubFilesMade);
+
+      if (!SubFilesMade.empty()) {
+        o << "  <key>" << SubPD->getName() << "_files</key>\n";
+        o << "  <array>\n";
+        for (size_t i = 0, n = SubFilesMade.size(); i < n ; ++i)
+          o << "   <string>" << SubFilesMade[i] << "</string>\n";
+        o << "  </array>\n";
+      }
+    }
+
+    // Close up the entry.
+    o << "  </dict>\n";
+  }
+
+  o << " </array>\n";
+
+  // Finish.
+  o << "</dict>\n</plist>";
+  
+  if (FilesMade)
+    FilesMade->push_back(OutputFile);
+  
+  BatchedDiags.clear();
+}
diff --git a/lib/Frontend/PrintParserCallbacks.cpp b/lib/Frontend/PrintParserCallbacks.cpp
new file mode 100644
index 0000000..4df5c52
--- /dev/null
+++ b/lib/Frontend/PrintParserCallbacks.cpp
@@ -0,0 +1,849 @@
+//===--- PrintParserActions.cpp - Implement -parse-print-callbacks mode ---===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This code simply runs the preprocessor on the input file and prints out the
+// result.  This is the traditional behavior of the -E option.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/Utils.h"
+#include "clang/Parse/Action.h"
+#include "clang/Parse/DeclSpec.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace clang;
+
+namespace {
+  class ParserPrintActions : public MinimalAction {
+  llvm::raw_ostream& Out;
+
+  public:
+    ParserPrintActions(Preprocessor &PP, llvm::raw_ostream& OS)
+      : MinimalAction(PP), Out(OS) {}
+
+    // Printing Functions which also must call MinimalAction
+
+    /// ActOnDeclarator - This callback is invoked when a declarator is parsed
+    /// and 'Init' specifies the initializer if any.  This is for things like:
+    /// "int X = 4" or "typedef int foo".
+    virtual DeclPtrTy ActOnDeclarator(Scope *S, Declarator &D) {
+      Out << __FUNCTION__ << " ";
+      if (IdentifierInfo *II = D.getIdentifier()) {
+        Out << "'" << II->getName() << "'";
+      } else {
+        Out << "<anon>";
+      }
+      Out << "\n";
+
+      // Pass up to EmptyActions so that the symbol table is maintained right.
+      return MinimalAction::ActOnDeclarator(S, D);
+    }
+    /// ActOnPopScope - This callback is called immediately before the specified
+    /// scope is popped and deleted.
+    virtual void ActOnPopScope(SourceLocation Loc, Scope *S) {
+      Out << __FUNCTION__ << "\n";
+      return MinimalAction::ActOnPopScope(Loc, S);
+    }
+
+    /// ActOnTranslationUnitScope - This callback is called once, immediately
+    /// after creating the translation unit scope (in Parser::Initialize).
+    virtual void ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) {
+      Out << __FUNCTION__ << "\n";
+      MinimalAction::ActOnTranslationUnitScope(Loc, S);
+    }
+
+
+    Action::DeclPtrTy ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
+                                               IdentifierInfo *ClassName,
+                                               SourceLocation ClassLoc,
+                                               IdentifierInfo *SuperName,
+                                               SourceLocation SuperLoc,
+                                               const DeclPtrTy *ProtoRefs,
+                                               unsigned NumProtocols,
+                                               const SourceLocation *ProtoLocs,
+                                               SourceLocation EndProtoLoc,
+                                               AttributeList *AttrList) {
+      Out << __FUNCTION__ << "\n";
+      return MinimalAction::ActOnStartClassInterface(AtInterfaceLoc,
+                                                     ClassName, ClassLoc,
+                                                     SuperName, SuperLoc,
+                                                     ProtoRefs, NumProtocols,
+                                                     ProtoLocs, EndProtoLoc,
+                                                     AttrList);
+    }
+
+    /// ActOnForwardClassDeclaration -
+    /// Scope will always be top level file scope.
+    Action::DeclPtrTy ActOnForwardClassDeclaration(SourceLocation AtClassLoc,
+                                                   IdentifierInfo **IdentList,
+                                                   SourceLocation *IdentLocs,
+                                                   unsigned NumElts) {
+      Out << __FUNCTION__ << "\n";
+      return MinimalAction::ActOnForwardClassDeclaration(AtClassLoc, IdentList,
+                                                         IdentLocs, NumElts);
+    }
+
+    // Pure Printing
+
+    /// ActOnParamDeclarator - This callback is invoked when a parameter
+    /// declarator is parsed. This callback only occurs for functions
+    /// with prototypes. S is the function prototype scope for the
+    /// parameters (C++ [basic.scope.proto]).
+    virtual DeclPtrTy ActOnParamDeclarator(Scope *S, Declarator &D) {
+      Out << __FUNCTION__ << " ";
+      if (IdentifierInfo *II = D.getIdentifier()) {
+        Out << "'" << II->getName() << "'";
+      } else {
+        Out << "<anon>";
+      }
+      Out << "\n";
+      return DeclPtrTy();
+    }
+
+    /// AddInitializerToDecl - This action is called immediately after
+    /// ParseDeclarator (when an initializer is present). The code is factored
+    /// this way to make sure we are able to handle the following:
+    ///   void func() { int xx = xx; }
+    /// This allows ActOnDeclarator to register "xx" prior to parsing the
+    /// initializer. The declaration above should still result in a warning,
+    /// since the reference to "xx" is uninitialized.
+    virtual void AddInitializerToDecl(DeclPtrTy Dcl, ExprArg Init) {
+      Out << __FUNCTION__ << "\n";
+    }
+
+    /// FinalizeDeclaratorGroup - After a sequence of declarators are parsed,
+    /// this gives the actions implementation a chance to process the group as
+    /// a whole.
+    virtual DeclGroupPtrTy FinalizeDeclaratorGroup(Scope *S, const DeclSpec& DS,
+                                                   DeclPtrTy *Group,
+                                                   unsigned NumDecls) {
+      Out << __FUNCTION__ << "\n";
+      return DeclGroupPtrTy();
+    }
+
+    /// ActOnStartOfFunctionDef - This is called at the start of a function
+    /// definition, instead of calling ActOnDeclarator.  The Declarator includes
+    /// information about formal arguments that are part of this function.
+    virtual DeclPtrTy ActOnStartOfFunctionDef(Scope *FnBodyScope,
+                                              Declarator &D){
+      Out << __FUNCTION__ << "\n";
+      return DeclPtrTy();
+    }
+
+    /// ActOnStartOfFunctionDef - This is called at the start of a function
+    /// definition, after the FunctionDecl has already been created.
+    virtual DeclPtrTy ActOnStartOfFunctionDef(Scope *FnBodyScope, DeclPtrTy D) {
+      Out << __FUNCTION__ << "\n";
+      return DeclPtrTy();
+    }
+
+    virtual void ActOnStartOfObjCMethodDef(Scope *FnBodyScope, DeclPtrTy D) {
+      Out << __FUNCTION__ << "\n";
+    }
+
+    /// ActOnFunctionDefBody - This is called when a function body has completed
+    /// parsing.  Decl is the DeclTy returned by ParseStartOfFunctionDef.
+    virtual DeclPtrTy ActOnFinishFunctionBody(DeclPtrTy Decl, StmtArg Body) {
+      Out << __FUNCTION__ << "\n";
+      return DeclPtrTy();
+    }
+
+    virtual DeclPtrTy ActOnFileScopeAsmDecl(SourceLocation Loc,
+                                            ExprArg AsmString) {
+      Out << __FUNCTION__ << "\n";
+      return DeclPtrTy();
+    }
+
+    /// ParsedFreeStandingDeclSpec - This method is invoked when a declspec with
+    /// no declarator (e.g. "struct foo;") is parsed.
+    virtual DeclPtrTy ParsedFreeStandingDeclSpec(Scope *S, DeclSpec &DS) {
+      Out << __FUNCTION__ << "\n";
+      return DeclPtrTy();
+    }
+
+    /// ActOnLinkageSpec - Parsed a C++ linkage-specification that
+    /// contained braces. Lang/StrSize contains the language string that
+    /// was parsed at location Loc. Decls/NumDecls provides the
+    /// declarations parsed inside the linkage specification.
+    virtual DeclPtrTy ActOnLinkageSpec(SourceLocation Loc,
+                                       SourceLocation LBrace,
+                                       SourceLocation RBrace, const char *Lang,
+                                       unsigned StrSize,
+                                       DeclPtrTy *Decls, unsigned NumDecls) {
+      Out << __FUNCTION__ << "\n";
+      return DeclPtrTy();
+    }
+
+    /// ActOnLinkageSpec - Parsed a C++ linkage-specification without
+    /// braces. Lang/StrSize contains the language string that was
+    /// parsed at location Loc. D is the declaration parsed.
+    virtual DeclPtrTy ActOnLinkageSpec(SourceLocation Loc, const char *Lang,
+                                       unsigned StrSize, DeclPtrTy D) {
+      return DeclPtrTy();
+    }
+
+    //===------------------------------------------------------------------===//
+    // Type Parsing Callbacks.
+    //===------------------------------------------------------------------===//
+
+    virtual TypeResult ActOnTypeName(Scope *S, Declarator &D) {
+      Out << __FUNCTION__ << "\n";
+      return TypeResult();
+    }
+
+    virtual DeclPtrTy ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
+                               SourceLocation KWLoc, CXXScopeSpec &SS,
+                               IdentifierInfo *Name, SourceLocation NameLoc,
+                               AttributeList *Attr, AccessSpecifier AS,
+                               MultiTemplateParamsArg TemplateParameterLists,
+                               bool &OwnedDecl, bool &IsDependent) {
+      // TagType is an instance of DeclSpec::TST, indicating what kind of tag this
+      // is (struct/union/enum/class).
+      Out << __FUNCTION__ << "\n";
+      return DeclPtrTy();
+    }
+
+    /// Act on @defs() element found when parsing a structure.  ClassName is the
+    /// name of the referenced class.
+    virtual void ActOnDefs(Scope *S, DeclPtrTy TagD, SourceLocation DeclStart,
+                           IdentifierInfo *ClassName,
+                           llvm::SmallVectorImpl<DeclPtrTy> &Decls) {
+      Out << __FUNCTION__ << "\n";
+    }
+
+    virtual DeclPtrTy ActOnField(Scope *S, DeclPtrTy TagD,
+                                 SourceLocation DeclStart,
+                                 Declarator &D, ExprTy *BitfieldWidth) {
+      Out << __FUNCTION__ << "\n";
+      return DeclPtrTy();
+    }
+
+    virtual DeclPtrTy ActOnIvar(Scope *S, SourceLocation DeclStart,
+                                DeclPtrTy IntfDecl,
+                                Declarator &D, ExprTy *BitfieldWidth,
+                                tok::ObjCKeywordKind visibility) {
+      Out << __FUNCTION__ << "\n";
+      return DeclPtrTy();
+    }
+
+    virtual void ActOnFields(Scope* S, SourceLocation RecLoc, DeclPtrTy TagDecl,
+                             DeclPtrTy *Fields, unsigned NumFields,
+                             SourceLocation LBrac, SourceLocation RBrac,
+                             AttributeList *AttrList) {
+      Out << __FUNCTION__ << "\n";
+    }
+
+    virtual DeclPtrTy ActOnEnumConstant(Scope *S, DeclPtrTy EnumDecl,
+                                        DeclPtrTy LastEnumConstant,
+                                        SourceLocation IdLoc,IdentifierInfo *Id,
+                                        SourceLocation EqualLoc, ExprTy *Val) {
+      Out << __FUNCTION__ << "\n";
+      return DeclPtrTy();
+    }
+
+    virtual void ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc,
+                               SourceLocation RBraceLoc, DeclPtrTy EnumDecl,
+                               DeclPtrTy *Elements, unsigned NumElements,
+                               Scope *S, AttributeList *AttrList) {
+      Out << __FUNCTION__ << "\n";
+    }
+
+    //===------------------------------------------------------------------===//
+    // Statement Parsing Callbacks.
+    //===------------------------------------------------------------------===//
+
+    virtual OwningStmtResult ActOnNullStmt(SourceLocation SemiLoc) {
+      Out << __FUNCTION__ << "\n";
+      return StmtEmpty();
+    }
+
+    virtual OwningStmtResult ActOnCompoundStmt(SourceLocation L,
+                                               SourceLocation R,
+                                               MultiStmtArg Elts,
+                                               bool isStmtExpr) {
+      Out << __FUNCTION__ << "\n";
+      return StmtEmpty();
+    }
+    virtual OwningStmtResult ActOnDeclStmt(DeclGroupPtrTy Decl,
+                                           SourceLocation StartLoc,
+                                           SourceLocation EndLoc) {
+      Out << __FUNCTION__ << "\n";
+      return StmtEmpty();
+    }
+
+    virtual OwningStmtResult ActOnExprStmt(FullExprArg Expr) {
+      Out << __FUNCTION__ << "\n";
+      return OwningStmtResult(*this, Expr->release());
+    }
+
+    /// ActOnCaseStmt - Note that this handles the GNU 'case 1 ... 4' extension,
+    /// which can specify an RHS value.
+    virtual OwningStmtResult ActOnCaseStmt(SourceLocation CaseLoc,
+                                           ExprArg LHSVal,
+                                           SourceLocation DotDotDotLoc,
+                                           ExprArg RHSVal,
+                                           SourceLocation ColonLoc) {
+      Out << __FUNCTION__ << "\n";
+      return StmtEmpty();
+    }
+    virtual OwningStmtResult ActOnDefaultStmt(SourceLocation DefaultLoc,
+                                              SourceLocation ColonLoc,
+                                              StmtArg SubStmt, Scope *CurScope){
+      Out << __FUNCTION__ << "\n";
+      return StmtEmpty();
+    }
+
+    virtual OwningStmtResult ActOnLabelStmt(SourceLocation IdentLoc,
+                                            IdentifierInfo *II,
+                                            SourceLocation ColonLoc,
+                                            StmtArg SubStmt) {
+      Out << __FUNCTION__ << "\n";
+      return StmtEmpty();
+    }
+
+    virtual OwningStmtResult ActOnIfStmt(SourceLocation IfLoc,
+                                         FullExprArg CondVal, DeclPtrTy CondVar,
+                                         StmtArg ThenVal,
+                                         SourceLocation ElseLoc,
+                                         StmtArg ElseVal) {
+      Out << __FUNCTION__ << "\n";
+      return StmtEmpty();
+    }
+
+    virtual OwningStmtResult ActOnStartOfSwitchStmt(FullExprArg Cond, 
+                                                    DeclPtrTy CondVar) {
+      Out << __FUNCTION__ << "\n";
+      return StmtEmpty();
+    }
+
+    virtual OwningStmtResult ActOnFinishSwitchStmt(SourceLocation SwitchLoc,
+                                                   StmtArg Switch,
+                                                   StmtArg Body) {
+      Out << __FUNCTION__ << "\n";
+      return StmtEmpty();
+    }
+
+    virtual OwningStmtResult ActOnWhileStmt(SourceLocation WhileLoc,
+                                            FullExprArg Cond, DeclPtrTy CondVar,
+                                            StmtArg Body) {
+      Out << __FUNCTION__ << "\n";
+      return StmtEmpty();
+    }
+    virtual OwningStmtResult ActOnDoStmt(SourceLocation DoLoc, StmtArg Body,
+                                         SourceLocation WhileLoc,
+                                         SourceLocation LPLoc, ExprArg Cond,
+                                         SourceLocation RPLoc){
+      Out << __FUNCTION__ << "\n";
+      return StmtEmpty();
+    }
+    virtual OwningStmtResult ActOnForStmt(SourceLocation ForLoc,
+                                        SourceLocation LParenLoc,
+                                        StmtArg First, FullExprArg Second,
+                                        DeclPtrTy SecondVar,
+                                        FullExprArg Third, 
+                                        SourceLocation RParenLoc,
+                                        StmtArg Body) {
+      Out << __FUNCTION__ << "\n";
+      return StmtEmpty();
+    }
+    virtual OwningStmtResult ActOnObjCForCollectionStmt(
+                                       SourceLocation ForColLoc,
+                                       SourceLocation LParenLoc,
+                                       StmtArg First, ExprArg Second,
+                                       SourceLocation RParenLoc, StmtArg Body) {
+      Out << __FUNCTION__ << "\n";
+      return StmtEmpty();
+    }
+    virtual OwningStmtResult ActOnGotoStmt(SourceLocation GotoLoc,
+                                           SourceLocation LabelLoc,
+                                           IdentifierInfo *LabelII) {
+      Out << __FUNCTION__ << "\n";
+      return StmtEmpty();
+    }
+    virtual OwningStmtResult ActOnIndirectGotoStmt(SourceLocation GotoLoc,
+                                                   SourceLocation StarLoc,
+                                                   ExprArg DestExp) {
+      Out << __FUNCTION__ << "\n";
+      return StmtEmpty();
+    }
+    virtual OwningStmtResult ActOnContinueStmt(SourceLocation ContinueLoc,
+                                               Scope *CurScope) {
+      Out << __FUNCTION__ << "\n";
+      return StmtEmpty();
+    }
+    virtual OwningStmtResult ActOnBreakStmt(SourceLocation GotoLoc,
+                                            Scope *CurScope) {
+      Out << __FUNCTION__ << "\n";
+      return StmtEmpty();
+    }
+    virtual OwningStmtResult ActOnReturnStmt(SourceLocation ReturnLoc,
+                                             ExprArg RetValExp) {
+      Out << __FUNCTION__ << "\n";
+      return StmtEmpty();
+    }
+    virtual OwningStmtResult ActOnAsmStmt(SourceLocation AsmLoc,
+                                          bool IsSimple,
+                                          bool IsVolatile,
+                                          unsigned NumOutputs,
+                                          unsigned NumInputs,
+                                          IdentifierInfo **Names,
+                                          MultiExprArg Constraints,
+                                          MultiExprArg Exprs,
+                                          ExprArg AsmString,
+                                          MultiExprArg Clobbers,
+                                          SourceLocation RParenLoc,
+                                          bool MSAsm) {
+      Out << __FUNCTION__ << "\n";
+      return StmtEmpty();
+    }
+
+    // Objective-c statements
+    virtual OwningStmtResult ActOnObjCAtCatchStmt(SourceLocation AtLoc,
+                                                  SourceLocation RParen,
+                                                  DeclPtrTy Parm,
+                                                  StmtArg Body) {
+      Out << __FUNCTION__ << "\n";
+      return StmtEmpty();
+    }
+
+    virtual OwningStmtResult ActOnObjCAtFinallyStmt(SourceLocation AtLoc,
+                                                    StmtArg Body) {
+      Out << __FUNCTION__ << "\n";
+      return StmtEmpty();
+    }
+
+    virtual OwningStmtResult ActOnObjCAtTryStmt(SourceLocation AtLoc,
+                                                StmtArg Try,
+                                                MultiStmtArg CatchStmts,
+                                                StmtArg Finally) {
+      Out << __FUNCTION__ << "\n";
+      return StmtEmpty();
+    }
+
+    virtual OwningStmtResult ActOnObjCAtThrowStmt(SourceLocation AtLoc,
+                                                  ExprArg Throw,
+                                                  Scope *CurScope) {
+      Out << __FUNCTION__ << "\n";
+      return StmtEmpty();
+    }
+
+    virtual OwningStmtResult ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc,
+                                                         ExprArg SynchExpr,
+                                                         StmtArg SynchBody) {
+      Out << __FUNCTION__ << "\n";
+      return StmtEmpty();
+    }
+
+    // C++ Statements
+    virtual DeclPtrTy ActOnExceptionDeclarator(Scope *S, Declarator &D) {
+      Out << __FUNCTION__ << "\n";
+      return DeclPtrTy();
+    }
+
+    virtual OwningStmtResult ActOnCXXCatchBlock(SourceLocation CatchLoc,
+                                                DeclPtrTy ExceptionDecl,
+                                                StmtArg HandlerBlock) {
+      Out << __FUNCTION__ << "\n";
+      return StmtEmpty();
+    }
+
+    virtual OwningStmtResult ActOnCXXTryBlock(SourceLocation TryLoc,
+                                              StmtArg TryBlock,
+                                              MultiStmtArg Handlers) {
+      Out << __FUNCTION__ << "\n";
+      return StmtEmpty();
+    }
+
+    //===------------------------------------------------------------------===//
+    // Expression Parsing Callbacks.
+    //===------------------------------------------------------------------===//
+
+    // Primary Expressions.
+
+    /// ActOnIdentifierExpr - Parse an identifier in expression context.
+    /// 'HasTrailingLParen' indicates whether or not the identifier has a '('
+    /// token immediately after it.
+    virtual OwningExprResult ActOnIdentifierExpr(Scope *S, SourceLocation Loc,
+                                                 IdentifierInfo &II,
+                                                 bool HasTrailingLParen,
+                                                 const CXXScopeSpec *SS,
+                                                 bool isAddressOfOperand) {
+      Out << __FUNCTION__ << "\n";
+      return ExprEmpty();
+    }
+
+    virtual OwningExprResult ActOnCXXOperatorFunctionIdExpr(
+                               Scope *S, SourceLocation OperatorLoc,
+                               OverloadedOperatorKind Op,
+                               bool HasTrailingLParen, const CXXScopeSpec &SS,
+                               bool isAddressOfOperand) {
+      Out << __FUNCTION__ << "\n";
+      return ExprEmpty();
+    }
+
+    virtual OwningExprResult ActOnCXXConversionFunctionExpr(
+                               Scope *S, SourceLocation OperatorLoc,
+                               TypeTy *Type, bool HasTrailingLParen,
+                               const CXXScopeSpec &SS,bool isAddressOfOperand) {
+      Out << __FUNCTION__ << "\n";
+      return ExprEmpty();
+    }
+
+    virtual OwningExprResult ActOnPredefinedExpr(SourceLocation Loc,
+                                                 tok::TokenKind Kind) {
+      Out << __FUNCTION__ << "\n";
+      return ExprEmpty();
+    }
+
+    virtual OwningExprResult ActOnCharacterConstant(const Token &) {
+      Out << __FUNCTION__ << "\n";
+      return ExprEmpty();
+    }
+
+    virtual OwningExprResult ActOnNumericConstant(const Token &) {
+      Out << __FUNCTION__ << "\n";
+      return ExprEmpty();
+    }
+
+    /// ActOnStringLiteral - The specified tokens were lexed as pasted string
+    /// fragments (e.g. "foo" "bar" L"baz").
+    virtual OwningExprResult ActOnStringLiteral(const Token *Toks,
+                                                unsigned NumToks) {
+      Out << __FUNCTION__ << "\n";
+      return ExprEmpty();
+    }
+
+    virtual OwningExprResult ActOnParenExpr(SourceLocation L, SourceLocation R,
+                                            ExprArg Val) {
+      Out << __FUNCTION__ << "\n";
+      return move(Val);  // Default impl returns operand.
+    }
+
+    // Postfix Expressions.
+    virtual OwningExprResult ActOnPostfixUnaryOp(Scope *S, SourceLocation OpLoc,
+                                                 tok::TokenKind Kind,
+                                                 ExprArg Input) {
+      Out << __FUNCTION__ << "\n";
+      return ExprEmpty();
+    }
+    virtual OwningExprResult ActOnArraySubscriptExpr(Scope *S, ExprArg Base,
+                                                     SourceLocation LLoc,
+                                                     ExprArg Idx,
+                                                     SourceLocation RLoc) {
+      Out << __FUNCTION__ << "\n";
+      return ExprEmpty();
+    }
+    virtual OwningExprResult ActOnMemberReferenceExpr(Scope *S, ExprArg Base,
+                                                      SourceLocation OpLoc,
+                                                      tok::TokenKind OpKind,
+                                                      SourceLocation MemberLoc,
+                                                      IdentifierInfo &Member,
+                                                      DeclPtrTy ImplDecl,
+                                                      const CXXScopeSpec *SS=0) {
+      Out << __FUNCTION__ << "\n";
+      return ExprEmpty();
+    }
+
+    virtual OwningExprResult ActOnCallExpr(Scope *S, ExprArg Fn,
+                                           SourceLocation LParenLoc,
+                                           MultiExprArg Args,
+                                           SourceLocation *CommaLocs,
+                                           SourceLocation RParenLoc) {
+      Out << __FUNCTION__ << "\n";
+      return ExprEmpty();
+    }
+
+    // Unary Operators.  'Tok' is the token for the operator.
+    virtual OwningExprResult ActOnUnaryOp(Scope *S, SourceLocation OpLoc,
+                                          tok::TokenKind Op, ExprArg Input) {
+      Out << __FUNCTION__ << "\n";
+      return ExprEmpty();
+    }
+    virtual OwningExprResult
+      ActOnSizeOfAlignOfExpr(SourceLocation OpLoc, bool isSizeof, bool isType,
+                             void *TyOrEx, const SourceRange &ArgRange) {
+      Out << __FUNCTION__ << "\n";
+      return ExprEmpty();
+    }
+
+    virtual OwningExprResult ActOnCompoundLiteral(SourceLocation LParen,
+                                                  TypeTy *Ty,
+                                                  SourceLocation RParen,
+                                                  ExprArg Op) {
+      Out << __FUNCTION__ << "\n";
+      return ExprEmpty();
+    }
+    virtual OwningExprResult ActOnInitList(SourceLocation LParenLoc,
+                                           MultiExprArg InitList,
+                                           SourceLocation RParenLoc) {
+      Out << __FUNCTION__ << "\n";
+      return ExprEmpty();
+    }
+    virtual OwningExprResult ActOnCastExpr(Scope *S, SourceLocation LParenLoc,
+                                           TypeTy *Ty, SourceLocation RParenLoc,
+                                           ExprArg Op) {
+      Out << __FUNCTION__ << "\n";
+      return ExprEmpty();
+    }
+
+    virtual OwningExprResult ActOnBinOp(Scope *S, SourceLocation TokLoc,
+                                        tok::TokenKind Kind,
+                                        ExprArg LHS, ExprArg RHS) {
+      Out << __FUNCTION__ << "\n";
+      return ExprEmpty();
+    }
+
+    /// ActOnConditionalOp - Parse a ?: operation.  Note that 'LHS' may be null
+    /// in the case of a the GNU conditional expr extension.
+    virtual OwningExprResult ActOnConditionalOp(SourceLocation QuestionLoc,
+                                                SourceLocation ColonLoc,
+                                                ExprArg Cond, ExprArg LHS,
+                                                ExprArg RHS) {
+      Out << __FUNCTION__ << "\n";
+      return ExprEmpty();
+    }
+
+    //===--------------------- GNU Extension Expressions ------------------===//
+
+    virtual OwningExprResult ActOnAddrLabel(SourceLocation OpLoc,
+                                            SourceLocation LabLoc,
+                                            IdentifierInfo *LabelII) {// "&&foo"
+      Out << __FUNCTION__ << "\n";
+      return ExprEmpty();
+    }
+
+    virtual OwningExprResult ActOnStmtExpr(SourceLocation LPLoc,
+                                           StmtArg SubStmt,
+                                           SourceLocation RPLoc) { // "({..})"
+      Out << __FUNCTION__ << "\n";
+      return ExprEmpty();
+    }
+
+    virtual OwningExprResult ActOnBuiltinOffsetOf(Scope *S,
+                                                  SourceLocation BuiltinLoc,
+                                                  SourceLocation TypeLoc,
+                                                  TypeTy *Arg1,
+                                                  OffsetOfComponent *CompPtr,
+                                                  unsigned NumComponents,
+                                                  SourceLocation RParenLoc) {
+      Out << __FUNCTION__ << "\n";
+      return ExprEmpty();
+    }
+
+    // __builtin_types_compatible_p(type1, type2)
+    virtual OwningExprResult ActOnTypesCompatibleExpr(SourceLocation BuiltinLoc,
+                                                      TypeTy *arg1,TypeTy *arg2,
+                                                      SourceLocation RPLoc) {
+      Out << __FUNCTION__ << "\n";
+      return ExprEmpty();
+    }
+    // __builtin_choose_expr(constExpr, expr1, expr2)
+    virtual OwningExprResult ActOnChooseExpr(SourceLocation BuiltinLoc,
+                                             ExprArg cond, ExprArg expr1,
+                                             ExprArg expr2,
+                                             SourceLocation RPLoc) {
+      Out << __FUNCTION__ << "\n";
+      return ExprEmpty();
+    }
+
+    // __builtin_va_arg(expr, type)
+    virtual OwningExprResult ActOnVAArg(SourceLocation BuiltinLoc,
+                                  ExprArg expr, TypeTy *type,
+                                  SourceLocation RPLoc) {
+      Out << __FUNCTION__ << "\n";
+      return ExprEmpty();
+    }
+
+    virtual OwningExprResult ActOnGNUNullExpr(SourceLocation TokenLoc) {
+      Out << __FUNCTION__ << "\n";
+      return ExprEmpty();
+    }
+
+    virtual void ActOnBlockStart(SourceLocation CaretLoc, Scope *CurScope) {
+      Out << __FUNCTION__ << "\n";
+    }
+
+    virtual void ActOnBlockArguments(Declarator &ParamInfo, Scope *CurScope) {
+      Out << __FUNCTION__ << "\n";
+    }
+
+    virtual void ActOnBlockError(SourceLocation CaretLoc, Scope *CurScope) {
+      Out << __FUNCTION__ << "\n";
+    }
+
+    virtual OwningExprResult ActOnBlockStmtExpr(SourceLocation CaretLoc,
+                                                StmtArg Body,
+                                                Scope *CurScope) {
+      Out << __FUNCTION__ << "\n";
+      return ExprEmpty();
+    }
+
+    virtual DeclPtrTy ActOnStartNamespaceDef(Scope *S, SourceLocation IdentLoc,
+                                             IdentifierInfo *Ident,
+                                             SourceLocation LBrace,
+                                             AttributeList *AttrList) {
+      Out << __FUNCTION__ << "\n";
+      return DeclPtrTy();
+    }
+
+    virtual void ActOnFinishNamespaceDef(DeclPtrTy Dcl, SourceLocation RBrace) {
+      Out << __FUNCTION__ << "\n";
+      return;
+    }
+
+#if 0
+    // FIXME: AttrList should be deleted by this function, but the definition
+    // would have to be available.
+    virtual DeclPtrTy ActOnUsingDirective(Scope *CurScope,
+                                          SourceLocation UsingLoc,
+                                          SourceLocation NamespcLoc,
+                                          const CXXScopeSpec &SS,
+                                          SourceLocation IdentLoc,
+                                          IdentifierInfo *NamespcName,
+                                          AttributeList *AttrList) {
+      Out << __FUNCTION__ << "\n";
+      return DeclPtrTy();
+    }
+#endif
+
+    virtual void ActOnParamDefaultArgument(DeclPtrTy param,
+                                           SourceLocation EqualLoc,
+                                           ExprArg defarg) {
+      Out << __FUNCTION__ << "\n";
+    }
+
+    virtual void ActOnParamUnparsedDefaultArgument(DeclPtrTy param,
+                                                   SourceLocation EqualLoc,
+                                                   SourceLocation ArgLoc) {
+      Out << __FUNCTION__ << "\n";
+    }
+
+    virtual void ActOnParamDefaultArgumentError(DeclPtrTy param) {
+      Out << __FUNCTION__ << "\n";
+    }
+
+    virtual void AddCXXDirectInitializerToDecl(DeclPtrTy Dcl,
+                                               SourceLocation LParenLoc,
+                                               MultiExprArg Exprs,
+                                               SourceLocation *CommaLocs,
+                                               SourceLocation RParenLoc) {
+      Out << __FUNCTION__ << "\n";
+      return;
+    }
+
+    virtual void ActOnStartDelayedCXXMethodDeclaration(Scope *S,
+                                                       DeclPtrTy Method) {
+      Out << __FUNCTION__ << "\n";
+    }
+
+    virtual void ActOnDelayedCXXMethodParameter(Scope *S, DeclPtrTy Param) {
+      Out << __FUNCTION__ << "\n";
+    }
+
+    virtual void ActOnFinishDelayedCXXMethodDeclaration(Scope *S,
+                                                        DeclPtrTy Method) {
+      Out << __FUNCTION__ << "\n";
+    }
+
+    virtual DeclPtrTy ActOnStaticAssertDeclaration(SourceLocation AssertLoc,
+                                                   ExprArg AssertExpr,
+                                                   ExprArg AssertMessageExpr) {
+      Out << __FUNCTION__ << "\n";
+      return DeclPtrTy();
+    }
+
+    virtual OwningExprResult ActOnCXXNamedCast(SourceLocation OpLoc,
+                                               tok::TokenKind Kind,
+                                               SourceLocation LAngleBracketLoc,
+                                               TypeTy *Ty,
+                                               SourceLocation RAngleBracketLoc,
+                                               SourceLocation LParenLoc,
+                                               ExprArg Op,
+                                               SourceLocation RParenLoc) {
+      Out << __FUNCTION__ << "\n";
+      return ExprEmpty();
+    }
+
+    virtual OwningExprResult ActOnCXXTypeid(SourceLocation OpLoc,
+                                            SourceLocation LParenLoc,
+                                            bool isType, void *TyOrExpr,
+                                            SourceLocation RParenLoc) {
+      Out << __FUNCTION__ << "\n";
+      return ExprEmpty();
+    }
+
+    virtual OwningExprResult ActOnCXXThis(SourceLocation ThisLoc) {
+      Out << __FUNCTION__ << "\n";
+      return ExprEmpty();
+    }
+
+    virtual OwningExprResult ActOnCXXBoolLiteral(SourceLocation OpLoc,
+                                                 tok::TokenKind Kind) {
+      Out << __FUNCTION__ << "\n";
+      return ExprEmpty();
+    }
+
+    virtual OwningExprResult ActOnCXXThrow(SourceLocation OpLoc, ExprArg Op) {
+      Out << __FUNCTION__ << "\n";
+      return ExprEmpty();
+    }
+
+    virtual OwningExprResult ActOnCXXTypeConstructExpr(SourceRange TypeRange,
+                                                     TypeTy *TypeRep,
+                                                     SourceLocation LParenLoc,
+                                                     MultiExprArg Exprs,
+                                                     SourceLocation *CommaLocs,
+                                                     SourceLocation RParenLoc) {
+      Out << __FUNCTION__ << "\n";
+      return ExprEmpty();
+    }
+
+    virtual OwningExprResult ActOnCXXConditionDeclarationExpr(Scope *S,
+                                                        SourceLocation StartLoc,
+                                                        Declarator &D,
+                                                        SourceLocation EqualLoc,
+                                                        ExprArg AssignExprVal) {
+      Out << __FUNCTION__ << "\n";
+      return ExprEmpty();
+    }
+
+    virtual OwningExprResult ActOnCXXNew(SourceLocation StartLoc,
+                                         bool UseGlobal,
+                                         SourceLocation PlacementLParen,
+                                         MultiExprArg PlacementArgs,
+                                         SourceLocation PlacementRParen,
+                                         bool ParenTypeId, Declarator &D,
+                                         SourceLocation ConstructorLParen,
+                                         MultiExprArg ConstructorArgs,
+                                         SourceLocation ConstructorRParen) {
+      Out << __FUNCTION__ << "\n";
+      return ExprEmpty();
+    }
+
+    virtual OwningExprResult ActOnCXXDelete(SourceLocation StartLoc,
+                                            bool UseGlobal, bool ArrayForm,
+                                            ExprArg Operand) {
+      Out << __FUNCTION__ << "\n";
+      return ExprEmpty();
+    }
+
+    virtual OwningExprResult ActOnUnaryTypeTrait(UnaryTypeTrait OTT,
+                                                 SourceLocation KWLoc,
+                                                 SourceLocation LParen,
+                                                 TypeTy *Ty,
+                                                 SourceLocation RParen) {
+      Out << __FUNCTION__ << "\n";
+      return ExprEmpty();
+    }
+  };
+}
+
+MinimalAction *clang::CreatePrintParserActionsAction(Preprocessor &PP,
+                                                     llvm::raw_ostream* OS) {
+  return new ParserPrintActions(PP, *OS);
+}
diff --git a/lib/Frontend/PrintPreprocessedOutput.cpp b/lib/Frontend/PrintPreprocessedOutput.cpp
new file mode 100644
index 0000000..b6c18b7
--- /dev/null
+++ b/lib/Frontend/PrintPreprocessedOutput.cpp
@@ -0,0 +1,520 @@
+//===--- PrintPreprocessedOutput.cpp - Implement the -E mode --------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This code simply runs the preprocessor on the input file and prints out the
+// result.  This is the traditional behavior of the -E option.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/Utils.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Frontend/PreprocessorOutputOptions.h"
+#include "clang/Lex/MacroInfo.h"
+#include "clang/Lex/PPCallbacks.h"
+#include "clang/Lex/Pragma.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Lex/TokenConcatenation.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Config/config.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cstdio>
+using namespace clang;
+
+/// PrintMacroDefinition - Print a macro definition in a form that will be
+/// properly accepted back as a definition.
+static void PrintMacroDefinition(const IdentifierInfo &II, const MacroInfo &MI,
+                                 Preprocessor &PP, llvm::raw_ostream &OS) {
+  OS << "#define " << II.getName();
+
+  if (MI.isFunctionLike()) {
+    OS << '(';
+    if (!MI.arg_empty()) {
+      MacroInfo::arg_iterator AI = MI.arg_begin(), E = MI.arg_end();
+      for (; AI+1 != E; ++AI) {
+        OS << (*AI)->getName();
+        OS << ',';
+      }
+
+      // Last argument.
+      if ((*AI)->getName() == "__VA_ARGS__")
+        OS << "...";
+      else
+        OS << (*AI)->getName();
+    }
+
+    if (MI.isGNUVarargs())
+      OS << "...";  // #define foo(x...)
+
+    OS << ')';
+  }
+
+  // GCC always emits a space, even if the macro body is empty.  However, do not
+  // want to emit two spaces if the first token has a leading space.
+  if (MI.tokens_empty() || !MI.tokens_begin()->hasLeadingSpace())
+    OS << ' ';
+
+  llvm::SmallString<128> SpellingBuffer;
+  for (MacroInfo::tokens_iterator I = MI.tokens_begin(), E = MI.tokens_end();
+       I != E; ++I) {
+    if (I->hasLeadingSpace())
+      OS << ' ';
+
+    OS << PP.getSpelling(*I, SpellingBuffer);
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// Preprocessed token printer
+//===----------------------------------------------------------------------===//
+
+namespace {
+class PrintPPOutputPPCallbacks : public PPCallbacks {
+  Preprocessor &PP;
+  SourceManager &SM;
+  TokenConcatenation ConcatInfo;
+public:
+  llvm::raw_ostream &OS;
+private:
+  unsigned CurLine;
+  bool EmittedTokensOnThisLine;
+  bool EmittedMacroOnThisLine;
+  SrcMgr::CharacteristicKind FileType;
+  llvm::SmallString<512> CurFilename;
+  bool Initialized;
+  bool DisableLineMarkers;
+  bool DumpDefines;
+  bool UseLineDirective;
+public:
+  PrintPPOutputPPCallbacks(Preprocessor &pp, llvm::raw_ostream &os,
+                           bool lineMarkers, bool defines)
+     : PP(pp), SM(PP.getSourceManager()),
+       ConcatInfo(PP), OS(os), DisableLineMarkers(lineMarkers),
+       DumpDefines(defines) {
+    CurLine = 0;
+    CurFilename += "<uninit>";
+    EmittedTokensOnThisLine = false;
+    EmittedMacroOnThisLine = false;
+    FileType = SrcMgr::C_User;
+    Initialized = false;
+
+    // If we're in microsoft mode, use normal #line instead of line markers.
+    UseLineDirective = PP.getLangOptions().Microsoft;
+  }
+
+  void SetEmittedTokensOnThisLine() { EmittedTokensOnThisLine = true; }
+  bool hasEmittedTokensOnThisLine() const { return EmittedTokensOnThisLine; }
+
+  virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,
+                           SrcMgr::CharacteristicKind FileType);
+  virtual void Ident(SourceLocation Loc, const std::string &str);
+  virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind,
+                             const std::string &Str);
+
+
+  bool HandleFirstTokOnLine(Token &Tok);
+  bool MoveToLine(SourceLocation Loc) {
+    return MoveToLine(SM.getPresumedLoc(Loc).getLine());
+  }
+  bool MoveToLine(unsigned LineNo);
+
+  bool AvoidConcat(const Token &PrevPrevTok, const Token &PrevTok, 
+                   const Token &Tok) {
+    return ConcatInfo.AvoidConcat(PrevPrevTok, PrevTok, Tok);
+  }
+  void WriteLineInfo(unsigned LineNo, const char *Extra=0, unsigned ExtraLen=0);
+
+  void HandleNewlinesInToken(const char *TokStr, unsigned Len);
+
+  /// MacroDefined - This hook is called whenever a macro definition is seen.
+  void MacroDefined(const IdentifierInfo *II, const MacroInfo *MI);
+
+};
+}  // end anonymous namespace
+
+void PrintPPOutputPPCallbacks::WriteLineInfo(unsigned LineNo,
+                                             const char *Extra,
+                                             unsigned ExtraLen) {
+  if (EmittedTokensOnThisLine || EmittedMacroOnThisLine) {
+    OS << '\n';
+    EmittedTokensOnThisLine = false;
+    EmittedMacroOnThisLine = false;
+  }
+
+  // Emit #line directives or GNU line markers depending on what mode we're in.
+  if (UseLineDirective) {
+    OS << "#line" << ' ' << LineNo << ' ' << '"';
+    OS.write(&CurFilename[0], CurFilename.size());
+    OS << '"';
+  } else {
+    OS << '#' << ' ' << LineNo << ' ' << '"';
+    OS.write(&CurFilename[0], CurFilename.size());
+    OS << '"';
+
+    if (ExtraLen)
+      OS.write(Extra, ExtraLen);
+
+    if (FileType == SrcMgr::C_System)
+      OS.write(" 3", 2);
+    else if (FileType == SrcMgr::C_ExternCSystem)
+      OS.write(" 3 4", 4);
+  }
+  OS << '\n';
+}
+
+/// MoveToLine - Move the output to the source line specified by the location
+/// object.  We can do this by emitting some number of \n's, or be emitting a
+/// #line directive.  This returns false if already at the specified line, true
+/// if some newlines were emitted.
+bool PrintPPOutputPPCallbacks::MoveToLine(unsigned LineNo) {
+  if (DisableLineMarkers) {
+    if (LineNo == CurLine) return false;
+
+    CurLine = LineNo;
+
+    if (!EmittedTokensOnThisLine && !EmittedMacroOnThisLine)
+      return true;
+
+    OS << '\n';
+    EmittedTokensOnThisLine = false;
+    EmittedMacroOnThisLine = false;
+    return true;
+  }
+
+  // If this line is "close enough" to the original line, just print newlines,
+  // otherwise print a #line directive.
+  if (LineNo-CurLine <= 8) {
+    if (LineNo-CurLine == 1)
+      OS << '\n';
+    else if (LineNo == CurLine)
+      return false;    // Spelling line moved, but instantiation line didn't.
+    else {
+      const char *NewLines = "\n\n\n\n\n\n\n\n";
+      OS.write(NewLines, LineNo-CurLine);
+    }
+  } else {
+    WriteLineInfo(LineNo, 0, 0);
+  }
+
+  CurLine = LineNo;
+  return true;
+}
+
+
+/// FileChanged - Whenever the preprocessor enters or exits a #include file
+/// it invokes this handler.  Update our conception of the current source
+/// position.
+void PrintPPOutputPPCallbacks::FileChanged(SourceLocation Loc,
+                                           FileChangeReason Reason,
+                                       SrcMgr::CharacteristicKind NewFileType) {
+  // Unless we are exiting a #include, make sure to skip ahead to the line the
+  // #include directive was at.
+  SourceManager &SourceMgr = SM;
+  
+  PresumedLoc UserLoc = SourceMgr.getPresumedLoc(Loc);
+  unsigned NewLine = UserLoc.getLine();
+  
+  if (Reason == PPCallbacks::EnterFile) {
+    SourceLocation IncludeLoc = SourceMgr.getPresumedLoc(Loc).getIncludeLoc();
+    if (IncludeLoc.isValid())
+      MoveToLine(IncludeLoc);
+  } else if (Reason == PPCallbacks::SystemHeaderPragma) {
+    MoveToLine(NewLine);
+
+    // TODO GCC emits the # directive for this directive on the line AFTER the
+    // directive and emits a bunch of spaces that aren't needed.  Emulate this
+    // strange behavior.
+  }
+  
+  CurLine = NewLine;
+
+  if (DisableLineMarkers) return;
+
+  CurFilename.clear();
+  CurFilename += UserLoc.getFilename();
+  Lexer::Stringify(CurFilename);
+  FileType = NewFileType;
+
+  if (!Initialized) {
+    WriteLineInfo(CurLine);
+    Initialized = true;
+  }
+
+  switch (Reason) {
+  case PPCallbacks::EnterFile:
+    WriteLineInfo(CurLine, " 1", 2);
+    break;
+  case PPCallbacks::ExitFile:
+    WriteLineInfo(CurLine, " 2", 2);
+    break;
+  case PPCallbacks::SystemHeaderPragma:
+  case PPCallbacks::RenameFile:
+    WriteLineInfo(CurLine);
+    break;
+  }
+}
+
+/// Ident - Handle #ident directives when read by the preprocessor.
+///
+void PrintPPOutputPPCallbacks::Ident(SourceLocation Loc, const std::string &S) {
+  MoveToLine(Loc);
+
+  OS.write("#ident ", strlen("#ident "));
+  OS.write(&S[0], S.size());
+  EmittedTokensOnThisLine = true;
+}
+
+/// MacroDefined - This hook is called whenever a macro definition is seen.
+void PrintPPOutputPPCallbacks::MacroDefined(const IdentifierInfo *II,
+                                            const MacroInfo *MI) {
+  // Only print out macro definitions in -dD mode.
+  if (!DumpDefines ||
+      // Ignore __FILE__ etc.
+      MI->isBuiltinMacro()) return;
+
+  MoveToLine(MI->getDefinitionLoc());
+  PrintMacroDefinition(*II, *MI, PP, OS);
+  EmittedMacroOnThisLine = true;
+}
+
+
+void PrintPPOutputPPCallbacks::PragmaComment(SourceLocation Loc,
+                                             const IdentifierInfo *Kind,
+                                             const std::string &Str) {
+  MoveToLine(Loc);
+  OS << "#pragma comment(" << Kind->getName();
+
+  if (!Str.empty()) {
+    OS << ", \"";
+
+    for (unsigned i = 0, e = Str.size(); i != e; ++i) {
+      unsigned char Char = Str[i];
+      if (isprint(Char) && Char != '\\' && Char != '"')
+        OS << (char)Char;
+      else  // Output anything hard as an octal escape.
+        OS << '\\'
+           << (char)('0'+ ((Char >> 6) & 7))
+           << (char)('0'+ ((Char >> 3) & 7))
+           << (char)('0'+ ((Char >> 0) & 7));
+    }
+    OS << '"';
+  }
+
+  OS << ')';
+  EmittedTokensOnThisLine = true;
+}
+
+
+/// HandleFirstTokOnLine - When emitting a preprocessed file in -E mode, this
+/// is called for the first token on each new line.  If this really is the start
+/// of a new logical line, handle it and return true, otherwise return false.
+/// This may not be the start of a logical line because the "start of line"
+/// marker is set for spelling lines, not instantiation ones.
+bool PrintPPOutputPPCallbacks::HandleFirstTokOnLine(Token &Tok) {
+  // Figure out what line we went to and insert the appropriate number of
+  // newline characters.
+  if (!MoveToLine(Tok.getLocation()))
+    return false;
+
+  // Print out space characters so that the first token on a line is
+  // indented for easy reading.
+  unsigned ColNo = SM.getInstantiationColumnNumber(Tok.getLocation());
+
+  // This hack prevents stuff like:
+  // #define HASH #
+  // HASH define foo bar
+  // From having the # character end up at column 1, which makes it so it
+  // is not handled as a #define next time through the preprocessor if in
+  // -fpreprocessed mode.
+  if (ColNo <= 1 && Tok.is(tok::hash))
+    OS << ' ';
+
+  // Otherwise, indent the appropriate number of spaces.
+  for (; ColNo > 1; --ColNo)
+    OS << ' ';
+
+  return true;
+}
+
+void PrintPPOutputPPCallbacks::HandleNewlinesInToken(const char *TokStr,
+                                                     unsigned Len) {
+  unsigned NumNewlines = 0;
+  for (; Len; --Len, ++TokStr) {
+    if (*TokStr != '\n' &&
+        *TokStr != '\r')
+      continue;
+
+    ++NumNewlines;
+
+    // If we have \n\r or \r\n, skip both and count as one line.
+    if (Len != 1 &&
+        (TokStr[1] == '\n' || TokStr[1] == '\r') &&
+        TokStr[0] != TokStr[1])
+      ++TokStr, --Len;
+  }
+
+  if (NumNewlines == 0) return;
+
+  CurLine += NumNewlines;
+}
+
+
+namespace {
+struct UnknownPragmaHandler : public PragmaHandler {
+  const char *Prefix;
+  PrintPPOutputPPCallbacks *Callbacks;
+
+  UnknownPragmaHandler(const char *prefix, PrintPPOutputPPCallbacks *callbacks)
+    : PragmaHandler(0), Prefix(prefix), Callbacks(callbacks) {}
+  virtual void HandlePragma(Preprocessor &PP, Token &PragmaTok) {
+    // Figure out what line we went to and insert the appropriate number of
+    // newline characters.
+    Callbacks->MoveToLine(PragmaTok.getLocation());
+    Callbacks->OS.write(Prefix, strlen(Prefix));
+
+    // Read and print all of the pragma tokens.
+    while (PragmaTok.isNot(tok::eom)) {
+      if (PragmaTok.hasLeadingSpace())
+        Callbacks->OS << ' ';
+      std::string TokSpell = PP.getSpelling(PragmaTok);
+      Callbacks->OS.write(&TokSpell[0], TokSpell.size());
+      PP.LexUnexpandedToken(PragmaTok);
+    }
+    Callbacks->OS << '\n';
+  }
+};
+} // end anonymous namespace
+
+
+static void PrintPreprocessedTokens(Preprocessor &PP, Token &Tok,
+                                    PrintPPOutputPPCallbacks *Callbacks,
+                                    llvm::raw_ostream &OS) {
+  char Buffer[256];
+  Token PrevPrevTok;
+  Token PrevTok;
+  while (1) {
+
+    // If this token is at the start of a line, emit newlines if needed.
+    if (Tok.isAtStartOfLine() && Callbacks->HandleFirstTokOnLine(Tok)) {
+      // done.
+    } else if (Tok.hasLeadingSpace() ||
+               // If we haven't emitted a token on this line yet, PrevTok isn't
+               // useful to look at and no concatenation could happen anyway.
+               (Callbacks->hasEmittedTokensOnThisLine() &&
+                // Don't print "-" next to "-", it would form "--".
+                Callbacks->AvoidConcat(PrevPrevTok, PrevTok, Tok))) {
+      OS << ' ';
+    }
+
+    if (IdentifierInfo *II = Tok.getIdentifierInfo()) {
+      OS << II->getName();
+    } else if (Tok.isLiteral() && !Tok.needsCleaning() &&
+               Tok.getLiteralData()) {
+      OS.write(Tok.getLiteralData(), Tok.getLength());
+    } else if (Tok.getLength() < 256) {
+      const char *TokPtr = Buffer;
+      unsigned Len = PP.getSpelling(Tok, TokPtr);
+      OS.write(TokPtr, Len);
+
+      // Tokens that can contain embedded newlines need to adjust our current
+      // line number.
+      if (Tok.getKind() == tok::comment)
+        Callbacks->HandleNewlinesInToken(TokPtr, Len);
+    } else {
+      std::string S = PP.getSpelling(Tok);
+      OS.write(&S[0], S.size());
+
+      // Tokens that can contain embedded newlines need to adjust our current
+      // line number.
+      if (Tok.getKind() == tok::comment)
+        Callbacks->HandleNewlinesInToken(&S[0], S.size());
+    }
+    Callbacks->SetEmittedTokensOnThisLine();
+
+    if (Tok.is(tok::eof)) break;
+
+    PrevPrevTok = PrevTok;
+    PrevTok = Tok;
+    PP.Lex(Tok);
+  }
+}
+
+typedef std::pair<IdentifierInfo*, MacroInfo*> id_macro_pair;
+static int MacroIDCompare(const void* a, const void* b) {
+  const id_macro_pair *LHS = static_cast<const id_macro_pair*>(a);
+  const id_macro_pair *RHS = static_cast<const id_macro_pair*>(b);
+  return LHS->first->getName().compare(RHS->first->getName());
+}
+
+static void DoPrintMacros(Preprocessor &PP, llvm::raw_ostream *OS) {
+  // -dM mode just scans and ignores all tokens in the files, then dumps out
+  // the macro table at the end.
+  PP.EnterMainSourceFile();
+
+  Token Tok;
+  do PP.Lex(Tok);
+  while (Tok.isNot(tok::eof));
+
+  llvm::SmallVector<id_macro_pair, 128>
+    MacrosByID(PP.macro_begin(), PP.macro_end());
+  llvm::array_pod_sort(MacrosByID.begin(), MacrosByID.end(), MacroIDCompare);
+
+  for (unsigned i = 0, e = MacrosByID.size(); i != e; ++i) {
+    MacroInfo &MI = *MacrosByID[i].second;
+    // Ignore computed macros like __LINE__ and friends.
+    if (MI.isBuiltinMacro()) continue;
+
+    PrintMacroDefinition(*MacrosByID[i].first, MI, PP, *OS);
+    *OS << '\n';
+  }
+}
+
+/// DoPrintPreprocessedInput - This implements -E mode.
+///
+void clang::DoPrintPreprocessedInput(Preprocessor &PP, llvm::raw_ostream *OS,
+                                     const PreprocessorOutputOptions &Opts) {
+  // Show macros with no output is handled specially.
+  if (!Opts.ShowCPP) {
+    assert(Opts.ShowMacros && "Not yet implemented!");
+    DoPrintMacros(PP, OS);
+    return;
+  }
+
+  // Inform the preprocessor whether we want it to retain comments or not, due
+  // to -C or -CC.
+  PP.SetCommentRetentionState(Opts.ShowComments, Opts.ShowMacroComments);
+
+  PrintPPOutputPPCallbacks *Callbacks =
+      new PrintPPOutputPPCallbacks(PP, *OS, !Opts.ShowLineMarkers,
+                                   Opts.ShowMacros);
+  PP.AddPragmaHandler(0, new UnknownPragmaHandler("#pragma", Callbacks));
+  PP.AddPragmaHandler("GCC", new UnknownPragmaHandler("#pragma GCC",
+                                                      Callbacks));
+
+  PP.addPPCallbacks(Callbacks);
+
+  // After we have configured the preprocessor, enter the main file.
+  PP.EnterMainSourceFile();
+
+  // Consume all of the tokens that come from the predefines buffer.  Those
+  // should not be emitted into the output and are guaranteed to be at the
+  // start.
+  const SourceManager &SourceMgr = PP.getSourceManager();
+  Token Tok;
+  do PP.Lex(Tok);
+  while (Tok.isNot(tok::eof) && Tok.getLocation().isFileID() &&
+         !strcmp(SourceMgr.getPresumedLoc(Tok.getLocation()).getFilename(),
+                 "<built-in>"));
+
+  // Read all the preprocessed tokens, printing them out to the stream.
+  PrintPreprocessedTokens(PP, Tok, Callbacks, *OS);
+  *OS << '\n';
+}
+
diff --git a/lib/Frontend/RewriteMacros.cpp b/lib/Frontend/RewriteMacros.cpp
new file mode 100644
index 0000000..954e8e2
--- /dev/null
+++ b/lib/Frontend/RewriteMacros.cpp
@@ -0,0 +1,217 @@
+//===--- RewriteMacros.cpp - Rewrite macros into their expansions ---------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This code rewrites macro invocations into their expansions.  This gives you
+// a macro expanded file that retains comments and #includes.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/Utils.h"
+#include "clang/Rewrite/Rewriter.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Basic/SourceManager.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/System/Path.h"
+#include "llvm/ADT/OwningPtr.h"
+#include <cstdio>
+
+using namespace clang;
+
+/// isSameToken - Return true if the two specified tokens start have the same
+/// content.
+static bool isSameToken(Token &RawTok, Token &PPTok) {
+  // If two tokens have the same kind and the same identifier info, they are
+  // obviously the same.
+  if (PPTok.getKind() == RawTok.getKind() &&
+      PPTok.getIdentifierInfo() == RawTok.getIdentifierInfo())
+    return true;
+
+  // Otherwise, if they are different but have the same identifier info, they
+  // are also considered to be the same.  This allows keywords and raw lexed
+  // identifiers with the same name to be treated the same.
+  if (PPTok.getIdentifierInfo() &&
+      PPTok.getIdentifierInfo() == RawTok.getIdentifierInfo())
+    return true;
+
+  return false;
+}
+
+
+/// GetNextRawTok - Return the next raw token in the stream, skipping over
+/// comments if ReturnComment is false.
+static const Token &GetNextRawTok(const std::vector<Token> &RawTokens,
+                                  unsigned &CurTok, bool ReturnComment) {
+  assert(CurTok < RawTokens.size() && "Overran eof!");
+
+  // If the client doesn't want comments and we have one, skip it.
+  if (!ReturnComment && RawTokens[CurTok].is(tok::comment))
+    ++CurTok;
+
+  return RawTokens[CurTok++];
+}
+
+
+/// LexRawTokensFromMainFile - Lets all the raw tokens from the main file into
+/// the specified vector.
+static void LexRawTokensFromMainFile(Preprocessor &PP,
+                                     std::vector<Token> &RawTokens) {
+  SourceManager &SM = PP.getSourceManager();
+
+  // Create a lexer to lex all the tokens of the main file in raw mode.  Even
+  // though it is in raw mode, it will not return comments.
+  const llvm::MemoryBuffer *FromFile = SM.getBuffer(SM.getMainFileID());
+  Lexer RawLex(SM.getMainFileID(), FromFile, SM, PP.getLangOptions());
+
+  // Switch on comment lexing because we really do want them.
+  RawLex.SetCommentRetentionState(true);
+
+  Token RawTok;
+  do {
+    RawLex.LexFromRawLexer(RawTok);
+
+    // If we have an identifier with no identifier info for our raw token, look
+    // up the indentifier info.  This is important for equality comparison of
+    // identifier tokens.
+    if (RawTok.is(tok::identifier) && !RawTok.getIdentifierInfo())
+      PP.LookUpIdentifierInfo(RawTok);
+
+    RawTokens.push_back(RawTok);
+  } while (RawTok.isNot(tok::eof));
+}
+
+
+/// RewriteMacrosInInput - Implement -rewrite-macros mode.
+void clang::RewriteMacrosInInput(Preprocessor &PP, llvm::raw_ostream *OS) {
+  SourceManager &SM = PP.getSourceManager();
+
+  Rewriter Rewrite;
+  Rewrite.setSourceMgr(SM, PP.getLangOptions());
+  RewriteBuffer &RB = Rewrite.getEditBuffer(SM.getMainFileID());
+
+  std::vector<Token> RawTokens;
+  LexRawTokensFromMainFile(PP, RawTokens);
+  unsigned CurRawTok = 0;
+  Token RawTok = GetNextRawTok(RawTokens, CurRawTok, false);
+
+
+  // Get the first preprocessing token.
+  PP.EnterMainSourceFile();
+  Token PPTok;
+  PP.Lex(PPTok);
+
+  // Preprocess the input file in parallel with raw lexing the main file. Ignore
+  // all tokens that are preprocessed from a file other than the main file (e.g.
+  // a header).  If we see tokens that are in the preprocessed file but not the
+  // lexed file, we have a macro expansion.  If we see tokens in the lexed file
+  // that aren't in the preprocessed view, we have macros that expand to no
+  // tokens, or macro arguments etc.
+  while (RawTok.isNot(tok::eof) || PPTok.isNot(tok::eof)) {
+    SourceLocation PPLoc = SM.getInstantiationLoc(PPTok.getLocation());
+
+    // If PPTok is from a different source file, ignore it.
+    if (!SM.isFromMainFile(PPLoc)) {
+      PP.Lex(PPTok);
+      continue;
+    }
+
+    // If the raw file hits a preprocessor directive, they will be extra tokens
+    // in the raw file that don't exist in the preprocsesed file.  However, we
+    // choose to preserve them in the output file and otherwise handle them
+    // specially.
+    if (RawTok.is(tok::hash) && RawTok.isAtStartOfLine()) {
+      // If this is a #warning directive or #pragma mark (GNU extensions),
+      // comment the line out.
+      if (RawTokens[CurRawTok].is(tok::identifier)) {
+        const IdentifierInfo *II = RawTokens[CurRawTok].getIdentifierInfo();
+        if (II->getName() == "warning") {
+          // Comment out #warning.
+          RB.InsertTextAfter(SM.getFileOffset(RawTok.getLocation()), "//");
+        } else if (II->getName() == "pragma" &&
+                   RawTokens[CurRawTok+1].is(tok::identifier) &&
+                   (RawTokens[CurRawTok+1].getIdentifierInfo()->getName() ==
+                    "mark")) {
+          // Comment out #pragma mark.
+          RB.InsertTextAfter(SM.getFileOffset(RawTok.getLocation()), "//");
+        }
+      }
+
+      // Otherwise, if this is a #include or some other directive, just leave it
+      // in the file by skipping over the line.
+      RawTok = GetNextRawTok(RawTokens, CurRawTok, false);
+      while (!RawTok.isAtStartOfLine() && RawTok.isNot(tok::eof))
+        RawTok = GetNextRawTok(RawTokens, CurRawTok, false);
+      continue;
+    }
+
+    // Okay, both tokens are from the same file.  Get their offsets from the
+    // start of the file.
+    unsigned PPOffs = SM.getFileOffset(PPLoc);
+    unsigned RawOffs = SM.getFileOffset(RawTok.getLocation());
+
+    // If the offsets are the same and the token kind is the same, ignore them.
+    if (PPOffs == RawOffs && isSameToken(RawTok, PPTok)) {
+      RawTok = GetNextRawTok(RawTokens, CurRawTok, false);
+      PP.Lex(PPTok);
+      continue;
+    }
+
+    // If the PP token is farther along than the raw token, something was
+    // deleted.  Comment out the raw token.
+    if (RawOffs <= PPOffs) {
+      // Comment out a whole run of tokens instead of bracketing each one with
+      // comments.  Add a leading space if RawTok didn't have one.
+      bool HasSpace = RawTok.hasLeadingSpace();
+      RB.InsertTextAfter(RawOffs, " /*"+HasSpace);
+      unsigned EndPos;
+
+      do {
+        EndPos = RawOffs+RawTok.getLength();
+
+        RawTok = GetNextRawTok(RawTokens, CurRawTok, true);
+        RawOffs = SM.getFileOffset(RawTok.getLocation());
+
+        if (RawTok.is(tok::comment)) {
+          // Skip past the comment.
+          RawTok = GetNextRawTok(RawTokens, CurRawTok, false);
+          break;
+        }
+
+      } while (RawOffs <= PPOffs && !RawTok.isAtStartOfLine() &&
+               (PPOffs != RawOffs || !isSameToken(RawTok, PPTok)));
+
+      RB.InsertTextBefore(EndPos, "*/");
+      continue;
+    }
+
+    // Otherwise, there was a replacement an expansion.  Insert the new token
+    // in the output buffer.  Insert the whole run of new tokens at once to get
+    // them in the right order.
+    unsigned InsertPos = PPOffs;
+    std::string Expansion;
+    while (PPOffs < RawOffs) {
+      Expansion += ' ' + PP.getSpelling(PPTok);
+      PP.Lex(PPTok);
+      PPLoc = SM.getInstantiationLoc(PPTok.getLocation());
+      PPOffs = SM.getFileOffset(PPLoc);
+    }
+    Expansion += ' ';
+    RB.InsertTextBefore(InsertPos, Expansion);
+  }
+
+  // Get the buffer corresponding to MainFileID.  If we haven't changed it, then
+  // we are done.
+  if (const RewriteBuffer *RewriteBuf =
+      Rewrite.getRewriteBufferFor(SM.getMainFileID())) {
+    //printf("Changed:\n");
+    *OS << std::string(RewriteBuf->begin(), RewriteBuf->end());
+  } else {
+    fprintf(stderr, "No changes\n");
+  }
+  OS->flush();
+}
diff --git a/lib/Frontend/RewriteObjC.cpp b/lib/Frontend/RewriteObjC.cpp
new file mode 100644
index 0000000..1169832
--- /dev/null
+++ b/lib/Frontend/RewriteObjC.cpp
@@ -0,0 +1,5727 @@
+//===--- RewriteObjC.cpp - Playground for the code rewriter ---------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Hacks and fun related to the code rewriter.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/ASTConsumers.h"
+#include "clang/Rewrite/Rewriter.h"
+#include "clang/AST/AST.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/ParentMap.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Lex/Lexer.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/DenseSet.h"
+
+using namespace clang;
+using llvm::utostr;
+
+namespace {
+  class RewriteObjC : public ASTConsumer {
+    enum {
+      BLOCK_FIELD_IS_OBJECT   =  3,  /* id, NSObject, __attribute__((NSObject)), 
+                                        block, ... */
+      BLOCK_FIELD_IS_BLOCK    =  7,  /* a block variable */
+      BLOCK_FIELD_IS_BYREF    =  8,  /* the on stack structure holding the 
+                                        __block variable */
+      BLOCK_FIELD_IS_WEAK     = 16,  /* declared __weak, only used in byref copy 
+                                        helpers */
+      BLOCK_BYREF_CALLER      = 128, /* called from __block (byref) copy/dispose 
+                                        support routines */
+      BLOCK_BYREF_CURRENT_MAX = 256
+    };
+    
+    enum {
+      BLOCK_NEEDS_FREE =        (1 << 24),
+      BLOCK_HAS_COPY_DISPOSE =  (1 << 25),
+      BLOCK_HAS_CXX_OBJ =       (1 << 26),
+      BLOCK_IS_GC =             (1 << 27),
+      BLOCK_IS_GLOBAL =         (1 << 28),
+      BLOCK_HAS_DESCRIPTOR =    (1 << 29)
+    };
+    
+    Rewriter Rewrite;
+    Diagnostic &Diags;
+    const LangOptions &LangOpts;
+    unsigned RewriteFailedDiag;
+    unsigned TryFinallyContainsReturnDiag;
+
+    ASTContext *Context;
+    SourceManager *SM;
+    TranslationUnitDecl *TUDecl;
+    FileID MainFileID;
+    const char *MainFileStart, *MainFileEnd;
+    SourceLocation LastIncLoc;
+
+    llvm::SmallVector<ObjCImplementationDecl *, 8> ClassImplementation;
+    llvm::SmallVector<ObjCCategoryImplDecl *, 8> CategoryImplementation;
+    llvm::SmallPtrSet<ObjCInterfaceDecl*, 8> ObjCSynthesizedStructs;
+    llvm::SmallPtrSet<ObjCProtocolDecl*, 8> ObjCSynthesizedProtocols;
+    llvm::SmallPtrSet<ObjCInterfaceDecl*, 8> ObjCForwardDecls;
+    llvm::DenseMap<ObjCMethodDecl*, std::string> MethodInternalNames;
+    llvm::SmallVector<Stmt *, 32> Stmts;
+    llvm::SmallVector<int, 8> ObjCBcLabelNo;
+    // Remember all the @protocol(<expr>) expressions.
+    llvm::SmallPtrSet<ObjCProtocolDecl *, 32> ProtocolExprDecls;
+    
+    llvm::DenseSet<uint64_t> CopyDestroyCache;
+    
+    unsigned NumObjCStringLiterals;
+
+    FunctionDecl *MsgSendFunctionDecl;
+    FunctionDecl *MsgSendSuperFunctionDecl;
+    FunctionDecl *MsgSendStretFunctionDecl;
+    FunctionDecl *MsgSendSuperStretFunctionDecl;
+    FunctionDecl *MsgSendFpretFunctionDecl;
+    FunctionDecl *GetClassFunctionDecl;
+    FunctionDecl *GetMetaClassFunctionDecl;
+    FunctionDecl *GetSuperClassFunctionDecl;
+    FunctionDecl *SelGetUidFunctionDecl;
+    FunctionDecl *CFStringFunctionDecl;
+    FunctionDecl *SuperContructorFunctionDecl;
+
+    // ObjC string constant support.
+    VarDecl *ConstantStringClassReference;
+    RecordDecl *NSStringRecord;
+
+    // ObjC foreach break/continue generation support.
+    int BcLabelCount;
+
+    // Needed for super.
+    ObjCMethodDecl *CurMethodDef;
+    RecordDecl *SuperStructDecl;
+    RecordDecl *ConstantStringDecl;
+
+    TypeDecl *ProtocolTypeDecl;
+    QualType getProtocolType();
+
+    // Needed for header files being rewritten
+    bool IsHeader;
+
+    std::string InFileName;
+    llvm::raw_ostream* OutFile;
+
+    bool SilenceRewriteMacroWarning;
+    bool objc_impl_method;
+
+    std::string Preamble;
+
+    // Block expressions.
+    llvm::SmallVector<BlockExpr *, 32> Blocks;
+    llvm::SmallVector<int, 32> InnerDeclRefsCount;
+    llvm::SmallVector<BlockDeclRefExpr *, 32> InnerDeclRefs;
+    
+    llvm::SmallVector<BlockDeclRefExpr *, 32> BlockDeclRefs;
+
+    // Block related declarations.
+    llvm::SmallVector<ValueDecl *, 8> BlockByCopyDecls;
+    llvm::SmallPtrSet<ValueDecl *, 8> BlockByCopyDeclsPtrSet;
+    llvm::SmallVector<ValueDecl *, 8> BlockByRefDecls;
+    llvm::SmallPtrSet<ValueDecl *, 8> BlockByRefDeclsPtrSet;
+    llvm::DenseMap<ValueDecl *, unsigned> BlockByRefDeclNo;
+    llvm::SmallPtrSet<ValueDecl *, 8> ImportedBlockDecls;
+    llvm::SmallPtrSet<VarDecl *, 8> ImportedLocalExternalDecls;
+    
+    llvm::DenseMap<BlockExpr *, std::string> RewrittenBlockExprs;
+
+    // This maps a property to it's assignment statement.
+    llvm::DenseMap<ObjCPropertyRefExpr *, BinaryOperator *> PropSetters;
+    // This maps a property to it's synthesied message expression.
+    // This allows us to rewrite chained getters (e.g. o.a.b.c).
+    llvm::DenseMap<ObjCPropertyRefExpr *, Stmt *> PropGetters;
+
+    // This maps an original source AST to it's rewritten form. This allows
+    // us to avoid rewriting the same node twice (which is very uncommon).
+    // This is needed to support some of the exotic property rewriting.
+    llvm::DenseMap<Stmt *, Stmt *> ReplacedNodes;
+
+    FunctionDecl *CurFunctionDef;
+    FunctionDecl *CurFunctionDeclToDeclareForBlock;
+    VarDecl *GlobalVarDecl;
+
+    bool DisableReplaceStmt;
+
+    static const int OBJC_ABI_VERSION =7 ;
+  public:
+    virtual void Initialize(ASTContext &context);
+
+    // Top Level Driver code.
+    virtual void HandleTopLevelDecl(DeclGroupRef D) {
+      for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I)
+        HandleTopLevelSingleDecl(*I);
+    }
+    void HandleTopLevelSingleDecl(Decl *D);
+    void HandleDeclInMainFile(Decl *D);
+    RewriteObjC(std::string inFile, llvm::raw_ostream *OS,
+                Diagnostic &D, const LangOptions &LOpts,
+                bool silenceMacroWarn);
+
+    ~RewriteObjC() {}
+
+    virtual void HandleTranslationUnit(ASTContext &C);
+
+    void ReplaceStmt(Stmt *Old, Stmt *New) {
+      Stmt *ReplacingStmt = ReplacedNodes[Old];
+
+      if (ReplacingStmt)
+        return; // We can't rewrite the same node twice.
+
+      if (DisableReplaceStmt)
+        return; // Used when rewriting the assignment of a property setter.
+
+      // If replacement succeeded or warning disabled return with no warning.
+      if (!Rewrite.ReplaceStmt(Old, New)) {
+        ReplacedNodes[Old] = New;
+        return;
+      }
+      if (SilenceRewriteMacroWarning)
+        return;
+      Diags.Report(Context->getFullLoc(Old->getLocStart()), RewriteFailedDiag)
+                   << Old->getSourceRange();
+    }
+
+    void ReplaceStmtWithRange(Stmt *Old, Stmt *New, SourceRange SrcRange) {
+      // Measaure the old text.
+      int Size = Rewrite.getRangeSize(SrcRange);
+      if (Size == -1) {
+        Diags.Report(Context->getFullLoc(Old->getLocStart()), RewriteFailedDiag)
+                     << Old->getSourceRange();
+        return;
+      }
+      // Get the new text.
+      std::string SStr;
+      llvm::raw_string_ostream S(SStr);
+      New->printPretty(S, *Context, 0, PrintingPolicy(LangOpts));
+      const std::string &Str = S.str();
+
+      // If replacement succeeded or warning disabled return with no warning.
+      if (!Rewrite.ReplaceText(SrcRange.getBegin(), Size, Str)) {
+        ReplacedNodes[Old] = New;
+        return;
+      }
+      if (SilenceRewriteMacroWarning)
+        return;
+      Diags.Report(Context->getFullLoc(Old->getLocStart()), RewriteFailedDiag)
+                   << Old->getSourceRange();
+    }
+
+    void InsertText(SourceLocation Loc, llvm::StringRef Str,
+                    bool InsertAfter = true) {
+      // If insertion succeeded or warning disabled return with no warning.
+      if (!Rewrite.InsertText(Loc, Str, InsertAfter) ||
+          SilenceRewriteMacroWarning)
+        return;
+
+      Diags.Report(Context->getFullLoc(Loc), RewriteFailedDiag);
+    }
+
+    void RemoveText(SourceLocation Loc, unsigned StrLen) {
+      // If removal succeeded or warning disabled return with no warning.
+      if (!Rewrite.RemoveText(Loc, StrLen) || SilenceRewriteMacroWarning)
+        return;
+
+      Diags.Report(Context->getFullLoc(Loc), RewriteFailedDiag);
+    }
+
+    void ReplaceText(SourceLocation Start, unsigned OrigLength,
+                     llvm::StringRef Str) {
+      // If removal succeeded or warning disabled return with no warning.
+      if (!Rewrite.ReplaceText(Start, OrigLength, Str) ||
+          SilenceRewriteMacroWarning)
+        return;
+
+      Diags.Report(Context->getFullLoc(Start), RewriteFailedDiag);
+    }
+
+    // Syntactic Rewriting.
+    void RewritePrologue(SourceLocation Loc);
+    void RewriteInclude();
+    void RewriteTabs();
+    void RewriteForwardClassDecl(ObjCClassDecl *Dcl);
+    void RewritePropertyImplDecl(ObjCPropertyImplDecl *PID,
+                                 ObjCImplementationDecl *IMD,
+                                 ObjCCategoryImplDecl *CID);
+    void RewriteInterfaceDecl(ObjCInterfaceDecl *Dcl);
+    void RewriteImplementationDecl(Decl *Dcl);
+    void RewriteObjCMethodDecl(ObjCMethodDecl *MDecl, std::string &ResultStr);
+    void RewriteTypeIntoString(QualType T, std::string &ResultStr,
+                               const FunctionType *&FPRetType);
+    void RewriteByRefString(std::string &ResultStr, const std::string &Name,
+                            ValueDecl *VD);
+    void RewriteCategoryDecl(ObjCCategoryDecl *Dcl);
+    void RewriteProtocolDecl(ObjCProtocolDecl *Dcl);
+    void RewriteForwardProtocolDecl(ObjCForwardProtocolDecl *Dcl);
+    void RewriteMethodDeclaration(ObjCMethodDecl *Method);
+    void RewriteProperty(ObjCPropertyDecl *prop);
+    void RewriteFunctionDecl(FunctionDecl *FD);
+    void RewriteBlockLiteralFunctionDecl(FunctionDecl *FD);
+    void RewriteObjCQualifiedInterfaceTypes(Decl *Dcl);
+    void RewriteTypeOfDecl(VarDecl *VD);
+    void RewriteObjCQualifiedInterfaceTypes(Expr *E);
+    bool needToScanForQualifiers(QualType T);
+    bool isSuperReceiver(Expr *recExpr);
+    QualType getSuperStructType();
+    QualType getConstantStringStructType();
+    bool BufferContainsPPDirectives(const char *startBuf, const char *endBuf);
+
+    // Expression Rewriting.
+    Stmt *RewriteFunctionBodyOrGlobalInitializer(Stmt *S);
+    void CollectPropertySetters(Stmt *S);
+
+    Stmt *CurrentBody;
+    ParentMap *PropParentMap; // created lazily.
+
+    Stmt *RewriteAtEncode(ObjCEncodeExpr *Exp);
+    Stmt *RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV, SourceLocation OrigStart,
+                                 bool &replaced);
+    Stmt *RewriteObjCNestedIvarRefExpr(Stmt *S, bool &replaced);
+    Stmt *RewritePropertyGetter(ObjCPropertyRefExpr *PropRefExpr);
+    Stmt *RewritePropertySetter(BinaryOperator *BinOp, Expr *newStmt,
+                                SourceRange SrcRange);
+    Stmt *RewriteAtSelector(ObjCSelectorExpr *Exp);
+    Stmt *RewriteMessageExpr(ObjCMessageExpr *Exp);
+    Stmt *RewriteObjCStringLiteral(ObjCStringLiteral *Exp);
+    Stmt *RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp);
+    void WarnAboutReturnGotoStmts(Stmt *S);
+    void HasReturnStmts(Stmt *S, bool &hasReturns);
+    void RewriteTryReturnStmts(Stmt *S);
+    void RewriteSyncReturnStmts(Stmt *S, std::string buf);
+    Stmt *RewriteObjCTryStmt(ObjCAtTryStmt *S);
+    Stmt *RewriteObjCSynchronizedStmt(ObjCAtSynchronizedStmt *S);
+    Stmt *RewriteObjCCatchStmt(ObjCAtCatchStmt *S);
+    Stmt *RewriteObjCFinallyStmt(ObjCAtFinallyStmt *S);
+    Stmt *RewriteObjCThrowStmt(ObjCAtThrowStmt *S);
+    Stmt *RewriteObjCForCollectionStmt(ObjCForCollectionStmt *S,
+                                       SourceLocation OrigEnd);
+    CallExpr *SynthesizeCallToFunctionDecl(FunctionDecl *FD,
+                                      Expr **args, unsigned nargs,
+                                      SourceLocation StartLoc=SourceLocation(),
+                                      SourceLocation EndLoc=SourceLocation());
+    Stmt *SynthMessageExpr(ObjCMessageExpr *Exp,
+                           SourceLocation StartLoc=SourceLocation(),
+                           SourceLocation EndLoc=SourceLocation());
+    Stmt *RewriteBreakStmt(BreakStmt *S);
+    Stmt *RewriteContinueStmt(ContinueStmt *S);
+    void SynthCountByEnumWithState(std::string &buf);
+
+    void SynthMsgSendFunctionDecl();
+    void SynthMsgSendSuperFunctionDecl();
+    void SynthMsgSendStretFunctionDecl();
+    void SynthMsgSendFpretFunctionDecl();
+    void SynthMsgSendSuperStretFunctionDecl();
+    void SynthGetClassFunctionDecl();
+    void SynthGetMetaClassFunctionDecl();
+    void SynthGetSuperClassFunctionDecl();
+    void SynthSelGetUidFunctionDecl();
+    void SynthSuperContructorFunctionDecl();
+
+    // Metadata emission.
+    void RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl,
+                                  std::string &Result);
+
+    void RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *CDecl,
+                                     std::string &Result);
+
+    template<typename MethodIterator>
+    void RewriteObjCMethodsMetaData(MethodIterator MethodBegin,
+                                    MethodIterator MethodEnd,
+                                    bool IsInstanceMethod,
+                                    const char *prefix,
+                                    const char *ClassName,
+                                    std::string &Result);
+
+    void RewriteObjCProtocolMetaData(ObjCProtocolDecl *Protocol,
+                                     const char *prefix,
+                                     const char *ClassName,
+                                     std::string &Result);
+    void RewriteObjCProtocolListMetaData(const ObjCList<ObjCProtocolDecl> &Prots,
+                                         const char *prefix,
+                                         const char *ClassName,
+                                         std::string &Result);
+    void SynthesizeObjCInternalStruct(ObjCInterfaceDecl *CDecl,
+                                      std::string &Result);
+    void SynthesizeIvarOffsetComputation(ObjCContainerDecl *IDecl,
+                                         ObjCIvarDecl *ivar,
+                                         std::string &Result);
+    void RewriteImplementations();
+    void SynthesizeMetaDataIntoBuffer(std::string &Result);
+
+    // Block rewriting.
+    void RewriteBlocksInFunctionProtoType(QualType funcType, NamedDecl *D);
+    void CheckFunctionPointerDecl(QualType dType, NamedDecl *ND);
+
+    void InsertBlockLiteralsWithinFunction(FunctionDecl *FD);
+    void InsertBlockLiteralsWithinMethod(ObjCMethodDecl *MD);
+
+    // Block specific rewrite rules.
+    void RewriteBlockCall(CallExpr *Exp);
+    void RewriteBlockPointerDecl(NamedDecl *VD);
+    void RewriteByRefVar(VarDecl *VD);
+    std::string SynthesizeByrefCopyDestroyHelper(VarDecl *VD, int flag);
+    Stmt *RewriteBlockDeclRefExpr(Expr *VD);
+    Stmt *RewriteLocalVariableExternalStorage(DeclRefExpr *DRE);
+    void RewriteBlockPointerFunctionArgs(FunctionDecl *FD);
+
+    std::string SynthesizeBlockHelperFuncs(BlockExpr *CE, int i,
+                                      const char *funcName, std::string Tag);
+    std::string SynthesizeBlockFunc(BlockExpr *CE, int i,
+                                      const char *funcName, std::string Tag);
+    std::string SynthesizeBlockImpl(BlockExpr *CE, 
+                                    std::string Tag, std::string Desc);
+    std::string SynthesizeBlockDescriptor(std::string DescTag, 
+                                          std::string ImplTag,
+                                          int i, const char *funcName,
+                                          unsigned hasCopy);
+    Stmt *SynthesizeBlockCall(CallExpr *Exp, const Expr* BlockExp);
+    void SynthesizeBlockLiterals(SourceLocation FunLocStart,
+                                 const char *FunName);
+    void RewriteRecordBody(RecordDecl *RD);
+
+    void CollectBlockDeclRefInfo(BlockExpr *Exp);
+    void GetBlockDeclRefExprs(Stmt *S);
+    void GetInnerBlockDeclRefExprs(Stmt *S, 
+                llvm::SmallVector<BlockDeclRefExpr *, 8> &InnerBlockDeclRefs,
+                llvm::SmallPtrSet<const DeclContext *, 8> &InnerContexts);
+
+    // We avoid calling Type::isBlockPointerType(), since it operates on the
+    // canonical type. We only care if the top-level type is a closure pointer.
+    bool isTopLevelBlockPointerType(QualType T) {
+      return isa<BlockPointerType>(T);
+    }
+
+    // FIXME: This predicate seems like it would be useful to add to ASTContext.
+    bool isObjCType(QualType T) {
+      if (!LangOpts.ObjC1 && !LangOpts.ObjC2)
+        return false;
+
+      QualType OCT = Context->getCanonicalType(T).getUnqualifiedType();
+
+      if (OCT == Context->getCanonicalType(Context->getObjCIdType()) ||
+          OCT == Context->getCanonicalType(Context->getObjCClassType()))
+        return true;
+
+      if (const PointerType *PT = OCT->getAs<PointerType>()) {
+        if (isa<ObjCInterfaceType>(PT->getPointeeType()) ||
+            PT->getPointeeType()->isObjCQualifiedIdType())
+          return true;
+      }
+      return false;
+    }
+    bool PointerTypeTakesAnyBlockArguments(QualType QT);
+    void GetExtentOfArgList(const char *Name, const char *&LParen,
+                            const char *&RParen);
+    void RewriteCastExpr(CStyleCastExpr *CE);
+
+    FunctionDecl *SynthBlockInitFunctionDecl(const char *name);
+    Stmt *SynthBlockInitExpr(BlockExpr *Exp,
+            const llvm::SmallVector<BlockDeclRefExpr *, 8> &InnerBlockDeclRefs);
+
+    void QuoteDoublequotes(std::string &From, std::string &To) {
+      for (unsigned i = 0; i < From.length(); i++) {
+        if (From[i] == '"')
+          To += "\\\"";
+        else
+          To += From[i];
+      }
+    }
+  };
+
+  // Helper function: create a CStyleCastExpr with trivial type source info.
+  CStyleCastExpr* NoTypeInfoCStyleCastExpr(ASTContext *Ctx, QualType Ty,
+                                           CastExpr::CastKind Kind, Expr *E) {
+    TypeSourceInfo *TInfo = Ctx->getTrivialTypeSourceInfo(Ty, SourceLocation());
+    return new (Ctx) CStyleCastExpr(Ty, Kind, E, CXXBaseSpecifierArray(), TInfo,
+                                    SourceLocation(), SourceLocation());
+  }
+}
+
+void RewriteObjC::RewriteBlocksInFunctionProtoType(QualType funcType,
+                                                   NamedDecl *D) {
+  if (FunctionProtoType *fproto = dyn_cast<FunctionProtoType>(funcType)) {
+    for (FunctionProtoType::arg_type_iterator I = fproto->arg_type_begin(),
+         E = fproto->arg_type_end(); I && (I != E); ++I)
+      if (isTopLevelBlockPointerType(*I)) {
+        // All the args are checked/rewritten. Don't call twice!
+        RewriteBlockPointerDecl(D);
+        break;
+      }
+  }
+}
+
+void RewriteObjC::CheckFunctionPointerDecl(QualType funcType, NamedDecl *ND) {
+  const PointerType *PT = funcType->getAs<PointerType>();
+  if (PT && PointerTypeTakesAnyBlockArguments(funcType))
+    RewriteBlocksInFunctionProtoType(PT->getPointeeType(), ND);
+}
+
+static bool IsHeaderFile(const std::string &Filename) {
+  std::string::size_type DotPos = Filename.rfind('.');
+
+  if (DotPos == std::string::npos) {
+    // no file extension
+    return false;
+  }
+
+  std::string Ext = std::string(Filename.begin()+DotPos+1, Filename.end());
+  // C header: .h
+  // C++ header: .hh or .H;
+  return Ext == "h" || Ext == "hh" || Ext == "H";
+}
+
+RewriteObjC::RewriteObjC(std::string inFile, llvm::raw_ostream* OS,
+                         Diagnostic &D, const LangOptions &LOpts,
+                         bool silenceMacroWarn)
+      : Diags(D), LangOpts(LOpts), InFileName(inFile), OutFile(OS),
+        SilenceRewriteMacroWarning(silenceMacroWarn) {
+  IsHeader = IsHeaderFile(inFile);
+  RewriteFailedDiag = Diags.getCustomDiagID(Diagnostic::Warning,
+               "rewriting sub-expression within a macro (may not be correct)");
+  TryFinallyContainsReturnDiag = Diags.getCustomDiagID(Diagnostic::Warning,
+               "rewriter doesn't support user-specified control flow semantics "
+               "for @try/@finally (code may not execute properly)");
+}
+
+ASTConsumer *clang::CreateObjCRewriter(const std::string& InFile,
+                                       llvm::raw_ostream* OS,
+                                       Diagnostic &Diags,
+                                       const LangOptions &LOpts,
+                                       bool SilenceRewriteMacroWarning) {
+  return new RewriteObjC(InFile, OS, Diags, LOpts, SilenceRewriteMacroWarning);
+}
+
+void RewriteObjC::Initialize(ASTContext &context) {
+  Context = &context;
+  SM = &Context->getSourceManager();
+  TUDecl = Context->getTranslationUnitDecl();
+  MsgSendFunctionDecl = 0;
+  MsgSendSuperFunctionDecl = 0;
+  MsgSendStretFunctionDecl = 0;
+  MsgSendSuperStretFunctionDecl = 0;
+  MsgSendFpretFunctionDecl = 0;
+  GetClassFunctionDecl = 0;
+  GetMetaClassFunctionDecl = 0;
+  GetSuperClassFunctionDecl = 0;
+  SelGetUidFunctionDecl = 0;
+  CFStringFunctionDecl = 0;
+  ConstantStringClassReference = 0;
+  NSStringRecord = 0;
+  CurMethodDef = 0;
+  CurFunctionDef = 0;
+  CurFunctionDeclToDeclareForBlock = 0;
+  GlobalVarDecl = 0;
+  SuperStructDecl = 0;
+  ProtocolTypeDecl = 0;
+  ConstantStringDecl = 0;
+  BcLabelCount = 0;
+  SuperContructorFunctionDecl = 0;
+  NumObjCStringLiterals = 0;
+  PropParentMap = 0;
+  CurrentBody = 0;
+  DisableReplaceStmt = false;
+  objc_impl_method = false;
+
+  // Get the ID and start/end of the main file.
+  MainFileID = SM->getMainFileID();
+  const llvm::MemoryBuffer *MainBuf = SM->getBuffer(MainFileID);
+  MainFileStart = MainBuf->getBufferStart();
+  MainFileEnd = MainBuf->getBufferEnd();
+
+  Rewrite.setSourceMgr(Context->getSourceManager(), Context->getLangOptions());
+
+  // declaring objc_selector outside the parameter list removes a silly
+  // scope related warning...
+  if (IsHeader)
+    Preamble = "#pragma once\n";
+  Preamble += "struct objc_selector; struct objc_class;\n";
+  Preamble += "struct __rw_objc_super { struct objc_object *object; ";
+  Preamble += "struct objc_object *superClass; ";
+  if (LangOpts.Microsoft) {
+    // Add a constructor for creating temporary objects.
+    Preamble += "__rw_objc_super(struct objc_object *o, struct objc_object *s) "
+                ": ";
+    Preamble += "object(o), superClass(s) {} ";
+  }
+  Preamble += "};\n";
+  Preamble += "#ifndef _REWRITER_typedef_Protocol\n";
+  Preamble += "typedef struct objc_object Protocol;\n";
+  Preamble += "#define _REWRITER_typedef_Protocol\n";
+  Preamble += "#endif\n";
+  if (LangOpts.Microsoft) {
+    Preamble += "#define __OBJC_RW_DLLIMPORT extern \"C\" __declspec(dllimport)\n";
+    Preamble += "#define __OBJC_RW_STATICIMPORT extern \"C\"\n";
+  } else
+  Preamble += "#define __OBJC_RW_DLLIMPORT extern\n";
+  Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_msgSend";
+  Preamble += "(struct objc_object *, struct objc_selector *, ...);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_msgSendSuper";
+  Preamble += "(struct objc_super *, struct objc_selector *, ...);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_msgSend_stret";
+  Preamble += "(struct objc_object *, struct objc_selector *, ...);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_msgSendSuper_stret";
+  Preamble += "(struct objc_super *, struct objc_selector *, ...);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT double objc_msgSend_fpret";
+  Preamble += "(struct objc_object *, struct objc_selector *, ...);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_getClass";
+  Preamble += "(const char *);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT struct objc_class *class_getSuperclass";
+  Preamble += "(struct objc_class *);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_getMetaClass";
+  Preamble += "(const char *);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT void objc_exception_throw(struct objc_object *);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT void objc_exception_try_enter(void *);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT void objc_exception_try_exit(void *);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_exception_extract(void *);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT int objc_exception_match";
+  Preamble += "(struct objc_class *, struct objc_object *);\n";
+  // @synchronized hooks.
+  Preamble += "__OBJC_RW_DLLIMPORT void objc_sync_enter(struct objc_object *);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT void objc_sync_exit(struct objc_object *);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT Protocol *objc_getProtocol(const char *);\n";
+  Preamble += "#ifndef __FASTENUMERATIONSTATE\n";
+  Preamble += "struct __objcFastEnumerationState {\n\t";
+  Preamble += "unsigned long state;\n\t";
+  Preamble += "void **itemsPtr;\n\t";
+  Preamble += "unsigned long *mutationsPtr;\n\t";
+  Preamble += "unsigned long extra[5];\n};\n";
+  Preamble += "__OBJC_RW_DLLIMPORT void objc_enumerationMutation(struct objc_object *);\n";
+  Preamble += "#define __FASTENUMERATIONSTATE\n";
+  Preamble += "#endif\n";
+  Preamble += "#ifndef __NSCONSTANTSTRINGIMPL\n";
+  Preamble += "struct __NSConstantStringImpl {\n";
+  Preamble += "  int *isa;\n";
+  Preamble += "  int flags;\n";
+  Preamble += "  char *str;\n";
+  Preamble += "  long length;\n";
+  Preamble += "};\n";
+  Preamble += "#ifdef CF_EXPORT_CONSTANT_STRING\n";
+  Preamble += "extern \"C\" __declspec(dllexport) int __CFConstantStringClassReference[];\n";
+  Preamble += "#else\n";
+  Preamble += "__OBJC_RW_DLLIMPORT int __CFConstantStringClassReference[];\n";
+  Preamble += "#endif\n";
+  Preamble += "#define __NSCONSTANTSTRINGIMPL\n";
+  Preamble += "#endif\n";
+  // Blocks preamble.
+  Preamble += "#ifndef BLOCK_IMPL\n";
+  Preamble += "#define BLOCK_IMPL\n";
+  Preamble += "struct __block_impl {\n";
+  Preamble += "  void *isa;\n";
+  Preamble += "  int Flags;\n";
+  Preamble += "  int Reserved;\n";
+  Preamble += "  void *FuncPtr;\n";
+  Preamble += "};\n";
+  Preamble += "// Runtime copy/destroy helper functions (from Block_private.h)\n";
+  Preamble += "#ifdef __OBJC_EXPORT_BLOCKS\n";
+  Preamble += "extern \"C\" __declspec(dllexport) "
+              "void _Block_object_assign(void *, const void *, const int);\n";
+  Preamble += "extern \"C\" __declspec(dllexport) void _Block_object_dispose(const void *, const int);\n";
+  Preamble += "extern \"C\" __declspec(dllexport) void *_NSConcreteGlobalBlock[32];\n";
+  Preamble += "extern \"C\" __declspec(dllexport) void *_NSConcreteStackBlock[32];\n";
+  Preamble += "#else\n";
+  Preamble += "__OBJC_RW_DLLIMPORT void _Block_object_assign(void *, const void *, const int);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT void _Block_object_dispose(const void *, const int);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT void *_NSConcreteGlobalBlock[32];\n";
+  Preamble += "__OBJC_RW_DLLIMPORT void *_NSConcreteStackBlock[32];\n";
+  Preamble += "#endif\n";
+  Preamble += "#endif\n";
+  if (LangOpts.Microsoft) {
+    Preamble += "#undef __OBJC_RW_DLLIMPORT\n";
+    Preamble += "#undef __OBJC_RW_STATICIMPORT\n";
+    Preamble += "#ifndef KEEP_ATTRIBUTES\n";  // We use this for clang tests.
+    Preamble += "#define __attribute__(X)\n";
+    Preamble += "#endif\n";
+    Preamble += "#define __weak\n";
+  }
+  else {
+    Preamble += "#define __block\n";
+    Preamble += "#define __weak\n";
+  }
+  // NOTE! Windows uses LLP64 for 64bit mode. So, cast pointer to long long
+  // as this avoids warning in any 64bit/32bit compilation model.
+  Preamble += "\n#define __OFFSETOFIVAR__(TYPE, MEMBER) ((long long) &((TYPE *)0)->MEMBER)\n";
+}
+
+
+//===----------------------------------------------------------------------===//
+// Top Level Driver Code
+//===----------------------------------------------------------------------===//
+
+void RewriteObjC::HandleTopLevelSingleDecl(Decl *D) {
+  if (Diags.hasErrorOccurred())
+    return;
+
+  // Two cases: either the decl could be in the main file, or it could be in a
+  // #included file.  If the former, rewrite it now.  If the later, check to see
+  // if we rewrote the #include/#import.
+  SourceLocation Loc = D->getLocation();
+  Loc = SM->getInstantiationLoc(Loc);
+
+  // If this is for a builtin, ignore it.
+  if (Loc.isInvalid()) return;
+
+  // Look for built-in declarations that we need to refer during the rewrite.
+  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+    RewriteFunctionDecl(FD);
+  } else if (VarDecl *FVD = dyn_cast<VarDecl>(D)) {
+    // declared in <Foundation/NSString.h>
+    if (strcmp(FVD->getNameAsCString(), "_NSConstantStringClassReference") == 0) {
+      ConstantStringClassReference = FVD;
+      return;
+    }
+  } else if (ObjCInterfaceDecl *MD = dyn_cast<ObjCInterfaceDecl>(D)) {
+    RewriteInterfaceDecl(MD);
+  } else if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(D)) {
+    RewriteCategoryDecl(CD);
+  } else if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D)) {
+    RewriteProtocolDecl(PD);
+  } else if (ObjCForwardProtocolDecl *FP =
+             dyn_cast<ObjCForwardProtocolDecl>(D)){
+    RewriteForwardProtocolDecl(FP);
+  } else if (LinkageSpecDecl *LSD = dyn_cast<LinkageSpecDecl>(D)) {
+    // Recurse into linkage specifications
+    for (DeclContext::decl_iterator DI = LSD->decls_begin(),
+                                 DIEnd = LSD->decls_end();
+         DI != DIEnd; ++DI)
+      HandleTopLevelSingleDecl(*DI);
+  }
+  // If we have a decl in the main file, see if we should rewrite it.
+  if (SM->isFromMainFile(Loc))
+    return HandleDeclInMainFile(D);
+}
+
+//===----------------------------------------------------------------------===//
+// Syntactic (non-AST) Rewriting Code
+//===----------------------------------------------------------------------===//
+
+void RewriteObjC::RewriteInclude() {
+  SourceLocation LocStart = SM->getLocForStartOfFile(MainFileID);
+  llvm::StringRef MainBuf = SM->getBufferData(MainFileID);
+  const char *MainBufStart = MainBuf.begin();
+  const char *MainBufEnd = MainBuf.end();
+  size_t ImportLen = strlen("import");
+
+  // Loop over the whole file, looking for includes.
+  for (const char *BufPtr = MainBufStart; BufPtr < MainBufEnd; ++BufPtr) {
+    if (*BufPtr == '#') {
+      if (++BufPtr == MainBufEnd)
+        return;
+      while (*BufPtr == ' ' || *BufPtr == '\t')
+        if (++BufPtr == MainBufEnd)
+          return;
+      if (!strncmp(BufPtr, "import", ImportLen)) {
+        // replace import with include
+        SourceLocation ImportLoc =
+          LocStart.getFileLocWithOffset(BufPtr-MainBufStart);
+        ReplaceText(ImportLoc, ImportLen, "include");
+        BufPtr += ImportLen;
+      }
+    }
+  }
+}
+
+void RewriteObjC::RewriteTabs() {
+  llvm::StringRef MainBuf = SM->getBufferData(MainFileID);
+  const char *MainBufStart = MainBuf.begin();
+  const char *MainBufEnd = MainBuf.end();
+
+  // Loop over the whole file, looking for tabs.
+  for (const char *BufPtr = MainBufStart; BufPtr != MainBufEnd; ++BufPtr) {
+    if (*BufPtr != '\t')
+      continue;
+
+    // Okay, we found a tab.  This tab will turn into at least one character,
+    // but it depends on which 'virtual column' it is in.  Compute that now.
+    unsigned VCol = 0;
+    while (BufPtr-VCol != MainBufStart && BufPtr[-VCol-1] != '\t' &&
+           BufPtr[-VCol-1] != '\n' && BufPtr[-VCol-1] != '\r')
+      ++VCol;
+
+    // Okay, now that we know the virtual column, we know how many spaces to
+    // insert.  We assume 8-character tab-stops.
+    unsigned Spaces = 8-(VCol & 7);
+
+    // Get the location of the tab.
+    SourceLocation TabLoc = SM->getLocForStartOfFile(MainFileID);
+    TabLoc = TabLoc.getFileLocWithOffset(BufPtr-MainBufStart);
+
+    // Rewrite the single tab character into a sequence of spaces.
+    ReplaceText(TabLoc, 1, llvm::StringRef("        ", Spaces));
+  }
+}
+
+static std::string getIvarAccessString(ObjCInterfaceDecl *ClassDecl,
+                                       ObjCIvarDecl *OID) {
+  std::string S;
+  S = "((struct ";
+  S += ClassDecl->getIdentifier()->getName();
+  S += "_IMPL *)self)->";
+  S += OID->getName();
+  return S;
+}
+
+void RewriteObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl *PID,
+                                          ObjCImplementationDecl *IMD,
+                                          ObjCCategoryImplDecl *CID) {
+  static bool objcGetPropertyDefined = false;
+  static bool objcSetPropertyDefined = false;
+  SourceLocation startLoc = PID->getLocStart();
+  InsertText(startLoc, "// ");
+  const char *startBuf = SM->getCharacterData(startLoc);
+  assert((*startBuf == '@') && "bogus @synthesize location");
+  const char *semiBuf = strchr(startBuf, ';');
+  assert((*semiBuf == ';') && "@synthesize: can't find ';'");
+  SourceLocation onePastSemiLoc =
+    startLoc.getFileLocWithOffset(semiBuf-startBuf+1);
+
+  if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
+    return; // FIXME: is this correct?
+
+  // Generate the 'getter' function.
+  ObjCPropertyDecl *PD = PID->getPropertyDecl();
+  ObjCInterfaceDecl *ClassDecl = PD->getGetterMethodDecl()->getClassInterface();
+  ObjCIvarDecl *OID = PID->getPropertyIvarDecl();
+
+  if (!OID)
+    return;
+  unsigned Attributes = PD->getPropertyAttributes();
+  bool GenGetProperty = !(Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic) &&
+                         (Attributes & (ObjCPropertyDecl::OBJC_PR_retain | 
+                                        ObjCPropertyDecl::OBJC_PR_copy));
+  std::string Getr;
+  if (GenGetProperty && !objcGetPropertyDefined) {
+    objcGetPropertyDefined = true;
+    // FIXME. Is this attribute correct in all cases?
+    Getr = "\nextern \"C\" __declspec(dllimport) "
+           "id objc_getProperty(id, SEL, long, bool);\n";
+  }
+  RewriteObjCMethodDecl(PD->getGetterMethodDecl(), Getr);
+  Getr += "{ ";
+  // Synthesize an explicit cast to gain access to the ivar.
+  // See objc-act.c:objc_synthesize_new_getter() for details.
+  if (GenGetProperty) {
+    // return objc_getProperty(self, _cmd, offsetof(ClassDecl, OID), 1)
+    Getr += "typedef ";
+    const FunctionType *FPRetType = 0;
+    RewriteTypeIntoString(PD->getGetterMethodDecl()->getResultType(), Getr, 
+                          FPRetType);
+    Getr += " _TYPE";
+    if (FPRetType) {
+      Getr += ")"; // close the precedence "scope" for "*".
+      
+      // Now, emit the argument types (if any).
+      if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(FPRetType)) {
+        Getr += "(";
+        for (unsigned i = 0, e = FT->getNumArgs(); i != e; ++i) {
+          if (i) Getr += ", ";
+          std::string ParamStr = FT->getArgType(i).getAsString();
+          Getr += ParamStr;
+        }
+        if (FT->isVariadic()) {
+          if (FT->getNumArgs()) Getr += ", ";
+          Getr += "...";
+        }
+        Getr += ")";
+      } else
+        Getr += "()";
+    }
+    Getr += ";\n";
+    Getr += "return (_TYPE)";
+    Getr += "objc_getProperty(self, _cmd, ";
+    SynthesizeIvarOffsetComputation(ClassDecl, OID, Getr);
+    Getr += ", 1)";
+  }
+  else
+    Getr += "return " + getIvarAccessString(ClassDecl, OID);
+  Getr += "; }";
+  InsertText(onePastSemiLoc, Getr);
+  if (PD->isReadOnly())
+    return;
+
+  // Generate the 'setter' function.
+  std::string Setr;
+  bool GenSetProperty = Attributes & (ObjCPropertyDecl::OBJC_PR_retain | 
+                                      ObjCPropertyDecl::OBJC_PR_copy);
+  if (GenSetProperty && !objcSetPropertyDefined) {
+    objcSetPropertyDefined = true;
+    // FIXME. Is this attribute correct in all cases?
+    Setr = "\nextern \"C\" __declspec(dllimport) "
+    "void objc_setProperty (id, SEL, long, id, bool, bool);\n";
+  }
+  
+  RewriteObjCMethodDecl(PD->getSetterMethodDecl(), Setr);
+  Setr += "{ ";
+  // Synthesize an explicit cast to initialize the ivar.
+  // See objc-act.c:objc_synthesize_new_setter() for details.
+  if (GenSetProperty) {
+    Setr += "objc_setProperty (self, _cmd, ";
+    SynthesizeIvarOffsetComputation(ClassDecl, OID, Setr);
+    Setr += ", (id)";
+    Setr += PD->getNameAsCString();
+    Setr += ", ";
+    if (Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic)
+      Setr += "0, ";
+    else
+      Setr += "1, ";
+    if (Attributes & ObjCPropertyDecl::OBJC_PR_copy)
+      Setr += "1)";
+    else
+      Setr += "0)";
+  }
+  else {
+    Setr += getIvarAccessString(ClassDecl, OID) + " = ";
+    Setr += PD->getNameAsCString();
+  }
+  Setr += "; }";
+  InsertText(onePastSemiLoc, Setr);
+}
+
+void RewriteObjC::RewriteForwardClassDecl(ObjCClassDecl *ClassDecl) {
+  // Get the start location and compute the semi location.
+  SourceLocation startLoc = ClassDecl->getLocation();
+  const char *startBuf = SM->getCharacterData(startLoc);
+  const char *semiPtr = strchr(startBuf, ';');
+
+  // Translate to typedef's that forward reference structs with the same name
+  // as the class. As a convenience, we include the original declaration
+  // as a comment.
+  std::string typedefString;
+  typedefString += "// @class ";
+  for (ObjCClassDecl::iterator I = ClassDecl->begin(), E = ClassDecl->end();
+       I != E; ++I) {
+    ObjCInterfaceDecl *ForwardDecl = I->getInterface();
+    typedefString += ForwardDecl->getNameAsString();
+    if (I+1 != E)
+      typedefString += ", ";
+    else
+      typedefString += ";\n";
+  }
+  
+  for (ObjCClassDecl::iterator I = ClassDecl->begin(), E = ClassDecl->end();
+       I != E; ++I) {
+    ObjCInterfaceDecl *ForwardDecl = I->getInterface();
+    typedefString += "#ifndef _REWRITER_typedef_";
+    typedefString += ForwardDecl->getNameAsString();
+    typedefString += "\n";
+    typedefString += "#define _REWRITER_typedef_";
+    typedefString += ForwardDecl->getNameAsString();
+    typedefString += "\n";
+    typedefString += "typedef struct objc_object ";
+    typedefString += ForwardDecl->getNameAsString();
+    typedefString += ";\n#endif\n";
+  }
+
+  // Replace the @class with typedefs corresponding to the classes.
+  ReplaceText(startLoc, semiPtr-startBuf+1, typedefString);
+}
+
+void RewriteObjC::RewriteMethodDeclaration(ObjCMethodDecl *Method) {
+  // When method is a synthesized one, such as a getter/setter there is
+  // nothing to rewrite.
+  if (Method->isSynthesized())
+    return;
+  SourceLocation LocStart = Method->getLocStart();
+  SourceLocation LocEnd = Method->getLocEnd();
+
+  if (SM->getInstantiationLineNumber(LocEnd) >
+      SM->getInstantiationLineNumber(LocStart)) {
+    InsertText(LocStart, "#if 0\n");
+    ReplaceText(LocEnd, 1, ";\n#endif\n");
+  } else {
+    InsertText(LocStart, "// ");
+  }
+}
+
+void RewriteObjC::RewriteProperty(ObjCPropertyDecl *prop) {
+  SourceLocation Loc = prop->getAtLoc();
+
+  ReplaceText(Loc, 0, "// ");
+  // FIXME: handle properties that are declared across multiple lines.
+}
+
+void RewriteObjC::RewriteCategoryDecl(ObjCCategoryDecl *CatDecl) {
+  SourceLocation LocStart = CatDecl->getLocStart();
+
+  // FIXME: handle category headers that are declared across multiple lines.
+  ReplaceText(LocStart, 0, "// ");
+
+  for (ObjCCategoryDecl::prop_iterator I = CatDecl->prop_begin(),
+       E = CatDecl->prop_end(); I != E; ++I)
+    RewriteProperty(*I);
+  
+  for (ObjCCategoryDecl::instmeth_iterator
+         I = CatDecl->instmeth_begin(), E = CatDecl->instmeth_end();
+       I != E; ++I)
+    RewriteMethodDeclaration(*I);
+  for (ObjCCategoryDecl::classmeth_iterator
+         I = CatDecl->classmeth_begin(), E = CatDecl->classmeth_end();
+       I != E; ++I)
+    RewriteMethodDeclaration(*I);
+
+  // Lastly, comment out the @end.
+  ReplaceText(CatDecl->getAtEndRange().getBegin(), 0, "// ");
+}
+
+void RewriteObjC::RewriteProtocolDecl(ObjCProtocolDecl *PDecl) {
+  SourceLocation LocStart = PDecl->getLocStart();
+
+  // FIXME: handle protocol headers that are declared across multiple lines.
+  ReplaceText(LocStart, 0, "// ");
+
+  for (ObjCProtocolDecl::instmeth_iterator
+         I = PDecl->instmeth_begin(), E = PDecl->instmeth_end();
+       I != E; ++I)
+    RewriteMethodDeclaration(*I);
+  for (ObjCProtocolDecl::classmeth_iterator
+         I = PDecl->classmeth_begin(), E = PDecl->classmeth_end();
+       I != E; ++I)
+    RewriteMethodDeclaration(*I);
+
+  // Lastly, comment out the @end.
+  SourceLocation LocEnd = PDecl->getAtEndRange().getBegin();
+  ReplaceText(LocEnd, 0, "// ");
+
+  // Must comment out @optional/@required
+  const char *startBuf = SM->getCharacterData(LocStart);
+  const char *endBuf = SM->getCharacterData(LocEnd);
+  for (const char *p = startBuf; p < endBuf; p++) {
+    if (*p == '@' && !strncmp(p+1, "optional", strlen("optional"))) {
+      SourceLocation OptionalLoc = LocStart.getFileLocWithOffset(p-startBuf);
+      ReplaceText(OptionalLoc, strlen("@optional"), "/* @optional */");
+
+    }
+    else if (*p == '@' && !strncmp(p+1, "required", strlen("required"))) {
+      SourceLocation OptionalLoc = LocStart.getFileLocWithOffset(p-startBuf);
+      ReplaceText(OptionalLoc, strlen("@required"), "/* @required */");
+
+    }
+  }
+}
+
+void RewriteObjC::RewriteForwardProtocolDecl(ObjCForwardProtocolDecl *PDecl) {
+  SourceLocation LocStart = PDecl->getLocation();
+  if (LocStart.isInvalid())
+    assert(false && "Invalid SourceLocation");
+  // FIXME: handle forward protocol that are declared across multiple lines.
+  ReplaceText(LocStart, 0, "// ");
+}
+
+void RewriteObjC::RewriteTypeIntoString(QualType T, std::string &ResultStr,
+                                        const FunctionType *&FPRetType) {
+  if (T->isObjCQualifiedIdType())
+    ResultStr += "id";
+  else if (T->isFunctionPointerType() ||
+           T->isBlockPointerType()) {
+    // needs special handling, since pointer-to-functions have special
+    // syntax (where a decaration models use).
+    QualType retType = T;
+    QualType PointeeTy;
+    if (const PointerType* PT = retType->getAs<PointerType>())
+      PointeeTy = PT->getPointeeType();
+    else if (const BlockPointerType *BPT = retType->getAs<BlockPointerType>())
+      PointeeTy = BPT->getPointeeType();
+    if ((FPRetType = PointeeTy->getAs<FunctionType>())) {
+      ResultStr += FPRetType->getResultType().getAsString();
+      ResultStr += "(*";
+    }
+  } else
+    ResultStr += T.getAsString();
+}
+
+void RewriteObjC::RewriteObjCMethodDecl(ObjCMethodDecl *OMD,
+                                        std::string &ResultStr) {
+  //fprintf(stderr,"In RewriteObjCMethodDecl\n");
+  const FunctionType *FPRetType = 0;
+  ResultStr += "\nstatic ";
+  RewriteTypeIntoString(OMD->getResultType(), ResultStr, FPRetType);
+  ResultStr += " ";
+
+  // Unique method name
+  std::string NameStr;
+
+  if (OMD->isInstanceMethod())
+    NameStr += "_I_";
+  else
+    NameStr += "_C_";
+
+  NameStr += OMD->getClassInterface()->getNameAsString();
+  NameStr += "_";
+
+  if (ObjCCategoryImplDecl *CID =
+      dyn_cast<ObjCCategoryImplDecl>(OMD->getDeclContext())) {
+    NameStr += CID->getNameAsString();
+    NameStr += "_";
+  }
+  // Append selector names, replacing ':' with '_'
+  {
+    std::string selString = OMD->getSelector().getAsString();
+    int len = selString.size();
+    for (int i = 0; i < len; i++)
+      if (selString[i] == ':')
+        selString[i] = '_';
+    NameStr += selString;
+  }
+  // Remember this name for metadata emission
+  MethodInternalNames[OMD] = NameStr;
+  ResultStr += NameStr;
+
+  // Rewrite arguments
+  ResultStr += "(";
+
+  // invisible arguments
+  if (OMD->isInstanceMethod()) {
+    QualType selfTy = Context->getObjCInterfaceType(OMD->getClassInterface());
+    selfTy = Context->getPointerType(selfTy);
+    if (!LangOpts.Microsoft) {
+      if (ObjCSynthesizedStructs.count(OMD->getClassInterface()))
+        ResultStr += "struct ";
+    }
+    // When rewriting for Microsoft, explicitly omit the structure name.
+    ResultStr += OMD->getClassInterface()->getNameAsString();
+    ResultStr += " *";
+  }
+  else
+    ResultStr += Context->getObjCClassType().getAsString();
+
+  ResultStr += " self, ";
+  ResultStr += Context->getObjCSelType().getAsString();
+  ResultStr += " _cmd";
+
+  // Method arguments.
+  for (ObjCMethodDecl::param_iterator PI = OMD->param_begin(),
+       E = OMD->param_end(); PI != E; ++PI) {
+    ParmVarDecl *PDecl = *PI;
+    ResultStr += ", ";
+    if (PDecl->getType()->isObjCQualifiedIdType()) {
+      ResultStr += "id ";
+      ResultStr += PDecl->getNameAsString();
+    } else {
+      std::string Name = PDecl->getNameAsString();
+      if (isTopLevelBlockPointerType(PDecl->getType())) {
+        // Make sure we convert "t (^)(...)" to "t (*)(...)".
+        const BlockPointerType *BPT = PDecl->getType()->getAs<BlockPointerType>();
+        Context->getPointerType(BPT->getPointeeType()).getAsStringInternal(Name,
+                                                        Context->PrintingPolicy);
+      } else
+        PDecl->getType().getAsStringInternal(Name, Context->PrintingPolicy);
+      ResultStr += Name;
+    }
+  }
+  if (OMD->isVariadic())
+    ResultStr += ", ...";
+  ResultStr += ") ";
+
+  if (FPRetType) {
+    ResultStr += ")"; // close the precedence "scope" for "*".
+
+    // Now, emit the argument types (if any).
+    if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(FPRetType)) {
+      ResultStr += "(";
+      for (unsigned i = 0, e = FT->getNumArgs(); i != e; ++i) {
+        if (i) ResultStr += ", ";
+        std::string ParamStr = FT->getArgType(i).getAsString();
+        ResultStr += ParamStr;
+      }
+      if (FT->isVariadic()) {
+        if (FT->getNumArgs()) ResultStr += ", ";
+        ResultStr += "...";
+      }
+      ResultStr += ")";
+    } else {
+      ResultStr += "()";
+    }
+  }
+}
+void RewriteObjC::RewriteImplementationDecl(Decl *OID) {
+  ObjCImplementationDecl *IMD = dyn_cast<ObjCImplementationDecl>(OID);
+  ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(OID);
+
+  InsertText(IMD ? IMD->getLocStart() : CID->getLocStart(), "// ");
+
+  for (ObjCCategoryImplDecl::instmeth_iterator
+       I = IMD ? IMD->instmeth_begin() : CID->instmeth_begin(),
+       E = IMD ? IMD->instmeth_end() : CID->instmeth_end();
+       I != E; ++I) {
+    std::string ResultStr;
+    ObjCMethodDecl *OMD = *I;
+    RewriteObjCMethodDecl(OMD, ResultStr);
+    SourceLocation LocStart = OMD->getLocStart();
+    SourceLocation LocEnd = OMD->getCompoundBody()->getLocStart();
+
+    const char *startBuf = SM->getCharacterData(LocStart);
+    const char *endBuf = SM->getCharacterData(LocEnd);
+    ReplaceText(LocStart, endBuf-startBuf, ResultStr);
+  }
+
+  for (ObjCCategoryImplDecl::classmeth_iterator
+       I = IMD ? IMD->classmeth_begin() : CID->classmeth_begin(),
+       E = IMD ? IMD->classmeth_end() : CID->classmeth_end();
+       I != E; ++I) {
+    std::string ResultStr;
+    ObjCMethodDecl *OMD = *I;
+    RewriteObjCMethodDecl(OMD, ResultStr);
+    SourceLocation LocStart = OMD->getLocStart();
+    SourceLocation LocEnd = OMD->getCompoundBody()->getLocStart();
+
+    const char *startBuf = SM->getCharacterData(LocStart);
+    const char *endBuf = SM->getCharacterData(LocEnd);
+    ReplaceText(LocStart, endBuf-startBuf, ResultStr);
+  }
+  for (ObjCCategoryImplDecl::propimpl_iterator
+       I = IMD ? IMD->propimpl_begin() : CID->propimpl_begin(),
+       E = IMD ? IMD->propimpl_end() : CID->propimpl_end();
+       I != E; ++I) {
+    RewritePropertyImplDecl(*I, IMD, CID);
+  }
+
+  InsertText(IMD ? IMD->getLocEnd() : CID->getLocEnd(), "// ");
+}
+
+void RewriteObjC::RewriteInterfaceDecl(ObjCInterfaceDecl *ClassDecl) {
+  std::string ResultStr;
+  if (!ObjCForwardDecls.count(ClassDecl)) {
+    // we haven't seen a forward decl - generate a typedef.
+    ResultStr = "#ifndef _REWRITER_typedef_";
+    ResultStr += ClassDecl->getNameAsString();
+    ResultStr += "\n";
+    ResultStr += "#define _REWRITER_typedef_";
+    ResultStr += ClassDecl->getNameAsString();
+    ResultStr += "\n";
+    ResultStr += "typedef struct objc_object ";
+    ResultStr += ClassDecl->getNameAsString();
+    ResultStr += ";\n#endif\n";
+    // Mark this typedef as having been generated.
+    ObjCForwardDecls.insert(ClassDecl);
+  }
+  SynthesizeObjCInternalStruct(ClassDecl, ResultStr);
+
+  for (ObjCInterfaceDecl::prop_iterator I = ClassDecl->prop_begin(),
+         E = ClassDecl->prop_end(); I != E; ++I)
+    RewriteProperty(*I);
+  for (ObjCInterfaceDecl::instmeth_iterator
+         I = ClassDecl->instmeth_begin(), E = ClassDecl->instmeth_end();
+       I != E; ++I)
+    RewriteMethodDeclaration(*I);
+  for (ObjCInterfaceDecl::classmeth_iterator
+         I = ClassDecl->classmeth_begin(), E = ClassDecl->classmeth_end();
+       I != E; ++I)
+    RewriteMethodDeclaration(*I);
+
+  // Lastly, comment out the @end.
+  ReplaceText(ClassDecl->getAtEndRange().getBegin(), 0, "// ");
+}
+
+Stmt *RewriteObjC::RewritePropertySetter(BinaryOperator *BinOp, Expr *newStmt,
+                                         SourceRange SrcRange) {
+  // Synthesize a ObjCMessageExpr from a ObjCPropertyRefExpr.
+  // This allows us to reuse all the fun and games in SynthMessageExpr().
+  ObjCPropertyRefExpr *PropRefExpr = dyn_cast<ObjCPropertyRefExpr>(BinOp->getLHS());
+  ObjCMessageExpr *MsgExpr;
+  ObjCPropertyDecl *PDecl = PropRefExpr->getProperty();
+  llvm::SmallVector<Expr *, 1> ExprVec;
+  ExprVec.push_back(newStmt);
+
+  Stmt *Receiver = PropRefExpr->getBase();
+  ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(Receiver);
+  if (PRE && PropGetters[PRE]) {
+    // This allows us to handle chain/nested property getters.
+    Receiver = PropGetters[PRE];
+  }
+  if (isa<ObjCSuperExpr>(Receiver))
+    MsgExpr = ObjCMessageExpr::Create(*Context, 
+                                      PDecl->getType().getNonReferenceType(),
+                                      /*FIXME?*/SourceLocation(),
+                                      Receiver->getLocStart(),
+                                      /*IsInstanceSuper=*/true,
+                                      cast<Expr>(Receiver)->getType(),
+                                      PDecl->getSetterName(),
+                                      PDecl->getSetterMethodDecl(),
+                                      &ExprVec[0], 1,
+                                      /*FIXME:*/SourceLocation());
+  else
+    MsgExpr = ObjCMessageExpr::Create(*Context, 
+                                      PDecl->getType().getNonReferenceType(),
+                                      /*FIXME: */SourceLocation(),
+                                      cast<Expr>(Receiver),
+                                      PDecl->getSetterName(),
+                                      PDecl->getSetterMethodDecl(),
+                                      &ExprVec[0], 1,
+                                      /*FIXME:*/SourceLocation());
+  Stmt *ReplacingStmt = SynthMessageExpr(MsgExpr);
+
+  // Now do the actual rewrite.
+  ReplaceStmtWithRange(BinOp, ReplacingStmt, SrcRange);
+  //delete BinOp;
+  // NOTE: We don't want to call MsgExpr->Destroy(), as it holds references
+  // to things that stay around.
+  Context->Deallocate(MsgExpr);
+  return ReplacingStmt;
+}
+
+Stmt *RewriteObjC::RewritePropertyGetter(ObjCPropertyRefExpr *PropRefExpr) {
+  // Synthesize a ObjCMessageExpr from a ObjCPropertyRefExpr.
+  // This allows us to reuse all the fun and games in SynthMessageExpr().
+  ObjCMessageExpr *MsgExpr;
+  ObjCPropertyDecl *PDecl = PropRefExpr->getProperty();
+
+  Stmt *Receiver = PropRefExpr->getBase();
+
+  ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(Receiver);
+  if (PRE && PropGetters[PRE]) {
+    // This allows us to handle chain/nested property getters.
+    Receiver = PropGetters[PRE];
+  }
+
+  if (isa<ObjCSuperExpr>(Receiver))
+    MsgExpr = ObjCMessageExpr::Create(*Context, 
+                                      PDecl->getType().getNonReferenceType(),
+                                      /*FIXME:*/SourceLocation(),
+                                      Receiver->getLocStart(),
+                                      /*IsInstanceSuper=*/true,
+                                      cast<Expr>(Receiver)->getType(),
+                                      PDecl->getGetterName(), 
+                                      PDecl->getGetterMethodDecl(),
+                                      0, 0, 
+                                      /*FIXME:*/SourceLocation());
+  else
+    MsgExpr = ObjCMessageExpr::Create(*Context, 
+                                      PDecl->getType().getNonReferenceType(),
+                                      /*FIXME:*/SourceLocation(),
+                                      cast<Expr>(Receiver),
+                                      PDecl->getGetterName(), 
+                                      PDecl->getGetterMethodDecl(),
+                                      0, 0, 
+                                      /*FIXME:*/SourceLocation());
+
+  Stmt *ReplacingStmt = SynthMessageExpr(MsgExpr);
+
+  if (!PropParentMap)
+    PropParentMap = new ParentMap(CurrentBody);
+
+  Stmt *Parent = PropParentMap->getParent(PropRefExpr);
+  if (Parent && isa<ObjCPropertyRefExpr>(Parent)) {
+    // We stash away the ReplacingStmt since actually doing the
+    // replacement/rewrite won't work for nested getters (e.g. obj.p.i)
+    PropGetters[PropRefExpr] = ReplacingStmt;
+    // NOTE: We don't want to call MsgExpr->Destroy(), as it holds references
+    // to things that stay around.
+    Context->Deallocate(MsgExpr);
+    return PropRefExpr; // return the original...
+  } else {
+    ReplaceStmt(PropRefExpr, ReplacingStmt);
+    // delete PropRefExpr; elsewhere...
+    // NOTE: We don't want to call MsgExpr->Destroy(), as it holds references
+    // to things that stay around.
+    Context->Deallocate(MsgExpr);
+    return ReplacingStmt;
+  }
+}
+
+Stmt *RewriteObjC::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV,
+                                          SourceLocation OrigStart,
+                                          bool &replaced) {
+  ObjCIvarDecl *D = IV->getDecl();
+  const Expr *BaseExpr = IV->getBase();
+  if (CurMethodDef) {
+    if (BaseExpr->getType()->isObjCObjectPointerType()) {
+      ObjCInterfaceType *iFaceDecl =
+        dyn_cast<ObjCInterfaceType>(BaseExpr->getType()->getPointeeType());
+      assert(iFaceDecl && "RewriteObjCIvarRefExpr - iFaceDecl is null");
+      // lookup which class implements the instance variable.
+      ObjCInterfaceDecl *clsDeclared = 0;
+      iFaceDecl->getDecl()->lookupInstanceVariable(D->getIdentifier(),
+                                                   clsDeclared);
+      assert(clsDeclared && "RewriteObjCIvarRefExpr(): Can't find class");
+
+      // Synthesize an explicit cast to gain access to the ivar.
+      std::string RecName = clsDeclared->getIdentifier()->getName();
+      RecName += "_IMPL";
+      IdentifierInfo *II = &Context->Idents.get(RecName);
+      RecordDecl *RD = RecordDecl::Create(*Context, TagDecl::TK_struct, TUDecl,
+                                          SourceLocation(), II);
+      assert(RD && "RewriteObjCIvarRefExpr(): Can't find RecordDecl");
+      QualType castT = Context->getPointerType(Context->getTagDeclType(RD));
+      CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, castT,
+                                                    CastExpr::CK_Unknown,
+                                                    IV->getBase());
+      // Don't forget the parens to enforce the proper binding.
+      ParenExpr *PE = new (Context) ParenExpr(IV->getBase()->getLocStart(),
+                                               IV->getBase()->getLocEnd(),
+                                               castExpr);
+      replaced = true;
+      if (IV->isFreeIvar() &&
+          CurMethodDef->getClassInterface() == iFaceDecl->getDecl()) {
+        MemberExpr *ME = new (Context) MemberExpr(PE, true, D,
+                                                   IV->getLocation(),
+                                                   D->getType());
+        // delete IV; leak for now, see RewritePropertySetter() usage for more info.
+        return ME;
+      }
+      // Get the new text
+      // Cannot delete IV->getBase(), since PE points to it.
+      // Replace the old base with the cast. This is important when doing
+      // embedded rewrites. For example, [newInv->_container addObject:0].
+      IV->setBase(PE);
+      return IV;
+    }
+  } else { // we are outside a method.
+    assert(!IV->isFreeIvar() && "Cannot have a free standing ivar outside a method");
+
+    // Explicit ivar refs need to have a cast inserted.
+    // FIXME: consider sharing some of this code with the code above.
+    if (BaseExpr->getType()->isObjCObjectPointerType()) {
+      ObjCInterfaceType *iFaceDecl =
+        dyn_cast<ObjCInterfaceType>(BaseExpr->getType()->getPointeeType());
+      // lookup which class implements the instance variable.
+      ObjCInterfaceDecl *clsDeclared = 0;
+      iFaceDecl->getDecl()->lookupInstanceVariable(D->getIdentifier(),
+                                                   clsDeclared);
+      assert(clsDeclared && "RewriteObjCIvarRefExpr(): Can't find class");
+
+      // Synthesize an explicit cast to gain access to the ivar.
+      std::string RecName = clsDeclared->getIdentifier()->getName();
+      RecName += "_IMPL";
+      IdentifierInfo *II = &Context->Idents.get(RecName);
+      RecordDecl *RD = RecordDecl::Create(*Context, TagDecl::TK_struct, TUDecl,
+                                          SourceLocation(), II);
+      assert(RD && "RewriteObjCIvarRefExpr(): Can't find RecordDecl");
+      QualType castT = Context->getPointerType(Context->getTagDeclType(RD));
+      CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, castT,
+                                                    CastExpr::CK_Unknown,
+                                                    IV->getBase());
+      // Don't forget the parens to enforce the proper binding.
+      ParenExpr *PE = new (Context) ParenExpr(IV->getBase()->getLocStart(),
+                                    IV->getBase()->getLocEnd(), castExpr);
+      replaced = true;
+      // Cannot delete IV->getBase(), since PE points to it.
+      // Replace the old base with the cast. This is important when doing
+      // embedded rewrites. For example, [newInv->_container addObject:0].
+      IV->setBase(PE);
+      return IV;
+    }
+  }
+  return IV;
+}
+
+Stmt *RewriteObjC::RewriteObjCNestedIvarRefExpr(Stmt *S, bool &replaced) {
+  for (Stmt::child_iterator CI = S->child_begin(), E = S->child_end();
+       CI != E; ++CI) {
+    if (*CI) {
+      Stmt *newStmt = RewriteObjCNestedIvarRefExpr(*CI, replaced);
+      if (newStmt)
+        *CI = newStmt;
+    }
+  }
+  if (ObjCIvarRefExpr *IvarRefExpr = dyn_cast<ObjCIvarRefExpr>(S)) {
+    SourceRange OrigStmtRange = S->getSourceRange();
+    Stmt *newStmt = RewriteObjCIvarRefExpr(IvarRefExpr, OrigStmtRange.getBegin(),
+                                           replaced);
+    return newStmt;
+  } 
+  if (ObjCMessageExpr *MsgRefExpr = dyn_cast<ObjCMessageExpr>(S)) {
+    Stmt *newStmt = SynthMessageExpr(MsgRefExpr);
+    return newStmt;
+  }
+  return S;
+}
+
+/// SynthCountByEnumWithState - To print:
+/// ((unsigned int (*)
+///  (id, SEL, struct __objcFastEnumerationState *, id *, unsigned int))
+///  (void *)objc_msgSend)((id)l_collection,
+///                        sel_registerName(
+///                          "countByEnumeratingWithState:objects:count:"),
+///                        &enumState,
+///                        (id *)items, (unsigned int)16)
+///
+void RewriteObjC::SynthCountByEnumWithState(std::string &buf) {
+  buf += "((unsigned int (*) (id, SEL, struct __objcFastEnumerationState *, "
+  "id *, unsigned int))(void *)objc_msgSend)";
+  buf += "\n\t\t";
+  buf += "((id)l_collection,\n\t\t";
+  buf += "sel_registerName(\"countByEnumeratingWithState:objects:count:\"),";
+  buf += "\n\t\t";
+  buf += "&enumState, "
+         "(id *)items, (unsigned int)16)";
+}
+
+/// RewriteBreakStmt - Rewrite for a break-stmt inside an ObjC2's foreach
+/// statement to exit to its outer synthesized loop.
+///
+Stmt *RewriteObjC::RewriteBreakStmt(BreakStmt *S) {
+  if (Stmts.empty() || !isa<ObjCForCollectionStmt>(Stmts.back()))
+    return S;
+  // replace break with goto __break_label
+  std::string buf;
+
+  SourceLocation startLoc = S->getLocStart();
+  buf = "goto __break_label_";
+  buf += utostr(ObjCBcLabelNo.back());
+  ReplaceText(startLoc, strlen("break"), buf);
+
+  return 0;
+}
+
+/// RewriteContinueStmt - Rewrite for a continue-stmt inside an ObjC2's foreach
+/// statement to continue with its inner synthesized loop.
+///
+Stmt *RewriteObjC::RewriteContinueStmt(ContinueStmt *S) {
+  if (Stmts.empty() || !isa<ObjCForCollectionStmt>(Stmts.back()))
+    return S;
+  // replace continue with goto __continue_label
+  std::string buf;
+
+  SourceLocation startLoc = S->getLocStart();
+  buf = "goto __continue_label_";
+  buf += utostr(ObjCBcLabelNo.back());
+  ReplaceText(startLoc, strlen("continue"), buf);
+
+  return 0;
+}
+
+/// RewriteObjCForCollectionStmt - Rewriter for ObjC2's foreach statement.
+///  It rewrites:
+/// for ( type elem in collection) { stmts; }
+
+/// Into:
+/// {
+///   type elem;
+///   struct __objcFastEnumerationState enumState = { 0 };
+///   id items[16];
+///   id l_collection = (id)collection;
+///   unsigned long limit = [l_collection countByEnumeratingWithState:&enumState
+///                                       objects:items count:16];
+/// if (limit) {
+///   unsigned long startMutations = *enumState.mutationsPtr;
+///   do {
+///        unsigned long counter = 0;
+///        do {
+///             if (startMutations != *enumState.mutationsPtr)
+///               objc_enumerationMutation(l_collection);
+///             elem = (type)enumState.itemsPtr[counter++];
+///             stmts;
+///             __continue_label: ;
+///        } while (counter < limit);
+///   } while (limit = [l_collection countByEnumeratingWithState:&enumState
+///                                  objects:items count:16]);
+///   elem = nil;
+///   __break_label: ;
+///  }
+///  else
+///       elem = nil;
+///  }
+///
+Stmt *RewriteObjC::RewriteObjCForCollectionStmt(ObjCForCollectionStmt *S,
+                                                SourceLocation OrigEnd) {
+  assert(!Stmts.empty() && "ObjCForCollectionStmt - Statement stack empty");
+  assert(isa<ObjCForCollectionStmt>(Stmts.back()) &&
+         "ObjCForCollectionStmt Statement stack mismatch");
+  assert(!ObjCBcLabelNo.empty() &&
+         "ObjCForCollectionStmt - Label No stack empty");
+
+  SourceLocation startLoc = S->getLocStart();
+  const char *startBuf = SM->getCharacterData(startLoc);
+  const char *elementName;
+  std::string elementTypeAsString;
+  std::string buf;
+  buf = "\n{\n\t";
+  if (DeclStmt *DS = dyn_cast<DeclStmt>(S->getElement())) {
+    // type elem;
+    NamedDecl* D = cast<NamedDecl>(DS->getSingleDecl());
+    QualType ElementType = cast<ValueDecl>(D)->getType();
+    if (ElementType->isObjCQualifiedIdType() ||
+        ElementType->isObjCQualifiedInterfaceType())
+      // Simply use 'id' for all qualified types.
+      elementTypeAsString = "id";
+    else
+      elementTypeAsString = ElementType.getAsString();
+    buf += elementTypeAsString;
+    buf += " ";
+    elementName = D->getNameAsCString();
+    buf += elementName;
+    buf += ";\n\t";
+  }
+  else {
+    DeclRefExpr *DR = cast<DeclRefExpr>(S->getElement());
+    elementName = DR->getDecl()->getNameAsCString();
+    ValueDecl *VD = cast<ValueDecl>(DR->getDecl());
+    if (VD->getType()->isObjCQualifiedIdType() ||
+        VD->getType()->isObjCQualifiedInterfaceType())
+      // Simply use 'id' for all qualified types.
+      elementTypeAsString = "id";
+    else
+      elementTypeAsString = VD->getType().getAsString();
+  }
+
+  // struct __objcFastEnumerationState enumState = { 0 };
+  buf += "struct __objcFastEnumerationState enumState = { 0 };\n\t";
+  // id items[16];
+  buf += "id items[16];\n\t";
+  // id l_collection = (id)
+  buf += "id l_collection = (id)";
+  // Find start location of 'collection' the hard way!
+  const char *startCollectionBuf = startBuf;
+  startCollectionBuf += 3;  // skip 'for'
+  startCollectionBuf = strchr(startCollectionBuf, '(');
+  startCollectionBuf++; // skip '('
+  // find 'in' and skip it.
+  while (*startCollectionBuf != ' ' ||
+         *(startCollectionBuf+1) != 'i' || *(startCollectionBuf+2) != 'n' ||
+         (*(startCollectionBuf+3) != ' ' &&
+          *(startCollectionBuf+3) != '[' && *(startCollectionBuf+3) != '('))
+    startCollectionBuf++;
+  startCollectionBuf += 3;
+
+  // Replace: "for (type element in" with string constructed thus far.
+  ReplaceText(startLoc, startCollectionBuf - startBuf, buf);
+  // Replace ')' in for '(' type elem in collection ')' with ';'
+  SourceLocation rightParenLoc = S->getRParenLoc();
+  const char *rparenBuf = SM->getCharacterData(rightParenLoc);
+  SourceLocation lparenLoc = startLoc.getFileLocWithOffset(rparenBuf-startBuf);
+  buf = ";\n\t";
+
+  // unsigned long limit = [l_collection countByEnumeratingWithState:&enumState
+  //                                   objects:items count:16];
+  // which is synthesized into:
+  // unsigned int limit =
+  // ((unsigned int (*)
+  //  (id, SEL, struct __objcFastEnumerationState *, id *, unsigned int))
+  //  (void *)objc_msgSend)((id)l_collection,
+  //                        sel_registerName(
+  //                          "countByEnumeratingWithState:objects:count:"),
+  //                        (struct __objcFastEnumerationState *)&state,
+  //                        (id *)items, (unsigned int)16);
+  buf += "unsigned long limit =\n\t\t";
+  SynthCountByEnumWithState(buf);
+  buf += ";\n\t";
+  /// if (limit) {
+  ///   unsigned long startMutations = *enumState.mutationsPtr;
+  ///   do {
+  ///        unsigned long counter = 0;
+  ///        do {
+  ///             if (startMutations != *enumState.mutationsPtr)
+  ///               objc_enumerationMutation(l_collection);
+  ///             elem = (type)enumState.itemsPtr[counter++];
+  buf += "if (limit) {\n\t";
+  buf += "unsigned long startMutations = *enumState.mutationsPtr;\n\t";
+  buf += "do {\n\t\t";
+  buf += "unsigned long counter = 0;\n\t\t";
+  buf += "do {\n\t\t\t";
+  buf += "if (startMutations != *enumState.mutationsPtr)\n\t\t\t\t";
+  buf += "objc_enumerationMutation(l_collection);\n\t\t\t";
+  buf += elementName;
+  buf += " = (";
+  buf += elementTypeAsString;
+  buf += ")enumState.itemsPtr[counter++];";
+  // Replace ')' in for '(' type elem in collection ')' with all of these.
+  ReplaceText(lparenLoc, 1, buf);
+
+  ///            __continue_label: ;
+  ///        } while (counter < limit);
+  ///   } while (limit = [l_collection countByEnumeratingWithState:&enumState
+  ///                                  objects:items count:16]);
+  ///   elem = nil;
+  ///   __break_label: ;
+  ///  }
+  ///  else
+  ///       elem = nil;
+  ///  }
+  ///
+  buf = ";\n\t";
+  buf += "__continue_label_";
+  buf += utostr(ObjCBcLabelNo.back());
+  buf += ": ;";
+  buf += "\n\t\t";
+  buf += "} while (counter < limit);\n\t";
+  buf += "} while (limit = ";
+  SynthCountByEnumWithState(buf);
+  buf += ");\n\t";
+  buf += elementName;
+  buf += " = ((";
+  buf += elementTypeAsString;
+  buf += ")0);\n\t";
+  buf += "__break_label_";
+  buf += utostr(ObjCBcLabelNo.back());
+  buf += ": ;\n\t";
+  buf += "}\n\t";
+  buf += "else\n\t\t";
+  buf += elementName;
+  buf += " = ((";
+  buf += elementTypeAsString;
+  buf += ")0);\n\t";
+  buf += "}\n";
+
+  // Insert all these *after* the statement body.
+  // FIXME: If this should support Obj-C++, support CXXTryStmt
+  if (isa<CompoundStmt>(S->getBody())) {
+    SourceLocation endBodyLoc = OrigEnd.getFileLocWithOffset(1);
+    InsertText(endBodyLoc, buf);
+  } else {
+    /* Need to treat single statements specially. For example:
+     *
+     *     for (A *a in b) if (stuff()) break;
+     *     for (A *a in b) xxxyy;
+     *
+     * The following code simply scans ahead to the semi to find the actual end.
+     */
+    const char *stmtBuf = SM->getCharacterData(OrigEnd);
+    const char *semiBuf = strchr(stmtBuf, ';');
+    assert(semiBuf && "Can't find ';'");
+    SourceLocation endBodyLoc = OrigEnd.getFileLocWithOffset(semiBuf-stmtBuf+1);
+    InsertText(endBodyLoc, buf);
+  }
+  Stmts.pop_back();
+  ObjCBcLabelNo.pop_back();
+  return 0;
+}
+
+/// RewriteObjCSynchronizedStmt -
+/// This routine rewrites @synchronized(expr) stmt;
+/// into:
+/// objc_sync_enter(expr);
+/// @try stmt @finally { objc_sync_exit(expr); }
+///
+Stmt *RewriteObjC::RewriteObjCSynchronizedStmt(ObjCAtSynchronizedStmt *S) {
+  // Get the start location and compute the semi location.
+  SourceLocation startLoc = S->getLocStart();
+  const char *startBuf = SM->getCharacterData(startLoc);
+
+  assert((*startBuf == '@') && "bogus @synchronized location");
+
+  std::string buf;
+  buf = "objc_sync_enter((id)";
+  const char *lparenBuf = startBuf;
+  while (*lparenBuf != '(') lparenBuf++;
+  ReplaceText(startLoc, lparenBuf-startBuf+1, buf);
+  // We can't use S->getSynchExpr()->getLocEnd() to find the end location, since
+  // the sync expression is typically a message expression that's already
+  // been rewritten! (which implies the SourceLocation's are invalid).
+  SourceLocation endLoc = S->getSynchBody()->getLocStart();
+  const char *endBuf = SM->getCharacterData(endLoc);
+  while (*endBuf != ')') endBuf--;
+  SourceLocation rparenLoc = startLoc.getFileLocWithOffset(endBuf-startBuf);
+  buf = ");\n";
+  // declare a new scope with two variables, _stack and _rethrow.
+  buf += "/* @try scope begin */ \n{ struct _objc_exception_data {\n";
+  buf += "int buf[18/*32-bit i386*/];\n";
+  buf += "char *pointers[4];} _stack;\n";
+  buf += "id volatile _rethrow = 0;\n";
+  buf += "objc_exception_try_enter(&_stack);\n";
+  buf += "if (!_setjmp(_stack.buf)) /* @try block continue */\n";
+  ReplaceText(rparenLoc, 1, buf);
+  startLoc = S->getSynchBody()->getLocEnd();
+  startBuf = SM->getCharacterData(startLoc);
+
+  assert((*startBuf == '}') && "bogus @synchronized block");
+  SourceLocation lastCurlyLoc = startLoc;
+  buf = "}\nelse {\n";
+  buf += "  _rethrow = objc_exception_extract(&_stack);\n";
+  buf += "}\n";
+  buf += "{ /* implicit finally clause */\n";
+  buf += "  if (!_rethrow) objc_exception_try_exit(&_stack);\n";
+  
+  std::string syncBuf;
+  syncBuf += " objc_sync_exit(";
+  Expr *syncExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
+                                            CastExpr::CK_Unknown,
+                                            S->getSynchExpr());
+  std::string syncExprBufS;
+  llvm::raw_string_ostream syncExprBuf(syncExprBufS);
+  syncExpr->printPretty(syncExprBuf, *Context, 0,
+                        PrintingPolicy(LangOpts));
+  syncBuf += syncExprBuf.str();
+  syncBuf += ");";
+  
+  buf += syncBuf;
+  buf += "\n  if (_rethrow) objc_exception_throw(_rethrow);\n";
+  buf += "}\n";
+  buf += "}";
+
+  ReplaceText(lastCurlyLoc, 1, buf);
+
+  bool hasReturns = false;
+  HasReturnStmts(S->getSynchBody(), hasReturns);
+  if (hasReturns)
+    RewriteSyncReturnStmts(S->getSynchBody(), syncBuf);
+
+  return 0;
+}
+
+void RewriteObjC::WarnAboutReturnGotoStmts(Stmt *S)
+{
+  // Perform a bottom up traversal of all children.
+  for (Stmt::child_iterator CI = S->child_begin(), E = S->child_end();
+       CI != E; ++CI)
+    if (*CI)
+      WarnAboutReturnGotoStmts(*CI);
+
+  if (isa<ReturnStmt>(S) || isa<GotoStmt>(S)) {
+    Diags.Report(Context->getFullLoc(S->getLocStart()),
+                 TryFinallyContainsReturnDiag);
+  }
+  return;
+}
+
+void RewriteObjC::HasReturnStmts(Stmt *S, bool &hasReturns) 
+{  
+  // Perform a bottom up traversal of all children.
+  for (Stmt::child_iterator CI = S->child_begin(), E = S->child_end();
+        CI != E; ++CI)
+   if (*CI)
+     HasReturnStmts(*CI, hasReturns);
+
+ if (isa<ReturnStmt>(S))
+   hasReturns = true;
+ return;
+}
+
+void RewriteObjC::RewriteTryReturnStmts(Stmt *S) {
+ // Perform a bottom up traversal of all children.
+ for (Stmt::child_iterator CI = S->child_begin(), E = S->child_end();
+      CI != E; ++CI)
+   if (*CI) {
+     RewriteTryReturnStmts(*CI);
+   }
+ if (isa<ReturnStmt>(S)) {
+   SourceLocation startLoc = S->getLocStart();
+   const char *startBuf = SM->getCharacterData(startLoc);
+
+   const char *semiBuf = strchr(startBuf, ';');
+   assert((*semiBuf == ';') && "RewriteTryReturnStmts: can't find ';'");
+   SourceLocation onePastSemiLoc = startLoc.getFileLocWithOffset(semiBuf-startBuf+1);
+
+   std::string buf;
+   buf = "{ objc_exception_try_exit(&_stack); return";
+   
+   ReplaceText(startLoc, 6, buf);
+   InsertText(onePastSemiLoc, "}");
+ }
+ return;
+}
+
+void RewriteObjC::RewriteSyncReturnStmts(Stmt *S, std::string syncExitBuf) {
+  // Perform a bottom up traversal of all children.
+  for (Stmt::child_iterator CI = S->child_begin(), E = S->child_end();
+       CI != E; ++CI)
+    if (*CI) {
+      RewriteSyncReturnStmts(*CI, syncExitBuf);
+    }
+  if (isa<ReturnStmt>(S)) {
+    SourceLocation startLoc = S->getLocStart();
+    const char *startBuf = SM->getCharacterData(startLoc);
+
+    const char *semiBuf = strchr(startBuf, ';');
+    assert((*semiBuf == ';') && "RewriteSyncReturnStmts: can't find ';'");
+    SourceLocation onePastSemiLoc = startLoc.getFileLocWithOffset(semiBuf-startBuf+1);
+
+    std::string buf;
+    buf = "{ objc_exception_try_exit(&_stack);";
+    buf += syncExitBuf;
+    buf += " return";
+    
+    ReplaceText(startLoc, 6, buf);
+    InsertText(onePastSemiLoc, "}");
+  }
+  return;
+}
+
+Stmt *RewriteObjC::RewriteObjCTryStmt(ObjCAtTryStmt *S) {
+  // Get the start location and compute the semi location.
+  SourceLocation startLoc = S->getLocStart();
+  const char *startBuf = SM->getCharacterData(startLoc);
+
+  assert((*startBuf == '@') && "bogus @try location");
+
+  std::string buf;
+  // declare a new scope with two variables, _stack and _rethrow.
+  buf = "/* @try scope begin */ { struct _objc_exception_data {\n";
+  buf += "int buf[18/*32-bit i386*/];\n";
+  buf += "char *pointers[4];} _stack;\n";
+  buf += "id volatile _rethrow = 0;\n";
+  buf += "objc_exception_try_enter(&_stack);\n";
+  buf += "if (!_setjmp(_stack.buf)) /* @try block continue */\n";
+
+  ReplaceText(startLoc, 4, buf);
+
+  startLoc = S->getTryBody()->getLocEnd();
+  startBuf = SM->getCharacterData(startLoc);
+
+  assert((*startBuf == '}') && "bogus @try block");
+
+  SourceLocation lastCurlyLoc = startLoc;
+  if (S->getNumCatchStmts()) {
+    startLoc = startLoc.getFileLocWithOffset(1);
+    buf = " /* @catch begin */ else {\n";
+    buf += " id _caught = objc_exception_extract(&_stack);\n";
+    buf += " objc_exception_try_enter (&_stack);\n";
+    buf += " if (_setjmp(_stack.buf))\n";
+    buf += "   _rethrow = objc_exception_extract(&_stack);\n";
+    buf += " else { /* @catch continue */";
+
+    InsertText(startLoc, buf);
+  } else { /* no catch list */
+    buf = "}\nelse {\n";
+    buf += "  _rethrow = objc_exception_extract(&_stack);\n";
+    buf += "}";
+    ReplaceText(lastCurlyLoc, 1, buf);
+  }
+  bool sawIdTypedCatch = false;
+  Stmt *lastCatchBody = 0;
+  for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I) {
+    ObjCAtCatchStmt *Catch = S->getCatchStmt(I);
+    VarDecl *catchDecl = Catch->getCatchParamDecl();
+
+    if (I == 0)
+      buf = "if ("; // we are generating code for the first catch clause
+    else
+      buf = "else if (";
+    startLoc = Catch->getLocStart();
+    startBuf = SM->getCharacterData(startLoc);
+
+    assert((*startBuf == '@') && "bogus @catch location");
+
+    const char *lParenLoc = strchr(startBuf, '(');
+
+    if (Catch->hasEllipsis()) {
+      // Now rewrite the body...
+      lastCatchBody = Catch->getCatchBody();
+      SourceLocation bodyLoc = lastCatchBody->getLocStart();
+      const char *bodyBuf = SM->getCharacterData(bodyLoc);
+      assert(*SM->getCharacterData(Catch->getRParenLoc()) == ')' &&
+             "bogus @catch paren location");
+      assert((*bodyBuf == '{') && "bogus @catch body location");
+
+      buf += "1) { id _tmp = _caught;";
+      Rewrite.ReplaceText(startLoc, bodyBuf-startBuf+1, buf);
+    } else if (catchDecl) {
+      QualType t = catchDecl->getType();
+      if (t == Context->getObjCIdType()) {
+        buf += "1) { ";
+        ReplaceText(startLoc, lParenLoc-startBuf+1, buf);
+        sawIdTypedCatch = true;
+      } else if (t->isObjCObjectPointerType()) {
+        QualType InterfaceTy = t->getPointeeType();
+        const ObjCInterfaceType *cls = // Should be a pointer to a class.
+          InterfaceTy->getAs<ObjCInterfaceType>();
+        if (cls) {
+          buf += "objc_exception_match((struct objc_class *)objc_getClass(\"";
+          buf += cls->getDecl()->getNameAsString();
+          buf += "\"), (struct objc_object *)_caught)) { ";
+          ReplaceText(startLoc, lParenLoc-startBuf+1, buf);
+        }
+      }
+      // Now rewrite the body...
+      lastCatchBody = Catch->getCatchBody();
+      SourceLocation rParenLoc = Catch->getRParenLoc();
+      SourceLocation bodyLoc = lastCatchBody->getLocStart();
+      const char *bodyBuf = SM->getCharacterData(bodyLoc);
+      const char *rParenBuf = SM->getCharacterData(rParenLoc);
+      assert((*rParenBuf == ')') && "bogus @catch paren location");
+      assert((*bodyBuf == '{') && "bogus @catch body location");
+
+      // Here we replace ") {" with "= _caught;" (which initializes and
+      // declares the @catch parameter).
+      ReplaceText(rParenLoc, bodyBuf-rParenBuf+1, " = _caught;");
+    } else {
+      assert(false && "@catch rewrite bug");
+    }
+  }
+  // Complete the catch list...
+  if (lastCatchBody) {
+    SourceLocation bodyLoc = lastCatchBody->getLocEnd();
+    assert(*SM->getCharacterData(bodyLoc) == '}' &&
+           "bogus @catch body location");
+
+    // Insert the last (implicit) else clause *before* the right curly brace.
+    bodyLoc = bodyLoc.getFileLocWithOffset(-1);
+    buf = "} /* last catch end */\n";
+    buf += "else {\n";
+    buf += " _rethrow = _caught;\n";
+    buf += " objc_exception_try_exit(&_stack);\n";
+    buf += "} } /* @catch end */\n";
+    if (!S->getFinallyStmt())
+      buf += "}\n";
+    InsertText(bodyLoc, buf);
+
+    // Set lastCurlyLoc
+    lastCurlyLoc = lastCatchBody->getLocEnd();
+  }
+  if (ObjCAtFinallyStmt *finalStmt = S->getFinallyStmt()) {
+    startLoc = finalStmt->getLocStart();
+    startBuf = SM->getCharacterData(startLoc);
+    assert((*startBuf == '@') && "bogus @finally start");
+
+    ReplaceText(startLoc, 8, "/* @finally */");
+
+    Stmt *body = finalStmt->getFinallyBody();
+    SourceLocation startLoc = body->getLocStart();
+    SourceLocation endLoc = body->getLocEnd();
+    assert(*SM->getCharacterData(startLoc) == '{' &&
+           "bogus @finally body location");
+    assert(*SM->getCharacterData(endLoc) == '}' &&
+           "bogus @finally body location");
+
+    startLoc = startLoc.getFileLocWithOffset(1);
+    InsertText(startLoc, " if (!_rethrow) objc_exception_try_exit(&_stack);\n");
+    endLoc = endLoc.getFileLocWithOffset(-1);
+    InsertText(endLoc, " if (_rethrow) objc_exception_throw(_rethrow);\n");
+
+    // Set lastCurlyLoc
+    lastCurlyLoc = body->getLocEnd();
+
+    // Now check for any return/continue/go statements within the @try.
+    WarnAboutReturnGotoStmts(S->getTryBody());
+  } else { /* no finally clause - make sure we synthesize an implicit one */
+    buf = "{ /* implicit finally clause */\n";
+    buf += " if (!_rethrow) objc_exception_try_exit(&_stack);\n";
+    buf += " if (_rethrow) objc_exception_throw(_rethrow);\n";
+    buf += "}";
+    ReplaceText(lastCurlyLoc, 1, buf);
+    
+    // Now check for any return/continue/go statements within the @try.
+    // The implicit finally clause won't called if the @try contains any
+    // jump statements.
+    bool hasReturns = false;
+    HasReturnStmts(S->getTryBody(), hasReturns);
+    if (hasReturns)
+      RewriteTryReturnStmts(S->getTryBody());
+  }
+  // Now emit the final closing curly brace...
+  lastCurlyLoc = lastCurlyLoc.getFileLocWithOffset(1);
+  InsertText(lastCurlyLoc, " } /* @try scope end */\n");
+  return 0;
+}
+
+Stmt *RewriteObjC::RewriteObjCCatchStmt(ObjCAtCatchStmt *S) {
+  return 0;
+}
+
+Stmt *RewriteObjC::RewriteObjCFinallyStmt(ObjCAtFinallyStmt *S) {
+  return 0;
+}
+
+// This can't be done with ReplaceStmt(S, ThrowExpr), since
+// the throw expression is typically a message expression that's already
+// been rewritten! (which implies the SourceLocation's are invalid).
+Stmt *RewriteObjC::RewriteObjCThrowStmt(ObjCAtThrowStmt *S) {
+  // Get the start location and compute the semi location.
+  SourceLocation startLoc = S->getLocStart();
+  const char *startBuf = SM->getCharacterData(startLoc);
+
+  assert((*startBuf == '@') && "bogus @throw location");
+
+  std::string buf;
+  /* void objc_exception_throw(id) __attribute__((noreturn)); */
+  if (S->getThrowExpr())
+    buf = "objc_exception_throw(";
+  else // add an implicit argument
+    buf = "objc_exception_throw(_caught";
+
+  // handle "@  throw" correctly.
+  const char *wBuf = strchr(startBuf, 'w');
+  assert((*wBuf == 'w') && "@throw: can't find 'w'");
+  ReplaceText(startLoc, wBuf-startBuf+1, buf);
+
+  const char *semiBuf = strchr(startBuf, ';');
+  assert((*semiBuf == ';') && "@throw: can't find ';'");
+  SourceLocation semiLoc = startLoc.getFileLocWithOffset(semiBuf-startBuf);
+  ReplaceText(semiLoc, 1, ");");
+  return 0;
+}
+
+Stmt *RewriteObjC::RewriteAtEncode(ObjCEncodeExpr *Exp) {
+  // Create a new string expression.
+  QualType StrType = Context->getPointerType(Context->CharTy);
+  std::string StrEncoding;
+  Context->getObjCEncodingForType(Exp->getEncodedType(), StrEncoding);
+  Expr *Replacement = StringLiteral::Create(*Context,StrEncoding.c_str(),
+                                            StrEncoding.length(), false,StrType,
+                                            SourceLocation());
+  ReplaceStmt(Exp, Replacement);
+
+  // Replace this subexpr in the parent.
+  // delete Exp; leak for now, see RewritePropertySetter() usage for more info.
+  return Replacement;
+}
+
+Stmt *RewriteObjC::RewriteAtSelector(ObjCSelectorExpr *Exp) {
+  if (!SelGetUidFunctionDecl)
+    SynthSelGetUidFunctionDecl();
+  assert(SelGetUidFunctionDecl && "Can't find sel_registerName() decl");
+  // Create a call to sel_registerName("selName").
+  llvm::SmallVector<Expr*, 8> SelExprs;
+  QualType argType = Context->getPointerType(Context->CharTy);
+  SelExprs.push_back(StringLiteral::Create(*Context,
+                                       Exp->getSelector().getAsString().c_str(),
+                                       Exp->getSelector().getAsString().size(),
+                                       false, argType, SourceLocation()));
+  CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
+                                                 &SelExprs[0], SelExprs.size());
+  ReplaceStmt(Exp, SelExp);
+  // delete Exp; leak for now, see RewritePropertySetter() usage for more info.
+  return SelExp;
+}
+
+CallExpr *RewriteObjC::SynthesizeCallToFunctionDecl(
+  FunctionDecl *FD, Expr **args, unsigned nargs, SourceLocation StartLoc,
+                                                    SourceLocation EndLoc) {
+  // Get the type, we will need to reference it in a couple spots.
+  QualType msgSendType = FD->getType();
+
+  // Create a reference to the objc_msgSend() declaration.
+  DeclRefExpr *DRE = new (Context) DeclRefExpr(FD, msgSendType, SourceLocation());
+
+  // Now, we cast the reference to a pointer to the objc_msgSend type.
+  QualType pToFunc = Context->getPointerType(msgSendType);
+  ImplicitCastExpr *ICE = 
+    new (Context) ImplicitCastExpr(pToFunc, CastExpr::CK_Unknown,
+                                   DRE, CXXBaseSpecifierArray(),
+                                   /*isLvalue=*/false);
+
+  const FunctionType *FT = msgSendType->getAs<FunctionType>();
+
+  CallExpr *Exp =  
+    new (Context) CallExpr(*Context, ICE, args, nargs, FT->getResultType(),
+                                EndLoc);
+  return Exp;
+}
+
+static bool scanForProtocolRefs(const char *startBuf, const char *endBuf,
+                                const char *&startRef, const char *&endRef) {
+  while (startBuf < endBuf) {
+    if (*startBuf == '<')
+      startRef = startBuf; // mark the start.
+    if (*startBuf == '>') {
+      if (startRef && *startRef == '<') {
+        endRef = startBuf; // mark the end.
+        return true;
+      }
+      return false;
+    }
+    startBuf++;
+  }
+  return false;
+}
+
+static void scanToNextArgument(const char *&argRef) {
+  int angle = 0;
+  while (*argRef != ')' && (*argRef != ',' || angle > 0)) {
+    if (*argRef == '<')
+      angle++;
+    else if (*argRef == '>')
+      angle--;
+    argRef++;
+  }
+  assert(angle == 0 && "scanToNextArgument - bad protocol type syntax");
+}
+
+bool RewriteObjC::needToScanForQualifiers(QualType T) {
+  if (T->isObjCQualifiedIdType())
+    return true;
+  if (const PointerType *PT = T->getAs<PointerType>()) {
+    if (PT->getPointeeType()->isObjCQualifiedIdType())
+      return true;
+  }
+  if (T->isObjCObjectPointerType()) {
+    T = T->getPointeeType();
+    return T->isObjCQualifiedInterfaceType();
+  }
+  return false;
+}
+
+void RewriteObjC::RewriteObjCQualifiedInterfaceTypes(Expr *E) {
+  QualType Type = E->getType();
+  if (needToScanForQualifiers(Type)) {
+    SourceLocation Loc, EndLoc;
+
+    if (const CStyleCastExpr *ECE = dyn_cast<CStyleCastExpr>(E)) {
+      Loc = ECE->getLParenLoc();
+      EndLoc = ECE->getRParenLoc();
+    } else {
+      Loc = E->getLocStart();
+      EndLoc = E->getLocEnd();
+    }
+    // This will defend against trying to rewrite synthesized expressions.
+    if (Loc.isInvalid() || EndLoc.isInvalid())
+      return;
+
+    const char *startBuf = SM->getCharacterData(Loc);
+    const char *endBuf = SM->getCharacterData(EndLoc);
+    const char *startRef = 0, *endRef = 0;
+    if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) {
+      // Get the locations of the startRef, endRef.
+      SourceLocation LessLoc = Loc.getFileLocWithOffset(startRef-startBuf);
+      SourceLocation GreaterLoc = Loc.getFileLocWithOffset(endRef-startBuf+1);
+      // Comment out the protocol references.
+      InsertText(LessLoc, "/*");
+      InsertText(GreaterLoc, "*/");
+    }
+  }
+}
+
+void RewriteObjC::RewriteObjCQualifiedInterfaceTypes(Decl *Dcl) {
+  SourceLocation Loc;
+  QualType Type;
+  const FunctionProtoType *proto = 0;
+  if (VarDecl *VD = dyn_cast<VarDecl>(Dcl)) {
+    Loc = VD->getLocation();
+    Type = VD->getType();
+  }
+  else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(Dcl)) {
+    Loc = FD->getLocation();
+    // Check for ObjC 'id' and class types that have been adorned with protocol
+    // information (id<p>, C<p>*). The protocol references need to be rewritten!
+    const FunctionType *funcType = FD->getType()->getAs<FunctionType>();
+    assert(funcType && "missing function type");
+    proto = dyn_cast<FunctionProtoType>(funcType);
+    if (!proto)
+      return;
+    Type = proto->getResultType();
+  }
+  else if (FieldDecl *FD = dyn_cast<FieldDecl>(Dcl)) {
+    Loc = FD->getLocation();
+    Type = FD->getType();
+  }
+  else
+    return;
+
+  if (needToScanForQualifiers(Type)) {
+    // Since types are unique, we need to scan the buffer.
+
+    const char *endBuf = SM->getCharacterData(Loc);
+    const char *startBuf = endBuf;
+    while (*startBuf != ';' && *startBuf != '<' && startBuf != MainFileStart)
+      startBuf--; // scan backward (from the decl location) for return type.
+    const char *startRef = 0, *endRef = 0;
+    if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) {
+      // Get the locations of the startRef, endRef.
+      SourceLocation LessLoc = Loc.getFileLocWithOffset(startRef-endBuf);
+      SourceLocation GreaterLoc = Loc.getFileLocWithOffset(endRef-endBuf+1);
+      // Comment out the protocol references.
+      InsertText(LessLoc, "/*");
+      InsertText(GreaterLoc, "*/");
+    }
+  }
+  if (!proto)
+      return; // most likely, was a variable
+  // Now check arguments.
+  const char *startBuf = SM->getCharacterData(Loc);
+  const char *startFuncBuf = startBuf;
+  for (unsigned i = 0; i < proto->getNumArgs(); i++) {
+    if (needToScanForQualifiers(proto->getArgType(i))) {
+      // Since types are unique, we need to scan the buffer.
+
+      const char *endBuf = startBuf;
+      // scan forward (from the decl location) for argument types.
+      scanToNextArgument(endBuf);
+      const char *startRef = 0, *endRef = 0;
+      if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) {
+        // Get the locations of the startRef, endRef.
+        SourceLocation LessLoc =
+          Loc.getFileLocWithOffset(startRef-startFuncBuf);
+        SourceLocation GreaterLoc =
+          Loc.getFileLocWithOffset(endRef-startFuncBuf+1);
+        // Comment out the protocol references.
+        InsertText(LessLoc, "/*");
+        InsertText(GreaterLoc, "*/");
+      }
+      startBuf = ++endBuf;
+    }
+    else {
+      // If the function name is derived from a macro expansion, then the
+      // argument buffer will not follow the name. Need to speak with Chris.
+      while (*startBuf && *startBuf != ')' && *startBuf != ',')
+        startBuf++; // scan forward (from the decl location) for argument types.
+      startBuf++;
+    }
+  }
+}
+
+void RewriteObjC::RewriteTypeOfDecl(VarDecl *ND) {
+  QualType QT = ND->getType();
+  const Type* TypePtr = QT->getAs<Type>();
+  if (!isa<TypeOfExprType>(TypePtr))
+    return;
+  while (isa<TypeOfExprType>(TypePtr)) {
+    const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr);
+    QT = TypeOfExprTypePtr->getUnderlyingExpr()->getType();
+    TypePtr = QT->getAs<Type>();
+  }
+  // FIXME. This will not work for multiple declarators; as in:
+  // __typeof__(a) b,c,d;
+  std::string TypeAsString(QT.getAsString());
+  SourceLocation DeclLoc = ND->getTypeSpecStartLoc();
+  const char *startBuf = SM->getCharacterData(DeclLoc);
+  if (ND->getInit()) {
+    std::string Name(ND->getNameAsString());
+    TypeAsString += " " + Name + " = ";
+    Expr *E = ND->getInit();
+    SourceLocation startLoc;
+    if (const CStyleCastExpr *ECE = dyn_cast<CStyleCastExpr>(E))
+      startLoc = ECE->getLParenLoc();
+    else
+      startLoc = E->getLocStart();
+    startLoc = SM->getInstantiationLoc(startLoc);
+    const char *endBuf = SM->getCharacterData(startLoc);
+    ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString);
+  }
+  else {
+    SourceLocation X = ND->getLocEnd();
+    X = SM->getInstantiationLoc(X);
+    const char *endBuf = SM->getCharacterData(X);
+    ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString);
+  }
+}
+
+// SynthSelGetUidFunctionDecl - SEL sel_registerName(const char *str);
+void RewriteObjC::SynthSelGetUidFunctionDecl() {
+  IdentifierInfo *SelGetUidIdent = &Context->Idents.get("sel_registerName");
+  llvm::SmallVector<QualType, 16> ArgTys;
+  ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst()));
+  QualType getFuncType = Context->getFunctionType(Context->getObjCSelType(),
+                                                  &ArgTys[0], ArgTys.size(),
+                                                  false /*isVariadic*/, 0,
+                                                  false, false, 0, 0,
+                                                  FunctionType::ExtInfo());
+  SelGetUidFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
+                                           SourceLocation(),
+                                           SelGetUidIdent, getFuncType, 0,
+                                           FunctionDecl::Extern,
+                                           FunctionDecl::None, false);
+}
+
+void RewriteObjC::RewriteFunctionDecl(FunctionDecl *FD) {
+  // declared in <objc/objc.h>
+  if (FD->getIdentifier() &&
+      strcmp(FD->getNameAsCString(), "sel_registerName") == 0) {
+    SelGetUidFunctionDecl = FD;
+    return;
+  }
+  RewriteObjCQualifiedInterfaceTypes(FD);
+}
+
+static void RewriteBlockPointerType(std::string& Str, QualType Type) {
+  std::string TypeString(Type.getAsString());
+  const char *argPtr = TypeString.c_str();
+  if (!strchr(argPtr, '^')) {
+    Str += TypeString;
+    return;
+  }
+  while (*argPtr) {
+    Str += (*argPtr == '^' ? '*' : *argPtr);
+    argPtr++;
+  }
+}
+
+// FIXME. Consolidate this routine with RewriteBlockPointerType.
+static void RewriteBlockPointerTypeVariable(std::string& Str, ValueDecl *VD) {
+  QualType Type = VD->getType();
+  std::string TypeString(Type.getAsString());
+  const char *argPtr = TypeString.c_str();
+  int paren = 0;
+  while (*argPtr) {
+    switch (*argPtr) {
+      case '(':
+        Str += *argPtr;
+        paren++;
+        break;
+      case ')':
+        Str += *argPtr;
+        paren--;
+        break;
+      case '^':
+        Str += '*';
+        if (paren == 1)
+          Str += VD->getNameAsString();
+        break;
+      default:
+        Str += *argPtr;
+        break;
+    }
+    argPtr++;
+  }
+}
+
+
+void RewriteObjC::RewriteBlockLiteralFunctionDecl(FunctionDecl *FD) {
+  SourceLocation FunLocStart = FD->getTypeSpecStartLoc();
+  const FunctionType *funcType = FD->getType()->getAs<FunctionType>();
+  const FunctionProtoType *proto = dyn_cast<FunctionProtoType>(funcType);
+  if (!proto)
+    return;
+  QualType Type = proto->getResultType();
+  std::string FdStr = Type.getAsString();
+  FdStr += " ";
+  FdStr += FD->getNameAsCString();
+  FdStr +=  "(";
+  unsigned numArgs = proto->getNumArgs();
+  for (unsigned i = 0; i < numArgs; i++) {
+    QualType ArgType = proto->getArgType(i);
+    RewriteBlockPointerType(FdStr, ArgType);
+    if (i+1 < numArgs)
+      FdStr += ", ";
+  }
+  FdStr +=  ");\n";
+  InsertText(FunLocStart, FdStr);
+  CurFunctionDeclToDeclareForBlock = 0;
+}
+
+// SynthSuperContructorFunctionDecl - id objc_super(id obj, id super);
+void RewriteObjC::SynthSuperContructorFunctionDecl() {
+  if (SuperContructorFunctionDecl)
+    return;
+  IdentifierInfo *msgSendIdent = &Context->Idents.get("__rw_objc_super");
+  llvm::SmallVector<QualType, 16> ArgTys;
+  QualType argT = Context->getObjCIdType();
+  assert(!argT.isNull() && "Can't find 'id' type");
+  ArgTys.push_back(argT);
+  ArgTys.push_back(argT);
+  QualType msgSendType = Context->getFunctionType(Context->getObjCIdType(),
+                                                  &ArgTys[0], ArgTys.size(),
+                                                  false, 0,
+                                                  false, false, 0, 0,
+                                                  FunctionType::ExtInfo());
+  SuperContructorFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
+                                         SourceLocation(),
+                                         msgSendIdent, msgSendType, 0,
+                                         FunctionDecl::Extern,
+                                         FunctionDecl::None, false);
+}
+
+// SynthMsgSendFunctionDecl - id objc_msgSend(id self, SEL op, ...);
+void RewriteObjC::SynthMsgSendFunctionDecl() {
+  IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSend");
+  llvm::SmallVector<QualType, 16> ArgTys;
+  QualType argT = Context->getObjCIdType();
+  assert(!argT.isNull() && "Can't find 'id' type");
+  ArgTys.push_back(argT);
+  argT = Context->getObjCSelType();
+  assert(!argT.isNull() && "Can't find 'SEL' type");
+  ArgTys.push_back(argT);
+  QualType msgSendType = Context->getFunctionType(Context->getObjCIdType(),
+                                                  &ArgTys[0], ArgTys.size(),
+                                                  true /*isVariadic*/, 0,
+                                                  false, false, 0, 0,
+                                                  FunctionType::ExtInfo());
+  MsgSendFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
+                                         SourceLocation(),
+                                         msgSendIdent, msgSendType, 0,
+                                         FunctionDecl::Extern,
+                                         FunctionDecl::None, false);
+}
+
+// SynthMsgSendSuperFunctionDecl - id objc_msgSendSuper(struct objc_super *, SEL op, ...);
+void RewriteObjC::SynthMsgSendSuperFunctionDecl() {
+  IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSendSuper");
+  llvm::SmallVector<QualType, 16> ArgTys;
+  RecordDecl *RD = RecordDecl::Create(*Context, TagDecl::TK_struct, TUDecl,
+                                      SourceLocation(),
+                                      &Context->Idents.get("objc_super"));
+  QualType argT = Context->getPointerType(Context->getTagDeclType(RD));
+  assert(!argT.isNull() && "Can't build 'struct objc_super *' type");
+  ArgTys.push_back(argT);
+  argT = Context->getObjCSelType();
+  assert(!argT.isNull() && "Can't find 'SEL' type");
+  ArgTys.push_back(argT);
+  QualType msgSendType = Context->getFunctionType(Context->getObjCIdType(),
+                                                  &ArgTys[0], ArgTys.size(),
+                                                  true /*isVariadic*/, 0,
+                                                  false, false, 0, 0,
+                                                  FunctionType::ExtInfo());
+  MsgSendSuperFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
+                                              SourceLocation(),
+                                              msgSendIdent, msgSendType, 0,
+                                              FunctionDecl::Extern,
+                                              FunctionDecl::None, false);
+}
+
+// SynthMsgSendStretFunctionDecl - id objc_msgSend_stret(id self, SEL op, ...);
+void RewriteObjC::SynthMsgSendStretFunctionDecl() {
+  IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSend_stret");
+  llvm::SmallVector<QualType, 16> ArgTys;
+  QualType argT = Context->getObjCIdType();
+  assert(!argT.isNull() && "Can't find 'id' type");
+  ArgTys.push_back(argT);
+  argT = Context->getObjCSelType();
+  assert(!argT.isNull() && "Can't find 'SEL' type");
+  ArgTys.push_back(argT);
+  QualType msgSendType = Context->getFunctionType(Context->getObjCIdType(),
+                                                  &ArgTys[0], ArgTys.size(),
+                                                  true /*isVariadic*/, 0,
+                                                  false, false, 0, 0,
+                                                  FunctionType::ExtInfo());
+  MsgSendStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
+                                         SourceLocation(),
+                                         msgSendIdent, msgSendType, 0,
+                                         FunctionDecl::Extern,
+                                         FunctionDecl::None, false);
+}
+
+// SynthMsgSendSuperStretFunctionDecl -
+// id objc_msgSendSuper_stret(struct objc_super *, SEL op, ...);
+void RewriteObjC::SynthMsgSendSuperStretFunctionDecl() {
+  IdentifierInfo *msgSendIdent =
+    &Context->Idents.get("objc_msgSendSuper_stret");
+  llvm::SmallVector<QualType, 16> ArgTys;
+  RecordDecl *RD = RecordDecl::Create(*Context, TagDecl::TK_struct, TUDecl,
+                                      SourceLocation(),
+                                      &Context->Idents.get("objc_super"));
+  QualType argT = Context->getPointerType(Context->getTagDeclType(RD));
+  assert(!argT.isNull() && "Can't build 'struct objc_super *' type");
+  ArgTys.push_back(argT);
+  argT = Context->getObjCSelType();
+  assert(!argT.isNull() && "Can't find 'SEL' type");
+  ArgTys.push_back(argT);
+  QualType msgSendType = Context->getFunctionType(Context->getObjCIdType(),
+                                                  &ArgTys[0], ArgTys.size(),
+                                                  true /*isVariadic*/, 0,
+                                                  false, false, 0, 0,
+                                                  FunctionType::ExtInfo());
+  MsgSendSuperStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
+                                                       SourceLocation(),
+                                              msgSendIdent, msgSendType, 0,
+                                              FunctionDecl::Extern,
+                                              FunctionDecl::None, false);
+}
+
+// SynthMsgSendFpretFunctionDecl - double objc_msgSend_fpret(id self, SEL op, ...);
+void RewriteObjC::SynthMsgSendFpretFunctionDecl() {
+  IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSend_fpret");
+  llvm::SmallVector<QualType, 16> ArgTys;
+  QualType argT = Context->getObjCIdType();
+  assert(!argT.isNull() && "Can't find 'id' type");
+  ArgTys.push_back(argT);
+  argT = Context->getObjCSelType();
+  assert(!argT.isNull() && "Can't find 'SEL' type");
+  ArgTys.push_back(argT);
+  QualType msgSendType = Context->getFunctionType(Context->DoubleTy,
+                                                  &ArgTys[0], ArgTys.size(),
+                                                  true /*isVariadic*/, 0,
+                                                  false, false, 0, 0,
+                                                  FunctionType::ExtInfo());
+  MsgSendFpretFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
+                                              SourceLocation(),
+                                              msgSendIdent, msgSendType, 0,
+                                              FunctionDecl::Extern,
+                                              FunctionDecl::None, false);
+}
+
+// SynthGetClassFunctionDecl - id objc_getClass(const char *name);
+void RewriteObjC::SynthGetClassFunctionDecl() {
+  IdentifierInfo *getClassIdent = &Context->Idents.get("objc_getClass");
+  llvm::SmallVector<QualType, 16> ArgTys;
+  ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst()));
+  QualType getClassType = Context->getFunctionType(Context->getObjCIdType(),
+                                                   &ArgTys[0], ArgTys.size(),
+                                                   false /*isVariadic*/, 0,
+                                                  false, false, 0, 0,
+                                                   FunctionType::ExtInfo());
+  GetClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
+                                          SourceLocation(),
+                                          getClassIdent, getClassType, 0,
+                                          FunctionDecl::Extern,
+                                          FunctionDecl::None, false);
+}
+
+// SynthGetSuperClassFunctionDecl - Class class_getSuperclass(Class cls);
+void RewriteObjC::SynthGetSuperClassFunctionDecl() {
+  IdentifierInfo *getSuperClassIdent = 
+    &Context->Idents.get("class_getSuperclass");
+  llvm::SmallVector<QualType, 16> ArgTys;
+  ArgTys.push_back(Context->getObjCClassType());
+  QualType getClassType = Context->getFunctionType(Context->getObjCClassType(),
+                                                   &ArgTys[0], ArgTys.size(),
+                                                   false /*isVariadic*/, 0,
+                                                   false, false, 0, 0,
+                                                   FunctionType::ExtInfo());
+  GetSuperClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
+                                                   SourceLocation(),
+                                                   getSuperClassIdent,
+                                                   getClassType, 0,
+                                                   FunctionDecl::Extern,
+                                                   FunctionDecl::None,
+                                                   false);
+}
+
+// SynthGetMetaClassFunctionDecl - id objc_getClass(const char *name);
+void RewriteObjC::SynthGetMetaClassFunctionDecl() {
+  IdentifierInfo *getClassIdent = &Context->Idents.get("objc_getMetaClass");
+  llvm::SmallVector<QualType, 16> ArgTys;
+  ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst()));
+  QualType getClassType = Context->getFunctionType(Context->getObjCIdType(),
+                                                   &ArgTys[0], ArgTys.size(),
+                                                   false /*isVariadic*/, 0,
+                                                   false, false, 0, 0,
+                                                   FunctionType::ExtInfo());
+  GetMetaClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
+                                              SourceLocation(),
+                                              getClassIdent, getClassType, 0,
+                                              FunctionDecl::Extern,
+                                              FunctionDecl::None, false);
+}
+
+Stmt *RewriteObjC::RewriteObjCStringLiteral(ObjCStringLiteral *Exp) {
+  QualType strType = getConstantStringStructType();
+
+  std::string S = "__NSConstantStringImpl_";
+
+  std::string tmpName = InFileName;
+  unsigned i;
+  for (i=0; i < tmpName.length(); i++) {
+    char c = tmpName.at(i);
+    // replace any non alphanumeric characters with '_'.
+    if (!isalpha(c) && (c < '0' || c > '9'))
+      tmpName[i] = '_';
+  }
+  S += tmpName;
+  S += "_";
+  S += utostr(NumObjCStringLiterals++);
+
+  Preamble += "static __NSConstantStringImpl " + S;
+  Preamble += " __attribute__ ((section (\"__DATA, __cfstring\"))) = {__CFConstantStringClassReference,";
+  Preamble += "0x000007c8,"; // utf8_str
+  // The pretty printer for StringLiteral handles escape characters properly.
+  std::string prettyBufS;
+  llvm::raw_string_ostream prettyBuf(prettyBufS);
+  Exp->getString()->printPretty(prettyBuf, *Context, 0,
+                                PrintingPolicy(LangOpts));
+  Preamble += prettyBuf.str();
+  Preamble += ",";
+  Preamble += utostr(Exp->getString()->getByteLength()) + "};\n";
+
+  VarDecl *NewVD = VarDecl::Create(*Context, TUDecl, SourceLocation(),
+                                    &Context->Idents.get(S), strType, 0,
+                                    VarDecl::Static, VarDecl::None);
+  DeclRefExpr *DRE = new (Context) DeclRefExpr(NewVD, strType, SourceLocation());
+  Expr *Unop = new (Context) UnaryOperator(DRE, UnaryOperator::AddrOf,
+                                 Context->getPointerType(DRE->getType()),
+                                 SourceLocation());
+  // cast to NSConstantString *
+  CastExpr *cast = NoTypeInfoCStyleCastExpr(Context, Exp->getType(),
+                                            CastExpr::CK_Unknown, Unop);
+  ReplaceStmt(Exp, cast);
+  // delete Exp; leak for now, see RewritePropertySetter() usage for more info.
+  return cast;
+}
+
+bool RewriteObjC::isSuperReceiver(Expr *recExpr) {
+  // check if we are sending a message to 'super'
+  if (!CurMethodDef || !CurMethodDef->isInstanceMethod()) return false;
+  return isa<ObjCSuperExpr>(recExpr);
+}
+
+// struct objc_super { struct objc_object *receiver; struct objc_class *super; };
+QualType RewriteObjC::getSuperStructType() {
+  if (!SuperStructDecl) {
+    SuperStructDecl = RecordDecl::Create(*Context, TagDecl::TK_struct, TUDecl,
+                                         SourceLocation(),
+                                         &Context->Idents.get("objc_super"));
+    QualType FieldTypes[2];
+
+    // struct objc_object *receiver;
+    FieldTypes[0] = Context->getObjCIdType();
+    // struct objc_class *super;
+    FieldTypes[1] = Context->getObjCClassType();
+
+    // Create fields
+    for (unsigned i = 0; i < 2; ++i) {
+      SuperStructDecl->addDecl(FieldDecl::Create(*Context, SuperStructDecl,
+                                                 SourceLocation(), 0,
+                                                 FieldTypes[i], 0,
+                                                 /*BitWidth=*/0,
+                                                 /*Mutable=*/false));
+    }
+
+    SuperStructDecl->completeDefinition();
+  }
+  return Context->getTagDeclType(SuperStructDecl);
+}
+
+QualType RewriteObjC::getConstantStringStructType() {
+  if (!ConstantStringDecl) {
+    ConstantStringDecl = RecordDecl::Create(*Context, TagDecl::TK_struct, TUDecl,
+                                            SourceLocation(),
+                         &Context->Idents.get("__NSConstantStringImpl"));
+    QualType FieldTypes[4];
+
+    // struct objc_object *receiver;
+    FieldTypes[0] = Context->getObjCIdType();
+    // int flags;
+    FieldTypes[1] = Context->IntTy;
+    // char *str;
+    FieldTypes[2] = Context->getPointerType(Context->CharTy);
+    // long length;
+    FieldTypes[3] = Context->LongTy;
+
+    // Create fields
+    for (unsigned i = 0; i < 4; ++i) {
+      ConstantStringDecl->addDecl(FieldDecl::Create(*Context,
+                                                    ConstantStringDecl,
+                                                    SourceLocation(), 0,
+                                                    FieldTypes[i], 0,
+                                                    /*BitWidth=*/0,
+                                                    /*Mutable=*/true));
+    }
+
+    ConstantStringDecl->completeDefinition();
+  }
+  return Context->getTagDeclType(ConstantStringDecl);
+}
+
+Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
+                                    SourceLocation StartLoc,
+                                    SourceLocation EndLoc) {
+  if (!SelGetUidFunctionDecl)
+    SynthSelGetUidFunctionDecl();
+  if (!MsgSendFunctionDecl)
+    SynthMsgSendFunctionDecl();
+  if (!MsgSendSuperFunctionDecl)
+    SynthMsgSendSuperFunctionDecl();
+  if (!MsgSendStretFunctionDecl)
+    SynthMsgSendStretFunctionDecl();
+  if (!MsgSendSuperStretFunctionDecl)
+    SynthMsgSendSuperStretFunctionDecl();
+  if (!MsgSendFpretFunctionDecl)
+    SynthMsgSendFpretFunctionDecl();
+  if (!GetClassFunctionDecl)
+    SynthGetClassFunctionDecl();
+  if (!GetSuperClassFunctionDecl)
+    SynthGetSuperClassFunctionDecl();
+  if (!GetMetaClassFunctionDecl)
+    SynthGetMetaClassFunctionDecl();
+
+  // default to objc_msgSend().
+  FunctionDecl *MsgSendFlavor = MsgSendFunctionDecl;
+  // May need to use objc_msgSend_stret() as well.
+  FunctionDecl *MsgSendStretFlavor = 0;
+  if (ObjCMethodDecl *mDecl = Exp->getMethodDecl()) {
+    QualType resultType = mDecl->getResultType();
+    if (resultType->isRecordType())
+      MsgSendStretFlavor = MsgSendStretFunctionDecl;
+    else if (resultType->isRealFloatingType())
+      MsgSendFlavor = MsgSendFpretFunctionDecl;
+  }
+
+  // Synthesize a call to objc_msgSend().
+  llvm::SmallVector<Expr*, 8> MsgExprs;
+  switch (Exp->getReceiverKind()) {
+  case ObjCMessageExpr::SuperClass: {
+    MsgSendFlavor = MsgSendSuperFunctionDecl;
+    if (MsgSendStretFlavor)
+      MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
+    assert(MsgSendFlavor && "MsgSendFlavor is NULL!");
+
+    ObjCInterfaceDecl *ClassDecl = CurMethodDef->getClassInterface();
+
+    llvm::SmallVector<Expr*, 4> InitExprs;
+
+    // set the receiver to self, the first argument to all methods.
+    InitExprs.push_back(
+      NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
+                               CastExpr::CK_Unknown,
+                   new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(),
+                                   Context->getObjCIdType(),
+                                   SourceLocation()))
+                        ); // set the 'receiver'.
+
+    // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
+    llvm::SmallVector<Expr*, 8> ClsExprs;
+    QualType argType = Context->getPointerType(Context->CharTy);
+    ClsExprs.push_back(StringLiteral::Create(*Context,
+                                   ClassDecl->getIdentifier()->getNameStart(),
+                                   ClassDecl->getIdentifier()->getLength(),
+                                   false, argType, SourceLocation()));
+    CallExpr *Cls = SynthesizeCallToFunctionDecl(GetMetaClassFunctionDecl,
+                                                 &ClsExprs[0],
+                                                 ClsExprs.size(),
+                                                 StartLoc,
+                                                 EndLoc);
+    // (Class)objc_getClass("CurrentClass")
+    CastExpr *ArgExpr = NoTypeInfoCStyleCastExpr(Context,
+                                             Context->getObjCClassType(),
+                                             CastExpr::CK_Unknown, Cls);
+    ClsExprs.clear();
+    ClsExprs.push_back(ArgExpr);
+    Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl,
+                                       &ClsExprs[0], ClsExprs.size(),
+                                       StartLoc, EndLoc);
+    
+    // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
+    // To turn off a warning, type-cast to 'id'
+    InitExprs.push_back( // set 'super class', using class_getSuperclass().
+                        NoTypeInfoCStyleCastExpr(Context,
+                                                 Context->getObjCIdType(),
+                                                 CastExpr::CK_Unknown, Cls));
+    // struct objc_super
+    QualType superType = getSuperStructType();
+    Expr *SuperRep;
+
+    if (LangOpts.Microsoft) {
+      SynthSuperContructorFunctionDecl();
+      // Simulate a contructor call...
+      DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperContructorFunctionDecl,
+                                         superType, SourceLocation());
+      SuperRep = new (Context) CallExpr(*Context, DRE, &InitExprs[0],
+                                        InitExprs.size(),
+                                        superType, SourceLocation());
+      // The code for super is a little tricky to prevent collision with
+      // the structure definition in the header. The rewriter has it's own
+      // internal definition (__rw_objc_super) that is uses. This is why
+      // we need the cast below. For example:
+      // (struct objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER"))
+      //
+      SuperRep = new (Context) UnaryOperator(SuperRep, UnaryOperator::AddrOf,
+                               Context->getPointerType(SuperRep->getType()),
+                               SourceLocation());
+      SuperRep = NoTypeInfoCStyleCastExpr(Context,
+                                          Context->getPointerType(superType),
+                                          CastExpr::CK_Unknown, SuperRep);
+    } else {
+      // (struct objc_super) { <exprs from above> }
+      InitListExpr *ILE =
+        new (Context) InitListExpr(*Context, SourceLocation(),
+                                   &InitExprs[0], InitExprs.size(),
+                                   SourceLocation());
+      TypeSourceInfo *superTInfo
+        = Context->getTrivialTypeSourceInfo(superType);
+      SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superTInfo,
+                                                   superType, ILE, false);
+      // struct objc_super *
+      SuperRep = new (Context) UnaryOperator(SuperRep, UnaryOperator::AddrOf,
+                               Context->getPointerType(SuperRep->getType()),
+                               SourceLocation());
+    }
+    MsgExprs.push_back(SuperRep);
+    break;
+  }
+
+  case ObjCMessageExpr::Class: {
+    llvm::SmallVector<Expr*, 8> ClsExprs;
+    QualType argType = Context->getPointerType(Context->CharTy);
+    ObjCInterfaceDecl *Class
+      = Exp->getClassReceiver()->getAs<ObjCInterfaceType>()->getDecl();
+    IdentifierInfo *clsName = Class->getIdentifier();
+    ClsExprs.push_back(StringLiteral::Create(*Context,
+                                             clsName->getNameStart(),
+                                             clsName->getLength(),
+                                             false, argType,
+                                             SourceLocation()));
+    CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
+                                                 &ClsExprs[0],
+                                                 ClsExprs.size(), 
+                                                 StartLoc, EndLoc);
+    MsgExprs.push_back(Cls);
+    break;
+  }
+
+  case ObjCMessageExpr::SuperInstance:{
+    MsgSendFlavor = MsgSendSuperFunctionDecl;
+    if (MsgSendStretFlavor)
+      MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
+    assert(MsgSendFlavor && "MsgSendFlavor is NULL!");
+    ObjCInterfaceDecl *ClassDecl = CurMethodDef->getClassInterface();
+    llvm::SmallVector<Expr*, 4> InitExprs;
+
+    InitExprs.push_back(
+      NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
+                               CastExpr::CK_Unknown,
+                   new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(),
+                                   Context->getObjCIdType(),
+                                   SourceLocation()))
+                        ); // set the 'receiver'.
+    
+    // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
+    llvm::SmallVector<Expr*, 8> ClsExprs;
+    QualType argType = Context->getPointerType(Context->CharTy);
+    ClsExprs.push_back(StringLiteral::Create(*Context,
+                                   ClassDecl->getIdentifier()->getNameStart(),
+                                   ClassDecl->getIdentifier()->getLength(),
+                                   false, argType, SourceLocation()));
+    CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
+                                                 &ClsExprs[0],
+                                                 ClsExprs.size(), 
+                                                 StartLoc, EndLoc);
+    // (Class)objc_getClass("CurrentClass")
+    CastExpr *ArgExpr = NoTypeInfoCStyleCastExpr(Context,
+                                                 Context->getObjCClassType(),
+                                                 CastExpr::CK_Unknown, Cls);
+    ClsExprs.clear();
+    ClsExprs.push_back(ArgExpr);
+    Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl,
+                                       &ClsExprs[0], ClsExprs.size(),
+                                       StartLoc, EndLoc);
+    
+    // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
+    // To turn off a warning, type-cast to 'id'
+    InitExprs.push_back(
+      // set 'super class', using class_getSuperclass().
+      NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
+                               CastExpr::CK_Unknown, Cls));
+    // struct objc_super
+    QualType superType = getSuperStructType();
+    Expr *SuperRep;
+
+    if (LangOpts.Microsoft) {
+      SynthSuperContructorFunctionDecl();
+      // Simulate a contructor call...
+      DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperContructorFunctionDecl,
+                                         superType, SourceLocation());
+      SuperRep = new (Context) CallExpr(*Context, DRE, &InitExprs[0],
+                                        InitExprs.size(),
+                                        superType, SourceLocation());
+      // The code for super is a little tricky to prevent collision with
+      // the structure definition in the header. The rewriter has it's own
+      // internal definition (__rw_objc_super) that is uses. This is why
+      // we need the cast below. For example:
+      // (struct objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER"))
+      //
+      SuperRep = new (Context) UnaryOperator(SuperRep, UnaryOperator::AddrOf,
+                               Context->getPointerType(SuperRep->getType()),
+                               SourceLocation());
+      SuperRep = NoTypeInfoCStyleCastExpr(Context,
+                               Context->getPointerType(superType),
+                               CastExpr::CK_Unknown, SuperRep);
+    } else {
+      // (struct objc_super) { <exprs from above> }
+      InitListExpr *ILE =
+        new (Context) InitListExpr(*Context, SourceLocation(),
+                                   &InitExprs[0], InitExprs.size(),
+                                   SourceLocation());
+      TypeSourceInfo *superTInfo
+        = Context->getTrivialTypeSourceInfo(superType);
+      SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superTInfo,
+                                                   superType, ILE, false);
+    }
+    MsgExprs.push_back(SuperRep);
+    break;
+  }
+
+  case ObjCMessageExpr::Instance: {
+    // Remove all type-casts because it may contain objc-style types; e.g.
+    // Foo<Proto> *.
+    Expr *recExpr = Exp->getInstanceReceiver();
+    while (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(recExpr))
+      recExpr = CE->getSubExpr();
+    recExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
+                                       CastExpr::CK_Unknown, recExpr);
+    MsgExprs.push_back(recExpr);
+    break;
+  }
+  }
+
+  // Create a call to sel_registerName("selName"), it will be the 2nd argument.
+  llvm::SmallVector<Expr*, 8> SelExprs;
+  QualType argType = Context->getPointerType(Context->CharTy);
+  SelExprs.push_back(StringLiteral::Create(*Context,
+                                       Exp->getSelector().getAsString().c_str(),
+                                       Exp->getSelector().getAsString().size(),
+                                       false, argType, SourceLocation()));
+  CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
+                                                 &SelExprs[0], SelExprs.size(),
+                                                  StartLoc,
+                                                  EndLoc);
+  MsgExprs.push_back(SelExp);
+
+  // Now push any user supplied arguments.
+  for (unsigned i = 0; i < Exp->getNumArgs(); i++) {
+    Expr *userExpr = Exp->getArg(i);
+    // Make all implicit casts explicit...ICE comes in handy:-)
+    if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(userExpr)) {
+      // Reuse the ICE type, it is exactly what the doctor ordered.
+      QualType type = ICE->getType()->isObjCQualifiedIdType()
+                                ? Context->getObjCIdType()
+                                : ICE->getType();
+      userExpr = NoTypeInfoCStyleCastExpr(Context, type, CastExpr::CK_Unknown,
+                                          userExpr);
+    }
+    // Make id<P...> cast into an 'id' cast.
+    else if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(userExpr)) {
+      if (CE->getType()->isObjCQualifiedIdType()) {
+        while ((CE = dyn_cast<CStyleCastExpr>(userExpr)))
+          userExpr = CE->getSubExpr();
+        userExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
+                                            CastExpr::CK_Unknown, userExpr);
+      }
+    }
+    MsgExprs.push_back(userExpr);
+    // We've transferred the ownership to MsgExprs. For now, we *don't* null
+    // out the argument in the original expression (since we aren't deleting
+    // the ObjCMessageExpr). See RewritePropertySetter() usage for more info.
+    //Exp->setArg(i, 0);
+  }
+  // Generate the funky cast.
+  CastExpr *cast;
+  llvm::SmallVector<QualType, 8> ArgTypes;
+  QualType returnType;
+
+  // Push 'id' and 'SEL', the 2 implicit arguments.
+  if (MsgSendFlavor == MsgSendSuperFunctionDecl)
+    ArgTypes.push_back(Context->getPointerType(getSuperStructType()));
+  else
+    ArgTypes.push_back(Context->getObjCIdType());
+  ArgTypes.push_back(Context->getObjCSelType());
+  if (ObjCMethodDecl *OMD = Exp->getMethodDecl()) {
+    // Push any user argument types.
+    for (ObjCMethodDecl::param_iterator PI = OMD->param_begin(),
+         E = OMD->param_end(); PI != E; ++PI) {
+      QualType t = (*PI)->getType()->isObjCQualifiedIdType()
+                     ? Context->getObjCIdType()
+                     : (*PI)->getType();
+      // Make sure we convert "t (^)(...)" to "t (*)(...)".
+      if (isTopLevelBlockPointerType(t)) {
+        const BlockPointerType *BPT = t->getAs<BlockPointerType>();
+        t = Context->getPointerType(BPT->getPointeeType());
+      }
+      ArgTypes.push_back(t);
+    }
+    returnType = OMD->getResultType()->isObjCQualifiedIdType()
+                   ? Context->getObjCIdType() : OMD->getResultType();
+    if (isTopLevelBlockPointerType(returnType)) {
+      const BlockPointerType *BPT = returnType->getAs<BlockPointerType>();
+      returnType = Context->getPointerType(BPT->getPointeeType());
+    }
+  } else {
+    returnType = Context->getObjCIdType();
+  }
+  // Get the type, we will need to reference it in a couple spots.
+  QualType msgSendType = MsgSendFlavor->getType();
+
+  // Create a reference to the objc_msgSend() declaration.
+  DeclRefExpr *DRE = new (Context) DeclRefExpr(MsgSendFlavor, msgSendType,
+                                     SourceLocation());
+
+  // Need to cast objc_msgSend to "void *" (to workaround a GCC bandaid).
+  // If we don't do this cast, we get the following bizarre warning/note:
+  // xx.m:13: warning: function called through a non-compatible type
+  // xx.m:13: note: if this code is reached, the program will abort
+  cast = NoTypeInfoCStyleCastExpr(Context,
+                                  Context->getPointerType(Context->VoidTy),
+                                  CastExpr::CK_Unknown, DRE);
+
+  // Now do the "normal" pointer to function cast.
+  QualType castType = Context->getFunctionType(returnType,
+    &ArgTypes[0], ArgTypes.size(),
+    // If we don't have a method decl, force a variadic cast.
+    Exp->getMethodDecl() ? Exp->getMethodDecl()->isVariadic() : true, 0,
+                                               false, false, 0, 0,
+                                               FunctionType::ExtInfo());
+  castType = Context->getPointerType(castType);
+  cast = NoTypeInfoCStyleCastExpr(Context, castType, CastExpr::CK_Unknown,
+                                  cast);
+
+  // Don't forget the parens to enforce the proper binding.
+  ParenExpr *PE = new (Context) ParenExpr(StartLoc, EndLoc, cast);
+
+  const FunctionType *FT = msgSendType->getAs<FunctionType>();
+  CallExpr *CE = new (Context) CallExpr(*Context, PE, &MsgExprs[0],
+                                        MsgExprs.size(),
+                                        FT->getResultType(), EndLoc);
+  Stmt *ReplacingStmt = CE;
+  if (MsgSendStretFlavor) {
+    // We have the method which returns a struct/union. Must also generate
+    // call to objc_msgSend_stret and hang both varieties on a conditional
+    // expression which dictate which one to envoke depending on size of
+    // method's return type.
+
+    // Create a reference to the objc_msgSend_stret() declaration.
+    DeclRefExpr *STDRE = new (Context) DeclRefExpr(MsgSendStretFlavor, msgSendType,
+                                         SourceLocation());
+    // Need to cast objc_msgSend_stret to "void *" (see above comment).
+    cast = NoTypeInfoCStyleCastExpr(Context,
+                                    Context->getPointerType(Context->VoidTy),
+                                    CastExpr::CK_Unknown, STDRE);
+    // Now do the "normal" pointer to function cast.
+    castType = Context->getFunctionType(returnType,
+      &ArgTypes[0], ArgTypes.size(),
+      Exp->getMethodDecl() ? Exp->getMethodDecl()->isVariadic() : false, 0,
+                                        false, false, 0, 0,
+                                        FunctionType::ExtInfo());
+    castType = Context->getPointerType(castType);
+    cast = NoTypeInfoCStyleCastExpr(Context, castType, CastExpr::CK_Unknown,
+                                    cast);
+
+    // Don't forget the parens to enforce the proper binding.
+    PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), cast);
+
+    FT = msgSendType->getAs<FunctionType>();
+    CallExpr *STCE = new (Context) CallExpr(*Context, PE, &MsgExprs[0],
+                                            MsgExprs.size(),
+                                            FT->getResultType(), SourceLocation());
+
+    // Build sizeof(returnType)
+    SizeOfAlignOfExpr *sizeofExpr = new (Context) SizeOfAlignOfExpr(true,
+                            Context->getTrivialTypeSourceInfo(returnType),
+                                      Context->getSizeType(),
+                                      SourceLocation(), SourceLocation());
+    // (sizeof(returnType) <= 8 ? objc_msgSend(...) : objc_msgSend_stret(...))
+    // FIXME: Value of 8 is base on ppc32/x86 ABI for the most common cases.
+    // For X86 it is more complicated and some kind of target specific routine
+    // is needed to decide what to do.
+    unsigned IntSize =
+      static_cast<unsigned>(Context->getTypeSize(Context->IntTy));
+    IntegerLiteral *limit = new (Context) IntegerLiteral(llvm::APInt(IntSize, 8),
+                                               Context->IntTy,
+                                               SourceLocation());
+    BinaryOperator *lessThanExpr = new (Context) BinaryOperator(sizeofExpr, limit,
+                                                      BinaryOperator::LE,
+                                                      Context->IntTy,
+                                                      SourceLocation());
+    // (sizeof(returnType) <= 8 ? objc_msgSend(...) : objc_msgSend_stret(...))
+    ConditionalOperator *CondExpr =
+      new (Context) ConditionalOperator(lessThanExpr,
+                                        SourceLocation(), CE,
+                                        SourceLocation(), STCE, returnType);
+    ReplacingStmt = new (Context) ParenExpr(SourceLocation(), SourceLocation(), CondExpr);
+  }
+  // delete Exp; leak for now, see RewritePropertySetter() usage for more info.
+  return ReplacingStmt;
+}
+
+Stmt *RewriteObjC::RewriteMessageExpr(ObjCMessageExpr *Exp) {
+  Stmt *ReplacingStmt = SynthMessageExpr(Exp, Exp->getLocStart(),
+                                         Exp->getLocEnd());
+
+  // Now do the actual rewrite.
+  ReplaceStmt(Exp, ReplacingStmt);
+
+  // delete Exp; leak for now, see RewritePropertySetter() usage for more info.
+  return ReplacingStmt;
+}
+
+// typedef struct objc_object Protocol;
+QualType RewriteObjC::getProtocolType() {
+  if (!ProtocolTypeDecl) {
+    TypeSourceInfo *TInfo
+      = Context->getTrivialTypeSourceInfo(Context->getObjCIdType());
+    ProtocolTypeDecl = TypedefDecl::Create(*Context, TUDecl,
+                                           SourceLocation(),
+                                           &Context->Idents.get("Protocol"),
+                                           TInfo);
+  }
+  return Context->getTypeDeclType(ProtocolTypeDecl);
+}
+
+/// RewriteObjCProtocolExpr - Rewrite a protocol expression into
+/// a synthesized/forward data reference (to the protocol's metadata).
+/// The forward references (and metadata) are generated in
+/// RewriteObjC::HandleTranslationUnit().
+Stmt *RewriteObjC::RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp) {
+  std::string Name = "_OBJC_PROTOCOL_" + Exp->getProtocol()->getNameAsString();
+  IdentifierInfo *ID = &Context->Idents.get(Name);
+  VarDecl *VD = VarDecl::Create(*Context, TUDecl, SourceLocation(),
+                                ID, getProtocolType(), 0,
+                                VarDecl::Extern, VarDecl::None);
+  DeclRefExpr *DRE = new (Context) DeclRefExpr(VD, getProtocolType(), SourceLocation());
+  Expr *DerefExpr = new (Context) UnaryOperator(DRE, UnaryOperator::AddrOf,
+                             Context->getPointerType(DRE->getType()),
+                             SourceLocation());
+  CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, DerefExpr->getType(),
+                                                CastExpr::CK_Unknown,
+                                                DerefExpr);
+  ReplaceStmt(Exp, castExpr);
+  ProtocolExprDecls.insert(Exp->getProtocol());
+  // delete Exp; leak for now, see RewritePropertySetter() usage for more info.
+  return castExpr;
+
+}
+
+bool RewriteObjC::BufferContainsPPDirectives(const char *startBuf,
+                                             const char *endBuf) {
+  while (startBuf < endBuf) {
+    if (*startBuf == '#') {
+      // Skip whitespace.
+      for (++startBuf; startBuf[0] == ' ' || startBuf[0] == '\t'; ++startBuf)
+        ;
+      if (!strncmp(startBuf, "if", strlen("if")) ||
+          !strncmp(startBuf, "ifdef", strlen("ifdef")) ||
+          !strncmp(startBuf, "ifndef", strlen("ifndef")) ||
+          !strncmp(startBuf, "define", strlen("define")) ||
+          !strncmp(startBuf, "undef", strlen("undef")) ||
+          !strncmp(startBuf, "else", strlen("else")) ||
+          !strncmp(startBuf, "elif", strlen("elif")) ||
+          !strncmp(startBuf, "endif", strlen("endif")) ||
+          !strncmp(startBuf, "pragma", strlen("pragma")) ||
+          !strncmp(startBuf, "include", strlen("include")) ||
+          !strncmp(startBuf, "import", strlen("import")) ||
+          !strncmp(startBuf, "include_next", strlen("include_next")))
+        return true;
+    }
+    startBuf++;
+  }
+  return false;
+}
+
+/// SynthesizeObjCInternalStruct - Rewrite one internal struct corresponding to
+/// an objective-c class with ivars.
+void RewriteObjC::SynthesizeObjCInternalStruct(ObjCInterfaceDecl *CDecl,
+                                               std::string &Result) {
+  assert(CDecl && "Class missing in SynthesizeObjCInternalStruct");
+  assert(CDecl->getNameAsCString() &&
+         "Name missing in SynthesizeObjCInternalStruct");
+  // Do not synthesize more than once.
+  if (ObjCSynthesizedStructs.count(CDecl))
+    return;
+  ObjCInterfaceDecl *RCDecl = CDecl->getSuperClass();
+  int NumIvars = CDecl->ivar_size();
+  SourceLocation LocStart = CDecl->getLocStart();
+  SourceLocation LocEnd = CDecl->getLocEnd();
+
+  const char *startBuf = SM->getCharacterData(LocStart);
+  const char *endBuf = SM->getCharacterData(LocEnd);
+
+  // If no ivars and no root or if its root, directly or indirectly,
+  // have no ivars (thus not synthesized) then no need to synthesize this class.
+  if ((CDecl->isForwardDecl() || NumIvars == 0) &&
+      (!RCDecl || !ObjCSynthesizedStructs.count(RCDecl))) {
+    endBuf += Lexer::MeasureTokenLength(LocEnd, *SM, LangOpts);
+    ReplaceText(LocStart, endBuf-startBuf, Result);
+    return;
+  }
+
+  // FIXME: This has potential of causing problem. If
+  // SynthesizeObjCInternalStruct is ever called recursively.
+  Result += "\nstruct ";
+  Result += CDecl->getNameAsString();
+  if (LangOpts.Microsoft)
+    Result += "_IMPL";
+
+  if (NumIvars > 0) {
+    const char *cursor = strchr(startBuf, '{');
+    assert((cursor && endBuf)
+           && "SynthesizeObjCInternalStruct - malformed @interface");
+    // If the buffer contains preprocessor directives, we do more fine-grained
+    // rewrites. This is intended to fix code that looks like (which occurs in
+    // NSURL.h, for example):
+    //
+    // #ifdef XYZ
+    // @interface Foo : NSObject
+    // #else
+    // @interface FooBar : NSObject
+    // #endif
+    // {
+    //    int i;
+    // }
+    // @end
+    //
+    // This clause is segregated to avoid breaking the common case.
+    if (BufferContainsPPDirectives(startBuf, cursor)) {
+      SourceLocation L = RCDecl ? CDecl->getSuperClassLoc() :
+                                  CDecl->getClassLoc();
+      const char *endHeader = SM->getCharacterData(L);
+      endHeader += Lexer::MeasureTokenLength(L, *SM, LangOpts);
+
+      if (CDecl->protocol_begin() != CDecl->protocol_end()) {
+        // advance to the end of the referenced protocols.
+        while (endHeader < cursor && *endHeader != '>') endHeader++;
+        endHeader++;
+      }
+      // rewrite the original header
+      ReplaceText(LocStart, endHeader-startBuf, Result);
+    } else {
+      // rewrite the original header *without* disturbing the '{'
+      ReplaceText(LocStart, cursor-startBuf, Result);
+    }
+    if (RCDecl && ObjCSynthesizedStructs.count(RCDecl)) {
+      Result = "\n    struct ";
+      Result += RCDecl->getNameAsString();
+      Result += "_IMPL ";
+      Result += RCDecl->getNameAsString();
+      Result += "_IVARS;\n";
+
+      // insert the super class structure definition.
+      SourceLocation OnePastCurly =
+        LocStart.getFileLocWithOffset(cursor-startBuf+1);
+      InsertText(OnePastCurly, Result);
+    }
+    cursor++; // past '{'
+
+    // Now comment out any visibility specifiers.
+    while (cursor < endBuf) {
+      if (*cursor == '@') {
+        SourceLocation atLoc = LocStart.getFileLocWithOffset(cursor-startBuf);
+        // Skip whitespace.
+        for (++cursor; cursor[0] == ' ' || cursor[0] == '\t'; ++cursor)
+          /*scan*/;
+
+        // FIXME: presence of @public, etc. inside comment results in
+        // this transformation as well, which is still correct c-code.
+        if (!strncmp(cursor, "public", strlen("public")) ||
+            !strncmp(cursor, "private", strlen("private")) ||
+            !strncmp(cursor, "package", strlen("package")) ||
+            !strncmp(cursor, "protected", strlen("protected")))
+          InsertText(atLoc, "// ");
+      }
+      // FIXME: If there are cases where '<' is used in ivar declaration part
+      // of user code, then scan the ivar list and use needToScanForQualifiers
+      // for type checking.
+      else if (*cursor == '<') {
+        SourceLocation atLoc = LocStart.getFileLocWithOffset(cursor-startBuf);
+        InsertText(atLoc, "/* ");
+        cursor = strchr(cursor, '>');
+        cursor++;
+        atLoc = LocStart.getFileLocWithOffset(cursor-startBuf);
+        InsertText(atLoc, " */");
+      } else if (*cursor == '^') { // rewrite block specifier.
+        SourceLocation caretLoc = LocStart.getFileLocWithOffset(cursor-startBuf);
+        ReplaceText(caretLoc, 1, "*");
+      }
+      cursor++;
+    }
+    // Don't forget to add a ';'!!
+    InsertText(LocEnd.getFileLocWithOffset(1), ";");
+  } else { // we don't have any instance variables - insert super struct.
+    endBuf += Lexer::MeasureTokenLength(LocEnd, *SM, LangOpts);
+    Result += " {\n    struct ";
+    Result += RCDecl->getNameAsString();
+    Result += "_IMPL ";
+    Result += RCDecl->getNameAsString();
+    Result += "_IVARS;\n};\n";
+    ReplaceText(LocStart, endBuf-startBuf, Result);
+  }
+  // Mark this struct as having been generated.
+  if (!ObjCSynthesizedStructs.insert(CDecl))
+    assert(false && "struct already synthesize- SynthesizeObjCInternalStruct");
+}
+
+// RewriteObjCMethodsMetaData - Rewrite methods metadata for instance or
+/// class methods.
+template<typename MethodIterator>
+void RewriteObjC::RewriteObjCMethodsMetaData(MethodIterator MethodBegin,
+                                             MethodIterator MethodEnd,
+                                             bool IsInstanceMethod,
+                                             const char *prefix,
+                                             const char *ClassName,
+                                             std::string &Result) {
+  if (MethodBegin == MethodEnd) return;
+
+  if (!objc_impl_method) {
+    /* struct _objc_method {
+       SEL _cmd;
+       char *method_types;
+       void *_imp;
+       }
+     */
+    Result += "\nstruct _objc_method {\n";
+    Result += "\tSEL _cmd;\n";
+    Result += "\tchar *method_types;\n";
+    Result += "\tvoid *_imp;\n";
+    Result += "};\n";
+
+    objc_impl_method = true;
+  }
+
+  // Build _objc_method_list for class's methods if needed
+
+  /* struct  {
+   struct _objc_method_list *next_method;
+   int method_count;
+   struct _objc_method method_list[];
+   }
+   */
+  unsigned NumMethods = std::distance(MethodBegin, MethodEnd);
+  Result += "\nstatic struct {\n";
+  Result += "\tstruct _objc_method_list *next_method;\n";
+  Result += "\tint method_count;\n";
+  Result += "\tstruct _objc_method method_list[";
+  Result += utostr(NumMethods);
+  Result += "];\n} _OBJC_";
+  Result += prefix;
+  Result += IsInstanceMethod ? "INSTANCE" : "CLASS";
+  Result += "_METHODS_";
+  Result += ClassName;
+  Result += " __attribute__ ((used, section (\"__OBJC, __";
+  Result += IsInstanceMethod ? "inst" : "cls";
+  Result += "_meth\")))= ";
+  Result += "{\n\t0, " + utostr(NumMethods) + "\n";
+
+  Result += "\t,{{(SEL)\"";
+  Result += (*MethodBegin)->getSelector().getAsString().c_str();
+  std::string MethodTypeString;
+  Context->getObjCEncodingForMethodDecl(*MethodBegin, MethodTypeString);
+  Result += "\", \"";
+  Result += MethodTypeString;
+  Result += "\", (void *)";
+  Result += MethodInternalNames[*MethodBegin];
+  Result += "}\n";
+  for (++MethodBegin; MethodBegin != MethodEnd; ++MethodBegin) {
+    Result += "\t  ,{(SEL)\"";
+    Result += (*MethodBegin)->getSelector().getAsString().c_str();
+    std::string MethodTypeString;
+    Context->getObjCEncodingForMethodDecl(*MethodBegin, MethodTypeString);
+    Result += "\", \"";
+    Result += MethodTypeString;
+    Result += "\", (void *)";
+    Result += MethodInternalNames[*MethodBegin];
+    Result += "}\n";
+  }
+  Result += "\t }\n};\n";
+}
+
+/// RewriteObjCProtocolMetaData - Rewrite protocols meta-data.
+void RewriteObjC::
+RewriteObjCProtocolMetaData(ObjCProtocolDecl *PDecl, const char *prefix,
+                            const char *ClassName, std::string &Result) {
+  static bool objc_protocol_methods = false;
+
+  // Output struct protocol_methods holder of method selector and type.
+  if (!objc_protocol_methods && !PDecl->isForwardDecl()) {
+    /* struct protocol_methods {
+     SEL _cmd;
+     char *method_types;
+     }
+     */
+    Result += "\nstruct _protocol_methods {\n";
+    Result += "\tstruct objc_selector *_cmd;\n";
+    Result += "\tchar *method_types;\n";
+    Result += "};\n";
+
+    objc_protocol_methods = true;
+  }
+  // Do not synthesize the protocol more than once.
+  if (ObjCSynthesizedProtocols.count(PDecl))
+    return;
+
+    if (PDecl->instmeth_begin() != PDecl->instmeth_end()) {
+      unsigned NumMethods = std::distance(PDecl->instmeth_begin(),
+                                          PDecl->instmeth_end());
+    /* struct _objc_protocol_method_list {
+     int protocol_method_count;
+     struct protocol_methods protocols[];
+     }
+     */
+    Result += "\nstatic struct {\n";
+    Result += "\tint protocol_method_count;\n";
+    Result += "\tstruct _protocol_methods protocol_methods[";
+    Result += utostr(NumMethods);
+    Result += "];\n} _OBJC_PROTOCOL_INSTANCE_METHODS_";
+    Result += PDecl->getNameAsString();
+    Result += " __attribute__ ((used, section (\"__OBJC, __cat_inst_meth\")))= "
+      "{\n\t" + utostr(NumMethods) + "\n";
+
+    // Output instance methods declared in this protocol.
+    for (ObjCProtocolDecl::instmeth_iterator
+           I = PDecl->instmeth_begin(), E = PDecl->instmeth_end();
+         I != E; ++I) {
+      if (I == PDecl->instmeth_begin())
+        Result += "\t  ,{{(struct objc_selector *)\"";
+      else
+        Result += "\t  ,{(struct objc_selector *)\"";
+      Result += (*I)->getSelector().getAsString().c_str();
+      std::string MethodTypeString;
+      Context->getObjCEncodingForMethodDecl((*I), MethodTypeString);
+      Result += "\", \"";
+      Result += MethodTypeString;
+      Result += "\"}\n";
+    }
+    Result += "\t }\n};\n";
+  }
+
+  // Output class methods declared in this protocol.
+  unsigned NumMethods = std::distance(PDecl->classmeth_begin(),
+                                      PDecl->classmeth_end());
+  if (NumMethods > 0) {
+    /* struct _objc_protocol_method_list {
+     int protocol_method_count;
+     struct protocol_methods protocols[];
+     }
+     */
+    Result += "\nstatic struct {\n";
+    Result += "\tint protocol_method_count;\n";
+    Result += "\tstruct _protocol_methods protocol_methods[";
+    Result += utostr(NumMethods);
+    Result += "];\n} _OBJC_PROTOCOL_CLASS_METHODS_";
+    Result += PDecl->getNameAsString();
+    Result += " __attribute__ ((used, section (\"__OBJC, __cat_cls_meth\")))= "
+           "{\n\t";
+    Result += utostr(NumMethods);
+    Result += "\n";
+
+    // Output instance methods declared in this protocol.
+    for (ObjCProtocolDecl::classmeth_iterator
+           I = PDecl->classmeth_begin(), E = PDecl->classmeth_end();
+         I != E; ++I) {
+      if (I == PDecl->classmeth_begin())
+        Result += "\t  ,{{(struct objc_selector *)\"";
+      else
+        Result += "\t  ,{(struct objc_selector *)\"";
+      Result += (*I)->getSelector().getAsString().c_str();
+      std::string MethodTypeString;
+      Context->getObjCEncodingForMethodDecl((*I), MethodTypeString);
+      Result += "\", \"";
+      Result += MethodTypeString;
+      Result += "\"}\n";
+    }
+    Result += "\t }\n};\n";
+  }
+
+  // Output:
+  /* struct _objc_protocol {
+   // Objective-C 1.0 extensions
+   struct _objc_protocol_extension *isa;
+   char *protocol_name;
+   struct _objc_protocol **protocol_list;
+   struct _objc_protocol_method_list *instance_methods;
+   struct _objc_protocol_method_list *class_methods;
+   };
+   */
+  static bool objc_protocol = false;
+  if (!objc_protocol) {
+    Result += "\nstruct _objc_protocol {\n";
+    Result += "\tstruct _objc_protocol_extension *isa;\n";
+    Result += "\tchar *protocol_name;\n";
+    Result += "\tstruct _objc_protocol **protocol_list;\n";
+    Result += "\tstruct _objc_protocol_method_list *instance_methods;\n";
+    Result += "\tstruct _objc_protocol_method_list *class_methods;\n";
+    Result += "};\n";
+
+    objc_protocol = true;
+  }
+
+  Result += "\nstatic struct _objc_protocol _OBJC_PROTOCOL_";
+  Result += PDecl->getNameAsString();
+  Result += " __attribute__ ((used, section (\"__OBJC, __protocol\")))= "
+    "{\n\t0, \"";
+  Result += PDecl->getNameAsString();
+  Result += "\", 0, ";
+  if (PDecl->instmeth_begin() != PDecl->instmeth_end()) {
+    Result += "(struct _objc_protocol_method_list *)&_OBJC_PROTOCOL_INSTANCE_METHODS_";
+    Result += PDecl->getNameAsString();
+    Result += ", ";
+  }
+  else
+    Result += "0, ";
+  if (PDecl->classmeth_begin() != PDecl->classmeth_end()) {
+    Result += "(struct _objc_protocol_method_list *)&_OBJC_PROTOCOL_CLASS_METHODS_";
+    Result += PDecl->getNameAsString();
+    Result += "\n";
+  }
+  else
+    Result += "0\n";
+  Result += "};\n";
+
+  // Mark this protocol as having been generated.
+  if (!ObjCSynthesizedProtocols.insert(PDecl))
+    assert(false && "protocol already synthesized");
+
+}
+
+void RewriteObjC::
+RewriteObjCProtocolListMetaData(const ObjCList<ObjCProtocolDecl> &Protocols,
+                                const char *prefix, const char *ClassName,
+                                std::string &Result) {
+  if (Protocols.empty()) return;
+
+  for (unsigned i = 0; i != Protocols.size(); i++)
+    RewriteObjCProtocolMetaData(Protocols[i], prefix, ClassName, Result);
+
+  // Output the top lovel protocol meta-data for the class.
+  /* struct _objc_protocol_list {
+   struct _objc_protocol_list *next;
+   int    protocol_count;
+   struct _objc_protocol *class_protocols[];
+   }
+   */
+  Result += "\nstatic struct {\n";
+  Result += "\tstruct _objc_protocol_list *next;\n";
+  Result += "\tint    protocol_count;\n";
+  Result += "\tstruct _objc_protocol *class_protocols[";
+  Result += utostr(Protocols.size());
+  Result += "];\n} _OBJC_";
+  Result += prefix;
+  Result += "_PROTOCOLS_";
+  Result += ClassName;
+  Result += " __attribute__ ((used, section (\"__OBJC, __cat_cls_meth\")))= "
+    "{\n\t0, ";
+  Result += utostr(Protocols.size());
+  Result += "\n";
+
+  Result += "\t,{&_OBJC_PROTOCOL_";
+  Result += Protocols[0]->getNameAsString();
+  Result += " \n";
+
+  for (unsigned i = 1; i != Protocols.size(); i++) {
+    Result += "\t ,&_OBJC_PROTOCOL_";
+    Result += Protocols[i]->getNameAsString();
+    Result += "\n";
+  }
+  Result += "\t }\n};\n";
+}
+
+
+/// RewriteObjCCategoryImplDecl - Rewrite metadata for each category
+/// implementation.
+void RewriteObjC::RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *IDecl,
+                                              std::string &Result) {
+  ObjCInterfaceDecl *ClassDecl = IDecl->getClassInterface();
+  // Find category declaration for this implementation.
+  ObjCCategoryDecl *CDecl;
+  for (CDecl = ClassDecl->getCategoryList(); CDecl;
+       CDecl = CDecl->getNextClassCategory())
+    if (CDecl->getIdentifier() == IDecl->getIdentifier())
+      break;
+
+  std::string FullCategoryName = ClassDecl->getNameAsString();
+  FullCategoryName += '_';
+  FullCategoryName += IDecl->getNameAsString();
+
+  // Build _objc_method_list for class's instance methods if needed
+  llvm::SmallVector<ObjCMethodDecl *, 32>
+    InstanceMethods(IDecl->instmeth_begin(), IDecl->instmeth_end());
+
+  // If any of our property implementations have associated getters or
+  // setters, produce metadata for them as well.
+  for (ObjCImplDecl::propimpl_iterator Prop = IDecl->propimpl_begin(),
+         PropEnd = IDecl->propimpl_end();
+       Prop != PropEnd; ++Prop) {
+    if ((*Prop)->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
+      continue;
+    if (!(*Prop)->getPropertyIvarDecl())
+      continue;
+    ObjCPropertyDecl *PD = (*Prop)->getPropertyDecl();
+    if (!PD)
+      continue;
+    if (ObjCMethodDecl *Getter = PD->getGetterMethodDecl())
+      InstanceMethods.push_back(Getter);
+    if (PD->isReadOnly())
+      continue;
+    if (ObjCMethodDecl *Setter = PD->getSetterMethodDecl())
+      InstanceMethods.push_back(Setter);
+  }
+  RewriteObjCMethodsMetaData(InstanceMethods.begin(), InstanceMethods.end(),
+                             true, "CATEGORY_", FullCategoryName.c_str(),
+                             Result);
+
+  // Build _objc_method_list for class's class methods if needed
+  RewriteObjCMethodsMetaData(IDecl->classmeth_begin(), IDecl->classmeth_end(),
+                             false, "CATEGORY_", FullCategoryName.c_str(),
+                             Result);
+
+  // Protocols referenced in class declaration?
+  // Null CDecl is case of a category implementation with no category interface
+  if (CDecl)
+    RewriteObjCProtocolListMetaData(CDecl->getReferencedProtocols(), "CATEGORY",
+                                    FullCategoryName.c_str(), Result);
+  /* struct _objc_category {
+   char *category_name;
+   char *class_name;
+   struct _objc_method_list *instance_methods;
+   struct _objc_method_list *class_methods;
+   struct _objc_protocol_list *protocols;
+   // Objective-C 1.0 extensions
+   uint32_t size;     // sizeof (struct _objc_category)
+   struct _objc_property_list *instance_properties;  // category's own
+                                                     // @property decl.
+   };
+   */
+
+  static bool objc_category = false;
+  if (!objc_category) {
+    Result += "\nstruct _objc_category {\n";
+    Result += "\tchar *category_name;\n";
+    Result += "\tchar *class_name;\n";
+    Result += "\tstruct _objc_method_list *instance_methods;\n";
+    Result += "\tstruct _objc_method_list *class_methods;\n";
+    Result += "\tstruct _objc_protocol_list *protocols;\n";
+    Result += "\tunsigned int size;\n";
+    Result += "\tstruct _objc_property_list *instance_properties;\n";
+    Result += "};\n";
+    objc_category = true;
+  }
+  Result += "\nstatic struct _objc_category _OBJC_CATEGORY_";
+  Result += FullCategoryName;
+  Result += " __attribute__ ((used, section (\"__OBJC, __category\")))= {\n\t\"";
+  Result += IDecl->getNameAsString();
+  Result += "\"\n\t, \"";
+  Result += ClassDecl->getNameAsString();
+  Result += "\"\n";
+
+  if (IDecl->instmeth_begin() != IDecl->instmeth_end()) {
+    Result += "\t, (struct _objc_method_list *)"
+           "&_OBJC_CATEGORY_INSTANCE_METHODS_";
+    Result += FullCategoryName;
+    Result += "\n";
+  }
+  else
+    Result += "\t, 0\n";
+  if (IDecl->classmeth_begin() != IDecl->classmeth_end()) {
+    Result += "\t, (struct _objc_method_list *)"
+           "&_OBJC_CATEGORY_CLASS_METHODS_";
+    Result += FullCategoryName;
+    Result += "\n";
+  }
+  else
+    Result += "\t, 0\n";
+
+  if (CDecl && CDecl->protocol_begin() != CDecl->protocol_end()) {
+    Result += "\t, (struct _objc_protocol_list *)&_OBJC_CATEGORY_PROTOCOLS_";
+    Result += FullCategoryName;
+    Result += "\n";
+  }
+  else
+    Result += "\t, 0\n";
+  Result += "\t, sizeof(struct _objc_category), 0\n};\n";
+}
+
+/// SynthesizeIvarOffsetComputation - This rutine synthesizes computation of
+/// ivar offset.
+void RewriteObjC::SynthesizeIvarOffsetComputation(ObjCContainerDecl *IDecl,
+                                                  ObjCIvarDecl *ivar,
+                                                  std::string &Result) {
+  if (ivar->isBitField()) {
+    // FIXME: The hack below doesn't work for bitfields. For now, we simply
+    // place all bitfields at offset 0.
+    Result += "0";
+  } else {
+    Result += "__OFFSETOFIVAR__(struct ";
+    Result += IDecl->getNameAsString();
+    if (LangOpts.Microsoft)
+      Result += "_IMPL";
+    Result += ", ";
+    Result += ivar->getNameAsString();
+    Result += ")";
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// Meta Data Emission
+//===----------------------------------------------------------------------===//
+
+void RewriteObjC::RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl,
+                                           std::string &Result) {
+  ObjCInterfaceDecl *CDecl = IDecl->getClassInterface();
+
+  // Explictly declared @interface's are already synthesized.
+  if (CDecl->isImplicitInterfaceDecl()) {
+    // FIXME: Implementation of a class with no @interface (legacy) doese not
+    // produce correct synthesis as yet.
+    SynthesizeObjCInternalStruct(CDecl, Result);
+  }
+
+  // Build _objc_ivar_list metadata for classes ivars if needed
+  unsigned NumIvars = !IDecl->ivar_empty()
+                      ? IDecl->ivar_size()
+                      : (CDecl ? CDecl->ivar_size() : 0);
+  if (NumIvars > 0) {
+    static bool objc_ivar = false;
+    if (!objc_ivar) {
+      /* struct _objc_ivar {
+          char *ivar_name;
+          char *ivar_type;
+          int ivar_offset;
+        };
+       */
+      Result += "\nstruct _objc_ivar {\n";
+      Result += "\tchar *ivar_name;\n";
+      Result += "\tchar *ivar_type;\n";
+      Result += "\tint ivar_offset;\n";
+      Result += "};\n";
+
+      objc_ivar = true;
+    }
+
+    /* struct {
+       int ivar_count;
+       struct _objc_ivar ivar_list[nIvars];
+       };
+     */
+    Result += "\nstatic struct {\n";
+    Result += "\tint ivar_count;\n";
+    Result += "\tstruct _objc_ivar ivar_list[";
+    Result += utostr(NumIvars);
+    Result += "];\n} _OBJC_INSTANCE_VARIABLES_";
+    Result += IDecl->getNameAsString();
+    Result += " __attribute__ ((used, section (\"__OBJC, __instance_vars\")))= "
+      "{\n\t";
+    Result += utostr(NumIvars);
+    Result += "\n";
+
+    ObjCInterfaceDecl::ivar_iterator IVI, IVE;
+    llvm::SmallVector<ObjCIvarDecl *, 8> IVars;
+    if (!IDecl->ivar_empty()) {
+      for (ObjCInterfaceDecl::ivar_iterator
+             IV = IDecl->ivar_begin(), IVEnd = IDecl->ivar_end();
+           IV != IVEnd; ++IV)
+        IVars.push_back(*IV);
+      IVI = IDecl->ivar_begin();
+      IVE = IDecl->ivar_end();
+    } else {
+      IVI = CDecl->ivar_begin();
+      IVE = CDecl->ivar_end();
+    }
+    Result += "\t,{{\"";
+    Result += (*IVI)->getNameAsString();
+    Result += "\", \"";
+    std::string TmpString, StrEncoding;
+    Context->getObjCEncodingForType((*IVI)->getType(), TmpString, *IVI);
+    QuoteDoublequotes(TmpString, StrEncoding);
+    Result += StrEncoding;
+    Result += "\", ";
+    SynthesizeIvarOffsetComputation(IDecl, *IVI, Result);
+    Result += "}\n";
+    for (++IVI; IVI != IVE; ++IVI) {
+      Result += "\t  ,{\"";
+      Result += (*IVI)->getNameAsString();
+      Result += "\", \"";
+      std::string TmpString, StrEncoding;
+      Context->getObjCEncodingForType((*IVI)->getType(), TmpString, *IVI);
+      QuoteDoublequotes(TmpString, StrEncoding);
+      Result += StrEncoding;
+      Result += "\", ";
+      SynthesizeIvarOffsetComputation(IDecl, (*IVI), Result);
+      Result += "}\n";
+    }
+
+    Result += "\t }\n};\n";
+  }
+
+  // Build _objc_method_list for class's instance methods if needed
+  llvm::SmallVector<ObjCMethodDecl *, 32>
+    InstanceMethods(IDecl->instmeth_begin(), IDecl->instmeth_end());
+
+  // If any of our property implementations have associated getters or
+  // setters, produce metadata for them as well.
+  for (ObjCImplDecl::propimpl_iterator Prop = IDecl->propimpl_begin(),
+         PropEnd = IDecl->propimpl_end();
+       Prop != PropEnd; ++Prop) {
+    if ((*Prop)->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
+      continue;
+    if (!(*Prop)->getPropertyIvarDecl())
+      continue;
+    ObjCPropertyDecl *PD = (*Prop)->getPropertyDecl();
+    if (!PD)
+      continue;
+    if (ObjCMethodDecl *Getter = PD->getGetterMethodDecl())
+      InstanceMethods.push_back(Getter);
+    if (PD->isReadOnly())
+      continue;
+    if (ObjCMethodDecl *Setter = PD->getSetterMethodDecl())
+      InstanceMethods.push_back(Setter);
+  }
+  RewriteObjCMethodsMetaData(InstanceMethods.begin(), InstanceMethods.end(),
+                             true, "", IDecl->getNameAsCString(), Result);
+
+  // Build _objc_method_list for class's class methods if needed
+  RewriteObjCMethodsMetaData(IDecl->classmeth_begin(), IDecl->classmeth_end(),
+                             false, "", IDecl->getNameAsCString(), Result);
+
+  // Protocols referenced in class declaration?
+  RewriteObjCProtocolListMetaData(CDecl->getReferencedProtocols(),
+                                  "CLASS", CDecl->getNameAsCString(), Result);
+
+  // Declaration of class/meta-class metadata
+  /* struct _objc_class {
+   struct _objc_class *isa; // or const char *root_class_name when metadata
+   const char *super_class_name;
+   char *name;
+   long version;
+   long info;
+   long instance_size;
+   struct _objc_ivar_list *ivars;
+   struct _objc_method_list *methods;
+   struct objc_cache *cache;
+   struct objc_protocol_list *protocols;
+   const char *ivar_layout;
+   struct _objc_class_ext  *ext;
+   };
+  */
+  static bool objc_class = false;
+  if (!objc_class) {
+    Result += "\nstruct _objc_class {\n";
+    Result += "\tstruct _objc_class *isa;\n";
+    Result += "\tconst char *super_class_name;\n";
+    Result += "\tchar *name;\n";
+    Result += "\tlong version;\n";
+    Result += "\tlong info;\n";
+    Result += "\tlong instance_size;\n";
+    Result += "\tstruct _objc_ivar_list *ivars;\n";
+    Result += "\tstruct _objc_method_list *methods;\n";
+    Result += "\tstruct objc_cache *cache;\n";
+    Result += "\tstruct _objc_protocol_list *protocols;\n";
+    Result += "\tconst char *ivar_layout;\n";
+    Result += "\tstruct _objc_class_ext  *ext;\n";
+    Result += "};\n";
+    objc_class = true;
+  }
+
+  // Meta-class metadata generation.
+  ObjCInterfaceDecl *RootClass = 0;
+  ObjCInterfaceDecl *SuperClass = CDecl->getSuperClass();
+  while (SuperClass) {
+    RootClass = SuperClass;
+    SuperClass = SuperClass->getSuperClass();
+  }
+  SuperClass = CDecl->getSuperClass();
+
+  Result += "\nstatic struct _objc_class _OBJC_METACLASS_";
+  Result += CDecl->getNameAsString();
+  Result += " __attribute__ ((used, section (\"__OBJC, __meta_class\")))= "
+  "{\n\t(struct _objc_class *)\"";
+  Result += (RootClass ? RootClass->getNameAsString() : CDecl->getNameAsString());
+  Result += "\"";
+
+  if (SuperClass) {
+    Result += ", \"";
+    Result += SuperClass->getNameAsString();
+    Result += "\", \"";
+    Result += CDecl->getNameAsString();
+    Result += "\"";
+  }
+  else {
+    Result += ", 0, \"";
+    Result += CDecl->getNameAsString();
+    Result += "\"";
+  }
+  // Set 'ivars' field for root class to 0. ObjC1 runtime does not use it.
+  // 'info' field is initialized to CLS_META(2) for metaclass
+  Result += ", 0,2, sizeof(struct _objc_class), 0";
+  if (IDecl->classmeth_begin() != IDecl->classmeth_end()) {
+    Result += "\n\t, (struct _objc_method_list *)&_OBJC_CLASS_METHODS_";
+    Result += IDecl->getNameAsString();
+    Result += "\n";
+  }
+  else
+    Result += ", 0\n";
+  if (CDecl->protocol_begin() != CDecl->protocol_end()) {
+    Result += "\t,0, (struct _objc_protocol_list *)&_OBJC_CLASS_PROTOCOLS_";
+    Result += CDecl->getNameAsString();
+    Result += ",0,0\n";
+  }
+  else
+    Result += "\t,0,0,0,0\n";
+  Result += "};\n";
+
+  // class metadata generation.
+  Result += "\nstatic struct _objc_class _OBJC_CLASS_";
+  Result += CDecl->getNameAsString();
+  Result += " __attribute__ ((used, section (\"__OBJC, __class\")))= "
+            "{\n\t&_OBJC_METACLASS_";
+  Result += CDecl->getNameAsString();
+  if (SuperClass) {
+    Result += ", \"";
+    Result += SuperClass->getNameAsString();
+    Result += "\", \"";
+    Result += CDecl->getNameAsString();
+    Result += "\"";
+  }
+  else {
+    Result += ", 0, \"";
+    Result += CDecl->getNameAsString();
+    Result += "\"";
+  }
+  // 'info' field is initialized to CLS_CLASS(1) for class
+  Result += ", 0,1";
+  if (!ObjCSynthesizedStructs.count(CDecl))
+    Result += ",0";
+  else {
+    // class has size. Must synthesize its size.
+    Result += ",sizeof(struct ";
+    Result += CDecl->getNameAsString();
+    if (LangOpts.Microsoft)
+      Result += "_IMPL";
+    Result += ")";
+  }
+  if (NumIvars > 0) {
+    Result += ", (struct _objc_ivar_list *)&_OBJC_INSTANCE_VARIABLES_";
+    Result += CDecl->getNameAsString();
+    Result += "\n\t";
+  }
+  else
+    Result += ",0";
+  if (IDecl->instmeth_begin() != IDecl->instmeth_end()) {
+    Result += ", (struct _objc_method_list *)&_OBJC_INSTANCE_METHODS_";
+    Result += CDecl->getNameAsString();
+    Result += ", 0\n\t";
+  }
+  else
+    Result += ",0,0";
+  if (CDecl->protocol_begin() != CDecl->protocol_end()) {
+    Result += ", (struct _objc_protocol_list*)&_OBJC_CLASS_PROTOCOLS_";
+    Result += CDecl->getNameAsString();
+    Result += ", 0,0\n";
+  }
+  else
+    Result += ",0,0,0\n";
+  Result += "};\n";
+}
+
+/// RewriteImplementations - This routine rewrites all method implementations
+/// and emits meta-data.
+
+void RewriteObjC::RewriteImplementations() {
+  int ClsDefCount = ClassImplementation.size();
+  int CatDefCount = CategoryImplementation.size();
+
+  // Rewrite implemented methods
+  for (int i = 0; i < ClsDefCount; i++)
+    RewriteImplementationDecl(ClassImplementation[i]);
+
+  for (int i = 0; i < CatDefCount; i++)
+    RewriteImplementationDecl(CategoryImplementation[i]);
+}
+
+void RewriteObjC::SynthesizeMetaDataIntoBuffer(std::string &Result) {
+  int ClsDefCount = ClassImplementation.size();
+  int CatDefCount = CategoryImplementation.size();
+  
+  // For each implemented class, write out all its meta data.
+  for (int i = 0; i < ClsDefCount; i++)
+    RewriteObjCClassMetaData(ClassImplementation[i], Result);
+
+  // For each implemented category, write out all its meta data.
+  for (int i = 0; i < CatDefCount; i++)
+    RewriteObjCCategoryImplDecl(CategoryImplementation[i], Result);
+
+  // Write objc_symtab metadata
+  /*
+   struct _objc_symtab
+   {
+   long sel_ref_cnt;
+   SEL *refs;
+   short cls_def_cnt;
+   short cat_def_cnt;
+   void *defs[cls_def_cnt + cat_def_cnt];
+   };
+   */
+
+  Result += "\nstruct _objc_symtab {\n";
+  Result += "\tlong sel_ref_cnt;\n";
+  Result += "\tSEL *refs;\n";
+  Result += "\tshort cls_def_cnt;\n";
+  Result += "\tshort cat_def_cnt;\n";
+  Result += "\tvoid *defs[" + utostr(ClsDefCount + CatDefCount)+ "];\n";
+  Result += "};\n\n";
+
+  Result += "static struct _objc_symtab "
+         "_OBJC_SYMBOLS __attribute__((used, section (\"__OBJC, __symbols\")))= {\n";
+  Result += "\t0, 0, " + utostr(ClsDefCount)
+            + ", " + utostr(CatDefCount) + "\n";
+  for (int i = 0; i < ClsDefCount; i++) {
+    Result += "\t,&_OBJC_CLASS_";
+    Result += ClassImplementation[i]->getNameAsString();
+    Result += "\n";
+  }
+
+  for (int i = 0; i < CatDefCount; i++) {
+    Result += "\t,&_OBJC_CATEGORY_";
+    Result += CategoryImplementation[i]->getClassInterface()->getNameAsString();
+    Result += "_";
+    Result += CategoryImplementation[i]->getNameAsString();
+    Result += "\n";
+  }
+
+  Result += "};\n\n";
+
+  // Write objc_module metadata
+
+  /*
+   struct _objc_module {
+    long version;
+    long size;
+    const char *name;
+    struct _objc_symtab *symtab;
+   }
+  */
+
+  Result += "\nstruct _objc_module {\n";
+  Result += "\tlong version;\n";
+  Result += "\tlong size;\n";
+  Result += "\tconst char *name;\n";
+  Result += "\tstruct _objc_symtab *symtab;\n";
+  Result += "};\n\n";
+  Result += "static struct _objc_module "
+    "_OBJC_MODULES __attribute__ ((used, section (\"__OBJC, __module_info\")))= {\n";
+  Result += "\t" + utostr(OBJC_ABI_VERSION) +
+  ", sizeof(struct _objc_module), \"\", &_OBJC_SYMBOLS\n";
+  Result += "};\n\n";
+
+  if (LangOpts.Microsoft) {
+    if (ProtocolExprDecls.size()) {
+      Result += "#pragma section(\".objc_protocol$B\",long,read,write)\n";
+      Result += "#pragma data_seg(push, \".objc_protocol$B\")\n";
+      for (llvm::SmallPtrSet<ObjCProtocolDecl *,8>::iterator I = ProtocolExprDecls.begin(),
+           E = ProtocolExprDecls.end(); I != E; ++I) {
+        Result += "static struct _objc_protocol *_POINTER_OBJC_PROTOCOL_";
+        Result += (*I)->getNameAsString();
+        Result += " = &_OBJC_PROTOCOL_";
+        Result += (*I)->getNameAsString();
+        Result += ";\n";
+      }
+      Result += "#pragma data_seg(pop)\n\n";
+    }
+    Result += "#pragma section(\".objc_module_info$B\",long,read,write)\n";
+    Result += "#pragma data_seg(push, \".objc_module_info$B\")\n";
+    Result += "static struct _objc_module *_POINTER_OBJC_MODULES = ";
+    Result += "&_OBJC_MODULES;\n";
+    Result += "#pragma data_seg(pop)\n\n";
+  }
+}
+
+void RewriteObjC::RewriteByRefString(std::string &ResultStr, 
+                                     const std::string &Name,
+                                     ValueDecl *VD) {
+  assert(BlockByRefDeclNo.count(VD) && 
+         "RewriteByRefString: ByRef decl missing");
+  ResultStr += "struct __Block_byref_" + Name + 
+    "_" + utostr(BlockByRefDeclNo[VD]) ;
+}
+
+static bool HasLocalVariableExternalStorage(ValueDecl *VD) {
+  if (VarDecl *Var = dyn_cast<VarDecl>(VD))
+    return (Var->isFunctionOrMethodVarDecl() && !Var->hasLocalStorage());
+  return false;
+}
+
+std::string RewriteObjC::SynthesizeBlockFunc(BlockExpr *CE, int i,
+                                                   const char *funcName,
+                                                   std::string Tag) {
+  const FunctionType *AFT = CE->getFunctionType();
+  QualType RT = AFT->getResultType();
+  std::string StructRef = "struct " + Tag;
+  std::string S = "static " + RT.getAsString() + " __" +
+                  funcName + "_" + "block_func_" + utostr(i);
+
+  BlockDecl *BD = CE->getBlockDecl();
+
+  if (isa<FunctionNoProtoType>(AFT)) {
+    // No user-supplied arguments. Still need to pass in a pointer to the
+    // block (to reference imported block decl refs).
+    S += "(" + StructRef + " *__cself)";
+  } else if (BD->param_empty()) {
+    S += "(" + StructRef + " *__cself)";
+  } else {
+    const FunctionProtoType *FT = cast<FunctionProtoType>(AFT);
+    assert(FT && "SynthesizeBlockFunc: No function proto");
+    S += '(';
+    // first add the implicit argument.
+    S += StructRef + " *__cself, ";
+    std::string ParamStr;
+    for (BlockDecl::param_iterator AI = BD->param_begin(),
+         E = BD->param_end(); AI != E; ++AI) {
+      if (AI != BD->param_begin()) S += ", ";
+      ParamStr = (*AI)->getNameAsString();
+      (*AI)->getType().getAsStringInternal(ParamStr, Context->PrintingPolicy);
+      S += ParamStr;
+    }
+    if (FT->isVariadic()) {
+      if (!BD->param_empty()) S += ", ";
+      S += "...";
+    }
+    S += ')';
+  }
+  S += " {\n";
+
+  // Create local declarations to avoid rewriting all closure decl ref exprs.
+  // First, emit a declaration for all "by ref" decls.
+  for (llvm::SmallVector<ValueDecl*,8>::iterator I = BlockByRefDecls.begin(),
+       E = BlockByRefDecls.end(); I != E; ++I) {
+    S += "  ";
+    std::string Name = (*I)->getNameAsString();
+    std::string TypeString;
+    RewriteByRefString(TypeString, Name, (*I));
+    TypeString += " *";
+    Name = TypeString + Name;
+    S += Name + " = __cself->" + (*I)->getNameAsString() + "; // bound by ref\n";
+  }
+  // Next, emit a declaration for all "by copy" declarations.
+  for (llvm::SmallVector<ValueDecl*,8>::iterator I = BlockByCopyDecls.begin(),
+       E = BlockByCopyDecls.end(); I != E; ++I) {
+    S += "  ";
+    // Handle nested closure invocation. For example:
+    //
+    //   void (^myImportedClosure)(void);
+    //   myImportedClosure  = ^(void) { setGlobalInt(x + y); };
+    //
+    //   void (^anotherClosure)(void);
+    //   anotherClosure = ^(void) {
+    //     myImportedClosure(); // import and invoke the closure
+    //   };
+    //
+    if (isTopLevelBlockPointerType((*I)->getType())) {
+      RewriteBlockPointerTypeVariable(S, (*I));
+      S += " = (";
+      RewriteBlockPointerType(S, (*I)->getType());
+      S += ")";
+      S += "__cself->" + (*I)->getNameAsString() + "; // bound by copy\n";
+    }
+    else {
+      std::string Name = (*I)->getNameAsString();
+      QualType QT = (*I)->getType();
+      if (HasLocalVariableExternalStorage(*I))
+        QT = Context->getPointerType(QT);
+      QT.getAsStringInternal(Name, Context->PrintingPolicy);
+      S += Name + " = __cself->" + 
+                              (*I)->getNameAsString() + "; // bound by copy\n";
+    }
+  }
+  std::string RewrittenStr = RewrittenBlockExprs[CE];
+  const char *cstr = RewrittenStr.c_str();
+  while (*cstr++ != '{') ;
+  S += cstr;
+  S += "\n";
+  return S;
+}
+
+std::string RewriteObjC::SynthesizeBlockHelperFuncs(BlockExpr *CE, int i,
+                                                   const char *funcName,
+                                                   std::string Tag) {
+  std::string StructRef = "struct " + Tag;
+  std::string S = "static void __";
+
+  S += funcName;
+  S += "_block_copy_" + utostr(i);
+  S += "(" + StructRef;
+  S += "*dst, " + StructRef;
+  S += "*src) {";
+  for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = ImportedBlockDecls.begin(),
+      E = ImportedBlockDecls.end(); I != E; ++I) {
+    S += "_Block_object_assign((void*)&dst->";
+    S += (*I)->getNameAsString();
+    S += ", (void*)src->";
+    S += (*I)->getNameAsString();
+    if (BlockByRefDeclsPtrSet.count((*I)))
+      S += ", " + utostr(BLOCK_FIELD_IS_BYREF) + "/*BLOCK_FIELD_IS_BYREF*/);";
+    else
+      S += ", " + utostr(BLOCK_FIELD_IS_OBJECT) + "/*BLOCK_FIELD_IS_OBJECT*/);";
+  }
+  S += "}\n";
+  
+  S += "\nstatic void __";
+  S += funcName;
+  S += "_block_dispose_" + utostr(i);
+  S += "(" + StructRef;
+  S += "*src) {";
+  for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = ImportedBlockDecls.begin(),
+      E = ImportedBlockDecls.end(); I != E; ++I) {
+    S += "_Block_object_dispose((void*)src->";
+    S += (*I)->getNameAsString();
+    if (BlockByRefDeclsPtrSet.count((*I)))
+      S += ", " + utostr(BLOCK_FIELD_IS_BYREF) + "/*BLOCK_FIELD_IS_BYREF*/);";
+    else
+      S += ", " + utostr(BLOCK_FIELD_IS_OBJECT) + "/*BLOCK_FIELD_IS_OBJECT*/);";
+  }
+  S += "}\n";
+  return S;
+}
+
+std::string RewriteObjC::SynthesizeBlockImpl(BlockExpr *CE, std::string Tag, 
+                                             std::string Desc) {
+  std::string S = "\nstruct " + Tag;
+  std::string Constructor = "  " + Tag;
+
+  S += " {\n  struct __block_impl impl;\n";
+  S += "  struct " + Desc;
+  S += "* Desc;\n";
+
+  Constructor += "(void *fp, "; // Invoke function pointer.
+  Constructor += "struct " + Desc; // Descriptor pointer.
+  Constructor += " *desc";
+
+  if (BlockDeclRefs.size()) {
+    // Output all "by copy" declarations.
+    for (llvm::SmallVector<ValueDecl*,8>::iterator I = BlockByCopyDecls.begin(),
+         E = BlockByCopyDecls.end(); I != E; ++I) {
+      S += "  ";
+      std::string FieldName = (*I)->getNameAsString();
+      std::string ArgName = "_" + FieldName;
+      // Handle nested closure invocation. For example:
+      //
+      //   void (^myImportedBlock)(void);
+      //   myImportedBlock  = ^(void) { setGlobalInt(x + y); };
+      //
+      //   void (^anotherBlock)(void);
+      //   anotherBlock = ^(void) {
+      //     myImportedBlock(); // import and invoke the closure
+      //   };
+      //
+      if (isTopLevelBlockPointerType((*I)->getType())) {
+        S += "struct __block_impl *";
+        Constructor += ", void *" + ArgName;
+      } else {
+        QualType QT = (*I)->getType();
+        if (HasLocalVariableExternalStorage(*I))
+          QT = Context->getPointerType(QT);
+        QT.getAsStringInternal(FieldName, Context->PrintingPolicy);
+        QT.getAsStringInternal(ArgName, Context->PrintingPolicy);
+        Constructor += ", " + ArgName;
+      }
+      S += FieldName + ";\n";
+    }
+    // Output all "by ref" declarations.
+    for (llvm::SmallVector<ValueDecl*,8>::iterator I = BlockByRefDecls.begin(),
+         E = BlockByRefDecls.end(); I != E; ++I) {
+      S += "  ";
+      std::string FieldName = (*I)->getNameAsString();
+      std::string ArgName = "_" + FieldName;
+      // Handle nested closure invocation. For example:
+      //
+      //   void (^myImportedBlock)(void);
+      //   myImportedBlock  = ^(void) { setGlobalInt(x + y); };
+      //
+      //   void (^anotherBlock)(void);
+      //   anotherBlock = ^(void) {
+      //     myImportedBlock(); // import and invoke the closure
+      //   };
+      //
+      if (isTopLevelBlockPointerType((*I)->getType())) {
+        S += "struct __block_impl *";
+        Constructor += ", void *" + ArgName;
+      } else {
+        std::string TypeString;
+        RewriteByRefString(TypeString, FieldName, (*I));
+        TypeString += " *";
+        FieldName = TypeString + FieldName;
+        ArgName = TypeString + ArgName;
+        Constructor += ", " + ArgName;
+      }
+      S += FieldName + "; // by ref\n";
+    }
+    // Finish writing the constructor.
+    Constructor += ", int flags=0) {\n";
+    if (GlobalVarDecl)
+      Constructor += "    impl.isa = &_NSConcreteGlobalBlock;\n";
+    else
+      Constructor += "    impl.isa = &_NSConcreteStackBlock;\n";
+    Constructor += "    impl.Flags = flags;\n    impl.FuncPtr = fp;\n";
+
+    Constructor += "    Desc = desc;\n";
+
+    // Initialize all "by copy" arguments.
+    for (llvm::SmallVector<ValueDecl*,8>::iterator I = BlockByCopyDecls.begin(),
+         E = BlockByCopyDecls.end(); I != E; ++I) {
+      std::string Name = (*I)->getNameAsString();
+      Constructor += "    ";
+      if (isTopLevelBlockPointerType((*I)->getType()))
+        Constructor += Name + " = (struct __block_impl *)_";
+      else
+        Constructor += Name + " = _";
+      Constructor += Name + ";\n";
+    }
+    // Initialize all "by ref" arguments.
+    for (llvm::SmallVector<ValueDecl*,8>::iterator I = BlockByRefDecls.begin(),
+         E = BlockByRefDecls.end(); I != E; ++I) {
+      std::string Name = (*I)->getNameAsString();
+      Constructor += "    ";
+      if (isTopLevelBlockPointerType((*I)->getType()))
+        Constructor += Name + " = (struct __block_impl *)_";
+      else
+        Constructor += Name + " = _";
+      Constructor += Name + "->__forwarding;\n";
+    }
+  } else {
+    // Finish writing the constructor.
+    Constructor += ", int flags=0) {\n";
+    if (GlobalVarDecl)
+      Constructor += "    impl.isa = &_NSConcreteGlobalBlock;\n";
+    else
+      Constructor += "    impl.isa = &_NSConcreteStackBlock;\n";
+    Constructor += "    impl.Flags = flags;\n    impl.FuncPtr = fp;\n";
+    Constructor += "    Desc = desc;\n";
+  }
+  Constructor += "  ";
+  Constructor += "}\n";
+  S += Constructor;
+  S += "};\n";
+  return S;
+}
+
+std::string RewriteObjC::SynthesizeBlockDescriptor(std::string DescTag, 
+                                                   std::string ImplTag, int i,
+                                                   const char *FunName,
+                                                   unsigned hasCopy) {
+  std::string S = "\nstatic struct " + DescTag;
+  
+  S += " {\n  unsigned long reserved;\n";
+  S += "  unsigned long Block_size;\n";
+  if (hasCopy) {
+    S += "  void (*copy)(struct ";
+    S += ImplTag; S += "*, struct ";
+    S += ImplTag; S += "*);\n";
+    
+    S += "  void (*dispose)(struct ";
+    S += ImplTag; S += "*);\n";
+  }
+  S += "} ";
+
+  S += DescTag + "_DATA = { 0, sizeof(struct ";
+  S += ImplTag + ")";
+  if (hasCopy) {
+    S += ", __" + std::string(FunName) + "_block_copy_" + utostr(i);
+    S += ", __" + std::string(FunName) + "_block_dispose_" + utostr(i);
+  }
+  S += "};\n";
+  return S;
+}
+
+void RewriteObjC::SynthesizeBlockLiterals(SourceLocation FunLocStart,
+                                          const char *FunName) {
+  // Insert declaration for the function in which block literal is used.
+  if (CurFunctionDeclToDeclareForBlock && !Blocks.empty())
+    RewriteBlockLiteralFunctionDecl(CurFunctionDeclToDeclareForBlock);
+  bool RewriteSC = (GlobalVarDecl &&
+                    !Blocks.empty() &&
+                    GlobalVarDecl->getStorageClass() == VarDecl::Static &&
+                    GlobalVarDecl->getType().getCVRQualifiers());
+  if (RewriteSC) {
+    std::string SC(" void __");
+    SC += GlobalVarDecl->getNameAsString();
+    SC += "() {}";
+    InsertText(FunLocStart, SC);
+  }
+  
+  // Insert closures that were part of the function.
+  for (unsigned i = 0, count=0; i < Blocks.size(); i++) {
+    CollectBlockDeclRefInfo(Blocks[i]);
+    // Need to copy-in the inner copied-in variables not actually used in this
+    // block.
+    for (int j = 0; j < InnerDeclRefsCount[i]; j++) {
+      BlockDeclRefExpr *Exp = InnerDeclRefs[count++];
+      ValueDecl *VD = Exp->getDecl();
+      BlockDeclRefs.push_back(Exp);
+      if (!Exp->isByRef() && !BlockByCopyDeclsPtrSet.count(VD)) {
+        BlockByCopyDeclsPtrSet.insert(VD);
+        BlockByCopyDecls.push_back(VD);
+      }
+      if (Exp->isByRef() && !BlockByRefDeclsPtrSet.count(VD)) {
+        BlockByRefDeclsPtrSet.insert(VD);
+        BlockByRefDecls.push_back(VD);
+      }
+    }
+
+    std::string ImplTag = "__" + std::string(FunName) + "_block_impl_" + utostr(i);
+    std::string DescTag = "__" + std::string(FunName) + "_block_desc_" + utostr(i);
+
+    std::string CI = SynthesizeBlockImpl(Blocks[i], ImplTag, DescTag);
+
+    InsertText(FunLocStart, CI);
+
+    std::string CF = SynthesizeBlockFunc(Blocks[i], i, FunName, ImplTag);
+
+    InsertText(FunLocStart, CF);
+
+    if (ImportedBlockDecls.size()) {
+      std::string HF = SynthesizeBlockHelperFuncs(Blocks[i], i, FunName, ImplTag);
+      InsertText(FunLocStart, HF);
+    }
+    std::string BD = SynthesizeBlockDescriptor(DescTag, ImplTag, i, FunName,
+                                               ImportedBlockDecls.size() > 0);
+    InsertText(FunLocStart, BD);
+
+    BlockDeclRefs.clear();
+    BlockByRefDecls.clear();
+    BlockByRefDeclsPtrSet.clear();
+    BlockByCopyDecls.clear();
+    BlockByCopyDeclsPtrSet.clear();
+    ImportedBlockDecls.clear();
+  }
+  if (RewriteSC) {
+    // Must insert any 'const/volatile/static here. Since it has been
+    // removed as result of rewriting of block literals.
+    std::string SC;
+    if (GlobalVarDecl->getStorageClass() == VarDecl::Static)
+      SC = "static ";
+    if (GlobalVarDecl->getType().isConstQualified())
+      SC += "const ";
+    if (GlobalVarDecl->getType().isVolatileQualified())
+      SC += "volatile ";
+    if (GlobalVarDecl->getType().isRestrictQualified())
+      SC += "restrict ";
+    InsertText(FunLocStart, SC);
+  }
+  
+  Blocks.clear();
+  InnerDeclRefsCount.clear();
+  InnerDeclRefs.clear();
+  RewrittenBlockExprs.clear();
+}
+
+void RewriteObjC::InsertBlockLiteralsWithinFunction(FunctionDecl *FD) {
+  SourceLocation FunLocStart = FD->getTypeSpecStartLoc();
+  const char *FuncName = FD->getNameAsCString();
+
+  SynthesizeBlockLiterals(FunLocStart, FuncName);
+}
+
+static void BuildUniqueMethodName(std::string &Name,
+                                  ObjCMethodDecl *MD) {
+  ObjCInterfaceDecl *IFace = MD->getClassInterface();
+  Name = IFace->getNameAsCString();
+  Name += "__" + MD->getSelector().getAsString();
+  // Convert colons to underscores.
+  std::string::size_type loc = 0;
+  while ((loc = Name.find(":", loc)) != std::string::npos)
+    Name.replace(loc, 1, "_");
+}
+
+void RewriteObjC::InsertBlockLiteralsWithinMethod(ObjCMethodDecl *MD) {
+  //fprintf(stderr,"In InsertBlockLiteralsWitinMethod\n");
+  //SourceLocation FunLocStart = MD->getLocStart();
+  SourceLocation FunLocStart = MD->getLocStart();
+  std::string FuncName;
+  BuildUniqueMethodName(FuncName, MD);
+  SynthesizeBlockLiterals(FunLocStart, FuncName.c_str());
+}
+
+void RewriteObjC::GetBlockDeclRefExprs(Stmt *S) {
+  for (Stmt::child_iterator CI = S->child_begin(), E = S->child_end();
+       CI != E; ++CI)
+    if (*CI) {
+      if (BlockExpr *CBE = dyn_cast<BlockExpr>(*CI))
+        GetBlockDeclRefExprs(CBE->getBody());
+      else
+        GetBlockDeclRefExprs(*CI);
+    }
+  // Handle specific things.
+  if (BlockDeclRefExpr *CDRE = dyn_cast<BlockDeclRefExpr>(S)) {
+    // FIXME: Handle enums.
+    if (!isa<FunctionDecl>(CDRE->getDecl()))
+      BlockDeclRefs.push_back(CDRE);
+  }
+  else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S))
+    if (HasLocalVariableExternalStorage(DRE->getDecl())) {
+        BlockDeclRefExpr *BDRE = 
+          new (Context)BlockDeclRefExpr(DRE->getDecl(), DRE->getType(), 
+                                        DRE->getLocation(), false);
+        BlockDeclRefs.push_back(BDRE);
+    }
+  
+  return;
+}
+
+void RewriteObjC::GetInnerBlockDeclRefExprs(Stmt *S, 
+                llvm::SmallVector<BlockDeclRefExpr *, 8> &InnerBlockDeclRefs,
+                llvm::SmallPtrSet<const DeclContext *, 8> &InnerContexts) {
+  for (Stmt::child_iterator CI = S->child_begin(), E = S->child_end();
+       CI != E; ++CI)
+    if (*CI) {
+      if (BlockExpr *CBE = dyn_cast<BlockExpr>(*CI)) {
+        InnerContexts.insert(cast<DeclContext>(CBE->getBlockDecl()));
+        GetInnerBlockDeclRefExprs(CBE->getBody(),
+                                  InnerBlockDeclRefs,
+                                  InnerContexts);
+      }
+      else
+        GetInnerBlockDeclRefExprs(*CI,
+                                  InnerBlockDeclRefs,
+                                  InnerContexts);
+
+    }
+  // Handle specific things.
+  if (BlockDeclRefExpr *CDRE = dyn_cast<BlockDeclRefExpr>(S)) {
+    if (!isa<FunctionDecl>(CDRE->getDecl()) &&
+        !InnerContexts.count(CDRE->getDecl()->getDeclContext()))
+      InnerBlockDeclRefs.push_back(CDRE);
+  }
+  else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
+    if (VarDecl *Var = dyn_cast<VarDecl>(DRE->getDecl()))
+      if (Var->isFunctionOrMethodVarDecl())
+        ImportedLocalExternalDecls.insert(Var);
+  }
+  
+  return;
+}
+
+Stmt *RewriteObjC::SynthesizeBlockCall(CallExpr *Exp, const Expr *BlockExp) {
+  // Navigate to relevant type information.
+  const BlockPointerType *CPT = 0;
+
+  if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(BlockExp)) {
+    CPT = DRE->getType()->getAs<BlockPointerType>();
+  } else if (const BlockDeclRefExpr *CDRE = 
+              dyn_cast<BlockDeclRefExpr>(BlockExp)) {
+    CPT = CDRE->getType()->getAs<BlockPointerType>();
+  } else if (const MemberExpr *MExpr = dyn_cast<MemberExpr>(BlockExp)) {
+    CPT = MExpr->getType()->getAs<BlockPointerType>();
+  } 
+  else if (const ParenExpr *PRE = dyn_cast<ParenExpr>(BlockExp)) {
+    return SynthesizeBlockCall(Exp, PRE->getSubExpr());
+  }
+  else if (const ImplicitCastExpr *IEXPR = dyn_cast<ImplicitCastExpr>(BlockExp)) 
+    CPT = IEXPR->getType()->getAs<BlockPointerType>();
+  else if (const ConditionalOperator *CEXPR = 
+            dyn_cast<ConditionalOperator>(BlockExp)) {
+    Expr *LHSExp = CEXPR->getLHS();
+    Stmt *LHSStmt = SynthesizeBlockCall(Exp, LHSExp);
+    Expr *RHSExp = CEXPR->getRHS();
+    Stmt *RHSStmt = SynthesizeBlockCall(Exp, RHSExp);
+    Expr *CONDExp = CEXPR->getCond();
+    ConditionalOperator *CondExpr =
+      new (Context) ConditionalOperator(CONDExp,
+                                      SourceLocation(), cast<Expr>(LHSStmt),
+                                      SourceLocation(), cast<Expr>(RHSStmt), 
+                                      Exp->getType());
+    return CondExpr;
+  } else if (const ObjCIvarRefExpr *IRE = dyn_cast<ObjCIvarRefExpr>(BlockExp)) {
+    CPT = IRE->getType()->getAs<BlockPointerType>();
+  } else {
+    assert(1 && "RewriteBlockClass: Bad type");
+  }
+  assert(CPT && "RewriteBlockClass: Bad type");
+  const FunctionType *FT = CPT->getPointeeType()->getAs<FunctionType>();
+  assert(FT && "RewriteBlockClass: Bad type");
+  const FunctionProtoType *FTP = dyn_cast<FunctionProtoType>(FT);
+  // FTP will be null for closures that don't take arguments.
+
+  RecordDecl *RD = RecordDecl::Create(*Context, TagDecl::TK_struct, TUDecl,
+                                      SourceLocation(),
+                                      &Context->Idents.get("__block_impl"));
+  QualType PtrBlock = Context->getPointerType(Context->getTagDeclType(RD));
+
+  // Generate a funky cast.
+  llvm::SmallVector<QualType, 8> ArgTypes;
+
+  // Push the block argument type.
+  ArgTypes.push_back(PtrBlock);
+  if (FTP) {
+    for (FunctionProtoType::arg_type_iterator I = FTP->arg_type_begin(),
+         E = FTP->arg_type_end(); I && (I != E); ++I) {
+      QualType t = *I;
+      // Make sure we convert "t (^)(...)" to "t (*)(...)".
+      if (isTopLevelBlockPointerType(t)) {
+        const BlockPointerType *BPT = t->getAs<BlockPointerType>();
+        t = Context->getPointerType(BPT->getPointeeType());
+      }
+      ArgTypes.push_back(t);
+    }
+  }
+  // Now do the pointer to function cast.
+  QualType PtrToFuncCastType = Context->getFunctionType(Exp->getType(),
+    &ArgTypes[0], ArgTypes.size(), false/*no variadic*/, 0,
+                                                        false, false, 0, 0, 
+                                                       FunctionType::ExtInfo());
+
+  PtrToFuncCastType = Context->getPointerType(PtrToFuncCastType);
+
+  CastExpr *BlkCast = NoTypeInfoCStyleCastExpr(Context, PtrBlock,
+                                               CastExpr::CK_Unknown,
+                                               const_cast<Expr*>(BlockExp));
+  // Don't forget the parens to enforce the proper binding.
+  ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(),
+                                          BlkCast);
+  //PE->dump();
+
+  FieldDecl *FD = FieldDecl::Create(*Context, 0, SourceLocation(),
+                     &Context->Idents.get("FuncPtr"), Context->VoidPtrTy, 0,
+                                    /*BitWidth=*/0, /*Mutable=*/true);
+  MemberExpr *ME = new (Context) MemberExpr(PE, true, FD, SourceLocation(),
+                                            FD->getType());
+
+  CastExpr *FunkCast = NoTypeInfoCStyleCastExpr(Context, PtrToFuncCastType,
+                                                CastExpr::CK_Unknown, ME);
+  PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), FunkCast);
+
+  llvm::SmallVector<Expr*, 8> BlkExprs;
+  // Add the implicit argument.
+  BlkExprs.push_back(BlkCast);
+  // Add the user arguments.
+  for (CallExpr::arg_iterator I = Exp->arg_begin(),
+       E = Exp->arg_end(); I != E; ++I) {
+    BlkExprs.push_back(*I);
+  }
+  CallExpr *CE = new (Context) CallExpr(*Context, PE, &BlkExprs[0],
+                                        BlkExprs.size(),
+                                        Exp->getType(), SourceLocation());
+  return CE;
+}
+
+void RewriteObjC::RewriteBlockCall(CallExpr *Exp) {
+  Stmt *BlockCall = SynthesizeBlockCall(Exp, Exp->getCallee());
+  ReplaceStmt(Exp, BlockCall);
+}
+
+// We need to return the rewritten expression to handle cases where the
+// BlockDeclRefExpr is embedded in another expression being rewritten.
+// For example:
+//
+// int main() {
+//    __block Foo *f;
+//    __block int i;
+//
+//    void (^myblock)() = ^() {
+//        [f test]; // f is a BlockDeclRefExpr embedded in a message (which is being rewritten).
+//        i = 77;
+//    };
+//}
+Stmt *RewriteObjC::RewriteBlockDeclRefExpr(Expr *DeclRefExp) {
+  // Rewrite the byref variable into BYREFVAR->__forwarding->BYREFVAR 
+  // for each DeclRefExp where BYREFVAR is name of the variable.
+  ValueDecl *VD;
+  bool isArrow = true;
+  if (BlockDeclRefExpr *BDRE = dyn_cast<BlockDeclRefExpr>(DeclRefExp))
+    VD = BDRE->getDecl();
+  else {
+    VD = cast<DeclRefExpr>(DeclRefExp)->getDecl();
+    isArrow = false;
+  }
+  
+  FieldDecl *FD = FieldDecl::Create(*Context, 0, SourceLocation(),
+                                    &Context->Idents.get("__forwarding"), 
+                                    Context->VoidPtrTy, 0,
+                                    /*BitWidth=*/0, /*Mutable=*/true);
+  MemberExpr *ME = new (Context) MemberExpr(DeclRefExp, isArrow,
+                                            FD, SourceLocation(),
+                                            FD->getType());
+
+  const char *Name = VD->getNameAsCString();
+  FD = FieldDecl::Create(*Context, 0, SourceLocation(),
+                         &Context->Idents.get(Name), 
+                         Context->VoidPtrTy, 0,
+                         /*BitWidth=*/0, /*Mutable=*/true);
+  ME = new (Context) MemberExpr(ME, true, FD, SourceLocation(),
+                                DeclRefExp->getType());
+  
+  
+  
+  // Need parens to enforce precedence.
+  ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), 
+                                          ME);
+  ReplaceStmt(DeclRefExp, PE);
+  return PE;
+}
+
+// Rewrites the imported local variable V with external storage 
+// (static, extern, etc.) as *V
+//
+Stmt *RewriteObjC::RewriteLocalVariableExternalStorage(DeclRefExpr *DRE) {
+  ValueDecl *VD = DRE->getDecl();
+  if (VarDecl *Var = dyn_cast<VarDecl>(VD))
+    if (!ImportedLocalExternalDecls.count(Var))
+      return DRE;
+  Expr *Exp = new (Context) UnaryOperator(DRE, UnaryOperator::Deref,
+                                    DRE->getType(), DRE->getLocation());
+  // Need parens to enforce precedence.
+  ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), 
+                                          Exp);
+  ReplaceStmt(DRE, PE);
+  return PE;
+}
+
+void RewriteObjC::RewriteCastExpr(CStyleCastExpr *CE) {
+  SourceLocation LocStart = CE->getLParenLoc();
+  SourceLocation LocEnd = CE->getRParenLoc();
+
+  // Need to avoid trying to rewrite synthesized casts.
+  if (LocStart.isInvalid())
+    return;
+  // Need to avoid trying to rewrite casts contained in macros.
+  if (!Rewriter::isRewritable(LocStart) || !Rewriter::isRewritable(LocEnd))
+    return;
+
+  const char *startBuf = SM->getCharacterData(LocStart);
+  const char *endBuf = SM->getCharacterData(LocEnd);
+  QualType QT = CE->getType();
+  const Type* TypePtr = QT->getAs<Type>();
+  if (isa<TypeOfExprType>(TypePtr)) {
+    const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr);
+    QT = TypeOfExprTypePtr->getUnderlyingExpr()->getType();
+    std::string TypeAsString = "(";
+    RewriteBlockPointerType(TypeAsString, QT);
+    TypeAsString += ")";
+    ReplaceText(LocStart, endBuf-startBuf+1, TypeAsString);
+    return;
+  }
+  // advance the location to startArgList.
+  const char *argPtr = startBuf;
+
+  while (*argPtr++ && (argPtr < endBuf)) {
+    switch (*argPtr) {
+    case '^':
+      // Replace the '^' with '*'.
+      LocStart = LocStart.getFileLocWithOffset(argPtr-startBuf);
+      ReplaceText(LocStart, 1, "*");
+      break;
+    }
+  }
+  return;
+}
+
+void RewriteObjC::RewriteBlockPointerFunctionArgs(FunctionDecl *FD) {
+  SourceLocation DeclLoc = FD->getLocation();
+  unsigned parenCount = 0;
+
+  // We have 1 or more arguments that have closure pointers.
+  const char *startBuf = SM->getCharacterData(DeclLoc);
+  const char *startArgList = strchr(startBuf, '(');
+
+  assert((*startArgList == '(') && "Rewriter fuzzy parser confused");
+
+  parenCount++;
+  // advance the location to startArgList.
+  DeclLoc = DeclLoc.getFileLocWithOffset(startArgList-startBuf);
+  assert((DeclLoc.isValid()) && "Invalid DeclLoc");
+
+  const char *argPtr = startArgList;
+
+  while (*argPtr++ && parenCount) {
+    switch (*argPtr) {
+    case '^':
+      // Replace the '^' with '*'.
+      DeclLoc = DeclLoc.getFileLocWithOffset(argPtr-startArgList);
+      ReplaceText(DeclLoc, 1, "*");
+      break;
+    case '(':
+      parenCount++;
+      break;
+    case ')':
+      parenCount--;
+      break;
+    }
+  }
+  return;
+}
+
+bool RewriteObjC::PointerTypeTakesAnyBlockArguments(QualType QT) {
+  const FunctionProtoType *FTP;
+  const PointerType *PT = QT->getAs<PointerType>();
+  if (PT) {
+    FTP = PT->getPointeeType()->getAs<FunctionProtoType>();
+  } else {
+    const BlockPointerType *BPT = QT->getAs<BlockPointerType>();
+    assert(BPT && "BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type");
+    FTP = BPT->getPointeeType()->getAs<FunctionProtoType>();
+  }
+  if (FTP) {
+    for (FunctionProtoType::arg_type_iterator I = FTP->arg_type_begin(),
+         E = FTP->arg_type_end(); I != E; ++I)
+      if (isTopLevelBlockPointerType(*I))
+        return true;
+  }
+  return false;
+}
+
+void RewriteObjC::GetExtentOfArgList(const char *Name, const char *&LParen,
+                                     const char *&RParen) {
+  const char *argPtr = strchr(Name, '(');
+  assert((*argPtr == '(') && "Rewriter fuzzy parser confused");
+
+  LParen = argPtr; // output the start.
+  argPtr++; // skip past the left paren.
+  unsigned parenCount = 1;
+
+  while (*argPtr && parenCount) {
+    switch (*argPtr) {
+    case '(': parenCount++; break;
+    case ')': parenCount--; break;
+    default: break;
+    }
+    if (parenCount) argPtr++;
+  }
+  assert((*argPtr == ')') && "Rewriter fuzzy parser confused");
+  RParen = argPtr; // output the end
+}
+
+void RewriteObjC::RewriteBlockPointerDecl(NamedDecl *ND) {
+  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
+    RewriteBlockPointerFunctionArgs(FD);
+    return;
+  }
+  // Handle Variables and Typedefs.
+  SourceLocation DeclLoc = ND->getLocation();
+  QualType DeclT;
+  if (VarDecl *VD = dyn_cast<VarDecl>(ND))
+    DeclT = VD->getType();
+  else if (TypedefDecl *TDD = dyn_cast<TypedefDecl>(ND))
+    DeclT = TDD->getUnderlyingType();
+  else if (FieldDecl *FD = dyn_cast<FieldDecl>(ND))
+    DeclT = FD->getType();
+  else
+    assert(0 && "RewriteBlockPointerDecl(): Decl type not yet handled");
+
+  const char *startBuf = SM->getCharacterData(DeclLoc);
+  const char *endBuf = startBuf;
+  // scan backward (from the decl location) for the end of the previous decl.
+  while (*startBuf != '^' && *startBuf != ';' && startBuf != MainFileStart)
+    startBuf--;
+
+  // *startBuf != '^' if we are dealing with a pointer to function that
+  // may take block argument types (which will be handled below).
+  if (*startBuf == '^') {
+    // Replace the '^' with '*', computing a negative offset.
+    DeclLoc = DeclLoc.getFileLocWithOffset(startBuf-endBuf);
+    ReplaceText(DeclLoc, 1, "*");
+  }
+  if (PointerTypeTakesAnyBlockArguments(DeclT)) {
+    // Replace the '^' with '*' for arguments.
+    DeclLoc = ND->getLocation();
+    startBuf = SM->getCharacterData(DeclLoc);
+    const char *argListBegin, *argListEnd;
+    GetExtentOfArgList(startBuf, argListBegin, argListEnd);
+    while (argListBegin < argListEnd) {
+      if (*argListBegin == '^') {
+        SourceLocation CaretLoc = DeclLoc.getFileLocWithOffset(argListBegin-startBuf);
+        ReplaceText(CaretLoc, 1, "*");
+      }
+      argListBegin++;
+    }
+  }
+  return;
+}
+
+
+/// SynthesizeByrefCopyDestroyHelper - This routine synthesizes:
+/// void __Block_byref_id_object_copy(struct Block_byref_id_object *dst,
+///                    struct Block_byref_id_object *src) {
+///  _Block_object_assign (&_dest->object, _src->object, 
+///                        BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_OBJECT
+///                        [|BLOCK_FIELD_IS_WEAK]) // object
+///  _Block_object_assign(&_dest->object, _src->object, 
+///                       BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_BLOCK
+///                       [|BLOCK_FIELD_IS_WEAK]) // block
+/// }
+/// And:
+/// void __Block_byref_id_object_dispose(struct Block_byref_id_object *_src) {
+///  _Block_object_dispose(_src->object, 
+///                        BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_OBJECT
+///                        [|BLOCK_FIELD_IS_WEAK]) // object
+///  _Block_object_dispose(_src->object, 
+///                         BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_BLOCK
+///                         [|BLOCK_FIELD_IS_WEAK]) // block
+/// }
+
+std::string RewriteObjC::SynthesizeByrefCopyDestroyHelper(VarDecl *VD,
+                                                          int flag) {
+  std::string S;
+  if (CopyDestroyCache.count(flag))
+    return S;
+  CopyDestroyCache.insert(flag);
+  S = "static void __Block_byref_id_object_copy_";
+  S += utostr(flag);
+  S += "(void *dst, void *src) {\n";
+  
+  // offset into the object pointer is computed as:
+  // void * + void* + int + int + void* + void *
+  unsigned IntSize = 
+  static_cast<unsigned>(Context->getTypeSize(Context->IntTy));
+  unsigned VoidPtrSize = 
+  static_cast<unsigned>(Context->getTypeSize(Context->VoidPtrTy));
+  
+  unsigned offset = (VoidPtrSize*4 + IntSize + IntSize)/8;
+  S += " _Block_object_assign((char*)dst + ";
+  S += utostr(offset);
+  S += ", *(void * *) ((char*)src + ";
+  S += utostr(offset);
+  S += "), ";
+  S += utostr(flag);
+  S += ");\n}\n";
+  
+  S += "static void __Block_byref_id_object_dispose_";
+  S += utostr(flag);
+  S += "(void *src) {\n";
+  S += " _Block_object_dispose(*(void * *) ((char*)src + ";
+  S += utostr(offset);
+  S += "), ";
+  S += utostr(flag);
+  S += ");\n}\n";
+  return S;
+}
+
+/// RewriteByRefVar - For each __block typex ND variable this routine transforms
+/// the declaration into:
+/// struct __Block_byref_ND {
+/// void *__isa;                  // NULL for everything except __weak pointers
+/// struct __Block_byref_ND *__forwarding;
+/// int32_t __flags;
+/// int32_t __size;
+/// void *__Block_byref_id_object_copy; // If variable is __block ObjC object
+/// void *__Block_byref_id_object_dispose; // If variable is __block ObjC object
+/// typex ND;
+/// };
+///
+/// It then replaces declaration of ND variable with:
+/// struct __Block_byref_ND ND = {__isa=0B, __forwarding=&ND, __flags=some_flag, 
+///                               __size=sizeof(struct __Block_byref_ND), 
+///                               ND=initializer-if-any};
+///
+///
+void RewriteObjC::RewriteByRefVar(VarDecl *ND) {
+  // Insert declaration for the function in which block literal is
+  // used.
+  if (CurFunctionDeclToDeclareForBlock)
+    RewriteBlockLiteralFunctionDecl(CurFunctionDeclToDeclareForBlock);
+  int flag = 0;
+  int isa = 0;
+  SourceLocation DeclLoc = ND->getTypeSpecStartLoc();
+  if (DeclLoc.isInvalid())
+    // If type location is missing, it is because of missing type (a warning).
+    // Use variable's location which is good for this case.
+    DeclLoc = ND->getLocation();
+  const char *startBuf = SM->getCharacterData(DeclLoc);
+  SourceLocation X = ND->getLocEnd();
+  X = SM->getInstantiationLoc(X);
+  const char *endBuf = SM->getCharacterData(X);
+  std::string Name(ND->getNameAsString());
+  std::string ByrefType;
+  RewriteByRefString(ByrefType, Name, ND);
+  ByrefType += " {\n";
+  ByrefType += "  void *__isa;\n";
+  RewriteByRefString(ByrefType, Name, ND);
+  ByrefType += " *__forwarding;\n";
+  ByrefType += " int __flags;\n";
+  ByrefType += " int __size;\n";
+  // Add void *__Block_byref_id_object_copy; 
+  // void *__Block_byref_id_object_dispose; if needed.
+  QualType Ty = ND->getType();
+  bool HasCopyAndDispose = Context->BlockRequiresCopying(Ty);
+  if (HasCopyAndDispose) {
+    ByrefType += " void (*__Block_byref_id_object_copy)(void*, void*);\n";
+    ByrefType += " void (*__Block_byref_id_object_dispose)(void*);\n";
+  }
+  
+  Ty.getAsStringInternal(Name, Context->PrintingPolicy);
+  ByrefType += " " + Name + ";\n";
+  ByrefType += "};\n";
+  // Insert this type in global scope. It is needed by helper function.
+  SourceLocation FunLocStart;
+  if (CurFunctionDef)
+     FunLocStart = CurFunctionDef->getTypeSpecStartLoc();
+  else {
+    assert(CurMethodDef && "RewriteByRefVar - CurMethodDef is null");
+    FunLocStart = CurMethodDef->getLocStart();
+  }
+  InsertText(FunLocStart, ByrefType);
+  if (Ty.isObjCGCWeak()) {
+    flag |= BLOCK_FIELD_IS_WEAK;
+    isa = 1;
+  }
+  
+  if (HasCopyAndDispose) {
+    flag = BLOCK_BYREF_CALLER;
+    QualType Ty = ND->getType();
+    // FIXME. Handle __weak variable (BLOCK_FIELD_IS_WEAK) as well.
+    if (Ty->isBlockPointerType())
+      flag |= BLOCK_FIELD_IS_BLOCK;
+    else
+      flag |= BLOCK_FIELD_IS_OBJECT;
+    std::string HF = SynthesizeByrefCopyDestroyHelper(ND, flag);
+    if (!HF.empty())
+      InsertText(FunLocStart, HF);
+  }
+  
+  // struct __Block_byref_ND ND = 
+  // {0, &ND, some_flag, __size=sizeof(struct __Block_byref_ND), 
+  //  initializer-if-any};
+  bool hasInit = (ND->getInit() != 0);
+  unsigned flags = 0;
+  if (HasCopyAndDispose)
+    flags |= BLOCK_HAS_COPY_DISPOSE;
+  Name = ND->getNameAsString();
+  ByrefType.clear();
+  RewriteByRefString(ByrefType, Name, ND);
+  std::string ForwardingCastType("(");
+  ForwardingCastType += ByrefType + " *)";
+  if (!hasInit) {
+    ByrefType += " " + Name + " = {(void*)";
+    ByrefType += utostr(isa);
+    ByrefType += "," +  ForwardingCastType + "&" + Name + ", ";
+    ByrefType += utostr(flags);
+    ByrefType += ", ";
+    ByrefType += "sizeof(";
+    RewriteByRefString(ByrefType, Name, ND);
+    ByrefType += ")";
+    if (HasCopyAndDispose) {
+      ByrefType += ", __Block_byref_id_object_copy_";
+      ByrefType += utostr(flag);
+      ByrefType += ", __Block_byref_id_object_dispose_";
+      ByrefType += utostr(flag);
+    }
+    ByrefType += "};\n";
+    ReplaceText(DeclLoc, endBuf-startBuf+Name.size(), ByrefType);
+  }
+  else {
+    SourceLocation startLoc;
+    Expr *E = ND->getInit();
+    if (const CStyleCastExpr *ECE = dyn_cast<CStyleCastExpr>(E))
+      startLoc = ECE->getLParenLoc();
+    else
+      startLoc = E->getLocStart();
+    startLoc = SM->getInstantiationLoc(startLoc);
+    endBuf = SM->getCharacterData(startLoc);
+   
+    ByrefType += " " + Name;
+    ByrefType += " = {(void*)";
+    ByrefType += utostr(isa);
+    ByrefType += "," +  ForwardingCastType + "&" + Name + ", ";
+    ByrefType += utostr(flags);
+    ByrefType += ", ";
+    ByrefType += "sizeof(";
+    RewriteByRefString(ByrefType, Name, ND);
+    ByrefType += "), ";
+    if (HasCopyAndDispose) {
+      ByrefType += "__Block_byref_id_object_copy_";
+      ByrefType += utostr(flag);
+      ByrefType += ", __Block_byref_id_object_dispose_";
+      ByrefType += utostr(flag);
+      ByrefType += ", ";
+    }
+    ReplaceText(DeclLoc, endBuf-startBuf, ByrefType);
+    
+    // Complete the newly synthesized compound expression by inserting a right
+    // curly brace before the end of the declaration.
+    // FIXME: This approach avoids rewriting the initializer expression. It
+    // also assumes there is only one declarator. For example, the following
+    // isn't currently supported by this routine (in general):
+    // 
+    // double __block BYREFVAR = 1.34, BYREFVAR2 = 1.37;
+    //
+    const char *startBuf = SM->getCharacterData(startLoc);
+    const char *semiBuf = strchr(startBuf, ';');
+    assert((*semiBuf == ';') && "RewriteByRefVar: can't find ';'");
+    SourceLocation semiLoc =
+      startLoc.getFileLocWithOffset(semiBuf-startBuf);
+
+    InsertText(semiLoc, "}");
+  }
+  return;
+}
+
+void RewriteObjC::CollectBlockDeclRefInfo(BlockExpr *Exp) {
+  // Add initializers for any closure decl refs.
+  GetBlockDeclRefExprs(Exp->getBody());
+  if (BlockDeclRefs.size()) {
+    // Unique all "by copy" declarations.
+    for (unsigned i = 0; i < BlockDeclRefs.size(); i++)
+      if (!BlockDeclRefs[i]->isByRef()) {
+        if (!BlockByCopyDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) {
+          BlockByCopyDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl());
+          BlockByCopyDecls.push_back(BlockDeclRefs[i]->getDecl());
+        }
+      }
+    // Unique all "by ref" declarations.
+    for (unsigned i = 0; i < BlockDeclRefs.size(); i++)
+      if (BlockDeclRefs[i]->isByRef()) {
+        if (!BlockByRefDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) {
+          BlockByRefDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl());
+          BlockByRefDecls.push_back(BlockDeclRefs[i]->getDecl());
+        }
+      }
+    // Find any imported blocks...they will need special attention.
+    for (unsigned i = 0; i < BlockDeclRefs.size(); i++)
+      if (BlockDeclRefs[i]->isByRef() ||
+          BlockDeclRefs[i]->getType()->isObjCObjectPointerType() || 
+          BlockDeclRefs[i]->getType()->isBlockPointerType())
+        ImportedBlockDecls.insert(BlockDeclRefs[i]->getDecl());
+  }
+}
+
+FunctionDecl *RewriteObjC::SynthBlockInitFunctionDecl(const char *name) {
+  IdentifierInfo *ID = &Context->Idents.get(name);
+  QualType FType = Context->getFunctionNoProtoType(Context->VoidPtrTy);
+  return FunctionDecl::Create(*Context, TUDecl,SourceLocation(),
+                              ID, FType, 0, FunctionDecl::Extern,
+                              FunctionDecl::None, false, false);
+}
+
+Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp,
+          const llvm::SmallVector<BlockDeclRefExpr *, 8> &InnerBlockDeclRefs) {
+  Blocks.push_back(Exp);
+
+  CollectBlockDeclRefInfo(Exp);
+  
+  // Add inner imported variables now used in current block.
+ int countOfInnerDecls = 0;
+  if (!InnerBlockDeclRefs.empty()) {
+    for (unsigned i = 0; i < InnerBlockDeclRefs.size(); i++) {
+      BlockDeclRefExpr *Exp = InnerBlockDeclRefs[i];
+      ValueDecl *VD = Exp->getDecl();
+      if (!Exp->isByRef() && !BlockByCopyDeclsPtrSet.count(VD)) {
+      // We need to save the copied-in variables in nested
+      // blocks because it is needed at the end for some of the API generations.
+      // See SynthesizeBlockLiterals routine.
+        InnerDeclRefs.push_back(Exp); countOfInnerDecls++;
+        BlockDeclRefs.push_back(Exp);
+        BlockByCopyDeclsPtrSet.insert(VD);
+        BlockByCopyDecls.push_back(VD);
+      }
+      if (Exp->isByRef() && !BlockByRefDeclsPtrSet.count(VD)) {
+        InnerDeclRefs.push_back(Exp); countOfInnerDecls++;
+        BlockDeclRefs.push_back(Exp);
+        BlockByRefDeclsPtrSet.insert(VD);
+        BlockByRefDecls.push_back(VD);
+      }
+    }
+    // Find any imported blocks...they will need special attention.
+    for (unsigned i = 0; i < InnerBlockDeclRefs.size(); i++)
+      if (InnerBlockDeclRefs[i]->isByRef() ||
+          InnerBlockDeclRefs[i]->getType()->isObjCObjectPointerType() || 
+          InnerBlockDeclRefs[i]->getType()->isBlockPointerType())
+        ImportedBlockDecls.insert(InnerBlockDeclRefs[i]->getDecl());
+  }
+  InnerDeclRefsCount.push_back(countOfInnerDecls);
+  
+  std::string FuncName;
+
+  if (CurFunctionDef)
+    FuncName = CurFunctionDef->getNameAsString();
+  else if (CurMethodDef)
+    BuildUniqueMethodName(FuncName, CurMethodDef);
+  else if (GlobalVarDecl)
+    FuncName = std::string(GlobalVarDecl->getNameAsString());
+
+  std::string BlockNumber = utostr(Blocks.size()-1);
+
+  std::string Tag = "__" + FuncName + "_block_impl_" + BlockNumber;
+  std::string Func = "__" + FuncName + "_block_func_" + BlockNumber;
+
+  // Get a pointer to the function type so we can cast appropriately.
+  QualType FType = Context->getPointerType(QualType(Exp->getFunctionType(),0));
+
+  FunctionDecl *FD;
+  Expr *NewRep;
+
+  // Simulate a contructor call...
+  FD = SynthBlockInitFunctionDecl(Tag.c_str());
+  DeclRefExpr *DRE = new (Context) DeclRefExpr(FD, FType, SourceLocation());
+
+  llvm::SmallVector<Expr*, 4> InitExprs;
+
+  // Initialize the block function.
+  FD = SynthBlockInitFunctionDecl(Func.c_str());
+  DeclRefExpr *Arg = new (Context) DeclRefExpr(FD, FD->getType(),
+                                               SourceLocation());
+  CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, Context->VoidPtrTy,
+                                                CastExpr::CK_Unknown, Arg);
+  InitExprs.push_back(castExpr);
+
+  // Initialize the block descriptor.
+  std::string DescData = "__" + FuncName + "_block_desc_" + BlockNumber + "_DATA";
+
+  VarDecl *NewVD = VarDecl::Create(*Context, TUDecl, SourceLocation(), 
+                                    &Context->Idents.get(DescData.c_str()), 
+                                    Context->VoidPtrTy, 0,
+                                    VarDecl::Static, VarDecl::None);
+  UnaryOperator *DescRefExpr = new (Context) UnaryOperator(
+                                  new (Context) DeclRefExpr(NewVD, 
+                                    Context->VoidPtrTy, SourceLocation()), 
+                                  UnaryOperator::AddrOf,
+                                  Context->getPointerType(Context->VoidPtrTy), 
+                                  SourceLocation());
+  InitExprs.push_back(DescRefExpr); 
+  
+  // Add initializers for any closure decl refs.
+  if (BlockDeclRefs.size()) {
+    Expr *Exp;
+    // Output all "by copy" declarations.
+    for (llvm::SmallVector<ValueDecl*,8>::iterator I = BlockByCopyDecls.begin(),
+         E = BlockByCopyDecls.end(); I != E; ++I) {
+      if (isObjCType((*I)->getType())) {
+        // FIXME: Conform to ABI ([[obj retain] autorelease]).
+        FD = SynthBlockInitFunctionDecl((*I)->getNameAsCString());
+        Exp = new (Context) DeclRefExpr(FD, FD->getType(), SourceLocation());
+      } else if (isTopLevelBlockPointerType((*I)->getType())) {
+        FD = SynthBlockInitFunctionDecl((*I)->getNameAsCString());
+        Arg = new (Context) DeclRefExpr(FD, FD->getType(), SourceLocation());
+        Exp = NoTypeInfoCStyleCastExpr(Context, Context->VoidPtrTy,
+                                       CastExpr::CK_Unknown, Arg);
+      } else {
+        FD = SynthBlockInitFunctionDecl((*I)->getNameAsCString());
+        Exp = new (Context) DeclRefExpr(FD, FD->getType(), SourceLocation());
+        if (HasLocalVariableExternalStorage(*I)) {
+          QualType QT = (*I)->getType();
+          QT = Context->getPointerType(QT);
+          Exp = new (Context) UnaryOperator(Exp, UnaryOperator::AddrOf, QT, 
+                                            SourceLocation());
+        }
+        
+      }
+      InitExprs.push_back(Exp);
+    }
+    // Output all "by ref" declarations.
+    for (llvm::SmallVector<ValueDecl*,8>::iterator I = BlockByRefDecls.begin(),
+         E = BlockByRefDecls.end(); I != E; ++I) {
+      ValueDecl *ND = (*I);
+      std::string Name(ND->getNameAsString());
+      std::string RecName;
+      RewriteByRefString(RecName, Name, ND);
+      IdentifierInfo *II = &Context->Idents.get(RecName.c_str() 
+                                                + sizeof("struct"));
+      RecordDecl *RD = RecordDecl::Create(*Context, TagDecl::TK_struct, TUDecl,
+                                          SourceLocation(), II);
+      assert(RD && "SynthBlockInitExpr(): Can't find RecordDecl");
+      QualType castT = Context->getPointerType(Context->getTagDeclType(RD));
+      
+      FD = SynthBlockInitFunctionDecl((*I)->getNameAsCString());
+      Exp = new (Context) DeclRefExpr(FD, FD->getType(), SourceLocation());
+      Exp = new (Context) UnaryOperator(Exp, UnaryOperator::AddrOf,
+                              Context->getPointerType(Exp->getType()),
+                              SourceLocation());
+      Exp = NoTypeInfoCStyleCastExpr(Context, castT, CastExpr::CK_Unknown, Exp);
+      InitExprs.push_back(Exp);
+    }
+  }
+  if (ImportedBlockDecls.size()) {
+    // generate BLOCK_HAS_COPY_DISPOSE(have helper funcs) | BLOCK_HAS_DESCRIPTOR
+    int flag = (BLOCK_HAS_COPY_DISPOSE | BLOCK_HAS_DESCRIPTOR);
+    unsigned IntSize = 
+      static_cast<unsigned>(Context->getTypeSize(Context->IntTy));
+    Expr *FlagExp = new (Context) IntegerLiteral(llvm::APInt(IntSize, flag), 
+                                             Context->IntTy, SourceLocation());
+    InitExprs.push_back(FlagExp);
+  }
+  NewRep = new (Context) CallExpr(*Context, DRE, &InitExprs[0], InitExprs.size(),
+                                  FType, SourceLocation());
+  NewRep = new (Context) UnaryOperator(NewRep, UnaryOperator::AddrOf,
+                             Context->getPointerType(NewRep->getType()),
+                             SourceLocation());
+  NewRep = NoTypeInfoCStyleCastExpr(Context, FType, CastExpr::CK_Unknown,
+                                    NewRep);
+  BlockDeclRefs.clear();
+  BlockByRefDecls.clear();
+  BlockByRefDeclsPtrSet.clear();
+  BlockByCopyDecls.clear();
+  BlockByCopyDeclsPtrSet.clear();
+  ImportedBlockDecls.clear();
+  return NewRep;
+}
+
+//===----------------------------------------------------------------------===//
+// Function Body / Expression rewriting
+//===----------------------------------------------------------------------===//
+
+// This is run as a first "pass" prior to RewriteFunctionBodyOrGlobalInitializer().
+// The allows the main rewrite loop to associate all ObjCPropertyRefExprs with
+// their respective BinaryOperator. Without this knowledge, we'd need to rewrite
+// the ObjCPropertyRefExpr twice (once as a getter, and later as a setter).
+// Since the rewriter isn't capable of rewriting rewritten code, it's important
+// we get this right.
+void RewriteObjC::CollectPropertySetters(Stmt *S) {
+  // Perform a bottom up traversal of all children.
+  for (Stmt::child_iterator CI = S->child_begin(), E = S->child_end();
+       CI != E; ++CI)
+    if (*CI)
+      CollectPropertySetters(*CI);
+
+  if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(S)) {
+    if (BinOp->isAssignmentOp()) {
+      if (ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(BinOp->getLHS()))
+        PropSetters[PRE] = BinOp;
+    }
+  }
+}
+
+Stmt *RewriteObjC::RewriteFunctionBodyOrGlobalInitializer(Stmt *S) {
+  if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) ||
+      isa<DoStmt>(S) || isa<ForStmt>(S))
+    Stmts.push_back(S);
+  else if (isa<ObjCForCollectionStmt>(S)) {
+    Stmts.push_back(S);
+    ObjCBcLabelNo.push_back(++BcLabelCount);
+  }
+
+  SourceRange OrigStmtRange = S->getSourceRange();
+
+  // Perform a bottom up rewrite of all children.
+  for (Stmt::child_iterator CI = S->child_begin(), E = S->child_end();
+       CI != E; ++CI)
+    if (*CI) {
+      Stmt *newStmt;
+      Stmt *S = (*CI);
+      if (ObjCIvarRefExpr *IvarRefExpr = dyn_cast<ObjCIvarRefExpr>(S)) {
+        Expr *OldBase = IvarRefExpr->getBase();
+        bool replaced = false;
+        newStmt = RewriteObjCNestedIvarRefExpr(S, replaced);
+        if (replaced) {
+          if (ObjCIvarRefExpr *IRE = dyn_cast<ObjCIvarRefExpr>(newStmt))
+            ReplaceStmt(OldBase, IRE->getBase());
+          else
+            ReplaceStmt(S, newStmt);
+        }
+      }
+      else
+        newStmt = RewriteFunctionBodyOrGlobalInitializer(S);
+      if (newStmt)
+        *CI = newStmt;
+    }
+
+  if (BlockExpr *BE = dyn_cast<BlockExpr>(S)) {
+    llvm::SmallVector<BlockDeclRefExpr *, 8> InnerBlockDeclRefs;
+    llvm::SmallPtrSet<const DeclContext *, 8> InnerContexts;
+    InnerContexts.insert(BE->getBlockDecl());
+    ImportedLocalExternalDecls.clear();
+    GetInnerBlockDeclRefExprs(BE->getBody(),
+                              InnerBlockDeclRefs, InnerContexts);
+    // Rewrite the block body in place.
+    RewriteFunctionBodyOrGlobalInitializer(BE->getBody());
+    ImportedLocalExternalDecls.clear();
+    // Now we snarf the rewritten text and stash it away for later use.
+    std::string Str = Rewrite.getRewrittenText(BE->getSourceRange());
+    RewrittenBlockExprs[BE] = Str;
+
+    Stmt *blockTranscribed = SynthBlockInitExpr(BE, InnerBlockDeclRefs);
+                            
+    //blockTranscribed->dump();
+    ReplaceStmt(S, blockTranscribed);
+    return blockTranscribed;
+  }
+  // Handle specific things.
+  if (ObjCEncodeExpr *AtEncode = dyn_cast<ObjCEncodeExpr>(S))
+    return RewriteAtEncode(AtEncode);
+
+  if (ObjCPropertyRefExpr *PropRefExpr = dyn_cast<ObjCPropertyRefExpr>(S)) {
+    BinaryOperator *BinOp = PropSetters[PropRefExpr];
+    if (BinOp) {
+      // Because the rewriter doesn't allow us to rewrite rewritten code,
+      // we need to rewrite the right hand side prior to rewriting the setter.
+      DisableReplaceStmt = true;
+      // Save the source range. Even if we disable the replacement, the
+      // rewritten node will have been inserted into the tree. If the synthesized
+      // node is at the 'end', the rewriter will fail. Consider this:
+      //    self.errorHandler = handler ? handler :
+      //              ^(NSURL *errorURL, NSError *error) { return (BOOL)1; };
+      SourceRange SrcRange = BinOp->getSourceRange();
+      Stmt *newStmt = RewriteFunctionBodyOrGlobalInitializer(BinOp->getRHS());
+      DisableReplaceStmt = false;
+      //
+      // Unlike the main iterator, we explicily avoid changing 'BinOp'. If
+      // we changed the RHS of BinOp, the rewriter would fail (since it needs
+      // to see the original expression). Consider this example:
+      //
+      // Foo *obj1, *obj2;
+      //
+      // obj1.i = [obj2 rrrr];
+      //
+      // 'BinOp' for the previous expression looks like:
+      //
+      // (BinaryOperator 0x231ccf0 'int' '='
+      //   (ObjCPropertyRefExpr 0x231cc70 'int' Kind=PropertyRef Property="i"
+      //     (DeclRefExpr 0x231cc50 'Foo *' Var='obj1' 0x231cbb0))
+      //   (ObjCMessageExpr 0x231ccb0 'int' selector=rrrr
+      //     (DeclRefExpr 0x231cc90 'Foo *' Var='obj2' 0x231cbe0)))
+      //
+      // 'newStmt' represents the rewritten message expression. For example:
+      //
+      // (CallExpr 0x231d300 'id':'struct objc_object *'
+      //   (ParenExpr 0x231d2e0 'int (*)(id, SEL)'
+      //     (CStyleCastExpr 0x231d2c0 'int (*)(id, SEL)'
+      //       (CStyleCastExpr 0x231d220 'void *'
+      //         (DeclRefExpr 0x231d200 'id (id, SEL, ...)' FunctionDecl='objc_msgSend' 0x231cdc0))))
+      //
+      // Note that 'newStmt' is passed to RewritePropertySetter so that it
+      // can be used as the setter argument. ReplaceStmt() will still 'see'
+      // the original RHS (since we haven't altered BinOp).
+      //
+      // This implies the Rewrite* routines can no longer delete the original
+      // node. As a result, we now leak the original AST nodes.
+      //
+      return RewritePropertySetter(BinOp, dyn_cast<Expr>(newStmt), SrcRange);
+    } else {
+      return RewritePropertyGetter(PropRefExpr);
+    }
+  }
+  if (ObjCSelectorExpr *AtSelector = dyn_cast<ObjCSelectorExpr>(S))
+    return RewriteAtSelector(AtSelector);
+
+  if (ObjCStringLiteral *AtString = dyn_cast<ObjCStringLiteral>(S))
+    return RewriteObjCStringLiteral(AtString);
+
+  if (ObjCMessageExpr *MessExpr = dyn_cast<ObjCMessageExpr>(S)) {
+#if 0
+    // Before we rewrite it, put the original message expression in a comment.
+    SourceLocation startLoc = MessExpr->getLocStart();
+    SourceLocation endLoc = MessExpr->getLocEnd();
+
+    const char *startBuf = SM->getCharacterData(startLoc);
+    const char *endBuf = SM->getCharacterData(endLoc);
+
+    std::string messString;
+    messString += "// ";
+    messString.append(startBuf, endBuf-startBuf+1);
+    messString += "\n";
+
+    // FIXME: Missing definition of
+    // InsertText(clang::SourceLocation, char const*, unsigned int).
+    // InsertText(startLoc, messString.c_str(), messString.size());
+    // Tried this, but it didn't work either...
+    // ReplaceText(startLoc, 0, messString.c_str(), messString.size());
+#endif
+    return RewriteMessageExpr(MessExpr);
+  }
+
+  if (ObjCAtTryStmt *StmtTry = dyn_cast<ObjCAtTryStmt>(S))
+    return RewriteObjCTryStmt(StmtTry);
+
+  if (ObjCAtSynchronizedStmt *StmtTry = dyn_cast<ObjCAtSynchronizedStmt>(S))
+    return RewriteObjCSynchronizedStmt(StmtTry);
+
+  if (ObjCAtThrowStmt *StmtThrow = dyn_cast<ObjCAtThrowStmt>(S))
+    return RewriteObjCThrowStmt(StmtThrow);
+
+  if (ObjCProtocolExpr *ProtocolExp = dyn_cast<ObjCProtocolExpr>(S))
+    return RewriteObjCProtocolExpr(ProtocolExp);
+
+  if (ObjCForCollectionStmt *StmtForCollection =
+        dyn_cast<ObjCForCollectionStmt>(S))
+    return RewriteObjCForCollectionStmt(StmtForCollection,
+                                        OrigStmtRange.getEnd());
+  if (BreakStmt *StmtBreakStmt =
+      dyn_cast<BreakStmt>(S))
+    return RewriteBreakStmt(StmtBreakStmt);
+  if (ContinueStmt *StmtContinueStmt =
+      dyn_cast<ContinueStmt>(S))
+    return RewriteContinueStmt(StmtContinueStmt);
+
+  // Need to check for protocol refs (id <P>, Foo <P> *) in variable decls
+  // and cast exprs.
+  if (DeclStmt *DS = dyn_cast<DeclStmt>(S)) {
+    // FIXME: What we're doing here is modifying the type-specifier that
+    // precedes the first Decl.  In the future the DeclGroup should have
+    // a separate type-specifier that we can rewrite.
+    // NOTE: We need to avoid rewriting the DeclStmt if it is within
+    // the context of an ObjCForCollectionStmt. For example:
+    //   NSArray *someArray;
+    //   for (id <FooProtocol> index in someArray) ;
+    // This is because RewriteObjCForCollectionStmt() does textual rewriting 
+    // and it depends on the original text locations/positions.
+    if (Stmts.empty() || !isa<ObjCForCollectionStmt>(Stmts.back()))
+      RewriteObjCQualifiedInterfaceTypes(*DS->decl_begin());
+
+    // Blocks rewrite rules.
+    for (DeclStmt::decl_iterator DI = DS->decl_begin(), DE = DS->decl_end();
+         DI != DE; ++DI) {
+      Decl *SD = *DI;
+      if (ValueDecl *ND = dyn_cast<ValueDecl>(SD)) {
+        if (isTopLevelBlockPointerType(ND->getType()))
+          RewriteBlockPointerDecl(ND);
+        else if (ND->getType()->isFunctionPointerType())
+          CheckFunctionPointerDecl(ND->getType(), ND);
+        if (VarDecl *VD = dyn_cast<VarDecl>(SD)) {
+          if (VD->hasAttr<BlocksAttr>()) {
+            static unsigned uniqueByrefDeclCount = 0;
+            assert(!BlockByRefDeclNo.count(ND) &&
+              "RewriteFunctionBodyOrGlobalInitializer: Duplicate byref decl");
+            BlockByRefDeclNo[ND] = uniqueByrefDeclCount++;
+            RewriteByRefVar(VD);
+          }
+          else           
+            RewriteTypeOfDecl(VD);
+        }
+      }
+      if (TypedefDecl *TD = dyn_cast<TypedefDecl>(SD)) {
+        if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
+          RewriteBlockPointerDecl(TD);
+        else if (TD->getUnderlyingType()->isFunctionPointerType())
+          CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
+      }
+    }
+  }
+
+  if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(S))
+    RewriteObjCQualifiedInterfaceTypes(CE);
+
+  if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) ||
+      isa<DoStmt>(S) || isa<ForStmt>(S)) {
+    assert(!Stmts.empty() && "Statement stack is empty");
+    assert ((isa<SwitchStmt>(Stmts.back()) || isa<WhileStmt>(Stmts.back()) ||
+             isa<DoStmt>(Stmts.back()) || isa<ForStmt>(Stmts.back()))
+            && "Statement stack mismatch");
+    Stmts.pop_back();
+  }
+  // Handle blocks rewriting.
+  if (BlockDeclRefExpr *BDRE = dyn_cast<BlockDeclRefExpr>(S)) {
+    if (BDRE->isByRef())
+      return RewriteBlockDeclRefExpr(BDRE);
+  }
+  if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
+    ValueDecl *VD = DRE->getDecl(); 
+    if (VD->hasAttr<BlocksAttr>())
+      return RewriteBlockDeclRefExpr(DRE);
+    if (HasLocalVariableExternalStorage(VD))
+      return RewriteLocalVariableExternalStorage(DRE);
+  }
+  
+  if (CallExpr *CE = dyn_cast<CallExpr>(S)) {
+    if (CE->getCallee()->getType()->isBlockPointerType()) {
+      Stmt *BlockCall = SynthesizeBlockCall(CE, CE->getCallee());
+      ReplaceStmt(S, BlockCall);
+      return BlockCall;
+    }
+  }
+  if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(S)) {
+    RewriteCastExpr(CE);
+  }
+#if 0
+  if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(S)) {
+    CastExpr *Replacement = new (Context) CastExpr(ICE->getType(), ICE->getSubExpr(), SourceLocation());
+    // Get the new text.
+    std::string SStr;
+    llvm::raw_string_ostream Buf(SStr);
+    Replacement->printPretty(Buf, *Context);
+    const std::string &Str = Buf.str();
+
+    printf("CAST = %s\n", &Str[0]);
+    InsertText(ICE->getSubExpr()->getLocStart(), &Str[0], Str.size());
+    delete S;
+    return Replacement;
+  }
+#endif
+  // Return this stmt unmodified.
+  return S;
+}
+
+void RewriteObjC::RewriteRecordBody(RecordDecl *RD) {
+  for (RecordDecl::field_iterator i = RD->field_begin(), 
+                                  e = RD->field_end(); i != e; ++i) {
+    FieldDecl *FD = *i;
+    if (isTopLevelBlockPointerType(FD->getType()))
+      RewriteBlockPointerDecl(FD);
+    if (FD->getType()->isObjCQualifiedIdType() ||
+        FD->getType()->isObjCQualifiedInterfaceType())
+      RewriteObjCQualifiedInterfaceTypes(FD);
+  }
+}
+
+/// HandleDeclInMainFile - This is called for each top-level decl defined in the
+/// main file of the input.
+void RewriteObjC::HandleDeclInMainFile(Decl *D) {
+  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+    if (FD->isOverloadedOperator())
+      return;
+
+    // Since function prototypes don't have ParmDecl's, we check the function
+    // prototype. This enables us to rewrite function declarations and
+    // definitions using the same code.
+    RewriteBlocksInFunctionProtoType(FD->getType(), FD);
+
+    // FIXME: If this should support Obj-C++, support CXXTryStmt
+    if (CompoundStmt *Body = FD->getCompoundBody()) {
+      CurFunctionDef = FD;
+      CurFunctionDeclToDeclareForBlock = FD;
+      CollectPropertySetters(Body);
+      CurrentBody = Body;
+      Body =
+       cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body));
+      FD->setBody(Body);
+      CurrentBody = 0;
+      if (PropParentMap) {
+        delete PropParentMap;
+        PropParentMap = 0;
+      }
+      // This synthesizes and inserts the block "impl" struct, invoke function,
+      // and any copy/dispose helper functions.
+      InsertBlockLiteralsWithinFunction(FD);
+      CurFunctionDef = 0;
+      CurFunctionDeclToDeclareForBlock = 0;
+    }
+    return;
+  }
+  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
+    if (CompoundStmt *Body = MD->getCompoundBody()) {
+      CurMethodDef = MD;
+      CollectPropertySetters(Body);
+      CurrentBody = Body;
+      Body =
+       cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body));
+      MD->setBody(Body);
+      CurrentBody = 0;
+      if (PropParentMap) {
+        delete PropParentMap;
+        PropParentMap = 0;
+      }
+      InsertBlockLiteralsWithinMethod(MD);
+      CurMethodDef = 0;
+    }
+  }
+  if (ObjCImplementationDecl *CI = dyn_cast<ObjCImplementationDecl>(D))
+    ClassImplementation.push_back(CI);
+  else if (ObjCCategoryImplDecl *CI = dyn_cast<ObjCCategoryImplDecl>(D))
+    CategoryImplementation.push_back(CI);
+  else if (ObjCClassDecl *CD = dyn_cast<ObjCClassDecl>(D))
+    RewriteForwardClassDecl(CD);
+  else if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
+    RewriteObjCQualifiedInterfaceTypes(VD);
+    if (isTopLevelBlockPointerType(VD->getType()))
+      RewriteBlockPointerDecl(VD);
+    else if (VD->getType()->isFunctionPointerType()) {
+      CheckFunctionPointerDecl(VD->getType(), VD);
+      if (VD->getInit()) {
+        if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(VD->getInit())) {
+          RewriteCastExpr(CE);
+        }
+      }
+    } else if (VD->getType()->isRecordType()) {
+      RecordDecl *RD = VD->getType()->getAs<RecordType>()->getDecl();
+      if (RD->isDefinition())
+        RewriteRecordBody(RD);
+    }
+    if (VD->getInit()) {
+      GlobalVarDecl = VD;
+      CollectPropertySetters(VD->getInit());
+      CurrentBody = VD->getInit();
+      RewriteFunctionBodyOrGlobalInitializer(VD->getInit());
+      CurrentBody = 0;
+      if (PropParentMap) {
+        delete PropParentMap;
+        PropParentMap = 0;
+      }
+      SynthesizeBlockLiterals(VD->getTypeSpecStartLoc(),
+                              VD->getNameAsCString());
+      GlobalVarDecl = 0;
+
+      // This is needed for blocks.
+      if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(VD->getInit())) {
+        RewriteCastExpr(CE);
+      }
+    }
+    return;
+  }
+  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
+    if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
+      RewriteBlockPointerDecl(TD);
+    else if (TD->getUnderlyingType()->isFunctionPointerType())
+      CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
+    return;
+  }
+  if (RecordDecl *RD = dyn_cast<RecordDecl>(D)) {
+    if (RD->isDefinition()) 
+      RewriteRecordBody(RD);
+    return;
+  }
+  // Nothing yet.
+}
+
+void RewriteObjC::HandleTranslationUnit(ASTContext &C) {
+  if (Diags.hasErrorOccurred())
+    return;
+
+  RewriteInclude();
+
+  // Here's a great place to add any extra declarations that may be needed.
+  // Write out meta data for each @protocol(<expr>).
+  for (llvm::SmallPtrSet<ObjCProtocolDecl *,8>::iterator I = ProtocolExprDecls.begin(),
+       E = ProtocolExprDecls.end(); I != E; ++I)
+    RewriteObjCProtocolMetaData(*I, "", "", Preamble);
+
+  InsertText(SM->getLocForStartOfFile(MainFileID), Preamble, false);
+  if (ClassImplementation.size() || CategoryImplementation.size())
+    RewriteImplementations();
+
+  // Get the buffer corresponding to MainFileID.  If we haven't changed it, then
+  // we are done.
+  if (const RewriteBuffer *RewriteBuf =
+      Rewrite.getRewriteBufferFor(MainFileID)) {
+    //printf("Changed:\n");
+    *OutFile << std::string(RewriteBuf->begin(), RewriteBuf->end());
+  } else {
+    llvm::errs() << "No changes\n";
+  }
+
+  if (ClassImplementation.size() || CategoryImplementation.size() ||
+      ProtocolExprDecls.size()) {
+    // Rewrite Objective-c meta data*
+    std::string ResultStr;
+    SynthesizeMetaDataIntoBuffer(ResultStr);
+    // Emit metadata.
+    *OutFile << ResultStr;
+  }
+  OutFile->flush();
+}
diff --git a/lib/Frontend/RewriteTest.cpp b/lib/Frontend/RewriteTest.cpp
new file mode 100644
index 0000000..0414678
--- /dev/null
+++ b/lib/Frontend/RewriteTest.cpp
@@ -0,0 +1,39 @@
+//===--- RewriteTest.cpp - Rewriter playground ----------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This is a testbed.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/Utils.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Rewrite/TokenRewriter.h"
+#include "llvm/Support/raw_ostream.h"
+
+void clang::DoRewriteTest(Preprocessor &PP, llvm::raw_ostream* OS) {
+  SourceManager &SM = PP.getSourceManager();
+  const LangOptions &LangOpts = PP.getLangOptions();
+
+  TokenRewriter Rewriter(SM.getMainFileID(), SM, LangOpts);
+
+  // Throw <i> </i> tags around comments.
+  for (TokenRewriter::token_iterator I = Rewriter.token_begin(),
+       E = Rewriter.token_end(); I != E; ++I) {
+    if (I->isNot(tok::comment)) continue;
+
+    Rewriter.AddTokenBefore(I, "<i>");
+    Rewriter.AddTokenAfter(I, "</i>");
+  }
+
+
+  // Print out the output.
+  for (TokenRewriter::token_iterator I = Rewriter.token_begin(),
+       E = Rewriter.token_end(); I != E; ++I)
+    *OS << PP.getSpelling(*I);
+}
diff --git a/lib/Frontend/StmtXML.cpp b/lib/Frontend/StmtXML.cpp
new file mode 100644
index 0000000..ce474d3
--- /dev/null
+++ b/lib/Frontend/StmtXML.cpp
@@ -0,0 +1,448 @@
+//===--- StmtXML.cpp - XML implementation for Stmt ASTs ------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Stmt::dumpXML methods, which dump out the
+// AST to an XML document.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/DocumentXML.h"
+#include "clang/AST/StmtVisitor.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/Basic/SourceManager.h"
+using namespace clang;
+
+//===----------------------------------------------------------------------===//
+// StmtXML Visitor
+//===----------------------------------------------------------------------===//
+
+namespace  {
+  class StmtXML : public StmtVisitor<StmtXML> {
+    DocumentXML&  Doc;
+
+    //static const char *getOpcodeStr(UnaryOperator::Opcode Op);
+    //static const char *getOpcodeStr(BinaryOperator::Opcode Op);
+
+
+  void addSpecialAttribute(const char* pName, StringLiteral* Str) {
+    Doc.addAttribute(pName, Doc.escapeString(Str->getStrData(), Str->getByteLength()));
+  }
+
+  void addSpecialAttribute(const char* pName, SizeOfAlignOfExpr* S) {
+    if (S->isArgumentType())
+      Doc.addAttribute(pName, S->getArgumentType());
+  }
+
+  void addSpecialAttribute(const char* pName, CXXTypeidExpr* S) {
+    if (S->isTypeOperand())
+      Doc.addAttribute(pName, S->getTypeOperand());
+  }
+
+
+  public:
+    StmtXML(DocumentXML& doc)
+      : Doc(doc) {
+    }
+
+    void DumpSubTree(Stmt *S) {
+      if (S) {
+        Visit(S);
+        if (DeclStmt* DS = dyn_cast<DeclStmt>(S)) {
+          for (DeclStmt::decl_iterator DI = DS->decl_begin(),
+                 DE = DS->decl_end(); DI != DE; ++DI) {
+            Doc.PrintDecl(*DI);
+          }
+        } else {
+          for (Stmt::child_iterator i = S->child_begin(), e = S->child_end();
+               i != e; ++i)
+            DumpSubTree(*i);
+        }
+        Doc.toParent();
+      } else {
+        Doc.addSubNode("NULL").toParent();
+      }
+    }
+
+
+#define NODE_XML( CLASS, NAME )          \
+  void Visit##CLASS(CLASS* S)            \
+  {                                      \
+    typedef CLASS tStmtType;             \
+    Doc.addSubNode(NAME);
+
+#define ATTRIBUTE_XML( FN, NAME )         Doc.addAttribute(NAME, S->FN);
+#define TYPE_ATTRIBUTE_XML( FN )          ATTRIBUTE_XML(FN, "type")
+#define ATTRIBUTE_OPT_XML( FN, NAME )     Doc.addAttributeOptional(NAME, S->FN);
+#define ATTRIBUTE_SPECIAL_XML( FN, NAME ) addSpecialAttribute(NAME, S);
+#define ATTRIBUTE_FILE_LOCATION_XML       Doc.addLocationRange(S->getSourceRange());
+
+
+#define ATTRIBUTE_ENUM_XML( FN, NAME )  \
+  {                                     \
+    const char* pAttributeName = NAME;  \
+    const bool optional = false;        \
+    switch (S->FN) {                    \
+    default: assert(0 && "unknown enum value");
+
+#define ATTRIBUTE_ENUM_OPT_XML( FN, NAME )  \
+  {                                         \
+    const char* pAttributeName = NAME;      \
+    const bool optional = true;             \
+    switch (S->FN) {                        \
+    default: assert(0 && "unknown enum value");
+
+#define ENUM_XML( VALUE, NAME )         case VALUE: if ((!optional) || NAME[0]) Doc.addAttribute(pAttributeName, NAME); break;
+#define END_ENUM_XML                    } }
+#define END_NODE_XML                    }
+
+#define ID_ATTRIBUTE_XML                Doc.addAttribute("id", S);
+#define SUB_NODE_XML( CLASS )
+#define SUB_NODE_SEQUENCE_XML( CLASS )
+#define SUB_NODE_OPT_XML( CLASS )
+
+#include "clang/Frontend/StmtXML.def"
+
+#if (0)
+    // Stmts.
+    void VisitStmt(Stmt *Node);
+    void VisitDeclStmt(DeclStmt *Node);
+    void VisitLabelStmt(LabelStmt *Node);
+    void VisitGotoStmt(GotoStmt *Node);
+
+    // Exprs
+    void VisitExpr(Expr *Node);
+    void VisitDeclRefExpr(DeclRefExpr *Node);
+    void VisitPredefinedExpr(PredefinedExpr *Node);
+    void VisitCharacterLiteral(CharacterLiteral *Node);
+    void VisitIntegerLiteral(IntegerLiteral *Node);
+    void VisitFloatingLiteral(FloatingLiteral *Node);
+    void VisitStringLiteral(StringLiteral *Str);
+    void VisitUnaryOperator(UnaryOperator *Node);
+    void VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *Node);
+    void VisitMemberExpr(MemberExpr *Node);
+    void VisitExtVectorElementExpr(ExtVectorElementExpr *Node);
+    void VisitBinaryOperator(BinaryOperator *Node);
+    void VisitCompoundAssignOperator(CompoundAssignOperator *Node);
+    void VisitAddrLabelExpr(AddrLabelExpr *Node);
+    void VisitTypesCompatibleExpr(TypesCompatibleExpr *Node);
+
+    // C++
+    void VisitCXXNamedCastExpr(CXXNamedCastExpr *Node);
+    void VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node);
+    void VisitCXXThisExpr(CXXThisExpr *Node);
+    void VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node);
+
+    // ObjC
+    void VisitObjCEncodeExpr(ObjCEncodeExpr *Node);
+    void VisitObjCMessageExpr(ObjCMessageExpr* Node);
+    void VisitObjCSelectorExpr(ObjCSelectorExpr *Node);
+    void VisitObjCProtocolExpr(ObjCProtocolExpr *Node);
+    void VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node);
+    void VisitObjCImplicitSetterGetterRefExpr(
+                        ObjCImplicitSetterGetterRefExpr *Node);
+    void VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node);
+    void VisitObjCSuperExpr(ObjCSuperExpr *Node);
+#endif
+  };
+}
+
+//===----------------------------------------------------------------------===//
+//  Stmt printing methods.
+//===----------------------------------------------------------------------===//
+#if (0)
+void StmtXML::VisitStmt(Stmt *Node) {
+  // nothing special to do
+}
+
+void StmtXML::VisitDeclStmt(DeclStmt *Node) {
+  for (DeclStmt::decl_iterator DI = Node->decl_begin(), DE = Node->decl_end();
+       DI != DE; ++DI) {
+    Doc.PrintDecl(*DI);
+  }
+}
+
+void StmtXML::VisitLabelStmt(LabelStmt *Node) {
+  Doc.addAttribute("name", Node->getName());
+}
+
+void StmtXML::VisitGotoStmt(GotoStmt *Node) {
+  Doc.addAttribute("name", Node->getLabel()->getName());
+}
+
+//===----------------------------------------------------------------------===//
+//  Expr printing methods.
+//===----------------------------------------------------------------------===//
+
+void StmtXML::VisitExpr(Expr *Node) {
+  DumpExpr(Node);
+}
+
+void StmtXML::VisitDeclRefExpr(DeclRefExpr *Node) {
+  DumpExpr(Node);
+
+  const char* pKind;
+  switch (Node->getDecl()->getKind()) {
+  case Decl::Function: pKind = "FunctionDecl"; break;
+  case Decl::Var: pKind = "Var"; break;
+  case Decl::ParmVar: pKind = "ParmVar"; break;
+  case Decl::EnumConstant: pKind = "EnumConstant"; break;
+  case Decl::Typedef: pKind = "Typedef"; break;
+  case Decl::Record: pKind = "Record"; break;
+  case Decl::Enum: pKind = "Enum"; break;
+  case Decl::CXXRecord: pKind = "CXXRecord"; break;
+  case Decl::ObjCInterface: pKind = "ObjCInterface"; break;
+  case Decl::ObjCClass: pKind = "ObjCClass"; break;
+  default: pKind = "Decl"; break;
+  }
+
+  Doc.addAttribute("kind", pKind);
+  Doc.addAttribute("name", Node->getDecl()->getNameAsString());
+  Doc.addRefAttribute(Node->getDecl());
+}
+
+void StmtXML::VisitPredefinedExpr(PredefinedExpr *Node) {
+  DumpExpr(Node);
+  switch (Node->getIdentType()) {
+  default: assert(0 && "unknown case");
+  case PredefinedExpr::Func:           Doc.addAttribute("predefined", " __func__"); break;
+  case PredefinedExpr::Function:       Doc.addAttribute("predefined", " __FUNCTION__"); break;
+  case PredefinedExpr::PrettyFunction: Doc.addAttribute("predefined", " __PRETTY_FUNCTION__");break;
+  }
+}
+
+void StmtXML::VisitCharacterLiteral(CharacterLiteral *Node) {
+  DumpExpr(Node);
+  Doc.addAttribute("value", Node->getValue());
+}
+
+void StmtXML::VisitIntegerLiteral(IntegerLiteral *Node) {
+  DumpExpr(Node);
+  bool isSigned = Node->getType()->isSignedIntegerType();
+  Doc.addAttribute("value", Node->getValue().toString(10, isSigned));
+}
+
+void StmtXML::VisitFloatingLiteral(FloatingLiteral *Node) {
+  DumpExpr(Node);
+  // FIXME: output float as written in source (no approximation or the like)
+  //Doc.addAttribute("value", Node->getValueAsApproximateDouble()));
+  Doc.addAttribute("value", "FIXME");
+}
+
+void StmtXML::VisitStringLiteral(StringLiteral *Str) {
+  DumpExpr(Str);
+  if (Str->isWide())
+    Doc.addAttribute("is_wide", "1");
+
+  Doc.addAttribute("value", Doc.escapeString(Str->getStrData(), Str->getByteLength()));
+}
+
+
+const char *StmtXML::getOpcodeStr(UnaryOperator::Opcode Op) {
+  switch (Op) {
+  default: assert(0 && "Unknown unary operator");
+  case UnaryOperator::PostInc: return "postinc";
+  case UnaryOperator::PostDec: return "postdec";
+  case UnaryOperator::PreInc:  return "preinc";
+  case UnaryOperator::PreDec:  return "predec";
+  case UnaryOperator::AddrOf:  return "addrof";
+  case UnaryOperator::Deref:   return "deref";
+  case UnaryOperator::Plus:    return "plus";
+  case UnaryOperator::Minus:   return "minus";
+  case UnaryOperator::Not:     return "not";
+  case UnaryOperator::LNot:    return "lnot";
+  case UnaryOperator::Real:    return "__real";
+  case UnaryOperator::Imag:    return "__imag";
+  case UnaryOperator::Extension: return "__extension__";
+  case UnaryOperator::OffsetOf: return "__builtin_offsetof";
+  }
+}
+
+
+const char *StmtXML::getOpcodeStr(BinaryOperator::Opcode Op) {
+  switch (Op) {
+  default: assert(0 && "Unknown binary operator");
+  case BinaryOperator::PtrMemD:   return "ptrmemd";
+  case BinaryOperator::PtrMemI:   return "ptrmemi";
+  case BinaryOperator::Mul:       return "mul";
+  case BinaryOperator::Div:       return "div";
+  case BinaryOperator::Rem:       return "rem";
+  case BinaryOperator::Add:       return "add";
+  case BinaryOperator::Sub:       return "sub";
+  case BinaryOperator::Shl:       return "shl";
+  case BinaryOperator::Shr:       return "shr";
+  case BinaryOperator::LT:        return "lt";
+  case BinaryOperator::GT:        return "gt";
+  case BinaryOperator::LE:        return "le";
+  case BinaryOperator::GE:        return "ge";
+  case BinaryOperator::EQ:        return "eq";
+  case BinaryOperator::NE:        return "ne";
+  case BinaryOperator::And:       return "and";
+  case BinaryOperator::Xor:       return "xor";
+  case BinaryOperator::Or:        return "or";
+  case BinaryOperator::LAnd:      return "land";
+  case BinaryOperator::LOr:       return "lor";
+  case BinaryOperator::Assign:    return "assign";
+  case BinaryOperator::MulAssign: return "mulassign";
+  case BinaryOperator::DivAssign: return "divassign";
+  case BinaryOperator::RemAssign: return "remassign";
+  case BinaryOperator::AddAssign: return "addassign";
+  case BinaryOperator::SubAssign: return "subassign";
+  case BinaryOperator::ShlAssign: return "shlassign";
+  case BinaryOperator::ShrAssign: return "shrassign";
+  case BinaryOperator::AndAssign: return "andassign";
+  case BinaryOperator::XorAssign: return "xorassign";
+  case BinaryOperator::OrAssign:  return "orassign";
+  case BinaryOperator::Comma:     return "comma";
+  }
+}
+
+void StmtXML::VisitUnaryOperator(UnaryOperator *Node) {
+  DumpExpr(Node);
+  Doc.addAttribute("op_code", getOpcodeStr(Node->getOpcode()));
+}
+
+void StmtXML::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *Node) {
+  DumpExpr(Node);
+  Doc.addAttribute("is_sizeof", Node->isSizeOf() ? "sizeof" : "alignof");
+  Doc.addAttribute("is_type", Node->isArgumentType() ? "1" : "0");
+  if (Node->isArgumentType())
+    DumpTypeExpr(Node->getArgumentType());
+}
+
+void StmtXML::VisitMemberExpr(MemberExpr *Node) {
+  DumpExpr(Node);
+  Doc.addAttribute("is_deref", Node->isArrow() ? "1" : "0");
+  Doc.addAttribute("name", Node->getMemberDecl()->getNameAsString());
+  Doc.addRefAttribute(Node->getMemberDecl());
+}
+
+void StmtXML::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) {
+  DumpExpr(Node);
+  Doc.addAttribute("name", Node->getAccessor().getName());
+}
+
+void StmtXML::VisitBinaryOperator(BinaryOperator *Node) {
+  DumpExpr(Node);
+  Doc.addAttribute("op_code", getOpcodeStr(Node->getOpcode()));
+}
+
+void StmtXML::VisitCompoundAssignOperator(CompoundAssignOperator *Node) {
+  VisitBinaryOperator(Node);
+/* FIXME: is this needed in the AST?
+  DumpExpr(Node);
+  CurrentNode = CurrentNode->addSubNode("ComputeLHSTy");
+  DumpType(Node->getComputationLHSType());
+  CurrentNode = CurrentNode->Parent->addSubNode("ComputeResultTy");
+  DumpType(Node->getComputationResultType());
+  Doc.toParent();
+*/
+}
+
+// GNU extensions.
+
+void StmtXML::VisitAddrLabelExpr(AddrLabelExpr *Node) {
+  DumpExpr(Node);
+  Doc.addAttribute("name", Node->getLabel()->getName());
+}
+
+void StmtXML::VisitTypesCompatibleExpr(TypesCompatibleExpr *Node) {
+  DumpExpr(Node);
+  DumpTypeExpr(Node->getArgType1());
+  DumpTypeExpr(Node->getArgType2());
+}
+
+//===----------------------------------------------------------------------===//
+// C++ Expressions
+//===----------------------------------------------------------------------===//
+
+void StmtXML::VisitCXXNamedCastExpr(CXXNamedCastExpr *Node) {
+  DumpExpr(Node);
+  Doc.addAttribute("kind", Node->getCastName());
+  DumpTypeExpr(Node->getTypeAsWritten());
+}
+
+void StmtXML::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) {
+  DumpExpr(Node);
+  Doc.addAttribute("value", Node->getValue() ? "true" : "false");
+}
+
+void StmtXML::VisitCXXThisExpr(CXXThisExpr *Node) {
+  DumpExpr(Node);
+}
+
+void StmtXML::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node) {
+  DumpExpr(Node);
+  DumpTypeExpr(Node->getTypeAsWritten());
+}
+
+//===----------------------------------------------------------------------===//
+// Obj-C Expressions
+//===----------------------------------------------------------------------===//
+
+void StmtXML::VisitObjCMessageExpr(ObjCMessageExpr* Node) {
+  DumpExpr(Node);
+  Doc.addAttribute("selector", Node->getSelector().getAsString());
+  IdentifierInfo* clsName = Node->getClassName();
+  if (clsName)
+    Doc.addAttribute("class", clsName->getName());
+}
+
+void StmtXML::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) {
+  DumpExpr(Node);
+  DumpTypeExpr(Node->getEncodedType());
+}
+
+void StmtXML::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) {
+  DumpExpr(Node);
+  Doc.addAttribute("selector", Node->getSelector().getAsString());
+}
+
+void StmtXML::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) {
+  DumpExpr(Node);
+  Doc.addAttribute("protocol", Node->getProtocol()->getNameAsString());
+}
+
+void StmtXML::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) {
+  DumpExpr(Node);
+  Doc.addAttribute("property", Node->getProperty()->getNameAsString());
+}
+
+void StmtXML::VisitObjCImplicitSetterGetterRefExpr(
+                             ObjCImplicitSetterGetterRefExpr *Node) {
+  DumpExpr(Node);
+  ObjCMethodDecl *Getter = Node->getGetterMethod();
+  ObjCMethodDecl *Setter = Node->getSetterMethod();
+  Doc.addAttribute("Getter", Getter->getSelector().getAsString());
+  Doc.addAttribute("Setter", Setter ? Setter->getSelector().getAsString().c_str() : "(null)");
+}
+
+void StmtXML::VisitObjCSuperExpr(ObjCSuperExpr *Node) {
+  DumpExpr(Node);
+  Doc.addAttribute("super", "1");
+}
+
+void StmtXML::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) {
+  DumpExpr(Node);
+  Doc.addAttribute("kind", Node->getDecl()->getDeclKindName());
+  Doc.addAttribute("decl", Node->getDecl()->getNameAsString());
+  if (Node->isFreeIvar())
+    Doc.addAttribute("isFreeIvar", "1");
+}
+#endif
+//===----------------------------------------------------------------------===//
+// Stmt method implementations
+//===----------------------------------------------------------------------===//
+
+/// dumpAll - This does a dump of the specified AST fragment and all subtrees.
+void DocumentXML::PrintStmt(const Stmt *S) {
+  StmtXML P(*this);
+  P.DumpSubTree(const_cast<Stmt*>(S));
+}
+
diff --git a/lib/Frontend/TextDiagnosticBuffer.cpp b/lib/Frontend/TextDiagnosticBuffer.cpp
new file mode 100644
index 0000000..fdf2ec8
--- /dev/null
+++ b/lib/Frontend/TextDiagnosticBuffer.cpp
@@ -0,0 +1,48 @@
+//===--- TextDiagnosticBuffer.cpp - Buffer Text Diagnostics ---------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This is a concrete diagnostic client, which buffers the diagnostic messages.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/TextDiagnosticBuffer.h"
+#include "llvm/ADT/SmallString.h"
+using namespace clang;
+
+/// HandleDiagnostic - Store the errors, warnings, and notes that are
+/// reported.
+///
+void TextDiagnosticBuffer::HandleDiagnostic(Diagnostic::Level Level,
+                                            const DiagnosticInfo &Info) {
+  llvm::SmallString<100> Buf;
+  Info.FormatDiagnostic(Buf);
+  switch (Level) {
+  default: assert(0 && "Diagnostic not handled during diagnostic buffering!");
+  case Diagnostic::Note:
+    Notes.push_back(std::make_pair(Info.getLocation(), Buf.str()));
+    break;
+  case Diagnostic::Warning:
+    Warnings.push_back(std::make_pair(Info.getLocation(), Buf.str()));
+    break;
+  case Diagnostic::Error:
+  case Diagnostic::Fatal:
+    Errors.push_back(std::make_pair(Info.getLocation(), Buf.str()));
+    break;
+  }
+}
+
+void TextDiagnosticBuffer::FlushDiagnostics(Diagnostic &Diags) const {
+  // FIXME: Flush the diagnostics in order.
+  for (const_iterator it = err_begin(), ie = err_end(); it != ie; ++it)
+    Diags.Report(Diags.getCustomDiagID(Diagnostic::Error, it->second.c_str()));
+  for (const_iterator it = warn_begin(), ie = warn_end(); it != ie; ++it)
+    Diags.Report(Diags.getCustomDiagID(Diagnostic::Warning,it->second.c_str()));
+  for (const_iterator it = note_begin(), ie = note_end(); it != ie; ++it)
+    Diags.Report(Diags.getCustomDiagID(Diagnostic::Note, it->second.c_str()));
+}
diff --git a/lib/Frontend/TextDiagnosticPrinter.cpp b/lib/Frontend/TextDiagnosticPrinter.cpp
new file mode 100644
index 0000000..28bb17a
--- /dev/null
+++ b/lib/Frontend/TextDiagnosticPrinter.cpp
@@ -0,0 +1,876 @@
+//===--- TextDiagnosticPrinter.cpp - Diagnostic Printer -------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This diagnostic client prints out their diagnostic messages.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/TextDiagnosticPrinter.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Frontend/DiagnosticOptions.h"
+#include "clang/Lex/Lexer.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/ADT/SmallString.h"
+#include <algorithm>
+using namespace clang;
+
+static const enum llvm::raw_ostream::Colors noteColor =
+  llvm::raw_ostream::BLACK;
+static const enum llvm::raw_ostream::Colors fixitColor =
+  llvm::raw_ostream::GREEN;
+static const enum llvm::raw_ostream::Colors caretColor =
+  llvm::raw_ostream::GREEN;
+static const enum llvm::raw_ostream::Colors warningColor =
+  llvm::raw_ostream::MAGENTA;
+static const enum llvm::raw_ostream::Colors errorColor = llvm::raw_ostream::RED;
+static const enum llvm::raw_ostream::Colors fatalColor = llvm::raw_ostream::RED;
+// Used for changing only the bold attribute.
+static const enum llvm::raw_ostream::Colors savedColor =
+  llvm::raw_ostream::SAVEDCOLOR;
+
+/// \brief Number of spaces to indent when word-wrapping.
+const unsigned WordWrapIndentation = 6;
+
+TextDiagnosticPrinter::TextDiagnosticPrinter(llvm::raw_ostream &os,
+                                             const DiagnosticOptions &diags,
+                                             bool _OwnsOutputStream)
+  : OS(os), LangOpts(0), DiagOpts(&diags),
+    LastCaretDiagnosticWasNote(0),
+    OwnsOutputStream(_OwnsOutputStream) {
+}
+
+TextDiagnosticPrinter::~TextDiagnosticPrinter() {
+  if (OwnsOutputStream)
+    delete &OS;
+}
+
+void TextDiagnosticPrinter::
+PrintIncludeStack(SourceLocation Loc, const SourceManager &SM) {
+  if (Loc.isInvalid()) return;
+
+  PresumedLoc PLoc = SM.getPresumedLoc(Loc);
+
+  // Print out the other include frames first.
+  PrintIncludeStack(PLoc.getIncludeLoc(), SM);
+
+  if (DiagOpts->ShowLocation)
+    OS << "In file included from " << PLoc.getFilename()
+       << ':' << PLoc.getLine() << ":\n";
+  else
+    OS << "In included file:\n";
+}
+
+/// HighlightRange - Given a SourceRange and a line number, highlight (with ~'s)
+/// any characters in LineNo that intersect the SourceRange.
+void TextDiagnosticPrinter::HighlightRange(const SourceRange &R,
+                                           const SourceManager &SM,
+                                           unsigned LineNo, FileID FID,
+                                           std::string &CaretLine,
+                                           const std::string &SourceLine) {
+  assert(CaretLine.size() == SourceLine.size() &&
+         "Expect a correspondence between source and caret line!");
+  if (!R.isValid()) return;
+
+  SourceLocation Begin = SM.getInstantiationLoc(R.getBegin());
+  SourceLocation End = SM.getInstantiationLoc(R.getEnd());
+
+  // If the End location and the start location are the same and are a macro
+  // location, then the range was something that came from a macro expansion
+  // or _Pragma.  If this is an object-like macro, the best we can do is to
+  // highlight the range.  If this is a function-like macro, we'd also like to
+  // highlight the arguments.
+  if (Begin == End && R.getEnd().isMacroID())
+    End = SM.getInstantiationRange(R.getEnd()).second;
+
+  unsigned StartLineNo = SM.getInstantiationLineNumber(Begin);
+  if (StartLineNo > LineNo || SM.getFileID(Begin) != FID)
+    return;  // No intersection.
+
+  unsigned EndLineNo = SM.getInstantiationLineNumber(End);
+  if (EndLineNo < LineNo || SM.getFileID(End) != FID)
+    return;  // No intersection.
+
+  // Compute the column number of the start.
+  unsigned StartColNo = 0;
+  if (StartLineNo == LineNo) {
+    StartColNo = SM.getInstantiationColumnNumber(Begin);
+    if (StartColNo) --StartColNo;  // Zero base the col #.
+  }
+
+  // Compute the column number of the end.
+  unsigned EndColNo = CaretLine.size();
+  if (EndLineNo == LineNo) {
+    EndColNo = SM.getInstantiationColumnNumber(End);
+    if (EndColNo) {
+      --EndColNo;  // Zero base the col #.
+
+      // Add in the length of the token, so that we cover multi-char tokens.
+      EndColNo += Lexer::MeasureTokenLength(End, SM, *LangOpts);
+    } else {
+      EndColNo = CaretLine.size();
+    }
+  }
+
+  assert(StartColNo <= EndColNo && "Invalid range!");
+
+  // Pick the first non-whitespace column.
+  while (StartColNo < SourceLine.size() &&
+         (SourceLine[StartColNo] == ' ' || SourceLine[StartColNo] == '\t'))
+    ++StartColNo;
+
+  // Pick the last non-whitespace column.
+  if (EndColNo > SourceLine.size())
+    EndColNo = SourceLine.size();
+  while (EndColNo-1 &&
+         (SourceLine[EndColNo-1] == ' ' || SourceLine[EndColNo-1] == '\t'))
+    --EndColNo;
+
+  // If the start/end passed each other, then we are trying to highlight a range
+  // that just exists in whitespace, which must be some sort of other bug.
+  assert(StartColNo <= EndColNo && "Trying to highlight whitespace??");
+
+  // Fill the range with ~'s.
+  for (unsigned i = StartColNo; i < EndColNo; ++i)
+    CaretLine[i] = '~';
+}
+
+/// \brief When the source code line we want to print is too long for
+/// the terminal, select the "interesting" region.
+static void SelectInterestingSourceRegion(std::string &SourceLine,
+                                          std::string &CaretLine,
+                                          std::string &FixItInsertionLine,
+                                          unsigned EndOfCaretToken,
+                                          unsigned Columns) {
+  unsigned MaxSize = std::max(SourceLine.size(),
+                              std::max(CaretLine.size(), 
+                                       FixItInsertionLine.size()));
+  if (MaxSize > SourceLine.size())
+    SourceLine.resize(MaxSize, ' ');
+  if (MaxSize > CaretLine.size())
+    CaretLine.resize(MaxSize, ' ');
+  if (!FixItInsertionLine.empty() && MaxSize > FixItInsertionLine.size())
+    FixItInsertionLine.resize(MaxSize, ' ');
+    
+  // Find the slice that we need to display the full caret line
+  // correctly.
+  unsigned CaretStart = 0, CaretEnd = CaretLine.size();
+  for (; CaretStart != CaretEnd; ++CaretStart)
+    if (!isspace(CaretLine[CaretStart]))
+      break;
+
+  for (; CaretEnd != CaretStart; --CaretEnd)
+    if (!isspace(CaretLine[CaretEnd - 1]))
+      break;
+
+  // Make sure we don't chop the string shorter than the caret token
+  // itself.
+  if (CaretEnd < EndOfCaretToken)
+    CaretEnd = EndOfCaretToken;
+
+  // If we have a fix-it line, make sure the slice includes all of the
+  // fix-it information.
+  if (!FixItInsertionLine.empty()) {
+    unsigned FixItStart = 0, FixItEnd = FixItInsertionLine.size();
+    for (; FixItStart != FixItEnd; ++FixItStart)
+      if (!isspace(FixItInsertionLine[FixItStart]))
+        break;
+
+    for (; FixItEnd != FixItStart; --FixItEnd)
+      if (!isspace(FixItInsertionLine[FixItEnd - 1]))
+        break;
+
+    if (FixItStart < CaretStart)
+      CaretStart = FixItStart;
+    if (FixItEnd > CaretEnd)
+      CaretEnd = FixItEnd;
+  }
+
+  // CaretLine[CaretStart, CaretEnd) contains all of the interesting
+  // parts of the caret line. While this slice is smaller than the
+  // number of columns we have, try to grow the slice to encompass
+  // more context.
+
+  // If the end of the interesting region comes before we run out of
+  // space in the terminal, start at the beginning of the line.
+  if (Columns > 3 && CaretEnd < Columns - 3)
+    CaretStart = 0;
+
+  unsigned TargetColumns = Columns;
+  if (TargetColumns > 8)
+    TargetColumns -= 8; // Give us extra room for the ellipses.
+  unsigned SourceLength = SourceLine.size();
+  while ((CaretEnd - CaretStart) < TargetColumns) {
+    bool ExpandedRegion = false;
+    // Move the start of the interesting region left until we've
+    // pulled in something else interesting.
+    if (CaretStart == 1)
+      CaretStart = 0;
+    else if (CaretStart > 1) {
+      unsigned NewStart = CaretStart - 1;
+
+      // Skip over any whitespace we see here; we're looking for
+      // another bit of interesting text.
+      while (NewStart && isspace(SourceLine[NewStart]))
+        --NewStart;
+
+      // Skip over this bit of "interesting" text.
+      while (NewStart && !isspace(SourceLine[NewStart]))
+        --NewStart;
+
+      // Move up to the non-whitespace character we just saw.
+      if (NewStart)
+        ++NewStart;
+
+      // If we're still within our limit, update the starting
+      // position within the source/caret line.
+      if (CaretEnd - NewStart <= TargetColumns) {
+        CaretStart = NewStart;
+        ExpandedRegion = true;
+      }
+    }
+
+    // Move the end of the interesting region right until we've
+    // pulled in something else interesting.
+    if (CaretEnd != SourceLength) {
+      assert(CaretEnd < SourceLength && "Unexpected caret position!");
+      unsigned NewEnd = CaretEnd;
+
+      // Skip over any whitespace we see here; we're looking for
+      // another bit of interesting text.
+      while (NewEnd != SourceLength && isspace(SourceLine[NewEnd - 1]))
+        ++NewEnd;
+
+      // Skip over this bit of "interesting" text.
+      while (NewEnd != SourceLength && !isspace(SourceLine[NewEnd - 1]))
+        ++NewEnd;
+
+      if (NewEnd - CaretStart <= TargetColumns) {
+        CaretEnd = NewEnd;
+        ExpandedRegion = true;
+      }
+    }
+
+    if (!ExpandedRegion)
+      break;
+  }
+
+  // [CaretStart, CaretEnd) is the slice we want. Update the various
+  // output lines to show only this slice, with two-space padding
+  // before the lines so that it looks nicer.
+  if (CaretEnd < SourceLine.size())
+    SourceLine.replace(CaretEnd, std::string::npos, "...");
+  if (CaretEnd < CaretLine.size())
+    CaretLine.erase(CaretEnd, std::string::npos);
+  if (FixItInsertionLine.size() > CaretEnd)
+    FixItInsertionLine.erase(CaretEnd, std::string::npos);
+
+  if (CaretStart > 2) {
+    SourceLine.replace(0, CaretStart, "  ...");
+    CaretLine.replace(0, CaretStart, "     ");
+    if (FixItInsertionLine.size() >= CaretStart)
+      FixItInsertionLine.replace(0, CaretStart, "     ");
+  }
+}
+
+void TextDiagnosticPrinter::EmitCaretDiagnostic(SourceLocation Loc,
+                                                SourceRange *Ranges,
+                                                unsigned NumRanges,
+                                                const SourceManager &SM,
+                                                const FixItHint *Hints,
+                                                unsigned NumHints,
+                                                unsigned Columns) {
+  assert(LangOpts && "Unexpected diagnostic outside source file processing");
+  assert(!Loc.isInvalid() && "must have a valid source location here");
+
+  // If this is a macro ID, first emit information about where this was
+  // instantiated (recursively) then emit information about where the token was
+  // spelled from.
+  if (!Loc.isFileID()) {
+    SourceLocation OneLevelUp = SM.getImmediateInstantiationRange(Loc).first;
+    // FIXME: Map ranges?
+    EmitCaretDiagnostic(OneLevelUp, Ranges, NumRanges, SM, 0, 0, Columns);
+
+    // Map the location.
+    Loc = SM.getImmediateSpellingLoc(Loc);
+
+    // Map the ranges.
+    for (unsigned i = 0; i != NumRanges; ++i) {
+      SourceLocation S = Ranges[i].getBegin(), E = Ranges[i].getEnd();
+      if (S.isMacroID()) S = SM.getImmediateSpellingLoc(S);
+      if (E.isMacroID()) E = SM.getImmediateSpellingLoc(E);
+      Ranges[i] = SourceRange(S, E);
+    }
+
+    // Get the pretty name, according to #line directives etc.
+    PresumedLoc PLoc = SM.getPresumedLoc(Loc);
+
+    // If this diagnostic is not in the main file, print out the "included from"
+    // lines.
+    if (LastWarningLoc != PLoc.getIncludeLoc()) {
+      LastWarningLoc = PLoc.getIncludeLoc();
+      PrintIncludeStack(LastWarningLoc, SM);
+    }
+
+    if (DiagOpts->ShowLocation) {
+      // Emit the file/line/column that this expansion came from.
+      OS << PLoc.getFilename() << ':' << PLoc.getLine() << ':';
+      if (DiagOpts->ShowColumn)
+        OS << PLoc.getColumn() << ':';
+      OS << ' ';
+    }
+    OS << "note: instantiated from:\n";
+
+    EmitCaretDiagnostic(Loc, Ranges, NumRanges, SM, Hints, NumHints, Columns);
+    return;
+  }
+
+  // Decompose the location into a FID/Offset pair.
+  std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Loc);
+  FileID FID = LocInfo.first;
+  unsigned FileOffset = LocInfo.second;
+
+  // Get information about the buffer it points into.
+  bool Invalid = false;
+  const char *BufStart = SM.getBufferData(FID, &Invalid).data();
+  if (Invalid)
+    return;
+
+  unsigned ColNo = SM.getColumnNumber(FID, FileOffset);
+  unsigned CaretEndColNo
+    = ColNo + Lexer::MeasureTokenLength(Loc, SM, *LangOpts);
+
+  // Rewind from the current position to the start of the line.
+  const char *TokPtr = BufStart+FileOffset;
+  const char *LineStart = TokPtr-ColNo+1; // Column # is 1-based.
+
+
+  // Compute the line end.  Scan forward from the error position to the end of
+  // the line.
+  const char *LineEnd = TokPtr;
+  while (*LineEnd != '\n' && *LineEnd != '\r' && *LineEnd != '\0')
+    ++LineEnd;
+
+  // FIXME: This shouldn't be necessary, but the CaretEndColNo can extend past
+  // the source line length as currently being computed. See
+  // test/Misc/message-length.c.
+  CaretEndColNo = std::min(CaretEndColNo, unsigned(LineEnd - LineStart));
+
+  // Copy the line of code into an std::string for ease of manipulation.
+  std::string SourceLine(LineStart, LineEnd);
+
+  // Create a line for the caret that is filled with spaces that is the same
+  // length as the line of source code.
+  std::string CaretLine(LineEnd-LineStart, ' ');
+
+  // Highlight all of the characters covered by Ranges with ~ characters.
+  if (NumRanges) {
+    unsigned LineNo = SM.getLineNumber(FID, FileOffset);
+
+    for (unsigned i = 0, e = NumRanges; i != e; ++i)
+      HighlightRange(Ranges[i], SM, LineNo, FID, CaretLine, SourceLine);
+  }
+
+  // Next, insert the caret itself.
+  if (ColNo-1 < CaretLine.size())
+    CaretLine[ColNo-1] = '^';
+  else
+    CaretLine.push_back('^');
+
+  // Scan the source line, looking for tabs.  If we find any, manually expand
+  // them to spaces and update the CaretLine to match.
+  for (unsigned i = 0; i != SourceLine.size(); ++i) {
+    if (SourceLine[i] != '\t') continue;
+
+    // Replace this tab with at least one space.
+    SourceLine[i] = ' ';
+
+    // Compute the number of spaces we need to insert.
+    unsigned TabStop = DiagOpts->TabStop;
+    assert(0 < TabStop && TabStop <= DiagnosticOptions::MaxTabStop &&
+           "Invalid -ftabstop value");
+    unsigned NumSpaces = ((i+TabStop)/TabStop * TabStop) - (i+1);
+    assert(NumSpaces < TabStop && "Invalid computation of space amt");
+
+    // Insert spaces into the SourceLine.
+    SourceLine.insert(i+1, NumSpaces, ' ');
+
+    // Insert spaces or ~'s into CaretLine.
+    CaretLine.insert(i+1, NumSpaces, CaretLine[i] == '~' ? '~' : ' ');
+  }
+
+  // If we are in -fdiagnostics-print-source-range-info mode, we are trying to
+  // produce easily machine parsable output.  Add a space before the source line
+  // and the caret to make it trivial to tell the main diagnostic line from what
+  // the user is intended to see.
+  if (DiagOpts->ShowSourceRanges) {
+    SourceLine = ' ' + SourceLine;
+    CaretLine = ' ' + CaretLine;
+  }
+
+  std::string FixItInsertionLine;
+  if (NumHints && DiagOpts->ShowFixits) {
+    for (const FixItHint *Hint = Hints, *LastHint = Hints + NumHints;
+         Hint != LastHint; ++Hint) {
+      if (Hint->InsertionLoc.isValid()) {
+        // We have an insertion hint. Determine whether the inserted
+        // code is on the same line as the caret.
+        std::pair<FileID, unsigned> HintLocInfo
+          = SM.getDecomposedInstantiationLoc(Hint->InsertionLoc);
+        if (SM.getLineNumber(HintLocInfo.first, HintLocInfo.second) ==
+              SM.getLineNumber(FID, FileOffset)) {
+          // Insert the new code into the line just below the code
+          // that the user wrote.
+          unsigned HintColNo
+            = SM.getColumnNumber(HintLocInfo.first, HintLocInfo.second);
+          unsigned LastColumnModified
+            = HintColNo - 1 + Hint->CodeToInsert.size();
+          if (LastColumnModified > FixItInsertionLine.size())
+            FixItInsertionLine.resize(LastColumnModified, ' ');
+          std::copy(Hint->CodeToInsert.begin(), Hint->CodeToInsert.end(),
+                    FixItInsertionLine.begin() + HintColNo - 1);
+        } else {
+          FixItInsertionLine.clear();
+          break;
+        }
+      }
+    }
+    // Now that we have the entire fixit line, expand the tabs in it.
+    // Since we don't want to insert spaces in the middle of a word,
+    // find each word and the column it should line up with and insert
+    // spaces until they match.
+    if (!FixItInsertionLine.empty()) {
+      unsigned FixItPos = 0;
+      unsigned LinePos = 0;
+      unsigned TabExpandedCol = 0;
+      unsigned LineLength = LineEnd - LineStart;
+
+      while (FixItPos < FixItInsertionLine.size() && LinePos < LineLength) {
+        // Find the next word in the FixIt line.
+        while (FixItPos < FixItInsertionLine.size() &&
+               FixItInsertionLine[FixItPos] == ' ')
+          ++FixItPos;
+        unsigned CharDistance = FixItPos - TabExpandedCol;
+
+        // Walk forward in the source line, keeping track of
+        // the tab-expanded column.
+        for (unsigned I = 0; I < CharDistance; ++I, ++LinePos)
+          if (LinePos >= LineLength || LineStart[LinePos] != '\t')
+            ++TabExpandedCol;
+          else
+            TabExpandedCol =
+              (TabExpandedCol/DiagOpts->TabStop + 1) * DiagOpts->TabStop;
+
+        // Adjust the fixit line to match this column.
+        FixItInsertionLine.insert(FixItPos, TabExpandedCol-FixItPos, ' ');
+        FixItPos = TabExpandedCol;
+
+        // Walk to the end of the word.
+        while (FixItPos < FixItInsertionLine.size() &&
+               FixItInsertionLine[FixItPos] != ' ')
+          ++FixItPos;
+      }
+    }
+  }
+
+  // If the source line is too long for our terminal, select only the
+  // "interesting" source region within that line.
+  if (Columns && SourceLine.size() > Columns)
+    SelectInterestingSourceRegion(SourceLine, CaretLine, FixItInsertionLine,
+                                  CaretEndColNo, Columns);
+
+  // Finally, remove any blank spaces from the end of CaretLine.
+  while (CaretLine[CaretLine.size()-1] == ' ')
+    CaretLine.erase(CaretLine.end()-1);
+
+  // Emit what we have computed.
+  OS << SourceLine << '\n';
+
+  if (DiagOpts->ShowColors)
+    OS.changeColor(caretColor, true);
+  OS << CaretLine << '\n';
+  if (DiagOpts->ShowColors)
+    OS.resetColor();
+
+  if (!FixItInsertionLine.empty()) {
+    if (DiagOpts->ShowColors)
+      // Print fixit line in color
+      OS.changeColor(fixitColor, false);
+    if (DiagOpts->ShowSourceRanges)
+      OS << ' ';
+    OS << FixItInsertionLine << '\n';
+    if (DiagOpts->ShowColors)
+      OS.resetColor();
+  }
+}
+
+/// \brief Skip over whitespace in the string, starting at the given
+/// index.
+///
+/// \returns The index of the first non-whitespace character that is
+/// greater than or equal to Idx or, if no such character exists,
+/// returns the end of the string.
+static unsigned skipWhitespace(unsigned Idx,
+                               const llvm::SmallVectorImpl<char> &Str,
+                               unsigned Length) {
+  while (Idx < Length && isspace(Str[Idx]))
+    ++Idx;
+  return Idx;
+}
+
+/// \brief If the given character is the start of some kind of
+/// balanced punctuation (e.g., quotes or parentheses), return the
+/// character that will terminate the punctuation.
+///
+/// \returns The ending punctuation character, if any, or the NULL
+/// character if the input character does not start any punctuation.
+static inline char findMatchingPunctuation(char c) {
+  switch (c) {
+  case '\'': return '\'';
+  case '`': return '\'';
+  case '"':  return '"';
+  case '(':  return ')';
+  case '[': return ']';
+  case '{': return '}';
+  default: break;
+  }
+
+  return 0;
+}
+
+/// \brief Find the end of the word starting at the given offset
+/// within a string.
+///
+/// \returns the index pointing one character past the end of the
+/// word.
+static unsigned findEndOfWord(unsigned Start,
+                              const llvm::SmallVectorImpl<char> &Str,
+                              unsigned Length, unsigned Column,
+                              unsigned Columns) {
+  assert(Start < Str.size() && "Invalid start position!");
+  unsigned End = Start + 1;
+
+  // If we are already at the end of the string, take that as the word.
+  if (End == Str.size())
+    return End;
+
+  // Determine if the start of the string is actually opening
+  // punctuation, e.g., a quote or parentheses.
+  char EndPunct = findMatchingPunctuation(Str[Start]);
+  if (!EndPunct) {
+    // This is a normal word. Just find the first space character.
+    while (End < Length && !isspace(Str[End]))
+      ++End;
+    return End;
+  }
+
+  // We have the start of a balanced punctuation sequence (quotes,
+  // parentheses, etc.). Determine the full sequence is.
+  llvm::SmallString<16> PunctuationEndStack;
+  PunctuationEndStack.push_back(EndPunct);
+  while (End < Length && !PunctuationEndStack.empty()) {
+    if (Str[End] == PunctuationEndStack.back())
+      PunctuationEndStack.pop_back();
+    else if (char SubEndPunct = findMatchingPunctuation(Str[End]))
+      PunctuationEndStack.push_back(SubEndPunct);
+
+    ++End;
+  }
+
+  // Find the first space character after the punctuation ended.
+  while (End < Length && !isspace(Str[End]))
+    ++End;
+
+  unsigned PunctWordLength = End - Start;
+  if (// If the word fits on this line
+      Column + PunctWordLength <= Columns ||
+      // ... or the word is "short enough" to take up the next line
+      // without too much ugly white space
+      PunctWordLength < Columns/3)
+    return End; // Take the whole thing as a single "word".
+
+  // The whole quoted/parenthesized string is too long to print as a
+  // single "word". Instead, find the "word" that starts just after
+  // the punctuation and use that end-point instead. This will recurse
+  // until it finds something small enough to consider a word.
+  return findEndOfWord(Start + 1, Str, Length, Column + 1, Columns);
+}
+
+/// \brief Print the given string to a stream, word-wrapping it to
+/// some number of columns in the process.
+///
+/// \brief OS the stream to which the word-wrapping string will be
+/// emitted.
+///
+/// \brief Str the string to word-wrap and output.
+///
+/// \brief Columns the number of columns to word-wrap to.
+///
+/// \brief Column the column number at which the first character of \p
+/// Str will be printed. This will be non-zero when part of the first
+/// line has already been printed.
+///
+/// \brief Indentation the number of spaces to indent any lines beyond
+/// the first line.
+///
+/// \returns true if word-wrapping was required, or false if the
+/// string fit on the first line.
+static bool PrintWordWrapped(llvm::raw_ostream &OS,
+                             const llvm::SmallVectorImpl<char> &Str,
+                             unsigned Columns,
+                             unsigned Column = 0,
+                             unsigned Indentation = WordWrapIndentation) {
+  unsigned Length = Str.size();
+
+  // If there is a newline in this message somewhere, find that
+  // newline and split the message into the part before the newline
+  // (which will be word-wrapped) and the part from the newline one
+  // (which will be emitted unchanged).
+  for (unsigned I = 0; I != Length; ++I)
+    if (Str[I] == '\n') {
+      Length = I;
+      break;
+    }
+
+  // The string used to indent each line.
+  llvm::SmallString<16> IndentStr;
+  IndentStr.assign(Indentation, ' ');
+  bool Wrapped = false;
+  for (unsigned WordStart = 0, WordEnd; WordStart < Length;
+       WordStart = WordEnd) {
+    // Find the beginning of the next word.
+    WordStart = skipWhitespace(WordStart, Str, Length);
+    if (WordStart == Length)
+      break;
+
+    // Find the end of this word.
+    WordEnd = findEndOfWord(WordStart, Str, Length, Column, Columns);
+
+    // Does this word fit on the current line?
+    unsigned WordLength = WordEnd - WordStart;
+    if (Column + WordLength < Columns) {
+      // This word fits on the current line; print it there.
+      if (WordStart) {
+        OS << ' ';
+        Column += 1;
+      }
+      OS.write(&Str[WordStart], WordLength);
+      Column += WordLength;
+      continue;
+    }
+
+    // This word does not fit on the current line, so wrap to the next
+    // line.
+    OS << '\n';
+    OS.write(&IndentStr[0], Indentation);
+    OS.write(&Str[WordStart], WordLength);
+    Column = Indentation + WordLength;
+    Wrapped = true;
+  }
+
+  if (Length == Str.size())
+    return Wrapped; // We're done.
+
+  // There is a newline in the message, followed by something that
+  // will not be word-wrapped. Print that.
+  OS.write(&Str[Length], Str.size() - Length);
+  return true;
+}
+
+void TextDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level,
+                                             const DiagnosticInfo &Info) {
+  // Keeps track of the the starting position of the location
+  // information (e.g., "foo.c:10:4:") that precedes the error
+  // message. We use this information to determine how long the
+  // file+line+column number prefix is.
+  uint64_t StartOfLocationInfo = OS.tell();
+
+  if (!Prefix.empty())
+    OS << Prefix << ": ";
+
+  // If the location is specified, print out a file/line/col and include trace
+  // if enabled.
+  if (Info.getLocation().isValid()) {
+    const SourceManager &SM = Info.getLocation().getManager();
+    PresumedLoc PLoc = SM.getPresumedLoc(Info.getLocation());
+    unsigned LineNo = PLoc.getLine();
+
+    // First, if this diagnostic is not in the main file, print out the
+    // "included from" lines.
+    if (LastWarningLoc != PLoc.getIncludeLoc()) {
+      LastWarningLoc = PLoc.getIncludeLoc();
+      PrintIncludeStack(LastWarningLoc, SM);
+      StartOfLocationInfo = OS.tell();
+    }
+
+    // Compute the column number.
+    if (DiagOpts->ShowLocation) {
+      if (DiagOpts->ShowColors)
+        OS.changeColor(savedColor, true);
+
+      // Emit a Visual Studio compatible line number syntax.
+      if (LangOpts && LangOpts->Microsoft) {
+        OS << PLoc.getFilename() << '(' << LineNo << ')';
+        OS << " : ";
+      } else {
+        OS << PLoc.getFilename() << ':' << LineNo << ':';
+        if (DiagOpts->ShowColumn)
+          if (unsigned ColNo = PLoc.getColumn())
+            OS << ColNo << ':';
+      }
+      if (DiagOpts->ShowSourceRanges && Info.getNumRanges()) {
+        FileID CaretFileID =
+          SM.getFileID(SM.getInstantiationLoc(Info.getLocation()));
+        bool PrintedRange = false;
+
+        for (unsigned i = 0, e = Info.getNumRanges(); i != e; ++i) {
+          // Ignore invalid ranges.
+          if (!Info.getRange(i).isValid()) continue;
+
+          SourceLocation B = Info.getRange(i).getBegin();
+          SourceLocation E = Info.getRange(i).getEnd();
+          B = SM.getInstantiationLoc(B);
+          E = SM.getInstantiationLoc(E);
+
+          // If the End location and the start location are the same and are a
+          // macro location, then the range was something that came from a macro
+          // expansion or _Pragma.  If this is an object-like macro, the best we
+          // can do is to highlight the range.  If this is a function-like
+          // macro, we'd also like to highlight the arguments.
+          if (B == E && Info.getRange(i).getEnd().isMacroID())
+            E = SM.getInstantiationRange(Info.getRange(i).getEnd()).second;
+
+          std::pair<FileID, unsigned> BInfo = SM.getDecomposedLoc(B);
+          std::pair<FileID, unsigned> EInfo = SM.getDecomposedLoc(E);
+
+          // If the start or end of the range is in another file, just discard
+          // it.
+          if (BInfo.first != CaretFileID || EInfo.first != CaretFileID)
+            continue;
+
+          // Add in the length of the token, so that we cover multi-char tokens.
+          unsigned TokSize = Lexer::MeasureTokenLength(E, SM, *LangOpts);
+
+          OS << '{' << SM.getLineNumber(BInfo.first, BInfo.second) << ':'
+             << SM.getColumnNumber(BInfo.first, BInfo.second) << '-'
+             << SM.getLineNumber(EInfo.first, EInfo.second) << ':'
+             << (SM.getColumnNumber(EInfo.first, EInfo.second)+TokSize) << '}';
+          PrintedRange = true;
+        }
+
+        if (PrintedRange)
+          OS << ':';
+      }
+      OS << ' ';
+      if (DiagOpts->ShowColors)
+        OS.resetColor();
+    }
+  }
+
+  if (DiagOpts->ShowColors) {
+    // Print diagnostic category in bold and color
+    switch (Level) {
+    case Diagnostic::Ignored: assert(0 && "Invalid diagnostic type");
+    case Diagnostic::Note:    OS.changeColor(noteColor, true); break;
+    case Diagnostic::Warning: OS.changeColor(warningColor, true); break;
+    case Diagnostic::Error:   OS.changeColor(errorColor, true); break;
+    case Diagnostic::Fatal:   OS.changeColor(fatalColor, true); break;
+    }
+  }
+
+  switch (Level) {
+  case Diagnostic::Ignored: assert(0 && "Invalid diagnostic type");
+  case Diagnostic::Note:    OS << "note: "; break;
+  case Diagnostic::Warning: OS << "warning: "; break;
+  case Diagnostic::Error:   OS << "error: "; break;
+  case Diagnostic::Fatal:   OS << "fatal error: "; break;
+  }
+
+  if (DiagOpts->ShowColors)
+    OS.resetColor();
+
+  llvm::SmallString<100> OutStr;
+  Info.FormatDiagnostic(OutStr);
+
+  if (DiagOpts->ShowOptionNames) {
+    if (const char *Opt = Diagnostic::getWarningOptionForDiag(Info.getID())) {
+      OutStr += " [-W";
+      OutStr += Opt;
+      OutStr += ']';
+    } else {
+      // If the diagnostic is an extension diagnostic and not enabled by default
+      // then it must have been turned on with -pedantic.
+      bool EnabledByDefault;
+      if (Diagnostic::isBuiltinExtensionDiag(Info.getID(), EnabledByDefault) &&
+          !EnabledByDefault)
+        OutStr += " [-pedantic]";
+    }
+  }
+
+  if (DiagOpts->ShowColors) {
+    // Print warnings, errors and fatal errors in bold, no color
+    switch (Level) {
+    case Diagnostic::Warning: OS.changeColor(savedColor, true); break;
+    case Diagnostic::Error:   OS.changeColor(savedColor, true); break;
+    case Diagnostic::Fatal:   OS.changeColor(savedColor, true); break;
+    default: break; //don't bold notes
+    }
+  }
+
+  if (DiagOpts->MessageLength) {
+    // We will be word-wrapping the error message, so compute the
+    // column number where we currently are (after printing the
+    // location information).
+    unsigned Column = OS.tell() - StartOfLocationInfo;
+    PrintWordWrapped(OS, OutStr, DiagOpts->MessageLength, Column);
+  } else {
+    OS.write(OutStr.begin(), OutStr.size());
+  }
+  OS << '\n';
+  if (DiagOpts->ShowColors)
+    OS.resetColor();
+
+  // If caret diagnostics are enabled and we have location, we want to
+  // emit the caret.  However, we only do this if the location moved
+  // from the last diagnostic, if the last diagnostic was a note that
+  // was part of a different warning or error diagnostic, or if the
+  // diagnostic has ranges.  We don't want to emit the same caret
+  // multiple times if one loc has multiple diagnostics.
+  if (DiagOpts->ShowCarets && Info.getLocation().isValid() &&
+      ((LastLoc != Info.getLocation()) || Info.getNumRanges() ||
+       (LastCaretDiagnosticWasNote && Level != Diagnostic::Note) ||
+       Info.getNumFixItHints())) {
+    // Cache the LastLoc, it allows us to omit duplicate source/caret spewage.
+    LastLoc = Info.getLocation();
+    LastCaretDiagnosticWasNote = (Level == Diagnostic::Note);
+
+    // Get the ranges into a local array we can hack on.
+    SourceRange Ranges[20];
+    unsigned NumRanges = Info.getNumRanges();
+    assert(NumRanges < 20 && "Out of space");
+    for (unsigned i = 0; i != NumRanges; ++i)
+      Ranges[i] = Info.getRange(i);
+
+    unsigned NumHints = Info.getNumFixItHints();
+    for (unsigned idx = 0; idx < NumHints; ++idx) {
+      const FixItHint &Hint = Info.getFixItHint(idx);
+      if (Hint.RemoveRange.isValid()) {
+        assert(NumRanges < 20 && "Out of space");
+        Ranges[NumRanges++] = Hint.RemoveRange;
+      }
+    }
+
+    EmitCaretDiagnostic(LastLoc, Ranges, NumRanges, LastLoc.getManager(),
+                        Info.getFixItHints(),
+                        Info.getNumFixItHints(),
+                        DiagOpts->MessageLength);
+  }
+
+  OS.flush();
+}
diff --git a/lib/Frontend/TypeXML.cpp b/lib/Frontend/TypeXML.cpp
new file mode 100644
index 0000000..be9db42
--- /dev/null
+++ b/lib/Frontend/TypeXML.cpp
@@ -0,0 +1,119 @@
+//===--- DocumentXML.cpp - XML document for ASTs --------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the XML document class, which provides the means to
+// dump out the AST in a XML form that exposes type details and other fields.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/DocumentXML.h"
+#include "clang/AST/TypeVisitor.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/Decl.h"
+
+namespace clang {
+  namespace XML {
+    namespace {
+
+//---------------------------------------------------------
+class TypeWriter : public TypeVisitor<TypeWriter> {
+  DocumentXML& Doc;
+
+public:
+  TypeWriter(DocumentXML& doc) : Doc(doc) {}
+
+#define NODE_XML( CLASS, NAME )          \
+  void Visit##CLASS(CLASS* T) {          \
+    Doc.addSubNode(NAME);
+
+#define ID_ATTRIBUTE_XML                // done by the Document class itself
+#define ATTRIBUTE_XML( FN, NAME )       Doc.addAttribute(NAME, T->FN);
+#define TYPE_ATTRIBUTE_XML( FN )        ATTRIBUTE_XML(FN, "type")
+#define CONTEXT_ATTRIBUTE_XML( FN )     ATTRIBUTE_XML(FN, "context")
+#define ATTRIBUTE_OPT_XML( FN, NAME )   Doc.addAttributeOptional(NAME, T->FN);
+
+#define ATTRIBUTE_ENUM_XML( FN, NAME )  \
+  {                                     \
+    const char* pAttributeName = NAME;  \
+    const bool optional = false;             \
+    switch (T->FN) {                    \
+    default: assert(0 && "unknown enum value");
+
+#define ATTRIBUTE_ENUM_OPT_XML( FN, NAME )  \
+  {                                     \
+    const char* pAttributeName = NAME;  \
+    const bool optional = true;              \
+    switch (T->FN) {                    \
+    default: assert(0 && "unknown enum value");
+
+#define ENUM_XML( VALUE, NAME )         case VALUE: if ((!optional) || NAME[0]) Doc.addAttribute(pAttributeName, NAME); break;
+#define END_ENUM_XML                    } }
+#define END_NODE_XML                    }
+
+#include "clang/Frontend/TypeXML.def"
+
+};
+
+//---------------------------------------------------------
+    } // anon clang
+  } // NS XML
+
+//---------------------------------------------------------
+class DocumentXML::TypeAdder : public TypeVisitor<DocumentXML::TypeAdder> {
+  DocumentXML& Doc;
+
+  void addIfType(const Type* pType) {
+    Doc.addTypeRecursively(pType);
+  }
+
+  void addIfType(const QualType& pType) {
+    Doc.addTypeRecursively(pType);
+  }
+
+  template<class T> void addIfType(T) {}
+
+public:
+  TypeAdder(DocumentXML& doc) : Doc(doc) {}
+
+#define NODE_XML( CLASS, NAME )          \
+  void Visit##CLASS(CLASS* T)            \
+  {
+
+#define ID_ATTRIBUTE_XML
+#define TYPE_ATTRIBUTE_XML( FN )        Doc.addTypeRecursively(T->FN);
+#define CONTEXT_ATTRIBUTE_XML( FN )
+#define ATTRIBUTE_XML( FN, NAME )       addIfType(T->FN);
+#define ATTRIBUTE_OPT_XML( FN, NAME )
+#define ATTRIBUTE_ENUM_XML( FN, NAME )
+#define ATTRIBUTE_ENUM_OPT_XML( FN, NAME )
+#define ENUM_XML( VALUE, NAME )
+#define END_ENUM_XML
+#define END_NODE_XML                    }
+
+#include "clang/Frontend/TypeXML.def"
+};
+
+//---------------------------------------------------------
+void DocumentXML::addParentTypes(const Type* pType) {
+  TypeAdder(*this).Visit(const_cast<Type*>(pType));
+}
+
+//---------------------------------------------------------
+void DocumentXML::writeTypeToXML(const Type* pType) {
+  XML::TypeWriter(*this).Visit(const_cast<Type*>(pType));
+}
+
+//---------------------------------------------------------
+void DocumentXML::writeTypeToXML(const QualType& pType) {
+  XML::TypeWriter(*this).VisitQualType(const_cast<QualType*>(&pType));
+}
+
+//---------------------------------------------------------
+} // NS clang
+
diff --git a/lib/Frontend/VerifyDiagnosticsClient.cpp b/lib/Frontend/VerifyDiagnosticsClient.cpp
new file mode 100644
index 0000000..99ec910
--- /dev/null
+++ b/lib/Frontend/VerifyDiagnosticsClient.cpp
@@ -0,0 +1,346 @@
+//===--- VerifyDiagnosticsClient.cpp - Verifying Diagnostic Client --------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This is a concrete diagnostic client, which buffers the diagnostic messages.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/VerifyDiagnosticsClient.h"
+#include "clang/Frontend/FrontendDiagnostic.h"
+#include "clang/Frontend/TextDiagnosticBuffer.h"
+#include "clang/Lex/Preprocessor.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace clang;
+
+VerifyDiagnosticsClient::VerifyDiagnosticsClient(Diagnostic &_Diags,
+                                                 DiagnosticClient *_Primary)
+  : Diags(_Diags), PrimaryClient(_Primary),
+    Buffer(new TextDiagnosticBuffer()), CurrentPreprocessor(0), NumErrors(0) {
+}
+
+VerifyDiagnosticsClient::~VerifyDiagnosticsClient() {
+  CheckDiagnostics();
+}
+
+// DiagnosticClient interface.
+
+void VerifyDiagnosticsClient::BeginSourceFile(const LangOptions &LangOpts,
+                                             const Preprocessor *PP) {
+  // FIXME: Const hack, we screw up the preprocessor but in practice its ok
+  // because it doesn't get reused. It would be better if we could make a copy
+  // though.
+  CurrentPreprocessor = const_cast<Preprocessor*>(PP);
+
+  PrimaryClient->BeginSourceFile(LangOpts, PP);
+}
+
+void VerifyDiagnosticsClient::EndSourceFile() {
+  CheckDiagnostics();
+
+  PrimaryClient->EndSourceFile();
+
+  CurrentPreprocessor = 0;
+}
+
+void VerifyDiagnosticsClient::HandleDiagnostic(Diagnostic::Level DiagLevel,
+                                              const DiagnosticInfo &Info) {
+  // Send the diagnostic to the buffer, we will check it once we reach the end
+  // of the source file (or are destructed).
+  Buffer->HandleDiagnostic(DiagLevel, Info);
+}
+
+// FIXME: It would be nice to just get this from the primary diagnostic client
+// or something.
+bool VerifyDiagnosticsClient::HadErrors() {
+  CheckDiagnostics();
+
+  return NumErrors != 0;
+}
+
+//===----------------------------------------------------------------------===//
+// Checking diagnostics implementation.
+//===----------------------------------------------------------------------===//
+
+typedef TextDiagnosticBuffer::DiagList DiagList;
+typedef TextDiagnosticBuffer::const_iterator const_diag_iterator;
+
+/// FindDiagnostics - Go through the comment and see if it indicates expected
+/// diagnostics. If so, then put them in a diagnostic list.
+///
+static void FindDiagnostics(const char *CommentStart, unsigned CommentLen,
+                            DiagList &ExpectedDiags,
+                            Preprocessor &PP, SourceLocation Pos,
+                            const char *ExpectedStr) {
+  const char *CommentEnd = CommentStart+CommentLen;
+  unsigned ExpectedStrLen = strlen(ExpectedStr);
+
+  // Find all expected-foo diagnostics in the string and add them to
+  // ExpectedDiags.
+  while (CommentStart != CommentEnd) {
+    CommentStart = std::find(CommentStart, CommentEnd, 'e');
+    if (unsigned(CommentEnd-CommentStart) < ExpectedStrLen) return;
+
+    // If this isn't expected-foo, ignore it.
+    if (memcmp(CommentStart, ExpectedStr, ExpectedStrLen)) {
+      ++CommentStart;
+      continue;
+    }
+
+    CommentStart += ExpectedStrLen;
+
+    // Skip whitespace.
+    while (CommentStart != CommentEnd &&
+           isspace(CommentStart[0]))
+      ++CommentStart;
+
+    // Default, if we find the '{' now, is 1 time.
+    int Times = 1;
+    int Temp = 0;
+    // In extended syntax, there could be a digit now.
+    while (CommentStart != CommentEnd &&
+           CommentStart[0] >= '0' && CommentStart[0] <= '9') {
+      Temp *= 10;
+      Temp += CommentStart[0] - '0';
+      ++CommentStart;
+    }
+    if (Temp > 0)
+      Times = Temp;
+
+    // Skip whitespace again.
+    while (CommentStart != CommentEnd &&
+           isspace(CommentStart[0]))
+      ++CommentStart;
+
+    // We should have a {{ now.
+    if (CommentEnd-CommentStart < 2 ||
+        CommentStart[0] != '{' || CommentStart[1] != '{') {
+      if (std::find(CommentStart, CommentEnd, '{') != CommentEnd)
+        PP.Diag(Pos, diag::err_verify_bogus_characters);
+      else
+        PP.Diag(Pos, diag::err_verify_missing_start);
+      return;
+    }
+    CommentStart += 2;
+
+    // Find the }}.
+    const char *ExpectedEnd = CommentStart;
+    while (1) {
+      ExpectedEnd = std::find(ExpectedEnd, CommentEnd, '}');
+      if (CommentEnd-ExpectedEnd < 2) {
+        PP.Diag(Pos, diag::err_verify_missing_end);
+        return;
+      }
+
+      if (ExpectedEnd[1] == '}')
+        break;
+
+      ++ExpectedEnd;  // Skip over singular }'s
+    }
+
+    std::string Msg(CommentStart, ExpectedEnd);
+    std::string::size_type FindPos;
+    while ((FindPos = Msg.find("\\n")) != std::string::npos)
+      Msg.replace(FindPos, 2, "\n");
+    // Add is possibly multiple times.
+    for (int i = 0; i < Times; ++i)
+      ExpectedDiags.push_back(std::make_pair(Pos, Msg));
+
+    CommentStart = ExpectedEnd;
+  }
+}
+
+/// FindExpectedDiags - Lex the main source file to find all of the
+//   expected errors and warnings.
+static void FindExpectedDiags(Preprocessor &PP,
+                              DiagList &ExpectedErrors,
+                              DiagList &ExpectedWarnings,
+                              DiagList &ExpectedNotes) {
+  // Create a raw lexer to pull all the comments out of the main file.  We don't
+  // want to look in #include'd headers for expected-error strings.
+  SourceManager &SM = PP.getSourceManager();
+  FileID FID = SM.getMainFileID();
+  if (SM.getMainFileID().isInvalid())
+    return;
+
+  // Create a lexer to lex all the tokens of the main file in raw mode.
+  const llvm::MemoryBuffer *FromFile = SM.getBuffer(FID);
+  Lexer RawLex(FID, FromFile, SM, PP.getLangOptions());
+
+  // Return comments as tokens, this is how we find expected diagnostics.
+  RawLex.SetCommentRetentionState(true);
+
+  Token Tok;
+  Tok.setKind(tok::comment);
+  while (Tok.isNot(tok::eof)) {
+    RawLex.Lex(Tok);
+    if (!Tok.is(tok::comment)) continue;
+
+    std::string Comment = PP.getSpelling(Tok);
+    if (Comment.empty()) continue;
+
+    // Find all expected errors.
+    FindDiagnostics(&Comment[0], Comment.size(), ExpectedErrors, PP,
+                    Tok.getLocation(), "expected-error");
+
+    // Find all expected warnings.
+    FindDiagnostics(&Comment[0], Comment.size(), ExpectedWarnings, PP,
+                    Tok.getLocation(), "expected-warning");
+
+    // Find all expected notes.
+    FindDiagnostics(&Comment[0], Comment.size(), ExpectedNotes, PP,
+                    Tok.getLocation(), "expected-note");
+  };
+}
+
+/// PrintProblem - This takes a diagnostic map of the delta between expected and
+/// seen diagnostics. If there's anything in it, then something unexpected
+/// happened. Print the map out in a nice format and return "true". If the map
+/// is empty and we're not going to print things, then return "false".
+///
+static unsigned PrintProblem(Diagnostic &Diags, SourceManager *SourceMgr,
+                             const_diag_iterator diag_begin,
+                             const_diag_iterator diag_end,
+                             const char *Kind, bool Expected) {
+  if (diag_begin == diag_end) return 0;
+
+  llvm::SmallString<256> Fmt;
+  llvm::raw_svector_ostream OS(Fmt);
+  for (const_diag_iterator I = diag_begin, E = diag_end; I != E; ++I) {
+    if (I->first.isInvalid() || !SourceMgr)
+      OS << "\n  (frontend)";
+    else
+      OS << "\n  Line " << SourceMgr->getInstantiationLineNumber(I->first);
+    OS << ": " << I->second;
+  }
+
+  Diags.Report(diag::err_verify_inconsistent_diags)
+    << Kind << !Expected << OS.str();
+  return std::distance(diag_begin, diag_end);
+}
+
+/// CompareDiagLists - Compare two diagnostic lists and return the difference
+/// between them.
+///
+static unsigned CompareDiagLists(Diagnostic &Diags,
+                                 SourceManager &SourceMgr,
+                                 const_diag_iterator d1_begin,
+                                 const_diag_iterator d1_end,
+                                 const_diag_iterator d2_begin,
+                                 const_diag_iterator d2_end,
+                                 const char *Label) {
+  DiagList LeftOnly;
+  DiagList Left(d1_begin, d1_end);
+  DiagList Right(d2_begin, d2_end);
+
+  for (const_diag_iterator I = Left.begin(), E = Left.end(); I != E; ++I) {
+    unsigned LineNo1 = SourceMgr.getInstantiationLineNumber(I->first);
+    const std::string &Diag1 = I->second;
+
+    DiagList::iterator II, IE;
+    for (II = Right.begin(), IE = Right.end(); II != IE; ++II) {
+      unsigned LineNo2 = SourceMgr.getInstantiationLineNumber(II->first);
+      if (LineNo1 != LineNo2) continue;
+
+      const std::string &Diag2 = II->second;
+      if (Diag2.find(Diag1) != std::string::npos ||
+          Diag1.find(Diag2) != std::string::npos) {
+        break;
+      }
+    }
+    if (II == IE) {
+      // Not found.
+      LeftOnly.push_back(*I);
+    } else {
+      // Found. The same cannot be found twice.
+      Right.erase(II);
+    }
+  }
+  // Now all that's left in Right are those that were not matched.
+
+  return (PrintProblem(Diags, &SourceMgr,
+                      LeftOnly.begin(), LeftOnly.end(), Label, true) +
+          PrintProblem(Diags, &SourceMgr,
+                       Right.begin(), Right.end(), Label, false));
+}
+
+/// CheckResults - This compares the expected results to those that
+/// were actually reported. It emits any discrepencies. Return "true" if there
+/// were problems. Return "false" otherwise.
+///
+static unsigned CheckResults(Diagnostic &Diags, SourceManager &SourceMgr,
+                             const TextDiagnosticBuffer &Buffer,
+                             const DiagList &ExpectedErrors,
+                             const DiagList &ExpectedWarnings,
+                             const DiagList &ExpectedNotes) {
+  // We want to capture the delta between what was expected and what was
+  // seen.
+  //
+  //   Expected \ Seen - set expected but not seen
+  //   Seen \ Expected - set seen but not expected
+  unsigned NumProblems = 0;
+
+  // See if there are error mismatches.
+  NumProblems += CompareDiagLists(Diags, SourceMgr,
+                                  ExpectedErrors.begin(), ExpectedErrors.end(),
+                                  Buffer.err_begin(), Buffer.err_end(),
+                                  "error");
+
+  // See if there are warning mismatches.
+  NumProblems += CompareDiagLists(Diags, SourceMgr,
+                                  ExpectedWarnings.begin(),
+                                  ExpectedWarnings.end(),
+                                  Buffer.warn_begin(), Buffer.warn_end(),
+                                  "warning");
+
+  // See if there are note mismatches.
+  NumProblems += CompareDiagLists(Diags, SourceMgr,
+                                  ExpectedNotes.begin(),
+                                  ExpectedNotes.end(),
+                                  Buffer.note_begin(), Buffer.note_end(),
+                                  "note");
+
+  return NumProblems;
+}
+
+
+void VerifyDiagnosticsClient::CheckDiagnostics() {
+  DiagList ExpectedErrors, ExpectedWarnings, ExpectedNotes;
+
+  // Ensure any diagnostics go to the primary client.
+  DiagnosticClient *CurClient = Diags.getClient();
+  Diags.setClient(PrimaryClient.get());
+
+  // If we have a preprocessor, scan the source for expected diagnostic
+  // markers. If not then any diagnostics are unexpected.
+  if (CurrentPreprocessor) {
+    FindExpectedDiags(*CurrentPreprocessor, ExpectedErrors, ExpectedWarnings,
+                      ExpectedNotes);
+
+    // Check that the expected diagnostics occurred.
+    NumErrors += CheckResults(Diags, CurrentPreprocessor->getSourceManager(),
+                              *Buffer,
+                              ExpectedErrors, ExpectedWarnings, ExpectedNotes);
+  } else {
+    NumErrors += (PrintProblem(Diags, 0,
+                               Buffer->err_begin(), Buffer->err_end(),
+                               "error", false) +
+                  PrintProblem(Diags, 0,
+                               Buffer->warn_begin(), Buffer->warn_end(),
+                               "warn", false) +
+                  PrintProblem(Diags, 0,
+                               Buffer->note_begin(), Buffer->note_end(),
+                               "note", false));
+  }
+
+  Diags.setClient(CurClient);
+
+  // Reset the buffer, we have processed all the diagnostics in it.
+  Buffer.reset(new TextDiagnosticBuffer());
+}
diff --git a/lib/Frontend/Warnings.cpp b/lib/Frontend/Warnings.cpp
new file mode 100644
index 0000000..84c4f5d
--- /dev/null
+++ b/lib/Frontend/Warnings.cpp
@@ -0,0 +1,131 @@
+//===--- Warnings.cpp - C-Language Front-end ------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Command line warning options handler.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is responsible for handling all warning options. This includes
+// a number of -Wfoo options and their variants, which are driven by TableGen-
+// generated data, and the special cases -pedantic, -pedantic-errors, -w,
+// -Werror and -Wfatal-errors.
+//
+// Each warning option controls any number of actual warnings.
+// Given a warning option 'foo', the following are valid:
+//    -Wfoo, -Wno-foo, -Werror=foo, -Wfatal-errors=foo
+//
+#include "clang/Frontend/Utils.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Sema/SemaDiagnostic.h"
+#include "clang/Lex/LexDiagnostic.h"
+#include "clang/Frontend/DiagnosticOptions.h"
+#include "clang/Frontend/FrontendDiagnostic.h"
+#include <cstring>
+#include <utility>
+#include <algorithm>
+using namespace clang;
+
+void clang::ProcessWarningOptions(Diagnostic &Diags,
+                                  const DiagnosticOptions &Opts) {
+  Diags.setSuppressSystemWarnings(true);  // Default to -Wno-system-headers
+  Diags.setIgnoreAllWarnings(Opts.IgnoreWarnings);
+  
+  // Handle -ferror-limit
+  if (Opts.ErrorLimit)
+    Diags.setErrorLimit(Opts.ErrorLimit);
+  if (Opts.TemplateBacktraceLimit)
+    Diags.setTemplateBacktraceLimit(Opts.TemplateBacktraceLimit);
+
+  // If -pedantic or -pedantic-errors was specified, then we want to map all
+  // extension diagnostics onto WARNING or ERROR unless the user has futz'd
+  // around with them explicitly.
+  if (Opts.PedanticErrors)
+    Diags.setExtensionHandlingBehavior(Diagnostic::Ext_Error);
+  else if (Opts.Pedantic)
+    Diags.setExtensionHandlingBehavior(Diagnostic::Ext_Warn);
+  else
+    Diags.setExtensionHandlingBehavior(Diagnostic::Ext_Ignore);
+
+  for (unsigned i = 0, e = Opts.Warnings.size(); i != e; ++i) {
+    const std::string &Opt = Opts.Warnings[i];
+    const char *OptStart = &Opt[0];
+    const char *OptEnd = OptStart+Opt.size();
+    assert(*OptEnd == 0 && "Expect null termination for lower-bound search");
+
+    // Check to see if this warning starts with "no-", if so, this is a negative
+    // form of the option.
+    bool isPositive = true;
+    if (OptEnd-OptStart > 3 && memcmp(OptStart, "no-", 3) == 0) {
+      isPositive = false;
+      OptStart += 3;
+    }
+
+    // Figure out how this option affects the warning.  If -Wfoo, map the
+    // diagnostic to a warning, if -Wno-foo, map it to ignore.
+    diag::Mapping Mapping = isPositive ? diag::MAP_WARNING : diag::MAP_IGNORE;
+
+    // -Wsystem-headers is a special case, not driven by the option table.  It
+    // cannot be controlled with -Werror.
+    if (OptEnd-OptStart == 14 && memcmp(OptStart, "system-headers", 14) == 0) {
+      Diags.setSuppressSystemWarnings(!isPositive);
+      continue;
+    }
+
+    // -Werror/-Wno-error is a special case, not controlled by the option table.
+    // It also has the "specifier" form of -Werror=foo and -Werror-foo.
+    if (OptEnd-OptStart >= 5 && memcmp(OptStart, "error", 5) == 0) {
+      const char *Specifier = 0;
+      if (OptEnd-OptStart != 5) {  // Specifier must be present.
+        if ((OptStart[5] != '=' && OptStart[5] != '-') ||
+            OptEnd-OptStart == 6) {
+          Diags.Report(diag::warn_unknown_warning_specifier)
+            << "-Werror" << ("-W" + Opt);
+          continue;
+        }
+        Specifier = OptStart+6;
+      }
+
+      if (Specifier == 0) {
+        Diags.setWarningsAsErrors(isPositive);
+        continue;
+      }
+
+      // -Werror=foo maps foo to Error, -Wno-error=foo maps it to Warning.
+      Mapping = isPositive ? diag::MAP_ERROR : diag::MAP_WARNING_NO_WERROR;
+      OptStart = Specifier;
+    }
+
+    // -Wfatal-errors is yet another special case.
+    if (OptEnd-OptStart >= 12 && memcmp(OptStart, "fatal-errors", 12) == 0) {
+      const char* Specifier = 0;
+      if (OptEnd-OptStart != 12) {
+        if ((OptStart[12] != '=' && OptStart[12] != '-') ||
+            OptEnd-OptStart == 13) {
+          Diags.Report(diag::warn_unknown_warning_specifier)
+            << "-Wfatal-errors" << ("-W" + Opt);
+          continue;
+        }
+        Specifier = OptStart + 13;
+      }
+
+      if (Specifier == 0) {
+        Diags.setErrorsAsFatal(isPositive);
+        continue;
+      }
+
+      // -Wfatal-errors=foo maps foo to Fatal, -Wno-fatal-errors=foo
+      // maps it to Error.
+      Mapping = isPositive ? diag::MAP_FATAL : diag::MAP_ERROR_NO_WFATAL;
+      OptStart = Specifier;
+    }
+
+    if (Diags.setDiagnosticGroupMapping(OptStart, Mapping))
+      Diags.Report(diag::warn_unknown_warning_option) << ("-W" + Opt);
+  }
+}
diff --git a/lib/Headers/CMakeLists.txt b/lib/Headers/CMakeLists.txt
new file mode 100644
index 0000000..4416302
--- /dev/null
+++ b/lib/Headers/CMakeLists.txt
@@ -0,0 +1,39 @@
+set(files
+  altivec.h
+  emmintrin.h	
+  float.h		
+  iso646.h	
+  limits.h	
+  mm_malloc.h	
+  mmintrin.h	
+  pmmintrin.h	
+  stdarg.h	
+  stdbool.h	
+  stddef.h	
+  stdint.h	
+  tgmath.h
+  tmmintrin.h
+  xmmintrin.h)
+
+if (MSVC_IDE OR XCODE)
+  set(output_dir ${LLVM_BINARY_DIR}/bin/lib/clang/${CLANG_VERSION}/include)
+else ()
+  set(output_dir ${LLVM_BINARY_DIR}/lib/clang/${CLANG_VERSION}/include)
+endif ()
+
+
+foreach( f ${files} )
+  set( src ${CMAKE_CURRENT_SOURCE_DIR}/${f} )
+  set( dst ${output_dir}/${f} )
+  add_custom_command(OUTPUT ${dst}
+    DEPENDS ${src}
+    COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src} ${dst}
+    COMMENT "Copying clang's ${f}...")
+endforeach( f )
+
+add_custom_target(clang-headers ALL
+  DEPENDS ${files})
+
+install(FILES ${files}
+  PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
+  DESTINATION lib${LLVM_LIBDIR_SUFFIX}/clang/${CLANG_VERSION}/include)
diff --git a/lib/Headers/Makefile b/lib/Headers/Makefile
new file mode 100644
index 0000000..cb36e84
--- /dev/null
+++ b/lib/Headers/Makefile
@@ -0,0 +1,40 @@
+##===- clang/lib/Headers/Makefile --------------------------*- Makefile -*-===##
+#
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+# 
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../../../..
+include $(LEVEL)/Makefile.common
+
+CLANG_VERSION := $(shell cat $(PROJ_SRC_DIR)/../../VER)
+
+HeaderDir := $(PROJ_OBJ_ROOT)/$(BuildMode)/lib/clang/$(CLANG_VERSION)/include
+
+HEADERS := $(notdir $(wildcard $(PROJ_SRC_DIR)/*.h))
+
+OBJHEADERS := $(addprefix $(HeaderDir)/, $(HEADERS))
+
+
+$(OBJHEADERS): $(HeaderDir)/%.h: $(PROJ_SRC_DIR)/%.h $(HeaderDir)/.dir
+	$(Verb) cp $< $@
+	$(Echo) Copying $(notdir $<) to build dir
+
+# Hook into the standard Makefile rules.
+all-local:: $(OBJHEADERS)
+
+PROJ_headers := $(DESTDIR)$(PROJ_prefix)/lib/clang/$(CLANG_VERSION)/include
+
+INSTHEADERS := $(addprefix $(PROJ_headers)/, $(HEADERS))
+
+$(PROJ_headers):
+	$(Verb) $(MKDIR) $@
+
+$(INSTHEADERS): $(PROJ_headers)/%.h: $(HeaderDir)/%.h | $(PROJ_headers)
+	$(Verb) $(DataInstall) $< $(PROJ_headers)
+	$(Echo) Installing compiler include file: $(notdir $<)
+
+install-local:: $(INSTHEADERS)
diff --git a/lib/Headers/altivec.h b/lib/Headers/altivec.h
new file mode 100644
index 0000000..1cd0db8
--- /dev/null
+++ b/lib/Headers/altivec.h
@@ -0,0 +1,1483 @@
+/*===---- altivec.h - Standard header for type generic math ---------------===*\
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+\*===----------------------------------------------------------------------===*/
+
+#ifndef __ALTIVEC_H
+#define __ALTIVEC_H
+
+#ifndef __ALTIVEC__
+#error "AltiVec support not enabled"
+#endif
+
+/* constants for mapping CR6 bits to predicate result. */
+
+#define __CR6_EQ     0
+#define __CR6_EQ_REV 1
+#define __CR6_LT     2
+#define __CR6_LT_REV 3
+
+#define _ATTRS_o_ai __attribute__((__overloadable__, __always_inline__))
+
+/* vec_abs */
+
+#define __builtin_vec_abs vec_abs
+#define __builtin_altivec_abs_v16qi vec_abs
+#define __builtin_altivec_abs_v8hi  vec_abs
+#define __builtin_altivec_abs_v4si  vec_abs
+
+static vector signed char _ATTRS_o_ai
+vec_abs(vector signed char a)
+{
+  return __builtin_altivec_vmaxsb(a, -a);
+}
+
+static vector signed short _ATTRS_o_ai
+vec_abs(vector signed short a)
+{
+  return __builtin_altivec_vmaxsh(a, -a);
+}
+
+static vector signed int _ATTRS_o_ai
+vec_abs(vector signed int a)
+{
+  return __builtin_altivec_vmaxsw(a, -a);
+}
+
+static vector float _ATTRS_o_ai
+vec_abs(vector float a)
+{
+  vector unsigned int res = (vector unsigned int)a &
+                            (vector unsigned int)(0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF);
+  return (vector float)res;
+}
+
+/* vec_abss */
+
+#define __builtin_vec_abss vec_abss
+#define __builtin_altivec_abss_v16qi vec_abss
+#define __builtin_altivec_abss_v8hi  vec_abss
+#define __builtin_altivec_abss_v4si  vec_abss
+
+static vector signed char _ATTRS_o_ai
+vec_abss(vector signed char a)
+{
+  return __builtin_altivec_vmaxsb(a, __builtin_altivec_vsubsbs(
+    (vector signed char)(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), a));
+}
+
+static vector signed short _ATTRS_o_ai
+vec_abss(vector signed short a)
+{
+  return __builtin_altivec_vmaxsh(a, __builtin_altivec_vsubshs(
+    (vector signed short)(0, 0, 0, 0, 0, 0, 0, 0), a));
+}
+
+static vector signed int _ATTRS_o_ai
+vec_abss(vector signed int a)
+{
+  return __builtin_altivec_vmaxsw(a, __builtin_altivec_vsubsws(
+    (vector signed int)(0, 0, 0, 0), a));
+}
+
+/* vec_add */
+
+#define __builtin_altivec_vaddubm vec_add
+#define __builtin_altivec_vadduhm vec_add
+#define __builtin_altivec_vadduwm vec_add
+#define __builtin_altivec_vaddfp  vec_add
+#define __builtin_vec_vaddubm vec_add
+#define __builtin_vec_vadduhm vec_add
+#define __builtin_vec_vadduwm vec_add
+#define __builtin_vec_vaddfp  vec_add
+#define vec_vaddubm vec_add
+#define vec_vadduhm vec_add
+#define vec_vadduwm vec_add
+#define vec_vaddfp  vec_add
+
+static vector signed char _ATTRS_o_ai
+vec_add(vector signed char a, vector signed char b)
+{
+  return a + b;
+}
+
+static vector unsigned char _ATTRS_o_ai
+vec_add(vector unsigned char a, vector unsigned char b)
+{
+  return a + b;
+}
+
+static vector short _ATTRS_o_ai
+vec_add(vector short a, vector short b)
+{
+  return a + b;
+}
+
+static vector unsigned short _ATTRS_o_ai
+vec_add(vector unsigned short a, vector unsigned short b)
+{
+  return a + b;
+}
+
+static vector int _ATTRS_o_ai
+vec_add(vector int a, vector int b)
+{
+  return a + b;
+}
+
+static vector unsigned int _ATTRS_o_ai
+vec_add(vector unsigned int a, vector unsigned int b)
+{
+  return a + b;
+}
+
+static vector float _ATTRS_o_ai
+vec_add(vector float a, vector float b)
+{
+  return a + b;
+}
+
+/* vec_addc */
+
+#define __builtin_vec_addc __builtin_altivec_vaddcuw
+#define vec_vaddcuw        __builtin_altivec_vaddcuw
+#define vec_addc           __builtin_altivec_vaddcuw
+
+/* vec_adds */
+
+#define __builtin_vec_vaddsbs __builtin_altivec_vaddsbs
+#define __builtin_vec_vaddubs __builtin_altivec_vaddubs
+#define __builtin_vec_vaddshs __builtin_altivec_vaddshs
+#define __builtin_vec_vadduhs __builtin_altivec_vadduhs
+#define __builtin_vec_vaddsws __builtin_altivec_vaddsws
+#define __builtin_vec_vadduws __builtin_altivec_vadduws
+#define vec_vaddsbs __builtin_altivec_vaddsbs
+#define vec_vaddubs __builtin_altivec_vaddubs
+#define vec_vaddshs __builtin_altivec_vaddshs
+#define vec_vadduhs __builtin_altivec_vadduhs
+#define vec_vaddsws __builtin_altivec_vaddsws
+#define vec_vadduws __builtin_altivec_vadduws
+
+static vector signed char _ATTRS_o_ai
+vec_adds(vector signed char a, vector signed char b)
+{
+  return __builtin_altivec_vaddsbs(a, b);
+}
+
+static vector unsigned char _ATTRS_o_ai
+vec_adds(vector unsigned char a, vector unsigned char b)
+{
+  return __builtin_altivec_vaddubs(a, b);
+}
+
+static vector short _ATTRS_o_ai
+vec_adds(vector short a, vector short b)
+{
+  return __builtin_altivec_vaddshs(a, b);
+}
+
+static vector unsigned short _ATTRS_o_ai
+vec_adds(vector unsigned short a, vector unsigned short b)
+{
+  return __builtin_altivec_vadduhs(a, b);
+}
+
+static vector int _ATTRS_o_ai
+vec_adds(vector int a, vector int b)
+{
+  return __builtin_altivec_vaddsws(a, b);
+}
+
+static vector unsigned int _ATTRS_o_ai
+vec_adds(vector unsigned int a, vector unsigned int b)
+{
+  return __builtin_altivec_vadduws(a, b);
+}
+
+/* vec_sub */
+
+#define __builtin_altivec_vsububm vec_sub
+#define __builtin_altivec_vsubuhm vec_sub
+#define __builtin_altivec_vsubuwm vec_sub
+#define __builtin_altivec_vsubfp  vec_sub
+#define __builtin_vec_vsububm vec_sub
+#define __builtin_vec_vsubuhm vec_sub
+#define __builtin_vec_vsubuwm vec_sub
+#define __builtin_vec_vsubfp  vec_sub
+#define vec_vsububm vec_sub
+#define vec_vsubuhm vec_sub
+#define vec_vsubuwm vec_sub
+#define vec_vsubfp  vec_sub
+
+static vector signed char _ATTRS_o_ai
+vec_sub(vector signed char a, vector signed char b)
+{
+  return a - b;
+}
+
+static vector unsigned char _ATTRS_o_ai
+vec_sub(vector unsigned char a, vector unsigned char b)
+{
+  return a - b;
+}
+
+static vector short _ATTRS_o_ai
+vec_sub(vector short a, vector short b)
+{
+  return a - b;
+}
+
+static vector unsigned short _ATTRS_o_ai
+vec_sub(vector unsigned short a, vector unsigned short b)
+{
+  return a - b;
+}
+
+static vector int _ATTRS_o_ai
+vec_sub(vector int a, vector int b)
+{
+  return a - b;
+}
+
+static vector unsigned int _ATTRS_o_ai
+vec_sub(vector unsigned int a, vector unsigned int b)
+{
+  return a - b;
+}
+
+static vector float _ATTRS_o_ai
+vec_sub(vector float a, vector float b)
+{
+  return a - b;
+}
+
+/* vec_subs */
+
+#define __builtin_vec_vsubsbs __builtin_altivec_vsubsbs
+#define __builtin_vec_vsububs __builtin_altivec_vsububs
+#define __builtin_vec_vsubshs __builtin_altivec_vsubshs
+#define __builtin_vec_vsubuhs __builtin_altivec_vsubuhs
+#define __builtin_vec_vsubsws __builtin_altivec_vsubsws
+#define __builtin_vec_vsubuws __builtin_altivec_vsubuws
+#define vec_vsubsbs __builtin_altivec_vsubsbs
+#define vec_vsububs __builtin_altivec_vsububs
+#define vec_vsubshs __builtin_altivec_vsubshs
+#define vec_vsubuhs __builtin_altivec_vsubuhs
+#define vec_vsubsws __builtin_altivec_vsubsws
+#define vec_vsubuws __builtin_altivec_vsubuws
+
+static vector signed char _ATTRS_o_ai
+vec_subs(vector signed char a, vector signed char b)
+{
+  return __builtin_altivec_vsubsbs(a, b);
+}
+
+static vector unsigned char _ATTRS_o_ai
+vec_subs(vector unsigned char a, vector unsigned char b)
+{
+  return __builtin_altivec_vsububs(a, b);
+}
+
+static vector short _ATTRS_o_ai
+vec_subs(vector short a, vector short b)
+{
+  return __builtin_altivec_vsubshs(a, b);
+}
+
+static vector unsigned short _ATTRS_o_ai
+vec_subs(vector unsigned short a, vector unsigned short b)
+{
+  return __builtin_altivec_vsubuhs(a, b);
+}
+
+static vector int _ATTRS_o_ai
+vec_subs(vector int a, vector int b)
+{
+  return __builtin_altivec_vsubsws(a, b);
+}
+
+static vector unsigned int _ATTRS_o_ai
+vec_subs(vector unsigned int a, vector unsigned int b)
+{
+  return __builtin_altivec_vsubuws(a, b);
+}
+
+/* vec_avg */
+
+#define __builtin_vec_vavgsb __builtin_altivec_vavgsb
+#define __builtin_vec_vavgub __builtin_altivec_vavgub
+#define __builtin_vec_vavgsh __builtin_altivec_vavgsh
+#define __builtin_vec_vavguh __builtin_altivec_vavguh
+#define __builtin_vec_vavgsw __builtin_altivec_vavgsw
+#define __builtin_vec_vavguw __builtin_altivec_vavguw
+#define vec_vavgsb __builtin_altivec_vavgsb
+#define vec_vavgub __builtin_altivec_vavgub
+#define vec_vavgsh __builtin_altivec_vavgsh
+#define vec_vavguh __builtin_altivec_vavguh
+#define vec_vavgsw __builtin_altivec_vavgsw
+#define vec_vavguw __builtin_altivec_vavguw
+
+static vector signed char _ATTRS_o_ai
+vec_avg(vector signed char a, vector signed char b)
+{
+  return __builtin_altivec_vavgsb(a, b);
+}
+
+static vector unsigned char _ATTRS_o_ai
+vec_avg(vector unsigned char a, vector unsigned char b)
+{
+  return __builtin_altivec_vavgub(a, b);
+}
+
+static vector short _ATTRS_o_ai
+vec_avg(vector short a, vector short b)
+{
+  return __builtin_altivec_vavgsh(a, b);
+}
+
+static vector unsigned short _ATTRS_o_ai
+vec_avg(vector unsigned short a, vector unsigned short b)
+{
+  return __builtin_altivec_vavguh(a, b);
+}
+
+static vector int _ATTRS_o_ai
+vec_avg(vector int a, vector int b)
+{
+  return __builtin_altivec_vavgsw(a, b);
+}
+
+static vector unsigned int _ATTRS_o_ai
+vec_avg(vector unsigned int a, vector unsigned int b)
+{
+  return __builtin_altivec_vavguw(a, b);
+}
+
+/* vec_st */
+
+#define __builtin_vec_st vec_st
+#define vec_stvx         vec_st
+
+static void _ATTRS_o_ai
+vec_st(vector signed char a, int b, vector signed char *c)
+{
+  __builtin_altivec_stvx((vector int)a, b, (void *)c);
+}
+
+static void _ATTRS_o_ai
+vec_st(vector unsigned char a, int b, vector unsigned char *c)
+{
+  __builtin_altivec_stvx((vector int)a, b, (void *)c);
+}
+
+static void _ATTRS_o_ai
+vec_st(vector short a, int b, vector short *c)
+{
+  __builtin_altivec_stvx((vector int)a, b, (void *)c);
+}
+
+static void _ATTRS_o_ai
+vec_st(vector unsigned short a, int b, vector unsigned short *c)
+{
+  __builtin_altivec_stvx((vector int)a, b, (void *)c);
+}
+
+static void _ATTRS_o_ai
+vec_st(vector int a, int b, vector int *c)
+{
+  __builtin_altivec_stvx(a, b, (void *)c);
+}
+
+static void _ATTRS_o_ai
+vec_st(vector unsigned int a, int b, vector unsigned int *c)
+{
+  __builtin_altivec_stvx((vector int)a, b, (void *)c);
+}
+
+static void _ATTRS_o_ai
+vec_st(vector float a, int b, vector float *c)
+{
+  __builtin_altivec_stvx((vector int)a, b, (void *)c);
+}
+
+/* vec_stl */
+
+#define __builtin_vec_stl vec_stl
+#define vec_stvxl         vec_stl
+
+static void _ATTRS_o_ai
+vec_stl(vector signed char a, int b, vector signed char *c)
+{
+  __builtin_altivec_stvxl((vector int)a, b, (void *)c);
+}
+
+static void _ATTRS_o_ai
+vec_stl(vector unsigned char a, int b, vector unsigned char *c)
+{
+  __builtin_altivec_stvxl((vector int)a, b, (void *)c);
+}
+
+static void _ATTRS_o_ai
+vec_stl(vector short a, int b, vector short *c)
+{
+  __builtin_altivec_stvxl((vector int)a, b, (void *)c);
+}
+
+static void _ATTRS_o_ai
+vec_stl(vector unsigned short a, int b, vector unsigned short *c)
+{
+  __builtin_altivec_stvxl((vector int)a, b, (void *)c);
+}
+
+static void _ATTRS_o_ai
+vec_stl(vector int a, int b, vector int *c)
+{
+  __builtin_altivec_stvxl(a, b, (void *)c);
+}
+
+static void _ATTRS_o_ai
+vec_stl(vector unsigned int a, int b, vector unsigned int *c)
+{
+  __builtin_altivec_stvxl((vector int)a, b, (void *)c);
+}
+
+static void _ATTRS_o_ai
+vec_stl(vector float a, int b, vector float *c)
+{
+  __builtin_altivec_stvxl((vector int)a, b, (void *)c);
+}
+
+/* vec_ste */
+
+#define __builtin_vec_stvebx __builtin_altivec_stvebx
+#define __builtin_vec_stvehx __builtin_altivec_stvehx
+#define __builtin_vec_stvewx __builtin_altivec_stvewx
+#define vec_stvebx __builtin_altivec_stvebx
+#define vec_stvehx __builtin_altivec_stvehx
+#define vec_stvewx __builtin_altivec_stvewx
+
+static void _ATTRS_o_ai
+vec_ste(vector signed char a, int b, vector signed char *c)
+{
+  __builtin_altivec_stvebx((vector char)a, b, (void *)c);
+}
+
+static void _ATTRS_o_ai
+vec_ste(vector unsigned char a, int b, vector unsigned char *c)
+{
+  __builtin_altivec_stvebx((vector char)a, b, (void *)c);
+}
+
+static void _ATTRS_o_ai
+vec_ste(vector short a, int b, vector short *c)
+{
+  __builtin_altivec_stvehx(a, b, (void *)c);
+}
+
+static void _ATTRS_o_ai
+vec_ste(vector unsigned short a, int b, vector unsigned short *c)
+{
+  __builtin_altivec_stvehx((vector short)a, b, (void *)c);
+}
+
+static void _ATTRS_o_ai
+vec_ste(vector int a, int b, vector int *c)
+{
+  __builtin_altivec_stvewx(a, b, (void *)c);
+}
+
+static void _ATTRS_o_ai
+vec_ste(vector unsigned int a, int b, vector unsigned int *c)
+{
+  __builtin_altivec_stvewx((vector int)a, b, (void *)c);
+}
+
+static void _ATTRS_o_ai
+vec_ste(vector float a, int b, vector float *c)
+{
+  __builtin_altivec_stvewx((vector int)a, b, (void *)c);
+}
+
+/* vec_cmpb */
+
+#define vec_cmpb           __builtin_altivec_vcmpbfp
+#define vec_vcmpbfp        __builtin_altivec_vcmpbfp
+#define __builtin_vec_cmpb __builtin_altivec_vcmpbfp
+
+/* vec_cmpeq */
+
+#define __builtin_vec_cmpeq vec_cmpeq
+
+static vector /*bool*/ char _ATTRS_o_ai
+vec_cmpeq(vector signed char a, vector signed char b)
+{
+  return __builtin_altivec_vcmpequb((vector char)a, (vector char)b);
+}
+
+static vector /*bool*/ char _ATTRS_o_ai
+vec_cmpeq(vector unsigned char a, vector unsigned char b)
+{
+  return __builtin_altivec_vcmpequb((vector char)a, (vector char)b);
+}
+
+static vector /*bool*/ short _ATTRS_o_ai
+vec_cmpeq(vector short a, vector short b)
+{
+  return __builtin_altivec_vcmpequh(a, b);
+}
+
+static vector /*bool*/ short _ATTRS_o_ai
+vec_cmpeq(vector unsigned short a, vector unsigned short b)
+{
+  return __builtin_altivec_vcmpequh((vector short)a, (vector short)b);
+}
+
+static vector /*bool*/ int _ATTRS_o_ai
+vec_cmpeq(vector int a, vector int b)
+{
+  return __builtin_altivec_vcmpequw(a, b);
+}
+
+static vector /*bool*/ int _ATTRS_o_ai
+vec_cmpeq(vector unsigned int a, vector unsigned int b)
+{
+  return __builtin_altivec_vcmpequw((vector int)a, (vector int)b);
+}
+
+static vector /*bool*/ int _ATTRS_o_ai
+vec_cmpeq(vector float a, vector float b)
+{
+  return __builtin_altivec_vcmpeqfp(a, b);
+}
+
+/* vec_cmpge */
+
+#define vec_cmpge           __builtin_altivec_vcmpgefp
+#define vec_vcmpgefp        __builtin_altivec_vcmpgefp
+#define __builtin_vec_cmpge __builtin_altivec_vcmpgefp
+
+/* vec_cmpgt */
+
+#define vec_vcmpgtsb __builtin_altivec_vcmpgtsb
+#define vec_vcmpgtub __builtin_altivec_vcmpgtub
+#define vec_vcmpgtsh __builtin_altivec_vcmpgtsh
+#define vec_vcmpgtuh __builtin_altivec_vcmpgtuh
+#define vec_vcmpgtsw __builtin_altivec_vcmpgtsw
+#define vec_vcmpgtuw __builtin_altivec_vcmpgtuw
+#define vec_vcmpgtfp __builtin_altivec_vcmpgtfp
+#define __builtin_vec_vcmpgtsb __builtin_altivec_vcmpgtsb
+#define __builtin_vec_vcmpgtub __builtin_altivec_vcmpgtub
+#define __builtin_vec_vcmpgtsh __builtin_altivec_vcmpgtsh
+#define __builtin_vec_vcmpgtuh __builtin_altivec_vcmpgtuh
+#define __builtin_vec_vcmpgtsw __builtin_altivec_vcmpgtsw
+#define __builtin_vec_vcmpgtuw __builtin_altivec_vcmpgtuw
+#define __builtin_vec_vcmpgtfp __builtin_altivec_vcmpgtfp
+
+static vector /*bool*/ char _ATTRS_o_ai
+vec_cmpgt(vector signed char a, vector signed char b)
+{
+  return __builtin_altivec_vcmpgtsb(a, b);
+}
+
+static vector /*bool*/ char _ATTRS_o_ai
+vec_cmpgt(vector unsigned char a, vector unsigned char b)
+{
+  return __builtin_altivec_vcmpgtub(a, b);
+}
+
+static vector /*bool*/ short _ATTRS_o_ai
+vec_cmpgt(vector short a, vector short b)
+{
+  return __builtin_altivec_vcmpgtsh(a, b);
+}
+
+static vector /*bool*/ short _ATTRS_o_ai
+vec_cmpgt(vector unsigned short a, vector unsigned short b)
+{
+  return __builtin_altivec_vcmpgtuh(a, b);
+}
+
+static vector /*bool*/ int _ATTRS_o_ai
+vec_cmpgt(vector int a, vector int b)
+{
+  return __builtin_altivec_vcmpgtsw(a, b);
+}
+
+static vector /*bool*/ int _ATTRS_o_ai
+vec_cmpgt(vector unsigned int a, vector unsigned int b)
+{
+  return __builtin_altivec_vcmpgtuw(a, b);
+}
+
+static vector /*bool*/ int _ATTRS_o_ai
+vec_cmpgt(vector float a, vector float b)
+{
+  return __builtin_altivec_vcmpgtfp(a, b);
+}
+
+/* vec_cmple */
+
+#define __builtin_vec_cmple vec_cmple
+
+static vector /*bool*/ int __attribute__((__always_inline__))
+vec_cmple(vector float a, vector float b)
+{
+  return __builtin_altivec_vcmpgefp(b, a);
+}
+
+/* vec_cmplt */
+
+#define __builtin_vec_cmplt vec_cmplt
+
+static vector /*bool*/ char _ATTRS_o_ai
+vec_cmplt(vector signed char a, vector signed char b)
+{
+  return __builtin_altivec_vcmpgtsb(b, a);
+}
+
+static vector /*bool*/ char _ATTRS_o_ai
+vec_cmplt(vector unsigned char a, vector unsigned char b)
+{
+  return __builtin_altivec_vcmpgtub(b, a);
+}
+
+static vector /*bool*/ short _ATTRS_o_ai
+vec_cmplt(vector short a, vector short b)
+{
+  return __builtin_altivec_vcmpgtsh(b, a);
+}
+
+static vector /*bool*/ short _ATTRS_o_ai
+vec_cmplt(vector unsigned short a, vector unsigned short b)
+{
+  return __builtin_altivec_vcmpgtuh(b, a);
+}
+
+static vector /*bool*/ int _ATTRS_o_ai
+vec_cmplt(vector int a, vector int b)
+{
+  return __builtin_altivec_vcmpgtsw(b, a);
+}
+
+static vector /*bool*/ int _ATTRS_o_ai
+vec_cmplt(vector unsigned int a, vector unsigned int b)
+{
+  return __builtin_altivec_vcmpgtuw(b, a);
+}
+
+static vector /*bool*/ int _ATTRS_o_ai
+vec_cmplt(vector float a, vector float b)
+{
+  return __builtin_altivec_vcmpgtfp(b, a);
+}
+
+/* vec_max */
+
+#define __builtin_vec_vmaxsb __builtin_altivec_vmaxsb
+#define __builtin_vec_vmaxub __builtin_altivec_vmaxub
+#define __builtin_vec_vmaxsh __builtin_altivec_vmaxsh
+#define __builtin_vec_vmaxuh __builtin_altivec_vmaxuh
+#define __builtin_vec_vmaxsw __builtin_altivec_vmaxsw
+#define __builtin_vec_vmaxuw __builtin_altivec_vmaxuw
+#define __builtin_vec_vmaxfp __builtin_altivec_vmaxfp
+#define vec_vmaxsb __builtin_altivec_vmaxsb
+#define vec_vmaxub __builtin_altivec_vmaxub
+#define vec_vmaxsh __builtin_altivec_vmaxsh
+#define vec_vmaxuh __builtin_altivec_vmaxuh
+#define vec_vmaxsw __builtin_altivec_vmaxsw
+#define vec_vmaxuw __builtin_altivec_vmaxuw
+#define vec_vmaxfp __builtin_altivec_vmaxfp
+#define __builtin_vec_max vec_max
+
+static vector signed char _ATTRS_o_ai
+vec_max(vector signed  char a, vector signed char b)
+{
+  return __builtin_altivec_vmaxsb(a, b);
+}
+
+static vector unsigned char _ATTRS_o_ai
+vec_max(vector unsigned  char a, vector unsigned char b)
+{
+  return __builtin_altivec_vmaxub(a, b);
+}
+
+static vector short _ATTRS_o_ai
+vec_max(vector short a, vector short b)
+{
+  return __builtin_altivec_vmaxsh(a, b);
+}
+
+static vector unsigned short _ATTRS_o_ai
+vec_max(vector unsigned short a, vector unsigned short b)
+{
+  return __builtin_altivec_vmaxuh(a, b);
+}
+
+static vector int _ATTRS_o_ai
+vec_max(vector int a, vector int b)
+{
+  return __builtin_altivec_vmaxsw(a, b);
+}
+
+static vector unsigned int _ATTRS_o_ai
+vec_max(vector unsigned int a, vector unsigned int b)
+{
+  return __builtin_altivec_vmaxuw(a, b);
+}
+
+static vector float _ATTRS_o_ai
+vec_max(vector float a, vector float b)
+{
+  return __builtin_altivec_vmaxfp(a, b);
+}
+
+/* vec_mfvscr */
+
+#define __builtin_vec_mfvscr __builtin_altivec_mfvscr
+#define vec_mfvscr           __builtin_altivec_mfvscr
+
+/* vec_min */
+
+#define __builtin_vec_vminsb __builtin_altivec_vminsb
+#define __builtin_vec_vminub __builtin_altivec_vminub
+#define __builtin_vec_vminsh __builtin_altivec_vminsh
+#define __builtin_vec_vminuh __builtin_altivec_vminuh
+#define __builtin_vec_vminsw __builtin_altivec_vminsw
+#define __builtin_vec_vminuw __builtin_altivec_vminuw
+#define __builtin_vec_vminfp __builtin_altivec_vminfp
+#define vec_vminsb __builtin_altivec_vminsb
+#define vec_vminub __builtin_altivec_vminub
+#define vec_vminsh __builtin_altivec_vminsh
+#define vec_vminuh __builtin_altivec_vminuh
+#define vec_vminsw __builtin_altivec_vminsw
+#define vec_vminuw __builtin_altivec_vminuw
+#define vec_vminfp __builtin_altivec_vminfp
+#define __builtin_vec_min vec_min
+
+static vector signed char _ATTRS_o_ai
+vec_min(vector signed  char a, vector signed char b)
+{
+  return __builtin_altivec_vminsb(a, b);
+}
+
+static vector unsigned char _ATTRS_o_ai
+vec_min(vector unsigned  char a, vector unsigned char b)
+{
+  return __builtin_altivec_vminub(a, b);
+}
+
+static vector short _ATTRS_o_ai
+vec_min(vector short a, vector short b)
+{
+  return __builtin_altivec_vminsh(a, b);
+}
+
+static vector unsigned short _ATTRS_o_ai
+vec_min(vector unsigned short a, vector unsigned short b)
+{
+  return __builtin_altivec_vminuh(a, b);
+}
+
+static vector int _ATTRS_o_ai
+vec_min(vector int a, vector int b)
+{
+  return __builtin_altivec_vminsw(a, b);
+}
+
+static vector unsigned int _ATTRS_o_ai
+vec_min(vector unsigned int a, vector unsigned int b)
+{
+  return __builtin_altivec_vminuw(a, b);
+}
+
+static vector float _ATTRS_o_ai
+vec_min(vector float a, vector float b)
+{
+  return __builtin_altivec_vminfp(a, b);
+}
+
+/* vec_mtvscr */
+
+#define __builtin_vec_mtvscr __builtin_altivec_mtvscr
+#define vec_mtvscr           __builtin_altivec_mtvscr
+
+/* ------------------------------ predicates ------------------------------------ */
+
+static int __attribute__((__always_inline__))
+__builtin_vec_vcmpeq_p(char CR6_param, vector float a, vector float b)
+{
+  return __builtin_altivec_vcmpeqfp_p(CR6_param, a, b);
+}
+
+static int __attribute__((__always_inline__))
+__builtin_vec_vcmpge_p(char CR6_param, vector float a, vector float b)
+{
+  return __builtin_altivec_vcmpgefp_p(CR6_param, a, b);
+}
+
+static int __attribute__((__always_inline__))
+__builtin_vec_vcmpgt_p(char CR6_param, vector float a, vector float b)
+{
+  return __builtin_altivec_vcmpgtfp_p(CR6_param, a, b);
+}
+
+/* vec_all_eq */
+
+static int _ATTRS_o_ai
+vec_all_eq(vector signed char a, vector signed char b)
+{
+  return __builtin_altivec_vcmpequb_p(__CR6_LT, (vector char)a, (vector char)b);
+}
+
+static int _ATTRS_o_ai
+vec_all_eq(vector unsigned char a, vector unsigned char b)
+{
+  return __builtin_altivec_vcmpequb_p(__CR6_LT, (vector char)a, (vector char)b);
+}
+
+static int _ATTRS_o_ai
+vec_all_eq(vector short a, vector short b)
+{
+  return __builtin_altivec_vcmpequh_p(__CR6_LT, a, b);
+}
+
+static int _ATTRS_o_ai
+vec_all_eq(vector unsigned short a, vector unsigned short b)
+{
+  return __builtin_altivec_vcmpequh_p(__CR6_LT, (vector short)a, (vector short)b);
+}
+
+static int _ATTRS_o_ai
+vec_all_eq(vector int a, vector int b)
+{
+  return __builtin_altivec_vcmpequw_p(__CR6_LT, a, b);
+}
+
+static int _ATTRS_o_ai
+vec_all_eq(vector unsigned int a, vector unsigned int b)
+{
+  return __builtin_altivec_vcmpequw_p(__CR6_LT, (vector int)a, (vector int)b);
+}
+
+static int _ATTRS_o_ai
+vec_all_eq(vector float a, vector float b)
+{
+  return __builtin_altivec_vcmpeqfp_p(__CR6_LT, a, b);
+}
+
+/* vec_all_ge */
+
+static int _ATTRS_o_ai
+vec_all_ge(vector signed char a, vector signed char b)
+{
+  return __builtin_altivec_vcmpgtsb_p(__CR6_LT, b, a);
+}
+
+static int _ATTRS_o_ai
+vec_all_ge(vector unsigned char a, vector unsigned char b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_LT, b, a);
+}
+
+static int _ATTRS_o_ai
+vec_all_ge(vector short a, vector short b)
+{
+  return __builtin_altivec_vcmpgtsh_p(__CR6_LT, b, a);
+}
+
+static int _ATTRS_o_ai
+vec_all_ge(vector unsigned short a, vector unsigned short b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_LT, b, a);
+}
+
+static int _ATTRS_o_ai
+vec_all_ge(vector int a, vector int b)
+{
+  return __builtin_altivec_vcmpgtsw_p(__CR6_LT, b, a);
+}
+
+static int _ATTRS_o_ai
+vec_all_ge(vector unsigned int a, vector unsigned int b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_LT, b, a);
+}
+
+static int _ATTRS_o_ai
+vec_all_ge(vector float a, vector float b)
+{
+  return __builtin_altivec_vcmpgtfp_p(__CR6_LT, b, a);
+}
+
+/* vec_all_gt */
+
+static int _ATTRS_o_ai
+vec_all_gt(vector signed char a, vector signed char b)
+{
+  return __builtin_altivec_vcmpgtsb_p(__CR6_LT, a, b);
+}
+
+static int _ATTRS_o_ai
+vec_all_gt(vector unsigned char a, vector unsigned char b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_LT, a, b);
+}
+
+static int _ATTRS_o_ai
+vec_all_gt(vector short a, vector short b)
+{
+  return __builtin_altivec_vcmpgtsh_p(__CR6_LT, a, b);
+}
+
+static int _ATTRS_o_ai
+vec_all_gt(vector unsigned short a, vector unsigned short b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_LT, a, b);
+}
+
+static int _ATTRS_o_ai
+vec_all_gt(vector int a, vector int b)
+{
+  return __builtin_altivec_vcmpgtsw_p(__CR6_LT, a, b);
+}
+
+static int _ATTRS_o_ai
+vec_all_gt(vector unsigned int a, vector unsigned int b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_LT, a, b);
+}
+
+static int _ATTRS_o_ai
+vec_all_gt(vector float a, vector float b)
+{
+  return __builtin_altivec_vcmpgtfp_p(__CR6_LT, a, b);
+}
+
+/* vec_all_in */
+
+static int __attribute__((__always_inline__))
+vec_all_in(vector float a, vector float b)
+{
+  return __builtin_altivec_vcmpbfp_p(__CR6_EQ, a, b);
+}
+
+/* vec_all_le */
+
+static int _ATTRS_o_ai
+vec_all_le(vector signed char a, vector signed char b)
+{
+  return __builtin_altivec_vcmpgtsb_p(__CR6_EQ, a, b);
+}
+
+static int _ATTRS_o_ai
+vec_all_le(vector unsigned char a, vector unsigned char b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_EQ, a, b);
+}
+
+static int _ATTRS_o_ai
+vec_all_le(vector short a, vector short b)
+{
+  return __builtin_altivec_vcmpgtsh_p(__CR6_EQ, a, b);
+}
+
+static int _ATTRS_o_ai
+vec_all_le(vector unsigned short a, vector unsigned short b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_EQ, a, b);
+}
+
+static int _ATTRS_o_ai
+vec_all_le(vector int a, vector int b)
+{
+  return __builtin_altivec_vcmpgtsw_p(__CR6_EQ, a, b);
+}
+
+static int _ATTRS_o_ai
+vec_all_le(vector unsigned int a, vector unsigned int b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_EQ, a, b);
+}
+
+static int _ATTRS_o_ai
+vec_all_le(vector float a, vector float b)
+{
+  return __builtin_altivec_vcmpgtfp_p(__CR6_EQ, a, b);
+}
+
+/* vec_all_lt */
+
+static int _ATTRS_o_ai
+vec_all_lt(vector signed char a, vector signed char b)
+{
+  return __builtin_altivec_vcmpgtsb_p(__CR6_LT, b, a);
+}
+
+static int _ATTRS_o_ai
+vec_all_lt(vector unsigned char a, vector unsigned char b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_LT, b, a);
+}
+
+static int _ATTRS_o_ai
+vec_all_lt(vector short a, vector short b)
+{
+  return __builtin_altivec_vcmpgtsh_p(__CR6_LT, b, a);
+}
+
+static int _ATTRS_o_ai
+vec_all_lt(vector unsigned short a, vector unsigned short b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_LT, b, a);
+}
+
+static int _ATTRS_o_ai
+vec_all_lt(vector int a, vector int b)
+{
+  return __builtin_altivec_vcmpgtsw_p(__CR6_LT, b, a);
+}
+
+static int _ATTRS_o_ai
+vec_all_lt(vector unsigned int a, vector unsigned int b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_LT, b, a);
+}
+
+static int _ATTRS_o_ai
+vec_all_lt(vector float a, vector float b)
+{
+  return __builtin_altivec_vcmpgtfp_p(__CR6_LT, b, a);
+}
+
+/* vec_all_nan */
+
+static int __attribute__((__always_inline__))
+vec_all_nan(vector float a)
+{
+  return __builtin_altivec_vcmpeqfp_p(__CR6_EQ, a, a);
+}
+
+/* vec_all_ne */
+
+static int _ATTRS_o_ai
+vec_all_ne(vector signed char a, vector signed char b)
+{
+  return __builtin_altivec_vcmpequb_p(__CR6_EQ, (vector char)a, (vector char)b);
+}
+
+static int _ATTRS_o_ai
+vec_all_ne(vector unsigned char a, vector unsigned char b)
+{
+  return __builtin_altivec_vcmpequb_p(__CR6_EQ, (vector char)a, (vector char)b);
+}
+
+static int _ATTRS_o_ai
+vec_all_ne(vector short a, vector short b)
+{
+  return __builtin_altivec_vcmpequh_p(__CR6_EQ, a, b);
+}
+
+static int _ATTRS_o_ai
+vec_all_ne(vector unsigned short a, vector unsigned short b)
+{
+  return __builtin_altivec_vcmpequh_p(__CR6_EQ, (vector short)a, (vector short)b);
+}
+
+static int _ATTRS_o_ai
+vec_all_ne(vector int a, vector int b)
+{
+  return __builtin_altivec_vcmpequw_p(__CR6_EQ, a, b);
+}
+
+static int _ATTRS_o_ai
+vec_all_ne(vector unsigned int a, vector unsigned int b)
+{
+  return __builtin_altivec_vcmpequw_p(__CR6_EQ, (vector int)a, (vector int)b);
+}
+
+static int _ATTRS_o_ai
+vec_all_ne(vector float a, vector float b)
+{
+  return __builtin_altivec_vcmpeqfp_p(__CR6_EQ, a, b);
+}
+
+/* vec_all_nge */
+
+static int __attribute__((__always_inline__))
+vec_all_nge(vector float a, vector float b)
+{
+  return __builtin_altivec_vcmpgefp_p(__CR6_EQ, a, b);
+}
+
+/* vec_all_ngt */
+
+static int __attribute__((__always_inline__))
+vec_all_ngt(vector float a, vector float b)
+{
+  return __builtin_altivec_vcmpgtfp_p(__CR6_EQ, a, b);
+}
+
+/* vec_all_nle */
+
+static int __attribute__((__always_inline__))
+vec_all_nle(vector float a, vector float b)
+{
+  return __builtin_altivec_vcmpgefp_p(__CR6_EQ, b, a);
+}
+
+/* vec_all_nlt */
+
+static int __attribute__((__always_inline__))
+vec_all_nlt(vector float a, vector float b)
+{
+  return __builtin_altivec_vcmpgtfp_p(__CR6_EQ, b, a);
+}
+
+/* vec_all_numeric */
+
+static int __attribute__((__always_inline__))
+vec_all_numeric(vector float a)
+{
+  return __builtin_altivec_vcmpeqfp_p(__CR6_LT, a, a);
+}
+
+/* vec_any_eq */
+
+static int _ATTRS_o_ai
+vec_any_eq(vector signed char a, vector signed char b)
+{
+  return __builtin_altivec_vcmpequb_p(__CR6_EQ_REV, (vector char)a, (vector char)b);
+}
+
+static int _ATTRS_o_ai
+vec_any_eq(vector unsigned char a, vector unsigned char b)
+{
+  return __builtin_altivec_vcmpequb_p(__CR6_EQ_REV, (vector char)a, (vector char)b);
+}
+
+static int _ATTRS_o_ai
+vec_any_eq(vector short a, vector short b)
+{
+  return __builtin_altivec_vcmpequh_p(__CR6_EQ_REV, a, b);
+}
+
+static int _ATTRS_o_ai
+vec_any_eq(vector unsigned short a, vector unsigned short b)
+{
+  return __builtin_altivec_vcmpequh_p(__CR6_EQ_REV, (vector short)a, (vector short)b);
+}
+
+static int _ATTRS_o_ai
+vec_any_eq(vector int a, vector int b)
+{
+  return __builtin_altivec_vcmpequw_p(__CR6_EQ_REV, a, b);
+}
+
+static int _ATTRS_o_ai
+vec_any_eq(vector unsigned int a, vector unsigned int b)
+{
+  return __builtin_altivec_vcmpequw_p(__CR6_EQ_REV, (vector int)a, (vector int)b);
+}
+
+static int _ATTRS_o_ai
+vec_any_eq(vector float a, vector float b)
+{
+  return __builtin_altivec_vcmpeqfp_p(__CR6_EQ_REV, a, b);
+}
+
+/* vec_any_ge */
+
+static int _ATTRS_o_ai
+vec_any_ge(vector signed char a, vector signed char b)
+{
+  return __builtin_altivec_vcmpgtsb_p(__CR6_LT_REV, b, a);
+}
+
+static int _ATTRS_o_ai
+vec_any_ge(vector unsigned char a, vector unsigned char b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_LT_REV, b, a);
+}
+
+static int _ATTRS_o_ai
+vec_any_ge(vector short a, vector short b)
+{
+  return __builtin_altivec_vcmpgtsh_p(__CR6_LT_REV, b, a);
+}
+
+static int _ATTRS_o_ai
+vec_any_ge(vector unsigned short a, vector unsigned short b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_LT_REV, b, a);
+}
+
+static int _ATTRS_o_ai
+vec_any_ge(vector int a, vector int b)
+{
+  return __builtin_altivec_vcmpgtsw_p(__CR6_LT_REV, b, a);
+}
+
+static int _ATTRS_o_ai
+vec_any_ge(vector unsigned int a, vector unsigned int b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_LT_REV, b, a);
+}
+
+static int _ATTRS_o_ai
+vec_any_ge(vector float a, vector float b)
+{
+  return __builtin_altivec_vcmpgtfp_p(__CR6_LT_REV, b, a);
+}
+
+/* vec_any_gt */
+
+static int _ATTRS_o_ai
+vec_any_gt(vector signed char a, vector signed char b)
+{
+  return __builtin_altivec_vcmpgtsb_p(__CR6_EQ_REV, a, b);
+}
+
+static int _ATTRS_o_ai
+vec_any_gt(vector unsigned char a, vector unsigned char b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_EQ_REV, a, b);
+}
+
+static int _ATTRS_o_ai
+vec_any_gt(vector short a, vector short b)
+{
+  return __builtin_altivec_vcmpgtsh_p(__CR6_EQ_REV, a, b);
+}
+
+static int _ATTRS_o_ai
+vec_any_gt(vector unsigned short a, vector unsigned short b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_EQ_REV, a, b);
+}
+
+static int _ATTRS_o_ai
+vec_any_gt(vector int a, vector int b)
+{
+  return __builtin_altivec_vcmpgtsw_p(__CR6_EQ_REV, a, b);
+}
+
+static int _ATTRS_o_ai
+vec_any_gt(vector unsigned int a, vector unsigned int b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_EQ_REV, a, b);
+}
+
+static int _ATTRS_o_ai
+vec_any_gt(vector float a, vector float b)
+{
+  return __builtin_altivec_vcmpgtfp_p(__CR6_EQ_REV, a, b);
+}
+
+/* vec_any_le */
+
+static int _ATTRS_o_ai
+vec_any_le(vector signed char a, vector signed char b)
+{
+  return __builtin_altivec_vcmpgtsb_p(__CR6_LT_REV, a, b);
+}
+
+static int _ATTRS_o_ai
+vec_any_le(vector unsigned char a, vector unsigned char b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_LT_REV, a, b);
+}
+
+static int _ATTRS_o_ai
+vec_any_le(vector short a, vector short b)
+{
+  return __builtin_altivec_vcmpgtsh_p(__CR6_LT_REV, a, b);
+}
+
+static int _ATTRS_o_ai
+vec_any_le(vector unsigned short a, vector unsigned short b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_LT_REV, a, b);
+}
+
+static int _ATTRS_o_ai
+vec_any_le(vector int a, vector int b)
+{
+  return __builtin_altivec_vcmpgtsw_p(__CR6_LT_REV, a, b);
+}
+
+static int _ATTRS_o_ai
+vec_any_le(vector unsigned int a, vector unsigned int b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_LT_REV, a, b);
+}
+
+static int _ATTRS_o_ai
+vec_any_le(vector float a, vector float b)
+{
+  return __builtin_altivec_vcmpgtfp_p(__CR6_LT_REV, a, b);
+}
+
+/* vec_any_lt */
+
+static int _ATTRS_o_ai
+vec_any_lt(vector signed char a, vector signed char b)
+{
+  return __builtin_altivec_vcmpgtsb_p(__CR6_EQ_REV, b, a);
+}
+
+static int _ATTRS_o_ai
+vec_any_lt(vector unsigned char a, vector unsigned char b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_EQ_REV, b, a);
+}
+
+static int _ATTRS_o_ai
+vec_any_lt(vector short a, vector short b)
+{
+  return __builtin_altivec_vcmpgtsh_p(__CR6_EQ_REV, b, a);
+}
+
+static int _ATTRS_o_ai
+vec_any_lt(vector unsigned short a, vector unsigned short b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_EQ_REV, b, a);
+}
+
+static int _ATTRS_o_ai
+vec_any_lt(vector int a, vector int b)
+{
+  return __builtin_altivec_vcmpgtsw_p(__CR6_EQ_REV, b, a);
+}
+
+static int _ATTRS_o_ai
+vec_any_lt(vector unsigned int a, vector unsigned int b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_EQ_REV, b, a);
+}
+
+static int _ATTRS_o_ai
+vec_any_lt(vector float a, vector float b)
+{
+  return __builtin_altivec_vcmpgtfp_p(__CR6_EQ_REV, b, a);
+}
+
+/* vec_any_nan */
+
+static int __attribute__((__always_inline__))
+vec_any_nan(vector float a)
+{
+  return __builtin_altivec_vcmpeqfp_p(__CR6_LT_REV, a, a);
+}
+
+/* vec_any_ne */
+
+static int _ATTRS_o_ai
+vec_any_ne(vector signed char a, vector signed char b)
+{
+  return __builtin_altivec_vcmpequb_p(__CR6_LT_REV, (vector char)a, (vector char)b);
+}
+
+static int _ATTRS_o_ai
+vec_any_ne(vector unsigned char a, vector unsigned char b)
+{
+  return __builtin_altivec_vcmpequb_p(__CR6_LT_REV, (vector char)a, (vector char)b);
+}
+
+static int _ATTRS_o_ai
+vec_any_ne(vector short a, vector short b)
+{
+  return __builtin_altivec_vcmpequh_p(__CR6_LT_REV, a, b);
+}
+
+static int _ATTRS_o_ai
+vec_any_ne(vector unsigned short a, vector unsigned short b)
+{
+  return __builtin_altivec_vcmpequh_p(__CR6_LT_REV, (vector short)a, (vector short)b);
+}
+
+static int _ATTRS_o_ai
+vec_any_ne(vector int a, vector int b)
+{
+  return __builtin_altivec_vcmpequw_p(__CR6_LT_REV, a, b);
+}
+
+static int _ATTRS_o_ai
+vec_any_ne(vector unsigned int a, vector unsigned int b)
+{
+  return __builtin_altivec_vcmpequw_p(__CR6_LT_REV, (vector int)a, (vector int)b);
+}
+
+static int _ATTRS_o_ai
+vec_any_ne(vector float a, vector float b)
+{
+  return __builtin_altivec_vcmpeqfp_p(__CR6_LT_REV, a, b);
+}
+
+/* vec_any_nge */
+
+static int __attribute__((__always_inline__))
+vec_any_nge(vector float a, vector float b)
+{
+  return __builtin_altivec_vcmpgefp_p(__CR6_LT_REV, a, b);
+}
+
+/* vec_any_ngt */
+
+static int __attribute__((__always_inline__))
+vec_any_ngt(vector float a, vector float b)
+{
+  return __builtin_altivec_vcmpgtfp_p(__CR6_LT_REV, a, b);
+}
+
+/* vec_any_nle */
+
+static int __attribute__((__always_inline__))
+vec_any_nle(vector float a, vector float b)
+{
+  return __builtin_altivec_vcmpgefp_p(__CR6_LT_REV, b, a);
+}
+
+/* vec_any_nlt */
+
+static int __attribute__((__always_inline__))
+vec_any_nlt(vector float a, vector float b)
+{
+  return __builtin_altivec_vcmpgtfp_p(__CR6_LT_REV, b, a);
+}
+
+/* vec_any_numeric */
+
+static int __attribute__((__always_inline__))
+vec_any_numeric(vector float a)
+{
+  return __builtin_altivec_vcmpeqfp_p(__CR6_EQ_REV, a, a);
+}
+
+/* vec_any_out */
+
+static int __attribute__((__always_inline__))
+vec_any_out(vector float a, vector float b)
+{
+  return __builtin_altivec_vcmpbfp_p(__CR6_EQ_REV, a, b);
+}
+
+#undef _ATTRS_o_ai
+
+#endif /* __ALTIVEC_H */
diff --git a/lib/Headers/emmintrin.h b/lib/Headers/emmintrin.h
new file mode 100644
index 0000000..6b9dd2a
--- /dev/null
+++ b/lib/Headers/emmintrin.h
@@ -0,0 +1,1362 @@
+/*===---- xmmintrin.h - SSE intrinsics -------------------------------------===
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+ 
+#ifndef __EMMINTRIN_H
+#define __EMMINTRIN_H
+
+#ifndef __SSE2__
+#error "SSE2 instruction set not enabled"
+#else
+
+#include <xmmintrin.h>
+
+typedef double __m128d __attribute__((__vector_size__(16)));
+typedef long long __m128i __attribute__((__vector_size__(16)));
+
+typedef short __v8hi __attribute__((__vector_size__(16)));
+typedef char __v16qi __attribute__((__vector_size__(16)));
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_add_sd(__m128d a, __m128d b)
+{
+  a[0] += b[0];
+  return a;
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_add_pd(__m128d a, __m128d b)
+{
+  return a + b;
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_sub_sd(__m128d a, __m128d b)
+{
+  a[0] -= b[0];
+  return a;
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_sub_pd(__m128d a, __m128d b)
+{
+  return a - b;
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_mul_sd(__m128d a, __m128d b)
+{
+  a[0] *= b[0];
+  return a;
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_mul_pd(__m128d a, __m128d b)
+{
+  return a * b;
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_div_sd(__m128d a, __m128d b)
+{
+  a[0] /= b[0];
+  return a;
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_div_pd(__m128d a, __m128d b)
+{
+  return a / b;
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_sqrt_sd(__m128d a, __m128d b)
+{
+  __m128d c = __builtin_ia32_sqrtsd(b);
+  return (__m128d) { c[0], a[1] };
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_sqrt_pd(__m128d a)
+{
+  return __builtin_ia32_sqrtpd(a);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_min_sd(__m128d a, __m128d b)
+{
+  return __builtin_ia32_minsd(a, b);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_min_pd(__m128d a, __m128d b)
+{
+  return __builtin_ia32_minpd(a, b);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_max_sd(__m128d a, __m128d b)
+{
+  return __builtin_ia32_maxsd(a, b);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_max_pd(__m128d a, __m128d b)
+{
+  return __builtin_ia32_maxpd(a, b);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_and_pd(__m128d a, __m128d b)
+{
+  return (__m128d)((__v4si)a & (__v4si)b);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_andnot_pd(__m128d a, __m128d b)
+{
+  return (__m128d)(~(__v4si)a & (__v4si)b);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_or_pd(__m128d a, __m128d b)
+{
+  return (__m128d)((__v4si)a | (__v4si)b);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_xor_pd(__m128d a, __m128d b)
+{
+  return (__m128d)((__v4si)a ^ (__v4si)b);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_cmpeq_pd(__m128d a, __m128d b)
+{
+  return (__m128d)__builtin_ia32_cmppd(a, b, 0);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_cmplt_pd(__m128d a, __m128d b)
+{
+  return (__m128d)__builtin_ia32_cmppd(a, b, 1);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_cmple_pd(__m128d a, __m128d b)
+{
+  return (__m128d)__builtin_ia32_cmppd(a, b, 2);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_cmpgt_pd(__m128d a, __m128d b)
+{
+  return (__m128d)__builtin_ia32_cmppd(b, a, 1);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_cmpge_pd(__m128d a, __m128d b)
+{
+  return (__m128d)__builtin_ia32_cmppd(b, a, 2);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_cmpord_pd(__m128d a, __m128d b)
+{
+  return (__m128d)__builtin_ia32_cmppd(a, b, 7);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_cmpunord_pd(__m128d a, __m128d b)
+{
+  return (__m128d)__builtin_ia32_cmppd(a, b, 3);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_cmpneq_pd(__m128d a, __m128d b)
+{
+  return (__m128d)__builtin_ia32_cmppd(a, b, 4);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_cmpnlt_pd(__m128d a, __m128d b)
+{
+  return (__m128d)__builtin_ia32_cmppd(a, b, 5);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_cmpnle_pd(__m128d a, __m128d b)
+{
+  return (__m128d)__builtin_ia32_cmppd(a, b, 6);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_cmpngt_pd(__m128d a, __m128d b)
+{
+  return (__m128d)__builtin_ia32_cmppd(b, a, 5);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_cmpnge_pd(__m128d a, __m128d b)
+{
+  return (__m128d)__builtin_ia32_cmppd(b, a, 6);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_cmpeq_sd(__m128d a, __m128d b)
+{
+  return (__m128d)__builtin_ia32_cmpsd(a, b, 0);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_cmplt_sd(__m128d a, __m128d b)
+{
+  return (__m128d)__builtin_ia32_cmpsd(a, b, 1);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_cmple_sd(__m128d a, __m128d b)
+{
+  return (__m128d)__builtin_ia32_cmpsd(a, b, 2);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_cmpgt_sd(__m128d a, __m128d b)
+{
+  return (__m128d)__builtin_ia32_cmpsd(b, a, 1);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_cmpge_sd(__m128d a, __m128d b)
+{
+  return (__m128d)__builtin_ia32_cmpsd(b, a, 2);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_cmpord_sd(__m128d a, __m128d b)
+{
+  return (__m128d)__builtin_ia32_cmpsd(a, b, 7);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_cmpunord_sd(__m128d a, __m128d b)
+{
+  return (__m128d)__builtin_ia32_cmpsd(a, b, 3);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_cmpneq_sd(__m128d a, __m128d b)
+{
+  return (__m128d)__builtin_ia32_cmpsd(a, b, 4);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_cmpnlt_sd(__m128d a, __m128d b)
+{
+  return (__m128d)__builtin_ia32_cmpsd(a, b, 5);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_cmpnle_sd(__m128d a, __m128d b)
+{
+  return (__m128d)__builtin_ia32_cmpsd(a, b, 6);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_cmpngt_sd(__m128d a, __m128d b)
+{
+  return (__m128d)__builtin_ia32_cmpsd(b, a, 5);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_cmpnge_sd(__m128d a, __m128d b)
+{
+  return (__m128d)__builtin_ia32_cmpsd(b, a, 6);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_comieq_sd(__m128d a, __m128d b)
+{
+  return __builtin_ia32_comisdeq(a, b);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_comilt_sd(__m128d a, __m128d b)
+{
+  return __builtin_ia32_comisdlt(a, b);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_comile_sd(__m128d a, __m128d b)
+{
+  return __builtin_ia32_comisdle(a, b);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_comigt_sd(__m128d a, __m128d b)
+{
+  return __builtin_ia32_comisdgt(a, b);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_comineq_sd(__m128d a, __m128d b)
+{
+  return __builtin_ia32_comisdneq(a, b);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_ucomieq_sd(__m128d a, __m128d b)
+{
+  return __builtin_ia32_ucomisdeq(a, b);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_ucomilt_sd(__m128d a, __m128d b)
+{
+  return __builtin_ia32_ucomisdlt(a, b);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_ucomile_sd(__m128d a, __m128d b)
+{
+  return __builtin_ia32_ucomisdle(a, b);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_ucomigt_sd(__m128d a, __m128d b)
+{
+  return __builtin_ia32_ucomisdgt(a, b);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_ucomineq_sd(__m128d a, __m128d b)
+{
+  return __builtin_ia32_ucomisdneq(a, b);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cvtpd_ps(__m128d a)
+{
+  return __builtin_ia32_cvtpd2ps(a);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_cvtps_pd(__m128 a)
+{
+  return __builtin_ia32_cvtps2pd(a);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_cvtepi32_pd(__m128i a)
+{
+  return __builtin_ia32_cvtdq2pd((__v4si)a);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_cvtpd_epi32(__m128d a)
+{
+  return __builtin_ia32_cvtpd2dq(a);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_cvtsd_si32(__m128d a)
+{
+  return __builtin_ia32_cvtsd2si(a);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cvtsd_ss(__m128 a, __m128d b)
+{
+  a[0] = b[0];
+  return a;
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_cvtsi32_sd(__m128d a, int b)
+{
+  a[0] = b;
+  return a;
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_cvtss_sd(__m128d a, __m128 b)
+{
+  a[0] = b[0];
+  return a;
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_cvttpd_epi32(__m128d a)
+{
+  return (__m128i)__builtin_ia32_cvttpd2dq(a);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_cvttsd_si32(__m128d a)
+{
+  return a[0];
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_cvtpd_pi32(__m128d a)
+{
+  return (__m64)__builtin_ia32_cvtpd2pi(a);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_cvttpd_pi32(__m128d a)
+{
+  return (__m64)__builtin_ia32_cvttpd2pi(a);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_cvtpi32_pd(__m64 a)
+{
+  return __builtin_ia32_cvtpi2pd((__v2si)a);
+}
+
+static __inline__ double __attribute__((__always_inline__, __nodebug__))
+_mm_cvtsd_f64(__m128d a)
+{
+  return a[0];
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_load_pd(double const *dp)
+{
+  return *(__m128d*)dp;
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_load1_pd(double const *dp)
+{
+  return (__m128d){ dp[0], dp[0] };
+}
+
+#define        _mm_load_pd1(dp)        _mm_load1_pd(dp)
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_loadr_pd(double const *dp)
+{
+  return (__m128d){ dp[1], dp[0] };
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_loadu_pd(double const *dp)
+{
+  return __builtin_ia32_loadupd(dp);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_load_sd(double const *dp)
+{
+  return (__m128d){ *dp, 0.0 };
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_loadh_pd(__m128d a, double const *dp)
+{
+  return __builtin_shufflevector(a, *(__m128d *)dp, 0, 2);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_loadl_pd(__m128d a, double const *dp)
+{
+  return __builtin_shufflevector(a, *(__m128d *)dp, 2, 1);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_set_sd(double w)
+{
+  return (__m128d){ w, 0 };
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_set1_pd(double w)
+{
+  return (__m128d){ w, w };
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_set_pd(double w, double x)
+{
+  return (__m128d){ x, w };
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_setr_pd(double w, double x)
+{
+  return (__m128d){ w, x };
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_setzero_pd(void)
+{
+  return (__m128d){ 0, 0 };
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_move_sd(__m128d a, __m128d b)
+{
+  return (__m128d){ b[0], a[1] };
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_store_sd(double *dp, __m128d a)
+{
+  dp[0] = a[0];
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_store1_pd(double *dp, __m128d a)
+{
+  dp[0] = a[0];
+  dp[1] = a[0];
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_store_pd(double *dp, __m128d a)
+{
+  *(__m128d *)dp = a;
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_storeu_pd(double *dp, __m128d a)
+{
+  __builtin_ia32_storeupd(dp, a);
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_storer_pd(double *dp, __m128d a)
+{
+  dp[0] = a[1];
+  dp[1] = a[0];
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_storeh_pd(double *dp, __m128d a)
+{
+  dp[0] = a[1];
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_storel_pd(double *dp, __m128d a)
+{
+  dp[0] = a[0];
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_add_epi8(__m128i a, __m128i b)
+{
+  return (__m128i)((__v16qi)a + (__v16qi)b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_add_epi16(__m128i a, __m128i b)
+{
+  return (__m128i)((__v8hi)a + (__v8hi)b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_add_epi32(__m128i a, __m128i b)
+{
+  return (__m128i)((__v4si)a + (__v4si)b);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_add_si64(__m64 a, __m64 b)
+{
+  return a + b;
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_add_epi64(__m128i a, __m128i b)
+{
+  return a + b;
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_adds_epi8(__m128i a, __m128i b)
+{
+  return (__m128i)__builtin_ia32_paddsb128((__v16qi)a, (__v16qi)b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_adds_epi16(__m128i a, __m128i b)
+{
+  return (__m128i)__builtin_ia32_paddsw128((__v8hi)a, (__v8hi)b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_adds_epu8(__m128i a, __m128i b)
+{
+  return (__m128i)__builtin_ia32_paddusb128((__v16qi)a, (__v16qi)b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_adds_epu16(__m128i a, __m128i b)
+{
+  return (__m128i)__builtin_ia32_paddusw128((__v8hi)a, (__v8hi)b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_avg_epu8(__m128i a, __m128i b)
+{
+  return (__m128i)__builtin_ia32_pavgb128((__v16qi)a, (__v16qi)b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_avg_epu16(__m128i a, __m128i b)
+{
+  return (__m128i)__builtin_ia32_pavgw128((__v8hi)a, (__v8hi)b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_madd_epi16(__m128i a, __m128i b)
+{
+  return (__m128i)__builtin_ia32_pmaddwd128((__v8hi)a, (__v8hi)b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_max_epi16(__m128i a, __m128i b)
+{
+  return (__m128i)__builtin_ia32_pmaxsw128((__v8hi)a, (__v8hi)b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_max_epu8(__m128i a, __m128i b)
+{
+  return (__m128i)__builtin_ia32_pmaxub128((__v16qi)a, (__v16qi)b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_min_epi16(__m128i a, __m128i b)
+{
+  return (__m128i)__builtin_ia32_pminsw128((__v8hi)a, (__v8hi)b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_min_epu8(__m128i a, __m128i b)
+{
+  return (__m128i)__builtin_ia32_pminub128((__v16qi)a, (__v16qi)b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_mulhi_epi16(__m128i a, __m128i b)
+{
+  return (__m128i)__builtin_ia32_pmulhw128((__v8hi)a, (__v8hi)b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_mulhi_epu16(__m128i a, __m128i b)
+{
+  return (__m128i)__builtin_ia32_pmulhuw128((__v8hi)a, (__v8hi)b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_mullo_epi16(__m128i a, __m128i b)
+{
+  return (__m128i)((__v8hi)a * (__v8hi)b);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_mul_su32(__m64 a, __m64 b)
+{
+  return __builtin_ia32_pmuludq((__v2si)a, (__v2si)b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_mul_epu32(__m128i a, __m128i b)
+{
+  return __builtin_ia32_pmuludq128((__v4si)a, (__v4si)b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_sad_epu8(__m128i a, __m128i b)
+{
+  return __builtin_ia32_psadbw128((__v16qi)a, (__v16qi)b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_sub_epi8(__m128i a, __m128i b)
+{
+  return (__m128i)((__v16qi)a - (__v16qi)b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_sub_epi16(__m128i a, __m128i b)
+{
+  return (__m128i)((__v8hi)a - (__v8hi)b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_sub_epi32(__m128i a, __m128i b)
+{
+  return (__m128i)((__v4si)a - (__v4si)b);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_sub_si64(__m64 a, __m64 b)
+{
+  return a - b;
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_sub_epi64(__m128i a, __m128i b)
+{
+  return a - b;
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_subs_epi8(__m128i a, __m128i b)
+{
+  return (__m128i)__builtin_ia32_psubsb128((__v16qi)a, (__v16qi)b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_subs_epi16(__m128i a, __m128i b)
+{
+  return (__m128i)__builtin_ia32_psubsw128((__v8hi)a, (__v8hi)b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_subs_epu8(__m128i a, __m128i b)
+{
+  return (__m128i)__builtin_ia32_psubusb128((__v16qi)a, (__v16qi)b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_subs_epu16(__m128i a, __m128i b)
+{
+  return (__m128i)__builtin_ia32_psubusw128((__v8hi)a, (__v8hi)b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_and_si128(__m128i a, __m128i b)
+{
+  return a & b;
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_andnot_si128(__m128i a, __m128i b)
+{
+  return ~a & b;
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_or_si128(__m128i a, __m128i b)
+{
+  return a | b;
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_xor_si128(__m128i a, __m128i b)
+{
+  return a ^ b;
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_slli_si128(__m128i a, int imm)
+{
+  return __builtin_ia32_pslldqi128(a, imm * 8);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_slli_epi16(__m128i a, int count)
+{
+  return (__m128i)__builtin_ia32_psllwi128((__v8hi)a, count);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_sll_epi16(__m128i a, __m128i count)
+{
+  return (__m128i)__builtin_ia32_psllw128((__v8hi)a, (__v8hi)count);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_slli_epi32(__m128i a, int count)
+{
+  return (__m128i)__builtin_ia32_pslldi128((__v4si)a, count);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_sll_epi32(__m128i a, __m128i count)
+{
+  return (__m128i)__builtin_ia32_pslld128((__v4si)a, (__v4si)count);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_slli_epi64(__m128i a, int count)
+{
+  return __builtin_ia32_psllqi128(a, count);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_sll_epi64(__m128i a, __m128i count)
+{
+  return __builtin_ia32_psllq128(a, count);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_srai_epi16(__m128i a, int count)
+{
+  return (__m128i)__builtin_ia32_psrawi128((__v8hi)a, count);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_sra_epi16(__m128i a, __m128i count)
+{
+  return (__m128i)__builtin_ia32_psraw128((__v8hi)a, (__v8hi)count);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_srai_epi32(__m128i a, int count)
+{
+  return (__m128i)__builtin_ia32_psradi128((__v4si)a, count);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_sra_epi32(__m128i a, __m128i count)
+{
+  return (__m128i)__builtin_ia32_psrad128((__v4si)a, (__v4si)count);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_srli_si128(__m128i a, int imm)
+{
+  return __builtin_ia32_psrldqi128(a, imm * 8);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_srli_epi16(__m128i a, int count)
+{
+  return (__m128i)__builtin_ia32_psrlwi128((__v8hi)a, count);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_srl_epi16(__m128i a, __m128i count)
+{
+  return (__m128i)__builtin_ia32_psrlw128((__v8hi)a, (__v8hi)count);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_srli_epi32(__m128i a, int count)
+{
+  return (__m128i)__builtin_ia32_psrldi128((__v4si)a, count);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_srl_epi32(__m128i a, __m128i count)
+{
+  return (__m128i)__builtin_ia32_psrld128((__v4si)a, (__v4si)count);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_srli_epi64(__m128i a, int count)
+{
+  return __builtin_ia32_psrlqi128(a, count);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_srl_epi64(__m128i a, __m128i count)
+{
+  return __builtin_ia32_psrlq128(a, count);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_cmpeq_epi8(__m128i a, __m128i b)
+{
+  return (__m128i)((__v16qi)a == (__v16qi)b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_cmpeq_epi16(__m128i a, __m128i b)
+{
+  return (__m128i)((__v8hi)a == (__v8hi)b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_cmpeq_epi32(__m128i a, __m128i b)
+{
+  return (__m128i)((__v4si)a == (__v4si)b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_cmpgt_epi8(__m128i a, __m128i b)
+{
+  return (__m128i)((__v16qi)a > (__v16qi)b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_cmpgt_epi16(__m128i a, __m128i b)
+{
+  return (__m128i)((__v8hi)a > (__v8hi)b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_cmpgt_epi32(__m128i a, __m128i b)
+{
+  return (__m128i)((__v4si)a > (__v4si)b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_cmplt_epi8(__m128i a, __m128i b)
+{
+  return _mm_cmpgt_epi8(b,a);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_cmplt_epi16(__m128i a, __m128i b)
+{
+  return _mm_cmpgt_epi16(b,a);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_cmplt_epi32(__m128i a, __m128i b)
+{
+  return _mm_cmpgt_epi32(b,a);
+}
+
+#ifdef __x86_64__
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_cvtsi64_sd(__m128d a, long long b)
+{
+  a[0] = b;
+  return a;
+}
+
+static __inline__ long long __attribute__((__always_inline__, __nodebug__))
+_mm_cvtsd_si64(__m128d a)
+{
+  return __builtin_ia32_cvtsd2si64(a);
+}
+
+static __inline__ long long __attribute__((__always_inline__, __nodebug__))
+_mm_cvttsd_si64(__m128d a)
+{
+  return a[0];
+}
+#endif
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cvtepi32_ps(__m128i a)
+{
+  return __builtin_ia32_cvtdq2ps((__v4si)a);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_cvtps_epi32(__m128 a)
+{
+  return (__m128i)__builtin_ia32_cvtps2dq(a);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_cvttps_epi32(__m128 a)
+{
+  return (__m128i)__builtin_ia32_cvttps2dq(a);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_cvtsi32_si128(int a)
+{
+  return (__m128i)(__v4si){ a, 0, 0, 0 };
+}
+
+#ifdef __x86_64__
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_cvtsi64_si128(long long a)
+{
+  return (__m128i){ a, 0 };
+}
+#endif
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_cvtsi128_si32(__m128i a)
+{
+  __v4si b = (__v4si)a;
+  return b[0];
+}
+
+#ifdef __x86_64__
+static __inline__ long long __attribute__((__always_inline__, __nodebug__))
+_mm_cvtsi128_si64(__m128i a)
+{
+  return a[0];
+}
+#endif
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_load_si128(__m128i const *p)
+{
+  return *p;
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_loadu_si128(__m128i const *p)
+{
+  return (__m128i)__builtin_ia32_loaddqu((char const *)p);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_loadl_epi64(__m128i const *p)
+{
+  return (__m128i) { *(long long*)p, 0};
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_set_epi64x(long long q1, long long q0)
+{
+  return (__m128i){ q0, q1 };
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_set_epi64(__m64 q1, __m64 q0)
+{
+  return (__m128i){ (long long)q0, (long long)q1 };
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_set_epi32(int i3, int i2, int i1, int i0)
+{
+  return (__m128i)(__v4si){ i0, i1, i2, i3};
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_set_epi16(short w7, short w6, short w5, short w4, short w3, short w2, short w1, short w0)
+{
+  return (__m128i)(__v8hi){ w0, w1, w2, w3, w4, w5, w6, w7 };
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_set_epi8(char b15, char b14, char b13, char b12, char b11, char b10, char b9, char b8, char b7, char b6, char b5, char b4, char b3, char b2, char b1, char b0)
+{
+  return (__m128i)(__v16qi){ b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15 };
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_set1_epi64x(long long q)
+{
+  return (__m128i){ q, q };
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_set1_epi64(__m64 q)
+{
+  return (__m128i){ (long long)q, (long long)q };
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_set1_epi32(int i)
+{
+  return (__m128i)(__v4si){ i, i, i, i };
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_set1_epi16(short w)
+{
+  return (__m128i)(__v8hi){ w, w, w, w, w, w, w, w };
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_set1_epi8(char b)
+{
+  return (__m128i)(__v16qi){ b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b };
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_setr_epi64(__m64 q0, __m64 q1)
+{
+  return (__m128i){ (long long)q0, (long long)q1 };
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_setr_epi32(int i0, int i1, int i2, int i3)
+{
+  return (__m128i)(__v4si){ i0, i1, i2, i3};
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_setr_epi16(short w0, short w1, short w2, short w3, short w4, short w5, short w6, short w7)
+{
+  return (__m128i)(__v8hi){ w0, w1, w2, w3, w4, w5, w6, w7 };
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_setr_epi8(char b0, char b1, char b2, char b3, char b4, char b5, char b6, char b7, char b8, char b9, char b10, char b11, char b12, char b13, char b14, char b15)
+{
+  return (__m128i)(__v16qi){ b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15 };
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_setzero_si128(void)
+{
+  return (__m128i){ 0LL, 0LL };
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_store_si128(__m128i *p, __m128i b)
+{
+  *p = b;
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_storeu_si128(__m128i *p, __m128i b)
+{
+  __builtin_ia32_storedqu((char *)p, (__v16qi)b);
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_maskmoveu_si128(__m128i d, __m128i n, char *p)
+{
+  __builtin_ia32_maskmovdqu((__v16qi)d, (__v16qi)n, p);
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_storel_epi64(__m128i *p, __m128i a)
+{
+  __builtin_ia32_storelv4si((__v2si *)p, a);
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_stream_pd(double *p, __m128d a)
+{
+  __builtin_ia32_movntpd(p, a);
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_stream_si128(__m128i *p, __m128i a)
+{
+  __builtin_ia32_movntdq(p, a);
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_stream_si32(int *p, int a)
+{
+  __builtin_ia32_movnti(p, a);
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_clflush(void const *p)
+{
+  __builtin_ia32_clflush(p);
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_lfence(void)
+{
+  __builtin_ia32_lfence();
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_mfence(void)
+{
+  __builtin_ia32_mfence();
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_packs_epi16(__m128i a, __m128i b)
+{
+  return (__m128i)__builtin_ia32_packsswb128((__v8hi)a, (__v8hi)b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_packs_epi32(__m128i a, __m128i b)
+{
+  return (__m128i)__builtin_ia32_packssdw128((__v4si)a, (__v4si)b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_packus_epi16(__m128i a, __m128i b)
+{
+  return (__m128i)__builtin_ia32_packuswb128((__v8hi)a, (__v8hi)b);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_extract_epi16(__m128i a, int imm)
+{
+  __v8hi b = (__v8hi)a;
+  return b[imm];
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_insert_epi16(__m128i a, int b, int imm)
+{
+  __v8hi c = (__v8hi)a;
+  c[imm & 7] = b;
+  return (__m128i)c;
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_movemask_epi8(__m128i a)
+{
+  return __builtin_ia32_pmovmskb128((__v16qi)a);
+}
+
+#define _mm_shuffle_epi32(a, imm) \
+  ((__m128i)__builtin_shufflevector((__v4si)(a), (__v4si) {0}, \
+                                    (imm) & 0x3, ((imm) & 0xc) >> 2, \
+                                    ((imm) & 0x30) >> 4, ((imm) & 0xc0) >> 6))
+#define _mm_shufflelo_epi16(a, imm) \
+  ((__m128i)__builtin_shufflevector((__v8hi)(a), (__v8hi) {0}, \
+                                    (imm) & 0x3, ((imm) & 0xc) >> 2, \
+                                    ((imm) & 0x30) >> 4, ((imm) & 0xc0) >> 6, \
+                                    4, 5, 6, 7))
+#define _mm_shufflehi_epi16(a, imm) \
+  ((__m128i)__builtin_shufflevector((__v8hi)(a), (__v8hi) {0}, 0, 1, 2, 3, \
+                                    4 + ((imm) & 0x3), 4 + ((imm) & 0xc) >> 2, \
+                                    4 + ((imm) & 0x30) >> 4, \
+                                    4 + ((imm) & 0xc0) >> 6))
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_unpackhi_epi8(__m128i a, __m128i b)
+{
+  return (__m128i)__builtin_shufflevector((__v16qi)a, (__v16qi)b, 8, 16+8, 9, 16+9, 10, 16+10, 11, 16+11, 12, 16+12, 13, 16+13, 14, 16+14, 15, 16+15);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_unpackhi_epi16(__m128i a, __m128i b)
+{
+  return (__m128i)__builtin_shufflevector((__v8hi)a, (__v8hi)b, 4, 8+4, 5, 8+5, 6, 8+6, 7, 8+7);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_unpackhi_epi32(__m128i a, __m128i b)
+{
+  return (__m128i)__builtin_shufflevector((__v4si)a, (__v4si)b, 2, 4+2, 3, 4+3);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_unpackhi_epi64(__m128i a, __m128i b)
+{
+  return (__m128i)__builtin_shufflevector(a, b, 1, 2+1);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_unpacklo_epi8(__m128i a, __m128i b)
+{
+  return (__m128i)__builtin_shufflevector((__v16qi)a, (__v16qi)b, 0, 16+0, 1, 16+1, 2, 16+2, 3, 16+3, 4, 16+4, 5, 16+5, 6, 16+6, 7, 16+7);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_unpacklo_epi16(__m128i a, __m128i b)
+{
+  return (__m128i)__builtin_shufflevector((__v8hi)a, (__v8hi)b, 0, 8+0, 1, 8+1, 2, 8+2, 3, 8+3);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_unpacklo_epi32(__m128i a, __m128i b)
+{
+  return (__m128i)__builtin_shufflevector((__v4si)a, (__v4si)b, 0, 4+0, 1, 4+1);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_unpacklo_epi64(__m128i a, __m128i b)
+{
+  return (__m128i)__builtin_shufflevector(a, b, 0, 2+0);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_movepi64_pi64(__m128i a)
+{
+  return (__m64)a[0];
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_movpi64_pi64(__m64 a)
+{
+  return (__m128i){ (long long)a, 0 };
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_move_epi64(__m128i a)
+{
+  return __builtin_shufflevector(a, (__m128i){ 0 }, 0, 2);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_unpackhi_pd(__m128d a, __m128d b)
+{
+  return __builtin_shufflevector(a, b, 1, 2+1);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_unpacklo_pd(__m128d a, __m128d b)
+{
+  return __builtin_shufflevector(a, b, 0, 2+0);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_movemask_pd(__m128d a)
+{
+  return __builtin_ia32_movmskpd(a);
+}
+
+#define _mm_shuffle_pd(a, b, i) (__builtin_shufflevector((a), (b), (i) & 1, \
+                                                         (((i) & 2) >> 1) + 2))
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_castpd_ps(__m128d in)
+{
+  return (__m128)in;
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_castpd_si128(__m128d in)
+{
+  return (__m128i)in;
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_castps_pd(__m128 in)
+{
+  return (__m128d)in;
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_castps_si128(__m128 in)
+{
+  return (__m128i)in;
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_castsi128_ps(__m128i in)
+{
+  return (__m128)in;
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_castsi128_pd(__m128i in)
+{
+  return (__m128d)in;
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_pause(void)
+{
+  __asm__ volatile ("pause");
+}
+
+#define _MM_SHUFFLE2(x, y) (((x) << 1) | (y))
+
+#endif /* __SSE2__ */
+
+#endif /* __EMMINTRIN_H */
diff --git a/lib/Headers/float.h b/lib/Headers/float.h
new file mode 100644
index 0000000..28fb882
--- /dev/null
+++ b/lib/Headers/float.h
@@ -0,0 +1,71 @@
+/*===---- float.h - Characteristics of floating point types ----------------===
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#ifndef __FLOAT_H
+#define __FLOAT_H
+
+/* Characteristics of floating point types, C99 5.2.4.2.2 */
+
+#define FLT_EVAL_METHOD __FLT_EVAL_METHOD__
+#define FLT_ROUNDS (__builtin_flt_rounds())
+#define FLT_RADIX __FLT_RADIX__
+
+#define FLT_MANT_DIG __FLT_MANT_DIG__
+#define DBL_MANT_DIG __DBL_MANT_DIG__
+#define LDBL_MANT_DIG __LDBL_MANT_DIG__
+
+#define DECIMAL_DIG __DECIMAL_DIG__
+
+#define FLT_DIG __FLT_DIG__
+#define DBL_DIG __DBL_DIG__
+#define LDBL_DIG __LDBL_DIG__
+
+#define FLT_MIN_EXP __FLT_MIN_EXP__
+#define DBL_MIN_EXP __DBL_MIN_EXP__
+#define LDBL_MIN_EXP __LDBL_MIN_EXP__
+
+#define FLT_MIN_10_EXP __FLT_MIN_10_EXP__
+#define DBL_MIN_10_EXP __DBL_MIN_10_EXP__
+#define LDBL_MIN_10_EXP __LDBL_MIN_10_EXP__
+
+#define FLT_MAX_EXP __FLT_MAX_EXP__
+#define DBL_MAX_EXP __DBL_MAX_EXP__
+#define LDBL_MAX_EXP __LDBL_MAX_EXP__
+
+#define FLT_MAX_10_EXP __FLT_MAX_10_EXP__
+#define DBL_MAX_10_EXP __DBL_MAX_10_EXP__
+#define LDBL_MAX_10_EXP __LDBL_MAX_10_EXP__
+
+#define FLT_MAX __FLT_MAX__
+#define DBL_MAX __DBL_MAX__
+#define LDBL_MAX __LDBL_MAX__
+
+#define FLT_EPSILON __FLT_EPSILON__
+#define DBL_EPSILON __DBL_EPSILON__
+#define LDBL_EPSILON __LDBL_EPSILON__
+
+#define FLT_MIN __FLT_MIN__
+#define DBL_MIN __DBL_MIN__
+#define LDBL_MIN __LDBL_MIN__
+
+#endif /* __FLOAT_H */
diff --git a/lib/Headers/iso646.h b/lib/Headers/iso646.h
new file mode 100644
index 0000000..dca13c5
--- /dev/null
+++ b/lib/Headers/iso646.h
@@ -0,0 +1,43 @@
+/*===---- iso646.h - Standard header for alternate spellings of operators---===
+ *
+ * Copyright (c) 2008 Eli Friedman
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#ifndef __ISO646_H
+#define __ISO646_H
+
+#ifndef __cplusplus
+#define and    &&
+#define and_eq &=
+#define bitand &
+#define bitor  |
+#define compl  ~
+#define not    !
+#define not_eq !=
+#define or     ||
+#define or_eq  |=
+#define xor    ^
+#define xor_eq ^=
+#endif
+
+#endif /* __ISO646_H */
diff --git a/lib/Headers/limits.h b/lib/Headers/limits.h
new file mode 100644
index 0000000..2627533
--- /dev/null
+++ b/lib/Headers/limits.h
@@ -0,0 +1,113 @@
+/*===---- limits.h - Standard header for integer sizes --------------------===*\
+ *
+ * Copyright (c) 2009 Chris Lattner
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+\*===----------------------------------------------------------------------===*/
+
+#ifndef __CLANG_LIMITS_H
+#define __CLANG_LIMITS_H
+
+/* The system's limits.h may, in turn, try to #include_next GCC's limits.h.
+   Avert this #include_next madness. */
+#if defined __GNUC__ && !defined _GCC_LIMITS_H_
+#define _GCC_LIMITS_H_
+#endif
+
+/* System headers include a number of constants from POSIX in <limits.h>. */
+#include_next <limits.h>
+
+/* Many system headers try to "help us out" by defining these.  No really, we
+   know how big each datatype is. */
+#undef  SCHAR_MIN
+#undef  SCHAR_MAX
+#undef  UCHAR_MAX
+#undef  SHRT_MIN
+#undef  SHRT_MAX
+#undef  USHRT_MAX
+#undef  INT_MIN
+#undef  INT_MAX
+#undef  UINT_MAX
+#undef  LONG_MIN
+#undef  LONG_MAX
+#undef  ULONG_MAX
+
+#undef  CHAR_BIT
+#undef  CHAR_MIN
+#undef  CHAR_MAX
+
+/* C90/99 5.2.4.2.1 */
+#define SCHAR_MAX __SCHAR_MAX__
+#define SHRT_MAX  __SHRT_MAX__
+#define INT_MAX   __INT_MAX__
+#define LONG_MAX  __LONG_MAX__
+
+#define SCHAR_MIN (-__SCHAR_MAX__-1)
+#define SHRT_MIN  (-__SHRT_MAX__ -1)
+#define INT_MIN   (-__INT_MAX__  -1)
+#define LONG_MIN  (-__LONG_MAX__ -1L)
+
+#define UCHAR_MAX (__SCHAR_MAX__*2  +1)
+#define USHRT_MAX (__SHRT_MAX__ *2  +1)
+#define UINT_MAX  (__INT_MAX__  *2U +1U)
+#define ULONG_MAX (__LONG_MAX__ *2UL+1UL)
+
+#ifndef MB_LEN_MAX
+#define MB_LEN_MAX 1
+#endif
+
+#define CHAR_BIT  __CHAR_BIT__
+
+#ifdef __CHAR_UNSIGNED__  /* -funsigned-char */
+#define CHAR_MIN 0
+#define CHAR_MAX UCHAR_MAX
+#else
+#define CHAR_MIN SCHAR_MIN
+#define CHAR_MAX __SCHAR_MAX__
+#endif
+
+/* C99 5.2.4.2.1: Added long long. */
+#if __STDC_VERSION__ >= 199901
+
+#undef  LLONG_MIN
+#undef  LLONG_MAX
+#undef  ULLONG_MAX
+
+#define LLONG_MAX  __LONG_LONG_MAX__
+#define LLONG_MIN  (-__LONG_LONG_MAX__-1LL)
+#define ULLONG_MAX (__LONG_LONG_MAX__*2ULL+1ULL)
+#endif
+
+/* LONG_LONG_MIN/LONG_LONG_MAX/ULONG_LONG_MAX are a GNU extension.  It's too bad
+   that we don't have something like #pragma poison that could be used to
+   deprecate a macro - the code should just use LLONG_MAX and friends.
+ */
+#if defined(__GNU_LIBRARY__) ? defined(__USE_GNU) : !defined(__STRICT_ANSI__)
+
+#undef   LONG_LONG_MIN
+#undef   LONG_LONG_MAX
+#undef   ULONG_LONG_MAX
+
+#define LONG_LONG_MAX  __LONG_LONG_MAX__
+#define LONG_LONG_MIN  (-__LONG_LONG_MAX__-1LL)
+#define ULONG_LONG_MAX (__LONG_LONG_MAX__*2ULL+1ULL)
+#endif
+
+#endif /* __CLANG_LIMITS_H */
diff --git a/lib/Headers/mm_malloc.h b/lib/Headers/mm_malloc.h
new file mode 100644
index 0000000..fba8651
--- /dev/null
+++ b/lib/Headers/mm_malloc.h
@@ -0,0 +1,62 @@
+/*===---- mm_malloc.h - Allocating and Freeing Aligned Memory Blocks -------===
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#ifndef __MM_MALLOC_H
+#define __MM_MALLOC_H
+
+#include <errno.h>
+#include <stdlib.h>
+
+static __inline__ void *__attribute__((__always_inline__, __nodebug__))
+_mm_malloc(size_t size, size_t align)
+{
+  if (align & (align - 1)) {
+    errno = EINVAL;
+    return 0;
+  }
+
+  if (!size)
+    return 0;
+
+  if (align < 2 * sizeof(void *))
+    align = 2 * sizeof(void *);
+
+  void *mallocedMemory = malloc(size + align);
+  if (!mallocedMemory)
+    return 0;
+
+  void *alignedMemory =
+    (void *)(((size_t)mallocedMemory + align) & ~((size_t)align - 1));
+  ((void **)alignedMemory)[-1] = mallocedMemory;
+
+  return alignedMemory;
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_free(void *p)
+{
+  if (p)
+    free(((void **)p)[-1]);
+}
+
+#endif /* __MM_MALLOC_H */
diff --git a/lib/Headers/mmintrin.h b/lib/Headers/mmintrin.h
new file mode 100644
index 0000000..401d8a7
--- /dev/null
+++ b/lib/Headers/mmintrin.h
@@ -0,0 +1,449 @@
+/*===---- mmintrin.h - MMX intrinsics --------------------------------------===
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#ifndef __MMINTRIN_H
+#define __MMINTRIN_H
+
+#ifndef __MMX__
+#error "MMX instruction set not enabled"
+#else
+
+typedef long long __m64 __attribute__((__vector_size__(8)));
+
+typedef int __v2si __attribute__((__vector_size__(8)));
+typedef short __v4hi __attribute__((__vector_size__(8)));
+typedef char __v8qi __attribute__((__vector_size__(8)));
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_empty(void)
+{
+    __builtin_ia32_emms();
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_cvtsi32_si64(int __i)
+{
+    return (__m64)(__v2si){__i, 0};
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_cvtsi64_si32(__m64 __m)
+{
+    __v2si __mmx_var2 = (__v2si)__m;
+    return __mmx_var2[0];
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_cvtsi64_m64(long long __i)
+{
+    return (__m64)__i;
+}
+
+static __inline__ long long __attribute__((__always_inline__, __nodebug__))
+_mm_cvtm64_si64(__m64 __m)
+{
+    return (long long)__m;
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_packs_pi16(__m64 __m1, __m64 __m2)
+{
+    return (__m64)__builtin_ia32_packsswb((__v4hi)__m1, (__v4hi)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_packs_pi32(__m64 __m1, __m64 __m2)
+{
+    return (__m64)__builtin_ia32_packssdw((__v2si)__m1, (__v2si)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_packs_pu16(__m64 __m1, __m64 __m2)
+{
+    return (__m64)__builtin_ia32_packuswb((__v4hi)__m1, (__v4hi)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_unpackhi_pi8(__m64 __m1, __m64 __m2)
+{
+    return (__m64)__builtin_shufflevector((__v8qi)__m1, (__v8qi)__m2, 4, 8+4, 5,
+                                          8+5, 6, 8+6, 7, 8+7);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_unpackhi_pi16(__m64 __m1, __m64 __m2)
+{
+    return (__m64)__builtin_shufflevector((__v4hi)__m1, (__v4hi)__m2, 2, 4+2, 3,
+                                          4+3);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_unpackhi_pi32(__m64 __m1, __m64 __m2)
+{
+    return (__m64)__builtin_shufflevector((__v2si)__m1, (__v2si)__m2, 1, 2+1);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_unpacklo_pi8(__m64 __m1, __m64 __m2)
+{
+    return (__m64)__builtin_shufflevector((__v8qi)__m1, (__v8qi)__m2, 0, 8+0, 1,
+                                          8+1, 2, 8+2, 3, 8+3);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_unpacklo_pi16(__m64 __m1, __m64 __m2)
+{
+    return (__m64)__builtin_shufflevector((__v4hi)__m1, (__v4hi)__m2, 0, 4+0, 1,
+                                          4+1);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_unpacklo_pi32(__m64 __m1, __m64 __m2)
+{
+    return (__m64)__builtin_shufflevector((__v2si)__m1, (__v2si)__m2, 0, 2+0);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_add_pi8(__m64 __m1, __m64 __m2)
+{
+    return (__m64)((__v8qi)__m1 + (__v8qi)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_add_pi16(__m64 __m1, __m64 __m2)
+{
+    return (__m64)((__v4hi)__m1 + (__v4hi)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_add_pi32(__m64 __m1, __m64 __m2)
+{
+    return (__m64)((__v2si)__m1 + (__v2si)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_adds_pi8(__m64 __m1, __m64 __m2) 
+{
+    return (__m64)__builtin_ia32_paddsb((__v8qi)__m1, (__v8qi)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_adds_pi16(__m64 __m1, __m64 __m2)
+{
+    return (__m64)__builtin_ia32_paddsw((__v4hi)__m1, (__v4hi)__m2);    
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_adds_pu8(__m64 __m1, __m64 __m2) 
+{
+    return (__m64)__builtin_ia32_paddusb((__v8qi)__m1, (__v8qi)__m2);
+}
+ 
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_adds_pu16(__m64 __m1, __m64 __m2) 
+{
+    return (__m64)__builtin_ia32_paddusw((__v4hi)__m1, (__v4hi)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_sub_pi8(__m64 __m1, __m64 __m2)
+{
+    return (__m64)((__v8qi)__m1 - (__v8qi)__m2);
+}
+ 
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_sub_pi16(__m64 __m1, __m64 __m2)
+{
+    return (__m64)((__v4hi)__m1 - (__v4hi)__m2);
+}
+ 
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_sub_pi32(__m64 __m1, __m64 __m2)
+{
+    return (__m64)((__v2si)__m1 - (__v2si)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_subs_pi8(__m64 __m1, __m64 __m2)
+{
+    return (__m64)__builtin_ia32_psubsb((__v8qi)__m1, (__v8qi)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_subs_pi16(__m64 __m1, __m64 __m2)
+{
+    return (__m64)__builtin_ia32_psubsw((__v4hi)__m1, (__v4hi)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_subs_pu8(__m64 __m1, __m64 __m2)
+{
+    return (__m64)__builtin_ia32_psubusb((__v8qi)__m1, (__v8qi)__m2);
+}
+ 
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_subs_pu16(__m64 __m1, __m64 __m2)
+{
+    return (__m64)__builtin_ia32_psubusw((__v4hi)__m1, (__v4hi)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_madd_pi16(__m64 __m1, __m64 __m2)
+{
+    return (__m64)__builtin_ia32_pmaddwd((__v4hi)__m1, (__v4hi)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_mulhi_pi16(__m64 __m1, __m64 __m2)
+{
+    return (__m64)__builtin_ia32_pmulhw((__v4hi)__m1, (__v4hi)__m2);
+}
+ 
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_mullo_pi16(__m64 __m1, __m64 __m2) 
+{
+    return (__m64)((__v4hi)__m1 * (__v4hi)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_sll_pi16(__m64 __m, __m64 __count)
+{
+    return (__m64)__builtin_ia32_psllw((__v4hi)__m, __count);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_slli_pi16(__m64 __m, int __count)
+{
+    return (__m64)__builtin_ia32_psllwi((__v4hi)__m, __count);    
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_sll_pi32(__m64 __m, __m64 __count)
+{
+    return (__m64)__builtin_ia32_pslld((__v2si)__m, __count);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_slli_pi32(__m64 __m, int __count)
+{
+    return (__m64)__builtin_ia32_pslldi((__v2si)__m, __count);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_sll_si64(__m64 __m, __m64 __count)
+{
+    return __builtin_ia32_psllq(__m, __count);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_slli_si64(__m64 __m, int __count)
+{
+    return __builtin_ia32_psllqi(__m, __count);    
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_sra_pi16(__m64 __m, __m64 __count)
+{
+    return (__m64)__builtin_ia32_psraw((__v4hi)__m, __count);    
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_srai_pi16(__m64 __m, int __count)
+{
+    return (__m64)__builtin_ia32_psrawi((__v4hi)__m, __count);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_sra_pi32(__m64 __m, __m64 __count)
+{
+    return (__m64)__builtin_ia32_psrad((__v2si)__m, __count);    
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_srai_pi32(__m64 __m, int __count)
+{
+    return (__m64)__builtin_ia32_psradi((__v2si)__m, __count);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_srl_pi16(__m64 __m, __m64 __count)
+{
+    return (__m64)__builtin_ia32_psrlw((__v4hi)__m, __count);    
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_srli_pi16(__m64 __m, int __count)
+{
+    return (__m64)__builtin_ia32_psrlwi((__v4hi)__m, __count);    
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_srl_pi32(__m64 __m, __m64 __count)
+{
+    return (__m64)__builtin_ia32_psrld((__v2si)__m, __count);       
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_srli_pi32(__m64 __m, int __count)
+{
+    return (__m64)__builtin_ia32_psrldi((__v2si)__m, __count);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_srl_si64(__m64 __m, __m64 __count)
+{
+    return (__m64)__builtin_ia32_psrlq(__m, __count);    
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_srli_si64(__m64 __m, int __count)
+{
+    return __builtin_ia32_psrlqi(__m, __count);    
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_and_si64(__m64 __m1, __m64 __m2)
+{
+    return __m1 & __m2;
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_andnot_si64(__m64 __m1, __m64 __m2)
+{
+    return ~__m1 & __m2;
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_or_si64(__m64 __m1, __m64 __m2)
+{
+    return __m1 | __m2;
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_xor_si64(__m64 __m1, __m64 __m2)
+{
+    return __m1 ^ __m2;
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_cmpeq_pi8(__m64 __m1, __m64 __m2)
+{
+    return (__m64)((__v8qi)__m1 == (__v8qi)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_cmpeq_pi16(__m64 __m1, __m64 __m2)
+{
+    return (__m64)((__v4hi)__m1 == (__v4hi)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_cmpeq_pi32(__m64 __m1, __m64 __m2)
+{
+    return (__m64)((__v2si)__m1 == (__v2si)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_cmpgt_pi8(__m64 __m1, __m64 __m2)
+{
+    return (__m64)((__v8qi)__m1 > (__v8qi)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_cmpgt_pi16(__m64 __m1, __m64 __m2)
+{
+    return (__m64)((__v4hi)__m1 > (__v4hi)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_cmpgt_pi32(__m64 __m1, __m64 __m2)
+{
+    return (__m64)((__v2si)__m1 > (__v2si)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_setzero_si64(void)
+{
+    return (__m64){ 0LL };
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_set_pi32(int __i1, int __i0)
+{
+    return (__m64)(__v2si){ __i0, __i1 };
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_set_pi16(short __s3, short __s2, short __s1, short __s0)
+{
+    return (__m64)(__v4hi){ __s0, __s1, __s2, __s3 };    
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_set_pi8(char __b7, char __b6, char __b5, char __b4, char __b3, char __b2,
+            char __b1, char __b0)
+{
+    return (__m64)(__v8qi){ __b0, __b1, __b2, __b3, __b4, __b5, __b6, __b7 };
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_set1_pi32(int __i)
+{
+    return (__m64)(__v2si){ __i, __i };
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_set1_pi16(short __s)
+{
+    return (__m64)(__v4hi){ __s, __s, __s, __s };
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_set1_pi8(char __b)
+{
+    return (__m64)(__v8qi){ __b, __b, __b, __b, __b, __b, __b, __b };
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_setr_pi32(int __i1, int __i0)
+{
+    return (__m64)(__v2si){ __i1, __i0 };
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_setr_pi16(short __s3, short __s2, short __s1, short __s0)
+{
+    return (__m64)(__v4hi){ __s3, __s2, __s1, __s0 };
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_setr_pi8(char __b7, char __b6, char __b5, char __b4, char __b3, char __b2,
+             char __b1, char __b0)
+{
+    return (__m64)(__v8qi){ __b7, __b6, __b5, __b4, __b3, __b2, __b1, __b0 };
+}
+
+#endif /* __MMX__ */
+
+#endif /* __MMINTRIN_H */
+
diff --git a/lib/Headers/nmmintrin.h b/lib/Headers/nmmintrin.h
new file mode 100644
index 0000000..cc213ce
--- /dev/null
+++ b/lib/Headers/nmmintrin.h
@@ -0,0 +1,35 @@
+/*===---- nmmintrin.h - SSE intrinsics -------------------------------------===
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to deal
+* in the Software without restriction, including without limitation the rights
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in
+* all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+* THE SOFTWARE.
+*
+*===-----------------------------------------------------------------------===
+*/
+
+#ifndef _NMMINTRIN_H
+#define _NMMINTRIN_H
+
+#ifndef __SSE4_2__
+#error "SSE4.2 instruction set not enabled"
+#else
+
+/* To match expectations of gcc we put the sse4.2 definitions into smmintrin.h,
+   just include it now then.  */
+#include <smmintrin.h>
+#endif /* __SSE4_2__ */
+#endif /* _NMMINTRIN_H */
diff --git a/lib/Headers/pmmintrin.h b/lib/Headers/pmmintrin.h
new file mode 100644
index 0000000..7ca386c
--- /dev/null
+++ b/lib/Headers/pmmintrin.h
@@ -0,0 +1,121 @@
+/*===---- pmmintrin.h - SSE3 intrinsics ------------------------------------===
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+ 
+#ifndef __PMMINTRIN_H
+#define __PMMINTRIN_H
+
+#ifndef __SSE3__
+#error "SSE3 instruction set not enabled"
+#else
+
+#include <emmintrin.h>
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_lddqu_si128(__m128i const *p)
+{
+  return (__m128i)__builtin_ia32_lddqu((char const *)p);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_addsub_ps(__m128 a, __m128 b)
+{
+  return __builtin_ia32_addsubps(a, b);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_hadd_ps(__m128 a, __m128 b)
+{
+  return __builtin_ia32_haddps(a, b);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_hsub_ps(__m128 a, __m128 b)
+{
+  return __builtin_ia32_hsubps(a, b);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_movehdup_ps(__m128 a)
+{
+  return __builtin_shufflevector(a, a, 1, 1, 3, 3);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_moveldup_ps(__m128 a)
+{
+  return __builtin_shufflevector(a, a, 0, 0, 2, 2);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_addsub_pd(__m128d a, __m128d b)
+{
+  return __builtin_ia32_addsubpd(a, b);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_hadd_pd(__m128d a, __m128d b)
+{
+  return __builtin_ia32_haddpd(a, b);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_hsub_pd(__m128d a, __m128d b)
+{
+  return __builtin_ia32_hsubpd(a, b);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_loaddup_pd(double const *dp)
+{
+  return (__m128d){ *dp, *dp };
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_movedup_pd(__m128d a)
+{
+  return __builtin_shufflevector(a, a, 0, 0);
+}
+
+#define _MM_DENORMALS_ZERO_ON   (0x0040)
+#define _MM_DENORMALS_ZERO_OFF  (0x0000)
+
+#define _MM_DENORMALS_ZERO_MASK (0x0040)
+
+#define _MM_GET_DENORMALS_ZERO_MODE() (_mm_getcsr() & _MM_DENORMALS_ZERO_MASK)
+#define _MM_SET_DENORMALS_ZERO_MODE(x) (_mm_setcsr((_mm_getcsr() & ~_MM_DENORMALS_ZERO_MASK) | (x)))
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_monitor(void const *p, unsigned extensions, unsigned hints)
+{
+  __builtin_ia32_monitor((void *)p, extensions, hints);
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_mwait(unsigned extensions, unsigned hints)
+{
+  __builtin_ia32_mwait(extensions, hints);
+}
+
+#endif /* __SSE3__ */
+
+#endif /* __PMMINTRIN_H */
diff --git a/lib/Headers/smmintrin.h b/lib/Headers/smmintrin.h
new file mode 100644
index 0000000..e271f99
--- /dev/null
+++ b/lib/Headers/smmintrin.h
@@ -0,0 +1,454 @@
+/*===---- smmintrin.h - SSE4 intrinsics ------------------------------------===
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#ifndef _SMMINTRIN_H
+#define _SMMINTRIN_H
+
+#ifndef __SSE4_1__
+#error "SSE4.1 instruction set not enabled"
+#else
+
+#include <tmmintrin.h>
+
+/* Type defines.  */
+typedef double __v2df __attribute__ ((__vector_size__ (16)));
+typedef long long __v2di __attribute__ ((__vector_size__ (16)));
+
+/* SSE4 Rounding macros. */
+#define _MM_FROUND_TO_NEAREST_INT    0x00
+#define _MM_FROUND_TO_NEG_INF        0x01
+#define _MM_FROUND_TO_POS_INF        0x02
+#define _MM_FROUND_TO_ZERO           0x03
+#define _MM_FROUND_CUR_DIRECTION     0x04
+
+#define _MM_FROUND_RAISE_EXC         0x00
+#define _MM_FROUND_NO_EXC            0x08
+
+#define _MM_FROUND_NINT      (_MM_FROUND_RAISE_EXC | _MM_FROUND_TO_NEAREST_INT)
+#define _MM_FROUND_FLOOR     (_MM_FROUND_RAISE_EXC | _MM_FROUND_TO_NEG_INF)
+#define _MM_FROUND_CEIL      (_MM_FROUND_RAISE_EXC | _MM_FROUND_TO_POS_INF)
+#define _MM_FROUND_TRUNC     (_MM_FROUND_RAISE_EXC | _MM_FROUND_TO_ZERO)
+#define _MM_FROUND_RINT      (_MM_FROUND_RAISE_EXC | _MM_FROUND_CUR_DIRECTION)
+#define _MM_FROUND_NEARBYINT (_MM_FROUND_NO_EXC | _MM_FROUND_CUR_DIRECTION)
+
+#define _mm_ceil_ps(X)       _mm_round_ps((X), _MM_FROUND_CEIL)
+#define _mm_ceil_pd(X)       _mm_round_pd((X), _MM_FROUND_CEIL)
+#define _mm_ceil_ss(X, Y)    _mm_round_ss((X), (Y), _MM_FROUND_CEIL)
+#define _mm_ceil_sd(X, Y)    _mm_round_sd((X), (Y), _MM_FROUND_CEIL)
+
+#define _mm_floor_ps(X)      _mm_round_ps((X), _MM_FROUND_FLOOR)
+#define _mm_floor_pd(X)      _mm_round_pd((X), _MM_FROUND_FLOOR)
+#define _mm_floor_ss(X, Y)   _mm_round_ss((X), (Y), _MM_FROUND_FLOOR)
+#define _mm_floor_sd(X, Y)   _mm_round_sd((X), (Y), _MM_FROUND_FLOOR)
+
+#define _mm_round_ps(X, Y)      __builtin_ia32_roundps((X), (Y))
+#define _mm_round_ss(X, Y, M)   __builtin_ia32_roundss((X), (Y), (M))
+#define _mm_round_pd(X, M)      __builtin_ia32_roundpd((X), (M))
+#define _mm_round_sd(X, Y, M)   __builtin_ia32_roundsd((X), (Y), (M))
+
+/* SSE4 Packed Blending Intrinsics.  */
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_blend_pd (__m128d __V1, __m128d __V2, const int __M)
+{
+  return (__m128d) __builtin_ia32_blendpd ((__v2df)__V1, (__v2df)__V2, __M);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_blend_ps (__m128 __V1, __m128 __V2, const int __M)
+{
+  return (__m128) __builtin_ia32_blendps ((__v4sf)__V1, (__v4sf)__V2, __M);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_blendv_pd (__m128d __V1, __m128d __V2, __m128d __M)
+{
+  return (__m128d) __builtin_ia32_blendvpd ((__v2df)__V1, (__v2df)__V2,
+                                            (__v2df)__M);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_blendv_ps (__m128 __V1, __m128 __V2, __m128 __M)
+{
+  return (__m128) __builtin_ia32_blendvps ((__v4sf)__V1, (__v4sf)__V2,
+                                           (__v4sf)__M);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_blendv_epi8 (__m128i __V1, __m128i __V2, __m128i __M)
+{
+  return (__m128i) __builtin_ia32_pblendvb128 ((__v16qi)__V1, (__v16qi)__V2,
+                                               (__v16qi)__M);
+}
+
+static __inline__  __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_blend_epi16 (__m128i __V1, __m128i __V2, const int __M)
+{
+  return (__m128i) __builtin_ia32_pblendw128 ((__v8hi)__V1, (__v8hi)__V2, __M);
+}
+
+/* SSE4 Dword Multiply Instructions.  */
+static __inline__  __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_mullo_epi32 (__m128i __V1, __m128i __V2)
+{
+  return (__m128i) ((__v4si)__V1 * (__v4si)__V2);
+}
+
+static __inline__  __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_mul_epi32 (__m128i __V1, __m128i __V2)
+{
+  return (__m128i) __builtin_ia32_pmuldq128 ((__v4si)__V1, (__v4si)__V2);
+}
+
+/* SSE4 Floating Point Dot Product Instructions.  */
+#define _mm_dp_ps(X, Y, M) __builtin_ia32_dpps ((X), (Y), (M))
+#define _mm_dp_pd(X, Y, M) __builtin_ia32_dppd ((X), (Y), (M))
+
+/* SSE4 Streaming Load Hint Instruction.  */
+static __inline__  __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_stream_load_si128 (__m128i *__V)
+{
+  return (__m128i) __builtin_ia32_movntdqa ((__v2di *) __V);
+}
+
+/* SSE4 Packed Integer Min/Max Instructions.  */
+static __inline__  __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_min_epi8 (__m128i __V1, __m128i __V2)
+{
+  return (__m128i) __builtin_ia32_pminsb128 ((__v16qi) __V1, (__v16qi) __V2);
+}
+
+static __inline__  __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_max_epi8 (__m128i __V1, __m128i __V2)
+{
+  return (__m128i) __builtin_ia32_pmaxsb128 ((__v16qi) __V1, (__v16qi) __V2);
+}
+
+static __inline__  __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_min_epu16 (__m128i __V1, __m128i __V2)
+{
+  return (__m128i) __builtin_ia32_pminuw128 ((__v8hi) __V1, (__v8hi) __V2);
+}
+
+static __inline__  __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_max_epu16 (__m128i __V1, __m128i __V2)
+{
+  return (__m128i) __builtin_ia32_pmaxuw128 ((__v8hi) __V1, (__v8hi) __V2);
+}
+
+static __inline__  __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_min_epi32 (__m128i __V1, __m128i __V2)
+{
+  return (__m128i) __builtin_ia32_pminsd128 ((__v4si) __V1, (__v4si) __V2);
+}
+
+static __inline__  __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_max_epi32 (__m128i __V1, __m128i __V2)
+{
+  return (__m128i) __builtin_ia32_pmaxsd128 ((__v4si) __V1, (__v4si) __V2);
+}
+
+static __inline__  __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_min_epu32 (__m128i __V1, __m128i __V2)
+{
+  return (__m128i) __builtin_ia32_pminud128((__v4si) __V1, (__v4si) __V2);
+}
+
+static __inline__  __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_max_epu32 (__m128i __V1, __m128i __V2)
+{
+  return (__m128i) __builtin_ia32_pmaxud128((__v4si) __V1, (__v4si) __V2);
+}
+
+/* SSE4 Insertion and Extraction from XMM Register Instructions.  */
+#define _mm_insert_ps(X, Y, N) __builtin_ia32_insertps128((X), (Y), (N))
+#define _mm_extract_ps(X, N) (__extension__                      \
+                              ({ union { int i; float f; } __t;  \
+                                 __v4sf __a = (__v4sf)X;         \
+                                 __t.f = __a[N];                 \
+                                 __t.i;}))
+
+/* Miscellaneous insert and extract macros.  */
+/* Extract a single-precision float from X at index N into D.  */
+#define _MM_EXTRACT_FLOAT(D, X, N) (__extension__ ({ __v4sf __a = (__v4sf)X; \
+                                                    (D) = __a[N]; }))
+                                                    
+/* Or together 2 sets of indexes (X and Y) with the zeroing bits (Z) to create
+   an index suitable for _mm_insert_ps.  */
+#define _MM_MK_INSERTPS_NDX(X, Y, Z) (((X) << 6) | ((Y) << 4) | (Z))
+                                           
+/* Extract a float from X at index N into the first index of the return.  */
+#define _MM_PICK_OUT_PS(X, N) _mm_insert_ps (_mm_setzero_ps(), (X),   \
+                                             _MM_MK_INSERTPS_NDX((N), 0, 0x0e))
+                                             
+/* Insert int into packed integer array at index.  */
+#define _mm_insert_epi8(X, I, N) (__extension__ ({ __v16qi __a = (__v16qi)X; \
+                                                   __a[N] = I;               \
+                                                   __a;}))
+#define _mm_insert_epi32(X, I, N) (__extension__ ({ __v4si __a = (__v4si)X; \
+                                                    __a[N] = I;             \
+                                                    __a;}))
+#ifdef __x86_64__
+#define _mm_insert_epi64(X, I, N) (__extension__ ({ __v2di __a = (__v2di)X; \
+                                                    __a[N] = I;             \
+                                                    __a;}))
+#endif /* __x86_64__ */
+
+/* Extract int from packed integer array at index.  */
+#define _mm_extract_epi8(X, N) (__extension__ ({ __v16qi __a = (__v16qi)X; \
+                                                 __a[N];}))
+#define _mm_extract_epi32(X, N) (__extension__ ({ __v4si __a = (__v4si)X; \
+                                                  __a[N];}))
+#ifdef __x86_64__
+#define _mm_extract_epi64(X, N) (__extension__ ({ __v2di __a = (__v2di)X; \
+                                                  __a[N];}))
+#endif /* __x86_64 */
+
+/* SSE4 128-bit Packed Integer Comparisons.  */
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_testz_si128(__m128i __M, __m128i __V)
+{
+  return __builtin_ia32_ptestz128((__v2di)__M, (__v2di)__V);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_testc_si128(__m128i __M, __m128i __V)
+{
+  return __builtin_ia32_ptestc128((__v2di)__M, (__v2di)__V);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_testnzc_si128(__m128i __M, __m128i __V)
+{
+  return __builtin_ia32_ptestnzc128((__v2di)__M, (__v2di)__V);
+}
+
+#define _mm_test_all_ones(V) _mm_testc_si128((V), _mm_cmpeq_epi32((V), (V)))
+#define _mm_test_mix_ones_zeros(M, V) _mm_testnzc_si128((M), (V))
+#define _mm_test_all_zeros(M, V) _mm_testz_si128 ((V), (V))
+
+/* SSE4 64-bit Packed Integer Comparisons.  */
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_cmpeq_epi64(__m128i __V1, __m128i __V2)
+{
+  return (__m128i) __builtin_ia32_pcmpeqq((__v2di)__V1, (__v2di)__V2);
+}
+
+/* SSE4 Packed Integer Sign-Extension.  */
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_cvtepi8_epi16(__m128i __V)
+{
+  return (__m128i) __builtin_ia32_pmovsxbw128((__v16qi) __V);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_cvtepi8_epi32(__m128i __V)
+{
+  return (__m128i) __builtin_ia32_pmovsxbd128((__v16qi) __V);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_cvtepi8_epi64(__m128i __V)
+{
+  return (__m128i) __builtin_ia32_pmovsxbq128((__v16qi) __V);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_cvtepi16_epi32(__m128i __V)
+{
+  return (__m128i) __builtin_ia32_pmovsxwd128((__v8hi) __V); 
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_cvtepi16_epi64(__m128i __V)
+{
+  return (__m128i) __builtin_ia32_pmovsxwq128((__v8hi)__V);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_cvtepi32_epi64(__m128i __V)
+{
+  return (__m128i) __builtin_ia32_pmovsxdq128((__v4si)__V);
+}
+
+/* SSE4 Packed Integer Zero-Extension.  */
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_cvtepu8_epi16(__m128i __V)
+{
+  return (__m128i) __builtin_ia32_pmovzxbw128((__v16qi) __V);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_cvtepu8_epi32(__m128i __V)
+{
+  return (__m128i) __builtin_ia32_pmovzxbd128((__v16qi)__V);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_cvtepu8_epi64(__m128i __V)
+{
+  return (__m128i) __builtin_ia32_pmovzxbq128((__v16qi)__V);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_cvtepu16_epi32(__m128i __V)
+{
+  return (__m128i) __builtin_ia32_pmovzxwd128((__v8hi)__V);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_cvtepu16_epi64(__m128i __V)
+{
+  return (__m128i) __builtin_ia32_pmovzxwq128((__v8hi)__V);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_cvtepu32_epi64(__m128i __V)
+{
+  return (__m128i) __builtin_ia32_pmovzxdq128((__v4si)__V);
+}
+
+/* SSE4 Pack with Unsigned Saturation.  */
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_packus_epi32(__m128i __V1, __m128i __V2)
+{
+  return (__m128i) __builtin_ia32_packusdw128((__v4si)__V1, (__v4si)__V2);
+}
+
+/* SSE4 Multiple Packed Sums of Absolute Difference.  */
+#define _mm_mpsadbw_epu8(X, Y, M) __builtin_ia32_mpsadbw128((X), (Y), (M))
+
+/* These definitions are normally in nmmintrin.h, but gcc puts them in here
+   so we'll do the same.  */
+#ifdef __SSE4_2__
+
+/* These specify the type of data that we're comparing.  */
+#define _SIDD_UBYTE_OPS                 0x00
+#define _SIDD_UWORD_OPS                 0x01
+#define _SIDD_SBYTE_OPS                 0x02
+#define _SIDD_SWORD_OPS                 0x03
+
+/* These specify the type of comparison operation.  */
+#define _SIDD_CMP_EQUAL_ANY             0x00
+#define _SIDD_CMP_RANGES                0x04
+#define _SIDD_CMP_EQUAL_EACH            0x08
+#define _SIDD_CMP_EQUAL_ORDERED         0x0c
+
+/* These macros specify the polarity of the operation.  */
+#define _SIDD_POSITIVE_POLARITY         0x00
+#define _SIDD_NEGATIVE_POLARITY         0x10
+#define _SIDD_MASKED_POSITIVE_POLARITY  0x20
+#define _SIDD_MASKED_NEGATIVE_POLARITY  0x30
+
+/* These macros are used in _mm_cmpXstri() to specify the return.  */
+#define _SIDD_LEAST_SIGNIFICANT         0x00
+#define _SIDD_MOST_SIGNIFICANT          0x40
+
+/* These macros are used in _mm_cmpXstri() to specify the return.  */
+#define _SIDD_BIT_MASK                  0x00
+#define _SIDD_UNIT_MASK                 0x40
+
+/* SSE4.2 Packed Comparison Intrinsics.  */
+#define _mm_cmpistrm(A, B, M) __builtin_ia32_pcmpistrm128((A), (B), (M))
+#define _mm_cmpistri(A, B, M) __builtin_ia32_pcmpistri128((A), (B), (M))
+
+#define _mm_cmpestrm(A, LA, B, LB, M) \
+     __builtin_ia32_pcmpestrm128((A), (LA), (B), (LB), (M))
+#define _mm_cmpestri(X, LX, Y, LY, M) \
+     __builtin_ia32_pcmpestri128((A), (LA), (B), (LB), (M))
+     
+/* SSE4.2 Packed Comparison Intrinsics and EFlag Reading.  */
+#define _mm_cmpistra(A, LA, B, LB, M) \
+     __builtin_ia32_pcmpistria128((A), (LA), (B), (LB), (M))
+#define _mm_cmpistrc(A, LA, B, LB, M) \
+     __builtin_ia32_pcmpistric128((A), (LA), (B), (LB), (M))
+#define _mm_cmpistro(A, LA, B, LB, M) \
+     __builtin_ia32_pcmpistrio128((A), (LA), (B), (LB), (M))
+#define _mm_cmpistrs(A, LA, B, LB, M) \
+     __builtin_ia32_pcmpistris128((A), (LA), (B), (LB), (M))
+#define _mm_cmpistrz(A, LA, B, LB, M) \
+     __builtin_ia32_pcmpistriz128((A), (LA), (B), (LB), (M))
+
+#define _mm_cmpestra(A, LA, B, LB, M) \
+     __builtin_ia32_pcmpestria128((A), (LA), (B), (LB), (M))
+#define _mm_cmpestrc(A, LA, B, LB, M) \
+     __builtin_ia32_pcmpestric128((A), (LA), (B), (LB), (M))
+#define _mm_cmpestro(A, LA, B, LB, M) \
+     __builtin_ia32_pcmpestrio128((A), (LA), (B), (LB), (M))
+#define _mm_cmpestrs(A, LA, B, LB, M) \
+     __builtin_ia32_pcmpestris128((A), (LA), (B), (LB), (M))
+#define _mm_cmpestrz(A, LA, B, LB, M) \
+     __builtin_ia32_pcmpestriz128((A), (LA), (B), (LB), (M))
+
+/* SSE4.2 Compare Packed Data -- Greater Than.  */
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_cmpgt_epi64(__m128i __V1, __m128i __V2)
+{
+  return __builtin_ia32_pcmpgtq((__v2di)__V1, (__v2di)__V2);
+}
+
+/* SSE4.2 Accumulate CRC32.  */
+static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
+_mm_crc32_u8(unsigned int __C, unsigned char __D)
+{
+  return __builtin_ia32_crc32qi(__C, __D);
+}
+
+static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
+_mm_crc32_u16(unsigned int __C, unsigned short __D)
+{
+  return __builtin_ia32_crc32hi(__C, __D);
+}
+
+static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
+_mm_crc32_u32(unsigned int __C, unsigned int __D)
+{
+  return __builtin_ia32_crc32si(__C, __D);
+}
+
+#ifdef __x86_64__
+static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__))
+_mm_crc32_u64(unsigned long long __C, unsigned long long __D)
+{
+  return __builtin_ia32_crc32di(__C, __D);
+}
+#endif /* __x86_64__ */
+
+/* SSE4.2 Population Count.  */
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_popcnt_u32(unsigned int __A)
+{
+  return __builtin_popcount(__A);
+}
+
+#ifdef __x86_64__
+static __inline__ long long __attribute__((__always_inline__, __nodebug__))
+_mm_popcnt_u64(unsigned long long __A)
+{
+  return __builtin_popcountll(__A);
+}
+#endif /* __x86_64__ */
+
+#endif /* __SSE4_2__ */
+#endif /* __SSE4_1__ */
+
+#endif /* _SMMINTRIN_H */
diff --git a/lib/Headers/stdarg.h b/lib/Headers/stdarg.h
new file mode 100644
index 0000000..c36ab12
--- /dev/null
+++ b/lib/Headers/stdarg.h
@@ -0,0 +1,50 @@
+/*===---- stdarg.h - Variable argument handling ----------------------------===
+ *
+ * Copyright (c) 2008 Eli Friedman
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#ifndef __STDARG_H
+#define __STDARG_H
+
+#ifndef _VA_LIST
+typedef __builtin_va_list va_list;
+#define _VA_LIST
+#endif
+#define va_start(ap, param) __builtin_va_start(ap, param)
+#define va_end(ap)          __builtin_va_end(ap)
+#define va_arg(ap, type)    __builtin_va_arg(ap, type)
+
+/* GCC always defines __va_copy, but does not define va_copy unless in c99 mode
+ * or -ansi is not specified, since it was not part of C90.
+ */
+#define __va_copy(d,s) __builtin_va_copy(d,s)
+
+#if __STDC_VERSION__ >= 199900L || !defined(__STRICT_ANSI__)
+#define va_copy(dest, src)  __builtin_va_copy(dest, src)
+#endif
+
+/* Hack required to make standard headers work, at least on Ubuntu */
+#define __GNUC_VA_LIST 1
+typedef __builtin_va_list __gnuc_va_list;
+
+#endif /* __STDARG_H */
diff --git a/lib/Headers/stdbool.h b/lib/Headers/stdbool.h
new file mode 100644
index 0000000..e44a1f9
--- /dev/null
+++ b/lib/Headers/stdbool.h
@@ -0,0 +1,38 @@
+/*===---- stdbool.h - Standard header for booleans -------------------------===
+ *
+ * Copyright (c) 2008 Eli Friedman
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#ifndef __STDBOOL_H
+#define __STDBOOL_H
+
+/* Don't define bool, true, and false in C++ */
+#ifndef __cplusplus
+#define bool _Bool
+#define true 1
+#define false 0
+#endif
+
+#define __bool_true_false_are_defined 1
+
+#endif /* __STDBOOL_H */
diff --git a/lib/Headers/stddef.h b/lib/Headers/stddef.h
new file mode 100644
index 0000000..6868ad3
--- /dev/null
+++ b/lib/Headers/stddef.h
@@ -0,0 +1,50 @@
+/*===---- stddef.h - Basic type definitions --------------------------------===
+ *
+ * Copyright (c) 2008 Eli Friedman
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#ifndef __STDDEF_H
+#define __STDDEF_H
+
+typedef __typeof__(((int*)0)-((int*)0)) ptrdiff_t;
+#ifndef _SIZE_T
+#define _SIZE_T
+typedef __typeof__(sizeof(int)) size_t;
+#endif
+#ifndef __cplusplus
+#ifndef _WCHAR_T
+#define _WCHAR_T
+typedef __typeof__(*L"") wchar_t;
+#endif
+#endif
+
+#undef NULL
+#ifdef __cplusplus
+#define NULL __null
+#else
+#define NULL ((void*)0)
+#endif
+
+#define offsetof(t, d) __builtin_offsetof(t, d)
+
+#endif /* __STDDEF_H */
diff --git a/lib/Headers/stdint.h b/lib/Headers/stdint.h
new file mode 100644
index 0000000..1785f31
--- /dev/null
+++ b/lib/Headers/stdint.h
@@ -0,0 +1,654 @@
+/*===---- stdint.h - Standard header for sized integer types --------------===*\
+ *
+ * Copyright (c) 2009 Chris Lattner
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+\*===----------------------------------------------------------------------===*/
+
+#ifndef __CLANG_STDINT_H
+#define __CLANG_STDINT_H
+
+/* If we're hosted, fall back to the system's stdint.h, which might have
+ * additional definitions.
+ */
+#if __STDC_HOSTED__ && \
+    defined(__has_include_next) && __has_include_next(<stdint.h>)
+# include_next <stdint.h>
+#else
+
+/* C99 7.18.1.1 Exact-width integer types.
+ * C99 7.18.1.2 Minimum-width integer types.
+ * C99 7.18.1.3 Fastest minimum-width integer types.
+ *
+ * The standard requires that exact-width type be defined for 8-, 16-, 32-, and 
+ * 64-bit types if they are implemented. Other exact width types are optional.
+ * This implementation defines an exact-width types for every integer width
+ * that is represented in the standard integer types.
+ *
+ * The standard also requires minimum-width types be defined for 8-, 16-, 32-,
+ * and 64-bit widths regardless of whether there are corresponding exact-width
+ * types. 
+ *
+ * To accomodate targets that are missing types that are exactly 8, 16, 32, or
+ * 64 bits wide, this implementation takes an approach of cascading
+ * redefintions, redefining __int_leastN_t to successively smaller exact-width
+ * types. It is therefore important that the types are defined in order of
+ * descending widths.
+ *
+ * We currently assume that the minimum-width types and the fastest
+ * minimum-width types are the same. This is allowed by the standard, but is
+ * suboptimal.
+ *
+ * In violation of the standard, some targets do not implement a type that is
+ * wide enough to represent all of the required widths (8-, 16-, 32-, 64-bit).  
+ * To accomodate these targets, a required minimum-width type is only
+ * defined if there exists an exact-width type of equal or greater width.
+ */
+
+#ifdef __INT64_TYPE__
+# ifndef __int8_t_defined /* glibc sys/types.h also defines int64_t*/
+typedef signed __INT64_TYPE__ int64_t;
+# endif /* __int8_t_defined */
+typedef unsigned __INT64_TYPE__ uint64_t;
+# define __int_least64_t int64_t
+# define __uint_least64_t uint64_t
+# define __int_least32_t int64_t
+# define __uint_least32_t uint64_t
+# define __int_least16_t int64_t
+# define __uint_least16_t uint64_t
+# define __int_least8_t int64_t
+# define __uint_least8_t uint64_t
+#endif /* __INT64_TYPE__ */
+
+#ifdef __int_least64_t
+typedef __int_least64_t int_least64_t;
+typedef __uint_least64_t uint_least64_t;
+typedef __int_least64_t int_fast64_t;
+typedef __uint_least64_t uint_fast64_t;
+#endif /* __int_least64_t */
+
+#ifdef __INT56_TYPE__
+typedef signed __INT56_TYPE__ int56_t;
+typedef unsigned __INT56_TYPE__ uint56_t;
+typedef int56_t int_least56_t;
+typedef uint56_t uint_least56_t;
+typedef int56_t int_fast56_t;
+typedef uint56_t uint_fast56_t;
+# define __int_least32_t int56_t
+# define __uint_least32_t uint56_t
+# define __int_least16_t int56_t
+# define __uint_least16_t uint56_t
+# define __int_least8_t int56_t
+# define __uint_least8_t uint56_t
+#endif /* __INT56_TYPE__ */
+
+
+#ifdef __INT48_TYPE__
+typedef signed __INT48_TYPE__ int48_t;
+typedef unsigned __INT48_TYPE__ uint48_t;
+typedef int48_t int_least48_t;
+typedef uint48_t uint_least48_t;
+typedef int48_t int_fast48_t;
+typedef uint48_t uint_fast48_t;
+# define __int_least32_t int48_t
+# define __uint_least32_t uint48_t
+# define __int_least16_t int48_t
+# define __uint_least16_t uint48_t
+# define __int_least8_t int48_t
+# define __uint_least8_t uint48_t
+#endif /* __INT48_TYPE__ */
+
+
+#ifdef __INT40_TYPE__
+typedef signed __INT40_TYPE__ int40_t;
+typedef unsigned __INT40_TYPE__ uint40_t;
+typedef int40_t int_least40_t;
+typedef uint40_t uint_least40_t;
+typedef int40_t int_fast40_t;
+typedef uint40_t uint_fast40_t;
+# define __int_least32_t int40_t
+# define __uint_least32_t uint40_t
+# define __int_least16_t int40_t
+# define __uint_least16_t uint40_t
+# define __int_least8_t int40_t
+# define __uint_least8_t uint40_t
+#endif /* __INT40_TYPE__ */
+
+
+#ifdef __INT32_TYPE__
+
+# ifndef __int8_t_defined /* glibc sys/types.h also defines int32_t*/
+typedef signed __INT32_TYPE__ int32_t;
+# endif /* __int8_t_defined */
+
+# ifndef __uint32_t_defined  /* more glibc compatibility */
+# define __uint32_t_defined
+typedef unsigned __INT32_TYPE__ uint32_t;
+# endif /* __uint32_t_defined */
+
+# define __int_least32_t int32_t
+# define __uint_least32_t uint32_t
+# define __int_least16_t int32_t
+# define __uint_least16_t uint32_t
+# define __int_least8_t int32_t
+# define __uint_least8_t uint32_t
+#endif /* __INT32_TYPE__ */
+
+#ifdef __int_least32_t
+typedef __int_least32_t int_least32_t;
+typedef __uint_least32_t uint_least32_t;
+typedef __int_least32_t int_fast32_t;
+typedef __uint_least32_t uint_fast32_t;
+#endif /* __int_least32_t */
+
+#ifdef __INT24_TYPE__
+typedef signed __INT24_TYPE__ int24_t;
+typedef unsigned __INT24_TYPE__ uint24_t;
+typedef int24_t int_least24_t;
+typedef uint24_t uint_least24_t;
+typedef int24_t int_fast24_t;
+typedef uint24_t uint_fast24_t;
+# define __int_least16_t int24_t
+# define __uint_least16_t uint24_t
+# define __int_least8_t int24_t
+# define __uint_least8_t uint24_t
+#endif /* __INT24_TYPE__ */
+
+#ifdef __INT16_TYPE__
+#ifndef __int8_t_defined /* glibc sys/types.h also defines int16_t*/
+typedef signed __INT16_TYPE__ int16_t;
+#endif /* __int8_t_defined */
+typedef unsigned __INT16_TYPE__ uint16_t;
+# define __int_least16_t int16_t
+# define __uint_least16_t uint16_t
+# define __int_least8_t int16_t
+# define __uint_least8_t uint16_t
+#endif /* __INT16_TYPE__ */
+
+#ifdef __int_least16_t
+typedef __int_least16_t int_least16_t;
+typedef __uint_least16_t uint_least16_t;
+typedef __int_least16_t int_fast16_t;
+typedef __uint_least16_t uint_fast16_t;
+#endif /* __int_least16_t */
+
+
+#ifdef __INT8_TYPE__
+#ifndef __int8_t_defined  /* glibc sys/types.h also defines int8_t*/
+typedef signed __INT8_TYPE__ int8_t;
+#endif /* __int8_t_defined */
+typedef unsigned __INT8_TYPE__ uint8_t;
+# define __int_least8_t int8_t
+# define __uint_least8_t uint8_t
+#endif /* __INT8_TYPE__ */
+
+#ifdef __int_least8_t
+typedef __int_least8_t int_least8_t;
+typedef __uint_least8_t uint_least8_t;
+typedef __int_least8_t int_fast8_t;
+typedef __uint_least8_t uint_fast8_t;
+#endif /* __int_least8_t */
+
+/* prevent glibc sys/types.h from defining conflicting types */
+#ifndef __int8_t_defined  
+# define __int8_t_defined
+#endif /* __int8_t_defined */
+
+/* C99 7.18.1.4 Integer types capable of holding object pointers.
+ */
+#define __stdint_join3(a,b,c) a ## b ## c
+
+#define  __intn_t(n) __stdint_join3( int, n, _t)
+#define __uintn_t(n) __stdint_join3(uint, n, _t)
+
+#ifndef _INTPTR_T
+#ifndef __intptr_t_defined
+typedef  __intn_t(__INTPTR_WIDTH__)  intptr_t;
+#define __intptr_t_defined
+#define _INTPTR_T
+#endif
+#endif
+
+#ifndef _UINTPTR_T
+typedef __uintn_t(__INTPTR_WIDTH__) uintptr_t;
+#define _UINTPTR_T
+#endif
+
+/* C99 7.18.1.5 Greatest-width integer types.
+ */
+typedef  __intn_t(__INTMAX_WIDTH__)  intmax_t;
+typedef __uintn_t(__INTMAX_WIDTH__) uintmax_t;
+
+/* C99 7.18.4 Macros for minimum-width integer constants.
+ *
+ * The standard requires that integer constant macros be defined for all the
+ * minimum-width types defined above. As 8-, 16-, 32-, and 64-bit minimum-width
+ * types are required, the corresponding integer constant macros are defined 
+ * here. This implementation also defines minimum-width types for every other
+ * integer width that the target implements, so corresponding macros are 
+ * defined below, too.
+ *
+ * These macros are defined using the same successive-shrinking approach as
+ * the type definitions above. It is likewise important that macros are defined
+ * in order of decending width.
+ *
+ * Note that C++ should not check __STDC_CONSTANT_MACROS here, contrary to the
+ * claims of the C standard (see C++ 18.3.1p2, [cstdint.syn]).
+ */
+
+#define __int_c_join(a, b) a ## b
+#define __int_c(v, suffix) __int_c_join(v, suffix)
+#define __uint_c(v, suffix) __int_c_join(v##U, suffix)
+
+
+#ifdef __INT64_TYPE__
+# ifdef __INT64_C_SUFFIX__
+#  define __int64_c_suffix __INT64_C_SUFFIX__
+#  define __int32_c_suffix __INT64_C_SUFFIX__
+#  define __int16_c_suffix __INT64_C_SUFFIX__
+#  define  __int8_c_suffix __INT64_C_SUFFIX__
+# else
+#  undef __int64_c_suffix
+#  undef __int32_c_suffix
+#  undef __int16_c_suffix
+#  undef  __int8_c_suffix
+# endif /* __INT64_C_SUFFIX__ */
+#endif /* __INT64_TYPE__ */
+
+#ifdef __int_least64_t
+# ifdef __int64_c_suffix
+#  define INT64_C(v) __int_c(v, __int64_c_suffix)
+#  define UINT64_C(v) __uint_c(v, __int64_c_suffix)
+# else
+#  define INT64_C(v) v
+#  define UINT64_C(v) v ## U
+# endif /* __int64_c_suffix */
+#endif /* __int_least64_t */
+
+
+#ifdef __INT56_TYPE__
+# ifdef __INT56_C_SUFFIX__
+#  define INT56_C(v) __int_c(v, __INT56_C_SUFFIX__)
+#  define UINT56_C(v) __uint_c(v, __INT56_C_SUFFIX__)
+#  define __int32_c_suffix __INT56_C_SUFFIX__
+#  define __int16_c_suffix __INT56_C_SUFFIX__
+#  define __int8_c_suffix  __INT56_C_SUFFIX__
+# else
+#  define INT56_C(v) v
+#  define UINT56_C(v) v ## U
+#  undef __int32_c_suffix
+#  undef __int16_c_suffix
+#  undef  __int8_c_suffix
+# endif /* __INT56_C_SUFFIX__ */
+#endif /* __INT56_TYPE__ */
+
+
+#ifdef __INT48_TYPE__
+# ifdef __INT48_C_SUFFIX__
+#  define INT48_C(v) __int_c(v, __INT48_C_SUFFIX__)
+#  define UINT48_C(v) __uint_c(v, __INT48_C_SUFFIX__)
+#  define __int32_c_suffix __INT48_C_SUFFIX__
+#  define __int16_c_suffix __INT48_C_SUFFIX__
+#  define __int8_c_suffix  __INT48_C_SUFFIX__
+# else
+#  define INT48_C(v) v
+#  define UINT48_C(v) v ## U
+#  undef __int32_c_suffix
+#  undef __int16_c_suffix
+#  undef  __int8_c_suffix
+# endif /* __INT48_C_SUFFIX__ */
+#endif /* __INT48_TYPE__ */
+
+
+#ifdef __INT40_TYPE__
+# ifdef __INT40_C_SUFFIX__
+#  define INT40_C(v) __int_c(v, __INT40_C_SUFFIX__)
+#  define UINT40_C(v) __uint_c(v, __INT40_C_SUFFIX__)
+#  define __int32_c_suffix __INT40_C_SUFFIX__
+#  define __int16_c_suffix __INT40_C_SUFFIX__
+#  define __int8_c_suffix  __INT40_C_SUFFIX__
+# else
+#  define INT40_C(v) v
+#  define UINT40_C(v) v ## U
+#  undef __int32_c_suffix
+#  undef __int16_c_suffix
+#  undef  __int8_c_suffix
+# endif /* __INT40_C_SUFFIX__ */
+#endif /* __INT40_TYPE__ */
+
+
+#ifdef __INT32_TYPE__
+# ifdef __INT32_C_SUFFIX__
+#  define __int32_c_suffix __INT32_C_SUFFIX__
+#  define __int16_c_suffix __INT32_C_SUFFIX__
+#  define __int8_c_suffix  __INT32_C_SUFFIX__
+#else
+#  undef __int32_c_suffix
+#  undef __int16_c_suffix
+#  undef  __int8_c_suffix
+# endif /* __INT32_C_SUFFIX__ */
+#endif /* __INT32_TYPE__ */
+
+#ifdef __int_least32_t
+# ifdef __int32_c_suffix
+#  define INT32_C(v) __int_c(v, __int32_c_suffix)
+#  define UINT32_C(v) __uint_c(v, __int32_c_suffix)
+# else
+#  define INT32_C(v) v
+#  define UINT32_C(v) v ## U
+# endif /* __int32_c_suffix */
+#endif /* __int_least32_t */
+
+
+#ifdef __INT24_TYPE__
+# ifdef __INT24_C_SUFFIX__
+#  define INT24_C(v) __int_c(v, __INT24_C_SUFFIX__)
+#  define UINT24_C(v) __uint_c(v, __INT24_C_SUFFIX__)
+#  define __int16_c_suffix __INT24_C_SUFFIX__
+#  define __int8_c_suffix  __INT24_C_SUFFIX__
+# else
+#  define INT24_C(v) v
+#  define UINT24_C(v) v ## U
+#  undef __int16_c_suffix
+#  undef  __int8_c_suffix
+# endif /* __INT24_C_SUFFIX__ */
+#endif /* __INT24_TYPE__ */
+
+
+#ifdef __INT16_TYPE__
+# ifdef __INT16_C_SUFFIX__
+#  define __int16_c_suffix __INT16_C_SUFFIX__
+#  define __int8_c_suffix  __INT16_C_SUFFIX__
+#else
+#  undef __int16_c_suffix
+#  undef  __int8_c_suffix
+# endif /* __INT16_C_SUFFIX__ */
+#endif /* __INT16_TYPE__ */
+
+#ifdef __int_least16_t
+# ifdef __int16_c_suffix
+#  define INT16_C(v) __int_c(v, __int16_c_suffix)
+#  define UINT16_C(v) __uint_c(v, __int16_c_suffix)
+# else
+#  define INT16_C(v) v
+#  define UINT16_C(v) v ## U
+# endif /* __int16_c_suffix */
+#endif /* __int_least16_t */
+
+
+#ifdef __INT8_TYPE__
+# ifdef __INT8_C_SUFFIX__
+#  define __int8_c_suffix __INT8_C_SUFFIX__
+#else
+#  undef  __int8_c_suffix
+# endif /* __INT8_C_SUFFIX__ */
+#endif /* __INT8_TYPE__ */
+
+#ifdef __int_least8_t
+# ifdef __int8_c_suffix
+#  define INT8_C(v) __int_c(v, __int8_c_suffix)
+#  define UINT8_C(v) __uint_c(v, __int8_c_suffix)
+# else
+#  define INT8_C(v) v
+#  define UINT8_C(v) v ## U
+# endif /* __int8_c_suffix */
+#endif /* __int_least8_t */
+
+
+/* C99 7.18.2.1 Limits of exact-width integer types. 
+ * C99 7.18.2.2 Limits of minimum-width integer types.
+ * C99 7.18.2.3 Limits of fastest minimum-width integer types.
+ *
+ * The presence of limit macros are completely optional in C99.  This
+ * implementation defines limits for all of the types (exact- and
+ * minimum-width) that it defines above, using the limits of the minimum-width
+ * type for any types that do not have exact-width representations.
+ *
+ * As in the type definitions, this section takes an approach of
+ * successive-shrinking to determine which limits to use for the standard (8,
+ * 16, 32, 64) bit widths when they don't have exact representations. It is
+ * therefore important that the defintions be kept in order of decending
+ * widths.
+ *
+ * Note that C++ should not check __STDC_LIMIT_MACROS here, contrary to the
+ * claims of the C standard (see C++ 18.3.1p2, [cstdint.syn]).
+ */
+
+#ifdef __INT64_TYPE__
+# define INT64_MAX           INT64_C( 9223372036854775807)
+# define INT64_MIN         (-INT64_C( 9223372036854775807)-1)
+# define UINT64_MAX         UINT64_C(18446744073709551615)
+# define __INT_LEAST64_MIN   INT64_MIN
+# define __INT_LEAST64_MAX   INT64_MAX
+# define __UINT_LEAST64_MAX UINT64_MAX
+# define __INT_LEAST32_MIN   INT64_MIN
+# define __INT_LEAST32_MAX   INT64_MAX
+# define __UINT_LEAST32_MAX UINT64_MAX
+# define __INT_LEAST16_MIN   INT64_MIN
+# define __INT_LEAST16_MAX   INT64_MAX
+# define __UINT_LEAST16_MAX UINT64_MAX
+# define __INT_LEAST8_MIN    INT64_MIN
+# define __INT_LEAST8_MAX    INT64_MAX
+# define __UINT_LEAST8_MAX  UINT64_MAX
+#endif /* __INT64_TYPE__ */
+
+#ifdef __INT_LEAST64_MIN
+# define INT_LEAST64_MIN   __INT_LEAST64_MIN
+# define INT_LEAST64_MAX   __INT_LEAST64_MAX
+# define UINT_LEAST64_MAX __UINT_LEAST64_MAX
+# define INT_FAST64_MIN    __INT_LEAST64_MIN
+# define INT_FAST64_MAX    __INT_LEAST64_MAX
+# define UINT_FAST64_MAX  __UINT_LEAST64_MAX
+#endif /* __INT_LEAST64_MIN */
+
+
+#ifdef __INT56_TYPE__
+# define INT56_MAX           INT56_C(36028797018963967)
+# define INT56_MIN         (-INT56_C(36028797018963967)-1)
+# define UINT56_MAX         UINT56_C(72057594037927935)
+# define INT_LEAST56_MIN     INT56_MIN
+# define INT_LEAST56_MAX     INT56_MAX
+# define UINT_LEAST56_MAX   UINT56_MAX
+# define INT_FAST56_MIN      INT56_MIN
+# define INT_FAST56_MAX      INT56_MAX
+# define UINT_FAST56_MAX    UINT56_MAX
+# define __INT_LEAST32_MIN   INT56_MIN
+# define __INT_LEAST32_MAX   INT56_MAX
+# define __UINT_LEAST32_MAX UINT56_MAX
+# define __INT_LEAST16_MIN   INT56_MIN
+# define __INT_LEAST16_MAX   INT56_MAX
+# define __UINT_LEAST16_MAX UINT56_MAX
+# define __INT_LEAST8_MIN    INT56_MIN
+# define __INT_LEAST8_MAX    INT56_MAX
+# define __UINT_LEAST8_MAX  UINT56_MAX
+#endif /* __INT56_TYPE__ */
+
+
+#ifdef __INT48_TYPE__
+# define INT48_MAX           INT48_C(140737488355327)
+# define INT48_MIN         (-INT48_C(140737488355327)-1)
+# define UINT48_MAX         UINT48_C(281474976710655)
+# define INT_LEAST48_MIN     INT48_MIN
+# define INT_LEAST48_MAX     INT48_MAX
+# define UINT_LEAST48_MAX   UINT48_MAX
+# define INT_FAST48_MIN      INT48_MIN
+# define INT_FAST48_MAX      INT48_MAX
+# define UINT_FAST48_MAX    UINT48_MAX
+# define __INT_LEAST32_MIN   INT48_MIN
+# define __INT_LEAST32_MAX   INT48_MAX
+# define __UINT_LEAST32_MAX UINT48_MAX
+# define __INT_LEAST16_MIN   INT48_MIN
+# define __INT_LEAST16_MAX   INT48_MAX
+# define __UINT_LEAST16_MAX UINT48_MAX
+# define __INT_LEAST8_MIN    INT48_MIN
+# define __INT_LEAST8_MAX    INT48_MAX
+# define __UINT_LEAST8_MAX  UINT48_MAX
+#endif /* __INT48_TYPE__ */
+
+
+#ifdef __INT40_TYPE__
+# define INT40_MAX           INT40_C(549755813887)
+# define INT40_MIN         (-INT40_C(549755813887)-1)
+# define UINT40_MAX         UINT40_C(1099511627775)
+# define INT_LEAST40_MIN     INT40_MIN
+# define INT_LEAST40_MAX     INT40_MAX
+# define UINT_LEAST40_MAX   UINT40_MAX
+# define INT_FAST40_MIN      INT40_MIN
+# define INT_FAST40_MAX      INT40_MAX
+# define UINT_FAST40_MAX    UINT40_MAX
+# define __INT_LEAST32_MIN   INT40_MIN
+# define __INT_LEAST32_MAX   INT40_MAX
+# define __UINT_LEAST32_MAX UINT40_MAX
+# define __INT_LEAST16_MIN   INT40_MIN
+# define __INT_LEAST16_MAX   INT40_MAX
+# define __UINT_LEAST16_MAX UINT40_MAX
+# define __INT_LEAST8_MIN    INT40_MIN
+# define __INT_LEAST8_MAX    INT40_MAX
+# define __UINT_LEAST8_MAX  UINT40_MAX
+#endif /* __INT40_TYPE__ */
+
+
+#ifdef __INT32_TYPE__
+# define INT32_MAX           INT32_C(2147483647)
+# define INT32_MIN         (-INT32_C(2147483647)-1)
+# define UINT32_MAX         UINT32_C(4294967295)
+# define __INT_LEAST32_MIN   INT32_MIN
+# define __INT_LEAST32_MAX   INT32_MAX
+# define __UINT_LEAST32_MAX UINT32_MAX
+# define __INT_LEAST16_MIN   INT32_MIN
+# define __INT_LEAST16_MAX   INT32_MAX
+# define __UINT_LEAST16_MAX UINT32_MAX
+# define __INT_LEAST8_MIN    INT32_MIN
+# define __INT_LEAST8_MAX    INT32_MAX
+# define __UINT_LEAST8_MAX  UINT32_MAX
+#endif /* __INT32_TYPE__ */
+
+#ifdef __INT_LEAST32_MIN
+# define INT_LEAST32_MIN   __INT_LEAST32_MIN
+# define INT_LEAST32_MAX   __INT_LEAST32_MAX
+# define UINT_LEAST32_MAX __UINT_LEAST32_MAX
+# define INT_FAST32_MIN    __INT_LEAST32_MIN
+# define INT_FAST32_MAX    __INT_LEAST32_MAX
+# define UINT_FAST32_MAX  __UINT_LEAST32_MAX
+#endif /* __INT_LEAST32_MIN */
+
+
+#ifdef __INT24_TYPE__
+# define INT24_MAX           INT24_C(8388607)
+# define INT24_MIN         (-INT24_C(8388607)-1)
+# define UINT24_MAX         UINT24_C(16777215)
+# define INT_LEAST24_MIN     INT24_MIN
+# define INT_LEAST24_MAX     INT24_MAX
+# define UINT_LEAST24_MAX   UINT24_MAX
+# define INT_FAST24_MIN      INT24_MIN
+# define INT_FAST24_MAX      INT24_MAX
+# define UINT_FAST24_MAX    UINT24_MAX
+# define __INT_LEAST16_MIN   INT24_MIN
+# define __INT_LEAST16_MAX   INT24_MAX
+# define __UINT_LEAST16_MAX UINT24_MAX
+# define __INT_LEAST8_MIN    INT24_MIN
+# define __INT_LEAST8_MAX    INT24_MAX
+# define __UINT_LEAST8_MAX  UINT24_MAX
+#endif /* __INT24_TYPE__ */
+
+
+#ifdef __INT16_TYPE__
+#define INT16_MAX            INT16_C(32767)
+#define INT16_MIN          (-INT16_C(32767)-1)
+#define UINT16_MAX          UINT16_C(65535)
+# define __INT_LEAST16_MIN   INT16_MIN
+# define __INT_LEAST16_MAX   INT16_MAX
+# define __UINT_LEAST16_MAX UINT16_MAX
+# define __INT_LEAST8_MIN    INT16_MIN
+# define __INT_LEAST8_MAX    INT16_MAX
+# define __UINT_LEAST8_MAX  UINT16_MAX
+#endif /* __INT16_TYPE__ */
+
+#ifdef __INT_LEAST16_MIN
+# define INT_LEAST16_MIN   __INT_LEAST16_MIN
+# define INT_LEAST16_MAX   __INT_LEAST16_MAX
+# define UINT_LEAST16_MAX __UINT_LEAST16_MAX
+# define INT_FAST16_MIN    __INT_LEAST16_MIN
+# define INT_FAST16_MAX    __INT_LEAST16_MAX
+# define UINT_FAST16_MAX  __UINT_LEAST16_MAX
+#endif /* __INT_LEAST16_MIN */
+
+
+#ifdef __INT8_TYPE__
+# define INT8_MAX            INT8_C(127)
+# define INT8_MIN          (-INT8_C(127)-1)
+# define UINT8_MAX          UINT8_C(255)
+# define __INT_LEAST8_MIN    INT8_MIN
+# define __INT_LEAST8_MAX    INT8_MAX
+# define __UINT_LEAST8_MAX  UINT8_MAX
+#endif /* __INT8_TYPE__ */
+
+#ifdef __INT_LEAST8_MIN
+# define INT_LEAST8_MIN   __INT_LEAST8_MIN
+# define INT_LEAST8_MAX   __INT_LEAST8_MAX
+# define UINT_LEAST8_MAX __UINT_LEAST8_MAX
+# define INT_FAST8_MIN    __INT_LEAST8_MIN
+# define INT_FAST8_MAX    __INT_LEAST8_MAX
+# define UINT_FAST8_MAX  __UINT_LEAST8_MAX
+#endif /* __INT_LEAST8_MIN */
+
+/* C99 7.18.2.4 Limits of integer types capable of holding object pointers. */
+/* C99 7.18.3 Limits of other integer types. */
+#define  __INTN_MIN(n) __stdint_join3( INT, n, _MIN)
+#define  __INTN_MAX(n) __stdint_join3( INT, n, _MAX)
+#define __UINTN_MAX(n) __stdint_join3(UINT, n, _MAX)
+
+#define  INTPTR_MIN  __INTN_MIN(__INTPTR_WIDTH__)
+#define  INTPTR_MAX  __INTN_MAX(__INTPTR_WIDTH__)
+#define UINTPTR_MAX __UINTN_MAX(__INTPTR_WIDTH__)
+#define PTRDIFF_MIN  __INTN_MIN(__PTRDIFF_WIDTH__)
+#define PTRDIFF_MAX  __INTN_MAX(__PTRDIFF_WIDTH__)
+#define    SIZE_MAX __UINTN_MAX(__SIZE_WIDTH__)
+
+/* C99 7.18.2.5 Limits of greatest-width integer types. */
+#define INTMAX_MIN   __INTN_MIN(__INTMAX_WIDTH__)
+#define INTMAX_MAX   __INTN_MAX(__INTMAX_WIDTH__)
+#define UINTMAX_MAX __UINTN_MAX(__INTMAX_WIDTH__)
+
+/* C99 7.18.3 Limits of other integer types. */
+#define SIG_ATOMIC_MIN __INTN_MIN(__SIG_ATOMIC_WIDTH__)
+#define SIG_ATOMIC_MAX __INTN_MAX(__SIG_ATOMIC_WIDTH__)
+#define WINT_MIN       __INTN_MIN(__WINT_WIDTH__)
+#define WINT_MAX       __INTN_MAX(__WINT_WIDTH__)
+
+/* FIXME: if we ever support a target with unsigned wchar_t, this should be
+ * 0 .. Max.
+ */
+#ifndef WCHAR_MAX
+#define WCHAR_MAX __INTN_MAX(__WCHAR_WIDTH__)
+#endif
+#ifndef WCHAR_MIN
+#define WCHAR_MIN __INTN_MIN(__WCHAR_WIDTH__)
+#endif
+
+/* 7.18.4.2 Macros for greatest-width integer constants. */
+#define  __INTN_C(n, v) __stdint_join3( INT, n, _C(v))
+#define __UINTN_C(n, v) __stdint_join3(UINT, n, _C(v))
+
+#define INTMAX_C(v)   __INTN_C(__INTMAX_WIDTH__, v)
+#define UINTMAX_C(v) __UINTN_C(__INTMAX_WIDTH__, v)
+
+#endif /* __STDC_HOSTED__ */
+#endif /* __CLANG_STDINT_H */
diff --git a/lib/Headers/tgmath.h b/lib/Headers/tgmath.h
new file mode 100644
index 0000000..e1a0023
--- /dev/null
+++ b/lib/Headers/tgmath.h
@@ -0,0 +1,1358 @@
+/*===---- tgmath.h - Standard header for type generic math ----------------===*\
+ *
+ * Copyright (c) 2009 Howard Hinnant
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+\*===----------------------------------------------------------------------===*/
+
+#ifndef __TGMATH_H
+#define __TGMATH_H
+
+/* C99 7.22 Type-generic math <tgmath.h>. */
+#include <math.h>
+
+/* C++ handles type genericity with overloading in math.h. */
+#ifndef __cplusplus
+#include <complex.h>
+
+#define _TG_ATTRSp __attribute__((__overloadable__))
+#define _TG_ATTRS __attribute__((__overloadable__, __always_inline__))
+
+// promotion
+
+typedef void _Argument_type_is_not_arithmetic;
+static _Argument_type_is_not_arithmetic __tg_promote(...)
+  __attribute__((__unavailable__,__overloadable__));
+static double               _TG_ATTRSp __tg_promote(int);
+static double               _TG_ATTRSp __tg_promote(unsigned int);
+static double               _TG_ATTRSp __tg_promote(long);
+static double               _TG_ATTRSp __tg_promote(unsigned long);
+static double               _TG_ATTRSp __tg_promote(long long);
+static double               _TG_ATTRSp __tg_promote(unsigned long long);
+static float                _TG_ATTRSp __tg_promote(float);
+static double               _TG_ATTRSp __tg_promote(double);
+static long double          _TG_ATTRSp __tg_promote(long double);
+static float _Complex       _TG_ATTRSp __tg_promote(float _Complex);
+static double _Complex      _TG_ATTRSp __tg_promote(double _Complex);
+static long double _Complex _TG_ATTRSp __tg_promote(long double _Complex);
+
+#define __tg_promote1(__x)           (__typeof__(__tg_promote(__x)))
+#define __tg_promote2(__x, __y)      (__typeof__(__tg_promote(__x) + \
+                                                 __tg_promote(__y)))
+#define __tg_promote3(__x, __y, __z) (__typeof__(__tg_promote(__x) + \
+                                                 __tg_promote(__y) + \
+                                                 __tg_promote(__z)))
+
+// acos
+
+static float
+    _TG_ATTRS
+    __tg_acos(float __x) {return acosf(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_acos(double __x) {return acos(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_acos(long double __x) {return acosl(__x);}
+
+static float _Complex
+    _TG_ATTRS
+    __tg_acos(float _Complex __x) {return cacosf(__x);}
+
+static double _Complex
+    _TG_ATTRS
+    __tg_acos(double _Complex __x) {return cacos(__x);}
+
+static long double _Complex
+    _TG_ATTRS
+    __tg_acos(long double _Complex __x) {return cacosl(__x);}
+
+#undef acos
+#define acos(__x) __tg_acos(__tg_promote1((__x))(__x))
+
+// asin
+
+static float
+    _TG_ATTRS
+    __tg_asin(float __x) {return asinf(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_asin(double __x) {return asin(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_asin(long double __x) {return asinl(__x);}
+
+static float _Complex
+    _TG_ATTRS
+    __tg_asin(float _Complex __x) {return casinf(__x);}
+
+static double _Complex
+    _TG_ATTRS
+    __tg_asin(double _Complex __x) {return casin(__x);}
+
+static long double _Complex
+    _TG_ATTRS
+    __tg_asin(long double _Complex __x) {return casinl(__x);}
+
+#undef asin
+#define asin(__x) __tg_asin(__tg_promote1((__x))(__x))
+
+// atan
+
+static float
+    _TG_ATTRS
+    __tg_atan(float __x) {return atanf(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_atan(double __x) {return atan(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_atan(long double __x) {return atanl(__x);}
+
+static float _Complex
+    _TG_ATTRS
+    __tg_atan(float _Complex __x) {return catanf(__x);}
+
+static double _Complex
+    _TG_ATTRS
+    __tg_atan(double _Complex __x) {return catan(__x);}
+
+static long double _Complex
+    _TG_ATTRS
+    __tg_atan(long double _Complex __x) {return catanl(__x);}
+
+#undef atan
+#define atan(__x) __tg_atan(__tg_promote1((__x))(__x))
+
+// acosh
+
+static float
+    _TG_ATTRS
+    __tg_acosh(float __x) {return acoshf(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_acosh(double __x) {return acosh(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_acosh(long double __x) {return acoshl(__x);}
+
+static float _Complex
+    _TG_ATTRS
+    __tg_acosh(float _Complex __x) {return cacoshf(__x);}
+
+static double _Complex
+    _TG_ATTRS
+    __tg_acosh(double _Complex __x) {return cacosh(__x);}
+
+static long double _Complex
+    _TG_ATTRS
+    __tg_acosh(long double _Complex __x) {return cacoshl(__x);}
+
+#undef acosh
+#define acosh(__x) __tg_acosh(__tg_promote1((__x))(__x))
+
+// asinh
+
+static float
+    _TG_ATTRS
+    __tg_asinh(float __x) {return asinhf(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_asinh(double __x) {return asinh(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_asinh(long double __x) {return asinhl(__x);}
+
+static float _Complex
+    _TG_ATTRS
+    __tg_asinh(float _Complex __x) {return casinhf(__x);}
+
+static double _Complex
+    _TG_ATTRS
+    __tg_asinh(double _Complex __x) {return casinh(__x);}
+
+static long double _Complex
+    _TG_ATTRS
+    __tg_asinh(long double _Complex __x) {return casinhl(__x);}
+
+#undef asinh
+#define asinh(__x) __tg_asinh(__tg_promote1((__x))(__x))
+
+// atanh
+
+static float
+    _TG_ATTRS
+    __tg_atanh(float __x) {return atanhf(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_atanh(double __x) {return atanh(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_atanh(long double __x) {return atanhl(__x);}
+
+static float _Complex
+    _TG_ATTRS
+    __tg_atanh(float _Complex __x) {return catanhf(__x);}
+
+static double _Complex
+    _TG_ATTRS
+    __tg_atanh(double _Complex __x) {return catanh(__x);}
+
+static long double _Complex
+    _TG_ATTRS
+    __tg_atanh(long double _Complex __x) {return catanhl(__x);}
+
+#undef atanh
+#define atanh(__x) __tg_atanh(__tg_promote1((__x))(__x))
+
+// cos
+
+static float
+    _TG_ATTRS
+    __tg_cos(float __x) {return cosf(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_cos(double __x) {return cos(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_cos(long double __x) {return cosl(__x);}
+
+static float _Complex
+    _TG_ATTRS
+    __tg_cos(float _Complex __x) {return ccosf(__x);}
+
+static double _Complex
+    _TG_ATTRS
+    __tg_cos(double _Complex __x) {return ccos(__x);}
+
+static long double _Complex
+    _TG_ATTRS
+    __tg_cos(long double _Complex __x) {return ccosl(__x);}
+
+#undef cos
+#define cos(__x) __tg_cos(__tg_promote1((__x))(__x))
+
+// sin
+
+static float
+    _TG_ATTRS
+    __tg_sin(float __x) {return sinf(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_sin(double __x) {return sin(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_sin(long double __x) {return sinl(__x);}
+
+static float _Complex
+    _TG_ATTRS
+    __tg_sin(float _Complex __x) {return csinf(__x);}
+
+static double _Complex
+    _TG_ATTRS
+    __tg_sin(double _Complex __x) {return csin(__x);}
+
+static long double _Complex
+    _TG_ATTRS
+    __tg_sin(long double _Complex __x) {return csinl(__x);}
+
+#undef sin
+#define sin(__x) __tg_sin(__tg_promote1((__x))(__x))
+
+// tan
+
+static float
+    _TG_ATTRS
+    __tg_tan(float __x) {return tanf(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_tan(double __x) {return tan(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_tan(long double __x) {return tanl(__x);}
+
+static float _Complex
+    _TG_ATTRS
+    __tg_tan(float _Complex __x) {return ctanf(__x);}
+
+static double _Complex
+    _TG_ATTRS
+    __tg_tan(double _Complex __x) {return ctan(__x);}
+
+static long double _Complex
+    _TG_ATTRS
+    __tg_tan(long double _Complex __x) {return ctanl(__x);}
+
+#undef tan
+#define tan(__x) __tg_tan(__tg_promote1((__x))(__x))
+
+// cosh
+
+static float
+    _TG_ATTRS
+    __tg_cosh(float __x) {return coshf(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_cosh(double __x) {return cosh(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_cosh(long double __x) {return coshl(__x);}
+
+static float _Complex
+    _TG_ATTRS
+    __tg_cosh(float _Complex __x) {return ccoshf(__x);}
+
+static double _Complex
+    _TG_ATTRS
+    __tg_cosh(double _Complex __x) {return ccosh(__x);}
+
+static long double _Complex
+    _TG_ATTRS
+    __tg_cosh(long double _Complex __x) {return ccoshl(__x);}
+
+#undef cosh
+#define cosh(__x) __tg_cosh(__tg_promote1((__x))(__x))
+
+// sinh
+
+static float
+    _TG_ATTRS
+    __tg_sinh(float __x) {return sinhf(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_sinh(double __x) {return sinh(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_sinh(long double __x) {return sinhl(__x);}
+
+static float _Complex
+    _TG_ATTRS
+    __tg_sinh(float _Complex __x) {return csinhf(__x);}
+
+static double _Complex
+    _TG_ATTRS
+    __tg_sinh(double _Complex __x) {return csinh(__x);}
+
+static long double _Complex
+    _TG_ATTRS
+    __tg_sinh(long double _Complex __x) {return csinhl(__x);}
+
+#undef sinh
+#define sinh(__x) __tg_sinh(__tg_promote1((__x))(__x))
+
+// tanh
+
+static float
+    _TG_ATTRS
+    __tg_tanh(float __x) {return tanhf(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_tanh(double __x) {return tanh(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_tanh(long double __x) {return tanhl(__x);}
+
+static float _Complex
+    _TG_ATTRS
+    __tg_tanh(float _Complex __x) {return ctanhf(__x);}
+
+static double _Complex
+    _TG_ATTRS
+    __tg_tanh(double _Complex __x) {return ctanh(__x);}
+
+static long double _Complex
+    _TG_ATTRS
+    __tg_tanh(long double _Complex __x) {return ctanhl(__x);}
+
+#undef tanh
+#define tanh(__x) __tg_tanh(__tg_promote1((__x))(__x))
+
+// exp
+
+static float
+    _TG_ATTRS
+    __tg_exp(float __x) {return expf(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_exp(double __x) {return exp(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_exp(long double __x) {return expl(__x);}
+
+static float _Complex
+    _TG_ATTRS
+    __tg_exp(float _Complex __x) {return cexpf(__x);}
+
+static double _Complex
+    _TG_ATTRS
+    __tg_exp(double _Complex __x) {return cexp(__x);}
+
+static long double _Complex
+    _TG_ATTRS
+    __tg_exp(long double _Complex __x) {return cexpl(__x);}
+
+#undef exp
+#define exp(__x) __tg_exp(__tg_promote1((__x))(__x))
+
+// log
+
+static float
+    _TG_ATTRS
+    __tg_log(float __x) {return logf(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_log(double __x) {return log(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_log(long double __x) {return logl(__x);}
+
+static float _Complex
+    _TG_ATTRS
+    __tg_log(float _Complex __x) {return clogf(__x);}
+
+static double _Complex
+    _TG_ATTRS
+    __tg_log(double _Complex __x) {return clog(__x);}
+
+static long double _Complex
+    _TG_ATTRS
+    __tg_log(long double _Complex __x) {return clogl(__x);}
+
+#undef log
+#define log(__x) __tg_log(__tg_promote1((__x))(__x))
+
+// pow
+
+static float
+    _TG_ATTRS
+    __tg_pow(float __x, float __y) {return powf(__x, __y);}
+
+static double
+    _TG_ATTRS
+    __tg_pow(double __x, double __y) {return pow(__x, __y);}
+
+static long double
+    _TG_ATTRS
+    __tg_pow(long double __x, long double __y) {return powl(__x, __y);}
+
+static float _Complex
+    _TG_ATTRS
+    __tg_pow(float _Complex __x, float _Complex __y) {return cpowf(__x, __y);}
+
+static double _Complex
+    _TG_ATTRS
+    __tg_pow(double _Complex __x, double _Complex __y) {return cpow(__x, __y);}
+
+static long double _Complex
+    _TG_ATTRS
+    __tg_pow(long double _Complex __x, long double _Complex __y) 
+    {return cpowl(__x, __y);}
+
+#undef pow
+#define pow(__x, __y) __tg_pow(__tg_promote2((__x), (__y))(__x), \
+                               __tg_promote2((__x), (__y))(__y))
+
+// sqrt
+
+static float
+    _TG_ATTRS
+    __tg_sqrt(float __x) {return sqrtf(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_sqrt(double __x) {return sqrt(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_sqrt(long double __x) {return sqrtl(__x);}
+
+static float _Complex
+    _TG_ATTRS
+    __tg_sqrt(float _Complex __x) {return csqrtf(__x);}
+
+static double _Complex
+    _TG_ATTRS
+    __tg_sqrt(double _Complex __x) {return csqrt(__x);}
+
+static long double _Complex
+    _TG_ATTRS
+    __tg_sqrt(long double _Complex __x) {return csqrtl(__x);}
+
+#undef sqrt
+#define sqrt(__x) __tg_sqrt(__tg_promote1((__x))(__x))
+
+// fabs
+
+static float
+    _TG_ATTRS
+    __tg_fabs(float __x) {return fabsf(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_fabs(double __x) {return fabs(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_fabs(long double __x) {return fabsl(__x);}
+
+static float _Complex
+    _TG_ATTRS
+    __tg_fabs(float _Complex __x) {return cabsf(__x);}
+
+static double _Complex
+    _TG_ATTRS
+    __tg_fabs(double _Complex __x) {return cabs(__x);}
+
+static long double _Complex
+    _TG_ATTRS
+    __tg_fabs(long double _Complex __x) {return cabsl(__x);}
+
+#undef fabs
+#define fabs(__x) __tg_fabs(__tg_promote1((__x))(__x))
+
+// atan2
+
+static float
+    _TG_ATTRS
+    __tg_atan2(float __x, float __y) {return atan2f(__x, __y);}
+
+static double
+    _TG_ATTRS
+    __tg_atan2(double __x, double __y) {return atan2(__x, __y);}
+
+static long double
+    _TG_ATTRS
+    __tg_atan2(long double __x, long double __y) {return atan2l(__x, __y);}
+
+#undef atan2
+#define atan2(__x, __y) __tg_atan2(__tg_promote2((__x), (__y))(__x), \
+                                   __tg_promote2((__x), (__y))(__y))
+
+// cbrt
+
+static float
+    _TG_ATTRS
+    __tg_cbrt(float __x) {return cbrtf(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_cbrt(double __x) {return cbrt(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_cbrt(long double __x) {return cbrtl(__x);}
+
+#undef cbrt
+#define cbrt(__x) __tg_cbrt(__tg_promote1((__x))(__x))
+
+// ceil
+
+static float
+    _TG_ATTRS
+    __tg_ceil(float __x) {return ceilf(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_ceil(double __x) {return ceil(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_ceil(long double __x) {return ceill(__x);}
+
+#undef ceil
+#define ceil(__x) __tg_ceil(__tg_promote1((__x))(__x))
+
+// copysign
+
+static float
+    _TG_ATTRS
+    __tg_copysign(float __x, float __y) {return copysignf(__x, __y);}
+
+static double
+    _TG_ATTRS
+    __tg_copysign(double __x, double __y) {return copysign(__x, __y);}
+
+static long double
+    _TG_ATTRS
+    __tg_copysign(long double __x, long double __y) {return copysignl(__x, __y);}
+
+#undef copysign
+#define copysign(__x, __y) __tg_copysign(__tg_promote2((__x), (__y))(__x), \
+                                         __tg_promote2((__x), (__y))(__y))
+
+// erf
+
+static float
+    _TG_ATTRS
+    __tg_erf(float __x) {return erff(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_erf(double __x) {return erf(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_erf(long double __x) {return erfl(__x);}
+
+#undef erf
+#define erf(__x) __tg_erf(__tg_promote1((__x))(__x))
+
+// erfc
+
+static float
+    _TG_ATTRS
+    __tg_erfc(float __x) {return erfcf(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_erfc(double __x) {return erfc(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_erfc(long double __x) {return erfcl(__x);}
+
+#undef erfc
+#define erfc(__x) __tg_erfc(__tg_promote1((__x))(__x))
+
+// exp2
+
+static float
+    _TG_ATTRS
+    __tg_exp2(float __x) {return exp2f(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_exp2(double __x) {return exp2(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_exp2(long double __x) {return exp2l(__x);}
+
+#undef exp2
+#define exp2(__x) __tg_exp2(__tg_promote1((__x))(__x))
+
+// expm1
+
+static float
+    _TG_ATTRS
+    __tg_expm1(float __x) {return expm1f(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_expm1(double __x) {return expm1(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_expm1(long double __x) {return expm1l(__x);}
+
+#undef expm1
+#define expm1(__x) __tg_expm1(__tg_promote1((__x))(__x))
+
+// fdim
+
+static float
+    _TG_ATTRS
+    __tg_fdim(float __x, float __y) {return fdimf(__x, __y);}
+
+static double
+    _TG_ATTRS
+    __tg_fdim(double __x, double __y) {return fdim(__x, __y);}
+
+static long double
+    _TG_ATTRS
+    __tg_fdim(long double __x, long double __y) {return fdiml(__x, __y);}
+
+#undef fdim
+#define fdim(__x, __y) __tg_fdim(__tg_promote2((__x), (__y))(__x), \
+                                 __tg_promote2((__x), (__y))(__y))
+
+// floor
+
+static float
+    _TG_ATTRS
+    __tg_floor(float __x) {return floorf(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_floor(double __x) {return floor(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_floor(long double __x) {return floorl(__x);}
+
+#undef floor
+#define floor(__x) __tg_floor(__tg_promote1((__x))(__x))
+
+// fma
+
+static float
+    _TG_ATTRS
+    __tg_fma(float __x, float __y, float __z)
+    {return fmaf(__x, __y, __z);}
+
+static double
+    _TG_ATTRS
+    __tg_fma(double __x, double __y, double __z)
+    {return fma(__x, __y, __z);}
+
+static long double
+    _TG_ATTRS
+    __tg_fma(long double __x,long double __y, long double __z)
+    {return fmal(__x, __y, __z);}
+
+#undef fma
+#define fma(__x, __y, __z)                                \
+        __tg_fma(__tg_promote3((__x), (__y), (__z))(__x), \
+                 __tg_promote3((__x), (__y), (__z))(__y), \
+                 __tg_promote3((__x), (__y), (__z))(__z))
+
+// fmax
+
+static float
+    _TG_ATTRS
+    __tg_fmax(float __x, float __y) {return fmaxf(__x, __y);}
+
+static double
+    _TG_ATTRS
+    __tg_fmax(double __x, double __y) {return fmax(__x, __y);}
+
+static long double
+    _TG_ATTRS
+    __tg_fmax(long double __x, long double __y) {return fmaxl(__x, __y);}
+
+#undef fmax
+#define fmax(__x, __y) __tg_fmax(__tg_promote2((__x), (__y))(__x), \
+                                 __tg_promote2((__x), (__y))(__y))
+
+// fmin
+
+static float
+    _TG_ATTRS
+    __tg_fmin(float __x, float __y) {return fminf(__x, __y);}
+
+static double
+    _TG_ATTRS
+    __tg_fmin(double __x, double __y) {return fmin(__x, __y);}
+
+static long double
+    _TG_ATTRS
+    __tg_fmin(long double __x, long double __y) {return fminl(__x, __y);}
+
+#undef fmin
+#define fmin(__x, __y) __tg_fmin(__tg_promote2((__x), (__y))(__x), \
+                                 __tg_promote2((__x), (__y))(__y))
+
+// fmod
+
+static float
+    _TG_ATTRS
+    __tg_fmod(float __x, float __y) {return fmodf(__x, __y);}
+
+static double
+    _TG_ATTRS
+    __tg_fmod(double __x, double __y) {return fmod(__x, __y);}
+
+static long double
+    _TG_ATTRS
+    __tg_fmod(long double __x, long double __y) {return fmodl(__x, __y);}
+
+#undef fmod
+#define fmod(__x, __y) __tg_fmod(__tg_promote2((__x), (__y))(__x), \
+                                 __tg_promote2((__x), (__y))(__y))
+
+// frexp
+
+static float
+    _TG_ATTRS
+    __tg_frexp(float __x, int* __y) {return frexpf(__x, __y);}
+
+static double
+    _TG_ATTRS
+    __tg_frexp(double __x, int* __y) {return frexp(__x, __y);}
+
+static long double
+    _TG_ATTRS
+    __tg_frexp(long double __x, int* __y) {return frexpl(__x, __y);}
+
+#undef frexp
+#define frexp(__x, __y) __tg_frexp(__tg_promote1((__x))(__x), __y)
+
+// hypot
+
+static float
+    _TG_ATTRS
+    __tg_hypot(float __x, float __y) {return hypotf(__x, __y);}
+
+static double
+    _TG_ATTRS
+    __tg_hypot(double __x, double __y) {return hypot(__x, __y);}
+
+static long double
+    _TG_ATTRS
+    __tg_hypot(long double __x, long double __y) {return hypotl(__x, __y);}
+
+#undef hypot
+#define hypot(__x, __y) __tg_hypot(__tg_promote2((__x), (__y))(__x), \
+                                   __tg_promote2((__x), (__y))(__y))
+
+// ilogb
+
+static int
+    _TG_ATTRS
+    __tg_ilogb(float __x) {return ilogbf(__x);}
+
+static int
+    _TG_ATTRS
+    __tg_ilogb(double __x) {return ilogb(__x);}
+
+static int
+    _TG_ATTRS
+    __tg_ilogb(long double __x) {return ilogbl(__x);}
+
+#undef ilogb
+#define ilogb(__x) __tg_ilogb(__tg_promote1((__x))(__x))
+
+// ldexp
+
+static float
+    _TG_ATTRS
+    __tg_ldexp(float __x, int __y) {return ldexpf(__x, __y);}
+
+static double
+    _TG_ATTRS
+    __tg_ldexp(double __x, int __y) {return ldexp(__x, __y);}
+
+static long double
+    _TG_ATTRS
+    __tg_ldexp(long double __x, int __y) {return ldexpl(__x, __y);}
+
+#undef ldexp
+#define ldexp(__x, __y) __tg_ldexp(__tg_promote1((__x))(__x), __y)
+
+// lgamma
+
+static float
+    _TG_ATTRS
+    __tg_lgamma(float __x) {return lgammaf(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_lgamma(double __x) {return lgamma(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_lgamma(long double __x) {return lgammal(__x);}
+
+#undef lgamma
+#define lgamma(__x) __tg_lgamma(__tg_promote1((__x))(__x))
+
+// llrint
+
+static long long
+    _TG_ATTRS
+    __tg_llrint(float __x) {return llrintf(__x);}
+
+static long long
+    _TG_ATTRS
+    __tg_llrint(double __x) {return llrint(__x);}
+
+static long long
+    _TG_ATTRS
+    __tg_llrint(long double __x) {return llrintl(__x);}
+
+#undef llrint
+#define llrint(__x) __tg_llrint(__tg_promote1((__x))(__x))
+
+// llround
+
+static long long
+    _TG_ATTRS
+    __tg_llround(float __x) {return llroundf(__x);}
+
+static long long
+    _TG_ATTRS
+    __tg_llround(double __x) {return llround(__x);}
+
+static long long
+    _TG_ATTRS
+    __tg_llround(long double __x) {return llroundl(__x);}
+
+#undef llround
+#define llround(__x) __tg_llround(__tg_promote1((__x))(__x))
+
+// log10
+
+static float
+    _TG_ATTRS
+    __tg_log10(float __x) {return log10f(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_log10(double __x) {return log10(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_log10(long double __x) {return log10l(__x);}
+
+#undef log10
+#define log10(__x) __tg_log10(__tg_promote1((__x))(__x))
+
+// log1p
+
+static float
+    _TG_ATTRS
+    __tg_log1p(float __x) {return log1pf(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_log1p(double __x) {return log1p(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_log1p(long double __x) {return log1pl(__x);}
+
+#undef log1p
+#define log1p(__x) __tg_log1p(__tg_promote1((__x))(__x))
+
+// log2
+
+static float
+    _TG_ATTRS
+    __tg_log2(float __x) {return log2f(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_log2(double __x) {return log2(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_log2(long double __x) {return log2l(__x);}
+
+#undef log2
+#define log2(__x) __tg_log2(__tg_promote1((__x))(__x))
+
+// lrint
+
+static long
+    _TG_ATTRS
+    __tg_lrint(float __x) {return lrintf(__x);}
+
+static long
+    _TG_ATTRS
+    __tg_lrint(double __x) {return lrint(__x);}
+
+static long
+    _TG_ATTRS
+    __tg_lrint(long double __x) {return lrintl(__x);}
+
+#undef lrint
+#define lrint(__x) __tg_lrint(__tg_promote1((__x))(__x))
+
+// lround
+
+static long
+    _TG_ATTRS
+    __tg_lround(float __x) {return lroundf(__x);}
+
+static long
+    _TG_ATTRS
+    __tg_lround(double __x) {return lround(__x);}
+
+static long
+    _TG_ATTRS
+    __tg_lround(long double __x) {return lroundl(__x);}
+
+#undef lround
+#define lround(__x) __tg_lround(__tg_promote1((__x))(__x))
+
+// nearbyint
+
+static float
+    _TG_ATTRS
+    __tg_nearbyint(float __x) {return nearbyintf(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_nearbyint(double __x) {return nearbyint(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_nearbyint(long double __x) {return nearbyintl(__x);}
+
+#undef nearbyint
+#define nearbyint(__x) __tg_nearbyint(__tg_promote1((__x))(__x))
+
+// nextafter
+
+static float
+    _TG_ATTRS
+    __tg_nextafter(float __x, float __y) {return nextafterf(__x, __y);}
+
+static double
+    _TG_ATTRS
+    __tg_nextafter(double __x, double __y) {return nextafter(__x, __y);}
+
+static long double
+    _TG_ATTRS
+    __tg_nextafter(long double __x, long double __y) {return nextafterl(__x, __y);}
+
+#undef nextafter
+#define nextafter(__x, __y) __tg_nextafter(__tg_promote2((__x), (__y))(__x), \
+                                           __tg_promote2((__x), (__y))(__y))
+
+// nexttoward
+
+static float
+    _TG_ATTRS
+    __tg_nexttoward(float __x, float __y) {return nexttowardf(__x, __y);}
+
+static double
+    _TG_ATTRS
+    __tg_nexttoward(double __x, double __y) {return nexttoward(__x, __y);}
+
+static long double
+    _TG_ATTRS
+    __tg_nexttoward(long double __x, long double __y) {return nexttowardl(__x, __y);}
+
+#undef nexttoward
+#define nexttoward(__x, __y) __tg_nexttoward(__tg_promote2((__x), (__y))(__x), \
+                                             __tg_promote2((__x), (__y))(__y))
+
+// remainder
+
+static float
+    _TG_ATTRS
+    __tg_remainder(float __x, float __y) {return remainderf(__x, __y);}
+
+static double
+    _TG_ATTRS
+    __tg_remainder(double __x, double __y) {return remainder(__x, __y);}
+
+static long double
+    _TG_ATTRS
+    __tg_remainder(long double __x, long double __y) {return remainderl(__x, __y);}
+
+#undef remainder
+#define remainder(__x, __y) __tg_remainder(__tg_promote2((__x), (__y))(__x), \
+                                           __tg_promote2((__x), (__y))(__y))
+
+// remquo
+
+static float
+    _TG_ATTRS
+    __tg_remquo(float __x, float __y, int* __z)
+    {return remquof(__x, __y, __z);}
+
+static double
+    _TG_ATTRS
+    __tg_remquo(double __x, double __y, int* __z)
+    {return remquo(__x, __y, __z);}
+
+static long double
+    _TG_ATTRS
+    __tg_remquo(long double __x,long double __y, int* __z)
+    {return remquol(__x, __y, __z);}
+
+#undef remquo
+#define remquo(__x, __y, __z)                         \
+        __tg_remquo(__tg_promote2((__x), (__y))(__x), \
+                    __tg_promote2((__x), (__y))(__y), \
+                    (__z))
+
+// rint
+
+static float
+    _TG_ATTRS
+    __tg_rint(float __x) {return rintf(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_rint(double __x) {return rint(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_rint(long double __x) {return rintl(__x);}
+
+#undef rint
+#define rint(__x) __tg_rint(__tg_promote1((__x))(__x))
+
+// round
+
+static float
+    _TG_ATTRS
+    __tg_round(float __x) {return roundf(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_round(double __x) {return round(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_round(long double __x) {return roundl(__x);}
+
+#undef round
+#define round(__x) __tg_round(__tg_promote1((__x))(__x))
+
+// scalbn
+
+static float
+    _TG_ATTRS
+    __tg_scalbn(float __x, int __y) {return scalbnf(__x, __y);}
+
+static double
+    _TG_ATTRS
+    __tg_scalbn(double __x, int __y) {return scalbn(__x, __y);}
+
+static long double
+    _TG_ATTRS
+    __tg_scalbn(long double __x, int __y) {return scalbnl(__x, __y);}
+
+#undef scalbn
+#define scalbn(__x, __y) __tg_scalbn(__tg_promote1((__x))(__x), __y)
+
+// scalbln
+
+static float
+    _TG_ATTRS
+    __tg_scalbln(float __x, long __y) {return scalblnf(__x, __y);}
+
+static double
+    _TG_ATTRS
+    __tg_scalbln(double __x, long __y) {return scalbln(__x, __y);}
+
+static long double
+    _TG_ATTRS
+    __tg_scalbln(long double __x, long __y) {return scalblnl(__x, __y);}
+
+#undef scalbln
+#define scalbln(__x, __y) __tg_scalbln(__tg_promote1((__x))(__x), __y)
+
+// tgamma
+
+static float
+    _TG_ATTRS
+    __tg_tgamma(float __x) {return tgammaf(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_tgamma(double __x) {return tgamma(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_tgamma(long double __x) {return tgammal(__x);}
+
+#undef tgamma
+#define tgamma(__x) __tg_tgamma(__tg_promote1((__x))(__x))
+
+// trunc
+
+static float
+    _TG_ATTRS
+    __tg_trunc(float __x) {return truncf(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_trunc(double __x) {return trunc(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_trunc(long double __x) {return truncl(__x);}
+
+#undef trunc
+#define trunc(__x) __tg_trunc(__tg_promote1((__x))(__x))
+
+// carg
+
+static float
+    _TG_ATTRS
+    __tg_carg(float __x) {return atan2f(0.F, __x);}
+
+static double
+    _TG_ATTRS
+    __tg_carg(double __x) {return atan2(0., __x);}
+
+static long double
+    _TG_ATTRS
+    __tg_carg(long double __x) {return atan2l(0.L, __x);}
+
+static float
+    _TG_ATTRS
+    __tg_carg(float _Complex __x) {return cargf(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_carg(double _Complex __x) {return carg(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_carg(long double _Complex __x) {return cargl(__x);}
+
+#undef carg
+#define carg(__x) __tg_carg(__tg_promote1((__x))(__x))
+
+// cimag
+
+static float
+    _TG_ATTRS
+    __tg_cimag(float __x) {return 0;}
+
+static double
+    _TG_ATTRS
+    __tg_cimag(double __x) {return 0;}
+
+static long double
+    _TG_ATTRS
+    __tg_cimag(long double __x) {return 0;}
+
+static float
+    _TG_ATTRS
+    __tg_cimag(float _Complex __x) {return cimagf(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_cimag(double _Complex __x) {return cimag(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_cimag(long double _Complex __x) {return cimagl(__x);}
+
+#undef cimag
+#define cimag(__x) __tg_cimag(__tg_promote1((__x))(__x))
+
+// conj
+
+static float _Complex
+    _TG_ATTRS
+    __tg_conj(float __x) {return __x;}
+
+static double _Complex
+    _TG_ATTRS
+    __tg_conj(double __x) {return __x;}
+
+static long double _Complex
+    _TG_ATTRS
+    __tg_conj(long double __x) {return __x;}
+
+static float _Complex
+    _TG_ATTRS
+    __tg_conj(float _Complex __x) {return conjf(__x);}
+
+static double _Complex
+    _TG_ATTRS
+    __tg_conj(double _Complex __x) {return conj(__x);}
+
+static long double _Complex
+    _TG_ATTRS
+    __tg_conj(long double _Complex __x) {return conjl(__x);}
+
+#undef conj
+#define conj(__x) __tg_conj(__tg_promote1((__x))(__x))
+
+// cproj
+
+static float _Complex
+    _TG_ATTRS
+    __tg_cproj(float __x) {return cprojf(__x);}
+
+static double _Complex
+    _TG_ATTRS
+    __tg_cproj(double __x) {return cproj(__x);}
+
+static long double _Complex
+    _TG_ATTRS
+    __tg_cproj(long double __x) {return cprojl(__x);}
+
+static float _Complex
+    _TG_ATTRS
+    __tg_cproj(float _Complex __x) {return cprojf(__x);}
+
+static double _Complex
+    _TG_ATTRS
+    __tg_cproj(double _Complex __x) {return cproj(__x);}
+
+static long double _Complex
+    _TG_ATTRS
+    __tg_cproj(long double _Complex __x) {return cprojl(__x);}
+
+#undef cproj
+#define cproj(__x) __tg_cproj(__tg_promote1((__x))(__x))
+
+// creal
+
+static float _Complex
+    _TG_ATTRS
+    __tg_creal(float __x) {return __x;}
+
+static double _Complex
+    _TG_ATTRS
+    __tg_creal(double __x) {return __x;}
+
+static long double _Complex
+    _TG_ATTRS
+    __tg_creal(long double __x) {return __x;}
+
+static float
+    _TG_ATTRS
+    __tg_creal(float _Complex __x) {return crealf(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_creal(double _Complex __x) {return creal(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_creal(long double _Complex __x) {return creall(__x);}
+
+#undef creal
+#define creal(__x) __tg_creal(__tg_promote1((__x))(__x))
+
+#undef _TG_ATTRSp
+#undef _TG_ATTRS
+
+#endif /* __cplusplus */
+#endif /* __TGMATH_H */
diff --git a/lib/Headers/tmmintrin.h b/lib/Headers/tmmintrin.h
new file mode 100644
index 0000000..07fea1c
--- /dev/null
+++ b/lib/Headers/tmmintrin.h
@@ -0,0 +1,218 @@
+/*===---- tmmintrin.h - SSSE3 intrinsics -----------------------------------===
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+ 
+#ifndef __TMMINTRIN_H
+#define __TMMINTRIN_H
+
+#ifndef __SSSE3__
+#error "SSSE3 instruction set not enabled"
+#else
+
+#include <pmmintrin.h>
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_abs_pi8(__m64 a)
+{
+    return (__m64)__builtin_ia32_pabsb((__v8qi)a);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_abs_epi8(__m128i a)
+{
+    return (__m128i)__builtin_ia32_pabsb128((__v16qi)a);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_abs_pi16(__m64 a)
+{
+    return (__m64)__builtin_ia32_pabsw((__v4hi)a);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_abs_epi16(__m128i a)
+{
+    return (__m128i)__builtin_ia32_pabsw128((__v8hi)a);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_abs_pi32(__m64 a)
+{
+    return (__m64)__builtin_ia32_pabsd((__v2si)a);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_abs_epi32(__m128i a)
+{
+    return (__m128i)__builtin_ia32_pabsd128((__v4si)a);
+}
+
+#define _mm_alignr_epi8(a, b, n) (__builtin_ia32_palignr128((a), (b), (n)))
+#define _mm_alignr_pi8(a, b, n) (__builtin_ia32_palignr((a), (b), (n)))
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_hadd_epi16(__m128i a, __m128i b)
+{
+    return (__m128i)__builtin_ia32_phaddw128((__v8hi)a, (__v8hi)b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_hadd_epi32(__m128i a, __m128i b)
+{
+    return (__m128i)__builtin_ia32_phaddd128((__v4si)a, (__v4si)b);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_hadd_pi16(__m64 a, __m64 b)
+{
+    return (__m64)__builtin_ia32_phaddw((__v4hi)a, (__v4hi)b);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_hadd_pi32(__m64 a, __m64 b)
+{
+    return (__m64)__builtin_ia32_phaddd((__v2si)a, (__v2si)b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_hadds_epi16(__m128i a, __m128i b)
+{
+    return (__m128i)__builtin_ia32_phaddsw128((__v8hi)a, (__v8hi)b);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_hadds_pi16(__m64 a, __m64 b)
+{
+    return (__m64)__builtin_ia32_phaddsw((__v4hi)a, (__v4hi)b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_hsub_epi16(__m128i a, __m128i b)
+{
+    return (__m128i)__builtin_ia32_phsubw128((__v8hi)a, (__v8hi)b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_hsub_epi32(__m128i a, __m128i b)
+{
+    return (__m128i)__builtin_ia32_phsubd128((__v4si)a, (__v4si)b);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_hsub_pi16(__m64 a, __m64 b)
+{
+    return (__m64)__builtin_ia32_phsubw((__v4hi)a, (__v4hi)b);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_hsub_pi32(__m64 a, __m64 b)
+{
+    return (__m64)__builtin_ia32_phsubd((__v2si)a, (__v2si)b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_hsubs_epi16(__m128i a, __m128i b)
+{
+    return (__m128i)__builtin_ia32_phsubsw128((__v8hi)a, (__v8hi)b);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_hsubs_pi16(__m64 a, __m64 b)
+{
+    return (__m64)__builtin_ia32_phsubsw((__v4hi)a, (__v4hi)b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_maddubs_epi16(__m128i a, __m128i b)
+{
+    return (__m128i)__builtin_ia32_pmaddubsw128((__v16qi)a, (__v16qi)b);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_maddubs_pi16(__m64 a, __m64 b)
+{
+    return (__m64)__builtin_ia32_pmaddubsw((__v8qi)a, (__v8qi)b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_mulhrs_epi16(__m128i a, __m128i b)
+{
+    return (__m128i)__builtin_ia32_pmulhrsw128((__v8hi)a, (__v8hi)b);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_mulhrs_pi16(__m64 a, __m64 b)
+{
+    return (__m64)__builtin_ia32_pmulhrsw((__v4hi)a, (__v4hi)b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_shuffle_epi8(__m128i a, __m128i b)
+{
+    return (__m128i)__builtin_ia32_pshufb128((__v16qi)a, (__v16qi)b);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_shuffle_pi8(__m64 a, __m64 b)
+{
+    return (__m64)__builtin_ia32_pshufb((__v8qi)a, (__v8qi)b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_sign_epi8(__m128i a, __m128i b)
+{
+    return (__m128i)__builtin_ia32_psignb128((__v16qi)a, (__v16qi)b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_sign_epi16(__m128i a, __m128i b)
+{
+    return (__m128i)__builtin_ia32_psignw128((__v8hi)a, (__v8hi)b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_sign_epi32(__m128i a, __m128i b)
+{
+    return (__m128i)__builtin_ia32_psignd128((__v4si)a, (__v4si)b);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_sign_pi8(__m64 a, __m64 b)
+{
+    return (__m64)__builtin_ia32_psignb((__v8qi)a, (__v8qi)b);  
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_sign_pi16(__m64 a, __m64 b)
+{
+    return (__m64)__builtin_ia32_psignw((__v4hi)a, (__v4hi)b);  
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_sign_pi32(__m64 a, __m64 b)
+{
+    return (__m64)__builtin_ia32_psignd((__v2si)a, (__v2si)b);
+}
+
+#endif /* __SSSE3__ */
+
+#endif /* __TMMINTRIN_H */
diff --git a/lib/Headers/varargs.h b/lib/Headers/varargs.h
new file mode 100644
index 0000000..b5477d0
--- /dev/null
+++ b/lib/Headers/varargs.h
@@ -0,0 +1,26 @@
+/*===---- varargs.h - Variable argument handling -------------------------------------===
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to deal
+* in the Software without restriction, including without limitation the rights
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in
+* all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+* THE SOFTWARE.
+*
+*===-----------------------------------------------------------------------===
+*/
+#ifndef __VARARGS_H
+#define __VARARGS_H
+  #error "Please use <stdarg.h> instead of <varargs.h>"
+#endif
diff --git a/lib/Headers/wmmintrin.h b/lib/Headers/wmmintrin.h
new file mode 100644
index 0000000..6b2e468
--- /dev/null
+++ b/lib/Headers/wmmintrin.h
@@ -0,0 +1,67 @@
+/*===---- wmmintrin.h - AES intrinsics ------------------------------------===
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#ifndef _WMMINTRIN_H
+#define _WMMINTRIN_H
+
+#if !defined (__AES__)
+# error "AES instructions not enabled"
+#else
+
+#include <smmintrin.h>
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_aesenc_si128(__m128i __V, __m128i __R)
+{
+  return (__m128i)__builtin_ia32_aesenc128(__V, __R);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_aesenclast_si128(__m128i __V, __m128i __R)
+{
+  return (__m128i)__builtin_ia32_aesenclast128(__V, __R);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_aesdec_si128(__m128i __V, __m128i __R)
+{
+  return (__m128i)__builtin_ia32_aesdec128(__V, __R);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_aesdeclast_si128(__m128i __V, __m128i __R)
+{
+  return (__m128i)__builtin_ia32_aesdeclast128(__V, __R);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_aesimc_si128(__m128i __V)
+{
+  return (__m128i)__builtin_ia32_aesimc128(__V);
+}
+
+#define _mm_aeskeygenassist_si128(C, R) \
+  __builtin_ia32_aeskeygenassist128((C), (R))
+
+#endif /* __AES__ */
+#endif /* _WMMINTRIN_H */
diff --git a/lib/Headers/xmmintrin.h b/lib/Headers/xmmintrin.h
new file mode 100644
index 0000000..4e313b2
--- /dev/null
+++ b/lib/Headers/xmmintrin.h
@@ -0,0 +1,917 @@
+/*===---- xmmintrin.h - SSE intrinsics -------------------------------------===
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+ 
+#ifndef __XMMINTRIN_H
+#define __XMMINTRIN_H
+ 
+#ifndef __SSE__
+#error "SSE instruction set not enabled"
+#else
+
+#include <mmintrin.h>
+
+typedef int __v4si __attribute__((__vector_size__(16)));
+typedef float __v4sf __attribute__((__vector_size__(16)));
+typedef float __m128 __attribute__((__vector_size__(16)));
+
+#include <mm_malloc.h>
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_add_ss(__m128 a, __m128 b)
+{
+  a[0] += b[0];
+  return a;
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_add_ps(__m128 a, __m128 b)
+{
+  return a + b;
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_sub_ss(__m128 a, __m128 b)
+{
+  a[0] -= b[0];
+  return a;
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_sub_ps(__m128 a, __m128 b)
+{
+  return a - b;
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_mul_ss(__m128 a, __m128 b)
+{
+  a[0] *= b[0];
+  return a;
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_mul_ps(__m128 a, __m128 b)
+{
+  return a * b;
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_div_ss(__m128 a, __m128 b)
+{
+  a[0] /= b[0];
+  return a;
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_div_ps(__m128 a, __m128 b)
+{
+  return a / b;
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_sqrt_ss(__m128 a)
+{
+  return __builtin_ia32_sqrtss(a);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_sqrt_ps(__m128 a)
+{
+  return __builtin_ia32_sqrtps(a);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_rcp_ss(__m128 a)
+{
+  return __builtin_ia32_rcpss(a);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_rcp_ps(__m128 a)
+{
+  return __builtin_ia32_rcpps(a);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_rsqrt_ss(__m128 a)
+{
+  return __builtin_ia32_rsqrtss(a);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_rsqrt_ps(__m128 a)
+{
+  return __builtin_ia32_rsqrtps(a);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_min_ss(__m128 a, __m128 b)
+{
+  return __builtin_ia32_minss(a, b);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_min_ps(__m128 a, __m128 b)
+{
+  return __builtin_ia32_minps(a, b);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_max_ss(__m128 a, __m128 b)
+{
+  return __builtin_ia32_maxss(a, b);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_max_ps(__m128 a, __m128 b)
+{
+  return __builtin_ia32_maxps(a, b);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_and_ps(__m128 a, __m128 b)
+{
+  return (__m128)((__v4si)a & (__v4si)b);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_andnot_ps(__m128 a, __m128 b)
+{
+  return (__m128)(~(__v4si)a & (__v4si)b);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_or_ps(__m128 a, __m128 b)
+{
+  return (__m128)((__v4si)a | (__v4si)b);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_xor_ps(__m128 a, __m128 b)
+{
+  return (__m128)((__v4si)a ^ (__v4si)b);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cmpeq_ss(__m128 a, __m128 b)
+{
+  return (__m128)__builtin_ia32_cmpss(a, b, 0);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cmpeq_ps(__m128 a, __m128 b)
+{
+  return (__m128)__builtin_ia32_cmpps(a, b, 0);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cmplt_ss(__m128 a, __m128 b)
+{
+  return (__m128)__builtin_ia32_cmpss(a, b, 1);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cmplt_ps(__m128 a, __m128 b)
+{
+  return (__m128)__builtin_ia32_cmpps(a, b, 1);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cmple_ss(__m128 a, __m128 b)
+{
+  return (__m128)__builtin_ia32_cmpss(a, b, 2);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cmple_ps(__m128 a, __m128 b)
+{
+  return (__m128)__builtin_ia32_cmpps(a, b, 2);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cmpgt_ss(__m128 a, __m128 b)
+{
+  return (__m128)__builtin_ia32_cmpss(b, a, 1);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cmpgt_ps(__m128 a, __m128 b)
+{
+  return (__m128)__builtin_ia32_cmpps(b, a, 1);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cmpge_ss(__m128 a, __m128 b)
+{
+  return (__m128)__builtin_ia32_cmpss(b, a, 2);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cmpge_ps(__m128 a, __m128 b)
+{
+  return (__m128)__builtin_ia32_cmpps(b, a, 2);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cmpneq_ss(__m128 a, __m128 b)
+{
+  return (__m128)__builtin_ia32_cmpss(a, b, 4);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cmpneq_ps(__m128 a, __m128 b)
+{
+  return (__m128)__builtin_ia32_cmpps(a, b, 4);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cmpnlt_ss(__m128 a, __m128 b)
+{
+  return (__m128)__builtin_ia32_cmpss(a, b, 5);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cmpnlt_ps(__m128 a, __m128 b)
+{
+  return (__m128)__builtin_ia32_cmpps(a, b, 5);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cmpnle_ss(__m128 a, __m128 b)
+{
+  return (__m128)__builtin_ia32_cmpss(a, b, 6);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cmpnle_ps(__m128 a, __m128 b)
+{
+  return (__m128)__builtin_ia32_cmpps(a, b, 6);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cmpngt_ss(__m128 a, __m128 b)
+{
+  return (__m128)__builtin_ia32_cmpss(b, a, 5);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cmpngt_ps(__m128 a, __m128 b)
+{
+  return (__m128)__builtin_ia32_cmpps(b, a, 5);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cmpnge_ss(__m128 a, __m128 b)
+{
+  return (__m128)__builtin_ia32_cmpss(b, a, 6);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cmpnge_ps(__m128 a, __m128 b)
+{
+  return (__m128)__builtin_ia32_cmpps(b, a, 6);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cmpord_ss(__m128 a, __m128 b)
+{
+  return (__m128)__builtin_ia32_cmpss(a, b, 7);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cmpord_ps(__m128 a, __m128 b)
+{
+  return (__m128)__builtin_ia32_cmpps(a, b, 7);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cmpunord_ss(__m128 a, __m128 b)
+{
+  return (__m128)__builtin_ia32_cmpss(a, b, 3);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cmpunord_ps(__m128 a, __m128 b)
+{
+  return (__m128)__builtin_ia32_cmpps(a, b, 3);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_comieq_ss(__m128 a, __m128 b)
+{
+  return __builtin_ia32_comieq(a, b);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_comilt_ss(__m128 a, __m128 b)
+{
+  return __builtin_ia32_comilt(a, b);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_comile_ss(__m128 a, __m128 b)
+{
+  return __builtin_ia32_comile(a, b);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_comigt_ss(__m128 a, __m128 b)
+{
+  return __builtin_ia32_comigt(a, b);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_comige_ss(__m128 a, __m128 b)
+{
+  return __builtin_ia32_comige(a, b);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_comineq_ss(__m128 a, __m128 b)
+{
+  return __builtin_ia32_comineq(a, b);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_ucomieq_ss(__m128 a, __m128 b)
+{
+  return __builtin_ia32_ucomieq(a, b);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_ucomilt_ss(__m128 a, __m128 b)
+{
+  return __builtin_ia32_ucomilt(a, b);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_ucomile_ss(__m128 a, __m128 b)
+{
+  return __builtin_ia32_ucomile(a, b);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_ucomigt_ss(__m128 a, __m128 b)
+{
+  return __builtin_ia32_ucomigt(a, b);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_ucomige_ss(__m128 a, __m128 b)
+{
+  return __builtin_ia32_ucomige(a, b);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_ucomineq_ss(__m128 a, __m128 b)
+{
+  return __builtin_ia32_ucomineq(a, b);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_cvtss_si32(__m128 a)
+{
+  return __builtin_ia32_cvtss2si(a);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_cvt_ss2si(__m128 a)
+{
+  return _mm_cvtss_si32(a);
+}
+
+#ifdef __x86_64__
+
+static __inline__ long long __attribute__((__always_inline__, __nodebug__))
+_mm_cvtss_si64(__m128 a)
+{
+  return __builtin_ia32_cvtss2si64(a);
+}
+
+#endif
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_cvtps_pi32(__m128 a)
+{
+  return (__m64)__builtin_ia32_cvtps2pi(a);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_cvttss_si32(__m128 a)
+{
+  return a[0];
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_cvtt_ss2si(__m128 a)
+{
+  return _mm_cvttss_si32(a);
+}
+
+static __inline__ long long __attribute__((__always_inline__, __nodebug__))
+_mm_cvttss_si64(__m128 a)
+{
+  return a[0];
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_cvttps_pi32(__m128 a)
+{
+  return (__m64)__builtin_ia32_cvttps2pi(a);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cvtsi32_ss(__m128 a, int b)
+{
+  a[0] = b;
+  return a;
+}
+
+#ifdef __x86_64__
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cvtsi64_ss(__m128 a, long long b)
+{
+  a[0] = b;
+  return a;
+}
+
+#endif
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cvtpi32_ps(__m128 a, __m64 b)
+{
+  return __builtin_ia32_cvtpi2ps(a, (__v2si)b);
+}
+
+static __inline__ float __attribute__((__always_inline__, __nodebug__))
+_mm_cvtss_f32(__m128 a)
+{
+  return a[0];
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_loadh_pi(__m128 a, const __m64 *p)
+{
+  __m128 b;
+  b[0] = *(float*)p;
+  b[1] = *((float*)p+1);
+  return __builtin_shufflevector(a, b, 0, 1, 4, 5);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_loadl_pi(__m128 a, const __m64 *p)
+{
+  __m128 b;
+  b[0] = *(float*)p;
+  b[1] = *((float*)p+1);
+  return __builtin_shufflevector(a, b, 4, 5, 2, 3);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_load_ss(const float *p)
+{
+  return (__m128){ *p, 0, 0, 0 };
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_load1_ps(const float *p)
+{
+  return (__m128){ *p, *p, *p, *p };
+}
+
+#define        _mm_load_ps1(p) _mm_load1_ps(p)
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_load_ps(const float *p)
+{
+  return *(__m128*)p;
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_loadu_ps(const float *p)
+{
+  return __builtin_ia32_loadups(p);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_loadr_ps(const float *p)
+{
+  __m128 a = _mm_load_ps(p);
+  return __builtin_shufflevector(a, a, 3, 2, 1, 0);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_set_ss(float w)
+{
+  return (__m128){ w, 0, 0, 0 };
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_set1_ps(float w)
+{
+  return (__m128){ w, w, w, w };
+}
+
+// Microsoft specific.
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_set_ps1(float w)
+{
+    return _mm_set1_ps(w);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_set_ps(float z, float y, float x, float w)
+{
+  return (__m128){ w, x, y, z };
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_setr_ps(float z, float y, float x, float w)
+{
+  return (__m128){ z, y, x, w };
+}
+
+static __inline__ __m128 __attribute__((__always_inline__))
+_mm_setzero_ps(void)
+{
+  return (__m128){ 0, 0, 0, 0 };
+}
+
+static __inline__ void __attribute__((__always_inline__))
+_mm_storeh_pi(__m64 *p, __m128 a)
+{
+  __builtin_ia32_storehps((__v2si *)p, a);
+}
+
+static __inline__ void __attribute__((__always_inline__))
+_mm_storel_pi(__m64 *p, __m128 a)
+{
+  __builtin_ia32_storelps((__v2si *)p, a);
+}
+
+static __inline__ void __attribute__((__always_inline__))
+_mm_store_ss(float *p, __m128 a)
+{
+  *p = a[0];
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_storeu_ps(float *p, __m128 a)
+{
+  __builtin_ia32_storeups(p, a);
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_store1_ps(float *p, __m128 a)
+{
+  a = __builtin_shufflevector(a, a, 0, 0, 0, 0);
+  _mm_storeu_ps(p, a);
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_store_ps(float *p, __m128 a)
+{
+  *(__m128 *)p = a;
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_storer_ps(float *p, __m128 a)
+{
+  a = __builtin_shufflevector(a, a, 3, 2, 1, 0);
+  _mm_store_ps(p, a);
+}
+
+#define _MM_HINT_T0 1
+#define _MM_HINT_T1 2
+#define _MM_HINT_T2 3
+#define _MM_HINT_NTA 0
+
+/* FIXME: We have to #define this because "sel" must be a constant integer, and 
+   Sema doesn't do any form of constant propagation yet. */
+
+#define _mm_prefetch(a, sel) (__builtin_prefetch((void *)a, 0, sel))
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_stream_pi(__m64 *p, __m64 a)
+{
+  __builtin_ia32_movntq(p, a);
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_stream_ps(float *p, __m128 a)
+{
+  __builtin_ia32_movntps(p, a);
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_sfence(void)
+{
+  __builtin_ia32_sfence();
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_extract_pi16(__m64 a, int n)
+{
+  __v4hi b = (__v4hi)a;
+  return (unsigned short)b[n & 3];
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_insert_pi16(__m64 a, int d, int n)
+{
+   __v4hi b = (__v4hi)a;
+   b[n & 3] = d;
+   return (__m64)b;
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_max_pi16(__m64 a, __m64 b)
+{
+  return (__m64)__builtin_ia32_pmaxsw((__v4hi)a, (__v4hi)b);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_max_pu8(__m64 a, __m64 b)
+{
+  return (__m64)__builtin_ia32_pmaxub((__v8qi)a, (__v8qi)b);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_min_pi16(__m64 a, __m64 b)
+{
+  return (__m64)__builtin_ia32_pminsw((__v4hi)a, (__v4hi)b);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_min_pu8(__m64 a, __m64 b)
+{
+  return (__m64)__builtin_ia32_pminub((__v8qi)a, (__v8qi)b);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_movemask_pi8(__m64 a)
+{
+  return __builtin_ia32_pmovmskb((__v8qi)a);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_mulhi_pu16(__m64 a, __m64 b)
+{
+  return (__m64)__builtin_ia32_pmulhuw((__v4hi)a, (__v4hi)b);  
+}
+
+#define _mm_shuffle_pi16(a, n) \
+  ((__m64)__builtin_shufflevector((__v4hi)(a), (__v4hi) {0}, \
+                                  (n) & 0x3, ((n) & 0xc) >> 2, \
+                                  ((n) & 0x30) >> 4, ((n) & 0xc0) >> 6))
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_maskmove_si64(__m64 d, __m64 n, char *p)
+{
+  __builtin_ia32_maskmovq((__v8qi)d, (__v8qi)n, p);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_avg_pu8(__m64 a, __m64 b)
+{
+  return (__m64)__builtin_ia32_pavgb((__v8qi)a, (__v8qi)b);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_avg_pu16(__m64 a, __m64 b)
+{
+  return (__m64)__builtin_ia32_pavgw((__v4hi)a, (__v4hi)b);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_sad_pu8(__m64 a, __m64 b)
+{
+  return (__m64)__builtin_ia32_psadbw((__v8qi)a, (__v8qi)b);
+}
+
+static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
+_mm_getcsr(void)
+{
+  return __builtin_ia32_stmxcsr();
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_setcsr(unsigned int i)
+{
+  __builtin_ia32_ldmxcsr(i);
+}
+
+#define _mm_shuffle_ps(a, b, mask) \
+        (__builtin_shufflevector(a, b, (mask) & 0x3, ((mask) & 0xc) >> 2, \
+                                 (((mask) & 0x30) >> 4) + 4, \
+                                 (((mask) & 0xc0) >> 6) + 4))
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_unpackhi_ps(__m128 a, __m128 b)
+{
+  return __builtin_shufflevector(a, b, 2, 6, 3, 7);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_unpacklo_ps(__m128 a, __m128 b)
+{
+  return __builtin_shufflevector(a, b, 0, 4, 1, 5);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_move_ss(__m128 a, __m128 b)
+{
+  return __builtin_shufflevector(a, b, 4, 1, 2, 3);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_movehl_ps(__m128 a, __m128 b)
+{
+  return __builtin_shufflevector(a, b, 6, 7, 2, 3);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_movelh_ps(__m128 a, __m128 b)
+{
+  return __builtin_shufflevector(a, b, 0, 1, 4, 5);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cvtpi16_ps(__m64 a)
+{
+  __m64 b, c;
+  __m128 r;
+
+  b = _mm_setzero_si64();
+  b = _mm_cmpgt_pi16(b, a);
+  c = _mm_unpackhi_pi16(a, b);  
+  r = _mm_setzero_ps();
+  r = _mm_cvtpi32_ps(r, c);
+  r = _mm_movelh_ps(r, r);
+  c = _mm_unpacklo_pi16(a, b);  
+  r = _mm_cvtpi32_ps(r, c);
+
+  return r;
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cvtpu16_ps(__m64 a)
+{
+  __m64 b, c;
+  __m128 r;
+
+  b = _mm_setzero_si64();
+  c = _mm_unpackhi_pi16(a, b);  
+  r = _mm_setzero_ps();
+  r = _mm_cvtpi32_ps(r, c);
+  r = _mm_movelh_ps(r, r);
+  c = _mm_unpacklo_pi16(a, b);  
+  r = _mm_cvtpi32_ps(r, c);
+
+  return r;
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cvtpi8_ps(__m64 a)
+{
+  __m64 b;
+  
+  b = _mm_setzero_si64();
+  b = _mm_cmpgt_pi8(b, a);
+  b = _mm_unpacklo_pi8(a, b);
+
+  return _mm_cvtpi16_ps(b);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cvtpu8_ps(__m64 a)
+{
+  __m64 b;
+  
+  b = _mm_setzero_si64();
+  b = _mm_unpacklo_pi8(a, b);
+
+  return _mm_cvtpi16_ps(b);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cvtpi32x2_ps(__m64 a, __m64 b)
+{
+  __m128 c;
+  
+  c = _mm_setzero_ps();  
+  c = _mm_cvtpi32_ps(c, b);
+  c = _mm_movelh_ps(c, c);
+
+  return _mm_cvtpi32_ps(c, a);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_cvtps_pi16(__m128 a)
+{
+  __m64 b, c;
+  
+  b = _mm_cvtps_pi32(a);
+  a = _mm_movehl_ps(a, a);
+  c = _mm_cvtps_pi32(a);
+  
+  return _mm_packs_pi16(b, c);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_cvtps_pi8(__m128 a)
+{
+  __m64 b, c;
+  
+  b = _mm_cvtps_pi16(a);
+  c = _mm_setzero_si64();
+  
+  return _mm_packs_pi16(b, c);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_movemask_ps(__m128 a)
+{
+  return __builtin_ia32_movmskps(a);
+}
+
+#define _MM_SHUFFLE(z, y, x, w) (((z) << 6) | ((y) << 4) | ((x) << 2) | (w))
+
+#define _MM_EXCEPT_INVALID    (0x0001)
+#define _MM_EXCEPT_DENORM     (0x0002)
+#define _MM_EXCEPT_DIV_ZERO   (0x0004)
+#define _MM_EXCEPT_OVERFLOW   (0x0008)
+#define _MM_EXCEPT_UNDERFLOW  (0x0010)
+#define _MM_EXCEPT_INEXACT    (0x0020)
+#define _MM_EXCEPT_MASK       (0x003f)
+
+#define _MM_MASK_INVALID      (0x0080)
+#define _MM_MASK_DENORM       (0x0100)
+#define _MM_MASK_DIV_ZERO     (0x0200)
+#define _MM_MASK_OVERFLOW     (0x0400)
+#define _MM_MASK_UNDERFLOW    (0x0800)
+#define _MM_MASK_INEXACT      (0x1000)
+#define _MM_MASK_MASK         (0x1f80)
+
+#define _MM_ROUND_NEAREST     (0x0000)
+#define _MM_ROUND_DOWN        (0x2000)
+#define _MM_ROUND_UP          (0x4000)
+#define _MM_ROUND_TOWARD_ZERO (0x6000)
+#define _MM_ROUND_MASK        (0x6000)
+
+#define _MM_FLUSH_ZERO_MASK   (0x8000)
+#define _MM_FLUSH_ZERO_ON     (0x8000)
+#define _MM_FLUSH_ZERO_OFF    (0x8000)
+
+#define _MM_GET_EXCEPTION_MASK() (_mm_getcsr() & _MM_MASK_MASK)
+#define _MM_GET_EXCEPTION_STATE() (_mm_getcsr() & _MM_EXCEPT_MASK)
+#define _MM_GET_FLUSH_ZERO_MODE() (_mm_getcsr() & _MM_FLUSH_ZERO_MASK)
+#define _MM_GET_ROUNDING_MODE() (_mm_getcsr() & _MM_ROUND_MASK)
+
+#define _MM_SET_EXCEPTION_MASK(x) (_mm_setcsr((_mm_getcsr() & ~_MM_MASK_MASK) | (x)))
+#define _MM_SET_EXCEPTION_STATE(x) (_mm_setcsr((_mm_getcsr() & ~_MM_EXCEPT_MASK) | (x)))
+#define _MM_SET_FLUSH_ZERO_MODE(x) (_mm_setcsr((_mm_getcsr() & ~_MM_FLUSH_ZERO_MASK) | (x)))
+#define _MM_SET_ROUNDING_MODE(x) (_mm_setcsr((_mm_getcsr() & ~_MM_ROUND_MASK) | (x)))
+
+#define _MM_TRANSPOSE4_PS(row0, row1, row2, row3) \
+do { \
+  __m128 tmp3, tmp2, tmp1, tmp0; \
+  tmp0 = _mm_unpacklo_ps((row0), (row1)); \
+  tmp2 = _mm_unpacklo_ps((row2), (row3)); \
+  tmp1 = _mm_unpackhi_ps((row0), (row1)); \
+  tmp3 = _mm_unpackhi_ps((row2), (row3)); \
+  (row0) = _mm_movelh_ps(tmp0, tmp2); \
+  (row1) = _mm_movehl_ps(tmp2, tmp0); \
+  (row2) = _mm_movelh_ps(tmp1, tmp3); \
+  (row3) = _mm_movehl_ps(tmp3, tmp1); \
+} while (0)
+
+/* Ugly hack for backwards-compatibility (compatible with gcc) */
+#ifdef __SSE2__
+#include <emmintrin.h>
+#endif
+
+#endif /* __SSE__ */
+
+#endif /* __XMMINTRIN_H */
diff --git a/lib/Index/ASTLocation.cpp b/lib/Index/ASTLocation.cpp
new file mode 100644
index 0000000..091bc78
--- /dev/null
+++ b/lib/Index/ASTLocation.cpp
@@ -0,0 +1,117 @@
+//===--- ASTLocation.cpp - A <Decl, Stmt> pair ------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  ASTLocation is Decl or a Stmt and its immediate Decl parent.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Index/ASTLocation.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/Stmt.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprObjC.h"
+using namespace clang;
+using namespace idx;
+
+static Decl *getDeclFromExpr(Stmt *E) {
+  if (DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
+    return RefExpr->getDecl();
+  if (MemberExpr *ME = dyn_cast<MemberExpr>(E))
+    return ME->getMemberDecl();
+  if (ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
+    return RE->getDecl();
+
+  if (CallExpr *CE = dyn_cast<CallExpr>(E))
+    return getDeclFromExpr(CE->getCallee());
+  if (CastExpr *CE = dyn_cast<CastExpr>(E))
+    return getDeclFromExpr(CE->getSubExpr());
+
+  return 0;
+}
+
+Decl *ASTLocation::getReferencedDecl() {
+  if (isInvalid())
+    return 0;
+
+  switch (getKind()) {
+  default: assert(0 && "Invalid Kind");
+  case N_Type:
+    return 0;
+  case N_Decl:
+    return D;
+  case N_NamedRef:
+    return NDRef.ND;
+  case N_Stmt:
+    return getDeclFromExpr(Stm);
+  }
+  
+  return 0;
+}
+
+SourceRange ASTLocation::getSourceRange() const {
+  if (isInvalid())
+    return SourceRange();
+
+  switch (getKind()) {
+  default: assert(0 && "Invalid Kind");
+    return SourceRange();
+  case N_Decl:
+    return D->getSourceRange();
+  case N_Stmt:
+    return Stm->getSourceRange();
+  case N_NamedRef:
+    return SourceRange(AsNamedRef().Loc, AsNamedRef().Loc);
+  case N_Type:
+    return AsTypeLoc().getSourceRange();
+  }
+  
+  return SourceRange();
+}
+
+void ASTLocation::print(llvm::raw_ostream &OS) const {
+  if (isInvalid()) {
+    OS << "<< Invalid ASTLocation >>\n";
+    return;
+  }
+  
+  ASTContext &Ctx = getParentDecl()->getASTContext();
+
+  switch (getKind()) {
+  case N_Decl:
+    OS << "[Decl: " << AsDecl()->getDeclKindName() << " ";
+    if (const NamedDecl *ND = dyn_cast<NamedDecl>(AsDecl()))
+      OS << ND;
+    break;
+
+  case N_Stmt:
+    OS << "[Stmt: " << AsStmt()->getStmtClassName() << " ";
+    AsStmt()->printPretty(OS, Ctx, 0, PrintingPolicy(Ctx.getLangOptions()));
+    break;
+    
+  case N_NamedRef:
+    OS << "[NamedRef: " << AsNamedRef().ND->getDeclKindName() << " ";
+    OS << AsNamedRef().ND;
+    break;
+    
+  case N_Type: {
+    QualType T = AsTypeLoc().getType();
+    OS << "[Type: " << T->getTypeClassName() << " " << T.getAsString();
+  }
+  }
+
+  OS << "] <";
+
+  SourceRange Range = getSourceRange();
+  SourceManager &SourceMgr = Ctx.getSourceManager();
+  Range.getBegin().print(OS, SourceMgr);
+  OS << ", ";
+  Range.getEnd().print(OS, SourceMgr);
+  OS << ">\n";
+}
diff --git a/lib/Index/ASTVisitor.h b/lib/Index/ASTVisitor.h
new file mode 100644
index 0000000..943c720
--- /dev/null
+++ b/lib/Index/ASTVisitor.h
@@ -0,0 +1,144 @@
+//===--- ASTVisitor.h - Visitor for an ASTContext ---------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the ASTVisitor interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_INDEX_ASTVISITOR_H
+#define LLVM_CLANG_INDEX_ASTVISITOR_H
+
+#include "clang/AST/DeclVisitor.h"
+#include "clang/AST/StmtVisitor.h"
+#include "clang/AST/TypeLocVisitor.h"
+
+namespace clang {
+
+namespace idx {
+
+/// \brief Traverses the full AST, both Decls and Stmts.
+template<typename ImplClass>
+class ASTVisitor : public DeclVisitor<ImplClass>,
+                   public StmtVisitor<ImplClass>,
+                   public TypeLocVisitor<ImplClass> {
+public:
+  ASTVisitor() : CurrentDecl(0) { }
+
+  Decl *CurrentDecl;
+
+  typedef ASTVisitor<ImplClass>  Base;
+  typedef DeclVisitor<ImplClass> BaseDeclVisitor;
+  typedef StmtVisitor<ImplClass> BaseStmtVisitor;
+  typedef TypeLocVisitor<ImplClass> BaseTypeLocVisitor;
+
+  using BaseStmtVisitor::Visit;
+
+  //===--------------------------------------------------------------------===//
+  // DeclVisitor
+  //===--------------------------------------------------------------------===//
+
+  void Visit(Decl *D) {
+    Decl *PrevDecl = CurrentDecl;
+    CurrentDecl = D;
+    BaseDeclVisitor::Visit(D);
+    CurrentDecl = PrevDecl;
+  }
+  
+  void VisitDeclaratorDecl(DeclaratorDecl *D) {
+    BaseDeclVisitor::VisitDeclaratorDecl(D);
+    if (TypeSourceInfo *TInfo = D->getTypeSourceInfo())
+      Visit(TInfo->getTypeLoc());
+  }
+
+  void VisitFunctionDecl(FunctionDecl *D) {
+    BaseDeclVisitor::VisitFunctionDecl(D);
+    if (D->isThisDeclarationADefinition())
+      Visit(D->getBody());
+  }
+
+  void VisitObjCMethodDecl(ObjCMethodDecl *D) {
+    BaseDeclVisitor::VisitObjCMethodDecl(D);
+    if (D->getBody())
+      Visit(D->getBody());
+  }
+
+  void VisitBlockDecl(BlockDecl *D) {
+    BaseDeclVisitor::VisitBlockDecl(D);
+    Visit(D->getBody());
+  }
+
+  void VisitVarDecl(VarDecl *D) {
+    BaseDeclVisitor::VisitVarDecl(D);
+    if (Expr *Init = D->getInit())
+      Visit(Init);
+  }
+
+  void VisitDecl(Decl *D) {
+    if (isa<FunctionDecl>(D) || isa<ObjCMethodDecl>(D) || isa<BlockDecl>(D))
+      return;
+
+    if (DeclContext *DC = dyn_cast<DeclContext>(D))
+      static_cast<ImplClass*>(this)->VisitDeclContext(DC);
+  }
+
+  void VisitDeclContext(DeclContext *DC) {
+    for (DeclContext::decl_iterator
+           I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I)
+      Visit(*I);
+  }
+
+  //===--------------------------------------------------------------------===//
+  // StmtVisitor
+  //===--------------------------------------------------------------------===//
+
+  void VisitDeclStmt(DeclStmt *Node) {
+    for (DeclStmt::decl_iterator
+           I = Node->decl_begin(), E = Node->decl_end(); I != E; ++I)
+      Visit(*I);
+  }
+
+  void VisitBlockExpr(BlockExpr *Node) {
+    // The BlockDecl is also visited by 'VisitDeclContext()'.  No need to visit it twice.
+  }
+
+  void VisitStmt(Stmt *Node) {
+    for (Stmt::child_iterator
+           I = Node->child_begin(), E = Node->child_end(); I != E; ++I)
+      if (*I)
+        Visit(*I);
+  }
+
+  //===--------------------------------------------------------------------===//
+  // TypeLocVisitor
+  //===--------------------------------------------------------------------===//
+  
+  void Visit(TypeLoc TL) {
+    for (; TL; TL = TL.getNextTypeLoc())
+      BaseTypeLocVisitor::Visit(TL);
+  }
+  
+  void VisitArrayLoc(ArrayTypeLoc TL) {
+    BaseTypeLocVisitor::VisitArrayTypeLoc(TL);
+    if (TL.getSizeExpr())
+      Visit(TL.getSizeExpr());
+  }
+  
+  void VisitFunctionTypeLoc(FunctionTypeLoc TL) {
+    BaseTypeLocVisitor::VisitFunctionTypeLoc(TL);
+    for (unsigned i = 0; i != TL.getNumArgs(); ++i)
+      Visit(TL.getArg(i));
+  }
+
+};
+
+} // namespace idx
+
+} // namespace clang
+
+#endif
diff --git a/lib/Index/Analyzer.cpp b/lib/Index/Analyzer.cpp
new file mode 100644
index 0000000..1354fe6
--- /dev/null
+++ b/lib/Index/Analyzer.cpp
@@ -0,0 +1,470 @@
+//===--- Analyzer.cpp - Analysis for indexing information -------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Analyzer interface.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Index/Analyzer.h"
+#include "clang/Index/Entity.h"
+#include "clang/Index/TranslationUnit.h"
+#include "clang/Index/Handlers.h"
+#include "clang/Index/ASTLocation.h"
+#include "clang/Index/GlobalSelector.h"
+#include "clang/Index/DeclReferenceMap.h"
+#include "clang/Index/SelectorMap.h"
+#include "clang/Index/IndexProvider.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/ExprObjC.h"
+#include "llvm/ADT/SmallSet.h"
+using namespace clang;
+using namespace idx;
+
+namespace  {
+
+//===----------------------------------------------------------------------===//
+// DeclEntityAnalyzer Implementation
+//===----------------------------------------------------------------------===//
+
+class DeclEntityAnalyzer : public TranslationUnitHandler {
+  Entity Ent;
+  TULocationHandler &TULocHandler;
+
+public:
+  DeclEntityAnalyzer(Entity ent, TULocationHandler &handler)
+    : Ent(ent), TULocHandler(handler) { }
+
+  virtual void Handle(TranslationUnit *TU) {
+    assert(TU && "Passed null translation unit");
+
+    Decl *D = Ent.getDecl(TU->getASTContext());
+    assert(D && "Couldn't resolve Entity");
+
+    for (Decl::redecl_iterator I = D->redecls_begin(),
+                               E = D->redecls_end(); I != E; ++I)
+      TULocHandler.Handle(TULocation(TU, ASTLocation(*I)));
+  }
+};
+
+//===----------------------------------------------------------------------===//
+// RefEntityAnalyzer Implementation
+//===----------------------------------------------------------------------===//
+
+class RefEntityAnalyzer : public TranslationUnitHandler {
+  Entity Ent;
+  TULocationHandler &TULocHandler;
+
+public:
+  RefEntityAnalyzer(Entity ent, TULocationHandler &handler)
+    : Ent(ent), TULocHandler(handler) { }
+
+  virtual void Handle(TranslationUnit *TU) {
+    assert(TU && "Passed null translation unit");
+
+    Decl *D = Ent.getDecl(TU->getASTContext());
+    assert(D && "Couldn't resolve Entity");
+    NamedDecl *ND = dyn_cast<NamedDecl>(D);
+    if (!ND)
+      return;
+
+    DeclReferenceMap &RefMap = TU->getDeclReferenceMap();
+    for (DeclReferenceMap::astlocation_iterator
+           I = RefMap.refs_begin(ND), E = RefMap.refs_end(ND); I != E; ++I)
+      TULocHandler.Handle(TULocation(TU, *I));
+  }
+};
+
+//===----------------------------------------------------------------------===//
+// RefSelectorAnalyzer Implementation
+//===----------------------------------------------------------------------===//
+
+/// \brief Accepts an ObjC method and finds all message expressions that this
+/// method may respond to.
+class RefSelectorAnalyzer : public TranslationUnitHandler {
+  Program &Prog;
+  TULocationHandler &TULocHandler;
+
+  // The original ObjCInterface associated with the method.
+  Entity IFaceEnt;
+  GlobalSelector GlobSel;
+  bool IsInstanceMethod;
+
+  /// \brief Super classes of the ObjCInterface.
+  typedef llvm::SmallSet<Entity, 16> EntitiesSetTy;
+  EntitiesSetTy HierarchyEntities;
+
+public:
+  RefSelectorAnalyzer(ObjCMethodDecl *MD,
+                      Program &prog, TULocationHandler &handler)
+    : Prog(prog), TULocHandler(handler) {
+    assert(MD);
+
+    // FIXME: Protocol methods.
+    assert(!isa<ObjCProtocolDecl>(MD->getDeclContext()) &&
+           "Protocol methods not supported yet");
+
+    ObjCInterfaceDecl *IFD = MD->getClassInterface();
+    assert(IFD);
+    IFaceEnt = Entity::get(IFD, Prog);
+    GlobSel = GlobalSelector::get(MD->getSelector(), Prog);
+    IsInstanceMethod = MD->isInstanceMethod();
+
+    for (ObjCInterfaceDecl *Cls = IFD->getSuperClass();
+           Cls; Cls = Cls->getSuperClass())
+      HierarchyEntities.insert(Entity::get(Cls, Prog));
+  }
+
+  virtual void Handle(TranslationUnit *TU) {
+    assert(TU && "Passed null translation unit");
+
+    ASTContext &Ctx = TU->getASTContext();
+    // Null means it doesn't exist in this translation unit.
+    ObjCInterfaceDecl *IFace =
+        cast_or_null<ObjCInterfaceDecl>(IFaceEnt.getDecl(Ctx));
+    Selector Sel = GlobSel.getSelector(Ctx);
+
+    SelectorMap &SelMap = TU->getSelectorMap();
+    for (SelectorMap::astlocation_iterator
+           I = SelMap.refs_begin(Sel), E = SelMap.refs_end(Sel); I != E; ++I) {
+      if (ValidReference(*I, IFace))
+        TULocHandler.Handle(TULocation(TU, *I));
+    }
+  }
+
+  /// \brief Determines whether the given message expression is likely to end
+  /// up at the given interface decl.
+  ///
+  /// It returns true "eagerly", meaning it will return false only if it can
+  /// "prove" statically that the interface cannot accept this message.
+  bool ValidReference(ASTLocation ASTLoc, ObjCInterfaceDecl *IFace) {
+    assert(ASTLoc.isStmt());
+
+    // FIXME: Finding @selector references should be through another Analyzer
+    // method, like FindSelectors.
+    if (isa<ObjCSelectorExpr>(ASTLoc.AsStmt()))
+      return false;
+
+    ObjCInterfaceDecl *MsgD = 0;
+    ObjCMessageExpr *Msg = cast<ObjCMessageExpr>(ASTLoc.AsStmt());
+
+    switch (Msg->getReceiverKind()) {
+    case ObjCMessageExpr::Instance: {
+      const ObjCObjectPointerType *OPT =
+          Msg->getInstanceReceiver()->getType()->getAsObjCInterfacePointerType();
+
+      // Can be anything! Accept it as a possibility..
+      if (!OPT || OPT->isObjCIdType() || OPT->isObjCQualifiedIdType())
+        return true;
+
+      // Expecting class method.
+      if (OPT->isObjCClassType() || OPT->isObjCQualifiedClassType())
+        return !IsInstanceMethod;
+
+      MsgD = OPT->getInterfaceDecl();
+      assert(MsgD);
+
+      // Should be an instance method.
+      if (!IsInstanceMethod)
+        return false;
+      break;
+    }
+
+    case ObjCMessageExpr::Class: {
+      // Expecting class method.
+      if (IsInstanceMethod)
+        return false;
+
+      MsgD = Msg->getClassReceiver()->getAs<ObjCInterfaceType>()->getDecl();
+      break;
+    }
+
+    case ObjCMessageExpr::SuperClass:
+      // Expecting class method.
+      if (IsInstanceMethod)
+        return false;
+
+      MsgD = Msg->getSuperType()->getAs<ObjCInterfaceType>()->getDecl();
+      break;
+
+    case ObjCMessageExpr::SuperInstance:
+      // Expecting instance method.
+      if (!IsInstanceMethod)
+        return false;
+
+      MsgD = Msg->getSuperType()->getAs<ObjCObjectPointerType>()
+                                                          ->getInterfaceDecl();
+      break;
+    }
+
+    assert(MsgD);
+
+    // Same interface ? We have a winner!
+    if (MsgD == IFace)
+      return true;
+
+    // If the message interface is a superclass of the original interface,
+    // accept this message as a possibility.
+    if (HierarchyEntities.count(Entity::get(MsgD, Prog)))
+      return true;
+
+    // If the message interface is a subclass of the original interface, accept
+    // the message unless there is a subclass in the hierarchy that will
+    // "steal" the message (thus the message "will go" to the subclass and not
+    /// the original interface).
+    if (IFace) {
+      Selector Sel = Msg->getSelector();
+      for (ObjCInterfaceDecl *Cls = MsgD; Cls; Cls = Cls->getSuperClass()) {
+        if (Cls == IFace)
+          return true;
+        if (Cls->getMethod(Sel, IsInstanceMethod))
+          return false;
+      }
+    }
+
+    // The interfaces are unrelated, don't accept the message.
+    return false;
+  }
+};
+
+//===----------------------------------------------------------------------===//
+// MessageAnalyzer Implementation
+//===----------------------------------------------------------------------===//
+
+/// \brief Accepts an ObjC message expression and finds all methods that may
+/// respond to it.
+class MessageAnalyzer : public TranslationUnitHandler {
+  Program &Prog;
+  TULocationHandler &TULocHandler;
+
+  // The ObjCInterface associated with the message. Can be null/invalid.
+  Entity MsgIFaceEnt;
+  GlobalSelector GlobSel;
+  bool CanBeInstanceMethod;
+  bool CanBeClassMethod;
+
+  /// \brief Super classes of the ObjCInterface.
+  typedef llvm::SmallSet<Entity, 16> EntitiesSetTy;
+  EntitiesSetTy HierarchyEntities;
+
+  /// \brief The interface in the message interface hierarchy that "intercepts"
+  /// the selector.
+  Entity ReceiverIFaceEnt;
+
+public:
+  MessageAnalyzer(ObjCMessageExpr *Msg,
+                  Program &prog, TULocationHandler &handler)
+    : Prog(prog), TULocHandler(handler),
+      CanBeInstanceMethod(false),
+      CanBeClassMethod(false) {
+
+    assert(Msg);
+
+    ObjCInterfaceDecl *MsgD = 0;
+
+    while (true) {
+      switch (Msg->getReceiverKind()) {
+      case ObjCMessageExpr::Instance: {
+        const ObjCObjectPointerType *OPT =
+          Msg->getInstanceReceiver()->getType()
+                                      ->getAsObjCInterfacePointerType();
+
+        if (!OPT || OPT->isObjCIdType() || OPT->isObjCQualifiedIdType()) {
+          CanBeInstanceMethod = CanBeClassMethod = true;
+          break;
+        }
+
+        if (OPT->isObjCClassType() || OPT->isObjCQualifiedClassType()) {
+          CanBeClassMethod = true;
+          break;
+        }
+
+        MsgD = OPT->getInterfaceDecl();
+        assert(MsgD);
+        CanBeInstanceMethod = true;
+        break;
+      }
+        
+      case ObjCMessageExpr::Class:
+        CanBeClassMethod = true;
+        MsgD = Msg->getClassReceiver()->getAs<ObjCInterfaceType>()->getDecl();
+        break;
+
+      case ObjCMessageExpr::SuperClass:
+        CanBeClassMethod = true;
+        MsgD = Msg->getSuperType()->getAs<ObjCInterfaceType>()->getDecl();
+        break;
+
+      case ObjCMessageExpr::SuperInstance:
+        CanBeInstanceMethod = true;
+        MsgD = Msg->getSuperType()->getAs<ObjCObjectPointerType>()
+                                                           ->getInterfaceDecl();
+        break;
+      }
+    }
+
+    assert(CanBeInstanceMethod || CanBeClassMethod);
+
+    Selector sel = Msg->getSelector();
+    assert(!sel.isNull());
+
+    MsgIFaceEnt = Entity::get(MsgD, Prog);
+    GlobSel = GlobalSelector::get(sel, Prog);
+
+    if (MsgD) {
+      for (ObjCInterfaceDecl *Cls = MsgD->getSuperClass();
+             Cls; Cls = Cls->getSuperClass())
+        HierarchyEntities.insert(Entity::get(Cls, Prog));
+
+      // Find the interface in the hierarchy that "receives" the message.
+      for (ObjCInterfaceDecl *Cls = MsgD; Cls; Cls = Cls->getSuperClass()) {
+        bool isReceiver = false;
+
+        ObjCInterfaceDecl::lookup_const_iterator Meth, MethEnd;
+        for (llvm::tie(Meth, MethEnd) = Cls->lookup(sel);
+               Meth != MethEnd; ++Meth) {
+          if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth))
+            if ((MD->isInstanceMethod() && CanBeInstanceMethod) ||
+                (MD->isClassMethod()    && CanBeClassMethod)) {
+              isReceiver = true;
+              break;
+            }
+        }
+
+        if (isReceiver) {
+          ReceiverIFaceEnt = Entity::get(Cls, Prog);
+          break;
+        }
+      }
+    }
+  }
+
+  virtual void Handle(TranslationUnit *TU) {
+    assert(TU && "Passed null translation unit");
+    ASTContext &Ctx = TU->getASTContext();
+
+    // Null means it doesn't exist in this translation unit or there was no
+    // interface that was determined to receive the original message.
+    ObjCInterfaceDecl *ReceiverIFace =
+        cast_or_null<ObjCInterfaceDecl>(ReceiverIFaceEnt.getDecl(Ctx));
+
+    // No subclass for the original receiver interface, so it remains the
+    // receiver.
+    if (ReceiverIFaceEnt.isValid() && ReceiverIFace == 0)
+      return;
+
+    // Null means it doesn't exist in this translation unit or there was no
+    // interface associated with the message in the first place.
+    ObjCInterfaceDecl *MsgIFace =
+        cast_or_null<ObjCInterfaceDecl>(MsgIFaceEnt.getDecl(Ctx));
+
+    Selector Sel = GlobSel.getSelector(Ctx);
+    SelectorMap &SelMap = TU->getSelectorMap();
+    for (SelectorMap::method_iterator
+           I = SelMap.methods_begin(Sel), E = SelMap.methods_end(Sel);
+           I != E; ++I) {
+      ObjCMethodDecl *D = *I;
+      if (ValidMethod(D, MsgIFace, ReceiverIFace)) {
+        for (ObjCMethodDecl::redecl_iterator
+               RI = D->redecls_begin(), RE = D->redecls_end(); RI != RE; ++RI)
+          TULocHandler.Handle(TULocation(TU, ASTLocation(*RI)));
+      }
+    }
+  }
+
+  /// \brief Determines whether the given method is likely to accept the
+  /// original message.
+  ///
+  /// It returns true "eagerly", meaning it will return false only if it can
+  /// "prove" statically that the method cannot accept the original message.
+  bool ValidMethod(ObjCMethodDecl *D, ObjCInterfaceDecl *MsgIFace,
+                   ObjCInterfaceDecl *ReceiverIFace) {
+    assert(D);
+
+    // FIXME: Protocol methods ?
+    if (isa<ObjCProtocolDecl>(D->getDeclContext()))
+      return false;
+
+    // No specific interface associated with the message. Can be anything.
+    if (MsgIFaceEnt.isInvalid())
+      return true;
+
+    if ((!CanBeInstanceMethod && D->isInstanceMethod()) ||
+        (!CanBeClassMethod    && D->isClassMethod()))
+      return false;
+
+    ObjCInterfaceDecl *IFace = D->getClassInterface();
+    assert(IFace);
+
+    // If the original message interface is the same or a superclass of the
+    // given interface, accept the method as a possibility.
+    if (MsgIFace && MsgIFace->isSuperClassOf(IFace))
+      return true;
+
+    if (ReceiverIFace) {
+      // The given interface, "overrides" the receiver.
+      if (ReceiverIFace->isSuperClassOf(IFace))
+        return true;
+    } else {
+      // No receiver was found for the original message.
+      assert(ReceiverIFaceEnt.isInvalid());
+
+      // If the original message interface is a subclass of the given interface,
+      // accept the message.
+      if (HierarchyEntities.count(Entity::get(IFace, Prog)))
+        return true;
+    }
+
+    // The interfaces are unrelated, or the receiver interface wasn't
+    // "overriden".
+    return false;
+  }
+};
+
+} // end anonymous namespace
+
+//===----------------------------------------------------------------------===//
+// Analyzer Implementation
+//===----------------------------------------------------------------------===//
+
+void Analyzer::FindDeclarations(Decl *D, TULocationHandler &Handler) {
+  assert(D && "Passed null declaration");
+  Entity Ent = Entity::get(D, Prog);
+  if (Ent.isInvalid())
+    return;
+
+  DeclEntityAnalyzer DEA(Ent, Handler);
+  Idxer.GetTranslationUnitsFor(Ent, DEA);
+}
+
+void Analyzer::FindReferences(Decl *D, TULocationHandler &Handler) {
+  assert(D && "Passed null declaration");
+  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
+    RefSelectorAnalyzer RSA(MD, Prog, Handler);
+    GlobalSelector Sel = GlobalSelector::get(MD->getSelector(), Prog);
+    Idxer.GetTranslationUnitsFor(Sel, RSA);
+    return;
+  }
+
+  Entity Ent = Entity::get(D, Prog);
+  if (Ent.isInvalid())
+    return;
+
+  RefEntityAnalyzer REA(Ent, Handler);
+  Idxer.GetTranslationUnitsFor(Ent, REA);
+}
+
+/// \brief Find methods that may respond to the given message and pass them
+/// to Handler.
+void Analyzer::FindObjCMethods(ObjCMessageExpr *Msg,
+                               TULocationHandler &Handler) {
+  assert(Msg);
+  MessageAnalyzer MsgAnalyz(Msg, Prog, Handler);
+  GlobalSelector GlobSel = GlobalSelector::get(Msg->getSelector(), Prog);
+  Idxer.GetTranslationUnitsFor(GlobSel, MsgAnalyz);
+}
diff --git a/lib/Index/Android.mk b/lib/Index/Android.mk
new file mode 100644
index 0000000..3c2dc66
--- /dev/null
+++ b/lib/Index/Android.mk
@@ -0,0 +1,31 @@
+LOCAL_PATH:= $(call my-dir)
+
+# For the host only
+# =====================================================
+include $(CLEAR_VARS)
+include $(CLEAR_TBLGEN_VARS)
+
+TBLGEN_TABLES :=    \
+    DiagnosticCommonKinds.inc 
+
+clang_index_SRC_FILES :=	\
+	ASTLocation.cpp	\
+	Analyzer.cpp	\
+	CallGraph.cpp	\
+	DeclReferenceMap.cpp	\
+	Entity.cpp	\
+	GlobalSelector.cpp	\
+	Handlers.cpp	\
+	IndexProvider.cpp	\
+	Indexer.cpp	\
+	Program.cpp	\
+	ResolveLocation.cpp	\
+	SelectorMap.cpp
+
+LOCAL_SRC_FILES := $(clang_index_SRC_FILES)
+
+LOCAL_MODULE:= libclangIndex
+
+include $(CLANG_HOST_BUILD_MK)
+include $(CLANG_TBLGEN_RULES_MK)
+include $(BUILD_HOST_STATIC_LIBRARY)
diff --git a/lib/Index/CMakeLists.txt b/lib/Index/CMakeLists.txt
new file mode 100644
index 0000000..4d67035
--- /dev/null
+++ b/lib/Index/CMakeLists.txt
@@ -0,0 +1,16 @@
+set(LLVM_NO_RTTI 1)
+
+add_clang_library(clangIndex
+  ASTLocation.cpp
+  Analyzer.cpp
+  CallGraph.cpp
+  DeclReferenceMap.cpp
+  Entity.cpp
+  GlobalSelector.cpp
+  Handlers.cpp
+  IndexProvider.cpp
+  Indexer.cpp
+  Program.cpp
+  ResolveLocation.cpp
+  SelectorMap.cpp
+  )
diff --git a/lib/Index/CallGraph.cpp b/lib/Index/CallGraph.cpp
new file mode 100644
index 0000000..6403319
--- /dev/null
+++ b/lib/Index/CallGraph.cpp
@@ -0,0 +1,150 @@
+//== CallGraph.cpp - Call graph building ------------------------*- C++ -*--==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defined the CallGraph and CGBuilder classes.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Index/CallGraph.h"
+
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/StmtVisitor.h"
+
+#include "llvm/Support/GraphWriter.h"
+
+using namespace clang;
+using namespace idx;
+
+namespace {
+class CGBuilder : public StmtVisitor<CGBuilder> {
+
+  CallGraph &G;
+  FunctionDecl *FD;
+
+  Entity CallerEnt;
+
+  CallGraphNode *CallerNode;
+
+public:
+  CGBuilder(CallGraph &g, FunctionDecl *fd, Entity E, CallGraphNode *N)
+    : G(g), FD(fd), CallerEnt(E), CallerNode(N) {}
+
+  void VisitStmt(Stmt *S) { VisitChildren(S); }
+
+  void VisitCallExpr(CallExpr *CE);
+
+  void VisitChildren(Stmt *S) {
+    for (Stmt::child_iterator I=S->child_begin(), E=S->child_end(); I != E;++I)
+      if (*I)
+        static_cast<CGBuilder*>(this)->Visit(*I);
+  }
+};
+}
+
+void CGBuilder::VisitCallExpr(CallExpr *CE) {
+  if (FunctionDecl *CalleeDecl = CE->getDirectCallee()) {
+    Entity Ent = Entity::get(CalleeDecl, G.getProgram());
+    CallGraphNode *CalleeNode = G.getOrInsertFunction(Ent);
+    CallerNode->addCallee(ASTLocation(FD, CE), CalleeNode);
+  }
+}
+
+CallGraph::CallGraph() : Root(0) {
+  ExternalCallingNode = getOrInsertFunction(Entity());
+}
+
+CallGraph::~CallGraph() {
+  if (!FunctionMap.empty()) {
+    for (FunctionMapTy::iterator I = FunctionMap.begin(), E = FunctionMap.end();
+        I != E; ++I)
+      delete I->second;
+    FunctionMap.clear();
+  }
+}
+
+void CallGraph::addTU(ASTContext& Ctx) {
+  DeclContext *DC = Ctx.getTranslationUnitDecl();
+  for (DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
+       I != E; ++I) {
+
+    if (FunctionDecl *FD = dyn_cast<FunctionDecl>(*I)) {
+      if (FD->isThisDeclarationADefinition()) {
+        // Set caller's ASTContext.
+        Entity Ent = Entity::get(FD, Prog);
+        CallGraphNode *Node = getOrInsertFunction(Ent);
+        CallerCtx[Node] = &Ctx;
+
+        // If this function has external linkage, anything could call it.
+        if (FD->isGlobal())
+          ExternalCallingNode->addCallee(idx::ASTLocation(), Node);
+
+        // Set root node to 'main' function.
+        if (FD->getNameAsString() == "main")
+          Root = Node;
+
+        CGBuilder builder(*this, FD, Ent, Node);
+        builder.Visit(FD->getBody());
+      }
+    }
+  }
+}
+
+CallGraphNode *CallGraph::getOrInsertFunction(Entity F) {
+  CallGraphNode *&Node = FunctionMap[F];
+  if (Node)
+    return Node;
+
+  return Node = new CallGraphNode(F);
+}
+
+Decl *CallGraph::getDecl(CallGraphNode *Node) {
+  // Get the function's context.
+  ASTContext *Ctx = CallerCtx[Node];
+
+  return Node->getDecl(*Ctx);
+}
+
+void CallGraph::print(llvm::raw_ostream &os) {
+  for (iterator I = begin(), E = end(); I != E; ++I) {
+    if (I->second->hasCallee()) {
+      os << "function: " << I->first.getPrintableName()
+         << " calls:\n";
+      for (CallGraphNode::iterator CI = I->second->begin(),
+             CE = I->second->end(); CI != CE; ++CI) {
+        os << "    " << CI->second->getName();
+      }
+      os << '\n';
+    }
+  }
+}
+
+void CallGraph::dump() {
+  print(llvm::errs());
+}
+
+void CallGraph::ViewCallGraph() const {
+  llvm::ViewGraph(*this, "CallGraph");
+}
+
+namespace llvm {
+
+template <>
+struct DOTGraphTraits<CallGraph> : public DefaultDOTGraphTraits {
+
+  DOTGraphTraits (bool isSimple=false) : DefaultDOTGraphTraits(isSimple) {}
+
+  static std::string getNodeLabel(const CallGraphNode *Node,
+                                  const CallGraph &CG) {
+    return Node->getName();
+
+  }
+
+};
+
+}
diff --git a/lib/Index/DeclReferenceMap.cpp b/lib/Index/DeclReferenceMap.cpp
new file mode 100644
index 0000000..d6e30ab
--- /dev/null
+++ b/lib/Index/DeclReferenceMap.cpp
@@ -0,0 +1,90 @@
+//===--- DeclReferenceMap.cpp - Map Decls to their references -------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  DeclReferenceMap creates a mapping from Decls to the ASTLocations that
+//  reference them.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Index/DeclReferenceMap.h"
+#include "clang/Index/ASTLocation.h"
+#include "ASTVisitor.h"
+using namespace clang;
+using namespace idx;
+
+namespace {
+
+class RefMapper : public ASTVisitor<RefMapper> {
+  DeclReferenceMap::MapTy &Map;
+
+public:
+  RefMapper(DeclReferenceMap::MapTy &map) : Map(map) { }
+
+  void VisitDeclRefExpr(DeclRefExpr *Node);
+  void VisitMemberExpr(MemberExpr *Node);
+  void VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node);
+  
+  void VisitTypedefTypeLoc(TypedefTypeLoc TL);
+  void VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL);
+};
+
+} // anonymous namespace
+
+//===----------------------------------------------------------------------===//
+// RefMapper Implementation
+//===----------------------------------------------------------------------===//
+
+void RefMapper::VisitDeclRefExpr(DeclRefExpr *Node) {
+  NamedDecl *PrimD = cast<NamedDecl>(Node->getDecl()->getCanonicalDecl());
+  Map.insert(std::make_pair(PrimD, ASTLocation(CurrentDecl, Node)));
+}
+
+void RefMapper::VisitMemberExpr(MemberExpr *Node) {
+  NamedDecl *PrimD = cast<NamedDecl>(Node->getMemberDecl()->getCanonicalDecl());
+  Map.insert(std::make_pair(PrimD, ASTLocation(CurrentDecl, Node)));
+}
+
+void RefMapper::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) {
+  Map.insert(std::make_pair(Node->getDecl(), ASTLocation(CurrentDecl, Node)));
+}
+
+void RefMapper::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
+  NamedDecl *ND = TL.getTypedefDecl();
+  Map.insert(std::make_pair(ND, ASTLocation(CurrentDecl, ND, TL.getNameLoc())));
+}
+
+void RefMapper::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
+  NamedDecl *ND = TL.getIFaceDecl();
+  Map.insert(std::make_pair(ND, ASTLocation(CurrentDecl, ND, TL.getNameLoc())));
+}
+
+//===----------------------------------------------------------------------===//
+// DeclReferenceMap Implementation
+//===----------------------------------------------------------------------===//
+
+DeclReferenceMap::DeclReferenceMap(ASTContext &Ctx) {
+  RefMapper(Map).Visit(Ctx.getTranslationUnitDecl());
+}
+
+DeclReferenceMap::astlocation_iterator
+DeclReferenceMap::refs_begin(NamedDecl *D) const {
+  NamedDecl *Prim = cast<NamedDecl>(D->getCanonicalDecl());
+  return astlocation_iterator(Map.lower_bound(Prim));
+}
+
+DeclReferenceMap::astlocation_iterator
+DeclReferenceMap::refs_end(NamedDecl *D) const {
+  NamedDecl *Prim = cast<NamedDecl>(D->getCanonicalDecl());
+  return astlocation_iterator(Map.upper_bound(Prim));
+}
+
+bool DeclReferenceMap::refs_empty(NamedDecl *D) const {
+  NamedDecl *Prim = cast<NamedDecl>(D->getCanonicalDecl());
+  return refs_begin(Prim) == refs_end(Prim);
+}
diff --git a/lib/Index/Entity.cpp b/lib/Index/Entity.cpp
new file mode 100644
index 0000000..cd9d277
--- /dev/null
+++ b/lib/Index/Entity.cpp
@@ -0,0 +1,223 @@
+//===--- Entity.cpp - Cross-translation-unit "token" for decls ------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  Entity is a ASTContext-independent way to refer to declarations that are
+//  visible across translation units.
+//
+//===----------------------------------------------------------------------===//
+
+#include "EntityImpl.h"
+#include "ProgramImpl.h"
+#include "clang/Index/Program.h"
+#include "clang/Index/GlobalSelector.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclVisitor.h"
+using namespace clang;
+using namespace idx;
+
+// FIXME: Entity is really really basic currently, mostly written to work
+// on variables and functions. Should support types and other decls eventually..
+
+
+//===----------------------------------------------------------------------===//
+// EntityGetter
+//===----------------------------------------------------------------------===//
+
+namespace clang {
+namespace idx {
+
+/// \brief Gets the Entity associated with a Decl.
+class EntityGetter : public DeclVisitor<EntityGetter, Entity> {
+  Program &Prog;
+  ProgramImpl &ProgImpl;
+
+public:
+  EntityGetter(Program &prog, ProgramImpl &progImpl)
+    : Prog(prog), ProgImpl(progImpl) { }
+
+  Entity VisitNamedDecl(NamedDecl *D);
+  Entity VisitVarDecl(VarDecl *D);
+  Entity VisitFunctionDecl(FunctionDecl *D);
+};
+
+}
+}
+
+Entity EntityGetter::VisitNamedDecl(NamedDecl *D) {
+  Entity Parent;
+  if (!D->getDeclContext()->isTranslationUnit()) {
+    Parent = Visit(cast<Decl>(D->getDeclContext()));
+    // FIXME: Anonymous structs ?
+    if (Parent.isInvalid())
+      return Entity();
+  }
+  if (Parent.isValid() && Parent.isInternalToTU())
+    return Entity(D);
+
+  // FIXME: Only works for DeclarationNames that are identifiers and selectors.
+  // Treats other DeclarationNames as internal Decls for now..
+
+  DeclarationName LocalName = D->getDeclName();
+  if (!LocalName)
+    return Entity(D);
+
+  DeclarationName GlobName;
+
+  if (IdentifierInfo *II = LocalName.getAsIdentifierInfo()) {
+    IdentifierInfo *GlobII = &ProgImpl.getIdents().get(II->getName());
+    GlobName = DeclarationName(GlobII);
+  } else {
+    Selector LocalSel = LocalName.getObjCSelector();
+
+    // Treats other DeclarationNames as internal Decls for now..
+    if (LocalSel.isNull())
+      return Entity(D);
+
+    Selector GlobSel =
+        (uintptr_t)GlobalSelector::get(LocalSel, Prog).getAsOpaquePtr();
+    GlobName = DeclarationName(GlobSel);
+  }
+
+  assert(GlobName);
+
+  unsigned IdNS = D->getIdentifierNamespace();
+
+  ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D);
+  bool isObjCInstanceMethod = MD && MD->isInstanceMethod();
+
+  llvm::FoldingSetNodeID ID;
+  EntityImpl::Profile(ID, Parent, GlobName, IdNS, isObjCInstanceMethod);
+
+  ProgramImpl::EntitySetTy &Entities = ProgImpl.getEntities();
+  void *InsertPos = 0;
+  if (EntityImpl *Ent = Entities.FindNodeOrInsertPos(ID, InsertPos))
+    return Entity(Ent);
+
+  void *Buf = ProgImpl.Allocate(sizeof(EntityImpl));
+  EntityImpl *New =
+      new (Buf) EntityImpl(Parent, GlobName, IdNS, isObjCInstanceMethod);
+  Entities.InsertNode(New, InsertPos);
+
+  return Entity(New);
+}
+
+Entity EntityGetter::VisitVarDecl(VarDecl *D) {
+  // If it's static it cannot be referred to by another translation unit.
+  if (D->getStorageClass() == VarDecl::Static)
+    return Entity(D);
+
+  return VisitNamedDecl(D);
+}
+
+Entity EntityGetter::VisitFunctionDecl(FunctionDecl *D) {
+  // If it's static it cannot be refered to by another translation unit.
+  if (D->getStorageClass() == FunctionDecl::Static)
+    return Entity(D);
+
+  return VisitNamedDecl(D);
+}
+
+//===----------------------------------------------------------------------===//
+// EntityImpl Implementation
+//===----------------------------------------------------------------------===//
+
+Decl *EntityImpl::getDecl(ASTContext &AST) {
+  DeclContext *DC =
+    Parent.isInvalid() ? AST.getTranslationUnitDecl()
+                       : cast<DeclContext>(Parent.getDecl(AST));
+  if (!DC)
+    return 0; // Couldn't get the parent context.
+
+  DeclarationName LocalName;
+
+  if (IdentifierInfo *GlobII = Name.getAsIdentifierInfo()) {
+    IdentifierInfo &II = AST.Idents.get(GlobII->getName());
+    LocalName = DeclarationName(&II);
+  } else {
+    Selector GlobSel = Name.getObjCSelector();
+    assert(!GlobSel.isNull() && "A not handled yet declaration name");
+    GlobalSelector GSel =
+        GlobalSelector::getFromOpaquePtr(GlobSel.getAsOpaquePtr());
+    LocalName = GSel.getSelector(AST);
+  }
+
+  assert(LocalName);
+
+  DeclContext::lookup_result Res = DC->lookup(LocalName);
+  for (DeclContext::lookup_iterator I = Res.first, E = Res.second; I!=E; ++I) {
+    Decl *D = *I;
+    if (D->getIdentifierNamespace() == IdNS) {
+      if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
+        if (MD->isInstanceMethod() == IsObjCInstanceMethod)
+          return MD;
+      } else
+        return D;
+    }
+  }
+
+  return 0; // Failed to find a decl using this Entity.
+}
+
+/// \brief Get an Entity associated with the given Decl.
+/// \returns Null if an Entity cannot refer to this Decl.
+Entity EntityImpl::get(Decl *D, Program &Prog, ProgramImpl &ProgImpl) {
+  assert(D && "Passed null Decl");
+  return EntityGetter(Prog, ProgImpl).Visit(D);
+}
+
+std::string EntityImpl::getPrintableName() {
+  return Name.getAsString();
+}
+
+//===----------------------------------------------------------------------===//
+// Entity Implementation
+//===----------------------------------------------------------------------===//
+
+Entity::Entity(Decl *D) : Val(D->getCanonicalDecl()) { }
+
+/// \brief Find the Decl that can be referred to by this entity.
+Decl *Entity::getDecl(ASTContext &AST) const {
+  if (isInvalid())
+    return 0;
+
+  if (Decl *D = Val.dyn_cast<Decl *>())
+    // Check that the passed AST is actually the one that this Decl belongs to.
+    return (&D->getASTContext() == &AST) ? D : 0;
+
+  return Val.get<EntityImpl *>()->getDecl(AST);
+}
+
+std::string Entity::getPrintableName() const {
+  if (isInvalid())
+    return "<< Invalid >>";
+
+  if (Decl *D = Val.dyn_cast<Decl *>()) {
+    if (NamedDecl *ND = dyn_cast<NamedDecl>(D))
+      return ND->getNameAsString();
+    else
+      return std::string();
+  }
+
+  return Val.get<EntityImpl *>()->getPrintableName();
+}
+
+/// \brief Get an Entity associated with the given Decl.
+/// \returns Null if an Entity cannot refer to this Decl.
+Entity Entity::get(Decl *D, Program &Prog) {
+  if (D == 0)
+    return Entity();
+  ProgramImpl &ProgImpl = *static_cast<ProgramImpl*>(Prog.Impl);
+  return EntityImpl::get(D, Prog, ProgImpl);
+}
+
+unsigned
+llvm::DenseMapInfo<Entity>::getHashValue(Entity E) {
+  return DenseMapInfo<void*>::getHashValue(E.getAsOpaquePtr());
+}
diff --git a/lib/Index/EntityImpl.h b/lib/Index/EntityImpl.h
new file mode 100644
index 0000000..cbce934
--- /dev/null
+++ b/lib/Index/EntityImpl.h
@@ -0,0 +1,70 @@
+//===--- EntityImpl.h - Internal Entity implementation---------*- C++ -*-=====//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  Internal implementation for the Entity class
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_INDEX_ENTITYIMPL_H
+#define LLVM_CLANG_INDEX_ENTITYIMPL_H
+
+#include "clang/Index/Entity.h"
+#include "clang/AST/DeclarationName.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/StringSet.h"
+
+namespace clang {
+
+namespace idx {
+  class ProgramImpl;
+
+class EntityImpl : public llvm::FoldingSetNode {
+  Entity Parent;
+  DeclarationName Name;
+
+  /// \brief Identifier namespace.
+  unsigned IdNS;
+
+  /// \brief If Name is a selector, this keeps track whether it's for an
+  /// instance method.
+  bool IsObjCInstanceMethod;
+
+public:
+  EntityImpl(Entity parent, DeclarationName name, unsigned idNS,
+             bool isObjCInstanceMethod)
+    : Parent(parent), Name(name), IdNS(idNS),
+      IsObjCInstanceMethod(isObjCInstanceMethod) { }
+
+  /// \brief Find the Decl that can be referred to by this entity.
+  Decl *getDecl(ASTContext &AST);
+
+  /// \brief Get an Entity associated with the given Decl.
+  /// \returns Null if an Entity cannot refer to this Decl.
+  static Entity get(Decl *D, Program &Prog, ProgramImpl &ProgImpl);
+
+  std::string getPrintableName();
+
+  void Profile(llvm::FoldingSetNodeID &ID) const {
+    Profile(ID, Parent, Name, IdNS, IsObjCInstanceMethod);
+  }
+  static void Profile(llvm::FoldingSetNodeID &ID, Entity Parent,
+                      DeclarationName Name, unsigned IdNS,
+                      bool isObjCInstanceMethod) {
+    ID.AddPointer(Parent.getAsOpaquePtr());
+    ID.AddPointer(Name.getAsOpaquePtr());
+    ID.AddInteger(IdNS);
+    ID.AddBoolean(isObjCInstanceMethod);
+  }
+};
+
+} // namespace idx
+
+} // namespace clang
+
+#endif
diff --git a/lib/Index/GlobalSelector.cpp b/lib/Index/GlobalSelector.cpp
new file mode 100644
index 0000000..3467918
--- /dev/null
+++ b/lib/Index/GlobalSelector.cpp
@@ -0,0 +1,71 @@
+//===-- GlobalSelector.cpp - Cross-translation-unit "token" for selectors -===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  GlobalSelector is a ASTContext-independent way to refer to selectors.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Index/GlobalSelector.h"
+#include "ProgramImpl.h"
+#include "clang/Index/Program.h"
+#include "clang/AST/ASTContext.h"
+using namespace clang;
+using namespace idx;
+
+/// \brief Get the ASTContext-specific selector.
+Selector GlobalSelector::getSelector(ASTContext &AST) const {
+  if (isInvalid())
+    return Selector();
+
+  Selector GlobSel = Selector(reinterpret_cast<uintptr_t>(Val));
+
+  llvm::SmallVector<IdentifierInfo *, 8> Ids;
+  for (unsigned i = 0, e = GlobSel.isUnarySelector() ? 1 : GlobSel.getNumArgs();
+         i != e; ++i) {
+    IdentifierInfo *GlobII = GlobSel.getIdentifierInfoForSlot(i);
+    IdentifierInfo *II = &AST.Idents.get(GlobII->getName());
+    Ids.push_back(II);
+  }
+
+  return AST.Selectors.getSelector(GlobSel.getNumArgs(), Ids.data());
+}
+
+/// \brief Get a printable name for debugging purpose.
+std::string GlobalSelector::getPrintableName() const {
+  if (isInvalid())
+    return "<< Invalid >>";
+
+  Selector GlobSel = Selector(reinterpret_cast<uintptr_t>(Val));
+  return GlobSel.getAsString();
+}
+
+/// \brief Get a GlobalSelector for the ASTContext-specific selector.
+GlobalSelector GlobalSelector::get(Selector Sel, Program &Prog) {
+  if (Sel.isNull())
+    return GlobalSelector();
+
+  ProgramImpl &ProgImpl = *static_cast<ProgramImpl*>(Prog.Impl);
+
+  llvm::SmallVector<IdentifierInfo *, 8> Ids;
+  for (unsigned i = 0, e = Sel.isUnarySelector() ? 1 : Sel.getNumArgs();
+         i != e; ++i) {
+    IdentifierInfo *II = Sel.getIdentifierInfoForSlot(i);
+    IdentifierInfo *GlobII = &ProgImpl.getIdents().get(II->getName());
+    Ids.push_back(GlobII);
+  }
+
+  Selector GlobSel = ProgImpl.getSelectors().getSelector(Sel.getNumArgs(),
+                                                         Ids.data());
+  return GlobalSelector(GlobSel.getAsOpaquePtr());
+}
+
+unsigned
+llvm::DenseMapInfo<GlobalSelector>::getHashValue(GlobalSelector Sel) {
+  return DenseMapInfo<void*>::getHashValue(Sel.getAsOpaquePtr());
+}
diff --git a/lib/Index/Handlers.cpp b/lib/Index/Handlers.cpp
new file mode 100644
index 0000000..1e9a27d
--- /dev/null
+++ b/lib/Index/Handlers.cpp
@@ -0,0 +1,22 @@
+//===--- Handlers.cpp - Interfaces for receiving information ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  Abstract interfaces for receiving information.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Index/Handlers.h"
+#include "clang/Index/Entity.h"
+using namespace clang;
+using namespace idx;
+
+// Out-of-line to give the virtual tables a home.
+EntityHandler::~EntityHandler() { }
+TranslationUnitHandler::~TranslationUnitHandler() { }
+TULocationHandler::~TULocationHandler() { }
diff --git a/lib/Index/IndexProvider.cpp b/lib/Index/IndexProvider.cpp
new file mode 100644
index 0000000..eea0988
--- /dev/null
+++ b/lib/Index/IndexProvider.cpp
@@ -0,0 +1,20 @@
+//===- IndexProvider.cpp - Maps information to translation units -*- C++ -*-==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  Maps information to TranslationUnits.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Index/IndexProvider.h"
+#include "clang/Index/Entity.h"
+using namespace clang;
+using namespace idx;
+
+// Out-of-line to give the virtual table a home.
+IndexProvider::~IndexProvider() { }
diff --git a/lib/Index/Indexer.cpp b/lib/Index/Indexer.cpp
new file mode 100644
index 0000000..57bfc5b
--- /dev/null
+++ b/lib/Index/Indexer.cpp
@@ -0,0 +1,104 @@
+//===--- Indexer.cpp - IndexProvider implementation -------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  IndexProvider implementation.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Index/Indexer.h"
+#include "clang/Index/Program.h"
+#include "clang/Index/Handlers.h"
+#include "clang/Index/TranslationUnit.h"
+#include "ASTVisitor.h"
+#include "clang/AST/DeclBase.h"
+using namespace clang;
+using namespace idx;
+
+namespace {
+
+class EntityIndexer : public EntityHandler {
+  TranslationUnit *TU;
+  Indexer::MapTy &Map;
+
+public:
+  EntityIndexer(TranslationUnit *tu, Indexer::MapTy &map) : TU(tu), Map(map) { }
+
+  virtual void Handle(Entity Ent) {
+    if (Ent.isInternalToTU())
+      return;
+    Map[Ent].insert(TU);
+  }
+};
+
+class SelectorIndexer : public ASTVisitor<SelectorIndexer> {
+  Program &Prog;
+  TranslationUnit *TU;
+  Indexer::SelMapTy &Map;
+
+public:
+  SelectorIndexer(Program &prog, TranslationUnit *tu, Indexer::SelMapTy &map)
+    : Prog(prog), TU(tu), Map(map) { }
+
+  void VisitObjCMethodDecl(ObjCMethodDecl *D) {
+    Map[GlobalSelector::get(D->getSelector(), Prog)].insert(TU);
+    Base::VisitObjCMethodDecl(D);
+  }
+
+  void VisitObjCMessageExpr(ObjCMessageExpr *Node) {
+    Map[GlobalSelector::get(Node->getSelector(), Prog)].insert(TU);
+    Base::VisitObjCMessageExpr(Node);
+  }
+};
+
+} // anonymous namespace
+
+void Indexer::IndexAST(TranslationUnit *TU) {
+  assert(TU && "Passed null TranslationUnit");
+  ASTContext &Ctx = TU->getASTContext();
+  CtxTUMap[&Ctx] = TU;
+  EntityIndexer Idx(TU, Map);
+  Prog.FindEntities(Ctx, Idx);
+
+  SelectorIndexer SelIdx(Prog, TU, SelMap);
+  SelIdx.Visit(Ctx.getTranslationUnitDecl());
+}
+
+void Indexer::GetTranslationUnitsFor(Entity Ent,
+                                     TranslationUnitHandler &Handler) {
+  assert(Ent.isValid() && "Expected valid Entity");
+
+  if (Ent.isInternalToTU()) {
+    Decl *D = Ent.getInternalDecl();
+    CtxTUMapTy::iterator I = CtxTUMap.find(&D->getASTContext());
+    if (I != CtxTUMap.end())
+      Handler.Handle(I->second);
+    return;
+  }
+
+  MapTy::iterator I = Map.find(Ent);
+  if (I == Map.end())
+    return;
+
+  TUSetTy &Set = I->second;
+  for (TUSetTy::iterator I = Set.begin(), E = Set.end(); I != E; ++I)
+    Handler.Handle(*I);
+}
+
+void Indexer::GetTranslationUnitsFor(GlobalSelector Sel,
+                                    TranslationUnitHandler &Handler) {
+  assert(Sel.isValid() && "Expected valid GlobalSelector");
+
+  SelMapTy::iterator I = SelMap.find(Sel);
+  if (I == SelMap.end())
+    return;
+
+  TUSetTy &Set = I->second;
+  for (TUSetTy::iterator I = Set.begin(), E = Set.end(); I != E; ++I)
+    Handler.Handle(*I);
+}
diff --git a/lib/Index/Makefile b/lib/Index/Makefile
new file mode 100644
index 0000000..4d86713
--- /dev/null
+++ b/lib/Index/Makefile
@@ -0,0 +1,27 @@
+##===- clang/lib/Index/Makefile ----------------------------*- Makefile -*-===##
+# 
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+# 
+##===----------------------------------------------------------------------===##
+#
+#  This implements the Indexer library for the C-Language front-end.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../../../..
+include $(LEVEL)/Makefile.config
+
+LIBRARYNAME := clangIndex
+BUILD_ARCHIVE = 1
+
+ifeq ($(ARCH),PowerPC)
+CXX.Flags += -maltivec
+endif
+
+CPP.Flags += -I$(PROJ_SRC_DIR)/../../include -I$(PROJ_OBJ_DIR)/../../include
+
+include $(LEVEL)/Makefile.common
+
diff --git a/lib/Index/Program.cpp b/lib/Index/Program.cpp
new file mode 100644
index 0000000..4efad2c
--- /dev/null
+++ b/lib/Index/Program.cpp
@@ -0,0 +1,50 @@
+//===--- Program.cpp - Entity originator and misc -------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  Storage for Entities and utility functions
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Index/Program.h"
+#include "ProgramImpl.h"
+#include "clang/Index/Handlers.h"
+#include "clang/Index/TranslationUnit.h"
+#include "clang/AST/DeclBase.h"
+#include "clang/AST/ASTContext.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace clang;
+using namespace idx;
+
+// Out-of-line to give the virtual tables a home.
+TranslationUnit::~TranslationUnit() { }
+
+Program::Program() : Impl(new ProgramImpl()) { }
+
+Program::~Program() {
+  delete static_cast<ProgramImpl *>(Impl);
+}
+
+static void FindEntitiesInDC(DeclContext *DC, Program &Prog,
+                             EntityHandler &Handler) {
+  for (DeclContext::decl_iterator
+         I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I) {
+    if (I->getLocation().isInvalid())
+      continue;
+    Entity Ent = Entity::get(*I, Prog);
+    if (Ent.isValid())
+      Handler.Handle(Ent);
+    if (DeclContext *SubDC = dyn_cast<DeclContext>(*I))
+      FindEntitiesInDC(SubDC, Prog, Handler);
+  }
+}
+
+/// \brief Traverses the AST and passes all the entities to the Handler.
+void Program::FindEntities(ASTContext &Ctx, EntityHandler &Handler) {
+  FindEntitiesInDC(Ctx.getTranslationUnitDecl(), *this, Handler);
+}
diff --git a/lib/Index/ProgramImpl.h b/lib/Index/ProgramImpl.h
new file mode 100644
index 0000000..57b9ce3
--- /dev/null
+++ b/lib/Index/ProgramImpl.h
@@ -0,0 +1,56 @@
+//===--- ProgramImpl.h - Internal Program implementation---------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  Internal implementation for the Program class
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_INDEX_PROGRAMIMPL_H
+#define LLVM_CLANG_INDEX_PROGRAMIMPL_H
+
+#include "EntityImpl.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/LangOptions.h"
+
+namespace clang {
+
+namespace idx {
+  class EntityListener;
+
+class ProgramImpl {
+public:
+  typedef llvm::FoldingSet<EntityImpl> EntitySetTy;
+
+private:
+  EntitySetTy Entities;
+  llvm::BumpPtrAllocator BumpAlloc;
+
+  IdentifierTable Identifiers;
+  SelectorTable Selectors;
+
+  ProgramImpl(const ProgramImpl&); // do not implement
+  ProgramImpl &operator=(const ProgramImpl &); // do not implement
+
+public:
+  ProgramImpl() : Identifiers(LangOptions()) { }
+
+  EntitySetTy &getEntities() { return Entities; }
+  IdentifierTable &getIdents() { return Identifiers; }
+  SelectorTable &getSelectors() { return Selectors; }
+
+  void *Allocate(unsigned Size, unsigned Align = 8) {
+    return BumpAlloc.Allocate(Size, Align);
+  }
+};
+
+} // namespace idx
+
+} // namespace clang
+
+#endif
diff --git a/lib/Index/ResolveLocation.cpp b/lib/Index/ResolveLocation.cpp
new file mode 100644
index 0000000..4bb1594
--- /dev/null
+++ b/lib/Index/ResolveLocation.cpp
@@ -0,0 +1,613 @@
+//===--- ResolveLocation.cpp - Source location resolver ---------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This defines the ResolveLocationInAST function, which resolves a
+//  source location into a ASTLocation.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Index/Utils.h"
+#include "clang/Index/ASTLocation.h"
+#include "clang/AST/TypeLocVisitor.h"
+#include "clang/AST/DeclVisitor.h"
+#include "clang/AST/StmtVisitor.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Basic/SourceManager.h"
+using namespace clang;
+using namespace idx;
+
+namespace {
+
+/// \brief Base for the LocResolver classes. Mostly does source range checking.
+class LocResolverBase {
+protected:
+  ASTContext &Ctx;
+  SourceLocation Loc;
+  
+  ASTLocation ResolveInDeclarator(Decl *D, Stmt *Stm, TypeSourceInfo *TInfo);
+
+  enum RangePos {
+    BeforeLoc,
+    ContainsLoc,
+    AfterLoc
+  };
+
+  RangePos CheckRange(SourceRange Range);
+  RangePos CheckRange(TypeSourceInfo *TInfo);
+  RangePos CheckRange(Decl *D) {
+    if (DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D))
+      if (ContainsLocation(DD->getTypeSourceInfo()))
+        return ContainsLoc;
+    if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
+      if (ContainsLocation(TD->getTypeSourceInfo()))
+        return ContainsLoc;
+
+    return CheckRange(D->getSourceRange());
+  }
+  RangePos CheckRange(Stmt *Node) { return CheckRange(Node->getSourceRange()); }
+  RangePos CheckRange(TypeLoc TL) { return CheckRange(TL.getSourceRange()); }
+
+  template <typename T>
+  bool isBeforeLocation(T Node) {
+    return CheckRange(Node) == BeforeLoc;
+  }
+
+  template <typename T>
+  bool isAfterLocation(T Node) {
+    return CheckRange(Node) == AfterLoc;
+  }
+
+public:
+  LocResolverBase(ASTContext &ctx, SourceLocation loc)
+    : Ctx(ctx), Loc(loc) {}
+    
+  template <typename T>
+  bool ContainsLocation(T Node) {
+    return CheckRange(Node) == ContainsLoc;
+  }
+
+#ifndef NDEBUG
+  /// \brief Debugging output.
+  void print(Decl *D);
+  /// \brief Debugging output.
+  void print(Stmt *Node);
+#endif
+};
+
+/// \brief Searches a statement for the ASTLocation that corresponds to a source
+/// location.
+class StmtLocResolver : public LocResolverBase,
+                                          public StmtVisitor<StmtLocResolver,
+                                                             ASTLocation     > {
+  Decl * const Parent;
+
+public:
+  StmtLocResolver(ASTContext &ctx, SourceLocation loc, Decl *parent)
+    : LocResolverBase(ctx, loc), Parent(parent) {}
+
+  ASTLocation VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *Node);
+  ASTLocation VisitCXXOperatorCallExpr(CXXOperatorCallExpr *Node);
+  ASTLocation VisitDeclStmt(DeclStmt *Node);
+  ASTLocation VisitStmt(Stmt *Node);
+};
+
+/// \brief Searches a declaration for the ASTLocation that corresponds to a
+/// source location.
+class DeclLocResolver : public LocResolverBase,
+                                          public DeclVisitor<DeclLocResolver,
+                                                             ASTLocation     > {
+public:
+  DeclLocResolver(ASTContext &ctx, SourceLocation loc)
+    : LocResolverBase(ctx, loc) {}
+
+  ASTLocation VisitDeclContext(DeclContext *DC);
+  ASTLocation VisitTranslationUnitDecl(TranslationUnitDecl *TU);
+  ASTLocation VisitDeclaratorDecl(DeclaratorDecl *D);
+  ASTLocation VisitVarDecl(VarDecl *D);
+  ASTLocation VisitFunctionDecl(FunctionDecl *D);
+  ASTLocation VisitObjCClassDecl(ObjCClassDecl *D);                                                             
+  ASTLocation VisitObjCMethodDecl(ObjCMethodDecl *D);
+  ASTLocation VisitTypedefDecl(TypedefDecl *D);
+  ASTLocation VisitDecl(Decl *D);
+};
+
+class TypeLocResolver : public LocResolverBase,
+                        public TypeLocVisitor<TypeLocResolver, ASTLocation> {
+  Decl * const ParentDecl;
+
+public:
+  TypeLocResolver(ASTContext &ctx, SourceLocation loc, Decl *pd)
+    : LocResolverBase(ctx, loc), ParentDecl(pd) { }
+
+  ASTLocation VisitBuiltinTypeLoc(BuiltinTypeLoc TL);
+  ASTLocation VisitTypedefTypeLoc(TypedefTypeLoc TL);
+  ASTLocation VisitFunctionTypeLoc(FunctionTypeLoc TL);
+  ASTLocation VisitArrayTypeLoc(ArrayTypeLoc TL);
+  ASTLocation VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL);
+  ASTLocation VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL);
+  ASTLocation VisitTypeLoc(TypeLoc TL);
+};
+
+} // anonymous namespace
+
+ASTLocation
+StmtLocResolver::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *Node) {
+  assert(ContainsLocation(Node) &&
+         "Should visit only after verifying that loc is in range");
+
+  if (Node->isArgumentType()) {
+    TypeSourceInfo *TInfo = Node->getArgumentTypeInfo();
+    if (ContainsLocation(TInfo))
+      return ResolveInDeclarator(Parent, Node, TInfo);
+  } else {
+    Expr *SubNode = Node->getArgumentExpr();
+    if (ContainsLocation(SubNode))
+      return Visit(SubNode);
+  }
+
+  return ASTLocation(Parent, Node);
+}
+
+
+ASTLocation
+StmtLocResolver::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *Node) {
+  assert(ContainsLocation(Node) &&
+         "Should visit only after verifying that loc is in range");
+
+  if (Node->getNumArgs() == 1)
+    // Unary operator. Let normal child traversal handle it.
+    return VisitCallExpr(Node);
+
+  assert(Node->getNumArgs() == 2 &&
+         "Wrong args for the C++ operator call expr ?");
+
+  llvm::SmallVector<Expr *, 3> Nodes;
+  // Binary operator. Check in order of 1-left arg, 2-callee, 3-right arg.
+  Nodes.push_back(Node->getArg(0));
+  Nodes.push_back(Node->getCallee());
+  Nodes.push_back(Node->getArg(1));
+
+  for (unsigned i = 0, e = Nodes.size(); i != e; ++i) {
+    RangePos RP = CheckRange(Nodes[i]);
+    if (RP == AfterLoc)
+      break;
+    if (RP == ContainsLoc)
+      return Visit(Nodes[i]);
+  }
+
+  return ASTLocation(Parent, Node);
+}
+
+ASTLocation StmtLocResolver::VisitDeclStmt(DeclStmt *Node) {
+  assert(ContainsLocation(Node) &&
+         "Should visit only after verifying that loc is in range");
+
+  // Search all declarations of this DeclStmt.
+  for (DeclStmt::decl_iterator
+         I = Node->decl_begin(), E = Node->decl_end(); I != E; ++I) {
+    RangePos RP = CheckRange(*I);
+    if (RP == AfterLoc)
+      break;
+    if (RP == ContainsLoc)
+      return DeclLocResolver(Ctx, Loc).Visit(*I);
+  }
+
+  return ASTLocation(Parent, Node);
+}
+
+ASTLocation StmtLocResolver::VisitStmt(Stmt *Node) {
+  assert(ContainsLocation(Node) &&
+         "Should visit only after verifying that loc is in range");
+
+  // Search the child statements.
+  for (Stmt::child_iterator
+         I = Node->child_begin(), E = Node->child_end(); I != E; ++I) {
+    if (*I == NULL)
+      continue;
+
+    RangePos RP = CheckRange(*I);
+    if (RP == AfterLoc)
+      break;
+    if (RP == ContainsLoc)
+      return Visit(*I);
+  }
+
+  return ASTLocation(Parent, Node);
+}
+
+ASTLocation DeclLocResolver::VisitDeclContext(DeclContext *DC) {
+  for (DeclContext::decl_iterator
+         I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I) {
+    RangePos RP = CheckRange(*I);
+    if (RP == AfterLoc)
+      break;
+    if (RP == ContainsLoc)
+      return Visit(*I);
+  }
+
+  return ASTLocation(cast<Decl>(DC));
+}
+
+ASTLocation DeclLocResolver::VisitTranslationUnitDecl(TranslationUnitDecl *TU) {
+  ASTLocation ASTLoc = VisitDeclContext(TU);
+  if (ASTLoc.getParentDecl() == TU)
+    return ASTLocation();
+  return ASTLoc;
+}
+
+ASTLocation DeclLocResolver::VisitFunctionDecl(FunctionDecl *D) {
+  assert(ContainsLocation(D) &&
+         "Should visit only after verifying that loc is in range");
+
+  if (ContainsLocation(D->getTypeSourceInfo()))
+    return ResolveInDeclarator(D, 0, D->getTypeSourceInfo());
+
+  // First, search through the parameters of the function.
+  for (FunctionDecl::param_iterator
+         I = D->param_begin(), E = D->param_end(); I != E; ++I) {
+    RangePos RP = CheckRange(*I);
+    if (RP == AfterLoc)
+      return ASTLocation(D);
+    if (RP == ContainsLoc)
+      return Visit(*I);
+  }
+
+  // We didn't find the location in the parameters and we didn't get passed it.
+
+  if (!D->isThisDeclarationADefinition())
+    return ASTLocation(D);
+
+  // Second, search through the declarations that are part of the function.
+  // If we find the location there, we won't have to search through its body.
+
+  for (DeclContext::decl_iterator
+         I = D->decls_begin(), E = D->decls_end(); I != E; ++I) {
+    if (isa<ParmVarDecl>(*I))
+      continue; // We already searched through the parameters.
+
+    RangePos RP = CheckRange(*I);
+    if (RP == AfterLoc)
+      break;
+    if (RP == ContainsLoc)
+      return Visit(*I);
+  }
+
+  // We didn't find a declaration that corresponds to the source location.
+
+  // Finally, search through the body of the function.
+  Stmt *Body = D->getBody();
+  assert(Body && "Expected definition");
+  assert(!isBeforeLocation(Body) &&
+         "This function is supposed to contain the loc");
+  if (isAfterLocation(Body))
+    return ASTLocation(D);
+
+  // The body contains the location.
+  assert(ContainsLocation(Body));
+  return StmtLocResolver(Ctx, Loc, D).Visit(Body);
+}
+
+ASTLocation DeclLocResolver::VisitDeclaratorDecl(DeclaratorDecl *D) {
+  assert(ContainsLocation(D) &&
+         "Should visit only after verifying that loc is in range");
+  if (ContainsLocation(D->getTypeSourceInfo()))
+    return ResolveInDeclarator(D, /*Stmt=*/0, D->getTypeSourceInfo());
+
+  return ASTLocation(D);
+}
+
+ASTLocation DeclLocResolver::VisitTypedefDecl(TypedefDecl *D) {
+  assert(ContainsLocation(D) &&
+         "Should visit only after verifying that loc is in range");
+
+  if (ContainsLocation(D->getTypeSourceInfo()))
+    return ResolveInDeclarator(D, /*Stmt=*/0, D->getTypeSourceInfo());
+
+  return ASTLocation(D);
+}
+
+ASTLocation DeclLocResolver::VisitVarDecl(VarDecl *D) {
+  assert(ContainsLocation(D) &&
+         "Should visit only after verifying that loc is in range");
+
+  // Check whether the location points to the init expression.
+  Expr *Init = D->getInit();
+  if (Init && ContainsLocation(Init))
+    return StmtLocResolver(Ctx, Loc, D).Visit(Init);
+  
+  if (ContainsLocation(D->getTypeSourceInfo()))
+    return ResolveInDeclarator(D, 0, D->getTypeSourceInfo());
+
+  return ASTLocation(D);
+}
+
+ASTLocation DeclLocResolver::VisitObjCClassDecl(ObjCClassDecl *D) {
+  assert(ContainsLocation(D) &&
+         "Should visit only after verifying that loc is in range");
+         
+  for (ObjCClassDecl::iterator I = D->begin(), E = D->end() ; I != E; ++I) {
+    if (CheckRange(I->getLocation()) == ContainsLoc)
+      return ASTLocation(D, I->getInterface(), I->getLocation());
+  }
+  return ASTLocation(D);
+}
+
+ASTLocation DeclLocResolver::VisitObjCMethodDecl(ObjCMethodDecl *D) {
+  assert(ContainsLocation(D) &&
+         "Should visit only after verifying that loc is in range");
+
+  // First, search through the parameters of the method.
+  for (ObjCMethodDecl::param_iterator
+         I = D->param_begin(), E = D->param_end(); I != E; ++I) {
+    RangePos RP = CheckRange(*I);
+    if (RP == AfterLoc)
+      return ASTLocation(D);
+    if (RP == ContainsLoc)
+      return Visit(*I);
+  }
+
+  // We didn't find the location in the parameters and we didn't get passed it.
+
+  if (!D->getBody())
+    return ASTLocation(D);
+
+  // Second, search through the declarations that are part of the method.
+  // If we find he location there, we won't have to search through its body.
+
+  for (DeclContext::decl_iterator
+         I = D->decls_begin(), E = D->decls_end(); I != E; ++I) {
+    if (isa<ParmVarDecl>(*I))
+      continue; // We already searched through the parameters.
+
+    RangePos RP = CheckRange(*I);
+    if (RP == AfterLoc)
+      break;
+    if (RP == ContainsLoc)
+      return Visit(*I);
+  }
+
+  // We didn't find a declaration that corresponds to the source location.
+
+  // Finally, search through the body of the method.
+  Stmt *Body = D->getBody();
+  assert(Body && "Expected definition");
+  assert(!isBeforeLocation(Body) &&
+         "This method is supposed to contain the loc");
+  if (isAfterLocation(Body))
+    return ASTLocation(D);
+
+  // The body contains the location.
+  assert(ContainsLocation(Body));
+  return StmtLocResolver(Ctx, Loc, D).Visit(Body);
+}
+
+ASTLocation DeclLocResolver::VisitDecl(Decl *D) {
+  assert(ContainsLocation(D) &&
+         "Should visit only after verifying that loc is in range");
+  if (DeclContext *DC = dyn_cast<DeclContext>(D))
+    return VisitDeclContext(DC);
+  return ASTLocation(D);
+}
+
+ASTLocation TypeLocResolver::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
+  // Continue the 'id' magic by making the builtin type (which cannot
+  // actually be spelled) map to the typedef.
+  BuiltinType *T = TL.getTypePtr();
+  if (T->getKind() == BuiltinType::ObjCId) {
+    TypedefDecl *D = Ctx.getObjCIdType()->getAs<TypedefType>()->getDecl();
+    return ASTLocation(ParentDecl, D, TL.getNameLoc());
+  }
+
+  // Same thing with 'Class'.
+  if (T->getKind() == BuiltinType::ObjCClass) {
+    TypedefDecl *D = Ctx.getObjCClassType()->getAs<TypedefType>()->getDecl();
+    return ASTLocation(ParentDecl, D, TL.getNameLoc());
+  }
+
+  return ASTLocation(ParentDecl, TL);
+}
+
+ASTLocation TypeLocResolver::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
+  assert(ContainsLocation(TL) &&
+         "Should visit only after verifying that loc is in range");
+  if (ContainsLocation(TL.getNameLoc()))
+    return ASTLocation(ParentDecl, TL.getTypedefDecl(), TL.getNameLoc());
+  return ASTLocation(ParentDecl, TL);
+}
+
+ASTLocation TypeLocResolver::VisitFunctionTypeLoc(FunctionTypeLoc TL) {
+  assert(ContainsLocation(TL) &&
+         "Should visit only after verifying that loc is in range");
+
+  for (unsigned i = 0; i != TL.getNumArgs(); ++i) {
+    ParmVarDecl *Parm = TL.getArg(i);
+    RangePos RP = CheckRange(Parm);
+    if (RP == AfterLoc)
+      break;
+    if (RP == ContainsLoc)
+      return DeclLocResolver(Ctx, Loc).Visit(Parm);
+  }
+
+  return ASTLocation(ParentDecl, TL);
+}
+
+ASTLocation TypeLocResolver::VisitArrayTypeLoc(ArrayTypeLoc TL) {
+  assert(ContainsLocation(TL) &&
+         "Should visit only after verifying that loc is in range");
+
+  Expr *E = TL.getSizeExpr();
+  if (E && ContainsLocation(E))
+    return StmtLocResolver(Ctx, Loc, ParentDecl).Visit(E);
+
+  return ASTLocation(ParentDecl, TL);
+}
+
+ASTLocation TypeLocResolver::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
+  assert(ContainsLocation(TL) &&
+         "Should visit only after verifying that loc is in range");
+  if (ContainsLocation(TL.getNameLoc()))
+    return ASTLocation(ParentDecl, TL.getIFaceDecl(), TL.getNameLoc());
+
+  for (unsigned i = 0; i != TL.getNumProtocols(); ++i) {
+    SourceLocation L = TL.getProtocolLoc(i);
+    RangePos RP = CheckRange(L);
+    if (RP == AfterLoc)
+      break;
+    if (RP == ContainsLoc)
+      return ASTLocation(ParentDecl, TL.getProtocol(i), L);
+  }
+
+  return ASTLocation(ParentDecl, TL);
+}
+
+ASTLocation TypeLocResolver::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
+  assert(ContainsLocation(TL) &&
+         "Should visit only after verifying that loc is in range");
+
+  if (TL.hasProtocolsAsWritten()) {
+    for (unsigned i = 0; i != TL.getNumProtocols(); ++i) {
+      SourceLocation L = TL.getProtocolLoc(i);
+      RangePos RP = CheckRange(L);
+      if (RP == AfterLoc)
+        break;
+      if (RP == ContainsLoc)
+        return ASTLocation(ParentDecl, TL.getProtocol(i), L);
+    }
+  }
+
+  return ASTLocation(ParentDecl, TL);
+}
+
+ASTLocation TypeLocResolver::VisitTypeLoc(TypeLoc TL) {
+  assert(ContainsLocation(TL) &&
+         "Should visit only after verifying that loc is in range");
+  return ASTLocation(ParentDecl, TL);
+}
+
+ASTLocation LocResolverBase::ResolveInDeclarator(Decl *D, Stmt *Stm,
+                                                 TypeSourceInfo *TInfo) {
+  assert(ContainsLocation(TInfo) &&
+         "Should visit only after verifying that loc is in range");
+  
+  (void)TypeLocResolver(Ctx, Loc, D);
+  for (TypeLoc TL = TInfo->getTypeLoc(); TL; TL = TL.getNextTypeLoc())
+    if (ContainsLocation(TL))
+      return TypeLocResolver(Ctx, Loc, D).Visit(TL);
+  
+  assert(0 && "Should have found the loc in a typeloc");
+  return ASTLocation(D, Stm);
+}
+
+LocResolverBase::RangePos LocResolverBase::CheckRange(TypeSourceInfo *TInfo) {
+  if (!TInfo)
+    return BeforeLoc; // Keep looking.
+
+  for (TypeLoc TL = TInfo->getTypeLoc(); TL; TL = TL.getNextTypeLoc())
+    if (ContainsLocation(TL))
+      return ContainsLoc;
+
+  return BeforeLoc; // Keep looking.
+}
+
+LocResolverBase::RangePos LocResolverBase::CheckRange(SourceRange Range) {
+  if (!Range.isValid())
+    return BeforeLoc; // Keep looking.
+
+  // Update the end source range to cover the full length of the token
+  // positioned at the end of the source range.
+  //
+  // e.g.,
+  //   int foo
+  //   ^   ^
+  //
+  // will be updated to
+  //   int foo
+  //   ^     ^
+  unsigned TokSize = Lexer::MeasureTokenLength(Range.getEnd(),
+                                               Ctx.getSourceManager(),
+                                               Ctx.getLangOptions());
+  Range.setEnd(Range.getEnd().getFileLocWithOffset(TokSize-1));
+
+  SourceManager &SourceMgr = Ctx.getSourceManager();
+  if (SourceMgr.isBeforeInTranslationUnit(Range.getEnd(), Loc))
+    return BeforeLoc;
+
+  if (SourceMgr.isBeforeInTranslationUnit(Loc, Range.getBegin()))
+    return AfterLoc;
+
+  return ContainsLoc;
+}
+
+#ifndef NDEBUG
+void LocResolverBase::print(Decl *D) {
+  llvm::raw_ostream &OS = llvm::outs();
+  OS << "#### DECL " << D->getDeclKindName() << " ####\n";
+  D->print(OS);
+  OS << " <";
+  D->getLocStart().print(OS, Ctx.getSourceManager());
+  OS << " > - <";
+  D->getLocEnd().print(OS, Ctx.getSourceManager());
+  OS << ">\n\n";
+  OS.flush();
+}
+
+void LocResolverBase::print(Stmt *Node) {
+  llvm::raw_ostream &OS = llvm::outs();
+  OS << "#### STMT " << Node->getStmtClassName() << " ####\n";
+  Node->printPretty(OS, Ctx, 0, PrintingPolicy(Ctx.getLangOptions()));
+  OS << " <";
+  Node->getLocStart().print(OS, Ctx.getSourceManager());
+  OS << " > - <";
+  Node->getLocEnd().print(OS, Ctx.getSourceManager());
+  OS << ">\n\n";
+  OS.flush();
+}
+#endif
+
+
+/// \brief Returns the AST node that a source location points to.
+///
+ASTLocation idx::ResolveLocationInAST(ASTContext &Ctx, SourceLocation Loc,
+                                      ASTLocation *LastLoc) {
+  if (Loc.isInvalid())
+    return ASTLocation();
+
+  if (LastLoc && LastLoc->isValid()) {
+    DeclContext *DC = 0;
+  
+    if (Decl *Dcl = LastLoc->dyn_AsDecl()) {
+      DC = Dcl->getDeclContext();
+    } else if (LastLoc->isStmt()) {
+      Decl *Parent = LastLoc->getParentDecl();
+      if (FunctionDecl *FD = dyn_cast<FunctionDecl>(Parent))
+        DC = FD;
+      else { 
+        // This is needed to handle statements within an initializer.
+        // Example:
+        //   void func() { long double fabsf = __builtin_fabsl(__x); }
+        // In this case, the 'parent' of __builtin_fabsl is fabsf.
+        DC = Parent->getDeclContext();
+      }
+    } else { // We have 'N_NamedRef' or 'N_Type'
+      DC = LastLoc->getParentDecl()->getDeclContext();
+    } 
+    assert(DC && "Missing DeclContext");
+    
+    FunctionDecl *FD = dyn_cast<FunctionDecl>(DC);
+    DeclLocResolver DLocResolver(Ctx, Loc);
+    
+    if (FD && FD->isThisDeclarationADefinition() &&
+        DLocResolver.ContainsLocation(FD)) {
+      return DLocResolver.VisitFunctionDecl(FD);
+    }
+    // Fall through and try the slow path...
+    // FIXME: Optimize more cases.
+  }
+  return DeclLocResolver(Ctx, Loc).Visit(Ctx.getTranslationUnitDecl());
+}
diff --git a/lib/Index/SelectorMap.cpp b/lib/Index/SelectorMap.cpp
new file mode 100644
index 0000000..0f11e31
--- /dev/null
+++ b/lib/Index/SelectorMap.cpp
@@ -0,0 +1,84 @@
+//===- SelectorMap.cpp - Maps selectors to methods and messages -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  SelectorMap creates a mapping from selectors to ObjC method declarations
+//  and ObjC message expressions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Index/SelectorMap.h"
+#include "ASTVisitor.h"
+using namespace clang;
+using namespace idx;
+
+namespace {
+
+class SelMapper : public ASTVisitor<SelMapper> {
+  SelectorMap::SelMethMapTy &SelMethMap;
+  SelectorMap::SelRefMapTy &SelRefMap;
+
+public:
+  SelMapper(SelectorMap::SelMethMapTy &MethMap,
+            SelectorMap::SelRefMapTy &RefMap)
+    : SelMethMap(MethMap), SelRefMap(RefMap) { }
+
+  void VisitObjCMethodDecl(ObjCMethodDecl *D);
+  void VisitObjCMessageExpr(ObjCMessageExpr *Node);
+  void VisitObjCSelectorExpr(ObjCSelectorExpr *Node);
+};
+
+} // anonymous namespace
+
+//===----------------------------------------------------------------------===//
+// SelMapper Implementation
+//===----------------------------------------------------------------------===//
+
+void SelMapper::VisitObjCMethodDecl(ObjCMethodDecl *D) {
+  if (D->getCanonicalDecl() == D)
+    SelMethMap.insert(std::make_pair(D->getSelector(), D));
+  Base::VisitObjCMethodDecl(D);
+}
+
+void SelMapper::VisitObjCMessageExpr(ObjCMessageExpr *Node) {
+  ASTLocation ASTLoc(CurrentDecl, Node);
+  SelRefMap.insert(std::make_pair(Node->getSelector(), ASTLoc));
+}
+
+void SelMapper::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) {
+  ASTLocation ASTLoc(CurrentDecl, Node);
+  SelRefMap.insert(std::make_pair(Node->getSelector(), ASTLoc));
+}
+
+//===----------------------------------------------------------------------===//
+// SelectorMap Implementation
+//===----------------------------------------------------------------------===//
+
+SelectorMap::SelectorMap(ASTContext &Ctx) {
+  SelMapper(SelMethMap, SelRefMap).Visit(Ctx.getTranslationUnitDecl());
+}
+
+SelectorMap::method_iterator
+SelectorMap::methods_begin(Selector Sel) const {
+  return method_iterator(SelMethMap.lower_bound(Sel));
+}
+
+SelectorMap::method_iterator
+SelectorMap::methods_end(Selector Sel) const {
+  return method_iterator(SelMethMap.upper_bound(Sel));
+}
+
+SelectorMap::astlocation_iterator
+SelectorMap::refs_begin(Selector Sel) const {
+  return astlocation_iterator(SelRefMap.lower_bound(Sel));
+}
+
+SelectorMap::astlocation_iterator
+SelectorMap::refs_end(Selector Sel) const {
+  return astlocation_iterator(SelRefMap.upper_bound(Sel));
+}
diff --git a/lib/Lex/Android.mk b/lib/Lex/Android.mk
new file mode 100644
index 0000000..f94d2e4
--- /dev/null
+++ b/lib/Lex/Android.mk
@@ -0,0 +1,39 @@
+LOCAL_PATH:= $(call my-dir)
+
+# For the host only
+# =====================================================
+include $(CLEAR_VARS)
+include $(CLEAR_TBLGEN_VARS)
+
+TBLGEN_TABLES :=    \
+	DiagnosticLexKinds.inc	\
+    DiagnosticCommonKinds.inc 
+
+clang_lex_SRC_FILES :=	\
+	HeaderMap.cpp	\
+	HeaderSearch.cpp	\
+	Lexer.cpp	\
+	LiteralSupport.cpp	\
+	MacroArgs.cpp	\
+	MacroInfo.cpp	\
+	PPCaching.cpp	\
+	PPDirectives.cpp	\
+	PPExpressions.cpp	\
+	PPLexerChange.cpp	\
+	PPMacroExpansion.cpp	\
+	PTHLexer.cpp	\
+	Pragma.cpp	\
+	PreprocessingRecord.cpp	\
+	Preprocessor.cpp	\
+	PreprocessorLexer.cpp	\
+	ScratchBuffer.cpp	\
+	TokenConcatenation.cpp	\
+	TokenLexer.cpp
+
+LOCAL_SRC_FILES := $(clang_lex_SRC_FILES)
+
+LOCAL_MODULE:= libclangLex
+
+include $(CLANG_HOST_BUILD_MK)
+include $(CLANG_TBLGEN_RULES_MK)
+include $(BUILD_HOST_STATIC_LIBRARY)
diff --git a/lib/Lex/CMakeLists.txt b/lib/Lex/CMakeLists.txt
new file mode 100644
index 0000000..632fbc6
--- /dev/null
+++ b/lib/Lex/CMakeLists.txt
@@ -0,0 +1,27 @@
+set(LLVM_NO_RTTI 1)
+
+# TODO: Add -maltivec when ARCH is PowerPC.
+
+add_clang_library(clangLex
+  HeaderMap.cpp
+  HeaderSearch.cpp
+  Lexer.cpp
+  LiteralSupport.cpp
+  MacroArgs.cpp
+  MacroInfo.cpp
+  PPCaching.cpp
+  PPDirectives.cpp
+  PPExpressions.cpp
+  PPLexerChange.cpp
+  PPMacroExpansion.cpp
+  PTHLexer.cpp
+  Pragma.cpp
+  PreprocessingRecord.cpp
+  Preprocessor.cpp
+  PreprocessorLexer.cpp
+  ScratchBuffer.cpp
+  TokenConcatenation.cpp
+  TokenLexer.cpp
+  )
+
+add_dependencies(clangLex ClangDiagnosticLex)
diff --git a/lib/Lex/HeaderMap.cpp b/lib/Lex/HeaderMap.cpp
new file mode 100644
index 0000000..4010d61
--- /dev/null
+++ b/lib/Lex/HeaderMap.cpp
@@ -0,0 +1,228 @@
+//===--- HeaderMap.cpp - A file that acts like dir of symlinks ------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the HeaderMap interface.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Lex/HeaderMap.h"
+#include "clang/Basic/FileManager.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/System/DataTypes.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include <cstdio>
+using namespace clang;
+
+//===----------------------------------------------------------------------===//
+// Data Structures and Manifest Constants
+//===----------------------------------------------------------------------===//
+
+enum {
+  HMAP_HeaderMagicNumber = ('h' << 24) | ('m' << 16) | ('a' << 8) | 'p',
+  HMAP_HeaderVersion = 1,
+
+  HMAP_EmptyBucketKey = 0
+};
+
+namespace clang {
+struct HMapBucket {
+  uint32_t Key;          // Offset (into strings) of key.
+
+  uint32_t Prefix;     // Offset (into strings) of value prefix.
+  uint32_t Suffix;     // Offset (into strings) of value suffix.
+};
+
+struct HMapHeader {
+  uint32_t Magic;           // Magic word, also indicates byte order.
+  uint16_t Version;         // Version number -- currently 1.
+  uint16_t Reserved;        // Reserved for future use - zero for now.
+  uint32_t StringsOffset;   // Offset to start of string pool.
+  uint32_t NumEntries;      // Number of entries in the string table.
+  uint32_t NumBuckets;      // Number of buckets (always a power of 2).
+  uint32_t MaxValueLength;  // Length of longest result path (excluding nul).
+  // An array of 'NumBuckets' HMapBucket objects follows this header.
+  // Strings follow the buckets, at StringsOffset.
+};
+} // end namespace clang.
+
+/// HashHMapKey - This is the 'well known' hash function required by the file
+/// format, used to look up keys in the hash table.  The hash table uses simple
+/// linear probing based on this function.
+static inline unsigned HashHMapKey(llvm::StringRef Str) {
+  unsigned Result = 0;
+  const char *S = Str.begin(), *End = Str.end();
+
+  for (; S != End; S++)
+    Result += tolower(*S) * 13;
+  return Result;
+}
+
+
+
+//===----------------------------------------------------------------------===//
+// Verification and Construction
+//===----------------------------------------------------------------------===//
+
+/// HeaderMap::Create - This attempts to load the specified file as a header
+/// map.  If it doesn't look like a HeaderMap, it gives up and returns null.
+/// If it looks like a HeaderMap but is obviously corrupted, it puts a reason
+/// into the string error argument and returns null.
+const HeaderMap *HeaderMap::Create(const FileEntry *FE) {
+  // If the file is too small to be a header map, ignore it.
+  unsigned FileSize = FE->getSize();
+  if (FileSize <= sizeof(HMapHeader)) return 0;
+
+  llvm::OwningPtr<const llvm::MemoryBuffer> FileBuffer(
+    llvm::MemoryBuffer::getFile(FE->getName(), 0, FE->getSize()));
+  if (FileBuffer == 0) return 0;  // Unreadable file?
+  const char *FileStart = FileBuffer->getBufferStart();
+
+  // We know the file is at least as big as the header, check it now.
+  const HMapHeader *Header = reinterpret_cast<const HMapHeader*>(FileStart);
+
+  // Sniff it to see if it's a headermap by checking the magic number and
+  // version.
+  bool NeedsByteSwap;
+  if (Header->Magic == HMAP_HeaderMagicNumber &&
+      Header->Version == HMAP_HeaderVersion)
+    NeedsByteSwap = false;
+  else if (Header->Magic == llvm::ByteSwap_32(HMAP_HeaderMagicNumber) &&
+           Header->Version == llvm::ByteSwap_16(HMAP_HeaderVersion))
+    NeedsByteSwap = true;  // Mixed endianness headermap.
+  else
+    return 0;  // Not a header map.
+
+  if (Header->Reserved != 0) return 0;
+
+  // Okay, everything looks good, create the header map.
+  return new HeaderMap(FileBuffer.take(), NeedsByteSwap);
+}
+
+HeaderMap::~HeaderMap() {
+  delete FileBuffer;
+}
+
+//===----------------------------------------------------------------------===//
+//  Utility Methods
+//===----------------------------------------------------------------------===//
+
+
+/// getFileName - Return the filename of the headermap.
+const char *HeaderMap::getFileName() const {
+  return FileBuffer->getBufferIdentifier();
+}
+
+unsigned HeaderMap::getEndianAdjustedWord(unsigned X) const {
+  if (!NeedsBSwap) return X;
+  return llvm::ByteSwap_32(X);
+}
+
+/// getHeader - Return a reference to the file header, in unbyte-swapped form.
+/// This method cannot fail.
+const HMapHeader &HeaderMap::getHeader() const {
+  // We know the file is at least as big as the header.  Return it.
+  return *reinterpret_cast<const HMapHeader*>(FileBuffer->getBufferStart());
+}
+
+/// getBucket - Return the specified hash table bucket from the header map,
+/// bswap'ing its fields as appropriate.  If the bucket number is not valid,
+/// this return a bucket with an empty key (0).
+HMapBucket HeaderMap::getBucket(unsigned BucketNo) const {
+  HMapBucket Result;
+  Result.Key = HMAP_EmptyBucketKey;
+
+  const HMapBucket *BucketArray =
+    reinterpret_cast<const HMapBucket*>(FileBuffer->getBufferStart() +
+                                        sizeof(HMapHeader));
+
+  const HMapBucket *BucketPtr = BucketArray+BucketNo;
+  if ((char*)(BucketPtr+1) > FileBuffer->getBufferEnd()) {
+    Result.Prefix = 0;
+    Result.Suffix = 0;
+    return Result;  // Invalid buffer, corrupt hmap.
+  }
+
+  // Otherwise, the bucket is valid.  Load the values, bswapping as needed.
+  Result.Key    = getEndianAdjustedWord(BucketPtr->Key);
+  Result.Prefix = getEndianAdjustedWord(BucketPtr->Prefix);
+  Result.Suffix = getEndianAdjustedWord(BucketPtr->Suffix);
+  return Result;
+}
+
+/// getString - Look up the specified string in the string table.  If the string
+/// index is not valid, it returns an empty string.
+const char *HeaderMap::getString(unsigned StrTabIdx) const {
+  // Add the start of the string table to the idx.
+  StrTabIdx += getEndianAdjustedWord(getHeader().StringsOffset);
+
+  // Check for invalid index.
+  if (StrTabIdx >= FileBuffer->getBufferSize())
+    return 0;
+
+  // Otherwise, we have a valid pointer into the file.  Just return it.  We know
+  // that the "string" can not overrun the end of the file, because the buffer
+  // is nul terminated by virtue of being a MemoryBuffer.
+  return FileBuffer->getBufferStart()+StrTabIdx;
+}
+
+//===----------------------------------------------------------------------===//
+// The Main Drivers
+//===----------------------------------------------------------------------===//
+
+/// dump - Print the contents of this headermap to stderr.
+void HeaderMap::dump() const {
+  const HMapHeader &Hdr = getHeader();
+  unsigned NumBuckets = getEndianAdjustedWord(Hdr.NumBuckets);
+
+  fprintf(stderr, "Header Map %s:\n  %d buckets, %d entries\n",
+          getFileName(), NumBuckets,
+          getEndianAdjustedWord(Hdr.NumEntries));
+
+  for (unsigned i = 0; i != NumBuckets; ++i) {
+    HMapBucket B = getBucket(i);
+    if (B.Key == HMAP_EmptyBucketKey) continue;
+
+    const char *Key    = getString(B.Key);
+    const char *Prefix = getString(B.Prefix);
+    const char *Suffix = getString(B.Suffix);
+    fprintf(stderr, "  %d. %s -> '%s' '%s'\n", i, Key, Prefix, Suffix);
+  }
+}
+
+/// LookupFile - Check to see if the specified relative filename is located in
+/// this HeaderMap.  If so, open it and return its FileEntry.
+const FileEntry *HeaderMap::LookupFile(llvm::StringRef Filename,
+                                       FileManager &FM) const {
+  const HMapHeader &Hdr = getHeader();
+  unsigned NumBuckets = getEndianAdjustedWord(Hdr.NumBuckets);
+
+  // If the number of buckets is not a power of two, the headermap is corrupt.
+  // Don't probe infinitely.
+  if (NumBuckets & (NumBuckets-1))
+    return 0;
+
+  // Linearly probe the hash table.
+  for (unsigned Bucket = HashHMapKey(Filename);; ++Bucket) {
+    HMapBucket B = getBucket(Bucket & (NumBuckets-1));
+    if (B.Key == HMAP_EmptyBucketKey) return 0; // Hash miss.
+
+    // See if the key matches.  If not, probe on.
+    if (!Filename.equals_lower(getString(B.Key)))
+      continue;
+
+    // If so, we have a match in the hash table.  Construct the destination
+    // path.
+    llvm::SmallString<1024> DestPath;
+    DestPath += getString(B.Prefix);
+    DestPath += getString(B.Suffix);
+    return FM.getFile(DestPath.begin(), DestPath.end());
+  }
+}
diff --git a/lib/Lex/HeaderSearch.cpp b/lib/Lex/HeaderSearch.cpp
new file mode 100644
index 0000000..4554aba
--- /dev/null
+++ b/lib/Lex/HeaderSearch.cpp
@@ -0,0 +1,440 @@
+//===--- HeaderSearch.cpp - Resolve Header File Locations ---===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements the DirectoryLookup and HeaderSearch interfaces.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Lex/HeaderSearch.h"
+#include "clang/Lex/HeaderMap.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "llvm/System/Path.h"
+#include "llvm/ADT/SmallString.h"
+#include <cstdio>
+using namespace clang;
+
+const IdentifierInfo *
+HeaderFileInfo::getControllingMacro(ExternalIdentifierLookup *External) {
+  if (ControllingMacro)
+    return ControllingMacro;
+
+  if (!ControllingMacroID || !External)
+    return 0;
+
+  ControllingMacro = External->GetIdentifier(ControllingMacroID);
+  return ControllingMacro;
+}
+
+HeaderSearch::HeaderSearch(FileManager &FM) : FileMgr(FM), FrameworkMap(64) {
+  SystemDirIdx = 0;
+  NoCurDirSearch = false;
+
+  ExternalLookup = 0;
+  NumIncluded = 0;
+  NumMultiIncludeFileOptzn = 0;
+  NumFrameworkLookups = NumSubFrameworkLookups = 0;
+}
+
+HeaderSearch::~HeaderSearch() {
+  // Delete headermaps.
+  for (unsigned i = 0, e = HeaderMaps.size(); i != e; ++i)
+    delete HeaderMaps[i].second;
+}
+
+void HeaderSearch::PrintStats() {
+  fprintf(stderr, "\n*** HeaderSearch Stats:\n");
+  fprintf(stderr, "%d files tracked.\n", (int)FileInfo.size());
+  unsigned NumOnceOnlyFiles = 0, MaxNumIncludes = 0, NumSingleIncludedFiles = 0;
+  for (unsigned i = 0, e = FileInfo.size(); i != e; ++i) {
+    NumOnceOnlyFiles += FileInfo[i].isImport;
+    if (MaxNumIncludes < FileInfo[i].NumIncludes)
+      MaxNumIncludes = FileInfo[i].NumIncludes;
+    NumSingleIncludedFiles += FileInfo[i].NumIncludes == 1;
+  }
+  fprintf(stderr, "  %d #import/#pragma once files.\n", NumOnceOnlyFiles);
+  fprintf(stderr, "  %d included exactly once.\n", NumSingleIncludedFiles);
+  fprintf(stderr, "  %d max times a file is included.\n", MaxNumIncludes);
+
+  fprintf(stderr, "  %d #include/#include_next/#import.\n", NumIncluded);
+  fprintf(stderr, "    %d #includes skipped due to"
+          " the multi-include optimization.\n", NumMultiIncludeFileOptzn);
+
+  fprintf(stderr, "%d framework lookups.\n", NumFrameworkLookups);
+  fprintf(stderr, "%d subframework lookups.\n", NumSubFrameworkLookups);
+}
+
+/// CreateHeaderMap - This method returns a HeaderMap for the specified
+/// FileEntry, uniquing them through the the 'HeaderMaps' datastructure.
+const HeaderMap *HeaderSearch::CreateHeaderMap(const FileEntry *FE) {
+  // We expect the number of headermaps to be small, and almost always empty.
+  // If it ever grows, use of a linear search should be re-evaluated.
+  if (!HeaderMaps.empty()) {
+    for (unsigned i = 0, e = HeaderMaps.size(); i != e; ++i)
+      // Pointer equality comparison of FileEntries works because they are
+      // already uniqued by inode.
+      if (HeaderMaps[i].first == FE)
+        return HeaderMaps[i].second;
+  }
+
+  if (const HeaderMap *HM = HeaderMap::Create(FE)) {
+    HeaderMaps.push_back(std::make_pair(FE, HM));
+    return HM;
+  }
+
+  return 0;
+}
+
+//===----------------------------------------------------------------------===//
+// File lookup within a DirectoryLookup scope
+//===----------------------------------------------------------------------===//
+
+/// getName - Return the directory or filename corresponding to this lookup
+/// object.
+const char *DirectoryLookup::getName() const {
+  if (isNormalDir())
+    return getDir()->getName();
+  if (isFramework())
+    return getFrameworkDir()->getName();
+  assert(isHeaderMap() && "Unknown DirectoryLookup");
+  return getHeaderMap()->getFileName();
+}
+
+
+/// LookupFile - Lookup the specified file in this search path, returning it
+/// if it exists or returning null if not.
+const FileEntry *DirectoryLookup::LookupFile(llvm::StringRef Filename,
+                                             HeaderSearch &HS) const {
+  llvm::SmallString<1024> TmpDir;
+  if (isNormalDir()) {
+    // Concatenate the requested file onto the directory.
+    // FIXME: Portability.  Filename concatenation should be in sys::Path.
+    TmpDir += getDir()->getName();
+    TmpDir.push_back('/');
+    TmpDir.append(Filename.begin(), Filename.end());
+    return HS.getFileMgr().getFile(TmpDir.begin(), TmpDir.end());
+  }
+
+  if (isFramework())
+    return DoFrameworkLookup(Filename, HS);
+
+  assert(isHeaderMap() && "Unknown directory lookup");
+  return getHeaderMap()->LookupFile(Filename, HS.getFileMgr());
+}
+
+
+/// DoFrameworkLookup - Do a lookup of the specified file in the current
+/// DirectoryLookup, which is a framework directory.
+const FileEntry *DirectoryLookup::DoFrameworkLookup(llvm::StringRef Filename,
+                                                    HeaderSearch &HS) const {
+  FileManager &FileMgr = HS.getFileMgr();
+
+  // Framework names must have a '/' in the filename.
+  size_t SlashPos = Filename.find('/');
+  if (SlashPos == llvm::StringRef::npos) return 0;
+
+  // Find out if this is the home for the specified framework, by checking
+  // HeaderSearch.  Possible answer are yes/no and unknown.
+  const DirectoryEntry *&FrameworkDirCache =
+    HS.LookupFrameworkCache(Filename.substr(0, SlashPos));
+
+  // If it is known and in some other directory, fail.
+  if (FrameworkDirCache && FrameworkDirCache != getFrameworkDir())
+    return 0;
+
+  // Otherwise, construct the path to this framework dir.
+
+  // FrameworkName = "/System/Library/Frameworks/"
+  llvm::SmallString<1024> FrameworkName;
+  FrameworkName += getFrameworkDir()->getName();
+  if (FrameworkName.empty() || FrameworkName.back() != '/')
+    FrameworkName.push_back('/');
+
+  // FrameworkName = "/System/Library/Frameworks/Cocoa"
+  FrameworkName.append(Filename.begin(), Filename.begin()+SlashPos);
+
+  // FrameworkName = "/System/Library/Frameworks/Cocoa.framework/"
+  FrameworkName += ".framework/";
+
+  // If the cache entry is still unresolved, query to see if the cache entry is
+  // still unresolved.  If so, check its existence now.
+  if (FrameworkDirCache == 0) {
+    HS.IncrementFrameworkLookupCount();
+
+    // If the framework dir doesn't exist, we fail.
+    // FIXME: It's probably more efficient to query this with FileMgr.getDir.
+    if (!llvm::sys::Path(std::string(FrameworkName.begin(),
+                                     FrameworkName.end())).exists())
+      return 0;
+
+    // Otherwise, if it does, remember that this is the right direntry for this
+    // framework.
+    FrameworkDirCache = getFrameworkDir();
+  }
+
+  // Check "/System/Library/Frameworks/Cocoa.framework/Headers/file.h"
+  unsigned OrigSize = FrameworkName.size();
+
+  FrameworkName += "Headers/";
+  FrameworkName.append(Filename.begin()+SlashPos+1, Filename.end());
+  if (const FileEntry *FE = FileMgr.getFile(FrameworkName.begin(),
+                                            FrameworkName.end())) {
+    return FE;
+  }
+
+  // Check "/System/Library/Frameworks/Cocoa.framework/PrivateHeaders/file.h"
+  const char *Private = "Private";
+  FrameworkName.insert(FrameworkName.begin()+OrigSize, Private,
+                       Private+strlen(Private));
+  return FileMgr.getFile(FrameworkName.begin(), FrameworkName.end());
+}
+
+
+//===----------------------------------------------------------------------===//
+// Header File Location.
+//===----------------------------------------------------------------------===//
+
+
+/// LookupFile - Given a "foo" or <foo> reference, look up the indicated file,
+/// return null on failure.  isAngled indicates whether the file reference is
+/// for system #include's or not (i.e. using <> instead of "").  CurFileEnt, if
+/// non-null, indicates where the #including file is, in case a relative search
+/// is needed.
+const FileEntry *HeaderSearch::LookupFile(llvm::StringRef Filename,
+                                          bool isAngled,
+                                          const DirectoryLookup *FromDir,
+                                          const DirectoryLookup *&CurDir,
+                                          const FileEntry *CurFileEnt) {
+  // If 'Filename' is absolute, check to see if it exists and no searching.
+  if (llvm::sys::Path::isAbsolute(Filename.begin(), Filename.size())) {
+    CurDir = 0;
+
+    // If this was an #include_next "/absolute/file", fail.
+    if (FromDir) return 0;
+
+    // Otherwise, just return the file.
+    return FileMgr.getFile(Filename);
+  }
+
+  // Step #0, unless disabled, check to see if the file is in the #includer's
+  // directory.  This has to be based on CurFileEnt, not CurDir, because
+  // CurFileEnt could be a #include of a subdirectory (#include "foo/bar.h") and
+  // a subsequent include of "baz.h" should resolve to "whatever/foo/baz.h".
+  // This search is not done for <> headers.
+  if (CurFileEnt && !isAngled && !NoCurDirSearch) {
+    llvm::SmallString<1024> TmpDir;
+    // Concatenate the requested file onto the directory.
+    // FIXME: Portability.  Filename concatenation should be in sys::Path.
+    TmpDir += CurFileEnt->getDir()->getName();
+    TmpDir.push_back('/');
+    TmpDir.append(Filename.begin(), Filename.end());
+    if (const FileEntry *FE = FileMgr.getFile(TmpDir.str())) {
+      // Leave CurDir unset.
+      // This file is a system header or C++ unfriendly if the old file is.
+      //
+      // Note that the temporary 'DirInfo' is required here, as either call to
+      // getFileInfo could resize the vector and we don't want to rely on order
+      // of evaluation.
+      unsigned DirInfo = getFileInfo(CurFileEnt).DirInfo;
+      getFileInfo(FE).DirInfo = DirInfo;
+      return FE;
+    }
+  }
+
+  CurDir = 0;
+
+  // If this is a system #include, ignore the user #include locs.
+  unsigned i = isAngled ? SystemDirIdx : 0;
+
+  // If this is a #include_next request, start searching after the directory the
+  // file was found in.
+  if (FromDir)
+    i = FromDir-&SearchDirs[0];
+
+  // Cache all of the lookups performed by this method.  Many headers are
+  // multiply included, and the "pragma once" optimization prevents them from
+  // being relex/pp'd, but they would still have to search through a
+  // (potentially huge) series of SearchDirs to find it.
+  std::pair<unsigned, unsigned> &CacheLookup =
+    LookupFileCache.GetOrCreateValue(Filename).getValue();
+
+  // If the entry has been previously looked up, the first value will be
+  // non-zero.  If the value is equal to i (the start point of our search), then
+  // this is a matching hit.
+  if (CacheLookup.first == i+1) {
+    // Skip querying potentially lots of directories for this lookup.
+    i = CacheLookup.second;
+  } else {
+    // Otherwise, this is the first query, or the previous query didn't match
+    // our search start.  We will fill in our found location below, so prime the
+    // start point value.
+    CacheLookup.first = i+1;
+  }
+
+  // Check each directory in sequence to see if it contains this file.
+  for (; i != SearchDirs.size(); ++i) {
+    const FileEntry *FE =
+      SearchDirs[i].LookupFile(Filename, *this);
+    if (!FE) continue;
+
+    CurDir = &SearchDirs[i];
+
+    // This file is a system header or C++ unfriendly if the dir is.
+    getFileInfo(FE).DirInfo = CurDir->getDirCharacteristic();
+
+    // Remember this location for the next lookup we do.
+    CacheLookup.second = i;
+    return FE;
+  }
+
+  // Otherwise, didn't find it. Remember we didn't find this.
+  CacheLookup.second = SearchDirs.size();
+  return 0;
+}
+
+/// LookupSubframeworkHeader - Look up a subframework for the specified
+/// #include file.  For example, if #include'ing <HIToolbox/HIToolbox.h> from
+/// within ".../Carbon.framework/Headers/Carbon.h", check to see if HIToolbox
+/// is a subframework within Carbon.framework.  If so, return the FileEntry
+/// for the designated file, otherwise return null.
+const FileEntry *HeaderSearch::
+LookupSubframeworkHeader(llvm::StringRef Filename,
+                         const FileEntry *ContextFileEnt) {
+  assert(ContextFileEnt && "No context file?");
+
+  // Framework names must have a '/' in the filename.  Find it.
+  size_t SlashPos = Filename.find('/');
+  if (SlashPos == llvm::StringRef::npos) return 0;
+
+  // Look up the base framework name of the ContextFileEnt.
+  const char *ContextName = ContextFileEnt->getName();
+
+  // If the context info wasn't a framework, couldn't be a subframework.
+  const char *FrameworkPos = strstr(ContextName, ".framework/");
+  if (FrameworkPos == 0)
+    return 0;
+
+  llvm::SmallString<1024> FrameworkName(ContextName,
+                                        FrameworkPos+strlen(".framework/"));
+
+  // Append Frameworks/HIToolbox.framework/
+  FrameworkName += "Frameworks/";
+  FrameworkName.append(Filename.begin(), Filename.begin()+SlashPos);
+  FrameworkName += ".framework/";
+
+  llvm::StringMapEntry<const DirectoryEntry *> &CacheLookup =
+    FrameworkMap.GetOrCreateValue(Filename.begin(), Filename.begin()+SlashPos);
+
+  // Some other location?
+  if (CacheLookup.getValue() &&
+      CacheLookup.getKeyLength() == FrameworkName.size() &&
+      memcmp(CacheLookup.getKeyData(), &FrameworkName[0],
+             CacheLookup.getKeyLength()) != 0)
+    return 0;
+
+  // Cache subframework.
+  if (CacheLookup.getValue() == 0) {
+    ++NumSubFrameworkLookups;
+
+    // If the framework dir doesn't exist, we fail.
+    const DirectoryEntry *Dir = FileMgr.getDirectory(FrameworkName.begin(),
+                                                     FrameworkName.end());
+    if (Dir == 0) return 0;
+
+    // Otherwise, if it does, remember that this is the right direntry for this
+    // framework.
+    CacheLookup.setValue(Dir);
+  }
+
+  const FileEntry *FE = 0;
+
+  // Check ".../Frameworks/HIToolbox.framework/Headers/HIToolbox.h"
+  llvm::SmallString<1024> HeadersFilename(FrameworkName);
+  HeadersFilename += "Headers/";
+  HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end());
+  if (!(FE = FileMgr.getFile(HeadersFilename.begin(),
+                             HeadersFilename.end()))) {
+
+    // Check ".../Frameworks/HIToolbox.framework/PrivateHeaders/HIToolbox.h"
+    HeadersFilename = FrameworkName;
+    HeadersFilename += "PrivateHeaders/";
+    HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end());
+    if (!(FE = FileMgr.getFile(HeadersFilename.begin(), HeadersFilename.end())))
+      return 0;
+  }
+
+  // This file is a system header or C++ unfriendly if the old file is.
+  //
+  // Note that the temporary 'DirInfo' is required here, as either call to
+  // getFileInfo could resize the vector and we don't want to rely on order
+  // of evaluation.
+  unsigned DirInfo = getFileInfo(ContextFileEnt).DirInfo;
+  getFileInfo(FE).DirInfo = DirInfo;
+  return FE;
+}
+
+//===----------------------------------------------------------------------===//
+// File Info Management.
+//===----------------------------------------------------------------------===//
+
+
+/// getFileInfo - Return the HeaderFileInfo structure for the specified
+/// FileEntry.
+HeaderFileInfo &HeaderSearch::getFileInfo(const FileEntry *FE) {
+  if (FE->getUID() >= FileInfo.size())
+    FileInfo.resize(FE->getUID()+1);
+  return FileInfo[FE->getUID()];
+}
+
+void HeaderSearch::setHeaderFileInfoForUID(HeaderFileInfo HFI, unsigned UID) {
+  if (UID >= FileInfo.size())
+    FileInfo.resize(UID+1);
+  FileInfo[UID] = HFI;
+}
+
+/// ShouldEnterIncludeFile - Mark the specified file as a target of of a
+/// #include, #include_next, or #import directive.  Return false if #including
+/// the file will have no effect or true if we should include it.
+bool HeaderSearch::ShouldEnterIncludeFile(const FileEntry *File, bool isImport){
+  ++NumIncluded; // Count # of attempted #includes.
+
+  // Get information about this file.
+  HeaderFileInfo &FileInfo = getFileInfo(File);
+
+  // If this is a #import directive, check that we have not already imported
+  // this header.
+  if (isImport) {
+    // If this has already been imported, don't import it again.
+    FileInfo.isImport = true;
+
+    // Has this already been #import'ed or #include'd?
+    if (FileInfo.NumIncludes) return false;
+  } else {
+    // Otherwise, if this is a #include of a file that was previously #import'd
+    // or if this is the second #include of a #pragma once file, ignore it.
+    if (FileInfo.isImport)
+      return false;
+  }
+
+  // Next, check to see if the file is wrapped with #ifndef guards.  If so, and
+  // if the macro that guards it is defined, we know the #include has no effect.
+  if (const IdentifierInfo *ControllingMacro
+      = FileInfo.getControllingMacro(ExternalLookup))
+    if (ControllingMacro->hasMacroDefinition()) {
+      ++NumMultiIncludeFileOptzn;
+      return false;
+    }
+
+  // Increment the number of times this file has been included.
+  ++FileInfo.NumIncludes;
+
+  return true;
+}
+
+
diff --git a/lib/Lex/Lexer.cpp b/lib/Lex/Lexer.cpp
new file mode 100644
index 0000000..74e8d74
--- /dev/null
+++ b/lib/Lex/Lexer.cpp
@@ -0,0 +1,2064 @@
+//===--- Lexer.cpp - C Language Family Lexer ------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements the Lexer and Token interfaces.
+//
+//===----------------------------------------------------------------------===//
+//
+// TODO: GCC Diagnostics emitted by the lexer:
+// PEDWARN: (form feed|vertical tab) in preprocessing directive
+//
+// Universal characters, unicode, char mapping:
+// WARNING: `%.*s' is not in NFKC
+// WARNING: `%.*s' is not in NFC
+//
+// Other:
+// TODO: Options to support:
+//    -fexec-charset,-fwide-exec-charset
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Lex/Lexer.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Lex/LexDiagnostic.h"
+#include "clang/Basic/SourceManager.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include <cctype>
+using namespace clang;
+
+static void InitCharacterInfo();
+
+//===----------------------------------------------------------------------===//
+// Token Class Implementation
+//===----------------------------------------------------------------------===//
+
+/// isObjCAtKeyword - Return true if we have an ObjC keyword identifier.
+bool Token::isObjCAtKeyword(tok::ObjCKeywordKind objcKey) const {
+  if (IdentifierInfo *II = getIdentifierInfo())
+    return II->getObjCKeywordID() == objcKey;
+  return false;
+}
+
+/// getObjCKeywordID - Return the ObjC keyword kind.
+tok::ObjCKeywordKind Token::getObjCKeywordID() const {
+  IdentifierInfo *specId = getIdentifierInfo();
+  return specId ? specId->getObjCKeywordID() : tok::objc_not_keyword;
+}
+
+
+//===----------------------------------------------------------------------===//
+// Lexer Class Implementation
+//===----------------------------------------------------------------------===//
+
+void Lexer::InitLexer(const char *BufStart, const char *BufPtr,
+                      const char *BufEnd) {
+  InitCharacterInfo();
+
+  BufferStart = BufStart;
+  BufferPtr = BufPtr;
+  BufferEnd = BufEnd;
+
+  assert(BufEnd[0] == 0 &&
+         "We assume that the input buffer has a null character at the end"
+         " to simplify lexing!");
+
+  Is_PragmaLexer = false;
+  IsInConflictMarker = false;
+  
+  // Start of the file is a start of line.
+  IsAtStartOfLine = true;
+
+  // We are not after parsing a #.
+  ParsingPreprocessorDirective = false;
+
+  // We are not after parsing #include.
+  ParsingFilename = false;
+
+  // We are not in raw mode.  Raw mode disables diagnostics and interpretation
+  // of tokens (e.g. identifiers, thus disabling macro expansion).  It is used
+  // to quickly lex the tokens of the buffer, e.g. when handling a "#if 0" block
+  // or otherwise skipping over tokens.
+  LexingRawMode = false;
+
+  // Default to not keeping comments.
+  ExtendedTokenMode = 0;
+}
+
+/// Lexer constructor - Create a new lexer object for the specified buffer
+/// with the specified preprocessor managing the lexing process.  This lexer
+/// assumes that the associated file buffer and Preprocessor objects will
+/// outlive it, so it doesn't take ownership of either of them.
+Lexer::Lexer(FileID FID, const llvm::MemoryBuffer *InputFile, Preprocessor &PP)
+  : PreprocessorLexer(&PP, FID),
+    FileLoc(PP.getSourceManager().getLocForStartOfFile(FID)),
+    Features(PP.getLangOptions()) {
+
+  InitLexer(InputFile->getBufferStart(), InputFile->getBufferStart(),
+            InputFile->getBufferEnd());
+
+  // Default to keeping comments if the preprocessor wants them.
+  SetCommentRetentionState(PP.getCommentRetentionState());
+}
+
+/// Lexer constructor - Create a new raw lexer object.  This object is only
+/// suitable for calls to 'LexRawToken'.  This lexer assumes that the text
+/// range will outlive it, so it doesn't take ownership of it.
+Lexer::Lexer(SourceLocation fileloc, const LangOptions &features,
+             const char *BufStart, const char *BufPtr, const char *BufEnd)
+  : FileLoc(fileloc), Features(features) {
+
+  InitLexer(BufStart, BufPtr, BufEnd);
+
+  // We *are* in raw mode.
+  LexingRawMode = true;
+}
+
+/// Lexer constructor - Create a new raw lexer object.  This object is only
+/// suitable for calls to 'LexRawToken'.  This lexer assumes that the text
+/// range will outlive it, so it doesn't take ownership of it.
+Lexer::Lexer(FileID FID, const llvm::MemoryBuffer *FromFile,
+             const SourceManager &SM, const LangOptions &features)
+  : FileLoc(SM.getLocForStartOfFile(FID)), Features(features) {
+
+  InitLexer(FromFile->getBufferStart(), FromFile->getBufferStart(),
+            FromFile->getBufferEnd());
+
+  // We *are* in raw mode.
+  LexingRawMode = true;
+}
+
+/// Create_PragmaLexer: Lexer constructor - Create a new lexer object for
+/// _Pragma expansion.  This has a variety of magic semantics that this method
+/// sets up.  It returns a new'd Lexer that must be delete'd when done.
+///
+/// On entrance to this routine, TokStartLoc is a macro location which has a
+/// spelling loc that indicates the bytes to be lexed for the token and an
+/// instantiation location that indicates where all lexed tokens should be
+/// "expanded from".
+///
+/// FIXME: It would really be nice to make _Pragma just be a wrapper around a
+/// normal lexer that remaps tokens as they fly by.  This would require making
+/// Preprocessor::Lex virtual.  Given that, we could just dump in a magic lexer
+/// interface that could handle this stuff.  This would pull GetMappedTokenLoc
+/// out of the critical path of the lexer!
+///
+Lexer *Lexer::Create_PragmaLexer(SourceLocation SpellingLoc,
+                                 SourceLocation InstantiationLocStart,
+                                 SourceLocation InstantiationLocEnd,
+                                 unsigned TokLen, Preprocessor &PP) {
+  SourceManager &SM = PP.getSourceManager();
+
+  // Create the lexer as if we were going to lex the file normally.
+  FileID SpellingFID = SM.getFileID(SpellingLoc);
+  const llvm::MemoryBuffer *InputFile = SM.getBuffer(SpellingFID);
+  Lexer *L = new Lexer(SpellingFID, InputFile, PP);
+
+  // Now that the lexer is created, change the start/end locations so that we
+  // just lex the subsection of the file that we want.  This is lexing from a
+  // scratch buffer.
+  const char *StrData = SM.getCharacterData(SpellingLoc);
+
+  L->BufferPtr = StrData;
+  L->BufferEnd = StrData+TokLen;
+  assert(L->BufferEnd[0] == 0 && "Buffer is not nul terminated!");
+
+  // Set the SourceLocation with the remapping information.  This ensures that
+  // GetMappedTokenLoc will remap the tokens as they are lexed.
+  L->FileLoc = SM.createInstantiationLoc(SM.getLocForStartOfFile(SpellingFID),
+                                         InstantiationLocStart,
+                                         InstantiationLocEnd, TokLen);
+
+  // Ensure that the lexer thinks it is inside a directive, so that end \n will
+  // return an EOM token.
+  L->ParsingPreprocessorDirective = true;
+
+  // This lexer really is for _Pragma.
+  L->Is_PragmaLexer = true;
+  return L;
+}
+
+
+/// Stringify - Convert the specified string into a C string, with surrounding
+/// ""'s, and with escaped \ and " characters.
+std::string Lexer::Stringify(const std::string &Str, bool Charify) {
+  std::string Result = Str;
+  char Quote = Charify ? '\'' : '"';
+  for (unsigned i = 0, e = Result.size(); i != e; ++i) {
+    if (Result[i] == '\\' || Result[i] == Quote) {
+      Result.insert(Result.begin()+i, '\\');
+      ++i; ++e;
+    }
+  }
+  return Result;
+}
+
+/// Stringify - Convert the specified string into a C string by escaping '\'
+/// and " characters.  This does not add surrounding ""'s to the string.
+void Lexer::Stringify(llvm::SmallVectorImpl<char> &Str) {
+  for (unsigned i = 0, e = Str.size(); i != e; ++i) {
+    if (Str[i] == '\\' || Str[i] == '"') {
+      Str.insert(Str.begin()+i, '\\');
+      ++i; ++e;
+    }
+  }
+}
+
+static bool isWhitespace(unsigned char c);
+
+/// MeasureTokenLength - Relex the token at the specified location and return
+/// its length in bytes in the input file.  If the token needs cleaning (e.g.
+/// includes a trigraph or an escaped newline) then this count includes bytes
+/// that are part of that.
+unsigned Lexer::MeasureTokenLength(SourceLocation Loc,
+                                   const SourceManager &SM,
+                                   const LangOptions &LangOpts) {
+  // TODO: this could be special cased for common tokens like identifiers, ')',
+  // etc to make this faster, if it mattered.  Just look at StrData[0] to handle
+  // all obviously single-char tokens.  This could use
+  // Lexer::isObviouslySimpleCharacter for example to handle identifiers or
+  // something.
+
+  // If this comes from a macro expansion, we really do want the macro name, not
+  // the token this macro expanded to.
+  Loc = SM.getInstantiationLoc(Loc);
+  std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Loc);
+  bool Invalid = false;
+  llvm::StringRef Buffer = SM.getBufferData(LocInfo.first, &Invalid);
+  if (Invalid)
+    return 0;
+
+  const char *StrData = Buffer.data()+LocInfo.second;
+
+  if (isWhitespace(StrData[0]))
+    return 0;
+
+  // Create a lexer starting at the beginning of this token.
+  Lexer TheLexer(Loc, LangOpts, Buffer.begin(), StrData, Buffer.end());
+  TheLexer.SetCommentRetentionState(true);
+  Token TheTok;
+  TheLexer.LexFromRawLexer(TheTok);
+  return TheTok.getLength();
+}
+
+//===----------------------------------------------------------------------===//
+// Character information.
+//===----------------------------------------------------------------------===//
+
+enum {
+  CHAR_HORZ_WS  = 0x01,  // ' ', '\t', '\f', '\v'.  Note, no '\0'
+  CHAR_VERT_WS  = 0x02,  // '\r', '\n'
+  CHAR_LETTER   = 0x04,  // a-z,A-Z
+  CHAR_NUMBER   = 0x08,  // 0-9
+  CHAR_UNDER    = 0x10,  // _
+  CHAR_PERIOD   = 0x20   // .
+};
+
+// Statically initialize CharInfo table based on ASCII character set
+// Reference: FreeBSD 7.2 /usr/share/misc/ascii
+static const unsigned char CharInfo[256] =
+{
+// 0 NUL         1 SOH         2 STX         3 ETX
+// 4 EOT         5 ENQ         6 ACK         7 BEL
+   0           , 0           , 0           , 0           ,
+   0           , 0           , 0           , 0           ,
+// 8 BS          9 HT         10 NL         11 VT
+//12 NP         13 CR         14 SO         15 SI
+   0           , CHAR_HORZ_WS, CHAR_VERT_WS, CHAR_HORZ_WS,
+   CHAR_HORZ_WS, CHAR_VERT_WS, 0           , 0           ,
+//16 DLE        17 DC1        18 DC2        19 DC3
+//20 DC4        21 NAK        22 SYN        23 ETB
+   0           , 0           , 0           , 0           ,
+   0           , 0           , 0           , 0           ,
+//24 CAN        25 EM         26 SUB        27 ESC
+//28 FS         29 GS         30 RS         31 US
+   0           , 0           , 0           , 0           ,
+   0           , 0           , 0           , 0           ,
+//32 SP         33  !         34  "         35  #
+//36  $         37  %         38  &         39  '
+   CHAR_HORZ_WS, 0           , 0           , 0           ,
+   0           , 0           , 0           , 0           ,
+//40  (         41  )         42  *         43  +
+//44  ,         45  -         46  .         47  /
+   0           , 0           , 0           , 0           ,
+   0           , 0           , CHAR_PERIOD , 0           ,
+//48  0         49  1         50  2         51  3
+//52  4         53  5         54  6         55  7
+   CHAR_NUMBER , CHAR_NUMBER , CHAR_NUMBER , CHAR_NUMBER ,
+   CHAR_NUMBER , CHAR_NUMBER , CHAR_NUMBER , CHAR_NUMBER ,
+//56  8         57  9         58  :         59  ;
+//60  <         61  =         62  >         63  ?
+   CHAR_NUMBER , CHAR_NUMBER , 0           , 0           ,
+   0           , 0           , 0           , 0           ,
+//64  @         65  A         66  B         67  C
+//68  D         69  E         70  F         71  G
+   0           , CHAR_LETTER , CHAR_LETTER , CHAR_LETTER ,
+   CHAR_LETTER , CHAR_LETTER , CHAR_LETTER , CHAR_LETTER ,
+//72  H         73  I         74  J         75  K
+//76  L         77  M         78  N         79  O
+   CHAR_LETTER , CHAR_LETTER , CHAR_LETTER , CHAR_LETTER ,
+   CHAR_LETTER , CHAR_LETTER , CHAR_LETTER , CHAR_LETTER ,
+//80  P         81  Q         82  R         83  S
+//84  T         85  U         86  V         87  W
+   CHAR_LETTER , CHAR_LETTER , CHAR_LETTER , CHAR_LETTER ,
+   CHAR_LETTER , CHAR_LETTER , CHAR_LETTER , CHAR_LETTER ,
+//88  X         89  Y         90  Z         91  [
+//92  \         93  ]         94  ^         95  _
+   CHAR_LETTER , CHAR_LETTER , CHAR_LETTER , 0           ,
+   0           , 0           , 0           , CHAR_UNDER  ,
+//96  `         97  a         98  b         99  c
+//100  d       101  e        102  f        103  g
+   0           , CHAR_LETTER , CHAR_LETTER , CHAR_LETTER ,
+   CHAR_LETTER , CHAR_LETTER , CHAR_LETTER , CHAR_LETTER ,
+//104  h       105  i        106  j        107  k
+//108  l       109  m        110  n        111  o
+   CHAR_LETTER , CHAR_LETTER , CHAR_LETTER , CHAR_LETTER ,
+   CHAR_LETTER , CHAR_LETTER , CHAR_LETTER , CHAR_LETTER ,
+//112  p       113  q        114  r        115  s
+//116  t       117  u        118  v        119  w
+   CHAR_LETTER , CHAR_LETTER , CHAR_LETTER , CHAR_LETTER ,
+   CHAR_LETTER , CHAR_LETTER , CHAR_LETTER , CHAR_LETTER ,
+//120  x       121  y        122  z        123  {
+//124  |        125  }        126  ~        127 DEL
+   CHAR_LETTER , CHAR_LETTER , CHAR_LETTER , 0           ,
+   0           , 0           , 0           , 0
+};
+
+static void InitCharacterInfo() {
+  static bool isInited = false;
+  if (isInited) return;
+  // check the statically-initialized CharInfo table
+  assert(CHAR_HORZ_WS == CharInfo[(int)' ']);
+  assert(CHAR_HORZ_WS == CharInfo[(int)'\t']);
+  assert(CHAR_HORZ_WS == CharInfo[(int)'\f']);
+  assert(CHAR_HORZ_WS == CharInfo[(int)'\v']);
+  assert(CHAR_VERT_WS == CharInfo[(int)'\n']);
+  assert(CHAR_VERT_WS == CharInfo[(int)'\r']);
+  assert(CHAR_UNDER   == CharInfo[(int)'_']);
+  assert(CHAR_PERIOD  == CharInfo[(int)'.']);
+  for (unsigned i = 'a'; i <= 'z'; ++i) {
+    assert(CHAR_LETTER == CharInfo[i]);
+    assert(CHAR_LETTER == CharInfo[i+'A'-'a']);
+  }
+  for (unsigned i = '0'; i <= '9'; ++i)
+    assert(CHAR_NUMBER == CharInfo[i]);
+    
+  isInited = true;
+}
+
+
+/// isIdentifierBody - Return true if this is the body character of an
+/// identifier, which is [a-zA-Z0-9_].
+static inline bool isIdentifierBody(unsigned char c) {
+  return (CharInfo[c] & (CHAR_LETTER|CHAR_NUMBER|CHAR_UNDER)) ? true : false;
+}
+
+/// isHorizontalWhitespace - Return true if this character is horizontal
+/// whitespace: ' ', '\t', '\f', '\v'.  Note that this returns false for '\0'.
+static inline bool isHorizontalWhitespace(unsigned char c) {
+  return (CharInfo[c] & CHAR_HORZ_WS) ? true : false;
+}
+
+/// isWhitespace - Return true if this character is horizontal or vertical
+/// whitespace: ' ', '\t', '\f', '\v', '\n', '\r'.  Note that this returns false
+/// for '\0'.
+static inline bool isWhitespace(unsigned char c) {
+  return (CharInfo[c] & (CHAR_HORZ_WS|CHAR_VERT_WS)) ? true : false;
+}
+
+/// isNumberBody - Return true if this is the body character of an
+/// preprocessing number, which is [a-zA-Z0-9_.].
+static inline bool isNumberBody(unsigned char c) {
+  return (CharInfo[c] & (CHAR_LETTER|CHAR_NUMBER|CHAR_UNDER|CHAR_PERIOD)) ?
+    true : false;
+}
+
+
+//===----------------------------------------------------------------------===//
+// Diagnostics forwarding code.
+//===----------------------------------------------------------------------===//
+
+/// GetMappedTokenLoc - If lexing out of a 'mapped buffer', where we pretend the
+/// lexer buffer was all instantiated at a single point, perform the mapping.
+/// This is currently only used for _Pragma implementation, so it is the slow
+/// path of the hot getSourceLocation method.  Do not allow it to be inlined.
+static DISABLE_INLINE SourceLocation GetMappedTokenLoc(Preprocessor &PP,
+                                                       SourceLocation FileLoc,
+                                                       unsigned CharNo,
+                                                       unsigned TokLen);
+static SourceLocation GetMappedTokenLoc(Preprocessor &PP,
+                                        SourceLocation FileLoc,
+                                        unsigned CharNo, unsigned TokLen) {
+  assert(FileLoc.isMacroID() && "Must be an instantiation");
+
+  // Otherwise, we're lexing "mapped tokens".  This is used for things like
+  // _Pragma handling.  Combine the instantiation location of FileLoc with the
+  // spelling location.
+  SourceManager &SM = PP.getSourceManager();
+
+  // Create a new SLoc which is expanded from Instantiation(FileLoc) but whose
+  // characters come from spelling(FileLoc)+Offset.
+  SourceLocation SpellingLoc = SM.getSpellingLoc(FileLoc);
+  SpellingLoc = SpellingLoc.getFileLocWithOffset(CharNo);
+
+  // Figure out the expansion loc range, which is the range covered by the
+  // original _Pragma(...) sequence.
+  std::pair<SourceLocation,SourceLocation> II =
+    SM.getImmediateInstantiationRange(FileLoc);
+
+  return SM.createInstantiationLoc(SpellingLoc, II.first, II.second, TokLen);
+}
+
+/// getSourceLocation - Return a source location identifier for the specified
+/// offset in the current file.
+SourceLocation Lexer::getSourceLocation(const char *Loc,
+                                        unsigned TokLen) const {
+  assert(Loc >= BufferStart && Loc <= BufferEnd &&
+         "Location out of range for this buffer!");
+
+  // In the normal case, we're just lexing from a simple file buffer, return
+  // the file id from FileLoc with the offset specified.
+  unsigned CharNo = Loc-BufferStart;
+  if (FileLoc.isFileID())
+    return FileLoc.getFileLocWithOffset(CharNo);
+
+  // Otherwise, this is the _Pragma lexer case, which pretends that all of the
+  // tokens are lexed from where the _Pragma was defined.
+  assert(PP && "This doesn't work on raw lexers");
+  return GetMappedTokenLoc(*PP, FileLoc, CharNo, TokLen);
+}
+
+/// Diag - Forwarding function for diagnostics.  This translate a source
+/// position in the current buffer into a SourceLocation object for rendering.
+DiagnosticBuilder Lexer::Diag(const char *Loc, unsigned DiagID) const {
+  return PP->Diag(getSourceLocation(Loc), DiagID);
+}
+
+//===----------------------------------------------------------------------===//
+// Trigraph and Escaped Newline Handling Code.
+//===----------------------------------------------------------------------===//
+
+/// GetTrigraphCharForLetter - Given a character that occurs after a ?? pair,
+/// return the decoded trigraph letter it corresponds to, or '\0' if nothing.
+static char GetTrigraphCharForLetter(char Letter) {
+  switch (Letter) {
+  default:   return 0;
+  case '=':  return '#';
+  case ')':  return ']';
+  case '(':  return '[';
+  case '!':  return '|';
+  case '\'': return '^';
+  case '>':  return '}';
+  case '/':  return '\\';
+  case '<':  return '{';
+  case '-':  return '~';
+  }
+}
+
+/// DecodeTrigraphChar - If the specified character is a legal trigraph when
+/// prefixed with ??, emit a trigraph warning.  If trigraphs are enabled,
+/// return the result character.  Finally, emit a warning about trigraph use
+/// whether trigraphs are enabled or not.
+static char DecodeTrigraphChar(const char *CP, Lexer *L) {
+  char Res = GetTrigraphCharForLetter(*CP);
+  if (!Res || !L) return Res;
+
+  if (!L->getFeatures().Trigraphs) {
+    if (!L->isLexingRawMode())
+      L->Diag(CP-2, diag::trigraph_ignored);
+    return 0;
+  }
+
+  if (!L->isLexingRawMode())
+    L->Diag(CP-2, diag::trigraph_converted) << std::string()+Res;
+  return Res;
+}
+
+/// getEscapedNewLineSize - Return the size of the specified escaped newline,
+/// or 0 if it is not an escaped newline. P[-1] is known to be a "\" or a
+/// trigraph equivalent on entry to this function.
+unsigned Lexer::getEscapedNewLineSize(const char *Ptr) {
+  unsigned Size = 0;
+  while (isWhitespace(Ptr[Size])) {
+    ++Size;
+
+    if (Ptr[Size-1] != '\n' && Ptr[Size-1] != '\r')
+      continue;
+
+    // If this is a \r\n or \n\r, skip the other half.
+    if ((Ptr[Size] == '\r' || Ptr[Size] == '\n') &&
+        Ptr[Size-1] != Ptr[Size])
+      ++Size;
+
+    return Size;
+  }
+
+  // Not an escaped newline, must be a \t or something else.
+  return 0;
+}
+
+/// SkipEscapedNewLines - If P points to an escaped newline (or a series of
+/// them), skip over them and return the first non-escaped-newline found,
+/// otherwise return P.
+const char *Lexer::SkipEscapedNewLines(const char *P) {
+  while (1) {
+    const char *AfterEscape;
+    if (*P == '\\') {
+      AfterEscape = P+1;
+    } else if (*P == '?') {
+      // If not a trigraph for escape, bail out.
+      if (P[1] != '?' || P[2] != '/')
+        return P;
+      AfterEscape = P+3;
+    } else {
+      return P;
+    }
+
+    unsigned NewLineSize = Lexer::getEscapedNewLineSize(AfterEscape);
+    if (NewLineSize == 0) return P;
+    P = AfterEscape+NewLineSize;
+  }
+}
+
+
+/// getCharAndSizeSlow - Peek a single 'character' from the specified buffer,
+/// get its size, and return it.  This is tricky in several cases:
+///   1. If currently at the start of a trigraph, we warn about the trigraph,
+///      then either return the trigraph (skipping 3 chars) or the '?',
+///      depending on whether trigraphs are enabled or not.
+///   2. If this is an escaped newline (potentially with whitespace between
+///      the backslash and newline), implicitly skip the newline and return
+///      the char after it.
+///   3. If this is a UCN, return it.  FIXME: C++ UCN's?
+///
+/// This handles the slow/uncommon case of the getCharAndSize method.  Here we
+/// know that we can accumulate into Size, and that we have already incremented
+/// Ptr by Size bytes.
+///
+/// NOTE: When this method is updated, getCharAndSizeSlowNoWarn (below) should
+/// be updated to match.
+///
+char Lexer::getCharAndSizeSlow(const char *Ptr, unsigned &Size,
+                               Token *Tok) {
+  // If we have a slash, look for an escaped newline.
+  if (Ptr[0] == '\\') {
+    ++Size;
+    ++Ptr;
+Slash:
+    // Common case, backslash-char where the char is not whitespace.
+    if (!isWhitespace(Ptr[0])) return '\\';
+
+    // See if we have optional whitespace characters between the slash and
+    // newline.
+    if (unsigned EscapedNewLineSize = getEscapedNewLineSize(Ptr)) {
+      // Remember that this token needs to be cleaned.
+      if (Tok) Tok->setFlag(Token::NeedsCleaning);
+
+      // Warn if there was whitespace between the backslash and newline.
+      if (Ptr[0] != '\n' && Ptr[0] != '\r' && Tok && !isLexingRawMode())
+        Diag(Ptr, diag::backslash_newline_space);
+
+      // Found backslash<whitespace><newline>.  Parse the char after it.
+      Size += EscapedNewLineSize;
+      Ptr  += EscapedNewLineSize;
+      // Use slow version to accumulate a correct size field.
+      return getCharAndSizeSlow(Ptr, Size, Tok);
+    }
+
+    // Otherwise, this is not an escaped newline, just return the slash.
+    return '\\';
+  }
+
+  // If this is a trigraph, process it.
+  if (Ptr[0] == '?' && Ptr[1] == '?') {
+    // If this is actually a legal trigraph (not something like "??x"), emit
+    // a trigraph warning.  If so, and if trigraphs are enabled, return it.
+    if (char C = DecodeTrigraphChar(Ptr+2, Tok ? this : 0)) {
+      // Remember that this token needs to be cleaned.
+      if (Tok) Tok->setFlag(Token::NeedsCleaning);
+
+      Ptr += 3;
+      Size += 3;
+      if (C == '\\') goto Slash;
+      return C;
+    }
+  }
+
+  // If this is neither, return a single character.
+  ++Size;
+  return *Ptr;
+}
+
+
+/// getCharAndSizeSlowNoWarn - Handle the slow/uncommon case of the
+/// getCharAndSizeNoWarn method.  Here we know that we can accumulate into Size,
+/// and that we have already incremented Ptr by Size bytes.
+///
+/// NOTE: When this method is updated, getCharAndSizeSlow (above) should
+/// be updated to match.
+char Lexer::getCharAndSizeSlowNoWarn(const char *Ptr, unsigned &Size,
+                                     const LangOptions &Features) {
+  // If we have a slash, look for an escaped newline.
+  if (Ptr[0] == '\\') {
+    ++Size;
+    ++Ptr;
+Slash:
+    // Common case, backslash-char where the char is not whitespace.
+    if (!isWhitespace(Ptr[0])) return '\\';
+
+    // See if we have optional whitespace characters followed by a newline.
+    if (unsigned EscapedNewLineSize = getEscapedNewLineSize(Ptr)) {
+      // Found backslash<whitespace><newline>.  Parse the char after it.
+      Size += EscapedNewLineSize;
+      Ptr  += EscapedNewLineSize;
+
+      // Use slow version to accumulate a correct size field.
+      return getCharAndSizeSlowNoWarn(Ptr, Size, Features);
+    }
+
+    // Otherwise, this is not an escaped newline, just return the slash.
+    return '\\';
+  }
+
+  // If this is a trigraph, process it.
+  if (Features.Trigraphs && Ptr[0] == '?' && Ptr[1] == '?') {
+    // If this is actually a legal trigraph (not something like "??x"), return
+    // it.
+    if (char C = GetTrigraphCharForLetter(Ptr[2])) {
+      Ptr += 3;
+      Size += 3;
+      if (C == '\\') goto Slash;
+      return C;
+    }
+  }
+
+  // If this is neither, return a single character.
+  ++Size;
+  return *Ptr;
+}
+
+//===----------------------------------------------------------------------===//
+// Helper methods for lexing.
+//===----------------------------------------------------------------------===//
+
+void Lexer::LexIdentifier(Token &Result, const char *CurPtr) {
+  // Match [_A-Za-z0-9]*, we have already matched [_A-Za-z$]
+  unsigned Size;
+  unsigned char C = *CurPtr++;
+  while (isIdentifierBody(C))
+    C = *CurPtr++;
+
+  --CurPtr;   // Back up over the skipped character.
+
+  // Fast path, no $,\,? in identifier found.  '\' might be an escaped newline
+  // or UCN, and ? might be a trigraph for '\', an escaped newline or UCN.
+  // FIXME: UCNs.
+  //
+  // TODO: Could merge these checks into a CharInfo flag to make the comparison
+  // cheaper
+  if (C != '\\' && C != '?' && (C != '$' || !Features.DollarIdents)) {
+FinishIdentifier:
+    const char *IdStart = BufferPtr;
+    FormTokenWithChars(Result, CurPtr, tok::identifier);
+
+    // If we are in raw mode, return this identifier raw.  There is no need to
+    // look up identifier information or attempt to macro expand it.
+    if (LexingRawMode) return;
+
+    // Fill in Result.IdentifierInfo, looking up the identifier in the
+    // identifier table.
+    IdentifierInfo *II = PP->LookUpIdentifierInfo(Result, IdStart);
+
+    // Change the kind of this identifier to the appropriate token kind, e.g.
+    // turning "for" into a keyword.
+    Result.setKind(II->getTokenID());
+
+    // Finally, now that we know we have an identifier, pass this off to the
+    // preprocessor, which may macro expand it or something.
+    if (II->isHandleIdentifierCase())
+      PP->HandleIdentifier(Result);
+    return;
+  }
+
+  // Otherwise, $,\,? in identifier found.  Enter slower path.
+
+  C = getCharAndSize(CurPtr, Size);
+  while (1) {
+    if (C == '$') {
+      // If we hit a $ and they are not supported in identifiers, we are done.
+      if (!Features.DollarIdents) goto FinishIdentifier;
+
+      // Otherwise, emit a diagnostic and continue.
+      if (!isLexingRawMode())
+        Diag(CurPtr, diag::ext_dollar_in_identifier);
+      CurPtr = ConsumeChar(CurPtr, Size, Result);
+      C = getCharAndSize(CurPtr, Size);
+      continue;
+    } else if (!isIdentifierBody(C)) { // FIXME: UCNs.
+      // Found end of identifier.
+      goto FinishIdentifier;
+    }
+
+    // Otherwise, this character is good, consume it.
+    CurPtr = ConsumeChar(CurPtr, Size, Result);
+
+    C = getCharAndSize(CurPtr, Size);
+    while (isIdentifierBody(C)) { // FIXME: UCNs.
+      CurPtr = ConsumeChar(CurPtr, Size, Result);
+      C = getCharAndSize(CurPtr, Size);
+    }
+  }
+}
+
+
+/// LexNumericConstant - Lex the remainder of a integer or floating point
+/// constant. From[-1] is the first character lexed.  Return the end of the
+/// constant.
+void Lexer::LexNumericConstant(Token &Result, const char *CurPtr) {
+  unsigned Size;
+  char C = getCharAndSize(CurPtr, Size);
+  char PrevCh = 0;
+  while (isNumberBody(C)) { // FIXME: UCNs?
+    CurPtr = ConsumeChar(CurPtr, Size, Result);
+    PrevCh = C;
+    C = getCharAndSize(CurPtr, Size);
+  }
+
+  // If we fell out, check for a sign, due to 1e+12.  If we have one, continue.
+  if ((C == '-' || C == '+') && (PrevCh == 'E' || PrevCh == 'e'))
+    return LexNumericConstant(Result, ConsumeChar(CurPtr, Size, Result));
+
+  // If we have a hex FP constant, continue.
+  if ((C == '-' || C == '+') && (PrevCh == 'P' || PrevCh == 'p') &&
+      (!PP || !PP->getLangOptions().CPlusPlus0x))
+    return LexNumericConstant(Result, ConsumeChar(CurPtr, Size, Result));
+
+  // Update the location of token as well as BufferPtr.
+  const char *TokStart = BufferPtr;
+  FormTokenWithChars(Result, CurPtr, tok::numeric_constant);
+  Result.setLiteralData(TokStart);
+}
+
+/// LexStringLiteral - Lex the remainder of a string literal, after having lexed
+/// either " or L".
+void Lexer::LexStringLiteral(Token &Result, const char *CurPtr, bool Wide) {
+  const char *NulCharacter = 0; // Does this string contain the \0 character?
+
+  char C = getAndAdvanceChar(CurPtr, Result);
+  while (C != '"') {
+    // Skip escaped characters.
+    if (C == '\\') {
+      // Skip the escaped character.
+      C = getAndAdvanceChar(CurPtr, Result);
+    } else if (C == '\n' || C == '\r' ||             // Newline.
+               (C == 0 && CurPtr-1 == BufferEnd)) {  // End of file.
+      if (!isLexingRawMode() && !Features.AsmPreprocessor)
+        Diag(BufferPtr, diag::err_unterminated_string);
+      FormTokenWithChars(Result, CurPtr-1, tok::unknown);
+      return;
+    } else if (C == 0) {
+      NulCharacter = CurPtr-1;
+    }
+    C = getAndAdvanceChar(CurPtr, Result);
+  }
+
+  // If a nul character existed in the string, warn about it.
+  if (NulCharacter && !isLexingRawMode())
+    Diag(NulCharacter, diag::null_in_string);
+
+  // Update the location of the token as well as the BufferPtr instance var.
+  const char *TokStart = BufferPtr;
+  FormTokenWithChars(Result, CurPtr,
+                     Wide ? tok::wide_string_literal : tok::string_literal);
+  Result.setLiteralData(TokStart);
+}
+
+/// LexAngledStringLiteral - Lex the remainder of an angled string literal,
+/// after having lexed the '<' character.  This is used for #include filenames.
+void Lexer::LexAngledStringLiteral(Token &Result, const char *CurPtr) {
+  const char *NulCharacter = 0; // Does this string contain the \0 character?
+  const char *AfterLessPos = CurPtr;
+  char C = getAndAdvanceChar(CurPtr, Result);
+  while (C != '>') {
+    // Skip escaped characters.
+    if (C == '\\') {
+      // Skip the escaped character.
+      C = getAndAdvanceChar(CurPtr, Result);
+    } else if (C == '\n' || C == '\r' ||             // Newline.
+               (C == 0 && CurPtr-1 == BufferEnd)) {  // End of file.
+      // If the filename is unterminated, then it must just be a lone <
+      // character.  Return this as such.
+      FormTokenWithChars(Result, AfterLessPos, tok::less);
+      return;
+    } else if (C == 0) {
+      NulCharacter = CurPtr-1;
+    }
+    C = getAndAdvanceChar(CurPtr, Result);
+  }
+
+  // If a nul character existed in the string, warn about it.
+  if (NulCharacter && !isLexingRawMode())
+    Diag(NulCharacter, diag::null_in_string);
+
+  // Update the location of token as well as BufferPtr.
+  const char *TokStart = BufferPtr;
+  FormTokenWithChars(Result, CurPtr, tok::angle_string_literal);
+  Result.setLiteralData(TokStart);
+}
+
+
+/// LexCharConstant - Lex the remainder of a character constant, after having
+/// lexed either ' or L'.
+void Lexer::LexCharConstant(Token &Result, const char *CurPtr) {
+  const char *NulCharacter = 0; // Does this character contain the \0 character?
+
+  // Handle the common case of 'x' and '\y' efficiently.
+  char C = getAndAdvanceChar(CurPtr, Result);
+  if (C == '\'') {
+    if (!isLexingRawMode() && !Features.AsmPreprocessor)
+      Diag(BufferPtr, diag::err_empty_character);
+    FormTokenWithChars(Result, CurPtr, tok::unknown);
+    return;
+  } else if (C == '\\') {
+    // Skip the escaped character.
+    // FIXME: UCN's.
+    C = getAndAdvanceChar(CurPtr, Result);
+  }
+
+  if (C && C != '\n' && C != '\r' && CurPtr[0] == '\'') {
+    ++CurPtr;
+  } else {
+    // Fall back on generic code for embedded nulls, newlines, wide chars.
+    do {
+      // Skip escaped characters.
+      if (C == '\\') {
+        // Skip the escaped character.
+        C = getAndAdvanceChar(CurPtr, Result);
+      } else if (C == '\n' || C == '\r' ||               // Newline.
+                 (C == 0 && CurPtr-1 == BufferEnd)) {    // End of file.
+        if (!isLexingRawMode() && !Features.AsmPreprocessor)
+          Diag(BufferPtr, diag::err_unterminated_char);
+        FormTokenWithChars(Result, CurPtr-1, tok::unknown);
+        return;
+      } else if (C == 0) {
+        NulCharacter = CurPtr-1;
+      }
+      C = getAndAdvanceChar(CurPtr, Result);
+    } while (C != '\'');
+  }
+
+  if (NulCharacter && !isLexingRawMode())
+    Diag(NulCharacter, diag::null_in_char);
+
+  // Update the location of token as well as BufferPtr.
+  const char *TokStart = BufferPtr;
+  FormTokenWithChars(Result, CurPtr, tok::char_constant);
+  Result.setLiteralData(TokStart);
+}
+
+/// SkipWhitespace - Efficiently skip over a series of whitespace characters.
+/// Update BufferPtr to point to the next non-whitespace character and return.
+///
+/// This method forms a token and returns true if KeepWhitespaceMode is enabled.
+///
+bool Lexer::SkipWhitespace(Token &Result, const char *CurPtr) {
+  // Whitespace - Skip it, then return the token after the whitespace.
+  unsigned char Char = *CurPtr;  // Skip consequtive spaces efficiently.
+  while (1) {
+    // Skip horizontal whitespace very aggressively.
+    while (isHorizontalWhitespace(Char))
+      Char = *++CurPtr;
+
+    // Otherwise if we have something other than whitespace, we're done.
+    if (Char != '\n' && Char != '\r')
+      break;
+
+    if (ParsingPreprocessorDirective) {
+      // End of preprocessor directive line, let LexTokenInternal handle this.
+      BufferPtr = CurPtr;
+      return false;
+    }
+
+    // ok, but handle newline.
+    // The returned token is at the start of the line.
+    Result.setFlag(Token::StartOfLine);
+    // No leading whitespace seen so far.
+    Result.clearFlag(Token::LeadingSpace);
+    Char = *++CurPtr;
+  }
+
+  // If this isn't immediately after a newline, there is leading space.
+  char PrevChar = CurPtr[-1];
+  if (PrevChar != '\n' && PrevChar != '\r')
+    Result.setFlag(Token::LeadingSpace);
+
+  // If the client wants us to return whitespace, return it now.
+  if (isKeepWhitespaceMode()) {
+    FormTokenWithChars(Result, CurPtr, tok::unknown);
+    return true;
+  }
+
+  BufferPtr = CurPtr;
+  return false;
+}
+
+// SkipBCPLComment - We have just read the // characters from input.  Skip until
+// we find the newline character thats terminate the comment.  Then update
+/// BufferPtr and return.
+///
+/// If we're in KeepCommentMode or any CommentHandler has inserted
+/// some tokens, this will store the first token and return true.
+bool Lexer::SkipBCPLComment(Token &Result, const char *CurPtr) {
+  // If BCPL comments aren't explicitly enabled for this language, emit an
+  // extension warning.
+  if (!Features.BCPLComment && !isLexingRawMode()) {
+    Diag(BufferPtr, diag::ext_bcpl_comment);
+
+    // Mark them enabled so we only emit one warning for this translation
+    // unit.
+    Features.BCPLComment = true;
+  }
+
+  // Scan over the body of the comment.  The common case, when scanning, is that
+  // the comment contains normal ascii characters with nothing interesting in
+  // them.  As such, optimize for this case with the inner loop.
+  char C;
+  do {
+    C = *CurPtr;
+    // FIXME: Speedup BCPL comment lexing.  Just scan for a \n or \r character.
+    // If we find a \n character, scan backwards, checking to see if it's an
+    // escaped newline, like we do for block comments.
+
+    // Skip over characters in the fast loop.
+    while (C != 0 &&                // Potentially EOF.
+           C != '\\' &&             // Potentially escaped newline.
+           C != '?' &&              // Potentially trigraph.
+           C != '\n' && C != '\r')  // Newline or DOS-style newline.
+      C = *++CurPtr;
+
+    // If this is a newline, we're done.
+    if (C == '\n' || C == '\r')
+      break;  // Found the newline? Break out!
+
+    // Otherwise, this is a hard case.  Fall back on getAndAdvanceChar to
+    // properly decode the character.  Read it in raw mode to avoid emitting
+    // diagnostics about things like trigraphs.  If we see an escaped newline,
+    // we'll handle it below.
+    const char *OldPtr = CurPtr;
+    bool OldRawMode = isLexingRawMode();
+    LexingRawMode = true;
+    C = getAndAdvanceChar(CurPtr, Result);
+    LexingRawMode = OldRawMode;
+
+    // If the char that we finally got was a \n, then we must have had something
+    // like \<newline><newline>.  We don't want to have consumed the second
+    // newline, we want CurPtr, to end up pointing to it down below.
+    if (C == '\n' || C == '\r') {
+      --CurPtr;
+      C = 'x'; // doesn't matter what this is.
+    }
+
+    // If we read multiple characters, and one of those characters was a \r or
+    // \n, then we had an escaped newline within the comment.  Emit diagnostic
+    // unless the next line is also a // comment.
+    if (CurPtr != OldPtr+1 && C != '/' && CurPtr[0] != '/') {
+      for (; OldPtr != CurPtr; ++OldPtr)
+        if (OldPtr[0] == '\n' || OldPtr[0] == '\r') {
+          // Okay, we found a // comment that ends in a newline, if the next
+          // line is also a // comment, but has spaces, don't emit a diagnostic.
+          if (isspace(C)) {
+            const char *ForwardPtr = CurPtr;
+            while (isspace(*ForwardPtr))  // Skip whitespace.
+              ++ForwardPtr;
+            if (ForwardPtr[0] == '/' && ForwardPtr[1] == '/')
+              break;
+          }
+
+          if (!isLexingRawMode())
+            Diag(OldPtr-1, diag::ext_multi_line_bcpl_comment);
+          break;
+        }
+    }
+
+    if (CurPtr == BufferEnd+1) { --CurPtr; break; }
+  } while (C != '\n' && C != '\r');
+
+  // Found but did not consume the newline.  Notify comment handlers about the
+  // comment unless we're in a #if 0 block.
+  if (PP && !isLexingRawMode() &&
+      PP->HandleComment(Result, SourceRange(getSourceLocation(BufferPtr),
+                                            getSourceLocation(CurPtr)))) {
+    BufferPtr = CurPtr;
+    return true; // A token has to be returned.
+  }
+
+  // If we are returning comments as tokens, return this comment as a token.
+  if (inKeepCommentMode())
+    return SaveBCPLComment(Result, CurPtr);
+
+  // If we are inside a preprocessor directive and we see the end of line,
+  // return immediately, so that the lexer can return this as an EOM token.
+  if (ParsingPreprocessorDirective || CurPtr == BufferEnd) {
+    BufferPtr = CurPtr;
+    return false;
+  }
+
+  // Otherwise, eat the \n character.  We don't care if this is a \n\r or
+  // \r\n sequence.  This is an efficiency hack (because we know the \n can't
+  // contribute to another token), it isn't needed for correctness.  Note that
+  // this is ok even in KeepWhitespaceMode, because we would have returned the
+  /// comment above in that mode.
+  ++CurPtr;
+
+  // The next returned token is at the start of the line.
+  Result.setFlag(Token::StartOfLine);
+  // No leading whitespace seen so far.
+  Result.clearFlag(Token::LeadingSpace);
+  BufferPtr = CurPtr;
+  return false;
+}
+
+/// SaveBCPLComment - If in save-comment mode, package up this BCPL comment in
+/// an appropriate way and return it.
+bool Lexer::SaveBCPLComment(Token &Result, const char *CurPtr) {
+  // If we're not in a preprocessor directive, just return the // comment
+  // directly.
+  FormTokenWithChars(Result, CurPtr, tok::comment);
+
+  if (!ParsingPreprocessorDirective)
+    return true;
+
+  // If this BCPL-style comment is in a macro definition, transmogrify it into
+  // a C-style block comment.
+  bool Invalid = false;
+  std::string Spelling = PP->getSpelling(Result, &Invalid);
+  if (Invalid)
+    return true;
+  
+  assert(Spelling[0] == '/' && Spelling[1] == '/' && "Not bcpl comment?");
+  Spelling[1] = '*';   // Change prefix to "/*".
+  Spelling += "*/";    // add suffix.
+
+  Result.setKind(tok::comment);
+  PP->CreateString(&Spelling[0], Spelling.size(), Result,
+                   Result.getLocation());
+  return true;
+}
+
+/// isBlockCommentEndOfEscapedNewLine - Return true if the specified newline
+/// character (either \n or \r) is part of an escaped newline sequence.  Issue a
+/// diagnostic if so.  We know that the newline is inside of a block comment.
+static bool isEndOfBlockCommentWithEscapedNewLine(const char *CurPtr,
+                                                  Lexer *L) {
+  assert(CurPtr[0] == '\n' || CurPtr[0] == '\r');
+
+  // Back up off the newline.
+  --CurPtr;
+
+  // If this is a two-character newline sequence, skip the other character.
+  if (CurPtr[0] == '\n' || CurPtr[0] == '\r') {
+    // \n\n or \r\r -> not escaped newline.
+    if (CurPtr[0] == CurPtr[1])
+      return false;
+    // \n\r or \r\n -> skip the newline.
+    --CurPtr;
+  }
+
+  // If we have horizontal whitespace, skip over it.  We allow whitespace
+  // between the slash and newline.
+  bool HasSpace = false;
+  while (isHorizontalWhitespace(*CurPtr) || *CurPtr == 0) {
+    --CurPtr;
+    HasSpace = true;
+  }
+
+  // If we have a slash, we know this is an escaped newline.
+  if (*CurPtr == '\\') {
+    if (CurPtr[-1] != '*') return false;
+  } else {
+    // It isn't a slash, is it the ?? / trigraph?
+    if (CurPtr[0] != '/' || CurPtr[-1] != '?' || CurPtr[-2] != '?' ||
+        CurPtr[-3] != '*')
+      return false;
+
+    // This is the trigraph ending the comment.  Emit a stern warning!
+    CurPtr -= 2;
+
+    // If no trigraphs are enabled, warn that we ignored this trigraph and
+    // ignore this * character.
+    if (!L->getFeatures().Trigraphs) {
+      if (!L->isLexingRawMode())
+        L->Diag(CurPtr, diag::trigraph_ignored_block_comment);
+      return false;
+    }
+    if (!L->isLexingRawMode())
+      L->Diag(CurPtr, diag::trigraph_ends_block_comment);
+  }
+
+  // Warn about having an escaped newline between the */ characters.
+  if (!L->isLexingRawMode())
+    L->Diag(CurPtr, diag::escaped_newline_block_comment_end);
+
+  // If there was space between the backslash and newline, warn about it.
+  if (HasSpace && !L->isLexingRawMode())
+    L->Diag(CurPtr, diag::backslash_newline_space);
+
+  return true;
+}
+
+#ifdef __SSE2__
+#include <emmintrin.h>
+#elif __ALTIVEC__
+#include <altivec.h>
+#undef bool
+#endif
+
+/// SkipBlockComment - We have just read the /* characters from input.  Read
+/// until we find the */ characters that terminate the comment.  Note that we
+/// don't bother decoding trigraphs or escaped newlines in block comments,
+/// because they cannot cause the comment to end.  The only thing that can
+/// happen is the comment could end with an escaped newline between the */ end
+/// of comment.
+///
+/// If we're in KeepCommentMode or any CommentHandler has inserted
+/// some tokens, this will store the first token and return true.
+bool Lexer::SkipBlockComment(Token &Result, const char *CurPtr) {
+  // Scan one character past where we should, looking for a '/' character.  Once
+  // we find it, check to see if it was preceeded by a *.  This common
+  // optimization helps people who like to put a lot of * characters in their
+  // comments.
+
+  // The first character we get with newlines and trigraphs skipped to handle
+  // the degenerate /*/ case below correctly if the * has an escaped newline
+  // after it.
+  unsigned CharSize;
+  unsigned char C = getCharAndSize(CurPtr, CharSize);
+  CurPtr += CharSize;
+  if (C == 0 && CurPtr == BufferEnd+1) {
+    if (!isLexingRawMode())
+      Diag(BufferPtr, diag::err_unterminated_block_comment);
+    --CurPtr;
+
+    // KeepWhitespaceMode should return this broken comment as a token.  Since
+    // it isn't a well formed comment, just return it as an 'unknown' token.
+    if (isKeepWhitespaceMode()) {
+      FormTokenWithChars(Result, CurPtr, tok::unknown);
+      return true;
+    }
+
+    BufferPtr = CurPtr;
+    return false;
+  }
+
+  // Check to see if the first character after the '/*' is another /.  If so,
+  // then this slash does not end the block comment, it is part of it.
+  if (C == '/')
+    C = *CurPtr++;
+
+  while (1) {
+    // Skip over all non-interesting characters until we find end of buffer or a
+    // (probably ending) '/' character.
+    if (CurPtr + 24 < BufferEnd) {
+      // While not aligned to a 16-byte boundary.
+      while (C != '/' && ((intptr_t)CurPtr & 0x0F) != 0)
+        C = *CurPtr++;
+
+      if (C == '/') goto FoundSlash;
+
+#ifdef __SSE2__
+      __m128i Slashes = _mm_set_epi8('/', '/', '/', '/', '/', '/', '/', '/',
+                                     '/', '/', '/', '/', '/', '/', '/', '/');
+      while (CurPtr+16 <= BufferEnd &&
+             _mm_movemask_epi8(_mm_cmpeq_epi8(*(__m128i*)CurPtr, Slashes)) == 0)
+        CurPtr += 16;
+#elif __ALTIVEC__
+      __vector unsigned char Slashes = {
+        '/', '/', '/', '/',  '/', '/', '/', '/',
+        '/', '/', '/', '/',  '/', '/', '/', '/'
+      };
+      while (CurPtr+16 <= BufferEnd &&
+             !vec_any_eq(*(vector unsigned char*)CurPtr, Slashes))
+        CurPtr += 16;
+#else
+      // Scan for '/' quickly.  Many block comments are very large.
+      while (CurPtr[0] != '/' &&
+             CurPtr[1] != '/' &&
+             CurPtr[2] != '/' &&
+             CurPtr[3] != '/' &&
+             CurPtr+4 < BufferEnd) {
+        CurPtr += 4;
+      }
+#endif
+
+      // It has to be one of the bytes scanned, increment to it and read one.
+      C = *CurPtr++;
+    }
+
+    // Loop to scan the remainder.
+    while (C != '/' && C != '\0')
+      C = *CurPtr++;
+
+  FoundSlash:
+    if (C == '/') {
+      if (CurPtr[-2] == '*')  // We found the final */.  We're done!
+        break;
+
+      if ((CurPtr[-2] == '\n' || CurPtr[-2] == '\r')) {
+        if (isEndOfBlockCommentWithEscapedNewLine(CurPtr-2, this)) {
+          // We found the final */, though it had an escaped newline between the
+          // * and /.  We're done!
+          break;
+        }
+      }
+      if (CurPtr[0] == '*' && CurPtr[1] != '/') {
+        // If this is a /* inside of the comment, emit a warning.  Don't do this
+        // if this is a /*/, which will end the comment.  This misses cases with
+        // embedded escaped newlines, but oh well.
+        if (!isLexingRawMode())
+          Diag(CurPtr-1, diag::warn_nested_block_comment);
+      }
+    } else if (C == 0 && CurPtr == BufferEnd+1) {
+      if (!isLexingRawMode())
+        Diag(BufferPtr, diag::err_unterminated_block_comment);
+      // Note: the user probably forgot a */.  We could continue immediately
+      // after the /*, but this would involve lexing a lot of what really is the
+      // comment, which surely would confuse the parser.
+      --CurPtr;
+
+      // KeepWhitespaceMode should return this broken comment as a token.  Since
+      // it isn't a well formed comment, just return it as an 'unknown' token.
+      if (isKeepWhitespaceMode()) {
+        FormTokenWithChars(Result, CurPtr, tok::unknown);
+        return true;
+      }
+
+      BufferPtr = CurPtr;
+      return false;
+    }
+    C = *CurPtr++;
+  }
+
+  // Notify comment handlers about the comment unless we're in a #if 0 block.
+  if (PP && !isLexingRawMode() &&
+      PP->HandleComment(Result, SourceRange(getSourceLocation(BufferPtr),
+                                            getSourceLocation(CurPtr)))) {
+    BufferPtr = CurPtr;
+    return true; // A token has to be returned.
+  }
+
+  // If we are returning comments as tokens, return this comment as a token.
+  if (inKeepCommentMode()) {
+    FormTokenWithChars(Result, CurPtr, tok::comment);
+    return true;
+  }
+
+  // It is common for the tokens immediately after a /**/ comment to be
+  // whitespace.  Instead of going through the big switch, handle it
+  // efficiently now.  This is safe even in KeepWhitespaceMode because we would
+  // have already returned above with the comment as a token.
+  if (isHorizontalWhitespace(*CurPtr)) {
+    Result.setFlag(Token::LeadingSpace);
+    SkipWhitespace(Result, CurPtr+1);
+    return false;
+  }
+
+  // Otherwise, just return so that the next character will be lexed as a token.
+  BufferPtr = CurPtr;
+  Result.setFlag(Token::LeadingSpace);
+  return false;
+}
+
+//===----------------------------------------------------------------------===//
+// Primary Lexing Entry Points
+//===----------------------------------------------------------------------===//
+
+/// ReadToEndOfLine - Read the rest of the current preprocessor line as an
+/// uninterpreted string.  This switches the lexer out of directive mode.
+std::string Lexer::ReadToEndOfLine() {
+  assert(ParsingPreprocessorDirective && ParsingFilename == false &&
+         "Must be in a preprocessing directive!");
+  std::string Result;
+  Token Tmp;
+
+  // CurPtr - Cache BufferPtr in an automatic variable.
+  const char *CurPtr = BufferPtr;
+  while (1) {
+    char Char = getAndAdvanceChar(CurPtr, Tmp);
+    switch (Char) {
+    default:
+      Result += Char;
+      break;
+    case 0:  // Null.
+      // Found end of file?
+      if (CurPtr-1 != BufferEnd) {
+        // Nope, normal character, continue.
+        Result += Char;
+        break;
+      }
+      // FALL THROUGH.
+    case '\r':
+    case '\n':
+      // Okay, we found the end of the line. First, back up past the \0, \r, \n.
+      assert(CurPtr[-1] == Char && "Trigraphs for newline?");
+      BufferPtr = CurPtr-1;
+
+      // Next, lex the character, which should handle the EOM transition.
+      Lex(Tmp);
+      assert(Tmp.is(tok::eom) && "Unexpected token!");
+
+      // Finally, we're done, return the string we found.
+      return Result;
+    }
+  }
+}
+
+/// LexEndOfFile - CurPtr points to the end of this file.  Handle this
+/// condition, reporting diagnostics and handling other edge cases as required.
+/// This returns true if Result contains a token, false if PP.Lex should be
+/// called again.
+bool Lexer::LexEndOfFile(Token &Result, const char *CurPtr) {
+  // If we hit the end of the file while parsing a preprocessor directive,
+  // end the preprocessor directive first.  The next token returned will
+  // then be the end of file.
+  if (ParsingPreprocessorDirective) {
+    // Done parsing the "line".
+    ParsingPreprocessorDirective = false;
+    // Update the location of token as well as BufferPtr.
+    FormTokenWithChars(Result, CurPtr, tok::eom);
+
+    // Restore comment saving mode, in case it was disabled for directive.
+    SetCommentRetentionState(PP->getCommentRetentionState());
+    return true;  // Have a token.
+  }
+ 
+  // If we are in raw mode, return this event as an EOF token.  Let the caller
+  // that put us in raw mode handle the event.
+  if (isLexingRawMode()) {
+    Result.startToken();
+    BufferPtr = BufferEnd;
+    FormTokenWithChars(Result, BufferEnd, tok::eof);
+    return true;
+  }
+
+  // Otherwise, check if we are code-completing, then issue diagnostics for 
+  // unterminated #if and missing newline.
+
+  if (PP && PP->isCodeCompletionFile(FileLoc)) {
+    // We're at the end of the file, but we've been asked to consider the
+    // end of the file to be a code-completion token. Return the
+    // code-completion token.
+    Result.startToken();
+    FormTokenWithChars(Result, CurPtr, tok::code_completion);
+    
+    // Only do the eof -> code_completion translation once.
+    PP->SetCodeCompletionPoint(0, 0, 0);
+    return true;
+  }
+  
+  // If we are in a #if directive, emit an error.
+  while (!ConditionalStack.empty()) {
+    PP->Diag(ConditionalStack.back().IfLoc,
+             diag::err_pp_unterminated_conditional);
+    ConditionalStack.pop_back();
+  }
+
+  // C99 5.1.1.2p2: If the file is non-empty and didn't end in a newline, issue
+  // a pedwarn.
+  if (CurPtr != BufferStart && (CurPtr[-1] != '\n' && CurPtr[-1] != '\r'))
+    Diag(BufferEnd, diag::ext_no_newline_eof)
+      << FixItHint::CreateInsertion(getSourceLocation(BufferEnd), "\n");
+
+  BufferPtr = CurPtr;
+
+  // Finally, let the preprocessor handle this.
+  return PP->HandleEndOfFile(Result);
+}
+
+/// isNextPPTokenLParen - Return 1 if the next unexpanded token lexed from
+/// the specified lexer will return a tok::l_paren token, 0 if it is something
+/// else and 2 if there are no more tokens in the buffer controlled by the
+/// lexer.
+unsigned Lexer::isNextPPTokenLParen() {
+  assert(!LexingRawMode && "How can we expand a macro from a skipping buffer?");
+
+  // Switch to 'skipping' mode.  This will ensure that we can lex a token
+  // without emitting diagnostics, disables macro expansion, and will cause EOF
+  // to return an EOF token instead of popping the include stack.
+  LexingRawMode = true;
+
+  // Save state that can be changed while lexing so that we can restore it.
+  const char *TmpBufferPtr = BufferPtr;
+  bool inPPDirectiveMode = ParsingPreprocessorDirective;
+
+  Token Tok;
+  Tok.startToken();
+  LexTokenInternal(Tok);
+
+  // Restore state that may have changed.
+  BufferPtr = TmpBufferPtr;
+  ParsingPreprocessorDirective = inPPDirectiveMode;
+
+  // Restore the lexer back to non-skipping mode.
+  LexingRawMode = false;
+
+  if (Tok.is(tok::eof))
+    return 2;
+  return Tok.is(tok::l_paren);
+}
+
+/// FindConflictEnd - Find the end of a version control conflict marker.
+static const char *FindConflictEnd(const char *CurPtr, const char *BufferEnd) {
+  llvm::StringRef RestOfBuffer(CurPtr+7, BufferEnd-CurPtr-7);
+  size_t Pos = RestOfBuffer.find(">>>>>>>");
+  while (Pos != llvm::StringRef::npos) {
+    // Must occur at start of line.
+    if (RestOfBuffer[Pos-1] != '\r' &&
+        RestOfBuffer[Pos-1] != '\n') {
+      RestOfBuffer = RestOfBuffer.substr(Pos+7);
+      continue;
+    }
+    return RestOfBuffer.data()+Pos;
+  }
+  return 0;
+}
+
+/// IsStartOfConflictMarker - If the specified pointer is the start of a version
+/// control conflict marker like '<<<<<<<', recognize it as such, emit an error
+/// and recover nicely.  This returns true if it is a conflict marker and false
+/// if not.
+bool Lexer::IsStartOfConflictMarker(const char *CurPtr) {
+  // Only a conflict marker if it starts at the beginning of a line.
+  if (CurPtr != BufferStart &&
+      CurPtr[-1] != '\n' && CurPtr[-1] != '\r')
+    return false;
+  
+  // Check to see if we have <<<<<<<.
+  if (BufferEnd-CurPtr < 8 ||
+      llvm::StringRef(CurPtr, 7) != "<<<<<<<")
+    return false;
+
+  // If we have a situation where we don't care about conflict markers, ignore
+  // it.
+  if (IsInConflictMarker || isLexingRawMode())
+    return false;
+  
+  // Check to see if there is a >>>>>>> somewhere in the buffer at the start of
+  // a line to terminate this conflict marker.
+  if (FindConflictEnd(CurPtr+7, BufferEnd)) {
+    // We found a match.  We are really in a conflict marker.
+    // Diagnose this, and ignore to the end of line.
+    Diag(CurPtr, diag::err_conflict_marker);
+    IsInConflictMarker = true;
+    
+    // Skip ahead to the end of line.  We know this exists because the
+    // end-of-conflict marker starts with \r or \n.
+    while (*CurPtr != '\r' && *CurPtr != '\n') {
+      assert(CurPtr != BufferEnd && "Didn't find end of line");
+      ++CurPtr;
+    }
+    BufferPtr = CurPtr;
+    return true;
+  }
+  
+  // No end of conflict marker found.
+  return false;
+}
+
+
+/// HandleEndOfConflictMarker - If this is a '=======' or '|||||||' or '>>>>>>>'
+/// marker, then it is the end of a conflict marker.  Handle it by ignoring up
+/// until the end of the line.  This returns true if it is a conflict marker and
+/// false if not.
+bool Lexer::HandleEndOfConflictMarker(const char *CurPtr) {
+  // Only a conflict marker if it starts at the beginning of a line.
+  if (CurPtr != BufferStart &&
+      CurPtr[-1] != '\n' && CurPtr[-1] != '\r')
+    return false;
+  
+  // If we have a situation where we don't care about conflict markers, ignore
+  // it.
+  if (!IsInConflictMarker || isLexingRawMode())
+    return false;
+  
+  // Check to see if we have the marker (7 characters in a row).
+  for (unsigned i = 1; i != 7; ++i)
+    if (CurPtr[i] != CurPtr[0])
+      return false;
+  
+  // If we do have it, search for the end of the conflict marker.  This could
+  // fail if it got skipped with a '#if 0' or something.  Note that CurPtr might
+  // be the end of conflict marker.
+  if (const char *End = FindConflictEnd(CurPtr, BufferEnd)) {
+    CurPtr = End;
+    
+    // Skip ahead to the end of line.
+    while (CurPtr != BufferEnd && *CurPtr != '\r' && *CurPtr != '\n')
+      ++CurPtr;
+    
+    BufferPtr = CurPtr;
+    
+    // No longer in the conflict marker.
+    IsInConflictMarker = false;
+    return true;
+  }
+  
+  return false;
+}
+
+
+/// LexTokenInternal - This implements a simple C family lexer.  It is an
+/// extremely performance critical piece of code.  This assumes that the buffer
+/// has a null character at the end of the file.  This returns a preprocessing
+/// token, not a normal token, as such, it is an internal interface.  It assumes
+/// that the Flags of result have been cleared before calling this.
+void Lexer::LexTokenInternal(Token &Result) {
+LexNextToken:
+  // New token, can't need cleaning yet.
+  Result.clearFlag(Token::NeedsCleaning);
+  Result.setIdentifierInfo(0);
+
+  // CurPtr - Cache BufferPtr in an automatic variable.
+  const char *CurPtr = BufferPtr;
+
+  // Small amounts of horizontal whitespace is very common between tokens.
+  if ((*CurPtr == ' ') || (*CurPtr == '\t')) {
+    ++CurPtr;
+    while ((*CurPtr == ' ') || (*CurPtr == '\t'))
+      ++CurPtr;
+
+    // If we are keeping whitespace and other tokens, just return what we just
+    // skipped.  The next lexer invocation will return the token after the
+    // whitespace.
+    if (isKeepWhitespaceMode()) {
+      FormTokenWithChars(Result, CurPtr, tok::unknown);
+      return;
+    }
+
+    BufferPtr = CurPtr;
+    Result.setFlag(Token::LeadingSpace);
+  }
+
+  unsigned SizeTmp, SizeTmp2;   // Temporaries for use in cases below.
+
+  // Read a character, advancing over it.
+  char Char = getAndAdvanceChar(CurPtr, Result);
+  tok::TokenKind Kind;
+
+  switch (Char) {
+  case 0:  // Null.
+    // Found end of file?
+    if (CurPtr-1 == BufferEnd) {
+      // Read the PP instance variable into an automatic variable, because
+      // LexEndOfFile will often delete 'this'.
+      Preprocessor *PPCache = PP;
+      if (LexEndOfFile(Result, CurPtr-1))  // Retreat back into the file.
+        return;   // Got a token to return.
+      assert(PPCache && "Raw buffer::LexEndOfFile should return a token");
+      return PPCache->Lex(Result);
+    }
+
+    if (!isLexingRawMode())
+      Diag(CurPtr-1, diag::null_in_file);
+    Result.setFlag(Token::LeadingSpace);
+    if (SkipWhitespace(Result, CurPtr))
+      return; // KeepWhitespaceMode
+
+    goto LexNextToken;   // GCC isn't tail call eliminating.
+      
+  case 26:  // DOS & CP/M EOF: "^Z".
+    // If we're in Microsoft extensions mode, treat this as end of file.
+    if (Features.Microsoft) {
+      // Read the PP instance variable into an automatic variable, because
+      // LexEndOfFile will often delete 'this'.
+      Preprocessor *PPCache = PP;
+      if (LexEndOfFile(Result, CurPtr-1))  // Retreat back into the file.
+        return;   // Got a token to return.
+      assert(PPCache && "Raw buffer::LexEndOfFile should return a token");
+      return PPCache->Lex(Result);
+    }
+    // If Microsoft extensions are disabled, this is just random garbage.
+    Kind = tok::unknown;
+    break;
+      
+  case '\n':
+  case '\r':
+    // If we are inside a preprocessor directive and we see the end of line,
+    // we know we are done with the directive, so return an EOM token.
+    if (ParsingPreprocessorDirective) {
+      // Done parsing the "line".
+      ParsingPreprocessorDirective = false;
+
+      // Restore comment saving mode, in case it was disabled for directive.
+      SetCommentRetentionState(PP->getCommentRetentionState());
+
+      // Since we consumed a newline, we are back at the start of a line.
+      IsAtStartOfLine = true;
+
+      Kind = tok::eom;
+      break;
+    }
+    // The returned token is at the start of the line.
+    Result.setFlag(Token::StartOfLine);
+    // No leading whitespace seen so far.
+    Result.clearFlag(Token::LeadingSpace);
+
+    if (SkipWhitespace(Result, CurPtr))
+      return; // KeepWhitespaceMode
+    goto LexNextToken;   // GCC isn't tail call eliminating.
+  case ' ':
+  case '\t':
+  case '\f':
+  case '\v':
+  SkipHorizontalWhitespace:
+    Result.setFlag(Token::LeadingSpace);
+    if (SkipWhitespace(Result, CurPtr))
+      return; // KeepWhitespaceMode
+
+  SkipIgnoredUnits:
+    CurPtr = BufferPtr;
+
+    // If the next token is obviously a // or /* */ comment, skip it efficiently
+    // too (without going through the big switch stmt).
+    if (CurPtr[0] == '/' && CurPtr[1] == '/' && !inKeepCommentMode() &&
+        Features.BCPLComment) {
+      if (SkipBCPLComment(Result, CurPtr+2))
+        return; // There is a token to return.
+      goto SkipIgnoredUnits;
+    } else if (CurPtr[0] == '/' && CurPtr[1] == '*' && !inKeepCommentMode()) {
+      if (SkipBlockComment(Result, CurPtr+2))
+        return; // There is a token to return.
+      goto SkipIgnoredUnits;
+    } else if (isHorizontalWhitespace(*CurPtr)) {
+      goto SkipHorizontalWhitespace;
+    }
+    goto LexNextToken;   // GCC isn't tail call eliminating.
+      
+  // C99 6.4.4.1: Integer Constants.
+  // C99 6.4.4.2: Floating Constants.
+  case '0': case '1': case '2': case '3': case '4':
+  case '5': case '6': case '7': case '8': case '9':
+    // Notify MIOpt that we read a non-whitespace/non-comment token.
+    MIOpt.ReadToken();
+    return LexNumericConstant(Result, CurPtr);
+
+  case 'L':   // Identifier (Loony) or wide literal (L'x' or L"xyz").
+    // Notify MIOpt that we read a non-whitespace/non-comment token.
+    MIOpt.ReadToken();
+    Char = getCharAndSize(CurPtr, SizeTmp);
+
+    // Wide string literal.
+    if (Char == '"')
+      return LexStringLiteral(Result, ConsumeChar(CurPtr, SizeTmp, Result),
+                              true);
+
+    // Wide character constant.
+    if (Char == '\'')
+      return LexCharConstant(Result, ConsumeChar(CurPtr, SizeTmp, Result));
+    // FALL THROUGH, treating L like the start of an identifier.
+
+  // C99 6.4.2: Identifiers.
+  case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G':
+  case 'H': case 'I': case 'J': case 'K':    /*'L'*/case 'M': case 'N':
+  case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U':
+  case 'V': case 'W': case 'X': case 'Y': case 'Z':
+  case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g':
+  case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n':
+  case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u':
+  case 'v': case 'w': case 'x': case 'y': case 'z':
+  case '_':
+    // Notify MIOpt that we read a non-whitespace/non-comment token.
+    MIOpt.ReadToken();
+    return LexIdentifier(Result, CurPtr);
+
+  case '$':   // $ in identifiers.
+    if (Features.DollarIdents) {
+      if (!isLexingRawMode())
+        Diag(CurPtr-1, diag::ext_dollar_in_identifier);
+      // Notify MIOpt that we read a non-whitespace/non-comment token.
+      MIOpt.ReadToken();
+      return LexIdentifier(Result, CurPtr);
+    }
+
+    Kind = tok::unknown;
+    break;
+
+  // C99 6.4.4: Character Constants.
+  case '\'':
+    // Notify MIOpt that we read a non-whitespace/non-comment token.
+    MIOpt.ReadToken();
+    return LexCharConstant(Result, CurPtr);
+
+  // C99 6.4.5: String Literals.
+  case '"':
+    // Notify MIOpt that we read a non-whitespace/non-comment token.
+    MIOpt.ReadToken();
+    return LexStringLiteral(Result, CurPtr, false);
+
+  // C99 6.4.6: Punctuators.
+  case '?':
+    Kind = tok::question;
+    break;
+  case '[':
+    Kind = tok::l_square;
+    break;
+  case ']':
+    Kind = tok::r_square;
+    break;
+  case '(':
+    Kind = tok::l_paren;
+    break;
+  case ')':
+    Kind = tok::r_paren;
+    break;
+  case '{':
+    Kind = tok::l_brace;
+    break;
+  case '}':
+    Kind = tok::r_brace;
+    break;
+  case '.':
+    Char = getCharAndSize(CurPtr, SizeTmp);
+    if (Char >= '0' && Char <= '9') {
+      // Notify MIOpt that we read a non-whitespace/non-comment token.
+      MIOpt.ReadToken();
+
+      return LexNumericConstant(Result, ConsumeChar(CurPtr, SizeTmp, Result));
+    } else if (Features.CPlusPlus && Char == '*') {
+      Kind = tok::periodstar;
+      CurPtr += SizeTmp;
+    } else if (Char == '.' &&
+               getCharAndSize(CurPtr+SizeTmp, SizeTmp2) == '.') {
+      Kind = tok::ellipsis;
+      CurPtr = ConsumeChar(ConsumeChar(CurPtr, SizeTmp, Result),
+                           SizeTmp2, Result);
+    } else {
+      Kind = tok::period;
+    }
+    break;
+  case '&':
+    Char = getCharAndSize(CurPtr, SizeTmp);
+    if (Char == '&') {
+      Kind = tok::ampamp;
+      CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
+    } else if (Char == '=') {
+      Kind = tok::ampequal;
+      CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
+    } else {
+      Kind = tok::amp;
+    }
+    break;
+  case '*':
+    if (getCharAndSize(CurPtr, SizeTmp) == '=') {
+      Kind = tok::starequal;
+      CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
+    } else {
+      Kind = tok::star;
+    }
+    break;
+  case '+':
+    Char = getCharAndSize(CurPtr, SizeTmp);
+    if (Char == '+') {
+      CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
+      Kind = tok::plusplus;
+    } else if (Char == '=') {
+      CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
+      Kind = tok::plusequal;
+    } else {
+      Kind = tok::plus;
+    }
+    break;
+  case '-':
+    Char = getCharAndSize(CurPtr, SizeTmp);
+    if (Char == '-') {      // --
+      CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
+      Kind = tok::minusminus;
+    } else if (Char == '>' && Features.CPlusPlus &&
+               getCharAndSize(CurPtr+SizeTmp, SizeTmp2) == '*') {  // C++ ->*
+      CurPtr = ConsumeChar(ConsumeChar(CurPtr, SizeTmp, Result),
+                           SizeTmp2, Result);
+      Kind = tok::arrowstar;
+    } else if (Char == '>') {   // ->
+      CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
+      Kind = tok::arrow;
+    } else if (Char == '=') {   // -=
+      CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
+      Kind = tok::minusequal;
+    } else {
+      Kind = tok::minus;
+    }
+    break;
+  case '~':
+    Kind = tok::tilde;
+    break;
+  case '!':
+    if (getCharAndSize(CurPtr, SizeTmp) == '=') {
+      Kind = tok::exclaimequal;
+      CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
+    } else {
+      Kind = tok::exclaim;
+    }
+    break;
+  case '/':
+    // 6.4.9: Comments
+    Char = getCharAndSize(CurPtr, SizeTmp);
+    if (Char == '/') {         // BCPL comment.
+      // Even if BCPL comments are disabled (e.g. in C89 mode), we generally
+      // want to lex this as a comment.  There is one problem with this though,
+      // that in one particular corner case, this can change the behavior of the
+      // resultant program.  For example, In  "foo //**/ bar", C89 would lex
+      // this as "foo / bar" and langauges with BCPL comments would lex it as
+      // "foo".  Check to see if the character after the second slash is a '*'.
+      // If so, we will lex that as a "/" instead of the start of a comment.
+      if (Features.BCPLComment ||
+          getCharAndSize(CurPtr+SizeTmp, SizeTmp2) != '*') {
+        if (SkipBCPLComment(Result, ConsumeChar(CurPtr, SizeTmp, Result)))
+          return; // There is a token to return.
+
+        // It is common for the tokens immediately after a // comment to be
+        // whitespace (indentation for the next line).  Instead of going through
+        // the big switch, handle it efficiently now.
+        goto SkipIgnoredUnits;
+      }
+    }
+
+    if (Char == '*') {  // /**/ comment.
+      if (SkipBlockComment(Result, ConsumeChar(CurPtr, SizeTmp, Result)))
+        return; // There is a token to return.
+      goto LexNextToken;   // GCC isn't tail call eliminating.
+    }
+
+    if (Char == '=') {
+      CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
+      Kind = tok::slashequal;
+    } else {
+      Kind = tok::slash;
+    }
+    break;
+  case '%':
+    Char = getCharAndSize(CurPtr, SizeTmp);
+    if (Char == '=') {
+      Kind = tok::percentequal;
+      CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
+    } else if (Features.Digraphs && Char == '>') {
+      Kind = tok::r_brace;                             // '%>' -> '}'
+      CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
+    } else if (Features.Digraphs && Char == ':') {
+      CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
+      Char = getCharAndSize(CurPtr, SizeTmp);
+      if (Char == '%' && getCharAndSize(CurPtr+SizeTmp, SizeTmp2) == ':') {
+        Kind = tok::hashhash;                          // '%:%:' -> '##'
+        CurPtr = ConsumeChar(ConsumeChar(CurPtr, SizeTmp, Result),
+                             SizeTmp2, Result);
+      } else if (Char == '@' && Features.Microsoft) {  // %:@ -> #@ -> Charize
+        CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
+        if (!isLexingRawMode())
+          Diag(BufferPtr, diag::charize_microsoft_ext);
+        Kind = tok::hashat;
+      } else {                                         // '%:' -> '#'
+        // We parsed a # character.  If this occurs at the start of the line,
+        // it's actually the start of a preprocessing directive.  Callback to
+        // the preprocessor to handle it.
+        // FIXME: -fpreprocessed mode??
+        if (Result.isAtStartOfLine() && !LexingRawMode && !Is_PragmaLexer) {
+          FormTokenWithChars(Result, CurPtr, tok::hash);
+          PP->HandleDirective(Result);
+
+          // As an optimization, if the preprocessor didn't switch lexers, tail
+          // recurse.
+          if (PP->isCurrentLexer(this)) {
+            // Start a new token. If this is a #include or something, the PP may
+            // want us starting at the beginning of the line again.  If so, set
+            // the StartOfLine flag and clear LeadingSpace.
+            if (IsAtStartOfLine) {
+              Result.setFlag(Token::StartOfLine);
+              Result.clearFlag(Token::LeadingSpace);
+              IsAtStartOfLine = false;
+            }
+            goto LexNextToken;   // GCC isn't tail call eliminating.
+          }
+
+          return PP->Lex(Result);
+        }
+
+        Kind = tok::hash;
+      }
+    } else {
+      Kind = tok::percent;
+    }
+    break;
+  case '<':
+    Char = getCharAndSize(CurPtr, SizeTmp);
+    if (ParsingFilename) {
+      return LexAngledStringLiteral(Result, CurPtr);
+    } else if (Char == '<') {
+      char After = getCharAndSize(CurPtr+SizeTmp, SizeTmp2);
+      if (After == '=') {
+        Kind = tok::lesslessequal;
+        CurPtr = ConsumeChar(ConsumeChar(CurPtr, SizeTmp, Result),
+                             SizeTmp2, Result);
+      } else if (After == '<' && IsStartOfConflictMarker(CurPtr-1)) {
+        // If this is actually a '<<<<<<<' version control conflict marker,
+        // recognize it as such and recover nicely.
+        goto LexNextToken;
+      } else {
+        CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
+        Kind = tok::lessless;
+      }
+    } else if (Char == '=') {
+      CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
+      Kind = tok::lessequal;
+    } else if (Features.Digraphs && Char == ':') {     // '<:' -> '['
+      CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
+      Kind = tok::l_square;
+    } else if (Features.Digraphs && Char == '%') {     // '<%' -> '{'
+      CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
+      Kind = tok::l_brace;
+    } else {
+      Kind = tok::less;
+    }
+    break;
+  case '>':
+    Char = getCharAndSize(CurPtr, SizeTmp);
+    if (Char == '=') {
+      CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
+      Kind = tok::greaterequal;
+    } else if (Char == '>') {
+      char After = getCharAndSize(CurPtr+SizeTmp, SizeTmp2);
+      if (After == '=') {
+        CurPtr = ConsumeChar(ConsumeChar(CurPtr, SizeTmp, Result),
+                             SizeTmp2, Result);
+        Kind = tok::greatergreaterequal;
+      } else if (After == '>' && HandleEndOfConflictMarker(CurPtr-1)) {
+        // If this is '>>>>>>>' and we're in a conflict marker, ignore it.
+        goto LexNextToken;
+      } else {
+        CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
+        Kind = tok::greatergreater;
+      }
+      
+    } else {
+      Kind = tok::greater;
+    }
+    break;
+  case '^':
+    Char = getCharAndSize(CurPtr, SizeTmp);
+    if (Char == '=') {
+      CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
+      Kind = tok::caretequal;
+    } else {
+      Kind = tok::caret;
+    }
+    break;
+  case '|':
+    Char = getCharAndSize(CurPtr, SizeTmp);
+    if (Char == '=') {
+      Kind = tok::pipeequal;
+      CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
+    } else if (Char == '|') {
+      // If this is '|||||||' and we're in a conflict marker, ignore it.
+      if (CurPtr[1] == '|' && HandleEndOfConflictMarker(CurPtr-1))
+        goto LexNextToken;
+      Kind = tok::pipepipe;
+      CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
+    } else {
+      Kind = tok::pipe;
+    }
+    break;
+  case ':':
+    Char = getCharAndSize(CurPtr, SizeTmp);
+    if (Features.Digraphs && Char == '>') {
+      Kind = tok::r_square; // ':>' -> ']'
+      CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
+    } else if (Features.CPlusPlus && Char == ':') {
+      Kind = tok::coloncolon;
+      CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
+    } else {
+      Kind = tok::colon;
+    }
+    break;
+  case ';':
+    Kind = tok::semi;
+    break;
+  case '=':
+    Char = getCharAndSize(CurPtr, SizeTmp);
+    if (Char == '=') {
+      // If this is '=======' and we're in a conflict marker, ignore it.
+      if (CurPtr[1] == '=' && HandleEndOfConflictMarker(CurPtr-1))
+        goto LexNextToken;
+      
+      Kind = tok::equalequal;
+      CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
+    } else {
+      Kind = tok::equal;
+    }
+    break;
+  case ',':
+    Kind = tok::comma;
+    break;
+  case '#':
+    Char = getCharAndSize(CurPtr, SizeTmp);
+    if (Char == '#') {
+      Kind = tok::hashhash;
+      CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
+    } else if (Char == '@' && Features.Microsoft) {  // #@ -> Charize
+      Kind = tok::hashat;
+      if (!isLexingRawMode())
+        Diag(BufferPtr, diag::charize_microsoft_ext);
+      CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
+    } else {
+      // We parsed a # character.  If this occurs at the start of the line,
+      // it's actually the start of a preprocessing directive.  Callback to
+      // the preprocessor to handle it.
+      // FIXME: -fpreprocessed mode??
+      if (Result.isAtStartOfLine() && !LexingRawMode && !Is_PragmaLexer) {
+        FormTokenWithChars(Result, CurPtr, tok::hash);
+        PP->HandleDirective(Result);
+
+        // As an optimization, if the preprocessor didn't switch lexers, tail
+        // recurse.
+        if (PP->isCurrentLexer(this)) {
+          // Start a new token.  If this is a #include or something, the PP may
+          // want us starting at the beginning of the line again.  If so, set
+          // the StartOfLine flag and clear LeadingSpace.
+          if (IsAtStartOfLine) {
+            Result.setFlag(Token::StartOfLine);
+            Result.clearFlag(Token::LeadingSpace);
+            IsAtStartOfLine = false;
+          }
+          goto LexNextToken;   // GCC isn't tail call eliminating.
+        }
+        return PP->Lex(Result);
+      }
+
+      Kind = tok::hash;
+    }
+    break;
+
+  case '@':
+    // Objective C support.
+    if (CurPtr[-1] == '@' && Features.ObjC1)
+      Kind = tok::at;
+    else
+      Kind = tok::unknown;
+    break;
+
+  case '\\':
+    // FIXME: UCN's.
+    // FALL THROUGH.
+  default:
+    Kind = tok::unknown;
+    break;
+  }
+
+  // Notify MIOpt that we read a non-whitespace/non-comment token.
+  MIOpt.ReadToken();
+
+  // Update the location of token as well as BufferPtr.
+  FormTokenWithChars(Result, CurPtr, Kind);
+}
diff --git a/lib/Lex/LiteralSupport.cpp b/lib/Lex/LiteralSupport.cpp
new file mode 100644
index 0000000..f425582
--- /dev/null
+++ b/lib/Lex/LiteralSupport.cpp
@@ -0,0 +1,954 @@
+//===--- LiteralSupport.cpp - Code to parse and process literals ----------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the NumericLiteralParser, CharLiteralParser, and
+// StringLiteralParser interfaces.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Lex/LiteralSupport.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Lex/LexDiagnostic.h"
+#include "clang/Basic/TargetInfo.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringExtras.h"
+using namespace clang;
+
+/// HexDigitValue - Return the value of the specified hex digit, or -1 if it's
+/// not valid.
+static int HexDigitValue(char C) {
+  if (C >= '0' && C <= '9') return C-'0';
+  if (C >= 'a' && C <= 'f') return C-'a'+10;
+  if (C >= 'A' && C <= 'F') return C-'A'+10;
+  return -1;
+}
+
+/// ProcessCharEscape - Parse a standard C escape sequence, which can occur in
+/// either a character or a string literal.
+static unsigned ProcessCharEscape(const char *&ThisTokBuf,
+                                  const char *ThisTokEnd, bool &HadError,
+                                  SourceLocation Loc, bool IsWide,
+                                  Preprocessor &PP) {
+  // Skip the '\' char.
+  ++ThisTokBuf;
+
+  // We know that this character can't be off the end of the buffer, because
+  // that would have been \", which would not have been the end of string.
+  unsigned ResultChar = *ThisTokBuf++;
+  switch (ResultChar) {
+  // These map to themselves.
+  case '\\': case '\'': case '"': case '?': break;
+
+    // These have fixed mappings.
+  case 'a':
+    // TODO: K&R: the meaning of '\\a' is different in traditional C
+    ResultChar = 7;
+    break;
+  case 'b':
+    ResultChar = 8;
+    break;
+  case 'e':
+    PP.Diag(Loc, diag::ext_nonstandard_escape) << "e";
+    ResultChar = 27;
+    break;
+  case 'E':
+    PP.Diag(Loc, diag::ext_nonstandard_escape) << "E";
+    ResultChar = 27;
+    break;
+  case 'f':
+    ResultChar = 12;
+    break;
+  case 'n':
+    ResultChar = 10;
+    break;
+  case 'r':
+    ResultChar = 13;
+    break;
+  case 't':
+    ResultChar = 9;
+    break;
+  case 'v':
+    ResultChar = 11;
+    break;
+  case 'x': { // Hex escape.
+    ResultChar = 0;
+    if (ThisTokBuf == ThisTokEnd || !isxdigit(*ThisTokBuf)) {
+      PP.Diag(Loc, diag::err_hex_escape_no_digits);
+      HadError = 1;
+      break;
+    }
+
+    // Hex escapes are a maximal series of hex digits.
+    bool Overflow = false;
+    for (; ThisTokBuf != ThisTokEnd; ++ThisTokBuf) {
+      int CharVal = HexDigitValue(ThisTokBuf[0]);
+      if (CharVal == -1) break;
+      // About to shift out a digit?
+      Overflow |= (ResultChar & 0xF0000000) ? true : false;
+      ResultChar <<= 4;
+      ResultChar |= CharVal;
+    }
+
+    // See if any bits will be truncated when evaluated as a character.
+    unsigned CharWidth = IsWide
+                       ? PP.getTargetInfo().getWCharWidth()
+                       : PP.getTargetInfo().getCharWidth();
+
+    if (CharWidth != 32 && (ResultChar >> CharWidth) != 0) {
+      Overflow = true;
+      ResultChar &= ~0U >> (32-CharWidth);
+    }
+
+    // Check for overflow.
+    if (Overflow)   // Too many digits to fit in
+      PP.Diag(Loc, diag::warn_hex_escape_too_large);
+    break;
+  }
+  case '0': case '1': case '2': case '3':
+  case '4': case '5': case '6': case '7': {
+    // Octal escapes.
+    --ThisTokBuf;
+    ResultChar = 0;
+
+    // Octal escapes are a series of octal digits with maximum length 3.
+    // "\0123" is a two digit sequence equal to "\012" "3".
+    unsigned NumDigits = 0;
+    do {
+      ResultChar <<= 3;
+      ResultChar |= *ThisTokBuf++ - '0';
+      ++NumDigits;
+    } while (ThisTokBuf != ThisTokEnd && NumDigits < 3 &&
+             ThisTokBuf[0] >= '0' && ThisTokBuf[0] <= '7');
+
+    // Check for overflow.  Reject '\777', but not L'\777'.
+    unsigned CharWidth = IsWide
+                       ? PP.getTargetInfo().getWCharWidth()
+                       : PP.getTargetInfo().getCharWidth();
+
+    if (CharWidth != 32 && (ResultChar >> CharWidth) != 0) {
+      PP.Diag(Loc, diag::warn_octal_escape_too_large);
+      ResultChar &= ~0U >> (32-CharWidth);
+    }
+    break;
+  }
+
+    // Otherwise, these are not valid escapes.
+  case '(': case '{': case '[': case '%':
+    // GCC accepts these as extensions.  We warn about them as such though.
+    PP.Diag(Loc, diag::ext_nonstandard_escape)
+      << std::string()+(char)ResultChar;
+    break;
+  default:
+    if (isgraph(ThisTokBuf[0]))
+      PP.Diag(Loc, diag::ext_unknown_escape) << std::string()+(char)ResultChar;
+    else
+      PP.Diag(Loc, diag::ext_unknown_escape) << "x"+llvm::utohexstr(ResultChar);
+    break;
+  }
+
+  return ResultChar;
+}
+
+/// ProcessUCNEscape - Read the Universal Character Name, check constraints and
+/// convert the UTF32 to UTF8. This is a subroutine of StringLiteralParser.
+/// When we decide to implement UCN's for character constants and identifiers,
+/// we will likely rework our support for UCN's.
+static void ProcessUCNEscape(const char *&ThisTokBuf, const char *ThisTokEnd,
+                             char *&ResultBuf, bool &HadError,
+                             SourceLocation Loc, bool IsWide, Preprocessor &PP)
+{
+  // FIXME: Add a warning - UCN's are only valid in C++ & C99.
+  // FIXME: Handle wide strings.
+
+  // Save the beginning of the string (for error diagnostics).
+  const char *ThisTokBegin = ThisTokBuf;
+
+  // Skip the '\u' char's.
+  ThisTokBuf += 2;
+
+  if (ThisTokBuf == ThisTokEnd || !isxdigit(*ThisTokBuf)) {
+    PP.Diag(Loc, diag::err_ucn_escape_no_digits);
+    HadError = 1;
+    return;
+  }
+  typedef uint32_t UTF32;
+
+  UTF32 UcnVal = 0;
+  unsigned short UcnLen = (ThisTokBuf[-1] == 'u' ? 4 : 8);
+  for (; ThisTokBuf != ThisTokEnd && UcnLen; ++ThisTokBuf, UcnLen--) {
+    int CharVal = HexDigitValue(ThisTokBuf[0]);
+    if (CharVal == -1) break;
+    UcnVal <<= 4;
+    UcnVal |= CharVal;
+  }
+  // If we didn't consume the proper number of digits, there is a problem.
+  if (UcnLen) {
+    PP.Diag(PP.AdvanceToTokenCharacter(Loc, ThisTokBuf-ThisTokBegin),
+            diag::err_ucn_escape_incomplete);
+    HadError = 1;
+    return;
+  }
+  // Check UCN constraints (C99 6.4.3p2).
+  if ((UcnVal < 0xa0 &&
+      (UcnVal != 0x24 && UcnVal != 0x40 && UcnVal != 0x60 )) // $, @, `
+      || (UcnVal >= 0xD800 && UcnVal <= 0xDFFF)
+      || (UcnVal > 0x10FFFF)) /* the maximum legal UTF32 value */ {
+    PP.Diag(Loc, diag::err_ucn_escape_invalid);
+    HadError = 1;
+    return;
+  }
+  // Now that we've parsed/checked the UCN, we convert from UTF32->UTF8.
+  // The conversion below was inspired by:
+  //   http://www.unicode.org/Public/PROGRAMS/CVTUTF/ConvertUTF.c
+  // First, we determine how many bytes the result will require.
+  typedef uint8_t UTF8;
+
+  unsigned short bytesToWrite = 0;
+  if (UcnVal < (UTF32)0x80)
+    bytesToWrite = 1;
+  else if (UcnVal < (UTF32)0x800)
+    bytesToWrite = 2;
+  else if (UcnVal < (UTF32)0x10000)
+    bytesToWrite = 3;
+  else
+    bytesToWrite = 4;
+
+  const unsigned byteMask = 0xBF;
+  const unsigned byteMark = 0x80;
+
+  // Once the bits are split out into bytes of UTF8, this is a mask OR-ed
+  // into the first byte, depending on how many bytes follow.
+  static const UTF8 firstByteMark[5] = {
+    0x00, 0x00, 0xC0, 0xE0, 0xF0
+  };
+  // Finally, we write the bytes into ResultBuf.
+  ResultBuf += bytesToWrite;
+  switch (bytesToWrite) { // note: everything falls through.
+    case 4: *--ResultBuf = (UTF8)((UcnVal | byteMark) & byteMask); UcnVal >>= 6;
+    case 3: *--ResultBuf = (UTF8)((UcnVal | byteMark) & byteMask); UcnVal >>= 6;
+    case 2: *--ResultBuf = (UTF8)((UcnVal | byteMark) & byteMask); UcnVal >>= 6;
+    case 1: *--ResultBuf = (UTF8) (UcnVal | firstByteMark[bytesToWrite]);
+  }
+  // Update the buffer.
+  ResultBuf += bytesToWrite;
+}
+
+
+///       integer-constant: [C99 6.4.4.1]
+///         decimal-constant integer-suffix
+///         octal-constant integer-suffix
+///         hexadecimal-constant integer-suffix
+///       decimal-constant:
+///         nonzero-digit
+///         decimal-constant digit
+///       octal-constant:
+///         0
+///         octal-constant octal-digit
+///       hexadecimal-constant:
+///         hexadecimal-prefix hexadecimal-digit
+///         hexadecimal-constant hexadecimal-digit
+///       hexadecimal-prefix: one of
+///         0x 0X
+///       integer-suffix:
+///         unsigned-suffix [long-suffix]
+///         unsigned-suffix [long-long-suffix]
+///         long-suffix [unsigned-suffix]
+///         long-long-suffix [unsigned-sufix]
+///       nonzero-digit:
+///         1 2 3 4 5 6 7 8 9
+///       octal-digit:
+///         0 1 2 3 4 5 6 7
+///       hexadecimal-digit:
+///         0 1 2 3 4 5 6 7 8 9
+///         a b c d e f
+///         A B C D E F
+///       unsigned-suffix: one of
+///         u U
+///       long-suffix: one of
+///         l L
+///       long-long-suffix: one of
+///         ll LL
+///
+///       floating-constant: [C99 6.4.4.2]
+///         TODO: add rules...
+///
+NumericLiteralParser::
+NumericLiteralParser(const char *begin, const char *end,
+                     SourceLocation TokLoc, Preprocessor &pp)
+  : PP(pp), ThisTokBegin(begin), ThisTokEnd(end) {
+
+  // This routine assumes that the range begin/end matches the regex for integer
+  // and FP constants (specifically, the 'pp-number' regex), and assumes that
+  // the byte at "*end" is both valid and not part of the regex.  Because of
+  // this, it doesn't have to check for 'overscan' in various places.
+  assert(!isalnum(*end) && *end != '.' && *end != '_' &&
+         "Lexer didn't maximally munch?");
+
+  s = DigitsBegin = begin;
+  saw_exponent = false;
+  saw_period = false;
+  isLong = false;
+  isUnsigned = false;
+  isLongLong = false;
+  isFloat = false;
+  isImaginary = false;
+  isMicrosoftInteger = false;
+  hadError = false;
+
+  if (*s == '0') { // parse radix
+    ParseNumberStartingWithZero(TokLoc);
+    if (hadError)
+      return;
+  } else { // the first digit is non-zero
+    radix = 10;
+    s = SkipDigits(s);
+    if (s == ThisTokEnd) {
+      // Done.
+    } else if (isxdigit(*s) && !(*s == 'e' || *s == 'E')) {
+      PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, s-begin),
+              diag::err_invalid_decimal_digit) << std::string(s, s+1);
+      hadError = true;
+      return;
+    } else if (*s == '.') {
+      s++;
+      saw_period = true;
+      s = SkipDigits(s);
+    }
+    if ((*s == 'e' || *s == 'E')) { // exponent
+      const char *Exponent = s;
+      s++;
+      saw_exponent = true;
+      if (*s == '+' || *s == '-')  s++; // sign
+      const char *first_non_digit = SkipDigits(s);
+      if (first_non_digit != s) {
+        s = first_non_digit;
+      } else {
+        PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, Exponent-begin),
+                diag::err_exponent_has_no_digits);
+        hadError = true;
+        return;
+      }
+    }
+  }
+
+  SuffixBegin = s;
+
+  // Parse the suffix.  At this point we can classify whether we have an FP or
+  // integer constant.
+  bool isFPConstant = isFloatingLiteral();
+
+  // Loop over all of the characters of the suffix.  If we see something bad,
+  // we break out of the loop.
+  for (; s != ThisTokEnd; ++s) {
+    switch (*s) {
+    case 'f':      // FP Suffix for "float"
+    case 'F':
+      if (!isFPConstant) break;  // Error for integer constant.
+      if (isFloat || isLong) break; // FF, LF invalid.
+      isFloat = true;
+      continue;  // Success.
+    case 'u':
+    case 'U':
+      if (isFPConstant) break;  // Error for floating constant.
+      if (isUnsigned) break;    // Cannot be repeated.
+      isUnsigned = true;
+      continue;  // Success.
+    case 'l':
+    case 'L':
+      if (isLong || isLongLong) break;  // Cannot be repeated.
+      if (isFloat) break;               // LF invalid.
+
+      // Check for long long.  The L's need to be adjacent and the same case.
+      if (s+1 != ThisTokEnd && s[1] == s[0]) {
+        if (isFPConstant) break;        // long long invalid for floats.
+        isLongLong = true;
+        ++s;  // Eat both of them.
+      } else {
+        isLong = true;
+      }
+      continue;  // Success.
+    case 'i':
+      if (PP.getLangOptions().Microsoft) {
+        if (isFPConstant || isLong || isLongLong) break;
+
+        // Allow i8, i16, i32, i64, and i128.
+        if (s + 1 != ThisTokEnd) {
+          switch (s[1]) {
+            case '8':
+              s += 2; // i8 suffix
+              isMicrosoftInteger = true;
+              break;
+            case '1':
+              if (s + 2 == ThisTokEnd) break;
+              if (s[2] == '6') s += 3; // i16 suffix
+              else if (s[2] == '2') {
+                if (s + 3 == ThisTokEnd) break;
+                if (s[3] == '8') s += 4; // i128 suffix
+              }
+              isMicrosoftInteger = true;
+              break;
+            case '3':
+              if (s + 2 == ThisTokEnd) break;
+              if (s[2] == '2') s += 3; // i32 suffix
+              isMicrosoftInteger = true;
+              break;
+            case '6':
+              if (s + 2 == ThisTokEnd) break;
+              if (s[2] == '4') s += 3; // i64 suffix
+              isMicrosoftInteger = true;
+              break;
+            default:
+              break;
+          }
+          break;
+        }
+      }
+      // fall through.
+    case 'I':
+    case 'j':
+    case 'J':
+      if (isImaginary) break;   // Cannot be repeated.
+      PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, s-begin),
+              diag::ext_imaginary_constant);
+      isImaginary = true;
+      continue;  // Success.
+    }
+    // If we reached here, there was an error.
+    break;
+  }
+
+  // Report an error if there are any.
+  if (s != ThisTokEnd) {
+    PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, s-begin),
+            isFPConstant ? diag::err_invalid_suffix_float_constant :
+                           diag::err_invalid_suffix_integer_constant)
+      << std::string(SuffixBegin, ThisTokEnd);
+    hadError = true;
+    return;
+  }
+}
+
+/// ParseNumberStartingWithZero - This method is called when the first character
+/// of the number is found to be a zero.  This means it is either an octal
+/// number (like '04') or a hex number ('0x123a') a binary number ('0b1010') or
+/// a floating point number (01239.123e4).  Eat the prefix, determining the
+/// radix etc.
+void NumericLiteralParser::ParseNumberStartingWithZero(SourceLocation TokLoc) {
+  assert(s[0] == '0' && "Invalid method call");
+  s++;
+
+  // Handle a hex number like 0x1234.
+  if ((*s == 'x' || *s == 'X') && (isxdigit(s[1]) || s[1] == '.')) {
+    s++;
+    radix = 16;
+    DigitsBegin = s;
+    s = SkipHexDigits(s);
+    if (s == ThisTokEnd) {
+      // Done.
+    } else if (*s == '.') {
+      s++;
+      saw_period = true;
+      s = SkipHexDigits(s);
+    }
+    // A binary exponent can appear with or with a '.'. If dotted, the
+    // binary exponent is required.
+    if ((*s == 'p' || *s == 'P') && !PP.getLangOptions().CPlusPlus0x) {
+      const char *Exponent = s;
+      s++;
+      saw_exponent = true;
+      if (*s == '+' || *s == '-')  s++; // sign
+      const char *first_non_digit = SkipDigits(s);
+      if (first_non_digit == s) {
+        PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, Exponent-ThisTokBegin),
+                diag::err_exponent_has_no_digits);
+        hadError = true;
+        return;
+      }
+      s = first_non_digit;
+
+      // In C++0x, we cannot support hexadecmial floating literals because
+      // they conflict with user-defined literals, so we warn in previous
+      // versions of C++ by default.
+      if (PP.getLangOptions().CPlusPlus)
+        PP.Diag(TokLoc, diag::ext_hexconstant_cplusplus);
+      else if (!PP.getLangOptions().HexFloats)
+        PP.Diag(TokLoc, diag::ext_hexconstant_invalid);
+    } else if (saw_period) {
+      PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, s-ThisTokBegin),
+              diag::err_hexconstant_requires_exponent);
+      hadError = true;
+    }
+    return;
+  }
+
+  // Handle simple binary numbers 0b01010
+  if (*s == 'b' || *s == 'B') {
+    // 0b101010 is a GCC extension.
+    PP.Diag(TokLoc, diag::ext_binary_literal);
+    ++s;
+    radix = 2;
+    DigitsBegin = s;
+    s = SkipBinaryDigits(s);
+    if (s == ThisTokEnd) {
+      // Done.
+    } else if (isxdigit(*s)) {
+      PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, s-ThisTokBegin),
+              diag::err_invalid_binary_digit) << std::string(s, s+1);
+      hadError = true;
+    }
+    // Other suffixes will be diagnosed by the caller.
+    return;
+  }
+
+  // For now, the radix is set to 8. If we discover that we have a
+  // floating point constant, the radix will change to 10. Octal floating
+  // point constants are not permitted (only decimal and hexadecimal).
+  radix = 8;
+  DigitsBegin = s;
+  s = SkipOctalDigits(s);
+  if (s == ThisTokEnd)
+    return; // Done, simple octal number like 01234
+
+  // If we have some other non-octal digit that *is* a decimal digit, see if
+  // this is part of a floating point number like 094.123 or 09e1.
+  if (isdigit(*s)) {
+    const char *EndDecimal = SkipDigits(s);
+    if (EndDecimal[0] == '.' || EndDecimal[0] == 'e' || EndDecimal[0] == 'E') {
+      s = EndDecimal;
+      radix = 10;
+    }
+  }
+
+  // If we have a hex digit other than 'e' (which denotes a FP exponent) then
+  // the code is using an incorrect base.
+  if (isxdigit(*s) && *s != 'e' && *s != 'E') {
+    PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, s-ThisTokBegin),
+            diag::err_invalid_octal_digit) << std::string(s, s+1);
+    hadError = true;
+    return;
+  }
+
+  if (*s == '.') {
+    s++;
+    radix = 10;
+    saw_period = true;
+    s = SkipDigits(s); // Skip suffix.
+  }
+  if (*s == 'e' || *s == 'E') { // exponent
+    const char *Exponent = s;
+    s++;
+    radix = 10;
+    saw_exponent = true;
+    if (*s == '+' || *s == '-')  s++; // sign
+    const char *first_non_digit = SkipDigits(s);
+    if (first_non_digit != s) {
+      s = first_non_digit;
+    } else {
+      PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, Exponent-ThisTokBegin),
+              diag::err_exponent_has_no_digits);
+      hadError = true;
+      return;
+    }
+  }
+}
+
+
+/// GetIntegerValue - Convert this numeric literal value to an APInt that
+/// matches Val's input width.  If there is an overflow, set Val to the low bits
+/// of the result and return true.  Otherwise, return false.
+bool NumericLiteralParser::GetIntegerValue(llvm::APInt &Val) {
+  // Fast path: Compute a conservative bound on the maximum number of
+  // bits per digit in this radix. If we can't possibly overflow a
+  // uint64 based on that bound then do the simple conversion to
+  // integer. This avoids the expensive overflow checking below, and
+  // handles the common cases that matter (small decimal integers and
+  // hex/octal values which don't overflow).
+  unsigned MaxBitsPerDigit = 1;
+  while ((1U << MaxBitsPerDigit) < radix)
+    MaxBitsPerDigit += 1;
+  if ((SuffixBegin - DigitsBegin) * MaxBitsPerDigit <= 64) {
+    uint64_t N = 0;
+    for (s = DigitsBegin; s != SuffixBegin; ++s)
+      N = N*radix + HexDigitValue(*s);
+
+    // This will truncate the value to Val's input width. Simply check
+    // for overflow by comparing.
+    Val = N;
+    return Val.getZExtValue() != N;
+  }
+
+  Val = 0;
+  s = DigitsBegin;
+
+  llvm::APInt RadixVal(Val.getBitWidth(), radix);
+  llvm::APInt CharVal(Val.getBitWidth(), 0);
+  llvm::APInt OldVal = Val;
+
+  bool OverflowOccurred = false;
+  while (s < SuffixBegin) {
+    unsigned C = HexDigitValue(*s++);
+
+    // If this letter is out of bound for this radix, reject it.
+    assert(C < radix && "NumericLiteralParser ctor should have rejected this");
+
+    CharVal = C;
+
+    // Add the digit to the value in the appropriate radix.  If adding in digits
+    // made the value smaller, then this overflowed.
+    OldVal = Val;
+
+    // Multiply by radix, did overflow occur on the multiply?
+    Val *= RadixVal;
+    OverflowOccurred |= Val.udiv(RadixVal) != OldVal;
+
+    // Add value, did overflow occur on the value?
+    //   (a + b) ult b  <=> overflow
+    Val += CharVal;
+    OverflowOccurred |= Val.ult(CharVal);
+  }
+  return OverflowOccurred;
+}
+
+llvm::APFloat::opStatus
+NumericLiteralParser::GetFloatValue(llvm::APFloat &Result) {
+  using llvm::APFloat;
+  using llvm::StringRef;
+
+  unsigned n = std::min(SuffixBegin - ThisTokBegin, ThisTokEnd - ThisTokBegin);
+  return Result.convertFromString(StringRef(ThisTokBegin, n),
+                                  APFloat::rmNearestTiesToEven);
+}
+
+
+CharLiteralParser::CharLiteralParser(const char *begin, const char *end,
+                                     SourceLocation Loc, Preprocessor &PP) {
+  // At this point we know that the character matches the regex "L?'.*'".
+  HadError = false;
+
+  // Determine if this is a wide character.
+  IsWide = begin[0] == 'L';
+  if (IsWide) ++begin;
+
+  // Skip over the entry quote.
+  assert(begin[0] == '\'' && "Invalid token lexed");
+  ++begin;
+
+  // FIXME: The "Value" is an uint64_t so we can handle char literals of
+  // upto 64-bits.
+  // FIXME: This extensively assumes that 'char' is 8-bits.
+  assert(PP.getTargetInfo().getCharWidth() == 8 &&
+         "Assumes char is 8 bits");
+  assert(PP.getTargetInfo().getIntWidth() <= 64 &&
+         (PP.getTargetInfo().getIntWidth() & 7) == 0 &&
+         "Assumes sizeof(int) on target is <= 64 and a multiple of char");
+  assert(PP.getTargetInfo().getWCharWidth() <= 64 &&
+         "Assumes sizeof(wchar) on target is <= 64");
+
+  // This is what we will use for overflow detection
+  llvm::APInt LitVal(PP.getTargetInfo().getIntWidth(), 0);
+
+  unsigned NumCharsSoFar = 0;
+  bool Warned = false;
+  while (begin[0] != '\'') {
+    uint64_t ResultChar;
+    if (begin[0] != '\\')     // If this is a normal character, consume it.
+      ResultChar = *begin++;
+    else                      // Otherwise, this is an escape character.
+      ResultChar = ProcessCharEscape(begin, end, HadError, Loc, IsWide, PP);
+
+    // If this is a multi-character constant (e.g. 'abc'), handle it.  These are
+    // implementation defined (C99 6.4.4.4p10).
+    if (NumCharsSoFar) {
+      if (IsWide) {
+        // Emulate GCC's (unintentional?) behavior: L'ab' -> L'b'.
+        LitVal = 0;
+      } else {
+        // Narrow character literals act as though their value is concatenated
+        // in this implementation, but warn on overflow.
+        if (LitVal.countLeadingZeros() < 8 && !Warned) {
+          PP.Diag(Loc, diag::warn_char_constant_too_large);
+          Warned = true;
+        }
+        LitVal <<= 8;
+      }
+    }
+
+    LitVal = LitVal + ResultChar;
+    ++NumCharsSoFar;
+  }
+
+  // If this is the second character being processed, do special handling.
+  if (NumCharsSoFar > 1) {
+    // Warn about discarding the top bits for multi-char wide-character
+    // constants (L'abcd').
+    if (IsWide)
+      PP.Diag(Loc, diag::warn_extraneous_wide_char_constant);
+    else if (NumCharsSoFar != 4)
+      PP.Diag(Loc, diag::ext_multichar_character_literal);
+    else
+      PP.Diag(Loc, diag::ext_four_char_character_literal);
+    IsMultiChar = true;
+  } else
+    IsMultiChar = false;
+
+  // Transfer the value from APInt to uint64_t
+  Value = LitVal.getZExtValue();
+
+  // If this is a single narrow character, sign extend it (e.g. '\xFF' is "-1")
+  // if 'char' is signed for this target (C99 6.4.4.4p10).  Note that multiple
+  // character constants are not sign extended in the this implementation:
+  // '\xFF\xFF' = 65536 and '\x0\xFF' = 255, which matches GCC.
+  if (!IsWide && NumCharsSoFar == 1 && (Value & 128) &&
+      PP.getLangOptions().CharIsSigned)
+    Value = (signed char)Value;
+}
+
+
+///       string-literal: [C99 6.4.5]
+///          " [s-char-sequence] "
+///         L" [s-char-sequence] "
+///       s-char-sequence:
+///         s-char
+///         s-char-sequence s-char
+///       s-char:
+///         any source character except the double quote ",
+///           backslash \, or newline character
+///         escape-character
+///         universal-character-name
+///       escape-character: [C99 6.4.4.4]
+///         \ escape-code
+///         universal-character-name
+///       escape-code:
+///         character-escape-code
+///         octal-escape-code
+///         hex-escape-code
+///       character-escape-code: one of
+///         n t b r f v a
+///         \ ' " ?
+///       octal-escape-code:
+///         octal-digit
+///         octal-digit octal-digit
+///         octal-digit octal-digit octal-digit
+///       hex-escape-code:
+///         x hex-digit
+///         hex-escape-code hex-digit
+///       universal-character-name:
+///         \u hex-quad
+///         \U hex-quad hex-quad
+///       hex-quad:
+///         hex-digit hex-digit hex-digit hex-digit
+///
+StringLiteralParser::
+StringLiteralParser(const Token *StringToks, unsigned NumStringToks,
+                    Preprocessor &pp) : PP(pp) {
+  // Scan all of the string portions, remember the max individual token length,
+  // computing a bound on the concatenated string length, and see whether any
+  // piece is a wide-string.  If any of the string portions is a wide-string
+  // literal, the result is a wide-string literal [C99 6.4.5p4].
+  MaxTokenLength = StringToks[0].getLength();
+  SizeBound = StringToks[0].getLength()-2;  // -2 for "".
+  AnyWide = StringToks[0].is(tok::wide_string_literal);
+
+  hadError = false;
+
+  // Implement Translation Phase #6: concatenation of string literals
+  /// (C99 5.1.1.2p1).  The common case is only one string fragment.
+  for (unsigned i = 1; i != NumStringToks; ++i) {
+    // The string could be shorter than this if it needs cleaning, but this is a
+    // reasonable bound, which is all we need.
+    SizeBound += StringToks[i].getLength()-2;  // -2 for "".
+
+    // Remember maximum string piece length.
+    if (StringToks[i].getLength() > MaxTokenLength)
+      MaxTokenLength = StringToks[i].getLength();
+
+    // Remember if we see any wide strings.
+    AnyWide |= StringToks[i].is(tok::wide_string_literal);
+  }
+
+  // Include space for the null terminator.
+  ++SizeBound;
+
+  // TODO: K&R warning: "traditional C rejects string constant concatenation"
+
+  // Get the width in bytes of wchar_t.  If no wchar_t strings are used, do not
+  // query the target.  As such, wchar_tByteWidth is only valid if AnyWide=true.
+  wchar_tByteWidth = ~0U;
+  if (AnyWide) {
+    wchar_tByteWidth = PP.getTargetInfo().getWCharWidth();
+    assert((wchar_tByteWidth & 7) == 0 && "Assumes wchar_t is byte multiple!");
+    wchar_tByteWidth /= 8;
+  }
+
+  // The output buffer size needs to be large enough to hold wide characters.
+  // This is a worst-case assumption which basically corresponds to L"" "long".
+  if (AnyWide)
+    SizeBound *= wchar_tByteWidth;
+
+  // Size the temporary buffer to hold the result string data.
+  ResultBuf.resize(SizeBound);
+
+  // Likewise, but for each string piece.
+  llvm::SmallString<512> TokenBuf;
+  TokenBuf.resize(MaxTokenLength);
+
+  // Loop over all the strings, getting their spelling, and expanding them to
+  // wide strings as appropriate.
+  ResultPtr = &ResultBuf[0];   // Next byte to fill in.
+
+  Pascal = false;
+
+  for (unsigned i = 0, e = NumStringToks; i != e; ++i) {
+    const char *ThisTokBuf = &TokenBuf[0];
+    // Get the spelling of the token, which eliminates trigraphs, etc.  We know
+    // that ThisTokBuf points to a buffer that is big enough for the whole token
+    // and 'spelled' tokens can only shrink.
+    bool StringInvalid = false;
+    unsigned ThisTokLen = PP.getSpelling(StringToks[i], ThisTokBuf, 
+                                         &StringInvalid);
+    if (StringInvalid) {
+      hadError = 1;
+      continue;
+    }
+
+    const char *ThisTokEnd = ThisTokBuf+ThisTokLen-1;  // Skip end quote.
+
+    // TODO: Input character set mapping support.
+
+    // Skip L marker for wide strings.
+    bool ThisIsWide = false;
+    if (ThisTokBuf[0] == 'L') {
+      ++ThisTokBuf;
+      ThisIsWide = true;
+    }
+
+    assert(ThisTokBuf[0] == '"' && "Expected quote, lexer broken?");
+    ++ThisTokBuf;
+
+    // Check if this is a pascal string
+    if (pp.getLangOptions().PascalStrings && ThisTokBuf + 1 != ThisTokEnd &&
+        ThisTokBuf[0] == '\\' && ThisTokBuf[1] == 'p') {
+
+      // If the \p sequence is found in the first token, we have a pascal string
+      // Otherwise, if we already have a pascal string, ignore the first \p
+      if (i == 0) {
+        ++ThisTokBuf;
+        Pascal = true;
+      } else if (Pascal)
+        ThisTokBuf += 2;
+    }
+
+    while (ThisTokBuf != ThisTokEnd) {
+      // Is this a span of non-escape characters?
+      if (ThisTokBuf[0] != '\\') {
+        const char *InStart = ThisTokBuf;
+        do {
+          ++ThisTokBuf;
+        } while (ThisTokBuf != ThisTokEnd && ThisTokBuf[0] != '\\');
+
+        // Copy the character span over.
+        unsigned Len = ThisTokBuf-InStart;
+        if (!AnyWide) {
+          memcpy(ResultPtr, InStart, Len);
+          ResultPtr += Len;
+        } else {
+          // Note: our internal rep of wide char tokens is always little-endian.
+          for (; Len; --Len, ++InStart) {
+            *ResultPtr++ = InStart[0];
+            // Add zeros at the end.
+            for (unsigned i = 1, e = wchar_tByteWidth; i != e; ++i)
+              *ResultPtr++ = 0;
+          }
+        }
+        continue;
+      }
+      // Is this a Universal Character Name escape?
+      if (ThisTokBuf[1] == 'u' || ThisTokBuf[1] == 'U') {
+        ProcessUCNEscape(ThisTokBuf, ThisTokEnd, ResultPtr,
+                         hadError, StringToks[i].getLocation(), ThisIsWide, PP);
+        continue;
+      }
+      // Otherwise, this is a non-UCN escape character.  Process it.
+      unsigned ResultChar = ProcessCharEscape(ThisTokBuf, ThisTokEnd, hadError,
+                                              StringToks[i].getLocation(),
+                                              ThisIsWide, PP);
+
+      // Note: our internal rep of wide char tokens is always little-endian.
+      *ResultPtr++ = ResultChar & 0xFF;
+
+      if (AnyWide) {
+        for (unsigned i = 1, e = wchar_tByteWidth; i != e; ++i)
+          *ResultPtr++ = ResultChar >> i*8;
+      }
+    }
+  }
+
+  if (Pascal) {
+    ResultBuf[0] = ResultPtr-&ResultBuf[0]-1;
+
+    // Verify that pascal strings aren't too large.
+    if (GetStringLength() > 256) {
+      PP.Diag(StringToks[0].getLocation(), diag::err_pascal_string_too_long)
+        << SourceRange(StringToks[0].getLocation(),
+                       StringToks[NumStringToks-1].getLocation());
+      hadError = 1;
+      return;
+    }
+  }
+}
+
+
+/// getOffsetOfStringByte - This function returns the offset of the
+/// specified byte of the string data represented by Token.  This handles
+/// advancing over escape sequences in the string.
+unsigned StringLiteralParser::getOffsetOfStringByte(const Token &Tok,
+                                                    unsigned ByteNo,
+                                                    Preprocessor &PP) {
+  // Get the spelling of the token.
+  llvm::SmallString<16> SpellingBuffer;
+  SpellingBuffer.resize(Tok.getLength());
+
+  bool StringInvalid = false;
+  const char *SpellingPtr = &SpellingBuffer[0];
+  unsigned TokLen = PP.getSpelling(Tok, SpellingPtr, &StringInvalid);
+  if (StringInvalid) {
+    return 0;
+  }
+
+  assert(SpellingPtr[0] != 'L' && "Doesn't handle wide strings yet");
+
+
+  const char *SpellingStart = SpellingPtr;
+  const char *SpellingEnd = SpellingPtr+TokLen;
+
+  // Skip over the leading quote.
+  assert(SpellingPtr[0] == '"' && "Should be a string literal!");
+  ++SpellingPtr;
+
+  // Skip over bytes until we find the offset we're looking for.
+  while (ByteNo) {
+    assert(SpellingPtr < SpellingEnd && "Didn't find byte offset!");
+
+    // Step over non-escapes simply.
+    if (*SpellingPtr != '\\') {
+      ++SpellingPtr;
+      --ByteNo;
+      continue;
+    }
+
+    // Otherwise, this is an escape character.  Advance over it.
+    bool HadError = false;
+    ProcessCharEscape(SpellingPtr, SpellingEnd, HadError,
+                      Tok.getLocation(), false, PP);
+    assert(!HadError && "This method isn't valid on erroneous strings");
+    --ByteNo;
+  }
+
+  return SpellingPtr-SpellingStart;
+}
diff --git a/lib/Lex/MacroArgs.cpp b/lib/Lex/MacroArgs.cpp
new file mode 100644
index 0000000..89f6368
--- /dev/null
+++ b/lib/Lex/MacroArgs.cpp
@@ -0,0 +1,293 @@
+//===--- TokenLexer.cpp - Lex from a token stream -------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the TokenLexer interface.
+//
+//===----------------------------------------------------------------------===//
+
+#include "MacroArgs.h"
+#include "clang/Lex/MacroInfo.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Lex/LexDiagnostic.h"
+using namespace clang;
+
+/// MacroArgs ctor function - This destroys the vector passed in.
+MacroArgs *MacroArgs::create(const MacroInfo *MI,
+                             const Token *UnexpArgTokens,
+                             unsigned NumToks, bool VarargsElided,
+                             Preprocessor &PP) {
+  assert(MI->isFunctionLike() &&
+         "Can't have args for an object-like macro!");
+  MacroArgs **ResultEnt = 0;
+  unsigned ClosestMatch = ~0U;
+  
+  // See if we have an entry with a big enough argument list to reuse on the
+  // free list.  If so, reuse it.
+  for (MacroArgs **Entry = &PP.MacroArgCache; *Entry;
+       Entry = &(*Entry)->ArgCache)
+    if ((*Entry)->NumUnexpArgTokens >= NumToks &&
+        (*Entry)->NumUnexpArgTokens < ClosestMatch) {
+      ResultEnt = Entry;
+      
+      // If we have an exact match, use it.
+      if ((*Entry)->NumUnexpArgTokens == NumToks)
+        break;
+      // Otherwise, use the best fit.
+      ClosestMatch = (*Entry)->NumUnexpArgTokens;
+    }
+  
+  MacroArgs *Result;
+  if (ResultEnt == 0) {
+    // Allocate memory for a MacroArgs object with the lexer tokens at the end.
+    Result = (MacroArgs*)malloc(sizeof(MacroArgs) + NumToks*sizeof(Token));
+    // Construct the MacroArgs object.
+    new (Result) MacroArgs(NumToks, VarargsElided);
+  } else {
+    Result = *ResultEnt;
+    // Unlink this node from the preprocessors singly linked list.
+    *ResultEnt = Result->ArgCache;
+    Result->NumUnexpArgTokens = NumToks;
+    Result->VarargsElided = VarargsElided;
+  }
+
+  // Copy the actual unexpanded tokens to immediately after the result ptr.
+  if (NumToks)
+    memcpy(const_cast<Token*>(Result->getUnexpArgument(0)),
+           UnexpArgTokens, NumToks*sizeof(Token));
+
+  return Result;
+}
+
+/// destroy - Destroy and deallocate the memory for this object.
+///
+void MacroArgs::destroy(Preprocessor &PP) {
+  StringifiedArgs.clear();
+
+  // Don't clear PreExpArgTokens, just clear the entries.  Clearing the entries
+  // would deallocate the element vectors.
+  for (unsigned i = 0, e = PreExpArgTokens.size(); i != e; ++i)
+    PreExpArgTokens[i].clear();
+  
+  // Add this to the preprocessor's free list.
+  ArgCache = PP.MacroArgCache;
+  PP.MacroArgCache = this;
+}
+
+/// deallocate - This should only be called by the Preprocessor when managing
+/// its freelist.
+MacroArgs *MacroArgs::deallocate() {
+  MacroArgs *Next = ArgCache;
+  
+  // Run the dtor to deallocate the vectors.
+  this->~MacroArgs();
+  // Release the memory for the object.
+  free(this);
+  
+  return Next;
+}
+
+
+/// getArgLength - Given a pointer to an expanded or unexpanded argument,
+/// return the number of tokens, not counting the EOF, that make up the
+/// argument.
+unsigned MacroArgs::getArgLength(const Token *ArgPtr) {
+  unsigned NumArgTokens = 0;
+  for (; ArgPtr->isNot(tok::eof); ++ArgPtr)
+    ++NumArgTokens;
+  return NumArgTokens;
+}
+
+
+/// getUnexpArgument - Return the unexpanded tokens for the specified formal.
+///
+const Token *MacroArgs::getUnexpArgument(unsigned Arg) const {
+  // The unexpanded argument tokens start immediately after the MacroArgs object
+  // in memory.
+  const Token *Start = (const Token *)(this+1);
+  const Token *Result = Start;
+  // Scan to find Arg.
+  for (; Arg; ++Result) {
+    assert(Result < Start+NumUnexpArgTokens && "Invalid arg #");
+    if (Result->is(tok::eof))
+      --Arg;
+  }
+  assert(Result < Start+NumUnexpArgTokens && "Invalid arg #");
+  return Result;
+}
+
+
+/// ArgNeedsPreexpansion - If we can prove that the argument won't be affected
+/// by pre-expansion, return false.  Otherwise, conservatively return true.
+bool MacroArgs::ArgNeedsPreexpansion(const Token *ArgTok,
+                                     Preprocessor &PP) const {
+  // If there are no identifiers in the argument list, or if the identifiers are
+  // known to not be macros, pre-expansion won't modify it.
+  for (; ArgTok->isNot(tok::eof); ++ArgTok)
+    if (IdentifierInfo *II = ArgTok->getIdentifierInfo()) {
+      if (II->hasMacroDefinition() && PP.getMacroInfo(II)->isEnabled())
+        // Return true even though the macro could be a function-like macro
+        // without a following '(' token.
+        return true;
+    }
+  return false;
+}
+
+/// getPreExpArgument - Return the pre-expanded form of the specified
+/// argument.
+const std::vector<Token> &
+MacroArgs::getPreExpArgument(unsigned Arg, const MacroInfo *MI, 
+                             Preprocessor &PP) {
+  assert(Arg < MI->getNumArgs() && "Invalid argument number!");
+
+  // If we have already computed this, return it.
+  if (PreExpArgTokens.size() < MI->getNumArgs())
+    PreExpArgTokens.resize(MI->getNumArgs());
+  
+  std::vector<Token> &Result = PreExpArgTokens[Arg];
+  if (!Result.empty()) return Result;
+
+  const Token *AT = getUnexpArgument(Arg);
+  unsigned NumToks = getArgLength(AT)+1;  // Include the EOF.
+
+  // Otherwise, we have to pre-expand this argument, populating Result.  To do
+  // this, we set up a fake TokenLexer to lex from the unexpanded argument
+  // list.  With this installed, we lex expanded tokens until we hit the EOF
+  // token at the end of the unexp list.
+  PP.EnterTokenStream(AT, NumToks, false /*disable expand*/,
+                      false /*owns tokens*/);
+
+  // Lex all of the macro-expanded tokens into Result.
+  do {
+    Result.push_back(Token());
+    Token &Tok = Result.back();
+    PP.Lex(Tok);
+  } while (Result.back().isNot(tok::eof));
+
+  // Pop the token stream off the top of the stack.  We know that the internal
+  // pointer inside of it is to the "end" of the token stream, but the stack
+  // will not otherwise be popped until the next token is lexed.  The problem is
+  // that the token may be lexed sometime after the vector of tokens itself is
+  // destroyed, which would be badness.
+  PP.RemoveTopOfLexerStack();
+  return Result;
+}
+
+
+/// StringifyArgument - Implement C99 6.10.3.2p2, converting a sequence of
+/// tokens into the literal string token that should be produced by the C #
+/// preprocessor operator.  If Charify is true, then it should be turned into
+/// a character literal for the Microsoft charize (#@) extension.
+///
+Token MacroArgs::StringifyArgument(const Token *ArgToks,
+                                   Preprocessor &PP, bool Charify) {
+  Token Tok;
+  Tok.startToken();
+  Tok.setKind(Charify ? tok::char_constant : tok::string_literal);
+
+  const Token *ArgTokStart = ArgToks;
+
+  // Stringify all the tokens.
+  llvm::SmallString<128> Result;
+  Result += "\"";
+
+  bool isFirst = true;
+  for (; ArgToks->isNot(tok::eof); ++ArgToks) {
+    const Token &Tok = *ArgToks;
+    if (!isFirst && (Tok.hasLeadingSpace() || Tok.isAtStartOfLine()))
+      Result += ' ';
+    isFirst = false;
+
+    // If this is a string or character constant, escape the token as specified
+    // by 6.10.3.2p2.
+    if (Tok.is(tok::string_literal) ||       // "foo"
+        Tok.is(tok::wide_string_literal) ||  // L"foo"
+        Tok.is(tok::char_constant)) {        // 'x' and L'x'.
+      bool Invalid = false;
+      std::string TokStr = PP.getSpelling(Tok, &Invalid);
+      if (!Invalid) {
+        std::string Str = Lexer::Stringify(TokStr);
+        Result.append(Str.begin(), Str.end());
+      }
+    } else {
+      // Otherwise, just append the token.  Do some gymnastics to get the token
+      // in place and avoid copies where possible.
+      unsigned CurStrLen = Result.size();
+      Result.resize(CurStrLen+Tok.getLength());
+      const char *BufPtr = &Result[CurStrLen];
+      bool Invalid = false;
+      unsigned ActualTokLen = PP.getSpelling(Tok, BufPtr, &Invalid);
+
+      if (!Invalid) {
+        // If getSpelling returned a pointer to an already uniqued version of
+        // the string instead of filling in BufPtr, memcpy it onto our string.
+        if (BufPtr != &Result[CurStrLen])
+          memcpy(&Result[CurStrLen], BufPtr, ActualTokLen);
+
+        // If the token was dirty, the spelling may be shorter than the token.
+        if (ActualTokLen != Tok.getLength())
+          Result.resize(CurStrLen+ActualTokLen);
+      }
+    }
+  }
+
+  // If the last character of the string is a \, and if it isn't escaped, this
+  // is an invalid string literal, diagnose it as specified in C99.
+  if (Result.back() == '\\') {
+    // Count the number of consequtive \ characters.  If even, then they are
+    // just escaped backslashes, otherwise it's an error.
+    unsigned FirstNonSlash = Result.size()-2;
+    // Guaranteed to find the starting " if nothing else.
+    while (Result[FirstNonSlash] == '\\')
+      --FirstNonSlash;
+    if ((Result.size()-1-FirstNonSlash) & 1) {
+      // Diagnose errors for things like: #define F(X) #X   /   F(\)
+      PP.Diag(ArgToks[-1], diag::pp_invalid_string_literal);
+      Result.pop_back();  // remove one of the \'s.
+    }
+  }
+  Result += '"';
+
+  // If this is the charify operation and the result is not a legal character
+  // constant, diagnose it.
+  if (Charify) {
+    // First step, turn double quotes into single quotes:
+    Result[0] = '\'';
+    Result[Result.size()-1] = '\'';
+
+    // Check for bogus character.
+    bool isBad = false;
+    if (Result.size() == 3)
+      isBad = Result[1] == '\'';   // ''' is not legal. '\' already fixed above.
+    else
+      isBad = (Result.size() != 4 || Result[1] != '\\');  // Not '\x'
+
+    if (isBad) {
+      PP.Diag(ArgTokStart[0], diag::err_invalid_character_to_charify);
+      Result = "' '";  // Use something arbitrary, but legal.
+    }
+  }
+
+  PP.CreateString(&Result[0], Result.size(), Tok);
+  return Tok;
+}
+
+/// getStringifiedArgument - Compute, cache, and return the specified argument
+/// that has been 'stringified' as required by the # operator.
+const Token &MacroArgs::getStringifiedArgument(unsigned ArgNo,
+                                               Preprocessor &PP) {
+  assert(ArgNo < NumUnexpArgTokens && "Invalid argument number!");
+  if (StringifiedArgs.empty()) {
+    StringifiedArgs.resize(getNumArguments());
+    memset(&StringifiedArgs[0], 0,
+           sizeof(StringifiedArgs[0])*getNumArguments());
+  }
+  if (StringifiedArgs[ArgNo].isNot(tok::string_literal))
+    StringifiedArgs[ArgNo] = StringifyArgument(getUnexpArgument(ArgNo), PP);
+  return StringifiedArgs[ArgNo];
+}
diff --git a/lib/Lex/MacroArgs.h b/lib/Lex/MacroArgs.h
new file mode 100644
index 0000000..6ff4856
--- /dev/null
+++ b/lib/Lex/MacroArgs.h
@@ -0,0 +1,119 @@
+//===--- MacroArgs.h - Formal argument info for Macros ----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the MacroArgs interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_MACROARGS_H
+#define LLVM_CLANG_MACROARGS_H
+
+#include <vector>
+
+namespace clang {
+  class MacroInfo;
+  class Preprocessor;
+  class Token;
+
+/// MacroArgs - An instance of this class captures information about
+/// the formal arguments specified to a function-like macro invocation.
+class MacroArgs {
+  /// NumUnexpArgTokens - The number of raw, unexpanded tokens for the
+  /// arguments.  All of the actual argument tokens are allocated immediately
+  /// after the MacroArgs object in memory.  This is all of the arguments
+  /// concatenated together, with 'EOF' markers at the end of each argument.
+  unsigned NumUnexpArgTokens;
+
+  /// VarargsElided - True if this is a C99 style varargs macro invocation and
+  /// there was no argument specified for the "..." argument.  If the argument
+  /// was specified (even empty) or this isn't a C99 style varargs function, or
+  /// if in strict mode and the C99 varargs macro had only a ... argument, this
+  /// is false.
+  bool VarargsElided;
+  
+  /// PreExpArgTokens - Pre-expanded tokens for arguments that need them.  Empty
+  /// if not yet computed.  This includes the EOF marker at the end of the
+  /// stream.
+  std::vector<std::vector<Token> > PreExpArgTokens;
+
+  /// StringifiedArgs - This contains arguments in 'stringified' form.  If the
+  /// stringified form of an argument has not yet been computed, this is empty.
+  std::vector<Token> StringifiedArgs;
+
+  /// ArgCache - This is a linked list of MacroArgs objects that the
+  /// Preprocessor owns which we use to avoid thrashing malloc/free.
+  MacroArgs *ArgCache;
+  
+  MacroArgs(unsigned NumToks, bool varargsElided)
+    : NumUnexpArgTokens(NumToks), VarargsElided(varargsElided), ArgCache(0) {}
+  ~MacroArgs() {}
+public:
+  /// MacroArgs ctor function - Create a new MacroArgs object with the specified
+  /// macro and argument info.
+  static MacroArgs *create(const MacroInfo *MI,
+                           const Token *UnexpArgTokens,
+                           unsigned NumArgTokens, bool VarargsElided,
+                           Preprocessor &PP);
+
+  /// destroy - Destroy and deallocate the memory for this object.
+  ///
+  void destroy(Preprocessor &PP);
+
+  /// ArgNeedsPreexpansion - If we can prove that the argument won't be affected
+  /// by pre-expansion, return false.  Otherwise, conservatively return true.
+  bool ArgNeedsPreexpansion(const Token *ArgTok, Preprocessor &PP) const;
+
+  /// getUnexpArgument - Return a pointer to the first token of the unexpanded
+  /// token list for the specified formal.
+  ///
+  const Token *getUnexpArgument(unsigned Arg) const;
+
+  /// getArgLength - Given a pointer to an expanded or unexpanded argument,
+  /// return the number of tokens, not counting the EOF, that make up the
+  /// argument.
+  static unsigned getArgLength(const Token *ArgPtr);
+
+  /// getPreExpArgument - Return the pre-expanded form of the specified
+  /// argument.
+  const std::vector<Token> &
+    getPreExpArgument(unsigned Arg, const MacroInfo *MI, Preprocessor &PP);
+
+  /// getStringifiedArgument - Compute, cache, and return the specified argument
+  /// that has been 'stringified' as required by the # operator.
+  const Token &getStringifiedArgument(unsigned ArgNo, Preprocessor &PP);
+
+  /// getNumArguments - Return the number of arguments passed into this macro
+  /// invocation.
+  unsigned getNumArguments() const { return NumUnexpArgTokens; }
+
+
+  /// isVarargsElidedUse - Return true if this is a C99 style varargs macro
+  /// invocation and there was no argument specified for the "..." argument.  If
+  /// the argument was specified (even empty) or this isn't a C99 style varargs
+  /// function, or if in strict mode and the C99 varargs macro had only a ...
+  /// argument, this returns false.
+  bool isVarargsElidedUse() const { return VarargsElided; }
+
+  /// StringifyArgument - Implement C99 6.10.3.2p2, converting a sequence of
+  /// tokens into the literal string token that should be produced by the C #
+  /// preprocessor operator.  If Charify is true, then it should be turned into
+  /// a character literal for the Microsoft charize (#@) extension.
+  ///
+  static Token StringifyArgument(const Token *ArgToks,
+                                 Preprocessor &PP, bool Charify = false);
+  
+  
+  /// deallocate - This should only be called by the Preprocessor when managing
+  /// its freelist.
+  MacroArgs *deallocate();
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/lib/Lex/MacroInfo.cpp b/lib/Lex/MacroInfo.cpp
new file mode 100644
index 0000000..fda884c
--- /dev/null
+++ b/lib/Lex/MacroInfo.cpp
@@ -0,0 +1,75 @@
+//===--- MacroInfo.cpp - Information about #defined identifiers -----------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the MacroInfo interface.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Lex/MacroInfo.h"
+#include "clang/Lex/Preprocessor.h"
+using namespace clang;
+
+MacroInfo::MacroInfo(SourceLocation DefLoc) : Location(DefLoc) {
+  IsFunctionLike = false;
+  IsC99Varargs = false;
+  IsGNUVarargs = false;
+  IsBuiltinMacro = false;
+  IsDisabled = false;
+  IsUsed = true;
+
+  ArgumentList = 0;
+  NumArguments = 0;
+}
+
+/// isIdenticalTo - Return true if the specified macro definition is equal to
+/// this macro in spelling, arguments, and whitespace.  This is used to emit
+/// duplicate definition warnings.  This implements the rules in C99 6.10.3.
+///
+bool MacroInfo::isIdenticalTo(const MacroInfo &Other, Preprocessor &PP) const {
+  // Check # tokens in replacement, number of args, and various flags all match.
+  if (ReplacementTokens.size() != Other.ReplacementTokens.size() ||
+      getNumArgs() != Other.getNumArgs() ||
+      isFunctionLike() != Other.isFunctionLike() ||
+      isC99Varargs() != Other.isC99Varargs() ||
+      isGNUVarargs() != Other.isGNUVarargs())
+    return false;
+
+  // Check arguments.
+  for (arg_iterator I = arg_begin(), OI = Other.arg_begin(), E = arg_end();
+       I != E; ++I, ++OI)
+    if (*I != *OI) return false;
+
+  // Check all the tokens.
+  for (unsigned i = 0, e = ReplacementTokens.size(); i != e; ++i) {
+    const Token &A = ReplacementTokens[i];
+    const Token &B = Other.ReplacementTokens[i];
+    if (A.getKind() != B.getKind())
+      return false;
+
+    // If this isn't the first first token, check that the whitespace and
+    // start-of-line characteristics match.
+    if (i != 0 &&
+        (A.isAtStartOfLine() != B.isAtStartOfLine() ||
+         A.hasLeadingSpace() != B.hasLeadingSpace()))
+      return false;
+
+    // If this is an identifier, it is easy.
+    if (A.getIdentifierInfo() || B.getIdentifierInfo()) {
+      if (A.getIdentifierInfo() != B.getIdentifierInfo())
+        return false;
+      continue;
+    }
+
+    // Otherwise, check the spelling.
+    if (PP.getSpelling(A) != PP.getSpelling(B))
+      return false;
+  }
+
+  return true;
+}
diff --git a/lib/Lex/Makefile b/lib/Lex/Makefile
new file mode 100644
index 0000000..bd3c7a8
--- /dev/null
+++ b/lib/Lex/Makefile
@@ -0,0 +1,27 @@
+##===- clang/lib/Lex/Makefile ------------------------------*- Makefile -*-===##
+# 
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+# 
+##===----------------------------------------------------------------------===##
+#
+#  This implements the Lexer library for the C-Language front-end.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../../../..
+include $(LEVEL)/Makefile.config
+
+LIBRARYNAME := clangLex
+BUILD_ARCHIVE = 1
+
+ifeq ($(ARCH),PowerPC)
+CXX.Flags += -maltivec
+endif
+
+CPP.Flags += -I$(PROJ_SRC_DIR)/../../include -I$(PROJ_OBJ_DIR)/../../include
+
+include $(LEVEL)/Makefile.common
+
diff --git a/lib/Lex/PPCaching.cpp b/lib/Lex/PPCaching.cpp
new file mode 100644
index 0000000..6aeb6fa
--- /dev/null
+++ b/lib/Lex/PPCaching.cpp
@@ -0,0 +1,112 @@
+//===--- PPCaching.cpp - Handle caching lexed tokens ----------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements pieces of the Preprocessor interface that manage the
+// caching of lexed tokens.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Lex/Preprocessor.h"
+using namespace clang;
+
+/// EnableBacktrackAtThisPos - From the point that this method is called, and
+/// until CommitBacktrackedTokens() or Backtrack() is called, the Preprocessor
+/// keeps track of the lexed tokens so that a subsequent Backtrack() call will
+/// make the Preprocessor re-lex the same tokens.
+///
+/// Nested backtracks are allowed, meaning that EnableBacktrackAtThisPos can
+/// be called multiple times and CommitBacktrackedTokens/Backtrack calls will
+/// be combined with the EnableBacktrackAtThisPos calls in reverse order.
+void Preprocessor::EnableBacktrackAtThisPos() {
+  BacktrackPositions.push_back(CachedLexPos);
+  EnterCachingLexMode();
+}
+
+/// CommitBacktrackedTokens - Disable the last EnableBacktrackAtThisPos call.
+void Preprocessor::CommitBacktrackedTokens() {
+  assert(!BacktrackPositions.empty()
+         && "EnableBacktrackAtThisPos was not called!");
+  BacktrackPositions.pop_back();
+}
+
+/// Backtrack - Make Preprocessor re-lex the tokens that were lexed since
+/// EnableBacktrackAtThisPos() was previously called.
+void Preprocessor::Backtrack() {
+  assert(!BacktrackPositions.empty()
+         && "EnableBacktrackAtThisPos was not called!");
+  CachedLexPos = BacktrackPositions.back();
+  BacktrackPositions.pop_back();
+}
+
+void Preprocessor::CachingLex(Token &Result) {
+  if (CachedLexPos < CachedTokens.size()) {
+    Result = CachedTokens[CachedLexPos++];
+    return;
+  }
+
+  ExitCachingLexMode();
+  Lex(Result);
+
+  if (!isBacktrackEnabled()) {
+    // All cached tokens were consumed.
+    CachedTokens.clear();
+    CachedLexPos = 0;
+    return;
+  }
+
+  // We should cache the lexed token.
+
+  EnterCachingLexMode();
+  if (Result.isNot(tok::eof)) {
+    CachedTokens.push_back(Result);
+    ++CachedLexPos;
+  }
+}
+
+void Preprocessor::EnterCachingLexMode() {
+  if (InCachingLexMode())
+    return;
+
+  PushIncludeMacroStack();
+}
+
+
+const Token &Preprocessor::PeekAhead(unsigned N) {
+  assert(CachedLexPos + N > CachedTokens.size() && "Confused caching.");
+  ExitCachingLexMode();
+  for (unsigned C = CachedLexPos + N - CachedTokens.size(); C > 0; --C) {
+    CachedTokens.push_back(Token());
+    Lex(CachedTokens.back());
+  }
+  EnterCachingLexMode();
+  return CachedTokens.back();
+}
+
+void Preprocessor::AnnotatePreviousCachedTokens(const Token &Tok) {
+  assert(Tok.isAnnotation() && "Expected annotation token");
+  assert(CachedLexPos != 0 && "Expected to have some cached tokens");
+  assert(CachedTokens[CachedLexPos-1].getLastLoc() == Tok.getAnnotationEndLoc()
+         && "The annotation should be until the most recent cached token");
+
+  // Start from the end of the cached tokens list and look for the token
+  // that is the beginning of the annotation token.
+  for (CachedTokensTy::size_type i = CachedLexPos; i != 0; --i) {
+    CachedTokensTy::iterator AnnotBegin = CachedTokens.begin() + i-1;
+    if (AnnotBegin->getLocation() == Tok.getLocation()) {
+      assert((BacktrackPositions.empty() || BacktrackPositions.back() < i) &&
+             "The backtrack pos points inside the annotated tokens!");
+      // Replace the cached tokens with the single annotation token.
+      if (i < CachedLexPos)
+        CachedTokens.erase(AnnotBegin + 1, CachedTokens.begin() + CachedLexPos);
+      *AnnotBegin = Tok;
+      CachedLexPos = i;
+      return;
+    }
+  }
+}
diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp
new file mode 100644
index 0000000..417724b
--- /dev/null
+++ b/lib/Lex/PPDirectives.cpp
@@ -0,0 +1,1669 @@
+//===--- PPDirectives.cpp - Directive Handling for Preprocessor -----------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements # directive processing for the Preprocessor.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Lex/LiteralSupport.h"
+#include "clang/Lex/HeaderSearch.h"
+#include "clang/Lex/MacroInfo.h"
+#include "clang/Lex/LexDiagnostic.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/SourceManager.h"
+#include "llvm/ADT/APInt.h"
+using namespace clang;
+
+//===----------------------------------------------------------------------===//
+// Utility Methods for Preprocessor Directive Handling.
+//===----------------------------------------------------------------------===//
+
+MacroInfo *Preprocessor::AllocateMacroInfo(SourceLocation L) {
+  MacroInfo *MI;
+
+  if (!MICache.empty()) {
+    MI = MICache.back();
+    MICache.pop_back();
+  } else
+    MI = (MacroInfo*) BP.Allocate<MacroInfo>();
+  new (MI) MacroInfo(L);
+  return MI;
+}
+
+/// ReleaseMacroInfo - Release the specified MacroInfo.  This memory will
+///  be reused for allocating new MacroInfo objects.
+void Preprocessor::ReleaseMacroInfo(MacroInfo* MI) {
+  MICache.push_back(MI);
+  MI->FreeArgumentList(BP);
+}
+
+
+/// DiscardUntilEndOfDirective - Read and discard all tokens remaining on the
+/// current line until the tok::eom token is found.
+void Preprocessor::DiscardUntilEndOfDirective() {
+  Token Tmp;
+  do {
+    LexUnexpandedToken(Tmp);
+  } while (Tmp.isNot(tok::eom));
+}
+
+/// ReadMacroName - Lex and validate a macro name, which occurs after a
+/// #define or #undef.  This sets the token kind to eom and discards the rest
+/// of the macro line if the macro name is invalid.  isDefineUndef is 1 if
+/// this is due to a a #define, 2 if #undef directive, 0 if it is something
+/// else (e.g. #ifdef).
+void Preprocessor::ReadMacroName(Token &MacroNameTok, char isDefineUndef) {
+  // Read the token, don't allow macro expansion on it.
+  LexUnexpandedToken(MacroNameTok);
+
+  // Missing macro name?
+  if (MacroNameTok.is(tok::eom)) {
+    Diag(MacroNameTok, diag::err_pp_missing_macro_name);
+    return;
+  }
+
+  IdentifierInfo *II = MacroNameTok.getIdentifierInfo();
+  if (II == 0) {
+    bool Invalid = false;
+    std::string Spelling = getSpelling(MacroNameTok, &Invalid);
+    if (Invalid)
+      return;
+    
+    const IdentifierInfo &Info = Identifiers.get(Spelling);
+    if (Info.isCPlusPlusOperatorKeyword())
+      // C++ 2.5p2: Alternative tokens behave the same as its primary token
+      // except for their spellings.
+      Diag(MacroNameTok, diag::err_pp_operator_used_as_macro_name) << Spelling;
+    else
+      Diag(MacroNameTok, diag::err_pp_macro_not_identifier);
+    // Fall through on error.
+  } else if (isDefineUndef && II->getPPKeywordID() == tok::pp_defined) {
+    // Error if defining "defined": C99 6.10.8.4.
+    Diag(MacroNameTok, diag::err_defined_macro_name);
+  } else if (isDefineUndef && II->hasMacroDefinition() &&
+             getMacroInfo(II)->isBuiltinMacro()) {
+    // Error if defining "__LINE__" and other builtins: C99 6.10.8.4.
+    if (isDefineUndef == 1)
+      Diag(MacroNameTok, diag::pp_redef_builtin_macro);
+    else
+      Diag(MacroNameTok, diag::pp_undef_builtin_macro);
+  } else {
+    // Okay, we got a good identifier node.  Return it.
+    return;
+  }
+
+  // Invalid macro name, read and discard the rest of the line.  Then set the
+  // token kind to tok::eom.
+  MacroNameTok.setKind(tok::eom);
+  return DiscardUntilEndOfDirective();
+}
+
+/// CheckEndOfDirective - Ensure that the next token is a tok::eom token.  If
+/// not, emit a diagnostic and consume up until the eom.  If EnableMacros is
+/// true, then we consider macros that expand to zero tokens as being ok.
+void Preprocessor::CheckEndOfDirective(const char *DirType, bool EnableMacros) {
+  Token Tmp;
+  // Lex unexpanded tokens for most directives: macros might expand to zero
+  // tokens, causing us to miss diagnosing invalid lines.  Some directives (like
+  // #line) allow empty macros.
+  if (EnableMacros)
+    Lex(Tmp);
+  else
+    LexUnexpandedToken(Tmp);
+
+  // There should be no tokens after the directive, but we allow them as an
+  // extension.
+  while (Tmp.is(tok::comment))  // Skip comments in -C mode.
+    LexUnexpandedToken(Tmp);
+
+  if (Tmp.isNot(tok::eom)) {
+    // Add a fixit in GNU/C99/C++ mode.  Don't offer a fixit for strict-C89,
+    // because it is more trouble than it is worth to insert /**/ and check that
+    // there is no /**/ in the range also.
+    FixItHint Hint;
+    if (Features.GNUMode || Features.C99 || Features.CPlusPlus)
+      Hint = FixItHint::CreateInsertion(Tmp.getLocation(),"//");
+    Diag(Tmp, diag::ext_pp_extra_tokens_at_eol) << DirType << Hint;
+    DiscardUntilEndOfDirective();
+  }
+}
+
+
+
+/// SkipExcludedConditionalBlock - We just read a #if or related directive and
+/// decided that the subsequent tokens are in the #if'd out portion of the
+/// file.  Lex the rest of the file, until we see an #endif.  If
+/// FoundNonSkipPortion is true, then we have already emitted code for part of
+/// this #if directive, so #else/#elif blocks should never be entered. If ElseOk
+/// is true, then #else directives are ok, if not, then we have already seen one
+/// so a #else directive is a duplicate.  When this returns, the caller can lex
+/// the first valid token.
+void Preprocessor::SkipExcludedConditionalBlock(SourceLocation IfTokenLoc,
+                                                bool FoundNonSkipPortion,
+                                                bool FoundElse) {
+  ++NumSkipped;
+  assert(CurTokenLexer == 0 && CurPPLexer && "Lexing a macro, not a file?");
+
+  CurPPLexer->pushConditionalLevel(IfTokenLoc, /*isSkipping*/false,
+                                 FoundNonSkipPortion, FoundElse);
+
+  if (CurPTHLexer) {
+    PTHSkipExcludedConditionalBlock();
+    return;
+  }
+
+  // Enter raw mode to disable identifier lookup (and thus macro expansion),
+  // disabling warnings, etc.
+  CurPPLexer->LexingRawMode = true;
+  Token Tok;
+  while (1) {
+    CurLexer->Lex(Tok);
+
+    // If this is the end of the buffer, we have an error.
+    if (Tok.is(tok::eof)) {
+      // Emit errors for each unterminated conditional on the stack, including
+      // the current one.
+      while (!CurPPLexer->ConditionalStack.empty()) {
+        Diag(CurPPLexer->ConditionalStack.back().IfLoc,
+             diag::err_pp_unterminated_conditional);
+        CurPPLexer->ConditionalStack.pop_back();
+      }
+
+      // Just return and let the caller lex after this #include.
+      break;
+    }
+
+    // If this token is not a preprocessor directive, just skip it.
+    if (Tok.isNot(tok::hash) || !Tok.isAtStartOfLine())
+      continue;
+
+    // We just parsed a # character at the start of a line, so we're in
+    // directive mode.  Tell the lexer this so any newlines we see will be
+    // converted into an EOM token (this terminates the macro).
+    CurPPLexer->ParsingPreprocessorDirective = true;
+    if (CurLexer) CurLexer->SetCommentRetentionState(false);
+
+
+    // Read the next token, the directive flavor.
+    LexUnexpandedToken(Tok);
+
+    // If this isn't an identifier directive (e.g. is "# 1\n" or "#\n", or
+    // something bogus), skip it.
+    if (Tok.isNot(tok::identifier)) {
+      CurPPLexer->ParsingPreprocessorDirective = false;
+      // Restore comment saving mode.
+      if (CurLexer) CurLexer->SetCommentRetentionState(KeepComments);
+      continue;
+    }
+
+    // If the first letter isn't i or e, it isn't intesting to us.  We know that
+    // this is safe in the face of spelling differences, because there is no way
+    // to spell an i/e in a strange way that is another letter.  Skipping this
+    // allows us to avoid looking up the identifier info for #define/#undef and
+    // other common directives.
+    bool Invalid = false;
+    const char *RawCharData = SourceMgr.getCharacterData(Tok.getLocation(),
+                                                         &Invalid);
+    if (Invalid)
+      return;
+    
+    char FirstChar = RawCharData[0];
+    if (FirstChar >= 'a' && FirstChar <= 'z' &&
+        FirstChar != 'i' && FirstChar != 'e') {
+      CurPPLexer->ParsingPreprocessorDirective = false;
+      // Restore comment saving mode.
+      if (CurLexer) CurLexer->SetCommentRetentionState(KeepComments);
+      continue;
+    }
+
+    // Get the identifier name without trigraphs or embedded newlines.  Note
+    // that we can't use Tok.getIdentifierInfo() because its lookup is disabled
+    // when skipping.
+    char DirectiveBuf[20];
+    llvm::StringRef Directive;
+    if (!Tok.needsCleaning() && Tok.getLength() < 20) {
+      Directive = llvm::StringRef(RawCharData, Tok.getLength());
+    } else {
+      std::string DirectiveStr = getSpelling(Tok);
+      unsigned IdLen = DirectiveStr.size();
+      if (IdLen >= 20) {
+        CurPPLexer->ParsingPreprocessorDirective = false;
+        // Restore comment saving mode.
+        if (CurLexer) CurLexer->SetCommentRetentionState(KeepComments);
+        continue;
+      }
+      memcpy(DirectiveBuf, &DirectiveStr[0], IdLen);
+      Directive = llvm::StringRef(DirectiveBuf, IdLen);
+    }
+
+    if (Directive.startswith("if")) {
+      llvm::StringRef Sub = Directive.substr(2);
+      if (Sub.empty() ||   // "if"
+          Sub == "def" ||   // "ifdef"
+          Sub == "ndef") {  // "ifndef"
+        // We know the entire #if/#ifdef/#ifndef block will be skipped, don't
+        // bother parsing the condition.
+        DiscardUntilEndOfDirective();
+        CurPPLexer->pushConditionalLevel(Tok.getLocation(), /*wasskipping*/true,
+                                       /*foundnonskip*/false,
+                                       /*fnddelse*/false);
+      }
+    } else if (Directive[0] == 'e') {
+      llvm::StringRef Sub = Directive.substr(1);
+      if (Sub == "ndif") {  // "endif"
+        CheckEndOfDirective("endif");
+        PPConditionalInfo CondInfo;
+        CondInfo.WasSkipping = true; // Silence bogus warning.
+        bool InCond = CurPPLexer->popConditionalLevel(CondInfo);
+        InCond = InCond;  // Silence warning in no-asserts mode.
+        assert(!InCond && "Can't be skipping if not in a conditional!");
+
+        // If we popped the outermost skipping block, we're done skipping!
+        if (!CondInfo.WasSkipping)
+          break;
+      } else if (Sub == "lse") { // "else".
+        // #else directive in a skipping conditional.  If not in some other
+        // skipping conditional, and if #else hasn't already been seen, enter it
+        // as a non-skipping conditional.
+        DiscardUntilEndOfDirective();  // C99 6.10p4.
+        PPConditionalInfo &CondInfo = CurPPLexer->peekConditionalLevel();
+
+        // If this is a #else with a #else before it, report the error.
+        if (CondInfo.FoundElse) Diag(Tok, diag::pp_err_else_after_else);
+
+        // Note that we've seen a #else in this conditional.
+        CondInfo.FoundElse = true;
+
+        // If the conditional is at the top level, and the #if block wasn't
+        // entered, enter the #else block now.
+        if (!CondInfo.WasSkipping && !CondInfo.FoundNonSkip) {
+          CondInfo.FoundNonSkip = true;
+          break;
+        }
+      } else if (Sub == "lif") {  // "elif".
+        PPConditionalInfo &CondInfo = CurPPLexer->peekConditionalLevel();
+
+        bool ShouldEnter;
+        // If this is in a skipping block or if we're already handled this #if
+        // block, don't bother parsing the condition.
+        if (CondInfo.WasSkipping || CondInfo.FoundNonSkip) {
+          DiscardUntilEndOfDirective();
+          ShouldEnter = false;
+        } else {
+          // Restore the value of LexingRawMode so that identifiers are
+          // looked up, etc, inside the #elif expression.
+          assert(CurPPLexer->LexingRawMode && "We have to be skipping here!");
+          CurPPLexer->LexingRawMode = false;
+          IdentifierInfo *IfNDefMacro = 0;
+          ShouldEnter = EvaluateDirectiveExpression(IfNDefMacro);
+          CurPPLexer->LexingRawMode = true;
+        }
+
+        // If this is a #elif with a #else before it, report the error.
+        if (CondInfo.FoundElse) Diag(Tok, diag::pp_err_elif_after_else);
+
+        // If this condition is true, enter it!
+        if (ShouldEnter) {
+          CondInfo.FoundNonSkip = true;
+          break;
+        }
+      }
+    }
+
+    CurPPLexer->ParsingPreprocessorDirective = false;
+    // Restore comment saving mode.
+    if (CurLexer) CurLexer->SetCommentRetentionState(KeepComments);
+  }
+
+  // Finally, if we are out of the conditional (saw an #endif or ran off the end
+  // of the file, just stop skipping and return to lexing whatever came after
+  // the #if block.
+  CurPPLexer->LexingRawMode = false;
+}
+
+void Preprocessor::PTHSkipExcludedConditionalBlock() {
+
+  while (1) {
+    assert(CurPTHLexer);
+    assert(CurPTHLexer->LexingRawMode == false);
+
+    // Skip to the next '#else', '#elif', or #endif.
+    if (CurPTHLexer->SkipBlock()) {
+      // We have reached an #endif.  Both the '#' and 'endif' tokens
+      // have been consumed by the PTHLexer.  Just pop off the condition level.
+      PPConditionalInfo CondInfo;
+      bool InCond = CurPTHLexer->popConditionalLevel(CondInfo);
+      InCond = InCond;  // Silence warning in no-asserts mode.
+      assert(!InCond && "Can't be skipping if not in a conditional!");
+      break;
+    }
+
+    // We have reached a '#else' or '#elif'.  Lex the next token to get
+    // the directive flavor.
+    Token Tok;
+    LexUnexpandedToken(Tok);
+
+    // We can actually look up the IdentifierInfo here since we aren't in
+    // raw mode.
+    tok::PPKeywordKind K = Tok.getIdentifierInfo()->getPPKeywordID();
+
+    if (K == tok::pp_else) {
+      // #else: Enter the else condition.  We aren't in a nested condition
+      //  since we skip those. We're always in the one matching the last
+      //  blocked we skipped.
+      PPConditionalInfo &CondInfo = CurPTHLexer->peekConditionalLevel();
+      // Note that we've seen a #else in this conditional.
+      CondInfo.FoundElse = true;
+
+      // If the #if block wasn't entered then enter the #else block now.
+      if (!CondInfo.FoundNonSkip) {
+        CondInfo.FoundNonSkip = true;
+
+        // Scan until the eom token.
+        CurPTHLexer->ParsingPreprocessorDirective = true;
+        DiscardUntilEndOfDirective();
+        CurPTHLexer->ParsingPreprocessorDirective = false;
+
+        break;
+      }
+
+      // Otherwise skip this block.
+      continue;
+    }
+
+    assert(K == tok::pp_elif);
+    PPConditionalInfo &CondInfo = CurPTHLexer->peekConditionalLevel();
+
+    // If this is a #elif with a #else before it, report the error.
+    if (CondInfo.FoundElse)
+      Diag(Tok, diag::pp_err_elif_after_else);
+
+    // If this is in a skipping block or if we're already handled this #if
+    // block, don't bother parsing the condition.  We just skip this block.
+    if (CondInfo.FoundNonSkip)
+      continue;
+
+    // Evaluate the condition of the #elif.
+    IdentifierInfo *IfNDefMacro = 0;
+    CurPTHLexer->ParsingPreprocessorDirective = true;
+    bool ShouldEnter = EvaluateDirectiveExpression(IfNDefMacro);
+    CurPTHLexer->ParsingPreprocessorDirective = false;
+
+    // If this condition is true, enter it!
+    if (ShouldEnter) {
+      CondInfo.FoundNonSkip = true;
+      break;
+    }
+
+    // Otherwise, skip this block and go to the next one.
+    continue;
+  }
+}
+
+/// LookupFile - Given a "foo" or <foo> reference, look up the indicated file,
+/// return null on failure.  isAngled indicates whether the file reference is
+/// for system #include's or not (i.e. using <> instead of "").
+const FileEntry *Preprocessor::LookupFile(llvm::StringRef Filename,
+                                          bool isAngled,
+                                          const DirectoryLookup *FromDir,
+                                          const DirectoryLookup *&CurDir) {
+  // If the header lookup mechanism may be relative to the current file, pass in
+  // info about where the current file is.
+  const FileEntry *CurFileEnt = 0;
+  if (!FromDir) {
+    FileID FID = getCurrentFileLexer()->getFileID();
+    CurFileEnt = SourceMgr.getFileEntryForID(FID);
+
+    // If there is no file entry associated with this file, it must be the
+    // predefines buffer.  Any other file is not lexed with a normal lexer, so
+    // it won't be scanned for preprocessor directives.   If we have the
+    // predefines buffer, resolve #include references (which come from the
+    // -include command line argument) as if they came from the main file, this
+    // affects file lookup etc.
+    if (CurFileEnt == 0) {
+      FID = SourceMgr.getMainFileID();
+      CurFileEnt = SourceMgr.getFileEntryForID(FID);
+    }
+  }
+
+  // Do a standard file entry lookup.
+  CurDir = CurDirLookup;
+  const FileEntry *FE =
+    HeaderInfo.LookupFile(Filename, isAngled, FromDir, CurDir, CurFileEnt);
+  if (FE) return FE;
+
+  // Otherwise, see if this is a subframework header.  If so, this is relative
+  // to one of the headers on the #include stack.  Walk the list of the current
+  // headers on the #include stack and pass them to HeaderInfo.
+  if (IsFileLexer()) {
+    if ((CurFileEnt = SourceMgr.getFileEntryForID(CurPPLexer->getFileID())))
+      if ((FE = HeaderInfo.LookupSubframeworkHeader(Filename, CurFileEnt)))
+        return FE;
+  }
+
+  for (unsigned i = 0, e = IncludeMacroStack.size(); i != e; ++i) {
+    IncludeStackInfo &ISEntry = IncludeMacroStack[e-i-1];
+    if (IsFileLexer(ISEntry)) {
+      if ((CurFileEnt =
+           SourceMgr.getFileEntryForID(ISEntry.ThePPLexer->getFileID())))
+        if ((FE = HeaderInfo.LookupSubframeworkHeader(Filename, CurFileEnt)))
+          return FE;
+    }
+  }
+
+  // Otherwise, we really couldn't find the file.
+  return 0;
+}
+
+
+//===----------------------------------------------------------------------===//
+// Preprocessor Directive Handling.
+//===----------------------------------------------------------------------===//
+
+/// HandleDirective - This callback is invoked when the lexer sees a # token
+/// at the start of a line.  This consumes the directive, modifies the
+/// lexer/preprocessor state, and advances the lexer(s) so that the next token
+/// read is the correct one.
+void Preprocessor::HandleDirective(Token &Result) {
+  // FIXME: Traditional: # with whitespace before it not recognized by K&R?
+
+  // We just parsed a # character at the start of a line, so we're in directive
+  // mode.  Tell the lexer this so any newlines we see will be converted into an
+  // EOM token (which terminates the directive).
+  CurPPLexer->ParsingPreprocessorDirective = true;
+
+  ++NumDirectives;
+
+  // We are about to read a token.  For the multiple-include optimization FA to
+  // work, we have to remember if we had read any tokens *before* this
+  // pp-directive.
+  bool ReadAnyTokensBeforeDirective =CurPPLexer->MIOpt.getHasReadAnyTokensVal();
+
+  // Save the '#' token in case we need to return it later.
+  Token SavedHash = Result;
+
+  // Read the next token, the directive flavor.  This isn't expanded due to
+  // C99 6.10.3p8.
+  LexUnexpandedToken(Result);
+
+  // C99 6.10.3p11: Is this preprocessor directive in macro invocation?  e.g.:
+  //   #define A(x) #x
+  //   A(abc
+  //     #warning blah
+  //   def)
+  // If so, the user is relying on non-portable behavior, emit a diagnostic.
+  if (InMacroArgs)
+    Diag(Result, diag::ext_embedded_directive);
+
+TryAgain:
+  switch (Result.getKind()) {
+  case tok::eom:
+    return;   // null directive.
+  case tok::comment:
+    // Handle stuff like "# /*foo*/ define X" in -E -C mode.
+    LexUnexpandedToken(Result);
+    goto TryAgain;
+
+  case tok::numeric_constant:  // # 7  GNU line marker directive.
+    if (getLangOptions().AsmPreprocessor)
+      break;  // # 4 is not a preprocessor directive in .S files.
+    return HandleDigitDirective(Result);
+  default:
+    IdentifierInfo *II = Result.getIdentifierInfo();
+    if (II == 0) break;  // Not an identifier.
+
+    // Ask what the preprocessor keyword ID is.
+    switch (II->getPPKeywordID()) {
+    default: break;
+    // C99 6.10.1 - Conditional Inclusion.
+    case tok::pp_if:
+      return HandleIfDirective(Result, ReadAnyTokensBeforeDirective);
+    case tok::pp_ifdef:
+      return HandleIfdefDirective(Result, false, true/*not valid for miopt*/);
+    case tok::pp_ifndef:
+      return HandleIfdefDirective(Result, true, ReadAnyTokensBeforeDirective);
+    case tok::pp_elif:
+      return HandleElifDirective(Result);
+    case tok::pp_else:
+      return HandleElseDirective(Result);
+    case tok::pp_endif:
+      return HandleEndifDirective(Result);
+
+    // C99 6.10.2 - Source File Inclusion.
+    case tok::pp_include:
+      return HandleIncludeDirective(Result);       // Handle #include.
+    case tok::pp___include_macros:
+      return HandleIncludeMacrosDirective(Result); // Handle -imacros.
+
+    // C99 6.10.3 - Macro Replacement.
+    case tok::pp_define:
+      return HandleDefineDirective(Result);
+    case tok::pp_undef:
+      return HandleUndefDirective(Result);
+
+    // C99 6.10.4 - Line Control.
+    case tok::pp_line:
+      return HandleLineDirective(Result);
+
+    // C99 6.10.5 - Error Directive.
+    case tok::pp_error:
+      return HandleUserDiagnosticDirective(Result, false);
+
+    // C99 6.10.6 - Pragma Directive.
+    case tok::pp_pragma:
+      return HandlePragmaDirective();
+
+    // GNU Extensions.
+    case tok::pp_import:
+      return HandleImportDirective(Result);
+    case tok::pp_include_next:
+      return HandleIncludeNextDirective(Result);
+
+    case tok::pp_warning:
+      Diag(Result, diag::ext_pp_warning_directive);
+      return HandleUserDiagnosticDirective(Result, true);
+    case tok::pp_ident:
+      return HandleIdentSCCSDirective(Result);
+    case tok::pp_sccs:
+      return HandleIdentSCCSDirective(Result);
+    case tok::pp_assert:
+      //isExtension = true;  // FIXME: implement #assert
+      break;
+    case tok::pp_unassert:
+      //isExtension = true;  // FIXME: implement #unassert
+      break;
+    }
+    break;
+  }
+
+  // If this is a .S file, treat unknown # directives as non-preprocessor
+  // directives.  This is important because # may be a comment or introduce
+  // various pseudo-ops.  Just return the # token and push back the following
+  // token to be lexed next time.
+  if (getLangOptions().AsmPreprocessor) {
+    Token *Toks = new Token[2];
+    // Return the # and the token after it.
+    Toks[0] = SavedHash;
+    Toks[1] = Result;
+    // Enter this token stream so that we re-lex the tokens.  Make sure to
+    // enable macro expansion, in case the token after the # is an identifier
+    // that is expanded.
+    EnterTokenStream(Toks, 2, false, true);
+    return;
+  }
+
+  // If we reached here, the preprocessing token is not valid!
+  Diag(Result, diag::err_pp_invalid_directive);
+
+  // Read the rest of the PP line.
+  DiscardUntilEndOfDirective();
+
+  // Okay, we're done parsing the directive.
+}
+
+/// GetLineValue - Convert a numeric token into an unsigned value, emitting
+/// Diagnostic DiagID if it is invalid, and returning the value in Val.
+static bool GetLineValue(Token &DigitTok, unsigned &Val,
+                         unsigned DiagID, Preprocessor &PP) {
+  if (DigitTok.isNot(tok::numeric_constant)) {
+    PP.Diag(DigitTok, DiagID);
+
+    if (DigitTok.isNot(tok::eom))
+      PP.DiscardUntilEndOfDirective();
+    return true;
+  }
+
+  llvm::SmallString<64> IntegerBuffer;
+  IntegerBuffer.resize(DigitTok.getLength());
+  const char *DigitTokBegin = &IntegerBuffer[0];
+  bool Invalid = false;
+  unsigned ActualLength = PP.getSpelling(DigitTok, DigitTokBegin, &Invalid);
+  if (Invalid)
+    return true;
+  
+  // Verify that we have a simple digit-sequence, and compute the value.  This
+  // is always a simple digit string computed in decimal, so we do this manually
+  // here.
+  Val = 0;
+  for (unsigned i = 0; i != ActualLength; ++i) {
+    if (!isdigit(DigitTokBegin[i])) {
+      PP.Diag(PP.AdvanceToTokenCharacter(DigitTok.getLocation(), i),
+              diag::err_pp_line_digit_sequence);
+      PP.DiscardUntilEndOfDirective();
+      return true;
+    }
+
+    unsigned NextVal = Val*10+(DigitTokBegin[i]-'0');
+    if (NextVal < Val) { // overflow.
+      PP.Diag(DigitTok, DiagID);
+      PP.DiscardUntilEndOfDirective();
+      return true;
+    }
+    Val = NextVal;
+  }
+
+  // Reject 0, this is needed both by #line numbers and flags.
+  if (Val == 0) {
+    PP.Diag(DigitTok, DiagID);
+    PP.DiscardUntilEndOfDirective();
+    return true;
+  }
+
+  if (DigitTokBegin[0] == '0')
+    PP.Diag(DigitTok.getLocation(), diag::warn_pp_line_decimal);
+
+  return false;
+}
+
+/// HandleLineDirective - Handle #line directive: C99 6.10.4.  The two
+/// acceptable forms are:
+///   # line digit-sequence
+///   # line digit-sequence "s-char-sequence"
+void Preprocessor::HandleLineDirective(Token &Tok) {
+  // Read the line # and string argument.  Per C99 6.10.4p5, these tokens are
+  // expanded.
+  Token DigitTok;
+  Lex(DigitTok);
+
+  // Validate the number and convert it to an unsigned.
+  unsigned LineNo;
+  if (GetLineValue(DigitTok, LineNo, diag::err_pp_line_requires_integer,*this))
+    return;
+
+  // Enforce C99 6.10.4p3: "The digit sequence shall not specify ... a
+  // number greater than 2147483647".  C90 requires that the line # be <= 32767.
+  unsigned LineLimit = Features.C99 ? 2147483648U : 32768U;
+  if (LineNo >= LineLimit)
+    Diag(DigitTok, diag::ext_pp_line_too_big) << LineLimit;
+
+  int FilenameID = -1;
+  Token StrTok;
+  Lex(StrTok);
+
+  // If the StrTok is "eom", then it wasn't present.  Otherwise, it must be a
+  // string followed by eom.
+  if (StrTok.is(tok::eom))
+    ; // ok
+  else if (StrTok.isNot(tok::string_literal)) {
+    Diag(StrTok, diag::err_pp_line_invalid_filename);
+    DiscardUntilEndOfDirective();
+    return;
+  } else {
+    // Parse and validate the string, converting it into a unique ID.
+    StringLiteralParser Literal(&StrTok, 1, *this);
+    assert(!Literal.AnyWide && "Didn't allow wide strings in");
+    if (Literal.hadError)
+      return DiscardUntilEndOfDirective();
+    if (Literal.Pascal) {
+      Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
+      return DiscardUntilEndOfDirective();
+    }
+    FilenameID = SourceMgr.getLineTableFilenameID(Literal.GetString(),
+                                                  Literal.GetStringLength());
+
+    // Verify that there is nothing after the string, other than EOM.  Because
+    // of C99 6.10.4p5, macros that expand to empty tokens are ok.
+    CheckEndOfDirective("line", true);
+  }
+
+  SourceMgr.AddLineNote(DigitTok.getLocation(), LineNo, FilenameID);
+
+  if (Callbacks)
+    Callbacks->FileChanged(CurPPLexer->getSourceLocation(),
+                           PPCallbacks::RenameFile,
+                           SrcMgr::C_User);
+}
+
+/// ReadLineMarkerFlags - Parse and validate any flags at the end of a GNU line
+/// marker directive.
+static bool ReadLineMarkerFlags(bool &IsFileEntry, bool &IsFileExit,
+                                bool &IsSystemHeader, bool &IsExternCHeader,
+                                Preprocessor &PP) {
+  unsigned FlagVal;
+  Token FlagTok;
+  PP.Lex(FlagTok);
+  if (FlagTok.is(tok::eom)) return false;
+  if (GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag, PP))
+    return true;
+
+  if (FlagVal == 1) {
+    IsFileEntry = true;
+
+    PP.Lex(FlagTok);
+    if (FlagTok.is(tok::eom)) return false;
+    if (GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag,PP))
+      return true;
+  } else if (FlagVal == 2) {
+    IsFileExit = true;
+
+    SourceManager &SM = PP.getSourceManager();
+    // If we are leaving the current presumed file, check to make sure the
+    // presumed include stack isn't empty!
+    FileID CurFileID =
+      SM.getDecomposedInstantiationLoc(FlagTok.getLocation()).first;
+    PresumedLoc PLoc = SM.getPresumedLoc(FlagTok.getLocation());
+
+    // If there is no include loc (main file) or if the include loc is in a
+    // different physical file, then we aren't in a "1" line marker flag region.
+    SourceLocation IncLoc = PLoc.getIncludeLoc();
+    if (IncLoc.isInvalid() ||
+        SM.getDecomposedInstantiationLoc(IncLoc).first != CurFileID) {
+      PP.Diag(FlagTok, diag::err_pp_linemarker_invalid_pop);
+      PP.DiscardUntilEndOfDirective();
+      return true;
+    }
+
+    PP.Lex(FlagTok);
+    if (FlagTok.is(tok::eom)) return false;
+    if (GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag,PP))
+      return true;
+  }
+
+  // We must have 3 if there are still flags.
+  if (FlagVal != 3) {
+    PP.Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
+    PP.DiscardUntilEndOfDirective();
+    return true;
+  }
+
+  IsSystemHeader = true;
+
+  PP.Lex(FlagTok);
+  if (FlagTok.is(tok::eom)) return false;
+  if (GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag, PP))
+    return true;
+
+  // We must have 4 if there is yet another flag.
+  if (FlagVal != 4) {
+    PP.Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
+    PP.DiscardUntilEndOfDirective();
+    return true;
+  }
+
+  IsExternCHeader = true;
+
+  PP.Lex(FlagTok);
+  if (FlagTok.is(tok::eom)) return false;
+
+  // There are no more valid flags here.
+  PP.Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
+  PP.DiscardUntilEndOfDirective();
+  return true;
+}
+
+/// HandleDigitDirective - Handle a GNU line marker directive, whose syntax is
+/// one of the following forms:
+///
+///     # 42
+///     # 42 "file" ('1' | '2')?
+///     # 42 "file" ('1' | '2')? '3' '4'?
+///
+void Preprocessor::HandleDigitDirective(Token &DigitTok) {
+  // Validate the number and convert it to an unsigned.  GNU does not have a
+  // line # limit other than it fit in 32-bits.
+  unsigned LineNo;
+  if (GetLineValue(DigitTok, LineNo, diag::err_pp_linemarker_requires_integer,
+                   *this))
+    return;
+
+  Token StrTok;
+  Lex(StrTok);
+
+  bool IsFileEntry = false, IsFileExit = false;
+  bool IsSystemHeader = false, IsExternCHeader = false;
+  int FilenameID = -1;
+
+  // If the StrTok is "eom", then it wasn't present.  Otherwise, it must be a
+  // string followed by eom.
+  if (StrTok.is(tok::eom))
+    ; // ok
+  else if (StrTok.isNot(tok::string_literal)) {
+    Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
+    return DiscardUntilEndOfDirective();
+  } else {
+    // Parse and validate the string, converting it into a unique ID.
+    StringLiteralParser Literal(&StrTok, 1, *this);
+    assert(!Literal.AnyWide && "Didn't allow wide strings in");
+    if (Literal.hadError)
+      return DiscardUntilEndOfDirective();
+    if (Literal.Pascal) {
+      Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
+      return DiscardUntilEndOfDirective();
+    }
+    FilenameID = SourceMgr.getLineTableFilenameID(Literal.GetString(),
+                                                  Literal.GetStringLength());
+
+    // If a filename was present, read any flags that are present.
+    if (ReadLineMarkerFlags(IsFileEntry, IsFileExit,
+                            IsSystemHeader, IsExternCHeader, *this))
+      return;
+  }
+
+  // Create a line note with this information.
+  SourceMgr.AddLineNote(DigitTok.getLocation(), LineNo, FilenameID,
+                        IsFileEntry, IsFileExit,
+                        IsSystemHeader, IsExternCHeader);
+
+  // If the preprocessor has callbacks installed, notify them of the #line
+  // change.  This is used so that the line marker comes out in -E mode for
+  // example.
+  if (Callbacks) {
+    PPCallbacks::FileChangeReason Reason = PPCallbacks::RenameFile;
+    if (IsFileEntry)
+      Reason = PPCallbacks::EnterFile;
+    else if (IsFileExit)
+      Reason = PPCallbacks::ExitFile;
+    SrcMgr::CharacteristicKind FileKind = SrcMgr::C_User;
+    if (IsExternCHeader)
+      FileKind = SrcMgr::C_ExternCSystem;
+    else if (IsSystemHeader)
+      FileKind = SrcMgr::C_System;
+
+    Callbacks->FileChanged(CurPPLexer->getSourceLocation(), Reason, FileKind);
+  }
+}
+
+
+/// HandleUserDiagnosticDirective - Handle a #warning or #error directive.
+///
+void Preprocessor::HandleUserDiagnosticDirective(Token &Tok,
+                                                 bool isWarning) {
+  // PTH doesn't emit #warning or #error directives.
+  if (CurPTHLexer)
+    return CurPTHLexer->DiscardToEndOfLine();
+
+  // Read the rest of the line raw.  We do this because we don't want macros
+  // to be expanded and we don't require that the tokens be valid preprocessing
+  // tokens.  For example, this is allowed: "#warning `   'foo".  GCC does
+  // collapse multiple consequtive white space between tokens, but this isn't
+  // specified by the standard.
+  std::string Message = CurLexer->ReadToEndOfLine();
+  if (isWarning)
+    Diag(Tok, diag::pp_hash_warning) << Message;
+  else
+    Diag(Tok, diag::err_pp_hash_error) << Message;
+}
+
+/// HandleIdentSCCSDirective - Handle a #ident/#sccs directive.
+///
+void Preprocessor::HandleIdentSCCSDirective(Token &Tok) {
+  // Yes, this directive is an extension.
+  Diag(Tok, diag::ext_pp_ident_directive);
+
+  // Read the string argument.
+  Token StrTok;
+  Lex(StrTok);
+
+  // If the token kind isn't a string, it's a malformed directive.
+  if (StrTok.isNot(tok::string_literal) &&
+      StrTok.isNot(tok::wide_string_literal)) {
+    Diag(StrTok, diag::err_pp_malformed_ident);
+    if (StrTok.isNot(tok::eom))
+      DiscardUntilEndOfDirective();
+    return;
+  }
+
+  // Verify that there is nothing after the string, other than EOM.
+  CheckEndOfDirective("ident");
+
+  if (Callbacks) {
+    bool Invalid = false;
+    std::string Str = getSpelling(StrTok, &Invalid);
+    if (!Invalid)
+      Callbacks->Ident(Tok.getLocation(), Str);
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// Preprocessor Include Directive Handling.
+//===----------------------------------------------------------------------===//
+
+/// GetIncludeFilenameSpelling - Turn the specified lexer token into a fully
+/// checked and spelled filename, e.g. as an operand of #include. This returns
+/// true if the input filename was in <>'s or false if it were in ""'s.  The
+/// caller is expected to provide a buffer that is large enough to hold the
+/// spelling of the filename, but is also expected to handle the case when
+/// this method decides to use a different buffer.
+bool Preprocessor::GetIncludeFilenameSpelling(SourceLocation Loc,
+                                              llvm::StringRef &Buffer) {
+  // Get the text form of the filename.
+  assert(!Buffer.empty() && "Can't have tokens with empty spellings!");
+
+  // Make sure the filename is <x> or "x".
+  bool isAngled;
+  if (Buffer[0] == '<') {
+    if (Buffer.back() != '>') {
+      Diag(Loc, diag::err_pp_expects_filename);
+      Buffer = llvm::StringRef();
+      return true;
+    }
+    isAngled = true;
+  } else if (Buffer[0] == '"') {
+    if (Buffer.back() != '"') {
+      Diag(Loc, diag::err_pp_expects_filename);
+      Buffer = llvm::StringRef();
+      return true;
+    }
+    isAngled = false;
+  } else {
+    Diag(Loc, diag::err_pp_expects_filename);
+    Buffer = llvm::StringRef();
+    return true;
+  }
+
+  // Diagnose #include "" as invalid.
+  if (Buffer.size() <= 2) {
+    Diag(Loc, diag::err_pp_empty_filename);
+    Buffer = llvm::StringRef();
+    return true;
+  }
+
+  // Skip the brackets.
+  Buffer = Buffer.substr(1, Buffer.size()-2);
+  return isAngled;
+}
+
+/// ConcatenateIncludeName - Handle cases where the #include name is expanded
+/// from a macro as multiple tokens, which need to be glued together.  This
+/// occurs for code like:
+///    #define FOO <a/b.h>
+///    #include FOO
+/// because in this case, "<a/b.h>" is returned as 7 tokens, not one.
+///
+/// This code concatenates and consumes tokens up to the '>' token.  It returns
+/// false if the > was found, otherwise it returns true if it finds and consumes
+/// the EOM marker.
+bool Preprocessor::ConcatenateIncludeName(
+  llvm::SmallString<128> &FilenameBuffer) {
+  Token CurTok;
+
+  Lex(CurTok);
+  while (CurTok.isNot(tok::eom)) {
+    // Append the spelling of this token to the buffer. If there was a space
+    // before it, add it now.
+    if (CurTok.hasLeadingSpace())
+      FilenameBuffer.push_back(' ');
+
+    // Get the spelling of the token, directly into FilenameBuffer if possible.
+    unsigned PreAppendSize = FilenameBuffer.size();
+    FilenameBuffer.resize(PreAppendSize+CurTok.getLength());
+
+    const char *BufPtr = &FilenameBuffer[PreAppendSize];
+    unsigned ActualLen = getSpelling(CurTok, BufPtr);
+
+    // If the token was spelled somewhere else, copy it into FilenameBuffer.
+    if (BufPtr != &FilenameBuffer[PreAppendSize])
+      memcpy(&FilenameBuffer[PreAppendSize], BufPtr, ActualLen);
+
+    // Resize FilenameBuffer to the correct size.
+    if (CurTok.getLength() != ActualLen)
+      FilenameBuffer.resize(PreAppendSize+ActualLen);
+
+    // If we found the '>' marker, return success.
+    if (CurTok.is(tok::greater))
+      return false;
+
+    Lex(CurTok);
+  }
+
+  // If we hit the eom marker, emit an error and return true so that the caller
+  // knows the EOM has been read.
+  Diag(CurTok.getLocation(), diag::err_pp_expects_filename);
+  return true;
+}
+
+/// HandleIncludeDirective - The "#include" tokens have just been read, read the
+/// file to be included from the lexer, then include it!  This is a common
+/// routine with functionality shared between #include, #include_next and
+/// #import.  LookupFrom is set when this is a #include_next directive, it
+/// specifies the file to start searching from.
+void Preprocessor::HandleIncludeDirective(Token &IncludeTok,
+                                          const DirectoryLookup *LookupFrom,
+                                          bool isImport) {
+
+  Token FilenameTok;
+  CurPPLexer->LexIncludeFilename(FilenameTok);
+
+  // Reserve a buffer to get the spelling.
+  llvm::SmallString<128> FilenameBuffer;
+  llvm::StringRef Filename;
+
+  switch (FilenameTok.getKind()) {
+  case tok::eom:
+    // If the token kind is EOM, the error has already been diagnosed.
+    return;
+
+  case tok::angle_string_literal:
+  case tok::string_literal:
+    Filename = getSpelling(FilenameTok, FilenameBuffer);
+    break;
+
+  case tok::less:
+    // This could be a <foo/bar.h> file coming from a macro expansion.  In this
+    // case, glue the tokens together into FilenameBuffer and interpret those.
+    FilenameBuffer.push_back('<');
+    if (ConcatenateIncludeName(FilenameBuffer))
+      return;   // Found <eom> but no ">"?  Diagnostic already emitted.
+    Filename = FilenameBuffer.str();
+    break;
+  default:
+    Diag(FilenameTok.getLocation(), diag::err_pp_expects_filename);
+    DiscardUntilEndOfDirective();
+    return;
+  }
+
+  bool isAngled =
+    GetIncludeFilenameSpelling(FilenameTok.getLocation(), Filename);
+  // If GetIncludeFilenameSpelling set the start ptr to null, there was an
+  // error.
+  if (Filename.empty()) {
+    DiscardUntilEndOfDirective();
+    return;
+  }
+
+  // Verify that there is nothing after the filename, other than EOM.  Note that
+  // we allow macros that expand to nothing after the filename, because this
+  // falls into the category of "#include pp-tokens new-line" specified in
+  // C99 6.10.2p4.
+  CheckEndOfDirective(IncludeTok.getIdentifierInfo()->getNameStart(), true);
+
+  // Check that we don't have infinite #include recursion.
+  if (IncludeMacroStack.size() == MaxAllowedIncludeStackDepth-1) {
+    Diag(FilenameTok, diag::err_pp_include_too_deep);
+    return;
+  }
+
+  // Search include directories.
+  const DirectoryLookup *CurDir;
+  const FileEntry *File = LookupFile(Filename, isAngled, LookupFrom, CurDir);
+  if (File == 0) {
+    Diag(FilenameTok, diag::err_pp_file_not_found) << Filename;
+    return;
+  }
+
+  // The #included file will be considered to be a system header if either it is
+  // in a system include directory, or if the #includer is a system include
+  // header.
+  SrcMgr::CharacteristicKind FileCharacter =
+    std::max(HeaderInfo.getFileDirFlavor(File),
+             SourceMgr.getFileCharacteristic(FilenameTok.getLocation()));
+
+  // Ask HeaderInfo if we should enter this #include file.  If not, #including
+  // this file will have no effect.
+  if (!HeaderInfo.ShouldEnterIncludeFile(File, isImport)) {
+    if (Callbacks)
+      Callbacks->FileSkipped(*File, FilenameTok, FileCharacter);
+    return;
+  }
+
+  // Look up the file, create a File ID for it.
+  FileID FID = SourceMgr.createFileID(File, FilenameTok.getLocation(),
+                                      FileCharacter);
+  if (FID.isInvalid()) {
+    Diag(FilenameTok, diag::err_pp_file_not_found) << Filename;
+    return;
+  }
+
+  // Finally, if all is good, enter the new file!
+  EnterSourceFile(FID, CurDir, FilenameTok.getLocation());
+}
+
+/// HandleIncludeNextDirective - Implements #include_next.
+///
+void Preprocessor::HandleIncludeNextDirective(Token &IncludeNextTok) {
+  Diag(IncludeNextTok, diag::ext_pp_include_next_directive);
+
+  // #include_next is like #include, except that we start searching after
+  // the current found directory.  If we can't do this, issue a
+  // diagnostic.
+  const DirectoryLookup *Lookup = CurDirLookup;
+  if (isInPrimaryFile()) {
+    Lookup = 0;
+    Diag(IncludeNextTok, diag::pp_include_next_in_primary);
+  } else if (Lookup == 0) {
+    Diag(IncludeNextTok, diag::pp_include_next_absolute_path);
+  } else {
+    // Start looking up in the next directory.
+    ++Lookup;
+  }
+
+  return HandleIncludeDirective(IncludeNextTok, Lookup);
+}
+
+/// HandleImportDirective - Implements #import.
+///
+void Preprocessor::HandleImportDirective(Token &ImportTok) {
+  if (!Features.ObjC1)  // #import is standard for ObjC.
+    Diag(ImportTok, diag::ext_pp_import_directive);
+
+  return HandleIncludeDirective(ImportTok, 0, true);
+}
+
+/// HandleIncludeMacrosDirective - The -imacros command line option turns into a
+/// pseudo directive in the predefines buffer.  This handles it by sucking all
+/// tokens through the preprocessor and discarding them (only keeping the side
+/// effects on the preprocessor).
+void Preprocessor::HandleIncludeMacrosDirective(Token &IncludeMacrosTok) {
+  // This directive should only occur in the predefines buffer.  If not, emit an
+  // error and reject it.
+  SourceLocation Loc = IncludeMacrosTok.getLocation();
+  if (strcmp(SourceMgr.getBufferName(Loc), "<built-in>") != 0) {
+    Diag(IncludeMacrosTok.getLocation(),
+         diag::pp_include_macros_out_of_predefines);
+    DiscardUntilEndOfDirective();
+    return;
+  }
+
+  // Treat this as a normal #include for checking purposes.  If this is
+  // successful, it will push a new lexer onto the include stack.
+  HandleIncludeDirective(IncludeMacrosTok, 0, false);
+
+  Token TmpTok;
+  do {
+    Lex(TmpTok);
+    assert(TmpTok.isNot(tok::eof) && "Didn't find end of -imacros!");
+  } while (TmpTok.isNot(tok::hashhash));
+}
+
+//===----------------------------------------------------------------------===//
+// Preprocessor Macro Directive Handling.
+//===----------------------------------------------------------------------===//
+
+/// ReadMacroDefinitionArgList - The ( starting an argument list of a macro
+/// definition has just been read.  Lex the rest of the arguments and the
+/// closing ), updating MI with what we learn.  Return true if an error occurs
+/// parsing the arg list.
+bool Preprocessor::ReadMacroDefinitionArgList(MacroInfo *MI) {
+  llvm::SmallVector<IdentifierInfo*, 32> Arguments;
+
+  Token Tok;
+  while (1) {
+    LexUnexpandedToken(Tok);
+    switch (Tok.getKind()) {
+    case tok::r_paren:
+      // Found the end of the argument list.
+      if (Arguments.empty())  // #define FOO()
+        return false;
+      // Otherwise we have #define FOO(A,)
+      Diag(Tok, diag::err_pp_expected_ident_in_arg_list);
+      return true;
+    case tok::ellipsis:  // #define X(... -> C99 varargs
+      // Warn if use of C99 feature in non-C99 mode.
+      if (!Features.C99) Diag(Tok, diag::ext_variadic_macro);
+
+      // Lex the token after the identifier.
+      LexUnexpandedToken(Tok);
+      if (Tok.isNot(tok::r_paren)) {
+        Diag(Tok, diag::err_pp_missing_rparen_in_macro_def);
+        return true;
+      }
+      // Add the __VA_ARGS__ identifier as an argument.
+      Arguments.push_back(Ident__VA_ARGS__);
+      MI->setIsC99Varargs();
+      MI->setArgumentList(&Arguments[0], Arguments.size(), BP);
+      return false;
+    case tok::eom:  // #define X(
+      Diag(Tok, diag::err_pp_missing_rparen_in_macro_def);
+      return true;
+    default:
+      // Handle keywords and identifiers here to accept things like
+      // #define Foo(for) for.
+      IdentifierInfo *II = Tok.getIdentifierInfo();
+      if (II == 0) {
+        // #define X(1
+        Diag(Tok, diag::err_pp_invalid_tok_in_arg_list);
+        return true;
+      }
+
+      // If this is already used as an argument, it is used multiple times (e.g.
+      // #define X(A,A.
+      if (std::find(Arguments.begin(), Arguments.end(), II) !=
+          Arguments.end()) {  // C99 6.10.3p6
+        Diag(Tok, diag::err_pp_duplicate_name_in_arg_list) << II;
+        return true;
+      }
+
+      // Add the argument to the macro info.
+      Arguments.push_back(II);
+
+      // Lex the token after the identifier.
+      LexUnexpandedToken(Tok);
+
+      switch (Tok.getKind()) {
+      default:          // #define X(A B
+        Diag(Tok, diag::err_pp_expected_comma_in_arg_list);
+        return true;
+      case tok::r_paren: // #define X(A)
+        MI->setArgumentList(&Arguments[0], Arguments.size(), BP);
+        return false;
+      case tok::comma:  // #define X(A,
+        break;
+      case tok::ellipsis:  // #define X(A... -> GCC extension
+        // Diagnose extension.
+        Diag(Tok, diag::ext_named_variadic_macro);
+
+        // Lex the token after the identifier.
+        LexUnexpandedToken(Tok);
+        if (Tok.isNot(tok::r_paren)) {
+          Diag(Tok, diag::err_pp_missing_rparen_in_macro_def);
+          return true;
+        }
+
+        MI->setIsGNUVarargs();
+        MI->setArgumentList(&Arguments[0], Arguments.size(), BP);
+        return false;
+      }
+    }
+  }
+}
+
+/// HandleDefineDirective - Implements #define.  This consumes the entire macro
+/// line then lets the caller lex the next real token.
+void Preprocessor::HandleDefineDirective(Token &DefineTok) {
+  ++NumDefined;
+
+  Token MacroNameTok;
+  ReadMacroName(MacroNameTok, 1);
+
+  // Error reading macro name?  If so, diagnostic already issued.
+  if (MacroNameTok.is(tok::eom))
+    return;
+
+  Token LastTok = MacroNameTok;
+
+  // If we are supposed to keep comments in #defines, reenable comment saving
+  // mode.
+  if (CurLexer) CurLexer->SetCommentRetentionState(KeepMacroComments);
+
+  // Create the new macro.
+  MacroInfo *MI = AllocateMacroInfo(MacroNameTok.getLocation());
+
+  Token Tok;
+  LexUnexpandedToken(Tok);
+
+  // If this is a function-like macro definition, parse the argument list,
+  // marking each of the identifiers as being used as macro arguments.  Also,
+  // check other constraints on the first token of the macro body.
+  if (Tok.is(tok::eom)) {
+    // If there is no body to this macro, we have no special handling here.
+  } else if (Tok.hasLeadingSpace()) {
+    // This is a normal token with leading space.  Clear the leading space
+    // marker on the first token to get proper expansion.
+    Tok.clearFlag(Token::LeadingSpace);
+  } else if (Tok.is(tok::l_paren)) {
+    // This is a function-like macro definition.  Read the argument list.
+    MI->setIsFunctionLike();
+    if (ReadMacroDefinitionArgList(MI)) {
+      // Forget about MI.
+      ReleaseMacroInfo(MI);
+      // Throw away the rest of the line.
+      if (CurPPLexer->ParsingPreprocessorDirective)
+        DiscardUntilEndOfDirective();
+      return;
+    }
+
+    // If this is a definition of a variadic C99 function-like macro, not using
+    // the GNU named varargs extension, enabled __VA_ARGS__.
+
+    // "Poison" __VA_ARGS__, which can only appear in the expansion of a macro.
+    // This gets unpoisoned where it is allowed.
+    assert(Ident__VA_ARGS__->isPoisoned() && "__VA_ARGS__ should be poisoned!");
+    if (MI->isC99Varargs())
+      Ident__VA_ARGS__->setIsPoisoned(false);
+
+    // Read the first token after the arg list for down below.
+    LexUnexpandedToken(Tok);
+  } else if (Features.C99) {
+    // C99 requires whitespace between the macro definition and the body.  Emit
+    // a diagnostic for something like "#define X+".
+    Diag(Tok, diag::ext_c99_whitespace_required_after_macro_name);
+  } else {
+    // C90 6.8 TC1 says: "In the definition of an object-like macro, if the
+    // first character of a replacement list is not a character required by
+    // subclause 5.2.1, then there shall be white-space separation between the
+    // identifier and the replacement list.".  5.2.1 lists this set:
+    //   "A-Za-z0-9!"#%&'()*+,_./:;<=>?[\]^_{|}~" as well as whitespace, which
+    // is irrelevant here.
+    bool isInvalid = false;
+    if (Tok.is(tok::at)) // @ is not in the list above.
+      isInvalid = true;
+    else if (Tok.is(tok::unknown)) {
+      // If we have an unknown token, it is something strange like "`".  Since
+      // all of valid characters would have lexed into a single character
+      // token of some sort, we know this is not a valid case.
+      isInvalid = true;
+    }
+    if (isInvalid)
+      Diag(Tok, diag::ext_missing_whitespace_after_macro_name);
+    else
+      Diag(Tok, diag::warn_missing_whitespace_after_macro_name);
+  }
+
+  if (!Tok.is(tok::eom))
+    LastTok = Tok;
+
+  // Read the rest of the macro body.
+  if (MI->isObjectLike()) {
+    // Object-like macros are very simple, just read their body.
+    while (Tok.isNot(tok::eom)) {
+      LastTok = Tok;
+      MI->AddTokenToBody(Tok);
+      // Get the next token of the macro.
+      LexUnexpandedToken(Tok);
+    }
+
+  } else {
+    // Otherwise, read the body of a function-like macro.  While we are at it,
+    // check C99 6.10.3.2p1: ensure that # operators are followed by macro
+    // parameters in function-like macro expansions.
+    while (Tok.isNot(tok::eom)) {
+      LastTok = Tok;
+
+      if (Tok.isNot(tok::hash)) {
+        MI->AddTokenToBody(Tok);
+
+        // Get the next token of the macro.
+        LexUnexpandedToken(Tok);
+        continue;
+      }
+
+      // Get the next token of the macro.
+      LexUnexpandedToken(Tok);
+
+      // Check for a valid macro arg identifier.
+      if (Tok.getIdentifierInfo() == 0 ||
+          MI->getArgumentNum(Tok.getIdentifierInfo()) == -1) {
+
+        // If this is assembler-with-cpp mode, we accept random gibberish after
+        // the '#' because '#' is often a comment character.  However, change
+        // the kind of the token to tok::unknown so that the preprocessor isn't
+        // confused.
+        if (getLangOptions().AsmPreprocessor && Tok.isNot(tok::eom)) {
+          LastTok.setKind(tok::unknown);
+        } else {
+          Diag(Tok, diag::err_pp_stringize_not_parameter);
+          ReleaseMacroInfo(MI);
+
+          // Disable __VA_ARGS__ again.
+          Ident__VA_ARGS__->setIsPoisoned(true);
+          return;
+        }
+      }
+
+      // Things look ok, add the '#' and param name tokens to the macro.
+      MI->AddTokenToBody(LastTok);
+      MI->AddTokenToBody(Tok);
+      LastTok = Tok;
+
+      // Get the next token of the macro.
+      LexUnexpandedToken(Tok);
+    }
+  }
+
+
+  // Disable __VA_ARGS__ again.
+  Ident__VA_ARGS__->setIsPoisoned(true);
+
+  // Check that there is no paste (##) operator at the begining or end of the
+  // replacement list.
+  unsigned NumTokens = MI->getNumTokens();
+  if (NumTokens != 0) {
+    if (MI->getReplacementToken(0).is(tok::hashhash)) {
+      Diag(MI->getReplacementToken(0), diag::err_paste_at_start);
+      ReleaseMacroInfo(MI);
+      return;
+    }
+    if (MI->getReplacementToken(NumTokens-1).is(tok::hashhash)) {
+      Diag(MI->getReplacementToken(NumTokens-1), diag::err_paste_at_end);
+      ReleaseMacroInfo(MI);
+      return;
+    }
+  }
+
+  // If this is the primary source file, remember that this macro hasn't been
+  // used yet.
+  if (isInPrimaryFile())
+    MI->setIsUsed(false);
+
+  MI->setDefinitionEndLoc(LastTok.getLocation());
+
+  // Finally, if this identifier already had a macro defined for it, verify that
+  // the macro bodies are identical and free the old definition.
+  if (MacroInfo *OtherMI = getMacroInfo(MacroNameTok.getIdentifierInfo())) {
+    // It is very common for system headers to have tons of macro redefinitions
+    // and for warnings to be disabled in system headers.  If this is the case,
+    // then don't bother calling MacroInfo::isIdenticalTo.
+    if (!getDiagnostics().getSuppressSystemWarnings() ||
+        !SourceMgr.isInSystemHeader(DefineTok.getLocation())) {
+      if (!OtherMI->isUsed())
+        Diag(OtherMI->getDefinitionLoc(), diag::pp_macro_not_used);
+
+      // Macros must be identical.  This means all tokes and whitespace
+      // separation must be the same.  C99 6.10.3.2.
+      if (!MI->isIdenticalTo(*OtherMI, *this)) {
+        Diag(MI->getDefinitionLoc(), diag::ext_pp_macro_redef)
+          << MacroNameTok.getIdentifierInfo();
+        Diag(OtherMI->getDefinitionLoc(), diag::note_previous_definition);
+      }
+    }
+
+    ReleaseMacroInfo(OtherMI);
+  }
+
+  setMacroInfo(MacroNameTok.getIdentifierInfo(), MI);
+
+  // If the callbacks want to know, tell them about the macro definition.
+  if (Callbacks)
+    Callbacks->MacroDefined(MacroNameTok.getIdentifierInfo(), MI);
+}
+
+/// HandleUndefDirective - Implements #undef.
+///
+void Preprocessor::HandleUndefDirective(Token &UndefTok) {
+  ++NumUndefined;
+
+  Token MacroNameTok;
+  ReadMacroName(MacroNameTok, 2);
+
+  // Error reading macro name?  If so, diagnostic already issued.
+  if (MacroNameTok.is(tok::eom))
+    return;
+
+  // Check to see if this is the last token on the #undef line.
+  CheckEndOfDirective("undef");
+
+  // Okay, we finally have a valid identifier to undef.
+  MacroInfo *MI = getMacroInfo(MacroNameTok.getIdentifierInfo());
+
+  // If the macro is not defined, this is a noop undef, just return.
+  if (MI == 0) return;
+
+  if (!MI->isUsed())
+    Diag(MI->getDefinitionLoc(), diag::pp_macro_not_used);
+
+  // If the callbacks want to know, tell them about the macro #undef.
+  if (Callbacks)
+    Callbacks->MacroUndefined(MacroNameTok.getIdentifierInfo(), MI);
+
+  // Free macro definition.
+  ReleaseMacroInfo(MI);
+  setMacroInfo(MacroNameTok.getIdentifierInfo(), 0);
+}
+
+
+//===----------------------------------------------------------------------===//
+// Preprocessor Conditional Directive Handling.
+//===----------------------------------------------------------------------===//
+
+/// HandleIfdefDirective - Implements the #ifdef/#ifndef directive.  isIfndef is
+/// true when this is a #ifndef directive.  ReadAnyTokensBeforeDirective is true
+/// if any tokens have been returned or pp-directives activated before this
+/// #ifndef has been lexed.
+///
+void Preprocessor::HandleIfdefDirective(Token &Result, bool isIfndef,
+                                        bool ReadAnyTokensBeforeDirective) {
+  ++NumIf;
+  Token DirectiveTok = Result;
+
+  Token MacroNameTok;
+  ReadMacroName(MacroNameTok);
+
+  // Error reading macro name?  If so, diagnostic already issued.
+  if (MacroNameTok.is(tok::eom)) {
+    // Skip code until we get to #endif.  This helps with recovery by not
+    // emitting an error when the #endif is reached.
+    SkipExcludedConditionalBlock(DirectiveTok.getLocation(),
+                                 /*Foundnonskip*/false, /*FoundElse*/false);
+    return;
+  }
+
+  // Check to see if this is the last token on the #if[n]def line.
+  CheckEndOfDirective(isIfndef ? "ifndef" : "ifdef");
+
+  IdentifierInfo *MII = MacroNameTok.getIdentifierInfo();
+  MacroInfo *MI = getMacroInfo(MII);
+
+  if (CurPPLexer->getConditionalStackDepth() == 0) {
+    // If the start of a top-level #ifdef and if the macro is not defined,
+    // inform MIOpt that this might be the start of a proper include guard.
+    // Otherwise it is some other form of unknown conditional which we can't
+    // handle.
+    if (!ReadAnyTokensBeforeDirective && MI == 0) {
+      assert(isIfndef && "#ifdef shouldn't reach here");
+      CurPPLexer->MIOpt.EnterTopLevelIFNDEF(MII);
+    } else
+      CurPPLexer->MIOpt.EnterTopLevelConditional();
+  }
+
+  // If there is a macro, process it.
+  if (MI)  // Mark it used.
+    MI->setIsUsed(true);
+
+  // Should we include the stuff contained by this directive?
+  if (!MI == isIfndef) {
+    // Yes, remember that we are inside a conditional, then lex the next token.
+    CurPPLexer->pushConditionalLevel(DirectiveTok.getLocation(),
+                                     /*wasskip*/false, /*foundnonskip*/true,
+                                     /*foundelse*/false);
+  } else {
+    // No, skip the contents of this block and return the first token after it.
+    SkipExcludedConditionalBlock(DirectiveTok.getLocation(),
+                                 /*Foundnonskip*/false,
+                                 /*FoundElse*/false);
+  }
+}
+
+/// HandleIfDirective - Implements the #if directive.
+///
+void Preprocessor::HandleIfDirective(Token &IfToken,
+                                     bool ReadAnyTokensBeforeDirective) {
+  ++NumIf;
+
+  // Parse and evaluation the conditional expression.
+  IdentifierInfo *IfNDefMacro = 0;
+  bool ConditionalTrue = EvaluateDirectiveExpression(IfNDefMacro);
+
+
+  // If this condition is equivalent to #ifndef X, and if this is the first
+  // directive seen, handle it for the multiple-include optimization.
+  if (CurPPLexer->getConditionalStackDepth() == 0) {
+    if (!ReadAnyTokensBeforeDirective && IfNDefMacro && ConditionalTrue)
+      CurPPLexer->MIOpt.EnterTopLevelIFNDEF(IfNDefMacro);
+    else
+      CurPPLexer->MIOpt.EnterTopLevelConditional();
+  }
+
+  // Should we include the stuff contained by this directive?
+  if (ConditionalTrue) {
+    // Yes, remember that we are inside a conditional, then lex the next token.
+    CurPPLexer->pushConditionalLevel(IfToken.getLocation(), /*wasskip*/false,
+                                   /*foundnonskip*/true, /*foundelse*/false);
+  } else {
+    // No, skip the contents of this block and return the first token after it.
+    SkipExcludedConditionalBlock(IfToken.getLocation(), /*Foundnonskip*/false,
+                                 /*FoundElse*/false);
+  }
+}
+
+/// HandleEndifDirective - Implements the #endif directive.
+///
+void Preprocessor::HandleEndifDirective(Token &EndifToken) {
+  ++NumEndif;
+
+  // Check that this is the whole directive.
+  CheckEndOfDirective("endif");
+
+  PPConditionalInfo CondInfo;
+  if (CurPPLexer->popConditionalLevel(CondInfo)) {
+    // No conditionals on the stack: this is an #endif without an #if.
+    Diag(EndifToken, diag::err_pp_endif_without_if);
+    return;
+  }
+
+  // If this the end of a top-level #endif, inform MIOpt.
+  if (CurPPLexer->getConditionalStackDepth() == 0)
+    CurPPLexer->MIOpt.ExitTopLevelConditional();
+
+  assert(!CondInfo.WasSkipping && !CurPPLexer->LexingRawMode &&
+         "This code should only be reachable in the non-skipping case!");
+}
+
+
+void Preprocessor::HandleElseDirective(Token &Result) {
+  ++NumElse;
+
+  // #else directive in a non-skipping conditional... start skipping.
+  CheckEndOfDirective("else");
+
+  PPConditionalInfo CI;
+  if (CurPPLexer->popConditionalLevel(CI)) {
+    Diag(Result, diag::pp_err_else_without_if);
+    return;
+  }
+
+  // If this is a top-level #else, inform the MIOpt.
+  if (CurPPLexer->getConditionalStackDepth() == 0)
+    CurPPLexer->MIOpt.EnterTopLevelConditional();
+
+  // If this is a #else with a #else before it, report the error.
+  if (CI.FoundElse) Diag(Result, diag::pp_err_else_after_else);
+
+  // Finally, skip the rest of the contents of this block and return the first
+  // token after it.
+  return SkipExcludedConditionalBlock(CI.IfLoc, /*Foundnonskip*/true,
+                                      /*FoundElse*/true);
+}
+
+void Preprocessor::HandleElifDirective(Token &ElifToken) {
+  ++NumElse;
+
+  // #elif directive in a non-skipping conditional... start skipping.
+  // We don't care what the condition is, because we will always skip it (since
+  // the block immediately before it was included).
+  DiscardUntilEndOfDirective();
+
+  PPConditionalInfo CI;
+  if (CurPPLexer->popConditionalLevel(CI)) {
+    Diag(ElifToken, diag::pp_err_elif_without_if);
+    return;
+  }
+
+  // If this is a top-level #elif, inform the MIOpt.
+  if (CurPPLexer->getConditionalStackDepth() == 0)
+    CurPPLexer->MIOpt.EnterTopLevelConditional();
+
+  // If this is a #elif with a #else before it, report the error.
+  if (CI.FoundElse) Diag(ElifToken, diag::pp_err_elif_after_else);
+
+  // Finally, skip the rest of the contents of this block and return the first
+  // token after it.
+  return SkipExcludedConditionalBlock(CI.IfLoc, /*Foundnonskip*/true,
+                                      /*FoundElse*/CI.FoundElse);
+}
diff --git a/lib/Lex/PPExpressions.cpp b/lib/Lex/PPExpressions.cpp
new file mode 100644
index 0000000..756ce27
--- /dev/null
+++ b/lib/Lex/PPExpressions.cpp
@@ -0,0 +1,750 @@
+//===--- PPExpressions.cpp - Preprocessor Expression Evaluation -----------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Preprocessor::EvaluateDirectiveExpression method,
+// which parses and evaluates integer constant expressions for #if directives.
+//
+//===----------------------------------------------------------------------===//
+//
+// FIXME: implement testing for #assert's.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Lex/MacroInfo.h"
+#include "clang/Lex/LiteralSupport.h"
+#include "clang/Basic/TargetInfo.h"
+#include "clang/Lex/LexDiagnostic.h"
+#include "llvm/ADT/APSInt.h"
+using namespace clang;
+
+/// PPValue - Represents the value of a subexpression of a preprocessor
+/// conditional and the source range covered by it.
+class PPValue {
+  SourceRange Range;
+public:
+  llvm::APSInt Val;
+
+  // Default ctor - Construct an 'invalid' PPValue.
+  PPValue(unsigned BitWidth) : Val(BitWidth) {}
+
+  unsigned getBitWidth() const { return Val.getBitWidth(); }
+  bool isUnsigned() const { return Val.isUnsigned(); }
+
+  const SourceRange &getRange() const { return Range; }
+
+  void setRange(SourceLocation L) { Range.setBegin(L); Range.setEnd(L); }
+  void setRange(SourceLocation B, SourceLocation E) {
+    Range.setBegin(B); Range.setEnd(E);
+  }
+  void setBegin(SourceLocation L) { Range.setBegin(L); }
+  void setEnd(SourceLocation L) { Range.setEnd(L); }
+};
+
+static bool EvaluateDirectiveSubExpr(PPValue &LHS, unsigned MinPrec,
+                                     Token &PeekTok, bool ValueLive,
+                                     Preprocessor &PP);
+
+/// DefinedTracker - This struct is used while parsing expressions to keep track
+/// of whether !defined(X) has been seen.
+///
+/// With this simple scheme, we handle the basic forms:
+///    !defined(X)   and !defined X
+/// but we also trivially handle (silly) stuff like:
+///    !!!defined(X) and +!defined(X) and !+!+!defined(X) and !(defined(X)).
+struct DefinedTracker {
+  /// Each time a Value is evaluated, it returns information about whether the
+  /// parsed value is of the form defined(X), !defined(X) or is something else.
+  enum TrackerState {
+    DefinedMacro,        // defined(X)
+    NotDefinedMacro,     // !defined(X)
+    Unknown              // Something else.
+  } State;
+  /// TheMacro - When the state is DefinedMacro or NotDefinedMacro, this
+  /// indicates the macro that was checked.
+  IdentifierInfo *TheMacro;
+};
+
+/// EvaluateDefined - Process a 'defined(sym)' expression.
+static bool EvaluateDefined(PPValue &Result, Token &PeekTok, DefinedTracker &DT,
+                            bool ValueLive, Preprocessor &PP) {
+  IdentifierInfo *II;
+  Result.setBegin(PeekTok.getLocation());
+
+  // Get the next token, don't expand it.
+  PP.LexUnexpandedToken(PeekTok);
+
+  // Two options, it can either be a pp-identifier or a (.
+  SourceLocation LParenLoc;
+  if (PeekTok.is(tok::l_paren)) {
+    // Found a paren, remember we saw it and skip it.
+    LParenLoc = PeekTok.getLocation();
+    PP.LexUnexpandedToken(PeekTok);
+  }
+
+  // If we don't have a pp-identifier now, this is an error.
+  if ((II = PeekTok.getIdentifierInfo()) == 0) {
+    PP.Diag(PeekTok, diag::err_pp_defined_requires_identifier);
+    return true;
+  }
+
+  // Otherwise, we got an identifier, is it defined to something?
+  Result.Val = II->hasMacroDefinition();
+  Result.Val.setIsUnsigned(false);  // Result is signed intmax_t.
+
+  // If there is a macro, mark it used.
+  if (Result.Val != 0 && ValueLive) {
+    MacroInfo *Macro = PP.getMacroInfo(II);
+    Macro->setIsUsed(true);
+  }
+
+  // Consume identifier.
+  Result.setEnd(PeekTok.getLocation());
+  PP.LexUnexpandedToken(PeekTok);
+
+  // If we are in parens, ensure we have a trailing ).
+  if (LParenLoc.isValid()) {
+    if (PeekTok.isNot(tok::r_paren)) {
+      PP.Diag(PeekTok.getLocation(), diag::err_pp_missing_rparen) << "defined";
+      PP.Diag(LParenLoc, diag::note_matching) << "(";
+      return true;
+    }
+    // Consume the ).
+    Result.setEnd(PeekTok.getLocation());
+    PP.LexNonComment(PeekTok);
+  }
+
+  // Success, remember that we saw defined(X).
+  DT.State = DefinedTracker::DefinedMacro;
+  DT.TheMacro = II;
+  return false;
+}
+
+/// EvaluateValue - Evaluate the token PeekTok (and any others needed) and
+/// return the computed value in Result.  Return true if there was an error
+/// parsing.  This function also returns information about the form of the
+/// expression in DT.  See above for information on what DT means.
+///
+/// If ValueLive is false, then this value is being evaluated in a context where
+/// the result is not used.  As such, avoid diagnostics that relate to
+/// evaluation.
+static bool EvaluateValue(PPValue &Result, Token &PeekTok, DefinedTracker &DT,
+                          bool ValueLive, Preprocessor &PP) {
+  DT.State = DefinedTracker::Unknown;
+
+  // If this token's spelling is a pp-identifier, check to see if it is
+  // 'defined' or if it is a macro.  Note that we check here because many
+  // keywords are pp-identifiers, so we can't check the kind.
+  if (IdentifierInfo *II = PeekTok.getIdentifierInfo()) {
+    // Handle "defined X" and "defined(X)".
+    if (II->isStr("defined"))
+      return(EvaluateDefined(Result, PeekTok, DT, ValueLive, PP));
+    
+    // If this identifier isn't 'defined' or one of the special
+    // preprocessor keywords and it wasn't macro expanded, it turns
+    // into a simple 0, unless it is the C++ keyword "true", in which case it
+    // turns into "1".
+    if (ValueLive)
+      PP.Diag(PeekTok, diag::warn_pp_undef_identifier) << II;
+    Result.Val = II->getTokenID() == tok::kw_true;
+    Result.Val.setIsUnsigned(false);  // "0" is signed intmax_t 0.
+    Result.setRange(PeekTok.getLocation());
+    PP.LexNonComment(PeekTok);
+    return false;
+  }
+
+  switch (PeekTok.getKind()) {
+  default:  // Non-value token.
+    PP.Diag(PeekTok, diag::err_pp_expr_bad_token_start_expr);
+    return true;
+  case tok::eom:
+  case tok::r_paren:
+    // If there is no expression, report and exit.
+    PP.Diag(PeekTok, diag::err_pp_expected_value_in_expr);
+    return true;
+  case tok::numeric_constant: {
+    llvm::SmallString<64> IntegerBuffer;
+    bool NumberInvalid = false;
+    llvm::StringRef Spelling = PP.getSpelling(PeekTok, IntegerBuffer, 
+                                              &NumberInvalid);
+    if (NumberInvalid)
+      return true; // a diagnostic was already reported
+
+    NumericLiteralParser Literal(Spelling.begin(), Spelling.end(),
+                                 PeekTok.getLocation(), PP);
+    if (Literal.hadError)
+      return true; // a diagnostic was already reported.
+
+    if (Literal.isFloatingLiteral() || Literal.isImaginary) {
+      PP.Diag(PeekTok, diag::err_pp_illegal_floating_literal);
+      return true;
+    }
+    assert(Literal.isIntegerLiteral() && "Unknown ppnumber");
+
+    // long long is a C99 feature.
+    if (!PP.getLangOptions().C99 && !PP.getLangOptions().CPlusPlus0x
+        && Literal.isLongLong)
+      PP.Diag(PeekTok, diag::ext_longlong);
+
+    // Parse the integer literal into Result.
+    if (Literal.GetIntegerValue(Result.Val)) {
+      // Overflow parsing integer literal.
+      if (ValueLive) PP.Diag(PeekTok, diag::warn_integer_too_large);
+      Result.Val.setIsUnsigned(true);
+    } else {
+      // Set the signedness of the result to match whether there was a U suffix
+      // or not.
+      Result.Val.setIsUnsigned(Literal.isUnsigned);
+
+      // Detect overflow based on whether the value is signed.  If signed
+      // and if the value is too large, emit a warning "integer constant is so
+      // large that it is unsigned" e.g. on 12345678901234567890 where intmax_t
+      // is 64-bits.
+      if (!Literal.isUnsigned && Result.Val.isNegative()) {
+        // Don't warn for a hex literal: 0x8000..0 shouldn't warn.
+        if (ValueLive && Literal.getRadix() != 16)
+          PP.Diag(PeekTok, diag::warn_integer_too_large_for_signed);
+        Result.Val.setIsUnsigned(true);
+      }
+    }
+
+    // Consume the token.
+    Result.setRange(PeekTok.getLocation());
+    PP.LexNonComment(PeekTok);
+    return false;
+  }
+  case tok::char_constant: {   // 'x'
+    llvm::SmallString<32> CharBuffer;
+    bool CharInvalid = false;
+    llvm::StringRef ThisTok = PP.getSpelling(PeekTok, CharBuffer, &CharInvalid);
+    if (CharInvalid)
+      return true;
+
+    CharLiteralParser Literal(ThisTok.begin(), ThisTok.end(),
+                              PeekTok.getLocation(), PP);
+    if (Literal.hadError())
+      return true;  // A diagnostic was already emitted.
+
+    // Character literals are always int or wchar_t, expand to intmax_t.
+    const TargetInfo &TI = PP.getTargetInfo();
+    unsigned NumBits;
+    if (Literal.isMultiChar())
+      NumBits = TI.getIntWidth();
+    else if (Literal.isWide())
+      NumBits = TI.getWCharWidth();
+    else
+      NumBits = TI.getCharWidth();
+
+    // Set the width.
+    llvm::APSInt Val(NumBits);
+    // Set the value.
+    Val = Literal.getValue();
+    // Set the signedness.
+    Val.setIsUnsigned(!PP.getLangOptions().CharIsSigned);
+
+    if (Result.Val.getBitWidth() > Val.getBitWidth()) {
+      Result.Val = Val.extend(Result.Val.getBitWidth());
+    } else {
+      assert(Result.Val.getBitWidth() == Val.getBitWidth() &&
+             "intmax_t smaller than char/wchar_t?");
+      Result.Val = Val;
+    }
+
+    // Consume the token.
+    Result.setRange(PeekTok.getLocation());
+    PP.LexNonComment(PeekTok);
+    return false;
+  }
+  case tok::l_paren: {
+    SourceLocation Start = PeekTok.getLocation();
+    PP.LexNonComment(PeekTok);  // Eat the (.
+    // Parse the value and if there are any binary operators involved, parse
+    // them.
+    if (EvaluateValue(Result, PeekTok, DT, ValueLive, PP)) return true;
+
+    // If this is a silly value like (X), which doesn't need parens, check for
+    // !(defined X).
+    if (PeekTok.is(tok::r_paren)) {
+      // Just use DT unmodified as our result.
+    } else {
+      // Otherwise, we have something like (x+y), and we consumed '(x'.
+      if (EvaluateDirectiveSubExpr(Result, 1, PeekTok, ValueLive, PP))
+        return true;
+
+      if (PeekTok.isNot(tok::r_paren)) {
+        PP.Diag(PeekTok.getLocation(), diag::err_pp_expected_rparen)
+          << Result.getRange();
+        PP.Diag(Start, diag::note_matching) << "(";
+        return true;
+      }
+      DT.State = DefinedTracker::Unknown;
+    }
+    Result.setRange(Start, PeekTok.getLocation());
+    PP.LexNonComment(PeekTok);  // Eat the ).
+    return false;
+  }
+  case tok::plus: {
+    SourceLocation Start = PeekTok.getLocation();
+    // Unary plus doesn't modify the value.
+    PP.LexNonComment(PeekTok);
+    if (EvaluateValue(Result, PeekTok, DT, ValueLive, PP)) return true;
+    Result.setBegin(Start);
+    return false;
+  }
+  case tok::minus: {
+    SourceLocation Loc = PeekTok.getLocation();
+    PP.LexNonComment(PeekTok);
+    if (EvaluateValue(Result, PeekTok, DT, ValueLive, PP)) return true;
+    Result.setBegin(Loc);
+
+    // C99 6.5.3.3p3: The sign of the result matches the sign of the operand.
+    Result.Val = -Result.Val;
+
+    // -MININT is the only thing that overflows.  Unsigned never overflows.
+    bool Overflow = !Result.isUnsigned() && Result.Val.isMinSignedValue();
+
+    // If this operator is live and overflowed, report the issue.
+    if (Overflow && ValueLive)
+      PP.Diag(Loc, diag::warn_pp_expr_overflow) << Result.getRange();
+
+    DT.State = DefinedTracker::Unknown;
+    return false;
+  }
+
+  case tok::tilde: {
+    SourceLocation Start = PeekTok.getLocation();
+    PP.LexNonComment(PeekTok);
+    if (EvaluateValue(Result, PeekTok, DT, ValueLive, PP)) return true;
+    Result.setBegin(Start);
+
+    // C99 6.5.3.3p4: The sign of the result matches the sign of the operand.
+    Result.Val = ~Result.Val;
+    DT.State = DefinedTracker::Unknown;
+    return false;
+  }
+
+  case tok::exclaim: {
+    SourceLocation Start = PeekTok.getLocation();
+    PP.LexNonComment(PeekTok);
+    if (EvaluateValue(Result, PeekTok, DT, ValueLive, PP)) return true;
+    Result.setBegin(Start);
+    Result.Val = !Result.Val;
+    // C99 6.5.3.3p5: The sign of the result is 'int', aka it is signed.
+    Result.Val.setIsUnsigned(false);
+
+    if (DT.State == DefinedTracker::DefinedMacro)
+      DT.State = DefinedTracker::NotDefinedMacro;
+    else if (DT.State == DefinedTracker::NotDefinedMacro)
+      DT.State = DefinedTracker::DefinedMacro;
+    return false;
+  }
+
+  // FIXME: Handle #assert
+  }
+}
+
+
+
+/// getPrecedence - Return the precedence of the specified binary operator
+/// token.  This returns:
+///   ~0 - Invalid token.
+///   14 -> 3 - various operators.
+///    0 - 'eom' or ')'
+static unsigned getPrecedence(tok::TokenKind Kind) {
+  switch (Kind) {
+  default: return ~0U;
+  case tok::percent:
+  case tok::slash:
+  case tok::star:                 return 14;
+  case tok::plus:
+  case tok::minus:                return 13;
+  case tok::lessless:
+  case tok::greatergreater:       return 12;
+  case tok::lessequal:
+  case tok::less:
+  case tok::greaterequal:
+  case tok::greater:              return 11;
+  case tok::exclaimequal:
+  case tok::equalequal:           return 10;
+  case tok::amp:                  return 9;
+  case tok::caret:                return 8;
+  case tok::pipe:                 return 7;
+  case tok::ampamp:               return 6;
+  case tok::pipepipe:             return 5;
+  case tok::question:             return 4;
+  case tok::comma:                return 3;
+  case tok::colon:                return 2;
+  case tok::r_paren:              return 0;   // Lowest priority, end of expr.
+  case tok::eom:                  return 0;   // Lowest priority, end of macro.
+  }
+}
+
+
+/// EvaluateDirectiveSubExpr - Evaluate the subexpression whose first token is
+/// PeekTok, and whose precedence is PeekPrec.  This returns the result in LHS.
+///
+/// If ValueLive is false, then this value is being evaluated in a context where
+/// the result is not used.  As such, avoid diagnostics that relate to
+/// evaluation, such as division by zero warnings.
+static bool EvaluateDirectiveSubExpr(PPValue &LHS, unsigned MinPrec,
+                                     Token &PeekTok, bool ValueLive,
+                                     Preprocessor &PP) {
+  unsigned PeekPrec = getPrecedence(PeekTok.getKind());
+  // If this token isn't valid, report the error.
+  if (PeekPrec == ~0U) {
+    PP.Diag(PeekTok.getLocation(), diag::err_pp_expr_bad_token_binop)
+      << LHS.getRange();
+    return true;
+  }
+
+  while (1) {
+    // If this token has a lower precedence than we are allowed to parse, return
+    // it so that higher levels of the recursion can parse it.
+    if (PeekPrec < MinPrec)
+      return false;
+
+    tok::TokenKind Operator = PeekTok.getKind();
+
+    // If this is a short-circuiting operator, see if the RHS of the operator is
+    // dead.  Note that this cannot just clobber ValueLive.  Consider
+    // "0 && 1 ? 4 : 1 / 0", which is parsed as "(0 && 1) ? 4 : (1 / 0)".  In
+    // this example, the RHS of the && being dead does not make the rest of the
+    // expr dead.
+    bool RHSIsLive;
+    if (Operator == tok::ampamp && LHS.Val == 0)
+      RHSIsLive = false;   // RHS of "0 && x" is dead.
+    else if (Operator == tok::pipepipe && LHS.Val != 0)
+      RHSIsLive = false;   // RHS of "1 || x" is dead.
+    else if (Operator == tok::question && LHS.Val == 0)
+      RHSIsLive = false;   // RHS (x) of "0 ? x : y" is dead.
+    else
+      RHSIsLive = ValueLive;
+
+    // Consume the operator, remembering the operator's location for reporting.
+    SourceLocation OpLoc = PeekTok.getLocation();
+    PP.LexNonComment(PeekTok);
+
+    PPValue RHS(LHS.getBitWidth());
+    // Parse the RHS of the operator.
+    DefinedTracker DT;
+    if (EvaluateValue(RHS, PeekTok, DT, RHSIsLive, PP)) return true;
+
+    // Remember the precedence of this operator and get the precedence of the
+    // operator immediately to the right of the RHS.
+    unsigned ThisPrec = PeekPrec;
+    PeekPrec = getPrecedence(PeekTok.getKind());
+
+    // If this token isn't valid, report the error.
+    if (PeekPrec == ~0U) {
+      PP.Diag(PeekTok.getLocation(), diag::err_pp_expr_bad_token_binop)
+        << RHS.getRange();
+      return true;
+    }
+
+    // Decide whether to include the next binop in this subexpression.  For
+    // example, when parsing x+y*z and looking at '*', we want to recursively
+    // handle y*z as a single subexpression.  We do this because the precedence
+    // of * is higher than that of +.  The only strange case we have to handle
+    // here is for the ?: operator, where the precedence is actually lower than
+    // the LHS of the '?'.  The grammar rule is:
+    //
+    // conditional-expression ::=
+    //    logical-OR-expression ? expression : conditional-expression
+    // where 'expression' is actually comma-expression.
+    unsigned RHSPrec;
+    if (Operator == tok::question)
+      // The RHS of "?" should be maximally consumed as an expression.
+      RHSPrec = getPrecedence(tok::comma);
+    else  // All others should munch while higher precedence.
+      RHSPrec = ThisPrec+1;
+
+    if (PeekPrec >= RHSPrec) {
+      if (EvaluateDirectiveSubExpr(RHS, RHSPrec, PeekTok, RHSIsLive, PP))
+        return true;
+      PeekPrec = getPrecedence(PeekTok.getKind());
+    }
+    assert(PeekPrec <= ThisPrec && "Recursion didn't work!");
+
+    // Usual arithmetic conversions (C99 6.3.1.8p1): result is unsigned if
+    // either operand is unsigned.
+    llvm::APSInt Res(LHS.getBitWidth());
+    switch (Operator) {
+    case tok::question:       // No UAC for x and y in "x ? y : z".
+    case tok::lessless:       // Shift amount doesn't UAC with shift value.
+    case tok::greatergreater: // Shift amount doesn't UAC with shift value.
+    case tok::comma:          // Comma operands are not subject to UACs.
+    case tok::pipepipe:       // Logical || does not do UACs.
+    case tok::ampamp:         // Logical && does not do UACs.
+      break;                  // No UAC
+    default:
+      Res.setIsUnsigned(LHS.isUnsigned()|RHS.isUnsigned());
+      // If this just promoted something from signed to unsigned, and if the
+      // value was negative, warn about it.
+      if (ValueLive && Res.isUnsigned()) {
+        if (!LHS.isUnsigned() && LHS.Val.isNegative())
+          PP.Diag(OpLoc, diag::warn_pp_convert_lhs_to_positive)
+            << LHS.Val.toString(10, true) + " to " +
+               LHS.Val.toString(10, false)
+            << LHS.getRange() << RHS.getRange();
+        if (!RHS.isUnsigned() && RHS.Val.isNegative())
+          PP.Diag(OpLoc, diag::warn_pp_convert_rhs_to_positive)
+            << RHS.Val.toString(10, true) + " to " +
+               RHS.Val.toString(10, false)
+            << LHS.getRange() << RHS.getRange();
+      }
+      LHS.Val.setIsUnsigned(Res.isUnsigned());
+      RHS.Val.setIsUnsigned(Res.isUnsigned());
+    }
+
+    // FIXME: All of these should detect and report overflow??
+    bool Overflow = false;
+    switch (Operator) {
+    default: assert(0 && "Unknown operator token!");
+    case tok::percent:
+      if (RHS.Val != 0)
+        Res = LHS.Val % RHS.Val;
+      else if (ValueLive) {
+        PP.Diag(OpLoc, diag::err_pp_remainder_by_zero)
+          << LHS.getRange() << RHS.getRange();
+        return true;
+      }
+      break;
+    case tok::slash:
+      if (RHS.Val != 0) {
+        Res = LHS.Val / RHS.Val;
+        if (LHS.Val.isSigned())   // MININT/-1  -->  overflow.
+          Overflow = LHS.Val.isMinSignedValue() && RHS.Val.isAllOnesValue();
+      } else if (ValueLive) {
+        PP.Diag(OpLoc, diag::err_pp_division_by_zero)
+          << LHS.getRange() << RHS.getRange();
+        return true;
+      }
+      break;
+
+    case tok::star:
+      Res = LHS.Val * RHS.Val;
+      if (Res.isSigned() && LHS.Val != 0 && RHS.Val != 0)
+        Overflow = Res/RHS.Val != LHS.Val || Res/LHS.Val != RHS.Val;
+      break;
+    case tok::lessless: {
+      // Determine whether overflow is about to happen.
+      unsigned ShAmt = static_cast<unsigned>(RHS.Val.getLimitedValue());
+      if (ShAmt >= LHS.Val.getBitWidth())
+        Overflow = true, ShAmt = LHS.Val.getBitWidth()-1;
+      else if (LHS.isUnsigned())
+        Overflow = false;
+      else if (LHS.Val.isNonNegative()) // Don't allow sign change.
+        Overflow = ShAmt >= LHS.Val.countLeadingZeros();
+      else
+        Overflow = ShAmt >= LHS.Val.countLeadingOnes();
+
+      Res = LHS.Val << ShAmt;
+      break;
+    }
+    case tok::greatergreater: {
+      // Determine whether overflow is about to happen.
+      unsigned ShAmt = static_cast<unsigned>(RHS.Val.getLimitedValue());
+      if (ShAmt >= LHS.getBitWidth())
+        Overflow = true, ShAmt = LHS.getBitWidth()-1;
+      Res = LHS.Val >> ShAmt;
+      break;
+    }
+    case tok::plus:
+      Res = LHS.Val + RHS.Val;
+      if (LHS.isUnsigned())
+        Overflow = false;
+      else if (LHS.Val.isNonNegative() == RHS.Val.isNonNegative() &&
+               Res.isNonNegative() != LHS.Val.isNonNegative())
+        Overflow = true;  // Overflow for signed addition.
+      break;
+    case tok::minus:
+      Res = LHS.Val - RHS.Val;
+      if (LHS.isUnsigned())
+        Overflow = false;
+      else if (LHS.Val.isNonNegative() != RHS.Val.isNonNegative() &&
+               Res.isNonNegative() != LHS.Val.isNonNegative())
+        Overflow = true;  // Overflow for signed subtraction.
+      break;
+    case tok::lessequal:
+      Res = LHS.Val <= RHS.Val;
+      Res.setIsUnsigned(false);  // C99 6.5.8p6, result is always int (signed)
+      break;
+    case tok::less:
+      Res = LHS.Val < RHS.Val;
+      Res.setIsUnsigned(false);  // C99 6.5.8p6, result is always int (signed)
+      break;
+    case tok::greaterequal:
+      Res = LHS.Val >= RHS.Val;
+      Res.setIsUnsigned(false);  // C99 6.5.8p6, result is always int (signed)
+      break;
+    case tok::greater:
+      Res = LHS.Val > RHS.Val;
+      Res.setIsUnsigned(false);  // C99 6.5.8p6, result is always int (signed)
+      break;
+    case tok::exclaimequal:
+      Res = LHS.Val != RHS.Val;
+      Res.setIsUnsigned(false);  // C99 6.5.9p3, result is always int (signed)
+      break;
+    case tok::equalequal:
+      Res = LHS.Val == RHS.Val;
+      Res.setIsUnsigned(false);  // C99 6.5.9p3, result is always int (signed)
+      break;
+    case tok::amp:
+      Res = LHS.Val & RHS.Val;
+      break;
+    case tok::caret:
+      Res = LHS.Val ^ RHS.Val;
+      break;
+    case tok::pipe:
+      Res = LHS.Val | RHS.Val;
+      break;
+    case tok::ampamp:
+      Res = (LHS.Val != 0 && RHS.Val != 0);
+      Res.setIsUnsigned(false);  // C99 6.5.13p3, result is always int (signed)
+      break;
+    case tok::pipepipe:
+      Res = (LHS.Val != 0 || RHS.Val != 0);
+      Res.setIsUnsigned(false);  // C99 6.5.14p3, result is always int (signed)
+      break;
+    case tok::comma:
+      // Comma is invalid in pp expressions in c89/c++ mode, but is valid in C99
+      // if not being evaluated.
+      if (!PP.getLangOptions().C99 || ValueLive)
+        PP.Diag(OpLoc, diag::ext_pp_comma_expr)
+          << LHS.getRange() << RHS.getRange();
+      Res = RHS.Val; // LHS = LHS,RHS -> RHS.
+      break;
+    case tok::question: {
+      // Parse the : part of the expression.
+      if (PeekTok.isNot(tok::colon)) {
+        PP.Diag(PeekTok.getLocation(), diag::err_expected_colon)
+          << LHS.getRange(), RHS.getRange();
+        PP.Diag(OpLoc, diag::note_matching) << "?";
+        return true;
+      }
+      // Consume the :.
+      PP.LexNonComment(PeekTok);
+
+      // Evaluate the value after the :.
+      bool AfterColonLive = ValueLive && LHS.Val == 0;
+      PPValue AfterColonVal(LHS.getBitWidth());
+      DefinedTracker DT;
+      if (EvaluateValue(AfterColonVal, PeekTok, DT, AfterColonLive, PP))
+        return true;
+
+      // Parse anything after the : with the same precedence as ?.  We allow
+      // things of equal precedence because ?: is right associative.
+      if (EvaluateDirectiveSubExpr(AfterColonVal, ThisPrec,
+                                   PeekTok, AfterColonLive, PP))
+        return true;
+
+      // Now that we have the condition, the LHS and the RHS of the :, evaluate.
+      Res = LHS.Val != 0 ? RHS.Val : AfterColonVal.Val;
+      RHS.setEnd(AfterColonVal.getRange().getEnd());
+
+      // Usual arithmetic conversions (C99 6.3.1.8p1): result is unsigned if
+      // either operand is unsigned.
+      Res.setIsUnsigned(RHS.isUnsigned() | AfterColonVal.isUnsigned());
+
+      // Figure out the precedence of the token after the : part.
+      PeekPrec = getPrecedence(PeekTok.getKind());
+      break;
+    }
+    case tok::colon:
+      // Don't allow :'s to float around without being part of ?: exprs.
+      PP.Diag(OpLoc, diag::err_pp_colon_without_question)
+        << LHS.getRange() << RHS.getRange();
+      return true;
+    }
+
+    // If this operator is live and overflowed, report the issue.
+    if (Overflow && ValueLive)
+      PP.Diag(OpLoc, diag::warn_pp_expr_overflow)
+        << LHS.getRange() << RHS.getRange();
+
+    // Put the result back into 'LHS' for our next iteration.
+    LHS.Val = Res;
+    LHS.setEnd(RHS.getRange().getEnd());
+  }
+
+  return false;
+}
+
+/// EvaluateDirectiveExpression - Evaluate an integer constant expression that
+/// may occur after a #if or #elif directive.  If the expression is equivalent
+/// to "!defined(X)" return X in IfNDefMacro.
+bool Preprocessor::
+EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro) {
+  // Save the current state of 'DisableMacroExpansion' and reset it to false. If
+  // 'DisableMacroExpansion' is true, then we must be in a macro argument list
+  // in which case a directive is undefined behavior.  We want macros to be able
+  // to recursively expand in order to get more gcc-list behavior, so we force
+  // DisableMacroExpansion to false and restore it when we're done parsing the
+  // expression.
+  bool DisableMacroExpansionAtStartOfDirective = DisableMacroExpansion;
+  DisableMacroExpansion = false;
+  
+  // Peek ahead one token.
+  Token Tok;
+  Lex(Tok);
+
+  // C99 6.10.1p3 - All expressions are evaluated as intmax_t or uintmax_t.
+  unsigned BitWidth = getTargetInfo().getIntMaxTWidth();
+
+  PPValue ResVal(BitWidth);
+  DefinedTracker DT;
+  if (EvaluateValue(ResVal, Tok, DT, true, *this)) {
+    // Parse error, skip the rest of the macro line.
+    if (Tok.isNot(tok::eom))
+      DiscardUntilEndOfDirective();
+    
+    // Restore 'DisableMacroExpansion'.
+    DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
+    return false;
+  }
+
+  // If we are at the end of the expression after just parsing a value, there
+  // must be no (unparenthesized) binary operators involved, so we can exit
+  // directly.
+  if (Tok.is(tok::eom)) {
+    // If the expression we parsed was of the form !defined(macro), return the
+    // macro in IfNDefMacro.
+    if (DT.State == DefinedTracker::NotDefinedMacro)
+      IfNDefMacro = DT.TheMacro;
+
+    // Restore 'DisableMacroExpansion'.
+    DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
+    return ResVal.Val != 0;
+  }
+
+  // Otherwise, we must have a binary operator (e.g. "#if 1 < 2"), so parse the
+  // operator and the stuff after it.
+  if (EvaluateDirectiveSubExpr(ResVal, getPrecedence(tok::question),
+                               Tok, true, *this)) {
+    // Parse error, skip the rest of the macro line.
+    if (Tok.isNot(tok::eom))
+      DiscardUntilEndOfDirective();
+    
+    // Restore 'DisableMacroExpansion'.
+    DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
+    return false;
+  }
+
+  // If we aren't at the tok::eom token, something bad happened, like an extra
+  // ')' token.
+  if (Tok.isNot(tok::eom)) {
+    Diag(Tok, diag::err_pp_expected_eol);
+    DiscardUntilEndOfDirective();
+  }
+
+  // Restore 'DisableMacroExpansion'.
+  DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
+  return ResVal.Val != 0;
+}
+
diff --git a/lib/Lex/PPLexerChange.cpp b/lib/Lex/PPLexerChange.cpp
new file mode 100644
index 0000000..4a40405
--- /dev/null
+++ b/lib/Lex/PPLexerChange.cpp
@@ -0,0 +1,362 @@
+//===--- PPLexerChange.cpp - Handle changing lexers in the preprocessor ---===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements pieces of the Preprocessor interface that manage the
+// current lexer stack.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Lex/HeaderSearch.h"
+#include "clang/Lex/MacroInfo.h"
+#include "clang/Lex/LexDiagnostic.h"
+#include "clang/Basic/SourceManager.h"
+#include "llvm/Support/MemoryBuffer.h"
+using namespace clang;
+
+PPCallbacks::~PPCallbacks() {}
+
+//===----------------------------------------------------------------------===//
+// Miscellaneous Methods.
+//===----------------------------------------------------------------------===//
+
+/// isInPrimaryFile - Return true if we're in the top-level file, not in a
+/// #include.  This looks through macro expansions and active _Pragma lexers.
+bool Preprocessor::isInPrimaryFile() const {
+  if (IsFileLexer())
+    return IncludeMacroStack.empty();
+
+  // If there are any stacked lexers, we're in a #include.
+  assert(IsFileLexer(IncludeMacroStack[0]) &&
+         "Top level include stack isn't our primary lexer?");
+  for (unsigned i = 1, e = IncludeMacroStack.size(); i != e; ++i)
+    if (IsFileLexer(IncludeMacroStack[i]))
+      return false;
+  return true;
+}
+
+/// getCurrentLexer - Return the current file lexer being lexed from.  Note
+/// that this ignores any potentially active macro expansions and _Pragma
+/// expansions going on at the time.
+PreprocessorLexer *Preprocessor::getCurrentFileLexer() const {
+  if (IsFileLexer())
+    return CurPPLexer;
+
+  // Look for a stacked lexer.
+  for (unsigned i = IncludeMacroStack.size(); i != 0; --i) {
+    const IncludeStackInfo& ISI = IncludeMacroStack[i-1];
+    if (IsFileLexer(ISI))
+      return ISI.ThePPLexer;
+  }
+  return 0;
+}
+
+
+//===----------------------------------------------------------------------===//
+// Methods for Entering and Callbacks for leaving various contexts
+//===----------------------------------------------------------------------===//
+
+/// EnterSourceFile - Add a source file to the top of the include stack and
+/// start lexing tokens from it instead of the current buffer.
+void Preprocessor::EnterSourceFile(FileID FID, const DirectoryLookup *CurDir,
+                                   SourceLocation Loc) {
+  assert(CurTokenLexer == 0 && "Cannot #include a file inside a macro!");
+  ++NumEnteredSourceFiles;
+
+  if (MaxIncludeStackDepth < IncludeMacroStack.size())
+    MaxIncludeStackDepth = IncludeMacroStack.size();
+
+  if (PTH) {
+    if (PTHLexer *PL = PTH->CreateLexer(FID)) {
+      EnterSourceFileWithPTH(PL, CurDir);
+      return;
+    }
+  }
+  
+  // Get the MemoryBuffer for this FID, if it fails, we fail.
+  bool Invalid = false;
+  const llvm::MemoryBuffer *InputFile = 
+    getSourceManager().getBuffer(FID, Loc, &Invalid);
+  if (Invalid) {
+    SourceLocation FileStart = SourceMgr.getLocForStartOfFile(FID);
+    Diag(Loc, diag::err_pp_error_opening_file)
+      << std::string(SourceMgr.getBufferName(FileStart)) << "";
+    return;
+  }
+  
+  EnterSourceFileWithLexer(new Lexer(FID, InputFile, *this), CurDir);
+  return;
+}
+
+/// EnterSourceFileWithLexer - Add a source file to the top of the include stack
+///  and start lexing tokens from it instead of the current buffer.
+void Preprocessor::EnterSourceFileWithLexer(Lexer *TheLexer,
+                                            const DirectoryLookup *CurDir) {
+
+  // Add the current lexer to the include stack.
+  if (CurPPLexer || CurTokenLexer)
+    PushIncludeMacroStack();
+
+  CurLexer.reset(TheLexer);
+  CurPPLexer = TheLexer;
+  CurDirLookup = CurDir;
+
+  // Notify the client, if desired, that we are in a new source file.
+  if (Callbacks && !CurLexer->Is_PragmaLexer) {
+    SrcMgr::CharacteristicKind FileType =
+       SourceMgr.getFileCharacteristic(CurLexer->getFileLoc());
+
+    Callbacks->FileChanged(CurLexer->getFileLoc(),
+                           PPCallbacks::EnterFile, FileType);
+  }
+}
+
+/// EnterSourceFileWithPTH - Add a source file to the top of the include stack
+/// and start getting tokens from it using the PTH cache.
+void Preprocessor::EnterSourceFileWithPTH(PTHLexer *PL,
+                                          const DirectoryLookup *CurDir) {
+
+  if (CurPPLexer || CurTokenLexer)
+    PushIncludeMacroStack();
+
+  CurDirLookup = CurDir;
+  CurPTHLexer.reset(PL);
+  CurPPLexer = CurPTHLexer.get();
+
+  // Notify the client, if desired, that we are in a new source file.
+  if (Callbacks) {
+    FileID FID = CurPPLexer->getFileID();
+    SourceLocation EnterLoc = SourceMgr.getLocForStartOfFile(FID);
+    SrcMgr::CharacteristicKind FileType =
+      SourceMgr.getFileCharacteristic(EnterLoc);
+    Callbacks->FileChanged(EnterLoc, PPCallbacks::EnterFile, FileType);
+  }
+}
+
+/// EnterMacro - Add a Macro to the top of the include stack and start lexing
+/// tokens from it instead of the current buffer.
+void Preprocessor::EnterMacro(Token &Tok, SourceLocation ILEnd,
+                              MacroArgs *Args) {
+  PushIncludeMacroStack();
+  CurDirLookup = 0;
+
+  if (NumCachedTokenLexers == 0) {
+    CurTokenLexer.reset(new TokenLexer(Tok, ILEnd, Args, *this));
+  } else {
+    CurTokenLexer.reset(TokenLexerCache[--NumCachedTokenLexers]);
+    CurTokenLexer->Init(Tok, ILEnd, Args);
+  }
+}
+
+/// EnterTokenStream - Add a "macro" context to the top of the include stack,
+/// which will cause the lexer to start returning the specified tokens.
+///
+/// If DisableMacroExpansion is true, tokens lexed from the token stream will
+/// not be subject to further macro expansion.  Otherwise, these tokens will
+/// be re-macro-expanded when/if expansion is enabled.
+///
+/// If OwnsTokens is false, this method assumes that the specified stream of
+/// tokens has a permanent owner somewhere, so they do not need to be copied.
+/// If it is true, it assumes the array of tokens is allocated with new[] and
+/// must be freed.
+///
+void Preprocessor::EnterTokenStream(const Token *Toks, unsigned NumToks,
+                                    bool DisableMacroExpansion,
+                                    bool OwnsTokens) {
+  // Save our current state.
+  PushIncludeMacroStack();
+  CurDirLookup = 0;
+
+  // Create a macro expander to expand from the specified token stream.
+  if (NumCachedTokenLexers == 0) {
+    CurTokenLexer.reset(new TokenLexer(Toks, NumToks, DisableMacroExpansion,
+                                       OwnsTokens, *this));
+  } else {
+    CurTokenLexer.reset(TokenLexerCache[--NumCachedTokenLexers]);
+    CurTokenLexer->Init(Toks, NumToks, DisableMacroExpansion, OwnsTokens);
+  }
+}
+
+/// HandleEndOfFile - This callback is invoked when the lexer hits the end of
+/// the current file.  This either returns the EOF token or pops a level off
+/// the include stack and keeps going.
+bool Preprocessor::HandleEndOfFile(Token &Result, bool isEndOfMacro) {
+  assert(!CurTokenLexer &&
+         "Ending a file when currently in a macro!");
+
+  // See if this file had a controlling macro.
+  if (CurPPLexer) {  // Not ending a macro, ignore it.
+    if (const IdentifierInfo *ControllingMacro =
+          CurPPLexer->MIOpt.GetControllingMacroAtEndOfFile()) {
+      // Okay, this has a controlling macro, remember in HeaderFileInfo.
+      if (const FileEntry *FE =
+            SourceMgr.getFileEntryForID(CurPPLexer->getFileID()))
+        HeaderInfo.SetFileControllingMacro(FE, ControllingMacro);
+    }
+  }
+
+  // If this is a #include'd file, pop it off the include stack and continue
+  // lexing the #includer file.
+  if (!IncludeMacroStack.empty()) {
+    // We're done with the #included file.
+    RemoveTopOfLexerStack();
+
+    // Notify the client, if desired, that we are in a new source file.
+    if (Callbacks && !isEndOfMacro && CurPPLexer) {
+      SrcMgr::CharacteristicKind FileType =
+        SourceMgr.getFileCharacteristic(CurPPLexer->getSourceLocation());
+      Callbacks->FileChanged(CurPPLexer->getSourceLocation(),
+                             PPCallbacks::ExitFile, FileType);
+    }
+
+    // Client should lex another token.
+    return false;
+  }
+
+  // If the file ends with a newline, form the EOF token on the newline itself,
+  // rather than "on the line following it", which doesn't exist.  This makes
+  // diagnostics relating to the end of file include the last file that the user
+  // actually typed, which is goodness.
+  if (CurLexer) {
+    const char *EndPos = CurLexer->BufferEnd;
+    if (EndPos != CurLexer->BufferStart &&
+        (EndPos[-1] == '\n' || EndPos[-1] == '\r')) {
+      --EndPos;
+
+      // Handle \n\r and \r\n:
+      if (EndPos != CurLexer->BufferStart &&
+          (EndPos[-1] == '\n' || EndPos[-1] == '\r') &&
+          EndPos[-1] != EndPos[0])
+        --EndPos;
+    }
+
+    Result.startToken();
+    CurLexer->BufferPtr = EndPos;
+    CurLexer->FormTokenWithChars(Result, EndPos, tok::eof);
+
+    // We're done with the #included file.
+    CurLexer.reset();
+  } else {
+    assert(CurPTHLexer && "Got EOF but no current lexer set!");
+    CurPTHLexer->getEOF(Result);
+    CurPTHLexer.reset();
+  }
+
+  CurPPLexer = 0;
+
+  // This is the end of the top-level file.  If the diag::pp_macro_not_used
+  // diagnostic is enabled, look for macros that have not been used.
+  if (getDiagnostics().getDiagnosticLevel(diag::pp_macro_not_used) !=
+        Diagnostic::Ignored) {
+    for (macro_iterator I = macro_begin(false), E = macro_end(false); 
+         I != E; ++I)
+      if (!I->second->isUsed())
+        Diag(I->second->getDefinitionLoc(), diag::pp_macro_not_used);
+  }
+
+  return true;
+}
+
+/// HandleEndOfTokenLexer - This callback is invoked when the current TokenLexer
+/// hits the end of its token stream.
+bool Preprocessor::HandleEndOfTokenLexer(Token &Result) {
+  assert(CurTokenLexer && !CurPPLexer &&
+         "Ending a macro when currently in a #include file!");
+
+  // Delete or cache the now-dead macro expander.
+  if (NumCachedTokenLexers == TokenLexerCacheSize)
+    CurTokenLexer.reset();
+  else
+    TokenLexerCache[NumCachedTokenLexers++] = CurTokenLexer.take();
+
+  // Handle this like a #include file being popped off the stack.
+  return HandleEndOfFile(Result, true);
+}
+
+/// RemoveTopOfLexerStack - Pop the current lexer/macro exp off the top of the
+/// lexer stack.  This should only be used in situations where the current
+/// state of the top-of-stack lexer is unknown.
+void Preprocessor::RemoveTopOfLexerStack() {
+  assert(!IncludeMacroStack.empty() && "Ran out of stack entries to load");
+
+  if (CurTokenLexer) {
+    // Delete or cache the now-dead macro expander.
+    if (NumCachedTokenLexers == TokenLexerCacheSize)
+      CurTokenLexer.reset();
+    else
+      TokenLexerCache[NumCachedTokenLexers++] = CurTokenLexer.take();
+  }
+
+  PopIncludeMacroStack();
+}
+
+/// HandleMicrosoftCommentPaste - When the macro expander pastes together a
+/// comment (/##/) in microsoft mode, this method handles updating the current
+/// state, returning the token on the next source line.
+void Preprocessor::HandleMicrosoftCommentPaste(Token &Tok) {
+  assert(CurTokenLexer && !CurPPLexer &&
+         "Pasted comment can only be formed from macro");
+
+  // We handle this by scanning for the closest real lexer, switching it to
+  // raw mode and preprocessor mode.  This will cause it to return \n as an
+  // explicit EOM token.
+  PreprocessorLexer *FoundLexer = 0;
+  bool LexerWasInPPMode = false;
+  for (unsigned i = 0, e = IncludeMacroStack.size(); i != e; ++i) {
+    IncludeStackInfo &ISI = *(IncludeMacroStack.end()-i-1);
+    if (ISI.ThePPLexer == 0) continue;  // Scan for a real lexer.
+
+    // Once we find a real lexer, mark it as raw mode (disabling macro
+    // expansions) and preprocessor mode (return EOM).  We know that the lexer
+    // was *not* in raw mode before, because the macro that the comment came
+    // from was expanded.  However, it could have already been in preprocessor
+    // mode (#if COMMENT) in which case we have to return it to that mode and
+    // return EOM.
+    FoundLexer = ISI.ThePPLexer;
+    FoundLexer->LexingRawMode = true;
+    LexerWasInPPMode = FoundLexer->ParsingPreprocessorDirective;
+    FoundLexer->ParsingPreprocessorDirective = true;
+    break;
+  }
+
+  // Okay, we either found and switched over the lexer, or we didn't find a
+  // lexer.  In either case, finish off the macro the comment came from, getting
+  // the next token.
+  if (!HandleEndOfTokenLexer(Tok)) Lex(Tok);
+
+  // Discarding comments as long as we don't have EOF or EOM.  This 'comments
+  // out' the rest of the line, including any tokens that came from other macros
+  // that were active, as in:
+  //  #define submacro a COMMENT b
+  //    submacro c
+  // which should lex to 'a' only: 'b' and 'c' should be removed.
+  while (Tok.isNot(tok::eom) && Tok.isNot(tok::eof))
+    Lex(Tok);
+
+  // If we got an eom token, then we successfully found the end of the line.
+  if (Tok.is(tok::eom)) {
+    assert(FoundLexer && "Can't get end of line without an active lexer");
+    // Restore the lexer back to normal mode instead of raw mode.
+    FoundLexer->LexingRawMode = false;
+
+    // If the lexer was already in preprocessor mode, just return the EOM token
+    // to finish the preprocessor line.
+    if (LexerWasInPPMode) return;
+
+    // Otherwise, switch out of PP mode and return the next lexed token.
+    FoundLexer->ParsingPreprocessorDirective = false;
+    return Lex(Tok);
+  }
+
+  // If we got an EOF token, then we reached the end of the token stream but
+  // didn't find an explicit \n.  This can only happen if there was no lexer
+  // active (an active lexer would return EOM at EOF if there was no \n in
+  // preprocessor directive mode), so just return EOF as our token.
+  assert(!FoundLexer && "Lexer should return EOM before EOF in PP mode");
+}
diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp
new file mode 100644
index 0000000..1c6a5ad
--- /dev/null
+++ b/lib/Lex/PPMacroExpansion.cpp
@@ -0,0 +1,797 @@
+//===--- MacroExpansion.cpp - Top level Macro Expansion -------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the top level handling of macro expasion for the
+// preprocessor.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Lex/Preprocessor.h"
+#include "MacroArgs.h"
+#include "clang/Lex/MacroInfo.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Lex/LexDiagnostic.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cstdio>
+#include <ctime>
+using namespace clang;
+
+/// setMacroInfo - Specify a macro for this identifier.
+///
+void Preprocessor::setMacroInfo(IdentifierInfo *II, MacroInfo *MI) {
+  if (MI) {
+    Macros[II] = MI;
+    II->setHasMacroDefinition(true);
+  } else if (II->hasMacroDefinition()) {
+    Macros.erase(II);
+    II->setHasMacroDefinition(false);
+  }
+}
+
+/// RegisterBuiltinMacro - Register the specified identifier in the identifier
+/// table and mark it as a builtin macro to be expanded.
+static IdentifierInfo *RegisterBuiltinMacro(Preprocessor &PP, const char *Name){
+  // Get the identifier.
+  IdentifierInfo *Id = PP.getIdentifierInfo(Name);
+
+  // Mark it as being a macro that is builtin.
+  MacroInfo *MI = PP.AllocateMacroInfo(SourceLocation());
+  MI->setIsBuiltinMacro();
+  PP.setMacroInfo(Id, MI);
+  return Id;
+}
+
+
+/// RegisterBuiltinMacros - Register builtin macros, such as __LINE__ with the
+/// identifier table.
+void Preprocessor::RegisterBuiltinMacros() {
+  Ident__LINE__ = RegisterBuiltinMacro(*this, "__LINE__");
+  Ident__FILE__ = RegisterBuiltinMacro(*this, "__FILE__");
+  Ident__DATE__ = RegisterBuiltinMacro(*this, "__DATE__");
+  Ident__TIME__ = RegisterBuiltinMacro(*this, "__TIME__");
+  Ident__COUNTER__ = RegisterBuiltinMacro(*this, "__COUNTER__");
+  Ident_Pragma  = RegisterBuiltinMacro(*this, "_Pragma");
+
+  // GCC Extensions.
+  Ident__BASE_FILE__     = RegisterBuiltinMacro(*this, "__BASE_FILE__");
+  Ident__INCLUDE_LEVEL__ = RegisterBuiltinMacro(*this, "__INCLUDE_LEVEL__");
+  Ident__TIMESTAMP__     = RegisterBuiltinMacro(*this, "__TIMESTAMP__");
+
+  // Clang Extensions.
+  Ident__has_feature      = RegisterBuiltinMacro(*this, "__has_feature");
+  Ident__has_builtin      = RegisterBuiltinMacro(*this, "__has_builtin");
+  Ident__has_include      = RegisterBuiltinMacro(*this, "__has_include");
+  Ident__has_include_next = RegisterBuiltinMacro(*this, "__has_include_next");
+}
+
+/// isTrivialSingleTokenExpansion - Return true if MI, which has a single token
+/// in its expansion, currently expands to that token literally.
+static bool isTrivialSingleTokenExpansion(const MacroInfo *MI,
+                                          const IdentifierInfo *MacroIdent,
+                                          Preprocessor &PP) {
+  IdentifierInfo *II = MI->getReplacementToken(0).getIdentifierInfo();
+
+  // If the token isn't an identifier, it's always literally expanded.
+  if (II == 0) return true;
+
+  // If the identifier is a macro, and if that macro is enabled, it may be
+  // expanded so it's not a trivial expansion.
+  if (II->hasMacroDefinition() && PP.getMacroInfo(II)->isEnabled() &&
+      // Fast expanding "#define X X" is ok, because X would be disabled.
+      II != MacroIdent)
+    return false;
+
+  // If this is an object-like macro invocation, it is safe to trivially expand
+  // it.
+  if (MI->isObjectLike()) return true;
+
+  // If this is a function-like macro invocation, it's safe to trivially expand
+  // as long as the identifier is not a macro argument.
+  for (MacroInfo::arg_iterator I = MI->arg_begin(), E = MI->arg_end();
+       I != E; ++I)
+    if (*I == II)
+      return false;   // Identifier is a macro argument.
+
+  return true;
+}
+
+
+/// isNextPPTokenLParen - Determine whether the next preprocessor token to be
+/// lexed is a '('.  If so, consume the token and return true, if not, this
+/// method should have no observable side-effect on the lexed tokens.
+bool Preprocessor::isNextPPTokenLParen() {
+  // Do some quick tests for rejection cases.
+  unsigned Val;
+  if (CurLexer)
+    Val = CurLexer->isNextPPTokenLParen();
+  else if (CurPTHLexer)
+    Val = CurPTHLexer->isNextPPTokenLParen();
+  else
+    Val = CurTokenLexer->isNextTokenLParen();
+
+  if (Val == 2) {
+    // We have run off the end.  If it's a source file we don't
+    // examine enclosing ones (C99 5.1.1.2p4).  Otherwise walk up the
+    // macro stack.
+    if (CurPPLexer)
+      return false;
+    for (unsigned i = IncludeMacroStack.size(); i != 0; --i) {
+      IncludeStackInfo &Entry = IncludeMacroStack[i-1];
+      if (Entry.TheLexer)
+        Val = Entry.TheLexer->isNextPPTokenLParen();
+      else if (Entry.ThePTHLexer)
+        Val = Entry.ThePTHLexer->isNextPPTokenLParen();
+      else
+        Val = Entry.TheTokenLexer->isNextTokenLParen();
+
+      if (Val != 2)
+        break;
+
+      // Ran off the end of a source file?
+      if (Entry.ThePPLexer)
+        return false;
+    }
+  }
+
+  // Okay, if we know that the token is a '(', lex it and return.  Otherwise we
+  // have found something that isn't a '(' or we found the end of the
+  // translation unit.  In either case, return false.
+  return Val == 1;
+}
+
+/// HandleMacroExpandedIdentifier - If an identifier token is read that is to be
+/// expanded as a macro, handle it and return the next token as 'Identifier'.
+bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier,
+                                                 MacroInfo *MI) {
+  if (Callbacks) Callbacks->MacroExpands(Identifier, MI);
+
+  // If this is a macro expansion in the "#if !defined(x)" line for the file,
+  // then the macro could expand to different things in other contexts, we need
+  // to disable the optimization in this case.
+  if (CurPPLexer) CurPPLexer->MIOpt.ExpandedMacro();
+
+  // If this is a builtin macro, like __LINE__ or _Pragma, handle it specially.
+  if (MI->isBuiltinMacro()) {
+    ExpandBuiltinMacro(Identifier);
+    return false;
+  }
+
+  /// Args - If this is a function-like macro expansion, this contains,
+  /// for each macro argument, the list of tokens that were provided to the
+  /// invocation.
+  MacroArgs *Args = 0;
+
+  // Remember where the end of the instantiation occurred.  For an object-like
+  // macro, this is the identifier.  For a function-like macro, this is the ')'.
+  SourceLocation InstantiationEnd = Identifier.getLocation();
+
+  // If this is a function-like macro, read the arguments.
+  if (MI->isFunctionLike()) {
+    // C99 6.10.3p10: If the preprocessing token immediately after the the macro
+    // name isn't a '(', this macro should not be expanded.
+    if (!isNextPPTokenLParen())
+      return true;
+
+    // Remember that we are now parsing the arguments to a macro invocation.
+    // Preprocessor directives used inside macro arguments are not portable, and
+    // this enables the warning.
+    InMacroArgs = true;
+    Args = ReadFunctionLikeMacroArgs(Identifier, MI, InstantiationEnd);
+
+    // Finished parsing args.
+    InMacroArgs = false;
+
+    // If there was an error parsing the arguments, bail out.
+    if (Args == 0) return false;
+
+    ++NumFnMacroExpanded;
+  } else {
+    ++NumMacroExpanded;
+  }
+
+  // Notice that this macro has been used.
+  MI->setIsUsed(true);
+
+  // If we started lexing a macro, enter the macro expansion body.
+
+  // If this macro expands to no tokens, don't bother to push it onto the
+  // expansion stack, only to take it right back off.
+  if (MI->getNumTokens() == 0) {
+    // No need for arg info.
+    if (Args) Args->destroy(*this);
+
+    // Ignore this macro use, just return the next token in the current
+    // buffer.
+    bool HadLeadingSpace = Identifier.hasLeadingSpace();
+    bool IsAtStartOfLine = Identifier.isAtStartOfLine();
+
+    Lex(Identifier);
+
+    // If the identifier isn't on some OTHER line, inherit the leading
+    // whitespace/first-on-a-line property of this token.  This handles
+    // stuff like "! XX," -> "! ," and "   XX," -> "    ,", when XX is
+    // empty.
+    if (!Identifier.isAtStartOfLine()) {
+      if (IsAtStartOfLine) Identifier.setFlag(Token::StartOfLine);
+      if (HadLeadingSpace) Identifier.setFlag(Token::LeadingSpace);
+    }
+    ++NumFastMacroExpanded;
+    return false;
+
+  } else if (MI->getNumTokens() == 1 &&
+             isTrivialSingleTokenExpansion(MI, Identifier.getIdentifierInfo(),
+                                           *this)) {
+    // Otherwise, if this macro expands into a single trivially-expanded
+    // token: expand it now.  This handles common cases like
+    // "#define VAL 42".
+
+    // No need for arg info.
+    if (Args) Args->destroy(*this);
+
+    // Propagate the isAtStartOfLine/hasLeadingSpace markers of the macro
+    // identifier to the expanded token.
+    bool isAtStartOfLine = Identifier.isAtStartOfLine();
+    bool hasLeadingSpace = Identifier.hasLeadingSpace();
+
+    // Remember where the token is instantiated.
+    SourceLocation InstantiateLoc = Identifier.getLocation();
+
+    // Replace the result token.
+    Identifier = MI->getReplacementToken(0);
+
+    // Restore the StartOfLine/LeadingSpace markers.
+    Identifier.setFlagValue(Token::StartOfLine , isAtStartOfLine);
+    Identifier.setFlagValue(Token::LeadingSpace, hasLeadingSpace);
+
+    // Update the tokens location to include both its instantiation and physical
+    // locations.
+    SourceLocation Loc =
+      SourceMgr.createInstantiationLoc(Identifier.getLocation(), InstantiateLoc,
+                                       InstantiationEnd,Identifier.getLength());
+    Identifier.setLocation(Loc);
+
+    // If this is a disabled macro or #define X X, we must mark the result as
+    // unexpandable.
+    if (IdentifierInfo *NewII = Identifier.getIdentifierInfo()) {
+      if (MacroInfo *NewMI = getMacroInfo(NewII))
+        if (!NewMI->isEnabled() || NewMI == MI)
+          Identifier.setFlag(Token::DisableExpand);
+    }
+
+    // Since this is not an identifier token, it can't be macro expanded, so
+    // we're done.
+    ++NumFastMacroExpanded;
+    return false;
+  }
+
+  // Start expanding the macro.
+  EnterMacro(Identifier, InstantiationEnd, Args);
+
+  // Now that the macro is at the top of the include stack, ask the
+  // preprocessor to read the next token from it.
+  Lex(Identifier);
+  return false;
+}
+
+/// ReadFunctionLikeMacroArgs - After reading "MACRO" and knowing that the next
+/// token is the '(' of the macro, this method is invoked to read all of the
+/// actual arguments specified for the macro invocation.  This returns null on
+/// error.
+MacroArgs *Preprocessor::ReadFunctionLikeMacroArgs(Token &MacroName,
+                                                   MacroInfo *MI,
+                                                   SourceLocation &MacroEnd) {
+  // The number of fixed arguments to parse.
+  unsigned NumFixedArgsLeft = MI->getNumArgs();
+  bool isVariadic = MI->isVariadic();
+
+  // Outer loop, while there are more arguments, keep reading them.
+  Token Tok;
+
+  // Read arguments as unexpanded tokens.  This avoids issues, e.g., where
+  // an argument value in a macro could expand to ',' or '(' or ')'.
+  LexUnexpandedToken(Tok);
+  assert(Tok.is(tok::l_paren) && "Error computing l-paren-ness?");
+
+  // ArgTokens - Build up a list of tokens that make up each argument.  Each
+  // argument is separated by an EOF token.  Use a SmallVector so we can avoid
+  // heap allocations in the common case.
+  llvm::SmallVector<Token, 64> ArgTokens;
+
+  unsigned NumActuals = 0;
+  while (Tok.isNot(tok::r_paren)) {
+    assert((Tok.is(tok::l_paren) || Tok.is(tok::comma)) &&
+           "only expect argument separators here");
+
+    unsigned ArgTokenStart = ArgTokens.size();
+    SourceLocation ArgStartLoc = Tok.getLocation();
+
+    // C99 6.10.3p11: Keep track of the number of l_parens we have seen.  Note
+    // that we already consumed the first one.
+    unsigned NumParens = 0;
+
+    while (1) {
+      // Read arguments as unexpanded tokens.  This avoids issues, e.g., where
+      // an argument value in a macro could expand to ',' or '(' or ')'.
+      LexUnexpandedToken(Tok);
+
+      if (Tok.is(tok::eof) || Tok.is(tok::eom)) { // "#if f(<eof>" & "#if f(\n"
+        Diag(MacroName, diag::err_unterm_macro_invoc);
+        // Do not lose the EOF/EOM.  Return it to the client.
+        MacroName = Tok;
+        return 0;
+      } else if (Tok.is(tok::r_paren)) {
+        // If we found the ) token, the macro arg list is done.
+        if (NumParens-- == 0) {
+          MacroEnd = Tok.getLocation();
+          break;
+        }
+      } else if (Tok.is(tok::l_paren)) {
+        ++NumParens;
+      } else if (Tok.is(tok::comma) && NumParens == 0) {
+        // Comma ends this argument if there are more fixed arguments expected.
+        // However, if this is a variadic macro, and this is part of the
+        // variadic part, then the comma is just an argument token.
+        if (!isVariadic) break;
+        if (NumFixedArgsLeft > 1)
+          break;
+      } else if (Tok.is(tok::comment) && !KeepMacroComments) {
+        // If this is a comment token in the argument list and we're just in
+        // -C mode (not -CC mode), discard the comment.
+        continue;
+      } else if (Tok.getIdentifierInfo() != 0) {
+        // Reading macro arguments can cause macros that we are currently
+        // expanding from to be popped off the expansion stack.  Doing so causes
+        // them to be reenabled for expansion.  Here we record whether any
+        // identifiers we lex as macro arguments correspond to disabled macros.
+        // If so, we mark the token as noexpand.  This is a subtle aspect of
+        // C99 6.10.3.4p2.
+        if (MacroInfo *MI = getMacroInfo(Tok.getIdentifierInfo()))
+          if (!MI->isEnabled())
+            Tok.setFlag(Token::DisableExpand);
+      }
+      ArgTokens.push_back(Tok);
+    }
+
+    // If this was an empty argument list foo(), don't add this as an empty
+    // argument.
+    if (ArgTokens.empty() && Tok.getKind() == tok::r_paren)
+      break;
+
+    // If this is not a variadic macro, and too many args were specified, emit
+    // an error.
+    if (!isVariadic && NumFixedArgsLeft == 0) {
+      if (ArgTokens.size() != ArgTokenStart)
+        ArgStartLoc = ArgTokens[ArgTokenStart].getLocation();
+
+      // Emit the diagnostic at the macro name in case there is a missing ).
+      // Emitting it at the , could be far away from the macro name.
+      Diag(ArgStartLoc, diag::err_too_many_args_in_macro_invoc);
+      return 0;
+    }
+
+    // Empty arguments are standard in C99 and supported as an extension in
+    // other modes.
+    if (ArgTokens.size() == ArgTokenStart && !Features.C99)
+      Diag(Tok, diag::ext_empty_fnmacro_arg);
+
+    // Add a marker EOF token to the end of the token list for this argument.
+    Token EOFTok;
+    EOFTok.startToken();
+    EOFTok.setKind(tok::eof);
+    EOFTok.setLocation(Tok.getLocation());
+    EOFTok.setLength(0);
+    ArgTokens.push_back(EOFTok);
+    ++NumActuals;
+    assert(NumFixedArgsLeft != 0 && "Too many arguments parsed");
+    --NumFixedArgsLeft;
+  }
+
+  // Okay, we either found the r_paren.  Check to see if we parsed too few
+  // arguments.
+  unsigned MinArgsExpected = MI->getNumArgs();
+
+  // See MacroArgs instance var for description of this.
+  bool isVarargsElided = false;
+
+  if (NumActuals < MinArgsExpected) {
+    // There are several cases where too few arguments is ok, handle them now.
+    if (NumActuals == 0 && MinArgsExpected == 1) {
+      // #define A(X)  or  #define A(...)   ---> A()
+
+      // If there is exactly one argument, and that argument is missing,
+      // then we have an empty "()" argument empty list.  This is fine, even if
+      // the macro expects one argument (the argument is just empty).
+      isVarargsElided = MI->isVariadic();
+    } else if (MI->isVariadic() &&
+               (NumActuals+1 == MinArgsExpected ||  // A(x, ...) -> A(X)
+                (NumActuals == 0 && MinArgsExpected == 2))) {// A(x,...) -> A()
+      // Varargs where the named vararg parameter is missing: ok as extension.
+      // #define A(x, ...)
+      // A("blah")
+      Diag(Tok, diag::ext_missing_varargs_arg);
+
+      // Remember this occurred, allowing us to elide the comma when used for
+      // cases like:
+      //   #define A(x, foo...) blah(a, ## foo)
+      //   #define B(x, ...) blah(a, ## __VA_ARGS__)
+      //   #define C(...) blah(a, ## __VA_ARGS__)
+      //  A(x) B(x) C()
+      isVarargsElided = true;
+    } else {
+      // Otherwise, emit the error.
+      Diag(Tok, diag::err_too_few_args_in_macro_invoc);
+      return 0;
+    }
+
+    // Add a marker EOF token to the end of the token list for this argument.
+    SourceLocation EndLoc = Tok.getLocation();
+    Tok.startToken();
+    Tok.setKind(tok::eof);
+    Tok.setLocation(EndLoc);
+    Tok.setLength(0);
+    ArgTokens.push_back(Tok);
+
+    // If we expect two arguments, add both as empty.
+    if (NumActuals == 0 && MinArgsExpected == 2)
+      ArgTokens.push_back(Tok);
+
+  } else if (NumActuals > MinArgsExpected && !MI->isVariadic()) {
+    // Emit the diagnostic at the macro name in case there is a missing ).
+    // Emitting it at the , could be far away from the macro name.
+    Diag(MacroName, diag::err_too_many_args_in_macro_invoc);
+    return 0;
+  }
+
+  return MacroArgs::create(MI, ArgTokens.data(), ArgTokens.size(),
+                           isVarargsElided, *this);
+}
+
+/// ComputeDATE_TIME - Compute the current time, enter it into the specified
+/// scratch buffer, then return DATELoc/TIMELoc locations with the position of
+/// the identifier tokens inserted.
+static void ComputeDATE_TIME(SourceLocation &DATELoc, SourceLocation &TIMELoc,
+                             Preprocessor &PP) {
+  time_t TT = time(0);
+  struct tm *TM = localtime(&TT);
+
+  static const char * const Months[] = {
+    "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"
+  };
+
+  char TmpBuffer[100];
+  sprintf(TmpBuffer, "\"%s %2d %4d\"", Months[TM->tm_mon], TM->tm_mday,
+          TM->tm_year+1900);
+
+  Token TmpTok;
+  TmpTok.startToken();
+  PP.CreateString(TmpBuffer, strlen(TmpBuffer), TmpTok);
+  DATELoc = TmpTok.getLocation();
+
+  sprintf(TmpBuffer, "\"%02d:%02d:%02d\"", TM->tm_hour, TM->tm_min, TM->tm_sec);
+  PP.CreateString(TmpBuffer, strlen(TmpBuffer), TmpTok);
+  TIMELoc = TmpTok.getLocation();
+}
+
+
+/// HasFeature - Return true if we recognize and implement the specified feature
+/// specified by the identifier.
+static bool HasFeature(const Preprocessor &PP, const IdentifierInfo *II) {
+  const LangOptions &LangOpts = PP.getLangOptions();
+
+  return llvm::StringSwitch<bool>(II->getName())
+           .Case("blocks", LangOpts.Blocks)
+           .Case("cxx_rtti", LangOpts.RTTI)
+         //.Case("cxx_lambdas", false)
+         //.Case("cxx_nullptr", false)
+         //.Case("cxx_concepts", false)
+           .Case("cxx_decltype", LangOpts.CPlusPlus0x)
+           .Case("cxx_auto_type", LangOpts.CPlusPlus0x)
+           .Case("cxx_exceptions", LangOpts.Exceptions)
+           .Case("cxx_attributes", LangOpts.CPlusPlus0x)
+           .Case("cxx_static_assert", LangOpts.CPlusPlus0x)
+           .Case("objc_nonfragile_abi", LangOpts.ObjCNonFragileABI)
+           .Case("cxx_deleted_functions", LangOpts.CPlusPlus0x)
+         //.Case("cxx_rvalue_references", false)
+           .Case("attribute_overloadable", true)
+         //.Case("cxx_variadic_templates", false)
+           .Case("attribute_ext_vector_type", true)
+           .Case("attribute_analyzer_noreturn", true)
+           .Case("attribute_cf_returns_not_retained", true)
+           .Case("attribute_cf_returns_retained", true)
+           .Case("attribute_ns_returns_not_retained", true)
+           .Case("attribute_ns_returns_retained", true)
+           .Case("attribute_objc_ivar_unused", true)
+           .Default(false);
+}
+
+/// EvaluateHasIncludeCommon - Process a '__has_include("path")'
+/// or '__has_include_next("path")' expression.
+/// Returns true if successful.
+static bool EvaluateHasIncludeCommon(bool &Result, Token &Tok,
+        IdentifierInfo *II, Preprocessor &PP,
+        const DirectoryLookup *LookupFrom) {
+  SourceLocation LParenLoc;
+
+  // Get '('.
+  PP.LexNonComment(Tok);
+
+  // Ensure we have a '('.
+  if (Tok.isNot(tok::l_paren)) {
+    PP.Diag(Tok.getLocation(), diag::err_pp_missing_lparen) << II->getName();
+    return false;
+  }
+
+  // Save '(' location for possible missing ')' message.
+  LParenLoc = Tok.getLocation();
+
+  // Get the file name.
+  PP.getCurrentLexer()->LexIncludeFilename(Tok);
+
+  // Reserve a buffer to get the spelling.
+  llvm::SmallString<128> FilenameBuffer;
+  llvm::StringRef Filename;
+
+  switch (Tok.getKind()) {
+  case tok::eom:
+    // If the token kind is EOM, the error has already been diagnosed.
+    return false;
+
+  case tok::angle_string_literal:
+  case tok::string_literal: {
+    bool Invalid = false;
+    Filename = PP.getSpelling(Tok, FilenameBuffer, &Invalid);
+    if (Invalid)
+      return false;
+    break;
+  }
+
+  case tok::less:
+    // This could be a <foo/bar.h> file coming from a macro expansion.  In this
+    // case, glue the tokens together into FilenameBuffer and interpret those.
+    FilenameBuffer.push_back('<');
+    if (PP.ConcatenateIncludeName(FilenameBuffer))
+      return false;   // Found <eom> but no ">"?  Diagnostic already emitted.
+    Filename = FilenameBuffer.str();
+    break;
+  default:
+    PP.Diag(Tok.getLocation(), diag::err_pp_expects_filename);
+    return false;
+  }
+
+  bool isAngled = PP.GetIncludeFilenameSpelling(Tok.getLocation(), Filename);
+  // If GetIncludeFilenameSpelling set the start ptr to null, there was an
+  // error.
+  if (Filename.empty())
+    return false;
+
+  // Search include directories.
+  const DirectoryLookup *CurDir;
+  const FileEntry *File = PP.LookupFile(Filename, isAngled, LookupFrom, CurDir);
+
+  // Get the result value.  Result = true means the file exists.
+  Result = File != 0;
+
+  // Get ')'.
+  PP.LexNonComment(Tok);
+
+  // Ensure we have a trailing ).
+  if (Tok.isNot(tok::r_paren)) {
+    PP.Diag(Tok.getLocation(), diag::err_pp_missing_rparen) << II->getName();
+    PP.Diag(LParenLoc, diag::note_matching) << "(";
+    return false;
+  }
+
+  return true;
+}
+
+/// EvaluateHasInclude - Process a '__has_include("path")' expression.
+/// Returns true if successful.
+static bool EvaluateHasInclude(bool &Result, Token &Tok, IdentifierInfo *II,
+                               Preprocessor &PP) {
+  return(EvaluateHasIncludeCommon(Result, Tok, II, PP, NULL));
+}
+
+/// EvaluateHasIncludeNext - Process '__has_include_next("path")' expression.
+/// Returns true if successful.
+static bool EvaluateHasIncludeNext(bool &Result, Token &Tok,
+                                   IdentifierInfo *II, Preprocessor &PP) {
+  // __has_include_next is like __has_include, except that we start
+  // searching after the current found directory.  If we can't do this,
+  // issue a diagnostic.
+  const DirectoryLookup *Lookup = PP.GetCurDirLookup();
+  if (PP.isInPrimaryFile()) {
+    Lookup = 0;
+    PP.Diag(Tok, diag::pp_include_next_in_primary);
+  } else if (Lookup == 0) {
+    PP.Diag(Tok, diag::pp_include_next_absolute_path);
+  } else {
+    // Start looking up in the next directory.
+    ++Lookup;
+  }
+
+  return(EvaluateHasIncludeCommon(Result, Tok, II, PP, Lookup));
+}
+
+/// ExpandBuiltinMacro - If an identifier token is read that is to be expanded
+/// as a builtin macro, handle it and return the next token as 'Tok'.
+void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
+  // Figure out which token this is.
+  IdentifierInfo *II = Tok.getIdentifierInfo();
+  assert(II && "Can't be a macro without id info!");
+
+  // If this is an _Pragma directive, expand it, invoke the pragma handler, then
+  // lex the token after it.
+  if (II == Ident_Pragma)
+    return Handle_Pragma(Tok);
+
+  ++NumBuiltinMacroExpanded;
+
+  llvm::SmallString<128> TmpBuffer;
+  llvm::raw_svector_ostream OS(TmpBuffer);
+
+  // Set up the return result.
+  Tok.setIdentifierInfo(0);
+  Tok.clearFlag(Token::NeedsCleaning);
+
+  if (II == Ident__LINE__) {
+    // C99 6.10.8: "__LINE__: The presumed line number (within the current
+    // source file) of the current source line (an integer constant)".  This can
+    // be affected by #line.
+    SourceLocation Loc = Tok.getLocation();
+
+    // Advance to the location of the first _, this might not be the first byte
+    // of the token if it starts with an escaped newline.
+    Loc = AdvanceToTokenCharacter(Loc, 0);
+
+    // One wrinkle here is that GCC expands __LINE__ to location of the *end* of
+    // a macro instantiation.  This doesn't matter for object-like macros, but
+    // can matter for a function-like macro that expands to contain __LINE__.
+    // Skip down through instantiation points until we find a file loc for the
+    // end of the instantiation history.
+    Loc = SourceMgr.getInstantiationRange(Loc).second;
+    PresumedLoc PLoc = SourceMgr.getPresumedLoc(Loc);
+
+    // __LINE__ expands to a simple numeric value.
+    OS << PLoc.getLine();
+    Tok.setKind(tok::numeric_constant);
+  } else if (II == Ident__FILE__ || II == Ident__BASE_FILE__) {
+    // C99 6.10.8: "__FILE__: The presumed name of the current source file (a
+    // character string literal)". This can be affected by #line.
+    PresumedLoc PLoc = SourceMgr.getPresumedLoc(Tok.getLocation());
+
+    // __BASE_FILE__ is a GNU extension that returns the top of the presumed
+    // #include stack instead of the current file.
+    if (II == Ident__BASE_FILE__) {
+      SourceLocation NextLoc = PLoc.getIncludeLoc();
+      while (NextLoc.isValid()) {
+        PLoc = SourceMgr.getPresumedLoc(NextLoc);
+        NextLoc = PLoc.getIncludeLoc();
+      }
+    }
+
+    // Escape this filename.  Turn '\' -> '\\' '"' -> '\"'
+    llvm::SmallString<128> FN;
+    FN += PLoc.getFilename();
+    Lexer::Stringify(FN);
+    OS << '"' << FN.str() << '"';
+    Tok.setKind(tok::string_literal);
+  } else if (II == Ident__DATE__) {
+    if (!DATELoc.isValid())
+      ComputeDATE_TIME(DATELoc, TIMELoc, *this);
+    Tok.setKind(tok::string_literal);
+    Tok.setLength(strlen("\"Mmm dd yyyy\""));
+    Tok.setLocation(SourceMgr.createInstantiationLoc(DATELoc, Tok.getLocation(),
+                                                     Tok.getLocation(),
+                                                     Tok.getLength()));
+    return;
+  } else if (II == Ident__TIME__) {
+    if (!TIMELoc.isValid())
+      ComputeDATE_TIME(DATELoc, TIMELoc, *this);
+    Tok.setKind(tok::string_literal);
+    Tok.setLength(strlen("\"hh:mm:ss\""));
+    Tok.setLocation(SourceMgr.createInstantiationLoc(TIMELoc, Tok.getLocation(),
+                                                     Tok.getLocation(),
+                                                     Tok.getLength()));
+    return;
+  } else if (II == Ident__INCLUDE_LEVEL__) {
+    // Compute the presumed include depth of this token.  This can be affected
+    // by GNU line markers.
+    unsigned Depth = 0;
+
+    PresumedLoc PLoc = SourceMgr.getPresumedLoc(Tok.getLocation());
+    PLoc = SourceMgr.getPresumedLoc(PLoc.getIncludeLoc());
+    for (; PLoc.isValid(); ++Depth)
+      PLoc = SourceMgr.getPresumedLoc(PLoc.getIncludeLoc());
+
+    // __INCLUDE_LEVEL__ expands to a simple numeric value.
+    OS << Depth;
+    Tok.setKind(tok::numeric_constant);
+  } else if (II == Ident__TIMESTAMP__) {
+    // MSVC, ICC, GCC, VisualAge C++ extension.  The generated string should be
+    // of the form "Ddd Mmm dd hh::mm::ss yyyy", which is returned by asctime.
+
+    // Get the file that we are lexing out of.  If we're currently lexing from
+    // a macro, dig into the include stack.
+    const FileEntry *CurFile = 0;
+    PreprocessorLexer *TheLexer = getCurrentFileLexer();
+
+    if (TheLexer)
+      CurFile = SourceMgr.getFileEntryForID(TheLexer->getFileID());
+
+    const char *Result;
+    if (CurFile) {
+      time_t TT = CurFile->getModificationTime();
+      struct tm *TM = localtime(&TT);
+      Result = asctime(TM);
+    } else {
+      Result = "??? ??? ?? ??:??:?? ????\n";
+    }
+    // Surround the string with " and strip the trailing newline.
+    OS << '"' << llvm::StringRef(Result, strlen(Result)-1) << '"';
+    Tok.setKind(tok::string_literal);
+  } else if (II == Ident__COUNTER__) {
+    // __COUNTER__ expands to a simple numeric value.
+    OS << CounterValue++;
+    Tok.setKind(tok::numeric_constant);
+  } else if (II == Ident__has_feature ||
+             II == Ident__has_builtin) {
+    // The argument to these two builtins should be a parenthesized identifier.
+    SourceLocation StartLoc = Tok.getLocation();
+
+    bool IsValid = false;
+    IdentifierInfo *FeatureII = 0;
+
+    // Read the '('.
+    Lex(Tok);
+    if (Tok.is(tok::l_paren)) {
+      // Read the identifier
+      Lex(Tok);
+      if (Tok.is(tok::identifier)) {
+        FeatureII = Tok.getIdentifierInfo();
+
+        // Read the ')'.
+        Lex(Tok);
+        if (Tok.is(tok::r_paren))
+          IsValid = true;
+      }
+    }
+
+    bool Value = false;
+    if (!IsValid)
+      Diag(StartLoc, diag::err_feature_check_malformed);
+    else if (II == Ident__has_builtin) {
+      // Check for a builtin is trivial.
+      Value = FeatureII->getBuiltinID() != 0;
+    } else {
+      assert(II == Ident__has_feature && "Must be feature check");
+      Value = HasFeature(*this, FeatureII);
+    }
+
+    OS << (int)Value;
+    Tok.setKind(tok::numeric_constant);
+  } else if (II == Ident__has_include ||
+             II == Ident__has_include_next) {
+    // The argument to these two builtins should be a parenthesized
+    // file name string literal using angle brackets (<>) or
+    // double-quotes ("").
+    bool Value = false;
+    bool IsValid;
+    if (II == Ident__has_include)
+      IsValid = EvaluateHasInclude(Value, Tok, II, *this);
+    else
+      IsValid = EvaluateHasIncludeNext(Value, Tok, II, *this);
+    OS << (int)Value;
+    Tok.setKind(tok::numeric_constant);
+  } else {
+    assert(0 && "Unknown identifier!");
+  }
+  CreateString(OS.str().data(), OS.str().size(), Tok, Tok.getLocation());
+}
diff --git a/lib/Lex/PTHLexer.cpp b/lib/Lex/PTHLexer.cpp
new file mode 100644
index 0000000..3b949d0
--- /dev/null
+++ b/lib/Lex/PTHLexer.cpp
@@ -0,0 +1,685 @@
+//===--- PTHLexer.cpp - Lex from a token stream ---------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the PTHLexer interface.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Basic/TokenKinds.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/OnDiskHashTable.h"
+#include "clang/Lex/LexDiagnostic.h"
+#include "clang/Lex/PTHLexer.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Lex/PTHManager.h"
+#include "clang/Lex/Token.h"
+#include "clang/Lex/Preprocessor.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include <sys/stat.h>
+using namespace clang;
+using namespace clang::io;
+
+#define DISK_TOKEN_SIZE (1+1+2+4+4)
+
+//===----------------------------------------------------------------------===//
+// PTHLexer methods.
+//===----------------------------------------------------------------------===//
+
+PTHLexer::PTHLexer(Preprocessor &PP, FileID FID, const unsigned char *D,
+                   const unsigned char *ppcond, PTHManager &PM)
+  : PreprocessorLexer(&PP, FID), TokBuf(D), CurPtr(D), LastHashTokPtr(0),
+    PPCond(ppcond), CurPPCondPtr(ppcond), PTHMgr(PM) {
+
+  FileStartLoc = PP.getSourceManager().getLocForStartOfFile(FID);
+}
+
+void PTHLexer::Lex(Token& Tok) {
+LexNextToken:
+
+  //===--------------------------------------==//
+  // Read the raw token data.
+  //===--------------------------------------==//
+
+  // Shadow CurPtr into an automatic variable.
+  const unsigned char *CurPtrShadow = CurPtr;
+
+  // Read in the data for the token.
+  unsigned Word0 = ReadLE32(CurPtrShadow);
+  uint32_t IdentifierID = ReadLE32(CurPtrShadow);
+  uint32_t FileOffset = ReadLE32(CurPtrShadow);
+
+  tok::TokenKind TKind = (tok::TokenKind) (Word0 & 0xFF);
+  Token::TokenFlags TFlags = (Token::TokenFlags) ((Word0 >> 8) & 0xFF);
+  uint32_t Len = Word0 >> 16;
+
+  CurPtr = CurPtrShadow;
+
+  //===--------------------------------------==//
+  // Construct the token itself.
+  //===--------------------------------------==//
+
+  Tok.startToken();
+  Tok.setKind(TKind);
+  Tok.setFlag(TFlags);
+  assert(!LexingRawMode);
+  Tok.setLocation(FileStartLoc.getFileLocWithOffset(FileOffset));
+  Tok.setLength(Len);
+
+  // Handle identifiers.
+  if (Tok.isLiteral()) {
+    Tok.setLiteralData((const char*) (PTHMgr.SpellingBase + IdentifierID));
+  }
+  else if (IdentifierID) {
+    MIOpt.ReadToken();
+    IdentifierInfo *II = PTHMgr.GetIdentifierInfo(IdentifierID-1);
+
+    Tok.setIdentifierInfo(II);
+
+    // Change the kind of this identifier to the appropriate token kind, e.g.
+    // turning "for" into a keyword.
+    Tok.setKind(II->getTokenID());
+
+    if (II->isHandleIdentifierCase())
+      PP->HandleIdentifier(Tok);
+    return;
+  }
+
+  //===--------------------------------------==//
+  // Process the token.
+  //===--------------------------------------==//
+  if (TKind == tok::eof) {
+    // Save the end-of-file token.
+    EofToken = Tok;
+
+    Preprocessor *PPCache = PP;
+
+    assert(!ParsingPreprocessorDirective);
+    assert(!LexingRawMode);
+
+    // FIXME: Issue diagnostics similar to Lexer.
+    if (PP->HandleEndOfFile(Tok, false))
+      return;
+
+    assert(PPCache && "Raw buffer::LexEndOfFile should return a token");
+    return PPCache->Lex(Tok);
+  }
+
+  if (TKind == tok::hash && Tok.isAtStartOfLine()) {
+    LastHashTokPtr = CurPtr - DISK_TOKEN_SIZE;
+    assert(!LexingRawMode);
+    PP->HandleDirective(Tok);
+
+    if (PP->isCurrentLexer(this))
+      goto LexNextToken;
+
+    return PP->Lex(Tok);
+  }
+
+  if (TKind == tok::eom) {
+    assert(ParsingPreprocessorDirective);
+    ParsingPreprocessorDirective = false;
+    return;
+  }
+
+  MIOpt.ReadToken();
+}
+
+// FIXME: We can just grab the last token instead of storing a copy
+// into EofToken.
+void PTHLexer::getEOF(Token& Tok) {
+  assert(EofToken.is(tok::eof));
+  Tok = EofToken;
+}
+
+void PTHLexer::DiscardToEndOfLine() {
+  assert(ParsingPreprocessorDirective && ParsingFilename == false &&
+         "Must be in a preprocessing directive!");
+
+  // We assume that if the preprocessor wishes to discard to the end of
+  // the line that it also means to end the current preprocessor directive.
+  ParsingPreprocessorDirective = false;
+
+  // Skip tokens by only peeking at their token kind and the flags.
+  // We don't need to actually reconstruct full tokens from the token buffer.
+  // This saves some copies and it also reduces IdentifierInfo* lookup.
+  const unsigned char* p = CurPtr;
+  while (1) {
+    // Read the token kind.  Are we at the end of the file?
+    tok::TokenKind x = (tok::TokenKind) (uint8_t) *p;
+    if (x == tok::eof) break;
+
+    // Read the token flags.  Are we at the start of the next line?
+    Token::TokenFlags y = (Token::TokenFlags) (uint8_t) p[1];
+    if (y & Token::StartOfLine) break;
+
+    // Skip to the next token.
+    p += DISK_TOKEN_SIZE;
+  }
+
+  CurPtr = p;
+}
+
+/// SkipBlock - Used by Preprocessor to skip the current conditional block.
+bool PTHLexer::SkipBlock() {
+  assert(CurPPCondPtr && "No cached PP conditional information.");
+  assert(LastHashTokPtr && "No known '#' token.");
+
+  const unsigned char* HashEntryI = 0;
+  uint32_t Offset;
+  uint32_t TableIdx;
+
+  do {
+    // Read the token offset from the side-table.
+    Offset = ReadLE32(CurPPCondPtr);
+
+    // Read the target table index from the side-table.
+    TableIdx = ReadLE32(CurPPCondPtr);
+
+    // Compute the actual memory address of the '#' token data for this entry.
+    HashEntryI = TokBuf + Offset;
+
+    // Optmization: "Sibling jumping".  #if...#else...#endif blocks can
+    //  contain nested blocks.  In the side-table we can jump over these
+    //  nested blocks instead of doing a linear search if the next "sibling"
+    //  entry is not at a location greater than LastHashTokPtr.
+    if (HashEntryI < LastHashTokPtr && TableIdx) {
+      // In the side-table we are still at an entry for a '#' token that
+      // is earlier than the last one we saw.  Check if the location we would
+      // stride gets us closer.
+      const unsigned char* NextPPCondPtr =
+        PPCond + TableIdx*(sizeof(uint32_t)*2);
+      assert(NextPPCondPtr >= CurPPCondPtr);
+      // Read where we should jump to.
+      uint32_t TmpOffset = ReadLE32(NextPPCondPtr);
+      const unsigned char* HashEntryJ = TokBuf + TmpOffset;
+
+      if (HashEntryJ <= LastHashTokPtr) {
+        // Jump directly to the next entry in the side table.
+        HashEntryI = HashEntryJ;
+        Offset = TmpOffset;
+        TableIdx = ReadLE32(NextPPCondPtr);
+        CurPPCondPtr = NextPPCondPtr;
+      }
+    }
+  }
+  while (HashEntryI < LastHashTokPtr);
+  assert(HashEntryI == LastHashTokPtr && "No PP-cond entry found for '#'");
+  assert(TableIdx && "No jumping from #endifs.");
+
+  // Update our side-table iterator.
+  const unsigned char* NextPPCondPtr = PPCond + TableIdx*(sizeof(uint32_t)*2);
+  assert(NextPPCondPtr >= CurPPCondPtr);
+  CurPPCondPtr = NextPPCondPtr;
+
+  // Read where we should jump to.
+  HashEntryI = TokBuf + ReadLE32(NextPPCondPtr);
+  uint32_t NextIdx = ReadLE32(NextPPCondPtr);
+
+  // By construction NextIdx will be zero if this is a #endif.  This is useful
+  // to know to obviate lexing another token.
+  bool isEndif = NextIdx == 0;
+
+  // This case can occur when we see something like this:
+  //
+  //  #if ...
+  //   /* a comment or nothing */
+  //  #elif
+  //
+  // If we are skipping the first #if block it will be the case that CurPtr
+  // already points 'elif'.  Just return.
+
+  if (CurPtr > HashEntryI) {
+    assert(CurPtr == HashEntryI + DISK_TOKEN_SIZE);
+    // Did we reach a #endif?  If so, go ahead and consume that token as well.
+    if (isEndif)
+      CurPtr += DISK_TOKEN_SIZE*2;
+    else
+      LastHashTokPtr = HashEntryI;
+
+    return isEndif;
+  }
+
+  // Otherwise, we need to advance.  Update CurPtr to point to the '#' token.
+  CurPtr = HashEntryI;
+
+  // Update the location of the last observed '#'.  This is useful if we
+  // are skipping multiple blocks.
+  LastHashTokPtr = CurPtr;
+
+  // Skip the '#' token.
+  assert(((tok::TokenKind)*CurPtr) == tok::hash);
+  CurPtr += DISK_TOKEN_SIZE;
+
+  // Did we reach a #endif?  If so, go ahead and consume that token as well.
+  if (isEndif) { CurPtr += DISK_TOKEN_SIZE*2; }
+
+  return isEndif;
+}
+
+SourceLocation PTHLexer::getSourceLocation() {
+  // getSourceLocation is not on the hot path.  It is used to get the location
+  // of the next token when transitioning back to this lexer when done
+  // handling a #included file.  Just read the necessary data from the token
+  // data buffer to construct the SourceLocation object.
+  // NOTE: This is a virtual function; hence it is defined out-of-line.
+  const unsigned char *OffsetPtr = CurPtr + (DISK_TOKEN_SIZE - 4);
+  uint32_t Offset = ReadLE32(OffsetPtr);
+  return FileStartLoc.getFileLocWithOffset(Offset);
+}
+
+//===----------------------------------------------------------------------===//
+// PTH file lookup: map from strings to file data.
+//===----------------------------------------------------------------------===//
+
+/// PTHFileLookup - This internal data structure is used by the PTHManager
+///  to map from FileEntry objects managed by FileManager to offsets within
+///  the PTH file.
+namespace {
+class PTHFileData {
+  const uint32_t TokenOff;
+  const uint32_t PPCondOff;
+public:
+  PTHFileData(uint32_t tokenOff, uint32_t ppCondOff)
+    : TokenOff(tokenOff), PPCondOff(ppCondOff) {}
+
+  uint32_t getTokenOffset() const { return TokenOff; }
+  uint32_t getPPCondOffset() const { return PPCondOff; }
+};
+
+
+class PTHFileLookupCommonTrait {
+public:
+  typedef std::pair<unsigned char, const char*> internal_key_type;
+
+  static unsigned ComputeHash(internal_key_type x) {
+    return llvm::HashString(x.second);
+  }
+
+  static std::pair<unsigned, unsigned>
+  ReadKeyDataLength(const unsigned char*& d) {
+    unsigned keyLen = (unsigned) ReadUnalignedLE16(d);
+    unsigned dataLen = (unsigned) *(d++);
+    return std::make_pair(keyLen, dataLen);
+  }
+
+  static internal_key_type ReadKey(const unsigned char* d, unsigned) {
+    unsigned char k = *(d++); // Read the entry kind.
+    return std::make_pair(k, (const char*) d);
+  }
+};
+
+class PTHFileLookupTrait : public PTHFileLookupCommonTrait {
+public:
+  typedef const FileEntry* external_key_type;
+  typedef PTHFileData      data_type;
+
+  static internal_key_type GetInternalKey(const FileEntry* FE) {
+    return std::make_pair((unsigned char) 0x1, FE->getName());
+  }
+
+  static bool EqualKey(internal_key_type a, internal_key_type b) {
+    return a.first == b.first && strcmp(a.second, b.second) == 0;
+  }
+
+  static PTHFileData ReadData(const internal_key_type& k,
+                              const unsigned char* d, unsigned) {
+    assert(k.first == 0x1 && "Only file lookups can match!");
+    uint32_t x = ::ReadUnalignedLE32(d);
+    uint32_t y = ::ReadUnalignedLE32(d);
+    return PTHFileData(x, y);
+  }
+};
+
+class PTHStringLookupTrait {
+public:
+  typedef uint32_t
+          data_type;
+
+  typedef const std::pair<const char*, unsigned>
+          external_key_type;
+
+  typedef external_key_type internal_key_type;
+
+  static bool EqualKey(const internal_key_type& a,
+                       const internal_key_type& b) {
+    return (a.second == b.second) ? memcmp(a.first, b.first, a.second) == 0
+                                  : false;
+  }
+
+  static unsigned ComputeHash(const internal_key_type& a) {
+    return llvm::HashString(llvm::StringRef(a.first, a.second));
+  }
+
+  // This hopefully will just get inlined and removed by the optimizer.
+  static const internal_key_type&
+  GetInternalKey(const external_key_type& x) { return x; }
+
+  static std::pair<unsigned, unsigned>
+  ReadKeyDataLength(const unsigned char*& d) {
+    return std::make_pair((unsigned) ReadUnalignedLE16(d), sizeof(uint32_t));
+  }
+
+  static std::pair<const char*, unsigned>
+  ReadKey(const unsigned char* d, unsigned n) {
+      assert(n >= 2 && d[n-1] == '\0');
+      return std::make_pair((const char*) d, n-1);
+    }
+
+  static uint32_t ReadData(const internal_key_type& k, const unsigned char* d,
+                           unsigned) {
+    return ::ReadUnalignedLE32(d);
+  }
+};
+
+} // end anonymous namespace
+
+typedef OnDiskChainedHashTable<PTHFileLookupTrait>   PTHFileLookup;
+typedef OnDiskChainedHashTable<PTHStringLookupTrait> PTHStringIdLookup;
+
+//===----------------------------------------------------------------------===//
+// PTHManager methods.
+//===----------------------------------------------------------------------===//
+
+PTHManager::PTHManager(const llvm::MemoryBuffer* buf, void* fileLookup,
+                       const unsigned char* idDataTable,
+                       IdentifierInfo** perIDCache,
+                       void* stringIdLookup, unsigned numIds,
+                       const unsigned char* spellingBase,
+                       const char* originalSourceFile)
+: Buf(buf), PerIDCache(perIDCache), FileLookup(fileLookup),
+  IdDataTable(idDataTable), StringIdLookup(stringIdLookup),
+  NumIds(numIds), PP(0), SpellingBase(spellingBase),
+  OriginalSourceFile(originalSourceFile) {}
+
+PTHManager::~PTHManager() {
+  delete Buf;
+  delete (PTHFileLookup*) FileLookup;
+  delete (PTHStringIdLookup*) StringIdLookup;
+  free(PerIDCache);
+}
+
+static void InvalidPTH(Diagnostic &Diags, const char *Msg) {
+  Diags.Report(Diags.getCustomDiagID(Diagnostic::Error, Msg));
+}
+
+PTHManager* PTHManager::Create(const std::string& file, Diagnostic &Diags) {
+  // Memory map the PTH file.
+  llvm::OwningPtr<llvm::MemoryBuffer>
+  File(llvm::MemoryBuffer::getFile(file.c_str()));
+
+  if (!File) {
+    Diags.Report(diag::err_invalid_pth_file) << file;
+    return 0;
+  }
+
+  // Get the buffer ranges and check if there are at least three 32-bit
+  // words at the end of the file.
+  const unsigned char* BufBeg = (unsigned char*)File->getBufferStart();
+  const unsigned char* BufEnd = (unsigned char*)File->getBufferEnd();
+
+  // Check the prologue of the file.
+  if ((BufEnd - BufBeg) < (signed) (sizeof("cfe-pth") + 3 + 4) ||
+      memcmp(BufBeg, "cfe-pth", sizeof("cfe-pth") - 1) != 0) {
+    Diags.Report(diag::err_invalid_pth_file) << file;
+    return 0;
+  }
+
+  // Read the PTH version.
+  const unsigned char *p = BufBeg + (sizeof("cfe-pth") - 1);
+  unsigned Version = ReadLE32(p);
+
+  if (Version < PTHManager::Version) {
+    InvalidPTH(Diags,
+        Version < PTHManager::Version
+        ? "PTH file uses an older PTH format that is no longer supported"
+        : "PTH file uses a newer PTH format that cannot be read");
+    return 0;
+  }
+
+  // Compute the address of the index table at the end of the PTH file.
+  const unsigned char *PrologueOffset = p;
+
+  if (PrologueOffset >= BufEnd) {
+    Diags.Report(diag::err_invalid_pth_file) << file;
+    return 0;
+  }
+
+  // Construct the file lookup table.  This will be used for mapping from
+  // FileEntry*'s to cached tokens.
+  const unsigned char* FileTableOffset = PrologueOffset + sizeof(uint32_t)*2;
+  const unsigned char* FileTable = BufBeg + ReadLE32(FileTableOffset);
+
+  if (!(FileTable > BufBeg && FileTable < BufEnd)) {
+    Diags.Report(diag::err_invalid_pth_file) << file;
+    return 0; // FIXME: Proper error diagnostic?
+  }
+
+  llvm::OwningPtr<PTHFileLookup> FL(PTHFileLookup::Create(FileTable, BufBeg));
+
+  // Warn if the PTH file is empty.  We still want to create a PTHManager
+  // as the PTH could be used with -include-pth.
+  if (FL->isEmpty())
+    InvalidPTH(Diags, "PTH file contains no cached source data");
+
+  // Get the location of the table mapping from persistent ids to the
+  // data needed to reconstruct identifiers.
+  const unsigned char* IDTableOffset = PrologueOffset + sizeof(uint32_t)*0;
+  const unsigned char* IData = BufBeg + ReadLE32(IDTableOffset);
+
+  if (!(IData >= BufBeg && IData < BufEnd)) {
+    Diags.Report(diag::err_invalid_pth_file) << file;
+    return 0;
+  }
+
+  // Get the location of the hashtable mapping between strings and
+  // persistent IDs.
+  const unsigned char* StringIdTableOffset = PrologueOffset + sizeof(uint32_t)*1;
+  const unsigned char* StringIdTable = BufBeg + ReadLE32(StringIdTableOffset);
+  if (!(StringIdTable >= BufBeg && StringIdTable < BufEnd)) {
+    Diags.Report(diag::err_invalid_pth_file) << file;
+    return 0;
+  }
+
+  llvm::OwningPtr<PTHStringIdLookup> SL(PTHStringIdLookup::Create(StringIdTable,
+                                                                  BufBeg));
+
+  // Get the location of the spelling cache.
+  const unsigned char* spellingBaseOffset = PrologueOffset + sizeof(uint32_t)*3;
+  const unsigned char* spellingBase = BufBeg + ReadLE32(spellingBaseOffset);
+  if (!(spellingBase >= BufBeg && spellingBase < BufEnd)) {
+    Diags.Report(diag::err_invalid_pth_file) << file;
+    return 0;
+  }
+
+  // Get the number of IdentifierInfos and pre-allocate the identifier cache.
+  uint32_t NumIds = ReadLE32(IData);
+
+  // Pre-allocate the peristent ID -> IdentifierInfo* cache.  We use calloc()
+  // so that we in the best case only zero out memory once when the OS returns
+  // us new pages.
+  IdentifierInfo** PerIDCache = 0;
+
+  if (NumIds) {
+    PerIDCache = (IdentifierInfo**)calloc(NumIds, sizeof(*PerIDCache));
+    if (!PerIDCache) {
+      InvalidPTH(Diags, "Could not allocate memory for processing PTH file");
+      return 0;
+    }
+  }
+
+  // Compute the address of the original source file.
+  const unsigned char* originalSourceBase = PrologueOffset + sizeof(uint32_t)*4;
+  unsigned len = ReadUnalignedLE16(originalSourceBase);
+  if (!len) originalSourceBase = 0;
+
+  // Create the new PTHManager.
+  return new PTHManager(File.take(), FL.take(), IData, PerIDCache,
+                        SL.take(), NumIds, spellingBase,
+                        (const char*) originalSourceBase);
+}
+
+IdentifierInfo* PTHManager::LazilyCreateIdentifierInfo(unsigned PersistentID) {
+  // Look in the PTH file for the string data for the IdentifierInfo object.
+  const unsigned char* TableEntry = IdDataTable + sizeof(uint32_t)*PersistentID;
+  const unsigned char* IDData =
+    (const unsigned char*)Buf->getBufferStart() + ReadLE32(TableEntry);
+  assert(IDData < (const unsigned char*)Buf->getBufferEnd());
+
+  // Allocate the object.
+  std::pair<IdentifierInfo,const unsigned char*> *Mem =
+    Alloc.Allocate<std::pair<IdentifierInfo,const unsigned char*> >();
+
+  Mem->second = IDData;
+  assert(IDData[0] != '\0');
+  IdentifierInfo *II = new ((void*) Mem) IdentifierInfo();
+
+  // Store the new IdentifierInfo in the cache.
+  PerIDCache[PersistentID] = II;
+  assert(II->getNameStart() && II->getNameStart()[0] != '\0');
+  return II;
+}
+
+IdentifierInfo* PTHManager::get(llvm::StringRef Name) {
+  PTHStringIdLookup& SL = *((PTHStringIdLookup*)StringIdLookup);
+  // Double check our assumption that the last character isn't '\0'.
+  assert(Name.empty() || Name.data()[Name.size()-1] != '\0');
+  PTHStringIdLookup::iterator I = SL.find(std::make_pair(Name.data(),
+                                                         Name.size()));
+  if (I == SL.end()) // No identifier found?
+    return 0;
+
+  // Match found.  Return the identifier!
+  assert(*I > 0);
+  return GetIdentifierInfo(*I-1);
+}
+
+PTHLexer *PTHManager::CreateLexer(FileID FID) {
+  const FileEntry *FE = PP->getSourceManager().getFileEntryForID(FID);
+  if (!FE)
+    return 0;
+
+  // Lookup the FileEntry object in our file lookup data structure.  It will
+  // return a variant that indicates whether or not there is an offset within
+  // the PTH file that contains cached tokens.
+  PTHFileLookup& PFL = *((PTHFileLookup*)FileLookup);
+  PTHFileLookup::iterator I = PFL.find(FE);
+
+  if (I == PFL.end()) // No tokens available?
+    return 0;
+
+  const PTHFileData& FileData = *I;
+
+  const unsigned char *BufStart = (const unsigned char *)Buf->getBufferStart();
+  // Compute the offset of the token data within the buffer.
+  const unsigned char* data = BufStart + FileData.getTokenOffset();
+
+  // Get the location of pp-conditional table.
+  const unsigned char* ppcond = BufStart + FileData.getPPCondOffset();
+  uint32_t Len = ReadLE32(ppcond);
+  if (Len == 0) ppcond = 0;
+
+  assert(PP && "No preprocessor set yet!");
+  return new PTHLexer(*PP, FID, data, ppcond, *this);
+}
+
+//===----------------------------------------------------------------------===//
+// 'stat' caching.
+//===----------------------------------------------------------------------===//
+
+namespace {
+class PTHStatData {
+public:
+  const bool hasStat;
+  const ino_t ino;
+  const dev_t dev;
+  const mode_t mode;
+  const time_t mtime;
+  const off_t size;
+
+  PTHStatData(ino_t i, dev_t d, mode_t mo, time_t m, off_t s)
+  : hasStat(true), ino(i), dev(d), mode(mo), mtime(m), size(s) {}
+
+  PTHStatData()
+    : hasStat(false), ino(0), dev(0), mode(0), mtime(0), size(0) {}
+};
+
+class PTHStatLookupTrait : public PTHFileLookupCommonTrait {
+public:
+  typedef const char* external_key_type;  // const char*
+  typedef PTHStatData data_type;
+
+  static internal_key_type GetInternalKey(const char *path) {
+    // The key 'kind' doesn't matter here because it is ignored in EqualKey.
+    return std::make_pair((unsigned char) 0x0, path);
+  }
+
+  static bool EqualKey(internal_key_type a, internal_key_type b) {
+    // When doing 'stat' lookups we don't care about the kind of 'a' and 'b',
+    // just the paths.
+    return strcmp(a.second, b.second) == 0;
+  }
+
+  static data_type ReadData(const internal_key_type& k, const unsigned char* d,
+                            unsigned) {
+
+    if (k.first /* File or Directory */) {
+      if (k.first == 0x1 /* File */) d += 4 * 2; // Skip the first 2 words.
+      ino_t ino = (ino_t) ReadUnalignedLE32(d);
+      dev_t dev = (dev_t) ReadUnalignedLE32(d);
+      mode_t mode = (mode_t) ReadUnalignedLE16(d);
+      time_t mtime = (time_t) ReadUnalignedLE64(d);
+      return data_type(ino, dev, mode, mtime, (off_t) ReadUnalignedLE64(d));
+    }
+
+    // Negative stat.  Don't read anything.
+    return data_type();
+  }
+};
+
+class PTHStatCache : public StatSysCallCache {
+  typedef OnDiskChainedHashTable<PTHStatLookupTrait> CacheTy;
+  CacheTy Cache;
+
+public:
+  PTHStatCache(PTHFileLookup &FL) :
+    Cache(FL.getNumBuckets(), FL.getNumEntries(), FL.getBuckets(),
+          FL.getBase()) {}
+
+  ~PTHStatCache() {}
+
+  int stat(const char *path, struct stat *buf) {
+    // Do the lookup for the file's data in the PTH file.
+    CacheTy::iterator I = Cache.find(path);
+
+    // If we don't get a hit in the PTH file just forward to 'stat'.
+    if (I == Cache.end())
+      return StatSysCallCache::stat(path, buf);
+
+    const PTHStatData& Data = *I;
+
+    if (!Data.hasStat)
+      return 1;
+
+    buf->st_ino = Data.ino;
+    buf->st_dev = Data.dev;
+    buf->st_mtime = Data.mtime;
+    buf->st_mode = Data.mode;
+    buf->st_size = Data.size;
+    return 0;
+  }
+};
+} // end anonymous namespace
+
+StatSysCallCache *PTHManager::createStatCache() {
+  return new PTHStatCache(*((PTHFileLookup*) FileLookup));
+}
diff --git a/lib/Lex/Pragma.cpp b/lib/Lex/Pragma.cpp
new file mode 100644
index 0000000..92332a0
--- /dev/null
+++ b/lib/Lex/Pragma.cpp
@@ -0,0 +1,740 @@
+//===--- Pragma.cpp - Pragma registration and handling --------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the PragmaHandler/PragmaTable interfaces and implements
+// pragma related methods of the Preprocessor class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Lex/Pragma.h"
+#include "clang/Lex/HeaderSearch.h"
+#include "clang/Lex/LiteralSupport.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Lex/LexDiagnostic.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/SourceManager.h"
+#include <algorithm>
+using namespace clang;
+
+// Out-of-line destructor to provide a home for the class.
+PragmaHandler::~PragmaHandler() {
+}
+
+//===----------------------------------------------------------------------===//
+// PragmaNamespace Implementation.
+//===----------------------------------------------------------------------===//
+
+
+PragmaNamespace::~PragmaNamespace() {
+  for (unsigned i = 0, e = Handlers.size(); i != e; ++i)
+    delete Handlers[i];
+}
+
+/// FindHandler - Check to see if there is already a handler for the
+/// specified name.  If not, return the handler for the null identifier if it
+/// exists, otherwise return null.  If IgnoreNull is true (the default) then
+/// the null handler isn't returned on failure to match.
+PragmaHandler *PragmaNamespace::FindHandler(const IdentifierInfo *Name,
+                                            bool IgnoreNull) const {
+  PragmaHandler *NullHandler = 0;
+  for (unsigned i = 0, e = Handlers.size(); i != e; ++i) {
+    if (Handlers[i]->getName() == Name)
+      return Handlers[i];
+
+    if (Handlers[i]->getName() == 0)
+      NullHandler = Handlers[i];
+  }
+  return IgnoreNull ? 0 : NullHandler;
+}
+
+void PragmaNamespace::RemovePragmaHandler(PragmaHandler *Handler) {
+  for (unsigned i = 0, e = Handlers.size(); i != e; ++i) {
+    if (Handlers[i] == Handler) {
+      Handlers[i] = Handlers.back();
+      Handlers.pop_back();
+      return;
+    }
+  }
+  assert(0 && "Handler not registered in this namespace");
+}
+
+void PragmaNamespace::HandlePragma(Preprocessor &PP, Token &Tok) {
+  // Read the 'namespace' that the directive is in, e.g. STDC.  Do not macro
+  // expand it, the user can have a STDC #define, that should not affect this.
+  PP.LexUnexpandedToken(Tok);
+
+  // Get the handler for this token.  If there is no handler, ignore the pragma.
+  PragmaHandler *Handler = FindHandler(Tok.getIdentifierInfo(), false);
+  if (Handler == 0) {
+    PP.Diag(Tok, diag::warn_pragma_ignored);
+    return;
+  }
+
+  // Otherwise, pass it down.
+  Handler->HandlePragma(PP, Tok);
+}
+
+//===----------------------------------------------------------------------===//
+// Preprocessor Pragma Directive Handling.
+//===----------------------------------------------------------------------===//
+
+/// HandlePragmaDirective - The "#pragma" directive has been parsed.  Lex the
+/// rest of the pragma, passing it to the registered pragma handlers.
+void Preprocessor::HandlePragmaDirective() {
+  ++NumPragma;
+
+  // Invoke the first level of pragma handlers which reads the namespace id.
+  Token Tok;
+  PragmaHandlers->HandlePragma(*this, Tok);
+
+  // If the pragma handler didn't read the rest of the line, consume it now.
+  if (CurPPLexer && CurPPLexer->ParsingPreprocessorDirective)
+    DiscardUntilEndOfDirective();
+}
+
+/// Handle_Pragma - Read a _Pragma directive, slice it up, process it, then
+/// return the first token after the directive.  The _Pragma token has just
+/// been read into 'Tok'.
+void Preprocessor::Handle_Pragma(Token &Tok) {
+  // Remember the pragma token location.
+  SourceLocation PragmaLoc = Tok.getLocation();
+
+  // Read the '('.
+  Lex(Tok);
+  if (Tok.isNot(tok::l_paren)) {
+    Diag(PragmaLoc, diag::err__Pragma_malformed);
+    return;
+  }
+
+  // Read the '"..."'.
+  Lex(Tok);
+  if (Tok.isNot(tok::string_literal) && Tok.isNot(tok::wide_string_literal)) {
+    Diag(PragmaLoc, diag::err__Pragma_malformed);
+    return;
+  }
+
+  // Remember the string.
+  std::string StrVal = getSpelling(Tok);
+
+  // Read the ')'.
+  Lex(Tok);
+  if (Tok.isNot(tok::r_paren)) {
+    Diag(PragmaLoc, diag::err__Pragma_malformed);
+    return;
+  }
+
+  SourceLocation RParenLoc = Tok.getLocation();
+
+  // The _Pragma is lexically sound.  Destringize according to C99 6.10.9.1:
+  // "The string literal is destringized by deleting the L prefix, if present,
+  // deleting the leading and trailing double-quotes, replacing each escape
+  // sequence \" by a double-quote, and replacing each escape sequence \\ by a
+  // single backslash."
+  if (StrVal[0] == 'L')  // Remove L prefix.
+    StrVal.erase(StrVal.begin());
+  assert(StrVal[0] == '"' && StrVal[StrVal.size()-1] == '"' &&
+         "Invalid string token!");
+
+  // Remove the front quote, replacing it with a space, so that the pragma
+  // contents appear to have a space before them.
+  StrVal[0] = ' ';
+
+  // Replace the terminating quote with a \n.
+  StrVal[StrVal.size()-1] = '\n';
+
+  // Remove escaped quotes and escapes.
+  for (unsigned i = 0, e = StrVal.size(); i != e-1; ++i) {
+    if (StrVal[i] == '\\' &&
+        (StrVal[i+1] == '\\' || StrVal[i+1] == '"')) {
+      // \\ -> '\' and \" -> '"'.
+      StrVal.erase(StrVal.begin()+i);
+      --e;
+    }
+  }
+
+  // Plop the string (including the newline and trailing null) into a buffer
+  // where we can lex it.
+  Token TmpTok;
+  TmpTok.startToken();
+  CreateString(&StrVal[0], StrVal.size(), TmpTok);
+  SourceLocation TokLoc = TmpTok.getLocation();
+
+  // Make and enter a lexer object so that we lex and expand the tokens just
+  // like any others.
+  Lexer *TL = Lexer::Create_PragmaLexer(TokLoc, PragmaLoc, RParenLoc,
+                                        StrVal.size(), *this);
+
+  EnterSourceFileWithLexer(TL, 0);
+
+  // With everything set up, lex this as a #pragma directive.
+  HandlePragmaDirective();
+
+  // Finally, return whatever came after the pragma directive.
+  return Lex(Tok);
+}
+
+
+
+/// HandlePragmaOnce - Handle #pragma once.  OnceTok is the 'once'.
+///
+void Preprocessor::HandlePragmaOnce(Token &OnceTok) {
+  if (isInPrimaryFile()) {
+    Diag(OnceTok, diag::pp_pragma_once_in_main_file);
+    return;
+  }
+
+  // Get the current file lexer we're looking at.  Ignore _Pragma 'files' etc.
+  // Mark the file as a once-only file now.
+  HeaderInfo.MarkFileIncludeOnce(getCurrentFileLexer()->getFileEntry());
+}
+
+void Preprocessor::HandlePragmaMark() {
+  assert(CurPPLexer && "No current lexer?");
+  if (CurLexer)
+    CurLexer->ReadToEndOfLine();
+  else
+    CurPTHLexer->DiscardToEndOfLine();
+}
+
+
+/// HandlePragmaPoison - Handle #pragma GCC poison.  PoisonTok is the 'poison'.
+///
+void Preprocessor::HandlePragmaPoison(Token &PoisonTok) {
+  Token Tok;
+
+  while (1) {
+    // Read the next token to poison.  While doing this, pretend that we are
+    // skipping while reading the identifier to poison.
+    // This avoids errors on code like:
+    //   #pragma GCC poison X
+    //   #pragma GCC poison X
+    if (CurPPLexer) CurPPLexer->LexingRawMode = true;
+    LexUnexpandedToken(Tok);
+    if (CurPPLexer) CurPPLexer->LexingRawMode = false;
+
+    // If we reached the end of line, we're done.
+    if (Tok.is(tok::eom)) return;
+
+    // Can only poison identifiers.
+    if (Tok.isNot(tok::identifier)) {
+      Diag(Tok, diag::err_pp_invalid_poison);
+      return;
+    }
+
+    // Look up the identifier info for the token.  We disabled identifier lookup
+    // by saying we're skipping contents, so we need to do this manually.
+    IdentifierInfo *II = LookUpIdentifierInfo(Tok);
+
+    // Already poisoned.
+    if (II->isPoisoned()) continue;
+
+    // If this is a macro identifier, emit a warning.
+    if (II->hasMacroDefinition())
+      Diag(Tok, diag::pp_poisoning_existing_macro);
+
+    // Finally, poison it!
+    II->setIsPoisoned();
+  }
+}
+
+/// HandlePragmaSystemHeader - Implement #pragma GCC system_header.  We know
+/// that the whole directive has been parsed.
+void Preprocessor::HandlePragmaSystemHeader(Token &SysHeaderTok) {
+  if (isInPrimaryFile()) {
+    Diag(SysHeaderTok, diag::pp_pragma_sysheader_in_main_file);
+    return;
+  }
+
+  // Get the current file lexer we're looking at.  Ignore _Pragma 'files' etc.
+  PreprocessorLexer *TheLexer = getCurrentFileLexer();
+
+  // Mark the file as a system header.
+  HeaderInfo.MarkFileSystemHeader(TheLexer->getFileEntry());
+
+
+  PresumedLoc PLoc = SourceMgr.getPresumedLoc(SysHeaderTok.getLocation());
+  unsigned FilenameLen = strlen(PLoc.getFilename());
+  unsigned FilenameID = SourceMgr.getLineTableFilenameID(PLoc.getFilename(),
+                                                         FilenameLen);
+
+  // Emit a line marker.  This will change any source locations from this point
+  // forward to realize they are in a system header.
+  // Create a line note with this information.
+  SourceMgr.AddLineNote(SysHeaderTok.getLocation(), PLoc.getLine(), FilenameID,
+                        false, false, true, false);
+
+  // Notify the client, if desired, that we are in a new source file.
+  if (Callbacks)
+    Callbacks->FileChanged(SysHeaderTok.getLocation(),
+                           PPCallbacks::SystemHeaderPragma, SrcMgr::C_System);
+}
+
+/// HandlePragmaDependency - Handle #pragma GCC dependency "foo" blah.
+///
+void Preprocessor::HandlePragmaDependency(Token &DependencyTok) {
+  Token FilenameTok;
+  CurPPLexer->LexIncludeFilename(FilenameTok);
+
+  // If the token kind is EOM, the error has already been diagnosed.
+  if (FilenameTok.is(tok::eom))
+    return;
+
+  // Reserve a buffer to get the spelling.
+  llvm::SmallString<128> FilenameBuffer;
+  bool Invalid = false;
+  llvm::StringRef Filename = getSpelling(FilenameTok, FilenameBuffer, &Invalid);
+  if (Invalid)
+    return;
+
+  bool isAngled =
+    GetIncludeFilenameSpelling(FilenameTok.getLocation(), Filename);
+  // If GetIncludeFilenameSpelling set the start ptr to null, there was an
+  // error.
+  if (Filename.empty())
+    return;
+
+  // Search include directories for this file.
+  const DirectoryLookup *CurDir;
+  const FileEntry *File = LookupFile(Filename, isAngled, 0, CurDir);
+  if (File == 0) {
+    Diag(FilenameTok, diag::err_pp_file_not_found) << Filename;
+    return;
+  }
+
+  const FileEntry *CurFile = getCurrentFileLexer()->getFileEntry();
+
+  // If this file is older than the file it depends on, emit a diagnostic.
+  if (CurFile && CurFile->getModificationTime() < File->getModificationTime()) {
+    // Lex tokens at the end of the message and include them in the message.
+    std::string Message;
+    Lex(DependencyTok);
+    while (DependencyTok.isNot(tok::eom)) {
+      Message += getSpelling(DependencyTok) + " ";
+      Lex(DependencyTok);
+    }
+
+    Message.erase(Message.end()-1);
+    Diag(FilenameTok, diag::pp_out_of_date_dependency) << Message;
+  }
+}
+
+/// HandlePragmaComment - Handle the microsoft #pragma comment extension.  The
+/// syntax is:
+///   #pragma comment(linker, "foo")
+/// 'linker' is one of five identifiers: compiler, exestr, lib, linker, user.
+/// "foo" is a string, which is fully macro expanded, and permits string
+/// concatenation, embedded escape characters etc.  See MSDN for more details.
+void Preprocessor::HandlePragmaComment(Token &Tok) {
+  SourceLocation CommentLoc = Tok.getLocation();
+  Lex(Tok);
+  if (Tok.isNot(tok::l_paren)) {
+    Diag(CommentLoc, diag::err_pragma_comment_malformed);
+    return;
+  }
+
+  // Read the identifier.
+  Lex(Tok);
+  if (Tok.isNot(tok::identifier)) {
+    Diag(CommentLoc, diag::err_pragma_comment_malformed);
+    return;
+  }
+
+  // Verify that this is one of the 5 whitelisted options.
+  // FIXME: warn that 'exestr' is deprecated.
+  const IdentifierInfo *II = Tok.getIdentifierInfo();
+  if (!II->isStr("compiler") && !II->isStr("exestr") && !II->isStr("lib") &&
+      !II->isStr("linker") && !II->isStr("user")) {
+    Diag(Tok.getLocation(), diag::err_pragma_comment_unknown_kind);
+    return;
+  }
+
+  // Read the optional string if present.
+  Lex(Tok);
+  std::string ArgumentString;
+  if (Tok.is(tok::comma)) {
+    Lex(Tok); // eat the comma.
+
+    // We need at least one string.
+    if (Tok.isNot(tok::string_literal)) {
+      Diag(Tok.getLocation(), diag::err_pragma_comment_malformed);
+      return;
+    }
+
+    // String concatenation allows multiple strings, which can even come from
+    // macro expansion.
+    // "foo " "bar" "Baz"
+    llvm::SmallVector<Token, 4> StrToks;
+    while (Tok.is(tok::string_literal)) {
+      StrToks.push_back(Tok);
+      Lex(Tok);
+    }
+
+    // Concatenate and parse the strings.
+    StringLiteralParser Literal(&StrToks[0], StrToks.size(), *this);
+    assert(!Literal.AnyWide && "Didn't allow wide strings in");
+    if (Literal.hadError)
+      return;
+    if (Literal.Pascal) {
+      Diag(StrToks[0].getLocation(), diag::err_pragma_comment_malformed);
+      return;
+    }
+
+    ArgumentString = std::string(Literal.GetString(),
+                                 Literal.GetString()+Literal.GetStringLength());
+  }
+
+  // FIXME: If the kind is "compiler" warn if the string is present (it is
+  // ignored).
+  // FIXME: 'lib' requires a comment string.
+  // FIXME: 'linker' requires a comment string, and has a specific list of
+  // things that are allowable.
+
+  if (Tok.isNot(tok::r_paren)) {
+    Diag(Tok.getLocation(), diag::err_pragma_comment_malformed);
+    return;
+  }
+  Lex(Tok);  // eat the r_paren.
+
+  if (Tok.isNot(tok::eom)) {
+    Diag(Tok.getLocation(), diag::err_pragma_comment_malformed);
+    return;
+  }
+
+  // If the pragma is lexically sound, notify any interested PPCallbacks.
+  if (Callbacks)
+    Callbacks->PragmaComment(CommentLoc, II, ArgumentString);
+}
+
+
+
+
+/// AddPragmaHandler - Add the specified pragma handler to the preprocessor.
+/// If 'Namespace' is non-null, then it is a token required to exist on the
+/// pragma line before the pragma string starts, e.g. "STDC" or "GCC".
+void Preprocessor::AddPragmaHandler(const char *Namespace,
+                                    PragmaHandler *Handler) {
+  PragmaNamespace *InsertNS = PragmaHandlers;
+
+  // If this is specified to be in a namespace, step down into it.
+  if (Namespace) {
+    IdentifierInfo *NSID = getIdentifierInfo(Namespace);
+
+    // If there is already a pragma handler with the name of this namespace,
+    // we either have an error (directive with the same name as a namespace) or
+    // we already have the namespace to insert into.
+    if (PragmaHandler *Existing = PragmaHandlers->FindHandler(NSID)) {
+      InsertNS = Existing->getIfNamespace();
+      assert(InsertNS != 0 && "Cannot have a pragma namespace and pragma"
+             " handler with the same name!");
+    } else {
+      // Otherwise, this namespace doesn't exist yet, create and insert the
+      // handler for it.
+      InsertNS = new PragmaNamespace(NSID);
+      PragmaHandlers->AddPragma(InsertNS);
+    }
+  }
+
+  // Check to make sure we don't already have a pragma for this identifier.
+  assert(!InsertNS->FindHandler(Handler->getName()) &&
+         "Pragma handler already exists for this identifier!");
+  InsertNS->AddPragma(Handler);
+}
+
+/// RemovePragmaHandler - Remove the specific pragma handler from the
+/// preprocessor. If \arg Namespace is non-null, then it should be the
+/// namespace that \arg Handler was added to. It is an error to remove
+/// a handler that has not been registered.
+void Preprocessor::RemovePragmaHandler(const char *Namespace,
+                                       PragmaHandler *Handler) {
+  PragmaNamespace *NS = PragmaHandlers;
+
+  // If this is specified to be in a namespace, step down into it.
+  if (Namespace) {
+    IdentifierInfo *NSID = getIdentifierInfo(Namespace);
+    PragmaHandler *Existing = PragmaHandlers->FindHandler(NSID);
+    assert(Existing && "Namespace containing handler does not exist!");
+
+    NS = Existing->getIfNamespace();
+    assert(NS && "Invalid namespace, registered as a regular pragma handler!");
+  }
+
+  NS->RemovePragmaHandler(Handler);
+
+  // If this is a non-default namespace and it is now empty, remove
+  // it.
+  if (NS != PragmaHandlers && NS->IsEmpty())
+    PragmaHandlers->RemovePragmaHandler(NS);
+}
+
+namespace {
+/// PragmaOnceHandler - "#pragma once" marks the file as atomically included.
+struct PragmaOnceHandler : public PragmaHandler {
+  PragmaOnceHandler(const IdentifierInfo *OnceID) : PragmaHandler(OnceID) {}
+  virtual void HandlePragma(Preprocessor &PP, Token &OnceTok) {
+    PP.CheckEndOfDirective("pragma once");
+    PP.HandlePragmaOnce(OnceTok);
+  }
+};
+
+/// PragmaMarkHandler - "#pragma mark ..." is ignored by the compiler, and the
+/// rest of the line is not lexed.
+struct PragmaMarkHandler : public PragmaHandler {
+  PragmaMarkHandler(const IdentifierInfo *MarkID) : PragmaHandler(MarkID) {}
+  virtual void HandlePragma(Preprocessor &PP, Token &MarkTok) {
+    PP.HandlePragmaMark();
+  }
+};
+
+/// PragmaPoisonHandler - "#pragma poison x" marks x as not usable.
+struct PragmaPoisonHandler : public PragmaHandler {
+  PragmaPoisonHandler(const IdentifierInfo *ID) : PragmaHandler(ID) {}
+  virtual void HandlePragma(Preprocessor &PP, Token &PoisonTok) {
+    PP.HandlePragmaPoison(PoisonTok);
+  }
+};
+
+/// PragmaSystemHeaderHandler - "#pragma system_header" marks the current file
+/// as a system header, which silences warnings in it.
+struct PragmaSystemHeaderHandler : public PragmaHandler {
+  PragmaSystemHeaderHandler(const IdentifierInfo *ID) : PragmaHandler(ID) {}
+  virtual void HandlePragma(Preprocessor &PP, Token &SHToken) {
+    PP.HandlePragmaSystemHeader(SHToken);
+    PP.CheckEndOfDirective("pragma");
+  }
+};
+struct PragmaDependencyHandler : public PragmaHandler {
+  PragmaDependencyHandler(const IdentifierInfo *ID) : PragmaHandler(ID) {}
+  virtual void HandlePragma(Preprocessor &PP, Token &DepToken) {
+    PP.HandlePragmaDependency(DepToken);
+  }
+};
+
+/// PragmaDiagnosticHandler - e.g. '#pragma GCC diagnostic ignored "-Wformat"'
+/// Since clang's diagnostic supports extended functionality beyond GCC's
+/// the constructor takes a clangMode flag to tell it whether or not to allow
+/// clang's extended functionality, or whether to reject it.
+struct PragmaDiagnosticHandler : public PragmaHandler {
+private:
+  const bool ClangMode;
+public:
+  PragmaDiagnosticHandler(const IdentifierInfo *ID,
+                          const bool clangMode) : PragmaHandler(ID),
+                                                  ClangMode(clangMode) {}
+  virtual void HandlePragma(Preprocessor &PP, Token &DiagToken) {
+    Token Tok;
+    PP.LexUnexpandedToken(Tok);
+    if (Tok.isNot(tok::identifier)) {
+      unsigned Diag = ClangMode ? diag::warn_pragma_diagnostic_clang_invalid
+                                 : diag::warn_pragma_diagnostic_gcc_invalid;
+      PP.Diag(Tok, Diag);
+      return;
+    }
+    IdentifierInfo *II = Tok.getIdentifierInfo();
+
+    diag::Mapping Map;
+    if (II->isStr("warning"))
+      Map = diag::MAP_WARNING;
+    else if (II->isStr("error"))
+      Map = diag::MAP_ERROR;
+    else if (II->isStr("ignored"))
+      Map = diag::MAP_IGNORE;
+    else if (II->isStr("fatal"))
+      Map = diag::MAP_FATAL;
+    else if (ClangMode) {
+      if (II->isStr("pop")) {
+        if (!PP.getDiagnostics().popMappings())
+          PP.Diag(Tok, diag::warn_pragma_diagnostic_clang_cannot_ppp);
+        return;
+      }
+
+      if (II->isStr("push")) {
+        PP.getDiagnostics().pushMappings();
+        return;
+      }
+
+      PP.Diag(Tok, diag::warn_pragma_diagnostic_clang_invalid);
+      return;
+    } else {
+      PP.Diag(Tok, diag::warn_pragma_diagnostic_gcc_invalid);
+      return;
+    }
+
+    PP.LexUnexpandedToken(Tok);
+
+    // We need at least one string.
+    if (Tok.isNot(tok::string_literal)) {
+      PP.Diag(Tok.getLocation(), diag::warn_pragma_diagnostic_invalid_token);
+      return;
+    }
+
+    // String concatenation allows multiple strings, which can even come from
+    // macro expansion.
+    // "foo " "bar" "Baz"
+    llvm::SmallVector<Token, 4> StrToks;
+    while (Tok.is(tok::string_literal)) {
+      StrToks.push_back(Tok);
+      PP.LexUnexpandedToken(Tok);
+    }
+
+    if (Tok.isNot(tok::eom)) {
+      PP.Diag(Tok.getLocation(), diag::warn_pragma_diagnostic_invalid_token);
+      return;
+    }
+
+    // Concatenate and parse the strings.
+    StringLiteralParser Literal(&StrToks[0], StrToks.size(), PP);
+    assert(!Literal.AnyWide && "Didn't allow wide strings in");
+    if (Literal.hadError)
+      return;
+    if (Literal.Pascal) {
+      unsigned Diag = ClangMode ? diag::warn_pragma_diagnostic_clang_invalid
+                                 : diag::warn_pragma_diagnostic_gcc_invalid;
+      PP.Diag(Tok, Diag);
+      return;
+    }
+
+    std::string WarningName(Literal.GetString(),
+                            Literal.GetString()+Literal.GetStringLength());
+
+    if (WarningName.size() < 3 || WarningName[0] != '-' ||
+        WarningName[1] != 'W') {
+      PP.Diag(StrToks[0].getLocation(),
+              diag::warn_pragma_diagnostic_invalid_option);
+      return;
+    }
+
+    if (PP.getDiagnostics().setDiagnosticGroupMapping(WarningName.c_str()+2,
+                                                      Map))
+      PP.Diag(StrToks[0].getLocation(),
+              diag::warn_pragma_diagnostic_unknown_warning) << WarningName;
+  }
+};
+
+/// PragmaCommentHandler - "#pragma comment ...".
+struct PragmaCommentHandler : public PragmaHandler {
+  PragmaCommentHandler(const IdentifierInfo *ID) : PragmaHandler(ID) {}
+  virtual void HandlePragma(Preprocessor &PP, Token &CommentTok) {
+    PP.HandlePragmaComment(CommentTok);
+  }
+};
+
+// Pragma STDC implementations.
+
+enum STDCSetting {
+  STDC_ON, STDC_OFF, STDC_DEFAULT, STDC_INVALID
+};
+
+static STDCSetting LexOnOffSwitch(Preprocessor &PP) {
+  Token Tok;
+  PP.LexUnexpandedToken(Tok);
+
+  if (Tok.isNot(tok::identifier)) {
+    PP.Diag(Tok, diag::ext_stdc_pragma_syntax);
+    return STDC_INVALID;
+  }
+  IdentifierInfo *II = Tok.getIdentifierInfo();
+  STDCSetting Result;
+  if (II->isStr("ON"))
+    Result = STDC_ON;
+  else if (II->isStr("OFF"))
+    Result = STDC_OFF;
+  else if (II->isStr("DEFAULT"))
+    Result = STDC_DEFAULT;
+  else {
+    PP.Diag(Tok, diag::ext_stdc_pragma_syntax);
+    return STDC_INVALID;
+  }
+
+  // Verify that this is followed by EOM.
+  PP.LexUnexpandedToken(Tok);
+  if (Tok.isNot(tok::eom))
+    PP.Diag(Tok, diag::ext_stdc_pragma_syntax_eom);
+  return Result;
+}
+
+/// PragmaSTDC_FP_CONTRACTHandler - "#pragma STDC FP_CONTRACT ...".
+struct PragmaSTDC_FP_CONTRACTHandler : public PragmaHandler {
+  PragmaSTDC_FP_CONTRACTHandler(const IdentifierInfo *ID) : PragmaHandler(ID) {}
+  virtual void HandlePragma(Preprocessor &PP, Token &Tok) {
+    // We just ignore the setting of FP_CONTRACT. Since we don't do contractions
+    // at all, our default is OFF and setting it to ON is an optimization hint
+    // we can safely ignore.  When we support -ffma or something, we would need
+    // to diagnose that we are ignoring FMA.
+    LexOnOffSwitch(PP);
+  }
+};
+
+/// PragmaSTDC_FENV_ACCESSHandler - "#pragma STDC FENV_ACCESS ...".
+struct PragmaSTDC_FENV_ACCESSHandler : public PragmaHandler {
+  PragmaSTDC_FENV_ACCESSHandler(const IdentifierInfo *ID) : PragmaHandler(ID) {}
+  virtual void HandlePragma(Preprocessor &PP, Token &Tok) {
+    if (LexOnOffSwitch(PP) == STDC_ON)
+      PP.Diag(Tok, diag::warn_stdc_fenv_access_not_supported);
+  }
+};
+
+/// PragmaSTDC_CX_LIMITED_RANGEHandler - "#pragma STDC CX_LIMITED_RANGE ...".
+struct PragmaSTDC_CX_LIMITED_RANGEHandler : public PragmaHandler {
+  PragmaSTDC_CX_LIMITED_RANGEHandler(const IdentifierInfo *ID)
+    : PragmaHandler(ID) {}
+  virtual void HandlePragma(Preprocessor &PP, Token &Tok) {
+    LexOnOffSwitch(PP);
+  }
+};
+
+/// PragmaSTDC_UnknownHandler - "#pragma STDC ...".
+struct PragmaSTDC_UnknownHandler : public PragmaHandler {
+  PragmaSTDC_UnknownHandler() : PragmaHandler(0) {}
+  virtual void HandlePragma(Preprocessor &PP, Token &UnknownTok) {
+    // C99 6.10.6p2, unknown forms are not allowed.
+    PP.Diag(UnknownTok, diag::ext_stdc_pragma_ignored);
+  }
+};
+
+}  // end anonymous namespace
+
+
+/// RegisterBuiltinPragmas - Install the standard preprocessor pragmas:
+/// #pragma GCC poison/system_header/dependency and #pragma once.
+void Preprocessor::RegisterBuiltinPragmas() {
+  AddPragmaHandler(0, new PragmaOnceHandler(getIdentifierInfo("once")));
+  AddPragmaHandler(0, new PragmaMarkHandler(getIdentifierInfo("mark")));
+
+  // #pragma GCC ...
+  AddPragmaHandler("GCC", new PragmaPoisonHandler(getIdentifierInfo("poison")));
+  AddPragmaHandler("GCC", new PragmaSystemHeaderHandler(
+                                          getIdentifierInfo("system_header")));
+  AddPragmaHandler("GCC", new PragmaDependencyHandler(
+                                          getIdentifierInfo("dependency")));
+  AddPragmaHandler("GCC", new PragmaDiagnosticHandler(
+                                              getIdentifierInfo("diagnostic"),
+                                              false));
+  // #pragma clang ...
+  AddPragmaHandler("clang", new PragmaPoisonHandler(
+                                          getIdentifierInfo("poison")));
+  AddPragmaHandler("clang", new PragmaSystemHeaderHandler(
+                                          getIdentifierInfo("system_header")));
+  AddPragmaHandler("clang", new PragmaDependencyHandler(
+                                          getIdentifierInfo("dependency")));
+  AddPragmaHandler("clang", new PragmaDiagnosticHandler(
+                                          getIdentifierInfo("diagnostic"),
+                                          true));
+
+  AddPragmaHandler("STDC", new PragmaSTDC_FP_CONTRACTHandler(
+                                             getIdentifierInfo("FP_CONTRACT")));
+  AddPragmaHandler("STDC", new PragmaSTDC_FENV_ACCESSHandler(
+                                             getIdentifierInfo("FENV_ACCESS")));
+  AddPragmaHandler("STDC", new PragmaSTDC_CX_LIMITED_RANGEHandler(
+                                        getIdentifierInfo("CX_LIMITED_RANGE")));
+  AddPragmaHandler("STDC", new PragmaSTDC_UnknownHandler());
+
+  // MS extensions.
+  if (Features.Microsoft)
+    AddPragmaHandler(0, new PragmaCommentHandler(getIdentifierInfo("comment")));
+}
diff --git a/lib/Lex/PreprocessingRecord.cpp b/lib/Lex/PreprocessingRecord.cpp
new file mode 100644
index 0000000..6966c38
--- /dev/null
+++ b/lib/Lex/PreprocessingRecord.cpp
@@ -0,0 +1,128 @@
+//===--- PreprocessingRecord.cpp - Record of Preprocessing ------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements the PreprocessingRecord class, which maintains a record
+//  of what occurred during preprocessing, and its helpers.
+//
+//===----------------------------------------------------------------------===//
+#include "clang/Lex/PreprocessingRecord.h"
+#include "clang/Lex/MacroInfo.h"
+#include "clang/Lex/Token.h"
+
+using namespace clang;
+
+ExternalPreprocessingRecordSource::~ExternalPreprocessingRecordSource() { }
+
+void PreprocessingRecord::MaybeLoadPreallocatedEntities() const {
+  if (!ExternalSource || LoadedPreallocatedEntities)
+    return;
+  
+  LoadedPreallocatedEntities = true;
+  ExternalSource->ReadPreprocessedEntities();
+}
+
+PreprocessingRecord::PreprocessingRecord()
+  : ExternalSource(0), NumPreallocatedEntities(0), 
+    LoadedPreallocatedEntities(false)
+{
+}
+
+PreprocessingRecord::iterator 
+PreprocessingRecord::begin(bool OnlyLocalEntities) {
+  if (OnlyLocalEntities)
+    return PreprocessedEntities.begin() + NumPreallocatedEntities;
+  
+  MaybeLoadPreallocatedEntities();
+  return PreprocessedEntities.begin();
+}
+
+PreprocessingRecord::iterator PreprocessingRecord::end(bool OnlyLocalEntities) {
+  if (!OnlyLocalEntities)
+    MaybeLoadPreallocatedEntities();
+  
+  return PreprocessedEntities.end();
+}
+
+PreprocessingRecord::const_iterator 
+PreprocessingRecord::begin(bool OnlyLocalEntities) const {
+  if (OnlyLocalEntities)
+    return PreprocessedEntities.begin() + NumPreallocatedEntities;
+  
+  MaybeLoadPreallocatedEntities();
+  return PreprocessedEntities.begin();
+}
+
+PreprocessingRecord::const_iterator 
+PreprocessingRecord::end(bool OnlyLocalEntities) const {
+  if (!OnlyLocalEntities)
+    MaybeLoadPreallocatedEntities();
+  
+  return PreprocessedEntities.end();
+}
+
+void PreprocessingRecord::addPreprocessedEntity(PreprocessedEntity *Entity) {
+  PreprocessedEntities.push_back(Entity);
+}
+
+void PreprocessingRecord::SetExternalSource(
+                                    ExternalPreprocessingRecordSource &Source,
+                                            unsigned NumPreallocatedEntities) {
+  assert(!ExternalSource &&
+         "Preprocessing record already has an external source");
+  ExternalSource = &Source;
+  this->NumPreallocatedEntities = NumPreallocatedEntities;
+  PreprocessedEntities.insert(PreprocessedEntities.begin(), 
+                              NumPreallocatedEntities, 0);
+}
+
+void PreprocessingRecord::SetPreallocatedEntity(unsigned Index, 
+                                                PreprocessedEntity *Entity) {
+  assert(Index < NumPreallocatedEntities &&"Out-of-bounds preallocated entity");
+  PreprocessedEntities[Index] = Entity;
+}
+
+void PreprocessingRecord::RegisterMacroDefinition(MacroInfo *Macro, 
+                                                  MacroDefinition *MD) {
+  MacroDefinitions[Macro] = MD;
+}
+
+MacroDefinition *PreprocessingRecord::findMacroDefinition(const MacroInfo *MI) {
+  llvm::DenseMap<const MacroInfo *, MacroDefinition *>::iterator Pos
+    = MacroDefinitions.find(MI);
+  if (Pos == MacroDefinitions.end())
+    return 0;
+  
+  return Pos->second;
+}
+
+void PreprocessingRecord::MacroExpands(const Token &Id, const MacroInfo* MI) {
+  if (MacroDefinition *Def = findMacroDefinition(MI))
+    PreprocessedEntities.push_back(
+                       new (*this) MacroInstantiation(Id.getIdentifierInfo(),
+                                                      Id.getLocation(),
+                                                      Def));
+}
+
+void PreprocessingRecord::MacroDefined(const IdentifierInfo *II, 
+                                       const MacroInfo *MI) {
+  SourceRange R(MI->getDefinitionLoc(), MI->getDefinitionEndLoc());
+  MacroDefinition *Def
+    = new (*this) MacroDefinition(II, MI->getDefinitionLoc(), R);
+  MacroDefinitions[MI] = Def;
+  PreprocessedEntities.push_back(Def);
+}
+
+void PreprocessingRecord::MacroUndefined(const IdentifierInfo *II, 
+                                         const MacroInfo *MI) {
+  llvm::DenseMap<const MacroInfo *, MacroDefinition *>::iterator Pos
+    = MacroDefinitions.find(MI);
+  if (Pos != MacroDefinitions.end())
+    MacroDefinitions.erase(Pos);
+}
+
diff --git a/lib/Lex/Preprocessor.cpp b/lib/Lex/Preprocessor.cpp
new file mode 100644
index 0000000..ce6d9ab
--- /dev/null
+++ b/lib/Lex/Preprocessor.cpp
@@ -0,0 +1,640 @@
+//===--- Preprocess.cpp - C Language Family Preprocessor Implementation ---===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements the Preprocessor interface.
+//
+//===----------------------------------------------------------------------===//
+//
+// Options to support:
+//   -H       - Print the name of each header file used.
+//   -d[DNI] - Dump various things.
+//   -fworking-directory - #line's with preprocessor's working dir.
+//   -fpreprocessed
+//   -dependency-file,-M,-MM,-MF,-MG,-MP,-MT,-MQ,-MD,-MMD
+//   -W*
+//   -w
+//
+// Messages to emit:
+//   "Multiple include guards may be useful for:\n"
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Lex/Preprocessor.h"
+#include "MacroArgs.h"
+#include "clang/Lex/ExternalPreprocessorSource.h"
+#include "clang/Lex/HeaderSearch.h"
+#include "clang/Lex/MacroInfo.h"
+#include "clang/Lex/Pragma.h"
+#include "clang/Lex/PreprocessingRecord.h"
+#include "clang/Lex/ScratchBuffer.h"
+#include "clang/Lex/LexDiagnostic.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/TargetInfo.h"
+#include "llvm/ADT/APFloat.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace clang;
+
+//===----------------------------------------------------------------------===//
+ExternalPreprocessorSource::~ExternalPreprocessorSource() { }
+
+Preprocessor::Preprocessor(Diagnostic &diags, const LangOptions &opts,
+                           const TargetInfo &target, SourceManager &SM,
+                           HeaderSearch &Headers,
+                           IdentifierInfoLookup* IILookup,
+                           bool OwnsHeaders)
+  : Diags(&diags), Features(opts), Target(target),FileMgr(Headers.getFileMgr()),
+    SourceMgr(SM), HeaderInfo(Headers), ExternalSource(0),
+    Identifiers(opts, IILookup), BuiltinInfo(Target), CodeCompletionFile(0),
+    CurPPLexer(0), CurDirLookup(0), Callbacks(0), MacroArgCache(0), Record(0) {
+  ScratchBuf = new ScratchBuffer(SourceMgr);
+  CounterValue = 0; // __COUNTER__ starts at 0.
+  OwnsHeaderSearch = OwnsHeaders;
+
+  // Clear stats.
+  NumDirectives = NumDefined = NumUndefined = NumPragma = 0;
+  NumIf = NumElse = NumEndif = 0;
+  NumEnteredSourceFiles = 0;
+  NumMacroExpanded = NumFnMacroExpanded = NumBuiltinMacroExpanded = 0;
+  NumFastMacroExpanded = NumTokenPaste = NumFastTokenPaste = 0;
+  MaxIncludeStackDepth = 0;
+  NumSkipped = 0;
+
+  // Default to discarding comments.
+  KeepComments = false;
+  KeepMacroComments = false;
+
+  // Macro expansion is enabled.
+  DisableMacroExpansion = false;
+  InMacroArgs = false;
+  NumCachedTokenLexers = 0;
+
+  CachedLexPos = 0;
+
+  // We haven't read anything from the external source.
+  ReadMacrosFromExternalSource = false;
+
+  // "Poison" __VA_ARGS__, which can only appear in the expansion of a macro.
+  // This gets unpoisoned where it is allowed.
+  (Ident__VA_ARGS__ = getIdentifierInfo("__VA_ARGS__"))->setIsPoisoned();
+
+  // Initialize the pragma handlers.
+  PragmaHandlers = new PragmaNamespace(0);
+  RegisterBuiltinPragmas();
+
+  // Initialize builtin macros like __LINE__ and friends.
+  RegisterBuiltinMacros();
+}
+
+Preprocessor::~Preprocessor() {
+  assert(BacktrackPositions.empty() && "EnableBacktrack/Backtrack imbalance!");
+
+  while (!IncludeMacroStack.empty()) {
+    delete IncludeMacroStack.back().TheLexer;
+    delete IncludeMacroStack.back().TheTokenLexer;
+    IncludeMacroStack.pop_back();
+  }
+
+  // Free any macro definitions.
+  for (llvm::DenseMap<IdentifierInfo*, MacroInfo*>::iterator I =
+       Macros.begin(), E = Macros.end(); I != E; ++I) {
+    // We don't need to free the MacroInfo objects directly.  These
+    // will be released when the BumpPtrAllocator 'BP' object gets
+    // destroyed.  We still need to run the dtor, however, to free
+    // memory alocated by MacroInfo.
+    I->second->Destroy(BP);
+    I->first->setHasMacroDefinition(false);
+  }
+
+  // Free any cached macro expanders.
+  for (unsigned i = 0, e = NumCachedTokenLexers; i != e; ++i)
+    delete TokenLexerCache[i];
+
+  // Free any cached MacroArgs.
+  for (MacroArgs *ArgList = MacroArgCache; ArgList; )
+    ArgList = ArgList->deallocate();
+
+  // Release pragma information.
+  delete PragmaHandlers;
+
+  // Delete the scratch buffer info.
+  delete ScratchBuf;
+
+  // Delete the header search info, if we own it.
+  if (OwnsHeaderSearch)
+    delete &HeaderInfo;
+
+  delete Callbacks;
+}
+
+void Preprocessor::setPTHManager(PTHManager* pm) {
+  PTH.reset(pm);
+  FileMgr.addStatCache(PTH->createStatCache());
+}
+
+void Preprocessor::DumpToken(const Token &Tok, bool DumpFlags) const {
+  llvm::errs() << tok::getTokenName(Tok.getKind()) << " '"
+               << getSpelling(Tok) << "'";
+
+  if (!DumpFlags) return;
+
+  llvm::errs() << "\t";
+  if (Tok.isAtStartOfLine())
+    llvm::errs() << " [StartOfLine]";
+  if (Tok.hasLeadingSpace())
+    llvm::errs() << " [LeadingSpace]";
+  if (Tok.isExpandDisabled())
+    llvm::errs() << " [ExpandDisabled]";
+  if (Tok.needsCleaning()) {
+    const char *Start = SourceMgr.getCharacterData(Tok.getLocation());
+    llvm::errs() << " [UnClean='" << std::string(Start, Start+Tok.getLength())
+                 << "']";
+  }
+
+  llvm::errs() << "\tLoc=<";
+  DumpLocation(Tok.getLocation());
+  llvm::errs() << ">";
+}
+
+void Preprocessor::DumpLocation(SourceLocation Loc) const {
+  Loc.dump(SourceMgr);
+}
+
+void Preprocessor::DumpMacro(const MacroInfo &MI) const {
+  llvm::errs() << "MACRO: ";
+  for (unsigned i = 0, e = MI.getNumTokens(); i != e; ++i) {
+    DumpToken(MI.getReplacementToken(i));
+    llvm::errs() << "  ";
+  }
+  llvm::errs() << "\n";
+}
+
+void Preprocessor::PrintStats() {
+  llvm::errs() << "\n*** Preprocessor Stats:\n";
+  llvm::errs() << NumDirectives << " directives found:\n";
+  llvm::errs() << "  " << NumDefined << " #define.\n";
+  llvm::errs() << "  " << NumUndefined << " #undef.\n";
+  llvm::errs() << "  #include/#include_next/#import:\n";
+  llvm::errs() << "    " << NumEnteredSourceFiles << " source files entered.\n";
+  llvm::errs() << "    " << MaxIncludeStackDepth << " max include stack depth\n";
+  llvm::errs() << "  " << NumIf << " #if/#ifndef/#ifdef.\n";
+  llvm::errs() << "  " << NumElse << " #else/#elif.\n";
+  llvm::errs() << "  " << NumEndif << " #endif.\n";
+  llvm::errs() << "  " << NumPragma << " #pragma.\n";
+  llvm::errs() << NumSkipped << " #if/#ifndef#ifdef regions skipped\n";
+
+  llvm::errs() << NumMacroExpanded << "/" << NumFnMacroExpanded << "/"
+             << NumBuiltinMacroExpanded << " obj/fn/builtin macros expanded, "
+             << NumFastMacroExpanded << " on the fast path.\n";
+  llvm::errs() << (NumFastTokenPaste+NumTokenPaste)
+             << " token paste (##) operations performed, "
+             << NumFastTokenPaste << " on the fast path.\n";
+}
+
+Preprocessor::macro_iterator
+Preprocessor::macro_begin(bool IncludeExternalMacros) const {
+  if (IncludeExternalMacros && ExternalSource &&
+      !ReadMacrosFromExternalSource) {
+    ReadMacrosFromExternalSource = true;
+    ExternalSource->ReadDefinedMacros();
+  }
+
+  return Macros.begin();
+}
+
+Preprocessor::macro_iterator
+Preprocessor::macro_end(bool IncludeExternalMacros) const {
+  if (IncludeExternalMacros && ExternalSource &&
+      !ReadMacrosFromExternalSource) {
+    ReadMacrosFromExternalSource = true;
+    ExternalSource->ReadDefinedMacros();
+  }
+
+  return Macros.end();
+}
+
+bool Preprocessor::SetCodeCompletionPoint(const FileEntry *File,
+                                          unsigned TruncateAtLine,
+                                          unsigned TruncateAtColumn) {
+  using llvm::MemoryBuffer;
+
+  CodeCompletionFile = File;
+
+  // Okay to clear out the code-completion point by passing NULL.
+  if (!CodeCompletionFile)
+    return false;
+
+  // Load the actual file's contents.
+  bool Invalid = false;
+  const MemoryBuffer *Buffer = SourceMgr.getMemoryBufferForFile(File, &Invalid);
+  if (Invalid)
+    return true;
+
+  // Find the byte position of the truncation point.
+  const char *Position = Buffer->getBufferStart();
+  for (unsigned Line = 1; Line < TruncateAtLine; ++Line) {
+    for (; *Position; ++Position) {
+      if (*Position != '\r' && *Position != '\n')
+        continue;
+
+      // Eat \r\n or \n\r as a single line.
+      if ((Position[1] == '\r' || Position[1] == '\n') &&
+          Position[0] != Position[1])
+        ++Position;
+      ++Position;
+      break;
+    }
+  }
+
+  Position += TruncateAtColumn - 1;
+
+  // Truncate the buffer.
+  if (Position < Buffer->getBufferEnd()) {
+    llvm::StringRef Data(Buffer->getBufferStart(),
+                         Position-Buffer->getBufferStart());
+    MemoryBuffer *TruncatedBuffer
+      = MemoryBuffer::getMemBufferCopy(Data, Buffer->getBufferIdentifier());
+    SourceMgr.overrideFileContents(File, TruncatedBuffer);
+  }
+
+  return false;
+}
+
+bool Preprocessor::isCodeCompletionFile(SourceLocation FileLoc) const {
+  return CodeCompletionFile && FileLoc.isFileID() &&
+    SourceMgr.getFileEntryForID(SourceMgr.getFileID(FileLoc))
+      == CodeCompletionFile;
+}
+
+//===----------------------------------------------------------------------===//
+// Token Spelling
+//===----------------------------------------------------------------------===//
+
+/// getSpelling() - Return the 'spelling' of this token.  The spelling of a
+/// token are the characters used to represent the token in the source file
+/// after trigraph expansion and escaped-newline folding.  In particular, this
+/// wants to get the true, uncanonicalized, spelling of things like digraphs
+/// UCNs, etc.
+std::string Preprocessor::getSpelling(const Token &Tok,
+                                      const SourceManager &SourceMgr,
+                                      const LangOptions &Features, 
+                                      bool *Invalid) {
+  assert((int)Tok.getLength() >= 0 && "Token character range is bogus!");
+
+  // If this token contains nothing interesting, return it directly.
+  bool CharDataInvalid = false;
+  const char* TokStart = SourceMgr.getCharacterData(Tok.getLocation(), 
+                                                    &CharDataInvalid);
+  if (Invalid)
+    *Invalid = CharDataInvalid;
+  if (CharDataInvalid)
+    return std::string();
+
+  if (!Tok.needsCleaning())
+    return std::string(TokStart, TokStart+Tok.getLength());
+
+  std::string Result;
+  Result.reserve(Tok.getLength());
+
+  // Otherwise, hard case, relex the characters into the string.
+  for (const char *Ptr = TokStart, *End = TokStart+Tok.getLength();
+       Ptr != End; ) {
+    unsigned CharSize;
+    Result.push_back(Lexer::getCharAndSizeNoWarn(Ptr, CharSize, Features));
+    Ptr += CharSize;
+  }
+  assert(Result.size() != unsigned(Tok.getLength()) &&
+         "NeedsCleaning flag set on something that didn't need cleaning!");
+  return Result;
+}
+
+/// getSpelling() - Return the 'spelling' of this token.  The spelling of a
+/// token are the characters used to represent the token in the source file
+/// after trigraph expansion and escaped-newline folding.  In particular, this
+/// wants to get the true, uncanonicalized, spelling of things like digraphs
+/// UCNs, etc.
+std::string Preprocessor::getSpelling(const Token &Tok, bool *Invalid) const {
+  return getSpelling(Tok, SourceMgr, Features, Invalid);
+}
+
+/// getSpelling - This method is used to get the spelling of a token into a
+/// preallocated buffer, instead of as an std::string.  The caller is required
+/// to allocate enough space for the token, which is guaranteed to be at least
+/// Tok.getLength() bytes long.  The actual length of the token is returned.
+///
+/// Note that this method may do two possible things: it may either fill in
+/// the buffer specified with characters, or it may *change the input pointer*
+/// to point to a constant buffer with the data already in it (avoiding a
+/// copy).  The caller is not allowed to modify the returned buffer pointer
+/// if an internal buffer is returned.
+unsigned Preprocessor::getSpelling(const Token &Tok,
+                                   const char *&Buffer, bool *Invalid) const {
+  assert((int)Tok.getLength() >= 0 && "Token character range is bogus!");
+
+  // If this token is an identifier, just return the string from the identifier
+  // table, which is very quick.
+  if (const IdentifierInfo *II = Tok.getIdentifierInfo()) {
+    Buffer = II->getNameStart();
+    return II->getLength();
+  }
+
+  // Otherwise, compute the start of the token in the input lexer buffer.
+  const char *TokStart = 0;
+
+  if (Tok.isLiteral())
+    TokStart = Tok.getLiteralData();
+
+  if (TokStart == 0) {
+    bool CharDataInvalid = false;
+    TokStart = SourceMgr.getCharacterData(Tok.getLocation(), &CharDataInvalid);
+    if (Invalid)
+      *Invalid = CharDataInvalid;
+    if (CharDataInvalid) {
+      Buffer = "";
+      return 0;
+    }
+  }
+
+  // If this token contains nothing interesting, return it directly.
+  if (!Tok.needsCleaning()) {
+    Buffer = TokStart;
+    return Tok.getLength();
+  }
+
+  // Otherwise, hard case, relex the characters into the string.
+  char *OutBuf = const_cast<char*>(Buffer);
+  for (const char *Ptr = TokStart, *End = TokStart+Tok.getLength();
+       Ptr != End; ) {
+    unsigned CharSize;
+    *OutBuf++ = Lexer::getCharAndSizeNoWarn(Ptr, CharSize, Features);
+    Ptr += CharSize;
+  }
+  assert(unsigned(OutBuf-Buffer) != Tok.getLength() &&
+         "NeedsCleaning flag set on something that didn't need cleaning!");
+
+  return OutBuf-Buffer;
+}
+
+/// getSpelling - This method is used to get the spelling of a token into a
+/// SmallVector. Note that the returned StringRef may not point to the
+/// supplied buffer if a copy can be avoided.
+llvm::StringRef Preprocessor::getSpelling(const Token &Tok,
+                                          llvm::SmallVectorImpl<char> &Buffer,
+                                          bool *Invalid) const {
+  // Try the fast path.
+  if (const IdentifierInfo *II = Tok.getIdentifierInfo())
+    return II->getName();
+
+  // Resize the buffer if we need to copy into it.
+  if (Tok.needsCleaning())
+    Buffer.resize(Tok.getLength());
+
+  const char *Ptr = Buffer.data();
+  unsigned Len = getSpelling(Tok, Ptr, Invalid);
+  return llvm::StringRef(Ptr, Len);
+}
+
+/// CreateString - Plop the specified string into a scratch buffer and return a
+/// location for it.  If specified, the source location provides a source
+/// location for the token.
+void Preprocessor::CreateString(const char *Buf, unsigned Len, Token &Tok,
+                                SourceLocation InstantiationLoc) {
+  Tok.setLength(Len);
+
+  const char *DestPtr;
+  SourceLocation Loc = ScratchBuf->getToken(Buf, Len, DestPtr);
+
+  if (InstantiationLoc.isValid())
+    Loc = SourceMgr.createInstantiationLoc(Loc, InstantiationLoc,
+                                           InstantiationLoc, Len);
+  Tok.setLocation(Loc);
+
+  // If this is a literal token, set the pointer data.
+  if (Tok.isLiteral())
+    Tok.setLiteralData(DestPtr);
+}
+
+
+/// AdvanceToTokenCharacter - Given a location that specifies the start of a
+/// token, return a new location that specifies a character within the token.
+SourceLocation Preprocessor::AdvanceToTokenCharacter(SourceLocation TokStart,
+                                                     unsigned CharNo) {
+  // Figure out how many physical characters away the specified instantiation
+  // character is.  This needs to take into consideration newlines and
+  // trigraphs.
+  bool Invalid = false;
+  const char *TokPtr = SourceMgr.getCharacterData(TokStart, &Invalid);
+
+  // If they request the first char of the token, we're trivially done.
+  if (Invalid || (CharNo == 0 && Lexer::isObviouslySimpleCharacter(*TokPtr)))
+    return TokStart;
+
+  unsigned PhysOffset = 0;
+
+  // The usual case is that tokens don't contain anything interesting.  Skip
+  // over the uninteresting characters.  If a token only consists of simple
+  // chars, this method is extremely fast.
+  while (Lexer::isObviouslySimpleCharacter(*TokPtr)) {
+    if (CharNo == 0)
+      return TokStart.getFileLocWithOffset(PhysOffset);
+    ++TokPtr, --CharNo, ++PhysOffset;
+  }
+
+  // If we have a character that may be a trigraph or escaped newline, use a
+  // lexer to parse it correctly.
+  for (; CharNo; --CharNo) {
+    unsigned Size;
+    Lexer::getCharAndSizeNoWarn(TokPtr, Size, Features);
+    TokPtr += Size;
+    PhysOffset += Size;
+  }
+
+  // Final detail: if we end up on an escaped newline, we want to return the
+  // location of the actual byte of the token.  For example foo\<newline>bar
+  // advanced by 3 should return the location of b, not of \\.  One compounding
+  // detail of this is that the escape may be made by a trigraph.
+  if (!Lexer::isObviouslySimpleCharacter(*TokPtr))
+    PhysOffset += Lexer::SkipEscapedNewLines(TokPtr)-TokPtr;
+
+  return TokStart.getFileLocWithOffset(PhysOffset);
+}
+
+SourceLocation Preprocessor::getLocForEndOfToken(SourceLocation Loc,
+                                                 unsigned Offset) {
+  if (Loc.isInvalid() || !Loc.isFileID())
+    return SourceLocation();
+
+  unsigned Len = Lexer::MeasureTokenLength(Loc, getSourceManager(), Features);
+  if (Len > Offset)
+    Len = Len - Offset;
+  else
+    return Loc;
+
+  return AdvanceToTokenCharacter(Loc, Len);
+}
+
+
+
+//===----------------------------------------------------------------------===//
+// Preprocessor Initialization Methods
+//===----------------------------------------------------------------------===//
+
+
+/// EnterMainSourceFile - Enter the specified FileID as the main source file,
+/// which implicitly adds the builtin defines etc.
+void Preprocessor::EnterMainSourceFile() {
+  // We do not allow the preprocessor to reenter the main file.  Doing so will
+  // cause FileID's to accumulate information from both runs (e.g. #line
+  // information) and predefined macros aren't guaranteed to be set properly.
+  assert(NumEnteredSourceFiles == 0 && "Cannot reenter the main file!");
+  FileID MainFileID = SourceMgr.getMainFileID();
+
+  // Enter the main file source buffer.
+  EnterSourceFile(MainFileID, 0, SourceLocation());
+
+  // Tell the header info that the main file was entered.  If the file is later
+  // #imported, it won't be re-entered.
+  if (const FileEntry *FE = SourceMgr.getFileEntryForID(MainFileID))
+    HeaderInfo.IncrementIncludeCount(FE);
+
+  // Preprocess Predefines to populate the initial preprocessor state.
+  llvm::MemoryBuffer *SB =
+    llvm::MemoryBuffer::getMemBufferCopy(Predefines, "<built-in>");
+  assert(SB && "Cannot fail to create predefined source buffer");
+  FileID FID = SourceMgr.createFileIDForMemBuffer(SB);
+  assert(!FID.isInvalid() && "Could not create FileID for predefines?");
+
+  // Start parsing the predefines.
+  EnterSourceFile(FID, 0, SourceLocation());
+}
+
+void Preprocessor::EndSourceFile() {
+  // Notify the client that we reached the end of the source file.
+  if (Callbacks)
+    Callbacks->EndOfMainFile();
+}
+
+//===----------------------------------------------------------------------===//
+// Lexer Event Handling.
+//===----------------------------------------------------------------------===//
+
+/// LookUpIdentifierInfo - Given a tok::identifier token, look up the
+/// identifier information for the token and install it into the token.
+IdentifierInfo *Preprocessor::LookUpIdentifierInfo(Token &Identifier,
+                                                   const char *BufPtr) const {
+  assert(Identifier.is(tok::identifier) && "Not an identifier!");
+  assert(Identifier.getIdentifierInfo() == 0 && "Identinfo already exists!");
+
+  // Look up this token, see if it is a macro, or if it is a language keyword.
+  IdentifierInfo *II;
+  if (BufPtr && !Identifier.needsCleaning()) {
+    // No cleaning needed, just use the characters from the lexed buffer.
+    II = getIdentifierInfo(llvm::StringRef(BufPtr, Identifier.getLength()));
+  } else {
+    // Cleaning needed, alloca a buffer, clean into it, then use the buffer.
+    llvm::SmallString<64> IdentifierBuffer;
+    llvm::StringRef CleanedStr = getSpelling(Identifier, IdentifierBuffer);
+    II = getIdentifierInfo(CleanedStr);
+  }
+  Identifier.setIdentifierInfo(II);
+  return II;
+}
+
+
+/// HandleIdentifier - This callback is invoked when the lexer reads an
+/// identifier.  This callback looks up the identifier in the map and/or
+/// potentially macro expands it or turns it into a named token (like 'for').
+///
+/// Note that callers of this method are guarded by checking the
+/// IdentifierInfo's 'isHandleIdentifierCase' bit.  If this method changes, the
+/// IdentifierInfo methods that compute these properties will need to change to
+/// match.
+void Preprocessor::HandleIdentifier(Token &Identifier) {
+  assert(Identifier.getIdentifierInfo() &&
+         "Can't handle identifiers without identifier info!");
+
+  IdentifierInfo &II = *Identifier.getIdentifierInfo();
+
+  // If this identifier was poisoned, and if it was not produced from a macro
+  // expansion, emit an error.
+  if (II.isPoisoned() && CurPPLexer) {
+    if (&II != Ident__VA_ARGS__)   // We warn about __VA_ARGS__ with poisoning.
+      Diag(Identifier, diag::err_pp_used_poisoned_id);
+    else
+      Diag(Identifier, diag::ext_pp_bad_vaargs_use);
+  }
+
+  // If this is a macro to be expanded, do it.
+  if (MacroInfo *MI = getMacroInfo(&II)) {
+    if (!DisableMacroExpansion && !Identifier.isExpandDisabled()) {
+      if (MI->isEnabled()) {
+        if (!HandleMacroExpandedIdentifier(Identifier, MI))
+          return;
+      } else {
+        // C99 6.10.3.4p2 says that a disabled macro may never again be
+        // expanded, even if it's in a context where it could be expanded in the
+        // future.
+        Identifier.setFlag(Token::DisableExpand);
+      }
+    }
+  }
+
+  // C++ 2.11p2: If this is an alternative representation of a C++ operator,
+  // then we act as if it is the actual operator and not the textual
+  // representation of it.
+  if (II.isCPlusPlusOperatorKeyword())
+    Identifier.setIdentifierInfo(0);
+
+  // If this is an extension token, diagnose its use.
+  // We avoid diagnosing tokens that originate from macro definitions.
+  // FIXME: This warning is disabled in cases where it shouldn't be,
+  // like "#define TY typeof", "TY(1) x".
+  if (II.isExtensionToken() && !DisableMacroExpansion)
+    Diag(Identifier, diag::ext_token_used);
+}
+
+void Preprocessor::AddCommentHandler(CommentHandler *Handler) {
+  assert(Handler && "NULL comment handler");
+  assert(std::find(CommentHandlers.begin(), CommentHandlers.end(), Handler) ==
+         CommentHandlers.end() && "Comment handler already registered");
+  CommentHandlers.push_back(Handler);
+}
+
+void Preprocessor::RemoveCommentHandler(CommentHandler *Handler) {
+  std::vector<CommentHandler *>::iterator Pos
+  = std::find(CommentHandlers.begin(), CommentHandlers.end(), Handler);
+  assert(Pos != CommentHandlers.end() && "Comment handler not registered");
+  CommentHandlers.erase(Pos);
+}
+
+bool Preprocessor::HandleComment(Token &result, SourceRange Comment) {
+  bool AnyPendingTokens = false;
+  for (std::vector<CommentHandler *>::iterator H = CommentHandlers.begin(),
+       HEnd = CommentHandlers.end();
+       H != HEnd; ++H) {
+    if ((*H)->HandleComment(*this, Comment))
+      AnyPendingTokens = true;
+  }
+  if (!AnyPendingTokens || getCommentRetentionState())
+    return false;
+  Lex(result);
+  return true;
+}
+
+CommentHandler::~CommentHandler() { }
+
+void Preprocessor::createPreprocessingRecord() {
+  if (Record)
+    return;
+  
+  Record = new PreprocessingRecord;
+  addPPCallbacks(Record);
+}
diff --git a/lib/Lex/PreprocessorLexer.cpp b/lib/Lex/PreprocessorLexer.cpp
new file mode 100644
index 0000000..e005c49
--- /dev/null
+++ b/lib/Lex/PreprocessorLexer.cpp
@@ -0,0 +1,45 @@
+//===--- PreprocessorLexer.cpp - C Language Family Lexer ------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements the PreprocessorLexer and Token interfaces.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Lex/PreprocessorLexer.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Lex/LexDiagnostic.h"
+#include "clang/Basic/SourceManager.h"
+using namespace clang;
+
+/// LexIncludeFilename - After the preprocessor has parsed a #include, lex and
+/// (potentially) macro expand the filename.
+void PreprocessorLexer::LexIncludeFilename(Token &FilenameTok) {
+  assert(ParsingPreprocessorDirective &&
+         ParsingFilename == false &&
+         "Must be in a preprocessing directive!");
+
+  // We are now parsing a filename!
+  ParsingFilename = true;
+
+  // Lex the filename.
+  IndirectLex(FilenameTok);
+
+  // We should have obtained the filename now.
+  ParsingFilename = false;
+
+  // No filename?
+  if (FilenameTok.is(tok::eom))
+    PP->Diag(FilenameTok.getLocation(), diag::err_pp_expects_filename);
+}
+
+/// getFileEntry - Return the FileEntry corresponding to this FileID.  Like
+/// getFileID(), this only works for lexers with attached preprocessors.
+const FileEntry *PreprocessorLexer::getFileEntry() const {
+  return PP->getSourceManager().getFileEntryForID(getFileID());
+}
diff --git a/lib/Lex/ScratchBuffer.cpp b/lib/Lex/ScratchBuffer.cpp
new file mode 100644
index 0000000..0e98c17
--- /dev/null
+++ b/lib/Lex/ScratchBuffer.cpp
@@ -0,0 +1,73 @@
+//===--- ScratchBuffer.cpp - Scratch space for forming tokens -------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements the ScratchBuffer interface.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Lex/ScratchBuffer.h"
+#include "clang/Basic/SourceManager.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include <cstring>
+using namespace clang;
+
+// ScratchBufSize - The size of each chunk of scratch memory.  Slightly less
+//than a page, almost certainly enough for anything. :)
+static const unsigned ScratchBufSize = 4060;
+
+ScratchBuffer::ScratchBuffer(SourceManager &SM) : SourceMgr(SM), CurBuffer(0) {
+  // Set BytesUsed so that the first call to getToken will require an alloc.
+  BytesUsed = ScratchBufSize;
+}
+
+/// getToken - Splat the specified text into a temporary MemoryBuffer and
+/// return a SourceLocation that refers to the token.  This is just like the
+/// method below, but returns a location that indicates the physloc of the
+/// token.
+SourceLocation ScratchBuffer::getToken(const char *Buf, unsigned Len,
+                                       const char *&DestPtr) {
+  if (BytesUsed+Len+2 > ScratchBufSize)
+    AllocScratchBuffer(Len+2);
+
+  // Prefix the token with a \n, so that it looks like it is the first thing on
+  // its own virtual line in caret diagnostics.
+  CurBuffer[BytesUsed++] = '\n';
+
+  // Return a pointer to the character data.
+  DestPtr = CurBuffer+BytesUsed;
+
+  // Copy the token data into the buffer.
+  memcpy(CurBuffer+BytesUsed, Buf, Len);
+
+  // Remember that we used these bytes.
+  BytesUsed += Len+1;
+
+  // Add a NUL terminator to the token.  This keeps the tokens separated, in
+  // case they get relexed, and puts them on their own virtual lines in case a
+  // diagnostic points to one.
+  CurBuffer[BytesUsed-1] = '\0';
+
+  return BufferStartLoc.getFileLocWithOffset(BytesUsed-Len-1);
+}
+
+void ScratchBuffer::AllocScratchBuffer(unsigned RequestLen) {
+  // Only pay attention to the requested length if it is larger than our default
+  // page size.  If it is, we allocate an entire chunk for it.  This is to
+  // support gigantic tokens, which almost certainly won't happen. :)
+  if (RequestLen < ScratchBufSize)
+    RequestLen = ScratchBufSize;
+
+  llvm::MemoryBuffer *Buf =
+    llvm::MemoryBuffer::getNewMemBuffer(RequestLen, "<scratch space>");
+  FileID FID = SourceMgr.createFileIDForMemBuffer(Buf);
+  BufferStartLoc = SourceMgr.getLocForStartOfFile(FID);
+  CurBuffer = const_cast<char*>(Buf->getBufferStart());
+  BytesUsed = 1;
+  CurBuffer[0] = '0';  // Start out with a \0 for cleanliness.
+}
diff --git a/lib/Lex/TokenConcatenation.cpp b/lib/Lex/TokenConcatenation.cpp
new file mode 100644
index 0000000..fc6db21
--- /dev/null
+++ b/lib/Lex/TokenConcatenation.cpp
@@ -0,0 +1,223 @@
+//===--- TokenConcatenation.cpp - Token Concatenation Avoidance -----------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the TokenConcatenation class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Lex/TokenConcatenation.h"
+#include "clang/Lex/Preprocessor.h"
+using namespace clang;
+
+
+/// StartsWithL - Return true if the spelling of this token starts with 'L'.
+bool TokenConcatenation::StartsWithL(const Token &Tok) const {
+  if (!Tok.needsCleaning()) {
+    SourceManager &SM = PP.getSourceManager();
+    return *SM.getCharacterData(SM.getSpellingLoc(Tok.getLocation())) == 'L';
+  }
+
+  if (Tok.getLength() < 256) {
+    char Buffer[256];
+    const char *TokPtr = Buffer;
+    PP.getSpelling(Tok, TokPtr);
+    return TokPtr[0] == 'L';
+  }
+
+  return PP.getSpelling(Tok)[0] == 'L';
+}
+
+/// IsIdentifierL - Return true if the spelling of this token is literally
+/// 'L'.
+bool TokenConcatenation::IsIdentifierL(const Token &Tok) const {
+  if (!Tok.needsCleaning()) {
+    if (Tok.getLength() != 1)
+      return false;
+    SourceManager &SM = PP.getSourceManager();
+    return *SM.getCharacterData(SM.getSpellingLoc(Tok.getLocation())) == 'L';
+  }
+
+  if (Tok.getLength() < 256) {
+    char Buffer[256];
+    const char *TokPtr = Buffer;
+    if (PP.getSpelling(Tok, TokPtr) != 1)
+      return false;
+    return TokPtr[0] == 'L';
+  }
+
+  return PP.getSpelling(Tok) == "L";
+}
+
+TokenConcatenation::TokenConcatenation(Preprocessor &pp) : PP(pp) {
+  memset(TokenInfo, 0, sizeof(TokenInfo));
+
+  // These tokens have custom code in AvoidConcat.
+  TokenInfo[tok::identifier      ] |= aci_custom;
+  TokenInfo[tok::numeric_constant] |= aci_custom_firstchar;
+  TokenInfo[tok::period          ] |= aci_custom_firstchar;
+  TokenInfo[tok::amp             ] |= aci_custom_firstchar;
+  TokenInfo[tok::plus            ] |= aci_custom_firstchar;
+  TokenInfo[tok::minus           ] |= aci_custom_firstchar;
+  TokenInfo[tok::slash           ] |= aci_custom_firstchar;
+  TokenInfo[tok::less            ] |= aci_custom_firstchar;
+  TokenInfo[tok::greater         ] |= aci_custom_firstchar;
+  TokenInfo[tok::pipe            ] |= aci_custom_firstchar;
+  TokenInfo[tok::percent         ] |= aci_custom_firstchar;
+  TokenInfo[tok::colon           ] |= aci_custom_firstchar;
+  TokenInfo[tok::hash            ] |= aci_custom_firstchar;
+  TokenInfo[tok::arrow           ] |= aci_custom_firstchar;
+
+  // These tokens change behavior if followed by an '='.
+  TokenInfo[tok::amp         ] |= aci_avoid_equal;           // &=
+  TokenInfo[tok::plus        ] |= aci_avoid_equal;           // +=
+  TokenInfo[tok::minus       ] |= aci_avoid_equal;           // -=
+  TokenInfo[tok::slash       ] |= aci_avoid_equal;           // /=
+  TokenInfo[tok::less        ] |= aci_avoid_equal;           // <=
+  TokenInfo[tok::greater     ] |= aci_avoid_equal;           // >=
+  TokenInfo[tok::pipe        ] |= aci_avoid_equal;           // |=
+  TokenInfo[tok::percent     ] |= aci_avoid_equal;           // %=
+  TokenInfo[tok::star        ] |= aci_avoid_equal;           // *=
+  TokenInfo[tok::exclaim     ] |= aci_avoid_equal;           // !=
+  TokenInfo[tok::lessless    ] |= aci_avoid_equal;           // <<=
+  TokenInfo[tok::greatergreater] |= aci_avoid_equal;         // >>=
+  TokenInfo[tok::caret       ] |= aci_avoid_equal;           // ^=
+  TokenInfo[tok::equal       ] |= aci_avoid_equal;           // ==
+}
+
+/// GetFirstChar - Get the first character of the token \arg Tok,
+/// avoiding calls to getSpelling where possible.
+static char GetFirstChar(Preprocessor &PP, const Token &Tok) {
+  if (IdentifierInfo *II = Tok.getIdentifierInfo()) {
+    // Avoid spelling identifiers, the most common form of token.
+    return II->getNameStart()[0];
+  } else if (!Tok.needsCleaning()) {
+    if (Tok.isLiteral() && Tok.getLiteralData()) {
+      return *Tok.getLiteralData();
+    } else {
+      SourceManager &SM = PP.getSourceManager();
+      return *SM.getCharacterData(SM.getSpellingLoc(Tok.getLocation()));
+    }
+  } else if (Tok.getLength() < 256) {
+    char Buffer[256];
+    const char *TokPtr = Buffer;
+    PP.getSpelling(Tok, TokPtr);
+    return TokPtr[0];
+  } else {
+    return PP.getSpelling(Tok)[0];
+  }
+}
+
+/// AvoidConcat - If printing PrevTok immediately followed by Tok would cause
+/// the two individual tokens to be lexed as a single token, return true
+/// (which causes a space to be printed between them).  This allows the output
+/// of -E mode to be lexed to the same token stream as lexing the input
+/// directly would.
+///
+/// This code must conservatively return true if it doesn't want to be 100%
+/// accurate.  This will cause the output to include extra space characters,
+/// but the resulting output won't have incorrect concatenations going on.
+/// Examples include "..", which we print with a space between, because we
+/// don't want to track enough to tell "x.." from "...".
+bool TokenConcatenation::AvoidConcat(const Token &PrevPrevTok,
+                                     const Token &PrevTok,
+                                     const Token &Tok) const {
+  // First, check to see if the tokens were directly adjacent in the original
+  // source.  If they were, it must be okay to stick them together: if there
+  // were an issue, the tokens would have been lexed differently.
+  if (PrevTok.getLocation().isFileID() && Tok.getLocation().isFileID() &&
+      PrevTok.getLocation().getFileLocWithOffset(PrevTok.getLength()) ==
+        Tok.getLocation())
+    return false;
+
+  tok::TokenKind PrevKind = PrevTok.getKind();
+  if (PrevTok.getIdentifierInfo())  // Language keyword or named operator.
+    PrevKind = tok::identifier;
+
+  // Look up information on when we should avoid concatenation with prevtok.
+  unsigned ConcatInfo = TokenInfo[PrevKind];
+
+  // If prevtok never causes a problem for anything after it, return quickly.
+  if (ConcatInfo == 0) return false;
+
+  if (ConcatInfo & aci_avoid_equal) {
+    // If the next token is '=' or '==', avoid concatenation.
+    if (Tok.is(tok::equal) || Tok.is(tok::equalequal))
+      return true;
+    ConcatInfo &= ~aci_avoid_equal;
+  }
+
+  if (ConcatInfo == 0) return false;
+
+  // Basic algorithm: we look at the first character of the second token, and
+  // determine whether it, if appended to the first token, would form (or
+  // would contribute) to a larger token if concatenated.
+  char FirstChar = 0;
+  if (ConcatInfo & aci_custom) {
+    // If the token does not need to know the first character, don't get it.
+  } else {
+    FirstChar = GetFirstChar(PP, Tok);
+  }
+
+  switch (PrevKind) {
+  default: assert(0 && "InitAvoidConcatTokenInfo built wrong");
+  case tok::identifier:   // id+id or id+number or id+L"foo".
+    // id+'.'... will not append.
+    if (Tok.is(tok::numeric_constant))
+      return GetFirstChar(PP, Tok) != '.';
+
+    if (Tok.getIdentifierInfo() || Tok.is(tok::wide_string_literal) /* ||
+     Tok.is(tok::wide_char_literal)*/)
+      return true;
+
+    // If this isn't identifier + string, we're done.
+    if (Tok.isNot(tok::char_constant) && Tok.isNot(tok::string_literal))
+      return false;
+
+    // FIXME: need a wide_char_constant!
+
+    // If the string was a wide string L"foo" or wide char L'f', it would
+    // concat with the previous identifier into fooL"bar".  Avoid this.
+    if (StartsWithL(Tok))
+      return true;
+
+    // Otherwise, this is a narrow character or string.  If the *identifier*
+    // is a literal 'L', avoid pasting L "foo" -> L"foo".
+    return IsIdentifierL(PrevTok);
+  case tok::numeric_constant:
+    return isalnum(FirstChar) || Tok.is(tok::numeric_constant) ||
+    FirstChar == '+' || FirstChar == '-' || FirstChar == '.';
+  case tok::period:          // ..., .*, .1234
+    return (FirstChar == '.' && PrevPrevTok.is(tok::period)) ||
+    isdigit(FirstChar) ||
+    (PP.getLangOptions().CPlusPlus && FirstChar == '*');
+  case tok::amp:             // &&
+    return FirstChar == '&';
+  case tok::plus:            // ++
+    return FirstChar == '+';
+  case tok::minus:           // --, ->, ->*
+    return FirstChar == '-' || FirstChar == '>';
+  case tok::slash:           //, /*, //
+    return FirstChar == '*' || FirstChar == '/';
+  case tok::less:            // <<, <<=, <:, <%
+    return FirstChar == '<' || FirstChar == ':' || FirstChar == '%';
+  case tok::greater:         // >>, >>=
+    return FirstChar == '>';
+  case tok::pipe:            // ||
+    return FirstChar == '|';
+  case tok::percent:         // %>, %:
+    return FirstChar == '>' || FirstChar == ':';
+  case tok::colon:           // ::, :>
+    return FirstChar == '>' ||
+    (PP.getLangOptions().CPlusPlus && FirstChar == ':');
+  case tok::hash:            // ##, #@, %:%:
+    return FirstChar == '#' || FirstChar == '@' || FirstChar == '%';
+  case tok::arrow:           // ->*
+    return PP.getLangOptions().CPlusPlus && FirstChar == '*';
+  }
+}
diff --git a/lib/Lex/TokenLexer.cpp b/lib/Lex/TokenLexer.cpp
new file mode 100644
index 0000000..56bb073
--- /dev/null
+++ b/lib/Lex/TokenLexer.cpp
@@ -0,0 +1,549 @@
+//===--- TokenLexer.cpp - Lex from a token stream -------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the TokenLexer interface.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Lex/TokenLexer.h"
+#include "MacroArgs.h"
+#include "clang/Lex/MacroInfo.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Lex/LexDiagnostic.h"
+#include "llvm/ADT/SmallVector.h"
+using namespace clang;
+
+
+/// Create a TokenLexer for the specified macro with the specified actual
+/// arguments.  Note that this ctor takes ownership of the ActualArgs pointer.
+void TokenLexer::Init(Token &Tok, SourceLocation ILEnd, MacroArgs *Actuals) {
+  // If the client is reusing a TokenLexer, make sure to free any memory
+  // associated with it.
+  destroy();
+
+  Macro = PP.getMacroInfo(Tok.getIdentifierInfo());
+  ActualArgs = Actuals;
+  CurToken = 0;
+
+  InstantiateLocStart = Tok.getLocation();
+  InstantiateLocEnd = ILEnd;
+  AtStartOfLine = Tok.isAtStartOfLine();
+  HasLeadingSpace = Tok.hasLeadingSpace();
+  Tokens = &*Macro->tokens_begin();
+  OwnsTokens = false;
+  DisableMacroExpansion = false;
+  NumTokens = Macro->tokens_end()-Macro->tokens_begin();
+
+  // If this is a function-like macro, expand the arguments and change
+  // Tokens to point to the expanded tokens.
+  if (Macro->isFunctionLike() && Macro->getNumArgs())
+    ExpandFunctionArguments();
+
+  // Mark the macro as currently disabled, so that it is not recursively
+  // expanded.  The macro must be disabled only after argument pre-expansion of
+  // function-like macro arguments occurs.
+  Macro->DisableMacro();
+}
+
+
+
+/// Create a TokenLexer for the specified token stream.  This does not
+/// take ownership of the specified token vector.
+void TokenLexer::Init(const Token *TokArray, unsigned NumToks,
+                      bool disableMacroExpansion, bool ownsTokens) {
+  // If the client is reusing a TokenLexer, make sure to free any memory
+  // associated with it.
+  destroy();
+
+  Macro = 0;
+  ActualArgs = 0;
+  Tokens = TokArray;
+  OwnsTokens = ownsTokens;
+  DisableMacroExpansion = disableMacroExpansion;
+  NumTokens = NumToks;
+  CurToken = 0;
+  InstantiateLocStart = InstantiateLocEnd = SourceLocation();
+  AtStartOfLine = false;
+  HasLeadingSpace = false;
+
+  // Set HasLeadingSpace/AtStartOfLine so that the first token will be
+  // returned unmodified.
+  if (NumToks != 0) {
+    AtStartOfLine   = TokArray[0].isAtStartOfLine();
+    HasLeadingSpace = TokArray[0].hasLeadingSpace();
+  }
+}
+
+
+void TokenLexer::destroy() {
+  // If this was a function-like macro that actually uses its arguments, delete
+  // the expanded tokens.
+  if (OwnsTokens) {
+    delete [] Tokens;
+    Tokens = 0;
+    OwnsTokens = false;
+  }
+
+  // TokenLexer owns its formal arguments.
+  if (ActualArgs) ActualArgs->destroy(PP);
+}
+
+/// Expand the arguments of a function-like macro so that we can quickly
+/// return preexpanded tokens from Tokens.
+void TokenLexer::ExpandFunctionArguments() {
+  llvm::SmallVector<Token, 128> ResultToks;
+
+  // Loop through 'Tokens', expanding them into ResultToks.  Keep
+  // track of whether we change anything.  If not, no need to keep them.  If so,
+  // we install the newly expanded sequence as the new 'Tokens' list.
+  bool MadeChange = false;
+
+  // NextTokGetsSpace - When this is true, the next token appended to the
+  // output list will get a leading space, regardless of whether it had one to
+  // begin with or not.  This is used for placemarker support.
+  bool NextTokGetsSpace = false;
+
+  for (unsigned i = 0, e = NumTokens; i != e; ++i) {
+    // If we found the stringify operator, get the argument stringified.  The
+    // preprocessor already verified that the following token is a macro name
+    // when the #define was parsed.
+    const Token &CurTok = Tokens[i];
+    if (CurTok.is(tok::hash) || CurTok.is(tok::hashat)) {
+      int ArgNo = Macro->getArgumentNum(Tokens[i+1].getIdentifierInfo());
+      assert(ArgNo != -1 && "Token following # is not an argument?");
+
+      Token Res;
+      if (CurTok.is(tok::hash))  // Stringify
+        Res = ActualArgs->getStringifiedArgument(ArgNo, PP);
+      else {
+        // 'charify': don't bother caching these.
+        Res = MacroArgs::StringifyArgument(ActualArgs->getUnexpArgument(ArgNo),
+                                           PP, true);
+      }
+
+      // The stringified/charified string leading space flag gets set to match
+      // the #/#@ operator.
+      if (CurTok.hasLeadingSpace() || NextTokGetsSpace)
+        Res.setFlag(Token::LeadingSpace);
+
+      ResultToks.push_back(Res);
+      MadeChange = true;
+      ++i;  // Skip arg name.
+      NextTokGetsSpace = false;
+      continue;
+    }
+
+    // Otherwise, if this is not an argument token, just add the token to the
+    // output buffer.
+    IdentifierInfo *II = CurTok.getIdentifierInfo();
+    int ArgNo = II ? Macro->getArgumentNum(II) : -1;
+    if (ArgNo == -1) {
+      // This isn't an argument, just add it.
+      ResultToks.push_back(CurTok);
+
+      if (NextTokGetsSpace) {
+        ResultToks.back().setFlag(Token::LeadingSpace);
+        NextTokGetsSpace = false;
+      }
+      continue;
+    }
+
+    // An argument is expanded somehow, the result is different than the
+    // input.
+    MadeChange = true;
+
+    // Otherwise, this is a use of the argument.  Find out if there is a paste
+    // (##) operator before or after the argument.
+    bool PasteBefore =
+      !ResultToks.empty() && ResultToks.back().is(tok::hashhash);
+    bool PasteAfter = i+1 != e && Tokens[i+1].is(tok::hashhash);
+
+    // If it is not the LHS/RHS of a ## operator, we must pre-expand the
+    // argument and substitute the expanded tokens into the result.  This is
+    // C99 6.10.3.1p1.
+    if (!PasteBefore && !PasteAfter) {
+      const Token *ResultArgToks;
+
+      // Only preexpand the argument if it could possibly need it.  This
+      // avoids some work in common cases.
+      const Token *ArgTok = ActualArgs->getUnexpArgument(ArgNo);
+      if (ActualArgs->ArgNeedsPreexpansion(ArgTok, PP))
+        ResultArgToks = &ActualArgs->getPreExpArgument(ArgNo, Macro, PP)[0];
+      else
+        ResultArgToks = ArgTok;  // Use non-preexpanded tokens.
+
+      // If the arg token expanded into anything, append it.
+      if (ResultArgToks->isNot(tok::eof)) {
+        unsigned FirstResult = ResultToks.size();
+        unsigned NumToks = MacroArgs::getArgLength(ResultArgToks);
+        ResultToks.append(ResultArgToks, ResultArgToks+NumToks);
+
+        // If any tokens were substituted from the argument, the whitespace
+        // before the first token should match the whitespace of the arg
+        // identifier.
+        ResultToks[FirstResult].setFlagValue(Token::LeadingSpace,
+                                             CurTok.hasLeadingSpace() ||
+                                             NextTokGetsSpace);
+        NextTokGetsSpace = false;
+      } else {
+        // If this is an empty argument, and if there was whitespace before the
+        // formal token, make sure the next token gets whitespace before it.
+        NextTokGetsSpace = CurTok.hasLeadingSpace();
+      }
+      continue;
+    }
+
+    // Okay, we have a token that is either the LHS or RHS of a paste (##)
+    // argument.  It gets substituted as its non-pre-expanded tokens.
+    const Token *ArgToks = ActualArgs->getUnexpArgument(ArgNo);
+    unsigned NumToks = MacroArgs::getArgLength(ArgToks);
+    if (NumToks) {  // Not an empty argument?
+      // If this is the GNU ", ## __VA_ARG__" extension, and we just learned
+      // that __VA_ARG__ expands to multiple tokens, avoid a pasting error when
+      // the expander trys to paste ',' with the first token of the __VA_ARG__
+      // expansion.
+      if (PasteBefore && ResultToks.size() >= 2 &&
+          ResultToks[ResultToks.size()-2].is(tok::comma) &&
+          (unsigned)ArgNo == Macro->getNumArgs()-1 &&
+          Macro->isVariadic()) {
+        // Remove the paste operator, report use of the extension.
+        PP.Diag(ResultToks.back().getLocation(), diag::ext_paste_comma);
+        ResultToks.pop_back();
+      }
+
+      ResultToks.append(ArgToks, ArgToks+NumToks);
+
+      // If this token (the macro argument) was supposed to get leading
+      // whitespace, transfer this information onto the first token of the
+      // expansion.
+      //
+      // Do not do this if the paste operator occurs before the macro argument,
+      // as in "A ## MACROARG".  In valid code, the first token will get
+      // smooshed onto the preceding one anyway (forming AMACROARG).  In
+      // assembler-with-cpp mode, invalid pastes are allowed through: in this
+      // case, we do not want the extra whitespace to be added.  For example,
+      // we want ". ## foo" -> ".foo" not ". foo".
+      if ((CurTok.hasLeadingSpace() || NextTokGetsSpace) &&
+          !PasteBefore)
+        ResultToks[ResultToks.size()-NumToks].setFlag(Token::LeadingSpace);
+
+      NextTokGetsSpace = false;
+      continue;
+    }
+
+    // If an empty argument is on the LHS or RHS of a paste, the standard (C99
+    // 6.10.3.3p2,3) calls for a bunch of placemarker stuff to occur.  We
+    // implement this by eating ## operators when a LHS or RHS expands to
+    // empty.
+    NextTokGetsSpace |= CurTok.hasLeadingSpace();
+    if (PasteAfter) {
+      // Discard the argument token and skip (don't copy to the expansion
+      // buffer) the paste operator after it.
+      NextTokGetsSpace |= Tokens[i+1].hasLeadingSpace();
+      ++i;
+      continue;
+    }
+
+    // If this is on the RHS of a paste operator, we've already copied the
+    // paste operator to the ResultToks list.  Remove it.
+    assert(PasteBefore && ResultToks.back().is(tok::hashhash));
+    NextTokGetsSpace |= ResultToks.back().hasLeadingSpace();
+    ResultToks.pop_back();
+
+    // If this is the __VA_ARGS__ token, and if the argument wasn't provided,
+    // and if the macro had at least one real argument, and if the token before
+    // the ## was a comma, remove the comma.
+    if ((unsigned)ArgNo == Macro->getNumArgs()-1 && // is __VA_ARGS__
+        ActualArgs->isVarargsElidedUse() &&       // Argument elided.
+        !ResultToks.empty() && ResultToks.back().is(tok::comma)) {
+      // Never add a space, even if the comma, ##, or arg had a space.
+      NextTokGetsSpace = false;
+      // Remove the paste operator, report use of the extension.
+      PP.Diag(ResultToks.back().getLocation(), diag::ext_paste_comma);
+      ResultToks.pop_back();
+    }
+    continue;
+  }
+
+  // If anything changed, install this as the new Tokens list.
+  if (MadeChange) {
+    assert(!OwnsTokens && "This would leak if we already own the token list");
+    // This is deleted in the dtor.
+    NumTokens = ResultToks.size();
+    llvm::BumpPtrAllocator &Alloc = PP.getPreprocessorAllocator();
+    Token *Res =
+      static_cast<Token *>(Alloc.Allocate(sizeof(Token)*ResultToks.size(),
+                                          llvm::alignof<Token>()));
+    if (NumTokens)
+      memcpy(Res, &ResultToks[0], NumTokens*sizeof(Token));
+    Tokens = Res;
+
+    // The preprocessor bump pointer owns these tokens, not us.
+    OwnsTokens = false;
+  }
+}
+
+/// Lex - Lex and return a token from this macro stream.
+///
+void TokenLexer::Lex(Token &Tok) {
+  // Lexing off the end of the macro, pop this macro off the expansion stack.
+  if (isAtEnd()) {
+    // If this is a macro (not a token stream), mark the macro enabled now
+    // that it is no longer being expanded.
+    if (Macro) Macro->EnableMacro();
+
+    // Pop this context off the preprocessors lexer stack and get the next
+    // token.  This will delete "this" so remember the PP instance var.
+    Preprocessor &PPCache = PP;
+    if (PP.HandleEndOfTokenLexer(Tok))
+      return;
+
+    // HandleEndOfTokenLexer may not return a token.  If it doesn't, lex
+    // whatever is next.
+    return PPCache.Lex(Tok);
+  }
+
+  // If this is the first token of the expanded result, we inherit spacing
+  // properties later.
+  bool isFirstToken = CurToken == 0;
+
+  // Get the next token to return.
+  Tok = Tokens[CurToken++];
+
+  bool TokenIsFromPaste = false;
+
+  // If this token is followed by a token paste (##) operator, paste the tokens!
+  if (!isAtEnd() && Tokens[CurToken].is(tok::hashhash)) {
+    // When handling the microsoft /##/ extension, the final token is
+    // returned by PasteTokens, not the pasted token.
+    if (PasteTokens(Tok))
+      return;
+
+    TokenIsFromPaste = true;
+  }
+
+  // The token's current location indicate where the token was lexed from.  We
+  // need this information to compute the spelling of the token, but any
+  // diagnostics for the expanded token should appear as if they came from
+  // InstantiationLoc.  Pull this information together into a new SourceLocation
+  // that captures all of this.
+  if (InstantiateLocStart.isValid()) {   // Don't do this for token streams.
+    SourceManager &SM = PP.getSourceManager();
+    Tok.setLocation(SM.createInstantiationLoc(Tok.getLocation(),
+                                              InstantiateLocStart,
+                                              InstantiateLocEnd,
+                                              Tok.getLength()));
+  }
+
+  // If this is the first token, set the lexical properties of the token to
+  // match the lexical properties of the macro identifier.
+  if (isFirstToken) {
+    Tok.setFlagValue(Token::StartOfLine , AtStartOfLine);
+    Tok.setFlagValue(Token::LeadingSpace, HasLeadingSpace);
+  }
+
+  // Handle recursive expansion!
+  if (!Tok.isAnnotation() && Tok.getIdentifierInfo() != 0) {
+    // Change the kind of this identifier to the appropriate token kind, e.g.
+    // turning "for" into a keyword.
+    IdentifierInfo *II = Tok.getIdentifierInfo();
+    Tok.setKind(II->getTokenID());
+
+    // If this identifier was poisoned and from a paste, emit an error.  This
+    // won't be handled by Preprocessor::HandleIdentifier because this is coming
+    // from a macro expansion.
+    if (II->isPoisoned() && TokenIsFromPaste) {
+      // We warn about __VA_ARGS__ with poisoning.
+      if (II->isStr("__VA_ARGS__"))
+        PP.Diag(Tok, diag::ext_pp_bad_vaargs_use);
+      else
+        PP.Diag(Tok, diag::err_pp_used_poisoned_id);
+    }
+
+    if (!DisableMacroExpansion && II->isHandleIdentifierCase())
+      PP.HandleIdentifier(Tok);
+  }
+
+  // Otherwise, return a normal token.
+}
+
+/// PasteTokens - Tok is the LHS of a ## operator, and CurToken is the ##
+/// operator.  Read the ## and RHS, and paste the LHS/RHS together.  If there
+/// are more ## after it, chomp them iteratively.  Return the result as Tok.
+/// If this returns true, the caller should immediately return the token.
+bool TokenLexer::PasteTokens(Token &Tok) {
+  llvm::SmallString<128> Buffer;
+  const char *ResultTokStrPtr = 0;
+  do {
+    // Consume the ## operator.
+    SourceLocation PasteOpLoc = Tokens[CurToken].getLocation();
+    ++CurToken;
+    assert(!isAtEnd() && "No token on the RHS of a paste operator!");
+
+    // Get the RHS token.
+    const Token &RHS = Tokens[CurToken];
+
+    // Allocate space for the result token.  This is guaranteed to be enough for
+    // the two tokens.
+    Buffer.resize(Tok.getLength() + RHS.getLength());
+
+    // Get the spelling of the LHS token in Buffer.
+    const char *BufPtr = &Buffer[0];
+    bool Invalid = false;
+    unsigned LHSLen = PP.getSpelling(Tok, BufPtr, &Invalid);
+    if (BufPtr != &Buffer[0])   // Really, we want the chars in Buffer!
+      memcpy(&Buffer[0], BufPtr, LHSLen);
+    if (Invalid)
+      return true;
+    
+    BufPtr = &Buffer[LHSLen];
+    unsigned RHSLen = PP.getSpelling(RHS, BufPtr, &Invalid);
+    if (Invalid)
+      return true;
+    if (BufPtr != &Buffer[LHSLen])   // Really, we want the chars in Buffer!
+      memcpy(&Buffer[LHSLen], BufPtr, RHSLen);
+
+    // Trim excess space.
+    Buffer.resize(LHSLen+RHSLen);
+
+    // Plop the pasted result (including the trailing newline and null) into a
+    // scratch buffer where we can lex it.
+    Token ResultTokTmp;
+    ResultTokTmp.startToken();
+
+    // Claim that the tmp token is a string_literal so that we can get the
+    // character pointer back from CreateString in getLiteralData().
+    ResultTokTmp.setKind(tok::string_literal);
+    PP.CreateString(&Buffer[0], Buffer.size(), ResultTokTmp);
+    SourceLocation ResultTokLoc = ResultTokTmp.getLocation();
+    ResultTokStrPtr = ResultTokTmp.getLiteralData();
+
+    // Lex the resultant pasted token into Result.
+    Token Result;
+
+    if (Tok.is(tok::identifier) && RHS.is(tok::identifier)) {
+      // Common paste case: identifier+identifier = identifier.  Avoid creating
+      // a lexer and other overhead.
+      PP.IncrementPasteCounter(true);
+      Result.startToken();
+      Result.setKind(tok::identifier);
+      Result.setLocation(ResultTokLoc);
+      Result.setLength(LHSLen+RHSLen);
+    } else {
+      PP.IncrementPasteCounter(false);
+
+      assert(ResultTokLoc.isFileID() &&
+             "Should be a raw location into scratch buffer");
+      SourceManager &SourceMgr = PP.getSourceManager();
+      FileID LocFileID = SourceMgr.getFileID(ResultTokLoc);
+
+      bool Invalid = false;
+      const char *ScratchBufStart
+        = SourceMgr.getBufferData(LocFileID, &Invalid).data();
+      if (Invalid)
+        return false;
+
+      // Make a lexer to lex this string from.  Lex just this one token.
+      // Make a lexer object so that we lex and expand the paste result.
+      Lexer TL(SourceMgr.getLocForStartOfFile(LocFileID),
+               PP.getLangOptions(), ScratchBufStart,
+               ResultTokStrPtr, ResultTokStrPtr+LHSLen+RHSLen);
+
+      // Lex a token in raw mode.  This way it won't look up identifiers
+      // automatically, lexing off the end will return an eof token, and
+      // warnings are disabled.  This returns true if the result token is the
+      // entire buffer.
+      bool isInvalid = !TL.LexFromRawLexer(Result);
+
+      // If we got an EOF token, we didn't form even ONE token.  For example, we
+      // did "/ ## /" to get "//".
+      isInvalid |= Result.is(tok::eof);
+
+      // If pasting the two tokens didn't form a full new token, this is an
+      // error.  This occurs with "x ## +"  and other stuff.  Return with Tok
+      // unmodified and with RHS as the next token to lex.
+      if (isInvalid) {
+        // Test for the Microsoft extension of /##/ turning into // here on the
+        // error path.
+        if (PP.getLangOptions().Microsoft && Tok.is(tok::slash) &&
+            RHS.is(tok::slash)) {
+          HandleMicrosoftCommentPaste(Tok);
+          return true;
+        }
+
+        // Do not emit the warning when preprocessing assembler code.
+        if (!PP.getLangOptions().AsmPreprocessor) {
+          // Explicitly convert the token location to have proper instantiation
+          // information so that the user knows where it came from.
+          SourceManager &SM = PP.getSourceManager();
+          SourceLocation Loc =
+            SM.createInstantiationLoc(PasteOpLoc, InstantiateLocStart,
+                                      InstantiateLocEnd, 2);
+          PP.Diag(Loc, diag::err_pp_bad_paste)
+            << std::string(Buffer.begin(), Buffer.end());
+        }
+
+        // Do not consume the RHS.
+        --CurToken;
+      }
+
+      // Turn ## into 'unknown' to avoid # ## # from looking like a paste
+      // operator.
+      if (Result.is(tok::hashhash))
+        Result.setKind(tok::unknown);
+    }
+
+    // Transfer properties of the LHS over the the Result.
+    Result.setFlagValue(Token::StartOfLine , Tok.isAtStartOfLine());
+    Result.setFlagValue(Token::LeadingSpace, Tok.hasLeadingSpace());
+
+    // Finally, replace LHS with the result, consume the RHS, and iterate.
+    ++CurToken;
+    Tok = Result;
+  } while (!isAtEnd() && Tokens[CurToken].is(tok::hashhash));
+
+  // Now that we got the result token, it will be subject to expansion.  Since
+  // token pasting re-lexes the result token in raw mode, identifier information
+  // isn't looked up.  As such, if the result is an identifier, look up id info.
+  if (Tok.is(tok::identifier)) {
+    // Look up the identifier info for the token.  We disabled identifier lookup
+    // by saying we're skipping contents, so we need to do this manually.
+    PP.LookUpIdentifierInfo(Tok, ResultTokStrPtr);
+  }
+  return false;
+}
+
+/// isNextTokenLParen - If the next token lexed will pop this macro off the
+/// expansion stack, return 2.  If the next unexpanded token is a '(', return
+/// 1, otherwise return 0.
+unsigned TokenLexer::isNextTokenLParen() const {
+  // Out of tokens?
+  if (isAtEnd())
+    return 2;
+  return Tokens[CurToken].is(tok::l_paren);
+}
+
+
+/// HandleMicrosoftCommentPaste - In microsoft compatibility mode, /##/ pastes
+/// together to form a comment that comments out everything in the current
+/// macro, other active macros, and anything left on the current physical
+/// source line of the instantiated buffer.  Handle this by returning the
+/// first token on the next line.
+void TokenLexer::HandleMicrosoftCommentPaste(Token &Tok) {
+  // We 'comment out' the rest of this macro by just ignoring the rest of the
+  // tokens that have not been lexed yet, if any.
+
+  // Since this must be a macro, mark the macro enabled now that it is no longer
+  // being expanded.
+  assert(Macro && "Token streams can't paste comments");
+  Macro->EnableMacro();
+
+  PP.HandleMicrosoftCommentPaste(Tok);
+}
diff --git a/lib/Makefile b/lib/Makefile
new file mode 100755
index 0000000..538bf43
--- /dev/null
+++ b/lib/Makefile
@@ -0,0 +1,15 @@
+##===- lib/Makefile ----------------------------------------*- Makefile -*-===##
+# 
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+# 
+##===----------------------------------------------------------------------===##
+LEVEL = ../../..
+
+PARALLEL_DIRS = Headers Runtime Basic Lex Parse AST Sema CodeGen Analysis \
+                Checker Rewrite Frontend Index Driver
+
+include $(LEVEL)/Makefile.common
+
diff --git a/lib/Parse/Android.mk b/lib/Parse/Android.mk
new file mode 100644
index 0000000..918a42c
--- /dev/null
+++ b/lib/Parse/Android.mk
@@ -0,0 +1,35 @@
+LOCAL_PATH:= $(call my-dir)
+
+# For the host only
+# =====================================================
+include $(CLEAR_VARS)
+include $(CLEAR_TBLGEN_VARS)
+
+TBLGEN_TABLES :=    \
+	DiagnosticParseKinds.inc	\
+    DiagnosticCommonKinds.inc
+
+clang_parse_SRC_FILES :=	\
+	AttributeList.cpp	\
+	DeclSpec.cpp	\
+	MinimalAction.cpp	\
+	ParseCXXInlineMethods.cpp	\
+	ParseDecl.cpp	\
+	ParseDeclCXX.cpp	\
+	ParseExpr.cpp	\
+	ParseExprCXX.cpp	\
+	ParseInit.cpp	\
+	ParseObjc.cpp	\
+	ParsePragma.cpp	\
+	ParseStmt.cpp	\
+	ParseTemplate.cpp	\
+	ParseTentative.cpp	\
+	Parser.cpp
+
+LOCAL_SRC_FILES := $(clang_parse_SRC_FILES)
+
+LOCAL_MODULE:= libclangParse
+
+include $(CLANG_HOST_BUILD_MK)
+include $(CLANG_TBLGEN_RULES_MK)
+include $(BUILD_HOST_STATIC_LIBRARY)
diff --git a/lib/Parse/AttributeList.cpp b/lib/Parse/AttributeList.cpp
new file mode 100644
index 0000000..0ab6710
--- /dev/null
+++ b/lib/Parse/AttributeList.cpp
@@ -0,0 +1,123 @@
+//===--- AttributeList.cpp --------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the AttributeList class implementation
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Parse/AttributeList.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "llvm/ADT/StringSwitch.h"
+using namespace clang;
+
+AttributeList::AttributeList(IdentifierInfo *aName, SourceLocation aLoc,
+                             IdentifierInfo *sName, SourceLocation sLoc,
+                             IdentifierInfo *pName, SourceLocation pLoc,
+                             ActionBase::ExprTy **ExprList, unsigned numArgs,
+                             AttributeList *n, bool declspec, bool cxx0x)
+  : AttrName(aName), AttrLoc(aLoc), ScopeName(sName), ScopeLoc(sLoc),
+    ParmName(pName), ParmLoc(pLoc), NumArgs(numArgs), Next(n),
+    DeclspecAttribute(declspec), CXX0XAttribute(cxx0x) {
+
+  if (numArgs == 0)
+    Args = 0;
+  else {
+    Args = new ActionBase::ExprTy*[numArgs];
+    memcpy(Args, ExprList, numArgs*sizeof(Args[0]));
+  }
+}
+
+AttributeList::~AttributeList() {
+  if (Args) {
+    // FIXME: before we delete the vector, we need to make sure the Expr's
+    // have been deleted. Since ActionBase::ExprTy is "void", we are dependent
+    // on the actions module for actually freeing the memory. The specific
+    // hooks are ActOnDeclarator, ActOnTypeName, ActOnParamDeclaratorType,
+    // ParseField, ParseTag. Once these routines have freed the expression,
+    // they should zero out the Args slot (to indicate the memory has been
+    // freed). If any element of the vector is non-null, we should assert.
+    delete [] Args;
+  }
+  delete Next;
+}
+
+AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name) {
+  llvm::StringRef AttrName = Name->getName();
+
+  // Normalize the attribute name, __foo__ becomes foo.
+  if (AttrName.startswith("__") && AttrName.endswith("__"))
+    AttrName = AttrName.substr(2, AttrName.size() - 4);
+
+  return llvm::StringSwitch<AttributeList::Kind>(AttrName)
+    .Case("weak", AT_weak)
+    .Case("weakref", AT_weakref)
+    .Case("pure", AT_pure)
+    .Case("mode", AT_mode)
+    .Case("used", AT_used)
+    .Case("alias", AT_alias)
+    .Case("align", AT_aligned)
+    .Case("final", AT_final)
+    .Case("cdecl", AT_cdecl)
+    .Case("const", AT_const)
+    .Case("blocks", AT_blocks)
+    .Case("format", AT_format)
+    .Case("hiding", AT_hiding)
+    .Case("malloc", AT_malloc)
+    .Case("packed", AT_packed)
+    .Case("unused", AT_unused)
+    .Case("aligned", AT_aligned)
+    .Case("cleanup", AT_cleanup)
+    .Case("nodebug", AT_nodebug)
+    .Case("nonnull", AT_nonnull)
+    .Case("nothrow", AT_nothrow)
+    .Case("objc_gc", AT_objc_gc)
+    .Case("regparm", AT_regparm)
+    .Case("section", AT_section)
+    .Case("stdcall", AT_stdcall)
+    .Case("annotate", AT_annotate)
+    .Case("fastcall", AT_fastcall)
+    .Case("ibaction", AT_IBAction)
+    .Case("iboutlet", AT_IBOutlet)
+    .Case("noreturn", AT_noreturn)
+    .Case("noinline", AT_noinline)
+    .Case("override", AT_override)
+    .Case("sentinel", AT_sentinel)
+    .Case("NSObject", AT_nsobject)
+    .Case("dllimport", AT_dllimport)
+    .Case("dllexport", AT_dllexport)
+    .Case("may_alias", IgnoredAttribute) // FIXME: TBAA
+    .Case("base_check", AT_base_check)
+    .Case("deprecated", AT_deprecated)
+    .Case("visibility", AT_visibility)
+    .Case("destructor", AT_destructor)
+    .Case("format_arg", AT_format_arg)
+    .Case("gnu_inline", AT_gnu_inline)
+    .Case("weak_import", AT_weak_import)
+    .Case("vector_size", AT_vector_size)
+    .Case("constructor", AT_constructor)
+    .Case("unavailable", AT_unavailable)
+    .Case("overloadable", AT_overloadable)
+    .Case("address_space", AT_address_space)
+    .Case("always_inline", AT_always_inline)
+    .Case("returns_twice", IgnoredAttribute)
+    .Case("vec_type_hint", IgnoredAttribute)
+    .Case("objc_exception", AT_objc_exception)
+    .Case("ext_vector_type", AT_ext_vector_type)
+    .Case("transparent_union", AT_transparent_union)
+    .Case("analyzer_noreturn", AT_analyzer_noreturn)
+    .Case("warn_unused_result", AT_warn_unused_result)
+    .Case("carries_dependency", AT_carries_dependency)
+    .Case("ns_returns_not_retained", AT_ns_returns_not_retained)
+    .Case("ns_returns_retained", AT_ns_returns_retained)
+    .Case("cf_returns_not_retained", AT_cf_returns_not_retained)
+    .Case("cf_returns_retained", AT_cf_returns_retained)
+    .Case("reqd_work_group_size", AT_reqd_wg_size)
+    .Case("no_instrument_function", AT_no_instrument_function)
+    .Default(UnknownAttribute);
+}
diff --git a/lib/Parse/CMakeLists.txt b/lib/Parse/CMakeLists.txt
new file mode 100644
index 0000000..bec1c6e
--- /dev/null
+++ b/lib/Parse/CMakeLists.txt
@@ -0,0 +1,21 @@
+set(LLVM_NO_RTTI 1)
+
+add_clang_library(clangParse
+  AttributeList.cpp
+  DeclSpec.cpp
+  MinimalAction.cpp
+  ParseCXXInlineMethods.cpp
+  ParseDecl.cpp
+  ParseDeclCXX.cpp
+  ParseExpr.cpp
+  ParseExprCXX.cpp
+  ParseInit.cpp
+  ParseObjc.cpp
+  ParsePragma.cpp
+  ParseStmt.cpp
+  ParseTemplate.cpp
+  ParseTentative.cpp
+  Parser.cpp
+  )
+
+add_dependencies(clangParse ClangDiagnosticParse)
diff --git a/lib/Parse/DeclSpec.cpp b/lib/Parse/DeclSpec.cpp
new file mode 100644
index 0000000..5dc08b3
--- /dev/null
+++ b/lib/Parse/DeclSpec.cpp
@@ -0,0 +1,556 @@
+//===--- SemaDeclSpec.cpp - Declaration Specifier Semantic Analysis -------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements semantic analysis for declaration specifiers.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Parse/DeclSpec.h"
+#include "clang/Parse/ParseDiagnostic.h"
+#include "clang/Parse/Template.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Basic/LangOptions.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/ErrorHandling.h"
+#include <cstring>
+using namespace clang;
+
+
+static DiagnosticBuilder Diag(Diagnostic &D, SourceLocation Loc,
+                              SourceManager &SrcMgr, unsigned DiagID) {
+  return D.Report(FullSourceLoc(Loc, SrcMgr), DiagID);
+}
+
+
+void UnqualifiedId::setTemplateId(TemplateIdAnnotation *TemplateId) {
+  assert(TemplateId && "NULL template-id annotation?");
+  Kind = IK_TemplateId;
+  this->TemplateId = TemplateId;
+  StartLocation = TemplateId->TemplateNameLoc;
+  EndLocation = TemplateId->RAngleLoc;
+}
+
+void UnqualifiedId::setConstructorTemplateId(TemplateIdAnnotation *TemplateId) {
+  assert(TemplateId && "NULL template-id annotation?");
+  Kind = IK_ConstructorTemplateId;
+  this->TemplateId = TemplateId;
+  StartLocation = TemplateId->TemplateNameLoc;
+  EndLocation = TemplateId->RAngleLoc;
+}
+
+/// DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function.
+/// "TheDeclarator" is the declarator that this will be added to.
+DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, bool isVariadic,
+                                             SourceLocation EllipsisLoc,
+                                             ParamInfo *ArgInfo,
+                                             unsigned NumArgs,
+                                             unsigned TypeQuals,
+                                             bool hasExceptionSpec,
+                                             SourceLocation ThrowLoc,
+                                             bool hasAnyExceptionSpec,
+                                             ActionBase::TypeTy **Exceptions,
+                                             SourceRange *ExceptionRanges,
+                                             unsigned NumExceptions,
+                                             SourceLocation LPLoc,
+                                             SourceLocation RPLoc,
+                                             Declarator &TheDeclarator) {
+  DeclaratorChunk I;
+  I.Kind                 = Function;
+  I.Loc                  = LPLoc;
+  I.EndLoc               = RPLoc;
+  I.Fun.hasPrototype     = hasProto;
+  I.Fun.isVariadic       = isVariadic;
+  I.Fun.EllipsisLoc      = EllipsisLoc.getRawEncoding();
+  I.Fun.DeleteArgInfo    = false;
+  I.Fun.TypeQuals        = TypeQuals;
+  I.Fun.NumArgs          = NumArgs;
+  I.Fun.ArgInfo          = 0;
+  I.Fun.hasExceptionSpec = hasExceptionSpec;
+  I.Fun.ThrowLoc         = ThrowLoc.getRawEncoding();
+  I.Fun.hasAnyExceptionSpec = hasAnyExceptionSpec;
+  I.Fun.NumExceptions    = NumExceptions;
+  I.Fun.Exceptions       = 0;
+
+  // new[] an argument array if needed.
+  if (NumArgs) {
+    // If the 'InlineParams' in Declarator is unused and big enough, put our
+    // parameter list there (in an effort to avoid new/delete traffic).  If it
+    // is already used (consider a function returning a function pointer) or too
+    // small (function taking too many arguments), go to the heap.
+    if (!TheDeclarator.InlineParamsUsed &&
+        NumArgs <= llvm::array_lengthof(TheDeclarator.InlineParams)) {
+      I.Fun.ArgInfo = TheDeclarator.InlineParams;
+      I.Fun.DeleteArgInfo = false;
+      TheDeclarator.InlineParamsUsed = true;
+    } else {
+      I.Fun.ArgInfo = new DeclaratorChunk::ParamInfo[NumArgs];
+      I.Fun.DeleteArgInfo = true;
+    }
+    memcpy(I.Fun.ArgInfo, ArgInfo, sizeof(ArgInfo[0])*NumArgs);
+  }
+  // new[] an exception array if needed
+  if (NumExceptions) {
+    I.Fun.Exceptions = new DeclaratorChunk::TypeAndRange[NumExceptions];
+    for (unsigned i = 0; i != NumExceptions; ++i) {
+      I.Fun.Exceptions[i].Ty = Exceptions[i];
+      I.Fun.Exceptions[i].Range = ExceptionRanges[i];
+    }
+  }
+  return I;
+}
+
+/// getParsedSpecifiers - Return a bitmask of which flavors of specifiers this
+/// declaration specifier includes.
+///
+unsigned DeclSpec::getParsedSpecifiers() const {
+  unsigned Res = 0;
+  if (StorageClassSpec != SCS_unspecified ||
+      SCS_thread_specified)
+    Res |= PQ_StorageClassSpecifier;
+
+  if (TypeQualifiers != TQ_unspecified)
+    Res |= PQ_TypeQualifier;
+
+  if (hasTypeSpecifier())
+    Res |= PQ_TypeSpecifier;
+
+  if (FS_inline_specified || FS_virtual_specified || FS_explicit_specified)
+    Res |= PQ_FunctionSpecifier;
+  return Res;
+}
+
+template <class T> static bool BadSpecifier(T TNew, T TPrev,
+                                            const char *&PrevSpec,
+                                            unsigned &DiagID) {
+  PrevSpec = DeclSpec::getSpecifierName(TPrev);
+  DiagID = (TNew == TPrev ? diag::ext_duplicate_declspec
+            : diag::err_invalid_decl_spec_combination);
+  return true;
+}
+
+const char *DeclSpec::getSpecifierName(DeclSpec::SCS S) {
+  switch (S) {
+  case DeclSpec::SCS_unspecified: return "unspecified";
+  case DeclSpec::SCS_typedef:     return "typedef";
+  case DeclSpec::SCS_extern:      return "extern";
+  case DeclSpec::SCS_static:      return "static";
+  case DeclSpec::SCS_auto:        return "auto";
+  case DeclSpec::SCS_register:    return "register";
+  case DeclSpec::SCS_private_extern: return "__private_extern__";
+  case DeclSpec::SCS_mutable:     return "mutable";
+  }
+  llvm_unreachable("Unknown typespec!");
+}
+
+const char *DeclSpec::getSpecifierName(TSW W) {
+  switch (W) {
+  case TSW_unspecified: return "unspecified";
+  case TSW_short:       return "short";
+  case TSW_long:        return "long";
+  case TSW_longlong:    return "long long";
+  }
+  llvm_unreachable("Unknown typespec!");
+}
+
+const char *DeclSpec::getSpecifierName(TSC C) {
+  switch (C) {
+  case TSC_unspecified: return "unspecified";
+  case TSC_imaginary:   return "imaginary";
+  case TSC_complex:     return "complex";
+  }
+  llvm_unreachable("Unknown typespec!");
+}
+
+
+const char *DeclSpec::getSpecifierName(TSS S) {
+  switch (S) {
+  case TSS_unspecified: return "unspecified";
+  case TSS_signed:      return "signed";
+  case TSS_unsigned:    return "unsigned";
+  }
+  llvm_unreachable("Unknown typespec!");
+}
+
+const char *DeclSpec::getSpecifierName(DeclSpec::TST T) {
+  switch (T) {
+  case DeclSpec::TST_unspecified: return "unspecified";
+  case DeclSpec::TST_void:        return "void";
+  case DeclSpec::TST_char:        return "char";
+  case DeclSpec::TST_wchar:       return "wchar_t";
+  case DeclSpec::TST_char16:      return "char16_t";
+  case DeclSpec::TST_char32:      return "char32_t";
+  case DeclSpec::TST_int:         return "int";
+  case DeclSpec::TST_float:       return "float";
+  case DeclSpec::TST_double:      return "double";
+  case DeclSpec::TST_bool:        return "_Bool";
+  case DeclSpec::TST_decimal32:   return "_Decimal32";
+  case DeclSpec::TST_decimal64:   return "_Decimal64";
+  case DeclSpec::TST_decimal128:  return "_Decimal128";
+  case DeclSpec::TST_enum:        return "enum";
+  case DeclSpec::TST_class:       return "class";
+  case DeclSpec::TST_union:       return "union";
+  case DeclSpec::TST_struct:      return "struct";
+  case DeclSpec::TST_typename:    return "type-name";
+  case DeclSpec::TST_typeofType:
+  case DeclSpec::TST_typeofExpr:  return "typeof";
+  case DeclSpec::TST_auto:        return "auto";
+  case DeclSpec::TST_decltype:    return "(decltype)";
+  case DeclSpec::TST_error:       return "(error)";
+  }
+  llvm_unreachable("Unknown typespec!");
+}
+
+const char *DeclSpec::getSpecifierName(TQ T) {
+  switch (T) {
+  case DeclSpec::TQ_unspecified: return "unspecified";
+  case DeclSpec::TQ_const:       return "const";
+  case DeclSpec::TQ_restrict:    return "restrict";
+  case DeclSpec::TQ_volatile:    return "volatile";
+  }
+  llvm_unreachable("Unknown typespec!");
+}
+
+bool DeclSpec::SetStorageClassSpec(SCS S, SourceLocation Loc,
+                                   const char *&PrevSpec,
+                                   unsigned &DiagID) {
+  if (StorageClassSpec != SCS_unspecified)
+    return BadSpecifier(S, (SCS)StorageClassSpec, PrevSpec, DiagID);
+  StorageClassSpec = S;
+  StorageClassSpecLoc = Loc;
+  assert((unsigned)S == StorageClassSpec && "SCS constants overflow bitfield");
+  return false;
+}
+
+bool DeclSpec::SetStorageClassSpecThread(SourceLocation Loc,
+                                         const char *&PrevSpec,
+                                         unsigned &DiagID) {
+  if (SCS_thread_specified) {
+    PrevSpec = "__thread";
+    DiagID = diag::ext_duplicate_declspec;
+    return true;
+  }
+  SCS_thread_specified = true;
+  SCS_threadLoc = Loc;
+  return false;
+}
+
+
+/// These methods set the specified attribute of the DeclSpec, but return true
+/// and ignore the request if invalid (e.g. "extern" then "auto" is
+/// specified).
+bool DeclSpec::SetTypeSpecWidth(TSW W, SourceLocation Loc,
+                                const char *&PrevSpec,
+                                unsigned &DiagID) {
+  if (TypeSpecWidth != TSW_unspecified &&
+      // Allow turning long -> long long.
+      (W != TSW_longlong || TypeSpecWidth != TSW_long))
+    return BadSpecifier(W, (TSW)TypeSpecWidth, PrevSpec, DiagID);
+  TypeSpecWidth = W;
+  TSWLoc = Loc;
+  if (TypeAltiVecVector && ((TypeSpecWidth == TSW_long) || (TypeSpecWidth == TSW_longlong))) {
+    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
+    DiagID = diag::warn_vector_long_decl_spec_combination;
+    return true;
+  }
+  return false;
+}
+
+bool DeclSpec::SetTypeSpecComplex(TSC C, SourceLocation Loc,
+                                  const char *&PrevSpec,
+                                  unsigned &DiagID) {
+  if (TypeSpecComplex != TSC_unspecified)
+    return BadSpecifier(C, (TSC)TypeSpecComplex, PrevSpec, DiagID);
+  TypeSpecComplex = C;
+  TSCLoc = Loc;
+  return false;
+}
+
+bool DeclSpec::SetTypeSpecSign(TSS S, SourceLocation Loc,
+                               const char *&PrevSpec,
+                               unsigned &DiagID) {
+  if (TypeSpecSign != TSS_unspecified)
+    return BadSpecifier(S, (TSS)TypeSpecSign, PrevSpec, DiagID);
+  TypeSpecSign = S;
+  TSSLoc = Loc;
+  return false;
+}
+
+bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
+                               const char *&PrevSpec,
+                               unsigned &DiagID,
+                               void *Rep, bool Owned) {
+  if (TypeSpecType != TST_unspecified) {
+    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
+    DiagID = diag::err_invalid_decl_spec_combination;
+    return true;
+  }
+  TypeSpecType = T;
+  TypeRep = Rep;
+  TSTLoc = Loc;
+  TypeSpecOwned = Owned;
+  if (TypeAltiVecVector && (TypeSpecType == TST_double)) {
+    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
+    DiagID = diag::err_invalid_vector_double_decl_spec_combination;
+    return true;
+  }
+  return false;
+}
+
+bool DeclSpec::SetTypeAltiVecVector(bool isAltiVecVector, SourceLocation Loc,
+                          const char *&PrevSpec, unsigned &DiagID) {
+  if (TypeSpecType != TST_unspecified) {
+    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
+    DiagID = diag::err_invalid_vector_decl_spec_combination;
+    return true;
+  }
+  TypeAltiVecVector = isAltiVecVector;
+  AltiVecLoc = Loc;
+  return false;
+}
+
+bool DeclSpec::SetTypeAltiVecPixel(bool isAltiVecPixel, SourceLocation Loc,
+                          const char *&PrevSpec, unsigned &DiagID) {
+  if (!TypeAltiVecVector || (TypeSpecType != TST_unspecified)) {
+    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
+    DiagID = diag::err_invalid_pixel_decl_spec_combination;
+    return true;
+  }
+  TypeSpecType = TST_int;
+  TypeSpecSign = TSS_unsigned;
+  TypeSpecWidth = TSW_short;
+  TypeAltiVecPixel = isAltiVecPixel;
+  TSTLoc = Loc;
+  return false;
+}
+
+bool DeclSpec::SetTypeSpecError() {
+  TypeSpecType = TST_error;
+  TypeRep = 0;
+  TSTLoc = SourceLocation();
+  return false;
+}
+
+bool DeclSpec::SetTypeQual(TQ T, SourceLocation Loc, const char *&PrevSpec,
+                           unsigned &DiagID, const LangOptions &Lang) {
+  // Duplicates turn into warnings pre-C99.
+  if ((TypeQualifiers & T) && !Lang.C99)
+    return BadSpecifier(T, T, PrevSpec, DiagID);
+  TypeQualifiers |= T;
+
+  switch (T) {
+  default: assert(0 && "Unknown type qualifier!");
+  case TQ_const:    TQ_constLoc = Loc; break;
+  case TQ_restrict: TQ_restrictLoc = Loc; break;
+  case TQ_volatile: TQ_volatileLoc = Loc; break;
+  }
+  return false;
+}
+
+bool DeclSpec::SetFunctionSpecInline(SourceLocation Loc, const char *&PrevSpec,
+                                     unsigned &DiagID) {
+  // 'inline inline' is ok.
+  FS_inline_specified = true;
+  FS_inlineLoc = Loc;
+  return false;
+}
+
+bool DeclSpec::SetFunctionSpecVirtual(SourceLocation Loc, const char *&PrevSpec,
+                                      unsigned &DiagID) {
+  // 'virtual virtual' is ok.
+  FS_virtual_specified = true;
+  FS_virtualLoc = Loc;
+  return false;
+}
+
+bool DeclSpec::SetFunctionSpecExplicit(SourceLocation Loc, const char *&PrevSpec,
+                                       unsigned &DiagID) {
+  // 'explicit explicit' is ok.
+  FS_explicit_specified = true;
+  FS_explicitLoc = Loc;
+  return false;
+}
+
+bool DeclSpec::SetFriendSpec(SourceLocation Loc, const char *&PrevSpec,
+                             unsigned &DiagID) {
+  if (Friend_specified) {
+    PrevSpec = "friend";
+    DiagID = diag::ext_duplicate_declspec;
+    return true;
+  }
+
+  Friend_specified = true;
+  FriendLoc = Loc;
+  return false;
+}
+
+bool DeclSpec::SetConstexprSpec(SourceLocation Loc, const char *&PrevSpec,
+                                unsigned &DiagID) {
+  // 'constexpr constexpr' is ok.
+  Constexpr_specified = true;
+  ConstexprLoc = Loc;
+  return false;
+}
+
+void DeclSpec::setProtocolQualifiers(const ActionBase::DeclPtrTy *Protos,
+                                     unsigned NP,
+                                     SourceLocation *ProtoLocs,
+                                     SourceLocation LAngleLoc) {
+  if (NP == 0) return;
+  ProtocolQualifiers = new ActionBase::DeclPtrTy[NP];
+  ProtocolLocs = new SourceLocation[NP];
+  memcpy((void*)ProtocolQualifiers, Protos, sizeof(ActionBase::DeclPtrTy)*NP);
+  memcpy(ProtocolLocs, ProtoLocs, sizeof(SourceLocation)*NP);
+  NumProtocolQualifiers = NP;
+  ProtocolLAngleLoc = LAngleLoc;
+}
+
+void DeclSpec::SaveWrittenBuiltinSpecs() {
+  writtenBS.Sign = getTypeSpecSign();
+  writtenBS.Width = getTypeSpecWidth();
+  writtenBS.Type = getTypeSpecType();
+  // Search the list of attributes for the presence of a mode attribute.
+  writtenBS.ModeAttr = false;
+  AttributeList* attrs = getAttributes();
+  while (attrs) {
+    if (attrs->getKind() == AttributeList::AT_mode) {
+      writtenBS.ModeAttr = true;
+      break;
+    }
+    attrs = attrs->getNext();
+  }
+}
+
+/// Finish - This does final analysis of the declspec, rejecting things like
+/// "_Imaginary" (lacking an FP type).  This returns a diagnostic to issue or
+/// diag::NUM_DIAGNOSTICS if there is no error.  After calling this method,
+/// DeclSpec is guaranteed self-consistent, even if an error occurred.
+void DeclSpec::Finish(Diagnostic &D, Preprocessor &PP) {
+  // Before possibly changing their values, save specs as written.
+  SaveWrittenBuiltinSpecs();
+  SaveStorageSpecifierAsWritten();
+
+  // Check the type specifier components first.
+  SourceManager &SrcMgr = PP.getSourceManager();
+
+  // signed/unsigned are only valid with int/char/wchar_t.
+  if (TypeSpecSign != TSS_unspecified) {
+    if (TypeSpecType == TST_unspecified)
+      TypeSpecType = TST_int; // unsigned -> unsigned int, signed -> signed int.
+    else if (TypeSpecType != TST_int  &&
+             TypeSpecType != TST_char && TypeSpecType != TST_wchar) {
+      Diag(D, TSSLoc, SrcMgr, diag::err_invalid_sign_spec)
+        << getSpecifierName((TST)TypeSpecType);
+      // signed double -> double.
+      TypeSpecSign = TSS_unspecified;
+    }
+  }
+
+  // Validate the width of the type.
+  switch (TypeSpecWidth) {
+  case TSW_unspecified: break;
+  case TSW_short:    // short int
+  case TSW_longlong: // long long int
+    if (TypeSpecType == TST_unspecified)
+      TypeSpecType = TST_int; // short -> short int, long long -> long long int.
+    else if (TypeSpecType != TST_int) {
+      Diag(D, TSWLoc, SrcMgr,
+           TypeSpecWidth == TSW_short ? diag::err_invalid_short_spec
+                                      : diag::err_invalid_longlong_spec)
+        <<  getSpecifierName((TST)TypeSpecType);
+      TypeSpecType = TST_int;
+    }
+    break;
+  case TSW_long:  // long double, long int
+    if (TypeSpecType == TST_unspecified)
+      TypeSpecType = TST_int;  // long -> long int.
+    else if (TypeSpecType != TST_int && TypeSpecType != TST_double) {
+      Diag(D, TSWLoc, SrcMgr, diag::err_invalid_long_spec)
+        << getSpecifierName((TST)TypeSpecType);
+      TypeSpecType = TST_int;
+    }
+    break;
+  }
+
+  // TODO: if the implementation does not implement _Complex or _Imaginary,
+  // disallow their use.  Need information about the backend.
+  if (TypeSpecComplex != TSC_unspecified) {
+    if (TypeSpecType == TST_unspecified) {
+      Diag(D, TSCLoc, SrcMgr, diag::ext_plain_complex)
+        << FixItHint::CreateInsertion(
+                              PP.getLocForEndOfToken(getTypeSpecComplexLoc()),
+                                                 " double");
+      TypeSpecType = TST_double;   // _Complex -> _Complex double.
+    } else if (TypeSpecType == TST_int || TypeSpecType == TST_char) {
+      // Note that this intentionally doesn't include _Complex _Bool.
+      Diag(D, TSTLoc, SrcMgr, diag::ext_integer_complex);
+    } else if (TypeSpecType != TST_float && TypeSpecType != TST_double) {
+      Diag(D, TSCLoc, SrcMgr, diag::err_invalid_complex_spec)
+        << getSpecifierName((TST)TypeSpecType);
+      TypeSpecComplex = TSC_unspecified;
+    }
+  }
+
+  // C++ [class.friend]p6:
+  //   No storage-class-specifier shall appear in the decl-specifier-seq
+  //   of a friend declaration.
+  if (isFriendSpecified() && getStorageClassSpec()) {
+    DeclSpec::SCS SC = getStorageClassSpec();
+    const char *SpecName = getSpecifierName(SC);
+
+    SourceLocation SCLoc = getStorageClassSpecLoc();
+    SourceLocation SCEndLoc = SCLoc.getFileLocWithOffset(strlen(SpecName));
+
+    Diag(D, SCLoc, SrcMgr, diag::err_friend_storage_spec)
+      << SpecName
+      << FixItHint::CreateRemoval(SourceRange(SCLoc, SCEndLoc));
+
+    ClearStorageClassSpecs();
+  }
+
+
+  // Okay, now we can infer the real type.
+
+  // TODO: return "auto function" and other bad things based on the real type.
+
+  // 'data definition has no type or storage class'?
+}
+
+bool DeclSpec::isMissingDeclaratorOk() {
+  TST tst = getTypeSpecType();
+  return (tst == TST_union
+       || tst == TST_struct
+       || tst == TST_class
+       || tst == TST_enum
+          ) && getTypeRep() != 0 && StorageClassSpec != DeclSpec::SCS_typedef;
+}
+
+void UnqualifiedId::clear() {
+  if (Kind == IK_TemplateId)
+    TemplateId->Destroy();
+  
+  Kind = IK_Identifier;
+  Identifier = 0;
+  StartLocation = SourceLocation();
+  EndLocation = SourceLocation();
+}
+
+void UnqualifiedId::setOperatorFunctionId(SourceLocation OperatorLoc, 
+                                          OverloadedOperatorKind Op,
+                                          SourceLocation SymbolLocations[3]) {
+  Kind = IK_OperatorFunctionId;
+  StartLocation = OperatorLoc;
+  EndLocation = OperatorLoc;
+  OperatorFunctionId.Operator = Op;
+  for (unsigned I = 0; I != 3; ++I) {
+    OperatorFunctionId.SymbolLocations[I] = SymbolLocations[I].getRawEncoding();
+    
+    if (SymbolLocations[I].isValid())
+      EndLocation = SymbolLocations[I];
+  }
+}
diff --git a/lib/Parse/Makefile b/lib/Parse/Makefile
new file mode 100644
index 0000000..6a5540f
--- /dev/null
+++ b/lib/Parse/Makefile
@@ -0,0 +1,21 @@
+##===- clang/lib/Parse/Makefile ----------------------------*- Makefile -*-===##
+# 
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+# 
+##===----------------------------------------------------------------------===##
+#
+#  This implements the Parser library for the C-Language front-end.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../../../..
+LIBRARYNAME := clangParse
+BUILD_ARCHIVE = 1
+
+CPP.Flags += -I$(PROJ_SRC_DIR)/../../include -I$(PROJ_OBJ_DIR)/../../include
+
+include $(LEVEL)/Makefile.common
+
diff --git a/lib/Parse/MinimalAction.cpp b/lib/Parse/MinimalAction.cpp
new file mode 100644
index 0000000..5a03767
--- /dev/null
+++ b/lib/Parse/MinimalAction.cpp
@@ -0,0 +1,279 @@
+//===--- MinimalAction.cpp - Implement the MinimalAction class ------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements the MinimalAction interface.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Parse/Parser.h"
+#include "clang/Parse/DeclSpec.h"
+#include "clang/Parse/Scope.h"
+#include "clang/Basic/TargetInfo.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/RecyclingAllocator.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace clang;
+
+///  Out-of-line virtual destructor to provide home for ActionBase class.
+ActionBase::~ActionBase() {}
+
+///  Out-of-line virtual destructor to provide home for Action class.
+Action::~Action() {}
+
+Action::ObjCMessageKind Action::getObjCMessageKind(Scope *S,
+                                                   IdentifierInfo *Name,
+                                                   SourceLocation NameLoc,
+                                                   bool IsSuper,
+                                                   bool HasTrailingDot,
+                                                   TypeTy *&ReceiverType) {
+  ReceiverType = 0;
+
+  if (IsSuper && !HasTrailingDot && S->isInObjcMethodScope())
+    return ObjCSuperMessage;
+      
+  if (TypeTy *TyName = getTypeName(*Name, NameLoc, S)) {
+    DeclSpec DS;
+    const char *PrevSpec = 0;
+    unsigned DiagID = 0;
+    if (!DS.SetTypeSpecType(DeclSpec::TST_typename, NameLoc, PrevSpec,
+                            DiagID, TyName)) {
+      DS.SetRangeEnd(NameLoc);
+      Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
+      TypeResult Ty = ActOnTypeName(S, DeclaratorInfo);
+      if (!Ty.isInvalid())
+        ReceiverType = Ty.get();
+    }
+    return ObjCClassMessage;
+  }
+      
+  return ObjCInstanceMessage;
+}
+
+// Defined out-of-line here because of dependecy on AttributeList
+Action::DeclPtrTy Action::ActOnUsingDirective(Scope *CurScope,
+                                              SourceLocation UsingLoc,
+                                              SourceLocation NamespcLoc,
+                                              CXXScopeSpec &SS,
+                                              SourceLocation IdentLoc,
+                                              IdentifierInfo *NamespcName,
+                                              AttributeList *AttrList) {
+
+  // FIXME: Parser seems to assume that Action::ActOn* takes ownership over
+  // passed AttributeList, however other actions don't free it, is it
+  // temporary state or bug?
+  delete AttrList;
+  return DeclPtrTy();
+}
+
+// Defined out-of-line here because of dependency on AttributeList
+Action::DeclPtrTy Action::ActOnUsingDeclaration(Scope *CurScope,
+                                                AccessSpecifier AS,
+                                                bool HasUsingKeyword,
+                                                SourceLocation UsingLoc,
+                                                CXXScopeSpec &SS,
+                                                UnqualifiedId &Name,
+                                                AttributeList *AttrList,
+                                                bool IsTypeName,
+                                                SourceLocation TypenameLoc) {
+
+  // FIXME: Parser seems to assume that Action::ActOn* takes ownership over
+  // passed AttributeList, however other actions don't free it, is it
+  // temporary state or bug?
+  delete AttrList;
+  return DeclPtrTy();
+}
+
+
+void PrettyStackTraceActionsDecl::print(llvm::raw_ostream &OS) const {
+  if (Loc.isValid()) {
+    Loc.print(OS, SM);
+    OS << ": ";
+  }
+  OS << Message;
+
+  std::string Name = Actions.getDeclName(TheDecl);
+  if (!Name.empty())
+    OS << " '" << Name << '\'';
+
+  OS << '\n';
+}
+
+/// TypeNameInfo - A link exists here for each scope that an identifier is
+/// defined.
+namespace {
+  struct TypeNameInfo {
+    TypeNameInfo *Prev;
+    bool isTypeName;
+
+    TypeNameInfo(bool istypename, TypeNameInfo *prev) {
+      isTypeName = istypename;
+      Prev = prev;
+    }
+  };
+
+  struct TypeNameInfoTable {
+    llvm::RecyclingAllocator<llvm::BumpPtrAllocator, TypeNameInfo> Allocator;
+
+    void AddEntry(bool isTypename, IdentifierInfo *II) {
+      TypeNameInfo *TI = Allocator.Allocate<TypeNameInfo>();
+      new (TI) TypeNameInfo(isTypename, II->getFETokenInfo<TypeNameInfo>());
+      II->setFETokenInfo(TI);
+    }
+
+    void DeleteEntry(TypeNameInfo *Entry) {
+      Entry->~TypeNameInfo();
+      Allocator.Deallocate(Entry);
+    }
+  };
+}
+
+static TypeNameInfoTable *getTable(void *TP) {
+  return static_cast<TypeNameInfoTable*>(TP);
+}
+
+MinimalAction::MinimalAction(Preprocessor &pp)
+  : Idents(pp.getIdentifierTable()), PP(pp) {
+  TypeNameInfoTablePtr = new TypeNameInfoTable();
+}
+
+MinimalAction::~MinimalAction() {
+  delete getTable(TypeNameInfoTablePtr);
+}
+
+void MinimalAction::ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) {
+  TUScope = S;
+
+  TypeNameInfoTable &TNIT = *getTable(TypeNameInfoTablePtr);
+
+  if (PP.getTargetInfo().getPointerWidth(0) >= 64) {
+    // Install [u]int128_t for 64-bit targets.
+    TNIT.AddEntry(true, &Idents.get("__int128_t"));
+    TNIT.AddEntry(true, &Idents.get("__uint128_t"));
+  }
+
+  if (PP.getLangOptions().ObjC1) {
+    // Recognize the ObjC built-in type identifiers as types.
+    TNIT.AddEntry(true, &Idents.get("id"));
+    TNIT.AddEntry(true, &Idents.get("SEL"));
+    TNIT.AddEntry(true, &Idents.get("Class"));
+    TNIT.AddEntry(true, &Idents.get("Protocol"));
+  }
+}
+
+/// isTypeName - This looks at the IdentifierInfo::FETokenInfo field to
+/// determine whether the name is a type name (objc class name or typedef) or
+/// not in this scope.
+///
+/// FIXME: Use the passed CXXScopeSpec for accurate C++ type checking.
+Action::TypeTy *
+MinimalAction::getTypeName(IdentifierInfo &II, SourceLocation Loc,
+                           Scope *S, CXXScopeSpec *SS,
+                           bool isClassName, TypeTy *ObjectType) {
+  if (TypeNameInfo *TI = II.getFETokenInfo<TypeNameInfo>())
+    if (TI->isTypeName)
+      return TI;
+  return 0;
+}
+
+/// isCurrentClassName - Always returns false, because MinimalAction
+/// does not support C++ classes with constructors.
+bool MinimalAction::isCurrentClassName(const IdentifierInfo &, Scope *,
+                                       const CXXScopeSpec *) {
+  return false;
+}
+
+TemplateNameKind
+MinimalAction::isTemplateName(Scope *S,
+                              CXXScopeSpec &SS,
+                              UnqualifiedId &Name,
+                              TypeTy *ObjectType,
+                              bool EnteringScope,
+                              TemplateTy &TemplateDecl) {
+  return TNK_Non_template;
+}
+
+/// ActOnDeclarator - If this is a typedef declarator, we modify the
+/// IdentifierInfo::FETokenInfo field to keep track of this fact, until S is
+/// popped.
+Action::DeclPtrTy
+MinimalAction::ActOnDeclarator(Scope *S, Declarator &D) {
+  IdentifierInfo *II = D.getIdentifier();
+
+  // If there is no identifier associated with this declarator, bail out.
+  if (II == 0) return DeclPtrTy();
+
+  TypeNameInfo *weCurrentlyHaveTypeInfo = II->getFETokenInfo<TypeNameInfo>();
+  bool isTypeName =
+    D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef;
+
+  // this check avoids creating TypeNameInfo objects for the common case.
+  // It does need to handle the uncommon case of shadowing a typedef name with a
+  // non-typedef name. e.g. { typedef int a; a xx; { int a; } }
+  if (weCurrentlyHaveTypeInfo || isTypeName) {
+    // Allocate and add the 'TypeNameInfo' "decl".
+    getTable(TypeNameInfoTablePtr)->AddEntry(isTypeName, II);
+
+    // Remember that this needs to be removed when the scope is popped.
+    S->AddDecl(DeclPtrTy::make(II));
+  }
+  return DeclPtrTy();
+}
+
+Action::DeclPtrTy
+MinimalAction::ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
+                                        IdentifierInfo *ClassName,
+                                        SourceLocation ClassLoc,
+                                        IdentifierInfo *SuperName,
+                                        SourceLocation SuperLoc,
+                                        const DeclPtrTy *ProtoRefs,
+                                        unsigned NumProtocols,
+                                        const SourceLocation *ProtoLocs,
+                                        SourceLocation EndProtoLoc,
+                                        AttributeList *AttrList) {
+  // Allocate and add the 'TypeNameInfo' "decl".
+  getTable(TypeNameInfoTablePtr)->AddEntry(true, ClassName);
+  return DeclPtrTy();
+}
+
+/// ActOnForwardClassDeclaration -
+/// Scope will always be top level file scope.
+Action::DeclPtrTy
+MinimalAction::ActOnForwardClassDeclaration(SourceLocation AtClassLoc,
+                                            IdentifierInfo **IdentList,
+                                            SourceLocation *IdentLocs,
+                                            unsigned NumElts) {
+  for (unsigned i = 0; i != NumElts; ++i) {
+    // Allocate and add the 'TypeNameInfo' "decl".
+    getTable(TypeNameInfoTablePtr)->AddEntry(true, IdentList[i]);
+
+    // Remember that this needs to be removed when the scope is popped.
+    TUScope->AddDecl(DeclPtrTy::make(IdentList[i]));
+  }
+  return DeclPtrTy();
+}
+
+/// ActOnPopScope - When a scope is popped, if any typedefs are now
+/// out-of-scope, they are removed from the IdentifierInfo::FETokenInfo field.
+void MinimalAction::ActOnPopScope(SourceLocation Loc, Scope *S) {
+  TypeNameInfoTable &Table = *getTable(TypeNameInfoTablePtr);
+
+  for (Scope::decl_iterator I = S->decl_begin(), E = S->decl_end();
+       I != E; ++I) {
+    IdentifierInfo &II = *(*I).getAs<IdentifierInfo>();
+    TypeNameInfo *TI = II.getFETokenInfo<TypeNameInfo>();
+    assert(TI && "This decl didn't get pushed??");
+
+    if (TI) {
+      TypeNameInfo *Next = TI->Prev;
+      Table.DeleteEntry(TI);
+
+      II.setFETokenInfo(Next);
+    }
+  }
+}
diff --git a/lib/Parse/ParseCXXInlineMethods.cpp b/lib/Parse/ParseCXXInlineMethods.cpp
new file mode 100644
index 0000000..5405c0c
--- /dev/null
+++ b/lib/Parse/ParseCXXInlineMethods.cpp
@@ -0,0 +1,333 @@
+//===--- ParseCXXInlineMethods.cpp - C++ class inline methods parsing------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements parsing for C++ class inline methods.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Parse/ParseDiagnostic.h"
+#include "clang/Parse/Parser.h"
+#include "clang/Parse/DeclSpec.h"
+#include "clang/Parse/Scope.h"
+using namespace clang;
+
+/// ParseCXXInlineMethodDef - We parsed and verified that the specified
+/// Declarator is a well formed C++ inline method definition. Now lex its body
+/// and store its tokens for parsing after the C++ class is complete.
+Parser::DeclPtrTy
+Parser::ParseCXXInlineMethodDef(AccessSpecifier AS, Declarator &D,
+                                const ParsedTemplateInfo &TemplateInfo) {
+  assert(D.getTypeObject(0).Kind == DeclaratorChunk::Function &&
+         "This isn't a function declarator!");
+  assert((Tok.is(tok::l_brace) || Tok.is(tok::colon) || Tok.is(tok::kw_try)) &&
+         "Current token not a '{', ':' or 'try'!");
+
+  Action::MultiTemplateParamsArg TemplateParams(Actions,
+          TemplateInfo.TemplateParams ? TemplateInfo.TemplateParams->data() : 0,
+          TemplateInfo.TemplateParams ? TemplateInfo.TemplateParams->size() : 0);
+
+  DeclPtrTy FnD;
+  if (D.getDeclSpec().isFriendSpecified())
+    // FIXME: Friend templates
+    FnD = Actions.ActOnFriendFunctionDecl(CurScope, D, true,
+                                          move(TemplateParams));
+  else // FIXME: pass template information through
+    FnD = Actions.ActOnCXXMemberDeclarator(CurScope, AS, D,
+                                           move(TemplateParams), 0, 0,
+                                           /*IsDefinition*/true);
+
+  HandleMemberFunctionDefaultArgs(D, FnD);
+
+  // Consume the tokens and store them for later parsing.
+
+  getCurrentClass().MethodDefs.push_back(LexedMethod(FnD));
+  getCurrentClass().MethodDefs.back().TemplateScope
+    = CurScope->isTemplateParamScope();
+  CachedTokens &Toks = getCurrentClass().MethodDefs.back().Toks;
+
+  tok::TokenKind kind = Tok.getKind();
+  // We may have a constructor initializer or function-try-block here.
+  if (kind == tok::colon || kind == tok::kw_try) {
+    // Consume everything up to (and including) the left brace.
+    if (!ConsumeAndStoreUntil(tok::l_brace, Toks)) {
+      // We didn't find the left-brace we expected after the
+      // constructor initializer.
+      if (Tok.is(tok::semi)) {
+        // We found a semicolon; complain, consume the semicolon, and
+        // don't try to parse this method later.
+        Diag(Tok.getLocation(), diag::err_expected_lbrace);
+        ConsumeAnyToken();
+        getCurrentClass().MethodDefs.pop_back();
+        return FnD;
+      }
+    }
+
+  } else {
+    // Begin by storing the '{' token.
+    Toks.push_back(Tok);
+    ConsumeBrace();
+  }
+  // Consume everything up to (and including) the matching right brace.
+  ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false);
+
+  // If we're in a function-try-block, we need to store all the catch blocks.
+  if (kind == tok::kw_try) {
+    while (Tok.is(tok::kw_catch)) {
+      ConsumeAndStoreUntil(tok::l_brace, Toks, /*StopAtSemi=*/false);
+      ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false);
+    }
+  }
+
+  return FnD;
+}
+
+/// ParseLexedMethodDeclarations - We finished parsing the member
+/// specification of a top (non-nested) C++ class. Now go over the
+/// stack of method declarations with some parts for which parsing was
+/// delayed (such as default arguments) and parse them.
+void Parser::ParseLexedMethodDeclarations(ParsingClass &Class) {
+  bool HasTemplateScope = !Class.TopLevelClass && Class.TemplateScope;
+  ParseScope TemplateScope(this, Scope::TemplateParamScope, HasTemplateScope);
+  if (HasTemplateScope)
+    Actions.ActOnReenterTemplateScope(CurScope, Class.TagOrTemplate);
+
+  // The current scope is still active if we're the top-level class.
+  // Otherwise we'll need to push and enter a new scope.
+  bool HasClassScope = !Class.TopLevelClass;
+  ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope,
+                        HasClassScope);
+  if (HasClassScope)
+    Actions.ActOnStartDelayedMemberDeclarations(CurScope, Class.TagOrTemplate);
+
+  for (; !Class.MethodDecls.empty(); Class.MethodDecls.pop_front()) {
+    LateParsedMethodDeclaration &LM = Class.MethodDecls.front();
+
+    // If this is a member template, introduce the template parameter scope.
+    ParseScope TemplateScope(this, Scope::TemplateParamScope, LM.TemplateScope);
+    if (LM.TemplateScope)
+      Actions.ActOnReenterTemplateScope(CurScope, LM.Method);
+
+    // Start the delayed C++ method declaration
+    Actions.ActOnStartDelayedCXXMethodDeclaration(CurScope, LM.Method);
+
+    // Introduce the parameters into scope and parse their default
+    // arguments.
+    ParseScope PrototypeScope(this,
+                              Scope::FunctionPrototypeScope|Scope::DeclScope);
+    for (unsigned I = 0, N = LM.DefaultArgs.size(); I != N; ++I) {
+      // Introduce the parameter into scope.
+      Actions.ActOnDelayedCXXMethodParameter(CurScope, LM.DefaultArgs[I].Param);
+
+      if (CachedTokens *Toks = LM.DefaultArgs[I].Toks) {
+        // Save the current token position.
+        SourceLocation origLoc = Tok.getLocation();
+
+        // Parse the default argument from its saved token stream.
+        Toks->push_back(Tok); // So that the current token doesn't get lost
+        PP.EnterTokenStream(&Toks->front(), Toks->size(), true, false);
+
+        // Consume the previously-pushed token.
+        ConsumeAnyToken();
+
+        // Consume the '='.
+        assert(Tok.is(tok::equal) && "Default argument not starting with '='");
+        SourceLocation EqualLoc = ConsumeToken();
+
+        OwningExprResult DefArgResult(ParseAssignmentExpression());
+        if (DefArgResult.isInvalid())
+          Actions.ActOnParamDefaultArgumentError(LM.DefaultArgs[I].Param);
+        else
+          Actions.ActOnParamDefaultArgument(LM.DefaultArgs[I].Param, EqualLoc,
+                                            move(DefArgResult));
+
+        assert(!PP.getSourceManager().isBeforeInTranslationUnit(origLoc,
+                                                           Tok.getLocation()) &&
+               "ParseAssignmentExpression went over the default arg tokens!");
+        // There could be leftover tokens (e.g. because of an error).
+        // Skip through until we reach the original token position.
+        while (Tok.getLocation() != origLoc)
+          ConsumeAnyToken();
+
+        delete Toks;
+        LM.DefaultArgs[I].Toks = 0;
+      }
+    }
+    PrototypeScope.Exit();
+
+    // Finish the delayed C++ method declaration.
+    Actions.ActOnFinishDelayedCXXMethodDeclaration(CurScope, LM.Method);
+  }
+
+  for (unsigned I = 0, N = Class.NestedClasses.size(); I != N; ++I)
+    ParseLexedMethodDeclarations(*Class.NestedClasses[I]);
+
+  if (HasClassScope)
+    Actions.ActOnFinishDelayedMemberDeclarations(CurScope, Class.TagOrTemplate);
+}
+
+/// ParseLexedMethodDefs - We finished parsing the member specification of a top
+/// (non-nested) C++ class. Now go over the stack of lexed methods that were
+/// collected during its parsing and parse them all.
+void Parser::ParseLexedMethodDefs(ParsingClass &Class) {
+  bool HasTemplateScope = !Class.TopLevelClass && Class.TemplateScope;
+  ParseScope TemplateScope(this, Scope::TemplateParamScope, HasTemplateScope);
+  if (HasTemplateScope)
+    Actions.ActOnReenterTemplateScope(CurScope, Class.TagOrTemplate);
+
+  bool HasClassScope = !Class.TopLevelClass;
+  ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope,
+                        HasClassScope);
+
+  for (; !Class.MethodDefs.empty(); Class.MethodDefs.pop_front()) {
+    LexedMethod &LM = Class.MethodDefs.front();
+
+    // If this is a member template, introduce the template parameter scope.
+    ParseScope TemplateScope(this, Scope::TemplateParamScope, LM.TemplateScope);
+    if (LM.TemplateScope)
+      Actions.ActOnReenterTemplateScope(CurScope, LM.D);
+
+    // Save the current token position.
+    SourceLocation origLoc = Tok.getLocation();
+
+    assert(!LM.Toks.empty() && "Empty body!");
+    // Append the current token at the end of the new token stream so that it
+    // doesn't get lost.
+    LM.Toks.push_back(Tok);
+    PP.EnterTokenStream(LM.Toks.data(), LM.Toks.size(), true, false);
+
+    // Consume the previously pushed token.
+    ConsumeAnyToken();
+    assert((Tok.is(tok::l_brace) || Tok.is(tok::colon) || Tok.is(tok::kw_try))
+           && "Inline method not starting with '{', ':' or 'try'");
+
+    // Parse the method body. Function body parsing code is similar enough
+    // to be re-used for method bodies as well.
+    ParseScope FnScope(this, Scope::FnScope|Scope::DeclScope);
+    Actions.ActOnStartOfFunctionDef(CurScope, LM.D);
+
+    if (Tok.is(tok::kw_try)) {
+      ParseFunctionTryBlock(LM.D);
+      assert(!PP.getSourceManager().isBeforeInTranslationUnit(origLoc,
+                                                           Tok.getLocation()) &&
+             "ParseFunctionTryBlock went over the cached tokens!");
+      assert(Tok.getLocation() == origLoc &&
+             "ParseFunctionTryBlock left tokens in the token stream!");
+      continue;
+    }
+    if (Tok.is(tok::colon)) {
+      ParseConstructorInitializer(LM.D);
+
+      // Error recovery.
+      if (!Tok.is(tok::l_brace)) {
+        Actions.ActOnFinishFunctionBody(LM.D, Action::StmtArg(Actions));
+        continue;
+      }
+    } else
+      Actions.ActOnDefaultCtorInitializers(LM.D);
+
+    ParseFunctionStatementBody(LM.D);
+    assert(!PP.getSourceManager().isBeforeInTranslationUnit(origLoc,
+                                                           Tok.getLocation()) &&
+           "We consumed more than the cached tokens!");
+    assert(Tok.getLocation() == origLoc &&
+           "Tokens were left in the token stream!");
+  }
+
+  for (unsigned I = 0, N = Class.NestedClasses.size(); I != N; ++I)
+    ParseLexedMethodDefs(*Class.NestedClasses[I]);
+}
+
+/// ConsumeAndStoreUntil - Consume and store the token at the passed token
+/// container until the token 'T' is reached (which gets
+/// consumed/stored too, if ConsumeFinalToken).
+/// If StopAtSemi is true, then we will stop early at a ';' character.
+/// Returns true if token 'T1' or 'T2' was found.
+/// NOTE: This is a specialized version of Parser::SkipUntil.
+bool Parser::ConsumeAndStoreUntil(tok::TokenKind T1, tok::TokenKind T2,
+                                  CachedTokens &Toks,
+                                  bool StopAtSemi, bool ConsumeFinalToken) {
+  // We always want this function to consume at least one token if the first
+  // token isn't T and if not at EOF.
+  bool isFirstTokenConsumed = true;
+  while (1) {
+    // If we found one of the tokens, stop and return true.
+    if (Tok.is(T1) || Tok.is(T2)) {
+      if (ConsumeFinalToken) {
+        Toks.push_back(Tok);
+        ConsumeAnyToken();
+      }
+      return true;
+    }
+
+    switch (Tok.getKind()) {
+    case tok::eof:
+      // Ran out of tokens.
+      return false;
+
+    case tok::l_paren:
+      // Recursively consume properly-nested parens.
+      Toks.push_back(Tok);
+      ConsumeParen();
+      ConsumeAndStoreUntil(tok::r_paren, Toks, /*StopAtSemi=*/false);
+      break;
+    case tok::l_square:
+      // Recursively consume properly-nested square brackets.
+      Toks.push_back(Tok);
+      ConsumeBracket();
+      ConsumeAndStoreUntil(tok::r_square, Toks, /*StopAtSemi=*/false);
+      break;
+    case tok::l_brace:
+      // Recursively consume properly-nested braces.
+      Toks.push_back(Tok);
+      ConsumeBrace();
+      ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false);
+      break;
+
+    // Okay, we found a ']' or '}' or ')', which we think should be balanced.
+    // Since the user wasn't looking for this token (if they were, it would
+    // already be handled), this isn't balanced.  If there is a LHS token at a
+    // higher level, we will assume that this matches the unbalanced token
+    // and return it.  Otherwise, this is a spurious RHS token, which we skip.
+    case tok::r_paren:
+      if (ParenCount && !isFirstTokenConsumed)
+        return false;  // Matches something.
+      Toks.push_back(Tok);
+      ConsumeParen();
+      break;
+    case tok::r_square:
+      if (BracketCount && !isFirstTokenConsumed)
+        return false;  // Matches something.
+      Toks.push_back(Tok);
+      ConsumeBracket();
+      break;
+    case tok::r_brace:
+      if (BraceCount && !isFirstTokenConsumed)
+        return false;  // Matches something.
+      Toks.push_back(Tok);
+      ConsumeBrace();
+      break;
+
+    case tok::string_literal:
+    case tok::wide_string_literal:
+      Toks.push_back(Tok);
+      ConsumeStringToken();
+      break;
+    case tok::semi:
+      if (StopAtSemi)
+        return false;
+      // FALL THROUGH.
+    default:
+      // consume this token.
+      Toks.push_back(Tok);
+      ConsumeToken();
+      break;
+    }
+    isFirstTokenConsumed = false;
+  }
+}
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
new file mode 100644
index 0000000..6669d40
--- /dev/null
+++ b/lib/Parse/ParseDecl.cpp
@@ -0,0 +1,3435 @@
+//===--- ParseDecl.cpp - Declaration Parsing ------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements the Declaration portions of the Parser interfaces.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Parse/Parser.h"
+#include "clang/Parse/ParseDiagnostic.h"
+#include "clang/Parse/Scope.h"
+#include "clang/Parse/Template.h"
+#include "RAIIObjectsForParser.h"
+#include "llvm/ADT/SmallSet.h"
+using namespace clang;
+
+//===----------------------------------------------------------------------===//
+// C99 6.7: Declarations.
+//===----------------------------------------------------------------------===//
+
+/// ParseTypeName
+///       type-name: [C99 6.7.6]
+///         specifier-qualifier-list abstract-declarator[opt]
+///
+/// Called type-id in C++.
+Action::TypeResult Parser::ParseTypeName(SourceRange *Range) {
+  // Parse the common declaration-specifiers piece.
+  DeclSpec DS;
+  ParseSpecifierQualifierList(DS);
+
+  // Parse the abstract-declarator, if present.
+  Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
+  ParseDeclarator(DeclaratorInfo);
+  if (Range)
+    *Range = DeclaratorInfo.getSourceRange();
+
+  if (DeclaratorInfo.isInvalidType())
+    return true;
+
+  return Actions.ActOnTypeName(CurScope, DeclaratorInfo);
+}
+
+/// ParseGNUAttributes - Parse a non-empty attributes list.
+///
+/// [GNU] attributes:
+///         attribute
+///         attributes attribute
+///
+/// [GNU]  attribute:
+///          '__attribute__' '(' '(' attribute-list ')' ')'
+///
+/// [GNU]  attribute-list:
+///          attrib
+///          attribute_list ',' attrib
+///
+/// [GNU]  attrib:
+///          empty
+///          attrib-name
+///          attrib-name '(' identifier ')'
+///          attrib-name '(' identifier ',' nonempty-expr-list ')'
+///          attrib-name '(' argument-expression-list [C99 6.5.2] ')'
+///
+/// [GNU]  attrib-name:
+///          identifier
+///          typespec
+///          typequal
+///          storageclass
+///
+/// FIXME: The GCC grammar/code for this construct implies we need two
+/// token lookahead. Comment from gcc: "If they start with an identifier
+/// which is followed by a comma or close parenthesis, then the arguments
+/// start with that identifier; otherwise they are an expression list."
+///
+/// At the moment, I am not doing 2 token lookahead. I am also unaware of
+/// any attributes that don't work (based on my limited testing). Most
+/// attributes are very simple in practice. Until we find a bug, I don't see
+/// a pressing need to implement the 2 token lookahead.
+
+AttributeList *Parser::ParseGNUAttributes(SourceLocation *EndLoc) {
+  assert(Tok.is(tok::kw___attribute) && "Not a GNU attribute list!");
+
+  AttributeList *CurrAttr = 0;
+
+  while (Tok.is(tok::kw___attribute)) {
+    ConsumeToken();
+    if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
+                         "attribute")) {
+      SkipUntil(tok::r_paren, true); // skip until ) or ;
+      return CurrAttr;
+    }
+    if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, "(")) {
+      SkipUntil(tok::r_paren, true); // skip until ) or ;
+      return CurrAttr;
+    }
+    // Parse the attribute-list. e.g. __attribute__(( weak, alias("__f") ))
+    while (Tok.is(tok::identifier) || isDeclarationSpecifier() ||
+           Tok.is(tok::comma)) {
+
+      if (Tok.is(tok::comma)) {
+        // allows for empty/non-empty attributes. ((__vector_size__(16),,,,))
+        ConsumeToken();
+        continue;
+      }
+      // we have an identifier or declaration specifier (const, int, etc.)
+      IdentifierInfo *AttrName = Tok.getIdentifierInfo();
+      SourceLocation AttrNameLoc = ConsumeToken();
+
+      // check if we have a "parameterized" attribute
+      if (Tok.is(tok::l_paren)) {
+        ConsumeParen(); // ignore the left paren loc for now
+
+        if (Tok.is(tok::identifier)) {
+          IdentifierInfo *ParmName = Tok.getIdentifierInfo();
+          SourceLocation ParmLoc = ConsumeToken();
+
+          if (Tok.is(tok::r_paren)) {
+            // __attribute__(( mode(byte) ))
+            ConsumeParen(); // ignore the right paren loc for now
+            CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0, AttrNameLoc,
+                                         ParmName, ParmLoc, 0, 0, CurrAttr);
+          } else if (Tok.is(tok::comma)) {
+            ConsumeToken();
+            // __attribute__(( format(printf, 1, 2) ))
+            ExprVector ArgExprs(Actions);
+            bool ArgExprsOk = true;
+
+            // now parse the non-empty comma separated list of expressions
+            while (1) {
+              OwningExprResult ArgExpr(ParseAssignmentExpression());
+              if (ArgExpr.isInvalid()) {
+                ArgExprsOk = false;
+                SkipUntil(tok::r_paren);
+                break;
+              } else {
+                ArgExprs.push_back(ArgExpr.release());
+              }
+              if (Tok.isNot(tok::comma))
+                break;
+              ConsumeToken(); // Eat the comma, move to the next argument
+            }
+            if (ArgExprsOk && Tok.is(tok::r_paren)) {
+              ConsumeParen(); // ignore the right paren loc for now
+              CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0,
+                                           AttrNameLoc, ParmName, ParmLoc,
+                                           ArgExprs.take(), ArgExprs.size(),
+                                           CurrAttr);
+            }
+          }
+        } else { // not an identifier
+          switch (Tok.getKind()) {
+          case tok::r_paren:
+          // parse a possibly empty comma separated list of expressions
+            // __attribute__(( nonnull() ))
+            ConsumeParen(); // ignore the right paren loc for now
+            CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0, AttrNameLoc,
+                                         0, SourceLocation(), 0, 0, CurrAttr);
+            break;
+          case tok::kw_char:
+          case tok::kw_wchar_t:
+          case tok::kw_char16_t:
+          case tok::kw_char32_t:
+          case tok::kw_bool:
+          case tok::kw_short:
+          case tok::kw_int:
+          case tok::kw_long:
+          case tok::kw_signed:
+          case tok::kw_unsigned:
+          case tok::kw_float:
+          case tok::kw_double:
+          case tok::kw_void:
+          case tok::kw_typeof:
+            // If it's a builtin type name, eat it and expect a rparen
+            // __attribute__(( vec_type_hint(char) ))
+            ConsumeToken();
+            CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0, AttrNameLoc,
+                                         0, SourceLocation(), 0, 0, CurrAttr);
+            if (Tok.is(tok::r_paren))
+              ConsumeParen();
+            break;
+          default:
+            // __attribute__(( aligned(16) ))
+            ExprVector ArgExprs(Actions);
+            bool ArgExprsOk = true;
+
+            // now parse the list of expressions
+            while (1) {
+              OwningExprResult ArgExpr(ParseAssignmentExpression());
+              if (ArgExpr.isInvalid()) {
+                ArgExprsOk = false;
+                SkipUntil(tok::r_paren);
+                break;
+              } else {
+                ArgExprs.push_back(ArgExpr.release());
+              }
+              if (Tok.isNot(tok::comma))
+                break;
+              ConsumeToken(); // Eat the comma, move to the next argument
+            }
+            // Match the ')'.
+            if (ArgExprsOk && Tok.is(tok::r_paren)) {
+              ConsumeParen(); // ignore the right paren loc for now
+              CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0,
+                           AttrNameLoc, 0, SourceLocation(), ArgExprs.take(),
+                           ArgExprs.size(),
+                           CurrAttr);
+            }
+            break;
+          }
+        }
+      } else {
+        CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0, AttrNameLoc,
+                                     0, SourceLocation(), 0, 0, CurrAttr);
+      }
+    }
+    if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
+      SkipUntil(tok::r_paren, false);
+    SourceLocation Loc = Tok.getLocation();
+    if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen)) {
+      SkipUntil(tok::r_paren, false);
+    }
+    if (EndLoc)
+      *EndLoc = Loc;
+  }
+  return CurrAttr;
+}
+
+/// ParseMicrosoftDeclSpec - Parse an __declspec construct
+///
+/// [MS] decl-specifier:
+///             __declspec ( extended-decl-modifier-seq )
+///
+/// [MS] extended-decl-modifier-seq:
+///             extended-decl-modifier[opt]
+///             extended-decl-modifier extended-decl-modifier-seq
+
+AttributeList* Parser::ParseMicrosoftDeclSpec(AttributeList *CurrAttr) {
+  assert(Tok.is(tok::kw___declspec) && "Not a declspec!");
+
+  ConsumeToken();
+  if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
+                       "declspec")) {
+    SkipUntil(tok::r_paren, true); // skip until ) or ;
+    return CurrAttr;
+  }
+  while (Tok.getIdentifierInfo()) {
+    IdentifierInfo *AttrName = Tok.getIdentifierInfo();
+    SourceLocation AttrNameLoc = ConsumeToken();
+    if (Tok.is(tok::l_paren)) {
+      ConsumeParen();
+      // FIXME: This doesn't parse __declspec(property(get=get_func_name))
+      // correctly.
+      OwningExprResult ArgExpr(ParseAssignmentExpression());
+      if (!ArgExpr.isInvalid()) {
+        ExprTy* ExprList = ArgExpr.take();
+        CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
+                                     SourceLocation(), &ExprList, 1,
+                                     CurrAttr, true);
+      }
+      if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
+        SkipUntil(tok::r_paren, false);
+    } else {
+      CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0, AttrNameLoc,
+                                   0, SourceLocation(), 0, 0, CurrAttr, true);
+    }
+  }
+  if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
+    SkipUntil(tok::r_paren, false);
+  return CurrAttr;
+}
+
+AttributeList* Parser::ParseMicrosoftTypeAttributes(AttributeList *CurrAttr) {
+  // Treat these like attributes
+  // FIXME: Allow Sema to distinguish between these and real attributes!
+  while (Tok.is(tok::kw___fastcall) || Tok.is(tok::kw___stdcall) ||
+         Tok.is(tok::kw___cdecl)    || Tok.is(tok::kw___ptr64) ||
+         Tok.is(tok::kw___w64)) {
+    IdentifierInfo *AttrName = Tok.getIdentifierInfo();
+    SourceLocation AttrNameLoc = ConsumeToken();
+    if (Tok.is(tok::kw___ptr64) || Tok.is(tok::kw___w64))
+      // FIXME: Support these properly!
+      continue;
+    CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
+                                 SourceLocation(), 0, 0, CurrAttr, true);
+  }
+  return CurrAttr;
+}
+
+/// ParseDeclaration - Parse a full 'declaration', which consists of
+/// declaration-specifiers, some number of declarators, and a semicolon.
+/// 'Context' should be a Declarator::TheContext value.  This returns the
+/// location of the semicolon in DeclEnd.
+///
+///       declaration: [C99 6.7]
+///         block-declaration ->
+///           simple-declaration
+///           others                   [FIXME]
+/// [C++]   template-declaration
+/// [C++]   namespace-definition
+/// [C++]   using-directive
+/// [C++]   using-declaration
+/// [C++0x] static_assert-declaration
+///         others... [FIXME]
+///
+Parser::DeclGroupPtrTy Parser::ParseDeclaration(unsigned Context,
+                                                SourceLocation &DeclEnd,
+                                                CXX0XAttributeList Attr) {
+  DeclPtrTy SingleDecl;
+  switch (Tok.getKind()) {
+  case tok::kw_template:
+  case tok::kw_export:
+    if (Attr.HasAttr)
+      Diag(Attr.Range.getBegin(), diag::err_attributes_not_allowed)
+        << Attr.Range;
+    SingleDecl = ParseDeclarationStartingWithTemplate(Context, DeclEnd);
+    break;
+  case tok::kw_namespace:
+    if (Attr.HasAttr)
+      Diag(Attr.Range.getBegin(), diag::err_attributes_not_allowed)
+        << Attr.Range;
+    SingleDecl = ParseNamespace(Context, DeclEnd);
+    break;
+  case tok::kw_using:
+    SingleDecl = ParseUsingDirectiveOrDeclaration(Context, DeclEnd, Attr);
+    break;
+  case tok::kw_static_assert:
+    if (Attr.HasAttr)
+      Diag(Attr.Range.getBegin(), diag::err_attributes_not_allowed)
+        << Attr.Range;
+    SingleDecl = ParseStaticAssertDeclaration(DeclEnd);
+    break;
+  default:
+    return ParseSimpleDeclaration(Context, DeclEnd, Attr.AttrList, true);
+  }
+  
+  // This routine returns a DeclGroup, if the thing we parsed only contains a
+  // single decl, convert it now.
+  return Actions.ConvertDeclToDeclGroup(SingleDecl);
+}
+
+///       simple-declaration: [C99 6.7: declaration] [C++ 7p1: dcl.dcl]
+///         declaration-specifiers init-declarator-list[opt] ';'
+///[C90/C++]init-declarator-list ';'                             [TODO]
+/// [OMP]   threadprivate-directive                              [TODO]
+///
+/// If RequireSemi is false, this does not check for a ';' at the end of the
+/// declaration.  If it is true, it checks for and eats it.
+Parser::DeclGroupPtrTy Parser::ParseSimpleDeclaration(unsigned Context,
+                                                      SourceLocation &DeclEnd,
+                                                      AttributeList *Attr,
+                                                      bool RequireSemi) {
+  // Parse the common declaration-specifiers piece.
+  ParsingDeclSpec DS(*this);
+  if (Attr)
+    DS.AddAttributes(Attr);
+  ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS_none,
+                            getDeclSpecContextFromDeclaratorContext(Context));
+
+  // C99 6.7.2.3p6: Handle "struct-or-union identifier;", "enum { X };"
+  // declaration-specifiers init-declarator-list[opt] ';'
+  if (Tok.is(tok::semi)) {
+    if (RequireSemi) ConsumeToken();
+    DeclPtrTy TheDecl = Actions.ParsedFreeStandingDeclSpec(CurScope, DS);
+    DS.complete(TheDecl);
+    return Actions.ConvertDeclToDeclGroup(TheDecl);
+  }
+
+  return ParseDeclGroup(DS, Context, /*FunctionDefs=*/ false, &DeclEnd);
+}
+
+/// ParseDeclGroup - Having concluded that this is either a function
+/// definition or a group of object declarations, actually parse the
+/// result.
+Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS,
+                                              unsigned Context,
+                                              bool AllowFunctionDefinitions,
+                                              SourceLocation *DeclEnd) {
+  // Parse the first declarator.
+  ParsingDeclarator D(*this, DS, static_cast<Declarator::TheContext>(Context));
+  ParseDeclarator(D);
+
+  // Bail out if the first declarator didn't seem well-formed.
+  if (!D.hasName() && !D.mayOmitIdentifier()) {
+    // Skip until ; or }.
+    SkipUntil(tok::r_brace, true, true);
+    if (Tok.is(tok::semi))
+      ConsumeToken();
+    return DeclGroupPtrTy();
+  }
+
+  if (AllowFunctionDefinitions && D.isFunctionDeclarator()) {
+    if (isDeclarationAfterDeclarator()) {
+      // Fall though.  We have to check this first, though, because
+      // __attribute__ might be the start of a function definition in
+      // (extended) K&R C.
+    } else if (isStartOfFunctionDefinition()) {
+      if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) {
+        Diag(Tok, diag::err_function_declared_typedef);
+
+        // Recover by treating the 'typedef' as spurious.
+        DS.ClearStorageClassSpecs();
+      }
+
+      DeclPtrTy TheDecl = ParseFunctionDefinition(D);
+      return Actions.ConvertDeclToDeclGroup(TheDecl);
+    } else {
+      Diag(Tok, diag::err_expected_fn_body);
+      SkipUntil(tok::semi);
+      return DeclGroupPtrTy();
+    }
+  }
+
+  llvm::SmallVector<DeclPtrTy, 8> DeclsInGroup;
+  DeclPtrTy FirstDecl = ParseDeclarationAfterDeclarator(D);
+  D.complete(FirstDecl);
+  if (FirstDecl.get())
+    DeclsInGroup.push_back(FirstDecl);
+
+  // If we don't have a comma, it is either the end of the list (a ';') or an
+  // error, bail out.
+  while (Tok.is(tok::comma)) {
+    // Consume the comma.
+    ConsumeToken();
+
+    // Parse the next declarator.
+    D.clear();
+
+    // Accept attributes in an init-declarator.  In the first declarator in a
+    // declaration, these would be part of the declspec.  In subsequent
+    // declarators, they become part of the declarator itself, so that they
+    // don't apply to declarators after *this* one.  Examples:
+    //    short __attribute__((common)) var;    -> declspec
+    //    short var __attribute__((common));    -> declarator
+    //    short x, __attribute__((common)) var;    -> declarator
+    if (Tok.is(tok::kw___attribute)) {
+      SourceLocation Loc;
+      AttributeList *AttrList = ParseGNUAttributes(&Loc);
+      D.AddAttributes(AttrList, Loc);
+    }
+
+    ParseDeclarator(D);
+
+    DeclPtrTy ThisDecl = ParseDeclarationAfterDeclarator(D);
+    D.complete(ThisDecl);
+    if (ThisDecl.get())
+      DeclsInGroup.push_back(ThisDecl);    
+  }
+
+  if (DeclEnd)
+    *DeclEnd = Tok.getLocation();
+
+  if (Context != Declarator::ForContext &&
+      ExpectAndConsume(tok::semi,
+                       Context == Declarator::FileContext
+                         ? diag::err_invalid_token_after_toplevel_declarator
+                         : diag::err_expected_semi_declaration)) {
+    SkipUntil(tok::r_brace, true, true);
+    if (Tok.is(tok::semi))
+      ConsumeToken();
+  }
+
+  return Actions.FinalizeDeclaratorGroup(CurScope, DS,
+                                         DeclsInGroup.data(),
+                                         DeclsInGroup.size());
+}
+
+/// \brief Parse 'declaration' after parsing 'declaration-specifiers
+/// declarator'. This method parses the remainder of the declaration
+/// (including any attributes or initializer, among other things) and
+/// finalizes the declaration.
+///
+///       init-declarator: [C99 6.7]
+///         declarator
+///         declarator '=' initializer
+/// [GNU]   declarator simple-asm-expr[opt] attributes[opt]
+/// [GNU]   declarator simple-asm-expr[opt] attributes[opt] '=' initializer
+/// [C++]   declarator initializer[opt]
+///
+/// [C++] initializer:
+/// [C++]   '=' initializer-clause
+/// [C++]   '(' expression-list ')'
+/// [C++0x] '=' 'default'                                                [TODO]
+/// [C++0x] '=' 'delete'
+///
+/// According to the standard grammar, =default and =delete are function
+/// definitions, but that definitely doesn't fit with the parser here.
+///
+Parser::DeclPtrTy Parser::ParseDeclarationAfterDeclarator(Declarator &D,
+                                     const ParsedTemplateInfo &TemplateInfo) {
+  // If a simple-asm-expr is present, parse it.
+  if (Tok.is(tok::kw_asm)) {
+    SourceLocation Loc;
+    OwningExprResult AsmLabel(ParseSimpleAsm(&Loc));
+    if (AsmLabel.isInvalid()) {
+      SkipUntil(tok::semi, true, true);
+      return DeclPtrTy();
+    }
+
+    D.setAsmLabel(AsmLabel.release());
+    D.SetRangeEnd(Loc);
+  }
+
+  // If attributes are present, parse them.
+  if (Tok.is(tok::kw___attribute)) {
+    SourceLocation Loc;
+    AttributeList *AttrList = ParseGNUAttributes(&Loc);
+    D.AddAttributes(AttrList, Loc);
+  }
+
+  // Inform the current actions module that we just parsed this declarator.
+  DeclPtrTy ThisDecl;
+  switch (TemplateInfo.Kind) {
+  case ParsedTemplateInfo::NonTemplate:
+    ThisDecl = Actions.ActOnDeclarator(CurScope, D);
+    break;
+      
+  case ParsedTemplateInfo::Template:
+  case ParsedTemplateInfo::ExplicitSpecialization:
+    ThisDecl = Actions.ActOnTemplateDeclarator(CurScope,
+                             Action::MultiTemplateParamsArg(Actions,
+                                          TemplateInfo.TemplateParams->data(),
+                                          TemplateInfo.TemplateParams->size()),
+                                               D);
+    break;
+      
+  case ParsedTemplateInfo::ExplicitInstantiation: {
+    Action::DeclResult ThisRes 
+      = Actions.ActOnExplicitInstantiation(CurScope,
+                                           TemplateInfo.ExternLoc,
+                                           TemplateInfo.TemplateLoc,
+                                           D);
+    if (ThisRes.isInvalid()) {
+      SkipUntil(tok::semi, true, true);
+      return DeclPtrTy();
+    }
+    
+    ThisDecl = ThisRes.get();
+    break;
+    }
+  }
+
+  // Parse declarator '=' initializer.
+  if (Tok.is(tok::equal)) {
+    ConsumeToken();
+    if (getLang().CPlusPlus0x && Tok.is(tok::kw_delete)) {
+      SourceLocation DelLoc = ConsumeToken();
+      Actions.SetDeclDeleted(ThisDecl, DelLoc);
+    } else {
+      if (getLang().CPlusPlus && D.getCXXScopeSpec().isSet()) {
+        EnterScope(0);
+        Actions.ActOnCXXEnterDeclInitializer(CurScope, ThisDecl);
+      }
+
+      OwningExprResult Init(ParseInitializer());
+
+      if (getLang().CPlusPlus && D.getCXXScopeSpec().isSet()) {
+        Actions.ActOnCXXExitDeclInitializer(CurScope, ThisDecl);
+        ExitScope();
+      }
+
+      if (Init.isInvalid()) {
+        SkipUntil(tok::comma, true, true);
+        Actions.ActOnInitializerError(ThisDecl);
+      } else
+        Actions.AddInitializerToDecl(ThisDecl, move(Init));
+    }
+  } else if (Tok.is(tok::l_paren)) {
+    // Parse C++ direct initializer: '(' expression-list ')'
+    SourceLocation LParenLoc = ConsumeParen();
+    ExprVector Exprs(Actions);
+    CommaLocsTy CommaLocs;
+
+    if (getLang().CPlusPlus && D.getCXXScopeSpec().isSet()) {
+      EnterScope(0);
+      Actions.ActOnCXXEnterDeclInitializer(CurScope, ThisDecl);
+    }
+
+    if (ParseExpressionList(Exprs, CommaLocs)) {
+      SkipUntil(tok::r_paren);
+
+      if (getLang().CPlusPlus && D.getCXXScopeSpec().isSet()) {
+        Actions.ActOnCXXExitDeclInitializer(CurScope, ThisDecl);
+        ExitScope();
+      }
+    } else {
+      // Match the ')'.
+      SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
+
+      assert(!Exprs.empty() && Exprs.size()-1 == CommaLocs.size() &&
+             "Unexpected number of commas!");
+
+      if (getLang().CPlusPlus && D.getCXXScopeSpec().isSet()) {
+        Actions.ActOnCXXExitDeclInitializer(CurScope, ThisDecl);
+        ExitScope();
+      }
+
+      Actions.AddCXXDirectInitializerToDecl(ThisDecl, LParenLoc,
+                                            move_arg(Exprs),
+                                            CommaLocs.data(), RParenLoc);
+    }
+  } else {
+    bool TypeContainsUndeducedAuto =
+      D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_auto;
+    Actions.ActOnUninitializedDecl(ThisDecl, TypeContainsUndeducedAuto);
+  }
+
+  return ThisDecl;
+}
+
+/// ParseSpecifierQualifierList
+///        specifier-qualifier-list:
+///          type-specifier specifier-qualifier-list[opt]
+///          type-qualifier specifier-qualifier-list[opt]
+/// [GNU]    attributes     specifier-qualifier-list[opt]
+///
+void Parser::ParseSpecifierQualifierList(DeclSpec &DS) {
+  /// specifier-qualifier-list is a subset of declaration-specifiers.  Just
+  /// parse declaration-specifiers and complain about extra stuff.
+  ParseDeclarationSpecifiers(DS);
+
+  // Validate declspec for type-name.
+  unsigned Specs = DS.getParsedSpecifiers();
+  if (Specs == DeclSpec::PQ_None && !DS.getNumProtocolQualifiers() &&
+      !DS.getAttributes())
+    Diag(Tok, diag::err_typename_requires_specqual);
+
+  // Issue diagnostic and remove storage class if present.
+  if (Specs & DeclSpec::PQ_StorageClassSpecifier) {
+    if (DS.getStorageClassSpecLoc().isValid())
+      Diag(DS.getStorageClassSpecLoc(),diag::err_typename_invalid_storageclass);
+    else
+      Diag(DS.getThreadSpecLoc(), diag::err_typename_invalid_storageclass);
+    DS.ClearStorageClassSpecs();
+  }
+
+  // Issue diagnostic and remove function specfier if present.
+  if (Specs & DeclSpec::PQ_FunctionSpecifier) {
+    if (DS.isInlineSpecified())
+      Diag(DS.getInlineSpecLoc(), diag::err_typename_invalid_functionspec);
+    if (DS.isVirtualSpecified())
+      Diag(DS.getVirtualSpecLoc(), diag::err_typename_invalid_functionspec);
+    if (DS.isExplicitSpecified())
+      Diag(DS.getExplicitSpecLoc(), diag::err_typename_invalid_functionspec);
+    DS.ClearFunctionSpecs();
+  }
+}
+
+/// isValidAfterIdentifierInDeclaratorAfterDeclSpec - Return true if the
+/// specified token is valid after the identifier in a declarator which
+/// immediately follows the declspec.  For example, these things are valid:
+///
+///      int x   [             4];         // direct-declarator
+///      int x   (             int y);     // direct-declarator
+///  int(int x   )                         // direct-declarator
+///      int x   ;                         // simple-declaration
+///      int x   =             17;         // init-declarator-list
+///      int x   ,             y;          // init-declarator-list
+///      int x   __asm__       ("foo");    // init-declarator-list
+///      int x   :             4;          // struct-declarator
+///      int x   {             5};         // C++'0x unified initializers
+///
+/// This is not, because 'x' does not immediately follow the declspec (though
+/// ')' happens to be valid anyway).
+///    int (x)
+///
+static bool isValidAfterIdentifierInDeclarator(const Token &T) {
+  return T.is(tok::l_square) || T.is(tok::l_paren) || T.is(tok::r_paren) ||
+         T.is(tok::semi) || T.is(tok::comma) || T.is(tok::equal) ||
+         T.is(tok::kw_asm) || T.is(tok::l_brace) || T.is(tok::colon);
+}
+
+
+/// ParseImplicitInt - This method is called when we have an non-typename
+/// identifier in a declspec (which normally terminates the decl spec) when
+/// the declspec has no type specifier.  In this case, the declspec is either
+/// malformed or is "implicit int" (in K&R and C89).
+///
+/// This method handles diagnosing this prettily and returns false if the
+/// declspec is done being processed.  If it recovers and thinks there may be
+/// other pieces of declspec after it, it returns true.
+///
+bool Parser::ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS,
+                              const ParsedTemplateInfo &TemplateInfo,
+                              AccessSpecifier AS) {
+  assert(Tok.is(tok::identifier) && "should have identifier");
+
+  SourceLocation Loc = Tok.getLocation();
+  // If we see an identifier that is not a type name, we normally would
+  // parse it as the identifer being declared.  However, when a typename
+  // is typo'd or the definition is not included, this will incorrectly
+  // parse the typename as the identifier name and fall over misparsing
+  // later parts of the diagnostic.
+  //
+  // As such, we try to do some look-ahead in cases where this would
+  // otherwise be an "implicit-int" case to see if this is invalid.  For
+  // example: "static foo_t x = 4;"  In this case, if we parsed foo_t as
+  // an identifier with implicit int, we'd get a parse error because the
+  // next token is obviously invalid for a type.  Parse these as a case
+  // with an invalid type specifier.
+  assert(!DS.hasTypeSpecifier() && "Type specifier checked above");
+
+  // Since we know that this either implicit int (which is rare) or an
+  // error, we'd do lookahead to try to do better recovery.
+  if (isValidAfterIdentifierInDeclarator(NextToken())) {
+    // If this token is valid for implicit int, e.g. "static x = 4", then
+    // we just avoid eating the identifier, so it will be parsed as the
+    // identifier in the declarator.
+    return false;
+  }
+
+  // Otherwise, if we don't consume this token, we are going to emit an
+  // error anyway.  Try to recover from various common problems.  Check
+  // to see if this was a reference to a tag name without a tag specified.
+  // This is a common problem in C (saying 'foo' instead of 'struct foo').
+  //
+  // C++ doesn't need this, and isTagName doesn't take SS.
+  if (SS == 0) {
+    const char *TagName = 0;
+    tok::TokenKind TagKind = tok::unknown;
+
+    switch (Actions.isTagName(*Tok.getIdentifierInfo(), CurScope)) {
+      default: break;
+      case DeclSpec::TST_enum:  TagName="enum"  ;TagKind=tok::kw_enum  ;break;
+      case DeclSpec::TST_union: TagName="union" ;TagKind=tok::kw_union ;break;
+      case DeclSpec::TST_struct:TagName="struct";TagKind=tok::kw_struct;break;
+      case DeclSpec::TST_class: TagName="class" ;TagKind=tok::kw_class ;break;
+    }
+
+    if (TagName) {
+      Diag(Loc, diag::err_use_of_tag_name_without_tag)
+        << Tok.getIdentifierInfo() << TagName << getLang().CPlusPlus
+        << FixItHint::CreateInsertion(Tok.getLocation(),TagName);
+
+      // Parse this as a tag as if the missing tag were present.
+      if (TagKind == tok::kw_enum)
+        ParseEnumSpecifier(Loc, DS, TemplateInfo, AS);
+      else
+        ParseClassSpecifier(TagKind, Loc, DS, TemplateInfo, AS);
+      return true;
+    }
+  }
+
+  // This is almost certainly an invalid type name. Let the action emit a 
+  // diagnostic and attempt to recover.
+  Action::TypeTy *T = 0;
+  if (Actions.DiagnoseUnknownTypeName(*Tok.getIdentifierInfo(), Loc,
+                                      CurScope, SS, T)) {
+    // The action emitted a diagnostic, so we don't have to.
+    if (T) {
+      // The action has suggested that the type T could be used. Set that as
+      // the type in the declaration specifiers, consume the would-be type
+      // name token, and we're done.
+      const char *PrevSpec;
+      unsigned DiagID;
+      DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, DiagID, T, 
+                         false);
+      DS.SetRangeEnd(Tok.getLocation());
+      ConsumeToken();
+      
+      // There may be other declaration specifiers after this.
+      return true;
+    }
+    
+    // Fall through; the action had no suggestion for us.
+  } else {
+    // The action did not emit a diagnostic, so emit one now.
+    SourceRange R;
+    if (SS) R = SS->getRange();
+    Diag(Loc, diag::err_unknown_typename) << Tok.getIdentifierInfo() << R;
+  }
+
+  // Mark this as an error.
+  const char *PrevSpec;
+  unsigned DiagID;
+  DS.SetTypeSpecType(DeclSpec::TST_error, Loc, PrevSpec, DiagID);
+  DS.SetRangeEnd(Tok.getLocation());
+  ConsumeToken();
+
+  // TODO: Could inject an invalid typedef decl in an enclosing scope to
+  // avoid rippling error messages on subsequent uses of the same type,
+  // could be useful if #include was forgotten.
+  return false;
+}
+
+/// \brief Determine the declaration specifier context from the declarator
+/// context.
+///
+/// \param Context the declarator context, which is one of the
+/// Declarator::TheContext enumerator values.
+Parser::DeclSpecContext 
+Parser::getDeclSpecContextFromDeclaratorContext(unsigned Context) {
+  if (Context == Declarator::MemberContext)
+    return DSC_class;
+  if (Context == Declarator::FileContext)
+    return DSC_top_level;
+  return DSC_normal;
+}
+
+/// ParseDeclarationSpecifiers
+///       declaration-specifiers: [C99 6.7]
+///         storage-class-specifier declaration-specifiers[opt]
+///         type-specifier declaration-specifiers[opt]
+/// [C99]   function-specifier declaration-specifiers[opt]
+/// [GNU]   attributes declaration-specifiers[opt]
+///
+///       storage-class-specifier: [C99 6.7.1]
+///         'typedef'
+///         'extern'
+///         'static'
+///         'auto'
+///         'register'
+/// [C++]   'mutable'
+/// [GNU]   '__thread'
+///       function-specifier: [C99 6.7.4]
+/// [C99]   'inline'
+/// [C++]   'virtual'
+/// [C++]   'explicit'
+///       'friend': [C++ dcl.friend]
+///       'constexpr': [C++0x dcl.constexpr]
+
+///
+void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
+                                        const ParsedTemplateInfo &TemplateInfo,
+                                        AccessSpecifier AS,
+                                        DeclSpecContext DSContext) {
+  if (Tok.is(tok::code_completion)) {
+    Action::CodeCompletionContext CCC = Action::CCC_Namespace;
+    if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate)
+      CCC = DSContext == DSC_class? Action::CCC_MemberTemplate 
+                                  : Action::CCC_Template;
+    else if (DSContext == DSC_class)
+      CCC = Action::CCC_Class;
+    else if (ObjCImpDecl)
+      CCC = Action::CCC_ObjCImplementation;
+    
+    Actions.CodeCompleteOrdinaryName(CurScope, CCC);
+    ConsumeToken();
+  }
+  
+  DS.SetRangeStart(Tok.getLocation());
+  while (1) {
+    bool isInvalid = false;
+    const char *PrevSpec = 0;
+    unsigned DiagID = 0;
+
+    SourceLocation Loc = Tok.getLocation();
+
+    switch (Tok.getKind()) {
+    default:
+    DoneWithDeclSpec:
+      // If this is not a declaration specifier token, we're done reading decl
+      // specifiers.  First verify that DeclSpec's are consistent.
+      DS.Finish(Diags, PP);
+      return;
+
+    case tok::coloncolon: // ::foo::bar
+      // C++ scope specifier.  Annotate and loop, or bail out on error.
+      if (TryAnnotateCXXScopeToken(true)) {
+        if (!DS.hasTypeSpecifier())
+          DS.SetTypeSpecError();
+        goto DoneWithDeclSpec;
+      }
+      if (Tok.is(tok::coloncolon)) // ::new or ::delete
+        goto DoneWithDeclSpec;
+      continue;
+
+    case tok::annot_cxxscope: {
+      if (DS.hasTypeSpecifier())
+        goto DoneWithDeclSpec;
+
+      CXXScopeSpec SS;
+      SS.setScopeRep(Tok.getAnnotationValue());
+      SS.setRange(Tok.getAnnotationRange());
+
+      // We are looking for a qualified typename.
+      Token Next = NextToken();
+      if (Next.is(tok::annot_template_id) &&
+          static_cast<TemplateIdAnnotation *>(Next.getAnnotationValue())
+            ->Kind == TNK_Type_template) {
+        // We have a qualified template-id, e.g., N::A<int>
+
+        // C++ [class.qual]p2:
+        //   In a lookup in which the constructor is an acceptable lookup
+        //   result and the nested-name-specifier nominates a class C:
+        //
+        //     - if the name specified after the
+        //       nested-name-specifier, when looked up in C, is the
+        //       injected-class-name of C (Clause 9), or
+        //
+        //     - if the name specified after the nested-name-specifier
+        //       is the same as the identifier or the
+        //       simple-template-id's template-name in the last
+        //       component of the nested-name-specifier,
+        //
+        //   the name is instead considered to name the constructor of
+        //   class C.
+        // 
+        // Thus, if the template-name is actually the constructor
+        // name, then the code is ill-formed; this interpretation is
+        // reinforced by the NAD status of core issue 635. 
+        TemplateIdAnnotation *TemplateId
+          = static_cast<TemplateIdAnnotation *>(Next.getAnnotationValue());
+        if ((DSContext == DSC_top_level ||
+             (DSContext == DSC_class && DS.isFriendSpecified())) &&
+            TemplateId->Name &&
+            Actions.isCurrentClassName(*TemplateId->Name, CurScope, &SS)) {
+          if (isConstructorDeclarator()) {
+            // The user meant this to be an out-of-line constructor
+            // definition, but template arguments are not allowed
+            // there.  Just allow this as a constructor; we'll
+            // complain about it later.
+            goto DoneWithDeclSpec;
+          }
+
+          // The user meant this to name a type, but it actually names
+          // a constructor with some extraneous template
+          // arguments. Complain, then parse it as a type as the user
+          // intended.
+          Diag(TemplateId->TemplateNameLoc,
+               diag::err_out_of_line_template_id_names_constructor)
+            << TemplateId->Name;
+        }
+
+        DS.getTypeSpecScope() = SS;
+        ConsumeToken(); // The C++ scope.
+        assert(Tok.is(tok::annot_template_id) &&
+               "ParseOptionalCXXScopeSpecifier not working");
+        AnnotateTemplateIdTokenAsType(&SS);
+        continue;
+      }
+
+      if (Next.is(tok::annot_typename)) {
+        DS.getTypeSpecScope() = SS;
+        ConsumeToken(); // The C++ scope.
+        if (Tok.getAnnotationValue())
+          isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, 
+                                         PrevSpec, DiagID, 
+                                         Tok.getAnnotationValue());
+        else
+          DS.SetTypeSpecError();
+        DS.SetRangeEnd(Tok.getAnnotationEndLoc());
+        ConsumeToken(); // The typename
+      }
+
+      if (Next.isNot(tok::identifier))
+        goto DoneWithDeclSpec;
+
+      // If we're in a context where the identifier could be a class name,
+      // check whether this is a constructor declaration.
+      if ((DSContext == DSC_top_level ||
+           (DSContext == DSC_class && DS.isFriendSpecified())) &&
+          Actions.isCurrentClassName(*Next.getIdentifierInfo(), CurScope, 
+                                     &SS)) {
+        if (isConstructorDeclarator())
+          goto DoneWithDeclSpec;
+
+        // As noted in C++ [class.qual]p2 (cited above), when the name
+        // of the class is qualified in a context where it could name
+        // a constructor, its a constructor name. However, we've
+        // looked at the declarator, and the user probably meant this
+        // to be a type. Complain that it isn't supposed to be treated
+        // as a type, then proceed to parse it as a type.
+        Diag(Next.getLocation(), diag::err_out_of_line_type_names_constructor)
+          << Next.getIdentifierInfo();
+      }
+
+      TypeTy *TypeRep = Actions.getTypeName(*Next.getIdentifierInfo(),
+                                            Next.getLocation(), CurScope, &SS);
+
+      // If the referenced identifier is not a type, then this declspec is
+      // erroneous: We already checked about that it has no type specifier, and
+      // C++ doesn't have implicit int.  Diagnose it as a typo w.r.t. to the
+      // typename.
+      if (TypeRep == 0) {
+        ConsumeToken();   // Eat the scope spec so the identifier is current.
+        if (ParseImplicitInt(DS, &SS, TemplateInfo, AS)) continue;
+        goto DoneWithDeclSpec;
+      }
+
+      DS.getTypeSpecScope() = SS;
+      ConsumeToken(); // The C++ scope.
+
+      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
+                                     DiagID, TypeRep);
+      if (isInvalid)
+        break;
+
+      DS.SetRangeEnd(Tok.getLocation());
+      ConsumeToken(); // The typename.
+
+      continue;
+    }
+
+    case tok::annot_typename: {
+      if (Tok.getAnnotationValue())
+        isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
+                                       DiagID, Tok.getAnnotationValue());
+      else
+        DS.SetTypeSpecError();
+      
+      if (isInvalid)
+        break;
+
+      DS.SetRangeEnd(Tok.getAnnotationEndLoc());
+      ConsumeToken(); // The typename
+
+      // Objective-C supports syntax of the form 'id<proto1,proto2>' where 'id'
+      // is a specific typedef and 'itf<proto1,proto2>' where 'itf' is an
+      // Objective-C interface.  If we don't have Objective-C or a '<', this is
+      // just a normal reference to a typedef name.
+      if (!Tok.is(tok::less) || !getLang().ObjC1)
+        continue;
+
+      SourceLocation LAngleLoc, EndProtoLoc;
+      llvm::SmallVector<DeclPtrTy, 8> ProtocolDecl;
+      llvm::SmallVector<SourceLocation, 8> ProtocolLocs;
+      ParseObjCProtocolReferences(ProtocolDecl, ProtocolLocs, false,
+                                  LAngleLoc, EndProtoLoc);
+      DS.setProtocolQualifiers(ProtocolDecl.data(), ProtocolDecl.size(),
+                               ProtocolLocs.data(), LAngleLoc);
+
+      DS.SetRangeEnd(EndProtoLoc);
+      continue;
+    }
+
+      // typedef-name
+    case tok::identifier: {
+      // In C++, check to see if this is a scope specifier like foo::bar::, if
+      // so handle it as such.  This is important for ctor parsing.
+      if (getLang().CPlusPlus) {
+        if (TryAnnotateCXXScopeToken(true)) {
+          if (!DS.hasTypeSpecifier())
+            DS.SetTypeSpecError();
+          goto DoneWithDeclSpec;
+        }
+        if (!Tok.is(tok::identifier))
+          continue;
+      }
+
+      // This identifier can only be a typedef name if we haven't already seen
+      // a type-specifier.  Without this check we misparse:
+      //  typedef int X; struct Y { short X; };  as 'short int'.
+      if (DS.hasTypeSpecifier())
+        goto DoneWithDeclSpec;
+
+      // Check for need to substitute AltiVec keyword tokens.
+      if (TryAltiVecToken(DS, Loc, PrevSpec, DiagID, isInvalid))
+        break;
+
+      // It has to be available as a typedef too!
+      TypeTy *TypeRep = Actions.getTypeName(*Tok.getIdentifierInfo(),
+                                            Tok.getLocation(), CurScope);
+
+      // If this is not a typedef name, don't parse it as part of the declspec,
+      // it must be an implicit int or an error.
+      if (TypeRep == 0) {
+        if (ParseImplicitInt(DS, 0, TemplateInfo, AS)) continue;
+        goto DoneWithDeclSpec;
+      }
+
+      // If we're in a context where the identifier could be a class name,
+      // check whether this is a constructor declaration.
+      if (getLang().CPlusPlus && DSContext == DSC_class &&
+          Actions.isCurrentClassName(*Tok.getIdentifierInfo(), CurScope) &&
+          isConstructorDeclarator())
+        goto DoneWithDeclSpec;
+
+      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
+                                     DiagID, TypeRep);
+      if (isInvalid)
+        break;
+
+      DS.SetRangeEnd(Tok.getLocation());
+      ConsumeToken(); // The identifier
+
+      // Objective-C supports syntax of the form 'id<proto1,proto2>' where 'id'
+      // is a specific typedef and 'itf<proto1,proto2>' where 'itf' is an
+      // Objective-C interface.  If we don't have Objective-C or a '<', this is
+      // just a normal reference to a typedef name.
+      if (!Tok.is(tok::less) || !getLang().ObjC1)
+        continue;
+
+      SourceLocation LAngleLoc, EndProtoLoc;
+      llvm::SmallVector<DeclPtrTy, 8> ProtocolDecl;
+      llvm::SmallVector<SourceLocation, 8> ProtocolLocs;
+      ParseObjCProtocolReferences(ProtocolDecl, ProtocolLocs, false,
+                                  LAngleLoc, EndProtoLoc);
+      DS.setProtocolQualifiers(ProtocolDecl.data(), ProtocolDecl.size(),
+                               ProtocolLocs.data(), LAngleLoc);
+
+      DS.SetRangeEnd(EndProtoLoc);
+
+      // Need to support trailing type qualifiers (e.g. "id<p> const").
+      // If a type specifier follows, it will be diagnosed elsewhere.
+      continue;
+    }
+
+      // type-name
+    case tok::annot_template_id: {
+      TemplateIdAnnotation *TemplateId
+        = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
+      if (TemplateId->Kind != TNK_Type_template) {
+        // This template-id does not refer to a type name, so we're
+        // done with the type-specifiers.
+        goto DoneWithDeclSpec;
+      }
+
+      // If we're in a context where the template-id could be a
+      // constructor name or specialization, check whether this is a
+      // constructor declaration.
+      if (getLang().CPlusPlus && DSContext == DSC_class &&
+          Actions.isCurrentClassName(*TemplateId->Name, CurScope) &&
+          isConstructorDeclarator())
+        goto DoneWithDeclSpec;
+
+      // Turn the template-id annotation token into a type annotation
+      // token, then try again to parse it as a type-specifier.
+      AnnotateTemplateIdTokenAsType();
+      continue;
+    }
+
+    // GNU attributes support.
+    case tok::kw___attribute:
+      DS.AddAttributes(ParseGNUAttributes());
+      continue;
+
+    // Microsoft declspec support.
+    case tok::kw___declspec:
+      DS.AddAttributes(ParseMicrosoftDeclSpec());
+      continue;
+
+    // Microsoft single token adornments.
+    case tok::kw___forceinline:
+      // FIXME: Add handling here!
+      break;
+
+    case tok::kw___ptr64:
+    case tok::kw___w64:
+    case tok::kw___cdecl:
+    case tok::kw___stdcall:
+    case tok::kw___fastcall:
+      DS.AddAttributes(ParseMicrosoftTypeAttributes());
+      continue;
+
+    // storage-class-specifier
+    case tok::kw_typedef:
+      isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_typedef, Loc, PrevSpec,
+                                         DiagID);
+      break;
+    case tok::kw_extern:
+      if (DS.isThreadSpecified())
+        Diag(Tok, diag::ext_thread_before) << "extern";
+      isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_extern, Loc, PrevSpec,
+                                         DiagID);
+      break;
+    case tok::kw___private_extern__:
+      isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_private_extern, Loc,
+                                         PrevSpec, DiagID);
+      break;
+    case tok::kw_static:
+      if (DS.isThreadSpecified())
+        Diag(Tok, diag::ext_thread_before) << "static";
+      isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_static, Loc, PrevSpec,
+                                         DiagID);
+      break;
+    case tok::kw_auto:
+      if (getLang().CPlusPlus0x)
+        isInvalid = DS.SetTypeSpecType(DeclSpec::TST_auto, Loc, PrevSpec,
+                                       DiagID);
+      else
+        isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_auto, Loc, PrevSpec,
+                                           DiagID);
+      break;
+    case tok::kw_register:
+      isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_register, Loc, PrevSpec,
+                                         DiagID);
+      break;
+    case tok::kw_mutable:
+      isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_mutable, Loc, PrevSpec,
+                                         DiagID);
+      break;
+    case tok::kw___thread:
+      isInvalid = DS.SetStorageClassSpecThread(Loc, PrevSpec, DiagID);
+      break;
+
+    // function-specifier
+    case tok::kw_inline:
+      isInvalid = DS.SetFunctionSpecInline(Loc, PrevSpec, DiagID);
+      break;
+    case tok::kw_virtual:
+      isInvalid = DS.SetFunctionSpecVirtual(Loc, PrevSpec, DiagID);
+      break;
+    case tok::kw_explicit:
+      isInvalid = DS.SetFunctionSpecExplicit(Loc, PrevSpec, DiagID);
+      break;
+
+    // friend
+    case tok::kw_friend:
+      if (DSContext == DSC_class)
+        isInvalid = DS.SetFriendSpec(Loc, PrevSpec, DiagID);
+      else {
+        PrevSpec = ""; // not actually used by the diagnostic
+        DiagID = diag::err_friend_invalid_in_context;
+        isInvalid = true;
+      }
+      break;
+
+    // constexpr
+    case tok::kw_constexpr:
+      isInvalid = DS.SetConstexprSpec(Loc, PrevSpec, DiagID);
+      break;
+
+    // type-specifier
+    case tok::kw_short:
+      isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec,
+                                      DiagID);
+      break;
+    case tok::kw_long:
+      if (DS.getTypeSpecWidth() != DeclSpec::TSW_long)
+        isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec,
+                                        DiagID);
+      else
+        isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_longlong, Loc, PrevSpec,
+                                        DiagID);
+      break;
+    case tok::kw_signed:
+      isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec,
+                                     DiagID);
+      break;
+    case tok::kw_unsigned:
+      isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec,
+                                     DiagID);
+      break;
+    case tok::kw__Complex:
+      isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_complex, Loc, PrevSpec,
+                                        DiagID);
+      break;
+    case tok::kw__Imaginary:
+      isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_imaginary, Loc, PrevSpec,
+                                        DiagID);
+      break;
+    case tok::kw_void:
+      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec,
+                                     DiagID);
+      break;
+    case tok::kw_char:
+      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec,
+                                     DiagID);
+      break;
+    case tok::kw_int:
+      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec,
+                                     DiagID);
+      break;
+    case tok::kw_float:
+      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec,
+                                     DiagID);
+      break;
+    case tok::kw_double:
+      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec,
+                                     DiagID);
+      break;
+    case tok::kw_wchar_t:
+      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec,
+                                     DiagID);
+      break;
+    case tok::kw_char16_t:
+      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char16, Loc, PrevSpec,
+                                     DiagID);
+      break;
+    case tok::kw_char32_t:
+      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char32, Loc, PrevSpec,
+                                     DiagID);
+      break;
+    case tok::kw_bool:
+    case tok::kw__Bool:
+      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec,
+                                     DiagID);
+      break;
+    case tok::kw__Decimal32:
+      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal32, Loc, PrevSpec,
+                                     DiagID);
+      break;
+    case tok::kw__Decimal64:
+      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal64, Loc, PrevSpec,
+                                     DiagID);
+      break;
+    case tok::kw__Decimal128:
+      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal128, Loc, PrevSpec,
+                                     DiagID);
+      break;
+    case tok::kw___vector:
+      isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID);
+      break;
+    case tok::kw___pixel:
+      isInvalid = DS.SetTypeAltiVecPixel(true, Loc, PrevSpec, DiagID);
+      break;
+
+    // class-specifier:
+    case tok::kw_class:
+    case tok::kw_struct:
+    case tok::kw_union: {
+      tok::TokenKind Kind = Tok.getKind();
+      ConsumeToken();
+      ParseClassSpecifier(Kind, Loc, DS, TemplateInfo, AS);
+      continue;
+    }
+
+    // enum-specifier:
+    case tok::kw_enum:
+      ConsumeToken();
+      ParseEnumSpecifier(Loc, DS, TemplateInfo, AS);
+      continue;
+
+    // cv-qualifier:
+    case tok::kw_const:
+      isInvalid = DS.SetTypeQual(DeclSpec::TQ_const, Loc, PrevSpec, DiagID,
+                                 getLang());
+      break;
+    case tok::kw_volatile:
+      isInvalid = DS.SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec, DiagID,
+                                 getLang());
+      break;
+    case tok::kw_restrict:
+      isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec, DiagID,
+                                 getLang());
+      break;
+
+    // C++ typename-specifier:
+    case tok::kw_typename:
+      if (TryAnnotateTypeOrScopeToken()) {
+        DS.SetTypeSpecError();
+        goto DoneWithDeclSpec;
+      }
+      if (!Tok.is(tok::kw_typename))
+        continue;
+      break;
+
+    // GNU typeof support.
+    case tok::kw_typeof:
+      ParseTypeofSpecifier(DS);
+      continue;
+
+    case tok::kw_decltype:
+      ParseDecltypeSpecifier(DS);
+      continue;
+
+    case tok::less:
+      // GCC ObjC supports types like "<SomeProtocol>" as a synonym for
+      // "id<SomeProtocol>".  This is hopelessly old fashioned and dangerous,
+      // but we support it.
+      if (DS.hasTypeSpecifier() || !getLang().ObjC1)
+        goto DoneWithDeclSpec;
+
+      {
+        SourceLocation LAngleLoc, EndProtoLoc;
+        llvm::SmallVector<DeclPtrTy, 8> ProtocolDecl;
+        llvm::SmallVector<SourceLocation, 8> ProtocolLocs;
+        ParseObjCProtocolReferences(ProtocolDecl, ProtocolLocs, false,
+                                    LAngleLoc, EndProtoLoc);
+        DS.setProtocolQualifiers(ProtocolDecl.data(), ProtocolDecl.size(),
+                                 ProtocolLocs.data(), LAngleLoc);
+        DS.SetRangeEnd(EndProtoLoc);
+
+        Diag(Loc, diag::warn_objc_protocol_qualifier_missing_id)
+          << FixItHint::CreateInsertion(Loc, "id")
+          << SourceRange(Loc, EndProtoLoc);
+        // Need to support trailing type qualifiers (e.g. "id<p> const").
+        // If a type specifier follows, it will be diagnosed elsewhere.
+        continue;
+      }
+    }
+    // If the specifier wasn't legal, issue a diagnostic.
+    if (isInvalid) {
+      assert(PrevSpec && "Method did not return previous specifier!");
+      assert(DiagID);
+      Diag(Tok, DiagID) << PrevSpec;
+    }
+    DS.SetRangeEnd(Tok.getLocation());
+    ConsumeToken();
+  }
+}
+
+/// ParseOptionalTypeSpecifier - Try to parse a single type-specifier. We
+/// primarily follow the C++ grammar with additions for C99 and GNU,
+/// which together subsume the C grammar. Note that the C++
+/// type-specifier also includes the C type-qualifier (for const,
+/// volatile, and C99 restrict). Returns true if a type-specifier was
+/// found (and parsed), false otherwise.
+///
+///       type-specifier: [C++ 7.1.5]
+///         simple-type-specifier
+///         class-specifier
+///         enum-specifier
+///         elaborated-type-specifier  [TODO]
+///         cv-qualifier
+///
+///       cv-qualifier: [C++ 7.1.5.1]
+///         'const'
+///         'volatile'
+/// [C99]   'restrict'
+///
+///       simple-type-specifier: [ C++ 7.1.5.2]
+///         '::'[opt] nested-name-specifier[opt] type-name [TODO]
+///         '::'[opt] nested-name-specifier 'template' template-id [TODO]
+///         'char'
+///         'wchar_t'
+///         'bool'
+///         'short'
+///         'int'
+///         'long'
+///         'signed'
+///         'unsigned'
+///         'float'
+///         'double'
+///         'void'
+/// [C99]   '_Bool'
+/// [C99]   '_Complex'
+/// [C99]   '_Imaginary'  // Removed in TC2?
+/// [GNU]   '_Decimal32'
+/// [GNU]   '_Decimal64'
+/// [GNU]   '_Decimal128'
+/// [GNU]   typeof-specifier
+/// [OBJC]  class-name objc-protocol-refs[opt]    [TODO]
+/// [OBJC]  typedef-name objc-protocol-refs[opt]  [TODO]
+/// [C++0x] 'decltype' ( expression )
+/// [AltiVec] '__vector'
+bool Parser::ParseOptionalTypeSpecifier(DeclSpec &DS, bool& isInvalid,
+                                        const char *&PrevSpec,
+                                        unsigned &DiagID,
+                                        const ParsedTemplateInfo &TemplateInfo,
+                                        bool SuppressDeclarations) {
+  SourceLocation Loc = Tok.getLocation();
+
+  switch (Tok.getKind()) {
+  case tok::identifier:   // foo::bar
+    // If we already have a type specifier, this identifier is not a type.
+    if (DS.getTypeSpecType() != DeclSpec::TST_unspecified ||
+        DS.getTypeSpecWidth() != DeclSpec::TSW_unspecified ||
+        DS.getTypeSpecSign() != DeclSpec::TSS_unspecified)
+      return false;
+    // Check for need to substitute AltiVec keyword tokens.
+    if (TryAltiVecToken(DS, Loc, PrevSpec, DiagID, isInvalid))
+      break;
+    // Fall through.
+  case tok::kw_typename:  // typename foo::bar
+    // Annotate typenames and C++ scope specifiers.  If we get one, just
+    // recurse to handle whatever we get.
+    if (TryAnnotateTypeOrScopeToken())
+      return true;
+    if (Tok.is(tok::identifier))
+      return false;
+    return ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec, DiagID,
+                                      TemplateInfo, SuppressDeclarations);
+  case tok::coloncolon:   // ::foo::bar
+    if (NextToken().is(tok::kw_new) ||    // ::new
+        NextToken().is(tok::kw_delete))   // ::delete
+      return false;
+
+    // Annotate typenames and C++ scope specifiers.  If we get one, just
+    // recurse to handle whatever we get.
+    if (TryAnnotateTypeOrScopeToken())
+      return true;
+    return ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec, DiagID,
+                                      TemplateInfo, SuppressDeclarations);
+
+  // simple-type-specifier:
+  case tok::annot_typename: {
+    if (Tok.getAnnotationValue())
+      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
+                                     DiagID, Tok.getAnnotationValue());
+    else
+      DS.SetTypeSpecError();
+    DS.SetRangeEnd(Tok.getAnnotationEndLoc());
+    ConsumeToken(); // The typename
+
+    // Objective-C supports syntax of the form 'id<proto1,proto2>' where 'id'
+    // is a specific typedef and 'itf<proto1,proto2>' where 'itf' is an
+    // Objective-C interface.  If we don't have Objective-C or a '<', this is
+    // just a normal reference to a typedef name.
+    if (!Tok.is(tok::less) || !getLang().ObjC1)
+      return true;
+
+    SourceLocation LAngleLoc, EndProtoLoc;
+    llvm::SmallVector<DeclPtrTy, 8> ProtocolDecl;
+    llvm::SmallVector<SourceLocation, 8> ProtocolLocs;
+    ParseObjCProtocolReferences(ProtocolDecl, ProtocolLocs, false,
+                                LAngleLoc, EndProtoLoc);
+    DS.setProtocolQualifiers(ProtocolDecl.data(), ProtocolDecl.size(),
+                             ProtocolLocs.data(), LAngleLoc);
+
+    DS.SetRangeEnd(EndProtoLoc);
+    return true;
+  }
+
+  case tok::kw_short:
+    isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec, DiagID);
+    break;
+  case tok::kw_long:
+    if (DS.getTypeSpecWidth() != DeclSpec::TSW_long)
+      isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec,
+                                      DiagID);
+    else
+      isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_longlong, Loc, PrevSpec,
+                                      DiagID);
+    break;
+  case tok::kw_signed:
+    isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec, DiagID);
+    break;
+  case tok::kw_unsigned:
+    isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec,
+                                   DiagID);
+    break;
+  case tok::kw__Complex:
+    isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_complex, Loc, PrevSpec,
+                                      DiagID);
+    break;
+  case tok::kw__Imaginary:
+    isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_imaginary, Loc, PrevSpec,
+                                      DiagID);
+    break;
+  case tok::kw_void:
+    isInvalid = DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec, DiagID);
+    break;
+  case tok::kw_char:
+    isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec, DiagID);
+    break;
+  case tok::kw_int:
+    isInvalid = DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec, DiagID);
+    break;
+  case tok::kw_float:
+    isInvalid = DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec, DiagID);
+    break;
+  case tok::kw_double:
+    isInvalid = DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec, DiagID);
+    break;
+  case tok::kw_wchar_t:
+    isInvalid = DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec, DiagID);
+    break;
+  case tok::kw_char16_t:
+    isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char16, Loc, PrevSpec, DiagID);
+    break;
+  case tok::kw_char32_t:
+    isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char32, Loc, PrevSpec, DiagID);
+    break;
+  case tok::kw_bool:
+  case tok::kw__Bool:
+    isInvalid = DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec, DiagID);
+    break;
+  case tok::kw__Decimal32:
+    isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal32, Loc, PrevSpec,
+                                   DiagID);
+    break;
+  case tok::kw__Decimal64:
+    isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal64, Loc, PrevSpec,
+                                   DiagID);
+    break;
+  case tok::kw__Decimal128:
+    isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal128, Loc, PrevSpec,
+                                   DiagID);
+    break;
+  case tok::kw___vector:
+    isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID);
+    break;
+  case tok::kw___pixel:
+    isInvalid = DS.SetTypeAltiVecPixel(true, Loc, PrevSpec, DiagID);
+    break;
+  
+  // class-specifier:
+  case tok::kw_class:
+  case tok::kw_struct:
+  case tok::kw_union: {
+    tok::TokenKind Kind = Tok.getKind();
+    ConsumeToken();
+    ParseClassSpecifier(Kind, Loc, DS, TemplateInfo, AS_none,
+                        SuppressDeclarations);
+    return true;
+  }
+
+  // enum-specifier:
+  case tok::kw_enum:
+    ConsumeToken();
+    ParseEnumSpecifier(Loc, DS, TemplateInfo, AS_none);
+    return true;
+
+  // cv-qualifier:
+  case tok::kw_const:
+    isInvalid = DS.SetTypeQual(DeclSpec::TQ_const   , Loc, PrevSpec,
+                               DiagID, getLang());
+    break;
+  case tok::kw_volatile:
+    isInvalid = DS.SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec,
+                               DiagID, getLang());
+    break;
+  case tok::kw_restrict:
+    isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec,
+                               DiagID, getLang());
+    break;
+
+  // GNU typeof support.
+  case tok::kw_typeof:
+    ParseTypeofSpecifier(DS);
+    return true;
+
+  // C++0x decltype support.
+  case tok::kw_decltype:
+    ParseDecltypeSpecifier(DS);
+    return true;
+
+  // C++0x auto support.
+  case tok::kw_auto:
+    if (!getLang().CPlusPlus0x)
+      return false;
+
+    isInvalid = DS.SetTypeSpecType(DeclSpec::TST_auto, Loc, PrevSpec, DiagID);
+    break;
+  case tok::kw___ptr64:
+  case tok::kw___w64:
+  case tok::kw___cdecl:
+  case tok::kw___stdcall:
+  case tok::kw___fastcall:
+    DS.AddAttributes(ParseMicrosoftTypeAttributes());
+    return true;
+
+  default:
+    // Not a type-specifier; do nothing.
+    return false;
+  }
+
+  // If the specifier combination wasn't legal, issue a diagnostic.
+  if (isInvalid) {
+    assert(PrevSpec && "Method did not return previous specifier!");
+    // Pick between error or extwarn.
+    Diag(Tok, DiagID) << PrevSpec;
+  }
+  DS.SetRangeEnd(Tok.getLocation());
+  ConsumeToken(); // whatever we parsed above.
+  return true;
+}
+
+/// ParseStructDeclaration - Parse a struct declaration without the terminating
+/// semicolon.
+///
+///       struct-declaration:
+///         specifier-qualifier-list struct-declarator-list
+/// [GNU]   __extension__ struct-declaration
+/// [GNU]   specifier-qualifier-list
+///       struct-declarator-list:
+///         struct-declarator
+///         struct-declarator-list ',' struct-declarator
+/// [GNU]   struct-declarator-list ',' attributes[opt] struct-declarator
+///       struct-declarator:
+///         declarator
+/// [GNU]   declarator attributes[opt]
+///         declarator[opt] ':' constant-expression
+/// [GNU]   declarator[opt] ':' constant-expression attributes[opt]
+///
+void Parser::
+ParseStructDeclaration(DeclSpec &DS, FieldCallback &Fields) {
+  if (Tok.is(tok::kw___extension__)) {
+    // __extension__ silences extension warnings in the subexpression.
+    ExtensionRAIIObject O(Diags);  // Use RAII to do this.
+    ConsumeToken();
+    return ParseStructDeclaration(DS, Fields);
+  }
+
+  // Parse the common specifier-qualifiers-list piece.
+  SourceLocation DSStart = Tok.getLocation();
+  ParseSpecifierQualifierList(DS);
+
+  // If there are no declarators, this is a free-standing declaration
+  // specifier. Let the actions module cope with it.
+  if (Tok.is(tok::semi)) {
+    Actions.ParsedFreeStandingDeclSpec(CurScope, DS);
+    return;
+  }
+
+  // Read struct-declarators until we find the semicolon.
+  bool FirstDeclarator = true;
+  while (1) {
+    ParsingDeclRAIIObject PD(*this);
+    FieldDeclarator DeclaratorInfo(DS);
+
+    // Attributes are only allowed here on successive declarators.
+    if (!FirstDeclarator && Tok.is(tok::kw___attribute)) {
+      SourceLocation Loc;
+      AttributeList *AttrList = ParseGNUAttributes(&Loc);
+      DeclaratorInfo.D.AddAttributes(AttrList, Loc);
+    }
+
+    /// struct-declarator: declarator
+    /// struct-declarator: declarator[opt] ':' constant-expression
+    if (Tok.isNot(tok::colon)) {
+      // Don't parse FOO:BAR as if it were a typo for FOO::BAR.
+      ColonProtectionRAIIObject X(*this);
+      ParseDeclarator(DeclaratorInfo.D);
+    }
+
+    if (Tok.is(tok::colon)) {
+      ConsumeToken();
+      OwningExprResult Res(ParseConstantExpression());
+      if (Res.isInvalid())
+        SkipUntil(tok::semi, true, true);
+      else
+        DeclaratorInfo.BitfieldSize = Res.release();
+    }
+
+    // If attributes exist after the declarator, parse them.
+    if (Tok.is(tok::kw___attribute)) {
+      SourceLocation Loc;
+      AttributeList *AttrList = ParseGNUAttributes(&Loc);
+      DeclaratorInfo.D.AddAttributes(AttrList, Loc);
+    }
+
+    // We're done with this declarator;  invoke the callback.
+    DeclPtrTy D = Fields.invoke(DeclaratorInfo);
+    PD.complete(D);
+
+    // If we don't have a comma, it is either the end of the list (a ';')
+    // or an error, bail out.
+    if (Tok.isNot(tok::comma))
+      return;
+
+    // Consume the comma.
+    ConsumeToken();
+
+    FirstDeclarator = false;
+  }
+}
+
+/// ParseStructUnionBody
+///       struct-contents:
+///         struct-declaration-list
+/// [EXT]   empty
+/// [GNU]   "struct-declaration-list" without terminatoring ';'
+///       struct-declaration-list:
+///         struct-declaration
+///         struct-declaration-list struct-declaration
+/// [OBC]   '@' 'defs' '(' class-name ')'
+///
+void Parser::ParseStructUnionBody(SourceLocation RecordLoc,
+                                  unsigned TagType, DeclPtrTy TagDecl) {
+  PrettyStackTraceActionsDecl CrashInfo(TagDecl, RecordLoc, Actions,
+                                        PP.getSourceManager(),
+                                        "parsing struct/union body");
+
+  SourceLocation LBraceLoc = ConsumeBrace();
+
+  ParseScope StructScope(this, Scope::ClassScope|Scope::DeclScope);
+  Actions.ActOnTagStartDefinition(CurScope, TagDecl);
+
+  // Empty structs are an extension in C (C99 6.7.2.1p7), but are allowed in
+  // C++.
+  if (Tok.is(tok::r_brace) && !getLang().CPlusPlus)
+    Diag(Tok, diag::ext_empty_struct_union_enum)
+      << DeclSpec::getSpecifierName((DeclSpec::TST)TagType);
+
+  llvm::SmallVector<DeclPtrTy, 32> FieldDecls;
+
+  // While we still have something to read, read the declarations in the struct.
+  while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
+    // Each iteration of this loop reads one struct-declaration.
+
+    // Check for extraneous top-level semicolon.
+    if (Tok.is(tok::semi)) {
+      Diag(Tok, diag::ext_extra_struct_semi)
+        << FixItHint::CreateRemoval(Tok.getLocation());
+      ConsumeToken();
+      continue;
+    }
+
+    // Parse all the comma separated declarators.
+    DeclSpec DS;
+
+    if (!Tok.is(tok::at)) {
+      struct CFieldCallback : FieldCallback {
+        Parser &P;
+        DeclPtrTy TagDecl;
+        llvm::SmallVectorImpl<DeclPtrTy> &FieldDecls;
+
+        CFieldCallback(Parser &P, DeclPtrTy TagDecl,
+                       llvm::SmallVectorImpl<DeclPtrTy> &FieldDecls) :
+          P(P), TagDecl(TagDecl), FieldDecls(FieldDecls) {}
+
+        virtual DeclPtrTy invoke(FieldDeclarator &FD) {
+          // Install the declarator into the current TagDecl.
+          DeclPtrTy Field = P.Actions.ActOnField(P.CurScope, TagDecl,
+                              FD.D.getDeclSpec().getSourceRange().getBegin(),
+                                                 FD.D, FD.BitfieldSize);
+          FieldDecls.push_back(Field);
+          return Field;
+        }
+      } Callback(*this, TagDecl, FieldDecls);
+
+      ParseStructDeclaration(DS, Callback);
+    } else { // Handle @defs
+      ConsumeToken();
+      if (!Tok.isObjCAtKeyword(tok::objc_defs)) {
+        Diag(Tok, diag::err_unexpected_at);
+        SkipUntil(tok::semi, true);
+        continue;
+      }
+      ConsumeToken();
+      ExpectAndConsume(tok::l_paren, diag::err_expected_lparen);
+      if (!Tok.is(tok::identifier)) {
+        Diag(Tok, diag::err_expected_ident);
+        SkipUntil(tok::semi, true);
+        continue;
+      }
+      llvm::SmallVector<DeclPtrTy, 16> Fields;
+      Actions.ActOnDefs(CurScope, TagDecl, Tok.getLocation(),
+                        Tok.getIdentifierInfo(), Fields);
+      FieldDecls.insert(FieldDecls.end(), Fields.begin(), Fields.end());
+      ConsumeToken();
+      ExpectAndConsume(tok::r_paren, diag::err_expected_rparen);
+    }
+
+    if (Tok.is(tok::semi)) {
+      ConsumeToken();
+    } else if (Tok.is(tok::r_brace)) {
+      ExpectAndConsume(tok::semi, diag::ext_expected_semi_decl_list);
+      break;
+    } else {
+      ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list);
+      // Skip to end of block or statement to avoid ext-warning on extra ';'.
+      SkipUntil(tok::r_brace, true, true);
+      // If we stopped at a ';', eat it.
+      if (Tok.is(tok::semi)) ConsumeToken();
+    }
+  }
+
+  SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc);
+
+  llvm::OwningPtr<AttributeList> AttrList;
+  // If attributes exist after struct contents, parse them.
+  if (Tok.is(tok::kw___attribute))
+    AttrList.reset(ParseGNUAttributes());
+
+  Actions.ActOnFields(CurScope,
+                      RecordLoc, TagDecl, FieldDecls.data(), FieldDecls.size(),
+                      LBraceLoc, RBraceLoc,
+                      AttrList.get());
+  StructScope.Exit();
+  Actions.ActOnTagFinishDefinition(CurScope, TagDecl, RBraceLoc);
+}
+
+
+/// ParseEnumSpecifier
+///       enum-specifier: [C99 6.7.2.2]
+///         'enum' identifier[opt] '{' enumerator-list '}'
+///[C99/C++]'enum' identifier[opt] '{' enumerator-list ',' '}'
+/// [GNU]   'enum' attributes[opt] identifier[opt] '{' enumerator-list ',' [opt]
+///                                                 '}' attributes[opt]
+///         'enum' identifier
+/// [GNU]   'enum' attributes[opt] identifier
+///
+/// [C++] elaborated-type-specifier:
+/// [C++]   'enum' '::'[opt] nested-name-specifier[opt] identifier
+///
+void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
+                                const ParsedTemplateInfo &TemplateInfo,
+                                AccessSpecifier AS) {
+  // Parse the tag portion of this.
+  if (Tok.is(tok::code_completion)) {
+    // Code completion for an enum name.
+    Actions.CodeCompleteTag(CurScope, DeclSpec::TST_enum);
+    ConsumeToken();
+  }
+  
+  llvm::OwningPtr<AttributeList> Attr;
+  // If attributes exist after tag, parse them.
+  if (Tok.is(tok::kw___attribute))
+    Attr.reset(ParseGNUAttributes());
+
+  CXXScopeSpec SS;
+  if (getLang().CPlusPlus) {
+    if (ParseOptionalCXXScopeSpecifier(SS, 0, false))
+      return;
+
+    if (SS.isSet() && Tok.isNot(tok::identifier)) {
+      Diag(Tok, diag::err_expected_ident);
+      if (Tok.isNot(tok::l_brace)) {
+        // Has no name and is not a definition.
+        // Skip the rest of this declarator, up until the comma or semicolon.
+        SkipUntil(tok::comma, true);
+        return;
+      }
+    }
+  }
+
+  // Must have either 'enum name' or 'enum {...}'.
+  if (Tok.isNot(tok::identifier) && Tok.isNot(tok::l_brace)) {
+    Diag(Tok, diag::err_expected_ident_lbrace);
+
+    // Skip the rest of this declarator, up until the comma or semicolon.
+    SkipUntil(tok::comma, true);
+    return;
+  }
+
+  // enums cannot be templates.
+  if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate) {
+    Diag(Tok, diag::err_enum_template);
+
+    // Skip the rest of this declarator, up until the comma or semicolon.
+    SkipUntil(tok::comma, true);
+    return;      
+  }
+
+  // If an identifier is present, consume and remember it.
+  IdentifierInfo *Name = 0;
+  SourceLocation NameLoc;
+  if (Tok.is(tok::identifier)) {
+    Name = Tok.getIdentifierInfo();
+    NameLoc = ConsumeToken();
+  }
+
+  // There are three options here.  If we have 'enum foo;', then this is a
+  // forward declaration.  If we have 'enum foo {...' then this is a
+  // definition. Otherwise we have something like 'enum foo xyz', a reference.
+  //
+  // This is needed to handle stuff like this right (C99 6.7.2.3p11):
+  // enum foo {..};  void bar() { enum foo; }    <- new foo in bar.
+  // enum foo {..};  void bar() { enum foo x; }  <- use of old foo.
+  //
+  Action::TagUseKind TUK;
+  if (Tok.is(tok::l_brace))
+    TUK = Action::TUK_Definition;
+  else if (Tok.is(tok::semi))
+    TUK = Action::TUK_Declaration;
+  else
+    TUK = Action::TUK_Reference;
+  bool Owned = false;
+  bool IsDependent = false;
+  SourceLocation TSTLoc = NameLoc.isValid()? NameLoc : StartLoc;
+  const char *PrevSpec = 0;
+  unsigned DiagID;
+  DeclPtrTy TagDecl = Actions.ActOnTag(CurScope, DeclSpec::TST_enum, TUK,
+                                       StartLoc, SS, Name, NameLoc, Attr.get(),
+                                       AS,
+                                       Action::MultiTemplateParamsArg(Actions),
+                                       Owned, IsDependent);
+  if (IsDependent) {
+    // This enum has a dependent nested-name-specifier. Handle it as a 
+    // dependent tag.
+    if (!Name) {
+      DS.SetTypeSpecError();
+      Diag(Tok, diag::err_expected_type_name_after_typename);
+      return;
+    }
+    
+    TypeResult Type = Actions.ActOnDependentTag(CurScope, DeclSpec::TST_enum,
+                                                TUK, SS, Name, StartLoc, 
+                                                NameLoc);
+    if (Type.isInvalid()) {
+      DS.SetTypeSpecError();
+      return;
+    }
+    
+    if (DS.SetTypeSpecType(DeclSpec::TST_typename, TSTLoc, PrevSpec, DiagID,
+                           Type.get(), false))
+      Diag(StartLoc, DiagID) << PrevSpec;
+    
+    return;
+  }
+
+  if (!TagDecl.get()) {
+    // The action failed to produce an enumeration tag. If this is a 
+    // definition, consume the entire definition.
+    if (Tok.is(tok::l_brace)) {
+      ConsumeBrace();
+      SkipUntil(tok::r_brace);
+    }
+    
+    DS.SetTypeSpecError();
+    return;
+  }
+  
+  if (Tok.is(tok::l_brace))
+    ParseEnumBody(StartLoc, TagDecl);
+
+  // FIXME: The DeclSpec should keep the locations of both the keyword and the
+  // name (if there is one).
+  if (DS.SetTypeSpecType(DeclSpec::TST_enum, TSTLoc, PrevSpec, DiagID,
+                         TagDecl.getAs<void>(), Owned))
+    Diag(StartLoc, DiagID) << PrevSpec;
+}
+
+/// ParseEnumBody - Parse a {} enclosed enumerator-list.
+///       enumerator-list:
+///         enumerator
+///         enumerator-list ',' enumerator
+///       enumerator:
+///         enumeration-constant
+///         enumeration-constant '=' constant-expression
+///       enumeration-constant:
+///         identifier
+///
+void Parser::ParseEnumBody(SourceLocation StartLoc, DeclPtrTy EnumDecl) {
+  // Enter the scope of the enum body and start the definition.
+  ParseScope EnumScope(this, Scope::DeclScope);
+  Actions.ActOnTagStartDefinition(CurScope, EnumDecl);
+
+  SourceLocation LBraceLoc = ConsumeBrace();
+
+  // C does not allow an empty enumerator-list, C++ does [dcl.enum].
+  if (Tok.is(tok::r_brace) && !getLang().CPlusPlus)
+    Diag(Tok, diag::ext_empty_struct_union_enum) << "enum";
+
+  llvm::SmallVector<DeclPtrTy, 32> EnumConstantDecls;
+
+  DeclPtrTy LastEnumConstDecl;
+
+  // Parse the enumerator-list.
+  while (Tok.is(tok::identifier)) {
+    IdentifierInfo *Ident = Tok.getIdentifierInfo();
+    SourceLocation IdentLoc = ConsumeToken();
+
+    SourceLocation EqualLoc;
+    OwningExprResult AssignedVal(Actions);
+    if (Tok.is(tok::equal)) {
+      EqualLoc = ConsumeToken();
+      AssignedVal = ParseConstantExpression();
+      if (AssignedVal.isInvalid())
+        SkipUntil(tok::comma, tok::r_brace, true, true);
+    }
+
+    // Install the enumerator constant into EnumDecl.
+    DeclPtrTy EnumConstDecl = Actions.ActOnEnumConstant(CurScope, EnumDecl,
+                                                        LastEnumConstDecl,
+                                                        IdentLoc, Ident,
+                                                        EqualLoc,
+                                                        AssignedVal.release());
+    EnumConstantDecls.push_back(EnumConstDecl);
+    LastEnumConstDecl = EnumConstDecl;
+
+    if (Tok.isNot(tok::comma))
+      break;
+    SourceLocation CommaLoc = ConsumeToken();
+
+    if (Tok.isNot(tok::identifier) &&
+        !(getLang().C99 || getLang().CPlusPlus0x))
+      Diag(CommaLoc, diag::ext_enumerator_list_comma)
+        << getLang().CPlusPlus
+        << FixItHint::CreateRemoval(CommaLoc);
+  }
+
+  // Eat the }.
+  SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc);
+
+  llvm::OwningPtr<AttributeList> Attr;
+  // If attributes exist after the identifier list, parse them.
+  if (Tok.is(tok::kw___attribute))
+    Attr.reset(ParseGNUAttributes()); // FIXME: where do they do?
+
+  Actions.ActOnEnumBody(StartLoc, LBraceLoc, RBraceLoc, EnumDecl,
+                        EnumConstantDecls.data(), EnumConstantDecls.size(),
+                        CurScope, Attr.get());
+
+  EnumScope.Exit();
+  Actions.ActOnTagFinishDefinition(CurScope, EnumDecl, RBraceLoc);
+}
+
+/// isTypeSpecifierQualifier - Return true if the current token could be the
+/// start of a type-qualifier-list.
+bool Parser::isTypeQualifier() const {
+  switch (Tok.getKind()) {
+  default: return false;
+    // type-qualifier
+  case tok::kw_const:
+  case tok::kw_volatile:
+  case tok::kw_restrict:
+    return true;
+  }
+}
+
+/// isKnownToBeTypeSpecifier - Return true if we know that the specified token
+/// is definitely a type-specifier.  Return false if it isn't part of a type
+/// specifier or if we're not sure.
+bool Parser::isKnownToBeTypeSpecifier(const Token &Tok) const {
+  switch (Tok.getKind()) {
+  default: return false;
+    // type-specifiers
+  case tok::kw_short:
+  case tok::kw_long:
+  case tok::kw_signed:
+  case tok::kw_unsigned:
+  case tok::kw__Complex:
+  case tok::kw__Imaginary:
+  case tok::kw_void:
+  case tok::kw_char:
+  case tok::kw_wchar_t:
+  case tok::kw_char16_t:
+  case tok::kw_char32_t:
+  case tok::kw_int:
+  case tok::kw_float:
+  case tok::kw_double:
+  case tok::kw_bool:
+  case tok::kw__Bool:
+  case tok::kw__Decimal32:
+  case tok::kw__Decimal64:
+  case tok::kw__Decimal128:
+  case tok::kw___vector:
+    
+    // struct-or-union-specifier (C99) or class-specifier (C++)
+  case tok::kw_class:
+  case tok::kw_struct:
+  case tok::kw_union:
+    // enum-specifier
+  case tok::kw_enum:
+    
+    // typedef-name
+  case tok::annot_typename:
+    return true;
+  }
+}
+
+/// isTypeSpecifierQualifier - Return true if the current token could be the
+/// start of a specifier-qualifier-list.
+bool Parser::isTypeSpecifierQualifier() {
+  switch (Tok.getKind()) {
+  default: return false;
+
+  case tok::identifier:   // foo::bar
+    if (TryAltiVecVectorToken())
+      return true;
+    // Fall through.
+  case tok::kw_typename:  // typename T::type
+    // Annotate typenames and C++ scope specifiers.  If we get one, just
+    // recurse to handle whatever we get.
+    if (TryAnnotateTypeOrScopeToken())
+      return true;
+    if (Tok.is(tok::identifier))
+      return false;
+    return isTypeSpecifierQualifier();
+
+  case tok::coloncolon:   // ::foo::bar
+    if (NextToken().is(tok::kw_new) ||    // ::new
+        NextToken().is(tok::kw_delete))   // ::delete
+      return false;
+
+    if (TryAnnotateTypeOrScopeToken())
+      return true;
+    return isTypeSpecifierQualifier();
+
+    // GNU attributes support.
+  case tok::kw___attribute:
+    // GNU typeof support.
+  case tok::kw_typeof:
+
+    // type-specifiers
+  case tok::kw_short:
+  case tok::kw_long:
+  case tok::kw_signed:
+  case tok::kw_unsigned:
+  case tok::kw__Complex:
+  case tok::kw__Imaginary:
+  case tok::kw_void:
+  case tok::kw_char:
+  case tok::kw_wchar_t:
+  case tok::kw_char16_t:
+  case tok::kw_char32_t:
+  case tok::kw_int:
+  case tok::kw_float:
+  case tok::kw_double:
+  case tok::kw_bool:
+  case tok::kw__Bool:
+  case tok::kw__Decimal32:
+  case tok::kw__Decimal64:
+  case tok::kw__Decimal128:
+  case tok::kw___vector:
+
+    // struct-or-union-specifier (C99) or class-specifier (C++)
+  case tok::kw_class:
+  case tok::kw_struct:
+  case tok::kw_union:
+    // enum-specifier
+  case tok::kw_enum:
+
+    // type-qualifier
+  case tok::kw_const:
+  case tok::kw_volatile:
+  case tok::kw_restrict:
+
+    // typedef-name
+  case tok::annot_typename:
+    return true;
+
+    // GNU ObjC bizarre protocol extension: <proto1,proto2> with implicit 'id'.
+  case tok::less:
+    return getLang().ObjC1;
+
+  case tok::kw___cdecl:
+  case tok::kw___stdcall:
+  case tok::kw___fastcall:
+  case tok::kw___w64:
+  case tok::kw___ptr64:
+    return true;
+  }
+}
+
+/// isDeclarationSpecifier() - Return true if the current token is part of a
+/// declaration specifier.
+bool Parser::isDeclarationSpecifier() {
+  switch (Tok.getKind()) {
+  default: return false;
+
+  case tok::identifier:   // foo::bar
+    // Unfortunate hack to support "Class.factoryMethod" notation.
+    if (getLang().ObjC1 && NextToken().is(tok::period))
+      return false;
+    if (TryAltiVecVectorToken())
+      return true;
+    // Fall through.
+  case tok::kw_typename: // typename T::type
+    // Annotate typenames and C++ scope specifiers.  If we get one, just
+    // recurse to handle whatever we get.
+    if (TryAnnotateTypeOrScopeToken())
+      return true;
+    if (Tok.is(tok::identifier))
+      return false;
+    return isDeclarationSpecifier();
+
+  case tok::coloncolon:   // ::foo::bar
+    if (NextToken().is(tok::kw_new) ||    // ::new
+        NextToken().is(tok::kw_delete))   // ::delete
+      return false;
+
+    // Annotate typenames and C++ scope specifiers.  If we get one, just
+    // recurse to handle whatever we get.
+    if (TryAnnotateTypeOrScopeToken())
+      return true;
+    return isDeclarationSpecifier();
+
+    // storage-class-specifier
+  case tok::kw_typedef:
+  case tok::kw_extern:
+  case tok::kw___private_extern__:
+  case tok::kw_static:
+  case tok::kw_auto:
+  case tok::kw_register:
+  case tok::kw___thread:
+
+    // type-specifiers
+  case tok::kw_short:
+  case tok::kw_long:
+  case tok::kw_signed:
+  case tok::kw_unsigned:
+  case tok::kw__Complex:
+  case tok::kw__Imaginary:
+  case tok::kw_void:
+  case tok::kw_char:
+  case tok::kw_wchar_t:
+  case tok::kw_char16_t:
+  case tok::kw_char32_t:
+
+  case tok::kw_int:
+  case tok::kw_float:
+  case tok::kw_double:
+  case tok::kw_bool:
+  case tok::kw__Bool:
+  case tok::kw__Decimal32:
+  case tok::kw__Decimal64:
+  case tok::kw__Decimal128:
+  case tok::kw___vector:
+
+    // struct-or-union-specifier (C99) or class-specifier (C++)
+  case tok::kw_class:
+  case tok::kw_struct:
+  case tok::kw_union:
+    // enum-specifier
+  case tok::kw_enum:
+
+    // type-qualifier
+  case tok::kw_const:
+  case tok::kw_volatile:
+  case tok::kw_restrict:
+
+    // function-specifier
+  case tok::kw_inline:
+  case tok::kw_virtual:
+  case tok::kw_explicit:
+
+    // typedef-name
+  case tok::annot_typename:
+
+    // GNU typeof support.
+  case tok::kw_typeof:
+
+    // GNU attributes.
+  case tok::kw___attribute:
+    return true;
+
+    // GNU ObjC bizarre protocol extension: <proto1,proto2> with implicit 'id'.
+  case tok::less:
+    return getLang().ObjC1;
+
+  case tok::kw___declspec:
+  case tok::kw___cdecl:
+  case tok::kw___stdcall:
+  case tok::kw___fastcall:
+  case tok::kw___w64:
+  case tok::kw___ptr64:
+  case tok::kw___forceinline:
+    return true;
+  }
+}
+
+bool Parser::isConstructorDeclarator() {
+  TentativeParsingAction TPA(*this);
+
+  // Parse the C++ scope specifier.
+  CXXScopeSpec SS;
+  if (ParseOptionalCXXScopeSpecifier(SS, 0, true)) {
+    TPA.Revert();
+    return false;
+  }
+
+  // Parse the constructor name.
+  if (Tok.is(tok::identifier) || Tok.is(tok::annot_template_id)) {
+    // We already know that we have a constructor name; just consume
+    // the token.
+    ConsumeToken();
+  } else {
+    TPA.Revert();
+    return false;
+  }
+
+  // Current class name must be followed by a left parentheses.
+  if (Tok.isNot(tok::l_paren)) {
+    TPA.Revert();
+    return false;
+  }
+  ConsumeParen();
+
+  // A right parentheses or ellipsis signals that we have a constructor.
+  if (Tok.is(tok::r_paren) || Tok.is(tok::ellipsis)) {
+    TPA.Revert();
+    return true;
+  }
+
+  // If we need to, enter the specified scope.
+  DeclaratorScopeObj DeclScopeObj(*this, SS);
+  if (SS.isSet() && Actions.ShouldEnterDeclaratorScope(CurScope, SS))
+    DeclScopeObj.EnterDeclaratorScope();
+
+  // Check whether the next token(s) are part of a declaration
+  // specifier, in which case we have the start of a parameter and,
+  // therefore, we know that this is a constructor.
+  bool IsConstructor = isDeclarationSpecifier();
+  TPA.Revert();
+  return IsConstructor;
+}
+
+/// ParseTypeQualifierListOpt
+///       type-qualifier-list: [C99 6.7.5]
+///         type-qualifier
+/// [GNU]   attributes                        [ only if AttributesAllowed=true ]
+///         type-qualifier-list type-qualifier
+/// [GNU]   type-qualifier-list attributes    [ only if AttributesAllowed=true ]
+/// [C++0x] attribute-specifier[opt] is allowed before cv-qualifier-seq
+///           if CXX0XAttributesAllowed = true
+///
+void Parser::ParseTypeQualifierListOpt(DeclSpec &DS, bool GNUAttributesAllowed,
+                                       bool CXX0XAttributesAllowed) {
+  if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier()) {
+    SourceLocation Loc = Tok.getLocation();
+    CXX0XAttributeList Attr = ParseCXX0XAttributes();
+    if (CXX0XAttributesAllowed)
+      DS.AddAttributes(Attr.AttrList);
+    else
+      Diag(Loc, diag::err_attributes_not_allowed);
+  }
+  
+  while (1) {
+    bool isInvalid = false;
+    const char *PrevSpec = 0;
+    unsigned DiagID = 0;
+    SourceLocation Loc = Tok.getLocation();
+
+    switch (Tok.getKind()) {
+    case tok::kw_const:
+      isInvalid = DS.SetTypeQual(DeclSpec::TQ_const   , Loc, PrevSpec, DiagID,
+                                 getLang());
+      break;
+    case tok::kw_volatile:
+      isInvalid = DS.SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec, DiagID,
+                                 getLang());
+      break;
+    case tok::kw_restrict:
+      isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec, DiagID,
+                                 getLang());
+      break;
+    case tok::kw___w64:
+    case tok::kw___ptr64:
+    case tok::kw___cdecl:
+    case tok::kw___stdcall:
+    case tok::kw___fastcall:
+      if (GNUAttributesAllowed) {
+        DS.AddAttributes(ParseMicrosoftTypeAttributes());
+        continue;
+      }
+      goto DoneWithTypeQuals;
+    case tok::kw___attribute:
+      if (GNUAttributesAllowed) {
+        DS.AddAttributes(ParseGNUAttributes());
+        continue; // do *not* consume the next token!
+      }
+      // otherwise, FALL THROUGH!
+    default:
+      DoneWithTypeQuals:
+      // If this is not a type-qualifier token, we're done reading type
+      // qualifiers.  First verify that DeclSpec's are consistent.
+      DS.Finish(Diags, PP);
+      return;
+    }
+
+    // If the specifier combination wasn't legal, issue a diagnostic.
+    if (isInvalid) {
+      assert(PrevSpec && "Method did not return previous specifier!");
+      Diag(Tok, DiagID) << PrevSpec;
+    }
+    ConsumeToken();
+  }
+}
+
+
+/// ParseDeclarator - Parse and verify a newly-initialized declarator.
+///
+void Parser::ParseDeclarator(Declarator &D) {
+  /// This implements the 'declarator' production in the C grammar, then checks
+  /// for well-formedness and issues diagnostics.
+  ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
+}
+
+/// ParseDeclaratorInternal - Parse a C or C++ declarator. The direct-declarator
+/// is parsed by the function passed to it. Pass null, and the direct-declarator
+/// isn't parsed at all, making this function effectively parse the C++
+/// ptr-operator production.
+///
+///       declarator: [C99 6.7.5] [C++ 8p4, dcl.decl]
+/// [C]     pointer[opt] direct-declarator
+/// [C++]   direct-declarator
+/// [C++]   ptr-operator declarator
+///
+///       pointer: [C99 6.7.5]
+///         '*' type-qualifier-list[opt]
+///         '*' type-qualifier-list[opt] pointer
+///
+///       ptr-operator:
+///         '*' cv-qualifier-seq[opt]
+///         '&'
+/// [C++0x] '&&'
+/// [GNU]   '&' restrict[opt] attributes[opt]
+/// [GNU?]  '&&' restrict[opt] attributes[opt]
+///         '::'[opt] nested-name-specifier '*' cv-qualifier-seq[opt]
+void Parser::ParseDeclaratorInternal(Declarator &D,
+                                     DirectDeclParseFunction DirectDeclParser) {
+  if (Diags.hasAllExtensionsSilenced())
+    D.setExtension();
+  // C++ member pointers start with a '::' or a nested-name.
+  // Member pointers get special handling, since there's no place for the
+  // scope spec in the generic path below.
+  if (getLang().CPlusPlus &&
+      (Tok.is(tok::coloncolon) || Tok.is(tok::identifier) ||
+       Tok.is(tok::annot_cxxscope))) {
+    CXXScopeSpec SS;
+    ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, true); // ignore fail
+
+    if (SS.isNotEmpty()) {
+      if (Tok.isNot(tok::star)) {
+        // The scope spec really belongs to the direct-declarator.
+        D.getCXXScopeSpec() = SS;
+        if (DirectDeclParser)
+          (this->*DirectDeclParser)(D);
+        return;
+      }
+
+      SourceLocation Loc = ConsumeToken();
+      D.SetRangeEnd(Loc);
+      DeclSpec DS;
+      ParseTypeQualifierListOpt(DS);
+      D.ExtendWithDeclSpec(DS);
+
+      // Recurse to parse whatever is left.
+      ParseDeclaratorInternal(D, DirectDeclParser);
+
+      // Sema will have to catch (syntactically invalid) pointers into global
+      // scope. It has to catch pointers into namespace scope anyway.
+      D.AddTypeInfo(DeclaratorChunk::getMemberPointer(SS,DS.getTypeQualifiers(),
+                                                      Loc, DS.TakeAttributes()),
+                    /* Don't replace range end. */SourceLocation());
+      return;
+    }
+  }
+
+  tok::TokenKind Kind = Tok.getKind();
+  // Not a pointer, C++ reference, or block.
+  if (Kind != tok::star && Kind != tok::caret &&
+      (Kind != tok::amp || !getLang().CPlusPlus) &&
+      // We parse rvalue refs in C++03, because otherwise the errors are scary.
+      (Kind != tok::ampamp || !getLang().CPlusPlus)) {
+    if (DirectDeclParser)
+      (this->*DirectDeclParser)(D);
+    return;
+  }
+
+  // Otherwise, '*' -> pointer, '^' -> block, '&' -> lvalue reference,
+  // '&&' -> rvalue reference
+  SourceLocation Loc = ConsumeToken();  // Eat the *, ^, & or &&.
+  D.SetRangeEnd(Loc);
+
+  if (Kind == tok::star || Kind == tok::caret) {
+    // Is a pointer.
+    DeclSpec DS;
+
+    ParseTypeQualifierListOpt(DS);
+    D.ExtendWithDeclSpec(DS);
+
+    // Recursively parse the declarator.
+    ParseDeclaratorInternal(D, DirectDeclParser);
+    if (Kind == tok::star)
+      // Remember that we parsed a pointer type, and remember the type-quals.
+      D.AddTypeInfo(DeclaratorChunk::getPointer(DS.getTypeQualifiers(), Loc,
+                                                DS.TakeAttributes()),
+                    SourceLocation());
+    else
+      // Remember that we parsed a Block type, and remember the type-quals.
+      D.AddTypeInfo(DeclaratorChunk::getBlockPointer(DS.getTypeQualifiers(),
+                                                     Loc, DS.TakeAttributes()),
+                    SourceLocation());
+  } else {
+    // Is a reference
+    DeclSpec DS;
+
+    // Complain about rvalue references in C++03, but then go on and build
+    // the declarator.
+    if (Kind == tok::ampamp && !getLang().CPlusPlus0x)
+      Diag(Loc, diag::err_rvalue_reference);
+
+    // C++ 8.3.2p1: cv-qualified references are ill-formed except when the
+    // cv-qualifiers are introduced through the use of a typedef or of a
+    // template type argument, in which case the cv-qualifiers are ignored.
+    //
+    // [GNU] Retricted references are allowed.
+    // [GNU] Attributes on references are allowed.
+    // [C++0x] Attributes on references are not allowed.
+    ParseTypeQualifierListOpt(DS, true, false);
+    D.ExtendWithDeclSpec(DS);
+
+    if (DS.getTypeQualifiers() != DeclSpec::TQ_unspecified) {
+      if (DS.getTypeQualifiers() & DeclSpec::TQ_const)
+        Diag(DS.getConstSpecLoc(),
+             diag::err_invalid_reference_qualifier_application) << "const";
+      if (DS.getTypeQualifiers() & DeclSpec::TQ_volatile)
+        Diag(DS.getVolatileSpecLoc(),
+             diag::err_invalid_reference_qualifier_application) << "volatile";
+    }
+
+    // Recursively parse the declarator.
+    ParseDeclaratorInternal(D, DirectDeclParser);
+
+    if (D.getNumTypeObjects() > 0) {
+      // C++ [dcl.ref]p4: There shall be no references to references.
+      DeclaratorChunk& InnerChunk = D.getTypeObject(D.getNumTypeObjects() - 1);
+      if (InnerChunk.Kind == DeclaratorChunk::Reference) {
+        if (const IdentifierInfo *II = D.getIdentifier())
+          Diag(InnerChunk.Loc, diag::err_illegal_decl_reference_to_reference)
+           << II;
+        else
+          Diag(InnerChunk.Loc, diag::err_illegal_decl_reference_to_reference)
+            << "type name";
+
+        // Once we've complained about the reference-to-reference, we
+        // can go ahead and build the (technically ill-formed)
+        // declarator: reference collapsing will take care of it.
+      }
+    }
+
+    // Remember that we parsed a reference type. It doesn't have type-quals.
+    D.AddTypeInfo(DeclaratorChunk::getReference(DS.getTypeQualifiers(), Loc,
+                                                DS.TakeAttributes(),
+                                                Kind == tok::amp),
+                  SourceLocation());
+  }
+}
+
+/// ParseDirectDeclarator
+///       direct-declarator: [C99 6.7.5]
+/// [C99]   identifier
+///         '(' declarator ')'
+/// [GNU]   '(' attributes declarator ')'
+/// [C90]   direct-declarator '[' constant-expression[opt] ']'
+/// [C99]   direct-declarator '[' type-qual-list[opt] assignment-expr[opt] ']'
+/// [C99]   direct-declarator '[' 'static' type-qual-list[opt] assign-expr ']'
+/// [C99]   direct-declarator '[' type-qual-list 'static' assignment-expr ']'
+/// [C99]   direct-declarator '[' type-qual-list[opt] '*' ']'
+///         direct-declarator '(' parameter-type-list ')'
+///         direct-declarator '(' identifier-list[opt] ')'
+/// [GNU]   direct-declarator '(' parameter-forward-declarations
+///                    parameter-type-list[opt] ')'
+/// [C++]   direct-declarator '(' parameter-declaration-clause ')'
+///                    cv-qualifier-seq[opt] exception-specification[opt]
+/// [C++]   declarator-id
+///
+///       declarator-id: [C++ 8]
+///         id-expression
+///         '::'[opt] nested-name-specifier[opt] type-name
+///
+///       id-expression: [C++ 5.1]
+///         unqualified-id
+///         qualified-id
+///
+///       unqualified-id: [C++ 5.1]
+///         identifier
+///         operator-function-id
+///         conversion-function-id
+///          '~' class-name
+///         template-id
+///
+void Parser::ParseDirectDeclarator(Declarator &D) {
+  DeclaratorScopeObj DeclScopeObj(*this, D.getCXXScopeSpec());
+
+  if (getLang().CPlusPlus && D.mayHaveIdentifier()) {
+    // ParseDeclaratorInternal might already have parsed the scope.
+    if (D.getCXXScopeSpec().isEmpty()) {
+      ParseOptionalCXXScopeSpecifier(D.getCXXScopeSpec(), /*ObjectType=*/0,
+                                     true);
+    }
+
+    if (D.getCXXScopeSpec().isValid()) {
+      if (Actions.ShouldEnterDeclaratorScope(CurScope, D.getCXXScopeSpec()))
+        // Change the declaration context for name lookup, until this function
+        // is exited (and the declarator has been parsed).
+        DeclScopeObj.EnterDeclaratorScope();
+    }
+
+    if (Tok.is(tok::identifier) || Tok.is(tok::kw_operator) ||
+        Tok.is(tok::annot_template_id) || Tok.is(tok::tilde)) {
+      // We found something that indicates the start of an unqualified-id.
+      // Parse that unqualified-id.
+      bool AllowConstructorName;
+      if (D.getDeclSpec().hasTypeSpecifier())
+        AllowConstructorName = false;
+      else if (D.getCXXScopeSpec().isSet())
+        AllowConstructorName =
+          (D.getContext() == Declarator::FileContext ||
+           (D.getContext() == Declarator::MemberContext &&
+            D.getDeclSpec().isFriendSpecified()));
+      else
+        AllowConstructorName = (D.getContext() == Declarator::MemberContext);
+
+      if (ParseUnqualifiedId(D.getCXXScopeSpec(), 
+                             /*EnteringContext=*/true, 
+                             /*AllowDestructorName=*/true, 
+                             AllowConstructorName,
+                             /*ObjectType=*/0,
+                             D.getName()) ||
+          // Once we're past the identifier, if the scope was bad, mark the
+          // whole declarator bad.
+          D.getCXXScopeSpec().isInvalid()) {
+        D.SetIdentifier(0, Tok.getLocation());
+        D.setInvalidType(true);
+      } else {
+        // Parsed the unqualified-id; update range information and move along.
+        if (D.getSourceRange().getBegin().isInvalid())
+          D.SetRangeBegin(D.getName().getSourceRange().getBegin());
+        D.SetRangeEnd(D.getName().getSourceRange().getEnd());
+      }
+      goto PastIdentifier;
+    }
+  } else if (Tok.is(tok::identifier) && D.mayHaveIdentifier()) {
+    assert(!getLang().CPlusPlus &&
+           "There's a C++-specific check for tok::identifier above");
+    assert(Tok.getIdentifierInfo() && "Not an identifier?");
+    D.SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
+    ConsumeToken();
+    goto PastIdentifier;
+  }
+    
+  if (Tok.is(tok::l_paren)) {
+    // direct-declarator: '(' declarator ')'
+    // direct-declarator: '(' attributes declarator ')'
+    // Example: 'char (*X)'   or 'int (*XX)(void)'
+    ParseParenDeclarator(D);
+
+    // If the declarator was parenthesized, we entered the declarator
+    // scope when parsing the parenthesized declarator, then exited
+    // the scope already. Re-enter the scope, if we need to.
+    if (D.getCXXScopeSpec().isSet()) {
+      if (Actions.ShouldEnterDeclaratorScope(CurScope, D.getCXXScopeSpec()))
+        // Change the declaration context for name lookup, until this function
+        // is exited (and the declarator has been parsed).
+        DeclScopeObj.EnterDeclaratorScope();
+    }
+  } else if (D.mayOmitIdentifier()) {
+    // This could be something simple like "int" (in which case the declarator
+    // portion is empty), if an abstract-declarator is allowed.
+    D.SetIdentifier(0, Tok.getLocation());
+  } else {
+    if (D.getContext() == Declarator::MemberContext)
+      Diag(Tok, diag::err_expected_member_name_or_semi)
+        << D.getDeclSpec().getSourceRange();
+    else if (getLang().CPlusPlus)
+      Diag(Tok, diag::err_expected_unqualified_id) << getLang().CPlusPlus;
+    else
+      Diag(Tok, diag::err_expected_ident_lparen);
+    D.SetIdentifier(0, Tok.getLocation());
+    D.setInvalidType(true);
+  }
+
+ PastIdentifier:
+  assert(D.isPastIdentifier() &&
+         "Haven't past the location of the identifier yet?");
+
+  // Don't parse attributes unless we have an identifier.
+  if (D.getIdentifier() && getLang().CPlusPlus0x
+   && isCXX0XAttributeSpecifier(true)) {
+    SourceLocation AttrEndLoc;
+    CXX0XAttributeList Attr = ParseCXX0XAttributes();
+    D.AddAttributes(Attr.AttrList, AttrEndLoc);
+  }
+
+  while (1) {
+    if (Tok.is(tok::l_paren)) {
+      // The paren may be part of a C++ direct initializer, eg. "int x(1);".
+      // In such a case, check if we actually have a function declarator; if it
+      // is not, the declarator has been fully parsed.
+      if (getLang().CPlusPlus && D.mayBeFollowedByCXXDirectInit()) {
+        // When not in file scope, warn for ambiguous function declarators, just
+        // in case the author intended it as a variable definition.
+        bool warnIfAmbiguous = D.getContext() != Declarator::FileContext;
+        if (!isCXXFunctionDeclarator(warnIfAmbiguous))
+          break;
+      }
+      ParseFunctionDeclarator(ConsumeParen(), D);
+    } else if (Tok.is(tok::l_square)) {
+      ParseBracketDeclarator(D);
+    } else {
+      break;
+    }
+  }
+}
+
+/// ParseParenDeclarator - We parsed the declarator D up to a paren.  This is
+/// only called before the identifier, so these are most likely just grouping
+/// parens for precedence.  If we find that these are actually function
+/// parameter parens in an abstract-declarator, we call ParseFunctionDeclarator.
+///
+///       direct-declarator:
+///         '(' declarator ')'
+/// [GNU]   '(' attributes declarator ')'
+///         direct-declarator '(' parameter-type-list ')'
+///         direct-declarator '(' identifier-list[opt] ')'
+/// [GNU]   direct-declarator '(' parameter-forward-declarations
+///                    parameter-type-list[opt] ')'
+///
+void Parser::ParseParenDeclarator(Declarator &D) {
+  SourceLocation StartLoc = ConsumeParen();
+  assert(!D.isPastIdentifier() && "Should be called before passing identifier");
+
+  // Eat any attributes before we look at whether this is a grouping or function
+  // declarator paren.  If this is a grouping paren, the attribute applies to
+  // the type being built up, for example:
+  //     int (__attribute__(()) *x)(long y)
+  // If this ends up not being a grouping paren, the attribute applies to the
+  // first argument, for example:
+  //     int (__attribute__(()) int x)
+  // In either case, we need to eat any attributes to be able to determine what
+  // sort of paren this is.
+  //
+  llvm::OwningPtr<AttributeList> AttrList;
+  bool RequiresArg = false;
+  if (Tok.is(tok::kw___attribute)) {
+    AttrList.reset(ParseGNUAttributes());
+
+    // We require that the argument list (if this is a non-grouping paren) be
+    // present even if the attribute list was empty.
+    RequiresArg = true;
+  }
+  // Eat any Microsoft extensions.
+  if  (Tok.is(tok::kw___cdecl) || Tok.is(tok::kw___stdcall) ||
+       Tok.is(tok::kw___fastcall) || Tok.is(tok::kw___w64) ||
+       Tok.is(tok::kw___ptr64)) {
+    AttrList.reset(ParseMicrosoftTypeAttributes(AttrList.take()));
+  }
+
+  // If we haven't past the identifier yet (or where the identifier would be
+  // stored, if this is an abstract declarator), then this is probably just
+  // grouping parens. However, if this could be an abstract-declarator, then
+  // this could also be the start of function arguments (consider 'void()').
+  bool isGrouping;
+
+  if (!D.mayOmitIdentifier()) {
+    // If this can't be an abstract-declarator, this *must* be a grouping
+    // paren, because we haven't seen the identifier yet.
+    isGrouping = true;
+  } else if (Tok.is(tok::r_paren) ||           // 'int()' is a function.
+             (getLang().CPlusPlus && Tok.is(tok::ellipsis)) || // C++ int(...)
+             isDeclarationSpecifier()) {       // 'int(int)' is a function.
+    // This handles C99 6.7.5.3p11: in "typedef int X; void foo(X)", X is
+    // considered to be a type, not a K&R identifier-list.
+    isGrouping = false;
+  } else {
+    // Otherwise, this is a grouping paren, e.g. 'int (*X)' or 'int(X)'.
+    isGrouping = true;
+  }
+
+  // If this is a grouping paren, handle:
+  // direct-declarator: '(' declarator ')'
+  // direct-declarator: '(' attributes declarator ')'
+  if (isGrouping) {
+    bool hadGroupingParens = D.hasGroupingParens();
+    D.setGroupingParens(true);
+    if (AttrList)
+      D.AddAttributes(AttrList.take(), SourceLocation());
+
+    ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
+    // Match the ')'.
+    SourceLocation Loc = MatchRHSPunctuation(tok::r_paren, StartLoc);
+
+    D.setGroupingParens(hadGroupingParens);
+    D.SetRangeEnd(Loc);
+    return;
+  }
+
+  // Okay, if this wasn't a grouping paren, it must be the start of a function
+  // argument list.  Recognize that this declarator will never have an
+  // identifier (and remember where it would have been), then call into
+  // ParseFunctionDeclarator to handle of argument list.
+  D.SetIdentifier(0, Tok.getLocation());
+
+  ParseFunctionDeclarator(StartLoc, D, AttrList.take(), RequiresArg);
+}
+
+/// ParseFunctionDeclarator - We are after the identifier and have parsed the
+/// declarator D up to a paren, which indicates that we are parsing function
+/// arguments.
+///
+/// If AttrList is non-null, then the caller parsed those arguments immediately
+/// after the open paren - they should be considered to be the first argument of
+/// a parameter.  If RequiresArg is true, then the first argument of the
+/// function is required to be present and required to not be an identifier
+/// list.
+///
+/// This method also handles this portion of the grammar:
+///       parameter-type-list: [C99 6.7.5]
+///         parameter-list
+///         parameter-list ',' '...'
+/// [C++]   parameter-list '...'
+///
+///       parameter-list: [C99 6.7.5]
+///         parameter-declaration
+///         parameter-list ',' parameter-declaration
+///
+///       parameter-declaration: [C99 6.7.5]
+///         declaration-specifiers declarator
+/// [C++]   declaration-specifiers declarator '=' assignment-expression
+/// [GNU]   declaration-specifiers declarator attributes
+///         declaration-specifiers abstract-declarator[opt]
+/// [C++]   declaration-specifiers abstract-declarator[opt]
+///           '=' assignment-expression
+/// [GNU]   declaration-specifiers abstract-declarator[opt] attributes
+///
+/// For C++, after the parameter-list, it also parses "cv-qualifier-seq[opt]"
+/// and "exception-specification[opt]".
+///
+void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
+                                     AttributeList *AttrList,
+                                     bool RequiresArg) {
+  // lparen is already consumed!
+  assert(D.isPastIdentifier() && "Should not call before identifier!");
+
+  // This parameter list may be empty.
+  if (Tok.is(tok::r_paren)) {
+    if (RequiresArg) {
+      Diag(Tok, diag::err_argument_required_after_attribute);
+      delete AttrList;
+    }
+
+    SourceLocation RParenLoc = ConsumeParen();  // Eat the closing ')'.
+    SourceLocation EndLoc = RParenLoc;
+
+    // cv-qualifier-seq[opt].
+    DeclSpec DS;
+    bool hasExceptionSpec = false;
+    SourceLocation ThrowLoc;
+    bool hasAnyExceptionSpec = false;
+    llvm::SmallVector<TypeTy*, 2> Exceptions;
+    llvm::SmallVector<SourceRange, 2> ExceptionRanges;
+    if (getLang().CPlusPlus) {
+      ParseTypeQualifierListOpt(DS, false /*no attributes*/);
+      if (!DS.getSourceRange().getEnd().isInvalid())
+        EndLoc = DS.getSourceRange().getEnd();
+
+      // Parse exception-specification[opt].
+      if (Tok.is(tok::kw_throw)) {
+        hasExceptionSpec = true;
+        ThrowLoc = Tok.getLocation();
+        ParseExceptionSpecification(EndLoc, Exceptions, ExceptionRanges,
+                                    hasAnyExceptionSpec);
+        assert(Exceptions.size() == ExceptionRanges.size() &&
+               "Produced different number of exception types and ranges.");
+      }
+    }
+
+    // Remember that we parsed a function type, and remember the attributes.
+    // int() -> no prototype, no '...'.
+    D.AddTypeInfo(DeclaratorChunk::getFunction(/*prototype*/getLang().CPlusPlus,
+                                               /*variadic*/ false,
+                                               SourceLocation(),
+                                               /*arglist*/ 0, 0,
+                                               DS.getTypeQualifiers(),
+                                               hasExceptionSpec, ThrowLoc,
+                                               hasAnyExceptionSpec,
+                                               Exceptions.data(),
+                                               ExceptionRanges.data(),
+                                               Exceptions.size(),
+                                               LParenLoc, RParenLoc, D),
+                  EndLoc);
+    return;
+  }
+
+  // Alternatively, this parameter list may be an identifier list form for a
+  // K&R-style function:  void foo(a,b,c)
+  if (!getLang().CPlusPlus && Tok.is(tok::identifier)
+      && !TryAltiVecVectorToken()) {
+    if (TryAnnotateTypeOrScopeToken() || !Tok.is(tok::annot_typename)) {
+      // K&R identifier lists can't have typedefs as identifiers, per
+      // C99 6.7.5.3p11.
+      if (RequiresArg) {
+        Diag(Tok, diag::err_argument_required_after_attribute);
+        delete AttrList;
+      }
+      // Identifier list.  Note that '(' identifier-list ')' is only allowed for
+      // normal declarators, not for abstract-declarators.
+      return ParseFunctionDeclaratorIdentifierList(LParenLoc, D);
+    }
+  }
+
+  // Finally, a normal, non-empty parameter type list.
+
+  // Build up an array of information about the parsed arguments.
+  llvm::SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo;
+
+  // Enter function-declaration scope, limiting any declarators to the
+  // function prototype scope, including parameter declarators.
+  ParseScope PrototypeScope(this,
+                            Scope::FunctionPrototypeScope|Scope::DeclScope);
+
+  bool IsVariadic = false;
+  SourceLocation EllipsisLoc;
+  while (1) {
+    if (Tok.is(tok::ellipsis)) {
+      IsVariadic = true;
+      EllipsisLoc = ConsumeToken();     // Consume the ellipsis.
+      break;
+    }
+
+    SourceLocation DSStart = Tok.getLocation();
+
+    // Parse the declaration-specifiers.
+    // Just use the ParsingDeclaration "scope" of the declarator.
+    DeclSpec DS;
+
+    // If the caller parsed attributes for the first argument, add them now.
+    if (AttrList) {
+      DS.AddAttributes(AttrList);
+      AttrList = 0;  // Only apply the attributes to the first parameter.
+    }
+    ParseDeclarationSpecifiers(DS);
+
+    // Parse the declarator.  This is "PrototypeContext", because we must
+    // accept either 'declarator' or 'abstract-declarator' here.
+    Declarator ParmDecl(DS, Declarator::PrototypeContext);
+    ParseDeclarator(ParmDecl);
+
+    // Parse GNU attributes, if present.
+    if (Tok.is(tok::kw___attribute)) {
+      SourceLocation Loc;
+      AttributeList *AttrList = ParseGNUAttributes(&Loc);
+      ParmDecl.AddAttributes(AttrList, Loc);
+    }
+
+    // Remember this parsed parameter in ParamInfo.
+    IdentifierInfo *ParmII = ParmDecl.getIdentifier();
+
+    // DefArgToks is used when the parsing of default arguments needs
+    // to be delayed.
+    CachedTokens *DefArgToks = 0;
+
+    // If no parameter was specified, verify that *something* was specified,
+    // otherwise we have a missing type and identifier.
+    if (DS.isEmpty() && ParmDecl.getIdentifier() == 0 &&
+        ParmDecl.getNumTypeObjects() == 0) {
+      // Completely missing, emit error.
+      Diag(DSStart, diag::err_missing_param);
+    } else {
+      // Otherwise, we have something.  Add it and let semantic analysis try
+      // to grok it and add the result to the ParamInfo we are building.
+
+      // Inform the actions module about the parameter declarator, so it gets
+      // added to the current scope.
+      DeclPtrTy Param = Actions.ActOnParamDeclarator(CurScope, ParmDecl);
+
+      // Parse the default argument, if any. We parse the default
+      // arguments in all dialects; the semantic analysis in
+      // ActOnParamDefaultArgument will reject the default argument in
+      // C.
+      if (Tok.is(tok::equal)) {
+        SourceLocation EqualLoc = Tok.getLocation();
+
+        // Parse the default argument
+        if (D.getContext() == Declarator::MemberContext) {
+          // If we're inside a class definition, cache the tokens
+          // corresponding to the default argument. We'll actually parse
+          // them when we see the end of the class definition.
+          // FIXME: Templates will require something similar.
+          // FIXME: Can we use a smart pointer for Toks?
+          DefArgToks = new CachedTokens;
+
+          if (!ConsumeAndStoreUntil(tok::comma, tok::r_paren, *DefArgToks,
+                                    /*StopAtSemi=*/true,
+                                    /*ConsumeFinalToken=*/false)) {
+            delete DefArgToks;
+            DefArgToks = 0;
+            Actions.ActOnParamDefaultArgumentError(Param);
+          } else
+            Actions.ActOnParamUnparsedDefaultArgument(Param, EqualLoc,
+                                                (*DefArgToks)[1].getLocation());
+        } else {
+          // Consume the '='.
+          ConsumeToken();
+
+          OwningExprResult DefArgResult(ParseAssignmentExpression());
+          if (DefArgResult.isInvalid()) {
+            Actions.ActOnParamDefaultArgumentError(Param);
+            SkipUntil(tok::comma, tok::r_paren, true, true);
+          } else {
+            // Inform the actions module about the default argument
+            Actions.ActOnParamDefaultArgument(Param, EqualLoc,
+                                              move(DefArgResult));
+          }
+        }
+      }
+
+      ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
+                                          ParmDecl.getIdentifierLoc(), Param,
+                                          DefArgToks));
+    }
+
+    // If the next token is a comma, consume it and keep reading arguments.
+    if (Tok.isNot(tok::comma)) {
+      if (Tok.is(tok::ellipsis)) {
+        IsVariadic = true;
+        EllipsisLoc = ConsumeToken();     // Consume the ellipsis.
+        
+        if (!getLang().CPlusPlus) {
+          // We have ellipsis without a preceding ',', which is ill-formed
+          // in C. Complain and provide the fix.
+          Diag(EllipsisLoc, diag::err_missing_comma_before_ellipsis)
+            << FixItHint::CreateInsertion(EllipsisLoc, ", ");
+        }
+      }
+      
+      break;
+    }
+
+    // Consume the comma.
+    ConsumeToken();
+  }
+
+  // Leave prototype scope.
+  PrototypeScope.Exit();
+
+  // If we have the closing ')', eat it.
+  SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
+  SourceLocation EndLoc = RParenLoc;
+
+  DeclSpec DS;
+  bool hasExceptionSpec = false;
+  SourceLocation ThrowLoc;
+  bool hasAnyExceptionSpec = false;
+  llvm::SmallVector<TypeTy*, 2> Exceptions;
+  llvm::SmallVector<SourceRange, 2> ExceptionRanges;
+  
+  if (getLang().CPlusPlus) {
+    // Parse cv-qualifier-seq[opt].
+    ParseTypeQualifierListOpt(DS, false /*no attributes*/);
+      if (!DS.getSourceRange().getEnd().isInvalid())
+        EndLoc = DS.getSourceRange().getEnd();
+
+    // Parse exception-specification[opt].
+    if (Tok.is(tok::kw_throw)) {
+      hasExceptionSpec = true;
+      ThrowLoc = Tok.getLocation();
+      ParseExceptionSpecification(EndLoc, Exceptions, ExceptionRanges,
+                                  hasAnyExceptionSpec);
+      assert(Exceptions.size() == ExceptionRanges.size() &&
+             "Produced different number of exception types and ranges.");
+    }
+  }
+
+  // Remember that we parsed a function type, and remember the attributes.
+  D.AddTypeInfo(DeclaratorChunk::getFunction(/*proto*/true, IsVariadic,
+                                             EllipsisLoc,
+                                             ParamInfo.data(), ParamInfo.size(),
+                                             DS.getTypeQualifiers(),
+                                             hasExceptionSpec, ThrowLoc,
+                                             hasAnyExceptionSpec,
+                                             Exceptions.data(),
+                                             ExceptionRanges.data(),
+                                             Exceptions.size(),
+                                             LParenLoc, RParenLoc, D),
+                EndLoc);
+}
+
+/// ParseFunctionDeclaratorIdentifierList - While parsing a function declarator
+/// we found a K&R-style identifier list instead of a type argument list.  The
+/// current token is known to be the first identifier in the list.
+///
+///       identifier-list: [C99 6.7.5]
+///         identifier
+///         identifier-list ',' identifier
+///
+void Parser::ParseFunctionDeclaratorIdentifierList(SourceLocation LParenLoc,
+                                                   Declarator &D) {
+  // Build up an array of information about the parsed arguments.
+  llvm::SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo;
+  llvm::SmallSet<const IdentifierInfo*, 16> ParamsSoFar;
+
+  // If there was no identifier specified for the declarator, either we are in
+  // an abstract-declarator, or we are in a parameter declarator which was found
+  // to be abstract.  In abstract-declarators, identifier lists are not valid:
+  // diagnose this.
+  if (!D.getIdentifier())
+    Diag(Tok, diag::ext_ident_list_in_param);
+
+  // Tok is known to be the first identifier in the list.  Remember this
+  // identifier in ParamInfo.
+  ParamsSoFar.insert(Tok.getIdentifierInfo());
+  ParamInfo.push_back(DeclaratorChunk::ParamInfo(Tok.getIdentifierInfo(),
+                                                 Tok.getLocation(),
+                                                 DeclPtrTy()));
+
+  ConsumeToken();  // eat the first identifier.
+
+  while (Tok.is(tok::comma)) {
+    // Eat the comma.
+    ConsumeToken();
+
+    // If this isn't an identifier, report the error and skip until ')'.
+    if (Tok.isNot(tok::identifier)) {
+      Diag(Tok, diag::err_expected_ident);
+      SkipUntil(tok::r_paren);
+      return;
+    }
+
+    IdentifierInfo *ParmII = Tok.getIdentifierInfo();
+
+    // Reject 'typedef int y; int test(x, y)', but continue parsing.
+    if (Actions.getTypeName(*ParmII, Tok.getLocation(), CurScope))
+      Diag(Tok, diag::err_unexpected_typedef_ident) << ParmII;
+
+    // Verify that the argument identifier has not already been mentioned.
+    if (!ParamsSoFar.insert(ParmII)) {
+      Diag(Tok, diag::err_param_redefinition) << ParmII;
+    } else {
+      // Remember this identifier in ParamInfo.
+      ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
+                                                     Tok.getLocation(),
+                                                     DeclPtrTy()));
+    }
+
+    // Eat the identifier.
+    ConsumeToken();
+  }
+
+  // If we have the closing ')', eat it and we're done.
+  SourceLocation RLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
+
+  // Remember that we parsed a function type, and remember the attributes.  This
+  // function type is always a K&R style function type, which is not varargs and
+  // has no prototype.
+  D.AddTypeInfo(DeclaratorChunk::getFunction(/*proto*/false, /*varargs*/false,
+                                             SourceLocation(),
+                                             &ParamInfo[0], ParamInfo.size(),
+                                             /*TypeQuals*/0,
+                                             /*exception*/false,
+                                             SourceLocation(), false, 0, 0, 0,
+                                             LParenLoc, RLoc, D),
+                RLoc);
+}
+
+/// [C90]   direct-declarator '[' constant-expression[opt] ']'
+/// [C99]   direct-declarator '[' type-qual-list[opt] assignment-expr[opt] ']'
+/// [C99]   direct-declarator '[' 'static' type-qual-list[opt] assign-expr ']'
+/// [C99]   direct-declarator '[' type-qual-list 'static' assignment-expr ']'
+/// [C99]   direct-declarator '[' type-qual-list[opt] '*' ']'
+void Parser::ParseBracketDeclarator(Declarator &D) {
+  SourceLocation StartLoc = ConsumeBracket();
+
+  // C array syntax has many features, but by-far the most common is [] and [4].
+  // This code does a fast path to handle some of the most obvious cases.
+  if (Tok.getKind() == tok::r_square) {
+    SourceLocation EndLoc = MatchRHSPunctuation(tok::r_square, StartLoc);
+    //FIXME: Use these
+    CXX0XAttributeList Attr;
+    if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier(true)) {
+      Attr = ParseCXX0XAttributes();
+    }
+    
+    // Remember that we parsed the empty array type.
+    OwningExprResult NumElements(Actions);
+    D.AddTypeInfo(DeclaratorChunk::getArray(0, false, false, 0,
+                                            StartLoc, EndLoc),
+                  EndLoc);
+    return;
+  } else if (Tok.getKind() == tok::numeric_constant &&
+             GetLookAheadToken(1).is(tok::r_square)) {
+    // [4] is very common.  Parse the numeric constant expression.
+    OwningExprResult ExprRes(Actions.ActOnNumericConstant(Tok));
+    ConsumeToken();
+
+    SourceLocation EndLoc = MatchRHSPunctuation(tok::r_square, StartLoc);
+    //FIXME: Use these
+    CXX0XAttributeList Attr;
+    if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier()) {
+      Attr = ParseCXX0XAttributes();
+    }
+
+    // If there was an error parsing the assignment-expression, recover.
+    if (ExprRes.isInvalid())
+      ExprRes.release();  // Deallocate expr, just use [].
+
+    // Remember that we parsed a array type, and remember its features.
+    D.AddTypeInfo(DeclaratorChunk::getArray(0, false, 0, ExprRes.release(),
+                                            StartLoc, EndLoc),
+                  EndLoc);
+    return;
+  }
+
+  // If valid, this location is the position where we read the 'static' keyword.
+  SourceLocation StaticLoc;
+  if (Tok.is(tok::kw_static))
+    StaticLoc = ConsumeToken();
+
+  // If there is a type-qualifier-list, read it now.
+  // Type qualifiers in an array subscript are a C99 feature.
+  DeclSpec DS;
+  ParseTypeQualifierListOpt(DS, false /*no attributes*/);
+
+  // If we haven't already read 'static', check to see if there is one after the
+  // type-qualifier-list.
+  if (!StaticLoc.isValid() && Tok.is(tok::kw_static))
+    StaticLoc = ConsumeToken();
+
+  // Handle "direct-declarator [ type-qual-list[opt] * ]".
+  bool isStar = false;
+  OwningExprResult NumElements(Actions);
+
+  // Handle the case where we have '[*]' as the array size.  However, a leading
+  // star could be the start of an expression, for example 'X[*p + 4]'.  Verify
+  // the the token after the star is a ']'.  Since stars in arrays are
+  // infrequent, use of lookahead is not costly here.
+  if (Tok.is(tok::star) && GetLookAheadToken(1).is(tok::r_square)) {
+    ConsumeToken();  // Eat the '*'.
+
+    if (StaticLoc.isValid()) {
+      Diag(StaticLoc, diag::err_unspecified_vla_size_with_static);
+      StaticLoc = SourceLocation();  // Drop the static.
+    }
+    isStar = true;
+  } else if (Tok.isNot(tok::r_square)) {
+    // Note, in C89, this production uses the constant-expr production instead
+    // of assignment-expr.  The only difference is that assignment-expr allows
+    // things like '=' and '*='.  Sema rejects these in C89 mode because they
+    // are not i-c-e's, so we don't need to distinguish between the two here.
+
+    // Parse the constant-expression or assignment-expression now (depending
+    // on dialect).
+    if (getLang().CPlusPlus)
+      NumElements = ParseConstantExpression();
+    else
+      NumElements = ParseAssignmentExpression();
+  }
+
+  // If there was an error parsing the assignment-expression, recover.
+  if (NumElements.isInvalid()) {
+    D.setInvalidType(true);
+    // If the expression was invalid, skip it.
+    SkipUntil(tok::r_square);
+    return;
+  }
+
+  SourceLocation EndLoc = MatchRHSPunctuation(tok::r_square, StartLoc);
+
+  //FIXME: Use these
+  CXX0XAttributeList Attr;
+  if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier()) {
+    Attr = ParseCXX0XAttributes();
+  }
+
+  // Remember that we parsed a array type, and remember its features.
+  D.AddTypeInfo(DeclaratorChunk::getArray(DS.getTypeQualifiers(),
+                                          StaticLoc.isValid(), isStar,
+                                          NumElements.release(),
+                                          StartLoc, EndLoc),
+                EndLoc);
+}
+
+/// [GNU]   typeof-specifier:
+///           typeof ( expressions )
+///           typeof ( type-name )
+/// [GNU/C++] typeof unary-expression
+///
+void Parser::ParseTypeofSpecifier(DeclSpec &DS) {
+  assert(Tok.is(tok::kw_typeof) && "Not a typeof specifier");
+  Token OpTok = Tok;
+  SourceLocation StartLoc = ConsumeToken();
+
+  const bool hasParens = Tok.is(tok::l_paren);
+
+  bool isCastExpr;
+  TypeTy *CastTy;
+  SourceRange CastRange;
+  OwningExprResult Operand = ParseExprAfterTypeofSizeofAlignof(OpTok,
+                                                               isCastExpr,
+                                                               CastTy,
+                                                               CastRange);
+  if (hasParens)
+    DS.setTypeofParensRange(CastRange);
+
+  if (CastRange.getEnd().isInvalid())
+    // FIXME: Not accurate, the range gets one token more than it should.
+    DS.SetRangeEnd(Tok.getLocation());
+  else
+    DS.SetRangeEnd(CastRange.getEnd());
+
+  if (isCastExpr) {
+    if (!CastTy) {
+      DS.SetTypeSpecError();
+      return;
+    }
+
+    const char *PrevSpec = 0;
+    unsigned DiagID;
+    // Check for duplicate type specifiers (e.g. "int typeof(int)").
+    if (DS.SetTypeSpecType(DeclSpec::TST_typeofType, StartLoc, PrevSpec,
+                           DiagID, CastTy))
+      Diag(StartLoc, DiagID) << PrevSpec;
+    return;
+  }
+
+  // If we get here, the operand to the typeof was an expresion.
+  if (Operand.isInvalid()) {
+    DS.SetTypeSpecError();
+    return;
+  }
+
+  const char *PrevSpec = 0;
+  unsigned DiagID;
+  // Check for duplicate type specifiers (e.g. "int typeof(int)").
+  if (DS.SetTypeSpecType(DeclSpec::TST_typeofExpr, StartLoc, PrevSpec,
+                         DiagID, Operand.release()))
+    Diag(StartLoc, DiagID) << PrevSpec;
+}
+
+
+/// TryAltiVecVectorTokenOutOfLine - Out of line body that should only be called
+/// from TryAltiVecVectorToken.
+bool Parser::TryAltiVecVectorTokenOutOfLine() {
+  Token Next = NextToken();
+  switch (Next.getKind()) {
+  default: return false;
+  case tok::kw_short:
+  case tok::kw_long:
+  case tok::kw_signed:
+  case tok::kw_unsigned:
+  case tok::kw_void:
+  case tok::kw_char:
+  case tok::kw_int:
+  case tok::kw_float:
+  case tok::kw_double:
+  case tok::kw_bool:
+  case tok::kw___pixel:
+    Tok.setKind(tok::kw___vector);
+    return true;
+  case tok::identifier:
+    if (Next.getIdentifierInfo() == Ident_pixel) {
+      Tok.setKind(tok::kw___vector);
+      return true;
+    }
+    return false;
+  }
+}
+
+bool Parser::TryAltiVecTokenOutOfLine(DeclSpec &DS, SourceLocation Loc,
+                                      const char *&PrevSpec, unsigned &DiagID,
+                                      bool &isInvalid) {
+  if (Tok.getIdentifierInfo() == Ident_vector) {
+    Token Next = NextToken();
+    switch (Next.getKind()) {
+    case tok::kw_short:
+    case tok::kw_long:
+    case tok::kw_signed:
+    case tok::kw_unsigned:
+    case tok::kw_void:
+    case tok::kw_char:
+    case tok::kw_int:
+    case tok::kw_float:
+    case tok::kw_double:
+    case tok::kw_bool:
+    case tok::kw___pixel:
+      isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID);
+      return true;
+    case tok::identifier:
+      if (Next.getIdentifierInfo() == Ident_pixel) {
+        isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID);
+        return true;
+      }
+      break;
+    default:
+      break;
+    }
+  } else if (Tok.getIdentifierInfo() == Ident_pixel &&
+             DS.isTypeAltiVecVector()) {
+    isInvalid = DS.SetTypeAltiVecPixel(true, Loc, PrevSpec, DiagID);
+    return true;
+  }
+  return false;
+}
+  
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp
new file mode 100644
index 0000000..60aee6a
--- /dev/null
+++ b/lib/Parse/ParseDeclCXX.cpp
@@ -0,0 +1,2007 @@
+//===--- ParseDeclCXX.cpp - C++ Declaration Parsing -----------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements the C++ Declaration portions of the Parser interfaces.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Basic/OperatorKinds.h"
+#include "clang/Parse/Parser.h"
+#include "clang/Parse/ParseDiagnostic.h"
+#include "clang/Parse/DeclSpec.h"
+#include "clang/Parse/Scope.h"
+#include "clang/Parse/Template.h"
+#include "RAIIObjectsForParser.h"
+using namespace clang;
+
+/// ParseNamespace - We know that the current token is a namespace keyword. This
+/// may either be a top level namespace or a block-level namespace alias.
+///
+///       namespace-definition: [C++ 7.3: basic.namespace]
+///         named-namespace-definition
+///         unnamed-namespace-definition
+///
+///       unnamed-namespace-definition:
+///         'namespace' attributes[opt] '{' namespace-body '}'
+///
+///       named-namespace-definition:
+///         original-namespace-definition
+///         extension-namespace-definition
+///
+///       original-namespace-definition:
+///         'namespace' identifier attributes[opt] '{' namespace-body '}'
+///
+///       extension-namespace-definition:
+///         'namespace' original-namespace-name '{' namespace-body '}'
+///
+///       namespace-alias-definition:  [C++ 7.3.2: namespace.alias]
+///         'namespace' identifier '=' qualified-namespace-specifier ';'
+///
+Parser::DeclPtrTy Parser::ParseNamespace(unsigned Context,
+                                         SourceLocation &DeclEnd) {
+  assert(Tok.is(tok::kw_namespace) && "Not a namespace!");
+  SourceLocation NamespaceLoc = ConsumeToken();  // eat the 'namespace'.
+
+  if (Tok.is(tok::code_completion)) {
+    Actions.CodeCompleteNamespaceDecl(CurScope);
+    ConsumeToken();
+  }
+
+  SourceLocation IdentLoc;
+  IdentifierInfo *Ident = 0;
+
+  Token attrTok;
+
+  if (Tok.is(tok::identifier)) {
+    Ident = Tok.getIdentifierInfo();
+    IdentLoc = ConsumeToken();  // eat the identifier.
+  }
+
+  // Read label attributes, if present.
+  llvm::OwningPtr<AttributeList> AttrList;
+  if (Tok.is(tok::kw___attribute)) {
+    attrTok = Tok;
+
+    // FIXME: save these somewhere.
+    AttrList.reset(ParseGNUAttributes());
+  }
+
+  if (Tok.is(tok::equal)) {
+    if (AttrList)
+      Diag(attrTok, diag::err_unexpected_namespace_attributes_alias);
+
+    return ParseNamespaceAlias(NamespaceLoc, IdentLoc, Ident, DeclEnd);
+  }
+
+  if (Tok.isNot(tok::l_brace)) {
+    Diag(Tok, Ident ? diag::err_expected_lbrace :
+         diag::err_expected_ident_lbrace);
+    return DeclPtrTy();
+  }
+
+  SourceLocation LBrace = ConsumeBrace();
+
+  // Enter a scope for the namespace.
+  ParseScope NamespaceScope(this, Scope::DeclScope);
+
+  DeclPtrTy NamespcDecl =
+    Actions.ActOnStartNamespaceDef(CurScope, IdentLoc, Ident, LBrace,
+                                   AttrList.get());
+
+  PrettyStackTraceActionsDecl CrashInfo(NamespcDecl, NamespaceLoc, Actions,
+                                        PP.getSourceManager(),
+                                        "parsing namespace");
+
+  while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
+    CXX0XAttributeList Attr;
+    if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier())
+      Attr = ParseCXX0XAttributes();
+    ParseExternalDeclaration(Attr);
+  }
+
+  // Leave the namespace scope.
+  NamespaceScope.Exit();
+
+  SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBrace);
+  Actions.ActOnFinishNamespaceDef(NamespcDecl, RBraceLoc);
+
+  DeclEnd = RBraceLoc;
+  return NamespcDecl;
+}
+
+/// ParseNamespaceAlias - Parse the part after the '=' in a namespace
+/// alias definition.
+///
+Parser::DeclPtrTy Parser::ParseNamespaceAlias(SourceLocation NamespaceLoc,
+                                              SourceLocation AliasLoc,
+                                              IdentifierInfo *Alias,
+                                              SourceLocation &DeclEnd) {
+  assert(Tok.is(tok::equal) && "Not equal token");
+
+  ConsumeToken(); // eat the '='.
+
+  if (Tok.is(tok::code_completion)) {
+    Actions.CodeCompleteNamespaceAliasDecl(CurScope);
+    ConsumeToken();
+  }
+
+  CXXScopeSpec SS;
+  // Parse (optional) nested-name-specifier.
+  ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, false);
+
+  if (SS.isInvalid() || Tok.isNot(tok::identifier)) {
+    Diag(Tok, diag::err_expected_namespace_name);
+    // Skip to end of the definition and eat the ';'.
+    SkipUntil(tok::semi);
+    return DeclPtrTy();
+  }
+
+  // Parse identifier.
+  IdentifierInfo *Ident = Tok.getIdentifierInfo();
+  SourceLocation IdentLoc = ConsumeToken();
+
+  // Eat the ';'.
+  DeclEnd = Tok.getLocation();
+  ExpectAndConsume(tok::semi, diag::err_expected_semi_after_namespace_name,
+                   "", tok::semi);
+
+  return Actions.ActOnNamespaceAliasDef(CurScope, NamespaceLoc, AliasLoc, Alias,
+                                        SS, IdentLoc, Ident);
+}
+
+/// ParseLinkage - We know that the current token is a string_literal
+/// and just before that, that extern was seen.
+///
+///       linkage-specification: [C++ 7.5p2: dcl.link]
+///         'extern' string-literal '{' declaration-seq[opt] '}'
+///         'extern' string-literal declaration
+///
+Parser::DeclPtrTy Parser::ParseLinkage(ParsingDeclSpec &DS,
+                                       unsigned Context) {
+  assert(Tok.is(tok::string_literal) && "Not a string literal!");
+  llvm::SmallString<8> LangBuffer;
+  // LangBuffer is guaranteed to be big enough.
+  bool Invalid = false;
+  llvm::StringRef Lang = PP.getSpelling(Tok, LangBuffer, &Invalid);
+  if (Invalid)
+    return DeclPtrTy();
+
+  SourceLocation Loc = ConsumeStringToken();
+
+  ParseScope LinkageScope(this, Scope::DeclScope);
+  DeclPtrTy LinkageSpec
+    = Actions.ActOnStartLinkageSpecification(CurScope,
+                                             /*FIXME: */SourceLocation(),
+                                             Loc, Lang.data(), Lang.size(),
+                                       Tok.is(tok::l_brace)? Tok.getLocation()
+                                                           : SourceLocation());
+
+  CXX0XAttributeList Attr;
+  if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier()) {
+    Attr = ParseCXX0XAttributes();
+  }
+
+  if (Tok.isNot(tok::l_brace)) {
+    ParseDeclarationOrFunctionDefinition(DS, Attr.AttrList);
+    return Actions.ActOnFinishLinkageSpecification(CurScope, LinkageSpec,
+                                                   SourceLocation());
+  }
+
+  DS.abort();
+
+  if (Attr.HasAttr)
+    Diag(Attr.Range.getBegin(), diag::err_attributes_not_allowed)
+      << Attr.Range;
+
+  SourceLocation LBrace = ConsumeBrace();
+  while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
+    CXX0XAttributeList Attr;
+    if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier())
+      Attr = ParseCXX0XAttributes();
+    ParseExternalDeclaration(Attr);
+  }
+
+  SourceLocation RBrace = MatchRHSPunctuation(tok::r_brace, LBrace);
+  return Actions.ActOnFinishLinkageSpecification(CurScope, LinkageSpec, RBrace);
+}
+
+/// ParseUsingDirectiveOrDeclaration - Parse C++ using using-declaration or
+/// using-directive. Assumes that current token is 'using'.
+Parser::DeclPtrTy Parser::ParseUsingDirectiveOrDeclaration(unsigned Context,
+                                                     SourceLocation &DeclEnd,
+                                                     CXX0XAttributeList Attr) {
+  assert(Tok.is(tok::kw_using) && "Not using token");
+
+  // Eat 'using'.
+  SourceLocation UsingLoc = ConsumeToken();
+
+  if (Tok.is(tok::code_completion)) {
+    Actions.CodeCompleteUsing(CurScope);
+    ConsumeToken();
+  }
+
+  if (Tok.is(tok::kw_namespace))
+    // Next token after 'using' is 'namespace' so it must be using-directive
+    return ParseUsingDirective(Context, UsingLoc, DeclEnd, Attr.AttrList);
+
+  if (Attr.HasAttr)
+    Diag(Attr.Range.getBegin(), diag::err_attributes_not_allowed)
+      << Attr.Range;
+
+  // Otherwise, it must be using-declaration.
+  // Ignore illegal attributes (the caller should already have issued an error.
+  return ParseUsingDeclaration(Context, UsingLoc, DeclEnd);
+}
+
+/// ParseUsingDirective - Parse C++ using-directive, assumes
+/// that current token is 'namespace' and 'using' was already parsed.
+///
+///       using-directive: [C++ 7.3.p4: namespace.udir]
+///        'using' 'namespace' ::[opt] nested-name-specifier[opt]
+///                 namespace-name ;
+/// [GNU] using-directive:
+///        'using' 'namespace' ::[opt] nested-name-specifier[opt]
+///                 namespace-name attributes[opt] ;
+///
+Parser::DeclPtrTy Parser::ParseUsingDirective(unsigned Context,
+                                              SourceLocation UsingLoc,
+                                              SourceLocation &DeclEnd,
+                                              AttributeList *Attr) {
+  assert(Tok.is(tok::kw_namespace) && "Not 'namespace' token");
+
+  // Eat 'namespace'.
+  SourceLocation NamespcLoc = ConsumeToken();
+
+  if (Tok.is(tok::code_completion)) {
+    Actions.CodeCompleteUsingDirective(CurScope);
+    ConsumeToken();
+  }
+
+  CXXScopeSpec SS;
+  // Parse (optional) nested-name-specifier.
+  ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, false);
+
+  IdentifierInfo *NamespcName = 0;
+  SourceLocation IdentLoc = SourceLocation();
+
+  // Parse namespace-name.
+  if (SS.isInvalid() || Tok.isNot(tok::identifier)) {
+    Diag(Tok, diag::err_expected_namespace_name);
+    // If there was invalid namespace name, skip to end of decl, and eat ';'.
+    SkipUntil(tok::semi);
+    // FIXME: Are there cases, when we would like to call ActOnUsingDirective?
+    return DeclPtrTy();
+  }
+
+  // Parse identifier.
+  NamespcName = Tok.getIdentifierInfo();
+  IdentLoc = ConsumeToken();
+
+  // Parse (optional) attributes (most likely GNU strong-using extension).
+  bool GNUAttr = false;
+  if (Tok.is(tok::kw___attribute)) {
+    GNUAttr = true;
+    Attr = addAttributeLists(Attr, ParseGNUAttributes());
+  }
+
+  // Eat ';'.
+  DeclEnd = Tok.getLocation();
+  ExpectAndConsume(tok::semi,
+                   GNUAttr ? diag::err_expected_semi_after_attribute_list :
+                   diag::err_expected_semi_after_namespace_name, "", tok::semi);
+
+  return Actions.ActOnUsingDirective(CurScope, UsingLoc, NamespcLoc, SS,
+                                      IdentLoc, NamespcName, Attr);
+}
+
+/// ParseUsingDeclaration - Parse C++ using-declaration. Assumes that
+/// 'using' was already seen.
+///
+///     using-declaration: [C++ 7.3.p3: namespace.udecl]
+///       'using' 'typename'[opt] ::[opt] nested-name-specifier
+///               unqualified-id
+///       'using' :: unqualified-id
+///
+Parser::DeclPtrTy Parser::ParseUsingDeclaration(unsigned Context,
+                                                SourceLocation UsingLoc,
+                                                SourceLocation &DeclEnd,
+                                                AccessSpecifier AS) {
+  CXXScopeSpec SS;
+  SourceLocation TypenameLoc;
+  bool IsTypeName;
+
+  // Ignore optional 'typename'.
+  // FIXME: This is wrong; we should parse this as a typename-specifier.
+  if (Tok.is(tok::kw_typename)) {
+    TypenameLoc = Tok.getLocation();
+    ConsumeToken();
+    IsTypeName = true;
+  }
+  else
+    IsTypeName = false;
+
+  // Parse nested-name-specifier.
+  ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, false);
+
+  // Check nested-name specifier.
+  if (SS.isInvalid()) {
+    SkipUntil(tok::semi);
+    return DeclPtrTy();
+  }
+
+  // Parse the unqualified-id. We allow parsing of both constructor and
+  // destructor names and allow the action module to diagnose any semantic
+  // errors.
+  UnqualifiedId Name;
+  if (ParseUnqualifiedId(SS,
+                         /*EnteringContext=*/false,
+                         /*AllowDestructorName=*/true,
+                         /*AllowConstructorName=*/true,
+                         /*ObjectType=*/0,
+                         Name)) {
+    SkipUntil(tok::semi);
+    return DeclPtrTy();
+  }
+
+  // Parse (optional) attributes (most likely GNU strong-using extension).
+  llvm::OwningPtr<AttributeList> AttrList;
+  if (Tok.is(tok::kw___attribute))
+    AttrList.reset(ParseGNUAttributes());
+
+  // Eat ';'.
+  DeclEnd = Tok.getLocation();
+  ExpectAndConsume(tok::semi, diag::err_expected_semi_after,
+                   AttrList ? "attributes list" : "using declaration",
+                   tok::semi);
+
+  return Actions.ActOnUsingDeclaration(CurScope, AS, true, UsingLoc, SS, Name,
+                                       AttrList.get(), IsTypeName, TypenameLoc);
+}
+
+/// ParseStaticAssertDeclaration - Parse C++0x static_assert-declaratoion.
+///
+///      static_assert-declaration:
+///        static_assert ( constant-expression  ,  string-literal  ) ;
+///
+Parser::DeclPtrTy Parser::ParseStaticAssertDeclaration(SourceLocation &DeclEnd){
+  assert(Tok.is(tok::kw_static_assert) && "Not a static_assert declaration");
+  SourceLocation StaticAssertLoc = ConsumeToken();
+
+  if (Tok.isNot(tok::l_paren)) {
+    Diag(Tok, diag::err_expected_lparen);
+    return DeclPtrTy();
+  }
+
+  SourceLocation LParenLoc = ConsumeParen();
+
+  OwningExprResult AssertExpr(ParseConstantExpression());
+  if (AssertExpr.isInvalid()) {
+    SkipUntil(tok::semi);
+    return DeclPtrTy();
+  }
+
+  if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "", tok::semi))
+    return DeclPtrTy();
+
+  if (Tok.isNot(tok::string_literal)) {
+    Diag(Tok, diag::err_expected_string_literal);
+    SkipUntil(tok::semi);
+    return DeclPtrTy();
+  }
+
+  OwningExprResult AssertMessage(ParseStringLiteralExpression());
+  if (AssertMessage.isInvalid())
+    return DeclPtrTy();
+
+  MatchRHSPunctuation(tok::r_paren, LParenLoc);
+
+  DeclEnd = Tok.getLocation();
+  ExpectAndConsume(tok::semi, diag::err_expected_semi_after_static_assert);
+
+  return Actions.ActOnStaticAssertDeclaration(StaticAssertLoc, move(AssertExpr),
+                                              move(AssertMessage));
+}
+
+/// ParseDecltypeSpecifier - Parse a C++0x decltype specifier.
+///
+/// 'decltype' ( expression )
+///
+void Parser::ParseDecltypeSpecifier(DeclSpec &DS) {
+  assert(Tok.is(tok::kw_decltype) && "Not a decltype specifier");
+
+  SourceLocation StartLoc = ConsumeToken();
+  SourceLocation LParenLoc = Tok.getLocation();
+
+  if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
+                       "decltype")) {
+    SkipUntil(tok::r_paren);
+    return;
+  }
+
+  // Parse the expression
+
+  // C++0x [dcl.type.simple]p4:
+  //   The operand of the decltype specifier is an unevaluated operand.
+  EnterExpressionEvaluationContext Unevaluated(Actions,
+                                               Action::Unevaluated);
+  OwningExprResult Result = ParseExpression();
+  if (Result.isInvalid()) {
+    SkipUntil(tok::r_paren);
+    return;
+  }
+
+  // Match the ')'
+  SourceLocation RParenLoc;
+  if (Tok.is(tok::r_paren))
+    RParenLoc = ConsumeParen();
+  else
+    MatchRHSPunctuation(tok::r_paren, LParenLoc);
+
+  if (RParenLoc.isInvalid())
+    return;
+
+  const char *PrevSpec = 0;
+  unsigned DiagID;
+  // Check for duplicate type specifiers (e.g. "int decltype(a)").
+  if (DS.SetTypeSpecType(DeclSpec::TST_decltype, StartLoc, PrevSpec,
+                         DiagID, Result.release()))
+    Diag(StartLoc, DiagID) << PrevSpec;
+}
+
+/// ParseClassName - Parse a C++ class-name, which names a class. Note
+/// that we only check that the result names a type; semantic analysis
+/// will need to verify that the type names a class. The result is
+/// either a type or NULL, depending on whether a type name was
+/// found.
+///
+///       class-name: [C++ 9.1]
+///         identifier
+///         simple-template-id
+///
+Parser::TypeResult Parser::ParseClassName(SourceLocation &EndLocation,
+                                          CXXScopeSpec *SS) {
+  // Check whether we have a template-id that names a type.
+  if (Tok.is(tok::annot_template_id)) {
+    TemplateIdAnnotation *TemplateId
+      = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
+    if (TemplateId->Kind == TNK_Type_template ||
+        TemplateId->Kind == TNK_Dependent_template_name) {
+      AnnotateTemplateIdTokenAsType(SS);
+
+      assert(Tok.is(tok::annot_typename) && "template-id -> type failed");
+      TypeTy *Type = Tok.getAnnotationValue();
+      EndLocation = Tok.getAnnotationEndLoc();
+      ConsumeToken();
+
+      if (Type)
+        return Type;
+      return true;
+    }
+
+    // Fall through to produce an error below.
+  }
+
+  if (Tok.isNot(tok::identifier)) {
+    Diag(Tok, diag::err_expected_class_name);
+    return true;
+  }
+
+  IdentifierInfo *Id = Tok.getIdentifierInfo();
+  SourceLocation IdLoc = ConsumeToken();
+
+  if (Tok.is(tok::less)) {
+    // It looks the user intended to write a template-id here, but the
+    // template-name was wrong. Try to fix that.
+    TemplateNameKind TNK = TNK_Type_template;
+    TemplateTy Template;
+    if (!Actions.DiagnoseUnknownTemplateName(*Id, IdLoc, CurScope,
+                                             SS, Template, TNK)) {
+      Diag(IdLoc, diag::err_unknown_template_name)
+        << Id;
+    }
+
+    if (!Template)
+      return true;
+
+    // Form the template name
+    UnqualifiedId TemplateName;
+    TemplateName.setIdentifier(Id, IdLoc);
+
+    // Parse the full template-id, then turn it into a type.
+    if (AnnotateTemplateIdToken(Template, TNK, SS, TemplateName,
+                                SourceLocation(), true))
+      return true;
+    if (TNK == TNK_Dependent_template_name)
+      AnnotateTemplateIdTokenAsType(SS);
+
+    // If we didn't end up with a typename token, there's nothing more we
+    // can do.
+    if (Tok.isNot(tok::annot_typename))
+      return true;
+
+    // Retrieve the type from the annotation token, consume that token, and
+    // return.
+    EndLocation = Tok.getAnnotationEndLoc();
+    TypeTy *Type = Tok.getAnnotationValue();
+    ConsumeToken();
+    return Type;
+  }
+
+  // We have an identifier; check whether it is actually a type.
+  TypeTy *Type = Actions.getTypeName(*Id, IdLoc, CurScope, SS, true);
+  if (!Type) {
+    Diag(IdLoc, diag::err_expected_class_name);
+    return true;
+  }
+
+  // Consume the identifier.
+  EndLocation = IdLoc;
+  return Type;
+}
+
+/// ParseClassSpecifier - Parse a C++ class-specifier [C++ class] or
+/// elaborated-type-specifier [C++ dcl.type.elab]; we can't tell which
+/// until we reach the start of a definition or see a token that
+/// cannot start a definition. If SuppressDeclarations is true, we do know.
+///
+///       class-specifier: [C++ class]
+///         class-head '{' member-specification[opt] '}'
+///         class-head '{' member-specification[opt] '}' attributes[opt]
+///       class-head:
+///         class-key identifier[opt] base-clause[opt]
+///         class-key nested-name-specifier identifier base-clause[opt]
+///         class-key nested-name-specifier[opt] simple-template-id
+///                          base-clause[opt]
+/// [GNU]   class-key attributes[opt] identifier[opt] base-clause[opt]
+/// [GNU]   class-key attributes[opt] nested-name-specifier
+///                          identifier base-clause[opt]
+/// [GNU]   class-key attributes[opt] nested-name-specifier[opt]
+///                          simple-template-id base-clause[opt]
+///       class-key:
+///         'class'
+///         'struct'
+///         'union'
+///
+///       elaborated-type-specifier: [C++ dcl.type.elab]
+///         class-key ::[opt] nested-name-specifier[opt] identifier
+///         class-key ::[opt] nested-name-specifier[opt] 'template'[opt]
+///                          simple-template-id
+///
+///  Note that the C++ class-specifier and elaborated-type-specifier,
+///  together, subsume the C99 struct-or-union-specifier:
+///
+///       struct-or-union-specifier: [C99 6.7.2.1]
+///         struct-or-union identifier[opt] '{' struct-contents '}'
+///         struct-or-union identifier
+/// [GNU]   struct-or-union attributes[opt] identifier[opt] '{' struct-contents
+///                                                         '}' attributes[opt]
+/// [GNU]   struct-or-union attributes[opt] identifier
+///       struct-or-union:
+///         'struct'
+///         'union'
+void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
+                                 SourceLocation StartLoc, DeclSpec &DS,
+                                 const ParsedTemplateInfo &TemplateInfo,
+                                 AccessSpecifier AS, bool SuppressDeclarations){
+  DeclSpec::TST TagType;
+  if (TagTokKind == tok::kw_struct)
+    TagType = DeclSpec::TST_struct;
+  else if (TagTokKind == tok::kw_class)
+    TagType = DeclSpec::TST_class;
+  else {
+    assert(TagTokKind == tok::kw_union && "Not a class specifier");
+    TagType = DeclSpec::TST_union;
+  }
+
+  if (Tok.is(tok::code_completion)) {
+    // Code completion for a struct, class, or union name.
+    Actions.CodeCompleteTag(CurScope, TagType);
+    ConsumeToken();
+  }
+
+  AttributeList *AttrList = 0;
+  // If attributes exist after tag, parse them.
+  if (Tok.is(tok::kw___attribute))
+    AttrList = ParseGNUAttributes();
+
+  // If declspecs exist after tag, parse them.
+  if (Tok.is(tok::kw___declspec))
+    AttrList = ParseMicrosoftDeclSpec(AttrList);
+
+  // If C++0x attributes exist here, parse them.
+  // FIXME: Are we consistent with the ordering of parsing of different
+  // styles of attributes?
+  if (isCXX0XAttributeSpecifier())
+    AttrList = addAttributeLists(AttrList, ParseCXX0XAttributes().AttrList);
+
+  if (TagType == DeclSpec::TST_struct && Tok.is(tok::kw___is_pod)) {
+    // GNU libstdc++ 4.2 uses __is_pod as the name of a struct template, but
+    // __is_pod is a keyword in GCC >= 4.3. Therefore, when we see the
+    // token sequence "struct __is_pod", make __is_pod into a normal
+    // identifier rather than a keyword, to allow libstdc++ 4.2 to work
+    // properly.
+    Tok.getIdentifierInfo()->setTokenID(tok::identifier);
+    Tok.setKind(tok::identifier);
+  }
+
+  if (TagType == DeclSpec::TST_struct && Tok.is(tok::kw___is_empty)) {
+    // GNU libstdc++ 4.2 uses __is_empty as the name of a struct template, but
+    // __is_empty is a keyword in GCC >= 4.3. Therefore, when we see the
+    // token sequence "struct __is_empty", make __is_empty into a normal
+    // identifier rather than a keyword, to allow libstdc++ 4.2 to work
+    // properly.
+    Tok.getIdentifierInfo()->setTokenID(tok::identifier);
+    Tok.setKind(tok::identifier);
+  }
+
+  // Parse the (optional) nested-name-specifier.
+  CXXScopeSpec &SS = DS.getTypeSpecScope();
+  if (getLang().CPlusPlus) {
+    // "FOO : BAR" is not a potential typo for "FOO::BAR".
+    ColonProtectionRAIIObject X(*this);
+
+    ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, true);
+    if (SS.isSet())
+      if (Tok.isNot(tok::identifier) && Tok.isNot(tok::annot_template_id))
+        Diag(Tok, diag::err_expected_ident);
+  }
+
+  TemplateParameterLists *TemplateParams = TemplateInfo.TemplateParams;
+
+  // Parse the (optional) class name or simple-template-id.
+  IdentifierInfo *Name = 0;
+  SourceLocation NameLoc;
+  TemplateIdAnnotation *TemplateId = 0;
+  if (Tok.is(tok::identifier)) {
+    Name = Tok.getIdentifierInfo();
+    NameLoc = ConsumeToken();
+
+    if (Tok.is(tok::less)) {
+      // The name was supposed to refer to a template, but didn't.
+      // Eat the template argument list and try to continue parsing this as
+      // a class (or template thereof).
+      TemplateArgList TemplateArgs;
+      SourceLocation LAngleLoc, RAngleLoc;
+      if (ParseTemplateIdAfterTemplateName(TemplateTy(), NameLoc, &SS,
+                                           true, LAngleLoc,
+                                           TemplateArgs, RAngleLoc)) {
+        // We couldn't parse the template argument list at all, so don't
+        // try to give any location information for the list.
+        LAngleLoc = RAngleLoc = SourceLocation();
+      }
+
+      Diag(NameLoc, diag::err_explicit_spec_non_template)
+        << (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation)
+        << (TagType == DeclSpec::TST_class? 0
+            : TagType == DeclSpec::TST_struct? 1
+            : 2)
+        << Name
+        << SourceRange(LAngleLoc, RAngleLoc);
+
+      // Strip off the last template parameter list if it was empty, since
+      // we've removed its template argument list.
+      if (TemplateParams && TemplateInfo.LastParameterListWasEmpty) {
+        if (TemplateParams && TemplateParams->size() > 1) {
+          TemplateParams->pop_back();
+        } else {
+          TemplateParams = 0;
+          const_cast<ParsedTemplateInfo&>(TemplateInfo).Kind
+            = ParsedTemplateInfo::NonTemplate;
+        }
+      } else if (TemplateInfo.Kind
+                                == ParsedTemplateInfo::ExplicitInstantiation) {
+        // Pretend this is just a forward declaration.
+        TemplateParams = 0;
+        const_cast<ParsedTemplateInfo&>(TemplateInfo).Kind
+          = ParsedTemplateInfo::NonTemplate;
+        const_cast<ParsedTemplateInfo&>(TemplateInfo).TemplateLoc
+          = SourceLocation();
+        const_cast<ParsedTemplateInfo&>(TemplateInfo).ExternLoc
+          = SourceLocation();
+      }
+
+
+    }
+  } else if (Tok.is(tok::annot_template_id)) {
+    TemplateId = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
+    NameLoc = ConsumeToken();
+
+    if (TemplateId->Kind != TNK_Type_template) {
+      // The template-name in the simple-template-id refers to
+      // something other than a class template. Give an appropriate
+      // error message and skip to the ';'.
+      SourceRange Range(NameLoc);
+      if (SS.isNotEmpty())
+        Range.setBegin(SS.getBeginLoc());
+
+      Diag(TemplateId->LAngleLoc, diag::err_template_spec_syntax_non_template)
+        << Name << static_cast<int>(TemplateId->Kind) << Range;
+
+      DS.SetTypeSpecError();
+      SkipUntil(tok::semi, false, true);
+      TemplateId->Destroy();
+      return;
+    }
+  }
+
+  // There are four options here.  If we have 'struct foo;', then this
+  // is either a forward declaration or a friend declaration, which
+  // have to be treated differently.  If we have 'struct foo {...' or
+  // 'struct foo :...' then this is a definition. Otherwise we have
+  // something like 'struct foo xyz', a reference.
+  // However, in some contexts, things look like declarations but are just
+  // references, e.g.
+  // new struct s;
+  // or
+  // &T::operator struct s;
+  // For these, SuppressDeclarations is true.
+  Action::TagUseKind TUK;
+  if (SuppressDeclarations)
+    TUK = Action::TUK_Reference;
+  else if (Tok.is(tok::l_brace) || (getLang().CPlusPlus && Tok.is(tok::colon))){
+    if (DS.isFriendSpecified()) {
+      // C++ [class.friend]p2:
+      //   A class shall not be defined in a friend declaration.
+      Diag(Tok.getLocation(), diag::err_friend_decl_defines_class)
+        << SourceRange(DS.getFriendSpecLoc());
+
+      // Skip everything up to the semicolon, so that this looks like a proper
+      // friend class (or template thereof) declaration.
+      SkipUntil(tok::semi, true, true);
+      TUK = Action::TUK_Friend;
+    } else {
+      // Okay, this is a class definition.
+      TUK = Action::TUK_Definition;
+    }
+  } else if (Tok.is(tok::semi))
+    TUK = DS.isFriendSpecified() ? Action::TUK_Friend : Action::TUK_Declaration;
+  else
+    TUK = Action::TUK_Reference;
+
+  if (!Name && !TemplateId && TUK != Action::TUK_Definition) {
+    // We have a declaration or reference to an anonymous class.
+    Diag(StartLoc, diag::err_anon_type_definition)
+      << DeclSpec::getSpecifierName(TagType);
+
+    SkipUntil(tok::comma, true);
+
+    if (TemplateId)
+      TemplateId->Destroy();
+    return;
+  }
+
+  // Create the tag portion of the class or class template.
+  Action::DeclResult TagOrTempResult = true; // invalid
+  Action::TypeResult TypeResult = true; // invalid
+
+  bool Owned = false;
+  if (TemplateId) {
+    // Explicit specialization, class template partial specialization,
+    // or explicit instantiation.
+    ASTTemplateArgsPtr TemplateArgsPtr(Actions,
+                                       TemplateId->getTemplateArgs(),
+                                       TemplateId->NumArgs);
+    if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation &&
+        TUK == Action::TUK_Declaration) {
+      // This is an explicit instantiation of a class template.
+      TagOrTempResult
+        = Actions.ActOnExplicitInstantiation(CurScope,
+                                             TemplateInfo.ExternLoc,
+                                             TemplateInfo.TemplateLoc,
+                                             TagType,
+                                             StartLoc,
+                                             SS,
+                                     TemplateTy::make(TemplateId->Template),
+                                             TemplateId->TemplateNameLoc,
+                                             TemplateId->LAngleLoc,
+                                             TemplateArgsPtr,
+                                             TemplateId->RAngleLoc,
+                                             AttrList);
+
+    // Friend template-ids are treated as references unless
+    // they have template headers, in which case they're ill-formed
+    // (FIXME: "template <class T> friend class A<T>::B<int>;").
+    // We diagnose this error in ActOnClassTemplateSpecialization.
+    } else if (TUK == Action::TUK_Reference ||
+               (TUK == Action::TUK_Friend &&
+                TemplateInfo.Kind == ParsedTemplateInfo::NonTemplate)) {
+      TypeResult
+        = Actions.ActOnTemplateIdType(TemplateTy::make(TemplateId->Template),
+                                      TemplateId->TemplateNameLoc,
+                                      TemplateId->LAngleLoc,
+                                      TemplateArgsPtr,
+                                      TemplateId->RAngleLoc);
+
+      TypeResult = Actions.ActOnTagTemplateIdType(TypeResult, TUK,
+                                                  TagType, StartLoc);
+    } else {
+      // This is an explicit specialization or a class template
+      // partial specialization.
+      TemplateParameterLists FakedParamLists;
+
+      if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) {
+        // This looks like an explicit instantiation, because we have
+        // something like
+        //
+        //   template class Foo<X>
+        //
+        // but it actually has a definition. Most likely, this was
+        // meant to be an explicit specialization, but the user forgot
+        // the '<>' after 'template'.
+        assert(TUK == Action::TUK_Definition && "Expected a definition here");
+
+        SourceLocation LAngleLoc
+          = PP.getLocForEndOfToken(TemplateInfo.TemplateLoc);
+        Diag(TemplateId->TemplateNameLoc,
+             diag::err_explicit_instantiation_with_definition)
+          << SourceRange(TemplateInfo.TemplateLoc)
+          << FixItHint::CreateInsertion(LAngleLoc, "<>");
+
+        // Create a fake template parameter list that contains only
+        // "template<>", so that we treat this construct as a class
+        // template specialization.
+        FakedParamLists.push_back(
+          Actions.ActOnTemplateParameterList(0, SourceLocation(),
+                                             TemplateInfo.TemplateLoc,
+                                             LAngleLoc,
+                                             0, 0,
+                                             LAngleLoc));
+        TemplateParams = &FakedParamLists;
+      }
+
+      // Build the class template specialization.
+      TagOrTempResult
+        = Actions.ActOnClassTemplateSpecialization(CurScope, TagType, TUK,
+                       StartLoc, SS,
+                       TemplateTy::make(TemplateId->Template),
+                       TemplateId->TemplateNameLoc,
+                       TemplateId->LAngleLoc,
+                       TemplateArgsPtr,
+                       TemplateId->RAngleLoc,
+                       AttrList,
+                       Action::MultiTemplateParamsArg(Actions,
+                                    TemplateParams? &(*TemplateParams)[0] : 0,
+                                 TemplateParams? TemplateParams->size() : 0));
+    }
+    TemplateId->Destroy();
+  } else if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation &&
+             TUK == Action::TUK_Declaration) {
+    // Explicit instantiation of a member of a class template
+    // specialization, e.g.,
+    //
+    //   template struct Outer<int>::Inner;
+    //
+    TagOrTempResult
+      = Actions.ActOnExplicitInstantiation(CurScope,
+                                           TemplateInfo.ExternLoc,
+                                           TemplateInfo.TemplateLoc,
+                                           TagType, StartLoc, SS, Name,
+                                           NameLoc, AttrList);
+  } else {
+    if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation &&
+        TUK == Action::TUK_Definition) {
+      // FIXME: Diagnose this particular error.
+    }
+
+    bool IsDependent = false;
+
+    // Declaration or definition of a class type
+    TagOrTempResult = Actions.ActOnTag(CurScope, TagType, TUK, StartLoc, SS,
+                                       Name, NameLoc, AttrList, AS,
+                                  Action::MultiTemplateParamsArg(Actions,
+                                    TemplateParams? &(*TemplateParams)[0] : 0,
+                                    TemplateParams? TemplateParams->size() : 0),
+                                       Owned, IsDependent);
+
+    // If ActOnTag said the type was dependent, try again with the
+    // less common call.
+    if (IsDependent)
+      TypeResult = Actions.ActOnDependentTag(CurScope, TagType, TUK,
+                                             SS, Name, StartLoc, NameLoc);
+  }
+
+  // If there is a body, parse it and inform the actions module.
+  if (TUK == Action::TUK_Definition) {
+    assert(Tok.is(tok::l_brace) ||
+           (getLang().CPlusPlus && Tok.is(tok::colon)));
+    if (getLang().CPlusPlus)
+      ParseCXXMemberSpecification(StartLoc, TagType, TagOrTempResult.get());
+    else
+      ParseStructUnionBody(StartLoc, TagType, TagOrTempResult.get());
+  }
+
+  void *Result;
+  if (!TypeResult.isInvalid()) {
+    TagType = DeclSpec::TST_typename;
+    Result = TypeResult.get();
+    Owned = false;
+  } else if (!TagOrTempResult.isInvalid()) {
+    Result = TagOrTempResult.get().getAs<void>();
+  } else {
+    DS.SetTypeSpecError();
+    return;
+  }
+
+  const char *PrevSpec = 0;
+  unsigned DiagID;
+
+  // FIXME: The DeclSpec should keep the locations of both the keyword and the
+  // name (if there is one).
+  SourceLocation TSTLoc = NameLoc.isValid()? NameLoc : StartLoc;
+
+  if (DS.SetTypeSpecType(TagType, TSTLoc, PrevSpec, DiagID,
+                         Result, Owned))
+    Diag(StartLoc, DiagID) << PrevSpec;
+
+  // At this point, we've successfully parsed a class-specifier in 'definition'
+  // form (e.g. "struct foo { int x; }".  While we could just return here, we're
+  // going to look at what comes after it to improve error recovery.  If an
+  // impossible token occurs next, we assume that the programmer forgot a ; at
+  // the end of the declaration and recover that way.
+  //
+  // This switch enumerates the valid "follow" set for definition.
+  if (TUK == Action::TUK_Definition) {
+    bool ExpectedSemi = true;
+    switch (Tok.getKind()) {
+    default: break;
+    case tok::semi:               // struct foo {...} ;
+    case tok::star:               // struct foo {...} *         P;
+    case tok::amp:                // struct foo {...} &         R = ...
+    case tok::identifier:         // struct foo {...} V         ;
+    case tok::r_paren:            //(struct foo {...} )         {4}
+    case tok::annot_cxxscope:     // struct foo {...} a::       b;
+    case tok::annot_typename:     // struct foo {...} a         ::b;
+    case tok::annot_template_id:  // struct foo {...} a<int>    ::b;
+    case tok::l_paren:            // struct foo {...} (         x);
+    case tok::comma:              // __builtin_offsetof(struct foo{...} ,
+      ExpectedSemi = false;
+      break;
+    // Type qualifiers
+    case tok::kw_const:           // struct foo {...} const     x;
+    case tok::kw_volatile:        // struct foo {...} volatile  x;
+    case tok::kw_restrict:        // struct foo {...} restrict  x;
+    case tok::kw_inline:          // struct foo {...} inline    foo() {};
+    // Storage-class specifiers
+    case tok::kw_static:          // struct foo {...} static    x;
+    case tok::kw_extern:          // struct foo {...} extern    x;
+    case tok::kw_typedef:         // struct foo {...} typedef   x;
+    case tok::kw_register:        // struct foo {...} register  x;
+    case tok::kw_auto:            // struct foo {...} auto      x;
+      // As shown above, type qualifiers and storage class specifiers absolutely
+      // can occur after class specifiers according to the grammar.  However,
+      // almost noone actually writes code like this.  If we see one of these,
+      // it is much more likely that someone missed a semi colon and the
+      // type/storage class specifier we're seeing is part of the *next*
+      // intended declaration, as in:
+      //
+      //   struct foo { ... }
+      //   typedef int X;
+      //
+      // We'd really like to emit a missing semicolon error instead of emitting
+      // an error on the 'int' saying that you can't have two type specifiers in
+      // the same declaration of X.  Because of this, we look ahead past this
+      // token to see if it's a type specifier.  If so, we know the code is
+      // otherwise invalid, so we can produce the expected semi error.
+      if (!isKnownToBeTypeSpecifier(NextToken()))
+        ExpectedSemi = false;
+      break;
+
+    case tok::r_brace:  // struct bar { struct foo {...} }
+      // Missing ';' at end of struct is accepted as an extension in C mode.
+      if (!getLang().CPlusPlus)
+        ExpectedSemi = false;
+      break;
+    }
+
+    if (ExpectedSemi) {
+      ExpectAndConsume(tok::semi, diag::err_expected_semi_after_tagdecl,
+                       TagType == DeclSpec::TST_class ? "class"
+                       : TagType == DeclSpec::TST_struct? "struct" : "union");
+      // Push this token back into the preprocessor and change our current token
+      // to ';' so that the rest of the code recovers as though there were an
+      // ';' after the definition.
+      PP.EnterToken(Tok);
+      Tok.setKind(tok::semi);
+    }
+  }
+}
+
+/// ParseBaseClause - Parse the base-clause of a C++ class [C++ class.derived].
+///
+///       base-clause : [C++ class.derived]
+///         ':' base-specifier-list
+///       base-specifier-list:
+///         base-specifier '...'[opt]
+///         base-specifier-list ',' base-specifier '...'[opt]
+void Parser::ParseBaseClause(DeclPtrTy ClassDecl) {
+  assert(Tok.is(tok::colon) && "Not a base clause");
+  ConsumeToken();
+
+  // Build up an array of parsed base specifiers.
+  llvm::SmallVector<BaseTy *, 8> BaseInfo;
+
+  while (true) {
+    // Parse a base-specifier.
+    BaseResult Result = ParseBaseSpecifier(ClassDecl);
+    if (Result.isInvalid()) {
+      // Skip the rest of this base specifier, up until the comma or
+      // opening brace.
+      SkipUntil(tok::comma, tok::l_brace, true, true);
+    } else {
+      // Add this to our array of base specifiers.
+      BaseInfo.push_back(Result.get());
+    }
+
+    // If the next token is a comma, consume it and keep reading
+    // base-specifiers.
+    if (Tok.isNot(tok::comma)) break;
+
+    // Consume the comma.
+    ConsumeToken();
+  }
+
+  // Attach the base specifiers
+  Actions.ActOnBaseSpecifiers(ClassDecl, BaseInfo.data(), BaseInfo.size());
+}
+
+/// ParseBaseSpecifier - Parse a C++ base-specifier. A base-specifier is
+/// one entry in the base class list of a class specifier, for example:
+///    class foo : public bar, virtual private baz {
+/// 'public bar' and 'virtual private baz' are each base-specifiers.
+///
+///       base-specifier: [C++ class.derived]
+///         ::[opt] nested-name-specifier[opt] class-name
+///         'virtual' access-specifier[opt] ::[opt] nested-name-specifier[opt]
+///                        class-name
+///         access-specifier 'virtual'[opt] ::[opt] nested-name-specifier[opt]
+///                        class-name
+Parser::BaseResult Parser::ParseBaseSpecifier(DeclPtrTy ClassDecl) {
+  bool IsVirtual = false;
+  SourceLocation StartLoc = Tok.getLocation();
+
+  // Parse the 'virtual' keyword.
+  if (Tok.is(tok::kw_virtual))  {
+    ConsumeToken();
+    IsVirtual = true;
+  }
+
+  // Parse an (optional) access specifier.
+  AccessSpecifier Access = getAccessSpecifierIfPresent();
+  if (Access != AS_none)
+    ConsumeToken();
+
+  // Parse the 'virtual' keyword (again!), in case it came after the
+  // access specifier.
+  if (Tok.is(tok::kw_virtual))  {
+    SourceLocation VirtualLoc = ConsumeToken();
+    if (IsVirtual) {
+      // Complain about duplicate 'virtual'
+      Diag(VirtualLoc, diag::err_dup_virtual)
+        << FixItHint::CreateRemoval(VirtualLoc);
+    }
+
+    IsVirtual = true;
+  }
+
+  // Parse optional '::' and optional nested-name-specifier.
+  CXXScopeSpec SS;
+  ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0,
+                                 /*EnteringContext=*/false);
+
+  // The location of the base class itself.
+  SourceLocation BaseLoc = Tok.getLocation();
+
+  // Parse the class-name.
+  SourceLocation EndLocation;
+  TypeResult BaseType = ParseClassName(EndLocation, &SS);
+  if (BaseType.isInvalid())
+    return true;
+
+  // Find the complete source range for the base-specifier.
+  SourceRange Range(StartLoc, EndLocation);
+
+  // Notify semantic analysis that we have parsed a complete
+  // base-specifier.
+  return Actions.ActOnBaseSpecifier(ClassDecl, Range, IsVirtual, Access,
+                                    BaseType.get(), BaseLoc);
+}
+
+/// getAccessSpecifierIfPresent - Determine whether the next token is
+/// a C++ access-specifier.
+///
+///       access-specifier: [C++ class.derived]
+///         'private'
+///         'protected'
+///         'public'
+AccessSpecifier Parser::getAccessSpecifierIfPresent() const {
+  switch (Tok.getKind()) {
+  default: return AS_none;
+  case tok::kw_private: return AS_private;
+  case tok::kw_protected: return AS_protected;
+  case tok::kw_public: return AS_public;
+  }
+}
+
+void Parser::HandleMemberFunctionDefaultArgs(Declarator& DeclaratorInfo,
+                                             DeclPtrTy ThisDecl) {
+  // We just declared a member function. If this member function
+  // has any default arguments, we'll need to parse them later.
+  LateParsedMethodDeclaration *LateMethod = 0;
+  DeclaratorChunk::FunctionTypeInfo &FTI
+    = DeclaratorInfo.getTypeObject(0).Fun;
+  for (unsigned ParamIdx = 0; ParamIdx < FTI.NumArgs; ++ParamIdx) {
+    if (LateMethod || FTI.ArgInfo[ParamIdx].DefaultArgTokens) {
+      if (!LateMethod) {
+        // Push this method onto the stack of late-parsed method
+        // declarations.
+        getCurrentClass().MethodDecls.push_back(
+                                LateParsedMethodDeclaration(ThisDecl));
+        LateMethod = &getCurrentClass().MethodDecls.back();
+        LateMethod->TemplateScope = CurScope->isTemplateParamScope();
+
+        // Add all of the parameters prior to this one (they don't
+        // have default arguments).
+        LateMethod->DefaultArgs.reserve(FTI.NumArgs);
+        for (unsigned I = 0; I < ParamIdx; ++I)
+          LateMethod->DefaultArgs.push_back(
+                             LateParsedDefaultArgument(FTI.ArgInfo[I].Param));
+      }
+
+      // Add this parameter to the list of parameters (it or may
+      // not have a default argument).
+      LateMethod->DefaultArgs.push_back(
+        LateParsedDefaultArgument(FTI.ArgInfo[ParamIdx].Param,
+                                  FTI.ArgInfo[ParamIdx].DefaultArgTokens));
+    }
+  }
+}
+
+/// ParseCXXClassMemberDeclaration - Parse a C++ class member declaration.
+///
+///       member-declaration:
+///         decl-specifier-seq[opt] member-declarator-list[opt] ';'
+///         function-definition ';'[opt]
+///         ::[opt] nested-name-specifier template[opt] unqualified-id ';'[TODO]
+///         using-declaration                                            [TODO]
+/// [C++0x] static_assert-declaration
+///         template-declaration
+/// [GNU]   '__extension__' member-declaration
+///
+///       member-declarator-list:
+///         member-declarator
+///         member-declarator-list ',' member-declarator
+///
+///       member-declarator:
+///         declarator pure-specifier[opt]
+///         declarator constant-initializer[opt]
+///         identifier[opt] ':' constant-expression
+///
+///       pure-specifier:
+///         '= 0'
+///
+///       constant-initializer:
+///         '=' constant-expression
+///
+void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
+                                       const ParsedTemplateInfo &TemplateInfo) {
+  // Access declarations.
+  if (!TemplateInfo.Kind &&
+      (Tok.is(tok::identifier) || Tok.is(tok::coloncolon)) &&
+      !TryAnnotateCXXScopeToken() &&
+      Tok.is(tok::annot_cxxscope)) {
+    bool isAccessDecl = false;
+    if (NextToken().is(tok::identifier))
+      isAccessDecl = GetLookAheadToken(2).is(tok::semi);
+    else
+      isAccessDecl = NextToken().is(tok::kw_operator);
+
+    if (isAccessDecl) {
+      // Collect the scope specifier token we annotated earlier.
+      CXXScopeSpec SS;
+      ParseOptionalCXXScopeSpecifier(SS, /*ObjectType*/ 0, false);
+
+      // Try to parse an unqualified-id.
+      UnqualifiedId Name;
+      if (ParseUnqualifiedId(SS, false, true, true, /*ObjectType*/ 0, Name)) {
+        SkipUntil(tok::semi);
+        return;
+      }
+
+      // TODO: recover from mistakenly-qualified operator declarations.
+      if (ExpectAndConsume(tok::semi,
+                           diag::err_expected_semi_after,
+                           "access declaration",
+                           tok::semi))
+        return;
+
+      Actions.ActOnUsingDeclaration(CurScope, AS,
+                                    false, SourceLocation(),
+                                    SS, Name,
+                                    /* AttrList */ 0,
+                                    /* IsTypeName */ false,
+                                    SourceLocation());
+      return;
+    }
+  }
+
+  // static_assert-declaration
+  if (Tok.is(tok::kw_static_assert)) {
+    // FIXME: Check for templates
+    SourceLocation DeclEnd;
+    ParseStaticAssertDeclaration(DeclEnd);
+    return;
+  }
+
+  if (Tok.is(tok::kw_template)) {
+    assert(!TemplateInfo.TemplateParams &&
+           "Nested template improperly parsed?");
+    SourceLocation DeclEnd;
+    ParseDeclarationStartingWithTemplate(Declarator::MemberContext, DeclEnd,
+                                         AS);
+    return;
+  }
+
+  // Handle:  member-declaration ::= '__extension__' member-declaration
+  if (Tok.is(tok::kw___extension__)) {
+    // __extension__ silences extension warnings in the subexpression.
+    ExtensionRAIIObject O(Diags);  // Use RAII to do this.
+    ConsumeToken();
+    return ParseCXXClassMemberDeclaration(AS, TemplateInfo);
+  }
+
+  // Don't parse FOO:BAR as if it were a typo for FOO::BAR, in this context it
+  // is a bitfield.
+  ColonProtectionRAIIObject X(*this);
+
+  CXX0XAttributeList AttrList;
+  // Optional C++0x attribute-specifier
+  if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier())
+    AttrList = ParseCXX0XAttributes();
+
+  if (Tok.is(tok::kw_using)) {
+    // FIXME: Check for template aliases
+
+    if (AttrList.HasAttr)
+      Diag(AttrList.Range.getBegin(), diag::err_attributes_not_allowed)
+        << AttrList.Range;
+
+    // Eat 'using'.
+    SourceLocation UsingLoc = ConsumeToken();
+
+    if (Tok.is(tok::kw_namespace)) {
+      Diag(UsingLoc, diag::err_using_namespace_in_class);
+      SkipUntil(tok::semi, true, true);
+    } else {
+      SourceLocation DeclEnd;
+      // Otherwise, it must be using-declaration.
+      ParseUsingDeclaration(Declarator::MemberContext, UsingLoc, DeclEnd, AS);
+    }
+    return;
+  }
+
+  SourceLocation DSStart = Tok.getLocation();
+  // decl-specifier-seq:
+  // Parse the common declaration-specifiers piece.
+  ParsingDeclSpec DS(*this);
+  DS.AddAttributes(AttrList.AttrList);
+  ParseDeclarationSpecifiers(DS, TemplateInfo, AS, DSC_class);
+
+  Action::MultiTemplateParamsArg TemplateParams(Actions,
+      TemplateInfo.TemplateParams? TemplateInfo.TemplateParams->data() : 0,
+      TemplateInfo.TemplateParams? TemplateInfo.TemplateParams->size() : 0);
+
+  if (Tok.is(tok::semi)) {
+    ConsumeToken();
+    Actions.ParsedFreeStandingDeclSpec(CurScope, DS);
+    return;
+  }
+
+  ParsingDeclarator DeclaratorInfo(*this, DS, Declarator::MemberContext);
+
+  if (Tok.isNot(tok::colon)) {
+    // Don't parse FOO:BAR as if it were a typo for FOO::BAR.
+    ColonProtectionRAIIObject X(*this);
+
+    // Parse the first declarator.
+    ParseDeclarator(DeclaratorInfo);
+    // Error parsing the declarator?
+    if (!DeclaratorInfo.hasName()) {
+      // If so, skip until the semi-colon or a }.
+      SkipUntil(tok::r_brace, true);
+      if (Tok.is(tok::semi))
+        ConsumeToken();
+      return;
+    }
+
+    // If attributes exist after the declarator, but before an '{', parse them.
+    if (Tok.is(tok::kw___attribute)) {
+      SourceLocation Loc;
+      AttributeList *AttrList = ParseGNUAttributes(&Loc);
+      DeclaratorInfo.AddAttributes(AttrList, Loc);
+    }
+
+    // function-definition:
+    if (Tok.is(tok::l_brace)
+        || (DeclaratorInfo.isFunctionDeclarator() &&
+            (Tok.is(tok::colon) || Tok.is(tok::kw_try)))) {
+      if (!DeclaratorInfo.isFunctionDeclarator()) {
+        Diag(Tok, diag::err_func_def_no_params);
+        ConsumeBrace();
+        SkipUntil(tok::r_brace, true);
+        return;
+      }
+
+      if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) {
+        Diag(Tok, diag::err_function_declared_typedef);
+        // This recovery skips the entire function body. It would be nice
+        // to simply call ParseCXXInlineMethodDef() below, however Sema
+        // assumes the declarator represents a function, not a typedef.
+        ConsumeBrace();
+        SkipUntil(tok::r_brace, true);
+        return;
+      }
+
+      ParseCXXInlineMethodDef(AS, DeclaratorInfo, TemplateInfo);
+      return;
+    }
+  }
+
+  // member-declarator-list:
+  //   member-declarator
+  //   member-declarator-list ',' member-declarator
+
+  llvm::SmallVector<DeclPtrTy, 8> DeclsInGroup;
+  OwningExprResult BitfieldSize(Actions);
+  OwningExprResult Init(Actions);
+  bool Deleted = false;
+
+  while (1) {
+    // member-declarator:
+    //   declarator pure-specifier[opt]
+    //   declarator constant-initializer[opt]
+    //   identifier[opt] ':' constant-expression
+
+    if (Tok.is(tok::colon)) {
+      ConsumeToken();
+      BitfieldSize = ParseConstantExpression();
+      if (BitfieldSize.isInvalid())
+        SkipUntil(tok::comma, true, true);
+    }
+
+    // pure-specifier:
+    //   '= 0'
+    //
+    // constant-initializer:
+    //   '=' constant-expression
+    //
+    // defaulted/deleted function-definition:
+    //   '=' 'default'                          [TODO]
+    //   '=' 'delete'
+
+    if (Tok.is(tok::equal)) {
+      ConsumeToken();
+      if (getLang().CPlusPlus0x && Tok.is(tok::kw_delete)) {
+        ConsumeToken();
+        Deleted = true;
+      } else {
+        Init = ParseInitializer();
+        if (Init.isInvalid())
+          SkipUntil(tok::comma, true, true);
+      }
+    }
+
+    // If attributes exist after the declarator, parse them.
+    if (Tok.is(tok::kw___attribute)) {
+      SourceLocation Loc;
+      AttributeList *AttrList = ParseGNUAttributes(&Loc);
+      DeclaratorInfo.AddAttributes(AttrList, Loc);
+    }
+
+    // NOTE: If Sema is the Action module and declarator is an instance field,
+    // this call will *not* return the created decl; It will return null.
+    // See Sema::ActOnCXXMemberDeclarator for details.
+
+    DeclPtrTy ThisDecl;
+    if (DS.isFriendSpecified()) {
+      // TODO: handle initializers, bitfields, 'delete'
+      ThisDecl = Actions.ActOnFriendFunctionDecl(CurScope, DeclaratorInfo,
+                                                 /*IsDefinition*/ false,
+                                                 move(TemplateParams));
+    } else {
+      ThisDecl = Actions.ActOnCXXMemberDeclarator(CurScope, AS,
+                                                  DeclaratorInfo,
+                                                  move(TemplateParams),
+                                                  BitfieldSize.release(),
+                                                  Init.release(),
+                                                  /*IsDefinition*/Deleted,
+                                                  Deleted);
+    }
+    if (ThisDecl)
+      DeclsInGroup.push_back(ThisDecl);
+
+    if (DeclaratorInfo.isFunctionDeclarator() &&
+        DeclaratorInfo.getDeclSpec().getStorageClassSpec()
+          != DeclSpec::SCS_typedef) {
+      HandleMemberFunctionDefaultArgs(DeclaratorInfo, ThisDecl);
+    }
+
+    DeclaratorInfo.complete(ThisDecl);
+
+    // If we don't have a comma, it is either the end of the list (a ';')
+    // or an error, bail out.
+    if (Tok.isNot(tok::comma))
+      break;
+
+    // Consume the comma.
+    ConsumeToken();
+
+    // Parse the next declarator.
+    DeclaratorInfo.clear();
+    BitfieldSize = 0;
+    Init = 0;
+    Deleted = false;
+
+    // Attributes are only allowed on the second declarator.
+    if (Tok.is(tok::kw___attribute)) {
+      SourceLocation Loc;
+      AttributeList *AttrList = ParseGNUAttributes(&Loc);
+      DeclaratorInfo.AddAttributes(AttrList, Loc);
+    }
+
+    if (Tok.isNot(tok::colon))
+      ParseDeclarator(DeclaratorInfo);
+  }
+
+  if (ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list)) {
+    // Skip to end of block or statement.
+    SkipUntil(tok::r_brace, true, true);
+    // If we stopped at a ';', eat it.
+    if (Tok.is(tok::semi)) ConsumeToken();
+    return;
+  }
+
+  Actions.FinalizeDeclaratorGroup(CurScope, DS, DeclsInGroup.data(),
+                                  DeclsInGroup.size());
+}
+
+/// ParseCXXMemberSpecification - Parse the class definition.
+///
+///       member-specification:
+///         member-declaration member-specification[opt]
+///         access-specifier ':' member-specification[opt]
+///
+void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
+                                         unsigned TagType, DeclPtrTy TagDecl) {
+  assert((TagType == DeclSpec::TST_struct ||
+         TagType == DeclSpec::TST_union  ||
+         TagType == DeclSpec::TST_class) && "Invalid TagType!");
+
+  PrettyStackTraceActionsDecl CrashInfo(TagDecl, RecordLoc, Actions,
+                                        PP.getSourceManager(),
+                                        "parsing struct/union/class body");
+
+  // Determine whether this is a non-nested class. Note that local
+  // classes are *not* considered to be nested classes.
+  bool NonNestedClass = true;
+  if (!ClassStack.empty()) {
+    for (const Scope *S = CurScope; S; S = S->getParent()) {
+      if (S->isClassScope()) {
+        // We're inside a class scope, so this is a nested class.
+        NonNestedClass = false;
+        break;
+      }
+
+      if ((S->getFlags() & Scope::FnScope)) {
+        // If we're in a function or function template declared in the
+        // body of a class, then this is a local class rather than a
+        // nested class.
+        const Scope *Parent = S->getParent();
+        if (Parent->isTemplateParamScope())
+          Parent = Parent->getParent();
+        if (Parent->isClassScope())
+          break;
+      }
+    }
+  }
+
+  // Enter a scope for the class.
+  ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope);
+
+  // Note that we are parsing a new (potentially-nested) class definition.
+  ParsingClassDefinition ParsingDef(*this, TagDecl, NonNestedClass);
+
+  if (TagDecl)
+    Actions.ActOnTagStartDefinition(CurScope, TagDecl);
+
+  if (Tok.is(tok::colon)) {
+    ParseBaseClause(TagDecl);
+
+    if (!Tok.is(tok::l_brace)) {
+      Diag(Tok, diag::err_expected_lbrace_after_base_specifiers);
+
+      if (TagDecl)
+        Actions.ActOnTagDefinitionError(CurScope, TagDecl);
+      return;
+    }
+  }
+
+  assert(Tok.is(tok::l_brace));
+
+  SourceLocation LBraceLoc = ConsumeBrace();
+
+  if (!TagDecl) {
+    SkipUntil(tok::r_brace, false, false);
+    return;
+  }
+
+  Actions.ActOnStartCXXMemberDeclarations(CurScope, TagDecl, LBraceLoc);
+
+  // C++ 11p3: Members of a class defined with the keyword class are private
+  // by default. Members of a class defined with the keywords struct or union
+  // are public by default.
+  AccessSpecifier CurAS;
+  if (TagType == DeclSpec::TST_class)
+    CurAS = AS_private;
+  else
+    CurAS = AS_public;
+
+  // While we still have something to read, read the member-declarations.
+  while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
+    // Each iteration of this loop reads one member-declaration.
+
+    // Check for extraneous top-level semicolon.
+    if (Tok.is(tok::semi)) {
+      Diag(Tok, diag::ext_extra_struct_semi)
+        << FixItHint::CreateRemoval(Tok.getLocation());
+      ConsumeToken();
+      continue;
+    }
+
+    AccessSpecifier AS = getAccessSpecifierIfPresent();
+    if (AS != AS_none) {
+      // Current token is a C++ access specifier.
+      CurAS = AS;
+      ConsumeToken();
+      ExpectAndConsume(tok::colon, diag::err_expected_colon);
+      continue;
+    }
+
+    // FIXME: Make sure we don't have a template here.
+
+    // Parse all the comma separated declarators.
+    ParseCXXClassMemberDeclaration(CurAS);
+  }
+
+  SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc);
+
+  // If attributes exist after class contents, parse them.
+  llvm::OwningPtr<AttributeList> AttrList;
+  if (Tok.is(tok::kw___attribute))
+    AttrList.reset(ParseGNUAttributes());
+
+  Actions.ActOnFinishCXXMemberSpecification(CurScope, RecordLoc, TagDecl,
+                                            LBraceLoc, RBraceLoc,
+                                            AttrList.get());
+
+  // C++ 9.2p2: Within the class member-specification, the class is regarded as
+  // complete within function bodies, default arguments,
+  // exception-specifications, and constructor ctor-initializers (including
+  // such things in nested classes).
+  //
+  // FIXME: Only function bodies and constructor ctor-initializers are
+  // parsed correctly, fix the rest.
+  if (NonNestedClass) {
+    // We are not inside a nested class. This class and its nested classes
+    // are complete and we can parse the delayed portions of method
+    // declarations and the lexed inline method definitions.
+    ParseLexedMethodDeclarations(getCurrentClass());
+    ParseLexedMethodDefs(getCurrentClass());
+  }
+
+  Actions.ActOnTagFinishDefinition(CurScope, TagDecl, RBraceLoc);
+
+  // Leave the class scope.
+  ParsingDef.Pop();
+  ClassScope.Exit();
+}
+
+/// ParseConstructorInitializer - Parse a C++ constructor initializer,
+/// which explicitly initializes the members or base classes of a
+/// class (C++ [class.base.init]). For example, the three initializers
+/// after the ':' in the Derived constructor below:
+///
+/// @code
+/// class Base { };
+/// class Derived : Base {
+///   int x;
+///   float f;
+/// public:
+///   Derived(float f) : Base(), x(17), f(f) { }
+/// };
+/// @endcode
+///
+/// [C++]  ctor-initializer:
+///          ':' mem-initializer-list
+///
+/// [C++]  mem-initializer-list:
+///          mem-initializer
+///          mem-initializer , mem-initializer-list
+void Parser::ParseConstructorInitializer(DeclPtrTy ConstructorDecl) {
+  assert(Tok.is(tok::colon) && "Constructor initializer always starts with ':'");
+
+  SourceLocation ColonLoc = ConsumeToken();
+
+  llvm::SmallVector<MemInitTy*, 4> MemInitializers;
+  bool AnyErrors = false;
+
+  do {
+    MemInitResult MemInit = ParseMemInitializer(ConstructorDecl);
+    if (!MemInit.isInvalid())
+      MemInitializers.push_back(MemInit.get());
+    else
+      AnyErrors = true;
+
+    if (Tok.is(tok::comma))
+      ConsumeToken();
+    else if (Tok.is(tok::l_brace))
+      break;
+    else {
+      // Skip over garbage, until we get to '{'.  Don't eat the '{'.
+      Diag(Tok.getLocation(), diag::err_expected_lbrace_or_comma);
+      SkipUntil(tok::l_brace, true, true);
+      break;
+    }
+  } while (true);
+
+  Actions.ActOnMemInitializers(ConstructorDecl, ColonLoc,
+                               MemInitializers.data(), MemInitializers.size(),
+                               AnyErrors);
+}
+
+/// ParseMemInitializer - Parse a C++ member initializer, which is
+/// part of a constructor initializer that explicitly initializes one
+/// member or base class (C++ [class.base.init]). See
+/// ParseConstructorInitializer for an example.
+///
+/// [C++] mem-initializer:
+///         mem-initializer-id '(' expression-list[opt] ')'
+///
+/// [C++] mem-initializer-id:
+///         '::'[opt] nested-name-specifier[opt] class-name
+///         identifier
+Parser::MemInitResult Parser::ParseMemInitializer(DeclPtrTy ConstructorDecl) {
+  // parse '::'[opt] nested-name-specifier[opt]
+  CXXScopeSpec SS;
+  ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, false);
+  TypeTy *TemplateTypeTy = 0;
+  if (Tok.is(tok::annot_template_id)) {
+    TemplateIdAnnotation *TemplateId
+      = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
+    if (TemplateId->Kind == TNK_Type_template ||
+        TemplateId->Kind == TNK_Dependent_template_name) {
+      AnnotateTemplateIdTokenAsType(&SS);
+      assert(Tok.is(tok::annot_typename) && "template-id -> type failed");
+      TemplateTypeTy = Tok.getAnnotationValue();
+    }
+  }
+  if (!TemplateTypeTy && Tok.isNot(tok::identifier)) {
+    Diag(Tok, diag::err_expected_member_or_base_name);
+    return true;
+  }
+
+  // Get the identifier. This may be a member name or a class name,
+  // but we'll let the semantic analysis determine which it is.
+  IdentifierInfo *II = Tok.is(tok::identifier) ? Tok.getIdentifierInfo() : 0;
+  SourceLocation IdLoc = ConsumeToken();
+
+  // Parse the '('.
+  if (Tok.isNot(tok::l_paren)) {
+    Diag(Tok, diag::err_expected_lparen);
+    return true;
+  }
+  SourceLocation LParenLoc = ConsumeParen();
+
+  // Parse the optional expression-list.
+  ExprVector ArgExprs(Actions);
+  CommaLocsTy CommaLocs;
+  if (Tok.isNot(tok::r_paren) && ParseExpressionList(ArgExprs, CommaLocs)) {
+    SkipUntil(tok::r_paren);
+    return true;
+  }
+
+  SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
+
+  return Actions.ActOnMemInitializer(ConstructorDecl, CurScope, SS, II,
+                                     TemplateTypeTy, IdLoc,
+                                     LParenLoc, ArgExprs.take(),
+                                     ArgExprs.size(), CommaLocs.data(),
+                                     RParenLoc);
+}
+
+/// ParseExceptionSpecification - Parse a C++ exception-specification
+/// (C++ [except.spec]).
+///
+///       exception-specification:
+///         'throw' '(' type-id-list [opt] ')'
+/// [MS]    'throw' '(' '...' ')'
+///
+///       type-id-list:
+///         type-id
+///         type-id-list ',' type-id
+///
+bool Parser::ParseExceptionSpecification(SourceLocation &EndLoc,
+                                         llvm::SmallVector<TypeTy*, 2>
+                                             &Exceptions,
+                                         llvm::SmallVector<SourceRange, 2>
+                                             &Ranges,
+                                         bool &hasAnyExceptionSpec) {
+  assert(Tok.is(tok::kw_throw) && "expected throw");
+
+  SourceLocation ThrowLoc = ConsumeToken();
+
+  if (!Tok.is(tok::l_paren)) {
+    return Diag(Tok, diag::err_expected_lparen_after) << "throw";
+  }
+  SourceLocation LParenLoc = ConsumeParen();
+
+  // Parse throw(...), a Microsoft extension that means "this function
+  // can throw anything".
+  if (Tok.is(tok::ellipsis)) {
+    hasAnyExceptionSpec = true;
+    SourceLocation EllipsisLoc = ConsumeToken();
+    if (!getLang().Microsoft)
+      Diag(EllipsisLoc, diag::ext_ellipsis_exception_spec);
+    EndLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
+    return false;
+  }
+
+  // Parse the sequence of type-ids.
+  SourceRange Range;
+  while (Tok.isNot(tok::r_paren)) {
+    TypeResult Res(ParseTypeName(&Range));
+    if (!Res.isInvalid()) {
+      Exceptions.push_back(Res.get());
+      Ranges.push_back(Range);
+    }
+    if (Tok.is(tok::comma))
+      ConsumeToken();
+    else
+      break;
+  }
+
+  EndLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
+  return false;
+}
+
+/// \brief We have just started parsing the definition of a new class,
+/// so push that class onto our stack of classes that is currently
+/// being parsed.
+void Parser::PushParsingClass(DeclPtrTy ClassDecl, bool NonNestedClass) {
+  assert((NonNestedClass || !ClassStack.empty()) &&
+         "Nested class without outer class");
+  ClassStack.push(new ParsingClass(ClassDecl, NonNestedClass));
+}
+
+/// \brief Deallocate the given parsed class and all of its nested
+/// classes.
+void Parser::DeallocateParsedClasses(Parser::ParsingClass *Class) {
+  for (unsigned I = 0, N = Class->NestedClasses.size(); I != N; ++I)
+    DeallocateParsedClasses(Class->NestedClasses[I]);
+  delete Class;
+}
+
+/// \brief Pop the top class of the stack of classes that are
+/// currently being parsed.
+///
+/// This routine should be called when we have finished parsing the
+/// definition of a class, but have not yet popped the Scope
+/// associated with the class's definition.
+///
+/// \returns true if the class we've popped is a top-level class,
+/// false otherwise.
+void Parser::PopParsingClass() {
+  assert(!ClassStack.empty() && "Mismatched push/pop for class parsing");
+
+  ParsingClass *Victim = ClassStack.top();
+  ClassStack.pop();
+  if (Victim->TopLevelClass) {
+    // Deallocate all of the nested classes of this class,
+    // recursively: we don't need to keep any of this information.
+    DeallocateParsedClasses(Victim);
+    return;
+  }
+  assert(!ClassStack.empty() && "Missing top-level class?");
+
+  if (Victim->MethodDecls.empty() && Victim->MethodDefs.empty() &&
+      Victim->NestedClasses.empty()) {
+    // The victim is a nested class, but we will not need to perform
+    // any processing after the definition of this class since it has
+    // no members whose handling was delayed. Therefore, we can just
+    // remove this nested class.
+    delete Victim;
+    return;
+  }
+
+  // This nested class has some members that will need to be processed
+  // after the top-level class is completely defined. Therefore, add
+  // it to the list of nested classes within its parent.
+  assert(CurScope->isClassScope() && "Nested class outside of class scope?");
+  ClassStack.top()->NestedClasses.push_back(Victim);
+  Victim->TemplateScope = CurScope->getParent()->isTemplateParamScope();
+}
+
+/// ParseCXX0XAttributes - Parse a C++0x attribute-specifier. Currently only
+/// parses standard attributes.
+///
+/// [C++0x] attribute-specifier:
+///         '[' '[' attribute-list ']' ']'
+///
+/// [C++0x] attribute-list:
+///         attribute[opt]
+///         attribute-list ',' attribute[opt]
+///
+/// [C++0x] attribute:
+///         attribute-token attribute-argument-clause[opt]
+///
+/// [C++0x] attribute-token:
+///         identifier
+///         attribute-scoped-token
+///
+/// [C++0x] attribute-scoped-token:
+///         attribute-namespace '::' identifier
+///
+/// [C++0x] attribute-namespace:
+///         identifier
+///
+/// [C++0x] attribute-argument-clause:
+///         '(' balanced-token-seq ')'
+///
+/// [C++0x] balanced-token-seq:
+///         balanced-token
+///         balanced-token-seq balanced-token
+///
+/// [C++0x] balanced-token:
+///         '(' balanced-token-seq ')'
+///         '[' balanced-token-seq ']'
+///         '{' balanced-token-seq '}'
+///         any token but '(', ')', '[', ']', '{', or '}'
+CXX0XAttributeList Parser::ParseCXX0XAttributes(SourceLocation *EndLoc) {
+  assert(Tok.is(tok::l_square) && NextToken().is(tok::l_square)
+      && "Not a C++0x attribute list");
+
+  SourceLocation StartLoc = Tok.getLocation(), Loc;
+  AttributeList *CurrAttr = 0;
+
+  ConsumeBracket();
+  ConsumeBracket();
+
+  if (Tok.is(tok::comma)) {
+    Diag(Tok.getLocation(), diag::err_expected_ident);
+    ConsumeToken();
+  }
+
+  while (Tok.is(tok::identifier) || Tok.is(tok::comma)) {
+    // attribute not present
+    if (Tok.is(tok::comma)) {
+      ConsumeToken();
+      continue;
+    }
+
+    IdentifierInfo *ScopeName = 0, *AttrName = Tok.getIdentifierInfo();
+    SourceLocation ScopeLoc, AttrLoc = ConsumeToken();
+
+    // scoped attribute
+    if (Tok.is(tok::coloncolon)) {
+      ConsumeToken();
+
+      if (!Tok.is(tok::identifier)) {
+        Diag(Tok.getLocation(), diag::err_expected_ident);
+        SkipUntil(tok::r_square, tok::comma, true, true);
+        continue;
+      }
+
+      ScopeName = AttrName;
+      ScopeLoc = AttrLoc;
+
+      AttrName = Tok.getIdentifierInfo();
+      AttrLoc = ConsumeToken();
+    }
+
+    bool AttrParsed = false;
+    // No scoped names are supported; ideally we could put all non-standard
+    // attributes into namespaces.
+    if (!ScopeName) {
+      switch(AttributeList::getKind(AttrName))
+      {
+      // No arguments
+      case AttributeList::AT_base_check:
+      case AttributeList::AT_carries_dependency:
+      case AttributeList::AT_final:
+      case AttributeList::AT_hiding:
+      case AttributeList::AT_noreturn:
+      case AttributeList::AT_override: {
+        if (Tok.is(tok::l_paren)) {
+          Diag(Tok.getLocation(), diag::err_cxx0x_attribute_forbids_arguments)
+            << AttrName->getName();
+          break;
+        }
+
+        CurrAttr = new AttributeList(AttrName, AttrLoc, 0, AttrLoc, 0,
+                                     SourceLocation(), 0, 0, CurrAttr, false,
+                                     true);
+        AttrParsed = true;
+        break;
+      }
+
+      // One argument; must be a type-id or assignment-expression
+      case AttributeList::AT_aligned: {
+        if (Tok.isNot(tok::l_paren)) {
+          Diag(Tok.getLocation(), diag::err_cxx0x_attribute_requires_arguments)
+            << AttrName->getName();
+          break;
+        }
+        SourceLocation ParamLoc = ConsumeParen();
+
+        OwningExprResult ArgExpr = ParseCXX0XAlignArgument(ParamLoc);
+
+        MatchRHSPunctuation(tok::r_paren, ParamLoc);
+
+        ExprVector ArgExprs(Actions);
+        ArgExprs.push_back(ArgExpr.release());
+        CurrAttr = new AttributeList(AttrName, AttrLoc, 0, AttrLoc,
+                                     0, ParamLoc, ArgExprs.take(), 1, CurrAttr,
+                                     false, true);
+
+        AttrParsed = true;
+        break;
+      }
+
+      // Silence warnings
+      default: break;
+      }
+    }
+
+    // Skip the entire parameter clause, if any
+    if (!AttrParsed && Tok.is(tok::l_paren)) {
+      ConsumeParen();
+      // SkipUntil maintains the balancedness of tokens.
+      SkipUntil(tok::r_paren, false);
+    }
+  }
+
+  if (ExpectAndConsume(tok::r_square, diag::err_expected_rsquare))
+    SkipUntil(tok::r_square, false);
+  Loc = Tok.getLocation();
+  if (ExpectAndConsume(tok::r_square, diag::err_expected_rsquare))
+    SkipUntil(tok::r_square, false);
+
+  CXX0XAttributeList Attr (CurrAttr, SourceRange(StartLoc, Loc), true);
+  return Attr;
+}
+
+/// ParseCXX0XAlignArgument - Parse the argument to C++0x's [[align]]
+/// attribute.
+///
+/// FIXME: Simply returns an alignof() expression if the argument is a
+/// type. Ideally, the type should be propagated directly into Sema.
+///
+/// [C++0x] 'align' '(' type-id ')'
+/// [C++0x] 'align' '(' assignment-expression ')'
+Parser::OwningExprResult Parser::ParseCXX0XAlignArgument(SourceLocation Start) {
+  if (isTypeIdInParens()) {
+    EnterExpressionEvaluationContext Unevaluated(Actions,
+                                                  Action::Unevaluated);
+    SourceLocation TypeLoc = Tok.getLocation();
+    TypeTy *Ty = ParseTypeName().get();
+    SourceRange TypeRange(Start, Tok.getLocation());
+    return Actions.ActOnSizeOfAlignOfExpr(TypeLoc, false, true, Ty,
+                                              TypeRange);
+  } else
+    return ParseConstantExpression();
+}
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
new file mode 100644
index 0000000..b9e632a
--- /dev/null
+++ b/lib/Parse/ParseExpr.cpp
@@ -0,0 +1,1686 @@
+//===--- ParseExpr.cpp - Expression Parsing -------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Expression parsing implementation.  Expressions in
+// C99 basically consist of a bunch of binary operators with unary operators and
+// other random stuff at the leaves.
+//
+// In the C99 grammar, these unary operators bind tightest and are represented
+// as the 'cast-expression' production.  Everything else is either a binary
+// operator (e.g. '/') or a ternary operator ("?:").  The unary leaves are
+// handled by ParseCastExpression, the higher level pieces are handled by
+// ParseBinaryExpression.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Parse/Parser.h"
+#include "clang/Parse/DeclSpec.h"
+#include "clang/Parse/Scope.h"
+#include "clang/Parse/Template.h"
+#include "clang/Basic/PrettyStackTrace.h"
+#include "RAIIObjectsForParser.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallString.h"
+using namespace clang;
+
+/// getBinOpPrecedence - Return the precedence of the specified binary operator
+/// token.  This returns:
+///
+static prec::Level getBinOpPrecedence(tok::TokenKind Kind,
+                                      bool GreaterThanIsOperator,
+                                      bool CPlusPlus0x) {
+  switch (Kind) {
+  case tok::greater:
+    // C++ [temp.names]p3:
+    //   [...] When parsing a template-argument-list, the first
+    //   non-nested > is taken as the ending delimiter rather than a
+    //   greater-than operator. [...]
+    if (GreaterThanIsOperator)
+      return prec::Relational;
+    return prec::Unknown;
+
+  case tok::greatergreater:
+    // C++0x [temp.names]p3:
+    //
+    //   [...] Similarly, the first non-nested >> is treated as two
+    //   consecutive but distinct > tokens, the first of which is
+    //   taken as the end of the template-argument-list and completes
+    //   the template-id. [...]
+    if (GreaterThanIsOperator || !CPlusPlus0x)
+      return prec::Shift;
+    return prec::Unknown;
+
+  default:                        return prec::Unknown;
+  case tok::comma:                return prec::Comma;
+  case tok::equal:
+  case tok::starequal:
+  case tok::slashequal:
+  case tok::percentequal:
+  case tok::plusequal:
+  case tok::minusequal:
+  case tok::lesslessequal:
+  case tok::greatergreaterequal:
+  case tok::ampequal:
+  case tok::caretequal:
+  case tok::pipeequal:            return prec::Assignment;
+  case tok::question:             return prec::Conditional;
+  case tok::pipepipe:             return prec::LogicalOr;
+  case tok::ampamp:               return prec::LogicalAnd;
+  case tok::pipe:                 return prec::InclusiveOr;
+  case tok::caret:                return prec::ExclusiveOr;
+  case tok::amp:                  return prec::And;
+  case tok::exclaimequal:
+  case tok::equalequal:           return prec::Equality;
+  case tok::lessequal:
+  case tok::less:
+  case tok::greaterequal:         return prec::Relational;
+  case tok::lessless:             return prec::Shift;
+  case tok::plus:
+  case tok::minus:                return prec::Additive;
+  case tok::percent:
+  case tok::slash:
+  case tok::star:                 return prec::Multiplicative;
+  case tok::periodstar:
+  case tok::arrowstar:            return prec::PointerToMember;
+  }
+}
+
+
+/// ParseExpression - Simple precedence-based parser for binary/ternary
+/// operators.
+///
+/// Note: we diverge from the C99 grammar when parsing the assignment-expression
+/// production.  C99 specifies that the LHS of an assignment operator should be
+/// parsed as a unary-expression, but consistency dictates that it be a
+/// conditional-expession.  In practice, the important thing here is that the
+/// LHS of an assignment has to be an l-value, which productions between
+/// unary-expression and conditional-expression don't produce.  Because we want
+/// consistency, we parse the LHS as a conditional-expression, then check for
+/// l-value-ness in semantic analysis stages.
+///
+///       pm-expression: [C++ 5.5]
+///         cast-expression
+///         pm-expression '.*' cast-expression
+///         pm-expression '->*' cast-expression
+///
+///       multiplicative-expression: [C99 6.5.5]
+///     Note: in C++, apply pm-expression instead of cast-expression
+///         cast-expression
+///         multiplicative-expression '*' cast-expression
+///         multiplicative-expression '/' cast-expression
+///         multiplicative-expression '%' cast-expression
+///
+///       additive-expression: [C99 6.5.6]
+///         multiplicative-expression
+///         additive-expression '+' multiplicative-expression
+///         additive-expression '-' multiplicative-expression
+///
+///       shift-expression: [C99 6.5.7]
+///         additive-expression
+///         shift-expression '<<' additive-expression
+///         shift-expression '>>' additive-expression
+///
+///       relational-expression: [C99 6.5.8]
+///         shift-expression
+///         relational-expression '<' shift-expression
+///         relational-expression '>' shift-expression
+///         relational-expression '<=' shift-expression
+///         relational-expression '>=' shift-expression
+///
+///       equality-expression: [C99 6.5.9]
+///         relational-expression
+///         equality-expression '==' relational-expression
+///         equality-expression '!=' relational-expression
+///
+///       AND-expression: [C99 6.5.10]
+///         equality-expression
+///         AND-expression '&' equality-expression
+///
+///       exclusive-OR-expression: [C99 6.5.11]
+///         AND-expression
+///         exclusive-OR-expression '^' AND-expression
+///
+///       inclusive-OR-expression: [C99 6.5.12]
+///         exclusive-OR-expression
+///         inclusive-OR-expression '|' exclusive-OR-expression
+///
+///       logical-AND-expression: [C99 6.5.13]
+///         inclusive-OR-expression
+///         logical-AND-expression '&&' inclusive-OR-expression
+///
+///       logical-OR-expression: [C99 6.5.14]
+///         logical-AND-expression
+///         logical-OR-expression '||' logical-AND-expression
+///
+///       conditional-expression: [C99 6.5.15]
+///         logical-OR-expression
+///         logical-OR-expression '?' expression ':' conditional-expression
+/// [GNU]   logical-OR-expression '?' ':' conditional-expression
+/// [C++] the third operand is an assignment-expression
+///
+///       assignment-expression: [C99 6.5.16]
+///         conditional-expression
+///         unary-expression assignment-operator assignment-expression
+/// [C++]   throw-expression [C++ 15]
+///
+///       assignment-operator: one of
+///         = *= /= %= += -= <<= >>= &= ^= |=
+///
+///       expression: [C99 6.5.17]
+///         assignment-expression
+///         expression ',' assignment-expression
+///
+Parser::OwningExprResult Parser::ParseExpression() {
+  OwningExprResult LHS(ParseAssignmentExpression());
+  if (LHS.isInvalid()) return move(LHS);
+
+  return ParseRHSOfBinaryExpression(move(LHS), prec::Comma);
+}
+
+/// This routine is called when the '@' is seen and consumed.
+/// Current token is an Identifier and is not a 'try'. This
+/// routine is necessary to disambiguate @try-statement from,
+/// for example, @encode-expression.
+///
+Parser::OwningExprResult
+Parser::ParseExpressionWithLeadingAt(SourceLocation AtLoc) {
+  OwningExprResult LHS(ParseObjCAtExpression(AtLoc));
+  if (LHS.isInvalid()) return move(LHS);
+
+  return ParseRHSOfBinaryExpression(move(LHS), prec::Comma);
+}
+
+/// This routine is called when a leading '__extension__' is seen and
+/// consumed.  This is necessary because the token gets consumed in the
+/// process of disambiguating between an expression and a declaration.
+Parser::OwningExprResult
+Parser::ParseExpressionWithLeadingExtension(SourceLocation ExtLoc) {
+  OwningExprResult LHS(Actions, true);
+  {
+    // Silence extension warnings in the sub-expression
+    ExtensionRAIIObject O(Diags);
+
+    LHS = ParseCastExpression(false);
+    if (LHS.isInvalid()) return move(LHS);
+  }
+
+  LHS = Actions.ActOnUnaryOp(CurScope, ExtLoc, tok::kw___extension__,
+                             move(LHS));
+  if (LHS.isInvalid()) return move(LHS);
+
+  return ParseRHSOfBinaryExpression(move(LHS), prec::Comma);
+}
+
+/// ParseAssignmentExpression - Parse an expr that doesn't include commas.
+///
+Parser::OwningExprResult Parser::ParseAssignmentExpression() {
+  if (Tok.is(tok::code_completion)) {
+    Actions.CodeCompleteOrdinaryName(CurScope, Action::CCC_Expression);
+    ConsumeToken();
+  }
+
+  if (Tok.is(tok::kw_throw))
+    return ParseThrowExpression();
+
+  OwningExprResult LHS(ParseCastExpression(false));
+  if (LHS.isInvalid()) return move(LHS);
+
+  return ParseRHSOfBinaryExpression(move(LHS), prec::Assignment);
+}
+
+/// ParseAssignmentExprWithObjCMessageExprStart - Parse an assignment expression
+/// where part of an objc message send has already been parsed.  In this case
+/// LBracLoc indicates the location of the '[' of the message send, and either
+/// ReceiverName or ReceiverExpr is non-null indicating the receiver of the
+/// message.
+///
+/// Since this handles full assignment-expression's, it handles postfix
+/// expressions and other binary operators for these expressions as well.
+Parser::OwningExprResult
+Parser::ParseAssignmentExprWithObjCMessageExprStart(SourceLocation LBracLoc,
+                                                    SourceLocation SuperLoc,
+                                                    TypeTy *ReceiverType,
+                                                    ExprArg ReceiverExpr) {
+  OwningExprResult R(ParseObjCMessageExpressionBody(LBracLoc, SuperLoc,
+                                                    ReceiverType,
+                                                    move(ReceiverExpr)));
+  if (R.isInvalid()) return move(R);
+  R = ParsePostfixExpressionSuffix(move(R));
+  if (R.isInvalid()) return move(R);
+  return ParseRHSOfBinaryExpression(move(R), prec::Assignment);
+}
+
+
+Parser::OwningExprResult Parser::ParseConstantExpression() {
+  // C++ [basic.def.odr]p2:
+  //   An expression is potentially evaluated unless it appears where an
+  //   integral constant expression is required (see 5.19) [...].
+  EnterExpressionEvaluationContext Unevaluated(Actions,
+                                               Action::Unevaluated);
+
+  OwningExprResult LHS(ParseCastExpression(false));
+  if (LHS.isInvalid()) return move(LHS);
+
+  return ParseRHSOfBinaryExpression(move(LHS), prec::Conditional);
+}
+
+/// ParseRHSOfBinaryExpression - Parse a binary expression that starts with
+/// LHS and has a precedence of at least MinPrec.
+Parser::OwningExprResult
+Parser::ParseRHSOfBinaryExpression(OwningExprResult LHS, prec::Level MinPrec) {
+  prec::Level NextTokPrec = getBinOpPrecedence(Tok.getKind(),
+                                               GreaterThanIsOperator,
+                                               getLang().CPlusPlus0x);
+  SourceLocation ColonLoc;
+
+  while (1) {
+    // If this token has a lower precedence than we are allowed to parse (e.g.
+    // because we are called recursively, or because the token is not a binop),
+    // then we are done!
+    if (NextTokPrec < MinPrec)
+      return move(LHS);
+
+    // Consume the operator, saving the operator token for error reporting.
+    Token OpToken = Tok;
+    ConsumeToken();
+
+    // Special case handling for the ternary operator.
+    OwningExprResult TernaryMiddle(Actions, true);
+    if (NextTokPrec == prec::Conditional) {
+      if (Tok.isNot(tok::colon)) {
+        // Don't parse FOO:BAR as if it were a typo for FOO::BAR.
+        ColonProtectionRAIIObject X(*this);
+
+        // Handle this production specially:
+        //   logical-OR-expression '?' expression ':' conditional-expression
+        // In particular, the RHS of the '?' is 'expression', not
+        // 'logical-OR-expression' as we might expect.
+        TernaryMiddle = ParseExpression();
+        if (TernaryMiddle.isInvalid())
+          return move(TernaryMiddle);
+      } else {
+        // Special case handling of "X ? Y : Z" where Y is empty:
+        //   logical-OR-expression '?' ':' conditional-expression   [GNU]
+        TernaryMiddle = 0;
+        Diag(Tok, diag::ext_gnu_conditional_expr);
+      }
+
+      if (Tok.is(tok::colon)) {
+        // Eat the colon.
+        ColonLoc = ConsumeToken();
+      } else {
+        Diag(Tok, diag::err_expected_colon)
+          << FixItHint::CreateInsertion(Tok.getLocation(), ": ");
+        Diag(OpToken, diag::note_matching) << "?";
+        ColonLoc = Tok.getLocation();
+      }
+    }
+    
+    // Parse another leaf here for the RHS of the operator.
+    // ParseCastExpression works here because all RHS expressions in C have it
+    // as a prefix, at least. However, in C++, an assignment-expression could
+    // be a throw-expression, which is not a valid cast-expression.
+    // Therefore we need some special-casing here.
+    // Also note that the third operand of the conditional operator is
+    // an assignment-expression in C++.
+    OwningExprResult RHS(Actions);
+    if (getLang().CPlusPlus && NextTokPrec <= prec::Conditional)
+      RHS = ParseAssignmentExpression();
+    else
+      RHS = ParseCastExpression(false);
+    if (RHS.isInvalid())
+      return move(RHS);
+
+    // Remember the precedence of this operator and get the precedence of the
+    // operator immediately to the right of the RHS.
+    prec::Level ThisPrec = NextTokPrec;
+    NextTokPrec = getBinOpPrecedence(Tok.getKind(), GreaterThanIsOperator,
+                                     getLang().CPlusPlus0x);
+
+    // Assignment and conditional expressions are right-associative.
+    bool isRightAssoc = ThisPrec == prec::Conditional ||
+                        ThisPrec == prec::Assignment;
+
+    // Get the precedence of the operator to the right of the RHS.  If it binds
+    // more tightly with RHS than we do, evaluate it completely first.
+    if (ThisPrec < NextTokPrec ||
+        (ThisPrec == NextTokPrec && isRightAssoc)) {
+      // If this is left-associative, only parse things on the RHS that bind
+      // more tightly than the current operator.  If it is left-associative, it
+      // is okay, to bind exactly as tightly.  For example, compile A=B=C=D as
+      // A=(B=(C=D)), where each paren is a level of recursion here.
+      // The function takes ownership of the RHS.
+      RHS = ParseRHSOfBinaryExpression(move(RHS), 
+                            static_cast<prec::Level>(ThisPrec + !isRightAssoc));
+      if (RHS.isInvalid())
+        return move(RHS);
+
+      NextTokPrec = getBinOpPrecedence(Tok.getKind(), GreaterThanIsOperator,
+                                       getLang().CPlusPlus0x);
+    }
+    assert(NextTokPrec <= ThisPrec && "Recursion didn't work!");
+
+    if (!LHS.isInvalid()) {
+      // Combine the LHS and RHS into the LHS (e.g. build AST).
+      if (TernaryMiddle.isInvalid()) {
+        // If we're using '>>' as an operator within a template
+        // argument list (in C++98), suggest the addition of
+        // parentheses so that the code remains well-formed in C++0x.
+        if (!GreaterThanIsOperator && OpToken.is(tok::greatergreater))
+          SuggestParentheses(OpToken.getLocation(),
+                             diag::warn_cxx0x_right_shift_in_template_arg,
+                         SourceRange(Actions.getExprRange(LHS.get()).getBegin(),
+                                     Actions.getExprRange(RHS.get()).getEnd()));
+
+        LHS = Actions.ActOnBinOp(CurScope, OpToken.getLocation(),
+                                 OpToken.getKind(), move(LHS), move(RHS));
+      } else
+        LHS = Actions.ActOnConditionalOp(OpToken.getLocation(), ColonLoc,
+                                         move(LHS), move(TernaryMiddle),
+                                         move(RHS));
+    }
+  }
+}
+
+/// ParseCastExpression - Parse a cast-expression, or, if isUnaryExpression is
+/// true, parse a unary-expression. isAddressOfOperand exists because an
+/// id-expression that is the operand of address-of gets special treatment
+/// due to member pointers.
+///
+Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression,
+                                                     bool isAddressOfOperand,
+                                                     TypeTy *TypeOfCast) {
+  bool NotCastExpr;
+  OwningExprResult Res = ParseCastExpression(isUnaryExpression,
+                                             isAddressOfOperand,
+                                             NotCastExpr,
+                                             TypeOfCast);
+  if (NotCastExpr)
+    Diag(Tok, diag::err_expected_expression);
+  return move(Res);
+}
+
+/// ParseCastExpression - Parse a cast-expression, or, if isUnaryExpression is
+/// true, parse a unary-expression. isAddressOfOperand exists because an
+/// id-expression that is the operand of address-of gets special treatment
+/// due to member pointers. NotCastExpr is set to true if the token is not the
+/// start of a cast-expression, and no diagnostic is emitted in this case.
+///
+///       cast-expression: [C99 6.5.4]
+///         unary-expression
+///         '(' type-name ')' cast-expression
+///
+///       unary-expression:  [C99 6.5.3]
+///         postfix-expression
+///         '++' unary-expression
+///         '--' unary-expression
+///         unary-operator cast-expression
+///         'sizeof' unary-expression
+///         'sizeof' '(' type-name ')'
+/// [GNU]   '__alignof' unary-expression
+/// [GNU]   '__alignof' '(' type-name ')'
+/// [C++0x] 'alignof' '(' type-id ')'
+/// [GNU]   '&&' identifier
+/// [C++]   new-expression
+/// [C++]   delete-expression
+///
+///       unary-operator: one of
+///         '&'  '*'  '+'  '-'  '~'  '!'
+/// [GNU]   '__extension__'  '__real'  '__imag'
+///
+///       primary-expression: [C99 6.5.1]
+/// [C99]   identifier
+/// [C++]   id-expression
+///         constant
+///         string-literal
+/// [C++]   boolean-literal  [C++ 2.13.5]
+/// [C++0x] 'nullptr'        [C++0x 2.14.7]
+///         '(' expression ')'
+///         '__func__'        [C99 6.4.2.2]
+/// [GNU]   '__FUNCTION__'
+/// [GNU]   '__PRETTY_FUNCTION__'
+/// [GNU]   '(' compound-statement ')'
+/// [GNU]   '__builtin_va_arg' '(' assignment-expression ',' type-name ')'
+/// [GNU]   '__builtin_offsetof' '(' type-name ',' offsetof-member-designator')'
+/// [GNU]   '__builtin_choose_expr' '(' assign-expr ',' assign-expr ','
+///                                     assign-expr ')'
+/// [GNU]   '__builtin_types_compatible_p' '(' type-name ',' type-name ')'
+/// [GNU]   '__null'
+/// [OBJC]  '[' objc-message-expr ']'
+/// [OBJC]  '@selector' '(' objc-selector-arg ')'
+/// [OBJC]  '@protocol' '(' identifier ')'
+/// [OBJC]  '@encode' '(' type-name ')'
+/// [OBJC]  objc-string-literal
+/// [C++]   simple-type-specifier '(' expression-list[opt] ')'      [C++ 5.2.3]
+/// [C++]   typename-specifier '(' expression-list[opt] ')'         [C++ 5.2.3]
+/// [C++]   'const_cast' '<' type-name '>' '(' expression ')'       [C++ 5.2p1]
+/// [C++]   'dynamic_cast' '<' type-name '>' '(' expression ')'     [C++ 5.2p1]
+/// [C++]   'reinterpret_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1]
+/// [C++]   'static_cast' '<' type-name '>' '(' expression ')'      [C++ 5.2p1]
+/// [C++]   'typeid' '(' expression ')'                             [C++ 5.2p1]
+/// [C++]   'typeid' '(' type-id ')'                                [C++ 5.2p1]
+/// [C++]   'this'          [C++ 9.3.2]
+/// [G++]   unary-type-trait '(' type-id ')'
+/// [G++]   binary-type-trait '(' type-id ',' type-id ')'           [TODO]
+/// [clang] '^' block-literal
+///
+///       constant: [C99 6.4.4]
+///         integer-constant
+///         floating-constant
+///         enumeration-constant -> identifier
+///         character-constant
+///
+///       id-expression: [C++ 5.1]
+///                   unqualified-id
+///                   qualified-id          
+///
+///       unqualified-id: [C++ 5.1]
+///                   identifier
+///                   operator-function-id
+///                   conversion-function-id
+///                   '~' class-name        
+///                   template-id           
+///
+///       new-expression: [C++ 5.3.4]
+///                   '::'[opt] 'new' new-placement[opt] new-type-id
+///                                     new-initializer[opt]
+///                   '::'[opt] 'new' new-placement[opt] '(' type-id ')'
+///                                     new-initializer[opt]
+///
+///       delete-expression: [C++ 5.3.5]
+///                   '::'[opt] 'delete' cast-expression
+///                   '::'[opt] 'delete' '[' ']' cast-expression
+///
+/// [GNU] unary-type-trait:
+///                   '__has_nothrow_assign'                  [TODO]
+///                   '__has_nothrow_copy'                    [TODO]
+///                   '__has_nothrow_constructor'             [TODO]
+///                   '__has_trivial_assign'                  [TODO]
+///                   '__has_trivial_copy'                    [TODO]
+///                   '__has_trivial_constructor'
+///                   '__has_trivial_destructor'
+///                   '__has_virtual_destructor'              [TODO]
+///                   '__is_abstract'                         [TODO]
+///                   '__is_class'
+///                   '__is_empty'                            [TODO]
+///                   '__is_enum'
+///                   '__is_pod'
+///                   '__is_polymorphic'
+///                   '__is_union'
+///
+/// [GNU] binary-type-trait:
+///                   '__is_base_of'                          [TODO]
+///
+Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression,
+                                                     bool isAddressOfOperand,
+                                                     bool &NotCastExpr,
+                                                     TypeTy *TypeOfCast) {
+  OwningExprResult Res(Actions);
+  tok::TokenKind SavedKind = Tok.getKind();
+  NotCastExpr = false;
+
+  // This handles all of cast-expression, unary-expression, postfix-expression,
+  // and primary-expression.  We handle them together like this for efficiency
+  // and to simplify handling of an expression starting with a '(' token: which
+  // may be one of a parenthesized expression, cast-expression, compound literal
+  // expression, or statement expression.
+  //
+  // If the parsed tokens consist of a primary-expression, the cases below
+  // call ParsePostfixExpressionSuffix to handle the postfix expression
+  // suffixes.  Cases that cannot be followed by postfix exprs should
+  // return without invoking ParsePostfixExpressionSuffix.
+  switch (SavedKind) {
+  case tok::l_paren: {
+    // If this expression is limited to being a unary-expression, the parent can
+    // not start a cast expression.
+    ParenParseOption ParenExprType =
+      isUnaryExpression ? CompoundLiteral : CastExpr;
+    TypeTy *CastTy;
+    SourceLocation LParenLoc = Tok.getLocation();
+    SourceLocation RParenLoc;
+    
+    {
+      // The inside of the parens don't need to be a colon protected scope.
+      ColonProtectionRAIIObject X(*this, false);
+    
+      Res = ParseParenExpression(ParenExprType, false/*stopIfCastExr*/,
+                                 TypeOfCast, CastTy, RParenLoc);
+      if (Res.isInvalid()) return move(Res);
+    }
+
+    switch (ParenExprType) {
+    case SimpleExpr:   break;    // Nothing else to do.
+    case CompoundStmt: break;  // Nothing else to do.
+    case CompoundLiteral:
+      // We parsed '(' type-name ')' '{' ... '}'.  If any suffixes of
+      // postfix-expression exist, parse them now.
+      break;
+    case CastExpr:
+      // We have parsed the cast-expression and no postfix-expr pieces are
+      // following.
+      return move(Res);
+    }
+
+    // These can be followed by postfix-expr pieces.
+    return ParsePostfixExpressionSuffix(move(Res));
+  }
+
+    // primary-expression
+  case tok::numeric_constant:
+    // constant: integer-constant
+    // constant: floating-constant
+
+    Res = Actions.ActOnNumericConstant(Tok);
+    ConsumeToken();
+
+    // These can be followed by postfix-expr pieces.
+    return ParsePostfixExpressionSuffix(move(Res));
+
+  case tok::kw_true:
+  case tok::kw_false:
+    return ParseCXXBoolLiteral();
+
+  case tok::kw_nullptr:
+    return Actions.ActOnCXXNullPtrLiteral(ConsumeToken());
+
+  case tok::identifier: {      // primary-expression: identifier
+                               // unqualified-id: identifier
+                               // constant: enumeration-constant
+    // Turn a potentially qualified name into a annot_typename or
+    // annot_cxxscope if it would be valid.  This handles things like x::y, etc.
+    if (getLang().CPlusPlus) {
+      // Avoid the unnecessary parse-time lookup in the common case
+      // where the syntax forbids a type.
+      const Token &Next = NextToken();
+      if (Next.is(tok::coloncolon) ||
+          (!ColonIsSacred && Next.is(tok::colon)) ||
+          Next.is(tok::less) ||
+          Next.is(tok::l_paren)) {
+        // If TryAnnotateTypeOrScopeToken annotates the token, tail recurse.
+        if (TryAnnotateTypeOrScopeToken())
+          return ExprError();
+        if (!Tok.is(tok::identifier))
+          return ParseCastExpression(isUnaryExpression, isAddressOfOperand);
+      }
+    }
+
+    // Consume the identifier so that we can see if it is followed by a '(' or
+    // '.'.
+    IdentifierInfo &II = *Tok.getIdentifierInfo();
+    SourceLocation ILoc = ConsumeToken();
+    
+    // Support 'Class.property' and 'super.property' notation.
+    if (getLang().ObjC1 && Tok.is(tok::period) &&
+        (Actions.getTypeName(II, ILoc, CurScope) ||
+         // Allow the base to be 'super' if in an objc-method.
+         (&II == Ident_super && CurScope->isInObjcMethodScope()))) {
+      SourceLocation DotLoc = ConsumeToken();
+      
+      if (Tok.isNot(tok::identifier)) {
+        Diag(Tok, diag::err_expected_property_name);
+        return ExprError();
+      }
+      IdentifierInfo &PropertyName = *Tok.getIdentifierInfo();
+      SourceLocation PropertyLoc = ConsumeToken();
+      
+      Res = Actions.ActOnClassPropertyRefExpr(II, PropertyName,
+                                              ILoc, PropertyLoc);
+      // These can be followed by postfix-expr pieces.
+      return ParsePostfixExpressionSuffix(move(Res));
+    }
+   
+    // Function designators are allowed to be undeclared (C99 6.5.1p2), so we
+    // need to know whether or not this identifier is a function designator or
+    // not.
+    UnqualifiedId Name;
+    CXXScopeSpec ScopeSpec;
+    Name.setIdentifier(&II, ILoc);
+    Res = Actions.ActOnIdExpression(CurScope, ScopeSpec, Name, 
+                                    Tok.is(tok::l_paren), false);
+    // These can be followed by postfix-expr pieces.
+    return ParsePostfixExpressionSuffix(move(Res));
+  }
+  case tok::char_constant:     // constant: character-constant
+    Res = Actions.ActOnCharacterConstant(Tok);
+    ConsumeToken();
+    // These can be followed by postfix-expr pieces.
+    return ParsePostfixExpressionSuffix(move(Res));
+  case tok::kw___func__:       // primary-expression: __func__ [C99 6.4.2.2]
+  case tok::kw___FUNCTION__:   // primary-expression: __FUNCTION__ [GNU]
+  case tok::kw___PRETTY_FUNCTION__:  // primary-expression: __P..Y_F..N__ [GNU]
+    Res = Actions.ActOnPredefinedExpr(Tok.getLocation(), SavedKind);
+    ConsumeToken();
+    // These can be followed by postfix-expr pieces.
+    return ParsePostfixExpressionSuffix(move(Res));
+  case tok::string_literal:    // primary-expression: string-literal
+  case tok::wide_string_literal:
+    Res = ParseStringLiteralExpression();
+    if (Res.isInvalid()) return move(Res);
+    // This can be followed by postfix-expr pieces (e.g. "foo"[1]).
+    return ParsePostfixExpressionSuffix(move(Res));
+  case tok::kw___builtin_va_arg:
+  case tok::kw___builtin_offsetof:
+  case tok::kw___builtin_choose_expr:
+  case tok::kw___builtin_types_compatible_p:
+    return ParseBuiltinPrimaryExpression();
+  case tok::kw___null:
+    return Actions.ActOnGNUNullExpr(ConsumeToken());
+    break;
+  case tok::plusplus:      // unary-expression: '++' unary-expression
+  case tok::minusminus: {  // unary-expression: '--' unary-expression
+    SourceLocation SavedLoc = ConsumeToken();
+    Res = ParseCastExpression(true);
+    if (!Res.isInvalid())
+      Res = Actions.ActOnUnaryOp(CurScope, SavedLoc, SavedKind, move(Res));
+    return move(Res);
+  }
+  case tok::amp: {         // unary-expression: '&' cast-expression
+    // Special treatment because of member pointers
+    SourceLocation SavedLoc = ConsumeToken();
+    Res = ParseCastExpression(false, true);
+    if (!Res.isInvalid())
+      Res = Actions.ActOnUnaryOp(CurScope, SavedLoc, SavedKind, move(Res));
+    return move(Res);
+  }
+
+  case tok::star:          // unary-expression: '*' cast-expression
+  case tok::plus:          // unary-expression: '+' cast-expression
+  case tok::minus:         // unary-expression: '-' cast-expression
+  case tok::tilde:         // unary-expression: '~' cast-expression
+  case tok::exclaim:       // unary-expression: '!' cast-expression
+  case tok::kw___real:     // unary-expression: '__real' cast-expression [GNU]
+  case tok::kw___imag: {   // unary-expression: '__imag' cast-expression [GNU]
+    SourceLocation SavedLoc = ConsumeToken();
+    Res = ParseCastExpression(false);
+    if (!Res.isInvalid())
+      Res = Actions.ActOnUnaryOp(CurScope, SavedLoc, SavedKind, move(Res));
+    return move(Res);
+  }
+
+  case tok::kw___extension__:{//unary-expression:'__extension__' cast-expr [GNU]
+    // __extension__ silences extension warnings in the subexpression.
+    ExtensionRAIIObject O(Diags);  // Use RAII to do this.
+    SourceLocation SavedLoc = ConsumeToken();
+    Res = ParseCastExpression(false);
+    if (!Res.isInvalid())
+      Res = Actions.ActOnUnaryOp(CurScope, SavedLoc, SavedKind, move(Res));
+    return move(Res);
+  }
+  case tok::kw_sizeof:     // unary-expression: 'sizeof' unary-expression
+                           // unary-expression: 'sizeof' '(' type-name ')'
+  case tok::kw_alignof:
+  case tok::kw___alignof:  // unary-expression: '__alignof' unary-expression
+                           // unary-expression: '__alignof' '(' type-name ')'
+                           // unary-expression: 'alignof' '(' type-id ')'
+    return ParseSizeofAlignofExpression();
+  case tok::ampamp: {      // unary-expression: '&&' identifier
+    SourceLocation AmpAmpLoc = ConsumeToken();
+    if (Tok.isNot(tok::identifier))
+      return ExprError(Diag(Tok, diag::err_expected_ident));
+
+    Diag(AmpAmpLoc, diag::ext_gnu_address_of_label);
+    Res = Actions.ActOnAddrLabel(AmpAmpLoc, Tok.getLocation(),
+                                 Tok.getIdentifierInfo());
+    ConsumeToken();
+    return move(Res);
+  }
+  case tok::kw_const_cast:
+  case tok::kw_dynamic_cast:
+  case tok::kw_reinterpret_cast:
+  case tok::kw_static_cast:
+    Res = ParseCXXCasts();
+    // These can be followed by postfix-expr pieces.
+    return ParsePostfixExpressionSuffix(move(Res));
+  case tok::kw_typeid:
+    Res = ParseCXXTypeid();
+    // This can be followed by postfix-expr pieces.
+    return ParsePostfixExpressionSuffix(move(Res));
+  case tok::kw_this:
+    Res = ParseCXXThis();
+    // This can be followed by postfix-expr pieces.
+    return ParsePostfixExpressionSuffix(move(Res));
+
+  case tok::kw_char:
+  case tok::kw_wchar_t:
+  case tok::kw_char16_t:
+  case tok::kw_char32_t:
+  case tok::kw_bool:
+  case tok::kw_short:
+  case tok::kw_int:
+  case tok::kw_long:
+  case tok::kw_signed:
+  case tok::kw_unsigned:
+  case tok::kw_float:
+  case tok::kw_double:
+  case tok::kw_void:
+  case tok::kw_typename:
+  case tok::kw_typeof:
+  case tok::kw___vector:
+  case tok::annot_typename: {
+    if (!getLang().CPlusPlus) {
+      Diag(Tok, diag::err_expected_expression);
+      return ExprError();
+    }
+
+    if (SavedKind == tok::kw_typename) {
+      // postfix-expression: typename-specifier '(' expression-list[opt] ')'
+      if (TryAnnotateTypeOrScopeToken())
+        return ExprError();
+    }
+
+    // postfix-expression: simple-type-specifier '(' expression-list[opt] ')'
+    //
+    DeclSpec DS;
+    ParseCXXSimpleTypeSpecifier(DS);
+    if (Tok.isNot(tok::l_paren))
+      return ExprError(Diag(Tok, diag::err_expected_lparen_after_type)
+                         << DS.getSourceRange());
+
+    Res = ParseCXXTypeConstructExpression(DS);
+    // This can be followed by postfix-expr pieces.
+    return ParsePostfixExpressionSuffix(move(Res));
+  }
+
+  case tok::annot_cxxscope: { // [C++] id-expression: qualified-id
+    // If TryAnnotateTypeOrScopeToken annotates the token, tail recurse.
+    // (We can end up in this situation after tentative parsing.)
+    if (TryAnnotateTypeOrScopeToken())
+      return ExprError();
+    if (!Tok.is(tok::annot_cxxscope))
+      return ParseCastExpression(isUnaryExpression, isAddressOfOperand,
+                                 NotCastExpr, TypeOfCast);
+
+    Token Next = NextToken();
+    if (Next.is(tok::annot_template_id)) {
+      TemplateIdAnnotation *TemplateId
+        = static_cast<TemplateIdAnnotation *>(Next.getAnnotationValue());
+      if (TemplateId->Kind == TNK_Type_template) {
+        // We have a qualified template-id that we know refers to a
+        // type, translate it into a type and continue parsing as a
+        // cast expression.
+        CXXScopeSpec SS;
+        ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, false);
+        AnnotateTemplateIdTokenAsType(&SS);
+        return ParseCastExpression(isUnaryExpression, isAddressOfOperand,
+                                   NotCastExpr, TypeOfCast);
+      }
+    }
+
+    // Parse as an id-expression.
+    Res = ParseCXXIdExpression(isAddressOfOperand);
+    return ParsePostfixExpressionSuffix(move(Res));
+  }
+
+  case tok::annot_template_id: { // [C++]          template-id
+    TemplateIdAnnotation *TemplateId
+      = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
+    if (TemplateId->Kind == TNK_Type_template) {
+      // We have a template-id that we know refers to a type,
+      // translate it into a type and continue parsing as a cast
+      // expression.
+      AnnotateTemplateIdTokenAsType();
+      return ParseCastExpression(isUnaryExpression, isAddressOfOperand,
+                                 NotCastExpr, TypeOfCast);
+    }
+
+    // Fall through to treat the template-id as an id-expression.
+  }
+
+  case tok::kw_operator: // [C++] id-expression: operator/conversion-function-id
+    Res = ParseCXXIdExpression(isAddressOfOperand);
+    return ParsePostfixExpressionSuffix(move(Res));
+
+  case tok::coloncolon: {
+    // ::foo::bar -> global qualified name etc.   If TryAnnotateTypeOrScopeToken
+    // annotates the token, tail recurse.
+    if (TryAnnotateTypeOrScopeToken())
+      return ExprError();
+    if (!Tok.is(tok::coloncolon))
+      return ParseCastExpression(isUnaryExpression, isAddressOfOperand);
+
+    // ::new -> [C++] new-expression
+    // ::delete -> [C++] delete-expression
+    SourceLocation CCLoc = ConsumeToken();
+    if (Tok.is(tok::kw_new))
+      return ParseCXXNewExpression(true, CCLoc);
+    if (Tok.is(tok::kw_delete))
+      return ParseCXXDeleteExpression(true, CCLoc);
+
+    // This is not a type name or scope specifier, it is an invalid expression.
+    Diag(CCLoc, diag::err_expected_expression);
+    return ExprError();
+  }
+
+  case tok::kw_new: // [C++] new-expression
+    return ParseCXXNewExpression(false, Tok.getLocation());
+
+  case tok::kw_delete: // [C++] delete-expression
+    return ParseCXXDeleteExpression(false, Tok.getLocation());
+
+  case tok::kw___is_pod: // [GNU] unary-type-trait
+  case tok::kw___is_class:
+  case tok::kw___is_enum:
+  case tok::kw___is_union:
+  case tok::kw___is_empty:
+  case tok::kw___is_polymorphic:
+  case tok::kw___is_abstract:
+  case tok::kw___is_literal:
+  case tok::kw___has_trivial_constructor:
+  case tok::kw___has_trivial_copy:
+  case tok::kw___has_trivial_assign:
+  case tok::kw___has_trivial_destructor:
+    return ParseUnaryTypeTrait();
+
+  case tok::at: {
+    SourceLocation AtLoc = ConsumeToken();
+    return ParseObjCAtExpression(AtLoc);
+  }
+  case tok::caret:
+    return ParsePostfixExpressionSuffix(ParseBlockLiteralExpression());
+  case tok::code_completion:
+    Actions.CodeCompleteOrdinaryName(CurScope, Action::CCC_Expression);
+    ConsumeToken();
+    return ParseCastExpression(isUnaryExpression, isAddressOfOperand, 
+                               NotCastExpr, TypeOfCast);
+  case tok::l_square:
+    // These can be followed by postfix-expr pieces.
+    if (getLang().ObjC1)
+      return ParsePostfixExpressionSuffix(ParseObjCMessageExpression());
+    // FALL THROUGH.      
+  default:
+    NotCastExpr = true;
+    return ExprError();
+  }
+
+  // unreachable.
+  abort();
+}
+
+/// ParsePostfixExpressionSuffix - Once the leading part of a postfix-expression
+/// is parsed, this method parses any suffixes that apply.
+///
+///       postfix-expression: [C99 6.5.2]
+///         primary-expression
+///         postfix-expression '[' expression ']'
+///         postfix-expression '(' argument-expression-list[opt] ')'
+///         postfix-expression '.' identifier
+///         postfix-expression '->' identifier
+///         postfix-expression '++'
+///         postfix-expression '--'
+///         '(' type-name ')' '{' initializer-list '}'
+///         '(' type-name ')' '{' initializer-list ',' '}'
+///
+///       argument-expression-list: [C99 6.5.2]
+///         argument-expression
+///         argument-expression-list ',' assignment-expression
+///
+Parser::OwningExprResult
+Parser::ParsePostfixExpressionSuffix(OwningExprResult LHS) {
+  // Now that the primary-expression piece of the postfix-expression has been
+  // parsed, see if there are any postfix-expression pieces here.
+  SourceLocation Loc;
+  while (1) {
+    switch (Tok.getKind()) {
+    default:  // Not a postfix-expression suffix.
+      return move(LHS);
+    case tok::l_square: {  // postfix-expression: p-e '[' expression ']'
+      Loc = ConsumeBracket();
+      OwningExprResult Idx(ParseExpression());
+
+      SourceLocation RLoc = Tok.getLocation();
+
+      if (!LHS.isInvalid() && !Idx.isInvalid() && Tok.is(tok::r_square)) {
+        LHS = Actions.ActOnArraySubscriptExpr(CurScope, move(LHS), Loc,
+                                              move(Idx), RLoc);
+      } else
+        LHS = ExprError();
+
+      // Match the ']'.
+      MatchRHSPunctuation(tok::r_square, Loc);
+      break;
+    }
+
+    case tok::l_paren: {   // p-e: p-e '(' argument-expression-list[opt] ')'
+      ExprVector ArgExprs(Actions);
+      CommaLocsTy CommaLocs;
+
+      Loc = ConsumeParen();
+
+      if (Tok.is(tok::code_completion)) {
+        Actions.CodeCompleteCall(CurScope, LHS.get(), 0, 0);
+        ConsumeToken();
+      }
+      
+      if (Tok.isNot(tok::r_paren)) {
+        if (ParseExpressionList(ArgExprs, CommaLocs, &Action::CodeCompleteCall,
+                                LHS.get())) {
+          SkipUntil(tok::r_paren);
+          return ExprError();
+        }
+      }
+
+      // Match the ')'.
+      if (Tok.isNot(tok::r_paren)) {
+        MatchRHSPunctuation(tok::r_paren, Loc);
+        return ExprError();
+      }
+
+      if (!LHS.isInvalid()) {
+        assert((ArgExprs.size() == 0 || ArgExprs.size()-1 == CommaLocs.size())&&
+               "Unexpected number of commas!");
+        LHS = Actions.ActOnCallExpr(CurScope, move(LHS), Loc,
+                                    move_arg(ArgExprs), CommaLocs.data(),
+                                    Tok.getLocation());
+      }
+
+      ConsumeParen();
+      break;
+    }
+    case tok::arrow:
+    case tok::period: {
+      // postfix-expression: p-e '->' template[opt] id-expression
+      // postfix-expression: p-e '.' template[opt] id-expression
+      tok::TokenKind OpKind = Tok.getKind();
+      SourceLocation OpLoc = ConsumeToken();  // Eat the "." or "->" token.
+
+      CXXScopeSpec SS;
+      Action::TypeTy *ObjectType = 0;
+      bool MayBePseudoDestructor = false;
+      if (getLang().CPlusPlus && !LHS.isInvalid()) {
+        LHS = Actions.ActOnStartCXXMemberReference(CurScope, move(LHS),
+                                                   OpLoc, OpKind, ObjectType,
+                                                   MayBePseudoDestructor);
+        if (LHS.isInvalid())
+          break;
+
+        ParseOptionalCXXScopeSpecifier(SS, ObjectType, false,
+                                       &MayBePseudoDestructor);
+      }
+
+      if (Tok.is(tok::code_completion)) {
+        // Code completion for a member access expression.
+        Actions.CodeCompleteMemberReferenceExpr(CurScope, LHS.get(),
+                                                OpLoc, OpKind == tok::arrow);
+        
+        ConsumeToken();
+      }
+      
+      if (MayBePseudoDestructor) {
+        LHS = ParseCXXPseudoDestructor(move(LHS), OpLoc, OpKind, SS, 
+                                       ObjectType);
+        break;
+      }
+
+      // Either the action has told is that this cannot be a
+      // pseudo-destructor expression (based on the type of base
+      // expression), or we didn't see a '~' in the right place. We
+      // can still parse a destructor name here, but in that case it
+      // names a real destructor.
+      UnqualifiedId Name;
+      if (ParseUnqualifiedId(SS, 
+                             /*EnteringContext=*/false, 
+                             /*AllowDestructorName=*/true,
+                             /*AllowConstructorName=*/false, 
+                             ObjectType,
+                             Name))
+        return ExprError();
+      
+      if (!LHS.isInvalid())
+        LHS = Actions.ActOnMemberAccessExpr(CurScope, move(LHS), OpLoc, 
+                                            OpKind, SS, Name, ObjCImpDecl,
+                                            Tok.is(tok::l_paren));
+      break;
+    }
+    case tok::plusplus:    // postfix-expression: postfix-expression '++'
+    case tok::minusminus:  // postfix-expression: postfix-expression '--'
+      if (!LHS.isInvalid()) {
+        LHS = Actions.ActOnPostfixUnaryOp(CurScope, Tok.getLocation(),
+                                          Tok.getKind(), move(LHS));
+      }
+      ConsumeToken();
+      break;
+    }
+  }
+}
+
+/// ParseExprAfterTypeofSizeofAlignof - We parsed a typeof/sizeof/alignof and
+/// we are at the start of an expression or a parenthesized type-id.
+/// OpTok is the operand token (typeof/sizeof/alignof). Returns the expression
+/// (isCastExpr == false) or the type (isCastExpr == true).
+///
+///       unary-expression:  [C99 6.5.3]
+///         'sizeof' unary-expression
+///         'sizeof' '(' type-name ')'
+/// [GNU]   '__alignof' unary-expression
+/// [GNU]   '__alignof' '(' type-name ')'
+/// [C++0x] 'alignof' '(' type-id ')'
+///
+/// [GNU]   typeof-specifier:
+///           typeof ( expressions )
+///           typeof ( type-name )
+/// [GNU/C++] typeof unary-expression
+///
+Parser::OwningExprResult
+Parser::ParseExprAfterTypeofSizeofAlignof(const Token &OpTok,
+                                          bool &isCastExpr,
+                                          TypeTy *&CastTy,
+                                          SourceRange &CastRange) {
+
+  assert((OpTok.is(tok::kw_typeof)    || OpTok.is(tok::kw_sizeof) ||
+          OpTok.is(tok::kw___alignof) || OpTok.is(tok::kw_alignof)) &&
+          "Not a typeof/sizeof/alignof expression!");
+
+  OwningExprResult Operand(Actions);
+
+  // If the operand doesn't start with an '(', it must be an expression.
+  if (Tok.isNot(tok::l_paren)) {
+    isCastExpr = false;
+    if (OpTok.is(tok::kw_typeof) && !getLang().CPlusPlus) {
+      Diag(Tok,diag::err_expected_lparen_after_id) << OpTok.getIdentifierInfo();
+      return ExprError();
+    }
+
+    // C++0x [expr.sizeof]p1:
+    //   [...] The operand is either an expression, which is an unevaluated
+    //   operand (Clause 5) [...]
+    //
+    // The GNU typeof and alignof extensions also behave as unevaluated
+    // operands.
+    EnterExpressionEvaluationContext Unevaluated(Actions,
+                                                 Action::Unevaluated);
+    Operand = ParseCastExpression(true/*isUnaryExpression*/);
+  } else {
+    // If it starts with a '(', we know that it is either a parenthesized
+    // type-name, or it is a unary-expression that starts with a compound
+    // literal, or starts with a primary-expression that is a parenthesized
+    // expression.
+    ParenParseOption ExprType = CastExpr;
+    SourceLocation LParenLoc = Tok.getLocation(), RParenLoc;
+
+    // C++0x [expr.sizeof]p1:
+    //   [...] The operand is either an expression, which is an unevaluated
+    //   operand (Clause 5) [...]
+    //
+    // The GNU typeof and alignof extensions also behave as unevaluated
+    // operands.
+    EnterExpressionEvaluationContext Unevaluated(Actions,
+                                                 Action::Unevaluated);
+    Operand = ParseParenExpression(ExprType, true/*stopIfCastExpr*/, 
+                                   0/*TypeOfCast*/,
+                                   CastTy, RParenLoc);
+    CastRange = SourceRange(LParenLoc, RParenLoc);
+
+    // If ParseParenExpression parsed a '(typename)' sequence only, then this is
+    // a type.
+    if (ExprType == CastExpr) {
+      isCastExpr = true;
+      return ExprEmpty();
+    }
+
+    // If this is a parenthesized expression, it is the start of a
+    // unary-expression, but doesn't include any postfix pieces.  Parse these
+    // now if present.
+    Operand = ParsePostfixExpressionSuffix(move(Operand));
+  }
+
+  // If we get here, the operand to the typeof/sizeof/alignof was an expresion.
+  isCastExpr = false;
+  return move(Operand);
+}
+
+
+/// ParseSizeofAlignofExpression - Parse a sizeof or alignof expression.
+///       unary-expression:  [C99 6.5.3]
+///         'sizeof' unary-expression
+///         'sizeof' '(' type-name ')'
+/// [GNU]   '__alignof' unary-expression
+/// [GNU]   '__alignof' '(' type-name ')'
+/// [C++0x] 'alignof' '(' type-id ')'
+Parser::OwningExprResult Parser::ParseSizeofAlignofExpression() {
+  assert((Tok.is(tok::kw_sizeof) || Tok.is(tok::kw___alignof)
+          || Tok.is(tok::kw_alignof)) &&
+         "Not a sizeof/alignof expression!");
+  Token OpTok = Tok;
+  ConsumeToken();
+
+  bool isCastExpr;
+  TypeTy *CastTy;
+  SourceRange CastRange;
+  OwningExprResult Operand = ParseExprAfterTypeofSizeofAlignof(OpTok,
+                                                               isCastExpr,
+                                                               CastTy,
+                                                               CastRange);
+
+  if (isCastExpr)
+    return Actions.ActOnSizeOfAlignOfExpr(OpTok.getLocation(),
+                                          OpTok.is(tok::kw_sizeof),
+                                          /*isType=*/true, CastTy,
+                                          CastRange);
+
+  // If we get here, the operand to the sizeof/alignof was an expresion.
+  if (!Operand.isInvalid())
+    Operand = Actions.ActOnSizeOfAlignOfExpr(OpTok.getLocation(),
+                                             OpTok.is(tok::kw_sizeof),
+                                             /*isType=*/false,
+                                             Operand.release(), CastRange);
+  return move(Operand);
+}
+
+/// ParseBuiltinPrimaryExpression
+///
+///       primary-expression: [C99 6.5.1]
+/// [GNU]   '__builtin_va_arg' '(' assignment-expression ',' type-name ')'
+/// [GNU]   '__builtin_offsetof' '(' type-name ',' offsetof-member-designator')'
+/// [GNU]   '__builtin_choose_expr' '(' assign-expr ',' assign-expr ','
+///                                     assign-expr ')'
+/// [GNU]   '__builtin_types_compatible_p' '(' type-name ',' type-name ')'
+///
+/// [GNU] offsetof-member-designator:
+/// [GNU]   identifier
+/// [GNU]   offsetof-member-designator '.' identifier
+/// [GNU]   offsetof-member-designator '[' expression ']'
+///
+Parser::OwningExprResult Parser::ParseBuiltinPrimaryExpression() {
+  OwningExprResult Res(Actions);
+  const IdentifierInfo *BuiltinII = Tok.getIdentifierInfo();
+
+  tok::TokenKind T = Tok.getKind();
+  SourceLocation StartLoc = ConsumeToken();   // Eat the builtin identifier.
+
+  // All of these start with an open paren.
+  if (Tok.isNot(tok::l_paren))
+    return ExprError(Diag(Tok, diag::err_expected_lparen_after_id)
+                       << BuiltinII);
+
+  SourceLocation LParenLoc = ConsumeParen();
+  // TODO: Build AST.
+
+  switch (T) {
+  default: assert(0 && "Not a builtin primary expression!");
+  case tok::kw___builtin_va_arg: {
+    OwningExprResult Expr(ParseAssignmentExpression());
+    if (Expr.isInvalid()) {
+      SkipUntil(tok::r_paren);
+      return ExprError();
+    }
+
+    if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren))
+      return ExprError();
+
+    TypeResult Ty = ParseTypeName();
+
+    if (Tok.isNot(tok::r_paren)) {
+      Diag(Tok, diag::err_expected_rparen);
+      return ExprError();
+    }
+    if (Ty.isInvalid())
+      Res = ExprError();
+    else
+      Res = Actions.ActOnVAArg(StartLoc, move(Expr), Ty.get(), ConsumeParen());
+    break;
+  }
+  case tok::kw___builtin_offsetof: {
+    SourceLocation TypeLoc = Tok.getLocation();
+    TypeResult Ty = ParseTypeName();
+    if (Ty.isInvalid()) {
+      SkipUntil(tok::r_paren);
+      return ExprError();
+    }
+
+    if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren))
+      return ExprError();
+
+    // We must have at least one identifier here.
+    if (Tok.isNot(tok::identifier)) {
+      Diag(Tok, diag::err_expected_ident);
+      SkipUntil(tok::r_paren);
+      return ExprError();
+    }
+
+    // Keep track of the various subcomponents we see.
+    llvm::SmallVector<Action::OffsetOfComponent, 4> Comps;
+
+    Comps.push_back(Action::OffsetOfComponent());
+    Comps.back().isBrackets = false;
+    Comps.back().U.IdentInfo = Tok.getIdentifierInfo();
+    Comps.back().LocStart = Comps.back().LocEnd = ConsumeToken();
+
+    // FIXME: This loop leaks the index expressions on error.
+    while (1) {
+      if (Tok.is(tok::period)) {
+        // offsetof-member-designator: offsetof-member-designator '.' identifier
+        Comps.push_back(Action::OffsetOfComponent());
+        Comps.back().isBrackets = false;
+        Comps.back().LocStart = ConsumeToken();
+
+        if (Tok.isNot(tok::identifier)) {
+          Diag(Tok, diag::err_expected_ident);
+          SkipUntil(tok::r_paren);
+          return ExprError();
+        }
+        Comps.back().U.IdentInfo = Tok.getIdentifierInfo();
+        Comps.back().LocEnd = ConsumeToken();
+
+      } else if (Tok.is(tok::l_square)) {
+        // offsetof-member-designator: offsetof-member-design '[' expression ']'
+        Comps.push_back(Action::OffsetOfComponent());
+        Comps.back().isBrackets = true;
+        Comps.back().LocStart = ConsumeBracket();
+        Res = ParseExpression();
+        if (Res.isInvalid()) {
+          SkipUntil(tok::r_paren);
+          return move(Res);
+        }
+        Comps.back().U.E = Res.release();
+
+        Comps.back().LocEnd =
+          MatchRHSPunctuation(tok::r_square, Comps.back().LocStart);
+      } else {
+        if (Tok.isNot(tok::r_paren)) {
+          MatchRHSPunctuation(tok::r_paren, LParenLoc);
+          Res = ExprError();
+        } else if (Ty.isInvalid()) {
+          Res = ExprError();
+        } else {
+          Res = Actions.ActOnBuiltinOffsetOf(CurScope, StartLoc, TypeLoc,
+                                             Ty.get(), &Comps[0],
+                                             Comps.size(), ConsumeParen());
+        }
+        break;
+      }
+    }
+    break;
+  }
+  case tok::kw___builtin_choose_expr: {
+    OwningExprResult Cond(ParseAssignmentExpression());
+    if (Cond.isInvalid()) {
+      SkipUntil(tok::r_paren);
+      return move(Cond);
+    }
+    if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren))
+      return ExprError();
+
+    OwningExprResult Expr1(ParseAssignmentExpression());
+    if (Expr1.isInvalid()) {
+      SkipUntil(tok::r_paren);
+      return move(Expr1);
+    }
+    if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren))
+      return ExprError();
+
+    OwningExprResult Expr2(ParseAssignmentExpression());
+    if (Expr2.isInvalid()) {
+      SkipUntil(tok::r_paren);
+      return move(Expr2);
+    }
+    if (Tok.isNot(tok::r_paren)) {
+      Diag(Tok, diag::err_expected_rparen);
+      return ExprError();
+    }
+    Res = Actions.ActOnChooseExpr(StartLoc, move(Cond), move(Expr1),
+                                  move(Expr2), ConsumeParen());
+    break;
+  }
+  case tok::kw___builtin_types_compatible_p:
+    TypeResult Ty1 = ParseTypeName();
+
+    if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren))
+      return ExprError();
+
+    TypeResult Ty2 = ParseTypeName();
+
+    if (Tok.isNot(tok::r_paren)) {
+      Diag(Tok, diag::err_expected_rparen);
+      return ExprError();
+    }
+
+    if (Ty1.isInvalid() || Ty2.isInvalid())
+      Res = ExprError();
+    else
+      Res = Actions.ActOnTypesCompatibleExpr(StartLoc, Ty1.get(), Ty2.get(),
+                                             ConsumeParen());
+    break;
+  }
+
+  // These can be followed by postfix-expr pieces because they are
+  // primary-expressions.
+  return ParsePostfixExpressionSuffix(move(Res));
+}
+
+/// ParseParenExpression - This parses the unit that starts with a '(' token,
+/// based on what is allowed by ExprType.  The actual thing parsed is returned
+/// in ExprType. If stopIfCastExpr is true, it will only return the parsed type,
+/// not the parsed cast-expression.
+///
+///       primary-expression: [C99 6.5.1]
+///         '(' expression ')'
+/// [GNU]   '(' compound-statement ')'      (if !ParenExprOnly)
+///       postfix-expression: [C99 6.5.2]
+///         '(' type-name ')' '{' initializer-list '}'
+///         '(' type-name ')' '{' initializer-list ',' '}'
+///       cast-expression: [C99 6.5.4]
+///         '(' type-name ')' cast-expression
+///
+Parser::OwningExprResult
+Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
+                             TypeTy *TypeOfCast, TypeTy *&CastTy,
+                             SourceLocation &RParenLoc) {
+  assert(Tok.is(tok::l_paren) && "Not a paren expr!");
+  GreaterThanIsOperatorScope G(GreaterThanIsOperator, true);
+  SourceLocation OpenLoc = ConsumeParen();
+  OwningExprResult Result(Actions, true);
+  bool isAmbiguousTypeId;
+  CastTy = 0;
+
+  if (ExprType >= CompoundStmt && Tok.is(tok::l_brace)) {
+    Diag(Tok, diag::ext_gnu_statement_expr);
+    OwningStmtResult Stmt(ParseCompoundStatement(0, true));
+    ExprType = CompoundStmt;
+
+    // If the substmt parsed correctly, build the AST node.
+    if (!Stmt.isInvalid() && Tok.is(tok::r_paren))
+      Result = Actions.ActOnStmtExpr(OpenLoc, move(Stmt), Tok.getLocation());
+
+  } else if (ExprType >= CompoundLiteral &&
+             isTypeIdInParens(isAmbiguousTypeId)) {
+
+    // Otherwise, this is a compound literal expression or cast expression.
+
+    // In C++, if the type-id is ambiguous we disambiguate based on context.
+    // If stopIfCastExpr is true the context is a typeof/sizeof/alignof
+    // in which case we should treat it as type-id.
+    // if stopIfCastExpr is false, we need to determine the context past the
+    // parens, so we defer to ParseCXXAmbiguousParenExpression for that.
+    if (isAmbiguousTypeId && !stopIfCastExpr)
+      return ParseCXXAmbiguousParenExpression(ExprType, CastTy,
+                                              OpenLoc, RParenLoc);
+
+    TypeResult Ty = ParseTypeName();
+
+    // Match the ')'.
+    if (Tok.is(tok::r_paren))
+      RParenLoc = ConsumeParen();
+    else
+      MatchRHSPunctuation(tok::r_paren, OpenLoc);
+
+    if (Tok.is(tok::l_brace)) {
+      ExprType = CompoundLiteral;
+      return ParseCompoundLiteralExpression(Ty.get(), OpenLoc, RParenLoc);
+    }
+
+    if (ExprType == CastExpr) {
+      // We parsed '(' type-name ')' and the thing after it wasn't a '{'.
+
+      if (Ty.isInvalid())
+        return ExprError();
+
+      CastTy = Ty.get();
+
+      // Note that this doesn't parse the subsequent cast-expression, it just
+      // returns the parsed type to the callee.
+      if (stopIfCastExpr)
+        return OwningExprResult(Actions);
+      
+      // Reject the cast of super idiom in ObjC.
+      if (Tok.is(tok::identifier) && getLang().ObjC1 &&
+          Tok.getIdentifierInfo() == Ident_super && 
+          CurScope->isInObjcMethodScope() &&
+          GetLookAheadToken(1).isNot(tok::period)) {
+        Diag(Tok.getLocation(), diag::err_illegal_super_cast)
+          << SourceRange(OpenLoc, RParenLoc);
+        return ExprError();
+      }
+
+      // Parse the cast-expression that follows it next.
+      // TODO: For cast expression with CastTy.
+      Result = ParseCastExpression(false, false, CastTy);
+      if (!Result.isInvalid())
+        Result = Actions.ActOnCastExpr(CurScope, OpenLoc, CastTy, RParenLoc,
+                                       move(Result));
+      return move(Result);
+    }
+
+    Diag(Tok, diag::err_expected_lbrace_in_compound_literal);
+    return ExprError();
+  } else if (TypeOfCast) {
+    // Parse the expression-list.
+    ExprVector ArgExprs(Actions);
+    CommaLocsTy CommaLocs;
+
+    if (!ParseExpressionList(ArgExprs, CommaLocs)) {
+      ExprType = SimpleExpr;
+      Result = Actions.ActOnParenOrParenListExpr(OpenLoc, Tok.getLocation(),
+                                          move_arg(ArgExprs), TypeOfCast);
+    }
+  } else {
+    Result = ParseExpression();
+    ExprType = SimpleExpr;
+    if (!Result.isInvalid() && Tok.is(tok::r_paren))
+      Result = Actions.ActOnParenExpr(OpenLoc, Tok.getLocation(), move(Result));
+  }
+
+  // Match the ')'.
+  if (Result.isInvalid()) {
+    SkipUntil(tok::r_paren);
+    return ExprError();
+  }
+
+  if (Tok.is(tok::r_paren))
+    RParenLoc = ConsumeParen();
+  else
+    MatchRHSPunctuation(tok::r_paren, OpenLoc);
+
+  return move(Result);
+}
+
+/// ParseCompoundLiteralExpression - We have parsed the parenthesized type-name
+/// and we are at the left brace.
+///
+///       postfix-expression: [C99 6.5.2]
+///         '(' type-name ')' '{' initializer-list '}'
+///         '(' type-name ')' '{' initializer-list ',' '}'
+///
+Parser::OwningExprResult
+Parser::ParseCompoundLiteralExpression(TypeTy *Ty,
+                                       SourceLocation LParenLoc,
+                                       SourceLocation RParenLoc) {
+  assert(Tok.is(tok::l_brace) && "Not a compound literal!");
+  if (!getLang().C99)   // Compound literals don't exist in C90.
+    Diag(LParenLoc, diag::ext_c99_compound_literal);
+  OwningExprResult Result = ParseInitializer();
+  if (!Result.isInvalid() && Ty)
+    return Actions.ActOnCompoundLiteral(LParenLoc, Ty, RParenLoc, move(Result));
+  return move(Result);
+}
+
+/// ParseStringLiteralExpression - This handles the various token types that
+/// form string literals, and also handles string concatenation [C99 5.1.1.2,
+/// translation phase #6].
+///
+///       primary-expression: [C99 6.5.1]
+///         string-literal
+Parser::OwningExprResult Parser::ParseStringLiteralExpression() {
+  assert(isTokenStringLiteral() && "Not a string literal!");
+
+  // String concat.  Note that keywords like __func__ and __FUNCTION__ are not
+  // considered to be strings for concatenation purposes.
+  llvm::SmallVector<Token, 4> StringToks;
+
+  do {
+    StringToks.push_back(Tok);
+    ConsumeStringToken();
+  } while (isTokenStringLiteral());
+
+  // Pass the set of string tokens, ready for concatenation, to the actions.
+  return Actions.ActOnStringLiteral(&StringToks[0], StringToks.size());
+}
+
+/// ParseExpressionList - Used for C/C++ (argument-)expression-list.
+///
+///       argument-expression-list:
+///         assignment-expression
+///         argument-expression-list , assignment-expression
+///
+/// [C++] expression-list:
+/// [C++]   assignment-expression
+/// [C++]   expression-list , assignment-expression
+///
+bool Parser::ParseExpressionList(ExprListTy &Exprs, CommaLocsTy &CommaLocs,
+                                 void (Action::*Completer)(Scope *S, 
+                                                           void *Data,
+                                                           ExprTy **Args,
+                                                           unsigned NumArgs),
+                                 void *Data) {
+  while (1) {
+    if (Tok.is(tok::code_completion)) {
+      if (Completer)
+        (Actions.*Completer)(CurScope, Data, Exprs.data(), Exprs.size());
+      ConsumeToken();
+    }
+    
+    OwningExprResult Expr(ParseAssignmentExpression());
+    if (Expr.isInvalid())
+      return true;
+
+    Exprs.push_back(Expr.release());
+
+    if (Tok.isNot(tok::comma))
+      return false;
+    // Move to the next argument, remember where the comma was.
+    CommaLocs.push_back(ConsumeToken());
+  }
+}
+
+/// ParseBlockId - Parse a block-id, which roughly looks like int (int x).
+///
+/// [clang] block-id:
+/// [clang]   specifier-qualifier-list block-declarator
+///
+void Parser::ParseBlockId() {
+  // Parse the specifier-qualifier-list piece.
+  DeclSpec DS;
+  ParseSpecifierQualifierList(DS);
+
+  // Parse the block-declarator.
+  Declarator DeclaratorInfo(DS, Declarator::BlockLiteralContext);
+  ParseDeclarator(DeclaratorInfo);
+
+  // We do this for: ^ __attribute__((noreturn)) {, as DS has the attributes.
+  DeclaratorInfo.AddAttributes(DS.TakeAttributes(),
+                               SourceLocation());
+
+  if (Tok.is(tok::kw___attribute)) {
+    SourceLocation Loc;
+    AttributeList *AttrList = ParseGNUAttributes(&Loc);
+    DeclaratorInfo.AddAttributes(AttrList, Loc);
+  }
+
+  // Inform sema that we are starting a block.
+  Actions.ActOnBlockArguments(DeclaratorInfo, CurScope);
+}
+
+/// ParseBlockLiteralExpression - Parse a block literal, which roughly looks
+/// like ^(int x){ return x+1; }
+///
+///         block-literal:
+/// [clang]   '^' block-args[opt] compound-statement
+/// [clang]   '^' block-id compound-statement
+/// [clang] block-args:
+/// [clang]   '(' parameter-list ')'
+///
+Parser::OwningExprResult Parser::ParseBlockLiteralExpression() {
+  assert(Tok.is(tok::caret) && "block literal starts with ^");
+  SourceLocation CaretLoc = ConsumeToken();
+
+  PrettyStackTraceLoc CrashInfo(PP.getSourceManager(), CaretLoc,
+                                "block literal parsing");
+
+  // Enter a scope to hold everything within the block.  This includes the
+  // argument decls, decls within the compound expression, etc.  This also
+  // allows determining whether a variable reference inside the block is
+  // within or outside of the block.
+  ParseScope BlockScope(this, Scope::BlockScope | Scope::FnScope |
+                              Scope::BreakScope | Scope::ContinueScope |
+                              Scope::DeclScope);
+
+  // Inform sema that we are starting a block.
+  Actions.ActOnBlockStart(CaretLoc, CurScope);
+
+  // Parse the return type if present.
+  DeclSpec DS;
+  Declarator ParamInfo(DS, Declarator::BlockLiteralContext);
+  // FIXME: Since the return type isn't actually parsed, it can't be used to
+  // fill ParamInfo with an initial valid range, so do it manually.
+  ParamInfo.SetSourceRange(SourceRange(Tok.getLocation(), Tok.getLocation()));
+
+  // If this block has arguments, parse them.  There is no ambiguity here with
+  // the expression case, because the expression case requires a parameter list.
+  if (Tok.is(tok::l_paren)) {
+    ParseParenDeclarator(ParamInfo);
+    // Parse the pieces after the identifier as if we had "int(...)".
+    // SetIdentifier sets the source range end, but in this case we're past
+    // that location.
+    SourceLocation Tmp = ParamInfo.getSourceRange().getEnd();
+    ParamInfo.SetIdentifier(0, CaretLoc);
+    ParamInfo.SetRangeEnd(Tmp);
+    if (ParamInfo.isInvalidType()) {
+      // If there was an error parsing the arguments, they may have
+      // tried to use ^(x+y) which requires an argument list.  Just
+      // skip the whole block literal.
+      Actions.ActOnBlockError(CaretLoc, CurScope);
+      return ExprError();
+    }
+
+    if (Tok.is(tok::kw___attribute)) {
+      SourceLocation Loc;
+      AttributeList *AttrList = ParseGNUAttributes(&Loc);
+      ParamInfo.AddAttributes(AttrList, Loc);
+    }
+
+    // Inform sema that we are starting a block.
+    Actions.ActOnBlockArguments(ParamInfo, CurScope);
+  } else if (!Tok.is(tok::l_brace)) {
+    ParseBlockId();
+  } else {
+    // Otherwise, pretend we saw (void).
+    ParamInfo.AddTypeInfo(DeclaratorChunk::getFunction(true, false,
+                                                       SourceLocation(),
+                                                       0, 0, 0,
+                                                       false, SourceLocation(),
+                                                       false, 0, 0, 0,
+                                                       CaretLoc, CaretLoc,
+                                                       ParamInfo),
+                          CaretLoc);
+
+    if (Tok.is(tok::kw___attribute)) {
+      SourceLocation Loc;
+      AttributeList *AttrList = ParseGNUAttributes(&Loc);
+      ParamInfo.AddAttributes(AttrList, Loc);
+    }
+
+    // Inform sema that we are starting a block.
+    Actions.ActOnBlockArguments(ParamInfo, CurScope);
+  }
+
+
+  OwningExprResult Result(Actions, true);
+  if (!Tok.is(tok::l_brace)) {
+    // Saw something like: ^expr
+    Diag(Tok, diag::err_expected_expression);
+    Actions.ActOnBlockError(CaretLoc, CurScope);
+    return ExprError();
+  }
+
+  OwningStmtResult Stmt(ParseCompoundStatementBody());
+  if (!Stmt.isInvalid())
+    Result = Actions.ActOnBlockStmtExpr(CaretLoc, move(Stmt), CurScope);
+  else
+    Actions.ActOnBlockError(CaretLoc, CurScope);
+  return move(Result);
+}
diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp
new file mode 100644
index 0000000..146762b
--- /dev/null
+++ b/lib/Parse/ParseExprCXX.cpp
@@ -0,0 +1,1823 @@
+//===--- ParseExprCXX.cpp - C++ Expression Parsing ------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Expression parsing implementation for C++.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Parse/ParseDiagnostic.h"
+#include "clang/Parse/Parser.h"
+#include "clang/Parse/DeclSpec.h"
+#include "clang/Parse/Template.h"
+#include "llvm/Support/ErrorHandling.h"
+
+using namespace clang;
+
+/// \brief Parse global scope or nested-name-specifier if present.
+///
+/// Parses a C++ global scope specifier ('::') or nested-name-specifier (which
+/// may be preceded by '::'). Note that this routine will not parse ::new or
+/// ::delete; it will just leave them in the token stream.
+///
+///       '::'[opt] nested-name-specifier
+///       '::'
+///
+///       nested-name-specifier:
+///         type-name '::'
+///         namespace-name '::'
+///         nested-name-specifier identifier '::'
+///         nested-name-specifier 'template'[opt] simple-template-id '::'
+///
+///
+/// \param SS the scope specifier that will be set to the parsed
+/// nested-name-specifier (or empty)
+///
+/// \param ObjectType if this nested-name-specifier is being parsed following
+/// the "." or "->" of a member access expression, this parameter provides the
+/// type of the object whose members are being accessed.
+///
+/// \param EnteringContext whether we will be entering into the context of
+/// the nested-name-specifier after parsing it.
+///
+/// \param MayBePseudoDestructor When non-NULL, points to a flag that
+/// indicates whether this nested-name-specifier may be part of a
+/// pseudo-destructor name. In this case, the flag will be set false
+/// if we don't actually end up parsing a destructor name. Moreorover,
+/// if we do end up determining that we are parsing a destructor name,
+/// the last component of the nested-name-specifier is not parsed as
+/// part of the scope specifier.
+
+/// member access expression, e.g., the \p T:: in \p p->T::m.
+///
+/// \returns true if there was an error parsing a scope specifier
+bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS,
+                                            Action::TypeTy *ObjectType,
+                                            bool EnteringContext,
+                                            bool *MayBePseudoDestructor) {
+  assert(getLang().CPlusPlus &&
+         "Call sites of this function should be guarded by checking for C++");
+
+  if (Tok.is(tok::annot_cxxscope)) {
+    SS.setScopeRep(Tok.getAnnotationValue());
+    SS.setRange(Tok.getAnnotationRange());
+    ConsumeToken();
+    return false;
+  }
+
+  bool HasScopeSpecifier = false;
+
+  if (Tok.is(tok::coloncolon)) {
+    // ::new and ::delete aren't nested-name-specifiers.
+    tok::TokenKind NextKind = NextToken().getKind();
+    if (NextKind == tok::kw_new || NextKind == tok::kw_delete)
+      return false;
+
+    // '::' - Global scope qualifier.
+    SourceLocation CCLoc = ConsumeToken();
+    SS.setBeginLoc(CCLoc);
+    SS.setScopeRep(Actions.ActOnCXXGlobalScopeSpecifier(CurScope, CCLoc));
+    SS.setEndLoc(CCLoc);
+    HasScopeSpecifier = true;
+  }
+
+  bool CheckForDestructor = false;
+  if (MayBePseudoDestructor && *MayBePseudoDestructor) {
+    CheckForDestructor = true;
+    *MayBePseudoDestructor = false;
+  }
+
+  while (true) {
+    if (HasScopeSpecifier) {
+      // C++ [basic.lookup.classref]p5:
+      //   If the qualified-id has the form
+      //
+      //       ::class-name-or-namespace-name::...
+      //
+      //   the class-name-or-namespace-name is looked up in global scope as a
+      //   class-name or namespace-name.
+      //
+      // To implement this, we clear out the object type as soon as we've
+      // seen a leading '::' or part of a nested-name-specifier.
+      ObjectType = 0;
+      
+      if (Tok.is(tok::code_completion)) {
+        // Code completion for a nested-name-specifier, where the code
+        // code completion token follows the '::'.
+        Actions.CodeCompleteQualifiedId(CurScope, SS, EnteringContext);
+        ConsumeToken();
+      }
+    }
+
+    // nested-name-specifier:
+    //   nested-name-specifier 'template'[opt] simple-template-id '::'
+
+    // Parse the optional 'template' keyword, then make sure we have
+    // 'identifier <' after it.
+    if (Tok.is(tok::kw_template)) {
+      // If we don't have a scope specifier or an object type, this isn't a
+      // nested-name-specifier, since they aren't allowed to start with
+      // 'template'.
+      if (!HasScopeSpecifier && !ObjectType)
+        break;
+
+      TentativeParsingAction TPA(*this);
+      SourceLocation TemplateKWLoc = ConsumeToken();
+      
+      UnqualifiedId TemplateName;
+      if (Tok.is(tok::identifier)) {
+        // Consume the identifier.
+        TemplateName.setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
+        ConsumeToken();
+      } else if (Tok.is(tok::kw_operator)) {
+        if (ParseUnqualifiedIdOperator(SS, EnteringContext, ObjectType, 
+                                       TemplateName)) {
+          TPA.Commit();
+          break;
+        }
+        
+        if (TemplateName.getKind() != UnqualifiedId::IK_OperatorFunctionId &&
+            TemplateName.getKind() != UnqualifiedId::IK_LiteralOperatorId) {
+          Diag(TemplateName.getSourceRange().getBegin(),
+               diag::err_id_after_template_in_nested_name_spec)
+            << TemplateName.getSourceRange();
+          TPA.Commit();
+          break;
+        }
+      } else {
+        TPA.Revert();
+        break;
+      }
+
+      // If the next token is not '<', we have a qualified-id that refers
+      // to a template name, such as T::template apply, but is not a 
+      // template-id.
+      if (Tok.isNot(tok::less)) {
+        TPA.Revert();
+        break;
+      }        
+      
+      // Commit to parsing the template-id.
+      TPA.Commit();
+      TemplateTy Template
+        = Actions.ActOnDependentTemplateName(TemplateKWLoc, SS, TemplateName,
+                                             ObjectType, EnteringContext);
+      if (!Template)
+        return true;
+      if (AnnotateTemplateIdToken(Template, TNK_Dependent_template_name,
+                                  &SS, TemplateName, TemplateKWLoc, false))
+        return true;
+
+      continue;
+    }
+
+    if (Tok.is(tok::annot_template_id) && NextToken().is(tok::coloncolon)) {
+      // We have
+      //
+      //   simple-template-id '::'
+      //
+      // So we need to check whether the simple-template-id is of the
+      // right kind (it should name a type or be dependent), and then
+      // convert it into a type within the nested-name-specifier.
+      TemplateIdAnnotation *TemplateId
+        = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
+      if (CheckForDestructor && GetLookAheadToken(2).is(tok::tilde)) {
+        *MayBePseudoDestructor = true;
+        return false;
+      }
+
+      if (TemplateId->Kind == TNK_Type_template ||
+          TemplateId->Kind == TNK_Dependent_template_name) {
+        AnnotateTemplateIdTokenAsType(&SS);
+
+        assert(Tok.is(tok::annot_typename) &&
+               "AnnotateTemplateIdTokenAsType isn't working");
+        Token TypeToken = Tok;
+        ConsumeToken();
+        assert(Tok.is(tok::coloncolon) && "NextToken() not working properly!");
+        SourceLocation CCLoc = ConsumeToken();
+
+        if (!HasScopeSpecifier) {
+          SS.setBeginLoc(TypeToken.getLocation());
+          HasScopeSpecifier = true;
+        }
+
+        if (TypeToken.getAnnotationValue())
+          SS.setScopeRep(
+            Actions.ActOnCXXNestedNameSpecifier(CurScope, SS,
+                                                TypeToken.getAnnotationValue(),
+                                                TypeToken.getAnnotationRange(),
+                                                CCLoc));
+        else
+          SS.setScopeRep(0);
+        SS.setEndLoc(CCLoc);
+        continue;
+      }
+
+      assert(false && "FIXME: Only type template names supported here");
+    }
+
+
+    // The rest of the nested-name-specifier possibilities start with
+    // tok::identifier.
+    if (Tok.isNot(tok::identifier))
+      break;
+
+    IdentifierInfo &II = *Tok.getIdentifierInfo();
+
+    // nested-name-specifier:
+    //   type-name '::'
+    //   namespace-name '::'
+    //   nested-name-specifier identifier '::'
+    Token Next = NextToken();
+    
+    // If we get foo:bar, this is almost certainly a typo for foo::bar.  Recover
+    // and emit a fixit hint for it.
+    if (Next.is(tok::colon) && !ColonIsSacred) {
+      if (Actions.IsInvalidUnlessNestedName(CurScope, SS, II, ObjectType, 
+                                            EnteringContext) &&
+          // If the token after the colon isn't an identifier, it's still an
+          // error, but they probably meant something else strange so don't
+          // recover like this.
+          PP.LookAhead(1).is(tok::identifier)) {
+        Diag(Next, diag::err_unexected_colon_in_nested_name_spec)
+          << FixItHint::CreateReplacement(Next.getLocation(), "::");
+        
+        // Recover as if the user wrote '::'.
+        Next.setKind(tok::coloncolon);
+      }
+    }
+    
+    if (Next.is(tok::coloncolon)) {
+      if (CheckForDestructor && GetLookAheadToken(2).is(tok::tilde) &&
+          !Actions.isNonTypeNestedNameSpecifier(CurScope, SS, Tok.getLocation(),
+                                                II, ObjectType)) {
+        *MayBePseudoDestructor = true;
+        return false;
+      }
+
+      // We have an identifier followed by a '::'. Lookup this name
+      // as the name in a nested-name-specifier.
+      SourceLocation IdLoc = ConsumeToken();
+      assert((Tok.is(tok::coloncolon) || Tok.is(tok::colon)) &&
+             "NextToken() not working properly!");
+      SourceLocation CCLoc = ConsumeToken();
+
+      if (!HasScopeSpecifier) {
+        SS.setBeginLoc(IdLoc);
+        HasScopeSpecifier = true;
+      }
+
+      if (SS.isInvalid())
+        continue;
+
+      SS.setScopeRep(
+        Actions.ActOnCXXNestedNameSpecifier(CurScope, SS, IdLoc, CCLoc, II,
+                                            ObjectType, EnteringContext));
+      SS.setEndLoc(CCLoc);
+      continue;
+    }
+
+    // nested-name-specifier:
+    //   type-name '<'
+    if (Next.is(tok::less)) {
+      TemplateTy Template;
+      UnqualifiedId TemplateName;
+      TemplateName.setIdentifier(&II, Tok.getLocation());
+      if (TemplateNameKind TNK = Actions.isTemplateName(CurScope, SS, 
+                                                        TemplateName,
+                                                        ObjectType,
+                                                        EnteringContext,
+                                                        Template)) {
+        // We have found a template name, so annotate this this token
+        // with a template-id annotation. We do not permit the
+        // template-id to be translated into a type annotation,
+        // because some clients (e.g., the parsing of class template
+        // specializations) still want to see the original template-id
+        // token.
+        ConsumeToken();
+        if (AnnotateTemplateIdToken(Template, TNK, &SS, TemplateName, 
+                                    SourceLocation(), false))
+          return true;
+        continue;
+      }
+    }
+
+    // We don't have any tokens that form the beginning of a
+    // nested-name-specifier, so we're done.
+    break;
+  }
+
+  // Even if we didn't see any pieces of a nested-name-specifier, we
+  // still check whether there is a tilde in this position, which
+  // indicates a potential pseudo-destructor.
+  if (CheckForDestructor && Tok.is(tok::tilde))
+    *MayBePseudoDestructor = true;
+
+  return false;
+}
+
+/// ParseCXXIdExpression - Handle id-expression.
+///
+///       id-expression:
+///         unqualified-id
+///         qualified-id
+///
+///       qualified-id:
+///         '::'[opt] nested-name-specifier 'template'[opt] unqualified-id
+///         '::' identifier
+///         '::' operator-function-id
+///         '::' template-id
+///
+/// NOTE: The standard specifies that, for qualified-id, the parser does not
+/// expect:
+///
+///   '::' conversion-function-id
+///   '::' '~' class-name
+///
+/// This may cause a slight inconsistency on diagnostics:
+///
+/// class C {};
+/// namespace A {}
+/// void f() {
+///   :: A :: ~ C(); // Some Sema error about using destructor with a
+///                  // namespace.
+///   :: ~ C(); // Some Parser error like 'unexpected ~'.
+/// }
+///
+/// We simplify the parser a bit and make it work like:
+///
+///       qualified-id:
+///         '::'[opt] nested-name-specifier 'template'[opt] unqualified-id
+///         '::' unqualified-id
+///
+/// That way Sema can handle and report similar errors for namespaces and the
+/// global scope.
+///
+/// The isAddressOfOperand parameter indicates that this id-expression is a
+/// direct operand of the address-of operator. This is, besides member contexts,
+/// the only place where a qualified-id naming a non-static class member may
+/// appear.
+///
+Parser::OwningExprResult Parser::ParseCXXIdExpression(bool isAddressOfOperand) {
+  // qualified-id:
+  //   '::'[opt] nested-name-specifier 'template'[opt] unqualified-id
+  //   '::' unqualified-id
+  //
+  CXXScopeSpec SS;
+  ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, false);
+  
+  UnqualifiedId Name;
+  if (ParseUnqualifiedId(SS, 
+                         /*EnteringContext=*/false, 
+                         /*AllowDestructorName=*/false, 
+                         /*AllowConstructorName=*/false, 
+                         /*ObjectType=*/0,
+                         Name))
+    return ExprError();
+
+  // This is only the direct operand of an & operator if it is not
+  // followed by a postfix-expression suffix.
+  if (isAddressOfOperand) {
+    switch (Tok.getKind()) {
+    case tok::l_square:
+    case tok::l_paren:
+    case tok::arrow:
+    case tok::period:
+    case tok::plusplus:
+    case tok::minusminus:
+      isAddressOfOperand = false;
+      break;
+
+    default:
+      break;
+    }
+  }
+  
+  return Actions.ActOnIdExpression(CurScope, SS, Name, Tok.is(tok::l_paren),
+                                   isAddressOfOperand);
+  
+}
+
+/// ParseCXXCasts - This handles the various ways to cast expressions to another
+/// type.
+///
+///       postfix-expression: [C++ 5.2p1]
+///         'dynamic_cast' '<' type-name '>' '(' expression ')'
+///         'static_cast' '<' type-name '>' '(' expression ')'
+///         'reinterpret_cast' '<' type-name '>' '(' expression ')'
+///         'const_cast' '<' type-name '>' '(' expression ')'
+///
+Parser::OwningExprResult Parser::ParseCXXCasts() {
+  tok::TokenKind Kind = Tok.getKind();
+  const char *CastName = 0;     // For error messages
+
+  switch (Kind) {
+  default: assert(0 && "Unknown C++ cast!"); abort();
+  case tok::kw_const_cast:       CastName = "const_cast";       break;
+  case tok::kw_dynamic_cast:     CastName = "dynamic_cast";     break;
+  case tok::kw_reinterpret_cast: CastName = "reinterpret_cast"; break;
+  case tok::kw_static_cast:      CastName = "static_cast";      break;
+  }
+
+  SourceLocation OpLoc = ConsumeToken();
+  SourceLocation LAngleBracketLoc = Tok.getLocation();
+
+  if (ExpectAndConsume(tok::less, diag::err_expected_less_after, CastName))
+    return ExprError();
+
+  TypeResult CastTy = ParseTypeName();
+  SourceLocation RAngleBracketLoc = Tok.getLocation();
+
+  if (ExpectAndConsume(tok::greater, diag::err_expected_greater))
+    return ExprError(Diag(LAngleBracketLoc, diag::note_matching) << "<");
+
+  SourceLocation LParenLoc = Tok.getLocation(), RParenLoc;
+
+  if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, CastName))
+    return ExprError();
+
+  OwningExprResult Result = ParseExpression();
+
+  // Match the ')'.
+  RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
+
+  if (!Result.isInvalid() && !CastTy.isInvalid())
+    Result = Actions.ActOnCXXNamedCast(OpLoc, Kind,
+                                       LAngleBracketLoc, CastTy.get(),
+                                       RAngleBracketLoc,
+                                       LParenLoc, move(Result), RParenLoc);
+
+  return move(Result);
+}
+
+/// ParseCXXTypeid - This handles the C++ typeid expression.
+///
+///       postfix-expression: [C++ 5.2p1]
+///         'typeid' '(' expression ')'
+///         'typeid' '(' type-id ')'
+///
+Parser::OwningExprResult Parser::ParseCXXTypeid() {
+  assert(Tok.is(tok::kw_typeid) && "Not 'typeid'!");
+
+  SourceLocation OpLoc = ConsumeToken();
+  SourceLocation LParenLoc = Tok.getLocation();
+  SourceLocation RParenLoc;
+
+  // typeid expressions are always parenthesized.
+  if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
+      "typeid"))
+    return ExprError();
+
+  OwningExprResult Result(Actions);
+
+  if (isTypeIdInParens()) {
+    TypeResult Ty = ParseTypeName();
+
+    // Match the ')'.
+    MatchRHSPunctuation(tok::r_paren, LParenLoc);
+
+    if (Ty.isInvalid())
+      return ExprError();
+
+    Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/true,
+                                    Ty.get(), RParenLoc);
+  } else {
+    // C++0x [expr.typeid]p3:
+    //   When typeid is applied to an expression other than an lvalue of a
+    //   polymorphic class type [...] The expression is an unevaluated
+    //   operand (Clause 5).
+    //
+    // Note that we can't tell whether the expression is an lvalue of a
+    // polymorphic class type until after we've parsed the expression, so
+    // we the expression is potentially potentially evaluated.
+    EnterExpressionEvaluationContext Unevaluated(Actions,
+                                       Action::PotentiallyPotentiallyEvaluated);
+    Result = ParseExpression();
+
+    // Match the ')'.
+    if (Result.isInvalid())
+      SkipUntil(tok::r_paren);
+    else {
+      MatchRHSPunctuation(tok::r_paren, LParenLoc);
+
+      Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/false,
+                                      Result.release(), RParenLoc);
+    }
+  }
+
+  return move(Result);
+}
+
+/// \brief Parse a C++ pseudo-destructor expression after the base,
+/// . or -> operator, and nested-name-specifier have already been
+/// parsed.
+///
+///       postfix-expression: [C++ 5.2]
+///         postfix-expression . pseudo-destructor-name
+///         postfix-expression -> pseudo-destructor-name
+///
+///       pseudo-destructor-name: 
+///         ::[opt] nested-name-specifier[opt] type-name :: ~type-name 
+///         ::[opt] nested-name-specifier template simple-template-id :: 
+///                 ~type-name 
+///         ::[opt] nested-name-specifier[opt] ~type-name
+///       
+Parser::OwningExprResult 
+Parser::ParseCXXPseudoDestructor(ExprArg Base, SourceLocation OpLoc,
+                                 tok::TokenKind OpKind,
+                                 CXXScopeSpec &SS,
+                                 Action::TypeTy *ObjectType) {
+  // We're parsing either a pseudo-destructor-name or a dependent
+  // member access that has the same form as a
+  // pseudo-destructor-name. We parse both in the same way and let
+  // the action model sort them out.
+  //
+  // Note that the ::[opt] nested-name-specifier[opt] has already
+  // been parsed, and if there was a simple-template-id, it has
+  // been coalesced into a template-id annotation token.
+  UnqualifiedId FirstTypeName;
+  SourceLocation CCLoc;
+  if (Tok.is(tok::identifier)) {
+    FirstTypeName.setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
+    ConsumeToken();
+    assert(Tok.is(tok::coloncolon) &&"ParseOptionalCXXScopeSpecifier fail");
+    CCLoc = ConsumeToken();
+  } else if (Tok.is(tok::annot_template_id)) {
+    FirstTypeName.setTemplateId(
+                              (TemplateIdAnnotation *)Tok.getAnnotationValue());
+    ConsumeToken();
+    assert(Tok.is(tok::coloncolon) &&"ParseOptionalCXXScopeSpecifier fail");
+    CCLoc = ConsumeToken();
+  } else {
+    FirstTypeName.setIdentifier(0, SourceLocation());
+  }
+
+  // Parse the tilde.
+  assert(Tok.is(tok::tilde) && "ParseOptionalCXXScopeSpecifier fail");
+  SourceLocation TildeLoc = ConsumeToken();
+  if (!Tok.is(tok::identifier)) {
+    Diag(Tok, diag::err_destructor_tilde_identifier);
+    return ExprError();
+  }
+  
+  // Parse the second type.
+  UnqualifiedId SecondTypeName;
+  IdentifierInfo *Name = Tok.getIdentifierInfo();
+  SourceLocation NameLoc = ConsumeToken();
+  SecondTypeName.setIdentifier(Name, NameLoc);
+  
+  // If there is a '<', the second type name is a template-id. Parse
+  // it as such.
+  if (Tok.is(tok::less) &&
+      ParseUnqualifiedIdTemplateId(SS, Name, NameLoc, false, ObjectType,
+                                   SecondTypeName, /*AssumeTemplateName=*/true))
+    return ExprError();
+
+  return Actions.ActOnPseudoDestructorExpr(CurScope, move(Base), OpLoc, OpKind,
+                                           SS, FirstTypeName, CCLoc,
+                                           TildeLoc, SecondTypeName,
+                                           Tok.is(tok::l_paren));
+}
+
+/// ParseCXXBoolLiteral - This handles the C++ Boolean literals.
+///
+///       boolean-literal: [C++ 2.13.5]
+///         'true'
+///         'false'
+Parser::OwningExprResult Parser::ParseCXXBoolLiteral() {
+  tok::TokenKind Kind = Tok.getKind();
+  return Actions.ActOnCXXBoolLiteral(ConsumeToken(), Kind);
+}
+
+/// ParseThrowExpression - This handles the C++ throw expression.
+///
+///       throw-expression: [C++ 15]
+///         'throw' assignment-expression[opt]
+Parser::OwningExprResult Parser::ParseThrowExpression() {
+  assert(Tok.is(tok::kw_throw) && "Not throw!");
+  SourceLocation ThrowLoc = ConsumeToken();           // Eat the throw token.
+
+  // If the current token isn't the start of an assignment-expression,
+  // then the expression is not present.  This handles things like:
+  //   "C ? throw : (void)42", which is crazy but legal.
+  switch (Tok.getKind()) {  // FIXME: move this predicate somewhere common.
+  case tok::semi:
+  case tok::r_paren:
+  case tok::r_square:
+  case tok::r_brace:
+  case tok::colon:
+  case tok::comma:
+    return Actions.ActOnCXXThrow(ThrowLoc, ExprArg(Actions));
+
+  default:
+    OwningExprResult Expr(ParseAssignmentExpression());
+    if (Expr.isInvalid()) return move(Expr);
+    return Actions.ActOnCXXThrow(ThrowLoc, move(Expr));
+  }
+}
+
+/// ParseCXXThis - This handles the C++ 'this' pointer.
+///
+/// C++ 9.3.2: In the body of a non-static member function, the keyword this is
+/// a non-lvalue expression whose value is the address of the object for which
+/// the function is called.
+Parser::OwningExprResult Parser::ParseCXXThis() {
+  assert(Tok.is(tok::kw_this) && "Not 'this'!");
+  SourceLocation ThisLoc = ConsumeToken();
+  return Actions.ActOnCXXThis(ThisLoc);
+}
+
+/// ParseCXXTypeConstructExpression - Parse construction of a specified type.
+/// Can be interpreted either as function-style casting ("int(x)")
+/// or class type construction ("ClassType(x,y,z)")
+/// or creation of a value-initialized type ("int()").
+///
+///       postfix-expression: [C++ 5.2p1]
+///         simple-type-specifier '(' expression-list[opt] ')'      [C++ 5.2.3]
+///         typename-specifier '(' expression-list[opt] ')'         [TODO]
+///
+Parser::OwningExprResult
+Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) {
+  Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
+  TypeTy *TypeRep = Actions.ActOnTypeName(CurScope, DeclaratorInfo).get();
+
+  assert(Tok.is(tok::l_paren) && "Expected '('!");
+  SourceLocation LParenLoc = ConsumeParen();
+
+  ExprVector Exprs(Actions);
+  CommaLocsTy CommaLocs;
+
+  if (Tok.isNot(tok::r_paren)) {
+    if (ParseExpressionList(Exprs, CommaLocs)) {
+      SkipUntil(tok::r_paren);
+      return ExprError();
+    }
+  }
+
+  // Match the ')'.
+  SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
+
+  // TypeRep could be null, if it references an invalid typedef.
+  if (!TypeRep)
+    return ExprError();
+
+  assert((Exprs.size() == 0 || Exprs.size()-1 == CommaLocs.size())&&
+         "Unexpected number of commas!");
+  return Actions.ActOnCXXTypeConstructExpr(DS.getSourceRange(), TypeRep,
+                                           LParenLoc, move_arg(Exprs),
+                                           CommaLocs.data(), RParenLoc);
+}
+
+/// ParseCXXCondition - if/switch/while condition expression.
+///
+///       condition:
+///         expression
+///         type-specifier-seq declarator '=' assignment-expression
+/// [GNU]   type-specifier-seq declarator simple-asm-expr[opt] attributes[opt]
+///             '=' assignment-expression
+///
+/// \param ExprResult if the condition was parsed as an expression, the
+/// parsed expression.
+///
+/// \param DeclResult if the condition was parsed as a declaration, the
+/// parsed declaration.
+///
+/// \returns true if there was a parsing, false otherwise.
+bool Parser::ParseCXXCondition(OwningExprResult &ExprResult,
+                               DeclPtrTy &DeclResult) {
+  if (Tok.is(tok::code_completion)) {
+    Actions.CodeCompleteOrdinaryName(CurScope, Action::CCC_Condition);
+    ConsumeToken();
+  }
+
+  if (!isCXXConditionDeclaration()) {
+    ExprResult = ParseExpression(); // expression
+    DeclResult = DeclPtrTy();
+    return ExprResult.isInvalid();
+  }
+
+  // type-specifier-seq
+  DeclSpec DS;
+  ParseSpecifierQualifierList(DS);
+
+  // declarator
+  Declarator DeclaratorInfo(DS, Declarator::ConditionContext);
+  ParseDeclarator(DeclaratorInfo);
+
+  // simple-asm-expr[opt]
+  if (Tok.is(tok::kw_asm)) {
+    SourceLocation Loc;
+    OwningExprResult AsmLabel(ParseSimpleAsm(&Loc));
+    if (AsmLabel.isInvalid()) {
+      SkipUntil(tok::semi);
+      return true;
+    }
+    DeclaratorInfo.setAsmLabel(AsmLabel.release());
+    DeclaratorInfo.SetRangeEnd(Loc);
+  }
+
+  // If attributes are present, parse them.
+  if (Tok.is(tok::kw___attribute)) {
+    SourceLocation Loc;
+    AttributeList *AttrList = ParseGNUAttributes(&Loc);
+    DeclaratorInfo.AddAttributes(AttrList, Loc);
+  }
+
+  // Type-check the declaration itself.
+  Action::DeclResult Dcl = Actions.ActOnCXXConditionDeclaration(CurScope, 
+                                                                DeclaratorInfo);
+  DeclResult = Dcl.get();
+  ExprResult = ExprError();
+  
+  // '=' assignment-expression
+  if (Tok.is(tok::equal)) {
+    SourceLocation EqualLoc = ConsumeToken();
+    OwningExprResult AssignExpr(ParseAssignmentExpression());
+    if (!AssignExpr.isInvalid()) 
+      Actions.AddInitializerToDecl(DeclResult, move(AssignExpr));
+  } else {
+    // FIXME: C++0x allows a braced-init-list
+    Diag(Tok, diag::err_expected_equal_after_declarator);
+  }
+  
+  return false;
+}
+
+/// \brief Determine whether the current token starts a C++
+/// simple-type-specifier.
+bool Parser::isCXXSimpleTypeSpecifier() const {
+  switch (Tok.getKind()) {
+  case tok::annot_typename:
+  case tok::kw_short:
+  case tok::kw_long:
+  case tok::kw_signed:
+  case tok::kw_unsigned:
+  case tok::kw_void:
+  case tok::kw_char:
+  case tok::kw_int:
+  case tok::kw_float:
+  case tok::kw_double:
+  case tok::kw_wchar_t:
+  case tok::kw_char16_t:
+  case tok::kw_char32_t:
+  case tok::kw_bool:
+    // FIXME: C++0x decltype support.
+  // GNU typeof support.
+  case tok::kw_typeof:
+    return true;
+
+  default:
+    break;
+  }
+
+  return false;
+}
+
+/// ParseCXXSimpleTypeSpecifier - [C++ 7.1.5.2] Simple type specifiers.
+/// This should only be called when the current token is known to be part of
+/// simple-type-specifier.
+///
+///       simple-type-specifier:
+///         '::'[opt] nested-name-specifier[opt] type-name
+///         '::'[opt] nested-name-specifier 'template' simple-template-id [TODO]
+///         char
+///         wchar_t
+///         bool
+///         short
+///         int
+///         long
+///         signed
+///         unsigned
+///         float
+///         double
+///         void
+/// [GNU]   typeof-specifier
+/// [C++0x] auto               [TODO]
+///
+///       type-name:
+///         class-name
+///         enum-name
+///         typedef-name
+///
+void Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) {
+  DS.SetRangeStart(Tok.getLocation());
+  const char *PrevSpec;
+  unsigned DiagID;
+  SourceLocation Loc = Tok.getLocation();
+
+  switch (Tok.getKind()) {
+  case tok::identifier:   // foo::bar
+  case tok::coloncolon:   // ::foo::bar
+    assert(0 && "Annotation token should already be formed!");
+  default:
+    assert(0 && "Not a simple-type-specifier token!");
+    abort();
+
+  // type-name
+  case tok::annot_typename: {
+    DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, DiagID,
+                       Tok.getAnnotationValue());
+    break;
+  }
+
+  // builtin types
+  case tok::kw_short:
+    DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec, DiagID);
+    break;
+  case tok::kw_long:
+    DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec, DiagID);
+    break;
+  case tok::kw_signed:
+    DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec, DiagID);
+    break;
+  case tok::kw_unsigned:
+    DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec, DiagID);
+    break;
+  case tok::kw_void:
+    DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec, DiagID);
+    break;
+  case tok::kw_char:
+    DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec, DiagID);
+    break;
+  case tok::kw_int:
+    DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec, DiagID);
+    break;
+  case tok::kw_float:
+    DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec, DiagID);
+    break;
+  case tok::kw_double:
+    DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec, DiagID);
+    break;
+  case tok::kw_wchar_t:
+    DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec, DiagID);
+    break;
+  case tok::kw_char16_t:
+    DS.SetTypeSpecType(DeclSpec::TST_char16, Loc, PrevSpec, DiagID);
+    break;
+  case tok::kw_char32_t:
+    DS.SetTypeSpecType(DeclSpec::TST_char32, Loc, PrevSpec, DiagID);
+    break;
+  case tok::kw_bool:
+    DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec, DiagID);
+    break;
+
+    // FIXME: C++0x decltype support.
+  // GNU typeof support.
+  case tok::kw_typeof:
+    ParseTypeofSpecifier(DS);
+    DS.Finish(Diags, PP);
+    return;
+  }
+  if (Tok.is(tok::annot_typename))
+    DS.SetRangeEnd(Tok.getAnnotationEndLoc());
+  else
+    DS.SetRangeEnd(Tok.getLocation());
+  ConsumeToken();
+  DS.Finish(Diags, PP);
+}
+
+/// ParseCXXTypeSpecifierSeq - Parse a C++ type-specifier-seq (C++
+/// [dcl.name]), which is a non-empty sequence of type-specifiers,
+/// e.g., "const short int". Note that the DeclSpec is *not* finished
+/// by parsing the type-specifier-seq, because these sequences are
+/// typically followed by some form of declarator. Returns true and
+/// emits diagnostics if this is not a type-specifier-seq, false
+/// otherwise.
+///
+///   type-specifier-seq: [C++ 8.1]
+///     type-specifier type-specifier-seq[opt]
+///
+bool Parser::ParseCXXTypeSpecifierSeq(DeclSpec &DS) {
+  DS.SetRangeStart(Tok.getLocation());
+  const char *PrevSpec = 0;
+  unsigned DiagID;
+  bool isInvalid = 0;
+
+  // Parse one or more of the type specifiers.
+  if (!ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec, DiagID,
+      ParsedTemplateInfo(), /*SuppressDeclarations*/true)) {
+    Diag(Tok, diag::err_operator_missing_type_specifier);
+    return true;
+  }
+
+  while (ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec, DiagID,
+         ParsedTemplateInfo(), /*SuppressDeclarations*/true))
+  {}
+
+  DS.Finish(Diags, PP);
+  return false;
+}
+
+/// \brief Finish parsing a C++ unqualified-id that is a template-id of
+/// some form. 
+///
+/// This routine is invoked when a '<' is encountered after an identifier or
+/// operator-function-id is parsed by \c ParseUnqualifiedId() to determine
+/// whether the unqualified-id is actually a template-id. This routine will
+/// then parse the template arguments and form the appropriate template-id to
+/// return to the caller.
+///
+/// \param SS the nested-name-specifier that precedes this template-id, if
+/// we're actually parsing a qualified-id.
+///
+/// \param Name for constructor and destructor names, this is the actual
+/// identifier that may be a template-name.
+///
+/// \param NameLoc the location of the class-name in a constructor or 
+/// destructor.
+///
+/// \param EnteringContext whether we're entering the scope of the 
+/// nested-name-specifier.
+///
+/// \param ObjectType if this unqualified-id occurs within a member access
+/// expression, the type of the base object whose member is being accessed.
+///
+/// \param Id as input, describes the template-name or operator-function-id
+/// that precedes the '<'. If template arguments were parsed successfully,
+/// will be updated with the template-id.
+/// 
+/// \param AssumeTemplateId When true, this routine will assume that the name
+/// refers to a template without performing name lookup to verify. 
+///
+/// \returns true if a parse error occurred, false otherwise.
+bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS,
+                                          IdentifierInfo *Name,
+                                          SourceLocation NameLoc,
+                                          bool EnteringContext,
+                                          TypeTy *ObjectType,
+                                          UnqualifiedId &Id,
+                                          bool AssumeTemplateId) {
+  assert(Tok.is(tok::less) && "Expected '<' to finish parsing a template-id");
+  
+  TemplateTy Template;
+  TemplateNameKind TNK = TNK_Non_template;
+  switch (Id.getKind()) {
+  case UnqualifiedId::IK_Identifier:
+  case UnqualifiedId::IK_OperatorFunctionId:
+  case UnqualifiedId::IK_LiteralOperatorId:
+    if (AssumeTemplateId) {
+      Template = Actions.ActOnDependentTemplateName(SourceLocation(), SS, 
+                                                    Id, ObjectType,
+                                                    EnteringContext);
+      TNK = TNK_Dependent_template_name;
+      if (!Template.get())
+        return true;      
+    } else 
+      TNK = Actions.isTemplateName(CurScope, SS, Id, ObjectType, 
+                                   EnteringContext, Template);
+    break;
+      
+  case UnqualifiedId::IK_ConstructorName: {
+    UnqualifiedId TemplateName;
+    TemplateName.setIdentifier(Name, NameLoc);
+    TNK = Actions.isTemplateName(CurScope, SS, TemplateName, ObjectType, 
+                                 EnteringContext, Template);
+    break;
+  }
+      
+  case UnqualifiedId::IK_DestructorName: {
+    UnqualifiedId TemplateName;
+    TemplateName.setIdentifier(Name, NameLoc);
+    if (ObjectType) {
+      Template = Actions.ActOnDependentTemplateName(SourceLocation(), SS, 
+                                                    TemplateName, ObjectType,
+                                                    EnteringContext);
+      TNK = TNK_Dependent_template_name;
+      if (!Template.get())
+        return true;
+    } else {
+      TNK = Actions.isTemplateName(CurScope, SS, TemplateName, ObjectType, 
+                                   EnteringContext, Template);
+      
+      if (TNK == TNK_Non_template && Id.DestructorName == 0) {
+        Diag(NameLoc, diag::err_destructor_template_id)
+          << Name << SS.getRange();
+        return true;        
+      }
+    }
+    break;
+  }
+      
+  default:
+    return false;
+  }
+  
+  if (TNK == TNK_Non_template)
+    return false;
+  
+  // Parse the enclosed template argument list.
+  SourceLocation LAngleLoc, RAngleLoc;
+  TemplateArgList TemplateArgs;
+  if (ParseTemplateIdAfterTemplateName(Template, Id.StartLocation,
+                                       &SS, true, LAngleLoc,
+                                       TemplateArgs,
+                                       RAngleLoc))
+    return true;
+  
+  if (Id.getKind() == UnqualifiedId::IK_Identifier ||
+      Id.getKind() == UnqualifiedId::IK_OperatorFunctionId ||
+      Id.getKind() == UnqualifiedId::IK_LiteralOperatorId) {
+    // Form a parsed representation of the template-id to be stored in the
+    // UnqualifiedId.
+    TemplateIdAnnotation *TemplateId
+      = TemplateIdAnnotation::Allocate(TemplateArgs.size());
+
+    if (Id.getKind() == UnqualifiedId::IK_Identifier) {
+      TemplateId->Name = Id.Identifier;
+      TemplateId->Operator = OO_None;
+      TemplateId->TemplateNameLoc = Id.StartLocation;
+    } else {
+      TemplateId->Name = 0;
+      TemplateId->Operator = Id.OperatorFunctionId.Operator;
+      TemplateId->TemplateNameLoc = Id.StartLocation;
+    }
+
+    TemplateId->Template = Template.getAs<void*>();
+    TemplateId->Kind = TNK;
+    TemplateId->LAngleLoc = LAngleLoc;
+    TemplateId->RAngleLoc = RAngleLoc;
+    ParsedTemplateArgument *Args = TemplateId->getTemplateArgs();
+    for (unsigned Arg = 0, ArgEnd = TemplateArgs.size(); 
+         Arg != ArgEnd; ++Arg)
+      Args[Arg] = TemplateArgs[Arg];
+    
+    Id.setTemplateId(TemplateId);
+    return false;
+  }
+
+  // Bundle the template arguments together.
+  ASTTemplateArgsPtr TemplateArgsPtr(Actions, TemplateArgs.data(),
+                                     TemplateArgs.size());
+  
+  // Constructor and destructor names.
+  Action::TypeResult Type
+    = Actions.ActOnTemplateIdType(Template, NameLoc,
+                                  LAngleLoc, TemplateArgsPtr,
+                                  RAngleLoc);
+  if (Type.isInvalid())
+    return true;
+  
+  if (Id.getKind() == UnqualifiedId::IK_ConstructorName)
+    Id.setConstructorName(Type.get(), NameLoc, RAngleLoc);
+  else
+    Id.setDestructorName(Id.StartLocation, Type.get(), RAngleLoc);
+  
+  return false;
+}
+
+/// \brief Parse an operator-function-id or conversion-function-id as part
+/// of a C++ unqualified-id.
+///
+/// This routine is responsible only for parsing the operator-function-id or
+/// conversion-function-id; it does not handle template arguments in any way.
+///
+/// \code
+///       operator-function-id: [C++ 13.5]
+///         'operator' operator
+///
+///       operator: one of
+///            new   delete  new[]   delete[]
+///            +     -    *  /    %  ^    &   |   ~
+///            !     =    <  >    += -=   *=  /=  %=
+///            ^=    &=   |= <<   >> >>= <<=  ==  !=
+///            <=    >=   && ||   ++ --   ,   ->* ->
+///            ()    []
+///
+///       conversion-function-id: [C++ 12.3.2]
+///         operator conversion-type-id
+///
+///       conversion-type-id:
+///         type-specifier-seq conversion-declarator[opt]
+///
+///       conversion-declarator:
+///         ptr-operator conversion-declarator[opt]
+/// \endcode
+///
+/// \param The nested-name-specifier that preceded this unqualified-id. If
+/// non-empty, then we are parsing the unqualified-id of a qualified-id.
+///
+/// \param EnteringContext whether we are entering the scope of the 
+/// nested-name-specifier.
+///
+/// \param ObjectType if this unqualified-id occurs within a member access
+/// expression, the type of the base object whose member is being accessed.
+///
+/// \param Result on a successful parse, contains the parsed unqualified-id.
+///
+/// \returns true if parsing fails, false otherwise.
+bool Parser::ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext,
+                                        TypeTy *ObjectType,
+                                        UnqualifiedId &Result) {
+  assert(Tok.is(tok::kw_operator) && "Expected 'operator' keyword");
+  
+  // Consume the 'operator' keyword.
+  SourceLocation KeywordLoc = ConsumeToken();
+  
+  // Determine what kind of operator name we have.
+  unsigned SymbolIdx = 0;
+  SourceLocation SymbolLocations[3];
+  OverloadedOperatorKind Op = OO_None;
+  switch (Tok.getKind()) {
+    case tok::kw_new:
+    case tok::kw_delete: {
+      bool isNew = Tok.getKind() == tok::kw_new;
+      // Consume the 'new' or 'delete'.
+      SymbolLocations[SymbolIdx++] = ConsumeToken();
+      if (Tok.is(tok::l_square)) {
+        // Consume the '['.
+        SourceLocation LBracketLoc = ConsumeBracket();
+        // Consume the ']'.
+        SourceLocation RBracketLoc = MatchRHSPunctuation(tok::r_square,
+                                                         LBracketLoc);
+        if (RBracketLoc.isInvalid())
+          return true;
+        
+        SymbolLocations[SymbolIdx++] = LBracketLoc;
+        SymbolLocations[SymbolIdx++] = RBracketLoc;
+        Op = isNew? OO_Array_New : OO_Array_Delete;
+      } else {
+        Op = isNew? OO_New : OO_Delete;
+      }
+      break;
+    }
+      
+#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
+    case tok::Token:                                                     \
+      SymbolLocations[SymbolIdx++] = ConsumeToken();                     \
+      Op = OO_##Name;                                                    \
+      break;
+#define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly)
+#include "clang/Basic/OperatorKinds.def"
+      
+    case tok::l_paren: {
+      // Consume the '('.
+      SourceLocation LParenLoc = ConsumeParen();
+      // Consume the ')'.
+      SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren,
+                                                     LParenLoc);
+      if (RParenLoc.isInvalid())
+        return true;
+      
+      SymbolLocations[SymbolIdx++] = LParenLoc;
+      SymbolLocations[SymbolIdx++] = RParenLoc;
+      Op = OO_Call;
+      break;
+    }
+      
+    case tok::l_square: {
+      // Consume the '['.
+      SourceLocation LBracketLoc = ConsumeBracket();
+      // Consume the ']'.
+      SourceLocation RBracketLoc = MatchRHSPunctuation(tok::r_square,
+                                                       LBracketLoc);
+      if (RBracketLoc.isInvalid())
+        return true;
+      
+      SymbolLocations[SymbolIdx++] = LBracketLoc;
+      SymbolLocations[SymbolIdx++] = RBracketLoc;
+      Op = OO_Subscript;
+      break;
+    }
+      
+    case tok::code_completion: {
+      // Code completion for the operator name.
+      Actions.CodeCompleteOperatorName(CurScope);
+      
+      // Consume the operator token.
+      ConsumeToken();
+      
+      // Don't try to parse any further.
+      return true;
+    }
+      
+    default:
+      break;
+  }
+  
+  if (Op != OO_None) {
+    // We have parsed an operator-function-id.
+    Result.setOperatorFunctionId(KeywordLoc, Op, SymbolLocations);
+    return false;
+  }
+
+  // Parse a literal-operator-id.
+  //
+  //   literal-operator-id: [C++0x 13.5.8]
+  //     operator "" identifier
+
+  if (getLang().CPlusPlus0x && Tok.is(tok::string_literal)) {
+    if (Tok.getLength() != 2)
+      Diag(Tok.getLocation(), diag::err_operator_string_not_empty);
+    ConsumeStringToken();
+
+    if (Tok.isNot(tok::identifier)) {
+      Diag(Tok.getLocation(), diag::err_expected_ident);
+      return true;
+    }
+
+    IdentifierInfo *II = Tok.getIdentifierInfo();
+    Result.setLiteralOperatorId(II, KeywordLoc, ConsumeToken());
+    return false;
+  }
+  
+  // Parse a conversion-function-id.
+  //
+  //   conversion-function-id: [C++ 12.3.2]
+  //     operator conversion-type-id
+  //
+  //   conversion-type-id:
+  //     type-specifier-seq conversion-declarator[opt]
+  //
+  //   conversion-declarator:
+  //     ptr-operator conversion-declarator[opt]
+  
+  // Parse the type-specifier-seq.
+  DeclSpec DS;
+  if (ParseCXXTypeSpecifierSeq(DS)) // FIXME: ObjectType?
+    return true;
+  
+  // Parse the conversion-declarator, which is merely a sequence of
+  // ptr-operators.
+  Declarator D(DS, Declarator::TypeNameContext);
+  ParseDeclaratorInternal(D, /*DirectDeclParser=*/0);
+  
+  // Finish up the type.
+  Action::TypeResult Ty = Actions.ActOnTypeName(CurScope, D);
+  if (Ty.isInvalid())
+    return true;
+  
+  // Note that this is a conversion-function-id.
+  Result.setConversionFunctionId(KeywordLoc, Ty.get(), 
+                                 D.getSourceRange().getEnd());
+  return false;  
+}
+
+/// \brief Parse a C++ unqualified-id (or a C identifier), which describes the
+/// name of an entity.
+///
+/// \code
+///       unqualified-id: [C++ expr.prim.general]
+///         identifier
+///         operator-function-id
+///         conversion-function-id
+/// [C++0x] literal-operator-id [TODO]
+///         ~ class-name
+///         template-id
+///
+/// \endcode
+///
+/// \param The nested-name-specifier that preceded this unqualified-id. If
+/// non-empty, then we are parsing the unqualified-id of a qualified-id.
+///
+/// \param EnteringContext whether we are entering the scope of the 
+/// nested-name-specifier.
+///
+/// \param AllowDestructorName whether we allow parsing of a destructor name.
+///
+/// \param AllowConstructorName whether we allow parsing a constructor name.
+///
+/// \param ObjectType if this unqualified-id occurs within a member access
+/// expression, the type of the base object whose member is being accessed.
+///
+/// \param Result on a successful parse, contains the parsed unqualified-id.
+///
+/// \returns true if parsing fails, false otherwise.
+bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext,
+                                bool AllowDestructorName,
+                                bool AllowConstructorName,
+                                TypeTy *ObjectType,
+                                UnqualifiedId &Result) {
+  // unqualified-id:
+  //   identifier
+  //   template-id (when it hasn't already been annotated)
+  if (Tok.is(tok::identifier)) {
+    // Consume the identifier.
+    IdentifierInfo *Id = Tok.getIdentifierInfo();
+    SourceLocation IdLoc = ConsumeToken();
+
+    if (!getLang().CPlusPlus) {
+      // If we're not in C++, only identifiers matter. Record the
+      // identifier and return.
+      Result.setIdentifier(Id, IdLoc);
+      return false;
+    }
+
+    if (AllowConstructorName && 
+        Actions.isCurrentClassName(*Id, CurScope, &SS)) {
+      // We have parsed a constructor name.
+      Result.setConstructorName(Actions.getTypeName(*Id, IdLoc, CurScope,
+                                                    &SS, false),
+                                IdLoc, IdLoc);
+    } else {
+      // We have parsed an identifier.
+      Result.setIdentifier(Id, IdLoc);      
+    }
+
+    // If the next token is a '<', we may have a template.
+    if (Tok.is(tok::less))
+      return ParseUnqualifiedIdTemplateId(SS, Id, IdLoc, EnteringContext, 
+                                          ObjectType, Result);
+    
+    return false;
+  }
+  
+  // unqualified-id:
+  //   template-id (already parsed and annotated)
+  if (Tok.is(tok::annot_template_id)) {
+    TemplateIdAnnotation *TemplateId
+      = static_cast<TemplateIdAnnotation*>(Tok.getAnnotationValue());
+
+    // If the template-name names the current class, then this is a constructor 
+    if (AllowConstructorName && TemplateId->Name &&
+        Actions.isCurrentClassName(*TemplateId->Name, CurScope, &SS)) {
+      if (SS.isSet()) {
+        // C++ [class.qual]p2 specifies that a qualified template-name
+        // is taken as the constructor name where a constructor can be
+        // declared. Thus, the template arguments are extraneous, so
+        // complain about them and remove them entirely.
+        Diag(TemplateId->TemplateNameLoc, 
+             diag::err_out_of_line_constructor_template_id)
+          << TemplateId->Name
+          << FixItHint::CreateRemoval(
+                    SourceRange(TemplateId->LAngleLoc, TemplateId->RAngleLoc));
+        Result.setConstructorName(Actions.getTypeName(*TemplateId->Name,
+                                                  TemplateId->TemplateNameLoc, 
+                                                      CurScope,
+                                                      &SS, false),
+                                  TemplateId->TemplateNameLoc, 
+                                  TemplateId->RAngleLoc);
+        TemplateId->Destroy();
+        ConsumeToken();
+        return false;
+      }
+
+      Result.setConstructorTemplateId(TemplateId);
+      ConsumeToken();
+      return false;
+    }
+
+    // We have already parsed a template-id; consume the annotation token as
+    // our unqualified-id.
+    Result.setTemplateId(TemplateId);
+    ConsumeToken();
+    return false;
+  }
+  
+  // unqualified-id:
+  //   operator-function-id
+  //   conversion-function-id
+  if (Tok.is(tok::kw_operator)) {
+    if (ParseUnqualifiedIdOperator(SS, EnteringContext, ObjectType, Result))
+      return true;
+    
+    // If we have an operator-function-id or a literal-operator-id and the next
+    // token is a '<', we may have a
+    // 
+    //   template-id:
+    //     operator-function-id < template-argument-list[opt] >
+    if ((Result.getKind() == UnqualifiedId::IK_OperatorFunctionId ||
+         Result.getKind() == UnqualifiedId::IK_LiteralOperatorId) &&
+        Tok.is(tok::less))
+      return ParseUnqualifiedIdTemplateId(SS, 0, SourceLocation(), 
+                                          EnteringContext, ObjectType, 
+                                          Result);
+    
+    return false;
+  }
+  
+  if (getLang().CPlusPlus && 
+      (AllowDestructorName || SS.isSet()) && Tok.is(tok::tilde)) {
+    // C++ [expr.unary.op]p10:
+    //   There is an ambiguity in the unary-expression ~X(), where X is a 
+    //   class-name. The ambiguity is resolved in favor of treating ~ as a 
+    //    unary complement rather than treating ~X as referring to a destructor.
+    
+    // Parse the '~'.
+    SourceLocation TildeLoc = ConsumeToken();
+    
+    // Parse the class-name.
+    if (Tok.isNot(tok::identifier)) {
+      Diag(Tok, diag::err_destructor_tilde_identifier);
+      return true;
+    }
+
+    // Parse the class-name (or template-name in a simple-template-id).
+    IdentifierInfo *ClassName = Tok.getIdentifierInfo();
+    SourceLocation ClassNameLoc = ConsumeToken();
+    
+    if (Tok.is(tok::less)) {
+      Result.setDestructorName(TildeLoc, 0, ClassNameLoc);
+      return ParseUnqualifiedIdTemplateId(SS, ClassName, ClassNameLoc,
+                                          EnteringContext, ObjectType, Result);
+    }
+    
+    // Note that this is a destructor name.
+    Action::TypeTy *Ty = Actions.getDestructorName(TildeLoc, *ClassName, 
+                                                   ClassNameLoc, CurScope,
+                                                   SS, ObjectType,
+                                                   EnteringContext);
+    if (!Ty)
+      return true;
+
+    Result.setDestructorName(TildeLoc, Ty, ClassNameLoc);
+    return false;
+  }
+  
+  Diag(Tok, diag::err_expected_unqualified_id)
+    << getLang().CPlusPlus;
+  return true;
+}
+
+/// ParseCXXNewExpression - Parse a C++ new-expression. New is used to allocate
+/// memory in a typesafe manner and call constructors.
+///
+/// This method is called to parse the new expression after the optional :: has
+/// been already parsed.  If the :: was present, "UseGlobal" is true and "Start"
+/// is its location.  Otherwise, "Start" is the location of the 'new' token.
+///
+///        new-expression:
+///                   '::'[opt] 'new' new-placement[opt] new-type-id
+///                                     new-initializer[opt]
+///                   '::'[opt] 'new' new-placement[opt] '(' type-id ')'
+///                                     new-initializer[opt]
+///
+///        new-placement:
+///                   '(' expression-list ')'
+///
+///        new-type-id:
+///                   type-specifier-seq new-declarator[opt]
+///
+///        new-declarator:
+///                   ptr-operator new-declarator[opt]
+///                   direct-new-declarator
+///
+///        new-initializer:
+///                   '(' expression-list[opt] ')'
+/// [C++0x]           braced-init-list                                   [TODO]
+///
+Parser::OwningExprResult
+Parser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) {
+  assert(Tok.is(tok::kw_new) && "expected 'new' token");
+  ConsumeToken();   // Consume 'new'
+
+  // A '(' now can be a new-placement or the '(' wrapping the type-id in the
+  // second form of new-expression. It can't be a new-type-id.
+
+  ExprVector PlacementArgs(Actions);
+  SourceLocation PlacementLParen, PlacementRParen;
+
+  bool ParenTypeId;
+  DeclSpec DS;
+  Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
+  if (Tok.is(tok::l_paren)) {
+    // If it turns out to be a placement, we change the type location.
+    PlacementLParen = ConsumeParen();
+    if (ParseExpressionListOrTypeId(PlacementArgs, DeclaratorInfo)) {
+      SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true);
+      return ExprError();
+    }
+
+    PlacementRParen = MatchRHSPunctuation(tok::r_paren, PlacementLParen);
+    if (PlacementRParen.isInvalid()) {
+      SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true);
+      return ExprError();
+    }
+
+    if (PlacementArgs.empty()) {
+      // Reset the placement locations. There was no placement.
+      PlacementLParen = PlacementRParen = SourceLocation();
+      ParenTypeId = true;
+    } else {
+      // We still need the type.
+      if (Tok.is(tok::l_paren)) {
+        SourceLocation LParen = ConsumeParen();
+        ParseSpecifierQualifierList(DS);
+        DeclaratorInfo.SetSourceRange(DS.getSourceRange());
+        ParseDeclarator(DeclaratorInfo);
+        MatchRHSPunctuation(tok::r_paren, LParen);
+        ParenTypeId = true;
+      } else {
+        if (ParseCXXTypeSpecifierSeq(DS))
+          DeclaratorInfo.setInvalidType(true);
+        else {
+          DeclaratorInfo.SetSourceRange(DS.getSourceRange());
+          ParseDeclaratorInternal(DeclaratorInfo,
+                                  &Parser::ParseDirectNewDeclarator);
+        }
+        ParenTypeId = false;
+      }
+    }
+  } else {
+    // A new-type-id is a simplified type-id, where essentially the
+    // direct-declarator is replaced by a direct-new-declarator.
+    if (ParseCXXTypeSpecifierSeq(DS))
+      DeclaratorInfo.setInvalidType(true);
+    else {
+      DeclaratorInfo.SetSourceRange(DS.getSourceRange());
+      ParseDeclaratorInternal(DeclaratorInfo,
+                              &Parser::ParseDirectNewDeclarator);
+    }
+    ParenTypeId = false;
+  }
+  if (DeclaratorInfo.isInvalidType()) {
+    SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true);
+    return ExprError();
+  }
+
+  ExprVector ConstructorArgs(Actions);
+  SourceLocation ConstructorLParen, ConstructorRParen;
+
+  if (Tok.is(tok::l_paren)) {
+    ConstructorLParen = ConsumeParen();
+    if (Tok.isNot(tok::r_paren)) {
+      CommaLocsTy CommaLocs;
+      if (ParseExpressionList(ConstructorArgs, CommaLocs)) {
+        SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true);
+        return ExprError();
+      }
+    }
+    ConstructorRParen = MatchRHSPunctuation(tok::r_paren, ConstructorLParen);
+    if (ConstructorRParen.isInvalid()) {
+      SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true);
+      return ExprError();
+    }
+  }
+
+  return Actions.ActOnCXXNew(Start, UseGlobal, PlacementLParen,
+                             move_arg(PlacementArgs), PlacementRParen,
+                             ParenTypeId, DeclaratorInfo, ConstructorLParen,
+                             move_arg(ConstructorArgs), ConstructorRParen);
+}
+
+/// ParseDirectNewDeclarator - Parses a direct-new-declarator. Intended to be
+/// passed to ParseDeclaratorInternal.
+///
+///        direct-new-declarator:
+///                   '[' expression ']'
+///                   direct-new-declarator '[' constant-expression ']'
+///
+void Parser::ParseDirectNewDeclarator(Declarator &D) {
+  // Parse the array dimensions.
+  bool first = true;
+  while (Tok.is(tok::l_square)) {
+    SourceLocation LLoc = ConsumeBracket();
+    OwningExprResult Size(first ? ParseExpression()
+                                : ParseConstantExpression());
+    if (Size.isInvalid()) {
+      // Recover
+      SkipUntil(tok::r_square);
+      return;
+    }
+    first = false;
+
+    SourceLocation RLoc = MatchRHSPunctuation(tok::r_square, LLoc);
+    D.AddTypeInfo(DeclaratorChunk::getArray(0, /*static=*/false, /*star=*/false,
+                                            Size.release(), LLoc, RLoc),
+                  RLoc);
+
+    if (RLoc.isInvalid())
+      return;
+  }
+}
+
+/// ParseExpressionListOrTypeId - Parse either an expression-list or a type-id.
+/// This ambiguity appears in the syntax of the C++ new operator.
+///
+///        new-expression:
+///                   '::'[opt] 'new' new-placement[opt] '(' type-id ')'
+///                                     new-initializer[opt]
+///
+///        new-placement:
+///                   '(' expression-list ')'
+///
+bool Parser::ParseExpressionListOrTypeId(ExprListTy &PlacementArgs,
+                                         Declarator &D) {
+  // The '(' was already consumed.
+  if (isTypeIdInParens()) {
+    ParseSpecifierQualifierList(D.getMutableDeclSpec());
+    D.SetSourceRange(D.getDeclSpec().getSourceRange());
+    ParseDeclarator(D);
+    return D.isInvalidType();
+  }
+
+  // It's not a type, it has to be an expression list.
+  // Discard the comma locations - ActOnCXXNew has enough parameters.
+  CommaLocsTy CommaLocs;
+  return ParseExpressionList(PlacementArgs, CommaLocs);
+}
+
+/// ParseCXXDeleteExpression - Parse a C++ delete-expression. Delete is used
+/// to free memory allocated by new.
+///
+/// This method is called to parse the 'delete' expression after the optional
+/// '::' has been already parsed.  If the '::' was present, "UseGlobal" is true
+/// and "Start" is its location.  Otherwise, "Start" is the location of the
+/// 'delete' token.
+///
+///        delete-expression:
+///                   '::'[opt] 'delete' cast-expression
+///                   '::'[opt] 'delete' '[' ']' cast-expression
+Parser::OwningExprResult
+Parser::ParseCXXDeleteExpression(bool UseGlobal, SourceLocation Start) {
+  assert(Tok.is(tok::kw_delete) && "Expected 'delete' keyword");
+  ConsumeToken(); // Consume 'delete'
+
+  // Array delete?
+  bool ArrayDelete = false;
+  if (Tok.is(tok::l_square)) {
+    ArrayDelete = true;
+    SourceLocation LHS = ConsumeBracket();
+    SourceLocation RHS = MatchRHSPunctuation(tok::r_square, LHS);
+    if (RHS.isInvalid())
+      return ExprError();
+  }
+
+  OwningExprResult Operand(ParseCastExpression(false));
+  if (Operand.isInvalid())
+    return move(Operand);
+
+  return Actions.ActOnCXXDelete(Start, UseGlobal, ArrayDelete, move(Operand));
+}
+
+static UnaryTypeTrait UnaryTypeTraitFromTokKind(tok::TokenKind kind) {
+  switch(kind) {
+  default: assert(false && "Not a known unary type trait.");
+  case tok::kw___has_nothrow_assign:      return UTT_HasNothrowAssign;
+  case tok::kw___has_nothrow_copy:        return UTT_HasNothrowCopy;
+  case tok::kw___has_nothrow_constructor: return UTT_HasNothrowConstructor;
+  case tok::kw___has_trivial_assign:      return UTT_HasTrivialAssign;
+  case tok::kw___has_trivial_copy:        return UTT_HasTrivialCopy;
+  case tok::kw___has_trivial_constructor: return UTT_HasTrivialConstructor;
+  case tok::kw___has_trivial_destructor:  return UTT_HasTrivialDestructor;
+  case tok::kw___has_virtual_destructor:  return UTT_HasVirtualDestructor;
+  case tok::kw___is_abstract:             return UTT_IsAbstract;
+  case tok::kw___is_class:                return UTT_IsClass;
+  case tok::kw___is_empty:                return UTT_IsEmpty;
+  case tok::kw___is_enum:                 return UTT_IsEnum;
+  case tok::kw___is_pod:                  return UTT_IsPOD;
+  case tok::kw___is_polymorphic:          return UTT_IsPolymorphic;
+  case tok::kw___is_union:                return UTT_IsUnion;
+  case tok::kw___is_literal:              return UTT_IsLiteral;
+  }
+}
+
+/// ParseUnaryTypeTrait - Parse the built-in unary type-trait
+/// pseudo-functions that allow implementation of the TR1/C++0x type traits
+/// templates.
+///
+///       primary-expression:
+/// [GNU]             unary-type-trait '(' type-id ')'
+///
+Parser::OwningExprResult Parser::ParseUnaryTypeTrait() {
+  UnaryTypeTrait UTT = UnaryTypeTraitFromTokKind(Tok.getKind());
+  SourceLocation Loc = ConsumeToken();
+
+  SourceLocation LParen = Tok.getLocation();
+  if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen))
+    return ExprError();
+
+  // FIXME: Error reporting absolutely sucks! If the this fails to parse a type
+  // there will be cryptic errors about mismatched parentheses and missing
+  // specifiers.
+  TypeResult Ty = ParseTypeName();
+
+  SourceLocation RParen = MatchRHSPunctuation(tok::r_paren, LParen);
+
+  if (Ty.isInvalid())
+    return ExprError();
+
+  return Actions.ActOnUnaryTypeTrait(UTT, Loc, LParen, Ty.get(), RParen);
+}
+
+/// ParseCXXAmbiguousParenExpression - We have parsed the left paren of a
+/// parenthesized ambiguous type-id. This uses tentative parsing to disambiguate
+/// based on the context past the parens.
+Parser::OwningExprResult
+Parser::ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType,
+                                         TypeTy *&CastTy,
+                                         SourceLocation LParenLoc,
+                                         SourceLocation &RParenLoc) {
+  assert(getLang().CPlusPlus && "Should only be called for C++!");
+  assert(ExprType == CastExpr && "Compound literals are not ambiguous!");
+  assert(isTypeIdInParens() && "Not a type-id!");
+
+  OwningExprResult Result(Actions, true);
+  CastTy = 0;
+
+  // We need to disambiguate a very ugly part of the C++ syntax:
+  //
+  // (T())x;  - type-id
+  // (T())*x; - type-id
+  // (T())/x; - expression
+  // (T());   - expression
+  //
+  // The bad news is that we cannot use the specialized tentative parser, since
+  // it can only verify that the thing inside the parens can be parsed as
+  // type-id, it is not useful for determining the context past the parens.
+  //
+  // The good news is that the parser can disambiguate this part without
+  // making any unnecessary Action calls.
+  //
+  // It uses a scheme similar to parsing inline methods. The parenthesized
+  // tokens are cached, the context that follows is determined (possibly by
+  // parsing a cast-expression), and then we re-introduce the cached tokens
+  // into the token stream and parse them appropriately.
+
+  ParenParseOption ParseAs;
+  CachedTokens Toks;
+
+  // Store the tokens of the parentheses. We will parse them after we determine
+  // the context that follows them.
+  if (!ConsumeAndStoreUntil(tok::r_paren, Toks)) {
+    // We didn't find the ')' we expected.
+    MatchRHSPunctuation(tok::r_paren, LParenLoc);
+    return ExprError();
+  }
+
+  if (Tok.is(tok::l_brace)) {
+    ParseAs = CompoundLiteral;
+  } else {
+    bool NotCastExpr;
+    // FIXME: Special-case ++ and --: "(S())++;" is not a cast-expression
+    if (Tok.is(tok::l_paren) && NextToken().is(tok::r_paren)) {
+      NotCastExpr = true;
+    } else {
+      // Try parsing the cast-expression that may follow.
+      // If it is not a cast-expression, NotCastExpr will be true and no token
+      // will be consumed.
+      Result = ParseCastExpression(false/*isUnaryExpression*/,
+                                   false/*isAddressofOperand*/,
+                                   NotCastExpr, false);
+    }
+
+    // If we parsed a cast-expression, it's really a type-id, otherwise it's
+    // an expression.
+    ParseAs = NotCastExpr ? SimpleExpr : CastExpr;
+  }
+
+  // The current token should go after the cached tokens.
+  Toks.push_back(Tok);
+  // Re-enter the stored parenthesized tokens into the token stream, so we may
+  // parse them now.
+  PP.EnterTokenStream(Toks.data(), Toks.size(),
+                      true/*DisableMacroExpansion*/, false/*OwnsTokens*/);
+  // Drop the current token and bring the first cached one. It's the same token
+  // as when we entered this function.
+  ConsumeAnyToken();
+
+  if (ParseAs >= CompoundLiteral) {
+    TypeResult Ty = ParseTypeName();
+
+    // Match the ')'.
+    if (Tok.is(tok::r_paren))
+      RParenLoc = ConsumeParen();
+    else
+      MatchRHSPunctuation(tok::r_paren, LParenLoc);
+
+    if (ParseAs == CompoundLiteral) {
+      ExprType = CompoundLiteral;
+      return ParseCompoundLiteralExpression(Ty.get(), LParenLoc, RParenLoc);
+    }
+
+    // We parsed '(' type-id ')' and the thing after it wasn't a '{'.
+    assert(ParseAs == CastExpr);
+
+    if (Ty.isInvalid())
+      return ExprError();
+
+    CastTy = Ty.get();
+
+    // Result is what ParseCastExpression returned earlier.
+    if (!Result.isInvalid())
+      Result = Actions.ActOnCastExpr(CurScope, LParenLoc, CastTy, RParenLoc,
+                                     move(Result));
+    return move(Result);
+  }
+
+  // Not a compound literal, and not followed by a cast-expression.
+  assert(ParseAs == SimpleExpr);
+
+  ExprType = SimpleExpr;
+  Result = ParseExpression();
+  if (!Result.isInvalid() && Tok.is(tok::r_paren))
+    Result = Actions.ActOnParenExpr(LParenLoc, Tok.getLocation(), move(Result));
+
+  // Match the ')'.
+  if (Result.isInvalid()) {
+    SkipUntil(tok::r_paren);
+    return ExprError();
+  }
+
+  if (Tok.is(tok::r_paren))
+    RParenLoc = ConsumeParen();
+  else
+    MatchRHSPunctuation(tok::r_paren, LParenLoc);
+
+  return move(Result);
+}
diff --git a/lib/Parse/ParseInit.cpp b/lib/Parse/ParseInit.cpp
new file mode 100644
index 0000000..a382a9a
--- /dev/null
+++ b/lib/Parse/ParseInit.cpp
@@ -0,0 +1,376 @@
+//===--- ParseInit.cpp - Initializer Parsing ------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements initializer parsing as specified by C99 6.7.8.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Parse/Designator.h"
+#include "clang/Parse/Parser.h"
+#include "clang/Parse/ParseDiagnostic.h"
+#include "clang/Parse/Scope.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace clang;
+
+
+/// MayBeDesignationStart - Return true if this token might be the start of a
+/// designator.  If we can tell it is impossible that it is a designator, return
+/// false.
+static bool MayBeDesignationStart(tok::TokenKind K, Preprocessor &PP) {
+  switch (K) {
+  default: return false;
+  case tok::period:      // designator: '.' identifier
+  case tok::l_square:    // designator: array-designator
+      return true;
+  case tok::identifier:  // designation: identifier ':'
+    return PP.LookAhead(0).is(tok::colon);
+  }
+}
+
+static void CheckArrayDesignatorSyntax(Parser &P, SourceLocation Loc,
+                                       Designation &Desig) {
+  // If we have exactly one array designator, this used the GNU
+  // 'designation: array-designator' extension, otherwise there should be no
+  // designators at all!
+  if (Desig.getNumDesignators() == 1 &&
+      (Desig.getDesignator(0).isArrayDesignator() ||
+       Desig.getDesignator(0).isArrayRangeDesignator()))
+    P.Diag(Loc, diag::ext_gnu_missing_equal_designator);
+  else if (Desig.getNumDesignators() > 0)
+    P.Diag(Loc, diag::err_expected_equal_designator);
+}
+
+/// ParseInitializerWithPotentialDesignator - Parse the 'initializer' production
+/// checking to see if the token stream starts with a designator.
+///
+///       designation:
+///         designator-list '='
+/// [GNU]   array-designator
+/// [GNU]   identifier ':'
+///
+///       designator-list:
+///         designator
+///         designator-list designator
+///
+///       designator:
+///         array-designator
+///         '.' identifier
+///
+///       array-designator:
+///         '[' constant-expression ']'
+/// [GNU]   '[' constant-expression '...' constant-expression ']'
+///
+/// NOTE: [OBC] allows '[ objc-receiver objc-message-args ]' as an
+/// initializer (because it is an expression).  We need to consider this case
+/// when parsing array designators.
+///
+Parser::OwningExprResult Parser::ParseInitializerWithPotentialDesignator() {
+
+  // If this is the old-style GNU extension:
+  //   designation ::= identifier ':'
+  // Handle it as a field designator.  Otherwise, this must be the start of a
+  // normal expression.
+  if (Tok.is(tok::identifier)) {
+    const IdentifierInfo *FieldName = Tok.getIdentifierInfo();
+
+    llvm::SmallString<256> NewSyntax;
+    llvm::raw_svector_ostream(NewSyntax) << '.' << FieldName->getName()
+                                         << " = ";
+
+    SourceLocation NameLoc = ConsumeToken(); // Eat the identifier.
+
+    assert(Tok.is(tok::colon) && "MayBeDesignationStart not working properly!");
+    SourceLocation ColonLoc = ConsumeToken();
+
+    Diag(Tok, diag::ext_gnu_old_style_field_designator)
+      << FixItHint::CreateReplacement(SourceRange(NameLoc, ColonLoc),
+                                      NewSyntax.str());
+
+    Designation D;
+    D.AddDesignator(Designator::getField(FieldName, SourceLocation(), NameLoc));
+    return Actions.ActOnDesignatedInitializer(D, ColonLoc, true,
+                                              ParseInitializer());
+  }
+
+  // Desig - This is initialized when we see our first designator.  We may have
+  // an objc message send with no designator, so we don't want to create this
+  // eagerly.
+  Designation Desig;
+
+  // Parse each designator in the designator list until we find an initializer.
+  while (Tok.is(tok::period) || Tok.is(tok::l_square)) {
+    if (Tok.is(tok::period)) {
+      // designator: '.' identifier
+      SourceLocation DotLoc = ConsumeToken();
+
+      if (Tok.isNot(tok::identifier)) {
+        Diag(Tok.getLocation(), diag::err_expected_field_designator);
+        return ExprError();
+      }
+
+      Desig.AddDesignator(Designator::getField(Tok.getIdentifierInfo(), DotLoc,
+                                               Tok.getLocation()));
+      ConsumeToken(); // Eat the identifier.
+      continue;
+    }
+
+    // We must have either an array designator now or an objc message send.
+    assert(Tok.is(tok::l_square) && "Unexpected token!");
+
+    // Handle the two forms of array designator:
+    //   array-designator: '[' constant-expression ']'
+    //   array-designator: '[' constant-expression '...' constant-expression ']'
+    //
+    // Also, we have to handle the case where the expression after the
+    // designator an an objc message send: '[' objc-message-expr ']'.
+    // Interesting cases are:
+    //   [foo bar]         -> objc message send
+    //   [foo]             -> array designator
+    //   [foo ... bar]     -> array designator
+    //   [4][foo bar]      -> obsolete GNU designation with objc message send.
+    //
+    SourceLocation StartLoc = ConsumeBracket();
+    OwningExprResult Idx(Actions);
+
+    // If Objective-C is enabled and this is a typename (class message
+    // send) or send to 'super', parse this as a message send
+    // expression.  We handle C++ and C separately, since C++ requires
+    // much more complicated parsing.
+    if  (getLang().ObjC1 && getLang().CPlusPlus) {
+      // Send to 'super'.
+      if (Tok.is(tok::identifier) && Tok.getIdentifierInfo() == Ident_super &&
+          NextToken().isNot(tok::period) && CurScope->isInObjcMethodScope()) {
+        CheckArrayDesignatorSyntax(*this, StartLoc, Desig);
+        return ParseAssignmentExprWithObjCMessageExprStart(StartLoc,
+                                                           ConsumeToken(), 0, 
+                                                           ExprArg(Actions));
+      }
+
+      // Parse the receiver, which is either a type or an expression.
+      bool IsExpr;
+      void *TypeOrExpr;
+      if (ParseObjCXXMessageReceiver(IsExpr, TypeOrExpr)) {
+        SkipUntil(tok::r_square);
+        return ExprError();
+      }
+      
+      // If the receiver was a type, we have a class message; parse
+      // the rest of it.
+      if (!IsExpr) {
+        CheckArrayDesignatorSyntax(*this, StartLoc, Desig);
+        return ParseAssignmentExprWithObjCMessageExprStart(StartLoc, 
+                                                           SourceLocation(), 
+                                                           TypeOrExpr, 
+                                                           ExprArg(Actions));
+      }
+
+      // If the receiver was an expression, we still don't know
+      // whether we have a message send or an array designator; just
+      // adopt the expression for further analysis below.
+      // FIXME: potentially-potentially evaluated expression above?
+      Idx = OwningExprResult(Actions, TypeOrExpr);
+    } else if (getLang().ObjC1 && Tok.is(tok::identifier)) {
+      IdentifierInfo *II = Tok.getIdentifierInfo();
+      SourceLocation IILoc = Tok.getLocation();
+      TypeTy *ReceiverType;
+      // Three cases. This is a message send to a type: [type foo]
+      // This is a message send to super:  [super foo]
+      // This is a message sent to an expr:  [super.bar foo]
+      switch (Action::ObjCMessageKind Kind
+                = Actions.getObjCMessageKind(CurScope, II, IILoc, 
+                                             II == Ident_super,
+                                             NextToken().is(tok::period),
+                                             ReceiverType)) {
+      case Action::ObjCSuperMessage:
+      case Action::ObjCClassMessage:
+        CheckArrayDesignatorSyntax(*this, StartLoc, Desig);
+        if (Kind == Action::ObjCSuperMessage)
+          return ParseAssignmentExprWithObjCMessageExprStart(StartLoc,
+                                                             ConsumeToken(),
+                                                             0,
+                                                             ExprArg(Actions));
+        ConsumeToken(); // the identifier
+        if (!ReceiverType) {
+          SkipUntil(tok::r_square);
+          return ExprError();
+        }
+
+        return ParseAssignmentExprWithObjCMessageExprStart(StartLoc, 
+                                                           SourceLocation(), 
+                                                           ReceiverType, 
+                                                           ExprArg(Actions));
+
+      case Action::ObjCInstanceMessage:
+        // Fall through; we'll just parse the expression and
+        // (possibly) treat this like an Objective-C message send
+        // later.
+        break;
+      }
+    }
+
+    // Parse the index expression, if we haven't already gotten one
+    // above (which can only happen in Objective-C++).
+    // Note that we parse this as an assignment expression, not a constant
+    // expression (allowing *=, =, etc) to handle the objc case.  Sema needs
+    // to validate that the expression is a constant.
+    // FIXME: We also need to tell Sema that we're in a
+    // potentially-potentially evaluated context.
+    if (!Idx.get()) {
+      Idx = ParseAssignmentExpression();
+      if (Idx.isInvalid()) {
+        SkipUntil(tok::r_square);
+        return move(Idx);
+      }
+    }
+
+    // Given an expression, we could either have a designator (if the next
+    // tokens are '...' or ']' or an objc message send.  If this is an objc
+    // message send, handle it now.  An objc-message send is the start of
+    // an assignment-expression production.
+    if (getLang().ObjC1 && Tok.isNot(tok::ellipsis) &&
+        Tok.isNot(tok::r_square)) {
+      CheckArrayDesignatorSyntax(*this, Tok.getLocation(), Desig);
+      return ParseAssignmentExprWithObjCMessageExprStart(StartLoc,
+                                                         SourceLocation(),
+                                                         0, move(Idx));
+    }
+
+    // If this is a normal array designator, remember it.
+    if (Tok.isNot(tok::ellipsis)) {
+      Desig.AddDesignator(Designator::getArray(Idx.release(), StartLoc));
+    } else {
+      // Handle the gnu array range extension.
+      Diag(Tok, diag::ext_gnu_array_range);
+      SourceLocation EllipsisLoc = ConsumeToken();
+
+      OwningExprResult RHS(ParseConstantExpression());
+      if (RHS.isInvalid()) {
+        SkipUntil(tok::r_square);
+        return move(RHS);
+      }
+      Desig.AddDesignator(Designator::getArrayRange(Idx.release(),
+                                                    RHS.release(),
+                                                    StartLoc, EllipsisLoc));
+    }
+
+    SourceLocation EndLoc = MatchRHSPunctuation(tok::r_square, StartLoc);
+    Desig.getDesignator(Desig.getNumDesignators() - 1).setRBracketLoc(EndLoc);
+  }
+
+  // Okay, we're done with the designator sequence.  We know that there must be
+  // at least one designator, because the only case we can get into this method
+  // without a designator is when we have an objc message send.  That case is
+  // handled and returned from above.
+  assert(!Desig.empty() && "Designator is empty?");
+
+  // Handle a normal designator sequence end, which is an equal.
+  if (Tok.is(tok::equal)) {
+    SourceLocation EqualLoc = ConsumeToken();
+    return Actions.ActOnDesignatedInitializer(Desig, EqualLoc, false,
+                                              ParseInitializer());
+  }
+
+  // We read some number of designators and found something that isn't an = or
+  // an initializer.  If we have exactly one array designator, this
+  // is the GNU 'designation: array-designator' extension.  Otherwise, it is a
+  // parse error.
+  if (Desig.getNumDesignators() == 1 &&
+      (Desig.getDesignator(0).isArrayDesignator() ||
+       Desig.getDesignator(0).isArrayRangeDesignator())) {
+    Diag(Tok, diag::ext_gnu_missing_equal_designator)
+      << FixItHint::CreateInsertion(Tok.getLocation(), "= ");
+    return Actions.ActOnDesignatedInitializer(Desig, Tok.getLocation(),
+                                              true, ParseInitializer());
+  }
+
+  Diag(Tok, diag::err_expected_equal_designator);
+  return ExprError();
+}
+
+
+/// ParseBraceInitializer - Called when parsing an initializer that has a
+/// leading open brace.
+///
+///       initializer: [C99 6.7.8]
+///         '{' initializer-list '}'
+///         '{' initializer-list ',' '}'
+/// [GNU]   '{' '}'
+///
+///       initializer-list:
+///         designation[opt] initializer
+///         initializer-list ',' designation[opt] initializer
+///
+Parser::OwningExprResult Parser::ParseBraceInitializer() {
+  SourceLocation LBraceLoc = ConsumeBrace();
+
+  /// InitExprs - This is the actual list of expressions contained in the
+  /// initializer.
+  ExprVector InitExprs(Actions);
+
+  if (Tok.is(tok::r_brace)) {
+    // Empty initializers are a C++ feature and a GNU extension to C.
+    if (!getLang().CPlusPlus)
+      Diag(LBraceLoc, diag::ext_gnu_empty_initializer);
+    // Match the '}'.
+    return Actions.ActOnInitList(LBraceLoc, Action::MultiExprArg(Actions),
+                                 ConsumeBrace());
+  }
+
+  bool InitExprsOk = true;
+
+  while (1) {
+    // Parse: designation[opt] initializer
+
+    // If we know that this cannot be a designation, just parse the nested
+    // initializer directly.
+    OwningExprResult SubElt(Actions);
+    if (MayBeDesignationStart(Tok.getKind(), PP))
+      SubElt = ParseInitializerWithPotentialDesignator();
+    else
+      SubElt = ParseInitializer();
+
+    // If we couldn't parse the subelement, bail out.
+    if (!SubElt.isInvalid()) {
+      InitExprs.push_back(SubElt.release());
+    } else {
+      InitExprsOk = false;
+
+      // We have two ways to try to recover from this error: if the code looks
+      // gramatically ok (i.e. we have a comma coming up) try to continue
+      // parsing the rest of the initializer.  This allows us to emit
+      // diagnostics for later elements that we find.  If we don't see a comma,
+      // assume there is a parse error, and just skip to recover.
+      // FIXME: This comment doesn't sound right. If there is a r_brace
+      // immediately, it can't be an error, since there is no other way of
+      // leaving this loop except through this if.
+      if (Tok.isNot(tok::comma)) {
+        SkipUntil(tok::r_brace, false, true);
+        break;
+      }
+    }
+
+    // If we don't have a comma continued list, we're done.
+    if (Tok.isNot(tok::comma)) break;
+
+    // TODO: save comma locations if some client cares.
+    ConsumeToken();
+
+    // Handle trailing comma.
+    if (Tok.is(tok::r_brace)) break;
+  }
+  if (InitExprsOk && Tok.is(tok::r_brace))
+    return Actions.ActOnInitList(LBraceLoc, move_arg(InitExprs),
+                                 ConsumeBrace());
+
+  // Match the '}'.
+  MatchRHSPunctuation(tok::r_brace, LBraceLoc);
+  return ExprError(); // an error occurred.
+}
+
diff --git a/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp
new file mode 100644
index 0000000..7b1ecf6
--- /dev/null
+++ b/lib/Parse/ParseObjc.cpp
@@ -0,0 +1,2171 @@
+//===--- ParseObjC.cpp - Objective C Parsing ------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements the Objective-C portions of the Parser interface.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Parse/Parser.h"
+#include "clang/Parse/DeclSpec.h"
+#include "clang/Parse/Scope.h"
+#include "clang/Parse/ParseDiagnostic.h"
+#include "llvm/ADT/SmallVector.h"
+using namespace clang;
+
+
+/// ParseObjCAtDirectives - Handle parts of the external-declaration production:
+///       external-declaration: [C99 6.9]
+/// [OBJC]  objc-class-definition
+/// [OBJC]  objc-class-declaration
+/// [OBJC]  objc-alias-declaration
+/// [OBJC]  objc-protocol-definition
+/// [OBJC]  objc-method-definition
+/// [OBJC]  '@' 'end'
+Parser::DeclPtrTy Parser::ParseObjCAtDirectives() {
+  SourceLocation AtLoc = ConsumeToken(); // the "@"
+
+  if (Tok.is(tok::code_completion)) {
+    Actions.CodeCompleteObjCAtDirective(CurScope, ObjCImpDecl, false);
+    ConsumeToken();
+  }
+
+  switch (Tok.getObjCKeywordID()) {
+  case tok::objc_class:
+    return ParseObjCAtClassDeclaration(AtLoc);
+  case tok::objc_interface:
+    return ParseObjCAtInterfaceDeclaration(AtLoc);
+  case tok::objc_protocol:
+    return ParseObjCAtProtocolDeclaration(AtLoc);
+  case tok::objc_implementation:
+    return ParseObjCAtImplementationDeclaration(AtLoc);
+  case tok::objc_end:
+    return ParseObjCAtEndDeclaration(AtLoc);
+  case tok::objc_compatibility_alias:
+    return ParseObjCAtAliasDeclaration(AtLoc);
+  case tok::objc_synthesize:
+    return ParseObjCPropertySynthesize(AtLoc);
+  case tok::objc_dynamic:
+    return ParseObjCPropertyDynamic(AtLoc);
+  default:
+    Diag(AtLoc, diag::err_unexpected_at);
+    SkipUntil(tok::semi);
+    return DeclPtrTy();
+  }
+}
+
+///
+/// objc-class-declaration:
+///    '@' 'class' identifier-list ';'
+///
+Parser::DeclPtrTy Parser::ParseObjCAtClassDeclaration(SourceLocation atLoc) {
+  ConsumeToken(); // the identifier "class"
+  llvm::SmallVector<IdentifierInfo *, 8> ClassNames;
+  llvm::SmallVector<SourceLocation, 8> ClassLocs;
+
+
+  while (1) {
+    if (Tok.isNot(tok::identifier)) {
+      Diag(Tok, diag::err_expected_ident);
+      SkipUntil(tok::semi);
+      return DeclPtrTy();
+    }
+    ClassNames.push_back(Tok.getIdentifierInfo());
+    ClassLocs.push_back(Tok.getLocation());
+    ConsumeToken();
+
+    if (Tok.isNot(tok::comma))
+      break;
+
+    ConsumeToken();
+  }
+
+  // Consume the ';'.
+  if (ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "@class"))
+    return DeclPtrTy();
+
+  return Actions.ActOnForwardClassDeclaration(atLoc, ClassNames.data(),
+                                              ClassLocs.data(),
+                                              ClassNames.size());
+}
+
+///
+///   objc-interface:
+///     objc-class-interface-attributes[opt] objc-class-interface
+///     objc-category-interface
+///
+///   objc-class-interface:
+///     '@' 'interface' identifier objc-superclass[opt]
+///       objc-protocol-refs[opt]
+///       objc-class-instance-variables[opt]
+///       objc-interface-decl-list
+///     @end
+///
+///   objc-category-interface:
+///     '@' 'interface' identifier '(' identifier[opt] ')'
+///       objc-protocol-refs[opt]
+///       objc-interface-decl-list
+///     @end
+///
+///   objc-superclass:
+///     ':' identifier
+///
+///   objc-class-interface-attributes:
+///     __attribute__((visibility("default")))
+///     __attribute__((visibility("hidden")))
+///     __attribute__((deprecated))
+///     __attribute__((unavailable))
+///     __attribute__((objc_exception)) - used by NSException on 64-bit
+///
+Parser::DeclPtrTy Parser::ParseObjCAtInterfaceDeclaration(
+  SourceLocation atLoc, AttributeList *attrList) {
+  assert(Tok.isObjCAtKeyword(tok::objc_interface) &&
+         "ParseObjCAtInterfaceDeclaration(): Expected @interface");
+  ConsumeToken(); // the "interface" identifier
+
+  // Code completion after '@interface'.
+  if (Tok.is(tok::code_completion)) {
+    Actions.CodeCompleteObjCInterfaceDecl(CurScope);
+    ConsumeToken();
+  }
+
+  if (Tok.isNot(tok::identifier)) {
+    Diag(Tok, diag::err_expected_ident); // missing class or category name.
+    return DeclPtrTy();
+  }
+
+  // We have a class or category name - consume it.
+  IdentifierInfo *nameId = Tok.getIdentifierInfo();
+  SourceLocation nameLoc = ConsumeToken();
+  if (Tok.is(tok::l_paren) && 
+      !isKnownToBeTypeSpecifier(GetLookAheadToken(1))) { // we have a category.
+    SourceLocation lparenLoc = ConsumeParen();
+    SourceLocation categoryLoc, rparenLoc;
+    IdentifierInfo *categoryId = 0;
+    if (Tok.is(tok::code_completion)) {
+      Actions.CodeCompleteObjCInterfaceCategory(CurScope, nameId, nameLoc);
+      ConsumeToken();
+    }
+    
+    // For ObjC2, the category name is optional (not an error).
+    if (Tok.is(tok::identifier)) {
+      categoryId = Tok.getIdentifierInfo();
+      categoryLoc = ConsumeToken();
+    }
+    else if (!getLang().ObjC2) {
+      Diag(Tok, diag::err_expected_ident); // missing category name.
+      return DeclPtrTy();
+    }
+    if (Tok.isNot(tok::r_paren)) {
+      Diag(Tok, diag::err_expected_rparen);
+      SkipUntil(tok::r_paren, false); // don't stop at ';'
+      return DeclPtrTy();
+    }
+    rparenLoc = ConsumeParen();
+    // Next, we need to check for any protocol references.
+    SourceLocation LAngleLoc, EndProtoLoc;
+    llvm::SmallVector<DeclPtrTy, 8> ProtocolRefs;
+    llvm::SmallVector<SourceLocation, 8> ProtocolLocs;
+    if (Tok.is(tok::less) &&
+        ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs, true,
+                                    LAngleLoc, EndProtoLoc))
+      return DeclPtrTy();
+
+    if (attrList) // categories don't support attributes.
+      Diag(Tok, diag::err_objc_no_attributes_on_category);
+
+    DeclPtrTy CategoryType =
+    Actions.ActOnStartCategoryInterface(atLoc,
+                                        nameId, nameLoc,
+                                        categoryId, categoryLoc,
+                                        ProtocolRefs.data(),
+                                        ProtocolRefs.size(),
+                                        ProtocolLocs.data(),
+                                        EndProtoLoc);
+    if (Tok.is(tok::l_brace))
+      ParseObjCClassInstanceVariables(CategoryType, tok::objc_private,
+                                      atLoc);
+    
+    ParseObjCInterfaceDeclList(CategoryType, tok::objc_not_keyword);
+    return CategoryType;
+  }
+  // Parse a class interface.
+  IdentifierInfo *superClassId = 0;
+  SourceLocation superClassLoc;
+
+  if (Tok.is(tok::colon)) { // a super class is specified.
+    ConsumeToken();
+
+    // Code completion of superclass names.
+    if (Tok.is(tok::code_completion)) {
+      Actions.CodeCompleteObjCSuperclass(CurScope, nameId, nameLoc);
+      ConsumeToken();
+    }
+
+    if (Tok.isNot(tok::identifier)) {
+      Diag(Tok, diag::err_expected_ident); // missing super class name.
+      return DeclPtrTy();
+    }
+    superClassId = Tok.getIdentifierInfo();
+    superClassLoc = ConsumeToken();
+  }
+  // Next, we need to check for any protocol references.
+  llvm::SmallVector<Action::DeclPtrTy, 8> ProtocolRefs;
+  llvm::SmallVector<SourceLocation, 8> ProtocolLocs;
+  SourceLocation LAngleLoc, EndProtoLoc;
+  if (Tok.is(tok::less) &&
+      ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs, true,
+                                  LAngleLoc, EndProtoLoc))
+    return DeclPtrTy();
+
+  DeclPtrTy ClsType =
+    Actions.ActOnStartClassInterface(atLoc, nameId, nameLoc,
+                                     superClassId, superClassLoc,
+                                     ProtocolRefs.data(), ProtocolRefs.size(),
+                                     ProtocolLocs.data(),
+                                     EndProtoLoc, attrList);
+
+  if (Tok.is(tok::l_brace))
+    ParseObjCClassInstanceVariables(ClsType, tok::objc_protected, atLoc);
+
+  ParseObjCInterfaceDeclList(ClsType, tok::objc_interface);
+  return ClsType;
+}
+
+/// The Objective-C property callback.  This should be defined where
+/// it's used, but instead it's been lifted to here to support VS2005.
+struct Parser::ObjCPropertyCallback : FieldCallback {
+  Parser &P;
+  DeclPtrTy IDecl;
+  llvm::SmallVectorImpl<DeclPtrTy> &Props;
+  ObjCDeclSpec &OCDS;
+  SourceLocation AtLoc;
+  tok::ObjCKeywordKind MethodImplKind;
+        
+  ObjCPropertyCallback(Parser &P, DeclPtrTy IDecl,
+                       llvm::SmallVectorImpl<DeclPtrTy> &Props,
+                       ObjCDeclSpec &OCDS, SourceLocation AtLoc,
+                       tok::ObjCKeywordKind MethodImplKind) :
+    P(P), IDecl(IDecl), Props(Props), OCDS(OCDS), AtLoc(AtLoc),
+    MethodImplKind(MethodImplKind) {
+  }
+
+  DeclPtrTy invoke(FieldDeclarator &FD) {
+    if (FD.D.getIdentifier() == 0) {
+      P.Diag(AtLoc, diag::err_objc_property_requires_field_name)
+        << FD.D.getSourceRange();
+      return DeclPtrTy();
+    }
+    if (FD.BitfieldSize) {
+      P.Diag(AtLoc, diag::err_objc_property_bitfield)
+        << FD.D.getSourceRange();
+      return DeclPtrTy();
+    }
+
+    // Install the property declarator into interfaceDecl.
+    IdentifierInfo *SelName =
+      OCDS.getGetterName() ? OCDS.getGetterName() : FD.D.getIdentifier();
+
+    Selector GetterSel =
+      P.PP.getSelectorTable().getNullarySelector(SelName);
+    IdentifierInfo *SetterName = OCDS.getSetterName();
+    Selector SetterSel;
+    if (SetterName)
+      SetterSel = P.PP.getSelectorTable().getSelector(1, &SetterName);
+    else
+      SetterSel = SelectorTable::constructSetterName(P.PP.getIdentifierTable(),
+                                                     P.PP.getSelectorTable(),
+                                                     FD.D.getIdentifier());
+    bool isOverridingProperty = false;
+    DeclPtrTy Property =
+      P.Actions.ActOnProperty(P.CurScope, AtLoc, FD, OCDS,
+                              GetterSel, SetterSel, IDecl,
+                              &isOverridingProperty,
+                              MethodImplKind);
+    if (!isOverridingProperty)
+      Props.push_back(Property);
+
+    return Property;
+  }
+};
+
+///   objc-interface-decl-list:
+///     empty
+///     objc-interface-decl-list objc-property-decl [OBJC2]
+///     objc-interface-decl-list objc-method-requirement [OBJC2]
+///     objc-interface-decl-list objc-method-proto ';'
+///     objc-interface-decl-list declaration
+///     objc-interface-decl-list ';'
+///
+///   objc-method-requirement: [OBJC2]
+///     @required
+///     @optional
+///
+void Parser::ParseObjCInterfaceDeclList(DeclPtrTy interfaceDecl,
+                                        tok::ObjCKeywordKind contextKey) {
+  llvm::SmallVector<DeclPtrTy, 32> allMethods;
+  llvm::SmallVector<DeclPtrTy, 16> allProperties;
+  llvm::SmallVector<DeclGroupPtrTy, 8> allTUVariables;
+  tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword;
+
+  SourceRange AtEnd;
+
+  while (1) {
+    // If this is a method prototype, parse it.
+    if (Tok.is(tok::minus) || Tok.is(tok::plus)) {
+      DeclPtrTy methodPrototype =
+        ParseObjCMethodPrototype(interfaceDecl, MethodImplKind);
+      allMethods.push_back(methodPrototype);
+      // Consume the ';' here, since ParseObjCMethodPrototype() is re-used for
+      // method definitions.
+      ExpectAndConsume(tok::semi, diag::err_expected_semi_after_method_proto,
+                       "", tok::semi);
+      continue;
+    }
+    if (Tok.is(tok::l_paren)) {
+      Diag(Tok, diag::err_expected_minus_or_plus);
+      DeclPtrTy methodPrototype = ParseObjCMethodDecl(Tok.getLocation(), 
+                                                      tok::minus, 
+                                                      interfaceDecl,
+                                                      MethodImplKind);
+      continue;
+    }
+    // Ignore excess semicolons.
+    if (Tok.is(tok::semi)) {
+      ConsumeToken();
+      continue;
+    }
+
+    // If we got to the end of the file, exit the loop.
+    if (Tok.is(tok::eof))
+      break;
+
+    // Code completion within an Objective-C interface.
+    if (Tok.is(tok::code_completion)) {
+      Actions.CodeCompleteOrdinaryName(CurScope, 
+                                  ObjCImpDecl? Action::CCC_ObjCImplementation
+                                             : Action::CCC_ObjCInterface);
+      ConsumeToken();
+    }
+    
+    // If we don't have an @ directive, parse it as a function definition.
+    if (Tok.isNot(tok::at)) {
+      // The code below does not consume '}'s because it is afraid of eating the
+      // end of a namespace.  Because of the way this code is structured, an
+      // erroneous r_brace would cause an infinite loop if not handled here.
+      if (Tok.is(tok::r_brace))
+        break;
+
+      // FIXME: as the name implies, this rule allows function definitions.
+      // We could pass a flag or check for functions during semantic analysis.
+      allTUVariables.push_back(ParseDeclarationOrFunctionDefinition(0));
+      continue;
+    }
+
+    // Otherwise, we have an @ directive, eat the @.
+    SourceLocation AtLoc = ConsumeToken(); // the "@"
+    if (Tok.is(tok::code_completion)) {
+      Actions.CodeCompleteObjCAtDirective(CurScope, ObjCImpDecl, true);
+      ConsumeToken();
+      break;
+    }
+
+    tok::ObjCKeywordKind DirectiveKind = Tok.getObjCKeywordID();
+
+    if (DirectiveKind == tok::objc_end) { // @end -> terminate list
+      AtEnd.setBegin(AtLoc);
+      AtEnd.setEnd(Tok.getLocation());
+      break;
+    } else if (DirectiveKind == tok::objc_not_keyword) {
+      Diag(Tok, diag::err_objc_unknown_at);
+      SkipUntil(tok::semi);
+      continue;
+    }
+
+    // Eat the identifier.
+    ConsumeToken();
+
+    switch (DirectiveKind) {
+    default:
+      // FIXME: If someone forgets an @end on a protocol, this loop will
+      // continue to eat up tons of stuff and spew lots of nonsense errors.  It
+      // would probably be better to bail out if we saw an @class or @interface
+      // or something like that.
+      Diag(AtLoc, diag::err_objc_illegal_interface_qual);
+      // Skip until we see an '@' or '}' or ';'.
+      SkipUntil(tok::r_brace, tok::at);
+      break;
+
+    case tok::objc_required:
+    case tok::objc_optional:
+      // This is only valid on protocols.
+      // FIXME: Should this check for ObjC2 being enabled?
+      if (contextKey != tok::objc_protocol)
+        Diag(AtLoc, diag::err_objc_directive_only_in_protocol);
+      else
+        MethodImplKind = DirectiveKind;
+      break;
+
+    case tok::objc_property:
+      if (!getLang().ObjC2)
+        Diag(AtLoc, diag::err_objc_propertoes_require_objc2);
+
+      ObjCDeclSpec OCDS;
+      // Parse property attribute list, if any.
+      if (Tok.is(tok::l_paren))
+        ParseObjCPropertyAttribute(OCDS, interfaceDecl,
+                                   allMethods.data(), allMethods.size());
+
+      ObjCPropertyCallback Callback(*this, interfaceDecl, allProperties,
+                                    OCDS, AtLoc, MethodImplKind);
+
+      // Parse all the comma separated declarators.
+      DeclSpec DS;
+      ParseStructDeclaration(DS, Callback);
+
+      ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list, "",
+                       tok::at);
+      break;
+    }
+  }
+
+  // We break out of the big loop in two cases: when we see @end or when we see
+  // EOF.  In the former case, eat the @end.  In the later case, emit an error.
+  if (Tok.is(tok::code_completion)) {
+    Actions.CodeCompleteObjCAtDirective(CurScope, ObjCImpDecl, true);
+    ConsumeToken();
+  } else if (Tok.isObjCAtKeyword(tok::objc_end))
+    ConsumeToken(); // the "end" identifier
+  else
+    Diag(Tok, diag::err_objc_missing_end);
+
+  // Insert collected methods declarations into the @interface object.
+  // This passes in an invalid SourceLocation for AtEndLoc when EOF is hit.
+  Actions.ActOnAtEnd(AtEnd, interfaceDecl,
+                     allMethods.data(), allMethods.size(),
+                     allProperties.data(), allProperties.size(),
+                     allTUVariables.data(), allTUVariables.size());
+}
+
+///   Parse property attribute declarations.
+///
+///   property-attr-decl: '(' property-attrlist ')'
+///   property-attrlist:
+///     property-attribute
+///     property-attrlist ',' property-attribute
+///   property-attribute:
+///     getter '=' identifier
+///     setter '=' identifier ':'
+///     readonly
+///     readwrite
+///     assign
+///     retain
+///     copy
+///     nonatomic
+///
+void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS, DeclPtrTy ClassDecl,
+                                        DeclPtrTy *Methods, 
+                                        unsigned NumMethods) {
+  assert(Tok.getKind() == tok::l_paren);
+  SourceLocation LHSLoc = ConsumeParen(); // consume '('
+
+  while (1) {
+    if (Tok.is(tok::code_completion)) {
+      Actions.CodeCompleteObjCPropertyFlags(CurScope, DS);
+      ConsumeToken();
+    }
+    const IdentifierInfo *II = Tok.getIdentifierInfo();
+
+    // If this is not an identifier at all, bail out early.
+    if (II == 0) {
+      MatchRHSPunctuation(tok::r_paren, LHSLoc);
+      return;
+    }
+
+    SourceLocation AttrName = ConsumeToken(); // consume last attribute name
+
+    if (II->isStr("readonly"))
+      DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_readonly);
+    else if (II->isStr("assign"))
+      DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_assign);
+    else if (II->isStr("readwrite"))
+      DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_readwrite);
+    else if (II->isStr("retain"))
+      DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_retain);
+    else if (II->isStr("copy"))
+      DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_copy);
+    else if (II->isStr("nonatomic"))
+      DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_nonatomic);
+    else if (II->isStr("getter") || II->isStr("setter")) {
+      // getter/setter require extra treatment.
+      if (ExpectAndConsume(tok::equal, diag::err_objc_expected_equal, "",
+                           tok::r_paren))
+        return;
+
+      if (Tok.is(tok::code_completion)) {
+        if (II->getNameStart()[0] == 's')
+          Actions.CodeCompleteObjCPropertySetter(CurScope, ClassDecl,
+                                                 Methods, NumMethods);
+        else
+          Actions.CodeCompleteObjCPropertyGetter(CurScope, ClassDecl,
+                                                 Methods, NumMethods);
+        ConsumeToken();
+      }
+
+      if (Tok.isNot(tok::identifier)) {
+        Diag(Tok, diag::err_expected_ident);
+        SkipUntil(tok::r_paren);
+        return;
+      }
+
+      if (II->getNameStart()[0] == 's') {
+        DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_setter);
+        DS.setSetterName(Tok.getIdentifierInfo());
+        ConsumeToken();  // consume method name
+
+        if (ExpectAndConsume(tok::colon, 
+                             diag::err_expected_colon_after_setter_name, "",
+                             tok::r_paren))
+          return;
+      } else {
+        DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_getter);
+        DS.setGetterName(Tok.getIdentifierInfo());
+        ConsumeToken();  // consume method name
+      }
+    } else {
+      Diag(AttrName, diag::err_objc_expected_property_attr) << II;
+      SkipUntil(tok::r_paren);
+      return;
+    }
+
+    if (Tok.isNot(tok::comma))
+      break;
+
+    ConsumeToken();
+  }
+
+  MatchRHSPunctuation(tok::r_paren, LHSLoc);
+}
+
+///   objc-method-proto:
+///     objc-instance-method objc-method-decl objc-method-attributes[opt]
+///     objc-class-method objc-method-decl objc-method-attributes[opt]
+///
+///   objc-instance-method: '-'
+///   objc-class-method: '+'
+///
+///   objc-method-attributes:         [OBJC2]
+///     __attribute__((deprecated))
+///
+Parser::DeclPtrTy Parser::ParseObjCMethodPrototype(DeclPtrTy IDecl,
+                                          tok::ObjCKeywordKind MethodImplKind) {
+  assert((Tok.is(tok::minus) || Tok.is(tok::plus)) && "expected +/-");
+
+  tok::TokenKind methodType = Tok.getKind();
+  SourceLocation mLoc = ConsumeToken();
+
+  DeclPtrTy MDecl = ParseObjCMethodDecl(mLoc, methodType, IDecl,MethodImplKind);
+  // Since this rule is used for both method declarations and definitions,
+  // the caller is (optionally) responsible for consuming the ';'.
+  return MDecl;
+}
+
+///   objc-selector:
+///     identifier
+///     one of
+///       enum struct union if else while do for switch case default
+///       break continue return goto asm sizeof typeof __alignof
+///       unsigned long const short volatile signed restrict _Complex
+///       in out inout bycopy byref oneway int char float double void _Bool
+///
+IdentifierInfo *Parser::ParseObjCSelectorPiece(SourceLocation &SelectorLoc) {
+  switch (Tok.getKind()) {
+  default:
+    return 0;
+  case tok::identifier:
+  case tok::kw_asm:
+  case tok::kw_auto:
+  case tok::kw_bool:
+  case tok::kw_break:
+  case tok::kw_case:
+  case tok::kw_catch:
+  case tok::kw_char:
+  case tok::kw_class:
+  case tok::kw_const:
+  case tok::kw_const_cast:
+  case tok::kw_continue:
+  case tok::kw_default:
+  case tok::kw_delete:
+  case tok::kw_do:
+  case tok::kw_double:
+  case tok::kw_dynamic_cast:
+  case tok::kw_else:
+  case tok::kw_enum:
+  case tok::kw_explicit:
+  case tok::kw_export:
+  case tok::kw_extern:
+  case tok::kw_false:
+  case tok::kw_float:
+  case tok::kw_for:
+  case tok::kw_friend:
+  case tok::kw_goto:
+  case tok::kw_if:
+  case tok::kw_inline:
+  case tok::kw_int:
+  case tok::kw_long:
+  case tok::kw_mutable:
+  case tok::kw_namespace:
+  case tok::kw_new:
+  case tok::kw_operator:
+  case tok::kw_private:
+  case tok::kw_protected:
+  case tok::kw_public:
+  case tok::kw_register:
+  case tok::kw_reinterpret_cast:
+  case tok::kw_restrict:
+  case tok::kw_return:
+  case tok::kw_short:
+  case tok::kw_signed:
+  case tok::kw_sizeof:
+  case tok::kw_static:
+  case tok::kw_static_cast:
+  case tok::kw_struct:
+  case tok::kw_switch:
+  case tok::kw_template:
+  case tok::kw_this:
+  case tok::kw_throw:
+  case tok::kw_true:
+  case tok::kw_try:
+  case tok::kw_typedef:
+  case tok::kw_typeid:
+  case tok::kw_typename:
+  case tok::kw_typeof:
+  case tok::kw_union:
+  case tok::kw_unsigned:
+  case tok::kw_using:
+  case tok::kw_virtual:
+  case tok::kw_void:
+  case tok::kw_volatile:
+  case tok::kw_wchar_t:
+  case tok::kw_while:
+  case tok::kw__Bool:
+  case tok::kw__Complex:
+  case tok::kw___alignof:
+    IdentifierInfo *II = Tok.getIdentifierInfo();
+    SelectorLoc = ConsumeToken();
+    return II;
+  }
+}
+
+///  objc-for-collection-in: 'in'
+///
+bool Parser::isTokIdentifier_in() const {
+  // FIXME: May have to do additional look-ahead to only allow for
+  // valid tokens following an 'in'; such as an identifier, unary operators,
+  // '[' etc.
+  return (getLang().ObjC2 && Tok.is(tok::identifier) &&
+          Tok.getIdentifierInfo() == ObjCTypeQuals[objc_in]);
+}
+
+/// ParseObjCTypeQualifierList - This routine parses the objective-c's type
+/// qualifier list and builds their bitmask representation in the input
+/// argument.
+///
+///   objc-type-qualifiers:
+///     objc-type-qualifier
+///     objc-type-qualifiers objc-type-qualifier
+///
+void Parser::ParseObjCTypeQualifierList(ObjCDeclSpec &DS) {
+  while (1) {
+    if (Tok.isNot(tok::identifier))
+      return;
+
+    const IdentifierInfo *II = Tok.getIdentifierInfo();
+    for (unsigned i = 0; i != objc_NumQuals; ++i) {
+      if (II != ObjCTypeQuals[i])
+        continue;
+
+      ObjCDeclSpec::ObjCDeclQualifier Qual;
+      switch (i) {
+      default: assert(0 && "Unknown decl qualifier");
+      case objc_in:     Qual = ObjCDeclSpec::DQ_In; break;
+      case objc_out:    Qual = ObjCDeclSpec::DQ_Out; break;
+      case objc_inout:  Qual = ObjCDeclSpec::DQ_Inout; break;
+      case objc_oneway: Qual = ObjCDeclSpec::DQ_Oneway; break;
+      case objc_bycopy: Qual = ObjCDeclSpec::DQ_Bycopy; break;
+      case objc_byref:  Qual = ObjCDeclSpec::DQ_Byref; break;
+      }
+      DS.setObjCDeclQualifier(Qual);
+      ConsumeToken();
+      II = 0;
+      break;
+    }
+
+    // If this wasn't a recognized qualifier, bail out.
+    if (II) return;
+  }
+}
+
+///   objc-type-name:
+///     '(' objc-type-qualifiers[opt] type-name ')'
+///     '(' objc-type-qualifiers[opt] ')'
+///
+Parser::TypeTy *Parser::ParseObjCTypeName(ObjCDeclSpec &DS) {
+  assert(Tok.is(tok::l_paren) && "expected (");
+
+  SourceLocation LParenLoc = ConsumeParen();
+  SourceLocation TypeStartLoc = Tok.getLocation();
+
+  // Parse type qualifiers, in, inout, etc.
+  ParseObjCTypeQualifierList(DS);
+
+  TypeTy *Ty = 0;
+  if (isTypeSpecifierQualifier()) {
+    TypeResult TypeSpec = ParseTypeName();
+    if (!TypeSpec.isInvalid())
+      Ty = TypeSpec.get();
+  }
+
+  if (Tok.is(tok::r_paren))
+    ConsumeParen();
+  else if (Tok.getLocation() == TypeStartLoc) {
+    // If we didn't eat any tokens, then this isn't a type.
+    Diag(Tok, diag::err_expected_type);
+    SkipUntil(tok::r_paren);
+  } else {
+    // Otherwise, we found *something*, but didn't get a ')' in the right
+    // place.  Emit an error then return what we have as the type.
+    MatchRHSPunctuation(tok::r_paren, LParenLoc);
+  }
+  return Ty;
+}
+
+///   objc-method-decl:
+///     objc-selector
+///     objc-keyword-selector objc-parmlist[opt]
+///     objc-type-name objc-selector
+///     objc-type-name objc-keyword-selector objc-parmlist[opt]
+///
+///   objc-keyword-selector:
+///     objc-keyword-decl
+///     objc-keyword-selector objc-keyword-decl
+///
+///   objc-keyword-decl:
+///     objc-selector ':' objc-type-name objc-keyword-attributes[opt] identifier
+///     objc-selector ':' objc-keyword-attributes[opt] identifier
+///     ':' objc-type-name objc-keyword-attributes[opt] identifier
+///     ':' objc-keyword-attributes[opt] identifier
+///
+///   objc-parmlist:
+///     objc-parms objc-ellipsis[opt]
+///
+///   objc-parms:
+///     objc-parms , parameter-declaration
+///
+///   objc-ellipsis:
+///     , ...
+///
+///   objc-keyword-attributes:         [OBJC2]
+///     __attribute__((unused))
+///
+Parser::DeclPtrTy Parser::ParseObjCMethodDecl(SourceLocation mLoc,
+                                              tok::TokenKind mType,
+                                              DeclPtrTy IDecl,
+                                          tok::ObjCKeywordKind MethodImplKind) {
+  ParsingDeclRAIIObject PD(*this);
+
+  if (Tok.is(tok::code_completion)) {
+    Actions.CodeCompleteObjCMethodDecl(CurScope, mType == tok::minus, 
+                                       /*ReturnType=*/0, IDecl);
+    ConsumeToken();
+  }
+
+  // Parse the return type if present.
+  TypeTy *ReturnType = 0;
+  ObjCDeclSpec DSRet;
+  if (Tok.is(tok::l_paren))
+    ReturnType = ParseObjCTypeName(DSRet);
+
+  // If attributes exist before the method, parse them.
+  llvm::OwningPtr<AttributeList> MethodAttrs;
+  if (getLang().ObjC2 && Tok.is(tok::kw___attribute))
+    MethodAttrs.reset(ParseGNUAttributes());
+
+  if (Tok.is(tok::code_completion)) {
+    Actions.CodeCompleteObjCMethodDecl(CurScope, mType == tok::minus, 
+                                       ReturnType, IDecl);
+    ConsumeToken();
+  }
+
+  // Now parse the selector.
+  SourceLocation selLoc;
+  IdentifierInfo *SelIdent = ParseObjCSelectorPiece(selLoc);
+
+  // An unnamed colon is valid.
+  if (!SelIdent && Tok.isNot(tok::colon)) { // missing selector name.
+    Diag(Tok, diag::err_expected_selector_for_method)
+      << SourceRange(mLoc, Tok.getLocation());
+    // Skip until we get a ; or {}.
+    SkipUntil(tok::r_brace);
+    return DeclPtrTy();
+  }
+
+  llvm::SmallVector<DeclaratorChunk::ParamInfo, 8> CParamInfo;
+  if (Tok.isNot(tok::colon)) {
+    // If attributes exist after the method, parse them.
+    if (getLang().ObjC2 && Tok.is(tok::kw___attribute))
+      MethodAttrs.reset(addAttributeLists(MethodAttrs.take(),
+                                          ParseGNUAttributes()));
+
+    Selector Sel = PP.getSelectorTable().getNullarySelector(SelIdent);
+    DeclPtrTy Result
+         = Actions.ActOnMethodDeclaration(mLoc, Tok.getLocation(),
+                                          mType, IDecl, DSRet, ReturnType, Sel,
+                                          0, 
+                                          CParamInfo.data(), CParamInfo.size(),
+                                          MethodAttrs.get(),
+                                          MethodImplKind);
+    PD.complete(Result);
+    return Result;
+  }
+
+  llvm::SmallVector<IdentifierInfo *, 12> KeyIdents;
+  llvm::SmallVector<Action::ObjCArgInfo, 12> ArgInfos;
+
+  while (1) {
+    Action::ObjCArgInfo ArgInfo;
+
+    // Each iteration parses a single keyword argument.
+    if (Tok.isNot(tok::colon)) {
+      Diag(Tok, diag::err_expected_colon);
+      break;
+    }
+    ConsumeToken(); // Eat the ':'.
+
+    ArgInfo.Type = 0;
+    if (Tok.is(tok::l_paren)) // Parse the argument type if present.
+      ArgInfo.Type = ParseObjCTypeName(ArgInfo.DeclSpec);
+
+    // If attributes exist before the argument name, parse them.
+    ArgInfo.ArgAttrs = 0;
+    if (getLang().ObjC2 && Tok.is(tok::kw___attribute))
+      ArgInfo.ArgAttrs = ParseGNUAttributes();
+
+    if (Tok.isNot(tok::identifier)) {
+      Diag(Tok, diag::err_expected_ident); // missing argument name.
+      break;
+    }
+
+    ArgInfo.Name = Tok.getIdentifierInfo();
+    ArgInfo.NameLoc = Tok.getLocation();
+    ConsumeToken(); // Eat the identifier.
+
+    ArgInfos.push_back(ArgInfo);
+    KeyIdents.push_back(SelIdent);
+
+    // Check for another keyword selector.
+    SourceLocation Loc;
+    SelIdent = ParseObjCSelectorPiece(Loc);
+    if (!SelIdent && Tok.isNot(tok::colon))
+      break;
+    // We have a selector or a colon, continue parsing.
+  }
+
+  bool isVariadic = false;
+
+  // Parse the (optional) parameter list.
+  while (Tok.is(tok::comma)) {
+    ConsumeToken();
+    if (Tok.is(tok::ellipsis)) {
+      isVariadic = true;
+      ConsumeToken();
+      break;
+    }
+    DeclSpec DS;
+    ParseDeclarationSpecifiers(DS);
+    // Parse the declarator.
+    Declarator ParmDecl(DS, Declarator::PrototypeContext);
+    ParseDeclarator(ParmDecl);
+    IdentifierInfo *ParmII = ParmDecl.getIdentifier();
+    DeclPtrTy Param = Actions.ActOnParamDeclarator(CurScope, ParmDecl);
+    CParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
+                                                    ParmDecl.getIdentifierLoc(), 
+                                                    Param,
+                                                   0));
+
+  }
+
+  // FIXME: Add support for optional parmameter list...
+  // If attributes exist after the method, parse them.
+  if (getLang().ObjC2 && Tok.is(tok::kw___attribute))
+    MethodAttrs.reset(addAttributeLists(MethodAttrs.take(),
+                                        ParseGNUAttributes()));
+
+  if (KeyIdents.size() == 0)
+    return DeclPtrTy();
+  Selector Sel = PP.getSelectorTable().getSelector(KeyIdents.size(),
+                                                   &KeyIdents[0]);
+  DeclPtrTy Result
+       = Actions.ActOnMethodDeclaration(mLoc, Tok.getLocation(),
+                                        mType, IDecl, DSRet, ReturnType, Sel,
+                                        &ArgInfos[0], 
+                                        CParamInfo.data(), CParamInfo.size(),
+                                        MethodAttrs.get(),
+                                        MethodImplKind, isVariadic);
+  PD.complete(Result);
+  
+  // Delete referenced AttributeList objects.
+  for (llvm::SmallVectorImpl<Action::ObjCArgInfo>::iterator
+       I = ArgInfos.begin(), E = ArgInfos.end(); I != E; ++I)
+    delete I->ArgAttrs;
+  
+  return Result;
+}
+
+///   objc-protocol-refs:
+///     '<' identifier-list '>'
+///
+bool Parser::
+ParseObjCProtocolReferences(llvm::SmallVectorImpl<Action::DeclPtrTy> &Protocols,
+                            llvm::SmallVectorImpl<SourceLocation> &ProtocolLocs,
+                            bool WarnOnDeclarations,
+                            SourceLocation &LAngleLoc, SourceLocation &EndLoc) {
+  assert(Tok.is(tok::less) && "expected <");
+
+  LAngleLoc = ConsumeToken(); // the "<"
+
+  llvm::SmallVector<IdentifierLocPair, 8> ProtocolIdents;
+
+  while (1) {
+    if (Tok.is(tok::code_completion)) {
+      Actions.CodeCompleteObjCProtocolReferences(ProtocolIdents.data(), 
+                                                 ProtocolIdents.size());
+      ConsumeToken();
+    }
+
+    if (Tok.isNot(tok::identifier)) {
+      Diag(Tok, diag::err_expected_ident);
+      SkipUntil(tok::greater);
+      return true;
+    }
+    ProtocolIdents.push_back(std::make_pair(Tok.getIdentifierInfo(),
+                                       Tok.getLocation()));
+    ProtocolLocs.push_back(Tok.getLocation());
+    ConsumeToken();
+
+    if (Tok.isNot(tok::comma))
+      break;
+    ConsumeToken();
+  }
+
+  // Consume the '>'.
+  if (Tok.isNot(tok::greater)) {
+    Diag(Tok, diag::err_expected_greater);
+    return true;
+  }
+
+  EndLoc = ConsumeAnyToken();
+
+  // Convert the list of protocols identifiers into a list of protocol decls.
+  Actions.FindProtocolDeclaration(WarnOnDeclarations,
+                                  &ProtocolIdents[0], ProtocolIdents.size(),
+                                  Protocols);
+  return false;
+}
+
+///   objc-class-instance-variables:
+///     '{' objc-instance-variable-decl-list[opt] '}'
+///
+///   objc-instance-variable-decl-list:
+///     objc-visibility-spec
+///     objc-instance-variable-decl ';'
+///     ';'
+///     objc-instance-variable-decl-list objc-visibility-spec
+///     objc-instance-variable-decl-list objc-instance-variable-decl ';'
+///     objc-instance-variable-decl-list ';'
+///
+///   objc-visibility-spec:
+///     @private
+///     @protected
+///     @public
+///     @package [OBJC2]
+///
+///   objc-instance-variable-decl:
+///     struct-declaration
+///
+void Parser::ParseObjCClassInstanceVariables(DeclPtrTy interfaceDecl,
+                                             tok::ObjCKeywordKind visibility,
+                                             SourceLocation atLoc) {
+  assert(Tok.is(tok::l_brace) && "expected {");
+  llvm::SmallVector<DeclPtrTy, 32> AllIvarDecls;
+
+  ParseScope ClassScope(this, Scope::DeclScope|Scope::ClassScope);
+
+  SourceLocation LBraceLoc = ConsumeBrace(); // the "{"
+
+  // While we still have something to read, read the instance variables.
+  while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
+    // Each iteration of this loop reads one objc-instance-variable-decl.
+
+    // Check for extraneous top-level semicolon.
+    if (Tok.is(tok::semi)) {
+      Diag(Tok, diag::ext_extra_struct_semi)
+        << FixItHint::CreateRemoval(Tok.getLocation());
+      ConsumeToken();
+      continue;
+    }
+
+    // Set the default visibility to private.
+    if (Tok.is(tok::at)) { // parse objc-visibility-spec
+      ConsumeToken(); // eat the @ sign
+      
+      if (Tok.is(tok::code_completion)) {
+        Actions.CodeCompleteObjCAtVisibility(CurScope);
+        ConsumeToken();
+      }
+      
+      switch (Tok.getObjCKeywordID()) {
+      case tok::objc_private:
+      case tok::objc_public:
+      case tok::objc_protected:
+      case tok::objc_package:
+        visibility = Tok.getObjCKeywordID();
+        ConsumeToken();
+        continue;
+      default:
+        Diag(Tok, diag::err_objc_illegal_visibility_spec);
+        continue;
+      }
+    }
+
+    if (Tok.is(tok::code_completion)) {
+      Actions.CodeCompleteOrdinaryName(CurScope, 
+                                       Action::CCC_ObjCInstanceVariableList);
+      ConsumeToken();
+    }
+    
+    struct ObjCIvarCallback : FieldCallback {
+      Parser &P;
+      DeclPtrTy IDecl;
+      tok::ObjCKeywordKind visibility;
+      llvm::SmallVectorImpl<DeclPtrTy> &AllIvarDecls;
+
+      ObjCIvarCallback(Parser &P, DeclPtrTy IDecl, tok::ObjCKeywordKind V,
+                       llvm::SmallVectorImpl<DeclPtrTy> &AllIvarDecls) :
+        P(P), IDecl(IDecl), visibility(V), AllIvarDecls(AllIvarDecls) {
+      }
+
+      DeclPtrTy invoke(FieldDeclarator &FD) {
+        // Install the declarator into the interface decl.
+        DeclPtrTy Field
+          = P.Actions.ActOnIvar(P.CurScope,
+                                FD.D.getDeclSpec().getSourceRange().getBegin(),
+                                IDecl, FD.D, FD.BitfieldSize, visibility);
+        if (Field)
+          AllIvarDecls.push_back(Field);
+        return Field;
+      }
+    } Callback(*this, interfaceDecl, visibility, AllIvarDecls);
+
+    // Parse all the comma separated declarators.
+    DeclSpec DS;
+    ParseStructDeclaration(DS, Callback);
+
+    if (Tok.is(tok::semi)) {
+      ConsumeToken();
+    } else {
+      Diag(Tok, diag::err_expected_semi_decl_list);
+      // Skip to end of block or statement
+      SkipUntil(tok::r_brace, true, true);
+    }
+  }
+  SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc);
+  // Call ActOnFields() even if we don't have any decls. This is useful
+  // for code rewriting tools that need to be aware of the empty list.
+  Actions.ActOnFields(CurScope, atLoc, interfaceDecl,
+                      AllIvarDecls.data(), AllIvarDecls.size(),
+                      LBraceLoc, RBraceLoc, 0);
+  return;
+}
+
+///   objc-protocol-declaration:
+///     objc-protocol-definition
+///     objc-protocol-forward-reference
+///
+///   objc-protocol-definition:
+///     @protocol identifier
+///       objc-protocol-refs[opt]
+///       objc-interface-decl-list
+///     @end
+///
+///   objc-protocol-forward-reference:
+///     @protocol identifier-list ';'
+///
+///   "@protocol identifier ;" should be resolved as "@protocol
+///   identifier-list ;": objc-interface-decl-list may not start with a
+///   semicolon in the first alternative if objc-protocol-refs are omitted.
+Parser::DeclPtrTy Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc,
+                                                      AttributeList *attrList) {
+  assert(Tok.isObjCAtKeyword(tok::objc_protocol) &&
+         "ParseObjCAtProtocolDeclaration(): Expected @protocol");
+  ConsumeToken(); // the "protocol" identifier
+
+  if (Tok.is(tok::code_completion)) {
+    Actions.CodeCompleteObjCProtocolDecl(CurScope);
+    ConsumeToken();
+  }
+
+  if (Tok.isNot(tok::identifier)) {
+    Diag(Tok, diag::err_expected_ident); // missing protocol name.
+    return DeclPtrTy();
+  }
+  // Save the protocol name, then consume it.
+  IdentifierInfo *protocolName = Tok.getIdentifierInfo();
+  SourceLocation nameLoc = ConsumeToken();
+
+  if (Tok.is(tok::semi)) { // forward declaration of one protocol.
+    IdentifierLocPair ProtoInfo(protocolName, nameLoc);
+    ConsumeToken();
+    return Actions.ActOnForwardProtocolDeclaration(AtLoc, &ProtoInfo, 1,
+                                                   attrList);
+  }
+
+  if (Tok.is(tok::comma)) { // list of forward declarations.
+    llvm::SmallVector<IdentifierLocPair, 8> ProtocolRefs;
+    ProtocolRefs.push_back(std::make_pair(protocolName, nameLoc));
+
+    // Parse the list of forward declarations.
+    while (1) {
+      ConsumeToken(); // the ','
+      if (Tok.isNot(tok::identifier)) {
+        Diag(Tok, diag::err_expected_ident);
+        SkipUntil(tok::semi);
+        return DeclPtrTy();
+      }
+      ProtocolRefs.push_back(IdentifierLocPair(Tok.getIdentifierInfo(),
+                                               Tok.getLocation()));
+      ConsumeToken(); // the identifier
+
+      if (Tok.isNot(tok::comma))
+        break;
+    }
+    // Consume the ';'.
+    if (ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "@protocol"))
+      return DeclPtrTy();
+
+    return Actions.ActOnForwardProtocolDeclaration(AtLoc,
+                                                   &ProtocolRefs[0],
+                                                   ProtocolRefs.size(),
+                                                   attrList);
+  }
+
+  // Last, and definitely not least, parse a protocol declaration.
+  SourceLocation LAngleLoc, EndProtoLoc;
+
+  llvm::SmallVector<DeclPtrTy, 8> ProtocolRefs;
+  llvm::SmallVector<SourceLocation, 8> ProtocolLocs;
+  if (Tok.is(tok::less) &&
+      ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs, false,
+                                  LAngleLoc, EndProtoLoc))
+    return DeclPtrTy();
+
+  DeclPtrTy ProtoType =
+    Actions.ActOnStartProtocolInterface(AtLoc, protocolName, nameLoc,
+                                        ProtocolRefs.data(),
+                                        ProtocolRefs.size(),
+                                        ProtocolLocs.data(),
+                                        EndProtoLoc, attrList);
+  ParseObjCInterfaceDeclList(ProtoType, tok::objc_protocol);
+  return ProtoType;
+}
+
+///   objc-implementation:
+///     objc-class-implementation-prologue
+///     objc-category-implementation-prologue
+///
+///   objc-class-implementation-prologue:
+///     @implementation identifier objc-superclass[opt]
+///       objc-class-instance-variables[opt]
+///
+///   objc-category-implementation-prologue:
+///     @implementation identifier ( identifier )
+Parser::DeclPtrTy Parser::ParseObjCAtImplementationDeclaration(
+  SourceLocation atLoc) {
+  assert(Tok.isObjCAtKeyword(tok::objc_implementation) &&
+         "ParseObjCAtImplementationDeclaration(): Expected @implementation");
+  ConsumeToken(); // the "implementation" identifier
+
+  // Code completion after '@implementation'.
+  if (Tok.is(tok::code_completion)) {
+    Actions.CodeCompleteObjCImplementationDecl(CurScope);
+    ConsumeToken();
+  }
+
+  if (Tok.isNot(tok::identifier)) {
+    Diag(Tok, diag::err_expected_ident); // missing class or category name.
+    return DeclPtrTy();
+  }
+  // We have a class or category name - consume it.
+  IdentifierInfo *nameId = Tok.getIdentifierInfo();
+  SourceLocation nameLoc = ConsumeToken(); // consume class or category name
+
+  if (Tok.is(tok::l_paren)) {
+    // we have a category implementation.
+    SourceLocation lparenLoc = ConsumeParen();
+    SourceLocation categoryLoc, rparenLoc;
+    IdentifierInfo *categoryId = 0;
+
+    if (Tok.is(tok::code_completion)) {
+      Actions.CodeCompleteObjCImplementationCategory(CurScope, nameId, nameLoc);
+      ConsumeToken();
+    }
+    
+    if (Tok.is(tok::identifier)) {
+      categoryId = Tok.getIdentifierInfo();
+      categoryLoc = ConsumeToken();
+    } else {
+      Diag(Tok, diag::err_expected_ident); // missing category name.
+      return DeclPtrTy();
+    }
+    if (Tok.isNot(tok::r_paren)) {
+      Diag(Tok, diag::err_expected_rparen);
+      SkipUntil(tok::r_paren, false); // don't stop at ';'
+      return DeclPtrTy();
+    }
+    rparenLoc = ConsumeParen();
+    DeclPtrTy ImplCatType = Actions.ActOnStartCategoryImplementation(
+                                    atLoc, nameId, nameLoc, categoryId,
+                                    categoryLoc);
+    ObjCImpDecl = ImplCatType;
+    PendingObjCImpDecl.push_back(ObjCImpDecl);
+    return DeclPtrTy();
+  }
+  // We have a class implementation
+  SourceLocation superClassLoc;
+  IdentifierInfo *superClassId = 0;
+  if (Tok.is(tok::colon)) {
+    // We have a super class
+    ConsumeToken();
+    if (Tok.isNot(tok::identifier)) {
+      Diag(Tok, diag::err_expected_ident); // missing super class name.
+      return DeclPtrTy();
+    }
+    superClassId = Tok.getIdentifierInfo();
+    superClassLoc = ConsumeToken(); // Consume super class name
+  }
+  DeclPtrTy ImplClsType = Actions.ActOnStartClassImplementation(
+                                  atLoc, nameId, nameLoc,
+                                  superClassId, superClassLoc);
+
+  if (Tok.is(tok::l_brace)) // we have ivars
+    ParseObjCClassInstanceVariables(ImplClsType/*FIXME*/, 
+                                    tok::objc_private, atLoc);
+  ObjCImpDecl = ImplClsType;
+  PendingObjCImpDecl.push_back(ObjCImpDecl);
+  
+  return DeclPtrTy();
+}
+
+Parser::DeclPtrTy Parser::ParseObjCAtEndDeclaration(SourceRange atEnd) {
+  assert(Tok.isObjCAtKeyword(tok::objc_end) &&
+         "ParseObjCAtEndDeclaration(): Expected @end");
+  DeclPtrTy Result = ObjCImpDecl;
+  ConsumeToken(); // the "end" identifier
+  if (ObjCImpDecl) {
+    Actions.ActOnAtEnd(atEnd, ObjCImpDecl);
+    ObjCImpDecl = DeclPtrTy();
+    PendingObjCImpDecl.pop_back();
+  }
+  else {
+    // missing @implementation
+    Diag(atEnd.getBegin(), diag::warn_expected_implementation);
+  }
+  return Result;
+}
+
+Parser::DeclGroupPtrTy Parser::RetrievePendingObjCImpDecl() {
+  if (PendingObjCImpDecl.empty())
+    return Actions.ConvertDeclToDeclGroup(DeclPtrTy());
+  DeclPtrTy ImpDecl = PendingObjCImpDecl.pop_back_val();
+  Actions.ActOnAtEnd(SourceRange(), ImpDecl);
+  return Actions.ConvertDeclToDeclGroup(ImpDecl);
+}
+
+///   compatibility-alias-decl:
+///     @compatibility_alias alias-name  class-name ';'
+///
+Parser::DeclPtrTy Parser::ParseObjCAtAliasDeclaration(SourceLocation atLoc) {
+  assert(Tok.isObjCAtKeyword(tok::objc_compatibility_alias) &&
+         "ParseObjCAtAliasDeclaration(): Expected @compatibility_alias");
+  ConsumeToken(); // consume compatibility_alias
+  if (Tok.isNot(tok::identifier)) {
+    Diag(Tok, diag::err_expected_ident);
+    return DeclPtrTy();
+  }
+  IdentifierInfo *aliasId = Tok.getIdentifierInfo();
+  SourceLocation aliasLoc = ConsumeToken(); // consume alias-name
+  if (Tok.isNot(tok::identifier)) {
+    Diag(Tok, diag::err_expected_ident);
+    return DeclPtrTy();
+  }
+  IdentifierInfo *classId = Tok.getIdentifierInfo();
+  SourceLocation classLoc = ConsumeToken(); // consume class-name;
+  if (Tok.isNot(tok::semi)) {
+    Diag(Tok, diag::err_expected_semi_after) << "@compatibility_alias";
+    return DeclPtrTy();
+  }
+  return Actions.ActOnCompatiblityAlias(atLoc, aliasId, aliasLoc,
+                                        classId, classLoc);
+}
+
+///   property-synthesis:
+///     @synthesize property-ivar-list ';'
+///
+///   property-ivar-list:
+///     property-ivar
+///     property-ivar-list ',' property-ivar
+///
+///   property-ivar:
+///     identifier
+///     identifier '=' identifier
+///
+Parser::DeclPtrTy Parser::ParseObjCPropertySynthesize(SourceLocation atLoc) {
+  assert(Tok.isObjCAtKeyword(tok::objc_synthesize) &&
+         "ParseObjCPropertyDynamic(): Expected '@synthesize'");
+  SourceLocation loc = ConsumeToken(); // consume synthesize
+
+  while (true) {
+    if (Tok.is(tok::code_completion)) {
+      Actions.CodeCompleteObjCPropertyDefinition(CurScope, ObjCImpDecl);
+      ConsumeToken();
+    }
+    
+    if (Tok.isNot(tok::identifier)) {
+      Diag(Tok, diag::err_synthesized_property_name);
+      SkipUntil(tok::semi);
+      return DeclPtrTy();
+    }
+    
+    IdentifierInfo *propertyIvar = 0;
+    IdentifierInfo *propertyId = Tok.getIdentifierInfo();
+    SourceLocation propertyLoc = ConsumeToken(); // consume property name
+    if (Tok.is(tok::equal)) {
+      // property '=' ivar-name
+      ConsumeToken(); // consume '='
+      
+      if (Tok.is(tok::code_completion)) {
+        Actions.CodeCompleteObjCPropertySynthesizeIvar(CurScope, propertyId,
+                                                       ObjCImpDecl);
+        ConsumeToken();
+      }
+      
+      if (Tok.isNot(tok::identifier)) {
+        Diag(Tok, diag::err_expected_ident);
+        break;
+      }
+      propertyIvar = Tok.getIdentifierInfo();
+      ConsumeToken(); // consume ivar-name
+    }
+    Actions.ActOnPropertyImplDecl(atLoc, propertyLoc, true, ObjCImpDecl,
+                                  propertyId, propertyIvar);
+    if (Tok.isNot(tok::comma))
+      break;
+    ConsumeToken(); // consume ','
+  }
+  if (Tok.isNot(tok::semi)) {
+    Diag(Tok, diag::err_expected_semi_after) << "@synthesize";
+    SkipUntil(tok::semi);
+  }
+  else
+    ConsumeToken(); // consume ';'
+  return DeclPtrTy();
+}
+
+///   property-dynamic:
+///     @dynamic  property-list
+///
+///   property-list:
+///     identifier
+///     property-list ',' identifier
+///
+Parser::DeclPtrTy Parser::ParseObjCPropertyDynamic(SourceLocation atLoc) {
+  assert(Tok.isObjCAtKeyword(tok::objc_dynamic) &&
+         "ParseObjCPropertyDynamic(): Expected '@dynamic'");
+  SourceLocation loc = ConsumeToken(); // consume dynamic
+  while (true) {
+    if (Tok.is(tok::code_completion)) {
+      Actions.CodeCompleteObjCPropertyDefinition(CurScope, ObjCImpDecl);
+      ConsumeToken();
+    }
+    
+    if (Tok.isNot(tok::identifier)) {
+      Diag(Tok, diag::err_expected_ident);
+      SkipUntil(tok::semi);
+      return DeclPtrTy();
+    }
+    
+    IdentifierInfo *propertyId = Tok.getIdentifierInfo();
+    SourceLocation propertyLoc = ConsumeToken(); // consume property name
+    Actions.ActOnPropertyImplDecl(atLoc, propertyLoc, false, ObjCImpDecl,
+                                  propertyId, 0);
+
+    if (Tok.isNot(tok::comma))
+      break;
+    ConsumeToken(); // consume ','
+  }
+  if (Tok.isNot(tok::semi)) {
+    Diag(Tok, diag::err_expected_semi_after) << "@dynamic";
+    SkipUntil(tok::semi);
+  }
+  else
+    ConsumeToken(); // consume ';'
+  return DeclPtrTy();
+}
+
+///  objc-throw-statement:
+///    throw expression[opt];
+///
+Parser::OwningStmtResult Parser::ParseObjCThrowStmt(SourceLocation atLoc) {
+  OwningExprResult Res(Actions);
+  ConsumeToken(); // consume throw
+  if (Tok.isNot(tok::semi)) {
+    Res = ParseExpression();
+    if (Res.isInvalid()) {
+      SkipUntil(tok::semi);
+      return StmtError();
+    }
+  }
+  // consume ';'
+  ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "@throw");
+  return Actions.ActOnObjCAtThrowStmt(atLoc, move(Res), CurScope);
+}
+
+/// objc-synchronized-statement:
+///   @synchronized '(' expression ')' compound-statement
+///
+Parser::OwningStmtResult
+Parser::ParseObjCSynchronizedStmt(SourceLocation atLoc) {
+  ConsumeToken(); // consume synchronized
+  if (Tok.isNot(tok::l_paren)) {
+    Diag(Tok, diag::err_expected_lparen_after) << "@synchronized";
+    return StmtError();
+  }
+  ConsumeParen();  // '('
+  OwningExprResult Res(ParseExpression());
+  if (Res.isInvalid()) {
+    SkipUntil(tok::semi);
+    return StmtError();
+  }
+  if (Tok.isNot(tok::r_paren)) {
+    Diag(Tok, diag::err_expected_lbrace);
+    return StmtError();
+  }
+  ConsumeParen();  // ')'
+  if (Tok.isNot(tok::l_brace)) {
+    Diag(Tok, diag::err_expected_lbrace);
+    return StmtError();
+  }
+  // Enter a scope to hold everything within the compound stmt.  Compound
+  // statements can always hold declarations.
+  ParseScope BodyScope(this, Scope::DeclScope);
+
+  OwningStmtResult SynchBody(ParseCompoundStatementBody());
+
+  BodyScope.Exit();
+  if (SynchBody.isInvalid())
+    SynchBody = Actions.ActOnNullStmt(Tok.getLocation());
+  return Actions.ActOnObjCAtSynchronizedStmt(atLoc, move(Res), move(SynchBody));
+}
+
+///  objc-try-catch-statement:
+///    @try compound-statement objc-catch-list[opt]
+///    @try compound-statement objc-catch-list[opt] @finally compound-statement
+///
+///  objc-catch-list:
+///    @catch ( parameter-declaration ) compound-statement
+///    objc-catch-list @catch ( catch-parameter-declaration ) compound-statement
+///  catch-parameter-declaration:
+///     parameter-declaration
+///     '...' [OBJC2]
+///
+Parser::OwningStmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) {
+  bool catch_or_finally_seen = false;
+
+  ConsumeToken(); // consume try
+  if (Tok.isNot(tok::l_brace)) {
+    Diag(Tok, diag::err_expected_lbrace);
+    return StmtError();
+  }
+  StmtVector CatchStmts(Actions);
+  OwningStmtResult FinallyStmt(Actions);
+  ParseScope TryScope(this, Scope::DeclScope);
+  OwningStmtResult TryBody(ParseCompoundStatementBody());
+  TryScope.Exit();
+  if (TryBody.isInvalid())
+    TryBody = Actions.ActOnNullStmt(Tok.getLocation());
+
+  while (Tok.is(tok::at)) {
+    // At this point, we need to lookahead to determine if this @ is the start
+    // of an @catch or @finally.  We don't want to consume the @ token if this
+    // is an @try or @encode or something else.
+    Token AfterAt = GetLookAheadToken(1);
+    if (!AfterAt.isObjCAtKeyword(tok::objc_catch) &&
+        !AfterAt.isObjCAtKeyword(tok::objc_finally))
+      break;
+
+    SourceLocation AtCatchFinallyLoc = ConsumeToken();
+    if (Tok.isObjCAtKeyword(tok::objc_catch)) {
+      DeclPtrTy FirstPart;
+      ConsumeToken(); // consume catch
+      if (Tok.is(tok::l_paren)) {
+        ConsumeParen();
+        ParseScope CatchScope(this, Scope::DeclScope|Scope::AtCatchScope);
+        if (Tok.isNot(tok::ellipsis)) {
+          DeclSpec DS;
+          ParseDeclarationSpecifiers(DS);
+          // For some odd reason, the name of the exception variable is
+          // optional. As a result, we need to use "PrototypeContext", because
+          // we must accept either 'declarator' or 'abstract-declarator' here.
+          Declarator ParmDecl(DS, Declarator::PrototypeContext);
+          ParseDeclarator(ParmDecl);
+
+          // Inform the actions module about the declarator, so it
+          // gets added to the current scope.
+          FirstPart = Actions.ActOnObjCExceptionDecl(CurScope, ParmDecl);
+        } else
+          ConsumeToken(); // consume '...'
+
+        SourceLocation RParenLoc;
+
+        if (Tok.is(tok::r_paren))
+          RParenLoc = ConsumeParen();
+        else // Skip over garbage, until we get to ')'.  Eat the ')'.
+          SkipUntil(tok::r_paren, true, false);
+
+        OwningStmtResult CatchBody(Actions, true);
+        if (Tok.is(tok::l_brace))
+          CatchBody = ParseCompoundStatementBody();
+        else
+          Diag(Tok, diag::err_expected_lbrace);
+        if (CatchBody.isInvalid())
+          CatchBody = Actions.ActOnNullStmt(Tok.getLocation());
+        
+        OwningStmtResult Catch = Actions.ActOnObjCAtCatchStmt(AtCatchFinallyLoc,
+                                                              RParenLoc, 
+                                                              FirstPart, 
+                                                              move(CatchBody));
+        if (!Catch.isInvalid())
+          CatchStmts.push_back(Catch.release());
+        
+      } else {
+        Diag(AtCatchFinallyLoc, diag::err_expected_lparen_after)
+          << "@catch clause";
+        return StmtError();
+      }
+      catch_or_finally_seen = true;
+    } else {
+      assert(Tok.isObjCAtKeyword(tok::objc_finally) && "Lookahead confused?");
+      ConsumeToken(); // consume finally
+      ParseScope FinallyScope(this, Scope::DeclScope);
+
+      OwningStmtResult FinallyBody(Actions, true);
+      if (Tok.is(tok::l_brace))
+        FinallyBody = ParseCompoundStatementBody();
+      else
+        Diag(Tok, diag::err_expected_lbrace);
+      if (FinallyBody.isInvalid())
+        FinallyBody = Actions.ActOnNullStmt(Tok.getLocation());
+      FinallyStmt = Actions.ActOnObjCAtFinallyStmt(AtCatchFinallyLoc,
+                                                   move(FinallyBody));
+      catch_or_finally_seen = true;
+      break;
+    }
+  }
+  if (!catch_or_finally_seen) {
+    Diag(atLoc, diag::err_missing_catch_finally);
+    return StmtError();
+  }
+  
+  return Actions.ActOnObjCAtTryStmt(atLoc, move(TryBody), 
+                                    move_arg(CatchStmts),
+                                    move(FinallyStmt));
+}
+
+///   objc-method-def: objc-method-proto ';'[opt] '{' body '}'
+///
+Parser::DeclPtrTy Parser::ParseObjCMethodDefinition() {
+  DeclPtrTy MDecl = ParseObjCMethodPrototype(ObjCImpDecl);
+
+  PrettyStackTraceActionsDecl CrashInfo(MDecl, Tok.getLocation(), Actions,
+                                        PP.getSourceManager(),
+                                        "parsing Objective-C method");
+
+  // parse optional ';'
+  if (Tok.is(tok::semi)) {
+    if (ObjCImpDecl) {
+      Diag(Tok, diag::warn_semicolon_before_method_body)
+        << FixItHint::CreateRemoval(Tok.getLocation());
+    }
+    ConsumeToken();
+  }
+
+  // We should have an opening brace now.
+  if (Tok.isNot(tok::l_brace)) {
+    Diag(Tok, diag::err_expected_method_body);
+
+    // Skip over garbage, until we get to '{'.  Don't eat the '{'.
+    SkipUntil(tok::l_brace, true, true);
+
+    // If we didn't find the '{', bail out.
+    if (Tok.isNot(tok::l_brace))
+      return DeclPtrTy();
+  }
+  SourceLocation BraceLoc = Tok.getLocation();
+
+  // Enter a scope for the method body.
+  ParseScope BodyScope(this,
+                       Scope::ObjCMethodScope|Scope::FnScope|Scope::DeclScope);
+
+  // Tell the actions module that we have entered a method definition with the
+  // specified Declarator for the method.
+  Actions.ActOnStartOfObjCMethodDef(CurScope, MDecl);
+
+  OwningStmtResult FnBody(ParseCompoundStatementBody());
+
+  // If the function body could not be parsed, make a bogus compoundstmt.
+  if (FnBody.isInvalid())
+    FnBody = Actions.ActOnCompoundStmt(BraceLoc, BraceLoc,
+                                       MultiStmtArg(Actions), false);
+
+  // TODO: Pass argument information.
+  Actions.ActOnFinishFunctionBody(MDecl, move(FnBody));
+
+  // Leave the function body scope.
+  BodyScope.Exit();
+
+  return MDecl;
+}
+
+Parser::OwningStmtResult Parser::ParseObjCAtStatement(SourceLocation AtLoc) {
+  if (Tok.is(tok::code_completion)) {
+    Actions.CodeCompleteObjCAtStatement(CurScope);
+    ConsumeToken();
+    return StmtError();
+  }
+  
+  if (Tok.isObjCAtKeyword(tok::objc_try))
+    return ParseObjCTryStmt(AtLoc);
+  
+  if (Tok.isObjCAtKeyword(tok::objc_throw))
+    return ParseObjCThrowStmt(AtLoc);
+  
+  if (Tok.isObjCAtKeyword(tok::objc_synchronized))
+    return ParseObjCSynchronizedStmt(AtLoc);
+  
+  OwningExprResult Res(ParseExpressionWithLeadingAt(AtLoc));
+  if (Res.isInvalid()) {
+    // If the expression is invalid, skip ahead to the next semicolon. Not
+    // doing this opens us up to the possibility of infinite loops if
+    // ParseExpression does not consume any tokens.
+    SkipUntil(tok::semi);
+    return StmtError();
+  }
+  
+  // Otherwise, eat the semicolon.
+  ExpectAndConsume(tok::semi, diag::err_expected_semi_after_expr);
+  return Actions.ActOnExprStmt(Actions.MakeFullExpr(Res));
+}
+
+Parser::OwningExprResult Parser::ParseObjCAtExpression(SourceLocation AtLoc) {
+  switch (Tok.getKind()) {
+  case tok::code_completion:
+    Actions.CodeCompleteObjCAtExpression(CurScope);
+    ConsumeToken();
+    return ExprError();
+
+  case tok::string_literal:    // primary-expression: string-literal
+  case tok::wide_string_literal:
+    return ParsePostfixExpressionSuffix(ParseObjCStringLiteral(AtLoc));
+  default:
+    if (Tok.getIdentifierInfo() == 0)
+      return ExprError(Diag(AtLoc, diag::err_unexpected_at));
+
+    switch (Tok.getIdentifierInfo()->getObjCKeywordID()) {
+    case tok::objc_encode:
+      return ParsePostfixExpressionSuffix(ParseObjCEncodeExpression(AtLoc));
+    case tok::objc_protocol:
+      return ParsePostfixExpressionSuffix(ParseObjCProtocolExpression(AtLoc));
+    case tok::objc_selector:
+      return ParsePostfixExpressionSuffix(ParseObjCSelectorExpression(AtLoc));
+    default:
+      return ExprError(Diag(AtLoc, diag::err_unexpected_at));
+    }
+  }
+}
+
+/// \brirg Parse the receiver of an Objective-C++ message send.
+///
+/// This routine parses the receiver of a message send in
+/// Objective-C++ either as a type or as an expression. Note that this
+/// routine must not be called to parse a send to 'super', since it
+/// has no way to return such a result.
+/// 
+/// \param IsExpr Whether the receiver was parsed as an expression.
+///
+/// \param TypeOrExpr If the receiver was parsed as an expression (\c
+/// IsExpr is true), the parsed expression. If the receiver was parsed
+/// as a type (\c IsExpr is false), the parsed type.
+///
+/// \returns True if an error occurred during parsing or semantic
+/// analysis, in which case the arguments do not have valid
+/// values. Otherwise, returns false for a successful parse.
+///
+///   objc-receiver: [C++]
+///     'super' [not parsed here]
+///     expression
+///     simple-type-specifier
+///     typename-specifier
+
+bool Parser::ParseObjCXXMessageReceiver(bool &IsExpr, void *&TypeOrExpr) {
+  if (Tok.is(tok::identifier) || Tok.is(tok::coloncolon) || 
+      Tok.is(tok::kw_typename) || Tok.is(tok::annot_cxxscope))
+    TryAnnotateTypeOrScopeToken();
+
+  if (!isCXXSimpleTypeSpecifier()) {
+    //   objc-receiver:
+    //     expression
+    OwningExprResult Receiver = ParseExpression();
+    if (Receiver.isInvalid())
+      return true;
+
+    IsExpr = true;
+    TypeOrExpr = Receiver.take();
+    return false;
+  }
+
+  // objc-receiver:
+  //   typename-specifier
+  //   simple-type-specifier
+  //   expression (that starts with one of the above)
+  DeclSpec DS;
+  ParseCXXSimpleTypeSpecifier(DS);
+  
+  if (Tok.is(tok::l_paren)) {
+    // If we see an opening parentheses at this point, we are
+    // actually parsing an expression that starts with a
+    // function-style cast, e.g.,
+    //
+    //   postfix-expression:
+    //     simple-type-specifier ( expression-list [opt] )
+    //     typename-specifier ( expression-list [opt] )
+    //
+    // Parse the remainder of this case, then the (optional)
+    // postfix-expression suffix, followed by the (optional)
+    // right-hand side of the binary expression. We have an
+    // instance method.
+    OwningExprResult Receiver = ParseCXXTypeConstructExpression(DS);
+    if (!Receiver.isInvalid())
+      Receiver = ParsePostfixExpressionSuffix(move(Receiver));
+    if (!Receiver.isInvalid())
+      Receiver = ParseRHSOfBinaryExpression(move(Receiver), prec::Comma);
+    if (Receiver.isInvalid())
+      return true;
+
+    IsExpr = true;
+    TypeOrExpr = Receiver.take();
+    return false;
+  }
+  
+  // We have a class message. Turn the simple-type-specifier or
+  // typename-specifier we parsed into a type and parse the
+  // remainder of the class message.
+  Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
+  TypeResult Type = Actions.ActOnTypeName(CurScope, DeclaratorInfo);
+  if (Type.isInvalid())
+    return true;
+
+  IsExpr = false;
+  TypeOrExpr = Type.get();
+  return false;
+}
+
+///   objc-message-expr:
+///     '[' objc-receiver objc-message-args ']'
+///
+///   objc-receiver: [C]
+///     'super'
+///     expression
+///     class-name
+///     type-name
+///
+Parser::OwningExprResult Parser::ParseObjCMessageExpression() {
+  assert(Tok.is(tok::l_square) && "'[' expected");
+  SourceLocation LBracLoc = ConsumeBracket(); // consume '['
+
+  if (getLang().CPlusPlus) {
+    // We completely separate the C and C++ cases because C++ requires
+    // more complicated (read: slower) parsing. 
+    
+    // Handle send to super.  
+    // FIXME: This doesn't benefit from the same typo-correction we
+    // get in Objective-C.
+    if (Tok.is(tok::identifier) && Tok.getIdentifierInfo() == Ident_super &&
+        NextToken().isNot(tok::period) && CurScope->isInObjcMethodScope())
+      return ParseObjCMessageExpressionBody(LBracLoc, ConsumeToken(), 0, 
+                                            ExprArg(Actions));
+
+    // Parse the receiver, which is either a type or an expression.
+    bool IsExpr;
+    void *TypeOrExpr;
+    if (ParseObjCXXMessageReceiver(IsExpr, TypeOrExpr)) {
+      SkipUntil(tok::r_square);
+      return ExprError();
+    }
+
+    if (IsExpr)
+      return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(), 0,
+                                         OwningExprResult(Actions, TypeOrExpr));
+
+    return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(), 
+                                          TypeOrExpr, ExprArg(Actions));
+  } else if (Tok.is(tok::identifier)) {
+    IdentifierInfo *Name = Tok.getIdentifierInfo();
+    SourceLocation NameLoc = Tok.getLocation();
+    TypeTy *ReceiverType;
+    switch (Actions.getObjCMessageKind(CurScope, Name, NameLoc,
+                                       Name == Ident_super,
+                                       NextToken().is(tok::period),
+                                       ReceiverType)) {
+    case Action::ObjCSuperMessage:
+      return ParseObjCMessageExpressionBody(LBracLoc, ConsumeToken(), 0,
+                                            ExprArg(Actions));
+
+    case Action::ObjCClassMessage:
+      if (!ReceiverType) {
+        SkipUntil(tok::r_square);
+        return ExprError();
+      }
+
+      ConsumeToken(); // the type name
+
+      return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(), 
+                                            ReceiverType,
+                                            ExprArg(Actions));
+        
+    case Action::ObjCInstanceMessage:
+      // Fall through to parse an expression.
+      break;
+    }
+  }
+  
+  // Otherwise, an arbitrary expression can be the receiver of a send.
+  OwningExprResult Res(ParseExpression());
+  if (Res.isInvalid()) {
+    SkipUntil(tok::r_square);
+    return move(Res);
+  }
+
+  return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(), 0, 
+                                        move(Res));
+}
+
+/// \brief Parse the remainder of an Objective-C message following the
+/// '[' objc-receiver.
+///
+/// This routine handles sends to super, class messages (sent to a
+/// class name), and instance messages (sent to an object), and the
+/// target is represented by \p SuperLoc, \p ReceiverType, or \p
+/// ReceiverExpr, respectively. Only one of these parameters may have
+/// a valid value.
+///
+/// \param LBracLoc The location of the opening '['.
+///
+/// \param SuperLoc If this is a send to 'super', the location of the
+/// 'super' keyword that indicates a send to the superclass.
+///
+/// \param ReceiverType If this is a class message, the type of the
+/// class we are sending a message to.
+///
+/// \param ReceiverExpr If this is an instance message, the expression
+/// used to compute the receiver object.
+///
+///   objc-message-args:
+///     objc-selector
+///     objc-keywordarg-list
+///
+///   objc-keywordarg-list:
+///     objc-keywordarg
+///     objc-keywordarg-list objc-keywordarg
+///
+///   objc-keywordarg:
+///     selector-name[opt] ':' objc-keywordexpr
+///
+///   objc-keywordexpr:
+///     nonempty-expr-list
+///
+///   nonempty-expr-list:
+///     assignment-expression
+///     nonempty-expr-list , assignment-expression
+///
+Parser::OwningExprResult
+Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc,
+                                       SourceLocation SuperLoc,
+                                       TypeTy *ReceiverType,
+                                       ExprArg ReceiverExpr) {
+  if (Tok.is(tok::code_completion)) {
+    if (SuperLoc.isValid())
+      Actions.CodeCompleteObjCSuperMessage(CurScope, SuperLoc, 0, 0);
+    else if (ReceiverType)
+      Actions.CodeCompleteObjCClassMessage(CurScope, ReceiverType, 0, 0);
+    else
+      Actions.CodeCompleteObjCInstanceMessage(CurScope, ReceiverExpr.get(), 
+                                              0, 0);
+    ConsumeToken();
+  }
+  
+  // Parse objc-selector
+  SourceLocation Loc;
+  IdentifierInfo *selIdent = ParseObjCSelectorPiece(Loc);
+
+  SourceLocation SelectorLoc = Loc;
+
+  llvm::SmallVector<IdentifierInfo *, 12> KeyIdents;
+  ExprVector KeyExprs(Actions);
+
+  if (Tok.is(tok::colon)) {
+    while (1) {
+      // Each iteration parses a single keyword argument.
+      KeyIdents.push_back(selIdent);
+
+      if (Tok.isNot(tok::colon)) {
+        Diag(Tok, diag::err_expected_colon);
+        // We must manually skip to a ']', otherwise the expression skipper will
+        // stop at the ']' when it skips to the ';'.  We want it to skip beyond
+        // the enclosing expression.
+        SkipUntil(tok::r_square);
+        return ExprError();
+      }
+
+      ConsumeToken(); // Eat the ':'.
+      ///  Parse the expression after ':'
+      OwningExprResult Res(ParseAssignmentExpression());
+      if (Res.isInvalid()) {
+        // We must manually skip to a ']', otherwise the expression skipper will
+        // stop at the ']' when it skips to the ';'.  We want it to skip beyond
+        // the enclosing expression.
+        SkipUntil(tok::r_square);
+        return move(Res);
+      }
+
+      // We have a valid expression.
+      KeyExprs.push_back(Res.release());
+
+      // Code completion after each argument.
+      if (Tok.is(tok::code_completion)) {
+        if (SuperLoc.isValid())
+          Actions.CodeCompleteObjCSuperMessage(CurScope, SuperLoc, 
+                                               KeyIdents.data(), 
+                                               KeyIdents.size());
+        else if (ReceiverType)
+          Actions.CodeCompleteObjCClassMessage(CurScope, ReceiverType,
+                                               KeyIdents.data(), 
+                                               KeyIdents.size());
+        else
+          Actions.CodeCompleteObjCInstanceMessage(CurScope, ReceiverExpr.get(),
+                                                  KeyIdents.data(), 
+                                                  KeyIdents.size());
+        ConsumeToken();
+      }
+            
+      // Check for another keyword selector.
+      selIdent = ParseObjCSelectorPiece(Loc);
+      if (!selIdent && Tok.isNot(tok::colon))
+        break;
+      // We have a selector or a colon, continue parsing.
+    }
+    // Parse the, optional, argument list, comma separated.
+    while (Tok.is(tok::comma)) {
+      ConsumeToken(); // Eat the ','.
+      ///  Parse the expression after ','
+      OwningExprResult Res(ParseAssignmentExpression());
+      if (Res.isInvalid()) {
+        // We must manually skip to a ']', otherwise the expression skipper will
+        // stop at the ']' when it skips to the ';'.  We want it to skip beyond
+        // the enclosing expression.
+        SkipUntil(tok::r_square);
+        return move(Res);
+      }
+
+      // We have a valid expression.
+      KeyExprs.push_back(Res.release());
+    }
+  } else if (!selIdent) {
+    Diag(Tok, diag::err_expected_ident); // missing selector name.
+
+    // We must manually skip to a ']', otherwise the expression skipper will
+    // stop at the ']' when it skips to the ';'.  We want it to skip beyond
+    // the enclosing expression.
+    SkipUntil(tok::r_square);
+    return ExprError();
+  }
+    
+  if (Tok.isNot(tok::r_square)) {
+    if (Tok.is(tok::identifier))
+      Diag(Tok, diag::err_expected_colon);
+    else
+      Diag(Tok, diag::err_expected_rsquare);
+    // We must manually skip to a ']', otherwise the expression skipper will
+    // stop at the ']' when it skips to the ';'.  We want it to skip beyond
+    // the enclosing expression.
+    SkipUntil(tok::r_square);
+    return ExprError();
+  }
+
+  SourceLocation RBracLoc = ConsumeBracket(); // consume ']'
+
+  unsigned nKeys = KeyIdents.size();
+  if (nKeys == 0)
+    KeyIdents.push_back(selIdent);
+  Selector Sel = PP.getSelectorTable().getSelector(nKeys, &KeyIdents[0]);
+
+  if (SuperLoc.isValid())
+    return Actions.ActOnSuperMessage(CurScope, SuperLoc, Sel,
+                                     LBracLoc, SelectorLoc, RBracLoc,
+                                     Action::MultiExprArg(Actions, 
+                                                          KeyExprs.take(),
+                                                          KeyExprs.size()));
+  else if (ReceiverType)
+    return Actions.ActOnClassMessage(CurScope, ReceiverType, Sel,
+                                     LBracLoc, SelectorLoc, RBracLoc,
+                                     Action::MultiExprArg(Actions, 
+                                                          KeyExprs.take(), 
+                                                          KeyExprs.size()));
+  return Actions.ActOnInstanceMessage(CurScope, move(ReceiverExpr), Sel,
+                                      LBracLoc, SelectorLoc, RBracLoc,
+                                      Action::MultiExprArg(Actions, 
+                                                           KeyExprs.take(), 
+                                                           KeyExprs.size()));
+}
+
+Parser::OwningExprResult Parser::ParseObjCStringLiteral(SourceLocation AtLoc) {
+  OwningExprResult Res(ParseStringLiteralExpression());
+  if (Res.isInvalid()) return move(Res);
+
+  // @"foo" @"bar" is a valid concatenated string.  Eat any subsequent string
+  // expressions.  At this point, we know that the only valid thing that starts
+  // with '@' is an @"".
+  llvm::SmallVector<SourceLocation, 4> AtLocs;
+  ExprVector AtStrings(Actions);
+  AtLocs.push_back(AtLoc);
+  AtStrings.push_back(Res.release());
+
+  while (Tok.is(tok::at)) {
+    AtLocs.push_back(ConsumeToken()); // eat the @.
+
+    // Invalid unless there is a string literal.
+    if (!isTokenStringLiteral())
+      return ExprError(Diag(Tok, diag::err_objc_concat_string));
+
+    OwningExprResult Lit(ParseStringLiteralExpression());
+    if (Lit.isInvalid())
+      return move(Lit);
+
+    AtStrings.push_back(Lit.release());
+  }
+
+  return Owned(Actions.ParseObjCStringLiteral(&AtLocs[0], AtStrings.take(),
+                                              AtStrings.size()));
+}
+
+///    objc-encode-expression:
+///      @encode ( type-name )
+Parser::OwningExprResult
+Parser::ParseObjCEncodeExpression(SourceLocation AtLoc) {
+  assert(Tok.isObjCAtKeyword(tok::objc_encode) && "Not an @encode expression!");
+
+  SourceLocation EncLoc = ConsumeToken();
+
+  if (Tok.isNot(tok::l_paren))
+    return ExprError(Diag(Tok, diag::err_expected_lparen_after) << "@encode");
+
+  SourceLocation LParenLoc = ConsumeParen();
+
+  TypeResult Ty = ParseTypeName();
+
+  SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
+
+  if (Ty.isInvalid())
+    return ExprError();
+
+  return Owned(Actions.ParseObjCEncodeExpression(AtLoc, EncLoc, LParenLoc,
+                                                 Ty.get(), RParenLoc));
+}
+
+///     objc-protocol-expression
+///       @protocol ( protocol-name )
+Parser::OwningExprResult
+Parser::ParseObjCProtocolExpression(SourceLocation AtLoc) {
+  SourceLocation ProtoLoc = ConsumeToken();
+
+  if (Tok.isNot(tok::l_paren))
+    return ExprError(Diag(Tok, diag::err_expected_lparen_after) << "@protocol");
+
+  SourceLocation LParenLoc = ConsumeParen();
+
+  if (Tok.isNot(tok::identifier))
+    return ExprError(Diag(Tok, diag::err_expected_ident));
+
+  IdentifierInfo *protocolId = Tok.getIdentifierInfo();
+  ConsumeToken();
+
+  SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
+
+  return Owned(Actions.ParseObjCProtocolExpression(protocolId, AtLoc, ProtoLoc,
+                                                   LParenLoc, RParenLoc));
+}
+
+///     objc-selector-expression
+///       @selector '(' objc-keyword-selector ')'
+Parser::OwningExprResult
+Parser::ParseObjCSelectorExpression(SourceLocation AtLoc) {
+  SourceLocation SelectorLoc = ConsumeToken();
+
+  if (Tok.isNot(tok::l_paren))
+    return ExprError(Diag(Tok, diag::err_expected_lparen_after) << "@selector");
+
+  llvm::SmallVector<IdentifierInfo *, 12> KeyIdents;
+  SourceLocation LParenLoc = ConsumeParen();
+  SourceLocation sLoc;
+  IdentifierInfo *SelIdent = ParseObjCSelectorPiece(sLoc);
+  if (!SelIdent && Tok.isNot(tok::colon)) // missing selector name.
+    return ExprError(Diag(Tok, diag::err_expected_ident));
+
+  KeyIdents.push_back(SelIdent);
+  unsigned nColons = 0;
+  if (Tok.isNot(tok::r_paren)) {
+    while (1) {
+      if (Tok.isNot(tok::colon))
+        return ExprError(Diag(Tok, diag::err_expected_colon));
+
+      nColons++;
+      ConsumeToken(); // Eat the ':'.
+      if (Tok.is(tok::r_paren))
+        break;
+      // Check for another keyword selector.
+      SourceLocation Loc;
+      SelIdent = ParseObjCSelectorPiece(Loc);
+      KeyIdents.push_back(SelIdent);
+      if (!SelIdent && Tok.isNot(tok::colon))
+        break;
+    }
+  }
+  SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
+  Selector Sel = PP.getSelectorTable().getSelector(nColons, &KeyIdents[0]);
+  return Owned(Actions.ParseObjCSelectorExpression(Sel, AtLoc, SelectorLoc,
+                                                   LParenLoc, RParenLoc));
+ }
diff --git a/lib/Parse/ParsePragma.cpp b/lib/Parse/ParsePragma.cpp
new file mode 100644
index 0000000..812d8e2
--- /dev/null
+++ b/lib/Parse/ParsePragma.cpp
@@ -0,0 +1,220 @@
+//===--- ParsePragma.cpp - Language specific pragma parsing ---------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the language specific #pragma handlers.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ParsePragma.h"
+#include "clang/Parse/ParseDiagnostic.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Parse/Action.h"
+#include "clang/Parse/Parser.h"
+using namespace clang;
+
+// #pragma pack(...) comes in the following delicious flavors:
+//   pack '(' [integer] ')'
+//   pack '(' 'show' ')'
+//   pack '(' ('push' | 'pop') [',' identifier] [, integer] ')'
+void PragmaPackHandler::HandlePragma(Preprocessor &PP, Token &PackTok) {
+  // FIXME: Should we be expanding macros here? My guess is no.
+  SourceLocation PackLoc = PackTok.getLocation();
+
+  Token Tok;
+  PP.Lex(Tok);
+  if (Tok.isNot(tok::l_paren)) {
+    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "pack";
+    return;
+  }
+
+  Action::PragmaPackKind Kind = Action::PPK_Default;
+  IdentifierInfo *Name = 0;
+  Action::OwningExprResult Alignment(Actions);
+  SourceLocation LParenLoc = Tok.getLocation();
+  PP.Lex(Tok);
+  if (Tok.is(tok::numeric_constant)) {
+    Alignment = Actions.ActOnNumericConstant(Tok);
+    if (Alignment.isInvalid())
+      return;
+
+    PP.Lex(Tok);
+  } else if (Tok.is(tok::identifier)) {
+    const IdentifierInfo *II = Tok.getIdentifierInfo();
+    if (II->isStr("show")) {
+      Kind = Action::PPK_Show;
+      PP.Lex(Tok);
+    } else {
+      if (II->isStr("push")) {
+        Kind = Action::PPK_Push;
+      } else if (II->isStr("pop")) {
+        Kind = Action::PPK_Pop;
+      } else {
+        PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_invalid_action);
+        return;
+      }
+      PP.Lex(Tok);
+
+      if (Tok.is(tok::comma)) {
+        PP.Lex(Tok);
+
+        if (Tok.is(tok::numeric_constant)) {
+          Alignment = Actions.ActOnNumericConstant(Tok);
+          if (Alignment.isInvalid())
+            return;
+
+          PP.Lex(Tok);
+        } else if (Tok.is(tok::identifier)) {
+          Name = Tok.getIdentifierInfo();
+          PP.Lex(Tok);
+
+          if (Tok.is(tok::comma)) {
+            PP.Lex(Tok);
+
+            if (Tok.isNot(tok::numeric_constant)) {
+              PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed);
+              return;
+            }
+
+            Alignment = Actions.ActOnNumericConstant(Tok);
+            if (Alignment.isInvalid())
+              return;
+
+            PP.Lex(Tok);
+          }
+        } else {
+          PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed);
+          return;
+        }
+      }
+    }
+  }
+
+  if (Tok.isNot(tok::r_paren)) {
+    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen) << "pack";
+    return;
+  }
+
+  PP.Lex(Tok);
+  if (Tok.isNot(tok::eom)) {
+    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << "pack";
+    return;
+  }
+
+  SourceLocation RParenLoc = Tok.getLocation();
+  Actions.ActOnPragmaPack(Kind, Name, Alignment.release(), PackLoc,
+                          LParenLoc, RParenLoc);
+}
+
+// #pragma unused(identifier)
+void PragmaUnusedHandler::HandlePragma(Preprocessor &PP, Token &UnusedTok) {
+  // FIXME: Should we be expanding macros here? My guess is no.
+  SourceLocation UnusedLoc = UnusedTok.getLocation();
+
+  // Lex the left '('.
+  Token Tok;
+  PP.Lex(Tok);
+  if (Tok.isNot(tok::l_paren)) {
+    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "unused";
+    return;
+  }
+  SourceLocation LParenLoc = Tok.getLocation();
+
+  // Lex the declaration reference(s).
+  llvm::SmallVector<Token, 5> Identifiers;
+  SourceLocation RParenLoc;
+  bool LexID = true;
+
+  while (true) {
+    PP.Lex(Tok);
+
+    if (LexID) {
+      if (Tok.is(tok::identifier)) {
+        Identifiers.push_back(Tok);
+        LexID = false;
+        continue;
+      }
+
+      // Illegal token!
+      PP.Diag(Tok.getLocation(), diag::warn_pragma_unused_expected_var);
+      return;
+    }
+
+    // We are execting a ')' or a ','.
+    if (Tok.is(tok::comma)) {
+      LexID = true;
+      continue;
+    }
+
+    if (Tok.is(tok::r_paren)) {
+      RParenLoc = Tok.getLocation();
+      break;
+    }
+
+    // Illegal token!
+    PP.Diag(Tok.getLocation(), diag::warn_pragma_unused_expected_punc);
+    return;
+  }
+
+  PP.Lex(Tok);
+  if (Tok.isNot(tok::eom)) {
+    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
+        "unused";
+    return;
+  }
+
+  // Verify that we have a location for the right parenthesis.
+  assert(RParenLoc.isValid() && "Valid '#pragma unused' must have ')'");
+  assert(!Identifiers.empty() && "Valid '#pragma unused' must have arguments");
+
+  // Perform the action to handle the pragma.
+  Actions.ActOnPragmaUnused(Identifiers.data(), Identifiers.size(),
+                            parser.CurScope, UnusedLoc, LParenLoc, RParenLoc);
+}
+
+// #pragma weak identifier
+// #pragma weak identifier '=' identifier
+void PragmaWeakHandler::HandlePragma(Preprocessor &PP, Token &WeakTok) {
+  // FIXME: Should we be expanding macros here? My guess is no.
+  SourceLocation WeakLoc = WeakTok.getLocation();
+
+  Token Tok;
+  PP.Lex(Tok);
+  if (Tok.isNot(tok::identifier)) {
+    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) << "weak";
+    return;
+  }
+
+  IdentifierInfo *WeakName = Tok.getIdentifierInfo(), *AliasName = 0;
+  SourceLocation WeakNameLoc = Tok.getLocation(), AliasNameLoc;
+
+  PP.Lex(Tok);
+  if (Tok.is(tok::equal)) {
+    PP.Lex(Tok);
+    if (Tok.isNot(tok::identifier)) {
+      PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
+          << "weak";
+      return;
+    }
+    AliasName = Tok.getIdentifierInfo();
+    AliasNameLoc = Tok.getLocation();
+    PP.Lex(Tok);
+  }
+
+  if (Tok.isNot(tok::eom)) {
+    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << "weak";
+    return;
+  }
+
+  if (AliasName) {
+    Actions.ActOnPragmaWeakAlias(WeakName, AliasName, WeakLoc, WeakNameLoc,
+                                 AliasNameLoc);
+  } else {
+    Actions.ActOnPragmaWeakID(WeakName, WeakLoc, WeakNameLoc);
+  }
+}
diff --git a/lib/Parse/ParsePragma.h b/lib/Parse/ParsePragma.h
new file mode 100644
index 0000000..db385c6
--- /dev/null
+++ b/lib/Parse/ParsePragma.h
@@ -0,0 +1,53 @@
+//===---- ParserPragmas.h - Language specific pragmas -----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines #pragma handlers for language specific pragmas.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_PARSE_PARSEPRAGMA_H
+#define LLVM_CLANG_PARSE_PARSEPRAGMA_H
+
+#include "clang/Lex/Pragma.h"
+
+namespace clang {
+  class Action;
+  class Parser;
+
+class PragmaPackHandler : public PragmaHandler {
+  Action &Actions;
+public:
+  PragmaPackHandler(const IdentifierInfo *N, Action &A) : PragmaHandler(N),
+                                                          Actions(A) {}
+
+  virtual void HandlePragma(Preprocessor &PP, Token &FirstToken);
+};
+
+class PragmaUnusedHandler : public PragmaHandler {
+  Action &Actions;
+  Parser &parser;
+public:
+  PragmaUnusedHandler(const IdentifierInfo *N, Action &A, Parser& p)
+    : PragmaHandler(N), Actions(A), parser(p) {}
+
+  virtual void HandlePragma(Preprocessor &PP, Token &FirstToken);
+};
+
+class PragmaWeakHandler : public PragmaHandler {
+  Action &Actions;
+public:
+  PragmaWeakHandler(const IdentifierInfo *N, Action &A)
+    : PragmaHandler(N), Actions(A) {}
+
+  virtual void HandlePragma(Preprocessor &PP, Token &FirstToken);
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp
new file mode 100644
index 0000000..9b22270
--- /dev/null
+++ b/lib/Parse/ParseStmt.cpp
@@ -0,0 +1,1581 @@
+//===--- ParseStmt.cpp - Statement and Block Parser -----------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Statement and Block portions of the Parser
+// interface.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Parse/Parser.h"
+#include "RAIIObjectsForParser.h"
+#include "clang/Parse/DeclSpec.h"
+#include "clang/Parse/Scope.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/PrettyStackTrace.h"
+#include "clang/Basic/SourceManager.h"
+using namespace clang;
+
+//===----------------------------------------------------------------------===//
+// C99 6.8: Statements and Blocks.
+//===----------------------------------------------------------------------===//
+
+/// ParseStatementOrDeclaration - Read 'statement' or 'declaration'.
+///       StatementOrDeclaration:
+///         statement
+///         declaration
+///
+///       statement:
+///         labeled-statement
+///         compound-statement
+///         expression-statement
+///         selection-statement
+///         iteration-statement
+///         jump-statement
+/// [C++]   declaration-statement
+/// [C++]   try-block
+/// [OBC]   objc-throw-statement
+/// [OBC]   objc-try-catch-statement
+/// [OBC]   objc-synchronized-statement
+/// [GNU]   asm-statement
+/// [OMP]   openmp-construct             [TODO]
+///
+///       labeled-statement:
+///         identifier ':' statement
+///         'case' constant-expression ':' statement
+///         'default' ':' statement
+///
+///       selection-statement:
+///         if-statement
+///         switch-statement
+///
+///       iteration-statement:
+///         while-statement
+///         do-statement
+///         for-statement
+///
+///       expression-statement:
+///         expression[opt] ';'
+///
+///       jump-statement:
+///         'goto' identifier ';'
+///         'continue' ';'
+///         'break' ';'
+///         'return' expression[opt] ';'
+/// [GNU]   'goto' '*' expression ';'
+///
+/// [OBC] objc-throw-statement:
+/// [OBC]   '@' 'throw' expression ';'
+/// [OBC]   '@' 'throw' ';'
+///
+Parser::OwningStmtResult
+Parser::ParseStatementOrDeclaration(bool OnlyStatement) {
+  const char *SemiError = 0;
+  OwningStmtResult Res(Actions);
+
+  CXX0XAttributeList Attr;
+  if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier())
+    Attr = ParseCXX0XAttributes();
+  llvm::OwningPtr<AttributeList> AttrList(Attr.AttrList);
+
+  // Cases in this switch statement should fall through if the parser expects
+  // the token to end in a semicolon (in which case SemiError should be set),
+  // or they directly 'return;' if not.
+  tok::TokenKind Kind  = Tok.getKind();
+  SourceLocation AtLoc;
+  switch (Kind) {
+  case tok::at: // May be a @try or @throw statement
+    {
+      AtLoc = ConsumeToken();  // consume @
+      return ParseObjCAtStatement(AtLoc);
+    }
+
+  case tok::code_completion:
+    Actions.CodeCompleteOrdinaryName(CurScope, Action::CCC_Statement);
+    ConsumeToken();
+    return ParseStatementOrDeclaration(OnlyStatement);
+      
+  case tok::identifier:
+    if (NextToken().is(tok::colon)) { // C99 6.8.1: labeled-statement
+      // identifier ':' statement
+      return ParseLabeledStatement(AttrList.take());
+    }
+    // PASS THROUGH.
+
+  default: {
+    if ((getLang().CPlusPlus || !OnlyStatement) && isDeclarationStatement()) {
+      SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
+      AttrList.take(); //Passing 'Attr' to ParseDeclaration transfers ownership.
+      DeclGroupPtrTy Decl = ParseDeclaration(Declarator::BlockContext, DeclEnd,
+                                             Attr);
+      return Actions.ActOnDeclStmt(Decl, DeclStart, DeclEnd);
+    }
+
+    if (Tok.is(tok::r_brace)) {
+      Diag(Tok, diag::err_expected_statement);
+      return StmtError();
+    }
+
+    // FIXME: Use the attributes
+    // expression[opt] ';'
+    OwningExprResult Expr(ParseExpression());
+    if (Expr.isInvalid()) {
+      // If the expression is invalid, skip ahead to the next semicolon or '}'.
+      // Not doing this opens us up to the possibility of infinite loops if
+      // ParseExpression does not consume any tokens.
+      SkipUntil(tok::r_brace, /*StopAtSemi=*/true, /*DontConsume=*/true);
+      if (Tok.is(tok::semi))
+        ConsumeToken();
+      return StmtError();
+    }
+    // Otherwise, eat the semicolon.
+    ExpectAndConsume(tok::semi, diag::err_expected_semi_after_expr);
+    return Actions.ActOnExprStmt(Actions.MakeFullExpr(Expr));
+  }
+
+  case tok::kw_case:                // C99 6.8.1: labeled-statement
+    return ParseCaseStatement(AttrList.take());
+  case tok::kw_default:             // C99 6.8.1: labeled-statement
+    return ParseDefaultStatement(AttrList.take());
+
+  case tok::l_brace:                // C99 6.8.2: compound-statement
+    return ParseCompoundStatement(AttrList.take());
+  case tok::semi:                   // C99 6.8.3p3: expression[opt] ';'
+    return Actions.ActOnNullStmt(ConsumeToken());
+
+  case tok::kw_if:                  // C99 6.8.4.1: if-statement
+    return ParseIfStatement(AttrList.take());
+  case tok::kw_switch:              // C99 6.8.4.2: switch-statement
+    return ParseSwitchStatement(AttrList.take());
+
+  case tok::kw_while:               // C99 6.8.5.1: while-statement
+    return ParseWhileStatement(AttrList.take());
+  case tok::kw_do:                  // C99 6.8.5.2: do-statement
+    Res = ParseDoStatement(AttrList.take());
+    SemiError = "do/while";
+    break;
+  case tok::kw_for:                 // C99 6.8.5.3: for-statement
+    return ParseForStatement(AttrList.take());
+
+  case tok::kw_goto:                // C99 6.8.6.1: goto-statement
+    Res = ParseGotoStatement(AttrList.take());
+    SemiError = "goto";
+    break;
+  case tok::kw_continue:            // C99 6.8.6.2: continue-statement
+    Res = ParseContinueStatement(AttrList.take());
+    SemiError = "continue";
+    break;
+  case tok::kw_break:               // C99 6.8.6.3: break-statement
+    Res = ParseBreakStatement(AttrList.take());
+    SemiError = "break";
+    break;
+  case tok::kw_return:              // C99 6.8.6.4: return-statement
+    Res = ParseReturnStatement(AttrList.take());
+    SemiError = "return";
+    break;
+
+  case tok::kw_asm: {
+    if (Attr.HasAttr)
+      Diag(Attr.Range.getBegin(), diag::err_attributes_not_allowed)
+        << Attr.Range;
+    bool msAsm = false;
+    Res = ParseAsmStatement(msAsm);
+    if (msAsm) return move(Res);
+    SemiError = "asm";
+    break;
+  }
+
+  case tok::kw_try:                 // C++ 15: try-block
+    return ParseCXXTryBlock(AttrList.take());
+  }
+
+  // If we reached this code, the statement must end in a semicolon.
+  if (Tok.is(tok::semi)) {
+    ConsumeToken();
+  } else if (!Res.isInvalid()) {
+    // If the result was valid, then we do want to diagnose this.  Use
+    // ExpectAndConsume to emit the diagnostic, even though we know it won't
+    // succeed.
+    ExpectAndConsume(tok::semi, diag::err_expected_semi_after_stmt, SemiError);
+    // Skip until we see a } or ;, but don't eat it.
+    SkipUntil(tok::r_brace, true, true);
+  }
+
+  return move(Res);
+}
+
+/// ParseLabeledStatement - We have an identifier and a ':' after it.
+///
+///       labeled-statement:
+///         identifier ':' statement
+/// [GNU]   identifier ':' attributes[opt] statement
+///
+Parser::OwningStmtResult Parser::ParseLabeledStatement(AttributeList *Attr) {
+  assert(Tok.is(tok::identifier) && Tok.getIdentifierInfo() &&
+         "Not an identifier!");
+
+  llvm::OwningPtr<AttributeList> AttrList(Attr);
+  Token IdentTok = Tok;  // Save the whole token.
+  ConsumeToken();  // eat the identifier.
+
+  assert(Tok.is(tok::colon) && "Not a label!");
+
+  // identifier ':' statement
+  SourceLocation ColonLoc = ConsumeToken();
+
+  // Read label attributes, if present.
+  if (Tok.is(tok::kw___attribute))
+    AttrList.reset(addAttributeLists(AttrList.take(), ParseGNUAttributes()));
+
+  OwningStmtResult SubStmt(ParseStatement());
+
+  // Broken substmt shouldn't prevent the label from being added to the AST.
+  if (SubStmt.isInvalid())
+    SubStmt = Actions.ActOnNullStmt(ColonLoc);
+
+  // FIXME: use attributes?
+  return Actions.ActOnLabelStmt(IdentTok.getLocation(),
+                                IdentTok.getIdentifierInfo(),
+                                ColonLoc, move(SubStmt));
+}
+
+/// ParseCaseStatement
+///       labeled-statement:
+///         'case' constant-expression ':' statement
+/// [GNU]   'case' constant-expression '...' constant-expression ':' statement
+///
+Parser::OwningStmtResult Parser::ParseCaseStatement(AttributeList *Attr) {
+  assert(Tok.is(tok::kw_case) && "Not a case stmt!");
+  // FIXME: Use attributes?
+  delete Attr;
+
+  // It is very very common for code to contain many case statements recursively
+  // nested, as in (but usually without indentation):
+  //  case 1:
+  //    case 2:
+  //      case 3:
+  //         case 4:
+  //           case 5: etc.
+  //
+  // Parsing this naively works, but is both inefficient and can cause us to run
+  // out of stack space in our recursive descent parser.  As a special case,
+  // flatten this recursion into an iterative loop.  This is complex and gross,
+  // but all the grossness is constrained to ParseCaseStatement (and some
+  // wierdness in the actions), so this is just local grossness :).
+
+  // TopLevelCase - This is the highest level we have parsed.  'case 1' in the
+  // example above.
+  OwningStmtResult TopLevelCase(Actions, true);
+
+  // DeepestParsedCaseStmt - This is the deepest statement we have parsed, which
+  // gets updated each time a new case is parsed, and whose body is unset so
+  // far.  When parsing 'case 4', this is the 'case 3' node.
+  StmtTy *DeepestParsedCaseStmt = 0;
+
+  // While we have case statements, eat and stack them.
+  do {
+    SourceLocation CaseLoc = ConsumeToken();  // eat the 'case'.
+
+    if (Tok.is(tok::code_completion)) {
+      Actions.CodeCompleteCase(CurScope);
+      ConsumeToken();
+    }
+    
+    /// We don't want to treat 'case x : y' as a potential typo for 'case x::y'.
+    /// Disable this form of error recovery while we're parsing the case
+    /// expression.
+    ColonProtectionRAIIObject ColonProtection(*this);
+    
+    OwningExprResult LHS(ParseConstantExpression());
+    if (LHS.isInvalid()) {
+      SkipUntil(tok::colon);
+      return StmtError();
+    }
+
+    // GNU case range extension.
+    SourceLocation DotDotDotLoc;
+    OwningExprResult RHS(Actions);
+    if (Tok.is(tok::ellipsis)) {
+      Diag(Tok, diag::ext_gnu_case_range);
+      DotDotDotLoc = ConsumeToken();
+
+      RHS = ParseConstantExpression();
+      if (RHS.isInvalid()) {
+        SkipUntil(tok::colon);
+        return StmtError();
+      }
+    }
+    
+    ColonProtection.restore();
+
+    if (Tok.isNot(tok::colon)) {
+      Diag(Tok, diag::err_expected_colon_after) << "'case'";
+      SkipUntil(tok::colon);
+      return StmtError();
+    }
+
+    SourceLocation ColonLoc = ConsumeToken();
+
+    OwningStmtResult Case =
+      Actions.ActOnCaseStmt(CaseLoc, move(LHS), DotDotDotLoc,
+                            move(RHS), ColonLoc);
+
+    // If we had a sema error parsing this case, then just ignore it and
+    // continue parsing the sub-stmt.
+    if (Case.isInvalid()) {
+      if (TopLevelCase.isInvalid())  // No parsed case stmts.
+        return ParseStatement();
+      // Otherwise, just don't add it as a nested case.
+    } else {
+      // If this is the first case statement we parsed, it becomes TopLevelCase.
+      // Otherwise we link it into the current chain.
+      StmtTy *NextDeepest = Case.get();
+      if (TopLevelCase.isInvalid())
+        TopLevelCase = move(Case);
+      else
+        Actions.ActOnCaseStmtBody(DeepestParsedCaseStmt, move(Case));
+      DeepestParsedCaseStmt = NextDeepest;
+    }
+
+    // Handle all case statements.
+  } while (Tok.is(tok::kw_case));
+
+  assert(!TopLevelCase.isInvalid() && "Should have parsed at least one case!");
+
+  // If we found a non-case statement, start by parsing it.
+  OwningStmtResult SubStmt(Actions);
+
+  if (Tok.isNot(tok::r_brace)) {
+    SubStmt = ParseStatement();
+  } else {
+    // Nicely diagnose the common error "switch (X) { case 4: }", which is
+    // not valid.
+    // FIXME: add insertion hint.
+    Diag(Tok, diag::err_label_end_of_compound_statement);
+    SubStmt = true;
+  }
+
+  // Broken sub-stmt shouldn't prevent forming the case statement properly.
+  if (SubStmt.isInvalid())
+    SubStmt = Actions.ActOnNullStmt(SourceLocation());
+
+  // Install the body into the most deeply-nested case.
+  Actions.ActOnCaseStmtBody(DeepestParsedCaseStmt, move(SubStmt));
+
+  // Return the top level parsed statement tree.
+  return move(TopLevelCase);
+}
+
+/// ParseDefaultStatement
+///       labeled-statement:
+///         'default' ':' statement
+/// Note that this does not parse the 'statement' at the end.
+///
+Parser::OwningStmtResult Parser::ParseDefaultStatement(AttributeList *Attr) {
+  //FIXME: Use attributes?
+  delete Attr;
+
+  assert(Tok.is(tok::kw_default) && "Not a default stmt!");
+  SourceLocation DefaultLoc = ConsumeToken();  // eat the 'default'.
+
+  if (Tok.isNot(tok::colon)) {
+    Diag(Tok, diag::err_expected_colon_after) << "'default'";
+    SkipUntil(tok::colon);
+    return StmtError();
+  }
+
+  SourceLocation ColonLoc = ConsumeToken();
+
+  // Diagnose the common error "switch (X) {... default: }", which is not valid.
+  if (Tok.is(tok::r_brace)) {
+    Diag(Tok, diag::err_label_end_of_compound_statement);
+    return StmtError();
+  }
+
+  OwningStmtResult SubStmt(ParseStatement());
+  if (SubStmt.isInvalid())
+    return StmtError();
+
+  return Actions.ActOnDefaultStmt(DefaultLoc, ColonLoc,
+                                  move(SubStmt), CurScope);
+}
+
+
+/// ParseCompoundStatement - Parse a "{}" block.
+///
+///       compound-statement: [C99 6.8.2]
+///         { block-item-list[opt] }
+/// [GNU]   { label-declarations block-item-list } [TODO]
+///
+///       block-item-list:
+///         block-item
+///         block-item-list block-item
+///
+///       block-item:
+///         declaration
+/// [GNU]   '__extension__' declaration
+///         statement
+/// [OMP]   openmp-directive            [TODO]
+///
+/// [GNU] label-declarations:
+/// [GNU]   label-declaration
+/// [GNU]   label-declarations label-declaration
+///
+/// [GNU] label-declaration:
+/// [GNU]   '__label__' identifier-list ';'
+///
+/// [OMP] openmp-directive:             [TODO]
+/// [OMP]   barrier-directive
+/// [OMP]   flush-directive
+///
+Parser::OwningStmtResult Parser::ParseCompoundStatement(AttributeList *Attr,
+                                                        bool isStmtExpr) {
+  //FIXME: Use attributes?
+  delete Attr;
+
+  assert(Tok.is(tok::l_brace) && "Not a compount stmt!");
+
+  // Enter a scope to hold everything within the compound stmt.  Compound
+  // statements can always hold declarations.
+  ParseScope CompoundScope(this, Scope::DeclScope);
+
+  // Parse the statements in the body.
+  return ParseCompoundStatementBody(isStmtExpr);
+}
+
+
+/// ParseCompoundStatementBody - Parse a sequence of statements and invoke the
+/// ActOnCompoundStmt action.  This expects the '{' to be the current token, and
+/// consume the '}' at the end of the block.  It does not manipulate the scope
+/// stack.
+Parser::OwningStmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) {
+  PrettyStackTraceLoc CrashInfo(PP.getSourceManager(),
+                                Tok.getLocation(),
+                                "in compound statement ('{}')");
+
+  SourceLocation LBraceLoc = ConsumeBrace();  // eat the '{'.
+
+  // TODO: "__label__ X, Y, Z;" is the GNU "Local Label" extension.  These are
+  // only allowed at the start of a compound stmt regardless of the language.
+
+  typedef StmtVector StmtsTy;
+  StmtsTy Stmts(Actions);
+  while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
+    OwningStmtResult R(Actions);
+    if (Tok.isNot(tok::kw___extension__)) {
+      R = ParseStatementOrDeclaration(false);
+    } else {
+      // __extension__ can start declarations and it can also be a unary
+      // operator for expressions.  Consume multiple __extension__ markers here
+      // until we can determine which is which.
+      // FIXME: This loses extension expressions in the AST!
+      SourceLocation ExtLoc = ConsumeToken();
+      while (Tok.is(tok::kw___extension__))
+        ConsumeToken();
+
+      CXX0XAttributeList Attr;
+      if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier())
+        Attr = ParseCXX0XAttributes();
+
+      // If this is the start of a declaration, parse it as such.
+      if (isDeclarationStatement()) {
+        // __extension__ silences extension warnings in the subdeclaration.
+        // FIXME: Save the __extension__ on the decl as a node somehow?
+        ExtensionRAIIObject O(Diags);
+
+        SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
+        DeclGroupPtrTy Res = ParseDeclaration(Declarator::BlockContext, DeclEnd,
+                                              Attr);
+        R = Actions.ActOnDeclStmt(Res, DeclStart, DeclEnd);
+      } else {
+        // Otherwise this was a unary __extension__ marker.
+        OwningExprResult Res(ParseExpressionWithLeadingExtension(ExtLoc));
+
+        if (Res.isInvalid()) {
+          SkipUntil(tok::semi);
+          continue;
+        }
+
+        // FIXME: Use attributes?
+        // Eat the semicolon at the end of stmt and convert the expr into a
+        // statement.
+        ExpectAndConsume(tok::semi, diag::err_expected_semi_after_expr);
+        R = Actions.ActOnExprStmt(Actions.MakeFullExpr(Res));
+      }
+    }
+
+    if (R.isUsable())
+      Stmts.push_back(R.release());
+  }
+
+  // We broke out of the while loop because we found a '}' or EOF.
+  if (Tok.isNot(tok::r_brace)) {
+    Diag(Tok, diag::err_expected_rbrace);
+    return StmtError();
+  }
+
+  SourceLocation RBraceLoc = ConsumeBrace();
+  return Actions.ActOnCompoundStmt(LBraceLoc, RBraceLoc, move_arg(Stmts),
+                                   isStmtExpr);
+}
+
+/// ParseParenExprOrCondition:
+/// [C  ]     '(' expression ')'
+/// [C++]     '(' condition ')'       [not allowed if OnlyAllowCondition=true]
+///
+/// This function parses and performs error recovery on the specified condition
+/// or expression (depending on whether we're in C++ or C mode).  This function
+/// goes out of its way to recover well.  It returns true if there was a parser
+/// error (the right paren couldn't be found), which indicates that the caller
+/// should try to recover harder.  It returns false if the condition is
+/// successfully parsed.  Note that a successful parse can still have semantic
+/// errors in the condition.
+bool Parser::ParseParenExprOrCondition(OwningExprResult &ExprResult,
+                                       DeclPtrTy &DeclResult) {
+  bool ParseError = false;
+  
+  SourceLocation LParenLoc = ConsumeParen();
+  if (getLang().CPlusPlus) 
+    ParseError = ParseCXXCondition(ExprResult, DeclResult);
+  else {
+    ExprResult = ParseExpression();
+    DeclResult = DeclPtrTy();
+  }
+
+  // If the parser was confused by the condition and we don't have a ')', try to
+  // recover by skipping ahead to a semi and bailing out.  If condexp is
+  // semantically invalid but we have well formed code, keep going.
+  if (ExprResult.isInvalid() && !DeclResult.get() && Tok.isNot(tok::r_paren)) {
+    SkipUntil(tok::semi);
+    // Skipping may have stopped if it found the containing ')'.  If so, we can
+    // continue parsing the if statement.
+    if (Tok.isNot(tok::r_paren))
+      return true;
+  }
+
+  // Otherwise the condition is valid or the rparen is present.
+  MatchRHSPunctuation(tok::r_paren, LParenLoc);
+  return false;
+}
+
+
+/// ParseIfStatement
+///       if-statement: [C99 6.8.4.1]
+///         'if' '(' expression ')' statement
+///         'if' '(' expression ')' statement 'else' statement
+/// [C++]   'if' '(' condition ')' statement
+/// [C++]   'if' '(' condition ')' statement 'else' statement
+///
+Parser::OwningStmtResult Parser::ParseIfStatement(AttributeList *Attr) {
+  // FIXME: Use attributes?
+  delete Attr;
+
+  assert(Tok.is(tok::kw_if) && "Not an if stmt!");
+  SourceLocation IfLoc = ConsumeToken();  // eat the 'if'.
+
+  if (Tok.isNot(tok::l_paren)) {
+    Diag(Tok, diag::err_expected_lparen_after) << "if";
+    SkipUntil(tok::semi);
+    return StmtError();
+  }
+
+  bool C99orCXX = getLang().C99 || getLang().CPlusPlus;
+
+  // C99 6.8.4p3 - In C99, the if statement is a block.  This is not
+  // the case for C90.
+  //
+  // C++ 6.4p3:
+  // A name introduced by a declaration in a condition is in scope from its
+  // point of declaration until the end of the substatements controlled by the
+  // condition.
+  // C++ 3.3.2p4:
+  // Names declared in the for-init-statement, and in the condition of if,
+  // while, for, and switch statements are local to the if, while, for, or
+  // switch statement (including the controlled statement).
+  //
+  ParseScope IfScope(this, Scope::DeclScope | Scope::ControlScope, C99orCXX);
+
+  // Parse the condition.
+  OwningExprResult CondExp(Actions);
+  DeclPtrTy CondVar;
+  if (ParseParenExprOrCondition(CondExp, CondVar))
+    return StmtError();
+
+  FullExprArg FullCondExp(Actions.MakeFullExpr(CondExp));
+
+  // C99 6.8.4p3 - In C99, the body of the if statement is a scope, even if
+  // there is no compound stmt.  C90 does not have this clause.  We only do this
+  // if the body isn't a compound statement to avoid push/pop in common cases.
+  //
+  // C++ 6.4p1:
+  // The substatement in a selection-statement (each substatement, in the else
+  // form of the if statement) implicitly defines a local scope.
+  //
+  // For C++ we create a scope for the condition and a new scope for
+  // substatements because:
+  // -When the 'then' scope exits, we want the condition declaration to still be
+  //    active for the 'else' scope too.
+  // -Sema will detect name clashes by considering declarations of a
+  //    'ControlScope' as part of its direct subscope.
+  // -If we wanted the condition and substatement to be in the same scope, we
+  //    would have to notify ParseStatement not to create a new scope. It's
+  //    simpler to let it create a new scope.
+  //
+  ParseScope InnerScope(this, Scope::DeclScope,
+                        C99orCXX && Tok.isNot(tok::l_brace));
+
+  // Read the 'then' stmt.
+  SourceLocation ThenStmtLoc = Tok.getLocation();
+  OwningStmtResult ThenStmt(ParseStatement());
+
+  // Pop the 'if' scope if needed.
+  InnerScope.Exit();
+
+  // If it has an else, parse it.
+  SourceLocation ElseLoc;
+  SourceLocation ElseStmtLoc;
+  OwningStmtResult ElseStmt(Actions);
+
+  if (Tok.is(tok::kw_else)) {
+    ElseLoc = ConsumeToken();
+    ElseStmtLoc = Tok.getLocation();
+
+    // C99 6.8.4p3 - In C99, the body of the if statement is a scope, even if
+    // there is no compound stmt.  C90 does not have this clause.  We only do
+    // this if the body isn't a compound statement to avoid push/pop in common
+    // cases.
+    //
+    // C++ 6.4p1:
+    // The substatement in a selection-statement (each substatement, in the else
+    // form of the if statement) implicitly defines a local scope.
+    //
+    ParseScope InnerScope(this, Scope::DeclScope,
+                          C99orCXX && Tok.isNot(tok::l_brace));
+
+    // Regardless of whether or not InnerScope actually pushed a scope, set the
+    // ElseScope flag for the innermost scope so we can diagnose use of the if
+    // condition variable in C++.
+    unsigned OldFlags = CurScope->getFlags();
+    CurScope->setFlags(OldFlags | Scope::ElseScope);
+    ElseStmt = ParseStatement();
+    CurScope->setFlags(OldFlags);
+    
+    // Pop the 'else' scope if needed.
+    InnerScope.Exit();
+  }
+
+  IfScope.Exit();
+
+  // If the condition was invalid, discard the if statement.  We could recover
+  // better by replacing it with a valid expr, but don't do that yet.
+  if (CondExp.isInvalid() && !CondVar.get())
+    return StmtError();
+
+  // If the then or else stmt is invalid and the other is valid (and present),
+  // make turn the invalid one into a null stmt to avoid dropping the other
+  // part.  If both are invalid, return error.
+  if ((ThenStmt.isInvalid() && ElseStmt.isInvalid()) ||
+      (ThenStmt.isInvalid() && ElseStmt.get() == 0) ||
+      (ThenStmt.get() == 0  && ElseStmt.isInvalid())) {
+    // Both invalid, or one is invalid and other is non-present: return error.
+    return StmtError();
+  }
+
+  // Now if either are invalid, replace with a ';'.
+  if (ThenStmt.isInvalid())
+    ThenStmt = Actions.ActOnNullStmt(ThenStmtLoc);
+  if (ElseStmt.isInvalid())
+    ElseStmt = Actions.ActOnNullStmt(ElseStmtLoc);
+
+  return Actions.ActOnIfStmt(IfLoc, FullCondExp, CondVar, move(ThenStmt),
+                             ElseLoc, move(ElseStmt));
+}
+
+/// ParseSwitchStatement
+///       switch-statement:
+///         'switch' '(' expression ')' statement
+/// [C++]   'switch' '(' condition ')' statement
+Parser::OwningStmtResult Parser::ParseSwitchStatement(AttributeList *Attr) {
+  // FIXME: Use attributes?
+  delete Attr;
+
+  assert(Tok.is(tok::kw_switch) && "Not a switch stmt!");
+  SourceLocation SwitchLoc = ConsumeToken();  // eat the 'switch'.
+
+  if (Tok.isNot(tok::l_paren)) {
+    Diag(Tok, diag::err_expected_lparen_after) << "switch";
+    SkipUntil(tok::semi);
+    return StmtError();
+  }
+
+  bool C99orCXX = getLang().C99 || getLang().CPlusPlus;
+
+  // C99 6.8.4p3 - In C99, the switch statement is a block.  This is
+  // not the case for C90.  Start the switch scope.
+  //
+  // C++ 6.4p3:
+  // A name introduced by a declaration in a condition is in scope from its
+  // point of declaration until the end of the substatements controlled by the
+  // condition.
+  // C++ 3.3.2p4:
+  // Names declared in the for-init-statement, and in the condition of if,
+  // while, for, and switch statements are local to the if, while, for, or
+  // switch statement (including the controlled statement).
+  //
+  unsigned ScopeFlags = Scope::BreakScope;
+  if (C99orCXX)
+    ScopeFlags |= Scope::DeclScope | Scope::ControlScope;
+  ParseScope SwitchScope(this, ScopeFlags);
+
+  // Parse the condition.
+  OwningExprResult Cond(Actions);
+  DeclPtrTy CondVar;
+  if (ParseParenExprOrCondition(Cond, CondVar))
+    return StmtError();
+
+  FullExprArg FullCond(Actions.MakeFullExpr(Cond));
+  
+  OwningStmtResult Switch = Actions.ActOnStartOfSwitchStmt(FullCond, CondVar);
+
+  // C99 6.8.4p3 - In C99, the body of the switch statement is a scope, even if
+  // there is no compound stmt.  C90 does not have this clause.  We only do this
+  // if the body isn't a compound statement to avoid push/pop in common cases.
+  //
+  // C++ 6.4p1:
+  // The substatement in a selection-statement (each substatement, in the else
+  // form of the if statement) implicitly defines a local scope.
+  //
+  // See comments in ParseIfStatement for why we create a scope for the
+  // condition and a new scope for substatement in C++.
+  //
+  ParseScope InnerScope(this, Scope::DeclScope,
+                        C99orCXX && Tok.isNot(tok::l_brace));
+
+  // Read the body statement.
+  OwningStmtResult Body(ParseStatement());
+
+  // Pop the scopes.
+  InnerScope.Exit();
+  SwitchScope.Exit();
+
+  if (Cond.isInvalid() && !CondVar.get()) {
+    Actions.ActOnSwitchBodyError(SwitchLoc, move(Switch), move(Body));
+    return StmtError();
+  }
+
+  if (Body.isInvalid())
+    // FIXME: Remove the case statement list from the Switch statement.
+    Body = Actions.ActOnNullStmt(Tok.getLocation());
+  
+  return Actions.ActOnFinishSwitchStmt(SwitchLoc, move(Switch), move(Body));
+}
+
+/// ParseWhileStatement
+///       while-statement: [C99 6.8.5.1]
+///         'while' '(' expression ')' statement
+/// [C++]   'while' '(' condition ')' statement
+Parser::OwningStmtResult Parser::ParseWhileStatement(AttributeList *Attr) {
+  // FIXME: Use attributes?
+  delete Attr;
+
+  assert(Tok.is(tok::kw_while) && "Not a while stmt!");
+  SourceLocation WhileLoc = Tok.getLocation();
+  ConsumeToken();  // eat the 'while'.
+
+  if (Tok.isNot(tok::l_paren)) {
+    Diag(Tok, diag::err_expected_lparen_after) << "while";
+    SkipUntil(tok::semi);
+    return StmtError();
+  }
+
+  bool C99orCXX = getLang().C99 || getLang().CPlusPlus;
+
+  // C99 6.8.5p5 - In C99, the while statement is a block.  This is not
+  // the case for C90.  Start the loop scope.
+  //
+  // C++ 6.4p3:
+  // A name introduced by a declaration in a condition is in scope from its
+  // point of declaration until the end of the substatements controlled by the
+  // condition.
+  // C++ 3.3.2p4:
+  // Names declared in the for-init-statement, and in the condition of if,
+  // while, for, and switch statements are local to the if, while, for, or
+  // switch statement (including the controlled statement).
+  //
+  unsigned ScopeFlags;
+  if (C99orCXX)
+    ScopeFlags = Scope::BreakScope | Scope::ContinueScope |
+                 Scope::DeclScope  | Scope::ControlScope;
+  else
+    ScopeFlags = Scope::BreakScope | Scope::ContinueScope;
+  ParseScope WhileScope(this, ScopeFlags);
+
+  // Parse the condition.
+  OwningExprResult Cond(Actions);
+  DeclPtrTy CondVar;
+  if (ParseParenExprOrCondition(Cond, CondVar))
+    return StmtError();
+
+  FullExprArg FullCond(Actions.MakeFullExpr(Cond));
+
+  // C99 6.8.5p5 - In C99, the body of the if statement is a scope, even if
+  // there is no compound stmt.  C90 does not have this clause.  We only do this
+  // if the body isn't a compound statement to avoid push/pop in common cases.
+  //
+  // C++ 6.5p2:
+  // The substatement in an iteration-statement implicitly defines a local scope
+  // which is entered and exited each time through the loop.
+  //
+  // See comments in ParseIfStatement for why we create a scope for the
+  // condition and a new scope for substatement in C++.
+  //
+  ParseScope InnerScope(this, Scope::DeclScope,
+                        C99orCXX && Tok.isNot(tok::l_brace));
+
+  // Read the body statement.
+  OwningStmtResult Body(ParseStatement());
+
+  // Pop the body scope if needed.
+  InnerScope.Exit();
+  WhileScope.Exit();
+
+  if ((Cond.isInvalid() && !CondVar.get()) || Body.isInvalid())
+    return StmtError();
+
+  return Actions.ActOnWhileStmt(WhileLoc, FullCond, CondVar, move(Body));
+}
+
+/// ParseDoStatement
+///       do-statement: [C99 6.8.5.2]
+///         'do' statement 'while' '(' expression ')' ';'
+/// Note: this lets the caller parse the end ';'.
+Parser::OwningStmtResult Parser::ParseDoStatement(AttributeList *Attr) {
+  // FIXME: Use attributes?
+  delete Attr;
+
+  assert(Tok.is(tok::kw_do) && "Not a do stmt!");
+  SourceLocation DoLoc = ConsumeToken();  // eat the 'do'.
+
+  // C99 6.8.5p5 - In C99, the do statement is a block.  This is not
+  // the case for C90.  Start the loop scope.
+  unsigned ScopeFlags;
+  if (getLang().C99)
+    ScopeFlags = Scope::BreakScope | Scope::ContinueScope | Scope::DeclScope;
+  else
+    ScopeFlags = Scope::BreakScope | Scope::ContinueScope;
+
+  ParseScope DoScope(this, ScopeFlags);
+
+  // C99 6.8.5p5 - In C99, the body of the if statement is a scope, even if
+  // there is no compound stmt.  C90 does not have this clause. We only do this
+  // if the body isn't a compound statement to avoid push/pop in common cases.
+  //
+  // C++ 6.5p2:
+  // The substatement in an iteration-statement implicitly defines a local scope
+  // which is entered and exited each time through the loop.
+  //
+  ParseScope InnerScope(this, Scope::DeclScope,
+                        (getLang().C99 || getLang().CPlusPlus) &&
+                        Tok.isNot(tok::l_brace));
+
+  // Read the body statement.
+  OwningStmtResult Body(ParseStatement());
+
+  // Pop the body scope if needed.
+  InnerScope.Exit();
+
+  if (Tok.isNot(tok::kw_while)) {
+    if (!Body.isInvalid()) {
+      Diag(Tok, diag::err_expected_while);
+      Diag(DoLoc, diag::note_matching) << "do";
+      SkipUntil(tok::semi, false, true);
+    }
+    return StmtError();
+  }
+  SourceLocation WhileLoc = ConsumeToken();
+
+  if (Tok.isNot(tok::l_paren)) {
+    Diag(Tok, diag::err_expected_lparen_after) << "do/while";
+    SkipUntil(tok::semi, false, true);
+    return StmtError();
+  }
+
+  // Parse the parenthesized condition.
+  SourceLocation LPLoc = ConsumeParen();
+  OwningExprResult Cond = ParseExpression();
+  SourceLocation RPLoc = MatchRHSPunctuation(tok::r_paren, LPLoc);
+  DoScope.Exit();
+
+  if (Cond.isInvalid() || Body.isInvalid())
+    return StmtError();
+
+  return Actions.ActOnDoStmt(DoLoc, move(Body), WhileLoc, LPLoc,
+                             move(Cond), RPLoc);
+}
+
+/// ParseForStatement
+///       for-statement: [C99 6.8.5.3]
+///         'for' '(' expr[opt] ';' expr[opt] ';' expr[opt] ')' statement
+///         'for' '(' declaration expr[opt] ';' expr[opt] ')' statement
+/// [C++]   'for' '(' for-init-statement condition[opt] ';' expression[opt] ')'
+/// [C++]       statement
+/// [OBJC2] 'for' '(' declaration 'in' expr ')' statement
+/// [OBJC2] 'for' '(' expr 'in' expr ')' statement
+///
+/// [C++] for-init-statement:
+/// [C++]   expression-statement
+/// [C++]   simple-declaration
+///
+Parser::OwningStmtResult Parser::ParseForStatement(AttributeList *Attr) {
+  // FIXME: Use attributes?
+  delete Attr;
+
+  assert(Tok.is(tok::kw_for) && "Not a for stmt!");
+  SourceLocation ForLoc = ConsumeToken();  // eat the 'for'.
+
+  if (Tok.isNot(tok::l_paren)) {
+    Diag(Tok, diag::err_expected_lparen_after) << "for";
+    SkipUntil(tok::semi);
+    return StmtError();
+  }
+
+  bool C99orCXXorObjC = getLang().C99 || getLang().CPlusPlus || getLang().ObjC1;
+
+  // C99 6.8.5p5 - In C99, the for statement is a block.  This is not
+  // the case for C90.  Start the loop scope.
+  //
+  // C++ 6.4p3:
+  // A name introduced by a declaration in a condition is in scope from its
+  // point of declaration until the end of the substatements controlled by the
+  // condition.
+  // C++ 3.3.2p4:
+  // Names declared in the for-init-statement, and in the condition of if,
+  // while, for, and switch statements are local to the if, while, for, or
+  // switch statement (including the controlled statement).
+  // C++ 6.5.3p1:
+  // Names declared in the for-init-statement are in the same declarative-region
+  // as those declared in the condition.
+  //
+  unsigned ScopeFlags;
+  if (C99orCXXorObjC)
+    ScopeFlags = Scope::BreakScope | Scope::ContinueScope |
+                 Scope::DeclScope  | Scope::ControlScope;
+  else
+    ScopeFlags = Scope::BreakScope | Scope::ContinueScope;
+
+  ParseScope ForScope(this, ScopeFlags);
+
+  SourceLocation LParenLoc = ConsumeParen();
+  OwningExprResult Value(Actions);
+
+  bool ForEach = false;
+  OwningStmtResult FirstPart(Actions);
+  OwningExprResult SecondPart(Actions), ThirdPart(Actions);
+  DeclPtrTy SecondVar;
+  
+  if (Tok.is(tok::code_completion)) {
+    Actions.CodeCompleteOrdinaryName(CurScope, 
+                                     C99orCXXorObjC? Action::CCC_ForInit
+                                                   : Action::CCC_Expression);
+    ConsumeToken();
+  }
+  
+  // Parse the first part of the for specifier.
+  if (Tok.is(tok::semi)) {  // for (;
+    // no first part, eat the ';'.
+    ConsumeToken();
+  } else if (isSimpleDeclaration()) {  // for (int X = 4;
+    // Parse declaration, which eats the ';'.
+    if (!C99orCXXorObjC)   // Use of C99-style for loops in C90 mode?
+      Diag(Tok, diag::ext_c99_variable_decl_in_for_loop);
+
+    AttributeList *AttrList = 0;
+    if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier())
+      AttrList = ParseCXX0XAttributes().AttrList;
+
+    SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
+    DeclGroupPtrTy DG = ParseSimpleDeclaration(Declarator::ForContext, DeclEnd,
+                                               AttrList, false);
+    FirstPart = Actions.ActOnDeclStmt(DG, DeclStart, Tok.getLocation());
+
+    if (Tok.is(tok::semi)) {  // for (int x = 4;
+      ConsumeToken();
+    } else if ((ForEach = isTokIdentifier_in())) {
+      Actions.ActOnForEachDeclStmt(DG);
+      // ObjC: for (id x in expr)
+      ConsumeToken(); // consume 'in'
+      SecondPart = ParseExpression();
+    } else {
+      Diag(Tok, diag::err_expected_semi_for);
+      SkipUntil(tok::semi);
+    }
+  } else {
+    Value = ParseExpression();
+
+    // Turn the expression into a stmt.
+    if (!Value.isInvalid())
+      FirstPart = Actions.ActOnExprStmt(Actions.MakeFullExpr(Value));
+
+    if (Tok.is(tok::semi)) {
+      ConsumeToken();
+    } else if ((ForEach = isTokIdentifier_in())) {
+      ConsumeToken(); // consume 'in'
+      SecondPart = ParseExpression();
+    } else {
+      if (!Value.isInvalid()) Diag(Tok, diag::err_expected_semi_for);
+      SkipUntil(tok::semi);
+    }
+  }
+  if (!ForEach) {
+    assert(!SecondPart.get() && "Shouldn't have a second expression yet.");
+    // Parse the second part of the for specifier.
+    if (Tok.is(tok::semi)) {  // for (...;;
+      // no second part.
+    } else {
+      if (getLang().CPlusPlus)
+        ParseCXXCondition(SecondPart, SecondVar);
+      else
+        SecondPart = ParseExpression();
+    }
+
+    if (Tok.is(tok::semi)) {
+      ConsumeToken();
+    } else {
+      if (!SecondPart.isInvalid() || SecondVar.get()) 
+        Diag(Tok, diag::err_expected_semi_for);
+      SkipUntil(tok::semi);
+    }
+
+    // Parse the third part of the for specifier.
+    if (Tok.isNot(tok::r_paren))    // for (...;...;)
+      ThirdPart = ParseExpression();
+  }
+  // Match the ')'.
+  SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
+
+  // C99 6.8.5p5 - In C99, the body of the if statement is a scope, even if
+  // there is no compound stmt.  C90 does not have this clause.  We only do this
+  // if the body isn't a compound statement to avoid push/pop in common cases.
+  //
+  // C++ 6.5p2:
+  // The substatement in an iteration-statement implicitly defines a local scope
+  // which is entered and exited each time through the loop.
+  //
+  // See comments in ParseIfStatement for why we create a scope for
+  // for-init-statement/condition and a new scope for substatement in C++.
+  //
+  ParseScope InnerScope(this, Scope::DeclScope,
+                        C99orCXXorObjC && Tok.isNot(tok::l_brace));
+
+  // Read the body statement.
+  OwningStmtResult Body(ParseStatement());
+
+  // Pop the body scope if needed.
+  InnerScope.Exit();
+
+  // Leave the for-scope.
+  ForScope.Exit();
+
+  if (Body.isInvalid())
+    return StmtError();
+
+  if (!ForEach)
+    return Actions.ActOnForStmt(ForLoc, LParenLoc, move(FirstPart),
+                                Actions.MakeFullExpr(SecondPart), SecondVar,
+                                Actions.MakeFullExpr(ThirdPart), RParenLoc, 
+                                move(Body));
+
+  return Actions.ActOnObjCForCollectionStmt(ForLoc, LParenLoc,
+                                            move(FirstPart),
+                                            move(SecondPart),
+                                            RParenLoc, move(Body));
+}
+
+/// ParseGotoStatement
+///       jump-statement:
+///         'goto' identifier ';'
+/// [GNU]   'goto' '*' expression ';'
+///
+/// Note: this lets the caller parse the end ';'.
+///
+Parser::OwningStmtResult Parser::ParseGotoStatement(AttributeList *Attr) {
+  // FIXME: Use attributes?
+  delete Attr;
+
+  assert(Tok.is(tok::kw_goto) && "Not a goto stmt!");
+  SourceLocation GotoLoc = ConsumeToken();  // eat the 'goto'.
+
+  OwningStmtResult Res(Actions);
+  if (Tok.is(tok::identifier)) {
+    Res = Actions.ActOnGotoStmt(GotoLoc, Tok.getLocation(),
+                                Tok.getIdentifierInfo());
+    ConsumeToken();
+  } else if (Tok.is(tok::star)) {
+    // GNU indirect goto extension.
+    Diag(Tok, diag::ext_gnu_indirect_goto);
+    SourceLocation StarLoc = ConsumeToken();
+    OwningExprResult R(ParseExpression());
+    if (R.isInvalid()) {  // Skip to the semicolon, but don't consume it.
+      SkipUntil(tok::semi, false, true);
+      return StmtError();
+    }
+    Res = Actions.ActOnIndirectGotoStmt(GotoLoc, StarLoc, move(R));
+  } else {
+    Diag(Tok, diag::err_expected_ident);
+    return StmtError();
+  }
+
+  return move(Res);
+}
+
+/// ParseContinueStatement
+///       jump-statement:
+///         'continue' ';'
+///
+/// Note: this lets the caller parse the end ';'.
+///
+Parser::OwningStmtResult Parser::ParseContinueStatement(AttributeList *Attr) {
+  // FIXME: Use attributes?
+  delete Attr;
+
+  SourceLocation ContinueLoc = ConsumeToken();  // eat the 'continue'.
+  return Actions.ActOnContinueStmt(ContinueLoc, CurScope);
+}
+
+/// ParseBreakStatement
+///       jump-statement:
+///         'break' ';'
+///
+/// Note: this lets the caller parse the end ';'.
+///
+Parser::OwningStmtResult Parser::ParseBreakStatement(AttributeList *Attr) {
+  // FIXME: Use attributes?
+  delete Attr;
+
+  SourceLocation BreakLoc = ConsumeToken();  // eat the 'break'.
+  return Actions.ActOnBreakStmt(BreakLoc, CurScope);
+}
+
+/// ParseReturnStatement
+///       jump-statement:
+///         'return' expression[opt] ';'
+Parser::OwningStmtResult Parser::ParseReturnStatement(AttributeList *Attr) {
+  // FIXME: Use attributes?
+  delete Attr;
+
+  assert(Tok.is(tok::kw_return) && "Not a return stmt!");
+  SourceLocation ReturnLoc = ConsumeToken();  // eat the 'return'.
+
+  OwningExprResult R(Actions);
+  if (Tok.isNot(tok::semi)) {
+    R = ParseExpression();
+    if (R.isInvalid()) {  // Skip to the semicolon, but don't consume it.
+      SkipUntil(tok::semi, false, true);
+      return StmtError();
+    }
+  }
+  return Actions.ActOnReturnStmt(ReturnLoc, move(R));
+}
+
+/// FuzzyParseMicrosoftAsmStatement. When -fms-extensions is enabled, this
+/// routine is called to skip/ignore tokens that comprise the MS asm statement.
+Parser::OwningStmtResult Parser::FuzzyParseMicrosoftAsmStatement() {
+  if (Tok.is(tok::l_brace)) {
+    unsigned short savedBraceCount = BraceCount;
+    do {
+      ConsumeAnyToken();
+    } while (BraceCount > savedBraceCount && Tok.isNot(tok::eof));
+  } else {
+    // From the MS website: If used without braces, the __asm keyword means
+    // that the rest of the line is an assembly-language statement.
+    SourceManager &SrcMgr = PP.getSourceManager();
+    SourceLocation TokLoc = Tok.getLocation();
+    unsigned LineNo = SrcMgr.getInstantiationLineNumber(TokLoc);
+    do {
+      ConsumeAnyToken();
+      TokLoc = Tok.getLocation();
+    } while ((SrcMgr.getInstantiationLineNumber(TokLoc) == LineNo) &&
+             Tok.isNot(tok::r_brace) && Tok.isNot(tok::semi) &&
+             Tok.isNot(tok::eof));
+  }
+  Token t;
+  t.setKind(tok::string_literal);
+  t.setLiteralData("\"FIXME: not done\"");
+  t.clearFlag(Token::NeedsCleaning);
+  t.setLength(17);
+  OwningExprResult AsmString(Actions.ActOnStringLiteral(&t, 1));
+  ExprVector Constraints(Actions);
+  ExprVector Exprs(Actions);
+  ExprVector Clobbers(Actions);
+  return Actions.ActOnAsmStmt(Tok.getLocation(), true, true, 0, 0, 0,
+                              move_arg(Constraints), move_arg(Exprs),
+                              move(AsmString), move_arg(Clobbers),
+                              Tok.getLocation(), true);
+}
+
+/// ParseAsmStatement - Parse a GNU extended asm statement.
+///       asm-statement:
+///         gnu-asm-statement
+///         ms-asm-statement
+///
+/// [GNU] gnu-asm-statement:
+///         'asm' type-qualifier[opt] '(' asm-argument ')' ';'
+///
+/// [GNU] asm-argument:
+///         asm-string-literal
+///         asm-string-literal ':' asm-operands[opt]
+///         asm-string-literal ':' asm-operands[opt] ':' asm-operands[opt]
+///         asm-string-literal ':' asm-operands[opt] ':' asm-operands[opt]
+///                 ':' asm-clobbers
+///
+/// [GNU] asm-clobbers:
+///         asm-string-literal
+///         asm-clobbers ',' asm-string-literal
+///
+/// [MS]  ms-asm-statement:
+///         '__asm' assembly-instruction ';'[opt]
+///         '__asm' '{' assembly-instruction-list '}' ';'[opt]
+///
+/// [MS]  assembly-instruction-list:
+///         assembly-instruction ';'[opt]
+///         assembly-instruction-list ';' assembly-instruction ';'[opt]
+///
+Parser::OwningStmtResult Parser::ParseAsmStatement(bool &msAsm) {
+  assert(Tok.is(tok::kw_asm) && "Not an asm stmt");
+  SourceLocation AsmLoc = ConsumeToken();
+
+  if (getLang().Microsoft && Tok.isNot(tok::l_paren) && !isTypeQualifier()) {
+    msAsm = true;
+    return FuzzyParseMicrosoftAsmStatement();
+  }
+  DeclSpec DS;
+  SourceLocation Loc = Tok.getLocation();
+  ParseTypeQualifierListOpt(DS, true, false);
+
+  // GNU asms accept, but warn, about type-qualifiers other than volatile.
+  if (DS.getTypeQualifiers() & DeclSpec::TQ_const)
+    Diag(Loc, diag::w_asm_qualifier_ignored) << "const";
+  if (DS.getTypeQualifiers() & DeclSpec::TQ_restrict)
+    Diag(Loc, diag::w_asm_qualifier_ignored) << "restrict";
+
+  // Remember if this was a volatile asm.
+  bool isVolatile = DS.getTypeQualifiers() & DeclSpec::TQ_volatile;
+  if (Tok.isNot(tok::l_paren)) {
+    Diag(Tok, diag::err_expected_lparen_after) << "asm";
+    SkipUntil(tok::r_paren);
+    return StmtError();
+  }
+  Loc = ConsumeParen();
+
+  OwningExprResult AsmString(ParseAsmStringLiteral());
+  if (AsmString.isInvalid())
+    return StmtError();
+
+  llvm::SmallVector<IdentifierInfo *, 4> Names;
+  ExprVector Constraints(Actions);
+  ExprVector Exprs(Actions);
+  ExprVector Clobbers(Actions);
+
+  if (Tok.is(tok::r_paren)) {
+    // We have a simple asm expression like 'asm("foo")'.
+    SourceLocation RParenLoc = ConsumeParen();
+    return Actions.ActOnAsmStmt(AsmLoc, /*isSimple*/ true, isVolatile,
+                                /*NumOutputs*/ 0, /*NumInputs*/ 0, 0, 
+                                move_arg(Constraints), move_arg(Exprs),
+                                move(AsmString), move_arg(Clobbers),
+                                RParenLoc);
+  }
+
+  // Parse Outputs, if present.
+  bool AteExtraColon = false;
+  if (Tok.is(tok::colon) || Tok.is(tok::coloncolon)) {
+    // In C++ mode, parse "::" like ": :".
+    AteExtraColon = Tok.is(tok::coloncolon);
+    ConsumeToken();
+  
+    if (!AteExtraColon &&
+        ParseAsmOperandsOpt(Names, Constraints, Exprs))
+      return StmtError();
+  }
+  
+  unsigned NumOutputs = Names.size();
+
+  // Parse Inputs, if present.
+  if (AteExtraColon ||
+      Tok.is(tok::colon) || Tok.is(tok::coloncolon)) {
+    // In C++ mode, parse "::" like ": :".
+    if (AteExtraColon)
+      AteExtraColon = false;
+    else {
+      AteExtraColon = Tok.is(tok::coloncolon);
+      ConsumeToken();
+    }
+    
+    if (!AteExtraColon &&
+        ParseAsmOperandsOpt(Names, Constraints, Exprs))
+      return StmtError();
+  }
+
+  assert(Names.size() == Constraints.size() &&
+         Constraints.size() == Exprs.size() &&
+         "Input operand size mismatch!");
+
+  unsigned NumInputs = Names.size() - NumOutputs;
+
+  // Parse the clobbers, if present.
+  if (AteExtraColon || Tok.is(tok::colon)) {
+    if (!AteExtraColon)
+      ConsumeToken();
+
+    // Parse the asm-string list for clobbers.
+    while (1) {
+      OwningExprResult Clobber(ParseAsmStringLiteral());
+
+      if (Clobber.isInvalid())
+        break;
+
+      Clobbers.push_back(Clobber.release());
+
+      if (Tok.isNot(tok::comma)) break;
+      ConsumeToken();
+    }
+  }
+
+  SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, Loc);
+  return Actions.ActOnAsmStmt(AsmLoc, false, isVolatile,
+                              NumOutputs, NumInputs, Names.data(),
+                              move_arg(Constraints), move_arg(Exprs),
+                              move(AsmString), move_arg(Clobbers),
+                              RParenLoc);
+}
+
+/// ParseAsmOperands - Parse the asm-operands production as used by
+/// asm-statement, assuming the leading ':' token was eaten.
+///
+/// [GNU] asm-operands:
+///         asm-operand
+///         asm-operands ',' asm-operand
+///
+/// [GNU] asm-operand:
+///         asm-string-literal '(' expression ')'
+///         '[' identifier ']' asm-string-literal '(' expression ')'
+///
+//
+// FIXME: Avoid unnecessary std::string trashing.
+bool Parser::ParseAsmOperandsOpt(llvm::SmallVectorImpl<IdentifierInfo *> &Names,
+                                 llvm::SmallVectorImpl<ExprTy *> &Constraints,
+                                 llvm::SmallVectorImpl<ExprTy *> &Exprs) {
+  // 'asm-operands' isn't present?
+  if (!isTokenStringLiteral() && Tok.isNot(tok::l_square))
+    return false;
+
+  while (1) {
+    // Read the [id] if present.
+    if (Tok.is(tok::l_square)) {
+      SourceLocation Loc = ConsumeBracket();
+
+      if (Tok.isNot(tok::identifier)) {
+        Diag(Tok, diag::err_expected_ident);
+        SkipUntil(tok::r_paren);
+        return true;
+      }
+
+      IdentifierInfo *II = Tok.getIdentifierInfo();
+      ConsumeToken();
+
+      Names.push_back(II);
+      MatchRHSPunctuation(tok::r_square, Loc);
+    } else
+      Names.push_back(0);
+
+    OwningExprResult Constraint(ParseAsmStringLiteral());
+    if (Constraint.isInvalid()) {
+        SkipUntil(tok::r_paren);
+        return true;
+    }
+    Constraints.push_back(Constraint.release());
+
+    if (Tok.isNot(tok::l_paren)) {
+      Diag(Tok, diag::err_expected_lparen_after) << "asm operand";
+      SkipUntil(tok::r_paren);
+      return true;
+    }
+
+    // Read the parenthesized expression.
+    SourceLocation OpenLoc = ConsumeParen();
+    OwningExprResult Res(ParseExpression());
+    MatchRHSPunctuation(tok::r_paren, OpenLoc);
+    if (Res.isInvalid()) {
+      SkipUntil(tok::r_paren);
+      return true;
+    }
+    Exprs.push_back(Res.release());
+    // Eat the comma and continue parsing if it exists.
+    if (Tok.isNot(tok::comma)) return false;
+    ConsumeToken();
+  }
+
+  return true;
+}
+
+Parser::DeclPtrTy Parser::ParseFunctionStatementBody(DeclPtrTy Decl) {
+  assert(Tok.is(tok::l_brace));
+  SourceLocation LBraceLoc = Tok.getLocation();
+
+  PrettyStackTraceActionsDecl CrashInfo(Decl, LBraceLoc, Actions,
+                                        PP.getSourceManager(),
+                                        "parsing function body");
+
+  // Do not enter a scope for the brace, as the arguments are in the same scope
+  // (the function body) as the body itself.  Instead, just read the statement
+  // list and put it into a CompoundStmt for safe keeping.
+  OwningStmtResult FnBody(ParseCompoundStatementBody());
+
+  // If the function body could not be parsed, make a bogus compoundstmt.
+  if (FnBody.isInvalid())
+    FnBody = Actions.ActOnCompoundStmt(LBraceLoc, LBraceLoc,
+                                       MultiStmtArg(Actions), false);
+
+  return Actions.ActOnFinishFunctionBody(Decl, move(FnBody));
+}
+
+/// ParseFunctionTryBlock - Parse a C++ function-try-block.
+///
+///       function-try-block:
+///         'try' ctor-initializer[opt] compound-statement handler-seq
+///
+Parser::DeclPtrTy Parser::ParseFunctionTryBlock(DeclPtrTy Decl) {
+  assert(Tok.is(tok::kw_try) && "Expected 'try'");
+  SourceLocation TryLoc = ConsumeToken();
+
+  PrettyStackTraceActionsDecl CrashInfo(Decl, TryLoc, Actions,
+                                        PP.getSourceManager(),
+                                        "parsing function try block");
+
+  // Constructor initializer list?
+  if (Tok.is(tok::colon))
+    ParseConstructorInitializer(Decl);
+
+  SourceLocation LBraceLoc = Tok.getLocation();
+  OwningStmtResult FnBody(ParseCXXTryBlockCommon(TryLoc));
+  // If we failed to parse the try-catch, we just give the function an empty
+  // compound statement as the body.
+  if (FnBody.isInvalid())
+    FnBody = Actions.ActOnCompoundStmt(LBraceLoc, LBraceLoc,
+                                       MultiStmtArg(Actions), false);
+
+  return Actions.ActOnFinishFunctionBody(Decl, move(FnBody));
+}
+
+/// ParseCXXTryBlock - Parse a C++ try-block.
+///
+///       try-block:
+///         'try' compound-statement handler-seq
+///
+Parser::OwningStmtResult Parser::ParseCXXTryBlock(AttributeList* Attr) {
+  // FIXME: Add attributes?
+  delete Attr;
+
+  assert(Tok.is(tok::kw_try) && "Expected 'try'");
+
+  SourceLocation TryLoc = ConsumeToken();
+  return ParseCXXTryBlockCommon(TryLoc);
+}
+
+/// ParseCXXTryBlockCommon - Parse the common part of try-block and
+/// function-try-block.
+///
+///       try-block:
+///         'try' compound-statement handler-seq
+///
+///       function-try-block:
+///         'try' ctor-initializer[opt] compound-statement handler-seq
+///
+///       handler-seq:
+///         handler handler-seq[opt]
+///
+Parser::OwningStmtResult Parser::ParseCXXTryBlockCommon(SourceLocation TryLoc) {
+  if (Tok.isNot(tok::l_brace))
+    return StmtError(Diag(Tok, diag::err_expected_lbrace));
+  // FIXME: Possible draft standard bug: attribute-specifier should be allowed?
+  OwningStmtResult TryBlock(ParseCompoundStatement(0));
+  if (TryBlock.isInvalid())
+    return move(TryBlock);
+
+  StmtVector Handlers(Actions);
+  if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier()) {
+    CXX0XAttributeList Attr = ParseCXX0XAttributes();
+    Diag(Attr.Range.getBegin(), diag::err_attributes_not_allowed)
+      << Attr.Range;
+  }
+  if (Tok.isNot(tok::kw_catch))
+    return StmtError(Diag(Tok, diag::err_expected_catch));
+  while (Tok.is(tok::kw_catch)) {
+    OwningStmtResult Handler(ParseCXXCatchBlock());
+    if (!Handler.isInvalid())
+      Handlers.push_back(Handler.release());
+  }
+  // Don't bother creating the full statement if we don't have any usable
+  // handlers.
+  if (Handlers.empty())
+    return StmtError();
+
+  return Actions.ActOnCXXTryBlock(TryLoc, move(TryBlock), move_arg(Handlers));
+}
+
+/// ParseCXXCatchBlock - Parse a C++ catch block, called handler in the standard
+///
+///       handler:
+///         'catch' '(' exception-declaration ')' compound-statement
+///
+///       exception-declaration:
+///         type-specifier-seq declarator
+///         type-specifier-seq abstract-declarator
+///         type-specifier-seq
+///         '...'
+///
+Parser::OwningStmtResult Parser::ParseCXXCatchBlock() {
+  assert(Tok.is(tok::kw_catch) && "Expected 'catch'");
+
+  SourceLocation CatchLoc = ConsumeToken();
+
+  SourceLocation LParenLoc = Tok.getLocation();
+  if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen))
+    return StmtError();
+
+  // C++ 3.3.2p3:
+  // The name in a catch exception-declaration is local to the handler and
+  // shall not be redeclared in the outermost block of the handler.
+  ParseScope CatchScope(this, Scope::DeclScope | Scope::ControlScope);
+
+  // exception-declaration is equivalent to '...' or a parameter-declaration
+  // without default arguments.
+  DeclPtrTy ExceptionDecl;
+  if (Tok.isNot(tok::ellipsis)) {
+    DeclSpec DS;
+    if (ParseCXXTypeSpecifierSeq(DS))
+      return StmtError();
+    Declarator ExDecl(DS, Declarator::CXXCatchContext);
+    ParseDeclarator(ExDecl);
+    ExceptionDecl = Actions.ActOnExceptionDeclarator(CurScope, ExDecl);
+  } else
+    ConsumeToken();
+
+  if (MatchRHSPunctuation(tok::r_paren, LParenLoc).isInvalid())
+    return StmtError();
+
+  if (Tok.isNot(tok::l_brace))
+    return StmtError(Diag(Tok, diag::err_expected_lbrace));
+
+  // FIXME: Possible draft standard bug: attribute-specifier should be allowed?
+  OwningStmtResult Block(ParseCompoundStatement(0));
+  if (Block.isInvalid())
+    return move(Block);
+
+  return Actions.ActOnCXXCatchBlock(CatchLoc, ExceptionDecl, move(Block));
+}
diff --git a/lib/Parse/ParseTemplate.cpp b/lib/Parse/ParseTemplate.cpp
new file mode 100644
index 0000000..ff69953
--- /dev/null
+++ b/lib/Parse/ParseTemplate.cpp
@@ -0,0 +1,1013 @@
+//===--- ParseTemplate.cpp - Template Parsing -----------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements parsing of C++ templates.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Parse/Parser.h"
+#include "clang/Parse/ParseDiagnostic.h"
+#include "clang/Parse/DeclSpec.h"
+#include "clang/Parse/Scope.h"
+#include "clang/Parse/Template.h"
+#include "RAIIObjectsForParser.h"
+using namespace clang;
+
+/// \brief Parse a template declaration, explicit instantiation, or
+/// explicit specialization.
+Parser::DeclPtrTy
+Parser::ParseDeclarationStartingWithTemplate(unsigned Context,
+                                             SourceLocation &DeclEnd,
+                                             AccessSpecifier AS) {
+  if (Tok.is(tok::kw_template) && NextToken().isNot(tok::less))
+    return ParseExplicitInstantiation(SourceLocation(), ConsumeToken(),
+                                      DeclEnd);
+
+  return ParseTemplateDeclarationOrSpecialization(Context, DeclEnd, AS);
+}
+
+/// \brief RAII class that manages the template parameter depth.
+namespace {
+  class TemplateParameterDepthCounter {
+    unsigned &Depth;
+    unsigned AddedLevels;
+
+  public:
+    explicit TemplateParameterDepthCounter(unsigned &Depth)
+      : Depth(Depth), AddedLevels(0) { }
+
+    ~TemplateParameterDepthCounter() {
+      Depth -= AddedLevels;
+    }
+
+    void operator++() {
+      ++Depth;
+      ++AddedLevels;
+    }
+
+    operator unsigned() const { return Depth; }
+  };
+}
+
+/// \brief Parse a template declaration or an explicit specialization.
+///
+/// Template declarations include one or more template parameter lists
+/// and either the function or class template declaration. Explicit
+/// specializations contain one or more 'template < >' prefixes
+/// followed by a (possibly templated) declaration. Since the
+/// syntactic form of both features is nearly identical, we parse all
+/// of the template headers together and let semantic analysis sort
+/// the declarations from the explicit specializations.
+///
+///       template-declaration: [C++ temp]
+///         'export'[opt] 'template' '<' template-parameter-list '>' declaration
+///
+///       explicit-specialization: [ C++ temp.expl.spec]
+///         'template' '<' '>' declaration
+Parser::DeclPtrTy
+Parser::ParseTemplateDeclarationOrSpecialization(unsigned Context,
+                                                 SourceLocation &DeclEnd,
+                                                 AccessSpecifier AS) {
+  assert((Tok.is(tok::kw_export) || Tok.is(tok::kw_template)) &&
+         "Token does not start a template declaration.");
+
+  // Enter template-parameter scope.
+  ParseScope TemplateParmScope(this, Scope::TemplateParamScope);
+
+  // Parse multiple levels of template headers within this template
+  // parameter scope, e.g.,
+  //
+  //   template<typename T>
+  //     template<typename U>
+  //       class A<T>::B { ... };
+  //
+  // We parse multiple levels non-recursively so that we can build a
+  // single data structure containing all of the template parameter
+  // lists to easily differentiate between the case above and:
+  //
+  //   template<typename T>
+  //   class A {
+  //     template<typename U> class B;
+  //   };
+  //
+  // In the first case, the action for declaring A<T>::B receives
+  // both template parameter lists. In the second case, the action for
+  // defining A<T>::B receives just the inner template parameter list
+  // (and retrieves the outer template parameter list from its
+  // context).
+  bool isSpecialization = true;
+  bool LastParamListWasEmpty = false;
+  TemplateParameterLists ParamLists;
+  TemplateParameterDepthCounter Depth(TemplateParameterDepth);
+  do {
+    // Consume the 'export', if any.
+    SourceLocation ExportLoc;
+    if (Tok.is(tok::kw_export)) {
+      ExportLoc = ConsumeToken();
+    }
+
+    // Consume the 'template', which should be here.
+    SourceLocation TemplateLoc;
+    if (Tok.is(tok::kw_template)) {
+      TemplateLoc = ConsumeToken();
+    } else {
+      Diag(Tok.getLocation(), diag::err_expected_template);
+      return DeclPtrTy();
+    }
+
+    // Parse the '<' template-parameter-list '>'
+    SourceLocation LAngleLoc, RAngleLoc;
+    TemplateParameterList TemplateParams;
+    if (ParseTemplateParameters(Depth, TemplateParams, LAngleLoc,
+                                RAngleLoc)) {
+      // Skip until the semi-colon or a }.
+      SkipUntil(tok::r_brace, true, true);
+      if (Tok.is(tok::semi))
+        ConsumeToken();
+      return DeclPtrTy();
+    }
+
+    ParamLists.push_back(
+      Actions.ActOnTemplateParameterList(Depth, ExportLoc,
+                                         TemplateLoc, LAngleLoc,
+                                         TemplateParams.data(),
+                                         TemplateParams.size(), RAngleLoc));
+
+    if (!TemplateParams.empty()) {
+      isSpecialization = false;
+      ++Depth;
+    } else {
+      LastParamListWasEmpty = true;
+    }
+  } while (Tok.is(tok::kw_export) || Tok.is(tok::kw_template));
+
+  // Parse the actual template declaration.
+  return ParseSingleDeclarationAfterTemplate(Context,
+                                             ParsedTemplateInfo(&ParamLists,
+                                                             isSpecialization,
+                                                         LastParamListWasEmpty),
+                                             DeclEnd, AS);
+}
+
+/// \brief Parse a single declaration that declares a template,
+/// template specialization, or explicit instantiation of a template.
+///
+/// \param TemplateParams if non-NULL, the template parameter lists
+/// that preceded this declaration. In this case, the declaration is a
+/// template declaration, out-of-line definition of a template, or an
+/// explicit template specialization. When NULL, the declaration is an
+/// explicit template instantiation.
+///
+/// \param TemplateLoc when TemplateParams is NULL, the location of
+/// the 'template' keyword that indicates that we have an explicit
+/// template instantiation.
+///
+/// \param DeclEnd will receive the source location of the last token
+/// within this declaration.
+///
+/// \param AS the access specifier associated with this
+/// declaration. Will be AS_none for namespace-scope declarations.
+///
+/// \returns the new declaration.
+Parser::DeclPtrTy
+Parser::ParseSingleDeclarationAfterTemplate(
+                                       unsigned Context,
+                                       const ParsedTemplateInfo &TemplateInfo,
+                                       SourceLocation &DeclEnd,
+                                       AccessSpecifier AS) {
+  assert(TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate &&
+         "Template information required");
+
+  if (Context == Declarator::MemberContext) {
+    // We are parsing a member template.
+    ParseCXXClassMemberDeclaration(AS, TemplateInfo);
+    return DeclPtrTy::make((void*)0);
+  }
+
+  // Parse the declaration specifiers.
+  ParsingDeclSpec DS(*this);
+
+  if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier())
+    DS.AddAttributes(ParseCXX0XAttributes().AttrList);
+
+  ParseDeclarationSpecifiers(DS, TemplateInfo, AS,
+                             getDeclSpecContextFromDeclaratorContext(Context));
+
+  if (Tok.is(tok::semi)) {
+    DeclEnd = ConsumeToken();
+    DeclPtrTy Decl = Actions.ParsedFreeStandingDeclSpec(CurScope, DS);
+    DS.complete(Decl);
+    return Decl;
+  }
+
+  // Parse the declarator.
+  ParsingDeclarator DeclaratorInfo(*this, DS, (Declarator::TheContext)Context);
+  ParseDeclarator(DeclaratorInfo);
+  // Error parsing the declarator?
+  if (!DeclaratorInfo.hasName()) {
+    // If so, skip until the semi-colon or a }.
+    SkipUntil(tok::r_brace, true, true);
+    if (Tok.is(tok::semi))
+      ConsumeToken();
+    return DeclPtrTy();
+  }
+
+  // If we have a declaration or declarator list, handle it.
+  if (isDeclarationAfterDeclarator()) {
+    // Parse this declaration.
+    DeclPtrTy ThisDecl = ParseDeclarationAfterDeclarator(DeclaratorInfo,
+                                                         TemplateInfo);
+
+    if (Tok.is(tok::comma)) {
+      Diag(Tok, diag::err_multiple_template_declarators)
+        << (int)TemplateInfo.Kind;
+      SkipUntil(tok::semi, true, false);
+      return ThisDecl;
+    }
+
+    // Eat the semi colon after the declaration.
+    ExpectAndConsume(tok::semi, diag::err_expected_semi_declaration);
+    DS.complete(ThisDecl);
+    return ThisDecl;
+  }
+
+  if (DeclaratorInfo.isFunctionDeclarator() &&
+      isStartOfFunctionDefinition()) {
+    if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) {
+      Diag(Tok, diag::err_function_declared_typedef);
+
+      if (Tok.is(tok::l_brace)) {
+        // This recovery skips the entire function body. It would be nice
+        // to simply call ParseFunctionDefinition() below, however Sema
+        // assumes the declarator represents a function, not a typedef.
+        ConsumeBrace();
+        SkipUntil(tok::r_brace, true);
+      } else {
+        SkipUntil(tok::semi);
+      }
+      return DeclPtrTy();
+    }
+    return ParseFunctionDefinition(DeclaratorInfo, TemplateInfo);
+  }
+
+  if (DeclaratorInfo.isFunctionDeclarator())
+    Diag(Tok, diag::err_expected_fn_body);
+  else
+    Diag(Tok, diag::err_invalid_token_after_toplevel_declarator);
+  SkipUntil(tok::semi);
+  return DeclPtrTy();
+}
+
+/// ParseTemplateParameters - Parses a template-parameter-list enclosed in
+/// angle brackets. Depth is the depth of this template-parameter-list, which
+/// is the number of template headers directly enclosing this template header.
+/// TemplateParams is the current list of template parameters we're building.
+/// The template parameter we parse will be added to this list. LAngleLoc and
+/// RAngleLoc will receive the positions of the '<' and '>', respectively,
+/// that enclose this template parameter list.
+///
+/// \returns true if an error occurred, false otherwise.
+bool Parser::ParseTemplateParameters(unsigned Depth,
+                                     TemplateParameterList &TemplateParams,
+                                     SourceLocation &LAngleLoc,
+                                     SourceLocation &RAngleLoc) {
+  // Get the template parameter list.
+  if (!Tok.is(tok::less)) {
+    Diag(Tok.getLocation(), diag::err_expected_less_after) << "template";
+    return true;
+  }
+  LAngleLoc = ConsumeToken();
+
+  // Try to parse the template parameter list.
+  if (Tok.is(tok::greater))
+    RAngleLoc = ConsumeToken();
+  else if (ParseTemplateParameterList(Depth, TemplateParams)) {
+    if (!Tok.is(tok::greater)) {
+      Diag(Tok.getLocation(), diag::err_expected_greater);
+      return true;
+    }
+    RAngleLoc = ConsumeToken();
+  }
+  return false;
+}
+
+/// ParseTemplateParameterList - Parse a template parameter list. If
+/// the parsing fails badly (i.e., closing bracket was left out), this
+/// will try to put the token stream in a reasonable position (closing
+/// a statement, etc.) and return false.
+///
+///       template-parameter-list:    [C++ temp]
+///         template-parameter
+///         template-parameter-list ',' template-parameter
+bool
+Parser::ParseTemplateParameterList(unsigned Depth,
+                                   TemplateParameterList &TemplateParams) {
+  while (1) {
+    if (DeclPtrTy TmpParam
+          = ParseTemplateParameter(Depth, TemplateParams.size())) {
+      TemplateParams.push_back(TmpParam);
+    } else {
+      // If we failed to parse a template parameter, skip until we find
+      // a comma or closing brace.
+      SkipUntil(tok::comma, tok::greater, true, true);
+    }
+
+    // Did we find a comma or the end of the template parmeter list?
+    if (Tok.is(tok::comma)) {
+      ConsumeToken();
+    } else if (Tok.is(tok::greater)) {
+      // Don't consume this... that's done by template parser.
+      break;
+    } else {
+      // Somebody probably forgot to close the template. Skip ahead and
+      // try to get out of the expression. This error is currently
+      // subsumed by whatever goes on in ParseTemplateParameter.
+      // TODO: This could match >>, and it would be nice to avoid those
+      // silly errors with template <vec<T>>.
+      // Diag(Tok.getLocation(), diag::err_expected_comma_greater);
+      SkipUntil(tok::greater, true, true);
+      return false;
+    }
+  }
+  return true;
+}
+
+/// \brief Determine whether the parser is at the start of a template
+/// type parameter.
+bool Parser::isStartOfTemplateTypeParameter() {
+  if (Tok.is(tok::kw_class))
+    return true;
+
+  if (Tok.isNot(tok::kw_typename))
+    return false;
+
+  // C++ [temp.param]p2:
+  //   There is no semantic difference between class and typename in a
+  //   template-parameter. typename followed by an unqualified-id
+  //   names a template type parameter. typename followed by a
+  //   qualified-id denotes the type in a non-type
+  //   parameter-declaration.
+  Token Next = NextToken();
+
+  // If we have an identifier, skip over it.
+  if (Next.getKind() == tok::identifier)
+    Next = GetLookAheadToken(2);
+
+  switch (Next.getKind()) {
+  case tok::equal:
+  case tok::comma:
+  case tok::greater:
+  case tok::greatergreater:
+  case tok::ellipsis:
+    return true;
+
+  default:
+    return false;
+  }
+}
+
+/// ParseTemplateParameter - Parse a template-parameter (C++ [temp.param]).
+///
+///       template-parameter: [C++ temp.param]
+///         type-parameter
+///         parameter-declaration
+///
+///       type-parameter: (see below)
+///         'class' ...[opt][C++0x] identifier[opt]
+///         'class' identifier[opt] '=' type-id
+///         'typename' ...[opt][C++0x] identifier[opt]
+///         'typename' identifier[opt] '=' type-id
+///         'template' ...[opt][C++0x] '<' template-parameter-list '>' 'class' identifier[opt]
+///         'template' '<' template-parameter-list '>' 'class' identifier[opt] = id-expression
+Parser::DeclPtrTy
+Parser::ParseTemplateParameter(unsigned Depth, unsigned Position) {
+  if (isStartOfTemplateTypeParameter())
+    return ParseTypeParameter(Depth, Position);
+
+  if (Tok.is(tok::kw_template))
+    return ParseTemplateTemplateParameter(Depth, Position);
+
+  // If it's none of the above, then it must be a parameter declaration.
+  // NOTE: This will pick up errors in the closure of the template parameter
+  // list (e.g., template < ; Check here to implement >> style closures.
+  return ParseNonTypeTemplateParameter(Depth, Position);
+}
+
+/// ParseTypeParameter - Parse a template type parameter (C++ [temp.param]).
+/// Other kinds of template parameters are parsed in
+/// ParseTemplateTemplateParameter and ParseNonTypeTemplateParameter.
+///
+///       type-parameter:     [C++ temp.param]
+///         'class' ...[opt][C++0x] identifier[opt]
+///         'class' identifier[opt] '=' type-id
+///         'typename' ...[opt][C++0x] identifier[opt]
+///         'typename' identifier[opt] '=' type-id
+Parser::DeclPtrTy Parser::ParseTypeParameter(unsigned Depth, unsigned Position){
+  assert((Tok.is(tok::kw_class) || Tok.is(tok::kw_typename)) &&
+         "A type-parameter starts with 'class' or 'typename'");
+
+  // Consume the 'class' or 'typename' keyword.
+  bool TypenameKeyword = Tok.is(tok::kw_typename);
+  SourceLocation KeyLoc = ConsumeToken();
+
+  // Grab the ellipsis (if given).
+  bool Ellipsis = false;
+  SourceLocation EllipsisLoc;
+  if (Tok.is(tok::ellipsis)) {
+    Ellipsis = true;
+    EllipsisLoc = ConsumeToken();
+
+    if (!getLang().CPlusPlus0x)
+      Diag(EllipsisLoc, diag::err_variadic_templates);
+  }
+
+  // Grab the template parameter name (if given)
+  SourceLocation NameLoc;
+  IdentifierInfo* ParamName = 0;
+  if (Tok.is(tok::identifier)) {
+    ParamName = Tok.getIdentifierInfo();
+    NameLoc = ConsumeToken();
+  } else if (Tok.is(tok::equal) || Tok.is(tok::comma) ||
+            Tok.is(tok::greater)) {
+    // Unnamed template parameter. Don't have to do anything here, just
+    // don't consume this token.
+  } else {
+    Diag(Tok.getLocation(), diag::err_expected_ident);
+    return DeclPtrTy();
+  }
+
+  DeclPtrTy TypeParam = Actions.ActOnTypeParameter(CurScope, TypenameKeyword,
+                                                   Ellipsis, EllipsisLoc,
+                                                   KeyLoc, ParamName, NameLoc,
+                                                   Depth, Position);
+
+  // Grab a default type id (if given).
+  if (Tok.is(tok::equal)) {
+    SourceLocation EqualLoc = ConsumeToken();
+    SourceLocation DefaultLoc = Tok.getLocation();
+    TypeResult DefaultType = ParseTypeName();
+    if (!DefaultType.isInvalid())
+      Actions.ActOnTypeParameterDefault(TypeParam, EqualLoc, DefaultLoc,
+                                        DefaultType.get());
+  }
+
+  return TypeParam;
+}
+
+/// ParseTemplateTemplateParameter - Handle the parsing of template
+/// template parameters.
+///
+///       type-parameter:    [C++ temp.param]
+///         'template' '<' template-parameter-list '>' 'class' identifier[opt]
+///         'template' '<' template-parameter-list '>' 'class' identifier[opt] = id-expression
+Parser::DeclPtrTy
+Parser::ParseTemplateTemplateParameter(unsigned Depth, unsigned Position) {
+  assert(Tok.is(tok::kw_template) && "Expected 'template' keyword");
+
+  // Handle the template <...> part.
+  SourceLocation TemplateLoc = ConsumeToken();
+  TemplateParameterList TemplateParams;
+  SourceLocation LAngleLoc, RAngleLoc;
+  {
+    ParseScope TemplateParmScope(this, Scope::TemplateParamScope);
+    if (ParseTemplateParameters(Depth + 1, TemplateParams, LAngleLoc,
+                               RAngleLoc)) {
+      return DeclPtrTy();
+    }
+  }
+
+  // Generate a meaningful error if the user forgot to put class before the
+  // identifier, comma, or greater.
+  if (!Tok.is(tok::kw_class)) {
+    Diag(Tok.getLocation(), diag::err_expected_class_before)
+      << PP.getSpelling(Tok);
+    return DeclPtrTy();
+  }
+  SourceLocation ClassLoc = ConsumeToken();
+
+  // Get the identifier, if given.
+  SourceLocation NameLoc;
+  IdentifierInfo* ParamName = 0;
+  if (Tok.is(tok::identifier)) {
+    ParamName = Tok.getIdentifierInfo();
+    NameLoc = ConsumeToken();
+  } else if (Tok.is(tok::equal) || Tok.is(tok::comma) || Tok.is(tok::greater)) {
+    // Unnamed template parameter. Don't have to do anything here, just
+    // don't consume this token.
+  } else {
+    Diag(Tok.getLocation(), diag::err_expected_ident);
+    return DeclPtrTy();
+  }
+
+  TemplateParamsTy *ParamList =
+    Actions.ActOnTemplateParameterList(Depth, SourceLocation(),
+                                       TemplateLoc, LAngleLoc,
+                                       &TemplateParams[0],
+                                       TemplateParams.size(),
+                                       RAngleLoc);
+
+  Parser::DeclPtrTy Param
+    = Actions.ActOnTemplateTemplateParameter(CurScope, TemplateLoc,
+                                             ParamList, ParamName,
+                                             NameLoc, Depth, Position);
+
+  // Get the a default value, if given.
+  if (Tok.is(tok::equal)) {
+    SourceLocation EqualLoc = ConsumeToken();
+    ParsedTemplateArgument Default = ParseTemplateTemplateArgument();
+    if (Default.isInvalid()) {
+      Diag(Tok.getLocation(), 
+           diag::err_default_template_template_parameter_not_template);
+      static const tok::TokenKind EndToks[] = { 
+        tok::comma, tok::greater, tok::greatergreater
+      };
+      SkipUntil(EndToks, 3, true, true);
+      return Param;
+    } else if (Param)
+      Actions.ActOnTemplateTemplateParameterDefault(Param, EqualLoc, Default);
+  }
+
+  return Param;
+}
+
+/// ParseNonTypeTemplateParameter - Handle the parsing of non-type
+/// template parameters (e.g., in "template<int Size> class array;").
+///
+///       template-parameter:
+///         ...
+///         parameter-declaration
+///
+/// NOTE: It would be ideal to simply call out to ParseParameterDeclaration(),
+/// but that didn't work out to well. Instead, this tries to recrate the basic
+/// parsing of parameter declarations, but tries to constrain it for template
+/// parameters.
+/// FIXME: We need to make a ParseParameterDeclaration that works for
+/// non-type template parameters and normal function parameters.
+Parser::DeclPtrTy
+Parser::ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position) {
+  SourceLocation StartLoc = Tok.getLocation();
+
+  // Parse the declaration-specifiers (i.e., the type).
+  // FIXME: The type should probably be restricted in some way... Not all
+  // declarators (parts of declarators?) are accepted for parameters.
+  DeclSpec DS;
+  ParseDeclarationSpecifiers(DS);
+
+  // Parse this as a typename.
+  Declarator ParamDecl(DS, Declarator::TemplateParamContext);
+  ParseDeclarator(ParamDecl);
+  if (DS.getTypeSpecType() == DeclSpec::TST_unspecified && !DS.getTypeRep()) {
+    // This probably shouldn't happen - and it's more of a Sema thing, but
+    // basically we didn't parse the type name because we couldn't associate
+    // it with an AST node. we should just skip to the comma or greater.
+    // TODO: This is currently a placeholder for some kind of Sema Error.
+    Diag(Tok.getLocation(), diag::err_parse_error);
+    SkipUntil(tok::comma, tok::greater, true, true);
+    return DeclPtrTy();
+  }
+
+  // Create the parameter.
+  DeclPtrTy Param = Actions.ActOnNonTypeTemplateParameter(CurScope, ParamDecl,
+                                                          Depth, Position);
+
+  // If there is a default value, parse it.
+  if (Tok.is(tok::equal)) {
+    SourceLocation EqualLoc = ConsumeToken();
+
+    // C++ [temp.param]p15:
+    //   When parsing a default template-argument for a non-type
+    //   template-parameter, the first non-nested > is taken as the
+    //   end of the template-parameter-list rather than a greater-than
+    //   operator.
+    GreaterThanIsOperatorScope G(GreaterThanIsOperator, false);
+
+    OwningExprResult DefaultArg = ParseAssignmentExpression();
+    if (DefaultArg.isInvalid())
+      SkipUntil(tok::comma, tok::greater, true, true);
+    else if (Param)
+      Actions.ActOnNonTypeTemplateParameterDefault(Param, EqualLoc,
+                                                   move(DefaultArg));
+  }
+
+  return Param;
+}
+
+/// \brief Parses a template-id that after the template name has
+/// already been parsed.
+///
+/// This routine takes care of parsing the enclosed template argument
+/// list ('<' template-parameter-list [opt] '>') and placing the
+/// results into a form that can be transferred to semantic analysis.
+///
+/// \param Template the template declaration produced by isTemplateName
+///
+/// \param TemplateNameLoc the source location of the template name
+///
+/// \param SS if non-NULL, the nested-name-specifier preceding the
+/// template name.
+///
+/// \param ConsumeLastToken if true, then we will consume the last
+/// token that forms the template-id. Otherwise, we will leave the
+/// last token in the stream (e.g., so that it can be replaced with an
+/// annotation token).
+bool
+Parser::ParseTemplateIdAfterTemplateName(TemplateTy Template,
+                                         SourceLocation TemplateNameLoc,
+                                         const CXXScopeSpec *SS,
+                                         bool ConsumeLastToken,
+                                         SourceLocation &LAngleLoc,
+                                         TemplateArgList &TemplateArgs,
+                                         SourceLocation &RAngleLoc) {
+  assert(Tok.is(tok::less) && "Must have already parsed the template-name");
+
+  // Consume the '<'.
+  LAngleLoc = ConsumeToken();
+
+  // Parse the optional template-argument-list.
+  bool Invalid = false;
+  {
+    GreaterThanIsOperatorScope G(GreaterThanIsOperator, false);
+    if (Tok.isNot(tok::greater))
+      Invalid = ParseTemplateArgumentList(TemplateArgs);
+
+    if (Invalid) {
+      // Try to find the closing '>'.
+      SkipUntil(tok::greater, true, !ConsumeLastToken);
+
+      return true;
+    }
+  }
+
+  if (Tok.isNot(tok::greater) && Tok.isNot(tok::greatergreater)) {
+    Diag(Tok.getLocation(), diag::err_expected_greater);
+    return true;
+  }
+
+  // Determine the location of the '>' or '>>'. Only consume this
+  // token if the caller asked us to.
+  RAngleLoc = Tok.getLocation();
+
+  if (Tok.is(tok::greatergreater)) {
+    if (!getLang().CPlusPlus0x) {
+      const char *ReplaceStr = "> >";
+      if (NextToken().is(tok::greater) || NextToken().is(tok::greatergreater))
+        ReplaceStr = "> > ";
+
+      Diag(Tok.getLocation(), diag::err_two_right_angle_brackets_need_space)
+        << FixItHint::CreateReplacement(
+                                 SourceRange(Tok.getLocation()), ReplaceStr);
+    }
+
+    Tok.setKind(tok::greater);
+    if (!ConsumeLastToken) {
+      // Since we're not supposed to consume the '>>' token, we need
+      // to insert a second '>' token after the first.
+      PP.EnterToken(Tok);
+    }
+  } else if (ConsumeLastToken)
+    ConsumeToken();
+
+  return false;
+}
+
+/// \brief Replace the tokens that form a simple-template-id with an
+/// annotation token containing the complete template-id.
+///
+/// The first token in the stream must be the name of a template that
+/// is followed by a '<'. This routine will parse the complete
+/// simple-template-id and replace the tokens with a single annotation
+/// token with one of two different kinds: if the template-id names a
+/// type (and \p AllowTypeAnnotation is true), the annotation token is
+/// a type annotation that includes the optional nested-name-specifier
+/// (\p SS). Otherwise, the annotation token is a template-id
+/// annotation that does not include the optional
+/// nested-name-specifier.
+///
+/// \param Template  the declaration of the template named by the first
+/// token (an identifier), as returned from \c Action::isTemplateName().
+///
+/// \param TemplateNameKind the kind of template that \p Template
+/// refers to, as returned from \c Action::isTemplateName().
+///
+/// \param SS if non-NULL, the nested-name-specifier that precedes
+/// this template name.
+///
+/// \param TemplateKWLoc if valid, specifies that this template-id
+/// annotation was preceded by the 'template' keyword and gives the
+/// location of that keyword. If invalid (the default), then this
+/// template-id was not preceded by a 'template' keyword.
+///
+/// \param AllowTypeAnnotation if true (the default), then a
+/// simple-template-id that refers to a class template, template
+/// template parameter, or other template that produces a type will be
+/// replaced with a type annotation token. Otherwise, the
+/// simple-template-id is always replaced with a template-id
+/// annotation token.
+///
+/// If an unrecoverable parse error occurs and no annotation token can be
+/// formed, this function returns true.
+///
+bool Parser::AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK,
+                                     const CXXScopeSpec *SS,
+                                     UnqualifiedId &TemplateName,
+                                     SourceLocation TemplateKWLoc,
+                                     bool AllowTypeAnnotation) {
+  assert(getLang().CPlusPlus && "Can only annotate template-ids in C++");
+  assert(Template && Tok.is(tok::less) &&
+         "Parser isn't at the beginning of a template-id");
+
+  // Consume the template-name.
+  SourceLocation TemplateNameLoc = TemplateName.getSourceRange().getBegin();
+
+  // Parse the enclosed template argument list.
+  SourceLocation LAngleLoc, RAngleLoc;
+  TemplateArgList TemplateArgs;
+  bool Invalid = ParseTemplateIdAfterTemplateName(Template, 
+                                                  TemplateNameLoc,
+                                                  SS, false, LAngleLoc,
+                                                  TemplateArgs,
+                                                  RAngleLoc);
+
+  if (Invalid) {
+    // If we failed to parse the template ID but skipped ahead to a >, we're not
+    // going to be able to form a token annotation.  Eat the '>' if present.
+    if (Tok.is(tok::greater))
+      ConsumeToken();
+    return true;
+  }
+
+  ASTTemplateArgsPtr TemplateArgsPtr(Actions, TemplateArgs.data(),
+                                     TemplateArgs.size());
+
+  // Build the annotation token.
+  if (TNK == TNK_Type_template && AllowTypeAnnotation) {
+    Action::TypeResult Type
+      = Actions.ActOnTemplateIdType(Template, TemplateNameLoc,
+                                    LAngleLoc, TemplateArgsPtr,
+                                    RAngleLoc);
+    if (Type.isInvalid()) {
+      // If we failed to parse the template ID but skipped ahead to a >, we're not
+      // going to be able to form a token annotation.  Eat the '>' if present.
+      if (Tok.is(tok::greater))
+        ConsumeToken();
+      return true;
+    }
+
+    Tok.setKind(tok::annot_typename);
+    Tok.setAnnotationValue(Type.get());
+    if (SS && SS->isNotEmpty())
+      Tok.setLocation(SS->getBeginLoc());
+    else if (TemplateKWLoc.isValid())
+      Tok.setLocation(TemplateKWLoc);
+    else
+      Tok.setLocation(TemplateNameLoc);
+  } else {
+    // Build a template-id annotation token that can be processed
+    // later.
+    Tok.setKind(tok::annot_template_id);
+    TemplateIdAnnotation *TemplateId
+      = TemplateIdAnnotation::Allocate(TemplateArgs.size());
+    TemplateId->TemplateNameLoc = TemplateNameLoc;
+    if (TemplateName.getKind() == UnqualifiedId::IK_Identifier) {
+      TemplateId->Name = TemplateName.Identifier;
+      TemplateId->Operator = OO_None;
+    } else {
+      TemplateId->Name = 0;
+      TemplateId->Operator = TemplateName.OperatorFunctionId.Operator;
+    }
+    TemplateId->Template = Template.getAs<void*>();
+    TemplateId->Kind = TNK;
+    TemplateId->LAngleLoc = LAngleLoc;
+    TemplateId->RAngleLoc = RAngleLoc;
+    ParsedTemplateArgument *Args = TemplateId->getTemplateArgs();
+    for (unsigned Arg = 0, ArgEnd = TemplateArgs.size(); Arg != ArgEnd; ++Arg)
+      Args[Arg] = TemplateArgs[Arg];
+    Tok.setAnnotationValue(TemplateId);
+    if (TemplateKWLoc.isValid())
+      Tok.setLocation(TemplateKWLoc);
+    else
+      Tok.setLocation(TemplateNameLoc);
+
+    TemplateArgsPtr.release();
+  }
+
+  // Common fields for the annotation token
+  Tok.setAnnotationEndLoc(RAngleLoc);
+
+  // In case the tokens were cached, have Preprocessor replace them with the
+  // annotation token.
+  PP.AnnotateCachedTokens(Tok);
+  return false;
+}
+
+/// \brief Replaces a template-id annotation token with a type
+/// annotation token.
+///
+/// If there was a failure when forming the type from the template-id,
+/// a type annotation token will still be created, but will have a
+/// NULL type pointer to signify an error.
+void Parser::AnnotateTemplateIdTokenAsType(const CXXScopeSpec *SS) {
+  assert(Tok.is(tok::annot_template_id) && "Requires template-id tokens");
+
+  TemplateIdAnnotation *TemplateId
+    = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
+  assert((TemplateId->Kind == TNK_Type_template ||
+          TemplateId->Kind == TNK_Dependent_template_name) &&
+         "Only works for type and dependent templates");
+
+  ASTTemplateArgsPtr TemplateArgsPtr(Actions,
+                                     TemplateId->getTemplateArgs(),
+                                     TemplateId->NumArgs);
+
+  Action::TypeResult Type
+    = Actions.ActOnTemplateIdType(TemplateTy::make(TemplateId->Template),
+                                  TemplateId->TemplateNameLoc,
+                                  TemplateId->LAngleLoc,
+                                  TemplateArgsPtr,
+                                  TemplateId->RAngleLoc);
+  // Create the new "type" annotation token.
+  Tok.setKind(tok::annot_typename);
+  Tok.setAnnotationValue(Type.isInvalid()? 0 : Type.get());
+  if (SS && SS->isNotEmpty()) // it was a C++ qualified type name.
+    Tok.setLocation(SS->getBeginLoc());
+  // End location stays the same
+
+  // Replace the template-id annotation token, and possible the scope-specifier
+  // that precedes it, with the typename annotation token.
+  PP.AnnotateCachedTokens(Tok);
+  TemplateId->Destroy();
+}
+
+/// \brief Determine whether the given token can end a template argument.
+static bool isEndOfTemplateArgument(Token Tok) {
+  return Tok.is(tok::comma) || Tok.is(tok::greater) || 
+         Tok.is(tok::greatergreater);
+}
+
+/// \brief Parse a C++ template template argument.
+ParsedTemplateArgument Parser::ParseTemplateTemplateArgument() {
+  if (!Tok.is(tok::identifier) && !Tok.is(tok::coloncolon) &&
+      !Tok.is(tok::annot_cxxscope))
+    return ParsedTemplateArgument();
+
+  // C++0x [temp.arg.template]p1:
+  //   A template-argument for a template template-parameter shall be the name
+  //   of a class template or a template alias, expressed as id-expression.
+  //   
+  // We parse an id-expression that refers to a class template or template
+  // alias. The grammar we parse is:
+  //
+  //   nested-name-specifier[opt] template[opt] identifier
+  //
+  // followed by a token that terminates a template argument, such as ',', 
+  // '>', or (in some cases) '>>'.
+  CXXScopeSpec SS; // nested-name-specifier, if present
+  ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, 
+                                 /*EnteringContext=*/false);
+  
+  if (SS.isSet() && Tok.is(tok::kw_template)) {
+    // Parse the optional 'template' keyword following the 
+    // nested-name-specifier.
+    SourceLocation TemplateLoc = ConsumeToken();
+    
+    if (Tok.is(tok::identifier)) {
+      // We appear to have a dependent template name.
+      UnqualifiedId Name;
+      Name.setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
+      ConsumeToken(); // the identifier
+      
+      // If the next token signals the end of a template argument,
+      // then we have a dependent template name that could be a template
+      // template argument.
+      if (isEndOfTemplateArgument(Tok)) {
+        TemplateTy Template
+        = Actions.ActOnDependentTemplateName(TemplateLoc, SS, Name, 
+                                             /*ObjectType=*/0,
+                                             /*EnteringContext=*/false);
+        if (Template.get())
+          return ParsedTemplateArgument(SS, Template, Name.StartLocation);
+      }
+    } 
+  } else if (Tok.is(tok::identifier)) {
+    // We may have a (non-dependent) template name.
+    TemplateTy Template;
+    UnqualifiedId Name;
+    Name.setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
+    ConsumeToken(); // the identifier
+    
+    if (isEndOfTemplateArgument(Tok)) {
+      TemplateNameKind TNK = Actions.isTemplateName(CurScope, SS, Name, 
+                                                    /*ObjectType=*/0, 
+                                                    /*EnteringContext=*/false, 
+                                                    Template);
+      if (TNK == TNK_Dependent_template_name || TNK == TNK_Type_template) {
+        // We have an id-expression that refers to a class template or
+        // (C++0x) template alias. 
+        return ParsedTemplateArgument(SS, Template, Name.StartLocation);
+      }
+    }
+  }
+  
+  // We don't have a template template argument.  
+  return ParsedTemplateArgument();
+}
+
+/// ParseTemplateArgument - Parse a C++ template argument (C++ [temp.names]).
+///
+///       template-argument: [C++ 14.2]
+///         constant-expression
+///         type-id
+///         id-expression
+ParsedTemplateArgument Parser::ParseTemplateArgument() {
+  // C++ [temp.arg]p2:
+  //   In a template-argument, an ambiguity between a type-id and an
+  //   expression is resolved to a type-id, regardless of the form of
+  //   the corresponding template-parameter.
+  //
+  // Therefore, we initially try to parse a type-id.  
+  if (isCXXTypeId(TypeIdAsTemplateArgument)) {
+    SourceLocation Loc = Tok.getLocation();
+    TypeResult TypeArg = ParseTypeName();
+    if (TypeArg.isInvalid())
+      return ParsedTemplateArgument();
+    
+    return ParsedTemplateArgument(ParsedTemplateArgument::Type, TypeArg.get(), 
+                                  Loc);
+  }
+  
+  // Try to parse a template template argument.
+  {
+    TentativeParsingAction TPA(*this);
+
+    ParsedTemplateArgument TemplateTemplateArgument
+      = ParseTemplateTemplateArgument();
+    if (!TemplateTemplateArgument.isInvalid()) {
+      TPA.Commit();
+      return TemplateTemplateArgument;
+    }
+    
+    // Revert this tentative parse to parse a non-type template argument.
+    TPA.Revert();
+  }
+  
+  // Parse a non-type template argument. 
+  SourceLocation Loc = Tok.getLocation();
+  OwningExprResult ExprArg = ParseConstantExpression();
+  if (ExprArg.isInvalid() || !ExprArg.get())
+    return ParsedTemplateArgument();
+
+  return ParsedTemplateArgument(ParsedTemplateArgument::NonType, 
+                                ExprArg.release(), Loc);
+}
+
+/// ParseTemplateArgumentList - Parse a C++ template-argument-list
+/// (C++ [temp.names]). Returns true if there was an error.
+///
+///       template-argument-list: [C++ 14.2]
+///         template-argument
+///         template-argument-list ',' template-argument
+bool
+Parser::ParseTemplateArgumentList(TemplateArgList &TemplateArgs) {
+  while (true) {
+    ParsedTemplateArgument Arg = ParseTemplateArgument();
+    if (Arg.isInvalid()) {
+      SkipUntil(tok::comma, tok::greater, true, true);
+      return true;
+    }
+
+    // Save this template argument.
+    TemplateArgs.push_back(Arg);
+      
+    // If the next token is a comma, consume it and keep reading
+    // arguments.
+    if (Tok.isNot(tok::comma)) break;
+
+    // Consume the comma.
+    ConsumeToken();
+  }
+
+  return false;
+}
+
+/// \brief Parse a C++ explicit template instantiation
+/// (C++ [temp.explicit]).
+///
+///       explicit-instantiation:
+///         'extern' [opt] 'template' declaration
+///
+/// Note that the 'extern' is a GNU extension and C++0x feature.
+Parser::DeclPtrTy
+Parser::ParseExplicitInstantiation(SourceLocation ExternLoc,
+                                   SourceLocation TemplateLoc,
+                                   SourceLocation &DeclEnd) {
+  return ParseSingleDeclarationAfterTemplate(Declarator::FileContext,
+                                             ParsedTemplateInfo(ExternLoc,
+                                                                TemplateLoc),
+                                             DeclEnd, AS_none);
+}
diff --git a/lib/Parse/ParseTentative.cpp b/lib/Parse/ParseTentative.cpp
new file mode 100644
index 0000000..516a9a6
--- /dev/null
+++ b/lib/Parse/ParseTentative.cpp
@@ -0,0 +1,1038 @@
+//===--- ParseTentative.cpp - Ambiguity Resolution Parsing ----------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements the tentative parsing portions of the Parser
+//  interfaces, for ambiguity resolution.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Parse/Parser.h"
+#include "clang/Parse/ParseDiagnostic.h"
+using namespace clang;
+
+/// isCXXDeclarationStatement - C++-specialized function that disambiguates
+/// between a declaration or an expression statement, when parsing function
+/// bodies. Returns true for declaration, false for expression.
+///
+///         declaration-statement:
+///           block-declaration
+///
+///         block-declaration:
+///           simple-declaration
+///           asm-definition
+///           namespace-alias-definition
+///           using-declaration
+///           using-directive
+/// [C++0x]   static_assert-declaration
+///
+///         asm-definition:
+///           'asm' '(' string-literal ')' ';'
+///
+///         namespace-alias-definition:
+///           'namespace' identifier = qualified-namespace-specifier ';'
+///
+///         using-declaration:
+///           'using' typename[opt] '::'[opt] nested-name-specifier
+///                 unqualified-id ';'
+///           'using' '::' unqualified-id ;
+///
+///         using-directive:
+///           'using' 'namespace' '::'[opt] nested-name-specifier[opt]
+///                 namespace-name ';'
+///
+bool Parser::isCXXDeclarationStatement() {
+  switch (Tok.getKind()) {
+    // asm-definition
+  case tok::kw_asm:
+    // namespace-alias-definition
+  case tok::kw_namespace:
+    // using-declaration
+    // using-directive
+  case tok::kw_using:
+    // static_assert-declaration
+  case tok::kw_static_assert:
+    return true;
+    // simple-declaration
+  default:
+    return isCXXSimpleDeclaration();
+  }
+}
+
+/// isCXXSimpleDeclaration - C++-specialized function that disambiguates
+/// between a simple-declaration or an expression-statement.
+/// If during the disambiguation process a parsing error is encountered,
+/// the function returns true to let the declaration parsing code handle it.
+/// Returns false if the statement is disambiguated as expression.
+///
+/// simple-declaration:
+///   decl-specifier-seq init-declarator-list[opt] ';'
+///
+bool Parser::isCXXSimpleDeclaration() {
+  // C++ 6.8p1:
+  // There is an ambiguity in the grammar involving expression-statements and
+  // declarations: An expression-statement with a function-style explicit type
+  // conversion (5.2.3) as its leftmost subexpression can be indistinguishable
+  // from a declaration where the first declarator starts with a '('. In those
+  // cases the statement is a declaration. [Note: To disambiguate, the whole
+  // statement might have to be examined to determine if it is an
+  // expression-statement or a declaration].
+
+  // C++ 6.8p3:
+  // The disambiguation is purely syntactic; that is, the meaning of the names
+  // occurring in such a statement, beyond whether they are type-names or not,
+  // is not generally used in or changed by the disambiguation. Class
+  // templates are instantiated as necessary to determine if a qualified name
+  // is a type-name. Disambiguation precedes parsing, and a statement
+  // disambiguated as a declaration may be an ill-formed declaration.
+
+  // We don't have to parse all of the decl-specifier-seq part. There's only
+  // an ambiguity if the first decl-specifier is
+  // simple-type-specifier/typename-specifier followed by a '(', which may
+  // indicate a function-style cast expression.
+  // isCXXDeclarationSpecifier will return TPResult::Ambiguous() only in such
+  // a case.
+
+  TPResult TPR = isCXXDeclarationSpecifier();
+  if (TPR != TPResult::Ambiguous())
+    return TPR != TPResult::False(); // Returns true for TPResult::True() or
+                                     // TPResult::Error().
+
+  // FIXME: Add statistics about the number of ambiguous statements encountered
+  // and how they were resolved (number of declarations+number of expressions).
+
+  // Ok, we have a simple-type-specifier/typename-specifier followed by a '('.
+  // We need tentative parsing...
+
+  TentativeParsingAction PA(*this);
+
+  TPR = TryParseSimpleDeclaration();
+  SourceLocation TentativeParseLoc = Tok.getLocation();
+
+  PA.Revert();
+
+  // In case of an error, let the declaration parsing code handle it.
+  if (TPR == TPResult::Error())
+    return true;
+
+  // Declarations take precedence over expressions.
+  if (TPR == TPResult::Ambiguous())
+    TPR = TPResult::True();
+
+  assert(TPR == TPResult::True() || TPR == TPResult::False());
+  return TPR == TPResult::True();
+}
+
+/// simple-declaration:
+///   decl-specifier-seq init-declarator-list[opt] ';'
+///
+Parser::TPResult Parser::TryParseSimpleDeclaration() {
+  // We know that we have a simple-type-specifier/typename-specifier followed
+  // by a '('.
+  assert(isCXXDeclarationSpecifier() == TPResult::Ambiguous());
+
+  if (Tok.is(tok::kw_typeof))
+    TryParseTypeofSpecifier();
+  else
+    ConsumeToken();
+
+  assert(Tok.is(tok::l_paren) && "Expected '('");
+
+  TPResult TPR = TryParseInitDeclaratorList();
+  if (TPR != TPResult::Ambiguous())
+    return TPR;
+
+  if (Tok.isNot(tok::semi))
+    return TPResult::False();
+
+  return TPResult::Ambiguous();
+}
+
+///       init-declarator-list:
+///         init-declarator
+///         init-declarator-list ',' init-declarator
+///
+///       init-declarator:
+///         declarator initializer[opt]
+/// [GNU]   declarator simple-asm-expr[opt] attributes[opt] initializer[opt]
+///
+/// initializer:
+///   '=' initializer-clause
+///   '(' expression-list ')'
+///
+/// initializer-clause:
+///   assignment-expression
+///   '{' initializer-list ','[opt] '}'
+///   '{' '}'
+///
+Parser::TPResult Parser::TryParseInitDeclaratorList() {
+  // GCC only examines the first declarator for disambiguation:
+  // i.e:
+  // int(x), ++x; // GCC regards it as ill-formed declaration.
+  //
+  // Comeau and MSVC will regard the above statement as correct expression.
+  // Clang examines all of the declarators and also regards the above statement
+  // as correct expression.
+
+  while (1) {
+    // declarator
+    TPResult TPR = TryParseDeclarator(false/*mayBeAbstract*/);
+    if (TPR != TPResult::Ambiguous())
+      return TPR;
+
+    // [GNU] simple-asm-expr[opt] attributes[opt]
+    if (Tok.is(tok::kw_asm) || Tok.is(tok::kw___attribute))
+      return TPResult::True();
+
+    // initializer[opt]
+    if (Tok.is(tok::l_paren)) {
+      // Parse through the parens.
+      ConsumeParen();
+      if (!SkipUntil(tok::r_paren))
+        return TPResult::Error();
+    } else if (Tok.is(tok::equal)) {
+      // MSVC won't examine the rest of declarators if '=' is encountered, it
+      // will conclude that it is a declaration.
+      // Comeau and Clang will examine the rest of declarators.
+      // Note that "int(x) = {0}, ++x;" will be interpreted as ill-formed
+      // expression.
+      //
+      // Parse through the initializer-clause.
+      SkipUntil(tok::comma, true/*StopAtSemi*/, true/*DontConsume*/);
+    }
+
+    if (Tok.isNot(tok::comma))
+      break;
+    ConsumeToken(); // the comma.
+  }
+
+  return TPResult::Ambiguous();
+}
+
+/// isCXXConditionDeclaration - Disambiguates between a declaration or an
+/// expression for a condition of a if/switch/while/for statement.
+/// If during the disambiguation process a parsing error is encountered,
+/// the function returns true to let the declaration parsing code handle it.
+///
+///       condition:
+///         expression
+///         type-specifier-seq declarator '=' assignment-expression
+/// [GNU]   type-specifier-seq declarator simple-asm-expr[opt] attributes[opt]
+///             '=' assignment-expression
+///
+bool Parser::isCXXConditionDeclaration() {
+  TPResult TPR = isCXXDeclarationSpecifier();
+  if (TPR != TPResult::Ambiguous())
+    return TPR != TPResult::False(); // Returns true for TPResult::True() or
+                                     // TPResult::Error().
+
+  // FIXME: Add statistics about the number of ambiguous statements encountered
+  // and how they were resolved (number of declarations+number of expressions).
+
+  // Ok, we have a simple-type-specifier/typename-specifier followed by a '('.
+  // We need tentative parsing...
+
+  TentativeParsingAction PA(*this);
+
+  // type-specifier-seq
+  if (Tok.is(tok::kw_typeof))
+    TryParseTypeofSpecifier();
+  else
+    ConsumeToken();
+  assert(Tok.is(tok::l_paren) && "Expected '('");
+
+  // declarator
+  TPR = TryParseDeclarator(false/*mayBeAbstract*/);
+
+  // In case of an error, let the declaration parsing code handle it.
+  if (TPR == TPResult::Error())
+    TPR = TPResult::True();
+
+  if (TPR == TPResult::Ambiguous()) {
+    // '='
+    // [GNU] simple-asm-expr[opt] attributes[opt]
+    if (Tok.is(tok::equal)  ||
+        Tok.is(tok::kw_asm) || Tok.is(tok::kw___attribute))
+      TPR = TPResult::True();
+    else
+      TPR = TPResult::False();
+  }
+
+  PA.Revert();
+
+  assert(TPR == TPResult::True() || TPR == TPResult::False());
+  return TPR == TPResult::True();
+}
+
+  /// \brief Determine whether the next set of tokens contains a type-id.
+  ///
+  /// The context parameter states what context we're parsing right
+  /// now, which affects how this routine copes with the token
+  /// following the type-id. If the context is TypeIdInParens, we have
+  /// already parsed the '(' and we will cease lookahead when we hit
+  /// the corresponding ')'. If the context is
+  /// TypeIdAsTemplateArgument, we've already parsed the '<' or ','
+  /// before this template argument, and will cease lookahead when we
+  /// hit a '>', '>>' (in C++0x), or ','. Returns true for a type-id
+  /// and false for an expression.  If during the disambiguation
+  /// process a parsing error is encountered, the function returns
+  /// true to let the declaration parsing code handle it.
+  ///
+  /// type-id:
+  ///   type-specifier-seq abstract-declarator[opt]
+  ///
+bool Parser::isCXXTypeId(TentativeCXXTypeIdContext Context, bool &isAmbiguous) {
+
+  isAmbiguous = false;
+
+  // C++ 8.2p2:
+  // The ambiguity arising from the similarity between a function-style cast and
+  // a type-id can occur in different contexts. The ambiguity appears as a
+  // choice between a function-style cast expression and a declaration of a
+  // type. The resolution is that any construct that could possibly be a type-id
+  // in its syntactic context shall be considered a type-id.
+
+  TPResult TPR = isCXXDeclarationSpecifier();
+  if (TPR != TPResult::Ambiguous())
+    return TPR != TPResult::False(); // Returns true for TPResult::True() or
+                                     // TPResult::Error().
+
+  // FIXME: Add statistics about the number of ambiguous statements encountered
+  // and how they were resolved (number of declarations+number of expressions).
+
+  // Ok, we have a simple-type-specifier/typename-specifier followed by a '('.
+  // We need tentative parsing...
+
+  TentativeParsingAction PA(*this);
+
+  // type-specifier-seq
+  if (Tok.is(tok::kw_typeof))
+    TryParseTypeofSpecifier();
+  else
+    ConsumeToken();
+  assert(Tok.is(tok::l_paren) && "Expected '('");
+
+  // declarator
+  TPR = TryParseDeclarator(true/*mayBeAbstract*/, false/*mayHaveIdentifier*/);
+
+  // In case of an error, let the declaration parsing code handle it.
+  if (TPR == TPResult::Error())
+    TPR = TPResult::True();
+
+  if (TPR == TPResult::Ambiguous()) {
+    // We are supposed to be inside parens, so if after the abstract declarator
+    // we encounter a ')' this is a type-id, otherwise it's an expression.
+    if (Context == TypeIdInParens && Tok.is(tok::r_paren)) {
+      TPR = TPResult::True();
+      isAmbiguous = true;
+
+    // We are supposed to be inside a template argument, so if after
+    // the abstract declarator we encounter a '>', '>>' (in C++0x), or
+    // ',', this is a type-id. Otherwise, it's an expression.
+    } else if (Context == TypeIdAsTemplateArgument &&
+               (Tok.is(tok::greater) || Tok.is(tok::comma) ||
+                (getLang().CPlusPlus0x && Tok.is(tok::greatergreater)))) {
+      TPR = TPResult::True();
+      isAmbiguous = true;
+
+    } else
+      TPR = TPResult::False();
+  }
+
+  PA.Revert();
+
+  assert(TPR == TPResult::True() || TPR == TPResult::False());
+  return TPR == TPResult::True();
+}
+
+/// isCXX0XAttributeSpecifier - returns true if this is a C++0x
+/// attribute-specifier. By default, unless in Obj-C++, only a cursory check is
+/// performed that will simply return true if a [[ is seen. Currently C++ has no
+/// syntactical ambiguities from this check, but it may inhibit error recovery.
+/// If CheckClosing is true, a check is made for closing ]] brackets.
+///
+/// If given, After is set to the token after the attribute-specifier so that
+/// appropriate parsing decisions can be made; it is left untouched if false is
+/// returned.
+///
+/// FIXME: If an error is in the closing ]] brackets, the program assumes
+/// the absence of an attribute-specifier, which can cause very yucky errors
+/// to occur.
+///
+/// [C++0x] attribute-specifier:
+///         '[' '[' attribute-list ']' ']'
+///
+/// [C++0x] attribute-list:
+///         attribute[opt]
+///         attribute-list ',' attribute[opt]
+///
+/// [C++0x] attribute:
+///         attribute-token attribute-argument-clause[opt]
+///
+/// [C++0x] attribute-token:
+///         identifier
+///         attribute-scoped-token
+///
+/// [C++0x] attribute-scoped-token:
+///         attribute-namespace '::' identifier
+///
+/// [C++0x] attribute-namespace:
+///         identifier
+///
+/// [C++0x] attribute-argument-clause:
+///         '(' balanced-token-seq ')'
+///
+/// [C++0x] balanced-token-seq:
+///         balanced-token
+///         balanced-token-seq balanced-token
+///
+/// [C++0x] balanced-token:
+///         '(' balanced-token-seq ')'
+///         '[' balanced-token-seq ']'
+///         '{' balanced-token-seq '}'
+///         any token but '(', ')', '[', ']', '{', or '}'
+bool Parser::isCXX0XAttributeSpecifier (bool CheckClosing,
+                                        tok::TokenKind *After) {
+  if (Tok.isNot(tok::l_square) || NextToken().isNot(tok::l_square))
+    return false;
+  
+  // No tentative parsing if we don't need to look for ]]
+  if (!CheckClosing && !getLang().ObjC1)
+    return true;
+  
+  struct TentativeReverter {
+    TentativeParsingAction PA;
+
+    TentativeReverter (Parser& P)
+      : PA(P)
+    {}
+    ~TentativeReverter () {
+      PA.Revert();
+    }
+  } R(*this);
+
+  // Opening brackets were checked for above.
+  ConsumeBracket();
+  ConsumeBracket();
+
+  // SkipUntil will handle balanced tokens, which are guaranteed in attributes.
+  SkipUntil(tok::r_square, false);
+
+  if (Tok.isNot(tok::r_square))
+    return false;
+  ConsumeBracket();
+
+  if (After)
+    *After = Tok.getKind();
+
+  return true;
+}
+
+///         declarator:
+///           direct-declarator
+///           ptr-operator declarator
+///
+///         direct-declarator:
+///           declarator-id
+///           direct-declarator '(' parameter-declaration-clause ')'
+///                 cv-qualifier-seq[opt] exception-specification[opt]
+///           direct-declarator '[' constant-expression[opt] ']'
+///           '(' declarator ')'
+/// [GNU]     '(' attributes declarator ')'
+///
+///         abstract-declarator:
+///           ptr-operator abstract-declarator[opt]
+///           direct-abstract-declarator
+///
+///         direct-abstract-declarator:
+///           direct-abstract-declarator[opt]
+///           '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
+///                 exception-specification[opt]
+///           direct-abstract-declarator[opt] '[' constant-expression[opt] ']'
+///           '(' abstract-declarator ')'
+///
+///         ptr-operator:
+///           '*' cv-qualifier-seq[opt]
+///           '&'
+/// [C++0x]   '&&'                                                        [TODO]
+///           '::'[opt] nested-name-specifier '*' cv-qualifier-seq[opt]
+///
+///         cv-qualifier-seq:
+///           cv-qualifier cv-qualifier-seq[opt]
+///
+///         cv-qualifier:
+///           'const'
+///           'volatile'
+///
+///         declarator-id:
+///           id-expression
+///
+///         id-expression:
+///           unqualified-id
+///           qualified-id                                                [TODO]
+///
+///         unqualified-id:
+///           identifier
+///           operator-function-id                                        [TODO]
+///           conversion-function-id                                      [TODO]
+///           '~' class-name                                              [TODO]
+///           template-id                                                 [TODO]
+///
+Parser::TPResult Parser::TryParseDeclarator(bool mayBeAbstract,
+                                            bool mayHaveIdentifier) {
+  // declarator:
+  //   direct-declarator
+  //   ptr-operator declarator
+
+  while (1) {
+    if (Tok.is(tok::coloncolon) || Tok.is(tok::identifier))
+      if (TryAnnotateCXXScopeToken(true))
+        return TPResult::Error();
+
+    if (Tok.is(tok::star) || Tok.is(tok::amp) || Tok.is(tok::caret) ||
+        (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::star))) {
+      // ptr-operator
+      ConsumeToken();
+      while (Tok.is(tok::kw_const)    ||
+             Tok.is(tok::kw_volatile) ||
+             Tok.is(tok::kw_restrict))
+        ConsumeToken();
+    } else {
+      break;
+    }
+  }
+
+  // direct-declarator:
+  // direct-abstract-declarator:
+
+  if ((Tok.is(tok::identifier) ||
+       (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::identifier))) &&
+      mayHaveIdentifier) {
+    // declarator-id
+    if (Tok.is(tok::annot_cxxscope))
+      ConsumeToken();
+    ConsumeToken();
+  } else if (Tok.is(tok::l_paren)) {
+    ConsumeParen();
+    if (mayBeAbstract &&
+        (Tok.is(tok::r_paren) ||       // 'int()' is a function.
+         Tok.is(tok::ellipsis) ||      // 'int(...)' is a function.
+         isDeclarationSpecifier())) {   // 'int(int)' is a function.
+      // '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
+      //        exception-specification[opt]
+      TPResult TPR = TryParseFunctionDeclarator();
+      if (TPR != TPResult::Ambiguous())
+        return TPR;
+    } else {
+      // '(' declarator ')'
+      // '(' attributes declarator ')'
+      // '(' abstract-declarator ')'
+      if (Tok.is(tok::kw___attribute))
+        return TPResult::True(); // attributes indicate declaration
+      TPResult TPR = TryParseDeclarator(mayBeAbstract, mayHaveIdentifier);
+      if (TPR != TPResult::Ambiguous())
+        return TPR;
+      if (Tok.isNot(tok::r_paren))
+        return TPResult::False();
+      ConsumeParen();
+    }
+  } else if (!mayBeAbstract) {
+    return TPResult::False();
+  }
+
+  while (1) {
+    TPResult TPR(TPResult::Ambiguous());
+
+    if (Tok.is(tok::l_paren)) {
+      // Check whether we have a function declarator or a possible ctor-style
+      // initializer that follows the declarator. Note that ctor-style
+      // initializers are not possible in contexts where abstract declarators
+      // are allowed.
+      if (!mayBeAbstract && !isCXXFunctionDeclarator(false/*warnIfAmbiguous*/))
+        break;
+
+      // direct-declarator '(' parameter-declaration-clause ')'
+      //        cv-qualifier-seq[opt] exception-specification[opt]
+      ConsumeParen();
+      TPR = TryParseFunctionDeclarator();
+    } else if (Tok.is(tok::l_square)) {
+      // direct-declarator '[' constant-expression[opt] ']'
+      // direct-abstract-declarator[opt] '[' constant-expression[opt] ']'
+      TPR = TryParseBracketDeclarator();
+    } else {
+      break;
+    }
+
+    if (TPR != TPResult::Ambiguous())
+      return TPR;
+  }
+
+  return TPResult::Ambiguous();
+}
+
+/// isCXXDeclarationSpecifier - Returns TPResult::True() if it is a declaration
+/// specifier, TPResult::False() if it is not, TPResult::Ambiguous() if it could
+/// be either a decl-specifier or a function-style cast, and TPResult::Error()
+/// if a parsing error was found and reported.
+///
+///         decl-specifier:
+///           storage-class-specifier
+///           type-specifier
+///           function-specifier
+///           'friend'
+///           'typedef'
+/// [C++0x]   'constexpr'
+/// [GNU]     attributes declaration-specifiers[opt]
+///
+///         storage-class-specifier:
+///           'register'
+///           'static'
+///           'extern'
+///           'mutable'
+///           'auto'
+/// [GNU]     '__thread'
+///
+///         function-specifier:
+///           'inline'
+///           'virtual'
+///           'explicit'
+///
+///         typedef-name:
+///           identifier
+///
+///         type-specifier:
+///           simple-type-specifier
+///           class-specifier
+///           enum-specifier
+///           elaborated-type-specifier
+///           typename-specifier
+///           cv-qualifier
+///
+///         simple-type-specifier:
+///           '::'[opt] nested-name-specifier[opt] type-name
+///           '::'[opt] nested-name-specifier 'template'
+///                 simple-template-id                              [TODO]
+///           'char'
+///           'wchar_t'
+///           'bool'
+///           'short'
+///           'int'
+///           'long'
+///           'signed'
+///           'unsigned'
+///           'float'
+///           'double'
+///           'void'
+/// [GNU]     typeof-specifier
+/// [GNU]     '_Complex'
+/// [C++0x]   'auto'                                                [TODO]
+/// [C++0x]   'decltype' ( expression )
+///
+///         type-name:
+///           class-name
+///           enum-name
+///           typedef-name
+///
+///         elaborated-type-specifier:
+///           class-key '::'[opt] nested-name-specifier[opt] identifier
+///           class-key '::'[opt] nested-name-specifier[opt] 'template'[opt]
+///               simple-template-id
+///           'enum' '::'[opt] nested-name-specifier[opt] identifier
+///
+///         enum-name:
+///           identifier
+///
+///         enum-specifier:
+///           'enum' identifier[opt] '{' enumerator-list[opt] '}'
+///           'enum' identifier[opt] '{' enumerator-list ',' '}'
+///
+///         class-specifier:
+///           class-head '{' member-specification[opt] '}'
+///
+///         class-head:
+///           class-key identifier[opt] base-clause[opt]
+///           class-key nested-name-specifier identifier base-clause[opt]
+///           class-key nested-name-specifier[opt] simple-template-id
+///               base-clause[opt]
+///
+///         class-key:
+///           'class'
+///           'struct'
+///           'union'
+///
+///         cv-qualifier:
+///           'const'
+///           'volatile'
+/// [GNU]     restrict
+///
+Parser::TPResult Parser::isCXXDeclarationSpecifier() {
+  switch (Tok.getKind()) {
+  case tok::identifier:   // foo::bar
+    // Check for need to substitute AltiVec __vector keyword
+    // for "vector" identifier.
+    if (TryAltiVecVectorToken())
+      return TPResult::True();
+    // Fall through.
+  case tok::kw_typename:  // typename T::type
+    // Annotate typenames and C++ scope specifiers.  If we get one, just
+    // recurse to handle whatever we get.
+    if (TryAnnotateTypeOrScopeToken())
+      return TPResult::Error();
+    if (Tok.is(tok::identifier))
+      return TPResult::False();
+    return isCXXDeclarationSpecifier();
+
+  case tok::coloncolon: {    // ::foo::bar
+    const Token &Next = NextToken();
+    if (Next.is(tok::kw_new) ||    // ::new
+        Next.is(tok::kw_delete))   // ::delete
+      return TPResult::False();
+
+    // Annotate typenames and C++ scope specifiers.  If we get one, just
+    // recurse to handle whatever we get.
+    if (TryAnnotateTypeOrScopeToken())
+      return TPResult::Error();
+    return isCXXDeclarationSpecifier();
+  }
+      
+    // decl-specifier:
+    //   storage-class-specifier
+    //   type-specifier
+    //   function-specifier
+    //   'friend'
+    //   'typedef'
+    //   'constexpr'
+  case tok::kw_friend:
+  case tok::kw_typedef:
+  case tok::kw_constexpr:
+    // storage-class-specifier
+  case tok::kw_register:
+  case tok::kw_static:
+  case tok::kw_extern:
+  case tok::kw_mutable:
+  case tok::kw_auto:
+  case tok::kw___thread:
+    // function-specifier
+  case tok::kw_inline:
+  case tok::kw_virtual:
+  case tok::kw_explicit:
+
+    // type-specifier:
+    //   simple-type-specifier
+    //   class-specifier
+    //   enum-specifier
+    //   elaborated-type-specifier
+    //   typename-specifier
+    //   cv-qualifier
+
+    // class-specifier
+    // elaborated-type-specifier
+  case tok::kw_class:
+  case tok::kw_struct:
+  case tok::kw_union:
+    // enum-specifier
+  case tok::kw_enum:
+    // cv-qualifier
+  case tok::kw_const:
+  case tok::kw_volatile:
+
+    // GNU
+  case tok::kw_restrict:
+  case tok::kw__Complex:
+  case tok::kw___attribute:
+    return TPResult::True();
+
+    // Microsoft
+  case tok::kw___declspec:
+  case tok::kw___cdecl:
+  case tok::kw___stdcall:
+  case tok::kw___fastcall:
+  case tok::kw___w64:
+  case tok::kw___ptr64:
+  case tok::kw___forceinline:
+    return TPResult::True();
+  
+    // AltiVec
+  case tok::kw___vector:
+    return TPResult::True();
+
+  case tok::annot_cxxscope: // foo::bar or ::foo::bar, but already parsed
+    // We've already annotated a scope; try to annotate a type.
+    if (TryAnnotateTypeOrScopeToken())
+      return TPResult::Error();
+    if (!Tok.is(tok::annot_typename))
+      return TPResult::False();
+    // If that succeeded, fallthrough into the generic simple-type-id case.
+
+    // The ambiguity resides in a simple-type-specifier/typename-specifier
+    // followed by a '('. The '(' could either be the start of:
+    //
+    //   direct-declarator:
+    //     '(' declarator ')'
+    //
+    //   direct-abstract-declarator:
+    //     '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
+    //              exception-specification[opt]
+    //     '(' abstract-declarator ')'
+    //
+    // or part of a function-style cast expression:
+    //
+    //     simple-type-specifier '(' expression-list[opt] ')'
+    //
+
+    // simple-type-specifier:
+
+  case tok::kw_char:
+  case tok::kw_wchar_t:
+  case tok::kw_char16_t:
+  case tok::kw_char32_t:
+  case tok::kw_bool:
+  case tok::kw_short:
+  case tok::kw_int:
+  case tok::kw_long:
+  case tok::kw_signed:
+  case tok::kw_unsigned:
+  case tok::kw_float:
+  case tok::kw_double:
+  case tok::kw_void:
+  case tok::annot_typename:
+    if (NextToken().is(tok::l_paren))
+      return TPResult::Ambiguous();
+
+    return TPResult::True();
+
+  // GNU typeof support.
+  case tok::kw_typeof: {
+    if (NextToken().isNot(tok::l_paren))
+      return TPResult::True();
+
+    TentativeParsingAction PA(*this);
+
+    TPResult TPR = TryParseTypeofSpecifier();
+    bool isFollowedByParen = Tok.is(tok::l_paren);
+
+    PA.Revert();
+
+    if (TPR == TPResult::Error())
+      return TPResult::Error();
+
+    if (isFollowedByParen)
+      return TPResult::Ambiguous();
+
+    return TPResult::True();
+  }
+
+  // C++0x decltype support.
+  case tok::kw_decltype:
+    return TPResult::True();
+
+  default:
+    return TPResult::False();
+  }
+}
+
+/// [GNU] typeof-specifier:
+///         'typeof' '(' expressions ')'
+///         'typeof' '(' type-name ')'
+///
+Parser::TPResult Parser::TryParseTypeofSpecifier() {
+  assert(Tok.is(tok::kw_typeof) && "Expected 'typeof'!");
+  ConsumeToken();
+
+  assert(Tok.is(tok::l_paren) && "Expected '('");
+  // Parse through the parens after 'typeof'.
+  ConsumeParen();
+  if (!SkipUntil(tok::r_paren))
+    return TPResult::Error();
+
+  return TPResult::Ambiguous();
+}
+
+Parser::TPResult Parser::TryParseDeclarationSpecifier() {
+  TPResult TPR = isCXXDeclarationSpecifier();
+  if (TPR != TPResult::Ambiguous())
+    return TPR;
+
+  if (Tok.is(tok::kw_typeof))
+    TryParseTypeofSpecifier();
+  else
+    ConsumeToken();
+
+  assert(Tok.is(tok::l_paren) && "Expected '('!");
+  return TPResult::Ambiguous();
+}
+
+/// isCXXFunctionDeclarator - Disambiguates between a function declarator or
+/// a constructor-style initializer, when parsing declaration statements.
+/// Returns true for function declarator and false for constructor-style
+/// initializer.
+/// If during the disambiguation process a parsing error is encountered,
+/// the function returns true to let the declaration parsing code handle it.
+///
+/// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
+///         exception-specification[opt]
+///
+bool Parser::isCXXFunctionDeclarator(bool warnIfAmbiguous) {
+
+  // C++ 8.2p1:
+  // The ambiguity arising from the similarity between a function-style cast and
+  // a declaration mentioned in 6.8 can also occur in the context of a
+  // declaration. In that context, the choice is between a function declaration
+  // with a redundant set of parentheses around a parameter name and an object
+  // declaration with a function-style cast as the initializer. Just as for the
+  // ambiguities mentioned in 6.8, the resolution is to consider any construct
+  // that could possibly be a declaration a declaration.
+
+  TentativeParsingAction PA(*this);
+
+  ConsumeParen();
+  TPResult TPR = TryParseParameterDeclarationClause();
+  if (TPR == TPResult::Ambiguous() && Tok.isNot(tok::r_paren))
+    TPR = TPResult::False();
+
+  SourceLocation TPLoc = Tok.getLocation();
+  PA.Revert();
+
+  // In case of an error, let the declaration parsing code handle it.
+  if (TPR == TPResult::Error())
+    return true;
+
+  if (TPR == TPResult::Ambiguous()) {
+    // Function declarator has precedence over constructor-style initializer.
+    // Emit a warning just in case the author intended a variable definition.
+    if (warnIfAmbiguous)
+      Diag(Tok, diag::warn_parens_disambiguated_as_function_decl)
+        << SourceRange(Tok.getLocation(), TPLoc);
+    return true;
+  }
+
+  return TPR == TPResult::True();
+}
+
+/// parameter-declaration-clause:
+///   parameter-declaration-list[opt] '...'[opt]
+///   parameter-declaration-list ',' '...'
+///
+/// parameter-declaration-list:
+///   parameter-declaration
+///   parameter-declaration-list ',' parameter-declaration
+///
+/// parameter-declaration:
+///   decl-specifier-seq declarator
+///   decl-specifier-seq declarator '=' assignment-expression
+///   decl-specifier-seq abstract-declarator[opt]
+///   decl-specifier-seq abstract-declarator[opt] '=' assignment-expression
+///
+Parser::TPResult Parser::TryParseParameterDeclarationClause() {
+
+  if (Tok.is(tok::r_paren))
+    return TPResult::True();
+
+  //   parameter-declaration-list[opt] '...'[opt]
+  //   parameter-declaration-list ',' '...'
+  //
+  // parameter-declaration-list:
+  //   parameter-declaration
+  //   parameter-declaration-list ',' parameter-declaration
+  //
+  while (1) {
+    // '...'[opt]
+    if (Tok.is(tok::ellipsis)) {
+      ConsumeToken();
+      return TPResult::True(); // '...' is a sign of a function declarator.
+    }
+
+    // decl-specifier-seq
+    TPResult TPR = TryParseDeclarationSpecifier();
+    if (TPR != TPResult::Ambiguous())
+      return TPR;
+
+    // declarator
+    // abstract-declarator[opt]
+    TPR = TryParseDeclarator(true/*mayBeAbstract*/);
+    if (TPR != TPResult::Ambiguous())
+      return TPR;
+
+    if (Tok.is(tok::equal)) {
+      // '=' assignment-expression
+      // Parse through assignment-expression.
+      tok::TokenKind StopToks[3] ={ tok::comma, tok::ellipsis, tok::r_paren };
+      if (!SkipUntil(StopToks, 3, true/*StopAtSemi*/, true/*DontConsume*/))
+        return TPResult::Error();
+    }
+
+    if (Tok.is(tok::ellipsis)) {
+      ConsumeToken();
+      return TPResult::True(); // '...' is a sign of a function declarator.
+    }
+
+    if (Tok.isNot(tok::comma))
+      break;
+    ConsumeToken(); // the comma.
+  }
+
+  return TPResult::Ambiguous();
+}
+
+/// TryParseFunctionDeclarator - We parsed a '(' and we want to try to continue
+/// parsing as a function declarator.
+/// If TryParseFunctionDeclarator fully parsed the function declarator, it will
+/// return TPResult::Ambiguous(), otherwise it will return either False() or
+/// Error().
+///
+/// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
+///         exception-specification[opt]
+///
+/// exception-specification:
+///   'throw' '(' type-id-list[opt] ')'
+///
+Parser::TPResult Parser::TryParseFunctionDeclarator() {
+
+  // The '(' is already parsed.
+
+  TPResult TPR = TryParseParameterDeclarationClause();
+  if (TPR == TPResult::Ambiguous() && Tok.isNot(tok::r_paren))
+    TPR = TPResult::False();
+
+  if (TPR == TPResult::False() || TPR == TPResult::Error())
+    return TPR;
+
+  // Parse through the parens.
+  if (!SkipUntil(tok::r_paren))
+    return TPResult::Error();
+
+  // cv-qualifier-seq
+  while (Tok.is(tok::kw_const)    ||
+         Tok.is(tok::kw_volatile) ||
+         Tok.is(tok::kw_restrict)   )
+    ConsumeToken();
+
+  // exception-specification
+  if (Tok.is(tok::kw_throw)) {
+    ConsumeToken();
+    if (Tok.isNot(tok::l_paren))
+      return TPResult::Error();
+
+    // Parse through the parens after 'throw'.
+    ConsumeParen();
+    if (!SkipUntil(tok::r_paren))
+      return TPResult::Error();
+  }
+
+  return TPResult::Ambiguous();
+}
+
+/// '[' constant-expression[opt] ']'
+///
+Parser::TPResult Parser::TryParseBracketDeclarator() {
+  ConsumeBracket();
+  if (!SkipUntil(tok::r_square))
+    return TPResult::Error();
+
+  return TPResult::Ambiguous();
+}
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
new file mode 100644
index 0000000..6dbb99e
--- /dev/null
+++ b/lib/Parse/Parser.cpp
@@ -0,0 +1,1079 @@
+//===--- Parser.cpp - C Language Family Parser ----------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements the Parser interfaces.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Parse/Parser.h"
+#include "clang/Parse/ParseDiagnostic.h"
+#include "clang/Parse/DeclSpec.h"
+#include "clang/Parse/Scope.h"
+#include "clang/Parse/Template.h"
+#include "llvm/Support/raw_ostream.h"
+#include "RAIIObjectsForParser.h"
+#include "ParsePragma.h"
+using namespace clang;
+
+Parser::Parser(Preprocessor &pp, Action &actions)
+  : CrashInfo(*this), PP(pp), Actions(actions), Diags(PP.getDiagnostics()),
+    GreaterThanIsOperator(true), ColonIsSacred(false),
+    TemplateParameterDepth(0) {
+  Tok.setKind(tok::eof);
+  CurScope = 0;
+  NumCachedScopes = 0;
+  ParenCount = BracketCount = BraceCount = 0;
+  ObjCImpDecl = DeclPtrTy();
+
+  // Add #pragma handlers. These are removed and destroyed in the
+  // destructor.
+  PackHandler.reset(new
+          PragmaPackHandler(&PP.getIdentifierTable().get("pack"), actions));
+  PP.AddPragmaHandler(0, PackHandler.get());
+
+  UnusedHandler.reset(new
+          PragmaUnusedHandler(&PP.getIdentifierTable().get("unused"), actions,
+                              *this));
+  PP.AddPragmaHandler(0, UnusedHandler.get());
+
+  WeakHandler.reset(new
+          PragmaWeakHandler(&PP.getIdentifierTable().get("weak"), actions));
+  PP.AddPragmaHandler(0, WeakHandler.get());
+}
+
+/// If a crash happens while the parser is active, print out a line indicating
+/// what the current token is.
+void PrettyStackTraceParserEntry::print(llvm::raw_ostream &OS) const {
+  const Token &Tok = P.getCurToken();
+  if (Tok.is(tok::eof)) {
+    OS << "<eof> parser at end of file\n";
+    return;
+  }
+
+  if (Tok.getLocation().isInvalid()) {
+    OS << "<unknown> parser at unknown location\n";
+    return;
+  }
+
+  const Preprocessor &PP = P.getPreprocessor();
+  Tok.getLocation().print(OS, PP.getSourceManager());
+  if (Tok.isAnnotation())
+    OS << ": at annotation token \n";
+  else
+    OS << ": current parser token '" << PP.getSpelling(Tok) << "'\n";
+}
+
+
+DiagnosticBuilder Parser::Diag(SourceLocation Loc, unsigned DiagID) {
+  return Diags.Report(FullSourceLoc(Loc, PP.getSourceManager()), DiagID);
+}
+
+DiagnosticBuilder Parser::Diag(const Token &Tok, unsigned DiagID) {
+  return Diag(Tok.getLocation(), DiagID);
+}
+
+/// \brief Emits a diagnostic suggesting parentheses surrounding a
+/// given range.
+///
+/// \param Loc The location where we'll emit the diagnostic.
+/// \param Loc The kind of diagnostic to emit.
+/// \param ParenRange Source range enclosing code that should be parenthesized.
+void Parser::SuggestParentheses(SourceLocation Loc, unsigned DK,
+                                SourceRange ParenRange) {
+  SourceLocation EndLoc = PP.getLocForEndOfToken(ParenRange.getEnd());
+  if (!ParenRange.getEnd().isFileID() || EndLoc.isInvalid()) {
+    // We can't display the parentheses, so just dig the
+    // warning/error and return.
+    Diag(Loc, DK);
+    return;
+  }
+
+  Diag(Loc, DK)
+    << FixItHint::CreateInsertion(ParenRange.getBegin(), "(")
+    << FixItHint::CreateInsertion(EndLoc, ")");
+}
+
+/// MatchRHSPunctuation - For punctuation with a LHS and RHS (e.g. '['/']'),
+/// this helper function matches and consumes the specified RHS token if
+/// present.  If not present, it emits the specified diagnostic indicating
+/// that the parser failed to match the RHS of the token at LHSLoc.  LHSName
+/// should be the name of the unmatched LHS token.
+SourceLocation Parser::MatchRHSPunctuation(tok::TokenKind RHSTok,
+                                           SourceLocation LHSLoc) {
+
+  if (Tok.is(RHSTok))
+    return ConsumeAnyToken();
+
+  SourceLocation R = Tok.getLocation();
+  const char *LHSName = "unknown";
+  diag::kind DID = diag::err_parse_error;
+  switch (RHSTok) {
+  default: break;
+  case tok::r_paren : LHSName = "("; DID = diag::err_expected_rparen; break;
+  case tok::r_brace : LHSName = "{"; DID = diag::err_expected_rbrace; break;
+  case tok::r_square: LHSName = "["; DID = diag::err_expected_rsquare; break;
+  case tok::greater:  LHSName = "<"; DID = diag::err_expected_greater; break;
+  }
+  Diag(Tok, DID);
+  Diag(LHSLoc, diag::note_matching) << LHSName;
+  SkipUntil(RHSTok);
+  return R;
+}
+
+/// ExpectAndConsume - The parser expects that 'ExpectedTok' is next in the
+/// input.  If so, it is consumed and false is returned.
+///
+/// If the input is malformed, this emits the specified diagnostic.  Next, if
+/// SkipToTok is specified, it calls SkipUntil(SkipToTok).  Finally, true is
+/// returned.
+bool Parser::ExpectAndConsume(tok::TokenKind ExpectedTok, unsigned DiagID,
+                              const char *Msg, tok::TokenKind SkipToTok) {
+  if (Tok.is(ExpectedTok)) {
+    ConsumeAnyToken();
+    return false;
+  }
+
+  const char *Spelling = 0;
+  SourceLocation EndLoc = PP.getLocForEndOfToken(PrevTokLocation);
+  if (EndLoc.isValid() &&
+      (Spelling = tok::getTokenSimpleSpelling(ExpectedTok))) {
+    // Show what code to insert to fix this problem.
+    Diag(EndLoc, DiagID)
+      << Msg
+      << FixItHint::CreateInsertion(EndLoc, Spelling);
+  } else
+    Diag(Tok, DiagID) << Msg;
+
+  if (SkipToTok != tok::unknown)
+    SkipUntil(SkipToTok);
+  return true;
+}
+
+//===----------------------------------------------------------------------===//
+// Error recovery.
+//===----------------------------------------------------------------------===//
+
+/// SkipUntil - Read tokens until we get to the specified token, then consume
+/// it (unless DontConsume is true).  Because we cannot guarantee that the
+/// token will ever occur, this skips to the next token, or to some likely
+/// good stopping point.  If StopAtSemi is true, skipping will stop at a ';'
+/// character.
+///
+/// If SkipUntil finds the specified token, it returns true, otherwise it
+/// returns false.
+bool Parser::SkipUntil(const tok::TokenKind *Toks, unsigned NumToks,
+                       bool StopAtSemi, bool DontConsume) {
+  // We always want this function to skip at least one token if the first token
+  // isn't T and if not at EOF.
+  bool isFirstTokenSkipped = true;
+  while (1) {
+    // If we found one of the tokens, stop and return true.
+    for (unsigned i = 0; i != NumToks; ++i) {
+      if (Tok.is(Toks[i])) {
+        if (DontConsume) {
+          // Noop, don't consume the token.
+        } else {
+          ConsumeAnyToken();
+        }
+        return true;
+      }
+    }
+
+    switch (Tok.getKind()) {
+    case tok::eof:
+      // Ran out of tokens.
+      return false;
+
+    case tok::l_paren:
+      // Recursively skip properly-nested parens.
+      ConsumeParen();
+      SkipUntil(tok::r_paren, false);
+      break;
+    case tok::l_square:
+      // Recursively skip properly-nested square brackets.
+      ConsumeBracket();
+      SkipUntil(tok::r_square, false);
+      break;
+    case tok::l_brace:
+      // Recursively skip properly-nested braces.
+      ConsumeBrace();
+      SkipUntil(tok::r_brace, false);
+      break;
+
+    // Okay, we found a ']' or '}' or ')', which we think should be balanced.
+    // Since the user wasn't looking for this token (if they were, it would
+    // already be handled), this isn't balanced.  If there is a LHS token at a
+    // higher level, we will assume that this matches the unbalanced token
+    // and return it.  Otherwise, this is a spurious RHS token, which we skip.
+    case tok::r_paren:
+      if (ParenCount && !isFirstTokenSkipped)
+        return false;  // Matches something.
+      ConsumeParen();
+      break;
+    case tok::r_square:
+      if (BracketCount && !isFirstTokenSkipped)
+        return false;  // Matches something.
+      ConsumeBracket();
+      break;
+    case tok::r_brace:
+      if (BraceCount && !isFirstTokenSkipped)
+        return false;  // Matches something.
+      ConsumeBrace();
+      break;
+
+    case tok::string_literal:
+    case tok::wide_string_literal:
+      ConsumeStringToken();
+      break;
+    case tok::semi:
+      if (StopAtSemi)
+        return false;
+      // FALL THROUGH.
+    default:
+      // Skip this token.
+      ConsumeToken();
+      break;
+    }
+    isFirstTokenSkipped = false;
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// Scope manipulation
+//===----------------------------------------------------------------------===//
+
+/// EnterScope - Start a new scope.
+void Parser::EnterScope(unsigned ScopeFlags) {
+  if (NumCachedScopes) {
+    Scope *N = ScopeCache[--NumCachedScopes];
+    N->Init(CurScope, ScopeFlags);
+    CurScope = N;
+  } else {
+    CurScope = new Scope(CurScope, ScopeFlags);
+  }
+  CurScope->setNumErrorsAtStart(Diags.getNumErrors());
+}
+
+/// ExitScope - Pop a scope off the scope stack.
+void Parser::ExitScope() {
+  assert(CurScope && "Scope imbalance!");
+
+  // Inform the actions module that this scope is going away if there are any
+  // decls in it.
+  if (!CurScope->decl_empty())
+    Actions.ActOnPopScope(Tok.getLocation(), CurScope);
+
+  Scope *OldScope = CurScope;
+  CurScope = OldScope->getParent();
+
+  if (NumCachedScopes == ScopeCacheSize)
+    delete OldScope;
+  else
+    ScopeCache[NumCachedScopes++] = OldScope;
+}
+
+
+
+
+//===----------------------------------------------------------------------===//
+// C99 6.9: External Definitions.
+//===----------------------------------------------------------------------===//
+
+Parser::~Parser() {
+  // If we still have scopes active, delete the scope tree.
+  delete CurScope;
+
+  // Free the scope cache.
+  for (unsigned i = 0, e = NumCachedScopes; i != e; ++i)
+    delete ScopeCache[i];
+
+  // Remove the pragma handlers we installed.
+  PP.RemovePragmaHandler(0, PackHandler.get());
+  PackHandler.reset();
+  PP.RemovePragmaHandler(0, UnusedHandler.get());
+  UnusedHandler.reset();
+  PP.RemovePragmaHandler(0, WeakHandler.get());
+  WeakHandler.reset();
+}
+
+/// Initialize - Warm up the parser.
+///
+void Parser::Initialize() {
+  // Prime the lexer look-ahead.
+  ConsumeToken();
+
+  // Create the translation unit scope.  Install it as the current scope.
+  assert(CurScope == 0 && "A scope is already active?");
+  EnterScope(Scope::DeclScope);
+  Actions.ActOnTranslationUnitScope(Tok.getLocation(), CurScope);
+
+  if (Tok.is(tok::eof) &&
+      !getLang().CPlusPlus)  // Empty source file is an extension in C
+    Diag(Tok, diag::ext_empty_source_file);
+
+  // Initialization for Objective-C context sensitive keywords recognition.
+  // Referenced in Parser::ParseObjCTypeQualifierList.
+  if (getLang().ObjC1) {
+    ObjCTypeQuals[objc_in] = &PP.getIdentifierTable().get("in");
+    ObjCTypeQuals[objc_out] = &PP.getIdentifierTable().get("out");
+    ObjCTypeQuals[objc_inout] = &PP.getIdentifierTable().get("inout");
+    ObjCTypeQuals[objc_oneway] = &PP.getIdentifierTable().get("oneway");
+    ObjCTypeQuals[objc_bycopy] = &PP.getIdentifierTable().get("bycopy");
+    ObjCTypeQuals[objc_byref] = &PP.getIdentifierTable().get("byref");
+  }
+
+  Ident_super = &PP.getIdentifierTable().get("super");
+
+  if (getLang().AltiVec) {
+    Ident_vector = &PP.getIdentifierTable().get("vector");
+    Ident_pixel = &PP.getIdentifierTable().get("pixel");
+  }
+}
+
+/// ParseTopLevelDecl - Parse one top-level declaration, return whatever the
+/// action tells us to.  This returns true if the EOF was encountered.
+bool Parser::ParseTopLevelDecl(DeclGroupPtrTy &Result) {
+  Result = DeclGroupPtrTy();
+  if (Tok.is(tok::eof)) {
+    Actions.ActOnEndOfTranslationUnit();
+    return true;
+  }
+
+  CXX0XAttributeList Attr;
+  if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier())
+    Attr = ParseCXX0XAttributes();
+  Result = ParseExternalDeclaration(Attr);
+  return false;
+}
+
+/// ParseTranslationUnit:
+///       translation-unit: [C99 6.9]
+///         external-declaration
+///         translation-unit external-declaration
+void Parser::ParseTranslationUnit() {
+  Initialize();
+
+  DeclGroupPtrTy Res;
+  while (!ParseTopLevelDecl(Res))
+    /*parse them all*/;
+
+  ExitScope();
+  assert(CurScope == 0 && "Scope imbalance!");
+}
+
+/// ParseExternalDeclaration:
+///
+///       external-declaration: [C99 6.9], declaration: [C++ dcl.dcl]
+///         function-definition
+///         declaration
+/// [C++0x] empty-declaration
+/// [GNU]   asm-definition
+/// [GNU]   __extension__ external-declaration
+/// [OBJC]  objc-class-definition
+/// [OBJC]  objc-class-declaration
+/// [OBJC]  objc-alias-declaration
+/// [OBJC]  objc-protocol-definition
+/// [OBJC]  objc-method-definition
+/// [OBJC]  @end
+/// [C++]   linkage-specification
+/// [GNU] asm-definition:
+///         simple-asm-expr ';'
+///
+/// [C++0x] empty-declaration:
+///           ';'
+///
+/// [C++0x/GNU] 'extern' 'template' declaration
+Parser::DeclGroupPtrTy Parser::ParseExternalDeclaration(CXX0XAttributeList Attr) {
+  DeclPtrTy SingleDecl;
+  switch (Tok.getKind()) {
+  case tok::semi:
+    if (!getLang().CPlusPlus0x)
+      Diag(Tok, diag::ext_top_level_semi)
+        << FixItHint::CreateRemoval(Tok.getLocation());
+
+    ConsumeToken();
+    // TODO: Invoke action for top-level semicolon.
+    return DeclGroupPtrTy();
+  case tok::r_brace:
+    Diag(Tok, diag::err_expected_external_declaration);
+    ConsumeBrace();
+    return DeclGroupPtrTy();
+  case tok::eof:
+    Diag(Tok, diag::err_expected_external_declaration);
+    return DeclGroupPtrTy();
+  case tok::kw___extension__: {
+    // __extension__ silences extension warnings in the subexpression.
+    ExtensionRAIIObject O(Diags);  // Use RAII to do this.
+    ConsumeToken();
+    return ParseExternalDeclaration(Attr);
+  }
+  case tok::kw_asm: {
+    if (Attr.HasAttr)
+      Diag(Attr.Range.getBegin(), diag::err_attributes_not_allowed)
+        << Attr.Range;
+
+    OwningExprResult Result(ParseSimpleAsm());
+
+    ExpectAndConsume(tok::semi, diag::err_expected_semi_after,
+                     "top-level asm block");
+
+    if (Result.isInvalid())
+      return DeclGroupPtrTy();
+    SingleDecl = Actions.ActOnFileScopeAsmDecl(Tok.getLocation(), move(Result));
+    break;
+  }
+  case tok::at:
+    // @ is not a legal token unless objc is enabled, no need to check for ObjC.
+    /// FIXME: ParseObjCAtDirectives should return a DeclGroup for things like
+    /// @class foo, bar;
+    SingleDecl = ParseObjCAtDirectives();
+    break;
+  case tok::minus:
+  case tok::plus:
+    if (!getLang().ObjC1) {
+      Diag(Tok, diag::err_expected_external_declaration);
+      ConsumeToken();
+      return DeclGroupPtrTy();
+    }
+    SingleDecl = ParseObjCMethodDefinition();
+    break;
+  case tok::code_completion:
+      Actions.CodeCompleteOrdinaryName(CurScope, 
+                                   ObjCImpDecl? Action::CCC_ObjCImplementation
+                                              : Action::CCC_Namespace);
+    ConsumeToken();
+    return ParseExternalDeclaration(Attr);
+  case tok::kw_using:
+  case tok::kw_namespace:
+  case tok::kw_typedef:
+  case tok::kw_template:
+  case tok::kw_export:    // As in 'export template'
+  case tok::kw_static_assert:
+    // A function definition cannot start with a these keywords.
+    {
+      SourceLocation DeclEnd;
+      return ParseDeclaration(Declarator::FileContext, DeclEnd, Attr);
+    }
+  case tok::kw_extern:
+    if (getLang().CPlusPlus && NextToken().is(tok::kw_template)) {
+      // Extern templates
+      SourceLocation ExternLoc = ConsumeToken();
+      SourceLocation TemplateLoc = ConsumeToken();
+      SourceLocation DeclEnd;
+      return Actions.ConvertDeclToDeclGroup(
+                  ParseExplicitInstantiation(ExternLoc, TemplateLoc, DeclEnd));
+    }
+
+    // FIXME: Detect C++ linkage specifications here?
+
+    // Fall through to handle other declarations or function definitions.
+
+  default:
+    // We can't tell whether this is a function-definition or declaration yet.
+    return ParseDeclarationOrFunctionDefinition(Attr.AttrList);
+  }
+
+  // This routine returns a DeclGroup, if the thing we parsed only contains a
+  // single decl, convert it now.
+  return Actions.ConvertDeclToDeclGroup(SingleDecl);
+}
+
+/// \brief Determine whether the current token, if it occurs after a
+/// declarator, continues a declaration or declaration list.
+bool Parser::isDeclarationAfterDeclarator() {
+  return Tok.is(tok::equal) ||      // int X()=  -> not a function def
+    Tok.is(tok::comma) ||           // int X(),  -> not a function def
+    Tok.is(tok::semi)  ||           // int X();  -> not a function def
+    Tok.is(tok::kw_asm) ||          // int X() __asm__ -> not a function def
+    Tok.is(tok::kw___attribute) ||  // int X() __attr__ -> not a function def
+    (getLang().CPlusPlus &&
+     Tok.is(tok::l_paren));         // int X(0) -> not a function def [C++]
+}
+
+/// \brief Determine whether the current token, if it occurs after a
+/// declarator, indicates the start of a function definition.
+bool Parser::isStartOfFunctionDefinition() {
+  if (Tok.is(tok::l_brace))   // int X() {}
+    return true;
+  
+  if (!getLang().CPlusPlus)
+    return isDeclarationSpecifier();   // int X(f) int f; {}
+  return Tok.is(tok::colon) ||         // X() : Base() {} (used for ctors)
+         Tok.is(tok::kw_try);          // X() try { ... }
+}
+
+/// ParseDeclarationOrFunctionDefinition - Parse either a function-definition or
+/// a declaration.  We can't tell which we have until we read up to the
+/// compound-statement in function-definition. TemplateParams, if
+/// non-NULL, provides the template parameters when we're parsing a
+/// C++ template-declaration.
+///
+///       function-definition: [C99 6.9.1]
+///         decl-specs      declarator declaration-list[opt] compound-statement
+/// [C90] function-definition: [C99 6.7.1] - implicit int result
+/// [C90]   decl-specs[opt] declarator declaration-list[opt] compound-statement
+///
+///       declaration: [C99 6.7]
+///         declaration-specifiers init-declarator-list[opt] ';'
+/// [!C99]  init-declarator-list ';'                   [TODO: warn in c99 mode]
+/// [OMP]   threadprivate-directive                              [TODO]
+///
+Parser::DeclGroupPtrTy
+Parser::ParseDeclarationOrFunctionDefinition(ParsingDeclSpec &DS,
+                                             AttributeList *Attr,
+                                             AccessSpecifier AS) {
+  // Parse the common declaration-specifiers piece.
+  if (Attr)
+    DS.AddAttributes(Attr);
+
+  ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS, DSC_top_level);
+
+  // C99 6.7.2.3p6: Handle "struct-or-union identifier;", "enum { X };"
+  // declaration-specifiers init-declarator-list[opt] ';'
+  if (Tok.is(tok::semi)) {
+    ConsumeToken();
+    DeclPtrTy TheDecl = Actions.ParsedFreeStandingDeclSpec(CurScope, DS);
+    DS.complete(TheDecl);
+    return Actions.ConvertDeclToDeclGroup(TheDecl);
+  }
+
+  // ObjC2 allows prefix attributes on class interfaces and protocols.
+  // FIXME: This still needs better diagnostics. We should only accept
+  // attributes here, no types, etc.
+  if (getLang().ObjC2 && Tok.is(tok::at)) {
+    SourceLocation AtLoc = ConsumeToken(); // the "@"
+    if (!Tok.isObjCAtKeyword(tok::objc_interface) &&
+        !Tok.isObjCAtKeyword(tok::objc_protocol)) {
+      Diag(Tok, diag::err_objc_unexpected_attr);
+      SkipUntil(tok::semi); // FIXME: better skip?
+      return DeclGroupPtrTy();
+    }
+
+    DS.abort();
+
+    const char *PrevSpec = 0;
+    unsigned DiagID;
+    if (DS.SetTypeSpecType(DeclSpec::TST_unspecified, AtLoc, PrevSpec, DiagID))
+      Diag(AtLoc, DiagID) << PrevSpec;
+
+    DeclPtrTy TheDecl;
+    if (Tok.isObjCAtKeyword(tok::objc_protocol))
+      TheDecl = ParseObjCAtProtocolDeclaration(AtLoc, DS.getAttributes());
+    else
+      TheDecl = ParseObjCAtInterfaceDeclaration(AtLoc, DS.getAttributes());
+    return Actions.ConvertDeclToDeclGroup(TheDecl);
+  }
+
+  // If the declspec consisted only of 'extern' and we have a string
+  // literal following it, this must be a C++ linkage specifier like
+  // 'extern "C"'.
+  if (Tok.is(tok::string_literal) && getLang().CPlusPlus &&
+      DS.getStorageClassSpec() == DeclSpec::SCS_extern &&
+      DS.getParsedSpecifiers() == DeclSpec::PQ_StorageClassSpecifier) {
+    DeclPtrTy TheDecl = ParseLinkage(DS, Declarator::FileContext);
+    return Actions.ConvertDeclToDeclGroup(TheDecl);
+  }
+
+  return ParseDeclGroup(DS, Declarator::FileContext, true);
+}
+
+Parser::DeclGroupPtrTy
+Parser::ParseDeclarationOrFunctionDefinition(AttributeList *Attr,
+                                             AccessSpecifier AS) {
+  ParsingDeclSpec DS(*this);
+  return ParseDeclarationOrFunctionDefinition(DS, Attr, AS);
+}
+
+/// ParseFunctionDefinition - We parsed and verified that the specified
+/// Declarator is well formed.  If this is a K&R-style function, read the
+/// parameters declaration-list, then start the compound-statement.
+///
+///       function-definition: [C99 6.9.1]
+///         decl-specs      declarator declaration-list[opt] compound-statement
+/// [C90] function-definition: [C99 6.7.1] - implicit int result
+/// [C90]   decl-specs[opt] declarator declaration-list[opt] compound-statement
+/// [C++] function-definition: [C++ 8.4]
+///         decl-specifier-seq[opt] declarator ctor-initializer[opt]
+///         function-body
+/// [C++] function-definition: [C++ 8.4]
+///         decl-specifier-seq[opt] declarator function-try-block
+///
+Parser::DeclPtrTy Parser::ParseFunctionDefinition(ParsingDeclarator &D,
+                                     const ParsedTemplateInfo &TemplateInfo) {
+  const DeclaratorChunk &FnTypeInfo = D.getTypeObject(0);
+  assert(FnTypeInfo.Kind == DeclaratorChunk::Function &&
+         "This isn't a function declarator!");
+  const DeclaratorChunk::FunctionTypeInfo &FTI = FnTypeInfo.Fun;
+
+  // If this is C90 and the declspecs were completely missing, fudge in an
+  // implicit int.  We do this here because this is the only place where
+  // declaration-specifiers are completely optional in the grammar.
+  if (getLang().ImplicitInt && D.getDeclSpec().isEmpty()) {
+    const char *PrevSpec;
+    unsigned DiagID;
+    D.getMutableDeclSpec().SetTypeSpecType(DeclSpec::TST_int,
+                                           D.getIdentifierLoc(),
+                                           PrevSpec, DiagID);
+    D.SetRangeBegin(D.getDeclSpec().getSourceRange().getBegin());
+  }
+
+  // If this declaration was formed with a K&R-style identifier list for the
+  // arguments, parse declarations for all of the args next.
+  // int foo(a,b) int a; float b; {}
+  if (!FTI.hasPrototype && FTI.NumArgs != 0)
+    ParseKNRParamDeclarations(D);
+
+  // We should have either an opening brace or, in a C++ constructor,
+  // we may have a colon.
+  if (Tok.isNot(tok::l_brace) && Tok.isNot(tok::colon) &&
+      Tok.isNot(tok::kw_try)) {
+    Diag(Tok, diag::err_expected_fn_body);
+
+    // Skip over garbage, until we get to '{'.  Don't eat the '{'.
+    SkipUntil(tok::l_brace, true, true);
+
+    // If we didn't find the '{', bail out.
+    if (Tok.isNot(tok::l_brace))
+      return DeclPtrTy();
+  }
+
+  // Enter a scope for the function body.
+  ParseScope BodyScope(this, Scope::FnScope|Scope::DeclScope);
+
+  // Tell the actions module that we have entered a function definition with the
+  // specified Declarator for the function.
+  DeclPtrTy Res = TemplateInfo.TemplateParams?
+      Actions.ActOnStartOfFunctionTemplateDef(CurScope,
+                              Action::MultiTemplateParamsArg(Actions,
+                                          TemplateInfo.TemplateParams->data(),
+                                         TemplateInfo.TemplateParams->size()),
+                                              D)
+    : Actions.ActOnStartOfFunctionDef(CurScope, D);
+
+  // Break out of the ParsingDeclarator context before we parse the body.
+  D.complete(Res);
+  
+  // Break out of the ParsingDeclSpec context, too.  This const_cast is
+  // safe because we're always the sole owner.
+  D.getMutableDeclSpec().abort();
+
+  if (Tok.is(tok::kw_try))
+    return ParseFunctionTryBlock(Res);
+
+  // If we have a colon, then we're probably parsing a C++
+  // ctor-initializer.
+  if (Tok.is(tok::colon)) {
+    ParseConstructorInitializer(Res);
+
+    // Recover from error.
+    if (!Tok.is(tok::l_brace)) {
+      Actions.ActOnFinishFunctionBody(Res, Action::StmtArg(Actions));
+      return Res;
+    }
+  } else
+    Actions.ActOnDefaultCtorInitializers(Res);
+
+  return ParseFunctionStatementBody(Res);
+}
+
+/// ParseKNRParamDeclarations - Parse 'declaration-list[opt]' which provides
+/// types for a function with a K&R-style identifier list for arguments.
+void Parser::ParseKNRParamDeclarations(Declarator &D) {
+  // We know that the top-level of this declarator is a function.
+  DeclaratorChunk::FunctionTypeInfo &FTI = D.getTypeObject(0).Fun;
+
+  // Enter function-declaration scope, limiting any declarators to the
+  // function prototype scope, including parameter declarators.
+  ParseScope PrototypeScope(this, Scope::FunctionPrototypeScope|Scope::DeclScope);
+
+  // Read all the argument declarations.
+  while (isDeclarationSpecifier()) {
+    SourceLocation DSStart = Tok.getLocation();
+
+    // Parse the common declaration-specifiers piece.
+    DeclSpec DS;
+    ParseDeclarationSpecifiers(DS);
+
+    // C99 6.9.1p6: 'each declaration in the declaration list shall have at
+    // least one declarator'.
+    // NOTE: GCC just makes this an ext-warn.  It's not clear what it does with
+    // the declarations though.  It's trivial to ignore them, really hard to do
+    // anything else with them.
+    if (Tok.is(tok::semi)) {
+      Diag(DSStart, diag::err_declaration_does_not_declare_param);
+      ConsumeToken();
+      continue;
+    }
+
+    // C99 6.9.1p6: Declarations shall contain no storage-class specifiers other
+    // than register.
+    if (DS.getStorageClassSpec() != DeclSpec::SCS_unspecified &&
+        DS.getStorageClassSpec() != DeclSpec::SCS_register) {
+      Diag(DS.getStorageClassSpecLoc(),
+           diag::err_invalid_storage_class_in_func_decl);
+      DS.ClearStorageClassSpecs();
+    }
+    if (DS.isThreadSpecified()) {
+      Diag(DS.getThreadSpecLoc(),
+           diag::err_invalid_storage_class_in_func_decl);
+      DS.ClearStorageClassSpecs();
+    }
+
+    // Parse the first declarator attached to this declspec.
+    Declarator ParmDeclarator(DS, Declarator::KNRTypeListContext);
+    ParseDeclarator(ParmDeclarator);
+
+    // Handle the full declarator list.
+    while (1) {
+      // If attributes are present, parse them.
+      if (Tok.is(tok::kw___attribute)) {
+        SourceLocation Loc;
+        AttributeList *AttrList = ParseGNUAttributes(&Loc);
+        ParmDeclarator.AddAttributes(AttrList, Loc);
+      }
+
+      // Ask the actions module to compute the type for this declarator.
+      Action::DeclPtrTy Param =
+        Actions.ActOnParamDeclarator(CurScope, ParmDeclarator);
+
+      if (Param &&
+          // A missing identifier has already been diagnosed.
+          ParmDeclarator.getIdentifier()) {
+
+        // Scan the argument list looking for the correct param to apply this
+        // type.
+        for (unsigned i = 0; ; ++i) {
+          // C99 6.9.1p6: those declarators shall declare only identifiers from
+          // the identifier list.
+          if (i == FTI.NumArgs) {
+            Diag(ParmDeclarator.getIdentifierLoc(), diag::err_no_matching_param)
+              << ParmDeclarator.getIdentifier();
+            break;
+          }
+
+          if (FTI.ArgInfo[i].Ident == ParmDeclarator.getIdentifier()) {
+            // Reject redefinitions of parameters.
+            if (FTI.ArgInfo[i].Param) {
+              Diag(ParmDeclarator.getIdentifierLoc(),
+                   diag::err_param_redefinition)
+                 << ParmDeclarator.getIdentifier();
+            } else {
+              FTI.ArgInfo[i].Param = Param;
+            }
+            break;
+          }
+        }
+      }
+
+      // If we don't have a comma, it is either the end of the list (a ';') or
+      // an error, bail out.
+      if (Tok.isNot(tok::comma))
+        break;
+
+      // Consume the comma.
+      ConsumeToken();
+
+      // Parse the next declarator.
+      ParmDeclarator.clear();
+      ParseDeclarator(ParmDeclarator);
+    }
+
+    if (Tok.is(tok::semi)) {
+      ConsumeToken();
+    } else {
+      Diag(Tok, diag::err_parse_error);
+      // Skip to end of block or statement
+      SkipUntil(tok::semi, true);
+      if (Tok.is(tok::semi))
+        ConsumeToken();
+    }
+  }
+
+  // The actions module must verify that all arguments were declared.
+  Actions.ActOnFinishKNRParamDeclarations(CurScope, D, Tok.getLocation());
+}
+
+
+/// ParseAsmStringLiteral - This is just a normal string-literal, but is not
+/// allowed to be a wide string, and is not subject to character translation.
+///
+/// [GNU] asm-string-literal:
+///         string-literal
+///
+Parser::OwningExprResult Parser::ParseAsmStringLiteral() {
+  if (!isTokenStringLiteral()) {
+    Diag(Tok, diag::err_expected_string_literal);
+    return ExprError();
+  }
+
+  OwningExprResult Res(ParseStringLiteralExpression());
+  if (Res.isInvalid()) return move(Res);
+
+  // TODO: Diagnose: wide string literal in 'asm'
+
+  return move(Res);
+}
+
+/// ParseSimpleAsm
+///
+/// [GNU] simple-asm-expr:
+///         'asm' '(' asm-string-literal ')'
+///
+Parser::OwningExprResult Parser::ParseSimpleAsm(SourceLocation *EndLoc) {
+  assert(Tok.is(tok::kw_asm) && "Not an asm!");
+  SourceLocation Loc = ConsumeToken();
+
+  if (Tok.is(tok::kw_volatile)) {
+    // Remove from the end of 'asm' to the end of 'volatile'.
+    SourceRange RemovalRange(PP.getLocForEndOfToken(Loc),
+                             PP.getLocForEndOfToken(Tok.getLocation()));
+
+    Diag(Tok, diag::warn_file_asm_volatile)
+      << FixItHint::CreateRemoval(RemovalRange);
+    ConsumeToken();
+  }
+
+  if (Tok.isNot(tok::l_paren)) {
+    Diag(Tok, diag::err_expected_lparen_after) << "asm";
+    return ExprError();
+  }
+
+  Loc = ConsumeParen();
+
+  OwningExprResult Result(ParseAsmStringLiteral());
+
+  if (Result.isInvalid()) {
+    SkipUntil(tok::r_paren, true, true);
+    if (EndLoc)
+      *EndLoc = Tok.getLocation();
+    ConsumeAnyToken();
+  } else {
+    Loc = MatchRHSPunctuation(tok::r_paren, Loc);
+    if (EndLoc)
+      *EndLoc = Loc;
+  }
+
+  return move(Result);
+}
+
+/// TryAnnotateTypeOrScopeToken - If the current token position is on a
+/// typename (possibly qualified in C++) or a C++ scope specifier not followed
+/// by a typename, TryAnnotateTypeOrScopeToken will replace one or more tokens
+/// with a single annotation token representing the typename or C++ scope
+/// respectively.
+/// This simplifies handling of C++ scope specifiers and allows efficient
+/// backtracking without the need to re-parse and resolve nested-names and
+/// typenames.
+/// It will mainly be called when we expect to treat identifiers as typenames
+/// (if they are typenames). For example, in C we do not expect identifiers
+/// inside expressions to be treated as typenames so it will not be called
+/// for expressions in C.
+/// The benefit for C/ObjC is that a typename will be annotated and
+/// Actions.getTypeName will not be needed to be called again (e.g. getTypeName
+/// will not be called twice, once to check whether we have a declaration
+/// specifier, and another one to get the actual type inside
+/// ParseDeclarationSpecifiers).
+///
+/// This returns true if an error occurred.
+///
+/// Note that this routine emits an error if you call it with ::new or ::delete
+/// as the current tokens, so only call it in contexts where these are invalid.
+bool Parser::TryAnnotateTypeOrScopeToken(bool EnteringContext) {
+  assert((Tok.is(tok::identifier) || Tok.is(tok::coloncolon)
+          || Tok.is(tok::kw_typename) || Tok.is(tok::annot_cxxscope)) &&
+         "Cannot be a type or scope token!");
+
+  if (Tok.is(tok::kw_typename)) {
+    // Parse a C++ typename-specifier, e.g., "typename T::type".
+    //
+    //   typename-specifier:
+    //     'typename' '::' [opt] nested-name-specifier identifier
+    //     'typename' '::' [opt] nested-name-specifier template [opt]
+    //            simple-template-id
+    SourceLocation TypenameLoc = ConsumeToken();
+    CXXScopeSpec SS;
+    if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, false))
+      return true;
+    if (!SS.isSet()) {
+      Diag(Tok.getLocation(), diag::err_expected_qualified_after_typename);
+      return true;
+    }
+
+    TypeResult Ty;
+    if (Tok.is(tok::identifier)) {
+      // FIXME: check whether the next token is '<', first!
+      Ty = Actions.ActOnTypenameType(TypenameLoc, SS, *Tok.getIdentifierInfo(),
+                                     Tok.getLocation());
+    } else if (Tok.is(tok::annot_template_id)) {
+      TemplateIdAnnotation *TemplateId
+        = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
+      if (TemplateId->Kind == TNK_Function_template) {
+        Diag(Tok, diag::err_typename_refers_to_non_type_template)
+          << Tok.getAnnotationRange();
+        return true;
+      }
+
+      AnnotateTemplateIdTokenAsType(0);
+      assert(Tok.is(tok::annot_typename) &&
+             "AnnotateTemplateIdTokenAsType isn't working properly");
+      if (Tok.getAnnotationValue())
+        Ty = Actions.ActOnTypenameType(TypenameLoc, SS, SourceLocation(),
+                                       Tok.getAnnotationValue());
+      else
+        Ty = true;
+    } else {
+      Diag(Tok, diag::err_expected_type_name_after_typename)
+        << SS.getRange();
+      return true;
+    }
+
+    SourceLocation EndLoc = Tok.getLastLoc();
+    Tok.setKind(tok::annot_typename);
+    Tok.setAnnotationValue(Ty.isInvalid()? 0 : Ty.get());
+    Tok.setAnnotationEndLoc(EndLoc);
+    Tok.setLocation(TypenameLoc);
+    PP.AnnotateCachedTokens(Tok);
+    return false;
+  }
+
+  // Remembers whether the token was originally a scope annotation.
+  bool wasScopeAnnotation = Tok.is(tok::annot_cxxscope);
+
+  CXXScopeSpec SS;
+  if (getLang().CPlusPlus)
+    if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, EnteringContext))
+      return true;
+
+  if (Tok.is(tok::identifier)) {
+    // Determine whether the identifier is a type name.
+    if (TypeTy *Ty = Actions.getTypeName(*Tok.getIdentifierInfo(),
+                                         Tok.getLocation(), CurScope, &SS)) {
+      // This is a typename. Replace the current token in-place with an
+      // annotation type token.
+      Tok.setKind(tok::annot_typename);
+      Tok.setAnnotationValue(Ty);
+      Tok.setAnnotationEndLoc(Tok.getLocation());
+      if (SS.isNotEmpty()) // it was a C++ qualified type name.
+        Tok.setLocation(SS.getBeginLoc());
+
+      // In case the tokens were cached, have Preprocessor replace
+      // them with the annotation token.
+      PP.AnnotateCachedTokens(Tok);
+      return false;
+    }
+
+    if (!getLang().CPlusPlus) {
+      // If we're in C, we can't have :: tokens at all (the lexer won't return
+      // them).  If the identifier is not a type, then it can't be scope either,
+      // just early exit.
+      return false;
+    }
+
+    // If this is a template-id, annotate with a template-id or type token.
+    if (NextToken().is(tok::less)) {
+      TemplateTy Template;
+      UnqualifiedId TemplateName;
+      TemplateName.setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
+      if (TemplateNameKind TNK
+            = Actions.isTemplateName(CurScope, SS, TemplateName, 
+                                     /*ObjectType=*/0, EnteringContext,
+                                     Template)) {
+        // Consume the identifier.
+        ConsumeToken();
+        if (AnnotateTemplateIdToken(Template, TNK, &SS, TemplateName)) {
+          // If an unrecoverable error occurred, we need to return true here,
+          // because the token stream is in a damaged state.  We may not return
+          // a valid identifier.
+          return true;
+        }
+      }
+    }
+
+    // The current token, which is either an identifier or a
+    // template-id, is not part of the annotation. Fall through to
+    // push that token back into the stream and complete the C++ scope
+    // specifier annotation.
+  }
+
+  if (Tok.is(tok::annot_template_id)) {
+    TemplateIdAnnotation *TemplateId
+      = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
+    if (TemplateId->Kind == TNK_Type_template) {
+      // A template-id that refers to a type was parsed into a
+      // template-id annotation in a context where we weren't allowed
+      // to produce a type annotation token. Update the template-id
+      // annotation token to a type annotation token now.
+      AnnotateTemplateIdTokenAsType(&SS);
+      return false;
+    }
+  }
+
+  if (SS.isEmpty())
+    return false;
+
+  // A C++ scope specifier that isn't followed by a typename.
+  // Push the current token back into the token stream (or revert it if it is
+  // cached) and use an annotation scope token for current token.
+  if (PP.isBacktrackEnabled())
+    PP.RevertCachedTokens(1);
+  else
+    PP.EnterToken(Tok);
+  Tok.setKind(tok::annot_cxxscope);
+  Tok.setAnnotationValue(SS.getScopeRep());
+  Tok.setAnnotationRange(SS.getRange());
+
+  // In case the tokens were cached, have Preprocessor replace them
+  // with the annotation token.  We don't need to do this if we've
+  // just reverted back to the state we were in before being called.
+  if (!wasScopeAnnotation)
+    PP.AnnotateCachedTokens(Tok);
+  return false;
+}
+
+/// TryAnnotateScopeToken - Like TryAnnotateTypeOrScopeToken but only
+/// annotates C++ scope specifiers and template-ids.  This returns
+/// true if the token was annotated or there was an error that could not be
+/// recovered from.
+///
+/// Note that this routine emits an error if you call it with ::new or ::delete
+/// as the current tokens, so only call it in contexts where these are invalid.
+bool Parser::TryAnnotateCXXScopeToken(bool EnteringContext) {
+  assert(getLang().CPlusPlus &&
+         "Call sites of this function should be guarded by checking for C++");
+  assert((Tok.is(tok::identifier) || Tok.is(tok::coloncolon)) &&
+         "Cannot be a type or scope token!");
+
+  CXXScopeSpec SS;
+  if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, EnteringContext))
+    return true;
+  if (SS.isEmpty())
+    return false;
+
+  // Push the current token back into the token stream (or revert it if it is
+  // cached) and use an annotation scope token for current token.
+  if (PP.isBacktrackEnabled())
+    PP.RevertCachedTokens(1);
+  else
+    PP.EnterToken(Tok);
+  Tok.setKind(tok::annot_cxxscope);
+  Tok.setAnnotationValue(SS.getScopeRep());
+  Tok.setAnnotationRange(SS.getRange());
+
+  // In case the tokens were cached, have Preprocessor replace them with the
+  // annotation token.
+  PP.AnnotateCachedTokens(Tok);
+  return false;
+}
+
+// Anchor the Parser::FieldCallback vtable to this translation unit.
+// We use a spurious method instead of the destructor because
+// destroying FieldCallbacks can actually be slightly
+// performance-sensitive.
+void Parser::FieldCallback::_anchor() {
+}
diff --git a/lib/Parse/RAIIObjectsForParser.h b/lib/Parse/RAIIObjectsForParser.h
new file mode 100644
index 0000000..06bbbc2
--- /dev/null
+++ b/lib/Parse/RAIIObjectsForParser.h
@@ -0,0 +1,85 @@
+//===--- RAIIObjectsForParser.h - RAII helpers for the parser ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines and implements the some simple RAII objects that are used
+// by the parser to manage bits in recursion.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_PARSE_RAII_OBJECTS_FOR_PARSER_H
+#define LLVM_CLANG_PARSE_RAII_OBJECTS_FOR_PARSER_H
+
+#include "clang/Parse/ParseDiagnostic.h"
+
+namespace clang {
+  // TODO: move ParsingDeclRAIIObject here.
+  // TODO: move ParsingClassDefinition here.
+  // TODO: move TentativeParsingAction here.
+  
+  
+  /// ExtensionRAIIObject - This saves the state of extension warnings when
+  /// constructed and disables them.  When destructed, it restores them back to
+  /// the way they used to be.  This is used to handle __extension__ in the
+  /// parser.
+  class ExtensionRAIIObject {
+    void operator=(const ExtensionRAIIObject &);     // DO NOT IMPLEMENT
+    ExtensionRAIIObject(const ExtensionRAIIObject&); // DO NOT IMPLEMENT
+    Diagnostic &Diags;
+  public:
+    ExtensionRAIIObject(Diagnostic &diags) : Diags(diags) {
+      Diags.IncrementAllExtensionsSilenced();
+    }
+
+    ~ExtensionRAIIObject() {
+      Diags.DecrementAllExtensionsSilenced();
+    }
+  };
+  
+  /// ColonProtectionRAIIObject - This sets the Parser::ColonIsSacred bool and
+  /// restores it when destroyed.  This says that "foo:" should not be
+  /// considered a possible typo for "foo::" for error recovery purposes.
+  class ColonProtectionRAIIObject {
+    Parser &P;
+    bool OldVal;
+  public:
+    ColonProtectionRAIIObject(Parser &p, bool Value = true)
+      : P(p), OldVal(P.ColonIsSacred) {
+      P.ColonIsSacred = Value;
+    }
+    
+    /// restore - This can be used to restore the state early, before the dtor
+    /// is run.
+    void restore() {
+      P.ColonIsSacred = OldVal;
+    }
+    
+    ~ColonProtectionRAIIObject() {
+      restore();
+    }
+  };
+  
+  /// \brief RAII object that makes '>' behave either as an operator
+  /// or as the closing angle bracket for a template argument list.
+  class GreaterThanIsOperatorScope {
+    bool &GreaterThanIsOperator;
+    bool OldGreaterThanIsOperator;
+  public:
+    GreaterThanIsOperatorScope(bool &GTIO, bool Val)
+    : GreaterThanIsOperator(GTIO), OldGreaterThanIsOperator(GTIO) {
+      GreaterThanIsOperator = Val;
+    }
+    
+    ~GreaterThanIsOperatorScope() {
+      GreaterThanIsOperator = OldGreaterThanIsOperator;
+    }
+  };
+  
+} // end namespace clang
+
+#endif
diff --git a/lib/Rewrite/CMakeLists.txt b/lib/Rewrite/CMakeLists.txt
new file mode 100644
index 0000000..ce9e1ed
--- /dev/null
+++ b/lib/Rewrite/CMakeLists.txt
@@ -0,0 +1,9 @@
+set(LLVM_NO_RTTI 1)
+
+add_clang_library(clangRewrite
+  DeltaTree.cpp
+  HTMLRewrite.cpp
+  RewriteRope.cpp
+  Rewriter.cpp
+  TokenRewriter.cpp
+  )
diff --git a/lib/Rewrite/DeltaTree.cpp b/lib/Rewrite/DeltaTree.cpp
new file mode 100644
index 0000000..35e888b
--- /dev/null
+++ b/lib/Rewrite/DeltaTree.cpp
@@ -0,0 +1,475 @@
+//===--- DeltaTree.cpp - B-Tree for Rewrite Delta tracking ----------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the DeltaTree and related classes.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Rewrite/DeltaTree.h"
+#include "llvm/Support/Casting.h"
+#include <cstring>
+#include <cstdio>
+using namespace clang;
+using llvm::cast;
+using llvm::dyn_cast;
+
+/// The DeltaTree class is a multiway search tree (BTree) structure with some
+/// fancy features.  B-Trees are generally more memory and cache efficient
+/// than binary trees, because they store multiple keys/values in each node.
+///
+/// DeltaTree implements a key/value mapping from FileIndex to Delta, allowing
+/// fast lookup by FileIndex.  However, an added (important) bonus is that it
+/// can also efficiently tell us the full accumulated delta for a specific
+/// file offset as well, without traversing the whole tree.
+///
+/// The nodes of the tree are made up of instances of two classes:
+/// DeltaTreeNode and DeltaTreeInteriorNode.  The later subclasses the
+/// former and adds children pointers.  Each node knows the full delta of all
+/// entries (recursively) contained inside of it, which allows us to get the
+/// full delta implied by a whole subtree in constant time.
+
+namespace {
+  /// SourceDelta - As code in the original input buffer is added and deleted,
+  /// SourceDelta records are used to keep track of how the input SourceLocation
+  /// object is mapped into the output buffer.
+  struct SourceDelta {
+    unsigned FileLoc;
+    int Delta;
+
+    static SourceDelta get(unsigned Loc, int D) {
+      SourceDelta Delta;
+      Delta.FileLoc = Loc;
+      Delta.Delta = D;
+      return Delta;
+    }
+  };
+  
+  /// DeltaTreeNode - The common part of all nodes.
+  ///
+  class DeltaTreeNode {
+  public:
+    struct InsertResult {
+      DeltaTreeNode *LHS, *RHS;
+      SourceDelta Split;
+    };
+    
+  private:
+    friend class DeltaTreeInteriorNode;
+
+    /// WidthFactor - This controls the number of K/V slots held in the BTree:
+    /// how wide it is.  Each level of the BTree is guaranteed to have at least
+    /// WidthFactor-1 K/V pairs (except the root) and may have at most
+    /// 2*WidthFactor-1 K/V pairs.
+    enum { WidthFactor = 8 };
+
+    /// Values - This tracks the SourceDelta's currently in this node.
+    ///
+    SourceDelta Values[2*WidthFactor-1];
+
+    /// NumValuesUsed - This tracks the number of values this node currently
+    /// holds.
+    unsigned char NumValuesUsed;
+
+    /// IsLeaf - This is true if this is a leaf of the btree.  If false, this is
+    /// an interior node, and is actually an instance of DeltaTreeInteriorNode.
+    bool IsLeaf;
+
+    /// FullDelta - This is the full delta of all the values in this node and
+    /// all children nodes.
+    int FullDelta;
+  public:
+    DeltaTreeNode(bool isLeaf = true)
+      : NumValuesUsed(0), IsLeaf(isLeaf), FullDelta(0) {}
+
+    bool isLeaf() const { return IsLeaf; }
+    int getFullDelta() const { return FullDelta; }
+    bool isFull() const { return NumValuesUsed == 2*WidthFactor-1; }
+
+    unsigned getNumValuesUsed() const { return NumValuesUsed; }
+    const SourceDelta &getValue(unsigned i) const {
+      assert(i < NumValuesUsed && "Invalid value #");
+      return Values[i];
+    }
+    SourceDelta &getValue(unsigned i) {
+      assert(i < NumValuesUsed && "Invalid value #");
+      return Values[i];
+    }
+
+    /// DoInsertion - Do an insertion of the specified FileIndex/Delta pair into
+    /// this node.  If insertion is easy, do it and return false.  Otherwise,
+    /// split the node, populate InsertRes with info about the split, and return
+    /// true.
+    bool DoInsertion(unsigned FileIndex, int Delta, InsertResult *InsertRes);
+
+    void DoSplit(InsertResult &InsertRes);
+
+
+    /// RecomputeFullDeltaLocally - Recompute the FullDelta field by doing a
+    /// local walk over our contained deltas.
+    void RecomputeFullDeltaLocally();
+
+    void Destroy();
+
+    static inline bool classof(const DeltaTreeNode *) { return true; }
+  };
+} // end anonymous namespace
+
+namespace {
+  /// DeltaTreeInteriorNode - When isLeaf = false, a node has child pointers.
+  /// This class tracks them.
+  class DeltaTreeInteriorNode : public DeltaTreeNode {
+    DeltaTreeNode *Children[2*WidthFactor];
+    ~DeltaTreeInteriorNode() {
+      for (unsigned i = 0, e = NumValuesUsed+1; i != e; ++i)
+        Children[i]->Destroy();
+    }
+    friend class DeltaTreeNode;
+  public:
+    DeltaTreeInteriorNode() : DeltaTreeNode(false /*nonleaf*/) {}
+
+    DeltaTreeInteriorNode(DeltaTreeNode *FirstChild)
+    : DeltaTreeNode(false /*nonleaf*/) {
+      FullDelta = FirstChild->FullDelta;
+      Children[0] = FirstChild;
+    }
+
+    DeltaTreeInteriorNode(const InsertResult &IR)
+      : DeltaTreeNode(false /*nonleaf*/) {
+      Children[0] = IR.LHS;
+      Children[1] = IR.RHS;
+      Values[0] = IR.Split;
+      FullDelta = IR.LHS->getFullDelta()+IR.RHS->getFullDelta()+IR.Split.Delta;
+      NumValuesUsed = 1;
+    }
+
+    const DeltaTreeNode *getChild(unsigned i) const {
+      assert(i < getNumValuesUsed()+1 && "Invalid child");
+      return Children[i];
+    }
+    DeltaTreeNode *getChild(unsigned i) {
+      assert(i < getNumValuesUsed()+1 && "Invalid child");
+      return Children[i];
+    }
+
+    static inline bool classof(const DeltaTreeInteriorNode *) { return true; }
+    static inline bool classof(const DeltaTreeNode *N) { return !N->isLeaf(); }
+  };
+}
+
+
+/// Destroy - A 'virtual' destructor.
+void DeltaTreeNode::Destroy() {
+  if (isLeaf())
+    delete this;
+  else
+    delete cast<DeltaTreeInteriorNode>(this);
+}
+
+/// RecomputeFullDeltaLocally - Recompute the FullDelta field by doing a
+/// local walk over our contained deltas.
+void DeltaTreeNode::RecomputeFullDeltaLocally() {
+  int NewFullDelta = 0;
+  for (unsigned i = 0, e = getNumValuesUsed(); i != e; ++i)
+    NewFullDelta += Values[i].Delta;
+  if (DeltaTreeInteriorNode *IN = dyn_cast<DeltaTreeInteriorNode>(this))
+    for (unsigned i = 0, e = getNumValuesUsed()+1; i != e; ++i)
+      NewFullDelta += IN->getChild(i)->getFullDelta();
+  FullDelta = NewFullDelta;
+}
+
+/// DoInsertion - Do an insertion of the specified FileIndex/Delta pair into
+/// this node.  If insertion is easy, do it and return false.  Otherwise,
+/// split the node, populate InsertRes with info about the split, and return
+/// true.
+bool DeltaTreeNode::DoInsertion(unsigned FileIndex, int Delta,
+                                InsertResult *InsertRes) {
+  // Maintain full delta for this node.
+  FullDelta += Delta;
+
+  // Find the insertion point, the first delta whose index is >= FileIndex.
+  unsigned i = 0, e = getNumValuesUsed();
+  while (i != e && FileIndex > getValue(i).FileLoc)
+    ++i;
+
+  // If we found an a record for exactly this file index, just merge this
+  // value into the pre-existing record and finish early.
+  if (i != e && getValue(i).FileLoc == FileIndex) {
+    // NOTE: Delta could drop to zero here.  This means that the delta entry is
+    // useless and could be removed.  Supporting erases is more complex than
+    // leaving an entry with Delta=0, so we just leave an entry with Delta=0 in
+    // the tree.
+    Values[i].Delta += Delta;
+    return false;
+  }
+
+  // Otherwise, we found an insertion point, and we know that the value at the
+  // specified index is > FileIndex.  Handle the leaf case first.
+  if (isLeaf()) {
+    if (!isFull()) {
+      // For an insertion into a non-full leaf node, just insert the value in
+      // its sorted position.  This requires moving later values over.
+      if (i != e)
+        memmove(&Values[i+1], &Values[i], sizeof(Values[0])*(e-i));
+      Values[i] = SourceDelta::get(FileIndex, Delta);
+      ++NumValuesUsed;
+      return false;
+    }
+
+    // Otherwise, if this is leaf is full, split the node at its median, insert
+    // the value into one of the children, and return the result.
+    assert(InsertRes && "No result location specified");
+    DoSplit(*InsertRes);
+
+    if (InsertRes->Split.FileLoc > FileIndex)
+      InsertRes->LHS->DoInsertion(FileIndex, Delta, 0 /*can't fail*/);
+    else
+      InsertRes->RHS->DoInsertion(FileIndex, Delta, 0 /*can't fail*/);
+    return true;
+  }
+
+  // Otherwise, this is an interior node.  Send the request down the tree.
+  DeltaTreeInteriorNode *IN = cast<DeltaTreeInteriorNode>(this);
+  if (!IN->Children[i]->DoInsertion(FileIndex, Delta, InsertRes))
+    return false; // If there was space in the child, just return.
+
+  // Okay, this split the subtree, producing a new value and two children to
+  // insert here.  If this node is non-full, we can just insert it directly.
+  if (!isFull()) {
+    // Now that we have two nodes and a new element, insert the perclated value
+    // into ourself by moving all the later values/children down, then inserting
+    // the new one.
+    if (i != e)
+      memmove(&IN->Children[i+2], &IN->Children[i+1],
+              (e-i)*sizeof(IN->Children[0]));
+    IN->Children[i] = InsertRes->LHS;
+    IN->Children[i+1] = InsertRes->RHS;
+
+    if (e != i)
+      memmove(&Values[i+1], &Values[i], (e-i)*sizeof(Values[0]));
+    Values[i] = InsertRes->Split;
+    ++NumValuesUsed;
+    return false;
+  }
+
+  // Finally, if this interior node was full and a node is percolated up, split
+  // ourself and return that up the chain.  Start by saving all our info to
+  // avoid having the split clobber it.
+  IN->Children[i] = InsertRes->LHS;
+  DeltaTreeNode *SubRHS = InsertRes->RHS;
+  SourceDelta SubSplit = InsertRes->Split;
+
+  // Do the split.
+  DoSplit(*InsertRes);
+
+  // Figure out where to insert SubRHS/NewSplit.
+  DeltaTreeInteriorNode *InsertSide;
+  if (SubSplit.FileLoc < InsertRes->Split.FileLoc)
+    InsertSide = cast<DeltaTreeInteriorNode>(InsertRes->LHS);
+  else
+    InsertSide = cast<DeltaTreeInteriorNode>(InsertRes->RHS);
+
+  // We now have a non-empty interior node 'InsertSide' to insert
+  // SubRHS/SubSplit into.  Find out where to insert SubSplit.
+
+  // Find the insertion point, the first delta whose index is >SubSplit.FileLoc.
+  i = 0; e = InsertSide->getNumValuesUsed();
+  while (i != e && SubSplit.FileLoc > InsertSide->getValue(i).FileLoc)
+    ++i;
+
+  // Now we know that i is the place to insert the split value into.  Insert it
+  // and the child right after it.
+  if (i != e)
+    memmove(&InsertSide->Children[i+2], &InsertSide->Children[i+1],
+            (e-i)*sizeof(IN->Children[0]));
+  InsertSide->Children[i+1] = SubRHS;
+
+  if (e != i)
+    memmove(&InsertSide->Values[i+1], &InsertSide->Values[i],
+            (e-i)*sizeof(Values[0]));
+  InsertSide->Values[i] = SubSplit;
+  ++InsertSide->NumValuesUsed;
+  InsertSide->FullDelta += SubSplit.Delta + SubRHS->getFullDelta();
+  return true;
+}
+
+/// DoSplit - Split the currently full node (which has 2*WidthFactor-1 values)
+/// into two subtrees each with "WidthFactor-1" values and a pivot value.
+/// Return the pieces in InsertRes.
+void DeltaTreeNode::DoSplit(InsertResult &InsertRes) {
+  assert(isFull() && "Why split a non-full node?");
+
+  // Since this node is full, it contains 2*WidthFactor-1 values.  We move
+  // the first 'WidthFactor-1' values to the LHS child (which we leave in this
+  // node), propagate one value up, and move the last 'WidthFactor-1' values
+  // into the RHS child.
+
+  // Create the new child node.
+  DeltaTreeNode *NewNode;
+  if (DeltaTreeInteriorNode *IN = dyn_cast<DeltaTreeInteriorNode>(this)) {
+    // If this is an interior node, also move over 'WidthFactor' children
+    // into the new node.
+    DeltaTreeInteriorNode *New = new DeltaTreeInteriorNode();
+    memcpy(&New->Children[0], &IN->Children[WidthFactor],
+           WidthFactor*sizeof(IN->Children[0]));
+    NewNode = New;
+  } else {
+    // Just create the new leaf node.
+    NewNode = new DeltaTreeNode();
+  }
+
+  // Move over the last 'WidthFactor-1' values from here to NewNode.
+  memcpy(&NewNode->Values[0], &Values[WidthFactor],
+         (WidthFactor-1)*sizeof(Values[0]));
+
+  // Decrease the number of values in the two nodes.
+  NewNode->NumValuesUsed = NumValuesUsed = WidthFactor-1;
+
+  // Recompute the two nodes' full delta.
+  NewNode->RecomputeFullDeltaLocally();
+  RecomputeFullDeltaLocally();
+
+  InsertRes.LHS = this;
+  InsertRes.RHS = NewNode;
+  InsertRes.Split = Values[WidthFactor-1];
+}
+
+
+
+//===----------------------------------------------------------------------===//
+//                        DeltaTree Implementation
+//===----------------------------------------------------------------------===//
+
+//#define VERIFY_TREE
+
+#ifdef VERIFY_TREE
+/// VerifyTree - Walk the btree performing assertions on various properties to
+/// verify consistency.  This is useful for debugging new changes to the tree.
+static void VerifyTree(const DeltaTreeNode *N) {
+  const DeltaTreeInteriorNode *IN = dyn_cast<DeltaTreeInteriorNode>(N);
+  if (IN == 0) {
+    // Verify leaves, just ensure that FullDelta matches up and the elements
+    // are in proper order.
+    int FullDelta = 0;
+    for (unsigned i = 0, e = N->getNumValuesUsed(); i != e; ++i) {
+      if (i)
+        assert(N->getValue(i-1).FileLoc < N->getValue(i).FileLoc);
+      FullDelta += N->getValue(i).Delta;
+    }
+    assert(FullDelta == N->getFullDelta());
+    return;
+  }
+
+  // Verify interior nodes: Ensure that FullDelta matches up and the
+  // elements are in proper order and the children are in proper order.
+  int FullDelta = 0;
+  for (unsigned i = 0, e = IN->getNumValuesUsed(); i != e; ++i) {
+    const SourceDelta &IVal = N->getValue(i);
+    const DeltaTreeNode *IChild = IN->getChild(i);
+    if (i)
+      assert(IN->getValue(i-1).FileLoc < IVal.FileLoc);
+    FullDelta += IVal.Delta;
+    FullDelta += IChild->getFullDelta();
+
+    // The largest value in child #i should be smaller than FileLoc.
+    assert(IChild->getValue(IChild->getNumValuesUsed()-1).FileLoc <
+           IVal.FileLoc);
+
+    // The smallest value in child #i+1 should be larger than FileLoc.
+    assert(IN->getChild(i+1)->getValue(0).FileLoc > IVal.FileLoc);
+    VerifyTree(IChild);
+  }
+
+  FullDelta += IN->getChild(IN->getNumValuesUsed())->getFullDelta();
+
+  assert(FullDelta == N->getFullDelta());
+}
+#endif  // VERIFY_TREE
+
+static DeltaTreeNode *getRoot(void *Root) {
+  return (DeltaTreeNode*)Root;
+}
+
+DeltaTree::DeltaTree() {
+  Root = new DeltaTreeNode();
+}
+DeltaTree::DeltaTree(const DeltaTree &RHS) {
+  // Currently we only support copying when the RHS is empty.
+  assert(getRoot(RHS.Root)->getNumValuesUsed() == 0 &&
+         "Can only copy empty tree");
+  Root = new DeltaTreeNode();
+}
+
+DeltaTree::~DeltaTree() {
+  getRoot(Root)->Destroy();
+}
+
+/// getDeltaAt - Return the accumulated delta at the specified file offset.
+/// This includes all insertions or delections that occurred *before* the
+/// specified file index.
+int DeltaTree::getDeltaAt(unsigned FileIndex) const {
+  const DeltaTreeNode *Node = getRoot(Root);
+
+  int Result = 0;
+
+  // Walk down the tree.
+  while (1) {
+    // For all nodes, include any local deltas before the specified file
+    // index by summing them up directly.  Keep track of how many were
+    // included.
+    unsigned NumValsGreater = 0;
+    for (unsigned e = Node->getNumValuesUsed(); NumValsGreater != e;
+         ++NumValsGreater) {
+      const SourceDelta &Val = Node->getValue(NumValsGreater);
+
+      if (Val.FileLoc >= FileIndex)
+        break;
+      Result += Val.Delta;
+    }
+
+    // If we have an interior node, include information about children and
+    // recurse.  Otherwise, if we have a leaf, we're done.
+    const DeltaTreeInteriorNode *IN = dyn_cast<DeltaTreeInteriorNode>(Node);
+    if (!IN) return Result;
+
+    // Include any children to the left of the values we skipped, all of
+    // their deltas should be included as well.
+    for (unsigned i = 0; i != NumValsGreater; ++i)
+      Result += IN->getChild(i)->getFullDelta();
+
+    // If we found exactly the value we were looking for, break off the
+    // search early.  There is no need to search the RHS of the value for
+    // partial results.
+    if (NumValsGreater != Node->getNumValuesUsed() &&
+        Node->getValue(NumValsGreater).FileLoc == FileIndex)
+      return Result+IN->getChild(NumValsGreater)->getFullDelta();
+
+    // Otherwise, traverse down the tree.  The selected subtree may be
+    // partially included in the range.
+    Node = IN->getChild(NumValsGreater);
+  }
+  // NOT REACHED.
+}
+
+/// AddDelta - When a change is made that shifts around the text buffer,
+/// this method is used to record that info.  It inserts a delta of 'Delta'
+/// into the current DeltaTree at offset FileIndex.
+void DeltaTree::AddDelta(unsigned FileIndex, int Delta) {
+  assert(Delta && "Adding a noop?");
+  DeltaTreeNode *MyRoot = getRoot(Root);
+
+  DeltaTreeNode::InsertResult InsertRes;
+  if (MyRoot->DoInsertion(FileIndex, Delta, &InsertRes)) {
+    Root = MyRoot = new DeltaTreeInteriorNode(InsertRes);
+  }
+
+#ifdef VERIFY_TREE
+  VerifyTree(MyRoot);
+#endif
+}
+
diff --git a/lib/Rewrite/HTMLRewrite.cpp b/lib/Rewrite/HTMLRewrite.cpp
new file mode 100644
index 0000000..5fe0649
--- /dev/null
+++ b/lib/Rewrite/HTMLRewrite.cpp
@@ -0,0 +1,580 @@
+//== HTMLRewrite.cpp - Translate source code into prettified HTML --*- C++ -*-//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the HTMLRewriter clas, which is used to translate the
+//  text of a source file into prettified HTML.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Rewrite/Rewriter.h"
+#include "clang/Rewrite/HTMLRewrite.h"
+#include "clang/Lex/TokenConcatenation.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Basic/SourceManager.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace clang;
+
+
+/// HighlightRange - Highlight a range in the source code with the specified
+/// start/end tags.  B/E must be in the same file.  This ensures that
+/// start/end tags are placed at the start/end of each line if the range is
+/// multiline.
+void html::HighlightRange(Rewriter &R, SourceLocation B, SourceLocation E,
+                          const char *StartTag, const char *EndTag) {
+  SourceManager &SM = R.getSourceMgr();
+  B = SM.getInstantiationLoc(B);
+  E = SM.getInstantiationLoc(E);
+  FileID FID = SM.getFileID(B);
+  assert(SM.getFileID(E) == FID && "B/E not in the same file!");
+
+  unsigned BOffset = SM.getFileOffset(B);
+  unsigned EOffset = SM.getFileOffset(E);
+
+  // Include the whole end token in the range.
+  EOffset += Lexer::MeasureTokenLength(E, R.getSourceMgr(), R.getLangOpts());
+
+  bool Invalid = false;
+  const char *BufferStart = SM.getBufferData(FID, &Invalid).data();
+  if (Invalid)
+    return;
+  
+  HighlightRange(R.getEditBuffer(FID), BOffset, EOffset,
+                 BufferStart, StartTag, EndTag);
+}
+
+/// HighlightRange - This is the same as the above method, but takes
+/// decomposed file locations.
+void html::HighlightRange(RewriteBuffer &RB, unsigned B, unsigned E,
+                          const char *BufferStart,
+                          const char *StartTag, const char *EndTag) {
+  // Insert the tag at the absolute start/end of the range.
+  RB.InsertTextAfter(B, StartTag);
+  RB.InsertTextBefore(E, EndTag);
+
+  // Scan the range to see if there is a \r or \n.  If so, and if the line is
+  // not blank, insert tags on that line as well.
+  bool HadOpenTag = true;
+
+  unsigned LastNonWhiteSpace = B;
+  for (unsigned i = B; i != E; ++i) {
+    switch (BufferStart[i]) {
+    case '\r':
+    case '\n':
+      // Okay, we found a newline in the range.  If we have an open tag, we need
+      // to insert a close tag at the first non-whitespace before the newline.
+      if (HadOpenTag)
+        RB.InsertTextBefore(LastNonWhiteSpace+1, EndTag);
+
+      // Instead of inserting an open tag immediately after the newline, we
+      // wait until we see a non-whitespace character.  This prevents us from
+      // inserting tags around blank lines, and also allows the open tag to
+      // be put *after* whitespace on a non-blank line.
+      HadOpenTag = false;
+      break;
+    case '\0':
+    case ' ':
+    case '\t':
+    case '\f':
+    case '\v':
+      // Ignore whitespace.
+      break;
+
+    default:
+      // If there is no tag open, do it now.
+      if (!HadOpenTag) {
+        RB.InsertTextAfter(i, StartTag);
+        HadOpenTag = true;
+      }
+
+      // Remember this character.
+      LastNonWhiteSpace = i;
+      break;
+    }
+  }
+}
+
+void html::EscapeText(Rewriter &R, FileID FID,
+                      bool EscapeSpaces, bool ReplaceTabs) {
+
+  const llvm::MemoryBuffer *Buf = R.getSourceMgr().getBuffer(FID);
+  const char* C = Buf->getBufferStart();
+  const char* FileEnd = Buf->getBufferEnd();
+
+  assert (C <= FileEnd);
+
+  RewriteBuffer &RB = R.getEditBuffer(FID);
+
+  unsigned ColNo = 0;
+  for (unsigned FilePos = 0; C != FileEnd ; ++C, ++FilePos) {
+    switch (*C) {
+    default: ++ColNo; break;
+    case '\n':
+    case '\r':
+      ColNo = 0;
+      break;
+
+    case ' ':
+      if (EscapeSpaces)
+        RB.ReplaceText(FilePos, 1, "&nbsp;");
+      ++ColNo;
+      break;
+    case '\f':
+      RB.ReplaceText(FilePos, 1, "<hr>");
+      ColNo = 0;
+      break;
+
+    case '\t': {
+      if (!ReplaceTabs)
+        break;
+      unsigned NumSpaces = 8-(ColNo&7);
+      if (EscapeSpaces)
+        RB.ReplaceText(FilePos, 1,
+                       llvm::StringRef("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"
+                                       "&nbsp;&nbsp;&nbsp;", 6*NumSpaces));
+      else
+        RB.ReplaceText(FilePos, 1, llvm::StringRef("        ", NumSpaces));
+      ColNo += NumSpaces;
+      break;
+    }
+    case '<':
+      RB.ReplaceText(FilePos, 1, "&lt;");
+      ++ColNo;
+      break;
+
+    case '>':
+      RB.ReplaceText(FilePos, 1, "&gt;");
+      ++ColNo;
+      break;
+
+    case '&':
+      RB.ReplaceText(FilePos, 1, "&amp;");
+      ++ColNo;
+      break;
+    }
+  }
+}
+
+std::string html::EscapeText(const std::string& s, bool EscapeSpaces,
+                             bool ReplaceTabs) {
+
+  unsigned len = s.size();
+  std::string Str;
+  llvm::raw_string_ostream os(Str);
+
+  for (unsigned i = 0 ; i < len; ++i) {
+
+    char c = s[i];
+    switch (c) {
+    default:
+      os << c; break;
+
+    case ' ':
+      if (EscapeSpaces) os << "&nbsp;";
+      else os << ' ';
+      break;
+
+    case '\t':
+      if (ReplaceTabs) {
+        if (EscapeSpaces)
+          for (unsigned i = 0; i < 4; ++i)
+            os << "&nbsp;";
+        else
+          for (unsigned i = 0; i < 4; ++i)
+            os << " ";
+      }
+      else
+        os << c;
+
+      break;
+
+    case '<': os << "&lt;"; break;
+    case '>': os << "&gt;"; break;
+    case '&': os << "&amp;"; break;
+    }
+  }
+
+  return os.str();
+}
+
+static void AddLineNumber(RewriteBuffer &RB, unsigned LineNo,
+                          unsigned B, unsigned E) {
+  llvm::SmallString<256> Str;
+  llvm::raw_svector_ostream OS(Str);
+
+  OS << "<tr><td class=\"num\" id=\"LN"
+     << LineNo << "\">"
+     << LineNo << "</td><td class=\"line\">";
+
+  if (B == E) { // Handle empty lines.
+    OS << " </td></tr>";
+    RB.InsertTextBefore(B, OS.str());
+  } else {
+    RB.InsertTextBefore(B, OS.str());
+    RB.InsertTextBefore(E, "</td></tr>");
+  }
+}
+
+void html::AddLineNumbers(Rewriter& R, FileID FID) {
+
+  const llvm::MemoryBuffer *Buf = R.getSourceMgr().getBuffer(FID);
+  const char* FileBeg = Buf->getBufferStart();
+  const char* FileEnd = Buf->getBufferEnd();
+  const char* C = FileBeg;
+  RewriteBuffer &RB = R.getEditBuffer(FID);
+
+  assert (C <= FileEnd);
+
+  unsigned LineNo = 0;
+  unsigned FilePos = 0;
+
+  while (C != FileEnd) {
+
+    ++LineNo;
+    unsigned LineStartPos = FilePos;
+    unsigned LineEndPos = FileEnd - FileBeg;
+
+    assert (FilePos <= LineEndPos);
+    assert (C < FileEnd);
+
+    // Scan until the newline (or end-of-file).
+
+    while (C != FileEnd) {
+      char c = *C;
+      ++C;
+
+      if (c == '\n') {
+        LineEndPos = FilePos++;
+        break;
+      }
+
+      ++FilePos;
+    }
+
+    AddLineNumber(RB, LineNo, LineStartPos, LineEndPos);
+  }
+
+  // Add one big table tag that surrounds all of the code.
+  RB.InsertTextBefore(0, "<table class=\"code\">\n");
+  RB.InsertTextAfter(FileEnd - FileBeg, "</table>");
+}
+
+void html::AddHeaderFooterInternalBuiltinCSS(Rewriter& R, FileID FID,
+                                             const char *title) {
+
+  const llvm::MemoryBuffer *Buf = R.getSourceMgr().getBuffer(FID);
+  const char* FileStart = Buf->getBufferStart();
+  const char* FileEnd = Buf->getBufferEnd();
+
+  SourceLocation StartLoc = R.getSourceMgr().getLocForStartOfFile(FID);
+  SourceLocation EndLoc = StartLoc.getFileLocWithOffset(FileEnd-FileStart);
+
+  std::string s;
+  llvm::raw_string_ostream os(s);
+  os << "<!doctype html>\n" // Use HTML 5 doctype
+        "<html>\n<head>\n";
+
+  if (title)
+    os << "<title>" << html::EscapeText(title) << "</title>\n";
+
+  os << "<style type=\"text/css\">\n"
+      " body { color:#000000; background-color:#ffffff }\n"
+      " body { font-family:Helvetica, sans-serif; font-size:10pt }\n"
+      " h1 { font-size:14pt }\n"
+      " .code { border-collapse:collapse; width:100%; }\n"
+      " .code { font-family: \"Andale Mono\", monospace; font-size:10pt }\n"
+      " .code { line-height: 1.2em }\n"
+      " .comment { color: green; font-style: oblique }\n"
+      " .keyword { color: blue }\n"
+      " .string_literal { color: red }\n"
+      " .directive { color: darkmagenta }\n"
+      // Macro expansions.
+      " .expansion { display: none; }\n"
+      " .macro:hover .expansion { display: block; border: 2px solid #FF0000; "
+          "padding: 2px; background-color:#FFF0F0; font-weight: normal; "
+          "  -webkit-border-radius:5px;  -webkit-box-shadow:1px 1px 7px #000; "
+          "position: absolute; top: -1em; left:10em; z-index: 1 } \n"
+      " .macro { color: darkmagenta; background-color:LemonChiffon;"
+             // Macros are position: relative to provide base for expansions.
+             " position: relative }\n"
+      " .num { width:2.5em; padding-right:2ex; background-color:#eeeeee }\n"
+      " .num { text-align:right; font-size:8pt }\n"
+      " .num { color:#444444 }\n"
+      " .line { padding-left: 1ex; border-left: 3px solid #ccc }\n"
+      " .line { white-space: pre }\n"
+      " .msg { -webkit-box-shadow:1px 1px 7px #000 }\n"
+      " .msg { -webkit-border-radius:5px }\n"
+      " .msg { font-family:Helvetica, sans-serif; font-size:8pt }\n"
+      " .msg { float:left }\n"
+      " .msg { padding:0.25em 1ex 0.25em 1ex }\n"
+      " .msg { margin-top:10px; margin-bottom:10px }\n"
+      " .msg { font-weight:bold }\n"
+      " .msg { max-width:60em; word-wrap: break-word; white-space: pre-wrap }\n"
+      " .msgT { padding:0x; spacing:0x }\n"
+      " .msgEvent { background-color:#fff8b4; color:#000000 }\n"
+      " .msgControl { background-color:#bbbbbb; color:#000000 }\n"
+      " .mrange { background-color:#dfddf3 }\n"
+      " .mrange { border-bottom:1px solid #6F9DBE }\n"
+      " .PathIndex { font-weight: bold; padding:0px 5px 0px 5px; "
+        "margin-right:5px; }\n"
+      " .PathIndex { -webkit-border-radius:8px }\n"
+      " .PathIndexEvent { background-color:#bfba87 }\n"
+      " .PathIndexControl { background-color:#8c8c8c }\n"
+      " .CodeInsertionHint { font-weight: bold; background-color: #10dd10 }\n"
+      " .CodeRemovalHint { background-color:#de1010 }\n"
+      " .CodeRemovalHint { border-bottom:1px solid #6F9DBE }\n"
+      " table.simpletable {\n"
+      "   padding: 5px;\n"
+      "   font-size:12pt;\n"
+      "   margin:20px;\n"
+      "   border-collapse: collapse; border-spacing: 0px;\n"
+      " }\n"
+      " td.rowname {\n"
+      "   text-align:right; font-weight:bold; color:#444444;\n"
+      "   padding-right:2ex; }\n"
+      "</style>\n</head>\n<body>";
+
+  // Generate header
+  R.InsertTextBefore(StartLoc, os.str());
+  // Generate footer
+
+  R.InsertTextAfter(EndLoc, "</body></html>\n");
+}
+
+/// SyntaxHighlight - Relex the specified FileID and annotate the HTML with
+/// information about keywords, macro expansions etc.  This uses the macro
+/// table state from the end of the file, so it won't be perfectly perfect,
+/// but it will be reasonably close.
+void html::SyntaxHighlight(Rewriter &R, FileID FID, const Preprocessor &PP) {
+  RewriteBuffer &RB = R.getEditBuffer(FID);
+
+  const SourceManager &SM = PP.getSourceManager();
+  const llvm::MemoryBuffer *FromFile = SM.getBuffer(FID);
+  Lexer L(FID, FromFile, SM, PP.getLangOptions());
+  const char *BufferStart = L.getBufferStart();
+
+  // Inform the preprocessor that we want to retain comments as tokens, so we
+  // can highlight them.
+  L.SetCommentRetentionState(true);
+
+  // Lex all the tokens in raw mode, to avoid entering #includes or expanding
+  // macros.
+  Token Tok;
+  L.LexFromRawLexer(Tok);
+
+  while (Tok.isNot(tok::eof)) {
+    // Since we are lexing unexpanded tokens, all tokens are from the main
+    // FileID.
+    unsigned TokOffs = SM.getFileOffset(Tok.getLocation());
+    unsigned TokLen = Tok.getLength();
+    switch (Tok.getKind()) {
+    default: break;
+    case tok::identifier: {
+      // Fill in Result.IdentifierInfo, looking up the identifier in the
+      // identifier table.
+      const IdentifierInfo *II =
+        PP.LookUpIdentifierInfo(Tok, BufferStart+TokOffs);
+
+      // If this is a pp-identifier, for a keyword, highlight it as such.
+      if (II->getTokenID() != tok::identifier)
+        HighlightRange(RB, TokOffs, TokOffs+TokLen, BufferStart,
+                       "<span class='keyword'>", "</span>");
+      break;
+    }
+    case tok::comment:
+      HighlightRange(RB, TokOffs, TokOffs+TokLen, BufferStart,
+                     "<span class='comment'>", "</span>");
+      break;
+    case tok::wide_string_literal:
+      // Chop off the L prefix
+      ++TokOffs;
+      --TokLen;
+      // FALL THROUGH.
+    case tok::string_literal:
+      HighlightRange(RB, TokOffs, TokOffs+TokLen, BufferStart,
+                     "<span class='string_literal'>", "</span>");
+      break;
+    case tok::hash: {
+      // If this is a preprocessor directive, all tokens to end of line are too.
+      if (!Tok.isAtStartOfLine())
+        break;
+
+      // Eat all of the tokens until we get to the next one at the start of
+      // line.
+      unsigned TokEnd = TokOffs+TokLen;
+      L.LexFromRawLexer(Tok);
+      while (!Tok.isAtStartOfLine() && Tok.isNot(tok::eof)) {
+        TokEnd = SM.getFileOffset(Tok.getLocation())+Tok.getLength();
+        L.LexFromRawLexer(Tok);
+      }
+
+      // Find end of line.  This is a hack.
+      HighlightRange(RB, TokOffs, TokEnd, BufferStart,
+                     "<span class='directive'>", "</span>");
+
+      // Don't skip the next token.
+      continue;
+    }
+    }
+
+    L.LexFromRawLexer(Tok);
+  }
+}
+
+namespace {
+/// IgnoringDiagClient - This is a diagnostic client that just ignores all
+/// diags.
+class IgnoringDiagClient : public DiagnosticClient {
+  void HandleDiagnostic(Diagnostic::Level DiagLevel,
+                        const DiagnosticInfo &Info) {
+    // Just ignore it.
+  }
+};
+}
+
+/// HighlightMacros - This uses the macro table state from the end of the
+/// file, to re-expand macros and insert (into the HTML) information about the
+/// macro expansions.  This won't be perfectly perfect, but it will be
+/// reasonably close.
+void html::HighlightMacros(Rewriter &R, FileID FID, const Preprocessor& PP) {
+  // Re-lex the raw token stream into a token buffer.
+  const SourceManager &SM = PP.getSourceManager();
+  std::vector<Token> TokenStream;
+
+  const llvm::MemoryBuffer *FromFile = SM.getBuffer(FID);
+  Lexer L(FID, FromFile, SM, PP.getLangOptions());
+
+  // Lex all the tokens in raw mode, to avoid entering #includes or expanding
+  // macros.
+  while (1) {
+    Token Tok;
+    L.LexFromRawLexer(Tok);
+
+    // If this is a # at the start of a line, discard it from the token stream.
+    // We don't want the re-preprocess step to see #defines, #includes or other
+    // preprocessor directives.
+    if (Tok.is(tok::hash) && Tok.isAtStartOfLine())
+      continue;
+
+    // If this is a ## token, change its kind to unknown so that repreprocessing
+    // it will not produce an error.
+    if (Tok.is(tok::hashhash))
+      Tok.setKind(tok::unknown);
+
+    // If this raw token is an identifier, the raw lexer won't have looked up
+    // the corresponding identifier info for it.  Do this now so that it will be
+    // macro expanded when we re-preprocess it.
+    if (Tok.is(tok::identifier)) {
+      // Change the kind of this identifier to the appropriate token kind, e.g.
+      // turning "for" into a keyword.
+      Tok.setKind(PP.LookUpIdentifierInfo(Tok)->getTokenID());
+    }
+
+    TokenStream.push_back(Tok);
+
+    if (Tok.is(tok::eof)) break;
+  }
+
+  // Temporarily change the diagnostics object so that we ignore any generated
+  // diagnostics from this pass.
+  IgnoringDiagClient TmpDC;
+  Diagnostic TmpDiags(&TmpDC);
+
+  // FIXME: This is a huge hack; we reuse the input preprocessor because we want
+  // its state, but we aren't actually changing it (we hope). This should really
+  // construct a copy of the preprocessor.
+  Preprocessor &TmpPP = const_cast<Preprocessor&>(PP);
+  Diagnostic *OldDiags = &TmpPP.getDiagnostics();
+  TmpPP.setDiagnostics(TmpDiags);
+
+  // Inform the preprocessor that we don't want comments.
+  TmpPP.SetCommentRetentionState(false, false);
+
+  // Enter the tokens we just lexed.  This will cause them to be macro expanded
+  // but won't enter sub-files (because we removed #'s).
+  TmpPP.EnterTokenStream(&TokenStream[0], TokenStream.size(), false, false);
+
+  TokenConcatenation ConcatInfo(TmpPP);
+
+  // Lex all the tokens.
+  Token Tok;
+  TmpPP.Lex(Tok);
+  while (Tok.isNot(tok::eof)) {
+    // Ignore non-macro tokens.
+    if (!Tok.getLocation().isMacroID()) {
+      TmpPP.Lex(Tok);
+      continue;
+    }
+
+    // Okay, we have the first token of a macro expansion: highlight the
+    // instantiation by inserting a start tag before the macro instantiation and
+    // end tag after it.
+    std::pair<SourceLocation, SourceLocation> LLoc =
+      SM.getInstantiationRange(Tok.getLocation());
+
+    // Ignore tokens whose instantiation location was not the main file.
+    if (SM.getFileID(LLoc.first) != FID) {
+      TmpPP.Lex(Tok);
+      continue;
+    }
+
+    assert(SM.getFileID(LLoc.second) == FID &&
+           "Start and end of expansion must be in the same ultimate file!");
+
+    std::string Expansion = EscapeText(TmpPP.getSpelling(Tok));
+    unsigned LineLen = Expansion.size();
+
+    Token PrevPrevTok;
+    Token PrevTok = Tok;
+    // Okay, eat this token, getting the next one.
+    TmpPP.Lex(Tok);
+
+    // Skip all the rest of the tokens that are part of this macro
+    // instantiation.  It would be really nice to pop up a window with all the
+    // spelling of the tokens or something.
+    while (!Tok.is(tok::eof) &&
+           SM.getInstantiationLoc(Tok.getLocation()) == LLoc.first) {
+      // Insert a newline if the macro expansion is getting large.
+      if (LineLen > 60) {
+        Expansion += "<br>";
+        LineLen = 0;
+      }
+
+      LineLen -= Expansion.size();
+
+      // If the tokens were already space separated, or if they must be to avoid
+      // them being implicitly pasted, add a space between them.
+      if (Tok.hasLeadingSpace() ||
+          ConcatInfo.AvoidConcat(PrevPrevTok, PrevTok, Tok))
+        Expansion += ' ';
+
+      // Escape any special characters in the token text.
+      Expansion += EscapeText(TmpPP.getSpelling(Tok));
+      LineLen += Expansion.size();
+
+      PrevPrevTok = PrevTok;
+      PrevTok = Tok;
+      TmpPP.Lex(Tok);
+    }
+
+
+    // Insert the expansion as the end tag, so that multi-line macros all get
+    // highlighted.
+    Expansion = "<span class='expansion'>" + Expansion + "</span></span>";
+
+    HighlightRange(R, LLoc.first, LLoc.second,
+                   "<span class='macro'>", Expansion.c_str());
+  }
+
+  // Restore diagnostics object back to its own thing.
+  TmpPP.setDiagnostics(*OldDiags);
+}
diff --git a/lib/Rewrite/Makefile b/lib/Rewrite/Makefile
new file mode 100644
index 0000000..04c3530
--- /dev/null
+++ b/lib/Rewrite/Makefile
@@ -0,0 +1,21 @@
+##===- clang/lib/Rewrite/Makefile --------------------------*- Makefile -*-===##
+# 
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+# 
+##===----------------------------------------------------------------------===##
+#
+# This implements code transformation / rewriting facilities.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../../../..
+LIBRARYNAME := clangRewrite
+BUILD_ARCHIVE = 1
+
+CPP.Flags += -I$(PROJ_SRC_DIR)/../../include -I$(PROJ_OBJ_DIR)/../../include
+
+include $(LEVEL)/Makefile.common
+
diff --git a/lib/Rewrite/RewriteRope.cpp b/lib/Rewrite/RewriteRope.cpp
new file mode 100644
index 0000000..fdb6fc3
--- /dev/null
+++ b/lib/Rewrite/RewriteRope.cpp
@@ -0,0 +1,808 @@
+//===--- RewriteRope.cpp - Rope specialized for rewriter --------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements the RewriteRope class, which is a powerful string.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Rewrite/RewriteRope.h"
+#include "llvm/Support/Casting.h"
+#include <algorithm>
+using namespace clang;
+using llvm::dyn_cast;
+using llvm::cast;
+
+/// RewriteRope is a "strong" string class, designed to make insertions and
+/// deletions in the middle of the string nearly constant time (really, they are
+/// O(log N), but with a very low constant factor).
+///
+/// The implementation of this datastructure is a conceptual linear sequence of
+/// RopePiece elements.  Each RopePiece represents a view on a separately
+/// allocated and reference counted string.  This means that splitting a very
+/// long string can be done in constant time by splitting a RopePiece that
+/// references the whole string into two rope pieces that reference each half.
+/// Once split, another string can be inserted in between the two halves by
+/// inserting a RopePiece in between the two others.  All of this is very
+/// inexpensive: it takes time proportional to the number of RopePieces, not the
+/// length of the strings they represent.
+///
+/// While a linear sequences of RopePieces is the conceptual model, the actual
+/// implementation captures them in an adapted B+ Tree.  Using a B+ tree (which
+/// is a tree that keeps the values in the leaves and has where each node
+/// contains a reasonable number of pointers to children/values) allows us to
+/// maintain efficient operation when the RewriteRope contains a *huge* number
+/// of RopePieces.  The basic idea of the B+ Tree is that it allows us to find
+/// the RopePiece corresponding to some offset very efficiently, and it
+/// automatically balances itself on insertions of RopePieces (which can happen
+/// for both insertions and erases of string ranges).
+///
+/// The one wrinkle on the theory is that we don't attempt to keep the tree
+/// properly balanced when erases happen.  Erases of string data can both insert
+/// new RopePieces (e.g. when the middle of some other rope piece is deleted,
+/// which results in two rope pieces, which is just like an insert) or it can
+/// reduce the number of RopePieces maintained by the B+Tree.  In the case when
+/// the number of RopePieces is reduced, we don't attempt to maintain the
+/// standard 'invariant' that each node in the tree contains at least
+/// 'WidthFactor' children/values.  For our use cases, this doesn't seem to
+/// matter.
+///
+/// The implementation below is primarily implemented in terms of three classes:
+///   RopePieceBTreeNode - Common base class for:
+///
+///     RopePieceBTreeLeaf - Directly manages up to '2*WidthFactor' RopePiece
+///          nodes.  This directly represents a chunk of the string with those
+///          RopePieces contatenated.
+///     RopePieceBTreeInterior - An interior node in the B+ Tree, which manages
+///          up to '2*WidthFactor' other nodes in the tree.
+
+
+//===----------------------------------------------------------------------===//
+// RopePieceBTreeNode Class
+//===----------------------------------------------------------------------===//
+
+namespace {
+  /// RopePieceBTreeNode - Common base class of RopePieceBTreeLeaf and
+  /// RopePieceBTreeInterior.  This provides some 'virtual' dispatching methods
+  /// and a flag that determines which subclass the instance is.  Also
+  /// important, this node knows the full extend of the node, including any
+  /// children that it has.  This allows efficient skipping over entire subtrees
+  /// when looking for an offset in the BTree.
+  class RopePieceBTreeNode {
+  protected:
+    /// WidthFactor - This controls the number of K/V slots held in the BTree:
+    /// how wide it is.  Each level of the BTree is guaranteed to have at least
+    /// 'WidthFactor' elements in it (either ropepieces or children), (except
+    /// the root, which may have less) and may have at most 2*WidthFactor
+    /// elements.
+    enum { WidthFactor = 8 };
+
+    /// Size - This is the number of bytes of file this node (including any
+    /// potential children) covers.
+    unsigned Size;
+
+    /// IsLeaf - True if this is an instance of RopePieceBTreeLeaf, false if it
+    /// is an instance of RopePieceBTreeInterior.
+    bool IsLeaf;
+
+    RopePieceBTreeNode(bool isLeaf) : Size(0), IsLeaf(isLeaf) {}
+    ~RopePieceBTreeNode() {}
+  public:
+
+    bool isLeaf() const { return IsLeaf; }
+    unsigned size() const { return Size; }
+
+    void Destroy();
+
+    /// split - Split the range containing the specified offset so that we are
+    /// guaranteed that there is a place to do an insertion at the specified
+    /// offset.  The offset is relative, so "0" is the start of the node.
+    ///
+    /// If there is no space in this subtree for the extra piece, the extra tree
+    /// node is returned and must be inserted into a parent.
+    RopePieceBTreeNode *split(unsigned Offset);
+
+    /// insert - Insert the specified ropepiece into this tree node at the
+    /// specified offset.  The offset is relative, so "0" is the start of the
+    /// node.
+    ///
+    /// If there is no space in this subtree for the extra piece, the extra tree
+    /// node is returned and must be inserted into a parent.
+    RopePieceBTreeNode *insert(unsigned Offset, const RopePiece &R);
+
+    /// erase - Remove NumBytes from this node at the specified offset.  We are
+    /// guaranteed that there is a split at Offset.
+    void erase(unsigned Offset, unsigned NumBytes);
+
+    static inline bool classof(const RopePieceBTreeNode *) { return true; }
+
+  };
+} // end anonymous namespace
+
+//===----------------------------------------------------------------------===//
+// RopePieceBTreeLeaf Class
+//===----------------------------------------------------------------------===//
+
+namespace {
+  /// RopePieceBTreeLeaf - Directly manages up to '2*WidthFactor' RopePiece
+  /// nodes.  This directly represents a chunk of the string with those
+  /// RopePieces contatenated.  Since this is a B+Tree, all values (in this case
+  /// instances of RopePiece) are stored in leaves like this.  To make iteration
+  /// over the leaves efficient, they maintain a singly linked list through the
+  /// NextLeaf field.  This allows the B+Tree forward iterator to be constant
+  /// time for all increments.
+  class RopePieceBTreeLeaf : public RopePieceBTreeNode {
+    /// NumPieces - This holds the number of rope pieces currently active in the
+    /// Pieces array.
+    unsigned char NumPieces;
+
+    /// Pieces - This tracks the file chunks currently in this leaf.
+    ///
+    RopePiece Pieces[2*WidthFactor];
+
+    /// NextLeaf - This is a pointer to the next leaf in the tree, allowing
+    /// efficient in-order forward iteration of the tree without traversal.
+    RopePieceBTreeLeaf **PrevLeaf, *NextLeaf;
+  public:
+    RopePieceBTreeLeaf() : RopePieceBTreeNode(true), NumPieces(0),
+                           PrevLeaf(0), NextLeaf(0) {}
+    ~RopePieceBTreeLeaf() {
+      if (PrevLeaf || NextLeaf)
+        removeFromLeafInOrder();
+      clear();
+    }
+
+    bool isFull() const { return NumPieces == 2*WidthFactor; }
+
+    /// clear - Remove all rope pieces from this leaf.
+    void clear() {
+      while (NumPieces)
+        Pieces[--NumPieces] = RopePiece();
+      Size = 0;
+    }
+
+    unsigned getNumPieces() const { return NumPieces; }
+
+    const RopePiece &getPiece(unsigned i) const {
+      assert(i < getNumPieces() && "Invalid piece ID");
+      return Pieces[i];
+    }
+
+    const RopePieceBTreeLeaf *getNextLeafInOrder() const { return NextLeaf; }
+    void insertAfterLeafInOrder(RopePieceBTreeLeaf *Node) {
+      assert(PrevLeaf == 0 && NextLeaf == 0 && "Already in ordering");
+
+      NextLeaf = Node->NextLeaf;
+      if (NextLeaf)
+        NextLeaf->PrevLeaf = &NextLeaf;
+      PrevLeaf = &Node->NextLeaf;
+      Node->NextLeaf = this;
+    }
+
+    void removeFromLeafInOrder() {
+      if (PrevLeaf) {
+        *PrevLeaf = NextLeaf;
+        if (NextLeaf)
+          NextLeaf->PrevLeaf = PrevLeaf;
+      } else if (NextLeaf) {
+        NextLeaf->PrevLeaf = 0;
+      }
+    }
+
+    /// FullRecomputeSizeLocally - This method recomputes the 'Size' field by
+    /// summing the size of all RopePieces.
+    void FullRecomputeSizeLocally() {
+      Size = 0;
+      for (unsigned i = 0, e = getNumPieces(); i != e; ++i)
+        Size += getPiece(i).size();
+    }
+
+    /// split - Split the range containing the specified offset so that we are
+    /// guaranteed that there is a place to do an insertion at the specified
+    /// offset.  The offset is relative, so "0" is the start of the node.
+    ///
+    /// If there is no space in this subtree for the extra piece, the extra tree
+    /// node is returned and must be inserted into a parent.
+    RopePieceBTreeNode *split(unsigned Offset);
+
+    /// insert - Insert the specified ropepiece into this tree node at the
+    /// specified offset.  The offset is relative, so "0" is the start of the
+    /// node.
+    ///
+    /// If there is no space in this subtree for the extra piece, the extra tree
+    /// node is returned and must be inserted into a parent.
+    RopePieceBTreeNode *insert(unsigned Offset, const RopePiece &R);
+
+
+    /// erase - Remove NumBytes from this node at the specified offset.  We are
+    /// guaranteed that there is a split at Offset.
+    void erase(unsigned Offset, unsigned NumBytes);
+
+    static inline bool classof(const RopePieceBTreeLeaf *) { return true; }
+    static inline bool classof(const RopePieceBTreeNode *N) {
+      return N->isLeaf();
+    }
+  };
+} // end anonymous namespace
+
+/// split - Split the range containing the specified offset so that we are
+/// guaranteed that there is a place to do an insertion at the specified
+/// offset.  The offset is relative, so "0" is the start of the node.
+///
+/// If there is no space in this subtree for the extra piece, the extra tree
+/// node is returned and must be inserted into a parent.
+RopePieceBTreeNode *RopePieceBTreeLeaf::split(unsigned Offset) {
+  // Find the insertion point.  We are guaranteed that there is a split at the
+  // specified offset so find it.
+  if (Offset == 0 || Offset == size()) {
+    // Fastpath for a common case.  There is already a splitpoint at the end.
+    return 0;
+  }
+
+  // Find the piece that this offset lands in.
+  unsigned PieceOffs = 0;
+  unsigned i = 0;
+  while (Offset >= PieceOffs+Pieces[i].size()) {
+    PieceOffs += Pieces[i].size();
+    ++i;
+  }
+
+  // If there is already a split point at the specified offset, just return
+  // success.
+  if (PieceOffs == Offset)
+    return 0;
+
+  // Otherwise, we need to split piece 'i' at Offset-PieceOffs.  Convert Offset
+  // to being Piece relative.
+  unsigned IntraPieceOffset = Offset-PieceOffs;
+
+  // We do this by shrinking the RopePiece and then doing an insert of the tail.
+  RopePiece Tail(Pieces[i].StrData, Pieces[i].StartOffs+IntraPieceOffset,
+                 Pieces[i].EndOffs);
+  Size -= Pieces[i].size();
+  Pieces[i].EndOffs = Pieces[i].StartOffs+IntraPieceOffset;
+  Size += Pieces[i].size();
+
+  return insert(Offset, Tail);
+}
+
+
+/// insert - Insert the specified RopePiece into this tree node at the
+/// specified offset.  The offset is relative, so "0" is the start of the node.
+///
+/// If there is no space in this subtree for the extra piece, the extra tree
+/// node is returned and must be inserted into a parent.
+RopePieceBTreeNode *RopePieceBTreeLeaf::insert(unsigned Offset,
+                                               const RopePiece &R) {
+  // If this node is not full, insert the piece.
+  if (!isFull()) {
+    // Find the insertion point.  We are guaranteed that there is a split at the
+    // specified offset so find it.
+    unsigned i = 0, e = getNumPieces();
+    if (Offset == size()) {
+      // Fastpath for a common case.
+      i = e;
+    } else {
+      unsigned SlotOffs = 0;
+      for (; Offset > SlotOffs; ++i)
+        SlotOffs += getPiece(i).size();
+      assert(SlotOffs == Offset && "Split didn't occur before insertion!");
+    }
+
+    // For an insertion into a non-full leaf node, just insert the value in
+    // its sorted position.  This requires moving later values over.
+    for (; i != e; --e)
+      Pieces[e] = Pieces[e-1];
+    Pieces[i] = R;
+    ++NumPieces;
+    Size += R.size();
+    return 0;
+  }
+
+  // Otherwise, if this is leaf is full, split it in two halves.  Since this
+  // node is full, it contains 2*WidthFactor values.  We move the first
+  // 'WidthFactor' values to the LHS child (which we leave in this node) and
+  // move the last 'WidthFactor' values into the RHS child.
+
+  // Create the new node.
+  RopePieceBTreeLeaf *NewNode = new RopePieceBTreeLeaf();
+
+  // Move over the last 'WidthFactor' values from here to NewNode.
+  std::copy(&Pieces[WidthFactor], &Pieces[2*WidthFactor],
+            &NewNode->Pieces[0]);
+  // Replace old pieces with null RopePieces to drop refcounts.
+  std::fill(&Pieces[WidthFactor], &Pieces[2*WidthFactor], RopePiece());
+
+  // Decrease the number of values in the two nodes.
+  NewNode->NumPieces = NumPieces = WidthFactor;
+
+  // Recompute the two nodes' size.
+  NewNode->FullRecomputeSizeLocally();
+  FullRecomputeSizeLocally();
+
+  // Update the list of leaves.
+  NewNode->insertAfterLeafInOrder(this);
+
+  // These insertions can't fail.
+  if (this->size() >= Offset)
+    this->insert(Offset, R);
+  else
+    NewNode->insert(Offset - this->size(), R);
+  return NewNode;
+}
+
+/// erase - Remove NumBytes from this node at the specified offset.  We are
+/// guaranteed that there is a split at Offset.
+void RopePieceBTreeLeaf::erase(unsigned Offset, unsigned NumBytes) {
+  // Since we are guaranteed that there is a split at Offset, we start by
+  // finding the Piece that starts there.
+  unsigned PieceOffs = 0;
+  unsigned i = 0;
+  for (; Offset > PieceOffs; ++i)
+    PieceOffs += getPiece(i).size();
+  assert(PieceOffs == Offset && "Split didn't occur before erase!");
+
+  unsigned StartPiece = i;
+
+  // Figure out how many pieces completely cover 'NumBytes'.  We want to remove
+  // all of them.
+  for (; Offset+NumBytes > PieceOffs+getPiece(i).size(); ++i)
+    PieceOffs += getPiece(i).size();
+
+  // If we exactly include the last one, include it in the region to delete.
+  if (Offset+NumBytes == PieceOffs+getPiece(i).size())
+    PieceOffs += getPiece(i).size(), ++i;
+
+  // If we completely cover some RopePieces, erase them now.
+  if (i != StartPiece) {
+    unsigned NumDeleted = i-StartPiece;
+    for (; i != getNumPieces(); ++i)
+      Pieces[i-NumDeleted] = Pieces[i];
+
+    // Drop references to dead rope pieces.
+    std::fill(&Pieces[getNumPieces()-NumDeleted], &Pieces[getNumPieces()],
+              RopePiece());
+    NumPieces -= NumDeleted;
+
+    unsigned CoverBytes = PieceOffs-Offset;
+    NumBytes -= CoverBytes;
+    Size -= CoverBytes;
+  }
+
+  // If we completely removed some stuff, we could be done.
+  if (NumBytes == 0) return;
+
+  // Okay, now might be erasing part of some Piece.  If this is the case, then
+  // move the start point of the piece.
+  assert(getPiece(StartPiece).size() > NumBytes);
+  Pieces[StartPiece].StartOffs += NumBytes;
+
+  // The size of this node just shrunk by NumBytes.
+  Size -= NumBytes;
+}
+
+//===----------------------------------------------------------------------===//
+// RopePieceBTreeInterior Class
+//===----------------------------------------------------------------------===//
+
+namespace {
+  /// RopePieceBTreeInterior - This represents an interior node in the B+Tree,
+  /// which holds up to 2*WidthFactor pointers to child nodes.
+  class RopePieceBTreeInterior : public RopePieceBTreeNode {
+    /// NumChildren - This holds the number of children currently active in the
+    /// Children array.
+    unsigned char NumChildren;
+    RopePieceBTreeNode *Children[2*WidthFactor];
+  public:
+    RopePieceBTreeInterior() : RopePieceBTreeNode(false), NumChildren(0) {}
+
+    RopePieceBTreeInterior(RopePieceBTreeNode *LHS, RopePieceBTreeNode *RHS)
+    : RopePieceBTreeNode(false) {
+      Children[0] = LHS;
+      Children[1] = RHS;
+      NumChildren = 2;
+      Size = LHS->size() + RHS->size();
+    }
+
+    bool isFull() const { return NumChildren == 2*WidthFactor; }
+
+    unsigned getNumChildren() const { return NumChildren; }
+    const RopePieceBTreeNode *getChild(unsigned i) const {
+      assert(i < NumChildren && "invalid child #");
+      return Children[i];
+    }
+    RopePieceBTreeNode *getChild(unsigned i) {
+      assert(i < NumChildren && "invalid child #");
+      return Children[i];
+    }
+
+    /// FullRecomputeSizeLocally - Recompute the Size field of this node by
+    /// summing up the sizes of the child nodes.
+    void FullRecomputeSizeLocally() {
+      Size = 0;
+      for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
+        Size += getChild(i)->size();
+    }
+
+
+    /// split - Split the range containing the specified offset so that we are
+    /// guaranteed that there is a place to do an insertion at the specified
+    /// offset.  The offset is relative, so "0" is the start of the node.
+    ///
+    /// If there is no space in this subtree for the extra piece, the extra tree
+    /// node is returned and must be inserted into a parent.
+    RopePieceBTreeNode *split(unsigned Offset);
+
+
+    /// insert - Insert the specified ropepiece into this tree node at the
+    /// specified offset.  The offset is relative, so "0" is the start of the
+    /// node.
+    ///
+    /// If there is no space in this subtree for the extra piece, the extra tree
+    /// node is returned and must be inserted into a parent.
+    RopePieceBTreeNode *insert(unsigned Offset, const RopePiece &R);
+
+    /// HandleChildPiece - A child propagated an insertion result up to us.
+    /// Insert the new child, and/or propagate the result further up the tree.
+    RopePieceBTreeNode *HandleChildPiece(unsigned i, RopePieceBTreeNode *RHS);
+
+    /// erase - Remove NumBytes from this node at the specified offset.  We are
+    /// guaranteed that there is a split at Offset.
+    void erase(unsigned Offset, unsigned NumBytes);
+
+    static inline bool classof(const RopePieceBTreeInterior *) { return true; }
+    static inline bool classof(const RopePieceBTreeNode *N) {
+      return !N->isLeaf();
+    }
+  };
+} // end anonymous namespace
+
+/// split - Split the range containing the specified offset so that we are
+/// guaranteed that there is a place to do an insertion at the specified
+/// offset.  The offset is relative, so "0" is the start of the node.
+///
+/// If there is no space in this subtree for the extra piece, the extra tree
+/// node is returned and must be inserted into a parent.
+RopePieceBTreeNode *RopePieceBTreeInterior::split(unsigned Offset) {
+  // Figure out which child to split.
+  if (Offset == 0 || Offset == size())
+    return 0;  // If we have an exact offset, we're already split.
+
+  unsigned ChildOffset = 0;
+  unsigned i = 0;
+  for (; Offset >= ChildOffset+getChild(i)->size(); ++i)
+    ChildOffset += getChild(i)->size();
+
+  // If already split there, we're done.
+  if (ChildOffset == Offset)
+    return 0;
+
+  // Otherwise, recursively split the child.
+  if (RopePieceBTreeNode *RHS = getChild(i)->split(Offset-ChildOffset))
+    return HandleChildPiece(i, RHS);
+  return 0;  // Done!
+}
+
+/// insert - Insert the specified ropepiece into this tree node at the
+/// specified offset.  The offset is relative, so "0" is the start of the
+/// node.
+///
+/// If there is no space in this subtree for the extra piece, the extra tree
+/// node is returned and must be inserted into a parent.
+RopePieceBTreeNode *RopePieceBTreeInterior::insert(unsigned Offset,
+                                                   const RopePiece &R) {
+  // Find the insertion point.  We are guaranteed that there is a split at the
+  // specified offset so find it.
+  unsigned i = 0, e = getNumChildren();
+
+  unsigned ChildOffs = 0;
+  if (Offset == size()) {
+    // Fastpath for a common case.  Insert at end of last child.
+    i = e-1;
+    ChildOffs = size()-getChild(i)->size();
+  } else {
+    for (; Offset > ChildOffs+getChild(i)->size(); ++i)
+      ChildOffs += getChild(i)->size();
+  }
+
+  Size += R.size();
+
+  // Insert at the end of this child.
+  if (RopePieceBTreeNode *RHS = getChild(i)->insert(Offset-ChildOffs, R))
+    return HandleChildPiece(i, RHS);
+
+  return 0;
+}
+
+/// HandleChildPiece - A child propagated an insertion result up to us.
+/// Insert the new child, and/or propagate the result further up the tree.
+RopePieceBTreeNode *
+RopePieceBTreeInterior::HandleChildPiece(unsigned i, RopePieceBTreeNode *RHS) {
+  // Otherwise the child propagated a subtree up to us as a new child.  See if
+  // we have space for it here.
+  if (!isFull()) {
+    // Insert RHS after child 'i'.
+    if (i + 1 != getNumChildren())
+      memmove(&Children[i+2], &Children[i+1],
+              (getNumChildren()-i-1)*sizeof(Children[0]));
+    Children[i+1] = RHS;
+    ++NumChildren;
+    return false;
+  }
+
+  // Okay, this node is full.  Split it in half, moving WidthFactor children to
+  // a newly allocated interior node.
+
+  // Create the new node.
+  RopePieceBTreeInterior *NewNode = new RopePieceBTreeInterior();
+
+  // Move over the last 'WidthFactor' values from here to NewNode.
+  memcpy(&NewNode->Children[0], &Children[WidthFactor],
+         WidthFactor*sizeof(Children[0]));
+
+  // Decrease the number of values in the two nodes.
+  NewNode->NumChildren = NumChildren = WidthFactor;
+
+  // Finally, insert the two new children in the side the can (now) hold them.
+  // These insertions can't fail.
+  if (i < WidthFactor)
+    this->HandleChildPiece(i, RHS);
+  else
+    NewNode->HandleChildPiece(i-WidthFactor, RHS);
+
+  // Recompute the two nodes' size.
+  NewNode->FullRecomputeSizeLocally();
+  FullRecomputeSizeLocally();
+  return NewNode;
+}
+
+/// erase - Remove NumBytes from this node at the specified offset.  We are
+/// guaranteed that there is a split at Offset.
+void RopePieceBTreeInterior::erase(unsigned Offset, unsigned NumBytes) {
+  // This will shrink this node by NumBytes.
+  Size -= NumBytes;
+
+  // Find the first child that overlaps with Offset.
+  unsigned i = 0;
+  for (; Offset >= getChild(i)->size(); ++i)
+    Offset -= getChild(i)->size();
+
+  // Propagate the delete request into overlapping children, or completely
+  // delete the children as appropriate.
+  while (NumBytes) {
+    RopePieceBTreeNode *CurChild = getChild(i);
+
+    // If we are deleting something contained entirely in the child, pass on the
+    // request.
+    if (Offset+NumBytes < CurChild->size()) {
+      CurChild->erase(Offset, NumBytes);
+      return;
+    }
+
+    // If this deletion request starts somewhere in the middle of the child, it
+    // must be deleting to the end of the child.
+    if (Offset) {
+      unsigned BytesFromChild = CurChild->size()-Offset;
+      CurChild->erase(Offset, BytesFromChild);
+      NumBytes -= BytesFromChild;
+      // Start at the beginning of the next child.
+      Offset = 0;
+      ++i;
+      continue;
+    }
+
+    // If the deletion request completely covers the child, delete it and move
+    // the rest down.
+    NumBytes -= CurChild->size();
+    CurChild->Destroy();
+    --NumChildren;
+    if (i != getNumChildren())
+      memmove(&Children[i], &Children[i+1],
+              (getNumChildren()-i)*sizeof(Children[0]));
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// RopePieceBTreeNode Implementation
+//===----------------------------------------------------------------------===//
+
+void RopePieceBTreeNode::Destroy() {
+  if (RopePieceBTreeLeaf *Leaf = dyn_cast<RopePieceBTreeLeaf>(this))
+    delete Leaf;
+  else
+    delete cast<RopePieceBTreeInterior>(this);
+}
+
+/// split - Split the range containing the specified offset so that we are
+/// guaranteed that there is a place to do an insertion at the specified
+/// offset.  The offset is relative, so "0" is the start of the node.
+///
+/// If there is no space in this subtree for the extra piece, the extra tree
+/// node is returned and must be inserted into a parent.
+RopePieceBTreeNode *RopePieceBTreeNode::split(unsigned Offset) {
+  assert(Offset <= size() && "Invalid offset to split!");
+  if (RopePieceBTreeLeaf *Leaf = dyn_cast<RopePieceBTreeLeaf>(this))
+    return Leaf->split(Offset);
+  return cast<RopePieceBTreeInterior>(this)->split(Offset);
+}
+
+/// insert - Insert the specified ropepiece into this tree node at the
+/// specified offset.  The offset is relative, so "0" is the start of the
+/// node.
+///
+/// If there is no space in this subtree for the extra piece, the extra tree
+/// node is returned and must be inserted into a parent.
+RopePieceBTreeNode *RopePieceBTreeNode::insert(unsigned Offset,
+                                               const RopePiece &R) {
+  assert(Offset <= size() && "Invalid offset to insert!");
+  if (RopePieceBTreeLeaf *Leaf = dyn_cast<RopePieceBTreeLeaf>(this))
+    return Leaf->insert(Offset, R);
+  return cast<RopePieceBTreeInterior>(this)->insert(Offset, R);
+}
+
+/// erase - Remove NumBytes from this node at the specified offset.  We are
+/// guaranteed that there is a split at Offset.
+void RopePieceBTreeNode::erase(unsigned Offset, unsigned NumBytes) {
+  assert(Offset+NumBytes <= size() && "Invalid offset to erase!");
+  if (RopePieceBTreeLeaf *Leaf = dyn_cast<RopePieceBTreeLeaf>(this))
+    return Leaf->erase(Offset, NumBytes);
+  return cast<RopePieceBTreeInterior>(this)->erase(Offset, NumBytes);
+}
+
+
+//===----------------------------------------------------------------------===//
+// RopePieceBTreeIterator Implementation
+//===----------------------------------------------------------------------===//
+
+static const RopePieceBTreeLeaf *getCN(const void *P) {
+  return static_cast<const RopePieceBTreeLeaf*>(P);
+}
+
+// begin iterator.
+RopePieceBTreeIterator::RopePieceBTreeIterator(const void *n) {
+  const RopePieceBTreeNode *N = static_cast<const RopePieceBTreeNode*>(n);
+
+  // Walk down the left side of the tree until we get to a leaf.
+  while (const RopePieceBTreeInterior *IN = dyn_cast<RopePieceBTreeInterior>(N))
+    N = IN->getChild(0);
+
+  // We must have at least one leaf.
+  CurNode = cast<RopePieceBTreeLeaf>(N);
+
+  // If we found a leaf that happens to be empty, skip over it until we get
+  // to something full.
+  while (CurNode && getCN(CurNode)->getNumPieces() == 0)
+    CurNode = getCN(CurNode)->getNextLeafInOrder();
+
+  if (CurNode != 0)
+    CurPiece = &getCN(CurNode)->getPiece(0);
+  else  // Empty tree, this is an end() iterator.
+    CurPiece = 0;
+  CurChar = 0;
+}
+
+void RopePieceBTreeIterator::MoveToNextPiece() {
+  if (CurPiece != &getCN(CurNode)->getPiece(getCN(CurNode)->getNumPieces()-1)) {
+    CurChar = 0;
+    ++CurPiece;
+    return;
+  }
+
+  // Find the next non-empty leaf node.
+  do
+    CurNode = getCN(CurNode)->getNextLeafInOrder();
+  while (CurNode && getCN(CurNode)->getNumPieces() == 0);
+
+  if (CurNode != 0)
+    CurPiece = &getCN(CurNode)->getPiece(0);
+  else // Hit end().
+    CurPiece = 0;
+  CurChar = 0;
+}
+
+//===----------------------------------------------------------------------===//
+// RopePieceBTree Implementation
+//===----------------------------------------------------------------------===//
+
+static RopePieceBTreeNode *getRoot(void *P) {
+  return static_cast<RopePieceBTreeNode*>(P);
+}
+
+RopePieceBTree::RopePieceBTree() {
+  Root = new RopePieceBTreeLeaf();
+}
+RopePieceBTree::RopePieceBTree(const RopePieceBTree &RHS) {
+  assert(RHS.empty() && "Can't copy non-empty tree yet");
+  Root = new RopePieceBTreeLeaf();
+}
+RopePieceBTree::~RopePieceBTree() {
+  getRoot(Root)->Destroy();
+}
+
+unsigned RopePieceBTree::size() const {
+  return getRoot(Root)->size();
+}
+
+void RopePieceBTree::clear() {
+  if (RopePieceBTreeLeaf *Leaf = dyn_cast<RopePieceBTreeLeaf>(getRoot(Root)))
+    Leaf->clear();
+  else {
+    getRoot(Root)->Destroy();
+    Root = new RopePieceBTreeLeaf();
+  }
+}
+
+void RopePieceBTree::insert(unsigned Offset, const RopePiece &R) {
+  // #1. Split at Offset.
+  if (RopePieceBTreeNode *RHS = getRoot(Root)->split(Offset))
+    Root = new RopePieceBTreeInterior(getRoot(Root), RHS);
+
+  // #2. Do the insertion.
+  if (RopePieceBTreeNode *RHS = getRoot(Root)->insert(Offset, R))
+    Root = new RopePieceBTreeInterior(getRoot(Root), RHS);
+}
+
+void RopePieceBTree::erase(unsigned Offset, unsigned NumBytes) {
+  // #1. Split at Offset.
+  if (RopePieceBTreeNode *RHS = getRoot(Root)->split(Offset))
+    Root = new RopePieceBTreeInterior(getRoot(Root), RHS);
+
+  // #2. Do the erasing.
+  getRoot(Root)->erase(Offset, NumBytes);
+}
+
+//===----------------------------------------------------------------------===//
+// RewriteRope Implementation
+//===----------------------------------------------------------------------===//
+
+/// MakeRopeString - This copies the specified byte range into some instance of
+/// RopeRefCountString, and return a RopePiece that represents it.  This uses
+/// the AllocBuffer object to aggregate requests for small strings into one
+/// allocation instead of doing tons of tiny allocations.
+RopePiece RewriteRope::MakeRopeString(const char *Start, const char *End) {
+  unsigned Len = End-Start;
+  assert(Len && "Zero length RopePiece is invalid!");
+
+  // If we have space for this string in the current alloc buffer, use it.
+  if (AllocOffs+Len <= AllocChunkSize) {
+    memcpy(AllocBuffer->Data+AllocOffs, Start, Len);
+    AllocOffs += Len;
+    return RopePiece(AllocBuffer, AllocOffs-Len, AllocOffs);
+  }
+
+  // If we don't have enough room because this specific allocation is huge,
+  // just allocate a new rope piece for it alone.
+  if (Len > AllocChunkSize) {
+    unsigned Size = End-Start+sizeof(RopeRefCountString)-1;
+    RopeRefCountString *Res =
+      reinterpret_cast<RopeRefCountString *>(new char[Size]);
+    Res->RefCount = 0;
+    memcpy(Res->Data, Start, End-Start);
+    return RopePiece(Res, 0, End-Start);
+  }
+
+  // Otherwise, this was a small request but we just don't have space for it
+  // Make a new chunk and share it with later allocations.
+
+  // If we had an old allocation, drop our reference to it.
+  if (AllocBuffer && --AllocBuffer->RefCount == 0)
+    delete [] (char*)AllocBuffer;
+
+  unsigned AllocSize = offsetof(RopeRefCountString, Data) + AllocChunkSize;
+  AllocBuffer = reinterpret_cast<RopeRefCountString *>(new char[AllocSize]);
+  AllocBuffer->RefCount = 0;
+  memcpy(AllocBuffer->Data, Start, Len);
+  AllocOffs = Len;
+
+  // Start out the new allocation with a refcount of 1, since we have an
+  // internal reference to it.
+  AllocBuffer->addRef();
+  return RopePiece(AllocBuffer, 0, Len);
+}
+
+
diff --git a/lib/Rewrite/Rewriter.cpp b/lib/Rewrite/Rewriter.cpp
new file mode 100644
index 0000000..376678a
--- /dev/null
+++ b/lib/Rewrite/Rewriter.cpp
@@ -0,0 +1,230 @@
+//===--- Rewriter.cpp - Code rewriting interface --------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the Rewriter class, which is used for code
+//  transformations.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Rewrite/Rewriter.h"
+#include "clang/AST/Stmt.h"
+#include "clang/AST/Decl.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Basic/SourceManager.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace clang;
+
+llvm::raw_ostream &RewriteBuffer::write(llvm::raw_ostream &os) const {
+  // FIXME: eliminate the copy by writing out each chunk at a time
+  os << std::string(begin(), end());
+  return os;
+}
+
+void RewriteBuffer::RemoveText(unsigned OrigOffset, unsigned Size) {
+  // Nothing to remove, exit early.
+  if (Size == 0) return;
+
+  unsigned RealOffset = getMappedOffset(OrigOffset, true);
+  assert(RealOffset+Size < Buffer.size() && "Invalid location");
+
+  // Remove the dead characters.
+  Buffer.erase(RealOffset, Size);
+
+  // Add a delta so that future changes are offset correctly.
+  AddReplaceDelta(OrigOffset, -Size);
+}
+
+void RewriteBuffer::InsertText(unsigned OrigOffset, const llvm::StringRef &Str,
+                               bool InsertAfter) {
+
+  // Nothing to insert, exit early.
+  if (Str.empty()) return;
+
+  unsigned RealOffset = getMappedOffset(OrigOffset, InsertAfter);
+  Buffer.insert(RealOffset, Str.begin(), Str.end());
+
+  // Add a delta so that future changes are offset correctly.
+  AddInsertDelta(OrigOffset, Str.size());
+}
+
+/// ReplaceText - This method replaces a range of characters in the input
+/// buffer with a new string.  This is effectively a combined "remove+insert"
+/// operation.
+void RewriteBuffer::ReplaceText(unsigned OrigOffset, unsigned OrigLength,
+                                const llvm::StringRef &NewStr) {
+  unsigned RealOffset = getMappedOffset(OrigOffset, true);
+  Buffer.erase(RealOffset, OrigLength);
+  Buffer.insert(RealOffset, NewStr.begin(), NewStr.end());
+  if (OrigLength != NewStr.size())
+    AddReplaceDelta(OrigOffset, NewStr.size() - OrigLength);
+}
+
+
+//===----------------------------------------------------------------------===//
+// Rewriter class
+//===----------------------------------------------------------------------===//
+
+/// getRangeSize - Return the size in bytes of the specified range if they
+/// are in the same file.  If not, this returns -1.
+int Rewriter::getRangeSize(SourceRange Range) const {
+  if (!isRewritable(Range.getBegin()) ||
+      !isRewritable(Range.getEnd())) return -1;
+
+  FileID StartFileID, EndFileID;
+  unsigned StartOff, EndOff;
+
+  StartOff = getLocationOffsetAndFileID(Range.getBegin(), StartFileID);
+  EndOff   = getLocationOffsetAndFileID(Range.getEnd(), EndFileID);
+
+  if (StartFileID != EndFileID)
+    return -1;
+
+  // If edits have been made to this buffer, the delta between the range may
+  // have changed.
+  std::map<FileID, RewriteBuffer>::const_iterator I =
+    RewriteBuffers.find(StartFileID);
+  if (I != RewriteBuffers.end()) {
+    const RewriteBuffer &RB = I->second;
+    EndOff = RB.getMappedOffset(EndOff, true);
+    StartOff = RB.getMappedOffset(StartOff);
+  }
+
+
+  // Adjust the end offset to the end of the last token, instead of being the
+  // start of the last token.
+  EndOff += Lexer::MeasureTokenLength(Range.getEnd(), *SourceMgr, *LangOpts);
+
+  return EndOff-StartOff;
+}
+
+/// getRewrittenText - Return the rewritten form of the text in the specified
+/// range.  If the start or end of the range was unrewritable or if they are
+/// in different buffers, this returns an empty string.
+///
+/// Note that this method is not particularly efficient.
+///
+std::string Rewriter::getRewrittenText(SourceRange Range) const {
+  if (!isRewritable(Range.getBegin()) ||
+      !isRewritable(Range.getEnd()))
+    return "";
+
+  FileID StartFileID, EndFileID;
+  unsigned StartOff, EndOff;
+  StartOff = getLocationOffsetAndFileID(Range.getBegin(), StartFileID);
+  EndOff   = getLocationOffsetAndFileID(Range.getEnd(), EndFileID);
+
+  if (StartFileID != EndFileID)
+    return ""; // Start and end in different buffers.
+
+  // If edits have been made to this buffer, the delta between the range may
+  // have changed.
+  std::map<FileID, RewriteBuffer>::const_iterator I =
+    RewriteBuffers.find(StartFileID);
+  if (I == RewriteBuffers.end()) {
+    // If the buffer hasn't been rewritten, just return the text from the input.
+    const char *Ptr = SourceMgr->getCharacterData(Range.getBegin());
+
+    // Adjust the end offset to the end of the last token, instead of being the
+    // start of the last token.
+    EndOff += Lexer::MeasureTokenLength(Range.getEnd(), *SourceMgr, *LangOpts);
+    return std::string(Ptr, Ptr+EndOff-StartOff);
+  }
+
+  const RewriteBuffer &RB = I->second;
+  EndOff = RB.getMappedOffset(EndOff, true);
+  StartOff = RB.getMappedOffset(StartOff);
+
+  // Adjust the end offset to the end of the last token, instead of being the
+  // start of the last token.
+  EndOff += Lexer::MeasureTokenLength(Range.getEnd(), *SourceMgr, *LangOpts);
+
+  // Advance the iterators to the right spot, yay for linear time algorithms.
+  RewriteBuffer::iterator Start = RB.begin();
+  std::advance(Start, StartOff);
+  RewriteBuffer::iterator End = Start;
+  std::advance(End, EndOff-StartOff);
+
+  return std::string(Start, End);
+}
+
+unsigned Rewriter::getLocationOffsetAndFileID(SourceLocation Loc,
+                                              FileID &FID) const {
+  assert(Loc.isValid() && "Invalid location");
+  std::pair<FileID,unsigned> V = SourceMgr->getDecomposedLoc(Loc);
+  FID = V.first;
+  return V.second;
+}
+
+
+/// getEditBuffer - Get or create a RewriteBuffer for the specified FileID.
+///
+RewriteBuffer &Rewriter::getEditBuffer(FileID FID) {
+  std::map<FileID, RewriteBuffer>::iterator I =
+    RewriteBuffers.lower_bound(FID);
+  if (I != RewriteBuffers.end() && I->first == FID)
+    return I->second;
+  I = RewriteBuffers.insert(I, std::make_pair(FID, RewriteBuffer()));
+
+  llvm::StringRef MB = SourceMgr->getBufferData(FID);
+  I->second.Initialize(MB.begin(), MB.end());
+
+  return I->second;
+}
+
+/// InsertText - Insert the specified string at the specified location in the
+/// original buffer.
+bool Rewriter::InsertText(SourceLocation Loc, const llvm::StringRef &Str,
+                          bool InsertAfter) {
+  if (!isRewritable(Loc)) return true;
+  FileID FID;
+  unsigned StartOffs = getLocationOffsetAndFileID(Loc, FID);
+  getEditBuffer(FID).InsertText(StartOffs, Str, InsertAfter);
+  return false;
+}
+
+/// RemoveText - Remove the specified text region.
+bool Rewriter::RemoveText(SourceLocation Start, unsigned Length) {
+  if (!isRewritable(Start)) return true;
+  FileID FID;
+  unsigned StartOffs = getLocationOffsetAndFileID(Start, FID);
+  getEditBuffer(FID).RemoveText(StartOffs, Length);
+  return false;
+}
+
+/// ReplaceText - This method replaces a range of characters in the input
+/// buffer with a new string.  This is effectively a combined "remove/insert"
+/// operation.
+bool Rewriter::ReplaceText(SourceLocation Start, unsigned OrigLength,
+                           const llvm::StringRef &NewStr) {
+  if (!isRewritable(Start)) return true;
+  FileID StartFileID;
+  unsigned StartOffs = getLocationOffsetAndFileID(Start, StartFileID);
+
+  getEditBuffer(StartFileID).ReplaceText(StartOffs, OrigLength, NewStr);
+  return false;
+}
+
+/// ReplaceStmt - This replaces a Stmt/Expr with another, using the pretty
+/// printer to generate the replacement code.  This returns true if the input
+/// could not be rewritten, or false if successful.
+bool Rewriter::ReplaceStmt(Stmt *From, Stmt *To) {
+  // Measaure the old text.
+  int Size = getRangeSize(From->getSourceRange());
+  if (Size == -1)
+    return true;
+
+  // Get the new text.
+  std::string SStr;
+  llvm::raw_string_ostream S(SStr);
+  To->printPretty(S, 0, PrintingPolicy(*LangOpts));
+  const std::string &Str = S.str();
+
+  ReplaceText(From->getLocStart(), Size, Str);
+  return false;
+}
diff --git a/lib/Rewrite/TokenRewriter.cpp b/lib/Rewrite/TokenRewriter.cpp
new file mode 100644
index 0000000..789d53f
--- /dev/null
+++ b/lib/Rewrite/TokenRewriter.cpp
@@ -0,0 +1,99 @@
+//===--- TokenRewriter.cpp - Token-based code rewriting interface ---------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements the TokenRewriter class, which is used for code
+//  transformations.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Rewrite/TokenRewriter.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Lex/ScratchBuffer.h"
+#include "clang/Basic/SourceManager.h"
+using namespace clang;
+
+TokenRewriter::TokenRewriter(FileID FID, SourceManager &SM,
+                             const LangOptions &LangOpts) {
+  ScratchBuf.reset(new ScratchBuffer(SM));
+
+  // Create a lexer to lex all the tokens of the main file in raw mode.
+  const llvm::MemoryBuffer *FromFile = SM.getBuffer(FID);
+  Lexer RawLex(FID, FromFile, SM, LangOpts);
+
+  // Return all comments and whitespace as tokens.
+  RawLex.SetKeepWhitespaceMode(true);
+
+  // Lex the file, populating our datastructures.
+  Token RawTok;
+  RawLex.LexFromRawLexer(RawTok);
+  while (RawTok.isNot(tok::eof)) {
+#if 0
+    if (Tok.is(tok::identifier)) {
+      // Look up the identifier info for the token.  This should use
+      // IdentifierTable directly instead of PP.
+      Tok.setIdentifierInfo(PP.LookUpIdentifierInfo(Tok));
+    }
+#endif
+
+    AddToken(RawTok, TokenList.end());
+    RawLex.LexFromRawLexer(RawTok);
+  }
+}
+
+TokenRewriter::~TokenRewriter() {
+}
+
+
+/// RemapIterator - Convert from token_iterator (a const iterator) to
+/// TokenRefTy (a non-const iterator).
+TokenRewriter::TokenRefTy TokenRewriter::RemapIterator(token_iterator I) {
+  if (I == token_end()) return TokenList.end();
+
+  // FIXME: This is horrible, we should use our own list or something to avoid
+  // this.
+  std::map<SourceLocation, TokenRefTy>::iterator MapIt =
+    TokenAtLoc.find(I->getLocation());
+  assert(MapIt != TokenAtLoc.end() && "iterator not in rewriter?");
+  return MapIt->second;
+}
+
+
+/// AddToken - Add the specified token into the Rewriter before the other
+/// position.
+TokenRewriter::TokenRefTy
+TokenRewriter::AddToken(const Token &T, TokenRefTy Where) {
+  Where = TokenList.insert(Where, T);
+
+  bool InsertSuccess = TokenAtLoc.insert(std::make_pair(T.getLocation(),
+                                                        Where)).second;
+  assert(InsertSuccess && "Token location already in rewriter!");
+  InsertSuccess = InsertSuccess;
+  return Where;
+}
+
+
+TokenRewriter::token_iterator
+TokenRewriter::AddTokenBefore(token_iterator I, const char *Val) {
+  unsigned Len = strlen(Val);
+
+  // Plop the string into the scratch buffer, then create a token for this
+  // string.
+  Token Tok;
+  Tok.startToken();
+  const char *Spelling;
+  Tok.setLocation(ScratchBuf->getToken(Val, Len, Spelling));
+  Tok.setLength(Len);
+
+  // TODO: Form a whole lexer around this and relex the token!  For now, just
+  // set kind to tok::unknown.
+  Tok.setKind(tok::unknown);
+
+  return AddToken(Tok, RemapIterator(I));
+}
+
diff --git a/lib/Runtime/Makefile b/lib/Runtime/Makefile
new file mode 100644
index 0000000..9a3c347
--- /dev/null
+++ b/lib/Runtime/Makefile
@@ -0,0 +1,99 @@
+##===- clang/lib/Runtime/Makefile --------------------------*- Makefile -*-===##
+#
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+#
+# This file defines support for building the Clang runtime libraries (which are
+# implemented by compiler-rt) and placing them in the proper locations in the
+# Clang resources directory (i.e., where the driver expects them).
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../../../..
+include $(LEVEL)/Makefile.common
+
+CLANG_VERSION := $(shell cat $(PROJ_SRC_DIR)/../../VER)
+ResourceDir := $(PROJ_OBJ_ROOT)/$(BuildMode)/lib/clang/$(CLANG_VERSION)
+PROJ_resources := $(DESTDIR)$(PROJ_prefix)/lib/clang/$(CLANG_VERSION)
+
+ResourceLibDir := $(ResourceDir)/lib
+PROJ_resources_lib := $(PROJ_resources)/lib
+
+# Expect compiler-rt to be in llvm/projects/compiler-rt
+COMPILERRT_SRC_ROOT := $(LLVM_SRC_ROOT)/projects/compiler-rt
+
+ifeq ($(shell test -d $(COMPILERRT_SRC_ROOT) && echo OK),OK)
+
+# Select the compiler-rt configuration to use, and install directory.
+#
+# FIXME: Eventually, we want some kind of configure support for this. We want to
+# build/install runtime libraries for as many targets as clang was configured to
+# support.
+RuntimeDirs :=
+ifeq ($(OS),Darwin)
+RuntimeDirs += darwin
+RuntimeLibrary.darwin.Configs = 10.4 armv6 cc_kext
+endif
+
+# Rule to build the compiler-rt libraries we need.
+#
+# We build all the libraries in a single shot to avoid recursive make as much as
+# possible.
+BuildRuntimeLibraries:
+	$(Verb) $(MAKE) -C $(COMPILERRT_SRC_ROOT) \
+	  ProjSrcRoot=$(COMPILERRT_SRC_ROOT) \
+	  ProjObjRoot=$(PROJ_OBJ_DIR) \
+	  $(RuntimeDirs:%=clang_%)
+.PHONY: BuildRuntimeLibraries
+CleanRuntimeLibraries:
+	$(Verb) $(MAKE) -C $(COMPILERRT_SRC_ROOT) \
+	  ProjSrcRoot=$(COMPILERRT_SRC_ROOT) \
+	  ProjObjRoot=$(PROJ_OBJ_DIR) \
+	  clean
+.PHONY: CleanRuntimeLibraries
+
+$(PROJ_resources_lib):
+	$(Verb) $(MKDIR) $@
+
+# Expand rules for copying/installing each individual library. We can't use
+# implicit rules here because we need to match against multiple things.
+define RuntimeLibraryTemplate
+$(PROJ_OBJ_DIR)/clang_$1/%/libcompiler_rt.a: BuildRuntimeLibraries
+	@true
+.PRECIOUS: $(PROJ_OBJ_DIR)/clang_$1/%/libcompiler_rt.a
+
+# Rule to copy the libraries to their resource directory location.
+$(ResourceLibDir)/$1/libclang_rt.%.a: \
+		$(PROJ_OBJ_DIR)/clang_$1/%/libcompiler_rt.a \
+		$(ResourceLibDir)/$1/.dir
+	$(Echo) Copying runtime library $1/$$* to build dir
+	$(Verb) cp $(PROJ_OBJ_DIR)/clang_$1/$$*/libcompiler_rt.a $$@
+RuntimeLibrary.$1: \
+		$(RuntimeLibrary.$1.Configs:%=$(ResourceLibDir)/$1/libclang_rt.%.a)
+.PHONY: RuntimeLibrary.$1
+
+$(PROJ_resources_lib)/$1: $(PROJ_resources_lib)
+	$(Verb) $(MKDIR) $$@
+
+$(PROJ_resources_lib)/$1/libclang_rt.%.a: \
+		$(ResourceLibDir)/$1/libclang_rt.%.a | $(PROJ_resources_lib)/$1
+	$(Echo) Installing compiler runtime library: $1/$$*
+	$(Verb) $(DataInstall) $$< $(PROJ_resources_lib)/$1
+
+# Rule to install runtime libraries.
+RuntimeLibraryInstall.$1: \
+		$(RuntimeLibrary.$1.Configs:%=$(PROJ_resources_lib)/$1/libclang_rt.%.a)
+.PHONY: RuntimeLibraryInstall.$1
+endef
+$(foreach lib,$(RuntimeDirs), $(eval $(call RuntimeLibraryTemplate,$(lib))))
+
+# Hook into the standard Makefile rules.
+all-local:: $(RuntimeDirs:%=RuntimeLibrary.%)
+install-local:: $(RuntimeDirs:%=RuntimeLibraryInstall.%)
+clean-local:: CleanRuntimeLibraries
+
+endif
diff --git a/lib/Sema/AnalysisBasedWarnings.cpp b/lib/Sema/AnalysisBasedWarnings.cpp
new file mode 100644
index 0000000..7c1d8cb
--- /dev/null
+++ b/lib/Sema/AnalysisBasedWarnings.cpp
@@ -0,0 +1,381 @@
+//=- AnalysisBasedWarnings.cpp - Sema warnings based on libAnalysis -*- C++ -*-=//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines analysis_warnings::[Policy,Executor].
+// Together they are used by Sema to issue warnings based on inexpensive
+// static analysis algorithms in libAnalysis.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Sema.h"
+#include "AnalysisBasedWarnings.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/AST/ExprObjC.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/StmtObjC.h"
+#include "clang/AST/StmtCXX.h"
+#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Analysis/CFG.h"
+#include "clang/Analysis/Analyses/ReachableCode.h"
+#include "llvm/ADT/BitVector.h"
+#include "llvm/Support/Casting.h"
+
+using namespace clang;
+
+//===----------------------------------------------------------------------===//
+// Unreachable code analysis.
+//===----------------------------------------------------------------------===//
+
+namespace {
+  class UnreachableCodeHandler : public reachable_code::Callback {
+    Sema &S;
+  public:
+    UnreachableCodeHandler(Sema &s) : S(s) {}
+
+    void HandleUnreachable(SourceLocation L, SourceRange R1, SourceRange R2) {
+      S.Diag(L, diag::warn_unreachable) << R1 << R2;
+    }
+  };
+}
+
+/// CheckUnreachable - Check for unreachable code.
+static void CheckUnreachable(Sema &S, AnalysisContext &AC) {
+  UnreachableCodeHandler UC(S);
+  reachable_code::FindUnreachableCode(AC, UC);
+}
+
+//===----------------------------------------------------------------------===//
+// Check for missing return value.
+//===----------------------------------------------------------------------===//
+
+enum ControlFlowKind { NeverFallThrough = 0, MaybeFallThrough = 1,
+  AlwaysFallThrough = 2, NeverFallThroughOrReturn = 3 };
+
+/// CheckFallThrough - Check that we don't fall off the end of a
+/// Statement that should return a value.
+///
+/// \returns AlwaysFallThrough iff we always fall off the end of the statement,
+/// MaybeFallThrough iff we might or might not fall off the end,
+/// NeverFallThroughOrReturn iff we never fall off the end of the statement or
+/// return.  We assume NeverFallThrough iff we never fall off the end of the
+/// statement but we may return.  We assume that functions not marked noreturn
+/// will return.
+static ControlFlowKind CheckFallThrough(AnalysisContext &AC) {
+  CFG *cfg = AC.getCFG();
+  if (cfg == 0)
+    // FIXME: This should be NeverFallThrough
+    return NeverFallThroughOrReturn;
+
+  // The CFG leaves in dead things, and we don't want the dead code paths to
+  // confuse us, so we mark all live things first.
+  llvm::BitVector live(cfg->getNumBlockIDs());
+  unsigned count = reachable_code::ScanReachableFromBlock(cfg->getEntry(),
+                                                          live);
+
+  bool AddEHEdges = AC.getAddEHEdges();
+  if (!AddEHEdges && count != cfg->getNumBlockIDs())
+    // When there are things remaining dead, and we didn't add EH edges
+    // from CallExprs to the catch clauses, we have to go back and
+    // mark them as live.
+    for (CFG::iterator I = cfg->begin(), E = cfg->end(); I != E; ++I) {
+      CFGBlock &b = **I;
+      if (!live[b.getBlockID()]) {
+        if (b.pred_begin() == b.pred_end()) {
+          if (b.getTerminator() && isa<CXXTryStmt>(b.getTerminator()))
+            // When not adding EH edges from calls, catch clauses
+            // can otherwise seem dead.  Avoid noting them as dead.
+            count += reachable_code::ScanReachableFromBlock(b, live);
+          continue;
+        }
+      }
+    }
+
+  // Now we know what is live, we check the live precessors of the exit block
+  // and look for fall through paths, being careful to ignore normal returns,
+  // and exceptional paths.
+  bool HasLiveReturn = false;
+  bool HasFakeEdge = false;
+  bool HasPlainEdge = false;
+  bool HasAbnormalEdge = false;
+  for (CFGBlock::pred_iterator I=cfg->getExit().pred_begin(),
+       E = cfg->getExit().pred_end();
+       I != E;
+       ++I) {
+    CFGBlock& B = **I;
+    if (!live[B.getBlockID()])
+      continue;
+    if (B.size() == 0) {
+      if (B.getTerminator() && isa<CXXTryStmt>(B.getTerminator())) {
+        HasAbnormalEdge = true;
+        continue;
+      }
+
+      // A labeled empty statement, or the entry block...
+      HasPlainEdge = true;
+      continue;
+    }
+    Stmt *S = B[B.size()-1];
+    if (isa<ReturnStmt>(S)) {
+      HasLiveReturn = true;
+      continue;
+    }
+    if (isa<ObjCAtThrowStmt>(S)) {
+      HasFakeEdge = true;
+      continue;
+    }
+    if (isa<CXXThrowExpr>(S)) {
+      HasFakeEdge = true;
+      continue;
+    }
+    if (const AsmStmt *AS = dyn_cast<AsmStmt>(S)) {
+      if (AS->isMSAsm()) {
+        HasFakeEdge = true;
+        HasLiveReturn = true;
+        continue;
+      }
+    }
+    if (isa<CXXTryStmt>(S)) {
+      HasAbnormalEdge = true;
+      continue;
+    }
+
+    bool NoReturnEdge = false;
+    if (CallExpr *C = dyn_cast<CallExpr>(S)) {
+      if (B.succ_begin()[0] != &cfg->getExit()) {
+        HasAbnormalEdge = true;
+        continue;
+      }
+      Expr *CEE = C->getCallee()->IgnoreParenCasts();
+      if (getFunctionExtInfo(CEE->getType()).getNoReturn()) {
+        NoReturnEdge = true;
+        HasFakeEdge = true;
+      } else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CEE)) {
+        ValueDecl *VD = DRE->getDecl();
+        if (VD->hasAttr<NoReturnAttr>()) {
+          NoReturnEdge = true;
+          HasFakeEdge = true;
+        }
+      }
+    }
+    // FIXME: Add noreturn message sends.
+    if (NoReturnEdge == false)
+      HasPlainEdge = true;
+  }
+  if (!HasPlainEdge) {
+    if (HasLiveReturn)
+      return NeverFallThrough;
+    return NeverFallThroughOrReturn;
+  }
+  if (HasAbnormalEdge || HasFakeEdge || HasLiveReturn)
+    return MaybeFallThrough;
+  // This says AlwaysFallThrough for calls to functions that are not marked
+  // noreturn, that don't return.  If people would like this warning to be more
+  // accurate, such functions should be marked as noreturn.
+  return AlwaysFallThrough;
+}
+
+struct CheckFallThroughDiagnostics {
+  unsigned diag_MaybeFallThrough_HasNoReturn;
+  unsigned diag_MaybeFallThrough_ReturnsNonVoid;
+  unsigned diag_AlwaysFallThrough_HasNoReturn;
+  unsigned diag_AlwaysFallThrough_ReturnsNonVoid;
+  unsigned diag_NeverFallThroughOrReturn;
+  bool funMode;
+
+  static CheckFallThroughDiagnostics MakeForFunction(const Decl *Func) {
+    CheckFallThroughDiagnostics D;
+    D.diag_MaybeFallThrough_HasNoReturn =
+      diag::warn_falloff_noreturn_function;
+    D.diag_MaybeFallThrough_ReturnsNonVoid =
+      diag::warn_maybe_falloff_nonvoid_function;
+    D.diag_AlwaysFallThrough_HasNoReturn =
+      diag::warn_falloff_noreturn_function;
+    D.diag_AlwaysFallThrough_ReturnsNonVoid =
+      diag::warn_falloff_nonvoid_function;
+
+    // Don't suggest that virtual functions be marked "noreturn", since they
+    // might be overridden by non-noreturn functions.
+    bool isVirtualMethod = false;
+    if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Func))
+      isVirtualMethod = Method->isVirtual();
+    
+    if (!isVirtualMethod)
+      D.diag_NeverFallThroughOrReturn =
+        diag::warn_suggest_noreturn_function;
+    else
+      D.diag_NeverFallThroughOrReturn = 0;
+    
+    D.funMode = true;
+    return D;
+  }
+
+  static CheckFallThroughDiagnostics MakeForBlock() {
+    CheckFallThroughDiagnostics D;
+    D.diag_MaybeFallThrough_HasNoReturn =
+      diag::err_noreturn_block_has_return_expr;
+    D.diag_MaybeFallThrough_ReturnsNonVoid =
+      diag::err_maybe_falloff_nonvoid_block;
+    D.diag_AlwaysFallThrough_HasNoReturn =
+      diag::err_noreturn_block_has_return_expr;
+    D.diag_AlwaysFallThrough_ReturnsNonVoid =
+      diag::err_falloff_nonvoid_block;
+    D.diag_NeverFallThroughOrReturn =
+      diag::warn_suggest_noreturn_block;
+    D.funMode = false;
+    return D;
+  }
+
+  bool checkDiagnostics(Diagnostic &D, bool ReturnsVoid,
+                        bool HasNoReturn) const {
+    if (funMode) {
+      return (D.getDiagnosticLevel(diag::warn_maybe_falloff_nonvoid_function)
+              == Diagnostic::Ignored || ReturnsVoid)
+        && (D.getDiagnosticLevel(diag::warn_noreturn_function_has_return_expr)
+              == Diagnostic::Ignored || !HasNoReturn)
+        && (D.getDiagnosticLevel(diag::warn_suggest_noreturn_block)
+              == Diagnostic::Ignored || !ReturnsVoid);
+    }
+
+    // For blocks.
+    return  ReturnsVoid && !HasNoReturn
+            && (D.getDiagnosticLevel(diag::warn_suggest_noreturn_block)
+                == Diagnostic::Ignored || !ReturnsVoid);
+  }
+};
+
+/// CheckFallThroughForFunctionDef - Check that we don't fall off the end of a
+/// function that should return a value.  Check that we don't fall off the end
+/// of a noreturn function.  We assume that functions and blocks not marked
+/// noreturn will return.
+static void CheckFallThroughForBody(Sema &S, const Decl *D, const Stmt *Body,
+                                    QualType BlockTy,
+                                    const CheckFallThroughDiagnostics& CD,
+                                    AnalysisContext &AC) {
+
+  bool ReturnsVoid = false;
+  bool HasNoReturn = false;
+
+  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+    ReturnsVoid = FD->getResultType()->isVoidType();
+    HasNoReturn = FD->hasAttr<NoReturnAttr>() ||
+       FD->getType()->getAs<FunctionType>()->getNoReturnAttr();
+  }
+  else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
+    ReturnsVoid = MD->getResultType()->isVoidType();
+    HasNoReturn = MD->hasAttr<NoReturnAttr>();
+  }
+  else if (isa<BlockDecl>(D)) {
+    if (const FunctionType *FT =
+          BlockTy->getPointeeType()->getAs<FunctionType>()) {
+      if (FT->getResultType()->isVoidType())
+        ReturnsVoid = true;
+      if (FT->getNoReturnAttr())
+        HasNoReturn = true;
+    }
+  }
+
+  Diagnostic &Diags = S.getDiagnostics();
+
+  // Short circuit for compilation speed.
+  if (CD.checkDiagnostics(Diags, ReturnsVoid, HasNoReturn))
+      return;
+
+  // FIXME: Function try block
+  if (const CompoundStmt *Compound = dyn_cast<CompoundStmt>(Body)) {
+    switch (CheckFallThrough(AC)) {
+      case MaybeFallThrough:
+        if (HasNoReturn)
+          S.Diag(Compound->getRBracLoc(),
+                 CD.diag_MaybeFallThrough_HasNoReturn);
+        else if (!ReturnsVoid)
+          S.Diag(Compound->getRBracLoc(),
+                 CD.diag_MaybeFallThrough_ReturnsNonVoid);
+        break;
+      case AlwaysFallThrough:
+        if (HasNoReturn)
+          S.Diag(Compound->getRBracLoc(),
+                 CD.diag_AlwaysFallThrough_HasNoReturn);
+        else if (!ReturnsVoid)
+          S.Diag(Compound->getRBracLoc(),
+                 CD.diag_AlwaysFallThrough_ReturnsNonVoid);
+        break;
+      case NeverFallThroughOrReturn:
+        if (ReturnsVoid && !HasNoReturn && CD.diag_NeverFallThroughOrReturn)
+          S.Diag(Compound->getLBracLoc(),
+                 CD.diag_NeverFallThroughOrReturn);
+        break;
+      case NeverFallThrough:
+        break;
+    }
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// AnalysisBasedWarnings - Worker object used by Sema to execute analysis-based
+//  warnings on a function, method, or block.
+//===----------------------------------------------------------------------===//
+
+clang::sema::AnalysisBasedWarnings::Policy::Policy() {
+  enableCheckFallThrough = 1;
+  enableCheckUnreachable = 0;
+}
+
+clang::sema::AnalysisBasedWarnings::AnalysisBasedWarnings(Sema &s) : S(s) {
+  Diagnostic &D = S.getDiagnostics();
+  DefaultPolicy.enableCheckUnreachable = (unsigned)
+    (D.getDiagnosticLevel(diag::warn_unreachable) != Diagnostic::Ignored);
+}
+
+void clang::sema::
+AnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P,
+                                     const Decl *D, QualType BlockTy) {
+
+  assert(BlockTy.isNull() || isa<BlockDecl>(D));
+
+  // We avoid doing analysis-based warnings when there are errors for
+  // two reasons:
+  // (1) The CFGs often can't be constructed (if the body is invalid), so
+  //     don't bother trying.
+  // (2) The code already has problems; running the analysis just takes more
+  //     time.
+  if (S.getDiagnostics().hasErrorOccurred())
+    return;
+
+  // Do not do any analysis for declarations in system headers if we are
+  // going to just ignore them.
+  if (S.getDiagnostics().getSuppressSystemWarnings() &&
+      S.SourceMgr.isInSystemHeader(D->getLocation()))
+    return;
+
+  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+    // For function templates, class templates and member function templates
+    // we'll do the analysis at instantiation time.
+    if (FD->isDependentContext())
+      return;
+  }
+
+  const Stmt *Body = D->getBody();
+  assert(Body);
+
+  // Don't generate EH edges for CallExprs as we'd like to avoid the n^2
+  // explosion for destrutors that can result and the compile time hit.
+  AnalysisContext AC(D, false);
+
+  // Warning: check missing 'return'
+  if (P.enableCheckFallThrough) {
+    const CheckFallThroughDiagnostics &CD =
+      (isa<BlockDecl>(D) ? CheckFallThroughDiagnostics::MakeForBlock()
+                         : CheckFallThroughDiagnostics::MakeForFunction(D));
+    CheckFallThroughForBody(S, D, Body, BlockTy, CD, AC);
+  }
+
+  // Warning: check for unreachable code
+  if (P.enableCheckUnreachable)
+    CheckUnreachable(S, AC);
+}
diff --git a/lib/Sema/AnalysisBasedWarnings.h b/lib/Sema/AnalysisBasedWarnings.h
new file mode 100644
index 0000000..dea19ba
--- /dev/null
+++ b/lib/Sema/AnalysisBasedWarnings.h
@@ -0,0 +1,55 @@
+//=- AnalysisBasedWarnings.h - Sema warnings based on libAnalysis -*- C++ -*-=//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines AnalysisBasedWarnings, a worker object used by Sema
+// that issues warnings based on dataflow-analysis.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SEMA_ANALYSIS_WARNINGS_H
+#define LLVM_CLANG_SEMA_ANALYSIS_WARNINGS_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/DenseMap.h"
+
+namespace clang {
+
+class Sema;
+
+namespace sema {
+
+class AnalysisBasedWarnings {
+public:
+  class Policy {
+    friend class AnalysisBasedWarnings;
+    // The warnings to run.
+    unsigned enableCheckFallThrough : 1;
+    unsigned enableCheckUnreachable : 1;
+  public:
+    Policy();
+    void disableCheckFallThrough() { enableCheckFallThrough = 0; }
+  };
+
+private:
+  Sema &S;
+  Policy DefaultPolicy;
+
+  enum VisitFlag { NotVisited = 0, Visited = 1, Pending = 2 };
+  llvm::DenseMap<const FunctionDecl*, VisitFlag> VisitedFD;
+
+public:
+  AnalysisBasedWarnings(Sema &s);
+
+  Policy getDefaultPolicy() { return DefaultPolicy; }
+
+  void IssueWarnings(Policy P, const Decl *D, QualType BlockTy = QualType());
+};
+
+}} // end namespace clang::sema
+
+#endif
diff --git a/lib/Sema/Android.mk b/lib/Sema/Android.mk
new file mode 100644
index 0000000..60f292e
--- /dev/null
+++ b/lib/Sema/Android.mk
@@ -0,0 +1,53 @@
+LOCAL_PATH:= $(call my-dir)
+
+# For the host only
+# =====================================================
+include $(CLEAR_VARS)
+include $(CLEAR_TBLGEN_VARS)
+
+TBLGEN_TABLES :=    \
+	DiagnosticASTKinds.inc	\
+	DiagnosticSemaKinds.inc	\
+	DiagnosticParseKinds.inc	\
+    DiagnosticCommonKinds.inc
+
+clang_sema_SRC_FILES :=	\
+	AnalysisBasedWarnings.cpp	\
+	CodeCompleteConsumer.cpp	\
+	IdentifierResolver.cpp	\
+	JumpDiagnostics.cpp	\
+	ParseAST.cpp	\
+	Sema.cpp	\
+	SemaAccess.cpp	\
+	SemaAttr.cpp	\
+	SemaCXXCast.cpp	\
+	SemaCXXScopeSpec.cpp	\
+	SemaChecking.cpp	\
+	SemaCodeComplete.cpp	\
+	SemaDecl.cpp	\
+	SemaDeclAttr.cpp	\
+	SemaDeclCXX.cpp	\
+	SemaDeclObjC.cpp	\
+	SemaExceptionSpec.cpp	\
+	SemaExpr.cpp	\
+	SemaExprCXX.cpp	\
+	SemaExprObjC.cpp	\
+	SemaInit.cpp	\
+	SemaLookup.cpp	\
+	SemaObjCProperty.cpp	\
+	SemaOverload.cpp	\
+	SemaStmt.cpp	\
+	SemaTemplate.cpp	\
+	SemaTemplateDeduction.cpp	\
+	SemaTemplateInstantiate.cpp	\
+	SemaTemplateInstantiateDecl.cpp	\
+	SemaType.cpp	\
+	TargetAttributesSema.cpp
+
+LOCAL_SRC_FILES := $(clang_sema_SRC_FILES)
+
+LOCAL_MODULE:= libclangSema
+
+include $(CLANG_HOST_BUILD_MK)
+include $(CLANG_TBLGEN_RULES_MK)
+include $(BUILD_HOST_STATIC_LIBRARY)
diff --git a/lib/Sema/CMakeLists.txt b/lib/Sema/CMakeLists.txt
new file mode 100644
index 0000000..ac0dfd6
--- /dev/null
+++ b/lib/Sema/CMakeLists.txt
@@ -0,0 +1,37 @@
+set(LLVM_NO_RTTI 1)
+
+add_clang_library(clangSema
+  AnalysisBasedWarnings.cpp
+  CodeCompleteConsumer.cpp
+  IdentifierResolver.cpp
+  JumpDiagnostics.cpp
+  ParseAST.cpp
+  Sema.cpp
+  SemaAccess.cpp
+  SemaAttr.cpp
+  SemaCXXCast.cpp
+  SemaCXXScopeSpec.cpp
+  SemaChecking.cpp
+  SemaCodeComplete.cpp
+  SemaDecl.cpp
+  SemaDeclAttr.cpp
+  SemaDeclCXX.cpp
+  SemaDeclObjC.cpp
+  SemaExceptionSpec.cpp
+  SemaExpr.cpp
+  SemaExprCXX.cpp
+  SemaExprObjC.cpp
+  SemaInit.cpp
+  SemaLookup.cpp
+  SemaObjCProperty.cpp
+  SemaOverload.cpp
+  SemaStmt.cpp
+  SemaTemplate.cpp
+  SemaTemplateDeduction.cpp
+  SemaTemplateInstantiate.cpp
+  SemaTemplateInstantiateDecl.cpp
+  SemaType.cpp
+  TargetAttributesSema.cpp
+  )
+
+add_dependencies(clangSema ClangDiagnosticSema)
diff --git a/lib/Sema/CXXFieldCollector.h b/lib/Sema/CXXFieldCollector.h
new file mode 100644
index 0000000..63c6ee3
--- /dev/null
+++ b/lib/Sema/CXXFieldCollector.h
@@ -0,0 +1,79 @@
+//===- CXXFieldCollector.h - Utility class for C++ class semantic analysis ===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file provides CXXFieldCollector that is used during parsing & semantic
+//  analysis of C++ classes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SEMA_CXXFIELDCOLLECTOR_H
+#define LLVM_CLANG_SEMA_CXXFIELDCOLLECTOR_H
+
+#include "llvm/ADT/SmallVector.h"
+
+namespace clang {
+  class FieldDecl;
+
+/// CXXFieldCollector - Used to keep track of CXXFieldDecls during parsing of
+/// C++ classes.
+class CXXFieldCollector {
+  /// Fields - Contains all FieldDecls collected during parsing of a C++
+  /// class. When a nested class is entered, its fields are appended to the
+  /// fields of its parent class, when it is exited its fields are removed.
+  llvm::SmallVector<FieldDecl*, 32> Fields;
+
+  /// FieldCount - Each entry represents the number of fields collected during
+  /// the parsing of a C++ class. When a nested class is entered, a new field
+  /// count is pushed, when it is exited, the field count is popped.
+  llvm::SmallVector<size_t, 4> FieldCount;
+
+  // Example:
+  //
+  // class C {
+  //   int x,y;
+  //   class NC {
+  //     int q;
+  //     // At this point, Fields contains [x,y,q] decls and FieldCount contains
+  //     // [2,1].
+  //   };
+  //   int z;
+  //   // At this point, Fields contains [x,y,z] decls and FieldCount contains
+  //   // [3].
+  // };
+
+public:
+  /// StartClass - Called by Sema::ActOnStartCXXClassDef.
+  void StartClass() { FieldCount.push_back(0); }
+
+  /// Add - Called by Sema::ActOnCXXMemberDeclarator.
+  void Add(FieldDecl *D) {
+    Fields.push_back(D);
+    ++FieldCount.back();
+  }
+
+  /// getCurNumField - The number of fields added to the currently parsed class.
+  size_t getCurNumFields() const {
+    assert(!FieldCount.empty() && "no currently-parsed class");
+    return FieldCount.back();
+  }
+
+  /// getCurFields - Pointer to array of fields added to the currently parsed
+  /// class.
+  FieldDecl **getCurFields() { return &*(Fields.end() - getCurNumFields()); }
+
+  /// FinishClass - Called by Sema::ActOnFinishCXXClassDef.
+  void FinishClass() {
+    Fields.resize(Fields.size() - getCurNumFields());
+    FieldCount.pop_back();
+  }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/lib/Sema/CodeCompleteConsumer.cpp b/lib/Sema/CodeCompleteConsumer.cpp
new file mode 100644
index 0000000..0ef9a15
--- /dev/null
+++ b/lib/Sema/CodeCompleteConsumer.cpp
@@ -0,0 +1,627 @@
+//===--- CodeCompleteConsumer.cpp - Code Completion Interface ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements the CodeCompleteConsumer class.
+//
+//===----------------------------------------------------------------------===//
+#include "clang/Sema/CodeCompleteConsumer.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/Parse/Scope.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang-c/Index.h"
+#include "Sema.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <cstring>
+#include <functional>
+
+using namespace clang;
+using llvm::StringRef;
+
+//===----------------------------------------------------------------------===//
+// Code completion string implementation
+//===----------------------------------------------------------------------===//
+CodeCompletionString::Chunk::Chunk(ChunkKind Kind, llvm::StringRef Text) 
+  : Kind(Kind), Text("")
+{
+  switch (Kind) {
+  case CK_TypedText:
+  case CK_Text:
+  case CK_Placeholder:
+  case CK_Informative:
+  case CK_ResultType:
+  case CK_CurrentParameter: {
+    char *New = new char [Text.size() + 1];
+    std::memcpy(New, Text.data(), Text.size());
+    New[Text.size()] = '\0';
+    this->Text = New;
+    break;
+  }
+
+  case CK_Optional:
+    llvm_unreachable("Optional strings cannot be created from text");
+    break;
+      
+  case CK_LeftParen:
+    this->Text = "(";
+    break;
+
+  case CK_RightParen:
+    this->Text = ")";
+    break;
+
+  case CK_LeftBracket:
+    this->Text = "[";
+    break;
+    
+  case CK_RightBracket:
+    this->Text = "]";
+    break;
+    
+  case CK_LeftBrace:
+    this->Text = "{";
+    break;
+
+  case CK_RightBrace:
+    this->Text = "}";
+    break;
+
+  case CK_LeftAngle:
+    this->Text = "<";
+    break;
+    
+  case CK_RightAngle:
+    this->Text = ">";
+    break;
+      
+  case CK_Comma:
+    this->Text = ", ";
+    break;
+
+  case CK_Colon:
+    this->Text = ":";
+    break;
+
+  case CK_SemiColon:
+    this->Text = ";";
+    break;
+
+  case CK_Equal:
+    this->Text = " = ";
+    break;
+
+  case CK_HorizontalSpace:
+    this->Text = " ";
+    break;
+
+  case CK_VerticalSpace:
+    this->Text = "\n";
+    break;
+  }
+}
+
+CodeCompletionString::Chunk
+CodeCompletionString::Chunk::CreateText(StringRef Text) {
+  return Chunk(CK_Text, Text);
+}
+
+CodeCompletionString::Chunk 
+CodeCompletionString::Chunk::CreateOptional(
+                                 std::auto_ptr<CodeCompletionString> Optional) {
+  Chunk Result;
+  Result.Kind = CK_Optional;
+  Result.Optional = Optional.release();
+  return Result;
+}
+
+CodeCompletionString::Chunk 
+CodeCompletionString::Chunk::CreatePlaceholder(StringRef Placeholder) {
+  return Chunk(CK_Placeholder, Placeholder);
+}
+
+CodeCompletionString::Chunk 
+CodeCompletionString::Chunk::CreateInformative(StringRef Informative) {
+  return Chunk(CK_Informative, Informative);
+}
+
+CodeCompletionString::Chunk 
+CodeCompletionString::Chunk::CreateResultType(StringRef ResultType) {
+  return Chunk(CK_ResultType, ResultType);
+}
+
+CodeCompletionString::Chunk 
+CodeCompletionString::Chunk::CreateCurrentParameter(
+                                                StringRef CurrentParameter) {
+  return Chunk(CK_CurrentParameter, CurrentParameter);
+}
+
+CodeCompletionString::Chunk CodeCompletionString::Chunk::Clone() const {
+  switch (Kind) {
+  case CK_TypedText:
+  case CK_Text:
+  case CK_Placeholder:
+  case CK_Informative:
+  case CK_ResultType:
+  case CK_CurrentParameter:
+  case CK_LeftParen:
+  case CK_RightParen:
+  case CK_LeftBracket:
+  case CK_RightBracket:
+  case CK_LeftBrace:
+  case CK_RightBrace:
+  case CK_LeftAngle:
+  case CK_RightAngle:
+  case CK_Comma:
+  case CK_Colon:
+  case CK_SemiColon:
+  case CK_Equal:
+  case CK_HorizontalSpace:
+  case CK_VerticalSpace:
+    return Chunk(Kind, Text);
+      
+  case CK_Optional: {
+    std::auto_ptr<CodeCompletionString> Opt(Optional->Clone());
+    return CreateOptional(Opt);
+  }
+  }
+
+  // Silence GCC warning.
+  return Chunk();
+}
+
+void
+CodeCompletionString::Chunk::Destroy() {
+  switch (Kind) {
+  case CK_Optional: 
+    delete Optional; 
+    break;
+      
+  case CK_TypedText:
+  case CK_Text: 
+  case CK_Placeholder:
+  case CK_Informative:
+  case CK_ResultType:
+  case CK_CurrentParameter:
+    delete [] Text;
+    break;
+
+  case CK_LeftParen:
+  case CK_RightParen:
+  case CK_LeftBracket:
+  case CK_RightBracket:
+  case CK_LeftBrace:
+  case CK_RightBrace:
+  case CK_LeftAngle:
+  case CK_RightAngle:
+  case CK_Comma:
+  case CK_Colon:
+  case CK_SemiColon:
+  case CK_Equal:
+  case CK_HorizontalSpace:
+  case CK_VerticalSpace:
+    break;
+  }
+}
+
+CodeCompletionString::~CodeCompletionString() {
+  std::for_each(Chunks.begin(), Chunks.end(), 
+                std::mem_fun_ref(&Chunk::Destroy));
+}
+
+std::string CodeCompletionString::getAsString() const {
+  std::string Result;
+  llvm::raw_string_ostream OS(Result);
+                          
+  for (iterator C = begin(), CEnd = end(); C != CEnd; ++C) {
+    switch (C->Kind) {
+    case CK_Optional: OS << "{#" << C->Optional->getAsString() << "#}"; break;
+    case CK_Placeholder: OS << "<#" << C->Text << "#>"; break;
+        
+    case CK_Informative: 
+    case CK_ResultType:
+      OS << "[#" << C->Text << "#]"; 
+      break;
+        
+    case CK_CurrentParameter: OS << "<#" << C->Text << "#>"; break;
+    default: OS << C->Text; break;
+    }
+  }
+  OS.flush();
+  return Result;
+}
+
+const char *CodeCompletionString::getTypedText() const {
+  for (iterator C = begin(), CEnd = end(); C != CEnd; ++C)
+    if (C->Kind == CK_TypedText)
+      return C->Text;
+  
+  return 0;
+}
+
+CodeCompletionString *CodeCompletionString::Clone() const {
+  CodeCompletionString *Result = new CodeCompletionString;
+  for (iterator C = begin(), CEnd = end(); C != CEnd; ++C)
+    Result->AddChunk(C->Clone());
+  return Result;
+}
+
+static void WriteUnsigned(llvm::raw_ostream &OS, unsigned Value) {
+  OS.write((const char *)&Value, sizeof(unsigned));
+}
+
+static bool ReadUnsigned(const char *&Memory, const char *MemoryEnd,
+                         unsigned &Value) {
+  if (Memory + sizeof(unsigned) > MemoryEnd)
+    return true;
+
+  memmove(&Value, Memory, sizeof(unsigned));
+  Memory += sizeof(unsigned);
+  return false;
+}
+
+void CodeCompletionString::Serialize(llvm::raw_ostream &OS) const {
+  // Write the number of chunks.
+  WriteUnsigned(OS, size());
+
+  for (iterator C = begin(), CEnd = end(); C != CEnd; ++C) {
+    WriteUnsigned(OS, C->Kind);
+
+    switch (C->Kind) {
+    case CK_TypedText:
+    case CK_Text:
+    case CK_Placeholder:
+    case CK_Informative:
+    case CK_ResultType:
+    case CK_CurrentParameter: {
+      const char *Text = C->Text;
+      unsigned StrLen = strlen(Text);
+      WriteUnsigned(OS, StrLen);
+      OS.write(Text, StrLen);
+      break;
+    }
+
+    case CK_Optional:
+      C->Optional->Serialize(OS);
+      break;
+
+    case CK_LeftParen:
+    case CK_RightParen:
+    case CK_LeftBracket:
+    case CK_RightBracket:
+    case CK_LeftBrace:
+    case CK_RightBrace:
+    case CK_LeftAngle:
+    case CK_RightAngle:
+    case CK_Comma:
+    case CK_Colon:
+    case CK_SemiColon:
+    case CK_Equal:
+    case CK_HorizontalSpace:
+    case CK_VerticalSpace:
+      break;
+    }
+  }
+}
+
+CodeCompletionString *CodeCompletionString::Deserialize(const char *&Str,
+                                                        const char *StrEnd) {
+  if (Str == StrEnd || *Str == 0)
+    return 0;
+
+  CodeCompletionString *Result = new CodeCompletionString;
+  unsigned NumBlocks;
+  if (ReadUnsigned(Str, StrEnd, NumBlocks))
+    return Result;
+
+  for (unsigned I = 0; I != NumBlocks; ++I) {
+    if (Str + 1 >= StrEnd)
+      break;
+
+    // Parse the next kind.
+    unsigned KindValue;
+    if (ReadUnsigned(Str, StrEnd, KindValue))
+      return Result;
+
+    switch (ChunkKind Kind = (ChunkKind)KindValue) {
+    case CK_TypedText:
+    case CK_Text:
+    case CK_Placeholder:
+    case CK_Informative:
+    case CK_ResultType:
+    case CK_CurrentParameter: {
+      unsigned StrLen;
+      if (ReadUnsigned(Str, StrEnd, StrLen) || (Str + StrLen > StrEnd))
+        return Result;
+
+      Result->AddChunk(Chunk(Kind, StringRef(Str, StrLen)));
+      Str += StrLen;
+      break;
+    }
+
+    case CK_Optional: {
+      std::auto_ptr<CodeCompletionString> Optional(Deserialize(Str, StrEnd));
+      Result->AddOptionalChunk(Optional);
+      break;
+    }
+
+    case CK_LeftParen:
+    case CK_RightParen:
+    case CK_LeftBracket:
+    case CK_RightBracket:
+    case CK_LeftBrace:
+    case CK_RightBrace:
+    case CK_LeftAngle:
+    case CK_RightAngle:
+    case CK_Comma:
+    case CK_Colon:
+    case CK_SemiColon:
+    case CK_Equal:
+    case CK_HorizontalSpace:
+    case CK_VerticalSpace:
+      Result->AddChunk(Chunk(Kind));
+      break;      
+    }
+  };
+  
+  return Result;
+}
+
+void CodeCompleteConsumer::Result::Destroy() {
+  if (Kind == RK_Pattern) {
+    delete Pattern;
+    Pattern = 0;
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// Code completion overload candidate implementation
+//===----------------------------------------------------------------------===//
+FunctionDecl *
+CodeCompleteConsumer::OverloadCandidate::getFunction() const {
+  if (getKind() == CK_Function)
+    return Function;
+  else if (getKind() == CK_FunctionTemplate)
+    return FunctionTemplate->getTemplatedDecl();
+  else
+    return 0;
+}
+
+const FunctionType *
+CodeCompleteConsumer::OverloadCandidate::getFunctionType() const {
+  switch (Kind) {
+  case CK_Function:
+    return Function->getType()->getAs<FunctionType>();
+      
+  case CK_FunctionTemplate:
+    return FunctionTemplate->getTemplatedDecl()->getType()
+             ->getAs<FunctionType>();
+      
+  case CK_FunctionType:
+    return Type;
+  }
+  
+  return 0;
+}
+
+//===----------------------------------------------------------------------===//
+// Code completion consumer implementation
+//===----------------------------------------------------------------------===//
+
+CodeCompleteConsumer::~CodeCompleteConsumer() { }
+
+void 
+PrintingCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &SemaRef,
+                                                         Result *Results, 
+                                                         unsigned NumResults) {
+  // Print the results.
+  for (unsigned I = 0; I != NumResults; ++I) {
+    OS << "COMPLETION: ";
+    switch (Results[I].Kind) {
+    case Result::RK_Declaration:
+      OS << Results[I].Declaration;
+      if (Results[I].Hidden)
+        OS << " (Hidden)";
+      if (CodeCompletionString *CCS 
+            = Results[I].CreateCodeCompletionString(SemaRef)) {
+        OS << " : " << CCS->getAsString();
+        delete CCS;
+      }
+        
+      OS << '\n';
+      break;
+      
+    case Result::RK_Keyword:
+      OS << Results[I].Keyword << '\n';
+      break;
+        
+    case Result::RK_Macro: {
+      OS << Results[I].Macro->getName();
+      if (CodeCompletionString *CCS 
+            = Results[I].CreateCodeCompletionString(SemaRef)) {
+        OS << " : " << CCS->getAsString();
+        delete CCS;
+      }
+      OS << '\n';
+      break;
+    }
+        
+    case Result::RK_Pattern: {
+      OS << "Pattern : " 
+         << Results[I].Pattern->getAsString() << '\n';
+      break;
+    }
+    }
+  }
+  
+  // Once we've printed the code-completion results, suppress remaining
+  // diagnostics.
+  // FIXME: Move this somewhere else!
+  SemaRef.PP.getDiagnostics().setSuppressAllDiagnostics();
+}
+
+void 
+PrintingCodeCompleteConsumer::ProcessOverloadCandidates(Sema &SemaRef,
+                                                        unsigned CurrentArg,
+                                              OverloadCandidate *Candidates,
+                                                     unsigned NumCandidates) {
+  for (unsigned I = 0; I != NumCandidates; ++I) {
+    if (CodeCompletionString *CCS
+          = Candidates[I].CreateSignatureString(CurrentArg, SemaRef)) {
+      OS << "OVERLOAD: " << CCS->getAsString() << "\n";
+      delete CCS;
+    }
+  }
+
+  // Once we've printed the code-completion results, suppress remaining
+  // diagnostics.
+  // FIXME: Move this somewhere else!
+  SemaRef.PP.getDiagnostics().setSuppressAllDiagnostics();
+}
+
+void 
+CIndexCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &SemaRef,
+                                                       Result *Results, 
+                                                       unsigned NumResults) {
+  // Print the results.
+  for (unsigned I = 0; I != NumResults; ++I) {
+    CXCursorKind Kind = CXCursor_NotImplemented;
+
+    switch (Results[I].Kind) {
+    case Result::RK_Declaration:
+      switch (Results[I].Declaration->getKind()) {
+      case Decl::Record:
+      case Decl::CXXRecord:
+      case Decl::ClassTemplateSpecialization: {
+        RecordDecl *Record = cast<RecordDecl>(Results[I].Declaration);
+        if (Record->isStruct())
+          Kind = CXCursor_StructDecl;
+        else if (Record->isUnion())
+          Kind = CXCursor_UnionDecl;
+        else
+          Kind = CXCursor_ClassDecl;
+        break;
+      }
+        
+      case Decl::ObjCMethod: {
+        ObjCMethodDecl *Method = cast<ObjCMethodDecl>(Results[I].Declaration);
+        if (Method->isInstanceMethod())
+            Kind = CXCursor_ObjCInstanceMethodDecl;
+        else
+          Kind = CXCursor_ObjCClassMethodDecl;
+        break;
+      }
+        
+      case Decl::Typedef:
+        Kind = CXCursor_TypedefDecl;
+        break;
+        
+      case Decl::Enum:
+        Kind = CXCursor_EnumDecl;
+        break;
+        
+      case Decl::Field:
+        Kind = CXCursor_FieldDecl;
+        break;
+        
+      case Decl::EnumConstant:
+        Kind = CXCursor_EnumConstantDecl;
+        break;
+        
+      case Decl::Function:
+      case Decl::CXXMethod:
+      case Decl::CXXConstructor:
+      case Decl::CXXDestructor:
+      case Decl::CXXConversion:
+        Kind = CXCursor_FunctionDecl;
+        break;
+        
+      case Decl::Var:
+        Kind = CXCursor_VarDecl;
+        break;
+        
+      case Decl::ParmVar:
+        Kind = CXCursor_ParmDecl;
+        break;
+        
+      case Decl::ObjCInterface:
+        Kind = CXCursor_ObjCInterfaceDecl;
+        break;
+        
+      case Decl::ObjCCategory:
+        Kind = CXCursor_ObjCCategoryDecl;
+        break;
+        
+      case Decl::ObjCProtocol:
+        Kind = CXCursor_ObjCProtocolDecl;
+        break;
+        
+      case Decl::ObjCProperty:
+        Kind = CXCursor_ObjCPropertyDecl;
+        break;
+        
+      case Decl::ObjCIvar:
+        Kind = CXCursor_ObjCIvarDecl;
+        break;
+        
+      case Decl::ObjCImplementation:
+        Kind = CXCursor_ObjCImplementationDecl;
+        break;
+        
+      case Decl::ObjCCategoryImpl:
+        Kind = CXCursor_ObjCCategoryImplDecl;
+        break;
+        
+      default:
+        break;
+      }
+      break;
+
+    case Result::RK_Macro:
+      Kind = CXCursor_MacroDefinition;
+      break;
+
+    case Result::RK_Keyword:
+    case Result::RK_Pattern:
+      Kind = CXCursor_NotImplemented;
+      break;
+    }
+
+    WriteUnsigned(OS, Kind);
+    CodeCompletionString *CCS = Results[I].CreateCodeCompletionString(SemaRef);
+    assert(CCS && "No code-completion string?");
+    CCS->Serialize(OS);
+    delete CCS;
+  }
+  
+  // Once we've printed the code-completion results, suppress remaining
+  // diagnostics.
+  // FIXME: Move this somewhere else!
+  SemaRef.PP.getDiagnostics().setSuppressAllDiagnostics();
+}
+
+void 
+CIndexCodeCompleteConsumer::ProcessOverloadCandidates(Sema &SemaRef,
+                                                      unsigned CurrentArg,
+                                                OverloadCandidate *Candidates,
+                                                       unsigned NumCandidates) {
+  for (unsigned I = 0; I != NumCandidates; ++I) {
+    WriteUnsigned(OS, CXCursor_NotImplemented);
+    CodeCompletionString *CCS
+      = Candidates[I].CreateSignatureString(CurrentArg, SemaRef);
+    assert(CCS && "No code-completion string?");
+    CCS->Serialize(OS);
+    delete CCS;
+  }
+  
+  // Once we've printed the code-completion results, suppress remaining
+  // diagnostics.
+  // FIXME: Move this somewhere else!
+  SemaRef.PP.getDiagnostics().setSuppressAllDiagnostics();
+}
diff --git a/lib/Sema/IdentifierResolver.cpp b/lib/Sema/IdentifierResolver.cpp
new file mode 100644
index 0000000..b09526e
--- /dev/null
+++ b/lib/Sema/IdentifierResolver.cpp
@@ -0,0 +1,263 @@
+//===- IdentifierResolver.cpp - Lexical Scope Name lookup -------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the IdentifierResolver class, which is used for lexical
+// scoped lookup, based on declaration names.
+//
+//===----------------------------------------------------------------------===//
+
+#include "IdentifierResolver.h"
+#include "clang/Basic/LangOptions.h"
+
+using namespace clang;
+
+//===----------------------------------------------------------------------===//
+// IdDeclInfoMap class
+//===----------------------------------------------------------------------===//
+
+/// IdDeclInfoMap - Associates IdDeclInfos with declaration names.
+/// Allocates 'pools' (vectors of IdDeclInfos) to avoid allocating each
+/// individual IdDeclInfo to heap.
+class IdentifierResolver::IdDeclInfoMap {
+  static const unsigned int POOL_SIZE = 512;
+
+  /// We use our own linked-list implementation because it is sadly
+  /// impossible to add something to a pre-C++0x STL container without
+  /// a completely unnecessary copy.
+  struct IdDeclInfoPool {
+    IdDeclInfoPool(IdDeclInfoPool *Next) : Next(Next) {}
+    
+    IdDeclInfoPool *Next;
+    IdDeclInfo Pool[POOL_SIZE];
+  };
+  
+  IdDeclInfoPool *CurPool;
+  unsigned int CurIndex;
+
+public:
+  IdDeclInfoMap() : CurPool(0), CurIndex(POOL_SIZE) {}
+
+  ~IdDeclInfoMap() {
+    IdDeclInfoPool *Cur = CurPool;
+    while (IdDeclInfoPool *P = Cur) {
+      Cur = Cur->Next;
+      delete P;
+    }
+  }
+
+  /// Returns the IdDeclInfo associated to the DeclarationName.
+  /// It creates a new IdDeclInfo if one was not created before for this id.
+  IdDeclInfo &operator[](DeclarationName Name);
+};
+
+
+//===----------------------------------------------------------------------===//
+// IdDeclInfo Implementation
+//===----------------------------------------------------------------------===//
+
+/// RemoveDecl - Remove the decl from the scope chain.
+/// The decl must already be part of the decl chain.
+void IdentifierResolver::IdDeclInfo::RemoveDecl(NamedDecl *D) {
+  for (DeclsTy::iterator I = Decls.end(); I != Decls.begin(); --I) {
+    if (D == *(I-1)) {
+      Decls.erase(I-1);
+      return;
+    }
+  }
+
+  assert(0 && "Didn't find this decl on its identifier's chain!");
+}
+
+bool
+IdentifierResolver::IdDeclInfo::ReplaceDecl(NamedDecl *Old, NamedDecl *New) {
+  for (DeclsTy::iterator I = Decls.end(); I != Decls.begin(); --I) {
+    if (Old == *(I-1)) {
+      *(I - 1) = New;
+      return true;
+    }
+  }
+
+  return false;
+}
+
+
+//===----------------------------------------------------------------------===//
+// IdentifierResolver Implementation
+//===----------------------------------------------------------------------===//
+
+IdentifierResolver::IdentifierResolver(const LangOptions &langOpt)
+    : LangOpt(langOpt), IdDeclInfos(new IdDeclInfoMap) {
+}
+IdentifierResolver::~IdentifierResolver() {
+  delete IdDeclInfos;
+}
+
+/// isDeclInScope - If 'Ctx' is a function/method, isDeclInScope returns true
+/// if 'D' is in Scope 'S', otherwise 'S' is ignored and isDeclInScope returns
+/// true if 'D' belongs to the given declaration context.
+bool IdentifierResolver::isDeclInScope(Decl *D, DeclContext *Ctx,
+                                       ASTContext &Context, Scope *S) const {
+  Ctx = Ctx->getLookupContext();
+
+  if (Ctx->isFunctionOrMethod()) {
+    // Ignore the scopes associated within transparent declaration contexts.
+    while (S->getEntity() &&
+           ((DeclContext *)S->getEntity())->isTransparentContext())
+      S = S->getParent();
+
+    if (S->isDeclScope(Action::DeclPtrTy::make(D)))
+      return true;
+    if (LangOpt.CPlusPlus) {
+      // C++ 3.3.2p3:
+      // The name declared in a catch exception-declaration is local to the
+      // handler and shall not be redeclared in the outermost block of the
+      // handler.
+      // C++ 3.3.2p4:
+      // Names declared in the for-init-statement, and in the condition of if,
+      // while, for, and switch statements are local to the if, while, for, or
+      // switch statement (including the controlled statement), and shall not be
+      // redeclared in a subsequent condition of that statement nor in the
+      // outermost block (or, for the if statement, any of the outermost blocks)
+      // of the controlled statement.
+      //
+      assert(S->getParent() && "No TUScope?");
+      if (S->getParent()->getFlags() & Scope::ControlScope)
+        return S->getParent()->isDeclScope(Action::DeclPtrTy::make(D));
+    }
+    return false;
+  }
+
+  return D->getDeclContext()->getLookupContext()->Equals(Ctx);
+}
+
+/// AddDecl - Link the decl to its shadowed decl chain.
+void IdentifierResolver::AddDecl(NamedDecl *D) {
+  DeclarationName Name = D->getDeclName();
+  void *Ptr = Name.getFETokenInfo<void>();
+
+  if (!Ptr) {
+    Name.setFETokenInfo(D);
+    return;
+  }
+
+  IdDeclInfo *IDI;
+
+  if (isDeclPtr(Ptr)) {
+    Name.setFETokenInfo(NULL);
+    IDI = &(*IdDeclInfos)[Name];
+    NamedDecl *PrevD = static_cast<NamedDecl*>(Ptr);
+    IDI->AddDecl(PrevD);
+  } else
+    IDI = toIdDeclInfo(Ptr);
+
+  IDI->AddDecl(D);
+}
+
+/// RemoveDecl - Unlink the decl from its shadowed decl chain.
+/// The decl must already be part of the decl chain.
+void IdentifierResolver::RemoveDecl(NamedDecl *D) {
+  assert(D && "null param passed");
+  DeclarationName Name = D->getDeclName();
+  void *Ptr = Name.getFETokenInfo<void>();
+
+  assert(Ptr && "Didn't find this decl on its identifier's chain!");
+
+  if (isDeclPtr(Ptr)) {
+    assert(D == Ptr && "Didn't find this decl on its identifier's chain!");
+    Name.setFETokenInfo(NULL);
+    return;
+  }
+
+  return toIdDeclInfo(Ptr)->RemoveDecl(D);
+}
+
+bool IdentifierResolver::ReplaceDecl(NamedDecl *Old, NamedDecl *New) {
+  assert(Old->getDeclName() == New->getDeclName() &&
+         "Cannot replace a decl with another decl of a different name");
+
+  DeclarationName Name = Old->getDeclName();
+  void *Ptr = Name.getFETokenInfo<void>();
+
+  if (!Ptr)
+    return false;
+
+  if (isDeclPtr(Ptr)) {
+    if (Ptr == Old) {
+      Name.setFETokenInfo(New);
+      return true;
+    }
+    return false;
+  }
+
+  return toIdDeclInfo(Ptr)->ReplaceDecl(Old, New);
+}
+
+/// begin - Returns an iterator for decls with name 'Name'.
+IdentifierResolver::iterator
+IdentifierResolver::begin(DeclarationName Name) {
+  void *Ptr = Name.getFETokenInfo<void>();
+  if (!Ptr) return end();
+
+  if (isDeclPtr(Ptr))
+    return iterator(static_cast<NamedDecl*>(Ptr));
+
+  IdDeclInfo *IDI = toIdDeclInfo(Ptr);
+
+  IdDeclInfo::DeclsTy::iterator I = IDI->decls_end();
+  if (I != IDI->decls_begin())
+    return iterator(I-1);
+  // No decls found.
+  return end();
+}
+
+void IdentifierResolver::AddDeclToIdentifierChain(IdentifierInfo *II,
+                                                  NamedDecl *D) {
+  void *Ptr = II->getFETokenInfo<void>();
+
+  if (!Ptr) {
+    II->setFETokenInfo(D);
+    return;
+  }
+
+  IdDeclInfo *IDI;
+
+  if (isDeclPtr(Ptr)) {
+    II->setFETokenInfo(NULL);
+    IDI = &(*IdDeclInfos)[II];
+    NamedDecl *PrevD = static_cast<NamedDecl*>(Ptr);
+    IDI->AddDecl(PrevD);
+  } else
+    IDI = toIdDeclInfo(Ptr);
+
+  IDI->AddDecl(D);
+}
+
+//===----------------------------------------------------------------------===//
+// IdDeclInfoMap Implementation
+//===----------------------------------------------------------------------===//
+
+/// Returns the IdDeclInfo associated to the DeclarationName.
+/// It creates a new IdDeclInfo if one was not created before for this id.
+IdentifierResolver::IdDeclInfo &
+IdentifierResolver::IdDeclInfoMap::operator[](DeclarationName Name) {
+  void *Ptr = Name.getFETokenInfo<void>();
+
+  if (Ptr) return *toIdDeclInfo(Ptr);
+
+  if (CurIndex == POOL_SIZE) {
+    CurPool = new IdDeclInfoPool(CurPool);
+    CurIndex = 0;
+  }
+  IdDeclInfo *IDI = &CurPool->Pool[CurIndex];
+  Name.setFETokenInfo(reinterpret_cast<void*>(
+                              reinterpret_cast<uintptr_t>(IDI) | 0x1)
+                                                                     );
+  ++CurIndex;
+  return *IDI;
+}
diff --git a/lib/Sema/IdentifierResolver.h b/lib/Sema/IdentifierResolver.h
new file mode 100644
index 0000000..59bd834
--- /dev/null
+++ b/lib/Sema/IdentifierResolver.h
@@ -0,0 +1,203 @@
+//===- IdentifierResolver.h - Lexical Scope Name lookup ---------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the IdentifierResolver class, which is used for lexical
+// scoped lookup, based on declaration names.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_SEMA_IDENTIFIERRESOLVER_H
+#define LLVM_CLANG_AST_SEMA_IDENTIFIERRESOLVER_H
+
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Parse/Scope.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclarationName.h"
+#include "clang/AST/DeclCXX.h"
+
+namespace clang {
+
+/// IdentifierResolver - Keeps track of shadowed decls on enclosing
+/// scopes.  It manages the shadowing chains of declaration names and
+/// implements efficent decl lookup based on a declaration name.
+class IdentifierResolver {
+
+  /// IdDeclInfo - Keeps track of information about decls associated
+  /// to a particular declaration name. IdDeclInfos are lazily
+  /// constructed and assigned to a declaration name the first time a
+  /// decl with that declaration name is shadowed in some scope.
+  class IdDeclInfo {
+  public:
+    typedef llvm::SmallVector<NamedDecl*, 2> DeclsTy;
+
+    inline DeclsTy::iterator decls_begin() { return Decls.begin(); }
+    inline DeclsTy::iterator decls_end() { return Decls.end(); }
+
+    void AddDecl(NamedDecl *D) { Decls.push_back(D); }
+
+    /// RemoveDecl - Remove the decl from the scope chain.
+    /// The decl must already be part of the decl chain.
+    void RemoveDecl(NamedDecl *D);
+
+    /// Replaces the Old declaration with the New declaration. If the
+    /// replacement is successful, returns true. If the old
+    /// declaration was not found, returns false.
+    bool ReplaceDecl(NamedDecl *Old, NamedDecl *New);
+
+  private:
+    DeclsTy Decls;
+  };
+
+public:
+
+  /// iterator - Iterate over the decls of a specified declaration name.
+  /// It will walk or not the parent declaration contexts depending on how
+  /// it was instantiated.
+  class iterator {
+  public:
+    typedef NamedDecl *             value_type;
+    typedef NamedDecl *             reference;
+    typedef NamedDecl *             pointer;
+    typedef std::input_iterator_tag iterator_category;
+    typedef std::ptrdiff_t          difference_type;
+
+    /// Ptr - There are 3 forms that 'Ptr' represents:
+    /// 1) A single NamedDecl. (Ptr & 0x1 == 0)
+    /// 2) A IdDeclInfo::DeclsTy::iterator that traverses only the decls of the
+    ///    same declaration context. (Ptr & 0x3 == 0x1)
+    /// 3) A IdDeclInfo::DeclsTy::iterator that traverses the decls of parent
+    ///    declaration contexts too. (Ptr & 0x3 == 0x3)
+    uintptr_t Ptr;
+    typedef IdDeclInfo::DeclsTy::iterator BaseIter;
+
+    /// A single NamedDecl. (Ptr & 0x1 == 0)
+    iterator(NamedDecl *D) {
+      Ptr = reinterpret_cast<uintptr_t>(D);
+      assert((Ptr & 0x1) == 0 && "Invalid Ptr!");
+    }
+    /// A IdDeclInfo::DeclsTy::iterator that walks or not the parent declaration
+    /// contexts depending on 'LookInParentCtx'.
+    iterator(BaseIter I) {
+      Ptr = reinterpret_cast<uintptr_t>(I) | 0x1;
+    }
+
+    bool isIterator() const { return (Ptr & 0x1); }
+
+    BaseIter getIterator() const {
+      assert(isIterator() && "Ptr not an iterator!");
+      return reinterpret_cast<BaseIter>(Ptr & ~0x3);
+    }
+
+    friend class IdentifierResolver;
+  public:
+    iterator() : Ptr(0) {}
+
+    NamedDecl *operator*() const {
+      if (isIterator())
+        return *getIterator();
+      else
+        return reinterpret_cast<NamedDecl*>(Ptr);
+    }
+
+    bool operator==(const iterator &RHS) const {
+      return Ptr == RHS.Ptr;
+    }
+    bool operator!=(const iterator &RHS) const {
+      return Ptr != RHS.Ptr;
+    }
+
+    // Preincrement.
+    iterator& operator++() {
+      if (!isIterator()) // common case.
+        Ptr = 0;
+      else {
+        NamedDecl *D = **this;
+        void *InfoPtr = D->getDeclName().getFETokenInfo<void>();
+        assert(!isDeclPtr(InfoPtr) && "Decl with wrong id ?");
+        IdDeclInfo *Info = toIdDeclInfo(InfoPtr);
+
+        BaseIter I = getIterator();
+        if (I != Info->decls_begin())
+          *this = iterator(I-1);
+        else // No more decls.
+          *this = iterator();
+      }
+      return *this;
+    }
+
+    uintptr_t getAsOpaqueValue() const { return Ptr; }
+
+    static iterator getFromOpaqueValue(uintptr_t P) {
+      iterator Result;
+      Result.Ptr = P;
+      return Result;
+    }
+  };
+
+  /// begin - Returns an iterator for decls with the name 'Name'.
+  static iterator begin(DeclarationName Name);
+
+  /// end - Returns an iterator that has 'finished'.
+  static iterator end() {
+    return iterator();
+  }
+
+  /// isDeclInScope - If 'Ctx' is a function/method, isDeclInScope returns true
+  /// if 'D' is in Scope 'S', otherwise 'S' is ignored and isDeclInScope returns
+  /// true if 'D' belongs to the given declaration context.
+  bool isDeclInScope(Decl *D, DeclContext *Ctx, ASTContext &Context,
+                     Scope *S = 0) const;
+
+  /// AddDecl - Link the decl to its shadowed decl chain.
+  void AddDecl(NamedDecl *D);
+
+  /// RemoveDecl - Unlink the decl from its shadowed decl chain.
+  /// The decl must already be part of the decl chain.
+  void RemoveDecl(NamedDecl *D);
+
+  /// Replace the decl Old with the new declaration New on its
+  /// identifier chain. Returns true if the old declaration was found
+  /// (and, therefore, replaced).
+  bool ReplaceDecl(NamedDecl *Old, NamedDecl *New);
+
+  /// \brief Link the declaration into the chain of declarations for
+  /// the given identifier.
+  ///
+  /// This is a lower-level routine used by the PCH reader to link a
+  /// declaration into a specific IdentifierInfo before the
+  /// declaration actually has a name.
+  void AddDeclToIdentifierChain(IdentifierInfo *II, NamedDecl *D);
+
+  explicit IdentifierResolver(const LangOptions &LangOpt);
+  ~IdentifierResolver();
+
+private:
+  const LangOptions &LangOpt;
+
+  class IdDeclInfoMap;
+  IdDeclInfoMap *IdDeclInfos;
+
+  /// FETokenInfo contains a Decl pointer if lower bit == 0.
+  static inline bool isDeclPtr(void *Ptr) {
+    return (reinterpret_cast<uintptr_t>(Ptr) & 0x1) == 0;
+  }
+
+  /// FETokenInfo contains a IdDeclInfo pointer if lower bit == 1.
+  static inline IdDeclInfo *toIdDeclInfo(void *Ptr) {
+    assert((reinterpret_cast<uintptr_t>(Ptr) & 0x1) == 1
+          && "Ptr not a IdDeclInfo* !");
+    return reinterpret_cast<IdDeclInfo*>(
+                    reinterpret_cast<uintptr_t>(Ptr) & ~0x1
+                                                            );
+  }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/lib/Sema/JumpDiagnostics.cpp b/lib/Sema/JumpDiagnostics.cpp
new file mode 100644
index 0000000..0694294
--- /dev/null
+++ b/lib/Sema/JumpDiagnostics.cpp
@@ -0,0 +1,333 @@
+//===--- JumpDiagnostics.cpp - Analyze Jump Targets for VLA issues --------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the JumpScopeChecker class, which is used to diagnose
+// jumps that enter a VLA scope in an invalid way.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Sema.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/StmtObjC.h"
+#include "clang/AST/StmtCXX.h"
+using namespace clang;
+
+namespace {
+
+/// JumpScopeChecker - This object is used by Sema to diagnose invalid jumps
+/// into VLA and other protected scopes.  For example, this rejects:
+///    goto L;
+///    int a[n];
+///  L:
+///
+class JumpScopeChecker {
+  Sema &S;
+
+  /// GotoScope - This is a record that we use to keep track of all of the
+  /// scopes that are introduced by VLAs and other things that scope jumps like
+  /// gotos.  This scope tree has nothing to do with the source scope tree,
+  /// because you can have multiple VLA scopes per compound statement, and most
+  /// compound statements don't introduce any scopes.
+  struct GotoScope {
+    /// ParentScope - The index in ScopeMap of the parent scope.  This is 0 for
+    /// the parent scope is the function body.
+    unsigned ParentScope;
+
+    /// Diag - The diagnostic to emit if there is a jump into this scope.
+    unsigned Diag;
+
+    /// Loc - Location to emit the diagnostic.
+    SourceLocation Loc;
+
+    GotoScope(unsigned parentScope, unsigned diag, SourceLocation L)
+    : ParentScope(parentScope), Diag(diag), Loc(L) {}
+  };
+
+  llvm::SmallVector<GotoScope, 48> Scopes;
+  llvm::DenseMap<Stmt*, unsigned> LabelAndGotoScopes;
+  llvm::SmallVector<Stmt*, 16> Jumps;
+public:
+  JumpScopeChecker(Stmt *Body, Sema &S);
+private:
+  void BuildScopeInformation(Stmt *S, unsigned ParentScope);
+  void VerifyJumps();
+  void CheckJump(Stmt *From, Stmt *To,
+                 SourceLocation DiagLoc, unsigned JumpDiag);
+};
+} // end anonymous namespace
+
+
+JumpScopeChecker::JumpScopeChecker(Stmt *Body, Sema &s) : S(s) {
+  // Add a scope entry for function scope.
+  Scopes.push_back(GotoScope(~0U, ~0U, SourceLocation()));
+
+  // Build information for the top level compound statement, so that we have a
+  // defined scope record for every "goto" and label.
+  BuildScopeInformation(Body, 0);
+
+  // Check that all jumps we saw are kosher.
+  VerifyJumps();
+}
+
+/// GetDiagForGotoScopeDecl - If this decl induces a new goto scope, return a
+/// diagnostic that should be emitted if control goes over it. If not, return 0.
+static unsigned GetDiagForGotoScopeDecl(const Decl *D, bool isCPlusPlus) {
+  if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
+    if (VD->getType()->isVariablyModifiedType())
+      return diag::note_protected_by_vla;
+    if (VD->hasAttr<CleanupAttr>())
+      return diag::note_protected_by_cleanup;
+    if (VD->hasAttr<BlocksAttr>())
+      return diag::note_protected_by___block;
+    // FIXME: In C++0x, we have to check more conditions than "did we
+    // just give it an initializer?". See 6.7p3.
+    if (isCPlusPlus && VD->hasLocalStorage() && VD->hasInit())
+      return diag::note_protected_by_variable_init;
+    
+  } else if (const TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
+    if (TD->getUnderlyingType()->isVariablyModifiedType())
+      return diag::note_protected_by_vla_typedef;
+  }
+
+  return 0;
+}
+
+
+/// BuildScopeInformation - The statements from CI to CE are known to form a
+/// coherent VLA scope with a specified parent node.  Walk through the
+/// statements, adding any labels or gotos to LabelAndGotoScopes and recursively
+/// walking the AST as needed.
+void JumpScopeChecker::BuildScopeInformation(Stmt *S, unsigned ParentScope) {
+
+  // If we found a label, remember that it is in ParentScope scope.
+  if (isa<LabelStmt>(S) || isa<DefaultStmt>(S) || isa<CaseStmt>(S)) {
+    LabelAndGotoScopes[S] = ParentScope;
+  } else if (isa<GotoStmt>(S) || isa<SwitchStmt>(S) ||
+             isa<IndirectGotoStmt>(S) || isa<AddrLabelExpr>(S)) {
+    // Remember both what scope a goto is in as well as the fact that we have
+    // it.  This makes the second scan not have to walk the AST again.
+    LabelAndGotoScopes[S] = ParentScope;
+    Jumps.push_back(S);
+  }
+
+  for (Stmt::child_iterator CI = S->child_begin(), E = S->child_end(); CI != E;
+       ++CI) {
+    Stmt *SubStmt = *CI;
+    if (SubStmt == 0) continue;
+
+    bool isCPlusPlus = this->S.getLangOptions().CPlusPlus;
+
+    // If this is a declstmt with a VLA definition, it defines a scope from here
+    // to the end of the containing context.
+    if (DeclStmt *DS = dyn_cast<DeclStmt>(SubStmt)) {
+      // The decl statement creates a scope if any of the decls in it are VLAs
+      // or have the cleanup attribute.
+      for (DeclStmt::decl_iterator I = DS->decl_begin(), E = DS->decl_end();
+           I != E; ++I) {
+        // If this decl causes a new scope, push and switch to it.
+        if (unsigned Diag = GetDiagForGotoScopeDecl(*I, isCPlusPlus)) {
+          Scopes.push_back(GotoScope(ParentScope, Diag, (*I)->getLocation()));
+          ParentScope = Scopes.size()-1;
+        }
+
+        // If the decl has an initializer, walk it with the potentially new
+        // scope we just installed.
+        if (VarDecl *VD = dyn_cast<VarDecl>(*I))
+          if (Expr *Init = VD->getInit())
+            BuildScopeInformation(Init, ParentScope);
+      }
+      continue;
+    }
+
+    // Disallow jumps into any part of an @try statement by pushing a scope and
+    // walking all sub-stmts in that scope.
+    if (ObjCAtTryStmt *AT = dyn_cast<ObjCAtTryStmt>(SubStmt)) {
+      // Recursively walk the AST for the @try part.
+      Scopes.push_back(GotoScope(ParentScope,diag::note_protected_by_objc_try,
+                                 AT->getAtTryLoc()));
+      if (Stmt *TryPart = AT->getTryBody())
+        BuildScopeInformation(TryPart, Scopes.size()-1);
+
+      // Jump from the catch to the finally or try is not valid.
+      for (unsigned I = 0, N = AT->getNumCatchStmts(); I != N; ++I) {
+        ObjCAtCatchStmt *AC = AT->getCatchStmt(I);
+        Scopes.push_back(GotoScope(ParentScope,
+                                   diag::note_protected_by_objc_catch,
+                                   AC->getAtCatchLoc()));
+        // @catches are nested and it isn't
+        BuildScopeInformation(AC->getCatchBody(), Scopes.size()-1);
+      }
+
+      // Jump from the finally to the try or catch is not valid.
+      if (ObjCAtFinallyStmt *AF = AT->getFinallyStmt()) {
+        Scopes.push_back(GotoScope(ParentScope,
+                                   diag::note_protected_by_objc_finally,
+                                   AF->getAtFinallyLoc()));
+        BuildScopeInformation(AF, Scopes.size()-1);
+      }
+
+      continue;
+    }
+
+    // Disallow jumps into the protected statement of an @synchronized, but
+    // allow jumps into the object expression it protects.
+    if (ObjCAtSynchronizedStmt *AS = dyn_cast<ObjCAtSynchronizedStmt>(SubStmt)){
+      // Recursively walk the AST for the @synchronized object expr, it is
+      // evaluated in the normal scope.
+      BuildScopeInformation(AS->getSynchExpr(), ParentScope);
+
+      // Recursively walk the AST for the @synchronized part, protected by a new
+      // scope.
+      Scopes.push_back(GotoScope(ParentScope,
+                                 diag::note_protected_by_objc_synchronized,
+                                 AS->getAtSynchronizedLoc()));
+      BuildScopeInformation(AS->getSynchBody(), Scopes.size()-1);
+      continue;
+    }
+
+    // Disallow jumps into any part of a C++ try statement. This is pretty
+    // much the same as for Obj-C.
+    if (CXXTryStmt *TS = dyn_cast<CXXTryStmt>(SubStmt)) {
+      Scopes.push_back(GotoScope(ParentScope, diag::note_protected_by_cxx_try,
+                                 TS->getSourceRange().getBegin()));
+      if (Stmt *TryBlock = TS->getTryBlock())
+        BuildScopeInformation(TryBlock, Scopes.size()-1);
+
+      // Jump from the catch into the try is not allowed either.
+      for (unsigned I = 0, E = TS->getNumHandlers(); I != E; ++I) {
+        CXXCatchStmt *CS = TS->getHandler(I);
+        Scopes.push_back(GotoScope(ParentScope,
+                                   diag::note_protected_by_cxx_catch,
+                                   CS->getSourceRange().getBegin()));
+        BuildScopeInformation(CS->getHandlerBlock(), Scopes.size()-1);
+      }
+
+      continue;
+    }
+
+    // Recursively walk the AST.
+    BuildScopeInformation(SubStmt, ParentScope);
+  }
+}
+
+/// VerifyJumps - Verify each element of the Jumps array to see if they are
+/// valid, emitting diagnostics if not.
+void JumpScopeChecker::VerifyJumps() {
+  while (!Jumps.empty()) {
+    Stmt *Jump = Jumps.pop_back_val();
+
+    // With a goto,
+    if (GotoStmt *GS = dyn_cast<GotoStmt>(Jump)) {
+      CheckJump(GS, GS->getLabel(), GS->getGotoLoc(),
+                diag::err_goto_into_protected_scope);
+      continue;
+    }
+
+    if (SwitchStmt *SS = dyn_cast<SwitchStmt>(Jump)) {
+      for (SwitchCase *SC = SS->getSwitchCaseList(); SC;
+           SC = SC->getNextSwitchCase()) {
+        assert(LabelAndGotoScopes.count(SC) && "Case not visited?");
+        CheckJump(SS, SC, SC->getLocStart(),
+                  diag::err_switch_into_protected_scope);
+      }
+      continue;
+    }
+
+    unsigned DiagnosticScope;
+
+    // We don't know where an indirect goto goes, require that it be at the
+    // top level of scoping.
+    if (IndirectGotoStmt *IG = dyn_cast<IndirectGotoStmt>(Jump)) {
+      assert(LabelAndGotoScopes.count(Jump) &&
+             "Jump didn't get added to scopes?");
+      unsigned GotoScope = LabelAndGotoScopes[IG];
+      if (GotoScope == 0) continue;  // indirect jump is ok.
+      S.Diag(IG->getGotoLoc(), diag::err_indirect_goto_in_protected_scope);
+      DiagnosticScope = GotoScope;
+    } else {
+      // We model &&Label as a jump for purposes of scope tracking.  We actually
+      // don't care *where* the address of label is, but we require the *label
+      // itself* to be in scope 0.  If it is nested inside of a VLA scope, then
+      // it is possible for an indirect goto to illegally enter the VLA scope by
+      // indirectly jumping to the label.
+      assert(isa<AddrLabelExpr>(Jump) && "Unknown jump type");
+      LabelStmt *TheLabel = cast<AddrLabelExpr>(Jump)->getLabel();
+
+      assert(LabelAndGotoScopes.count(TheLabel) &&
+             "Referenced label didn't get added to scopes?");
+      unsigned LabelScope = LabelAndGotoScopes[TheLabel];
+      if (LabelScope == 0) continue; // Addr of label is ok.
+
+      S.Diag(Jump->getLocStart(), diag::err_addr_of_label_in_protected_scope);
+      DiagnosticScope = LabelScope;
+    }
+
+    // Report all the things that would be skipped over by this &&label or
+    // indirect goto.
+    while (DiagnosticScope != 0) {
+      S.Diag(Scopes[DiagnosticScope].Loc, Scopes[DiagnosticScope].Diag);
+      DiagnosticScope = Scopes[DiagnosticScope].ParentScope;
+    }
+  }
+}
+
+/// CheckJump - Validate that the specified jump statement is valid: that it is
+/// jumping within or out of its current scope, not into a deeper one.
+void JumpScopeChecker::CheckJump(Stmt *From, Stmt *To,
+                                 SourceLocation DiagLoc, unsigned JumpDiag) {
+  assert(LabelAndGotoScopes.count(From) && "Jump didn't get added to scopes?");
+  unsigned FromScope = LabelAndGotoScopes[From];
+
+  assert(LabelAndGotoScopes.count(To) && "Jump didn't get added to scopes?");
+  unsigned ToScope = LabelAndGotoScopes[To];
+
+  // Common case: exactly the same scope, which is fine.
+  if (FromScope == ToScope) return;
+
+  // The only valid mismatch jump case happens when the jump is more deeply
+  // nested inside the jump target.  Do a quick scan to see if the jump is valid
+  // because valid code is more common than invalid code.
+  unsigned TestScope = Scopes[FromScope].ParentScope;
+  while (TestScope != ~0U) {
+    // If we found the jump target, then we're jumping out of our current scope,
+    // which is perfectly fine.
+    if (TestScope == ToScope) return;
+
+    // Otherwise, scan up the hierarchy.
+    TestScope = Scopes[TestScope].ParentScope;
+  }
+
+  // If we get here, then we know we have invalid code.  Diagnose the bad jump,
+  // and then emit a note at each VLA being jumped out of.
+  S.Diag(DiagLoc, JumpDiag);
+
+  // Eliminate the common prefix of the jump and the target.  Start by
+  // linearizing both scopes, reversing them as we go.
+  std::vector<unsigned> FromScopes, ToScopes;
+  for (TestScope = FromScope; TestScope != ~0U;
+       TestScope = Scopes[TestScope].ParentScope)
+    FromScopes.push_back(TestScope);
+  for (TestScope = ToScope; TestScope != ~0U;
+       TestScope = Scopes[TestScope].ParentScope)
+    ToScopes.push_back(TestScope);
+
+  // Remove any common entries (such as the top-level function scope).
+  while (!FromScopes.empty() && FromScopes.back() == ToScopes.back()) {
+    FromScopes.pop_back();
+    ToScopes.pop_back();
+  }
+
+  // Emit diagnostics for whatever is left in ToScopes.
+  for (unsigned i = 0, e = ToScopes.size(); i != e; ++i)
+    S.Diag(Scopes[ToScopes[i]].Loc, Scopes[ToScopes[i]].Diag);
+}
+
+void Sema::DiagnoseInvalidJumps(Stmt *Body) {
+  (void)JumpScopeChecker(Body, *this);
+}
diff --git a/lib/Sema/Lookup.h b/lib/Sema/Lookup.h
new file mode 100644
index 0000000..0961299
--- /dev/null
+++ b/lib/Sema/Lookup.h
@@ -0,0 +1,649 @@
+//===--- Lookup.h - Classes for name lookup ---------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the LookupResult class, which is integral to
+// Sema's name-lookup subsystem.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SEMA_LOOKUP_H
+#define LLVM_CLANG_SEMA_LOOKUP_H
+
+#include "Sema.h"
+
+namespace clang {
+
+/// @brief Represents the results of name lookup.
+///
+/// An instance of the LookupResult class captures the results of a
+/// single name lookup, which can return no result (nothing found),
+/// a single declaration, a set of overloaded functions, or an
+/// ambiguity. Use the getKind() method to determine which of these
+/// results occurred for a given lookup.
+class LookupResult {
+public:
+  enum LookupResultKind {
+    /// @brief No entity found met the criteria.
+    NotFound = 0,
+
+    /// @brief No entity found met the criteria within the current 
+    /// instantiation,, but there were dependent base classes of the 
+    /// current instantiation that could not be searched.
+    NotFoundInCurrentInstantiation,
+    
+    /// @brief Name lookup found a single declaration that met the
+    /// criteria.  getFoundDecl() will return this declaration.
+    Found,
+
+    /// @brief Name lookup found a set of overloaded functions that
+    /// met the criteria.
+    FoundOverloaded,
+
+    /// @brief Name lookup found an unresolvable value declaration
+    /// and cannot yet complete.  This only happens in C++ dependent
+    /// contexts with dependent using declarations.
+    FoundUnresolvedValue,
+
+    /// @brief Name lookup results in an ambiguity; use
+    /// getAmbiguityKind to figure out what kind of ambiguity
+    /// we have.
+    Ambiguous
+  };
+
+  enum AmbiguityKind {
+    /// Name lookup results in an ambiguity because multiple
+    /// entities that meet the lookup criteria were found in
+    /// subobjects of different types. For example:
+    /// @code
+    /// struct A { void f(int); }
+    /// struct B { void f(double); }
+    /// struct C : A, B { };
+    /// void test(C c) {
+    ///   c.f(0); // error: A::f and B::f come from subobjects of different
+    ///           // types. overload resolution is not performed.
+    /// }
+    /// @endcode
+    AmbiguousBaseSubobjectTypes,
+
+    /// Name lookup results in an ambiguity because multiple
+    /// nonstatic entities that meet the lookup criteria were found
+    /// in different subobjects of the same type. For example:
+    /// @code
+    /// struct A { int x; };
+    /// struct B : A { };
+    /// struct C : A { };
+    /// struct D : B, C { };
+    /// int test(D d) {
+    ///   return d.x; // error: 'x' is found in two A subobjects (of B and C)
+    /// }
+    /// @endcode
+    AmbiguousBaseSubobjects,
+
+    /// Name lookup results in an ambiguity because multiple definitions
+    /// of entity that meet the lookup criteria were found in different
+    /// declaration contexts.
+    /// @code
+    /// namespace A {
+    ///   int i;
+    ///   namespace B { int i; }
+    ///   int test() {
+    ///     using namespace B;
+    ///     return i; // error 'i' is found in namespace A and A::B
+    ///    }
+    /// }
+    /// @endcode
+    AmbiguousReference,
+
+    /// Name lookup results in an ambiguity because an entity with a
+    /// tag name was hidden by an entity with an ordinary name from
+    /// a different context.
+    /// @code
+    /// namespace A { struct Foo {}; }
+    /// namespace B { void Foo(); }
+    /// namespace C {
+    ///   using namespace A;
+    ///   using namespace B;
+    /// }
+    /// void test() {
+    ///   C::Foo(); // error: tag 'A::Foo' is hidden by an object in a
+    ///             // different namespace
+    /// }
+    /// @endcode
+    AmbiguousTagHiding
+  };
+
+  /// A little identifier for flagging temporary lookup results.
+  enum TemporaryToken {
+    Temporary
+  };
+
+  typedef UnresolvedSetImpl::iterator iterator;
+
+  LookupResult(Sema &SemaRef, DeclarationName Name, SourceLocation NameLoc,
+               Sema::LookupNameKind LookupKind,
+               Sema::RedeclarationKind Redecl = Sema::NotForRedeclaration)
+    : ResultKind(NotFound),
+      Paths(0),
+      NamingClass(0),
+      SemaRef(SemaRef),
+      Name(Name),
+      NameLoc(NameLoc),
+      LookupKind(LookupKind),
+      IDNS(0),
+      Redecl(Redecl != Sema::NotForRedeclaration),
+      HideTags(true),
+      Diagnose(Redecl == Sema::NotForRedeclaration)
+  {
+    configure();
+  }
+
+  /// Creates a temporary lookup result, initializing its core data
+  /// using the information from another result.  Diagnostics are always
+  /// disabled.
+  LookupResult(TemporaryToken _, const LookupResult &Other)
+    : ResultKind(NotFound),
+      Paths(0),
+      NamingClass(0),
+      SemaRef(Other.SemaRef),
+      Name(Other.Name),
+      NameLoc(Other.NameLoc),
+      LookupKind(Other.LookupKind),
+      IDNS(Other.IDNS),
+      Redecl(Other.Redecl),
+      HideTags(Other.HideTags),
+      Diagnose(false)
+  {}
+
+  ~LookupResult() {
+    if (Diagnose) diagnose();
+    if (Paths) deletePaths(Paths);
+  }
+
+  /// Gets the name to look up.
+  DeclarationName getLookupName() const {
+    return Name;
+  }
+
+  /// \brief Sets the name to look up.
+  void setLookupName(DeclarationName Name) {
+    this->Name = Name;
+  }
+
+  /// Gets the kind of lookup to perform.
+  Sema::LookupNameKind getLookupKind() const {
+    return LookupKind;
+  }
+
+  /// True if this lookup is just looking for an existing declaration.
+  bool isForRedeclaration() const {
+    return Redecl;
+  }
+
+  /// Sets whether tag declarations should be hidden by non-tag
+  /// declarations during resolution.  The default is true.
+  void setHideTags(bool Hide) {
+    HideTags = Hide;
+  }
+
+  bool isAmbiguous() const {
+    return getResultKind() == Ambiguous;
+  }
+
+  /// Determines if this names a single result which is not an
+  /// unresolved value using decl.  If so, it is safe to call
+  /// getFoundDecl().
+  bool isSingleResult() const {
+    return getResultKind() == Found;
+  }
+
+  /// Determines if the results are overloaded.
+  bool isOverloadedResult() const {
+    return getResultKind() == FoundOverloaded;
+  }
+
+  bool isUnresolvableResult() const {
+    return getResultKind() == FoundUnresolvedValue;
+  }
+
+  LookupResultKind getResultKind() const {
+    sanity();
+    return ResultKind;
+  }
+
+  AmbiguityKind getAmbiguityKind() const {
+    assert(isAmbiguous());
+    return Ambiguity;
+  }
+
+  const UnresolvedSetImpl &asUnresolvedSet() const {
+    return Decls;
+  }
+
+  iterator begin() const { return iterator(Decls.begin()); }
+  iterator end() const { return iterator(Decls.end()); }
+
+  /// \brief Return true if no decls were found
+  bool empty() const { return Decls.empty(); }
+
+  /// \brief Return the base paths structure that's associated with
+  /// these results, or null if none is.
+  CXXBasePaths *getBasePaths() const {
+    return Paths;
+  }
+
+  /// \brief Tests whether the given declaration is acceptable.
+  bool isAcceptableDecl(NamedDecl *D) const {
+    return D->isInIdentifierNamespace(IDNS);
+  }
+
+  /// \brief Returns the identifier namespace mask for this lookup.
+  unsigned getIdentifierNamespace() const {
+    return IDNS;
+  }
+
+  /// \brief Returns whether these results arose from performing a
+  /// lookup into a class.
+  bool isClassLookup() const {
+    return NamingClass != 0;
+  }
+
+  /// \brief Returns the 'naming class' for this lookup, i.e. the
+  /// class which was looked into to find these results.
+  ///
+  /// C++0x [class.access.base]p5:
+  ///   The access to a member is affected by the class in which the
+  ///   member is named. This naming class is the class in which the
+  ///   member name was looked up and found. [Note: this class can be
+  ///   explicit, e.g., when a qualified-id is used, or implicit,
+  ///   e.g., when a class member access operator (5.2.5) is used
+  ///   (including cases where an implicit "this->" is added). If both
+  ///   a class member access operator and a qualified-id are used to
+  ///   name the member (as in p->T::m), the class naming the member
+  ///   is the class named by the nested-name-specifier of the
+  ///   qualified-id (that is, T). -- end note ]
+  ///
+  /// This is set by the lookup routines when they find results in a class.
+  CXXRecordDecl *getNamingClass() const {
+    return NamingClass;
+  }
+
+  /// \brief Sets the 'naming class' for this lookup.
+  void setNamingClass(CXXRecordDecl *Record) {
+    NamingClass = Record;
+  }
+
+  /// \brief Returns the base object type associated with this lookup;
+  /// important for [class.protected].  Most lookups do not have an
+  /// associated base object.
+  QualType getBaseObjectType() const {
+    return BaseObjectType;
+  }
+
+  /// \brief Sets the base object type for this lookup.
+  void setBaseObjectType(QualType T) {
+    BaseObjectType = T;
+  }
+
+  /// \brief Add a declaration to these results with its natural access.
+  /// Does not test the acceptance criteria.
+  void addDecl(NamedDecl *D) {
+    addDecl(D, D->getAccess());
+  }
+
+  /// \brief Add a declaration to these results with the given access.
+  /// Does not test the acceptance criteria.
+  void addDecl(NamedDecl *D, AccessSpecifier AS) {
+    Decls.addDecl(D, AS);
+    ResultKind = Found;
+  }
+
+  /// \brief Add all the declarations from another set of lookup
+  /// results.
+  void addAllDecls(const LookupResult &Other) {
+    Decls.append(Other.Decls.begin(), Other.Decls.end());
+    ResultKind = Found;
+  }
+
+  /// \brief Determine whether no result was found because we could not
+  /// search into dependent base classes of the current instantiation.
+  bool wasNotFoundInCurrentInstantiation() const {
+    return ResultKind == NotFoundInCurrentInstantiation;
+  }
+  
+  /// \brief Note that while no result was found in the current instantiation,
+  /// there were dependent base classes that could not be searched.
+  void setNotFoundInCurrentInstantiation() {
+    assert(ResultKind == NotFound && Decls.empty());
+    ResultKind = NotFoundInCurrentInstantiation;
+  }
+  
+  /// \brief Resolves the result kind of the lookup, possibly hiding
+  /// decls.
+  ///
+  /// This should be called in any environment where lookup might
+  /// generate multiple lookup results.
+  void resolveKind();
+
+  /// \brief Re-resolves the result kind of the lookup after a set of
+  /// removals has been performed.
+  void resolveKindAfterFilter() {
+    if (Decls.empty()) {
+      if (ResultKind != NotFoundInCurrentInstantiation)
+        ResultKind = NotFound;
+    } else {
+      ResultKind = Found;
+      resolveKind();
+      
+      if (Paths && (ResultKind != Ambiguous)) {
+        deletePaths(Paths);
+        Paths = 0;
+      }
+    }
+  }
+
+  template <class DeclClass>
+  DeclClass *getAsSingle() const {
+    if (getResultKind() != Found) return 0;
+    return dyn_cast<DeclClass>(getFoundDecl());
+  }
+
+  /// \brief Fetch the unique decl found by this lookup.  Asserts
+  /// that one was found.
+  ///
+  /// This is intended for users who have examined the result kind
+  /// and are certain that there is only one result.
+  NamedDecl *getFoundDecl() const {
+    assert(getResultKind() == Found
+           && "getFoundDecl called on non-unique result");
+    return (*begin())->getUnderlyingDecl();
+  }
+
+  /// Fetches a representative decl.  Useful for lazy diagnostics.
+  NamedDecl *getRepresentativeDecl() const {
+    assert(!Decls.empty() && "cannot get representative of empty set");
+    return *begin();
+  }
+
+  /// \brief Asks if the result is a single tag decl.
+  bool isSingleTagDecl() const {
+    return getResultKind() == Found && isa<TagDecl>(getFoundDecl());
+  }
+
+  /// \brief Make these results show that the name was found in
+  /// base classes of different types.
+  ///
+  /// The given paths object is copied and invalidated.
+  void setAmbiguousBaseSubobjectTypes(CXXBasePaths &P);
+
+  /// \brief Make these results show that the name was found in
+  /// distinct base classes of the same type.
+  ///
+  /// The given paths object is copied and invalidated.
+  void setAmbiguousBaseSubobjects(CXXBasePaths &P);
+
+  /// \brief Make these results show that the name was found in
+  /// different contexts and a tag decl was hidden by an ordinary
+  /// decl in a different context.
+  void setAmbiguousQualifiedTagHiding() {
+    setAmbiguous(AmbiguousTagHiding);
+  }
+
+  /// \brief Clears out any current state.
+  void clear() {
+    ResultKind = NotFound;
+    Decls.clear();
+    if (Paths) deletePaths(Paths);
+    Paths = NULL;
+  }
+
+  /// \brief Clears out any current state and re-initializes for a
+  /// different kind of lookup.
+  void clear(Sema::LookupNameKind Kind) {
+    clear();
+    LookupKind = Kind;
+    configure();
+  }
+
+  /// \brief Change this lookup's redeclaration kind.
+  void setRedeclarationKind(Sema::RedeclarationKind RK) {
+    Redecl = RK;
+    configure();
+  }
+
+  void print(llvm::raw_ostream &);
+
+  /// Suppress the diagnostics that would normally fire because of this
+  /// lookup.  This happens during (e.g.) redeclaration lookups.
+  void suppressDiagnostics() {
+    Diagnose = false;
+  }
+
+  /// Sets a 'context' source range.
+  void setContextRange(SourceRange SR) {
+    NameContextRange = SR;
+  }
+
+  /// Gets the source range of the context of this name; for C++
+  /// qualified lookups, this is the source range of the scope
+  /// specifier.
+  SourceRange getContextRange() const {
+    return NameContextRange;
+  }
+
+  /// Gets the location of the identifier.  This isn't always defined:
+  /// sometimes we're doing lookups on synthesized names.
+  SourceLocation getNameLoc() const {
+    return NameLoc;
+  }
+
+  /// \brief Get the Sema object that this lookup result is searching
+  /// with.
+  Sema &getSema() const { return SemaRef; }
+
+  /// A class for iterating through a result set and possibly
+  /// filtering out results.  The results returned are possibly
+  /// sugared.
+  class Filter {
+    LookupResult &Results;
+    LookupResult::iterator I;
+    bool Changed;
+#ifndef NDEBUG
+    bool CalledDone;
+#endif
+    
+    friend class LookupResult;
+    Filter(LookupResult &Results)
+      : Results(Results), I(Results.begin()), Changed(false)
+#ifndef NDEBUG
+      , CalledDone(false)
+#endif
+    {}
+
+  public:
+#ifndef NDEBUG
+    ~Filter() {
+      assert(CalledDone &&
+             "LookupResult::Filter destroyed without done() call");
+    }
+#endif
+
+    bool hasNext() const {
+      return I != Results.end();
+    }
+
+    NamedDecl *next() {
+      assert(I != Results.end() && "next() called on empty filter");
+      return *I++;
+    }
+
+    /// Erase the last element returned from this iterator.
+    void erase() {
+      Results.Decls.erase(--I);
+      Changed = true;
+    }
+
+    /// Replaces the current entry with the given one, preserving the
+    /// access bits.
+    void replace(NamedDecl *D) {
+      Results.Decls.replace(I-1, D);
+      Changed = true;
+    }
+
+    /// Replaces the current entry with the given one.
+    void replace(NamedDecl *D, AccessSpecifier AS) {
+      Results.Decls.replace(I-1, D, AS);
+      Changed = true;
+    }
+
+    void done() {
+#ifndef NDEBUG
+      assert(!CalledDone && "done() called twice");
+      CalledDone = true;
+#endif
+
+      if (Changed)
+        Results.resolveKindAfterFilter();
+    }
+  };
+
+  /// Create a filter for this result set.
+  Filter makeFilter() {
+    return Filter(*this);
+  }
+
+private:
+  void diagnose() {
+    if (isAmbiguous())
+      SemaRef.DiagnoseAmbiguousLookup(*this);
+    else if (isClassLookup() && SemaRef.getLangOptions().AccessControl)
+      SemaRef.CheckLookupAccess(*this);
+  }
+
+  void setAmbiguous(AmbiguityKind AK) {
+    ResultKind = Ambiguous;
+    Ambiguity = AK;
+  }
+
+  void addDeclsFromBasePaths(const CXXBasePaths &P);
+  void configure();
+
+  // Sanity checks.
+  void sanity() const {
+    assert(ResultKind != NotFound || Decls.size() == 0);
+    assert(ResultKind != Found || Decls.size() == 1);
+    assert(ResultKind != FoundOverloaded || Decls.size() > 1 ||
+           (Decls.size() == 1 &&
+            isa<FunctionTemplateDecl>((*begin())->getUnderlyingDecl())));
+    assert(ResultKind != FoundUnresolvedValue || sanityCheckUnresolved());
+    assert(ResultKind != Ambiguous || Decls.size() > 1 ||
+           (Decls.size() == 1 && Ambiguity == AmbiguousBaseSubobjects));
+    assert((Paths != NULL) == (ResultKind == Ambiguous &&
+                               (Ambiguity == AmbiguousBaseSubobjectTypes ||
+                                Ambiguity == AmbiguousBaseSubobjects)));
+  }
+
+  bool sanityCheckUnresolved() const {
+    for (iterator I = begin(), E = end(); I != E; ++I)
+      if (isa<UnresolvedUsingValueDecl>(*I))
+        return true;
+    return false;
+  }
+
+  static void deletePaths(CXXBasePaths *);
+
+  // Results.
+  LookupResultKind ResultKind;
+  AmbiguityKind Ambiguity; // ill-defined unless ambiguous
+  UnresolvedSet<8> Decls;
+  CXXBasePaths *Paths;
+  CXXRecordDecl *NamingClass;
+  QualType BaseObjectType;
+
+  // Parameters.
+  Sema &SemaRef;
+  DeclarationName Name;
+  SourceLocation NameLoc;
+  SourceRange NameContextRange;
+  Sema::LookupNameKind LookupKind;
+  unsigned IDNS; // set by configure()
+
+  bool Redecl;
+
+  /// \brief True if tag declarations should be hidden if non-tags
+  ///   are present
+  bool HideTags;
+
+  bool Diagnose;
+};
+
+  /// \brief Consumes visible declarations found when searching for
+  /// all visible names within a given scope or context.
+  ///
+  /// This abstract class is meant to be subclassed by clients of \c
+  /// Sema::LookupVisibleDecls(), each of which should override the \c
+  /// FoundDecl() function to process declarations as they are found.
+  class VisibleDeclConsumer {
+  public:
+    /// \brief Destroys the visible declaration consumer.
+    virtual ~VisibleDeclConsumer();
+
+    /// \brief Invoked each time \p Sema::LookupVisibleDecls() finds a
+    /// declaration visible from the current scope or context.
+    ///
+    /// \param ND the declaration found.
+    ///
+    /// \param Hiding a declaration that hides the declaration \p ND,
+    /// or NULL if no such declaration exists.
+    ///
+    /// \param InBaseClass whether this declaration was found in base
+    /// class of the context we searched.
+    virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, 
+                           bool InBaseClass) = 0;
+  };
+
+/// \brief A class for storing results from argument-dependent lookup.
+class ADLResult {
+private:
+  /// A map from canonical decls to the 'most recent' decl.
+  llvm::DenseMap<NamedDecl*, NamedDecl*> Decls;
+
+public:
+  /// Adds a new ADL candidate to this map.
+  void insert(NamedDecl *D);
+
+  /// Removes any data associated with a given decl.
+  void erase(NamedDecl *D) {
+    Decls.erase(cast<NamedDecl>(D->getCanonicalDecl()));
+  }
+
+  class iterator {
+    typedef llvm::DenseMap<NamedDecl*,NamedDecl*>::iterator inner_iterator;
+    inner_iterator iter;
+
+    friend class ADLResult;
+    iterator(const inner_iterator &iter) : iter(iter) {}
+  public:
+    iterator() {}
+
+    iterator &operator++() { ++iter; return *this; }
+    iterator operator++(int) { return iterator(iter++); }
+
+    NamedDecl *operator*() const { return iter->second; }
+
+    bool operator==(const iterator &other) const { return iter == other.iter; }
+    bool operator!=(const iterator &other) const { return iter != other.iter; }
+  };
+
+  iterator begin() { return iterator(Decls.begin()); }
+  iterator end() { return iterator(Decls.end()); }
+};
+
+}
+
+#endif
diff --git a/lib/Sema/Makefile b/lib/Sema/Makefile
new file mode 100644
index 0000000..3a5a99a
--- /dev/null
+++ b/lib/Sema/Makefile
@@ -0,0 +1,22 @@
+##===- clang/lib/Sema/Makefile -----------------------------*- Makefile -*-===##
+# 
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+# 
+##===----------------------------------------------------------------------===##
+#
+#  This implements the semantic analyzer and AST builder library for the 
+#  C-Language front-end.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../../../..
+LIBRARYNAME := clangSema
+BUILD_ARCHIVE = 1
+
+CPP.Flags += -I$(PROJ_SRC_DIR)/../../include -I$(PROJ_OBJ_DIR)/../../include
+
+include $(LEVEL)/Makefile.common
+
diff --git a/lib/Sema/ParseAST.cpp b/lib/Sema/ParseAST.cpp
new file mode 100644
index 0000000..bb0bd9e
--- /dev/null
+++ b/lib/Sema/ParseAST.cpp
@@ -0,0 +1,125 @@
+//===--- ParseAST.cpp - Provide the clang::ParseAST method ----------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the clang::ParseAST method.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Sema/ParseAST.h"
+#include "Sema.h"
+#include "clang/Sema/CodeCompleteConsumer.h"
+#include "clang/Sema/SemaConsumer.h"
+#include "clang/Sema/ExternalSemaSource.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/ExternalASTSource.h"
+#include "clang/AST/Stmt.h"
+#include "clang/Parse/Parser.h"
+#include <cstdio>
+
+using namespace clang;
+
+static void DumpRecordLayouts(ASTContext &C) {
+  for (ASTContext::type_iterator I = C.types_begin(), E = C.types_end();
+       I != E; ++I) {
+    const RecordType *RT = dyn_cast<RecordType>(*I);
+    if (!RT)
+      continue;
+
+    const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());
+    if (!RD || RD->isImplicit() || RD->isDependentType() ||
+        RD->isInvalidDecl() || !RD->getDefinition())
+      continue;
+
+    // FIXME: Do we really need to hard code this?
+    if (RD->getQualifiedNameAsString() == "__va_list_tag")
+      continue;
+
+    C.DumpRecordLayout(RD, llvm::errs());
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// Public interface to the file
+//===----------------------------------------------------------------------===//
+
+/// ParseAST - Parse the entire file specified, notifying the ASTConsumer as
+/// the file is parsed.  This inserts the parsed decls into the translation unit
+/// held by Ctx.
+///
+void clang::ParseAST(Preprocessor &PP, ASTConsumer *Consumer,
+                     ASTContext &Ctx, bool PrintStats,
+                     bool CompleteTranslationUnit,
+                     CodeCompleteConsumer *CompletionConsumer) {
+  // Collect global stats on Decls/Stmts (until we have a module streamer).
+  if (PrintStats) {
+    Decl::CollectingStats(true);
+    Stmt::CollectingStats(true);
+  }
+
+  Sema S(PP, Ctx, *Consumer, CompleteTranslationUnit, CompletionConsumer);
+  Parser P(PP, S);
+  PP.EnterMainSourceFile();
+
+  // Initialize the parser.
+  P.Initialize();
+
+  Consumer->Initialize(Ctx);
+
+  if (SemaConsumer *SC = dyn_cast<SemaConsumer>(Consumer))
+    SC->InitializeSema(S);
+
+  if (ExternalASTSource *External = Ctx.getExternalSource()) {
+    if (ExternalSemaSource *ExternalSema =
+          dyn_cast<ExternalSemaSource>(External))
+      ExternalSema->InitializeSema(S);
+
+    External->StartTranslationUnit(Consumer);
+  }
+
+  Parser::DeclGroupPtrTy ADecl;
+
+  while (!P.ParseTopLevelDecl(ADecl)) {  // Not end of file.
+    // If we got a null return and something *was* parsed, ignore it.  This
+    // is due to a top-level semicolon, an action override, or a parse error
+    // skipping something.
+    if (ADecl)
+      Consumer->HandleTopLevelDecl(ADecl.getAsVal<DeclGroupRef>());
+  };
+  // Check for any pending objective-c implementation decl.
+  while ((ADecl = P.RetrievePendingObjCImpDecl()))
+    Consumer->HandleTopLevelDecl(ADecl.getAsVal<DeclGroupRef>());
+
+  // Process any TopLevelDecls generated by #pragma weak.
+  for (llvm::SmallVector<Decl*,2>::iterator
+        I = S.WeakTopLevelDecls().begin(),
+        E = S.WeakTopLevelDecls().end(); I != E; ++I)
+    Consumer->HandleTopLevelDecl(DeclGroupRef(*I));
+
+  // Dump record layouts, if requested.
+  if (PP.getLangOptions().DumpRecordLayouts)
+    DumpRecordLayouts(Ctx);
+
+  Consumer->HandleTranslationUnit(Ctx);
+
+  if (ExternalSemaSource *ESS =
+        dyn_cast_or_null<ExternalSemaSource>(Ctx.getExternalSource()))
+    ESS->ForgetSema();
+
+  if (SemaConsumer *SC = dyn_cast<SemaConsumer>(Consumer))
+    SC->ForgetSema();
+
+  if (PrintStats) {
+    fprintf(stderr, "\nSTATISTICS:\n");
+    P.getActions().PrintStats();
+    Ctx.PrintStats();
+    Decl::PrintStats();
+    Stmt::PrintStats();
+    Consumer->PrintStats();
+  }
+}
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp
new file mode 100644
index 0000000..755af84
--- /dev/null
+++ b/lib/Sema/Sema.cpp
@@ -0,0 +1,426 @@
+//===--- Sema.cpp - AST Builder and Semantic Analysis Implementation ------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the actions class which performs semantic analysis and
+// builds an AST out of a parse stream.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Sema.h"
+#include "TargetAttributesSema.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/APFloat.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTDiagnostic.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/Expr.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Basic/PartialDiagnostic.h"
+#include "clang/Basic/TargetInfo.h"
+using namespace clang;
+
+FunctionScopeInfo::~FunctionScopeInfo() { }
+
+void FunctionScopeInfo::Clear(unsigned NumErrors) {
+  NeedsScopeChecking = false;
+  LabelMap.clear();
+  SwitchStack.clear();
+  NumErrorsAtStartOfFunction = NumErrors;
+}
+
+BlockScopeInfo::~BlockScopeInfo() { }
+
+static inline RecordDecl *CreateStructDecl(ASTContext &C, const char *Name) {
+  if (C.getLangOptions().CPlusPlus)
+    return CXXRecordDecl::Create(C, TagDecl::TK_struct,
+                                 C.getTranslationUnitDecl(),
+                                 SourceLocation(), &C.Idents.get(Name));
+
+  return RecordDecl::Create(C, TagDecl::TK_struct,
+                            C.getTranslationUnitDecl(),
+                            SourceLocation(), &C.Idents.get(Name));
+}
+
+void Sema::ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) {
+  TUScope = S;
+  PushDeclContext(S, Context.getTranslationUnitDecl());
+
+  if (PP.getTargetInfo().getPointerWidth(0) >= 64) {
+    TypeSourceInfo *TInfo;
+
+    // Install [u]int128_t for 64-bit targets.
+    TInfo = Context.getTrivialTypeSourceInfo(Context.Int128Ty);
+    PushOnScopeChains(TypedefDecl::Create(Context, CurContext,
+                                          SourceLocation(),
+                                          &Context.Idents.get("__int128_t"),
+                                          TInfo), TUScope);
+
+    TInfo = Context.getTrivialTypeSourceInfo(Context.UnsignedInt128Ty);
+    PushOnScopeChains(TypedefDecl::Create(Context, CurContext,
+                                          SourceLocation(),
+                                          &Context.Idents.get("__uint128_t"),
+                                          TInfo), TUScope);
+  }
+
+
+  if (!PP.getLangOptions().ObjC1) return;
+
+  // Built-in ObjC types may already be set by PCHReader (hence isNull checks).
+  if (Context.getObjCSelType().isNull()) {
+    // Create the built-in typedef for 'SEL'.
+    QualType SelT = Context.getPointerType(Context.ObjCBuiltinSelTy);
+    TypeSourceInfo *SelInfo = Context.getTrivialTypeSourceInfo(SelT);
+    TypedefDecl *SelTypedef
+      = TypedefDecl::Create(Context, CurContext, SourceLocation(),
+                            &Context.Idents.get("SEL"), SelInfo);
+    PushOnScopeChains(SelTypedef, TUScope);
+    Context.setObjCSelType(Context.getTypeDeclType(SelTypedef));
+    Context.ObjCSelRedefinitionType = Context.getObjCSelType();
+  }
+
+  // Synthesize "@class Protocol;
+  if (Context.getObjCProtoType().isNull()) {
+    ObjCInterfaceDecl *ProtocolDecl =
+      ObjCInterfaceDecl::Create(Context, CurContext, SourceLocation(),
+                                &Context.Idents.get("Protocol"),
+                                SourceLocation(), true);
+    Context.setObjCProtoType(Context.getObjCInterfaceType(ProtocolDecl));
+    PushOnScopeChains(ProtocolDecl, TUScope, false);
+  }
+  // Create the built-in typedef for 'id'.
+  if (Context.getObjCIdType().isNull()) {
+    QualType IdT = Context.getObjCObjectPointerType(Context.ObjCBuiltinIdTy);
+    TypeSourceInfo *IdInfo = Context.getTrivialTypeSourceInfo(IdT);
+    TypedefDecl *IdTypedef
+      = TypedefDecl::Create(Context, CurContext, SourceLocation(),
+                            &Context.Idents.get("id"), IdInfo);
+    PushOnScopeChains(IdTypedef, TUScope);
+    Context.setObjCIdType(Context.getTypeDeclType(IdTypedef));
+    Context.ObjCIdRedefinitionType = Context.getObjCIdType();
+  }
+  // Create the built-in typedef for 'Class'.
+  if (Context.getObjCClassType().isNull()) {
+    QualType ClassType
+      = Context.getObjCObjectPointerType(Context.ObjCBuiltinClassTy);
+    TypeSourceInfo *ClassInfo = Context.getTrivialTypeSourceInfo(ClassType);
+    TypedefDecl *ClassTypedef
+      = TypedefDecl::Create(Context, CurContext, SourceLocation(),
+                            &Context.Idents.get("Class"), ClassInfo);
+    PushOnScopeChains(ClassTypedef, TUScope);
+    Context.setObjCClassType(Context.getTypeDeclType(ClassTypedef));
+    Context.ObjCClassRedefinitionType = Context.getObjCClassType();
+  }
+}
+
+Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
+           bool CompleteTranslationUnit,
+           CodeCompleteConsumer *CodeCompleter)
+  : TheTargetAttributesSema(0),
+    LangOpts(pp.getLangOptions()), PP(pp), Context(ctxt), Consumer(consumer),
+    Diags(PP.getDiagnostics()), SourceMgr(PP.getSourceManager()),
+    ExternalSource(0), CodeCompleter(CodeCompleter), CurContext(0), 
+    PackContext(0), TopFunctionScope(0), ParsingDeclDepth(0),
+    IdResolver(pp.getLangOptions()), StdNamespace(0), StdBadAlloc(0),
+    GlobalNewDeleteDeclared(false), 
+    CompleteTranslationUnit(CompleteTranslationUnit),
+    NumSFINAEErrors(0), NonInstantiationEntries(0), 
+    CurrentInstantiationScope(0), TyposCorrected(0),
+    AnalysisWarnings(*this)
+{
+  TUScope = 0;
+  if (getLangOptions().CPlusPlus)
+    FieldCollector.reset(new CXXFieldCollector());
+
+  // Tell diagnostics how to render things from the AST library.
+  PP.getDiagnostics().SetArgToStringFn(&FormatASTNodeDiagnosticArgument, 
+                                       &Context);
+
+  ExprEvalContexts.push_back(
+                  ExpressionEvaluationContextRecord(PotentiallyEvaluated, 0));
+}
+
+Sema::~Sema() {
+  if (PackContext) FreePackedContext();
+  delete TheTargetAttributesSema;
+  while (!FunctionScopes.empty())
+    PopFunctionOrBlockScope();
+}
+
+/// ImpCastExprToType - If Expr is not of type 'Type', insert an implicit cast.
+/// If there is already an implicit cast, merge into the existing one.
+/// If isLvalue, the result of the cast is an lvalue.
+void Sema::ImpCastExprToType(Expr *&Expr, QualType Ty,
+                             CastExpr::CastKind Kind, 
+                             bool isLvalue, CXXBaseSpecifierArray BasePath) {
+  QualType ExprTy = Context.getCanonicalType(Expr->getType());
+  QualType TypeTy = Context.getCanonicalType(Ty);
+
+  if (ExprTy == TypeTy)
+    return;
+
+  if (Expr->getType()->isPointerType() && Ty->isPointerType()) {
+    QualType ExprBaseType = cast<PointerType>(ExprTy)->getPointeeType();
+    QualType BaseType = cast<PointerType>(TypeTy)->getPointeeType();
+    if (ExprBaseType.getAddressSpace() != BaseType.getAddressSpace()) {
+      Diag(Expr->getExprLoc(), diag::err_implicit_pointer_address_space_cast)
+        << Expr->getSourceRange();
+    }
+  }
+
+  CheckImplicitConversion(Expr, Ty);
+
+  if (ImplicitCastExpr *ImpCast = dyn_cast<ImplicitCastExpr>(Expr)) {
+    if (ImpCast->getCastKind() == Kind && BasePath.empty()) {
+      ImpCast->setType(Ty);
+      ImpCast->setLvalueCast(isLvalue);
+      return;
+    }
+  }
+
+  Expr = new (Context) ImplicitCastExpr(Ty, Kind, Expr, BasePath, isLvalue);
+}
+
+void Sema::DeleteExpr(ExprTy *E) {
+  if (E) static_cast<Expr*>(E)->Destroy(Context);
+}
+void Sema::DeleteStmt(StmtTy *S) {
+  if (S) static_cast<Stmt*>(S)->Destroy(Context);
+}
+
+/// ActOnEndOfTranslationUnit - This is called at the very end of the
+/// translation unit when EOF is reached and all but the top-level scope is
+/// popped.
+void Sema::ActOnEndOfTranslationUnit() {  
+  while (1) {
+    // C++: Perform implicit template instantiations.
+    //
+    // FIXME: When we perform these implicit instantiations, we do not carefully
+    // keep track of the point of instantiation (C++ [temp.point]). This means
+    // that name lookup that occurs within the template instantiation will
+    // always happen at the end of the translation unit, so it will find
+    // some names that should not be found. Although this is common behavior
+    // for C++ compilers, it is technically wrong. In the future, we either need
+    // to be able to filter the results of name lookup or we need to perform
+    // template instantiations earlier.
+    PerformPendingImplicitInstantiations();
+    
+    /// If ProcessPendingClassesWithUnmarkedVirtualMembers ends up marking 
+    /// any virtual member functions it might lead to more pending template
+    /// instantiations, which is why we need to loop here.
+    if (!ProcessPendingClassesWithUnmarkedVirtualMembers())
+      break;
+  }
+  
+  // Remove functions that turned out to be used.
+  UnusedStaticFuncs.erase(std::remove_if(UnusedStaticFuncs.begin(), 
+                                         UnusedStaticFuncs.end(), 
+                                         std::mem_fun(&FunctionDecl::isUsed)), 
+                          UnusedStaticFuncs.end());
+
+  // Check for #pragma weak identifiers that were never declared
+  // FIXME: This will cause diagnostics to be emitted in a non-determinstic
+  // order!  Iterating over a densemap like this is bad.
+  for (llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator
+       I = WeakUndeclaredIdentifiers.begin(),
+       E = WeakUndeclaredIdentifiers.end(); I != E; ++I) {
+    if (I->second.getUsed()) continue;
+
+    Diag(I->second.getLocation(), diag::warn_weak_identifier_undeclared)
+      << I->first;
+  }
+
+  if (!CompleteTranslationUnit)
+    return;
+
+  // C99 6.9.2p2:
+  //   A declaration of an identifier for an object that has file
+  //   scope without an initializer, and without a storage-class
+  //   specifier or with the storage-class specifier static,
+  //   constitutes a tentative definition. If a translation unit
+  //   contains one or more tentative definitions for an identifier,
+  //   and the translation unit contains no external definition for
+  //   that identifier, then the behavior is exactly as if the
+  //   translation unit contains a file scope declaration of that
+  //   identifier, with the composite type as of the end of the
+  //   translation unit, with an initializer equal to 0.
+  llvm::SmallSet<VarDecl *, 32> Seen;
+  for (unsigned i = 0, e = TentativeDefinitions.size(); i != e; ++i) {
+    VarDecl *VD = TentativeDefinitions[i]->getActingDefinition();
+
+    // If the tentative definition was completed, getActingDefinition() returns
+    // null. If we've already seen this variable before, insert()'s second
+    // return value is false.
+    if (VD == 0 || VD->isInvalidDecl() || !Seen.insert(VD))
+      continue;
+
+    if (const IncompleteArrayType *ArrayT
+        = Context.getAsIncompleteArrayType(VD->getType())) {
+      if (RequireCompleteType(VD->getLocation(),
+                              ArrayT->getElementType(),
+                              diag::err_tentative_def_incomplete_type_arr)) {
+        VD->setInvalidDecl();
+        continue;
+      }
+
+      // Set the length of the array to 1 (C99 6.9.2p5).
+      Diag(VD->getLocation(), diag::warn_tentative_incomplete_array);
+      llvm::APInt One(Context.getTypeSize(Context.getSizeType()), true);
+      QualType T = Context.getConstantArrayType(ArrayT->getElementType(),
+                                                One, ArrayType::Normal, 0);
+      VD->setType(T);
+    } else if (RequireCompleteType(VD->getLocation(), VD->getType(),
+                                   diag::err_tentative_def_incomplete_type))
+      VD->setInvalidDecl();
+
+    // Notify the consumer that we've completed a tentative definition.
+    if (!VD->isInvalidDecl())
+      Consumer.CompleteTentativeDefinition(VD);
+
+  }
+  
+  // Output warning for unused functions.
+  for (std::vector<FunctionDecl*>::iterator
+       F = UnusedStaticFuncs.begin(),
+       FEnd = UnusedStaticFuncs.end();
+       F != FEnd;
+       ++F)
+    Diag((*F)->getLocation(), diag::warn_unused_function) << (*F)->getDeclName();
+  
+}
+
+
+//===----------------------------------------------------------------------===//
+// Helper functions.
+//===----------------------------------------------------------------------===//
+
+DeclContext *Sema::getFunctionLevelDeclContext() {
+  DeclContext *DC = CurContext;
+
+  while (isa<BlockDecl>(DC))
+    DC = DC->getParent();
+
+  return DC;
+}
+
+/// getCurFunctionDecl - If inside of a function body, this returns a pointer
+/// to the function decl for the function being parsed.  If we're currently
+/// in a 'block', this returns the containing context.
+FunctionDecl *Sema::getCurFunctionDecl() {
+  DeclContext *DC = getFunctionLevelDeclContext();
+  return dyn_cast<FunctionDecl>(DC);
+}
+
+ObjCMethodDecl *Sema::getCurMethodDecl() {
+  DeclContext *DC = getFunctionLevelDeclContext();
+  return dyn_cast<ObjCMethodDecl>(DC);
+}
+
+NamedDecl *Sema::getCurFunctionOrMethodDecl() {
+  DeclContext *DC = getFunctionLevelDeclContext();
+  if (isa<ObjCMethodDecl>(DC) || isa<FunctionDecl>(DC))
+    return cast<NamedDecl>(DC);
+  return 0;
+}
+
+Sema::SemaDiagnosticBuilder::~SemaDiagnosticBuilder() {
+  if (!this->Emit())
+    return;
+
+  // If this is not a note, and we're in a template instantiation
+  // that is different from the last template instantiation where
+  // we emitted an error, print a template instantiation
+  // backtrace.
+  if (!SemaRef.Diags.isBuiltinNote(DiagID) &&
+      !SemaRef.ActiveTemplateInstantiations.empty() &&
+      SemaRef.ActiveTemplateInstantiations.back()
+        != SemaRef.LastTemplateInstantiationErrorContext) {
+    SemaRef.PrintInstantiationStack();
+    SemaRef.LastTemplateInstantiationErrorContext
+      = SemaRef.ActiveTemplateInstantiations.back();
+  }
+}
+
+Sema::SemaDiagnosticBuilder Sema::Diag(SourceLocation Loc, unsigned DiagID) {
+  if (isSFINAEContext()) {
+    switch (Diagnostic::getDiagnosticSFINAEResponse(DiagID)) {
+    case Diagnostic::SFINAE_Report:
+      // Fall through; we'll report the diagnostic below.
+      break;
+
+    case Diagnostic::SFINAE_SubstitutionFailure:
+      // Count this failure so that we know that template argument deduction
+      // has failed.
+      ++NumSFINAEErrors;
+      // Fall through
+        
+    case Diagnostic::SFINAE_Suppress:
+      // Suppress this diagnostic.
+      Diags.setLastDiagnosticIgnored();
+      return SemaDiagnosticBuilder(*this);
+    }
+  }
+  
+  DiagnosticBuilder DB = Diags.Report(FullSourceLoc(Loc, SourceMgr), DiagID);
+  return SemaDiagnosticBuilder(DB, *this, DiagID);
+}
+
+Sema::SemaDiagnosticBuilder
+Sema::Diag(SourceLocation Loc, const PartialDiagnostic& PD) {
+  SemaDiagnosticBuilder Builder(Diag(Loc, PD.getDiagID()));
+  PD.Emit(Builder);
+
+  return Builder;
+}
+
+
+/// \brief Enter a new function scope
+void Sema::PushFunctionScope() {
+  if (FunctionScopes.empty()) {
+    // Use the "top" function scope rather than having to allocate memory for
+    // a new scope.
+    TopFunctionScope.Clear(getDiagnostics().getNumErrors());
+    FunctionScopes.push_back(&TopFunctionScope);
+    return;
+  }
+  
+  FunctionScopes.push_back(
+                      new FunctionScopeInfo(getDiagnostics().getNumErrors()));
+}
+
+void Sema::PushBlockScope(Scope *BlockScope, BlockDecl *Block) {
+  FunctionScopes.push_back(new BlockScopeInfo(getDiagnostics().getNumErrors(),
+                                              BlockScope, Block));
+}
+
+void Sema::PopFunctionOrBlockScope() {
+  if (FunctionScopes.back() != &TopFunctionScope)
+    delete FunctionScopes.back();
+  else
+    TopFunctionScope.Clear(getDiagnostics().getNumErrors());
+  
+  FunctionScopes.pop_back();
+}
+
+/// \brief Determine whether any errors occurred within this function/method/
+/// block.
+bool Sema::hasAnyErrorsInThisFunction() const {
+  unsigned NumErrors = TopFunctionScope.NumErrorsAtStartOfFunction;
+  if (!FunctionScopes.empty())
+    NumErrors = FunctionScopes.back()->NumErrorsAtStartOfFunction;
+  return NumErrors != getDiagnostics().getNumErrors();
+}
+
+BlockScopeInfo *Sema::getCurBlock() {
+  if (FunctionScopes.empty())
+    return 0;
+  
+  return dyn_cast<BlockScopeInfo>(FunctionScopes.back());  
+}
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
new file mode 100644
index 0000000..212a36f
--- /dev/null
+++ b/lib/Sema/Sema.h
@@ -0,0 +1,4463 @@
+//===--- Sema.h - Semantic Analysis & AST Building --------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the Sema class, which performs semantic analysis and
+// builds ASTs.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_SEMA_H
+#define LLVM_CLANG_AST_SEMA_H
+
+#include "IdentifierResolver.h"
+#include "CXXFieldCollector.h"
+#include "SemaOverload.h"
+#include "SemaTemplate.h"
+#include "AnalysisBasedWarnings.h"
+#include "clang/AST/Attr.h"
+#include "clang/AST/DeclBase.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/FullExpr.h"
+#include "clang/Parse/Action.h"
+#include "clang/Sema/SemaDiagnostic.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/OwningPtr.h"
+#include <deque>
+#include <list>
+#include <map>
+#include <string>
+#include <vector>
+
+namespace llvm {
+  class APSInt;
+}
+
+namespace clang {
+  class ASTContext;
+  class ASTConsumer;
+  class CodeCompleteConsumer;
+  class Preprocessor;
+  class Decl;
+  class DeclContext;
+  class DeclSpec;
+  class ExternalSemaSource;
+  class NamedDecl;
+  class Stmt;
+  class Expr;
+  class InitListExpr;
+  class ParenListExpr;
+  class DesignatedInitExpr;
+  class CallExpr;
+  class DeclRefExpr;
+  class UnresolvedLookupExpr;
+  class UnresolvedMemberExpr;
+  class VarDecl;
+  class ParmVarDecl;
+  class TypedefDecl;
+  class FunctionDecl;
+  class QualType;
+  class LangOptions;
+  class Token;
+  class IntegerLiteral;
+  class StringLiteral;
+  class ArrayType;
+  class LabelStmt;
+  class SwitchStmt;
+  class CXXTryStmt;
+  class ExtVectorType;
+  class TypedefDecl;
+  class TemplateDecl;
+  class TemplateArgument;
+  class TemplateArgumentLoc;
+  class TemplateArgumentList;
+  class TemplateParameterList;
+  class TemplateTemplateParmDecl;
+  class ClassTemplatePartialSpecializationDecl;
+  class ClassTemplateDecl;
+  class ObjCInterfaceDecl;
+  class ObjCCompatibleAliasDecl;
+  class ObjCProtocolDecl;
+  class ObjCImplDecl;
+  class ObjCImplementationDecl;
+  class ObjCCategoryImplDecl;
+  class ObjCCategoryDecl;
+  class ObjCIvarDecl;
+  class ObjCMethodDecl;
+  class ObjCPropertyDecl;
+  class ObjCContainerDecl;
+  class PseudoDestructorTypeStorage;
+  class FunctionProtoType;
+  class CXXBasePath;
+  class CXXBasePaths;
+  class CXXTemporary;
+  class LookupResult;
+  class InitializedEntity;
+  class InitializationKind;
+  class InitializationSequence;
+  class VisibleDeclConsumer;
+  class TargetAttributesSema;
+  class ADLResult;
+
+/// \brief Retains information about a function, method, or block that is 
+/// currently being parsed.
+struct FunctionScopeInfo {
+  /// \brief Whether this scope information structure defined information for
+  /// a block.
+  bool IsBlockInfo;
+  
+  /// \brief Set true when a function, method contains a VLA or ObjC try block, 
+  /// which introduce scopes that need to be checked for goto conditions.  If a
+  /// function does not contain this, then it need not have the jump checker run on it.
+  bool NeedsScopeChecking;
+    
+  /// \brief The number of errors that had occurred before starting this
+  /// function or block.
+  unsigned NumErrorsAtStartOfFunction;
+  
+  /// LabelMap - This is a mapping from label identifiers to the LabelStmt for
+  /// it (which acts like the label decl in some ways).  Forward referenced
+  /// labels have a LabelStmt created for them with a null location & SubStmt.
+  llvm::DenseMap<IdentifierInfo*, LabelStmt*> LabelMap;
+  
+  /// SwitchStack - This is the current set of active switch statements in the
+  /// block.
+  llvm::SmallVector<SwitchStmt*, 8> SwitchStack;  
+  
+  FunctionScopeInfo(unsigned NumErrors) 
+    : IsBlockInfo(false), NeedsScopeChecking(false), 
+      NumErrorsAtStartOfFunction(NumErrors) { }
+
+  virtual ~FunctionScopeInfo();
+
+  /// \brief Clear out the information in this function scope, making it
+  /// suitable for reuse.
+  void Clear(unsigned NumErrors);
+  
+  static bool classof(const FunctionScopeInfo *FSI) { return true; }  
+};
+  
+  
+/// \brief Retains information about a block that is currently being parsed.
+struct BlockScopeInfo : FunctionScopeInfo {
+  llvm::SmallVector<ParmVarDecl*, 8> Params;
+  bool hasPrototype;
+  bool isVariadic;
+  bool hasBlockDeclRefExprs;
+
+  BlockDecl *TheDecl;
+
+  /// TheScope - This is the scope for the block itself, which contains
+  /// arguments etc.
+  Scope *TheScope;
+
+  /// ReturnType - This will get set to block result type, by looking at
+  /// return types, if any, in the block body.
+  QualType ReturnType;
+
+  BlockScopeInfo(unsigned NumErrors, Scope *BlockScope, BlockDecl *Block) 
+    : FunctionScopeInfo(NumErrors), hasPrototype(false), isVariadic(false), 
+      hasBlockDeclRefExprs(false), TheDecl(Block), TheScope(BlockScope) 
+  {
+    IsBlockInfo = true; 
+  }
+
+  virtual ~BlockScopeInfo();
+
+  static bool classof(const FunctionScopeInfo *FSI) { return FSI->IsBlockInfo; }
+  static bool classof(const BlockScopeInfo *BSI) { return true; }
+};
+
+/// \brief Holds a QualType and a TypeSourceInfo* that came out of a declarator
+/// parsing.
+///
+/// LocInfoType is a "transient" type, only needed for passing to/from Parser
+/// and Sema, when we want to preserve type source info for a parsed type.
+/// It will not participate in the type system semantics in any way.
+class LocInfoType : public Type {
+  enum {
+    // The last number that can fit in Type's TC.
+    // Avoids conflict with an existing Type class.
+    LocInfo = Type::TypeLast + 1
+  };
+
+  TypeSourceInfo *DeclInfo;
+
+  LocInfoType(QualType ty, TypeSourceInfo *TInfo)
+    : Type((TypeClass)LocInfo, ty, ty->isDependentType()), DeclInfo(TInfo) {
+    assert(getTypeClass() == (TypeClass)LocInfo && "LocInfo didn't fit in TC?");
+  }
+  friend class Sema;
+
+public:
+  QualType getType() const { return getCanonicalTypeInternal(); }
+  TypeSourceInfo *getTypeSourceInfo() const { return DeclInfo; }
+
+  virtual void getAsStringInternal(std::string &Str,
+                                   const PrintingPolicy &Policy) const;
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == (TypeClass)LocInfo;
+  }
+  static bool classof(const LocInfoType *) { return true; }
+};
+
+/// Sema - This implements semantic analysis and AST building for C.
+class Sema : public Action {
+  Sema(const Sema&);           // DO NOT IMPLEMENT
+  void operator=(const Sema&); // DO NOT IMPLEMENT
+  mutable const TargetAttributesSema* TheTargetAttributesSema;
+public:
+  const LangOptions &LangOpts;
+  Preprocessor &PP;
+  ASTContext &Context;
+  ASTConsumer &Consumer;
+  Diagnostic &Diags;
+  SourceManager &SourceMgr;
+
+  /// \brief Source of additional semantic information.
+  ExternalSemaSource *ExternalSource;
+
+  /// \brief Code-completion consumer.
+  CodeCompleteConsumer *CodeCompleter;
+
+  /// CurContext - This is the current declaration context of parsing.
+  DeclContext *CurContext;
+
+  /// PackContext - Manages the stack for #pragma pack. An alignment
+  /// of 0 indicates default alignment.
+  void *PackContext; // Really a "PragmaPackStack*"
+
+  /// \brief Stack containing information about each of the nested function,
+  /// block, and method scopes that are currently active.
+  llvm::SmallVector<FunctionScopeInfo *, 4> FunctionScopes;
+  
+  /// \brief Cached function scope object used for the top function scope
+  /// and when there is no function scope (in error cases).
+  ///
+  /// This should never be accessed directly; rather, it's address will be 
+  /// pushed into \c FunctionScopes when we want to re-use it.
+  FunctionScopeInfo TopFunctionScope;
+  
+  /// ExprTemporaries - This is the stack of temporaries that are created by
+  /// the current full expression.
+  llvm::SmallVector<CXXTemporary*, 8> ExprTemporaries;
+
+  /// ExtVectorDecls - This is a list all the extended vector types. This allows
+  /// us to associate a raw vector type with one of the ext_vector type names.
+  /// This is only necessary for issuing pretty diagnostics.
+  llvm::SmallVector<TypedefDecl*, 24> ExtVectorDecls;
+
+  /// FieldCollector - Collects CXXFieldDecls during parsing of C++ classes.
+  llvm::OwningPtr<CXXFieldCollector> FieldCollector;
+
+  typedef llvm::SmallPtrSet<const CXXRecordDecl*, 8> RecordDeclSetTy;
+
+  /// PureVirtualClassDiagSet - a set of class declarations which we have
+  /// emitted a list of pure virtual functions. Used to prevent emitting the
+  /// same list more than once.
+  llvm::OwningPtr<RecordDeclSetTy> PureVirtualClassDiagSet;
+
+  /// \brief A mapping from external names to the most recent
+  /// locally-scoped external declaration with that name.
+  ///
+  /// This map contains external declarations introduced in local
+  /// scoped, e.g.,
+  ///
+  /// \code
+  /// void f() {
+  ///   void foo(int, int);
+  /// }
+  /// \endcode
+  ///
+  /// Here, the name "foo" will be associated with the declaration on
+  /// "foo" within f. This name is not visible outside of
+  /// "f". However, we still find it in two cases:
+  ///
+  ///   - If we are declaring another external with the name "foo", we
+  ///     can find "foo" as a previous declaration, so that the types
+  ///     of this external declaration can be checked for
+  ///     compatibility.
+  ///
+  ///   - If we would implicitly declare "foo" (e.g., due to a call to
+  ///     "foo" in C when no prototype or definition is visible), then
+  ///     we find this declaration of "foo" and complain that it is
+  ///     not visible.
+  llvm::DenseMap<DeclarationName, NamedDecl *> LocallyScopedExternalDecls;
+
+  /// \brief All the tentative definitions encountered in the TU.
+  std::vector<VarDecl *> TentativeDefinitions;
+
+  /// \brief The set of static functions seen so far that have not been used.
+  std::vector<FunctionDecl*> UnusedStaticFuncs;
+
+  class AccessedEntity {
+  public:
+    /// A member declaration found through lookup.  The target is the
+    /// member.
+    enum MemberNonce { Member };
+
+    /// A hierarchy (base-to-derived or derived-to-base) conversion.
+    /// The target is the base class.
+    enum BaseNonce { Base };
+
+    bool isMemberAccess() const { return IsMember; }
+
+    AccessedEntity(ASTContext &Context, 
+                   MemberNonce _,
+                   CXXRecordDecl *NamingClass,
+                   DeclAccessPair FoundDecl,
+                   QualType BaseObjectType)
+      : Access(FoundDecl.getAccess()), IsMember(true), 
+        Target(FoundDecl.getDecl()), NamingClass(NamingClass),
+        BaseObjectType(BaseObjectType), Diag(0, Context.getDiagAllocator()) {
+    }
+
+    AccessedEntity(ASTContext &Context, 
+                   BaseNonce _,
+                   CXXRecordDecl *BaseClass,
+                   CXXRecordDecl *DerivedClass,
+                   AccessSpecifier Access)
+      : Access(Access), IsMember(false),
+        Target(BaseClass), NamingClass(DerivedClass),
+        Diag(0, Context.getDiagAllocator()) {
+    }
+
+    bool isQuiet() const { return Diag.getDiagID() == 0; }
+
+    AccessSpecifier getAccess() const { return AccessSpecifier(Access); }
+
+    // These apply to member decls...
+    NamedDecl *getTargetDecl() const { return Target; }
+    CXXRecordDecl *getNamingClass() const { return NamingClass; }
+
+    // ...and these apply to hierarchy conversions.
+    CXXRecordDecl *getBaseClass() const { return cast<CXXRecordDecl>(Target); }
+    CXXRecordDecl *getDerivedClass() const { return NamingClass; }
+
+    /// Retrieves the base object type, important when accessing
+    /// an instance member.
+    QualType getBaseObjectType() const { return BaseObjectType; }
+
+    /// Sets a diagnostic to be performed.  The diagnostic is given
+    /// four (additional) arguments:
+    ///   %0 - 0 if the entity was private, 1 if protected
+    ///   %1 - the DeclarationName of the entity
+    ///   %2 - the TypeDecl type of the naming class
+    ///   %3 - the TypeDecl type of the declaring class
+    void setDiag(const PartialDiagnostic &PDiag) {
+      assert(isQuiet() && "partial diagnostic already defined");
+      Diag = PDiag;
+    }
+    PartialDiagnostic &setDiag(unsigned DiagID) {
+      assert(isQuiet() && "partial diagnostic already defined");
+      assert(DiagID && "creating null diagnostic");
+      Diag.Reset(DiagID);
+      return Diag;
+    }
+    const PartialDiagnostic &getDiag() const {
+      return Diag;
+    }
+
+  private:
+    unsigned Access : 2;
+    bool IsMember;
+    NamedDecl *Target;
+    CXXRecordDecl *NamingClass;    
+    QualType BaseObjectType;
+    PartialDiagnostic Diag;
+  };
+
+  struct DelayedDiagnostic {
+    enum DDKind { Deprecation, Access };
+
+    unsigned char Kind; // actually a DDKind
+    bool Triggered;
+
+    SourceLocation Loc;
+
+    union {
+      /// Deprecation.
+      struct { NamedDecl *Decl; } DeprecationData;
+
+      /// Access control.
+      char AccessData[sizeof(AccessedEntity)];
+    };
+
+    void destroy() {
+      switch (Kind) {
+      case Access: getAccessData().~AccessedEntity(); break;
+      case Deprecation: break;
+      }
+    }
+
+    static DelayedDiagnostic makeDeprecation(SourceLocation Loc,
+                                             NamedDecl *D) {
+      DelayedDiagnostic DD;
+      DD.Kind = Deprecation;
+      DD.Triggered = false;
+      DD.Loc = Loc;
+      DD.DeprecationData.Decl = D;
+      return DD;
+    }
+
+    static DelayedDiagnostic makeAccess(SourceLocation Loc,
+                                        const AccessedEntity &Entity) {
+      DelayedDiagnostic DD;
+      DD.Kind = Access;
+      DD.Triggered = false;
+      DD.Loc = Loc;
+      new (&DD.getAccessData()) AccessedEntity(Entity);
+      return DD;
+    }
+
+    AccessedEntity &getAccessData() {
+      return *reinterpret_cast<AccessedEntity*>(AccessData);
+    }
+    const AccessedEntity &getAccessData() const {
+      return *reinterpret_cast<const AccessedEntity*>(AccessData);
+    }
+  };
+
+  /// \brief The stack of diagnostics that were delayed due to being
+  /// produced during the parsing of a declaration.
+  llvm::SmallVector<DelayedDiagnostic, 8> DelayedDiagnostics;
+
+  /// \brief The depth of the current ParsingDeclaration stack.
+  /// If nonzero, we are currently parsing a declaration (and
+  /// hence should delay deprecation warnings).
+  unsigned ParsingDeclDepth;
+
+  /// WeakUndeclaredIdentifiers - Identifiers contained in
+  /// #pragma weak before declared. rare. may alias another
+  /// identifier, declared or undeclared
+  class WeakInfo {
+    IdentifierInfo *alias;  // alias (optional)
+    SourceLocation loc;     // for diagnostics
+    bool used;              // identifier later declared?
+  public:
+    WeakInfo()
+      : alias(0), loc(SourceLocation()), used(false) {}
+    WeakInfo(IdentifierInfo *Alias, SourceLocation Loc)
+      : alias(Alias), loc(Loc), used(false) {}
+    inline IdentifierInfo * getAlias() const { return alias; }
+    inline SourceLocation getLocation() const { return loc; }
+    void setUsed(bool Used=true) { used = Used; }
+    inline bool getUsed() { return used; }
+    bool operator==(WeakInfo RHS) const {
+      return alias == RHS.getAlias() && loc == RHS.getLocation();
+    }
+    bool operator!=(WeakInfo RHS) const { return !(*this == RHS); }
+  };
+  llvm::DenseMap<IdentifierInfo*,WeakInfo> WeakUndeclaredIdentifiers;
+
+  /// WeakTopLevelDecl - Translation-unit scoped declarations generated by
+  /// #pragma weak during processing of other Decls.
+  /// I couldn't figure out a clean way to generate these in-line, so
+  /// we store them here and handle separately -- which is a hack.
+  /// It would be best to refactor this.
+  llvm::SmallVector<Decl*,2> WeakTopLevelDecl;
+
+  IdentifierResolver IdResolver;
+
+  /// Translation Unit Scope - useful to Objective-C actions that need
+  /// to lookup file scope declarations in the "ordinary" C decl namespace.
+  /// For example, user-defined classes, built-in "id" type, etc.
+  Scope *TUScope;
+
+  /// \brief The C++ "std" namespace, where the standard library resides.
+  NamespaceDecl *StdNamespace;
+
+  /// \brief The C++ "std::bad_alloc" class, which is defined by the C++
+  /// standard library.
+  CXXRecordDecl *StdBadAlloc;
+  
+  /// A flag to remember whether the implicit forms of operator new and delete
+  /// have been declared.
+  bool GlobalNewDeleteDeclared;
+
+  /// \brief The set of declarations that have been referenced within
+  /// a potentially evaluated expression.
+  typedef std::vector<std::pair<SourceLocation, Decl *> > 
+    PotentiallyReferencedDecls;
+
+  /// \brief A set of diagnostics that may be emitted.
+  typedef std::vector<std::pair<SourceLocation, PartialDiagnostic> >
+    PotentiallyEmittedDiagnostics;
+
+  /// \brief Data structure used to record current or nested
+  /// expression evaluation contexts.
+  struct ExpressionEvaluationContextRecord {
+    /// \brief The expression evaluation context.
+    ExpressionEvaluationContext Context;
+
+    /// \brief The number of temporaries that were active when we
+    /// entered this expression evaluation context.
+    unsigned NumTemporaries;
+
+    /// \brief The set of declarations referenced within a
+    /// potentially potentially-evaluated context.
+    ///
+    /// When leaving a potentially potentially-evaluated context, each
+    /// of these elements will be as referenced if the corresponding
+    /// potentially potentially evaluated expression is potentially
+    /// evaluated.
+    PotentiallyReferencedDecls *PotentiallyReferenced;
+
+    /// \brief The set of diagnostics to emit should this potentially
+    /// potentially-evaluated context become evaluated.
+    PotentiallyEmittedDiagnostics *PotentiallyDiagnosed;
+
+    ExpressionEvaluationContextRecord(ExpressionEvaluationContext Context,
+                                      unsigned NumTemporaries) 
+      : Context(Context), NumTemporaries(NumTemporaries), 
+        PotentiallyReferenced(0), PotentiallyDiagnosed(0) { }
+
+    void addReferencedDecl(SourceLocation Loc, Decl *Decl) {
+      if (!PotentiallyReferenced)
+        PotentiallyReferenced = new PotentiallyReferencedDecls;
+      PotentiallyReferenced->push_back(std::make_pair(Loc, Decl));
+    }
+
+    void addDiagnostic(SourceLocation Loc, const PartialDiagnostic &PD) {
+      if (!PotentiallyDiagnosed)
+        PotentiallyDiagnosed = new PotentiallyEmittedDiagnostics;
+      PotentiallyDiagnosed->push_back(std::make_pair(Loc, PD));
+    }
+
+    void Destroy() {
+      delete PotentiallyReferenced;
+      delete PotentiallyDiagnosed;
+      PotentiallyReferenced = 0;
+      PotentiallyDiagnosed = 0;
+    }
+  };
+
+  /// A stack of expression evaluation contexts.
+  llvm::SmallVector<ExpressionEvaluationContextRecord, 8> ExprEvalContexts;
+
+  /// \brief Whether the code handled by Sema should be considered a
+  /// complete translation unit or not.
+  ///
+  /// When true (which is generally the case), Sema will perform
+  /// end-of-translation-unit semantic tasks (such as creating
+  /// initializers for tentative definitions in C) once parsing has
+  /// completed. This flag will be false when building PCH files,
+  /// since a PCH file is by definition not a complete translation
+  /// unit.
+  bool CompleteTranslationUnit;
+
+  llvm::BumpPtrAllocator BumpAlloc;
+
+  /// \brief The number of SFINAE diagnostics that have been trapped.
+  unsigned NumSFINAEErrors;
+
+  typedef llvm::DenseMap<Selector, ObjCMethodList> MethodPool;
+
+  /// Instance/Factory Method Pools - allows efficient lookup when typechecking
+  /// messages to "id". We need to maintain a list, since selectors can have
+  /// differing signatures across classes. In Cocoa, this happens to be
+  /// extremely uncommon (only 1% of selectors are "overloaded").
+  MethodPool InstanceMethodPool;
+  MethodPool FactoryMethodPool;
+
+  MethodPool::iterator ReadMethodPool(Selector Sel, bool isInstance);
+
+  /// Private Helper predicate to check for 'self'.
+  bool isSelfExpr(Expr *RExpr);
+public:
+  Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
+       bool CompleteTranslationUnit = true,
+       CodeCompleteConsumer *CompletionConsumer = 0);
+  ~Sema();
+
+  const LangOptions &getLangOptions() const { return LangOpts; }
+  Diagnostic &getDiagnostics() const { return Diags; }
+  SourceManager &getSourceManager() const { return SourceMgr; }
+  const TargetAttributesSema &getTargetAttributesSema() const;
+
+  /// \brief Helper class that creates diagnostics with optional
+  /// template instantiation stacks.
+  ///
+  /// This class provides a wrapper around the basic DiagnosticBuilder
+  /// class that emits diagnostics. SemaDiagnosticBuilder is
+  /// responsible for emitting the diagnostic (as DiagnosticBuilder
+  /// does) and, if the diagnostic comes from inside a template
+  /// instantiation, printing the template instantiation stack as
+  /// well.
+  class SemaDiagnosticBuilder : public DiagnosticBuilder {
+    Sema &SemaRef;
+    unsigned DiagID;
+
+  public:
+    SemaDiagnosticBuilder(DiagnosticBuilder &DB, Sema &SemaRef, unsigned DiagID)
+      : DiagnosticBuilder(DB), SemaRef(SemaRef), DiagID(DiagID) { }
+
+    explicit SemaDiagnosticBuilder(Sema &SemaRef)
+      : DiagnosticBuilder(DiagnosticBuilder::Suppress), SemaRef(SemaRef) { }
+
+    ~SemaDiagnosticBuilder();
+  };
+
+  /// \brief Emit a diagnostic.
+  SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID);
+
+  /// \brief Emit a partial diagnostic.
+  SemaDiagnosticBuilder Diag(SourceLocation Loc, const PartialDiagnostic& PD);
+
+  /// \brief Build a partial diagnostic. 
+  PartialDiagnostic PDiag(unsigned DiagID = 0) {
+    return PartialDiagnostic(DiagID, Context.getDiagAllocator());
+  }
+  
+  virtual void DeleteExpr(ExprTy *E);
+  virtual void DeleteStmt(StmtTy *S);
+
+  OwningExprResult Owned(Expr* E) {
+    assert(!E || E->isRetained());
+    return OwningExprResult(*this, E);
+  }
+  OwningExprResult Owned(ExprResult R) {
+    if (R.isInvalid())
+      return ExprError();
+    assert(!R.get() || ((Expr*) R.get())->isRetained());
+    return OwningExprResult(*this, R.get());
+  }
+  OwningStmtResult Owned(Stmt* S) {
+    assert(!S || S->isRetained());
+    return OwningStmtResult(*this, S);
+  }
+
+  virtual void ActOnEndOfTranslationUnit();
+
+  void PushFunctionScope();
+  void PushBlockScope(Scope *BlockScope, BlockDecl *Block);
+  void PopFunctionOrBlockScope();
+  
+  /// getLabelMap() - Return the current label map.  If we're in a block, we
+  /// return it.
+  llvm::DenseMap<IdentifierInfo*, LabelStmt*> &getLabelMap() {
+    if (FunctionScopes.empty())
+      return TopFunctionScope.LabelMap;
+    
+    return FunctionScopes.back()->LabelMap;
+  }
+
+  /// getSwitchStack - This is returns the switch stack for the current block or
+  /// function.
+  llvm::SmallVector<SwitchStmt*,8> &getSwitchStack() {
+    if (FunctionScopes.empty())
+      return TopFunctionScope.SwitchStack;
+    
+    return FunctionScopes.back()->SwitchStack;
+  }
+
+  /// \brief Determine whether the current function or block needs scope 
+  /// checking.
+  bool &FunctionNeedsScopeChecking() {
+    if (FunctionScopes.empty())
+      return TopFunctionScope.NeedsScopeChecking;
+    
+    return FunctionScopes.back()->NeedsScopeChecking;
+  }
+  
+  bool hasAnyErrorsInThisFunction() const;
+  
+  /// \brief Retrieve the current block, if any.
+  BlockScopeInfo *getCurBlock();
+  
+  /// WeakTopLevelDeclDecls - access to #pragma weak-generated Decls
+  llvm::SmallVector<Decl*,2> &WeakTopLevelDecls() { return WeakTopLevelDecl; }
+
+  //===--------------------------------------------------------------------===//
+  // Type Analysis / Processing: SemaType.cpp.
+  //
+
+  QualType adjustParameterType(QualType T);
+  QualType BuildPointerType(QualType T, unsigned Quals,
+                            SourceLocation Loc, DeclarationName Entity);
+  QualType BuildReferenceType(QualType T, bool LValueRef, unsigned Quals,
+                              SourceLocation Loc, DeclarationName Entity);
+  QualType BuildArrayType(QualType T, ArrayType::ArraySizeModifier ASM,
+                          Expr *ArraySize, unsigned Quals,
+                          SourceRange Brackets, DeclarationName Entity);
+  QualType BuildExtVectorType(QualType T, ExprArg ArraySize,
+                              SourceLocation AttrLoc);
+  QualType BuildFunctionType(QualType T,
+                             QualType *ParamTypes, unsigned NumParamTypes,
+                             bool Variadic, unsigned Quals,
+                             SourceLocation Loc, DeclarationName Entity);
+  QualType BuildMemberPointerType(QualType T, QualType Class,
+                                  unsigned Quals, SourceLocation Loc,
+                                  DeclarationName Entity);
+  QualType BuildBlockPointerType(QualType T, unsigned Quals,
+                                 SourceLocation Loc, DeclarationName Entity);
+  QualType GetTypeForDeclarator(Declarator &D, Scope *S,
+                                TypeSourceInfo **TInfo = 0,
+                                TagDecl **OwnedDecl = 0);
+  TypeSourceInfo *GetTypeSourceInfoForDeclarator(Declarator &D, QualType T,
+                                               TypeSourceInfo *ReturnTypeInfo);
+  /// \brief Create a LocInfoType to hold the given QualType and TypeSourceInfo.
+  QualType CreateLocInfoType(QualType T, TypeSourceInfo *TInfo);
+  DeclarationName GetNameForDeclarator(Declarator &D);
+  DeclarationName GetNameFromUnqualifiedId(const UnqualifiedId &Name);
+  static QualType GetTypeFromParser(TypeTy *Ty, TypeSourceInfo **TInfo = 0);
+  bool CheckSpecifiedExceptionType(QualType T, const SourceRange &Range);
+  bool CheckDistantExceptionSpec(QualType T);
+  bool CheckEquivalentExceptionSpec(FunctionDecl *Old, FunctionDecl *New);
+  bool CheckEquivalentExceptionSpec(
+      const FunctionProtoType *Old, SourceLocation OldLoc,
+      const FunctionProtoType *New, SourceLocation NewLoc);
+  bool CheckEquivalentExceptionSpec(
+      const PartialDiagnostic &DiagID, const PartialDiagnostic & NoteID,
+      const FunctionProtoType *Old, SourceLocation OldLoc,
+      const FunctionProtoType *New, SourceLocation NewLoc,
+      bool *MissingExceptionSpecification = 0,
+      bool *MissingEmptyExceptionSpecification = 0);
+  bool CheckExceptionSpecSubset(
+      const PartialDiagnostic &DiagID, const PartialDiagnostic & NoteID,
+      const FunctionProtoType *Superset, SourceLocation SuperLoc,
+      const FunctionProtoType *Subset, SourceLocation SubLoc);
+  bool CheckParamExceptionSpec(const PartialDiagnostic & NoteID,
+      const FunctionProtoType *Target, SourceLocation TargetLoc,
+      const FunctionProtoType *Source, SourceLocation SourceLoc);
+
+  bool UnwrapSimilarPointerTypes(QualType& T1, QualType& T2);
+
+  virtual TypeResult ActOnTypeName(Scope *S, Declarator &D);
+
+  bool RequireCompleteType(SourceLocation Loc, QualType T,
+                           const PartialDiagnostic &PD,
+                           std::pair<SourceLocation, PartialDiagnostic> Note);
+  bool RequireCompleteType(SourceLocation Loc, QualType T,
+                           const PartialDiagnostic &PD);
+  bool RequireCompleteType(SourceLocation Loc, QualType T,
+                           unsigned DiagID);
+  
+  QualType getQualifiedNameType(const CXXScopeSpec &SS, QualType T);
+
+  QualType BuildTypeofExprType(Expr *E);
+  QualType BuildDecltypeType(Expr *E);
+
+  //===--------------------------------------------------------------------===//
+  // Symbol table / Decl tracking callbacks: SemaDecl.cpp.
+  //
+
+  /// getDeclName - Return a pretty name for the specified decl if possible, or
+  /// an empty string if not.  This is used for pretty crash reporting.
+  virtual std::string getDeclName(DeclPtrTy D);
+
+  DeclGroupPtrTy ConvertDeclToDeclGroup(DeclPtrTy Ptr);
+
+  virtual TypeTy *getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
+                              Scope *S, CXXScopeSpec *SS,
+                              bool isClassName = false,
+                              TypeTy *ObjectType = 0);
+  virtual DeclSpec::TST isTagName(IdentifierInfo &II, Scope *S);
+  virtual bool DiagnoseUnknownTypeName(const IdentifierInfo &II, 
+                                       SourceLocation IILoc,
+                                       Scope *S,
+                                       CXXScopeSpec *SS,
+                                       TypeTy *&SuggestedType);
+  
+  virtual DeclPtrTy ActOnDeclarator(Scope *S, Declarator &D) {
+    return HandleDeclarator(S, D, MultiTemplateParamsArg(*this), false);
+  }
+
+  DeclPtrTy HandleDeclarator(Scope *S, Declarator &D,
+                             MultiTemplateParamsArg TemplateParameterLists,
+                             bool IsFunctionDefinition);
+  void RegisterLocallyScopedExternCDecl(NamedDecl *ND,
+                                        const LookupResult &Previous,
+                                        Scope *S);
+  void DiagnoseFunctionSpecifiers(Declarator& D);
+  void CheckShadow(Scope *S, VarDecl *D, const LookupResult& R);
+  void CheckShadow(Scope *S, VarDecl *D);
+  NamedDecl* ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC,
+                                    QualType R, TypeSourceInfo *TInfo,
+                                    LookupResult &Previous, bool &Redeclaration);
+  NamedDecl* ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
+                                     QualType R, TypeSourceInfo *TInfo,
+                                     LookupResult &Previous,
+                                     MultiTemplateParamsArg TemplateParamLists,
+                                     bool &Redeclaration);
+  void CheckVariableDeclaration(VarDecl *NewVD, LookupResult &Previous,
+                                bool &Redeclaration);
+  NamedDecl* ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
+                                     QualType R, TypeSourceInfo *TInfo,
+                                     LookupResult &Previous,
+                                     MultiTemplateParamsArg TemplateParamLists,
+                                     bool IsFunctionDefinition,
+                                     bool &Redeclaration);
+  void AddOverriddenMethods(CXXRecordDecl *DC, CXXMethodDecl *MD);
+  void CheckFunctionDeclaration(Scope *S,
+                                FunctionDecl *NewFD, LookupResult &Previous,
+                                bool IsExplicitSpecialization,
+                                bool &Redeclaration,
+                                bool &OverloadableAttrRequired);
+  void CheckMain(FunctionDecl *FD);
+  virtual DeclPtrTy ActOnParamDeclarator(Scope *S, Declarator &D);
+  ParmVarDecl *CheckParameter(DeclContext *DC, 
+                              TypeSourceInfo *TSInfo, QualType T,
+                              IdentifierInfo *Name,
+                              SourceLocation NameLoc,
+                              VarDecl::StorageClass StorageClass,
+                              VarDecl::StorageClass StorageClassAsWritten);
+  virtual void ActOnParamDefaultArgument(DeclPtrTy param,
+                                         SourceLocation EqualLoc,
+                                         ExprArg defarg);
+  virtual void ActOnParamUnparsedDefaultArgument(DeclPtrTy param,
+                                                 SourceLocation EqualLoc,
+                                                 SourceLocation ArgLoc);
+  virtual void ActOnParamDefaultArgumentError(DeclPtrTy param);
+  bool SetParamDefaultArgument(ParmVarDecl *Param, ExprArg DefaultArg,
+                               SourceLocation EqualLoc);
+
+
+  // Contains the locations of the beginning of unparsed default
+  // argument locations.
+  llvm::DenseMap<ParmVarDecl *,SourceLocation> UnparsedDefaultArgLocs;
+
+  virtual void AddInitializerToDecl(DeclPtrTy dcl, ExprArg init);
+  void AddInitializerToDecl(DeclPtrTy dcl, ExprArg init, bool DirectInit);
+  void ActOnUninitializedDecl(DeclPtrTy dcl, bool TypeContainsUndeducedAuto);
+  virtual void ActOnInitializerError(DeclPtrTy Dcl);
+  virtual void SetDeclDeleted(DeclPtrTy dcl, SourceLocation DelLoc);
+  virtual DeclGroupPtrTy FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS,
+                                                 DeclPtrTy *Group,
+                                                 unsigned NumDecls);
+  virtual void ActOnFinishKNRParamDeclarations(Scope *S, Declarator &D,
+                                               SourceLocation LocAfterDecls);
+  virtual DeclPtrTy ActOnStartOfFunctionDef(Scope *S, Declarator &D);
+  virtual DeclPtrTy ActOnStartOfFunctionDef(Scope *S, DeclPtrTy D);
+  virtual void ActOnStartOfObjCMethodDef(Scope *S, DeclPtrTy D);
+
+  virtual DeclPtrTy ActOnFinishFunctionBody(DeclPtrTy Decl, StmtArg Body);
+  DeclPtrTy ActOnFinishFunctionBody(DeclPtrTy Decl, StmtArg Body,
+                                    bool IsInstantiation);
+
+  /// \brief Diagnose any unused parameters in the given sequence of
+  /// ParmVarDecl pointers.
+  template<typename InputIterator>
+  void DiagnoseUnusedParameters(InputIterator Param, InputIterator ParamEnd) {
+    if (Diags.getDiagnosticLevel(diag::warn_unused_parameter) == 
+          Diagnostic::Ignored)
+      return;
+
+    // Don't diagnose unused-parameter errors in template instantiations; we
+    // will already have done so in the template itself.
+    if (!ActiveTemplateInstantiations.empty())
+      return;
+    
+    for (; Param != ParamEnd; ++Param) {
+      if (!(*Param)->isUsed() && (*Param)->getDeclName() &&
+          !(*Param)->template hasAttr<UnusedAttr>()) {
+        Diag((*Param)->getLocation(), diag::warn_unused_parameter)
+          << (*Param)->getDeclName();
+      }
+    }
+  }
+
+  void DiagnoseInvalidJumps(Stmt *Body);
+  virtual DeclPtrTy ActOnFileScopeAsmDecl(SourceLocation Loc, ExprArg expr);
+
+  /// Scope actions.
+  virtual void ActOnPopScope(SourceLocation Loc, Scope *S);
+  virtual void ActOnTranslationUnitScope(SourceLocation Loc, Scope *S);
+
+  /// ParsedFreeStandingDeclSpec - This method is invoked when a declspec with
+  /// no declarator (e.g. "struct foo;") is parsed.
+  virtual DeclPtrTy ParsedFreeStandingDeclSpec(Scope *S, DeclSpec &DS);
+
+  bool InjectAnonymousStructOrUnionMembers(Scope *S, DeclContext *Owner,
+                                           RecordDecl *AnonRecord);
+  virtual DeclPtrTy BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
+                                                RecordDecl *Record);
+
+  bool isAcceptableTagRedeclaration(const TagDecl *Previous,
+                                    TagDecl::TagKind NewTag,
+                                    SourceLocation NewTagLoc,
+                                    const IdentifierInfo &Name);
+
+  virtual DeclPtrTy ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
+                             SourceLocation KWLoc, CXXScopeSpec &SS,
+                             IdentifierInfo *Name, SourceLocation NameLoc,
+                             AttributeList *Attr, AccessSpecifier AS,
+                             MultiTemplateParamsArg TemplateParameterLists,
+                             bool &OwnedDecl, bool &IsDependent);
+
+  virtual TypeResult ActOnDependentTag(Scope *S,
+                                       unsigned TagSpec,
+                                       TagUseKind TUK,
+                                       const CXXScopeSpec &SS,
+                                       IdentifierInfo *Name,
+                                       SourceLocation TagLoc,
+                                       SourceLocation NameLoc);
+
+  virtual void ActOnDefs(Scope *S, DeclPtrTy TagD, SourceLocation DeclStart,
+                         IdentifierInfo *ClassName,
+                         llvm::SmallVectorImpl<DeclPtrTy> &Decls);
+  virtual DeclPtrTy ActOnField(Scope *S, DeclPtrTy TagD,
+                               SourceLocation DeclStart,
+                               Declarator &D, ExprTy *BitfieldWidth);
+
+  FieldDecl *HandleField(Scope *S, RecordDecl *TagD, SourceLocation DeclStart,
+                         Declarator &D, Expr *BitfieldWidth,
+                         AccessSpecifier AS);
+
+  FieldDecl *CheckFieldDecl(DeclarationName Name, QualType T,
+                            TypeSourceInfo *TInfo,
+                            RecordDecl *Record, SourceLocation Loc,
+                            bool Mutable, Expr *BitfieldWidth,
+                            SourceLocation TSSL,
+                            AccessSpecifier AS, NamedDecl *PrevDecl,
+                            Declarator *D = 0);
+
+  enum CXXSpecialMember {
+    CXXInvalid = -1,
+    CXXConstructor = 0,
+    CXXCopyConstructor = 1,
+    CXXCopyAssignment = 2,
+    CXXDestructor = 3
+  };
+  void DiagnoseNontrivial(const RecordType* Record, CXXSpecialMember mem);
+  CXXSpecialMember getSpecialMember(const CXXMethodDecl *MD);
+
+  virtual DeclPtrTy ActOnIvar(Scope *S, SourceLocation DeclStart,
+                              DeclPtrTy IntfDecl,
+                              Declarator &D, ExprTy *BitfieldWidth,
+                              tok::ObjCKeywordKind visibility);
+
+  // This is used for both record definitions and ObjC interface declarations.
+  virtual void ActOnFields(Scope* S,
+                           SourceLocation RecLoc, DeclPtrTy TagDecl,
+                           DeclPtrTy *Fields, unsigned NumFields,
+                           SourceLocation LBrac, SourceLocation RBrac,
+                           AttributeList *AttrList);
+
+  /// ActOnTagStartDefinition - Invoked when we have entered the
+  /// scope of a tag's definition (e.g., for an enumeration, class,
+  /// struct, or union).
+  virtual void ActOnTagStartDefinition(Scope *S, DeclPtrTy TagDecl);
+
+  /// ActOnStartCXXMemberDeclarations - Invoked when we have parsed a
+  /// C++ record definition's base-specifiers clause and are starting its
+  /// member declarations.
+  virtual void ActOnStartCXXMemberDeclarations(Scope *S, DeclPtrTy TagDecl,
+                                               SourceLocation LBraceLoc);
+
+  /// ActOnTagFinishDefinition - Invoked once we have finished parsing
+  /// the definition of a tag (enumeration, class, struct, or union).
+  virtual void ActOnTagFinishDefinition(Scope *S, DeclPtrTy TagDecl,
+                                        SourceLocation RBraceLoc);
+
+  /// ActOnTagDefinitionError - Invoked when there was an unrecoverable
+  /// error parsing the definition of a tag.
+  virtual void ActOnTagDefinitionError(Scope *S, DeclPtrTy TagDecl);
+
+  EnumConstantDecl *CheckEnumConstant(EnumDecl *Enum,
+                                      EnumConstantDecl *LastEnumConst,
+                                      SourceLocation IdLoc,
+                                      IdentifierInfo *Id,
+                                      ExprArg val);
+
+  virtual DeclPtrTy ActOnEnumConstant(Scope *S, DeclPtrTy EnumDecl,
+                                      DeclPtrTy LastEnumConstant,
+                                      SourceLocation IdLoc, IdentifierInfo *Id,
+                                      SourceLocation EqualLoc, ExprTy *Val);
+  virtual void ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc,
+                             SourceLocation RBraceLoc, DeclPtrTy EnumDecl,
+                             DeclPtrTy *Elements, unsigned NumElements,
+                             Scope *S, AttributeList *Attr);
+
+  DeclContext *getContainingDC(DeclContext *DC);
+
+  /// Set the current declaration context until it gets popped.
+  void PushDeclContext(Scope *S, DeclContext *DC);
+  void PopDeclContext();
+
+  /// EnterDeclaratorContext - Used when we must lookup names in the context
+  /// of a declarator's nested name specifier.
+  void EnterDeclaratorContext(Scope *S, DeclContext *DC);
+  void ExitDeclaratorContext(Scope *S);
+
+  DeclContext *getFunctionLevelDeclContext();
+
+  /// getCurFunctionDecl - If inside of a function body, this returns a pointer
+  /// to the function decl for the function being parsed.  If we're currently
+  /// in a 'block', this returns the containing context.
+  FunctionDecl *getCurFunctionDecl();
+
+  /// getCurMethodDecl - If inside of a method body, this returns a pointer to
+  /// the method decl for the method being parsed.  If we're currently
+  /// in a 'block', this returns the containing context.
+  ObjCMethodDecl *getCurMethodDecl();
+
+  /// getCurFunctionOrMethodDecl - Return the Decl for the current ObjC method
+  /// or C function we're in, otherwise return null.  If we're currently
+  /// in a 'block', this returns the containing context.
+  NamedDecl *getCurFunctionOrMethodDecl();
+
+  /// Add this decl to the scope shadowed decl chains.
+  void PushOnScopeChains(NamedDecl *D, Scope *S, bool AddToContext = true);
+
+  /// isDeclInScope - If 'Ctx' is a function/method, isDeclInScope returns true
+  /// if 'D' is in Scope 'S', otherwise 'S' is ignored and isDeclInScope returns
+  /// true if 'D' belongs to the given declaration context.
+  bool isDeclInScope(NamedDecl *&D, DeclContext *Ctx, Scope *S = 0);
+
+  /// Finds the scope corresponding to the given decl context, if it
+  /// happens to be an enclosing scope.  Otherwise return NULL.
+  Scope *getScopeForDeclContext(Scope *S, DeclContext *DC) {
+    DeclContext *TargetDC = DC->getPrimaryContext();
+    do {
+      if (DeclContext *ScopeDC = (DeclContext*) S->getEntity())
+        if (ScopeDC->getPrimaryContext() == TargetDC)
+          return S;
+    } while ((S = S->getParent()));
+
+    return NULL;
+  }
+
+  /// Subroutines of ActOnDeclarator().
+  TypedefDecl *ParseTypedefDecl(Scope *S, Declarator &D, QualType T,
+                                TypeSourceInfo *TInfo);
+  void MergeTypeDefDecl(TypedefDecl *New, LookupResult &OldDecls);
+  bool MergeFunctionDecl(FunctionDecl *New, Decl *Old);
+  bool MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old);
+  void MergeVarDecl(VarDecl *New, LookupResult &OldDecls);
+  bool MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old);
+
+  // AssignmentAction - This is used by all the assignment diagnostic functions
+  // to represent what is actually causing the operation
+  enum AssignmentAction {
+    AA_Assigning,
+    AA_Passing,
+    AA_Returning,
+    AA_Converting,
+    AA_Initializing,
+    AA_Sending,
+    AA_Casting
+  };
+  
+  /// C++ Overloading.
+  enum OverloadKind {
+    /// This is a legitimate overload: the existing declarations are
+    /// functions or function templates with different signatures.
+    Ovl_Overload,
+
+    /// This is not an overload because the signature exactly matches
+    /// an existing declaration.
+    Ovl_Match,
+
+    /// This is not an overload because the lookup results contain a
+    /// non-function.
+    Ovl_NonFunction
+  };
+  OverloadKind CheckOverload(FunctionDecl *New,
+                             const LookupResult &OldDecls,
+                             NamedDecl *&OldDecl);
+  bool IsOverload(FunctionDecl *New, FunctionDecl *Old);
+
+  ImplicitConversionSequence
+  TryImplicitConversion(Expr* From, QualType ToType,
+                        bool SuppressUserConversions,
+                        bool AllowExplicit,
+                        bool InOverloadResolution);
+  bool IsStandardConversion(Expr *From, QualType ToType,
+                            bool InOverloadResolution,
+                            StandardConversionSequence& SCS);
+  bool IsIntegralPromotion(Expr *From, QualType FromType, QualType ToType);
+  bool IsFloatingPointPromotion(QualType FromType, QualType ToType);
+  bool IsComplexPromotion(QualType FromType, QualType ToType);
+  bool IsPointerConversion(Expr *From, QualType FromType, QualType ToType,
+                           bool InOverloadResolution,
+                           QualType& ConvertedType, bool &IncompatibleObjC);
+  bool isObjCPointerConversion(QualType FromType, QualType ToType,
+                               QualType& ConvertedType, bool &IncompatibleObjC);
+  bool CheckPointerConversion(Expr *From, QualType ToType,
+                              CastExpr::CastKind &Kind,
+                              CXXBaseSpecifierArray& BasePath,
+                              bool IgnoreBaseAccess);
+  bool IsMemberPointerConversion(Expr *From, QualType FromType, QualType ToType,
+                                 bool InOverloadResolution,
+                                 QualType &ConvertedType);
+  bool CheckMemberPointerConversion(Expr *From, QualType ToType,
+                                    CastExpr::CastKind &Kind,
+                                    CXXBaseSpecifierArray &BasePath,
+                                    bool IgnoreBaseAccess);
+  bool IsQualificationConversion(QualType FromType, QualType ToType);
+  OverloadingResult IsUserDefinedConversion(Expr *From, QualType ToType,
+                               UserDefinedConversionSequence& User,
+                               OverloadCandidateSet& Conversions,
+                               bool AllowExplicit);
+  bool DiagnoseMultipleUserDefinedConversion(Expr *From, QualType ToType);
+                                              
+
+  ImplicitConversionSequence::CompareKind
+  CompareImplicitConversionSequences(const ImplicitConversionSequence& ICS1,
+                                     const ImplicitConversionSequence& ICS2);
+
+  ImplicitConversionSequence::CompareKind
+  CompareStandardConversionSequences(const StandardConversionSequence& SCS1,
+                                     const StandardConversionSequence& SCS2);
+
+  ImplicitConversionSequence::CompareKind
+  CompareQualificationConversions(const StandardConversionSequence& SCS1,
+                                  const StandardConversionSequence& SCS2);
+
+  ImplicitConversionSequence::CompareKind
+  CompareDerivedToBaseConversions(const StandardConversionSequence& SCS1,
+                                  const StandardConversionSequence& SCS2);
+
+  OwningExprResult PerformCopyInitialization(const InitializedEntity &Entity,
+                                             SourceLocation EqualLoc,
+                                             OwningExprResult Init);
+  ImplicitConversionSequence
+  TryObjectArgumentInitialization(QualType FromType, CXXMethodDecl *Method,
+                                  CXXRecordDecl *ActingContext);
+  bool PerformObjectArgumentInitialization(Expr *&From, 
+                                           NestedNameSpecifier *Qualifier,
+                                           NamedDecl *FoundDecl,
+                                           CXXMethodDecl *Method);
+
+  ImplicitConversionSequence TryContextuallyConvertToBool(Expr *From);
+  bool PerformContextuallyConvertToBool(Expr *&From);
+
+  bool PerformObjectMemberConversion(Expr *&From, 
+                                     NestedNameSpecifier *Qualifier,
+                                     NamedDecl *FoundDecl,
+                                     NamedDecl *Member);
+
+  // Members have to be NamespaceDecl* or TranslationUnitDecl*.
+  // TODO: make this is a typesafe union.
+  typedef llvm::SmallPtrSet<DeclContext   *, 16> AssociatedNamespaceSet;
+  typedef llvm::SmallPtrSet<CXXRecordDecl *, 16> AssociatedClassSet;
+
+  void AddOverloadCandidate(NamedDecl *Function,
+                            DeclAccessPair FoundDecl,
+                            Expr **Args, unsigned NumArgs,
+                            OverloadCandidateSet &CandidateSet);
+
+  void AddOverloadCandidate(FunctionDecl *Function,
+                            DeclAccessPair FoundDecl,
+                            Expr **Args, unsigned NumArgs,
+                            OverloadCandidateSet& CandidateSet,
+                            bool SuppressUserConversions = false,
+                            bool PartialOverloading = false);
+  void AddFunctionCandidates(const UnresolvedSetImpl &Functions,
+                             Expr **Args, unsigned NumArgs,
+                             OverloadCandidateSet& CandidateSet,
+                             bool SuppressUserConversions = false);
+  void AddMethodCandidate(DeclAccessPair FoundDecl,
+                          QualType ObjectType,
+                          Expr **Args, unsigned NumArgs,
+                          OverloadCandidateSet& CandidateSet,
+                          bool SuppressUserConversion = false);
+  void AddMethodCandidate(CXXMethodDecl *Method,
+                          DeclAccessPair FoundDecl,
+                          CXXRecordDecl *ActingContext, QualType ObjectType,
+                          Expr **Args, unsigned NumArgs,
+                          OverloadCandidateSet& CandidateSet,
+                          bool SuppressUserConversions = false);
+  void AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl,
+                                  DeclAccessPair FoundDecl,
+                                  CXXRecordDecl *ActingContext,
+                         const TemplateArgumentListInfo *ExplicitTemplateArgs,
+                                  QualType ObjectType,
+                                  Expr **Args, unsigned NumArgs,
+                                  OverloadCandidateSet& CandidateSet,
+                                  bool SuppressUserConversions = false);
+  void AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate,
+                                    DeclAccessPair FoundDecl,
+                      const TemplateArgumentListInfo *ExplicitTemplateArgs,
+                                    Expr **Args, unsigned NumArgs,
+                                    OverloadCandidateSet& CandidateSet,
+                                    bool SuppressUserConversions = false);
+  void AddConversionCandidate(CXXConversionDecl *Conversion,
+                              DeclAccessPair FoundDecl,
+                              CXXRecordDecl *ActingContext,
+                              Expr *From, QualType ToType,
+                              OverloadCandidateSet& CandidateSet);
+  void AddTemplateConversionCandidate(FunctionTemplateDecl *FunctionTemplate,
+                                      DeclAccessPair FoundDecl,
+                                      CXXRecordDecl *ActingContext,
+                                      Expr *From, QualType ToType,
+                                      OverloadCandidateSet &CandidateSet);
+  void AddSurrogateCandidate(CXXConversionDecl *Conversion,
+                             DeclAccessPair FoundDecl,
+                             CXXRecordDecl *ActingContext,
+                             const FunctionProtoType *Proto,
+                             QualType ObjectTy, Expr **Args, unsigned NumArgs,
+                             OverloadCandidateSet& CandidateSet);
+  void AddMemberOperatorCandidates(OverloadedOperatorKind Op,
+                                   SourceLocation OpLoc,
+                                   Expr **Args, unsigned NumArgs,
+                                   OverloadCandidateSet& CandidateSet,
+                                   SourceRange OpRange = SourceRange());
+  void AddBuiltinCandidate(QualType ResultTy, QualType *ParamTys,
+                           Expr **Args, unsigned NumArgs,
+                           OverloadCandidateSet& CandidateSet,
+                           bool IsAssignmentOperator = false,
+                           unsigned NumContextualBoolArguments = 0);
+  void AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
+                                    SourceLocation OpLoc,
+                                    Expr **Args, unsigned NumArgs,
+                                    OverloadCandidateSet& CandidateSet);
+  void AddArgumentDependentLookupCandidates(DeclarationName Name,
+                                            bool Operator,
+                                            Expr **Args, unsigned NumArgs,
+                        const TemplateArgumentListInfo *ExplicitTemplateArgs,
+                                            OverloadCandidateSet& CandidateSet,
+                                            bool PartialOverloading = false);
+  bool isBetterOverloadCandidate(const OverloadCandidate& Cand1,
+                                 const OverloadCandidate& Cand2,
+                                 SourceLocation Loc);
+  OverloadingResult BestViableFunction(OverloadCandidateSet& CandidateSet,
+                                       SourceLocation Loc,
+                                       OverloadCandidateSet::iterator& Best);
+
+  enum OverloadCandidateDisplayKind {
+    /// Requests that all candidates be shown.  Viable candidates will
+    /// be printed first.
+    OCD_AllCandidates,
+
+    /// Requests that only viable candidates be shown.
+    OCD_ViableCandidates
+  };
+  void PrintOverloadCandidates(OverloadCandidateSet& CandidateSet,
+                               OverloadCandidateDisplayKind OCD,
+                               Expr **Args, unsigned NumArgs,
+                               const char *Opc = 0,
+                               SourceLocation Loc = SourceLocation());
+
+  void NoteOverloadCandidate(FunctionDecl *Fn);
+  void DiagnoseAmbiguousConversion(const ImplicitConversionSequence &ICS,
+                                   SourceLocation CaretLoc,
+                                   const PartialDiagnostic &PDiag);
+
+  FunctionDecl *ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
+                                                   bool Complain,
+                                                   DeclAccessPair &Found);
+  FunctionDecl *ResolveSingleFunctionTemplateSpecialization(Expr *From);
+
+  Expr *FixOverloadedFunctionReference(Expr *E,
+                                       DeclAccessPair FoundDecl,
+                                       FunctionDecl *Fn);
+  OwningExprResult FixOverloadedFunctionReference(OwningExprResult, 
+                                                  DeclAccessPair FoundDecl,
+                                                  FunctionDecl *Fn);
+
+  void AddOverloadedCallCandidates(UnresolvedLookupExpr *ULE,
+                                   Expr **Args, unsigned NumArgs,
+                                   OverloadCandidateSet &CandidateSet,
+                                   bool PartialOverloading = false);
+    
+  OwningExprResult BuildOverloadedCallExpr(Scope *S, Expr *Fn,
+                                           UnresolvedLookupExpr *ULE,
+                                           SourceLocation LParenLoc,
+                                           Expr **Args, unsigned NumArgs,
+                                           SourceLocation *CommaLocs,
+                                           SourceLocation RParenLoc);
+
+  OwningExprResult CreateOverloadedUnaryOp(SourceLocation OpLoc,
+                                           unsigned Opc,
+                                           const UnresolvedSetImpl &Fns,
+                                           ExprArg input);
+
+  OwningExprResult CreateOverloadedBinOp(SourceLocation OpLoc,
+                                         unsigned Opc,
+                                         const UnresolvedSetImpl &Fns,
+                                         Expr *LHS, Expr *RHS);
+
+  OwningExprResult CreateOverloadedArraySubscriptExpr(SourceLocation LLoc,
+                                                      SourceLocation RLoc,
+                                                      ExprArg Base,ExprArg Idx);
+
+  OwningExprResult
+  BuildCallToMemberFunction(Scope *S, Expr *MemExpr,
+                            SourceLocation LParenLoc, Expr **Args,
+                            unsigned NumArgs, SourceLocation *CommaLocs,
+                            SourceLocation RParenLoc);
+  ExprResult
+  BuildCallToObjectOfClassType(Scope *S, Expr *Object, SourceLocation LParenLoc,
+                               Expr **Args, unsigned NumArgs,
+                               SourceLocation *CommaLocs,
+                               SourceLocation RParenLoc);
+
+  OwningExprResult BuildOverloadedArrowExpr(Scope *S, ExprArg Base,
+                                            SourceLocation OpLoc);
+
+  /// CheckCallReturnType - Checks that a call expression's return type is
+  /// complete. Returns true on failure. The location passed in is the location
+  /// that best represents the call.
+  bool CheckCallReturnType(QualType ReturnType, SourceLocation Loc,
+                           CallExpr *CE, FunctionDecl *FD);
+                           
+  /// Helpers for dealing with blocks and functions.
+  bool CheckParmsForFunctionDef(FunctionDecl *FD);
+  void CheckCXXDefaultArguments(FunctionDecl *FD);
+  void CheckExtraCXXDefaultArguments(Declarator &D);
+  Scope *getNonFieldDeclScope(Scope *S);
+
+  /// \name Name lookup
+  ///
+  /// These routines provide name lookup that is used during semantic
+  /// analysis to resolve the various kinds of names (identifiers,
+  /// overloaded operator names, constructor names, etc.) into zero or
+  /// more declarations within a particular scope. The major entry
+  /// points are LookupName, which performs unqualified name lookup,
+  /// and LookupQualifiedName, which performs qualified name lookup.
+  ///
+  /// All name lookup is performed based on some specific criteria,
+  /// which specify what names will be visible to name lookup and how
+  /// far name lookup should work. These criteria are important both
+  /// for capturing language semantics (certain lookups will ignore
+  /// certain names, for example) and for performance, since name
+  /// lookup is often a bottleneck in the compilation of C++. Name
+  /// lookup criteria is specified via the LookupCriteria enumeration.
+  ///
+  /// The results of name lookup can vary based on the kind of name
+  /// lookup performed, the current language, and the translation
+  /// unit. In C, for example, name lookup will either return nothing
+  /// (no entity found) or a single declaration. In C++, name lookup
+  /// can additionally refer to a set of overloaded functions or
+  /// result in an ambiguity. All of the possible results of name
+  /// lookup are captured by the LookupResult class, which provides
+  /// the ability to distinguish among them.
+  //@{
+
+  /// @brief Describes the kind of name lookup to perform.
+  enum LookupNameKind {
+    /// Ordinary name lookup, which finds ordinary names (functions,
+    /// variables, typedefs, etc.) in C and most kinds of names
+    /// (functions, variables, members, types, etc.) in C++.
+    LookupOrdinaryName = 0,
+    /// Tag name lookup, which finds the names of enums, classes,
+    /// structs, and unions.
+    LookupTagName,
+    /// Member name lookup, which finds the names of
+    /// class/struct/union members.
+    LookupMemberName,
+    // Look up of an operator name (e.g., operator+) for use with
+    // operator overloading. This lookup is similar to ordinary name
+    // lookup, but will ignore any declarations that are class
+    // members.
+    LookupOperatorName,
+    /// Look up of a name that precedes the '::' scope resolution
+    /// operator in C++. This lookup completely ignores operator, object,
+    /// function, and enumerator names (C++ [basic.lookup.qual]p1).
+    LookupNestedNameSpecifierName,
+    /// Look up a namespace name within a C++ using directive or
+    /// namespace alias definition, ignoring non-namespace names (C++
+    /// [basic.lookup.udir]p1).
+    LookupNamespaceName,
+    /// Look up all declarations in a scope with the given name,
+    /// including resolved using declarations.  This is appropriate
+    /// for checking redeclarations for a using declaration.
+    LookupUsingDeclName,
+    /// Look up an ordinary name that is going to be redeclared as a
+    /// name with linkage. This lookup ignores any declarations that
+    /// are outside of the current scope unless they have linkage. See
+    /// C99 6.2.2p4-5 and C++ [basic.link]p6.
+    LookupRedeclarationWithLinkage,
+    /// Look up the name of an Objective-C protocol.
+    LookupObjCProtocolName
+  };
+
+  /// \brief Specifies whether (or how) name lookup is being performed for a
+  /// redeclaration (vs. a reference).
+  enum RedeclarationKind {
+    /// \brief The lookup is a reference to this name that is not for the
+    /// purpose of redeclaring the name.
+    NotForRedeclaration = 0,
+    /// \brief The lookup results will be used for redeclaration of a name,
+    /// if an entity by that name already exists.
+    ForRedeclaration
+  };
+
+private:
+  bool CppLookupName(LookupResult &R, Scope *S);
+
+public:
+  /// \brief Look up a name, looking for a single declaration.  Return
+  /// null if the results were absent, ambiguous, or overloaded.
+  ///
+  /// It is preferable to use the elaborated form and explicitly handle
+  /// ambiguity and overloaded.
+  NamedDecl *LookupSingleName(Scope *S, DeclarationName Name,
+                              SourceLocation Loc,
+                              LookupNameKind NameKind,
+                              RedeclarationKind Redecl
+                                = NotForRedeclaration);
+  bool LookupName(LookupResult &R, Scope *S,
+                  bool AllowBuiltinCreation = false);
+  bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx,
+                           bool InUnqualifiedLookup = false);
+  bool LookupParsedName(LookupResult &R, Scope *S, CXXScopeSpec *SS,
+                        bool AllowBuiltinCreation = false,
+                        bool EnteringContext = false);
+  ObjCProtocolDecl *LookupProtocol(IdentifierInfo *II, SourceLocation IdLoc);
+
+  void LookupOverloadedOperatorName(OverloadedOperatorKind Op, Scope *S,
+                                    QualType T1, QualType T2,
+                                    UnresolvedSetImpl &Functions);
+  
+  void ArgumentDependentLookup(DeclarationName Name, bool Operator,
+                               Expr **Args, unsigned NumArgs,
+                               ADLResult &Functions);
+
+  void LookupVisibleDecls(Scope *S, LookupNameKind Kind,
+                          VisibleDeclConsumer &Consumer);
+  void LookupVisibleDecls(DeclContext *Ctx, LookupNameKind Kind,
+                          VisibleDeclConsumer &Consumer);
+
+  /// \brief The context in which typo-correction occurs.
+  ///
+  /// The typo-correction context affects which keywords (if any) are 
+  /// considered when trying to correct for typos.
+  enum CorrectTypoContext {
+    /// \brief An unknown context, where any keyword might be valid.
+    CTC_Unknown,
+    /// \brief A context where no keywords are used (e.g. we expect an actual
+    /// name).
+    CTC_NoKeywords,
+    /// \brief A context where we're correcting a type name.
+    CTC_Type,
+    /// \brief An expression context.
+    CTC_Expression,
+    /// \brief A type cast, or anything else that can be followed by a '<'. 
+    CTC_CXXCasts,
+    /// \brief A member lookup context.
+    CTC_MemberLookup,
+    /// \brief The receiver of an Objective-C message send within an 
+    /// Objective-C method where 'super' is a valid keyword.
+    CTC_ObjCMessageReceiver
+  };
+  
+  DeclarationName CorrectTypo(LookupResult &R, Scope *S, CXXScopeSpec *SS,
+                              DeclContext *MemberContext = 0,
+                              bool EnteringContext = false,
+                              CorrectTypoContext CTC = CTC_Unknown,
+                              const ObjCObjectPointerType *OPT = 0);
+
+  void FindAssociatedClassesAndNamespaces(Expr **Args, unsigned NumArgs,
+                                   AssociatedNamespaceSet &AssociatedNamespaces,
+                                   AssociatedClassSet &AssociatedClasses);
+
+  bool DiagnoseAmbiguousLookup(LookupResult &Result);
+  //@}
+
+  ObjCInterfaceDecl *getObjCInterfaceDecl(IdentifierInfo *&Id,
+                                          SourceLocation IdLoc,
+                                          bool TypoCorrection = false);
+  NamedDecl *LazilyCreateBuiltin(IdentifierInfo *II, unsigned ID,
+                                 Scope *S, bool ForRedeclaration,
+                                 SourceLocation Loc);
+  NamedDecl *ImplicitlyDefineFunction(SourceLocation Loc, IdentifierInfo &II,
+                                      Scope *S);
+  void AddKnownFunctionAttributes(FunctionDecl *FD);
+
+  // More parsing and symbol table subroutines.
+
+  // Decl attributes - this routine is the top level dispatcher.
+  void ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD);
+  void ProcessDeclAttributeList(Scope *S, Decl *D, const AttributeList *AttrList);
+
+  void WarnUndefinedMethod(SourceLocation ImpLoc, ObjCMethodDecl *method,
+                           bool &IncompleteImpl, unsigned DiagID);
+  void WarnConflictingTypedMethods(ObjCMethodDecl *ImpMethod,
+                                   ObjCMethodDecl *IntfMethod);
+
+  bool isPropertyReadonly(ObjCPropertyDecl *PropertyDecl,
+                          ObjCInterfaceDecl *IDecl);
+
+  /// CheckProtocolMethodDefs - This routine checks unimplemented
+  /// methods declared in protocol, and those referenced by it.
+  /// \param IDecl - Used for checking for methods which may have been
+  /// inherited.
+  void CheckProtocolMethodDefs(SourceLocation ImpLoc,
+                               ObjCProtocolDecl *PDecl,
+                               bool& IncompleteImpl,
+                               const llvm::DenseSet<Selector> &InsMap,
+                               const llvm::DenseSet<Selector> &ClsMap,
+                               ObjCContainerDecl *CDecl);
+
+  /// CheckImplementationIvars - This routine checks if the instance variables
+  /// listed in the implelementation match those listed in the interface.
+  void CheckImplementationIvars(ObjCImplementationDecl *ImpDecl,
+                                ObjCIvarDecl **Fields, unsigned nIvars,
+                                SourceLocation Loc);
+
+  /// ImplMethodsVsClassMethods - This is main routine to warn if any method
+  /// remains unimplemented in the class or category @implementation.
+  void ImplMethodsVsClassMethods(ObjCImplDecl* IMPDecl,
+                                 ObjCContainerDecl* IDecl,
+                                 bool IncompleteImpl = false);
+  
+  /// DiagnoseUnimplementedProperties - This routine warns on those properties
+  /// which must be implemented by this implementation.
+  void DiagnoseUnimplementedProperties(ObjCImplDecl* IMPDecl,
+                                       ObjCContainerDecl *CDecl,
+                                       const llvm::DenseSet<Selector>& InsMap);
+
+  /// CollectImmediateProperties - This routine collects all properties in
+  /// the class and its conforming protocols; but not those it its super class.
+  void CollectImmediateProperties(ObjCContainerDecl *CDecl,
+                  llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>& PropMap);
+  
+  /// LookupPropertyDecl - Looks up a property in the current class and all
+  /// its protocols.
+  ObjCPropertyDecl *LookupPropertyDecl(const ObjCContainerDecl *CDecl, 
+                                       IdentifierInfo *II);
+  
+  /// Called by ActOnProperty to handle @property declarations in
+  ////  class extensions.
+  DeclPtrTy HandlePropertyInClassExtension(Scope *S,
+                                           ObjCCategoryDecl *CDecl,
+                                           SourceLocation AtLoc,
+                                           FieldDeclarator &FD,
+                                           Selector GetterSel,
+                                           Selector SetterSel,
+                                           const bool isAssign,
+                                           const bool isReadWrite,
+                                           const unsigned Attributes,
+                                           bool *isOverridingProperty,
+                                           QualType T,
+                                           tok::ObjCKeywordKind MethodImplKind);
+
+  /// Called by ActOnProperty and HandlePropertyInClassExtension to
+  ///  handle creating the ObjcPropertyDecl for a category or @interface.
+  ObjCPropertyDecl *CreatePropertyDecl(Scope *S,
+                                       ObjCContainerDecl *CDecl,
+                                       SourceLocation AtLoc,
+                                       FieldDeclarator &FD,
+                                       Selector GetterSel,
+                                       Selector SetterSel,
+                                       const bool isAssign,
+                                       const bool isReadWrite,
+                                       const unsigned Attributes, QualType T,
+                                       tok::ObjCKeywordKind MethodImplKind);
+
+  /// AtomicPropertySetterGetterRules - This routine enforces the rule (via
+  /// warning) when atomic property has one but not the other user-declared
+  /// setter or getter.
+  void AtomicPropertySetterGetterRules(ObjCImplDecl* IMPDecl,
+                                       ObjCContainerDecl* IDecl);
+
+  void DiagnoseDuplicateIvars(ObjCInterfaceDecl *ID, ObjCInterfaceDecl *SID);
+
+  /// MatchTwoMethodDeclarations - Checks if two methods' type match and returns
+  /// true, or false, accordingly.
+  bool MatchTwoMethodDeclarations(const ObjCMethodDecl *Method,
+                                  const ObjCMethodDecl *PrevMethod,
+                                  bool matchBasedOnSizeAndAlignment = false);
+
+  /// MatchAllMethodDeclarations - Check methods declaraed in interface or
+  /// or protocol against those declared in their implementations.
+  void MatchAllMethodDeclarations(const llvm::DenseSet<Selector> &InsMap,
+                                  const llvm::DenseSet<Selector> &ClsMap,
+                                  llvm::DenseSet<Selector> &InsMapSeen,
+                                  llvm::DenseSet<Selector> &ClsMapSeen,
+                                  ObjCImplDecl* IMPDecl,
+                                  ObjCContainerDecl* IDecl,
+                                  bool &IncompleteImpl,
+                                  bool ImmediateClass);
+
+  /// AddInstanceMethodToGlobalPool - All instance methods in a translation
+  /// unit are added to a global pool. This allows us to efficiently associate
+  /// a selector with a method declaraation for purposes of typechecking
+  /// messages sent to "id" (where the class of the object is unknown).
+  void AddInstanceMethodToGlobalPool(ObjCMethodDecl *Method);
+
+  /// LookupInstanceMethodInGlobalPool - Returns the method and warns if
+  /// there are multiple signatures.
+  ObjCMethodDecl *LookupInstanceMethodInGlobalPool(Selector Sel, SourceRange R,
+                                                   bool warn=true);
+
+  /// LookupFactoryMethodInGlobalPool - Returns the method and warns if
+  /// there are multiple signatures.
+  ObjCMethodDecl *LookupFactoryMethodInGlobalPool(Selector Sel, SourceRange R);
+
+  /// AddFactoryMethodToGlobalPool - Same as above, but for factory methods.
+  void AddFactoryMethodToGlobalPool(ObjCMethodDecl *Method);
+  //===--------------------------------------------------------------------===//
+  // Statement Parsing Callbacks: SemaStmt.cpp.
+public:
+  virtual OwningStmtResult ActOnExprStmt(FullExprArg Expr);
+
+  virtual OwningStmtResult ActOnNullStmt(SourceLocation SemiLoc);
+  virtual OwningStmtResult ActOnCompoundStmt(SourceLocation L, SourceLocation R,
+                                             MultiStmtArg Elts,
+                                             bool isStmtExpr);
+  virtual OwningStmtResult ActOnDeclStmt(DeclGroupPtrTy Decl,
+                                         SourceLocation StartLoc,
+                                         SourceLocation EndLoc);
+  virtual void ActOnForEachDeclStmt(DeclGroupPtrTy Decl);
+  virtual OwningStmtResult ActOnCaseStmt(SourceLocation CaseLoc, ExprArg LHSVal,
+                                    SourceLocation DotDotDotLoc, ExprArg RHSVal,
+                                    SourceLocation ColonLoc);
+  virtual void ActOnCaseStmtBody(StmtTy *CaseStmt, StmtArg SubStmt);
+
+  virtual OwningStmtResult ActOnDefaultStmt(SourceLocation DefaultLoc,
+                                            SourceLocation ColonLoc,
+                                            StmtArg SubStmt, Scope *CurScope);
+  virtual OwningStmtResult ActOnLabelStmt(SourceLocation IdentLoc,
+                                          IdentifierInfo *II,
+                                          SourceLocation ColonLoc,
+                                          StmtArg SubStmt);
+  virtual OwningStmtResult ActOnIfStmt(SourceLocation IfLoc,
+                                       FullExprArg CondVal, DeclPtrTy CondVar,
+                                       StmtArg ThenVal,
+                                       SourceLocation ElseLoc, StmtArg ElseVal);
+  virtual OwningStmtResult ActOnStartOfSwitchStmt(FullExprArg Cond, 
+                                                  DeclPtrTy CondVar);
+  virtual void ActOnSwitchBodyError(SourceLocation SwitchLoc, StmtArg Switch,
+                                    StmtArg Body);
+  virtual OwningStmtResult ActOnFinishSwitchStmt(SourceLocation SwitchLoc,
+                                                 StmtArg Switch, StmtArg Body);
+  virtual OwningStmtResult ActOnWhileStmt(SourceLocation WhileLoc,
+                                          FullExprArg Cond,
+                                          DeclPtrTy CondVar, StmtArg Body);
+  virtual OwningStmtResult ActOnDoStmt(SourceLocation DoLoc, StmtArg Body,
+                                       SourceLocation WhileLoc,
+                                       SourceLocation CondLParen, ExprArg Cond,
+                                       SourceLocation CondRParen);
+
+  virtual OwningStmtResult ActOnForStmt(SourceLocation ForLoc,
+                                        SourceLocation LParenLoc,
+                                        StmtArg First, FullExprArg Second,
+                                        DeclPtrTy SecondVar,
+                                        FullExprArg Third, 
+                                        SourceLocation RParenLoc,
+                                        StmtArg Body);
+  virtual OwningStmtResult ActOnObjCForCollectionStmt(SourceLocation ForColLoc,
+                                       SourceLocation LParenLoc,
+                                       StmtArg First, ExprArg Second,
+                                       SourceLocation RParenLoc, StmtArg Body);
+
+  virtual OwningStmtResult ActOnGotoStmt(SourceLocation GotoLoc,
+                                         SourceLocation LabelLoc,
+                                         IdentifierInfo *LabelII);
+  virtual OwningStmtResult ActOnIndirectGotoStmt(SourceLocation GotoLoc,
+                                                 SourceLocation StarLoc,
+                                                 ExprArg DestExp);
+  virtual OwningStmtResult ActOnContinueStmt(SourceLocation ContinueLoc,
+                                             Scope *CurScope);
+  virtual OwningStmtResult ActOnBreakStmt(SourceLocation GotoLoc,
+                                          Scope *CurScope);
+
+  virtual OwningStmtResult ActOnReturnStmt(SourceLocation ReturnLoc,
+                                           ExprArg RetValExp);
+  OwningStmtResult ActOnBlockReturnStmt(SourceLocation ReturnLoc,
+                                        Expr *RetValExp);
+
+  virtual OwningStmtResult ActOnAsmStmt(SourceLocation AsmLoc,
+                                        bool IsSimple,
+                                        bool IsVolatile,
+                                        unsigned NumOutputs,
+                                        unsigned NumInputs,
+                                        IdentifierInfo **Names,
+                                        MultiExprArg Constraints,
+                                        MultiExprArg Exprs,
+                                        ExprArg AsmString,
+                                        MultiExprArg Clobbers,
+                                        SourceLocation RParenLoc,
+                                        bool MSAsm = false);
+
+
+  VarDecl *BuildObjCExceptionDecl(TypeSourceInfo *TInfo, QualType ExceptionType,
+                                  IdentifierInfo *Name, SourceLocation NameLoc,
+                                  bool Invalid = false);
+  
+  virtual DeclPtrTy ActOnObjCExceptionDecl(Scope *S, Declarator &D);
+
+  virtual OwningStmtResult ActOnObjCAtCatchStmt(SourceLocation AtLoc,
+                                                SourceLocation RParen,
+                                                DeclPtrTy Parm, StmtArg Body);
+
+  virtual OwningStmtResult ActOnObjCAtFinallyStmt(SourceLocation AtLoc,
+                                                  StmtArg Body);
+
+  virtual OwningStmtResult ActOnObjCAtTryStmt(SourceLocation AtLoc,
+                                              StmtArg Try,
+                                              MultiStmtArg Catch, 
+                                              StmtArg Finally);
+
+  virtual OwningStmtResult BuildObjCAtThrowStmt(SourceLocation AtLoc,
+                                                ExprArg Throw);
+  virtual OwningStmtResult ActOnObjCAtThrowStmt(SourceLocation AtLoc,
+                                                ExprArg Throw,
+                                                Scope *CurScope);
+  virtual OwningStmtResult ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc,
+                                                       ExprArg SynchExpr,
+                                                       StmtArg SynchBody);
+
+  VarDecl *BuildExceptionDeclaration(Scope *S, QualType ExDeclType,
+                                     TypeSourceInfo *TInfo,
+                                     IdentifierInfo *Name,
+                                     SourceLocation Loc,
+                                     SourceRange Range);
+  virtual DeclPtrTy ActOnExceptionDeclarator(Scope *S, Declarator &D);
+
+  virtual OwningStmtResult ActOnCXXCatchBlock(SourceLocation CatchLoc,
+                                              DeclPtrTy ExDecl,
+                                              StmtArg HandlerBlock);
+  virtual OwningStmtResult ActOnCXXTryBlock(SourceLocation TryLoc,
+                                            StmtArg TryBlock,
+                                            MultiStmtArg Handlers);
+  void DiagnoseReturnInConstructorExceptionHandler(CXXTryStmt *TryBlock);
+
+  /// DiagnoseUnusedExprResult - If the statement passed in is an expression
+  /// whose result is unused, warn.
+  void DiagnoseUnusedExprResult(const Stmt *S);
+
+  ParsingDeclStackState PushParsingDeclaration();
+  void PopParsingDeclaration(ParsingDeclStackState S, DeclPtrTy D);
+  void EmitDeprecationWarning(NamedDecl *D, SourceLocation Loc);
+
+  void HandleDelayedDeprecationCheck(DelayedDiagnostic &DD, Decl *Ctx);
+
+  //===--------------------------------------------------------------------===//
+  // Expression Parsing Callbacks: SemaExpr.cpp.
+
+  bool DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc);
+  bool DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *PD,
+                                        ObjCMethodDecl *Getter,
+                                        SourceLocation Loc);
+  void DiagnoseSentinelCalls(NamedDecl *D, SourceLocation Loc,
+                             Expr **Args, unsigned NumArgs);
+
+  virtual void
+  PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext);
+
+  virtual void PopExpressionEvaluationContext();
+
+  void MarkDeclarationReferenced(SourceLocation Loc, Decl *D);
+  bool DiagRuntimeBehavior(SourceLocation Loc, const PartialDiagnostic &PD);
+  
+  // Primary Expressions.
+  virtual SourceRange getExprRange(ExprTy *E) const;
+
+  virtual OwningExprResult ActOnIdExpression(Scope *S,
+                                             CXXScopeSpec &SS,
+                                             UnqualifiedId &Name,
+                                             bool HasTrailingLParen,
+                                             bool IsAddressOfOperand);
+
+  bool DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R);
+
+  OwningExprResult LookupInObjCMethod(LookupResult &R,
+                                      Scope *S,
+                                      IdentifierInfo *II,
+                                      bool AllowBuiltinCreation=false);
+
+  OwningExprResult ActOnDependentIdExpression(const CXXScopeSpec &SS,
+                                              DeclarationName Name,
+                                              SourceLocation NameLoc,
+                                              bool isAddressOfOperand,
+                                const TemplateArgumentListInfo *TemplateArgs);
+  
+  OwningExprResult BuildDeclRefExpr(ValueDecl *D, QualType Ty,
+                                    SourceLocation Loc,
+                                    const CXXScopeSpec *SS = 0);
+  VarDecl *BuildAnonymousStructUnionMemberPath(FieldDecl *Field,
+                                    llvm::SmallVectorImpl<FieldDecl *> &Path);
+  OwningExprResult
+  BuildAnonymousStructUnionMemberReference(SourceLocation Loc,
+                                           FieldDecl *Field,
+                                           Expr *BaseObjectExpr = 0,
+                                      SourceLocation OpLoc = SourceLocation());
+  OwningExprResult BuildPossibleImplicitMemberExpr(const CXXScopeSpec &SS,
+                                                   LookupResult &R,
+                                const TemplateArgumentListInfo *TemplateArgs);
+  OwningExprResult BuildImplicitMemberExpr(const CXXScopeSpec &SS,
+                                           LookupResult &R,
+                                const TemplateArgumentListInfo *TemplateArgs,
+                                           bool IsDefiniteInstance);
+  bool UseArgumentDependentLookup(const CXXScopeSpec &SS,
+                                  const LookupResult &R,
+                                  bool HasTrailingLParen);
+
+  OwningExprResult BuildQualifiedDeclarationNameExpr(CXXScopeSpec &SS,
+                                                     DeclarationName Name,
+                                                     SourceLocation NameLoc);
+  OwningExprResult BuildDependentDeclRefExpr(const CXXScopeSpec &SS,
+                                             DeclarationName Name,
+                                             SourceLocation NameLoc,
+                                const TemplateArgumentListInfo *TemplateArgs);
+
+  OwningExprResult BuildDeclarationNameExpr(const CXXScopeSpec &SS,
+                                            LookupResult &R,
+                                            bool ADL);
+  OwningExprResult BuildDeclarationNameExpr(const CXXScopeSpec &SS,
+                                            SourceLocation Loc,
+                                            NamedDecl *D);
+
+  virtual OwningExprResult ActOnPredefinedExpr(SourceLocation Loc,
+                                               tok::TokenKind Kind);
+  virtual OwningExprResult ActOnNumericConstant(const Token &);
+  virtual OwningExprResult ActOnCharacterConstant(const Token &);
+  virtual OwningExprResult ActOnParenExpr(SourceLocation L, SourceLocation R,
+                                          ExprArg Val);
+  virtual OwningExprResult ActOnParenOrParenListExpr(SourceLocation L,
+                                              SourceLocation R,
+                                              MultiExprArg Val,
+                                              TypeTy *TypeOfCast=0);
+
+  /// ActOnStringLiteral - The specified tokens were lexed as pasted string
+  /// fragments (e.g. "foo" "bar" L"baz").
+  virtual OwningExprResult ActOnStringLiteral(const Token *Toks,
+                                              unsigned NumToks);
+
+  // Binary/Unary Operators.  'Tok' is the token for the operator.
+  OwningExprResult CreateBuiltinUnaryOp(SourceLocation OpLoc,
+                                        unsigned OpcIn,
+                                        ExprArg InputArg);
+  OwningExprResult BuildUnaryOp(Scope *S, SourceLocation OpLoc,
+                                UnaryOperator::Opcode Opc, ExprArg input);
+  virtual OwningExprResult ActOnUnaryOp(Scope *S, SourceLocation OpLoc,
+                                        tok::TokenKind Op, ExprArg Input);
+
+  OwningExprResult CreateSizeOfAlignOfExpr(TypeSourceInfo *T,
+                                           SourceLocation OpLoc,
+                                           bool isSizeOf, SourceRange R);
+  OwningExprResult CreateSizeOfAlignOfExpr(Expr *E, SourceLocation OpLoc,
+                                           bool isSizeOf, SourceRange R);
+  virtual OwningExprResult
+    ActOnSizeOfAlignOfExpr(SourceLocation OpLoc, bool isSizeof, bool isType,
+                           void *TyOrEx, const SourceRange &ArgRange);
+
+  bool CheckAlignOfExpr(Expr *E, SourceLocation OpLoc, const SourceRange &R);
+  bool CheckSizeOfAlignOfOperand(QualType type, SourceLocation OpLoc,
+                                 const SourceRange &R, bool isSizeof);
+
+  virtual OwningExprResult ActOnPostfixUnaryOp(Scope *S, SourceLocation OpLoc,
+                                               tok::TokenKind Kind,
+                                               ExprArg Input);
+
+  virtual OwningExprResult ActOnArraySubscriptExpr(Scope *S, ExprArg Base,
+                                                   SourceLocation LLoc,
+                                                   ExprArg Idx,
+                                                   SourceLocation RLoc);
+  OwningExprResult CreateBuiltinArraySubscriptExpr(ExprArg Base,
+                                                   SourceLocation LLoc,
+                                                   ExprArg Idx,
+                                                   SourceLocation RLoc);
+
+  OwningExprResult BuildMemberReferenceExpr(ExprArg Base,
+                                            QualType BaseType,
+                                            SourceLocation OpLoc,
+                                            bool IsArrow,
+                                            CXXScopeSpec &SS,
+                                            NamedDecl *FirstQualifierInScope,
+                                            DeclarationName Name,
+                                            SourceLocation NameLoc,
+                                const TemplateArgumentListInfo *TemplateArgs);
+
+  OwningExprResult BuildMemberReferenceExpr(ExprArg Base,
+                                            QualType BaseType,
+                                            SourceLocation OpLoc, bool IsArrow,
+                                            const CXXScopeSpec &SS,
+                                            NamedDecl *FirstQualifierInScope,
+                                            LookupResult &R,
+                                 const TemplateArgumentListInfo *TemplateArgs);
+
+  OwningExprResult LookupMemberExpr(LookupResult &R, Expr *&Base,
+                                    bool &IsArrow, SourceLocation OpLoc,
+                                    CXXScopeSpec &SS,
+                                    DeclPtrTy ObjCImpDecl);
+
+  bool CheckQualifiedMemberReference(Expr *BaseExpr, QualType BaseType,
+                                     const CXXScopeSpec &SS,
+                                     const LookupResult &R);
+
+  OwningExprResult ActOnDependentMemberExpr(ExprArg Base,
+                                            QualType BaseType,
+                                            bool IsArrow,
+                                            SourceLocation OpLoc,
+                                            const CXXScopeSpec &SS,
+                                            NamedDecl *FirstQualifierInScope,
+                                            DeclarationName Name,
+                                            SourceLocation NameLoc,
+                               const TemplateArgumentListInfo *TemplateArgs);
+
+  virtual OwningExprResult ActOnMemberAccessExpr(Scope *S, ExprArg Base,
+                                                 SourceLocation OpLoc,
+                                                 tok::TokenKind OpKind,
+                                                 CXXScopeSpec &SS,
+                                                 UnqualifiedId &Member,
+                                                 DeclPtrTy ObjCImpDecl,
+                                                 bool HasTrailingLParen);
+    
+  virtual void ActOnDefaultCtorInitializers(DeclPtrTy CDtorDecl);
+  bool ConvertArgumentsForCall(CallExpr *Call, Expr *Fn,
+                               FunctionDecl *FDecl,
+                               const FunctionProtoType *Proto,
+                               Expr **Args, unsigned NumArgs,
+                               SourceLocation RParenLoc);
+
+  /// ActOnCallExpr - Handle a call to Fn with the specified array of arguments.
+  /// This provides the location of the left/right parens and a list of comma
+  /// locations.
+  virtual OwningExprResult ActOnCallExpr(Scope *S, ExprArg Fn,
+                                         SourceLocation LParenLoc,
+                                         MultiExprArg Args,
+                                         SourceLocation *CommaLocs,
+                                         SourceLocation RParenLoc);
+  OwningExprResult BuildResolvedCallExpr(Expr *Fn,
+                                         NamedDecl *NDecl,
+                                         SourceLocation LParenLoc,
+                                         Expr **Args, unsigned NumArgs,
+                                         SourceLocation RParenLoc);
+
+  virtual OwningExprResult ActOnCastExpr(Scope *S, SourceLocation LParenLoc,
+                                         TypeTy *Ty, SourceLocation RParenLoc,
+                                         ExprArg Op);
+  OwningExprResult BuildCStyleCastExpr(SourceLocation LParenLoc,
+                                       TypeSourceInfo *Ty,
+                                       SourceLocation RParenLoc,
+                                       ExprArg Op);
+
+  virtual bool TypeIsVectorType(TypeTy *Ty) {
+    return GetTypeFromParser(Ty)->isVectorType();
+  }
+
+  OwningExprResult MaybeConvertParenListExprToParenExpr(Scope *S, ExprArg ME);
+  OwningExprResult ActOnCastOfParenListExpr(Scope *S, SourceLocation LParenLoc,
+                                            SourceLocation RParenLoc, ExprArg E,
+                                            TypeSourceInfo *TInfo);
+
+  virtual OwningExprResult ActOnCompoundLiteral(SourceLocation LParenLoc,
+                                                TypeTy *Ty,
+                                                SourceLocation RParenLoc,
+                                                ExprArg Op);
+
+  OwningExprResult BuildCompoundLiteralExpr(SourceLocation LParenLoc,
+                                            TypeSourceInfo *TInfo,
+                                            SourceLocation RParenLoc,
+                                            ExprArg InitExpr);
+
+  virtual OwningExprResult ActOnInitList(SourceLocation LParenLoc,
+                                         MultiExprArg InitList,
+                                         SourceLocation RParenLoc);
+
+  virtual OwningExprResult ActOnDesignatedInitializer(Designation &Desig,
+                                                      SourceLocation Loc,
+                                                      bool GNUSyntax,
+                                                      OwningExprResult Init);
+
+  virtual OwningExprResult ActOnBinOp(Scope *S, SourceLocation TokLoc,
+                                      tok::TokenKind Kind,
+                                      ExprArg LHS, ExprArg RHS);
+  OwningExprResult BuildBinOp(Scope *S, SourceLocation OpLoc,
+                              BinaryOperator::Opcode Opc,
+                              Expr *lhs, Expr *rhs);
+  OwningExprResult CreateBuiltinBinOp(SourceLocation TokLoc,
+                                      unsigned Opc, Expr *lhs, Expr *rhs);
+
+  /// ActOnConditionalOp - Parse a ?: operation.  Note that 'LHS' may be null
+  /// in the case of a the GNU conditional expr extension.
+  virtual OwningExprResult ActOnConditionalOp(SourceLocation QuestionLoc,
+                                              SourceLocation ColonLoc,
+                                              ExprArg Cond, ExprArg LHS,
+                                              ExprArg RHS);
+
+  /// ActOnAddrLabel - Parse the GNU address of label extension: "&&foo".
+  virtual OwningExprResult ActOnAddrLabel(SourceLocation OpLoc,
+                                          SourceLocation LabLoc,
+                                          IdentifierInfo *LabelII);
+
+  virtual OwningExprResult ActOnStmtExpr(SourceLocation LPLoc, StmtArg SubStmt,
+                                         SourceLocation RPLoc); // "({..})"
+
+  /// __builtin_offsetof(type, a.b[123][456].c)
+  virtual OwningExprResult ActOnBuiltinOffsetOf(Scope *S,
+                                                SourceLocation BuiltinLoc,
+                                                SourceLocation TypeLoc,
+                                                TypeTy *Arg1,
+                                                OffsetOfComponent *CompPtr,
+                                                unsigned NumComponents,
+                                                SourceLocation RParenLoc);
+
+  // __builtin_types_compatible_p(type1, type2)
+  virtual OwningExprResult ActOnTypesCompatibleExpr(SourceLocation BuiltinLoc,
+                                                    TypeTy *arg1, TypeTy *arg2,
+                                                    SourceLocation RPLoc);
+
+  // __builtin_choose_expr(constExpr, expr1, expr2)
+  virtual OwningExprResult ActOnChooseExpr(SourceLocation BuiltinLoc,
+                                           ExprArg cond, ExprArg expr1,
+                                           ExprArg expr2, SourceLocation RPLoc);
+
+  // __builtin_va_arg(expr, type)
+  virtual OwningExprResult ActOnVAArg(SourceLocation BuiltinLoc,
+                                      ExprArg expr, TypeTy *type,
+                                      SourceLocation RPLoc);
+
+  // __null
+  virtual OwningExprResult ActOnGNUNullExpr(SourceLocation TokenLoc);
+
+  //===------------------------- "Block" Extension ------------------------===//
+
+  /// ActOnBlockStart - This callback is invoked when a block literal is
+  /// started.
+  virtual void ActOnBlockStart(SourceLocation CaretLoc, Scope *CurScope);
+
+  /// ActOnBlockArguments - This callback allows processing of block arguments.
+  /// If there are no arguments, this is still invoked.
+  virtual void ActOnBlockArguments(Declarator &ParamInfo, Scope *CurScope);
+
+  /// ActOnBlockError - If there is an error parsing a block, this callback
+  /// is invoked to pop the information about the block from the action impl.
+  virtual void ActOnBlockError(SourceLocation CaretLoc, Scope *CurScope);
+
+  /// ActOnBlockStmtExpr - This is called when the body of a block statement
+  /// literal was successfully completed.  ^(int x){...}
+  virtual OwningExprResult ActOnBlockStmtExpr(SourceLocation CaretLoc,
+                                              StmtArg Body, Scope *CurScope);
+
+  //===---------------------------- C++ Features --------------------------===//
+
+  // Act on C++ namespaces
+  virtual DeclPtrTy ActOnStartNamespaceDef(Scope *S, SourceLocation IdentLoc,
+                                           IdentifierInfo *Ident,
+                                           SourceLocation LBrace,
+                                           AttributeList *AttrList);
+  virtual void ActOnFinishNamespaceDef(DeclPtrTy Dcl, SourceLocation RBrace);
+
+  virtual DeclPtrTy ActOnUsingDirective(Scope *CurScope,
+                                        SourceLocation UsingLoc,
+                                        SourceLocation NamespcLoc,
+                                        CXXScopeSpec &SS,
+                                        SourceLocation IdentLoc,
+                                        IdentifierInfo *NamespcName,
+                                        AttributeList *AttrList);
+
+  void PushUsingDirective(Scope *S, UsingDirectiveDecl *UDir);
+
+  virtual DeclPtrTy ActOnNamespaceAliasDef(Scope *CurScope,
+                                           SourceLocation NamespaceLoc,
+                                           SourceLocation AliasLoc,
+                                           IdentifierInfo *Alias,
+                                           CXXScopeSpec &SS,
+                                           SourceLocation IdentLoc,
+                                           IdentifierInfo *Ident);
+
+  void HideUsingShadowDecl(Scope *S, UsingShadowDecl *Shadow);
+  bool CheckUsingShadowDecl(UsingDecl *UD, NamedDecl *Target,
+                            const LookupResult &PreviousDecls);
+  UsingShadowDecl *BuildUsingShadowDecl(Scope *S, UsingDecl *UD,
+                                        NamedDecl *Target);
+
+  bool CheckUsingDeclRedeclaration(SourceLocation UsingLoc,
+                                   bool isTypeName,
+                                   const CXXScopeSpec &SS,
+                                   SourceLocation NameLoc,
+                                   const LookupResult &Previous);
+  bool CheckUsingDeclQualifier(SourceLocation UsingLoc,
+                               const CXXScopeSpec &SS,
+                               SourceLocation NameLoc);
+
+  NamedDecl *BuildUsingDeclaration(Scope *S, AccessSpecifier AS,
+                                   SourceLocation UsingLoc,
+                                   CXXScopeSpec &SS,
+                                   SourceLocation IdentLoc,
+                                   DeclarationName Name,
+                                   AttributeList *AttrList,
+                                   bool IsInstantiation,
+                                   bool IsTypeName,
+                                   SourceLocation TypenameLoc);
+
+  virtual DeclPtrTy ActOnUsingDeclaration(Scope *CurScope,
+                                          AccessSpecifier AS,
+                                          bool HasUsingKeyword,
+                                          SourceLocation UsingLoc,
+                                          CXXScopeSpec &SS,
+                                          UnqualifiedId &Name,
+                                          AttributeList *AttrList,
+                                          bool IsTypeName,
+                                          SourceLocation TypenameLoc);
+
+  /// AddCXXDirectInitializerToDecl - This action is called immediately after
+  /// ActOnDeclarator, when a C++ direct initializer is present.
+  /// e.g: "int x(1);"
+  virtual void AddCXXDirectInitializerToDecl(DeclPtrTy Dcl,
+                                             SourceLocation LParenLoc,
+                                             MultiExprArg Exprs,
+                                             SourceLocation *CommaLocs,
+                                             SourceLocation RParenLoc);
+
+  /// InitializeVarWithConstructor - Creates an CXXConstructExpr
+  /// and sets it as the initializer for the the passed in VarDecl.
+  bool InitializeVarWithConstructor(VarDecl *VD,
+                                    CXXConstructorDecl *Constructor,
+                                    MultiExprArg Exprs);
+
+  /// BuildCXXConstructExpr - Creates a complete call to a constructor,
+  /// including handling of its default argument expressions.
+  OwningExprResult BuildCXXConstructExpr(SourceLocation ConstructLoc,
+                                         QualType DeclInitType,
+                                         CXXConstructorDecl *Constructor,
+                                         MultiExprArg Exprs,
+                                         bool RequiresZeroInit = false,
+                                         bool BaseInitialization = false);
+
+  // FIXME: Can re remove this and have the above BuildCXXConstructExpr check if
+  // the constructor can be elidable?
+  OwningExprResult BuildCXXConstructExpr(SourceLocation ConstructLoc,
+                                         QualType DeclInitType,
+                                         CXXConstructorDecl *Constructor,
+                                         bool Elidable,
+                                         MultiExprArg Exprs,
+                                         bool RequiresZeroInit = false,
+                                         bool BaseInitialization = false);
+
+  /// BuildCXXDefaultArgExpr - Creates a CXXDefaultArgExpr, instantiating
+  /// the default expr if needed.
+  OwningExprResult BuildCXXDefaultArgExpr(SourceLocation CallLoc,
+                                          FunctionDecl *FD,
+                                          ParmVarDecl *Param);
+
+  /// FinalizeVarWithDestructor - Prepare for calling destructor on the
+  /// constructed variable.
+  void FinalizeVarWithDestructor(VarDecl *VD, const RecordType *DeclInitType);
+
+  /// DefineImplicitDefaultConstructor - Checks for feasibility of
+  /// defining this constructor as the default constructor.
+  void DefineImplicitDefaultConstructor(SourceLocation CurrentLocation,
+                                        CXXConstructorDecl *Constructor);
+
+  /// DefineImplicitDestructor - Checks for feasibility of
+  /// defining this destructor as the default destructor.
+  void DefineImplicitDestructor(SourceLocation CurrentLocation,
+                                        CXXDestructorDecl *Destructor);
+
+  /// DefineImplicitCopyConstructor - Checks for feasibility of
+  /// defining this constructor as the copy constructor.
+  void DefineImplicitCopyConstructor(SourceLocation CurrentLocation,
+                                     CXXConstructorDecl *Constructor,
+                                     unsigned TypeQuals);
+
+  /// DefineImplicitOverloadedAssign - Checks for feasibility of
+  /// defining implicit this overloaded assignment operator.
+  void DefineImplicitOverloadedAssign(SourceLocation CurrentLocation,
+                                      CXXMethodDecl *MethodDecl);
+
+  /// getAssignOperatorMethod - Returns the default copy assignmment operator
+  /// for the class.
+  CXXMethodDecl *getAssignOperatorMethod(SourceLocation CurrentLocation,
+                                         ParmVarDecl *Decl,
+                                         CXXRecordDecl *ClassDecl);
+
+  /// MaybeBindToTemporary - If the passed in expression has a record type with
+  /// a non-trivial destructor, this will return CXXBindTemporaryExpr. Otherwise
+  /// it simply returns the passed in expression.
+  OwningExprResult MaybeBindToTemporary(Expr *E);
+
+  bool CompleteConstructorCall(CXXConstructorDecl *Constructor,
+                               MultiExprArg ArgsPtr,
+                               SourceLocation Loc,
+                      ASTOwningVector<&ActionBase::DeleteExpr> &ConvertedArgs);
+    
+  virtual TypeTy *getDestructorName(SourceLocation TildeLoc,
+                                    IdentifierInfo &II, SourceLocation NameLoc,
+                                    Scope *S, CXXScopeSpec &SS,
+                                    TypeTy *ObjectType,
+                                    bool EnteringContext);
+
+  /// ActOnCXXNamedCast - Parse {dynamic,static,reinterpret,const}_cast's.
+  virtual OwningExprResult ActOnCXXNamedCast(SourceLocation OpLoc,
+                                             tok::TokenKind Kind,
+                                             SourceLocation LAngleBracketLoc,
+                                             TypeTy *Ty,
+                                             SourceLocation RAngleBracketLoc,
+                                             SourceLocation LParenLoc,
+                                             ExprArg E,
+                                             SourceLocation RParenLoc);
+
+  OwningExprResult BuildCXXNamedCast(SourceLocation OpLoc,
+                                     tok::TokenKind Kind,
+                                     TypeSourceInfo *Ty,
+                                     ExprArg E,
+                                     SourceRange AngleBrackets,
+                                     SourceRange Parens);
+
+  OwningExprResult BuildCXXTypeId(QualType TypeInfoType,
+                                  SourceLocation TypeidLoc,
+                                  TypeSourceInfo *Operand,
+                                  SourceLocation RParenLoc);
+  OwningExprResult BuildCXXTypeId(QualType TypeInfoType,
+                                  SourceLocation TypeidLoc,
+                                  ExprArg Operand,
+                                  SourceLocation RParenLoc);
+  
+  /// ActOnCXXTypeid - Parse typeid( something ).
+  virtual OwningExprResult ActOnCXXTypeid(SourceLocation OpLoc,
+                                          SourceLocation LParenLoc, bool isType,
+                                          void *TyOrExpr,
+                                          SourceLocation RParenLoc);
+
+  //// ActOnCXXThis -  Parse 'this' pointer.
+  virtual OwningExprResult ActOnCXXThis(SourceLocation ThisLoc);
+
+  /// ActOnCXXBoolLiteral - Parse {true,false} literals.
+  virtual OwningExprResult ActOnCXXBoolLiteral(SourceLocation OpLoc,
+                                               tok::TokenKind Kind);
+
+  /// ActOnCXXNullPtrLiteral - Parse 'nullptr'.
+  virtual OwningExprResult ActOnCXXNullPtrLiteral(SourceLocation Loc);
+
+  //// ActOnCXXThrow -  Parse throw expressions.
+  virtual OwningExprResult ActOnCXXThrow(SourceLocation OpLoc,
+                                         ExprArg expr);
+  bool CheckCXXThrowOperand(SourceLocation ThrowLoc, Expr *&E);
+
+  /// ActOnCXXTypeConstructExpr - Parse construction of a specified type.
+  /// Can be interpreted either as function-style casting ("int(x)")
+  /// or class type construction ("ClassType(x,y,z)")
+  /// or creation of a value-initialized type ("int()").
+  virtual OwningExprResult ActOnCXXTypeConstructExpr(SourceRange TypeRange,
+                                                     TypeTy *TypeRep,
+                                                     SourceLocation LParenLoc,
+                                                     MultiExprArg Exprs,
+                                                     SourceLocation *CommaLocs,
+                                                     SourceLocation RParenLoc);
+
+  /// ActOnCXXNew - Parsed a C++ 'new' expression.
+  virtual OwningExprResult ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal,
+                                       SourceLocation PlacementLParen,
+                                       MultiExprArg PlacementArgs,
+                                       SourceLocation PlacementRParen,
+                                       bool ParenTypeId, Declarator &D,
+                                       SourceLocation ConstructorLParen,
+                                       MultiExprArg ConstructorArgs,
+                                       SourceLocation ConstructorRParen);
+  OwningExprResult BuildCXXNew(SourceLocation StartLoc, bool UseGlobal,
+                               SourceLocation PlacementLParen,
+                               MultiExprArg PlacementArgs,
+                               SourceLocation PlacementRParen,
+                               bool ParenTypeId,
+                               QualType AllocType,
+                               SourceLocation TypeLoc,
+                               SourceRange TypeRange,
+                               ExprArg ArraySize,
+                               SourceLocation ConstructorLParen,
+                               MultiExprArg ConstructorArgs,
+                               SourceLocation ConstructorRParen);
+
+  bool CheckAllocatedType(QualType AllocType, SourceLocation Loc,
+                          SourceRange R);
+  bool FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range,
+                               bool UseGlobal, QualType AllocType, bool IsArray,
+                               Expr **PlaceArgs, unsigned NumPlaceArgs,
+                               FunctionDecl *&OperatorNew,
+                               FunctionDecl *&OperatorDelete);
+  bool FindAllocationOverload(SourceLocation StartLoc, SourceRange Range,
+                              DeclarationName Name, Expr** Args,
+                              unsigned NumArgs, DeclContext *Ctx,
+                              bool AllowMissing, FunctionDecl *&Operator);
+  void DeclareGlobalNewDelete();
+  void DeclareGlobalAllocationFunction(DeclarationName Name, QualType Return,
+                                       QualType Argument,
+                                       bool addMallocAttr = false);
+
+  bool FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD, 
+                                DeclarationName Name, FunctionDecl* &Operator);
+
+  /// ActOnCXXDelete - Parsed a C++ 'delete' expression
+  virtual OwningExprResult ActOnCXXDelete(SourceLocation StartLoc,
+                                          bool UseGlobal, bool ArrayForm,
+                                          ExprArg Operand);
+
+  virtual DeclResult ActOnCXXConditionDeclaration(Scope *S,
+                                                  Declarator &D);
+  OwningExprResult CheckConditionVariable(VarDecl *ConditionVar);
+                                          
+  /// ActOnUnaryTypeTrait - Parsed one of the unary type trait support
+  /// pseudo-functions.
+  virtual OwningExprResult ActOnUnaryTypeTrait(UnaryTypeTrait OTT,
+                                               SourceLocation KWLoc,
+                                               SourceLocation LParen,
+                                               TypeTy *Ty,
+                                               SourceLocation RParen);
+
+  virtual OwningExprResult ActOnStartCXXMemberReference(Scope *S,
+                                                        ExprArg Base,
+                                                        SourceLocation OpLoc,
+                                                        tok::TokenKind OpKind,
+                                                        TypeTy *&ObjectType,
+                                                   bool &MayBePseudoDestructor);
+
+  OwningExprResult DiagnoseDtorReference(SourceLocation NameLoc,
+                                         ExprArg MemExpr);
+  
+  OwningExprResult BuildPseudoDestructorExpr(ExprArg Base,
+                                             SourceLocation OpLoc,
+                                             tok::TokenKind OpKind,
+                                             const CXXScopeSpec &SS,
+                                             TypeSourceInfo *ScopeType,
+                                             SourceLocation CCLoc,
+                                             SourceLocation TildeLoc,
+                                     PseudoDestructorTypeStorage DestroyedType,
+                                             bool HasTrailingLParen);
+    
+  virtual OwningExprResult ActOnPseudoDestructorExpr(Scope *S, ExprArg Base,
+                                                     SourceLocation OpLoc,
+                                                     tok::TokenKind OpKind,
+                                                     CXXScopeSpec &SS,
+                                                   UnqualifiedId &FirstTypeName,
+                                                     SourceLocation CCLoc,
+                                                     SourceLocation TildeLoc,
+                                                  UnqualifiedId &SecondTypeName,
+                                                     bool HasTrailingLParen);
+   
+  /// MaybeCreateCXXExprWithTemporaries - If the list of temporaries is
+  /// non-empty, will create a new CXXExprWithTemporaries expression.
+  /// Otherwise, just returs the passed in expression.
+  Expr *MaybeCreateCXXExprWithTemporaries(Expr *SubExpr);
+  OwningExprResult MaybeCreateCXXExprWithTemporaries(OwningExprResult SubExpr);
+  FullExpr CreateFullExpr(Expr *SubExpr);
+  
+  virtual OwningExprResult ActOnFinishFullExpr(ExprArg Expr);
+
+  // Marks SS invalid if it represents an incomplete type.
+  bool RequireCompleteDeclContext(CXXScopeSpec &SS);
+
+  DeclContext *computeDeclContext(QualType T);
+  DeclContext *computeDeclContext(const CXXScopeSpec &SS,
+                                  bool EnteringContext = false);
+  bool isDependentScopeSpecifier(const CXXScopeSpec &SS);
+  CXXRecordDecl *getCurrentInstantiationOf(NestedNameSpecifier *NNS);
+  bool isUnknownSpecialization(const CXXScopeSpec &SS);
+
+  /// ActOnCXXGlobalScopeSpecifier - Return the object that represents the
+  /// global scope ('::').
+  virtual CXXScopeTy *ActOnCXXGlobalScopeSpecifier(Scope *S,
+                                                   SourceLocation CCLoc);
+
+  bool isAcceptableNestedNameSpecifier(NamedDecl *SD);
+  NamedDecl *FindFirstQualifierInScope(Scope *S, NestedNameSpecifier *NNS);
+
+  virtual bool isNonTypeNestedNameSpecifier(Scope *S, CXXScopeSpec &SS,
+                                            SourceLocation IdLoc,
+                                            IdentifierInfo &II,
+                                            TypeTy *ObjectType);
+  
+  CXXScopeTy *BuildCXXNestedNameSpecifier(Scope *S,
+                                          CXXScopeSpec &SS,
+                                          SourceLocation IdLoc,
+                                          SourceLocation CCLoc,
+                                          IdentifierInfo &II,
+                                          QualType ObjectType,
+                                          NamedDecl *ScopeLookupResult,
+                                          bool EnteringContext,
+                                          bool ErrorRecoveryLookup);
+
+  virtual CXXScopeTy *ActOnCXXNestedNameSpecifier(Scope *S,
+                                                  CXXScopeSpec &SS,
+                                                  SourceLocation IdLoc,
+                                                  SourceLocation CCLoc,
+                                                  IdentifierInfo &II,
+                                                  TypeTy *ObjectType,
+                                                  bool EnteringContext);
+
+  virtual bool IsInvalidUnlessNestedName(Scope *S,
+                                         CXXScopeSpec &SS,
+                                         IdentifierInfo &II,
+                                         TypeTy *ObjectType,
+                                         bool EnteringContext);
+  
+  /// ActOnCXXNestedNameSpecifier - Called during parsing of a
+  /// nested-name-specifier that involves a template-id, e.g.,
+  /// "foo::bar<int, float>::", and now we need to build a scope
+  /// specifier. \p SS is empty or the previously parsed nested-name
+  /// part ("foo::"), \p Type is the already-parsed class template
+  /// specialization (or other template-id that names a type), \p
+  /// TypeRange is the source range where the type is located, and \p
+  /// CCLoc is the location of the trailing '::'.
+  virtual CXXScopeTy *ActOnCXXNestedNameSpecifier(Scope *S,
+                                                  const CXXScopeSpec &SS,
+                                                  TypeTy *Type,
+                                                  SourceRange TypeRange,
+                                                  SourceLocation CCLoc);
+
+  virtual bool ShouldEnterDeclaratorScope(Scope *S, const CXXScopeSpec &SS);
+
+  /// ActOnCXXEnterDeclaratorScope - Called when a C++ scope specifier (global
+  /// scope or nested-name-specifier) is parsed, part of a declarator-id.
+  /// After this method is called, according to [C++ 3.4.3p3], names should be
+  /// looked up in the declarator-id's scope, until the declarator is parsed and
+  /// ActOnCXXExitDeclaratorScope is called.
+  /// The 'SS' should be a non-empty valid CXXScopeSpec.
+  virtual bool ActOnCXXEnterDeclaratorScope(Scope *S, CXXScopeSpec &SS);
+
+  /// ActOnCXXExitDeclaratorScope - Called when a declarator that previously
+  /// invoked ActOnCXXEnterDeclaratorScope(), is finished. 'SS' is the same
+  /// CXXScopeSpec that was passed to ActOnCXXEnterDeclaratorScope as well.
+  /// Used to indicate that names should revert to being looked up in the
+  /// defining scope.
+  virtual void ActOnCXXExitDeclaratorScope(Scope *S, const CXXScopeSpec &SS);
+
+  /// ActOnCXXEnterDeclInitializer - Invoked when we are about to parse an
+  /// initializer for the declaration 'Dcl'.
+  /// After this method is called, according to [C++ 3.4.1p13], if 'Dcl' is a
+  /// static data member of class X, names should be looked up in the scope of
+  /// class X.
+  virtual void ActOnCXXEnterDeclInitializer(Scope *S, DeclPtrTy Dcl);
+
+  /// ActOnCXXExitDeclInitializer - Invoked after we are finished parsing an
+  /// initializer for the declaration 'Dcl'.
+  virtual void ActOnCXXExitDeclInitializer(Scope *S, DeclPtrTy Dcl);
+
+  // ParseObjCStringLiteral - Parse Objective-C string literals.
+  virtual ExprResult ParseObjCStringLiteral(SourceLocation *AtLocs,
+                                            ExprTy **Strings,
+                                            unsigned NumStrings);
+
+  Expr *BuildObjCEncodeExpression(SourceLocation AtLoc,
+                                  TypeSourceInfo *EncodedTypeInfo,
+                                  SourceLocation RParenLoc);
+  CXXMemberCallExpr *BuildCXXMemberCallExpr(Expr *Exp,
+                                            NamedDecl *FoundDecl,
+                                            CXXMethodDecl *Method);
+
+  virtual ExprResult ParseObjCEncodeExpression(SourceLocation AtLoc,
+                                               SourceLocation EncodeLoc,
+                                               SourceLocation LParenLoc,
+                                               TypeTy *Ty,
+                                               SourceLocation RParenLoc);
+
+  // ParseObjCSelectorExpression - Build selector expression for @selector
+  virtual ExprResult ParseObjCSelectorExpression(Selector Sel,
+                                                 SourceLocation AtLoc,
+                                                 SourceLocation SelLoc,
+                                                 SourceLocation LParenLoc,
+                                                 SourceLocation RParenLoc);
+
+  // ParseObjCProtocolExpression - Build protocol expression for @protocol
+  virtual ExprResult ParseObjCProtocolExpression(IdentifierInfo * ProtocolName,
+                                                 SourceLocation AtLoc,
+                                                 SourceLocation ProtoLoc,
+                                                 SourceLocation LParenLoc,
+                                                 SourceLocation RParenLoc);
+
+  //===--------------------------------------------------------------------===//
+  // C++ Declarations
+  //
+  virtual DeclPtrTy ActOnStartLinkageSpecification(Scope *S,
+                                                   SourceLocation ExternLoc,
+                                                   SourceLocation LangLoc,
+                                                   const char *Lang,
+                                                   unsigned StrSize,
+                                                   SourceLocation LBraceLoc);
+  virtual DeclPtrTy ActOnFinishLinkageSpecification(Scope *S,
+                                                    DeclPtrTy LinkageSpec,
+                                                    SourceLocation RBraceLoc);
+
+
+  //===--------------------------------------------------------------------===//
+  // C++ Classes
+  //
+  virtual bool isCurrentClassName(const IdentifierInfo &II, Scope *S,
+                                  const CXXScopeSpec *SS);
+
+  virtual DeclPtrTy ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS,
+                                             Declarator &D,
+                                 MultiTemplateParamsArg TemplateParameterLists,
+                                             ExprTy *BitfieldWidth,
+                                             ExprTy *Init, bool IsDefinition,
+                                             bool Deleted = false);
+
+  virtual MemInitResult ActOnMemInitializer(DeclPtrTy ConstructorD,
+                                            Scope *S,
+                                            CXXScopeSpec &SS,
+                                            IdentifierInfo *MemberOrBase,
+                                            TypeTy *TemplateTypeTy,
+                                            SourceLocation IdLoc,
+                                            SourceLocation LParenLoc,
+                                            ExprTy **Args, unsigned NumArgs,
+                                            SourceLocation *CommaLocs,
+                                            SourceLocation RParenLoc);
+
+  MemInitResult BuildMemberInitializer(FieldDecl *Member, Expr **Args,
+                                       unsigned NumArgs, SourceLocation IdLoc,
+                                       SourceLocation LParenLoc,
+                                       SourceLocation RParenLoc);
+
+  MemInitResult BuildBaseInitializer(QualType BaseType,
+                                     TypeSourceInfo *BaseTInfo,
+                                     Expr **Args, unsigned NumArgs,
+                                     SourceLocation LParenLoc,
+                                     SourceLocation RParenLoc,
+                                     CXXRecordDecl *ClassDecl);
+
+  bool SetBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
+                                   CXXBaseOrMemberInitializer **Initializers,
+                                   unsigned NumInitializers, bool AnyErrors);
+
+  /// MarkBaseAndMemberDestructorsReferenced - Given a record decl,
+  /// mark all the non-trivial destructors of its members and bases as
+  /// referenced.
+  void MarkBaseAndMemberDestructorsReferenced(SourceLocation Loc,
+                                              CXXRecordDecl *Record);
+
+  /// ClassesWithUnmarkedVirtualMembers - Contains record decls whose virtual
+  /// members need to be marked as referenced at the end of the translation
+  /// unit. It will contain polymorphic classes that do not have a key
+  /// function or have a key function that has been defined.
+  llvm::SmallVector<std::pair<CXXRecordDecl *, SourceLocation>, 4>
+    ClassesWithUnmarkedVirtualMembers;
+
+  /// MaybeMarkVirtualMembersReferenced - If the passed in method is the
+  /// key function of the record decl, will mark virtual member functions as 
+  /// referenced.
+  void MaybeMarkVirtualMembersReferenced(SourceLocation Loc, CXXMethodDecl *MD);
+  
+  /// MarkVirtualMembersReferenced - Will mark all virtual members of the given
+  /// CXXRecordDecl referenced.
+  void MarkVirtualMembersReferenced(SourceLocation Loc,
+                                    const CXXRecordDecl *RD);
+
+  /// ProcessPendingClassesWithUnmarkedVirtualMembers - Will process classes 
+  /// that might need to have their virtual members marked as referenced.
+  /// Returns false if no work was done.
+  bool ProcessPendingClassesWithUnmarkedVirtualMembers();
+  
+  void AddImplicitlyDeclaredMembersToClass(Scope *S, CXXRecordDecl *ClassDecl);
+
+  virtual void ActOnMemInitializers(DeclPtrTy ConstructorDecl,
+                                    SourceLocation ColonLoc,
+                                    MemInitTy **MemInits, unsigned NumMemInits,
+                                    bool AnyErrors);
+
+  void CheckCompletedCXXClass(Scope *S, CXXRecordDecl *Record);
+  virtual void ActOnFinishCXXMemberSpecification(Scope* S, SourceLocation RLoc,
+                                                 DeclPtrTy TagDecl,
+                                                 SourceLocation LBrac,
+                                                 SourceLocation RBrac,
+                                                 AttributeList *AttrList);
+
+  virtual void ActOnReenterTemplateScope(Scope *S, DeclPtrTy Template);
+  virtual void ActOnStartDelayedMemberDeclarations(Scope *S,
+                                                   DeclPtrTy Record);
+  virtual void ActOnStartDelayedCXXMethodDeclaration(Scope *S,
+                                                     DeclPtrTy Method);
+  virtual void ActOnDelayedCXXMethodParameter(Scope *S, DeclPtrTy Param);
+  virtual void ActOnFinishDelayedCXXMethodDeclaration(Scope *S,
+                                                      DeclPtrTy Method);
+  virtual void ActOnFinishDelayedMemberDeclarations(Scope *S,
+                                                    DeclPtrTy Record);
+
+  virtual DeclPtrTy ActOnStaticAssertDeclaration(SourceLocation AssertLoc,
+                                                 ExprArg AssertExpr,
+                                                 ExprArg AssertMessageExpr);
+
+  FriendDecl *CheckFriendTypeDecl(SourceLocation FriendLoc, 
+                                  TypeSourceInfo *TSInfo);
+  DeclPtrTy ActOnFriendTypeDecl(Scope *S, const DeclSpec &DS,
+                                MultiTemplateParamsArg TemplateParams);
+  DeclPtrTy ActOnFriendFunctionDecl(Scope *S, Declarator &D, bool IsDefinition,
+                                    MultiTemplateParamsArg TemplateParams);
+
+  QualType CheckConstructorDeclarator(Declarator &D, QualType R,
+                                      FunctionDecl::StorageClass& SC);
+  void CheckConstructor(CXXConstructorDecl *Constructor);
+  QualType CheckDestructorDeclarator(Declarator &D,
+                                     FunctionDecl::StorageClass& SC);
+  bool CheckDestructor(CXXDestructorDecl *Destructor);
+  void CheckConversionDeclarator(Declarator &D, QualType &R,
+                                 FunctionDecl::StorageClass& SC);
+  DeclPtrTy ActOnConversionDeclarator(CXXConversionDecl *Conversion);
+  
+  //===--------------------------------------------------------------------===//
+  // C++ Derived Classes
+  //
+
+  /// ActOnBaseSpecifier - Parsed a base specifier
+  CXXBaseSpecifier *CheckBaseSpecifier(CXXRecordDecl *Class,
+                                       SourceRange SpecifierRange,
+                                       bool Virtual, AccessSpecifier Access,
+                                       QualType BaseType,
+                                       SourceLocation BaseLoc);
+  
+  /// SetClassDeclAttributesFromBase - Copies class decl traits 
+  /// (such as whether the class has a trivial constructor, 
+  /// trivial destructor etc) from the given base class.
+  void SetClassDeclAttributesFromBase(CXXRecordDecl *Class,
+                                      const CXXRecordDecl *BaseClass,
+                                      bool BaseIsVirtual);
+  
+  virtual BaseResult ActOnBaseSpecifier(DeclPtrTy classdecl,
+                                        SourceRange SpecifierRange,
+                                        bool Virtual, AccessSpecifier Access,
+                                        TypeTy *basetype, SourceLocation
+                                        BaseLoc);
+
+  bool AttachBaseSpecifiers(CXXRecordDecl *Class, CXXBaseSpecifier **Bases,
+                            unsigned NumBases);
+  virtual void ActOnBaseSpecifiers(DeclPtrTy ClassDecl, BaseTy **Bases,
+                                   unsigned NumBases);
+
+  bool IsDerivedFrom(QualType Derived, QualType Base);
+  bool IsDerivedFrom(QualType Derived, QualType Base, CXXBasePaths &Paths);
+
+  // FIXME: I don't like this name.
+  void BuildBasePathArray(const CXXBasePaths &Paths,
+                          CXXBaseSpecifierArray &BasePath);
+
+  bool CheckDerivedToBaseConversion(QualType Derived, QualType Base,
+                                    SourceLocation Loc, SourceRange Range,
+                                    CXXBaseSpecifierArray *BasePath = 0,
+                                    bool IgnoreAccess = false);
+  bool CheckDerivedToBaseConversion(QualType Derived, QualType Base,
+                                    unsigned InaccessibleBaseID,
+                                    unsigned AmbigiousBaseConvID,
+                                    SourceLocation Loc, SourceRange Range,
+                                    DeclarationName Name,
+                                    CXXBaseSpecifierArray *BasePath);
+
+  std::string getAmbiguousPathsDisplayString(CXXBasePaths &Paths);
+
+  /// CheckOverridingFunctionReturnType - Checks whether the return types are
+  /// covariant, according to C++ [class.virtual]p5.
+  bool CheckOverridingFunctionReturnType(const CXXMethodDecl *New,
+                                         const CXXMethodDecl *Old);
+
+  /// CheckOverridingFunctionExceptionSpec - Checks whether the exception
+  /// spec is a subset of base spec.
+  bool CheckOverridingFunctionExceptionSpec(const CXXMethodDecl *New,
+                                            const CXXMethodDecl *Old);
+
+  /// CheckOverridingFunctionAttributes - Checks whether attributes are
+  /// incompatible or prevent overriding.
+  bool CheckOverridingFunctionAttributes(const CXXMethodDecl *New,
+                                         const CXXMethodDecl *Old);
+
+  bool CheckPureMethod(CXXMethodDecl *Method, SourceRange InitRange);
+  //===--------------------------------------------------------------------===//
+  // C++ Access Control
+  //
+
+  enum AccessResult {
+    AR_accessible,
+    AR_inaccessible,
+    AR_dependent,
+    AR_delayed
+  };
+
+  bool SetMemberAccessSpecifier(NamedDecl *MemberDecl,
+                                NamedDecl *PrevMemberDecl,
+                                AccessSpecifier LexicalAS);
+
+  AccessResult CheckUnresolvedMemberAccess(UnresolvedMemberExpr *E,
+                                           DeclAccessPair FoundDecl);
+  AccessResult CheckUnresolvedLookupAccess(UnresolvedLookupExpr *E,
+                                           DeclAccessPair FoundDecl);
+  AccessResult CheckAllocationAccess(SourceLocation OperatorLoc,
+                                     SourceRange PlacementRange,
+                                     CXXRecordDecl *NamingClass,
+                                     DeclAccessPair FoundDecl);
+  AccessResult CheckConstructorAccess(SourceLocation Loc,
+                                      CXXConstructorDecl *D,
+                                      const InitializedEntity &Entity,
+                                      AccessSpecifier Access);
+  AccessResult CheckDestructorAccess(SourceLocation Loc,
+                                     CXXDestructorDecl *Dtor,
+                                     const PartialDiagnostic &PDiag);
+  AccessResult CheckDirectMemberAccess(SourceLocation Loc,
+                                       NamedDecl *D,
+                                       const PartialDiagnostic &PDiag);
+  AccessResult CheckMemberOperatorAccess(SourceLocation Loc,
+                                         Expr *ObjectExpr,
+                                         Expr *ArgExpr,
+                                         DeclAccessPair FoundDecl);
+  AccessResult CheckAddressOfMemberAccess(Expr *OvlExpr,
+                                          DeclAccessPair FoundDecl);
+  AccessResult CheckBaseClassAccess(SourceLocation AccessLoc,
+                                    QualType Base, QualType Derived,
+                                    const CXXBasePath &Path,
+                                    unsigned DiagID,
+                                    bool ForceCheck = false,
+                                    bool ForceUnprivileged = false);
+  void CheckLookupAccess(const LookupResult &R);
+
+  void HandleDependentAccessCheck(const DependentDiagnostic &DD,
+                         const MultiLevelTemplateArgumentList &TemplateArgs);
+  void PerformDependentDiagnostics(const DeclContext *Pattern,
+                        const MultiLevelTemplateArgumentList &TemplateArgs);
+
+  void HandleDelayedAccessCheck(DelayedDiagnostic &DD, Decl *Ctx);
+
+  enum AbstractDiagSelID {
+    AbstractNone = -1,
+    AbstractReturnType,
+    AbstractParamType,
+    AbstractVariableType,
+    AbstractFieldType
+  };
+
+  bool RequireNonAbstractType(SourceLocation Loc, QualType T,
+                              const PartialDiagnostic &PD,
+                              const CXXRecordDecl *CurrentRD = 0);
+
+  bool RequireNonAbstractType(SourceLocation Loc, QualType T, unsigned DiagID,
+                              AbstractDiagSelID SelID = AbstractNone,
+                              const CXXRecordDecl *CurrentRD = 0);
+
+  //===--------------------------------------------------------------------===//
+  // C++ Overloaded Operators [C++ 13.5]
+  //
+
+  bool CheckOverloadedOperatorDeclaration(FunctionDecl *FnDecl);
+
+  bool CheckLiteralOperatorDeclaration(FunctionDecl *FnDecl);
+
+  //===--------------------------------------------------------------------===//
+  // C++ Templates [C++ 14]
+  //
+  void LookupTemplateName(LookupResult &R, Scope *S, CXXScopeSpec &SS,
+                          QualType ObjectType, bool EnteringContext);
+
+  virtual TemplateNameKind isTemplateName(Scope *S,
+                                          CXXScopeSpec &SS,
+                                          UnqualifiedId &Name,
+                                          TypeTy *ObjectType,
+                                          bool EnteringContext,
+                                          TemplateTy &Template);
+  
+  virtual bool DiagnoseUnknownTemplateName(const IdentifierInfo &II, 
+                                           SourceLocation IILoc,
+                                           Scope *S,
+                                           const CXXScopeSpec *SS,
+                                           TemplateTy &SuggestedTemplate,
+                                           TemplateNameKind &SuggestedKind);
+    
+  bool DiagnoseTemplateParameterShadow(SourceLocation Loc, Decl *PrevDecl);
+  TemplateDecl *AdjustDeclIfTemplate(DeclPtrTy &Decl);
+
+  virtual DeclPtrTy ActOnTypeParameter(Scope *S, bool Typename, bool Ellipsis,
+                                       SourceLocation EllipsisLoc,
+                                       SourceLocation KeyLoc,
+                                       IdentifierInfo *ParamName,
+                                       SourceLocation ParamNameLoc,
+                                       unsigned Depth, unsigned Position);
+  virtual void ActOnTypeParameterDefault(DeclPtrTy TypeParam,
+                                         SourceLocation EqualLoc,
+                                         SourceLocation DefaultLoc,
+                                         TypeTy *Default);
+
+  QualType CheckNonTypeTemplateParameterType(QualType T, SourceLocation Loc);
+  virtual DeclPtrTy ActOnNonTypeTemplateParameter(Scope *S, Declarator &D,
+                                                  unsigned Depth,
+                                                  unsigned Position);
+  virtual void ActOnNonTypeTemplateParameterDefault(DeclPtrTy TemplateParam,
+                                                    SourceLocation EqualLoc,
+                                                    ExprArg Default);
+  virtual DeclPtrTy ActOnTemplateTemplateParameter(Scope *S,
+                                                   SourceLocation TmpLoc,
+                                                   TemplateParamsTy *Params,
+                                                   IdentifierInfo *ParamName,
+                                                   SourceLocation ParamNameLoc,
+                                                   unsigned Depth,
+                                                   unsigned Position);
+  virtual void ActOnTemplateTemplateParameterDefault(DeclPtrTy TemplateParam,
+                                                     SourceLocation EqualLoc,
+                                        const ParsedTemplateArgument &Default);
+
+  virtual TemplateParamsTy *
+  ActOnTemplateParameterList(unsigned Depth,
+                             SourceLocation ExportLoc,
+                             SourceLocation TemplateLoc,
+                             SourceLocation LAngleLoc,
+                             DeclPtrTy *Params, unsigned NumParams,
+                             SourceLocation RAngleLoc);
+
+  /// \brief The context in which we are checking a template parameter
+  /// list.
+  enum TemplateParamListContext {
+    TPC_ClassTemplate,
+    TPC_FunctionTemplate,
+    TPC_ClassTemplateMember,
+    TPC_FriendFunctionTemplate
+  };
+
+  bool CheckTemplateParameterList(TemplateParameterList *NewParams,
+                                  TemplateParameterList *OldParams,
+                                  TemplateParamListContext TPC);
+  TemplateParameterList *
+  MatchTemplateParametersToScopeSpecifier(SourceLocation DeclStartLoc,
+                                          const CXXScopeSpec &SS,
+                                          TemplateParameterList **ParamLists,
+                                          unsigned NumParamLists,
+                                          bool IsFriend,
+                                          bool &IsExplicitSpecialization);
+
+  DeclResult CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK,
+                                SourceLocation KWLoc, CXXScopeSpec &SS,
+                                IdentifierInfo *Name, SourceLocation NameLoc,
+                                AttributeList *Attr,
+                                TemplateParameterList *TemplateParams,
+                                AccessSpecifier AS);
+
+  void translateTemplateArguments(const ASTTemplateArgsPtr &In,
+                                  TemplateArgumentListInfo &Out);
+    
+  QualType CheckTemplateIdType(TemplateName Template,
+                               SourceLocation TemplateLoc,
+                               const TemplateArgumentListInfo &TemplateArgs);
+
+  virtual TypeResult
+  ActOnTemplateIdType(TemplateTy Template, SourceLocation TemplateLoc,
+                      SourceLocation LAngleLoc,
+                      ASTTemplateArgsPtr TemplateArgs,
+                      SourceLocation RAngleLoc);
+
+  virtual TypeResult ActOnTagTemplateIdType(TypeResult Type,
+                                            TagUseKind TUK,
+                                            DeclSpec::TST TagSpec,
+                                            SourceLocation TagLoc);
+
+  OwningExprResult BuildTemplateIdExpr(const CXXScopeSpec &SS,
+                                       LookupResult &R,
+                                       bool RequiresADL,
+                               const TemplateArgumentListInfo &TemplateArgs);
+  OwningExprResult BuildQualifiedTemplateIdExpr(CXXScopeSpec &SS,
+                                                DeclarationName Name,
+                                                SourceLocation NameLoc,
+                               const TemplateArgumentListInfo &TemplateArgs);
+
+  virtual TemplateTy ActOnDependentTemplateName(SourceLocation TemplateKWLoc,
+                                                CXXScopeSpec &SS,
+                                                UnqualifiedId &Name,
+                                                TypeTy *ObjectType,
+                                                bool EnteringContext);
+
+  bool CheckClassTemplatePartialSpecializationArgs(
+                                        TemplateParameterList *TemplateParams,
+                              const TemplateArgumentListBuilder &TemplateArgs,
+                                        bool &MirrorsPrimaryTemplate);
+
+  virtual DeclResult
+  ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagUseKind TUK,
+                                   SourceLocation KWLoc,
+                                   CXXScopeSpec &SS,
+                                   TemplateTy Template,
+                                   SourceLocation TemplateNameLoc,
+                                   SourceLocation LAngleLoc,
+                                   ASTTemplateArgsPtr TemplateArgs,
+                                   SourceLocation RAngleLoc,
+                                   AttributeList *Attr,
+                                 MultiTemplateParamsArg TemplateParameterLists);
+
+  virtual DeclPtrTy ActOnTemplateDeclarator(Scope *S,
+                                  MultiTemplateParamsArg TemplateParameterLists,
+                                            Declarator &D);
+
+  virtual DeclPtrTy ActOnStartOfFunctionTemplateDef(Scope *FnBodyScope,
+                                                    MultiTemplateParamsArg TemplateParameterLists,
+                                                    Declarator &D);
+
+  bool
+  CheckSpecializationInstantiationRedecl(SourceLocation NewLoc,
+                                         TemplateSpecializationKind NewTSK,
+                                         NamedDecl *PrevDecl,
+                                         TemplateSpecializationKind PrevTSK,
+                                         SourceLocation PrevPointOfInstantiation,
+                                         bool &SuppressNew);
+    
+  bool CheckDependentFunctionTemplateSpecialization(FunctionDecl *FD,
+                    const TemplateArgumentListInfo &ExplicitTemplateArgs,
+                                                    LookupResult &Previous);
+                                                    
+  bool CheckFunctionTemplateSpecialization(FunctionDecl *FD,
+                        const TemplateArgumentListInfo *ExplicitTemplateArgs,
+                                           LookupResult &Previous);
+  bool CheckMemberSpecialization(NamedDecl *Member, LookupResult &Previous);
+    
+  virtual DeclResult
+  ActOnExplicitInstantiation(Scope *S,
+                             SourceLocation ExternLoc,
+                             SourceLocation TemplateLoc,
+                             unsigned TagSpec,
+                             SourceLocation KWLoc,
+                             const CXXScopeSpec &SS,
+                             TemplateTy Template,
+                             SourceLocation TemplateNameLoc,
+                             SourceLocation LAngleLoc,
+                             ASTTemplateArgsPtr TemplateArgs,
+                             SourceLocation RAngleLoc,
+                             AttributeList *Attr);
+
+  virtual DeclResult
+  ActOnExplicitInstantiation(Scope *S,
+                             SourceLocation ExternLoc,
+                             SourceLocation TemplateLoc,
+                             unsigned TagSpec,
+                             SourceLocation KWLoc,
+                             CXXScopeSpec &SS,
+                             IdentifierInfo *Name,
+                             SourceLocation NameLoc,
+                             AttributeList *Attr);
+
+  virtual DeclResult ActOnExplicitInstantiation(Scope *S,
+                                                SourceLocation ExternLoc,
+                                                SourceLocation TemplateLoc,
+                                                Declarator &D);
+    
+  TemplateArgumentLoc 
+  SubstDefaultTemplateArgumentIfAvailable(TemplateDecl *Template,
+                                          SourceLocation TemplateLoc,
+                                          SourceLocation RAngleLoc,
+                                          Decl *Param,
+                                      TemplateArgumentListBuilder &Converted);
+
+  /// \brief Specifies the context in which a particular template
+  /// argument is being checked.
+  enum CheckTemplateArgumentKind {
+    /// \brief The template argument was specified in the code or was
+    /// instantiated with some deduced template arguments.
+    CTAK_Specified,
+
+    /// \brief The template argument was deduced via template argument
+    /// deduction.
+    CTAK_Deduced,
+
+    /// \brief The template argument was deduced from an array bound
+    /// via template argument deduction.
+    CTAK_DeducedFromArrayBound
+  };
+
+  bool CheckTemplateArgument(NamedDecl *Param,
+                             const TemplateArgumentLoc &Arg,
+                             TemplateDecl *Template,
+                             SourceLocation TemplateLoc,
+                             SourceLocation RAngleLoc,
+                             TemplateArgumentListBuilder &Converted,
+                             CheckTemplateArgumentKind CTAK = CTAK_Specified);
+  
+  bool CheckTemplateArgumentList(TemplateDecl *Template,
+                                 SourceLocation TemplateLoc,
+                                 const TemplateArgumentListInfo &TemplateArgs,
+                                 bool PartialTemplateArgs,
+                                 TemplateArgumentListBuilder &Converted);
+
+  bool CheckTemplateTypeArgument(TemplateTypeParmDecl *Param,
+                                 const TemplateArgumentLoc &Arg,
+                                 TemplateArgumentListBuilder &Converted);
+
+  bool CheckTemplateArgument(TemplateTypeParmDecl *Param,
+                             TypeSourceInfo *Arg);
+  bool CheckTemplateArgumentPointerToMember(Expr *Arg, 
+                                            TemplateArgument &Converted);
+  bool CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
+                             QualType InstantiatedParamType, Expr *&Arg,
+                             TemplateArgument &Converted,
+                             CheckTemplateArgumentKind CTAK = CTAK_Specified);
+  bool CheckTemplateArgument(TemplateTemplateParmDecl *Param, 
+                             const TemplateArgumentLoc &Arg);
+
+  OwningExprResult 
+  BuildExpressionFromDeclTemplateArgument(const TemplateArgument &Arg,
+                                          QualType ParamType,
+                                          SourceLocation Loc);
+  OwningExprResult 
+  BuildExpressionFromIntegralTemplateArgument(const TemplateArgument &Arg,
+                                              SourceLocation Loc);
+  
+  /// \brief Enumeration describing how template parameter lists are compared
+  /// for equality.
+  enum TemplateParameterListEqualKind {
+    /// \brief We are matching the template parameter lists of two templates
+    /// that might be redeclarations.
+    ///
+    /// \code
+    /// template<typename T> struct X;
+    /// template<typename T> struct X;
+    /// \endcode
+    TPL_TemplateMatch,
+    
+    /// \brief We are matching the template parameter lists of two template
+    /// template parameters as part of matching the template parameter lists
+    /// of two templates that might be redeclarations.
+    ///
+    /// \code
+    /// template<template<int I> class TT> struct X;
+    /// template<template<int Value> class Other> struct X;
+    /// \endcode
+    TPL_TemplateTemplateParmMatch,
+    
+    /// \brief We are matching the template parameter lists of a template
+    /// template argument against the template parameter lists of a template
+    /// template parameter.
+    ///
+    /// \code
+    /// template<template<int Value> class Metafun> struct X;
+    /// template<int Value> struct integer_c;
+    /// X<integer_c> xic;
+    /// \endcode
+    TPL_TemplateTemplateArgumentMatch
+  };
+  
+  bool TemplateParameterListsAreEqual(TemplateParameterList *New,
+                                      TemplateParameterList *Old,
+                                      bool Complain,
+                                      TemplateParameterListEqualKind Kind,
+                                      SourceLocation TemplateArgLoc
+                                        = SourceLocation());
+
+  bool CheckTemplateDeclScope(Scope *S, TemplateParameterList *TemplateParams);
+
+  /// \brief Called when the parser has parsed a C++ typename
+  /// specifier, e.g., "typename T::type".
+  ///
+  /// \param TypenameLoc the location of the 'typename' keyword
+  /// \param SS the nested-name-specifier following the typename (e.g., 'T::').
+  /// \param II the identifier we're retrieving (e.g., 'type' in the example).
+  /// \param IdLoc the location of the identifier.
+  virtual TypeResult
+  ActOnTypenameType(SourceLocation TypenameLoc, const CXXScopeSpec &SS,
+                    const IdentifierInfo &II, SourceLocation IdLoc);
+
+  /// \brief Called when the parser has parsed a C++ typename
+  /// specifier that ends in a template-id, e.g.,
+  /// "typename MetaFun::template apply<T1, T2>".
+  ///
+  /// \param TypenameLoc the location of the 'typename' keyword
+  /// \param SS the nested-name-specifier following the typename (e.g., 'T::').
+  /// \param TemplateLoc the location of the 'template' keyword, if any.
+  /// \param Ty the type that the typename specifier refers to.
+  virtual TypeResult
+  ActOnTypenameType(SourceLocation TypenameLoc, const CXXScopeSpec &SS,
+                    SourceLocation TemplateLoc, TypeTy *Ty);
+
+  QualType CheckTypenameType(ElaboratedTypeKeyword Keyword,
+                             NestedNameSpecifier *NNS,
+                             const IdentifierInfo &II,
+                             SourceRange Range);
+
+  QualType RebuildTypeInCurrentInstantiation(QualType T, SourceLocation Loc,
+                                             DeclarationName Name);
+  void RebuildNestedNameSpecifierInCurrentInstantiation(CXXScopeSpec &SS);
+
+  std::string
+  getTemplateArgumentBindingsText(const TemplateParameterList *Params,
+                                  const TemplateArgumentList &Args);
+
+  std::string
+  getTemplateArgumentBindingsText(const TemplateParameterList *Params,
+                                  const TemplateArgument *Args,
+                                  unsigned NumArgs);
+  
+  /// \brief Describes the result of template argument deduction.
+  ///
+  /// The TemplateDeductionResult enumeration describes the result of
+  /// template argument deduction, as returned from
+  /// DeduceTemplateArguments(). The separate TemplateDeductionInfo
+  /// structure provides additional information about the results of
+  /// template argument deduction, e.g., the deduced template argument
+  /// list (if successful) or the specific template parameters or
+  /// deduced arguments that were involved in the failure.
+  enum TemplateDeductionResult {
+    /// \brief Template argument deduction was successful.
+    TDK_Success = 0,
+    /// \brief Template argument deduction exceeded the maximum template
+    /// instantiation depth (which has already been diagnosed).
+    TDK_InstantiationDepth,
+    /// \brief Template argument deduction did not deduce a value
+    /// for every template parameter.
+    TDK_Incomplete,
+    /// \brief Template argument deduction produced inconsistent
+    /// deduced values for the given template parameter.
+    TDK_Inconsistent,
+    /// \brief Template argument deduction failed due to inconsistent
+    /// cv-qualifiers on a template parameter type that would
+    /// otherwise be deduced, e.g., we tried to deduce T in "const T"
+    /// but were given a non-const "X".
+    TDK_InconsistentQuals,
+    /// \brief Substitution of the deduced template argument values
+    /// resulted in an error.
+    TDK_SubstitutionFailure,
+    /// \brief Substitution of the deduced template argument values
+    /// into a non-deduced context produced a type or value that
+    /// produces a type that does not match the original template
+    /// arguments provided.
+    TDK_NonDeducedMismatch,
+    /// \brief When performing template argument deduction for a function
+    /// template, there were too many call arguments.
+    TDK_TooManyArguments,
+    /// \brief When performing template argument deduction for a function
+    /// template, there were too few call arguments.
+    TDK_TooFewArguments,
+    /// \brief The explicitly-specified template arguments were not valid
+    /// template arguments for the given template.
+    TDK_InvalidExplicitArguments,
+    /// \brief The arguments included an overloaded function name that could
+    /// not be resolved to a suitable function.
+    TDK_FailedOverloadResolution
+  };
+
+  /// \brief Provides information about an attempted template argument
+  /// deduction, whose success or failure was described by a
+  /// TemplateDeductionResult value.
+  class TemplateDeductionInfo {
+    /// \brief The context in which the template arguments are stored.
+    ASTContext &Context;
+
+    /// \brief The deduced template argument list.
+    ///
+    TemplateArgumentList *Deduced;
+
+    /// \brief The source location at which template argument
+    /// deduction is occurring.
+    SourceLocation Loc;
+
+    // do not implement these
+    TemplateDeductionInfo(const TemplateDeductionInfo&);
+    TemplateDeductionInfo &operator=(const TemplateDeductionInfo&);
+
+  public:
+    TemplateDeductionInfo(ASTContext &Context, SourceLocation Loc)
+      : Context(Context), Deduced(0), Loc(Loc) { }
+
+    ~TemplateDeductionInfo() {
+      // FIXME: if (Deduced) Deduced->Destroy(Context);
+    }
+
+    /// \brief Returns the location at which template argument is
+    /// occuring.
+    SourceLocation getLocation() const {
+      return Loc;
+    }
+
+    /// \brief Take ownership of the deduced template argument list.
+    TemplateArgumentList *take() {
+      TemplateArgumentList *Result = Deduced;
+      Deduced = 0;
+      return Result;
+    }
+
+    /// \brief Provide a new template argument list that contains the
+    /// results of template argument deduction.
+    void reset(TemplateArgumentList *NewDeduced) {
+      // FIXME: if (Deduced) Deduced->Destroy(Context);
+      Deduced = NewDeduced;
+    }
+
+    /// \brief The template parameter to which a template argument
+    /// deduction failure refers.
+    ///
+    /// Depending on the result of template argument deduction, this
+    /// template parameter may have different meanings:
+    ///
+    ///   TDK_Incomplete: this is the first template parameter whose
+    ///   corresponding template argument was not deduced.
+    ///
+    ///   TDK_Inconsistent: this is the template parameter for which
+    ///   two different template argument values were deduced.
+    TemplateParameter Param;
+
+    /// \brief The first template argument to which the template
+    /// argument deduction failure refers.
+    ///
+    /// Depending on the result of the template argument deduction,
+    /// this template argument may have different meanings:
+    ///
+    ///   TDK_Inconsistent: this argument is the first value deduced
+    ///   for the corresponding template parameter.
+    ///
+    ///   TDK_SubstitutionFailure: this argument is the template
+    ///   argument we were instantiating when we encountered an error.
+    ///
+    ///   TDK_NonDeducedMismatch: this is the template argument
+    ///   provided in the source code.
+    TemplateArgument FirstArg;
+
+    /// \brief The second template argument to which the template
+    /// argument deduction failure refers.
+    ///
+    /// FIXME: Finish documenting this.
+    TemplateArgument SecondArg;
+  };
+
+  TemplateDeductionResult
+  DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial,
+                          const TemplateArgumentList &TemplateArgs,
+                          TemplateDeductionInfo &Info);
+
+  TemplateDeductionResult
+  SubstituteExplicitTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
+                        const TemplateArgumentListInfo &ExplicitTemplateArgs,
+                      llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced,
+                                 llvm::SmallVectorImpl<QualType> &ParamTypes,
+                                      QualType *FunctionType,
+                                      TemplateDeductionInfo &Info);
+
+  TemplateDeductionResult
+  FinishTemplateArgumentDeduction(FunctionTemplateDecl *FunctionTemplate,
+                      llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced,
+                                  unsigned NumExplicitlySpecified,
+                                  FunctionDecl *&Specialization,
+                                  TemplateDeductionInfo &Info);
+
+  TemplateDeductionResult
+  DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
+                          const TemplateArgumentListInfo *ExplicitTemplateArgs,
+                          Expr **Args, unsigned NumArgs,
+                          FunctionDecl *&Specialization,
+                          TemplateDeductionInfo &Info);
+
+  TemplateDeductionResult
+  DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
+                          const TemplateArgumentListInfo *ExplicitTemplateArgs,
+                          QualType ArgFunctionType,
+                          FunctionDecl *&Specialization,
+                          TemplateDeductionInfo &Info);
+
+  TemplateDeductionResult
+  DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
+                          QualType ToType,
+                          CXXConversionDecl *&Specialization,
+                          TemplateDeductionInfo &Info);
+
+  TemplateDeductionResult
+  DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
+                          const TemplateArgumentListInfo *ExplicitTemplateArgs,
+                          FunctionDecl *&Specialization,
+                          TemplateDeductionInfo &Info);
+
+  FunctionTemplateDecl *getMoreSpecializedTemplate(FunctionTemplateDecl *FT1,
+                                                   FunctionTemplateDecl *FT2,
+                                                   SourceLocation Loc,
+                                           TemplatePartialOrderingContext TPOC);
+  UnresolvedSetIterator getMostSpecialized(UnresolvedSetIterator SBegin,
+                                           UnresolvedSetIterator SEnd,
+                                           TemplatePartialOrderingContext TPOC,
+                                           SourceLocation Loc,
+                                           const PartialDiagnostic &NoneDiag,
+                                           const PartialDiagnostic &AmbigDiag,
+                                        const PartialDiagnostic &CandidateDiag);
+                                   
+  ClassTemplatePartialSpecializationDecl *
+  getMoreSpecializedPartialSpecialization(
+                                  ClassTemplatePartialSpecializationDecl *PS1,
+                                  ClassTemplatePartialSpecializationDecl *PS2,
+                                  SourceLocation Loc);
+  
+  void MarkUsedTemplateParameters(const TemplateArgumentList &TemplateArgs,
+                                  bool OnlyDeduced,
+                                  unsigned Depth,
+                                  llvm::SmallVectorImpl<bool> &Used);
+  void MarkDeducedTemplateParameters(FunctionTemplateDecl *FunctionTemplate,
+                                     llvm::SmallVectorImpl<bool> &Deduced);
+  
+  //===--------------------------------------------------------------------===//
+  // C++ Template Instantiation
+  //
+
+  MultiLevelTemplateArgumentList getTemplateInstantiationArgs(NamedDecl *D,
+                                     const TemplateArgumentList *Innermost = 0,
+                                     bool RelativeToPrimary = false);
+
+  /// \brief A template instantiation that is currently in progress.
+  struct ActiveTemplateInstantiation {
+    /// \brief The kind of template instantiation we are performing
+    enum InstantiationKind {
+      /// We are instantiating a template declaration. The entity is
+      /// the declaration we're instantiating (e.g., a CXXRecordDecl).
+      TemplateInstantiation,
+
+      /// We are instantiating a default argument for a template
+      /// parameter. The Entity is the template, and
+      /// TemplateArgs/NumTemplateArguments provides the template
+      /// arguments as specified.
+      /// FIXME: Use a TemplateArgumentList
+      DefaultTemplateArgumentInstantiation,
+
+      /// We are instantiating a default argument for a function.
+      /// The Entity is the ParmVarDecl, and TemplateArgs/NumTemplateArgs
+      /// provides the template arguments as specified.
+      DefaultFunctionArgumentInstantiation,
+
+      /// We are substituting explicit template arguments provided for
+      /// a function template. The entity is a FunctionTemplateDecl.
+      ExplicitTemplateArgumentSubstitution,
+
+      /// We are substituting template argument determined as part of
+      /// template argument deduction for either a class template
+      /// partial specialization or a function template. The
+      /// Entity is either a ClassTemplatePartialSpecializationDecl or
+      /// a FunctionTemplateDecl.
+      DeducedTemplateArgumentSubstitution,
+      
+      /// We are substituting prior template arguments into a new
+      /// template parameter. The template parameter itself is either a
+      /// NonTypeTemplateParmDecl or a TemplateTemplateParmDecl.
+      PriorTemplateArgumentSubstitution,
+      
+      /// We are checking the validity of a default template argument that
+      /// has been used when naming a template-id.
+      DefaultTemplateArgumentChecking
+    } Kind;
+
+    /// \brief The point of instantiation within the source code.
+    SourceLocation PointOfInstantiation;
+
+    /// \brief The template in which we are performing the instantiation,
+    /// for substitutions of prior template arguments.
+    TemplateDecl *Template;
+    
+    /// \brief The entity that is being instantiated.
+    uintptr_t Entity;
+
+    /// \brief The list of template arguments we are substituting, if they
+    /// are not part of the entity.
+    const TemplateArgument *TemplateArgs;
+
+    /// \brief The number of template arguments in TemplateArgs.
+    unsigned NumTemplateArgs;
+
+    /// \brief The source range that covers the construct that cause
+    /// the instantiation, e.g., the template-id that causes a class
+    /// template instantiation.
+    SourceRange InstantiationRange;
+
+    ActiveTemplateInstantiation()
+      : Kind(TemplateInstantiation), Template(0), Entity(0), TemplateArgs(0), 
+        NumTemplateArgs(0) {}
+
+    /// \brief Determines whether this template is an actual instantiation
+    /// that should be counted toward the maximum instantiation depth.
+    bool isInstantiationRecord() const;
+    
+    friend bool operator==(const ActiveTemplateInstantiation &X,
+                           const ActiveTemplateInstantiation &Y) {
+      if (X.Kind != Y.Kind)
+        return false;
+
+      if (X.Entity != Y.Entity)
+        return false;
+
+      switch (X.Kind) {
+      case TemplateInstantiation:
+        return true;
+
+      case PriorTemplateArgumentSubstitution:
+      case DefaultTemplateArgumentChecking:
+        if (X.Template != Y.Template)
+          return false;
+          
+        // Fall through
+          
+      case DefaultTemplateArgumentInstantiation:
+      case ExplicitTemplateArgumentSubstitution:
+      case DeducedTemplateArgumentSubstitution:
+      case DefaultFunctionArgumentInstantiation:
+        return X.TemplateArgs == Y.TemplateArgs;
+
+      }
+
+      return true;
+    }
+
+    friend bool operator!=(const ActiveTemplateInstantiation &X,
+                           const ActiveTemplateInstantiation &Y) {
+      return !(X == Y);
+    }
+  };
+
+  /// \brief List of active template instantiations.
+  ///
+  /// This vector is treated as a stack. As one template instantiation
+  /// requires another template instantiation, additional
+  /// instantiations are pushed onto the stack up to a
+  /// user-configurable limit LangOptions::InstantiationDepth.
+  llvm::SmallVector<ActiveTemplateInstantiation, 16>
+    ActiveTemplateInstantiations;
+
+  /// \brief The number of ActiveTemplateInstantiation entries in
+  /// \c ActiveTemplateInstantiations that are not actual instantiations and,
+  /// therefore, should not be counted as part of the instantiation depth.
+  unsigned NonInstantiationEntries;
+  
+  /// \brief The last template from which a template instantiation
+  /// error or warning was produced.
+  ///
+  /// This value is used to suppress printing of redundant template
+  /// instantiation backtraces when there are multiple errors in the
+  /// same instantiation. FIXME: Does this belong in Sema? It's tough
+  /// to implement it anywhere else.
+  ActiveTemplateInstantiation LastTemplateInstantiationErrorContext;
+
+  /// \brief A stack object to be created when performing template
+  /// instantiation.
+  ///
+  /// Construction of an object of type \c InstantiatingTemplate
+  /// pushes the current instantiation onto the stack of active
+  /// instantiations. If the size of this stack exceeds the maximum
+  /// number of recursive template instantiations, construction
+  /// produces an error and evaluates true.
+  ///
+  /// Destruction of this object will pop the named instantiation off
+  /// the stack.
+  struct InstantiatingTemplate {
+    /// \brief Note that we are instantiating a class template,
+    /// function template, or a member thereof.
+    InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
+                          Decl *Entity,
+                          SourceRange InstantiationRange = SourceRange());
+
+    /// \brief Note that we are instantiating a default argument in a
+    /// template-id.
+    InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
+                          TemplateDecl *Template,
+                          const TemplateArgument *TemplateArgs,
+                          unsigned NumTemplateArgs,
+                          SourceRange InstantiationRange = SourceRange());
+
+    /// \brief Note that we are instantiating a default argument in a
+    /// template-id.
+    InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
+                          FunctionTemplateDecl *FunctionTemplate,
+                          const TemplateArgument *TemplateArgs,
+                          unsigned NumTemplateArgs,
+                          ActiveTemplateInstantiation::InstantiationKind Kind,
+                          SourceRange InstantiationRange = SourceRange());
+
+    /// \brief Note that we are instantiating as part of template
+    /// argument deduction for a class template partial
+    /// specialization.
+    InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
+                          ClassTemplatePartialSpecializationDecl *PartialSpec,
+                          const TemplateArgument *TemplateArgs,
+                          unsigned NumTemplateArgs,
+                          SourceRange InstantiationRange = SourceRange());
+
+    InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
+                          ParmVarDecl *Param,
+                          const TemplateArgument *TemplateArgs,
+                          unsigned NumTemplateArgs,
+                          SourceRange InstantiationRange = SourceRange());
+
+    /// \brief Note that we are substituting prior template arguments into a
+    /// non-type or template template parameter.
+    InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
+                          TemplateDecl *Template,
+                          NonTypeTemplateParmDecl *Param,
+                          const TemplateArgument *TemplateArgs,
+                          unsigned NumTemplateArgs,
+                          SourceRange InstantiationRange);
+
+    InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
+                          TemplateDecl *Template,
+                          TemplateTemplateParmDecl *Param,
+                          const TemplateArgument *TemplateArgs,
+                          unsigned NumTemplateArgs,
+                          SourceRange InstantiationRange);
+    
+    /// \brief Note that we are checking the default template argument
+    /// against the template parameter for a given template-id.
+    InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
+                          TemplateDecl *Template,
+                          NamedDecl *Param,
+                          const TemplateArgument *TemplateArgs,
+                          unsigned NumTemplateArgs,
+                          SourceRange InstantiationRange);
+    
+    
+    /// \brief Note that we have finished instantiating this template.
+    void Clear();
+
+    ~InstantiatingTemplate() { Clear(); }
+
+    /// \brief Determines whether we have exceeded the maximum
+    /// recursive template instantiations.
+    operator bool() const { return Invalid; }
+
+  private:
+    Sema &SemaRef;
+    bool Invalid;
+
+    bool CheckInstantiationDepth(SourceLocation PointOfInstantiation,
+                                 SourceRange InstantiationRange);
+
+    InstantiatingTemplate(const InstantiatingTemplate&); // not implemented
+
+    InstantiatingTemplate&
+    operator=(const InstantiatingTemplate&); // not implemented
+  };
+
+  void PrintInstantiationStack();
+
+  /// \brief Determines whether we are currently in a context where
+  /// template argument substitution failures are not considered
+  /// errors.
+  ///
+  /// When this routine returns true, the emission of most diagnostics
+  /// will be suppressed and there will be no local error recovery.
+  bool isSFINAEContext() const;
+
+  /// \brief RAII class used to determine whether SFINAE has
+  /// trapped any errors that occur during template argument
+  /// deduction.
+  class SFINAETrap {
+    Sema &SemaRef;
+    unsigned PrevSFINAEErrors;
+  public:
+    explicit SFINAETrap(Sema &SemaRef)
+      : SemaRef(SemaRef), PrevSFINAEErrors(SemaRef.NumSFINAEErrors) { }
+
+    ~SFINAETrap() { SemaRef.NumSFINAEErrors = PrevSFINAEErrors; }
+
+    /// \brief Determine whether any SFINAE errors have been trapped.
+    bool hasErrorOccurred() const {
+      return SemaRef.NumSFINAEErrors > PrevSFINAEErrors;
+    }
+  };
+
+  /// \brief A stack-allocated class that identifies which local
+  /// variable declaration instantiations are present in this scope.
+  ///
+  /// A new instance of this class type will be created whenever we
+  /// instantiate a new function declaration, which will have its own
+  /// set of parameter declarations.
+  class LocalInstantiationScope {
+    /// \brief Reference to the semantic analysis that is performing
+    /// this template instantiation.
+    Sema &SemaRef;
+
+    /// \brief A mapping from local declarations that occur
+    /// within a template to their instantiations.
+    ///
+    /// This mapping is used during instantiation to keep track of,
+    /// e.g., function parameter and variable declarations. For example,
+    /// given:
+    ///
+    /// \code
+    ///   template<typename T> T add(T x, T y) { return x + y; }
+    /// \endcode
+    ///
+    /// when we instantiate add<int>, we will introduce a mapping from
+    /// the ParmVarDecl for 'x' that occurs in the template to the
+    /// instantiated ParmVarDecl for 'x'.
+    llvm::DenseMap<const Decl *, Decl *> LocalDecls;
+
+    /// \brief The outer scope, in which contains local variable
+    /// definitions from some other instantiation (that may not be
+    /// relevant to this particular scope).
+    LocalInstantiationScope *Outer;
+
+    /// \brief Whether we have already exited this scope.
+    bool Exited;
+
+    /// \brief Whether this scope is temporary, meaning that we should
+    /// remove any additions we make once we exit this
+    /// scope. Temporary scopes are always combined with their outer
+    /// scopes.
+    bool Temporary;
+
+    /// \brief List of the declarations that we have added into this
+    /// temporary scope. They will be removed when we exit the
+    /// temporary scope.
+    llvm::SmallVector<const Decl *, 4> AddedTemporaryDecls;
+
+    // This class is non-copyable
+    LocalInstantiationScope(const LocalInstantiationScope &);
+    LocalInstantiationScope &operator=(const LocalInstantiationScope &);
+
+  public:
+    LocalInstantiationScope(Sema &SemaRef, bool CombineWithOuterScope = false,
+                            bool Temporary = false)
+      : SemaRef(SemaRef), Outer(SemaRef.CurrentInstantiationScope), 
+        Exited(false), Temporary(Temporary) {
+      if (!CombineWithOuterScope && !Temporary)
+        SemaRef.CurrentInstantiationScope = this;
+      else
+        assert(SemaRef.CurrentInstantiationScope && 
+               "No outer instantiation scope?");
+    }
+
+    ~LocalInstantiationScope() {
+      if (!Exited) {
+        SemaRef.CurrentInstantiationScope = Outer;
+        for (unsigned I = 0, N = AddedTemporaryDecls.size(); I != N; ++I)
+          LocalDecls.erase(AddedTemporaryDecls[I]);
+      }
+    }
+
+    /// \brief Exit this local instantiation scope early.
+    void Exit() {
+      SemaRef.CurrentInstantiationScope = Outer;
+      LocalDecls.clear();
+      Exited = true;
+    }
+
+    Decl *getInstantiationOf(const Decl *D) {
+      Decl *Result = LocalDecls[D];
+      assert((Result || D->isInvalidDecl()) && 
+             "declaration was not instantiated in this scope!");
+      return Result;
+    }
+
+    VarDecl *getInstantiationOf(const VarDecl *Var) {
+      return cast<VarDecl>(getInstantiationOf(cast<Decl>(Var)));
+    }
+
+    ParmVarDecl *getInstantiationOf(const ParmVarDecl *Var) {
+      return cast<ParmVarDecl>(getInstantiationOf(cast<Decl>(Var)));
+    }
+
+    NonTypeTemplateParmDecl *getInstantiationOf(
+                                          const NonTypeTemplateParmDecl *Var) {
+      return cast<NonTypeTemplateParmDecl>(getInstantiationOf(cast<Decl>(Var)));
+    }
+    
+    void InstantiatedLocal(const Decl *D, Decl *Inst) {
+      Decl *&Stored = LocalDecls[D];
+      assert((!Stored || Stored == Inst) && "Already instantiated this local");
+
+      if (Temporary && !Stored)
+        AddedTemporaryDecls.push_back(D);
+
+      Stored = Inst;
+    }
+  };
+
+  /// \brief The current instantiation scope used to store local
+  /// variables.
+  LocalInstantiationScope *CurrentInstantiationScope;
+
+  /// \brief The number of typos corrected by CorrectTypo.
+  unsigned TyposCorrected;
+
+  /// \brief Worker object for performing CFG-based warnings.
+  sema::AnalysisBasedWarnings AnalysisWarnings;
+
+  /// \brief An entity for which implicit template instantiation is required.
+  ///
+  /// The source location associated with the declaration is the first place in
+  /// the source code where the declaration was "used". It is not necessarily
+  /// the point of instantiation (which will be either before or after the
+  /// namespace-scope declaration that triggered this implicit instantiation),
+  /// However, it is the location that diagnostics should generally refer to,
+  /// because users will need to know what code triggered the instantiation.
+  typedef std::pair<ValueDecl *, SourceLocation> PendingImplicitInstantiation;
+
+  /// \brief The queue of implicit template instantiations that are required
+  /// but have not yet been performed.
+  std::deque<PendingImplicitInstantiation> PendingImplicitInstantiations;
+
+  /// \brief The queue of implicit template instantiations that are required
+  /// and must be performed within the current local scope.
+  ///
+  /// This queue is only used for member functions of local classes in
+  /// templates, which must be instantiated in the same scope as their
+  /// enclosing function, so that they can reference function-local
+  /// types, static variables, enumerators, etc.
+  std::deque<PendingImplicitInstantiation> PendingLocalImplicitInstantiations;
+
+  void PerformPendingImplicitInstantiations(bool LocalOnly = false);
+
+  TypeSourceInfo *SubstType(TypeSourceInfo *T,
+                            const MultiLevelTemplateArgumentList &TemplateArgs,
+                            SourceLocation Loc, DeclarationName Entity);
+
+  QualType SubstType(QualType T,
+                     const MultiLevelTemplateArgumentList &TemplateArgs,
+                     SourceLocation Loc, DeclarationName Entity);
+
+  TypeSourceInfo *SubstFunctionDeclType(TypeSourceInfo *T,
+                            const MultiLevelTemplateArgumentList &TemplateArgs,
+                                        SourceLocation Loc,
+                                        DeclarationName Entity);
+  ParmVarDecl *SubstParmVarDecl(ParmVarDecl *D, 
+                            const MultiLevelTemplateArgumentList &TemplateArgs);
+  OwningExprResult SubstExpr(Expr *E,
+                            const MultiLevelTemplateArgumentList &TemplateArgs);
+
+  OwningStmtResult SubstStmt(Stmt *S,
+                            const MultiLevelTemplateArgumentList &TemplateArgs);
+
+  Decl *SubstDecl(Decl *D, DeclContext *Owner,
+                  const MultiLevelTemplateArgumentList &TemplateArgs);
+
+  bool
+  SubstBaseSpecifiers(CXXRecordDecl *Instantiation,
+                      CXXRecordDecl *Pattern,
+                      const MultiLevelTemplateArgumentList &TemplateArgs);
+
+  bool
+  InstantiateClass(SourceLocation PointOfInstantiation,
+                   CXXRecordDecl *Instantiation, CXXRecordDecl *Pattern,
+                   const MultiLevelTemplateArgumentList &TemplateArgs,
+                   TemplateSpecializationKind TSK,
+                   bool Complain = true);
+
+  bool
+  InstantiateClassTemplateSpecialization(SourceLocation PointOfInstantiation,
+                           ClassTemplateSpecializationDecl *ClassTemplateSpec,
+                           TemplateSpecializationKind TSK,
+                           bool Complain = true);
+
+  void InstantiateClassMembers(SourceLocation PointOfInstantiation,
+                               CXXRecordDecl *Instantiation,
+                            const MultiLevelTemplateArgumentList &TemplateArgs,
+                               TemplateSpecializationKind TSK);
+
+  void InstantiateClassTemplateSpecializationMembers(
+                                          SourceLocation PointOfInstantiation,
+                           ClassTemplateSpecializationDecl *ClassTemplateSpec,
+                                                TemplateSpecializationKind TSK);
+
+  NestedNameSpecifier *
+  SubstNestedNameSpecifier(NestedNameSpecifier *NNS,
+                           SourceRange Range,
+                           const MultiLevelTemplateArgumentList &TemplateArgs);
+
+  TemplateName
+  SubstTemplateName(TemplateName Name, SourceLocation Loc,
+                    const MultiLevelTemplateArgumentList &TemplateArgs);
+  bool Subst(const TemplateArgumentLoc &Arg, TemplateArgumentLoc &Result,
+             const MultiLevelTemplateArgumentList &TemplateArgs);
+
+  void InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
+                                     FunctionDecl *Function,
+                                     bool Recursive = false,
+                                     bool DefinitionRequired = false);
+  void InstantiateStaticDataMemberDefinition(
+                                     SourceLocation PointOfInstantiation,
+                                     VarDecl *Var,
+                                     bool Recursive = false,
+                                     bool DefinitionRequired = false);
+
+  void InstantiateMemInitializers(CXXConstructorDecl *New,
+                                  const CXXConstructorDecl *Tmpl,
+                            const MultiLevelTemplateArgumentList &TemplateArgs);
+
+  NamedDecl *FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D,
+                          const MultiLevelTemplateArgumentList &TemplateArgs);
+  DeclContext *FindInstantiatedContext(SourceLocation Loc, DeclContext *DC,
+                          const MultiLevelTemplateArgumentList &TemplateArgs);
+
+  // Objective-C declarations.
+  virtual DeclPtrTy ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
+                                             IdentifierInfo *ClassName,
+                                             SourceLocation ClassLoc,
+                                             IdentifierInfo *SuperName,
+                                             SourceLocation SuperLoc,
+                                             const DeclPtrTy *ProtoRefs,
+                                             unsigned NumProtoRefs,
+                                             const SourceLocation *ProtoLocs,
+                                             SourceLocation EndProtoLoc,
+                                             AttributeList *AttrList);
+
+  virtual DeclPtrTy ActOnCompatiblityAlias(
+                    SourceLocation AtCompatibilityAliasLoc,
+                    IdentifierInfo *AliasName,  SourceLocation AliasLocation,
+                    IdentifierInfo *ClassName, SourceLocation ClassLocation);
+
+  void CheckForwardProtocolDeclarationForCircularDependency(
+    IdentifierInfo *PName,
+    SourceLocation &PLoc, SourceLocation PrevLoc,
+    const ObjCList<ObjCProtocolDecl> &PList);
+
+  virtual DeclPtrTy ActOnStartProtocolInterface(
+                    SourceLocation AtProtoInterfaceLoc,
+                    IdentifierInfo *ProtocolName, SourceLocation ProtocolLoc,
+                    const DeclPtrTy *ProtoRefNames, unsigned NumProtoRefs,
+                    const SourceLocation *ProtoLocs,
+                    SourceLocation EndProtoLoc,
+                    AttributeList *AttrList);
+
+  virtual DeclPtrTy ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc,
+                                                IdentifierInfo *ClassName,
+                                                SourceLocation ClassLoc,
+                                                IdentifierInfo *CategoryName,
+                                                SourceLocation CategoryLoc,
+                                                const DeclPtrTy *ProtoRefs,
+                                                unsigned NumProtoRefs,
+                                                const SourceLocation *ProtoLocs,
+                                                SourceLocation EndProtoLoc);
+
+  virtual DeclPtrTy ActOnStartClassImplementation(
+                    SourceLocation AtClassImplLoc,
+                    IdentifierInfo *ClassName, SourceLocation ClassLoc,
+                    IdentifierInfo *SuperClassname,
+                    SourceLocation SuperClassLoc);
+
+  virtual DeclPtrTy ActOnStartCategoryImplementation(
+                                                  SourceLocation AtCatImplLoc,
+                                                  IdentifierInfo *ClassName,
+                                                  SourceLocation ClassLoc,
+                                                  IdentifierInfo *CatName,
+                                                  SourceLocation CatLoc);
+
+  virtual DeclPtrTy ActOnForwardClassDeclaration(SourceLocation Loc,
+                                                 IdentifierInfo **IdentList,
+                                                 SourceLocation *IdentLocs,
+                                                 unsigned NumElts);
+
+  virtual DeclPtrTy ActOnForwardProtocolDeclaration(SourceLocation AtProtocolLoc,
+                                            const IdentifierLocPair *IdentList,
+                                                  unsigned NumElts,
+                                                  AttributeList *attrList);
+
+  virtual void FindProtocolDeclaration(bool WarnOnDeclarations,
+                                       const IdentifierLocPair *ProtocolId,
+                                       unsigned NumProtocols,
+                                   llvm::SmallVectorImpl<DeclPtrTy> &Protocols);
+
+  /// Ensure attributes are consistent with type.
+  /// \param [in, out] Attributes The attributes to check; they will
+  /// be modified to be consistent with \arg PropertyTy.
+  void CheckObjCPropertyAttributes(DeclPtrTy PropertyPtrTy,
+                                   SourceLocation Loc,
+                                   unsigned &Attributes);
+  void ProcessPropertyDecl(ObjCPropertyDecl *property, ObjCContainerDecl *DC);
+  void DiagnosePropertyMismatch(ObjCPropertyDecl *Property,
+                                ObjCPropertyDecl *SuperProperty,
+                                const IdentifierInfo *Name);
+  void ComparePropertiesInBaseAndSuper(ObjCInterfaceDecl *IDecl);
+
+  void CompareMethodParamsInBaseAndSuper(Decl *IDecl,
+                                         ObjCMethodDecl *MethodDecl,
+                                         bool IsInstance);
+
+  void CompareProperties(Decl *CDecl, DeclPtrTy MergeProtocols);
+
+  void DiagnoseClassExtensionDupMethods(ObjCCategoryDecl *CAT,
+                                        ObjCInterfaceDecl *ID);
+
+  void MatchOneProtocolPropertiesInClass(Decl *CDecl,
+                                         ObjCProtocolDecl *PDecl);
+
+  virtual void ActOnAtEnd(SourceRange AtEnd,
+                          DeclPtrTy classDecl,
+                          DeclPtrTy *allMethods = 0, unsigned allNum = 0,
+                          DeclPtrTy *allProperties = 0, unsigned pNum = 0,
+                          DeclGroupPtrTy *allTUVars = 0, unsigned tuvNum = 0);
+
+  virtual DeclPtrTy ActOnProperty(Scope *S, SourceLocation AtLoc,
+                                  FieldDeclarator &FD, ObjCDeclSpec &ODS,
+                                  Selector GetterSel, Selector SetterSel,
+                                  DeclPtrTy ClassCategory,
+                                  bool *OverridingProperty,
+                                  tok::ObjCKeywordKind MethodImplKind);
+
+  virtual DeclPtrTy ActOnPropertyImplDecl(SourceLocation AtLoc,
+                                          SourceLocation PropertyLoc,
+                                          bool ImplKind,DeclPtrTy ClassImplDecl,
+                                          IdentifierInfo *PropertyId,
+                                          IdentifierInfo *PropertyIvar);
+
+  virtual DeclPtrTy ActOnMethodDeclaration(
+    SourceLocation BeginLoc, // location of the + or -.
+    SourceLocation EndLoc,   // location of the ; or {.
+    tok::TokenKind MethodType,
+    DeclPtrTy ClassDecl, ObjCDeclSpec &ReturnQT, TypeTy *ReturnType,
+    Selector Sel,
+    // optional arguments. The number of types/arguments is obtained
+    // from the Sel.getNumArgs().
+    ObjCArgInfo *ArgInfo,
+    DeclaratorChunk::ParamInfo *CParamInfo, unsigned CNumArgs, // c-style args
+    AttributeList *AttrList, tok::ObjCKeywordKind MethodImplKind,
+    bool isVariadic = false);
+
+  // Helper method for ActOnClassMethod/ActOnInstanceMethod.
+  // Will search "local" class/category implementations for a method decl.
+  // Will also search in class's root looking for instance method.
+  // Returns 0 if no method is found.
+  ObjCMethodDecl *LookupPrivateClassMethod(Selector Sel,
+                                           ObjCInterfaceDecl *CDecl);
+  ObjCMethodDecl *LookupPrivateInstanceMethod(Selector Sel,
+                                              ObjCInterfaceDecl *ClassDecl);
+
+  OwningExprResult
+  HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT,
+                            Expr *BaseExpr,
+                            DeclarationName MemberName,
+                            SourceLocation MemberLoc);
+  
+  virtual OwningExprResult
+  ActOnClassPropertyRefExpr(IdentifierInfo &receiverName,
+                            IdentifierInfo &propertyName,
+                            SourceLocation receiverNameLoc,
+                            SourceLocation propertyNameLoc);
+
+  virtual ObjCMessageKind getObjCMessageKind(Scope *S,
+                                             IdentifierInfo *Name,
+                                             SourceLocation NameLoc,
+                                             bool IsSuper,
+                                             bool HasTrailingDot,
+                                             TypeTy *&ReceiverType);
+
+  virtual OwningExprResult ActOnSuperMessage(Scope *S, SourceLocation SuperLoc,
+                                             Selector Sel,
+                                             SourceLocation LBracLoc,
+                                             SourceLocation SelectorLoc,
+                                             SourceLocation RBracLoc,
+                                             MultiExprArg Args);
+
+  OwningExprResult BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo,
+                                     QualType ReceiverType,
+                                     SourceLocation SuperLoc,
+                                     Selector Sel,
+                                     ObjCMethodDecl *Method,
+                                     SourceLocation LBracLoc, 
+                                     SourceLocation RBracLoc,
+                                     MultiExprArg Args);
+                                     
+  virtual OwningExprResult ActOnClassMessage(Scope *S,
+                                             TypeTy *Receiver,
+                                             Selector Sel,
+                                             SourceLocation LBracLoc, 
+                                             SourceLocation SelectorLoc,
+                                             SourceLocation RBracLoc,
+                                             MultiExprArg Args);
+  
+  OwningExprResult BuildInstanceMessage(ExprArg Receiver,
+                                        QualType ReceiverType,
+                                        SourceLocation SuperLoc,
+                                        Selector Sel,
+                                        ObjCMethodDecl *Method,
+                                        SourceLocation LBracLoc, 
+                                        SourceLocation RBracLoc,
+                                        MultiExprArg Args);
+
+  virtual OwningExprResult ActOnInstanceMessage(Scope *S,
+                                                ExprArg Receiver,
+                                                Selector Sel,
+                                                SourceLocation LBracLoc, 
+                                                SourceLocation SelectorLoc, 
+                                                SourceLocation RBracLoc,
+                                                MultiExprArg Args);
+
+
+  /// ActOnPragmaPack - Called on well formed #pragma pack(...).
+  virtual void ActOnPragmaPack(PragmaPackKind Kind,
+                               IdentifierInfo *Name,
+                               ExprTy *Alignment,
+                               SourceLocation PragmaLoc,
+                               SourceLocation LParenLoc,
+                               SourceLocation RParenLoc);
+
+  /// ActOnPragmaUnused - Called on well-formed '#pragma unused'.
+  virtual void ActOnPragmaUnused(const Token *Identifiers,
+                                 unsigned NumIdentifiers, Scope *curScope,
+                                 SourceLocation PragmaLoc,
+                                 SourceLocation LParenLoc,
+                                 SourceLocation RParenLoc);
+
+  NamedDecl *DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II);
+  void DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W);
+
+  /// ActOnPragmaWeakID - Called on well formed #pragma weak ident.
+  virtual void ActOnPragmaWeakID(IdentifierInfo* WeakName,
+                                 SourceLocation PragmaLoc,
+                                 SourceLocation WeakNameLoc);
+
+  /// ActOnPragmaWeakAlias - Called on well formed #pragma weak ident = ident.
+  virtual void ActOnPragmaWeakAlias(IdentifierInfo* WeakName,
+                                    IdentifierInfo* AliasName,
+                                    SourceLocation PragmaLoc,
+                                    SourceLocation WeakNameLoc,
+                                    SourceLocation AliasNameLoc);
+
+  /// getPragmaPackAlignment() - Return the current alignment as specified by
+  /// the current #pragma pack directive, or 0 if none is currently active.
+  unsigned getPragmaPackAlignment() const;
+
+  /// FreePackedContext - Deallocate and null out PackContext.
+  void FreePackedContext();
+
+  /// ImpCastExprToType - If Expr is not of type 'Type', insert an implicit
+  /// cast.  If there is already an implicit cast, merge into the existing one.
+  /// If isLvalue, the result of the cast is an lvalue.
+  void ImpCastExprToType(Expr *&Expr, QualType Type, CastExpr::CastKind Kind,
+                         bool isLvalue = false,
+                         CXXBaseSpecifierArray BasePath = 
+                          CXXBaseSpecifierArray());
+
+  // UsualUnaryConversions - promotes integers (C99 6.3.1.1p2) and converts
+  // functions and arrays to their respective pointers (C99 6.3.2.1).
+  Expr *UsualUnaryConversions(Expr *&expr);
+
+  // DefaultFunctionArrayConversion - converts functions and arrays
+  // to their respective pointers (C99 6.3.2.1).
+  void DefaultFunctionArrayConversion(Expr *&expr);
+
+  // DefaultFunctionArrayLvalueConversion - converts functions and
+  // arrays to their respective pointers and performs the
+  // lvalue-to-rvalue conversion.
+  void DefaultFunctionArrayLvalueConversion(Expr *&expr);
+
+  // DefaultArgumentPromotion (C99 6.5.2.2p6). Used for function calls that
+  // do not have a prototype. Integer promotions are performed on each
+  // argument, and arguments that have type float are promoted to double.
+  void DefaultArgumentPromotion(Expr *&Expr);
+
+  // Used for emitting the right warning by DefaultVariadicArgumentPromotion
+  enum VariadicCallType {
+    VariadicFunction,
+    VariadicBlock,
+    VariadicMethod,
+    VariadicConstructor,
+    VariadicDoesNotApply
+  };
+
+  /// GatherArgumentsForCall - Collector argument expressions for various
+  /// form of call prototypes.
+  bool GatherArgumentsForCall(SourceLocation CallLoc,
+                              FunctionDecl *FDecl,
+                              const FunctionProtoType *Proto,
+                              unsigned FirstProtoArg,
+                              Expr **Args, unsigned NumArgs,
+                              llvm::SmallVector<Expr *, 8> &AllArgs,
+                              VariadicCallType CallType = VariadicDoesNotApply);
+
+  // DefaultVariadicArgumentPromotion - Like DefaultArgumentPromotion, but
+  // will warn if the resulting type is not a POD type.
+  bool DefaultVariadicArgumentPromotion(Expr *&Expr, VariadicCallType CT);
+
+  // UsualArithmeticConversions - performs the UsualUnaryConversions on it's
+  // operands and then handles various conversions that are common to binary
+  // operators (C99 6.3.1.8). If both operands aren't arithmetic, this
+  // routine returns the first non-arithmetic type found. The client is
+  // responsible for emitting appropriate error diagnostics.
+  QualType UsualArithmeticConversions(Expr *&lExpr, Expr *&rExpr,
+                                      bool isCompAssign = false);
+
+  /// AssignConvertType - All of the 'assignment' semantic checks return this
+  /// enum to indicate whether the assignment was allowed.  These checks are
+  /// done for simple assignments, as well as initialization, return from
+  /// function, argument passing, etc.  The query is phrased in terms of a
+  /// source and destination type.
+  enum AssignConvertType {
+    /// Compatible - the types are compatible according to the standard.
+    Compatible,
+
+    /// PointerToInt - The assignment converts a pointer to an int, which we
+    /// accept as an extension.
+    PointerToInt,
+
+    /// IntToPointer - The assignment converts an int to a pointer, which we
+    /// accept as an extension.
+    IntToPointer,
+
+    /// FunctionVoidPointer - The assignment is between a function pointer and
+    /// void*, which the standard doesn't allow, but we accept as an extension.
+    FunctionVoidPointer,
+
+    /// IncompatiblePointer - The assignment is between two pointers types that
+    /// are not compatible, but we accept them as an extension.
+    IncompatiblePointer,
+
+    /// IncompatiblePointer - The assignment is between two pointers types which
+    /// point to integers which have a different sign, but are otherwise identical.
+    /// This is a subset of the above, but broken out because it's by far the most
+    /// common case of incompatible pointers.
+    IncompatiblePointerSign,
+
+    /// CompatiblePointerDiscardsQualifiers - The assignment discards
+    /// c/v/r qualifiers, which we accept as an extension.
+    CompatiblePointerDiscardsQualifiers,
+    
+    /// IncompatibleNestedPointerQualifiers - The assignment is between two
+    /// nested pointer types, and the qualifiers other than the first two
+    /// levels differ e.g. char ** -> const char **, but we accept them as an 
+    /// extension. 
+    IncompatibleNestedPointerQualifiers,
+
+    /// IncompatibleVectors - The assignment is between two vector types that
+    /// have the same size, which we accept as an extension.
+    IncompatibleVectors,
+
+    /// IntToBlockPointer - The assignment converts an int to a block
+    /// pointer. We disallow this.
+    IntToBlockPointer,
+
+    /// IncompatibleBlockPointer - The assignment is between two block
+    /// pointers types that are not compatible.
+    IncompatibleBlockPointer,
+
+    /// IncompatibleObjCQualifiedId - The assignment is between a qualified
+    /// id type and something else (that is incompatible with it). For example,
+    /// "id <XXX>" = "Foo *", where "Foo *" doesn't implement the XXX protocol.
+    IncompatibleObjCQualifiedId,
+
+    /// Incompatible - We reject this conversion outright, it is invalid to
+    /// represent it in the AST.
+    Incompatible
+  };
+  
+  /// DiagnoseAssignmentResult - Emit a diagnostic, if required, for the
+  /// assignment conversion type specified by ConvTy.  This returns true if the
+  /// conversion was invalid or false if the conversion was accepted.
+  bool DiagnoseAssignmentResult(AssignConvertType ConvTy,
+                                SourceLocation Loc,
+                                QualType DstType, QualType SrcType,
+                                Expr *SrcExpr, AssignmentAction Action,
+                                bool *Complained = 0);
+
+  /// CheckAssignmentConstraints - Perform type checking for assignment,
+  /// argument passing, variable initialization, and function return values.
+  /// This routine is only used by the following two methods. C99 6.5.16.
+  AssignConvertType CheckAssignmentConstraints(QualType lhs, QualType rhs);
+
+  // CheckSingleAssignmentConstraints - Currently used by
+  // CheckAssignmentOperands, and ActOnReturnStmt. Prior to type checking,
+  // this routine performs the default function/array converions.
+  AssignConvertType CheckSingleAssignmentConstraints(QualType lhs,
+                                                     Expr *&rExpr);
+
+  // \brief If the lhs type is a transparent union, check whether we
+  // can initialize the transparent union with the given expression.
+  AssignConvertType CheckTransparentUnionArgumentConstraints(QualType lhs,
+                                                             Expr *&rExpr);
+
+  // Helper function for CheckAssignmentConstraints (C99 6.5.16.1p1)
+  AssignConvertType CheckPointerTypesForAssignment(QualType lhsType,
+                                                   QualType rhsType);
+
+  AssignConvertType CheckObjCPointerTypesForAssignment(QualType lhsType,
+                                                       QualType rhsType);
+
+  // Helper function for CheckAssignmentConstraints involving two
+  // block pointer types.
+  AssignConvertType CheckBlockPointerTypesForAssignment(QualType lhsType,
+                                                        QualType rhsType);
+
+  bool IsStringLiteralToNonConstPointerConversion(Expr *From, QualType ToType);
+
+  bool CheckExceptionSpecCompatibility(Expr *From, QualType ToType);
+
+  bool PerformImplicitConversion(Expr *&From, QualType ToType,
+                                 AssignmentAction Action,
+                                 bool AllowExplicit = false);
+  bool PerformImplicitConversion(Expr *&From, QualType ToType,
+                                 AssignmentAction Action,
+                                 bool AllowExplicit,
+                                 ImplicitConversionSequence& ICS);
+  bool PerformImplicitConversion(Expr *&From, QualType ToType,
+                                 const ImplicitConversionSequence& ICS,
+                                 AssignmentAction Action,
+                                 bool IgnoreBaseAccess = false);
+  bool PerformImplicitConversion(Expr *&From, QualType ToType,
+                                 const StandardConversionSequence& SCS,
+                                 AssignmentAction Action, bool IgnoreBaseAccess);
+
+  /// the following "Check" methods will return a valid/converted QualType
+  /// or a null QualType (indicating an error diagnostic was issued).
+
+  /// type checking binary operators (subroutines of CreateBuiltinBinOp).
+  QualType InvalidOperands(SourceLocation l, Expr *&lex, Expr *&rex);
+  QualType CheckPointerToMemberOperands( // C++ 5.5
+    Expr *&lex, Expr *&rex, SourceLocation OpLoc, bool isIndirect);
+  QualType CheckMultiplyDivideOperands( // C99 6.5.5
+    Expr *&lex, Expr *&rex, SourceLocation OpLoc, bool isCompAssign,
+                                       bool isDivide);
+  QualType CheckRemainderOperands( // C99 6.5.5
+    Expr *&lex, Expr *&rex, SourceLocation OpLoc, bool isCompAssign = false);
+  QualType CheckAdditionOperands( // C99 6.5.6
+    Expr *&lex, Expr *&rex, SourceLocation OpLoc, QualType* CompLHSTy = 0);
+  QualType CheckSubtractionOperands( // C99 6.5.6
+    Expr *&lex, Expr *&rex, SourceLocation OpLoc, QualType* CompLHSTy = 0);
+  QualType CheckShiftOperands( // C99 6.5.7
+    Expr *&lex, Expr *&rex, SourceLocation OpLoc, bool isCompAssign = false);
+  QualType CheckCompareOperands( // C99 6.5.8/9
+    Expr *&lex, Expr *&rex, SourceLocation OpLoc, unsigned Opc, bool isRelational);
+  QualType CheckBitwiseOperands( // C99 6.5.[10...12]
+    Expr *&lex, Expr *&rex, SourceLocation OpLoc, bool isCompAssign = false);
+  QualType CheckLogicalOperands( // C99 6.5.[13,14]
+    Expr *&lex, Expr *&rex, SourceLocation OpLoc);
+  // CheckAssignmentOperands is used for both simple and compound assignment.
+  // For simple assignment, pass both expressions and a null converted type.
+  // For compound assignment, pass both expressions and the converted type.
+  QualType CheckAssignmentOperands( // C99 6.5.16.[1,2]
+    Expr *lex, Expr *&rex, SourceLocation OpLoc, QualType convertedType);
+  QualType CheckCommaOperands( // C99 6.5.17
+    Expr *lex, Expr *&rex, SourceLocation OpLoc);
+  QualType CheckConditionalOperands( // C99 6.5.15
+    Expr *&cond, Expr *&lhs, Expr *&rhs, SourceLocation questionLoc);
+  QualType CXXCheckConditionalOperands( // C++ 5.16
+    Expr *&cond, Expr *&lhs, Expr *&rhs, SourceLocation questionLoc);
+  QualType FindCompositePointerType(SourceLocation Loc, Expr *&E1, Expr *&E2,
+                                    bool *NonStandardCompositeType = 0);
+
+  QualType FindCompositeObjCPointerType(Expr *&LHS, Expr *&RHS,
+                                        SourceLocation questionLoc);
+  
+  /// type checking for vector binary operators.
+  inline QualType CheckVectorOperands(SourceLocation l, Expr *&lex, Expr *&rex);
+  inline QualType CheckVectorCompareOperands(Expr *&lex, Expr *&rx,
+                                             SourceLocation l, bool isRel);
+
+  /// type checking unary operators (subroutines of ActOnUnaryOp).
+  /// C99 6.5.3.1, 6.5.3.2, 6.5.3.4
+  QualType CheckIncrementDecrementOperand(Expr *op, SourceLocation OpLoc,
+                                          bool isInc);
+  QualType CheckAddressOfOperand(Expr *op, SourceLocation OpLoc);
+  QualType CheckIndirectionOperand(Expr *op, SourceLocation OpLoc);
+  QualType CheckRealImagOperand(Expr *&Op, SourceLocation OpLoc, bool isReal);
+
+  /// type checking primary expressions.
+  QualType CheckExtVectorComponent(QualType baseType, SourceLocation OpLoc,
+                                   const IdentifierInfo *Comp,
+                                   SourceLocation CmpLoc);
+
+  /// type checking declaration initializers (C99 6.7.8)
+  bool CheckInitList(const InitializedEntity &Entity,
+                     InitListExpr *&InitList, QualType &DeclType);
+  bool CheckForConstantInitializer(Expr *e, QualType t);
+
+  // type checking C++ declaration initializers (C++ [dcl.init]).
+
+  /// ReferenceCompareResult - Expresses the result of comparing two
+  /// types (cv1 T1 and cv2 T2) to determine their compatibility for the
+  /// purposes of initialization by reference (C++ [dcl.init.ref]p4).
+  enum ReferenceCompareResult {
+    /// Ref_Incompatible - The two types are incompatible, so direct
+    /// reference binding is not possible.
+    Ref_Incompatible = 0,
+    /// Ref_Related - The two types are reference-related, which means
+    /// that their unqualified forms (T1 and T2) are either the same
+    /// or T1 is a base class of T2.
+    Ref_Related,
+    /// Ref_Compatible_With_Added_Qualification - The two types are
+    /// reference-compatible with added qualification, meaning that
+    /// they are reference-compatible and the qualifiers on T1 (cv1)
+    /// are greater than the qualifiers on T2 (cv2).
+    Ref_Compatible_With_Added_Qualification,
+    /// Ref_Compatible - The two types are reference-compatible and
+    /// have equivalent qualifiers (cv1 == cv2).
+    Ref_Compatible
+  };
+
+  ReferenceCompareResult CompareReferenceRelationship(SourceLocation Loc,
+                                                      QualType T1, QualType T2,
+                                                      bool& DerivedToBase);
+
+  /// CheckCastTypes - Check type constraints for casting between types under
+  /// C semantics, or forward to CXXCheckCStyleCast in C++.
+  bool CheckCastTypes(SourceRange TyRange, QualType CastTy, Expr *&CastExpr,
+                      CastExpr::CastKind &Kind, CXXBaseSpecifierArray &BasePath,
+                      bool FunctionalStyle = false);
+
+  // CheckVectorCast - check type constraints for vectors.
+  // Since vectors are an extension, there are no C standard reference for this.
+  // We allow casting between vectors and integer datatypes of the same size.
+  // returns true if the cast is invalid
+  bool CheckVectorCast(SourceRange R, QualType VectorTy, QualType Ty,
+                       CastExpr::CastKind &Kind);
+
+  // CheckExtVectorCast - check type constraints for extended vectors.
+  // Since vectors are an extension, there are no C standard reference for this.
+  // We allow casting between vectors and integer datatypes of the same size,
+  // or vectors and the element type of that vector.
+  // returns true if the cast is invalid
+  bool CheckExtVectorCast(SourceRange R, QualType VectorTy, Expr *&CastExpr,
+                          CastExpr::CastKind &Kind);
+
+  /// CXXCheckCStyleCast - Check constraints of a C-style or function-style
+  /// cast under C++ semantics.
+  bool CXXCheckCStyleCast(SourceRange R, QualType CastTy, Expr *&CastExpr,
+                          CastExpr::CastKind &Kind, 
+                          CXXBaseSpecifierArray &BasePath,
+                          bool FunctionalStyle);
+
+  /// CheckMessageArgumentTypes - Check types in an Obj-C message send.
+  /// \param Method - May be null.
+  /// \param [out] ReturnType - The return type of the send.
+  /// \return true iff there were any incompatible types.
+  bool CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs, Selector Sel,
+                                 ObjCMethodDecl *Method, bool isClassMessage,
+                                 SourceLocation lbrac, SourceLocation rbrac,
+                                 QualType &ReturnType);
+
+  /// CheckBooleanCondition - Diagnose problems involving the use of
+  /// the given expression as a boolean condition (e.g. in an if
+  /// statement).  Also performs the standard function and array
+  /// decays, possibly changing the input variable.
+  ///
+  /// \param Loc - A location associated with the condition, e.g. the
+  /// 'if' keyword.
+  /// \return true iff there were any errors
+  bool CheckBooleanCondition(Expr *&CondExpr, SourceLocation Loc);
+
+  /// DiagnoseAssignmentAsCondition - Given that an expression is
+  /// being used as a boolean condition, warn if it's an assignment.
+  void DiagnoseAssignmentAsCondition(Expr *E);
+
+  /// CheckCXXBooleanCondition - Returns true if conversion to bool is invalid.
+  bool CheckCXXBooleanCondition(Expr *&CondExpr);
+
+  /// ConvertIntegerToTypeWarnOnOverflow - Convert the specified APInt to have
+  /// the specified width and sign.  If an overflow occurs, detect it and emit
+  /// the specified diagnostic.
+  void ConvertIntegerToTypeWarnOnOverflow(llvm::APSInt &OldVal,
+                                          unsigned NewWidth, bool NewSign,
+                                          SourceLocation Loc, unsigned DiagID);
+
+  /// Checks that the Objective-C declaration is declared in the global scope.
+  /// Emits an error and marks the declaration as invalid if it's not declared
+  /// in the global scope.
+  bool CheckObjCDeclScope(Decl *D);
+
+  void InitBuiltinVaListType();
+
+  /// VerifyIntegerConstantExpression - verifies that an expression is an ICE,
+  /// and reports the appropriate diagnostics. Returns false on success.
+  /// Can optionally return the value of the expression.
+  bool VerifyIntegerConstantExpression(const Expr *E, llvm::APSInt *Result = 0);
+
+  /// VerifyBitField - verifies that a bit field expression is an ICE and has
+  /// the correct width, and that the field type is valid.
+  /// Returns false on success.
+  /// Can optionally return whether the bit-field is of width 0
+  bool VerifyBitField(SourceLocation FieldLoc, IdentifierInfo *FieldName,
+                      QualType FieldTy, const Expr *BitWidth,
+                      bool *ZeroWidth = 0);
+
+  /// \name Code completion
+  //@{
+  virtual void CodeCompleteOrdinaryName(Scope *S, 
+                                     CodeCompletionContext CompletionContext);
+  virtual void CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *Base,
+                                               SourceLocation OpLoc,
+                                               bool IsArrow);
+  virtual void CodeCompleteTag(Scope *S, unsigned TagSpec);
+  virtual void CodeCompleteCase(Scope *S);
+  virtual void CodeCompleteCall(Scope *S, ExprTy *Fn,
+                                ExprTy **Args, unsigned NumArgs);
+  virtual void CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
+                                       bool EnteringContext);
+  virtual void CodeCompleteUsing(Scope *S);
+  virtual void CodeCompleteUsingDirective(Scope *S);
+  virtual void CodeCompleteNamespaceDecl(Scope *S);
+  virtual void CodeCompleteNamespaceAliasDecl(Scope *S);
+  virtual void CodeCompleteOperatorName(Scope *S);
+  
+  virtual void CodeCompleteObjCAtDirective(Scope *S, DeclPtrTy ObjCImpDecl,
+                                           bool InInterface);
+  virtual void CodeCompleteObjCAtVisibility(Scope *S);
+  virtual void CodeCompleteObjCAtStatement(Scope *S);
+  virtual void CodeCompleteObjCAtExpression(Scope *S);
+  virtual void CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS);
+  virtual void CodeCompleteObjCPropertyGetter(Scope *S, DeclPtrTy ClassDecl,
+                                              DeclPtrTy *Methods,
+                                              unsigned NumMethods);
+  virtual void CodeCompleteObjCPropertySetter(Scope *S, DeclPtrTy ClassDecl,
+                                              DeclPtrTy *Methods,
+                                              unsigned NumMethods);
+
+  virtual void CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc,
+                                            IdentifierInfo **SelIdents,
+                                            unsigned NumSelIdents);
+  virtual void CodeCompleteObjCClassMessage(Scope *S, TypeTy *Receiver,
+                                            IdentifierInfo **SelIdents, 
+                                            unsigned NumSelIdents);
+  virtual void CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
+                                               IdentifierInfo **SelIdents,
+                                               unsigned NumSelIdents);
+  virtual void CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
+                                                  unsigned NumProtocols);
+  virtual void CodeCompleteObjCProtocolDecl(Scope *S);
+  virtual void CodeCompleteObjCInterfaceDecl(Scope *S);
+  virtual void CodeCompleteObjCSuperclass(Scope *S, 
+                                          IdentifierInfo *ClassName,
+                                          SourceLocation ClassNameLoc);
+  virtual void CodeCompleteObjCImplementationDecl(Scope *S);
+  virtual void CodeCompleteObjCInterfaceCategory(Scope *S, 
+                                                 IdentifierInfo *ClassName,
+                                                 SourceLocation ClassNameLoc);
+  virtual void CodeCompleteObjCImplementationCategory(Scope *S, 
+                                                  IdentifierInfo *ClassName,
+                                                  SourceLocation ClassNameLoc);
+  virtual void CodeCompleteObjCPropertyDefinition(Scope *S, 
+                                                  DeclPtrTy ObjCImpDecl);
+  virtual void CodeCompleteObjCPropertySynthesizeIvar(Scope *S, 
+                                                  IdentifierInfo *PropertyName,
+                                                      DeclPtrTy ObjCImpDecl);
+  virtual void CodeCompleteObjCMethodDecl(Scope *S, 
+                                          bool IsInstanceMethod,
+                                          TypeTy *ReturnType,
+                                          DeclPtrTy IDecl);
+  //@}
+  
+  //===--------------------------------------------------------------------===//
+  // Extra semantic analysis beyond the C type system
+
+public:
+  SourceLocation getLocationOfStringLiteralByte(const StringLiteral *SL,
+                                                unsigned ByteNo) const;
+
+private:
+  bool CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall);
+  bool CheckBlockCall(NamedDecl *NDecl, CallExpr *TheCall);
+
+  bool CheckablePrintfAttr(const FormatAttr *Format, CallExpr *TheCall);
+  bool CheckObjCString(Expr *Arg);
+
+  Action::OwningExprResult CheckBuiltinFunctionCall(unsigned BuiltinID,
+                                                    CallExpr *TheCall);
+  bool SemaBuiltinVAStart(CallExpr *TheCall);
+  bool SemaBuiltinUnorderedCompare(CallExpr *TheCall);
+  bool SemaBuiltinFPClassification(CallExpr *TheCall, unsigned NumArgs);
+
+public:
+  // Used by C++ template instantiation.
+  Action::OwningExprResult SemaBuiltinShuffleVector(CallExpr *TheCall);
+
+private:
+  bool SemaBuiltinPrefetch(CallExpr *TheCall);
+  bool SemaBuiltinObjectSize(CallExpr *TheCall);
+  bool SemaBuiltinLongjmp(CallExpr *TheCall);
+  bool SemaBuiltinAtomicOverloaded(CallExpr *TheCall);
+  bool SemaBuiltinConstantArg(CallExpr *TheCall, int ArgNum,
+                              llvm::APSInt &Result);
+  bool SemaCheckStringLiteral(const Expr *E, const CallExpr *TheCall,
+                              bool HasVAListArg, unsigned format_idx,
+                              unsigned firstDataArg);
+  void CheckPrintfString(const StringLiteral *FExpr, const Expr *OrigFormatExpr,
+                         const CallExpr *TheCall, bool HasVAListArg,
+                         unsigned format_idx, unsigned firstDataArg);
+  void CheckNonNullArguments(const NonNullAttr *NonNull,
+                             const CallExpr *TheCall);
+  void CheckPrintfArguments(const CallExpr *TheCall, bool HasVAListArg,
+                            unsigned format_idx, unsigned firstDataArg);
+  void CheckReturnStackAddr(Expr *RetValExp, QualType lhsType,
+                            SourceLocation ReturnLoc);
+  void CheckFloatComparison(SourceLocation loc, Expr* lex, Expr* rex);
+  void CheckSignCompare(Expr *LHS, Expr *RHS, SourceLocation Loc,
+                        const BinaryOperator::Opcode* BinOpc = 0);
+  void CheckImplicitConversion(Expr *E, QualType Target);
+};
+
+//===--------------------------------------------------------------------===//
+// Typed version of Parser::ExprArg (smart pointer for wrapping Expr pointers).
+template <typename T>
+class ExprOwningPtr : public Action::ExprArg {
+public:
+  ExprOwningPtr(Sema *S, T *expr) : Action::ExprArg(*S, expr) {}
+
+  void reset(T* p) { Action::ExprArg::operator=(p); }
+  T* get() const { return static_cast<T*>(Action::ExprArg::get()); }
+  T* take() { return static_cast<T*>(Action::ExprArg::take()); }
+  T* release() { return take(); }
+
+  T& operator*() const { return *get(); }
+  T* operator->() const { return get(); }
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/lib/Sema/SemaAccess.cpp b/lib/Sema/SemaAccess.cpp
new file mode 100644
index 0000000..30c53ed
--- /dev/null
+++ b/lib/Sema/SemaAccess.cpp
@@ -0,0 +1,1303 @@
+//===---- SemaAccess.cpp - C++ Access Control -------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides Sema routines for C++ access control semantics.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Sema.h"
+#include "SemaInit.h"
+#include "Lookup.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/CXXInheritance.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclFriend.h"
+#include "clang/AST/DependentDiagnostic.h"
+#include "clang/AST/ExprCXX.h"
+
+using namespace clang;
+
+/// A copy of Sema's enum without AR_delayed.
+enum AccessResult {
+  AR_accessible,
+  AR_inaccessible,
+  AR_dependent
+};
+
+/// SetMemberAccessSpecifier - Set the access specifier of a member.
+/// Returns true on error (when the previous member decl access specifier
+/// is different from the new member decl access specifier).
+bool Sema::SetMemberAccessSpecifier(NamedDecl *MemberDecl,
+                                    NamedDecl *PrevMemberDecl,
+                                    AccessSpecifier LexicalAS) {
+  if (!PrevMemberDecl) {
+    // Use the lexical access specifier.
+    MemberDecl->setAccess(LexicalAS);
+    return false;
+  }
+
+  // C++ [class.access.spec]p3: When a member is redeclared its access
+  // specifier must be same as its initial declaration.
+  if (LexicalAS != AS_none && LexicalAS != PrevMemberDecl->getAccess()) {
+    Diag(MemberDecl->getLocation(),
+         diag::err_class_redeclared_with_different_access)
+      << MemberDecl << LexicalAS;
+    Diag(PrevMemberDecl->getLocation(), diag::note_previous_access_declaration)
+      << PrevMemberDecl << PrevMemberDecl->getAccess();
+
+    MemberDecl->setAccess(LexicalAS);
+    return true;
+  }
+
+  MemberDecl->setAccess(PrevMemberDecl->getAccess());
+  return false;
+}
+
+static CXXRecordDecl *FindDeclaringClass(NamedDecl *D) {
+  DeclContext *DC = D->getDeclContext();
+
+  // This can only happen at top: enum decls only "publish" their
+  // immediate members.
+  if (isa<EnumDecl>(DC))
+    DC = cast<EnumDecl>(DC)->getDeclContext();
+
+  CXXRecordDecl *DeclaringClass = cast<CXXRecordDecl>(DC);
+  while (DeclaringClass->isAnonymousStructOrUnion())
+    DeclaringClass = cast<CXXRecordDecl>(DeclaringClass->getDeclContext());
+  return DeclaringClass;
+}
+
+namespace {
+struct EffectiveContext {
+  EffectiveContext() : Inner(0), Dependent(false) {}
+
+  explicit EffectiveContext(DeclContext *DC)
+    : Inner(DC),
+      Dependent(DC->isDependentContext()) {
+
+    // C++ [class.access.nest]p1:
+    //   A nested class is a member and as such has the same access
+    //   rights as any other member.
+    // C++ [class.access]p2:
+    //   A member of a class can also access all the names to which
+    //   the class has access.  A local class of a member function
+    //   may access the same names that the member function itself
+    //   may access.
+    // This almost implies that the privileges of nesting are transitive.
+    // Technically it says nothing about the local classes of non-member
+    // functions (which can gain privileges through friendship), but we
+    // take that as an oversight.
+    while (true) {
+      if (isa<CXXRecordDecl>(DC)) {
+        CXXRecordDecl *Record = cast<CXXRecordDecl>(DC)->getCanonicalDecl();
+        Records.push_back(Record);
+        DC = Record->getDeclContext();
+      } else if (isa<FunctionDecl>(DC)) {
+        FunctionDecl *Function = cast<FunctionDecl>(DC)->getCanonicalDecl();
+        Functions.push_back(Function);
+        DC = Function->getDeclContext();
+      } else if (DC->isFileContext()) {
+        break;
+      } else {
+        DC = DC->getParent();
+      }
+    }
+  }
+
+  bool isDependent() const { return Dependent; }
+
+  bool includesClass(const CXXRecordDecl *R) const {
+    R = R->getCanonicalDecl();
+    return std::find(Records.begin(), Records.end(), R)
+             != Records.end();
+  }
+
+  /// Retrieves the innermost "useful" context.  Can be null if we're
+  /// doing access-control without privileges.
+  DeclContext *getInnerContext() const {
+    return Inner;
+  }
+
+  typedef llvm::SmallVectorImpl<CXXRecordDecl*>::const_iterator record_iterator;
+
+  DeclContext *Inner;
+  llvm::SmallVector<FunctionDecl*, 4> Functions;
+  llvm::SmallVector<CXXRecordDecl*, 4> Records;
+  bool Dependent;
+};
+
+/// Like Sema's AccessedEntity, but kindly lets us scribble all over
+/// it.
+struct AccessTarget : public Sema::AccessedEntity {
+  AccessTarget(const Sema::AccessedEntity &Entity)
+    : AccessedEntity(Entity) {
+    initialize();
+  }
+    
+  AccessTarget(ASTContext &Context, 
+               MemberNonce _,
+               CXXRecordDecl *NamingClass,
+               DeclAccessPair FoundDecl,
+               QualType BaseObjectType)
+    : AccessedEntity(Context, Member, NamingClass, FoundDecl, BaseObjectType) {
+    initialize();
+  }
+
+  AccessTarget(ASTContext &Context, 
+               BaseNonce _,
+               CXXRecordDecl *BaseClass,
+               CXXRecordDecl *DerivedClass,
+               AccessSpecifier Access)
+    : AccessedEntity(Context, Base, BaseClass, DerivedClass, Access) {
+    initialize();
+  }
+
+  bool hasInstanceContext() const {
+    return HasInstanceContext;
+  }
+
+  class SavedInstanceContext {
+  public:
+    ~SavedInstanceContext() {
+      Target.HasInstanceContext = Has;
+    }
+
+  private:
+    friend struct AccessTarget;
+    explicit SavedInstanceContext(AccessTarget &Target)
+      : Target(Target), Has(Target.HasInstanceContext) {}
+    AccessTarget &Target;
+    bool Has;
+  };
+
+  SavedInstanceContext saveInstanceContext() {
+    return SavedInstanceContext(*this);
+  }
+
+  void suppressInstanceContext() {
+    HasInstanceContext = false;
+  }
+
+  const CXXRecordDecl *resolveInstanceContext(Sema &S) const {
+    assert(HasInstanceContext);
+    if (CalculatedInstanceContext)
+      return InstanceContext;
+
+    CalculatedInstanceContext = true;
+    DeclContext *IC = S.computeDeclContext(getBaseObjectType());
+    InstanceContext = (IC ? cast<CXXRecordDecl>(IC)->getCanonicalDecl() : 0);
+    return InstanceContext;
+  }
+
+  const CXXRecordDecl *getDeclaringClass() const {
+    return DeclaringClass;
+  }
+
+private:
+  void initialize() {
+    HasInstanceContext = (isMemberAccess() &&
+                          !getBaseObjectType().isNull() &&
+                          getTargetDecl()->isCXXInstanceMember());
+    CalculatedInstanceContext = false;
+    InstanceContext = 0;
+
+    if (isMemberAccess())
+      DeclaringClass = FindDeclaringClass(getTargetDecl());
+    else
+      DeclaringClass = getBaseClass();
+    DeclaringClass = DeclaringClass->getCanonicalDecl();
+  }
+
+  bool HasInstanceContext : 1;
+  mutable bool CalculatedInstanceContext : 1;
+  mutable const CXXRecordDecl *InstanceContext;
+  const CXXRecordDecl *DeclaringClass;
+};
+
+}
+
+/// Checks whether one class is derived from another, inclusively.
+/// Properly indicates when it couldn't be determined due to
+/// dependence.
+///
+/// This should probably be donated to AST or at least Sema.
+static AccessResult IsDerivedFromInclusive(const CXXRecordDecl *Derived,
+                                           const CXXRecordDecl *Target) {
+  assert(Derived->getCanonicalDecl() == Derived);
+  assert(Target->getCanonicalDecl() == Target);
+
+  if (Derived == Target) return AR_accessible;
+
+  AccessResult OnFailure = AR_inaccessible;
+  llvm::SmallVector<const CXXRecordDecl*, 8> Queue; // actually a stack
+
+  while (true) {
+    for (CXXRecordDecl::base_class_const_iterator
+           I = Derived->bases_begin(), E = Derived->bases_end(); I != E; ++I) {
+
+      const CXXRecordDecl *RD;
+
+      QualType T = I->getType();
+      if (const RecordType *RT = T->getAs<RecordType>()) {
+        RD = cast<CXXRecordDecl>(RT->getDecl());
+      } else {
+        // It's possible for a base class to be the current
+        // instantiation of some enclosing template, but I'm guessing
+        // nobody will ever care that we just dependently delay here.
+        assert(T->isDependentType() && "non-dependent base wasn't a record?");
+        OnFailure = AR_dependent;
+        continue;
+      }
+
+      RD = RD->getCanonicalDecl();
+      if (RD == Target) return AR_accessible;
+      Queue.push_back(RD);
+    }
+
+    if (Queue.empty()) break;
+
+    Derived = Queue.back();
+    Queue.pop_back();
+  }
+
+  return OnFailure;
+}
+
+
+static bool MightInstantiateTo(Sema &S, DeclContext *Context,
+                               DeclContext *Friend) {
+  if (Friend == Context)
+    return true;
+
+  assert(!Friend->isDependentContext() &&
+         "can't handle friends with dependent contexts here");
+
+  if (!Context->isDependentContext())
+    return false;
+
+  if (Friend->isFileContext())
+    return false;
+
+  // TODO: this is very conservative
+  return true;
+}
+
+// Asks whether the type in 'context' can ever instantiate to the type
+// in 'friend'.
+static bool MightInstantiateTo(Sema &S, CanQualType Context, CanQualType Friend) {
+  if (Friend == Context)
+    return true;
+
+  if (!Friend->isDependentType() && !Context->isDependentType())
+    return false;
+
+  // TODO: this is very conservative.
+  return true;
+}
+
+static bool MightInstantiateTo(Sema &S,
+                               FunctionDecl *Context,
+                               FunctionDecl *Friend) {
+  if (Context->getDeclName() != Friend->getDeclName())
+    return false;
+
+  if (!MightInstantiateTo(S,
+                          Context->getDeclContext(),
+                          Friend->getDeclContext()))
+    return false;
+
+  CanQual<FunctionProtoType> FriendTy
+    = S.Context.getCanonicalType(Friend->getType())
+         ->getAs<FunctionProtoType>();
+  CanQual<FunctionProtoType> ContextTy
+    = S.Context.getCanonicalType(Context->getType())
+         ->getAs<FunctionProtoType>();
+
+  // There isn't any way that I know of to add qualifiers
+  // during instantiation.
+  if (FriendTy.getQualifiers() != ContextTy.getQualifiers())
+    return false;
+
+  if (FriendTy->getNumArgs() != ContextTy->getNumArgs())
+    return false;
+
+  if (!MightInstantiateTo(S,
+                          ContextTy->getResultType(),
+                          FriendTy->getResultType()))
+    return false;
+
+  for (unsigned I = 0, E = FriendTy->getNumArgs(); I != E; ++I)
+    if (!MightInstantiateTo(S,
+                            ContextTy->getArgType(I),
+                            FriendTy->getArgType(I)))
+      return false;
+
+  return true;
+}
+
+static bool MightInstantiateTo(Sema &S,
+                               FunctionTemplateDecl *Context,
+                               FunctionTemplateDecl *Friend) {
+  return MightInstantiateTo(S,
+                            Context->getTemplatedDecl(),
+                            Friend->getTemplatedDecl());
+}
+
+static AccessResult MatchesFriend(Sema &S,
+                                  const EffectiveContext &EC,
+                                  const CXXRecordDecl *Friend) {
+  if (EC.includesClass(Friend))
+    return AR_accessible;
+
+  if (EC.isDependent()) {
+    CanQualType FriendTy
+      = S.Context.getCanonicalType(S.Context.getTypeDeclType(Friend));
+
+    for (EffectiveContext::record_iterator
+           I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
+      CanQualType ContextTy
+        = S.Context.getCanonicalType(S.Context.getTypeDeclType(*I));
+      if (MightInstantiateTo(S, ContextTy, FriendTy))
+        return AR_dependent;
+    }
+  }
+
+  return AR_inaccessible;
+}
+
+static AccessResult MatchesFriend(Sema &S,
+                                  const EffectiveContext &EC,
+                                  CanQualType Friend) {
+  if (const RecordType *RT = Friend->getAs<RecordType>())
+    return MatchesFriend(S, EC, cast<CXXRecordDecl>(RT->getDecl()));
+
+  // TODO: we can do better than this
+  if (Friend->isDependentType())
+    return AR_dependent;
+
+  return AR_inaccessible;
+}
+
+/// Determines whether the given friend class template matches
+/// anything in the effective context.
+static AccessResult MatchesFriend(Sema &S,
+                                  const EffectiveContext &EC,
+                                  ClassTemplateDecl *Friend) {
+  AccessResult OnFailure = AR_inaccessible;
+
+  // Check whether the friend is the template of a class in the
+  // context chain.
+  for (llvm::SmallVectorImpl<CXXRecordDecl*>::const_iterator
+         I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
+    CXXRecordDecl *Record = *I;
+
+    // Figure out whether the current class has a template:
+    ClassTemplateDecl *CTD;
+
+    // A specialization of the template...
+    if (isa<ClassTemplateSpecializationDecl>(Record)) {
+      CTD = cast<ClassTemplateSpecializationDecl>(Record)
+        ->getSpecializedTemplate();
+
+    // ... or the template pattern itself.
+    } else {
+      CTD = Record->getDescribedClassTemplate();
+      if (!CTD) continue;
+    }
+
+    // It's a match.
+    if (Friend == CTD->getCanonicalDecl())
+      return AR_accessible;
+
+    // If the context isn't dependent, it can't be a dependent match.
+    if (!EC.isDependent())
+      continue;
+
+    // If the template names don't match, it can't be a dependent
+    // match.  This isn't true in C++0x because of template aliases.
+    if (!S.LangOpts.CPlusPlus0x && CTD->getDeclName() != Friend->getDeclName())
+      continue;
+
+    // If the class's context can't instantiate to the friend's
+    // context, it can't be a dependent match.
+    if (!MightInstantiateTo(S, CTD->getDeclContext(),
+                            Friend->getDeclContext()))
+      continue;
+
+    // Otherwise, it's a dependent match.
+    OnFailure = AR_dependent;
+  }
+
+  return OnFailure;
+}
+
+/// Determines whether the given friend function matches anything in
+/// the effective context.
+static AccessResult MatchesFriend(Sema &S,
+                                  const EffectiveContext &EC,
+                                  FunctionDecl *Friend) {
+  AccessResult OnFailure = AR_inaccessible;
+
+  for (llvm::SmallVectorImpl<FunctionDecl*>::const_iterator
+         I = EC.Functions.begin(), E = EC.Functions.end(); I != E; ++I) {
+    if (Friend == *I)
+      return AR_accessible;
+
+    if (EC.isDependent() && MightInstantiateTo(S, *I, Friend))
+      OnFailure = AR_dependent;
+  }
+
+  return OnFailure;
+}
+
+/// Determines whether the given friend function template matches
+/// anything in the effective context.
+static AccessResult MatchesFriend(Sema &S,
+                                  const EffectiveContext &EC,
+                                  FunctionTemplateDecl *Friend) {
+  if (EC.Functions.empty()) return AR_inaccessible;
+
+  AccessResult OnFailure = AR_inaccessible;
+
+  for (llvm::SmallVectorImpl<FunctionDecl*>::const_iterator
+         I = EC.Functions.begin(), E = EC.Functions.end(); I != E; ++I) {
+
+    FunctionTemplateDecl *FTD = (*I)->getPrimaryTemplate();
+    if (!FTD)
+      FTD = (*I)->getDescribedFunctionTemplate();
+    if (!FTD)
+      continue;
+
+    FTD = FTD->getCanonicalDecl();
+
+    if (Friend == FTD)
+      return AR_accessible;
+
+    if (EC.isDependent() && MightInstantiateTo(S, FTD, Friend))
+      OnFailure = AR_dependent;
+  }
+
+  return OnFailure;
+}
+
+/// Determines whether the given friend declaration matches anything
+/// in the effective context.
+static AccessResult MatchesFriend(Sema &S,
+                                  const EffectiveContext &EC,
+                                  FriendDecl *FriendD) {
+  if (TypeSourceInfo *T = FriendD->getFriendType())
+    return MatchesFriend(S, EC, T->getType()->getCanonicalTypeUnqualified());
+
+  NamedDecl *Friend
+    = cast<NamedDecl>(FriendD->getFriendDecl()->getCanonicalDecl());
+
+  // FIXME: declarations with dependent or templated scope.
+
+  if (isa<ClassTemplateDecl>(Friend))
+    return MatchesFriend(S, EC, cast<ClassTemplateDecl>(Friend));
+
+  if (isa<FunctionTemplateDecl>(Friend))
+    return MatchesFriend(S, EC, cast<FunctionTemplateDecl>(Friend));
+
+  if (isa<CXXRecordDecl>(Friend))
+    return MatchesFriend(S, EC, cast<CXXRecordDecl>(Friend));
+
+  assert(isa<FunctionDecl>(Friend) && "unknown friend decl kind");
+  return MatchesFriend(S, EC, cast<FunctionDecl>(Friend));
+}
+
+static AccessResult GetFriendKind(Sema &S,
+                                  const EffectiveContext &EC,
+                                  const CXXRecordDecl *Class) {
+  AccessResult OnFailure = AR_inaccessible;
+
+  // Okay, check friends.
+  for (CXXRecordDecl::friend_iterator I = Class->friend_begin(),
+         E = Class->friend_end(); I != E; ++I) {
+    FriendDecl *Friend = *I;
+
+    switch (MatchesFriend(S, EC, Friend)) {
+    case AR_accessible:
+      return AR_accessible;
+
+    case AR_inaccessible:
+      continue;
+
+    case AR_dependent:
+      OnFailure = AR_dependent;
+      break;
+    }
+  }
+
+  // That's it, give up.
+  return OnFailure;
+}
+
+static AccessResult HasAccess(Sema &S,
+                              const EffectiveContext &EC,
+                              const CXXRecordDecl *NamingClass,
+                              AccessSpecifier Access,
+                              const AccessTarget &Target) {
+  assert(NamingClass->getCanonicalDecl() == NamingClass &&
+         "declaration should be canonicalized before being passed here");
+
+  if (Access == AS_public) return AR_accessible;
+  assert(Access == AS_private || Access == AS_protected);
+
+  AccessResult OnFailure = AR_inaccessible;
+
+  for (EffectiveContext::record_iterator
+         I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
+    // All the declarations in EC have been canonicalized, so pointer
+    // equality from this point on will work fine.
+    const CXXRecordDecl *ECRecord = *I;
+
+    // [B2] and [M2]
+    if (Access == AS_private) {
+      if (ECRecord == NamingClass)
+        return AR_accessible;
+
+    // [B3] and [M3]
+    } else {
+      assert(Access == AS_protected);
+      switch (IsDerivedFromInclusive(ECRecord, NamingClass)) {
+      case AR_accessible: break;
+      case AR_inaccessible: continue;
+      case AR_dependent: OnFailure = AR_dependent; continue;
+      }
+
+      if (!Target.hasInstanceContext())
+        return AR_accessible;
+
+      const CXXRecordDecl *InstanceContext = Target.resolveInstanceContext(S);
+      if (!InstanceContext) {
+        OnFailure = AR_dependent;
+        continue;
+      }
+
+      // C++ [class.protected]p1:
+      //   An additional access check beyond those described earlier in
+      //   [class.access] is applied when a non-static data member or
+      //   non-static member function is a protected member of its naming
+      //   class.  As described earlier, access to a protected member is
+      //   granted because the reference occurs in a friend or member of
+      //   some class C.  If the access is to form a pointer to member,
+      //   the nested-name-specifier shall name C or a class derived from
+      //   C. All other accesses involve a (possibly implicit) object
+      //   expression. In this case, the class of the object expression
+      //   shall be C or a class derived from C.
+      //
+      // We interpret this as a restriction on [M3].  Most of the
+      // conditions are encoded by not having any instance context.
+      switch (IsDerivedFromInclusive(InstanceContext, ECRecord)) {
+      case AR_accessible: return AR_accessible;
+      case AR_inaccessible: continue;
+      case AR_dependent: OnFailure = AR_dependent; continue;
+      }
+    }
+  }
+
+  if (!NamingClass->hasFriends())
+    return OnFailure;
+
+  // Don't consider friends if we're under the [class.protected]
+  // restriction, above.
+  if (Access == AS_protected && Target.hasInstanceContext()) {
+    const CXXRecordDecl *InstanceContext = Target.resolveInstanceContext(S);
+    if (!InstanceContext) return AR_dependent;
+
+    switch (IsDerivedFromInclusive(InstanceContext, NamingClass)) {
+    case AR_accessible: break;
+    case AR_inaccessible: return OnFailure;
+    case AR_dependent: return AR_dependent;
+    }
+  }
+
+  switch (GetFriendKind(S, EC, NamingClass)) {
+  case AR_accessible: return AR_accessible;
+  case AR_inaccessible: return OnFailure;
+  case AR_dependent: return AR_dependent;
+  }
+
+  // Silence bogus warnings
+  llvm_unreachable("impossible friendship kind");
+  return OnFailure;
+}
+
+/// Finds the best path from the naming class to the declaring class,
+/// taking friend declarations into account.
+///
+/// C++0x [class.access.base]p5:
+///   A member m is accessible at the point R when named in class N if
+///   [M1] m as a member of N is public, or
+///   [M2] m as a member of N is private, and R occurs in a member or
+///        friend of class N, or
+///   [M3] m as a member of N is protected, and R occurs in a member or
+///        friend of class N, or in a member or friend of a class P
+///        derived from N, where m as a member of P is public, private,
+///        or protected, or
+///   [M4] there exists a base class B of N that is accessible at R, and
+///        m is accessible at R when named in class B.
+///
+/// C++0x [class.access.base]p4:
+///   A base class B of N is accessible at R, if
+///   [B1] an invented public member of B would be a public member of N, or
+///   [B2] R occurs in a member or friend of class N, and an invented public
+///        member of B would be a private or protected member of N, or
+///   [B3] R occurs in a member or friend of a class P derived from N, and an
+///        invented public member of B would be a private or protected member
+///        of P, or
+///   [B4] there exists a class S such that B is a base class of S accessible
+///        at R and S is a base class of N accessible at R.
+///
+/// Along a single inheritance path we can restate both of these
+/// iteratively:
+///
+/// First, we note that M1-4 are equivalent to B1-4 if the member is
+/// treated as a notional base of its declaring class with inheritance
+/// access equivalent to the member's access.  Therefore we need only
+/// ask whether a class B is accessible from a class N in context R.
+///
+/// Let B_1 .. B_n be the inheritance path in question (i.e. where
+/// B_1 = N, B_n = B, and for all i, B_{i+1} is a direct base class of
+/// B_i).  For i in 1..n, we will calculate ACAB(i), the access to the
+/// closest accessible base in the path:
+///   Access(a, b) = (* access on the base specifier from a to b *)
+///   Merge(a, forbidden) = forbidden
+///   Merge(a, private) = forbidden
+///   Merge(a, b) = min(a,b)
+///   Accessible(c, forbidden) = false
+///   Accessible(c, private) = (R is c) || IsFriend(c, R)
+///   Accessible(c, protected) = (R derived from c) || IsFriend(c, R)
+///   Accessible(c, public) = true
+///   ACAB(n) = public
+///   ACAB(i) =
+///     let AccessToBase = Merge(Access(B_i, B_{i+1}), ACAB(i+1)) in
+///     if Accessible(B_i, AccessToBase) then public else AccessToBase
+///
+/// B is an accessible base of N at R iff ACAB(1) = public.
+///
+/// \param FinalAccess the access of the "final step", or AS_public if
+///   there is no final step.
+/// \return null if friendship is dependent
+static CXXBasePath *FindBestPath(Sema &S,
+                                 const EffectiveContext &EC,
+                                 AccessTarget &Target,
+                                 AccessSpecifier FinalAccess,
+                                 CXXBasePaths &Paths) {
+  // Derive the paths to the desired base.
+  const CXXRecordDecl *Derived = Target.getNamingClass();
+  const CXXRecordDecl *Base = Target.getDeclaringClass();
+
+  // FIXME: fail correctly when there are dependent paths.
+  bool isDerived = Derived->isDerivedFrom(const_cast<CXXRecordDecl*>(Base),
+                                          Paths);
+  assert(isDerived && "derived class not actually derived from base");
+  (void) isDerived;
+
+  CXXBasePath *BestPath = 0;
+
+  assert(FinalAccess != AS_none && "forbidden access after declaring class");
+
+  bool AnyDependent = false;
+
+  // Derive the friend-modified access along each path.
+  for (CXXBasePaths::paths_iterator PI = Paths.begin(), PE = Paths.end();
+         PI != PE; ++PI) {
+    AccessTarget::SavedInstanceContext _ = Target.saveInstanceContext();
+
+    // Walk through the path backwards.
+    AccessSpecifier PathAccess = FinalAccess;
+    CXXBasePath::iterator I = PI->end(), E = PI->begin();
+    while (I != E) {
+      --I;
+
+      assert(PathAccess != AS_none);
+
+      // If the declaration is a private member of a base class, there
+      // is no level of friendship in derived classes that can make it
+      // accessible.
+      if (PathAccess == AS_private) {
+        PathAccess = AS_none;
+        break;
+      }
+
+      const CXXRecordDecl *NC = I->Class->getCanonicalDecl();
+
+      AccessSpecifier BaseAccess = I->Base->getAccessSpecifier();
+      PathAccess = std::max(PathAccess, BaseAccess);
+
+      switch (HasAccess(S, EC, NC, PathAccess, Target)) {
+      case AR_inaccessible: break;
+      case AR_accessible:
+        PathAccess = AS_public;
+
+        // Future tests are not against members and so do not have
+        // instance context.
+        Target.suppressInstanceContext();
+        break;
+      case AR_dependent:
+        AnyDependent = true;
+        goto Next;
+      }
+    }
+
+    // Note that we modify the path's Access field to the
+    // friend-modified access.
+    if (BestPath == 0 || PathAccess < BestPath->Access) {
+      BestPath = &*PI;
+      BestPath->Access = PathAccess;
+
+      // Short-circuit if we found a public path.
+      if (BestPath->Access == AS_public)
+        return BestPath;
+    }
+
+  Next: ;
+  }
+
+  assert((!BestPath || BestPath->Access != AS_public) &&
+         "fell out of loop with public path");
+
+  // We didn't find a public path, but at least one path was subject
+  // to dependent friendship, so delay the check.
+  if (AnyDependent)
+    return 0;
+
+  return BestPath;
+}
+
+/// Diagnose the path which caused the given declaration or base class
+/// to become inaccessible.
+static void DiagnoseAccessPath(Sema &S,
+                               const EffectiveContext &EC,
+                               AccessTarget &Entity) {
+  AccessSpecifier Access = Entity.getAccess();
+  const CXXRecordDecl *NamingClass = Entity.getNamingClass();
+  NamingClass = NamingClass->getCanonicalDecl();
+
+  NamedDecl *D = (Entity.isMemberAccess() ? Entity.getTargetDecl() : 0);
+  const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass();
+
+  // Easy case: the decl's natural access determined its path access.
+  // We have to check against AS_private here in case Access is AS_none,
+  // indicating a non-public member of a private base class.
+  if (D && (Access == D->getAccess() || D->getAccess() == AS_private)) {
+    switch (HasAccess(S, EC, DeclaringClass, D->getAccess(), Entity)) {
+    case AR_inaccessible: {
+      S.Diag(D->getLocation(), diag::note_access_natural)
+        << (unsigned) (Access == AS_protected)
+        << /*FIXME: not implicitly*/ 0;
+      return;
+    }
+
+    case AR_accessible: break;
+
+    case AR_dependent:
+      llvm_unreachable("can't diagnose dependent access failures");
+      return;
+    }
+  }
+
+  CXXBasePaths Paths;
+  CXXBasePath &Path = *FindBestPath(S, EC, Entity, AS_public, Paths);
+
+  CXXBasePath::iterator I = Path.end(), E = Path.begin();
+  while (I != E) {
+    --I;
+
+    const CXXBaseSpecifier *BS = I->Base;
+    AccessSpecifier BaseAccess = BS->getAccessSpecifier();
+
+    // If this is public inheritance, or the derived class is a friend,
+    // skip this step.
+    if (BaseAccess == AS_public)
+      continue;
+
+    switch (GetFriendKind(S, EC, I->Class)) {
+    case AR_accessible: continue;
+    case AR_inaccessible: break;
+    case AR_dependent:
+      llvm_unreachable("can't diagnose dependent access failures");
+    }
+
+    // Check whether this base specifier is the tighest point
+    // constraining access.  We have to check against AS_private for
+    // the same reasons as above.
+    if (BaseAccess == AS_private || BaseAccess >= Access) {
+
+      // We're constrained by inheritance, but we want to say
+      // "declared private here" if we're diagnosing a hierarchy
+      // conversion and this is the final step.
+      unsigned diagnostic;
+      if (D) diagnostic = diag::note_access_constrained_by_path;
+      else if (I + 1 == Path.end()) diagnostic = diag::note_access_natural;
+      else diagnostic = diag::note_access_constrained_by_path;
+
+      S.Diag(BS->getSourceRange().getBegin(), diagnostic)
+        << BS->getSourceRange()
+        << (BaseAccess == AS_protected)
+        << (BS->getAccessSpecifierAsWritten() == AS_none);
+      return;
+    }
+  }
+
+  llvm_unreachable("access not apparently constrained by path");
+}
+
+static void DiagnoseBadAccess(Sema &S, SourceLocation Loc,
+                              const EffectiveContext &EC,
+                              AccessTarget &Entity) {
+  const CXXRecordDecl *NamingClass = Entity.getNamingClass();
+  const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass();
+  NamedDecl *D = (Entity.isMemberAccess() ? Entity.getTargetDecl() : 0);
+
+  S.Diag(Loc, Entity.getDiag())
+    << (Entity.getAccess() == AS_protected)
+    << (D ? D->getDeclName() : DeclarationName())
+    << S.Context.getTypeDeclType(NamingClass)
+    << S.Context.getTypeDeclType(DeclaringClass);
+  DiagnoseAccessPath(S, EC, Entity);
+}
+
+/// Determines whether the accessed entity is accessible.  Public members
+/// have been weeded out by this point.
+static AccessResult IsAccessible(Sema &S,
+                                 const EffectiveContext &EC,
+                                 AccessTarget &Entity) {
+  // Determine the actual naming class.
+  CXXRecordDecl *NamingClass = Entity.getNamingClass();
+  while (NamingClass->isAnonymousStructOrUnion())
+    NamingClass = cast<CXXRecordDecl>(NamingClass->getParent());
+  NamingClass = NamingClass->getCanonicalDecl();
+
+  AccessSpecifier UnprivilegedAccess = Entity.getAccess();
+  assert(UnprivilegedAccess != AS_public && "public access not weeded out");
+
+  // Before we try to recalculate access paths, try to white-list
+  // accesses which just trade in on the final step, i.e. accesses
+  // which don't require [M4] or [B4]. These are by far the most
+  // common forms of privileged access.
+  if (UnprivilegedAccess != AS_none) {
+    switch (HasAccess(S, EC, NamingClass, UnprivilegedAccess, Entity)) {
+    case AR_dependent:
+      // This is actually an interesting policy decision.  We don't
+      // *have* to delay immediately here: we can do the full access
+      // calculation in the hope that friendship on some intermediate
+      // class will make the declaration accessible non-dependently.
+      // But that's not cheap, and odds are very good (note: assertion
+      // made without data) that the friend declaration will determine
+      // access.
+      return AR_dependent;
+
+    case AR_accessible: return AR_accessible;
+    case AR_inaccessible: break;
+    }
+  }
+
+  AccessTarget::SavedInstanceContext _ = Entity.saveInstanceContext();
+
+  // We lower member accesses to base accesses by pretending that the
+  // member is a base class of its declaring class.
+  AccessSpecifier FinalAccess;
+
+  if (Entity.isMemberAccess()) {
+    // Determine if the declaration is accessible from EC when named
+    // in its declaring class.
+    NamedDecl *Target = Entity.getTargetDecl();
+    const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass();
+
+    FinalAccess = Target->getAccess();
+    switch (HasAccess(S, EC, DeclaringClass, FinalAccess, Entity)) {
+    case AR_accessible:
+      FinalAccess = AS_public;
+      break;
+    case AR_inaccessible: break;
+    case AR_dependent: return AR_dependent; // see above
+    }
+
+    if (DeclaringClass == NamingClass)
+      return (FinalAccess == AS_public ? AR_accessible : AR_inaccessible);
+
+    Entity.suppressInstanceContext();
+  } else {
+    FinalAccess = AS_public;
+  }
+
+  assert(Entity.getDeclaringClass() != NamingClass);
+
+  // Append the declaration's access if applicable.
+  CXXBasePaths Paths;
+  CXXBasePath *Path = FindBestPath(S, EC, Entity, FinalAccess, Paths);
+  if (!Path)
+    return AR_dependent;
+
+  assert(Path->Access <= UnprivilegedAccess &&
+         "access along best path worse than direct?");
+  if (Path->Access == AS_public)
+    return AR_accessible;
+  return AR_inaccessible;
+}
+
+static void DelayDependentAccess(Sema &S,
+                                 const EffectiveContext &EC,
+                                 SourceLocation Loc,
+                                 const AccessTarget &Entity) {
+  assert(EC.isDependent() && "delaying non-dependent access");
+  DeclContext *DC = EC.getInnerContext();
+  assert(DC->isDependentContext() && "delaying non-dependent access");
+  DependentDiagnostic::Create(S.Context, DC, DependentDiagnostic::Access,
+                              Loc,
+                              Entity.isMemberAccess(),
+                              Entity.getAccess(),
+                              Entity.getTargetDecl(),
+                              Entity.getNamingClass(),
+                              Entity.getBaseObjectType(),
+                              Entity.getDiag());
+}
+
+/// Checks access to an entity from the given effective context.
+static AccessResult CheckEffectiveAccess(Sema &S,
+                                         const EffectiveContext &EC,
+                                         SourceLocation Loc,
+                                         AccessTarget &Entity) {
+  assert(Entity.getAccess() != AS_public && "called for public access!");
+
+  switch (IsAccessible(S, EC, Entity)) {
+  case AR_dependent:
+    DelayDependentAccess(S, EC, Loc, Entity);
+    return AR_dependent;
+
+  case AR_inaccessible:
+    if (!Entity.isQuiet())
+      DiagnoseBadAccess(S, Loc, EC, Entity);
+    return AR_inaccessible;
+
+  case AR_accessible:
+    return AR_accessible;
+  }
+
+  // silence unnecessary warning
+  llvm_unreachable("invalid access result");
+  return AR_accessible;
+}
+
+static Sema::AccessResult CheckAccess(Sema &S, SourceLocation Loc,
+                                      AccessTarget &Entity) {
+  // If the access path is public, it's accessible everywhere.
+  if (Entity.getAccess() == AS_public)
+    return Sema::AR_accessible;
+
+  // If we're currently parsing a top-level declaration, delay
+  // diagnostics.  This is the only case where parsing a declaration
+  // can actually change our effective context for the purposes of
+  // access control.
+  if (S.CurContext->isFileContext() && S.ParsingDeclDepth) {
+    S.DelayedDiagnostics.push_back(
+        Sema::DelayedDiagnostic::makeAccess(Loc, Entity));
+    return Sema::AR_delayed;
+  }
+
+  EffectiveContext EC(S.CurContext);
+  switch (CheckEffectiveAccess(S, EC, Loc, Entity)) {
+  case AR_accessible: return Sema::AR_accessible;
+  case AR_inaccessible: return Sema::AR_inaccessible;
+  case AR_dependent: return Sema::AR_dependent;
+  }
+  llvm_unreachable("falling off end");
+  return Sema::AR_accessible;
+}
+
+void Sema::HandleDelayedAccessCheck(DelayedDiagnostic &DD, Decl *Ctx) {
+  // Pretend we did this from the context of the newly-parsed
+  // declaration. If that declaration itself forms a declaration context,
+  // include it in the effective context so that parameters and return types of
+  // befriended functions have that function's access priveledges.
+  DeclContext *DC = Ctx->getDeclContext();
+  if (isa<FunctionDecl>(Ctx))
+    DC = cast<DeclContext>(Ctx);
+  else if (FunctionTemplateDecl *FnTpl = dyn_cast<FunctionTemplateDecl>(Ctx))
+    DC = cast<DeclContext>(FnTpl->getTemplatedDecl());
+  EffectiveContext EC(DC);
+
+  AccessTarget Target(DD.getAccessData());
+
+  if (CheckEffectiveAccess(*this, EC, DD.Loc, Target) == ::AR_inaccessible)
+    DD.Triggered = true;
+}
+
+void Sema::HandleDependentAccessCheck(const DependentDiagnostic &DD,
+                        const MultiLevelTemplateArgumentList &TemplateArgs) {
+  SourceLocation Loc = DD.getAccessLoc();
+  AccessSpecifier Access = DD.getAccess();
+
+  Decl *NamingD = FindInstantiatedDecl(Loc, DD.getAccessNamingClass(),
+                                       TemplateArgs);
+  if (!NamingD) return;
+  Decl *TargetD = FindInstantiatedDecl(Loc, DD.getAccessTarget(),
+                                       TemplateArgs);
+  if (!TargetD) return;
+
+  if (DD.isAccessToMember()) {
+    CXXRecordDecl *NamingClass = cast<CXXRecordDecl>(NamingD);
+    NamedDecl *TargetDecl = cast<NamedDecl>(TargetD);
+    QualType BaseObjectType = DD.getAccessBaseObjectType();
+    if (!BaseObjectType.isNull()) {
+      BaseObjectType = SubstType(BaseObjectType, TemplateArgs, Loc,
+                                 DeclarationName());
+      if (BaseObjectType.isNull()) return;
+    }
+
+    AccessTarget Entity(Context,
+                        AccessTarget::Member,
+                        NamingClass,
+                        DeclAccessPair::make(TargetDecl, Access),
+                        BaseObjectType);
+    Entity.setDiag(DD.getDiagnostic());
+    CheckAccess(*this, Loc, Entity);
+  } else {
+    AccessTarget Entity(Context,
+                        AccessTarget::Base,
+                        cast<CXXRecordDecl>(TargetD),
+                        cast<CXXRecordDecl>(NamingD),
+                        Access);
+    Entity.setDiag(DD.getDiagnostic());
+    CheckAccess(*this, Loc, Entity);
+  }
+}
+
+Sema::AccessResult Sema::CheckUnresolvedLookupAccess(UnresolvedLookupExpr *E,
+                                                     DeclAccessPair Found) {
+  if (!getLangOptions().AccessControl ||
+      !E->getNamingClass() ||
+      Found.getAccess() == AS_public)
+    return AR_accessible;
+
+  AccessTarget Entity(Context, AccessTarget::Member, E->getNamingClass(), 
+                      Found, QualType());
+  Entity.setDiag(diag::err_access) << E->getSourceRange();
+
+  return CheckAccess(*this, E->getNameLoc(), Entity);
+}
+
+/// Perform access-control checking on a previously-unresolved member
+/// access which has now been resolved to a member.
+Sema::AccessResult Sema::CheckUnresolvedMemberAccess(UnresolvedMemberExpr *E,
+                                                     DeclAccessPair Found) {
+  if (!getLangOptions().AccessControl ||
+      Found.getAccess() == AS_public)
+    return AR_accessible;
+
+  QualType BaseType = E->getBaseType();
+  if (E->isArrow())
+    BaseType = BaseType->getAs<PointerType>()->getPointeeType();
+
+  AccessTarget Entity(Context, AccessTarget::Member, E->getNamingClass(),
+                      Found, BaseType);
+  Entity.setDiag(diag::err_access) << E->getSourceRange();
+
+  return CheckAccess(*this, E->getMemberLoc(), Entity);
+}
+
+Sema::AccessResult Sema::CheckDestructorAccess(SourceLocation Loc,
+                                               CXXDestructorDecl *Dtor,
+                                               const PartialDiagnostic &PDiag) {
+  if (!getLangOptions().AccessControl)
+    return AR_accessible;
+
+  // There's never a path involved when checking implicit destructor access.
+  AccessSpecifier Access = Dtor->getAccess();
+  if (Access == AS_public)
+    return AR_accessible;
+
+  CXXRecordDecl *NamingClass = Dtor->getParent();
+  AccessTarget Entity(Context, AccessTarget::Member, NamingClass,
+                      DeclAccessPair::make(Dtor, Access),
+                      QualType());
+  Entity.setDiag(PDiag); // TODO: avoid copy
+
+  return CheckAccess(*this, Loc, Entity);
+}
+
+/// Checks access to a constructor.
+Sema::AccessResult Sema::CheckConstructorAccess(SourceLocation UseLoc,
+                                  CXXConstructorDecl *Constructor,
+                                  const InitializedEntity &Entity,
+                                  AccessSpecifier Access) {
+  if (!getLangOptions().AccessControl ||
+      Access == AS_public)
+    return AR_accessible;
+
+  CXXRecordDecl *NamingClass = Constructor->getParent();
+  AccessTarget AccessEntity(Context, AccessTarget::Member, NamingClass,
+                            DeclAccessPair::make(Constructor, Access),
+                            QualType());
+  switch (Entity.getKind()) {
+  default:
+    AccessEntity.setDiag(diag::err_access_ctor);
+    break;
+
+  case InitializedEntity::EK_Base:
+    AccessEntity.setDiag(PDiag(diag::err_access_base)
+                          << Entity.isInheritedVirtualBase()
+                          << Entity.getBaseSpecifier()->getType()
+                          << getSpecialMember(Constructor));
+    break;
+
+  case InitializedEntity::EK_Member: {
+    const FieldDecl *Field = cast<FieldDecl>(Entity.getDecl());
+    AccessEntity.setDiag(PDiag(diag::err_access_field)
+                          << Field->getType()
+                          << getSpecialMember(Constructor));
+    break;
+  }
+
+  }
+
+  return CheckAccess(*this, UseLoc, AccessEntity);
+}
+
+/// Checks direct (i.e. non-inherited) access to an arbitrary class
+/// member.
+Sema::AccessResult Sema::CheckDirectMemberAccess(SourceLocation UseLoc,
+                                                 NamedDecl *Target,
+                                           const PartialDiagnostic &Diag) {
+  AccessSpecifier Access = Target->getAccess();
+  if (!getLangOptions().AccessControl ||
+      Access == AS_public)
+    return AR_accessible;
+
+  CXXRecordDecl *NamingClass = cast<CXXRecordDecl>(Target->getDeclContext());
+  AccessTarget Entity(Context, AccessTarget::Member, NamingClass,
+                      DeclAccessPair::make(Target, Access),
+                      QualType());
+  Entity.setDiag(Diag);
+  return CheckAccess(*this, UseLoc, Entity);
+}
+                                           
+
+/// Checks access to an overloaded operator new or delete.
+Sema::AccessResult Sema::CheckAllocationAccess(SourceLocation OpLoc,
+                                               SourceRange PlacementRange,
+                                               CXXRecordDecl *NamingClass,
+                                               DeclAccessPair Found) {
+  if (!getLangOptions().AccessControl ||
+      !NamingClass ||
+      Found.getAccess() == AS_public)
+    return AR_accessible;
+
+  AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
+                      QualType());
+  Entity.setDiag(diag::err_access)
+    << PlacementRange;
+
+  return CheckAccess(*this, OpLoc, Entity);
+}
+
+/// Checks access to an overloaded member operator, including
+/// conversion operators.
+Sema::AccessResult Sema::CheckMemberOperatorAccess(SourceLocation OpLoc,
+                                                   Expr *ObjectExpr,
+                                                   Expr *ArgExpr,
+                                                   DeclAccessPair Found) {
+  if (!getLangOptions().AccessControl ||
+      Found.getAccess() == AS_public)
+    return AR_accessible;
+
+  const RecordType *RT = ObjectExpr->getType()->getAs<RecordType>();
+  assert(RT && "found member operator but object expr not of record type");
+  CXXRecordDecl *NamingClass = cast<CXXRecordDecl>(RT->getDecl());
+
+  AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
+                      ObjectExpr->getType());
+  Entity.setDiag(diag::err_access)
+    << ObjectExpr->getSourceRange()
+    << (ArgExpr ? ArgExpr->getSourceRange() : SourceRange());
+
+  return CheckAccess(*this, OpLoc, Entity);
+}
+
+Sema::AccessResult Sema::CheckAddressOfMemberAccess(Expr *OvlExpr,
+                                                    DeclAccessPair Found) {
+  if (!getLangOptions().AccessControl ||
+      Found.getAccess() == AS_none ||
+      Found.getAccess() == AS_public)
+    return AR_accessible;
+
+  OverloadExpr *Ovl = OverloadExpr::find(OvlExpr).getPointer();
+  CXXRecordDecl *NamingClass = Ovl->getNamingClass();
+
+  AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
+                      Context.getTypeDeclType(NamingClass));
+  Entity.setDiag(diag::err_access)
+    << Ovl->getSourceRange();
+
+  return CheckAccess(*this, Ovl->getNameLoc(), Entity);
+}
+
+/// Checks access for a hierarchy conversion.
+///
+/// \param IsBaseToDerived whether this is a base-to-derived conversion (true)
+///     or a derived-to-base conversion (false)
+/// \param ForceCheck true if this check should be performed even if access
+///     control is disabled;  some things rely on this for semantics
+/// \param ForceUnprivileged true if this check should proceed as if the
+///     context had no special privileges
+/// \param ADK controls the kind of diagnostics that are used
+Sema::AccessResult Sema::CheckBaseClassAccess(SourceLocation AccessLoc,
+                                              QualType Base,
+                                              QualType Derived,
+                                              const CXXBasePath &Path,
+                                              unsigned DiagID,
+                                              bool ForceCheck,
+                                              bool ForceUnprivileged) {
+  if (!ForceCheck && !getLangOptions().AccessControl)
+    return AR_accessible;
+
+  if (Path.Access == AS_public)
+    return AR_accessible;
+
+  CXXRecordDecl *BaseD, *DerivedD;
+  BaseD = cast<CXXRecordDecl>(Base->getAs<RecordType>()->getDecl());
+  DerivedD = cast<CXXRecordDecl>(Derived->getAs<RecordType>()->getDecl());
+
+  AccessTarget Entity(Context, AccessTarget::Base, BaseD, DerivedD, 
+                      Path.Access);
+  if (DiagID)
+    Entity.setDiag(DiagID) << Derived << Base;
+
+  if (ForceUnprivileged) {
+    switch (CheckEffectiveAccess(*this, EffectiveContext(),
+                                 AccessLoc, Entity)) {
+    case ::AR_accessible: return Sema::AR_accessible;
+    case ::AR_inaccessible: return Sema::AR_inaccessible;
+    case ::AR_dependent: return Sema::AR_dependent;
+    }
+    llvm_unreachable("unexpected result from CheckEffectiveAccess");
+  }
+  return CheckAccess(*this, AccessLoc, Entity);
+}
+
+/// Checks access to all the declarations in the given result set.
+void Sema::CheckLookupAccess(const LookupResult &R) {
+  assert(getLangOptions().AccessControl
+         && "performing access check without access control");
+  assert(R.getNamingClass() && "performing access check without naming class");
+
+  for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) {
+    if (I.getAccess() != AS_public) {
+      AccessTarget Entity(Context, AccessedEntity::Member,
+                          R.getNamingClass(), I.getPair(),
+                          R.getBaseObjectType());
+      Entity.setDiag(diag::err_access);
+
+      CheckAccess(*this, R.getNameLoc(), Entity);
+    }
+  }
+}
diff --git a/lib/Sema/SemaAttr.cpp b/lib/Sema/SemaAttr.cpp
new file mode 100644
index 0000000..095f537
--- /dev/null
+++ b/lib/Sema/SemaAttr.cpp
@@ -0,0 +1,201 @@
+//===--- SemaAttr.cpp - Semantic Analysis for Attributes ------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements semantic analysis for non-trivial attributes and
+// pragmas.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Sema.h"
+#include "Lookup.h"
+#include "clang/AST/Expr.h"
+using namespace clang;
+
+//===----------------------------------------------------------------------===//
+// Pragma Packed
+//===----------------------------------------------------------------------===//
+
+namespace {
+  /// PragmaPackStack - Simple class to wrap the stack used by #pragma
+  /// pack.
+  class PragmaPackStack {
+    typedef std::vector< std::pair<unsigned, IdentifierInfo*> > stack_ty;
+
+    /// Alignment - The current user specified alignment.
+    unsigned Alignment;
+
+    /// Stack - Entries in the #pragma pack stack, consisting of saved
+    /// alignments and optional names.
+    stack_ty Stack;
+
+  public:
+    PragmaPackStack() : Alignment(0) {}
+
+    void setAlignment(unsigned A) { Alignment = A; }
+    unsigned getAlignment() { return Alignment; }
+
+    /// push - Push the current alignment onto the stack, optionally
+    /// using the given \arg Name for the record, if non-zero.
+    void push(IdentifierInfo *Name) {
+      Stack.push_back(std::make_pair(Alignment, Name));
+    }
+
+    /// pop - Pop a record from the stack and restore the current
+    /// alignment to the previous value. If \arg Name is non-zero then
+    /// the first such named record is popped, otherwise the top record
+    /// is popped. Returns true if the pop succeeded.
+    bool pop(IdentifierInfo *Name);
+  };
+}  // end anonymous namespace.
+
+bool PragmaPackStack::pop(IdentifierInfo *Name) {
+  if (Stack.empty())
+    return false;
+
+  // If name is empty just pop top.
+  if (!Name) {
+    Alignment = Stack.back().first;
+    Stack.pop_back();
+    return true;
+  }
+
+  // Otherwise, find the named record.
+  for (unsigned i = Stack.size(); i != 0; ) {
+    --i;
+    if (Stack[i].second == Name) {
+      // Found it, pop up to and including this record.
+      Alignment = Stack[i].first;
+      Stack.erase(Stack.begin() + i, Stack.end());
+      return true;
+    }
+  }
+
+  return false;
+}
+
+
+/// FreePackedContext - Deallocate and null out PackContext.
+void Sema::FreePackedContext() {
+  delete static_cast<PragmaPackStack*>(PackContext);
+  PackContext = 0;
+}
+
+/// getPragmaPackAlignment() - Return the current alignment as specified by
+/// the current #pragma pack directive, or 0 if none is currently active.
+unsigned Sema::getPragmaPackAlignment() const {
+  if (PackContext)
+    return static_cast<PragmaPackStack*>(PackContext)->getAlignment();
+  return 0;
+}
+
+void Sema::ActOnPragmaPack(PragmaPackKind Kind, IdentifierInfo *Name,
+                           ExprTy *alignment, SourceLocation PragmaLoc,
+                           SourceLocation LParenLoc, SourceLocation RParenLoc) {
+  Expr *Alignment = static_cast<Expr *>(alignment);
+
+  // If specified then alignment must be a "small" power of two.
+  unsigned AlignmentVal = 0;
+  if (Alignment) {
+    llvm::APSInt Val;
+
+    // pack(0) is like pack(), which just works out since that is what
+    // we use 0 for in PackAttr.
+    if (!Alignment->isIntegerConstantExpr(Val, Context) ||
+        !(Val == 0 || Val.isPowerOf2()) ||
+        Val.getZExtValue() > 16) {
+      Diag(PragmaLoc, diag::warn_pragma_pack_invalid_alignment);
+      Alignment->Destroy(Context);
+      return; // Ignore
+    }
+
+    AlignmentVal = (unsigned) Val.getZExtValue();
+  }
+
+  if (PackContext == 0)
+    PackContext = new PragmaPackStack();
+
+  PragmaPackStack *Context = static_cast<PragmaPackStack*>(PackContext);
+
+  switch (Kind) {
+  case Action::PPK_Default: // pack([n])
+    Context->setAlignment(AlignmentVal);
+    break;
+
+  case Action::PPK_Show: // pack(show)
+    // Show the current alignment, making sure to show the right value
+    // for the default.
+    AlignmentVal = Context->getAlignment();
+    // FIXME: This should come from the target.
+    if (AlignmentVal == 0)
+      AlignmentVal = 8;
+    Diag(PragmaLoc, diag::warn_pragma_pack_show) << AlignmentVal;
+    break;
+
+  case Action::PPK_Push: // pack(push [, id] [, [n])
+    Context->push(Name);
+    // Set the new alignment if specified.
+    if (Alignment)
+      Context->setAlignment(AlignmentVal);
+    break;
+
+  case Action::PPK_Pop: // pack(pop [, id] [,  n])
+    // MSDN, C/C++ Preprocessor Reference > Pragma Directives > pack:
+    // "#pragma pack(pop, identifier, n) is undefined"
+    if (Alignment && Name)
+      Diag(PragmaLoc, diag::warn_pragma_pack_pop_identifer_and_alignment);
+
+    // Do the pop.
+    if (!Context->pop(Name)) {
+      // If a name was specified then failure indicates the name
+      // wasn't found. Otherwise failure indicates the stack was
+      // empty.
+      Diag(PragmaLoc, diag::warn_pragma_pack_pop_failed)
+        << (Name ? "no record matching name" : "stack empty");
+
+      // FIXME: Warn about popping named records as MSVC does.
+    } else {
+      // Pop succeeded, set the new alignment if specified.
+      if (Alignment)
+        Context->setAlignment(AlignmentVal);
+    }
+    break;
+
+  default:
+    assert(0 && "Invalid #pragma pack kind.");
+  }
+}
+
+void Sema::ActOnPragmaUnused(const Token *Identifiers, unsigned NumIdentifiers,
+                             Scope *curScope,
+                             SourceLocation PragmaLoc,
+                             SourceLocation LParenLoc,
+                             SourceLocation RParenLoc) {
+
+  for (unsigned i = 0; i < NumIdentifiers; ++i) {
+    const Token &Tok = Identifiers[i];
+    IdentifierInfo *Name = Tok.getIdentifierInfo();
+    LookupResult Lookup(*this, Name, Tok.getLocation(), LookupOrdinaryName);
+    LookupParsedName(Lookup, curScope, NULL, true);
+
+    if (Lookup.empty()) {
+      Diag(PragmaLoc, diag::warn_pragma_unused_undeclared_var)
+        << Name << SourceRange(Tok.getLocation());
+      continue;
+    }
+
+    VarDecl *VD = Lookup.getAsSingle<VarDecl>();
+    if (!VD || !VD->hasLocalStorage()) {
+      Diag(PragmaLoc, diag::warn_pragma_unused_expected_localvar)
+        << Name << SourceRange(Tok.getLocation());
+      continue;
+    }
+
+    VD->addAttr(::new (Context) UnusedAttr());
+  }
+}
diff --git a/lib/Sema/SemaCXXCast.cpp b/lib/Sema/SemaCXXCast.cpp
new file mode 100644
index 0000000..ba7e1ff
--- /dev/null
+++ b/lib/Sema/SemaCXXCast.cpp
@@ -0,0 +1,1261 @@
+//===--- SemaNamedCast.cpp - Semantic Analysis for Named Casts ------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements semantic analysis for C++ named casts.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Sema.h"
+#include "SemaInit.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/CXXInheritance.h"
+#include "clang/Basic/PartialDiagnostic.h"
+#include "llvm/ADT/SmallVector.h"
+#include <set>
+using namespace clang;
+
+enum TryCastResult {
+  TC_NotApplicable, ///< The cast method is not applicable.
+  TC_Success,       ///< The cast method is appropriate and successful.
+  TC_Failed         ///< The cast method is appropriate, but failed. A
+                    ///< diagnostic has been emitted.
+};
+
+enum CastType {
+  CT_Const,       ///< const_cast
+  CT_Static,      ///< static_cast
+  CT_Reinterpret, ///< reinterpret_cast
+  CT_Dynamic,     ///< dynamic_cast
+  CT_CStyle,      ///< (Type)expr
+  CT_Functional   ///< Type(expr)
+};
+
+static void CheckConstCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
+                           const SourceRange &OpRange,
+                           const SourceRange &DestRange);
+static void CheckReinterpretCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
+                                 const SourceRange &OpRange,
+                                 const SourceRange &DestRange,
+                                 CastExpr::CastKind &Kind);
+static void CheckStaticCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
+                            const SourceRange &OpRange,
+                            CastExpr::CastKind &Kind,
+                            CXXBaseSpecifierArray &BasePath);
+static void CheckDynamicCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
+                             const SourceRange &OpRange,
+                             const SourceRange &DestRange,
+                             CastExpr::CastKind &Kind,
+                             CXXBaseSpecifierArray &BasePath);
+
+static bool CastsAwayConstness(Sema &Self, QualType SrcType, QualType DestType);
+
+// The Try functions attempt a specific way of casting. If they succeed, they
+// return TC_Success. If their way of casting is not appropriate for the given
+// arguments, they return TC_NotApplicable and *may* set diag to a diagnostic
+// to emit if no other way succeeds. If their way of casting is appropriate but
+// fails, they return TC_Failed and *must* set diag; they can set it to 0 if
+// they emit a specialized diagnostic.
+// All diagnostics returned by these functions must expect the same three
+// arguments:
+// %0: Cast Type (a value from the CastType enumeration)
+// %1: Source Type
+// %2: Destination Type
+static TryCastResult TryLValueToRValueCast(Sema &Self, Expr *SrcExpr,
+                                           QualType DestType, unsigned &msg);
+static TryCastResult TryStaticReferenceDowncast(Sema &Self, Expr *SrcExpr,
+                                               QualType DestType, bool CStyle,
+                                               const SourceRange &OpRange,
+                                               unsigned &msg,
+                                               CastExpr::CastKind &Kind,
+                                               CXXBaseSpecifierArray &BasePath);
+static TryCastResult TryStaticPointerDowncast(Sema &Self, QualType SrcType,
+                                              QualType DestType, bool CStyle,
+                                              const SourceRange &OpRange,
+                                              unsigned &msg,
+                                              CastExpr::CastKind &Kind,
+                                              CXXBaseSpecifierArray &BasePath);
+static TryCastResult TryStaticDowncast(Sema &Self, CanQualType SrcType,
+                                       CanQualType DestType, bool CStyle,
+                                       const SourceRange &OpRange,
+                                       QualType OrigSrcType,
+                                       QualType OrigDestType, unsigned &msg,
+                                       CastExpr::CastKind &Kind,
+                                       CXXBaseSpecifierArray &BasePath);
+static TryCastResult TryStaticMemberPointerUpcast(Sema &Self, Expr *&SrcExpr,
+                                               QualType SrcType,
+                                               QualType DestType,bool CStyle,
+                                               const SourceRange &OpRange,
+                                               unsigned &msg,
+                                               CastExpr::CastKind &Kind,
+                                               CXXBaseSpecifierArray &BasePath);
+
+static TryCastResult TryStaticImplicitCast(Sema &Self, Expr *&SrcExpr,
+                                           QualType DestType, bool CStyle,
+                                           const SourceRange &OpRange,
+                                           unsigned &msg,
+                                           CastExpr::CastKind &Kind);
+static TryCastResult TryStaticCast(Sema &Self, Expr *&SrcExpr,
+                                   QualType DestType, bool CStyle,
+                                   const SourceRange &OpRange,
+                                   unsigned &msg,
+                                   CastExpr::CastKind &Kind,
+                                   CXXBaseSpecifierArray &BasePath);
+static TryCastResult TryConstCast(Sema &Self, Expr *SrcExpr, QualType DestType,
+                                  bool CStyle, unsigned &msg);
+static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr,
+                                        QualType DestType, bool CStyle,
+                                        const SourceRange &OpRange,
+                                        unsigned &msg,
+                                        CastExpr::CastKind &Kind);
+
+/// ActOnCXXNamedCast - Parse {dynamic,static,reinterpret,const}_cast's.
+Action::OwningExprResult
+Sema::ActOnCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind,
+                        SourceLocation LAngleBracketLoc, TypeTy *Ty,
+                        SourceLocation RAngleBracketLoc,
+                        SourceLocation LParenLoc, ExprArg E,
+                        SourceLocation RParenLoc) {
+  
+  TypeSourceInfo *DestTInfo;
+  QualType DestType = GetTypeFromParser(Ty, &DestTInfo);
+  if (!DestTInfo)
+    DestTInfo = Context.getTrivialTypeSourceInfo(DestType, SourceLocation());
+
+  return BuildCXXNamedCast(OpLoc, Kind, DestTInfo, move(E),
+                           SourceRange(LAngleBracketLoc, RAngleBracketLoc),
+                           SourceRange(LParenLoc, RParenLoc));
+}
+
+Action::OwningExprResult
+Sema::BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind,
+                        TypeSourceInfo *DestTInfo, ExprArg E,
+                        SourceRange AngleBrackets, SourceRange Parens) {
+  Expr *Ex = E.takeAs<Expr>();
+  QualType DestType = DestTInfo->getType();
+
+  SourceRange OpRange(OpLoc, Parens.getEnd());
+  SourceRange DestRange = AngleBrackets;
+
+  // If the type is dependent, we won't do the semantic analysis now.
+  // FIXME: should we check this in a more fine-grained manner?
+  bool TypeDependent = DestType->isDependentType() || Ex->isTypeDependent();
+
+  switch (Kind) {
+  default: assert(0 && "Unknown C++ cast!");
+
+  case tok::kw_const_cast:
+    if (!TypeDependent)
+      CheckConstCast(*this, Ex, DestType, OpRange, DestRange);
+    return Owned(new (Context) CXXConstCastExpr(DestType.getNonReferenceType(),
+                                                Ex, DestTInfo, OpLoc));
+
+  case tok::kw_dynamic_cast: {
+    CastExpr::CastKind Kind = CastExpr::CK_Unknown;
+    CXXBaseSpecifierArray BasePath;
+    if (!TypeDependent)
+      CheckDynamicCast(*this, Ex, DestType, OpRange, DestRange, Kind, BasePath);
+    return Owned(new (Context)CXXDynamicCastExpr(DestType.getNonReferenceType(),
+                                                 Kind, Ex, BasePath, DestTInfo,
+                                                 OpLoc));
+  }
+  case tok::kw_reinterpret_cast: {
+    CastExpr::CastKind Kind = CastExpr::CK_Unknown;
+    if (!TypeDependent)
+      CheckReinterpretCast(*this, Ex, DestType, OpRange, DestRange, Kind);
+    return Owned(new (Context) CXXReinterpretCastExpr(
+                                  DestType.getNonReferenceType(),
+                                  Kind, Ex, CXXBaseSpecifierArray(), 
+                                  DestTInfo, OpLoc));
+  }
+  case tok::kw_static_cast: {
+    CastExpr::CastKind Kind = CastExpr::CK_Unknown;
+    CXXBaseSpecifierArray BasePath;
+    if (!TypeDependent)
+      CheckStaticCast(*this, Ex, DestType, OpRange, Kind, BasePath);
+    
+    return Owned(new (Context) CXXStaticCastExpr(DestType.getNonReferenceType(),
+                                                 Kind, Ex, BasePath,
+                                                 DestTInfo, OpLoc));
+  }
+  }
+
+  return ExprError();
+}
+
+/// UnwrapDissimilarPointerTypes - Like Sema::UnwrapSimilarPointerTypes,
+/// this removes one level of indirection from both types, provided that they're
+/// the same kind of pointer (plain or to-member). Unlike the Sema function,
+/// this one doesn't care if the two pointers-to-member don't point into the
+/// same class. This is because CastsAwayConstness doesn't care.
+bool UnwrapDissimilarPointerTypes(QualType& T1, QualType& T2) {
+  const PointerType *T1PtrType = T1->getAs<PointerType>(),
+                    *T2PtrType = T2->getAs<PointerType>();
+  if (T1PtrType && T2PtrType) {
+    T1 = T1PtrType->getPointeeType();
+    T2 = T2PtrType->getPointeeType();
+    return true;
+  }
+  const ObjCObjectPointerType *T1ObjCPtrType = 
+                                            T1->getAs<ObjCObjectPointerType>(),
+                              *T2ObjCPtrType = 
+                                            T2->getAs<ObjCObjectPointerType>();
+  if (T1ObjCPtrType) {
+    if (T2ObjCPtrType) {
+      T1 = T1ObjCPtrType->getPointeeType();
+      T2 = T2ObjCPtrType->getPointeeType();
+      return true;
+    }
+    else if (T2PtrType) {
+      T1 = T1ObjCPtrType->getPointeeType();
+      T2 = T2PtrType->getPointeeType();
+      return true;
+    }
+  }
+  else if (T2ObjCPtrType) {
+    if (T1PtrType) {
+      T2 = T2ObjCPtrType->getPointeeType();
+      T1 = T1PtrType->getPointeeType();
+      return true;
+    }
+  }
+  
+  const MemberPointerType *T1MPType = T1->getAs<MemberPointerType>(),
+                          *T2MPType = T2->getAs<MemberPointerType>();
+  if (T1MPType && T2MPType) {
+    T1 = T1MPType->getPointeeType();
+    T2 = T2MPType->getPointeeType();
+    return true;
+  }
+  return false;
+}
+
+/// CastsAwayConstness - Check if the pointer conversion from SrcType to
+/// DestType casts away constness as defined in C++ 5.2.11p8ff. This is used by
+/// the cast checkers.  Both arguments must denote pointer (possibly to member)
+/// types.
+static bool
+CastsAwayConstness(Sema &Self, QualType SrcType, QualType DestType) {
+  // Casting away constness is defined in C++ 5.2.11p8 with reference to
+  // C++ 4.4. We piggyback on Sema::IsQualificationConversion for this, since
+  // the rules are non-trivial. So first we construct Tcv *...cv* as described
+  // in C++ 5.2.11p8.
+  assert((SrcType->isAnyPointerType() || SrcType->isMemberPointerType()) &&
+         "Source type is not pointer or pointer to member.");
+  assert((DestType->isAnyPointerType() || DestType->isMemberPointerType()) &&
+         "Destination type is not pointer or pointer to member.");
+
+  QualType UnwrappedSrcType = Self.Context.getCanonicalType(SrcType), 
+           UnwrappedDestType = Self.Context.getCanonicalType(DestType);
+  llvm::SmallVector<Qualifiers, 8> cv1, cv2;
+
+  // Find the qualifications.
+  while (UnwrapDissimilarPointerTypes(UnwrappedSrcType, UnwrappedDestType)) {
+    cv1.push_back(UnwrappedSrcType.getQualifiers());
+    cv2.push_back(UnwrappedDestType.getQualifiers());
+  }
+  assert(cv1.size() > 0 && "Must have at least one pointer level.");
+
+  // Construct void pointers with those qualifiers (in reverse order of
+  // unwrapping, of course).
+  QualType SrcConstruct = Self.Context.VoidTy;
+  QualType DestConstruct = Self.Context.VoidTy;
+  ASTContext &Context = Self.Context;
+  for (llvm::SmallVector<Qualifiers, 8>::reverse_iterator i1 = cv1.rbegin(),
+                                                          i2 = cv2.rbegin();
+       i1 != cv1.rend(); ++i1, ++i2) {
+    SrcConstruct
+      = Context.getPointerType(Context.getQualifiedType(SrcConstruct, *i1));
+    DestConstruct
+      = Context.getPointerType(Context.getQualifiedType(DestConstruct, *i2));
+  }
+
+  // Test if they're compatible.
+  return SrcConstruct != DestConstruct &&
+    !Self.IsQualificationConversion(SrcConstruct, DestConstruct);
+}
+
+/// CheckDynamicCast - Check that a dynamic_cast\<DestType\>(SrcExpr) is valid.
+/// Refer to C++ 5.2.7 for details. Dynamic casts are used mostly for runtime-
+/// checked downcasts in class hierarchies.
+static void
+CheckDynamicCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
+                 const SourceRange &OpRange,
+                 const SourceRange &DestRange, CastExpr::CastKind &Kind,
+                 CXXBaseSpecifierArray &BasePath) {
+  QualType OrigDestType = DestType, OrigSrcType = SrcExpr->getType();
+  DestType = Self.Context.getCanonicalType(DestType);
+
+  // C++ 5.2.7p1: T shall be a pointer or reference to a complete class type,
+  //   or "pointer to cv void".
+
+  QualType DestPointee;
+  const PointerType *DestPointer = DestType->getAs<PointerType>();
+  const ReferenceType *DestReference = DestType->getAs<ReferenceType>();
+  if (DestPointer) {
+    DestPointee = DestPointer->getPointeeType();
+  } else if (DestReference) {
+    DestPointee = DestReference->getPointeeType();
+  } else {
+    Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_ref_or_ptr)
+      << OrigDestType << DestRange;
+    return;
+  }
+
+  const RecordType *DestRecord = DestPointee->getAs<RecordType>();
+  if (DestPointee->isVoidType()) {
+    assert(DestPointer && "Reference to void is not possible");
+  } else if (DestRecord) {
+    if (Self.RequireCompleteType(OpRange.getBegin(), DestPointee,
+                               Self.PDiag(diag::err_bad_dynamic_cast_incomplete)
+                                   << DestRange))
+      return;
+  } else {
+    Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_class)
+      << DestPointee.getUnqualifiedType() << DestRange;
+    return;
+  }
+
+  // C++0x 5.2.7p2: If T is a pointer type, v shall be an rvalue of a pointer to
+  //   complete class type, [...]. If T is an lvalue reference type, v shall be
+  //   an lvalue of a complete class type, [...]. If T is an rvalue reference
+  //   type, v shall be an expression having a complete effective class type,
+  //   [...]
+
+  QualType SrcType = Self.Context.getCanonicalType(OrigSrcType);
+  QualType SrcPointee;
+  if (DestPointer) {
+    if (const PointerType *SrcPointer = SrcType->getAs<PointerType>()) {
+      SrcPointee = SrcPointer->getPointeeType();
+    } else {
+      Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_ptr)
+        << OrigSrcType << SrcExpr->getSourceRange();
+      return;
+    }
+  } else if (DestReference->isLValueReferenceType()) {
+    if (SrcExpr->isLvalue(Self.Context) != Expr::LV_Valid) {
+      Self.Diag(OpRange.getBegin(), diag::err_bad_cxx_cast_rvalue)
+        << CT_Dynamic << OrigSrcType << OrigDestType << OpRange;
+    }
+    SrcPointee = SrcType;
+  } else {
+    SrcPointee = SrcType;
+  }
+
+  const RecordType *SrcRecord = SrcPointee->getAs<RecordType>();
+  if (SrcRecord) {
+    if (Self.RequireCompleteType(OpRange.getBegin(), SrcPointee,
+                             Self.PDiag(diag::err_bad_dynamic_cast_incomplete)
+                                   << SrcExpr->getSourceRange()))
+      return;
+  } else {
+    Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_class)
+      << SrcPointee.getUnqualifiedType() << SrcExpr->getSourceRange();
+    return;
+  }
+
+  assert((DestPointer || DestReference) &&
+    "Bad destination non-ptr/ref slipped through.");
+  assert((DestRecord || DestPointee->isVoidType()) &&
+    "Bad destination pointee slipped through.");
+  assert(SrcRecord && "Bad source pointee slipped through.");
+
+  // C++ 5.2.7p1: The dynamic_cast operator shall not cast away constness.
+  if (!DestPointee.isAtLeastAsQualifiedAs(SrcPointee)) {
+    Self.Diag(OpRange.getBegin(), diag::err_bad_cxx_cast_const_away)
+      << CT_Dynamic << OrigSrcType << OrigDestType << OpRange;
+    return;
+  }
+
+  // C++ 5.2.7p3: If the type of v is the same as the required result type,
+  //   [except for cv].
+  if (DestRecord == SrcRecord) {
+    return;
+  }
+
+  // C++ 5.2.7p5
+  // Upcasts are resolved statically.
+  if (DestRecord && Self.IsDerivedFrom(SrcPointee, DestPointee)) {
+    if (Self.CheckDerivedToBaseConversion(SrcPointee, DestPointee,
+                                           OpRange.getBegin(), OpRange, 
+                                           &BasePath))
+        return;
+        
+    Kind = CastExpr::CK_DerivedToBase;
+    return;
+  }
+
+  // C++ 5.2.7p6: Otherwise, v shall be [polymorphic].
+  const RecordDecl *SrcDecl = SrcRecord->getDecl()->getDefinition();
+  assert(SrcDecl && "Definition missing");
+  if (!cast<CXXRecordDecl>(SrcDecl)->isPolymorphic()) {
+    Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_polymorphic)
+      << SrcPointee.getUnqualifiedType() << SrcExpr->getSourceRange();
+  }
+
+  // Done. Everything else is run-time checks.
+  Kind = CastExpr::CK_Dynamic;
+}
+
+/// CheckConstCast - Check that a const_cast\<DestType\>(SrcExpr) is valid.
+/// Refer to C++ 5.2.11 for details. const_cast is typically used in code
+/// like this:
+/// const char *str = "literal";
+/// legacy_function(const_cast\<char*\>(str));
+void
+CheckConstCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
+               const SourceRange &OpRange, const SourceRange &DestRange) {
+  if (!DestType->isLValueReferenceType())
+    Self.DefaultFunctionArrayLvalueConversion(SrcExpr);
+
+  unsigned msg = diag::err_bad_cxx_cast_generic;
+  if (TryConstCast(Self, SrcExpr, DestType, /*CStyle*/false, msg) != TC_Success
+      && msg != 0)
+    Self.Diag(OpRange.getBegin(), msg) << CT_Const
+      << SrcExpr->getType() << DestType << OpRange;
+}
+
+/// CheckReinterpretCast - Check that a reinterpret_cast\<DestType\>(SrcExpr) is
+/// valid.
+/// Refer to C++ 5.2.10 for details. reinterpret_cast is typically used in code
+/// like this:
+/// char *bytes = reinterpret_cast\<char*\>(int_ptr);
+void
+CheckReinterpretCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
+                     const SourceRange &OpRange, const SourceRange &DestRange,
+                     CastExpr::CastKind &Kind) {
+  if (!DestType->isLValueReferenceType())
+    Self.DefaultFunctionArrayLvalueConversion(SrcExpr);
+
+  unsigned msg = diag::err_bad_cxx_cast_generic;
+  if (TryReinterpretCast(Self, SrcExpr, DestType, /*CStyle*/false, OpRange,
+                         msg, Kind)
+      != TC_Success && msg != 0)
+    Self.Diag(OpRange.getBegin(), msg) << CT_Reinterpret
+      << SrcExpr->getType() << DestType << OpRange;
+}
+
+
+/// CheckStaticCast - Check that a static_cast\<DestType\>(SrcExpr) is valid.
+/// Refer to C++ 5.2.9 for details. Static casts are mostly used for making
+/// implicit conversions explicit and getting rid of data loss warnings.
+void
+CheckStaticCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
+                const SourceRange &OpRange, CastExpr::CastKind &Kind,
+                CXXBaseSpecifierArray &BasePath) {
+  // This test is outside everything else because it's the only case where
+  // a non-lvalue-reference target type does not lead to decay.
+  // C++ 5.2.9p4: Any expression can be explicitly converted to type "cv void".
+  if (DestType->isVoidType()) {
+    Kind = CastExpr::CK_ToVoid;
+    return;
+  }
+
+  if (!DestType->isLValueReferenceType() && !DestType->isRecordType())
+    Self.DefaultFunctionArrayLvalueConversion(SrcExpr);
+
+  unsigned msg = diag::err_bad_cxx_cast_generic;
+  if (TryStaticCast(Self, SrcExpr, DestType, /*CStyle*/false, OpRange, msg,
+                    Kind, BasePath) != TC_Success && msg != 0)
+    Self.Diag(OpRange.getBegin(), msg) << CT_Static
+      << SrcExpr->getType() << DestType << OpRange;
+}
+
+/// TryStaticCast - Check if a static cast can be performed, and do so if
+/// possible. If @p CStyle, ignore access restrictions on hierarchy casting
+/// and casting away constness.
+static TryCastResult TryStaticCast(Sema &Self, Expr *&SrcExpr,
+                                   QualType DestType, bool CStyle,
+                                   const SourceRange &OpRange, unsigned &msg,
+                                   CastExpr::CastKind &Kind,
+                                   CXXBaseSpecifierArray &BasePath) {
+  // The order the tests is not entirely arbitrary. There is one conversion
+  // that can be handled in two different ways. Given:
+  // struct A {};
+  // struct B : public A {
+  //   B(); B(const A&);
+  // };
+  // const A &a = B();
+  // the cast static_cast<const B&>(a) could be seen as either a static
+  // reference downcast, or an explicit invocation of the user-defined
+  // conversion using B's conversion constructor.
+  // DR 427 specifies that the downcast is to be applied here.
+
+  // C++ 5.2.9p4: Any expression can be explicitly converted to type "cv void".
+  // Done outside this function.
+
+  TryCastResult tcr;
+
+  // C++ 5.2.9p5, reference downcast.
+  // See the function for details.
+  // DR 427 specifies that this is to be applied before paragraph 2.
+  tcr = TryStaticReferenceDowncast(Self, SrcExpr, DestType, CStyle, OpRange,
+                                   msg, Kind, BasePath);
+  if (tcr != TC_NotApplicable)
+    return tcr;
+
+  // N2844 5.2.9p3: An lvalue of type "cv1 T1" can be cast to type "rvalue
+  //   reference to cv2 T2" if "cv2 T2" is reference-compatible with "cv1 T1".
+  tcr = TryLValueToRValueCast(Self, SrcExpr, DestType, msg);
+  if (tcr != TC_NotApplicable) {
+    Kind = CastExpr::CK_NoOp;
+    return tcr;
+  }
+
+  // C++ 5.2.9p2: An expression e can be explicitly converted to a type T
+  //   [...] if the declaration "T t(e);" is well-formed, [...].
+  tcr = TryStaticImplicitCast(Self, SrcExpr, DestType, CStyle, OpRange, msg,
+                              Kind);
+  if (tcr != TC_NotApplicable)
+    return tcr;
+  
+  // C++ 5.2.9p6: May apply the reverse of any standard conversion, except
+  // lvalue-to-rvalue, array-to-pointer, function-to-pointer, and boolean
+  // conversions, subject to further restrictions.
+  // Also, C++ 5.2.9p1 forbids casting away constness, which makes reversal
+  // of qualification conversions impossible.
+  // In the CStyle case, the earlier attempt to const_cast should have taken
+  // care of reverse qualification conversions.
+
+  QualType OrigSrcType = SrcExpr->getType();
+
+  QualType SrcType = Self.Context.getCanonicalType(SrcExpr->getType());
+
+  // Reverse integral promotion/conversion. All such conversions are themselves
+  // again integral promotions or conversions and are thus already handled by
+  // p2 (TryDirectInitialization above).
+  // (Note: any data loss warnings should be suppressed.)
+  // The exception is the reverse of enum->integer, i.e. integer->enum (and
+  // enum->enum). See also C++ 5.2.9p7.
+  // The same goes for reverse floating point promotion/conversion and
+  // floating-integral conversions. Again, only floating->enum is relevant.
+  if (DestType->isEnumeralType()) {
+    if (SrcType->isComplexType() || SrcType->isVectorType()) {
+      // Fall through - these cannot be converted.
+    } else if (SrcType->isArithmeticType() || SrcType->isEnumeralType()) {
+      Kind = CastExpr::CK_IntegralCast;
+      return TC_Success;
+    }
+  }
+
+  // Reverse pointer upcast. C++ 4.10p3 specifies pointer upcast.
+  // C++ 5.2.9p8 additionally disallows a cast path through virtual inheritance.
+  tcr = TryStaticPointerDowncast(Self, SrcType, DestType, CStyle, OpRange, msg,
+                                 Kind, BasePath);
+  if (tcr != TC_NotApplicable)
+    return tcr;
+
+  // Reverse member pointer conversion. C++ 4.11 specifies member pointer
+  // conversion. C++ 5.2.9p9 has additional information.
+  // DR54's access restrictions apply here also.
+  tcr = TryStaticMemberPointerUpcast(Self, SrcExpr, SrcType, DestType, CStyle,
+                                     OpRange, msg, Kind, BasePath);
+  if (tcr != TC_NotApplicable)
+    return tcr;
+
+  // Reverse pointer conversion to void*. C++ 4.10.p2 specifies conversion to
+  // void*. C++ 5.2.9p10 specifies additional restrictions, which really is
+  // just the usual constness stuff.
+  if (const PointerType *SrcPointer = SrcType->getAs<PointerType>()) {
+    QualType SrcPointee = SrcPointer->getPointeeType();
+    if (SrcPointee->isVoidType()) {
+      if (const PointerType *DestPointer = DestType->getAs<PointerType>()) {
+        QualType DestPointee = DestPointer->getPointeeType();
+        if (DestPointee->isIncompleteOrObjectType()) {
+          // This is definitely the intended conversion, but it might fail due
+          // to a const violation.
+          if (!CStyle && !DestPointee.isAtLeastAsQualifiedAs(SrcPointee)) {
+            msg = diag::err_bad_cxx_cast_const_away;
+            return TC_Failed;
+          }
+          Kind = CastExpr::CK_BitCast;
+          return TC_Success;
+        }
+      }
+      else if (CStyle && DestType->isObjCObjectPointerType()) {
+        // allow c-style cast of objective-c pointers as they are pervasive.
+        Kind = CastExpr::CK_AnyPointerToObjCPointerCast;
+        return TC_Success;
+      }
+      else if (CStyle && DestType->isBlockPointerType()) {
+        // allow c-style cast of void * to block pointers.
+        Kind = CastExpr::CK_AnyPointerToBlockPointerCast;
+        return TC_Success;
+      }
+    }
+  }
+
+  // We tried everything. Everything! Nothing works! :-(
+  return TC_NotApplicable;
+}
+
+/// Tests whether a conversion according to N2844 is valid.
+TryCastResult
+TryLValueToRValueCast(Sema &Self, Expr *SrcExpr, QualType DestType,
+                      unsigned &msg) {
+  // N2844 5.2.9p3: An lvalue of type "cv1 T1" can be cast to type "rvalue
+  //   reference to cv2 T2" if "cv2 T2" is reference-compatible with "cv1 T1".
+  const RValueReferenceType *R = DestType->getAs<RValueReferenceType>();
+  if (!R)
+    return TC_NotApplicable;
+
+  if (SrcExpr->isLvalue(Self.Context) != Expr::LV_Valid)
+    return TC_NotApplicable;
+
+  // Because we try the reference downcast before this function, from now on
+  // this is the only cast possibility, so we issue an error if we fail now.
+  // FIXME: Should allow casting away constness if CStyle.
+  bool DerivedToBase;
+  if (Self.CompareReferenceRelationship(SrcExpr->getLocStart(),
+                                        SrcExpr->getType(), R->getPointeeType(),
+                                        DerivedToBase) <
+        Sema::Ref_Compatible_With_Added_Qualification) {
+    msg = diag::err_bad_lvalue_to_rvalue_cast;
+    return TC_Failed;
+  }
+
+  // FIXME: We should probably have an AST node for lvalue-to-rvalue 
+  // conversions.
+  return TC_Success;
+}
+
+/// Tests whether a conversion according to C++ 5.2.9p5 is valid.
+TryCastResult
+TryStaticReferenceDowncast(Sema &Self, Expr *SrcExpr, QualType DestType,
+                           bool CStyle, const SourceRange &OpRange,
+                           unsigned &msg, CastExpr::CastKind &Kind,
+                           CXXBaseSpecifierArray &BasePath) {
+  // C++ 5.2.9p5: An lvalue of type "cv1 B", where B is a class type, can be
+  //   cast to type "reference to cv2 D", where D is a class derived from B,
+  //   if a valid standard conversion from "pointer to D" to "pointer to B"
+  //   exists, cv2 >= cv1, and B is not a virtual base class of D.
+  // In addition, DR54 clarifies that the base must be accessible in the
+  // current context. Although the wording of DR54 only applies to the pointer
+  // variant of this rule, the intent is clearly for it to apply to the this
+  // conversion as well.
+
+  const ReferenceType *DestReference = DestType->getAs<ReferenceType>();
+  if (!DestReference) {
+    return TC_NotApplicable;
+  }
+  bool RValueRef = DestReference->isRValueReferenceType();
+  if (!RValueRef && SrcExpr->isLvalue(Self.Context) != Expr::LV_Valid) {
+    // We know the left side is an lvalue reference, so we can suggest a reason.
+    msg = diag::err_bad_cxx_cast_rvalue;
+    return TC_NotApplicable;
+  }
+
+  QualType DestPointee = DestReference->getPointeeType();
+
+  return TryStaticDowncast(Self, 
+                           Self.Context.getCanonicalType(SrcExpr->getType()), 
+                           Self.Context.getCanonicalType(DestPointee), CStyle,
+                           OpRange, SrcExpr->getType(), DestType, msg, Kind,
+                           BasePath);
+}
+
+/// Tests whether a conversion according to C++ 5.2.9p8 is valid.
+TryCastResult
+TryStaticPointerDowncast(Sema &Self, QualType SrcType, QualType DestType,
+                         bool CStyle, const SourceRange &OpRange,
+                         unsigned &msg, CastExpr::CastKind &Kind,
+                         CXXBaseSpecifierArray &BasePath) {
+  // C++ 5.2.9p8: An rvalue of type "pointer to cv1 B", where B is a class
+  //   type, can be converted to an rvalue of type "pointer to cv2 D", where D
+  //   is a class derived from B, if a valid standard conversion from "pointer
+  //   to D" to "pointer to B" exists, cv2 >= cv1, and B is not a virtual base
+  //   class of D.
+  // In addition, DR54 clarifies that the base must be accessible in the
+  // current context.
+
+  const PointerType *DestPointer = DestType->getAs<PointerType>();
+  if (!DestPointer) {
+    return TC_NotApplicable;
+  }
+
+  const PointerType *SrcPointer = SrcType->getAs<PointerType>();
+  if (!SrcPointer) {
+    msg = diag::err_bad_static_cast_pointer_nonpointer;
+    return TC_NotApplicable;
+  }
+
+  return TryStaticDowncast(Self, 
+                   Self.Context.getCanonicalType(SrcPointer->getPointeeType()),
+                  Self.Context.getCanonicalType(DestPointer->getPointeeType()), 
+                           CStyle, OpRange, SrcType, DestType, msg, Kind,
+                           BasePath);
+}
+
+/// TryStaticDowncast - Common functionality of TryStaticReferenceDowncast and
+/// TryStaticPointerDowncast. Tests whether a static downcast from SrcType to
+/// DestType is possible and allowed.
+TryCastResult
+TryStaticDowncast(Sema &Self, CanQualType SrcType, CanQualType DestType,
+                  bool CStyle, const SourceRange &OpRange, QualType OrigSrcType,
+                  QualType OrigDestType, unsigned &msg, 
+                  CastExpr::CastKind &Kind, CXXBaseSpecifierArray &BasePath) {
+  // We can only work with complete types. But don't complain if it doesn't work
+  if (Self.RequireCompleteType(OpRange.getBegin(), SrcType, Self.PDiag(0)) ||
+      Self.RequireCompleteType(OpRange.getBegin(), DestType, Self.PDiag(0)))
+    return TC_NotApplicable;
+
+  // Downcast can only happen in class hierarchies, so we need classes.
+  if (!DestType->getAs<RecordType>() || !SrcType->getAs<RecordType>()) {
+    return TC_NotApplicable;
+  }
+
+  CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
+                     /*DetectVirtual=*/true);
+  if (!Self.IsDerivedFrom(DestType, SrcType, Paths)) {
+    return TC_NotApplicable;
+  }
+
+  // Target type does derive from source type. Now we're serious. If an error
+  // appears now, it's not ignored.
+  // This may not be entirely in line with the standard. Take for example:
+  // struct A {};
+  // struct B : virtual A {
+  //   B(A&);
+  // };
+  //
+  // void f()
+  // {
+  //   (void)static_cast<const B&>(*((A*)0));
+  // }
+  // As far as the standard is concerned, p5 does not apply (A is virtual), so
+  // p2 should be used instead - "const B& t(*((A*)0));" is perfectly valid.
+  // However, both GCC and Comeau reject this example, and accepting it would
+  // mean more complex code if we're to preserve the nice error message.
+  // FIXME: Being 100% compliant here would be nice to have.
+
+  // Must preserve cv, as always, unless we're in C-style mode.
+  if (!CStyle && !DestType.isAtLeastAsQualifiedAs(SrcType)) {
+    msg = diag::err_bad_cxx_cast_const_away;
+    return TC_Failed;
+  }
+
+  if (Paths.isAmbiguous(SrcType.getUnqualifiedType())) {
+    // This code is analoguous to that in CheckDerivedToBaseConversion, except
+    // that it builds the paths in reverse order.
+    // To sum up: record all paths to the base and build a nice string from
+    // them. Use it to spice up the error message.
+    if (!Paths.isRecordingPaths()) {
+      Paths.clear();
+      Paths.setRecordingPaths(true);
+      Self.IsDerivedFrom(DestType, SrcType, Paths);
+    }
+    std::string PathDisplayStr;
+    std::set<unsigned> DisplayedPaths;
+    for (CXXBasePaths::paths_iterator PI = Paths.begin(), PE = Paths.end();
+         PI != PE; ++PI) {
+      if (DisplayedPaths.insert(PI->back().SubobjectNumber).second) {
+        // We haven't displayed a path to this particular base
+        // class subobject yet.
+        PathDisplayStr += "\n    ";
+        for (CXXBasePath::const_reverse_iterator EI = PI->rbegin(),
+                                                 EE = PI->rend();
+             EI != EE; ++EI)
+          PathDisplayStr += EI->Base->getType().getAsString() + " -> ";
+        PathDisplayStr += QualType(DestType).getAsString();
+      }
+    }
+
+    Self.Diag(OpRange.getBegin(), diag::err_ambiguous_base_to_derived_cast)
+      << QualType(SrcType).getUnqualifiedType() 
+      << QualType(DestType).getUnqualifiedType()
+      << PathDisplayStr << OpRange;
+    msg = 0;
+    return TC_Failed;
+  }
+
+  if (Paths.getDetectedVirtual() != 0) {
+    QualType VirtualBase(Paths.getDetectedVirtual(), 0);
+    Self.Diag(OpRange.getBegin(), diag::err_static_downcast_via_virtual)
+      << OrigSrcType << OrigDestType << VirtualBase << OpRange;
+    msg = 0;
+    return TC_Failed;
+  }
+
+  if (!CStyle && Self.CheckBaseClassAccess(OpRange.getBegin(),
+                                           SrcType, DestType,
+                                           Paths.front(),
+                                diag::err_downcast_from_inaccessible_base)) {
+    msg = 0;
+    return TC_Failed;
+  }
+
+  Self.BuildBasePathArray(Paths, BasePath);
+  Kind = CastExpr::CK_BaseToDerived;
+  return TC_Success;
+}
+
+/// TryStaticMemberPointerUpcast - Tests whether a conversion according to
+/// C++ 5.2.9p9 is valid:
+///
+///   An rvalue of type "pointer to member of D of type cv1 T" can be
+///   converted to an rvalue of type "pointer to member of B of type cv2 T",
+///   where B is a base class of D [...].
+///
+TryCastResult
+TryStaticMemberPointerUpcast(Sema &Self, Expr *&SrcExpr, QualType SrcType, 
+                             QualType DestType, bool CStyle, 
+                             const SourceRange &OpRange,
+                             unsigned &msg, CastExpr::CastKind &Kind,
+                             CXXBaseSpecifierArray &BasePath) {
+  const MemberPointerType *DestMemPtr = DestType->getAs<MemberPointerType>();
+  if (!DestMemPtr)
+    return TC_NotApplicable;
+
+  bool WasOverloadedFunction = false;
+  DeclAccessPair FoundOverload;
+  if (SrcExpr->getType() == Self.Context.OverloadTy) {
+    if (FunctionDecl *Fn
+          = Self.ResolveAddressOfOverloadedFunction(SrcExpr, DestType, false,
+                                                    FoundOverload)) {
+      CXXMethodDecl *M = cast<CXXMethodDecl>(Fn);
+      SrcType = Self.Context.getMemberPointerType(Fn->getType(),
+                      Self.Context.getTypeDeclType(M->getParent()).getTypePtr());
+      WasOverloadedFunction = true;
+    }
+  }
+  
+  const MemberPointerType *SrcMemPtr = SrcType->getAs<MemberPointerType>();
+  if (!SrcMemPtr) {
+    msg = diag::err_bad_static_cast_member_pointer_nonmp;
+    return TC_NotApplicable;
+  }
+
+  // T == T, modulo cv
+  if (!Self.Context.hasSameUnqualifiedType(SrcMemPtr->getPointeeType(),
+                                           DestMemPtr->getPointeeType()))
+    return TC_NotApplicable;
+
+  // B base of D
+  QualType SrcClass(SrcMemPtr->getClass(), 0);
+  QualType DestClass(DestMemPtr->getClass(), 0);
+  CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
+                  /*DetectVirtual=*/true);
+  if (!Self.IsDerivedFrom(SrcClass, DestClass, Paths)) {
+    return TC_NotApplicable;
+  }
+
+  // B is a base of D. But is it an allowed base? If not, it's a hard error.
+  if (Paths.isAmbiguous(DestClass)) {
+    Paths.clear();
+    Paths.setRecordingPaths(true);
+    bool StillOkay = Self.IsDerivedFrom(SrcClass, DestClass, Paths);
+    assert(StillOkay);
+    StillOkay = StillOkay;
+    std::string PathDisplayStr = Self.getAmbiguousPathsDisplayString(Paths);
+    Self.Diag(OpRange.getBegin(), diag::err_ambiguous_memptr_conv)
+      << 1 << SrcClass << DestClass << PathDisplayStr << OpRange;
+    msg = 0;
+    return TC_Failed;
+  }
+
+  if (const RecordType *VBase = Paths.getDetectedVirtual()) {
+    Self.Diag(OpRange.getBegin(), diag::err_memptr_conv_via_virtual)
+      << SrcClass << DestClass << QualType(VBase, 0) << OpRange;
+    msg = 0;
+    return TC_Failed;
+  }
+
+  if (!CStyle && Self.CheckBaseClassAccess(OpRange.getBegin(),
+                                           DestType, SrcType,
+                                           Paths.front(),
+                                     diag::err_upcast_to_inaccessible_base)) {
+    msg = 0;
+    return TC_Failed;
+  }
+
+  if (WasOverloadedFunction) {
+    // Resolve the address of the overloaded function again, this time
+    // allowing complaints if something goes wrong.
+    FunctionDecl *Fn = Self.ResolveAddressOfOverloadedFunction(SrcExpr, 
+                                                               DestType, 
+                                                               true,
+                                                               FoundOverload);
+    if (!Fn) {
+      msg = 0;
+      return TC_Failed;
+    }
+
+    SrcExpr = Self.FixOverloadedFunctionReference(SrcExpr, FoundOverload, Fn);
+    if (!SrcExpr) {
+      msg = 0;
+      return TC_Failed;
+    }
+  }
+
+  Self.BuildBasePathArray(Paths, BasePath);
+  Kind = CastExpr::CK_DerivedToBaseMemberPointer;
+  return TC_Success;
+}
+
+/// TryStaticImplicitCast - Tests whether a conversion according to C++ 5.2.9p2
+/// is valid:
+///
+///   An expression e can be explicitly converted to a type T using a
+///   @c static_cast if the declaration "T t(e);" is well-formed [...].
+TryCastResult
+TryStaticImplicitCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
+                      bool CStyle, const SourceRange &OpRange, unsigned &msg,
+                      CastExpr::CastKind &Kind) {
+  if (DestType->isRecordType()) {
+    if (Self.RequireCompleteType(OpRange.getBegin(), DestType,
+                                 diag::err_bad_dynamic_cast_incomplete)) {
+      msg = 0;
+      return TC_Failed;
+    }
+  }
+  
+  // At this point of CheckStaticCast, if the destination is a reference,
+  // this has to work. There is no other way that works.
+  // On the other hand, if we're checking a C-style cast, we've still got
+  // the reinterpret_cast way.
+  InitializedEntity Entity = InitializedEntity::InitializeTemporary(DestType);
+  InitializationKind InitKind
+    = InitializationKind::CreateCast(/*FIXME:*/OpRange, 
+                                                               CStyle);    
+  InitializationSequence InitSeq(Self, Entity, InitKind, &SrcExpr, 1);
+  if (InitSeq.getKind() == InitializationSequence::FailedSequence && 
+      (CStyle || !DestType->isReferenceType()))
+    return TC_NotApplicable;
+    
+  Sema::OwningExprResult Result
+    = InitSeq.Perform(Self, Entity, InitKind,
+                      Action::MultiExprArg(Self, (void**)&SrcExpr, 1));
+  if (Result.isInvalid()) {
+    msg = 0;
+    return TC_Failed;
+  }
+  
+  if (InitSeq.isConstructorInitialization())
+    Kind = CastExpr::CK_ConstructorConversion;
+  else
+    Kind = CastExpr::CK_NoOp;
+  
+  SrcExpr = Result.takeAs<Expr>();
+  return TC_Success;
+}
+
+/// TryConstCast - See if a const_cast from source to destination is allowed,
+/// and perform it if it is.
+static TryCastResult TryConstCast(Sema &Self, Expr *SrcExpr, QualType DestType,
+                                  bool CStyle, unsigned &msg) {
+  DestType = Self.Context.getCanonicalType(DestType);
+  QualType SrcType = SrcExpr->getType();
+  if (const LValueReferenceType *DestTypeTmp =
+        DestType->getAs<LValueReferenceType>()) {
+    if (SrcExpr->isLvalue(Self.Context) != Expr::LV_Valid) {
+      // Cannot const_cast non-lvalue to lvalue reference type. But if this
+      // is C-style, static_cast might find a way, so we simply suggest a
+      // message and tell the parent to keep searching.
+      msg = diag::err_bad_cxx_cast_rvalue;
+      return TC_NotApplicable;
+    }
+
+    // C++ 5.2.11p4: An lvalue of type T1 can be [cast] to an lvalue of type T2
+    //   [...] if a pointer to T1 can be [cast] to the type pointer to T2.
+    DestType = Self.Context.getPointerType(DestTypeTmp->getPointeeType());
+    SrcType = Self.Context.getPointerType(SrcType);
+  }
+
+  // C++ 5.2.11p5: For a const_cast involving pointers to data members [...]
+  //   the rules for const_cast are the same as those used for pointers.
+
+  if (!DestType->isPointerType() && !DestType->isMemberPointerType()) {
+    // Cannot cast to non-pointer, non-reference type. Note that, if DestType
+    // was a reference type, we converted it to a pointer above.
+    // The status of rvalue references isn't entirely clear, but it looks like
+    // conversion to them is simply invalid.
+    // C++ 5.2.11p3: For two pointer types [...]
+    if (!CStyle)
+      msg = diag::err_bad_const_cast_dest;
+    return TC_NotApplicable;
+  }
+  if (DestType->isFunctionPointerType() ||
+      DestType->isMemberFunctionPointerType()) {
+    // Cannot cast direct function pointers.
+    // C++ 5.2.11p2: [...] where T is any object type or the void type [...]
+    // T is the ultimate pointee of source and target type.
+    if (!CStyle)
+      msg = diag::err_bad_const_cast_dest;
+    return TC_NotApplicable;
+  }
+  SrcType = Self.Context.getCanonicalType(SrcType);
+
+  // Unwrap the pointers. Ignore qualifiers. Terminate early if the types are
+  // completely equal.
+  // FIXME: const_cast should probably not be able to convert between pointers
+  // to different address spaces.
+  // C++ 5.2.11p3 describes the core semantics of const_cast. All cv specifiers
+  // in multi-level pointers may change, but the level count must be the same,
+  // as must be the final pointee type.
+  while (SrcType != DestType &&
+         Self.UnwrapSimilarPointerTypes(SrcType, DestType)) {
+    Qualifiers Quals;
+    SrcType = Self.Context.getUnqualifiedArrayType(SrcType, Quals);
+    DestType = Self.Context.getUnqualifiedArrayType(DestType, Quals);
+  }
+
+  // Since we're dealing in canonical types, the remainder must be the same.
+  if (SrcType != DestType)
+    return TC_NotApplicable;
+
+  return TC_Success;
+}
+
+static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr,
+                                        QualType DestType, bool CStyle,
+                                        const SourceRange &OpRange,
+                                        unsigned &msg,
+                                        CastExpr::CastKind &Kind) {
+  DestType = Self.Context.getCanonicalType(DestType);
+  QualType SrcType = SrcExpr->getType();
+  if (const ReferenceType *DestTypeTmp = DestType->getAs<ReferenceType>()) {
+    bool LValue = DestTypeTmp->isLValueReferenceType();
+    if (LValue && SrcExpr->isLvalue(Self.Context) != Expr::LV_Valid) {
+      // Cannot cast non-lvalue to reference type. See the similar comment in
+      // const_cast.
+      msg = diag::err_bad_cxx_cast_rvalue;
+      return TC_NotApplicable;
+    }
+
+    // C++ 5.2.10p10: [...] a reference cast reinterpret_cast<T&>(x) has the
+    //   same effect as the conversion *reinterpret_cast<T*>(&x) with the
+    //   built-in & and * operators.
+    // This code does this transformation for the checked types.
+    DestType = Self.Context.getPointerType(DestTypeTmp->getPointeeType());
+    SrcType = Self.Context.getPointerType(SrcType);
+  }
+
+  // Canonicalize source for comparison.
+  SrcType = Self.Context.getCanonicalType(SrcType);
+
+  const MemberPointerType *DestMemPtr = DestType->getAs<MemberPointerType>(),
+                          *SrcMemPtr = SrcType->getAs<MemberPointerType>();
+  if (DestMemPtr && SrcMemPtr) {
+    // C++ 5.2.10p9: An rvalue of type "pointer to member of X of type T1"
+    //   can be explicitly converted to an rvalue of type "pointer to member
+    //   of Y of type T2" if T1 and T2 are both function types or both object
+    //   types.
+    if (DestMemPtr->getPointeeType()->isFunctionType() !=
+        SrcMemPtr->getPointeeType()->isFunctionType())
+      return TC_NotApplicable;
+
+    // C++ 5.2.10p2: The reinterpret_cast operator shall not cast away
+    //   constness.
+    // A reinterpret_cast followed by a const_cast can, though, so in C-style,
+    // we accept it.
+    if (!CStyle && CastsAwayConstness(Self, SrcType, DestType)) {
+      msg = diag::err_bad_cxx_cast_const_away;
+      return TC_Failed;
+    }
+
+    // A valid member pointer cast.
+    Kind = CastExpr::CK_BitCast;
+    return TC_Success;
+  }
+
+  // See below for the enumeral issue.
+  if (SrcType->isNullPtrType() && DestType->isIntegralType() &&
+      !DestType->isEnumeralType()) {
+    // C++0x 5.2.10p4: A pointer can be explicitly converted to any integral
+    //   type large enough to hold it. A value of std::nullptr_t can be
+    //   converted to an integral type; the conversion has the same meaning
+    //   and validity as a conversion of (void*)0 to the integral type.
+    if (Self.Context.getTypeSize(SrcType) >
+        Self.Context.getTypeSize(DestType)) {
+      msg = diag::err_bad_reinterpret_cast_small_int;
+      return TC_Failed;
+    }
+    Kind = CastExpr::CK_PointerToIntegral;
+    return TC_Success;
+  }
+
+  bool destIsVector = DestType->isVectorType();
+  bool srcIsVector = SrcType->isVectorType();
+  if (srcIsVector || destIsVector) {
+    bool srcIsScalar = SrcType->isIntegralType() && !SrcType->isEnumeralType();
+    bool destIsScalar = 
+      DestType->isIntegralType() && !DestType->isEnumeralType();
+    
+    // Check if this is a cast between a vector and something else.
+    if (!(srcIsScalar && destIsVector) && !(srcIsVector && destIsScalar) &&
+        !(srcIsVector && destIsVector))
+      return TC_NotApplicable;
+
+    // If both types have the same size, we can successfully cast.
+    if (Self.Context.getTypeSize(SrcType)
+          == Self.Context.getTypeSize(DestType)) {
+      Kind = CastExpr::CK_BitCast;
+      return TC_Success;
+    }
+    
+    if (destIsScalar)
+      msg = diag::err_bad_cxx_cast_vector_to_scalar_different_size;
+    else if (srcIsScalar)
+      msg = diag::err_bad_cxx_cast_scalar_to_vector_different_size;
+    else
+      msg = diag::err_bad_cxx_cast_vector_to_vector_different_size;
+    
+    return TC_Failed;
+  }
+  
+  bool destIsPtr = DestType->isAnyPointerType();
+  bool srcIsPtr = SrcType->isAnyPointerType();
+  if (!destIsPtr && !srcIsPtr) {
+    // Except for std::nullptr_t->integer and lvalue->reference, which are
+    // handled above, at least one of the two arguments must be a pointer.
+    return TC_NotApplicable;
+  }
+
+  if (SrcType == DestType) {
+    // C++ 5.2.10p2 has a note that mentions that, subject to all other
+    // restrictions, a cast to the same type is allowed. The intent is not
+    // entirely clear here, since all other paragraphs explicitly forbid casts
+    // to the same type. However, the behavior of compilers is pretty consistent
+    // on this point: allow same-type conversion if the involved types are
+    // pointers, disallow otherwise.
+    Kind = CastExpr::CK_NoOp;
+    return TC_Success;
+  }
+
+  // Note: Clang treats enumeration types as integral types. If this is ever
+  // changed for C++, the additional check here will be redundant.
+  if (DestType->isIntegralType() && !DestType->isEnumeralType()) {
+    assert(srcIsPtr && "One type must be a pointer");
+    // C++ 5.2.10p4: A pointer can be explicitly converted to any integral
+    //   type large enough to hold it.
+    if (Self.Context.getTypeSize(SrcType) >
+        Self.Context.getTypeSize(DestType)) {
+      msg = diag::err_bad_reinterpret_cast_small_int;
+      return TC_Failed;
+    }
+    Kind = CastExpr::CK_PointerToIntegral;
+    return TC_Success;
+  }
+
+  if (SrcType->isIntegralType() || SrcType->isEnumeralType()) {
+    assert(destIsPtr && "One type must be a pointer");
+    // C++ 5.2.10p5: A value of integral or enumeration type can be explicitly
+    //   converted to a pointer.
+    Kind = CastExpr::CK_IntegralToPointer;
+    return TC_Success;
+  }
+
+  if (!destIsPtr || !srcIsPtr) {
+    // With the valid non-pointer conversions out of the way, we can be even
+    // more stringent.
+    return TC_NotApplicable;
+  }
+
+  // C++ 5.2.10p2: The reinterpret_cast operator shall not cast away constness.
+  // The C-style cast operator can.
+  if (!CStyle && CastsAwayConstness(Self, SrcType, DestType)) {
+    msg = diag::err_bad_cxx_cast_const_away;
+    return TC_Failed;
+  }
+  if (CStyle && DestType->isObjCObjectPointerType()) {
+    Kind = CastExpr::CK_AnyPointerToObjCPointerCast;
+    return TC_Success;
+  }
+  
+  // Not casting away constness, so the only remaining check is for compatible
+  // pointer categories.
+  Kind = CastExpr::CK_BitCast;
+
+  if (SrcType->isFunctionPointerType()) {
+    if (DestType->isFunctionPointerType()) {
+      // C++ 5.2.10p6: A pointer to a function can be explicitly converted to
+      // a pointer to a function of a different type.
+      return TC_Success;
+    }
+
+    // C++0x 5.2.10p8: Converting a pointer to a function into a pointer to
+    //   an object type or vice versa is conditionally-supported.
+    // Compilers support it in C++03 too, though, because it's necessary for
+    // casting the return value of dlsym() and GetProcAddress().
+    // FIXME: Conditionally-supported behavior should be configurable in the
+    // TargetInfo or similar.
+    if (!Self.getLangOptions().CPlusPlus0x)
+      Self.Diag(OpRange.getBegin(), diag::ext_cast_fn_obj) << OpRange;
+    return TC_Success;
+  }
+
+  if (DestType->isFunctionPointerType()) {
+    // See above.
+    if (!Self.getLangOptions().CPlusPlus0x)
+      Self.Diag(OpRange.getBegin(), diag::ext_cast_fn_obj) << OpRange;
+    return TC_Success;
+  }
+
+  // C++ 5.2.10p7: A pointer to an object can be explicitly converted to
+  //   a pointer to an object of different type.
+  // Void pointers are not specified, but supported by every compiler out there.
+  // So we finish by allowing everything that remains - it's got to be two
+  // object pointers.
+  return TC_Success;
+}
+
+bool 
+Sema::CXXCheckCStyleCast(SourceRange R, QualType CastTy, Expr *&CastExpr,
+                         CastExpr::CastKind &Kind, 
+                         CXXBaseSpecifierArray &BasePath,
+                         bool FunctionalStyle) {
+  // This test is outside everything else because it's the only case where
+  // a non-lvalue-reference target type does not lead to decay.
+  // C++ 5.2.9p4: Any expression can be explicitly converted to type "cv void".
+  if (CastTy->isVoidType()) {
+    Kind = CastExpr::CK_ToVoid;
+    return false;
+  }
+
+  // If the type is dependent, we won't do any other semantic analysis now.
+  if (CastTy->isDependentType() || CastExpr->isTypeDependent())
+    return false;
+
+  if (!CastTy->isLValueReferenceType() && !CastTy->isRecordType())
+    DefaultFunctionArrayLvalueConversion(CastExpr);
+
+  // C++ [expr.cast]p5: The conversions performed by
+  //   - a const_cast,
+  //   - a static_cast,
+  //   - a static_cast followed by a const_cast,
+  //   - a reinterpret_cast, or
+  //   - a reinterpret_cast followed by a const_cast,
+  //   can be performed using the cast notation of explicit type conversion.
+  //   [...] If a conversion can be interpreted in more than one of the ways
+  //   listed above, the interpretation that appears first in the list is used,
+  //   even if a cast resulting from that interpretation is ill-formed.
+  // In plain language, this means trying a const_cast ...
+  unsigned msg = diag::err_bad_cxx_cast_generic;
+  TryCastResult tcr = TryConstCast(*this, CastExpr, CastTy, /*CStyle*/true,
+                                   msg);
+  if (tcr == TC_Success)
+    Kind = CastExpr::CK_NoOp;
+
+  if (tcr == TC_NotApplicable) {
+    // ... or if that is not possible, a static_cast, ignoring const, ...
+    tcr = TryStaticCast(*this, CastExpr, CastTy, /*CStyle*/true, R, msg, Kind,
+                        BasePath);
+    if (tcr == TC_NotApplicable) {
+      // ... and finally a reinterpret_cast, ignoring const.
+      tcr = TryReinterpretCast(*this, CastExpr, CastTy, /*CStyle*/true, R, msg,
+                               Kind);
+    }
+  }
+
+  if (tcr != TC_Success && msg != 0)
+    Diag(R.getBegin(), msg) << (FunctionalStyle ? CT_Functional : CT_CStyle)
+      << CastExpr->getType() << CastTy << R;
+
+  return tcr != TC_Success;
+}
diff --git a/lib/Sema/SemaCXXScopeSpec.cpp b/lib/Sema/SemaCXXScopeSpec.cpp
new file mode 100644
index 0000000..10adc67
--- /dev/null
+++ b/lib/Sema/SemaCXXScopeSpec.cpp
@@ -0,0 +1,683 @@
+//===--- SemaCXXScopeSpec.cpp - Semantic Analysis for C++ scope specifiers-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements C++ semantic analysis for scope specifiers.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Sema.h"
+#include "Lookup.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/NestedNameSpecifier.h"
+#include "clang/Basic/PartialDiagnostic.h"
+#include "clang/Parse/DeclSpec.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace clang;
+
+/// \brief Find the current instantiation that associated with the given type.
+static CXXRecordDecl *getCurrentInstantiationOf(QualType T) {
+  if (T.isNull())
+    return 0;
+
+  const Type *Ty = T->getCanonicalTypeInternal().getTypePtr();
+  if (isa<RecordType>(Ty))
+    return cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl());
+  else if (isa<InjectedClassNameType>(Ty))
+    return cast<InjectedClassNameType>(Ty)->getDecl();
+  else
+    return 0;
+}
+
+/// \brief Compute the DeclContext that is associated with the given type.
+///
+/// \param T the type for which we are attempting to find a DeclContext.
+///
+/// \returns the declaration context represented by the type T,
+/// or NULL if the declaration context cannot be computed (e.g., because it is
+/// dependent and not the current instantiation).
+DeclContext *Sema::computeDeclContext(QualType T) {
+  if (const TagType *Tag = T->getAs<TagType>())
+    return Tag->getDecl();
+
+  return ::getCurrentInstantiationOf(T);
+}
+
+/// \brief Compute the DeclContext that is associated with the given
+/// scope specifier.
+///
+/// \param SS the C++ scope specifier as it appears in the source
+///
+/// \param EnteringContext when true, we will be entering the context of
+/// this scope specifier, so we can retrieve the declaration context of a
+/// class template or class template partial specialization even if it is
+/// not the current instantiation.
+///
+/// \returns the declaration context represented by the scope specifier @p SS,
+/// or NULL if the declaration context cannot be computed (e.g., because it is
+/// dependent and not the current instantiation).
+DeclContext *Sema::computeDeclContext(const CXXScopeSpec &SS,
+                                      bool EnteringContext) {
+  if (!SS.isSet() || SS.isInvalid())
+    return 0;
+
+  NestedNameSpecifier *NNS
+    = static_cast<NestedNameSpecifier *>(SS.getScopeRep());
+  if (NNS->isDependent()) {
+    // If this nested-name-specifier refers to the current
+    // instantiation, return its DeclContext.
+    if (CXXRecordDecl *Record = getCurrentInstantiationOf(NNS))
+      return Record;
+
+    if (EnteringContext) {
+      const Type *NNSType = NNS->getAsType();
+      if (!NNSType) {
+        // do nothing, fall out
+      } else if (const TemplateSpecializationType *SpecType
+                   = NNSType->getAs<TemplateSpecializationType>()) {
+        // We are entering the context of the nested name specifier, so try to
+        // match the nested name specifier to either a primary class template
+        // or a class template partial specialization.
+        if (ClassTemplateDecl *ClassTemplate
+              = dyn_cast_or_null<ClassTemplateDecl>(
+                            SpecType->getTemplateName().getAsTemplateDecl())) {
+          QualType ContextType
+            = Context.getCanonicalType(QualType(SpecType, 0));
+
+          // If the type of the nested name specifier is the same as the
+          // injected class name of the named class template, we're entering
+          // into that class template definition.
+          QualType Injected
+            = ClassTemplate->getInjectedClassNameSpecialization(Context);
+          if (Context.hasSameType(Injected, ContextType))
+            return ClassTemplate->getTemplatedDecl();
+
+          // If the type of the nested name specifier is the same as the
+          // type of one of the class template's class template partial
+          // specializations, we're entering into the definition of that
+          // class template partial specialization.
+          if (ClassTemplatePartialSpecializationDecl *PartialSpec
+                = ClassTemplate->findPartialSpecialization(ContextType))
+            return PartialSpec;
+        }
+      } else if (const RecordType *RecordT = NNSType->getAs<RecordType>()) {
+        // The nested name specifier refers to a member of a class template.
+        return RecordT->getDecl();
+      }
+    }
+
+    return 0;
+  }
+
+  switch (NNS->getKind()) {
+  case NestedNameSpecifier::Identifier:
+    assert(false && "Dependent nested-name-specifier has no DeclContext");
+    break;
+
+  case NestedNameSpecifier::Namespace:
+    return NNS->getAsNamespace();
+
+  case NestedNameSpecifier::TypeSpec:
+  case NestedNameSpecifier::TypeSpecWithTemplate: {
+    const TagType *Tag = NNS->getAsType()->getAs<TagType>();
+    assert(Tag && "Non-tag type in nested-name-specifier");
+    return Tag->getDecl();
+  } break;
+
+  case NestedNameSpecifier::Global:
+    return Context.getTranslationUnitDecl();
+  }
+
+  // Required to silence a GCC warning.
+  return 0;
+}
+
+bool Sema::isDependentScopeSpecifier(const CXXScopeSpec &SS) {
+  if (!SS.isSet() || SS.isInvalid())
+    return false;
+
+  NestedNameSpecifier *NNS
+    = static_cast<NestedNameSpecifier *>(SS.getScopeRep());
+  return NNS->isDependent();
+}
+
+// \brief Determine whether this C++ scope specifier refers to an
+// unknown specialization, i.e., a dependent type that is not the
+// current instantiation.
+bool Sema::isUnknownSpecialization(const CXXScopeSpec &SS) {
+  if (!isDependentScopeSpecifier(SS))
+    return false;
+
+  NestedNameSpecifier *NNS
+    = static_cast<NestedNameSpecifier *>(SS.getScopeRep());
+  return getCurrentInstantiationOf(NNS) == 0;
+}
+
+/// \brief If the given nested name specifier refers to the current
+/// instantiation, return the declaration that corresponds to that
+/// current instantiation (C++0x [temp.dep.type]p1).
+///
+/// \param NNS a dependent nested name specifier.
+CXXRecordDecl *Sema::getCurrentInstantiationOf(NestedNameSpecifier *NNS) {
+  assert(getLangOptions().CPlusPlus && "Only callable in C++");
+  assert(NNS->isDependent() && "Only dependent nested-name-specifier allowed");
+
+  if (!NNS->getAsType())
+    return 0;
+
+  QualType T = QualType(NNS->getAsType(), 0);
+  return ::getCurrentInstantiationOf(T);
+}
+
+/// \brief Require that the context specified by SS be complete.
+///
+/// If SS refers to a type, this routine checks whether the type is
+/// complete enough (or can be made complete enough) for name lookup
+/// into the DeclContext. A type that is not yet completed can be
+/// considered "complete enough" if it is a class/struct/union/enum
+/// that is currently being defined. Or, if we have a type that names
+/// a class template specialization that is not a complete type, we
+/// will attempt to instantiate that class template.
+bool Sema::RequireCompleteDeclContext(CXXScopeSpec &SS) {
+  if (!SS.isSet() || SS.isInvalid())
+    return false;
+
+  DeclContext *DC = computeDeclContext(SS, true);
+  if (!DC) {
+    // It's dependent.
+    assert(isDependentScopeSpecifier(SS) && 
+           "No context for non-dependent scope specifier?");
+    Diag(SS.getRange().getBegin(), diag::err_dependent_nested_name_spec)
+      << SS.getRange();
+    SS.setScopeRep(0);
+    return true;
+  }
+  
+  if (TagDecl *Tag = dyn_cast<TagDecl>(DC)) {
+    // If this is a dependent type, then we consider it complete.
+    if (Tag->isDependentContext())
+      return false;
+
+    // If we're currently defining this type, then lookup into the
+    // type is okay: don't complain that it isn't complete yet.
+    const TagType *TagT = Context.getTypeDeclType(Tag)->getAs<TagType>();
+    if (TagT && TagT->isBeingDefined())
+      return false;
+
+    // The type must be complete.
+    if (RequireCompleteType(SS.getRange().getBegin(),
+                            Context.getTypeDeclType(Tag),
+                            PDiag(diag::err_incomplete_nested_name_spec)
+                            << SS.getRange())) {
+      SS.setScopeRep(0);  // Mark the ScopeSpec invalid.
+      return true;
+    }
+  }
+
+  return false;
+}
+
+/// ActOnCXXGlobalScopeSpecifier - Return the object that represents the
+/// global scope ('::').
+Sema::CXXScopeTy *Sema::ActOnCXXGlobalScopeSpecifier(Scope *S,
+                                                     SourceLocation CCLoc) {
+  return NestedNameSpecifier::GlobalSpecifier(Context);
+}
+
+/// \brief Determines whether the given declaration is an valid acceptable
+/// result for name lookup of a nested-name-specifier.
+bool Sema::isAcceptableNestedNameSpecifier(NamedDecl *SD) {
+  if (!SD)
+    return false;
+
+  // Namespace and namespace aliases are fine.
+  if (isa<NamespaceDecl>(SD) || isa<NamespaceAliasDecl>(SD))
+    return true;
+
+  if (!isa<TypeDecl>(SD))
+    return false;
+
+  // Determine whether we have a class (or, in C++0x, an enum) or
+  // a typedef thereof. If so, build the nested-name-specifier.
+  QualType T = Context.getTypeDeclType(cast<TypeDecl>(SD));
+  if (T->isDependentType())
+    return true;
+  else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(SD)) {
+    if (TD->getUnderlyingType()->isRecordType() ||
+        (Context.getLangOptions().CPlusPlus0x &&
+         TD->getUnderlyingType()->isEnumeralType()))
+      return true;
+  } else if (isa<RecordDecl>(SD) ||
+             (Context.getLangOptions().CPlusPlus0x && isa<EnumDecl>(SD)))
+    return true;
+
+  return false;
+}
+
+/// \brief If the given nested-name-specifier begins with a bare identifier
+/// (e.g., Base::), perform name lookup for that identifier as a
+/// nested-name-specifier within the given scope, and return the result of that
+/// name lookup.
+NamedDecl *Sema::FindFirstQualifierInScope(Scope *S, NestedNameSpecifier *NNS) {
+  if (!S || !NNS)
+    return 0;
+
+  while (NNS->getPrefix())
+    NNS = NNS->getPrefix();
+
+  if (NNS->getKind() != NestedNameSpecifier::Identifier)
+    return 0;
+
+  LookupResult Found(*this, NNS->getAsIdentifier(), SourceLocation(),
+                     LookupNestedNameSpecifierName);
+  LookupName(Found, S);
+  assert(!Found.isAmbiguous() && "Cannot handle ambiguities here yet");
+
+  if (!Found.isSingleResult())
+    return 0;
+
+  NamedDecl *Result = Found.getFoundDecl();
+  if (isAcceptableNestedNameSpecifier(Result))
+    return Result;
+
+  return 0;
+}
+
+bool Sema::isNonTypeNestedNameSpecifier(Scope *S, CXXScopeSpec &SS,
+                                        SourceLocation IdLoc,
+                                        IdentifierInfo &II,
+                                        TypeTy *ObjectTypePtr) {
+  QualType ObjectType = GetTypeFromParser(ObjectTypePtr);
+  LookupResult Found(*this, &II, IdLoc, LookupNestedNameSpecifierName);
+  
+  // Determine where to perform name lookup
+  DeclContext *LookupCtx = 0;
+  bool isDependent = false;
+  if (!ObjectType.isNull()) {
+    // This nested-name-specifier occurs in a member access expression, e.g.,
+    // x->B::f, and we are looking into the type of the object.
+    assert(!SS.isSet() && "ObjectType and scope specifier cannot coexist");
+    LookupCtx = computeDeclContext(ObjectType);
+    isDependent = ObjectType->isDependentType();
+  } else if (SS.isSet()) {
+    // This nested-name-specifier occurs after another nested-name-specifier,
+    // so long into the context associated with the prior nested-name-specifier.
+    LookupCtx = computeDeclContext(SS, false);
+    isDependent = isDependentScopeSpecifier(SS);
+    Found.setContextRange(SS.getRange());
+  }
+  
+  if (LookupCtx) {
+    // Perform "qualified" name lookup into the declaration context we
+    // computed, which is either the type of the base of a member access
+    // expression or the declaration context associated with a prior
+    // nested-name-specifier.
+    
+    // The declaration context must be complete.
+    if (!LookupCtx->isDependentContext() && RequireCompleteDeclContext(SS))
+      return false;
+    
+    LookupQualifiedName(Found, LookupCtx);
+  } else if (isDependent) {
+    return false;
+  } else {
+    LookupName(Found, S);
+  }
+  Found.suppressDiagnostics();
+  
+  if (NamedDecl *ND = Found.getAsSingle<NamedDecl>())
+    return isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND);
+  
+  return false;
+}
+
+/// \brief Build a new nested-name-specifier for "identifier::", as described
+/// by ActOnCXXNestedNameSpecifier.
+///
+/// This routine differs only slightly from ActOnCXXNestedNameSpecifier, in
+/// that it contains an extra parameter \p ScopeLookupResult, which provides
+/// the result of name lookup within the scope of the nested-name-specifier
+/// that was computed at template definition time.
+///
+/// If ErrorRecoveryLookup is true, then this call is used to improve error
+/// recovery.  This means that it should not emit diagnostics, it should
+/// just return null on failure.  It also means it should only return a valid
+/// scope if it *knows* that the result is correct.  It should not return in a
+/// dependent context, for example.
+Sema::CXXScopeTy *Sema::BuildCXXNestedNameSpecifier(Scope *S,
+                                                    CXXScopeSpec &SS,
+                                                    SourceLocation IdLoc,
+                                                    SourceLocation CCLoc,
+                                                    IdentifierInfo &II,
+                                                    QualType ObjectType,
+                                                  NamedDecl *ScopeLookupResult,
+                                                    bool EnteringContext,
+                                                    bool ErrorRecoveryLookup) {
+  NestedNameSpecifier *Prefix
+    = static_cast<NestedNameSpecifier *>(SS.getScopeRep());
+
+  LookupResult Found(*this, &II, IdLoc, LookupNestedNameSpecifierName);
+
+  // Determine where to perform name lookup
+  DeclContext *LookupCtx = 0;
+  bool isDependent = false;
+  if (!ObjectType.isNull()) {
+    // This nested-name-specifier occurs in a member access expression, e.g.,
+    // x->B::f, and we are looking into the type of the object.
+    assert(!SS.isSet() && "ObjectType and scope specifier cannot coexist");
+    LookupCtx = computeDeclContext(ObjectType);
+    isDependent = ObjectType->isDependentType();
+  } else if (SS.isSet()) {
+    // This nested-name-specifier occurs after another nested-name-specifier,
+    // so long into the context associated with the prior nested-name-specifier.
+    LookupCtx = computeDeclContext(SS, EnteringContext);
+    isDependent = isDependentScopeSpecifier(SS);
+    Found.setContextRange(SS.getRange());
+  }
+
+
+  bool ObjectTypeSearchedInScope = false;
+  if (LookupCtx) {
+    // Perform "qualified" name lookup into the declaration context we
+    // computed, which is either the type of the base of a member access
+    // expression or the declaration context associated with a prior
+    // nested-name-specifier.
+
+    // The declaration context must be complete.
+    if (!LookupCtx->isDependentContext() && RequireCompleteDeclContext(SS))
+      return 0;
+
+    LookupQualifiedName(Found, LookupCtx);
+
+    if (!ObjectType.isNull() && Found.empty()) {
+      // C++ [basic.lookup.classref]p4:
+      //   If the id-expression in a class member access is a qualified-id of
+      //   the form
+      //
+      //        class-name-or-namespace-name::...
+      //
+      //   the class-name-or-namespace-name following the . or -> operator is
+      //   looked up both in the context of the entire postfix-expression and in
+      //   the scope of the class of the object expression. If the name is found
+      //   only in the scope of the class of the object expression, the name
+      //   shall refer to a class-name. If the name is found only in the
+      //   context of the entire postfix-expression, the name shall refer to a
+      //   class-name or namespace-name. [...]
+      //
+      // Qualified name lookup into a class will not find a namespace-name,
+      // so we do not need to diagnoste that case specifically. However,
+      // this qualified name lookup may find nothing. In that case, perform
+      // unqualified name lookup in the given scope (if available) or
+      // reconstruct the result from when name lookup was performed at template
+      // definition time.
+      if (S)
+        LookupName(Found, S);
+      else if (ScopeLookupResult)
+        Found.addDecl(ScopeLookupResult);
+
+      ObjectTypeSearchedInScope = true;
+    }
+  } else if (isDependent) {
+    // Don't speculate if we're just trying to improve error recovery.
+    if (ErrorRecoveryLookup)
+      return 0;
+    
+    // We were not able to compute the declaration context for a dependent
+    // base object type or prior nested-name-specifier, so this
+    // nested-name-specifier refers to an unknown specialization. Just build
+    // a dependent nested-name-specifier.
+    if (!Prefix)
+      return NestedNameSpecifier::Create(Context, &II);
+
+    return NestedNameSpecifier::Create(Context, Prefix, &II);
+  } else {
+    // Perform unqualified name lookup in the current scope.
+    LookupName(Found, S);
+  }
+
+  // FIXME: Deal with ambiguities cleanly.
+
+  if (Found.empty() && !ErrorRecoveryLookup) {
+    // We haven't found anything, and we're not recovering from a
+    // different kind of error, so look for typos.
+    DeclarationName Name = Found.getLookupName();
+    if (CorrectTypo(Found, S, &SS, LookupCtx, EnteringContext,  
+                    CTC_NoKeywords) &&
+        Found.isSingleResult() &&
+        isAcceptableNestedNameSpecifier(Found.getAsSingle<NamedDecl>())) {
+      if (LookupCtx)
+        Diag(Found.getNameLoc(), diag::err_no_member_suggest)
+          << Name << LookupCtx << Found.getLookupName() << SS.getRange()
+          << FixItHint::CreateReplacement(Found.getNameLoc(),
+                                          Found.getLookupName().getAsString());
+      else
+        Diag(Found.getNameLoc(), diag::err_undeclared_var_use_suggest)
+          << Name << Found.getLookupName()
+          << FixItHint::CreateReplacement(Found.getNameLoc(),
+                                          Found.getLookupName().getAsString());
+      
+      if (NamedDecl *ND = Found.getAsSingle<NamedDecl>())
+        Diag(ND->getLocation(), diag::note_previous_decl)
+          << ND->getDeclName();
+    } else
+      Found.clear();
+  }
+
+  NamedDecl *SD = Found.getAsSingle<NamedDecl>();
+  if (isAcceptableNestedNameSpecifier(SD)) {
+    if (!ObjectType.isNull() && !ObjectTypeSearchedInScope) {
+      // C++ [basic.lookup.classref]p4:
+      //   [...] If the name is found in both contexts, the
+      //   class-name-or-namespace-name shall refer to the same entity.
+      //
+      // We already found the name in the scope of the object. Now, look
+      // into the current scope (the scope of the postfix-expression) to
+      // see if we can find the same name there. As above, if there is no
+      // scope, reconstruct the result from the template instantiation itself.
+      NamedDecl *OuterDecl;
+      if (S) {
+        LookupResult FoundOuter(*this, &II, IdLoc, LookupNestedNameSpecifierName);
+        LookupName(FoundOuter, S);
+        OuterDecl = FoundOuter.getAsSingle<NamedDecl>();
+      } else
+        OuterDecl = ScopeLookupResult;
+
+      if (isAcceptableNestedNameSpecifier(OuterDecl) &&
+          OuterDecl->getCanonicalDecl() != SD->getCanonicalDecl() &&
+          (!isa<TypeDecl>(OuterDecl) || !isa<TypeDecl>(SD) ||
+           !Context.hasSameType(
+                            Context.getTypeDeclType(cast<TypeDecl>(OuterDecl)),
+                               Context.getTypeDeclType(cast<TypeDecl>(SD))))) {
+             if (ErrorRecoveryLookup)
+               return 0;
+             
+             Diag(IdLoc, diag::err_nested_name_member_ref_lookup_ambiguous)
+               << &II;
+             Diag(SD->getLocation(), diag::note_ambig_member_ref_object_type)
+               << ObjectType;
+             Diag(OuterDecl->getLocation(), diag::note_ambig_member_ref_scope);
+
+             // Fall through so that we'll pick the name we found in the object
+             // type, since that's probably what the user wanted anyway.
+           }
+    }
+
+    if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(SD))
+      return NestedNameSpecifier::Create(Context, Prefix, Namespace);
+
+    // FIXME: It would be nice to maintain the namespace alias name, then
+    // see through that alias when resolving the nested-name-specifier down to
+    // a declaration context.
+    if (NamespaceAliasDecl *Alias = dyn_cast<NamespaceAliasDecl>(SD))
+      return NestedNameSpecifier::Create(Context, Prefix,
+
+                                         Alias->getNamespace());
+
+    QualType T = Context.getTypeDeclType(cast<TypeDecl>(SD));
+    return NestedNameSpecifier::Create(Context, Prefix, false,
+                                       T.getTypePtr());
+  }
+
+  // Otherwise, we have an error case.  If we don't want diagnostics, just
+  // return an error now.
+  if (ErrorRecoveryLookup)
+    return 0;
+
+  // If we didn't find anything during our lookup, try again with
+  // ordinary name lookup, which can help us produce better error
+  // messages.
+  if (Found.empty()) {
+    Found.clear(LookupOrdinaryName);
+    LookupName(Found, S);
+  }
+
+  unsigned DiagID;
+  if (!Found.empty())
+    DiagID = diag::err_expected_class_or_namespace;
+  else if (SS.isSet()) {
+    Diag(IdLoc, diag::err_no_member) << &II << LookupCtx << SS.getRange();
+    return 0;
+  } else
+    DiagID = diag::err_undeclared_var_use;
+
+  if (SS.isSet())
+    Diag(IdLoc, DiagID) << &II << SS.getRange();
+  else
+    Diag(IdLoc, DiagID) << &II;
+
+  return 0;
+}
+
+/// ActOnCXXNestedNameSpecifier - Called during parsing of a
+/// nested-name-specifier. e.g. for "foo::bar::" we parsed "foo::" and now
+/// we want to resolve "bar::". 'SS' is empty or the previously parsed
+/// nested-name part ("foo::"), 'IdLoc' is the source location of 'bar',
+/// 'CCLoc' is the location of '::' and 'II' is the identifier for 'bar'.
+/// Returns a CXXScopeTy* object representing the C++ scope.
+Sema::CXXScopeTy *Sema::ActOnCXXNestedNameSpecifier(Scope *S,
+                                                    CXXScopeSpec &SS,
+                                                    SourceLocation IdLoc,
+                                                    SourceLocation CCLoc,
+                                                    IdentifierInfo &II,
+                                                    TypeTy *ObjectTypePtr,
+                                                    bool EnteringContext) {
+  return BuildCXXNestedNameSpecifier(S, SS, IdLoc, CCLoc, II,
+                                     QualType::getFromOpaquePtr(ObjectTypePtr),
+                                     /*ScopeLookupResult=*/0, EnteringContext,
+                                     false);
+}
+
+/// IsInvalidUnlessNestedName - This method is used for error recovery
+/// purposes to determine whether the specified identifier is only valid as
+/// a nested name specifier, for example a namespace name.  It is
+/// conservatively correct to always return false from this method.
+///
+/// The arguments are the same as those passed to ActOnCXXNestedNameSpecifier.
+bool Sema::IsInvalidUnlessNestedName(Scope *S, CXXScopeSpec &SS,
+                                     IdentifierInfo &II, TypeTy *ObjectType,
+                                     bool EnteringContext) {
+  return BuildCXXNestedNameSpecifier(S, SS, SourceLocation(), SourceLocation(),
+                                     II, QualType::getFromOpaquePtr(ObjectType),
+                                     /*ScopeLookupResult=*/0, EnteringContext,
+                                     true);
+}
+
+Sema::CXXScopeTy *Sema::ActOnCXXNestedNameSpecifier(Scope *S,
+                                                    const CXXScopeSpec &SS,
+                                                    TypeTy *Ty,
+                                                    SourceRange TypeRange,
+                                                    SourceLocation CCLoc) {
+  NestedNameSpecifier *Prefix
+    = static_cast<NestedNameSpecifier *>(SS.getScopeRep());
+  QualType T = GetTypeFromParser(Ty);
+  return NestedNameSpecifier::Create(Context, Prefix, /*FIXME:*/false,
+                                     T.getTypePtr());
+}
+
+bool Sema::ShouldEnterDeclaratorScope(Scope *S, const CXXScopeSpec &SS) {
+  assert(SS.isSet() && "Parser passed invalid CXXScopeSpec.");
+
+  NestedNameSpecifier *Qualifier =
+    static_cast<NestedNameSpecifier*>(SS.getScopeRep());
+
+  // There are only two places a well-formed program may qualify a
+  // declarator: first, when defining a namespace or class member
+  // out-of-line, and second, when naming an explicitly-qualified
+  // friend function.  The latter case is governed by
+  // C++03 [basic.lookup.unqual]p10:
+  //   In a friend declaration naming a member function, a name used
+  //   in the function declarator and not part of a template-argument
+  //   in a template-id is first looked up in the scope of the member
+  //   function's class. If it is not found, or if the name is part of
+  //   a template-argument in a template-id, the look up is as
+  //   described for unqualified names in the definition of the class
+  //   granting friendship.
+  // i.e. we don't push a scope unless it's a class member.
+
+  switch (Qualifier->getKind()) {
+  case NestedNameSpecifier::Global:
+  case NestedNameSpecifier::Namespace:
+    // These are always namespace scopes.  We never want to enter a
+    // namespace scope from anything but a file context.
+    return CurContext->getLookupContext()->isFileContext();
+
+  case NestedNameSpecifier::Identifier:
+  case NestedNameSpecifier::TypeSpec:
+  case NestedNameSpecifier::TypeSpecWithTemplate:
+    // These are never namespace scopes.
+    return true;
+  }
+
+  // Silence bogus warning.
+  return false;
+}
+
+/// ActOnCXXEnterDeclaratorScope - Called when a C++ scope specifier (global
+/// scope or nested-name-specifier) is parsed, part of a declarator-id.
+/// After this method is called, according to [C++ 3.4.3p3], names should be
+/// looked up in the declarator-id's scope, until the declarator is parsed and
+/// ActOnCXXExitDeclaratorScope is called.
+/// The 'SS' should be a non-empty valid CXXScopeSpec.
+bool Sema::ActOnCXXEnterDeclaratorScope(Scope *S, CXXScopeSpec &SS) {
+  assert(SS.isSet() && "Parser passed invalid CXXScopeSpec.");
+
+  if (SS.isInvalid()) return true;
+
+  DeclContext *DC = computeDeclContext(SS, true);
+  if (!DC) return true;
+
+  // Before we enter a declarator's context, we need to make sure that
+  // it is a complete declaration context.
+  if (!DC->isDependentContext() && RequireCompleteDeclContext(SS))
+    return true;
+    
+  EnterDeclaratorContext(S, DC);
+
+  // Rebuild the nested name specifier for the new scope.
+  if (DC->isDependentContext())
+    RebuildNestedNameSpecifierInCurrentInstantiation(SS);
+
+  return false;
+}
+
+/// ActOnCXXExitDeclaratorScope - Called when a declarator that previously
+/// invoked ActOnCXXEnterDeclaratorScope(), is finished. 'SS' is the same
+/// CXXScopeSpec that was passed to ActOnCXXEnterDeclaratorScope as well.
+/// Used to indicate that names should revert to being looked up in the
+/// defining scope.
+void Sema::ActOnCXXExitDeclaratorScope(Scope *S, const CXXScopeSpec &SS) {
+  assert(SS.isSet() && "Parser passed invalid CXXScopeSpec.");
+  if (SS.isInvalid())
+    return;
+  assert(!SS.isInvalid() && computeDeclContext(SS, true) &&
+         "exiting declarator scope we never really entered");
+  ExitDeclaratorContext(S);
+}
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
new file mode 100644
index 0000000..0373ca8
--- /dev/null
+++ b/lib/Sema/SemaChecking.cpp
@@ -0,0 +1,2265 @@
+//===--- SemaChecking.cpp - Extra Semantic Checking -----------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements extra semantic analysis beyond what is enforced
+//  by the C type system.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Sema.h"
+#include "clang/Analysis/Analyses/PrintfFormatString.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/CharUnits.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/ExprObjC.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/StmtCXX.h"
+#include "clang/AST/StmtObjC.h"
+#include "clang/Lex/LiteralSupport.h"
+#include "clang/Lex/Preprocessor.h"
+#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/STLExtras.h"
+#include "clang/Basic/TargetBuiltins.h"
+#include <limits>
+using namespace clang;
+
+/// getLocationOfStringLiteralByte - Return a source location that points to the
+/// specified byte of the specified string literal.
+///
+/// Strings are amazingly complex.  They can be formed from multiple tokens and
+/// can have escape sequences in them in addition to the usual trigraph and
+/// escaped newline business.  This routine handles this complexity.
+///
+SourceLocation Sema::getLocationOfStringLiteralByte(const StringLiteral *SL,
+                                                    unsigned ByteNo) const {
+  assert(!SL->isWide() && "This doesn't work for wide strings yet");
+
+  // Loop over all of the tokens in this string until we find the one that
+  // contains the byte we're looking for.
+  unsigned TokNo = 0;
+  while (1) {
+    assert(TokNo < SL->getNumConcatenated() && "Invalid byte number!");
+    SourceLocation StrTokLoc = SL->getStrTokenLoc(TokNo);
+
+    // Get the spelling of the string so that we can get the data that makes up
+    // the string literal, not the identifier for the macro it is potentially
+    // expanded through.
+    SourceLocation StrTokSpellingLoc = SourceMgr.getSpellingLoc(StrTokLoc);
+
+    // Re-lex the token to get its length and original spelling.
+    std::pair<FileID, unsigned> LocInfo =
+      SourceMgr.getDecomposedLoc(StrTokSpellingLoc);
+    bool Invalid = false;
+    llvm::StringRef Buffer = SourceMgr.getBufferData(LocInfo.first, &Invalid);
+    if (Invalid)
+      return StrTokSpellingLoc;
+      
+    const char *StrData = Buffer.data()+LocInfo.second;
+
+    // Create a langops struct and enable trigraphs.  This is sufficient for
+    // relexing tokens.
+    LangOptions LangOpts;
+    LangOpts.Trigraphs = true;
+
+    // Create a lexer starting at the beginning of this token.
+    Lexer TheLexer(StrTokSpellingLoc, LangOpts, Buffer.begin(), StrData,
+                   Buffer.end());
+    Token TheTok;
+    TheLexer.LexFromRawLexer(TheTok);
+
+    // Use the StringLiteralParser to compute the length of the string in bytes.
+    StringLiteralParser SLP(&TheTok, 1, PP);
+    unsigned TokNumBytes = SLP.GetStringLength();
+
+    // If the byte is in this token, return the location of the byte.
+    if (ByteNo < TokNumBytes ||
+        (ByteNo == TokNumBytes && TokNo == SL->getNumConcatenated())) {
+      unsigned Offset =
+        StringLiteralParser::getOffsetOfStringByte(TheTok, ByteNo, PP);
+
+      // Now that we know the offset of the token in the spelling, use the
+      // preprocessor to get the offset in the original source.
+      return PP.AdvanceToTokenCharacter(StrTokLoc, Offset);
+    }
+
+    // Move to the next string token.
+    ++TokNo;
+    ByteNo -= TokNumBytes;
+  }
+}
+
+/// CheckablePrintfAttr - does a function call have a "printf" attribute
+/// and arguments that merit checking?
+bool Sema::CheckablePrintfAttr(const FormatAttr *Format, CallExpr *TheCall) {
+  if (Format->getType() == "printf") return true;
+  if (Format->getType() == "printf0") {
+    // printf0 allows null "format" string; if so don't check format/args
+    unsigned format_idx = Format->getFormatIdx() - 1;
+    // Does the index refer to the implicit object argument?
+    if (isa<CXXMemberCallExpr>(TheCall)) {
+      if (format_idx == 0)
+        return false;
+      --format_idx;
+    }
+    if (format_idx < TheCall->getNumArgs()) {
+      Expr *Format = TheCall->getArg(format_idx)->IgnoreParenCasts();
+      if (!Format->isNullPointerConstant(Context,
+                                         Expr::NPC_ValueDependentIsNull))
+        return true;
+    }
+  }
+  return false;
+}
+
+Action::OwningExprResult
+Sema::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
+  OwningExprResult TheCallResult(Owned(TheCall));
+
+  switch (BuiltinID) {
+  case Builtin::BI__builtin___CFStringMakeConstantString:
+    assert(TheCall->getNumArgs() == 1 &&
+           "Wrong # arguments to builtin CFStringMakeConstantString");
+    if (CheckObjCString(TheCall->getArg(0)))
+      return ExprError();
+    break;
+  case Builtin::BI__builtin_stdarg_start:
+  case Builtin::BI__builtin_va_start:
+    if (SemaBuiltinVAStart(TheCall))
+      return ExprError();
+    break;
+  case Builtin::BI__builtin_isgreater:
+  case Builtin::BI__builtin_isgreaterequal:
+  case Builtin::BI__builtin_isless:
+  case Builtin::BI__builtin_islessequal:
+  case Builtin::BI__builtin_islessgreater:
+  case Builtin::BI__builtin_isunordered:
+    if (SemaBuiltinUnorderedCompare(TheCall))
+      return ExprError();
+    break;
+  case Builtin::BI__builtin_fpclassify:
+    if (SemaBuiltinFPClassification(TheCall, 6))
+      return ExprError();
+    break;
+  case Builtin::BI__builtin_isfinite:
+  case Builtin::BI__builtin_isinf:
+  case Builtin::BI__builtin_isinf_sign:
+  case Builtin::BI__builtin_isnan:
+  case Builtin::BI__builtin_isnormal:
+    if (SemaBuiltinFPClassification(TheCall, 1))
+      return ExprError();
+    break;
+  case Builtin::BI__builtin_return_address:
+  case Builtin::BI__builtin_frame_address: {
+    llvm::APSInt Result;
+    if (SemaBuiltinConstantArg(TheCall, 0, Result))
+      return ExprError();
+    break;
+  }
+  case Builtin::BI__builtin_eh_return_data_regno: {
+    llvm::APSInt Result;
+    if (SemaBuiltinConstantArg(TheCall, 0, Result))
+      return ExprError();
+    break;
+  }
+  case Builtin::BI__builtin_shufflevector:
+    return SemaBuiltinShuffleVector(TheCall);
+    // TheCall will be freed by the smart pointer here, but that's fine, since
+    // SemaBuiltinShuffleVector guts it, but then doesn't release it.
+  case Builtin::BI__builtin_prefetch:
+    if (SemaBuiltinPrefetch(TheCall))
+      return ExprError();
+    break;
+  case Builtin::BI__builtin_object_size:
+    if (SemaBuiltinObjectSize(TheCall))
+      return ExprError();
+    break;
+  case Builtin::BI__builtin_longjmp:
+    if (SemaBuiltinLongjmp(TheCall))
+      return ExprError();
+    break;
+  case Builtin::BI__sync_fetch_and_add:
+  case Builtin::BI__sync_fetch_and_sub:
+  case Builtin::BI__sync_fetch_and_or:
+  case Builtin::BI__sync_fetch_and_and:
+  case Builtin::BI__sync_fetch_and_xor:
+  case Builtin::BI__sync_add_and_fetch:
+  case Builtin::BI__sync_sub_and_fetch:
+  case Builtin::BI__sync_and_and_fetch:
+  case Builtin::BI__sync_or_and_fetch:
+  case Builtin::BI__sync_xor_and_fetch:
+  case Builtin::BI__sync_val_compare_and_swap:
+  case Builtin::BI__sync_bool_compare_and_swap:
+  case Builtin::BI__sync_lock_test_and_set:
+  case Builtin::BI__sync_lock_release:
+    if (SemaBuiltinAtomicOverloaded(TheCall))
+      return ExprError();
+    break;
+    
+  // Target specific builtins start here.
+  case X86::BI__builtin_ia32_palignr128:
+  case X86::BI__builtin_ia32_palignr: {
+    llvm::APSInt Result;
+    if (SemaBuiltinConstantArg(TheCall, 2, Result))
+      return ExprError();
+    break;
+  }
+  }
+
+  return move(TheCallResult);
+}
+
+/// CheckFunctionCall - Check a direct function call for various correctness
+/// and safety properties not strictly enforced by the C type system.
+bool Sema::CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall) {
+  // Get the IdentifierInfo* for the called function.
+  IdentifierInfo *FnInfo = FDecl->getIdentifier();
+
+  // None of the checks below are needed for functions that don't have
+  // simple names (e.g., C++ conversion functions).
+  if (!FnInfo)
+    return false;
+
+  // FIXME: This mechanism should be abstracted to be less fragile and
+  // more efficient. For example, just map function ids to custom
+  // handlers.
+
+  // Printf checking.
+  if (const FormatAttr *Format = FDecl->getAttr<FormatAttr>()) {
+    if (CheckablePrintfAttr(Format, TheCall)) {
+      bool HasVAListArg = Format->getFirstArg() == 0;
+      CheckPrintfArguments(TheCall, HasVAListArg, Format->getFormatIdx() - 1,
+                           HasVAListArg ? 0 : Format->getFirstArg() - 1);
+    }
+  }
+
+  for (const NonNullAttr *NonNull = FDecl->getAttr<NonNullAttr>(); NonNull;
+       NonNull = NonNull->getNext<NonNullAttr>())
+    CheckNonNullArguments(NonNull, TheCall);
+
+  return false;
+}
+
+bool Sema::CheckBlockCall(NamedDecl *NDecl, CallExpr *TheCall) {
+  // Printf checking.
+  const FormatAttr *Format = NDecl->getAttr<FormatAttr>();
+  if (!Format)
+    return false;
+
+  const VarDecl *V = dyn_cast<VarDecl>(NDecl);
+  if (!V)
+    return false;
+
+  QualType Ty = V->getType();
+  if (!Ty->isBlockPointerType())
+    return false;
+
+  if (!CheckablePrintfAttr(Format, TheCall))
+    return false;
+
+  bool HasVAListArg = Format->getFirstArg() == 0;
+  CheckPrintfArguments(TheCall, HasVAListArg, Format->getFormatIdx() - 1,
+                       HasVAListArg ? 0 : Format->getFirstArg() - 1);
+
+  return false;
+}
+
+/// SemaBuiltinAtomicOverloaded - We have a call to a function like
+/// __sync_fetch_and_add, which is an overloaded function based on the pointer
+/// type of its first argument.  The main ActOnCallExpr routines have already
+/// promoted the types of arguments because all of these calls are prototyped as
+/// void(...).
+///
+/// This function goes through and does final semantic checking for these
+/// builtins,
+bool Sema::SemaBuiltinAtomicOverloaded(CallExpr *TheCall) {
+  DeclRefExpr *DRE =cast<DeclRefExpr>(TheCall->getCallee()->IgnoreParenCasts());
+  FunctionDecl *FDecl = cast<FunctionDecl>(DRE->getDecl());
+
+  // Ensure that we have at least one argument to do type inference from.
+  if (TheCall->getNumArgs() < 1)
+    return Diag(TheCall->getLocEnd(),
+              diag::err_typecheck_call_too_few_args_at_least)
+              << 0 << 1 << TheCall->getNumArgs()
+              << TheCall->getCallee()->getSourceRange();
+
+  // Inspect the first argument of the atomic builtin.  This should always be
+  // a pointer type, whose element is an integral scalar or pointer type.
+  // Because it is a pointer type, we don't have to worry about any implicit
+  // casts here.
+  Expr *FirstArg = TheCall->getArg(0);
+  if (!FirstArg->getType()->isPointerType())
+    return Diag(DRE->getLocStart(), diag::err_atomic_builtin_must_be_pointer)
+             << FirstArg->getType() << FirstArg->getSourceRange();
+
+  QualType ValType = FirstArg->getType()->getAs<PointerType>()->getPointeeType();
+  if (!ValType->isIntegerType() && !ValType->isPointerType() &&
+      !ValType->isBlockPointerType())
+    return Diag(DRE->getLocStart(),
+                diag::err_atomic_builtin_must_be_pointer_intptr)
+             << FirstArg->getType() << FirstArg->getSourceRange();
+
+  // We need to figure out which concrete builtin this maps onto.  For example,
+  // __sync_fetch_and_add with a 2 byte object turns into
+  // __sync_fetch_and_add_2.
+#define BUILTIN_ROW(x) \
+  { Builtin::BI##x##_1, Builtin::BI##x##_2, Builtin::BI##x##_4, \
+    Builtin::BI##x##_8, Builtin::BI##x##_16 }
+
+  static const unsigned BuiltinIndices[][5] = {
+    BUILTIN_ROW(__sync_fetch_and_add),
+    BUILTIN_ROW(__sync_fetch_and_sub),
+    BUILTIN_ROW(__sync_fetch_and_or),
+    BUILTIN_ROW(__sync_fetch_and_and),
+    BUILTIN_ROW(__sync_fetch_and_xor),
+
+    BUILTIN_ROW(__sync_add_and_fetch),
+    BUILTIN_ROW(__sync_sub_and_fetch),
+    BUILTIN_ROW(__sync_and_and_fetch),
+    BUILTIN_ROW(__sync_or_and_fetch),
+    BUILTIN_ROW(__sync_xor_and_fetch),
+
+    BUILTIN_ROW(__sync_val_compare_and_swap),
+    BUILTIN_ROW(__sync_bool_compare_and_swap),
+    BUILTIN_ROW(__sync_lock_test_and_set),
+    BUILTIN_ROW(__sync_lock_release)
+  };
+#undef BUILTIN_ROW
+
+  // Determine the index of the size.
+  unsigned SizeIndex;
+  switch (Context.getTypeSizeInChars(ValType).getQuantity()) {
+  case 1: SizeIndex = 0; break;
+  case 2: SizeIndex = 1; break;
+  case 4: SizeIndex = 2; break;
+  case 8: SizeIndex = 3; break;
+  case 16: SizeIndex = 4; break;
+  default:
+    return Diag(DRE->getLocStart(), diag::err_atomic_builtin_pointer_size)
+             << FirstArg->getType() << FirstArg->getSourceRange();
+  }
+
+  // Each of these builtins has one pointer argument, followed by some number of
+  // values (0, 1 or 2) followed by a potentially empty varags list of stuff
+  // that we ignore.  Find out which row of BuiltinIndices to read from as well
+  // as the number of fixed args.
+  unsigned BuiltinID = FDecl->getBuiltinID();
+  unsigned BuiltinIndex, NumFixed = 1;
+  switch (BuiltinID) {
+  default: assert(0 && "Unknown overloaded atomic builtin!");
+  case Builtin::BI__sync_fetch_and_add: BuiltinIndex = 0; break;
+  case Builtin::BI__sync_fetch_and_sub: BuiltinIndex = 1; break;
+  case Builtin::BI__sync_fetch_and_or:  BuiltinIndex = 2; break;
+  case Builtin::BI__sync_fetch_and_and: BuiltinIndex = 3; break;
+  case Builtin::BI__sync_fetch_and_xor: BuiltinIndex = 4; break;
+
+  case Builtin::BI__sync_add_and_fetch: BuiltinIndex = 5; break;
+  case Builtin::BI__sync_sub_and_fetch: BuiltinIndex = 6; break;
+  case Builtin::BI__sync_and_and_fetch: BuiltinIndex = 7; break;
+  case Builtin::BI__sync_or_and_fetch:  BuiltinIndex = 8; break;
+  case Builtin::BI__sync_xor_and_fetch: BuiltinIndex = 9; break;
+
+  case Builtin::BI__sync_val_compare_and_swap:
+    BuiltinIndex = 10;
+    NumFixed = 2;
+    break;
+  case Builtin::BI__sync_bool_compare_and_swap:
+    BuiltinIndex = 11;
+    NumFixed = 2;
+    break;
+  case Builtin::BI__sync_lock_test_and_set: BuiltinIndex = 12; break;
+  case Builtin::BI__sync_lock_release:
+    BuiltinIndex = 13;
+    NumFixed = 0;
+    break;
+  }
+
+  // Now that we know how many fixed arguments we expect, first check that we
+  // have at least that many.
+  if (TheCall->getNumArgs() < 1+NumFixed)
+    return Diag(TheCall->getLocEnd(),
+            diag::err_typecheck_call_too_few_args_at_least)
+            << 0 << 1+NumFixed << TheCall->getNumArgs()
+            << TheCall->getCallee()->getSourceRange();
+
+
+  // Get the decl for the concrete builtin from this, we can tell what the
+  // concrete integer type we should convert to is.
+  unsigned NewBuiltinID = BuiltinIndices[BuiltinIndex][SizeIndex];
+  const char *NewBuiltinName = Context.BuiltinInfo.GetName(NewBuiltinID);
+  IdentifierInfo *NewBuiltinII = PP.getIdentifierInfo(NewBuiltinName);
+  FunctionDecl *NewBuiltinDecl =
+    cast<FunctionDecl>(LazilyCreateBuiltin(NewBuiltinII, NewBuiltinID,
+                                           TUScope, false, DRE->getLocStart()));
+  const FunctionProtoType *BuiltinFT =
+    NewBuiltinDecl->getType()->getAs<FunctionProtoType>();
+  ValType = BuiltinFT->getArgType(0)->getAs<PointerType>()->getPointeeType();
+
+  // If the first type needs to be converted (e.g. void** -> int*), do it now.
+  if (BuiltinFT->getArgType(0) != FirstArg->getType()) {
+    ImpCastExprToType(FirstArg, BuiltinFT->getArgType(0), CastExpr::CK_BitCast);
+    TheCall->setArg(0, FirstArg);
+  }
+
+  // Next, walk the valid ones promoting to the right type.
+  for (unsigned i = 0; i != NumFixed; ++i) {
+    Expr *Arg = TheCall->getArg(i+1);
+
+    // If the argument is an implicit cast, then there was a promotion due to
+    // "...", just remove it now.
+    if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Arg)) {
+      Arg = ICE->getSubExpr();
+      ICE->setSubExpr(0);
+      ICE->Destroy(Context);
+      TheCall->setArg(i+1, Arg);
+    }
+
+    // GCC does an implicit conversion to the pointer or integer ValType.  This
+    // can fail in some cases (1i -> int**), check for this error case now.
+    CastExpr::CastKind Kind = CastExpr::CK_Unknown;
+    CXXBaseSpecifierArray BasePath;
+    if (CheckCastTypes(Arg->getSourceRange(), ValType, Arg, Kind, BasePath))
+      return true;
+
+    // Okay, we have something that *can* be converted to the right type.  Check
+    // to see if there is a potentially weird extension going on here.  This can
+    // happen when you do an atomic operation on something like an char* and
+    // pass in 42.  The 42 gets converted to char.  This is even more strange
+    // for things like 45.123 -> char, etc.
+    // FIXME: Do this check.
+    ImpCastExprToType(Arg, ValType, Kind);
+    TheCall->setArg(i+1, Arg);
+  }
+
+  // Switch the DeclRefExpr to refer to the new decl.
+  DRE->setDecl(NewBuiltinDecl);
+  DRE->setType(NewBuiltinDecl->getType());
+
+  // Set the callee in the CallExpr.
+  // FIXME: This leaks the original parens and implicit casts.
+  Expr *PromotedCall = DRE;
+  UsualUnaryConversions(PromotedCall);
+  TheCall->setCallee(PromotedCall);
+
+
+  // Change the result type of the call to match the result type of the decl.
+  TheCall->setType(NewBuiltinDecl->getResultType());
+  return false;
+}
+
+
+/// CheckObjCString - Checks that the argument to the builtin
+/// CFString constructor is correct
+/// FIXME: GCC currently emits the following warning:
+/// "warning: input conversion stopped due to an input byte that does not
+///           belong to the input codeset UTF-8"
+/// Note: It might also make sense to do the UTF-16 conversion here (would
+/// simplify the backend).
+bool Sema::CheckObjCString(Expr *Arg) {
+  Arg = Arg->IgnoreParenCasts();
+  StringLiteral *Literal = dyn_cast<StringLiteral>(Arg);
+
+  if (!Literal || Literal->isWide()) {
+    Diag(Arg->getLocStart(), diag::err_cfstring_literal_not_string_constant)
+      << Arg->getSourceRange();
+    return true;
+  }
+
+  const char *Data = Literal->getStrData();
+  unsigned Length = Literal->getByteLength();
+
+  for (unsigned i = 0; i < Length; ++i) {
+    if (!Data[i]) {
+      Diag(getLocationOfStringLiteralByte(Literal, i),
+           diag::warn_cfstring_literal_contains_nul_character)
+        << Arg->getSourceRange();
+      break;
+    }
+  }
+
+  return false;
+}
+
+/// SemaBuiltinVAStart - Check the arguments to __builtin_va_start for validity.
+/// Emit an error and return true on failure, return false on success.
+bool Sema::SemaBuiltinVAStart(CallExpr *TheCall) {
+  Expr *Fn = TheCall->getCallee();
+  if (TheCall->getNumArgs() > 2) {
+    Diag(TheCall->getArg(2)->getLocStart(),
+         diag::err_typecheck_call_too_many_args)
+      << 0 /*function call*/ << 2 << TheCall->getNumArgs()
+      << Fn->getSourceRange()
+      << SourceRange(TheCall->getArg(2)->getLocStart(),
+                     (*(TheCall->arg_end()-1))->getLocEnd());
+    return true;
+  }
+
+  if (TheCall->getNumArgs() < 2) {
+    return Diag(TheCall->getLocEnd(),
+      diag::err_typecheck_call_too_few_args_at_least)
+      << 0 /*function call*/ << 2 << TheCall->getNumArgs();
+  }
+
+  // Determine whether the current function is variadic or not.
+  BlockScopeInfo *CurBlock = getCurBlock();
+  bool isVariadic;
+  if (CurBlock)
+    isVariadic = CurBlock->isVariadic;
+  else if (getCurFunctionDecl()) {
+    if (FunctionProtoType* FTP =
+            dyn_cast<FunctionProtoType>(getCurFunctionDecl()->getType()))
+      isVariadic = FTP->isVariadic();
+    else
+      isVariadic = false;
+  } else {
+    isVariadic = getCurMethodDecl()->isVariadic();
+  }
+
+  if (!isVariadic) {
+    Diag(Fn->getLocStart(), diag::err_va_start_used_in_non_variadic_function);
+    return true;
+  }
+
+  // Verify that the second argument to the builtin is the last argument of the
+  // current function or method.
+  bool SecondArgIsLastNamedArgument = false;
+  const Expr *Arg = TheCall->getArg(1)->IgnoreParenCasts();
+
+  if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Arg)) {
+    if (const ParmVarDecl *PV = dyn_cast<ParmVarDecl>(DR->getDecl())) {
+      // FIXME: This isn't correct for methods (results in bogus warning).
+      // Get the last formal in the current function.
+      const ParmVarDecl *LastArg;
+      if (CurBlock)
+        LastArg = *(CurBlock->TheDecl->param_end()-1);
+      else if (FunctionDecl *FD = getCurFunctionDecl())
+        LastArg = *(FD->param_end()-1);
+      else
+        LastArg = *(getCurMethodDecl()->param_end()-1);
+      SecondArgIsLastNamedArgument = PV == LastArg;
+    }
+  }
+
+  if (!SecondArgIsLastNamedArgument)
+    Diag(TheCall->getArg(1)->getLocStart(),
+         diag::warn_second_parameter_of_va_start_not_last_named_argument);
+  return false;
+}
+
+/// SemaBuiltinUnorderedCompare - Handle functions like __builtin_isgreater and
+/// friends.  This is declared to take (...), so we have to check everything.
+bool Sema::SemaBuiltinUnorderedCompare(CallExpr *TheCall) {
+  if (TheCall->getNumArgs() < 2)
+    return Diag(TheCall->getLocEnd(), diag::err_typecheck_call_too_few_args)
+      << 0 << 2 << TheCall->getNumArgs()/*function call*/;
+  if (TheCall->getNumArgs() > 2)
+    return Diag(TheCall->getArg(2)->getLocStart(),
+                diag::err_typecheck_call_too_many_args)
+      << 0 /*function call*/ << 2 << TheCall->getNumArgs()
+      << SourceRange(TheCall->getArg(2)->getLocStart(),
+                     (*(TheCall->arg_end()-1))->getLocEnd());
+
+  Expr *OrigArg0 = TheCall->getArg(0);
+  Expr *OrigArg1 = TheCall->getArg(1);
+
+  // Do standard promotions between the two arguments, returning their common
+  // type.
+  QualType Res = UsualArithmeticConversions(OrigArg0, OrigArg1, false);
+
+  // Make sure any conversions are pushed back into the call; this is
+  // type safe since unordered compare builtins are declared as "_Bool
+  // foo(...)".
+  TheCall->setArg(0, OrigArg0);
+  TheCall->setArg(1, OrigArg1);
+
+  if (OrigArg0->isTypeDependent() || OrigArg1->isTypeDependent())
+    return false;
+
+  // If the common type isn't a real floating type, then the arguments were
+  // invalid for this operation.
+  if (!Res->isRealFloatingType())
+    return Diag(OrigArg0->getLocStart(),
+                diag::err_typecheck_call_invalid_ordered_compare)
+      << OrigArg0->getType() << OrigArg1->getType()
+      << SourceRange(OrigArg0->getLocStart(), OrigArg1->getLocEnd());
+
+  return false;
+}
+
+/// SemaBuiltinSemaBuiltinFPClassification - Handle functions like
+/// __builtin_isnan and friends.  This is declared to take (...), so we have
+/// to check everything. We expect the last argument to be a floating point
+/// value.
+bool Sema::SemaBuiltinFPClassification(CallExpr *TheCall, unsigned NumArgs) {
+  if (TheCall->getNumArgs() < NumArgs)
+    return Diag(TheCall->getLocEnd(), diag::err_typecheck_call_too_few_args)
+      << 0 << NumArgs << TheCall->getNumArgs()/*function call*/;
+  if (TheCall->getNumArgs() > NumArgs)
+    return Diag(TheCall->getArg(NumArgs)->getLocStart(),
+                diag::err_typecheck_call_too_many_args)
+      << 0 /*function call*/ << NumArgs << TheCall->getNumArgs()
+      << SourceRange(TheCall->getArg(NumArgs)->getLocStart(),
+                     (*(TheCall->arg_end()-1))->getLocEnd());
+
+  Expr *OrigArg = TheCall->getArg(NumArgs-1);
+
+  if (OrigArg->isTypeDependent())
+    return false;
+
+  // This operation requires a floating-point number
+  if (!OrigArg->getType()->isRealFloatingType())
+    return Diag(OrigArg->getLocStart(),
+                diag::err_typecheck_call_invalid_unary_fp)
+      << OrigArg->getType() << OrigArg->getSourceRange();
+
+  return false;
+}
+
+/// SemaBuiltinShuffleVector - Handle __builtin_shufflevector.
+// This is declared to take (...), so we have to check everything.
+Action::OwningExprResult Sema::SemaBuiltinShuffleVector(CallExpr *TheCall) {
+  if (TheCall->getNumArgs() < 3)
+    return ExprError(Diag(TheCall->getLocEnd(),
+                          diag::err_typecheck_call_too_few_args_at_least)
+      << 0 /*function call*/ << 3 << TheCall->getNumArgs()
+      << TheCall->getSourceRange());
+
+  unsigned numElements = std::numeric_limits<unsigned>::max();
+  if (!TheCall->getArg(0)->isTypeDependent() &&
+      !TheCall->getArg(1)->isTypeDependent()) {
+    QualType FAType = TheCall->getArg(0)->getType();
+    QualType SAType = TheCall->getArg(1)->getType();
+
+    if (!FAType->isVectorType() || !SAType->isVectorType()) {
+      Diag(TheCall->getLocStart(), diag::err_shufflevector_non_vector)
+        << SourceRange(TheCall->getArg(0)->getLocStart(),
+                       TheCall->getArg(1)->getLocEnd());
+      return ExprError();
+    }
+
+    if (!Context.hasSameUnqualifiedType(FAType, SAType)) {
+      Diag(TheCall->getLocStart(), diag::err_shufflevector_incompatible_vector)
+        << SourceRange(TheCall->getArg(0)->getLocStart(),
+                       TheCall->getArg(1)->getLocEnd());
+      return ExprError();
+    }
+
+    numElements = FAType->getAs<VectorType>()->getNumElements();
+    if (TheCall->getNumArgs() != numElements+2) {
+      if (TheCall->getNumArgs() < numElements+2)
+        return ExprError(Diag(TheCall->getLocEnd(),
+                              diag::err_typecheck_call_too_few_args)
+                 << 0 /*function call*/ 
+                 << numElements+2 << TheCall->getNumArgs()
+                 << TheCall->getSourceRange());
+      return ExprError(Diag(TheCall->getLocEnd(),
+                            diag::err_typecheck_call_too_many_args)
+                 << 0 /*function call*/ 
+                 << numElements+2 << TheCall->getNumArgs()
+                 << TheCall->getSourceRange());
+    }
+  }
+
+  for (unsigned i = 2; i < TheCall->getNumArgs(); i++) {
+    if (TheCall->getArg(i)->isTypeDependent() ||
+        TheCall->getArg(i)->isValueDependent())
+      continue;
+
+    llvm::APSInt Result;
+    if (SemaBuiltinConstantArg(TheCall, i, Result))
+      return ExprError();
+
+    if (Result.getActiveBits() > 64 || Result.getZExtValue() >= numElements*2)
+      return ExprError(Diag(TheCall->getLocStart(),
+                  diag::err_shufflevector_argument_too_large)
+               << TheCall->getArg(i)->getSourceRange());
+  }
+
+  llvm::SmallVector<Expr*, 32> exprs;
+
+  for (unsigned i = 0, e = TheCall->getNumArgs(); i != e; i++) {
+    exprs.push_back(TheCall->getArg(i));
+    TheCall->setArg(i, 0);
+  }
+
+  return Owned(new (Context) ShuffleVectorExpr(Context, exprs.begin(),
+                                            exprs.size(), exprs[0]->getType(),
+                                            TheCall->getCallee()->getLocStart(),
+                                            TheCall->getRParenLoc()));
+}
+
+/// SemaBuiltinPrefetch - Handle __builtin_prefetch.
+// This is declared to take (const void*, ...) and can take two
+// optional constant int args.
+bool Sema::SemaBuiltinPrefetch(CallExpr *TheCall) {
+  unsigned NumArgs = TheCall->getNumArgs();
+
+  if (NumArgs > 3)
+    return Diag(TheCall->getLocEnd(),
+             diag::err_typecheck_call_too_many_args_at_most)
+             << 0 /*function call*/ << 3 << NumArgs
+             << TheCall->getSourceRange();
+
+  // Argument 0 is checked for us and the remaining arguments must be
+  // constant integers.
+  for (unsigned i = 1; i != NumArgs; ++i) {
+    Expr *Arg = TheCall->getArg(i);
+    
+    llvm::APSInt Result;
+    if (SemaBuiltinConstantArg(TheCall, i, Result))
+      return true;
+
+    // FIXME: gcc issues a warning and rewrites these to 0. These
+    // seems especially odd for the third argument since the default
+    // is 3.
+    if (i == 1) {
+      if (Result.getLimitedValue() > 1)
+        return Diag(TheCall->getLocStart(), diag::err_argument_invalid_range)
+             << "0" << "1" << Arg->getSourceRange();
+    } else {
+      if (Result.getLimitedValue() > 3)
+        return Diag(TheCall->getLocStart(), diag::err_argument_invalid_range)
+            << "0" << "3" << Arg->getSourceRange();
+    }
+  }
+
+  return false;
+}
+
+/// SemaBuiltinConstantArg - Handle a check if argument ArgNum of CallExpr
+/// TheCall is a constant expression.
+bool Sema::SemaBuiltinConstantArg(CallExpr *TheCall, int ArgNum,
+                                  llvm::APSInt &Result) {
+  Expr *Arg = TheCall->getArg(ArgNum);
+  DeclRefExpr *DRE =cast<DeclRefExpr>(TheCall->getCallee()->IgnoreParenCasts());
+  FunctionDecl *FDecl = cast<FunctionDecl>(DRE->getDecl());
+  
+  if (Arg->isTypeDependent() || Arg->isValueDependent()) return false;
+  
+  if (!Arg->isIntegerConstantExpr(Result, Context))
+    return Diag(TheCall->getLocStart(), diag::err_constant_integer_arg_type)
+                << FDecl->getDeclName() <<  Arg->getSourceRange();
+  
+  return false;
+}
+
+/// SemaBuiltinObjectSize - Handle __builtin_object_size(void *ptr,
+/// int type). This simply type checks that type is one of the defined
+/// constants (0-3).
+// For compatability check 0-3, llvm only handles 0 and 2.
+bool Sema::SemaBuiltinObjectSize(CallExpr *TheCall) {
+  llvm::APSInt Result;
+  
+  // Check constant-ness first.
+  if (SemaBuiltinConstantArg(TheCall, 1, Result))
+    return true;
+
+  Expr *Arg = TheCall->getArg(1);
+  if (Result.getSExtValue() < 0 || Result.getSExtValue() > 3) {
+    return Diag(TheCall->getLocStart(), diag::err_argument_invalid_range)
+             << "0" << "3" << SourceRange(Arg->getLocStart(), Arg->getLocEnd());
+  }
+
+  return false;
+}
+
+/// SemaBuiltinLongjmp - Handle __builtin_longjmp(void *env[5], int val).
+/// This checks that val is a constant 1.
+bool Sema::SemaBuiltinLongjmp(CallExpr *TheCall) {
+  Expr *Arg = TheCall->getArg(1);
+  llvm::APSInt Result;
+
+  // TODO: This is less than ideal. Overload this to take a value.
+  if (SemaBuiltinConstantArg(TheCall, 1, Result))
+    return true;
+  
+  if (Result != 1)
+    return Diag(TheCall->getLocStart(), diag::err_builtin_longjmp_invalid_val)
+             << SourceRange(Arg->getLocStart(), Arg->getLocEnd());
+
+  return false;
+}
+
+// Handle i > 1 ? "x" : "y", recursivelly
+bool Sema::SemaCheckStringLiteral(const Expr *E, const CallExpr *TheCall,
+                                  bool HasVAListArg,
+                                  unsigned format_idx, unsigned firstDataArg) {
+  if (E->isTypeDependent() || E->isValueDependent())
+    return false;
+
+  switch (E->getStmtClass()) {
+  case Stmt::ConditionalOperatorClass: {
+    const ConditionalOperator *C = cast<ConditionalOperator>(E);
+    return SemaCheckStringLiteral(C->getTrueExpr(), TheCall,
+                                  HasVAListArg, format_idx, firstDataArg)
+        && SemaCheckStringLiteral(C->getRHS(), TheCall,
+                                  HasVAListArg, format_idx, firstDataArg);
+  }
+
+  case Stmt::ImplicitCastExprClass: {
+    const ImplicitCastExpr *Expr = cast<ImplicitCastExpr>(E);
+    return SemaCheckStringLiteral(Expr->getSubExpr(), TheCall, HasVAListArg,
+                                  format_idx, firstDataArg);
+  }
+
+  case Stmt::ParenExprClass: {
+    const ParenExpr *Expr = cast<ParenExpr>(E);
+    return SemaCheckStringLiteral(Expr->getSubExpr(), TheCall, HasVAListArg,
+                                  format_idx, firstDataArg);
+  }
+
+  case Stmt::DeclRefExprClass: {
+    const DeclRefExpr *DR = cast<DeclRefExpr>(E);
+
+    // As an exception, do not flag errors for variables binding to
+    // const string literals.
+    if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
+      bool isConstant = false;
+      QualType T = DR->getType();
+
+      if (const ArrayType *AT = Context.getAsArrayType(T)) {
+        isConstant = AT->getElementType().isConstant(Context);
+      } else if (const PointerType *PT = T->getAs<PointerType>()) {
+        isConstant = T.isConstant(Context) &&
+                     PT->getPointeeType().isConstant(Context);
+      }
+
+      if (isConstant) {
+        if (const Expr *Init = VD->getAnyInitializer())
+          return SemaCheckStringLiteral(Init, TheCall,
+                                        HasVAListArg, format_idx, firstDataArg);
+      }
+
+      // For vprintf* functions (i.e., HasVAListArg==true), we add a
+      // special check to see if the format string is a function parameter
+      // of the function calling the printf function.  If the function
+      // has an attribute indicating it is a printf-like function, then we
+      // should suppress warnings concerning non-literals being used in a call
+      // to a vprintf function.  For example:
+      //
+      // void
+      // logmessage(char const *fmt __attribute__ (format (printf, 1, 2)), ...){
+      //      va_list ap;
+      //      va_start(ap, fmt);
+      //      vprintf(fmt, ap);  // Do NOT emit a warning about "fmt".
+      //      ...
+      //
+      //
+      //  FIXME: We don't have full attribute support yet, so just check to see
+      //    if the argument is a DeclRefExpr that references a parameter.  We'll
+      //    add proper support for checking the attribute later.
+      if (HasVAListArg)
+        if (isa<ParmVarDecl>(VD))
+          return true;
+    }
+
+    return false;
+  }
+
+  case Stmt::CallExprClass: {
+    const CallExpr *CE = cast<CallExpr>(E);
+    if (const ImplicitCastExpr *ICE
+          = dyn_cast<ImplicitCastExpr>(CE->getCallee())) {
+      if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(ICE->getSubExpr())) {
+        if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(DRE->getDecl())) {
+          if (const FormatArgAttr *FA = FD->getAttr<FormatArgAttr>()) {
+            unsigned ArgIndex = FA->getFormatIdx();
+            const Expr *Arg = CE->getArg(ArgIndex - 1);
+
+            return SemaCheckStringLiteral(Arg, TheCall, HasVAListArg,
+                                          format_idx, firstDataArg);
+          }
+        }
+      }
+    }
+
+    return false;
+  }
+  case Stmt::ObjCStringLiteralClass:
+  case Stmt::StringLiteralClass: {
+    const StringLiteral *StrE = NULL;
+
+    if (const ObjCStringLiteral *ObjCFExpr = dyn_cast<ObjCStringLiteral>(E))
+      StrE = ObjCFExpr->getString();
+    else
+      StrE = cast<StringLiteral>(E);
+
+    if (StrE) {
+      CheckPrintfString(StrE, E, TheCall, HasVAListArg, format_idx,
+                        firstDataArg);
+      return true;
+    }
+
+    return false;
+  }
+
+  default:
+    return false;
+  }
+}
+
+void
+Sema::CheckNonNullArguments(const NonNullAttr *NonNull,
+                            const CallExpr *TheCall) {
+  for (NonNullAttr::iterator i = NonNull->begin(), e = NonNull->end();
+       i != e; ++i) {
+    const Expr *ArgExpr = TheCall->getArg(*i);
+    if (ArgExpr->isNullPointerConstant(Context,
+                                       Expr::NPC_ValueDependentIsNotNull))
+      Diag(TheCall->getCallee()->getLocStart(), diag::warn_null_arg)
+        << ArgExpr->getSourceRange();
+  }
+}
+
+/// CheckPrintfArguments - Check calls to printf (and similar functions) for
+/// correct use of format strings.
+///
+///  HasVAListArg - A predicate indicating whether the printf-like
+///    function is passed an explicit va_arg argument (e.g., vprintf)
+///
+///  format_idx - The index into Args for the format string.
+///
+/// Improper format strings to functions in the printf family can be
+/// the source of bizarre bugs and very serious security holes.  A
+/// good source of information is available in the following paper
+/// (which includes additional references):
+///
+///  FormatGuard: Automatic Protection From printf Format String
+///  Vulnerabilities, Proceedings of the 10th USENIX Security Symposium, 2001.
+///
+/// TODO:
+/// Functionality implemented:
+///
+///  We can statically check the following properties for string
+///  literal format strings for non v.*printf functions (where the
+///  arguments are passed directly):
+//
+///  (1) Are the number of format conversions equal to the number of
+///      data arguments?
+///
+///  (2) Does each format conversion correctly match the type of the
+///      corresponding data argument?
+///
+/// Moreover, for all printf functions we can:
+///
+///  (3) Check for a missing format string (when not caught by type checking).
+///
+///  (4) Check for no-operation flags; e.g. using "#" with format
+///      conversion 'c'  (TODO)
+///
+///  (5) Check the use of '%n', a major source of security holes.
+///
+///  (6) Check for malformed format conversions that don't specify anything.
+///
+///  (7) Check for empty format strings.  e.g: printf("");
+///
+///  (8) Check that the format string is a wide literal.
+///
+/// All of these checks can be done by parsing the format string.
+///
+void
+Sema::CheckPrintfArguments(const CallExpr *TheCall, bool HasVAListArg,
+                           unsigned format_idx, unsigned firstDataArg) {
+  const Expr *Fn = TheCall->getCallee();
+
+  // The way the format attribute works in GCC, the implicit this argument
+  // of member functions is counted. However, it doesn't appear in our own
+  // lists, so decrement format_idx in that case.
+  if (isa<CXXMemberCallExpr>(TheCall)) {
+    // Catch a format attribute mistakenly referring to the object argument.
+    if (format_idx == 0)
+      return;
+    --format_idx;
+    if(firstDataArg != 0)
+      --firstDataArg;
+  }
+
+  // CHECK: printf-like function is called with no format string.
+  if (format_idx >= TheCall->getNumArgs()) {
+    Diag(TheCall->getRParenLoc(), diag::warn_printf_missing_format_string)
+      << Fn->getSourceRange();
+    return;
+  }
+
+  const Expr *OrigFormatExpr = TheCall->getArg(format_idx)->IgnoreParenCasts();
+
+  // CHECK: format string is not a string literal.
+  //
+  // Dynamically generated format strings are difficult to
+  // automatically vet at compile time.  Requiring that format strings
+  // are string literals: (1) permits the checking of format strings by
+  // the compiler and thereby (2) can practically remove the source of
+  // many format string exploits.
+
+  // Format string can be either ObjC string (e.g. @"%d") or
+  // C string (e.g. "%d")
+  // ObjC string uses the same format specifiers as C string, so we can use
+  // the same format string checking logic for both ObjC and C strings.
+  if (SemaCheckStringLiteral(OrigFormatExpr, TheCall, HasVAListArg, format_idx,
+                             firstDataArg))
+    return;  // Literal format string found, check done!
+
+  // If there are no arguments specified, warn with -Wformat-security, otherwise
+  // warn only with -Wformat-nonliteral.
+  if (TheCall->getNumArgs() == format_idx+1)
+    Diag(TheCall->getArg(format_idx)->getLocStart(),
+         diag::warn_printf_nonliteral_noargs)
+      << OrigFormatExpr->getSourceRange();
+  else
+    Diag(TheCall->getArg(format_idx)->getLocStart(),
+         diag::warn_printf_nonliteral)
+           << OrigFormatExpr->getSourceRange();
+}
+
+namespace {
+class CheckPrintfHandler : public analyze_printf::FormatStringHandler {
+  Sema &S;
+  const StringLiteral *FExpr;
+  const Expr *OrigFormatExpr;
+  const unsigned FirstDataArg;
+  const unsigned NumDataArgs;
+  const bool IsObjCLiteral;
+  const char *Beg; // Start of format string.
+  const bool HasVAListArg;
+  const CallExpr *TheCall;
+  unsigned FormatIdx;
+  llvm::BitVector CoveredArgs;
+  bool usesPositionalArgs;
+  bool atFirstArg;
+public:
+  CheckPrintfHandler(Sema &s, const StringLiteral *fexpr,
+                     const Expr *origFormatExpr, unsigned firstDataArg,
+                     unsigned numDataArgs, bool isObjCLiteral,
+                     const char *beg, bool hasVAListArg,
+                     const CallExpr *theCall, unsigned formatIdx)
+    : S(s), FExpr(fexpr), OrigFormatExpr(origFormatExpr),
+      FirstDataArg(firstDataArg),
+      NumDataArgs(numDataArgs),
+      IsObjCLiteral(isObjCLiteral), Beg(beg),
+      HasVAListArg(hasVAListArg),
+      TheCall(theCall), FormatIdx(formatIdx),
+      usesPositionalArgs(false), atFirstArg(true) {
+        CoveredArgs.resize(numDataArgs);
+        CoveredArgs.reset();
+      }
+
+  void DoneProcessing();
+
+  void HandleIncompleteFormatSpecifier(const char *startSpecifier,
+                                       unsigned specifierLen);
+
+  bool
+  HandleInvalidConversionSpecifier(const analyze_printf::FormatSpecifier &FS,
+                                   const char *startSpecifier,
+                                   unsigned specifierLen);
+
+  virtual void HandleInvalidPosition(const char *startSpecifier,
+                                     unsigned specifierLen,
+                                     analyze_printf::PositionContext p);
+
+  virtual void HandleZeroPosition(const char *startPos, unsigned posLen);
+
+  void HandleNullChar(const char *nullCharacter);
+
+  bool HandleFormatSpecifier(const analyze_printf::FormatSpecifier &FS,
+                             const char *startSpecifier,
+                             unsigned specifierLen);
+private:
+  SourceRange getFormatStringRange();
+  SourceRange getFormatSpecifierRange(const char *startSpecifier,
+                                      unsigned specifierLen);
+  SourceLocation getLocationOfByte(const char *x);
+
+  bool HandleAmount(const analyze_printf::OptionalAmount &Amt, unsigned k,
+                    const char *startSpecifier, unsigned specifierLen);
+  void HandleFlags(const analyze_printf::FormatSpecifier &FS,
+                   llvm::StringRef flag, llvm::StringRef cspec,
+                   const char *startSpecifier, unsigned specifierLen);
+
+  const Expr *getDataArg(unsigned i) const;
+};
+}
+
+SourceRange CheckPrintfHandler::getFormatStringRange() {
+  return OrigFormatExpr->getSourceRange();
+}
+
+SourceRange CheckPrintfHandler::
+getFormatSpecifierRange(const char *startSpecifier, unsigned specifierLen) {
+  return SourceRange(getLocationOfByte(startSpecifier),
+                     getLocationOfByte(startSpecifier+specifierLen-1));
+}
+
+SourceLocation CheckPrintfHandler::getLocationOfByte(const char *x) {
+  return S.getLocationOfStringLiteralByte(FExpr, x - Beg);
+}
+
+void CheckPrintfHandler::
+HandleIncompleteFormatSpecifier(const char *startSpecifier,
+                                unsigned specifierLen) {
+  SourceLocation Loc = getLocationOfByte(startSpecifier);
+  S.Diag(Loc, diag::warn_printf_incomplete_specifier)
+    << getFormatSpecifierRange(startSpecifier, specifierLen);
+}
+
+void
+CheckPrintfHandler::HandleInvalidPosition(const char *startPos, unsigned posLen,
+                                          analyze_printf::PositionContext p) {
+  SourceLocation Loc = getLocationOfByte(startPos);
+  S.Diag(Loc, diag::warn_printf_invalid_positional_specifier)
+    << (unsigned) p << getFormatSpecifierRange(startPos, posLen);
+}
+
+void CheckPrintfHandler::HandleZeroPosition(const char *startPos,
+                                            unsigned posLen) {
+  SourceLocation Loc = getLocationOfByte(startPos);
+  S.Diag(Loc, diag::warn_printf_zero_positional_specifier)
+    << getFormatSpecifierRange(startPos, posLen);
+}
+
+bool CheckPrintfHandler::
+HandleInvalidConversionSpecifier(const analyze_printf::FormatSpecifier &FS,
+                                 const char *startSpecifier,
+                                 unsigned specifierLen) {
+
+  unsigned argIndex = FS.getArgIndex();
+  bool keepGoing = true;
+  if (argIndex < NumDataArgs) {
+    // Consider the argument coverered, even though the specifier doesn't
+    // make sense.
+    CoveredArgs.set(argIndex);
+  }
+  else {
+    // If argIndex exceeds the number of data arguments we
+    // don't issue a warning because that is just a cascade of warnings (and
+    // they may have intended '%%' anyway). We don't want to continue processing
+    // the format string after this point, however, as we will like just get
+    // gibberish when trying to match arguments.
+    keepGoing = false;
+  }
+
+  const analyze_printf::ConversionSpecifier &CS =
+    FS.getConversionSpecifier();
+  SourceLocation Loc = getLocationOfByte(CS.getStart());
+  S.Diag(Loc, diag::warn_printf_invalid_conversion)
+      << llvm::StringRef(CS.getStart(), CS.getLength())
+      << getFormatSpecifierRange(startSpecifier, specifierLen);
+
+  return keepGoing;
+}
+
+void CheckPrintfHandler::HandleNullChar(const char *nullCharacter) {
+  // The presence of a null character is likely an error.
+  S.Diag(getLocationOfByte(nullCharacter),
+         diag::warn_printf_format_string_contains_null_char)
+    << getFormatStringRange();
+}
+
+const Expr *CheckPrintfHandler::getDataArg(unsigned i) const {
+  return TheCall->getArg(FirstDataArg + i);
+}
+
+void CheckPrintfHandler::HandleFlags(const analyze_printf::FormatSpecifier &FS,
+                                     llvm::StringRef flag,
+                                     llvm::StringRef cspec,
+                                     const char *startSpecifier,
+                                     unsigned specifierLen) {
+  const analyze_printf::ConversionSpecifier &CS = FS.getConversionSpecifier();
+  S.Diag(getLocationOfByte(CS.getStart()), diag::warn_printf_nonsensical_flag)
+    << flag << cspec << getFormatSpecifierRange(startSpecifier, specifierLen);
+}
+
+bool
+CheckPrintfHandler::HandleAmount(const analyze_printf::OptionalAmount &Amt,
+                                 unsigned k, const char *startSpecifier,
+                                 unsigned specifierLen) {
+
+  if (Amt.hasDataArgument()) {
+    if (!HasVAListArg) {
+      unsigned argIndex = Amt.getArgIndex();
+      if (argIndex >= NumDataArgs) {
+        S.Diag(getLocationOfByte(Amt.getStart()),
+               diag::warn_printf_asterisk_missing_arg)
+          << k << getFormatSpecifierRange(startSpecifier, specifierLen);
+        // Don't do any more checking.  We will just emit
+        // spurious errors.
+        return false;
+      }
+
+      // Type check the data argument.  It should be an 'int'.
+      // Although not in conformance with C99, we also allow the argument to be
+      // an 'unsigned int' as that is a reasonably safe case.  GCC also
+      // doesn't emit a warning for that case.
+      CoveredArgs.set(argIndex);
+      const Expr *Arg = getDataArg(argIndex);
+      QualType T = Arg->getType();
+
+      const analyze_printf::ArgTypeResult &ATR = Amt.getArgType(S.Context);
+      assert(ATR.isValid());
+
+      if (!ATR.matchesType(S.Context, T)) {
+        S.Diag(getLocationOfByte(Amt.getStart()),
+               diag::warn_printf_asterisk_wrong_type)
+          << k
+          << ATR.getRepresentativeType(S.Context) << T
+          << getFormatSpecifierRange(startSpecifier, specifierLen)
+          << Arg->getSourceRange();
+        // Don't do any more checking.  We will just emit
+        // spurious errors.
+        return false;
+      }
+    }
+  }
+  return true;
+}
+
+bool
+CheckPrintfHandler::HandleFormatSpecifier(const analyze_printf::FormatSpecifier
+                                            &FS,
+                                          const char *startSpecifier,
+                                          unsigned specifierLen) {
+
+  using namespace analyze_printf;  
+  const ConversionSpecifier &CS = FS.getConversionSpecifier();
+
+  if (atFirstArg) {
+    atFirstArg = false;
+    usesPositionalArgs = FS.usesPositionalArg();
+  }
+  else if (usesPositionalArgs != FS.usesPositionalArg()) {
+    // Cannot mix-and-match positional and non-positional arguments.
+    S.Diag(getLocationOfByte(CS.getStart()),
+           diag::warn_printf_mix_positional_nonpositional_args)
+      << getFormatSpecifierRange(startSpecifier, specifierLen);
+    return false;
+  }
+
+  // First check if the field width, precision, and conversion specifier
+  // have matching data arguments.
+  if (!HandleAmount(FS.getFieldWidth(), /* field width */ 0,
+                    startSpecifier, specifierLen)) {
+    return false;
+  }
+
+  if (!HandleAmount(FS.getPrecision(), /* precision */ 1,
+                    startSpecifier, specifierLen)) {
+    return false;
+  }
+
+  if (!CS.consumesDataArgument()) {
+    // FIXME: Technically specifying a precision or field width here
+    // makes no sense.  Worth issuing a warning at some point.
+    return true;
+  }
+
+  // Consume the argument.
+  unsigned argIndex = FS.getArgIndex();
+  if (argIndex < NumDataArgs) {
+    // The check to see if the argIndex is valid will come later.
+    // We set the bit here because we may exit early from this
+    // function if we encounter some other error.
+    CoveredArgs.set(argIndex);
+  }
+
+  // Check for using an Objective-C specific conversion specifier
+  // in a non-ObjC literal.
+  if (!IsObjCLiteral && CS.isObjCArg()) {
+    return HandleInvalidConversionSpecifier(FS, startSpecifier, specifierLen);
+  }
+
+  // Are we using '%n'?  Issue a warning about this being
+  // a possible security issue.
+  if (CS.getKind() == ConversionSpecifier::OutIntPtrArg) {
+    S.Diag(getLocationOfByte(CS.getStart()), diag::warn_printf_write_back)
+      << getFormatSpecifierRange(startSpecifier, specifierLen);
+    // Continue checking the other format specifiers.
+    return true;
+  }
+
+  if (CS.getKind() == ConversionSpecifier::VoidPtrArg) {
+    if (FS.getPrecision().getHowSpecified() != OptionalAmount::NotSpecified)
+      S.Diag(getLocationOfByte(CS.getStart()),
+             diag::warn_printf_nonsensical_precision)
+        << CS.getCharacters()
+        << getFormatSpecifierRange(startSpecifier, specifierLen);
+  }
+  if (CS.getKind() == ConversionSpecifier::VoidPtrArg ||
+      CS.getKind() == ConversionSpecifier::CStrArg) {
+    // FIXME: Instead of using "0", "+", etc., eventually get them from
+    // the FormatSpecifier.
+    if (FS.hasLeadingZeros())
+      HandleFlags(FS, "0", CS.getCharacters(), startSpecifier, specifierLen);
+    if (FS.hasPlusPrefix())
+      HandleFlags(FS, "+", CS.getCharacters(), startSpecifier, specifierLen);
+    if (FS.hasSpacePrefix())
+      HandleFlags(FS, " ", CS.getCharacters(), startSpecifier, specifierLen);
+  }
+
+  // The remaining checks depend on the data arguments.
+  if (HasVAListArg)
+    return true;
+
+  if (argIndex >= NumDataArgs) {
+    if (FS.usesPositionalArg())  {
+      S.Diag(getLocationOfByte(CS.getStart()),
+             diag::warn_printf_positional_arg_exceeds_data_args)
+        << (argIndex+1) << NumDataArgs
+        << getFormatSpecifierRange(startSpecifier, specifierLen);
+    }
+    else {
+      S.Diag(getLocationOfByte(CS.getStart()),
+             diag::warn_printf_insufficient_data_args)
+        << getFormatSpecifierRange(startSpecifier, specifierLen);
+    }
+
+    // Don't do any more checking.
+    return false;
+  }
+
+  // Now type check the data expression that matches the
+  // format specifier.
+  const Expr *Ex = getDataArg(argIndex);
+  const analyze_printf::ArgTypeResult &ATR = FS.getArgType(S.Context);
+  if (ATR.isValid() && !ATR.matchesType(S.Context, Ex->getType())) {
+    // Check if we didn't match because of an implicit cast from a 'char'
+    // or 'short' to an 'int'.  This is done because printf is a varargs
+    // function.
+    if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Ex))
+      if (ICE->getType() == S.Context.IntTy)
+        if (ATR.matchesType(S.Context, ICE->getSubExpr()->getType()))
+          return true;
+
+    S.Diag(getLocationOfByte(CS.getStart()),
+           diag::warn_printf_conversion_argument_type_mismatch)
+      << ATR.getRepresentativeType(S.Context) << Ex->getType()
+      << getFormatSpecifierRange(startSpecifier, specifierLen)
+      << Ex->getSourceRange();
+  }
+
+  return true;
+}
+
+void CheckPrintfHandler::DoneProcessing() {
+  // Does the number of data arguments exceed the number of
+  // format conversions in the format string?
+  if (!HasVAListArg) {
+    // Find any arguments that weren't covered.
+    CoveredArgs.flip();
+    signed notCoveredArg = CoveredArgs.find_first();
+    if (notCoveredArg >= 0) {
+      assert((unsigned)notCoveredArg < NumDataArgs);
+      S.Diag(getDataArg((unsigned) notCoveredArg)->getLocStart(),
+             diag::warn_printf_data_arg_not_used)
+        << getFormatStringRange();
+    }
+  }
+}
+
+void Sema::CheckPrintfString(const StringLiteral *FExpr,
+                             const Expr *OrigFormatExpr,
+                             const CallExpr *TheCall, bool HasVAListArg,
+                             unsigned format_idx, unsigned firstDataArg) {
+
+  // CHECK: is the format string a wide literal?
+  if (FExpr->isWide()) {
+    Diag(FExpr->getLocStart(),
+         diag::warn_printf_format_string_is_wide_literal)
+    << OrigFormatExpr->getSourceRange();
+    return;
+  }
+
+  // Str - The format string.  NOTE: this is NOT null-terminated!
+  const char *Str = FExpr->getStrData();
+
+  // CHECK: empty format string?
+  unsigned StrLen = FExpr->getByteLength();
+
+  if (StrLen == 0) {
+    Diag(FExpr->getLocStart(), diag::warn_printf_empty_format_string)
+    << OrigFormatExpr->getSourceRange();
+    return;
+  }
+
+  CheckPrintfHandler H(*this, FExpr, OrigFormatExpr, firstDataArg,
+                       TheCall->getNumArgs() - firstDataArg,
+                       isa<ObjCStringLiteral>(OrigFormatExpr), Str,
+                       HasVAListArg, TheCall, format_idx);
+
+  if (!analyze_printf::ParseFormatString(H, Str, Str + StrLen))
+    H.DoneProcessing();
+}
+
+//===--- CHECK: Return Address of Stack Variable --------------------------===//
+
+static DeclRefExpr* EvalVal(Expr *E);
+static DeclRefExpr* EvalAddr(Expr* E);
+
+/// CheckReturnStackAddr - Check if a return statement returns the address
+///   of a stack variable.
+void
+Sema::CheckReturnStackAddr(Expr *RetValExp, QualType lhsType,
+                           SourceLocation ReturnLoc) {
+
+  // Perform checking for returned stack addresses.
+  if (lhsType->isPointerType() || lhsType->isBlockPointerType()) {
+    if (DeclRefExpr *DR = EvalAddr(RetValExp))
+      Diag(DR->getLocStart(), diag::warn_ret_stack_addr)
+       << DR->getDecl()->getDeclName() << RetValExp->getSourceRange();
+
+    // Skip over implicit cast expressions when checking for block expressions.
+    RetValExp = RetValExp->IgnoreParenCasts();
+
+    if (BlockExpr *C = dyn_cast<BlockExpr>(RetValExp))
+      if (C->hasBlockDeclRefExprs())
+        Diag(C->getLocStart(), diag::err_ret_local_block)
+          << C->getSourceRange();
+
+    if (AddrLabelExpr *ALE = dyn_cast<AddrLabelExpr>(RetValExp))
+      Diag(ALE->getLocStart(), diag::warn_ret_addr_label)
+        << ALE->getSourceRange();
+
+  } else if (lhsType->isReferenceType()) {
+    // Perform checking for stack values returned by reference.
+    // Check for a reference to the stack
+    if (DeclRefExpr *DR = EvalVal(RetValExp))
+      Diag(DR->getLocStart(), diag::warn_ret_stack_ref)
+        << DR->getDecl()->getDeclName() << RetValExp->getSourceRange();
+  }
+}
+
+/// EvalAddr - EvalAddr and EvalVal are mutually recursive functions that
+///  check if the expression in a return statement evaluates to an address
+///  to a location on the stack.  The recursion is used to traverse the
+///  AST of the return expression, with recursion backtracking when we
+///  encounter a subexpression that (1) clearly does not lead to the address
+///  of a stack variable or (2) is something we cannot determine leads to
+///  the address of a stack variable based on such local checking.
+///
+///  EvalAddr processes expressions that are pointers that are used as
+///  references (and not L-values).  EvalVal handles all other values.
+///  At the base case of the recursion is a check for a DeclRefExpr* in
+///  the refers to a stack variable.
+///
+///  This implementation handles:
+///
+///   * pointer-to-pointer casts
+///   * implicit conversions from array references to pointers
+///   * taking the address of fields
+///   * arbitrary interplay between "&" and "*" operators
+///   * pointer arithmetic from an address of a stack variable
+///   * taking the address of an array element where the array is on the stack
+static DeclRefExpr* EvalAddr(Expr *E) {
+  // We should only be called for evaluating pointer expressions.
+  assert((E->getType()->isAnyPointerType() ||
+          E->getType()->isBlockPointerType() ||
+          E->getType()->isObjCQualifiedIdType()) &&
+         "EvalAddr only works on pointers");
+
+  // Our "symbolic interpreter" is just a dispatch off the currently
+  // viewed AST node.  We then recursively traverse the AST by calling
+  // EvalAddr and EvalVal appropriately.
+  switch (E->getStmtClass()) {
+  case Stmt::ParenExprClass:
+    // Ignore parentheses.
+    return EvalAddr(cast<ParenExpr>(E)->getSubExpr());
+
+  case Stmt::UnaryOperatorClass: {
+    // The only unary operator that make sense to handle here
+    // is AddrOf.  All others don't make sense as pointers.
+    UnaryOperator *U = cast<UnaryOperator>(E);
+
+    if (U->getOpcode() == UnaryOperator::AddrOf)
+      return EvalVal(U->getSubExpr());
+    else
+      return NULL;
+  }
+
+  case Stmt::BinaryOperatorClass: {
+    // Handle pointer arithmetic.  All other binary operators are not valid
+    // in this context.
+    BinaryOperator *B = cast<BinaryOperator>(E);
+    BinaryOperator::Opcode op = B->getOpcode();
+
+    if (op != BinaryOperator::Add && op != BinaryOperator::Sub)
+      return NULL;
+
+    Expr *Base = B->getLHS();
+
+    // Determine which argument is the real pointer base.  It could be
+    // the RHS argument instead of the LHS.
+    if (!Base->getType()->isPointerType()) Base = B->getRHS();
+
+    assert (Base->getType()->isPointerType());
+    return EvalAddr(Base);
+  }
+
+  // For conditional operators we need to see if either the LHS or RHS are
+  // valid DeclRefExpr*s.  If one of them is valid, we return it.
+  case Stmt::ConditionalOperatorClass: {
+    ConditionalOperator *C = cast<ConditionalOperator>(E);
+
+    // Handle the GNU extension for missing LHS.
+    if (Expr *lhsExpr = C->getLHS())
+      if (DeclRefExpr* LHS = EvalAddr(lhsExpr))
+        return LHS;
+
+     return EvalAddr(C->getRHS());
+  }
+
+  // For casts, we need to handle conversions from arrays to
+  // pointer values, and pointer-to-pointer conversions.
+  case Stmt::ImplicitCastExprClass:
+  case Stmt::CStyleCastExprClass:
+  case Stmt::CXXFunctionalCastExprClass: {
+    Expr* SubExpr = cast<CastExpr>(E)->getSubExpr();
+    QualType T = SubExpr->getType();
+
+    if (SubExpr->getType()->isPointerType() ||
+        SubExpr->getType()->isBlockPointerType() ||
+        SubExpr->getType()->isObjCQualifiedIdType())
+      return EvalAddr(SubExpr);
+    else if (T->isArrayType())
+      return EvalVal(SubExpr);
+    else
+      return 0;
+  }
+
+  // C++ casts.  For dynamic casts, static casts, and const casts, we
+  // are always converting from a pointer-to-pointer, so we just blow
+  // through the cast.  In the case the dynamic cast doesn't fail (and
+  // return NULL), we take the conservative route and report cases
+  // where we return the address of a stack variable.  For Reinterpre
+  // FIXME: The comment about is wrong; we're not always converting
+  // from pointer to pointer. I'm guessing that this code should also
+  // handle references to objects.
+  case Stmt::CXXStaticCastExprClass:
+  case Stmt::CXXDynamicCastExprClass:
+  case Stmt::CXXConstCastExprClass:
+  case Stmt::CXXReinterpretCastExprClass: {
+      Expr *S = cast<CXXNamedCastExpr>(E)->getSubExpr();
+      if (S->getType()->isPointerType() || S->getType()->isBlockPointerType())
+        return EvalAddr(S);
+      else
+        return NULL;
+  }
+
+  // Everything else: we simply don't reason about them.
+  default:
+    return NULL;
+  }
+}
+
+
+///  EvalVal - This function is complements EvalAddr in the mutual recursion.
+///   See the comments for EvalAddr for more details.
+static DeclRefExpr* EvalVal(Expr *E) {
+
+  // We should only be called for evaluating non-pointer expressions, or
+  // expressions with a pointer type that are not used as references but instead
+  // are l-values (e.g., DeclRefExpr with a pointer type).
+
+  // Our "symbolic interpreter" is just a dispatch off the currently
+  // viewed AST node.  We then recursively traverse the AST by calling
+  // EvalAddr and EvalVal appropriately.
+  switch (E->getStmtClass()) {
+  case Stmt::DeclRefExprClass: {
+    // DeclRefExpr: the base case.  When we hit a DeclRefExpr we are looking
+    //  at code that refers to a variable's name.  We check if it has local
+    //  storage within the function, and if so, return the expression.
+    DeclRefExpr *DR = cast<DeclRefExpr>(E);
+
+    if (VarDecl *V = dyn_cast<VarDecl>(DR->getDecl()))
+      if (V->hasLocalStorage() && !V->getType()->isReferenceType()) return DR;
+
+    return NULL;
+  }
+
+  case Stmt::ParenExprClass:
+    // Ignore parentheses.
+    return EvalVal(cast<ParenExpr>(E)->getSubExpr());
+
+  case Stmt::UnaryOperatorClass: {
+    // The only unary operator that make sense to handle here
+    // is Deref.  All others don't resolve to a "name."  This includes
+    // handling all sorts of rvalues passed to a unary operator.
+    UnaryOperator *U = cast<UnaryOperator>(E);
+
+    if (U->getOpcode() == UnaryOperator::Deref)
+      return EvalAddr(U->getSubExpr());
+
+    return NULL;
+  }
+
+  case Stmt::ArraySubscriptExprClass: {
+    // Array subscripts are potential references to data on the stack.  We
+    // retrieve the DeclRefExpr* for the array variable if it indeed
+    // has local storage.
+    return EvalAddr(cast<ArraySubscriptExpr>(E)->getBase());
+  }
+
+  case Stmt::ConditionalOperatorClass: {
+    // For conditional operators we need to see if either the LHS or RHS are
+    // non-NULL DeclRefExpr's.  If one is non-NULL, we return it.
+    ConditionalOperator *C = cast<ConditionalOperator>(E);
+
+    // Handle the GNU extension for missing LHS.
+    if (Expr *lhsExpr = C->getLHS())
+      if (DeclRefExpr *LHS = EvalVal(lhsExpr))
+        return LHS;
+
+    return EvalVal(C->getRHS());
+  }
+
+  // Accesses to members are potential references to data on the stack.
+  case Stmt::MemberExprClass: {
+    MemberExpr *M = cast<MemberExpr>(E);
+
+    // Check for indirect access.  We only want direct field accesses.
+    if (!M->isArrow())
+      return EvalVal(M->getBase());
+    else
+      return NULL;
+  }
+
+  // Everything else: we simply don't reason about them.
+  default:
+    return NULL;
+  }
+}
+
+//===--- CHECK: Floating-Point comparisons (-Wfloat-equal) ---------------===//
+
+/// Check for comparisons of floating point operands using != and ==.
+/// Issue a warning if these are no self-comparisons, as they are not likely
+/// to do what the programmer intended.
+void Sema::CheckFloatComparison(SourceLocation loc, Expr* lex, Expr *rex) {
+  bool EmitWarning = true;
+
+  Expr* LeftExprSansParen = lex->IgnoreParens();
+  Expr* RightExprSansParen = rex->IgnoreParens();
+
+  // Special case: check for x == x (which is OK).
+  // Do not emit warnings for such cases.
+  if (DeclRefExpr* DRL = dyn_cast<DeclRefExpr>(LeftExprSansParen))
+    if (DeclRefExpr* DRR = dyn_cast<DeclRefExpr>(RightExprSansParen))
+      if (DRL->getDecl() == DRR->getDecl())
+        EmitWarning = false;
+
+
+  // Special case: check for comparisons against literals that can be exactly
+  //  represented by APFloat.  In such cases, do not emit a warning.  This
+  //  is a heuristic: often comparison against such literals are used to
+  //  detect if a value in a variable has not changed.  This clearly can
+  //  lead to false negatives.
+  if (EmitWarning) {
+    if (FloatingLiteral* FLL = dyn_cast<FloatingLiteral>(LeftExprSansParen)) {
+      if (FLL->isExact())
+        EmitWarning = false;
+    } else
+      if (FloatingLiteral* FLR = dyn_cast<FloatingLiteral>(RightExprSansParen)){
+        if (FLR->isExact())
+          EmitWarning = false;
+    }
+  }
+
+  // Check for comparisons with builtin types.
+  if (EmitWarning)
+    if (CallExpr* CL = dyn_cast<CallExpr>(LeftExprSansParen))
+      if (CL->isBuiltinCall(Context))
+        EmitWarning = false;
+
+  if (EmitWarning)
+    if (CallExpr* CR = dyn_cast<CallExpr>(RightExprSansParen))
+      if (CR->isBuiltinCall(Context))
+        EmitWarning = false;
+
+  // Emit the diagnostic.
+  if (EmitWarning)
+    Diag(loc, diag::warn_floatingpoint_eq)
+      << lex->getSourceRange() << rex->getSourceRange();
+}
+
+//===--- CHECK: Integer mixed-sign comparisons (-Wsign-compare) --------===//
+//===--- CHECK: Lossy implicit conversions (-Wconversion) --------------===//
+
+namespace {
+
+/// Structure recording the 'active' range of an integer-valued
+/// expression.
+struct IntRange {
+  /// The number of bits active in the int.
+  unsigned Width;
+
+  /// True if the int is known not to have negative values.
+  bool NonNegative;
+
+  IntRange() {}
+  IntRange(unsigned Width, bool NonNegative)
+    : Width(Width), NonNegative(NonNegative)
+  {}
+
+  // Returns the range of the bool type.
+  static IntRange forBoolType() {
+    return IntRange(1, true);
+  }
+
+  // Returns the range of an integral type.
+  static IntRange forType(ASTContext &C, QualType T) {
+    return forCanonicalType(C, T->getCanonicalTypeInternal().getTypePtr());
+  }
+
+  // Returns the range of an integeral type based on its canonical
+  // representation.
+  static IntRange forCanonicalType(ASTContext &C, const Type *T) {
+    assert(T->isCanonicalUnqualified());
+
+    if (const VectorType *VT = dyn_cast<VectorType>(T))
+      T = VT->getElementType().getTypePtr();
+    if (const ComplexType *CT = dyn_cast<ComplexType>(T))
+      T = CT->getElementType().getTypePtr();
+    if (const EnumType *ET = dyn_cast<EnumType>(T))
+      T = ET->getDecl()->getIntegerType().getTypePtr();
+
+    const BuiltinType *BT = cast<BuiltinType>(T);
+    assert(BT->isInteger());
+
+    return IntRange(C.getIntWidth(QualType(T, 0)), BT->isUnsignedInteger());
+  }
+
+  // Returns the supremum of two ranges: i.e. their conservative merge.
+  static IntRange join(IntRange L, IntRange R) {
+    return IntRange(std::max(L.Width, R.Width),
+                    L.NonNegative && R.NonNegative);
+  }
+
+  // Returns the infinum of two ranges: i.e. their aggressive merge.
+  static IntRange meet(IntRange L, IntRange R) {
+    return IntRange(std::min(L.Width, R.Width),
+                    L.NonNegative || R.NonNegative);
+  }
+};
+
+IntRange GetValueRange(ASTContext &C, llvm::APSInt &value, unsigned MaxWidth) {
+  if (value.isSigned() && value.isNegative())
+    return IntRange(value.getMinSignedBits(), false);
+
+  if (value.getBitWidth() > MaxWidth)
+    value.trunc(MaxWidth);
+
+  // isNonNegative() just checks the sign bit without considering
+  // signedness.
+  return IntRange(value.getActiveBits(), true);
+}
+
+IntRange GetValueRange(ASTContext &C, APValue &result, QualType Ty,
+                       unsigned MaxWidth) {
+  if (result.isInt())
+    return GetValueRange(C, result.getInt(), MaxWidth);
+
+  if (result.isVector()) {
+    IntRange R = GetValueRange(C, result.getVectorElt(0), Ty, MaxWidth);
+    for (unsigned i = 1, e = result.getVectorLength(); i != e; ++i) {
+      IntRange El = GetValueRange(C, result.getVectorElt(i), Ty, MaxWidth);
+      R = IntRange::join(R, El);
+    }
+    return R;
+  }
+
+  if (result.isComplexInt()) {
+    IntRange R = GetValueRange(C, result.getComplexIntReal(), MaxWidth);
+    IntRange I = GetValueRange(C, result.getComplexIntImag(), MaxWidth);
+    return IntRange::join(R, I);
+  }
+
+  // This can happen with lossless casts to intptr_t of "based" lvalues.
+  // Assume it might use arbitrary bits.
+  // FIXME: The only reason we need to pass the type in here is to get
+  // the sign right on this one case.  It would be nice if APValue
+  // preserved this.
+  assert(result.isLValue());
+  return IntRange(MaxWidth, Ty->isUnsignedIntegerType());
+}
+
+/// Pseudo-evaluate the given integer expression, estimating the
+/// range of values it might take.
+///
+/// \param MaxWidth - the width to which the value will be truncated
+IntRange GetExprRange(ASTContext &C, Expr *E, unsigned MaxWidth) {
+  E = E->IgnoreParens();
+
+  // Try a full evaluation first.
+  Expr::EvalResult result;
+  if (E->Evaluate(result, C))
+    return GetValueRange(C, result.Val, E->getType(), MaxWidth);
+
+  // I think we only want to look through implicit casts here; if the
+  // user has an explicit widening cast, we should treat the value as
+  // being of the new, wider type.
+  if (ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E)) {
+    if (CE->getCastKind() == CastExpr::CK_NoOp)
+      return GetExprRange(C, CE->getSubExpr(), MaxWidth);
+
+    IntRange OutputTypeRange = IntRange::forType(C, CE->getType());
+
+    bool isIntegerCast = (CE->getCastKind() == CastExpr::CK_IntegralCast);
+    if (!isIntegerCast && CE->getCastKind() == CastExpr::CK_Unknown)
+      isIntegerCast = CE->getSubExpr()->getType()->isIntegerType();
+
+    // Assume that non-integer casts can span the full range of the type.
+    if (!isIntegerCast)
+      return OutputTypeRange;
+
+    IntRange SubRange
+      = GetExprRange(C, CE->getSubExpr(),
+                     std::min(MaxWidth, OutputTypeRange.Width));
+
+    // Bail out if the subexpr's range is as wide as the cast type.
+    if (SubRange.Width >= OutputTypeRange.Width)
+      return OutputTypeRange;
+
+    // Otherwise, we take the smaller width, and we're non-negative if
+    // either the output type or the subexpr is.
+    return IntRange(SubRange.Width,
+                    SubRange.NonNegative || OutputTypeRange.NonNegative);
+  }
+
+  if (ConditionalOperator *CO = dyn_cast<ConditionalOperator>(E)) {
+    // If we can fold the condition, just take that operand.
+    bool CondResult;
+    if (CO->getCond()->EvaluateAsBooleanCondition(CondResult, C))
+      return GetExprRange(C, CondResult ? CO->getTrueExpr()
+                                        : CO->getFalseExpr(),
+                          MaxWidth);
+
+    // Otherwise, conservatively merge.
+    IntRange L = GetExprRange(C, CO->getTrueExpr(), MaxWidth);
+    IntRange R = GetExprRange(C, CO->getFalseExpr(), MaxWidth);
+    return IntRange::join(L, R);
+  }
+
+  if (BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) {
+    switch (BO->getOpcode()) {
+
+    // Boolean-valued operations are single-bit and positive.
+    case BinaryOperator::LAnd:
+    case BinaryOperator::LOr:
+    case BinaryOperator::LT:
+    case BinaryOperator::GT:
+    case BinaryOperator::LE:
+    case BinaryOperator::GE:
+    case BinaryOperator::EQ:
+    case BinaryOperator::NE:
+      return IntRange::forBoolType();
+
+    // The type of these compound assignments is the type of the LHS,
+    // so the RHS is not necessarily an integer.
+    case BinaryOperator::MulAssign:
+    case BinaryOperator::DivAssign:
+    case BinaryOperator::RemAssign:
+    case BinaryOperator::AddAssign:
+    case BinaryOperator::SubAssign:
+      return IntRange::forType(C, E->getType());
+
+    // Operations with opaque sources are black-listed.
+    case BinaryOperator::PtrMemD:
+    case BinaryOperator::PtrMemI:
+      return IntRange::forType(C, E->getType());
+
+    // Bitwise-and uses the *infinum* of the two source ranges.
+    case BinaryOperator::And:
+    case BinaryOperator::AndAssign:
+      return IntRange::meet(GetExprRange(C, BO->getLHS(), MaxWidth),
+                            GetExprRange(C, BO->getRHS(), MaxWidth));
+
+    // Left shift gets black-listed based on a judgement call.
+    case BinaryOperator::Shl:
+      // ...except that we want to treat '1 << (blah)' as logically
+      // positive.  It's an important idiom.
+      if (IntegerLiteral *I
+            = dyn_cast<IntegerLiteral>(BO->getLHS()->IgnoreParenCasts())) {
+        if (I->getValue() == 1) {
+          IntRange R = IntRange::forType(C, E->getType());
+          return IntRange(R.Width, /*NonNegative*/ true);
+        }
+      }
+      // fallthrough
+
+    case BinaryOperator::ShlAssign:
+      return IntRange::forType(C, E->getType());
+
+    // Right shift by a constant can narrow its left argument.
+    case BinaryOperator::Shr:
+    case BinaryOperator::ShrAssign: {
+      IntRange L = GetExprRange(C, BO->getLHS(), MaxWidth);
+
+      // If the shift amount is a positive constant, drop the width by
+      // that much.
+      llvm::APSInt shift;
+      if (BO->getRHS()->isIntegerConstantExpr(shift, C) &&
+          shift.isNonNegative()) {
+        unsigned zext = shift.getZExtValue();
+        if (zext >= L.Width)
+          L.Width = (L.NonNegative ? 0 : 1);
+        else
+          L.Width -= zext;
+      }
+
+      return L;
+    }
+
+    // Comma acts as its right operand.
+    case BinaryOperator::Comma:
+      return GetExprRange(C, BO->getRHS(), MaxWidth);
+
+    // Black-list pointer subtractions.
+    case BinaryOperator::Sub:
+      if (BO->getLHS()->getType()->isPointerType())
+        return IntRange::forType(C, E->getType());
+      // fallthrough
+
+    default:
+      break;
+    }
+
+    // Treat every other operator as if it were closed on the
+    // narrowest type that encompasses both operands.
+    IntRange L = GetExprRange(C, BO->getLHS(), MaxWidth);
+    IntRange R = GetExprRange(C, BO->getRHS(), MaxWidth);
+    return IntRange::join(L, R);
+  }
+
+  if (UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) {
+    switch (UO->getOpcode()) {
+    // Boolean-valued operations are white-listed.
+    case UnaryOperator::LNot:
+      return IntRange::forBoolType();
+
+    // Operations with opaque sources are black-listed.
+    case UnaryOperator::Deref:
+    case UnaryOperator::AddrOf: // should be impossible
+    case UnaryOperator::OffsetOf:
+      return IntRange::forType(C, E->getType());
+
+    default:
+      return GetExprRange(C, UO->getSubExpr(), MaxWidth);
+    }
+  }
+
+  FieldDecl *BitField = E->getBitField();
+  if (BitField) {
+    llvm::APSInt BitWidthAP = BitField->getBitWidth()->EvaluateAsInt(C);
+    unsigned BitWidth = BitWidthAP.getZExtValue();
+
+    return IntRange(BitWidth, BitField->getType()->isUnsignedIntegerType());
+  }
+
+  return IntRange::forType(C, E->getType());
+}
+
+/// Checks whether the given value, which currently has the given
+/// source semantics, has the same value when coerced through the
+/// target semantics.
+bool IsSameFloatAfterCast(const llvm::APFloat &value,
+                          const llvm::fltSemantics &Src,
+                          const llvm::fltSemantics &Tgt) {
+  llvm::APFloat truncated = value;
+
+  bool ignored;
+  truncated.convert(Src, llvm::APFloat::rmNearestTiesToEven, &ignored);
+  truncated.convert(Tgt, llvm::APFloat::rmNearestTiesToEven, &ignored);
+
+  return truncated.bitwiseIsEqual(value);
+}
+
+/// Checks whether the given value, which currently has the given
+/// source semantics, has the same value when coerced through the
+/// target semantics.
+///
+/// The value might be a vector of floats (or a complex number).
+bool IsSameFloatAfterCast(const APValue &value,
+                          const llvm::fltSemantics &Src,
+                          const llvm::fltSemantics &Tgt) {
+  if (value.isFloat())
+    return IsSameFloatAfterCast(value.getFloat(), Src, Tgt);
+
+  if (value.isVector()) {
+    for (unsigned i = 0, e = value.getVectorLength(); i != e; ++i)
+      if (!IsSameFloatAfterCast(value.getVectorElt(i), Src, Tgt))
+        return false;
+    return true;
+  }
+
+  assert(value.isComplexFloat());
+  return (IsSameFloatAfterCast(value.getComplexFloatReal(), Src, Tgt) &&
+          IsSameFloatAfterCast(value.getComplexFloatImag(), Src, Tgt));
+}
+
+} // end anonymous namespace
+
+/// \brief Implements -Wsign-compare.
+///
+/// \param lex the left-hand expression
+/// \param rex the right-hand expression
+/// \param OpLoc the location of the joining operator
+/// \param BinOpc binary opcode or 0
+void Sema::CheckSignCompare(Expr *lex, Expr *rex, SourceLocation OpLoc,
+                            const BinaryOperator::Opcode* BinOpc) {
+  // Don't warn if we're in an unevaluated context.
+  if (ExprEvalContexts.back().Context == Unevaluated)
+    return;
+
+  // If either expression is value-dependent, don't warn. We'll get another
+  // chance at instantiation time.
+  if (lex->isValueDependent() || rex->isValueDependent())
+    return;
+
+  QualType lt = lex->getType(), rt = rex->getType();
+
+  // Only warn if both operands are integral.
+  if (!lt->isIntegerType() || !rt->isIntegerType())
+    return;
+
+  // In C, the width of a bitfield determines its type, and the
+  // declared type only contributes the signedness.  This duplicates
+  // the work that will later be done by UsualUnaryConversions.
+  // Eventually, this check will be reorganized in a way that avoids
+  // this duplication.
+  if (!getLangOptions().CPlusPlus) {
+    QualType tmp;
+    tmp = Context.isPromotableBitField(lex);
+    if (!tmp.isNull()) lt = tmp;
+    tmp = Context.isPromotableBitField(rex);
+    if (!tmp.isNull()) rt = tmp;
+  }
+
+  if (const EnumType *E = lt->getAs<EnumType>())
+    lt = E->getDecl()->getPromotionType();
+  if (const EnumType *E = rt->getAs<EnumType>())
+    rt = E->getDecl()->getPromotionType();
+
+  // The rule is that the signed operand becomes unsigned, so isolate the
+  // signed operand.
+  Expr *signedOperand = lex, *unsignedOperand = rex;
+  QualType signedType = lt, unsignedType = rt;
+  if (lt->isSignedIntegerType()) {
+    if (rt->isSignedIntegerType()) return;
+  } else {
+    if (!rt->isSignedIntegerType()) return;
+    std::swap(signedOperand, unsignedOperand);
+    std::swap(signedType, unsignedType);
+  }
+
+  unsigned unsignedWidth = Context.getIntWidth(unsignedType);
+  unsigned signedWidth = Context.getIntWidth(signedType);
+
+  // If the unsigned type is strictly smaller than the signed type,
+  // then (1) the result type will be signed and (2) the unsigned
+  // value will fit fully within the signed type, and thus the result
+  // of the comparison will be exact.
+  if (signedWidth > unsignedWidth)
+    return;
+
+  // Otherwise, calculate the effective ranges.
+  IntRange signedRange = GetExprRange(Context, signedOperand, signedWidth);
+  IntRange unsignedRange = GetExprRange(Context, unsignedOperand, unsignedWidth);
+
+  // We should never be unable to prove that the unsigned operand is
+  // non-negative.
+  assert(unsignedRange.NonNegative && "unsigned range includes negative?");
+
+  // If the signed operand is non-negative, then the signed->unsigned
+  // conversion won't change it.
+  if (signedRange.NonNegative) {
+    // Emit warnings for comparisons of unsigned to integer constant 0.
+    //   always false: x < 0  (or 0 > x)
+    //   always true:  x >= 0 (or 0 <= x)
+    llvm::APSInt X;
+    if (BinOpc && signedOperand->isIntegerConstantExpr(X, Context) && X == 0) {
+      if (signedOperand != lex) {
+        if (*BinOpc == BinaryOperator::LT) {
+          Diag(OpLoc, diag::warn_lunsigned_always_true_comparison)
+            << "< 0" << "false"
+            << lex->getSourceRange() << rex->getSourceRange();
+        }
+        else if (*BinOpc == BinaryOperator::GE) {
+          Diag(OpLoc, diag::warn_lunsigned_always_true_comparison)
+            << ">= 0" << "true"
+            << lex->getSourceRange() << rex->getSourceRange();
+        }
+      }
+      else {
+        if (*BinOpc == BinaryOperator::GT) {
+          Diag(OpLoc, diag::warn_runsigned_always_true_comparison)
+            << "0 >" << "false" 
+            << lex->getSourceRange() << rex->getSourceRange();
+        } 
+        else if (*BinOpc == BinaryOperator::LE) {
+          Diag(OpLoc, diag::warn_runsigned_always_true_comparison)
+            << "0 <=" << "true" 
+            << lex->getSourceRange() << rex->getSourceRange();
+        }
+      }
+    }
+    return;
+  }
+
+  // For (in)equality comparisons, if the unsigned operand is a
+  // constant which cannot collide with a overflowed signed operand,
+  // then reinterpreting the signed operand as unsigned will not
+  // change the result of the comparison.
+  if (BinOpc &&
+      (*BinOpc == BinaryOperator::EQ || *BinOpc == BinaryOperator::NE) &&
+      unsignedRange.Width < unsignedWidth)
+    return;
+
+  Diag(OpLoc, BinOpc ? diag::warn_mixed_sign_comparison
+                     : diag::warn_mixed_sign_conditional)
+    << lt << rt << lex->getSourceRange() << rex->getSourceRange();
+}
+
+/// Diagnose an implicit cast;  purely a helper for CheckImplicitConversion.
+static void DiagnoseImpCast(Sema &S, Expr *E, QualType T, unsigned diag) {
+  S.Diag(E->getExprLoc(), diag) << E->getType() << T << E->getSourceRange();
+}
+
+/// Implements -Wconversion.
+void Sema::CheckImplicitConversion(Expr *E, QualType T) {
+  // Don't diagnose in unevaluated contexts.
+  if (ExprEvalContexts.back().Context == Sema::Unevaluated)
+    return;
+
+  // Don't diagnose for value-dependent expressions.
+  if (E->isValueDependent())
+    return;
+
+  const Type *Source = Context.getCanonicalType(E->getType()).getTypePtr();
+  const Type *Target = Context.getCanonicalType(T).getTypePtr();
+
+  // Never diagnose implicit casts to bool.
+  if (Target->isSpecificBuiltinType(BuiltinType::Bool))
+    return;
+
+  // Strip vector types.
+  if (isa<VectorType>(Source)) {
+    if (!isa<VectorType>(Target))
+      return DiagnoseImpCast(*this, E, T, diag::warn_impcast_vector_scalar);
+
+    Source = cast<VectorType>(Source)->getElementType().getTypePtr();
+    Target = cast<VectorType>(Target)->getElementType().getTypePtr();
+  }
+
+  // Strip complex types.
+  if (isa<ComplexType>(Source)) {
+    if (!isa<ComplexType>(Target))
+      return DiagnoseImpCast(*this, E, T, diag::warn_impcast_complex_scalar);
+
+    Source = cast<ComplexType>(Source)->getElementType().getTypePtr();
+    Target = cast<ComplexType>(Target)->getElementType().getTypePtr();
+  }
+
+  const BuiltinType *SourceBT = dyn_cast<BuiltinType>(Source);
+  const BuiltinType *TargetBT = dyn_cast<BuiltinType>(Target);
+
+  // If the source is floating point...
+  if (SourceBT && SourceBT->isFloatingPoint()) {
+    // ...and the target is floating point...
+    if (TargetBT && TargetBT->isFloatingPoint()) {
+      // ...then warn if we're dropping FP rank.
+
+      // Builtin FP kinds are ordered by increasing FP rank.
+      if (SourceBT->getKind() > TargetBT->getKind()) {
+        // Don't warn about float constants that are precisely
+        // representable in the target type.
+        Expr::EvalResult result;
+        if (E->Evaluate(result, Context)) {
+          // Value might be a float, a float vector, or a float complex.
+          if (IsSameFloatAfterCast(result.Val,
+                     Context.getFloatTypeSemantics(QualType(TargetBT, 0)),
+                     Context.getFloatTypeSemantics(QualType(SourceBT, 0))))
+            return;
+        }
+
+        DiagnoseImpCast(*this, E, T, diag::warn_impcast_float_precision);
+      }
+      return;
+    }
+
+    // If the target is integral, always warn.
+    if ((TargetBT && TargetBT->isInteger()))
+      // TODO: don't warn for integer values?
+      return DiagnoseImpCast(*this, E, T, diag::warn_impcast_float_integer);
+
+    return;
+  }
+
+  if (!Source->isIntegerType() || !Target->isIntegerType())
+    return;
+
+  IntRange SourceRange = GetExprRange(Context, E, Context.getIntWidth(E->getType()));
+  IntRange TargetRange = IntRange::forCanonicalType(Context, Target);
+
+  // FIXME: also signed<->unsigned?
+
+  if (SourceRange.Width > TargetRange.Width) {
+    // People want to build with -Wshorten-64-to-32 and not -Wconversion
+    // and by god we'll let them.
+    if (SourceRange.Width == 64 && TargetRange.Width == 32)
+      return DiagnoseImpCast(*this, E, T, diag::warn_impcast_integer_64_32);
+    return DiagnoseImpCast(*this, E, T, diag::warn_impcast_integer_precision);
+  }
+
+  return;
+}
+
+/// CheckParmsForFunctionDef - Check that the parameters of the given
+/// function are appropriate for the definition of a function. This
+/// takes care of any checks that cannot be performed on the
+/// declaration itself, e.g., that the types of each of the function
+/// parameters are complete.
+bool Sema::CheckParmsForFunctionDef(FunctionDecl *FD) {
+  bool HasInvalidParm = false;
+  for (unsigned p = 0, NumParams = FD->getNumParams(); p < NumParams; ++p) {
+    ParmVarDecl *Param = FD->getParamDecl(p);
+
+    // C99 6.7.5.3p4: the parameters in a parameter type list in a
+    // function declarator that is part of a function definition of
+    // that function shall not have incomplete type.
+    //
+    // This is also C++ [dcl.fct]p6.
+    if (!Param->isInvalidDecl() &&
+        RequireCompleteType(Param->getLocation(), Param->getType(),
+                               diag::err_typecheck_decl_incomplete_type)) {
+      Param->setInvalidDecl();
+      HasInvalidParm = true;
+    }
+
+    // C99 6.9.1p5: If the declarator includes a parameter type list, the
+    // declaration of each parameter shall include an identifier.
+    if (Param->getIdentifier() == 0 &&
+        !Param->isImplicit() &&
+        !getLangOptions().CPlusPlus)
+      Diag(Param->getLocation(), diag::err_parameter_name_omitted);
+
+    // C99 6.7.5.3p12:
+    //   If the function declarator is not part of a definition of that
+    //   function, parameters may have incomplete type and may use the [*]
+    //   notation in their sequences of declarator specifiers to specify
+    //   variable length array types.
+    QualType PType = Param->getOriginalType();
+    if (const ArrayType *AT = Context.getAsArrayType(PType)) {
+      if (AT->getSizeModifier() == ArrayType::Star) {
+        // FIXME: This diagnosic should point the the '[*]' if source-location
+        // information is added for it.
+        Diag(Param->getLocation(), diag::err_array_star_in_function_definition);
+      }
+    }
+  }
+
+  return HasInvalidParm;
+}
diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp
new file mode 100644
index 0000000..35bb697
--- /dev/null
+++ b/lib/Sema/SemaCodeComplete.cpp
@@ -0,0 +1,3678 @@
+//===---------------- SemaCodeComplete.cpp - Code Completion ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the code-completion semantic actions.
+//
+//===----------------------------------------------------------------------===//
+#include "Sema.h"
+#include "Lookup.h"
+#include "clang/Sema/CodeCompleteConsumer.h"
+#include "clang/Sema/ExternalSemaSource.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/ExprObjC.h"
+#include "clang/Lex/MacroInfo.h"
+#include "clang/Lex/Preprocessor.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringSwitch.h"
+#include <list>
+#include <map>
+#include <vector>
+
+using namespace clang;
+
+namespace {
+  /// \brief A container of code-completion results.
+  class ResultBuilder {
+  public:
+    /// \brief The type of a name-lookup filter, which can be provided to the
+    /// name-lookup routines to specify which declarations should be included in
+    /// the result set (when it returns true) and which declarations should be
+    /// filtered out (returns false).
+    typedef bool (ResultBuilder::*LookupFilter)(NamedDecl *) const;
+    
+    typedef CodeCompleteConsumer::Result Result;
+    
+  private:
+    /// \brief The actual results we have found.
+    std::vector<Result> Results;
+    
+    /// \brief A record of all of the declarations we have found and placed
+    /// into the result set, used to ensure that no declaration ever gets into
+    /// the result set twice.
+    llvm::SmallPtrSet<Decl*, 16> AllDeclsFound;
+    
+    typedef std::pair<NamedDecl *, unsigned> DeclIndexPair;
+
+    /// \brief An entry in the shadow map, which is optimized to store
+    /// a single (declaration, index) mapping (the common case) but
+    /// can also store a list of (declaration, index) mappings.
+    class ShadowMapEntry {
+      typedef llvm::SmallVector<DeclIndexPair, 4> DeclIndexPairVector;
+
+      /// \brief Contains either the solitary NamedDecl * or a vector
+      /// of (declaration, index) pairs.
+      llvm::PointerUnion<NamedDecl *, DeclIndexPairVector*> DeclOrVector;
+
+      /// \brief When the entry contains a single declaration, this is
+      /// the index associated with that entry.
+      unsigned SingleDeclIndex;
+
+    public:
+      ShadowMapEntry() : DeclOrVector(), SingleDeclIndex(0) { }
+
+      void Add(NamedDecl *ND, unsigned Index) {
+        if (DeclOrVector.isNull()) {
+          // 0 - > 1 elements: just set the single element information.
+          DeclOrVector = ND;
+          SingleDeclIndex = Index;
+          return;
+        }
+
+        if (NamedDecl *PrevND = DeclOrVector.dyn_cast<NamedDecl *>()) {
+          // 1 -> 2 elements: create the vector of results and push in the
+          // existing declaration.
+          DeclIndexPairVector *Vec = new DeclIndexPairVector;
+          Vec->push_back(DeclIndexPair(PrevND, SingleDeclIndex));
+          DeclOrVector = Vec;
+        }
+
+        // Add the new element to the end of the vector.
+        DeclOrVector.get<DeclIndexPairVector*>()->push_back(
+                                                    DeclIndexPair(ND, Index));
+      }
+
+      void Destroy() {
+        if (DeclIndexPairVector *Vec
+              = DeclOrVector.dyn_cast<DeclIndexPairVector *>()) {
+          delete Vec;
+          DeclOrVector = ((NamedDecl *)0);
+        }
+      }
+
+      // Iteration.
+      class iterator;
+      iterator begin() const;
+      iterator end() const;
+    };
+
+    /// \brief A mapping from declaration names to the declarations that have
+    /// this name within a particular scope and their index within the list of
+    /// results.
+    typedef llvm::DenseMap<DeclarationName, ShadowMapEntry> ShadowMap;
+    
+    /// \brief The semantic analysis object for which results are being 
+    /// produced.
+    Sema &SemaRef;
+    
+    /// \brief If non-NULL, a filter function used to remove any code-completion
+    /// results that are not desirable.
+    LookupFilter Filter;
+
+    /// \brief Whether we should allow declarations as
+    /// nested-name-specifiers that would otherwise be filtered out.
+    bool AllowNestedNameSpecifiers;
+
+    /// \brief A list of shadow maps, which is used to model name hiding at
+    /// different levels of, e.g., the inheritance hierarchy.
+    std::list<ShadowMap> ShadowMaps;
+    
+  public:
+    explicit ResultBuilder(Sema &SemaRef, LookupFilter Filter = 0)
+      : SemaRef(SemaRef), Filter(Filter), AllowNestedNameSpecifiers(false) { }
+    
+    /// \brief Set the filter used for code-completion results.
+    void setFilter(LookupFilter Filter) {
+      this->Filter = Filter;
+    }
+    
+    typedef std::vector<Result>::iterator iterator;
+    iterator begin() { return Results.begin(); }
+    iterator end() { return Results.end(); }
+    
+    Result *data() { return Results.empty()? 0 : &Results.front(); }
+    unsigned size() const { return Results.size(); }
+    bool empty() const { return Results.empty(); }
+    
+    /// \brief Specify whether nested-name-specifiers are allowed.
+    void allowNestedNameSpecifiers(bool Allow = true) {
+      AllowNestedNameSpecifiers = Allow;
+    }
+
+    /// \brief Determine whether the given declaration is at all interesting
+    /// as a code-completion result.
+    ///
+    /// \param ND the declaration that we are inspecting.
+    ///
+    /// \param AsNestedNameSpecifier will be set true if this declaration is
+    /// only interesting when it is a nested-name-specifier.
+    bool isInterestingDecl(NamedDecl *ND, bool &AsNestedNameSpecifier) const;
+    
+    /// \brief Check whether the result is hidden by the Hiding declaration.
+    ///
+    /// \returns true if the result is hidden and cannot be found, false if
+    /// the hidden result could still be found. When false, \p R may be
+    /// modified to describe how the result can be found (e.g., via extra
+    /// qualification).
+    bool CheckHiddenResult(Result &R, DeclContext *CurContext,
+                           NamedDecl *Hiding);
+    
+    /// \brief Add a new result to this result set (if it isn't already in one
+    /// of the shadow maps), or replace an existing result (for, e.g., a 
+    /// redeclaration).
+    ///
+    /// \param CurContext the result to add (if it is unique).
+    ///
+    /// \param R the context in which this result will be named.
+    void MaybeAddResult(Result R, DeclContext *CurContext = 0);
+    
+    /// \brief Add a new result to this result set, where we already know
+    /// the hiding declation (if any).
+    ///
+    /// \param R the result to add (if it is unique).
+    ///
+    /// \param CurContext the context in which this result will be named.
+    ///
+    /// \param Hiding the declaration that hides the result.
+    ///
+    /// \param InBaseClass whether the result was found in a base
+    /// class of the searched context.
+    void AddResult(Result R, DeclContext *CurContext, NamedDecl *Hiding,
+                   bool InBaseClass);
+    
+    /// \brief Add a new non-declaration result to this result set.
+    void AddResult(Result R);
+
+    /// \brief Enter into a new scope.
+    void EnterNewScope();
+    
+    /// \brief Exit from the current scope.
+    void ExitScope();
+    
+    /// \brief Ignore this declaration, if it is seen again.
+    void Ignore(Decl *D) { AllDeclsFound.insert(D->getCanonicalDecl()); }
+
+    /// \name Name lookup predicates
+    ///
+    /// These predicates can be passed to the name lookup functions to filter the
+    /// results of name lookup. All of the predicates have the same type, so that
+    /// 
+    //@{
+    bool IsOrdinaryName(NamedDecl *ND) const;
+    bool IsOrdinaryNonValueName(NamedDecl *ND) const;
+    bool IsNestedNameSpecifier(NamedDecl *ND) const;
+    bool IsEnum(NamedDecl *ND) const;
+    bool IsClassOrStruct(NamedDecl *ND) const;
+    bool IsUnion(NamedDecl *ND) const;
+    bool IsNamespace(NamedDecl *ND) const;
+    bool IsNamespaceOrAlias(NamedDecl *ND) const;
+    bool IsType(NamedDecl *ND) const;
+    bool IsMember(NamedDecl *ND) const;
+    bool IsObjCIvar(NamedDecl *ND) const;
+    //@}    
+  };  
+}
+
+class ResultBuilder::ShadowMapEntry::iterator {
+  llvm::PointerUnion<NamedDecl*, const DeclIndexPair*> DeclOrIterator;
+  unsigned SingleDeclIndex;
+
+public:
+  typedef DeclIndexPair value_type;
+  typedef value_type reference;
+  typedef std::ptrdiff_t difference_type;
+  typedef std::input_iterator_tag iterator_category;
+        
+  class pointer {
+    DeclIndexPair Value;
+
+  public:
+    pointer(const DeclIndexPair &Value) : Value(Value) { }
+
+    const DeclIndexPair *operator->() const {
+      return &Value;
+    }
+  };
+        
+  iterator() : DeclOrIterator((NamedDecl *)0), SingleDeclIndex(0) { }
+
+  iterator(NamedDecl *SingleDecl, unsigned Index)
+    : DeclOrIterator(SingleDecl), SingleDeclIndex(Index) { }
+
+  iterator(const DeclIndexPair *Iterator)
+    : DeclOrIterator(Iterator), SingleDeclIndex(0) { }
+
+  iterator &operator++() {
+    if (DeclOrIterator.is<NamedDecl *>()) {
+      DeclOrIterator = (NamedDecl *)0;
+      SingleDeclIndex = 0;
+      return *this;
+    }
+
+    const DeclIndexPair *I = DeclOrIterator.get<const DeclIndexPair*>();
+    ++I;
+    DeclOrIterator = I;
+    return *this;
+  }
+
+  iterator operator++(int) {
+    iterator tmp(*this);
+    ++(*this);
+    return tmp;
+  }
+
+  reference operator*() const {
+    if (NamedDecl *ND = DeclOrIterator.dyn_cast<NamedDecl *>())
+      return reference(ND, SingleDeclIndex);
+
+    return *DeclOrIterator.get<const DeclIndexPair*>();
+  }
+
+  pointer operator->() const {
+    return pointer(**this);
+  }
+
+  friend bool operator==(const iterator &X, const iterator &Y) {
+    return X.DeclOrIterator.getOpaqueValue()
+                                  == Y.DeclOrIterator.getOpaqueValue() &&
+      X.SingleDeclIndex == Y.SingleDeclIndex;
+  }
+
+  friend bool operator!=(const iterator &X, const iterator &Y) {
+    return !(X == Y);
+  }
+};
+
+ResultBuilder::ShadowMapEntry::iterator 
+ResultBuilder::ShadowMapEntry::begin() const {
+  if (DeclOrVector.isNull())
+    return iterator();
+
+  if (NamedDecl *ND = DeclOrVector.dyn_cast<NamedDecl *>())
+    return iterator(ND, SingleDeclIndex);
+
+  return iterator(DeclOrVector.get<DeclIndexPairVector *>()->begin());
+}
+
+ResultBuilder::ShadowMapEntry::iterator 
+ResultBuilder::ShadowMapEntry::end() const {
+  if (DeclOrVector.is<NamedDecl *>() || DeclOrVector.isNull())
+    return iterator();
+
+  return iterator(DeclOrVector.get<DeclIndexPairVector *>()->end());
+}
+
+/// \brief Compute the qualification required to get from the current context
+/// (\p CurContext) to the target context (\p TargetContext).
+///
+/// \param Context the AST context in which the qualification will be used.
+///
+/// \param CurContext the context where an entity is being named, which is
+/// typically based on the current scope.
+///
+/// \param TargetContext the context in which the named entity actually 
+/// resides.
+///
+/// \returns a nested name specifier that refers into the target context, or
+/// NULL if no qualification is needed.
+static NestedNameSpecifier *
+getRequiredQualification(ASTContext &Context,
+                         DeclContext *CurContext,
+                         DeclContext *TargetContext) {
+  llvm::SmallVector<DeclContext *, 4> TargetParents;
+  
+  for (DeclContext *CommonAncestor = TargetContext;
+       CommonAncestor && !CommonAncestor->Encloses(CurContext);
+       CommonAncestor = CommonAncestor->getLookupParent()) {
+    if (CommonAncestor->isTransparentContext() ||
+        CommonAncestor->isFunctionOrMethod())
+      continue;
+    
+    TargetParents.push_back(CommonAncestor);
+  }
+  
+  NestedNameSpecifier *Result = 0;
+  while (!TargetParents.empty()) {
+    DeclContext *Parent = TargetParents.back();
+    TargetParents.pop_back();
+    
+    if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Parent))
+      Result = NestedNameSpecifier::Create(Context, Result, Namespace);
+    else if (TagDecl *TD = dyn_cast<TagDecl>(Parent))
+      Result = NestedNameSpecifier::Create(Context, Result,
+                                           false,
+                                     Context.getTypeDeclType(TD).getTypePtr());
+    else
+      assert(Parent->isTranslationUnit());
+  }  
+  return Result;
+}
+
+bool ResultBuilder::isInterestingDecl(NamedDecl *ND, 
+                                      bool &AsNestedNameSpecifier) const {
+  AsNestedNameSpecifier = false;
+
+  ND = ND->getUnderlyingDecl();
+  unsigned IDNS = ND->getIdentifierNamespace();
+
+  // Skip unnamed entities.
+  if (!ND->getDeclName())
+    return false;
+  
+  // Friend declarations and declarations introduced due to friends are never
+  // added as results.
+  if (IDNS & (Decl::IDNS_OrdinaryFriend | Decl::IDNS_TagFriend))
+    return false;
+  
+  // Class template (partial) specializations are never added as results.
+  if (isa<ClassTemplateSpecializationDecl>(ND) ||
+      isa<ClassTemplatePartialSpecializationDecl>(ND))
+    return false;
+  
+  // Using declarations themselves are never added as results.
+  if (isa<UsingDecl>(ND))
+    return false;
+  
+  // Some declarations have reserved names that we don't want to ever show.
+  if (const IdentifierInfo *Id = ND->getIdentifier()) {
+    // __va_list_tag is a freak of nature. Find it and skip it.
+    if (Id->isStr("__va_list_tag") || Id->isStr("__builtin_va_list"))
+      return false;
+    
+    // Filter out names reserved for the implementation (C99 7.1.3, 
+    // C++ [lib.global.names]). Users don't need to see those.
+    //
+    // FIXME: Add predicate for this.
+    if (Id->getLength() >= 2) {
+      const char *Name = Id->getNameStart();
+      if (Name[0] == '_' &&
+          (Name[1] == '_' || (Name[1] >= 'A' && Name[1] <= 'Z')))
+        return false;
+    }
+  }
+ 
+  // C++ constructors are never found by name lookup.
+  if (isa<CXXConstructorDecl>(ND))
+    return false;
+  
+  // Filter out any unwanted results.
+  if (Filter && !(this->*Filter)(ND)) {
+    // Check whether it is interesting as a nested-name-specifier.
+    if (AllowNestedNameSpecifiers && SemaRef.getLangOptions().CPlusPlus && 
+        IsNestedNameSpecifier(ND) &&
+        (Filter != &ResultBuilder::IsMember ||
+         (isa<CXXRecordDecl>(ND) && 
+          cast<CXXRecordDecl>(ND)->isInjectedClassName()))) {
+      AsNestedNameSpecifier = true;
+      return true;
+    }
+
+    return false;
+  }
+
+  if (Filter == &ResultBuilder::IsNestedNameSpecifier)
+    AsNestedNameSpecifier = true;
+  
+  // ... then it must be interesting!
+  return true;
+}
+
+bool ResultBuilder::CheckHiddenResult(Result &R, DeclContext *CurContext,
+                                      NamedDecl *Hiding) {
+  // In C, there is no way to refer to a hidden name.
+  // FIXME: This isn't true; we can find a tag name hidden by an ordinary
+  // name if we introduce the tag type.
+  if (!SemaRef.getLangOptions().CPlusPlus)
+    return true;
+  
+  DeclContext *HiddenCtx = R.Declaration->getDeclContext()->getLookupContext();
+  
+  // There is no way to qualify a name declared in a function or method.
+  if (HiddenCtx->isFunctionOrMethod())
+    return true;
+  
+  if (HiddenCtx == Hiding->getDeclContext()->getLookupContext())
+    return true;
+  
+  // We can refer to the result with the appropriate qualification. Do it.
+  R.Hidden = true;
+  R.QualifierIsInformative = false;
+  
+  if (!R.Qualifier)
+    R.Qualifier = getRequiredQualification(SemaRef.Context, 
+                                           CurContext, 
+                                           R.Declaration->getDeclContext());
+  return false;
+}
+
+void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) {
+  assert(!ShadowMaps.empty() && "Must enter into a results scope");
+  
+  if (R.Kind != Result::RK_Declaration) {
+    // For non-declaration results, just add the result.
+    Results.push_back(R);
+    return;
+  }
+
+  // Look through using declarations.
+  if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
+    MaybeAddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext);
+    return;
+  }
+  
+  Decl *CanonDecl = R.Declaration->getCanonicalDecl();
+  unsigned IDNS = CanonDecl->getIdentifierNamespace();
+
+  bool AsNestedNameSpecifier = false;
+  if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
+    return;
+      
+  ShadowMap &SMap = ShadowMaps.back();
+  ShadowMapEntry::iterator I, IEnd;
+  ShadowMap::iterator NamePos = SMap.find(R.Declaration->getDeclName());
+  if (NamePos != SMap.end()) {
+    I = NamePos->second.begin();
+    IEnd = NamePos->second.end();
+  }
+
+  for (; I != IEnd; ++I) {
+    NamedDecl *ND = I->first;
+    unsigned Index = I->second;
+    if (ND->getCanonicalDecl() == CanonDecl) {
+      // This is a redeclaration. Always pick the newer declaration.
+      Results[Index].Declaration = R.Declaration;
+      
+      // We're done.
+      return;
+    }
+  }
+  
+  // This is a new declaration in this scope. However, check whether this
+  // declaration name is hidden by a similarly-named declaration in an outer
+  // scope.
+  std::list<ShadowMap>::iterator SM, SMEnd = ShadowMaps.end();
+  --SMEnd;
+  for (SM = ShadowMaps.begin(); SM != SMEnd; ++SM) {
+    ShadowMapEntry::iterator I, IEnd;
+    ShadowMap::iterator NamePos = SM->find(R.Declaration->getDeclName());
+    if (NamePos != SM->end()) {
+      I = NamePos->second.begin();
+      IEnd = NamePos->second.end();
+    }
+    for (; I != IEnd; ++I) {
+      // A tag declaration does not hide a non-tag declaration.
+      if (I->first->hasTagIdentifierNamespace() &&
+          (IDNS & (Decl::IDNS_Member | Decl::IDNS_Ordinary | 
+                   Decl::IDNS_ObjCProtocol)))
+        continue;
+      
+      // Protocols are in distinct namespaces from everything else.
+      if (((I->first->getIdentifierNamespace() & Decl::IDNS_ObjCProtocol)
+           || (IDNS & Decl::IDNS_ObjCProtocol)) &&
+          I->first->getIdentifierNamespace() != IDNS)
+        continue;
+      
+      // The newly-added result is hidden by an entry in the shadow map.
+      if (CheckHiddenResult(R, CurContext, I->first))
+        return;
+      
+      break;
+    }
+  }
+  
+  // Make sure that any given declaration only shows up in the result set once.
+  if (!AllDeclsFound.insert(CanonDecl))
+    return;
+  
+  // If the filter is for nested-name-specifiers, then this result starts a
+  // nested-name-specifier.
+  if (AsNestedNameSpecifier)
+    R.StartsNestedNameSpecifier = true;
+  
+  // If this result is supposed to have an informative qualifier, add one.
+  if (R.QualifierIsInformative && !R.Qualifier &&
+      !R.StartsNestedNameSpecifier) {
+    DeclContext *Ctx = R.Declaration->getDeclContext();
+    if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
+      R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
+    else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
+      R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false, 
+                             SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
+    else
+      R.QualifierIsInformative = false;
+  }
+    
+  // Insert this result into the set of results and into the current shadow
+  // map.
+  SMap[R.Declaration->getDeclName()].Add(R.Declaration, Results.size());
+  Results.push_back(R);
+}
+
+void ResultBuilder::AddResult(Result R, DeclContext *CurContext, 
+                              NamedDecl *Hiding, bool InBaseClass = false) {
+  if (R.Kind != Result::RK_Declaration) {
+    // For non-declaration results, just add the result.
+    Results.push_back(R);
+    return;
+  }
+
+  // Look through using declarations.
+  if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
+    AddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext, Hiding);
+    return;
+  }
+  
+  bool AsNestedNameSpecifier = false;
+  if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
+    return;
+  
+  if (Hiding && CheckHiddenResult(R, CurContext, Hiding))
+    return;
+      
+  // Make sure that any given declaration only shows up in the result set once.
+  if (!AllDeclsFound.insert(R.Declaration->getCanonicalDecl()))
+    return;
+  
+  // If the filter is for nested-name-specifiers, then this result starts a
+  // nested-name-specifier.
+  if (AsNestedNameSpecifier)
+    R.StartsNestedNameSpecifier = true;
+  else if (Filter == &ResultBuilder::IsMember && !R.Qualifier && InBaseClass &&
+           isa<CXXRecordDecl>(R.Declaration->getDeclContext()
+                                                  ->getLookupContext()))
+    R.QualifierIsInformative = true;
+
+  // If this result is supposed to have an informative qualifier, add one.
+  if (R.QualifierIsInformative && !R.Qualifier &&
+      !R.StartsNestedNameSpecifier) {
+    DeclContext *Ctx = R.Declaration->getDeclContext();
+    if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
+      R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
+    else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
+      R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false, 
+                            SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
+    else
+      R.QualifierIsInformative = false;
+  }
+  
+  // Insert this result into the set of results.
+  Results.push_back(R);
+}
+
+void ResultBuilder::AddResult(Result R) {
+  assert(R.Kind != Result::RK_Declaration && 
+          "Declaration results need more context");
+  Results.push_back(R);
+}
+
+/// \brief Enter into a new scope.
+void ResultBuilder::EnterNewScope() {
+  ShadowMaps.push_back(ShadowMap());
+}
+
+/// \brief Exit from the current scope.
+void ResultBuilder::ExitScope() {
+  for (ShadowMap::iterator E = ShadowMaps.back().begin(),
+                        EEnd = ShadowMaps.back().end();
+       E != EEnd;
+       ++E)
+    E->second.Destroy();
+         
+  ShadowMaps.pop_back();
+}
+
+/// \brief Determines whether this given declaration will be found by
+/// ordinary name lookup.
+bool ResultBuilder::IsOrdinaryName(NamedDecl *ND) const {
+  unsigned IDNS = Decl::IDNS_Ordinary;
+  if (SemaRef.getLangOptions().CPlusPlus)
+    IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace;
+  else if (SemaRef.getLangOptions().ObjC1 && isa<ObjCIvarDecl>(ND))
+    return true;
+
+  return ND->getIdentifierNamespace() & IDNS;
+}
+
+/// \brief Determines whether this given declaration will be found by
+/// ordinary name lookup.
+bool ResultBuilder::IsOrdinaryNonValueName(NamedDecl *ND) const {
+  unsigned IDNS = Decl::IDNS_Ordinary;
+  if (SemaRef.getLangOptions().CPlusPlus)
+    IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace;
+  
+  return (ND->getIdentifierNamespace() & IDNS) && 
+    !isa<ValueDecl>(ND) && !isa<FunctionTemplateDecl>(ND);
+}
+
+/// \brief Determines whether the given declaration is suitable as the 
+/// start of a C++ nested-name-specifier, e.g., a class or namespace.
+bool ResultBuilder::IsNestedNameSpecifier(NamedDecl *ND) const {
+  // Allow us to find class templates, too.
+  if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
+    ND = ClassTemplate->getTemplatedDecl();
+  
+  return SemaRef.isAcceptableNestedNameSpecifier(ND);
+}
+
+/// \brief Determines whether the given declaration is an enumeration.
+bool ResultBuilder::IsEnum(NamedDecl *ND) const {
+  return isa<EnumDecl>(ND);
+}
+
+/// \brief Determines whether the given declaration is a class or struct.
+bool ResultBuilder::IsClassOrStruct(NamedDecl *ND) const {
+  // Allow us to find class templates, too.
+  if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
+    ND = ClassTemplate->getTemplatedDecl();
+  
+  if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
+    return RD->getTagKind() == TagDecl::TK_class ||
+    RD->getTagKind() == TagDecl::TK_struct;
+  
+  return false;
+}
+
+/// \brief Determines whether the given declaration is a union.
+bool ResultBuilder::IsUnion(NamedDecl *ND) const {
+  // Allow us to find class templates, too.
+  if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
+    ND = ClassTemplate->getTemplatedDecl();
+  
+  if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
+    return RD->getTagKind() == TagDecl::TK_union;
+  
+  return false;
+}
+
+/// \brief Determines whether the given declaration is a namespace.
+bool ResultBuilder::IsNamespace(NamedDecl *ND) const {
+  return isa<NamespaceDecl>(ND);
+}
+
+/// \brief Determines whether the given declaration is a namespace or 
+/// namespace alias.
+bool ResultBuilder::IsNamespaceOrAlias(NamedDecl *ND) const {
+  return isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND);
+}
+
+/// \brief Determines whether the given declaration is a type.
+bool ResultBuilder::IsType(NamedDecl *ND) const {
+  return isa<TypeDecl>(ND);
+}
+
+/// \brief Determines which members of a class should be visible via
+/// "." or "->".  Only value declarations, nested name specifiers, and
+/// using declarations thereof should show up.
+bool ResultBuilder::IsMember(NamedDecl *ND) const {
+  if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
+    ND = Using->getTargetDecl();
+
+  return isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND) ||
+    isa<ObjCPropertyDecl>(ND);
+}
+
+/// \rief Determines whether the given declaration is an Objective-C
+/// instance variable.
+bool ResultBuilder::IsObjCIvar(NamedDecl *ND) const {
+  return isa<ObjCIvarDecl>(ND);
+}
+
+namespace {
+  /// \brief Visible declaration consumer that adds a code-completion result
+  /// for each visible declaration.
+  class CodeCompletionDeclConsumer : public VisibleDeclConsumer {
+    ResultBuilder &Results;
+    DeclContext *CurContext;
+    
+  public:
+    CodeCompletionDeclConsumer(ResultBuilder &Results, DeclContext *CurContext)
+      : Results(Results), CurContext(CurContext) { }
+    
+    virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, bool InBaseClass) {
+      Results.AddResult(ND, CurContext, Hiding, InBaseClass);
+    }
+  };
+}
+
+/// \brief Add type specifiers for the current language as keyword results.
+static void AddTypeSpecifierResults(const LangOptions &LangOpts,
+                                    ResultBuilder &Results) {
+  typedef CodeCompleteConsumer::Result Result;
+  Results.AddResult(Result("short"));
+  Results.AddResult(Result("long"));
+  Results.AddResult(Result("signed"));
+  Results.AddResult(Result("unsigned"));
+  Results.AddResult(Result("void"));
+  Results.AddResult(Result("char"));
+  Results.AddResult(Result("int"));
+  Results.AddResult(Result("float"));
+  Results.AddResult(Result("double"));
+  Results.AddResult(Result("enum"));
+  Results.AddResult(Result("struct"));
+  Results.AddResult(Result("union"));
+  Results.AddResult(Result("const"));
+  Results.AddResult(Result("volatile"));
+
+  if (LangOpts.C99) {
+    // C99-specific
+    Results.AddResult(Result("_Complex"));
+    Results.AddResult(Result("_Imaginary"));
+    Results.AddResult(Result("_Bool"));
+    Results.AddResult(Result("restrict"));
+  }
+  
+  if (LangOpts.CPlusPlus) {
+    // C++-specific
+    Results.AddResult(Result("bool"));
+    Results.AddResult(Result("class"));
+    Results.AddResult(Result("wchar_t"));
+    
+    // typename qualified-id
+    CodeCompletionString *Pattern = new CodeCompletionString;
+    Pattern->AddTypedTextChunk("typename");
+    Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+    Pattern->AddPlaceholderChunk("qualified-id");
+    Results.AddResult(Result(Pattern));
+
+    if (LangOpts.CPlusPlus0x) {
+      Results.AddResult(Result("auto"));
+      Results.AddResult(Result("char16_t"));
+      Results.AddResult(Result("char32_t"));
+      Results.AddResult(Result("decltype"));
+    }
+  }
+  
+  // GNU extensions
+  if (LangOpts.GNUMode) {
+    // FIXME: Enable when we actually support decimal floating point.
+    //    Results.AddResult(Result("_Decimal32"));
+    //    Results.AddResult(Result("_Decimal64"));
+    //    Results.AddResult(Result("_Decimal128"));
+    
+    CodeCompletionString *Pattern = new CodeCompletionString;
+    Pattern->AddTypedTextChunk("typeof");
+    Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+    Pattern->AddPlaceholderChunk("expression-or-type");
+    Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+    Results.AddResult(Result(Pattern));
+  }
+}
+
+static void AddStorageSpecifiers(Action::CodeCompletionContext CCC,
+                                 const LangOptions &LangOpts, 
+                                 ResultBuilder &Results) {
+  typedef CodeCompleteConsumer::Result Result;
+  // Note: we don't suggest either "auto" or "register", because both
+  // are pointless as storage specifiers. Elsewhere, we suggest "auto"
+  // in C++0x as a type specifier.
+  Results.AddResult(Result("extern"));
+  Results.AddResult(Result("static"));
+}
+
+static void AddFunctionSpecifiers(Action::CodeCompletionContext CCC,
+                                  const LangOptions &LangOpts, 
+                                  ResultBuilder &Results) {
+  typedef CodeCompleteConsumer::Result Result;
+  switch (CCC) {
+  case Action::CCC_Class:
+  case Action::CCC_MemberTemplate:
+    if (LangOpts.CPlusPlus) {
+      Results.AddResult(Result("explicit"));
+      Results.AddResult(Result("friend"));
+      Results.AddResult(Result("mutable"));
+      Results.AddResult(Result("virtual"));
+    }    
+    // Fall through
+
+  case Action::CCC_ObjCInterface:
+  case Action::CCC_ObjCImplementation:
+  case Action::CCC_Namespace:
+  case Action::CCC_Template:
+    if (LangOpts.CPlusPlus || LangOpts.C99)
+      Results.AddResult(Result("inline"));
+    break;
+
+  case Action::CCC_ObjCInstanceVariableList:
+  case Action::CCC_Expression:
+  case Action::CCC_Statement:
+  case Action::CCC_ForInit:
+  case Action::CCC_Condition:
+    break;
+  }
+}
+
+static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt);
+static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt);
+static void AddObjCVisibilityResults(const LangOptions &LangOpts,
+                                     ResultBuilder &Results,
+                                     bool NeedAt);  
+static void AddObjCImplementationResults(const LangOptions &LangOpts,
+                                         ResultBuilder &Results,
+                                         bool NeedAt);
+static void AddObjCInterfaceResults(const LangOptions &LangOpts,
+                                    ResultBuilder &Results,
+                                    bool NeedAt);
+static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt);
+
+/// \brief Add language constructs that show up for "ordinary" names.
+static void AddOrdinaryNameResults(Action::CodeCompletionContext CCC,
+                                   Scope *S,
+                                   Sema &SemaRef,
+                                   ResultBuilder &Results) {
+  typedef CodeCompleteConsumer::Result Result;
+  switch (CCC) {
+  case Action::CCC_Namespace:
+    if (SemaRef.getLangOptions().CPlusPlus) {
+      // namespace <identifier> { }
+      CodeCompletionString *Pattern = new CodeCompletionString;
+      Pattern->AddTypedTextChunk("namespace");
+      Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+      Pattern->AddPlaceholderChunk("identifier");
+      Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
+      Pattern->AddPlaceholderChunk("declarations");
+      Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
+      Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
+      Results.AddResult(Result(Pattern));
+
+      // namespace identifier = identifier ;
+      Pattern = new CodeCompletionString;
+      Pattern->AddTypedTextChunk("namespace");
+      Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+      Pattern->AddPlaceholderChunk("identifier");
+      Pattern->AddChunk(CodeCompletionString::CK_Equal);
+      Pattern->AddPlaceholderChunk("identifier");
+      Results.AddResult(Result(Pattern));
+
+      // Using directives
+      Pattern = new CodeCompletionString;
+      Pattern->AddTypedTextChunk("using");
+      Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+      Pattern->AddTextChunk("namespace");
+      Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+      Pattern->AddPlaceholderChunk("identifier");
+      Results.AddResult(Result(Pattern));
+
+      // asm(string-literal)      
+      Pattern = new CodeCompletionString;
+      Pattern->AddTypedTextChunk("asm");
+      Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+      Pattern->AddPlaceholderChunk("string-literal");
+      Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+      Results.AddResult(Result(Pattern));
+
+      // Explicit template instantiation
+      Pattern = new CodeCompletionString;
+      Pattern->AddTypedTextChunk("template");
+      Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+      Pattern->AddPlaceholderChunk("declaration");
+      Results.AddResult(Result(Pattern));
+    }
+      
+    if (SemaRef.getLangOptions().ObjC1)
+      AddObjCTopLevelResults(Results, true);
+      
+    // Fall through
+
+  case Action::CCC_Class:
+    Results.AddResult(Result("typedef"));
+    if (SemaRef.getLangOptions().CPlusPlus) {
+      // Using declaration
+      CodeCompletionString *Pattern = new CodeCompletionString;
+      Pattern->AddTypedTextChunk("using");
+      Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+      Pattern->AddPlaceholderChunk("qualified-id");
+      Results.AddResult(Result(Pattern));
+      
+      // using typename qualified-id; (only in a dependent context)
+      if (SemaRef.CurContext->isDependentContext()) {
+        Pattern = new CodeCompletionString;
+        Pattern->AddTypedTextChunk("using");
+        Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+        Pattern->AddTextChunk("typename");
+        Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+        Pattern->AddPlaceholderChunk("qualified-id");
+        Results.AddResult(Result(Pattern));
+      }
+
+      if (CCC == Action::CCC_Class) {
+        // public:
+        Pattern = new CodeCompletionString;
+        Pattern->AddTypedTextChunk("public");
+        Pattern->AddChunk(CodeCompletionString::CK_Colon);
+        Results.AddResult(Result(Pattern));
+
+        // protected:
+        Pattern = new CodeCompletionString;
+        Pattern->AddTypedTextChunk("protected");
+        Pattern->AddChunk(CodeCompletionString::CK_Colon);
+        Results.AddResult(Result(Pattern));
+
+        // private:
+        Pattern = new CodeCompletionString;
+        Pattern->AddTypedTextChunk("private");
+        Pattern->AddChunk(CodeCompletionString::CK_Colon);
+        Results.AddResult(Result(Pattern));
+      }
+    }
+    // Fall through
+
+  case Action::CCC_Template:
+  case Action::CCC_MemberTemplate:
+    if (SemaRef.getLangOptions().CPlusPlus) {
+      // template < parameters >
+      CodeCompletionString *Pattern = new CodeCompletionString;
+      Pattern->AddTypedTextChunk("template");
+      Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
+      Pattern->AddPlaceholderChunk("parameters");
+      Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
+      Results.AddResult(Result(Pattern));
+    }
+
+    AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
+    AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
+    break;
+
+  case Action::CCC_ObjCInterface:
+    AddObjCInterfaceResults(SemaRef.getLangOptions(), Results, true);
+    AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
+    AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
+    break;
+      
+  case Action::CCC_ObjCImplementation:
+    AddObjCImplementationResults(SemaRef.getLangOptions(), Results, true);
+    AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
+    AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
+    break;
+      
+  case Action::CCC_ObjCInstanceVariableList:
+    AddObjCVisibilityResults(SemaRef.getLangOptions(), Results, true);
+    break;
+      
+  case Action::CCC_Statement: {
+    Results.AddResult(Result("typedef"));
+
+    CodeCompletionString *Pattern = 0;
+    if (SemaRef.getLangOptions().CPlusPlus) {
+      Pattern = new CodeCompletionString;
+      Pattern->AddTypedTextChunk("try");
+      Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
+      Pattern->AddPlaceholderChunk("statements");
+      Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
+      Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
+      Pattern->AddTextChunk("catch");
+      Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+      Pattern->AddPlaceholderChunk("declaration");
+      Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+      Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
+      Pattern->AddPlaceholderChunk("statements");
+      Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
+      Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
+      Results.AddResult(Result(Pattern));
+    }
+    if (SemaRef.getLangOptions().ObjC1)
+      AddObjCStatementResults(Results, true);
+    
+    // if (condition) { statements }
+    Pattern = new CodeCompletionString;
+    Pattern->AddTypedTextChunk("if");
+    Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+    if (SemaRef.getLangOptions().CPlusPlus)
+      Pattern->AddPlaceholderChunk("condition");
+    else
+      Pattern->AddPlaceholderChunk("expression");
+    Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+    Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
+    Pattern->AddPlaceholderChunk("statements");
+    Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
+    Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
+    Results.AddResult(Result(Pattern));
+
+    // switch (condition) { }
+    Pattern = new CodeCompletionString;
+    Pattern->AddTypedTextChunk("switch");
+    Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+    if (SemaRef.getLangOptions().CPlusPlus)
+      Pattern->AddPlaceholderChunk("condition");
+    else
+      Pattern->AddPlaceholderChunk("expression");
+    Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+    Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
+    Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
+    Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
+    Results.AddResult(Result(Pattern));
+
+    // Switch-specific statements.
+    if (!SemaRef.getSwitchStack().empty()) {
+      // case expression:
+      Pattern = new CodeCompletionString;
+      Pattern->AddTypedTextChunk("case");
+      Pattern->AddPlaceholderChunk("expression");
+      Pattern->AddChunk(CodeCompletionString::CK_Colon);
+      Results.AddResult(Result(Pattern));
+
+      // default:
+      Pattern = new CodeCompletionString;
+      Pattern->AddTypedTextChunk("default");
+      Pattern->AddChunk(CodeCompletionString::CK_Colon);
+      Results.AddResult(Result(Pattern));
+    }
+
+    /// while (condition) { statements }
+    Pattern = new CodeCompletionString;
+    Pattern->AddTypedTextChunk("while");
+    Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+    if (SemaRef.getLangOptions().CPlusPlus)
+      Pattern->AddPlaceholderChunk("condition");
+    else
+      Pattern->AddPlaceholderChunk("expression");
+    Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+    Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
+    Pattern->AddPlaceholderChunk("statements");
+    Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
+    Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
+    Results.AddResult(Result(Pattern));
+
+    // do { statements } while ( expression );
+    Pattern = new CodeCompletionString;
+    Pattern->AddTypedTextChunk("do");
+    Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
+    Pattern->AddPlaceholderChunk("statements");
+    Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
+    Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
+    Pattern->AddTextChunk("while");
+    Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+    Pattern->AddPlaceholderChunk("expression");
+    Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+    Results.AddResult(Result(Pattern));
+
+    // for ( for-init-statement ; condition ; expression ) { statements }
+    Pattern = new CodeCompletionString;
+    Pattern->AddTypedTextChunk("for");
+    Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+    if (SemaRef.getLangOptions().CPlusPlus || SemaRef.getLangOptions().C99)
+      Pattern->AddPlaceholderChunk("init-statement");
+    else
+      Pattern->AddPlaceholderChunk("init-expression");
+    Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
+    Pattern->AddPlaceholderChunk("condition");
+    Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
+    Pattern->AddPlaceholderChunk("inc-expression");
+    Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+    Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
+    Pattern->AddPlaceholderChunk("statements");
+    Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
+    Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
+    Results.AddResult(Result(Pattern));
+    
+    if (S->getContinueParent()) {
+      // continue ;
+      Pattern = new CodeCompletionString;
+      Pattern->AddTypedTextChunk("continue");
+      Results.AddResult(Result(Pattern));
+    }
+
+    if (S->getBreakParent()) {
+      // break ;
+      Pattern = new CodeCompletionString;
+      Pattern->AddTypedTextChunk("break");
+      Results.AddResult(Result(Pattern));
+    }
+
+    // "return expression ;" or "return ;", depending on whether we
+    // know the function is void or not.
+    bool isVoid = false;
+    if (FunctionDecl *Function = dyn_cast<FunctionDecl>(SemaRef.CurContext))
+      isVoid = Function->getResultType()->isVoidType();
+    else if (ObjCMethodDecl *Method
+                                 = dyn_cast<ObjCMethodDecl>(SemaRef.CurContext))
+      isVoid = Method->getResultType()->isVoidType();
+    else if (SemaRef.getCurBlock() && 
+             !SemaRef.getCurBlock()->ReturnType.isNull())
+      isVoid = SemaRef.getCurBlock()->ReturnType->isVoidType();
+    Pattern = new CodeCompletionString;
+    Pattern->AddTypedTextChunk("return");
+    if (!isVoid) {
+      Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+      Pattern->AddPlaceholderChunk("expression");
+    }
+    Results.AddResult(Result(Pattern));
+
+    // goto identifier ;
+    Pattern = new CodeCompletionString;
+    Pattern->AddTypedTextChunk("goto");
+    Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+    Pattern->AddPlaceholderChunk("identifier");
+    Results.AddResult(Result(Pattern));    
+
+    // Using directives
+    Pattern = new CodeCompletionString;
+    Pattern->AddTypedTextChunk("using");
+    Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+    Pattern->AddTextChunk("namespace");
+    Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+    Pattern->AddPlaceholderChunk("identifier");
+    Results.AddResult(Result(Pattern));
+  }
+
+  // Fall through (for statement expressions).
+  case Action::CCC_ForInit:
+  case Action::CCC_Condition:
+    AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
+    // Fall through: conditions and statements can have expressions.
+
+  case Action::CCC_Expression: {
+    CodeCompletionString *Pattern = 0;
+    if (SemaRef.getLangOptions().CPlusPlus) {
+      // 'this', if we're in a non-static member function.
+      if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(SemaRef.CurContext))
+        if (!Method->isStatic())
+          Results.AddResult(Result("this"));
+      
+      // true, false
+      Results.AddResult(Result("true"));
+      Results.AddResult(Result("false"));
+
+      // dynamic_cast < type-id > ( expression )
+      Pattern = new CodeCompletionString;
+      Pattern->AddTypedTextChunk("dynamic_cast");
+      Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
+      Pattern->AddPlaceholderChunk("type-id");
+      Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
+      Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+      Pattern->AddPlaceholderChunk("expression");
+      Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+      Results.AddResult(Result(Pattern));      
+      
+      // static_cast < type-id > ( expression )
+      Pattern = new CodeCompletionString;
+      Pattern->AddTypedTextChunk("static_cast");
+      Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
+      Pattern->AddPlaceholderChunk("type-id");
+      Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
+      Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+      Pattern->AddPlaceholderChunk("expression");
+      Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+      Results.AddResult(Result(Pattern));      
+
+      // reinterpret_cast < type-id > ( expression )
+      Pattern = new CodeCompletionString;
+      Pattern->AddTypedTextChunk("reinterpret_cast");
+      Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
+      Pattern->AddPlaceholderChunk("type-id");
+      Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
+      Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+      Pattern->AddPlaceholderChunk("expression");
+      Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+      Results.AddResult(Result(Pattern));      
+
+      // const_cast < type-id > ( expression )
+      Pattern = new CodeCompletionString;
+      Pattern->AddTypedTextChunk("const_cast");
+      Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
+      Pattern->AddPlaceholderChunk("type-id");
+      Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
+      Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+      Pattern->AddPlaceholderChunk("expression");
+      Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+      Results.AddResult(Result(Pattern));      
+
+      // typeid ( expression-or-type )
+      Pattern = new CodeCompletionString;
+      Pattern->AddTypedTextChunk("typeid");
+      Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+      Pattern->AddPlaceholderChunk("expression-or-type");
+      Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+      Results.AddResult(Result(Pattern));      
+
+      // new T ( ... )
+      Pattern = new CodeCompletionString;
+      Pattern->AddTypedTextChunk("new");
+      Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+      Pattern->AddPlaceholderChunk("type-id");
+      Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+      Pattern->AddPlaceholderChunk("expressions");
+      Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+      Results.AddResult(Result(Pattern));      
+
+      // new T [ ] ( ... )
+      Pattern = new CodeCompletionString;
+      Pattern->AddTypedTextChunk("new");
+      Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+      Pattern->AddPlaceholderChunk("type-id");
+      Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
+      Pattern->AddPlaceholderChunk("size");
+      Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
+      Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+      Pattern->AddPlaceholderChunk("expressions");
+      Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+      Results.AddResult(Result(Pattern));      
+
+      // delete expression
+      Pattern = new CodeCompletionString;
+      Pattern->AddTypedTextChunk("delete");
+      Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+      Pattern->AddPlaceholderChunk("expression");
+      Results.AddResult(Result(Pattern));      
+
+      // delete [] expression
+      Pattern = new CodeCompletionString;
+      Pattern->AddTypedTextChunk("delete");
+      Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
+      Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
+      Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+      Pattern->AddPlaceholderChunk("expression");
+      Results.AddResult(Result(Pattern));
+
+      // throw expression
+      Pattern = new CodeCompletionString;
+      Pattern->AddTypedTextChunk("throw");
+      Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+      Pattern->AddPlaceholderChunk("expression");
+      Results.AddResult(Result(Pattern));
+    }
+
+    if (SemaRef.getLangOptions().ObjC1) {
+      // Add "super", if we're in an Objective-C class with a superclass.
+      if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl())
+        if (Method->getClassInterface()->getSuperClass())
+          Results.AddResult(Result("super"));
+      
+      AddObjCExpressionResults(Results, true);
+    }
+
+    // sizeof expression
+    Pattern = new CodeCompletionString;
+    Pattern->AddTypedTextChunk("sizeof");
+    Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+    Pattern->AddPlaceholderChunk("expression-or-type");
+    Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+    Results.AddResult(Result(Pattern));
+    break;
+  }
+  }
+
+  AddTypeSpecifierResults(SemaRef.getLangOptions(), Results);
+
+  if (SemaRef.getLangOptions().CPlusPlus)
+    Results.AddResult(Result("operator"));
+}
+
+/// \brief If the given declaration has an associated type, add it as a result 
+/// type chunk.
+static void AddResultTypeChunk(ASTContext &Context,
+                               NamedDecl *ND,
+                               CodeCompletionString *Result) {
+  if (!ND)
+    return;
+  
+  // Determine the type of the declaration (if it has a type).
+  QualType T;
+  if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
+    T = Function->getResultType();
+  else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
+    T = Method->getResultType();
+  else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
+    T = FunTmpl->getTemplatedDecl()->getResultType();
+  else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
+    T = Context.getTypeDeclType(cast<TypeDecl>(Enumerator->getDeclContext()));
+  else if (isa<UnresolvedUsingValueDecl>(ND)) {
+    /* Do nothing: ignore unresolved using declarations*/
+  } else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND))
+    T = Value->getType();
+  else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
+    T = Property->getType();
+  
+  if (T.isNull() || Context.hasSameType(T, Context.DependentTy))
+    return;
+  
+  PrintingPolicy Policy(Context.PrintingPolicy);
+  Policy.AnonymousTagLocations = false;
+  
+  std::string TypeStr;
+  T.getAsStringInternal(TypeStr, Policy);
+  Result->AddResultTypeChunk(TypeStr);
+}
+
+/// \brief Add function parameter chunks to the given code completion string.
+static void AddFunctionParameterChunks(ASTContext &Context,
+                                       FunctionDecl *Function,
+                                       CodeCompletionString *Result) {
+  typedef CodeCompletionString::Chunk Chunk;
+  
+  CodeCompletionString *CCStr = Result;
+  
+  for (unsigned P = 0, N = Function->getNumParams(); P != N; ++P) {
+    ParmVarDecl *Param = Function->getParamDecl(P);
+    
+    if (Param->hasDefaultArg()) {
+      // When we see an optional default argument, put that argument and
+      // the remaining default arguments into a new, optional string.
+      CodeCompletionString *Opt = new CodeCompletionString;
+      CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
+      CCStr = Opt;
+    }
+    
+    if (P != 0)
+      CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
+    
+    // Format the placeholder string.
+    std::string PlaceholderStr;
+    if (Param->getIdentifier())
+      PlaceholderStr = Param->getIdentifier()->getName();
+    
+    Param->getType().getAsStringInternal(PlaceholderStr, 
+                                         Context.PrintingPolicy);
+    
+    // Add the placeholder string.
+    CCStr->AddPlaceholderChunk(PlaceholderStr);
+  }
+  
+  if (const FunctionProtoType *Proto 
+        = Function->getType()->getAs<FunctionProtoType>())
+    if (Proto->isVariadic())
+      CCStr->AddPlaceholderChunk(", ...");
+}
+
+/// \brief Add template parameter chunks to the given code completion string.
+static void AddTemplateParameterChunks(ASTContext &Context,
+                                       TemplateDecl *Template,
+                                       CodeCompletionString *Result,
+                                       unsigned MaxParameters = 0) {
+  typedef CodeCompletionString::Chunk Chunk;
+  
+  CodeCompletionString *CCStr = Result;
+  bool FirstParameter = true;
+  
+  TemplateParameterList *Params = Template->getTemplateParameters();
+  TemplateParameterList::iterator PEnd = Params->end();
+  if (MaxParameters)
+    PEnd = Params->begin() + MaxParameters;
+  for (TemplateParameterList::iterator P = Params->begin(); P != PEnd; ++P) {
+    bool HasDefaultArg = false;
+    std::string PlaceholderStr;
+    if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
+      if (TTP->wasDeclaredWithTypename())
+        PlaceholderStr = "typename";
+      else
+        PlaceholderStr = "class";
+      
+      if (TTP->getIdentifier()) {
+        PlaceholderStr += ' ';
+        PlaceholderStr += TTP->getIdentifier()->getName();
+      }
+      
+      HasDefaultArg = TTP->hasDefaultArgument();
+    } else if (NonTypeTemplateParmDecl *NTTP 
+               = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
+      if (NTTP->getIdentifier())
+        PlaceholderStr = NTTP->getIdentifier()->getName();
+      NTTP->getType().getAsStringInternal(PlaceholderStr, 
+                                          Context.PrintingPolicy);
+      HasDefaultArg = NTTP->hasDefaultArgument();
+    } else {
+      assert(isa<TemplateTemplateParmDecl>(*P));
+      TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
+      
+      // Since putting the template argument list into the placeholder would
+      // be very, very long, we just use an abbreviation.
+      PlaceholderStr = "template<...> class";
+      if (TTP->getIdentifier()) {
+        PlaceholderStr += ' ';
+        PlaceholderStr += TTP->getIdentifier()->getName();
+      }
+      
+      HasDefaultArg = TTP->hasDefaultArgument();
+    }
+    
+    if (HasDefaultArg) {
+      // When we see an optional default argument, put that argument and
+      // the remaining default arguments into a new, optional string.
+      CodeCompletionString *Opt = new CodeCompletionString;
+      CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
+      CCStr = Opt;
+    }
+    
+    if (FirstParameter)
+      FirstParameter = false;
+    else
+      CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
+    
+    // Add the placeholder string.
+    CCStr->AddPlaceholderChunk(PlaceholderStr);
+  }    
+}
+
+/// \brief Add a qualifier to the given code-completion string, if the
+/// provided nested-name-specifier is non-NULL.
+static void 
+AddQualifierToCompletionString(CodeCompletionString *Result, 
+                               NestedNameSpecifier *Qualifier, 
+                               bool QualifierIsInformative,
+                               ASTContext &Context) {
+  if (!Qualifier)
+    return;
+  
+  std::string PrintedNNS;
+  {
+    llvm::raw_string_ostream OS(PrintedNNS);
+    Qualifier->print(OS, Context.PrintingPolicy);
+  }
+  if (QualifierIsInformative)
+    Result->AddInformativeChunk(PrintedNNS);
+  else
+    Result->AddTextChunk(PrintedNNS);
+}
+
+static void AddFunctionTypeQualsToCompletionString(CodeCompletionString *Result,
+                                                   FunctionDecl *Function) {
+  const FunctionProtoType *Proto
+    = Function->getType()->getAs<FunctionProtoType>();
+  if (!Proto || !Proto->getTypeQuals())
+    return;
+
+  std::string QualsStr;
+  if (Proto->getTypeQuals() & Qualifiers::Const)
+    QualsStr += " const";
+  if (Proto->getTypeQuals() & Qualifiers::Volatile)
+    QualsStr += " volatile";
+  if (Proto->getTypeQuals() & Qualifiers::Restrict)
+    QualsStr += " restrict";
+  Result->AddInformativeChunk(QualsStr);
+}
+
+/// \brief If possible, create a new code completion string for the given
+/// result.
+///
+/// \returns Either a new, heap-allocated code completion string describing
+/// how to use this result, or NULL to indicate that the string or name of the
+/// result is all that is needed.
+CodeCompletionString *
+CodeCompleteConsumer::Result::CreateCodeCompletionString(Sema &S) {
+  typedef CodeCompletionString::Chunk Chunk;
+  
+  if (Kind == RK_Pattern)
+    return Pattern->Clone();
+  
+  CodeCompletionString *Result = new CodeCompletionString;
+
+  if (Kind == RK_Keyword) {
+    Result->AddTypedTextChunk(Keyword);
+    return Result;
+  }
+  
+  if (Kind == RK_Macro) {
+    MacroInfo *MI = S.PP.getMacroInfo(Macro);
+    assert(MI && "Not a macro?");
+
+    Result->AddTypedTextChunk(Macro->getName());
+
+    if (!MI->isFunctionLike())
+      return Result;
+    
+    // Format a function-like macro with placeholders for the arguments.
+    Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
+    for (MacroInfo::arg_iterator A = MI->arg_begin(), AEnd = MI->arg_end();
+         A != AEnd; ++A) {
+      if (A != MI->arg_begin())
+        Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
+      
+      if (!MI->isVariadic() || A != AEnd - 1) {
+        // Non-variadic argument.
+        Result->AddPlaceholderChunk((*A)->getName());
+        continue;
+      }
+      
+      // Variadic argument; cope with the different between GNU and C99
+      // variadic macros, providing a single placeholder for the rest of the
+      // arguments.
+      if ((*A)->isStr("__VA_ARGS__"))
+        Result->AddPlaceholderChunk("...");
+      else {
+        std::string Arg = (*A)->getName();
+        Arg += "...";
+        Result->AddPlaceholderChunk(Arg);
+      }
+    }
+    Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
+    return Result;
+  }
+  
+  assert(Kind == RK_Declaration && "Missed a macro kind?");
+  NamedDecl *ND = Declaration;
+  
+  if (StartsNestedNameSpecifier) {
+    Result->AddTypedTextChunk(ND->getNameAsString());
+    Result->AddTextChunk("::");
+    return Result;
+  }
+  
+  AddResultTypeChunk(S.Context, ND, Result);
+  
+  if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) {
+    AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative, 
+                                   S.Context);
+    Result->AddTypedTextChunk(Function->getNameAsString());
+    Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
+    AddFunctionParameterChunks(S.Context, Function, Result);
+    Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
+    AddFunctionTypeQualsToCompletionString(Result, Function);
+    return Result;
+  }
+  
+  if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND)) {
+    AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative, 
+                                   S.Context);
+    FunctionDecl *Function = FunTmpl->getTemplatedDecl();
+    Result->AddTypedTextChunk(Function->getNameAsString());
+    
+    // Figure out which template parameters are deduced (or have default
+    // arguments).
+    llvm::SmallVector<bool, 16> Deduced;
+    S.MarkDeducedTemplateParameters(FunTmpl, Deduced);
+    unsigned LastDeducibleArgument;
+    for (LastDeducibleArgument = Deduced.size(); LastDeducibleArgument > 0;
+         --LastDeducibleArgument) {
+      if (!Deduced[LastDeducibleArgument - 1]) {
+        // C++0x: Figure out if the template argument has a default. If so,
+        // the user doesn't need to type this argument.
+        // FIXME: We need to abstract template parameters better!
+        bool HasDefaultArg = false;
+        NamedDecl *Param = FunTmpl->getTemplateParameters()->getParam(
+                                                                      LastDeducibleArgument - 1);
+        if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
+          HasDefaultArg = TTP->hasDefaultArgument();
+        else if (NonTypeTemplateParmDecl *NTTP 
+                 = dyn_cast<NonTypeTemplateParmDecl>(Param))
+          HasDefaultArg = NTTP->hasDefaultArgument();
+        else {
+          assert(isa<TemplateTemplateParmDecl>(Param));
+          HasDefaultArg 
+            = cast<TemplateTemplateParmDecl>(Param)->hasDefaultArgument();
+        }
+        
+        if (!HasDefaultArg)
+          break;
+      }
+    }
+    
+    if (LastDeducibleArgument) {
+      // Some of the function template arguments cannot be deduced from a
+      // function call, so we introduce an explicit template argument list
+      // containing all of the arguments up to the first deducible argument.
+      Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
+      AddTemplateParameterChunks(S.Context, FunTmpl, Result, 
+                                 LastDeducibleArgument);
+      Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
+    }
+    
+    // Add the function parameters
+    Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
+    AddFunctionParameterChunks(S.Context, Function, Result);
+    Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
+    AddFunctionTypeQualsToCompletionString(Result, Function);
+    return Result;
+  }
+  
+  if (TemplateDecl *Template = dyn_cast<TemplateDecl>(ND)) {
+    AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative, 
+                                   S.Context);
+    Result->AddTypedTextChunk(Template->getNameAsString());
+    Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
+    AddTemplateParameterChunks(S.Context, Template, Result);
+    Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
+    return Result;
+  }
+  
+  if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) {
+    Selector Sel = Method->getSelector();
+    if (Sel.isUnarySelector()) {
+      Result->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
+      return Result;
+    }
+
+    std::string SelName = Sel.getIdentifierInfoForSlot(0)->getName().str();
+    SelName += ':';
+    if (StartParameter == 0)
+      Result->AddTypedTextChunk(SelName);
+    else {
+      Result->AddInformativeChunk(SelName);
+      
+      // If there is only one parameter, and we're past it, add an empty
+      // typed-text chunk since there is nothing to type.
+      if (Method->param_size() == 1)
+        Result->AddTypedTextChunk("");
+    }
+    unsigned Idx = 0;
+    for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
+                                     PEnd = Method->param_end();
+         P != PEnd; (void)++P, ++Idx) {
+      if (Idx > 0) {
+        std::string Keyword;
+        if (Idx > StartParameter)
+          Result->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+        if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Idx))
+          Keyword += II->getName().str();
+        Keyword += ":";
+        if (Idx < StartParameter || AllParametersAreInformative) {
+          Result->AddInformativeChunk(Keyword);
+        } else if (Idx == StartParameter)
+          Result->AddTypedTextChunk(Keyword);
+        else
+          Result->AddTextChunk(Keyword);
+      }
+      
+      // If we're before the starting parameter, skip the placeholder.
+      if (Idx < StartParameter)
+        continue;
+
+      std::string Arg;
+      (*P)->getType().getAsStringInternal(Arg, S.Context.PrintingPolicy);
+      Arg = "(" + Arg + ")";
+      if (IdentifierInfo *II = (*P)->getIdentifier())
+        Arg += II->getName().str();
+      if (AllParametersAreInformative)
+        Result->AddInformativeChunk(Arg);
+      else
+        Result->AddPlaceholderChunk(Arg);
+    }
+
+    if (Method->isVariadic()) {
+      if (AllParametersAreInformative)
+        Result->AddInformativeChunk(", ...");
+      else
+        Result->AddPlaceholderChunk(", ...");
+    }
+    
+    return Result;
+  }
+
+  if (Qualifier)
+    AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative, 
+                                   S.Context);
+
+  Result->AddTypedTextChunk(ND->getNameAsString());
+  return Result;
+}
+
+CodeCompletionString *
+CodeCompleteConsumer::OverloadCandidate::CreateSignatureString(
+                                                          unsigned CurrentArg,
+                                                               Sema &S) const {
+  typedef CodeCompletionString::Chunk Chunk;
+  
+  CodeCompletionString *Result = new CodeCompletionString;
+  FunctionDecl *FDecl = getFunction();
+  AddResultTypeChunk(S.Context, FDecl, Result);
+  const FunctionProtoType *Proto 
+    = dyn_cast<FunctionProtoType>(getFunctionType());
+  if (!FDecl && !Proto) {
+    // Function without a prototype. Just give the return type and a 
+    // highlighted ellipsis.
+    const FunctionType *FT = getFunctionType();
+    Result->AddTextChunk(
+            FT->getResultType().getAsString(S.Context.PrintingPolicy));
+    Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
+    Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
+    Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
+    return Result;
+  }
+  
+  if (FDecl)
+    Result->AddTextChunk(FDecl->getNameAsString());
+  else
+    Result->AddTextChunk(
+         Proto->getResultType().getAsString(S.Context.PrintingPolicy));
+  
+  Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
+  unsigned NumParams = FDecl? FDecl->getNumParams() : Proto->getNumArgs();
+  for (unsigned I = 0; I != NumParams; ++I) {
+    if (I)
+      Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
+    
+    std::string ArgString;
+    QualType ArgType;
+    
+    if (FDecl) {
+      ArgString = FDecl->getParamDecl(I)->getNameAsString();
+      ArgType = FDecl->getParamDecl(I)->getOriginalType();
+    } else {
+      ArgType = Proto->getArgType(I);
+    }
+    
+    ArgType.getAsStringInternal(ArgString, S.Context.PrintingPolicy);
+    
+    if (I == CurrentArg)
+      Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, 
+                             ArgString));
+    else
+      Result->AddTextChunk(ArgString);
+  }
+  
+  if (Proto && Proto->isVariadic()) {
+    Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
+    if (CurrentArg < NumParams)
+      Result->AddTextChunk("...");
+    else
+      Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
+  }
+  Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
+  
+  return Result;
+}
+
+namespace {
+  struct SortCodeCompleteResult {
+    typedef CodeCompleteConsumer::Result Result;
+    
+    bool isEarlierDeclarationName(DeclarationName X, DeclarationName Y) const {
+      Selector XSel = X.getObjCSelector();
+      Selector YSel = Y.getObjCSelector();
+      if (!XSel.isNull() && !YSel.isNull()) {
+        // We are comparing two selectors.
+        unsigned N = std::min(XSel.getNumArgs(), YSel.getNumArgs());
+        if (N == 0)
+          ++N;
+        for (unsigned I = 0; I != N; ++I) {
+          IdentifierInfo *XId = XSel.getIdentifierInfoForSlot(I);
+          IdentifierInfo *YId = YSel.getIdentifierInfoForSlot(I);
+          if (!XId || !YId)
+            return XId && !YId;
+          
+          switch (XId->getName().compare_lower(YId->getName())) {
+          case -1: return true;
+          case 1: return false;
+          default: break;
+          }
+        }
+    
+        return XSel.getNumArgs() < YSel.getNumArgs();
+      }
+
+      // For non-selectors, order by kind.
+      if (X.getNameKind() != Y.getNameKind())
+        return X.getNameKind() < Y.getNameKind();
+      
+      // Order identifiers by comparison of their lowercased names.
+      if (IdentifierInfo *XId = X.getAsIdentifierInfo())
+        return XId->getName().compare_lower(
+                                     Y.getAsIdentifierInfo()->getName()) < 0;
+
+      // Order overloaded operators by the order in which they appear
+      // in our list of operators.
+      if (OverloadedOperatorKind XOp = X.getCXXOverloadedOperator())
+        return XOp < Y.getCXXOverloadedOperator();
+
+      // Order C++0x user-defined literal operators lexically by their
+      // lowercased suffixes.
+      if (IdentifierInfo *XLit = X.getCXXLiteralIdentifier())
+        return XLit->getName().compare_lower(
+                                  Y.getCXXLiteralIdentifier()->getName()) < 0;
+
+      // The only stable ordering we have is to turn the name into a
+      // string and then compare the lower-case strings. This is
+      // inefficient, but thankfully does not happen too often.
+      return llvm::StringRef(X.getAsString()).compare_lower(
+                                                 Y.getAsString()) < 0;
+    }
+    
+    /// \brief Retrieve the name that should be used to order a result.
+    ///
+    /// If the name needs to be constructed as a string, that string will be
+    /// saved into Saved and the returned StringRef will refer to it.
+    static llvm::StringRef getOrderedName(const Result &R,
+                                          std::string &Saved) {
+      switch (R.Kind) {
+      case Result::RK_Keyword:
+        return R.Keyword;
+          
+      case Result::RK_Pattern:
+        return R.Pattern->getTypedText();
+          
+      case Result::RK_Macro:
+        return R.Macro->getName();
+          
+      case Result::RK_Declaration:
+        // Handle declarations below.
+        break;
+      }
+            
+      DeclarationName Name = R.Declaration->getDeclName();
+      
+      // If the name is a simple identifier (by far the common case), or a
+      // zero-argument selector, just return a reference to that identifier.
+      if (IdentifierInfo *Id = Name.getAsIdentifierInfo())
+        return Id->getName();
+      if (Name.isObjCZeroArgSelector())
+        if (IdentifierInfo *Id
+                          = Name.getObjCSelector().getIdentifierInfoForSlot(0))
+          return Id->getName();
+      
+      Saved = Name.getAsString();
+      return Saved;
+    }
+    
+    bool operator()(const Result &X, const Result &Y) const {
+      std::string XSaved, YSaved;
+      llvm::StringRef XStr = getOrderedName(X, XSaved);
+      llvm::StringRef YStr = getOrderedName(Y, YSaved);
+      int cmp = XStr.compare_lower(YStr);
+      if (cmp)
+        return cmp < 0;
+      
+      // Non-hidden names precede hidden names.
+      if (X.Hidden != Y.Hidden)
+        return !X.Hidden;
+      
+      // Non-nested-name-specifiers precede nested-name-specifiers.
+      if (X.StartsNestedNameSpecifier != Y.StartsNestedNameSpecifier)
+        return !X.StartsNestedNameSpecifier;
+      
+      return false;
+    }
+  };
+}
+
+static void AddMacroResults(Preprocessor &PP, ResultBuilder &Results) {
+  Results.EnterNewScope();
+  for (Preprocessor::macro_iterator M = PP.macro_begin(), 
+                                 MEnd = PP.macro_end();
+       M != MEnd; ++M)
+    Results.AddResult(M->first);
+  Results.ExitScope();
+}
+
+static void HandleCodeCompleteResults(Sema *S,
+                                      CodeCompleteConsumer *CodeCompleter,
+                                     CodeCompleteConsumer::Result *Results,
+                                     unsigned NumResults) {
+  std::stable_sort(Results, Results + NumResults, SortCodeCompleteResult());
+
+  if (CodeCompleter)
+    CodeCompleter->ProcessCodeCompleteResults(*S, Results, NumResults);
+  
+  for (unsigned I = 0; I != NumResults; ++I)
+    Results[I].Destroy();
+}
+
+void Sema::CodeCompleteOrdinaryName(Scope *S, 
+                                    CodeCompletionContext CompletionContext) {
+  typedef CodeCompleteConsumer::Result Result;
+  ResultBuilder Results(*this);
+
+  // Determine how to filter results, e.g., so that the names of
+  // values (functions, enumerators, function templates, etc.) are
+  // only allowed where we can have an expression.
+  switch (CompletionContext) {
+  case CCC_Namespace:
+  case CCC_Class:
+  case CCC_ObjCInterface:
+  case CCC_ObjCImplementation:
+  case CCC_ObjCInstanceVariableList:
+  case CCC_Template:
+  case CCC_MemberTemplate:
+    Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
+    break;
+
+  case CCC_Expression:
+  case CCC_Statement:
+  case CCC_ForInit:
+  case CCC_Condition:
+    Results.setFilter(&ResultBuilder::IsOrdinaryName);
+    break;
+  }
+
+  CodeCompletionDeclConsumer Consumer(Results, CurContext);
+  LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
+
+  Results.EnterNewScope();
+  AddOrdinaryNameResults(CompletionContext, S, *this, Results);
+  Results.ExitScope();
+
+  if (CodeCompleter->includeMacros())
+    AddMacroResults(PP, Results);
+  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+}
+
+static void AddObjCProperties(ObjCContainerDecl *Container, 
+                              bool AllowCategories,
+                              DeclContext *CurContext,
+                              ResultBuilder &Results) {
+  typedef CodeCompleteConsumer::Result Result;
+
+  // Add properties in this container.
+  for (ObjCContainerDecl::prop_iterator P = Container->prop_begin(),
+                                     PEnd = Container->prop_end();
+       P != PEnd;
+       ++P)
+    Results.MaybeAddResult(Result(*P, 0), CurContext);
+  
+  // Add properties in referenced protocols.
+  if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
+    for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
+                                          PEnd = Protocol->protocol_end();
+         P != PEnd; ++P)
+      AddObjCProperties(*P, AllowCategories, CurContext, Results);
+  } else if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)){
+    if (AllowCategories) {
+      // Look through categories.
+      for (ObjCCategoryDecl *Category = IFace->getCategoryList();
+           Category; Category = Category->getNextClassCategory())
+        AddObjCProperties(Category, AllowCategories, CurContext, Results);
+    }
+    
+    // Look through protocols.
+    for (ObjCInterfaceDecl::protocol_iterator I = IFace->protocol_begin(),
+                                              E = IFace->protocol_end(); 
+         I != E; ++I)
+      AddObjCProperties(*I, AllowCategories, CurContext, Results);
+    
+    // Look in the superclass.
+    if (IFace->getSuperClass())
+      AddObjCProperties(IFace->getSuperClass(), AllowCategories, CurContext, 
+                        Results);
+  } else if (const ObjCCategoryDecl *Category
+                                    = dyn_cast<ObjCCategoryDecl>(Container)) {
+    // Look through protocols.
+    for (ObjCInterfaceDecl::protocol_iterator P = Category->protocol_begin(),
+                                           PEnd = Category->protocol_end(); 
+         P != PEnd; ++P)
+      AddObjCProperties(*P, AllowCategories, CurContext, Results);
+  }
+}
+
+void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
+                                           SourceLocation OpLoc,
+                                           bool IsArrow) {
+  if (!BaseE || !CodeCompleter)
+    return;
+  
+  typedef CodeCompleteConsumer::Result Result;
+  
+  Expr *Base = static_cast<Expr *>(BaseE);
+  QualType BaseType = Base->getType();
+
+  if (IsArrow) {
+    if (const PointerType *Ptr = BaseType->getAs<PointerType>())
+      BaseType = Ptr->getPointeeType();
+    else if (BaseType->isObjCObjectPointerType())
+    /*Do nothing*/ ;
+    else
+      return;
+  }
+  
+  ResultBuilder Results(*this, &ResultBuilder::IsMember);
+  Results.EnterNewScope();
+  if (const RecordType *Record = BaseType->getAs<RecordType>()) {
+    // Access to a C/C++ class, struct, or union.
+    Results.allowNestedNameSpecifiers();
+    CodeCompletionDeclConsumer Consumer(Results, CurContext);
+    LookupVisibleDecls(Record->getDecl(), LookupMemberName, Consumer);
+
+    if (getLangOptions().CPlusPlus) {
+      if (!Results.empty()) {
+        // The "template" keyword can follow "->" or "." in the grammar.
+        // However, we only want to suggest the template keyword if something
+        // is dependent.
+        bool IsDependent = BaseType->isDependentType();
+        if (!IsDependent) {
+          for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent())
+            if (DeclContext *Ctx = (DeclContext *)DepScope->getEntity()) {
+              IsDependent = Ctx->isDependentContext();
+              break;
+            }
+        }
+
+        if (IsDependent)
+          Results.AddResult(Result("template"));
+      }
+    }
+  } else if (!IsArrow && BaseType->getAsObjCInterfacePointerType()) {
+    // Objective-C property reference.
+    
+    // Add property results based on our interface.
+    const ObjCObjectPointerType *ObjCPtr
+      = BaseType->getAsObjCInterfacePointerType();
+    assert(ObjCPtr && "Non-NULL pointer guaranteed above!");
+    AddObjCProperties(ObjCPtr->getInterfaceDecl(), true, CurContext, Results);
+    
+    // Add properties from the protocols in a qualified interface.
+    for (ObjCObjectPointerType::qual_iterator I = ObjCPtr->qual_begin(),
+                                              E = ObjCPtr->qual_end();
+         I != E; ++I)
+      AddObjCProperties(*I, true, CurContext, Results);
+  } else if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
+             (!IsArrow && BaseType->isObjCInterfaceType())) {
+    // Objective-C instance variable access.
+    ObjCInterfaceDecl *Class = 0;
+    if (const ObjCObjectPointerType *ObjCPtr
+                                    = BaseType->getAs<ObjCObjectPointerType>())
+      Class = ObjCPtr->getInterfaceDecl();
+    else
+      Class = BaseType->getAs<ObjCInterfaceType>()->getDecl();
+    
+    // Add all ivars from this class and its superclasses.
+    if (Class) {
+      CodeCompletionDeclConsumer Consumer(Results, CurContext);
+      Results.setFilter(&ResultBuilder::IsObjCIvar);
+      LookupVisibleDecls(Class, LookupMemberName, Consumer);
+    }
+  }
+  
+  // FIXME: How do we cope with isa?
+  
+  Results.ExitScope();
+
+  // Hand off the results found for code completion.
+  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+}
+
+void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
+  if (!CodeCompleter)
+    return;
+  
+  typedef CodeCompleteConsumer::Result Result;
+  ResultBuilder::LookupFilter Filter = 0;
+  switch ((DeclSpec::TST)TagSpec) {
+  case DeclSpec::TST_enum:
+    Filter = &ResultBuilder::IsEnum;
+    break;
+    
+  case DeclSpec::TST_union:
+    Filter = &ResultBuilder::IsUnion;
+    break;
+    
+  case DeclSpec::TST_struct:
+  case DeclSpec::TST_class:
+    Filter = &ResultBuilder::IsClassOrStruct;
+    break;
+    
+  default:
+    assert(false && "Unknown type specifier kind in CodeCompleteTag");
+    return;
+  }
+  
+  ResultBuilder Results(*this);
+  CodeCompletionDeclConsumer Consumer(Results, CurContext);
+
+  // First pass: look for tags.
+  Results.setFilter(Filter);
+  LookupVisibleDecls(S, LookupTagName, Consumer);
+
+  // Second pass: look for nested name specifiers.
+  Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
+  LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer);
+  
+  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+}
+
+void Sema::CodeCompleteCase(Scope *S) {
+  if (getSwitchStack().empty() || !CodeCompleter)
+    return;
+  
+  SwitchStmt *Switch = getSwitchStack().back();
+  if (!Switch->getCond()->getType()->isEnumeralType())
+    return;
+  
+  // Code-complete the cases of a switch statement over an enumeration type
+  // by providing the list of 
+  EnumDecl *Enum = Switch->getCond()->getType()->getAs<EnumType>()->getDecl();
+  
+  // Determine which enumerators we have already seen in the switch statement.
+  // FIXME: Ideally, we would also be able to look *past* the code-completion
+  // token, in case we are code-completing in the middle of the switch and not
+  // at the end. However, we aren't able to do so at the moment.
+  llvm::SmallPtrSet<EnumConstantDecl *, 8> EnumeratorsSeen;
+  NestedNameSpecifier *Qualifier = 0;
+  for (SwitchCase *SC = Switch->getSwitchCaseList(); SC; 
+       SC = SC->getNextSwitchCase()) {
+    CaseStmt *Case = dyn_cast<CaseStmt>(SC);
+    if (!Case)
+      continue;
+
+    Expr *CaseVal = Case->getLHS()->IgnoreParenCasts();
+    if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseVal))
+      if (EnumConstantDecl *Enumerator 
+            = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
+        // We look into the AST of the case statement to determine which 
+        // enumerator was named. Alternatively, we could compute the value of 
+        // the integral constant expression, then compare it against the
+        // values of each enumerator. However, value-based approach would not 
+        // work as well with C++ templates where enumerators declared within a 
+        // template are type- and value-dependent.
+        EnumeratorsSeen.insert(Enumerator);
+        
+        // If this is a qualified-id, keep track of the nested-name-specifier
+        // so that we can reproduce it as part of code completion, e.g.,
+        //
+        //   switch (TagD.getKind()) {
+        //     case TagDecl::TK_enum:
+        //       break;
+        //     case XXX
+        //
+        // At the XXX, our completions are TagDecl::TK_union,
+        // TagDecl::TK_struct, and TagDecl::TK_class, rather than TK_union,
+        // TK_struct, and TK_class.
+        Qualifier = DRE->getQualifier();
+      }
+  }
+  
+  if (getLangOptions().CPlusPlus && !Qualifier && EnumeratorsSeen.empty()) {
+    // If there are no prior enumerators in C++, check whether we have to 
+    // qualify the names of the enumerators that we suggest, because they
+    // may not be visible in this scope.
+    Qualifier = getRequiredQualification(Context, CurContext,
+                                         Enum->getDeclContext());
+    
+    // FIXME: Scoped enums need to start with "EnumDecl" as the context!
+  }
+  
+  // Add any enumerators that have not yet been mentioned.
+  ResultBuilder Results(*this);
+  Results.EnterNewScope();
+  for (EnumDecl::enumerator_iterator E = Enum->enumerator_begin(),
+                                  EEnd = Enum->enumerator_end();
+       E != EEnd; ++E) {
+    if (EnumeratorsSeen.count(*E))
+      continue;
+    
+    Results.AddResult(CodeCompleteConsumer::Result(*E, Qualifier),
+                      CurContext, 0, false);
+  }
+  Results.ExitScope();
+
+  if (CodeCompleter->includeMacros())
+    AddMacroResults(PP, Results);
+  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+}
+
+namespace {
+  struct IsBetterOverloadCandidate {
+    Sema &S;
+    SourceLocation Loc;
+    
+  public:
+    explicit IsBetterOverloadCandidate(Sema &S, SourceLocation Loc)
+      : S(S), Loc(Loc) { }
+    
+    bool 
+    operator()(const OverloadCandidate &X, const OverloadCandidate &Y) const {
+      return S.isBetterOverloadCandidate(X, Y, Loc);
+    }
+  };
+}
+
+void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
+                            ExprTy **ArgsIn, unsigned NumArgs) {
+  if (!CodeCompleter)
+    return;
+
+  // When we're code-completing for a call, we fall back to ordinary
+  // name code-completion whenever we can't produce specific
+  // results. We may want to revisit this strategy in the future,
+  // e.g., by merging the two kinds of results.
+
+  Expr *Fn = (Expr *)FnIn;
+  Expr **Args = (Expr **)ArgsIn;
+
+  // Ignore type-dependent call expressions entirely.
+  if (Fn->isTypeDependent() || 
+      Expr::hasAnyTypeDependentArguments(Args, NumArgs)) {
+    CodeCompleteOrdinaryName(S, CCC_Expression);
+    return;
+  }
+
+  // Build an overload candidate set based on the functions we find.
+  SourceLocation Loc = Fn->getExprLoc();
+  OverloadCandidateSet CandidateSet(Loc);
+
+  // FIXME: What if we're calling something that isn't a function declaration?
+  // FIXME: What if we're calling a pseudo-destructor?
+  // FIXME: What if we're calling a member function?
+  
+  typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate;
+  llvm::SmallVector<ResultCandidate, 8> Results;
+
+  Expr *NakedFn = Fn->IgnoreParenCasts();
+  if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(NakedFn))
+    AddOverloadedCallCandidates(ULE, Args, NumArgs, CandidateSet,
+                                /*PartialOverloading=*/ true);
+  else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(NakedFn)) {
+    FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl());
+    if (FDecl) {
+      if (!FDecl->getType()->getAs<FunctionProtoType>())
+        Results.push_back(ResultCandidate(FDecl));
+      else
+        // FIXME: access?
+        AddOverloadCandidate(FDecl, DeclAccessPair::make(FDecl, AS_none),
+                             Args, NumArgs, CandidateSet,
+                             false, /*PartialOverloading*/true);
+    }
+  }
+  
+  if (!CandidateSet.empty()) {
+    // Sort the overload candidate set by placing the best overloads first.
+    std::stable_sort(CandidateSet.begin(), CandidateSet.end(),
+                     IsBetterOverloadCandidate(*this, Loc));
+  
+    // Add the remaining viable overload candidates as code-completion reslults.
+    for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
+                                     CandEnd = CandidateSet.end();
+         Cand != CandEnd; ++Cand) {
+      if (Cand->Viable)
+        Results.push_back(ResultCandidate(Cand->Function));
+    }
+  }
+
+  CodeCompleteOrdinaryName(S, CCC_Expression);
+  if (!Results.empty())
+    CodeCompleter->ProcessOverloadCandidates(*this, NumArgs, Results.data(), 
+                                             Results.size());
+}
+
+void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
+                                   bool EnteringContext) {
+  if (!SS.getScopeRep() || !CodeCompleter)
+    return;
+  
+  DeclContext *Ctx = computeDeclContext(SS, EnteringContext);
+  if (!Ctx)
+    return;
+
+  // Try to instantiate any non-dependent declaration contexts before
+  // we look in them.
+  if (!isDependentScopeSpecifier(SS) && RequireCompleteDeclContext(SS))
+    return;
+
+  ResultBuilder Results(*this);
+  CodeCompletionDeclConsumer Consumer(Results, CurContext);
+  LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer);
+  
+  // The "template" keyword can follow "::" in the grammar, but only
+  // put it into the grammar if the nested-name-specifier is dependent.
+  NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
+  if (!Results.empty() && NNS->isDependent())
+    Results.AddResult("template");
+  
+  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+}
+
+void Sema::CodeCompleteUsing(Scope *S) {
+  if (!CodeCompleter)
+    return;
+  
+  ResultBuilder Results(*this, &ResultBuilder::IsNestedNameSpecifier);
+  Results.EnterNewScope();
+  
+  // If we aren't in class scope, we could see the "namespace" keyword.
+  if (!S->isClassScope())
+    Results.AddResult(CodeCompleteConsumer::Result("namespace"));
+  
+  // After "using", we can see anything that would start a 
+  // nested-name-specifier.
+  CodeCompletionDeclConsumer Consumer(Results, CurContext);
+  LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
+  Results.ExitScope();
+  
+  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+}
+
+void Sema::CodeCompleteUsingDirective(Scope *S) {
+  if (!CodeCompleter)
+    return;
+  
+  // After "using namespace", we expect to see a namespace name or namespace
+  // alias.
+  ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
+  Results.EnterNewScope();
+  CodeCompletionDeclConsumer Consumer(Results, CurContext);
+  LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
+  Results.ExitScope();
+  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+}
+
+void Sema::CodeCompleteNamespaceDecl(Scope *S)  {
+  if (!CodeCompleter)
+    return;
+  
+  ResultBuilder Results(*this, &ResultBuilder::IsNamespace);
+  DeclContext *Ctx = (DeclContext *)S->getEntity();
+  if (!S->getParent())
+    Ctx = Context.getTranslationUnitDecl();
+  
+  if (Ctx && Ctx->isFileContext()) {
+    // We only want to see those namespaces that have already been defined
+    // within this scope, because its likely that the user is creating an
+    // extended namespace declaration. Keep track of the most recent 
+    // definition of each namespace.
+    std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest;
+    for (DeclContext::specific_decl_iterator<NamespaceDecl> 
+         NS(Ctx->decls_begin()), NSEnd(Ctx->decls_end());
+         NS != NSEnd; ++NS)
+      OrigToLatest[NS->getOriginalNamespace()] = *NS;
+    
+    // Add the most recent definition (or extended definition) of each 
+    // namespace to the list of results.
+    Results.EnterNewScope();
+    for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator 
+         NS = OrigToLatest.begin(), NSEnd = OrigToLatest.end();
+         NS != NSEnd; ++NS)
+      Results.AddResult(CodeCompleteConsumer::Result(NS->second, 0),
+                        CurContext, 0, false);
+    Results.ExitScope();
+  }
+  
+  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+}
+
+void Sema::CodeCompleteNamespaceAliasDecl(Scope *S)  {
+  if (!CodeCompleter)
+    return;
+  
+  // After "namespace", we expect to see a namespace or alias.
+  ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
+  CodeCompletionDeclConsumer Consumer(Results, CurContext);
+  LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
+  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+}
+
+void Sema::CodeCompleteOperatorName(Scope *S) {
+  if (!CodeCompleter)
+    return;
+
+  typedef CodeCompleteConsumer::Result Result;
+  ResultBuilder Results(*this, &ResultBuilder::IsType);
+  Results.EnterNewScope();
+  
+  // Add the names of overloadable operators.
+#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly)      \
+  if (std::strcmp(Spelling, "?"))                                                  \
+    Results.AddResult(Result(Spelling));
+#include "clang/Basic/OperatorKinds.def"
+  
+  // Add any type names visible from the current scope
+  Results.allowNestedNameSpecifiers();
+  CodeCompletionDeclConsumer Consumer(Results, CurContext);
+  LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
+  
+  // Add any type specifiers
+  AddTypeSpecifierResults(getLangOptions(), Results);
+  Results.ExitScope();
+  
+  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+}
+
+// Macro that expands to @Keyword or Keyword, depending on whether NeedAt is
+// true or false.
+#define OBJC_AT_KEYWORD_NAME(NeedAt,Keyword) NeedAt? "@" #Keyword : #Keyword
+static void AddObjCImplementationResults(const LangOptions &LangOpts,
+                                         ResultBuilder &Results,
+                                         bool NeedAt) {
+  typedef CodeCompleteConsumer::Result Result;
+  // Since we have an implementation, we can end it.
+  Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
+  
+  CodeCompletionString *Pattern = 0;
+  if (LangOpts.ObjC2) {
+    // @dynamic
+    Pattern = new CodeCompletionString;
+    Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,dynamic));
+    Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+    Pattern->AddPlaceholderChunk("property");
+    Results.AddResult(Result(Pattern));
+    
+    // @synthesize
+    Pattern = new CodeCompletionString;
+    Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synthesize));
+    Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+    Pattern->AddPlaceholderChunk("property");
+    Results.AddResult(Result(Pattern));
+  }  
+}
+
+static void AddObjCInterfaceResults(const LangOptions &LangOpts,
+                                    ResultBuilder &Results,
+                                    bool NeedAt) {
+  typedef CodeCompleteConsumer::Result Result;
+  
+  // Since we have an interface or protocol, we can end it.
+  Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
+  
+  if (LangOpts.ObjC2) {
+    // @property
+    Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,property)));
+  
+    // @required
+    Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,required)));
+  
+    // @optional
+    Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,optional)));
+  }
+}
+
+static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) {
+  typedef CodeCompleteConsumer::Result Result;
+  CodeCompletionString *Pattern = 0;
+  
+  // @class name ;
+  Pattern = new CodeCompletionString;
+  Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,class));
+  Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+  Pattern->AddPlaceholderChunk("identifier");
+  Results.AddResult(Result(Pattern));
+  
+  // @interface name 
+  // FIXME: Could introduce the whole pattern, including superclasses and 
+  // such.
+  Pattern = new CodeCompletionString;
+  Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,interface));
+  Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+  Pattern->AddPlaceholderChunk("class");
+  Results.AddResult(Result(Pattern));
+  
+  // @protocol name
+  Pattern = new CodeCompletionString;
+  Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
+  Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+  Pattern->AddPlaceholderChunk("protocol");
+  Results.AddResult(Result(Pattern));
+  
+  // @implementation name
+  Pattern = new CodeCompletionString;
+  Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,implementation));
+  Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+  Pattern->AddPlaceholderChunk("class");
+  Results.AddResult(Result(Pattern));
+  
+  // @compatibility_alias name
+  Pattern = new CodeCompletionString;
+  Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,compatibility_alias));
+  Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+  Pattern->AddPlaceholderChunk("alias");
+  Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+  Pattern->AddPlaceholderChunk("class");
+  Results.AddResult(Result(Pattern));
+}
+
+void Sema::CodeCompleteObjCAtDirective(Scope *S, DeclPtrTy ObjCImpDecl,
+                                       bool InInterface) {
+  typedef CodeCompleteConsumer::Result Result;
+  ResultBuilder Results(*this);
+  Results.EnterNewScope();
+  if (ObjCImpDecl)
+    AddObjCImplementationResults(getLangOptions(), Results, false);
+  else if (InInterface)
+    AddObjCInterfaceResults(getLangOptions(), Results, false);
+  else
+    AddObjCTopLevelResults(Results, false);
+  Results.ExitScope();
+  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+}
+
+static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) {
+  typedef CodeCompleteConsumer::Result Result;
+  CodeCompletionString *Pattern = 0;
+
+  // @encode ( type-name )
+  Pattern = new CodeCompletionString;
+  Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,encode));
+  Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+  Pattern->AddPlaceholderChunk("type-name");
+  Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+  Results.AddResult(Result(Pattern));
+  
+  // @protocol ( protocol-name )
+  Pattern = new CodeCompletionString;
+  Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
+  Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+  Pattern->AddPlaceholderChunk("protocol-name");
+  Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+  Results.AddResult(Result(Pattern));
+
+  // @selector ( selector )
+  Pattern = new CodeCompletionString;
+  Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,selector));
+  Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+  Pattern->AddPlaceholderChunk("selector");
+  Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+  Results.AddResult(Result(Pattern));
+}
+
+static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) {
+  typedef CodeCompleteConsumer::Result Result;
+  CodeCompletionString *Pattern = 0;
+  
+  // @try { statements } @catch ( declaration ) { statements } @finally
+  //   { statements }
+  Pattern = new CodeCompletionString;
+  Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,try));
+  Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
+  Pattern->AddPlaceholderChunk("statements");
+  Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
+  Pattern->AddTextChunk("@catch");
+  Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+  Pattern->AddPlaceholderChunk("parameter");
+  Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+  Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
+  Pattern->AddPlaceholderChunk("statements");
+  Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
+  Pattern->AddTextChunk("@finally");
+  Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
+  Pattern->AddPlaceholderChunk("statements");
+  Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
+  Results.AddResult(Result(Pattern));
+  
+  // @throw
+  Pattern = new CodeCompletionString;
+  Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,throw));
+  Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+  Pattern->AddPlaceholderChunk("expression");
+  Results.AddResult(Result(Pattern));
+  
+  // @synchronized ( expression ) { statements }
+  Pattern = new CodeCompletionString;
+  Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synchronized));
+  Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+  Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+  Pattern->AddPlaceholderChunk("expression");
+  Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+  Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
+  Pattern->AddPlaceholderChunk("statements");
+  Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
+  Results.AddResult(Result(Pattern));
+}
+
+static void AddObjCVisibilityResults(const LangOptions &LangOpts,
+                                     ResultBuilder &Results,
+                                     bool NeedAt) {
+  typedef CodeCompleteConsumer::Result Result;
+  Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,private)));
+  Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,protected)));
+  Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,public)));
+  if (LangOpts.ObjC2)
+    Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,package)));    
+}
+
+void Sema::CodeCompleteObjCAtVisibility(Scope *S) {
+  ResultBuilder Results(*this);
+  Results.EnterNewScope();
+  AddObjCVisibilityResults(getLangOptions(), Results, false);
+  Results.ExitScope();
+  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+}
+
+void Sema::CodeCompleteObjCAtStatement(Scope *S) {
+  ResultBuilder Results(*this);
+  Results.EnterNewScope();
+  AddObjCStatementResults(Results, false);
+  AddObjCExpressionResults(Results, false);
+  Results.ExitScope();
+  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+}
+
+void Sema::CodeCompleteObjCAtExpression(Scope *S) {
+  ResultBuilder Results(*this);
+  Results.EnterNewScope();
+  AddObjCExpressionResults(Results, false);
+  Results.ExitScope();
+  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+}
+
+/// \brief Determine whether the addition of the given flag to an Objective-C
+/// property's attributes will cause a conflict.
+static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {
+  // Check if we've already added this flag.
+  if (Attributes & NewFlag)
+    return true;
+  
+  Attributes |= NewFlag;
+  
+  // Check for collisions with "readonly".
+  if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
+      (Attributes & (ObjCDeclSpec::DQ_PR_readwrite |
+                     ObjCDeclSpec::DQ_PR_assign |
+                     ObjCDeclSpec::DQ_PR_copy |
+                     ObjCDeclSpec::DQ_PR_retain)))
+    return true;
+  
+  // Check for more than one of { assign, copy, retain }.
+  unsigned AssignCopyRetMask = Attributes & (ObjCDeclSpec::DQ_PR_assign |
+                                             ObjCDeclSpec::DQ_PR_copy |
+                                             ObjCDeclSpec::DQ_PR_retain);
+  if (AssignCopyRetMask &&
+      AssignCopyRetMask != ObjCDeclSpec::DQ_PR_assign &&
+      AssignCopyRetMask != ObjCDeclSpec::DQ_PR_copy &&
+      AssignCopyRetMask != ObjCDeclSpec::DQ_PR_retain)
+    return true;
+  
+  return false;
+}
+
+void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) { 
+  if (!CodeCompleter)
+    return;
+  
+  unsigned Attributes = ODS.getPropertyAttributes();
+  
+  typedef CodeCompleteConsumer::Result Result;
+  ResultBuilder Results(*this);
+  Results.EnterNewScope();
+  if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly))
+    Results.AddResult(CodeCompleteConsumer::Result("readonly"));
+  if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_assign))
+    Results.AddResult(CodeCompleteConsumer::Result("assign"));
+  if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readwrite))
+    Results.AddResult(CodeCompleteConsumer::Result("readwrite"));
+  if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_retain))
+    Results.AddResult(CodeCompleteConsumer::Result("retain"));
+  if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_copy))
+    Results.AddResult(CodeCompleteConsumer::Result("copy"));
+  if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nonatomic))
+    Results.AddResult(CodeCompleteConsumer::Result("nonatomic"));
+  if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) {
+    CodeCompletionString *Setter = new CodeCompletionString;
+    Setter->AddTypedTextChunk("setter");
+    Setter->AddTextChunk(" = ");
+    Setter->AddPlaceholderChunk("method");
+    Results.AddResult(CodeCompleteConsumer::Result(Setter));
+  }
+  if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) {
+    CodeCompletionString *Getter = new CodeCompletionString;
+    Getter->AddTypedTextChunk("getter");
+    Getter->AddTextChunk(" = ");
+    Getter->AddPlaceholderChunk("method");
+    Results.AddResult(CodeCompleteConsumer::Result(Getter));
+  }
+  Results.ExitScope();
+  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+}
+
+/// \brief Descripts the kind of Objective-C method that we want to find
+/// via code completion.
+enum ObjCMethodKind {
+  MK_Any, //< Any kind of method, provided it means other specified criteria.
+  MK_ZeroArgSelector, //< Zero-argument (unary) selector.
+  MK_OneArgSelector //< One-argument selector.
+};
+
+static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
+                                   ObjCMethodKind WantKind,
+                                   IdentifierInfo **SelIdents,
+                                   unsigned NumSelIdents) {
+  Selector Sel = Method->getSelector();
+  if (NumSelIdents > Sel.getNumArgs())
+    return false;
+      
+  switch (WantKind) {
+  case MK_Any:             break;
+  case MK_ZeroArgSelector: return Sel.isUnarySelector();
+  case MK_OneArgSelector:  return Sel.getNumArgs() == 1;
+  }
+
+  for (unsigned I = 0; I != NumSelIdents; ++I)
+    if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I))
+      return false;
+
+  return true;
+}
+                                   
+/// \brief Add all of the Objective-C methods in the given Objective-C 
+/// container to the set of results.
+///
+/// The container will be a class, protocol, category, or implementation of 
+/// any of the above. This mether will recurse to include methods from 
+/// the superclasses of classes along with their categories, protocols, and
+/// implementations.
+///
+/// \param Container the container in which we'll look to find methods.
+///
+/// \param WantInstance whether to add instance methods (only); if false, this
+/// routine will add factory methods (only).
+///
+/// \param CurContext the context in which we're performing the lookup that
+/// finds methods.
+///
+/// \param Results the structure into which we'll add results.
+static void AddObjCMethods(ObjCContainerDecl *Container, 
+                           bool WantInstanceMethods,
+                           ObjCMethodKind WantKind,
+                           IdentifierInfo **SelIdents,
+                           unsigned NumSelIdents,
+                           DeclContext *CurContext,
+                           ResultBuilder &Results) {
+  typedef CodeCompleteConsumer::Result Result;
+  for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
+                                       MEnd = Container->meth_end();
+       M != MEnd; ++M) {
+    if ((*M)->isInstanceMethod() == WantInstanceMethods) {
+      // Check whether the selector identifiers we've been given are a 
+      // subset of the identifiers for this particular method.
+      if (!isAcceptableObjCMethod(*M, WantKind, SelIdents, NumSelIdents))
+        continue;
+
+      Result R = Result(*M, 0);
+      R.StartParameter = NumSelIdents;
+      R.AllParametersAreInformative = (WantKind != MK_Any);
+      Results.MaybeAddResult(R, CurContext);
+    }
+  }
+  
+  ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
+  if (!IFace)
+    return;
+  
+  // Add methods in protocols.
+  const ObjCList<ObjCProtocolDecl> &Protocols= IFace->getReferencedProtocols();
+  for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
+                                            E = Protocols.end(); 
+       I != E; ++I)
+    AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents, 
+                   CurContext, Results);
+  
+  // Add methods in categories.
+  for (ObjCCategoryDecl *CatDecl = IFace->getCategoryList(); CatDecl;
+       CatDecl = CatDecl->getNextClassCategory()) {
+    AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents, 
+                   NumSelIdents, CurContext, Results);
+    
+    // Add a categories protocol methods.
+    const ObjCList<ObjCProtocolDecl> &Protocols 
+      = CatDecl->getReferencedProtocols();
+    for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
+                                              E = Protocols.end();
+         I != E; ++I)
+      AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, 
+                     NumSelIdents, CurContext, Results);
+    
+    // Add methods in category implementations.
+    if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
+      AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents, 
+                     NumSelIdents, CurContext, Results);
+  }
+  
+  // Add methods in superclass.
+  if (IFace->getSuperClass())
+    AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind, 
+                   SelIdents, NumSelIdents, CurContext, Results);
+
+  // Add methods in our implementation, if any.
+  if (ObjCImplementationDecl *Impl = IFace->getImplementation())
+    AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
+                   NumSelIdents, CurContext, Results);
+}
+
+
+void Sema::CodeCompleteObjCPropertyGetter(Scope *S, DeclPtrTy ClassDecl,
+                                          DeclPtrTy *Methods,
+                                          unsigned NumMethods) {
+  typedef CodeCompleteConsumer::Result Result;
+
+  // Try to find the interface where getters might live.
+  ObjCInterfaceDecl *Class
+    = dyn_cast_or_null<ObjCInterfaceDecl>(ClassDecl.getAs<Decl>());
+  if (!Class) {
+    if (ObjCCategoryDecl *Category
+          = dyn_cast_or_null<ObjCCategoryDecl>(ClassDecl.getAs<Decl>()))
+      Class = Category->getClassInterface();
+
+    if (!Class)
+      return;
+  }
+
+  // Find all of the potential getters.
+  ResultBuilder Results(*this);
+  Results.EnterNewScope();
+
+  // FIXME: We need to do this because Objective-C methods don't get
+  // pushed into DeclContexts early enough. Argh!
+  for (unsigned I = 0; I != NumMethods; ++I) { 
+    if (ObjCMethodDecl *Method
+            = dyn_cast_or_null<ObjCMethodDecl>(Methods[I].getAs<Decl>()))
+      if (Method->isInstanceMethod() &&
+          isAcceptableObjCMethod(Method, MK_ZeroArgSelector, 0, 0)) {
+        Result R = Result(Method, 0);
+        R.AllParametersAreInformative = true;
+        Results.MaybeAddResult(R, CurContext);
+      }
+  }
+
+  AddObjCMethods(Class, true, MK_ZeroArgSelector, 0, 0, CurContext, Results);
+  Results.ExitScope();
+  HandleCodeCompleteResults(this, CodeCompleter,Results.data(),Results.size());
+}
+
+void Sema::CodeCompleteObjCPropertySetter(Scope *S, DeclPtrTy ObjCImplDecl,
+                                          DeclPtrTy *Methods,
+                                          unsigned NumMethods) {
+  typedef CodeCompleteConsumer::Result Result;
+
+  // Try to find the interface where setters might live.
+  ObjCInterfaceDecl *Class
+    = dyn_cast_or_null<ObjCInterfaceDecl>(ObjCImplDecl.getAs<Decl>());
+  if (!Class) {
+    if (ObjCCategoryDecl *Category
+          = dyn_cast_or_null<ObjCCategoryDecl>(ObjCImplDecl.getAs<Decl>()))
+      Class = Category->getClassInterface();
+
+    if (!Class)
+      return;
+  }
+
+  // Find all of the potential getters.
+  ResultBuilder Results(*this);
+  Results.EnterNewScope();
+
+  // FIXME: We need to do this because Objective-C methods don't get
+  // pushed into DeclContexts early enough. Argh!
+  for (unsigned I = 0; I != NumMethods; ++I) { 
+    if (ObjCMethodDecl *Method
+            = dyn_cast_or_null<ObjCMethodDecl>(Methods[I].getAs<Decl>()))
+      if (Method->isInstanceMethod() &&
+          isAcceptableObjCMethod(Method, MK_OneArgSelector, 0, 0)) {
+        Result R = Result(Method, 0);
+        R.AllParametersAreInformative = true;
+        Results.MaybeAddResult(R, CurContext);
+      }
+  }
+
+  AddObjCMethods(Class, true, MK_OneArgSelector, 0, 0, CurContext, Results);
+
+  Results.ExitScope();
+  HandleCodeCompleteResults(this, CodeCompleter,Results.data(),Results.size());
+}
+
+/// \brief When we have an expression with type "id", we may assume
+/// that it has some more-specific class type based on knowledge of
+/// common uses of Objective-C. This routine returns that class type,
+/// or NULL if no better result could be determined.
+static ObjCInterfaceDecl *GetAssumedMessageSendExprType(Expr *E) {
+  ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E);
+  if (!Msg)
+    return 0;
+
+  Selector Sel = Msg->getSelector();
+  if (Sel.isNull())
+    return 0;
+
+  IdentifierInfo *Id = Sel.getIdentifierInfoForSlot(0);
+  if (!Id)
+    return 0;
+
+  ObjCMethodDecl *Method = Msg->getMethodDecl();
+  if (!Method)
+    return 0;
+
+  // Determine the class that we're sending the message to.
+  ObjCInterfaceDecl *IFace = 0;
+  switch (Msg->getReceiverKind()) {
+  case ObjCMessageExpr::Class:
+    if (const ObjCInterfaceType *IFaceType
+                           = Msg->getClassReceiver()->getAs<ObjCInterfaceType>())
+      IFace = IFaceType->getDecl();
+    break;
+
+  case ObjCMessageExpr::Instance: {
+    QualType T = Msg->getInstanceReceiver()->getType();
+    if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
+      IFace = Ptr->getInterfaceDecl();
+    break;
+  }
+
+  case ObjCMessageExpr::SuperInstance:
+  case ObjCMessageExpr::SuperClass:
+    break;
+  }
+
+  if (!IFace)
+    return 0;
+
+  ObjCInterfaceDecl *Super = IFace->getSuperClass();
+  if (Method->isInstanceMethod())
+    return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
+      .Case("retain", IFace)
+      .Case("autorelease", IFace)
+      .Case("copy", IFace)
+      .Case("copyWithZone", IFace)
+      .Case("mutableCopy", IFace)
+      .Case("mutableCopyWithZone", IFace)
+      .Case("awakeFromCoder", IFace)
+      .Case("replacementObjectFromCoder", IFace)
+      .Case("class", IFace)
+      .Case("classForCoder", IFace)
+      .Case("superclass", Super)
+      .Default(0);
+
+  return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
+    .Case("new", IFace)
+    .Case("alloc", IFace)
+    .Case("allocWithZone", IFace)
+    .Case("class", IFace)
+    .Case("superclass", Super)
+    .Default(0);
+}
+
+void Sema::CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc,
+                                        IdentifierInfo **SelIdents,
+                                        unsigned NumSelIdents) {
+  ObjCInterfaceDecl *CDecl = 0;
+  if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
+    // Figure out which interface we're in.
+    CDecl = CurMethod->getClassInterface();
+    if (!CDecl)
+      return;
+    
+    // Find the superclass of this class.
+    CDecl = CDecl->getSuperClass();
+    if (!CDecl)
+      return;
+
+    if (CurMethod->isInstanceMethod()) {
+      // We are inside an instance method, which means that the message
+      // send [super ...] is actually calling an instance method on the
+      // current object. Build the super expression and handle this like
+      // an instance method.
+      QualType SuperTy = Context.getObjCInterfaceType(CDecl);
+      SuperTy = Context.getObjCObjectPointerType(SuperTy);
+      OwningExprResult Super
+        = Owned(new (Context) ObjCSuperExpr(SuperLoc, SuperTy));
+      return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
+                                             SelIdents, NumSelIdents);
+    }
+
+    // Fall through to send to the superclass in CDecl.
+  } else {
+    // "super" may be the name of a type or variable. Figure out which
+    // it is.
+    IdentifierInfo *Super = &Context.Idents.get("super");
+    NamedDecl *ND = LookupSingleName(S, Super, SuperLoc, 
+                                     LookupOrdinaryName);
+    if ((CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(ND))) {
+      // "super" names an interface. Use it.
+    } else if (TypeDecl *TD = dyn_cast_or_null<TypeDecl>(ND)) {
+      if (const ObjCInterfaceType *Iface
+            = Context.getTypeDeclType(TD)->getAs<ObjCInterfaceType>())
+        CDecl = Iface->getDecl();
+    } else if (ND && isa<UnresolvedUsingTypenameDecl>(ND)) {
+      // "super" names an unresolved type; we can't be more specific.
+    } else {
+      // Assume that "super" names some kind of value and parse that way.
+      CXXScopeSpec SS;
+      UnqualifiedId id;
+      id.setIdentifier(Super, SuperLoc);
+      OwningExprResult SuperExpr = ActOnIdExpression(S, SS, id, false, false);
+      return CodeCompleteObjCInstanceMessage(S, (Expr *)SuperExpr.get(),
+                                             SelIdents, NumSelIdents);
+    }
+
+    // Fall through
+  }
+
+  TypeTy *Receiver = 0;
+  if (CDecl)
+    Receiver = Context.getObjCInterfaceType(CDecl).getAsOpaquePtr();
+  return CodeCompleteObjCClassMessage(S, Receiver, SelIdents, 
+                                      NumSelIdents);
+}
+
+void Sema::CodeCompleteObjCClassMessage(Scope *S, TypeTy *Receiver,
+                                        IdentifierInfo **SelIdents,
+                                        unsigned NumSelIdents) {
+  typedef CodeCompleteConsumer::Result Result;
+  ObjCInterfaceDecl *CDecl = 0;
+
+  // If the given name refers to an interface type, retrieve the
+  // corresponding declaration.
+  if (Receiver) {
+    QualType T = GetTypeFromParser(Receiver, 0);
+    if (!T.isNull()) 
+      if (const ObjCInterfaceType *Interface = T->getAs<ObjCInterfaceType>())
+        CDecl = Interface->getDecl();
+  }
+
+  // Add all of the factory methods in this Objective-C class, its protocols,
+  // superclasses, categories, implementation, etc.
+  ResultBuilder Results(*this);
+  Results.EnterNewScope();
+
+  if (CDecl) 
+    AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents, CurContext, 
+                   Results);  
+  else {
+    // We're messaging "id" as a type; provide all class/factory methods.
+
+    // If we have an external source, load the entire class method
+    // pool from the PCH file.
+    if (ExternalSource) {
+      for (uint32_t I = 0, N = ExternalSource->GetNumKnownSelectors(); I != N;
+           ++I) {
+        Selector Sel = ExternalSource->GetSelector(I);
+        if (Sel.isNull() || FactoryMethodPool.count(Sel) || 
+            InstanceMethodPool.count(Sel))
+          continue;
+
+        ReadMethodPool(Sel, /*isInstance=*/false);
+      }
+    }
+
+    for (llvm::DenseMap<Selector, ObjCMethodList>::iterator
+           M = FactoryMethodPool.begin(),
+           MEnd = FactoryMethodPool.end();
+         M != MEnd;
+         ++M) {
+      for (ObjCMethodList *MethList = &M->second; MethList && MethList->Method; 
+           MethList = MethList->Next) {
+        if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents, 
+                                    NumSelIdents))
+          continue;
+
+        Result R(MethList->Method, 0);
+        R.StartParameter = NumSelIdents;
+        R.AllParametersAreInformative = false;
+        Results.MaybeAddResult(R, CurContext);
+      }
+    }
+  }
+
+  Results.ExitScope();
+  
+  // This also suppresses remaining diagnostics.
+  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+}
+
+void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
+                                           IdentifierInfo **SelIdents,
+                                           unsigned NumSelIdents) {
+  typedef CodeCompleteConsumer::Result Result;
+  
+  Expr *RecExpr = static_cast<Expr *>(Receiver);
+  
+  // If necessary, apply function/array conversion to the receiver.
+  // C99 6.7.5.3p[7,8].
+  DefaultFunctionArrayLvalueConversion(RecExpr);
+  QualType ReceiverType = RecExpr->getType();
+  
+  // Build the set of methods we can see.
+  ResultBuilder Results(*this);
+  Results.EnterNewScope();
+
+  // If we're messaging an expression with type "id" or "Class", check
+  // whether we know something special about the receiver that allows
+  // us to assume a more-specific receiver type.
+  if (ReceiverType->isObjCIdType() || ReceiverType->isObjCClassType())
+    if (ObjCInterfaceDecl *IFace = GetAssumedMessageSendExprType(RecExpr))
+      ReceiverType = Context.getObjCObjectPointerType(
+                                          Context.getObjCInterfaceType(IFace));
+  
+  // Handle messages to Class. This really isn't a message to an instance
+  // method, so we treat it the same way we would treat a message send to a
+  // class method.
+  if (ReceiverType->isObjCClassType() || 
+      ReceiverType->isObjCQualifiedClassType()) {
+    if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
+      if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface())
+        AddObjCMethods(ClassDecl, false, MK_Any, SelIdents, NumSelIdents, 
+                       CurContext, Results);
+    }
+  } 
+  // Handle messages to a qualified ID ("id<foo>").
+  else if (const ObjCObjectPointerType *QualID
+             = ReceiverType->getAsObjCQualifiedIdType()) {
+    // Search protocols for instance methods.
+    for (ObjCObjectPointerType::qual_iterator I = QualID->qual_begin(),
+                                              E = QualID->qual_end(); 
+         I != E; ++I)
+      AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext, 
+                     Results);
+  }
+  // Handle messages to a pointer to interface type.
+  else if (const ObjCObjectPointerType *IFacePtr
+                              = ReceiverType->getAsObjCInterfacePointerType()) {
+    // Search the class, its superclasses, etc., for instance methods.
+    AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents,
+                   NumSelIdents, CurContext, Results);
+    
+    // Search protocols for instance methods.
+    for (ObjCObjectPointerType::qual_iterator I = IFacePtr->qual_begin(),
+         E = IFacePtr->qual_end(); 
+         I != E; ++I)
+      AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext, 
+                     Results);
+  }
+  // Handle messages to "id".
+  else if (ReceiverType->isObjCIdType()) {
+    // We're messaging "id", so provide all instance methods we know
+    // about as code-completion results.
+
+    // If we have an external source, load the entire class method
+    // pool from the PCH file.
+    if (ExternalSource) {
+      for (uint32_t I = 0, N = ExternalSource->GetNumKnownSelectors(); I != N;
+           ++I) {
+        Selector Sel = ExternalSource->GetSelector(I);
+        if (Sel.isNull() || InstanceMethodPool.count(Sel) ||
+            FactoryMethodPool.count(Sel))
+          continue;
+
+        ReadMethodPool(Sel, /*isInstance=*/true);
+      }
+    }
+
+    for (llvm::DenseMap<Selector, ObjCMethodList>::iterator
+           M = InstanceMethodPool.begin(),
+           MEnd = InstanceMethodPool.end();
+         M != MEnd;
+         ++M) {
+      for (ObjCMethodList *MethList = &M->second; MethList && MethList->Method; 
+           MethList = MethList->Next) {
+        if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents, 
+                                    NumSelIdents))
+          continue;
+
+        Result R(MethList->Method, 0);
+        R.StartParameter = NumSelIdents;
+        R.AllParametersAreInformative = false;
+        Results.MaybeAddResult(R, CurContext);
+      }
+    }
+  }
+
+  Results.ExitScope();
+  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+}
+
+/// \brief Add all of the protocol declarations that we find in the given
+/// (translation unit) context.
+static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
+                               bool OnlyForwardDeclarations,
+                               ResultBuilder &Results) {
+  typedef CodeCompleteConsumer::Result Result;
+  
+  for (DeclContext::decl_iterator D = Ctx->decls_begin(), 
+                               DEnd = Ctx->decls_end();
+       D != DEnd; ++D) {
+    // Record any protocols we find.
+    if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*D))
+      if (!OnlyForwardDeclarations || Proto->isForwardDecl())
+        Results.AddResult(Result(Proto, 0), CurContext, 0, false);
+
+    // Record any forward-declared protocols we find.
+    if (ObjCForwardProtocolDecl *Forward
+          = dyn_cast<ObjCForwardProtocolDecl>(*D)) {
+      for (ObjCForwardProtocolDecl::protocol_iterator 
+             P = Forward->protocol_begin(),
+             PEnd = Forward->protocol_end();
+           P != PEnd; ++P)
+        if (!OnlyForwardDeclarations || (*P)->isForwardDecl())
+          Results.AddResult(Result(*P, 0), CurContext, 0, false);
+    }
+  }
+}
+
+void Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
+                                              unsigned NumProtocols) {
+  ResultBuilder Results(*this);
+  Results.EnterNewScope();
+  
+  // Tell the result set to ignore all of the protocols we have
+  // already seen.
+  for (unsigned I = 0; I != NumProtocols; ++I)
+    if (ObjCProtocolDecl *Protocol = LookupProtocol(Protocols[I].first,
+                                                    Protocols[I].second))
+      Results.Ignore(Protocol);
+
+  // Add all protocols.
+  AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, false,
+                     Results);
+
+  Results.ExitScope();
+  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+}
+
+void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
+  ResultBuilder Results(*this);
+  Results.EnterNewScope();
+  
+  // Add all protocols.
+  AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, true,
+                     Results);
+
+  Results.ExitScope();
+  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+}
+
+/// \brief Add all of the Objective-C interface declarations that we find in
+/// the given (translation unit) context.
+static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
+                                bool OnlyForwardDeclarations,
+                                bool OnlyUnimplemented,
+                                ResultBuilder &Results) {
+  typedef CodeCompleteConsumer::Result Result;
+  
+  for (DeclContext::decl_iterator D = Ctx->decls_begin(), 
+                               DEnd = Ctx->decls_end();
+       D != DEnd; ++D) {
+    // Record any interfaces we find.
+    if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
+      if ((!OnlyForwardDeclarations || Class->isForwardDecl()) &&
+          (!OnlyUnimplemented || !Class->getImplementation()))
+        Results.AddResult(Result(Class, 0), CurContext, 0, false);
+
+    // Record any forward-declared interfaces we find.
+    if (ObjCClassDecl *Forward = dyn_cast<ObjCClassDecl>(*D)) {
+      for (ObjCClassDecl::iterator C = Forward->begin(), CEnd = Forward->end();
+           C != CEnd; ++C)
+        if ((!OnlyForwardDeclarations || C->getInterface()->isForwardDecl()) &&
+            (!OnlyUnimplemented || !C->getInterface()->getImplementation()))
+          Results.AddResult(Result(C->getInterface(), 0), CurContext,
+                            0, false);
+    }
+  }
+}
+
+void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) { 
+  ResultBuilder Results(*this);
+  Results.EnterNewScope();
+  
+  // Add all classes.
+  AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, true,
+                      false, Results);
+
+  Results.ExitScope();
+  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+}
+
+void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName,
+                                      SourceLocation ClassNameLoc) { 
+  ResultBuilder Results(*this);
+  Results.EnterNewScope();
+  
+  // Make sure that we ignore the class we're currently defining.
+  NamedDecl *CurClass
+    = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
+  if (CurClass && isa<ObjCInterfaceDecl>(CurClass))
+    Results.Ignore(CurClass);
+
+  // Add all classes.
+  AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
+                      false, Results);
+
+  Results.ExitScope();
+  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+}
+
+void Sema::CodeCompleteObjCImplementationDecl(Scope *S) { 
+  ResultBuilder Results(*this);
+  Results.EnterNewScope();
+
+  // Add all unimplemented classes.
+  AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
+                      true, Results);
+
+  Results.ExitScope();
+  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+}
+
+void Sema::CodeCompleteObjCInterfaceCategory(Scope *S, 
+                                             IdentifierInfo *ClassName,
+                                             SourceLocation ClassNameLoc) {
+  typedef CodeCompleteConsumer::Result Result;
+  
+  ResultBuilder Results(*this);
+  
+  // Ignore any categories we find that have already been implemented by this
+  // interface.
+  llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
+  NamedDecl *CurClass
+    = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
+  if (ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass))
+    for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
+         Category = Category->getNextClassCategory())
+      CategoryNames.insert(Category->getIdentifier());
+  
+  // Add all of the categories we know about.
+  Results.EnterNewScope();
+  TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
+  for (DeclContext::decl_iterator D = TU->decls_begin(), 
+                               DEnd = TU->decls_end();
+       D != DEnd; ++D) 
+    if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(*D))
+      if (CategoryNames.insert(Category->getIdentifier()))
+        Results.AddResult(Result(Category, 0), CurContext, 0, false);
+  Results.ExitScope();
+  
+  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());  
+}
+
+void Sema::CodeCompleteObjCImplementationCategory(Scope *S, 
+                                                  IdentifierInfo *ClassName,
+                                                  SourceLocation ClassNameLoc) {
+  typedef CodeCompleteConsumer::Result Result;
+  
+  // Find the corresponding interface. If we couldn't find the interface, the
+  // program itself is ill-formed. However, we'll try to be helpful still by
+  // providing the list of all of the categories we know about.
+  NamedDecl *CurClass
+    = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
+  ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass);
+  if (!Class)
+    return CodeCompleteObjCInterfaceCategory(S, ClassName, ClassNameLoc);
+    
+  ResultBuilder Results(*this);
+  
+  // Add all of the categories that have have corresponding interface 
+  // declarations in this class and any of its superclasses, except for
+  // already-implemented categories in the class itself.
+  llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
+  Results.EnterNewScope();
+  bool IgnoreImplemented = true;
+  while (Class) {
+    for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
+         Category = Category->getNextClassCategory())
+      if ((!IgnoreImplemented || !Category->getImplementation()) &&
+          CategoryNames.insert(Category->getIdentifier()))
+        Results.AddResult(Result(Category, 0), CurContext, 0, false);
+    
+    Class = Class->getSuperClass();
+    IgnoreImplemented = false;
+  }
+  Results.ExitScope();
+  
+  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());  
+}
+
+void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, DeclPtrTy ObjCImpDecl) {
+  typedef CodeCompleteConsumer::Result Result;
+  ResultBuilder Results(*this);
+
+  // Figure out where this @synthesize lives.
+  ObjCContainerDecl *Container
+    = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl.getAs<Decl>());
+  if (!Container || 
+      (!isa<ObjCImplementationDecl>(Container) && 
+       !isa<ObjCCategoryImplDecl>(Container)))
+    return; 
+
+  // Ignore any properties that have already been implemented.
+  for (DeclContext::decl_iterator D = Container->decls_begin(), 
+                               DEnd = Container->decls_end();
+       D != DEnd; ++D)
+    if (ObjCPropertyImplDecl *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(*D))
+      Results.Ignore(PropertyImpl->getPropertyDecl());
+  
+  // Add any properties that we find.
+  Results.EnterNewScope();
+  if (ObjCImplementationDecl *ClassImpl
+        = dyn_cast<ObjCImplementationDecl>(Container))
+    AddObjCProperties(ClassImpl->getClassInterface(), false, CurContext, 
+                      Results);
+  else
+    AddObjCProperties(cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(),
+                      false, CurContext, Results);
+  Results.ExitScope();
+  
+  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());  
+}
+
+void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S, 
+                                                  IdentifierInfo *PropertyName,
+                                                  DeclPtrTy ObjCImpDecl) {
+  typedef CodeCompleteConsumer::Result Result;
+  ResultBuilder Results(*this);
+
+  // Figure out where this @synthesize lives.
+  ObjCContainerDecl *Container
+    = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl.getAs<Decl>());
+  if (!Container || 
+      (!isa<ObjCImplementationDecl>(Container) && 
+       !isa<ObjCCategoryImplDecl>(Container)))
+    return; 
+  
+  // Figure out which interface we're looking into.
+  ObjCInterfaceDecl *Class = 0;
+  if (ObjCImplementationDecl *ClassImpl
+                                 = dyn_cast<ObjCImplementationDecl>(Container))  
+    Class = ClassImpl->getClassInterface();
+  else
+    Class = cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl()
+                                                          ->getClassInterface();
+
+  // Add all of the instance variables in this class and its superclasses.
+  Results.EnterNewScope();
+  for(; Class; Class = Class->getSuperClass()) {
+    // FIXME: We could screen the type of each ivar for compatibility with
+    // the property, but is that being too paternal?
+    for (ObjCInterfaceDecl::ivar_iterator IVar = Class->ivar_begin(),
+                                       IVarEnd = Class->ivar_end();
+         IVar != IVarEnd; ++IVar) 
+      Results.AddResult(Result(*IVar, 0), CurContext, 0, false);
+  }
+  Results.ExitScope();
+  
+  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+}
+
+typedef llvm::DenseMap<Selector, ObjCMethodDecl *> KnownMethodsMap;
+
+/// \brief Find all of the methods that reside in the given container
+/// (and its superclasses, protocols, etc.) that meet the given
+/// criteria. Insert those methods into the map of known methods,
+/// indexed by selector so they can be easily found.
+static void FindImplementableMethods(ASTContext &Context,
+                                     ObjCContainerDecl *Container,
+                                     bool WantInstanceMethods,
+                                     QualType ReturnType,
+                                     bool IsInImplementation,
+                                     KnownMethodsMap &KnownMethods) {
+  if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)) {
+    // Recurse into protocols.
+    const ObjCList<ObjCProtocolDecl> &Protocols
+      = IFace->getReferencedProtocols();
+    for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
+           E = Protocols.end(); 
+         I != E; ++I)
+      FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
+                               IsInImplementation, KnownMethods);
+
+    // If we're not in the implementation of a class, also visit the
+    // superclass.
+    if (!IsInImplementation && IFace->getSuperClass())
+      FindImplementableMethods(Context, IFace->getSuperClass(), 
+                               WantInstanceMethods, ReturnType,
+                               IsInImplementation, KnownMethods);
+
+    // Add methods from any class extensions (but not from categories;
+    // those should go into category implementations).
+    for (ObjCCategoryDecl *Cat = IFace->getCategoryList(); Cat;
+         Cat = Cat->getNextClassCategory()) {
+      if (!Cat->IsClassExtension())
+        continue;
+
+      FindImplementableMethods(Context, Cat, WantInstanceMethods, ReturnType,
+                               IsInImplementation, KnownMethods);      
+    }
+  }
+
+  if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
+    // Recurse into protocols.
+    const ObjCList<ObjCProtocolDecl> &Protocols
+      = Category->getReferencedProtocols();
+    for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
+           E = Protocols.end(); 
+         I != E; ++I)
+      FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
+                               IsInImplementation, KnownMethods);
+  }
+
+  if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
+    // Recurse into protocols.
+    const ObjCList<ObjCProtocolDecl> &Protocols
+      = Protocol->getReferencedProtocols();
+    for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
+           E = Protocols.end(); 
+         I != E; ++I)
+      FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
+                               IsInImplementation, KnownMethods);
+  }
+
+  // Add methods in this container. This operation occurs last because
+  // we want the methods from this container to override any methods
+  // we've previously seen with the same selector.
+  for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
+                                       MEnd = Container->meth_end();
+       M != MEnd; ++M) {
+    if ((*M)->isInstanceMethod() == WantInstanceMethods) {
+      if (!ReturnType.isNull() &&
+          !Context.hasSameUnqualifiedType(ReturnType, (*M)->getResultType()))
+        continue;
+
+      KnownMethods[(*M)->getSelector()] = *M;
+    }
+  }
+}
+
+void Sema::CodeCompleteObjCMethodDecl(Scope *S, 
+                                      bool IsInstanceMethod,
+                                      TypeTy *ReturnTy,
+                                      DeclPtrTy IDecl) {
+  // Determine the return type of the method we're declaring, if
+  // provided.
+  QualType ReturnType = GetTypeFromParser(ReturnTy);
+
+  // Determine where we should start searching for methods, and where we 
+  ObjCContainerDecl *SearchDecl = 0, *CurrentDecl = 0;
+  bool IsInImplementation = false;
+  if (Decl *D = IDecl.getAs<Decl>()) {
+    if (ObjCImplementationDecl *Impl = dyn_cast<ObjCImplementationDecl>(D)) {
+      SearchDecl = Impl->getClassInterface();
+      CurrentDecl = Impl;
+      IsInImplementation = true;
+    } else if (ObjCCategoryImplDecl *CatImpl 
+                                       = dyn_cast<ObjCCategoryImplDecl>(D)) {
+      SearchDecl = CatImpl->getCategoryDecl();
+      CurrentDecl = CatImpl;
+      IsInImplementation = true;
+    } else {
+      SearchDecl = dyn_cast<ObjCContainerDecl>(D);
+      CurrentDecl = SearchDecl;
+    }
+  }
+
+  if (!SearchDecl && S) {
+    if (DeclContext *DC = static_cast<DeclContext *>(S->getEntity())) {
+      SearchDecl = dyn_cast<ObjCContainerDecl>(DC);
+      CurrentDecl = SearchDecl;
+    }
+  }
+
+  if (!SearchDecl || !CurrentDecl) {
+    HandleCodeCompleteResults(this, CodeCompleter, 0, 0);
+    return;
+  }
+    
+  // Find all of the methods that we could declare/implement here.
+  KnownMethodsMap KnownMethods;
+  FindImplementableMethods(Context, SearchDecl, IsInstanceMethod, 
+                           ReturnType, IsInImplementation, KnownMethods);
+  
+  // Erase any methods that have already been declared or
+  // implemented here.
+  for (ObjCContainerDecl::method_iterator M = CurrentDecl->meth_begin(),
+                                       MEnd = CurrentDecl->meth_end();
+       M != MEnd; ++M) {
+    if ((*M)->isInstanceMethod() != IsInstanceMethod)
+      continue;
+    
+    KnownMethodsMap::iterator Pos = KnownMethods.find((*M)->getSelector());
+    if (Pos != KnownMethods.end())
+      KnownMethods.erase(Pos);
+  }
+
+  // Add declarations or definitions for each of the known methods.
+  typedef CodeCompleteConsumer::Result Result;
+  ResultBuilder Results(*this);
+  Results.EnterNewScope();
+  PrintingPolicy Policy(Context.PrintingPolicy);
+  Policy.AnonymousTagLocations = false;
+  for (KnownMethodsMap::iterator M = KnownMethods.begin(), 
+                              MEnd = KnownMethods.end();
+       M != MEnd; ++M) {
+    ObjCMethodDecl *Method = M->second;
+    CodeCompletionString *Pattern = new CodeCompletionString;
+    
+    // If the result type was not already provided, add it to the
+    // pattern as (type).
+    if (ReturnType.isNull()) {
+      std::string TypeStr;
+      Method->getResultType().getAsStringInternal(TypeStr, Policy);
+      Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+      Pattern->AddTextChunk(TypeStr);
+      Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+    }
+
+    Selector Sel = Method->getSelector();
+
+    // Add the first part of the selector to the pattern.
+    Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
+
+    // Add parameters to the pattern.
+    unsigned I = 0;
+    for (ObjCMethodDecl::param_iterator P = Method->param_begin(), 
+                                     PEnd = Method->param_end();
+         P != PEnd; (void)++P, ++I) {
+      // Add the part of the selector name.
+      if (I == 0)
+        Pattern->AddChunk(CodeCompletionString::CK_Colon);
+      else if (I < Sel.getNumArgs()) {
+        Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+        Pattern->AddTextChunk(Sel.getIdentifierInfoForSlot(1)->getName());
+        Pattern->AddChunk(CodeCompletionString::CK_Colon);
+      } else
+        break;
+
+      // Add the parameter type.
+      std::string TypeStr;
+      (*P)->getOriginalType().getAsStringInternal(TypeStr, Policy);
+      Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+      Pattern->AddTextChunk(TypeStr);
+      Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+      
+      if (IdentifierInfo *Id = (*P)->getIdentifier())
+        Pattern->AddTextChunk(Id->getName());
+    }
+
+    if (Method->isVariadic()) {
+      if (Method->param_size() > 0)
+        Pattern->AddChunk(CodeCompletionString::CK_Comma);
+      Pattern->AddTextChunk("...");
+    }
+
+    if (IsInImplementation) {
+      // We will be defining the method here, so add a compound statement.
+      Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+      Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
+      Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
+      if (!Method->getResultType()->isVoidType()) {
+        // If the result type is not void, add a return clause.
+        Pattern->AddTextChunk("return");
+        Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+        Pattern->AddPlaceholderChunk("expression");
+        Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
+      } else
+        Pattern->AddPlaceholderChunk("statements");
+        
+      Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
+      Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
+    }
+
+    Results.AddResult(Result(Pattern));
+  }
+
+  Results.ExitScope();
+  
+  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+}
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
new file mode 100644
index 0000000..3f309bb
--- /dev/null
+++ b/lib/Sema/SemaDecl.cpp
@@ -0,0 +1,6572 @@
+//===--- SemaDecl.cpp - Semantic Analysis for Declarations ----------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements semantic analysis for declarations.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Sema.h"
+#include "SemaInit.h"
+#include "Lookup.h"
+#include "clang/AST/APValue.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/CXXInheritance.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/StmtCXX.h"
+#include "clang/Parse/DeclSpec.h"
+#include "clang/Parse/ParseDiagnostic.h"
+#include "clang/Parse/Template.h"
+#include "clang/Basic/PartialDiagnostic.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/TargetInfo.h"
+// FIXME: layering (ideally, Sema shouldn't be dependent on Lex API's)
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Lex/HeaderSearch.h"
+#include "llvm/ADT/Triple.h"
+#include <algorithm>
+#include <cstring>
+#include <functional>
+using namespace clang;
+
+/// getDeclName - Return a pretty name for the specified decl if possible, or
+/// an empty string if not.  This is used for pretty crash reporting.
+std::string Sema::getDeclName(DeclPtrTy d) {
+  Decl *D = d.getAs<Decl>();
+  if (NamedDecl *DN = dyn_cast_or_null<NamedDecl>(D))
+    return DN->getQualifiedNameAsString();
+  return "";
+}
+
+Sema::DeclGroupPtrTy Sema::ConvertDeclToDeclGroup(DeclPtrTy Ptr) {
+  return DeclGroupPtrTy::make(DeclGroupRef(Ptr.getAs<Decl>()));
+}
+
+/// \brief If the identifier refers to a type name within this scope,
+/// return the declaration of that type.
+///
+/// This routine performs ordinary name lookup of the identifier II
+/// within the given scope, with optional C++ scope specifier SS, to
+/// determine whether the name refers to a type. If so, returns an
+/// opaque pointer (actually a QualType) corresponding to that
+/// type. Otherwise, returns NULL.
+///
+/// If name lookup results in an ambiguity, this routine will complain
+/// and then return NULL.
+Sema::TypeTy *Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
+                                Scope *S, CXXScopeSpec *SS,
+                                bool isClassName,
+                                TypeTy *ObjectTypePtr) {
+  // Determine where we will perform name lookup.
+  DeclContext *LookupCtx = 0;
+  if (ObjectTypePtr) {
+    QualType ObjectType = QualType::getFromOpaquePtr(ObjectTypePtr);
+    if (ObjectType->isRecordType())
+      LookupCtx = computeDeclContext(ObjectType);
+  } else if (SS && SS->isNotEmpty()) {
+    LookupCtx = computeDeclContext(*SS, false);
+
+    if (!LookupCtx) {
+      if (isDependentScopeSpecifier(*SS)) {
+        // C++ [temp.res]p3:
+        //   A qualified-id that refers to a type and in which the
+        //   nested-name-specifier depends on a template-parameter (14.6.2)
+        //   shall be prefixed by the keyword typename to indicate that the
+        //   qualified-id denotes a type, forming an
+        //   elaborated-type-specifier (7.1.5.3).
+        //
+        // We therefore do not perform any name lookup if the result would
+        // refer to a member of an unknown specialization.
+        if (!isClassName)
+          return 0;
+        
+        // We know from the grammar that this name refers to a type, so build a
+        // DependentNameType node to describe the type.
+        return CheckTypenameType(ETK_None,
+                                 (NestedNameSpecifier *)SS->getScopeRep(),
+                                 II, SS->getRange()).getAsOpaquePtr();
+      }
+      
+      return 0;
+    }
+    
+    if (!LookupCtx->isDependentContext() && RequireCompleteDeclContext(*SS))
+      return 0;
+  }
+
+  // FIXME: LookupNestedNameSpecifierName isn't the right kind of
+  // lookup for class-names.
+  LookupNameKind Kind = isClassName ? LookupNestedNameSpecifierName :
+                                      LookupOrdinaryName;
+  LookupResult Result(*this, &II, NameLoc, Kind);
+  if (LookupCtx) {
+    // Perform "qualified" name lookup into the declaration context we
+    // computed, which is either the type of the base of a member access
+    // expression or the declaration context associated with a prior
+    // nested-name-specifier.
+    LookupQualifiedName(Result, LookupCtx);
+
+    if (ObjectTypePtr && Result.empty()) {
+      // C++ [basic.lookup.classref]p3:
+      //   If the unqualified-id is ~type-name, the type-name is looked up
+      //   in the context of the entire postfix-expression. If the type T of 
+      //   the object expression is of a class type C, the type-name is also
+      //   looked up in the scope of class C. At least one of the lookups shall
+      //   find a name that refers to (possibly cv-qualified) T.
+      LookupName(Result, S);
+    }
+  } else {
+    // Perform unqualified name lookup.
+    LookupName(Result, S);
+  }
+  
+  NamedDecl *IIDecl = 0;
+  switch (Result.getResultKind()) {
+  case LookupResult::NotFound:
+  case LookupResult::NotFoundInCurrentInstantiation:
+  case LookupResult::FoundOverloaded:
+  case LookupResult::FoundUnresolvedValue:
+    Result.suppressDiagnostics();
+    return 0;
+
+  case LookupResult::Ambiguous:
+    // Recover from type-hiding ambiguities by hiding the type.  We'll
+    // do the lookup again when looking for an object, and we can
+    // diagnose the error then.  If we don't do this, then the error
+    // about hiding the type will be immediately followed by an error
+    // that only makes sense if the identifier was treated like a type.
+    if (Result.getAmbiguityKind() == LookupResult::AmbiguousTagHiding) {
+      Result.suppressDiagnostics();
+      return 0;
+    }
+
+    // Look to see if we have a type anywhere in the list of results.
+    for (LookupResult::iterator Res = Result.begin(), ResEnd = Result.end();
+         Res != ResEnd; ++Res) {
+      if (isa<TypeDecl>(*Res) || isa<ObjCInterfaceDecl>(*Res)) {
+        if (!IIDecl ||
+            (*Res)->getLocation().getRawEncoding() <
+              IIDecl->getLocation().getRawEncoding())
+          IIDecl = *Res;
+      }
+    }
+
+    if (!IIDecl) {
+      // None of the entities we found is a type, so there is no way
+      // to even assume that the result is a type. In this case, don't
+      // complain about the ambiguity. The parser will either try to
+      // perform this lookup again (e.g., as an object name), which
+      // will produce the ambiguity, or will complain that it expected
+      // a type name.
+      Result.suppressDiagnostics();
+      return 0;
+    }
+
+    // We found a type within the ambiguous lookup; diagnose the
+    // ambiguity and then return that type. This might be the right
+    // answer, or it might not be, but it suppresses any attempt to
+    // perform the name lookup again.
+    break;
+
+  case LookupResult::Found:
+    IIDecl = Result.getFoundDecl();
+    break;
+  }
+
+  assert(IIDecl && "Didn't find decl");
+
+  QualType T;
+  if (TypeDecl *TD = dyn_cast<TypeDecl>(IIDecl)) {
+    DiagnoseUseOfDecl(IIDecl, NameLoc);
+
+    if (T.isNull())
+      T = Context.getTypeDeclType(TD);
+    
+    if (SS)
+      T = getQualifiedNameType(*SS, T);
+    
+  } else if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(IIDecl)) {
+    T = Context.getObjCInterfaceType(IDecl);
+  } else if (UnresolvedUsingTypenameDecl *UUDecl =
+               dyn_cast<UnresolvedUsingTypenameDecl>(IIDecl)) {
+    // FIXME: preserve source structure information.
+    T = Context.getDependentNameType(ETK_None, 
+                                     UUDecl->getTargetNestedNameSpecifier(), 
+                                     &II);
+  } else {
+    // If it's not plausibly a type, suppress diagnostics.
+    Result.suppressDiagnostics();
+    return 0;
+  }
+
+  return T.getAsOpaquePtr();
+}
+
+/// isTagName() - This method is called *for error recovery purposes only*
+/// to determine if the specified name is a valid tag name ("struct foo").  If
+/// so, this returns the TST for the tag corresponding to it (TST_enum,
+/// TST_union, TST_struct, TST_class).  This is used to diagnose cases in C
+/// where the user forgot to specify the tag.
+DeclSpec::TST Sema::isTagName(IdentifierInfo &II, Scope *S) {
+  // Do a tag name lookup in this scope.
+  LookupResult R(*this, &II, SourceLocation(), LookupTagName);
+  LookupName(R, S, false);
+  R.suppressDiagnostics();
+  if (R.getResultKind() == LookupResult::Found)
+    if (const TagDecl *TD = R.getAsSingle<TagDecl>()) {
+      switch (TD->getTagKind()) {
+      case TagDecl::TK_struct: return DeclSpec::TST_struct;
+      case TagDecl::TK_union:  return DeclSpec::TST_union;
+      case TagDecl::TK_class:  return DeclSpec::TST_class;
+      case TagDecl::TK_enum:   return DeclSpec::TST_enum;
+      }
+    }
+
+  return DeclSpec::TST_unspecified;
+}
+
+bool Sema::DiagnoseUnknownTypeName(const IdentifierInfo &II, 
+                                   SourceLocation IILoc,
+                                   Scope *S,
+                                   CXXScopeSpec *SS,
+                                   TypeTy *&SuggestedType) {
+  // We don't have anything to suggest (yet).
+  SuggestedType = 0;
+  
+  // There may have been a typo in the name of the type. Look up typo
+  // results, in case we have something that we can suggest.
+  LookupResult Lookup(*this, &II, IILoc, LookupOrdinaryName, 
+                      NotForRedeclaration);
+
+  if (DeclarationName Corrected = CorrectTypo(Lookup, S, SS, 0, 0, CTC_Type)) {
+    if (NamedDecl *Result = Lookup.getAsSingle<NamedDecl>()) {
+      if ((isa<TypeDecl>(Result) || isa<ObjCInterfaceDecl>(Result)) &&
+          !Result->isInvalidDecl()) {
+        // We found a similarly-named type or interface; suggest that.
+        if (!SS || !SS->isSet())
+          Diag(IILoc, diag::err_unknown_typename_suggest)
+            << &II << Lookup.getLookupName()
+            << FixItHint::CreateReplacement(SourceRange(IILoc),
+                                            Result->getNameAsString());
+        else if (DeclContext *DC = computeDeclContext(*SS, false))
+          Diag(IILoc, diag::err_unknown_nested_typename_suggest) 
+            << &II << DC << Lookup.getLookupName() << SS->getRange()
+            << FixItHint::CreateReplacement(SourceRange(IILoc),
+                                            Result->getNameAsString());
+        else
+          llvm_unreachable("could not have corrected a typo here");
+
+        Diag(Result->getLocation(), diag::note_previous_decl)
+          << Result->getDeclName();
+        
+        SuggestedType = getTypeName(*Result->getIdentifier(), IILoc, S, SS);
+        return true;
+      }
+    } else if (Lookup.empty()) {
+      // We corrected to a keyword.
+      // FIXME: Actually recover with the keyword we suggest, and emit a fix-it.
+      Diag(IILoc, diag::err_unknown_typename_suggest)
+        << &II << Corrected;
+      return true;      
+    }
+  }
+
+  if (getLangOptions().CPlusPlus) {
+    // See if II is a class template that the user forgot to pass arguments to.
+    UnqualifiedId Name;
+    Name.setIdentifier(&II, IILoc);
+    CXXScopeSpec EmptySS;
+    TemplateTy TemplateResult;
+    if (isTemplateName(S, SS ? *SS : EmptySS, Name, 0, true, TemplateResult)
+        == TNK_Type_template) {
+      TemplateName TplName = TemplateResult.getAsVal<TemplateName>();
+      Diag(IILoc, diag::err_template_missing_args) << TplName;
+      if (TemplateDecl *TplDecl = TplName.getAsTemplateDecl()) {
+        Diag(TplDecl->getLocation(), diag::note_template_decl_here)
+          << TplDecl->getTemplateParameters()->getSourceRange();
+      }
+      return true;
+    }
+  }
+
+  // FIXME: Should we move the logic that tries to recover from a missing tag
+  // (struct, union, enum) from Parser::ParseImplicitInt here, instead?
+  
+  if (!SS || (!SS->isSet() && !SS->isInvalid()))
+    Diag(IILoc, diag::err_unknown_typename) << &II;
+  else if (DeclContext *DC = computeDeclContext(*SS, false))
+    Diag(IILoc, diag::err_typename_nested_not_found) 
+      << &II << DC << SS->getRange();
+  else if (isDependentScopeSpecifier(*SS)) {
+    Diag(SS->getRange().getBegin(), diag::err_typename_missing)
+      << (NestedNameSpecifier *)SS->getScopeRep() << II.getName()
+      << SourceRange(SS->getRange().getBegin(), IILoc)
+      << FixItHint::CreateInsertion(SS->getRange().getBegin(), "typename ");
+    SuggestedType = ActOnTypenameType(SourceLocation(), *SS, II, IILoc).get();
+  } else {
+    assert(SS && SS->isInvalid() && 
+           "Invalid scope specifier has already been diagnosed");
+  }
+  
+  return true;
+}
+
+// Determines the context to return to after temporarily entering a
+// context.  This depends in an unnecessarily complicated way on the
+// exact ordering of callbacks from the parser.
+DeclContext *Sema::getContainingDC(DeclContext *DC) {
+
+  // Functions defined inline within classes aren't parsed until we've
+  // finished parsing the top-level class, so the top-level class is
+  // the context we'll need to return to.
+  if (isa<FunctionDecl>(DC)) {
+    DC = DC->getLexicalParent();
+
+    // A function not defined within a class will always return to its
+    // lexical context.
+    if (!isa<CXXRecordDecl>(DC))
+      return DC;
+
+    // A C++ inline method/friend is parsed *after* the topmost class
+    // it was declared in is fully parsed ("complete");  the topmost
+    // class is the context we need to return to.
+    while (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(DC->getLexicalParent()))
+      DC = RD;
+
+    // Return the declaration context of the topmost class the inline method is
+    // declared in.
+    return DC;
+  }
+
+  if (isa<ObjCMethodDecl>(DC))
+    return Context.getTranslationUnitDecl();
+
+  return DC->getLexicalParent();
+}
+
+void Sema::PushDeclContext(Scope *S, DeclContext *DC) {
+  assert(getContainingDC(DC) == CurContext &&
+      "The next DeclContext should be lexically contained in the current one.");
+  CurContext = DC;
+  S->setEntity(DC);
+}
+
+void Sema::PopDeclContext() {
+  assert(CurContext && "DeclContext imbalance!");
+
+  CurContext = getContainingDC(CurContext);
+}
+
+/// EnterDeclaratorContext - Used when we must lookup names in the context
+/// of a declarator's nested name specifier.
+///
+void Sema::EnterDeclaratorContext(Scope *S, DeclContext *DC) {
+  // C++0x [basic.lookup.unqual]p13:
+  //   A name used in the definition of a static data member of class
+  //   X (after the qualified-id of the static member) is looked up as
+  //   if the name was used in a member function of X.
+  // C++0x [basic.lookup.unqual]p14:
+  //   If a variable member of a namespace is defined outside of the
+  //   scope of its namespace then any name used in the definition of
+  //   the variable member (after the declarator-id) is looked up as
+  //   if the definition of the variable member occurred in its
+  //   namespace.
+  // Both of these imply that we should push a scope whose context
+  // is the semantic context of the declaration.  We can't use
+  // PushDeclContext here because that context is not necessarily
+  // lexically contained in the current context.  Fortunately,
+  // the containing scope should have the appropriate information.
+
+  assert(!S->getEntity() && "scope already has entity");
+
+#ifndef NDEBUG
+  Scope *Ancestor = S->getParent();
+  while (!Ancestor->getEntity()) Ancestor = Ancestor->getParent();
+  assert(Ancestor->getEntity() == CurContext && "ancestor context mismatch");
+#endif
+
+  CurContext = DC;
+  S->setEntity(DC);
+}
+
+void Sema::ExitDeclaratorContext(Scope *S) {
+  assert(S->getEntity() == CurContext && "Context imbalance!");
+
+  // Switch back to the lexical context.  The safety of this is
+  // enforced by an assert in EnterDeclaratorContext.
+  Scope *Ancestor = S->getParent();
+  while (!Ancestor->getEntity()) Ancestor = Ancestor->getParent();
+  CurContext = (DeclContext*) Ancestor->getEntity();
+
+  // We don't need to do anything with the scope, which is going to
+  // disappear.
+}
+
+/// \brief Determine whether we allow overloading of the function
+/// PrevDecl with another declaration.
+///
+/// This routine determines whether overloading is possible, not
+/// whether some new function is actually an overload. It will return
+/// true in C++ (where we can always provide overloads) or, as an
+/// extension, in C when the previous function is already an
+/// overloaded function declaration or has the "overloadable"
+/// attribute.
+static bool AllowOverloadingOfFunction(LookupResult &Previous,
+                                       ASTContext &Context) {
+  if (Context.getLangOptions().CPlusPlus)
+    return true;
+
+  if (Previous.getResultKind() == LookupResult::FoundOverloaded)
+    return true;
+
+  return (Previous.getResultKind() == LookupResult::Found
+          && Previous.getFoundDecl()->hasAttr<OverloadableAttr>());
+}
+
+/// Add this decl to the scope shadowed decl chains.
+void Sema::PushOnScopeChains(NamedDecl *D, Scope *S, bool AddToContext) {
+  // Move up the scope chain until we find the nearest enclosing
+  // non-transparent context. The declaration will be introduced into this
+  // scope.
+  while (S->getEntity() &&
+         ((DeclContext *)S->getEntity())->isTransparentContext())
+    S = S->getParent();
+
+  // Add scoped declarations into their context, so that they can be
+  // found later. Declarations without a context won't be inserted
+  // into any context.
+  if (AddToContext)
+    CurContext->addDecl(D);
+
+  // Out-of-line definitions shouldn't be pushed into scope in C++.
+  // Out-of-line variable and function definitions shouldn't even in C.
+  if ((getLangOptions().CPlusPlus || isa<VarDecl>(D) || isa<FunctionDecl>(D)) &&
+      D->isOutOfLine())
+    return;
+
+  // Template instantiations should also not be pushed into scope.
+  if (isa<FunctionDecl>(D) &&
+      cast<FunctionDecl>(D)->isFunctionTemplateSpecialization())
+    return;
+
+  // If this replaces anything in the current scope, 
+  IdentifierResolver::iterator I = IdResolver.begin(D->getDeclName()),
+                               IEnd = IdResolver.end();
+  for (; I != IEnd; ++I) {
+    if (S->isDeclScope(DeclPtrTy::make(*I)) && D->declarationReplaces(*I)) {
+      S->RemoveDecl(DeclPtrTy::make(*I));
+      IdResolver.RemoveDecl(*I);
+
+      // Should only need to replace one decl.
+      break;
+    }
+  }
+
+  S->AddDecl(DeclPtrTy::make(D));
+  IdResolver.AddDecl(D);
+}
+
+bool Sema::isDeclInScope(NamedDecl *&D, DeclContext *Ctx, Scope *S) {
+  return IdResolver.isDeclInScope(D, Ctx, Context, S);
+}
+
+static bool isOutOfScopePreviousDeclaration(NamedDecl *,
+                                            DeclContext*,
+                                            ASTContext&);
+
+/// Filters out lookup results that don't fall within the given scope
+/// as determined by isDeclInScope.
+static void FilterLookupForScope(Sema &SemaRef, LookupResult &R,
+                                 DeclContext *Ctx, Scope *S,
+                                 bool ConsiderLinkage) {
+  LookupResult::Filter F = R.makeFilter();
+  while (F.hasNext()) {
+    NamedDecl *D = F.next();
+
+    if (SemaRef.isDeclInScope(D, Ctx, S))
+      continue;
+
+    if (ConsiderLinkage &&
+        isOutOfScopePreviousDeclaration(D, Ctx, SemaRef.Context))
+      continue;
+    
+    F.erase();
+  }
+
+  F.done();
+}
+
+static bool isUsingDecl(NamedDecl *D) {
+  return isa<UsingShadowDecl>(D) ||
+         isa<UnresolvedUsingTypenameDecl>(D) ||
+         isa<UnresolvedUsingValueDecl>(D);
+}
+
+/// Removes using shadow declarations from the lookup results.
+static void RemoveUsingDecls(LookupResult &R) {
+  LookupResult::Filter F = R.makeFilter();
+  while (F.hasNext())
+    if (isUsingDecl(F.next()))
+      F.erase();
+
+  F.done();
+}
+
+static bool ShouldDiagnoseUnusedDecl(const NamedDecl *D) {
+  if (D->isInvalidDecl())
+    return false;
+
+  if (D->isUsed() || D->hasAttr<UnusedAttr>())
+    return false;
+
+  // White-list anything that isn't a local variable.
+  if (!isa<VarDecl>(D) || isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D) ||
+      !D->getDeclContext()->isFunctionOrMethod())
+    return false;
+
+  // Types of valid local variables should be complete, so this should succeed.
+  if (const ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
+
+    // White-list anything with an __attribute__((unused)) type.
+    QualType Ty = VD->getType();
+
+    // Only look at the outermost level of typedef.
+    if (const TypedefType *TT = dyn_cast<TypedefType>(Ty)) {
+      if (TT->getDecl()->hasAttr<UnusedAttr>())
+        return false;
+    }
+
+    if (const TagType *TT = Ty->getAs<TagType>()) {
+      const TagDecl *Tag = TT->getDecl();
+      if (Tag->hasAttr<UnusedAttr>())
+        return false;
+
+      if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(Tag)) {
+        if (!RD->hasTrivialConstructor())
+          return false;
+        if (!RD->hasTrivialDestructor())
+          return false;
+      }
+    }
+
+    // TODO: __attribute__((unused)) templates?
+  }
+  
+  return true;
+}
+
+void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) {
+  if (S->decl_empty()) return;
+  assert((S->getFlags() & (Scope::DeclScope | Scope::TemplateParamScope)) &&
+         "Scope shouldn't contain decls!");
+
+  for (Scope::decl_iterator I = S->decl_begin(), E = S->decl_end();
+       I != E; ++I) {
+    Decl *TmpD = (*I).getAs<Decl>();
+    assert(TmpD && "This decl didn't get pushed??");
+
+    assert(isa<NamedDecl>(TmpD) && "Decl isn't NamedDecl?");
+    NamedDecl *D = cast<NamedDecl>(TmpD);
+
+    if (!D->getDeclName()) continue;
+
+    // Diagnose unused variables in this scope.
+    if (ShouldDiagnoseUnusedDecl(D) && 
+        S->getNumErrorsAtStart() == getDiagnostics().getNumErrors())
+      Diag(D->getLocation(), diag::warn_unused_variable) << D->getDeclName();
+    
+    // Remove this name from our lexical scope.
+    IdResolver.RemoveDecl(D);
+  }
+}
+
+/// \brief Look for an Objective-C class in the translation unit.
+///
+/// \param Id The name of the Objective-C class we're looking for. If
+/// typo-correction fixes this name, the Id will be updated
+/// to the fixed name.
+///
+/// \param IdLoc The location of the name in the translation unit.
+///
+/// \param TypoCorrection If true, this routine will attempt typo correction
+/// if there is no class with the given name.
+///
+/// \returns The declaration of the named Objective-C class, or NULL if the
+/// class could not be found.
+ObjCInterfaceDecl *Sema::getObjCInterfaceDecl(IdentifierInfo *&Id,
+                                              SourceLocation IdLoc,
+                                              bool TypoCorrection) {
+  // The third "scope" argument is 0 since we aren't enabling lazy built-in
+  // creation from this context.
+  NamedDecl *IDecl = LookupSingleName(TUScope, Id, IdLoc, LookupOrdinaryName);
+
+  if (!IDecl && TypoCorrection) {
+    // Perform typo correction at the given location, but only if we
+    // find an Objective-C class name.
+    LookupResult R(*this, Id, IdLoc, LookupOrdinaryName);
+    if (CorrectTypo(R, TUScope, 0, 0, false, CTC_NoKeywords) &&
+        (IDecl = R.getAsSingle<ObjCInterfaceDecl>())) {
+      Diag(IdLoc, diag::err_undef_interface_suggest)
+        << Id << IDecl->getDeclName() 
+        << FixItHint::CreateReplacement(IdLoc, IDecl->getNameAsString());
+      Diag(IDecl->getLocation(), diag::note_previous_decl)
+        << IDecl->getDeclName();
+      
+      Id = IDecl->getIdentifier();
+    }
+  }
+
+  return dyn_cast_or_null<ObjCInterfaceDecl>(IDecl);
+}
+
+/// getNonFieldDeclScope - Retrieves the innermost scope, starting
+/// from S, where a non-field would be declared. This routine copes
+/// with the difference between C and C++ scoping rules in structs and
+/// unions. For example, the following code is well-formed in C but
+/// ill-formed in C++:
+/// @code
+/// struct S6 {
+///   enum { BAR } e;
+/// };
+///
+/// void test_S6() {
+///   struct S6 a;
+///   a.e = BAR;
+/// }
+/// @endcode
+/// For the declaration of BAR, this routine will return a different
+/// scope. The scope S will be the scope of the unnamed enumeration
+/// within S6. In C++, this routine will return the scope associated
+/// with S6, because the enumeration's scope is a transparent
+/// context but structures can contain non-field names. In C, this
+/// routine will return the translation unit scope, since the
+/// enumeration's scope is a transparent context and structures cannot
+/// contain non-field names.
+Scope *Sema::getNonFieldDeclScope(Scope *S) {
+  while (((S->getFlags() & Scope::DeclScope) == 0) ||
+         (S->getEntity() &&
+          ((DeclContext *)S->getEntity())->isTransparentContext()) ||
+         (S->isClassScope() && !getLangOptions().CPlusPlus))
+    S = S->getParent();
+  return S;
+}
+
+void Sema::InitBuiltinVaListType() {
+  if (!Context.getBuiltinVaListType().isNull())
+    return;
+
+  IdentifierInfo *VaIdent = &Context.Idents.get("__builtin_va_list");
+  NamedDecl *VaDecl = LookupSingleName(TUScope, VaIdent, SourceLocation(),
+                                       LookupOrdinaryName, ForRedeclaration);
+  TypedefDecl *VaTypedef = cast<TypedefDecl>(VaDecl);
+  Context.setBuiltinVaListType(Context.getTypedefType(VaTypedef));
+}
+
+/// LazilyCreateBuiltin - The specified Builtin-ID was first used at
+/// file scope.  lazily create a decl for it. ForRedeclaration is true
+/// if we're creating this built-in in anticipation of redeclaring the
+/// built-in.
+NamedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned bid,
+                                     Scope *S, bool ForRedeclaration,
+                                     SourceLocation Loc) {
+  Builtin::ID BID = (Builtin::ID)bid;
+
+  if (Context.BuiltinInfo.hasVAListUse(BID))
+    InitBuiltinVaListType();
+
+  ASTContext::GetBuiltinTypeError Error;
+  QualType R = Context.GetBuiltinType(BID, Error);
+  switch (Error) {
+  case ASTContext::GE_None:
+    // Okay
+    break;
+
+  case ASTContext::GE_Missing_stdio:
+    if (ForRedeclaration)
+      Diag(Loc, diag::err_implicit_decl_requires_stdio)
+        << Context.BuiltinInfo.GetName(BID);
+    return 0;
+
+  case ASTContext::GE_Missing_setjmp:
+    if (ForRedeclaration)
+      Diag(Loc, diag::err_implicit_decl_requires_setjmp)
+        << Context.BuiltinInfo.GetName(BID);
+    return 0;
+  }
+
+  if (!ForRedeclaration && Context.BuiltinInfo.isPredefinedLibFunction(BID)) {
+    Diag(Loc, diag::ext_implicit_lib_function_decl)
+      << Context.BuiltinInfo.GetName(BID)
+      << R;
+    if (Context.BuiltinInfo.getHeaderName(BID) &&
+        Diags.getDiagnosticLevel(diag::ext_implicit_lib_function_decl)
+          != Diagnostic::Ignored)
+      Diag(Loc, diag::note_please_include_header)
+        << Context.BuiltinInfo.getHeaderName(BID)
+        << Context.BuiltinInfo.GetName(BID);
+  }
+
+  FunctionDecl *New = FunctionDecl::Create(Context,
+                                           Context.getTranslationUnitDecl(),
+                                           Loc, II, R, /*TInfo=*/0,
+                                           FunctionDecl::Extern,
+                                           FunctionDecl::None, false,
+                                           /*hasPrototype=*/true);
+  New->setImplicit();
+
+  // Create Decl objects for each parameter, adding them to the
+  // FunctionDecl.
+  if (FunctionProtoType *FT = dyn_cast<FunctionProtoType>(R)) {
+    llvm::SmallVector<ParmVarDecl*, 16> Params;
+    for (unsigned i = 0, e = FT->getNumArgs(); i != e; ++i)
+      Params.push_back(ParmVarDecl::Create(Context, New, SourceLocation(), 0,
+                                           FT->getArgType(i), /*TInfo=*/0,
+                                           VarDecl::None, VarDecl::None, 0));
+    New->setParams(Params.data(), Params.size());
+  }
+
+  AddKnownFunctionAttributes(New);
+
+  // TUScope is the translation-unit scope to insert this function into.
+  // FIXME: This is hideous. We need to teach PushOnScopeChains to
+  // relate Scopes to DeclContexts, and probably eliminate CurContext
+  // entirely, but we're not there yet.
+  DeclContext *SavedContext = CurContext;
+  CurContext = Context.getTranslationUnitDecl();
+  PushOnScopeChains(New, TUScope);
+  CurContext = SavedContext;
+  return New;
+}
+
+/// MergeTypeDefDecl - We just parsed a typedef 'New' which has the
+/// same name and scope as a previous declaration 'Old'.  Figure out
+/// how to resolve this situation, merging decls or emitting
+/// diagnostics as appropriate. If there was an error, set New to be invalid.
+///
+void Sema::MergeTypeDefDecl(TypedefDecl *New, LookupResult &OldDecls) {
+  // If the new decl is known invalid already, don't bother doing any
+  // merging checks.
+  if (New->isInvalidDecl()) return;
+
+  // Allow multiple definitions for ObjC built-in typedefs.
+  // FIXME: Verify the underlying types are equivalent!
+  if (getLangOptions().ObjC1) {
+    const IdentifierInfo *TypeID = New->getIdentifier();
+    switch (TypeID->getLength()) {
+    default: break;
+    case 2:
+      if (!TypeID->isStr("id"))
+        break;
+      Context.ObjCIdRedefinitionType = New->getUnderlyingType();
+      // Install the built-in type for 'id', ignoring the current definition.
+      New->setTypeForDecl(Context.getObjCIdType().getTypePtr());
+      return;
+    case 5:
+      if (!TypeID->isStr("Class"))
+        break;
+      Context.ObjCClassRedefinitionType = New->getUnderlyingType();
+      // Install the built-in type for 'Class', ignoring the current definition.
+      New->setTypeForDecl(Context.getObjCClassType().getTypePtr());
+      return;
+    case 3:
+      if (!TypeID->isStr("SEL"))
+        break;
+      Context.ObjCSelRedefinitionType = New->getUnderlyingType();
+      // Install the built-in type for 'SEL', ignoring the current definition.
+      New->setTypeForDecl(Context.getObjCSelType().getTypePtr());
+      return;
+    case 8:
+      if (!TypeID->isStr("Protocol"))
+        break;
+      Context.setObjCProtoType(New->getUnderlyingType());
+      return;
+    }
+    // Fall through - the typedef name was not a builtin type.
+  }
+
+  // Verify the old decl was also a type.
+  TypeDecl *Old = OldDecls.getAsSingle<TypeDecl>();
+  if (!Old) {
+    Diag(New->getLocation(), diag::err_redefinition_different_kind)
+      << New->getDeclName();
+
+    NamedDecl *OldD = OldDecls.getRepresentativeDecl();
+    if (OldD->getLocation().isValid())
+      Diag(OldD->getLocation(), diag::note_previous_definition);
+
+    return New->setInvalidDecl();
+  }
+
+  // If the old declaration is invalid, just give up here.
+  if (Old->isInvalidDecl())
+    return New->setInvalidDecl();
+
+  // Determine the "old" type we'll use for checking and diagnostics.
+  QualType OldType;
+  if (TypedefDecl *OldTypedef = dyn_cast<TypedefDecl>(Old))
+    OldType = OldTypedef->getUnderlyingType();
+  else
+    OldType = Context.getTypeDeclType(Old);
+
+  // If the typedef types are not identical, reject them in all languages and
+  // with any extensions enabled.
+
+  if (OldType != New->getUnderlyingType() &&
+      Context.getCanonicalType(OldType) !=
+      Context.getCanonicalType(New->getUnderlyingType())) {
+    Diag(New->getLocation(), diag::err_redefinition_different_typedef)
+      << New->getUnderlyingType() << OldType;
+    if (Old->getLocation().isValid())
+      Diag(Old->getLocation(), diag::note_previous_definition);
+    return New->setInvalidDecl();
+  }
+
+  // The types match.  Link up the redeclaration chain if the old
+  // declaration was a typedef.
+  // FIXME: this is a potential source of wierdness if the type
+  // spellings don't match exactly.
+  if (isa<TypedefDecl>(Old))
+    New->setPreviousDeclaration(cast<TypedefDecl>(Old));
+
+  if (getLangOptions().Microsoft)
+    return;
+
+  if (getLangOptions().CPlusPlus) {
+    // C++ [dcl.typedef]p2:
+    //   In a given non-class scope, a typedef specifier can be used to
+    //   redefine the name of any type declared in that scope to refer
+    //   to the type to which it already refers.
+    if (!isa<CXXRecordDecl>(CurContext))
+      return;
+
+    // C++0x [dcl.typedef]p4:
+    //   In a given class scope, a typedef specifier can be used to redefine 
+    //   any class-name declared in that scope that is not also a typedef-name
+    //   to refer to the type to which it already refers.
+    //
+    // This wording came in via DR424, which was a correction to the
+    // wording in DR56, which accidentally banned code like:
+    //
+    //   struct S {
+    //     typedef struct A { } A;
+    //   };
+    //
+    // in the C++03 standard. We implement the C++0x semantics, which
+    // allow the above but disallow
+    //
+    //   struct S {
+    //     typedef int I;
+    //     typedef int I;
+    //   };
+    //
+    // since that was the intent of DR56.
+    if (!isa<TypedefDecl >(Old))
+      return;
+
+    Diag(New->getLocation(), diag::err_redefinition)
+      << New->getDeclName();
+    Diag(Old->getLocation(), diag::note_previous_definition);
+    return New->setInvalidDecl();
+  }
+
+  // If we have a redefinition of a typedef in C, emit a warning.  This warning
+  // is normally mapped to an error, but can be controlled with
+  // -Wtypedef-redefinition.  If either the original or the redefinition is
+  // in a system header, don't emit this for compatibility with GCC.
+  if (getDiagnostics().getSuppressSystemWarnings() &&
+      (Context.getSourceManager().isInSystemHeader(Old->getLocation()) ||
+       Context.getSourceManager().isInSystemHeader(New->getLocation())))
+    return;
+
+  Diag(New->getLocation(), diag::warn_redefinition_of_typedef)
+    << New->getDeclName();
+  Diag(Old->getLocation(), diag::note_previous_definition);
+  return;
+}
+
+/// DeclhasAttr - returns true if decl Declaration already has the target
+/// attribute.
+static bool
+DeclHasAttr(const Decl *decl, const Attr *target) {
+  for (const Attr *attr = decl->getAttrs(); attr; attr = attr->getNext())
+    if (attr->getKind() == target->getKind())
+      return true;
+
+  return false;
+}
+
+/// MergeAttributes - append attributes from the Old decl to the New one.
+static void MergeAttributes(Decl *New, Decl *Old, ASTContext &C) {
+  for (const Attr *attr = Old->getAttrs(); attr; attr = attr->getNext()) {
+    if (!DeclHasAttr(New, attr) && attr->isMerged()) {
+      Attr *NewAttr = attr->clone(C);
+      NewAttr->setInherited(true);
+      New->addAttr(NewAttr);
+    }
+  }
+}
+
+/// Used in MergeFunctionDecl to keep track of function parameters in
+/// C.
+struct GNUCompatibleParamWarning {
+  ParmVarDecl *OldParm;
+  ParmVarDecl *NewParm;
+  QualType PromotedType;
+};
+
+
+/// getSpecialMember - get the special member enum for a method.
+Sema::CXXSpecialMember Sema::getSpecialMember(const CXXMethodDecl *MD) {
+  if (const CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(MD)) {
+    if (Ctor->isCopyConstructor())
+      return Sema::CXXCopyConstructor;
+    
+    return Sema::CXXConstructor;
+  } 
+  
+  if (isa<CXXDestructorDecl>(MD))
+    return Sema::CXXDestructor;
+  
+  assert(MD->isCopyAssignment() && "Must have copy assignment operator");
+  return Sema::CXXCopyAssignment;
+}
+
+/// canREdefineFunction - checks if a function can be redefined. Currently,
+/// only extern inline functions can be redefined, and even then only in
+/// GNU89 mode.
+static bool canRedefineFunction(const FunctionDecl *FD,
+                                const LangOptions& LangOpts) {
+  return (LangOpts.GNUMode && !LangOpts.C99 && !LangOpts.CPlusPlus &&
+          FD->isInlineSpecified() &&
+          FD->getStorageClass() == FunctionDecl::Extern);
+}
+
+/// MergeFunctionDecl - We just parsed a function 'New' from
+/// declarator D which has the same name and scope as a previous
+/// declaration 'Old'.  Figure out how to resolve this situation,
+/// merging decls or emitting diagnostics as appropriate.
+///
+/// In C++, New and Old must be declarations that are not
+/// overloaded. Use IsOverload to determine whether New and Old are
+/// overloaded, and to select the Old declaration that New should be
+/// merged with.
+///
+/// Returns true if there was an error, false otherwise.
+bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD) {
+  // Verify the old decl was also a function.
+  FunctionDecl *Old = 0;
+  if (FunctionTemplateDecl *OldFunctionTemplate
+        = dyn_cast<FunctionTemplateDecl>(OldD))
+    Old = OldFunctionTemplate->getTemplatedDecl();
+  else
+    Old = dyn_cast<FunctionDecl>(OldD);
+  if (!Old) {
+    if (UsingShadowDecl *Shadow = dyn_cast<UsingShadowDecl>(OldD)) {
+      Diag(New->getLocation(), diag::err_using_decl_conflict_reverse);
+      Diag(Shadow->getTargetDecl()->getLocation(),
+           diag::note_using_decl_target);
+      Diag(Shadow->getUsingDecl()->getLocation(),
+           diag::note_using_decl) << 0;
+      return true;
+    }
+
+    Diag(New->getLocation(), diag::err_redefinition_different_kind)
+      << New->getDeclName();
+    Diag(OldD->getLocation(), diag::note_previous_definition);
+    return true;
+  }
+
+  // Determine whether the previous declaration was a definition,
+  // implicit declaration, or a declaration.
+  diag::kind PrevDiag;
+  if (Old->isThisDeclarationADefinition())
+    PrevDiag = diag::note_previous_definition;
+  else if (Old->isImplicit())
+    PrevDiag = diag::note_previous_implicit_declaration;
+  else
+    PrevDiag = diag::note_previous_declaration;
+
+  QualType OldQType = Context.getCanonicalType(Old->getType());
+  QualType NewQType = Context.getCanonicalType(New->getType());
+
+  // Don't complain about this if we're in GNU89 mode and the old function
+  // is an extern inline function.
+  if (!isa<CXXMethodDecl>(New) && !isa<CXXMethodDecl>(Old) &&
+      New->getStorageClass() == FunctionDecl::Static &&
+      Old->getStorageClass() != FunctionDecl::Static &&
+      !canRedefineFunction(Old, getLangOptions())) {
+    Diag(New->getLocation(), diag::err_static_non_static)
+      << New;
+    Diag(Old->getLocation(), PrevDiag);
+    return true;
+  }
+
+  // If a function is first declared with a calling convention, but is
+  // later declared or defined without one, the second decl assumes the
+  // calling convention of the first.
+  //
+  // For the new decl, we have to look at the NON-canonical type to tell the
+  // difference between a function that really doesn't have a calling
+  // convention and one that is declared cdecl. That's because in
+  // canonicalization (see ASTContext.cpp), cdecl is canonicalized away
+  // because it is the default calling convention.
+  //
+  // Note also that we DO NOT return at this point, because we still have
+  // other tests to run.
+  const FunctionType *OldType = OldQType->getAs<FunctionType>();
+  const FunctionType *NewType = New->getType()->getAs<FunctionType>();
+  const FunctionType::ExtInfo OldTypeInfo = OldType->getExtInfo();
+  const FunctionType::ExtInfo NewTypeInfo = NewType->getExtInfo();
+  if (OldTypeInfo.getCC() != CC_Default &&
+      NewTypeInfo.getCC() == CC_Default) {
+    NewQType = Context.getCallConvType(NewQType, OldTypeInfo.getCC());
+    New->setType(NewQType);
+    NewQType = Context.getCanonicalType(NewQType);
+  } else if (!Context.isSameCallConv(OldTypeInfo.getCC(),
+                                     NewTypeInfo.getCC())) {
+    // Calling conventions really aren't compatible, so complain.
+    Diag(New->getLocation(), diag::err_cconv_change)
+      << FunctionType::getNameForCallConv(NewTypeInfo.getCC())
+      << (OldTypeInfo.getCC() == CC_Default)
+      << (OldTypeInfo.getCC() == CC_Default ? "" :
+          FunctionType::getNameForCallConv(OldTypeInfo.getCC()));
+    Diag(Old->getLocation(), diag::note_previous_declaration);
+    return true;
+  }
+
+  // FIXME: diagnose the other way around?
+  if (OldType->getNoReturnAttr() &&
+      !NewType->getNoReturnAttr()) {
+    NewQType = Context.getNoReturnType(NewQType);
+    New->setType(NewQType);
+    assert(NewQType.isCanonical());
+  }
+
+  if (getLangOptions().CPlusPlus) {
+    // (C++98 13.1p2):
+    //   Certain function declarations cannot be overloaded:
+    //     -- Function declarations that differ only in the return type
+    //        cannot be overloaded.
+    QualType OldReturnType
+      = cast<FunctionType>(OldQType.getTypePtr())->getResultType();
+    QualType NewReturnType
+      = cast<FunctionType>(NewQType.getTypePtr())->getResultType();
+    if (OldReturnType != NewReturnType) {
+      Diag(New->getLocation(), diag::err_ovl_diff_return_type);
+      Diag(Old->getLocation(), PrevDiag) << Old << Old->getType();
+      return true;
+    }
+
+    const CXXMethodDecl* OldMethod = dyn_cast<CXXMethodDecl>(Old);
+    CXXMethodDecl* NewMethod = dyn_cast<CXXMethodDecl>(New);
+    if (OldMethod && NewMethod) {
+      // Preserve triviality.
+      NewMethod->setTrivial(OldMethod->isTrivial());
+
+      bool isFriend = NewMethod->getFriendObjectKind();
+
+      if (!isFriend && NewMethod->getLexicalDeclContext()->isRecord()) {
+        //    -- Member function declarations with the same name and the
+        //       same parameter types cannot be overloaded if any of them
+        //       is a static member function declaration.
+        if (OldMethod->isStatic() || NewMethod->isStatic()) {
+          Diag(New->getLocation(), diag::err_ovl_static_nonstatic_member);
+          Diag(Old->getLocation(), PrevDiag) << Old << Old->getType();
+          return true;
+        }
+      
+        // C++ [class.mem]p1:
+        //   [...] A member shall not be declared twice in the
+        //   member-specification, except that a nested class or member
+        //   class template can be declared and then later defined.
+        unsigned NewDiag;
+        if (isa<CXXConstructorDecl>(OldMethod))
+          NewDiag = diag::err_constructor_redeclared;
+        else if (isa<CXXDestructorDecl>(NewMethod))
+          NewDiag = diag::err_destructor_redeclared;
+        else if (isa<CXXConversionDecl>(NewMethod))
+          NewDiag = diag::err_conv_function_redeclared;
+        else
+          NewDiag = diag::err_member_redeclared;
+
+        Diag(New->getLocation(), NewDiag);
+        Diag(Old->getLocation(), PrevDiag) << Old << Old->getType();
+
+      // Complain if this is an explicit declaration of a special
+      // member that was initially declared implicitly.
+      //
+      // As an exception, it's okay to befriend such methods in order
+      // to permit the implicit constructor/destructor/operator calls.
+      } else if (OldMethod->isImplicit()) {
+        if (isFriend) {
+          NewMethod->setImplicit();
+        } else {
+          Diag(NewMethod->getLocation(),
+               diag::err_definition_of_implicitly_declared_member) 
+            << New << getSpecialMember(OldMethod);
+          return true;
+        }
+      }
+    }
+
+    // (C++98 8.3.5p3):
+    //   All declarations for a function shall agree exactly in both the
+    //   return type and the parameter-type-list.
+    // attributes should be ignored when comparing.
+    if (Context.getNoReturnType(OldQType, false) ==
+        Context.getNoReturnType(NewQType, false))
+      return MergeCompatibleFunctionDecls(New, Old);
+
+    // Fall through for conflicting redeclarations and redefinitions.
+  }
+
+  // C: Function types need to be compatible, not identical. This handles
+  // duplicate function decls like "void f(int); void f(enum X);" properly.
+  if (!getLangOptions().CPlusPlus &&
+      Context.typesAreCompatible(OldQType, NewQType)) {
+    const FunctionType *OldFuncType = OldQType->getAs<FunctionType>();
+    const FunctionType *NewFuncType = NewQType->getAs<FunctionType>();
+    const FunctionProtoType *OldProto = 0;
+    if (isa<FunctionNoProtoType>(NewFuncType) &&
+        (OldProto = dyn_cast<FunctionProtoType>(OldFuncType))) {
+      // The old declaration provided a function prototype, but the
+      // new declaration does not. Merge in the prototype.
+      assert(!OldProto->hasExceptionSpec() && "Exception spec in C");
+      llvm::SmallVector<QualType, 16> ParamTypes(OldProto->arg_type_begin(),
+                                                 OldProto->arg_type_end());
+      NewQType = Context.getFunctionType(NewFuncType->getResultType(),
+                                         ParamTypes.data(), ParamTypes.size(),
+                                         OldProto->isVariadic(),
+                                         OldProto->getTypeQuals(),
+                                         false, false, 0, 0,
+                                         OldProto->getExtInfo());
+      New->setType(NewQType);
+      New->setHasInheritedPrototype();
+
+      // Synthesize a parameter for each argument type.
+      llvm::SmallVector<ParmVarDecl*, 16> Params;
+      for (FunctionProtoType::arg_type_iterator
+             ParamType = OldProto->arg_type_begin(),
+             ParamEnd = OldProto->arg_type_end();
+           ParamType != ParamEnd; ++ParamType) {
+        ParmVarDecl *Param = ParmVarDecl::Create(Context, New,
+                                                 SourceLocation(), 0,
+                                                 *ParamType, /*TInfo=*/0,
+                                                 VarDecl::None, VarDecl::None,
+                                                 0);
+        Param->setImplicit();
+        Params.push_back(Param);
+      }
+
+      New->setParams(Params.data(), Params.size());
+    }
+
+    return MergeCompatibleFunctionDecls(New, Old);
+  }
+
+  // GNU C permits a K&R definition to follow a prototype declaration
+  // if the declared types of the parameters in the K&R definition
+  // match the types in the prototype declaration, even when the
+  // promoted types of the parameters from the K&R definition differ
+  // from the types in the prototype. GCC then keeps the types from
+  // the prototype.
+  //
+  // If a variadic prototype is followed by a non-variadic K&R definition,
+  // the K&R definition becomes variadic.  This is sort of an edge case, but
+  // it's legal per the standard depending on how you read C99 6.7.5.3p15 and
+  // C99 6.9.1p8.
+  if (!getLangOptions().CPlusPlus &&
+      Old->hasPrototype() && !New->hasPrototype() &&
+      New->getType()->getAs<FunctionProtoType>() &&
+      Old->getNumParams() == New->getNumParams()) {
+    llvm::SmallVector<QualType, 16> ArgTypes;
+    llvm::SmallVector<GNUCompatibleParamWarning, 16> Warnings;
+    const FunctionProtoType *OldProto
+      = Old->getType()->getAs<FunctionProtoType>();
+    const FunctionProtoType *NewProto
+      = New->getType()->getAs<FunctionProtoType>();
+
+    // Determine whether this is the GNU C extension.
+    QualType MergedReturn = Context.mergeTypes(OldProto->getResultType(),
+                                               NewProto->getResultType());
+    bool LooseCompatible = !MergedReturn.isNull();
+    for (unsigned Idx = 0, End = Old->getNumParams();
+         LooseCompatible && Idx != End; ++Idx) {
+      ParmVarDecl *OldParm = Old->getParamDecl(Idx);
+      ParmVarDecl *NewParm = New->getParamDecl(Idx);
+      if (Context.typesAreCompatible(OldParm->getType(),
+                                     NewProto->getArgType(Idx))) {
+        ArgTypes.push_back(NewParm->getType());
+      } else if (Context.typesAreCompatible(OldParm->getType(),
+                                            NewParm->getType())) {
+        GNUCompatibleParamWarning Warn
+          = { OldParm, NewParm, NewProto->getArgType(Idx) };
+        Warnings.push_back(Warn);
+        ArgTypes.push_back(NewParm->getType());
+      } else
+        LooseCompatible = false;
+    }
+
+    if (LooseCompatible) {
+      for (unsigned Warn = 0; Warn < Warnings.size(); ++Warn) {
+        Diag(Warnings[Warn].NewParm->getLocation(),
+             diag::ext_param_promoted_not_compatible_with_prototype)
+          << Warnings[Warn].PromotedType
+          << Warnings[Warn].OldParm->getType();
+        Diag(Warnings[Warn].OldParm->getLocation(),
+             diag::note_previous_declaration);
+      }
+
+      New->setType(Context.getFunctionType(MergedReturn, &ArgTypes[0],
+                                           ArgTypes.size(),
+                                           OldProto->isVariadic(), 0,
+                                           false, false, 0, 0,
+                                           OldProto->getExtInfo()));
+      return MergeCompatibleFunctionDecls(New, Old);
+    }
+
+    // Fall through to diagnose conflicting types.
+  }
+
+  // A function that has already been declared has been redeclared or defined
+  // with a different type- show appropriate diagnostic
+  if (unsigned BuiltinID = Old->getBuiltinID()) {
+    // The user has declared a builtin function with an incompatible
+    // signature.
+    if (Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID)) {
+      // The function the user is redeclaring is a library-defined
+      // function like 'malloc' or 'printf'. Warn about the
+      // redeclaration, then pretend that we don't know about this
+      // library built-in.
+      Diag(New->getLocation(), diag::warn_redecl_library_builtin) << New;
+      Diag(Old->getLocation(), diag::note_previous_builtin_declaration)
+        << Old << Old->getType();
+      New->getIdentifier()->setBuiltinID(Builtin::NotBuiltin);
+      Old->setInvalidDecl();
+      return false;
+    }
+
+    PrevDiag = diag::note_previous_builtin_declaration;
+  }
+
+  Diag(New->getLocation(), diag::err_conflicting_types) << New->getDeclName();
+  Diag(Old->getLocation(), PrevDiag) << Old << Old->getType();
+  return true;
+}
+
+/// \brief Completes the merge of two function declarations that are
+/// known to be compatible.
+///
+/// This routine handles the merging of attributes and other
+/// properties of function declarations form the old declaration to
+/// the new declaration, once we know that New is in fact a
+/// redeclaration of Old.
+///
+/// \returns false
+bool Sema::MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old) {
+  // Merge the attributes
+  MergeAttributes(New, Old, Context);
+
+  // Merge the storage class.
+  if (Old->getStorageClass() != FunctionDecl::Extern &&
+      Old->getStorageClass() != FunctionDecl::None)
+    New->setStorageClass(Old->getStorageClass());
+
+  // Merge "pure" flag.
+  if (Old->isPure())
+    New->setPure();
+
+  // Merge the "deleted" flag.
+  if (Old->isDeleted())
+    New->setDeleted();
+
+  if (getLangOptions().CPlusPlus)
+    return MergeCXXFunctionDecl(New, Old);
+
+  return false;
+}
+
+/// MergeVarDecl - We just parsed a variable 'New' which has the same name
+/// and scope as a previous declaration 'Old'.  Figure out how to resolve this
+/// situation, merging decls or emitting diagnostics as appropriate.
+///
+/// Tentative definition rules (C99 6.9.2p2) are checked by
+/// FinalizeDeclaratorGroup. Unfortunately, we can't analyze tentative
+/// definitions here, since the initializer hasn't been attached.
+///
+void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {
+  // If the new decl is already invalid, don't do any other checking.
+  if (New->isInvalidDecl())
+    return;
+
+  // Verify the old decl was also a variable.
+  VarDecl *Old = 0;
+  if (!Previous.isSingleResult() ||
+      !(Old = dyn_cast<VarDecl>(Previous.getFoundDecl()))) {
+    Diag(New->getLocation(), diag::err_redefinition_different_kind)
+      << New->getDeclName();
+    Diag(Previous.getRepresentativeDecl()->getLocation(),
+         diag::note_previous_definition);
+    return New->setInvalidDecl();
+  }
+
+  MergeAttributes(New, Old, Context);
+
+  // Merge the types
+  QualType MergedT;
+  if (getLangOptions().CPlusPlus) {
+    if (Context.hasSameType(New->getType(), Old->getType()))
+      MergedT = New->getType();
+    // C++ [basic.link]p10:
+    //   [...] the types specified by all declarations referring to a given
+    //   object or function shall be identical, except that declarations for an
+    //   array object can specify array types that differ by the presence or
+    //   absence of a major array bound (8.3.4).
+    else if (Old->getType()->isIncompleteArrayType() &&
+             New->getType()->isArrayType()) {
+      CanQual<ArrayType> OldArray
+        = Context.getCanonicalType(Old->getType())->getAs<ArrayType>();
+      CanQual<ArrayType> NewArray
+        = Context.getCanonicalType(New->getType())->getAs<ArrayType>();
+      if (OldArray->getElementType() == NewArray->getElementType())
+        MergedT = New->getType();
+    } else if (Old->getType()->isArrayType() &&
+             New->getType()->isIncompleteArrayType()) {
+      CanQual<ArrayType> OldArray
+        = Context.getCanonicalType(Old->getType())->getAs<ArrayType>();
+      CanQual<ArrayType> NewArray
+        = Context.getCanonicalType(New->getType())->getAs<ArrayType>();
+      if (OldArray->getElementType() == NewArray->getElementType())
+        MergedT = Old->getType();
+    }
+  } else {
+    MergedT = Context.mergeTypes(New->getType(), Old->getType());
+  }
+  if (MergedT.isNull()) {
+    Diag(New->getLocation(), diag::err_redefinition_different_type)
+      << New->getDeclName();
+    Diag(Old->getLocation(), diag::note_previous_definition);
+    return New->setInvalidDecl();
+  }
+  New->setType(MergedT);
+
+  // C99 6.2.2p4: Check if we have a static decl followed by a non-static.
+  if (New->getStorageClass() == VarDecl::Static &&
+      (Old->getStorageClass() == VarDecl::None || Old->hasExternalStorage())) {
+    Diag(New->getLocation(), diag::err_static_non_static) << New->getDeclName();
+    Diag(Old->getLocation(), diag::note_previous_definition);
+    return New->setInvalidDecl();
+  }
+  // C99 6.2.2p4:
+  //   For an identifier declared with the storage-class specifier
+  //   extern in a scope in which a prior declaration of that
+  //   identifier is visible,23) if the prior declaration specifies
+  //   internal or external linkage, the linkage of the identifier at
+  //   the later declaration is the same as the linkage specified at
+  //   the prior declaration. If no prior declaration is visible, or
+  //   if the prior declaration specifies no linkage, then the
+  //   identifier has external linkage.
+  if (New->hasExternalStorage() && Old->hasLinkage())
+    /* Okay */;
+  else if (New->getStorageClass() != VarDecl::Static &&
+           Old->getStorageClass() == VarDecl::Static) {
+    Diag(New->getLocation(), diag::err_non_static_static) << New->getDeclName();
+    Diag(Old->getLocation(), diag::note_previous_definition);
+    return New->setInvalidDecl();
+  }
+
+  // Variables with external linkage are analyzed in FinalizeDeclaratorGroup.
+
+  // FIXME: The test for external storage here seems wrong? We still
+  // need to check for mismatches.
+  if (!New->hasExternalStorage() && !New->isFileVarDecl() &&
+      // Don't complain about out-of-line definitions of static members.
+      !(Old->getLexicalDeclContext()->isRecord() &&
+        !New->getLexicalDeclContext()->isRecord())) {
+    Diag(New->getLocation(), diag::err_redefinition) << New->getDeclName();
+    Diag(Old->getLocation(), diag::note_previous_definition);
+    return New->setInvalidDecl();
+  }
+
+  if (New->isThreadSpecified() && !Old->isThreadSpecified()) {
+    Diag(New->getLocation(), diag::err_thread_non_thread) << New->getDeclName();
+    Diag(Old->getLocation(), diag::note_previous_definition);
+  } else if (!New->isThreadSpecified() && Old->isThreadSpecified()) {
+    Diag(New->getLocation(), diag::err_non_thread_thread) << New->getDeclName();
+    Diag(Old->getLocation(), diag::note_previous_definition);
+  }
+
+  // C++ doesn't have tentative definitions, so go right ahead and check here.
+  const VarDecl *Def;
+  if (getLangOptions().CPlusPlus &&
+      New->isThisDeclarationADefinition() == VarDecl::Definition &&
+      (Def = Old->getDefinition())) {
+    Diag(New->getLocation(), diag::err_redefinition)
+      << New->getDeclName();
+    Diag(Def->getLocation(), diag::note_previous_definition);
+    New->setInvalidDecl();
+    return;
+  }
+
+  // Keep a chain of previous declarations.
+  New->setPreviousDeclaration(Old);
+
+  // Inherit access appropriately.
+  New->setAccess(Old->getAccess());
+}
+
+/// ParsedFreeStandingDeclSpec - This method is invoked when a declspec with
+/// no declarator (e.g. "struct foo;") is parsed.
+Sema::DeclPtrTy Sema::ParsedFreeStandingDeclSpec(Scope *S, DeclSpec &DS) {
+  // FIXME: Error on auto/register at file scope
+  // FIXME: Error on inline/virtual/explicit
+  // FIXME: Warn on useless __thread
+  // FIXME: Warn on useless const/volatile
+  // FIXME: Warn on useless static/extern/typedef/private_extern/mutable
+  // FIXME: Warn on useless attributes
+  Decl *TagD = 0;
+  TagDecl *Tag = 0;
+  if (DS.getTypeSpecType() == DeclSpec::TST_class ||
+      DS.getTypeSpecType() == DeclSpec::TST_struct ||
+      DS.getTypeSpecType() == DeclSpec::TST_union ||
+      DS.getTypeSpecType() == DeclSpec::TST_enum) {
+    TagD = static_cast<Decl *>(DS.getTypeRep());
+
+    if (!TagD) // We probably had an error
+      return DeclPtrTy();
+
+    // Note that the above type specs guarantee that the
+    // type rep is a Decl, whereas in many of the others
+    // it's a Type.
+    Tag = dyn_cast<TagDecl>(TagD);
+  }
+
+  if (unsigned TypeQuals = DS.getTypeQualifiers()) {
+    // Enforce C99 6.7.3p2: "Types other than pointer types derived from object
+    // or incomplete types shall not be restrict-qualified."
+    if (TypeQuals & DeclSpec::TQ_restrict)
+      Diag(DS.getRestrictSpecLoc(),
+           diag::err_typecheck_invalid_restrict_not_pointer_noarg)
+           << DS.getSourceRange();
+  }
+
+  if (DS.isFriendSpecified()) {
+    // If we're dealing with a class template decl, assume that the
+    // template routines are handling it.
+    if (TagD && isa<ClassTemplateDecl>(TagD))
+      return DeclPtrTy();
+    return ActOnFriendTypeDecl(S, DS, MultiTemplateParamsArg(*this, 0, 0));
+  }
+         
+  if (RecordDecl *Record = dyn_cast_or_null<RecordDecl>(Tag)) {
+    // If there are attributes in the DeclSpec, apply them to the record.
+    if (const AttributeList *AL = DS.getAttributes())
+      ProcessDeclAttributeList(S, Record, AL);
+    
+    if (!Record->getDeclName() && Record->isDefinition() &&
+        DS.getStorageClassSpec() != DeclSpec::SCS_typedef) {
+      if (getLangOptions().CPlusPlus ||
+          Record->getDeclContext()->isRecord())
+        return BuildAnonymousStructOrUnion(S, DS, Record);
+
+      Diag(DS.getSourceRange().getBegin(), diag::ext_no_declarators)
+        << DS.getSourceRange();
+    }
+
+    // Microsoft allows unnamed struct/union fields. Don't complain
+    // about them.
+    // FIXME: Should we support Microsoft's extensions in this area?
+    if (Record->getDeclName() && getLangOptions().Microsoft)
+      return DeclPtrTy::make(Tag);
+  }
+  
+  if (!DS.isMissingDeclaratorOk() &&
+      DS.getTypeSpecType() != DeclSpec::TST_error) {
+    // Warn about typedefs of enums without names, since this is an
+    // extension in both Microsoft an GNU.
+    if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef &&
+        Tag && isa<EnumDecl>(Tag)) {
+      Diag(DS.getSourceRange().getBegin(), diag::ext_typedef_without_a_name)
+        << DS.getSourceRange();
+      return DeclPtrTy::make(Tag);
+    }
+
+    Diag(DS.getSourceRange().getBegin(), diag::ext_no_declarators)
+      << DS.getSourceRange();
+  }
+
+  return DeclPtrTy::make(Tag);
+}
+
+/// We are trying to inject an anonymous member into the given scope;
+/// check if there's an existing declaration that can't be overloaded.
+///
+/// \return true if this is a forbidden redeclaration
+static bool CheckAnonMemberRedeclaration(Sema &SemaRef,
+                                         Scope *S,
+                                         DeclContext *Owner,
+                                         DeclarationName Name,
+                                         SourceLocation NameLoc,
+                                         unsigned diagnostic) {
+  LookupResult R(SemaRef, Name, NameLoc, Sema::LookupMemberName,
+                 Sema::ForRedeclaration);
+  if (!SemaRef.LookupName(R, S)) return false;
+
+  if (R.getAsSingle<TagDecl>())
+    return false;
+
+  // Pick a representative declaration.
+  NamedDecl *PrevDecl = R.getRepresentativeDecl()->getUnderlyingDecl();
+  if (PrevDecl && Owner->isRecord()) {
+    RecordDecl *Record = cast<RecordDecl>(Owner);
+    if (!SemaRef.isDeclInScope(PrevDecl, Record, S))
+      return false;
+  }
+
+  SemaRef.Diag(NameLoc, diagnostic) << Name;
+  SemaRef.Diag(PrevDecl->getLocation(), diag::note_previous_declaration);
+
+  return true;
+}
+
+/// InjectAnonymousStructOrUnionMembers - Inject the members of the
+/// anonymous struct or union AnonRecord into the owning context Owner
+/// and scope S. This routine will be invoked just after we realize
+/// that an unnamed union or struct is actually an anonymous union or
+/// struct, e.g.,
+///
+/// @code
+/// union {
+///   int i;
+///   float f;
+/// }; // InjectAnonymousStructOrUnionMembers called here to inject i and
+///    // f into the surrounding scope.x
+/// @endcode
+///
+/// This routine is recursive, injecting the names of nested anonymous
+/// structs/unions into the owning context and scope as well.
+bool Sema::InjectAnonymousStructOrUnionMembers(Scope *S, DeclContext *Owner,
+                                               RecordDecl *AnonRecord) {
+  unsigned diagKind
+    = AnonRecord->isUnion() ? diag::err_anonymous_union_member_redecl
+                            : diag::err_anonymous_struct_member_redecl;
+
+  bool Invalid = false;
+  for (RecordDecl::field_iterator F = AnonRecord->field_begin(),
+                               FEnd = AnonRecord->field_end();
+       F != FEnd; ++F) {
+    if ((*F)->getDeclName()) {
+      if (CheckAnonMemberRedeclaration(*this, S, Owner, (*F)->getDeclName(),
+                                       (*F)->getLocation(), diagKind)) {
+        // C++ [class.union]p2:
+        //   The names of the members of an anonymous union shall be
+        //   distinct from the names of any other entity in the
+        //   scope in which the anonymous union is declared.
+        Invalid = true;
+      } else {
+        // C++ [class.union]p2:
+        //   For the purpose of name lookup, after the anonymous union
+        //   definition, the members of the anonymous union are
+        //   considered to have been defined in the scope in which the
+        //   anonymous union is declared.
+        Owner->makeDeclVisibleInContext(*F);
+        S->AddDecl(DeclPtrTy::make(*F));
+        IdResolver.AddDecl(*F);
+      }
+    } else if (const RecordType *InnerRecordType
+                 = (*F)->getType()->getAs<RecordType>()) {
+      RecordDecl *InnerRecord = InnerRecordType->getDecl();
+      if (InnerRecord->isAnonymousStructOrUnion())
+        Invalid = Invalid ||
+          InjectAnonymousStructOrUnionMembers(S, Owner, InnerRecord);
+    }
+  }
+
+  return Invalid;
+}
+
+/// StorageClassSpecToVarDeclStorageClass - Maps a DeclSpec::SCS to
+/// a VarDecl::StorageClass. Any error reporting is up to the caller:
+/// illegal input values are mapped to VarDecl::None.
+static VarDecl::StorageClass
+StorageClassSpecToVarDeclStorageClass(DeclSpec::SCS StorageClassSpec) {
+  switch (StorageClassSpec) {
+  case DeclSpec::SCS_unspecified:    return VarDecl::None;
+  case DeclSpec::SCS_extern:         return VarDecl::Extern;
+  case DeclSpec::SCS_static:         return VarDecl::Static;
+  case DeclSpec::SCS_auto:           return VarDecl::Auto;
+  case DeclSpec::SCS_register:       return VarDecl::Register;
+  case DeclSpec::SCS_private_extern: return VarDecl::PrivateExtern;
+    // Illegal SCSs map to None: error reporting is up to the caller.
+  case DeclSpec::SCS_mutable:        // Fall through.
+  case DeclSpec::SCS_typedef:        return VarDecl::None;
+  }
+  llvm_unreachable("unknown storage class specifier");
+}
+
+/// StorageClassSpecToFunctionDeclStorageClass - Maps a DeclSpec::SCS to
+/// a FunctionDecl::StorageClass. Any error reporting is up to the caller:
+/// illegal input values are mapped to FunctionDecl::None.
+static FunctionDecl::StorageClass
+StorageClassSpecToFunctionDeclStorageClass(DeclSpec::SCS StorageClassSpec) {
+  switch (StorageClassSpec) {
+  case DeclSpec::SCS_unspecified:    return FunctionDecl::None;
+  case DeclSpec::SCS_extern:         return FunctionDecl::Extern;
+  case DeclSpec::SCS_static:         return FunctionDecl::Static;
+  case DeclSpec::SCS_private_extern: return FunctionDecl::PrivateExtern;
+    // Illegal SCSs map to None: error reporting is up to the caller.
+  case DeclSpec::SCS_auto:           // Fall through.
+  case DeclSpec::SCS_mutable:        // Fall through.
+  case DeclSpec::SCS_register:       // Fall through.
+  case DeclSpec::SCS_typedef:        return FunctionDecl::None;
+  }
+  llvm_unreachable("unknown storage class specifier");
+}
+
+/// ActOnAnonymousStructOrUnion - Handle the declaration of an
+/// anonymous structure or union. Anonymous unions are a C++ feature
+/// (C++ [class.union]) and a GNU C extension; anonymous structures
+/// are a GNU C and GNU C++ extension.
+Sema::DeclPtrTy Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
+                                                  RecordDecl *Record) {
+  DeclContext *Owner = Record->getDeclContext();
+
+  // Diagnose whether this anonymous struct/union is an extension.
+  if (Record->isUnion() && !getLangOptions().CPlusPlus)
+    Diag(Record->getLocation(), diag::ext_anonymous_union);
+  else if (!Record->isUnion())
+    Diag(Record->getLocation(), diag::ext_anonymous_struct);
+
+  // C and C++ require different kinds of checks for anonymous
+  // structs/unions.
+  bool Invalid = false;
+  if (getLangOptions().CPlusPlus) {
+    const char* PrevSpec = 0;
+    unsigned DiagID;
+    // C++ [class.union]p3:
+    //   Anonymous unions declared in a named namespace or in the
+    //   global namespace shall be declared static.
+    if (DS.getStorageClassSpec() != DeclSpec::SCS_static &&
+        (isa<TranslationUnitDecl>(Owner) ||
+         (isa<NamespaceDecl>(Owner) &&
+          cast<NamespaceDecl>(Owner)->getDeclName()))) {
+      Diag(Record->getLocation(), diag::err_anonymous_union_not_static);
+      Invalid = true;
+
+      // Recover by adding 'static'.
+      DS.SetStorageClassSpec(DeclSpec::SCS_static, SourceLocation(),
+                             PrevSpec, DiagID);
+    }
+    // C++ [class.union]p3:
+    //   A storage class is not allowed in a declaration of an
+    //   anonymous union in a class scope.
+    else if (DS.getStorageClassSpec() != DeclSpec::SCS_unspecified &&
+             isa<RecordDecl>(Owner)) {
+      Diag(DS.getStorageClassSpecLoc(),
+           diag::err_anonymous_union_with_storage_spec);
+      Invalid = true;
+
+      // Recover by removing the storage specifier.
+      DS.SetStorageClassSpec(DeclSpec::SCS_unspecified, SourceLocation(),
+                             PrevSpec, DiagID);
+    }
+
+    // C++ [class.union]p2:
+    //   The member-specification of an anonymous union shall only
+    //   define non-static data members. [Note: nested types and
+    //   functions cannot be declared within an anonymous union. ]
+    for (DeclContext::decl_iterator Mem = Record->decls_begin(),
+                                 MemEnd = Record->decls_end();
+         Mem != MemEnd; ++Mem) {
+      if (FieldDecl *FD = dyn_cast<FieldDecl>(*Mem)) {
+        // C++ [class.union]p3:
+        //   An anonymous union shall not have private or protected
+        //   members (clause 11).
+        if (FD->getAccess() == AS_protected || FD->getAccess() == AS_private) {
+          Diag(FD->getLocation(), diag::err_anonymous_record_nonpublic_member)
+            << (int)Record->isUnion() << (int)(FD->getAccess() == AS_protected);
+          Invalid = true;
+        }
+      } else if ((*Mem)->isImplicit()) {
+        // Any implicit members are fine.
+      } else if (isa<TagDecl>(*Mem) && (*Mem)->getDeclContext() != Record) {
+        // This is a type that showed up in an
+        // elaborated-type-specifier inside the anonymous struct or
+        // union, but which actually declares a type outside of the
+        // anonymous struct or union. It's okay.
+      } else if (RecordDecl *MemRecord = dyn_cast<RecordDecl>(*Mem)) {
+        if (!MemRecord->isAnonymousStructOrUnion() &&
+            MemRecord->getDeclName()) {
+          // This is a nested type declaration.
+          Diag(MemRecord->getLocation(), diag::err_anonymous_record_with_type)
+            << (int)Record->isUnion();
+          Invalid = true;
+        }
+      } else {
+        // We have something that isn't a non-static data
+        // member. Complain about it.
+        unsigned DK = diag::err_anonymous_record_bad_member;
+        if (isa<TypeDecl>(*Mem))
+          DK = diag::err_anonymous_record_with_type;
+        else if (isa<FunctionDecl>(*Mem))
+          DK = diag::err_anonymous_record_with_function;
+        else if (isa<VarDecl>(*Mem))
+          DK = diag::err_anonymous_record_with_static;
+        Diag((*Mem)->getLocation(), DK)
+            << (int)Record->isUnion();
+          Invalid = true;
+      }
+    }
+  }
+
+  if (!Record->isUnion() && !Owner->isRecord()) {
+    Diag(Record->getLocation(), diag::err_anonymous_struct_not_member)
+      << (int)getLangOptions().CPlusPlus;
+    Invalid = true;
+  }
+
+  // Mock up a declarator.
+  Declarator Dc(DS, Declarator::TypeNameContext);
+  TypeSourceInfo *TInfo = 0;
+  GetTypeForDeclarator(Dc, S, &TInfo);
+  assert(TInfo && "couldn't build declarator info for anonymous struct/union");
+
+  // Create a declaration for this anonymous struct/union.
+  NamedDecl *Anon = 0;
+  if (RecordDecl *OwningClass = dyn_cast<RecordDecl>(Owner)) {
+    Anon = FieldDecl::Create(Context, OwningClass, Record->getLocation(),
+                             /*IdentifierInfo=*/0,
+                             Context.getTypeDeclType(Record),
+                             TInfo,
+                             /*BitWidth=*/0, /*Mutable=*/false);
+    Anon->setAccess(AS_public);
+    if (getLangOptions().CPlusPlus)
+      FieldCollector->Add(cast<FieldDecl>(Anon));
+  } else {
+    DeclSpec::SCS SCSpec = DS.getStorageClassSpec();
+    assert(SCSpec != DeclSpec::SCS_typedef &&
+           "Parser allowed 'typedef' as storage class VarDecl.");
+    VarDecl::StorageClass SC = StorageClassSpecToVarDeclStorageClass(SCSpec);
+    if (SCSpec == DeclSpec::SCS_mutable) {
+      // mutable can only appear on non-static class members, so it's always
+      // an error here
+      Diag(Record->getLocation(), diag::err_mutable_nonmember);
+      Invalid = true;
+      SC = VarDecl::None;
+    }
+    SCSpec = DS.getStorageClassSpecAsWritten();
+    VarDecl::StorageClass SCAsWritten
+      = StorageClassSpecToVarDeclStorageClass(SCSpec);
+
+    Anon = VarDecl::Create(Context, Owner, Record->getLocation(),
+                           /*IdentifierInfo=*/0,
+                           Context.getTypeDeclType(Record),
+                           TInfo, SC, SCAsWritten);
+  }
+  Anon->setImplicit();
+
+  // Add the anonymous struct/union object to the current
+  // context. We'll be referencing this object when we refer to one of
+  // its members.
+  Owner->addDecl(Anon);
+
+  // Inject the members of the anonymous struct/union into the owning
+  // context and into the identifier resolver chain for name lookup
+  // purposes.
+  if (InjectAnonymousStructOrUnionMembers(S, Owner, Record))
+    Invalid = true;
+
+  // Mark this as an anonymous struct/union type. Note that we do not
+  // do this until after we have already checked and injected the
+  // members of this anonymous struct/union type, because otherwise
+  // the members could be injected twice: once by DeclContext when it
+  // builds its lookup table, and once by
+  // InjectAnonymousStructOrUnionMembers.
+  Record->setAnonymousStructOrUnion(true);
+
+  if (Invalid)
+    Anon->setInvalidDecl();
+
+  return DeclPtrTy::make(Anon);
+}
+
+
+/// GetNameForDeclarator - Determine the full declaration name for the
+/// given Declarator.
+DeclarationName Sema::GetNameForDeclarator(Declarator &D) {
+  return GetNameFromUnqualifiedId(D.getName());
+}
+
+/// \brief Retrieves the canonicalized name from a parsed unqualified-id.
+DeclarationName Sema::GetNameFromUnqualifiedId(const UnqualifiedId &Name) {
+  switch (Name.getKind()) {
+    case UnqualifiedId::IK_Identifier:
+      return DeclarationName(Name.Identifier);
+      
+    case UnqualifiedId::IK_OperatorFunctionId:
+      return Context.DeclarationNames.getCXXOperatorName(
+                                              Name.OperatorFunctionId.Operator);
+
+    case UnqualifiedId::IK_LiteralOperatorId:
+      return Context.DeclarationNames.getCXXLiteralOperatorName(
+                                                               Name.Identifier);
+
+    case UnqualifiedId::IK_ConversionFunctionId: {
+      QualType Ty = GetTypeFromParser(Name.ConversionFunctionId);
+      if (Ty.isNull())
+        return DeclarationName();
+      
+      return Context.DeclarationNames.getCXXConversionFunctionName(
+                                                  Context.getCanonicalType(Ty));
+    }
+      
+    case UnqualifiedId::IK_ConstructorName: {
+      QualType Ty = GetTypeFromParser(Name.ConstructorName);
+      if (Ty.isNull())
+        return DeclarationName();
+      
+      return Context.DeclarationNames.getCXXConstructorName(
+                                                  Context.getCanonicalType(Ty));
+    }
+      
+    case UnqualifiedId::IK_ConstructorTemplateId: {
+      // In well-formed code, we can only have a constructor
+      // template-id that refers to the current context, so go there
+      // to find the actual type being constructed.
+      CXXRecordDecl *CurClass = dyn_cast<CXXRecordDecl>(CurContext);
+      if (!CurClass || CurClass->getIdentifier() != Name.TemplateId->Name)
+        return DeclarationName();
+
+      // Determine the type of the class being constructed.
+      QualType CurClassType = Context.getTypeDeclType(CurClass);
+
+      // FIXME: Check two things: that the template-id names the same type as
+      // CurClassType, and that the template-id does not occur when the name
+      // was qualified.
+
+      return Context.DeclarationNames.getCXXConstructorName(
+                                       Context.getCanonicalType(CurClassType));
+    }
+
+    case UnqualifiedId::IK_DestructorName: {
+      QualType Ty = GetTypeFromParser(Name.DestructorName);
+      if (Ty.isNull())
+        return DeclarationName();
+      
+      return Context.DeclarationNames.getCXXDestructorName(
+                                                           Context.getCanonicalType(Ty));
+    }
+      
+    case UnqualifiedId::IK_TemplateId: {
+      TemplateName TName
+        = TemplateName::getFromVoidPointer(Name.TemplateId->Template);
+      return Context.getNameForTemplate(TName);
+    }
+  }
+  
+  assert(false && "Unknown name kind");
+  return DeclarationName();  
+}
+
+/// isNearlyMatchingFunction - Determine whether the C++ functions
+/// Declaration and Definition are "nearly" matching. This heuristic
+/// is used to improve diagnostics in the case where an out-of-line
+/// function definition doesn't match any declaration within
+/// the class or namespace.
+static bool isNearlyMatchingFunction(ASTContext &Context,
+                                     FunctionDecl *Declaration,
+                                     FunctionDecl *Definition) {
+  if (Declaration->param_size() != Definition->param_size())
+    return false;
+  for (unsigned Idx = 0; Idx < Declaration->param_size(); ++Idx) {
+    QualType DeclParamTy = Declaration->getParamDecl(Idx)->getType();
+    QualType DefParamTy = Definition->getParamDecl(Idx)->getType();
+
+    if (!Context.hasSameUnqualifiedType(DeclParamTy.getNonReferenceType(),
+                                        DefParamTy.getNonReferenceType()))
+      return false;
+  }
+
+  return true;
+}
+
+Sema::DeclPtrTy
+Sema::HandleDeclarator(Scope *S, Declarator &D,
+                       MultiTemplateParamsArg TemplateParamLists,
+                       bool IsFunctionDefinition) {
+  DeclarationName Name = GetNameForDeclarator(D);
+
+  // All of these full declarators require an identifier.  If it doesn't have
+  // one, the ParsedFreeStandingDeclSpec action should be used.
+  if (!Name) {
+    if (!D.isInvalidType())  // Reject this if we think it is valid.
+      Diag(D.getDeclSpec().getSourceRange().getBegin(),
+           diag::err_declarator_need_ident)
+        << D.getDeclSpec().getSourceRange() << D.getSourceRange();
+    return DeclPtrTy();
+  }
+
+  // The scope passed in may not be a decl scope.  Zip up the scope tree until
+  // we find one that is.
+  while ((S->getFlags() & Scope::DeclScope) == 0 ||
+         (S->getFlags() & Scope::TemplateParamScope) != 0)
+    S = S->getParent();
+
+  // If this is an out-of-line definition of a member of a class template
+  // or class template partial specialization, we may need to rebuild the
+  // type specifier in the declarator. See RebuildTypeInCurrentInstantiation()
+  // for more information.
+  // FIXME: cope with decltype(expr) and typeof(expr) once the rebuilder can
+  // handle expressions properly.
+  DeclSpec &DS = const_cast<DeclSpec&>(D.getDeclSpec());
+  if (D.getCXXScopeSpec().isSet() && !D.getCXXScopeSpec().isInvalid() &&
+      isDependentScopeSpecifier(D.getCXXScopeSpec()) &&
+      (DS.getTypeSpecType() == DeclSpec::TST_typename ||
+       DS.getTypeSpecType() == DeclSpec::TST_typeofType ||
+       DS.getTypeSpecType() == DeclSpec::TST_typeofExpr ||
+       DS.getTypeSpecType() == DeclSpec::TST_decltype)) {
+    if (DeclContext *DC = computeDeclContext(D.getCXXScopeSpec(), true)) {
+      // FIXME: Preserve type source info.
+      QualType T = GetTypeFromParser(DS.getTypeRep());
+
+      DeclContext *SavedContext = CurContext;
+      CurContext = DC;
+      T = RebuildTypeInCurrentInstantiation(T, D.getIdentifierLoc(), Name);
+      CurContext = SavedContext;
+
+      if (T.isNull())
+        return DeclPtrTy();
+      DS.UpdateTypeRep(T.getAsOpaquePtr());
+    }
+  }
+
+  DeclContext *DC;
+  NamedDecl *New;
+
+  TypeSourceInfo *TInfo = 0;
+  QualType R = GetTypeForDeclarator(D, S, &TInfo);
+
+  LookupResult Previous(*this, Name, D.getIdentifierLoc(), LookupOrdinaryName,
+                        ForRedeclaration);
+
+  // See if this is a redefinition of a variable in the same scope.
+  if (D.getCXXScopeSpec().isInvalid()) {
+    DC = CurContext;
+    D.setInvalidType();
+  } else if (!D.getCXXScopeSpec().isSet()) {
+    bool IsLinkageLookup = false;
+
+    // If the declaration we're planning to build will be a function
+    // or object with linkage, then look for another declaration with
+    // linkage (C99 6.2.2p4-5 and C++ [basic.link]p6).
+    if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef)
+      /* Do nothing*/;
+    else if (R->isFunctionType()) {
+      if (CurContext->isFunctionOrMethod() ||
+          D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_static)
+        IsLinkageLookup = true;
+    } else if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_extern)
+      IsLinkageLookup = true;
+    else if (CurContext->getLookupContext()->isTranslationUnit() &&
+             D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_static)
+      IsLinkageLookup = true;
+
+    if (IsLinkageLookup)
+      Previous.clear(LookupRedeclarationWithLinkage);
+
+    DC = CurContext;
+    LookupName(Previous, S, /* CreateBuiltins = */ IsLinkageLookup);
+  } else { // Something like "int foo::x;"
+    DC = computeDeclContext(D.getCXXScopeSpec(), true);
+
+    if (!DC) {
+      // If we could not compute the declaration context, it's because the
+      // declaration context is dependent but does not refer to a class,
+      // class template, or class template partial specialization. Complain
+      // and return early, to avoid the coming semantic disaster.
+      Diag(D.getIdentifierLoc(),
+           diag::err_template_qualified_declarator_no_match)
+        << (NestedNameSpecifier*)D.getCXXScopeSpec().getScopeRep()
+        << D.getCXXScopeSpec().getRange();
+      return DeclPtrTy();
+    }
+
+    if (!DC->isDependentContext() && 
+        RequireCompleteDeclContext(D.getCXXScopeSpec()))
+      return DeclPtrTy();
+
+    if (isa<CXXRecordDecl>(DC) && !cast<CXXRecordDecl>(DC)->hasDefinition()) {
+      Diag(D.getIdentifierLoc(),
+           diag::err_member_def_undefined_record)
+        << Name << DC << D.getCXXScopeSpec().getRange();
+      D.setInvalidType();
+    }
+    
+    LookupQualifiedName(Previous, DC);
+
+    // Don't consider using declarations as previous declarations for
+    // out-of-line members.
+    RemoveUsingDecls(Previous);
+
+    // C++ 7.3.1.2p2:
+    // Members (including explicit specializations of templates) of a named
+    // namespace can also be defined outside that namespace by explicit
+    // qualification of the name being defined, provided that the entity being
+    // defined was already declared in the namespace and the definition appears
+    // after the point of declaration in a namespace that encloses the
+    // declarations namespace.
+    //
+    // Note that we only check the context at this point. We don't yet
+    // have enough information to make sure that PrevDecl is actually
+    // the declaration we want to match. For example, given:
+    //
+    //   class X {
+    //     void f();
+    //     void f(float);
+    //   };
+    //
+    //   void X::f(int) { } // ill-formed
+    //
+    // In this case, PrevDecl will point to the overload set
+    // containing the two f's declared in X, but neither of them
+    // matches.
+
+    // First check whether we named the global scope.
+    if (isa<TranslationUnitDecl>(DC)) {
+      Diag(D.getIdentifierLoc(), diag::err_invalid_declarator_global_scope)
+        << Name << D.getCXXScopeSpec().getRange();
+    } else {
+      DeclContext *Cur = CurContext;
+      while (isa<LinkageSpecDecl>(Cur))
+        Cur = Cur->getParent();
+      if (!Cur->Encloses(DC)) {
+        // The qualifying scope doesn't enclose the original declaration.
+        // Emit diagnostic based on current scope.
+        SourceLocation L = D.getIdentifierLoc();
+        SourceRange R = D.getCXXScopeSpec().getRange();
+        if (isa<FunctionDecl>(Cur))
+          Diag(L, diag::err_invalid_declarator_in_function) << Name << R;
+        else
+          Diag(L, diag::err_invalid_declarator_scope)
+            << Name << cast<NamedDecl>(DC) << R;
+        D.setInvalidType();
+      }
+    }
+  }
+
+  if (Previous.isSingleResult() &&
+      Previous.getFoundDecl()->isTemplateParameter()) {
+    // Maybe we will complain about the shadowed template parameter.
+    if (!D.isInvalidType())
+      if (DiagnoseTemplateParameterShadow(D.getIdentifierLoc(),
+                                          Previous.getFoundDecl()))
+        D.setInvalidType();
+
+    // Just pretend that we didn't see the previous declaration.
+    Previous.clear();
+  }
+
+  // In C++, the previous declaration we find might be a tag type
+  // (class or enum). In this case, the new declaration will hide the
+  // tag type. Note that this does does not apply if we're declaring a
+  // typedef (C++ [dcl.typedef]p4).
+  if (Previous.isSingleTagDecl() &&
+      D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_typedef)
+    Previous.clear();
+
+  bool Redeclaration = false;
+  if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef) {
+    if (TemplateParamLists.size()) {
+      Diag(D.getIdentifierLoc(), diag::err_template_typedef);
+      return DeclPtrTy();
+    }
+
+    New = ActOnTypedefDeclarator(S, D, DC, R, TInfo, Previous, Redeclaration);
+  } else if (R->isFunctionType()) {
+    New = ActOnFunctionDeclarator(S, D, DC, R, TInfo, Previous,
+                                  move(TemplateParamLists),
+                                  IsFunctionDefinition, Redeclaration);
+  } else {
+    New = ActOnVariableDeclarator(S, D, DC, R, TInfo, Previous,
+                                  move(TemplateParamLists),
+                                  Redeclaration);
+  }
+
+  if (New == 0)
+    return DeclPtrTy();
+
+  // If this has an identifier and is not an invalid redeclaration or 
+  // function template specialization, add it to the scope stack.
+  if (Name && !(Redeclaration && New->isInvalidDecl()))
+    PushOnScopeChains(New, S);
+
+  return DeclPtrTy::make(New);
+}
+
+/// TryToFixInvalidVariablyModifiedType - Helper method to turn variable array
+/// types into constant array types in certain situations which would otherwise
+/// be errors (for GCC compatibility).
+static QualType TryToFixInvalidVariablyModifiedType(QualType T,
+                                                    ASTContext &Context,
+                                                    bool &SizeIsNegative) {
+  // This method tries to turn a variable array into a constant
+  // array even when the size isn't an ICE.  This is necessary
+  // for compatibility with code that depends on gcc's buggy
+  // constant expression folding, like struct {char x[(int)(char*)2];}
+  SizeIsNegative = false;
+
+  QualifierCollector Qs;
+  const Type *Ty = Qs.strip(T);
+
+  if (const PointerType* PTy = dyn_cast<PointerType>(Ty)) {
+    QualType Pointee = PTy->getPointeeType();
+    QualType FixedType =
+        TryToFixInvalidVariablyModifiedType(Pointee, Context, SizeIsNegative);
+    if (FixedType.isNull()) return FixedType;
+    FixedType = Context.getPointerType(FixedType);
+    return Qs.apply(FixedType);
+  }
+
+  const VariableArrayType* VLATy = dyn_cast<VariableArrayType>(T);
+  if (!VLATy)
+    return QualType();
+  // FIXME: We should probably handle this case
+  if (VLATy->getElementType()->isVariablyModifiedType())
+    return QualType();
+
+  Expr::EvalResult EvalResult;
+  if (!VLATy->getSizeExpr() ||
+      !VLATy->getSizeExpr()->Evaluate(EvalResult, Context) ||
+      !EvalResult.Val.isInt())
+    return QualType();
+
+  llvm::APSInt &Res = EvalResult.Val.getInt();
+  if (Res >= llvm::APSInt(Res.getBitWidth(), Res.isUnsigned())) {
+    // TODO: preserve the size expression in declarator info
+    return Context.getConstantArrayType(VLATy->getElementType(),
+                                        Res, ArrayType::Normal, 0);
+  }
+
+  SizeIsNegative = true;
+  return QualType();
+}
+
+/// \brief Register the given locally-scoped external C declaration so
+/// that it can be found later for redeclarations
+void
+Sema::RegisterLocallyScopedExternCDecl(NamedDecl *ND,
+                                       const LookupResult &Previous,
+                                       Scope *S) {
+  assert(ND->getLexicalDeclContext()->isFunctionOrMethod() &&
+         "Decl is not a locally-scoped decl!");
+  // Note that we have a locally-scoped external with this name.
+  LocallyScopedExternalDecls[ND->getDeclName()] = ND;
+
+  if (!Previous.isSingleResult())
+    return;
+
+  NamedDecl *PrevDecl = Previous.getFoundDecl();
+
+  // If there was a previous declaration of this variable, it may be
+  // in our identifier chain. Update the identifier chain with the new
+  // declaration.
+  if (S && IdResolver.ReplaceDecl(PrevDecl, ND)) {
+    // The previous declaration was found on the identifer resolver
+    // chain, so remove it from its scope.
+    while (S && !S->isDeclScope(DeclPtrTy::make(PrevDecl)))
+      S = S->getParent();
+
+    if (S)
+      S->RemoveDecl(DeclPtrTy::make(PrevDecl));
+  }
+}
+
+/// \brief Diagnose function specifiers on a declaration of an identifier that
+/// does not identify a function.
+void Sema::DiagnoseFunctionSpecifiers(Declarator& D) {
+  // FIXME: We should probably indicate the identifier in question to avoid
+  // confusion for constructs like "inline int a(), b;"
+  if (D.getDeclSpec().isInlineSpecified())
+    Diag(D.getDeclSpec().getInlineSpecLoc(),
+         diag::err_inline_non_function);
+
+  if (D.getDeclSpec().isVirtualSpecified())
+    Diag(D.getDeclSpec().getVirtualSpecLoc(),
+         diag::err_virtual_non_function);
+
+  if (D.getDeclSpec().isExplicitSpecified())
+    Diag(D.getDeclSpec().getExplicitSpecLoc(),
+         diag::err_explicit_non_function);
+}
+
+NamedDecl*
+Sema::ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC,
+                             QualType R,  TypeSourceInfo *TInfo,
+                             LookupResult &Previous, bool &Redeclaration) {
+  // Typedef declarators cannot be qualified (C++ [dcl.meaning]p1).
+  if (D.getCXXScopeSpec().isSet()) {
+    Diag(D.getIdentifierLoc(), diag::err_qualified_typedef_declarator)
+      << D.getCXXScopeSpec().getRange();
+    D.setInvalidType();
+    // Pretend we didn't see the scope specifier.
+    DC = CurContext;
+    Previous.clear();
+  }
+
+  if (getLangOptions().CPlusPlus) {
+    // Check that there are no default arguments (C++ only).
+    CheckExtraCXXDefaultArguments(D);
+  }
+
+  DiagnoseFunctionSpecifiers(D);
+
+  if (D.getDeclSpec().isThreadSpecified())
+    Diag(D.getDeclSpec().getThreadSpecLoc(), diag::err_invalid_thread);
+
+  TypedefDecl *NewTD = ParseTypedefDecl(S, D, R, TInfo);
+  if (!NewTD) return 0;
+
+  // Handle attributes prior to checking for duplicates in MergeVarDecl
+  ProcessDeclAttributes(S, NewTD, D);
+
+  // Merge the decl with the existing one if appropriate. If the decl is
+  // in an outer scope, it isn't the same thing.
+  FilterLookupForScope(*this, Previous, DC, S, /*ConsiderLinkage*/ false);
+  if (!Previous.empty()) {
+    Redeclaration = true;
+    MergeTypeDefDecl(NewTD, Previous);
+  }
+
+  // C99 6.7.7p2: If a typedef name specifies a variably modified type
+  // then it shall have block scope.
+  QualType T = NewTD->getUnderlyingType();
+  if (T->isVariablyModifiedType()) {
+    FunctionNeedsScopeChecking() = true;
+
+    if (S->getFnParent() == 0) {
+      bool SizeIsNegative;
+      QualType FixedTy =
+          TryToFixInvalidVariablyModifiedType(T, Context, SizeIsNegative);
+      if (!FixedTy.isNull()) {
+        Diag(D.getIdentifierLoc(), diag::warn_illegal_constant_array_size);
+        NewTD->setTypeSourceInfo(Context.getTrivialTypeSourceInfo(FixedTy));
+      } else {
+        if (SizeIsNegative)
+          Diag(D.getIdentifierLoc(), diag::err_typecheck_negative_array_size);
+        else if (T->isVariableArrayType())
+          Diag(D.getIdentifierLoc(), diag::err_vla_decl_in_file_scope);
+        else
+          Diag(D.getIdentifierLoc(), diag::err_vm_decl_in_file_scope);
+        NewTD->setInvalidDecl();
+      }
+    }
+  }
+
+  // If this is the C FILE type, notify the AST context.
+  if (IdentifierInfo *II = NewTD->getIdentifier())
+    if (!NewTD->isInvalidDecl() &&
+        NewTD->getDeclContext()->getLookupContext()->isTranslationUnit()) {
+      if (II->isStr("FILE"))
+        Context.setFILEDecl(NewTD);
+      else if (II->isStr("jmp_buf"))
+        Context.setjmp_bufDecl(NewTD);
+      else if (II->isStr("sigjmp_buf"))
+        Context.setsigjmp_bufDecl(NewTD);
+    }
+
+  return NewTD;
+}
+
+/// \brief Determines whether the given declaration is an out-of-scope
+/// previous declaration.
+///
+/// This routine should be invoked when name lookup has found a
+/// previous declaration (PrevDecl) that is not in the scope where a
+/// new declaration by the same name is being introduced. If the new
+/// declaration occurs in a local scope, previous declarations with
+/// linkage may still be considered previous declarations (C99
+/// 6.2.2p4-5, C++ [basic.link]p6).
+///
+/// \param PrevDecl the previous declaration found by name
+/// lookup
+///
+/// \param DC the context in which the new declaration is being
+/// declared.
+///
+/// \returns true if PrevDecl is an out-of-scope previous declaration
+/// for a new delcaration with the same name.
+static bool
+isOutOfScopePreviousDeclaration(NamedDecl *PrevDecl, DeclContext *DC,
+                                ASTContext &Context) {
+  if (!PrevDecl)
+    return 0;
+
+  if (!PrevDecl->hasLinkage())
+    return false;
+
+  if (Context.getLangOptions().CPlusPlus) {
+    // C++ [basic.link]p6:
+    //   If there is a visible declaration of an entity with linkage
+    //   having the same name and type, ignoring entities declared
+    //   outside the innermost enclosing namespace scope, the block
+    //   scope declaration declares that same entity and receives the
+    //   linkage of the previous declaration.
+    DeclContext *OuterContext = DC->getLookupContext();
+    if (!OuterContext->isFunctionOrMethod())
+      // This rule only applies to block-scope declarations.
+      return false;
+    else {
+      DeclContext *PrevOuterContext = PrevDecl->getDeclContext();
+      if (PrevOuterContext->isRecord())
+        // We found a member function: ignore it.
+        return false;
+      else {
+        // Find the innermost enclosing namespace for the new and
+        // previous declarations.
+        while (!OuterContext->isFileContext())
+          OuterContext = OuterContext->getParent();
+        while (!PrevOuterContext->isFileContext())
+          PrevOuterContext = PrevOuterContext->getParent();
+
+        // The previous declaration is in a different namespace, so it
+        // isn't the same function.
+        if (OuterContext->getPrimaryContext() !=
+            PrevOuterContext->getPrimaryContext())
+          return false;
+      }
+    }
+  }
+
+  return true;
+}
+
+static void SetNestedNameSpecifier(DeclaratorDecl *DD, Declarator &D) {
+  CXXScopeSpec &SS = D.getCXXScopeSpec();
+  if (!SS.isSet()) return;
+  DD->setQualifierInfo(static_cast<NestedNameSpecifier*>(SS.getScopeRep()),
+                       SS.getRange());
+}
+
+NamedDecl*
+Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
+                              QualType R, TypeSourceInfo *TInfo,
+                              LookupResult &Previous,
+                              MultiTemplateParamsArg TemplateParamLists,
+                              bool &Redeclaration) {
+  DeclarationName Name = GetNameForDeclarator(D);
+
+  // Check that there are no default arguments (C++ only).
+  if (getLangOptions().CPlusPlus)
+    CheckExtraCXXDefaultArguments(D);
+
+  DeclSpec::SCS SCSpec = D.getDeclSpec().getStorageClassSpec();
+  assert(SCSpec != DeclSpec::SCS_typedef &&
+         "Parser allowed 'typedef' as storage class VarDecl.");
+  VarDecl::StorageClass SC = StorageClassSpecToVarDeclStorageClass(SCSpec);
+  if (SCSpec == DeclSpec::SCS_mutable) {
+    // mutable can only appear on non-static class members, so it's always
+    // an error here
+    Diag(D.getIdentifierLoc(), diag::err_mutable_nonmember);
+    D.setInvalidType();
+    SC = VarDecl::None;
+  }
+  SCSpec = D.getDeclSpec().getStorageClassSpecAsWritten();
+  VarDecl::StorageClass SCAsWritten
+    = StorageClassSpecToVarDeclStorageClass(SCSpec);
+
+  IdentifierInfo *II = Name.getAsIdentifierInfo();
+  if (!II) {
+    Diag(D.getIdentifierLoc(), diag::err_bad_variable_name)
+      << Name.getAsString();
+    return 0;
+  }
+
+  DiagnoseFunctionSpecifiers(D);
+
+  if (!DC->isRecord() && S->getFnParent() == 0) {
+    // C99 6.9p2: The storage-class specifiers auto and register shall not
+    // appear in the declaration specifiers in an external declaration.
+    if (SC == VarDecl::Auto || SC == VarDecl::Register) {
+
+      // If this is a register variable with an asm label specified, then this
+      // is a GNU extension.
+      if (SC == VarDecl::Register && D.getAsmLabel())
+        Diag(D.getIdentifierLoc(), diag::err_unsupported_global_register);
+      else
+        Diag(D.getIdentifierLoc(), diag::err_typecheck_sclass_fscope);
+      D.setInvalidType();
+    }
+  }
+  if (DC->isRecord() && !CurContext->isRecord()) {
+    // This is an out-of-line definition of a static data member.
+    if (SC == VarDecl::Static) {
+      Diag(D.getDeclSpec().getStorageClassSpecLoc(),
+           diag::err_static_out_of_line)
+        << FixItHint::CreateRemoval(D.getDeclSpec().getStorageClassSpecLoc());
+    } else if (SC == VarDecl::None)
+      SC = VarDecl::Static;
+  }
+  if (SC == VarDecl::Static) {
+    if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(DC)) {
+      if (RD->isLocalClass())
+        Diag(D.getIdentifierLoc(),
+             diag::err_static_data_member_not_allowed_in_local_class)
+          << Name << RD->getDeclName();
+    }
+  }
+
+  // Match up the template parameter lists with the scope specifier, then
+  // determine whether we have a template or a template specialization.
+  bool isExplicitSpecialization = false;
+  if (TemplateParameterList *TemplateParams
+        = MatchTemplateParametersToScopeSpecifier(
+                                  D.getDeclSpec().getSourceRange().getBegin(),
+                                                  D.getCXXScopeSpec(),
+                        (TemplateParameterList**)TemplateParamLists.get(),
+                                                   TemplateParamLists.size(),
+                                                  /*never a friend*/ false,
+                                                  isExplicitSpecialization)) {
+    if (TemplateParams->size() > 0) {
+      // There is no such thing as a variable template.
+      Diag(D.getIdentifierLoc(), diag::err_template_variable)
+        << II
+        << SourceRange(TemplateParams->getTemplateLoc(),
+                       TemplateParams->getRAngleLoc());
+      return 0;
+    } else {
+      // There is an extraneous 'template<>' for this variable. Complain
+      // about it, but allow the declaration of the variable.
+      Diag(TemplateParams->getTemplateLoc(),
+           diag::err_template_variable_noparams)
+        << II
+        << SourceRange(TemplateParams->getTemplateLoc(),
+                       TemplateParams->getRAngleLoc());
+      
+      isExplicitSpecialization = true;
+    }
+  }
+
+  VarDecl *NewVD = VarDecl::Create(Context, DC, D.getIdentifierLoc(),
+                                   II, R, TInfo, SC, SCAsWritten);
+
+  if (D.isInvalidType())
+    NewVD->setInvalidDecl();
+
+  SetNestedNameSpecifier(NewVD, D);
+
+  if (D.getDeclSpec().isThreadSpecified()) {
+    if (NewVD->hasLocalStorage())
+      Diag(D.getDeclSpec().getThreadSpecLoc(), diag::err_thread_non_global);
+    else if (!Context.Target.isTLSSupported())
+      Diag(D.getDeclSpec().getThreadSpecLoc(), diag::err_thread_unsupported);
+    else
+      NewVD->setThreadSpecified(true);
+  }
+
+  // Set the lexical context. If the declarator has a C++ scope specifier, the
+  // lexical context will be different from the semantic context.
+  NewVD->setLexicalDeclContext(CurContext);
+
+  // Handle attributes prior to checking for duplicates in MergeVarDecl
+  ProcessDeclAttributes(S, NewVD, D);
+
+  // Handle GNU asm-label extension (encoded as an attribute).
+  if (Expr *E = (Expr*) D.getAsmLabel()) {
+    // The parser guarantees this is a string.
+    StringLiteral *SE = cast<StringLiteral>(E);
+    NewVD->addAttr(::new (Context) AsmLabelAttr(Context, SE->getString()));
+  }
+
+  // Diagnose shadowed variables before filtering for scope.
+  if (!D.getCXXScopeSpec().isSet())
+    CheckShadow(S, NewVD, Previous);
+
+  // Don't consider existing declarations that are in a different
+  // scope and are out-of-semantic-context declarations (if the new
+  // declaration has linkage).
+  FilterLookupForScope(*this, Previous, DC, S, NewVD->hasLinkage());
+  
+  // Merge the decl with the existing one if appropriate.
+  if (!Previous.empty()) {
+    if (Previous.isSingleResult() &&
+        isa<FieldDecl>(Previous.getFoundDecl()) &&
+        D.getCXXScopeSpec().isSet()) {
+      // The user tried to define a non-static data member
+      // out-of-line (C++ [dcl.meaning]p1).
+      Diag(NewVD->getLocation(), diag::err_nonstatic_member_out_of_line)
+        << D.getCXXScopeSpec().getRange();
+      Previous.clear();
+      NewVD->setInvalidDecl();
+    }
+  } else if (D.getCXXScopeSpec().isSet()) {
+    // No previous declaration in the qualifying scope.
+    Diag(D.getIdentifierLoc(), diag::err_no_member)
+      << Name << computeDeclContext(D.getCXXScopeSpec(), true)
+      << D.getCXXScopeSpec().getRange();
+    NewVD->setInvalidDecl();
+  }
+
+  CheckVariableDeclaration(NewVD, Previous, Redeclaration);
+
+  // This is an explicit specialization of a static data member. Check it.
+  if (isExplicitSpecialization && !NewVD->isInvalidDecl() &&
+      CheckMemberSpecialization(NewVD, Previous))
+    NewVD->setInvalidDecl();
+
+  // attributes declared post-definition are currently ignored
+  if (Previous.isSingleResult()) {
+    VarDecl *Def = dyn_cast<VarDecl>(Previous.getFoundDecl());
+    if (Def && (Def = Def->getDefinition()) &&
+        Def != NewVD && D.hasAttributes()) {
+      Diag(NewVD->getLocation(), diag::warn_attribute_precede_definition);
+      Diag(Def->getLocation(), diag::note_previous_definition);
+    }
+  }
+
+  // If this is a locally-scoped extern C variable, update the map of
+  // such variables.
+  if (CurContext->isFunctionOrMethod() && NewVD->isExternC() &&
+      !NewVD->isInvalidDecl())
+    RegisterLocallyScopedExternCDecl(NewVD, Previous, S);
+
+  return NewVD;
+}
+
+/// \brief Diagnose variable or built-in function shadowing.  Implements
+/// -Wshadow.
+///
+/// This method is called whenever a VarDecl is added to a "useful"
+/// scope.
+///
+/// \param S the scope in which the shadowing name is being declared
+/// \param R the lookup of the name
+///
+void Sema::CheckShadow(Scope *S, VarDecl *D, const LookupResult& R) {
+  // Return if warning is ignored.
+  if (Diags.getDiagnosticLevel(diag::warn_decl_shadow) == Diagnostic::Ignored)
+    return;
+
+  // Don't diagnose declarations at file scope.  The scope might not
+  // have a DeclContext if (e.g.) we're parsing a function prototype.
+  DeclContext *NewDC = static_cast<DeclContext*>(S->getEntity());
+  if (NewDC && NewDC->isFileContext())
+    return;
+  
+  // Only diagnose if we're shadowing an unambiguous field or variable.
+  if (R.getResultKind() != LookupResult::Found)
+    return;
+
+  NamedDecl* ShadowedDecl = R.getFoundDecl();
+  if (!isa<VarDecl>(ShadowedDecl) && !isa<FieldDecl>(ShadowedDecl))
+    return;
+
+  DeclContext *OldDC = ShadowedDecl->getDeclContext();
+
+  // Only warn about certain kinds of shadowing for class members.
+  if (NewDC && NewDC->isRecord()) {
+    // In particular, don't warn about shadowing non-class members.
+    if (!OldDC->isRecord())
+      return;
+
+    // TODO: should we warn about static data members shadowing
+    // static data members from base classes?
+    
+    // TODO: don't diagnose for inaccessible shadowed members.
+    // This is hard to do perfectly because we might friend the
+    // shadowing context, but that's just a false negative.
+  }
+
+  // Determine what kind of declaration we're shadowing.
+  unsigned Kind;
+  if (isa<RecordDecl>(OldDC)) {
+    if (isa<FieldDecl>(ShadowedDecl))
+      Kind = 3; // field
+    else
+      Kind = 2; // static data member
+  } else if (OldDC->isFileContext())
+    Kind = 1; // global
+  else
+    Kind = 0; // local
+
+  DeclarationName Name = R.getLookupName();
+
+  // Emit warning and note.
+  Diag(R.getNameLoc(), diag::warn_decl_shadow) << Name << Kind << OldDC;
+  Diag(ShadowedDecl->getLocation(), diag::note_previous_declaration);
+}
+
+/// \brief Check -Wshadow without the advantage of a previous lookup.
+void Sema::CheckShadow(Scope *S, VarDecl *D) {
+  LookupResult R(*this, D->getDeclName(), D->getLocation(),
+                 Sema::LookupOrdinaryName, Sema::ForRedeclaration);
+  LookupName(R, S);
+  CheckShadow(S, D, R);
+}
+
+/// \brief Perform semantic checking on a newly-created variable
+/// declaration.
+///
+/// This routine performs all of the type-checking required for a
+/// variable declaration once it has been built. It is used both to
+/// check variables after they have been parsed and their declarators
+/// have been translated into a declaration, and to check variables
+/// that have been instantiated from a template.
+///
+/// Sets NewVD->isInvalidDecl() if an error was encountered.
+void Sema::CheckVariableDeclaration(VarDecl *NewVD,
+                                    LookupResult &Previous,
+                                    bool &Redeclaration) {
+  // If the decl is already known invalid, don't check it.
+  if (NewVD->isInvalidDecl())
+    return;
+
+  QualType T = NewVD->getType();
+
+  if (T->isObjCInterfaceType()) {
+    Diag(NewVD->getLocation(), diag::err_statically_allocated_object);
+    return NewVD->setInvalidDecl();
+  }
+
+  // Emit an error if an address space was applied to decl with local storage.
+  // This includes arrays of objects with address space qualifiers, but not
+  // automatic variables that point to other address spaces.
+  // ISO/IEC TR 18037 S5.1.2
+  if (NewVD->hasLocalStorage() && (T.getAddressSpace() != 0)) {
+    Diag(NewVD->getLocation(), diag::err_as_qualified_auto_decl);
+    return NewVD->setInvalidDecl();
+  }
+
+  if (NewVD->hasLocalStorage() && T.isObjCGCWeak()
+      && !NewVD->hasAttr<BlocksAttr>())
+    Diag(NewVD->getLocation(), diag::warn_attribute_weak_on_local);
+
+  bool isVM = T->isVariablyModifiedType();
+  if (isVM || NewVD->hasAttr<CleanupAttr>() ||
+      NewVD->hasAttr<BlocksAttr>() ||
+      // FIXME: We need to diagnose jumps passed initialized variables in C++.
+      // However, this turns on the scope checker for everything with a variable
+      // which may impact compile time.  See if we can find a better solution
+      // to this, perhaps only checking functions that contain gotos in C++?
+      (LangOpts.CPlusPlus && NewVD->hasLocalStorage()))
+    FunctionNeedsScopeChecking() = true;
+
+  if ((isVM && NewVD->hasLinkage()) ||
+      (T->isVariableArrayType() && NewVD->hasGlobalStorage())) {
+    bool SizeIsNegative;
+    QualType FixedTy =
+        TryToFixInvalidVariablyModifiedType(T, Context, SizeIsNegative);
+
+    if (FixedTy.isNull() && T->isVariableArrayType()) {
+      const VariableArrayType *VAT = Context.getAsVariableArrayType(T);
+      // FIXME: This won't give the correct result for
+      // int a[10][n];
+      SourceRange SizeRange = VAT->getSizeExpr()->getSourceRange();
+
+      if (NewVD->isFileVarDecl())
+        Diag(NewVD->getLocation(), diag::err_vla_decl_in_file_scope)
+        << SizeRange;
+      else if (NewVD->getStorageClass() == VarDecl::Static)
+        Diag(NewVD->getLocation(), diag::err_vla_decl_has_static_storage)
+        << SizeRange;
+      else
+        Diag(NewVD->getLocation(), diag::err_vla_decl_has_extern_linkage)
+        << SizeRange;
+      return NewVD->setInvalidDecl();
+    }
+
+    if (FixedTy.isNull()) {
+      if (NewVD->isFileVarDecl())
+        Diag(NewVD->getLocation(), diag::err_vm_decl_in_file_scope);
+      else
+        Diag(NewVD->getLocation(), diag::err_vm_decl_has_extern_linkage);
+      return NewVD->setInvalidDecl();
+    }
+
+    Diag(NewVD->getLocation(), diag::warn_illegal_constant_array_size);
+    NewVD->setType(FixedTy);
+  }
+
+  if (Previous.empty() && NewVD->isExternC()) {
+    // Since we did not find anything by this name and we're declaring
+    // an extern "C" variable, look for a non-visible extern "C"
+    // declaration with the same name.
+    llvm::DenseMap<DeclarationName, NamedDecl *>::iterator Pos
+      = LocallyScopedExternalDecls.find(NewVD->getDeclName());
+    if (Pos != LocallyScopedExternalDecls.end())
+      Previous.addDecl(Pos->second);
+  }
+
+  if (T->isVoidType() && !NewVD->hasExternalStorage()) {
+    Diag(NewVD->getLocation(), diag::err_typecheck_decl_incomplete_type)
+      << T;
+    return NewVD->setInvalidDecl();
+  }
+
+  if (!NewVD->hasLocalStorage() && NewVD->hasAttr<BlocksAttr>()) {
+    Diag(NewVD->getLocation(), diag::err_block_on_nonlocal);
+    return NewVD->setInvalidDecl();
+  }
+
+  if (isVM && NewVD->hasAttr<BlocksAttr>()) {
+    Diag(NewVD->getLocation(), diag::err_block_on_vm);
+    return NewVD->setInvalidDecl();
+  }
+
+  if (!Previous.empty()) {
+    Redeclaration = true;
+    MergeVarDecl(NewVD, Previous);
+  }
+}
+
+/// \brief Data used with FindOverriddenMethod
+struct FindOverriddenMethodData {
+  Sema *S;
+  CXXMethodDecl *Method;
+};
+
+/// \brief Member lookup function that determines whether a given C++
+/// method overrides a method in a base class, to be used with
+/// CXXRecordDecl::lookupInBases().
+static bool FindOverriddenMethod(const CXXBaseSpecifier *Specifier,
+                                 CXXBasePath &Path,
+                                 void *UserData) {
+  RecordDecl *BaseRecord = Specifier->getType()->getAs<RecordType>()->getDecl();
+
+  FindOverriddenMethodData *Data 
+    = reinterpret_cast<FindOverriddenMethodData*>(UserData);
+  
+  DeclarationName Name = Data->Method->getDeclName();
+  
+  // FIXME: Do we care about other names here too?
+  if (Name.getNameKind() == DeclarationName::CXXDestructorName) {
+    // We really want to find the base class constructor here.
+    QualType T = Data->S->Context.getTypeDeclType(BaseRecord);
+    CanQualType CT = Data->S->Context.getCanonicalType(T);
+    
+    Name = Data->S->Context.DeclarationNames.getCXXDestructorName(CT);
+  }    
+  
+  for (Path.Decls = BaseRecord->lookup(Name);
+       Path.Decls.first != Path.Decls.second;
+       ++Path.Decls.first) {
+    if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(*Path.Decls.first)) {
+      if (MD->isVirtual() && !Data->S->IsOverload(Data->Method, MD))
+        return true;
+    }
+  }
+  
+  return false;
+}
+
+/// AddOverriddenMethods - See if a method overrides any in the base classes,
+/// and if so, check that it's a valid override and remember it.
+void Sema::AddOverriddenMethods(CXXRecordDecl *DC, CXXMethodDecl *MD) {
+  // Look for virtual methods in base classes that this method might override.
+  CXXBasePaths Paths;
+  FindOverriddenMethodData Data;
+  Data.Method = MD;
+  Data.S = this;
+  if (DC->lookupInBases(&FindOverriddenMethod, &Data, Paths)) {
+    for (CXXBasePaths::decl_iterator I = Paths.found_decls_begin(),
+         E = Paths.found_decls_end(); I != E; ++I) {
+      if (CXXMethodDecl *OldMD = dyn_cast<CXXMethodDecl>(*I)) {
+        if (!CheckOverridingFunctionReturnType(MD, OldMD) &&
+            !CheckOverridingFunctionExceptionSpec(MD, OldMD) &&
+            !CheckOverridingFunctionAttributes(MD, OldMD))
+          MD->addOverriddenMethod(OldMD->getCanonicalDecl());
+      }
+    }
+  }
+}
+
+NamedDecl*
+Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
+                              QualType R, TypeSourceInfo *TInfo,
+                              LookupResult &Previous,
+                              MultiTemplateParamsArg TemplateParamLists,
+                              bool IsFunctionDefinition, bool &Redeclaration) {
+  assert(R.getTypePtr()->isFunctionType());
+
+  DeclarationName Name = GetNameForDeclarator(D);
+  FunctionDecl::StorageClass SC = FunctionDecl::None;
+  switch (D.getDeclSpec().getStorageClassSpec()) {
+  default: assert(0 && "Unknown storage class!");
+  case DeclSpec::SCS_auto:
+  case DeclSpec::SCS_register:
+  case DeclSpec::SCS_mutable:
+    Diag(D.getDeclSpec().getStorageClassSpecLoc(),
+         diag::err_typecheck_sclass_func);
+    D.setInvalidType();
+    break;
+  case DeclSpec::SCS_unspecified: SC = FunctionDecl::None; break;
+  case DeclSpec::SCS_extern:      SC = FunctionDecl::Extern; break;
+  case DeclSpec::SCS_static: {
+    if (CurContext->getLookupContext()->isFunctionOrMethod()) {
+      // C99 6.7.1p5:
+      //   The declaration of an identifier for a function that has
+      //   block scope shall have no explicit storage-class specifier
+      //   other than extern
+      // See also (C++ [dcl.stc]p4).
+      Diag(D.getDeclSpec().getStorageClassSpecLoc(),
+           diag::err_static_block_func);
+      SC = FunctionDecl::None;
+    } else
+      SC = FunctionDecl::Static;
+    break;
+  }
+  case DeclSpec::SCS_private_extern: SC = FunctionDecl::PrivateExtern;break;
+  }
+
+  if (D.getDeclSpec().isThreadSpecified())
+    Diag(D.getDeclSpec().getThreadSpecLoc(), diag::err_invalid_thread);
+
+  bool isFriend = D.getDeclSpec().isFriendSpecified();
+  bool isInline = D.getDeclSpec().isInlineSpecified();
+  bool isVirtual = D.getDeclSpec().isVirtualSpecified();
+  bool isExplicit = D.getDeclSpec().isExplicitSpecified();
+
+  DeclSpec::SCS SCSpec = D.getDeclSpec().getStorageClassSpecAsWritten();
+  FunctionDecl::StorageClass SCAsWritten
+    = StorageClassSpecToFunctionDeclStorageClass(SCSpec);
+
+  // Check that the return type is not an abstract class type.
+  // For record types, this is done by the AbstractClassUsageDiagnoser once
+  // the class has been completely parsed.
+  if (!DC->isRecord() &&
+      RequireNonAbstractType(D.getIdentifierLoc(),
+                             R->getAs<FunctionType>()->getResultType(),
+                             diag::err_abstract_type_in_decl,
+                             AbstractReturnType))
+    D.setInvalidType();
+
+  // Do not allow returning a objc interface by-value.
+  if (R->getAs<FunctionType>()->getResultType()->isObjCInterfaceType()) {
+    Diag(D.getIdentifierLoc(),
+         diag::err_object_cannot_be_passed_returned_by_value) << 0
+      << R->getAs<FunctionType>()->getResultType();
+    D.setInvalidType();
+  }
+
+  bool isVirtualOkay = false;
+  FunctionDecl *NewFD;
+
+  if (isFriend) {
+    // C++ [class.friend]p5
+    //   A function can be defined in a friend declaration of a
+    //   class . . . . Such a function is implicitly inline.
+    isInline |= IsFunctionDefinition;
+  }
+
+  if (Name.getNameKind() == DeclarationName::CXXConstructorName) {
+    // This is a C++ constructor declaration.
+    assert(DC->isRecord() &&
+           "Constructors can only be declared in a member context");
+
+    R = CheckConstructorDeclarator(D, R, SC);
+
+    // Create the new declaration
+    NewFD = CXXConstructorDecl::Create(Context,
+                                       cast<CXXRecordDecl>(DC),
+                                       D.getIdentifierLoc(), Name, R, TInfo,
+                                       isExplicit, isInline,
+                                       /*isImplicitlyDeclared=*/false);
+  } else if (Name.getNameKind() == DeclarationName::CXXDestructorName) {
+    // This is a C++ destructor declaration.
+    if (DC->isRecord()) {
+      R = CheckDestructorDeclarator(D, SC);
+
+      NewFD = CXXDestructorDecl::Create(Context,
+                                        cast<CXXRecordDecl>(DC),
+                                        D.getIdentifierLoc(), Name, R,
+                                        isInline,
+                                        /*isImplicitlyDeclared=*/false);
+      NewFD->setTypeSourceInfo(TInfo);
+
+      isVirtualOkay = true;
+    } else {
+      Diag(D.getIdentifierLoc(), diag::err_destructor_not_member);
+
+      // Create a FunctionDecl to satisfy the function definition parsing
+      // code path.
+      NewFD = FunctionDecl::Create(Context, DC, D.getIdentifierLoc(),
+                                   Name, R, TInfo, SC, SCAsWritten, isInline,
+                                   /*hasPrototype=*/true);
+      D.setInvalidType();
+    }
+  } else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName) {
+    if (!DC->isRecord()) {
+      Diag(D.getIdentifierLoc(),
+           diag::err_conv_function_not_member);
+      return 0;
+    }
+
+    CheckConversionDeclarator(D, R, SC);
+    NewFD = CXXConversionDecl::Create(Context, cast<CXXRecordDecl>(DC),
+                                      D.getIdentifierLoc(), Name, R, TInfo,
+                                      isInline, isExplicit);
+
+    isVirtualOkay = true;
+  } else if (DC->isRecord()) {
+    // If the of the function is the same as the name of the record, then this
+    // must be an invalid constructor that has a return type.
+    // (The parser checks for a return type and makes the declarator a
+    // constructor if it has no return type).
+    // must have an invalid constructor that has a return type
+    if (Name.getAsIdentifierInfo() &&
+        Name.getAsIdentifierInfo() == cast<CXXRecordDecl>(DC)->getIdentifier()){
+      Diag(D.getIdentifierLoc(), diag::err_constructor_return_type)
+        << SourceRange(D.getDeclSpec().getTypeSpecTypeLoc())
+        << SourceRange(D.getIdentifierLoc());
+      return 0;
+    }
+
+    bool isStatic = SC == FunctionDecl::Static;
+    
+    // [class.free]p1:
+    // Any allocation function for a class T is a static member
+    // (even if not explicitly declared static).
+    if (Name.getCXXOverloadedOperator() == OO_New ||
+        Name.getCXXOverloadedOperator() == OO_Array_New)
+      isStatic = true;
+
+    // [class.free]p6 Any deallocation function for a class X is a static member
+    // (even if not explicitly declared static).
+    if (Name.getCXXOverloadedOperator() == OO_Delete ||
+        Name.getCXXOverloadedOperator() == OO_Array_Delete)
+      isStatic = true;
+    
+    // This is a C++ method declaration.
+    NewFD = CXXMethodDecl::Create(Context, cast<CXXRecordDecl>(DC),
+                                  D.getIdentifierLoc(), Name, R, TInfo,
+                                  isStatic, SCAsWritten, isInline);
+
+    isVirtualOkay = !isStatic;
+  } else {
+    // Determine whether the function was written with a
+    // prototype. This true when:
+    //   - we're in C++ (where every function has a prototype),
+    //   - there is a prototype in the declarator, or
+    //   - the type R of the function is some kind of typedef or other reference
+    //     to a type name (which eventually refers to a function type).
+    bool HasPrototype =
+       getLangOptions().CPlusPlus ||
+       (D.getNumTypeObjects() && D.getTypeObject(0).Fun.hasPrototype) ||
+       (!isa<FunctionType>(R.getTypePtr()) && R->isFunctionProtoType());
+
+    NewFD = FunctionDecl::Create(Context, DC,
+                                 D.getIdentifierLoc(),
+                                 Name, R, TInfo, SC, SCAsWritten, isInline,
+                                 HasPrototype);
+  }
+
+  if (D.isInvalidType())
+    NewFD->setInvalidDecl();
+
+  SetNestedNameSpecifier(NewFD, D);
+
+  // Set the lexical context. If the declarator has a C++
+  // scope specifier, or is the object of a friend declaration, the
+  // lexical context will be different from the semantic context.
+  NewFD->setLexicalDeclContext(CurContext);
+
+  // Match up the template parameter lists with the scope specifier, then
+  // determine whether we have a template or a template specialization.
+  FunctionTemplateDecl *FunctionTemplate = 0;
+  bool isExplicitSpecialization = false;
+  bool isFunctionTemplateSpecialization = false;
+  if (TemplateParameterList *TemplateParams
+        = MatchTemplateParametersToScopeSpecifier(
+                                  D.getDeclSpec().getSourceRange().getBegin(),
+                                  D.getCXXScopeSpec(),
+                           (TemplateParameterList**)TemplateParamLists.get(),
+                                                  TemplateParamLists.size(),
+                                                  isFriend,
+                                                  isExplicitSpecialization)) {
+    if (TemplateParams->size() > 0) {
+      // This is a function template
+
+      // Check that we can declare a template here.
+      if (CheckTemplateDeclScope(S, TemplateParams))
+        return 0;
+
+      FunctionTemplate = FunctionTemplateDecl::Create(Context, DC,
+                                                      NewFD->getLocation(),
+                                                      Name, TemplateParams,
+                                                      NewFD);
+      FunctionTemplate->setLexicalDeclContext(CurContext);
+      NewFD->setDescribedFunctionTemplate(FunctionTemplate);
+    } else {
+      // This is a function template specialization.
+      isFunctionTemplateSpecialization = true;
+
+      // C++0x [temp.expl.spec]p20 forbids "template<> friend void foo(int);".
+      if (isFriend && isFunctionTemplateSpecialization) {
+        // We want to remove the "template<>", found here.
+        SourceRange RemoveRange = TemplateParams->getSourceRange();
+
+        // If we remove the template<> and the name is not a
+        // template-id, we're actually silently creating a problem:
+        // the friend declaration will refer to an untemplated decl,
+        // and clearly the user wants a template specialization.  So
+        // we need to insert '<>' after the name.
+        SourceLocation InsertLoc;
+        if (D.getName().getKind() != UnqualifiedId::IK_TemplateId) {
+          InsertLoc = D.getName().getSourceRange().getEnd();
+          InsertLoc = PP.getLocForEndOfToken(InsertLoc);
+        }
+
+        Diag(D.getIdentifierLoc(), diag::err_template_spec_decl_friend)
+          << Name << RemoveRange
+          << FixItHint::CreateRemoval(RemoveRange)
+          << FixItHint::CreateInsertion(InsertLoc, "<>");
+      }
+    }
+
+    // FIXME: Free this memory properly.
+    TemplateParamLists.release();
+  }
+  
+  // C++ [dcl.fct.spec]p5:
+  //   The virtual specifier shall only be used in declarations of
+  //   nonstatic class member functions that appear within a
+  //   member-specification of a class declaration; see 10.3.
+  //
+  if (isVirtual && !NewFD->isInvalidDecl()) {
+    if (!isVirtualOkay) {
+       Diag(D.getDeclSpec().getVirtualSpecLoc(),
+           diag::err_virtual_non_function);
+    } else if (!CurContext->isRecord()) {
+      // 'virtual' was specified outside of the class.
+      Diag(D.getDeclSpec().getVirtualSpecLoc(), diag::err_virtual_out_of_class)
+        << FixItHint::CreateRemoval(D.getDeclSpec().getVirtualSpecLoc());
+    } else {
+      // Okay: Add virtual to the method.
+      CXXRecordDecl *CurClass = cast<CXXRecordDecl>(DC);
+      CurClass->setMethodAsVirtual(NewFD);
+    }
+  }
+
+  // C++ [dcl.fct.spec]p6:
+  //  The explicit specifier shall be used only in the declaration of a
+  //  constructor or conversion function within its class definition; see 12.3.1
+  //  and 12.3.2.
+  if (isExplicit && !NewFD->isInvalidDecl()) {
+    if (!CurContext->isRecord()) {
+      // 'explicit' was specified outside of the class.
+      Diag(D.getDeclSpec().getExplicitSpecLoc(), 
+           diag::err_explicit_out_of_class)
+        << FixItHint::CreateRemoval(D.getDeclSpec().getExplicitSpecLoc());
+    } else if (!isa<CXXConstructorDecl>(NewFD) && 
+               !isa<CXXConversionDecl>(NewFD)) {
+      // 'explicit' was specified on a function that wasn't a constructor
+      // or conversion function.
+      Diag(D.getDeclSpec().getExplicitSpecLoc(),
+           diag::err_explicit_non_ctor_or_conv_function)
+        << FixItHint::CreateRemoval(D.getDeclSpec().getExplicitSpecLoc());
+    }      
+  }
+
+  // Filter out previous declarations that don't match the scope.
+  FilterLookupForScope(*this, Previous, DC, S, NewFD->hasLinkage());
+
+  if (isFriend) {
+    // DC is the namespace in which the function is being declared.
+    assert((DC->isFileContext() || !Previous.empty()) &&
+           "previously-undeclared friend function being created "
+           "in a non-namespace context");
+
+    // For now, claim that the objects have no previous declaration.
+    if (FunctionTemplate) {
+      FunctionTemplate->setObjectOfFriendDecl(false);
+      FunctionTemplate->setAccess(AS_public);
+    }
+    NewFD->setObjectOfFriendDecl(false);
+    NewFD->setAccess(AS_public);
+  }
+
+  if (SC == FunctionDecl::Static && isa<CXXMethodDecl>(NewFD) &&
+      !CurContext->isRecord()) {
+    // C++ [class.static]p1:
+    //   A data or function member of a class may be declared static
+    //   in a class definition, in which case it is a static member of
+    //   the class.
+
+    // Complain about the 'static' specifier if it's on an out-of-line
+    // member function definition.
+    Diag(D.getDeclSpec().getStorageClassSpecLoc(),
+         diag::err_static_out_of_line)
+      << FixItHint::CreateRemoval(D.getDeclSpec().getStorageClassSpecLoc());
+  }
+
+  // Handle GNU asm-label extension (encoded as an attribute).
+  if (Expr *E = (Expr*) D.getAsmLabel()) {
+    // The parser guarantees this is a string.
+    StringLiteral *SE = cast<StringLiteral>(E);
+    NewFD->addAttr(::new (Context) AsmLabelAttr(Context, SE->getString()));
+  }
+
+  // Copy the parameter declarations from the declarator D to the function
+  // declaration NewFD, if they are available.  First scavenge them into Params.
+  llvm::SmallVector<ParmVarDecl*, 16> Params;
+  if (D.getNumTypeObjects() > 0) {
+    DeclaratorChunk::FunctionTypeInfo &FTI = D.getTypeObject(0).Fun;
+
+    // Check for C99 6.7.5.3p10 - foo(void) is a non-varargs
+    // function that takes no arguments, not a function that takes a
+    // single void argument.
+    // We let through "const void" here because Sema::GetTypeForDeclarator
+    // already checks for that case.
+    if (FTI.NumArgs == 1 && !FTI.isVariadic && FTI.ArgInfo[0].Ident == 0 &&
+        FTI.ArgInfo[0].Param &&
+        FTI.ArgInfo[0].Param.getAs<ParmVarDecl>()->getType()->isVoidType()) {
+      // Empty arg list, don't push any params.
+      ParmVarDecl *Param = FTI.ArgInfo[0].Param.getAs<ParmVarDecl>();
+
+      // In C++, the empty parameter-type-list must be spelled "void"; a
+      // typedef of void is not permitted.
+      if (getLangOptions().CPlusPlus &&
+          Param->getType().getUnqualifiedType() != Context.VoidTy)
+        Diag(Param->getLocation(), diag::err_param_typedef_of_void);
+      // FIXME: Leaks decl?
+    } else if (FTI.NumArgs > 0 && FTI.ArgInfo[0].Param != 0) {
+      for (unsigned i = 0, e = FTI.NumArgs; i != e; ++i) {
+        ParmVarDecl *Param = FTI.ArgInfo[i].Param.getAs<ParmVarDecl>();
+        assert(Param->getDeclContext() != NewFD && "Was set before ?");
+        Param->setDeclContext(NewFD);
+        Params.push_back(Param);
+
+        if (Param->isInvalidDecl())
+          NewFD->setInvalidDecl();
+      }
+    }
+
+  } else if (const FunctionProtoType *FT = R->getAs<FunctionProtoType>()) {
+    // When we're declaring a function with a typedef, typeof, etc as in the
+    // following example, we'll need to synthesize (unnamed)
+    // parameters for use in the declaration.
+    //
+    // @code
+    // typedef void fn(int);
+    // fn f;
+    // @endcode
+
+    // Synthesize a parameter for each argument type.
+    for (FunctionProtoType::arg_type_iterator AI = FT->arg_type_begin(),
+         AE = FT->arg_type_end(); AI != AE; ++AI) {
+      ParmVarDecl *Param = ParmVarDecl::Create(Context, NewFD,
+                                               SourceLocation(), 0,
+                                               *AI, /*TInfo=*/0,
+                                               VarDecl::None,
+                                               VarDecl::None, 0);
+      Param->setImplicit();
+      Params.push_back(Param);
+    }
+  } else {
+    assert(R->isFunctionNoProtoType() && NewFD->getNumParams() == 0 &&
+           "Should not need args for typedef of non-prototype fn");
+  }
+  // Finally, we know we have the right number of parameters, install them.
+  NewFD->setParams(Params.data(), Params.size());
+
+  // If the declarator is a template-id, translate the parser's template 
+  // argument list into our AST format.
+  bool HasExplicitTemplateArgs = false;
+  TemplateArgumentListInfo TemplateArgs;
+  if (D.getName().getKind() == UnqualifiedId::IK_TemplateId) {
+    TemplateIdAnnotation *TemplateId = D.getName().TemplateId;
+    TemplateArgs.setLAngleLoc(TemplateId->LAngleLoc);
+    TemplateArgs.setRAngleLoc(TemplateId->RAngleLoc);
+    ASTTemplateArgsPtr TemplateArgsPtr(*this,
+                                       TemplateId->getTemplateArgs(),
+                                       TemplateId->NumArgs);
+    translateTemplateArguments(TemplateArgsPtr,
+                               TemplateArgs);
+    TemplateArgsPtr.release();
+    
+    HasExplicitTemplateArgs = true;
+    
+    if (FunctionTemplate) {
+      // FIXME: Diagnose function template with explicit template
+      // arguments.
+      HasExplicitTemplateArgs = false;
+    } else if (!isFunctionTemplateSpecialization && 
+               !D.getDeclSpec().isFriendSpecified()) {
+      // We have encountered something that the user meant to be a 
+      // specialization (because it has explicitly-specified template
+      // arguments) but that was not introduced with a "template<>" (or had
+      // too few of them).
+      Diag(D.getIdentifierLoc(), diag::err_template_spec_needs_header)
+        << SourceRange(TemplateId->LAngleLoc, TemplateId->RAngleLoc)
+        << FixItHint::CreateInsertion(
+                                   D.getDeclSpec().getSourceRange().getBegin(),
+                                                 "template<> ");
+      isFunctionTemplateSpecialization = true;
+    } else {
+      // "friend void foo<>(int);" is an implicit specialization decl.
+      isFunctionTemplateSpecialization = true;
+    }
+  } else if (isFriend && isFunctionTemplateSpecialization) {
+    // This combination is only possible in a recovery case;  the user
+    // wrote something like:
+    //   template <> friend void foo(int);
+    // which we're recovering from as if the user had written:
+    //   friend void foo<>(int);
+    // Go ahead and fake up a template id.
+    HasExplicitTemplateArgs = true;
+    TemplateArgs.setLAngleLoc(D.getIdentifierLoc());
+    TemplateArgs.setRAngleLoc(D.getIdentifierLoc());
+  }
+
+  // If it's a friend (and only if it's a friend), it's possible
+  // that either the specialized function type or the specialized
+  // template is dependent, and therefore matching will fail.  In
+  // this case, don't check the specialization yet.
+  if (isFunctionTemplateSpecialization && isFriend &&
+      (NewFD->getType()->isDependentType() || DC->isDependentContext())) {
+    assert(HasExplicitTemplateArgs &&
+           "friend function specialization without template args");
+    if (CheckDependentFunctionTemplateSpecialization(NewFD, TemplateArgs,
+                                                     Previous))
+      NewFD->setInvalidDecl();
+  } else if (isFunctionTemplateSpecialization) {
+    if (CheckFunctionTemplateSpecialization(NewFD,
+                               (HasExplicitTemplateArgs ? &TemplateArgs : 0),
+                                            Previous))
+      NewFD->setInvalidDecl();
+  } else if (isExplicitSpecialization && isa<CXXMethodDecl>(NewFD)) {
+    if (CheckMemberSpecialization(NewFD, Previous))
+      NewFD->setInvalidDecl();
+  }
+
+  // Perform semantic checking on the function declaration.
+  bool OverloadableAttrRequired = false; // FIXME: HACK!
+  CheckFunctionDeclaration(S, NewFD, Previous, isExplicitSpecialization,
+                           Redeclaration, /*FIXME:*/OverloadableAttrRequired);
+
+  assert((NewFD->isInvalidDecl() || !Redeclaration ||
+          Previous.getResultKind() != LookupResult::FoundOverloaded) &&
+         "previous declaration set still overloaded");
+
+  NamedDecl *PrincipalDecl = (FunctionTemplate
+                              ? cast<NamedDecl>(FunctionTemplate)
+                              : NewFD);
+
+  if (isFriend && Redeclaration) {
+    AccessSpecifier Access = AS_public;
+    if (!NewFD->isInvalidDecl())
+      Access = NewFD->getPreviousDeclaration()->getAccess();
+
+    NewFD->setAccess(Access);
+    if (FunctionTemplate) FunctionTemplate->setAccess(Access);
+
+    PrincipalDecl->setObjectOfFriendDecl(true);
+  }
+
+  if (NewFD->isOverloadedOperator() && !DC->isRecord() &&
+      PrincipalDecl->isInIdentifierNamespace(Decl::IDNS_Ordinary))
+    PrincipalDecl->setNonMemberOperator();
+
+  // If we have a function template, check the template parameter
+  // list. This will check and merge default template arguments.
+  if (FunctionTemplate) {
+    FunctionTemplateDecl *PrevTemplate = FunctionTemplate->getPreviousDeclaration();
+    CheckTemplateParameterList(FunctionTemplate->getTemplateParameters(),
+                      PrevTemplate? PrevTemplate->getTemplateParameters() : 0,
+             D.getDeclSpec().isFriendSpecified()? TPC_FriendFunctionTemplate
+                                                : TPC_FunctionTemplate);
+  }
+
+  if (D.getCXXScopeSpec().isSet() && !NewFD->isInvalidDecl()) {
+    // Fake up an access specifier if it's supposed to be a class member.
+    if (!Redeclaration && isa<CXXRecordDecl>(NewFD->getDeclContext()))
+      NewFD->setAccess(AS_public);
+
+    // An out-of-line member function declaration must also be a
+    // definition (C++ [dcl.meaning]p1).
+    // Note that this is not the case for explicit specializations of
+    // function templates or member functions of class templates, per
+    // C++ [temp.expl.spec]p2.
+    if (!IsFunctionDefinition && !isFriend &&
+        !isFunctionTemplateSpecialization && !isExplicitSpecialization) {
+      Diag(NewFD->getLocation(), diag::err_out_of_line_declaration)
+        << D.getCXXScopeSpec().getRange();
+      NewFD->setInvalidDecl();
+    } else if (!Redeclaration && 
+               !(isFriend && CurContext->isDependentContext())) {
+      // The user tried to provide an out-of-line definition for a
+      // function that is a member of a class or namespace, but there
+      // was no such member function declared (C++ [class.mfct]p2,
+      // C++ [namespace.memdef]p2). For example:
+      //
+      // class X {
+      //   void f() const;
+      // };
+      //
+      // void X::f() { } // ill-formed
+      //
+      // Complain about this problem, and attempt to suggest close
+      // matches (e.g., those that differ only in cv-qualifiers and
+      // whether the parameter types are references).
+      Diag(D.getIdentifierLoc(), diag::err_member_def_does_not_match)
+        << Name << DC << D.getCXXScopeSpec().getRange();
+      NewFD->setInvalidDecl();
+
+      LookupResult Prev(*this, Name, D.getIdentifierLoc(), LookupOrdinaryName,
+                        ForRedeclaration);
+      LookupQualifiedName(Prev, DC);
+      assert(!Prev.isAmbiguous() &&
+             "Cannot have an ambiguity in previous-declaration lookup");
+      for (LookupResult::iterator Func = Prev.begin(), FuncEnd = Prev.end();
+           Func != FuncEnd; ++Func) {
+        if (isa<FunctionDecl>(*Func) &&
+            isNearlyMatchingFunction(Context, cast<FunctionDecl>(*Func), NewFD))
+          Diag((*Func)->getLocation(), diag::note_member_def_close_match);
+      }
+    }
+  }
+
+  // Handle attributes. We need to have merged decls when handling attributes
+  // (for example to check for conflicts, etc).
+  // FIXME: This needs to happen before we merge declarations. Then,
+  // let attribute merging cope with attribute conflicts.
+  ProcessDeclAttributes(S, NewFD, D);
+
+  // attributes declared post-definition are currently ignored
+  if (Redeclaration && Previous.isSingleResult()) {
+    const FunctionDecl *Def;
+    FunctionDecl *PrevFD = dyn_cast<FunctionDecl>(Previous.getFoundDecl());
+    if (PrevFD && PrevFD->getBody(Def) && D.hasAttributes()) {
+      Diag(NewFD->getLocation(), diag::warn_attribute_precede_definition);
+      Diag(Def->getLocation(), diag::note_previous_definition);
+    }
+  }
+
+  AddKnownFunctionAttributes(NewFD);
+
+  if (OverloadableAttrRequired && !NewFD->getAttr<OverloadableAttr>()) {
+    // If a function name is overloadable in C, then every function
+    // with that name must be marked "overloadable".
+    Diag(NewFD->getLocation(), diag::err_attribute_overloadable_missing)
+      << Redeclaration << NewFD;
+    if (!Previous.empty())
+      Diag(Previous.getRepresentativeDecl()->getLocation(),
+           diag::note_attribute_overloadable_prev_overload);
+    NewFD->addAttr(::new (Context) OverloadableAttr());
+  }
+
+  // If this is a locally-scoped extern C function, update the
+  // map of such names.
+  if (CurContext->isFunctionOrMethod() && NewFD->isExternC()
+      && !NewFD->isInvalidDecl())
+    RegisterLocallyScopedExternCDecl(NewFD, Previous, S);
+
+  // Set this FunctionDecl's range up to the right paren.
+  NewFD->setLocEnd(D.getSourceRange().getEnd());
+
+  if (FunctionTemplate && NewFD->isInvalidDecl())
+    FunctionTemplate->setInvalidDecl();
+
+  if (FunctionTemplate)
+    return FunctionTemplate;
+
+  
+  // Keep track of static, non-inlined function definitions that
+  // have not been used. We will warn later.
+  // FIXME: Also include static functions declared but not defined.
+  if (!NewFD->isInvalidDecl() && IsFunctionDefinition 
+      && !NewFD->isInlined() && NewFD->getLinkage() == InternalLinkage
+      && !NewFD->isUsed() && !NewFD->hasAttr<UnusedAttr>()
+      && !NewFD->hasAttr<ConstructorAttr>()
+      && !NewFD->hasAttr<DestructorAttr>())
+    UnusedStaticFuncs.push_back(NewFD);
+  
+  return NewFD;
+}
+
+/// \brief Perform semantic checking of a new function declaration.
+///
+/// Performs semantic analysis of the new function declaration
+/// NewFD. This routine performs all semantic checking that does not
+/// require the actual declarator involved in the declaration, and is
+/// used both for the declaration of functions as they are parsed
+/// (called via ActOnDeclarator) and for the declaration of functions
+/// that have been instantiated via C++ template instantiation (called
+/// via InstantiateDecl).
+///
+/// \param IsExplicitSpecialiation whether this new function declaration is
+/// an explicit specialization of the previous declaration.
+///
+/// This sets NewFD->isInvalidDecl() to true if there was an error.
+void Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
+                                    LookupResult &Previous,
+                                    bool IsExplicitSpecialization,
+                                    bool &Redeclaration,
+                                    bool &OverloadableAttrRequired) {
+  // If NewFD is already known erroneous, don't do any of this checking.
+  if (NewFD->isInvalidDecl())
+    return;
+
+  if (NewFD->getResultType()->isVariablyModifiedType()) {
+    // Functions returning a variably modified type violate C99 6.7.5.2p2
+    // because all functions have linkage.
+    Diag(NewFD->getLocation(), diag::err_vm_func_decl);
+    return NewFD->setInvalidDecl();
+  }
+
+  if (NewFD->isMain()) 
+    CheckMain(NewFD);
+
+  // Check for a previous declaration of this name.
+  if (Previous.empty() && NewFD->isExternC()) {
+    // Since we did not find anything by this name and we're declaring
+    // an extern "C" function, look for a non-visible extern "C"
+    // declaration with the same name.
+    llvm::DenseMap<DeclarationName, NamedDecl *>::iterator Pos
+      = LocallyScopedExternalDecls.find(NewFD->getDeclName());
+    if (Pos != LocallyScopedExternalDecls.end())
+      Previous.addDecl(Pos->second);
+  }
+
+  // Merge or overload the declaration with an existing declaration of
+  // the same name, if appropriate.
+  if (!Previous.empty()) {
+    // Determine whether NewFD is an overload of PrevDecl or
+    // a declaration that requires merging. If it's an overload,
+    // there's no more work to do here; we'll just add the new
+    // function to the scope.
+
+    NamedDecl *OldDecl = 0;
+    if (!AllowOverloadingOfFunction(Previous, Context)) {
+      Redeclaration = true;
+      OldDecl = Previous.getFoundDecl();
+    } else {
+      if (!getLangOptions().CPlusPlus) {
+        OverloadableAttrRequired = true;
+
+        // Functions marked "overloadable" must have a prototype (that
+        // we can't get through declaration merging).
+        if (!NewFD->getType()->getAs<FunctionProtoType>()) {
+          Diag(NewFD->getLocation(),
+               diag::err_attribute_overloadable_no_prototype)
+            << NewFD;
+          Redeclaration = true;
+
+          // Turn this into a variadic function with no parameters.
+          QualType R = Context.getFunctionType(
+                     NewFD->getType()->getAs<FunctionType>()->getResultType(),
+                     0, 0, true, 0, false, false, 0, 0,
+                     FunctionType::ExtInfo());
+          NewFD->setType(R);
+          return NewFD->setInvalidDecl();
+        }
+      }
+
+      switch (CheckOverload(NewFD, Previous, OldDecl)) {
+      case Ovl_Match:
+        Redeclaration = true;
+        if (isa<UsingShadowDecl>(OldDecl) && CurContext->isRecord()) {
+          HideUsingShadowDecl(S, cast<UsingShadowDecl>(OldDecl));
+          Redeclaration = false;
+        }
+        break;
+
+      case Ovl_NonFunction:
+        Redeclaration = true;
+        break;
+
+      case Ovl_Overload:
+        Redeclaration = false;
+        break;
+      }
+    }
+
+    if (Redeclaration) {
+      // NewFD and OldDecl represent declarations that need to be
+      // merged.
+      if (MergeFunctionDecl(NewFD, OldDecl))
+        return NewFD->setInvalidDecl();
+
+      Previous.clear();
+      Previous.addDecl(OldDecl);
+
+      if (FunctionTemplateDecl *OldTemplateDecl
+                                    = dyn_cast<FunctionTemplateDecl>(OldDecl)) {
+        NewFD->setPreviousDeclaration(OldTemplateDecl->getTemplatedDecl());        
+        FunctionTemplateDecl *NewTemplateDecl
+          = NewFD->getDescribedFunctionTemplate();
+        assert(NewTemplateDecl && "Template/non-template mismatch");
+        if (CXXMethodDecl *Method 
+              = dyn_cast<CXXMethodDecl>(NewTemplateDecl->getTemplatedDecl())) {
+          Method->setAccess(OldTemplateDecl->getAccess());
+          NewTemplateDecl->setAccess(OldTemplateDecl->getAccess());
+        }
+        
+        // If this is an explicit specialization of a member that is a function
+        // template, mark it as a member specialization.
+        if (IsExplicitSpecialization && 
+            NewTemplateDecl->getInstantiatedFromMemberTemplate()) {
+          NewTemplateDecl->setMemberSpecialization();
+          assert(OldTemplateDecl->isMemberSpecialization());
+        }
+      } else {
+        if (isa<CXXMethodDecl>(NewFD)) // Set access for out-of-line definitions
+          NewFD->setAccess(OldDecl->getAccess());
+        NewFD->setPreviousDeclaration(cast<FunctionDecl>(OldDecl));
+      }
+    }
+  }
+
+  // Semantic checking for this function declaration (in isolation).
+  if (getLangOptions().CPlusPlus) {
+    // C++-specific checks.
+    if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(NewFD)) {
+      CheckConstructor(Constructor);
+    } else if (CXXDestructorDecl *Destructor = 
+                dyn_cast<CXXDestructorDecl>(NewFD)) {
+      CXXRecordDecl *Record = Destructor->getParent();
+      QualType ClassType = Context.getTypeDeclType(Record);
+      
+      // FIXME: Shouldn't we be able to perform thisc heck even when the class
+      // type is dependent? Both gcc and edg can handle that.
+      if (!ClassType->isDependentType()) {
+        DeclarationName Name
+          = Context.DeclarationNames.getCXXDestructorName(
+                                        Context.getCanonicalType(ClassType));
+        if (NewFD->getDeclName() != Name) {
+          Diag(NewFD->getLocation(), diag::err_destructor_name);
+          return NewFD->setInvalidDecl();
+        }
+      }
+
+      Record->setUserDeclaredDestructor(true);
+      // C++ [class]p4: A POD-struct is an aggregate class that has [...] no
+      // user-defined destructor.
+      Record->setPOD(false);
+
+      // C++ [class.dtor]p3: A destructor is trivial if it is an implicitly-
+      // declared destructor.
+      // FIXME: C++0x: don't do this for "= default" destructors
+      Record->setHasTrivialDestructor(false);
+    } else if (CXXConversionDecl *Conversion
+               = dyn_cast<CXXConversionDecl>(NewFD)) {
+      ActOnConversionDeclarator(Conversion);
+    }
+
+    // Find any virtual functions that this function overrides.
+    if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(NewFD)) {
+      if (!Method->isFunctionTemplateSpecialization() && 
+          !Method->getDescribedFunctionTemplate())
+        AddOverriddenMethods(Method->getParent(), Method);
+    }
+
+    // Additional checks for the destructor; make sure we do this after we
+    // figure out whether the destructor is virtual.
+    if (CXXDestructorDecl *Destructor = dyn_cast<CXXDestructorDecl>(NewFD))
+      if (!Destructor->getParent()->isDependentType())
+        CheckDestructor(Destructor);
+
+    // Extra checking for C++ overloaded operators (C++ [over.oper]).
+    if (NewFD->isOverloadedOperator() &&
+        CheckOverloadedOperatorDeclaration(NewFD))
+      return NewFD->setInvalidDecl();
+
+    // Extra checking for C++0x literal operators (C++0x [over.literal]).
+    if (NewFD->getLiteralIdentifier() &&
+        CheckLiteralOperatorDeclaration(NewFD))
+      return NewFD->setInvalidDecl();
+
+    // In C++, check default arguments now that we have merged decls. Unless
+    // the lexical context is the class, because in this case this is done
+    // during delayed parsing anyway.
+    if (!CurContext->isRecord())
+      CheckCXXDefaultArguments(NewFD);
+  }
+}
+
+void Sema::CheckMain(FunctionDecl* FD) {
+  // C++ [basic.start.main]p3:  A program that declares main to be inline
+  //   or static is ill-formed.
+  // C99 6.7.4p4:  In a hosted environment, the inline function specifier
+  //   shall not appear in a declaration of main.
+  // static main is not an error under C99, but we should warn about it.
+  bool isInline = FD->isInlineSpecified();
+  bool isStatic = FD->getStorageClass() == FunctionDecl::Static;
+  if (isInline || isStatic) {
+    unsigned diagID = diag::warn_unusual_main_decl;
+    if (isInline || getLangOptions().CPlusPlus)
+      diagID = diag::err_unusual_main_decl;
+
+    int which = isStatic + (isInline << 1) - 1;
+    Diag(FD->getLocation(), diagID) << which;
+  }
+
+  QualType T = FD->getType();
+  assert(T->isFunctionType() && "function decl is not of function type");
+  const FunctionType* FT = T->getAs<FunctionType>();
+
+  if (!Context.hasSameUnqualifiedType(FT->getResultType(), Context.IntTy)) {
+    // TODO: add a replacement fixit to turn the return type into 'int'.
+    Diag(FD->getTypeSpecStartLoc(), diag::err_main_returns_nonint);
+    FD->setInvalidDecl(true);
+  }
+
+  // Treat protoless main() as nullary.
+  if (isa<FunctionNoProtoType>(FT)) return;
+
+  const FunctionProtoType* FTP = cast<const FunctionProtoType>(FT);
+  unsigned nparams = FTP->getNumArgs();
+  assert(FD->getNumParams() == nparams);
+
+  bool HasExtraParameters = (nparams > 3);
+
+  // Darwin passes an undocumented fourth argument of type char**.  If
+  // other platforms start sprouting these, the logic below will start
+  // getting shifty.
+  if (nparams == 4 &&
+      Context.Target.getTriple().getOS() == llvm::Triple::Darwin)
+    HasExtraParameters = false;
+
+  if (HasExtraParameters) {
+    Diag(FD->getLocation(), diag::err_main_surplus_args) << nparams;
+    FD->setInvalidDecl(true);
+    nparams = 3;
+  }
+
+  // FIXME: a lot of the following diagnostics would be improved
+  // if we had some location information about types.
+
+  QualType CharPP =
+    Context.getPointerType(Context.getPointerType(Context.CharTy));
+  QualType Expected[] = { Context.IntTy, CharPP, CharPP, CharPP };
+
+  for (unsigned i = 0; i < nparams; ++i) {
+    QualType AT = FTP->getArgType(i);
+
+    bool mismatch = true;
+
+    if (Context.hasSameUnqualifiedType(AT, Expected[i]))
+      mismatch = false;
+    else if (Expected[i] == CharPP) {
+      // As an extension, the following forms are okay:
+      //   char const **
+      //   char const * const *
+      //   char * const *
+
+      QualifierCollector qs;
+      const PointerType* PT;
+      if ((PT = qs.strip(AT)->getAs<PointerType>()) &&
+          (PT = qs.strip(PT->getPointeeType())->getAs<PointerType>()) &&
+          (QualType(qs.strip(PT->getPointeeType()), 0) == Context.CharTy)) {
+        qs.removeConst();
+        mismatch = !qs.empty();
+      }
+    }
+
+    if (mismatch) {
+      Diag(FD->getLocation(), diag::err_main_arg_wrong) << i << Expected[i];
+      // TODO: suggest replacing given type with expected type
+      FD->setInvalidDecl(true);
+    }
+  }
+
+  if (nparams == 1 && !FD->isInvalidDecl()) {
+    Diag(FD->getLocation(), diag::warn_main_one_arg);
+  }
+}
+
+bool Sema::CheckForConstantInitializer(Expr *Init, QualType DclT) {
+  // FIXME: Need strict checking.  In C89, we need to check for
+  // any assignment, increment, decrement, function-calls, or
+  // commas outside of a sizeof.  In C99, it's the same list,
+  // except that the aforementioned are allowed in unevaluated
+  // expressions.  Everything else falls under the
+  // "may accept other forms of constant expressions" exception.
+  // (We never end up here for C++, so the constant expression
+  // rules there don't matter.)
+  if (Init->isConstantInitializer(Context))
+    return false;
+  Diag(Init->getExprLoc(), diag::err_init_element_not_constant)
+    << Init->getSourceRange();
+  return true;
+}
+
+void Sema::AddInitializerToDecl(DeclPtrTy dcl, ExprArg init) {
+  AddInitializerToDecl(dcl, move(init), /*DirectInit=*/false);
+}
+
+/// AddInitializerToDecl - Adds the initializer Init to the
+/// declaration dcl. If DirectInit is true, this is C++ direct
+/// initialization rather than copy initialization.
+void Sema::AddInitializerToDecl(DeclPtrTy dcl, ExprArg init, bool DirectInit) {
+  Decl *RealDecl = dcl.getAs<Decl>();
+  // If there is no declaration, there was an error parsing it.  Just ignore
+  // the initializer.
+  if (RealDecl == 0)
+    return;
+
+  if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(RealDecl)) {
+    // With declarators parsed the way they are, the parser cannot
+    // distinguish between a normal initializer and a pure-specifier.
+    // Thus this grotesque test.
+    IntegerLiteral *IL;
+    Expr *Init = static_cast<Expr *>(init.get());
+    if ((IL = dyn_cast<IntegerLiteral>(Init)) && IL->getValue() == 0 &&
+        Context.getCanonicalType(IL->getType()) == Context.IntTy)
+      CheckPureMethod(Method, Init->getSourceRange());
+    else {
+      Diag(Method->getLocation(), diag::err_member_function_initialization)
+        << Method->getDeclName() << Init->getSourceRange();
+      Method->setInvalidDecl();
+    }
+    return;
+  }
+
+  VarDecl *VDecl = dyn_cast<VarDecl>(RealDecl);
+  if (!VDecl) {
+    if (getLangOptions().CPlusPlus &&
+        RealDecl->getLexicalDeclContext()->isRecord() &&
+        isa<NamedDecl>(RealDecl))
+      Diag(RealDecl->getLocation(), diag::err_member_initialization)
+        << cast<NamedDecl>(RealDecl)->getDeclName();
+    else
+      Diag(RealDecl->getLocation(), diag::err_illegal_initializer);
+    RealDecl->setInvalidDecl();
+    return;
+  }
+
+  // A definition must end up with a complete type, which means it must be
+  // complete with the restriction that an array type might be completed by the
+  // initializer; note that later code assumes this restriction.
+  QualType BaseDeclType = VDecl->getType();
+  if (const ArrayType *Array = Context.getAsIncompleteArrayType(BaseDeclType))
+    BaseDeclType = Array->getElementType();
+  if (RequireCompleteType(VDecl->getLocation(), BaseDeclType,
+                          diag::err_typecheck_decl_incomplete_type)) {
+    RealDecl->setInvalidDecl();
+    return;
+  }
+
+  // The variable can not have an abstract class type.
+  if (RequireNonAbstractType(VDecl->getLocation(), VDecl->getType(),
+                             diag::err_abstract_type_in_decl,
+                             AbstractVariableType))
+    VDecl->setInvalidDecl();
+
+  const VarDecl *Def;
+  if ((Def = VDecl->getDefinition()) && Def != VDecl) {
+    Diag(VDecl->getLocation(), diag::err_redefinition)
+      << VDecl->getDeclName();
+    Diag(Def->getLocation(), diag::note_previous_definition);
+    VDecl->setInvalidDecl();
+    return;
+  }
+
+  // Take ownership of the expression, now that we're sure we have somewhere
+  // to put it.
+  Expr *Init = init.takeAs<Expr>();
+  assert(Init && "missing initializer");
+
+  // Capture the variable that is being initialized and the style of
+  // initialization.
+  InitializedEntity Entity = InitializedEntity::InitializeVariable(VDecl);
+  
+  // FIXME: Poor source location information.
+  InitializationKind Kind
+    = DirectInit? InitializationKind::CreateDirect(VDecl->getLocation(),
+                                                   Init->getLocStart(),
+                                                   Init->getLocEnd())
+                : InitializationKind::CreateCopy(VDecl->getLocation(),
+                                                 Init->getLocStart());
+  
+  // Get the decls type and save a reference for later, since
+  // CheckInitializerTypes may change it.
+  QualType DclT = VDecl->getType(), SavT = DclT;
+  if (VDecl->isBlockVarDecl()) {
+    if (VDecl->hasExternalStorage()) { // C99 6.7.8p5
+      Diag(VDecl->getLocation(), diag::err_block_extern_cant_init);
+      VDecl->setInvalidDecl();
+    } else if (!VDecl->isInvalidDecl()) {
+      InitializationSequence InitSeq(*this, Entity, Kind, &Init, 1);
+      OwningExprResult Result = InitSeq.Perform(*this, Entity, Kind,
+                                          MultiExprArg(*this, (void**)&Init, 1),
+                                                &DclT);
+      if (Result.isInvalid()) {
+        VDecl->setInvalidDecl();
+        return;
+      }
+
+      Init = Result.takeAs<Expr>();
+
+      // C++ 3.6.2p2, allow dynamic initialization of static initializers.
+      // Don't check invalid declarations to avoid emitting useless diagnostics.
+      if (!getLangOptions().CPlusPlus && !VDecl->isInvalidDecl()) {
+        if (VDecl->getStorageClass() == VarDecl::Static) // C99 6.7.8p4.
+          CheckForConstantInitializer(Init, DclT);
+      }
+    }
+  } else if (VDecl->isStaticDataMember() &&
+             VDecl->getLexicalDeclContext()->isRecord()) {
+    // This is an in-class initialization for a static data member, e.g.,
+    //
+    // struct S {
+    //   static const int value = 17;
+    // };
+
+    // Attach the initializer
+    VDecl->setInit(Init);
+
+    // C++ [class.mem]p4:
+    //   A member-declarator can contain a constant-initializer only
+    //   if it declares a static member (9.4) of const integral or
+    //   const enumeration type, see 9.4.2.
+    QualType T = VDecl->getType();
+    if (!T->isDependentType() &&
+        (!Context.getCanonicalType(T).isConstQualified() ||
+         !T->isIntegralType())) {
+      Diag(VDecl->getLocation(), diag::err_member_initialization)
+        << VDecl->getDeclName() << Init->getSourceRange();
+      VDecl->setInvalidDecl();
+    } else {
+      // C++ [class.static.data]p4:
+      //   If a static data member is of const integral or const
+      //   enumeration type, its declaration in the class definition
+      //   can specify a constant-initializer which shall be an
+      //   integral constant expression (5.19).
+      if (!Init->isTypeDependent() &&
+          !Init->getType()->isIntegralType()) {
+        // We have a non-dependent, non-integral or enumeration type.
+        Diag(Init->getSourceRange().getBegin(),
+             diag::err_in_class_initializer_non_integral_type)
+          << Init->getType() << Init->getSourceRange();
+        VDecl->setInvalidDecl();
+      } else if (!Init->isTypeDependent() && !Init->isValueDependent()) {
+        // Check whether the expression is a constant expression.
+        llvm::APSInt Value;
+        SourceLocation Loc;
+        if (!Init->isIntegerConstantExpr(Value, Context, &Loc)) {
+          Diag(Loc, diag::err_in_class_initializer_non_constant)
+            << Init->getSourceRange();
+          VDecl->setInvalidDecl();
+        } else if (!VDecl->getType()->isDependentType())
+          ImpCastExprToType(Init, VDecl->getType(), CastExpr::CK_IntegralCast);
+      }
+    }
+  } else if (VDecl->isFileVarDecl()) {
+    if (VDecl->getStorageClass() == VarDecl::Extern && 
+        (!getLangOptions().CPlusPlus || 
+         !Context.getBaseElementType(VDecl->getType()).isConstQualified()))
+      Diag(VDecl->getLocation(), diag::warn_extern_init);
+    if (!VDecl->isInvalidDecl()) {
+      InitializationSequence InitSeq(*this, Entity, Kind, &Init, 1);
+      OwningExprResult Result = InitSeq.Perform(*this, Entity, Kind,
+                                          MultiExprArg(*this, (void**)&Init, 1),
+                                                &DclT);
+      if (Result.isInvalid()) {
+        VDecl->setInvalidDecl();
+        return;
+      }
+
+      Init = Result.takeAs<Expr>();
+    }
+
+    // C++ 3.6.2p2, allow dynamic initialization of static initializers.
+    // Don't check invalid declarations to avoid emitting useless diagnostics.
+    if (!getLangOptions().CPlusPlus && !VDecl->isInvalidDecl()) {
+      // C99 6.7.8p4. All file scoped initializers need to be constant.
+      CheckForConstantInitializer(Init, DclT);
+    }
+  }
+  // If the type changed, it means we had an incomplete type that was
+  // completed by the initializer. For example:
+  //   int ary[] = { 1, 3, 5 };
+  // "ary" transitions from a VariableArrayType to a ConstantArrayType.
+  if (!VDecl->isInvalidDecl() && (DclT != SavT)) {
+    VDecl->setType(DclT);
+    Init->setType(DclT);
+  }
+
+  Init = MaybeCreateCXXExprWithTemporaries(Init);
+  // Attach the initializer to the decl.
+  VDecl->setInit(Init);
+
+  if (getLangOptions().CPlusPlus) {
+    // Make sure we mark the destructor as used if necessary.
+    QualType InitType = VDecl->getType();
+    while (const ArrayType *Array = Context.getAsArrayType(InitType))
+      InitType = Context.getBaseElementType(Array);
+    if (const RecordType *Record = InitType->getAs<RecordType>())
+      FinalizeVarWithDestructor(VDecl, Record);
+  }
+
+  return;
+}
+
+/// ActOnInitializerError - Given that there was an error parsing an
+/// initializer for the given declaration, try to return to some form
+/// of sanity.
+void Sema::ActOnInitializerError(DeclPtrTy dcl) {
+  // Our main concern here is re-establishing invariants like "a
+  // variable's type is either dependent or complete".
+  Decl *D = dcl.getAs<Decl>();
+  if (!D || D->isInvalidDecl()) return;
+
+  VarDecl *VD = dyn_cast<VarDecl>(D);
+  if (!VD) return;
+
+  QualType Ty = VD->getType();
+  if (Ty->isDependentType()) return;
+
+  // Require a complete type.
+  if (RequireCompleteType(VD->getLocation(), 
+                          Context.getBaseElementType(Ty),
+                          diag::err_typecheck_decl_incomplete_type)) {
+    VD->setInvalidDecl();
+    return;
+  }
+
+  // Require an abstract type.
+  if (RequireNonAbstractType(VD->getLocation(), Ty,
+                             diag::err_abstract_type_in_decl,
+                             AbstractVariableType)) {
+    VD->setInvalidDecl();
+    return;
+  }
+
+  // Don't bother complaining about constructors or destructors,
+  // though.
+}
+
+void Sema::ActOnUninitializedDecl(DeclPtrTy dcl,
+                                  bool TypeContainsUndeducedAuto) {
+  Decl *RealDecl = dcl.getAs<Decl>();
+
+  // If there is no declaration, there was an error parsing it. Just ignore it.
+  if (RealDecl == 0)
+    return;
+
+  if (VarDecl *Var = dyn_cast<VarDecl>(RealDecl)) {
+    QualType Type = Var->getType();
+
+    // C++0x [dcl.spec.auto]p3
+    if (TypeContainsUndeducedAuto) {
+      Diag(Var->getLocation(), diag::err_auto_var_requires_init)
+        << Var->getDeclName() << Type;
+      Var->setInvalidDecl();
+      return;
+    }
+
+    switch (Var->isThisDeclarationADefinition()) {
+    case VarDecl::Definition:
+      if (!Var->isStaticDataMember() || !Var->getAnyInitializer())
+        break;
+
+      // We have an out-of-line definition of a static data member
+      // that has an in-class initializer, so we type-check this like
+      // a declaration. 
+      //
+      // Fall through
+      
+    case VarDecl::DeclarationOnly:
+      // It's only a declaration. 
+
+      // Block scope. C99 6.7p7: If an identifier for an object is
+      // declared with no linkage (C99 6.2.2p6), the type for the
+      // object shall be complete.
+      if (!Type->isDependentType() && Var->isBlockVarDecl() && 
+          !Var->getLinkage() && !Var->isInvalidDecl() &&
+          RequireCompleteType(Var->getLocation(), Type,
+                              diag::err_typecheck_decl_incomplete_type))
+        Var->setInvalidDecl();
+
+      // Make sure that the type is not abstract.
+      if (!Type->isDependentType() && !Var->isInvalidDecl() &&
+          RequireNonAbstractType(Var->getLocation(), Type,
+                                 diag::err_abstract_type_in_decl,
+                                 AbstractVariableType))
+        Var->setInvalidDecl();
+      return;
+
+    case VarDecl::TentativeDefinition:
+      // File scope. C99 6.9.2p2: A declaration of an identifier for an
+      // object that has file scope without an initializer, and without a
+      // storage-class specifier or with the storage-class specifier "static",
+      // constitutes a tentative definition. Note: A tentative definition with
+      // external linkage is valid (C99 6.2.2p5).
+      if (!Var->isInvalidDecl()) {
+        if (const IncompleteArrayType *ArrayT
+                                    = Context.getAsIncompleteArrayType(Type)) {
+          if (RequireCompleteType(Var->getLocation(),
+                                  ArrayT->getElementType(),
+                                  diag::err_illegal_decl_array_incomplete_type))
+            Var->setInvalidDecl();
+        } else if (Var->getStorageClass() == VarDecl::Static) {
+          // C99 6.9.2p3: If the declaration of an identifier for an object is
+          // a tentative definition and has internal linkage (C99 6.2.2p3), the
+          // declared type shall not be an incomplete type.
+          // NOTE: code such as the following
+          //     static struct s;
+          //     struct s { int a; };
+          // is accepted by gcc. Hence here we issue a warning instead of
+          // an error and we do not invalidate the static declaration.
+          // NOTE: to avoid multiple warnings, only check the first declaration.
+          if (Var->getPreviousDeclaration() == 0)
+            RequireCompleteType(Var->getLocation(), Type,
+                                diag::ext_typecheck_decl_incomplete_type);
+        }
+      }
+
+      // Record the tentative definition; we're done.
+      if (!Var->isInvalidDecl())
+        TentativeDefinitions.push_back(Var);
+      return;
+    }
+
+    // Provide a specific diagnostic for uninitialized variable
+    // definitions with incomplete array type.
+    if (Type->isIncompleteArrayType()) {
+      Diag(Var->getLocation(),
+           diag::err_typecheck_incomplete_array_needs_initializer);
+      Var->setInvalidDecl();
+      return;
+    }
+
+   // Provide a specific diagnostic for uninitialized variable
+   // definitions with reference type.
+   if (Type->isReferenceType()) {
+     Diag(Var->getLocation(), diag::err_reference_var_requires_init)
+       << Var->getDeclName()
+       << SourceRange(Var->getLocation(), Var->getLocation());
+     Var->setInvalidDecl();
+     return;
+   }
+
+    // Do not attempt to type-check the default initializer for a
+    // variable with dependent type.
+    if (Type->isDependentType())
+      return;
+
+    if (Var->isInvalidDecl())
+      return;
+
+    if (RequireCompleteType(Var->getLocation(), 
+                            Context.getBaseElementType(Type),
+                            diag::err_typecheck_decl_incomplete_type)) {
+      Var->setInvalidDecl();
+      return;
+    }
+
+    // The variable can not have an abstract class type.
+    if (RequireNonAbstractType(Var->getLocation(), Type,
+                               diag::err_abstract_type_in_decl,
+                               AbstractVariableType)) {
+      Var->setInvalidDecl();
+      return;
+    }
+
+    const RecordType *Record
+      = Context.getBaseElementType(Type)->getAs<RecordType>();
+    if (Record && getLangOptions().CPlusPlus && !getLangOptions().CPlusPlus0x &&
+        cast<CXXRecordDecl>(Record->getDecl())->isPOD()) {
+      // C++03 [dcl.init]p9:
+      //   If no initializer is specified for an object, and the
+      //   object is of (possibly cv-qualified) non-POD class type (or
+      //   array thereof), the object shall be default-initialized; if
+      //   the object is of const-qualified type, the underlying class
+      //   type shall have a user-declared default
+      //   constructor. Otherwise, if no initializer is specified for
+      //   a non- static object, the object and its subobjects, if
+      //   any, have an indeterminate initial value); if the object
+      //   or any of its subobjects are of const-qualified type, the
+      //   program is ill-formed.
+      // FIXME: DPG thinks it is very fishy that C++0x disables this.
+    } else {
+      InitializedEntity Entity = InitializedEntity::InitializeVariable(Var);
+      InitializationKind Kind
+        = InitializationKind::CreateDefault(Var->getLocation());
+    
+      InitializationSequence InitSeq(*this, Entity, Kind, 0, 0);
+      OwningExprResult Init = InitSeq.Perform(*this, Entity, Kind,
+                                              MultiExprArg(*this, 0, 0));
+      if (Init.isInvalid())
+        Var->setInvalidDecl();
+      else if (Init.get())
+        Var->setInit(MaybeCreateCXXExprWithTemporaries(Init.takeAs<Expr>()));
+    }
+
+    if (!Var->isInvalidDecl() && getLangOptions().CPlusPlus && Record)
+      FinalizeVarWithDestructor(Var, Record);
+  }
+}
+
+Sema::DeclGroupPtrTy Sema::FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS,
+                                                   DeclPtrTy *Group,
+                                                   unsigned NumDecls) {
+  llvm::SmallVector<Decl*, 8> Decls;
+
+  if (DS.isTypeSpecOwned())
+    Decls.push_back((Decl*)DS.getTypeRep());
+
+  for (unsigned i = 0; i != NumDecls; ++i)
+    if (Decl *D = Group[i].getAs<Decl>())
+      Decls.push_back(D);
+
+  return DeclGroupPtrTy::make(DeclGroupRef::Create(Context,
+                                                   Decls.data(), Decls.size()));
+}
+
+
+/// ActOnParamDeclarator - Called from Parser::ParseFunctionDeclarator()
+/// to introduce parameters into function prototype scope.
+Sema::DeclPtrTy
+Sema::ActOnParamDeclarator(Scope *S, Declarator &D) {
+  const DeclSpec &DS = D.getDeclSpec();
+
+  // Verify C99 6.7.5.3p2: The only SCS allowed is 'register'.
+  VarDecl::StorageClass StorageClass = VarDecl::None;
+  VarDecl::StorageClass StorageClassAsWritten = VarDecl::None;
+  if (DS.getStorageClassSpec() == DeclSpec::SCS_register) {
+    StorageClass = VarDecl::Register;
+    StorageClassAsWritten = VarDecl::Register;
+  } else if (DS.getStorageClassSpec() != DeclSpec::SCS_unspecified) {
+    Diag(DS.getStorageClassSpecLoc(),
+         diag::err_invalid_storage_class_in_func_decl);
+    D.getMutableDeclSpec().ClearStorageClassSpecs();
+  }
+
+  if (D.getDeclSpec().isThreadSpecified())
+    Diag(D.getDeclSpec().getThreadSpecLoc(), diag::err_invalid_thread);
+
+  DiagnoseFunctionSpecifiers(D);
+
+  // Check that there are no default arguments inside the type of this
+  // parameter (C++ only).
+  if (getLangOptions().CPlusPlus)
+    CheckExtraCXXDefaultArguments(D);
+
+  TypeSourceInfo *TInfo = 0;
+  TagDecl *OwnedDecl = 0;
+  QualType parmDeclType = GetTypeForDeclarator(D, S, &TInfo, &OwnedDecl);
+
+  if (getLangOptions().CPlusPlus && OwnedDecl && OwnedDecl->isDefinition()) {
+    // C++ [dcl.fct]p6:
+    //   Types shall not be defined in return or parameter types.
+    Diag(OwnedDecl->getLocation(), diag::err_type_defined_in_param_type)
+      << Context.getTypeDeclType(OwnedDecl);
+  }
+
+  // Check for redeclaration of parameters, e.g. int foo(int x, int x);
+  IdentifierInfo *II = D.getIdentifier();
+  if (II) {
+    LookupResult R(*this, II, D.getIdentifierLoc(), LookupOrdinaryName,
+                   ForRedeclaration);
+    LookupName(R, S);
+    if (R.isSingleResult()) {
+      NamedDecl *PrevDecl = R.getFoundDecl();
+      if (PrevDecl->isTemplateParameter()) {
+        // Maybe we will complain about the shadowed template parameter.
+        DiagnoseTemplateParameterShadow(D.getIdentifierLoc(), PrevDecl);
+        // Just pretend that we didn't see the previous declaration.
+        PrevDecl = 0;
+      } else if (S->isDeclScope(DeclPtrTy::make(PrevDecl))) {
+        Diag(D.getIdentifierLoc(), diag::err_param_redefinition) << II;
+        Diag(PrevDecl->getLocation(), diag::note_previous_declaration);
+
+        // Recover by removing the name
+        II = 0;
+        D.SetIdentifier(0, D.getIdentifierLoc());
+        D.setInvalidType(true);
+      }
+    }
+  }
+
+  // Temporarily put parameter variables in the translation unit, not
+  // the enclosing context.  This prevents them from accidentally
+  // looking like class members in C++.
+  ParmVarDecl *New = CheckParameter(Context.getTranslationUnitDecl(),
+                                    TInfo, parmDeclType, II, 
+                                    D.getIdentifierLoc(),
+                                    StorageClass, StorageClassAsWritten);
+
+  if (D.isInvalidType())
+    New->setInvalidDecl();  
+  
+  // Parameter declarators cannot be qualified (C++ [dcl.meaning]p1).
+  if (D.getCXXScopeSpec().isSet()) {
+    Diag(D.getIdentifierLoc(), diag::err_qualified_param_declarator)
+      << D.getCXXScopeSpec().getRange();
+    New->setInvalidDecl();
+  }
+
+  // Add the parameter declaration into this scope.
+  S->AddDecl(DeclPtrTy::make(New));
+  if (II)
+    IdResolver.AddDecl(New);
+
+  ProcessDeclAttributes(S, New, D);
+
+  if (New->hasAttr<BlocksAttr>()) {
+    Diag(New->getLocation(), diag::err_block_on_nonlocal);
+  }
+  return DeclPtrTy::make(New);
+}
+
+ParmVarDecl *Sema::CheckParameter(DeclContext *DC, 
+                                  TypeSourceInfo *TSInfo, QualType T,
+                                  IdentifierInfo *Name,
+                                  SourceLocation NameLoc,
+                                  VarDecl::StorageClass StorageClass,
+                                  VarDecl::StorageClass StorageClassAsWritten) {
+  ParmVarDecl *New = ParmVarDecl::Create(Context, DC, NameLoc, Name,
+                                         adjustParameterType(T), TSInfo, 
+                                         StorageClass, StorageClassAsWritten,
+                                         0);
+
+  // Parameters can not be abstract class types.
+  // For record types, this is done by the AbstractClassUsageDiagnoser once
+  // the class has been completely parsed.
+  if (!CurContext->isRecord() &&
+      RequireNonAbstractType(NameLoc, T, diag::err_abstract_type_in_decl,
+                             AbstractParamType))
+    New->setInvalidDecl();
+
+  // Parameter declarators cannot be interface types. All ObjC objects are
+  // passed by reference.
+  if (T->isObjCInterfaceType()) {
+    Diag(NameLoc,
+         diag::err_object_cannot_be_passed_returned_by_value) << 1 << T;
+    New->setInvalidDecl();
+  }
+
+  // ISO/IEC TR 18037 S6.7.3: "The type of an object with automatic storage 
+  // duration shall not be qualified by an address-space qualifier."
+  // Since all parameters have automatic store duration, they can not have
+  // an address space.
+  if (T.getAddressSpace() != 0) {
+    Diag(NameLoc, diag::err_arg_with_address_space);
+    New->setInvalidDecl();
+  }   
+
+  return New;
+}
+
+void Sema::ActOnFinishKNRParamDeclarations(Scope *S, Declarator &D,
+                                           SourceLocation LocAfterDecls) {
+  assert(D.getTypeObject(0).Kind == DeclaratorChunk::Function &&
+         "Not a function declarator!");
+  DeclaratorChunk::FunctionTypeInfo &FTI = D.getTypeObject(0).Fun;
+
+  // Verify 6.9.1p6: 'every identifier in the identifier list shall be declared'
+  // for a K&R function.
+  if (!FTI.hasPrototype) {
+    for (int i = FTI.NumArgs; i != 0; /* decrement in loop */) {
+      --i;
+      if (FTI.ArgInfo[i].Param == 0) {
+        llvm::SmallString<256> Code;
+        llvm::raw_svector_ostream(Code) << "  int "
+                                        << FTI.ArgInfo[i].Ident->getName()
+                                        << ";\n";
+        Diag(FTI.ArgInfo[i].IdentLoc, diag::ext_param_not_declared)
+          << FTI.ArgInfo[i].Ident
+          << FixItHint::CreateInsertion(LocAfterDecls, Code.str());
+
+        // Implicitly declare the argument as type 'int' for lack of a better
+        // type.
+        DeclSpec DS;
+        const char* PrevSpec; // unused
+        unsigned DiagID; // unused
+        DS.SetTypeSpecType(DeclSpec::TST_int, FTI.ArgInfo[i].IdentLoc,
+                           PrevSpec, DiagID);
+        Declarator ParamD(DS, Declarator::KNRTypeListContext);
+        ParamD.SetIdentifier(FTI.ArgInfo[i].Ident, FTI.ArgInfo[i].IdentLoc);
+        FTI.ArgInfo[i].Param = ActOnParamDeclarator(S, ParamD);
+      }
+    }
+  }
+}
+
+Sema::DeclPtrTy Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope,
+                                              Declarator &D) {
+  assert(getCurFunctionDecl() == 0 && "Function parsing confused");
+  assert(D.getTypeObject(0).Kind == DeclaratorChunk::Function &&
+         "Not a function declarator!");
+  DeclaratorChunk::FunctionTypeInfo &FTI = D.getTypeObject(0).Fun;
+
+  if (FTI.hasPrototype) {
+    // FIXME: Diagnose arguments without names in C.
+  }
+
+  Scope *ParentScope = FnBodyScope->getParent();
+
+  DeclPtrTy DP = HandleDeclarator(ParentScope, D,
+                                  MultiTemplateParamsArg(*this),
+                                  /*IsFunctionDefinition=*/true);
+  return ActOnStartOfFunctionDef(FnBodyScope, DP);
+}
+
+static bool ShouldWarnAboutMissingPrototype(const FunctionDecl *FD) {
+  // Don't warn about invalid declarations.
+  if (FD->isInvalidDecl())
+    return false;
+
+  // Or declarations that aren't global.
+  if (!FD->isGlobal())
+    return false;
+
+  // Don't warn about C++ member functions.
+  if (isa<CXXMethodDecl>(FD))
+    return false;
+
+  // Don't warn about 'main'.
+  if (FD->isMain())
+    return false;
+
+  // Don't warn about inline functions.
+  if (FD->isInlineSpecified())
+    return false;
+
+  // Don't warn about function templates.
+  if (FD->getDescribedFunctionTemplate())
+    return false;
+
+  // Don't warn about function template specializations.
+  if (FD->isFunctionTemplateSpecialization())
+    return false;
+
+  bool MissingPrototype = true;
+  for (const FunctionDecl *Prev = FD->getPreviousDeclaration();
+       Prev; Prev = Prev->getPreviousDeclaration()) {
+    // Ignore any declarations that occur in function or method
+    // scope, because they aren't visible from the header.
+    if (Prev->getDeclContext()->isFunctionOrMethod())
+      continue;
+      
+    MissingPrototype = !Prev->getType()->isFunctionProtoType();
+    break;
+  }
+    
+  return MissingPrototype;
+}
+
+Sema::DeclPtrTy Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, DeclPtrTy D) {
+  // Clear the last template instantiation error context.
+  LastTemplateInstantiationErrorContext = ActiveTemplateInstantiation();
+  
+  if (!D)
+    return D;
+  FunctionDecl *FD = 0;
+
+  if (FunctionTemplateDecl *FunTmpl
+        = dyn_cast<FunctionTemplateDecl>(D.getAs<Decl>()))
+    FD = FunTmpl->getTemplatedDecl();
+  else
+    FD = cast<FunctionDecl>(D.getAs<Decl>());
+
+  // Enter a new function scope
+  PushFunctionScope();
+
+  // See if this is a redefinition.
+  // But don't complain if we're in GNU89 mode and the previous definition
+  // was an extern inline function.
+  const FunctionDecl *Definition;
+  if (FD->getBody(Definition) &&
+      !canRedefineFunction(Definition, getLangOptions())) {
+    Diag(FD->getLocation(), diag::err_redefinition) << FD->getDeclName();
+    Diag(Definition->getLocation(), diag::note_previous_definition);
+  }
+
+  // Builtin functions cannot be defined.
+  if (unsigned BuiltinID = FD->getBuiltinID()) {
+    if (!Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID)) {
+      Diag(FD->getLocation(), diag::err_builtin_definition) << FD;
+      FD->setInvalidDecl();
+    }
+  }
+
+  // The return type of a function definition must be complete
+  // (C99 6.9.1p3, C++ [dcl.fct]p6).
+  QualType ResultType = FD->getResultType();
+  if (!ResultType->isDependentType() && !ResultType->isVoidType() &&
+      !FD->isInvalidDecl() &&
+      RequireCompleteType(FD->getLocation(), ResultType,
+                          diag::err_func_def_incomplete_result))
+    FD->setInvalidDecl();
+
+  // GNU warning -Wmissing-prototypes:
+  //   Warn if a global function is defined without a previous
+  //   prototype declaration. This warning is issued even if the
+  //   definition itself provides a prototype. The aim is to detect
+  //   global functions that fail to be declared in header files.
+  if (ShouldWarnAboutMissingPrototype(FD))
+    Diag(FD->getLocation(), diag::warn_missing_prototype) << FD;
+
+  if (FnBodyScope)
+    PushDeclContext(FnBodyScope, FD);
+
+  // Check the validity of our function parameters
+  CheckParmsForFunctionDef(FD);
+
+  bool ShouldCheckShadow =
+    Diags.getDiagnosticLevel(diag::warn_decl_shadow) != Diagnostic::Ignored;
+
+  // Introduce our parameters into the function scope
+  for (unsigned p = 0, NumParams = FD->getNumParams(); p < NumParams; ++p) {
+    ParmVarDecl *Param = FD->getParamDecl(p);
+    Param->setOwningFunction(FD);
+
+    // If this has an identifier, add it to the scope stack.
+    if (Param->getIdentifier() && FnBodyScope) {
+      if (ShouldCheckShadow)
+        CheckShadow(FnBodyScope, Param);
+
+      PushOnScopeChains(Param, FnBodyScope);
+    }
+  }
+
+  // Checking attributes of current function definition
+  // dllimport attribute.
+  if (FD->getAttr<DLLImportAttr>() &&
+      (!FD->getAttr<DLLExportAttr>())) {
+    // dllimport attribute cannot be applied to definition.
+    if (!(FD->getAttr<DLLImportAttr>())->isInherited()) {
+      Diag(FD->getLocation(),
+           diag::err_attribute_can_be_applied_only_to_symbol_declaration)
+        << "dllimport";
+      FD->setInvalidDecl();
+      return DeclPtrTy::make(FD);
+    }
+
+    // Visual C++ appears to not think this is an issue, so only issue
+    // a warning when Microsoft extensions are disabled.
+    if (!LangOpts.Microsoft) {
+      // If a symbol previously declared dllimport is later defined, the
+      // attribute is ignored in subsequent references, and a warning is
+      // emitted.
+      Diag(FD->getLocation(),
+           diag::warn_redeclaration_without_attribute_prev_attribute_ignored)
+        << FD->getNameAsCString() << "dllimport";
+    }
+  }
+  return DeclPtrTy::make(FD);
+}
+
+Sema::DeclPtrTy Sema::ActOnFinishFunctionBody(DeclPtrTy D, StmtArg BodyArg) {
+  return ActOnFinishFunctionBody(D, move(BodyArg), false);
+}
+
+Sema::DeclPtrTy Sema::ActOnFinishFunctionBody(DeclPtrTy D, StmtArg BodyArg,
+                                              bool IsInstantiation) {
+  Decl *dcl = D.getAs<Decl>();
+  Stmt *Body = BodyArg.takeAs<Stmt>();
+
+  FunctionDecl *FD = 0;
+  FunctionTemplateDecl *FunTmpl = dyn_cast_or_null<FunctionTemplateDecl>(dcl);
+  if (FunTmpl)
+    FD = FunTmpl->getTemplatedDecl();
+  else
+    FD = dyn_cast_or_null<FunctionDecl>(dcl);
+
+  sema::AnalysisBasedWarnings::Policy WP = AnalysisWarnings.getDefaultPolicy();
+
+  if (FD) {
+    FD->setBody(Body);
+    if (FD->isMain()) {
+      // C and C++ allow for main to automagically return 0.
+      // Implements C++ [basic.start.main]p5 and C99 5.1.2.2.3.
+      FD->setHasImplicitReturnZero(true);
+      WP.disableCheckFallThrough();
+    }
+
+    if (!FD->isInvalidDecl())
+      DiagnoseUnusedParameters(FD->param_begin(), FD->param_end());
+
+    if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(FD))
+      MaybeMarkVirtualMembersReferenced(Method->getLocation(), Method);
+
+    assert(FD == getCurFunctionDecl() && "Function parsing confused");
+  } else if (ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(dcl)) {
+    assert(MD == getCurMethodDecl() && "Method parsing confused");
+    MD->setBody(Body);
+    MD->setEndLoc(Body->getLocEnd());
+    if (!MD->isInvalidDecl())
+      DiagnoseUnusedParameters(MD->param_begin(), MD->param_end());
+  } else {
+    Body->Destroy(Context);
+    return DeclPtrTy();
+  }
+
+  // Verify and clean out per-function state.
+
+  // Check goto/label use.
+  for (llvm::DenseMap<IdentifierInfo*, LabelStmt*>::iterator
+       I = getLabelMap().begin(), E = getLabelMap().end(); I != E; ++I) {
+    LabelStmt *L = I->second;
+
+    // Verify that we have no forward references left.  If so, there was a goto
+    // or address of a label taken, but no definition of it.  Label fwd
+    // definitions are indicated with a null substmt.
+    if (L->getSubStmt() != 0)
+      continue;
+
+    // Emit error.
+    Diag(L->getIdentLoc(), diag::err_undeclared_label_use) << L->getName();
+
+    // At this point, we have gotos that use the bogus label.  Stitch it into
+    // the function body so that they aren't leaked and that the AST is well
+    // formed.
+    if (Body == 0) {
+      // The whole function wasn't parsed correctly, just delete this.
+      L->Destroy(Context);
+      continue;
+    }
+
+    // Otherwise, the body is valid: we want to stitch the label decl into the
+    // function somewhere so that it is properly owned and so that the goto
+    // has a valid target.  Do this by creating a new compound stmt with the
+    // label in it.
+
+    // Give the label a sub-statement.
+    L->setSubStmt(new (Context) NullStmt(L->getIdentLoc()));
+
+    CompoundStmt *Compound = isa<CXXTryStmt>(Body) ?
+                               cast<CXXTryStmt>(Body)->getTryBlock() :
+                               cast<CompoundStmt>(Body);
+    llvm::SmallVector<Stmt*, 64> Elements(Compound->body_begin(),
+                                          Compound->body_end());
+    Elements.push_back(L);
+    Compound->setStmts(Context, Elements.data(), Elements.size());
+  }
+
+  if (Body) {
+    // C++ constructors that have function-try-blocks can't have return
+    // statements in the handlers of that block. (C++ [except.handle]p14)
+    // Verify this.
+    if (FD && isa<CXXConstructorDecl>(FD) && isa<CXXTryStmt>(Body))
+      DiagnoseReturnInConstructorExceptionHandler(cast<CXXTryStmt>(Body));
+    
+    // Verify that that gotos and switch cases don't jump into scopes illegally.
+    // Verify that that gotos and switch cases don't jump into scopes illegally.
+    if (FunctionNeedsScopeChecking() && !hasAnyErrorsInThisFunction())
+      DiagnoseInvalidJumps(Body);
+
+    if (CXXDestructorDecl *Destructor = dyn_cast<CXXDestructorDecl>(dcl))
+      MarkBaseAndMemberDestructorsReferenced(Destructor->getLocation(),
+                                             Destructor->getParent());
+    
+    // If any errors have occurred, clear out any temporaries that may have
+    // been leftover. This ensures that these temporaries won't be picked up for
+    // deletion in some later function.
+    if (PP.getDiagnostics().hasErrorOccurred())
+      ExprTemporaries.clear();
+    else if (!isa<FunctionTemplateDecl>(dcl)) {
+      // Since the body is valid, issue any analysis-based warnings that are
+      // enabled.
+      QualType ResultType;
+      if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(dcl)) {
+        ResultType = FD->getResultType();
+      }
+      else {
+        ObjCMethodDecl *MD = cast<ObjCMethodDecl>(dcl);
+        ResultType = MD->getResultType();
+      }
+      AnalysisWarnings.IssueWarnings(WP, dcl);
+    }
+
+    assert(ExprTemporaries.empty() && "Leftover temporaries in function");
+  }
+  
+  if (!IsInstantiation)
+    PopDeclContext();
+
+  PopFunctionOrBlockScope();
+  
+  // If any errors have occurred, clear out any temporaries that may have
+  // been leftover. This ensures that these temporaries won't be picked up for
+  // deletion in some later function.
+  if (getDiagnostics().hasErrorOccurred())
+    ExprTemporaries.clear();
+  
+  return D;
+}
+
+/// ImplicitlyDefineFunction - An undeclared identifier was used in a function
+/// call, forming a call to an implicitly defined function (per C99 6.5.1p2).
+NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc,
+                                          IdentifierInfo &II, Scope *S) {
+  // Before we produce a declaration for an implicitly defined
+  // function, see whether there was a locally-scoped declaration of
+  // this name as a function or variable. If so, use that
+  // (non-visible) declaration, and complain about it.
+  llvm::DenseMap<DeclarationName, NamedDecl *>::iterator Pos
+    = LocallyScopedExternalDecls.find(&II);
+  if (Pos != LocallyScopedExternalDecls.end()) {
+    Diag(Loc, diag::warn_use_out_of_scope_declaration) << Pos->second;
+    Diag(Pos->second->getLocation(), diag::note_previous_declaration);
+    return Pos->second;
+  }
+
+  // Extension in C99.  Legal in C90, but warn about it.
+  if (II.getName().startswith("__builtin_"))
+    Diag(Loc, diag::warn_builtin_unknown) << &II;
+  else if (getLangOptions().C99)
+    Diag(Loc, diag::ext_implicit_function_decl) << &II;
+  else
+    Diag(Loc, diag::warn_implicit_function_decl) << &II;
+
+  // Set a Declarator for the implicit definition: int foo();
+  const char *Dummy;
+  DeclSpec DS;
+  unsigned DiagID;
+  bool Error = DS.SetTypeSpecType(DeclSpec::TST_int, Loc, Dummy, DiagID);
+  Error = Error; // Silence warning.
+  assert(!Error && "Error setting up implicit decl!");
+  Declarator D(DS, Declarator::BlockContext);
+  D.AddTypeInfo(DeclaratorChunk::getFunction(false, false, SourceLocation(), 0,
+                                             0, 0, false, SourceLocation(),
+                                             false, 0,0,0, Loc, Loc, D),
+                SourceLocation());
+  D.SetIdentifier(&II, Loc);
+
+  // Insert this function into translation-unit scope.
+
+  DeclContext *PrevDC = CurContext;
+  CurContext = Context.getTranslationUnitDecl();
+
+  FunctionDecl *FD =
+ dyn_cast<FunctionDecl>(ActOnDeclarator(TUScope, D).getAs<Decl>());
+  FD->setImplicit();
+
+  CurContext = PrevDC;
+
+  AddKnownFunctionAttributes(FD);
+
+  return FD;
+}
+
+/// \brief Adds any function attributes that we know a priori based on
+/// the declaration of this function.
+///
+/// These attributes can apply both to implicitly-declared builtins
+/// (like __builtin___printf_chk) or to library-declared functions
+/// like NSLog or printf.
+void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) {
+  if (FD->isInvalidDecl())
+    return;
+
+  // If this is a built-in function, map its builtin attributes to
+  // actual attributes.
+  if (unsigned BuiltinID = FD->getBuiltinID()) {
+    // Handle printf-formatting attributes.
+    unsigned FormatIdx;
+    bool HasVAListArg;
+    if (Context.BuiltinInfo.isPrintfLike(BuiltinID, FormatIdx, HasVAListArg)) {
+      if (!FD->getAttr<FormatAttr>())
+        FD->addAttr(::new (Context) FormatAttr(Context, "printf", FormatIdx+1,
+                                               HasVAListArg ? 0 : FormatIdx+2));
+    }
+
+    // Mark const if we don't care about errno and that is the only
+    // thing preventing the function from being const. This allows
+    // IRgen to use LLVM intrinsics for such functions.
+    if (!getLangOptions().MathErrno &&
+        Context.BuiltinInfo.isConstWithoutErrno(BuiltinID)) {
+      if (!FD->getAttr<ConstAttr>())
+        FD->addAttr(::new (Context) ConstAttr());
+    }
+
+    if (Context.BuiltinInfo.isNoReturn(BuiltinID))
+      FD->setType(Context.getNoReturnType(FD->getType()));
+    if (Context.BuiltinInfo.isNoThrow(BuiltinID))
+      FD->addAttr(::new (Context) NoThrowAttr());
+    if (Context.BuiltinInfo.isConst(BuiltinID))
+      FD->addAttr(::new (Context) ConstAttr());
+  }
+
+  IdentifierInfo *Name = FD->getIdentifier();
+  if (!Name)
+    return;
+  if ((!getLangOptions().CPlusPlus &&
+       FD->getDeclContext()->isTranslationUnit()) ||
+      (isa<LinkageSpecDecl>(FD->getDeclContext()) &&
+       cast<LinkageSpecDecl>(FD->getDeclContext())->getLanguage() ==
+       LinkageSpecDecl::lang_c)) {
+    // Okay: this could be a libc/libm/Objective-C function we know
+    // about.
+  } else
+    return;
+
+  if (Name->isStr("NSLog") || Name->isStr("NSLogv")) {
+    // FIXME: NSLog and NSLogv should be target specific
+    if (const FormatAttr *Format = FD->getAttr<FormatAttr>()) {
+      // FIXME: We known better than our headers.
+      const_cast<FormatAttr *>(Format)->setType(Context, "printf");
+    } else
+      FD->addAttr(::new (Context) FormatAttr(Context, "printf", 1,
+                                             Name->isStr("NSLogv") ? 0 : 2));
+  } else if (Name->isStr("asprintf") || Name->isStr("vasprintf")) {
+    // FIXME: asprintf and vasprintf aren't C99 functions. Should they be
+    // target-specific builtins, perhaps?
+    if (!FD->getAttr<FormatAttr>())
+      FD->addAttr(::new (Context) FormatAttr(Context, "printf", 2,
+                                             Name->isStr("vasprintf") ? 0 : 3));
+  }
+}
+
+TypedefDecl *Sema::ParseTypedefDecl(Scope *S, Declarator &D, QualType T,
+                                    TypeSourceInfo *TInfo) {
+  assert(D.getIdentifier() && "Wrong callback for declspec without declarator");
+  assert(!T.isNull() && "GetTypeForDeclarator() returned null type");
+
+  if (!TInfo) {
+    assert(D.isInvalidType() && "no declarator info for valid type");
+    TInfo = Context.getTrivialTypeSourceInfo(T);
+  }
+
+  // Scope manipulation handled by caller.
+  TypedefDecl *NewTD = TypedefDecl::Create(Context, CurContext,
+                                           D.getIdentifierLoc(),
+                                           D.getIdentifier(),
+                                           TInfo);
+
+  if (const TagType *TT = T->getAs<TagType>()) {
+    TagDecl *TD = TT->getDecl();
+
+    // If the TagDecl that the TypedefDecl points to is an anonymous decl
+    // keep track of the TypedefDecl.
+    if (!TD->getIdentifier() && !TD->getTypedefForAnonDecl())
+      TD->setTypedefForAnonDecl(NewTD);
+  }
+
+  if (D.isInvalidType())
+    NewTD->setInvalidDecl();
+  return NewTD;
+}
+
+
+/// \brief Determine whether a tag with a given kind is acceptable
+/// as a redeclaration of the given tag declaration.
+///
+/// \returns true if the new tag kind is acceptable, false otherwise.
+bool Sema::isAcceptableTagRedeclaration(const TagDecl *Previous,
+                                        TagDecl::TagKind NewTag,
+                                        SourceLocation NewTagLoc,
+                                        const IdentifierInfo &Name) {
+  // C++ [dcl.type.elab]p3:
+  //   The class-key or enum keyword present in the
+  //   elaborated-type-specifier shall agree in kind with the
+  //   declaration to which the name in theelaborated-type-specifier
+  //   refers. This rule also applies to the form of
+  //   elaborated-type-specifier that declares a class-name or
+  //   friend class since it can be construed as referring to the
+  //   definition of the class. Thus, in any
+  //   elaborated-type-specifier, the enum keyword shall be used to
+  //   refer to an enumeration (7.2), the union class-keyshall be
+  //   used to refer to a union (clause 9), and either the class or
+  //   struct class-key shall be used to refer to a class (clause 9)
+  //   declared using the class or struct class-key.
+  TagDecl::TagKind OldTag = Previous->getTagKind();
+  if (OldTag == NewTag)
+    return true;
+
+  if ((OldTag == TagDecl::TK_struct || OldTag == TagDecl::TK_class) &&
+      (NewTag == TagDecl::TK_struct || NewTag == TagDecl::TK_class)) {
+    // Warn about the struct/class tag mismatch.
+    bool isTemplate = false;
+    if (const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(Previous))
+      isTemplate = Record->getDescribedClassTemplate();
+
+    Diag(NewTagLoc, diag::warn_struct_class_tag_mismatch)
+      << (NewTag == TagDecl::TK_class)
+      << isTemplate << &Name
+      << FixItHint::CreateReplacement(SourceRange(NewTagLoc),
+                              OldTag == TagDecl::TK_class? "class" : "struct");
+    Diag(Previous->getLocation(), diag::note_previous_use);
+    return true;
+  }
+  return false;
+}
+
+/// ActOnTag - This is invoked when we see 'struct foo' or 'struct {'.  In the
+/// former case, Name will be non-null.  In the later case, Name will be null.
+/// TagSpec indicates what kind of tag this is. TUK indicates whether this is a
+/// reference/declaration/definition of a tag.
+Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
+                               SourceLocation KWLoc, CXXScopeSpec &SS,
+                               IdentifierInfo *Name, SourceLocation NameLoc,
+                               AttributeList *Attr, AccessSpecifier AS,
+                               MultiTemplateParamsArg TemplateParameterLists,
+                               bool &OwnedDecl, bool &IsDependent) {
+  // If this is not a definition, it must have a name.
+  assert((Name != 0 || TUK == TUK_Definition) &&
+         "Nameless record must be a definition!");
+
+  OwnedDecl = false;
+  TagDecl::TagKind Kind = TagDecl::getTagKindForTypeSpec(TagSpec);
+
+  // FIXME: Check explicit specializations more carefully.
+  bool isExplicitSpecialization = false;
+  if (TUK != TUK_Reference) {
+    if (TemplateParameterList *TemplateParams
+          = MatchTemplateParametersToScopeSpecifier(KWLoc, SS,
+                        (TemplateParameterList**)TemplateParameterLists.get(),
+                                              TemplateParameterLists.size(),
+                                                    TUK == TUK_Friend,
+                                                    isExplicitSpecialization)) {
+      if (TemplateParams->size() > 0) {
+        // This is a declaration or definition of a class template (which may
+        // be a member of another template).
+        OwnedDecl = false;
+        DeclResult Result = CheckClassTemplate(S, TagSpec, TUK, KWLoc,
+                                               SS, Name, NameLoc, Attr,
+                                               TemplateParams,
+                                               AS);
+        TemplateParameterLists.release();
+        return Result.get();
+      } else {
+        // The "template<>" header is extraneous.
+        Diag(TemplateParams->getTemplateLoc(), diag::err_template_tag_noparams)
+          << ElaboratedType::getNameForTagKind(Kind) << Name;
+        isExplicitSpecialization = true;
+      }
+    }
+             
+    TemplateParameterLists.release();
+  }
+
+  DeclContext *SearchDC = CurContext;
+  DeclContext *DC = CurContext;
+  bool isStdBadAlloc = false;
+  bool Invalid = false;
+
+  RedeclarationKind Redecl = ForRedeclaration;
+  if (TUK == TUK_Friend || TUK == TUK_Reference)
+    Redecl = NotForRedeclaration;
+
+  LookupResult Previous(*this, Name, NameLoc, LookupTagName, Redecl);
+
+  if (Name && SS.isNotEmpty()) {
+    // We have a nested-name tag ('struct foo::bar').
+
+    // Check for invalid 'foo::'.
+    if (SS.isInvalid()) {
+      Name = 0;
+      goto CreateNewDecl;
+    }
+
+    // If this is a friend or a reference to a class in a dependent
+    // context, don't try to make a decl for it.
+    if (TUK == TUK_Friend || TUK == TUK_Reference) {
+      DC = computeDeclContext(SS, false);
+      if (!DC) {
+        IsDependent = true;
+        return DeclPtrTy();
+      }
+    }
+
+    if (RequireCompleteDeclContext(SS))
+      return DeclPtrTy::make((Decl *)0);
+
+    DC = computeDeclContext(SS, true);
+    SearchDC = DC;
+    // Look-up name inside 'foo::'.
+    LookupQualifiedName(Previous, DC);
+
+    if (Previous.isAmbiguous())
+      return DeclPtrTy();
+
+    if (Previous.empty()) {
+      // Name lookup did not find anything. However, if the
+      // nested-name-specifier refers to the current instantiation,
+      // and that current instantiation has any dependent base
+      // classes, we might find something at instantiation time: treat
+      // this as a dependent elaborated-type-specifier.
+      if (Previous.wasNotFoundInCurrentInstantiation()) {
+        IsDependent = true;
+        return DeclPtrTy();
+      }
+
+      // A tag 'foo::bar' must already exist.
+      Diag(NameLoc, diag::err_not_tag_in_scope) 
+        << Kind << Name << DC << SS.getRange();
+      Name = 0;
+      Invalid = true;
+      goto CreateNewDecl;
+    }
+  } else if (Name) {
+    // If this is a named struct, check to see if there was a previous forward
+    // declaration or definition.
+    // FIXME: We're looking into outer scopes here, even when we
+    // shouldn't be. Doing so can result in ambiguities that we
+    // shouldn't be diagnosing.
+    LookupName(Previous, S);
+
+    // Note:  there used to be some attempt at recovery here.
+    if (Previous.isAmbiguous())
+      return DeclPtrTy();
+
+    if (!getLangOptions().CPlusPlus && TUK != TUK_Reference) {
+      // FIXME: This makes sure that we ignore the contexts associated
+      // with C structs, unions, and enums when looking for a matching
+      // tag declaration or definition. See the similar lookup tweak
+      // in Sema::LookupName; is there a better way to deal with this?
+      while (isa<RecordDecl>(SearchDC) || isa<EnumDecl>(SearchDC))
+        SearchDC = SearchDC->getParent();
+    }
+  }
+
+  if (Previous.isSingleResult() &&
+      Previous.getFoundDecl()->isTemplateParameter()) {
+    // Maybe we will complain about the shadowed template parameter.
+    DiagnoseTemplateParameterShadow(NameLoc, Previous.getFoundDecl());
+    // Just pretend that we didn't see the previous declaration.
+    Previous.clear();
+  }
+
+  if (getLangOptions().CPlusPlus && Name && DC && StdNamespace &&
+      DC->Equals(StdNamespace) && Name->isStr("bad_alloc")) {
+    // This is a declaration of or a reference to "std::bad_alloc".
+    isStdBadAlloc = true;
+    
+    if (Previous.empty() && StdBadAlloc) {
+      // std::bad_alloc has been implicitly declared (but made invisible to
+      // name lookup). Fill in this implicit declaration as the previous 
+      // declaration, so that the declarations get chained appropriately.
+      Previous.addDecl(StdBadAlloc);
+    }
+  }
+
+  // If we didn't find a previous declaration, and this is a reference
+  // (or friend reference), move to the correct scope.  In C++, we
+  // also need to do a redeclaration lookup there, just in case
+  // there's a shadow friend decl.
+  if (Name && Previous.empty() &&
+      (TUK == TUK_Reference || TUK == TUK_Friend)) {
+    if (Invalid) goto CreateNewDecl;
+    assert(SS.isEmpty());
+
+    if (TUK == TUK_Reference) {
+      // C++ [basic.scope.pdecl]p5:
+      //   -- for an elaborated-type-specifier of the form
+      //
+      //          class-key identifier
+      //
+      //      if the elaborated-type-specifier is used in the
+      //      decl-specifier-seq or parameter-declaration-clause of a
+      //      function defined in namespace scope, the identifier is
+      //      declared as a class-name in the namespace that contains
+      //      the declaration; otherwise, except as a friend
+      //      declaration, the identifier is declared in the smallest
+      //      non-class, non-function-prototype scope that contains the
+      //      declaration.
+      //
+      // C99 6.7.2.3p8 has a similar (but not identical!) provision for
+      // C structs and unions.
+      //
+      // It is an error in C++ to declare (rather than define) an enum
+      // type, including via an elaborated type specifier.  We'll
+      // diagnose that later; for now, declare the enum in the same
+      // scope as we would have picked for any other tag type.
+      //
+      // GNU C also supports this behavior as part of its incomplete
+      // enum types extension, while GNU C++ does not.
+      //
+      // Find the context where we'll be declaring the tag.
+      // FIXME: We would like to maintain the current DeclContext as the
+      // lexical context,
+      while (SearchDC->isRecord())
+        SearchDC = SearchDC->getParent();
+
+      // Find the scope where we'll be declaring the tag.
+      while (S->isClassScope() ||
+             (getLangOptions().CPlusPlus &&
+              S->isFunctionPrototypeScope()) ||
+             ((S->getFlags() & Scope::DeclScope) == 0) ||
+             (S->getEntity() &&
+              ((DeclContext *)S->getEntity())->isTransparentContext()))
+        S = S->getParent();
+    } else {
+      assert(TUK == TUK_Friend);
+      // C++ [namespace.memdef]p3:
+      //   If a friend declaration in a non-local class first declares a
+      //   class or function, the friend class or function is a member of
+      //   the innermost enclosing namespace.
+      SearchDC = SearchDC->getEnclosingNamespaceContext();
+    }
+
+    // In C++, we need to do a redeclaration lookup to properly
+    // diagnose some problems.
+    if (getLangOptions().CPlusPlus) {
+      Previous.setRedeclarationKind(ForRedeclaration);
+      LookupQualifiedName(Previous, SearchDC);
+    }
+  }
+
+  if (!Previous.empty()) {
+    NamedDecl *PrevDecl = (*Previous.begin())->getUnderlyingDecl();
+
+    // It's okay to have a tag decl in the same scope as a typedef
+    // which hides a tag decl in the same scope.  Finding this
+    // insanity with a redeclaration lookup can only actually happen
+    // in C++.
+    //
+    // This is also okay for elaborated-type-specifiers, which is
+    // technically forbidden by the current standard but which is
+    // okay according to the likely resolution of an open issue;
+    // see http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#407
+    if (getLangOptions().CPlusPlus) {
+      if (TypedefDecl *TD = dyn_cast<TypedefDecl>(PrevDecl)) {
+        if (const TagType *TT = TD->getUnderlyingType()->getAs<TagType>()) {
+          TagDecl *Tag = TT->getDecl();
+          if (Tag->getDeclName() == Name &&
+              Tag->getDeclContext()->Equals(TD->getDeclContext())) {
+            PrevDecl = Tag;
+            Previous.clear();
+            Previous.addDecl(Tag);
+          }
+        }
+      }
+    }
+
+    if (TagDecl *PrevTagDecl = dyn_cast<TagDecl>(PrevDecl)) {
+      // If this is a use of a previous tag, or if the tag is already declared
+      // in the same scope (so that the definition/declaration completes or
+      // rementions the tag), reuse the decl.
+      if (TUK == TUK_Reference || TUK == TUK_Friend ||
+          isDeclInScope(PrevDecl, SearchDC, S)) {
+        // Make sure that this wasn't declared as an enum and now used as a
+        // struct or something similar.
+        if (!isAcceptableTagRedeclaration(PrevTagDecl, Kind, KWLoc, *Name)) {
+          bool SafeToContinue
+            = (PrevTagDecl->getTagKind() != TagDecl::TK_enum &&
+               Kind != TagDecl::TK_enum);
+          if (SafeToContinue)
+            Diag(KWLoc, diag::err_use_with_wrong_tag)
+              << Name
+              << FixItHint::CreateReplacement(SourceRange(KWLoc),
+                                              PrevTagDecl->getKindName());
+          else
+            Diag(KWLoc, diag::err_use_with_wrong_tag) << Name;
+          Diag(PrevTagDecl->getLocation(), diag::note_previous_use);
+
+          if (SafeToContinue)
+            Kind = PrevTagDecl->getTagKind();
+          else {
+            // Recover by making this an anonymous redefinition.
+            Name = 0;
+            Previous.clear();
+            Invalid = true;
+          }
+        }
+
+        if (!Invalid) {
+          // If this is a use, just return the declaration we found.
+
+          // FIXME: In the future, return a variant or some other clue
+          // for the consumer of this Decl to know it doesn't own it.
+          // For our current ASTs this shouldn't be a problem, but will
+          // need to be changed with DeclGroups.
+          if (TUK == TUK_Reference || TUK == TUK_Friend)
+            return DeclPtrTy::make(PrevTagDecl);
+
+          // Diagnose attempts to redefine a tag.
+          if (TUK == TUK_Definition) {
+            if (TagDecl *Def = PrevTagDecl->getDefinition()) {
+              // If we're defining a specialization and the previous definition
+              // is from an implicit instantiation, don't emit an error
+              // here; we'll catch this in the general case below.
+              if (!isExplicitSpecialization ||
+                  !isa<CXXRecordDecl>(Def) ||
+                  cast<CXXRecordDecl>(Def)->getTemplateSpecializationKind() 
+                                               == TSK_ExplicitSpecialization) {
+                Diag(NameLoc, diag::err_redefinition) << Name;
+                Diag(Def->getLocation(), diag::note_previous_definition);
+                // If this is a redefinition, recover by making this
+                // struct be anonymous, which will make any later
+                // references get the previous definition.
+                Name = 0;
+                Previous.clear();
+                Invalid = true;
+              }
+            } else {
+              // If the type is currently being defined, complain
+              // about a nested redefinition.
+              TagType *Tag = cast<TagType>(Context.getTagDeclType(PrevTagDecl));
+              if (Tag->isBeingDefined()) {
+                Diag(NameLoc, diag::err_nested_redefinition) << Name;
+                Diag(PrevTagDecl->getLocation(),
+                     diag::note_previous_definition);
+                Name = 0;
+                Previous.clear();
+                Invalid = true;
+              }
+            }
+
+            // Okay, this is definition of a previously declared or referenced
+            // tag PrevDecl. We're going to create a new Decl for it.
+          }
+        }
+        // If we get here we have (another) forward declaration or we
+        // have a definition.  Just create a new decl.
+
+      } else {
+        // If we get here, this is a definition of a new tag type in a nested
+        // scope, e.g. "struct foo; void bar() { struct foo; }", just create a
+        // new decl/type.  We set PrevDecl to NULL so that the entities
+        // have distinct types.
+        Previous.clear();
+      }
+      // If we get here, we're going to create a new Decl. If PrevDecl
+      // is non-NULL, it's a definition of the tag declared by
+      // PrevDecl. If it's NULL, we have a new definition.
+
+
+    // Otherwise, PrevDecl is not a tag, but was found with tag
+    // lookup.  This is only actually possible in C++, where a few
+    // things like templates still live in the tag namespace.
+    } else {
+      assert(getLangOptions().CPlusPlus);
+
+      // Use a better diagnostic if an elaborated-type-specifier
+      // found the wrong kind of type on the first
+      // (non-redeclaration) lookup.
+      if ((TUK == TUK_Reference || TUK == TUK_Friend) &&
+          !Previous.isForRedeclaration()) {
+        unsigned Kind = 0;
+        if (isa<TypedefDecl>(PrevDecl)) Kind = 1;
+        else if (isa<ClassTemplateDecl>(PrevDecl)) Kind = 2;
+        Diag(NameLoc, diag::err_tag_reference_non_tag) << Kind;
+        Diag(PrevDecl->getLocation(), diag::note_declared_at);
+        Invalid = true;
+
+      // Otherwise, only diagnose if the declaration is in scope.
+      } else if (!isDeclInScope(PrevDecl, SearchDC, S)) {
+        // do nothing
+
+      // Diagnose implicit declarations introduced by elaborated types.
+      } else if (TUK == TUK_Reference || TUK == TUK_Friend) {
+        unsigned Kind = 0;
+        if (isa<TypedefDecl>(PrevDecl)) Kind = 1;
+        else if (isa<ClassTemplateDecl>(PrevDecl)) Kind = 2;
+        Diag(NameLoc, diag::err_tag_reference_conflict) << Kind;
+        Diag(PrevDecl->getLocation(), diag::note_previous_decl) << PrevDecl;
+        Invalid = true;
+
+      // Otherwise it's a declaration.  Call out a particularly common
+      // case here.
+      } else if (isa<TypedefDecl>(PrevDecl)) {
+        Diag(NameLoc, diag::err_tag_definition_of_typedef)
+          << Name
+          << cast<TypedefDecl>(PrevDecl)->getUnderlyingType();
+        Diag(PrevDecl->getLocation(), diag::note_previous_decl) << PrevDecl;
+        Invalid = true;
+
+      // Otherwise, diagnose.
+      } else {
+        // The tag name clashes with something else in the target scope,
+        // issue an error and recover by making this tag be anonymous.
+        Diag(NameLoc, diag::err_redefinition_different_kind) << Name;
+        Diag(PrevDecl->getLocation(), diag::note_previous_definition);
+        Name = 0;
+        Invalid = true;
+      }
+
+      // The existing declaration isn't relevant to us; we're in a
+      // new scope, so clear out the previous declaration.
+      Previous.clear();
+    }
+  }
+
+CreateNewDecl:
+
+  TagDecl *PrevDecl = 0;
+  if (Previous.isSingleResult())
+    PrevDecl = cast<TagDecl>(Previous.getFoundDecl());
+
+  // If there is an identifier, use the location of the identifier as the
+  // location of the decl, otherwise use the location of the struct/union
+  // keyword.
+  SourceLocation Loc = NameLoc.isValid() ? NameLoc : KWLoc;
+
+  // Otherwise, create a new declaration. If there is a previous
+  // declaration of the same entity, the two will be linked via
+  // PrevDecl.
+  TagDecl *New;
+
+  if (Kind == TagDecl::TK_enum) {
+    // FIXME: Tag decls should be chained to any simultaneous vardecls, e.g.:
+    // enum X { A, B, C } D;    D should chain to X.
+    New = EnumDecl::Create(Context, SearchDC, Loc, Name, KWLoc,
+                           cast_or_null<EnumDecl>(PrevDecl));
+    // If this is an undefined enum, warn.
+    if (TUK != TUK_Definition && !Invalid)  {
+      unsigned DK = getLangOptions().CPlusPlus? diag::err_forward_ref_enum
+                                              : diag::ext_forward_ref_enum;
+      Diag(Loc, DK);
+    }
+  } else {
+    // struct/union/class
+
+    // FIXME: Tag decls should be chained to any simultaneous vardecls, e.g.:
+    // struct X { int A; } D;    D should chain to X.
+    if (getLangOptions().CPlusPlus) {
+      // FIXME: Look for a way to use RecordDecl for simple structs.
+      New = CXXRecordDecl::Create(Context, Kind, SearchDC, Loc, Name, KWLoc,
+                                  cast_or_null<CXXRecordDecl>(PrevDecl));
+      
+      if (isStdBadAlloc && (!StdBadAlloc || StdBadAlloc->isImplicit()))
+        StdBadAlloc = cast<CXXRecordDecl>(New);
+    } else
+      New = RecordDecl::Create(Context, Kind, SearchDC, Loc, Name, KWLoc,
+                               cast_or_null<RecordDecl>(PrevDecl));
+  }
+
+  // Maybe add qualifier info.
+  if (SS.isNotEmpty()) {
+    NestedNameSpecifier *NNS
+      = static_cast<NestedNameSpecifier*>(SS.getScopeRep());
+    New->setQualifierInfo(NNS, SS.getRange());
+  }
+
+  if (Kind != TagDecl::TK_enum) {
+    // Handle #pragma pack: if the #pragma pack stack has non-default
+    // alignment, make up a packed attribute for this decl. These
+    // attributes are checked when the ASTContext lays out the
+    // structure.
+    //
+    // It is important for implementing the correct semantics that this
+    // happen here (in act on tag decl). The #pragma pack stack is
+    // maintained as a result of parser callbacks which can occur at
+    // many points during the parsing of a struct declaration (because
+    // the #pragma tokens are effectively skipped over during the
+    // parsing of the struct).
+    if (unsigned Alignment = getPragmaPackAlignment())
+      New->addAttr(::new (Context) PragmaPackAttr(Alignment * 8));
+  }
+
+  // If this is a specialization of a member class (of a class template),
+  // check the specialization.
+  if (isExplicitSpecialization && CheckMemberSpecialization(New, Previous))
+    Invalid = true;
+      
+  if (Invalid)
+    New->setInvalidDecl();
+
+  if (Attr)
+    ProcessDeclAttributeList(S, New, Attr);
+
+  // If we're declaring or defining a tag in function prototype scope
+  // in C, note that this type can only be used within the function.
+  if (Name && S->isFunctionPrototypeScope() && !getLangOptions().CPlusPlus)
+    Diag(Loc, diag::warn_decl_in_param_list) << Context.getTagDeclType(New);
+
+  // Set the lexical context. If the tag has a C++ scope specifier, the
+  // lexical context will be different from the semantic context.
+  New->setLexicalDeclContext(CurContext);
+
+  // Mark this as a friend decl if applicable.
+  if (TUK == TUK_Friend)
+    New->setObjectOfFriendDecl(/* PreviouslyDeclared = */ !Previous.empty());
+
+  // Set the access specifier.
+  if (!Invalid && SearchDC->isRecord())
+    SetMemberAccessSpecifier(New, PrevDecl, AS);
+
+  if (TUK == TUK_Definition)
+    New->startDefinition();
+
+  // If this has an identifier, add it to the scope stack.
+  if (TUK == TUK_Friend) {
+    // We might be replacing an existing declaration in the lookup tables;
+    // if so, borrow its access specifier.
+    if (PrevDecl)
+      New->setAccess(PrevDecl->getAccess());
+
+    DeclContext *DC = New->getDeclContext()->getLookupContext();
+    DC->makeDeclVisibleInContext(New, /* Recoverable = */ false);
+    if (Name) // can be null along some error paths
+      if (Scope *EnclosingScope = getScopeForDeclContext(S, DC))
+        PushOnScopeChains(New, EnclosingScope, /* AddToContext = */ false);
+  } else if (Name) {
+    S = getNonFieldDeclScope(S);
+    PushOnScopeChains(New, S);
+  } else {
+    CurContext->addDecl(New);
+  }
+
+  // If this is the C FILE type, notify the AST context.
+  if (IdentifierInfo *II = New->getIdentifier())
+    if (!New->isInvalidDecl() &&
+        New->getDeclContext()->getLookupContext()->isTranslationUnit() &&
+        II->isStr("FILE"))
+      Context.setFILEDecl(New);
+
+  OwnedDecl = true;
+  return DeclPtrTy::make(New);
+}
+
+void Sema::ActOnTagStartDefinition(Scope *S, DeclPtrTy TagD) {
+  AdjustDeclIfTemplate(TagD);
+  TagDecl *Tag = cast<TagDecl>(TagD.getAs<Decl>());
+  
+  // Enter the tag context.
+  PushDeclContext(S, Tag);
+}
+
+void Sema::ActOnStartCXXMemberDeclarations(Scope *S, DeclPtrTy TagD,
+                                           SourceLocation LBraceLoc) {
+  AdjustDeclIfTemplate(TagD);
+  CXXRecordDecl *Record = cast<CXXRecordDecl>(TagD.getAs<Decl>());
+
+  FieldCollector->StartClass();
+
+  if (!Record->getIdentifier())
+    return;
+
+  // C++ [class]p2:
+  //   [...] The class-name is also inserted into the scope of the
+  //   class itself; this is known as the injected-class-name. For
+  //   purposes of access checking, the injected-class-name is treated
+  //   as if it were a public member name.
+  CXXRecordDecl *InjectedClassName
+    = CXXRecordDecl::Create(Context, Record->getTagKind(),
+                            CurContext, Record->getLocation(),
+                            Record->getIdentifier(),
+                            Record->getTagKeywordLoc(),
+                            Record);
+  InjectedClassName->setImplicit();
+  InjectedClassName->setAccess(AS_public);
+  if (ClassTemplateDecl *Template = Record->getDescribedClassTemplate())
+      InjectedClassName->setDescribedClassTemplate(Template);
+  PushOnScopeChains(InjectedClassName, S);
+  assert(InjectedClassName->isInjectedClassName() &&
+         "Broken injected-class-name");
+}
+
+// Traverses the class and any nested classes, making a note of any 
+// dynamic classes that have no key function so that we can mark all of
+// their virtual member functions as "used" at the end of the translation
+// unit. This ensures that all functions needed by the vtable will get
+// instantiated/synthesized.
+static void 
+RecordDynamicClassesWithNoKeyFunction(Sema &S, CXXRecordDecl *Record,
+                                      SourceLocation Loc) {
+  // We don't look at dependent or undefined classes.
+  if (Record->isDependentContext() || !Record->isDefinition())
+    return;
+  
+  if (Record->isDynamicClass()) {
+    const CXXMethodDecl *KeyFunction = S.Context.getKeyFunction(Record);
+  
+    if (!KeyFunction)
+      S.ClassesWithUnmarkedVirtualMembers.push_back(std::make_pair(Record,
+                                                                   Loc));
+
+    if ((!KeyFunction || (KeyFunction->getBody() && KeyFunction->isInlined()))
+        && Record->getLinkage() == ExternalLinkage)
+      S.Diag(Record->getLocation(), diag::warn_weak_vtable) << Record;
+  }
+  for (DeclContext::decl_iterator D = Record->decls_begin(), 
+                               DEnd = Record->decls_end();
+       D != DEnd; ++D) {
+    if (CXXRecordDecl *Nested = dyn_cast<CXXRecordDecl>(*D))
+      RecordDynamicClassesWithNoKeyFunction(S, Nested, Loc);
+  }
+}
+
+void Sema::ActOnTagFinishDefinition(Scope *S, DeclPtrTy TagD,
+                                    SourceLocation RBraceLoc) {
+  AdjustDeclIfTemplate(TagD);
+  TagDecl *Tag = cast<TagDecl>(TagD.getAs<Decl>());
+  Tag->setRBraceLoc(RBraceLoc);
+
+  if (isa<CXXRecordDecl>(Tag))
+    FieldCollector->FinishClass();
+
+  // Exit this scope of this tag's definition.
+  PopDeclContext();
+
+  if (isa<CXXRecordDecl>(Tag) && !Tag->getLexicalDeclContext()->isRecord())
+    RecordDynamicClassesWithNoKeyFunction(*this, cast<CXXRecordDecl>(Tag),
+                                          RBraceLoc);
+                                          
+  // Notify the consumer that we've defined a tag.
+  Consumer.HandleTagDeclDefinition(Tag);
+}
+
+void Sema::ActOnTagDefinitionError(Scope *S, DeclPtrTy TagD) {
+  AdjustDeclIfTemplate(TagD);
+  TagDecl *Tag = cast<TagDecl>(TagD.getAs<Decl>());
+  Tag->setInvalidDecl();
+
+  // We're undoing ActOnTagStartDefinition here, not
+  // ActOnStartCXXMemberDeclarations, so we don't have to mess with
+  // the FieldCollector.
+
+  PopDeclContext();  
+}
+
+// Note that FieldName may be null for anonymous bitfields.
+bool Sema::VerifyBitField(SourceLocation FieldLoc, IdentifierInfo *FieldName,
+                          QualType FieldTy, const Expr *BitWidth,
+                          bool *ZeroWidth) {
+  // Default to true; that shouldn't confuse checks for emptiness
+  if (ZeroWidth)
+    *ZeroWidth = true;
+
+  // C99 6.7.2.1p4 - verify the field type.
+  // C++ 9.6p3: A bit-field shall have integral or enumeration type.
+  if (!FieldTy->isDependentType() && !FieldTy->isIntegralType()) {
+    // Handle incomplete types with specific error.
+    if (RequireCompleteType(FieldLoc, FieldTy, diag::err_field_incomplete))
+      return true;
+    if (FieldName)
+      return Diag(FieldLoc, diag::err_not_integral_type_bitfield)
+        << FieldName << FieldTy << BitWidth->getSourceRange();
+    return Diag(FieldLoc, diag::err_not_integral_type_anon_bitfield)
+      << FieldTy << BitWidth->getSourceRange();
+  }
+
+  // If the bit-width is type- or value-dependent, don't try to check
+  // it now.
+  if (BitWidth->isValueDependent() || BitWidth->isTypeDependent())
+    return false;
+
+  llvm::APSInt Value;
+  if (VerifyIntegerConstantExpression(BitWidth, &Value))
+    return true;
+
+  if (Value != 0 && ZeroWidth)
+    *ZeroWidth = false;
+
+  // Zero-width bitfield is ok for anonymous field.
+  if (Value == 0 && FieldName)
+    return Diag(FieldLoc, diag::err_bitfield_has_zero_width) << FieldName;
+
+  if (Value.isSigned() && Value.isNegative()) {
+    if (FieldName)
+      return Diag(FieldLoc, diag::err_bitfield_has_negative_width)
+               << FieldName << Value.toString(10);
+    return Diag(FieldLoc, diag::err_anon_bitfield_has_negative_width)
+      << Value.toString(10);
+  }
+
+  if (!FieldTy->isDependentType()) {
+    uint64_t TypeSize = Context.getTypeSize(FieldTy);
+    if (Value.getZExtValue() > TypeSize) {
+      if (!getLangOptions().CPlusPlus) {
+        if (FieldName) 
+          return Diag(FieldLoc, diag::err_bitfield_width_exceeds_type_size)
+            << FieldName << (unsigned)Value.getZExtValue() 
+            << (unsigned)TypeSize;
+        
+        return Diag(FieldLoc, diag::err_anon_bitfield_width_exceeds_type_size)
+          << (unsigned)Value.getZExtValue() << (unsigned)TypeSize;
+      }
+      
+      if (FieldName)
+        Diag(FieldLoc, diag::warn_bitfield_width_exceeds_type_size)
+          << FieldName << (unsigned)Value.getZExtValue() 
+          << (unsigned)TypeSize;
+      else
+        Diag(FieldLoc, diag::warn_anon_bitfield_width_exceeds_type_size)
+          << (unsigned)Value.getZExtValue() << (unsigned)TypeSize;        
+    }
+  }
+
+  return false;
+}
+
+/// ActOnField - Each field of a struct/union/class is passed into this in order
+/// to create a FieldDecl object for it.
+Sema::DeclPtrTy Sema::ActOnField(Scope *S, DeclPtrTy TagD,
+                                 SourceLocation DeclStart,
+                                 Declarator &D, ExprTy *BitfieldWidth) {
+  FieldDecl *Res = HandleField(S, cast_or_null<RecordDecl>(TagD.getAs<Decl>()),
+                               DeclStart, D, static_cast<Expr*>(BitfieldWidth),
+                               AS_public);
+  return DeclPtrTy::make(Res);
+}
+
+/// HandleField - Analyze a field of a C struct or a C++ data member.
+///
+FieldDecl *Sema::HandleField(Scope *S, RecordDecl *Record,
+                             SourceLocation DeclStart,
+                             Declarator &D, Expr *BitWidth,
+                             AccessSpecifier AS) {
+  IdentifierInfo *II = D.getIdentifier();
+  SourceLocation Loc = DeclStart;
+  if (II) Loc = D.getIdentifierLoc();
+
+  TypeSourceInfo *TInfo = 0;
+  QualType T = GetTypeForDeclarator(D, S, &TInfo);
+  if (getLangOptions().CPlusPlus)
+    CheckExtraCXXDefaultArguments(D);
+
+  DiagnoseFunctionSpecifiers(D);
+
+  if (D.getDeclSpec().isThreadSpecified())
+    Diag(D.getDeclSpec().getThreadSpecLoc(), diag::err_invalid_thread);
+
+  NamedDecl *PrevDecl = LookupSingleName(S, II, Loc, LookupMemberName,
+                                         ForRedeclaration);
+
+  if (PrevDecl && PrevDecl->isTemplateParameter()) {
+    // Maybe we will complain about the shadowed template parameter.
+    DiagnoseTemplateParameterShadow(D.getIdentifierLoc(), PrevDecl);
+    // Just pretend that we didn't see the previous declaration.
+    PrevDecl = 0;
+  }
+
+  if (PrevDecl && !isDeclInScope(PrevDecl, Record, S))
+    PrevDecl = 0;
+
+  bool Mutable
+    = (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_mutable);
+  SourceLocation TSSL = D.getSourceRange().getBegin();
+  FieldDecl *NewFD
+    = CheckFieldDecl(II, T, TInfo, Record, Loc, Mutable, BitWidth, TSSL,
+                     AS, PrevDecl, &D);
+
+  if (NewFD->isInvalidDecl())
+    Record->setInvalidDecl();
+
+  if (NewFD->isInvalidDecl() && PrevDecl) {
+    // Don't introduce NewFD into scope; there's already something
+    // with the same name in the same scope.
+  } else if (II) {
+    PushOnScopeChains(NewFD, S);
+  } else
+    Record->addDecl(NewFD);
+
+  return NewFD;
+}
+
+/// \brief Build a new FieldDecl and check its well-formedness.
+///
+/// This routine builds a new FieldDecl given the fields name, type,
+/// record, etc. \p PrevDecl should refer to any previous declaration
+/// with the same name and in the same scope as the field to be
+/// created.
+///
+/// \returns a new FieldDecl.
+///
+/// \todo The Declarator argument is a hack. It will be removed once
+FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T,
+                                TypeSourceInfo *TInfo,
+                                RecordDecl *Record, SourceLocation Loc,
+                                bool Mutable, Expr *BitWidth,
+                                SourceLocation TSSL,
+                                AccessSpecifier AS, NamedDecl *PrevDecl,
+                                Declarator *D) {
+  IdentifierInfo *II = Name.getAsIdentifierInfo();
+  bool InvalidDecl = false;
+  if (D) InvalidDecl = D->isInvalidType();
+
+  // If we receive a broken type, recover by assuming 'int' and
+  // marking this declaration as invalid.
+  if (T.isNull()) {
+    InvalidDecl = true;
+    T = Context.IntTy;
+  }
+
+  QualType EltTy = Context.getBaseElementType(T);
+  if (!EltTy->isDependentType() &&
+      RequireCompleteType(Loc, EltTy, diag::err_field_incomplete))
+    InvalidDecl = true;
+
+  // C99 6.7.2.1p8: A member of a structure or union may have any type other
+  // than a variably modified type.
+  if (!InvalidDecl && T->isVariablyModifiedType()) {
+    bool SizeIsNegative;
+    QualType FixedTy = TryToFixInvalidVariablyModifiedType(T, Context,
+                                                           SizeIsNegative);
+    if (!FixedTy.isNull()) {
+      Diag(Loc, diag::warn_illegal_constant_array_size);
+      T = FixedTy;
+    } else {
+      if (SizeIsNegative)
+        Diag(Loc, diag::err_typecheck_negative_array_size);
+      else
+        Diag(Loc, diag::err_typecheck_field_variable_size);
+      InvalidDecl = true;
+    }
+  }
+
+  // Fields can not have abstract class types
+  if (!InvalidDecl && RequireNonAbstractType(Loc, T,
+                                             diag::err_abstract_type_in_decl,
+                                             AbstractFieldType))
+    InvalidDecl = true;
+
+  bool ZeroWidth = false;
+  // If this is declared as a bit-field, check the bit-field.
+  if (!InvalidDecl && BitWidth &&
+      VerifyBitField(Loc, II, T, BitWidth, &ZeroWidth)) {
+    InvalidDecl = true;
+    DeleteExpr(BitWidth);
+    BitWidth = 0;
+    ZeroWidth = false;
+  }
+
+  FieldDecl *NewFD = FieldDecl::Create(Context, Record, Loc, II, T, TInfo,
+                                       BitWidth, Mutable);
+  if (InvalidDecl)
+    NewFD->setInvalidDecl();
+
+  if (PrevDecl && !isa<TagDecl>(PrevDecl)) {
+    Diag(Loc, diag::err_duplicate_member) << II;
+    Diag(PrevDecl->getLocation(), diag::note_previous_declaration);
+    NewFD->setInvalidDecl();
+  }
+
+  if (!InvalidDecl && getLangOptions().CPlusPlus) {
+    CXXRecordDecl* CXXRecord = cast<CXXRecordDecl>(Record);
+
+    if (!T->isPODType())
+      CXXRecord->setPOD(false);
+    if (!ZeroWidth)
+      CXXRecord->setEmpty(false);
+
+    if (const RecordType *RT = EltTy->getAs<RecordType>()) {
+      CXXRecordDecl* RDecl = cast<CXXRecordDecl>(RT->getDecl());
+
+      if (!RDecl->hasTrivialConstructor())
+        CXXRecord->setHasTrivialConstructor(false);
+      if (!RDecl->hasTrivialCopyConstructor())
+        CXXRecord->setHasTrivialCopyConstructor(false);
+      if (!RDecl->hasTrivialCopyAssignment())
+        CXXRecord->setHasTrivialCopyAssignment(false);
+      if (!RDecl->hasTrivialDestructor())
+        CXXRecord->setHasTrivialDestructor(false);
+
+      // C++ 9.5p1: An object of a class with a non-trivial
+      // constructor, a non-trivial copy constructor, a non-trivial
+      // destructor, or a non-trivial copy assignment operator
+      // cannot be a member of a union, nor can an array of such
+      // objects.
+      // TODO: C++0x alters this restriction significantly.
+      if (Record->isUnion()) {
+        // We check for copy constructors before constructors
+        // because otherwise we'll never get complaints about
+        // copy constructors.
+
+        CXXSpecialMember member = CXXInvalid;
+        if (!RDecl->hasTrivialCopyConstructor())
+          member = CXXCopyConstructor;
+        else if (!RDecl->hasTrivialConstructor())
+          member = CXXConstructor;
+        else if (!RDecl->hasTrivialCopyAssignment())
+          member = CXXCopyAssignment;
+        else if (!RDecl->hasTrivialDestructor())
+          member = CXXDestructor;
+
+        if (member != CXXInvalid) {
+          Diag(Loc, diag::err_illegal_union_member) << Name << member;
+          DiagnoseNontrivial(RT, member);
+          NewFD->setInvalidDecl();
+        }
+      }
+    }
+  }
+
+  // FIXME: We need to pass in the attributes given an AST
+  // representation, not a parser representation.
+  if (D)
+    // FIXME: What to pass instead of TUScope?
+    ProcessDeclAttributes(TUScope, NewFD, *D);
+
+  if (T.isObjCGCWeak())
+    Diag(Loc, diag::warn_attribute_weak_on_field);
+
+  NewFD->setAccess(AS);
+
+  // C++ [dcl.init.aggr]p1:
+  //   An aggregate is an array or a class (clause 9) with [...] no
+  //   private or protected non-static data members (clause 11).
+  // A POD must be an aggregate.
+  if (getLangOptions().CPlusPlus &&
+      (AS == AS_private || AS == AS_protected)) {
+    CXXRecordDecl *CXXRecord = cast<CXXRecordDecl>(Record);
+    CXXRecord->setAggregate(false);
+    CXXRecord->setPOD(false);
+  }
+
+  return NewFD;
+}
+
+/// DiagnoseNontrivial - Given that a class has a non-trivial
+/// special member, figure out why.
+void Sema::DiagnoseNontrivial(const RecordType* T, CXXSpecialMember member) {
+  QualType QT(T, 0U);
+  CXXRecordDecl* RD = cast<CXXRecordDecl>(T->getDecl());
+
+  // Check whether the member was user-declared.
+  switch (member) {
+  case CXXInvalid:
+    break;
+
+  case CXXConstructor:
+    if (RD->hasUserDeclaredConstructor()) {
+      typedef CXXRecordDecl::ctor_iterator ctor_iter;
+      for (ctor_iter ci = RD->ctor_begin(), ce = RD->ctor_end(); ci != ce;++ci){
+        const FunctionDecl *body = 0;
+        ci->getBody(body);
+        if (!body || !cast<CXXConstructorDecl>(body)->isImplicitlyDefined()) {
+          SourceLocation CtorLoc = ci->getLocation();
+          Diag(CtorLoc, diag::note_nontrivial_user_defined) << QT << member;
+          return;
+        }
+      }
+
+      assert(0 && "found no user-declared constructors");
+      return;
+    }
+    break;
+
+  case CXXCopyConstructor:
+    if (RD->hasUserDeclaredCopyConstructor()) {
+      SourceLocation CtorLoc =
+        RD->getCopyConstructor(Context, 0)->getLocation();
+      Diag(CtorLoc, diag::note_nontrivial_user_defined) << QT << member;
+      return;
+    }
+    break;
+
+  case CXXCopyAssignment:
+    if (RD->hasUserDeclaredCopyAssignment()) {
+      // FIXME: this should use the location of the copy
+      // assignment, not the type.
+      SourceLocation TyLoc = RD->getSourceRange().getBegin();
+      Diag(TyLoc, diag::note_nontrivial_user_defined) << QT << member;
+      return;
+    }
+    break;
+
+  case CXXDestructor:
+    if (RD->hasUserDeclaredDestructor()) {
+      SourceLocation DtorLoc = RD->getDestructor(Context)->getLocation();
+      Diag(DtorLoc, diag::note_nontrivial_user_defined) << QT << member;
+      return;
+    }
+    break;
+  }
+
+  typedef CXXRecordDecl::base_class_iterator base_iter;
+
+  // Virtual bases and members inhibit trivial copying/construction,
+  // but not trivial destruction.
+  if (member != CXXDestructor) {
+    // Check for virtual bases.  vbases includes indirect virtual bases,
+    // so we just iterate through the direct bases.
+    for (base_iter bi = RD->bases_begin(), be = RD->bases_end(); bi != be; ++bi)
+      if (bi->isVirtual()) {
+        SourceLocation BaseLoc = bi->getSourceRange().getBegin();
+        Diag(BaseLoc, diag::note_nontrivial_has_virtual) << QT << 1;
+        return;
+      }
+
+    // Check for virtual methods.
+    typedef CXXRecordDecl::method_iterator meth_iter;
+    for (meth_iter mi = RD->method_begin(), me = RD->method_end(); mi != me;
+         ++mi) {
+      if (mi->isVirtual()) {
+        SourceLocation MLoc = mi->getSourceRange().getBegin();
+        Diag(MLoc, diag::note_nontrivial_has_virtual) << QT << 0;
+        return;
+      }
+    }
+  }
+
+  bool (CXXRecordDecl::*hasTrivial)() const;
+  switch (member) {
+  case CXXConstructor:
+    hasTrivial = &CXXRecordDecl::hasTrivialConstructor; break;
+  case CXXCopyConstructor:
+    hasTrivial = &CXXRecordDecl::hasTrivialCopyConstructor; break;
+  case CXXCopyAssignment:
+    hasTrivial = &CXXRecordDecl::hasTrivialCopyAssignment; break;
+  case CXXDestructor:
+    hasTrivial = &CXXRecordDecl::hasTrivialDestructor; break;
+  default:
+    assert(0 && "unexpected special member"); return;
+  }
+
+  // Check for nontrivial bases (and recurse).
+  for (base_iter bi = RD->bases_begin(), be = RD->bases_end(); bi != be; ++bi) {
+    const RecordType *BaseRT = bi->getType()->getAs<RecordType>();
+    assert(BaseRT && "Don't know how to handle dependent bases");
+    CXXRecordDecl *BaseRecTy = cast<CXXRecordDecl>(BaseRT->getDecl());
+    if (!(BaseRecTy->*hasTrivial)()) {
+      SourceLocation BaseLoc = bi->getSourceRange().getBegin();
+      Diag(BaseLoc, diag::note_nontrivial_has_nontrivial) << QT << 1 << member;
+      DiagnoseNontrivial(BaseRT, member);
+      return;
+    }
+  }
+
+  // Check for nontrivial members (and recurse).
+  typedef RecordDecl::field_iterator field_iter;
+  for (field_iter fi = RD->field_begin(), fe = RD->field_end(); fi != fe;
+       ++fi) {
+    QualType EltTy = Context.getBaseElementType((*fi)->getType());
+    if (const RecordType *EltRT = EltTy->getAs<RecordType>()) {
+      CXXRecordDecl* EltRD = cast<CXXRecordDecl>(EltRT->getDecl());
+
+      if (!(EltRD->*hasTrivial)()) {
+        SourceLocation FLoc = (*fi)->getLocation();
+        Diag(FLoc, diag::note_nontrivial_has_nontrivial) << QT << 0 << member;
+        DiagnoseNontrivial(EltRT, member);
+        return;
+      }
+    }
+  }
+
+  assert(0 && "found no explanation for non-trivial member");
+}
+
+/// TranslateIvarVisibility - Translate visibility from a token ID to an
+///  AST enum value.
+static ObjCIvarDecl::AccessControl
+TranslateIvarVisibility(tok::ObjCKeywordKind ivarVisibility) {
+  switch (ivarVisibility) {
+  default: assert(0 && "Unknown visitibility kind");
+  case tok::objc_private: return ObjCIvarDecl::Private;
+  case tok::objc_public: return ObjCIvarDecl::Public;
+  case tok::objc_protected: return ObjCIvarDecl::Protected;
+  case tok::objc_package: return ObjCIvarDecl::Package;
+  }
+}
+
+/// ActOnIvar - Each ivar field of an objective-c class is passed into this
+/// in order to create an IvarDecl object for it.
+Sema::DeclPtrTy Sema::ActOnIvar(Scope *S,
+                                SourceLocation DeclStart,
+                                DeclPtrTy IntfDecl,
+                                Declarator &D, ExprTy *BitfieldWidth,
+                                tok::ObjCKeywordKind Visibility) {
+
+  IdentifierInfo *II = D.getIdentifier();
+  Expr *BitWidth = (Expr*)BitfieldWidth;
+  SourceLocation Loc = DeclStart;
+  if (II) Loc = D.getIdentifierLoc();
+
+  // FIXME: Unnamed fields can be handled in various different ways, for
+  // example, unnamed unions inject all members into the struct namespace!
+
+  TypeSourceInfo *TInfo = 0;
+  QualType T = GetTypeForDeclarator(D, S, &TInfo);
+
+  if (BitWidth) {
+    // 6.7.2.1p3, 6.7.2.1p4
+    if (VerifyBitField(Loc, II, T, BitWidth)) {
+      D.setInvalidType();
+      DeleteExpr(BitWidth);
+      BitWidth = 0;
+    }
+  } else {
+    // Not a bitfield.
+
+    // validate II.
+
+  }
+  if (T->isReferenceType()) {
+    Diag(Loc, diag::err_ivar_reference_type);
+    D.setInvalidType();
+  }
+  // C99 6.7.2.1p8: A member of a structure or union may have any type other
+  // than a variably modified type.
+  else if (T->isVariablyModifiedType()) {
+    Diag(Loc, diag::err_typecheck_ivar_variable_size);
+    D.setInvalidType();
+  }
+
+  // Get the visibility (access control) for this ivar.
+  ObjCIvarDecl::AccessControl ac =
+    Visibility != tok::objc_not_keyword ? TranslateIvarVisibility(Visibility)
+                                        : ObjCIvarDecl::None;
+  // Must set ivar's DeclContext to its enclosing interface.
+  ObjCContainerDecl *EnclosingDecl = IntfDecl.getAs<ObjCContainerDecl>();
+  ObjCContainerDecl *EnclosingContext;
+  if (ObjCImplementationDecl *IMPDecl =
+      dyn_cast<ObjCImplementationDecl>(EnclosingDecl)) {
+    // Case of ivar declared in an implementation. Context is that of its class.
+    EnclosingContext = IMPDecl->getClassInterface();
+    assert(EnclosingContext && "Implementation has no class interface!");
+  } else {
+    if (ObjCCategoryDecl *CDecl = 
+        dyn_cast<ObjCCategoryDecl>(EnclosingDecl)) {
+      if (!LangOpts.ObjCNonFragileABI2 || !CDecl->IsClassExtension()) {
+        Diag(Loc, diag::err_misplaced_ivar) << CDecl->IsClassExtension();
+        return DeclPtrTy();
+      }
+    }
+    EnclosingContext = EnclosingDecl;
+  }
+
+  // Construct the decl.
+  ObjCIvarDecl *NewID = ObjCIvarDecl::Create(Context,
+                                             EnclosingContext, Loc, II, T,
+                                             TInfo, ac, (Expr *)BitfieldWidth);
+
+  if (II) {
+    NamedDecl *PrevDecl = LookupSingleName(S, II, Loc, LookupMemberName,
+                                           ForRedeclaration);
+    if (PrevDecl && isDeclInScope(PrevDecl, EnclosingContext, S)
+        && !isa<TagDecl>(PrevDecl)) {
+      Diag(Loc, diag::err_duplicate_member) << II;
+      Diag(PrevDecl->getLocation(), diag::note_previous_declaration);
+      NewID->setInvalidDecl();
+    }
+  }
+
+  // Process attributes attached to the ivar.
+  ProcessDeclAttributes(S, NewID, D);
+
+  if (D.isInvalidType())
+    NewID->setInvalidDecl();
+
+  if (II) {
+    // FIXME: When interfaces are DeclContexts, we'll need to add
+    // these to the interface.
+    S->AddDecl(DeclPtrTy::make(NewID));
+    IdResolver.AddDecl(NewID);
+  }
+
+  return DeclPtrTy::make(NewID);
+}
+
+void Sema::ActOnFields(Scope* S,
+                       SourceLocation RecLoc, DeclPtrTy RecDecl,
+                       DeclPtrTy *Fields, unsigned NumFields,
+                       SourceLocation LBrac, SourceLocation RBrac,
+                       AttributeList *Attr) {
+  Decl *EnclosingDecl = RecDecl.getAs<Decl>();
+  assert(EnclosingDecl && "missing record or interface decl");
+
+  // If the decl this is being inserted into is invalid, then it may be a
+  // redeclaration or some other bogus case.  Don't try to add fields to it.
+  if (EnclosingDecl->isInvalidDecl()) {
+    // FIXME: Deallocate fields?
+    return;
+  }
+
+
+  // Verify that all the fields are okay.
+  unsigned NumNamedMembers = 0;
+  llvm::SmallVector<FieldDecl*, 32> RecFields;
+
+  RecordDecl *Record = dyn_cast<RecordDecl>(EnclosingDecl);
+  for (unsigned i = 0; i != NumFields; ++i) {
+    FieldDecl *FD = cast<FieldDecl>(Fields[i].getAs<Decl>());
+
+    // Get the type for the field.
+    Type *FDTy = FD->getType().getTypePtr();
+
+    if (!FD->isAnonymousStructOrUnion()) {
+      // Remember all fields written by the user.
+      RecFields.push_back(FD);
+    }
+
+    // If the field is already invalid for some reason, don't emit more
+    // diagnostics about it.
+    if (FD->isInvalidDecl()) {
+      EnclosingDecl->setInvalidDecl();
+      continue;
+    }
+
+    // C99 6.7.2.1p2:
+    //   A structure or union shall not contain a member with
+    //   incomplete or function type (hence, a structure shall not
+    //   contain an instance of itself, but may contain a pointer to
+    //   an instance of itself), except that the last member of a
+    //   structure with more than one named member may have incomplete
+    //   array type; such a structure (and any union containing,
+    //   possibly recursively, a member that is such a structure)
+    //   shall not be a member of a structure or an element of an
+    //   array.
+    if (FDTy->isFunctionType()) {
+      // Field declared as a function.
+      Diag(FD->getLocation(), diag::err_field_declared_as_function)
+        << FD->getDeclName();
+      FD->setInvalidDecl();
+      EnclosingDecl->setInvalidDecl();
+      continue;
+    } else if (FDTy->isIncompleteArrayType() && i == NumFields - 1 &&
+               Record && Record->isStruct()) {
+      // Flexible array member.
+      if (NumNamedMembers < 1) {
+        Diag(FD->getLocation(), diag::err_flexible_array_empty_struct)
+          << FD->getDeclName();
+        FD->setInvalidDecl();
+        EnclosingDecl->setInvalidDecl();
+        continue;
+      }
+      // Okay, we have a legal flexible array member at the end of the struct.
+      if (Record)
+        Record->setHasFlexibleArrayMember(true);
+    } else if (!FDTy->isDependentType() &&
+               RequireCompleteType(FD->getLocation(), FD->getType(),
+                                   diag::err_field_incomplete)) {
+      // Incomplete type
+      FD->setInvalidDecl();
+      EnclosingDecl->setInvalidDecl();
+      continue;
+    } else if (const RecordType *FDTTy = FDTy->getAs<RecordType>()) {
+      if (FDTTy->getDecl()->hasFlexibleArrayMember()) {
+        // If this is a member of a union, then entire union becomes "flexible".
+        if (Record && Record->isUnion()) {
+          Record->setHasFlexibleArrayMember(true);
+        } else {
+          // If this is a struct/class and this is not the last element, reject
+          // it.  Note that GCC supports variable sized arrays in the middle of
+          // structures.
+          if (i != NumFields-1)
+            Diag(FD->getLocation(), diag::ext_variable_sized_type_in_struct)
+              << FD->getDeclName() << FD->getType();
+          else {
+            // We support flexible arrays at the end of structs in
+            // other structs as an extension.
+            Diag(FD->getLocation(), diag::ext_flexible_array_in_struct)
+              << FD->getDeclName();
+            if (Record)
+              Record->setHasFlexibleArrayMember(true);
+          }
+        }
+      }
+      if (Record && FDTTy->getDecl()->hasObjectMember())
+        Record->setHasObjectMember(true);
+    } else if (FDTy->isObjCInterfaceType()) {
+      /// A field cannot be an Objective-c object
+      Diag(FD->getLocation(), diag::err_statically_allocated_object);
+      FD->setInvalidDecl();
+      EnclosingDecl->setInvalidDecl();
+      continue;
+    } else if (getLangOptions().ObjC1 &&
+               getLangOptions().getGCMode() != LangOptions::NonGC &&
+               Record &&
+               (FD->getType()->isObjCObjectPointerType() ||
+                FD->getType().isObjCGCStrong()))
+      Record->setHasObjectMember(true);
+    // Keep track of the number of named members.
+    if (FD->getIdentifier())
+      ++NumNamedMembers;
+  }
+
+  // Okay, we successfully defined 'Record'.
+  if (Record) {
+    Record->completeDefinition();
+  } else {
+    ObjCIvarDecl **ClsFields =
+      reinterpret_cast<ObjCIvarDecl**>(RecFields.data());
+    if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(EnclosingDecl)) {
+      ID->setLocEnd(RBrac);
+      // Add ivar's to class's DeclContext.
+      for (unsigned i = 0, e = RecFields.size(); i != e; ++i) {
+        ClsFields[i]->setLexicalDeclContext(ID);
+        ID->addDecl(ClsFields[i]);
+      }
+      // Must enforce the rule that ivars in the base classes may not be
+      // duplicates.
+      if (ID->getSuperClass())
+        DiagnoseDuplicateIvars(ID, ID->getSuperClass());
+    } else if (ObjCImplementationDecl *IMPDecl =
+                  dyn_cast<ObjCImplementationDecl>(EnclosingDecl)) {
+      assert(IMPDecl && "ActOnFields - missing ObjCImplementationDecl");
+      for (unsigned I = 0, N = RecFields.size(); I != N; ++I)
+        // Ivar declared in @implementation never belongs to the implementation.
+        // Only it is in implementation's lexical context.
+        ClsFields[I]->setLexicalDeclContext(IMPDecl);
+      CheckImplementationIvars(IMPDecl, ClsFields, RecFields.size(), RBrac);
+    } else if (ObjCCategoryDecl *CDecl = 
+                dyn_cast<ObjCCategoryDecl>(EnclosingDecl)) {
+      // case of ivars in class extension; all other cases have been
+      // reported as errors elsewhere.
+      // FIXME. Class extension does not have a LocEnd field.
+      // CDecl->setLocEnd(RBrac);
+      // Add ivar's to class extension's DeclContext.
+      for (unsigned i = 0, e = RecFields.size(); i != e; ++i) {
+        ClsFields[i]->setLexicalDeclContext(CDecl);
+        CDecl->addDecl(ClsFields[i]);
+      }
+    }
+  }
+
+  if (Attr)
+    ProcessDeclAttributeList(S, Record, Attr);
+}
+
+/// \brief Determine whether the given integral value is representable within
+/// the given type T.
+static bool isRepresentableIntegerValue(ASTContext &Context,
+                                        llvm::APSInt &Value,
+                                        QualType T) {
+  assert(T->isIntegralType() && "Integral type required!");
+  unsigned BitWidth = Context.getIntWidth(T);
+  
+  if (Value.isUnsigned() || Value.isNonNegative())
+    return Value.getActiveBits() < BitWidth;
+  
+  return Value.getMinSignedBits() <= BitWidth;
+}
+
+// \brief Given an integral type, return the next larger integral type
+// (or a NULL type of no such type exists).
+static QualType getNextLargerIntegralType(ASTContext &Context, QualType T) {
+  // FIXME: Int128/UInt128 support, which also needs to be introduced into 
+  // enum checking below.
+  assert(T->isIntegralType() && "Integral type required!");
+  const unsigned NumTypes = 4;
+  QualType SignedIntegralTypes[NumTypes] = { 
+    Context.ShortTy, Context.IntTy, Context.LongTy, Context.LongLongTy
+  };
+  QualType UnsignedIntegralTypes[NumTypes] = { 
+    Context.UnsignedShortTy, Context.UnsignedIntTy, Context.UnsignedLongTy, 
+    Context.UnsignedLongLongTy
+  };
+  
+  unsigned BitWidth = Context.getTypeSize(T);
+  QualType *Types = T->isSignedIntegerType()? SignedIntegralTypes
+                                            : UnsignedIntegralTypes;
+  for (unsigned I = 0; I != NumTypes; ++I)
+    if (Context.getTypeSize(Types[I]) > BitWidth)
+      return Types[I];
+  
+  return QualType();
+}
+
+EnumConstantDecl *Sema::CheckEnumConstant(EnumDecl *Enum,
+                                          EnumConstantDecl *LastEnumConst,
+                                          SourceLocation IdLoc,
+                                          IdentifierInfo *Id,
+                                          ExprArg val) {
+  Expr *Val = (Expr *)val.get();
+
+  unsigned IntWidth = Context.Target.getIntWidth();
+  llvm::APSInt EnumVal(IntWidth);
+  QualType EltTy;
+  if (Val) {
+    if (Enum->isDependentType() || Val->isTypeDependent())
+      EltTy = Context.DependentTy;
+    else {
+      // C99 6.7.2.2p2: Make sure we have an integer constant expression.
+      SourceLocation ExpLoc;
+      if (!Val->isValueDependent() &&
+          VerifyIntegerConstantExpression(Val, &EnumVal)) {
+        Val = 0;
+      } else {        
+        if (!getLangOptions().CPlusPlus) {
+          // C99 6.7.2.2p2:
+          //   The expression that defines the value of an enumeration constant
+          //   shall be an integer constant expression that has a value 
+          //   representable as an int.
+          
+          // Complain if the value is not representable in an int.
+          if (!isRepresentableIntegerValue(Context, EnumVal, Context.IntTy))
+            Diag(IdLoc, diag::ext_enum_value_not_int)
+              << EnumVal.toString(10) << Val->getSourceRange()
+              << (EnumVal.isUnsigned() || EnumVal.isNonNegative());
+          else if (!Context.hasSameType(Val->getType(), Context.IntTy)) {
+            // Force the type of the expression to 'int'.
+            ImpCastExprToType(Val, Context.IntTy, CastExpr::CK_IntegralCast);
+            
+            if (Val != val.get()) {
+              val.release();
+              val = Val;
+            }
+          }
+        }
+        
+        // C++0x [dcl.enum]p5:
+        //   If the underlying type is not fixed, the type of each enumerator
+        //   is the type of its initializing value:
+        //     - If an initializer is specified for an enumerator, the 
+        //       initializing value has the same type as the expression.
+        EltTy = Val->getType();
+      }
+    }
+  }
+
+  if (!Val) {
+    if (Enum->isDependentType())
+      EltTy = Context.DependentTy;
+    else if (!LastEnumConst) {
+      // C++0x [dcl.enum]p5:
+      //   If the underlying type is not fixed, the type of each enumerator
+      //   is the type of its initializing value:
+      //     - If no initializer is specified for the first enumerator, the 
+      //       initializing value has an unspecified integral type.
+      //
+      // GCC uses 'int' for its unspecified integral type, as does 
+      // C99 6.7.2.2p3.
+      EltTy = Context.IntTy;
+    } else {
+      // Assign the last value + 1.
+      EnumVal = LastEnumConst->getInitVal();
+      ++EnumVal;
+      EltTy = LastEnumConst->getType();
+
+      // Check for overflow on increment.
+      if (EnumVal < LastEnumConst->getInitVal()) {
+        // C++0x [dcl.enum]p5:
+        //   If the underlying type is not fixed, the type of each enumerator
+        //   is the type of its initializing value:
+        //
+        //     - Otherwise the type of the initializing value is the same as
+        //       the type of the initializing value of the preceding enumerator
+        //       unless the incremented value is not representable in that type,
+        //       in which case the type is an unspecified integral type 
+        //       sufficient to contain the incremented value. If no such type
+        //       exists, the program is ill-formed.
+        QualType T = getNextLargerIntegralType(Context, EltTy);
+        if (T.isNull()) {
+          // There is no integral type larger enough to represent this 
+          // value. Complain, then allow the value to wrap around.
+          EnumVal = LastEnumConst->getInitVal();
+          EnumVal.zext(EnumVal.getBitWidth() * 2);
+          Diag(IdLoc, diag::warn_enumerator_too_large)
+            << EnumVal.toString(10);
+        } else {
+          EltTy = T;
+        }
+        
+        // Retrieve the last enumerator's value, extent that type to the
+        // type that is supposed to be large enough to represent the incremented
+        // value, then increment.
+        EnumVal = LastEnumConst->getInitVal();
+        EnumVal.setIsSigned(EltTy->isSignedIntegerType());
+        EnumVal.zextOrTrunc(Context.getIntWidth(EltTy));
+        ++EnumVal;        
+        
+        // If we're not in C++, diagnose the overflow of enumerator values,
+        // which in C99 means that the enumerator value is not representable in
+        // an int (C99 6.7.2.2p2). However, we support GCC's extension that
+        // permits enumerator values that are representable in some larger
+        // integral type.
+        if (!getLangOptions().CPlusPlus && !T.isNull())
+          Diag(IdLoc, diag::warn_enum_value_overflow);
+      } else if (!getLangOptions().CPlusPlus &&
+                 !isRepresentableIntegerValue(Context, EnumVal, EltTy)) {
+        // Enforce C99 6.7.2.2p2 even when we compute the next value.
+        Diag(IdLoc, diag::ext_enum_value_not_int)
+          << EnumVal.toString(10) << 1;
+      }
+    }
+  }
+
+  if (!EltTy->isDependentType()) {
+    // Make the enumerator value match the signedness and size of the 
+    // enumerator's type.
+    EnumVal.zextOrTrunc(Context.getIntWidth(EltTy));
+    EnumVal.setIsSigned(EltTy->isSignedIntegerType());
+  }
+  
+  val.release();
+  return EnumConstantDecl::Create(Context, Enum, IdLoc, Id, EltTy,
+                                  Val, EnumVal);
+}
+
+
+Sema::DeclPtrTy Sema::ActOnEnumConstant(Scope *S, DeclPtrTy theEnumDecl,
+                                        DeclPtrTy lastEnumConst,
+                                        SourceLocation IdLoc,
+                                        IdentifierInfo *Id,
+                                        SourceLocation EqualLoc, ExprTy *val) {
+  EnumDecl *TheEnumDecl = cast<EnumDecl>(theEnumDecl.getAs<Decl>());
+  EnumConstantDecl *LastEnumConst =
+    cast_or_null<EnumConstantDecl>(lastEnumConst.getAs<Decl>());
+  Expr *Val = static_cast<Expr*>(val);
+
+  // The scope passed in may not be a decl scope.  Zip up the scope tree until
+  // we find one that is.
+  S = getNonFieldDeclScope(S);
+
+  // Verify that there isn't already something declared with this name in this
+  // scope.
+  NamedDecl *PrevDecl = LookupSingleName(S, Id, IdLoc, LookupOrdinaryName,
+                                         ForRedeclaration);
+  if (PrevDecl && PrevDecl->isTemplateParameter()) {
+    // Maybe we will complain about the shadowed template parameter.
+    DiagnoseTemplateParameterShadow(IdLoc, PrevDecl);
+    // Just pretend that we didn't see the previous declaration.
+    PrevDecl = 0;
+  }
+
+  if (PrevDecl) {
+    // When in C++, we may get a TagDecl with the same name; in this case the
+    // enum constant will 'hide' the tag.
+    assert((getLangOptions().CPlusPlus || !isa<TagDecl>(PrevDecl)) &&
+           "Received TagDecl when not in C++!");
+    if (!isa<TagDecl>(PrevDecl) && isDeclInScope(PrevDecl, CurContext, S)) {
+      if (isa<EnumConstantDecl>(PrevDecl))
+        Diag(IdLoc, diag::err_redefinition_of_enumerator) << Id;
+      else
+        Diag(IdLoc, diag::err_redefinition) << Id;
+      Diag(PrevDecl->getLocation(), diag::note_previous_definition);
+      if (Val) Val->Destroy(Context);
+      return DeclPtrTy();
+    }
+  }
+
+  EnumConstantDecl *New = CheckEnumConstant(TheEnumDecl, LastEnumConst,
+                                            IdLoc, Id, Owned(Val));
+
+  // Register this decl in the current scope stack.
+  if (New) {
+    New->setAccess(TheEnumDecl->getAccess());
+    PushOnScopeChains(New, S);
+  }
+
+  return DeclPtrTy::make(New);
+}
+
+void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc,
+                         SourceLocation RBraceLoc, DeclPtrTy EnumDeclX,
+                         DeclPtrTy *Elements, unsigned NumElements,
+                         Scope *S, AttributeList *Attr) {
+  EnumDecl *Enum = cast<EnumDecl>(EnumDeclX.getAs<Decl>());
+  QualType EnumType = Context.getTypeDeclType(Enum);
+
+  if (Attr)
+    ProcessDeclAttributeList(S, Enum, Attr);
+
+  if (Enum->isDependentType()) {
+    for (unsigned i = 0; i != NumElements; ++i) {
+      EnumConstantDecl *ECD =
+        cast_or_null<EnumConstantDecl>(Elements[i].getAs<Decl>());
+      if (!ECD) continue;
+
+      ECD->setType(EnumType);
+    }
+
+    Enum->completeDefinition(Context.DependentTy, Context.DependentTy);
+    return;
+  }
+
+  // TODO: If the result value doesn't fit in an int, it must be a long or long
+  // long value.  ISO C does not support this, but GCC does as an extension,
+  // emit a warning.
+  unsigned IntWidth = Context.Target.getIntWidth();
+  unsigned CharWidth = Context.Target.getCharWidth();
+  unsigned ShortWidth = Context.Target.getShortWidth();
+
+  // Verify that all the values are okay, compute the size of the values, and
+  // reverse the list.
+  unsigned NumNegativeBits = 0;
+  unsigned NumPositiveBits = 0;
+
+  // Keep track of whether all elements have type int.
+  bool AllElementsInt = true;
+
+  for (unsigned i = 0; i != NumElements; ++i) {
+    EnumConstantDecl *ECD =
+      cast_or_null<EnumConstantDecl>(Elements[i].getAs<Decl>());
+    if (!ECD) continue;  // Already issued a diagnostic.
+
+    const llvm::APSInt &InitVal = ECD->getInitVal();
+
+    // Keep track of the size of positive and negative values.
+    if (InitVal.isUnsigned() || InitVal.isNonNegative())
+      NumPositiveBits = std::max(NumPositiveBits,
+                                 (unsigned)InitVal.getActiveBits());
+    else
+      NumNegativeBits = std::max(NumNegativeBits,
+                                 (unsigned)InitVal.getMinSignedBits());
+
+    // Keep track of whether every enum element has type int (very commmon).
+    if (AllElementsInt)
+      AllElementsInt = ECD->getType() == Context.IntTy;
+  }
+
+  // Figure out the type that should be used for this enum.
+  // FIXME: Support -fshort-enums.
+  QualType BestType;
+  unsigned BestWidth;
+
+  // C++0x N3000 [conv.prom]p3:
+  //   An rvalue of an unscoped enumeration type whose underlying
+  //   type is not fixed can be converted to an rvalue of the first
+  //   of the following types that can represent all the values of
+  //   the enumeration: int, unsigned int, long int, unsigned long
+  //   int, long long int, or unsigned long long int.
+  // C99 6.4.4.3p2:
+  //   An identifier declared as an enumeration constant has type int.
+  // The C99 rule is modified by a gcc extension 
+  QualType BestPromotionType;
+
+  bool Packed = Enum->getAttr<PackedAttr>() ? true : false;
+
+  if (NumNegativeBits) {
+    // If there is a negative value, figure out the smallest integer type (of
+    // int/long/longlong) that fits.
+    // If it's packed, check also if it fits a char or a short.
+    if (Packed && NumNegativeBits <= CharWidth && NumPositiveBits < CharWidth) {
+      BestType = Context.SignedCharTy;
+      BestWidth = CharWidth;
+    } else if (Packed && NumNegativeBits <= ShortWidth &&
+               NumPositiveBits < ShortWidth) {
+      BestType = Context.ShortTy;
+      BestWidth = ShortWidth;
+    } else if (NumNegativeBits <= IntWidth && NumPositiveBits < IntWidth) {
+      BestType = Context.IntTy;
+      BestWidth = IntWidth;
+    } else {
+      BestWidth = Context.Target.getLongWidth();
+
+      if (NumNegativeBits <= BestWidth && NumPositiveBits < BestWidth) {
+        BestType = Context.LongTy;
+      } else {
+        BestWidth = Context.Target.getLongLongWidth();
+
+        if (NumNegativeBits > BestWidth || NumPositiveBits >= BestWidth)
+          Diag(Enum->getLocation(), diag::warn_enum_too_large);
+        BestType = Context.LongLongTy;
+      }
+    }
+    BestPromotionType = (BestWidth <= IntWidth ? Context.IntTy : BestType);
+  } else {
+    // If there is no negative value, figure out the smallest type that fits
+    // all of the enumerator values.
+    // If it's packed, check also if it fits a char or a short.
+    if (Packed && NumPositiveBits <= CharWidth) {
+      BestType = Context.UnsignedCharTy;
+      BestPromotionType = Context.IntTy;
+      BestWidth = CharWidth;
+    } else if (Packed && NumPositiveBits <= ShortWidth) {
+      BestType = Context.UnsignedShortTy;
+      BestPromotionType = Context.IntTy;
+      BestWidth = ShortWidth;
+    } else if (NumPositiveBits <= IntWidth) {
+      BestType = Context.UnsignedIntTy;
+      BestWidth = IntWidth;
+      BestPromotionType
+        = (NumPositiveBits == BestWidth || !getLangOptions().CPlusPlus)
+                           ? Context.UnsignedIntTy : Context.IntTy;
+    } else if (NumPositiveBits <=
+               (BestWidth = Context.Target.getLongWidth())) {
+      BestType = Context.UnsignedLongTy;
+      BestPromotionType
+        = (NumPositiveBits == BestWidth || !getLangOptions().CPlusPlus)
+                           ? Context.UnsignedLongTy : Context.LongTy;
+    } else {
+      BestWidth = Context.Target.getLongLongWidth();
+      assert(NumPositiveBits <= BestWidth &&
+             "How could an initializer get larger than ULL?");
+      BestType = Context.UnsignedLongLongTy;
+      BestPromotionType
+        = (NumPositiveBits == BestWidth || !getLangOptions().CPlusPlus)
+                           ? Context.UnsignedLongLongTy : Context.LongLongTy;
+    }
+  }
+
+  // Loop over all of the enumerator constants, changing their types to match
+  // the type of the enum if needed.
+  for (unsigned i = 0; i != NumElements; ++i) {
+    EnumConstantDecl *ECD =
+      cast_or_null<EnumConstantDecl>(Elements[i].getAs<Decl>());
+    if (!ECD) continue;  // Already issued a diagnostic.
+
+    // Standard C says the enumerators have int type, but we allow, as an
+    // extension, the enumerators to be larger than int size.  If each
+    // enumerator value fits in an int, type it as an int, otherwise type it the
+    // same as the enumerator decl itself.  This means that in "enum { X = 1U }"
+    // that X has type 'int', not 'unsigned'.
+
+    // Determine whether the value fits into an int.
+    llvm::APSInt InitVal = ECD->getInitVal();
+
+    // If it fits into an integer type, force it.  Otherwise force it to match
+    // the enum decl type.
+    QualType NewTy;
+    unsigned NewWidth;
+    bool NewSign;
+    if (!getLangOptions().CPlusPlus &&
+        isRepresentableIntegerValue(Context, InitVal, Context.IntTy)) {
+      NewTy = Context.IntTy;
+      NewWidth = IntWidth;
+      NewSign = true;
+    } else if (ECD->getType() == BestType) {
+      // Already the right type!
+      if (getLangOptions().CPlusPlus)
+        // C++ [dcl.enum]p4: Following the closing brace of an
+        // enum-specifier, each enumerator has the type of its
+        // enumeration.
+        ECD->setType(EnumType);
+      continue;
+    } else {
+      NewTy = BestType;
+      NewWidth = BestWidth;
+      NewSign = BestType->isSignedIntegerType();
+    }
+
+    // Adjust the APSInt value.
+    InitVal.extOrTrunc(NewWidth);
+    InitVal.setIsSigned(NewSign);
+    ECD->setInitVal(InitVal);
+
+    // Adjust the Expr initializer and type.
+    if (ECD->getInitExpr())
+      ECD->setInitExpr(new (Context) ImplicitCastExpr(NewTy,
+                                                      CastExpr::CK_IntegralCast,
+                                                      ECD->getInitExpr(),
+                                                      CXXBaseSpecifierArray(),
+                                                      /*isLvalue=*/false));
+    if (getLangOptions().CPlusPlus)
+      // C++ [dcl.enum]p4: Following the closing brace of an
+      // enum-specifier, each enumerator has the type of its
+      // enumeration.
+      ECD->setType(EnumType);
+    else
+      ECD->setType(NewTy);
+  }
+
+  Enum->completeDefinition(BestType, BestPromotionType);
+}
+
+Sema::DeclPtrTy Sema::ActOnFileScopeAsmDecl(SourceLocation Loc,
+                                            ExprArg expr) {
+  StringLiteral *AsmString = cast<StringLiteral>(expr.takeAs<Expr>());
+
+  FileScopeAsmDecl *New = FileScopeAsmDecl::Create(Context, CurContext,
+                                                   Loc, AsmString);
+  CurContext->addDecl(New);
+  return DeclPtrTy::make(New);
+}
+
+void Sema::ActOnPragmaWeakID(IdentifierInfo* Name,
+                             SourceLocation PragmaLoc,
+                             SourceLocation NameLoc) {
+  Decl *PrevDecl = LookupSingleName(TUScope, Name, NameLoc, LookupOrdinaryName);
+
+  if (PrevDecl) {
+    PrevDecl->addAttr(::new (Context) WeakAttr());
+  } else {
+    (void)WeakUndeclaredIdentifiers.insert(
+      std::pair<IdentifierInfo*,WeakInfo>
+        (Name, WeakInfo((IdentifierInfo*)0, NameLoc)));
+  }
+}
+
+void Sema::ActOnPragmaWeakAlias(IdentifierInfo* Name,
+                                IdentifierInfo* AliasName,
+                                SourceLocation PragmaLoc,
+                                SourceLocation NameLoc,
+                                SourceLocation AliasNameLoc) {
+  Decl *PrevDecl = LookupSingleName(TUScope, AliasName, AliasNameLoc,
+                                    LookupOrdinaryName);
+  WeakInfo W = WeakInfo(Name, NameLoc);
+
+  if (PrevDecl) {
+    if (!PrevDecl->hasAttr<AliasAttr>())
+      if (NamedDecl *ND = dyn_cast<NamedDecl>(PrevDecl))
+        DeclApplyPragmaWeak(TUScope, ND, W);
+  } else {
+    (void)WeakUndeclaredIdentifiers.insert(
+      std::pair<IdentifierInfo*,WeakInfo>(AliasName, W));
+  }
+}
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
new file mode 100644
index 0000000..1c07d9b
--- /dev/null
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -0,0 +1,2132 @@
+//===--- SemaDeclAttr.cpp - Declaration Attribute Handling ----------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements decl-related attribute processing.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Sema.h"
+#include "TargetAttributesSema.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/Expr.h"
+#include "clang/Basic/TargetInfo.h"
+#include "clang/Parse/DeclSpec.h"
+#include "llvm/ADT/StringExtras.h"
+using namespace clang;
+
+//===----------------------------------------------------------------------===//
+//  Helper functions
+//===----------------------------------------------------------------------===//
+
+static const FunctionType *getFunctionType(const Decl *d,
+                                           bool blocksToo = true) {
+  QualType Ty;
+  if (const ValueDecl *decl = dyn_cast<ValueDecl>(d))
+    Ty = decl->getType();
+  else if (const FieldDecl *decl = dyn_cast<FieldDecl>(d))
+    Ty = decl->getType();
+  else if (const TypedefDecl* decl = dyn_cast<TypedefDecl>(d))
+    Ty = decl->getUnderlyingType();
+  else
+    return 0;
+
+  if (Ty->isFunctionPointerType())
+    Ty = Ty->getAs<PointerType>()->getPointeeType();
+  else if (blocksToo && Ty->isBlockPointerType())
+    Ty = Ty->getAs<BlockPointerType>()->getPointeeType();
+
+  return Ty->getAs<FunctionType>();
+}
+
+// FIXME: We should provide an abstraction around a method or function
+// to provide the following bits of information.
+
+/// isFunction - Return true if the given decl has function
+/// type (function or function-typed variable).
+static bool isFunction(const Decl *d) {
+  return getFunctionType(d, false) != NULL;
+}
+
+/// isFunctionOrMethod - Return true if the given decl has function
+/// type (function or function-typed variable) or an Objective-C
+/// method.
+static bool isFunctionOrMethod(const Decl *d) {
+  return isFunction(d)|| isa<ObjCMethodDecl>(d);
+}
+
+/// isFunctionOrMethodOrBlock - Return true if the given decl has function
+/// type (function or function-typed variable) or an Objective-C
+/// method or a block.
+static bool isFunctionOrMethodOrBlock(const Decl *d) {
+  if (isFunctionOrMethod(d))
+    return true;
+  // check for block is more involved.
+  if (const VarDecl *V = dyn_cast<VarDecl>(d)) {
+    QualType Ty = V->getType();
+    return Ty->isBlockPointerType();
+  }
+  return isa<BlockDecl>(d);
+}
+
+/// hasFunctionProto - Return true if the given decl has a argument
+/// information. This decl should have already passed
+/// isFunctionOrMethod or isFunctionOrMethodOrBlock.
+static bool hasFunctionProto(const Decl *d) {
+  if (const FunctionType *FnTy = getFunctionType(d))
+    return isa<FunctionProtoType>(FnTy);
+  else {
+    assert(isa<ObjCMethodDecl>(d) || isa<BlockDecl>(d));
+    return true;
+  }
+}
+
+/// getFunctionOrMethodNumArgs - Return number of function or method
+/// arguments. It is an error to call this on a K&R function (use
+/// hasFunctionProto first).
+static unsigned getFunctionOrMethodNumArgs(const Decl *d) {
+  if (const FunctionType *FnTy = getFunctionType(d))
+    return cast<FunctionProtoType>(FnTy)->getNumArgs();
+  if (const BlockDecl *BD = dyn_cast<BlockDecl>(d))
+    return BD->getNumParams();
+  return cast<ObjCMethodDecl>(d)->param_size();
+}
+
+static QualType getFunctionOrMethodArgType(const Decl *d, unsigned Idx) {
+  if (const FunctionType *FnTy = getFunctionType(d))
+    return cast<FunctionProtoType>(FnTy)->getArgType(Idx);
+  if (const BlockDecl *BD = dyn_cast<BlockDecl>(d))
+    return BD->getParamDecl(Idx)->getType();
+
+  return cast<ObjCMethodDecl>(d)->param_begin()[Idx]->getType();
+}
+
+static QualType getFunctionOrMethodResultType(const Decl *d) {
+  if (const FunctionType *FnTy = getFunctionType(d))
+    return cast<FunctionProtoType>(FnTy)->getResultType();
+  return cast<ObjCMethodDecl>(d)->getResultType();
+}
+
+static bool isFunctionOrMethodVariadic(const Decl *d) {
+  if (const FunctionType *FnTy = getFunctionType(d)) {
+    const FunctionProtoType *proto = cast<FunctionProtoType>(FnTy);
+    return proto->isVariadic();
+  } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(d))
+    return BD->IsVariadic();
+  else {
+    return cast<ObjCMethodDecl>(d)->isVariadic();
+  }
+}
+
+static inline bool isNSStringType(QualType T, ASTContext &Ctx) {
+  const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>();
+  if (!PT)
+    return false;
+
+  const ObjCInterfaceType *ClsT =PT->getPointeeType()->getAs<ObjCInterfaceType>();
+  if (!ClsT)
+    return false;
+
+  IdentifierInfo* ClsName = ClsT->getDecl()->getIdentifier();
+
+  // FIXME: Should we walk the chain of classes?
+  return ClsName == &Ctx.Idents.get("NSString") ||
+         ClsName == &Ctx.Idents.get("NSMutableString");
+}
+
+static inline bool isCFStringType(QualType T, ASTContext &Ctx) {
+  const PointerType *PT = T->getAs<PointerType>();
+  if (!PT)
+    return false;
+
+  const RecordType *RT = PT->getPointeeType()->getAs<RecordType>();
+  if (!RT)
+    return false;
+
+  const RecordDecl *RD = RT->getDecl();
+  if (RD->getTagKind() != TagDecl::TK_struct)
+    return false;
+
+  return RD->getIdentifier() == &Ctx.Idents.get("__CFString");
+}
+
+//===----------------------------------------------------------------------===//
+// Attribute Implementations
+//===----------------------------------------------------------------------===//
+
+// FIXME: All this manual attribute parsing code is gross. At the
+// least add some helper functions to check most argument patterns (#
+// and types of args).
+
+static void HandleExtVectorTypeAttr(Scope *scope, Decl *d,
+                                    const AttributeList &Attr, Sema &S) {
+  TypedefDecl *tDecl = dyn_cast<TypedefDecl>(d);
+  if (tDecl == 0) {
+    S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef);
+    return;
+  }
+
+  QualType curType = tDecl->getUnderlyingType();
+
+  Expr *sizeExpr;
+
+  // Special case where the argument is a template id.
+  if (Attr.getParameterName()) {
+    CXXScopeSpec SS;
+    UnqualifiedId id;
+    id.setIdentifier(Attr.getParameterName(), Attr.getLoc());
+    sizeExpr = S.ActOnIdExpression(scope, SS, id, false, false).takeAs<Expr>();
+  } else {
+    // check the attribute arguments.
+    if (Attr.getNumArgs() != 1) {
+      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
+      return;
+    }
+    sizeExpr = static_cast<Expr *>(Attr.getArg(0));
+  }
+
+  // Instantiate/Install the vector type, and let Sema build the type for us.
+  // This will run the reguired checks.
+  QualType T = S.BuildExtVectorType(curType, S.Owned(sizeExpr), Attr.getLoc());
+  if (!T.isNull()) {
+    // FIXME: preserve the old source info.
+    tDecl->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(T));
+
+    // Remember this typedef decl, we will need it later for diagnostics.
+    S.ExtVectorDecls.push_back(tDecl);
+  }
+}
+
+static void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+  // check the attribute arguments.
+  if (Attr.getNumArgs() > 0) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+    return;
+  }
+
+  if (TagDecl *TD = dyn_cast<TagDecl>(d))
+    TD->addAttr(::new (S.Context) PackedAttr);
+  else if (FieldDecl *FD = dyn_cast<FieldDecl>(d)) {
+    // If the alignment is less than or equal to 8 bits, the packed attribute
+    // has no effect.
+    if (!FD->getType()->isIncompleteType() &&
+        S.Context.getTypeAlign(FD->getType()) <= 8)
+      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type)
+        << Attr.getName() << FD->getType();
+    else
+      FD->addAttr(::new (S.Context) PackedAttr);
+  } else
+    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
+}
+
+static void HandleIBAction(Decl *d, const AttributeList &Attr, Sema &S) {
+  // check the attribute arguments.
+  if (Attr.getNumArgs() > 0) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+    return;
+  }
+
+  // The IBAction attributes only apply to instance methods.
+  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d))
+    if (MD->isInstanceMethod()) {
+      d->addAttr(::new (S.Context) IBActionAttr());
+      return;
+    }
+
+  S.Diag(Attr.getLoc(), diag::err_attribute_ibaction) << Attr.getName();
+}
+
+static void HandleIBOutlet(Decl *d, const AttributeList &Attr, Sema &S) {
+  // check the attribute arguments.
+  if (Attr.getNumArgs() > 0) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+    return;
+  }
+
+  // The IBOutlet attributes only apply to instance variables of
+  // Objective-C classes.
+  if (isa<ObjCIvarDecl>(d) || isa<ObjCPropertyDecl>(d)) {
+    d->addAttr(::new (S.Context) IBOutletAttr());
+    return;
+  }
+
+  S.Diag(Attr.getLoc(), diag::err_attribute_iboutlet) << Attr.getName();
+}
+
+static void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+  // GCC ignores the nonnull attribute on K&R style function prototypes, so we
+  // ignore it as well
+  if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << 0 /*function*/;
+    return;
+  }
+
+  unsigned NumArgs = getFunctionOrMethodNumArgs(d);
+
+  // The nonnull attribute only applies to pointers.
+  llvm::SmallVector<unsigned, 10> NonNullArgs;
+
+  for (AttributeList::arg_iterator I=Attr.arg_begin(),
+                                   E=Attr.arg_end(); I!=E; ++I) {
+
+
+    // The argument must be an integer constant expression.
+    Expr *Ex = static_cast<Expr *>(*I);
+    llvm::APSInt ArgNum(32);
+    if (!Ex->isIntegerConstantExpr(ArgNum, S.Context)) {
+      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
+        << "nonnull" << Ex->getSourceRange();
+      return;
+    }
+
+    unsigned x = (unsigned) ArgNum.getZExtValue();
+
+    if (x < 1 || x > NumArgs) {
+      S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
+       << "nonnull" << I.getArgNum() << Ex->getSourceRange();
+      return;
+    }
+
+    --x;
+
+    // Is the function argument a pointer type?
+    QualType T = getFunctionOrMethodArgType(d, x);
+    if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
+      // FIXME: Should also highlight argument in decl.
+      S.Diag(Attr.getLoc(), diag::err_nonnull_pointers_only)
+        << "nonnull" << Ex->getSourceRange();
+      continue;
+    }
+
+    NonNullArgs.push_back(x);
+  }
+
+  // If no arguments were specified to __attribute__((nonnull)) then all pointer
+  // arguments have a nonnull attribute.
+  if (NonNullArgs.empty()) {
+    for (unsigned I = 0, E = getFunctionOrMethodNumArgs(d); I != E; ++I) {
+      QualType T = getFunctionOrMethodArgType(d, I);
+      if (T->isAnyPointerType() || T->isBlockPointerType())
+        NonNullArgs.push_back(I);
+    }
+
+    if (NonNullArgs.empty()) {
+      S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers);
+      return;
+    }
+  }
+
+  unsigned* start = &NonNullArgs[0];
+  unsigned size = NonNullArgs.size();
+  std::sort(start, start + size);
+  d->addAttr(::new (S.Context) NonNullAttr(S.Context, start, size));
+}
+
+static bool isStaticVarOrStaticFunciton(Decl *D) {
+  if (VarDecl *VD = dyn_cast<VarDecl>(D))
+    return VD->getStorageClass() == VarDecl::Static;
+  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
+    return FD->getStorageClass() == FunctionDecl::Static;
+  return false;
+}
+
+static void HandleWeakRefAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+  // Check the attribute arguments.
+  if (Attr.getNumArgs() > 1) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
+    return;
+  }
+
+  // gcc rejects
+  // class c {
+  //   static int a __attribute__((weakref ("v2")));
+  //   static int b() __attribute__((weakref ("f3")));
+  // };
+  // and ignores the attributes of
+  // void f(void) {
+  //   static int a __attribute__((weakref ("v2")));
+  // }
+  // we reject them
+  if (const DeclContext *Ctx = d->getDeclContext()) {
+    Ctx = Ctx->getLookupContext();
+    if (!isa<TranslationUnitDecl>(Ctx) && !isa<NamespaceDecl>(Ctx) ) {
+      S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context) <<
+	dyn_cast<NamedDecl>(d)->getNameAsString();
+      return;
+    }
+  }
+
+  // The GCC manual says
+  //
+  // At present, a declaration to which `weakref' is attached can only
+  // be `static'.
+  //
+  // It also says
+  //
+  // Without a TARGET,
+  // given as an argument to `weakref' or to `alias', `weakref' is
+  // equivalent to `weak'.
+  //
+  // gcc 4.4.1 will accept
+  // int a7 __attribute__((weakref));
+  // as
+  // int a7 __attribute__((weak));
+  // This looks like a bug in gcc. We reject that for now. We should revisit
+  // it if this behaviour is actually used.
+
+  if (!isStaticVarOrStaticFunciton(d)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_static) <<
+      dyn_cast<NamedDecl>(d)->getNameAsString();
+    return;
+  }
+
+  // GCC rejects
+  // static ((alias ("y"), weakref)).
+  // Should we? How to check that weakref is before or after alias?
+
+  if (Attr.getNumArgs() == 1) {
+    Expr *Arg = static_cast<Expr*>(Attr.getArg(0));
+    Arg = Arg->IgnoreParenCasts();
+    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
+
+    if (Str == 0 || Str->isWide()) {
+      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
+          << "weakref" << 1;
+      return;
+    }
+    // GCC will accept anything as the argument of weakref. Should we
+    // check for an existing decl?
+    d->addAttr(::new (S.Context) AliasAttr(S.Context, Str->getString()));
+  }
+
+  d->addAttr(::new (S.Context) WeakRefAttr());
+}
+
+static void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+  // check the attribute arguments.
+  if (Attr.getNumArgs() != 1) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
+    return;
+  }
+
+  Expr *Arg = static_cast<Expr*>(Attr.getArg(0));
+  Arg = Arg->IgnoreParenCasts();
+  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
+
+  if (Str == 0 || Str->isWide()) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
+      << "alias" << 1;
+    return;
+  }
+
+  // FIXME: check if target symbol exists in current file
+
+  d->addAttr(::new (S.Context) AliasAttr(S.Context, Str->getString()));
+}
+
+static void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr,
+                                   Sema &S) {
+  // check the attribute arguments.
+  if (Attr.getNumArgs() != 0) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+    return;
+  }
+
+  if (!isa<FunctionDecl>(d)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+    << Attr.getName() << 0 /*function*/;
+    return;
+  }
+
+  d->addAttr(::new (S.Context) AlwaysInlineAttr());
+}
+
+static void HandleMallocAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+  // check the attribute arguments.
+  if (Attr.getNumArgs() != 0) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+    return;
+  }
+
+  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) {
+    QualType RetTy = FD->getResultType();
+    if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) {
+      d->addAttr(::new (S.Context) MallocAttr());
+      return;
+    }
+  }
+
+  S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only);
+}
+
+static bool HandleCommonNoReturnAttr(Decl *d, const AttributeList &Attr,
+                                     Sema &S) {
+  // check the attribute arguments.
+  if (Attr.getNumArgs() != 0) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+    return false;
+  }
+
+  if (!isFunctionOrMethod(d) && !isa<BlockDecl>(d)) {
+    ValueDecl *VD = dyn_cast<ValueDecl>(d);
+    if (VD == 0 || (!VD->getType()->isBlockPointerType()
+                    && !VD->getType()->isFunctionPointerType())) {
+      S.Diag(Attr.getLoc(),
+             Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
+                                     : diag::warn_attribute_wrong_decl_type)
+        << Attr.getName() << 0 /*function*/;
+      return false;
+    }
+  }
+
+  return true;
+}
+
+static void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+  // NOTE: We don't add the attribute to a FunctionDecl because the noreturn
+  //  trait will be part of the function's type.
+
+  // Don't apply as a decl attribute to ValueDecl.
+  // FIXME: probably ought to diagnose this.
+  if (isa<ValueDecl>(d))
+    return;
+
+  if (HandleCommonNoReturnAttr(d, Attr, S))
+    d->addAttr(::new (S.Context) NoReturnAttr());
+}
+
+static void HandleAnalyzerNoReturnAttr(Decl *d, const AttributeList &Attr,
+                                       Sema &S) {
+  if (HandleCommonNoReturnAttr(d, Attr, S))
+    d->addAttr(::new (S.Context) AnalyzerNoReturnAttr());
+}
+
+static void HandleDependencyAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+  if (!isFunctionOrMethod(d) && !isa<ParmVarDecl>(d)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
+      << Attr.getName() << 8 /*function, method, or parameter*/;
+    return;
+  }
+  // FIXME: Actually store the attribute on the declaration
+}
+
+static void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+  // check the attribute arguments.
+  if (Attr.getNumArgs() != 0) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+    return;
+  }
+
+  if (!isa<VarDecl>(d) && !isa<ObjCIvarDecl>(d) && !isFunctionOrMethod(d) &&
+      !isa<TypeDecl>(d)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << 2 /*variable and function*/;
+    return;
+  }
+
+  d->addAttr(::new (S.Context) UnusedAttr());
+}
+
+static void HandleUsedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+  // check the attribute arguments.
+  if (Attr.getNumArgs() != 0) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+    return;
+  }
+
+  if (const VarDecl *VD = dyn_cast<VarDecl>(d)) {
+    if (VD->hasLocalStorage() || VD->hasExternalStorage()) {
+      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used";
+      return;
+    }
+  } else if (!isFunctionOrMethod(d)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << 2 /*variable and function*/;
+    return;
+  }
+
+  d->addAttr(::new (S.Context) UsedAttr());
+}
+
+static void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+  // check the attribute arguments.
+  if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
+      << "0 or 1";
+    return;
+  }
+
+  int priority = 65535; // FIXME: Do not hardcode such constants.
+  if (Attr.getNumArgs() > 0) {
+    Expr *E = static_cast<Expr *>(Attr.getArg(0));
+    llvm::APSInt Idx(32);
+    if (!E->isIntegerConstantExpr(Idx, S.Context)) {
+      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
+        << "constructor" << 1 << E->getSourceRange();
+      return;
+    }
+    priority = Idx.getZExtValue();
+  }
+
+  if (!isa<FunctionDecl>(d)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << 0 /*function*/;
+    return;
+  }
+
+  d->addAttr(::new (S.Context) ConstructorAttr(priority));
+}
+
+static void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+  // check the attribute arguments.
+  if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
+       << "0 or 1";
+    return;
+  }
+
+  int priority = 65535; // FIXME: Do not hardcode such constants.
+  if (Attr.getNumArgs() > 0) {
+    Expr *E = static_cast<Expr *>(Attr.getArg(0));
+    llvm::APSInt Idx(32);
+    if (!E->isIntegerConstantExpr(Idx, S.Context)) {
+      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
+        << "destructor" << 1 << E->getSourceRange();
+      return;
+    }
+    priority = Idx.getZExtValue();
+  }
+
+  if (!isa<FunctionDecl>(d)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << 0 /*function*/;
+    return;
+  }
+
+  d->addAttr(::new (S.Context) DestructorAttr(priority));
+}
+
+static void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+  // check the attribute arguments.
+  if (Attr.getNumArgs() != 0) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+    return;
+  }
+
+  d->addAttr(::new (S.Context) DeprecatedAttr());
+}
+
+static void HandleUnavailableAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+  // check the attribute arguments.
+  if (Attr.getNumArgs() != 0) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+    return;
+  }
+
+  d->addAttr(::new (S.Context) UnavailableAttr());
+}
+
+static void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+  // check the attribute arguments.
+  if (Attr.getNumArgs() != 1) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
+    return;
+  }
+
+  Expr *Arg = static_cast<Expr*>(Attr.getArg(0));
+  Arg = Arg->IgnoreParenCasts();
+  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
+
+  if (Str == 0 || Str->isWide()) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
+      << "visibility" << 1;
+    return;
+  }
+
+  llvm::StringRef TypeStr = Str->getString();
+  VisibilityAttr::VisibilityTypes type;
+
+  if (TypeStr == "default")
+    type = VisibilityAttr::DefaultVisibility;
+  else if (TypeStr == "hidden")
+    type = VisibilityAttr::HiddenVisibility;
+  else if (TypeStr == "internal")
+    type = VisibilityAttr::HiddenVisibility; // FIXME
+  else if (TypeStr == "protected")
+    type = VisibilityAttr::ProtectedVisibility;
+  else {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr;
+    return;
+  }
+
+  d->addAttr(::new (S.Context) VisibilityAttr(type));
+}
+
+static void HandleObjCExceptionAttr(Decl *D, const AttributeList &Attr,
+                                    Sema &S) {
+  if (Attr.getNumArgs() != 0) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+    return;
+  }
+
+  ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D);
+  if (OCI == 0) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface);
+    return;
+  }
+
+  D->addAttr(::new (S.Context) ObjCExceptionAttr());
+}
+
+static void HandleObjCNSObject(Decl *D, const AttributeList &Attr, Sema &S) {
+  if (Attr.getNumArgs() != 0) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
+    return;
+  }
+  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
+    QualType T = TD->getUnderlyingType();
+    if (!T->isPointerType() ||
+        !T->getAs<PointerType>()->getPointeeType()->isRecordType()) {
+      S.Diag(TD->getLocation(), diag::err_nsobject_attribute);
+      return;
+    }
+  }
+  D->addAttr(::new (S.Context) ObjCNSObjectAttr());
+}
+
+static void
+HandleOverloadableAttr(Decl *D, const AttributeList &Attr, Sema &S) {
+  if (Attr.getNumArgs() != 0) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
+    return;
+  }
+
+  if (!isa<FunctionDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function);
+    return;
+  }
+
+  D->addAttr(::new (S.Context) OverloadableAttr());
+}
+
+static void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+  if (!Attr.getParameterName()) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
+      << "blocks" << 1;
+    return;
+  }
+
+  if (Attr.getNumArgs() != 0) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
+    return;
+  }
+
+  BlocksAttr::BlocksAttrTypes type;
+  if (Attr.getParameterName()->isStr("byref"))
+    type = BlocksAttr::ByRef;
+  else {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
+      << "blocks" << Attr.getParameterName();
+    return;
+  }
+
+  d->addAttr(::new (S.Context) BlocksAttr(type));
+}
+
+static void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+  // check the attribute arguments.
+  if (Attr.getNumArgs() > 2) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
+      << "0, 1 or 2";
+    return;
+  }
+
+  int sentinel = 0;
+  if (Attr.getNumArgs() > 0) {
+    Expr *E = static_cast<Expr *>(Attr.getArg(0));
+    llvm::APSInt Idx(32);
+    if (!E->isIntegerConstantExpr(Idx, S.Context)) {
+      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
+       << "sentinel" << 1 << E->getSourceRange();
+      return;
+    }
+    sentinel = Idx.getZExtValue();
+
+    if (sentinel < 0) {
+      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero)
+        << E->getSourceRange();
+      return;
+    }
+  }
+
+  int nullPos = 0;
+  if (Attr.getNumArgs() > 1) {
+    Expr *E = static_cast<Expr *>(Attr.getArg(1));
+    llvm::APSInt Idx(32);
+    if (!E->isIntegerConstantExpr(Idx, S.Context)) {
+      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
+        << "sentinel" << 2 << E->getSourceRange();
+      return;
+    }
+    nullPos = Idx.getZExtValue();
+
+    if (nullPos > 1 || nullPos < 0) {
+      // FIXME: This error message could be improved, it would be nice
+      // to say what the bounds actually are.
+      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one)
+        << E->getSourceRange();
+      return;
+    }
+  }
+
+  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) {
+    const FunctionType *FT = FD->getType()->getAs<FunctionType>();
+    assert(FT && "FunctionDecl has non-function type?");
+
+    if (isa<FunctionNoProtoType>(FT)) {
+      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments);
+      return;
+    }
+
+    if (!cast<FunctionProtoType>(FT)->isVariadic()) {
+      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
+      return;
+    }
+  } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) {
+    if (!MD->isVariadic()) {
+      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
+      return;
+    }
+  } else if (isa<BlockDecl>(d)) {
+    // Note! BlockDecl is typeless. Variadic diagnostics will be issued by the
+    // caller.
+    ;
+  } else if (const VarDecl *V = dyn_cast<VarDecl>(d)) {
+    QualType Ty = V->getType();
+    if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) {
+      const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(d)
+        : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>();
+      if (!cast<FunctionProtoType>(FT)->isVariadic()) {
+        int m = Ty->isFunctionPointerType() ? 0 : 1;
+        S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m;
+        return;
+      }
+    } else {
+      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << 6 /*function, method or block */;
+      return;
+    }
+  } else {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << 6 /*function, method or block */;
+    return;
+  }
+  d->addAttr(::new (S.Context) SentinelAttr(sentinel, nullPos));
+}
+
+static void HandleWarnUnusedResult(Decl *D, const AttributeList &Attr, Sema &S) {
+  // check the attribute arguments.
+  if (Attr.getNumArgs() != 0) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+    return;
+  }
+
+  if (!isFunction(D) && !isa<ObjCMethodDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << 0 /*function*/;
+    return;
+  }
+
+  if (isFunction(D) && getFunctionType(D)->getResultType()->isVoidType()) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
+      << Attr.getName() << 0;
+    return;
+  }
+  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
+    if (MD->getResultType()->isVoidType()) {
+      S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
+      << Attr.getName() << 1;
+      return;
+    }
+  
+  D->addAttr(::new (S.Context) WarnUnusedResultAttr());
+}
+
+static void HandleWeakAttr(Decl *D, const AttributeList &Attr, Sema &S) {
+  // check the attribute arguments.
+  if (Attr.getNumArgs() != 0) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+    return;
+  }
+
+  /* weak only applies to non-static declarations */
+  if (isStaticVarOrStaticFunciton(D)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_weak_static) <<
+      dyn_cast<NamedDecl>(D)->getNameAsString();
+    return;
+  }
+
+  // TODO: could also be applied to methods?
+  if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << 2 /*variable and function*/;
+    return;
+  }
+
+  D->addAttr(::new (S.Context) WeakAttr());
+}
+
+static void HandleWeakImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
+  // check the attribute arguments.
+  if (Attr.getNumArgs() != 0) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+    return;
+  }
+
+  // weak_import only applies to variable & function declarations.
+  bool isDef = false;
+  if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
+    isDef = (!VD->hasExternalStorage() || VD->getInit());
+  } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+    isDef = FD->getBody();
+  } else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D)) {
+    // We ignore weak import on properties and methods
+    return;
+  } else if (!(S.LangOpts.ObjCNonFragileABI && isa<ObjCInterfaceDecl>(D))) {
+    // Don't issue the warning for darwin as target; yet, ignore the attribute.
+    if (S.Context.Target.getTriple().getOS() != llvm::Triple::Darwin ||
+        !isa<ObjCInterfaceDecl>(D)) 
+      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+        << Attr.getName() << 2 /*variable and function*/;
+      return;
+  }
+
+  // Merge should handle any subsequent violations.
+  if (isDef) {
+    S.Diag(Attr.getLoc(),
+           diag::warn_attribute_weak_import_invalid_on_definition)
+      << "weak_import" << 2 /*variable and function*/;
+    return;
+  }
+
+  D->addAttr(::new (S.Context) WeakImportAttr());
+}
+
+static void HandleReqdWorkGroupSize(Decl *D, const AttributeList &Attr,
+                                    Sema &S) {
+  // Attribute has 3 arguments.
+  if (Attr.getNumArgs() != 3) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
+    return;
+  }
+
+  unsigned WGSize[3];
+  for (unsigned i = 0; i < 3; ++i) {
+    Expr *E = static_cast<Expr *>(Attr.getArg(i));
+    llvm::APSInt ArgNum(32);
+    if (!E->isIntegerConstantExpr(ArgNum, S.Context)) {
+      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
+        << "reqd_work_group_size" << E->getSourceRange();
+      return;
+    }
+    WGSize[i] = (unsigned) ArgNum.getZExtValue();
+  }
+  D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(WGSize[0], WGSize[1],
+                                                     WGSize[2]));
+}
+
+static void HandleSectionAttr(Decl *D, const AttributeList &Attr, Sema &S) {
+  // Attribute has no arguments.
+  if (Attr.getNumArgs() != 1) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
+    return;
+  }
+
+  // Make sure that there is a string literal as the sections's single
+  // argument.
+  Expr *ArgExpr = static_cast<Expr *>(Attr.getArg(0));
+  StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
+  if (!SE) {
+    S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) << "section";
+    return;
+  }
+
+  // If the target wants to validate the section specifier, make it happen.
+  std::string Error = S.Context.Target.isValidSectionSpecifier(SE->getString());
+  if (!Error.empty()) {
+    S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target)
+    << Error;
+    return;
+  }
+
+  // This attribute cannot be applied to local variables.
+  if (isa<VarDecl>(D) && cast<VarDecl>(D)->hasLocalStorage()) {
+    S.Diag(SE->getLocStart(), diag::err_attribute_section_local_variable);
+    return;
+  }
+  
+  D->addAttr(::new (S.Context) SectionAttr(S.Context, SE->getString()));
+}
+
+
+static void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+  // check the attribute arguments.
+  if (Attr.getNumArgs() != 0) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+    return;
+  }
+
+  d->addAttr(::new (S.Context) NoThrowAttr());
+}
+
+static void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+  // check the attribute arguments.
+  if (Attr.getNumArgs() != 0) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+    return;
+  }
+
+  d->addAttr(::new (S.Context) ConstAttr());
+}
+
+static void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+  // check the attribute arguments.
+  if (Attr.getNumArgs() != 0) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+    return;
+  }
+
+  d->addAttr(::new (S.Context) PureAttr());
+}
+
+static void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+  if (!Attr.getParameterName()) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
+    return;
+  }
+
+  if (Attr.getNumArgs() != 0) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
+    return;
+  }
+
+  VarDecl *VD = dyn_cast<VarDecl>(d);
+
+  if (!VD || !VD->hasLocalStorage()) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup";
+    return;
+  }
+
+  // Look up the function
+  // FIXME: Lookup probably isn't looking in the right place
+  // FIXME: The lookup source location should be in the attribute, not the
+  // start of the attribute.
+  NamedDecl *CleanupDecl
+    = S.LookupSingleName(S.TUScope, Attr.getParameterName(), Attr.getLoc(),
+                         Sema::LookupOrdinaryName);
+  if (!CleanupDecl) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_found) <<
+      Attr.getParameterName();
+    return;
+  }
+
+  FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl);
+  if (!FD) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_function) <<
+      Attr.getParameterName();
+    return;
+  }
+
+  if (FD->getNumParams() != 1) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_func_must_take_one_arg) <<
+      Attr.getParameterName();
+    return;
+  }
+
+  // We're currently more strict than GCC about what function types we accept.
+  // If this ever proves to be a problem it should be easy to fix.
+  QualType Ty = S.Context.getPointerType(VD->getType());
+  QualType ParamTy = FD->getParamDecl(0)->getType();
+  if (S.CheckAssignmentConstraints(ParamTy, Ty) != Sema::Compatible) {
+    S.Diag(Attr.getLoc(),
+           diag::err_attribute_cleanup_func_arg_incompatible_type) <<
+      Attr.getParameterName() << ParamTy << Ty;
+    return;
+  }
+
+  d->addAttr(::new (S.Context) CleanupAttr(FD));
+}
+
+/// Handle __attribute__((format_arg((idx)))) attribute based on
+/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
+static void HandleFormatArgAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+  if (Attr.getNumArgs() != 1) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
+    return;
+  }
+  if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+    << Attr.getName() << 0 /*function*/;
+    return;
+  }
+  // FIXME: in C++ the implicit 'this' function parameter also counts.  this is
+  // needed in order to be compatible with GCC the index must start with 1.
+  unsigned NumArgs  = getFunctionOrMethodNumArgs(d);
+  unsigned FirstIdx = 1;
+  // checks for the 2nd argument
+  Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0));
+  llvm::APSInt Idx(32);
+  if (!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
+    << "format" << 2 << IdxExpr->getSourceRange();
+    return;
+  }
+
+  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
+    << "format" << 2 << IdxExpr->getSourceRange();
+    return;
+  }
+
+  unsigned ArgIdx = Idx.getZExtValue() - 1;
+
+  // make sure the format string is really a string
+  QualType Ty = getFunctionOrMethodArgType(d, ArgIdx);
+
+  bool not_nsstring_type = !isNSStringType(Ty, S.Context);
+  if (not_nsstring_type &&
+      !isCFStringType(Ty, S.Context) &&
+      (!Ty->isPointerType() ||
+       !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
+    // FIXME: Should highlight the actual expression that has the wrong type.
+    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
+    << (not_nsstring_type ? "a string type" : "an NSString")
+       << IdxExpr->getSourceRange();
+    return;
+  }
+  Ty = getFunctionOrMethodResultType(d);
+  if (!isNSStringType(Ty, S.Context) &&
+      !isCFStringType(Ty, S.Context) &&
+      (!Ty->isPointerType() ||
+       !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
+    // FIXME: Should highlight the actual expression that has the wrong type.
+    S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not)
+    << (not_nsstring_type ? "string type" : "NSString")
+       << IdxExpr->getSourceRange();
+    return;
+  }
+
+  d->addAttr(::new (S.Context) FormatArgAttr(Idx.getZExtValue()));
+}
+
+enum FormatAttrKind {
+  CFStringFormat,
+  NSStringFormat,
+  StrftimeFormat,
+  SupportedFormat,
+  IgnoredFormat,
+  InvalidFormat
+};
+
+/// getFormatAttrKind - Map from format attribute names to supported format
+/// types.
+static FormatAttrKind getFormatAttrKind(llvm::StringRef Format) {
+  // Check for formats that get handled specially.
+  if (Format == "NSString")
+    return NSStringFormat;
+  if (Format == "CFString")
+    return CFStringFormat;
+  if (Format == "strftime")
+    return StrftimeFormat;
+
+  // Otherwise, check for supported formats.
+  if (Format == "scanf" || Format == "printf" || Format == "printf0" ||
+      Format == "strfmon" || Format == "cmn_err" || Format == "strftime" ||
+      Format == "NSString" || Format == "CFString" || Format == "vcmn_err" ||
+      Format == "zcmn_err")
+    return SupportedFormat;
+
+  if (Format == "gcc_diag" || Format == "gcc_cdiag" ||
+      Format == "gcc_cxxdiag" || Format == "gcc_tdiag")
+    return IgnoredFormat;
+  
+  return InvalidFormat;
+}
+
+/// Handle __attribute__((format(type,idx,firstarg))) attributes based on
+/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
+static void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+
+  if (!Attr.getParameterName()) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
+      << "format" << 1;
+    return;
+  }
+
+  if (Attr.getNumArgs() != 2) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3;
+    return;
+  }
+
+  if (!isFunctionOrMethodOrBlock(d) || !hasFunctionProto(d)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << 0 /*function*/;
+    return;
+  }
+
+  unsigned NumArgs  = getFunctionOrMethodNumArgs(d);
+  unsigned FirstIdx = 1;
+
+  llvm::StringRef Format = Attr.getParameterName()->getName();
+
+  // Normalize the argument, __foo__ becomes foo.
+  if (Format.startswith("__") && Format.endswith("__"))
+    Format = Format.substr(2, Format.size() - 4);
+
+  // Check for supported formats.
+  FormatAttrKind Kind = getFormatAttrKind(Format);
+  
+  if (Kind == IgnoredFormat)
+    return;
+  
+  if (Kind == InvalidFormat) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
+      << "format" << Attr.getParameterName()->getName();
+    return;
+  }
+
+  // checks for the 2nd argument
+  Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0));
+  llvm::APSInt Idx(32);
+  if (!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
+      << "format" << 2 << IdxExpr->getSourceRange();
+    return;
+  }
+
+  // FIXME: We should handle the implicit 'this' parameter in a more generic
+  // way that can be used for other arguments.
+  bool HasImplicitThisParam = false;
+  if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(d)) {
+    if (MD->isInstance()) {
+      HasImplicitThisParam = true;
+      NumArgs++;
+    }
+  }
+
+  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
+      << "format" << 2 << IdxExpr->getSourceRange();
+    return;
+  }
+
+  // FIXME: Do we need to bounds check?
+  unsigned ArgIdx = Idx.getZExtValue() - 1;
+
+  if (HasImplicitThisParam) {
+    if (ArgIdx == 0) {
+      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
+        << "a string type" << IdxExpr->getSourceRange();
+      return;
+    }
+    ArgIdx--;
+  }
+
+  // make sure the format string is really a string
+  QualType Ty = getFunctionOrMethodArgType(d, ArgIdx);
+
+  if (Kind == CFStringFormat) {
+    if (!isCFStringType(Ty, S.Context)) {
+      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
+        << "a CFString" << IdxExpr->getSourceRange();
+      return;
+    }
+  } else if (Kind == NSStringFormat) {
+    // FIXME: do we need to check if the type is NSString*?  What are the
+    // semantics?
+    if (!isNSStringType(Ty, S.Context)) {
+      // FIXME: Should highlight the actual expression that has the wrong type.
+      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
+        << "an NSString" << IdxExpr->getSourceRange();
+      return;
+    }
+  } else if (!Ty->isPointerType() ||
+             !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) {
+    // FIXME: Should highlight the actual expression that has the wrong type.
+    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
+      << "a string type" << IdxExpr->getSourceRange();
+    return;
+  }
+
+  // check the 3rd argument
+  Expr *FirstArgExpr = static_cast<Expr *>(Attr.getArg(1));
+  llvm::APSInt FirstArg(32);
+  if (!FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
+      << "format" << 3 << FirstArgExpr->getSourceRange();
+    return;
+  }
+
+  // check if the function is variadic if the 3rd argument non-zero
+  if (FirstArg != 0) {
+    if (isFunctionOrMethodVariadic(d)) {
+      ++NumArgs; // +1 for ...
+    } else {
+      S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic);
+      return;
+    }
+  }
+
+  // strftime requires FirstArg to be 0 because it doesn't read from any
+  // variable the input is just the current time + the format string.
+  if (Kind == StrftimeFormat) {
+    if (FirstArg != 0) {
+      S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter)
+        << FirstArgExpr->getSourceRange();
+      return;
+    }
+  // if 0 it disables parameter checking (to use with e.g. va_list)
+  } else if (FirstArg != 0 && FirstArg != NumArgs) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
+      << "format" << 3 << FirstArgExpr->getSourceRange();
+    return;
+  }
+
+  d->addAttr(::new (S.Context) FormatAttr(S.Context, Format, Idx.getZExtValue(),
+                                          FirstArg.getZExtValue()));
+}
+
+static void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr,
+                                       Sema &S) {
+  // check the attribute arguments.
+  if (Attr.getNumArgs() != 0) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+    return;
+  }
+
+  // Try to find the underlying union declaration.
+  RecordDecl *RD = 0;
+  TypedefDecl *TD = dyn_cast<TypedefDecl>(d);
+  if (TD && TD->getUnderlyingType()->isUnionType())
+    RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();
+  else
+    RD = dyn_cast<RecordDecl>(d);
+
+  if (!RD || !RD->isUnion()) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << 1 /*union*/;
+    return;
+  }
+
+  if (!RD->isDefinition()) {
+    S.Diag(Attr.getLoc(),
+        diag::warn_transparent_union_attribute_not_definition);
+    return;
+  }
+
+  RecordDecl::field_iterator Field = RD->field_begin(),
+                          FieldEnd = RD->field_end();
+  if (Field == FieldEnd) {
+    S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields);
+    return;
+  }
+
+  FieldDecl *FirstField = *Field;
+  QualType FirstType = FirstField->getType();
+  if (FirstType->isFloatingType() || FirstType->isVectorType()) {
+    S.Diag(FirstField->getLocation(),
+           diag::warn_transparent_union_attribute_floating);
+    return;
+  }
+
+  uint64_t FirstSize = S.Context.getTypeSize(FirstType);
+  uint64_t FirstAlign = S.Context.getTypeAlign(FirstType);
+  for (; Field != FieldEnd; ++Field) {
+    QualType FieldType = Field->getType();
+    if (S.Context.getTypeSize(FieldType) != FirstSize ||
+        S.Context.getTypeAlign(FieldType) != FirstAlign) {
+      // Warn if we drop the attribute.
+      bool isSize = S.Context.getTypeSize(FieldType) != FirstSize;
+      unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType)
+                                 : S.Context.getTypeAlign(FieldType);
+      S.Diag(Field->getLocation(),
+          diag::warn_transparent_union_attribute_field_size_align)
+        << isSize << Field->getDeclName() << FieldBits;
+      unsigned FirstBits = isSize? FirstSize : FirstAlign;
+      S.Diag(FirstField->getLocation(),
+             diag::note_transparent_union_first_field_size_align)
+        << isSize << FirstBits;
+      return;
+    }
+  }
+
+  RD->addAttr(::new (S.Context) TransparentUnionAttr());
+}
+
+static void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+  // check the attribute arguments.
+  if (Attr.getNumArgs() != 1) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
+    return;
+  }
+  Expr *ArgExpr = static_cast<Expr *>(Attr.getArg(0));
+  StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
+
+  // Make sure that there is a string literal as the annotation's single
+  // argument.
+  if (!SE) {
+    S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate";
+    return;
+  }
+  d->addAttr(::new (S.Context) AnnotateAttr(S.Context, SE->getString()));
+}
+
+static void HandleAlignedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+  // check the attribute arguments.
+  if (Attr.getNumArgs() > 1) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
+    return;
+  }
+  
+  //FIXME: The C++0x version of this attribute has more limited applicabilty
+  //       than GNU's, and should error out when it is used to specify a
+  //       weaker alignment, rather than being silently ignored.
+
+  unsigned Align = 0;
+  if (Attr.getNumArgs() == 0) {
+    // FIXME: This should be the target specific maximum alignment.
+    // (For now we just use 128 bits which is the maximum on X86).
+    Align = 128;
+    d->addAttr(::new (S.Context) AlignedAttr(Align));
+    return;
+  }
+
+  Expr *alignmentExpr = static_cast<Expr *>(Attr.getArg(0));
+  llvm::APSInt Alignment(32);
+  if (!alignmentExpr->isIntegerConstantExpr(Alignment, S.Context)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
+      << "aligned" << alignmentExpr->getSourceRange();
+    return;
+  }
+  if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_aligned_not_power_of_two)
+      << alignmentExpr->getSourceRange();
+    return;
+  }
+
+  d->addAttr(::new (S.Context) AlignedAttr(Alignment.getZExtValue() * 8));
+}
+
+/// HandleModeAttr - This attribute modifies the width of a decl with primitive
+/// type.
+///
+/// Despite what would be logical, the mode attribute is a decl attribute, not a
+/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be
+/// HImode, not an intermediate pointer.
+static void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) {
+  // This attribute isn't documented, but glibc uses it.  It changes
+  // the width of an int or unsigned int to the specified size.
+
+  // Check that there aren't any arguments
+  if (Attr.getNumArgs() != 0) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+    return;
+  }
+
+  IdentifierInfo *Name = Attr.getParameterName();
+  if (!Name) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name);
+    return;
+  }
+
+  llvm::StringRef Str = Attr.getParameterName()->getName();
+
+  // Normalize the attribute name, __foo__ becomes foo.
+  if (Str.startswith("__") && Str.endswith("__"))
+    Str = Str.substr(2, Str.size() - 4);
+
+  unsigned DestWidth = 0;
+  bool IntegerMode = true;
+  bool ComplexMode = false;
+  switch (Str.size()) {
+  case 2:
+    switch (Str[0]) {
+    case 'Q': DestWidth = 8; break;
+    case 'H': DestWidth = 16; break;
+    case 'S': DestWidth = 32; break;
+    case 'D': DestWidth = 64; break;
+    case 'X': DestWidth = 96; break;
+    case 'T': DestWidth = 128; break;
+    }
+    if (Str[1] == 'F') {
+      IntegerMode = false;
+    } else if (Str[1] == 'C') {
+      IntegerMode = false;
+      ComplexMode = true;
+    } else if (Str[1] != 'I') {
+      DestWidth = 0;
+    }
+    break;
+  case 4:
+    // FIXME: glibc uses 'word' to define register_t; this is narrower than a
+    // pointer on PIC16 and other embedded platforms.
+    if (Str == "word")
+      DestWidth = S.Context.Target.getPointerWidth(0);
+    else if (Str == "byte")
+      DestWidth = S.Context.Target.getCharWidth();
+    break;
+  case 7:
+    if (Str == "pointer")
+      DestWidth = S.Context.Target.getPointerWidth(0);
+    break;
+  }
+
+  QualType OldTy;
+  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
+    OldTy = TD->getUnderlyingType();
+  else if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
+    OldTy = VD->getType();
+  else {
+    S.Diag(D->getLocation(), diag::err_attr_wrong_decl)
+      << "mode" << SourceRange(Attr.getLoc(), Attr.getLoc());
+    return;
+  }
+
+  if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType())
+    S.Diag(Attr.getLoc(), diag::err_mode_not_primitive);
+  else if (IntegerMode) {
+    if (!OldTy->isIntegralType())
+      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
+  } else if (ComplexMode) {
+    if (!OldTy->isComplexType())
+      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
+  } else {
+    if (!OldTy->isFloatingType())
+      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
+  }
+
+  // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t
+  // and friends, at least with glibc.
+  // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong
+  // width on unusual platforms.
+  // FIXME: Make sure floating-point mappings are accurate
+  // FIXME: Support XF and TF types
+  QualType NewTy;
+  switch (DestWidth) {
+  case 0:
+    S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name;
+    return;
+  default:
+    S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
+    return;
+  case 8:
+    if (!IntegerMode) {
+      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
+      return;
+    }
+    if (OldTy->isSignedIntegerType())
+      NewTy = S.Context.SignedCharTy;
+    else
+      NewTy = S.Context.UnsignedCharTy;
+    break;
+  case 16:
+    if (!IntegerMode) {
+      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
+      return;
+    }
+    if (OldTy->isSignedIntegerType())
+      NewTy = S.Context.ShortTy;
+    else
+      NewTy = S.Context.UnsignedShortTy;
+    break;
+  case 32:
+    if (!IntegerMode)
+      NewTy = S.Context.FloatTy;
+    else if (OldTy->isSignedIntegerType())
+      NewTy = S.Context.IntTy;
+    else
+      NewTy = S.Context.UnsignedIntTy;
+    break;
+  case 64:
+    if (!IntegerMode)
+      NewTy = S.Context.DoubleTy;
+    else if (OldTy->isSignedIntegerType())
+      if (S.Context.Target.getLongWidth() == 64)
+        NewTy = S.Context.LongTy;
+      else
+        NewTy = S.Context.LongLongTy;
+    else
+      if (S.Context.Target.getLongWidth() == 64)
+        NewTy = S.Context.UnsignedLongTy;
+      else
+        NewTy = S.Context.UnsignedLongLongTy;
+    break;
+  case 96:
+    NewTy = S.Context.LongDoubleTy;
+    break;
+  case 128:
+    if (!IntegerMode) {
+      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
+      return;
+    }
+    if (OldTy->isSignedIntegerType())
+      NewTy = S.Context.Int128Ty;
+    else
+      NewTy = S.Context.UnsignedInt128Ty;
+    break;
+  }
+
+  if (ComplexMode) {
+    NewTy = S.Context.getComplexType(NewTy);
+  }
+
+  // Install the new type.
+  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
+    // FIXME: preserve existing source info.
+    TD->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(NewTy));
+  } else
+    cast<ValueDecl>(D)->setType(NewTy);
+}
+
+static void HandleNoDebugAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+  // check the attribute arguments.
+  if (Attr.getNumArgs() > 0) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+    return;
+  }
+
+  if (!isFunctionOrMethod(d)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << 0 /*function*/;
+    return;
+  }
+
+  d->addAttr(::new (S.Context) NoDebugAttr());
+}
+
+static void HandleNoInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+  // check the attribute arguments.
+  if (Attr.getNumArgs() != 0) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+    return;
+  }
+
+  if (!isa<FunctionDecl>(d)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+    << Attr.getName() << 0 /*function*/;
+    return;
+  }
+
+  d->addAttr(::new (S.Context) NoInlineAttr());
+}
+
+static void HandleGNUInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+  // check the attribute arguments.
+  if (Attr.getNumArgs() != 0) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+    return;
+  }
+
+  FunctionDecl *Fn = dyn_cast<FunctionDecl>(d);
+  if (Fn == 0) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << 0 /*function*/;
+    return;
+  }
+
+  if (!Fn->isInlineSpecified()) {
+    S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline);
+    return;
+  }
+
+  d->addAttr(::new (S.Context) GNUInlineAttr());
+}
+
+static void HandleRegparmAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+  // check the attribute arguments.
+  if (Attr.getNumArgs() != 1) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
+    return;
+  }
+
+  if (!isFunctionOrMethod(d)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+    << Attr.getName() << 0 /*function*/;
+    return;
+  }
+
+  Expr *NumParamsExpr = static_cast<Expr *>(Attr.getArg(0));
+  llvm::APSInt NumParams(32);
+  if (!NumParamsExpr->isIntegerConstantExpr(NumParams, S.Context)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
+      << "regparm" << NumParamsExpr->getSourceRange();
+    return;
+  }
+
+  if (S.Context.Target.getRegParmMax() == 0) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform)
+      << NumParamsExpr->getSourceRange();
+    return;
+  }
+
+  if (NumParams.getLimitedValue(255) > S.Context.Target.getRegParmMax()) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number)
+      << S.Context.Target.getRegParmMax() << NumParamsExpr->getSourceRange();
+    return;
+  }
+
+  d->addAttr(::new (S.Context) RegparmAttr(NumParams.getZExtValue()));
+}
+
+static void HandleFinalAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+  // check the attribute arguments.
+  if (Attr.getNumArgs() != 0) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+    return;
+  }
+
+  if (!isa<CXXRecordDecl>(d)
+   && (!isa<CXXMethodDecl>(d) || !cast<CXXMethodDecl>(d)->isVirtual())) {
+    S.Diag(Attr.getLoc(),
+           Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
+                                   : diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << 7 /*virtual method or class*/;
+    return;
+  }
+  
+  // FIXME: Conform to C++0x redeclaration rules.
+  
+  if (d->getAttr<FinalAttr>()) {
+    S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "final";
+    return;
+  }
+
+  d->addAttr(::new (S.Context) FinalAttr());
+}
+
+//===----------------------------------------------------------------------===//
+// C++0x member checking attributes
+//===----------------------------------------------------------------------===//
+
+static void HandleBaseCheckAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+  if (Attr.getNumArgs() != 0) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+    return;
+  }
+  
+  if (!isa<CXXRecordDecl>(d)) {
+    S.Diag(Attr.getLoc(),
+           Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
+                                   : diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << 9 /*class*/;
+    return;
+  }
+  
+  if (d->getAttr<BaseCheckAttr>()) {
+    S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "base_check";
+    return;
+  }
+  
+  d->addAttr(::new (S.Context) BaseCheckAttr());
+}
+
+static void HandleHidingAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+  if (Attr.getNumArgs() != 0) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+    return;
+  }
+
+  if (!isa<RecordDecl>(d->getDeclContext())) {
+    // FIXME: It's not the type that's the problem
+    S.Diag(Attr.getLoc(),
+           Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
+                                   : diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << 11 /*member*/;
+    return;
+  }
+
+  // FIXME: Conform to C++0x redeclaration rules.
+
+  if (d->getAttr<HidingAttr>()) {
+    S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "hiding";
+    return;
+  }
+
+  d->addAttr(::new (S.Context) HidingAttr());
+}
+
+static void HandleOverrideAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+  if (Attr.getNumArgs() != 0) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+    return;
+  }
+
+  if (!isa<CXXMethodDecl>(d) || !cast<CXXMethodDecl>(d)->isVirtual()) {
+    // FIXME: It's not the type that's the problem
+    S.Diag(Attr.getLoc(),
+           Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
+                                   : diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << 10 /*virtual method*/;
+    return;
+  }
+
+  // FIXME: Conform to C++0x redeclaration rules.
+
+  if (d->getAttr<OverrideAttr>()) {
+    S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "override";
+    return;
+  }
+
+  d->addAttr(::new (S.Context) OverrideAttr());
+}
+
+//===----------------------------------------------------------------------===//
+// Checker-specific attribute handlers.
+//===----------------------------------------------------------------------===//
+
+static void HandleNSReturnsRetainedAttr(Decl *d, const AttributeList &Attr,
+                                        Sema &S) {
+
+  QualType RetTy;
+
+  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d))
+    RetTy = MD->getResultType();
+  else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d))
+    RetTy = FD->getResultType();
+  else {
+    SourceLocation L = Attr.getLoc();
+    S.Diag(d->getLocStart(), diag::warn_attribute_wrong_decl_type)
+        << SourceRange(L, L) << Attr.getName() << 3 /* function or method */;
+    return;
+  }
+
+  if (!(S.Context.isObjCNSObjectType(RetTy) || RetTy->getAs<PointerType>()
+        || RetTy->getAs<ObjCObjectPointerType>())) {
+    SourceLocation L = Attr.getLoc();
+    S.Diag(d->getLocStart(), diag::warn_ns_attribute_wrong_return_type)
+      << SourceRange(L, L) << Attr.getName();
+    return;
+  }
+
+  switch (Attr.getKind()) {
+    default:
+      assert(0 && "invalid ownership attribute");
+      return;
+    case AttributeList::AT_cf_returns_not_retained:
+      d->addAttr(::new (S.Context) CFReturnsNotRetainedAttr());
+      return;
+    case AttributeList::AT_ns_returns_not_retained:
+      d->addAttr(::new (S.Context) NSReturnsNotRetainedAttr());
+      return;
+    case AttributeList::AT_cf_returns_retained:
+      d->addAttr(::new (S.Context) CFReturnsRetainedAttr());
+      return;
+    case AttributeList::AT_ns_returns_retained:
+      d->addAttr(::new (S.Context) NSReturnsRetainedAttr());
+      return;
+  };
+}
+
+static bool isKnownDeclSpecAttr(const AttributeList &Attr) {
+  return Attr.getKind() == AttributeList::AT_dllimport ||
+         Attr.getKind() == AttributeList::AT_dllexport;
+}
+
+//===----------------------------------------------------------------------===//
+// Top Level Sema Entry Points
+//===----------------------------------------------------------------------===//
+
+/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if
+/// the attribute applies to decls.  If the attribute is a type attribute, just
+/// silently ignore it if a GNU attribute. FIXME: Applying a C++0x attribute to
+/// the wrong thing is illegal (C++0x [dcl.attr.grammar]/4).
+static void ProcessDeclAttribute(Scope *scope, Decl *D,
+                                 const AttributeList &Attr, Sema &S) {
+  if (Attr.isDeclspecAttribute() && !isKnownDeclSpecAttr(Attr))
+    // FIXME: Try to deal with other __declspec attributes!
+    return;
+  switch (Attr.getKind()) {
+  case AttributeList::AT_IBAction:            HandleIBAction(D, Attr, S); break;
+  case AttributeList::AT_IBOutlet:            HandleIBOutlet(D, Attr, S); break;
+  case AttributeList::AT_address_space:
+  case AttributeList::AT_objc_gc:
+  case AttributeList::AT_vector_size:
+    // Ignore these, these are type attributes, handled by
+    // ProcessTypeAttributes.
+    break;
+  case AttributeList::AT_alias:       HandleAliasAttr       (D, Attr, S); break;
+  case AttributeList::AT_aligned:     HandleAlignedAttr     (D, Attr, S); break;
+  case AttributeList::AT_always_inline:
+    HandleAlwaysInlineAttr  (D, Attr, S); break;
+  case AttributeList::AT_analyzer_noreturn:
+    HandleAnalyzerNoReturnAttr  (D, Attr, S); break;
+  case AttributeList::AT_annotate:    HandleAnnotateAttr    (D, Attr, S); break;
+  case AttributeList::AT_base_check:  HandleBaseCheckAttr   (D, Attr, S); break;
+  case AttributeList::AT_carries_dependency:
+                                      HandleDependencyAttr  (D, Attr, S); break;
+  case AttributeList::AT_constructor: HandleConstructorAttr (D, Attr, S); break;
+  case AttributeList::AT_deprecated:  HandleDeprecatedAttr  (D, Attr, S); break;
+  case AttributeList::AT_destructor:  HandleDestructorAttr  (D, Attr, S); break;
+  case AttributeList::AT_ext_vector_type:
+    HandleExtVectorTypeAttr(scope, D, Attr, S);
+    break;
+  case AttributeList::AT_final:       HandleFinalAttr       (D, Attr, S); break;
+  case AttributeList::AT_format:      HandleFormatAttr      (D, Attr, S); break;
+  case AttributeList::AT_format_arg:  HandleFormatArgAttr   (D, Attr, S); break;
+  case AttributeList::AT_gnu_inline:  HandleGNUInlineAttr   (D, Attr, S); break;
+  case AttributeList::AT_hiding:      HandleHidingAttr      (D, Attr, S); break;
+  case AttributeList::AT_mode:        HandleModeAttr        (D, Attr, S); break;
+  case AttributeList::AT_malloc:      HandleMallocAttr      (D, Attr, S); break;
+  case AttributeList::AT_nonnull:     HandleNonNullAttr     (D, Attr, S); break;
+  case AttributeList::AT_noreturn:    HandleNoReturnAttr    (D, Attr, S); break;
+  case AttributeList::AT_nothrow:     HandleNothrowAttr     (D, Attr, S); break;
+  case AttributeList::AT_override:    HandleOverrideAttr    (D, Attr, S); break;
+
+  // Checker-specific.
+  case AttributeList::AT_ns_returns_not_retained:
+  case AttributeList::AT_cf_returns_not_retained:
+  case AttributeList::AT_ns_returns_retained:
+  case AttributeList::AT_cf_returns_retained:
+    HandleNSReturnsRetainedAttr(D, Attr, S); break;
+
+  case AttributeList::AT_reqd_wg_size:
+    HandleReqdWorkGroupSize(D, Attr, S); break;
+
+  case AttributeList::AT_packed:      HandlePackedAttr      (D, Attr, S); break;
+  case AttributeList::AT_section:     HandleSectionAttr     (D, Attr, S); break;
+  case AttributeList::AT_unavailable: HandleUnavailableAttr (D, Attr, S); break;
+  case AttributeList::AT_unused:      HandleUnusedAttr      (D, Attr, S); break;
+  case AttributeList::AT_used:        HandleUsedAttr        (D, Attr, S); break;
+  case AttributeList::AT_visibility:  HandleVisibilityAttr  (D, Attr, S); break;
+  case AttributeList::AT_warn_unused_result: HandleWarnUnusedResult(D,Attr,S);
+    break;
+  case AttributeList::AT_weak:        HandleWeakAttr        (D, Attr, S); break;
+  case AttributeList::AT_weakref:     HandleWeakRefAttr     (D, Attr, S); break;
+  case AttributeList::AT_weak_import: HandleWeakImportAttr  (D, Attr, S); break;
+  case AttributeList::AT_transparent_union:
+    HandleTransparentUnionAttr(D, Attr, S);
+    break;
+  case AttributeList::AT_objc_exception:
+    HandleObjCExceptionAttr(D, Attr, S);
+    break;
+  case AttributeList::AT_overloadable:HandleOverloadableAttr(D, Attr, S); break;
+  case AttributeList::AT_nsobject:    HandleObjCNSObject    (D, Attr, S); break;
+  case AttributeList::AT_blocks:      HandleBlocksAttr      (D, Attr, S); break;
+  case AttributeList::AT_sentinel:    HandleSentinelAttr    (D, Attr, S); break;
+  case AttributeList::AT_const:       HandleConstAttr       (D, Attr, S); break;
+  case AttributeList::AT_pure:        HandlePureAttr        (D, Attr, S); break;
+  case AttributeList::AT_cleanup:     HandleCleanupAttr     (D, Attr, S); break;
+  case AttributeList::AT_nodebug:     HandleNoDebugAttr     (D, Attr, S); break;
+  case AttributeList::AT_noinline:    HandleNoInlineAttr    (D, Attr, S); break;
+  case AttributeList::AT_regparm:     HandleRegparmAttr     (D, Attr, S); break;
+  case AttributeList::IgnoredAttribute:
+  case AttributeList::AT_no_instrument_function:  // Interacts with -pg.
+    // Just ignore
+    break;
+  case AttributeList::AT_stdcall:
+  case AttributeList::AT_cdecl:
+  case AttributeList::AT_fastcall:
+    // These are all treated as type attributes.
+    break;
+  default:
+    // Ask target about the attribute.
+    const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema();
+    if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S))
+      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
+    break;
+  }
+}
+
+/// ProcessDeclAttributeList - Apply all the decl attributes in the specified
+/// attribute list to the specified decl, ignoring any type attributes.
+void Sema::ProcessDeclAttributeList(Scope *S, Decl *D, const AttributeList *AttrList) {
+  for (const AttributeList* l = AttrList; l; l = l->getNext()) {
+    ProcessDeclAttribute(S, D, *l, *this);
+  }
+
+  // GCC accepts
+  // static int a9 __attribute__((weakref));
+  // but that looks really pointless. We reject it.
+  if (D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) {
+    Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias) <<
+	dyn_cast<NamedDecl>(D)->getNameAsString();
+    return;
+  }
+}
+
+/// DeclClonePragmaWeak - clone existing decl (maybe definition),
+/// #pragma weak needs a non-definition decl and source may not have one
+NamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II) {
+  assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND));
+  NamedDecl *NewD = 0;
+  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
+    NewD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(),
+                                FD->getLocation(), DeclarationName(II),
+                                FD->getType(), FD->getTypeSourceInfo());
+    if (FD->getQualifier()) {
+      FunctionDecl *NewFD = cast<FunctionDecl>(NewD);
+      NewFD->setQualifierInfo(FD->getQualifier(), FD->getQualifierRange());
+    }
+  } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) {
+    NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(),
+                           VD->getLocation(), II,
+                           VD->getType(), VD->getTypeSourceInfo(),
+                           VD->getStorageClass(),
+                           VD->getStorageClassAsWritten());
+    if (VD->getQualifier()) {
+      VarDecl *NewVD = cast<VarDecl>(NewD);
+      NewVD->setQualifierInfo(VD->getQualifier(), VD->getQualifierRange());
+    }
+  }
+  return NewD;
+}
+
+/// DeclApplyPragmaWeak - A declaration (maybe definition) needs #pragma weak
+/// applied to it, possibly with an alias.
+void Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) {
+  if (W.getUsed()) return; // only do this once
+  W.setUsed(true);
+  if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...))
+    IdentifierInfo *NDId = ND->getIdentifier();
+    NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias());
+    NewD->addAttr(::new (Context) AliasAttr(Context, NDId->getName()));
+    NewD->addAttr(::new (Context) WeakAttr());
+    WeakTopLevelDecl.push_back(NewD);
+    // FIXME: "hideous" code from Sema::LazilyCreateBuiltin
+    // to insert Decl at TU scope, sorry.
+    DeclContext *SavedContext = CurContext;
+    CurContext = Context.getTranslationUnitDecl();
+    PushOnScopeChains(NewD, S);
+    CurContext = SavedContext;
+  } else { // just add weak to existing
+    ND->addAttr(::new (Context) WeakAttr());
+  }
+}
+
+/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
+/// it, apply them to D.  This is a bit tricky because PD can have attributes
+/// specified in many different places, and we need to find and apply them all.
+void Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD) {
+  // Handle #pragma weak
+  if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
+    if (ND->hasLinkage()) {
+      WeakInfo W = WeakUndeclaredIdentifiers.lookup(ND->getIdentifier());
+      if (W != WeakInfo()) {
+        // Identifier referenced by #pragma weak before it was declared
+        DeclApplyPragmaWeak(S, ND, W);
+        WeakUndeclaredIdentifiers[ND->getIdentifier()] = W;
+      }
+    }
+  }
+
+  // Apply decl attributes from the DeclSpec if present.
+  if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes())
+    ProcessDeclAttributeList(S, D, Attrs);
+
+  // Walk the declarator structure, applying decl attributes that were in a type
+  // position to the decl itself.  This handles cases like:
+  //   int *__attr__(x)** D;
+  // when X is a decl attribute.
+  for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i)
+    if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs())
+      ProcessDeclAttributeList(S, D, Attrs);
+
+  // Finally, apply any attributes on the decl itself.
+  if (const AttributeList *Attrs = PD.getAttributes())
+    ProcessDeclAttributeList(S, D, Attrs);
+}
+
+/// PushParsingDeclaration - Enter a new "scope" of deprecation
+/// warnings.
+///
+/// The state token we use is the start index of this scope
+/// on the warning stack.
+Action::ParsingDeclStackState Sema::PushParsingDeclaration() {
+  ParsingDeclDepth++;
+  return (ParsingDeclStackState) DelayedDiagnostics.size();
+}
+
+void Sema::PopParsingDeclaration(ParsingDeclStackState S, DeclPtrTy Ctx) {
+  assert(ParsingDeclDepth > 0 && "empty ParsingDeclaration stack");
+  ParsingDeclDepth--;
+
+  if (DelayedDiagnostics.empty())
+    return;
+
+  unsigned SavedIndex = (unsigned) S;
+  assert(SavedIndex <= DelayedDiagnostics.size() &&
+         "saved index is out of bounds");
+
+  unsigned E = DelayedDiagnostics.size();
+
+  // We only want to actually emit delayed diagnostics when we
+  // successfully parsed a decl.
+  Decl *D = Ctx ? Ctx.getAs<Decl>() : 0;
+  if (D) {
+    // We really do want to start with 0 here.  We get one push for a
+    // decl spec and another for each declarator;  in a decl group like:
+    //   deprecated_typedef foo, *bar, baz();
+    // only the declarator pops will be passed decls.  This is correct;
+    // we really do need to consider delayed diagnostics from the decl spec
+    // for each of the different declarations.
+    for (unsigned I = 0; I != E; ++I) {
+      if (DelayedDiagnostics[I].Triggered)
+        continue;
+
+      switch (DelayedDiagnostics[I].Kind) {
+      case DelayedDiagnostic::Deprecation:
+        HandleDelayedDeprecationCheck(DelayedDiagnostics[I], D);
+        break;
+
+      case DelayedDiagnostic::Access:
+        HandleDelayedAccessCheck(DelayedDiagnostics[I], D);
+        break;
+      }
+    }
+  }
+
+  // Destroy all the delayed diagnostics we're about to pop off.
+  for (unsigned I = SavedIndex; I != E; ++I)
+    DelayedDiagnostics[I].destroy();
+
+  DelayedDiagnostics.set_size(SavedIndex);
+}
+
+static bool isDeclDeprecated(Decl *D) {
+  do {
+    if (D->hasAttr<DeprecatedAttr>())
+      return true;
+  } while ((D = cast_or_null<Decl>(D->getDeclContext())));
+  return false;
+}
+
+void Sema::HandleDelayedDeprecationCheck(Sema::DelayedDiagnostic &DD,
+                                         Decl *Ctx) {
+  if (isDeclDeprecated(Ctx))
+    return;
+
+  DD.Triggered = true;
+  Diag(DD.Loc, diag::warn_deprecated)
+    << DD.DeprecationData.Decl->getDeclName();
+}
+
+void Sema::EmitDeprecationWarning(NamedDecl *D, SourceLocation Loc) {
+  // Delay if we're currently parsing a declaration.
+  if (ParsingDeclDepth) {
+    DelayedDiagnostics.push_back(DelayedDiagnostic::makeDeprecation(Loc, D));
+    return;
+  }
+
+  // Otherwise, don't warn if our current context is deprecated.
+  if (isDeclDeprecated(cast<Decl>(CurContext)))
+    return;
+
+  Diag(Loc, diag::warn_deprecated) << D->getDeclName();
+}
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
new file mode 100644
index 0000000..f6ff400
--- /dev/null
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -0,0 +1,5701 @@
+//===------ SemaDeclCXX.cpp - Semantic Analysis for C++ Declarations ------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements semantic analysis for C++ declarations.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Sema.h"
+#include "SemaInit.h"
+#include "Lookup.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/RecordLayout.h"
+#include "clang/AST/CXXInheritance.h"
+#include "clang/AST/DeclVisitor.h"
+#include "clang/AST/TypeLoc.h"
+#include "clang/AST/TypeOrdering.h"
+#include "clang/AST/StmtVisitor.h"
+#include "clang/Parse/DeclSpec.h"
+#include "clang/Parse/Template.h"
+#include "clang/Basic/PartialDiagnostic.h"
+#include "clang/Lex/Preprocessor.h"
+#include "llvm/ADT/STLExtras.h"
+#include <map>
+#include <set>
+
+using namespace clang;
+
+//===----------------------------------------------------------------------===//
+// CheckDefaultArgumentVisitor
+//===----------------------------------------------------------------------===//
+
+namespace {
+  /// CheckDefaultArgumentVisitor - C++ [dcl.fct.default] Traverses
+  /// the default argument of a parameter to determine whether it
+  /// contains any ill-formed subexpressions. For example, this will
+  /// diagnose the use of local variables or parameters within the
+  /// default argument expression.
+  class CheckDefaultArgumentVisitor
+    : public StmtVisitor<CheckDefaultArgumentVisitor, bool> {
+    Expr *DefaultArg;
+    Sema *S;
+
+  public:
+    CheckDefaultArgumentVisitor(Expr *defarg, Sema *s)
+      : DefaultArg(defarg), S(s) {}
+
+    bool VisitExpr(Expr *Node);
+    bool VisitDeclRefExpr(DeclRefExpr *DRE);
+    bool VisitCXXThisExpr(CXXThisExpr *ThisE);
+  };
+
+  /// VisitExpr - Visit all of the children of this expression.
+  bool CheckDefaultArgumentVisitor::VisitExpr(Expr *Node) {
+    bool IsInvalid = false;
+    for (Stmt::child_iterator I = Node->child_begin(),
+         E = Node->child_end(); I != E; ++I)
+      IsInvalid |= Visit(*I);
+    return IsInvalid;
+  }
+
+  /// VisitDeclRefExpr - Visit a reference to a declaration, to
+  /// determine whether this declaration can be used in the default
+  /// argument expression.
+  bool CheckDefaultArgumentVisitor::VisitDeclRefExpr(DeclRefExpr *DRE) {
+    NamedDecl *Decl = DRE->getDecl();
+    if (ParmVarDecl *Param = dyn_cast<ParmVarDecl>(Decl)) {
+      // C++ [dcl.fct.default]p9
+      //   Default arguments are evaluated each time the function is
+      //   called. The order of evaluation of function arguments is
+      //   unspecified. Consequently, parameters of a function shall not
+      //   be used in default argument expressions, even if they are not
+      //   evaluated. Parameters of a function declared before a default
+      //   argument expression are in scope and can hide namespace and
+      //   class member names.
+      return S->Diag(DRE->getSourceRange().getBegin(),
+                     diag::err_param_default_argument_references_param)
+         << Param->getDeclName() << DefaultArg->getSourceRange();
+    } else if (VarDecl *VDecl = dyn_cast<VarDecl>(Decl)) {
+      // C++ [dcl.fct.default]p7
+      //   Local variables shall not be used in default argument
+      //   expressions.
+      if (VDecl->isBlockVarDecl())
+        return S->Diag(DRE->getSourceRange().getBegin(),
+                       diag::err_param_default_argument_references_local)
+          << VDecl->getDeclName() << DefaultArg->getSourceRange();
+    }
+
+    return false;
+  }
+
+  /// VisitCXXThisExpr - Visit a C++ "this" expression.
+  bool CheckDefaultArgumentVisitor::VisitCXXThisExpr(CXXThisExpr *ThisE) {
+    // C++ [dcl.fct.default]p8:
+    //   The keyword this shall not be used in a default argument of a
+    //   member function.
+    return S->Diag(ThisE->getSourceRange().getBegin(),
+                   diag::err_param_default_argument_references_this)
+               << ThisE->getSourceRange();
+  }
+}
+
+bool
+Sema::SetParamDefaultArgument(ParmVarDecl *Param, ExprArg DefaultArg,
+                              SourceLocation EqualLoc) {
+  if (RequireCompleteType(Param->getLocation(), Param->getType(),
+                          diag::err_typecheck_decl_incomplete_type)) {
+    Param->setInvalidDecl();
+    return true;
+  }
+
+  Expr *Arg = (Expr *)DefaultArg.get();
+
+  // C++ [dcl.fct.default]p5
+  //   A default argument expression is implicitly converted (clause
+  //   4) to the parameter type. The default argument expression has
+  //   the same semantic constraints as the initializer expression in
+  //   a declaration of a variable of the parameter type, using the
+  //   copy-initialization semantics (8.5).
+  InitializedEntity Entity = InitializedEntity::InitializeParameter(Param);
+  InitializationKind Kind = InitializationKind::CreateCopy(Param->getLocation(),
+                                                           EqualLoc);
+  InitializationSequence InitSeq(*this, Entity, Kind, &Arg, 1);
+  OwningExprResult Result = InitSeq.Perform(*this, Entity, Kind,
+                                          MultiExprArg(*this, (void**)&Arg, 1));
+  if (Result.isInvalid())
+    return true;
+  Arg = Result.takeAs<Expr>();
+
+  Arg = MaybeCreateCXXExprWithTemporaries(Arg);
+
+  // Okay: add the default argument to the parameter
+  Param->setDefaultArg(Arg);
+
+  DefaultArg.release();
+
+  return false;
+}
+
+/// ActOnParamDefaultArgument - Check whether the default argument
+/// provided for a function parameter is well-formed. If so, attach it
+/// to the parameter declaration.
+void
+Sema::ActOnParamDefaultArgument(DeclPtrTy param, SourceLocation EqualLoc,
+                                ExprArg defarg) {
+  if (!param || !defarg.get())
+    return;
+
+  ParmVarDecl *Param = cast<ParmVarDecl>(param.getAs<Decl>());
+  UnparsedDefaultArgLocs.erase(Param);
+
+  ExprOwningPtr<Expr> DefaultArg(this, defarg.takeAs<Expr>());
+
+  // Default arguments are only permitted in C++
+  if (!getLangOptions().CPlusPlus) {
+    Diag(EqualLoc, diag::err_param_default_argument)
+      << DefaultArg->getSourceRange();
+    Param->setInvalidDecl();
+    return;
+  }
+
+  // Check that the default argument is well-formed
+  CheckDefaultArgumentVisitor DefaultArgChecker(DefaultArg.get(), this);
+  if (DefaultArgChecker.Visit(DefaultArg.get())) {
+    Param->setInvalidDecl();
+    return;
+  }
+
+  SetParamDefaultArgument(Param, move(DefaultArg), EqualLoc);
+}
+
+/// ActOnParamUnparsedDefaultArgument - We've seen a default
+/// argument for a function parameter, but we can't parse it yet
+/// because we're inside a class definition. Note that this default
+/// argument will be parsed later.
+void Sema::ActOnParamUnparsedDefaultArgument(DeclPtrTy param,
+                                             SourceLocation EqualLoc,
+                                             SourceLocation ArgLoc) {
+  if (!param)
+    return;
+
+  ParmVarDecl *Param = cast<ParmVarDecl>(param.getAs<Decl>());
+  if (Param)
+    Param->setUnparsedDefaultArg();
+
+  UnparsedDefaultArgLocs[Param] = ArgLoc;
+}
+
+/// ActOnParamDefaultArgumentError - Parsing or semantic analysis of
+/// the default argument for the parameter param failed.
+void Sema::ActOnParamDefaultArgumentError(DeclPtrTy param) {
+  if (!param)
+    return;
+
+  ParmVarDecl *Param = cast<ParmVarDecl>(param.getAs<Decl>());
+
+  Param->setInvalidDecl();
+
+  UnparsedDefaultArgLocs.erase(Param);
+}
+
+/// CheckExtraCXXDefaultArguments - Check for any extra default
+/// arguments in the declarator, which is not a function declaration
+/// or definition and therefore is not permitted to have default
+/// arguments. This routine should be invoked for every declarator
+/// that is not a function declaration or definition.
+void Sema::CheckExtraCXXDefaultArguments(Declarator &D) {
+  // C++ [dcl.fct.default]p3
+  //   A default argument expression shall be specified only in the
+  //   parameter-declaration-clause of a function declaration or in a
+  //   template-parameter (14.1). It shall not be specified for a
+  //   parameter pack. If it is specified in a
+  //   parameter-declaration-clause, it shall not occur within a
+  //   declarator or abstract-declarator of a parameter-declaration.
+  for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i) {
+    DeclaratorChunk &chunk = D.getTypeObject(i);
+    if (chunk.Kind == DeclaratorChunk::Function) {
+      for (unsigned argIdx = 0, e = chunk.Fun.NumArgs; argIdx != e; ++argIdx) {
+        ParmVarDecl *Param =
+          cast<ParmVarDecl>(chunk.Fun.ArgInfo[argIdx].Param.getAs<Decl>());
+        if (Param->hasUnparsedDefaultArg()) {
+          CachedTokens *Toks = chunk.Fun.ArgInfo[argIdx].DefaultArgTokens;
+          Diag(Param->getLocation(), diag::err_param_default_argument_nonfunc)
+            << SourceRange((*Toks)[1].getLocation(), Toks->back().getLocation());
+          delete Toks;
+          chunk.Fun.ArgInfo[argIdx].DefaultArgTokens = 0;
+        } else if (Param->getDefaultArg()) {
+          Diag(Param->getLocation(), diag::err_param_default_argument_nonfunc)
+            << Param->getDefaultArg()->getSourceRange();
+          Param->setDefaultArg(0);
+        }
+      }
+    }
+  }
+}
+
+// MergeCXXFunctionDecl - Merge two declarations of the same C++
+// function, once we already know that they have the same
+// type. Subroutine of MergeFunctionDecl. Returns true if there was an
+// error, false otherwise.
+bool Sema::MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old) {
+  bool Invalid = false;
+
+  // C++ [dcl.fct.default]p4:
+  //   For non-template functions, default arguments can be added in
+  //   later declarations of a function in the same
+  //   scope. Declarations in different scopes have completely
+  //   distinct sets of default arguments. That is, declarations in
+  //   inner scopes do not acquire default arguments from
+  //   declarations in outer scopes, and vice versa. In a given
+  //   function declaration, all parameters subsequent to a
+  //   parameter with a default argument shall have default
+  //   arguments supplied in this or previous declarations. A
+  //   default argument shall not be redefined by a later
+  //   declaration (not even to the same value).
+  //
+  // C++ [dcl.fct.default]p6:
+  //   Except for member functions of class templates, the default arguments 
+  //   in a member function definition that appears outside of the class 
+  //   definition are added to the set of default arguments provided by the 
+  //   member function declaration in the class definition.
+  for (unsigned p = 0, NumParams = Old->getNumParams(); p < NumParams; ++p) {
+    ParmVarDecl *OldParam = Old->getParamDecl(p);
+    ParmVarDecl *NewParam = New->getParamDecl(p);
+
+    if (OldParam->hasDefaultArg() && NewParam->hasDefaultArg()) {
+      // FIXME: If we knew where the '=' was, we could easily provide a fix-it 
+      // hint here. Alternatively, we could walk the type-source information
+      // for NewParam to find the last source location in the type... but it
+      // isn't worth the effort right now. This is the kind of test case that
+      // is hard to get right:
+      
+      //   int f(int);
+      //   void g(int (*fp)(int) = f);
+      //   void g(int (*fp)(int) = &f);
+      Diag(NewParam->getLocation(),
+           diag::err_param_default_argument_redefinition)
+        << NewParam->getDefaultArgRange();
+      
+      // Look for the function declaration where the default argument was
+      // actually written, which may be a declaration prior to Old.
+      for (FunctionDecl *Older = Old->getPreviousDeclaration();
+           Older; Older = Older->getPreviousDeclaration()) {
+        if (!Older->getParamDecl(p)->hasDefaultArg())
+          break;
+        
+        OldParam = Older->getParamDecl(p);
+      }        
+      
+      Diag(OldParam->getLocation(), diag::note_previous_definition)
+        << OldParam->getDefaultArgRange();
+      Invalid = true;
+    } else if (OldParam->hasDefaultArg()) {
+      // Merge the old default argument into the new parameter
+      NewParam->setHasInheritedDefaultArg();
+      if (OldParam->hasUninstantiatedDefaultArg())
+        NewParam->setUninstantiatedDefaultArg(
+                                      OldParam->getUninstantiatedDefaultArg());
+      else
+        NewParam->setDefaultArg(OldParam->getDefaultArg());
+    } else if (NewParam->hasDefaultArg()) {
+      if (New->getDescribedFunctionTemplate()) {
+        // Paragraph 4, quoted above, only applies to non-template functions.
+        Diag(NewParam->getLocation(),
+             diag::err_param_default_argument_template_redecl)
+          << NewParam->getDefaultArgRange();
+        Diag(Old->getLocation(), diag::note_template_prev_declaration)
+          << false;
+      } else if (New->getTemplateSpecializationKind()
+                   != TSK_ImplicitInstantiation &&
+                 New->getTemplateSpecializationKind() != TSK_Undeclared) {
+        // C++ [temp.expr.spec]p21:
+        //   Default function arguments shall not be specified in a declaration
+        //   or a definition for one of the following explicit specializations:
+        //     - the explicit specialization of a function template;
+        //     - the explicit specialization of a member function template;
+        //     - the explicit specialization of a member function of a class 
+        //       template where the class template specialization to which the
+        //       member function specialization belongs is implicitly 
+        //       instantiated.
+        Diag(NewParam->getLocation(), diag::err_template_spec_default_arg)
+          << (New->getTemplateSpecializationKind() ==TSK_ExplicitSpecialization)
+          << New->getDeclName()
+          << NewParam->getDefaultArgRange();
+      } else if (New->getDeclContext()->isDependentContext()) {
+        // C++ [dcl.fct.default]p6 (DR217):
+        //   Default arguments for a member function of a class template shall 
+        //   be specified on the initial declaration of the member function 
+        //   within the class template.
+        //
+        // Reading the tea leaves a bit in DR217 and its reference to DR205 
+        // leads me to the conclusion that one cannot add default function 
+        // arguments for an out-of-line definition of a member function of a 
+        // dependent type.
+        int WhichKind = 2;
+        if (CXXRecordDecl *Record 
+              = dyn_cast<CXXRecordDecl>(New->getDeclContext())) {
+          if (Record->getDescribedClassTemplate())
+            WhichKind = 0;
+          else if (isa<ClassTemplatePartialSpecializationDecl>(Record))
+            WhichKind = 1;
+          else
+            WhichKind = 2;
+        }
+        
+        Diag(NewParam->getLocation(), 
+             diag::err_param_default_argument_member_template_redecl)
+          << WhichKind
+          << NewParam->getDefaultArgRange();
+      }
+    }
+  }
+
+  if (CheckEquivalentExceptionSpec(Old, New))
+    Invalid = true;
+
+  return Invalid;
+}
+
+/// CheckCXXDefaultArguments - Verify that the default arguments for a
+/// function declaration are well-formed according to C++
+/// [dcl.fct.default].
+void Sema::CheckCXXDefaultArguments(FunctionDecl *FD) {
+  unsigned NumParams = FD->getNumParams();
+  unsigned p;
+
+  // Find first parameter with a default argument
+  for (p = 0; p < NumParams; ++p) {
+    ParmVarDecl *Param = FD->getParamDecl(p);
+    if (Param->hasDefaultArg())
+      break;
+  }
+
+  // C++ [dcl.fct.default]p4:
+  //   In a given function declaration, all parameters
+  //   subsequent to a parameter with a default argument shall
+  //   have default arguments supplied in this or previous
+  //   declarations. A default argument shall not be redefined
+  //   by a later declaration (not even to the same value).
+  unsigned LastMissingDefaultArg = 0;
+  for (; p < NumParams; ++p) {
+    ParmVarDecl *Param = FD->getParamDecl(p);
+    if (!Param->hasDefaultArg()) {
+      if (Param->isInvalidDecl())
+        /* We already complained about this parameter. */;
+      else if (Param->getIdentifier())
+        Diag(Param->getLocation(),
+             diag::err_param_default_argument_missing_name)
+          << Param->getIdentifier();
+      else
+        Diag(Param->getLocation(),
+             diag::err_param_default_argument_missing);
+
+      LastMissingDefaultArg = p;
+    }
+  }
+
+  if (LastMissingDefaultArg > 0) {
+    // Some default arguments were missing. Clear out all of the
+    // default arguments up to (and including) the last missing
+    // default argument, so that we leave the function parameters
+    // in a semantically valid state.
+    for (p = 0; p <= LastMissingDefaultArg; ++p) {
+      ParmVarDecl *Param = FD->getParamDecl(p);
+      if (Param->hasDefaultArg()) {
+        if (!Param->hasUnparsedDefaultArg())
+          Param->getDefaultArg()->Destroy(Context);
+        Param->setDefaultArg(0);
+      }
+    }
+  }
+}
+
+/// isCurrentClassName - Determine whether the identifier II is the
+/// name of the class type currently being defined. In the case of
+/// nested classes, this will only return true if II is the name of
+/// the innermost class.
+bool Sema::isCurrentClassName(const IdentifierInfo &II, Scope *,
+                              const CXXScopeSpec *SS) {
+  assert(getLangOptions().CPlusPlus && "No class names in C!");
+
+  CXXRecordDecl *CurDecl;
+  if (SS && SS->isSet() && !SS->isInvalid()) {
+    DeclContext *DC = computeDeclContext(*SS, true);
+    CurDecl = dyn_cast_or_null<CXXRecordDecl>(DC);
+  } else
+    CurDecl = dyn_cast_or_null<CXXRecordDecl>(CurContext);
+
+  if (CurDecl && CurDecl->getIdentifier())
+    return &II == CurDecl->getIdentifier();
+  else
+    return false;
+}
+
+/// \brief Check the validity of a C++ base class specifier.
+///
+/// \returns a new CXXBaseSpecifier if well-formed, emits diagnostics
+/// and returns NULL otherwise.
+CXXBaseSpecifier *
+Sema::CheckBaseSpecifier(CXXRecordDecl *Class,
+                         SourceRange SpecifierRange,
+                         bool Virtual, AccessSpecifier Access,
+                         QualType BaseType,
+                         SourceLocation BaseLoc) {
+  // C++ [class.union]p1:
+  //   A union shall not have base classes.
+  if (Class->isUnion()) {
+    Diag(Class->getLocation(), diag::err_base_clause_on_union)
+      << SpecifierRange;
+    return 0;
+  }
+
+  if (BaseType->isDependentType())
+    return new (Context) CXXBaseSpecifier(SpecifierRange, Virtual,
+                                Class->getTagKind() == RecordDecl::TK_class,
+                                Access, BaseType);
+
+  // Base specifiers must be record types.
+  if (!BaseType->isRecordType()) {
+    Diag(BaseLoc, diag::err_base_must_be_class) << SpecifierRange;
+    return 0;
+  }
+
+  // C++ [class.union]p1:
+  //   A union shall not be used as a base class.
+  if (BaseType->isUnionType()) {
+    Diag(BaseLoc, diag::err_union_as_base_class) << SpecifierRange;
+    return 0;
+  }
+
+  // C++ [class.derived]p2:
+  //   The class-name in a base-specifier shall not be an incompletely
+  //   defined class.
+  if (RequireCompleteType(BaseLoc, BaseType,
+                          PDiag(diag::err_incomplete_base_class)
+                            << SpecifierRange))
+    return 0;
+
+  // If the base class is polymorphic or isn't empty, the new one is/isn't, too.
+  RecordDecl *BaseDecl = BaseType->getAs<RecordType>()->getDecl();
+  assert(BaseDecl && "Record type has no declaration");
+  BaseDecl = BaseDecl->getDefinition();
+  assert(BaseDecl && "Base type is not incomplete, but has no definition");
+  CXXRecordDecl * CXXBaseDecl = cast<CXXRecordDecl>(BaseDecl);
+  assert(CXXBaseDecl && "Base type is not a C++ type");
+
+  // C++0x CWG Issue #817 indicates that [[final]] classes shouldn't be bases.
+  if (CXXBaseDecl->hasAttr<FinalAttr>()) {
+    Diag(BaseLoc, diag::err_final_base) << BaseType.getAsString();
+    Diag(CXXBaseDecl->getLocation(), diag::note_previous_decl)
+      << BaseType;
+    return 0;
+  }
+
+  SetClassDeclAttributesFromBase(Class, CXXBaseDecl, Virtual);
+  
+  // Create the base specifier.
+  // FIXME: Allocate via ASTContext?
+  return new (Context) CXXBaseSpecifier(SpecifierRange, Virtual,
+                              Class->getTagKind() == RecordDecl::TK_class,
+                              Access, BaseType);
+}
+
+void Sema::SetClassDeclAttributesFromBase(CXXRecordDecl *Class,
+                                          const CXXRecordDecl *BaseClass,
+                                          bool BaseIsVirtual) {
+  // A class with a non-empty base class is not empty.
+  // FIXME: Standard ref?
+  if (!BaseClass->isEmpty())
+    Class->setEmpty(false);
+
+  // C++ [class.virtual]p1:
+  //   A class that [...] inherits a virtual function is called a polymorphic
+  //   class.
+  if (BaseClass->isPolymorphic())
+    Class->setPolymorphic(true);
+
+  // C++ [dcl.init.aggr]p1:
+  //   An aggregate is [...] a class with [...] no base classes [...].
+  Class->setAggregate(false);
+
+  // C++ [class]p4:
+  //   A POD-struct is an aggregate class...
+  Class->setPOD(false);
+
+  if (BaseIsVirtual) {
+    // C++ [class.ctor]p5:
+    //   A constructor is trivial if its class has no virtual base classes.
+    Class->setHasTrivialConstructor(false);
+
+    // C++ [class.copy]p6:
+    //   A copy constructor is trivial if its class has no virtual base classes.
+    Class->setHasTrivialCopyConstructor(false);
+
+    // C++ [class.copy]p11:
+    //   A copy assignment operator is trivial if its class has no virtual
+    //   base classes.
+    Class->setHasTrivialCopyAssignment(false);
+
+    // C++0x [meta.unary.prop] is_empty:
+    //    T is a class type, but not a union type, with ... no virtual base
+    //    classes
+    Class->setEmpty(false);
+  } else {
+    // C++ [class.ctor]p5:
+    //   A constructor is trivial if all the direct base classes of its
+    //   class have trivial constructors.
+    if (!BaseClass->hasTrivialConstructor())
+      Class->setHasTrivialConstructor(false);
+
+    // C++ [class.copy]p6:
+    //   A copy constructor is trivial if all the direct base classes of its
+    //   class have trivial copy constructors.
+    if (!BaseClass->hasTrivialCopyConstructor())
+      Class->setHasTrivialCopyConstructor(false);
+
+    // C++ [class.copy]p11:
+    //   A copy assignment operator is trivial if all the direct base classes
+    //   of its class have trivial copy assignment operators.
+    if (!BaseClass->hasTrivialCopyAssignment())
+      Class->setHasTrivialCopyAssignment(false);
+  }
+
+  // C++ [class.ctor]p3:
+  //   A destructor is trivial if all the direct base classes of its class
+  //   have trivial destructors.
+  if (!BaseClass->hasTrivialDestructor())
+    Class->setHasTrivialDestructor(false);
+}
+
+/// ActOnBaseSpecifier - Parsed a base specifier. A base specifier is
+/// one entry in the base class list of a class specifier, for
+/// example:
+///    class foo : public bar, virtual private baz {
+/// 'public bar' and 'virtual private baz' are each base-specifiers.
+Sema::BaseResult
+Sema::ActOnBaseSpecifier(DeclPtrTy classdecl, SourceRange SpecifierRange,
+                         bool Virtual, AccessSpecifier Access,
+                         TypeTy *basetype, SourceLocation BaseLoc) {
+  if (!classdecl)
+    return true;
+
+  AdjustDeclIfTemplate(classdecl);
+  CXXRecordDecl *Class = dyn_cast<CXXRecordDecl>(classdecl.getAs<Decl>());
+  if (!Class)
+    return true;
+
+  QualType BaseType = GetTypeFromParser(basetype);
+  if (CXXBaseSpecifier *BaseSpec = CheckBaseSpecifier(Class, SpecifierRange,
+                                                      Virtual, Access,
+                                                      BaseType, BaseLoc))
+    return BaseSpec;
+
+  return true;
+}
+
+/// \brief Performs the actual work of attaching the given base class
+/// specifiers to a C++ class.
+bool Sema::AttachBaseSpecifiers(CXXRecordDecl *Class, CXXBaseSpecifier **Bases,
+                                unsigned NumBases) {
+ if (NumBases == 0)
+    return false;
+
+  // Used to keep track of which base types we have already seen, so
+  // that we can properly diagnose redundant direct base types. Note
+  // that the key is always the unqualified canonical type of the base
+  // class.
+  std::map<QualType, CXXBaseSpecifier*, QualTypeOrdering> KnownBaseTypes;
+
+  // Copy non-redundant base specifiers into permanent storage.
+  unsigned NumGoodBases = 0;
+  bool Invalid = false;
+  for (unsigned idx = 0; idx < NumBases; ++idx) {
+    QualType NewBaseType
+      = Context.getCanonicalType(Bases[idx]->getType());
+    NewBaseType = NewBaseType.getLocalUnqualifiedType();
+
+    if (KnownBaseTypes[NewBaseType]) {
+      // C++ [class.mi]p3:
+      //   A class shall not be specified as a direct base class of a
+      //   derived class more than once.
+      Diag(Bases[idx]->getSourceRange().getBegin(),
+           diag::err_duplicate_base_class)
+        << KnownBaseTypes[NewBaseType]->getType()
+        << Bases[idx]->getSourceRange();
+
+      // Delete the duplicate base class specifier; we're going to
+      // overwrite its pointer later.
+      Context.Deallocate(Bases[idx]);
+
+      Invalid = true;
+    } else {
+      // Okay, add this new base class.
+      KnownBaseTypes[NewBaseType] = Bases[idx];
+      Bases[NumGoodBases++] = Bases[idx];
+    }
+  }
+
+  // Attach the remaining base class specifiers to the derived class.
+  Class->setBases(Bases, NumGoodBases);
+
+  // Delete the remaining (good) base class specifiers, since their
+  // data has been copied into the CXXRecordDecl.
+  for (unsigned idx = 0; idx < NumGoodBases; ++idx)
+    Context.Deallocate(Bases[idx]);
+
+  return Invalid;
+}
+
+/// ActOnBaseSpecifiers - Attach the given base specifiers to the
+/// class, after checking whether there are any duplicate base
+/// classes.
+void Sema::ActOnBaseSpecifiers(DeclPtrTy ClassDecl, BaseTy **Bases,
+                               unsigned NumBases) {
+  if (!ClassDecl || !Bases || !NumBases)
+    return;
+
+  AdjustDeclIfTemplate(ClassDecl);
+  AttachBaseSpecifiers(cast<CXXRecordDecl>(ClassDecl.getAs<Decl>()),
+                       (CXXBaseSpecifier**)(Bases), NumBases);
+}
+
+static CXXRecordDecl *GetClassForType(QualType T) {
+  if (const RecordType *RT = T->getAs<RecordType>())
+    return cast<CXXRecordDecl>(RT->getDecl());
+  else if (const InjectedClassNameType *ICT = T->getAs<InjectedClassNameType>())
+    return ICT->getDecl();
+  else
+    return 0;
+}
+
+/// \brief Determine whether the type \p Derived is a C++ class that is
+/// derived from the type \p Base.
+bool Sema::IsDerivedFrom(QualType Derived, QualType Base) {
+  if (!getLangOptions().CPlusPlus)
+    return false;
+  
+  CXXRecordDecl *DerivedRD = GetClassForType(Derived);
+  if (!DerivedRD)
+    return false;
+  
+  CXXRecordDecl *BaseRD = GetClassForType(Base);
+  if (!BaseRD)
+    return false;
+  
+  // FIXME: instantiate DerivedRD if necessary.  We need a PoI for this.
+  return DerivedRD->hasDefinition() && DerivedRD->isDerivedFrom(BaseRD);
+}
+
+/// \brief Determine whether the type \p Derived is a C++ class that is
+/// derived from the type \p Base.
+bool Sema::IsDerivedFrom(QualType Derived, QualType Base, CXXBasePaths &Paths) {
+  if (!getLangOptions().CPlusPlus)
+    return false;
+  
+  CXXRecordDecl *DerivedRD = GetClassForType(Derived);
+  if (!DerivedRD)
+    return false;
+  
+  CXXRecordDecl *BaseRD = GetClassForType(Base);
+  if (!BaseRD)
+    return false;
+  
+  return DerivedRD->isDerivedFrom(BaseRD, Paths);
+}
+
+void Sema::BuildBasePathArray(const CXXBasePaths &Paths, 
+                              CXXBaseSpecifierArray &BasePathArray) {
+  assert(BasePathArray.empty() && "Base path array must be empty!");
+  assert(Paths.isRecordingPaths() && "Must record paths!");
+  
+  const CXXBasePath &Path = Paths.front();
+       
+  // We first go backward and check if we have a virtual base.
+  // FIXME: It would be better if CXXBasePath had the base specifier for
+  // the nearest virtual base.
+  unsigned Start = 0;
+  for (unsigned I = Path.size(); I != 0; --I) {
+    if (Path[I - 1].Base->isVirtual()) {
+      Start = I - 1;
+      break;
+    }
+  }
+
+  // Now add all bases.
+  for (unsigned I = Start, E = Path.size(); I != E; ++I)
+    BasePathArray.push_back(Path[I].Base);
+}
+
+/// CheckDerivedToBaseConversion - Check whether the Derived-to-Base
+/// conversion (where Derived and Base are class types) is
+/// well-formed, meaning that the conversion is unambiguous (and
+/// that all of the base classes are accessible). Returns true
+/// and emits a diagnostic if the code is ill-formed, returns false
+/// otherwise. Loc is the location where this routine should point to
+/// if there is an error, and Range is the source range to highlight
+/// if there is an error.
+bool
+Sema::CheckDerivedToBaseConversion(QualType Derived, QualType Base,
+                                   unsigned InaccessibleBaseID,
+                                   unsigned AmbigiousBaseConvID,
+                                   SourceLocation Loc, SourceRange Range,
+                                   DeclarationName Name,
+                                   CXXBaseSpecifierArray *BasePath) {
+  // First, determine whether the path from Derived to Base is
+  // ambiguous. This is slightly more expensive than checking whether
+  // the Derived to Base conversion exists, because here we need to
+  // explore multiple paths to determine if there is an ambiguity.
+  CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
+                     /*DetectVirtual=*/false);
+  bool DerivationOkay = IsDerivedFrom(Derived, Base, Paths);
+  assert(DerivationOkay &&
+         "Can only be used with a derived-to-base conversion");
+  (void)DerivationOkay;
+  
+  if (!Paths.isAmbiguous(Context.getCanonicalType(Base).getUnqualifiedType())) {
+    if (InaccessibleBaseID) {
+      // Check that the base class can be accessed.
+      switch (CheckBaseClassAccess(Loc, Base, Derived, Paths.front(),
+                                   InaccessibleBaseID)) {
+        case AR_inaccessible: 
+          return true;
+        case AR_accessible: 
+        case AR_dependent:
+        case AR_delayed:
+          break;
+      }
+    }
+    
+    // Build a base path if necessary.
+    if (BasePath)
+      BuildBasePathArray(Paths, *BasePath);
+    return false;
+  }
+  
+  // We know that the derived-to-base conversion is ambiguous, and
+  // we're going to produce a diagnostic. Perform the derived-to-base
+  // search just one more time to compute all of the possible paths so
+  // that we can print them out. This is more expensive than any of
+  // the previous derived-to-base checks we've done, but at this point
+  // performance isn't as much of an issue.
+  Paths.clear();
+  Paths.setRecordingPaths(true);
+  bool StillOkay = IsDerivedFrom(Derived, Base, Paths);
+  assert(StillOkay && "Can only be used with a derived-to-base conversion");
+  (void)StillOkay;
+  
+  // Build up a textual representation of the ambiguous paths, e.g.,
+  // D -> B -> A, that will be used to illustrate the ambiguous
+  // conversions in the diagnostic. We only print one of the paths
+  // to each base class subobject.
+  std::string PathDisplayStr = getAmbiguousPathsDisplayString(Paths);
+  
+  Diag(Loc, AmbigiousBaseConvID)
+  << Derived << Base << PathDisplayStr << Range << Name;
+  return true;
+}
+
+bool
+Sema::CheckDerivedToBaseConversion(QualType Derived, QualType Base,
+                                   SourceLocation Loc, SourceRange Range,
+                                   CXXBaseSpecifierArray *BasePath,
+                                   bool IgnoreAccess) {
+  return CheckDerivedToBaseConversion(Derived, Base,
+                                      IgnoreAccess ? 0
+                                       : diag::err_upcast_to_inaccessible_base,
+                                      diag::err_ambiguous_derived_to_base_conv,
+                                      Loc, Range, DeclarationName(), 
+                                      BasePath);
+}
+
+
+/// @brief Builds a string representing ambiguous paths from a
+/// specific derived class to different subobjects of the same base
+/// class.
+///
+/// This function builds a string that can be used in error messages
+/// to show the different paths that one can take through the
+/// inheritance hierarchy to go from the derived class to different
+/// subobjects of a base class. The result looks something like this:
+/// @code
+/// struct D -> struct B -> struct A
+/// struct D -> struct C -> struct A
+/// @endcode
+std::string Sema::getAmbiguousPathsDisplayString(CXXBasePaths &Paths) {
+  std::string PathDisplayStr;
+  std::set<unsigned> DisplayedPaths;
+  for (CXXBasePaths::paths_iterator Path = Paths.begin();
+       Path != Paths.end(); ++Path) {
+    if (DisplayedPaths.insert(Path->back().SubobjectNumber).second) {
+      // We haven't displayed a path to this particular base
+      // class subobject yet.
+      PathDisplayStr += "\n    ";
+      PathDisplayStr += Context.getTypeDeclType(Paths.getOrigin()).getAsString();
+      for (CXXBasePath::const_iterator Element = Path->begin();
+           Element != Path->end(); ++Element)
+        PathDisplayStr += " -> " + Element->Base->getType().getAsString();
+    }
+  }
+  
+  return PathDisplayStr;
+}
+
+//===----------------------------------------------------------------------===//
+// C++ class member Handling
+//===----------------------------------------------------------------------===//
+
+/// ActOnCXXMemberDeclarator - This is invoked when a C++ class member
+/// declarator is parsed. 'AS' is the access specifier, 'BW' specifies the
+/// bitfield width if there is one and 'InitExpr' specifies the initializer if
+/// any.
+Sema::DeclPtrTy
+Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D,
+                               MultiTemplateParamsArg TemplateParameterLists,
+                               ExprTy *BW, ExprTy *InitExpr, bool IsDefinition,
+                               bool Deleted) {
+  const DeclSpec &DS = D.getDeclSpec();
+  DeclarationName Name = GetNameForDeclarator(D);
+  Expr *BitWidth = static_cast<Expr*>(BW);
+  Expr *Init = static_cast<Expr*>(InitExpr);
+  SourceLocation Loc = D.getIdentifierLoc();
+
+  bool isFunc = D.isFunctionDeclarator();
+
+  assert(!DS.isFriendSpecified());
+
+  // C++ 9.2p6: A member shall not be declared to have automatic storage
+  // duration (auto, register) or with the extern storage-class-specifier.
+  // C++ 7.1.1p8: The mutable specifier can be applied only to names of class
+  // data members and cannot be applied to names declared const or static,
+  // and cannot be applied to reference members.
+  switch (DS.getStorageClassSpec()) {
+    case DeclSpec::SCS_unspecified:
+    case DeclSpec::SCS_typedef:
+    case DeclSpec::SCS_static:
+      // FALL THROUGH.
+      break;
+    case DeclSpec::SCS_mutable:
+      if (isFunc) {
+        if (DS.getStorageClassSpecLoc().isValid())
+          Diag(DS.getStorageClassSpecLoc(), diag::err_mutable_function);
+        else
+          Diag(DS.getThreadSpecLoc(), diag::err_mutable_function);
+
+        // FIXME: It would be nicer if the keyword was ignored only for this
+        // declarator. Otherwise we could get follow-up errors.
+        D.getMutableDeclSpec().ClearStorageClassSpecs();
+      } else {
+        QualType T = GetTypeForDeclarator(D, S);
+        diag::kind err = static_cast<diag::kind>(0);
+        if (T->isReferenceType())
+          err = diag::err_mutable_reference;
+        else if (T.isConstQualified())
+          err = diag::err_mutable_const;
+        if (err != 0) {
+          if (DS.getStorageClassSpecLoc().isValid())
+            Diag(DS.getStorageClassSpecLoc(), err);
+          else
+            Diag(DS.getThreadSpecLoc(), err);
+          // FIXME: It would be nicer if the keyword was ignored only for this
+          // declarator. Otherwise we could get follow-up errors.
+          D.getMutableDeclSpec().ClearStorageClassSpecs();
+        }
+      }
+      break;
+    default:
+      if (DS.getStorageClassSpecLoc().isValid())
+        Diag(DS.getStorageClassSpecLoc(),
+             diag::err_storageclass_invalid_for_member);
+      else
+        Diag(DS.getThreadSpecLoc(), diag::err_storageclass_invalid_for_member);
+      D.getMutableDeclSpec().ClearStorageClassSpecs();
+  }
+
+  if (!isFunc &&
+      D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_typename &&
+      D.getNumTypeObjects() == 0) {
+    // Check also for this case:
+    //
+    // typedef int f();
+    // f a;
+    //
+    QualType TDType = GetTypeFromParser(DS.getTypeRep());
+    isFunc = TDType->isFunctionType();
+  }
+
+  bool isInstField = ((DS.getStorageClassSpec() == DeclSpec::SCS_unspecified ||
+                       DS.getStorageClassSpec() == DeclSpec::SCS_mutable) &&
+                      !isFunc);
+
+  Decl *Member;
+  if (isInstField) {
+    // FIXME: Check for template parameters!
+    Member = HandleField(S, cast<CXXRecordDecl>(CurContext), Loc, D, BitWidth,
+                         AS);
+    assert(Member && "HandleField never returns null");
+  } else {
+    Member = HandleDeclarator(S, D, move(TemplateParameterLists), IsDefinition)
+               .getAs<Decl>();
+    if (!Member) {
+      if (BitWidth) DeleteExpr(BitWidth);
+      return DeclPtrTy();
+    }
+
+    // Non-instance-fields can't have a bitfield.
+    if (BitWidth) {
+      if (Member->isInvalidDecl()) {
+        // don't emit another diagnostic.
+      } else if (isa<VarDecl>(Member)) {
+        // C++ 9.6p3: A bit-field shall not be a static member.
+        // "static member 'A' cannot be a bit-field"
+        Diag(Loc, diag::err_static_not_bitfield)
+          << Name << BitWidth->getSourceRange();
+      } else if (isa<TypedefDecl>(Member)) {
+        // "typedef member 'x' cannot be a bit-field"
+        Diag(Loc, diag::err_typedef_not_bitfield)
+          << Name << BitWidth->getSourceRange();
+      } else {
+        // A function typedef ("typedef int f(); f a;").
+        // C++ 9.6p3: A bit-field shall have integral or enumeration type.
+        Diag(Loc, diag::err_not_integral_type_bitfield)
+          << Name << cast<ValueDecl>(Member)->getType()
+          << BitWidth->getSourceRange();
+      }
+
+      DeleteExpr(BitWidth);
+      BitWidth = 0;
+      Member->setInvalidDecl();
+    }
+
+    Member->setAccess(AS);
+
+    // If we have declared a member function template, set the access of the
+    // templated declaration as well.
+    if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(Member))
+      FunTmpl->getTemplatedDecl()->setAccess(AS);
+  }
+
+  assert((Name || isInstField) && "No identifier for non-field ?");
+
+  if (Init)
+    AddInitializerToDecl(DeclPtrTy::make(Member), ExprArg(*this, Init), false);
+  if (Deleted) // FIXME: Source location is not very good.
+    SetDeclDeleted(DeclPtrTy::make(Member), D.getSourceRange().getBegin());
+
+  if (isInstField) {
+    FieldCollector->Add(cast<FieldDecl>(Member));
+    return DeclPtrTy();
+  }
+  return DeclPtrTy::make(Member);
+}
+
+/// \brief Find the direct and/or virtual base specifiers that
+/// correspond to the given base type, for use in base initialization
+/// within a constructor.
+static bool FindBaseInitializer(Sema &SemaRef, 
+                                CXXRecordDecl *ClassDecl,
+                                QualType BaseType,
+                                const CXXBaseSpecifier *&DirectBaseSpec,
+                                const CXXBaseSpecifier *&VirtualBaseSpec) {
+  // First, check for a direct base class.
+  DirectBaseSpec = 0;
+  for (CXXRecordDecl::base_class_const_iterator Base
+         = ClassDecl->bases_begin(); 
+       Base != ClassDecl->bases_end(); ++Base) {
+    if (SemaRef.Context.hasSameUnqualifiedType(BaseType, Base->getType())) {
+      // We found a direct base of this type. That's what we're
+      // initializing.
+      DirectBaseSpec = &*Base;
+      break;
+    }
+  }
+
+  // Check for a virtual base class.
+  // FIXME: We might be able to short-circuit this if we know in advance that
+  // there are no virtual bases.
+  VirtualBaseSpec = 0;
+  if (!DirectBaseSpec || !DirectBaseSpec->isVirtual()) {
+    // We haven't found a base yet; search the class hierarchy for a
+    // virtual base class.
+    CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
+                       /*DetectVirtual=*/false);
+    if (SemaRef.IsDerivedFrom(SemaRef.Context.getTypeDeclType(ClassDecl), 
+                              BaseType, Paths)) {
+      for (CXXBasePaths::paths_iterator Path = Paths.begin();
+           Path != Paths.end(); ++Path) {
+        if (Path->back().Base->isVirtual()) {
+          VirtualBaseSpec = Path->back().Base;
+          break;
+        }
+      }
+    }
+  }
+
+  return DirectBaseSpec || VirtualBaseSpec;
+}
+
+/// ActOnMemInitializer - Handle a C++ member initializer.
+Sema::MemInitResult
+Sema::ActOnMemInitializer(DeclPtrTy ConstructorD,
+                          Scope *S,
+                          CXXScopeSpec &SS,
+                          IdentifierInfo *MemberOrBase,
+                          TypeTy *TemplateTypeTy,
+                          SourceLocation IdLoc,
+                          SourceLocation LParenLoc,
+                          ExprTy **Args, unsigned NumArgs,
+                          SourceLocation *CommaLocs,
+                          SourceLocation RParenLoc) {
+  if (!ConstructorD)
+    return true;
+
+  AdjustDeclIfTemplate(ConstructorD);
+
+  CXXConstructorDecl *Constructor
+    = dyn_cast<CXXConstructorDecl>(ConstructorD.getAs<Decl>());
+  if (!Constructor) {
+    // The user wrote a constructor initializer on a function that is
+    // not a C++ constructor. Ignore the error for now, because we may
+    // have more member initializers coming; we'll diagnose it just
+    // once in ActOnMemInitializers.
+    return true;
+  }
+
+  CXXRecordDecl *ClassDecl = Constructor->getParent();
+
+  // C++ [class.base.init]p2:
+  //   Names in a mem-initializer-id are looked up in the scope of the
+  //   constructor’s class and, if not found in that scope, are looked
+  //   up in the scope containing the constructor’s
+  //   definition. [Note: if the constructor’s class contains a member
+  //   with the same name as a direct or virtual base class of the
+  //   class, a mem-initializer-id naming the member or base class and
+  //   composed of a single identifier refers to the class member. A
+  //   mem-initializer-id for the hidden base class may be specified
+  //   using a qualified name. ]
+  if (!SS.getScopeRep() && !TemplateTypeTy) {
+    // Look for a member, first.
+    FieldDecl *Member = 0;
+    DeclContext::lookup_result Result
+      = ClassDecl->lookup(MemberOrBase);
+    if (Result.first != Result.second)
+      Member = dyn_cast<FieldDecl>(*Result.first);
+
+    // FIXME: Handle members of an anonymous union.
+
+    if (Member)
+      return BuildMemberInitializer(Member, (Expr**)Args, NumArgs, IdLoc,
+                                    LParenLoc, RParenLoc);
+  }
+  // It didn't name a member, so see if it names a class.
+  QualType BaseType;
+  TypeSourceInfo *TInfo = 0;
+
+  if (TemplateTypeTy) {
+    BaseType = GetTypeFromParser(TemplateTypeTy, &TInfo);
+  } else {
+    LookupResult R(*this, MemberOrBase, IdLoc, LookupOrdinaryName);
+    LookupParsedName(R, S, &SS);
+
+    TypeDecl *TyD = R.getAsSingle<TypeDecl>();
+    if (!TyD) {
+      if (R.isAmbiguous()) return true;
+
+      // We don't want access-control diagnostics here.
+      R.suppressDiagnostics();
+
+      if (SS.isSet() && isDependentScopeSpecifier(SS)) {
+        bool NotUnknownSpecialization = false;
+        DeclContext *DC = computeDeclContext(SS, false);
+        if (CXXRecordDecl *Record = dyn_cast_or_null<CXXRecordDecl>(DC)) 
+          NotUnknownSpecialization = !Record->hasAnyDependentBases();
+
+        if (!NotUnknownSpecialization) {
+          // When the scope specifier can refer to a member of an unknown
+          // specialization, we take it as a type name.
+          BaseType = CheckTypenameType(ETK_None,
+                                       (NestedNameSpecifier *)SS.getScopeRep(),
+                                       *MemberOrBase, SS.getRange());
+          if (BaseType.isNull())
+            return true;
+
+          R.clear();
+        }
+      }
+
+      // If no results were found, try to correct typos.
+      if (R.empty() && BaseType.isNull() &&
+          CorrectTypo(R, S, &SS, ClassDecl, 0, CTC_NoKeywords) && 
+          R.isSingleResult()) {
+        if (FieldDecl *Member = R.getAsSingle<FieldDecl>()) {
+          if (Member->getDeclContext()->getLookupContext()->Equals(ClassDecl)) {
+            // We have found a non-static data member with a similar
+            // name to what was typed; complain and initialize that
+            // member.
+            Diag(R.getNameLoc(), diag::err_mem_init_not_member_or_class_suggest)
+              << MemberOrBase << true << R.getLookupName()
+              << FixItHint::CreateReplacement(R.getNameLoc(),
+                                              R.getLookupName().getAsString());
+            Diag(Member->getLocation(), diag::note_previous_decl)
+              << Member->getDeclName();
+
+            return BuildMemberInitializer(Member, (Expr**)Args, NumArgs, IdLoc,
+                                          LParenLoc, RParenLoc);
+          }
+        } else if (TypeDecl *Type = R.getAsSingle<TypeDecl>()) {
+          const CXXBaseSpecifier *DirectBaseSpec;
+          const CXXBaseSpecifier *VirtualBaseSpec;
+          if (FindBaseInitializer(*this, ClassDecl, 
+                                  Context.getTypeDeclType(Type),
+                                  DirectBaseSpec, VirtualBaseSpec)) {
+            // We have found a direct or virtual base class with a
+            // similar name to what was typed; complain and initialize
+            // that base class.
+            Diag(R.getNameLoc(), diag::err_mem_init_not_member_or_class_suggest)
+              << MemberOrBase << false << R.getLookupName()
+              << FixItHint::CreateReplacement(R.getNameLoc(),
+                                              R.getLookupName().getAsString());
+
+            const CXXBaseSpecifier *BaseSpec = DirectBaseSpec? DirectBaseSpec 
+                                                             : VirtualBaseSpec;
+            Diag(BaseSpec->getSourceRange().getBegin(),
+                 diag::note_base_class_specified_here)
+              << BaseSpec->getType()
+              << BaseSpec->getSourceRange();
+
+            TyD = Type;
+          }
+        }
+      }
+
+      if (!TyD && BaseType.isNull()) {
+        Diag(IdLoc, diag::err_mem_init_not_member_or_class)
+          << MemberOrBase << SourceRange(IdLoc, RParenLoc);
+        return true;
+      }
+    }
+
+    if (BaseType.isNull()) {
+      BaseType = Context.getTypeDeclType(TyD);
+      if (SS.isSet()) {
+        NestedNameSpecifier *Qualifier =
+          static_cast<NestedNameSpecifier*>(SS.getScopeRep());
+
+        // FIXME: preserve source range information
+        BaseType = Context.getQualifiedNameType(Qualifier, BaseType);
+      }
+    }
+  }
+
+  if (!TInfo)
+    TInfo = Context.getTrivialTypeSourceInfo(BaseType, IdLoc);
+
+  return BuildBaseInitializer(BaseType, TInfo, (Expr **)Args, NumArgs, 
+                              LParenLoc, RParenLoc, ClassDecl);
+}
+
+/// Checks an initializer expression for use of uninitialized fields, such as
+/// containing the field that is being initialized. Returns true if there is an
+/// uninitialized field was used an updates the SourceLocation parameter; false
+/// otherwise.
+static bool InitExprContainsUninitializedFields(const Stmt* S,
+                                                const FieldDecl* LhsField,
+                                                SourceLocation* L) {
+  const MemberExpr* ME = dyn_cast<MemberExpr>(S);
+  if (ME) {
+    const NamedDecl* RhsField = ME->getMemberDecl();
+    if (RhsField == LhsField) {
+      // Initializing a field with itself. Throw a warning.
+      // But wait; there are exceptions!
+      // Exception #1:  The field may not belong to this record.
+      // e.g. Foo(const Foo& rhs) : A(rhs.A) {}
+      const Expr* base = ME->getBase();
+      if (base != NULL && !isa<CXXThisExpr>(base->IgnoreParenCasts())) {
+        // Even though the field matches, it does not belong to this record.
+        return false;
+      }
+      // None of the exceptions triggered; return true to indicate an
+      // uninitialized field was used.
+      *L = ME->getMemberLoc();
+      return true;
+    }
+  }
+  bool found = false;
+  for (Stmt::const_child_iterator it = S->child_begin();
+       it != S->child_end() && found == false;
+       ++it) {
+    if (isa<CallExpr>(S)) {
+      // Do not descend into function calls or constructors, as the use
+      // of an uninitialized field may be valid. One would have to inspect
+      // the contents of the function/ctor to determine if it is safe or not.
+      // i.e. Pass-by-value is never safe, but pass-by-reference and pointers
+      // may be safe, depending on what the function/ctor does.
+      continue;
+    }
+    found = InitExprContainsUninitializedFields(*it, LhsField, L);
+  }
+  return found;
+}
+
+Sema::MemInitResult
+Sema::BuildMemberInitializer(FieldDecl *Member, Expr **Args,
+                             unsigned NumArgs, SourceLocation IdLoc,
+                             SourceLocation LParenLoc,
+                             SourceLocation RParenLoc) {
+  // Diagnose value-uses of fields to initialize themselves, e.g.
+  //   foo(foo)
+  // where foo is not also a parameter to the constructor.
+  // TODO: implement -Wuninitialized and fold this into that framework.
+  for (unsigned i = 0; i < NumArgs; ++i) {
+    SourceLocation L;
+    if (InitExprContainsUninitializedFields(Args[i], Member, &L)) {
+      // FIXME: Return true in the case when other fields are used before being
+      // uninitialized. For example, let this field be the i'th field. When
+      // initializing the i'th field, throw a warning if any of the >= i'th
+      // fields are used, as they are not yet initialized.
+      // Right now we are only handling the case where the i'th field uses
+      // itself in its initializer.
+      Diag(L, diag::warn_field_is_uninit);
+    }
+  }
+
+  bool HasDependentArg = false;
+  for (unsigned i = 0; i < NumArgs; i++)
+    HasDependentArg |= Args[i]->isTypeDependent();
+
+  QualType FieldType = Member->getType();
+  if (const ArrayType *Array = Context.getAsArrayType(FieldType))
+    FieldType = Array->getElementType();
+  if (FieldType->isDependentType() || HasDependentArg) {
+    // Can't check initialization for a member of dependent type or when
+    // any of the arguments are type-dependent expressions.
+    OwningExprResult Init
+      = Owned(new (Context) ParenListExpr(Context, LParenLoc, Args, NumArgs,
+                                          RParenLoc));
+
+    // Erase any temporaries within this evaluation context; we're not
+    // going to track them in the AST, since we'll be rebuilding the
+    // ASTs during template instantiation.
+    ExprTemporaries.erase(
+              ExprTemporaries.begin() + ExprEvalContexts.back().NumTemporaries,
+                          ExprTemporaries.end());
+    
+    return new (Context) CXXBaseOrMemberInitializer(Context, Member, IdLoc,
+                                                    LParenLoc, 
+                                                    Init.takeAs<Expr>(),
+                                                    RParenLoc);
+    
+  }
+  
+  if (Member->isInvalidDecl())
+    return true;
+  
+  // Initialize the member.
+  InitializedEntity MemberEntity =
+    InitializedEntity::InitializeMember(Member, 0);
+  InitializationKind Kind = 
+    InitializationKind::CreateDirect(IdLoc, LParenLoc, RParenLoc);
+  
+  InitializationSequence InitSeq(*this, MemberEntity, Kind, Args, NumArgs);
+  
+  OwningExprResult MemberInit =
+    InitSeq.Perform(*this, MemberEntity, Kind, 
+                    MultiExprArg(*this, (void**)Args, NumArgs), 0);
+  if (MemberInit.isInvalid())
+    return true;
+  
+  // C++0x [class.base.init]p7:
+  //   The initialization of each base and member constitutes a 
+  //   full-expression.
+  MemberInit = MaybeCreateCXXExprWithTemporaries(move(MemberInit));
+  if (MemberInit.isInvalid())
+    return true;
+  
+  // If we are in a dependent context, template instantiation will
+  // perform this type-checking again. Just save the arguments that we
+  // received in a ParenListExpr.
+  // FIXME: This isn't quite ideal, since our ASTs don't capture all
+  // of the information that we have about the member
+  // initializer. However, deconstructing the ASTs is a dicey process,
+  // and this approach is far more likely to get the corner cases right.
+  if (CurContext->isDependentContext()) {
+    // Bump the reference count of all of the arguments.
+    for (unsigned I = 0; I != NumArgs; ++I)
+      Args[I]->Retain();
+
+    OwningExprResult Init
+      = Owned(new (Context) ParenListExpr(Context, LParenLoc, Args, NumArgs,
+                                          RParenLoc));
+    return new (Context) CXXBaseOrMemberInitializer(Context, Member, IdLoc,
+                                                    LParenLoc, 
+                                                    Init.takeAs<Expr>(),
+                                                    RParenLoc);
+  }
+
+  return new (Context) CXXBaseOrMemberInitializer(Context, Member, IdLoc,
+                                                  LParenLoc, 
+                                                  MemberInit.takeAs<Expr>(),
+                                                  RParenLoc);
+}
+
+Sema::MemInitResult
+Sema::BuildBaseInitializer(QualType BaseType, TypeSourceInfo *BaseTInfo,
+                           Expr **Args, unsigned NumArgs, 
+                           SourceLocation LParenLoc, SourceLocation RParenLoc, 
+                           CXXRecordDecl *ClassDecl) {
+  bool HasDependentArg = false;
+  for (unsigned i = 0; i < NumArgs; i++)
+    HasDependentArg |= Args[i]->isTypeDependent();
+
+  SourceLocation BaseLoc = BaseTInfo->getTypeLoc().getSourceRange().getBegin();
+  if (BaseType->isDependentType() || HasDependentArg) {
+    // Can't check initialization for a base of dependent type or when
+    // any of the arguments are type-dependent expressions.
+    OwningExprResult BaseInit
+      = Owned(new (Context) ParenListExpr(Context, LParenLoc, Args, NumArgs,
+                                          RParenLoc));
+
+    // Erase any temporaries within this evaluation context; we're not
+    // going to track them in the AST, since we'll be rebuilding the
+    // ASTs during template instantiation.
+    ExprTemporaries.erase(
+              ExprTemporaries.begin() + ExprEvalContexts.back().NumTemporaries,
+                          ExprTemporaries.end());
+
+    return new (Context) CXXBaseOrMemberInitializer(Context, BaseTInfo, 
+                                                    /*IsVirtual=*/false,
+                                                    LParenLoc, 
+                                                    BaseInit.takeAs<Expr>(),
+                                                    RParenLoc);
+  }
+  
+  if (!BaseType->isRecordType())
+    return Diag(BaseLoc, diag::err_base_init_does_not_name_class)
+             << BaseType << BaseTInfo->getTypeLoc().getSourceRange();
+
+  // C++ [class.base.init]p2:
+  //   [...] Unless the mem-initializer-id names a nonstatic data
+  //   member of the constructor’s class or a direct or virtual base
+  //   of that class, the mem-initializer is ill-formed. A
+  //   mem-initializer-list can initialize a base class using any
+  //   name that denotes that base class type.
+
+  // Check for direct and virtual base classes.
+  const CXXBaseSpecifier *DirectBaseSpec = 0;
+  const CXXBaseSpecifier *VirtualBaseSpec = 0;
+  FindBaseInitializer(*this, ClassDecl, BaseType, DirectBaseSpec, 
+                      VirtualBaseSpec);
+
+  // C++ [base.class.init]p2:
+  //   If a mem-initializer-id is ambiguous because it designates both
+  //   a direct non-virtual base class and an inherited virtual base
+  //   class, the mem-initializer is ill-formed.
+  if (DirectBaseSpec && VirtualBaseSpec)
+    return Diag(BaseLoc, diag::err_base_init_direct_and_virtual)
+      << BaseType << BaseTInfo->getTypeLoc().getSourceRange();
+  // C++ [base.class.init]p2:
+  // Unless the mem-initializer-id names a nonstatic data membeer of the
+  // constructor's class ot a direst or virtual base of that class, the
+  // mem-initializer is ill-formed.
+  if (!DirectBaseSpec && !VirtualBaseSpec)
+    return Diag(BaseLoc, diag::err_not_direct_base_or_virtual)
+      << BaseType << Context.getTypeDeclType(ClassDecl)
+      << BaseTInfo->getTypeLoc().getSourceRange();
+
+  CXXBaseSpecifier *BaseSpec
+    = const_cast<CXXBaseSpecifier *>(DirectBaseSpec);
+  if (!BaseSpec)
+    BaseSpec = const_cast<CXXBaseSpecifier *>(VirtualBaseSpec);
+
+  // Initialize the base.
+  InitializedEntity BaseEntity =
+    InitializedEntity::InitializeBase(Context, BaseSpec, VirtualBaseSpec);
+  InitializationKind Kind = 
+    InitializationKind::CreateDirect(BaseLoc, LParenLoc, RParenLoc);
+  
+  InitializationSequence InitSeq(*this, BaseEntity, Kind, Args, NumArgs);
+  
+  OwningExprResult BaseInit =
+    InitSeq.Perform(*this, BaseEntity, Kind, 
+                    MultiExprArg(*this, (void**)Args, NumArgs), 0);
+  if (BaseInit.isInvalid())
+    return true;
+  
+  // C++0x [class.base.init]p7:
+  //   The initialization of each base and member constitutes a 
+  //   full-expression.
+  BaseInit = MaybeCreateCXXExprWithTemporaries(move(BaseInit));
+  if (BaseInit.isInvalid())
+    return true;
+
+  // If we are in a dependent context, template instantiation will
+  // perform this type-checking again. Just save the arguments that we
+  // received in a ParenListExpr.
+  // FIXME: This isn't quite ideal, since our ASTs don't capture all
+  // of the information that we have about the base
+  // initializer. However, deconstructing the ASTs is a dicey process,
+  // and this approach is far more likely to get the corner cases right.
+  if (CurContext->isDependentContext()) {
+    // Bump the reference count of all of the arguments.
+    for (unsigned I = 0; I != NumArgs; ++I)
+      Args[I]->Retain();
+
+    OwningExprResult Init
+      = Owned(new (Context) ParenListExpr(Context, LParenLoc, Args, NumArgs,
+                                          RParenLoc));
+    return new (Context) CXXBaseOrMemberInitializer(Context, BaseTInfo,
+                                                    BaseSpec->isVirtual(),
+                                                    LParenLoc, 
+                                                    Init.takeAs<Expr>(),
+                                                    RParenLoc);
+  }
+
+  return new (Context) CXXBaseOrMemberInitializer(Context, BaseTInfo,
+                                                  BaseSpec->isVirtual(),
+                                                  LParenLoc, 
+                                                  BaseInit.takeAs<Expr>(),
+                                                  RParenLoc);
+}
+
+/// ImplicitInitializerKind - How an implicit base or member initializer should
+/// initialize its base or member.
+enum ImplicitInitializerKind {
+  IIK_Default,
+  IIK_Copy,
+  IIK_Move
+};
+
+static bool
+BuildImplicitBaseInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor,
+                             ImplicitInitializerKind ImplicitInitKind,
+                             CXXBaseSpecifier *BaseSpec,
+                             bool IsInheritedVirtualBase,
+                             CXXBaseOrMemberInitializer *&CXXBaseInit) {
+  InitializedEntity InitEntity
+    = InitializedEntity::InitializeBase(SemaRef.Context, BaseSpec,
+                                        IsInheritedVirtualBase);
+
+  Sema::OwningExprResult BaseInit(SemaRef);
+  
+  switch (ImplicitInitKind) {
+  case IIK_Default: {
+    InitializationKind InitKind
+      = InitializationKind::CreateDefault(Constructor->getLocation());
+    InitializationSequence InitSeq(SemaRef, InitEntity, InitKind, 0, 0);
+    BaseInit = InitSeq.Perform(SemaRef, InitEntity, InitKind,
+                               Sema::MultiExprArg(SemaRef, 0, 0));
+    break;
+  }
+
+  case IIK_Copy: {
+    ParmVarDecl *Param = Constructor->getParamDecl(0);
+    QualType ParamType = Param->getType().getNonReferenceType();
+    
+    Expr *CopyCtorArg = 
+      DeclRefExpr::Create(SemaRef.Context, 0, SourceRange(), Param, 
+                          SourceLocation(), ParamType, 0);
+    
+    // Cast to the base class to avoid ambiguities.
+    SemaRef.ImpCastExprToType(CopyCtorArg, BaseSpec->getType(), 
+                              CastExpr::CK_UncheckedDerivedToBase,
+                              /*isLvalue=*/true, 
+                              CXXBaseSpecifierArray(BaseSpec));
+
+    InitializationKind InitKind
+      = InitializationKind::CreateDirect(Constructor->getLocation(),
+                                         SourceLocation(), SourceLocation());
+    InitializationSequence InitSeq(SemaRef, InitEntity, InitKind, 
+                                   &CopyCtorArg, 1);
+    BaseInit = InitSeq.Perform(SemaRef, InitEntity, InitKind,
+                               Sema::MultiExprArg(SemaRef, 
+                                                  (void**)&CopyCtorArg, 1));
+    break;
+  }
+
+  case IIK_Move:
+    assert(false && "Unhandled initializer kind!");
+  }
+      
+  BaseInit = SemaRef.MaybeCreateCXXExprWithTemporaries(move(BaseInit));
+  if (BaseInit.isInvalid())
+    return true;
+        
+  CXXBaseInit =
+    new (SemaRef.Context) CXXBaseOrMemberInitializer(SemaRef.Context,
+               SemaRef.Context.getTrivialTypeSourceInfo(BaseSpec->getType(), 
+                                                        SourceLocation()),
+                                             BaseSpec->isVirtual(),
+                                             SourceLocation(),
+                                             BaseInit.takeAs<Expr>(),
+                                             SourceLocation());
+
+  return false;
+}
+
+static bool
+BuildImplicitMemberInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor,
+                               ImplicitInitializerKind ImplicitInitKind,
+                               FieldDecl *Field,
+                               CXXBaseOrMemberInitializer *&CXXMemberInit) {
+  if (ImplicitInitKind == IIK_Copy) {
+    ParmVarDecl *Param = Constructor->getParamDecl(0);
+    QualType ParamType = Param->getType().getNonReferenceType();
+    
+    Expr *MemberExprBase = 
+      DeclRefExpr::Create(SemaRef.Context, 0, SourceRange(), Param, 
+                          SourceLocation(), ParamType, 0);
+    
+    
+    Expr *CopyCtorArg = 
+      MemberExpr::Create(SemaRef.Context, MemberExprBase, /*IsArrow=*/false, 
+                         0, SourceRange(), Field, 
+                         DeclAccessPair::make(Field, Field->getAccess()),
+                         SourceLocation(), 0, 
+                         Field->getType().getNonReferenceType());
+    
+    InitializedEntity InitEntity = InitializedEntity::InitializeMember(Field);
+    InitializationKind InitKind =
+      InitializationKind::CreateDirect(Constructor->getLocation(), 
+                                       SourceLocation(), SourceLocation());
+    
+    InitializationSequence InitSeq(SemaRef, InitEntity, InitKind,
+                                   &CopyCtorArg, 1);
+    
+    Sema::OwningExprResult MemberInit =
+      InitSeq.Perform(SemaRef, InitEntity, InitKind, 
+                      Sema::MultiExprArg(SemaRef, (void**)&CopyCtorArg, 1), 0);
+    if (MemberInit.isInvalid())
+      return true;
+    
+    CXXMemberInit = 0;
+    return false;
+  }
+
+  assert(ImplicitInitKind == IIK_Default && "Unhandled implicit init kind!");
+
+  QualType FieldBaseElementType = 
+    SemaRef.Context.getBaseElementType(Field->getType());
+  
+  if (FieldBaseElementType->isRecordType()) {
+    InitializedEntity InitEntity = InitializedEntity::InitializeMember(Field);
+    InitializationKind InitKind = 
+      InitializationKind::CreateDefault(Constructor->getLocation());
+    
+    InitializationSequence InitSeq(SemaRef, InitEntity, InitKind, 0, 0);
+    Sema::OwningExprResult MemberInit = 
+      InitSeq.Perform(SemaRef, InitEntity, InitKind, 
+                      Sema::MultiExprArg(SemaRef, 0, 0));
+    MemberInit = SemaRef.MaybeCreateCXXExprWithTemporaries(move(MemberInit));
+    if (MemberInit.isInvalid())
+      return true;
+    
+    CXXMemberInit =
+      new (SemaRef.Context) CXXBaseOrMemberInitializer(SemaRef.Context,
+                                                       Field, SourceLocation(),
+                                                       SourceLocation(),
+                                                      MemberInit.takeAs<Expr>(),
+                                                       SourceLocation());
+    return false;
+  }
+
+  if (FieldBaseElementType->isReferenceType()) {
+    SemaRef.Diag(Constructor->getLocation(), 
+                 diag::err_uninitialized_member_in_ctor)
+    << (int)Constructor->isImplicit() 
+    << SemaRef.Context.getTagDeclType(Constructor->getParent())
+    << 0 << Field->getDeclName();
+    SemaRef.Diag(Field->getLocation(), diag::note_declared_at);
+    return true;
+  }
+
+  if (FieldBaseElementType.isConstQualified()) {
+    SemaRef.Diag(Constructor->getLocation(), 
+                 diag::err_uninitialized_member_in_ctor)
+    << (int)Constructor->isImplicit() 
+    << SemaRef.Context.getTagDeclType(Constructor->getParent())
+    << 1 << Field->getDeclName();
+    SemaRef.Diag(Field->getLocation(), diag::note_declared_at);
+    return true;
+  }
+  
+  // Nothing to initialize.
+  CXXMemberInit = 0;
+  return false;
+}
+                               
+bool
+Sema::SetBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
+                                  CXXBaseOrMemberInitializer **Initializers,
+                                  unsigned NumInitializers,
+                                  bool AnyErrors) {
+  if (Constructor->getDeclContext()->isDependentContext()) {
+    // Just store the initializers as written, they will be checked during
+    // instantiation.
+    if (NumInitializers > 0) {
+      Constructor->setNumBaseOrMemberInitializers(NumInitializers);
+      CXXBaseOrMemberInitializer **baseOrMemberInitializers =
+        new (Context) CXXBaseOrMemberInitializer*[NumInitializers];
+      memcpy(baseOrMemberInitializers, Initializers,
+             NumInitializers * sizeof(CXXBaseOrMemberInitializer*));
+      Constructor->setBaseOrMemberInitializers(baseOrMemberInitializers);
+    }
+    
+    return false;
+  }
+
+  ImplicitInitializerKind ImplicitInitKind = IIK_Default;
+  
+  // FIXME: Handle implicit move constructors.
+  if (Constructor->isImplicit() && Constructor->isCopyConstructor())
+    ImplicitInitKind = IIK_Copy;
+
+  // We need to build the initializer AST according to order of construction
+  // and not what user specified in the Initializers list.
+  CXXRecordDecl *ClassDecl = Constructor->getParent()->getDefinition();
+  if (!ClassDecl)
+    return true;
+  
+  llvm::SmallVector<CXXBaseOrMemberInitializer*, 32> AllToInit;
+  llvm::DenseMap<const void *, CXXBaseOrMemberInitializer*> AllBaseFields;
+  bool HadError = false;
+
+  for (unsigned i = 0; i < NumInitializers; i++) {
+    CXXBaseOrMemberInitializer *Member = Initializers[i];
+    
+    if (Member->isBaseInitializer())
+      AllBaseFields[Member->getBaseClass()->getAs<RecordType>()] = Member;
+    else
+      AllBaseFields[Member->getMember()] = Member;
+  }
+
+  // Keep track of the direct virtual bases.
+  llvm::SmallPtrSet<CXXBaseSpecifier *, 16> DirectVBases;
+  for (CXXRecordDecl::base_class_iterator I = ClassDecl->bases_begin(),
+       E = ClassDecl->bases_end(); I != E; ++I) {
+    if (I->isVirtual())
+      DirectVBases.insert(I);
+  }
+
+  // Push virtual bases before others.
+  for (CXXRecordDecl::base_class_iterator VBase = ClassDecl->vbases_begin(),
+       E = ClassDecl->vbases_end(); VBase != E; ++VBase) {
+
+    if (CXXBaseOrMemberInitializer *Value
+        = AllBaseFields.lookup(VBase->getType()->getAs<RecordType>())) {
+      AllToInit.push_back(Value);
+    } else if (!AnyErrors) {
+      bool IsInheritedVirtualBase = !DirectVBases.count(VBase);
+      CXXBaseOrMemberInitializer *CXXBaseInit;
+      if (BuildImplicitBaseInitializer(*this, Constructor, ImplicitInitKind,
+                                       VBase, IsInheritedVirtualBase, 
+                                       CXXBaseInit)) {
+        HadError = true;
+        continue;
+      }
+
+      AllToInit.push_back(CXXBaseInit);
+    }
+  }
+
+  for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(),
+       E = ClassDecl->bases_end(); Base != E; ++Base) {
+    // Virtuals are in the virtual base list and already constructed.
+    if (Base->isVirtual())
+      continue;
+
+    if (CXXBaseOrMemberInitializer *Value
+          = AllBaseFields.lookup(Base->getType()->getAs<RecordType>())) {
+      AllToInit.push_back(Value);
+    } else if (!AnyErrors) {
+      CXXBaseOrMemberInitializer *CXXBaseInit;
+      if (BuildImplicitBaseInitializer(*this, Constructor, ImplicitInitKind,
+                                       Base, /*IsInheritedVirtualBase=*/false,
+                                       CXXBaseInit)) {
+        HadError = true;
+        continue;
+      }
+
+      AllToInit.push_back(CXXBaseInit);
+    }
+  }
+
+  // non-static data members.
+  for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
+       E = ClassDecl->field_end(); Field != E; ++Field) {
+    if ((*Field)->isAnonymousStructOrUnion()) {
+      if (const RecordType *FieldClassType =
+          Field->getType()->getAs<RecordType>()) {
+        CXXRecordDecl *FieldClassDecl
+          = cast<CXXRecordDecl>(FieldClassType->getDecl());
+        for (RecordDecl::field_iterator FA = FieldClassDecl->field_begin(),
+            EA = FieldClassDecl->field_end(); FA != EA; FA++) {
+          if (CXXBaseOrMemberInitializer *Value = AllBaseFields.lookup(*FA)) {
+            // 'Member' is the anonymous union field and 'AnonUnionMember' is
+            // set to the anonymous union data member used in the initializer
+            // list.
+            Value->setMember(*Field);
+            Value->setAnonUnionMember(*FA);
+            AllToInit.push_back(Value);
+            break;
+          }
+        }
+      }
+      continue;
+    }
+    if (CXXBaseOrMemberInitializer *Value = AllBaseFields.lookup(*Field)) {
+      AllToInit.push_back(Value);
+      continue;
+    }
+
+    if (AnyErrors)
+      continue;
+    
+    CXXBaseOrMemberInitializer *Member;
+    if (BuildImplicitMemberInitializer(*this, Constructor, ImplicitInitKind,
+                                       *Field, Member)) {
+      HadError = true;
+      continue;
+    }
+    
+    // If the member doesn't need to be initialized, it will be null.
+    if (Member)
+      AllToInit.push_back(Member);
+  }
+
+  NumInitializers = AllToInit.size();
+  if (NumInitializers > 0) {
+    Constructor->setNumBaseOrMemberInitializers(NumInitializers);
+    CXXBaseOrMemberInitializer **baseOrMemberInitializers =
+      new (Context) CXXBaseOrMemberInitializer*[NumInitializers];
+    memcpy(baseOrMemberInitializers, AllToInit.data(),
+           NumInitializers * sizeof(CXXBaseOrMemberInitializer*));
+    Constructor->setBaseOrMemberInitializers(baseOrMemberInitializers);
+
+    // Constructors implicitly reference the base and member
+    // destructors.
+    MarkBaseAndMemberDestructorsReferenced(Constructor->getLocation(),
+                                           Constructor->getParent());
+  }
+
+  return HadError;
+}
+
+static void *GetKeyForTopLevelField(FieldDecl *Field) {
+  // For anonymous unions, use the class declaration as the key.
+  if (const RecordType *RT = Field->getType()->getAs<RecordType>()) {
+    if (RT->getDecl()->isAnonymousStructOrUnion())
+      return static_cast<void *>(RT->getDecl());
+  }
+  return static_cast<void *>(Field);
+}
+
+static void *GetKeyForBase(ASTContext &Context, QualType BaseType) {
+  return Context.getCanonicalType(BaseType).getTypePtr();
+}
+
+static void *GetKeyForMember(ASTContext &Context,
+                             CXXBaseOrMemberInitializer *Member,
+                             bool MemberMaybeAnon = false) {
+  if (!Member->isMemberInitializer())
+    return GetKeyForBase(Context, QualType(Member->getBaseClass(), 0));
+    
+  // For fields injected into the class via declaration of an anonymous union,
+  // use its anonymous union class declaration as the unique key.
+  FieldDecl *Field = Member->getMember();
+
+  // After SetBaseOrMemberInitializers call, Field is the anonymous union
+  // data member of the class. Data member used in the initializer list is
+  // in AnonUnionMember field.
+  if (MemberMaybeAnon && Field->isAnonymousStructOrUnion())
+    Field = Member->getAnonUnionMember();
+  
+  // If the field is a member of an anonymous struct or union, our key
+  // is the anonymous record decl that's a direct child of the class.
+  RecordDecl *RD = Field->getParent();
+  if (RD->isAnonymousStructOrUnion()) {
+    while (true) {
+      RecordDecl *Parent = cast<RecordDecl>(RD->getDeclContext());
+      if (Parent->isAnonymousStructOrUnion())
+        RD = Parent;
+      else
+        break;
+    }
+      
+    return static_cast<void *>(RD);
+  }
+
+  return static_cast<void *>(Field);
+}
+
+static void
+DiagnoseBaseOrMemInitializerOrder(Sema &SemaRef,
+                                  const CXXConstructorDecl *Constructor,
+                                  CXXBaseOrMemberInitializer **Inits,
+                                  unsigned NumInits) {
+  if (Constructor->getDeclContext()->isDependentContext())
+    return;
+
+  if (SemaRef.Diags.getDiagnosticLevel(diag::warn_initializer_out_of_order)
+        == Diagnostic::Ignored)
+    return;
+  
+  // Build the list of bases and members in the order that they'll
+  // actually be initialized.  The explicit initializers should be in
+  // this same order but may be missing things.
+  llvm::SmallVector<const void*, 32> IdealInitKeys;
+
+  const CXXRecordDecl *ClassDecl = Constructor->getParent();
+
+  // 1. Virtual bases.
+  for (CXXRecordDecl::base_class_const_iterator VBase =
+       ClassDecl->vbases_begin(),
+       E = ClassDecl->vbases_end(); VBase != E; ++VBase)
+    IdealInitKeys.push_back(GetKeyForBase(SemaRef.Context, VBase->getType()));
+
+  // 2. Non-virtual bases.
+  for (CXXRecordDecl::base_class_const_iterator Base = ClassDecl->bases_begin(),
+       E = ClassDecl->bases_end(); Base != E; ++Base) {
+    if (Base->isVirtual())
+      continue;
+    IdealInitKeys.push_back(GetKeyForBase(SemaRef.Context, Base->getType()));
+  }
+
+  // 3. Direct fields.
+  for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
+       E = ClassDecl->field_end(); Field != E; ++Field)
+    IdealInitKeys.push_back(GetKeyForTopLevelField(*Field));
+
+  unsigned NumIdealInits = IdealInitKeys.size();
+  unsigned IdealIndex = 0;
+
+  CXXBaseOrMemberInitializer *PrevInit = 0;
+  for (unsigned InitIndex = 0; InitIndex != NumInits; ++InitIndex) {
+    CXXBaseOrMemberInitializer *Init = Inits[InitIndex];
+    void *InitKey = GetKeyForMember(SemaRef.Context, Init, true);
+
+    // Scan forward to try to find this initializer in the idealized
+    // initializers list.
+    for (; IdealIndex != NumIdealInits; ++IdealIndex)
+      if (InitKey == IdealInitKeys[IdealIndex])
+        break;
+
+    // If we didn't find this initializer, it must be because we
+    // scanned past it on a previous iteration.  That can only
+    // happen if we're out of order;  emit a warning.
+    if (IdealIndex == NumIdealInits) {
+      assert(PrevInit && "initializer not found in initializer list");
+
+      Sema::SemaDiagnosticBuilder D =
+        SemaRef.Diag(PrevInit->getSourceLocation(),
+                     diag::warn_initializer_out_of_order);
+
+      if (PrevInit->isMemberInitializer())
+        D << 0 << PrevInit->getMember()->getDeclName();
+      else
+        D << 1 << PrevInit->getBaseClassInfo()->getType();
+      
+      if (Init->isMemberInitializer())
+        D << 0 << Init->getMember()->getDeclName();
+      else
+        D << 1 << Init->getBaseClassInfo()->getType();
+
+      // Move back to the initializer's location in the ideal list.
+      for (IdealIndex = 0; IdealIndex != NumIdealInits; ++IdealIndex)
+        if (InitKey == IdealInitKeys[IdealIndex])
+          break;
+
+      assert(IdealIndex != NumIdealInits &&
+             "initializer not found in initializer list");
+    }
+
+    PrevInit = Init;
+  }
+}
+
+namespace {
+bool CheckRedundantInit(Sema &S,
+                        CXXBaseOrMemberInitializer *Init,
+                        CXXBaseOrMemberInitializer *&PrevInit) {
+  if (!PrevInit) {
+    PrevInit = Init;
+    return false;
+  }
+
+  if (FieldDecl *Field = Init->getMember())
+    S.Diag(Init->getSourceLocation(),
+           diag::err_multiple_mem_initialization)
+      << Field->getDeclName()
+      << Init->getSourceRange();
+  else {
+    Type *BaseClass = Init->getBaseClass();
+    assert(BaseClass && "neither field nor base");
+    S.Diag(Init->getSourceLocation(),
+           diag::err_multiple_base_initialization)
+      << QualType(BaseClass, 0)
+      << Init->getSourceRange();
+  }
+  S.Diag(PrevInit->getSourceLocation(), diag::note_previous_initializer)
+    << 0 << PrevInit->getSourceRange();
+
+  return true;
+}
+
+typedef std::pair<NamedDecl *, CXXBaseOrMemberInitializer *> UnionEntry;
+typedef llvm::DenseMap<RecordDecl*, UnionEntry> RedundantUnionMap;
+
+bool CheckRedundantUnionInit(Sema &S,
+                             CXXBaseOrMemberInitializer *Init,
+                             RedundantUnionMap &Unions) {
+  FieldDecl *Field = Init->getMember();
+  RecordDecl *Parent = Field->getParent();
+  if (!Parent->isAnonymousStructOrUnion())
+    return false;
+
+  NamedDecl *Child = Field;
+  do {
+    if (Parent->isUnion()) {
+      UnionEntry &En = Unions[Parent];
+      if (En.first && En.first != Child) {
+        S.Diag(Init->getSourceLocation(),
+               diag::err_multiple_mem_union_initialization)
+          << Field->getDeclName()
+          << Init->getSourceRange();
+        S.Diag(En.second->getSourceLocation(), diag::note_previous_initializer)
+          << 0 << En.second->getSourceRange();
+        return true;
+      } else if (!En.first) {
+        En.first = Child;
+        En.second = Init;
+      }
+    }
+
+    Child = Parent;
+    Parent = cast<RecordDecl>(Parent->getDeclContext());
+  } while (Parent->isAnonymousStructOrUnion());
+
+  return false;
+}
+}
+
+/// ActOnMemInitializers - Handle the member initializers for a constructor.
+void Sema::ActOnMemInitializers(DeclPtrTy ConstructorDecl,
+                                SourceLocation ColonLoc,
+                                MemInitTy **meminits, unsigned NumMemInits,
+                                bool AnyErrors) {
+  if (!ConstructorDecl)
+    return;
+
+  AdjustDeclIfTemplate(ConstructorDecl);
+
+  CXXConstructorDecl *Constructor
+    = dyn_cast<CXXConstructorDecl>(ConstructorDecl.getAs<Decl>());
+
+  if (!Constructor) {
+    Diag(ColonLoc, diag::err_only_constructors_take_base_inits);
+    return;
+  }
+  
+  CXXBaseOrMemberInitializer **MemInits =
+    reinterpret_cast<CXXBaseOrMemberInitializer **>(meminits);
+
+  // Mapping for the duplicate initializers check.
+  // For member initializers, this is keyed with a FieldDecl*.
+  // For base initializers, this is keyed with a Type*.
+  llvm::DenseMap<void*, CXXBaseOrMemberInitializer *> Members;
+
+  // Mapping for the inconsistent anonymous-union initializers check.
+  RedundantUnionMap MemberUnions;
+
+  bool HadError = false;
+  for (unsigned i = 0; i < NumMemInits; i++) {
+    CXXBaseOrMemberInitializer *Init = MemInits[i];
+
+    if (Init->isMemberInitializer()) {
+      FieldDecl *Field = Init->getMember();
+      if (CheckRedundantInit(*this, Init, Members[Field]) ||
+          CheckRedundantUnionInit(*this, Init, MemberUnions))
+        HadError = true;
+    } else {
+      void *Key = GetKeyForBase(Context, QualType(Init->getBaseClass(), 0));
+      if (CheckRedundantInit(*this, Init, Members[Key]))
+        HadError = true;
+    }
+  }
+
+  if (HadError)
+    return;
+
+  DiagnoseBaseOrMemInitializerOrder(*this, Constructor, MemInits, NumMemInits);
+
+  SetBaseOrMemberInitializers(Constructor, MemInits, NumMemInits, AnyErrors);
+}
+
+void
+Sema::MarkBaseAndMemberDestructorsReferenced(SourceLocation Location,
+                                             CXXRecordDecl *ClassDecl) {
+  // Ignore dependent contexts.
+  if (ClassDecl->isDependentContext())
+    return;
+
+  // FIXME: all the access-control diagnostics are positioned on the
+  // field/base declaration.  That's probably good; that said, the
+  // user might reasonably want to know why the destructor is being
+  // emitted, and we currently don't say.
+  
+  // Non-static data members.
+  for (CXXRecordDecl::field_iterator I = ClassDecl->field_begin(),
+       E = ClassDecl->field_end(); I != E; ++I) {
+    FieldDecl *Field = *I;
+    
+    QualType FieldType = Context.getBaseElementType(Field->getType());
+    
+    const RecordType* RT = FieldType->getAs<RecordType>();
+    if (!RT)
+      continue;
+    
+    CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl());
+    if (FieldClassDecl->hasTrivialDestructor())
+      continue;
+
+    CXXDestructorDecl *Dtor = FieldClassDecl->getDestructor(Context);
+    CheckDestructorAccess(Field->getLocation(), Dtor,
+                          PDiag(diag::err_access_dtor_field)
+                            << Field->getDeclName()
+                            << FieldType);
+
+    MarkDeclarationReferenced(Location, const_cast<CXXDestructorDecl*>(Dtor));
+  }
+
+  llvm::SmallPtrSet<const RecordType *, 8> DirectVirtualBases;
+
+  // Bases.
+  for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(),
+       E = ClassDecl->bases_end(); Base != E; ++Base) {
+    // Bases are always records in a well-formed non-dependent class.
+    const RecordType *RT = Base->getType()->getAs<RecordType>();
+
+    // Remember direct virtual bases.
+    if (Base->isVirtual())
+      DirectVirtualBases.insert(RT);
+
+    // Ignore trivial destructors.
+    CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(RT->getDecl());
+    if (BaseClassDecl->hasTrivialDestructor())
+      continue;
+
+    CXXDestructorDecl *Dtor = BaseClassDecl->getDestructor(Context);
+
+    // FIXME: caret should be on the start of the class name
+    CheckDestructorAccess(Base->getSourceRange().getBegin(), Dtor,
+                          PDiag(diag::err_access_dtor_base)
+                            << Base->getType()
+                            << Base->getSourceRange());
+    
+    MarkDeclarationReferenced(Location, const_cast<CXXDestructorDecl*>(Dtor));
+  }
+  
+  // Virtual bases.
+  for (CXXRecordDecl::base_class_iterator VBase = ClassDecl->vbases_begin(),
+       E = ClassDecl->vbases_end(); VBase != E; ++VBase) {
+
+    // Bases are always records in a well-formed non-dependent class.
+    const RecordType *RT = VBase->getType()->getAs<RecordType>();
+
+    // Ignore direct virtual bases.
+    if (DirectVirtualBases.count(RT))
+      continue;
+
+    // Ignore trivial destructors.
+    CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(RT->getDecl());
+    if (BaseClassDecl->hasTrivialDestructor())
+      continue;
+
+    CXXDestructorDecl *Dtor = BaseClassDecl->getDestructor(Context);
+    CheckDestructorAccess(ClassDecl->getLocation(), Dtor,
+                          PDiag(diag::err_access_dtor_vbase)
+                            << VBase->getType());
+
+    MarkDeclarationReferenced(Location, const_cast<CXXDestructorDecl*>(Dtor));
+  }
+}
+
+void Sema::ActOnDefaultCtorInitializers(DeclPtrTy CDtorDecl) {
+  if (!CDtorDecl)
+    return;
+
+  if (CXXConstructorDecl *Constructor
+      = dyn_cast<CXXConstructorDecl>(CDtorDecl.getAs<Decl>()))
+    SetBaseOrMemberInitializers(Constructor, 0, 0, /*AnyErrors=*/false);
+}
+
+bool Sema::RequireNonAbstractType(SourceLocation Loc, QualType T,
+                                  unsigned DiagID, AbstractDiagSelID SelID,
+                                  const CXXRecordDecl *CurrentRD) {
+  if (SelID == -1)
+    return RequireNonAbstractType(Loc, T,
+                                  PDiag(DiagID), CurrentRD);
+  else
+    return RequireNonAbstractType(Loc, T,
+                                  PDiag(DiagID) << SelID, CurrentRD);
+}
+
+bool Sema::RequireNonAbstractType(SourceLocation Loc, QualType T,
+                                  const PartialDiagnostic &PD,
+                                  const CXXRecordDecl *CurrentRD) {
+  if (!getLangOptions().CPlusPlus)
+    return false;
+
+  if (const ArrayType *AT = Context.getAsArrayType(T))
+    return RequireNonAbstractType(Loc, AT->getElementType(), PD,
+                                  CurrentRD);
+
+  if (const PointerType *PT = T->getAs<PointerType>()) {
+    // Find the innermost pointer type.
+    while (const PointerType *T = PT->getPointeeType()->getAs<PointerType>())
+      PT = T;
+
+    if (const ArrayType *AT = Context.getAsArrayType(PT->getPointeeType()))
+      return RequireNonAbstractType(Loc, AT->getElementType(), PD, CurrentRD);
+  }
+
+  const RecordType *RT = T->getAs<RecordType>();
+  if (!RT)
+    return false;
+
+  const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
+
+  if (CurrentRD && CurrentRD != RD)
+    return false;
+
+  // FIXME: is this reasonable?  It matches current behavior, but....
+  if (!RD->getDefinition())
+    return false;
+
+  if (!RD->isAbstract())
+    return false;
+
+  Diag(Loc, PD) << RD->getDeclName();
+
+  // Check if we've already emitted the list of pure virtual functions for this
+  // class.
+  if (PureVirtualClassDiagSet && PureVirtualClassDiagSet->count(RD))
+    return true;
+
+  CXXFinalOverriderMap FinalOverriders;
+  RD->getFinalOverriders(FinalOverriders);
+
+  for (CXXFinalOverriderMap::iterator M = FinalOverriders.begin(), 
+                                   MEnd = FinalOverriders.end();
+       M != MEnd; 
+       ++M) {
+    for (OverridingMethods::iterator SO = M->second.begin(), 
+                                  SOEnd = M->second.end();
+         SO != SOEnd; ++SO) {
+      // C++ [class.abstract]p4:
+      //   A class is abstract if it contains or inherits at least one
+      //   pure virtual function for which the final overrider is pure
+      //   virtual.
+
+      // 
+      if (SO->second.size() != 1)
+        continue;
+
+      if (!SO->second.front().Method->isPure())
+        continue;
+
+      Diag(SO->second.front().Method->getLocation(), 
+           diag::note_pure_virtual_function) 
+        << SO->second.front().Method->getDeclName();
+    }
+  }
+
+  if (!PureVirtualClassDiagSet)
+    PureVirtualClassDiagSet.reset(new RecordDeclSetTy);
+  PureVirtualClassDiagSet->insert(RD);
+
+  return true;
+}
+
+namespace {
+  class AbstractClassUsageDiagnoser
+    : public DeclVisitor<AbstractClassUsageDiagnoser, bool> {
+    Sema &SemaRef;
+    CXXRecordDecl *AbstractClass;
+
+    bool VisitDeclContext(const DeclContext *DC) {
+      bool Invalid = false;
+
+      for (CXXRecordDecl::decl_iterator I = DC->decls_begin(),
+           E = DC->decls_end(); I != E; ++I)
+        Invalid |= Visit(*I);
+
+      return Invalid;
+    }
+
+  public:
+    AbstractClassUsageDiagnoser(Sema& SemaRef, CXXRecordDecl *ac)
+      : SemaRef(SemaRef), AbstractClass(ac) {
+        Visit(SemaRef.Context.getTranslationUnitDecl());
+    }
+
+    bool VisitFunctionDecl(const FunctionDecl *FD) {
+      if (FD->isThisDeclarationADefinition()) {
+        // No need to do the check if we're in a definition, because it requires
+        // that the return/param types are complete.
+        // because that requires
+        return VisitDeclContext(FD);
+      }
+
+      // Check the return type.
+      QualType RTy = FD->getType()->getAs<FunctionType>()->getResultType();
+      bool Invalid =
+        SemaRef.RequireNonAbstractType(FD->getLocation(), RTy,
+                                       diag::err_abstract_type_in_decl,
+                                       Sema::AbstractReturnType,
+                                       AbstractClass);
+
+      for (FunctionDecl::param_const_iterator I = FD->param_begin(),
+           E = FD->param_end(); I != E; ++I) {
+        const ParmVarDecl *VD = *I;
+        Invalid |=
+          SemaRef.RequireNonAbstractType(VD->getLocation(),
+                                         VD->getOriginalType(),
+                                         diag::err_abstract_type_in_decl,
+                                         Sema::AbstractParamType,
+                                         AbstractClass);
+      }
+
+      return Invalid;
+    }
+
+    bool VisitDecl(const Decl* D) {
+      if (const DeclContext *DC = dyn_cast<DeclContext>(D))
+        return VisitDeclContext(DC);
+
+      return false;
+    }
+  };
+}
+
+/// \brief Perform semantic checks on a class definition that has been
+/// completing, introducing implicitly-declared members, checking for
+/// abstract types, etc.
+void Sema::CheckCompletedCXXClass(Scope *S, CXXRecordDecl *Record) {
+  if (!Record || Record->isInvalidDecl())
+    return;
+
+  if (!Record->isDependentType())
+    AddImplicitlyDeclaredMembersToClass(S, Record);
+  
+  if (Record->isInvalidDecl())
+    return;
+
+  // Set access bits correctly on the directly-declared conversions.
+  UnresolvedSetImpl *Convs = Record->getConversionFunctions();
+  for (UnresolvedSetIterator I = Convs->begin(), E = Convs->end(); I != E; ++I)
+    Convs->setAccess(I, (*I)->getAccess());
+
+  // Determine whether we need to check for final overriders. We do
+  // this either when there are virtual base classes (in which case we
+  // may end up finding multiple final overriders for a given virtual
+  // function) or any of the base classes is abstract (in which case
+  // we might detect that this class is abstract).
+  bool CheckFinalOverriders = false;
+  if (Record->isPolymorphic() && !Record->isInvalidDecl() &&
+      !Record->isDependentType()) {
+    if (Record->getNumVBases())
+      CheckFinalOverriders = true;
+    else if (!Record->isAbstract()) {
+      for (CXXRecordDecl::base_class_const_iterator B = Record->bases_begin(),
+                                                 BEnd = Record->bases_end();
+           B != BEnd; ++B) {
+        CXXRecordDecl *BaseDecl 
+          = cast<CXXRecordDecl>(B->getType()->getAs<RecordType>()->getDecl());
+        if (BaseDecl->isAbstract()) {
+          CheckFinalOverriders = true; 
+          break;
+        }
+      }
+    }
+  }
+
+  if (CheckFinalOverriders) {
+    CXXFinalOverriderMap FinalOverriders;
+    Record->getFinalOverriders(FinalOverriders);
+
+    for (CXXFinalOverriderMap::iterator M = FinalOverriders.begin(), 
+                                     MEnd = FinalOverriders.end();
+         M != MEnd; ++M) {
+      for (OverridingMethods::iterator SO = M->second.begin(), 
+                                    SOEnd = M->second.end();
+           SO != SOEnd; ++SO) {
+        assert(SO->second.size() > 0 && 
+               "All virtual functions have overridding virtual functions");
+        if (SO->second.size() == 1) {
+          // C++ [class.abstract]p4:
+          //   A class is abstract if it contains or inherits at least one
+          //   pure virtual function for which the final overrider is pure
+          //   virtual.
+          if (SO->second.front().Method->isPure())
+            Record->setAbstract(true);
+          continue;
+        }
+
+        // C++ [class.virtual]p2:
+        //   In a derived class, if a virtual member function of a base
+        //   class subobject has more than one final overrider the
+        //   program is ill-formed.
+        Diag(Record->getLocation(), diag::err_multiple_final_overriders)
+          << (NamedDecl *)M->first << Record;
+        Diag(M->first->getLocation(), diag::note_overridden_virtual_function);
+        for (OverridingMethods::overriding_iterator OM = SO->second.begin(), 
+                                                 OMEnd = SO->second.end();
+             OM != OMEnd; ++OM)
+          Diag(OM->Method->getLocation(), diag::note_final_overrider)
+            << (NamedDecl *)M->first << OM->Method->getParent();
+        
+        Record->setInvalidDecl();
+      }
+    }
+  }
+
+  if (Record->isAbstract() && !Record->isInvalidDecl())
+    (void)AbstractClassUsageDiagnoser(*this, Record);
+  
+  // If this is not an aggregate type and has no user-declared constructor,
+  // complain about any non-static data members of reference or const scalar
+  // type, since they will never get initializers.
+  if (!Record->isInvalidDecl() && !Record->isDependentType() &&
+      !Record->isAggregate() && !Record->hasUserDeclaredConstructor()) {
+    bool Complained = false;
+    for (RecordDecl::field_iterator F = Record->field_begin(), 
+                                 FEnd = Record->field_end();
+         F != FEnd; ++F) {
+      if (F->getType()->isReferenceType() ||
+          (F->getType().isConstQualified() && F->getType()->isScalarType())) {
+        if (!Complained) {
+          Diag(Record->getLocation(), diag::warn_no_constructor_for_refconst)
+            << Record->getTagKind() << Record;
+          Complained = true;
+        }
+        
+        Diag(F->getLocation(), diag::note_refconst_member_not_initialized)
+          << F->getType()->isReferenceType()
+          << F->getDeclName();
+      }
+    }
+  }
+}
+
+void Sema::ActOnFinishCXXMemberSpecification(Scope* S, SourceLocation RLoc,
+                                             DeclPtrTy TagDecl,
+                                             SourceLocation LBrac,
+                                             SourceLocation RBrac,
+                                             AttributeList *AttrList) {
+  if (!TagDecl)
+    return;
+
+  AdjustDeclIfTemplate(TagDecl);
+
+  ActOnFields(S, RLoc, TagDecl,
+              (DeclPtrTy*)FieldCollector->getCurFields(),
+              FieldCollector->getCurNumFields(), LBrac, RBrac, AttrList);
+
+  CheckCompletedCXXClass(S, 
+                      dyn_cast_or_null<CXXRecordDecl>(TagDecl.getAs<Decl>()));
+}
+
+/// AddImplicitlyDeclaredMembersToClass - Adds any implicitly-declared
+/// special functions, such as the default constructor, copy
+/// constructor, or destructor, to the given C++ class (C++
+/// [special]p1).  This routine can only be executed just before the
+/// definition of the class is complete.
+///
+/// The scope, if provided, is the class scope.
+void Sema::AddImplicitlyDeclaredMembersToClass(Scope *S, 
+                                               CXXRecordDecl *ClassDecl) {
+  CanQualType ClassType
+    = Context.getCanonicalType(Context.getTypeDeclType(ClassDecl));
+
+  // FIXME: Implicit declarations have exception specifications, which are
+  // the union of the specifications of the implicitly called functions.
+
+  if (!ClassDecl->hasUserDeclaredConstructor()) {
+    // C++ [class.ctor]p5:
+    //   A default constructor for a class X is a constructor of class X
+    //   that can be called without an argument. If there is no
+    //   user-declared constructor for class X, a default constructor is
+    //   implicitly declared. An implicitly-declared default constructor
+    //   is an inline public member of its class.
+    DeclarationName Name
+      = Context.DeclarationNames.getCXXConstructorName(ClassType);
+    CXXConstructorDecl *DefaultCon =
+      CXXConstructorDecl::Create(Context, ClassDecl,
+                                 ClassDecl->getLocation(), Name,
+                                 Context.getFunctionType(Context.VoidTy,
+                                                         0, 0, false, 0,
+                                                         /*FIXME*/false, false,
+                                                         0, 0,
+                                                       FunctionType::ExtInfo()),
+                                 /*TInfo=*/0,
+                                 /*isExplicit=*/false,
+                                 /*isInline=*/true,
+                                 /*isImplicitlyDeclared=*/true);
+    DefaultCon->setAccess(AS_public);
+    DefaultCon->setImplicit();
+    DefaultCon->setTrivial(ClassDecl->hasTrivialConstructor());
+    if (S)
+      PushOnScopeChains(DefaultCon, S, true);
+    else
+      ClassDecl->addDecl(DefaultCon);
+  }
+
+  if (!ClassDecl->hasUserDeclaredCopyConstructor()) {
+    // C++ [class.copy]p4:
+    //   If the class definition does not explicitly declare a copy
+    //   constructor, one is declared implicitly.
+
+    // C++ [class.copy]p5:
+    //   The implicitly-declared copy constructor for a class X will
+    //   have the form
+    //
+    //       X::X(const X&)
+    //
+    //   if
+    bool HasConstCopyConstructor = true;
+
+    //     -- each direct or virtual base class B of X has a copy
+    //        constructor whose first parameter is of type const B& or
+    //        const volatile B&, and
+    for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin();
+         HasConstCopyConstructor && Base != ClassDecl->bases_end(); ++Base) {
+      const CXXRecordDecl *BaseClassDecl
+        = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
+      HasConstCopyConstructor
+        = BaseClassDecl->hasConstCopyConstructor(Context);
+    }
+
+    //     -- for all the nonstatic data members of X that are of a
+    //        class type M (or array thereof), each such class type
+    //        has a copy constructor whose first parameter is of type
+    //        const M& or const volatile M&.
+    for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin();
+         HasConstCopyConstructor && Field != ClassDecl->field_end();
+         ++Field) {
+      QualType FieldType = (*Field)->getType();
+      if (const ArrayType *Array = Context.getAsArrayType(FieldType))
+        FieldType = Array->getElementType();
+      if (const RecordType *FieldClassType = FieldType->getAs<RecordType>()) {
+        const CXXRecordDecl *FieldClassDecl
+          = cast<CXXRecordDecl>(FieldClassType->getDecl());
+        HasConstCopyConstructor
+          = FieldClassDecl->hasConstCopyConstructor(Context);
+      }
+    }
+
+    //   Otherwise, the implicitly declared copy constructor will have
+    //   the form
+    //
+    //       X::X(X&)
+    QualType ArgType = ClassType;
+    if (HasConstCopyConstructor)
+      ArgType = ArgType.withConst();
+    ArgType = Context.getLValueReferenceType(ArgType);
+
+    //   An implicitly-declared copy constructor is an inline public
+    //   member of its class.
+    DeclarationName Name
+      = Context.DeclarationNames.getCXXConstructorName(ClassType);
+    CXXConstructorDecl *CopyConstructor
+      = CXXConstructorDecl::Create(Context, ClassDecl,
+                                   ClassDecl->getLocation(), Name,
+                                   Context.getFunctionType(Context.VoidTy,
+                                                           &ArgType, 1,
+                                                           false, 0,
+                                                           /*FIXME:*/false,
+                                                           false, 0, 0,
+                                                       FunctionType::ExtInfo()),
+                                   /*TInfo=*/0,
+                                   /*isExplicit=*/false,
+                                   /*isInline=*/true,
+                                   /*isImplicitlyDeclared=*/true);
+    CopyConstructor->setAccess(AS_public);
+    CopyConstructor->setImplicit();
+    CopyConstructor->setTrivial(ClassDecl->hasTrivialCopyConstructor());
+
+    // Add the parameter to the constructor.
+    ParmVarDecl *FromParam = ParmVarDecl::Create(Context, CopyConstructor,
+                                                 ClassDecl->getLocation(),
+                                                 /*IdentifierInfo=*/0,
+                                                 ArgType, /*TInfo=*/0,
+                                                 VarDecl::None,
+                                                 VarDecl::None, 0);
+    CopyConstructor->setParams(&FromParam, 1);
+    if (S)
+      PushOnScopeChains(CopyConstructor, S, true);
+    else
+      ClassDecl->addDecl(CopyConstructor);
+  }
+
+  if (!ClassDecl->hasUserDeclaredCopyAssignment()) {
+    // Note: The following rules are largely analoguous to the copy
+    // constructor rules. Note that virtual bases are not taken into account
+    // for determining the argument type of the operator. Note also that
+    // operators taking an object instead of a reference are allowed.
+    //
+    // C++ [class.copy]p10:
+    //   If the class definition does not explicitly declare a copy
+    //   assignment operator, one is declared implicitly.
+    //   The implicitly-defined copy assignment operator for a class X
+    //   will have the form
+    //
+    //       X& X::operator=(const X&)
+    //
+    //   if
+    bool HasConstCopyAssignment = true;
+
+    //       -- each direct base class B of X has a copy assignment operator
+    //          whose parameter is of type const B&, const volatile B& or B,
+    //          and
+    for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin();
+         HasConstCopyAssignment && Base != ClassDecl->bases_end(); ++Base) {
+      assert(!Base->getType()->isDependentType() &&
+            "Cannot generate implicit members for class with dependent bases.");
+      const CXXRecordDecl *BaseClassDecl
+        = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
+      const CXXMethodDecl *MD = 0;
+      HasConstCopyAssignment = BaseClassDecl->hasConstCopyAssignment(Context,
+                                                                     MD);
+    }
+
+    //       -- for all the nonstatic data members of X that are of a class
+    //          type M (or array thereof), each such class type has a copy
+    //          assignment operator whose parameter is of type const M&,
+    //          const volatile M& or M.
+    for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin();
+         HasConstCopyAssignment && Field != ClassDecl->field_end();
+         ++Field) {
+      QualType FieldType = (*Field)->getType();
+      if (const ArrayType *Array = Context.getAsArrayType(FieldType))
+        FieldType = Array->getElementType();
+      if (const RecordType *FieldClassType = FieldType->getAs<RecordType>()) {
+        const CXXRecordDecl *FieldClassDecl
+          = cast<CXXRecordDecl>(FieldClassType->getDecl());
+        const CXXMethodDecl *MD = 0;
+        HasConstCopyAssignment
+          = FieldClassDecl->hasConstCopyAssignment(Context, MD);
+      }
+    }
+
+    //   Otherwise, the implicitly declared copy assignment operator will
+    //   have the form
+    //
+    //       X& X::operator=(X&)
+    QualType ArgType = ClassType;
+    QualType RetType = Context.getLValueReferenceType(ArgType);
+    if (HasConstCopyAssignment)
+      ArgType = ArgType.withConst();
+    ArgType = Context.getLValueReferenceType(ArgType);
+
+    //   An implicitly-declared copy assignment operator is an inline public
+    //   member of its class.
+    DeclarationName Name =
+      Context.DeclarationNames.getCXXOperatorName(OO_Equal);
+    CXXMethodDecl *CopyAssignment =
+      CXXMethodDecl::Create(Context, ClassDecl, ClassDecl->getLocation(), Name,
+                            Context.getFunctionType(RetType, &ArgType, 1,
+                                                    false, 0,
+                                                    /*FIXME:*/false,
+                                                    false, 0, 0,
+                                                    FunctionType::ExtInfo()),
+                            /*TInfo=*/0, /*isStatic=*/false,
+                            /*StorageClassAsWritten=*/FunctionDecl::None,
+                            /*isInline=*/true);
+    CopyAssignment->setAccess(AS_public);
+    CopyAssignment->setImplicit();
+    CopyAssignment->setTrivial(ClassDecl->hasTrivialCopyAssignment());
+    CopyAssignment->setCopyAssignment(true);
+
+    // Add the parameter to the operator.
+    ParmVarDecl *FromParam = ParmVarDecl::Create(Context, CopyAssignment,
+                                                 ClassDecl->getLocation(),
+                                                 /*IdentifierInfo=*/0,
+                                                 ArgType, /*TInfo=*/0,
+                                                 VarDecl::None,
+                                                 VarDecl::None, 0);
+    CopyAssignment->setParams(&FromParam, 1);
+
+    // Don't call addedAssignmentOperator. There is no way to distinguish an
+    // implicit from an explicit assignment operator.
+    if (S)
+      PushOnScopeChains(CopyAssignment, S, true);
+    else
+      ClassDecl->addDecl(CopyAssignment);
+    AddOverriddenMethods(ClassDecl, CopyAssignment);
+  }
+
+  if (!ClassDecl->hasUserDeclaredDestructor()) {
+    // C++ [class.dtor]p2:
+    //   If a class has no user-declared destructor, a destructor is
+    //   declared implicitly. An implicitly-declared destructor is an
+    //   inline public member of its class.
+    QualType Ty = Context.getFunctionType(Context.VoidTy,
+                                          0, 0, false, 0,
+                                          /*FIXME:*/false,
+                                          false, 0, 0, FunctionType::ExtInfo());
+
+    DeclarationName Name
+      = Context.DeclarationNames.getCXXDestructorName(ClassType);
+    CXXDestructorDecl *Destructor
+      = CXXDestructorDecl::Create(Context, ClassDecl,
+                                  ClassDecl->getLocation(), Name, Ty,
+                                  /*isInline=*/true,
+                                  /*isImplicitlyDeclared=*/true);
+    Destructor->setAccess(AS_public);
+    Destructor->setImplicit();
+    Destructor->setTrivial(ClassDecl->hasTrivialDestructor());
+    if (S)
+      PushOnScopeChains(Destructor, S, true);
+    else
+      ClassDecl->addDecl(Destructor);
+
+    // This could be uniqued if it ever proves significant.
+    Destructor->setTypeSourceInfo(Context.getTrivialTypeSourceInfo(Ty));
+    
+    AddOverriddenMethods(ClassDecl, Destructor);
+  }
+}
+
+void Sema::ActOnReenterTemplateScope(Scope *S, DeclPtrTy TemplateD) {
+  Decl *D = TemplateD.getAs<Decl>();
+  if (!D)
+    return;
+  
+  TemplateParameterList *Params = 0;
+  if (TemplateDecl *Template = dyn_cast<TemplateDecl>(D))
+    Params = Template->getTemplateParameters();
+  else if (ClassTemplatePartialSpecializationDecl *PartialSpec
+           = dyn_cast<ClassTemplatePartialSpecializationDecl>(D))
+    Params = PartialSpec->getTemplateParameters();
+  else
+    return;
+
+  for (TemplateParameterList::iterator Param = Params->begin(),
+                                    ParamEnd = Params->end();
+       Param != ParamEnd; ++Param) {
+    NamedDecl *Named = cast<NamedDecl>(*Param);
+    if (Named->getDeclName()) {
+      S->AddDecl(DeclPtrTy::make(Named));
+      IdResolver.AddDecl(Named);
+    }
+  }
+}
+
+void Sema::ActOnStartDelayedMemberDeclarations(Scope *S, DeclPtrTy RecordD) {
+  if (!RecordD) return;
+  AdjustDeclIfTemplate(RecordD);
+  CXXRecordDecl *Record = cast<CXXRecordDecl>(RecordD.getAs<Decl>());
+  PushDeclContext(S, Record);
+}
+
+void Sema::ActOnFinishDelayedMemberDeclarations(Scope *S, DeclPtrTy RecordD) {
+  if (!RecordD) return;
+  PopDeclContext();
+}
+
+/// ActOnStartDelayedCXXMethodDeclaration - We have completed
+/// parsing a top-level (non-nested) C++ class, and we are now
+/// parsing those parts of the given Method declaration that could
+/// not be parsed earlier (C++ [class.mem]p2), such as default
+/// arguments. This action should enter the scope of the given
+/// Method declaration as if we had just parsed the qualified method
+/// name. However, it should not bring the parameters into scope;
+/// that will be performed by ActOnDelayedCXXMethodParameter.
+void Sema::ActOnStartDelayedCXXMethodDeclaration(Scope *S, DeclPtrTy MethodD) {
+}
+
+/// ActOnDelayedCXXMethodParameter - We've already started a delayed
+/// C++ method declaration. We're (re-)introducing the given
+/// function parameter into scope for use in parsing later parts of
+/// the method declaration. For example, we could see an
+/// ActOnParamDefaultArgument event for this parameter.
+void Sema::ActOnDelayedCXXMethodParameter(Scope *S, DeclPtrTy ParamD) {
+  if (!ParamD)
+    return;
+
+  ParmVarDecl *Param = cast<ParmVarDecl>(ParamD.getAs<Decl>());
+
+  // If this parameter has an unparsed default argument, clear it out
+  // to make way for the parsed default argument.
+  if (Param->hasUnparsedDefaultArg())
+    Param->setDefaultArg(0);
+
+  S->AddDecl(DeclPtrTy::make(Param));
+  if (Param->getDeclName())
+    IdResolver.AddDecl(Param);
+}
+
+/// ActOnFinishDelayedCXXMethodDeclaration - We have finished
+/// processing the delayed method declaration for Method. The method
+/// declaration is now considered finished. There may be a separate
+/// ActOnStartOfFunctionDef action later (not necessarily
+/// immediately!) for this method, if it was also defined inside the
+/// class body.
+void Sema::ActOnFinishDelayedCXXMethodDeclaration(Scope *S, DeclPtrTy MethodD) {
+  if (!MethodD)
+    return;
+
+  AdjustDeclIfTemplate(MethodD);
+
+  FunctionDecl *Method = cast<FunctionDecl>(MethodD.getAs<Decl>());
+
+  // Now that we have our default arguments, check the constructor
+  // again. It could produce additional diagnostics or affect whether
+  // the class has implicitly-declared destructors, among other
+  // things.
+  if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(Method))
+    CheckConstructor(Constructor);
+
+  // Check the default arguments, which we may have added.
+  if (!Method->isInvalidDecl())
+    CheckCXXDefaultArguments(Method);
+}
+
+/// CheckConstructorDeclarator - Called by ActOnDeclarator to check
+/// the well-formedness of the constructor declarator @p D with type @p
+/// R. If there are any errors in the declarator, this routine will
+/// emit diagnostics and set the invalid bit to true.  In any case, the type
+/// will be updated to reflect a well-formed type for the constructor and
+/// returned.
+QualType Sema::CheckConstructorDeclarator(Declarator &D, QualType R,
+                                          FunctionDecl::StorageClass &SC) {
+  bool isVirtual = D.getDeclSpec().isVirtualSpecified();
+
+  // C++ [class.ctor]p3:
+  //   A constructor shall not be virtual (10.3) or static (9.4). A
+  //   constructor can be invoked for a const, volatile or const
+  //   volatile object. A constructor shall not be declared const,
+  //   volatile, or const volatile (9.3.2).
+  if (isVirtual) {
+    if (!D.isInvalidType())
+      Diag(D.getIdentifierLoc(), diag::err_constructor_cannot_be)
+        << "virtual" << SourceRange(D.getDeclSpec().getVirtualSpecLoc())
+        << SourceRange(D.getIdentifierLoc());
+    D.setInvalidType();
+  }
+  if (SC == FunctionDecl::Static) {
+    if (!D.isInvalidType())
+      Diag(D.getIdentifierLoc(), diag::err_constructor_cannot_be)
+        << "static" << SourceRange(D.getDeclSpec().getStorageClassSpecLoc())
+        << SourceRange(D.getIdentifierLoc());
+    D.setInvalidType();
+    SC = FunctionDecl::None;
+  }
+
+  DeclaratorChunk::FunctionTypeInfo &FTI = D.getTypeObject(0).Fun;
+  if (FTI.TypeQuals != 0) {
+    if (FTI.TypeQuals & Qualifiers::Const)
+      Diag(D.getIdentifierLoc(), diag::err_invalid_qualified_constructor)
+        << "const" << SourceRange(D.getIdentifierLoc());
+    if (FTI.TypeQuals & Qualifiers::Volatile)
+      Diag(D.getIdentifierLoc(), diag::err_invalid_qualified_constructor)
+        << "volatile" << SourceRange(D.getIdentifierLoc());
+    if (FTI.TypeQuals & Qualifiers::Restrict)
+      Diag(D.getIdentifierLoc(), diag::err_invalid_qualified_constructor)
+        << "restrict" << SourceRange(D.getIdentifierLoc());
+  }
+
+  // Rebuild the function type "R" without any type qualifiers (in
+  // case any of the errors above fired) and with "void" as the
+  // return type, since constructors don't have return types. We
+  // *always* have to do this, because GetTypeForDeclarator will
+  // put in a result type of "int" when none was specified.
+  const FunctionProtoType *Proto = R->getAs<FunctionProtoType>();
+  return Context.getFunctionType(Context.VoidTy, Proto->arg_type_begin(),
+                                 Proto->getNumArgs(),
+                                 Proto->isVariadic(), 0,
+                                 Proto->hasExceptionSpec(),
+                                 Proto->hasAnyExceptionSpec(),
+                                 Proto->getNumExceptions(),
+                                 Proto->exception_begin(),
+                                 Proto->getExtInfo());
+}
+
+/// CheckConstructor - Checks a fully-formed constructor for
+/// well-formedness, issuing any diagnostics required. Returns true if
+/// the constructor declarator is invalid.
+void Sema::CheckConstructor(CXXConstructorDecl *Constructor) {
+  CXXRecordDecl *ClassDecl
+    = dyn_cast<CXXRecordDecl>(Constructor->getDeclContext());
+  if (!ClassDecl)
+    return Constructor->setInvalidDecl();
+
+  // C++ [class.copy]p3:
+  //   A declaration of a constructor for a class X is ill-formed if
+  //   its first parameter is of type (optionally cv-qualified) X and
+  //   either there are no other parameters or else all other
+  //   parameters have default arguments.
+  if (!Constructor->isInvalidDecl() &&
+      ((Constructor->getNumParams() == 1) ||
+       (Constructor->getNumParams() > 1 &&
+        Constructor->getParamDecl(1)->hasDefaultArg())) &&
+      Constructor->getTemplateSpecializationKind()
+                                              != TSK_ImplicitInstantiation) {
+    QualType ParamType = Constructor->getParamDecl(0)->getType();
+    QualType ClassTy = Context.getTagDeclType(ClassDecl);
+    if (Context.getCanonicalType(ParamType).getUnqualifiedType() == ClassTy) {
+      SourceLocation ParamLoc = Constructor->getParamDecl(0)->getLocation();
+      Diag(ParamLoc, diag::err_constructor_byvalue_arg)
+        << FixItHint::CreateInsertion(ParamLoc, " const &");
+
+      // FIXME: Rather that making the constructor invalid, we should endeavor
+      // to fix the type.
+      Constructor->setInvalidDecl();
+    }
+  }
+
+  // Notify the class that we've added a constructor.  In principle we
+  // don't need to do this for out-of-line declarations; in practice
+  // we only instantiate the most recent declaration of a method, so
+  // we have to call this for everything but friends.
+  if (!Constructor->getFriendObjectKind())
+    ClassDecl->addedConstructor(Context, Constructor);
+}
+
+/// CheckDestructor - Checks a fully-formed destructor for well-formedness, 
+/// issuing any diagnostics required. Returns true on error.
+bool Sema::CheckDestructor(CXXDestructorDecl *Destructor) {
+  CXXRecordDecl *RD = Destructor->getParent();
+  
+  if (Destructor->isVirtual()) {
+    SourceLocation Loc;
+    
+    if (!Destructor->isImplicit())
+      Loc = Destructor->getLocation();
+    else
+      Loc = RD->getLocation();
+    
+    // If we have a virtual destructor, look up the deallocation function
+    FunctionDecl *OperatorDelete = 0;
+    DeclarationName Name = 
+    Context.DeclarationNames.getCXXOperatorName(OO_Delete);
+    if (FindDeallocationFunction(Loc, RD, Name, OperatorDelete))
+      return true;
+    
+    Destructor->setOperatorDelete(OperatorDelete);
+  }
+  
+  return false;
+}
+
+static inline bool
+FTIHasSingleVoidArgument(DeclaratorChunk::FunctionTypeInfo &FTI) {
+  return (FTI.NumArgs == 1 && !FTI.isVariadic && FTI.ArgInfo[0].Ident == 0 &&
+          FTI.ArgInfo[0].Param &&
+          FTI.ArgInfo[0].Param.getAs<ParmVarDecl>()->getType()->isVoidType());
+}
+
+/// CheckDestructorDeclarator - Called by ActOnDeclarator to check
+/// the well-formednes of the destructor declarator @p D with type @p
+/// R. If there are any errors in the declarator, this routine will
+/// emit diagnostics and set the declarator to invalid.  Even if this happens,
+/// will be updated to reflect a well-formed type for the destructor and
+/// returned.
+QualType Sema::CheckDestructorDeclarator(Declarator &D,
+                                         FunctionDecl::StorageClass& SC) {
+  // C++ [class.dtor]p1:
+  //   [...] A typedef-name that names a class is a class-name
+  //   (7.1.3); however, a typedef-name that names a class shall not
+  //   be used as the identifier in the declarator for a destructor
+  //   declaration.
+  QualType DeclaratorType = GetTypeFromParser(D.getName().DestructorName);
+  if (isa<TypedefType>(DeclaratorType)) {
+    Diag(D.getIdentifierLoc(), diag::err_destructor_typedef_name)
+      << DeclaratorType;
+    D.setInvalidType();
+  }
+
+  // C++ [class.dtor]p2:
+  //   A destructor is used to destroy objects of its class type. A
+  //   destructor takes no parameters, and no return type can be
+  //   specified for it (not even void). The address of a destructor
+  //   shall not be taken. A destructor shall not be static. A
+  //   destructor can be invoked for a const, volatile or const
+  //   volatile object. A destructor shall not be declared const,
+  //   volatile or const volatile (9.3.2).
+  if (SC == FunctionDecl::Static) {
+    if (!D.isInvalidType())
+      Diag(D.getIdentifierLoc(), diag::err_destructor_cannot_be)
+        << "static" << SourceRange(D.getDeclSpec().getStorageClassSpecLoc())
+        << SourceRange(D.getIdentifierLoc());
+    SC = FunctionDecl::None;
+    D.setInvalidType();
+  }
+  if (D.getDeclSpec().hasTypeSpecifier() && !D.isInvalidType()) {
+    // Destructors don't have return types, but the parser will
+    // happily parse something like:
+    //
+    //   class X {
+    //     float ~X();
+    //   };
+    //
+    // The return type will be eliminated later.
+    Diag(D.getIdentifierLoc(), diag::err_destructor_return_type)
+      << SourceRange(D.getDeclSpec().getTypeSpecTypeLoc())
+      << SourceRange(D.getIdentifierLoc());
+  }
+
+  DeclaratorChunk::FunctionTypeInfo &FTI = D.getTypeObject(0).Fun;
+  if (FTI.TypeQuals != 0 && !D.isInvalidType()) {
+    if (FTI.TypeQuals & Qualifiers::Const)
+      Diag(D.getIdentifierLoc(), diag::err_invalid_qualified_destructor)
+        << "const" << SourceRange(D.getIdentifierLoc());
+    if (FTI.TypeQuals & Qualifiers::Volatile)
+      Diag(D.getIdentifierLoc(), diag::err_invalid_qualified_destructor)
+        << "volatile" << SourceRange(D.getIdentifierLoc());
+    if (FTI.TypeQuals & Qualifiers::Restrict)
+      Diag(D.getIdentifierLoc(), diag::err_invalid_qualified_destructor)
+        << "restrict" << SourceRange(D.getIdentifierLoc());
+    D.setInvalidType();
+  }
+
+  // Make sure we don't have any parameters.
+  if (FTI.NumArgs > 0 && !FTIHasSingleVoidArgument(FTI)) {
+    Diag(D.getIdentifierLoc(), diag::err_destructor_with_params);
+
+    // Delete the parameters.
+    FTI.freeArgs();
+    D.setInvalidType();
+  }
+
+  // Make sure the destructor isn't variadic.
+  if (FTI.isVariadic) {
+    Diag(D.getIdentifierLoc(), diag::err_destructor_variadic);
+    D.setInvalidType();
+  }
+
+  // Rebuild the function type "R" without any type qualifiers or
+  // parameters (in case any of the errors above fired) and with
+  // "void" as the return type, since destructors don't have return
+  // types. We *always* have to do this, because GetTypeForDeclarator
+  // will put in a result type of "int" when none was specified.
+  // FIXME: Exceptions!
+  return Context.getFunctionType(Context.VoidTy, 0, 0, false, 0,
+                                 false, false, 0, 0, FunctionType::ExtInfo());
+}
+
+/// CheckConversionDeclarator - Called by ActOnDeclarator to check the
+/// well-formednes of the conversion function declarator @p D with
+/// type @p R. If there are any errors in the declarator, this routine
+/// will emit diagnostics and return true. Otherwise, it will return
+/// false. Either way, the type @p R will be updated to reflect a
+/// well-formed type for the conversion operator.
+void Sema::CheckConversionDeclarator(Declarator &D, QualType &R,
+                                     FunctionDecl::StorageClass& SC) {
+  // C++ [class.conv.fct]p1:
+  //   Neither parameter types nor return type can be specified. The
+  //   type of a conversion function (8.3.5) is "function taking no
+  //   parameter returning conversion-type-id."
+  if (SC == FunctionDecl::Static) {
+    if (!D.isInvalidType())
+      Diag(D.getIdentifierLoc(), diag::err_conv_function_not_member)
+        << "static" << SourceRange(D.getDeclSpec().getStorageClassSpecLoc())
+        << SourceRange(D.getIdentifierLoc());
+    D.setInvalidType();
+    SC = FunctionDecl::None;
+  }
+
+  QualType ConvType = GetTypeFromParser(D.getName().ConversionFunctionId);
+
+  if (D.getDeclSpec().hasTypeSpecifier() && !D.isInvalidType()) {
+    // Conversion functions don't have return types, but the parser will
+    // happily parse something like:
+    //
+    //   class X {
+    //     float operator bool();
+    //   };
+    //
+    // The return type will be changed later anyway.
+    Diag(D.getIdentifierLoc(), diag::err_conv_function_return_type)
+      << SourceRange(D.getDeclSpec().getTypeSpecTypeLoc())
+      << SourceRange(D.getIdentifierLoc());
+    D.setInvalidType();
+  }
+
+  const FunctionProtoType *Proto = R->getAs<FunctionProtoType>();
+
+  // Make sure we don't have any parameters.
+  if (Proto->getNumArgs() > 0) {
+    Diag(D.getIdentifierLoc(), diag::err_conv_function_with_params);
+
+    // Delete the parameters.
+    D.getTypeObject(0).Fun.freeArgs();
+    D.setInvalidType();
+  } else if (Proto->isVariadic()) {
+    Diag(D.getIdentifierLoc(), diag::err_conv_function_variadic);
+    D.setInvalidType();
+  }
+
+  // Diagnose "&operator bool()" and other such nonsense.  This
+  // is actually a gcc extension which we don't support.
+  if (Proto->getResultType() != ConvType) {
+    Diag(D.getIdentifierLoc(), diag::err_conv_function_with_complex_decl)
+      << Proto->getResultType();
+    D.setInvalidType();
+    ConvType = Proto->getResultType();
+  }
+
+  // C++ [class.conv.fct]p4:
+  //   The conversion-type-id shall not represent a function type nor
+  //   an array type.
+  if (ConvType->isArrayType()) {
+    Diag(D.getIdentifierLoc(), diag::err_conv_function_to_array);
+    ConvType = Context.getPointerType(ConvType);
+    D.setInvalidType();
+  } else if (ConvType->isFunctionType()) {
+    Diag(D.getIdentifierLoc(), diag::err_conv_function_to_function);
+    ConvType = Context.getPointerType(ConvType);
+    D.setInvalidType();
+  }
+
+  // Rebuild the function type "R" without any parameters (in case any
+  // of the errors above fired) and with the conversion type as the
+  // return type.
+  if (D.isInvalidType()) {
+    R = Context.getFunctionType(ConvType, 0, 0, false,
+                                Proto->getTypeQuals(),
+                                Proto->hasExceptionSpec(),
+                                Proto->hasAnyExceptionSpec(),
+                                Proto->getNumExceptions(),
+                                Proto->exception_begin(),
+                                Proto->getExtInfo());
+  }
+
+  // C++0x explicit conversion operators.
+  if (D.getDeclSpec().isExplicitSpecified() && !getLangOptions().CPlusPlus0x)
+    Diag(D.getDeclSpec().getExplicitSpecLoc(),
+         diag::warn_explicit_conversion_functions)
+      << SourceRange(D.getDeclSpec().getExplicitSpecLoc());
+}
+
+/// ActOnConversionDeclarator - Called by ActOnDeclarator to complete
+/// the declaration of the given C++ conversion function. This routine
+/// is responsible for recording the conversion function in the C++
+/// class, if possible.
+Sema::DeclPtrTy Sema::ActOnConversionDeclarator(CXXConversionDecl *Conversion) {
+  assert(Conversion && "Expected to receive a conversion function declaration");
+
+  CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(Conversion->getDeclContext());
+
+  // Make sure we aren't redeclaring the conversion function.
+  QualType ConvType = Context.getCanonicalType(Conversion->getConversionType());
+
+  // C++ [class.conv.fct]p1:
+  //   [...] A conversion function is never used to convert a
+  //   (possibly cv-qualified) object to the (possibly cv-qualified)
+  //   same object type (or a reference to it), to a (possibly
+  //   cv-qualified) base class of that type (or a reference to it),
+  //   or to (possibly cv-qualified) void.
+  // FIXME: Suppress this warning if the conversion function ends up being a
+  // virtual function that overrides a virtual function in a base class.
+  QualType ClassType
+    = Context.getCanonicalType(Context.getTypeDeclType(ClassDecl));
+  if (const ReferenceType *ConvTypeRef = ConvType->getAs<ReferenceType>())
+    ConvType = ConvTypeRef->getPointeeType();
+  if (ConvType->isRecordType()) {
+    ConvType = Context.getCanonicalType(ConvType).getUnqualifiedType();
+    if (ConvType == ClassType)
+      Diag(Conversion->getLocation(), diag::warn_conv_to_self_not_used)
+        << ClassType;
+    else if (IsDerivedFrom(ClassType, ConvType))
+      Diag(Conversion->getLocation(), diag::warn_conv_to_base_not_used)
+        <<  ClassType << ConvType;
+  } else if (ConvType->isVoidType()) {
+    Diag(Conversion->getLocation(), diag::warn_conv_to_void_not_used)
+      << ClassType << ConvType;
+  }
+
+  if (Conversion->getPrimaryTemplate()) {
+    // ignore specializations
+  } else if (Conversion->getPreviousDeclaration()) {
+    if (FunctionTemplateDecl *ConversionTemplate
+                                  = Conversion->getDescribedFunctionTemplate()) {
+      if (ClassDecl->replaceConversion(
+                                   ConversionTemplate->getPreviousDeclaration(),
+                                       ConversionTemplate))
+        return DeclPtrTy::make(ConversionTemplate);
+    } else if (ClassDecl->replaceConversion(Conversion->getPreviousDeclaration(),
+                                            Conversion))
+      return DeclPtrTy::make(Conversion);
+    assert(Conversion->isInvalidDecl() && "Conversion should not get here.");
+  } else if (FunctionTemplateDecl *ConversionTemplate
+               = Conversion->getDescribedFunctionTemplate())
+    ClassDecl->addConversionFunction(ConversionTemplate);
+  else 
+    ClassDecl->addConversionFunction(Conversion);
+
+  return DeclPtrTy::make(Conversion);
+}
+
+//===----------------------------------------------------------------------===//
+// Namespace Handling
+//===----------------------------------------------------------------------===//
+
+/// ActOnStartNamespaceDef - This is called at the start of a namespace
+/// definition.
+Sema::DeclPtrTy Sema::ActOnStartNamespaceDef(Scope *NamespcScope,
+                                             SourceLocation IdentLoc,
+                                             IdentifierInfo *II,
+                                             SourceLocation LBrace,
+                                             AttributeList *AttrList) {
+  NamespaceDecl *Namespc =
+      NamespaceDecl::Create(Context, CurContext, IdentLoc, II);
+  Namespc->setLBracLoc(LBrace);
+
+  Scope *DeclRegionScope = NamespcScope->getParent();
+
+  ProcessDeclAttributeList(DeclRegionScope, Namespc, AttrList);
+
+  if (II) {
+    // C++ [namespace.def]p2:
+    // The identifier in an original-namespace-definition shall not have been
+    // previously defined in the declarative region in which the
+    // original-namespace-definition appears. The identifier in an
+    // original-namespace-definition is the name of the namespace. Subsequently
+    // in that declarative region, it is treated as an original-namespace-name.
+
+    NamedDecl *PrevDecl
+      = LookupSingleName(DeclRegionScope, II, IdentLoc, LookupOrdinaryName,
+                         ForRedeclaration);
+
+    if (NamespaceDecl *OrigNS = dyn_cast_or_null<NamespaceDecl>(PrevDecl)) {
+      // This is an extended namespace definition.
+      // Attach this namespace decl to the chain of extended namespace
+      // definitions.
+      OrigNS->setNextNamespace(Namespc);
+      Namespc->setOriginalNamespace(OrigNS->getOriginalNamespace());
+
+      // Remove the previous declaration from the scope.
+      if (DeclRegionScope->isDeclScope(DeclPtrTy::make(OrigNS))) {
+        IdResolver.RemoveDecl(OrigNS);
+        DeclRegionScope->RemoveDecl(DeclPtrTy::make(OrigNS));
+      }
+    } else if (PrevDecl) {
+      // This is an invalid name redefinition.
+      Diag(Namespc->getLocation(), diag::err_redefinition_different_kind)
+       << Namespc->getDeclName();
+      Diag(PrevDecl->getLocation(), diag::note_previous_definition);
+      Namespc->setInvalidDecl();
+      // Continue on to push Namespc as current DeclContext and return it.
+    } else if (II->isStr("std") && 
+               CurContext->getLookupContext()->isTranslationUnit()) {
+      // This is the first "real" definition of the namespace "std", so update
+      // our cache of the "std" namespace to point at this definition.
+      if (StdNamespace) {
+        // We had already defined a dummy namespace "std". Link this new 
+        // namespace definition to the dummy namespace "std".
+        StdNamespace->setNextNamespace(Namespc);
+        StdNamespace->setLocation(IdentLoc);
+        Namespc->setOriginalNamespace(StdNamespace->getOriginalNamespace());
+      }
+      
+      // Make our StdNamespace cache point at the first real definition of the
+      // "std" namespace.
+      StdNamespace = Namespc;
+    }
+
+    PushOnScopeChains(Namespc, DeclRegionScope);
+  } else {
+    // Anonymous namespaces.
+    assert(Namespc->isAnonymousNamespace());
+
+    // Link the anonymous namespace into its parent.
+    NamespaceDecl *PrevDecl;
+    DeclContext *Parent = CurContext->getLookupContext();
+    if (TranslationUnitDecl *TU = dyn_cast<TranslationUnitDecl>(Parent)) {
+      PrevDecl = TU->getAnonymousNamespace();
+      TU->setAnonymousNamespace(Namespc);
+    } else {
+      NamespaceDecl *ND = cast<NamespaceDecl>(Parent);
+      PrevDecl = ND->getAnonymousNamespace();
+      ND->setAnonymousNamespace(Namespc);
+    }
+
+    // Link the anonymous namespace with its previous declaration.
+    if (PrevDecl) {
+      assert(PrevDecl->isAnonymousNamespace());
+      assert(!PrevDecl->getNextNamespace());
+      Namespc->setOriginalNamespace(PrevDecl->getOriginalNamespace());
+      PrevDecl->setNextNamespace(Namespc);
+    }
+
+    CurContext->addDecl(Namespc);
+
+    // C++ [namespace.unnamed]p1.  An unnamed-namespace-definition
+    //   behaves as if it were replaced by
+    //     namespace unique { /* empty body */ }
+    //     using namespace unique;
+    //     namespace unique { namespace-body }
+    //   where all occurrences of 'unique' in a translation unit are
+    //   replaced by the same identifier and this identifier differs
+    //   from all other identifiers in the entire program.
+
+    // We just create the namespace with an empty name and then add an
+    // implicit using declaration, just like the standard suggests.
+    //
+    // CodeGen enforces the "universally unique" aspect by giving all
+    // declarations semantically contained within an anonymous
+    // namespace internal linkage.
+
+    if (!PrevDecl) {
+      UsingDirectiveDecl* UD
+        = UsingDirectiveDecl::Create(Context, CurContext,
+                                     /* 'using' */ LBrace,
+                                     /* 'namespace' */ SourceLocation(),
+                                     /* qualifier */ SourceRange(),
+                                     /* NNS */ NULL,
+                                     /* identifier */ SourceLocation(),
+                                     Namespc,
+                                     /* Ancestor */ CurContext);
+      UD->setImplicit();
+      CurContext->addDecl(UD);
+    }
+  }
+
+  // Although we could have an invalid decl (i.e. the namespace name is a
+  // redefinition), push it as current DeclContext and try to continue parsing.
+  // FIXME: We should be able to push Namespc here, so that the each DeclContext
+  // for the namespace has the declarations that showed up in that particular
+  // namespace definition.
+  PushDeclContext(NamespcScope, Namespc);
+  return DeclPtrTy::make(Namespc);
+}
+
+/// getNamespaceDecl - Returns the namespace a decl represents. If the decl
+/// is a namespace alias, returns the namespace it points to.
+static inline NamespaceDecl *getNamespaceDecl(NamedDecl *D) {
+  if (NamespaceAliasDecl *AD = dyn_cast_or_null<NamespaceAliasDecl>(D))
+    return AD->getNamespace();
+  return dyn_cast_or_null<NamespaceDecl>(D);
+}
+
+/// ActOnFinishNamespaceDef - This callback is called after a namespace is
+/// exited. Decl is the DeclTy returned by ActOnStartNamespaceDef.
+void Sema::ActOnFinishNamespaceDef(DeclPtrTy D, SourceLocation RBrace) {
+  Decl *Dcl = D.getAs<Decl>();
+  NamespaceDecl *Namespc = dyn_cast_or_null<NamespaceDecl>(Dcl);
+  assert(Namespc && "Invalid parameter, expected NamespaceDecl");
+  Namespc->setRBracLoc(RBrace);
+  PopDeclContext();
+}
+
+Sema::DeclPtrTy Sema::ActOnUsingDirective(Scope *S,
+                                          SourceLocation UsingLoc,
+                                          SourceLocation NamespcLoc,
+                                          CXXScopeSpec &SS,
+                                          SourceLocation IdentLoc,
+                                          IdentifierInfo *NamespcName,
+                                          AttributeList *AttrList) {
+  assert(!SS.isInvalid() && "Invalid CXXScopeSpec.");
+  assert(NamespcName && "Invalid NamespcName.");
+  assert(IdentLoc.isValid() && "Invalid NamespceName location.");
+  assert(S->getFlags() & Scope::DeclScope && "Invalid Scope.");
+
+  UsingDirectiveDecl *UDir = 0;
+
+  // Lookup namespace name.
+  LookupResult R(*this, NamespcName, IdentLoc, LookupNamespaceName);
+  LookupParsedName(R, S, &SS);
+  if (R.isAmbiguous())
+    return DeclPtrTy();
+
+  if (!R.empty()) {
+    NamedDecl *Named = R.getFoundDecl();
+    assert((isa<NamespaceDecl>(Named) || isa<NamespaceAliasDecl>(Named))
+        && "expected namespace decl");
+    // C++ [namespace.udir]p1:
+    //   A using-directive specifies that the names in the nominated
+    //   namespace can be used in the scope in which the
+    //   using-directive appears after the using-directive. During
+    //   unqualified name lookup (3.4.1), the names appear as if they
+    //   were declared in the nearest enclosing namespace which
+    //   contains both the using-directive and the nominated
+    //   namespace. [Note: in this context, "contains" means "contains
+    //   directly or indirectly". ]
+
+    // Find enclosing context containing both using-directive and
+    // nominated namespace.
+    NamespaceDecl *NS = getNamespaceDecl(Named);
+    DeclContext *CommonAncestor = cast<DeclContext>(NS);
+    while (CommonAncestor && !CommonAncestor->Encloses(CurContext))
+      CommonAncestor = CommonAncestor->getParent();
+
+    UDir = UsingDirectiveDecl::Create(Context, CurContext, UsingLoc, NamespcLoc,
+                                      SS.getRange(),
+                                      (NestedNameSpecifier *)SS.getScopeRep(),
+                                      IdentLoc, Named, CommonAncestor);
+    PushUsingDirective(S, UDir);
+  } else {
+    Diag(IdentLoc, diag::err_expected_namespace_name) << SS.getRange();
+  }
+
+  // FIXME: We ignore attributes for now.
+  delete AttrList;
+  return DeclPtrTy::make(UDir);
+}
+
+void Sema::PushUsingDirective(Scope *S, UsingDirectiveDecl *UDir) {
+  // If scope has associated entity, then using directive is at namespace
+  // or translation unit scope. We add UsingDirectiveDecls, into
+  // it's lookup structure.
+  if (DeclContext *Ctx = static_cast<DeclContext*>(S->getEntity()))
+    Ctx->addDecl(UDir);
+  else
+    // Otherwise it is block-sope. using-directives will affect lookup
+    // only to the end of scope.
+    S->PushUsingDirective(DeclPtrTy::make(UDir));
+}
+
+
+Sema::DeclPtrTy Sema::ActOnUsingDeclaration(Scope *S,
+                                            AccessSpecifier AS,
+                                            bool HasUsingKeyword,
+                                            SourceLocation UsingLoc,
+                                            CXXScopeSpec &SS,
+                                            UnqualifiedId &Name,
+                                            AttributeList *AttrList,
+                                            bool IsTypeName,
+                                            SourceLocation TypenameLoc) {
+  assert(S->getFlags() & Scope::DeclScope && "Invalid Scope.");
+
+  switch (Name.getKind()) {
+  case UnqualifiedId::IK_Identifier:
+  case UnqualifiedId::IK_OperatorFunctionId:
+  case UnqualifiedId::IK_LiteralOperatorId:
+  case UnqualifiedId::IK_ConversionFunctionId:
+    break;
+      
+  case UnqualifiedId::IK_ConstructorName:
+  case UnqualifiedId::IK_ConstructorTemplateId:
+    // C++0x inherited constructors.
+    if (getLangOptions().CPlusPlus0x) break;
+
+    Diag(Name.getSourceRange().getBegin(), diag::err_using_decl_constructor)
+      << SS.getRange();
+    return DeclPtrTy();
+      
+  case UnqualifiedId::IK_DestructorName:
+    Diag(Name.getSourceRange().getBegin(), diag::err_using_decl_destructor)
+      << SS.getRange();
+    return DeclPtrTy();
+      
+  case UnqualifiedId::IK_TemplateId:
+    Diag(Name.getSourceRange().getBegin(), diag::err_using_decl_template_id)
+      << SourceRange(Name.TemplateId->LAngleLoc, Name.TemplateId->RAngleLoc);
+    return DeclPtrTy();
+  }
+  
+  DeclarationName TargetName = GetNameFromUnqualifiedId(Name);
+  if (!TargetName)
+    return DeclPtrTy();
+
+  // Warn about using declarations.
+  // TODO: store that the declaration was written without 'using' and
+  // talk about access decls instead of using decls in the
+  // diagnostics.
+  if (!HasUsingKeyword) {
+    UsingLoc = Name.getSourceRange().getBegin();
+    
+    Diag(UsingLoc, diag::warn_access_decl_deprecated)
+      << FixItHint::CreateInsertion(SS.getRange().getBegin(), "using ");
+  }
+
+  NamedDecl *UD = BuildUsingDeclaration(S, AS, UsingLoc, SS,
+                                        Name.getSourceRange().getBegin(),
+                                        TargetName, AttrList,
+                                        /* IsInstantiation */ false,
+                                        IsTypeName, TypenameLoc);
+  if (UD)
+    PushOnScopeChains(UD, S, /*AddToContext*/ false);
+
+  return DeclPtrTy::make(UD);
+}
+
+/// Determines whether to create a using shadow decl for a particular
+/// decl, given the set of decls existing prior to this using lookup.
+bool Sema::CheckUsingShadowDecl(UsingDecl *Using, NamedDecl *Orig,
+                                const LookupResult &Previous) {
+  // Diagnose finding a decl which is not from a base class of the
+  // current class.  We do this now because there are cases where this
+  // function will silently decide not to build a shadow decl, which
+  // will pre-empt further diagnostics.
+  //
+  // We don't need to do this in C++0x because we do the check once on
+  // the qualifier.
+  //
+  // FIXME: diagnose the following if we care enough:
+  //   struct A { int foo; };
+  //   struct B : A { using A::foo; };
+  //   template <class T> struct C : A {};
+  //   template <class T> struct D : C<T> { using B::foo; } // <---
+  // This is invalid (during instantiation) in C++03 because B::foo
+  // resolves to the using decl in B, which is not a base class of D<T>.
+  // We can't diagnose it immediately because C<T> is an unknown
+  // specialization.  The UsingShadowDecl in D<T> then points directly
+  // to A::foo, which will look well-formed when we instantiate.
+  // The right solution is to not collapse the shadow-decl chain.
+  if (!getLangOptions().CPlusPlus0x && CurContext->isRecord()) {
+    DeclContext *OrigDC = Orig->getDeclContext();
+
+    // Handle enums and anonymous structs.
+    if (isa<EnumDecl>(OrigDC)) OrigDC = OrigDC->getParent();
+    CXXRecordDecl *OrigRec = cast<CXXRecordDecl>(OrigDC);
+    while (OrigRec->isAnonymousStructOrUnion())
+      OrigRec = cast<CXXRecordDecl>(OrigRec->getDeclContext());
+
+    if (cast<CXXRecordDecl>(CurContext)->isProvablyNotDerivedFrom(OrigRec)) {
+      if (OrigDC == CurContext) {
+        Diag(Using->getLocation(),
+             diag::err_using_decl_nested_name_specifier_is_current_class)
+          << Using->getNestedNameRange();
+        Diag(Orig->getLocation(), diag::note_using_decl_target);
+        return true;
+      }
+
+      Diag(Using->getNestedNameRange().getBegin(),
+           diag::err_using_decl_nested_name_specifier_is_not_base_class)
+        << Using->getTargetNestedNameDecl()
+        << cast<CXXRecordDecl>(CurContext)
+        << Using->getNestedNameRange();
+      Diag(Orig->getLocation(), diag::note_using_decl_target);
+      return true;
+    }
+  }
+
+  if (Previous.empty()) return false;
+
+  NamedDecl *Target = Orig;
+  if (isa<UsingShadowDecl>(Target))
+    Target = cast<UsingShadowDecl>(Target)->getTargetDecl();
+
+  // If the target happens to be one of the previous declarations, we
+  // don't have a conflict.
+  // 
+  // FIXME: but we might be increasing its access, in which case we
+  // should redeclare it.
+  NamedDecl *NonTag = 0, *Tag = 0;
+  for (LookupResult::iterator I = Previous.begin(), E = Previous.end();
+         I != E; ++I) {
+    NamedDecl *D = (*I)->getUnderlyingDecl();
+    if (D->getCanonicalDecl() == Target->getCanonicalDecl())
+      return false;
+
+    (isa<TagDecl>(D) ? Tag : NonTag) = D;
+  }
+
+  if (Target->isFunctionOrFunctionTemplate()) {
+    FunctionDecl *FD;
+    if (isa<FunctionTemplateDecl>(Target))
+      FD = cast<FunctionTemplateDecl>(Target)->getTemplatedDecl();
+    else
+      FD = cast<FunctionDecl>(Target);
+
+    NamedDecl *OldDecl = 0;
+    switch (CheckOverload(FD, Previous, OldDecl)) {
+    case Ovl_Overload:
+      return false;
+
+    case Ovl_NonFunction:
+      Diag(Using->getLocation(), diag::err_using_decl_conflict);
+      break;
+      
+    // We found a decl with the exact signature.
+    case Ovl_Match:
+      if (isa<UsingShadowDecl>(OldDecl)) {
+        // Silently ignore the possible conflict.
+        return false;
+      }
+
+      // If we're in a record, we want to hide the target, so we
+      // return true (without a diagnostic) to tell the caller not to
+      // build a shadow decl.
+      if (CurContext->isRecord())
+        return true;
+
+      // If we're not in a record, this is an error.
+      Diag(Using->getLocation(), diag::err_using_decl_conflict);
+      break;
+    }
+
+    Diag(Target->getLocation(), diag::note_using_decl_target);
+    Diag(OldDecl->getLocation(), diag::note_using_decl_conflict);
+    return true;
+  }
+
+  // Target is not a function.
+
+  if (isa<TagDecl>(Target)) {
+    // No conflict between a tag and a non-tag.
+    if (!Tag) return false;
+
+    Diag(Using->getLocation(), diag::err_using_decl_conflict);
+    Diag(Target->getLocation(), diag::note_using_decl_target);
+    Diag(Tag->getLocation(), diag::note_using_decl_conflict);
+    return true;
+  }
+
+  // No conflict between a tag and a non-tag.
+  if (!NonTag) return false;
+
+  Diag(Using->getLocation(), diag::err_using_decl_conflict);
+  Diag(Target->getLocation(), diag::note_using_decl_target);
+  Diag(NonTag->getLocation(), diag::note_using_decl_conflict);
+  return true;
+}
+
+/// Builds a shadow declaration corresponding to a 'using' declaration.
+UsingShadowDecl *Sema::BuildUsingShadowDecl(Scope *S,
+                                            UsingDecl *UD,
+                                            NamedDecl *Orig) {
+
+  // If we resolved to another shadow declaration, just coalesce them.
+  NamedDecl *Target = Orig;
+  if (isa<UsingShadowDecl>(Target)) {
+    Target = cast<UsingShadowDecl>(Target)->getTargetDecl();
+    assert(!isa<UsingShadowDecl>(Target) && "nested shadow declaration");
+  }
+  
+  UsingShadowDecl *Shadow
+    = UsingShadowDecl::Create(Context, CurContext,
+                              UD->getLocation(), UD, Target);
+  UD->addShadowDecl(Shadow);
+
+  if (S)
+    PushOnScopeChains(Shadow, S);
+  else
+    CurContext->addDecl(Shadow);
+  Shadow->setAccess(UD->getAccess());
+
+  // Register it as a conversion if appropriate.
+  if (Shadow->getDeclName().getNameKind()
+        == DeclarationName::CXXConversionFunctionName)
+    cast<CXXRecordDecl>(CurContext)->addConversionFunction(Shadow);
+
+  if (Orig->isInvalidDecl() || UD->isInvalidDecl())
+    Shadow->setInvalidDecl();
+
+  return Shadow;
+}
+
+/// Hides a using shadow declaration.  This is required by the current
+/// using-decl implementation when a resolvable using declaration in a
+/// class is followed by a declaration which would hide or override
+/// one or more of the using decl's targets; for example:
+///
+///   struct Base { void foo(int); };
+///   struct Derived : Base {
+///     using Base::foo;
+///     void foo(int);
+///   };
+///
+/// The governing language is C++03 [namespace.udecl]p12:
+///
+///   When a using-declaration brings names from a base class into a
+///   derived class scope, member functions in the derived class
+///   override and/or hide member functions with the same name and
+///   parameter types in a base class (rather than conflicting).
+///
+/// There are two ways to implement this:
+///   (1) optimistically create shadow decls when they're not hidden
+///       by existing declarations, or
+///   (2) don't create any shadow decls (or at least don't make them
+///       visible) until we've fully parsed/instantiated the class.
+/// The problem with (1) is that we might have to retroactively remove
+/// a shadow decl, which requires several O(n) operations because the
+/// decl structures are (very reasonably) not designed for removal.
+/// (2) avoids this but is very fiddly and phase-dependent.
+void Sema::HideUsingShadowDecl(Scope *S, UsingShadowDecl *Shadow) {
+  if (Shadow->getDeclName().getNameKind() ==
+        DeclarationName::CXXConversionFunctionName)
+    cast<CXXRecordDecl>(Shadow->getDeclContext())->removeConversion(Shadow);
+
+  // Remove it from the DeclContext...
+  Shadow->getDeclContext()->removeDecl(Shadow);
+
+  // ...and the scope, if applicable...
+  if (S) {
+    S->RemoveDecl(DeclPtrTy::make(static_cast<Decl*>(Shadow)));
+    IdResolver.RemoveDecl(Shadow);
+  }
+
+  // ...and the using decl.
+  Shadow->getUsingDecl()->removeShadowDecl(Shadow);
+
+  // TODO: complain somehow if Shadow was used.  It shouldn't
+  // be possible for this to happen, because...?
+}
+
+/// Builds a using declaration.
+///
+/// \param IsInstantiation - Whether this call arises from an
+///   instantiation of an unresolved using declaration.  We treat
+///   the lookup differently for these declarations.
+NamedDecl *Sema::BuildUsingDeclaration(Scope *S, AccessSpecifier AS,
+                                       SourceLocation UsingLoc,
+                                       CXXScopeSpec &SS,
+                                       SourceLocation IdentLoc,
+                                       DeclarationName Name,
+                                       AttributeList *AttrList,
+                                       bool IsInstantiation,
+                                       bool IsTypeName,
+                                       SourceLocation TypenameLoc) {
+  assert(!SS.isInvalid() && "Invalid CXXScopeSpec.");
+  assert(IdentLoc.isValid() && "Invalid TargetName location.");
+
+  // FIXME: We ignore attributes for now.
+  delete AttrList;
+
+  if (SS.isEmpty()) {
+    Diag(IdentLoc, diag::err_using_requires_qualname);
+    return 0;
+  }
+
+  // Do the redeclaration lookup in the current scope.
+  LookupResult Previous(*this, Name, IdentLoc, LookupUsingDeclName,
+                        ForRedeclaration);
+  Previous.setHideTags(false);
+  if (S) {
+    LookupName(Previous, S);
+
+    // It is really dumb that we have to do this.
+    LookupResult::Filter F = Previous.makeFilter();
+    while (F.hasNext()) {
+      NamedDecl *D = F.next();
+      if (!isDeclInScope(D, CurContext, S))
+        F.erase();
+    }
+    F.done();
+  } else {
+    assert(IsInstantiation && "no scope in non-instantiation");
+    assert(CurContext->isRecord() && "scope not record in instantiation");
+    LookupQualifiedName(Previous, CurContext);
+  }
+
+  NestedNameSpecifier *NNS =
+    static_cast<NestedNameSpecifier *>(SS.getScopeRep());
+
+  // Check for invalid redeclarations.
+  if (CheckUsingDeclRedeclaration(UsingLoc, IsTypeName, SS, IdentLoc, Previous))
+    return 0;
+
+  // Check for bad qualifiers.
+  if (CheckUsingDeclQualifier(UsingLoc, SS, IdentLoc))
+    return 0;
+
+  DeclContext *LookupContext = computeDeclContext(SS);
+  NamedDecl *D;
+  if (!LookupContext) {
+    if (IsTypeName) {
+      // FIXME: not all declaration name kinds are legal here
+      D = UnresolvedUsingTypenameDecl::Create(Context, CurContext,
+                                              UsingLoc, TypenameLoc,
+                                              SS.getRange(), NNS,
+                                              IdentLoc, Name);
+    } else {
+      D = UnresolvedUsingValueDecl::Create(Context, CurContext,
+                                           UsingLoc, SS.getRange(), NNS,
+                                           IdentLoc, Name);
+    }
+  } else {
+    D = UsingDecl::Create(Context, CurContext, IdentLoc,
+                          SS.getRange(), UsingLoc, NNS, Name,
+                          IsTypeName);
+  }
+  D->setAccess(AS);
+  CurContext->addDecl(D);
+
+  if (!LookupContext) return D;
+  UsingDecl *UD = cast<UsingDecl>(D);
+
+  if (RequireCompleteDeclContext(SS)) {
+    UD->setInvalidDecl();
+    return UD;
+  }
+
+  // Look up the target name.
+
+  LookupResult R(*this, Name, IdentLoc, LookupOrdinaryName);
+
+  // Unlike most lookups, we don't always want to hide tag
+  // declarations: tag names are visible through the using declaration
+  // even if hidden by ordinary names, *except* in a dependent context
+  // where it's important for the sanity of two-phase lookup.
+  if (!IsInstantiation)
+    R.setHideTags(false);
+
+  LookupQualifiedName(R, LookupContext);
+
+  if (R.empty()) {
+    Diag(IdentLoc, diag::err_no_member) 
+      << Name << LookupContext << SS.getRange();
+    UD->setInvalidDecl();
+    return UD;
+  }
+
+  if (R.isAmbiguous()) {
+    UD->setInvalidDecl();
+    return UD;
+  }
+
+  if (IsTypeName) {
+    // If we asked for a typename and got a non-type decl, error out.
+    if (!R.getAsSingle<TypeDecl>()) {
+      Diag(IdentLoc, diag::err_using_typename_non_type);
+      for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I)
+        Diag((*I)->getUnderlyingDecl()->getLocation(),
+             diag::note_using_decl_target);
+      UD->setInvalidDecl();
+      return UD;
+    }
+  } else {
+    // If we asked for a non-typename and we got a type, error out,
+    // but only if this is an instantiation of an unresolved using
+    // decl.  Otherwise just silently find the type name.
+    if (IsInstantiation && R.getAsSingle<TypeDecl>()) {
+      Diag(IdentLoc, diag::err_using_dependent_value_is_type);
+      Diag(R.getFoundDecl()->getLocation(), diag::note_using_decl_target);
+      UD->setInvalidDecl();
+      return UD;
+    }
+  }
+
+  // C++0x N2914 [namespace.udecl]p6:
+  // A using-declaration shall not name a namespace.
+  if (R.getAsSingle<NamespaceDecl>()) {
+    Diag(IdentLoc, diag::err_using_decl_can_not_refer_to_namespace)
+      << SS.getRange();
+    UD->setInvalidDecl();
+    return UD;
+  }
+
+  for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) {
+    if (!CheckUsingShadowDecl(UD, *I, Previous))
+      BuildUsingShadowDecl(S, UD, *I);
+  }
+
+  return UD;
+}
+
+/// Checks that the given using declaration is not an invalid
+/// redeclaration.  Note that this is checking only for the using decl
+/// itself, not for any ill-formedness among the UsingShadowDecls.
+bool Sema::CheckUsingDeclRedeclaration(SourceLocation UsingLoc,
+                                       bool isTypeName,
+                                       const CXXScopeSpec &SS,
+                                       SourceLocation NameLoc,
+                                       const LookupResult &Prev) {
+  // C++03 [namespace.udecl]p8:
+  // C++0x [namespace.udecl]p10:
+  //   A using-declaration is a declaration and can therefore be used
+  //   repeatedly where (and only where) multiple declarations are
+  //   allowed.
+  // That's only in file contexts.
+  if (CurContext->getLookupContext()->isFileContext())
+    return false;
+
+  NestedNameSpecifier *Qual
+    = static_cast<NestedNameSpecifier*>(SS.getScopeRep());
+
+  for (LookupResult::iterator I = Prev.begin(), E = Prev.end(); I != E; ++I) {
+    NamedDecl *D = *I;
+
+    bool DTypename;
+    NestedNameSpecifier *DQual;
+    if (UsingDecl *UD = dyn_cast<UsingDecl>(D)) {
+      DTypename = UD->isTypeName();
+      DQual = UD->getTargetNestedNameDecl();
+    } else if (UnresolvedUsingValueDecl *UD
+                 = dyn_cast<UnresolvedUsingValueDecl>(D)) {
+      DTypename = false;
+      DQual = UD->getTargetNestedNameSpecifier();
+    } else if (UnresolvedUsingTypenameDecl *UD
+                 = dyn_cast<UnresolvedUsingTypenameDecl>(D)) {
+      DTypename = true;
+      DQual = UD->getTargetNestedNameSpecifier();
+    } else continue;
+
+    // using decls differ if one says 'typename' and the other doesn't.
+    // FIXME: non-dependent using decls?
+    if (isTypeName != DTypename) continue;
+
+    // using decls differ if they name different scopes (but note that
+    // template instantiation can cause this check to trigger when it
+    // didn't before instantiation).
+    if (Context.getCanonicalNestedNameSpecifier(Qual) !=
+        Context.getCanonicalNestedNameSpecifier(DQual))
+      continue;
+
+    Diag(NameLoc, diag::err_using_decl_redeclaration) << SS.getRange();
+    Diag(D->getLocation(), diag::note_using_decl) << 1;
+    return true;
+  }
+
+  return false;
+}
+
+
+/// Checks that the given nested-name qualifier used in a using decl
+/// in the current context is appropriately related to the current
+/// scope.  If an error is found, diagnoses it and returns true.
+bool Sema::CheckUsingDeclQualifier(SourceLocation UsingLoc,
+                                   const CXXScopeSpec &SS,
+                                   SourceLocation NameLoc) {
+  DeclContext *NamedContext = computeDeclContext(SS);
+
+  if (!CurContext->isRecord()) {
+    // C++03 [namespace.udecl]p3:
+    // C++0x [namespace.udecl]p8:
+    //   A using-declaration for a class member shall be a member-declaration.
+
+    // If we weren't able to compute a valid scope, it must be a
+    // dependent class scope.
+    if (!NamedContext || NamedContext->isRecord()) {
+      Diag(NameLoc, diag::err_using_decl_can_not_refer_to_class_member)
+        << SS.getRange();
+      return true;
+    }
+
+    // Otherwise, everything is known to be fine.
+    return false;
+  }
+
+  // The current scope is a record.
+
+  // If the named context is dependent, we can't decide much.
+  if (!NamedContext) {
+    // FIXME: in C++0x, we can diagnose if we can prove that the
+    // nested-name-specifier does not refer to a base class, which is
+    // still possible in some cases.
+
+    // Otherwise we have to conservatively report that things might be
+    // okay.
+    return false;
+  }
+
+  if (!NamedContext->isRecord()) {
+    // Ideally this would point at the last name in the specifier,
+    // but we don't have that level of source info.
+    Diag(SS.getRange().getBegin(),
+         diag::err_using_decl_nested_name_specifier_is_not_class)
+      << (NestedNameSpecifier*) SS.getScopeRep() << SS.getRange();
+    return true;
+  }
+
+  if (getLangOptions().CPlusPlus0x) {
+    // C++0x [namespace.udecl]p3:
+    //   In a using-declaration used as a member-declaration, the
+    //   nested-name-specifier shall name a base class of the class
+    //   being defined.
+
+    if (cast<CXXRecordDecl>(CurContext)->isProvablyNotDerivedFrom(
+                                 cast<CXXRecordDecl>(NamedContext))) {
+      if (CurContext == NamedContext) {
+        Diag(NameLoc,
+             diag::err_using_decl_nested_name_specifier_is_current_class)
+          << SS.getRange();
+        return true;
+      }
+
+      Diag(SS.getRange().getBegin(),
+           diag::err_using_decl_nested_name_specifier_is_not_base_class)
+        << (NestedNameSpecifier*) SS.getScopeRep()
+        << cast<CXXRecordDecl>(CurContext)
+        << SS.getRange();
+      return true;
+    }
+
+    return false;
+  }
+
+  // C++03 [namespace.udecl]p4:
+  //   A using-declaration used as a member-declaration shall refer
+  //   to a member of a base class of the class being defined [etc.].
+
+  // Salient point: SS doesn't have to name a base class as long as
+  // lookup only finds members from base classes.  Therefore we can
+  // diagnose here only if we can prove that that can't happen,
+  // i.e. if the class hierarchies provably don't intersect.
+
+  // TODO: it would be nice if "definitely valid" results were cached
+  // in the UsingDecl and UsingShadowDecl so that these checks didn't
+  // need to be repeated.
+
+  struct UserData {
+    llvm::DenseSet<const CXXRecordDecl*> Bases;
+
+    static bool collect(const CXXRecordDecl *Base, void *OpaqueData) {
+      UserData *Data = reinterpret_cast<UserData*>(OpaqueData);
+      Data->Bases.insert(Base);
+      return true;
+    }
+
+    bool hasDependentBases(const CXXRecordDecl *Class) {
+      return !Class->forallBases(collect, this);
+    }
+
+    /// Returns true if the base is dependent or is one of the
+    /// accumulated base classes.
+    static bool doesNotContain(const CXXRecordDecl *Base, void *OpaqueData) {
+      UserData *Data = reinterpret_cast<UserData*>(OpaqueData);
+      return !Data->Bases.count(Base);
+    }
+
+    bool mightShareBases(const CXXRecordDecl *Class) {
+      return Bases.count(Class) || !Class->forallBases(doesNotContain, this);
+    }
+  };
+
+  UserData Data;
+
+  // Returns false if we find a dependent base.
+  if (Data.hasDependentBases(cast<CXXRecordDecl>(CurContext)))
+    return false;
+
+  // Returns false if the class has a dependent base or if it or one
+  // of its bases is present in the base set of the current context.
+  if (Data.mightShareBases(cast<CXXRecordDecl>(NamedContext)))
+    return false;
+
+  Diag(SS.getRange().getBegin(),
+       diag::err_using_decl_nested_name_specifier_is_not_base_class)
+    << (NestedNameSpecifier*) SS.getScopeRep()
+    << cast<CXXRecordDecl>(CurContext)
+    << SS.getRange();
+
+  return true;
+}
+
+Sema::DeclPtrTy Sema::ActOnNamespaceAliasDef(Scope *S,
+                                             SourceLocation NamespaceLoc,
+                                             SourceLocation AliasLoc,
+                                             IdentifierInfo *Alias,
+                                             CXXScopeSpec &SS,
+                                             SourceLocation IdentLoc,
+                                             IdentifierInfo *Ident) {
+
+  // Lookup the namespace name.
+  LookupResult R(*this, Ident, IdentLoc, LookupNamespaceName);
+  LookupParsedName(R, S, &SS);
+
+  // Check if we have a previous declaration with the same name.
+  if (NamedDecl *PrevDecl
+        = LookupSingleName(S, Alias, AliasLoc, LookupOrdinaryName, 
+                           ForRedeclaration)) {
+    if (NamespaceAliasDecl *AD = dyn_cast<NamespaceAliasDecl>(PrevDecl)) {
+      // We already have an alias with the same name that points to the same
+      // namespace, so don't create a new one.
+      // FIXME: At some point, we'll want to create the (redundant)
+      // declaration to maintain better source information.
+      if (!R.isAmbiguous() && !R.empty() &&
+          AD->getNamespace()->Equals(getNamespaceDecl(R.getFoundDecl())))
+        return DeclPtrTy();
+    }
+
+    unsigned DiagID = isa<NamespaceDecl>(PrevDecl) ? diag::err_redefinition :
+      diag::err_redefinition_different_kind;
+    Diag(AliasLoc, DiagID) << Alias;
+    Diag(PrevDecl->getLocation(), diag::note_previous_definition);
+    return DeclPtrTy();
+  }
+
+  if (R.isAmbiguous())
+    return DeclPtrTy();
+
+  if (R.empty()) {
+    Diag(NamespaceLoc, diag::err_expected_namespace_name) << SS.getRange();
+    return DeclPtrTy();
+  }
+
+  NamespaceAliasDecl *AliasDecl =
+    NamespaceAliasDecl::Create(Context, CurContext, NamespaceLoc, AliasLoc,
+                               Alias, SS.getRange(),
+                               (NestedNameSpecifier *)SS.getScopeRep(),
+                               IdentLoc, R.getFoundDecl());
+
+  PushOnScopeChains(AliasDecl, S);
+  return DeclPtrTy::make(AliasDecl);
+}
+
+void Sema::DefineImplicitDefaultConstructor(SourceLocation CurrentLocation,
+                                            CXXConstructorDecl *Constructor) {
+  assert((Constructor->isImplicit() && Constructor->isDefaultConstructor() &&
+          !Constructor->isUsed()) &&
+    "DefineImplicitDefaultConstructor - call it for implicit default ctor");
+
+  CXXRecordDecl *ClassDecl = Constructor->getParent();
+  assert(ClassDecl && "DefineImplicitDefaultConstructor - invalid constructor");
+
+  DeclContext *PreviousContext = CurContext;
+  CurContext = Constructor;
+  if (SetBaseOrMemberInitializers(Constructor, 0, 0, /*AnyErrors=*/false)) {
+    Diag(CurrentLocation, diag::note_member_synthesized_at) 
+      << CXXConstructor << Context.getTagDeclType(ClassDecl);
+    Constructor->setInvalidDecl();
+  } else {
+    Constructor->setUsed();
+  }
+  CurContext = PreviousContext;
+}
+
+void Sema::DefineImplicitDestructor(SourceLocation CurrentLocation,
+                                    CXXDestructorDecl *Destructor) {
+  assert((Destructor->isImplicit() && !Destructor->isUsed()) &&
+         "DefineImplicitDestructor - call it for implicit default dtor");
+  CXXRecordDecl *ClassDecl = Destructor->getParent();
+  assert(ClassDecl && "DefineImplicitDestructor - invalid destructor");
+
+  DeclContext *PreviousContext = CurContext;
+  CurContext = Destructor;
+
+  MarkBaseAndMemberDestructorsReferenced(Destructor->getLocation(),
+                                         Destructor->getParent());
+
+  // FIXME: If CheckDestructor fails, we should emit a note about where the
+  // implicit destructor was needed.
+  if (CheckDestructor(Destructor)) {
+    Diag(CurrentLocation, diag::note_member_synthesized_at) 
+      << CXXDestructor << Context.getTagDeclType(ClassDecl);
+
+    Destructor->setInvalidDecl();
+    CurContext = PreviousContext;
+
+    return;
+  }
+  CurContext = PreviousContext;
+
+  Destructor->setUsed();
+}
+
+void Sema::DefineImplicitOverloadedAssign(SourceLocation CurrentLocation,
+                                          CXXMethodDecl *MethodDecl) {
+  assert((MethodDecl->isImplicit() && MethodDecl->isOverloadedOperator() &&
+          MethodDecl->getOverloadedOperator() == OO_Equal &&
+          !MethodDecl->isUsed()) &&
+         "DefineImplicitOverloadedAssign - call it for implicit assignment op");
+
+  CXXRecordDecl *ClassDecl
+    = cast<CXXRecordDecl>(MethodDecl->getDeclContext());
+
+  DeclContext *PreviousContext = CurContext;
+  CurContext = MethodDecl;
+
+  // C++[class.copy] p12
+  // Before the implicitly-declared copy assignment operator for a class is
+  // implicitly defined, all implicitly-declared copy assignment operators
+  // for its direct base classes and its nonstatic data members shall have
+  // been implicitly defined.
+  bool err = false;
+  for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(),
+       E = ClassDecl->bases_end(); Base != E; ++Base) {
+    CXXRecordDecl *BaseClassDecl
+      = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
+    if (CXXMethodDecl *BaseAssignOpMethod =
+          getAssignOperatorMethod(CurrentLocation, MethodDecl->getParamDecl(0), 
+                                  BaseClassDecl)) {
+      CheckDirectMemberAccess(Base->getSourceRange().getBegin(),
+                              BaseAssignOpMethod,
+                              PDiag(diag::err_access_assign_base)
+                                << Base->getType());
+
+      MarkDeclarationReferenced(CurrentLocation, BaseAssignOpMethod);
+    }
+  }
+  for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
+       E = ClassDecl->field_end(); Field != E; ++Field) {
+    QualType FieldType = Context.getCanonicalType((*Field)->getType());
+    if (const ArrayType *Array = Context.getAsArrayType(FieldType))
+      FieldType = Array->getElementType();
+    if (const RecordType *FieldClassType = FieldType->getAs<RecordType>()) {
+      CXXRecordDecl *FieldClassDecl
+        = cast<CXXRecordDecl>(FieldClassType->getDecl());
+      if (CXXMethodDecl *FieldAssignOpMethod =
+          getAssignOperatorMethod(CurrentLocation, MethodDecl->getParamDecl(0), 
+                                  FieldClassDecl)) {
+        CheckDirectMemberAccess(Field->getLocation(),
+                                FieldAssignOpMethod,
+                                PDiag(diag::err_access_assign_field)
+                                  << Field->getDeclName() << Field->getType());
+
+        MarkDeclarationReferenced(CurrentLocation, FieldAssignOpMethod);
+      }
+    } else if (FieldType->isReferenceType()) {
+      Diag(ClassDecl->getLocation(), diag::err_uninitialized_member_for_assign)
+      << Context.getTagDeclType(ClassDecl) << 0 << Field->getDeclName();
+      Diag(Field->getLocation(), diag::note_declared_at);
+      Diag(CurrentLocation, diag::note_first_required_here);
+      err = true;
+    } else if (FieldType.isConstQualified()) {
+      Diag(ClassDecl->getLocation(), diag::err_uninitialized_member_for_assign)
+      << Context.getTagDeclType(ClassDecl) << 1 << Field->getDeclName();
+      Diag(Field->getLocation(), diag::note_declared_at);
+      Diag(CurrentLocation, diag::note_first_required_here);
+      err = true;
+    }
+  }
+  if (!err)
+    MethodDecl->setUsed();
+
+  CurContext = PreviousContext;
+}
+
+CXXMethodDecl *
+Sema::getAssignOperatorMethod(SourceLocation CurrentLocation,
+                              ParmVarDecl *ParmDecl,
+                              CXXRecordDecl *ClassDecl) {
+  QualType LHSType = Context.getTypeDeclType(ClassDecl);
+  QualType RHSType(LHSType);
+  // If class's assignment operator argument is const/volatile qualified,
+  // look for operator = (const/volatile B&). Otherwise, look for
+  // operator = (B&).
+  RHSType = Context.getCVRQualifiedType(RHSType,
+                                     ParmDecl->getType().getCVRQualifiers());
+  ExprOwningPtr<Expr> LHS(this,  new (Context) DeclRefExpr(ParmDecl,
+                                                           LHSType,
+                                                           SourceLocation()));
+  ExprOwningPtr<Expr> RHS(this,  new (Context) DeclRefExpr(ParmDecl,
+                                                           RHSType,
+                                                           CurrentLocation));
+  Expr *Args[2] = { &*LHS, &*RHS };
+  OverloadCandidateSet CandidateSet(CurrentLocation);
+  AddMemberOperatorCandidates(clang::OO_Equal, SourceLocation(), Args, 2,
+                              CandidateSet);
+  OverloadCandidateSet::iterator Best;
+  if (BestViableFunction(CandidateSet, CurrentLocation, Best) == OR_Success)
+    return cast<CXXMethodDecl>(Best->Function);
+  assert(false &&
+         "getAssignOperatorMethod - copy assignment operator method not found");
+  return 0;
+}
+
+void Sema::DefineImplicitCopyConstructor(SourceLocation CurrentLocation,
+                                   CXXConstructorDecl *CopyConstructor,
+                                   unsigned TypeQuals) {
+  assert((CopyConstructor->isImplicit() &&
+          CopyConstructor->isCopyConstructor(TypeQuals) &&
+          !CopyConstructor->isUsed()) &&
+         "DefineImplicitCopyConstructor - call it for implicit copy ctor");
+
+  CXXRecordDecl *ClassDecl = CopyConstructor->getParent();
+  assert(ClassDecl && "DefineImplicitCopyConstructor - invalid constructor");
+
+  DeclContext *PreviousContext = CurContext;
+  CurContext = CopyConstructor;
+
+  // C++ [class.copy] p209
+  // Before the implicitly-declared copy constructor for a class is
+  // implicitly defined, all the implicitly-declared copy constructors
+  // for its base class and its non-static data members shall have been
+  // implicitly defined.
+  for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin();
+       Base != ClassDecl->bases_end(); ++Base) {
+    CXXRecordDecl *BaseClassDecl
+      = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
+    if (CXXConstructorDecl *BaseCopyCtor =
+        BaseClassDecl->getCopyConstructor(Context, TypeQuals)) {
+      CheckDirectMemberAccess(Base->getSourceRange().getBegin(),
+                              BaseCopyCtor,
+                              PDiag(diag::err_access_copy_base)
+                                << Base->getType());
+
+      MarkDeclarationReferenced(CurrentLocation, BaseCopyCtor);
+    }
+  }
+  for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
+                                  FieldEnd = ClassDecl->field_end();
+       Field != FieldEnd; ++Field) {
+    QualType FieldType = Context.getCanonicalType((*Field)->getType());
+    if (const ArrayType *Array = Context.getAsArrayType(FieldType))
+      FieldType = Array->getElementType();
+    if (const RecordType *FieldClassType = FieldType->getAs<RecordType>()) {
+      CXXRecordDecl *FieldClassDecl
+        = cast<CXXRecordDecl>(FieldClassType->getDecl());
+      if (CXXConstructorDecl *FieldCopyCtor =
+          FieldClassDecl->getCopyConstructor(Context, TypeQuals)) {
+        CheckDirectMemberAccess(Field->getLocation(),
+                                FieldCopyCtor,
+                                PDiag(diag::err_access_copy_field)
+                                  << Field->getDeclName() << Field->getType());
+
+        MarkDeclarationReferenced(CurrentLocation, FieldCopyCtor);
+      }
+    }
+  }
+  CopyConstructor->setUsed();
+
+  CurContext = PreviousContext;
+}
+
+Sema::OwningExprResult
+Sema::BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
+                            CXXConstructorDecl *Constructor,
+                            MultiExprArg ExprArgs,
+                            bool RequiresZeroInit,
+                            bool BaseInitialization) {
+  bool Elidable = false;
+
+  // C++0x [class.copy]p34:
+  //   When certain criteria are met, an implementation is allowed to
+  //   omit the copy/move construction of a class object, even if the
+  //   copy/move constructor and/or destructor for the object have
+  //   side effects. [...]
+  //     - when a temporary class object that has not been bound to a
+  //       reference (12.2) would be copied/moved to a class object
+  //       with the same cv-unqualified type, the copy/move operation
+  //       can be omitted by constructing the temporary object
+  //       directly into the target of the omitted copy/move
+  if (Constructor->isCopyConstructor() && ExprArgs.size() >= 1) {
+    Expr *SubExpr = ((Expr **)ExprArgs.get())[0];
+    Elidable = SubExpr->isTemporaryObject() &&
+      Context.hasSameUnqualifiedType(SubExpr->getType(), 
+                           Context.getTypeDeclType(Constructor->getParent()));
+  }
+
+  return BuildCXXConstructExpr(ConstructLoc, DeclInitType, Constructor,
+                               Elidable, move(ExprArgs), RequiresZeroInit,
+                               BaseInitialization);
+}
+
+/// BuildCXXConstructExpr - Creates a complete call to a constructor,
+/// including handling of its default argument expressions.
+Sema::OwningExprResult
+Sema::BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
+                            CXXConstructorDecl *Constructor, bool Elidable,
+                            MultiExprArg ExprArgs,
+                            bool RequiresZeroInit,
+                            bool BaseInitialization) {
+  unsigned NumExprs = ExprArgs.size();
+  Expr **Exprs = (Expr **)ExprArgs.release();
+
+  MarkDeclarationReferenced(ConstructLoc, Constructor);
+  return Owned(CXXConstructExpr::Create(Context, DeclInitType, ConstructLoc,
+                                        Constructor, Elidable, Exprs, NumExprs, 
+                                        RequiresZeroInit, BaseInitialization));
+}
+
+bool Sema::InitializeVarWithConstructor(VarDecl *VD,
+                                        CXXConstructorDecl *Constructor,
+                                        MultiExprArg Exprs) {
+  OwningExprResult TempResult =
+    BuildCXXConstructExpr(VD->getLocation(), VD->getType(), Constructor,
+                          move(Exprs));
+  if (TempResult.isInvalid())
+    return true;
+
+  Expr *Temp = TempResult.takeAs<Expr>();
+  MarkDeclarationReferenced(VD->getLocation(), Constructor);
+  Temp = MaybeCreateCXXExprWithTemporaries(Temp);
+  VD->setInit(Temp);
+
+  return false;
+}
+
+void Sema::FinalizeVarWithDestructor(VarDecl *VD, const RecordType *Record) {
+  CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(Record->getDecl());
+  if (!ClassDecl->isInvalidDecl() && !VD->isInvalidDecl() &&
+      !ClassDecl->hasTrivialDestructor()) {
+    CXXDestructorDecl *Destructor = ClassDecl->getDestructor(Context);
+    MarkDeclarationReferenced(VD->getLocation(), Destructor);
+    CheckDestructorAccess(VD->getLocation(), Destructor,
+                          PDiag(diag::err_access_dtor_var)
+                            << VD->getDeclName()
+                            << VD->getType());
+  }
+}
+
+/// AddCXXDirectInitializerToDecl - This action is called immediately after
+/// ActOnDeclarator, when a C++ direct initializer is present.
+/// e.g: "int x(1);"
+void Sema::AddCXXDirectInitializerToDecl(DeclPtrTy Dcl,
+                                         SourceLocation LParenLoc,
+                                         MultiExprArg Exprs,
+                                         SourceLocation *CommaLocs,
+                                         SourceLocation RParenLoc) {
+  assert(Exprs.size() != 0 && Exprs.get() && "missing expressions");
+  Decl *RealDecl = Dcl.getAs<Decl>();
+
+  // If there is no declaration, there was an error parsing it.  Just ignore
+  // the initializer.
+  if (RealDecl == 0)
+    return;
+
+  VarDecl *VDecl = dyn_cast<VarDecl>(RealDecl);
+  if (!VDecl) {
+    Diag(RealDecl->getLocation(), diag::err_illegal_initializer);
+    RealDecl->setInvalidDecl();
+    return;
+  }
+
+  // We will represent direct-initialization similarly to copy-initialization:
+  //    int x(1);  -as-> int x = 1;
+  //    ClassType x(a,b,c); -as-> ClassType x = ClassType(a,b,c);
+  //
+  // Clients that want to distinguish between the two forms, can check for
+  // direct initializer using VarDecl::hasCXXDirectInitializer().
+  // A major benefit is that clients that don't particularly care about which
+  // exactly form was it (like the CodeGen) can handle both cases without
+  // special case code.
+
+  // C++ 8.5p11:
+  // The form of initialization (using parentheses or '=') is generally
+  // insignificant, but does matter when the entity being initialized has a
+  // class type.
+  QualType DeclInitType = VDecl->getType();
+  if (const ArrayType *Array = Context.getAsArrayType(DeclInitType))
+    DeclInitType = Context.getBaseElementType(Array);
+
+  if (!VDecl->getType()->isDependentType() &&
+      RequireCompleteType(VDecl->getLocation(), VDecl->getType(),
+                          diag::err_typecheck_decl_incomplete_type)) {
+    VDecl->setInvalidDecl();
+    return;
+  }
+
+  // The variable can not have an abstract class type.
+  if (RequireNonAbstractType(VDecl->getLocation(), VDecl->getType(),
+                             diag::err_abstract_type_in_decl,
+                             AbstractVariableType))
+    VDecl->setInvalidDecl();
+
+  const VarDecl *Def;
+  if ((Def = VDecl->getDefinition()) && Def != VDecl) {
+    Diag(VDecl->getLocation(), diag::err_redefinition)
+    << VDecl->getDeclName();
+    Diag(Def->getLocation(), diag::note_previous_definition);
+    VDecl->setInvalidDecl();
+    return;
+  }
+
+  // If either the declaration has a dependent type or if any of the
+  // expressions is type-dependent, we represent the initialization
+  // via a ParenListExpr for later use during template instantiation.
+  if (VDecl->getType()->isDependentType() ||
+      Expr::hasAnyTypeDependentArguments((Expr **)Exprs.get(), Exprs.size())) {
+    // Let clients know that initialization was done with a direct initializer.
+    VDecl->setCXXDirectInitializer(true);
+
+    // Store the initialization expressions as a ParenListExpr.
+    unsigned NumExprs = Exprs.size();
+    VDecl->setInit(new (Context) ParenListExpr(Context, LParenLoc,
+                                               (Expr **)Exprs.release(),
+                                               NumExprs, RParenLoc));
+    return;
+  }
+  
+  // Capture the variable that is being initialized and the style of
+  // initialization.
+  InitializedEntity Entity = InitializedEntity::InitializeVariable(VDecl);
+  
+  // FIXME: Poor source location information.
+  InitializationKind Kind
+    = InitializationKind::CreateDirect(VDecl->getLocation(),
+                                       LParenLoc, RParenLoc);
+  
+  InitializationSequence InitSeq(*this, Entity, Kind, 
+                                 (Expr**)Exprs.get(), Exprs.size());
+  OwningExprResult Result = InitSeq.Perform(*this, Entity, Kind, move(Exprs));
+  if (Result.isInvalid()) {
+    VDecl->setInvalidDecl();
+    return;
+  }
+  
+  Result = MaybeCreateCXXExprWithTemporaries(move(Result));
+  VDecl->setInit(Result.takeAs<Expr>());
+  VDecl->setCXXDirectInitializer(true);
+
+  if (const RecordType *Record = VDecl->getType()->getAs<RecordType>())
+    FinalizeVarWithDestructor(VDecl, Record);
+}
+
+/// \brief Given a constructor and the set of arguments provided for the
+/// constructor, convert the arguments and add any required default arguments
+/// to form a proper call to this constructor.
+///
+/// \returns true if an error occurred, false otherwise.
+bool 
+Sema::CompleteConstructorCall(CXXConstructorDecl *Constructor,
+                              MultiExprArg ArgsPtr,
+                              SourceLocation Loc,                                    
+                     ASTOwningVector<&ActionBase::DeleteExpr> &ConvertedArgs) {
+  // FIXME: This duplicates a lot of code from Sema::ConvertArgumentsForCall.
+  unsigned NumArgs = ArgsPtr.size();
+  Expr **Args = (Expr **)ArgsPtr.get();
+
+  const FunctionProtoType *Proto 
+    = Constructor->getType()->getAs<FunctionProtoType>();
+  assert(Proto && "Constructor without a prototype?");
+  unsigned NumArgsInProto = Proto->getNumArgs();
+  
+  // If too few arguments are available, we'll fill in the rest with defaults.
+  if (NumArgs < NumArgsInProto)
+    ConvertedArgs.reserve(NumArgsInProto);
+  else
+    ConvertedArgs.reserve(NumArgs);
+
+  VariadicCallType CallType = 
+    Proto->isVariadic() ? VariadicConstructor : VariadicDoesNotApply;
+  llvm::SmallVector<Expr *, 8> AllArgs;
+  bool Invalid = GatherArgumentsForCall(Loc, Constructor,
+                                        Proto, 0, Args, NumArgs, AllArgs, 
+                                        CallType);
+  for (unsigned i =0, size = AllArgs.size(); i < size; i++)
+    ConvertedArgs.push_back(AllArgs[i]);
+  return Invalid;
+}
+
+static inline bool
+CheckOperatorNewDeleteDeclarationScope(Sema &SemaRef, 
+                                       const FunctionDecl *FnDecl) {
+  const DeclContext *DC = FnDecl->getDeclContext()->getLookupContext();
+  if (isa<NamespaceDecl>(DC)) {
+    return SemaRef.Diag(FnDecl->getLocation(), 
+                        diag::err_operator_new_delete_declared_in_namespace)
+      << FnDecl->getDeclName();
+  }
+  
+  if (isa<TranslationUnitDecl>(DC) && 
+      FnDecl->getStorageClass() == FunctionDecl::Static) {
+    return SemaRef.Diag(FnDecl->getLocation(),
+                        diag::err_operator_new_delete_declared_static)
+      << FnDecl->getDeclName();
+  }
+  
+  return false;
+}
+
+static inline bool
+CheckOperatorNewDeleteTypes(Sema &SemaRef, const FunctionDecl *FnDecl,
+                            CanQualType ExpectedResultType,
+                            CanQualType ExpectedFirstParamType,
+                            unsigned DependentParamTypeDiag,
+                            unsigned InvalidParamTypeDiag) {
+  QualType ResultType = 
+    FnDecl->getType()->getAs<FunctionType>()->getResultType();
+
+  // Check that the result type is not dependent.
+  if (ResultType->isDependentType())
+    return SemaRef.Diag(FnDecl->getLocation(),
+                        diag::err_operator_new_delete_dependent_result_type)
+    << FnDecl->getDeclName() << ExpectedResultType;
+
+  // Check that the result type is what we expect.
+  if (SemaRef.Context.getCanonicalType(ResultType) != ExpectedResultType)
+    return SemaRef.Diag(FnDecl->getLocation(),
+                        diag::err_operator_new_delete_invalid_result_type) 
+    << FnDecl->getDeclName() << ExpectedResultType;
+  
+  // A function template must have at least 2 parameters.
+  if (FnDecl->getDescribedFunctionTemplate() && FnDecl->getNumParams() < 2)
+    return SemaRef.Diag(FnDecl->getLocation(),
+                      diag::err_operator_new_delete_template_too_few_parameters)
+        << FnDecl->getDeclName();
+  
+  // The function decl must have at least 1 parameter.
+  if (FnDecl->getNumParams() == 0)
+    return SemaRef.Diag(FnDecl->getLocation(),
+                        diag::err_operator_new_delete_too_few_parameters)
+      << FnDecl->getDeclName();
+ 
+  // Check the the first parameter type is not dependent.
+  QualType FirstParamType = FnDecl->getParamDecl(0)->getType();
+  if (FirstParamType->isDependentType())
+    return SemaRef.Diag(FnDecl->getLocation(), DependentParamTypeDiag)
+      << FnDecl->getDeclName() << ExpectedFirstParamType;
+
+  // Check that the first parameter type is what we expect.
+  if (SemaRef.Context.getCanonicalType(FirstParamType).getUnqualifiedType() != 
+      ExpectedFirstParamType)
+    return SemaRef.Diag(FnDecl->getLocation(), InvalidParamTypeDiag)
+    << FnDecl->getDeclName() << ExpectedFirstParamType;
+  
+  return false;
+}
+
+static bool
+CheckOperatorNewDeclaration(Sema &SemaRef, const FunctionDecl *FnDecl) {
+  // C++ [basic.stc.dynamic.allocation]p1:
+  //   A program is ill-formed if an allocation function is declared in a
+  //   namespace scope other than global scope or declared static in global 
+  //   scope.
+  if (CheckOperatorNewDeleteDeclarationScope(SemaRef, FnDecl))
+    return true;
+
+  CanQualType SizeTy = 
+    SemaRef.Context.getCanonicalType(SemaRef.Context.getSizeType());
+
+  // C++ [basic.stc.dynamic.allocation]p1:
+  //  The return type shall be void*. The first parameter shall have type 
+  //  std::size_t.
+  if (CheckOperatorNewDeleteTypes(SemaRef, FnDecl, SemaRef.Context.VoidPtrTy, 
+                                  SizeTy,
+                                  diag::err_operator_new_dependent_param_type,
+                                  diag::err_operator_new_param_type))
+    return true;
+
+  // C++ [basic.stc.dynamic.allocation]p1:
+  //  The first parameter shall not have an associated default argument.
+  if (FnDecl->getParamDecl(0)->hasDefaultArg())
+    return SemaRef.Diag(FnDecl->getLocation(),
+                        diag::err_operator_new_default_arg)
+      << FnDecl->getDeclName() << FnDecl->getParamDecl(0)->getDefaultArgRange();
+
+  return false;
+}
+
+static bool
+CheckOperatorDeleteDeclaration(Sema &SemaRef, const FunctionDecl *FnDecl) {
+  // C++ [basic.stc.dynamic.deallocation]p1:
+  //   A program is ill-formed if deallocation functions are declared in a
+  //   namespace scope other than global scope or declared static in global 
+  //   scope.
+  if (CheckOperatorNewDeleteDeclarationScope(SemaRef, FnDecl))
+    return true;
+
+  // C++ [basic.stc.dynamic.deallocation]p2:
+  //   Each deallocation function shall return void and its first parameter 
+  //   shall be void*.
+  if (CheckOperatorNewDeleteTypes(SemaRef, FnDecl, SemaRef.Context.VoidTy, 
+                                  SemaRef.Context.VoidPtrTy,
+                                 diag::err_operator_delete_dependent_param_type,
+                                 diag::err_operator_delete_param_type))
+    return true;
+
+  QualType FirstParamType = FnDecl->getParamDecl(0)->getType();
+  if (FirstParamType->isDependentType())
+    return SemaRef.Diag(FnDecl->getLocation(),
+                        diag::err_operator_delete_dependent_param_type)
+    << FnDecl->getDeclName() << SemaRef.Context.VoidPtrTy;
+
+  if (SemaRef.Context.getCanonicalType(FirstParamType) != 
+      SemaRef.Context.VoidPtrTy)
+    return SemaRef.Diag(FnDecl->getLocation(),
+                        diag::err_operator_delete_param_type)
+      << FnDecl->getDeclName() << SemaRef.Context.VoidPtrTy;
+  
+  return false;
+}
+
+/// CheckOverloadedOperatorDeclaration - Check whether the declaration
+/// of this overloaded operator is well-formed. If so, returns false;
+/// otherwise, emits appropriate diagnostics and returns true.
+bool Sema::CheckOverloadedOperatorDeclaration(FunctionDecl *FnDecl) {
+  assert(FnDecl && FnDecl->isOverloadedOperator() &&
+         "Expected an overloaded operator declaration");
+
+  OverloadedOperatorKind Op = FnDecl->getOverloadedOperator();
+
+  // C++ [over.oper]p5:
+  //   The allocation and deallocation functions, operator new,
+  //   operator new[], operator delete and operator delete[], are
+  //   described completely in 3.7.3. The attributes and restrictions
+  //   found in the rest of this subclause do not apply to them unless
+  //   explicitly stated in 3.7.3.
+  if (Op == OO_Delete || Op == OO_Array_Delete)
+    return CheckOperatorDeleteDeclaration(*this, FnDecl);
+  
+  if (Op == OO_New || Op == OO_Array_New)
+    return CheckOperatorNewDeclaration(*this, FnDecl);
+
+  // C++ [over.oper]p6:
+  //   An operator function shall either be a non-static member
+  //   function or be a non-member function and have at least one
+  //   parameter whose type is a class, a reference to a class, an
+  //   enumeration, or a reference to an enumeration.
+  if (CXXMethodDecl *MethodDecl = dyn_cast<CXXMethodDecl>(FnDecl)) {
+    if (MethodDecl->isStatic())
+      return Diag(FnDecl->getLocation(),
+                  diag::err_operator_overload_static) << FnDecl->getDeclName();
+  } else {
+    bool ClassOrEnumParam = false;
+    for (FunctionDecl::param_iterator Param = FnDecl->param_begin(),
+                                   ParamEnd = FnDecl->param_end();
+         Param != ParamEnd; ++Param) {
+      QualType ParamType = (*Param)->getType().getNonReferenceType();
+      if (ParamType->isDependentType() || ParamType->isRecordType() ||
+          ParamType->isEnumeralType()) {
+        ClassOrEnumParam = true;
+        break;
+      }
+    }
+
+    if (!ClassOrEnumParam)
+      return Diag(FnDecl->getLocation(),
+                  diag::err_operator_overload_needs_class_or_enum)
+        << FnDecl->getDeclName();
+  }
+
+  // C++ [over.oper]p8:
+  //   An operator function cannot have default arguments (8.3.6),
+  //   except where explicitly stated below.
+  //
+  // Only the function-call operator allows default arguments
+  // (C++ [over.call]p1).
+  if (Op != OO_Call) {
+    for (FunctionDecl::param_iterator Param = FnDecl->param_begin();
+         Param != FnDecl->param_end(); ++Param) {
+      if ((*Param)->hasDefaultArg())
+        return Diag((*Param)->getLocation(),
+                    diag::err_operator_overload_default_arg)
+          << FnDecl->getDeclName() << (*Param)->getDefaultArgRange();
+    }
+  }
+
+  static const bool OperatorUses[NUM_OVERLOADED_OPERATORS][3] = {
+    { false, false, false }
+#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
+    , { Unary, Binary, MemberOnly }
+#include "clang/Basic/OperatorKinds.def"
+  };
+
+  bool CanBeUnaryOperator = OperatorUses[Op][0];
+  bool CanBeBinaryOperator = OperatorUses[Op][1];
+  bool MustBeMemberOperator = OperatorUses[Op][2];
+
+  // C++ [over.oper]p8:
+  //   [...] Operator functions cannot have more or fewer parameters
+  //   than the number required for the corresponding operator, as
+  //   described in the rest of this subclause.
+  unsigned NumParams = FnDecl->getNumParams()
+                     + (isa<CXXMethodDecl>(FnDecl)? 1 : 0);
+  if (Op != OO_Call &&
+      ((NumParams == 1 && !CanBeUnaryOperator) ||
+       (NumParams == 2 && !CanBeBinaryOperator) ||
+       (NumParams < 1) || (NumParams > 2))) {
+    // We have the wrong number of parameters.
+    unsigned ErrorKind;
+    if (CanBeUnaryOperator && CanBeBinaryOperator) {
+      ErrorKind = 2;  // 2 -> unary or binary.
+    } else if (CanBeUnaryOperator) {
+      ErrorKind = 0;  // 0 -> unary
+    } else {
+      assert(CanBeBinaryOperator &&
+             "All non-call overloaded operators are unary or binary!");
+      ErrorKind = 1;  // 1 -> binary
+    }
+
+    return Diag(FnDecl->getLocation(), diag::err_operator_overload_must_be)
+      << FnDecl->getDeclName() << NumParams << ErrorKind;
+  }
+
+  // Overloaded operators other than operator() cannot be variadic.
+  if (Op != OO_Call &&
+      FnDecl->getType()->getAs<FunctionProtoType>()->isVariadic()) {
+    return Diag(FnDecl->getLocation(), diag::err_operator_overload_variadic)
+      << FnDecl->getDeclName();
+  }
+
+  // Some operators must be non-static member functions.
+  if (MustBeMemberOperator && !isa<CXXMethodDecl>(FnDecl)) {
+    return Diag(FnDecl->getLocation(),
+                diag::err_operator_overload_must_be_member)
+      << FnDecl->getDeclName();
+  }
+
+  // C++ [over.inc]p1:
+  //   The user-defined function called operator++ implements the
+  //   prefix and postfix ++ operator. If this function is a member
+  //   function with no parameters, or a non-member function with one
+  //   parameter of class or enumeration type, it defines the prefix
+  //   increment operator ++ for objects of that type. If the function
+  //   is a member function with one parameter (which shall be of type
+  //   int) or a non-member function with two parameters (the second
+  //   of which shall be of type int), it defines the postfix
+  //   increment operator ++ for objects of that type.
+  if ((Op == OO_PlusPlus || Op == OO_MinusMinus) && NumParams == 2) {
+    ParmVarDecl *LastParam = FnDecl->getParamDecl(FnDecl->getNumParams() - 1);
+    bool ParamIsInt = false;
+    if (const BuiltinType *BT = LastParam->getType()->getAs<BuiltinType>())
+      ParamIsInt = BT->getKind() == BuiltinType::Int;
+
+    if (!ParamIsInt)
+      return Diag(LastParam->getLocation(),
+                  diag::err_operator_overload_post_incdec_must_be_int)
+        << LastParam->getType() << (Op == OO_MinusMinus);
+  }
+
+  // Notify the class if it got an assignment operator.
+  if (Op == OO_Equal) {
+    // Would have returned earlier otherwise.
+    assert(isa<CXXMethodDecl>(FnDecl) &&
+      "Overloaded = not member, but not filtered.");
+    CXXMethodDecl *Method = cast<CXXMethodDecl>(FnDecl);
+    Method->getParent()->addedAssignmentOperator(Context, Method);
+  }
+
+  return false;
+}
+
+/// CheckLiteralOperatorDeclaration - Check whether the declaration
+/// of this literal operator function is well-formed. If so, returns
+/// false; otherwise, emits appropriate diagnostics and returns true.
+bool Sema::CheckLiteralOperatorDeclaration(FunctionDecl *FnDecl) {
+  DeclContext *DC = FnDecl->getDeclContext();
+  Decl::Kind Kind = DC->getDeclKind();
+  if (Kind != Decl::TranslationUnit && Kind != Decl::Namespace &&
+      Kind != Decl::LinkageSpec) {
+    Diag(FnDecl->getLocation(), diag::err_literal_operator_outside_namespace)
+      << FnDecl->getDeclName();
+    return true;
+  }
+
+  bool Valid = false;
+
+  // template <char...> type operator "" name() is the only valid template
+  // signature, and the only valid signature with no parameters.
+  if (FnDecl->param_size() == 0) {
+    if (FunctionTemplateDecl *TpDecl = FnDecl->getDescribedFunctionTemplate()) {
+      // Must have only one template parameter
+      TemplateParameterList *Params = TpDecl->getTemplateParameters();
+      if (Params->size() == 1) {
+        NonTypeTemplateParmDecl *PmDecl =
+          cast<NonTypeTemplateParmDecl>(Params->getParam(0));
+
+        // The template parameter must be a char parameter pack.
+        // FIXME: This test will always fail because non-type parameter packs
+        //   have not been implemented.
+        if (PmDecl && PmDecl->isTemplateParameterPack() &&
+            Context.hasSameType(PmDecl->getType(), Context.CharTy))
+          Valid = true;
+      }
+    }
+  } else {
+    // Check the first parameter
+    FunctionDecl::param_iterator Param = FnDecl->param_begin();
+
+    QualType T = (*Param)->getType();
+
+    // unsigned long long int, long double, and any character type are allowed
+    // as the only parameters.
+    if (Context.hasSameType(T, Context.UnsignedLongLongTy) ||
+        Context.hasSameType(T, Context.LongDoubleTy) ||
+        Context.hasSameType(T, Context.CharTy) ||
+        Context.hasSameType(T, Context.WCharTy) ||
+        Context.hasSameType(T, Context.Char16Ty) ||
+        Context.hasSameType(T, Context.Char32Ty)) {
+      if (++Param == FnDecl->param_end())
+        Valid = true;
+      goto FinishedParams;
+    }
+
+    // Otherwise it must be a pointer to const; let's strip those qualifiers.
+    const PointerType *PT = T->getAs<PointerType>();
+    if (!PT)
+      goto FinishedParams;
+    T = PT->getPointeeType();
+    if (!T.isConstQualified())
+      goto FinishedParams;
+    T = T.getUnqualifiedType();
+
+    // Move on to the second parameter;
+    ++Param;
+
+    // If there is no second parameter, the first must be a const char *
+    if (Param == FnDecl->param_end()) {
+      if (Context.hasSameType(T, Context.CharTy))
+        Valid = true;
+      goto FinishedParams;
+    }
+
+    // const char *, const wchar_t*, const char16_t*, and const char32_t*
+    // are allowed as the first parameter to a two-parameter function
+    if (!(Context.hasSameType(T, Context.CharTy) ||
+          Context.hasSameType(T, Context.WCharTy) ||
+          Context.hasSameType(T, Context.Char16Ty) ||
+          Context.hasSameType(T, Context.Char32Ty)))
+      goto FinishedParams;
+
+    // The second and final parameter must be an std::size_t
+    T = (*Param)->getType().getUnqualifiedType();
+    if (Context.hasSameType(T, Context.getSizeType()) &&
+        ++Param == FnDecl->param_end())
+      Valid = true;
+  }
+
+  // FIXME: This diagnostic is absolutely terrible.
+FinishedParams:
+  if (!Valid) {
+    Diag(FnDecl->getLocation(), diag::err_literal_operator_params)
+      << FnDecl->getDeclName();
+    return true;
+  }
+
+  return false;
+}
+
+/// ActOnStartLinkageSpecification - Parsed the beginning of a C++
+/// linkage specification, including the language and (if present)
+/// the '{'. ExternLoc is the location of the 'extern', LangLoc is
+/// the location of the language string literal, which is provided
+/// by Lang/StrSize. LBraceLoc, if valid, provides the location of
+/// the '{' brace. Otherwise, this linkage specification does not
+/// have any braces.
+Sema::DeclPtrTy Sema::ActOnStartLinkageSpecification(Scope *S,
+                                                     SourceLocation ExternLoc,
+                                                     SourceLocation LangLoc,
+                                                     const char *Lang,
+                                                     unsigned StrSize,
+                                                     SourceLocation LBraceLoc) {
+  LinkageSpecDecl::LanguageIDs Language;
+  if (strncmp(Lang, "\"C\"", StrSize) == 0)
+    Language = LinkageSpecDecl::lang_c;
+  else if (strncmp(Lang, "\"C++\"", StrSize) == 0)
+    Language = LinkageSpecDecl::lang_cxx;
+  else {
+    Diag(LangLoc, diag::err_bad_language);
+    return DeclPtrTy();
+  }
+
+  // FIXME: Add all the various semantics of linkage specifications
+
+  LinkageSpecDecl *D = LinkageSpecDecl::Create(Context, CurContext,
+                                               LangLoc, Language,
+                                               LBraceLoc.isValid());
+  CurContext->addDecl(D);
+  PushDeclContext(S, D);
+  return DeclPtrTy::make(D);
+}
+
+/// ActOnFinishLinkageSpecification - Completely the definition of
+/// the C++ linkage specification LinkageSpec. If RBraceLoc is
+/// valid, it's the position of the closing '}' brace in a linkage
+/// specification that uses braces.
+Sema::DeclPtrTy Sema::ActOnFinishLinkageSpecification(Scope *S,
+                                                      DeclPtrTy LinkageSpec,
+                                                      SourceLocation RBraceLoc) {
+  if (LinkageSpec)
+    PopDeclContext();
+  return LinkageSpec;
+}
+
+/// \brief Perform semantic analysis for the variable declaration that
+/// occurs within a C++ catch clause, returning the newly-created
+/// variable.
+VarDecl *Sema::BuildExceptionDeclaration(Scope *S, QualType ExDeclType,
+                                         TypeSourceInfo *TInfo,
+                                         IdentifierInfo *Name,
+                                         SourceLocation Loc,
+                                         SourceRange Range) {
+  bool Invalid = false;
+
+  // Arrays and functions decay.
+  if (ExDeclType->isArrayType())
+    ExDeclType = Context.getArrayDecayedType(ExDeclType);
+  else if (ExDeclType->isFunctionType())
+    ExDeclType = Context.getPointerType(ExDeclType);
+
+  // C++ 15.3p1: The exception-declaration shall not denote an incomplete type.
+  // The exception-declaration shall not denote a pointer or reference to an
+  // incomplete type, other than [cv] void*.
+  // N2844 forbids rvalue references.
+  if (!ExDeclType->isDependentType() && ExDeclType->isRValueReferenceType()) {
+    Diag(Loc, diag::err_catch_rvalue_ref) << Range;
+    Invalid = true;
+  }
+
+  // GCC allows catching pointers and references to incomplete types
+  // as an extension; so do we, but we warn by default.
+
+  QualType BaseType = ExDeclType;
+  int Mode = 0; // 0 for direct type, 1 for pointer, 2 for reference
+  unsigned DK = diag::err_catch_incomplete;
+  bool IncompleteCatchIsInvalid = true;
+  if (const PointerType *Ptr = BaseType->getAs<PointerType>()) {
+    BaseType = Ptr->getPointeeType();
+    Mode = 1;
+    DK = diag::ext_catch_incomplete_ptr;
+    IncompleteCatchIsInvalid = false;
+  } else if (const ReferenceType *Ref = BaseType->getAs<ReferenceType>()) {
+    // For the purpose of error recovery, we treat rvalue refs like lvalue refs.
+    BaseType = Ref->getPointeeType();
+    Mode = 2;
+    DK = diag::ext_catch_incomplete_ref;
+    IncompleteCatchIsInvalid = false;
+  }
+  if (!Invalid && (Mode == 0 || !BaseType->isVoidType()) &&
+      !BaseType->isDependentType() && RequireCompleteType(Loc, BaseType, DK) &&
+      IncompleteCatchIsInvalid)
+    Invalid = true;
+
+  if (!Invalid && !ExDeclType->isDependentType() &&
+      RequireNonAbstractType(Loc, ExDeclType,
+                             diag::err_abstract_type_in_decl,
+                             AbstractVariableType))
+    Invalid = true;
+
+  VarDecl *ExDecl = VarDecl::Create(Context, CurContext, Loc,
+                                    Name, ExDeclType, TInfo, VarDecl::None,
+                                    VarDecl::None);
+
+  if (!Invalid) {
+    if (const RecordType *RecordTy = ExDeclType->getAs<RecordType>()) {
+      // C++ [except.handle]p16:
+      //   The object declared in an exception-declaration or, if the 
+      //   exception-declaration does not specify a name, a temporary (12.2) is 
+      //   copy-initialized (8.5) from the exception object. [...]
+      //   The object is destroyed when the handler exits, after the destruction
+      //   of any automatic objects initialized within the handler.
+      //
+      // We just pretend to initialize the object with itself, then make sure 
+      // it can be destroyed later.
+      InitializedEntity Entity = InitializedEntity::InitializeVariable(ExDecl);
+      Expr *ExDeclRef = DeclRefExpr::Create(Context, 0, SourceRange(), ExDecl, 
+                                            Loc, ExDeclType, 0);
+      InitializationKind Kind = InitializationKind::CreateCopy(Loc, 
+                                                               SourceLocation());
+      InitializationSequence InitSeq(*this, Entity, Kind, &ExDeclRef, 1);
+      OwningExprResult Result = InitSeq.Perform(*this, Entity, Kind, 
+                                    MultiExprArg(*this, (void**)&ExDeclRef, 1));
+      if (Result.isInvalid())
+        Invalid = true;
+      else 
+        FinalizeVarWithDestructor(ExDecl, RecordTy);
+    }
+  }
+  
+  if (Invalid)
+    ExDecl->setInvalidDecl();
+
+  return ExDecl;
+}
+
+/// ActOnExceptionDeclarator - Parsed the exception-declarator in a C++ catch
+/// handler.
+Sema::DeclPtrTy Sema::ActOnExceptionDeclarator(Scope *S, Declarator &D) {
+  TypeSourceInfo *TInfo = 0;
+  QualType ExDeclType = GetTypeForDeclarator(D, S, &TInfo);
+
+  bool Invalid = D.isInvalidType();
+  IdentifierInfo *II = D.getIdentifier();
+  if (NamedDecl *PrevDecl = LookupSingleName(S, II, D.getIdentifierLoc(),
+                                             LookupOrdinaryName,
+                                             ForRedeclaration)) {
+    // The scope should be freshly made just for us. There is just no way
+    // it contains any previous declaration.
+    assert(!S->isDeclScope(DeclPtrTy::make(PrevDecl)));
+    if (PrevDecl->isTemplateParameter()) {
+      // Maybe we will complain about the shadowed template parameter.
+      DiagnoseTemplateParameterShadow(D.getIdentifierLoc(), PrevDecl);
+    }
+  }
+
+  if (D.getCXXScopeSpec().isSet() && !Invalid) {
+    Diag(D.getIdentifierLoc(), diag::err_qualified_catch_declarator)
+      << D.getCXXScopeSpec().getRange();
+    Invalid = true;
+  }
+
+  VarDecl *ExDecl = BuildExceptionDeclaration(S, ExDeclType, TInfo,
+                                              D.getIdentifier(),
+                                              D.getIdentifierLoc(),
+                                            D.getDeclSpec().getSourceRange());
+
+  if (Invalid)
+    ExDecl->setInvalidDecl();
+
+  // Add the exception declaration into this scope.
+  if (II)
+    PushOnScopeChains(ExDecl, S);
+  else
+    CurContext->addDecl(ExDecl);
+
+  ProcessDeclAttributes(S, ExDecl, D);
+  return DeclPtrTy::make(ExDecl);
+}
+
+Sema::DeclPtrTy Sema::ActOnStaticAssertDeclaration(SourceLocation AssertLoc,
+                                                   ExprArg assertexpr,
+                                                   ExprArg assertmessageexpr) {
+  Expr *AssertExpr = (Expr *)assertexpr.get();
+  StringLiteral *AssertMessage =
+    cast<StringLiteral>((Expr *)assertmessageexpr.get());
+
+  if (!AssertExpr->isTypeDependent() && !AssertExpr->isValueDependent()) {
+    llvm::APSInt Value(32);
+    if (!AssertExpr->isIntegerConstantExpr(Value, Context)) {
+      Diag(AssertLoc, diag::err_static_assert_expression_is_not_constant) <<
+        AssertExpr->getSourceRange();
+      return DeclPtrTy();
+    }
+
+    if (Value == 0) {
+      Diag(AssertLoc, diag::err_static_assert_failed)
+        << AssertMessage->getString() << AssertExpr->getSourceRange();
+    }
+  }
+
+  assertexpr.release();
+  assertmessageexpr.release();
+  Decl *Decl = StaticAssertDecl::Create(Context, CurContext, AssertLoc,
+                                        AssertExpr, AssertMessage);
+
+  CurContext->addDecl(Decl);
+  return DeclPtrTy::make(Decl);
+}
+
+/// \brief Perform semantic analysis of the given friend type declaration.
+///
+/// \returns A friend declaration that.
+FriendDecl *Sema::CheckFriendTypeDecl(SourceLocation FriendLoc, 
+                                      TypeSourceInfo *TSInfo) {
+  assert(TSInfo && "NULL TypeSourceInfo for friend type declaration");
+  
+  QualType T = TSInfo->getType();
+  SourceRange TypeRange = TSInfo->getTypeLoc().getSourceRange();
+  
+  if (!getLangOptions().CPlusPlus0x) {
+    // C++03 [class.friend]p2:
+    //   An elaborated-type-specifier shall be used in a friend declaration
+    //   for a class.*
+    //
+    //   * The class-key of the elaborated-type-specifier is required.
+    if (!ActiveTemplateInstantiations.empty()) {
+      // Do not complain about the form of friend template types during
+      // template instantiation; we will already have complained when the
+      // template was declared.
+    } else if (!T->isElaboratedTypeSpecifier()) {
+      // If we evaluated the type to a record type, suggest putting
+      // a tag in front.
+      if (const RecordType *RT = T->getAs<RecordType>()) {
+        RecordDecl *RD = RT->getDecl();
+        
+        std::string InsertionText = std::string(" ") + RD->getKindName();
+        
+        Diag(TypeRange.getBegin(), diag::ext_unelaborated_friend_type)
+          << (unsigned) RD->getTagKind()
+          << T
+          << FixItHint::CreateInsertion(PP.getLocForEndOfToken(FriendLoc),
+                                        InsertionText);
+      } else {
+        Diag(FriendLoc, diag::ext_nonclass_type_friend)
+          << T
+          << SourceRange(FriendLoc, TypeRange.getEnd());
+      }
+    } else if (T->getAs<EnumType>()) {
+      Diag(FriendLoc, diag::ext_enum_friend)
+        << T
+        << SourceRange(FriendLoc, TypeRange.getEnd());
+    }
+  }
+  
+  // C++0x [class.friend]p3:
+  //   If the type specifier in a friend declaration designates a (possibly
+  //   cv-qualified) class type, that class is declared as a friend; otherwise, 
+  //   the friend declaration is ignored.
+  
+  // FIXME: C++0x has some syntactic restrictions on friend type declarations
+  // in [class.friend]p3 that we do not implement.
+  
+  return FriendDecl::Create(Context, CurContext, FriendLoc, TSInfo, FriendLoc);
+}
+
+/// Handle a friend type declaration.  This works in tandem with
+/// ActOnTag.
+///
+/// Notes on friend class templates:
+///
+/// We generally treat friend class declarations as if they were
+/// declaring a class.  So, for example, the elaborated type specifier
+/// in a friend declaration is required to obey the restrictions of a
+/// class-head (i.e. no typedefs in the scope chain), template
+/// parameters are required to match up with simple template-ids, &c.
+/// However, unlike when declaring a template specialization, it's
+/// okay to refer to a template specialization without an empty
+/// template parameter declaration, e.g.
+///   friend class A<T>::B<unsigned>;
+/// We permit this as a special case; if there are any template
+/// parameters present at all, require proper matching, i.e.
+///   template <> template <class T> friend class A<int>::B;
+Sema::DeclPtrTy Sema::ActOnFriendTypeDecl(Scope *S, const DeclSpec &DS,
+                                          MultiTemplateParamsArg TempParams) {
+  SourceLocation Loc = DS.getSourceRange().getBegin();
+
+  assert(DS.isFriendSpecified());
+  assert(DS.getStorageClassSpec() == DeclSpec::SCS_unspecified);
+
+  // Try to convert the decl specifier to a type.  This works for
+  // friend templates because ActOnTag never produces a ClassTemplateDecl
+  // for a TUK_Friend.
+  Declarator TheDeclarator(DS, Declarator::MemberContext);
+  TypeSourceInfo *TSI;
+  QualType T = GetTypeForDeclarator(TheDeclarator, S, &TSI);
+  if (TheDeclarator.isInvalidType())
+    return DeclPtrTy();
+
+  if (!TSI)
+    TSI = Context.getTrivialTypeSourceInfo(T, DS.getSourceRange().getBegin());
+  
+  // This is definitely an error in C++98.  It's probably meant to
+  // be forbidden in C++0x, too, but the specification is just
+  // poorly written.
+  //
+  // The problem is with declarations like the following:
+  //   template <T> friend A<T>::foo;
+  // where deciding whether a class C is a friend or not now hinges
+  // on whether there exists an instantiation of A that causes
+  // 'foo' to equal C.  There are restrictions on class-heads
+  // (which we declare (by fiat) elaborated friend declarations to
+  // be) that makes this tractable.
+  //
+  // FIXME: handle "template <> friend class A<T>;", which
+  // is possibly well-formed?  Who even knows?
+  if (TempParams.size() && !T->isElaboratedTypeSpecifier()) {
+    Diag(Loc, diag::err_tagless_friend_type_template)
+      << DS.getSourceRange();
+    return DeclPtrTy();
+  }
+  
+  // C++98 [class.friend]p1: A friend of a class is a function
+  //   or class that is not a member of the class . . .
+  // This is fixed in DR77, which just barely didn't make the C++03
+  // deadline.  It's also a very silly restriction that seriously
+  // affects inner classes and which nobody else seems to implement;
+  // thus we never diagnose it, not even in -pedantic.
+  //
+  // But note that we could warn about it: it's always useless to
+  // friend one of your own members (it's not, however, worthless to
+  // friend a member of an arbitrary specialization of your template).
+
+  Decl *D;
+  if (unsigned NumTempParamLists = TempParams.size())
+    D = FriendTemplateDecl::Create(Context, CurContext, Loc,
+                                   NumTempParamLists,
+                                 (TemplateParameterList**) TempParams.release(),
+                                   TSI,
+                                   DS.getFriendSpecLoc());
+  else
+    D = CheckFriendTypeDecl(DS.getFriendSpecLoc(), TSI);
+  
+  if (!D)
+    return DeclPtrTy();
+  
+  D->setAccess(AS_public);
+  CurContext->addDecl(D);
+
+  return DeclPtrTy::make(D);
+}
+
+Sema::DeclPtrTy
+Sema::ActOnFriendFunctionDecl(Scope *S,
+                              Declarator &D,
+                              bool IsDefinition,
+                              MultiTemplateParamsArg TemplateParams) {
+  const DeclSpec &DS = D.getDeclSpec();
+
+  assert(DS.isFriendSpecified());
+  assert(DS.getStorageClassSpec() == DeclSpec::SCS_unspecified);
+
+  SourceLocation Loc = D.getIdentifierLoc();
+  TypeSourceInfo *TInfo = 0;
+  QualType T = GetTypeForDeclarator(D, S, &TInfo);
+
+  // C++ [class.friend]p1
+  //   A friend of a class is a function or class....
+  // Note that this sees through typedefs, which is intended.
+  // It *doesn't* see through dependent types, which is correct
+  // according to [temp.arg.type]p3:
+  //   If a declaration acquires a function type through a
+  //   type dependent on a template-parameter and this causes
+  //   a declaration that does not use the syntactic form of a
+  //   function declarator to have a function type, the program
+  //   is ill-formed.
+  if (!T->isFunctionType()) {
+    Diag(Loc, diag::err_unexpected_friend);
+
+    // It might be worthwhile to try to recover by creating an
+    // appropriate declaration.
+    return DeclPtrTy();
+  }
+
+  // C++ [namespace.memdef]p3
+  //  - If a friend declaration in a non-local class first declares a
+  //    class or function, the friend class or function is a member
+  //    of the innermost enclosing namespace.
+  //  - The name of the friend is not found by simple name lookup
+  //    until a matching declaration is provided in that namespace
+  //    scope (either before or after the class declaration granting
+  //    friendship).
+  //  - If a friend function is called, its name may be found by the
+  //    name lookup that considers functions from namespaces and
+  //    classes associated with the types of the function arguments.
+  //  - When looking for a prior declaration of a class or a function
+  //    declared as a friend, scopes outside the innermost enclosing
+  //    namespace scope are not considered.
+
+  CXXScopeSpec &ScopeQual = D.getCXXScopeSpec();
+  DeclarationName Name = GetNameForDeclarator(D);
+  assert(Name);
+
+  // The context we found the declaration in, or in which we should
+  // create the declaration.
+  DeclContext *DC;
+
+  // FIXME: handle local classes
+
+  // Recover from invalid scope qualifiers as if they just weren't there.
+  LookupResult Previous(*this, Name, D.getIdentifierLoc(), LookupOrdinaryName,
+                        ForRedeclaration);
+  if (!ScopeQual.isInvalid() && ScopeQual.isSet()) {
+    // FIXME: RequireCompleteDeclContext
+    DC = computeDeclContext(ScopeQual);
+
+    // FIXME: handle dependent contexts
+    if (!DC) return DeclPtrTy();
+
+    LookupQualifiedName(Previous, DC);
+
+    // If searching in that context implicitly found a declaration in
+    // a different context, treat it like it wasn't found at all.
+    // TODO: better diagnostics for this case.  Suggesting the right
+    // qualified scope would be nice...
+    // FIXME: getRepresentativeDecl() is not right here at all
+    if (Previous.empty() ||
+        !Previous.getRepresentativeDecl()->getDeclContext()->Equals(DC)) {
+      D.setInvalidType();
+      Diag(Loc, diag::err_qualified_friend_not_found) << Name << T;
+      return DeclPtrTy();
+    }
+
+    // C++ [class.friend]p1: A friend of a class is a function or
+    //   class that is not a member of the class . . .
+    if (DC->Equals(CurContext))
+      Diag(DS.getFriendSpecLoc(), diag::err_friend_is_member);
+
+  // Otherwise walk out to the nearest namespace scope looking for matches.
+  } else {
+    // TODO: handle local class contexts.
+
+    DC = CurContext;
+    while (true) {
+      // Skip class contexts.  If someone can cite chapter and verse
+      // for this behavior, that would be nice --- it's what GCC and
+      // EDG do, and it seems like a reasonable intent, but the spec
+      // really only says that checks for unqualified existing
+      // declarations should stop at the nearest enclosing namespace,
+      // not that they should only consider the nearest enclosing
+      // namespace.
+      while (DC->isRecord()) 
+        DC = DC->getParent();
+
+      LookupQualifiedName(Previous, DC);
+
+      // TODO: decide what we think about using declarations.
+      if (!Previous.empty())
+        break;
+      
+      if (DC->isFileContext()) break;
+      DC = DC->getParent();
+    }
+
+    // C++ [class.friend]p1: A friend of a class is a function or
+    //   class that is not a member of the class . . .
+    // C++0x changes this for both friend types and functions.
+    // Most C++ 98 compilers do seem to give an error here, so
+    // we do, too.
+    if (!Previous.empty() && DC->Equals(CurContext)
+        && !getLangOptions().CPlusPlus0x)
+      Diag(DS.getFriendSpecLoc(), diag::err_friend_is_member);
+  }
+
+  if (DC->isFileContext()) {
+    // This implies that it has to be an operator or function.
+    if (D.getName().getKind() == UnqualifiedId::IK_ConstructorName ||
+        D.getName().getKind() == UnqualifiedId::IK_DestructorName ||
+        D.getName().getKind() == UnqualifiedId::IK_ConversionFunctionId) {
+      Diag(Loc, diag::err_introducing_special_friend) <<
+        (D.getName().getKind() == UnqualifiedId::IK_ConstructorName ? 0 :
+         D.getName().getKind() == UnqualifiedId::IK_DestructorName ? 1 : 2);
+      return DeclPtrTy();
+    }
+  }
+
+  bool Redeclaration = false;
+  NamedDecl *ND = ActOnFunctionDeclarator(S, D, DC, T, TInfo, Previous,
+                                          move(TemplateParams),
+                                          IsDefinition,
+                                          Redeclaration);
+  if (!ND) return DeclPtrTy();
+
+  assert(ND->getDeclContext() == DC);
+  assert(ND->getLexicalDeclContext() == CurContext);
+
+  // Add the function declaration to the appropriate lookup tables,
+  // adjusting the redeclarations list as necessary.  We don't
+  // want to do this yet if the friending class is dependent.
+  //
+  // Also update the scope-based lookup if the target context's
+  // lookup context is in lexical scope.
+  if (!CurContext->isDependentContext()) {
+    DC = DC->getLookupContext();
+    DC->makeDeclVisibleInContext(ND, /* Recoverable=*/ false);
+    if (Scope *EnclosingScope = getScopeForDeclContext(S, DC))
+      PushOnScopeChains(ND, EnclosingScope, /*AddToContext=*/ false);
+  }
+
+  FriendDecl *FrD = FriendDecl::Create(Context, CurContext,
+                                       D.getIdentifierLoc(), ND,
+                                       DS.getFriendSpecLoc());
+  FrD->setAccess(AS_public);
+  CurContext->addDecl(FrD);
+
+  return DeclPtrTy::make(ND);
+}
+
+void Sema::SetDeclDeleted(DeclPtrTy dcl, SourceLocation DelLoc) {
+  AdjustDeclIfTemplate(dcl);
+
+  Decl *Dcl = dcl.getAs<Decl>();
+  FunctionDecl *Fn = dyn_cast<FunctionDecl>(Dcl);
+  if (!Fn) {
+    Diag(DelLoc, diag::err_deleted_non_function);
+    return;
+  }
+  if (const FunctionDecl *Prev = Fn->getPreviousDeclaration()) {
+    Diag(DelLoc, diag::err_deleted_decl_not_first);
+    Diag(Prev->getLocation(), diag::note_previous_declaration);
+    // If the declaration wasn't the first, we delete the function anyway for
+    // recovery.
+  }
+  Fn->setDeleted();
+}
+
+static void SearchForReturnInStmt(Sema &Self, Stmt *S) {
+  for (Stmt::child_iterator CI = S->child_begin(), E = S->child_end(); CI != E;
+       ++CI) {
+    Stmt *SubStmt = *CI;
+    if (!SubStmt)
+      continue;
+    if (isa<ReturnStmt>(SubStmt))
+      Self.Diag(SubStmt->getSourceRange().getBegin(),
+           diag::err_return_in_constructor_handler);
+    if (!isa<Expr>(SubStmt))
+      SearchForReturnInStmt(Self, SubStmt);
+  }
+}
+
+void Sema::DiagnoseReturnInConstructorExceptionHandler(CXXTryStmt *TryBlock) {
+  for (unsigned I = 0, E = TryBlock->getNumHandlers(); I != E; ++I) {
+    CXXCatchStmt *Handler = TryBlock->getHandler(I);
+    SearchForReturnInStmt(*this, Handler);
+  }
+}
+
+bool Sema::CheckOverridingFunctionReturnType(const CXXMethodDecl *New,
+                                             const CXXMethodDecl *Old) {
+  QualType NewTy = New->getType()->getAs<FunctionType>()->getResultType();
+  QualType OldTy = Old->getType()->getAs<FunctionType>()->getResultType();
+
+  if (Context.hasSameType(NewTy, OldTy) ||
+      NewTy->isDependentType() || OldTy->isDependentType())
+    return false;
+
+  // Check if the return types are covariant
+  QualType NewClassTy, OldClassTy;
+
+  /// Both types must be pointers or references to classes.
+  if (const PointerType *NewPT = NewTy->getAs<PointerType>()) {
+    if (const PointerType *OldPT = OldTy->getAs<PointerType>()) {
+      NewClassTy = NewPT->getPointeeType();
+      OldClassTy = OldPT->getPointeeType();
+    }
+  } else if (const ReferenceType *NewRT = NewTy->getAs<ReferenceType>()) {
+    if (const ReferenceType *OldRT = OldTy->getAs<ReferenceType>()) {
+      if (NewRT->getTypeClass() == OldRT->getTypeClass()) {
+        NewClassTy = NewRT->getPointeeType();
+        OldClassTy = OldRT->getPointeeType();
+      }
+    }
+  }
+
+  // The return types aren't either both pointers or references to a class type.
+  if (NewClassTy.isNull()) {
+    Diag(New->getLocation(),
+         diag::err_different_return_type_for_overriding_virtual_function)
+      << New->getDeclName() << NewTy << OldTy;
+    Diag(Old->getLocation(), diag::note_overridden_virtual_function);
+
+    return true;
+  }
+
+  // C++ [class.virtual]p6:
+  //   If the return type of D::f differs from the return type of B::f, the 
+  //   class type in the return type of D::f shall be complete at the point of
+  //   declaration of D::f or shall be the class type D.
+  if (const RecordType *RT = NewClassTy->getAs<RecordType>()) {
+    if (!RT->isBeingDefined() &&
+        RequireCompleteType(New->getLocation(), NewClassTy, 
+                            PDiag(diag::err_covariant_return_incomplete)
+                              << New->getDeclName()))
+    return true;
+  }
+
+  if (!Context.hasSameUnqualifiedType(NewClassTy, OldClassTy)) {
+    // Check if the new class derives from the old class.
+    if (!IsDerivedFrom(NewClassTy, OldClassTy)) {
+      Diag(New->getLocation(),
+           diag::err_covariant_return_not_derived)
+      << New->getDeclName() << NewTy << OldTy;
+      Diag(Old->getLocation(), diag::note_overridden_virtual_function);
+      return true;
+    }
+
+    // Check if we the conversion from derived to base is valid.
+    if (CheckDerivedToBaseConversion(NewClassTy, OldClassTy,
+                    diag::err_covariant_return_inaccessible_base,
+                    diag::err_covariant_return_ambiguous_derived_to_base_conv,
+                    // FIXME: Should this point to the return type?
+                    New->getLocation(), SourceRange(), New->getDeclName(), 0)) {
+      Diag(Old->getLocation(), diag::note_overridden_virtual_function);
+      return true;
+    }
+  }
+
+  // The qualifiers of the return types must be the same.
+  if (NewTy.getLocalCVRQualifiers() != OldTy.getLocalCVRQualifiers()) {
+    Diag(New->getLocation(),
+         diag::err_covariant_return_type_different_qualifications)
+    << New->getDeclName() << NewTy << OldTy;
+    Diag(Old->getLocation(), diag::note_overridden_virtual_function);
+    return true;
+  };
+
+
+  // The new class type must have the same or less qualifiers as the old type.
+  if (NewClassTy.isMoreQualifiedThan(OldClassTy)) {
+    Diag(New->getLocation(),
+         diag::err_covariant_return_type_class_type_more_qualified)
+    << New->getDeclName() << NewTy << OldTy;
+    Diag(Old->getLocation(), diag::note_overridden_virtual_function);
+    return true;
+  };
+
+  return false;
+}
+
+bool Sema::CheckOverridingFunctionAttributes(const CXXMethodDecl *New,
+                                             const CXXMethodDecl *Old)
+{
+  if (Old->hasAttr<FinalAttr>()) {
+    Diag(New->getLocation(), diag::err_final_function_overridden)
+      << New->getDeclName();
+    Diag(Old->getLocation(), diag::note_overridden_virtual_function);
+    return true;
+  }
+
+  return false;
+}
+
+/// \brief Mark the given method pure.
+///
+/// \param Method the method to be marked pure.
+///
+/// \param InitRange the source range that covers the "0" initializer.
+bool Sema::CheckPureMethod(CXXMethodDecl *Method, SourceRange InitRange) {
+  if (Method->isVirtual() || Method->getParent()->isDependentContext()) {
+    Method->setPure();
+    
+    // A class is abstract if at least one function is pure virtual.
+    Method->getParent()->setAbstract(true);
+    return false;
+  } 
+
+  if (!Method->isInvalidDecl())
+    Diag(Method->getLocation(), diag::err_non_virtual_pure)
+      << Method->getDeclName() << InitRange;
+  return true;
+}
+
+/// ActOnCXXEnterDeclInitializer - Invoked when we are about to parse
+/// an initializer for the out-of-line declaration 'Dcl'.  The scope
+/// is a fresh scope pushed for just this purpose.
+///
+/// After this method is called, according to [C++ 3.4.1p13], if 'Dcl' is a
+/// static data member of class X, names should be looked up in the scope of
+/// class X.
+void Sema::ActOnCXXEnterDeclInitializer(Scope *S, DeclPtrTy Dcl) {
+  // If there is no declaration, there was an error parsing it.
+  Decl *D = Dcl.getAs<Decl>();
+  if (D == 0) return;
+
+  // We should only get called for declarations with scope specifiers, like:
+  //   int foo::bar;
+  assert(D->isOutOfLine());
+  EnterDeclaratorContext(S, D->getDeclContext());
+}
+
+/// ActOnCXXExitDeclInitializer - Invoked after we are finished parsing an
+/// initializer for the out-of-line declaration 'Dcl'.
+void Sema::ActOnCXXExitDeclInitializer(Scope *S, DeclPtrTy Dcl) {
+  // If there is no declaration, there was an error parsing it.
+  Decl *D = Dcl.getAs<Decl>();
+  if (D == 0) return;
+
+  assert(D->isOutOfLine());
+  ExitDeclaratorContext(S);
+}
+
+/// ActOnCXXConditionDeclarationExpr - Parsed a condition declaration of a
+/// C++ if/switch/while/for statement.
+/// e.g: "if (int x = f()) {...}"
+Action::DeclResult
+Sema::ActOnCXXConditionDeclaration(Scope *S, Declarator &D) {
+  // C++ 6.4p2:
+  // The declarator shall not specify a function or an array.
+  // The type-specifier-seq shall not contain typedef and shall not declare a
+  // new class or enumeration.
+  assert(D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_typedef &&
+         "Parser allowed 'typedef' as storage class of condition decl.");
+  
+  TypeSourceInfo *TInfo = 0;
+  TagDecl *OwnedTag = 0;
+  QualType Ty = GetTypeForDeclarator(D, S, &TInfo, &OwnedTag);
+  
+  if (Ty->isFunctionType()) { // The declarator shall not specify a function...
+                              // We exit without creating a CXXConditionDeclExpr because a FunctionDecl
+                              // would be created and CXXConditionDeclExpr wants a VarDecl.
+    Diag(D.getIdentifierLoc(), diag::err_invalid_use_of_function_type)
+      << D.getSourceRange();
+    return DeclResult();
+  } else if (OwnedTag && OwnedTag->isDefinition()) {
+    // The type-specifier-seq shall not declare a new class or enumeration.
+    Diag(OwnedTag->getLocation(), diag::err_type_defined_in_condition);
+  }
+  
+  DeclPtrTy Dcl = ActOnDeclarator(S, D);
+  if (!Dcl)
+    return DeclResult();
+
+  VarDecl *VD = cast<VarDecl>(Dcl.getAs<Decl>());
+  VD->setDeclaredInCondition(true);
+  return Dcl;
+}
+
+static bool needsVTable(CXXMethodDecl *MD, ASTContext &Context) {
+  // Ignore dependent types.
+  if (MD->isDependentContext())
+    return false;
+
+  // Ignore declarations that are not definitions.
+  if (!MD->isThisDeclarationADefinition())
+    return false;
+
+  CXXRecordDecl *RD = MD->getParent();
+
+  // Ignore classes without a vtable.
+  if (!RD->isDynamicClass())
+    return false;
+
+  switch (MD->getParent()->getTemplateSpecializationKind()) {
+  case TSK_Undeclared:
+  case TSK_ExplicitSpecialization:
+    // Classes that aren't instantiations of templates don't need their
+    // virtual methods marked until we see the definition of the key 
+    // function.
+    break;
+
+  case TSK_ImplicitInstantiation:
+    // This is a constructor of a class template; mark all of the virtual
+    // members as referenced to ensure that they get instantiatied.
+    if (isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD))
+      return true;
+    break;
+
+  case TSK_ExplicitInstantiationDeclaration:
+    return false;
+
+  case TSK_ExplicitInstantiationDefinition:
+    // This is method of a explicit instantiation; mark all of the virtual
+    // members as referenced to ensure that they get instantiatied.
+    return true;
+  }
+
+  // Consider only out-of-line definitions of member functions. When we see
+  // an inline definition, it's too early to compute the key function.
+  if (!MD->isOutOfLine())
+    return false;
+
+  const CXXMethodDecl *KeyFunction = Context.getKeyFunction(RD);
+
+  // If there is no key function, we will need a copy of the vtable.
+  if (!KeyFunction)
+    return true;
+
+  // If this is the key function, we need to mark virtual members.
+  if (KeyFunction->getCanonicalDecl() == MD->getCanonicalDecl())
+    return true;
+
+  return false;
+}
+
+void Sema::MaybeMarkVirtualMembersReferenced(SourceLocation Loc,
+                                             CXXMethodDecl *MD) {
+  CXXRecordDecl *RD = MD->getParent();
+
+  // We will need to mark all of the virtual members as referenced to build the
+  // vtable.
+  if (!needsVTable(MD, Context))
+    return;
+
+  TemplateSpecializationKind kind = RD->getTemplateSpecializationKind();
+  if (kind == TSK_ImplicitInstantiation)
+    ClassesWithUnmarkedVirtualMembers.push_back(std::make_pair(RD, Loc));
+  else
+    MarkVirtualMembersReferenced(Loc, RD);
+}
+
+bool Sema::ProcessPendingClassesWithUnmarkedVirtualMembers() {
+  if (ClassesWithUnmarkedVirtualMembers.empty())
+    return false;
+  
+  while (!ClassesWithUnmarkedVirtualMembers.empty()) {
+    CXXRecordDecl *RD = ClassesWithUnmarkedVirtualMembers.back().first;
+    SourceLocation Loc = ClassesWithUnmarkedVirtualMembers.back().second;
+    ClassesWithUnmarkedVirtualMembers.pop_back();
+    MarkVirtualMembersReferenced(Loc, RD);
+  }
+  
+  return true;
+}
+
+void Sema::MarkVirtualMembersReferenced(SourceLocation Loc,
+                                        const CXXRecordDecl *RD) {
+  for (CXXRecordDecl::method_iterator i = RD->method_begin(), 
+       e = RD->method_end(); i != e; ++i) {
+    CXXMethodDecl *MD = *i;
+
+    // C++ [basic.def.odr]p2:
+    //   [...] A virtual member function is used if it is not pure. [...]
+    if (MD->isVirtual() && !MD->isPure())
+      MarkDeclarationReferenced(Loc, MD);
+  }
+
+  // Only classes that have virtual bases need a VTT.
+  if (RD->getNumVBases() == 0)
+    return;
+
+  for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
+           e = RD->bases_end(); i != e; ++i) {
+    const CXXRecordDecl *Base =
+        cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
+    if (i->isVirtual())
+      continue;
+    if (Base->getNumVBases() == 0)
+      continue;
+    MarkVirtualMembersReferenced(Loc, Base);
+  }
+}
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
new file mode 100644
index 0000000..0e93ebd
--- /dev/null
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -0,0 +1,1800 @@
+//===--- SemaDeclObjC.cpp - Semantic Analysis for ObjC Declarations -------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements semantic analysis for Objective C declarations.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Sema.h"
+#include "Lookup.h"
+#include "clang/Sema/ExternalSemaSource.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/Parse/DeclSpec.h"
+using namespace clang;
+
+/// ActOnStartOfObjCMethodDef - This routine sets up parameters; invisible
+/// and user declared, in the method definition's AST.
+void Sema::ActOnStartOfObjCMethodDef(Scope *FnBodyScope, DeclPtrTy D) {
+  assert(getCurMethodDecl() == 0 && "Method parsing confused");
+  ObjCMethodDecl *MDecl = dyn_cast_or_null<ObjCMethodDecl>(D.getAs<Decl>());
+
+  // If we don't have a valid method decl, simply return.
+  if (!MDecl)
+    return;
+
+  // Allow the rest of sema to find private method decl implementations.
+  if (MDecl->isInstanceMethod())
+    AddInstanceMethodToGlobalPool(MDecl);
+  else
+    AddFactoryMethodToGlobalPool(MDecl);
+
+  // Allow all of Sema to see that we are entering a method definition.
+  PushDeclContext(FnBodyScope, MDecl);
+  PushFunctionScope();
+  
+  // Create Decl objects for each parameter, entrring them in the scope for
+  // binding to their use.
+
+  // Insert the invisible arguments, self and _cmd!
+  MDecl->createImplicitParams(Context, MDecl->getClassInterface());
+
+  PushOnScopeChains(MDecl->getSelfDecl(), FnBodyScope);
+  PushOnScopeChains(MDecl->getCmdDecl(), FnBodyScope);
+
+  // Introduce all of the other parameters into this scope.
+  for (ObjCMethodDecl::param_iterator PI = MDecl->param_begin(),
+       E = MDecl->param_end(); PI != E; ++PI)
+    if ((*PI)->getIdentifier())
+      PushOnScopeChains(*PI, FnBodyScope);
+}
+
+Sema::DeclPtrTy Sema::
+ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
+                         IdentifierInfo *ClassName, SourceLocation ClassLoc,
+                         IdentifierInfo *SuperName, SourceLocation SuperLoc,
+                         const DeclPtrTy *ProtoRefs, unsigned NumProtoRefs,
+                         const SourceLocation *ProtoLocs, 
+                         SourceLocation EndProtoLoc, AttributeList *AttrList) {
+  assert(ClassName && "Missing class identifier");
+
+  // Check for another declaration kind with the same name.
+  NamedDecl *PrevDecl = LookupSingleName(TUScope, ClassName, ClassLoc,
+                                         LookupOrdinaryName, ForRedeclaration);
+
+  if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
+    Diag(ClassLoc, diag::err_redefinition_different_kind) << ClassName;
+    Diag(PrevDecl->getLocation(), diag::note_previous_definition);
+  }
+
+  ObjCInterfaceDecl* IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
+  if (IDecl) {
+    // Class already seen. Is it a forward declaration?
+    if (!IDecl->isForwardDecl()) {
+      IDecl->setInvalidDecl();
+      Diag(AtInterfaceLoc, diag::err_duplicate_class_def)<<IDecl->getDeclName();
+      Diag(IDecl->getLocation(), diag::note_previous_definition);
+
+      // Return the previous class interface.
+      // FIXME: don't leak the objects passed in!
+      return DeclPtrTy::make(IDecl);
+    } else {
+      IDecl->setLocation(AtInterfaceLoc);
+      IDecl->setForwardDecl(false);
+      IDecl->setClassLoc(ClassLoc);
+      
+      // Since this ObjCInterfaceDecl was created by a forward declaration,
+      // we now add it to the DeclContext since it wasn't added before
+      // (see ActOnForwardClassDeclaration).
+      IDecl->setLexicalDeclContext(CurContext);
+      CurContext->addDecl(IDecl);
+      
+      if (AttrList)
+        ProcessDeclAttributeList(TUScope, IDecl, AttrList);
+    }
+  } else {
+    IDecl = ObjCInterfaceDecl::Create(Context, CurContext, AtInterfaceLoc,
+                                      ClassName, ClassLoc);
+    if (AttrList)
+      ProcessDeclAttributeList(TUScope, IDecl, AttrList);
+
+    PushOnScopeChains(IDecl, TUScope);
+  }
+
+  if (SuperName) {
+    // Check if a different kind of symbol declared in this scope.
+    PrevDecl = LookupSingleName(TUScope, SuperName, SuperLoc,
+                                LookupOrdinaryName);
+
+    if (!PrevDecl) {
+      // Try to correct for a typo in the superclass name.
+      LookupResult R(*this, SuperName, SuperLoc, LookupOrdinaryName);
+      if (CorrectTypo(R, TUScope, 0, 0, false, CTC_NoKeywords) &&
+          (PrevDecl = R.getAsSingle<ObjCInterfaceDecl>())) {
+        Diag(SuperLoc, diag::err_undef_superclass_suggest)
+          << SuperName << ClassName << PrevDecl->getDeclName();
+        Diag(PrevDecl->getLocation(), diag::note_previous_decl)
+          << PrevDecl->getDeclName();
+      }
+    }
+
+    if (PrevDecl == IDecl) {
+      Diag(SuperLoc, diag::err_recursive_superclass)
+        << SuperName << ClassName << SourceRange(AtInterfaceLoc, ClassLoc);
+      IDecl->setLocEnd(ClassLoc);
+    } else {
+      ObjCInterfaceDecl *SuperClassDecl =
+                                dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
+
+      // Diagnose classes that inherit from deprecated classes.
+      if (SuperClassDecl)
+        (void)DiagnoseUseOfDecl(SuperClassDecl, SuperLoc);
+
+      if (PrevDecl && SuperClassDecl == 0) {
+        // The previous declaration was not a class decl. Check if we have a
+        // typedef. If we do, get the underlying class type.
+        if (const TypedefDecl *TDecl = dyn_cast_or_null<TypedefDecl>(PrevDecl)) {
+          QualType T = TDecl->getUnderlyingType();
+          if (T->isObjCInterfaceType()) {
+            if (NamedDecl *IDecl = T->getAs<ObjCInterfaceType>()->getDecl())
+              SuperClassDecl = dyn_cast<ObjCInterfaceDecl>(IDecl);
+          }
+        }
+
+        // This handles the following case:
+        //
+        // typedef int SuperClass;
+        // @interface MyClass : SuperClass {} @end
+        //
+        if (!SuperClassDecl) {
+          Diag(SuperLoc, diag::err_redefinition_different_kind) << SuperName;
+          Diag(PrevDecl->getLocation(), diag::note_previous_definition);
+        }
+      }
+
+      if (!dyn_cast_or_null<TypedefDecl>(PrevDecl)) {
+        if (!SuperClassDecl)
+          Diag(SuperLoc, diag::err_undef_superclass)
+            << SuperName << ClassName << SourceRange(AtInterfaceLoc, ClassLoc);
+        else if (SuperClassDecl->isForwardDecl())
+          Diag(SuperLoc, diag::err_undef_superclass)
+            << SuperClassDecl->getDeclName() << ClassName
+            << SourceRange(AtInterfaceLoc, ClassLoc);
+      }
+      IDecl->setSuperClass(SuperClassDecl);
+      IDecl->setSuperClassLoc(SuperLoc);
+      IDecl->setLocEnd(SuperLoc);
+    }
+  } else { // we have a root class.
+    IDecl->setLocEnd(ClassLoc);
+  }
+
+  /// Check then save referenced protocols.
+  if (NumProtoRefs) {
+    IDecl->setProtocolList((ObjCProtocolDecl**)ProtoRefs, NumProtoRefs,
+                           ProtoLocs, Context);
+    IDecl->setLocEnd(EndProtoLoc);
+  }
+
+  CheckObjCDeclScope(IDecl);
+  return DeclPtrTy::make(IDecl);
+}
+
+/// ActOnCompatiblityAlias - this action is called after complete parsing of
+/// @compatibility_alias declaration. It sets up the alias relationships.
+Sema::DeclPtrTy Sema::ActOnCompatiblityAlias(SourceLocation AtLoc,
+                                             IdentifierInfo *AliasName,
+                                             SourceLocation AliasLocation,
+                                             IdentifierInfo *ClassName,
+                                             SourceLocation ClassLocation) {
+  // Look for previous declaration of alias name
+  NamedDecl *ADecl = LookupSingleName(TUScope, AliasName, AliasLocation,
+                                      LookupOrdinaryName, ForRedeclaration);
+  if (ADecl) {
+    if (isa<ObjCCompatibleAliasDecl>(ADecl))
+      Diag(AliasLocation, diag::warn_previous_alias_decl);
+    else
+      Diag(AliasLocation, diag::err_conflicting_aliasing_type) << AliasName;
+    Diag(ADecl->getLocation(), diag::note_previous_declaration);
+    return DeclPtrTy();
+  }
+  // Check for class declaration
+  NamedDecl *CDeclU = LookupSingleName(TUScope, ClassName, ClassLocation,
+                                       LookupOrdinaryName, ForRedeclaration);
+  if (const TypedefDecl *TDecl = dyn_cast_or_null<TypedefDecl>(CDeclU)) {
+    QualType T = TDecl->getUnderlyingType();
+    if (T->isObjCInterfaceType()) {
+      if (NamedDecl *IDecl = T->getAs<ObjCInterfaceType>()->getDecl()) {
+        ClassName = IDecl->getIdentifier();
+        CDeclU = LookupSingleName(TUScope, ClassName, ClassLocation,
+                                  LookupOrdinaryName, ForRedeclaration);
+      }
+    }
+  }
+  ObjCInterfaceDecl *CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(CDeclU);
+  if (CDecl == 0) {
+    Diag(ClassLocation, diag::warn_undef_interface) << ClassName;
+    if (CDeclU)
+      Diag(CDeclU->getLocation(), diag::note_previous_declaration);
+    return DeclPtrTy();
+  }
+
+  // Everything checked out, instantiate a new alias declaration AST.
+  ObjCCompatibleAliasDecl *AliasDecl =
+    ObjCCompatibleAliasDecl::Create(Context, CurContext, AtLoc, AliasName, CDecl);
+
+  if (!CheckObjCDeclScope(AliasDecl))
+    PushOnScopeChains(AliasDecl, TUScope);
+
+  return DeclPtrTy::make(AliasDecl);
+}
+
+void Sema::CheckForwardProtocolDeclarationForCircularDependency(
+  IdentifierInfo *PName,
+  SourceLocation &Ploc, SourceLocation PrevLoc,
+  const ObjCList<ObjCProtocolDecl> &PList) {
+  for (ObjCList<ObjCProtocolDecl>::iterator I = PList.begin(),
+       E = PList.end(); I != E; ++I) {
+
+    if (ObjCProtocolDecl *PDecl = LookupProtocol((*I)->getIdentifier(),
+                                                 Ploc)) {
+      if (PDecl->getIdentifier() == PName) {
+        Diag(Ploc, diag::err_protocol_has_circular_dependency);
+        Diag(PrevLoc, diag::note_previous_definition);
+      }
+      CheckForwardProtocolDeclarationForCircularDependency(PName, Ploc,
+        PDecl->getLocation(), PDecl->getReferencedProtocols());
+    }
+  }
+}
+
+Sema::DeclPtrTy
+Sema::ActOnStartProtocolInterface(SourceLocation AtProtoInterfaceLoc,
+                                  IdentifierInfo *ProtocolName,
+                                  SourceLocation ProtocolLoc,
+                                  const DeclPtrTy *ProtoRefs,
+                                  unsigned NumProtoRefs,
+                                  const SourceLocation *ProtoLocs,
+                                  SourceLocation EndProtoLoc,
+                                  AttributeList *AttrList) {
+  // FIXME: Deal with AttrList.
+  assert(ProtocolName && "Missing protocol identifier");
+  ObjCProtocolDecl *PDecl = LookupProtocol(ProtocolName, ProtocolLoc);
+  if (PDecl) {
+    // Protocol already seen. Better be a forward protocol declaration
+    if (!PDecl->isForwardDecl()) {
+      Diag(ProtocolLoc, diag::warn_duplicate_protocol_def) << ProtocolName;
+      Diag(PDecl->getLocation(), diag::note_previous_definition);
+      // Just return the protocol we already had.
+      // FIXME: don't leak the objects passed in!
+      return DeclPtrTy::make(PDecl);
+    }
+    ObjCList<ObjCProtocolDecl> PList;
+    PList.set((ObjCProtocolDecl *const*)ProtoRefs, NumProtoRefs, Context);
+    CheckForwardProtocolDeclarationForCircularDependency(
+      ProtocolName, ProtocolLoc, PDecl->getLocation(), PList);
+    PList.Destroy(Context);
+
+    // Make sure the cached decl gets a valid start location.
+    PDecl->setLocation(AtProtoInterfaceLoc);
+    PDecl->setForwardDecl(false);
+  } else {
+    PDecl = ObjCProtocolDecl::Create(Context, CurContext,
+                                     AtProtoInterfaceLoc,ProtocolName);
+    PushOnScopeChains(PDecl, TUScope);
+    PDecl->setForwardDecl(false);
+  }
+  if (AttrList)
+    ProcessDeclAttributeList(TUScope, PDecl, AttrList);
+  if (NumProtoRefs) {
+    /// Check then save referenced protocols.
+    PDecl->setProtocolList((ObjCProtocolDecl**)ProtoRefs, NumProtoRefs,
+                           ProtoLocs, Context);
+    PDecl->setLocEnd(EndProtoLoc);
+  }
+
+  CheckObjCDeclScope(PDecl);
+  return DeclPtrTy::make(PDecl);
+}
+
+/// FindProtocolDeclaration - This routine looks up protocols and
+/// issues an error if they are not declared. It returns list of
+/// protocol declarations in its 'Protocols' argument.
+void
+Sema::FindProtocolDeclaration(bool WarnOnDeclarations,
+                              const IdentifierLocPair *ProtocolId,
+                              unsigned NumProtocols,
+                              llvm::SmallVectorImpl<DeclPtrTy> &Protocols) {
+  for (unsigned i = 0; i != NumProtocols; ++i) {
+    ObjCProtocolDecl *PDecl = LookupProtocol(ProtocolId[i].first,
+                                             ProtocolId[i].second);
+    if (!PDecl) {
+      LookupResult R(*this, ProtocolId[i].first, ProtocolId[i].second,
+                     LookupObjCProtocolName);
+      if (CorrectTypo(R, TUScope, 0, 0, false, CTC_NoKeywords) &&
+          (PDecl = R.getAsSingle<ObjCProtocolDecl>())) {
+        Diag(ProtocolId[i].second, diag::err_undeclared_protocol_suggest)
+          << ProtocolId[i].first << R.getLookupName();
+        Diag(PDecl->getLocation(), diag::note_previous_decl)
+          << PDecl->getDeclName();
+      }
+    }
+
+    if (!PDecl) {
+      Diag(ProtocolId[i].second, diag::err_undeclared_protocol)
+        << ProtocolId[i].first;
+      continue;
+    }
+
+    (void)DiagnoseUseOfDecl(PDecl, ProtocolId[i].second);
+
+    // If this is a forward declaration and we are supposed to warn in this
+    // case, do it.
+    if (WarnOnDeclarations && PDecl->isForwardDecl())
+      Diag(ProtocolId[i].second, diag::warn_undef_protocolref)
+        << ProtocolId[i].first;
+    Protocols.push_back(DeclPtrTy::make(PDecl));
+  }
+}
+
+/// DiagnoseClassExtensionDupMethods - Check for duplicate declaration of
+/// a class method in its extension.
+///
+void Sema::DiagnoseClassExtensionDupMethods(ObjCCategoryDecl *CAT,
+                                            ObjCInterfaceDecl *ID) {
+  if (!ID)
+    return;  // Possibly due to previous error
+
+  llvm::DenseMap<Selector, const ObjCMethodDecl*> MethodMap;
+  for (ObjCInterfaceDecl::method_iterator i = ID->meth_begin(),
+       e =  ID->meth_end(); i != e; ++i) {
+    ObjCMethodDecl *MD = *i;
+    MethodMap[MD->getSelector()] = MD;
+  }
+
+  if (MethodMap.empty())
+    return;
+  for (ObjCCategoryDecl::method_iterator i = CAT->meth_begin(),
+       e =  CAT->meth_end(); i != e; ++i) {
+    ObjCMethodDecl *Method = *i;
+    const ObjCMethodDecl *&PrevMethod = MethodMap[Method->getSelector()];
+    if (PrevMethod && !MatchTwoMethodDeclarations(Method, PrevMethod)) {
+      Diag(Method->getLocation(), diag::err_duplicate_method_decl)
+            << Method->getDeclName();
+      Diag(PrevMethod->getLocation(), diag::note_previous_declaration);
+    }
+  }
+}
+
+/// ActOnForwardProtocolDeclaration - Handle @protocol foo;
+Action::DeclPtrTy
+Sema::ActOnForwardProtocolDeclaration(SourceLocation AtProtocolLoc,
+                                      const IdentifierLocPair *IdentList,
+                                      unsigned NumElts,
+                                      AttributeList *attrList) {
+  llvm::SmallVector<ObjCProtocolDecl*, 32> Protocols;
+  llvm::SmallVector<SourceLocation, 8> ProtoLocs;
+
+  for (unsigned i = 0; i != NumElts; ++i) {
+    IdentifierInfo *Ident = IdentList[i].first;
+    ObjCProtocolDecl *PDecl = LookupProtocol(Ident, IdentList[i].second);
+    if (PDecl == 0) { // Not already seen?
+      PDecl = ObjCProtocolDecl::Create(Context, CurContext,
+                                       IdentList[i].second, Ident);
+      PushOnScopeChains(PDecl, TUScope);
+    }
+    if (attrList)
+      ProcessDeclAttributeList(TUScope, PDecl, attrList);
+    Protocols.push_back(PDecl);
+    ProtoLocs.push_back(IdentList[i].second);
+  }
+
+  ObjCForwardProtocolDecl *PDecl =
+    ObjCForwardProtocolDecl::Create(Context, CurContext, AtProtocolLoc,
+                                    Protocols.data(), Protocols.size(),
+                                    ProtoLocs.data());
+  CurContext->addDecl(PDecl);
+  CheckObjCDeclScope(PDecl);
+  return DeclPtrTy::make(PDecl);
+}
+
+Sema::DeclPtrTy Sema::
+ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc,
+                            IdentifierInfo *ClassName, SourceLocation ClassLoc,
+                            IdentifierInfo *CategoryName,
+                            SourceLocation CategoryLoc,
+                            const DeclPtrTy *ProtoRefs,
+                            unsigned NumProtoRefs,
+                            const SourceLocation *ProtoLocs,
+                            SourceLocation EndProtoLoc) {
+  ObjCCategoryDecl *CDecl = 0;
+  ObjCInterfaceDecl *IDecl = getObjCInterfaceDecl(ClassName, ClassLoc, true);
+
+  /// Check that class of this category is already completely declared.
+  if (!IDecl || IDecl->isForwardDecl()) {
+    // Create an invalid ObjCCategoryDecl to serve as context for
+    // the enclosing method declarations.  We mark the decl invalid
+    // to make it clear that this isn't a valid AST.
+    CDecl = ObjCCategoryDecl::Create(Context, CurContext, AtInterfaceLoc,
+                                     ClassLoc, CategoryLoc, CategoryName);
+    CDecl->setInvalidDecl();
+    Diag(ClassLoc, diag::err_undef_interface) << ClassName;
+    return DeclPtrTy::make(CDecl);
+  }
+
+  if (!CategoryName) {
+    // Class extensions require a special treatment. Use an existing one.
+    // Note that 'getClassExtension()' can return NULL.
+    CDecl = IDecl->getClassExtension();
+    if (IDecl->getImplementation()) {
+      Diag(ClassLoc, diag::err_class_extension_after_impl) << ClassName;
+      Diag(IDecl->getImplementation()->getLocation(), 
+           diag::note_implementation_declared);
+    }
+  }
+
+  if (!CDecl) {
+    CDecl = ObjCCategoryDecl::Create(Context, CurContext, AtInterfaceLoc,
+                                     ClassLoc, CategoryLoc, CategoryName);
+    // FIXME: PushOnScopeChains?
+    CurContext->addDecl(CDecl);
+
+    CDecl->setClassInterface(IDecl);
+    // Insert first use of class extension to the list of class's categories.
+    if (!CategoryName)
+      CDecl->insertNextClassCategory();
+  }
+
+  // If the interface is deprecated, warn about it.
+  (void)DiagnoseUseOfDecl(IDecl, ClassLoc);
+
+  if (CategoryName) {
+    /// Check for duplicate interface declaration for this category
+    ObjCCategoryDecl *CDeclChain;
+    for (CDeclChain = IDecl->getCategoryList(); CDeclChain;
+         CDeclChain = CDeclChain->getNextClassCategory()) {
+      if (CDeclChain->getIdentifier() == CategoryName) {
+        // Class extensions can be declared multiple times.
+        Diag(CategoryLoc, diag::warn_dup_category_def)
+          << ClassName << CategoryName;
+        Diag(CDeclChain->getLocation(), diag::note_previous_definition);
+        break;
+      }
+    }
+    if (!CDeclChain)
+      CDecl->insertNextClassCategory();
+  }
+
+  if (NumProtoRefs) {
+    CDecl->setProtocolList((ObjCProtocolDecl**)ProtoRefs, NumProtoRefs, 
+                           ProtoLocs, Context);
+    // Protocols in the class extension belong to the class.
+    if (CDecl->IsClassExtension())
+     IDecl->mergeClassExtensionProtocolList((ObjCProtocolDecl**)ProtoRefs, 
+                                            NumProtoRefs, ProtoLocs,
+                                            Context); 
+  }
+
+  CheckObjCDeclScope(CDecl);
+  return DeclPtrTy::make(CDecl);
+}
+
+/// ActOnStartCategoryImplementation - Perform semantic checks on the
+/// category implementation declaration and build an ObjCCategoryImplDecl
+/// object.
+Sema::DeclPtrTy Sema::ActOnStartCategoryImplementation(
+                      SourceLocation AtCatImplLoc,
+                      IdentifierInfo *ClassName, SourceLocation ClassLoc,
+                      IdentifierInfo *CatName, SourceLocation CatLoc) {
+  ObjCInterfaceDecl *IDecl = getObjCInterfaceDecl(ClassName, ClassLoc, true);
+  ObjCCategoryDecl *CatIDecl = 0;
+  if (IDecl) {
+    CatIDecl = IDecl->FindCategoryDeclaration(CatName);
+    if (!CatIDecl) {
+      // Category @implementation with no corresponding @interface.
+      // Create and install one.
+      CatIDecl = ObjCCategoryDecl::Create(Context, CurContext, SourceLocation(),
+                                          SourceLocation(), SourceLocation(),
+                                          CatName);
+      CatIDecl->setClassInterface(IDecl);
+      CatIDecl->insertNextClassCategory();
+    }
+  }
+
+  ObjCCategoryImplDecl *CDecl =
+    ObjCCategoryImplDecl::Create(Context, CurContext, AtCatImplLoc, CatName,
+                                 IDecl);
+  /// Check that class of this category is already completely declared.
+  if (!IDecl || IDecl->isForwardDecl())
+    Diag(ClassLoc, diag::err_undef_interface) << ClassName;
+
+  // FIXME: PushOnScopeChains?
+  CurContext->addDecl(CDecl);
+
+  /// Check that CatName, category name, is not used in another implementation.
+  if (CatIDecl) {
+    if (CatIDecl->getImplementation()) {
+      Diag(ClassLoc, diag::err_dup_implementation_category) << ClassName
+        << CatName;
+      Diag(CatIDecl->getImplementation()->getLocation(),
+           diag::note_previous_definition);
+    } else
+      CatIDecl->setImplementation(CDecl);
+  }
+
+  CheckObjCDeclScope(CDecl);
+  return DeclPtrTy::make(CDecl);
+}
+
+Sema::DeclPtrTy Sema::ActOnStartClassImplementation(
+                      SourceLocation AtClassImplLoc,
+                      IdentifierInfo *ClassName, SourceLocation ClassLoc,
+                      IdentifierInfo *SuperClassname,
+                      SourceLocation SuperClassLoc) {
+  ObjCInterfaceDecl* IDecl = 0;
+  // Check for another declaration kind with the same name.
+  NamedDecl *PrevDecl
+    = LookupSingleName(TUScope, ClassName, ClassLoc, LookupOrdinaryName,
+                       ForRedeclaration);
+  if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
+    Diag(ClassLoc, diag::err_redefinition_different_kind) << ClassName;
+    Diag(PrevDecl->getLocation(), diag::note_previous_definition);
+  } else if ((IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl))) {
+    // If this is a forward declaration of an interface, warn.
+    if (IDecl->isForwardDecl()) {
+      Diag(ClassLoc, diag::warn_undef_interface) << ClassName;
+      IDecl = 0;
+    }
+  } else {
+    // We did not find anything with the name ClassName; try to correct for 
+    // typos in the class name.
+    LookupResult R(*this, ClassName, ClassLoc, LookupOrdinaryName);
+    if (CorrectTypo(R, TUScope, 0, 0, false, CTC_NoKeywords) &&
+        (IDecl = R.getAsSingle<ObjCInterfaceDecl>())) {
+      // Suggest the (potentially) correct interface name. However, put the
+      // fix-it hint itself in a separate note, since changing the name in 
+      // the warning would make the fix-it change semantics.However, don't
+      // provide a code-modification hint or use the typo name for recovery,
+      // because this is just a warning. The program may actually be correct.
+      Diag(ClassLoc, diag::warn_undef_interface_suggest)
+        << ClassName << R.getLookupName();
+      Diag(IDecl->getLocation(), diag::note_previous_decl)
+        << R.getLookupName()
+        << FixItHint::CreateReplacement(ClassLoc,
+                                        R.getLookupName().getAsString());
+      IDecl = 0;
+    } else {
+      Diag(ClassLoc, diag::warn_undef_interface) << ClassName;
+    }
+  }
+
+  // Check that super class name is valid class name
+  ObjCInterfaceDecl* SDecl = 0;
+  if (SuperClassname) {
+    // Check if a different kind of symbol declared in this scope.
+    PrevDecl = LookupSingleName(TUScope, SuperClassname, SuperClassLoc,
+                                LookupOrdinaryName);
+    if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
+      Diag(SuperClassLoc, diag::err_redefinition_different_kind)
+        << SuperClassname;
+      Diag(PrevDecl->getLocation(), diag::note_previous_definition);
+    } else {
+      SDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
+      if (!SDecl)
+        Diag(SuperClassLoc, diag::err_undef_superclass)
+          << SuperClassname << ClassName;
+      else if (IDecl && IDecl->getSuperClass() != SDecl) {
+        // This implementation and its interface do not have the same
+        // super class.
+        Diag(SuperClassLoc, diag::err_conflicting_super_class)
+          << SDecl->getDeclName();
+        Diag(SDecl->getLocation(), diag::note_previous_definition);
+      }
+    }
+  }
+
+  if (!IDecl) {
+    // Legacy case of @implementation with no corresponding @interface.
+    // Build, chain & install the interface decl into the identifier.
+
+    // FIXME: Do we support attributes on the @implementation? If so we should
+    // copy them over.
+    IDecl = ObjCInterfaceDecl::Create(Context, CurContext, AtClassImplLoc,
+                                      ClassName, ClassLoc, false, true);
+    IDecl->setSuperClass(SDecl);
+    IDecl->setLocEnd(ClassLoc);
+
+    PushOnScopeChains(IDecl, TUScope);
+  } else {
+    // Mark the interface as being completed, even if it was just as
+    //   @class ....;
+    // declaration; the user cannot reopen it.
+    IDecl->setForwardDecl(false);
+  }
+
+  ObjCImplementationDecl* IMPDecl =
+    ObjCImplementationDecl::Create(Context, CurContext, AtClassImplLoc,
+                                   IDecl, SDecl);
+
+  if (CheckObjCDeclScope(IMPDecl))
+    return DeclPtrTy::make(IMPDecl);
+
+  // Check that there is no duplicate implementation of this class.
+  if (IDecl->getImplementation()) {
+    // FIXME: Don't leak everything!
+    Diag(ClassLoc, diag::err_dup_implementation_class) << ClassName;
+    Diag(IDecl->getImplementation()->getLocation(),
+         diag::note_previous_definition);
+  } else { // add it to the list.
+    IDecl->setImplementation(IMPDecl);
+    PushOnScopeChains(IMPDecl, TUScope);
+  }
+  return DeclPtrTy::make(IMPDecl);
+}
+
+void Sema::CheckImplementationIvars(ObjCImplementationDecl *ImpDecl,
+                                    ObjCIvarDecl **ivars, unsigned numIvars,
+                                    SourceLocation RBrace) {
+  assert(ImpDecl && "missing implementation decl");
+  ObjCInterfaceDecl* IDecl = ImpDecl->getClassInterface();
+  if (!IDecl)
+    return;
+  /// Check case of non-existing @interface decl.
+  /// (legacy objective-c @implementation decl without an @interface decl).
+  /// Add implementations's ivar to the synthesize class's ivar list.
+  if (IDecl->isImplicitInterfaceDecl()) {
+    IDecl->setLocEnd(RBrace);
+    // Add ivar's to class's DeclContext.
+    for (unsigned i = 0, e = numIvars; i != e; ++i) {
+      ivars[i]->setLexicalDeclContext(ImpDecl);
+      IDecl->makeDeclVisibleInContext(ivars[i], false);
+      ImpDecl->addDecl(ivars[i]);
+    }
+    
+    return;
+  }
+  // If implementation has empty ivar list, just return.
+  if (numIvars == 0)
+    return;
+
+  assert(ivars && "missing @implementation ivars");
+  if (LangOpts.ObjCNonFragileABI2) {
+    if (ImpDecl->getSuperClass())
+      Diag(ImpDecl->getLocation(), diag::warn_on_superclass_use);
+    for (unsigned i = 0; i < numIvars; i++) {
+      ObjCIvarDecl* ImplIvar = ivars[i];
+      if (const ObjCIvarDecl *ClsIvar = 
+            IDecl->getIvarDecl(ImplIvar->getIdentifier())) {
+        Diag(ImplIvar->getLocation(), diag::err_duplicate_ivar_declaration); 
+        Diag(ClsIvar->getLocation(), diag::note_previous_definition);
+        continue;
+      }
+      // Instance ivar to Implementation's DeclContext.
+      ImplIvar->setLexicalDeclContext(ImpDecl);
+      IDecl->makeDeclVisibleInContext(ImplIvar, false);
+      ImpDecl->addDecl(ImplIvar);
+    }
+    return;
+  }
+  // Check interface's Ivar list against those in the implementation.
+  // names and types must match.
+  //
+  unsigned j = 0;
+  ObjCInterfaceDecl::ivar_iterator
+    IVI = IDecl->ivar_begin(), IVE = IDecl->ivar_end();
+  for (; numIvars > 0 && IVI != IVE; ++IVI) {
+    ObjCIvarDecl* ImplIvar = ivars[j++];
+    ObjCIvarDecl* ClsIvar = *IVI;
+    assert (ImplIvar && "missing implementation ivar");
+    assert (ClsIvar && "missing class ivar");
+
+    // First, make sure the types match.
+    if (Context.getCanonicalType(ImplIvar->getType()) !=
+        Context.getCanonicalType(ClsIvar->getType())) {
+      Diag(ImplIvar->getLocation(), diag::err_conflicting_ivar_type)
+        << ImplIvar->getIdentifier()
+        << ImplIvar->getType() << ClsIvar->getType();
+      Diag(ClsIvar->getLocation(), diag::note_previous_definition);
+    } else if (ImplIvar->isBitField() && ClsIvar->isBitField()) {
+      Expr *ImplBitWidth = ImplIvar->getBitWidth();
+      Expr *ClsBitWidth = ClsIvar->getBitWidth();
+      if (ImplBitWidth->EvaluateAsInt(Context).getZExtValue() !=
+          ClsBitWidth->EvaluateAsInt(Context).getZExtValue()) {
+        Diag(ImplBitWidth->getLocStart(), diag::err_conflicting_ivar_bitwidth)
+          << ImplIvar->getIdentifier();
+        Diag(ClsBitWidth->getLocStart(), diag::note_previous_definition);
+      }
+    }
+    // Make sure the names are identical.
+    if (ImplIvar->getIdentifier() != ClsIvar->getIdentifier()) {
+      Diag(ImplIvar->getLocation(), diag::err_conflicting_ivar_name)
+        << ImplIvar->getIdentifier() << ClsIvar->getIdentifier();
+      Diag(ClsIvar->getLocation(), diag::note_previous_definition);
+    }
+    --numIvars;
+  }
+
+  if (numIvars > 0)
+    Diag(ivars[j]->getLocation(), diag::err_inconsistant_ivar_count);
+  else if (IVI != IVE)
+    Diag((*IVI)->getLocation(), diag::err_inconsistant_ivar_count);
+}
+
+void Sema::WarnUndefinedMethod(SourceLocation ImpLoc, ObjCMethodDecl *method,
+                               bool &IncompleteImpl, unsigned DiagID) {
+  if (!IncompleteImpl) {
+    Diag(ImpLoc, diag::warn_incomplete_impl);
+    IncompleteImpl = true;
+  }
+  Diag(method->getLocation(), DiagID) 
+    << method->getDeclName();
+}
+
+void Sema::WarnConflictingTypedMethods(ObjCMethodDecl *ImpMethodDecl,
+                                       ObjCMethodDecl *IntfMethodDecl) {
+  if (!Context.typesAreCompatible(IntfMethodDecl->getResultType(),
+                                  ImpMethodDecl->getResultType()) &&
+      !Context.QualifiedIdConformsQualifiedId(IntfMethodDecl->getResultType(),
+                                              ImpMethodDecl->getResultType())) {
+    Diag(ImpMethodDecl->getLocation(), diag::warn_conflicting_ret_types)
+      << ImpMethodDecl->getDeclName() << IntfMethodDecl->getResultType()
+      << ImpMethodDecl->getResultType();
+    Diag(IntfMethodDecl->getLocation(), diag::note_previous_definition);
+  }
+
+  for (ObjCMethodDecl::param_iterator IM = ImpMethodDecl->param_begin(),
+       IF = IntfMethodDecl->param_begin(), EM = ImpMethodDecl->param_end();
+       IM != EM; ++IM, ++IF) {
+    QualType ParmDeclTy = (*IF)->getType().getUnqualifiedType();
+    QualType ParmImpTy = (*IM)->getType().getUnqualifiedType();
+    if (Context.typesAreCompatible(ParmDeclTy, ParmImpTy) ||
+        Context.QualifiedIdConformsQualifiedId(ParmDeclTy, ParmImpTy))
+      continue;
+
+    Diag((*IM)->getLocation(), diag::warn_conflicting_param_types)
+      << ImpMethodDecl->getDeclName() << (*IF)->getType()
+      << (*IM)->getType();
+    Diag((*IF)->getLocation(), diag::note_previous_definition);
+  }
+}
+
+/// FIXME: Type hierarchies in Objective-C can be deep. We could most likely
+/// improve the efficiency of selector lookups and type checking by associating
+/// with each protocol / interface / category the flattened instance tables. If
+/// we used an immutable set to keep the table then it wouldn't add significant
+/// memory cost and it would be handy for lookups.
+
+/// CheckProtocolMethodDefs - This routine checks unimplemented methods
+/// Declared in protocol, and those referenced by it.
+void Sema::CheckProtocolMethodDefs(SourceLocation ImpLoc,
+                                   ObjCProtocolDecl *PDecl,
+                                   bool& IncompleteImpl,
+                                   const llvm::DenseSet<Selector> &InsMap,
+                                   const llvm::DenseSet<Selector> &ClsMap,
+                                   ObjCContainerDecl *CDecl) {
+  ObjCInterfaceDecl *IDecl;
+  if (ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(CDecl))
+    IDecl = C->getClassInterface();
+  else
+    IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl);
+  assert (IDecl && "CheckProtocolMethodDefs - IDecl is null");
+  
+  ObjCInterfaceDecl *Super = IDecl->getSuperClass();
+  ObjCInterfaceDecl *NSIDecl = 0;
+  if (getLangOptions().NeXTRuntime) {
+    // check to see if class implements forwardInvocation method and objects
+    // of this class are derived from 'NSProxy' so that to forward requests
+    // from one object to another.
+    // Under such conditions, which means that every method possible is
+    // implemented in the class, we should not issue "Method definition not
+    // found" warnings.
+    // FIXME: Use a general GetUnarySelector method for this.
+    IdentifierInfo* II = &Context.Idents.get("forwardInvocation");
+    Selector fISelector = Context.Selectors.getSelector(1, &II);
+    if (InsMap.count(fISelector))
+      // Is IDecl derived from 'NSProxy'? If so, no instance methods
+      // need be implemented in the implementation.
+      NSIDecl = IDecl->lookupInheritedClass(&Context.Idents.get("NSProxy"));
+  }
+
+  // If a method lookup fails locally we still need to look and see if
+  // the method was implemented by a base class or an inherited
+  // protocol. This lookup is slow, but occurs rarely in correct code
+  // and otherwise would terminate in a warning.
+
+  // check unimplemented instance methods.
+  if (!NSIDecl)
+    for (ObjCProtocolDecl::instmeth_iterator I = PDecl->instmeth_begin(),
+         E = PDecl->instmeth_end(); I != E; ++I) {
+      ObjCMethodDecl *method = *I;
+      if (method->getImplementationControl() != ObjCMethodDecl::Optional &&
+          !method->isSynthesized() && !InsMap.count(method->getSelector()) &&
+          (!Super ||
+           !Super->lookupInstanceMethod(method->getSelector()))) {
+            // Ugly, but necessary. Method declared in protcol might have
+            // have been synthesized due to a property declared in the class which
+            // uses the protocol.
+            ObjCMethodDecl *MethodInClass =
+            IDecl->lookupInstanceMethod(method->getSelector());
+            if (!MethodInClass || !MethodInClass->isSynthesized()) {
+              unsigned DIAG = diag::warn_unimplemented_protocol_method;
+              if (Diags.getDiagnosticLevel(DIAG) != Diagnostic::Ignored) {
+                WarnUndefinedMethod(ImpLoc, method, IncompleteImpl, DIAG);
+                Diag(CDecl->getLocation(), diag::note_required_for_protocol_at)
+                  << PDecl->getDeclName();
+              }
+            }
+          }
+    }
+  // check unimplemented class methods
+  for (ObjCProtocolDecl::classmeth_iterator
+         I = PDecl->classmeth_begin(), E = PDecl->classmeth_end();
+       I != E; ++I) {
+    ObjCMethodDecl *method = *I;
+    if (method->getImplementationControl() != ObjCMethodDecl::Optional &&
+        !ClsMap.count(method->getSelector()) &&
+        (!Super || !Super->lookupClassMethod(method->getSelector()))) {
+      unsigned DIAG = diag::warn_unimplemented_protocol_method;
+      if (Diags.getDiagnosticLevel(DIAG) != Diagnostic::Ignored) {
+        WarnUndefinedMethod(ImpLoc, method, IncompleteImpl, DIAG);
+        Diag(IDecl->getLocation(), diag::note_required_for_protocol_at) <<
+          PDecl->getDeclName();
+      }
+    }
+  }
+  // Check on this protocols's referenced protocols, recursively.
+  for (ObjCProtocolDecl::protocol_iterator PI = PDecl->protocol_begin(),
+       E = PDecl->protocol_end(); PI != E; ++PI)
+    CheckProtocolMethodDefs(ImpLoc, *PI, IncompleteImpl, InsMap, ClsMap, IDecl);
+}
+
+/// MatchAllMethodDeclarations - Check methods declaraed in interface or
+/// or protocol against those declared in their implementations.
+///
+void Sema::MatchAllMethodDeclarations(const llvm::DenseSet<Selector> &InsMap,
+                                      const llvm::DenseSet<Selector> &ClsMap,
+                                      llvm::DenseSet<Selector> &InsMapSeen,
+                                      llvm::DenseSet<Selector> &ClsMapSeen,
+                                      ObjCImplDecl* IMPDecl,
+                                      ObjCContainerDecl* CDecl,
+                                      bool &IncompleteImpl,
+                                      bool ImmediateClass) {
+  // Check and see if instance methods in class interface have been
+  // implemented in the implementation class. If so, their types match.
+  for (ObjCInterfaceDecl::instmeth_iterator I = CDecl->instmeth_begin(),
+       E = CDecl->instmeth_end(); I != E; ++I) {
+    if (InsMapSeen.count((*I)->getSelector()))
+        continue;
+    InsMapSeen.insert((*I)->getSelector());
+    if (!(*I)->isSynthesized() &&
+        !InsMap.count((*I)->getSelector())) {
+      if (ImmediateClass)
+        WarnUndefinedMethod(IMPDecl->getLocation(), *I, IncompleteImpl,
+                            diag::note_undef_method_impl);
+      continue;
+    } else {
+      ObjCMethodDecl *ImpMethodDecl =
+      IMPDecl->getInstanceMethod((*I)->getSelector());
+      ObjCMethodDecl *IntfMethodDecl =
+      CDecl->getInstanceMethod((*I)->getSelector());
+      assert(IntfMethodDecl &&
+             "IntfMethodDecl is null in ImplMethodsVsClassMethods");
+      // ImpMethodDecl may be null as in a @dynamic property.
+      if (ImpMethodDecl)
+        WarnConflictingTypedMethods(ImpMethodDecl, IntfMethodDecl);
+    }
+  }
+
+  // Check and see if class methods in class interface have been
+  // implemented in the implementation class. If so, their types match.
+   for (ObjCInterfaceDecl::classmeth_iterator
+       I = CDecl->classmeth_begin(), E = CDecl->classmeth_end(); I != E; ++I) {
+     if (ClsMapSeen.count((*I)->getSelector()))
+       continue;
+     ClsMapSeen.insert((*I)->getSelector());
+    if (!ClsMap.count((*I)->getSelector())) {
+      if (ImmediateClass)
+        WarnUndefinedMethod(IMPDecl->getLocation(), *I, IncompleteImpl,
+                            diag::note_undef_method_impl);
+    } else {
+      ObjCMethodDecl *ImpMethodDecl =
+        IMPDecl->getClassMethod((*I)->getSelector());
+      ObjCMethodDecl *IntfMethodDecl =
+        CDecl->getClassMethod((*I)->getSelector());
+      WarnConflictingTypedMethods(ImpMethodDecl, IntfMethodDecl);
+    }
+  }
+  if (ObjCInterfaceDecl *I = dyn_cast<ObjCInterfaceDecl> (CDecl)) {
+    // Check for any implementation of a methods declared in protocol.
+    for (ObjCInterfaceDecl::protocol_iterator PI = I->protocol_begin(),
+         E = I->protocol_end(); PI != E; ++PI)
+      MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen,
+                                 IMPDecl,
+                                 (*PI), IncompleteImpl, false);
+    if (I->getSuperClass())
+      MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen,
+                                 IMPDecl,
+                                 I->getSuperClass(), IncompleteImpl, false);
+  }
+}
+
+void Sema::ImplMethodsVsClassMethods(ObjCImplDecl* IMPDecl,
+                                     ObjCContainerDecl* CDecl,
+                                     bool IncompleteImpl) {
+  llvm::DenseSet<Selector> InsMap;
+  // Check and see if instance methods in class interface have been
+  // implemented in the implementation class.
+  for (ObjCImplementationDecl::instmeth_iterator
+         I = IMPDecl->instmeth_begin(), E = IMPDecl->instmeth_end(); I!=E; ++I)
+    InsMap.insert((*I)->getSelector());
+
+  // Check and see if properties declared in the interface have either 1)
+  // an implementation or 2) there is a @synthesize/@dynamic implementation
+  // of the property in the @implementation.
+  if (isa<ObjCInterfaceDecl>(CDecl))
+    DiagnoseUnimplementedProperties(IMPDecl, CDecl, InsMap);
+      
+  llvm::DenseSet<Selector> ClsMap;
+  for (ObjCImplementationDecl::classmeth_iterator
+       I = IMPDecl->classmeth_begin(),
+       E = IMPDecl->classmeth_end(); I != E; ++I)
+    ClsMap.insert((*I)->getSelector());
+
+  // Check for type conflict of methods declared in a class/protocol and
+  // its implementation; if any.
+  llvm::DenseSet<Selector> InsMapSeen, ClsMapSeen;
+  MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen,
+                             IMPDecl, CDecl,
+                             IncompleteImpl, true);
+
+  // Check the protocol list for unimplemented methods in the @implementation
+  // class.
+  // Check and see if class methods in class interface have been
+  // implemented in the implementation class.
+
+  if (ObjCInterfaceDecl *I = dyn_cast<ObjCInterfaceDecl> (CDecl)) {
+    for (ObjCInterfaceDecl::protocol_iterator PI = I->protocol_begin(),
+         E = I->protocol_end(); PI != E; ++PI)
+      CheckProtocolMethodDefs(IMPDecl->getLocation(), *PI, IncompleteImpl,
+                              InsMap, ClsMap, I);
+    // Check class extensions (unnamed categories)
+    for (ObjCCategoryDecl *Categories = I->getCategoryList();
+         Categories; Categories = Categories->getNextClassCategory()) {
+      if (Categories->IsClassExtension()) {
+        ImplMethodsVsClassMethods(IMPDecl, Categories, IncompleteImpl);
+        break;
+      }
+    }
+  } else if (ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(CDecl)) {
+    // For extended class, unimplemented methods in its protocols will
+    // be reported in the primary class.
+    if (!C->IsClassExtension()) {
+      for (ObjCCategoryDecl::protocol_iterator PI = C->protocol_begin(),
+           E = C->protocol_end(); PI != E; ++PI)
+        CheckProtocolMethodDefs(IMPDecl->getLocation(), *PI, IncompleteImpl,
+                                InsMap, ClsMap, CDecl);
+      // Report unimplemented properties in the category as well.
+      // When reporting on missing setter/getters, do not report when
+      // setter/getter is implemented in category's primary class 
+      // implementation.
+      if (ObjCInterfaceDecl *ID = C->getClassInterface())
+        if (ObjCImplDecl *IMP = ID->getImplementation()) {
+          for (ObjCImplementationDecl::instmeth_iterator
+               I = IMP->instmeth_begin(), E = IMP->instmeth_end(); I!=E; ++I)
+            InsMap.insert((*I)->getSelector());
+        }
+      DiagnoseUnimplementedProperties(IMPDecl, CDecl, InsMap);      
+    } 
+  } else
+    assert(false && "invalid ObjCContainerDecl type.");
+}
+
+/// ActOnForwardClassDeclaration -
+Action::DeclPtrTy
+Sema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc,
+                                   IdentifierInfo **IdentList,
+                                   SourceLocation *IdentLocs,
+                                   unsigned NumElts) {
+  llvm::SmallVector<ObjCInterfaceDecl*, 32> Interfaces;
+
+  for (unsigned i = 0; i != NumElts; ++i) {
+    // Check for another declaration kind with the same name.
+    NamedDecl *PrevDecl
+      = LookupSingleName(TUScope, IdentList[i], IdentLocs[i], 
+                         LookupOrdinaryName, ForRedeclaration);
+    if (PrevDecl && PrevDecl->isTemplateParameter()) {
+      // Maybe we will complain about the shadowed template parameter.
+      DiagnoseTemplateParameterShadow(AtClassLoc, PrevDecl);
+      // Just pretend that we didn't see the previous declaration.
+      PrevDecl = 0;
+    }
+
+    if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
+      // GCC apparently allows the following idiom:
+      //
+      // typedef NSObject < XCElementTogglerP > XCElementToggler;
+      // @class XCElementToggler;
+      //
+      // FIXME: Make an extension?
+      TypedefDecl *TDD = dyn_cast<TypedefDecl>(PrevDecl);
+      if (!TDD || !isa<ObjCInterfaceType>(TDD->getUnderlyingType())) {
+        Diag(AtClassLoc, diag::err_redefinition_different_kind) << IdentList[i];
+        Diag(PrevDecl->getLocation(), diag::note_previous_definition);
+      } else if (TDD) {
+        // a forward class declaration matching a typedef name of a class refers
+        // to the underlying class.
+        if (ObjCInterfaceType * OI =
+              dyn_cast<ObjCInterfaceType>(TDD->getUnderlyingType()))
+          PrevDecl = OI->getDecl();
+      }
+    }
+    ObjCInterfaceDecl *IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
+    if (!IDecl) {  // Not already seen?  Make a forward decl.
+      IDecl = ObjCInterfaceDecl::Create(Context, CurContext, AtClassLoc,
+                                        IdentList[i], IdentLocs[i], true);
+      
+      // Push the ObjCInterfaceDecl on the scope chain but do *not* add it to
+      // the current DeclContext.  This prevents clients that walk DeclContext
+      // from seeing the imaginary ObjCInterfaceDecl until it is actually
+      // declared later (if at all).  We also take care to explicitly make
+      // sure this declaration is visible for name lookup.
+      PushOnScopeChains(IDecl, TUScope, false);
+      CurContext->makeDeclVisibleInContext(IDecl, true);
+    }
+
+    Interfaces.push_back(IDecl);
+  }
+
+  assert(Interfaces.size() == NumElts);
+  ObjCClassDecl *CDecl = ObjCClassDecl::Create(Context, CurContext, AtClassLoc,
+                                               Interfaces.data(), IdentLocs,
+                                               Interfaces.size());
+  CurContext->addDecl(CDecl);
+  CheckObjCDeclScope(CDecl);
+  return DeclPtrTy::make(CDecl);
+}
+
+
+/// MatchTwoMethodDeclarations - Checks that two methods have matching type and
+/// returns true, or false, accordingly.
+/// TODO: Handle protocol list; such as id<p1,p2> in type comparisons
+bool Sema::MatchTwoMethodDeclarations(const ObjCMethodDecl *Method,
+                                      const ObjCMethodDecl *PrevMethod,
+                                      bool matchBasedOnSizeAndAlignment) {
+  QualType T1 = Context.getCanonicalType(Method->getResultType());
+  QualType T2 = Context.getCanonicalType(PrevMethod->getResultType());
+
+  if (T1 != T2) {
+    // The result types are different.
+    if (!matchBasedOnSizeAndAlignment)
+      return false;
+    // Incomplete types don't have a size and alignment.
+    if (T1->isIncompleteType() || T2->isIncompleteType())
+      return false;
+    // Check is based on size and alignment.
+    if (Context.getTypeInfo(T1) != Context.getTypeInfo(T2))
+      return false;
+  }
+
+  ObjCMethodDecl::param_iterator ParamI = Method->param_begin(),
+       E = Method->param_end();
+  ObjCMethodDecl::param_iterator PrevI = PrevMethod->param_begin();
+
+  for (; ParamI != E; ++ParamI, ++PrevI) {
+    assert(PrevI != PrevMethod->param_end() && "Param mismatch");
+    T1 = Context.getCanonicalType((*ParamI)->getType());
+    T2 = Context.getCanonicalType((*PrevI)->getType());
+    if (T1 != T2) {
+      // The result types are different.
+      if (!matchBasedOnSizeAndAlignment)
+        return false;
+      // Incomplete types don't have a size and alignment.
+      if (T1->isIncompleteType() || T2->isIncompleteType())
+        return false;
+      // Check is based on size and alignment.
+      if (Context.getTypeInfo(T1) != Context.getTypeInfo(T2))
+        return false;
+    }
+  }
+  return true;
+}
+
+/// \brief Read the contents of the instance and factory method pools
+/// for a given selector from external storage.
+///
+/// This routine should only be called once, when neither the instance
+/// nor the factory method pool has an entry for this selector.
+Sema::MethodPool::iterator Sema::ReadMethodPool(Selector Sel,
+                                                bool isInstance) {
+  assert(ExternalSource && "We need an external AST source");
+  assert(InstanceMethodPool.find(Sel) == InstanceMethodPool.end() &&
+         "Selector data already loaded into the instance method pool");
+  assert(FactoryMethodPool.find(Sel) == FactoryMethodPool.end() &&
+         "Selector data already loaded into the factory method pool");
+
+  // Read the method list from the external source.
+  std::pair<ObjCMethodList, ObjCMethodList> Methods
+    = ExternalSource->ReadMethodPool(Sel);
+
+  if (isInstance) {
+    if (Methods.second.Method)
+      FactoryMethodPool[Sel] = Methods.second;
+    return InstanceMethodPool.insert(std::make_pair(Sel, Methods.first)).first;
+  }
+
+  if (Methods.first.Method)
+    InstanceMethodPool[Sel] = Methods.first;
+
+  return FactoryMethodPool.insert(std::make_pair(Sel, Methods.second)).first;
+}
+
+void Sema::AddInstanceMethodToGlobalPool(ObjCMethodDecl *Method) {
+  llvm::DenseMap<Selector, ObjCMethodList>::iterator Pos
+    = InstanceMethodPool.find(Method->getSelector());
+  if (Pos == InstanceMethodPool.end()) {
+    if (ExternalSource && !FactoryMethodPool.count(Method->getSelector()))
+      Pos = ReadMethodPool(Method->getSelector(), /*isInstance=*/true);
+    else
+      Pos = InstanceMethodPool.insert(std::make_pair(Method->getSelector(),
+                                                     ObjCMethodList())).first;
+  }
+
+  ObjCMethodList &Entry = Pos->second;
+  if (Entry.Method == 0) {
+    // Haven't seen a method with this selector name yet - add it.
+    Entry.Method = Method;
+    Entry.Next = 0;
+    return;
+  }
+
+  // We've seen a method with this name, see if we have already seen this type
+  // signature.
+  for (ObjCMethodList *List = &Entry; List; List = List->Next)
+    if (MatchTwoMethodDeclarations(Method, List->Method))
+      return;
+
+  // We have a new signature for an existing method - add it.
+  // This is extremely rare. Only 1% of Cocoa selectors are "overloaded".
+  ObjCMethodList *Mem = BumpAlloc.Allocate<ObjCMethodList>();
+  Entry.Next = new (Mem) ObjCMethodList(Method, Entry.Next);
+}
+
+// FIXME: Finish implementing -Wno-strict-selector-match.
+ObjCMethodDecl *Sema::LookupInstanceMethodInGlobalPool(Selector Sel,
+                                                       SourceRange R,
+                                                       bool warn) {
+  llvm::DenseMap<Selector, ObjCMethodList>::iterator Pos
+    = InstanceMethodPool.find(Sel);
+  if (Pos == InstanceMethodPool.end()) {
+    if (ExternalSource && !FactoryMethodPool.count(Sel))
+      Pos = ReadMethodPool(Sel, /*isInstance=*/true);
+    else
+      return 0;
+  }
+
+  ObjCMethodList &MethList = Pos->second;
+  bool issueWarning = false;
+
+  if (MethList.Method && MethList.Next) {
+    for (ObjCMethodList *Next = MethList.Next; Next; Next = Next->Next)
+      // This checks if the methods differ by size & alignment.
+      if (!MatchTwoMethodDeclarations(MethList.Method, Next->Method, true))
+        issueWarning = warn;
+  }
+  if (issueWarning && (MethList.Method && MethList.Next)) {
+    Diag(R.getBegin(), diag::warn_multiple_method_decl) << Sel << R;
+    Diag(MethList.Method->getLocStart(), diag::note_using)
+      << MethList.Method->getSourceRange();
+    for (ObjCMethodList *Next = MethList.Next; Next; Next = Next->Next)
+      Diag(Next->Method->getLocStart(), diag::note_also_found)
+        << Next->Method->getSourceRange();
+  }
+  return MethList.Method;
+}
+
+void Sema::AddFactoryMethodToGlobalPool(ObjCMethodDecl *Method) {
+  llvm::DenseMap<Selector, ObjCMethodList>::iterator Pos
+    = FactoryMethodPool.find(Method->getSelector());
+  if (Pos == FactoryMethodPool.end()) {
+    if (ExternalSource && !InstanceMethodPool.count(Method->getSelector()))
+      Pos = ReadMethodPool(Method->getSelector(), /*isInstance=*/false);
+    else
+      Pos = FactoryMethodPool.insert(std::make_pair(Method->getSelector(),
+                                                    ObjCMethodList())).first;
+  }
+
+  ObjCMethodList &FirstMethod = Pos->second;
+  if (!FirstMethod.Method) {
+    // Haven't seen a method with this selector name yet - add it.
+    FirstMethod.Method = Method;
+    FirstMethod.Next = 0;
+  } else {
+    // We've seen a method with this name, now check the type signature(s).
+    bool match = MatchTwoMethodDeclarations(Method, FirstMethod.Method);
+
+    for (ObjCMethodList *Next = FirstMethod.Next; !match && Next;
+         Next = Next->Next)
+      match = MatchTwoMethodDeclarations(Method, Next->Method);
+
+    if (!match) {
+      // We have a new signature for an existing method - add it.
+      // This is extremely rare. Only 1% of Cocoa selectors are "overloaded".
+      ObjCMethodList *Mem = BumpAlloc.Allocate<ObjCMethodList>();
+      ObjCMethodList *OMI = new (Mem) ObjCMethodList(Method, FirstMethod.Next);
+      FirstMethod.Next = OMI;
+    }
+  }
+}
+
+ObjCMethodDecl *Sema::LookupFactoryMethodInGlobalPool(Selector Sel,
+                                                      SourceRange R) {
+  llvm::DenseMap<Selector, ObjCMethodList>::iterator Pos
+    = FactoryMethodPool.find(Sel);
+  if (Pos == FactoryMethodPool.end()) {
+    if (ExternalSource && !InstanceMethodPool.count(Sel))
+      Pos = ReadMethodPool(Sel, /*isInstance=*/false);
+    else
+      return 0;
+  }
+
+  ObjCMethodList &MethList = Pos->second;
+  bool issueWarning = false;
+
+  if (MethList.Method && MethList.Next) {
+    for (ObjCMethodList *Next = MethList.Next; Next; Next = Next->Next)
+      // This checks if the methods differ by size & alignment.
+      if (!MatchTwoMethodDeclarations(MethList.Method, Next->Method, true))
+        issueWarning = true;
+  }
+  if (issueWarning && (MethList.Method && MethList.Next)) {
+    Diag(R.getBegin(), diag::warn_multiple_method_decl) << Sel << R;
+    Diag(MethList.Method->getLocStart(), diag::note_using)
+      << MethList.Method->getSourceRange();
+    for (ObjCMethodList *Next = MethList.Next; Next; Next = Next->Next)
+      Diag(Next->Method->getLocStart(), diag::note_also_found)
+        << Next->Method->getSourceRange();
+  }
+  return MethList.Method;
+}
+
+/// CompareMethodParamsInBaseAndSuper - This routine compares methods with
+/// identical selector names in current and its super classes and issues
+/// a warning if any of their argument types are incompatible.
+void Sema::CompareMethodParamsInBaseAndSuper(Decl *ClassDecl,
+                                             ObjCMethodDecl *Method,
+                                             bool IsInstance)  {
+  ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(ClassDecl);
+  if (ID == 0) return;
+
+  while (ObjCInterfaceDecl *SD = ID->getSuperClass()) {
+    ObjCMethodDecl *SuperMethodDecl =
+        SD->lookupMethod(Method->getSelector(), IsInstance);
+    if (SuperMethodDecl == 0) {
+      ID = SD;
+      continue;
+    }
+    ObjCMethodDecl::param_iterator ParamI = Method->param_begin(),
+      E = Method->param_end();
+    ObjCMethodDecl::param_iterator PrevI = SuperMethodDecl->param_begin();
+    for (; ParamI != E; ++ParamI, ++PrevI) {
+      // Number of parameters are the same and is guaranteed by selector match.
+      assert(PrevI != SuperMethodDecl->param_end() && "Param mismatch");
+      QualType T1 = Context.getCanonicalType((*ParamI)->getType());
+      QualType T2 = Context.getCanonicalType((*PrevI)->getType());
+      // If type of arguement of method in this class does not match its
+      // respective argument type in the super class method, issue warning;
+      if (!Context.typesAreCompatible(T1, T2)) {
+        Diag((*ParamI)->getLocation(), diag::ext_typecheck_base_super)
+          << T1 << T2;
+        Diag(SuperMethodDecl->getLocation(), diag::note_previous_declaration);
+        return;
+      }
+    }
+    ID = SD;
+  }
+}
+
+/// DiagnoseDuplicateIvars - 
+/// Check for duplicate ivars in the entire class at the start of 
+/// @implementation. This becomes necesssary because class extension can
+/// add ivars to a class in random order which will not be known until
+/// class's @implementation is seen.
+void Sema::DiagnoseDuplicateIvars(ObjCInterfaceDecl *ID, 
+                                  ObjCInterfaceDecl *SID) {
+  for (ObjCInterfaceDecl::ivar_iterator IVI = ID->ivar_begin(),
+       IVE = ID->ivar_end(); IVI != IVE; ++IVI) {
+    ObjCIvarDecl* Ivar = (*IVI);
+    if (Ivar->isInvalidDecl())
+      continue;
+    if (IdentifierInfo *II = Ivar->getIdentifier()) {
+      ObjCIvarDecl* prevIvar = SID->lookupInstanceVariable(II);
+      if (prevIvar) {
+        Diag(Ivar->getLocation(), diag::err_duplicate_member) << II;
+        Diag(prevIvar->getLocation(), diag::note_previous_declaration);
+        Ivar->setInvalidDecl();
+      }
+    }
+  }
+}
+
+// Note: For class/category implemenations, allMethods/allProperties is
+// always null.
+void Sema::ActOnAtEnd(SourceRange AtEnd,
+                      DeclPtrTy classDecl,
+                      DeclPtrTy *allMethods, unsigned allNum,
+                      DeclPtrTy *allProperties, unsigned pNum,
+                      DeclGroupPtrTy *allTUVars, unsigned tuvNum) {
+  Decl *ClassDecl = classDecl.getAs<Decl>();
+
+  // FIXME: If we don't have a ClassDecl, we have an error. We should consider
+  // always passing in a decl. If the decl has an error, isInvalidDecl()
+  // should be true.
+  if (!ClassDecl)
+    return;
+  
+  bool isInterfaceDeclKind =
+        isa<ObjCInterfaceDecl>(ClassDecl) || isa<ObjCCategoryDecl>(ClassDecl)
+         || isa<ObjCProtocolDecl>(ClassDecl);
+  bool checkIdenticalMethods = isa<ObjCImplementationDecl>(ClassDecl);
+
+  if (!isInterfaceDeclKind && AtEnd.isInvalid()) {
+    // FIXME: This is wrong.  We shouldn't be pretending that there is
+    //  an '@end' in the declaration.
+    SourceLocation L = ClassDecl->getLocation();
+    AtEnd.setBegin(L);
+    AtEnd.setEnd(L);
+    Diag(L, diag::warn_missing_atend);
+  }
+  
+  DeclContext *DC = dyn_cast<DeclContext>(ClassDecl);
+
+  // FIXME: Remove these and use the ObjCContainerDecl/DeclContext.
+  llvm::DenseMap<Selector, const ObjCMethodDecl*> InsMap;
+  llvm::DenseMap<Selector, const ObjCMethodDecl*> ClsMap;
+
+  for (unsigned i = 0; i < allNum; i++ ) {
+    ObjCMethodDecl *Method =
+      cast_or_null<ObjCMethodDecl>(allMethods[i].getAs<Decl>());
+
+    if (!Method) continue;  // Already issued a diagnostic.
+    if (Method->isInstanceMethod()) {
+      /// Check for instance method of the same name with incompatible types
+      const ObjCMethodDecl *&PrevMethod = InsMap[Method->getSelector()];
+      bool match = PrevMethod ? MatchTwoMethodDeclarations(Method, PrevMethod)
+                              : false;
+      if ((isInterfaceDeclKind && PrevMethod && !match)
+          || (checkIdenticalMethods && match)) {
+          Diag(Method->getLocation(), diag::err_duplicate_method_decl)
+            << Method->getDeclName();
+          Diag(PrevMethod->getLocation(), diag::note_previous_declaration);
+      } else {
+        DC->addDecl(Method);
+        InsMap[Method->getSelector()] = Method;
+        /// The following allows us to typecheck messages to "id".
+        AddInstanceMethodToGlobalPool(Method);
+        // verify that the instance method conforms to the same definition of
+        // parent methods if it shadows one.
+        CompareMethodParamsInBaseAndSuper(ClassDecl, Method, true);
+      }
+    } else {
+      /// Check for class method of the same name with incompatible types
+      const ObjCMethodDecl *&PrevMethod = ClsMap[Method->getSelector()];
+      bool match = PrevMethod ? MatchTwoMethodDeclarations(Method, PrevMethod)
+                              : false;
+      if ((isInterfaceDeclKind && PrevMethod && !match)
+          || (checkIdenticalMethods && match)) {
+        Diag(Method->getLocation(), diag::err_duplicate_method_decl)
+          << Method->getDeclName();
+        Diag(PrevMethod->getLocation(), diag::note_previous_declaration);
+      } else {
+        DC->addDecl(Method);
+        ClsMap[Method->getSelector()] = Method;
+        /// The following allows us to typecheck messages to "Class".
+        AddFactoryMethodToGlobalPool(Method);
+        // verify that the class method conforms to the same definition of
+        // parent methods if it shadows one.
+        CompareMethodParamsInBaseAndSuper(ClassDecl, Method, false);
+      }
+    }
+  }
+  if (ObjCInterfaceDecl *I = dyn_cast<ObjCInterfaceDecl>(ClassDecl)) {
+    // Compares properties declared in this class to those of its
+    // super class.
+    ComparePropertiesInBaseAndSuper(I);
+    CompareProperties(I, DeclPtrTy::make(I));
+  } else if (ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(ClassDecl)) {
+    // Categories are used to extend the class by declaring new methods.
+    // By the same token, they are also used to add new properties. No
+    // need to compare the added property to those in the class.
+
+    // Compare protocol properties with those in category
+    CompareProperties(C, DeclPtrTy::make(C));
+    if (C->IsClassExtension())
+      DiagnoseClassExtensionDupMethods(C, C->getClassInterface());
+  }
+  if (ObjCContainerDecl *CDecl = dyn_cast<ObjCContainerDecl>(ClassDecl)) {
+    if (CDecl->getIdentifier())
+      // ProcessPropertyDecl is responsible for diagnosing conflicts with any
+      // user-defined setter/getter. It also synthesizes setter/getter methods
+      // and adds them to the DeclContext and global method pools.
+      for (ObjCContainerDecl::prop_iterator I = CDecl->prop_begin(),
+                                            E = CDecl->prop_end();
+           I != E; ++I)
+        ProcessPropertyDecl(*I, CDecl);
+    CDecl->setAtEndRange(AtEnd);
+  }
+  if (ObjCImplementationDecl *IC=dyn_cast<ObjCImplementationDecl>(ClassDecl)) {
+    IC->setAtEndRange(AtEnd);
+    if (ObjCInterfaceDecl* IDecl = IC->getClassInterface()) {
+      ImplMethodsVsClassMethods(IC, IDecl);
+      AtomicPropertySetterGetterRules(IC, IDecl);
+      if (LangOpts.ObjCNonFragileABI2)
+        while (IDecl->getSuperClass()) {
+          DiagnoseDuplicateIvars(IDecl, IDecl->getSuperClass());
+          IDecl = IDecl->getSuperClass();
+        }
+    }
+  } else if (ObjCCategoryImplDecl* CatImplClass =
+                                   dyn_cast<ObjCCategoryImplDecl>(ClassDecl)) {
+    CatImplClass->setAtEndRange(AtEnd);
+
+    // Find category interface decl and then check that all methods declared
+    // in this interface are implemented in the category @implementation.
+    if (ObjCInterfaceDecl* IDecl = CatImplClass->getClassInterface()) {
+      for (ObjCCategoryDecl *Categories = IDecl->getCategoryList();
+           Categories; Categories = Categories->getNextClassCategory()) {
+        if (Categories->getIdentifier() == CatImplClass->getIdentifier()) {
+          ImplMethodsVsClassMethods(CatImplClass, Categories);
+          break;
+        }
+      }
+    }
+  }
+  if (isInterfaceDeclKind) {
+    // Reject invalid vardecls.
+    for (unsigned i = 0; i != tuvNum; i++) {
+      DeclGroupRef DG = allTUVars[i].getAsVal<DeclGroupRef>();
+      for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I)
+        if (VarDecl *VDecl = dyn_cast<VarDecl>(*I)) {
+          if (!VDecl->hasExternalStorage())
+            Diag(VDecl->getLocation(), diag::err_objc_var_decl_inclass);
+        }
+    }
+  }
+}
+
+
+/// CvtQTToAstBitMask - utility routine to produce an AST bitmask for
+/// objective-c's type qualifier from the parser version of the same info.
+static Decl::ObjCDeclQualifier
+CvtQTToAstBitMask(ObjCDeclSpec::ObjCDeclQualifier PQTVal) {
+  Decl::ObjCDeclQualifier ret = Decl::OBJC_TQ_None;
+  if (PQTVal & ObjCDeclSpec::DQ_In)
+    ret = (Decl::ObjCDeclQualifier)(ret | Decl::OBJC_TQ_In);
+  if (PQTVal & ObjCDeclSpec::DQ_Inout)
+    ret = (Decl::ObjCDeclQualifier)(ret | Decl::OBJC_TQ_Inout);
+  if (PQTVal & ObjCDeclSpec::DQ_Out)
+    ret = (Decl::ObjCDeclQualifier)(ret | Decl::OBJC_TQ_Out);
+  if (PQTVal & ObjCDeclSpec::DQ_Bycopy)
+    ret = (Decl::ObjCDeclQualifier)(ret | Decl::OBJC_TQ_Bycopy);
+  if (PQTVal & ObjCDeclSpec::DQ_Byref)
+    ret = (Decl::ObjCDeclQualifier)(ret | Decl::OBJC_TQ_Byref);
+  if (PQTVal & ObjCDeclSpec::DQ_Oneway)
+    ret = (Decl::ObjCDeclQualifier)(ret | Decl::OBJC_TQ_Oneway);
+
+  return ret;
+}
+
+static inline
+bool containsInvalidMethodImplAttribute(const AttributeList *A) {
+  // The 'ibaction' attribute is allowed on method definitions because of
+  // how the IBAction macro is used on both method declarations and definitions.
+  // If the method definitions contains any other attributes, return true.
+  while (A && A->getKind() == AttributeList::AT_IBAction)
+    A = A->getNext();
+  return A != NULL;
+}
+
+Sema::DeclPtrTy Sema::ActOnMethodDeclaration(
+    SourceLocation MethodLoc, SourceLocation EndLoc,
+    tok::TokenKind MethodType, DeclPtrTy classDecl,
+    ObjCDeclSpec &ReturnQT, TypeTy *ReturnType,
+    Selector Sel,
+    // optional arguments. The number of types/arguments is obtained
+    // from the Sel.getNumArgs().
+    ObjCArgInfo *ArgInfo,
+    DeclaratorChunk::ParamInfo *CParamInfo, unsigned CNumArgs, // c-style args
+    AttributeList *AttrList, tok::ObjCKeywordKind MethodDeclKind,
+    bool isVariadic) {
+  Decl *ClassDecl = classDecl.getAs<Decl>();
+
+  // Make sure we can establish a context for the method.
+  if (!ClassDecl) {
+    Diag(MethodLoc, diag::error_missing_method_context);
+    getLabelMap().clear();
+    return DeclPtrTy();
+  }
+  QualType resultDeclType;
+
+  TypeSourceInfo *ResultTInfo = 0;
+  if (ReturnType) {
+    resultDeclType = GetTypeFromParser(ReturnType, &ResultTInfo);
+
+    // Methods cannot return interface types. All ObjC objects are
+    // passed by reference.
+    if (resultDeclType->isObjCInterfaceType()) {
+      Diag(MethodLoc, diag::err_object_cannot_be_passed_returned_by_value)
+        << 0 << resultDeclType;
+      return DeclPtrTy();
+    }
+  } else // get the type for "id".
+    resultDeclType = Context.getObjCIdType();
+
+  ObjCMethodDecl* ObjCMethod =
+    ObjCMethodDecl::Create(Context, MethodLoc, EndLoc, Sel, resultDeclType,
+                           ResultTInfo,
+                           cast<DeclContext>(ClassDecl),
+                           MethodType == tok::minus, isVariadic,
+                           false,
+                           MethodDeclKind == tok::objc_optional ?
+                           ObjCMethodDecl::Optional :
+                           ObjCMethodDecl::Required);
+
+  llvm::SmallVector<ParmVarDecl*, 16> Params;
+
+  for (unsigned i = 0, e = Sel.getNumArgs(); i != e; ++i) {
+    QualType ArgType;
+    TypeSourceInfo *DI;
+
+    if (ArgInfo[i].Type == 0) {
+      ArgType = Context.getObjCIdType();
+      DI = 0;
+    } else {
+      ArgType = GetTypeFromParser(ArgInfo[i].Type, &DI);
+      // Perform the default array/function conversions (C99 6.7.5.3p[7,8]).
+      ArgType = adjustParameterType(ArgType);
+    }
+
+    ParmVarDecl* Param
+      = ParmVarDecl::Create(Context, ObjCMethod, ArgInfo[i].NameLoc,
+                            ArgInfo[i].Name, ArgType, DI,
+                            VarDecl::None, VarDecl::None, 0);
+
+    if (ArgType->isObjCInterfaceType()) {
+      Diag(ArgInfo[i].NameLoc,
+           diag::err_object_cannot_be_passed_returned_by_value)
+        << 1 << ArgType;
+      Param->setInvalidDecl();
+    }
+
+    Param->setObjCDeclQualifier(
+      CvtQTToAstBitMask(ArgInfo[i].DeclSpec.getObjCDeclQualifier()));
+
+    // Apply the attributes to the parameter.
+    ProcessDeclAttributeList(TUScope, Param, ArgInfo[i].ArgAttrs);
+
+    Params.push_back(Param);
+  }
+
+  for (unsigned i = 0, e = CNumArgs; i != e; ++i) {
+    ParmVarDecl *Param = CParamInfo[i].Param.getAs<ParmVarDecl>();
+    QualType ArgType = Param->getType();
+    if (ArgType.isNull())
+      ArgType = Context.getObjCIdType();
+    else
+      // Perform the default array/function conversions (C99 6.7.5.3p[7,8]).
+      ArgType = adjustParameterType(ArgType);
+    if (ArgType->isObjCInterfaceType()) {
+      Diag(Param->getLocation(),
+           diag::err_object_cannot_be_passed_returned_by_value)
+      << 1 << ArgType;
+      Param->setInvalidDecl();
+    }
+    Param->setDeclContext(ObjCMethod);
+    IdResolver.RemoveDecl(Param);
+    Params.push_back(Param);
+  }
+  
+  ObjCMethod->setMethodParams(Context, Params.data(), Params.size(),
+                              Sel.getNumArgs());
+  ObjCMethod->setObjCDeclQualifier(
+    CvtQTToAstBitMask(ReturnQT.getObjCDeclQualifier()));
+  const ObjCMethodDecl *PrevMethod = 0;
+
+  if (AttrList)
+    ProcessDeclAttributeList(TUScope, ObjCMethod, AttrList);
+
+  const ObjCMethodDecl *InterfaceMD = 0;
+
+  // For implementations (which can be very "coarse grain"), we add the
+  // method now. This allows the AST to implement lookup methods that work
+  // incrementally (without waiting until we parse the @end). It also allows
+  // us to flag multiple declaration errors as they occur.
+  if (ObjCImplementationDecl *ImpDecl =
+        dyn_cast<ObjCImplementationDecl>(ClassDecl)) {
+    if (MethodType == tok::minus) {
+      PrevMethod = ImpDecl->getInstanceMethod(Sel);
+      ImpDecl->addInstanceMethod(ObjCMethod);
+    } else {
+      PrevMethod = ImpDecl->getClassMethod(Sel);
+      ImpDecl->addClassMethod(ObjCMethod);
+    }
+    InterfaceMD = ImpDecl->getClassInterface()->getMethod(Sel,
+                                                   MethodType == tok::minus);
+    if (containsInvalidMethodImplAttribute(AttrList))
+      Diag(EndLoc, diag::warn_attribute_method_def);
+  } else if (ObjCCategoryImplDecl *CatImpDecl =
+             dyn_cast<ObjCCategoryImplDecl>(ClassDecl)) {
+    if (MethodType == tok::minus) {
+      PrevMethod = CatImpDecl->getInstanceMethod(Sel);
+      CatImpDecl->addInstanceMethod(ObjCMethod);
+    } else {
+      PrevMethod = CatImpDecl->getClassMethod(Sel);
+      CatImpDecl->addClassMethod(ObjCMethod);
+    }
+    if (containsInvalidMethodImplAttribute(AttrList))
+      Diag(EndLoc, diag::warn_attribute_method_def);
+  }
+  if (PrevMethod) {
+    // You can never have two method definitions with the same name.
+    Diag(ObjCMethod->getLocation(), diag::err_duplicate_method_decl)
+      << ObjCMethod->getDeclName();
+    Diag(PrevMethod->getLocation(), diag::note_previous_declaration);
+  }
+
+  // If the interface declared this method, and it was deprecated there,
+  // mark it deprecated here.
+  if (InterfaceMD && InterfaceMD->hasAttr<DeprecatedAttr>())
+    ObjCMethod->addAttr(::new (Context) DeprecatedAttr());
+
+  return DeclPtrTy::make(ObjCMethod);
+}
+
+bool Sema::CheckObjCDeclScope(Decl *D) {
+  if (isa<TranslationUnitDecl>(CurContext->getLookupContext()))
+    return false;
+
+  Diag(D->getLocation(), diag::err_objc_decls_may_only_appear_in_global_scope);
+  D->setInvalidDecl();
+
+  return true;
+}
+
+/// Called whenever @defs(ClassName) is encountered in the source.  Inserts the
+/// instance variables of ClassName into Decls.
+void Sema::ActOnDefs(Scope *S, DeclPtrTy TagD, SourceLocation DeclStart,
+                     IdentifierInfo *ClassName,
+                     llvm::SmallVectorImpl<DeclPtrTy> &Decls) {
+  // Check that ClassName is a valid class
+  ObjCInterfaceDecl *Class = getObjCInterfaceDecl(ClassName, DeclStart);
+  if (!Class) {
+    Diag(DeclStart, diag::err_undef_interface) << ClassName;
+    return;
+  }
+  if (LangOpts.ObjCNonFragileABI) {
+    Diag(DeclStart, diag::err_atdef_nonfragile_interface);
+    return;
+  }
+
+  // Collect the instance variables
+  llvm::SmallVector<FieldDecl*, 32> RecFields;
+  Context.CollectObjCIvars(Class, RecFields);
+  // For each ivar, create a fresh ObjCAtDefsFieldDecl.
+  for (unsigned i = 0; i < RecFields.size(); i++) {
+    FieldDecl* ID = RecFields[i];
+    RecordDecl *Record = dyn_cast<RecordDecl>(TagD.getAs<Decl>());
+    Decl *FD = ObjCAtDefsFieldDecl::Create(Context, Record, ID->getLocation(),
+                                           ID->getIdentifier(), ID->getType(),
+                                           ID->getBitWidth());
+    Decls.push_back(Sema::DeclPtrTy::make(FD));
+  }
+
+  // Introduce all of these fields into the appropriate scope.
+  for (llvm::SmallVectorImpl<DeclPtrTy>::iterator D = Decls.begin();
+       D != Decls.end(); ++D) {
+    FieldDecl *FD = cast<FieldDecl>(D->getAs<Decl>());
+    if (getLangOptions().CPlusPlus)
+      PushOnScopeChains(cast<FieldDecl>(FD), S);
+    else if (RecordDecl *Record = dyn_cast<RecordDecl>(TagD.getAs<Decl>()))
+      Record->addDecl(FD);
+  }
+}
+
+/// \brief Build a type-check a new Objective-C exception variable declaration.
+VarDecl *Sema::BuildObjCExceptionDecl(TypeSourceInfo *TInfo, 
+                                      QualType T,
+                                      IdentifierInfo *Name, 
+                                      SourceLocation NameLoc,
+                                      bool Invalid) {
+  // ISO/IEC TR 18037 S6.7.3: "The type of an object with automatic storage 
+  // duration shall not be qualified by an address-space qualifier."
+  // Since all parameters have automatic store duration, they can not have
+  // an address space.
+  if (T.getAddressSpace() != 0) {
+    Diag(NameLoc, diag::err_arg_with_address_space);
+    Invalid = true;
+  }
+  
+  // An @catch parameter must be an unqualified object pointer type;
+  // FIXME: Recover from "NSObject foo" by inserting the * in "NSObject *foo"?
+  if (Invalid) {
+    // Don't do any further checking.
+  } else if (T->isDependentType()) {
+    // Okay: we don't know what this type will instantiate to.
+  } else if (!T->isObjCObjectPointerType()) {
+    Invalid = true;
+    Diag(NameLoc ,diag::err_catch_param_not_objc_type);
+  } else if (T->isObjCQualifiedIdType()) {
+    Invalid = true;
+    Diag(NameLoc, diag::err_illegal_qualifiers_on_catch_parm);
+  }
+  
+  VarDecl *New = VarDecl::Create(Context, CurContext, NameLoc, Name, T, TInfo,
+                                 VarDecl::None, VarDecl::None);  
+  if (Invalid)
+    New->setInvalidDecl();
+  return New;
+}
+
+Sema::DeclPtrTy Sema::ActOnObjCExceptionDecl(Scope *S, Declarator &D) {
+  const DeclSpec &DS = D.getDeclSpec();
+  
+  // We allow the "register" storage class on exception variables because
+  // GCC did, but we drop it completely. Any other storage class is an error.
+  if (DS.getStorageClassSpec() == DeclSpec::SCS_register) {
+    Diag(DS.getStorageClassSpecLoc(), diag::warn_register_objc_catch_parm)
+      << FixItHint::CreateRemoval(SourceRange(DS.getStorageClassSpecLoc()));
+  } else if (DS.getStorageClassSpec() != DeclSpec::SCS_unspecified) {
+    Diag(DS.getStorageClassSpecLoc(), diag::err_storage_spec_on_catch_parm)
+      << DS.getStorageClassSpec();
+  }  
+  if (D.getDeclSpec().isThreadSpecified())
+    Diag(D.getDeclSpec().getThreadSpecLoc(), diag::err_invalid_thread);
+  D.getMutableDeclSpec().ClearStorageClassSpecs();
+
+  DiagnoseFunctionSpecifiers(D);
+  
+  // Check that there are no default arguments inside the type of this
+  // exception object (C++ only).
+  if (getLangOptions().CPlusPlus)
+    CheckExtraCXXDefaultArguments(D);
+  
+  TypeSourceInfo *TInfo = 0;
+  TagDecl *OwnedDecl = 0;
+  QualType ExceptionType = GetTypeForDeclarator(D, S, &TInfo, &OwnedDecl);
+  
+  if (getLangOptions().CPlusPlus && OwnedDecl && OwnedDecl->isDefinition()) {
+    // Objective-C++: Types shall not be defined in exception types.
+    Diag(OwnedDecl->getLocation(), diag::err_type_defined_in_param_type)
+      << Context.getTypeDeclType(OwnedDecl);
+  }
+
+  VarDecl *New = BuildObjCExceptionDecl(TInfo, ExceptionType, D.getIdentifier(), 
+                                        D.getIdentifierLoc(), 
+                                        D.isInvalidType());
+  
+  // Parameter declarators cannot be qualified (C++ [dcl.meaning]p1).
+  if (D.getCXXScopeSpec().isSet()) {
+    Diag(D.getIdentifierLoc(), diag::err_qualified_objc_catch_parm)
+      << D.getCXXScopeSpec().getRange();
+    New->setInvalidDecl();
+  }
+  
+  // Add the parameter declaration into this scope.
+  S->AddDecl(DeclPtrTy::make(New));
+  if (D.getIdentifier())
+    IdResolver.AddDecl(New);
+  
+  ProcessDeclAttributes(S, New, D);
+  
+  if (New->hasAttr<BlocksAttr>())
+    Diag(New->getLocation(), diag::err_block_on_nonlocal);
+  return DeclPtrTy::make(New);
+}
diff --git a/lib/Sema/SemaExceptionSpec.cpp b/lib/Sema/SemaExceptionSpec.cpp
new file mode 100644
index 0000000..53e9385
--- /dev/null
+++ b/lib/Sema/SemaExceptionSpec.cpp
@@ -0,0 +1,506 @@
+//===--- SemaExceptionSpec.cpp - C++ Exception Specifications ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides Sema routines for C++ exception specification testing.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Sema.h"
+#include "clang/AST/CXXInheritance.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/TypeLoc.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/SourceManager.h"
+#include "llvm/ADT/SmallPtrSet.h"
+
+namespace clang {
+
+static const FunctionProtoType *GetUnderlyingFunction(QualType T)
+{
+  if (const PointerType *PtrTy = T->getAs<PointerType>())
+    T = PtrTy->getPointeeType();
+  else if (const ReferenceType *RefTy = T->getAs<ReferenceType>())
+    T = RefTy->getPointeeType();
+  else if (const MemberPointerType *MPTy = T->getAs<MemberPointerType>())
+    T = MPTy->getPointeeType();
+  return T->getAs<FunctionProtoType>();
+}
+
+/// CheckSpecifiedExceptionType - Check if the given type is valid in an
+/// exception specification. Incomplete types, or pointers to incomplete types
+/// other than void are not allowed.
+bool Sema::CheckSpecifiedExceptionType(QualType T, const SourceRange &Range) {
+
+  // This check (and the similar one below) deals with issue 437, that changes
+  // C++ 9.2p2 this way:
+  // Within the class member-specification, the class is regarded as complete
+  // within function bodies, default arguments, exception-specifications, and
+  // constructor ctor-initializers (including such things in nested classes).
+  if (T->isRecordType() && T->getAs<RecordType>()->isBeingDefined())
+    return false;
+    
+  // C++ 15.4p2: A type denoted in an exception-specification shall not denote
+  //   an incomplete type.
+  if (RequireCompleteType(Range.getBegin(), T,
+      PDiag(diag::err_incomplete_in_exception_spec) << /*direct*/0 << Range))
+    return true;
+
+  // C++ 15.4p2: A type denoted in an exception-specification shall not denote
+  //   an incomplete type a pointer or reference to an incomplete type, other
+  //   than (cv) void*.
+  int kind;
+  if (const PointerType* IT = T->getAs<PointerType>()) {
+    T = IT->getPointeeType();
+    kind = 1;
+  } else if (const ReferenceType* IT = T->getAs<ReferenceType>()) {
+    T = IT->getPointeeType();
+    kind = 2;
+  } else
+    return false;
+
+  // Again as before
+  if (T->isRecordType() && T->getAs<RecordType>()->isBeingDefined())
+    return false;
+    
+  if (!T->isVoidType() && RequireCompleteType(Range.getBegin(), T,
+      PDiag(diag::err_incomplete_in_exception_spec) << kind << Range))
+    return true;
+
+  return false;
+}
+
+/// CheckDistantExceptionSpec - Check if the given type is a pointer or pointer
+/// to member to a function with an exception specification. This means that
+/// it is invalid to add another level of indirection.
+bool Sema::CheckDistantExceptionSpec(QualType T) {
+  if (const PointerType *PT = T->getAs<PointerType>())
+    T = PT->getPointeeType();
+  else if (const MemberPointerType *PT = T->getAs<MemberPointerType>())
+    T = PT->getPointeeType();
+  else
+    return false;
+
+  const FunctionProtoType *FnT = T->getAs<FunctionProtoType>();
+  if (!FnT)
+    return false;
+
+  return FnT->hasExceptionSpec();
+}
+
+bool Sema::CheckEquivalentExceptionSpec(FunctionDecl *Old, FunctionDecl *New) {
+  bool MissingExceptionSpecification = false;
+  bool MissingEmptyExceptionSpecification = false;
+  if (!CheckEquivalentExceptionSpec(PDiag(diag::err_mismatched_exception_spec),
+                                    PDiag(diag::note_previous_declaration),
+                                    Old->getType()->getAs<FunctionProtoType>(),
+                                    Old->getLocation(),
+                                    New->getType()->getAs<FunctionProtoType>(),
+                                    New->getLocation(),
+                                    &MissingExceptionSpecification,
+                                    &MissingEmptyExceptionSpecification))
+    return false;
+
+  // The failure was something other than an empty exception
+  // specification; return an error.
+  if (!MissingExceptionSpecification && !MissingEmptyExceptionSpecification)
+    return true;
+
+  // The new function declaration is only missing an empty exception
+  // specification "throw()". If the throw() specification came from a
+  // function in a system header that has C linkage, just add an empty
+  // exception specification to the "new" declaration. This is an
+  // egregious workaround for glibc, which adds throw() specifications
+  // to many libc functions as an optimization. Unfortunately, that
+  // optimization isn't permitted by the C++ standard, so we're forced
+  // to work around it here.
+  if (MissingEmptyExceptionSpecification &&
+      isa<FunctionProtoType>(New->getType()) &&
+      (Old->getLocation().isInvalid() ||
+       Context.getSourceManager().isInSystemHeader(Old->getLocation())) &&
+      Old->isExternC()) {
+    const FunctionProtoType *NewProto 
+      = cast<FunctionProtoType>(New->getType());
+    QualType NewType = Context.getFunctionType(NewProto->getResultType(),
+                                               NewProto->arg_type_begin(),
+                                               NewProto->getNumArgs(),
+                                               NewProto->isVariadic(),
+                                               NewProto->getTypeQuals(),
+                                               true, false, 0, 0,
+                                               NewProto->getExtInfo());
+    New->setType(NewType);
+    return false;
+  }
+
+  if (MissingExceptionSpecification && isa<FunctionProtoType>(New->getType())) {
+    const FunctionProtoType *NewProto 
+      = cast<FunctionProtoType>(New->getType());
+    const FunctionProtoType *OldProto
+      = Old->getType()->getAs<FunctionProtoType>();
+
+    // Update the type of the function with the appropriate exception
+    // specification.
+    QualType NewType = Context.getFunctionType(NewProto->getResultType(),
+                                               NewProto->arg_type_begin(),
+                                               NewProto->getNumArgs(),
+                                               NewProto->isVariadic(),
+                                               NewProto->getTypeQuals(),
+                                               OldProto->hasExceptionSpec(),
+                                               OldProto->hasAnyExceptionSpec(),
+                                               OldProto->getNumExceptions(),
+                                               OldProto->exception_begin(),
+                                               NewProto->getExtInfo());
+    New->setType(NewType);
+
+    // If exceptions are disabled, suppress the warning about missing
+    // exception specifications for new and delete operators.
+    if (!getLangOptions().Exceptions) {
+      switch (New->getDeclName().getCXXOverloadedOperator()) {
+      case OO_New:
+      case OO_Array_New:
+      case OO_Delete:
+      case OO_Array_Delete:
+        if (New->getDeclContext()->isTranslationUnit())
+          return false;
+        break;
+
+      default:
+        break;
+      }
+    } 
+
+    // Warn about the lack of exception specification.
+    llvm::SmallString<128> ExceptionSpecString;
+    llvm::raw_svector_ostream OS(ExceptionSpecString);
+    OS << "throw(";
+    bool OnFirstException = true;
+    for (FunctionProtoType::exception_iterator E = OldProto->exception_begin(),
+                                            EEnd = OldProto->exception_end();
+         E != EEnd;
+         ++E) {
+      if (OnFirstException)
+        OnFirstException = false;
+      else
+        OS << ", ";
+      
+      OS << E->getAsString(Context.PrintingPolicy);
+    }
+    OS << ")";
+    OS.flush();
+
+    SourceLocation AfterParenLoc;
+    if (TypeSourceInfo *TSInfo = New->getTypeSourceInfo()) {
+      TypeLoc TL = TSInfo->getTypeLoc();
+      if (const FunctionTypeLoc *FTLoc = dyn_cast<FunctionTypeLoc>(&TL))
+        AfterParenLoc = PP.getLocForEndOfToken(FTLoc->getRParenLoc());
+    }
+
+    if (AfterParenLoc.isInvalid())
+      Diag(New->getLocation(), diag::warn_missing_exception_specification)
+        << New << OS.str();
+    else {
+      // FIXME: This will get more complicated with C++0x
+      // late-specified return types.
+      Diag(New->getLocation(), diag::warn_missing_exception_specification)
+        << New << OS.str()
+        << FixItHint::CreateInsertion(AfterParenLoc, " " + OS.str().str());
+    }
+
+    if (!Old->getLocation().isInvalid())
+      Diag(Old->getLocation(), diag::note_previous_declaration);
+
+    return false;    
+  }
+
+  Diag(New->getLocation(), diag::err_mismatched_exception_spec);
+  Diag(Old->getLocation(), diag::note_previous_declaration);
+  return true;
+}
+
+/// CheckEquivalentExceptionSpec - Check if the two types have equivalent
+/// exception specifications. Exception specifications are equivalent if
+/// they allow exactly the same set of exception types. It does not matter how
+/// that is achieved. See C++ [except.spec]p2.
+bool Sema::CheckEquivalentExceptionSpec(
+    const FunctionProtoType *Old, SourceLocation OldLoc,
+    const FunctionProtoType *New, SourceLocation NewLoc) {
+  return CheckEquivalentExceptionSpec(
+                                    PDiag(diag::err_mismatched_exception_spec),
+                                      PDiag(diag::note_previous_declaration),
+                                      Old, OldLoc, New, NewLoc);
+}
+
+/// CheckEquivalentExceptionSpec - Check if the two types have equivalent
+/// exception specifications. Exception specifications are equivalent if
+/// they allow exactly the same set of exception types. It does not matter how
+/// that is achieved. See C++ [except.spec]p2.
+bool Sema::CheckEquivalentExceptionSpec(const PartialDiagnostic &DiagID, 
+                                        const PartialDiagnostic & NoteID,
+                                        const FunctionProtoType *Old, 
+                                        SourceLocation OldLoc,
+                                        const FunctionProtoType *New, 
+                                        SourceLocation NewLoc,
+                                        bool *MissingExceptionSpecification,
+                                     bool *MissingEmptyExceptionSpecification)  {
+  if (MissingExceptionSpecification)
+    *MissingExceptionSpecification = false;
+
+  if (MissingEmptyExceptionSpecification)
+    *MissingEmptyExceptionSpecification = false;
+
+  bool OldAny = !Old->hasExceptionSpec() || Old->hasAnyExceptionSpec();
+  bool NewAny = !New->hasExceptionSpec() || New->hasAnyExceptionSpec();
+  if (OldAny && NewAny)
+    return false;
+  if (OldAny || NewAny) {
+    if (MissingExceptionSpecification && Old->hasExceptionSpec() &&
+        !New->hasExceptionSpec()) {
+      // The old type has an exception specification of some sort, but
+      // the new type does not.
+      *MissingExceptionSpecification = true;
+
+      if (MissingEmptyExceptionSpecification && 
+          !Old->hasAnyExceptionSpec() && Old->getNumExceptions() == 0) {
+        // The old type has a throw() exception specification and the
+        // new type has no exception specification, and the caller asked
+        // to handle this itself.
+        *MissingEmptyExceptionSpecification = true;
+      }
+
+      return true;
+    }
+
+    Diag(NewLoc, DiagID);
+    if (NoteID.getDiagID() != 0)
+      Diag(OldLoc, NoteID);
+    return true;
+  }
+
+  bool Success = true;
+  // Both have a definite exception spec. Collect the first set, then compare
+  // to the second.
+  llvm::SmallPtrSet<CanQualType, 8> OldTypes, NewTypes;
+  for (FunctionProtoType::exception_iterator I = Old->exception_begin(),
+       E = Old->exception_end(); I != E; ++I)
+    OldTypes.insert(Context.getCanonicalType(*I).getUnqualifiedType());
+
+  for (FunctionProtoType::exception_iterator I = New->exception_begin(),
+       E = New->exception_end(); I != E && Success; ++I) {
+    CanQualType TypePtr = Context.getCanonicalType(*I).getUnqualifiedType();
+    if(OldTypes.count(TypePtr))
+      NewTypes.insert(TypePtr);
+    else
+      Success = false;
+  }
+
+  Success = Success && OldTypes.size() == NewTypes.size();
+
+  if (Success) {
+    return false;
+  }
+  Diag(NewLoc, DiagID);
+  if (NoteID.getDiagID() != 0)
+    Diag(OldLoc, NoteID);
+  return true;
+}
+
+/// CheckExceptionSpecSubset - Check whether the second function type's
+/// exception specification is a subset (or equivalent) of the first function
+/// type. This is used by override and pointer assignment checks.
+bool Sema::CheckExceptionSpecSubset(
+    const PartialDiagnostic &DiagID, const PartialDiagnostic & NoteID,
+    const FunctionProtoType *Superset, SourceLocation SuperLoc,
+    const FunctionProtoType *Subset, SourceLocation SubLoc) {
+  // FIXME: As usual, we could be more specific in our error messages, but
+  // that better waits until we've got types with source locations.
+
+  if (!SubLoc.isValid())
+    SubLoc = SuperLoc;
+
+  // If superset contains everything, we're done.
+  if (!Superset->hasExceptionSpec() || Superset->hasAnyExceptionSpec())
+    return CheckParamExceptionSpec(NoteID, Superset, SuperLoc, Subset, SubLoc);
+
+  // It does not. If the subset contains everything, we've failed.
+  if (!Subset->hasExceptionSpec() || Subset->hasAnyExceptionSpec()) {
+    Diag(SubLoc, DiagID);
+    if (NoteID.getDiagID() != 0)
+      Diag(SuperLoc, NoteID);
+    return true;
+  }
+
+  // Neither contains everything. Do a proper comparison.
+  for (FunctionProtoType::exception_iterator SubI = Subset->exception_begin(),
+       SubE = Subset->exception_end(); SubI != SubE; ++SubI) {
+    // Take one type from the subset.
+    QualType CanonicalSubT = Context.getCanonicalType(*SubI);
+    // Unwrap pointers and references so that we can do checks within a class
+    // hierarchy. Don't unwrap member pointers; they don't have hierarchy
+    // conversions on the pointee.
+    bool SubIsPointer = false;
+    if (const ReferenceType *RefTy = CanonicalSubT->getAs<ReferenceType>())
+      CanonicalSubT = RefTy->getPointeeType();
+    if (const PointerType *PtrTy = CanonicalSubT->getAs<PointerType>()) {
+      CanonicalSubT = PtrTy->getPointeeType();
+      SubIsPointer = true;
+    }
+    bool SubIsClass = CanonicalSubT->isRecordType();
+    CanonicalSubT = CanonicalSubT.getLocalUnqualifiedType();
+
+    CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
+                       /*DetectVirtual=*/false);
+
+    bool Contained = false;
+    // Make sure it's in the superset.
+    for (FunctionProtoType::exception_iterator SuperI =
+           Superset->exception_begin(), SuperE = Superset->exception_end();
+         SuperI != SuperE; ++SuperI) {
+      QualType CanonicalSuperT = Context.getCanonicalType(*SuperI);
+      // SubT must be SuperT or derived from it, or pointer or reference to
+      // such types.
+      if (const ReferenceType *RefTy = CanonicalSuperT->getAs<ReferenceType>())
+        CanonicalSuperT = RefTy->getPointeeType();
+      if (SubIsPointer) {
+        if (const PointerType *PtrTy = CanonicalSuperT->getAs<PointerType>())
+          CanonicalSuperT = PtrTy->getPointeeType();
+        else {
+          continue;
+        }
+      }
+      CanonicalSuperT = CanonicalSuperT.getLocalUnqualifiedType();
+      // If the types are the same, move on to the next type in the subset.
+      if (CanonicalSubT == CanonicalSuperT) {
+        Contained = true;
+        break;
+      }
+
+      // Otherwise we need to check the inheritance.
+      if (!SubIsClass || !CanonicalSuperT->isRecordType())
+        continue;
+
+      Paths.clear();
+      if (!IsDerivedFrom(CanonicalSubT, CanonicalSuperT, Paths))
+        continue;
+
+      if (Paths.isAmbiguous(CanonicalSuperT))
+        continue;
+
+      // Do this check from a context without privileges.
+      switch (CheckBaseClassAccess(SourceLocation(),
+                                   CanonicalSuperT, CanonicalSubT,
+                                   Paths.front(),
+                                   /*Diagnostic*/ 0,
+                                   /*ForceCheck*/ true,
+                                   /*ForceUnprivileged*/ true)) {
+      case AR_accessible: break;
+      case AR_inaccessible: continue;
+      case AR_dependent:
+        llvm_unreachable("access check dependent for unprivileged context");
+        break;
+      case AR_delayed:
+        llvm_unreachable("access check delayed in non-declaration");
+        break;
+      }
+
+      Contained = true;
+      break;
+    }
+    if (!Contained) {
+      Diag(SubLoc, DiagID);
+      if (NoteID.getDiagID() != 0)
+        Diag(SuperLoc, NoteID);
+      return true;
+    }
+  }
+  // We've run half the gauntlet.
+  return CheckParamExceptionSpec(NoteID, Superset, SuperLoc, Subset, SubLoc);
+}
+
+static bool CheckSpecForTypesEquivalent(Sema &S,
+    const PartialDiagnostic &DiagID, const PartialDiagnostic & NoteID,
+    QualType Target, SourceLocation TargetLoc,
+    QualType Source, SourceLocation SourceLoc)
+{
+  const FunctionProtoType *TFunc = GetUnderlyingFunction(Target);
+  if (!TFunc)
+    return false;
+  const FunctionProtoType *SFunc = GetUnderlyingFunction(Source);
+  if (!SFunc)
+    return false;
+
+  return S.CheckEquivalentExceptionSpec(DiagID, NoteID, TFunc, TargetLoc,
+                                        SFunc, SourceLoc);
+}
+
+/// CheckParamExceptionSpec - Check if the parameter and return types of the
+/// two functions have equivalent exception specs. This is part of the
+/// assignment and override compatibility check. We do not check the parameters
+/// of parameter function pointers recursively, as no sane programmer would
+/// even be able to write such a function type.
+bool Sema::CheckParamExceptionSpec(const PartialDiagnostic & NoteID,
+    const FunctionProtoType *Target, SourceLocation TargetLoc,
+    const FunctionProtoType *Source, SourceLocation SourceLoc)
+{
+  if (CheckSpecForTypesEquivalent(*this,
+                           PDiag(diag::err_deep_exception_specs_differ) << 0, 
+                                  PDiag(),
+                                  Target->getResultType(), TargetLoc,
+                                  Source->getResultType(), SourceLoc))
+    return true;
+
+  // We shouldn't even be testing this unless the arguments are otherwise
+  // compatible.
+  assert(Target->getNumArgs() == Source->getNumArgs() &&
+         "Functions have different argument counts.");
+  for (unsigned i = 0, E = Target->getNumArgs(); i != E; ++i) {
+    if (CheckSpecForTypesEquivalent(*this,
+                           PDiag(diag::err_deep_exception_specs_differ) << 1, 
+                                    PDiag(),
+                                    Target->getArgType(i), TargetLoc,
+                                    Source->getArgType(i), SourceLoc))
+      return true;
+  }
+  return false;
+}
+
+bool Sema::CheckExceptionSpecCompatibility(Expr *From, QualType ToType)
+{
+  // First we check for applicability.
+  // Target type must be a function, function pointer or function reference.
+  const FunctionProtoType *ToFunc = GetUnderlyingFunction(ToType);
+  if (!ToFunc)
+    return false;
+
+  // SourceType must be a function or function pointer.
+  const FunctionProtoType *FromFunc = GetUnderlyingFunction(From->getType());
+  if (!FromFunc)
+    return false;
+
+  // Now we've got the correct types on both sides, check their compatibility.
+  // This means that the source of the conversion can only throw a subset of
+  // the exceptions of the target, and any exception specs on arguments or
+  // return types must be equivalent.
+  return CheckExceptionSpecSubset(PDiag(diag::err_incompatible_exception_specs),
+                                  PDiag(), ToFunc, 
+                                  From->getSourceRange().getBegin(),
+                                  FromFunc, SourceLocation());
+}
+
+bool Sema::CheckOverridingFunctionExceptionSpec(const CXXMethodDecl *New,
+                                                const CXXMethodDecl *Old) {
+  return CheckExceptionSpecSubset(PDiag(diag::err_override_exception_spec),
+                                  PDiag(diag::note_overridden_virtual_function),
+                                  Old->getType()->getAs<FunctionProtoType>(),
+                                  Old->getLocation(),
+                                  New->getType()->getAs<FunctionProtoType>(),
+                                  New->getLocation());
+}
+
+} // end namespace clang
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
new file mode 100644
index 0000000..088ca96
--- /dev/null
+++ b/lib/Sema/SemaExpr.cpp
@@ -0,0 +1,7487 @@
+//===--- SemaExpr.cpp - Semantic Analysis for Expressions -----------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements semantic analysis for expressions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Sema.h"
+#include "SemaInit.h"
+#include "Lookup.h"
+#include "AnalysisBasedWarnings.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/ExprObjC.h"
+#include "clang/Basic/PartialDiagnostic.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/TargetInfo.h"
+#include "clang/Lex/LiteralSupport.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Parse/DeclSpec.h"
+#include "clang/Parse/Designator.h"
+#include "clang/Parse/Scope.h"
+#include "clang/Parse/Template.h"
+using namespace clang;
+
+
+/// \brief Determine whether the use of this declaration is valid, and
+/// emit any corresponding diagnostics.
+///
+/// This routine diagnoses various problems with referencing
+/// declarations that can occur when using a declaration. For example,
+/// it might warn if a deprecated or unavailable declaration is being
+/// used, or produce an error (and return true) if a C++0x deleted
+/// function is being used.
+///
+/// If IgnoreDeprecated is set to true, this should not want about deprecated
+/// decls.
+///
+/// \returns true if there was an error (this declaration cannot be
+/// referenced), false otherwise.
+///
+bool Sema::DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc) {
+  // See if the decl is deprecated.
+  if (D->getAttr<DeprecatedAttr>()) {
+    EmitDeprecationWarning(D, Loc);
+  }
+
+  // See if the decl is unavailable
+  if (D->getAttr<UnavailableAttr>()) {
+    Diag(Loc, diag::warn_unavailable) << D->getDeclName();
+    Diag(D->getLocation(), diag::note_unavailable_here) << 0;
+  }
+
+  // See if this is a deleted function.
+  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+    if (FD->isDeleted()) {
+      Diag(Loc, diag::err_deleted_function_use);
+      Diag(D->getLocation(), diag::note_unavailable_here) << true;
+      return true;
+    }
+  }
+
+  return false;
+}
+
+/// DiagnoseSentinelCalls - This routine checks on method dispatch calls
+/// (and other functions in future), which have been declared with sentinel
+/// attribute. It warns if call does not have the sentinel argument.
+///
+void Sema::DiagnoseSentinelCalls(NamedDecl *D, SourceLocation Loc,
+                                 Expr **Args, unsigned NumArgs) {
+  const SentinelAttr *attr = D->getAttr<SentinelAttr>();
+  if (!attr)
+    return;
+
+  // FIXME: In C++0x, if any of the arguments are parameter pack
+  // expansions, we can't check for the sentinel now.
+  int sentinelPos = attr->getSentinel();
+  int nullPos = attr->getNullPos();
+
+  // FIXME. ObjCMethodDecl and FunctionDecl need be derived from the same common
+  // base class. Then we won't be needing two versions of the same code.
+  unsigned int i = 0;
+  bool warnNotEnoughArgs = false;
+  int isMethod = 0;
+  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
+    // skip over named parameters.
+    ObjCMethodDecl::param_iterator P, E = MD->param_end();
+    for (P = MD->param_begin(); (P != E && i < NumArgs); ++P) {
+      if (nullPos)
+        --nullPos;
+      else
+        ++i;
+    }
+    warnNotEnoughArgs = (P != E || i >= NumArgs);
+    isMethod = 1;
+  } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+    // skip over named parameters.
+    ObjCMethodDecl::param_iterator P, E = FD->param_end();
+    for (P = FD->param_begin(); (P != E && i < NumArgs); ++P) {
+      if (nullPos)
+        --nullPos;
+      else
+        ++i;
+    }
+    warnNotEnoughArgs = (P != E || i >= NumArgs);
+  } else if (VarDecl *V = dyn_cast<VarDecl>(D)) {
+    // block or function pointer call.
+    QualType Ty = V->getType();
+    if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) {
+      const FunctionType *FT = Ty->isFunctionPointerType()
+      ? Ty->getAs<PointerType>()->getPointeeType()->getAs<FunctionType>()
+      : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>();
+      if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FT)) {
+        unsigned NumArgsInProto = Proto->getNumArgs();
+        unsigned k;
+        for (k = 0; (k != NumArgsInProto && i < NumArgs); k++) {
+          if (nullPos)
+            --nullPos;
+          else
+            ++i;
+        }
+        warnNotEnoughArgs = (k != NumArgsInProto || i >= NumArgs);
+      }
+      if (Ty->isBlockPointerType())
+        isMethod = 2;
+    } else
+      return;
+  } else
+    return;
+
+  if (warnNotEnoughArgs) {
+    Diag(Loc, diag::warn_not_enough_argument) << D->getDeclName();
+    Diag(D->getLocation(), diag::note_sentinel_here) << isMethod;
+    return;
+  }
+  int sentinel = i;
+  while (sentinelPos > 0 && i < NumArgs-1) {
+    --sentinelPos;
+    ++i;
+  }
+  if (sentinelPos > 0) {
+    Diag(Loc, diag::warn_not_enough_argument) << D->getDeclName();
+    Diag(D->getLocation(), diag::note_sentinel_here) << isMethod;
+    return;
+  }
+  while (i < NumArgs-1) {
+    ++i;
+    ++sentinel;
+  }
+  Expr *sentinelExpr = Args[sentinel];
+  if (sentinelExpr && (!isa<GNUNullExpr>(sentinelExpr) &&
+                       !sentinelExpr->isTypeDependent() &&
+                       !sentinelExpr->isValueDependent() &&
+                       (!sentinelExpr->getType()->isPointerType() ||
+                        !sentinelExpr->isNullPointerConstant(Context,
+                                            Expr::NPC_ValueDependentIsNull)))) {
+    Diag(Loc, diag::warn_missing_sentinel) << isMethod;
+    Diag(D->getLocation(), diag::note_sentinel_here) << isMethod;
+  }
+  return;
+}
+
+SourceRange Sema::getExprRange(ExprTy *E) const {
+  Expr *Ex = (Expr *)E;
+  return Ex? Ex->getSourceRange() : SourceRange();
+}
+
+//===----------------------------------------------------------------------===//
+//  Standard Promotions and Conversions
+//===----------------------------------------------------------------------===//
+
+/// DefaultFunctionArrayConversion (C99 6.3.2.1p3, C99 6.3.2.1p4).
+void Sema::DefaultFunctionArrayConversion(Expr *&E) {
+  QualType Ty = E->getType();
+  assert(!Ty.isNull() && "DefaultFunctionArrayConversion - missing type");
+
+  if (Ty->isFunctionType())
+    ImpCastExprToType(E, Context.getPointerType(Ty),
+                      CastExpr::CK_FunctionToPointerDecay);
+  else if (Ty->isArrayType()) {
+    // In C90 mode, arrays only promote to pointers if the array expression is
+    // an lvalue.  The relevant legalese is C90 6.2.2.1p3: "an lvalue that has
+    // type 'array of type' is converted to an expression that has type 'pointer
+    // to type'...".  In C99 this was changed to: C99 6.3.2.1p3: "an expression
+    // that has type 'array of type' ...".  The relevant change is "an lvalue"
+    // (C90) to "an expression" (C99).
+    //
+    // C++ 4.2p1:
+    // An lvalue or rvalue of type "array of N T" or "array of unknown bound of
+    // T" can be converted to an rvalue of type "pointer to T".
+    //
+    if (getLangOptions().C99 || getLangOptions().CPlusPlus ||
+        E->isLvalue(Context) == Expr::LV_Valid)
+      ImpCastExprToType(E, Context.getArrayDecayedType(Ty),
+                        CastExpr::CK_ArrayToPointerDecay);
+  }
+}
+
+void Sema::DefaultFunctionArrayLvalueConversion(Expr *&E) {
+  DefaultFunctionArrayConversion(E);
+
+  QualType Ty = E->getType();
+  assert(!Ty.isNull() && "DefaultFunctionArrayLvalueConversion - missing type");
+  if (!Ty->isDependentType() && Ty.hasQualifiers() &&
+      (!getLangOptions().CPlusPlus || !Ty->isRecordType()) &&
+      E->isLvalue(Context) == Expr::LV_Valid) {
+    // C++ [conv.lval]p1:
+    //   [...] If T is a non-class type, the type of the rvalue is the
+    //   cv-unqualified version of T. Otherwise, the type of the
+    //   rvalue is T
+    //
+    // C99 6.3.2.1p2:
+    //   If the lvalue has qualified type, the value has the unqualified
+    //   version of the type of the lvalue; otherwise, the value has the
+    //   type of the lvalue.
+    ImpCastExprToType(E, Ty.getUnqualifiedType(), CastExpr::CK_NoOp);
+  }
+}
+
+
+/// UsualUnaryConversions - Performs various conversions that are common to most
+/// operators (C99 6.3). The conversions of array and function types are
+/// sometimes surpressed. For example, the array->pointer conversion doesn't
+/// apply if the array is an argument to the sizeof or address (&) operators.
+/// In these instances, this routine should *not* be called.
+Expr *Sema::UsualUnaryConversions(Expr *&Expr) {
+  QualType Ty = Expr->getType();
+  assert(!Ty.isNull() && "UsualUnaryConversions - missing type");
+
+  // C99 6.3.1.1p2:
+  //
+  //   The following may be used in an expression wherever an int or
+  //   unsigned int may be used:
+  //     - an object or expression with an integer type whose integer
+  //       conversion rank is less than or equal to the rank of int
+  //       and unsigned int.
+  //     - A bit-field of type _Bool, int, signed int, or unsigned int.
+  //
+  //   If an int can represent all values of the original type, the
+  //   value is converted to an int; otherwise, it is converted to an
+  //   unsigned int. These are called the integer promotions. All
+  //   other types are unchanged by the integer promotions.
+  QualType PTy = Context.isPromotableBitField(Expr);
+  if (!PTy.isNull()) {
+    ImpCastExprToType(Expr, PTy, CastExpr::CK_IntegralCast);
+    return Expr;
+  }
+  if (Ty->isPromotableIntegerType()) {
+    QualType PT = Context.getPromotedIntegerType(Ty);
+    ImpCastExprToType(Expr, PT, CastExpr::CK_IntegralCast);
+    return Expr;
+  }
+
+  DefaultFunctionArrayLvalueConversion(Expr);
+  return Expr;
+}
+
+/// DefaultArgumentPromotion (C99 6.5.2.2p6). Used for function calls that
+/// do not have a prototype. Arguments that have type float are promoted to
+/// double. All other argument types are converted by UsualUnaryConversions().
+void Sema::DefaultArgumentPromotion(Expr *&Expr) {
+  QualType Ty = Expr->getType();
+  assert(!Ty.isNull() && "DefaultArgumentPromotion - missing type");
+
+  // If this is a 'float' (CVR qualified or typedef) promote to double.
+  if (const BuiltinType *BT = Ty->getAs<BuiltinType>())
+    if (BT->getKind() == BuiltinType::Float)
+      return ImpCastExprToType(Expr, Context.DoubleTy,
+                               CastExpr::CK_FloatingCast);
+
+  UsualUnaryConversions(Expr);
+}
+
+/// DefaultVariadicArgumentPromotion - Like DefaultArgumentPromotion, but
+/// will warn if the resulting type is not a POD type, and rejects ObjC
+/// interfaces passed by value.  This returns true if the argument type is
+/// completely illegal.
+bool Sema::DefaultVariadicArgumentPromotion(Expr *&Expr, VariadicCallType CT) {
+  DefaultArgumentPromotion(Expr);
+
+  if (Expr->getType()->isObjCInterfaceType() &&
+      DiagRuntimeBehavior(Expr->getLocStart(),
+        PDiag(diag::err_cannot_pass_objc_interface_to_vararg)
+          << Expr->getType() << CT))
+    return true;
+
+  if (!Expr->getType()->isPODType() &&
+      DiagRuntimeBehavior(Expr->getLocStart(),
+                          PDiag(diag::warn_cannot_pass_non_pod_arg_to_vararg)
+                            << Expr->getType() << CT))
+    return true;
+
+  return false;
+}
+
+
+/// UsualArithmeticConversions - Performs various conversions that are common to
+/// binary operators (C99 6.3.1.8). If both operands aren't arithmetic, this
+/// routine returns the first non-arithmetic type found. The client is
+/// responsible for emitting appropriate error diagnostics.
+/// FIXME: verify the conversion rules for "complex int" are consistent with
+/// GCC.
+QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr,
+                                          bool isCompAssign) {
+  if (!isCompAssign)
+    UsualUnaryConversions(lhsExpr);
+
+  UsualUnaryConversions(rhsExpr);
+
+  // For conversion purposes, we ignore any qualifiers.
+  // For example, "const float" and "float" are equivalent.
+  QualType lhs =
+    Context.getCanonicalType(lhsExpr->getType()).getUnqualifiedType();
+  QualType rhs =
+    Context.getCanonicalType(rhsExpr->getType()).getUnqualifiedType();
+
+  // If both types are identical, no conversion is needed.
+  if (lhs == rhs)
+    return lhs;
+
+  // If either side is a non-arithmetic type (e.g. a pointer), we are done.
+  // The caller can deal with this (e.g. pointer + int).
+  if (!lhs->isArithmeticType() || !rhs->isArithmeticType())
+    return lhs;
+
+  // Perform bitfield promotions.
+  QualType LHSBitfieldPromoteTy = Context.isPromotableBitField(lhsExpr);
+  if (!LHSBitfieldPromoteTy.isNull())
+    lhs = LHSBitfieldPromoteTy;
+  QualType RHSBitfieldPromoteTy = Context.isPromotableBitField(rhsExpr);
+  if (!RHSBitfieldPromoteTy.isNull())
+    rhs = RHSBitfieldPromoteTy;
+
+  QualType destType = Context.UsualArithmeticConversionsType(lhs, rhs);
+  if (!isCompAssign)
+    ImpCastExprToType(lhsExpr, destType, CastExpr::CK_Unknown);
+  ImpCastExprToType(rhsExpr, destType, CastExpr::CK_Unknown);
+  return destType;
+}
+
+//===----------------------------------------------------------------------===//
+//  Semantic Analysis for various Expression Types
+//===----------------------------------------------------------------------===//
+
+
+/// ActOnStringLiteral - The specified tokens were lexed as pasted string
+/// fragments (e.g. "foo" "bar" L"baz").  The result string has to handle string
+/// concatenation ([C99 5.1.1.2, translation phase #6]), so it may come from
+/// multiple tokens.  However, the common case is that StringToks points to one
+/// string.
+///
+Action::OwningExprResult
+Sema::ActOnStringLiteral(const Token *StringToks, unsigned NumStringToks) {
+  assert(NumStringToks && "Must have at least one string!");
+
+  StringLiteralParser Literal(StringToks, NumStringToks, PP);
+  if (Literal.hadError)
+    return ExprError();
+
+  llvm::SmallVector<SourceLocation, 4> StringTokLocs;
+  for (unsigned i = 0; i != NumStringToks; ++i)
+    StringTokLocs.push_back(StringToks[i].getLocation());
+
+  QualType StrTy = Context.CharTy;
+  if (Literal.AnyWide) StrTy = Context.getWCharType();
+  if (Literal.Pascal) StrTy = Context.UnsignedCharTy;
+
+  // A C++ string literal has a const-qualified element type (C++ 2.13.4p1).
+  if (getLangOptions().CPlusPlus || getLangOptions().ConstStrings )
+    StrTy.addConst();
+
+  // Get an array type for the string, according to C99 6.4.5.  This includes
+  // the nul terminator character as well as the string length for pascal
+  // strings.
+  StrTy = Context.getConstantArrayType(StrTy,
+                                 llvm::APInt(32, Literal.GetNumStringChars()+1),
+                                       ArrayType::Normal, 0);
+
+  // Pass &StringTokLocs[0], StringTokLocs.size() to factory!
+  return Owned(StringLiteral::Create(Context, Literal.GetString(),
+                                     Literal.GetStringLength(),
+                                     Literal.AnyWide, StrTy,
+                                     &StringTokLocs[0],
+                                     StringTokLocs.size()));
+}
+
+/// ShouldSnapshotBlockValueReference - Return true if a reference inside of
+/// CurBlock to VD should cause it to be snapshotted (as we do for auto
+/// variables defined outside the block) or false if this is not needed (e.g.
+/// for values inside the block or for globals).
+///
+/// This also keeps the 'hasBlockDeclRefExprs' in the BlockScopeInfo records
+/// up-to-date.
+///
+static bool ShouldSnapshotBlockValueReference(Sema &S, BlockScopeInfo *CurBlock,
+                                              ValueDecl *VD) {
+  // If the value is defined inside the block, we couldn't snapshot it even if
+  // we wanted to.
+  if (CurBlock->TheDecl == VD->getDeclContext())
+    return false;
+
+  // If this is an enum constant or function, it is constant, don't snapshot.
+  if (isa<EnumConstantDecl>(VD) || isa<FunctionDecl>(VD))
+    return false;
+
+  // If this is a reference to an extern, static, or global variable, no need to
+  // snapshot it.
+  // FIXME: What about 'const' variables in C++?
+  if (const VarDecl *Var = dyn_cast<VarDecl>(VD))
+    if (!Var->hasLocalStorage())
+      return false;
+
+  // Blocks that have these can't be constant.
+  CurBlock->hasBlockDeclRefExprs = true;
+
+  // If we have nested blocks, the decl may be declared in an outer block (in
+  // which case that outer block doesn't get "hasBlockDeclRefExprs") or it may
+  // be defined outside all of the current blocks (in which case the blocks do
+  // all get the bit).  Walk the nesting chain.
+  for (unsigned I = S.FunctionScopes.size() - 1; I; --I) {
+    BlockScopeInfo *NextBlock = dyn_cast<BlockScopeInfo>(S.FunctionScopes[I]);
+
+    if (!NextBlock)
+      continue;
+
+    // If we found the defining block for the variable, don't mark the block as
+    // having a reference outside it.
+    if (NextBlock->TheDecl == VD->getDeclContext())
+      break;
+
+    // Otherwise, the DeclRef from the inner block causes the outer one to need
+    // a snapshot as well.
+    NextBlock->hasBlockDeclRefExprs = true;
+  }
+
+  return true;
+}
+
+
+
+/// BuildDeclRefExpr - Build a DeclRefExpr.
+Sema::OwningExprResult
+Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, SourceLocation Loc,
+                       const CXXScopeSpec *SS) {
+  if (Context.getCanonicalType(Ty) == Context.UndeducedAutoTy) {
+    Diag(Loc,
+         diag::err_auto_variable_cannot_appear_in_own_initializer)
+      << D->getDeclName();
+    return ExprError();
+  }
+
+  if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
+    if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(CurContext)) {
+      if (const FunctionDecl *FD = MD->getParent()->isLocalClass()) {
+        if (VD->hasLocalStorage() && VD->getDeclContext() != CurContext) {
+          Diag(Loc, diag::err_reference_to_local_var_in_enclosing_function)
+            << D->getIdentifier() << FD->getDeclName();
+          Diag(D->getLocation(), diag::note_local_variable_declared_here)
+            << D->getIdentifier();
+          return ExprError();
+        }
+      }
+    }
+  }
+
+  MarkDeclarationReferenced(Loc, D);
+
+  return Owned(DeclRefExpr::Create(Context,
+                              SS? (NestedNameSpecifier *)SS->getScopeRep() : 0,
+                                   SS? SS->getRange() : SourceRange(),
+                                   D, Loc, Ty));
+}
+
+/// getObjectForAnonymousRecordDecl - Retrieve the (unnamed) field or
+/// variable corresponding to the anonymous union or struct whose type
+/// is Record.
+static Decl *getObjectForAnonymousRecordDecl(ASTContext &Context,
+                                             RecordDecl *Record) {
+  assert(Record->isAnonymousStructOrUnion() &&
+         "Record must be an anonymous struct or union!");
+
+  // FIXME: Once Decls are directly linked together, this will be an O(1)
+  // operation rather than a slow walk through DeclContext's vector (which
+  // itself will be eliminated). DeclGroups might make this even better.
+  DeclContext *Ctx = Record->getDeclContext();
+  for (DeclContext::decl_iterator D = Ctx->decls_begin(),
+                               DEnd = Ctx->decls_end();
+       D != DEnd; ++D) {
+    if (*D == Record) {
+      // The object for the anonymous struct/union directly
+      // follows its type in the list of declarations.
+      ++D;
+      assert(D != DEnd && "Missing object for anonymous record");
+      assert(!cast<NamedDecl>(*D)->getDeclName() && "Decl should be unnamed");
+      return *D;
+    }
+  }
+
+  assert(false && "Missing object for anonymous record");
+  return 0;
+}
+
+/// \brief Given a field that represents a member of an anonymous
+/// struct/union, build the path from that field's context to the
+/// actual member.
+///
+/// Construct the sequence of field member references we'll have to
+/// perform to get to the field in the anonymous union/struct. The
+/// list of members is built from the field outward, so traverse it
+/// backwards to go from an object in the current context to the field
+/// we found.
+///
+/// \returns The variable from which the field access should begin,
+/// for an anonymous struct/union that is not a member of another
+/// class. Otherwise, returns NULL.
+VarDecl *Sema::BuildAnonymousStructUnionMemberPath(FieldDecl *Field,
+                                   llvm::SmallVectorImpl<FieldDecl *> &Path) {
+  assert(Field->getDeclContext()->isRecord() &&
+         cast<RecordDecl>(Field->getDeclContext())->isAnonymousStructOrUnion()
+         && "Field must be stored inside an anonymous struct or union");
+
+  Path.push_back(Field);
+  VarDecl *BaseObject = 0;
+  DeclContext *Ctx = Field->getDeclContext();
+  do {
+    RecordDecl *Record = cast<RecordDecl>(Ctx);
+    Decl *AnonObject = getObjectForAnonymousRecordDecl(Context, Record);
+    if (FieldDecl *AnonField = dyn_cast<FieldDecl>(AnonObject))
+      Path.push_back(AnonField);
+    else {
+      BaseObject = cast<VarDecl>(AnonObject);
+      break;
+    }
+    Ctx = Ctx->getParent();
+  } while (Ctx->isRecord() &&
+           cast<RecordDecl>(Ctx)->isAnonymousStructOrUnion());
+
+  return BaseObject;
+}
+
+Sema::OwningExprResult
+Sema::BuildAnonymousStructUnionMemberReference(SourceLocation Loc,
+                                               FieldDecl *Field,
+                                               Expr *BaseObjectExpr,
+                                               SourceLocation OpLoc) {
+  llvm::SmallVector<FieldDecl *, 4> AnonFields;
+  VarDecl *BaseObject = BuildAnonymousStructUnionMemberPath(Field,
+                                                            AnonFields);
+
+  // Build the expression that refers to the base object, from
+  // which we will build a sequence of member references to each
+  // of the anonymous union objects and, eventually, the field we
+  // found via name lookup.
+  bool BaseObjectIsPointer = false;
+  Qualifiers BaseQuals;
+  if (BaseObject) {
+    // BaseObject is an anonymous struct/union variable (and is,
+    // therefore, not part of another non-anonymous record).
+    if (BaseObjectExpr) BaseObjectExpr->Destroy(Context);
+    MarkDeclarationReferenced(Loc, BaseObject);
+    BaseObjectExpr = new (Context) DeclRefExpr(BaseObject,BaseObject->getType(),
+                                               SourceLocation());
+    BaseQuals
+      = Context.getCanonicalType(BaseObject->getType()).getQualifiers();
+  } else if (BaseObjectExpr) {
+    // The caller provided the base object expression. Determine
+    // whether its a pointer and whether it adds any qualifiers to the
+    // anonymous struct/union fields we're looking into.
+    QualType ObjectType = BaseObjectExpr->getType();
+    if (const PointerType *ObjectPtr = ObjectType->getAs<PointerType>()) {
+      BaseObjectIsPointer = true;
+      ObjectType = ObjectPtr->getPointeeType();
+    }
+    BaseQuals
+      = Context.getCanonicalType(ObjectType).getQualifiers();
+  } else {
+    // We've found a member of an anonymous struct/union that is
+    // inside a non-anonymous struct/union, so in a well-formed
+    // program our base object expression is "this".
+    if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(CurContext)) {
+      if (!MD->isStatic()) {
+        QualType AnonFieldType
+          = Context.getTagDeclType(
+                     cast<RecordDecl>(AnonFields.back()->getDeclContext()));
+        QualType ThisType = Context.getTagDeclType(MD->getParent());
+        if ((Context.getCanonicalType(AnonFieldType)
+               == Context.getCanonicalType(ThisType)) ||
+            IsDerivedFrom(ThisType, AnonFieldType)) {
+          // Our base object expression is "this".
+          BaseObjectExpr = new (Context) CXXThisExpr(Loc,
+                                                     MD->getThisType(Context),
+                                                     /*isImplicit=*/true);
+          BaseObjectIsPointer = true;
+        }
+      } else {
+        return ExprError(Diag(Loc,diag::err_invalid_member_use_in_static_method)
+          << Field->getDeclName());
+      }
+      BaseQuals = Qualifiers::fromCVRMask(MD->getTypeQualifiers());
+    }
+
+    if (!BaseObjectExpr)
+      return ExprError(Diag(Loc, diag::err_invalid_non_static_member_use)
+        << Field->getDeclName());
+  }
+
+  // Build the implicit member references to the field of the
+  // anonymous struct/union.
+  Expr *Result = BaseObjectExpr;
+  Qualifiers ResultQuals = BaseQuals;
+  for (llvm::SmallVector<FieldDecl *, 4>::reverse_iterator
+         FI = AnonFields.rbegin(), FIEnd = AnonFields.rend();
+       FI != FIEnd; ++FI) {
+    QualType MemberType = (*FI)->getType();
+    Qualifiers MemberTypeQuals =
+      Context.getCanonicalType(MemberType).getQualifiers();
+
+    // CVR attributes from the base are picked up by members,
+    // except that 'mutable' members don't pick up 'const'.
+    if ((*FI)->isMutable())
+      ResultQuals.removeConst();
+
+    // GC attributes are never picked up by members.
+    ResultQuals.removeObjCGCAttr();
+
+    // TR 18037 does not allow fields to be declared with address spaces.
+    assert(!MemberTypeQuals.hasAddressSpace());
+
+    Qualifiers NewQuals = ResultQuals + MemberTypeQuals;
+    if (NewQuals != MemberTypeQuals)
+      MemberType = Context.getQualifiedType(MemberType, NewQuals);
+
+    MarkDeclarationReferenced(Loc, *FI);
+    PerformObjectMemberConversion(Result, /*FIXME:Qualifier=*/0, *FI, *FI);
+    // FIXME: Might this end up being a qualified name?
+    Result = new (Context) MemberExpr(Result, BaseObjectIsPointer, *FI,
+                                      OpLoc, MemberType);
+    BaseObjectIsPointer = false;
+    ResultQuals = NewQuals;
+  }
+
+  return Owned(Result);
+}
+
+/// Decomposes the given name into a DeclarationName, its location, and
+/// possibly a list of template arguments.
+///
+/// If this produces template arguments, it is permitted to call
+/// DecomposeTemplateName.
+///
+/// This actually loses a lot of source location information for
+/// non-standard name kinds; we should consider preserving that in
+/// some way.
+static void DecomposeUnqualifiedId(Sema &SemaRef,
+                                   const UnqualifiedId &Id,
+                                   TemplateArgumentListInfo &Buffer,
+                                   DeclarationName &Name,
+                                   SourceLocation &NameLoc,
+                             const TemplateArgumentListInfo *&TemplateArgs) {
+  if (Id.getKind() == UnqualifiedId::IK_TemplateId) {
+    Buffer.setLAngleLoc(Id.TemplateId->LAngleLoc);
+    Buffer.setRAngleLoc(Id.TemplateId->RAngleLoc);
+
+    ASTTemplateArgsPtr TemplateArgsPtr(SemaRef,
+                                       Id.TemplateId->getTemplateArgs(),
+                                       Id.TemplateId->NumArgs);
+    SemaRef.translateTemplateArguments(TemplateArgsPtr, Buffer);
+    TemplateArgsPtr.release();
+
+    TemplateName TName =
+      Sema::TemplateTy::make(Id.TemplateId->Template).getAsVal<TemplateName>();
+
+    Name = SemaRef.Context.getNameForTemplate(TName);
+    NameLoc = Id.TemplateId->TemplateNameLoc;
+    TemplateArgs = &Buffer;
+  } else {
+    Name = SemaRef.GetNameFromUnqualifiedId(Id);
+    NameLoc = Id.StartLocation;
+    TemplateArgs = 0;
+  }
+}
+
+/// Decompose the given template name into a list of lookup results.
+///
+/// The unqualified ID must name a non-dependent template, which can
+/// be more easily tested by checking whether DecomposeUnqualifiedId
+/// found template arguments.
+static void DecomposeTemplateName(LookupResult &R, const UnqualifiedId &Id) {
+  assert(Id.getKind() == UnqualifiedId::IK_TemplateId);
+  TemplateName TName =
+    Sema::TemplateTy::make(Id.TemplateId->Template).getAsVal<TemplateName>();
+
+  if (TemplateDecl *TD = TName.getAsTemplateDecl())
+    R.addDecl(TD);
+  else if (OverloadedTemplateStorage *OT = TName.getAsOverloadedTemplate())
+    for (OverloadedTemplateStorage::iterator I = OT->begin(), E = OT->end();
+           I != E; ++I)
+      R.addDecl(*I);
+
+  R.resolveKind();
+}
+
+/// Determines whether the given record is "fully-formed" at the given
+/// location, i.e. whether a qualified lookup into it is assured of
+/// getting consistent results already.
+static bool IsFullyFormedScope(Sema &SemaRef, CXXRecordDecl *Record) {
+  if (!Record->hasDefinition())
+    return false;
+
+  for (CXXRecordDecl::base_class_iterator I = Record->bases_begin(),
+         E = Record->bases_end(); I != E; ++I) {
+    CanQualType BaseT = SemaRef.Context.getCanonicalType((*I).getType());
+    CanQual<RecordType> BaseRT = BaseT->getAs<RecordType>();
+    if (!BaseRT) return false;
+
+    CXXRecordDecl *BaseRecord = cast<CXXRecordDecl>(BaseRT->getDecl());
+    if (!BaseRecord->hasDefinition() ||
+        !IsFullyFormedScope(SemaRef, BaseRecord))
+      return false;
+  }
+
+  return true;
+}
+
+/// Determines whether we can lookup this id-expression now or whether
+/// we have to wait until template instantiation is complete.
+static bool IsDependentIdExpression(Sema &SemaRef, const CXXScopeSpec &SS) {
+  DeclContext *DC = SemaRef.computeDeclContext(SS, false);
+
+  // If the qualifier scope isn't computable, it's definitely dependent.
+  if (!DC) return true;
+
+  // If the qualifier scope doesn't name a record, we can always look into it.
+  if (!isa<CXXRecordDecl>(DC)) return false;
+
+  // We can't look into record types unless they're fully-formed.
+  if (!IsFullyFormedScope(SemaRef, cast<CXXRecordDecl>(DC))) return true;
+
+  return false;
+}
+
+/// Determines if the given class is provably not derived from all of
+/// the prospective base classes.
+static bool IsProvablyNotDerivedFrom(Sema &SemaRef,
+                                     CXXRecordDecl *Record,
+                            const llvm::SmallPtrSet<CXXRecordDecl*, 4> &Bases) {
+  if (Bases.count(Record->getCanonicalDecl()))
+    return false;
+
+  RecordDecl *RD = Record->getDefinition();
+  if (!RD) return false;
+  Record = cast<CXXRecordDecl>(RD);
+
+  for (CXXRecordDecl::base_class_iterator I = Record->bases_begin(),
+         E = Record->bases_end(); I != E; ++I) {
+    CanQualType BaseT = SemaRef.Context.getCanonicalType((*I).getType());
+    CanQual<RecordType> BaseRT = BaseT->getAs<RecordType>();
+    if (!BaseRT) return false;
+
+    CXXRecordDecl *BaseRecord = cast<CXXRecordDecl>(BaseRT->getDecl());
+    if (!IsProvablyNotDerivedFrom(SemaRef, BaseRecord, Bases))
+      return false;
+  }
+
+  return true;
+}
+
+enum IMAKind {
+  /// The reference is definitely not an instance member access.
+  IMA_Static,
+
+  /// The reference may be an implicit instance member access.
+  IMA_Mixed,
+
+  /// The reference may be to an instance member, but it is invalid if
+  /// so, because the context is not an instance method.
+  IMA_Mixed_StaticContext,
+
+  /// The reference may be to an instance member, but it is invalid if
+  /// so, because the context is from an unrelated class.
+  IMA_Mixed_Unrelated,
+
+  /// The reference is definitely an implicit instance member access.
+  IMA_Instance,
+
+  /// The reference may be to an unresolved using declaration.
+  IMA_Unresolved,
+
+  /// The reference may be to an unresolved using declaration and the
+  /// context is not an instance method.
+  IMA_Unresolved_StaticContext,
+
+  /// The reference is to a member of an anonymous structure in a
+  /// non-class context.
+  IMA_AnonymousMember,
+
+  /// All possible referrents are instance members and the current
+  /// context is not an instance method.
+  IMA_Error_StaticContext,
+
+  /// All possible referrents are instance members of an unrelated
+  /// class.
+  IMA_Error_Unrelated
+};
+
+/// The given lookup names class member(s) and is not being used for
+/// an address-of-member expression.  Classify the type of access
+/// according to whether it's possible that this reference names an
+/// instance member.  This is best-effort; it is okay to
+/// conservatively answer "yes", in which case some errors will simply
+/// not be caught until template-instantiation.
+static IMAKind ClassifyImplicitMemberAccess(Sema &SemaRef,
+                                            const LookupResult &R) {
+  assert(!R.empty() && (*R.begin())->isCXXClassMember());
+
+  bool isStaticContext =
+    (!isa<CXXMethodDecl>(SemaRef.CurContext) ||
+     cast<CXXMethodDecl>(SemaRef.CurContext)->isStatic());
+
+  if (R.isUnresolvableResult())
+    return isStaticContext ? IMA_Unresolved_StaticContext : IMA_Unresolved;
+
+  // Collect all the declaring classes of instance members we find.
+  bool hasNonInstance = false;
+  llvm::SmallPtrSet<CXXRecordDecl*, 4> Classes;
+  for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) {
+    NamedDecl *D = *I;
+    if (D->isCXXInstanceMember()) {
+      CXXRecordDecl *R = cast<CXXRecordDecl>(D->getDeclContext());
+
+      // If this is a member of an anonymous record, move out to the
+      // innermost non-anonymous struct or union.  If there isn't one,
+      // that's a special case.
+      while (R->isAnonymousStructOrUnion()) {
+        R = dyn_cast<CXXRecordDecl>(R->getParent());
+        if (!R) return IMA_AnonymousMember;
+      }
+      Classes.insert(R->getCanonicalDecl());
+    }
+    else
+      hasNonInstance = true;
+  }
+
+  // If we didn't find any instance members, it can't be an implicit
+  // member reference.
+  if (Classes.empty())
+    return IMA_Static;
+
+  // If the current context is not an instance method, it can't be
+  // an implicit member reference.
+  if (isStaticContext)
+    return (hasNonInstance ? IMA_Mixed_StaticContext : IMA_Error_StaticContext);
+
+  // If we can prove that the current context is unrelated to all the
+  // declaring classes, it can't be an implicit member reference (in
+  // which case it's an error if any of those members are selected).
+  if (IsProvablyNotDerivedFrom(SemaRef,
+                        cast<CXXMethodDecl>(SemaRef.CurContext)->getParent(),
+                               Classes))
+    return (hasNonInstance ? IMA_Mixed_Unrelated : IMA_Error_Unrelated);
+
+  return (hasNonInstance ? IMA_Mixed : IMA_Instance);
+}
+
+/// Diagnose a reference to a field with no object available.
+static void DiagnoseInstanceReference(Sema &SemaRef,
+                                      const CXXScopeSpec &SS,
+                                      const LookupResult &R) {
+  SourceLocation Loc = R.getNameLoc();
+  SourceRange Range(Loc);
+  if (SS.isSet()) Range.setBegin(SS.getRange().getBegin());
+
+  if (R.getAsSingle<FieldDecl>()) {
+    if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(SemaRef.CurContext)) {
+      if (MD->isStatic()) {
+        // "invalid use of member 'x' in static member function"
+        SemaRef.Diag(Loc, diag::err_invalid_member_use_in_static_method)
+          << Range << R.getLookupName();
+        return;
+      }
+    }
+
+    SemaRef.Diag(Loc, diag::err_invalid_non_static_member_use)
+      << R.getLookupName() << Range;
+    return;
+  }
+
+  SemaRef.Diag(Loc, diag::err_member_call_without_object) << Range;
+}
+
+/// Diagnose an empty lookup.
+///
+/// \return false if new lookup candidates were found
+bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS,
+                               LookupResult &R) {
+  DeclarationName Name = R.getLookupName();
+
+  unsigned diagnostic = diag::err_undeclared_var_use;
+  unsigned diagnostic_suggest = diag::err_undeclared_var_use_suggest;
+  if (Name.getNameKind() == DeclarationName::CXXOperatorName ||
+      Name.getNameKind() == DeclarationName::CXXLiteralOperatorName ||
+      Name.getNameKind() == DeclarationName::CXXConversionFunctionName) {
+    diagnostic = diag::err_undeclared_use;
+    diagnostic_suggest = diag::err_undeclared_use_suggest;
+  }
+
+  // If the original lookup was an unqualified lookup, fake an
+  // unqualified lookup.  This is useful when (for example) the
+  // original lookup would not have found something because it was a
+  // dependent name.
+  for (DeclContext *DC = SS.isEmpty()? CurContext : 0;
+       DC; DC = DC->getParent()) {
+    if (isa<CXXRecordDecl>(DC)) {
+      LookupQualifiedName(R, DC);
+
+      if (!R.empty()) {
+        // Don't give errors about ambiguities in this lookup.
+        R.suppressDiagnostics();
+
+        CXXMethodDecl *CurMethod = dyn_cast<CXXMethodDecl>(CurContext);
+        bool isInstance = CurMethod &&
+                          CurMethod->isInstance() &&
+                          DC == CurMethod->getParent();
+
+        // Give a code modification hint to insert 'this->'.
+        // TODO: fixit for inserting 'Base<T>::' in the other cases.
+        // Actually quite difficult!
+        if (isInstance)
+          Diag(R.getNameLoc(), diagnostic) << Name
+            << FixItHint::CreateInsertion(R.getNameLoc(), "this->");
+        else
+          Diag(R.getNameLoc(), diagnostic) << Name;
+
+        // Do we really want to note all of these?
+        for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I)
+          Diag((*I)->getLocation(), diag::note_dependent_var_use);
+
+        // Tell the callee to try to recover.
+        return false;
+      }
+    }
+  }
+
+  // We didn't find anything, so try to correct for a typo.
+  DeclarationName Corrected;
+  if (S && (Corrected = CorrectTypo(R, S, &SS))) {
+    if (!R.empty()) {
+      if (isa<ValueDecl>(*R.begin()) || isa<FunctionTemplateDecl>(*R.begin())) {
+        if (SS.isEmpty())
+          Diag(R.getNameLoc(), diagnostic_suggest) << Name << R.getLookupName()
+            << FixItHint::CreateReplacement(R.getNameLoc(),
+                                            R.getLookupName().getAsString());
+        else
+          Diag(R.getNameLoc(), diag::err_no_member_suggest)
+            << Name << computeDeclContext(SS, false) << R.getLookupName()
+            << SS.getRange()
+            << FixItHint::CreateReplacement(R.getNameLoc(),
+                                            R.getLookupName().getAsString());
+        if (NamedDecl *ND = R.getAsSingle<NamedDecl>())
+          Diag(ND->getLocation(), diag::note_previous_decl)
+            << ND->getDeclName();
+
+        // Tell the callee to try to recover.
+        return false;
+      }
+    
+      if (isa<TypeDecl>(*R.begin()) || isa<ObjCInterfaceDecl>(*R.begin())) {
+        // FIXME: If we ended up with a typo for a type name or
+        // Objective-C class name, we're in trouble because the parser
+        // is in the wrong place to recover. Suggest the typo
+        // correction, but don't make it a fix-it since we're not going
+        // to recover well anyway.
+        if (SS.isEmpty())
+          Diag(R.getNameLoc(), diagnostic_suggest) << Name << R.getLookupName();
+        else
+          Diag(R.getNameLoc(), diag::err_no_member_suggest)
+            << Name << computeDeclContext(SS, false) << R.getLookupName()
+            << SS.getRange();
+
+        // Don't try to recover; it won't work.
+        return true;
+      }
+    } else {
+      // FIXME: We found a keyword. Suggest it, but don't provide a fix-it 
+      // because we aren't able to recover.
+      if (SS.isEmpty())
+        Diag(R.getNameLoc(), diagnostic_suggest) << Name << Corrected;
+      else
+        Diag(R.getNameLoc(), diag::err_no_member_suggest)
+        << Name << computeDeclContext(SS, false) << Corrected
+        << SS.getRange();
+      return true;
+    }
+    R.clear();
+  }
+
+  // Emit a special diagnostic for failed member lookups.
+  // FIXME: computing the declaration context might fail here (?)
+  if (!SS.isEmpty()) {
+    Diag(R.getNameLoc(), diag::err_no_member)
+      << Name << computeDeclContext(SS, false)
+      << SS.getRange();
+    return true;
+  }
+
+  // Give up, we can't recover.
+  Diag(R.getNameLoc(), diagnostic) << Name;
+  return true;
+}
+
+Sema::OwningExprResult Sema::ActOnIdExpression(Scope *S,
+                                               CXXScopeSpec &SS,
+                                               UnqualifiedId &Id,
+                                               bool HasTrailingLParen,
+                                               bool isAddressOfOperand) {
+  assert(!(isAddressOfOperand && HasTrailingLParen) &&
+         "cannot be direct & operand and have a trailing lparen");
+
+  if (SS.isInvalid())
+    return ExprError();
+
+  TemplateArgumentListInfo TemplateArgsBuffer;
+
+  // Decompose the UnqualifiedId into the following data.
+  DeclarationName Name;
+  SourceLocation NameLoc;
+  const TemplateArgumentListInfo *TemplateArgs;
+  DecomposeUnqualifiedId(*this, Id, TemplateArgsBuffer,
+                         Name, NameLoc, TemplateArgs);
+
+  IdentifierInfo *II = Name.getAsIdentifierInfo();
+
+  // C++ [temp.dep.expr]p3:
+  //   An id-expression is type-dependent if it contains:
+  //     -- an identifier that was declared with a dependent type,
+  //        (note: handled after lookup)
+  //     -- a template-id that is dependent,
+  //        (note: handled in BuildTemplateIdExpr)
+  //     -- a conversion-function-id that specifies a dependent type,
+  //     -- a nested-name-specifier that contains a class-name that
+  //        names a dependent type.
+  // Determine whether this is a member of an unknown specialization;
+  // we need to handle these differently.
+  if ((Name.getNameKind() == DeclarationName::CXXConversionFunctionName &&
+       Name.getCXXNameType()->isDependentType()) ||
+      (SS.isSet() && IsDependentIdExpression(*this, SS))) {
+    return ActOnDependentIdExpression(SS, Name, NameLoc,
+                                      isAddressOfOperand,
+                                      TemplateArgs);
+  }
+
+  // Perform the required lookup.
+  LookupResult R(*this, Name, NameLoc, LookupOrdinaryName);
+  if (TemplateArgs) {
+    // Just re-use the lookup done by isTemplateName.
+    DecomposeTemplateName(R, Id);
+  } else {
+    bool IvarLookupFollowUp = (!SS.isSet() && II && getCurMethodDecl());
+    LookupParsedName(R, S, &SS, !IvarLookupFollowUp);
+
+    // If this reference is in an Objective-C method, then we need to do
+    // some special Objective-C lookup, too.
+    if (IvarLookupFollowUp) {
+      OwningExprResult E(LookupInObjCMethod(R, S, II, true));
+      if (E.isInvalid())
+        return ExprError();
+
+      Expr *Ex = E.takeAs<Expr>();
+      if (Ex) return Owned(Ex);
+    }
+  }
+
+  if (R.isAmbiguous())
+    return ExprError();
+
+  // Determine whether this name might be a candidate for
+  // argument-dependent lookup.
+  bool ADL = UseArgumentDependentLookup(SS, R, HasTrailingLParen);
+
+  if (R.empty() && !ADL) {
+    // Otherwise, this could be an implicitly declared function reference (legal
+    // in C90, extension in C99, forbidden in C++).
+    if (HasTrailingLParen && II && !getLangOptions().CPlusPlus) {
+      NamedDecl *D = ImplicitlyDefineFunction(NameLoc, *II, S);
+      if (D) R.addDecl(D);
+    }
+
+    // If this name wasn't predeclared and if this is not a function
+    // call, diagnose the problem.
+    if (R.empty()) {
+      if (DiagnoseEmptyLookup(S, SS, R))
+        return ExprError();
+
+      assert(!R.empty() &&
+             "DiagnoseEmptyLookup returned false but added no results");
+
+      // If we found an Objective-C instance variable, let
+      // LookupInObjCMethod build the appropriate expression to
+      // reference the ivar.
+      if (ObjCIvarDecl *Ivar = R.getAsSingle<ObjCIvarDecl>()) {
+        R.clear();
+        OwningExprResult E(LookupInObjCMethod(R, S, Ivar->getIdentifier()));
+        assert(E.isInvalid() || E.get());
+        return move(E);
+      }
+    }
+  }
+
+  // This is guaranteed from this point on.
+  assert(!R.empty() || ADL);
+
+  if (VarDecl *Var = R.getAsSingle<VarDecl>()) {
+    // Warn about constructs like:
+    //   if (void *X = foo()) { ... } else { X }.
+    // In the else block, the pointer is always false.
+    if (Var->isDeclaredInCondition() && Var->getType()->isScalarType()) {
+      Scope *CheckS = S;
+      while (CheckS && CheckS->getControlParent()) {
+        if ((CheckS->getFlags() & Scope::ElseScope) &&
+            CheckS->getControlParent()->isDeclScope(DeclPtrTy::make(Var))) {
+          ExprError(Diag(NameLoc, diag::warn_value_always_zero)
+            << Var->getDeclName()
+            << (Var->getType()->isPointerType() ? 2 :
+                Var->getType()->isBooleanType() ? 1 : 0));
+          break;
+        }
+
+        // Move to the parent of this scope.
+        CheckS = CheckS->getParent();
+      }
+    }
+  } else if (FunctionDecl *Func = R.getAsSingle<FunctionDecl>()) {
+    if (!getLangOptions().CPlusPlus && !Func->hasPrototype()) {
+      // C99 DR 316 says that, if a function type comes from a
+      // function definition (without a prototype), that type is only
+      // used for checking compatibility. Therefore, when referencing
+      // the function, we pretend that we don't have the full function
+      // type.
+      if (DiagnoseUseOfDecl(Func, NameLoc))
+        return ExprError();
+
+      QualType T = Func->getType();
+      QualType NoProtoType = T;
+      if (const FunctionProtoType *Proto = T->getAs<FunctionProtoType>())
+        NoProtoType = Context.getFunctionNoProtoType(Proto->getResultType());
+      return BuildDeclRefExpr(Func, NoProtoType, NameLoc, &SS);
+    }
+  }
+
+  // Check whether this might be a C++ implicit instance member access.
+  // C++ [expr.prim.general]p6:
+  //   Within the definition of a non-static member function, an
+  //   identifier that names a non-static member is transformed to a
+  //   class member access expression.
+  // But note that &SomeClass::foo is grammatically distinct, even
+  // though we don't parse it that way.
+  if (!R.empty() && (*R.begin())->isCXXClassMember()) {
+    bool isAbstractMemberPointer = (isAddressOfOperand && !SS.isEmpty());
+    if (!isAbstractMemberPointer)
+      return BuildPossibleImplicitMemberExpr(SS, R, TemplateArgs);
+  }
+
+  if (TemplateArgs)
+    return BuildTemplateIdExpr(SS, R, ADL, *TemplateArgs);
+
+  return BuildDeclarationNameExpr(SS, R, ADL);
+}
+
+/// Builds an expression which might be an implicit member expression.
+Sema::OwningExprResult
+Sema::BuildPossibleImplicitMemberExpr(const CXXScopeSpec &SS,
+                                      LookupResult &R,
+                                const TemplateArgumentListInfo *TemplateArgs) {
+  switch (ClassifyImplicitMemberAccess(*this, R)) {
+  case IMA_Instance:
+    return BuildImplicitMemberExpr(SS, R, TemplateArgs, true);
+
+  case IMA_AnonymousMember:
+    assert(R.isSingleResult());
+    return BuildAnonymousStructUnionMemberReference(R.getNameLoc(),
+                                                    R.getAsSingle<FieldDecl>());
+
+  case IMA_Mixed:
+  case IMA_Mixed_Unrelated:
+  case IMA_Unresolved:
+    return BuildImplicitMemberExpr(SS, R, TemplateArgs, false);
+
+  case IMA_Static:
+  case IMA_Mixed_StaticContext:
+  case IMA_Unresolved_StaticContext:
+    if (TemplateArgs)
+      return BuildTemplateIdExpr(SS, R, false, *TemplateArgs);
+    return BuildDeclarationNameExpr(SS, R, false);
+
+  case IMA_Error_StaticContext:
+  case IMA_Error_Unrelated:
+    DiagnoseInstanceReference(*this, SS, R);
+    return ExprError();
+  }
+
+  llvm_unreachable("unexpected instance member access kind");
+  return ExprError();
+}
+
+/// BuildQualifiedDeclarationNameExpr - Build a C++ qualified
+/// declaration name, generally during template instantiation.
+/// There's a large number of things which don't need to be done along
+/// this path.
+Sema::OwningExprResult
+Sema::BuildQualifiedDeclarationNameExpr(CXXScopeSpec &SS,
+                                        DeclarationName Name,
+                                        SourceLocation NameLoc) {
+  DeclContext *DC;
+  if (!(DC = computeDeclContext(SS, false)) ||
+      DC->isDependentContext() ||
+      RequireCompleteDeclContext(SS))
+    return BuildDependentDeclRefExpr(SS, Name, NameLoc, 0);
+
+  LookupResult R(*this, Name, NameLoc, LookupOrdinaryName);
+  LookupQualifiedName(R, DC);
+
+  if (R.isAmbiguous())
+    return ExprError();
+
+  if (R.empty()) {
+    Diag(NameLoc, diag::err_no_member) << Name << DC << SS.getRange();
+    return ExprError();
+  }
+
+  return BuildDeclarationNameExpr(SS, R, /*ADL*/ false);
+}
+
+/// LookupInObjCMethod - The parser has read a name in, and Sema has
+/// detected that we're currently inside an ObjC method.  Perform some
+/// additional lookup.
+///
+/// Ideally, most of this would be done by lookup, but there's
+/// actually quite a lot of extra work involved.
+///
+/// Returns a null sentinel to indicate trivial success.
+Sema::OwningExprResult
+Sema::LookupInObjCMethod(LookupResult &Lookup, Scope *S,
+                         IdentifierInfo *II, bool AllowBuiltinCreation) {
+  SourceLocation Loc = Lookup.getNameLoc();
+  ObjCMethodDecl *CurMethod = getCurMethodDecl();
+  
+  // There are two cases to handle here.  1) scoped lookup could have failed,
+  // in which case we should look for an ivar.  2) scoped lookup could have
+  // found a decl, but that decl is outside the current instance method (i.e.
+  // a global variable).  In these two cases, we do a lookup for an ivar with
+  // this name, if the lookup sucedes, we replace it our current decl.
+
+  // If we're in a class method, we don't normally want to look for
+  // ivars.  But if we don't find anything else, and there's an
+  // ivar, that's an error.
+  bool IsClassMethod = CurMethod->isClassMethod();
+
+  bool LookForIvars;
+  if (Lookup.empty())
+    LookForIvars = true;
+  else if (IsClassMethod)
+    LookForIvars = false;
+  else
+    LookForIvars = (Lookup.isSingleResult() &&
+                    Lookup.getFoundDecl()->isDefinedOutsideFunctionOrMethod());
+  ObjCInterfaceDecl *IFace = 0;
+  if (LookForIvars) {
+    IFace = CurMethod->getClassInterface();
+    ObjCInterfaceDecl *ClassDeclared;
+    if (ObjCIvarDecl *IV = IFace->lookupInstanceVariable(II, ClassDeclared)) {
+      // Diagnose using an ivar in a class method.
+      if (IsClassMethod)
+        return ExprError(Diag(Loc, diag::error_ivar_use_in_class_method)
+                         << IV->getDeclName());
+
+      // If we're referencing an invalid decl, just return this as a silent
+      // error node.  The error diagnostic was already emitted on the decl.
+      if (IV->isInvalidDecl())
+        return ExprError();
+
+      // Check if referencing a field with __attribute__((deprecated)).
+      if (DiagnoseUseOfDecl(IV, Loc))
+        return ExprError();
+
+      // Diagnose the use of an ivar outside of the declaring class.
+      if (IV->getAccessControl() == ObjCIvarDecl::Private &&
+          ClassDeclared != IFace)
+        Diag(Loc, diag::error_private_ivar_access) << IV->getDeclName();
+
+      // FIXME: This should use a new expr for a direct reference, don't
+      // turn this into Self->ivar, just return a BareIVarExpr or something.
+      IdentifierInfo &II = Context.Idents.get("self");
+      UnqualifiedId SelfName;
+      SelfName.setIdentifier(&II, SourceLocation());
+      CXXScopeSpec SelfScopeSpec;
+      OwningExprResult SelfExpr = ActOnIdExpression(S, SelfScopeSpec,
+                                                    SelfName, false, false);
+      MarkDeclarationReferenced(Loc, IV);
+      return Owned(new (Context)
+                   ObjCIvarRefExpr(IV, IV->getType(), Loc,
+                                   SelfExpr.takeAs<Expr>(), true, true));
+    }
+  } else if (CurMethod->isInstanceMethod()) {
+    // We should warn if a local variable hides an ivar.
+    ObjCInterfaceDecl *IFace = CurMethod->getClassInterface();
+    ObjCInterfaceDecl *ClassDeclared;
+    if (ObjCIvarDecl *IV = IFace->lookupInstanceVariable(II, ClassDeclared)) {
+      if (IV->getAccessControl() != ObjCIvarDecl::Private ||
+          IFace == ClassDeclared)
+        Diag(Loc, diag::warn_ivar_use_hidden) << IV->getDeclName();
+    }
+  }
+
+  if (Lookup.empty() && II && AllowBuiltinCreation) {
+    // FIXME. Consolidate this with similar code in LookupName.
+    if (unsigned BuiltinID = II->getBuiltinID()) {
+      if (!(getLangOptions().CPlusPlus &&
+            Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID))) {
+        NamedDecl *D = LazilyCreateBuiltin((IdentifierInfo *)II, BuiltinID,
+                                           S, Lookup.isForRedeclaration(),
+                                           Lookup.getNameLoc());
+        if (D) Lookup.addDecl(D);
+      }
+    }
+  }
+  // Sentinel value saying that we didn't do anything special.
+  return Owned((Expr*) 0);
+}
+
+/// \brief Cast a base object to a member's actual type.
+///
+/// Logically this happens in three phases:
+///
+/// * First we cast from the base type to the naming class.
+///   The naming class is the class into which we were looking
+///   when we found the member;  it's the qualifier type if a
+///   qualifier was provided, and otherwise it's the base type.
+///
+/// * Next we cast from the naming class to the declaring class.
+///   If the member we found was brought into a class's scope by
+///   a using declaration, this is that class;  otherwise it's
+///   the class declaring the member.
+///
+/// * Finally we cast from the declaring class to the "true"
+///   declaring class of the member.  This conversion does not
+///   obey access control.
+bool
+Sema::PerformObjectMemberConversion(Expr *&From,
+                                    NestedNameSpecifier *Qualifier,
+                                    NamedDecl *FoundDecl,
+                                    NamedDecl *Member) {
+  CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(Member->getDeclContext());
+  if (!RD)
+    return false;
+
+  QualType DestRecordType;
+  QualType DestType;
+  QualType FromRecordType;
+  QualType FromType = From->getType();
+  bool PointerConversions = false;
+  if (isa<FieldDecl>(Member)) {
+    DestRecordType = Context.getCanonicalType(Context.getTypeDeclType(RD));
+
+    if (FromType->getAs<PointerType>()) {
+      DestType = Context.getPointerType(DestRecordType);
+      FromRecordType = FromType->getPointeeType();
+      PointerConversions = true;
+    } else {
+      DestType = DestRecordType;
+      FromRecordType = FromType;
+    }
+  } else if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Member)) {
+    if (Method->isStatic())
+      return false;
+
+    DestType = Method->getThisType(Context);
+    DestRecordType = DestType->getPointeeType();
+
+    if (FromType->getAs<PointerType>()) {
+      FromRecordType = FromType->getPointeeType();
+      PointerConversions = true;
+    } else {
+      FromRecordType = FromType;
+      DestType = DestRecordType;
+    }
+  } else {
+    // No conversion necessary.
+    return false;
+  }
+
+  if (DestType->isDependentType() || FromType->isDependentType())
+    return false;
+
+  // If the unqualified types are the same, no conversion is necessary.
+  if (Context.hasSameUnqualifiedType(FromRecordType, DestRecordType))
+    return false;
+
+  SourceRange FromRange = From->getSourceRange();
+  SourceLocation FromLoc = FromRange.getBegin();
+
+  // C++ [class.member.lookup]p8:
+  //   [...] Ambiguities can often be resolved by qualifying a name with its
+  //   class name.
+  //
+  // If the member was a qualified name and the qualified referred to a
+  // specific base subobject type, we'll cast to that intermediate type
+  // first and then to the object in which the member is declared. That allows
+  // one to resolve ambiguities in, e.g., a diamond-shaped hierarchy such as:
+  //
+  //   class Base { public: int x; };
+  //   class Derived1 : public Base { };
+  //   class Derived2 : public Base { };
+  //   class VeryDerived : public Derived1, public Derived2 { void f(); };
+  //
+  //   void VeryDerived::f() {
+  //     x = 17; // error: ambiguous base subobjects
+  //     Derived1::x = 17; // okay, pick the Base subobject of Derived1
+  //   }
+  if (Qualifier) {
+    QualType QType = QualType(Qualifier->getAsType(), 0);
+    assert(!QType.isNull() && "lookup done with dependent qualifier?");
+    assert(QType->isRecordType() && "lookup done with non-record type");
+
+    QualType QRecordType = QualType(QType->getAs<RecordType>(), 0);
+
+    // In C++98, the qualifier type doesn't actually have to be a base
+    // type of the object type, in which case we just ignore it.
+    // Otherwise build the appropriate casts.
+    if (IsDerivedFrom(FromRecordType, QRecordType)) {
+      CXXBaseSpecifierArray BasePath;
+      if (CheckDerivedToBaseConversion(FromRecordType, QRecordType,
+                                       FromLoc, FromRange, &BasePath))
+        return true;
+
+      if (PointerConversions)
+        QType = Context.getPointerType(QType);
+      ImpCastExprToType(From, QType, CastExpr::CK_UncheckedDerivedToBase,
+                        /*isLvalue=*/!PointerConversions, BasePath);
+
+      FromType = QType;
+      FromRecordType = QRecordType;
+
+      // If the qualifier type was the same as the destination type,
+      // we're done.
+      if (Context.hasSameUnqualifiedType(FromRecordType, DestRecordType))
+        return false;
+    }
+  }
+
+  bool IgnoreAccess = false;
+
+  // If we actually found the member through a using declaration, cast
+  // down to the using declaration's type.
+  //
+  // Pointer equality is fine here because only one declaration of a
+  // class ever has member declarations.
+  if (FoundDecl->getDeclContext() != Member->getDeclContext()) {
+    assert(isa<UsingShadowDecl>(FoundDecl));
+    QualType URecordType = Context.getTypeDeclType(
+                           cast<CXXRecordDecl>(FoundDecl->getDeclContext()));
+
+    // We only need to do this if the naming-class to declaring-class
+    // conversion is non-trivial.
+    if (!Context.hasSameUnqualifiedType(FromRecordType, URecordType)) {
+      assert(IsDerivedFrom(FromRecordType, URecordType));
+      CXXBaseSpecifierArray BasePath;
+      if (CheckDerivedToBaseConversion(FromRecordType, URecordType,
+                                       FromLoc, FromRange, &BasePath))
+        return true;
+      
+      QualType UType = URecordType;
+      if (PointerConversions)
+        UType = Context.getPointerType(UType);
+      ImpCastExprToType(From, UType, CastExpr::CK_UncheckedDerivedToBase,
+                        /*isLvalue=*/!PointerConversions, BasePath);
+      FromType = UType;
+      FromRecordType = URecordType;
+    }
+
+    // We don't do access control for the conversion from the
+    // declaring class to the true declaring class.
+    IgnoreAccess = true;
+  }
+
+  CXXBaseSpecifierArray BasePath;
+  if (CheckDerivedToBaseConversion(FromRecordType, DestRecordType,
+                                   FromLoc, FromRange, &BasePath,
+                                   IgnoreAccess))
+    return true;
+
+  ImpCastExprToType(From, DestType, CastExpr::CK_UncheckedDerivedToBase,
+                    /*isLvalue=*/!PointerConversions, BasePath);
+  return false;
+}
+
+/// \brief Build a MemberExpr AST node.
+static MemberExpr *BuildMemberExpr(ASTContext &C, Expr *Base, bool isArrow,
+                                   const CXXScopeSpec &SS, ValueDecl *Member,
+                                   DeclAccessPair FoundDecl,
+                                   SourceLocation Loc, QualType Ty,
+                          const TemplateArgumentListInfo *TemplateArgs = 0) {
+  NestedNameSpecifier *Qualifier = 0;
+  SourceRange QualifierRange;
+  if (SS.isSet()) {
+    Qualifier = (NestedNameSpecifier *) SS.getScopeRep();
+    QualifierRange = SS.getRange();
+  }
+
+  return MemberExpr::Create(C, Base, isArrow, Qualifier, QualifierRange,
+                            Member, FoundDecl, Loc, TemplateArgs, Ty);
+}
+
+/// Builds an implicit member access expression.  The current context
+/// is known to be an instance method, and the given unqualified lookup
+/// set is known to contain only instance members, at least one of which
+/// is from an appropriate type.
+Sema::OwningExprResult
+Sema::BuildImplicitMemberExpr(const CXXScopeSpec &SS,
+                              LookupResult &R,
+                              const TemplateArgumentListInfo *TemplateArgs,
+                              bool IsKnownInstance) {
+  assert(!R.empty() && !R.isAmbiguous());
+
+  SourceLocation Loc = R.getNameLoc();
+
+  // We may have found a field within an anonymous union or struct
+  // (C++ [class.union]).
+  // FIXME: This needs to happen post-isImplicitMemberReference?
+  // FIXME: template-ids inside anonymous structs?
+  if (FieldDecl *FD = R.getAsSingle<FieldDecl>())
+    if (cast<RecordDecl>(FD->getDeclContext())->isAnonymousStructOrUnion())
+      return BuildAnonymousStructUnionMemberReference(Loc, FD);
+
+  // If this is known to be an instance access, go ahead and build a
+  // 'this' expression now.
+  QualType ThisType = cast<CXXMethodDecl>(CurContext)->getThisType(Context);
+  Expr *This = 0; // null signifies implicit access
+  if (IsKnownInstance) {
+    SourceLocation Loc = R.getNameLoc();
+    if (SS.getRange().isValid())
+      Loc = SS.getRange().getBegin();
+    This = new (Context) CXXThisExpr(Loc, ThisType, /*isImplicit=*/true);
+  }
+
+  return BuildMemberReferenceExpr(ExprArg(*this, This), ThisType,
+                                  /*OpLoc*/ SourceLocation(),
+                                  /*IsArrow*/ true,
+                                  SS,
+                                  /*FirstQualifierInScope*/ 0,
+                                  R, TemplateArgs);
+}
+
+bool Sema::UseArgumentDependentLookup(const CXXScopeSpec &SS,
+                                      const LookupResult &R,
+                                      bool HasTrailingLParen) {
+  // Only when used directly as the postfix-expression of a call.
+  if (!HasTrailingLParen)
+    return false;
+
+  // Never if a scope specifier was provided.
+  if (SS.isSet())
+    return false;
+
+  // Only in C++ or ObjC++.
+  if (!getLangOptions().CPlusPlus)
+    return false;
+
+  // Turn off ADL when we find certain kinds of declarations during
+  // normal lookup:
+  for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) {
+    NamedDecl *D = *I;
+
+    // C++0x [basic.lookup.argdep]p3:
+    //     -- a declaration of a class member
+    // Since using decls preserve this property, we check this on the
+    // original decl.
+    if (D->isCXXClassMember())
+      return false;
+
+    // C++0x [basic.lookup.argdep]p3:
+    //     -- a block-scope function declaration that is not a
+    //        using-declaration
+    // NOTE: we also trigger this for function templates (in fact, we
+    // don't check the decl type at all, since all other decl types
+    // turn off ADL anyway).
+    if (isa<UsingShadowDecl>(D))
+      D = cast<UsingShadowDecl>(D)->getTargetDecl();
+    else if (D->getDeclContext()->isFunctionOrMethod())
+      return false;
+
+    // C++0x [basic.lookup.argdep]p3:
+    //     -- a declaration that is neither a function or a function
+    //        template
+    // And also for builtin functions.
+    if (isa<FunctionDecl>(D)) {
+      FunctionDecl *FDecl = cast<FunctionDecl>(D);
+
+      // But also builtin functions.
+      if (FDecl->getBuiltinID() && FDecl->isImplicit())
+        return false;
+    } else if (!isa<FunctionTemplateDecl>(D))
+      return false;
+  }
+
+  return true;
+}
+
+
+/// Diagnoses obvious problems with the use of the given declaration
+/// as an expression.  This is only actually called for lookups that
+/// were not overloaded, and it doesn't promise that the declaration
+/// will in fact be used.
+static bool CheckDeclInExpr(Sema &S, SourceLocation Loc, NamedDecl *D) {
+  if (isa<TypedefDecl>(D)) {
+    S.Diag(Loc, diag::err_unexpected_typedef) << D->getDeclName();
+    return true;
+  }
+
+  if (isa<ObjCInterfaceDecl>(D)) {
+    S.Diag(Loc, diag::err_unexpected_interface) << D->getDeclName();
+    return true;
+  }
+
+  if (isa<NamespaceDecl>(D)) {
+    S.Diag(Loc, diag::err_unexpected_namespace) << D->getDeclName();
+    return true;
+  }
+
+  return false;
+}
+
+Sema::OwningExprResult
+Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS,
+                               LookupResult &R,
+                               bool NeedsADL) {
+  // If this is a single, fully-resolved result and we don't need ADL,
+  // just build an ordinary singleton decl ref.
+  if (!NeedsADL && R.isSingleResult() && !R.getAsSingle<FunctionTemplateDecl>())
+    return BuildDeclarationNameExpr(SS, R.getNameLoc(), R.getFoundDecl());
+
+  // We only need to check the declaration if there's exactly one
+  // result, because in the overloaded case the results can only be
+  // functions and function templates.
+  if (R.isSingleResult() &&
+      CheckDeclInExpr(*this, R.getNameLoc(), R.getFoundDecl()))
+    return ExprError();
+
+  // Otherwise, just build an unresolved lookup expression.  Suppress
+  // any lookup-related diagnostics; we'll hash these out later, when
+  // we've picked a target.
+  R.suppressDiagnostics();
+
+  bool Dependent
+    = UnresolvedLookupExpr::ComputeDependence(R.begin(), R.end(), 0);
+  UnresolvedLookupExpr *ULE
+    = UnresolvedLookupExpr::Create(Context, Dependent, R.getNamingClass(),
+                                   (NestedNameSpecifier*) SS.getScopeRep(),
+                                   SS.getRange(),
+                                   R.getLookupName(), R.getNameLoc(),
+                                   NeedsADL, R.isOverloadedResult());
+  ULE->addDecls(R.begin(), R.end());
+
+  return Owned(ULE);
+}
+
+
+/// \brief Complete semantic analysis for a reference to the given declaration.
+Sema::OwningExprResult
+Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS,
+                               SourceLocation Loc, NamedDecl *D) {
+  assert(D && "Cannot refer to a NULL declaration");
+  assert(!isa<FunctionTemplateDecl>(D) &&
+         "Cannot refer unambiguously to a function template");
+
+  if (CheckDeclInExpr(*this, Loc, D))
+    return ExprError();
+
+  if (TemplateDecl *Template = dyn_cast<TemplateDecl>(D)) {
+    // Specifically diagnose references to class templates that are missing
+    // a template argument list.
+    Diag(Loc, diag::err_template_decl_ref)
+      << Template << SS.getRange();
+    Diag(Template->getLocation(), diag::note_template_decl_here);
+    return ExprError();
+  }
+
+  // Make sure that we're referring to a value.
+  ValueDecl *VD = dyn_cast<ValueDecl>(D);
+  if (!VD) {
+    Diag(Loc, diag::err_ref_non_value)
+      << D << SS.getRange();
+    Diag(D->getLocation(), diag::note_declared_at);
+    return ExprError();
+  }
+
+  // Check whether this declaration can be used. Note that we suppress
+  // this check when we're going to perform argument-dependent lookup
+  // on this function name, because this might not be the function
+  // that overload resolution actually selects.
+  if (DiagnoseUseOfDecl(VD, Loc))
+    return ExprError();
+
+  // Only create DeclRefExpr's for valid Decl's.
+  if (VD->isInvalidDecl())
+    return ExprError();
+
+  // If the identifier reference is inside a block, and it refers to a value
+  // that is outside the block, create a BlockDeclRefExpr instead of a
+  // DeclRefExpr.  This ensures the value is treated as a copy-in snapshot when
+  // the block is formed.
+  //
+  // We do not do this for things like enum constants, global variables, etc,
+  // as they do not get snapshotted.
+  //
+  if (getCurBlock() &&
+      ShouldSnapshotBlockValueReference(*this, getCurBlock(), VD)) {
+    if (VD->getType().getTypePtr()->isVariablyModifiedType()) {
+      Diag(Loc, diag::err_ref_vm_type);
+      Diag(D->getLocation(), diag::note_declared_at);
+      return ExprError();
+    }
+
+    if (VD->getType()->isArrayType()) {
+      Diag(Loc, diag::err_ref_array_type);
+      Diag(D->getLocation(), diag::note_declared_at);
+      return ExprError();
+    }
+
+    MarkDeclarationReferenced(Loc, VD);
+    QualType ExprTy = VD->getType().getNonReferenceType();
+    // The BlocksAttr indicates the variable is bound by-reference.
+    if (VD->getAttr<BlocksAttr>())
+      return Owned(new (Context) BlockDeclRefExpr(VD, ExprTy, Loc, true));
+    // This is to record that a 'const' was actually synthesize and added.
+    bool constAdded = !ExprTy.isConstQualified();
+    // Variable will be bound by-copy, make it const within the closure.
+
+    ExprTy.addConst();
+    return Owned(new (Context) BlockDeclRefExpr(VD, ExprTy, Loc, false,
+                                                constAdded));
+  }
+  // If this reference is not in a block or if the referenced variable is
+  // within the block, create a normal DeclRefExpr.
+
+  return BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), Loc, &SS);
+}
+
+Sema::OwningExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc,
+                                                 tok::TokenKind Kind) {
+  PredefinedExpr::IdentType IT;
+
+  switch (Kind) {
+  default: assert(0 && "Unknown simple primary expr!");
+  case tok::kw___func__: IT = PredefinedExpr::Func; break; // [C99 6.4.2.2]
+  case tok::kw___FUNCTION__: IT = PredefinedExpr::Function; break;
+  case tok::kw___PRETTY_FUNCTION__: IT = PredefinedExpr::PrettyFunction; break;
+  }
+
+  // Pre-defined identifiers are of type char[x], where x is the length of the
+  // string.
+
+  Decl *currentDecl = getCurFunctionOrMethodDecl();
+  if (!currentDecl) {
+    Diag(Loc, diag::ext_predef_outside_function);
+    currentDecl = Context.getTranslationUnitDecl();
+  }
+
+  QualType ResTy;
+  if (cast<DeclContext>(currentDecl)->isDependentContext()) {
+    ResTy = Context.DependentTy;
+  } else {
+    unsigned Length = PredefinedExpr::ComputeName(IT, currentDecl).length();
+
+    llvm::APInt LengthI(32, Length + 1);
+    ResTy = Context.CharTy.withConst();
+    ResTy = Context.getConstantArrayType(ResTy, LengthI, ArrayType::Normal, 0);
+  }
+  return Owned(new (Context) PredefinedExpr(Loc, ResTy, IT));
+}
+
+Sema::OwningExprResult Sema::ActOnCharacterConstant(const Token &Tok) {
+  llvm::SmallString<16> CharBuffer;
+  bool Invalid = false;
+  llvm::StringRef ThisTok = PP.getSpelling(Tok, CharBuffer, &Invalid);
+  if (Invalid)
+    return ExprError();
+
+  CharLiteralParser Literal(ThisTok.begin(), ThisTok.end(), Tok.getLocation(),
+                            PP);
+  if (Literal.hadError())
+    return ExprError();
+
+  QualType Ty;
+  if (!getLangOptions().CPlusPlus)
+    Ty = Context.IntTy;   // 'x' and L'x' -> int in C.
+  else if (Literal.isWide())
+    Ty = Context.WCharTy; // L'x' -> wchar_t in C++.
+  else if (Literal.isMultiChar())
+    Ty = Context.IntTy;   // 'wxyz' -> int in C++.
+  else
+    Ty = Context.CharTy;  // 'x' -> char in C++
+
+  return Owned(new (Context) CharacterLiteral(Literal.getValue(),
+                                              Literal.isWide(),
+                                              Ty, Tok.getLocation()));
+}
+
+Action::OwningExprResult Sema::ActOnNumericConstant(const Token &Tok) {
+  // Fast path for a single digit (which is quite common).  A single digit
+  // cannot have a trigraph, escaped newline, radix prefix, or type suffix.
+  if (Tok.getLength() == 1) {
+    const char Val = PP.getSpellingOfSingleCharacterNumericConstant(Tok);
+    unsigned IntSize = Context.Target.getIntWidth();
+    return Owned(new (Context) IntegerLiteral(llvm::APInt(IntSize, Val-'0'),
+                    Context.IntTy, Tok.getLocation()));
+  }
+
+  llvm::SmallString<512> IntegerBuffer;
+  // Add padding so that NumericLiteralParser can overread by one character.
+  IntegerBuffer.resize(Tok.getLength()+1);
+  const char *ThisTokBegin = &IntegerBuffer[0];
+
+  // Get the spelling of the token, which eliminates trigraphs, etc.
+  bool Invalid = false;
+  unsigned ActualLength = PP.getSpelling(Tok, ThisTokBegin, &Invalid);
+  if (Invalid)
+    return ExprError();
+
+  NumericLiteralParser Literal(ThisTokBegin, ThisTokBegin+ActualLength,
+                               Tok.getLocation(), PP);
+  if (Literal.hadError)
+    return ExprError();
+
+  Expr *Res;
+
+  if (Literal.isFloatingLiteral()) {
+    QualType Ty;
+    if (Literal.isFloat)
+      Ty = Context.FloatTy;
+    else if (!Literal.isLong)
+      Ty = Context.DoubleTy;
+    else
+      Ty = Context.LongDoubleTy;
+
+    const llvm::fltSemantics &Format = Context.getFloatTypeSemantics(Ty);
+
+    using llvm::APFloat;
+    APFloat Val(Format);
+
+    APFloat::opStatus result = Literal.GetFloatValue(Val);
+
+    // Overflow is always an error, but underflow is only an error if
+    // we underflowed to zero (APFloat reports denormals as underflow).
+    if ((result & APFloat::opOverflow) ||
+        ((result & APFloat::opUnderflow) && Val.isZero())) {
+      unsigned diagnostic;
+      llvm::SmallString<20> buffer;
+      if (result & APFloat::opOverflow) {
+        diagnostic = diag::warn_float_overflow;
+        APFloat::getLargest(Format).toString(buffer);
+      } else {
+        diagnostic = diag::warn_float_underflow;
+        APFloat::getSmallest(Format).toString(buffer);
+      }
+
+      Diag(Tok.getLocation(), diagnostic)
+        << Ty
+        << llvm::StringRef(buffer.data(), buffer.size());
+    }
+
+    bool isExact = (result == APFloat::opOK);
+    Res = new (Context) FloatingLiteral(Val, isExact, Ty, Tok.getLocation());
+
+  } else if (!Literal.isIntegerLiteral()) {
+    return ExprError();
+  } else {
+    QualType Ty;
+
+    // long long is a C99 feature.
+    if (!getLangOptions().C99 && !getLangOptions().CPlusPlus0x &&
+        Literal.isLongLong)
+      Diag(Tok.getLocation(), diag::ext_longlong);
+
+    // Get the value in the widest-possible width.
+    llvm::APInt ResultVal(Context.Target.getIntMaxTWidth(), 0);
+
+    if (Literal.GetIntegerValue(ResultVal)) {
+      // If this value didn't fit into uintmax_t, warn and force to ull.
+      Diag(Tok.getLocation(), diag::warn_integer_too_large);
+      Ty = Context.UnsignedLongLongTy;
+      assert(Context.getTypeSize(Ty) == ResultVal.getBitWidth() &&
+             "long long is not intmax_t?");
+    } else {
+      // If this value fits into a ULL, try to figure out what else it fits into
+      // according to the rules of C99 6.4.4.1p5.
+
+      // Octal, Hexadecimal, and integers with a U suffix are allowed to
+      // be an unsigned int.
+      bool AllowUnsigned = Literal.isUnsigned || Literal.getRadix() != 10;
+
+      // Check from smallest to largest, picking the smallest type we can.
+      unsigned Width = 0;
+      if (!Literal.isLong && !Literal.isLongLong) {
+        // Are int/unsigned possibilities?
+        unsigned IntSize = Context.Target.getIntWidth();
+
+        // Does it fit in a unsigned int?
+        if (ResultVal.isIntN(IntSize)) {
+          // Does it fit in a signed int?
+          if (!Literal.isUnsigned && ResultVal[IntSize-1] == 0)
+            Ty = Context.IntTy;
+          else if (AllowUnsigned)
+            Ty = Context.UnsignedIntTy;
+          Width = IntSize;
+        }
+      }
+
+      // Are long/unsigned long possibilities?
+      if (Ty.isNull() && !Literal.isLongLong) {
+        unsigned LongSize = Context.Target.getLongWidth();
+
+        // Does it fit in a unsigned long?
+        if (ResultVal.isIntN(LongSize)) {
+          // Does it fit in a signed long?
+          if (!Literal.isUnsigned && ResultVal[LongSize-1] == 0)
+            Ty = Context.LongTy;
+          else if (AllowUnsigned)
+            Ty = Context.UnsignedLongTy;
+          Width = LongSize;
+        }
+      }
+
+      // Finally, check long long if needed.
+      if (Ty.isNull()) {
+        unsigned LongLongSize = Context.Target.getLongLongWidth();
+
+        // Does it fit in a unsigned long long?
+        if (ResultVal.isIntN(LongLongSize)) {
+          // Does it fit in a signed long long?
+          if (!Literal.isUnsigned && ResultVal[LongLongSize-1] == 0)
+            Ty = Context.LongLongTy;
+          else if (AllowUnsigned)
+            Ty = Context.UnsignedLongLongTy;
+          Width = LongLongSize;
+        }
+      }
+
+      // If we still couldn't decide a type, we probably have something that
+      // does not fit in a signed long long, but has no U suffix.
+      if (Ty.isNull()) {
+        Diag(Tok.getLocation(), diag::warn_integer_too_large_for_signed);
+        Ty = Context.UnsignedLongLongTy;
+        Width = Context.Target.getLongLongWidth();
+      }
+
+      if (ResultVal.getBitWidth() != Width)
+        ResultVal.trunc(Width);
+    }
+    Res = new (Context) IntegerLiteral(ResultVal, Ty, Tok.getLocation());
+  }
+
+  // If this is an imaginary literal, create the ImaginaryLiteral wrapper.
+  if (Literal.isImaginary)
+    Res = new (Context) ImaginaryLiteral(Res,
+                                        Context.getComplexType(Res->getType()));
+
+  return Owned(Res);
+}
+
+Action::OwningExprResult Sema::ActOnParenExpr(SourceLocation L,
+                                              SourceLocation R, ExprArg Val) {
+  Expr *E = Val.takeAs<Expr>();
+  assert((E != 0) && "ActOnParenExpr() missing expr");
+  return Owned(new (Context) ParenExpr(L, R, E));
+}
+
+/// The UsualUnaryConversions() function is *not* called by this routine.
+/// See C99 6.3.2.1p[2-4] for more details.
+bool Sema::CheckSizeOfAlignOfOperand(QualType exprType,
+                                     SourceLocation OpLoc,
+                                     const SourceRange &ExprRange,
+                                     bool isSizeof) {
+  if (exprType->isDependentType())
+    return false;
+
+  // C++ [expr.sizeof]p2: "When applied to a reference or a reference type,
+  //   the result is the size of the referenced type."
+  // C++ [expr.alignof]p3: "When alignof is applied to a reference type, the
+  //   result shall be the alignment of the referenced type."
+  if (const ReferenceType *Ref = exprType->getAs<ReferenceType>())
+    exprType = Ref->getPointeeType();
+
+  // C99 6.5.3.4p1:
+  if (exprType->isFunctionType()) {
+    // alignof(function) is allowed as an extension.
+    if (isSizeof)
+      Diag(OpLoc, diag::ext_sizeof_function_type) << ExprRange;
+    return false;
+  }
+
+  // Allow sizeof(void)/alignof(void) as an extension.
+  if (exprType->isVoidType()) {
+    Diag(OpLoc, diag::ext_sizeof_void_type)
+      << (isSizeof ? "sizeof" : "__alignof") << ExprRange;
+    return false;
+  }
+
+  if (RequireCompleteType(OpLoc, exprType,
+                          PDiag(diag::err_sizeof_alignof_incomplete_type)
+                          << int(!isSizeof) << ExprRange))
+    return true;
+
+  // Reject sizeof(interface) and sizeof(interface<proto>) in 64-bit mode.
+  if (LangOpts.ObjCNonFragileABI && exprType->isObjCInterfaceType()) {
+    Diag(OpLoc, diag::err_sizeof_nonfragile_interface)
+      << exprType << isSizeof << ExprRange;
+    return true;
+  }
+
+  return false;
+}
+
+bool Sema::CheckAlignOfExpr(Expr *E, SourceLocation OpLoc,
+                            const SourceRange &ExprRange) {
+  E = E->IgnoreParens();
+
+  // alignof decl is always ok.
+  if (isa<DeclRefExpr>(E))
+    return false;
+
+  // Cannot know anything else if the expression is dependent.
+  if (E->isTypeDependent())
+    return false;
+
+  if (E->getBitField()) {
+    Diag(OpLoc, diag::err_sizeof_alignof_bitfield) << 1 << ExprRange;
+    return true;
+  }
+
+  // Alignment of a field access is always okay, so long as it isn't a
+  // bit-field.
+  if (MemberExpr *ME = dyn_cast<MemberExpr>(E))
+    if (isa<FieldDecl>(ME->getMemberDecl()))
+      return false;
+
+  return CheckSizeOfAlignOfOperand(E->getType(), OpLoc, ExprRange, false);
+}
+
+/// \brief Build a sizeof or alignof expression given a type operand.
+Action::OwningExprResult
+Sema::CreateSizeOfAlignOfExpr(TypeSourceInfo *TInfo,
+                              SourceLocation OpLoc,
+                              bool isSizeOf, SourceRange R) {
+  if (!TInfo)
+    return ExprError();
+
+  QualType T = TInfo->getType();
+
+  if (!T->isDependentType() &&
+      CheckSizeOfAlignOfOperand(T, OpLoc, R, isSizeOf))
+    return ExprError();
+
+  // C99 6.5.3.4p4: the type (an unsigned integer type) is size_t.
+  return Owned(new (Context) SizeOfAlignOfExpr(isSizeOf, TInfo,
+                                               Context.getSizeType(), OpLoc,
+                                               R.getEnd()));
+}
+
+/// \brief Build a sizeof or alignof expression given an expression
+/// operand.
+Action::OwningExprResult
+Sema::CreateSizeOfAlignOfExpr(Expr *E, SourceLocation OpLoc,
+                              bool isSizeOf, SourceRange R) {
+  // Verify that the operand is valid.
+  bool isInvalid = false;
+  if (E->isTypeDependent()) {
+    // Delay type-checking for type-dependent expressions.
+  } else if (!isSizeOf) {
+    isInvalid = CheckAlignOfExpr(E, OpLoc, R);
+  } else if (E->getBitField()) {  // C99 6.5.3.4p1.
+    Diag(OpLoc, diag::err_sizeof_alignof_bitfield) << 0;
+    isInvalid = true;
+  } else {
+    isInvalid = CheckSizeOfAlignOfOperand(E->getType(), OpLoc, R, true);
+  }
+
+  if (isInvalid)
+    return ExprError();
+
+  // C99 6.5.3.4p4: the type (an unsigned integer type) is size_t.
+  return Owned(new (Context) SizeOfAlignOfExpr(isSizeOf, E,
+                                               Context.getSizeType(), OpLoc,
+                                               R.getEnd()));
+}
+
+/// ActOnSizeOfAlignOfExpr - Handle @c sizeof(type) and @c sizeof @c expr and
+/// the same for @c alignof and @c __alignof
+/// Note that the ArgRange is invalid if isType is false.
+Action::OwningExprResult
+Sema::ActOnSizeOfAlignOfExpr(SourceLocation OpLoc, bool isSizeof, bool isType,
+                             void *TyOrEx, const SourceRange &ArgRange) {
+  // If error parsing type, ignore.
+  if (TyOrEx == 0) return ExprError();
+
+  if (isType) {
+    TypeSourceInfo *TInfo;
+    (void) GetTypeFromParser(TyOrEx, &TInfo);
+    return CreateSizeOfAlignOfExpr(TInfo, OpLoc, isSizeof, ArgRange);
+  }
+
+  Expr *ArgEx = (Expr *)TyOrEx;
+  Action::OwningExprResult Result
+    = CreateSizeOfAlignOfExpr(ArgEx, OpLoc, isSizeof, ArgEx->getSourceRange());
+
+  if (Result.isInvalid())
+    DeleteExpr(ArgEx);
+
+  return move(Result);
+}
+
+QualType Sema::CheckRealImagOperand(Expr *&V, SourceLocation Loc, bool isReal) {
+  if (V->isTypeDependent())
+    return Context.DependentTy;
+
+  // These operators return the element type of a complex type.
+  if (const ComplexType *CT = V->getType()->getAs<ComplexType>())
+    return CT->getElementType();
+
+  // Otherwise they pass through real integer and floating point types here.
+  if (V->getType()->isArithmeticType())
+    return V->getType();
+
+  // Reject anything else.
+  Diag(Loc, diag::err_realimag_invalid_type) << V->getType()
+    << (isReal ? "__real" : "__imag");
+  return QualType();
+}
+
+
+
+Action::OwningExprResult
+Sema::ActOnPostfixUnaryOp(Scope *S, SourceLocation OpLoc,
+                          tok::TokenKind Kind, ExprArg Input) {
+  UnaryOperator::Opcode Opc;
+  switch (Kind) {
+  default: assert(0 && "Unknown unary op!");
+  case tok::plusplus:   Opc = UnaryOperator::PostInc; break;
+  case tok::minusminus: Opc = UnaryOperator::PostDec; break;
+  }
+
+  return BuildUnaryOp(S, OpLoc, Opc, move(Input));
+}
+
+Action::OwningExprResult
+Sema::ActOnArraySubscriptExpr(Scope *S, ExprArg Base, SourceLocation LLoc,
+                              ExprArg Idx, SourceLocation RLoc) {
+  // Since this might be a postfix expression, get rid of ParenListExprs.
+  Base = MaybeConvertParenListExprToParenExpr(S, move(Base));
+
+  Expr *LHSExp = static_cast<Expr*>(Base.get()),
+       *RHSExp = static_cast<Expr*>(Idx.get());
+
+  if (getLangOptions().CPlusPlus &&
+      (LHSExp->isTypeDependent() || RHSExp->isTypeDependent())) {
+    Base.release();
+    Idx.release();
+    return Owned(new (Context) ArraySubscriptExpr(LHSExp, RHSExp,
+                                                  Context.DependentTy, RLoc));
+  }
+
+  if (getLangOptions().CPlusPlus &&
+      (LHSExp->getType()->isRecordType() ||
+       LHSExp->getType()->isEnumeralType() ||
+       RHSExp->getType()->isRecordType() ||
+       RHSExp->getType()->isEnumeralType())) {
+    return CreateOverloadedArraySubscriptExpr(LLoc, RLoc, move(Base),move(Idx));
+  }
+
+  return CreateBuiltinArraySubscriptExpr(move(Base), LLoc, move(Idx), RLoc);
+}
+
+
+Action::OwningExprResult
+Sema::CreateBuiltinArraySubscriptExpr(ExprArg Base, SourceLocation LLoc,
+                                     ExprArg Idx, SourceLocation RLoc) {
+  Expr *LHSExp = static_cast<Expr*>(Base.get());
+  Expr *RHSExp = static_cast<Expr*>(Idx.get());
+
+  // Perform default conversions.
+  if (!LHSExp->getType()->getAs<VectorType>())
+      DefaultFunctionArrayLvalueConversion(LHSExp);
+  DefaultFunctionArrayLvalueConversion(RHSExp);
+
+  QualType LHSTy = LHSExp->getType(), RHSTy = RHSExp->getType();
+
+  // C99 6.5.2.1p2: the expression e1[e2] is by definition precisely equivalent
+  // to the expression *((e1)+(e2)). This means the array "Base" may actually be
+  // in the subscript position. As a result, we need to derive the array base
+  // and index from the expression types.
+  Expr *BaseExpr, *IndexExpr;
+  QualType ResultType;
+  if (LHSTy->isDependentType() || RHSTy->isDependentType()) {
+    BaseExpr = LHSExp;
+    IndexExpr = RHSExp;
+    ResultType = Context.DependentTy;
+  } else if (const PointerType *PTy = LHSTy->getAs<PointerType>()) {
+    BaseExpr = LHSExp;
+    IndexExpr = RHSExp;
+    ResultType = PTy->getPointeeType();
+  } else if (const PointerType *PTy = RHSTy->getAs<PointerType>()) {
+     // Handle the uncommon case of "123[Ptr]".
+    BaseExpr = RHSExp;
+    IndexExpr = LHSExp;
+    ResultType = PTy->getPointeeType();
+  } else if (const ObjCObjectPointerType *PTy =
+               LHSTy->getAs<ObjCObjectPointerType>()) {
+    BaseExpr = LHSExp;
+    IndexExpr = RHSExp;
+    ResultType = PTy->getPointeeType();
+  } else if (const ObjCObjectPointerType *PTy =
+               RHSTy->getAs<ObjCObjectPointerType>()) {
+     // Handle the uncommon case of "123[Ptr]".
+    BaseExpr = RHSExp;
+    IndexExpr = LHSExp;
+    ResultType = PTy->getPointeeType();
+  } else if (const VectorType *VTy = LHSTy->getAs<VectorType>()) {
+    BaseExpr = LHSExp;    // vectors: V[123]
+    IndexExpr = RHSExp;
+
+    // FIXME: need to deal with const...
+    ResultType = VTy->getElementType();
+  } else if (LHSTy->isArrayType()) {
+    // If we see an array that wasn't promoted by
+    // DefaultFunctionArrayLvalueConversion, it must be an array that
+    // wasn't promoted because of the C90 rule that doesn't
+    // allow promoting non-lvalue arrays.  Warn, then
+    // force the promotion here.
+    Diag(LHSExp->getLocStart(), diag::ext_subscript_non_lvalue) <<
+        LHSExp->getSourceRange();
+    ImpCastExprToType(LHSExp, Context.getArrayDecayedType(LHSTy),
+                      CastExpr::CK_ArrayToPointerDecay);
+    LHSTy = LHSExp->getType();
+
+    BaseExpr = LHSExp;
+    IndexExpr = RHSExp;
+    ResultType = LHSTy->getAs<PointerType>()->getPointeeType();
+  } else if (RHSTy->isArrayType()) {
+    // Same as previous, except for 123[f().a] case
+    Diag(RHSExp->getLocStart(), diag::ext_subscript_non_lvalue) <<
+        RHSExp->getSourceRange();
+    ImpCastExprToType(RHSExp, Context.getArrayDecayedType(RHSTy),
+                      CastExpr::CK_ArrayToPointerDecay);
+    RHSTy = RHSExp->getType();
+
+    BaseExpr = RHSExp;
+    IndexExpr = LHSExp;
+    ResultType = RHSTy->getAs<PointerType>()->getPointeeType();
+  } else {
+    return ExprError(Diag(LLoc, diag::err_typecheck_subscript_value)
+       << LHSExp->getSourceRange() << RHSExp->getSourceRange());
+  }
+  // C99 6.5.2.1p1
+  if (!(IndexExpr->getType()->isIntegerType() &&
+        IndexExpr->getType()->isScalarType()) && !IndexExpr->isTypeDependent())
+    return ExprError(Diag(LLoc, diag::err_typecheck_subscript_not_integer)
+                     << IndexExpr->getSourceRange());
+
+  if ((IndexExpr->getType()->isSpecificBuiltinType(BuiltinType::Char_S) ||
+       IndexExpr->getType()->isSpecificBuiltinType(BuiltinType::Char_U))
+         && !IndexExpr->isTypeDependent())
+    Diag(LLoc, diag::warn_subscript_is_char) << IndexExpr->getSourceRange();
+
+  // C99 6.5.2.1p1: "shall have type "pointer to *object* type". Similarly,
+  // C++ [expr.sub]p1: The type "T" shall be a completely-defined object
+  // type. Note that Functions are not objects, and that (in C99 parlance)
+  // incomplete types are not object types.
+  if (ResultType->isFunctionType()) {
+    Diag(BaseExpr->getLocStart(), diag::err_subscript_function_type)
+      << ResultType << BaseExpr->getSourceRange();
+    return ExprError();
+  }
+
+  if (!ResultType->isDependentType() &&
+      RequireCompleteType(LLoc, ResultType,
+                          PDiag(diag::err_subscript_incomplete_type)
+                            << BaseExpr->getSourceRange()))
+    return ExprError();
+
+  // Diagnose bad cases where we step over interface counts.
+  if (ResultType->isObjCInterfaceType() && LangOpts.ObjCNonFragileABI) {
+    Diag(LLoc, diag::err_subscript_nonfragile_interface)
+      << ResultType << BaseExpr->getSourceRange();
+    return ExprError();
+  }
+
+  Base.release();
+  Idx.release();
+  return Owned(new (Context) ArraySubscriptExpr(LHSExp, RHSExp,
+                                                ResultType, RLoc));
+}
+
+QualType Sema::
+CheckExtVectorComponent(QualType baseType, SourceLocation OpLoc,
+                        const IdentifierInfo *CompName,
+                        SourceLocation CompLoc) {
+  // FIXME: Share logic with ExtVectorElementExpr::containsDuplicateElements,
+  // see FIXME there.
+  //
+  // FIXME: This logic can be greatly simplified by splitting it along
+  // halving/not halving and reworking the component checking.
+  const ExtVectorType *vecType = baseType->getAs<ExtVectorType>();
+
+  // The vector accessor can't exceed the number of elements.
+  const char *compStr = CompName->getNameStart();
+
+  // This flag determines whether or not the component is one of the four
+  // special names that indicate a subset of exactly half the elements are
+  // to be selected.
+  bool HalvingSwizzle = false;
+
+  // This flag determines whether or not CompName has an 's' char prefix,
+  // indicating that it is a string of hex values to be used as vector indices.
+  bool HexSwizzle = *compStr == 's' || *compStr == 'S';
+
+  // Check that we've found one of the special components, or that the component
+  // names must come from the same set.
+  if (!strcmp(compStr, "hi") || !strcmp(compStr, "lo") ||
+      !strcmp(compStr, "even") || !strcmp(compStr, "odd")) {
+    HalvingSwizzle = true;
+  } else if (vecType->getPointAccessorIdx(*compStr) != -1) {
+    do
+      compStr++;
+    while (*compStr && vecType->getPointAccessorIdx(*compStr) != -1);
+  } else if (HexSwizzle || vecType->getNumericAccessorIdx(*compStr) != -1) {
+    do
+      compStr++;
+    while (*compStr && vecType->getNumericAccessorIdx(*compStr) != -1);
+  }
+
+  if (!HalvingSwizzle && *compStr) {
+    // We didn't get to the end of the string. This means the component names
+    // didn't come from the same set *or* we encountered an illegal name.
+    Diag(OpLoc, diag::err_ext_vector_component_name_illegal)
+      << std::string(compStr,compStr+1) << SourceRange(CompLoc);
+    return QualType();
+  }
+
+  // Ensure no component accessor exceeds the width of the vector type it
+  // operates on.
+  if (!HalvingSwizzle) {
+    compStr = CompName->getNameStart();
+
+    if (HexSwizzle)
+      compStr++;
+
+    while (*compStr) {
+      if (!vecType->isAccessorWithinNumElements(*compStr++)) {
+        Diag(OpLoc, diag::err_ext_vector_component_exceeds_length)
+          << baseType << SourceRange(CompLoc);
+        return QualType();
+      }
+    }
+  }
+
+  // The component accessor looks fine - now we need to compute the actual type.
+  // The vector type is implied by the component accessor. For example,
+  // vec4.b is a float, vec4.xy is a vec2, vec4.rgb is a vec3, etc.
+  // vec4.s0 is a float, vec4.s23 is a vec3, etc.
+  // vec4.hi, vec4.lo, vec4.e, and vec4.o all return vec2.
+  unsigned CompSize = HalvingSwizzle ? (vecType->getNumElements() + 1) / 2
+                                     : CompName->getLength();
+  if (HexSwizzle)
+    CompSize--;
+
+  if (CompSize == 1)
+    return vecType->getElementType();
+
+  QualType VT = Context.getExtVectorType(vecType->getElementType(), CompSize);
+  // Now look up the TypeDefDecl from the vector type. Without this,
+  // diagostics look bad. We want extended vector types to appear built-in.
+  for (unsigned i = 0, E = ExtVectorDecls.size(); i != E; ++i) {
+    if (ExtVectorDecls[i]->getUnderlyingType() == VT)
+      return Context.getTypedefType(ExtVectorDecls[i]);
+  }
+  return VT; // should never get here (a typedef type should always be found).
+}
+
+static Decl *FindGetterNameDeclFromProtocolList(const ObjCProtocolDecl*PDecl,
+                                                IdentifierInfo *Member,
+                                                const Selector &Sel,
+                                                ASTContext &Context) {
+
+  if (ObjCPropertyDecl *PD = PDecl->FindPropertyDeclaration(Member))
+    return PD;
+  if (ObjCMethodDecl *OMD = PDecl->getInstanceMethod(Sel))
+    return OMD;
+
+  for (ObjCProtocolDecl::protocol_iterator I = PDecl->protocol_begin(),
+       E = PDecl->protocol_end(); I != E; ++I) {
+    if (Decl *D = FindGetterNameDeclFromProtocolList(*I, Member, Sel,
+                                                     Context))
+      return D;
+  }
+  return 0;
+}
+
+static Decl *FindGetterNameDecl(const ObjCObjectPointerType *QIdTy,
+                                IdentifierInfo *Member,
+                                const Selector &Sel,
+                                ASTContext &Context) {
+  // Check protocols on qualified interfaces.
+  Decl *GDecl = 0;
+  for (ObjCObjectPointerType::qual_iterator I = QIdTy->qual_begin(),
+       E = QIdTy->qual_end(); I != E; ++I) {
+    if (ObjCPropertyDecl *PD = (*I)->FindPropertyDeclaration(Member)) {
+      GDecl = PD;
+      break;
+    }
+    // Also must look for a getter name which uses property syntax.
+    if (ObjCMethodDecl *OMD = (*I)->getInstanceMethod(Sel)) {
+      GDecl = OMD;
+      break;
+    }
+  }
+  if (!GDecl) {
+    for (ObjCObjectPointerType::qual_iterator I = QIdTy->qual_begin(),
+         E = QIdTy->qual_end(); I != E; ++I) {
+      // Search in the protocol-qualifier list of current protocol.
+      GDecl = FindGetterNameDeclFromProtocolList(*I, Member, Sel, Context);
+      if (GDecl)
+        return GDecl;
+    }
+  }
+  return GDecl;
+}
+
+Sema::OwningExprResult
+Sema::ActOnDependentMemberExpr(ExprArg Base, QualType BaseType,
+                               bool IsArrow, SourceLocation OpLoc,
+                               const CXXScopeSpec &SS,
+                               NamedDecl *FirstQualifierInScope,
+                               DeclarationName Name, SourceLocation NameLoc,
+                               const TemplateArgumentListInfo *TemplateArgs) {
+  Expr *BaseExpr = Base.takeAs<Expr>();
+
+  // Even in dependent contexts, try to diagnose base expressions with
+  // obviously wrong types, e.g.:
+  //
+  // T* t;
+  // t.f;
+  //
+  // In Obj-C++, however, the above expression is valid, since it could be
+  // accessing the 'f' property if T is an Obj-C interface. The extra check
+  // allows this, while still reporting an error if T is a struct pointer.
+  if (!IsArrow) {
+    const PointerType *PT = BaseType->getAs<PointerType>();
+    if (PT && (!getLangOptions().ObjC1 ||
+               PT->getPointeeType()->isRecordType())) {
+      assert(BaseExpr && "cannot happen with implicit member accesses");
+      Diag(NameLoc, diag::err_typecheck_member_reference_struct_union)
+        << BaseType << BaseExpr->getSourceRange();
+      return ExprError();
+    }
+  }
+
+  assert(BaseType->isDependentType() || Name.isDependentName() || 
+         isDependentScopeSpecifier(SS));
+
+  // Get the type being accessed in BaseType.  If this is an arrow, the BaseExpr
+  // must have pointer type, and the accessed type is the pointee.
+  return Owned(CXXDependentScopeMemberExpr::Create(Context, BaseExpr, BaseType,
+                                                   IsArrow, OpLoc,
+                 static_cast<NestedNameSpecifier*>(SS.getScopeRep()),
+                                                   SS.getRange(),
+                                                   FirstQualifierInScope,
+                                                   Name, NameLoc,
+                                                   TemplateArgs));
+}
+
+/// We know that the given qualified member reference points only to
+/// declarations which do not belong to the static type of the base
+/// expression.  Diagnose the problem.
+static void DiagnoseQualifiedMemberReference(Sema &SemaRef,
+                                             Expr *BaseExpr,
+                                             QualType BaseType,
+                                             const CXXScopeSpec &SS,
+                                             const LookupResult &R) {
+  // If this is an implicit member access, use a different set of
+  // diagnostics.
+  if (!BaseExpr)
+    return DiagnoseInstanceReference(SemaRef, SS, R);
+
+  SemaRef.Diag(R.getNameLoc(), diag::err_qualified_member_of_unrelated)
+    << SS.getRange() << R.getRepresentativeDecl() << BaseType;
+}
+
+// Check whether the declarations we found through a nested-name
+// specifier in a member expression are actually members of the base
+// type.  The restriction here is:
+//
+//   C++ [expr.ref]p2:
+//     ... In these cases, the id-expression shall name a
+//     member of the class or of one of its base classes.
+//
+// So it's perfectly legitimate for the nested-name specifier to name
+// an unrelated class, and for us to find an overload set including
+// decls from classes which are not superclasses, as long as the decl
+// we actually pick through overload resolution is from a superclass.
+bool Sema::CheckQualifiedMemberReference(Expr *BaseExpr,
+                                         QualType BaseType,
+                                         const CXXScopeSpec &SS,
+                                         const LookupResult &R) {
+  const RecordType *BaseRT = BaseType->getAs<RecordType>();
+  if (!BaseRT) {
+    // We can't check this yet because the base type is still
+    // dependent.
+    assert(BaseType->isDependentType());
+    return false;
+  }
+  CXXRecordDecl *BaseRecord = cast<CXXRecordDecl>(BaseRT->getDecl());
+
+  for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) {
+    // If this is an implicit member reference and we find a
+    // non-instance member, it's not an error.
+    if (!BaseExpr && !(*I)->isCXXInstanceMember())
+      return false;
+
+    // Note that we use the DC of the decl, not the underlying decl.
+    CXXRecordDecl *RecordD = cast<CXXRecordDecl>((*I)->getDeclContext());
+    while (RecordD->isAnonymousStructOrUnion())
+      RecordD = cast<CXXRecordDecl>(RecordD->getParent());
+
+    llvm::SmallPtrSet<CXXRecordDecl*,4> MemberRecord;
+    MemberRecord.insert(RecordD->getCanonicalDecl());
+
+    if (!IsProvablyNotDerivedFrom(*this, BaseRecord, MemberRecord))
+      return false;
+  }
+
+  DiagnoseQualifiedMemberReference(*this, BaseExpr, BaseType, SS, R);
+  return true;
+}
+
+static bool
+LookupMemberExprInRecord(Sema &SemaRef, LookupResult &R,
+                         SourceRange BaseRange, const RecordType *RTy,
+                         SourceLocation OpLoc, CXXScopeSpec &SS) {
+  RecordDecl *RDecl = RTy->getDecl();
+  if (SemaRef.RequireCompleteType(OpLoc, QualType(RTy, 0),
+                              SemaRef.PDiag(diag::err_typecheck_incomplete_tag)
+                                    << BaseRange))
+    return true;
+
+  DeclContext *DC = RDecl;
+  if (SS.isSet()) {
+    // If the member name was a qualified-id, look into the
+    // nested-name-specifier.
+    DC = SemaRef.computeDeclContext(SS, false);
+
+    if (SemaRef.RequireCompleteDeclContext(SS)) {
+      SemaRef.Diag(SS.getRange().getEnd(), diag::err_typecheck_incomplete_tag)
+        << SS.getRange() << DC;
+      return true;
+    }
+
+    assert(DC && "Cannot handle non-computable dependent contexts in lookup");
+
+    if (!isa<TypeDecl>(DC)) {
+      SemaRef.Diag(R.getNameLoc(), diag::err_qualified_member_nonclass)
+        << DC << SS.getRange();
+      return true;
+    }
+  }
+
+  // The record definition is complete, now look up the member.
+  SemaRef.LookupQualifiedName(R, DC);
+
+  if (!R.empty())
+    return false;
+
+  // We didn't find anything with the given name, so try to correct
+  // for typos.
+  DeclarationName Name = R.getLookupName();
+  if (SemaRef.CorrectTypo(R, 0, &SS, DC, false, Sema::CTC_MemberLookup) && 
+      !R.empty() &&
+      (isa<ValueDecl>(*R.begin()) || isa<FunctionTemplateDecl>(*R.begin()))) {
+    SemaRef.Diag(R.getNameLoc(), diag::err_no_member_suggest)
+      << Name << DC << R.getLookupName() << SS.getRange()
+      << FixItHint::CreateReplacement(R.getNameLoc(),
+                                      R.getLookupName().getAsString());
+    if (NamedDecl *ND = R.getAsSingle<NamedDecl>())
+      SemaRef.Diag(ND->getLocation(), diag::note_previous_decl)
+        << ND->getDeclName();
+    return false;
+  } else {
+    R.clear();
+  }
+
+  return false;
+}
+
+Sema::OwningExprResult
+Sema::BuildMemberReferenceExpr(ExprArg BaseArg, QualType BaseType,
+                               SourceLocation OpLoc, bool IsArrow,
+                               CXXScopeSpec &SS,
+                               NamedDecl *FirstQualifierInScope,
+                               DeclarationName Name, SourceLocation NameLoc,
+                               const TemplateArgumentListInfo *TemplateArgs) {
+  Expr *Base = BaseArg.takeAs<Expr>();
+
+  if (BaseType->isDependentType() ||
+      (SS.isSet() && isDependentScopeSpecifier(SS)))
+    return ActOnDependentMemberExpr(ExprArg(*this, Base), BaseType,
+                                    IsArrow, OpLoc,
+                                    SS, FirstQualifierInScope,
+                                    Name, NameLoc,
+                                    TemplateArgs);
+
+  LookupResult R(*this, Name, NameLoc, LookupMemberName);
+
+  // Implicit member accesses.
+  if (!Base) {
+    QualType RecordTy = BaseType;
+    if (IsArrow) RecordTy = RecordTy->getAs<PointerType>()->getPointeeType();
+    if (LookupMemberExprInRecord(*this, R, SourceRange(),
+                                 RecordTy->getAs<RecordType>(),
+                                 OpLoc, SS))
+      return ExprError();
+
+  // Explicit member accesses.
+  } else {
+    OwningExprResult Result =
+      LookupMemberExpr(R, Base, IsArrow, OpLoc,
+                       SS, /*ObjCImpDecl*/ DeclPtrTy());
+
+    if (Result.isInvalid()) {
+      Owned(Base);
+      return ExprError();
+    }
+
+    if (Result.get())
+      return move(Result);
+  }
+
+  return BuildMemberReferenceExpr(ExprArg(*this, Base), BaseType,
+                                  OpLoc, IsArrow, SS, FirstQualifierInScope,
+                                  R, TemplateArgs);
+}
+
+Sema::OwningExprResult
+Sema::BuildMemberReferenceExpr(ExprArg Base, QualType BaseExprType,
+                               SourceLocation OpLoc, bool IsArrow,
+                               const CXXScopeSpec &SS,
+                               NamedDecl *FirstQualifierInScope,
+                               LookupResult &R,
+                         const TemplateArgumentListInfo *TemplateArgs) {
+  Expr *BaseExpr = Base.takeAs<Expr>();
+  QualType BaseType = BaseExprType;
+  if (IsArrow) {
+    assert(BaseType->isPointerType());
+    BaseType = BaseType->getAs<PointerType>()->getPointeeType();
+  }
+  R.setBaseObjectType(BaseType);
+
+  NestedNameSpecifier *Qualifier =
+    static_cast<NestedNameSpecifier*>(SS.getScopeRep());
+  DeclarationName MemberName = R.getLookupName();
+  SourceLocation MemberLoc = R.getNameLoc();
+
+  if (R.isAmbiguous())
+    return ExprError();
+
+  if (R.empty()) {
+    // Rederive where we looked up.
+    DeclContext *DC = (SS.isSet()
+                       ? computeDeclContext(SS, false)
+                       : BaseType->getAs<RecordType>()->getDecl());
+
+    Diag(R.getNameLoc(), diag::err_no_member)
+      << MemberName << DC
+      << (BaseExpr ? BaseExpr->getSourceRange() : SourceRange());
+    return ExprError();
+  }
+
+  // Diagnose lookups that find only declarations from a non-base
+  // type.  This is possible for either qualified lookups (which may
+  // have been qualified with an unrelated type) or implicit member
+  // expressions (which were found with unqualified lookup and thus
+  // may have come from an enclosing scope).  Note that it's okay for
+  // lookup to find declarations from a non-base type as long as those
+  // aren't the ones picked by overload resolution.
+  if ((SS.isSet() || !BaseExpr ||
+       (isa<CXXThisExpr>(BaseExpr) &&
+        cast<CXXThisExpr>(BaseExpr)->isImplicit())) &&
+      CheckQualifiedMemberReference(BaseExpr, BaseType, SS, R))
+    return ExprError();
+
+  // Construct an unresolved result if we in fact got an unresolved
+  // result.
+  if (R.isOverloadedResult() || R.isUnresolvableResult()) {
+    bool Dependent =
+      BaseExprType->isDependentType() ||
+      R.isUnresolvableResult() ||
+      OverloadExpr::ComputeDependence(R.begin(), R.end(), TemplateArgs);
+
+    // Suppress any lookup-related diagnostics; we'll do these when we
+    // pick a member.
+    R.suppressDiagnostics();
+
+    UnresolvedMemberExpr *MemExpr
+      = UnresolvedMemberExpr::Create(Context, Dependent,
+                                     R.isUnresolvableResult(),
+                                     BaseExpr, BaseExprType,
+                                     IsArrow, OpLoc,
+                                     Qualifier, SS.getRange(),
+                                     MemberName, MemberLoc,
+                                     TemplateArgs);
+    MemExpr->addDecls(R.begin(), R.end());
+
+    return Owned(MemExpr);
+  }
+
+  assert(R.isSingleResult());
+  DeclAccessPair FoundDecl = R.begin().getPair();
+  NamedDecl *MemberDecl = R.getFoundDecl();
+
+  // FIXME: diagnose the presence of template arguments now.
+
+  // If the decl being referenced had an error, return an error for this
+  // sub-expr without emitting another error, in order to avoid cascading
+  // error cases.
+  if (MemberDecl->isInvalidDecl())
+    return ExprError();
+
+  // Handle the implicit-member-access case.
+  if (!BaseExpr) {
+    // If this is not an instance member, convert to a non-member access.
+    if (!MemberDecl->isCXXInstanceMember())
+      return BuildDeclarationNameExpr(SS, R.getNameLoc(), MemberDecl);
+
+    SourceLocation Loc = R.getNameLoc();
+    if (SS.getRange().isValid())
+      Loc = SS.getRange().getBegin();
+    BaseExpr = new (Context) CXXThisExpr(Loc, BaseExprType,/*isImplicit=*/true);
+  }
+
+  bool ShouldCheckUse = true;
+  if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MemberDecl)) {
+    // Don't diagnose the use of a virtual member function unless it's
+    // explicitly qualified.
+    if (MD->isVirtual() && !SS.isSet())
+      ShouldCheckUse = false;
+  }
+
+  // Check the use of this member.
+  if (ShouldCheckUse && DiagnoseUseOfDecl(MemberDecl, MemberLoc)) {
+    Owned(BaseExpr);
+    return ExprError();
+  }
+
+  if (FieldDecl *FD = dyn_cast<FieldDecl>(MemberDecl)) {
+    // We may have found a field within an anonymous union or struct
+    // (C++ [class.union]).
+    if (cast<RecordDecl>(FD->getDeclContext())->isAnonymousStructOrUnion() &&
+        !BaseType->getAs<RecordType>()->getDecl()->isAnonymousStructOrUnion())
+      return BuildAnonymousStructUnionMemberReference(MemberLoc, FD,
+                                                      BaseExpr, OpLoc);
+
+    // Figure out the type of the member; see C99 6.5.2.3p3, C++ [expr.ref]
+    QualType MemberType = FD->getType();
+    if (const ReferenceType *Ref = MemberType->getAs<ReferenceType>())
+      MemberType = Ref->getPointeeType();
+    else {
+      Qualifiers BaseQuals = BaseType.getQualifiers();
+      BaseQuals.removeObjCGCAttr();
+      if (FD->isMutable()) BaseQuals.removeConst();
+
+      Qualifiers MemberQuals
+        = Context.getCanonicalType(MemberType).getQualifiers();
+
+      Qualifiers Combined = BaseQuals + MemberQuals;
+      if (Combined != MemberQuals)
+        MemberType = Context.getQualifiedType(MemberType, Combined);
+    }
+
+    MarkDeclarationReferenced(MemberLoc, FD);
+    if (PerformObjectMemberConversion(BaseExpr, Qualifier, FoundDecl, FD))
+      return ExprError();
+    return Owned(BuildMemberExpr(Context, BaseExpr, IsArrow, SS,
+                                 FD, FoundDecl, MemberLoc, MemberType));
+  }
+
+  if (VarDecl *Var = dyn_cast<VarDecl>(MemberDecl)) {
+    MarkDeclarationReferenced(MemberLoc, Var);
+    return Owned(BuildMemberExpr(Context, BaseExpr, IsArrow, SS,
+                                 Var, FoundDecl, MemberLoc,
+                                 Var->getType().getNonReferenceType()));
+  }
+
+  if (FunctionDecl *MemberFn = dyn_cast<FunctionDecl>(MemberDecl)) {
+    MarkDeclarationReferenced(MemberLoc, MemberDecl);
+    return Owned(BuildMemberExpr(Context, BaseExpr, IsArrow, SS,
+                                 MemberFn, FoundDecl, MemberLoc,
+                                 MemberFn->getType()));
+  }
+
+  if (EnumConstantDecl *Enum = dyn_cast<EnumConstantDecl>(MemberDecl)) {
+    MarkDeclarationReferenced(MemberLoc, MemberDecl);
+    return Owned(BuildMemberExpr(Context, BaseExpr, IsArrow, SS,
+                                 Enum, FoundDecl, MemberLoc, Enum->getType()));
+  }
+
+  Owned(BaseExpr);
+
+  // We found something that we didn't expect. Complain.
+  if (isa<TypeDecl>(MemberDecl))
+    Diag(MemberLoc,diag::err_typecheck_member_reference_type)
+      << MemberName << BaseType << int(IsArrow);
+  else
+    Diag(MemberLoc, diag::err_typecheck_member_reference_unknown)
+      << MemberName << BaseType << int(IsArrow);
+
+  Diag(MemberDecl->getLocation(), diag::note_member_declared_here)
+    << MemberName;
+  R.suppressDiagnostics();
+  return ExprError();
+}
+
+/// Look up the given member of the given non-type-dependent
+/// expression.  This can return in one of two ways:
+///  * If it returns a sentinel null-but-valid result, the caller will
+///    assume that lookup was performed and the results written into
+///    the provided structure.  It will take over from there.
+///  * Otherwise, the returned expression will be produced in place of
+///    an ordinary member expression.
+///
+/// The ObjCImpDecl bit is a gross hack that will need to be properly
+/// fixed for ObjC++.
+Sema::OwningExprResult
+Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr,
+                       bool &IsArrow, SourceLocation OpLoc,
+                       CXXScopeSpec &SS,
+                       DeclPtrTy ObjCImpDecl) {
+  assert(BaseExpr && "no base expression");
+
+  // Perform default conversions.
+  DefaultFunctionArrayConversion(BaseExpr);
+
+  QualType BaseType = BaseExpr->getType();
+  assert(!BaseType->isDependentType());
+
+  DeclarationName MemberName = R.getLookupName();
+  SourceLocation MemberLoc = R.getNameLoc();
+
+  // If the user is trying to apply -> or . to a function pointer
+  // type, it's probably because they forgot parentheses to call that
+  // function. Suggest the addition of those parentheses, build the
+  // call, and continue on.
+  if (const PointerType *Ptr = BaseType->getAs<PointerType>()) {
+    if (const FunctionProtoType *Fun
+          = Ptr->getPointeeType()->getAs<FunctionProtoType>()) {
+      QualType ResultTy = Fun->getResultType();
+      if (Fun->getNumArgs() == 0 &&
+          ((!IsArrow && ResultTy->isRecordType()) ||
+           (IsArrow && ResultTy->isPointerType() &&
+            ResultTy->getAs<PointerType>()->getPointeeType()
+                                                          ->isRecordType()))) {
+        SourceLocation Loc = PP.getLocForEndOfToken(BaseExpr->getLocEnd());
+        Diag(Loc, diag::err_member_reference_needs_call)
+          << QualType(Fun, 0)
+          << FixItHint::CreateInsertion(Loc, "()");
+
+        OwningExprResult NewBase
+          = ActOnCallExpr(0, ExprArg(*this, BaseExpr), Loc,
+                          MultiExprArg(*this, 0, 0), 0, Loc);
+        if (NewBase.isInvalid())
+          return ExprError();
+
+        BaseExpr = NewBase.takeAs<Expr>();
+        DefaultFunctionArrayConversion(BaseExpr);
+        BaseType = BaseExpr->getType();
+      }
+    }
+  }
+
+  // If this is an Objective-C pseudo-builtin and a definition is provided then
+  // use that.
+  if (BaseType->isObjCIdType()) {
+    if (IsArrow) {
+      // Handle the following exceptional case PObj->isa.
+      if (const ObjCObjectPointerType *OPT =
+          BaseType->getAs<ObjCObjectPointerType>()) {
+        if (OPT->getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCId) &&
+            MemberName.getAsIdentifierInfo()->isStr("isa"))
+          return Owned(new (Context) ObjCIsaExpr(BaseExpr, true, MemberLoc,
+                                                 Context.getObjCClassType()));
+      }
+    }
+    // We have an 'id' type. Rather than fall through, we check if this
+    // is a reference to 'isa'.
+    if (BaseType != Context.ObjCIdRedefinitionType) {
+      BaseType = Context.ObjCIdRedefinitionType;
+      ImpCastExprToType(BaseExpr, BaseType, CastExpr::CK_BitCast);
+    }
+  }
+
+  // If this is an Objective-C pseudo-builtin and a definition is provided then
+  // use that.
+  if (Context.isObjCSelType(BaseType)) {
+    // We have an 'SEL' type. Rather than fall through, we check if this
+    // is a reference to 'sel_id'.
+    if (BaseType != Context.ObjCSelRedefinitionType) {
+      BaseType = Context.ObjCSelRedefinitionType;
+      ImpCastExprToType(BaseExpr, BaseType, CastExpr::CK_BitCast);
+    }
+  }
+
+  assert(!BaseType.isNull() && "no type for member expression");
+
+  // Handle properties on ObjC 'Class' types.
+  if (!IsArrow && BaseType->isObjCClassType()) {
+    // Also must look for a getter name which uses property syntax.
+    IdentifierInfo *Member = MemberName.getAsIdentifierInfo();
+    Selector Sel = PP.getSelectorTable().getNullarySelector(Member);
+    if (ObjCMethodDecl *MD = getCurMethodDecl()) {
+      ObjCInterfaceDecl *IFace = MD->getClassInterface();
+      ObjCMethodDecl *Getter;
+      // FIXME: need to also look locally in the implementation.
+      if ((Getter = IFace->lookupClassMethod(Sel))) {
+        // Check the use of this method.
+        if (DiagnoseUseOfDecl(Getter, MemberLoc))
+          return ExprError();
+      }
+      // If we found a getter then this may be a valid dot-reference, we
+      // will look for the matching setter, in case it is needed.
+      Selector SetterSel =
+      SelectorTable::constructSetterName(PP.getIdentifierTable(),
+                                         PP.getSelectorTable(), Member);
+      ObjCMethodDecl *Setter = IFace->lookupClassMethod(SetterSel);
+      if (!Setter) {
+        // If this reference is in an @implementation, also check for 'private'
+        // methods.
+        Setter = IFace->lookupPrivateInstanceMethod(SetterSel);
+      }
+      // Look through local category implementations associated with the class.
+      if (!Setter)
+        Setter = IFace->getCategoryClassMethod(SetterSel);
+
+      if (Setter && DiagnoseUseOfDecl(Setter, MemberLoc))
+        return ExprError();
+
+      if (Getter || Setter) {
+        QualType PType;
+
+        if (Getter)
+          PType = Getter->getResultType();
+        else
+          // Get the expression type from Setter's incoming parameter.
+          PType = (*(Setter->param_end() -1))->getType();
+        // FIXME: we must check that the setter has property type.
+        return Owned(new (Context) ObjCImplicitSetterGetterRefExpr(Getter,
+                                                  PType,
+                                                  Setter, MemberLoc, BaseExpr));
+      }
+      return ExprError(Diag(MemberLoc, diag::err_property_not_found)
+                       << MemberName << BaseType);
+    }
+  }
+
+  if (BaseType->isObjCClassType() &&
+      BaseType != Context.ObjCClassRedefinitionType) {
+    BaseType = Context.ObjCClassRedefinitionType;
+    ImpCastExprToType(BaseExpr, BaseType, CastExpr::CK_BitCast);
+  }
+
+  if (IsArrow) {
+    if (const PointerType *PT = BaseType->getAs<PointerType>())
+      BaseType = PT->getPointeeType();
+    else if (BaseType->isObjCObjectPointerType())
+      ;
+    else if (BaseType->isRecordType()) {
+      // Recover from arrow accesses to records, e.g.:
+      //   struct MyRecord foo;
+      //   foo->bar
+      // This is actually well-formed in C++ if MyRecord has an
+      // overloaded operator->, but that should have been dealt with
+      // by now.
+      Diag(OpLoc, diag::err_typecheck_member_reference_suggestion)
+        << BaseType << int(IsArrow) << BaseExpr->getSourceRange()
+        << FixItHint::CreateReplacement(OpLoc, ".");
+      IsArrow = false;
+    } else {
+      Diag(MemberLoc, diag::err_typecheck_member_reference_arrow)
+        << BaseType << BaseExpr->getSourceRange();
+      return ExprError();
+    }
+  } else {
+    // Recover from dot accesses to pointers, e.g.:
+    //   type *foo;
+    //   foo.bar
+    // This is actually well-formed in two cases:
+    //   - 'type' is an Objective C type
+    //   - 'bar' is a pseudo-destructor name which happens to refer to
+    //     the appropriate pointer type
+    if (MemberName.getNameKind() != DeclarationName::CXXDestructorName) {
+      const PointerType *PT = BaseType->getAs<PointerType>();
+      if (PT && PT->getPointeeType()->isRecordType()) {
+        Diag(OpLoc, diag::err_typecheck_member_reference_suggestion)
+          << BaseType << int(IsArrow) << BaseExpr->getSourceRange()
+          << FixItHint::CreateReplacement(OpLoc, "->");
+        BaseType = PT->getPointeeType();
+        IsArrow = true;
+      }
+    }
+  }
+
+  // Handle field access to simple records.  This also handles access
+  // to fields of the ObjC 'id' struct.
+  if (const RecordType *RTy = BaseType->getAs<RecordType>()) {
+    if (LookupMemberExprInRecord(*this, R, BaseExpr->getSourceRange(),
+                                 RTy, OpLoc, SS))
+      return ExprError();
+    return Owned((Expr*) 0);
+  }
+
+  // Handle access to Objective-C instance variables, such as "Obj->ivar" and
+  // (*Obj).ivar.
+  if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
+      (!IsArrow && BaseType->isObjCInterfaceType())) {
+    const ObjCObjectPointerType *OPT = BaseType->getAs<ObjCObjectPointerType>();
+    const ObjCInterfaceType *IFaceT =
+      OPT ? OPT->getInterfaceType() : BaseType->getAs<ObjCInterfaceType>();
+    if (IFaceT) {
+      IdentifierInfo *Member = MemberName.getAsIdentifierInfo();
+
+      ObjCInterfaceDecl *IDecl = IFaceT->getDecl();
+      ObjCInterfaceDecl *ClassDeclared;
+      ObjCIvarDecl *IV = IDecl->lookupInstanceVariable(Member, ClassDeclared);
+
+      if (!IV) {
+        // Attempt to correct for typos in ivar names.
+        LookupResult Res(*this, R.getLookupName(), R.getNameLoc(),
+                         LookupMemberName);
+        if (CorrectTypo(Res, 0, 0, IDecl, false, CTC_MemberLookup) &&
+            (IV = Res.getAsSingle<ObjCIvarDecl>())) {
+          Diag(R.getNameLoc(),
+               diag::err_typecheck_member_reference_ivar_suggest)
+            << IDecl->getDeclName() << MemberName << IV->getDeclName()
+            << FixItHint::CreateReplacement(R.getNameLoc(),
+                                            IV->getNameAsString());
+          Diag(IV->getLocation(), diag::note_previous_decl)
+            << IV->getDeclName();
+        }
+      }
+
+      if (IV) {
+        // If the decl being referenced had an error, return an error for this
+        // sub-expr without emitting another error, in order to avoid cascading
+        // error cases.
+        if (IV->isInvalidDecl())
+          return ExprError();
+
+        // Check whether we can reference this field.
+        if (DiagnoseUseOfDecl(IV, MemberLoc))
+          return ExprError();
+        if (IV->getAccessControl() != ObjCIvarDecl::Public &&
+            IV->getAccessControl() != ObjCIvarDecl::Package) {
+          ObjCInterfaceDecl *ClassOfMethodDecl = 0;
+          if (ObjCMethodDecl *MD = getCurMethodDecl())
+            ClassOfMethodDecl =  MD->getClassInterface();
+          else if (ObjCImpDecl && getCurFunctionDecl()) {
+            // Case of a c-function declared inside an objc implementation.
+            // FIXME: For a c-style function nested inside an objc implementation
+            // class, there is no implementation context available, so we pass
+            // down the context as argument to this routine. Ideally, this context
+            // need be passed down in the AST node and somehow calculated from the
+            // AST for a function decl.
+            Decl *ImplDecl = ObjCImpDecl.getAs<Decl>();
+            if (ObjCImplementationDecl *IMPD =
+                dyn_cast<ObjCImplementationDecl>(ImplDecl))
+              ClassOfMethodDecl = IMPD->getClassInterface();
+            else if (ObjCCategoryImplDecl* CatImplClass =
+                        dyn_cast<ObjCCategoryImplDecl>(ImplDecl))
+              ClassOfMethodDecl = CatImplClass->getClassInterface();
+          }
+
+          if (IV->getAccessControl() == ObjCIvarDecl::Private) {
+            if (ClassDeclared != IDecl ||
+                ClassOfMethodDecl != ClassDeclared)
+              Diag(MemberLoc, diag::error_private_ivar_access)
+                << IV->getDeclName();
+          } else if (!IDecl->isSuperClassOf(ClassOfMethodDecl))
+            // @protected
+            Diag(MemberLoc, diag::error_protected_ivar_access)
+              << IV->getDeclName();
+        }
+
+        return Owned(new (Context) ObjCIvarRefExpr(IV, IV->getType(),
+                                                   MemberLoc, BaseExpr,
+                                                   IsArrow));
+      }
+      return ExprError(Diag(MemberLoc, diag::err_typecheck_member_reference_ivar)
+                         << IDecl->getDeclName() << MemberName
+                         << BaseExpr->getSourceRange());
+    }
+  }
+  // Handle properties on 'id' and qualified "id".
+  if (!IsArrow && (BaseType->isObjCIdType() ||
+                   BaseType->isObjCQualifiedIdType())) {
+    const ObjCObjectPointerType *QIdTy = BaseType->getAs<ObjCObjectPointerType>();
+    IdentifierInfo *Member = MemberName.getAsIdentifierInfo();
+
+    // Check protocols on qualified interfaces.
+    Selector Sel = PP.getSelectorTable().getNullarySelector(Member);
+    if (Decl *PMDecl = FindGetterNameDecl(QIdTy, Member, Sel, Context)) {
+      if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(PMDecl)) {
+        // Check the use of this declaration
+        if (DiagnoseUseOfDecl(PD, MemberLoc))
+          return ExprError();
+
+        return Owned(new (Context) ObjCPropertyRefExpr(PD, PD->getType(),
+                                                       MemberLoc, BaseExpr));
+      }
+      if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(PMDecl)) {
+        // Check the use of this method.
+        if (DiagnoseUseOfDecl(OMD, MemberLoc))
+          return ExprError();
+
+        return Owned(ObjCMessageExpr::Create(Context, 
+                                     OMD->getResultType().getNonReferenceType(),
+                                             OpLoc, BaseExpr, Sel,
+                                             OMD, NULL, 0, MemberLoc));
+      }
+    }
+
+    return ExprError(Diag(MemberLoc, diag::err_property_not_found)
+                       << MemberName << BaseType);
+  }
+  
+  // Handle Objective-C property access, which is "Obj.property" where Obj is a
+  // pointer to a (potentially qualified) interface type.
+  if (!IsArrow)
+    if (const ObjCObjectPointerType *OPT =
+          BaseType->getAsObjCInterfacePointerType())
+      return HandleExprPropertyRefExpr(OPT, BaseExpr, MemberName, MemberLoc);
+
+  // Handle the following exceptional case (*Obj).isa.
+  if (!IsArrow &&
+      BaseType->isSpecificBuiltinType(BuiltinType::ObjCId) &&
+      MemberName.getAsIdentifierInfo()->isStr("isa"))
+    return Owned(new (Context) ObjCIsaExpr(BaseExpr, false, MemberLoc,
+                                           Context.getObjCClassType()));
+
+  // Handle 'field access' to vectors, such as 'V.xx'.
+  if (BaseType->isExtVectorType()) {
+    IdentifierInfo *Member = MemberName.getAsIdentifierInfo();
+    QualType ret = CheckExtVectorComponent(BaseType, OpLoc, Member, MemberLoc);
+    if (ret.isNull())
+      return ExprError();
+    return Owned(new (Context) ExtVectorElementExpr(ret, BaseExpr, *Member,
+                                                    MemberLoc));
+  }
+
+  Diag(MemberLoc, diag::err_typecheck_member_reference_struct_union)
+    << BaseType << BaseExpr->getSourceRange();
+
+  return ExprError();
+}
+
+/// The main callback when the parser finds something like
+///   expression . [nested-name-specifier] identifier
+///   expression -> [nested-name-specifier] identifier
+/// where 'identifier' encompasses a fairly broad spectrum of
+/// possibilities, including destructor and operator references.
+///
+/// \param OpKind either tok::arrow or tok::period
+/// \param HasTrailingLParen whether the next token is '(', which
+///   is used to diagnose mis-uses of special members that can
+///   only be called
+/// \param ObjCImpDecl the current ObjC @implementation decl;
+///   this is an ugly hack around the fact that ObjC @implementations
+///   aren't properly put in the context chain
+Sema::OwningExprResult Sema::ActOnMemberAccessExpr(Scope *S, ExprArg BaseArg,
+                                                   SourceLocation OpLoc,
+                                                   tok::TokenKind OpKind,
+                                                   CXXScopeSpec &SS,
+                                                   UnqualifiedId &Id,
+                                                   DeclPtrTy ObjCImpDecl,
+                                                   bool HasTrailingLParen) {
+  if (SS.isSet() && SS.isInvalid())
+    return ExprError();
+
+  TemplateArgumentListInfo TemplateArgsBuffer;
+
+  // Decompose the name into its component parts.
+  DeclarationName Name;
+  SourceLocation NameLoc;
+  const TemplateArgumentListInfo *TemplateArgs;
+  DecomposeUnqualifiedId(*this, Id, TemplateArgsBuffer,
+                         Name, NameLoc, TemplateArgs);
+
+  bool IsArrow = (OpKind == tok::arrow);
+
+  NamedDecl *FirstQualifierInScope
+    = (!SS.isSet() ? 0 : FindFirstQualifierInScope(S,
+                       static_cast<NestedNameSpecifier*>(SS.getScopeRep())));
+
+  // This is a postfix expression, so get rid of ParenListExprs.
+  BaseArg = MaybeConvertParenListExprToParenExpr(S, move(BaseArg));
+
+  Expr *Base = BaseArg.takeAs<Expr>();
+  OwningExprResult Result(*this);
+  if (Base->getType()->isDependentType() || Name.isDependentName() ||
+      isDependentScopeSpecifier(SS)) {
+    Result = ActOnDependentMemberExpr(ExprArg(*this, Base), Base->getType(),
+                                      IsArrow, OpLoc,
+                                      SS, FirstQualifierInScope,
+                                      Name, NameLoc,
+                                      TemplateArgs);
+  } else {
+    LookupResult R(*this, Name, NameLoc, LookupMemberName);
+    if (TemplateArgs) {
+      // Re-use the lookup done for the template name.
+      DecomposeTemplateName(R, Id);
+    } else {
+      Result = LookupMemberExpr(R, Base, IsArrow, OpLoc,
+                                SS, ObjCImpDecl);
+
+      if (Result.isInvalid()) {
+        Owned(Base);
+        return ExprError();
+      }
+
+      if (Result.get()) {
+        // The only way a reference to a destructor can be used is to
+        // immediately call it, which falls into this case.  If the
+        // next token is not a '(', produce a diagnostic and build the
+        // call now.
+        if (!HasTrailingLParen &&
+            Id.getKind() == UnqualifiedId::IK_DestructorName)
+          return DiagnoseDtorReference(NameLoc, move(Result));
+
+        return move(Result);
+      }
+    }
+
+    Result = BuildMemberReferenceExpr(ExprArg(*this, Base), Base->getType(),
+                                      OpLoc, IsArrow, SS, FirstQualifierInScope,
+                                      R, TemplateArgs);
+  }
+
+  return move(Result);
+}
+
+Sema::OwningExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation CallLoc,
+                                                    FunctionDecl *FD,
+                                                    ParmVarDecl *Param) {
+  if (Param->hasUnparsedDefaultArg()) {
+    Diag (CallLoc,
+          diag::err_use_of_default_argument_to_function_declared_later) <<
+      FD << cast<CXXRecordDecl>(FD->getDeclContext())->getDeclName();
+    Diag(UnparsedDefaultArgLocs[Param],
+          diag::note_default_argument_declared_here);
+  } else {
+    if (Param->hasUninstantiatedDefaultArg()) {
+      Expr *UninstExpr = Param->getUninstantiatedDefaultArg();
+
+      // Instantiate the expression.
+      MultiLevelTemplateArgumentList ArgList
+        = getTemplateInstantiationArgs(FD, 0, /*RelativeToPrimary=*/true);
+
+      InstantiatingTemplate Inst(*this, CallLoc, Param,
+                                 ArgList.getInnermost().getFlatArgumentList(),
+                                 ArgList.getInnermost().flat_size());
+
+      OwningExprResult Result = SubstExpr(UninstExpr, ArgList);
+      if (Result.isInvalid())
+        return ExprError();
+
+      // Check the expression as an initializer for the parameter.
+      InitializedEntity Entity
+        = InitializedEntity::InitializeParameter(Param);
+      InitializationKind Kind
+        = InitializationKind::CreateCopy(Param->getLocation(),
+               /*FIXME:EqualLoc*/UninstExpr->getSourceRange().getBegin());
+      Expr *ResultE = Result.takeAs<Expr>();
+
+      InitializationSequence InitSeq(*this, Entity, Kind, &ResultE, 1);
+      Result = InitSeq.Perform(*this, Entity, Kind,
+                               MultiExprArg(*this, (void**)&ResultE, 1));
+      if (Result.isInvalid())
+        return ExprError();
+
+      // Build the default argument expression.
+      return Owned(CXXDefaultArgExpr::Create(Context, CallLoc, Param,
+                                             Result.takeAs<Expr>()));
+    }
+
+    // If the default expression creates temporaries, we need to
+    // push them to the current stack of expression temporaries so they'll
+    // be properly destroyed.
+    // FIXME: We should really be rebuilding the default argument with new
+    // bound temporaries; see the comment in PR5810.
+    for (unsigned i = 0, e = Param->getNumDefaultArgTemporaries(); i != e; ++i)
+      ExprTemporaries.push_back(Param->getDefaultArgTemporary(i));
+  }
+
+  // We already type-checked the argument, so we know it works.
+  return Owned(CXXDefaultArgExpr::Create(Context, CallLoc, Param));
+}
+
+/// ConvertArgumentsForCall - Converts the arguments specified in
+/// Args/NumArgs to the parameter types of the function FDecl with
+/// function prototype Proto. Call is the call expression itself, and
+/// Fn is the function expression. For a C++ member function, this
+/// routine does not attempt to convert the object argument. Returns
+/// true if the call is ill-formed.
+bool
+Sema::ConvertArgumentsForCall(CallExpr *Call, Expr *Fn,
+                              FunctionDecl *FDecl,
+                              const FunctionProtoType *Proto,
+                              Expr **Args, unsigned NumArgs,
+                              SourceLocation RParenLoc) {
+  // C99 6.5.2.2p7 - the arguments are implicitly converted, as if by
+  // assignment, to the types of the corresponding parameter, ...
+  unsigned NumArgsInProto = Proto->getNumArgs();
+  bool Invalid = false;
+
+  // If too few arguments are available (and we don't have default
+  // arguments for the remaining parameters), don't make the call.
+  if (NumArgs < NumArgsInProto) {
+    if (!FDecl || NumArgs < FDecl->getMinRequiredArguments())
+      return Diag(RParenLoc, diag::err_typecheck_call_too_few_args)
+        << Fn->getType()->isBlockPointerType() 
+        << NumArgsInProto << NumArgs << Fn->getSourceRange();
+    Call->setNumArgs(Context, NumArgsInProto);
+  }
+
+  // If too many are passed and not variadic, error on the extras and drop
+  // them.
+  if (NumArgs > NumArgsInProto) {
+    if (!Proto->isVariadic()) {
+      Diag(Args[NumArgsInProto]->getLocStart(),
+           diag::err_typecheck_call_too_many_args)
+        << Fn->getType()->isBlockPointerType() 
+        << NumArgsInProto << NumArgs << Fn->getSourceRange()
+        << SourceRange(Args[NumArgsInProto]->getLocStart(),
+                       Args[NumArgs-1]->getLocEnd());
+      // This deletes the extra arguments.
+      Call->setNumArgs(Context, NumArgsInProto);
+      return true;
+    }
+  }
+  llvm::SmallVector<Expr *, 8> AllArgs;
+  VariadicCallType CallType =
+    Proto->isVariadic() ? VariadicFunction : VariadicDoesNotApply;
+  if (Fn->getType()->isBlockPointerType())
+    CallType = VariadicBlock; // Block
+  else if (isa<MemberExpr>(Fn))
+    CallType = VariadicMethod;
+  Invalid = GatherArgumentsForCall(Call->getSourceRange().getBegin(), FDecl,
+                                   Proto, 0, Args, NumArgs, AllArgs, CallType);
+  if (Invalid)
+    return true;
+  unsigned TotalNumArgs = AllArgs.size();
+  for (unsigned i = 0; i < TotalNumArgs; ++i)
+    Call->setArg(i, AllArgs[i]);
+
+  return false;
+}
+
+bool Sema::GatherArgumentsForCall(SourceLocation CallLoc,
+                                  FunctionDecl *FDecl,
+                                  const FunctionProtoType *Proto,
+                                  unsigned FirstProtoArg,
+                                  Expr **Args, unsigned NumArgs,
+                                  llvm::SmallVector<Expr *, 8> &AllArgs,
+                                  VariadicCallType CallType) {
+  unsigned NumArgsInProto = Proto->getNumArgs();
+  unsigned NumArgsToCheck = NumArgs;
+  bool Invalid = false;
+  if (NumArgs != NumArgsInProto)
+    // Use default arguments for missing arguments
+    NumArgsToCheck = NumArgsInProto;
+  unsigned ArgIx = 0;
+  // Continue to check argument types (even if we have too few/many args).
+  for (unsigned i = FirstProtoArg; i != NumArgsToCheck; i++) {
+    QualType ProtoArgType = Proto->getArgType(i);
+
+    Expr *Arg;
+    if (ArgIx < NumArgs) {
+      Arg = Args[ArgIx++];
+
+      if (RequireCompleteType(Arg->getSourceRange().getBegin(),
+                              ProtoArgType,
+                              PDiag(diag::err_call_incomplete_argument)
+                              << Arg->getSourceRange()))
+        return true;
+
+      // Pass the argument
+      ParmVarDecl *Param = 0;
+      if (FDecl && i < FDecl->getNumParams())
+        Param = FDecl->getParamDecl(i);
+
+
+      InitializedEntity Entity =
+        Param? InitializedEntity::InitializeParameter(Param)
+             : InitializedEntity::InitializeParameter(ProtoArgType);
+      OwningExprResult ArgE = PerformCopyInitialization(Entity,
+                                                        SourceLocation(),
+                                                        Owned(Arg));
+      if (ArgE.isInvalid())
+        return true;
+
+      Arg = ArgE.takeAs<Expr>();
+    } else {
+      ParmVarDecl *Param = FDecl->getParamDecl(i);
+
+      OwningExprResult ArgExpr =
+        BuildCXXDefaultArgExpr(CallLoc, FDecl, Param);
+      if (ArgExpr.isInvalid())
+        return true;
+
+      Arg = ArgExpr.takeAs<Expr>();
+    }
+    AllArgs.push_back(Arg);
+  }
+
+  // If this is a variadic call, handle args passed through "...".
+  if (CallType != VariadicDoesNotApply) {
+    // Promote the arguments (C99 6.5.2.2p7).
+    for (unsigned i = ArgIx; i < NumArgs; i++) {
+      Expr *Arg = Args[i];
+      Invalid |= DefaultVariadicArgumentPromotion(Arg, CallType);
+      AllArgs.push_back(Arg);
+    }
+  }
+  return Invalid;
+}
+
+/// ActOnCallExpr - Handle a call to Fn with the specified array of arguments.
+/// This provides the location of the left/right parens and a list of comma
+/// locations.
+Action::OwningExprResult
+Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc,
+                    MultiExprArg args,
+                    SourceLocation *CommaLocs, SourceLocation RParenLoc) {
+  unsigned NumArgs = args.size();
+
+  // Since this might be a postfix expression, get rid of ParenListExprs.
+  fn = MaybeConvertParenListExprToParenExpr(S, move(fn));
+
+  Expr *Fn = fn.takeAs<Expr>();
+  Expr **Args = reinterpret_cast<Expr**>(args.release());
+  assert(Fn && "no function call expression");
+
+  if (getLangOptions().CPlusPlus) {
+    // If this is a pseudo-destructor expression, build the call immediately.
+    if (isa<CXXPseudoDestructorExpr>(Fn)) {
+      if (NumArgs > 0) {
+        // Pseudo-destructor calls should not have any arguments.
+        Diag(Fn->getLocStart(), diag::err_pseudo_dtor_call_with_args)
+          << FixItHint::CreateRemoval(
+                                    SourceRange(Args[0]->getLocStart(),
+                                                Args[NumArgs-1]->getLocEnd()));
+
+        for (unsigned I = 0; I != NumArgs; ++I)
+          Args[I]->Destroy(Context);
+
+        NumArgs = 0;
+      }
+
+      return Owned(new (Context) CallExpr(Context, Fn, 0, 0, Context.VoidTy,
+                                          RParenLoc));
+    }
+
+    // Determine whether this is a dependent call inside a C++ template,
+    // in which case we won't do any semantic analysis now.
+    // FIXME: Will need to cache the results of name lookup (including ADL) in
+    // Fn.
+    bool Dependent = false;
+    if (Fn->isTypeDependent())
+      Dependent = true;
+    else if (Expr::hasAnyTypeDependentArguments(Args, NumArgs))
+      Dependent = true;
+
+    if (Dependent)
+      return Owned(new (Context) CallExpr(Context, Fn, Args, NumArgs,
+                                          Context.DependentTy, RParenLoc));
+
+    // Determine whether this is a call to an object (C++ [over.call.object]).
+    if (Fn->getType()->isRecordType())
+      return Owned(BuildCallToObjectOfClassType(S, Fn, LParenLoc, Args, NumArgs,
+                                                CommaLocs, RParenLoc));
+
+    Expr *NakedFn = Fn->IgnoreParens();
+
+    // Determine whether this is a call to an unresolved member function.
+    if (UnresolvedMemberExpr *MemE = dyn_cast<UnresolvedMemberExpr>(NakedFn)) {
+      // If lookup was unresolved but not dependent (i.e. didn't find
+      // an unresolved using declaration), it has to be an overloaded
+      // function set, which means it must contain either multiple
+      // declarations (all methods or method templates) or a single
+      // method template.
+      assert((MemE->getNumDecls() > 1) ||
+             isa<FunctionTemplateDecl>(
+                                 (*MemE->decls_begin())->getUnderlyingDecl()));
+      (void)MemE;
+
+      return BuildCallToMemberFunction(S, Fn, LParenLoc, Args, NumArgs,
+                                       CommaLocs, RParenLoc);
+    }
+
+    // Determine whether this is a call to a member function.
+    if (MemberExpr *MemExpr = dyn_cast<MemberExpr>(NakedFn)) {
+      NamedDecl *MemDecl = MemExpr->getMemberDecl();
+      if (isa<CXXMethodDecl>(MemDecl))
+        return BuildCallToMemberFunction(S, Fn, LParenLoc, Args, NumArgs,
+                                         CommaLocs, RParenLoc);
+    }
+
+    // Determine whether this is a call to a pointer-to-member function.
+    if (BinaryOperator *BO = dyn_cast<BinaryOperator>(NakedFn)) {
+      if (BO->getOpcode() == BinaryOperator::PtrMemD ||
+          BO->getOpcode() == BinaryOperator::PtrMemI) {
+        if (const FunctionProtoType *FPT =
+              dyn_cast<FunctionProtoType>(BO->getType())) {
+          QualType ResultTy = FPT->getResultType().getNonReferenceType();
+
+          ExprOwningPtr<CXXMemberCallExpr>
+            TheCall(this, new (Context) CXXMemberCallExpr(Context, BO, Args,
+                                                          NumArgs, ResultTy,
+                                                          RParenLoc));
+
+          if (CheckCallReturnType(FPT->getResultType(),
+                                  BO->getRHS()->getSourceRange().getBegin(),
+                                  TheCall.get(), 0))
+            return ExprError();
+
+          if (ConvertArgumentsForCall(&*TheCall, BO, 0, FPT, Args, NumArgs,
+                                      RParenLoc))
+            return ExprError();
+
+          return Owned(MaybeBindToTemporary(TheCall.release()).release());
+        }
+        return ExprError(Diag(Fn->getLocStart(),
+                              diag::err_typecheck_call_not_function)
+                              << Fn->getType() << Fn->getSourceRange());
+      }
+    }
+  }
+
+  // If we're directly calling a function, get the appropriate declaration.
+  // Also, in C++, keep track of whether we should perform argument-dependent
+  // lookup and whether there were any explicitly-specified template arguments.
+
+  Expr *NakedFn = Fn->IgnoreParens();
+  if (isa<UnresolvedLookupExpr>(NakedFn)) {
+    UnresolvedLookupExpr *ULE = cast<UnresolvedLookupExpr>(NakedFn);
+    return BuildOverloadedCallExpr(S, Fn, ULE, LParenLoc, Args, NumArgs,
+                                   CommaLocs, RParenLoc);
+  }
+
+  NamedDecl *NDecl = 0;
+  if (isa<DeclRefExpr>(NakedFn))
+    NDecl = cast<DeclRefExpr>(NakedFn)->getDecl();
+
+  return BuildResolvedCallExpr(Fn, NDecl, LParenLoc, Args, NumArgs, RParenLoc);
+}
+
+/// BuildResolvedCallExpr - Build a call to a resolved expression,
+/// i.e. an expression not of \p OverloadTy.  The expression should
+/// unary-convert to an expression of function-pointer or
+/// block-pointer type.
+///
+/// \param NDecl the declaration being called, if available
+Sema::OwningExprResult
+Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl,
+                            SourceLocation LParenLoc,
+                            Expr **Args, unsigned NumArgs,
+                            SourceLocation RParenLoc) {
+  FunctionDecl *FDecl = dyn_cast_or_null<FunctionDecl>(NDecl);
+
+  // Promote the function operand.
+  UsualUnaryConversions(Fn);
+
+  // Make the call expr early, before semantic checks.  This guarantees cleanup
+  // of arguments and function on error.
+  ExprOwningPtr<CallExpr> TheCall(this, new (Context) CallExpr(Context, Fn,
+                                                               Args, NumArgs,
+                                                               Context.BoolTy,
+                                                               RParenLoc));
+
+  const FunctionType *FuncT;
+  if (!Fn->getType()->isBlockPointerType()) {
+    // C99 6.5.2.2p1 - "The expression that denotes the called function shall
+    // have type pointer to function".
+    const PointerType *PT = Fn->getType()->getAs<PointerType>();
+    if (PT == 0)
+      return ExprError(Diag(LParenLoc, diag::err_typecheck_call_not_function)
+        << Fn->getType() << Fn->getSourceRange());
+    FuncT = PT->getPointeeType()->getAs<FunctionType>();
+  } else { // This is a block call.
+    FuncT = Fn->getType()->getAs<BlockPointerType>()->getPointeeType()->
+                getAs<FunctionType>();
+  }
+  if (FuncT == 0)
+    return ExprError(Diag(LParenLoc, diag::err_typecheck_call_not_function)
+      << Fn->getType() << Fn->getSourceRange());
+
+  // Check for a valid return type
+  if (CheckCallReturnType(FuncT->getResultType(),
+                          Fn->getSourceRange().getBegin(), TheCall.get(),
+                          FDecl))
+    return ExprError();
+
+  // We know the result type of the call, set it.
+  TheCall->setType(FuncT->getResultType().getNonReferenceType());
+
+  if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FuncT)) {
+    if (ConvertArgumentsForCall(&*TheCall, Fn, FDecl, Proto, Args, NumArgs,
+                                RParenLoc))
+      return ExprError();
+  } else {
+    assert(isa<FunctionNoProtoType>(FuncT) && "Unknown FunctionType!");
+
+    if (FDecl) {
+      // Check if we have too few/too many template arguments, based
+      // on our knowledge of the function definition.
+      const FunctionDecl *Def = 0;
+      if (FDecl->getBody(Def) && NumArgs != Def->param_size()) {
+        const FunctionProtoType *Proto =
+            Def->getType()->getAs<FunctionProtoType>();
+        if (!Proto || !(Proto->isVariadic() && NumArgs >= Def->param_size())) {
+          Diag(RParenLoc, diag::warn_call_wrong_number_of_arguments)
+            << (NumArgs > Def->param_size()) << FDecl << Fn->getSourceRange();
+        }
+      }
+    }
+
+    // Promote the arguments (C99 6.5.2.2p6).
+    for (unsigned i = 0; i != NumArgs; i++) {
+      Expr *Arg = Args[i];
+      DefaultArgumentPromotion(Arg);
+      if (RequireCompleteType(Arg->getSourceRange().getBegin(),
+                              Arg->getType(),
+                              PDiag(diag::err_call_incomplete_argument)
+                                << Arg->getSourceRange()))
+        return ExprError();
+      TheCall->setArg(i, Arg);
+    }
+  }
+
+  if (CXXMethodDecl *Method = dyn_cast_or_null<CXXMethodDecl>(FDecl))
+    if (!Method->isStatic())
+      return ExprError(Diag(LParenLoc, diag::err_member_call_without_object)
+        << Fn->getSourceRange());
+
+  // Check for sentinels
+  if (NDecl)
+    DiagnoseSentinelCalls(NDecl, LParenLoc, Args, NumArgs);
+
+  // Do special checking on direct calls to functions.
+  if (FDecl) {
+    if (CheckFunctionCall(FDecl, TheCall.get()))
+      return ExprError();
+
+    if (unsigned BuiltinID = FDecl->getBuiltinID())
+      return CheckBuiltinFunctionCall(BuiltinID, TheCall.take());
+  } else if (NDecl) {
+    if (CheckBlockCall(NDecl, TheCall.get()))
+      return ExprError();
+  }
+
+  return MaybeBindToTemporary(TheCall.take());
+}
+
+Action::OwningExprResult
+Sema::ActOnCompoundLiteral(SourceLocation LParenLoc, TypeTy *Ty,
+                           SourceLocation RParenLoc, ExprArg InitExpr) {
+  assert((Ty != 0) && "ActOnCompoundLiteral(): missing type");
+  // FIXME: put back this assert when initializers are worked out.
+  //assert((InitExpr != 0) && "ActOnCompoundLiteral(): missing expression");
+
+  TypeSourceInfo *TInfo;
+  QualType literalType = GetTypeFromParser(Ty, &TInfo);
+  if (!TInfo)
+    TInfo = Context.getTrivialTypeSourceInfo(literalType);
+
+  return BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc, move(InitExpr));
+}
+
+Action::OwningExprResult
+Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo,
+                               SourceLocation RParenLoc, ExprArg InitExpr) {
+  QualType literalType = TInfo->getType();
+  Expr *literalExpr = static_cast<Expr*>(InitExpr.get());
+
+  if (literalType->isArrayType()) {
+    if (literalType->isVariableArrayType())
+      return ExprError(Diag(LParenLoc, diag::err_variable_object_no_init)
+        << SourceRange(LParenLoc, literalExpr->getSourceRange().getEnd()));
+  } else if (!literalType->isDependentType() &&
+             RequireCompleteType(LParenLoc, literalType,
+                      PDiag(diag::err_typecheck_decl_incomplete_type)
+                        << SourceRange(LParenLoc,
+                                       literalExpr->getSourceRange().getEnd())))
+    return ExprError();
+
+  InitializedEntity Entity
+    = InitializedEntity::InitializeTemporary(literalType);
+  InitializationKind Kind
+    = InitializationKind::CreateCast(SourceRange(LParenLoc, RParenLoc),
+                                     /*IsCStyleCast=*/true);
+  InitializationSequence InitSeq(*this, Entity, Kind, &literalExpr, 1);
+  OwningExprResult Result = InitSeq.Perform(*this, Entity, Kind,
+                                   MultiExprArg(*this, (void**)&literalExpr, 1),
+                                            &literalType);
+  if (Result.isInvalid())
+    return ExprError();
+  InitExpr.release();
+  literalExpr = static_cast<Expr*>(Result.get());
+
+  bool isFileScope = getCurFunctionOrMethodDecl() == 0;
+  if (isFileScope) { // 6.5.2.5p3
+    if (CheckForConstantInitializer(literalExpr, literalType))
+      return ExprError();
+  }
+
+  Result.release();
+
+  return Owned(new (Context) CompoundLiteralExpr(LParenLoc, TInfo, literalType,
+                                                 literalExpr, isFileScope));
+}
+
+Action::OwningExprResult
+Sema::ActOnInitList(SourceLocation LBraceLoc, MultiExprArg initlist,
+                    SourceLocation RBraceLoc) {
+  unsigned NumInit = initlist.size();
+  Expr **InitList = reinterpret_cast<Expr**>(initlist.release());
+
+  // Semantic analysis for initializers is done by ActOnDeclarator() and
+  // CheckInitializer() - it requires knowledge of the object being intialized.
+
+  InitListExpr *E = new (Context) InitListExpr(Context, LBraceLoc, InitList,
+                                               NumInit, RBraceLoc);
+  E->setType(Context.VoidTy); // FIXME: just a place holder for now.
+  return Owned(E);
+}
+
+static CastExpr::CastKind getScalarCastKind(ASTContext &Context,
+                                            QualType SrcTy, QualType DestTy) {
+  if (Context.hasSameUnqualifiedType(SrcTy, DestTy))
+    return CastExpr::CK_NoOp;
+
+  if (SrcTy->hasPointerRepresentation()) {
+    if (DestTy->hasPointerRepresentation())
+      return DestTy->isObjCObjectPointerType() ?
+                CastExpr::CK_AnyPointerToObjCPointerCast :
+                CastExpr::CK_BitCast;
+    if (DestTy->isIntegerType())
+      return CastExpr::CK_PointerToIntegral;
+  }
+
+  if (SrcTy->isIntegerType()) {
+    if (DestTy->isIntegerType())
+      return CastExpr::CK_IntegralCast;
+    if (DestTy->hasPointerRepresentation())
+      return CastExpr::CK_IntegralToPointer;
+    if (DestTy->isRealFloatingType())
+      return CastExpr::CK_IntegralToFloating;
+  }
+
+  if (SrcTy->isRealFloatingType()) {
+    if (DestTy->isRealFloatingType())
+      return CastExpr::CK_FloatingCast;
+    if (DestTy->isIntegerType())
+      return CastExpr::CK_FloatingToIntegral;
+  }
+
+  // FIXME: Assert here.
+  // assert(false && "Unhandled cast combination!");
+  return CastExpr::CK_Unknown;
+}
+
+/// CheckCastTypes - Check type constraints for casting between types.
+bool Sema::CheckCastTypes(SourceRange TyR, QualType castType, Expr *&castExpr,
+                          CastExpr::CastKind& Kind,
+                          CXXBaseSpecifierArray &BasePath,
+                          bool FunctionalStyle) {
+  if (getLangOptions().CPlusPlus)
+    return CXXCheckCStyleCast(TyR, castType, castExpr, Kind, BasePath,
+                              FunctionalStyle);
+
+  DefaultFunctionArrayLvalueConversion(castExpr);
+
+  // C99 6.5.4p2: the cast type needs to be void or scalar and the expression
+  // type needs to be scalar.
+  if (castType->isVoidType()) {
+    // Cast to void allows any expr type.
+    Kind = CastExpr::CK_ToVoid;
+    return false;
+  }
+
+  if (!castType->isScalarType() && !castType->isVectorType()) {
+    if (Context.hasSameUnqualifiedType(castType, castExpr->getType()) &&
+        (castType->isStructureType() || castType->isUnionType())) {
+      // GCC struct/union extension: allow cast to self.
+      // FIXME: Check that the cast destination type is complete.
+      Diag(TyR.getBegin(), diag::ext_typecheck_cast_nonscalar)
+        << castType << castExpr->getSourceRange();
+      Kind = CastExpr::CK_NoOp;
+      return false;
+    }
+
+    if (castType->isUnionType()) {
+      // GCC cast to union extension
+      RecordDecl *RD = castType->getAs<RecordType>()->getDecl();
+      RecordDecl::field_iterator Field, FieldEnd;
+      for (Field = RD->field_begin(), FieldEnd = RD->field_end();
+           Field != FieldEnd; ++Field) {
+        if (Context.hasSameUnqualifiedType(Field->getType(),
+                                           castExpr->getType())) {
+          Diag(TyR.getBegin(), diag::ext_typecheck_cast_to_union)
+            << castExpr->getSourceRange();
+          break;
+        }
+      }
+      if (Field == FieldEnd)
+        return Diag(TyR.getBegin(), diag::err_typecheck_cast_to_union_no_type)
+          << castExpr->getType() << castExpr->getSourceRange();
+      Kind = CastExpr::CK_ToUnion;
+      return false;
+    }
+
+    // Reject any other conversions to non-scalar types.
+    return Diag(TyR.getBegin(), diag::err_typecheck_cond_expect_scalar)
+      << castType << castExpr->getSourceRange();
+  }
+
+  if (!castExpr->getType()->isScalarType() &&
+      !castExpr->getType()->isVectorType()) {
+    return Diag(castExpr->getLocStart(),
+                diag::err_typecheck_expect_scalar_operand)
+      << castExpr->getType() << castExpr->getSourceRange();
+  }
+
+  if (castType->isExtVectorType())
+    return CheckExtVectorCast(TyR, castType, castExpr, Kind);
+
+  if (castType->isVectorType())
+    return CheckVectorCast(TyR, castType, castExpr->getType(), Kind);
+  if (castExpr->getType()->isVectorType())
+    return CheckVectorCast(TyR, castExpr->getType(), castType, Kind);
+
+  if (isa<ObjCSelectorExpr>(castExpr))
+    return Diag(castExpr->getLocStart(), diag::err_cast_selector_expr);
+
+  if (!castType->isArithmeticType()) {
+    QualType castExprType = castExpr->getType();
+    if (!castExprType->isIntegralType() && castExprType->isArithmeticType())
+      return Diag(castExpr->getLocStart(),
+                  diag::err_cast_pointer_from_non_pointer_int)
+        << castExprType << castExpr->getSourceRange();
+  } else if (!castExpr->getType()->isArithmeticType()) {
+    if (!castType->isIntegralType() && castType->isArithmeticType())
+      return Diag(castExpr->getLocStart(),
+                  diag::err_cast_pointer_to_non_pointer_int)
+        << castType << castExpr->getSourceRange();
+  }
+
+  Kind = getScalarCastKind(Context, castExpr->getType(), castType);
+  return false;
+}
+
+bool Sema::CheckVectorCast(SourceRange R, QualType VectorTy, QualType Ty,
+                           CastExpr::CastKind &Kind) {
+  assert(VectorTy->isVectorType() && "Not a vector type!");
+
+  if (Ty->isVectorType() || Ty->isIntegerType()) {
+    if (Context.getTypeSize(VectorTy) != Context.getTypeSize(Ty))
+      return Diag(R.getBegin(),
+                  Ty->isVectorType() ?
+                  diag::err_invalid_conversion_between_vectors :
+                  diag::err_invalid_conversion_between_vector_and_integer)
+        << VectorTy << Ty << R;
+  } else
+    return Diag(R.getBegin(),
+                diag::err_invalid_conversion_between_vector_and_scalar)
+      << VectorTy << Ty << R;
+
+  Kind = CastExpr::CK_BitCast;
+  return false;
+}
+
+bool Sema::CheckExtVectorCast(SourceRange R, QualType DestTy, Expr *&CastExpr,
+                              CastExpr::CastKind &Kind) {
+  assert(DestTy->isExtVectorType() && "Not an extended vector type!");
+
+  QualType SrcTy = CastExpr->getType();
+
+  // If SrcTy is a VectorType, the total size must match to explicitly cast to
+  // an ExtVectorType.
+  if (SrcTy->isVectorType()) {
+    if (Context.getTypeSize(DestTy) != Context.getTypeSize(SrcTy))
+      return Diag(R.getBegin(),diag::err_invalid_conversion_between_ext_vectors)
+        << DestTy << SrcTy << R;
+    Kind = CastExpr::CK_BitCast;
+    return false;
+  }
+
+  // All non-pointer scalars can be cast to ExtVector type.  The appropriate
+  // conversion will take place first from scalar to elt type, and then
+  // splat from elt type to vector.
+  if (SrcTy->isPointerType())
+    return Diag(R.getBegin(),
+                diag::err_invalid_conversion_between_vector_and_scalar)
+      << DestTy << SrcTy << R;
+
+  QualType DestElemTy = DestTy->getAs<ExtVectorType>()->getElementType();
+  ImpCastExprToType(CastExpr, DestElemTy,
+                    getScalarCastKind(Context, SrcTy, DestElemTy));
+
+  Kind = CastExpr::CK_VectorSplat;
+  return false;
+}
+
+Action::OwningExprResult
+Sema::ActOnCastExpr(Scope *S, SourceLocation LParenLoc, TypeTy *Ty,
+                    SourceLocation RParenLoc, ExprArg Op) {
+  assert((Ty != 0) && (Op.get() != 0) &&
+         "ActOnCastExpr(): missing type or expr");
+
+  TypeSourceInfo *castTInfo;
+  QualType castType = GetTypeFromParser(Ty, &castTInfo);
+  if (!castTInfo)
+    castTInfo = Context.getTrivialTypeSourceInfo(castType);
+
+  // If the Expr being casted is a ParenListExpr, handle it specially.
+  Expr *castExpr = (Expr *)Op.get();
+  if (isa<ParenListExpr>(castExpr))
+    return ActOnCastOfParenListExpr(S, LParenLoc, RParenLoc, move(Op),
+                                    castTInfo);
+
+  return BuildCStyleCastExpr(LParenLoc, castTInfo, RParenLoc, move(Op));
+}
+
+Action::OwningExprResult
+Sema::BuildCStyleCastExpr(SourceLocation LParenLoc, TypeSourceInfo *Ty,
+                          SourceLocation RParenLoc, ExprArg Op) {
+  Expr *castExpr = static_cast<Expr*>(Op.get());
+
+  CastExpr::CastKind Kind = CastExpr::CK_Unknown;
+  CXXBaseSpecifierArray BasePath;
+  if (CheckCastTypes(SourceRange(LParenLoc, RParenLoc), Ty->getType(), castExpr,
+                     Kind, BasePath))
+    return ExprError();
+
+  Op.release();
+  return Owned(new (Context) CStyleCastExpr(Ty->getType().getNonReferenceType(),
+                                            Kind, castExpr, BasePath, Ty,
+                                            LParenLoc, RParenLoc));
+}
+
+/// This is not an AltiVec-style cast, so turn the ParenListExpr into a sequence
+/// of comma binary operators.
+Action::OwningExprResult
+Sema::MaybeConvertParenListExprToParenExpr(Scope *S, ExprArg EA) {
+  Expr *expr = EA.takeAs<Expr>();
+  ParenListExpr *E = dyn_cast<ParenListExpr>(expr);
+  if (!E)
+    return Owned(expr);
+
+  OwningExprResult Result(*this, E->getExpr(0));
+
+  for (unsigned i = 1, e = E->getNumExprs(); i != e && !Result.isInvalid(); ++i)
+    Result = ActOnBinOp(S, E->getExprLoc(), tok::comma, move(Result),
+                        Owned(E->getExpr(i)));
+
+  return ActOnParenExpr(E->getLParenLoc(), E->getRParenLoc(), move(Result));
+}
+
+Action::OwningExprResult
+Sema::ActOnCastOfParenListExpr(Scope *S, SourceLocation LParenLoc,
+                               SourceLocation RParenLoc, ExprArg Op,
+                               TypeSourceInfo *TInfo) {
+  ParenListExpr *PE = (ParenListExpr *)Op.get();
+  QualType Ty = TInfo->getType();
+
+  // If this is an altivec initializer, '(' type ')' '(' init, ..., init ')'
+  // then handle it as such.
+  if (getLangOptions().AltiVec && Ty->isVectorType()) {
+    if (PE->getNumExprs() == 0) {
+      Diag(PE->getExprLoc(), diag::err_altivec_empty_initializer);
+      return ExprError();
+    }
+
+    llvm::SmallVector<Expr *, 8> initExprs;
+    for (unsigned i = 0, e = PE->getNumExprs(); i != e; ++i)
+      initExprs.push_back(PE->getExpr(i));
+
+    // FIXME: This means that pretty-printing the final AST will produce curly
+    // braces instead of the original commas.
+    Op.release();
+    InitListExpr *E = new (Context) InitListExpr(Context, LParenLoc,
+                                                 &initExprs[0],
+                                                 initExprs.size(), RParenLoc);
+    E->setType(Ty);
+    return BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc, Owned(E));
+  } else {
+    // This is not an AltiVec-style cast, so turn the ParenListExpr into a
+    // sequence of BinOp comma operators.
+    Op = MaybeConvertParenListExprToParenExpr(S, move(Op));
+    return BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc, move(Op));
+  }
+}
+
+Action::OwningExprResult Sema::ActOnParenOrParenListExpr(SourceLocation L,
+                                                  SourceLocation R,
+                                                  MultiExprArg Val,
+                                                  TypeTy *TypeOfCast) {
+  unsigned nexprs = Val.size();
+  Expr **exprs = reinterpret_cast<Expr**>(Val.release());
+  assert((exprs != 0) && "ActOnParenOrParenListExpr() missing expr list");
+  Expr *expr;
+  if (nexprs == 1 && TypeOfCast && !TypeIsVectorType(TypeOfCast))
+    expr = new (Context) ParenExpr(L, R, exprs[0]);
+  else
+    expr = new (Context) ParenListExpr(Context, L, exprs, nexprs, R);
+  return Owned(expr);
+}
+
+/// Note that lhs is not null here, even if this is the gnu "x ?: y" extension.
+/// In that case, lhs = cond.
+/// C99 6.5.15
+QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS,
+                                        SourceLocation QuestionLoc) {
+  // C++ is sufficiently different to merit its own checker.
+  if (getLangOptions().CPlusPlus)
+    return CXXCheckConditionalOperands(Cond, LHS, RHS, QuestionLoc);
+
+  CheckSignCompare(LHS, RHS, QuestionLoc);
+
+  UsualUnaryConversions(Cond);
+  UsualUnaryConversions(LHS);
+  UsualUnaryConversions(RHS);
+  QualType CondTy = Cond->getType();
+  QualType LHSTy = LHS->getType();
+  QualType RHSTy = RHS->getType();
+
+  // first, check the condition.
+  if (!CondTy->isScalarType()) { // C99 6.5.15p2
+    Diag(Cond->getLocStart(), diag::err_typecheck_cond_expect_scalar)
+      << CondTy;
+    return QualType();
+  }
+
+  // Now check the two expressions.
+  if (LHSTy->isVectorType() || RHSTy->isVectorType())
+    return CheckVectorOperands(QuestionLoc, LHS, RHS);
+
+  // If both operands have arithmetic type, do the usual arithmetic conversions
+  // to find a common type: C99 6.5.15p3,5.
+  if (LHSTy->isArithmeticType() && RHSTy->isArithmeticType()) {
+    UsualArithmeticConversions(LHS, RHS);
+    return LHS->getType();
+  }
+
+  // If both operands are the same structure or union type, the result is that
+  // type.
+  if (const RecordType *LHSRT = LHSTy->getAs<RecordType>()) {    // C99 6.5.15p3
+    if (const RecordType *RHSRT = RHSTy->getAs<RecordType>())
+      if (LHSRT->getDecl() == RHSRT->getDecl())
+        // "If both the operands have structure or union type, the result has
+        // that type."  This implies that CV qualifiers are dropped.
+        return LHSTy.getUnqualifiedType();
+    // FIXME: Type of conditional expression must be complete in C mode.
+  }
+
+  // C99 6.5.15p5: "If both operands have void type, the result has void type."
+  // The following || allows only one side to be void (a GCC-ism).
+  if (LHSTy->isVoidType() || RHSTy->isVoidType()) {
+    if (!LHSTy->isVoidType())
+      Diag(RHS->getLocStart(), diag::ext_typecheck_cond_one_void)
+        << RHS->getSourceRange();
+    if (!RHSTy->isVoidType())
+      Diag(LHS->getLocStart(), diag::ext_typecheck_cond_one_void)
+        << LHS->getSourceRange();
+    ImpCastExprToType(LHS, Context.VoidTy, CastExpr::CK_ToVoid);
+    ImpCastExprToType(RHS, Context.VoidTy, CastExpr::CK_ToVoid);
+    return Context.VoidTy;
+  }
+  // C99 6.5.15p6 - "if one operand is a null pointer constant, the result has
+  // the type of the other operand."
+  if ((LHSTy->isAnyPointerType() || LHSTy->isBlockPointerType()) &&
+      RHS->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) {
+    // promote the null to a pointer.
+    ImpCastExprToType(RHS, LHSTy, CastExpr::CK_Unknown);
+    return LHSTy;
+  }
+  if ((RHSTy->isAnyPointerType() || RHSTy->isBlockPointerType()) &&
+      LHS->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) {
+    ImpCastExprToType(LHS, RHSTy, CastExpr::CK_Unknown);
+    return RHSTy;
+  }
+
+  // All objective-c pointer type analysis is done here.
+  QualType compositeType = FindCompositeObjCPointerType(LHS, RHS,
+                                                        QuestionLoc);
+  if (!compositeType.isNull())
+    return compositeType;
+
+
+  // Handle block pointer types.
+  if (LHSTy->isBlockPointerType() || RHSTy->isBlockPointerType()) {
+    if (!LHSTy->isBlockPointerType() || !RHSTy->isBlockPointerType()) {
+      if (LHSTy->isVoidPointerType() || RHSTy->isVoidPointerType()) {
+        QualType destType = Context.getPointerType(Context.VoidTy);
+        ImpCastExprToType(LHS, destType, CastExpr::CK_BitCast);
+        ImpCastExprToType(RHS, destType, CastExpr::CK_BitCast);
+        return destType;
+      }
+      Diag(QuestionLoc, diag::err_typecheck_cond_incompatible_operands)
+      << LHSTy << RHSTy << LHS->getSourceRange() << RHS->getSourceRange();
+      return QualType();
+    }
+    // We have 2 block pointer types.
+    if (Context.getCanonicalType(LHSTy) == Context.getCanonicalType(RHSTy)) {
+      // Two identical block pointer types are always compatible.
+      return LHSTy;
+    }
+    // The block pointer types aren't identical, continue checking.
+    QualType lhptee = LHSTy->getAs<BlockPointerType>()->getPointeeType();
+    QualType rhptee = RHSTy->getAs<BlockPointerType>()->getPointeeType();
+
+    if (!Context.typesAreCompatible(lhptee.getUnqualifiedType(),
+                                    rhptee.getUnqualifiedType())) {
+      Diag(QuestionLoc, diag::warn_typecheck_cond_incompatible_pointers)
+      << LHSTy << RHSTy << LHS->getSourceRange() << RHS->getSourceRange();
+      // In this situation, we assume void* type. No especially good
+      // reason, but this is what gcc does, and we do have to pick
+      // to get a consistent AST.
+      QualType incompatTy = Context.getPointerType(Context.VoidTy);
+      ImpCastExprToType(LHS, incompatTy, CastExpr::CK_BitCast);
+      ImpCastExprToType(RHS, incompatTy, CastExpr::CK_BitCast);
+      return incompatTy;
+    }
+    // The block pointer types are compatible.
+    ImpCastExprToType(LHS, LHSTy, CastExpr::CK_BitCast);
+    ImpCastExprToType(RHS, LHSTy, CastExpr::CK_BitCast);
+    return LHSTy;
+  }
+
+  // Check constraints for C object pointers types (C99 6.5.15p3,6).
+  if (LHSTy->isPointerType() && RHSTy->isPointerType()) {
+    // get the "pointed to" types
+    QualType lhptee = LHSTy->getAs<PointerType>()->getPointeeType();
+    QualType rhptee = RHSTy->getAs<PointerType>()->getPointeeType();
+
+    // ignore qualifiers on void (C99 6.5.15p3, clause 6)
+    if (lhptee->isVoidType() && rhptee->isIncompleteOrObjectType()) {
+      // Figure out necessary qualifiers (C99 6.5.15p6)
+      QualType destPointee
+        = Context.getQualifiedType(lhptee, rhptee.getQualifiers());
+      QualType destType = Context.getPointerType(destPointee);
+      // Add qualifiers if necessary.
+      ImpCastExprToType(LHS, destType, CastExpr::CK_NoOp);
+      // Promote to void*.
+      ImpCastExprToType(RHS, destType, CastExpr::CK_BitCast);
+      return destType;
+    }
+    if (rhptee->isVoidType() && lhptee->isIncompleteOrObjectType()) {
+      QualType destPointee
+        = Context.getQualifiedType(rhptee, lhptee.getQualifiers());
+      QualType destType = Context.getPointerType(destPointee);
+      // Add qualifiers if necessary.
+      ImpCastExprToType(RHS, destType, CastExpr::CK_NoOp);
+      // Promote to void*.
+      ImpCastExprToType(LHS, destType, CastExpr::CK_BitCast);
+      return destType;
+    }
+
+    if (Context.getCanonicalType(LHSTy) == Context.getCanonicalType(RHSTy)) {
+      // Two identical pointer types are always compatible.
+      return LHSTy;
+    }
+    if (!Context.typesAreCompatible(lhptee.getUnqualifiedType(),
+                                    rhptee.getUnqualifiedType())) {
+      Diag(QuestionLoc, diag::warn_typecheck_cond_incompatible_pointers)
+        << LHSTy << RHSTy << LHS->getSourceRange() << RHS->getSourceRange();
+      // In this situation, we assume void* type. No especially good
+      // reason, but this is what gcc does, and we do have to pick
+      // to get a consistent AST.
+      QualType incompatTy = Context.getPointerType(Context.VoidTy);
+      ImpCastExprToType(LHS, incompatTy, CastExpr::CK_BitCast);
+      ImpCastExprToType(RHS, incompatTy, CastExpr::CK_BitCast);
+      return incompatTy;
+    }
+    // The pointer types are compatible.
+    // C99 6.5.15p6: If both operands are pointers to compatible types *or* to
+    // differently qualified versions of compatible types, the result type is
+    // a pointer to an appropriately qualified version of the *composite*
+    // type.
+    // FIXME: Need to calculate the composite type.
+    // FIXME: Need to add qualifiers
+    ImpCastExprToType(LHS, LHSTy, CastExpr::CK_BitCast);
+    ImpCastExprToType(RHS, LHSTy, CastExpr::CK_BitCast);
+    return LHSTy;
+  }
+
+  // GCC compatibility: soften pointer/integer mismatch.
+  if (RHSTy->isPointerType() && LHSTy->isIntegerType()) {
+    Diag(QuestionLoc, diag::warn_typecheck_cond_pointer_integer_mismatch)
+      << LHSTy << RHSTy << LHS->getSourceRange() << RHS->getSourceRange();
+    ImpCastExprToType(LHS, RHSTy, CastExpr::CK_IntegralToPointer);
+    return RHSTy;
+  }
+  if (LHSTy->isPointerType() && RHSTy->isIntegerType()) {
+    Diag(QuestionLoc, diag::warn_typecheck_cond_pointer_integer_mismatch)
+      << LHSTy << RHSTy << LHS->getSourceRange() << RHS->getSourceRange();
+    ImpCastExprToType(RHS, LHSTy, CastExpr::CK_IntegralToPointer);
+    return LHSTy;
+  }
+
+  // Otherwise, the operands are not compatible.
+  Diag(QuestionLoc, diag::err_typecheck_cond_incompatible_operands)
+    << LHSTy << RHSTy << LHS->getSourceRange() << RHS->getSourceRange();
+  return QualType();
+}
+
+/// FindCompositeObjCPointerType - Helper method to find composite type of
+/// two objective-c pointer types of the two input expressions.
+QualType Sema::FindCompositeObjCPointerType(Expr *&LHS, Expr *&RHS,
+                                        SourceLocation QuestionLoc) {
+  QualType LHSTy = LHS->getType();
+  QualType RHSTy = RHS->getType();
+
+  // Handle things like Class and struct objc_class*.  Here we case the result
+  // to the pseudo-builtin, because that will be implicitly cast back to the
+  // redefinition type if an attempt is made to access its fields.
+  if (LHSTy->isObjCClassType() &&
+      (RHSTy.getDesugaredType() == Context.ObjCClassRedefinitionType)) {
+    ImpCastExprToType(RHS, LHSTy, CastExpr::CK_BitCast);
+    return LHSTy;
+  }
+  if (RHSTy->isObjCClassType() &&
+      (LHSTy.getDesugaredType() == Context.ObjCClassRedefinitionType)) {
+    ImpCastExprToType(LHS, RHSTy, CastExpr::CK_BitCast);
+    return RHSTy;
+  }
+  // And the same for struct objc_object* / id
+  if (LHSTy->isObjCIdType() &&
+      (RHSTy.getDesugaredType() == Context.ObjCIdRedefinitionType)) {
+    ImpCastExprToType(RHS, LHSTy, CastExpr::CK_BitCast);
+    return LHSTy;
+  }
+  if (RHSTy->isObjCIdType() &&
+      (LHSTy.getDesugaredType() == Context.ObjCIdRedefinitionType)) {
+    ImpCastExprToType(LHS, RHSTy, CastExpr::CK_BitCast);
+    return RHSTy;
+  }
+  // And the same for struct objc_selector* / SEL
+  if (Context.isObjCSelType(LHSTy) &&
+      (RHSTy.getDesugaredType() == Context.ObjCSelRedefinitionType)) {
+    ImpCastExprToType(RHS, LHSTy, CastExpr::CK_BitCast);
+    return LHSTy;
+  }
+  if (Context.isObjCSelType(RHSTy) &&
+      (LHSTy.getDesugaredType() == Context.ObjCSelRedefinitionType)) {
+    ImpCastExprToType(LHS, RHSTy, CastExpr::CK_BitCast);
+    return RHSTy;
+  }
+  // Check constraints for Objective-C object pointers types.
+  if (LHSTy->isObjCObjectPointerType() && RHSTy->isObjCObjectPointerType()) {
+
+    if (Context.getCanonicalType(LHSTy) == Context.getCanonicalType(RHSTy)) {
+      // Two identical object pointer types are always compatible.
+      return LHSTy;
+    }
+    const ObjCObjectPointerType *LHSOPT = LHSTy->getAs<ObjCObjectPointerType>();
+    const ObjCObjectPointerType *RHSOPT = RHSTy->getAs<ObjCObjectPointerType>();
+    QualType compositeType = LHSTy;
+
+    // If both operands are interfaces and either operand can be
+    // assigned to the other, use that type as the composite
+    // type. This allows
+    //   xxx ? (A*) a : (B*) b
+    // where B is a subclass of A.
+    //
+    // Additionally, as for assignment, if either type is 'id'
+    // allow silent coercion. Finally, if the types are
+    // incompatible then make sure to use 'id' as the composite
+    // type so the result is acceptable for sending messages to.
+
+    // FIXME: Consider unifying with 'areComparableObjCPointerTypes'.
+    // It could return the composite type.
+    if (Context.canAssignObjCInterfaces(LHSOPT, RHSOPT)) {
+      compositeType = RHSOPT->isObjCBuiltinType() ? RHSTy : LHSTy;
+    } else if (Context.canAssignObjCInterfaces(RHSOPT, LHSOPT)) {
+      compositeType = LHSOPT->isObjCBuiltinType() ? LHSTy : RHSTy;
+    } else if ((LHSTy->isObjCQualifiedIdType() ||
+                RHSTy->isObjCQualifiedIdType()) &&
+               Context.ObjCQualifiedIdTypesAreCompatible(LHSTy, RHSTy, true)) {
+      // Need to handle "id<xx>" explicitly.
+      // GCC allows qualified id and any Objective-C type to devolve to
+      // id. Currently localizing to here until clear this should be
+      // part of ObjCQualifiedIdTypesAreCompatible.
+      compositeType = Context.getObjCIdType();
+    } else if (LHSTy->isObjCIdType() || RHSTy->isObjCIdType()) {
+      compositeType = Context.getObjCIdType();
+    } else if (!(compositeType =
+                 Context.areCommonBaseCompatible(LHSOPT, RHSOPT)).isNull())
+      ;
+    else {
+      Diag(QuestionLoc, diag::ext_typecheck_cond_incompatible_operands)
+      << LHSTy << RHSTy
+      << LHS->getSourceRange() << RHS->getSourceRange();
+      QualType incompatTy = Context.getObjCIdType();
+      ImpCastExprToType(LHS, incompatTy, CastExpr::CK_BitCast);
+      ImpCastExprToType(RHS, incompatTy, CastExpr::CK_BitCast);
+      return incompatTy;
+    }
+    // The object pointer types are compatible.
+    ImpCastExprToType(LHS, compositeType, CastExpr::CK_BitCast);
+    ImpCastExprToType(RHS, compositeType, CastExpr::CK_BitCast);
+    return compositeType;
+  }
+  // Check Objective-C object pointer types and 'void *'
+  if (LHSTy->isVoidPointerType() && RHSTy->isObjCObjectPointerType()) {
+    QualType lhptee = LHSTy->getAs<PointerType>()->getPointeeType();
+    QualType rhptee = RHSTy->getAs<ObjCObjectPointerType>()->getPointeeType();
+    QualType destPointee
+    = Context.getQualifiedType(lhptee, rhptee.getQualifiers());
+    QualType destType = Context.getPointerType(destPointee);
+    // Add qualifiers if necessary.
+    ImpCastExprToType(LHS, destType, CastExpr::CK_NoOp);
+    // Promote to void*.
+    ImpCastExprToType(RHS, destType, CastExpr::CK_BitCast);
+    return destType;
+  }
+  if (LHSTy->isObjCObjectPointerType() && RHSTy->isVoidPointerType()) {
+    QualType lhptee = LHSTy->getAs<ObjCObjectPointerType>()->getPointeeType();
+    QualType rhptee = RHSTy->getAs<PointerType>()->getPointeeType();
+    QualType destPointee
+    = Context.getQualifiedType(rhptee, lhptee.getQualifiers());
+    QualType destType = Context.getPointerType(destPointee);
+    // Add qualifiers if necessary.
+    ImpCastExprToType(RHS, destType, CastExpr::CK_NoOp);
+    // Promote to void*.
+    ImpCastExprToType(LHS, destType, CastExpr::CK_BitCast);
+    return destType;
+  }
+  return QualType();
+}
+
+/// ActOnConditionalOp - Parse a ?: operation.  Note that 'LHS' may be null
+/// in the case of a the GNU conditional expr extension.
+Action::OwningExprResult Sema::ActOnConditionalOp(SourceLocation QuestionLoc,
+                                                  SourceLocation ColonLoc,
+                                                  ExprArg Cond, ExprArg LHS,
+                                                  ExprArg RHS) {
+  Expr *CondExpr = (Expr *) Cond.get();
+  Expr *LHSExpr = (Expr *) LHS.get(), *RHSExpr = (Expr *) RHS.get();
+
+  // If this is the gnu "x ?: y" extension, analyze the types as though the LHS
+  // was the condition.
+  bool isLHSNull = LHSExpr == 0;
+  if (isLHSNull)
+    LHSExpr = CondExpr;
+
+  QualType result = CheckConditionalOperands(CondExpr, LHSExpr,
+                                             RHSExpr, QuestionLoc);
+  if (result.isNull())
+    return ExprError();
+
+  Cond.release();
+  LHS.release();
+  RHS.release();
+  return Owned(new (Context) ConditionalOperator(CondExpr, QuestionLoc,
+                                                 isLHSNull ? 0 : LHSExpr,
+                                                 ColonLoc, RHSExpr, result));
+}
+
+// CheckPointerTypesForAssignment - This is a very tricky routine (despite
+// being closely modeled after the C99 spec:-). The odd characteristic of this
+// routine is it effectively iqnores the qualifiers on the top level pointee.
+// This circumvents the usual type rules specified in 6.2.7p1 & 6.7.5.[1-3].
+// FIXME: add a couple examples in this comment.
+Sema::AssignConvertType
+Sema::CheckPointerTypesForAssignment(QualType lhsType, QualType rhsType) {
+  QualType lhptee, rhptee;
+
+  if ((lhsType->isObjCClassType() &&
+       (rhsType.getDesugaredType() == Context.ObjCClassRedefinitionType)) ||
+     (rhsType->isObjCClassType() &&
+       (lhsType.getDesugaredType() == Context.ObjCClassRedefinitionType))) {
+      return Compatible;
+  }
+
+  // get the "pointed to" type (ignoring qualifiers at the top level)
+  lhptee = lhsType->getAs<PointerType>()->getPointeeType();
+  rhptee = rhsType->getAs<PointerType>()->getPointeeType();
+
+  // make sure we operate on the canonical type
+  lhptee = Context.getCanonicalType(lhptee);
+  rhptee = Context.getCanonicalType(rhptee);
+
+  AssignConvertType ConvTy = Compatible;
+
+  // C99 6.5.16.1p1: This following citation is common to constraints
+  // 3 & 4 (below). ...and the type *pointed to* by the left has all the
+  // qualifiers of the type *pointed to* by the right;
+  // FIXME: Handle ExtQualType
+  if (!lhptee.isAtLeastAsQualifiedAs(rhptee))
+    ConvTy = CompatiblePointerDiscardsQualifiers;
+
+  // C99 6.5.16.1p1 (constraint 4): If one operand is a pointer to an object or
+  // incomplete type and the other is a pointer to a qualified or unqualified
+  // version of void...
+  if (lhptee->isVoidType()) {
+    if (rhptee->isIncompleteOrObjectType())
+      return ConvTy;
+
+    // As an extension, we allow cast to/from void* to function pointer.
+    assert(rhptee->isFunctionType());
+    return FunctionVoidPointer;
+  }
+
+  if (rhptee->isVoidType()) {
+    if (lhptee->isIncompleteOrObjectType())
+      return ConvTy;
+
+    // As an extension, we allow cast to/from void* to function pointer.
+    assert(lhptee->isFunctionType());
+    return FunctionVoidPointer;
+  }
+  // C99 6.5.16.1p1 (constraint 3): both operands are pointers to qualified or
+  // unqualified versions of compatible types, ...
+  lhptee = lhptee.getUnqualifiedType();
+  rhptee = rhptee.getUnqualifiedType();
+  if (!Context.typesAreCompatible(lhptee, rhptee)) {
+    // Check if the pointee types are compatible ignoring the sign.
+    // We explicitly check for char so that we catch "char" vs
+    // "unsigned char" on systems where "char" is unsigned.
+    if (lhptee->isCharType())
+      lhptee = Context.UnsignedCharTy;
+    else if (lhptee->isSignedIntegerType())
+      lhptee = Context.getCorrespondingUnsignedType(lhptee);
+
+    if (rhptee->isCharType())
+      rhptee = Context.UnsignedCharTy;
+    else if (rhptee->isSignedIntegerType())
+      rhptee = Context.getCorrespondingUnsignedType(rhptee);
+
+    if (lhptee == rhptee) {
+      // Types are compatible ignoring the sign. Qualifier incompatibility
+      // takes priority over sign incompatibility because the sign
+      // warning can be disabled.
+      if (ConvTy != Compatible)
+        return ConvTy;
+      return IncompatiblePointerSign;
+    }
+
+    // If we are a multi-level pointer, it's possible that our issue is simply
+    // one of qualification - e.g. char ** -> const char ** is not allowed. If
+    // the eventual target type is the same and the pointers have the same
+    // level of indirection, this must be the issue.
+    if (lhptee->isPointerType() && rhptee->isPointerType()) {
+      do {
+        lhptee = lhptee->getAs<PointerType>()->getPointeeType();
+        rhptee = rhptee->getAs<PointerType>()->getPointeeType();
+
+        lhptee = Context.getCanonicalType(lhptee);
+        rhptee = Context.getCanonicalType(rhptee);
+      } while (lhptee->isPointerType() && rhptee->isPointerType());
+
+      if (Context.hasSameUnqualifiedType(lhptee, rhptee))
+        return IncompatibleNestedPointerQualifiers;
+    }
+
+    // General pointer incompatibility takes priority over qualifiers.
+    return IncompatiblePointer;
+  }
+  return ConvTy;
+}
+
+/// CheckBlockPointerTypesForAssignment - This routine determines whether two
+/// block pointer types are compatible or whether a block and normal pointer
+/// are compatible. It is more restrict than comparing two function pointer
+// types.
+Sema::AssignConvertType
+Sema::CheckBlockPointerTypesForAssignment(QualType lhsType,
+                                          QualType rhsType) {
+  QualType lhptee, rhptee;
+
+  // get the "pointed to" type (ignoring qualifiers at the top level)
+  lhptee = lhsType->getAs<BlockPointerType>()->getPointeeType();
+  rhptee = rhsType->getAs<BlockPointerType>()->getPointeeType();
+
+  // make sure we operate on the canonical type
+  lhptee = Context.getCanonicalType(lhptee);
+  rhptee = Context.getCanonicalType(rhptee);
+
+  AssignConvertType ConvTy = Compatible;
+
+  // For blocks we enforce that qualifiers are identical.
+  if (lhptee.getLocalCVRQualifiers() != rhptee.getLocalCVRQualifiers())
+    ConvTy = CompatiblePointerDiscardsQualifiers;
+
+  if (!getLangOptions().CPlusPlus) {
+    if (!Context.typesAreBlockPointerCompatible(lhsType, rhsType))
+      return IncompatibleBlockPointer;
+  }
+  else if (!Context.typesAreCompatible(lhptee, rhptee))
+    return IncompatibleBlockPointer;
+  return ConvTy;
+}
+
+/// CheckObjCPointerTypesForAssignment - Compares two objective-c pointer types
+/// for assignment compatibility.
+Sema::AssignConvertType
+Sema::CheckObjCPointerTypesForAssignment(QualType lhsType, QualType rhsType) {
+  if (lhsType->isObjCBuiltinType()) {
+    // Class is not compatible with ObjC object pointers.
+    if (lhsType->isObjCClassType() && !rhsType->isObjCBuiltinType() &&
+        !rhsType->isObjCQualifiedClassType())
+      return IncompatiblePointer;
+    return Compatible;
+  }
+  if (rhsType->isObjCBuiltinType()) {
+    // Class is not compatible with ObjC object pointers.
+    if (rhsType->isObjCClassType() && !lhsType->isObjCBuiltinType() &&
+        !lhsType->isObjCQualifiedClassType())
+      return IncompatiblePointer;
+    return Compatible;
+  }
+  QualType lhptee =
+  lhsType->getAs<ObjCObjectPointerType>()->getPointeeType();
+  QualType rhptee =
+  rhsType->getAs<ObjCObjectPointerType>()->getPointeeType();
+  // make sure we operate on the canonical type
+  lhptee = Context.getCanonicalType(lhptee);
+  rhptee = Context.getCanonicalType(rhptee);
+  if (!lhptee.isAtLeastAsQualifiedAs(rhptee))
+    return CompatiblePointerDiscardsQualifiers;
+
+  if (Context.typesAreCompatible(lhsType, rhsType))
+    return Compatible;
+  if (lhsType->isObjCQualifiedIdType() || rhsType->isObjCQualifiedIdType())
+    return IncompatibleObjCQualifiedId;
+  return IncompatiblePointer;
+}
+
+/// CheckAssignmentConstraints (C99 6.5.16) - This routine currently
+/// has code to accommodate several GCC extensions when type checking
+/// pointers. Here are some objectionable examples that GCC considers warnings:
+///
+///  int a, *pint;
+///  short *pshort;
+///  struct foo *pfoo;
+///
+///  pint = pshort; // warning: assignment from incompatible pointer type
+///  a = pint; // warning: assignment makes integer from pointer without a cast
+///  pint = a; // warning: assignment makes pointer from integer without a cast
+///  pint = pfoo; // warning: assignment from incompatible pointer type
+///
+/// As a result, the code for dealing with pointers is more complex than the
+/// C99 spec dictates.
+///
+Sema::AssignConvertType
+Sema::CheckAssignmentConstraints(QualType lhsType, QualType rhsType) {
+  // Get canonical types.  We're not formatting these types, just comparing
+  // them.
+  lhsType = Context.getCanonicalType(lhsType).getUnqualifiedType();
+  rhsType = Context.getCanonicalType(rhsType).getUnqualifiedType();
+
+  if (lhsType == rhsType)
+    return Compatible; // Common case: fast path an exact match.
+
+  if ((lhsType->isObjCClassType() &&
+       (rhsType.getDesugaredType() == Context.ObjCClassRedefinitionType)) ||
+     (rhsType->isObjCClassType() &&
+       (lhsType.getDesugaredType() == Context.ObjCClassRedefinitionType))) {
+      return Compatible;
+  }
+
+  // If the left-hand side is a reference type, then we are in a
+  // (rare!) case where we've allowed the use of references in C,
+  // e.g., as a parameter type in a built-in function. In this case,
+  // just make sure that the type referenced is compatible with the
+  // right-hand side type. The caller is responsible for adjusting
+  // lhsType so that the resulting expression does not have reference
+  // type.
+  if (const ReferenceType *lhsTypeRef = lhsType->getAs<ReferenceType>()) {
+    if (Context.typesAreCompatible(lhsTypeRef->getPointeeType(), rhsType))
+      return Compatible;
+    return Incompatible;
+  }
+  // Allow scalar to ExtVector assignments, and assignments of an ExtVector type
+  // to the same ExtVector type.
+  if (lhsType->isExtVectorType()) {
+    if (rhsType->isExtVectorType())
+      return lhsType == rhsType ? Compatible : Incompatible;
+    if (!rhsType->isVectorType() && rhsType->isArithmeticType())
+      return Compatible;
+  }
+
+  if (lhsType->isVectorType() || rhsType->isVectorType()) {
+    // If we are allowing lax vector conversions, and LHS and RHS are both
+    // vectors, the total size only needs to be the same. This is a bitcast;
+    // no bits are changed but the result type is different.
+    if (getLangOptions().LaxVectorConversions &&
+        lhsType->isVectorType() && rhsType->isVectorType()) {
+      if (Context.getTypeSize(lhsType) == Context.getTypeSize(rhsType))
+        return IncompatibleVectors;
+    }
+    return Incompatible;
+  }
+
+  if (lhsType->isArithmeticType() && rhsType->isArithmeticType())
+    return Compatible;
+
+  if (isa<PointerType>(lhsType)) {
+    if (rhsType->isIntegerType())
+      return IntToPointer;
+
+    if (isa<PointerType>(rhsType))
+      return CheckPointerTypesForAssignment(lhsType, rhsType);
+
+    // In general, C pointers are not compatible with ObjC object pointers.
+    if (isa<ObjCObjectPointerType>(rhsType)) {
+      if (lhsType->isVoidPointerType()) // an exception to the rule.
+        return Compatible;
+      return IncompatiblePointer;
+    }
+    if (rhsType->getAs<BlockPointerType>()) {
+      if (lhsType->getAs<PointerType>()->getPointeeType()->isVoidType())
+        return Compatible;
+
+      // Treat block pointers as objects.
+      if (getLangOptions().ObjC1 && lhsType->isObjCIdType())
+        return Compatible;
+    }
+    return Incompatible;
+  }
+
+  if (isa<BlockPointerType>(lhsType)) {
+    if (rhsType->isIntegerType())
+      return IntToBlockPointer;
+
+    // Treat block pointers as objects.
+    if (getLangOptions().ObjC1 && rhsType->isObjCIdType())
+      return Compatible;
+
+    if (rhsType->isBlockPointerType())
+      return CheckBlockPointerTypesForAssignment(lhsType, rhsType);
+
+    if (const PointerType *RHSPT = rhsType->getAs<PointerType>()) {
+      if (RHSPT->getPointeeType()->isVoidType())
+        return Compatible;
+    }
+    return Incompatible;
+  }
+
+  if (isa<ObjCObjectPointerType>(lhsType)) {
+    if (rhsType->isIntegerType())
+      return IntToPointer;
+
+    // In general, C pointers are not compatible with ObjC object pointers.
+    if (isa<PointerType>(rhsType)) {
+      if (rhsType->isVoidPointerType()) // an exception to the rule.
+        return Compatible;
+      return IncompatiblePointer;
+    }
+    if (rhsType->isObjCObjectPointerType()) {
+      return CheckObjCPointerTypesForAssignment(lhsType, rhsType);
+    }
+    if (const PointerType *RHSPT = rhsType->getAs<PointerType>()) {
+      if (RHSPT->getPointeeType()->isVoidType())
+        return Compatible;
+    }
+    // Treat block pointers as objects.
+    if (rhsType->isBlockPointerType())
+      return Compatible;
+    return Incompatible;
+  }
+  if (isa<PointerType>(rhsType)) {
+    // C99 6.5.16.1p1: the left operand is _Bool and the right is a pointer.
+    if (lhsType == Context.BoolTy)
+      return Compatible;
+
+    if (lhsType->isIntegerType())
+      return PointerToInt;
+
+    if (isa<PointerType>(lhsType))
+      return CheckPointerTypesForAssignment(lhsType, rhsType);
+
+    if (isa<BlockPointerType>(lhsType) &&
+        rhsType->getAs<PointerType>()->getPointeeType()->isVoidType())
+      return Compatible;
+    return Incompatible;
+  }
+  if (isa<ObjCObjectPointerType>(rhsType)) {
+    // C99 6.5.16.1p1: the left operand is _Bool and the right is a pointer.
+    if (lhsType == Context.BoolTy)
+      return Compatible;
+
+    if (lhsType->isIntegerType())
+      return PointerToInt;
+
+    // In general, C pointers are not compatible with ObjC object pointers.
+    if (isa<PointerType>(lhsType)) {
+      if (lhsType->isVoidPointerType()) // an exception to the rule.
+        return Compatible;
+      return IncompatiblePointer;
+    }
+    if (isa<BlockPointerType>(lhsType) &&
+        rhsType->getAs<PointerType>()->getPointeeType()->isVoidType())
+      return Compatible;
+    return Incompatible;
+  }
+
+  if (isa<TagType>(lhsType) && isa<TagType>(rhsType)) {
+    if (Context.typesAreCompatible(lhsType, rhsType))
+      return Compatible;
+  }
+  return Incompatible;
+}
+
+/// \brief Constructs a transparent union from an expression that is
+/// used to initialize the transparent union.
+static void ConstructTransparentUnion(ASTContext &C, Expr *&E,
+                                      QualType UnionType, FieldDecl *Field) {
+  // Build an initializer list that designates the appropriate member
+  // of the transparent union.
+  InitListExpr *Initializer = new (C) InitListExpr(C, SourceLocation(),
+                                                   &E, 1,
+                                                   SourceLocation());
+  Initializer->setType(UnionType);
+  Initializer->setInitializedFieldInUnion(Field);
+
+  // Build a compound literal constructing a value of the transparent
+  // union type from this initializer list.
+  TypeSourceInfo *unionTInfo = C.getTrivialTypeSourceInfo(UnionType);
+  E = new (C) CompoundLiteralExpr(SourceLocation(), unionTInfo, UnionType,
+                                  Initializer, false);
+}
+
+Sema::AssignConvertType
+Sema::CheckTransparentUnionArgumentConstraints(QualType ArgType, Expr *&rExpr) {
+  QualType FromType = rExpr->getType();
+
+  // If the ArgType is a Union type, we want to handle a potential
+  // transparent_union GCC extension.
+  const RecordType *UT = ArgType->getAsUnionType();
+  if (!UT || !UT->getDecl()->hasAttr<TransparentUnionAttr>())
+    return Incompatible;
+
+  // The field to initialize within the transparent union.
+  RecordDecl *UD = UT->getDecl();
+  FieldDecl *InitField = 0;
+  // It's compatible if the expression matches any of the fields.
+  for (RecordDecl::field_iterator it = UD->field_begin(),
+         itend = UD->field_end();
+       it != itend; ++it) {
+    if (it->getType()->isPointerType()) {
+      // If the transparent union contains a pointer type, we allow:
+      // 1) void pointer
+      // 2) null pointer constant
+      if (FromType->isPointerType())
+        if (FromType->getAs<PointerType>()->getPointeeType()->isVoidType()) {
+          ImpCastExprToType(rExpr, it->getType(), CastExpr::CK_BitCast);
+          InitField = *it;
+          break;
+        }
+
+      if (rExpr->isNullPointerConstant(Context,
+                                       Expr::NPC_ValueDependentIsNull)) {
+        ImpCastExprToType(rExpr, it->getType(), CastExpr::CK_IntegralToPointer);
+        InitField = *it;
+        break;
+      }
+    }
+
+    if (CheckAssignmentConstraints(it->getType(), rExpr->getType())
+          == Compatible) {
+      InitField = *it;
+      break;
+    }
+  }
+
+  if (!InitField)
+    return Incompatible;
+
+  ConstructTransparentUnion(Context, rExpr, ArgType, InitField);
+  return Compatible;
+}
+
+Sema::AssignConvertType
+Sema::CheckSingleAssignmentConstraints(QualType lhsType, Expr *&rExpr) {
+  if (getLangOptions().CPlusPlus) {
+    if (!lhsType->isRecordType()) {
+      // C++ 5.17p3: If the left operand is not of class type, the
+      // expression is implicitly converted (C++ 4) to the
+      // cv-unqualified type of the left operand.
+      if (PerformImplicitConversion(rExpr, lhsType.getUnqualifiedType(),
+                                    AA_Assigning))
+        return Incompatible;
+      return Compatible;
+    }
+
+    // FIXME: Currently, we fall through and treat C++ classes like C
+    // structures.
+  }
+
+  // C99 6.5.16.1p1: the left operand is a pointer and the right is
+  // a null pointer constant.
+  if ((lhsType->isPointerType() ||
+       lhsType->isObjCObjectPointerType() ||
+       lhsType->isBlockPointerType())
+      && rExpr->isNullPointerConstant(Context,
+                                      Expr::NPC_ValueDependentIsNull)) {
+    ImpCastExprToType(rExpr, lhsType, CastExpr::CK_Unknown);
+    return Compatible;
+  }
+
+  // This check seems unnatural, however it is necessary to ensure the proper
+  // conversion of functions/arrays. If the conversion were done for all
+  // DeclExpr's (created by ActOnIdExpression), it would mess up the unary
+  // expressions that surpress this implicit conversion (&, sizeof).
+  //
+  // Suppress this for references: C++ 8.5.3p5.
+  if (!lhsType->isReferenceType())
+    DefaultFunctionArrayLvalueConversion(rExpr);
+
+  Sema::AssignConvertType result =
+    CheckAssignmentConstraints(lhsType, rExpr->getType());
+
+  // C99 6.5.16.1p2: The value of the right operand is converted to the
+  // type of the assignment expression.
+  // CheckAssignmentConstraints allows the left-hand side to be a reference,
+  // so that we can use references in built-in functions even in C.
+  // The getNonReferenceType() call makes sure that the resulting expression
+  // does not have reference type.
+  if (result != Incompatible && rExpr->getType() != lhsType)
+    ImpCastExprToType(rExpr, lhsType.getNonReferenceType(),
+                      CastExpr::CK_Unknown);
+  return result;
+}
+
+QualType Sema::InvalidOperands(SourceLocation Loc, Expr *&lex, Expr *&rex) {
+  Diag(Loc, diag::err_typecheck_invalid_operands)
+    << lex->getType() << rex->getType()
+    << lex->getSourceRange() << rex->getSourceRange();
+  return QualType();
+}
+
+QualType Sema::CheckVectorOperands(SourceLocation Loc, Expr *&lex, Expr *&rex) {
+  // For conversion purposes, we ignore any qualifiers.
+  // For example, "const float" and "float" are equivalent.
+  QualType lhsType =
+    Context.getCanonicalType(lex->getType()).getUnqualifiedType();
+  QualType rhsType =
+    Context.getCanonicalType(rex->getType()).getUnqualifiedType();
+
+  // If the vector types are identical, return.
+  if (lhsType == rhsType)
+    return lhsType;
+
+  // Handle the case of a vector & extvector type of the same size and element
+  // type.  It would be nice if we only had one vector type someday.
+  if (getLangOptions().LaxVectorConversions) {
+    // FIXME: Should we warn here?
+    if (const VectorType *LV = lhsType->getAs<VectorType>()) {
+      if (const VectorType *RV = rhsType->getAs<VectorType>())
+        if (LV->getElementType() == RV->getElementType() &&
+            LV->getNumElements() == RV->getNumElements()) {
+          return lhsType->isExtVectorType() ? lhsType : rhsType;
+        }
+    }
+  }
+
+  // Canonicalize the ExtVector to the LHS, remember if we swapped so we can
+  // swap back (so that we don't reverse the inputs to a subtract, for instance.
+  bool swapped = false;
+  if (rhsType->isExtVectorType()) {
+    swapped = true;
+    std::swap(rex, lex);
+    std::swap(rhsType, lhsType);
+  }
+
+  // Handle the case of an ext vector and scalar.
+  if (const ExtVectorType *LV = lhsType->getAs<ExtVectorType>()) {
+    QualType EltTy = LV->getElementType();
+    if (EltTy->isIntegralType() && rhsType->isIntegralType()) {
+      if (Context.getIntegerTypeOrder(EltTy, rhsType) >= 0) {
+        ImpCastExprToType(rex, lhsType, CastExpr::CK_IntegralCast);
+        if (swapped) std::swap(rex, lex);
+        return lhsType;
+      }
+    }
+    if (EltTy->isRealFloatingType() && rhsType->isScalarType() &&
+        rhsType->isRealFloatingType()) {
+      if (Context.getFloatingTypeOrder(EltTy, rhsType) >= 0) {
+        ImpCastExprToType(rex, lhsType, CastExpr::CK_FloatingCast);
+        if (swapped) std::swap(rex, lex);
+        return lhsType;
+      }
+    }
+  }
+
+  // Vectors of different size or scalar and non-ext-vector are errors.
+  Diag(Loc, diag::err_typecheck_vector_not_convertable)
+    << lex->getType() << rex->getType()
+    << lex->getSourceRange() << rex->getSourceRange();
+  return QualType();
+}
+
+QualType Sema::CheckMultiplyDivideOperands(
+  Expr *&lex, Expr *&rex, SourceLocation Loc, bool isCompAssign, bool isDiv) {
+  if (lex->getType()->isVectorType() || rex->getType()->isVectorType())
+    return CheckVectorOperands(Loc, lex, rex);
+
+  QualType compType = UsualArithmeticConversions(lex, rex, isCompAssign);
+
+  if (!lex->getType()->isArithmeticType() ||
+      !rex->getType()->isArithmeticType())
+    return InvalidOperands(Loc, lex, rex);
+
+  // Check for division by zero.
+  if (isDiv &&
+      rex->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNotNull))
+    DiagRuntimeBehavior(Loc, PDiag(diag::warn_division_by_zero)
+                                     << rex->getSourceRange());
+
+  return compType;
+}
+
+QualType Sema::CheckRemainderOperands(
+  Expr *&lex, Expr *&rex, SourceLocation Loc, bool isCompAssign) {
+  if (lex->getType()->isVectorType() || rex->getType()->isVectorType()) {
+    if (lex->getType()->isIntegerType() && rex->getType()->isIntegerType())
+      return CheckVectorOperands(Loc, lex, rex);
+    return InvalidOperands(Loc, lex, rex);
+  }
+
+  QualType compType = UsualArithmeticConversions(lex, rex, isCompAssign);
+
+  if (!lex->getType()->isIntegerType() || !rex->getType()->isIntegerType())
+    return InvalidOperands(Loc, lex, rex);
+
+  // Check for remainder by zero.
+  if (rex->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNotNull))
+    DiagRuntimeBehavior(Loc, PDiag(diag::warn_remainder_by_zero)
+                                 << rex->getSourceRange());
+
+  return compType;
+}
+
+QualType Sema::CheckAdditionOperands( // C99 6.5.6
+  Expr *&lex, Expr *&rex, SourceLocation Loc, QualType* CompLHSTy) {
+  if (lex->getType()->isVectorType() || rex->getType()->isVectorType()) {
+    QualType compType = CheckVectorOperands(Loc, lex, rex);
+    if (CompLHSTy) *CompLHSTy = compType;
+    return compType;
+  }
+
+  QualType compType = UsualArithmeticConversions(lex, rex, CompLHSTy);
+
+  // handle the common case first (both operands are arithmetic).
+  if (lex->getType()->isArithmeticType() &&
+      rex->getType()->isArithmeticType()) {
+    if (CompLHSTy) *CompLHSTy = compType;
+    return compType;
+  }
+
+  // Put any potential pointer into PExp
+  Expr* PExp = lex, *IExp = rex;
+  if (IExp->getType()->isAnyPointerType())
+    std::swap(PExp, IExp);
+
+  if (PExp->getType()->isAnyPointerType()) {
+
+    if (IExp->getType()->isIntegerType()) {
+      QualType PointeeTy = PExp->getType()->getPointeeType();
+
+      // Check for arithmetic on pointers to incomplete types.
+      if (PointeeTy->isVoidType()) {
+        if (getLangOptions().CPlusPlus) {
+          Diag(Loc, diag::err_typecheck_pointer_arith_void_type)
+            << lex->getSourceRange() << rex->getSourceRange();
+          return QualType();
+        }
+
+        // GNU extension: arithmetic on pointer to void
+        Diag(Loc, diag::ext_gnu_void_ptr)
+          << lex->getSourceRange() << rex->getSourceRange();
+      } else if (PointeeTy->isFunctionType()) {
+        if (getLangOptions().CPlusPlus) {
+          Diag(Loc, diag::err_typecheck_pointer_arith_function_type)
+            << lex->getType() << lex->getSourceRange();
+          return QualType();
+        }
+
+        // GNU extension: arithmetic on pointer to function
+        Diag(Loc, diag::ext_gnu_ptr_func_arith)
+          << lex->getType() << lex->getSourceRange();
+      } else {
+        // Check if we require a complete type.
+        if (((PExp->getType()->isPointerType() &&
+              !PExp->getType()->isDependentType()) ||
+              PExp->getType()->isObjCObjectPointerType()) &&
+             RequireCompleteType(Loc, PointeeTy,
+                           PDiag(diag::err_typecheck_arithmetic_incomplete_type)
+                             << PExp->getSourceRange()
+                             << PExp->getType()))
+          return QualType();
+      }
+      // Diagnose bad cases where we step over interface counts.
+      if (PointeeTy->isObjCInterfaceType() && LangOpts.ObjCNonFragileABI) {
+        Diag(Loc, diag::err_arithmetic_nonfragile_interface)
+          << PointeeTy << PExp->getSourceRange();
+        return QualType();
+      }
+
+      if (CompLHSTy) {
+        QualType LHSTy = Context.isPromotableBitField(lex);
+        if (LHSTy.isNull()) {
+          LHSTy = lex->getType();
+          if (LHSTy->isPromotableIntegerType())
+            LHSTy = Context.getPromotedIntegerType(LHSTy);
+        }
+        *CompLHSTy = LHSTy;
+      }
+      return PExp->getType();
+    }
+  }
+
+  return InvalidOperands(Loc, lex, rex);
+}
+
+// C99 6.5.6
+QualType Sema::CheckSubtractionOperands(Expr *&lex, Expr *&rex,
+                                        SourceLocation Loc, QualType* CompLHSTy) {
+  if (lex->getType()->isVectorType() || rex->getType()->isVectorType()) {
+    QualType compType = CheckVectorOperands(Loc, lex, rex);
+    if (CompLHSTy) *CompLHSTy = compType;
+    return compType;
+  }
+
+  QualType compType = UsualArithmeticConversions(lex, rex, CompLHSTy);
+
+  // Enforce type constraints: C99 6.5.6p3.
+
+  // Handle the common case first (both operands are arithmetic).
+  if (lex->getType()->isArithmeticType()
+      && rex->getType()->isArithmeticType()) {
+    if (CompLHSTy) *CompLHSTy = compType;
+    return compType;
+  }
+
+  // Either ptr - int   or   ptr - ptr.
+  if (lex->getType()->isAnyPointerType()) {
+    QualType lpointee = lex->getType()->getPointeeType();
+
+    // The LHS must be an completely-defined object type.
+
+    bool ComplainAboutVoid = false;
+    Expr *ComplainAboutFunc = 0;
+    if (lpointee->isVoidType()) {
+      if (getLangOptions().CPlusPlus) {
+        Diag(Loc, diag::err_typecheck_pointer_arith_void_type)
+          << lex->getSourceRange() << rex->getSourceRange();
+        return QualType();
+      }
+
+      // GNU C extension: arithmetic on pointer to void
+      ComplainAboutVoid = true;
+    } else if (lpointee->isFunctionType()) {
+      if (getLangOptions().CPlusPlus) {
+        Diag(Loc, diag::err_typecheck_pointer_arith_function_type)
+          << lex->getType() << lex->getSourceRange();
+        return QualType();
+      }
+
+      // GNU C extension: arithmetic on pointer to function
+      ComplainAboutFunc = lex;
+    } else if (!lpointee->isDependentType() &&
+               RequireCompleteType(Loc, lpointee,
+                                   PDiag(diag::err_typecheck_sub_ptr_object)
+                                     << lex->getSourceRange()
+                                     << lex->getType()))
+      return QualType();
+
+    // Diagnose bad cases where we step over interface counts.
+    if (lpointee->isObjCInterfaceType() && LangOpts.ObjCNonFragileABI) {
+      Diag(Loc, diag::err_arithmetic_nonfragile_interface)
+        << lpointee << lex->getSourceRange();
+      return QualType();
+    }
+
+    // The result type of a pointer-int computation is the pointer type.
+    if (rex->getType()->isIntegerType()) {
+      if (ComplainAboutVoid)
+        Diag(Loc, diag::ext_gnu_void_ptr)
+          << lex->getSourceRange() << rex->getSourceRange();
+      if (ComplainAboutFunc)
+        Diag(Loc, diag::ext_gnu_ptr_func_arith)
+          << ComplainAboutFunc->getType()
+          << ComplainAboutFunc->getSourceRange();
+
+      if (CompLHSTy) *CompLHSTy = lex->getType();
+      return lex->getType();
+    }
+
+    // Handle pointer-pointer subtractions.
+    if (const PointerType *RHSPTy = rex->getType()->getAs<PointerType>()) {
+      QualType rpointee = RHSPTy->getPointeeType();
+
+      // RHS must be a completely-type object type.
+      // Handle the GNU void* extension.
+      if (rpointee->isVoidType()) {
+        if (getLangOptions().CPlusPlus) {
+          Diag(Loc, diag::err_typecheck_pointer_arith_void_type)
+            << lex->getSourceRange() << rex->getSourceRange();
+          return QualType();
+        }
+
+        ComplainAboutVoid = true;
+      } else if (rpointee->isFunctionType()) {
+        if (getLangOptions().CPlusPlus) {
+          Diag(Loc, diag::err_typecheck_pointer_arith_function_type)
+            << rex->getType() << rex->getSourceRange();
+          return QualType();
+        }
+
+        // GNU extension: arithmetic on pointer to function
+        if (!ComplainAboutFunc)
+          ComplainAboutFunc = rex;
+      } else if (!rpointee->isDependentType() &&
+                 RequireCompleteType(Loc, rpointee,
+                                     PDiag(diag::err_typecheck_sub_ptr_object)
+                                       << rex->getSourceRange()
+                                       << rex->getType()))
+        return QualType();
+
+      if (getLangOptions().CPlusPlus) {
+        // Pointee types must be the same: C++ [expr.add]
+        if (!Context.hasSameUnqualifiedType(lpointee, rpointee)) {
+          Diag(Loc, diag::err_typecheck_sub_ptr_compatible)
+            << lex->getType() << rex->getType()
+            << lex->getSourceRange() << rex->getSourceRange();
+          return QualType();
+        }
+      } else {
+        // Pointee types must be compatible C99 6.5.6p3
+        if (!Context.typesAreCompatible(
+                Context.getCanonicalType(lpointee).getUnqualifiedType(),
+                Context.getCanonicalType(rpointee).getUnqualifiedType())) {
+          Diag(Loc, diag::err_typecheck_sub_ptr_compatible)
+            << lex->getType() << rex->getType()
+            << lex->getSourceRange() << rex->getSourceRange();
+          return QualType();
+        }
+      }
+
+      if (ComplainAboutVoid)
+        Diag(Loc, diag::ext_gnu_void_ptr)
+          << lex->getSourceRange() << rex->getSourceRange();
+      if (ComplainAboutFunc)
+        Diag(Loc, diag::ext_gnu_ptr_func_arith)
+          << ComplainAboutFunc->getType()
+          << ComplainAboutFunc->getSourceRange();
+
+      if (CompLHSTy) *CompLHSTy = lex->getType();
+      return Context.getPointerDiffType();
+    }
+  }
+
+  return InvalidOperands(Loc, lex, rex);
+}
+
+// C99 6.5.7
+QualType Sema::CheckShiftOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
+                                  bool isCompAssign) {
+  // C99 6.5.7p2: Each of the operands shall have integer type.
+  if (!lex->getType()->isIntegerType() || !rex->getType()->isIntegerType())
+    return InvalidOperands(Loc, lex, rex);
+
+  // Vector shifts promote their scalar inputs to vector type.
+  if (lex->getType()->isVectorType() || rex->getType()->isVectorType())
+    return CheckVectorOperands(Loc, lex, rex);
+
+  // Shifts don't perform usual arithmetic conversions, they just do integer
+  // promotions on each operand. C99 6.5.7p3
+  QualType LHSTy = Context.isPromotableBitField(lex);
+  if (LHSTy.isNull()) {
+    LHSTy = lex->getType();
+    if (LHSTy->isPromotableIntegerType())
+      LHSTy = Context.getPromotedIntegerType(LHSTy);
+  }
+  if (!isCompAssign)
+    ImpCastExprToType(lex, LHSTy, CastExpr::CK_IntegralCast);
+
+  UsualUnaryConversions(rex);
+
+  // Sanity-check shift operands
+  llvm::APSInt Right;
+  // Check right/shifter operand
+  if (!rex->isValueDependent() &&
+      rex->isIntegerConstantExpr(Right, Context)) {
+    if (Right.isNegative())
+      Diag(Loc, diag::warn_shift_negative) << rex->getSourceRange();
+    else {
+      llvm::APInt LeftBits(Right.getBitWidth(),
+                          Context.getTypeSize(lex->getType()));
+      if (Right.uge(LeftBits))
+        Diag(Loc, diag::warn_shift_gt_typewidth) << rex->getSourceRange();
+    }
+  }
+
+  // "The type of the result is that of the promoted left operand."
+  return LHSTy;
+}
+
+// C99 6.5.8, C++ [expr.rel]
+QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
+                                    unsigned OpaqueOpc, bool isRelational) {
+  BinaryOperator::Opcode Opc = (BinaryOperator::Opcode)OpaqueOpc;
+
+  // Handle vector comparisons separately.
+  if (lex->getType()->isVectorType() || rex->getType()->isVectorType())
+    return CheckVectorCompareOperands(lex, rex, Loc, isRelational);
+
+  CheckSignCompare(lex, rex, Loc, &Opc);
+
+  // C99 6.5.8p3 / C99 6.5.9p4
+  if (lex->getType()->isArithmeticType() && rex->getType()->isArithmeticType())
+    UsualArithmeticConversions(lex, rex);
+  else {
+    UsualUnaryConversions(lex);
+    UsualUnaryConversions(rex);
+  }
+  QualType lType = lex->getType();
+  QualType rType = rex->getType();
+
+  if (!lType->isFloatingType()
+      && !(lType->isBlockPointerType() && isRelational)) {
+    // For non-floating point types, check for self-comparisons of the form
+    // x == x, x != x, x < x, etc.  These always evaluate to a constant, and
+    // often indicate logic errors in the program.
+    // NOTE: Don't warn about comparisons of enum constants. These can arise
+    //  from macro expansions, and are usually quite deliberate.
+    Expr *LHSStripped = lex->IgnoreParens();
+    Expr *RHSStripped = rex->IgnoreParens();
+    if (DeclRefExpr* DRL = dyn_cast<DeclRefExpr>(LHSStripped))
+      if (DeclRefExpr* DRR = dyn_cast<DeclRefExpr>(RHSStripped))
+        if (DRL->getDecl() == DRR->getDecl() &&
+            !isa<EnumConstantDecl>(DRL->getDecl()))
+          DiagRuntimeBehavior(Loc, PDiag(diag::warn_selfcomparison));
+
+    if (isa<CastExpr>(LHSStripped))
+      LHSStripped = LHSStripped->IgnoreParenCasts();
+    if (isa<CastExpr>(RHSStripped))
+      RHSStripped = RHSStripped->IgnoreParenCasts();
+
+    // Warn about comparisons against a string constant (unless the other
+    // operand is null), the user probably wants strcmp.
+    Expr *literalString = 0;
+    Expr *literalStringStripped = 0;
+    if ((isa<StringLiteral>(LHSStripped) || isa<ObjCEncodeExpr>(LHSStripped)) &&
+        !RHSStripped->isNullPointerConstant(Context,
+                                            Expr::NPC_ValueDependentIsNull)) {
+      literalString = lex;
+      literalStringStripped = LHSStripped;
+    } else if ((isa<StringLiteral>(RHSStripped) ||
+                isa<ObjCEncodeExpr>(RHSStripped)) &&
+               !LHSStripped->isNullPointerConstant(Context,
+                                            Expr::NPC_ValueDependentIsNull)) {
+      literalString = rex;
+      literalStringStripped = RHSStripped;
+    }
+
+    if (literalString) {
+      std::string resultComparison;
+      switch (Opc) {
+      case BinaryOperator::LT: resultComparison = ") < 0"; break;
+      case BinaryOperator::GT: resultComparison = ") > 0"; break;
+      case BinaryOperator::LE: resultComparison = ") <= 0"; break;
+      case BinaryOperator::GE: resultComparison = ") >= 0"; break;
+      case BinaryOperator::EQ: resultComparison = ") == 0"; break;
+      case BinaryOperator::NE: resultComparison = ") != 0"; break;
+      default: assert(false && "Invalid comparison operator");
+      }
+
+      DiagRuntimeBehavior(Loc,
+        PDiag(diag::warn_stringcompare)
+          << isa<ObjCEncodeExpr>(literalStringStripped)
+          << literalString->getSourceRange());
+    }
+  }
+
+  // The result of comparisons is 'bool' in C++, 'int' in C.
+  QualType ResultTy = getLangOptions().CPlusPlus ? Context.BoolTy:Context.IntTy;
+
+  if (isRelational) {
+    if (lType->isRealType() && rType->isRealType())
+      return ResultTy;
+  } else {
+    // Check for comparisons of floating point operands using != and ==.
+    if (lType->isFloatingType() && rType->isFloatingType())
+      CheckFloatComparison(Loc,lex,rex);
+
+    if (lType->isArithmeticType() && rType->isArithmeticType())
+      return ResultTy;
+  }
+
+  bool LHSIsNull = lex->isNullPointerConstant(Context,
+                                              Expr::NPC_ValueDependentIsNull);
+  bool RHSIsNull = rex->isNullPointerConstant(Context,
+                                              Expr::NPC_ValueDependentIsNull);
+
+  // All of the following pointer related warnings are GCC extensions, except
+  // when handling null pointer constants. One day, we can consider making them
+  // errors (when -pedantic-errors is enabled).
+  if (lType->isPointerType() && rType->isPointerType()) { // C99 6.5.8p2
+    QualType LCanPointeeTy =
+      Context.getCanonicalType(lType->getAs<PointerType>()->getPointeeType());
+    QualType RCanPointeeTy =
+      Context.getCanonicalType(rType->getAs<PointerType>()->getPointeeType());
+
+    if (getLangOptions().CPlusPlus) {
+      if (LCanPointeeTy == RCanPointeeTy)
+        return ResultTy;
+      if (!isRelational &&
+          (LCanPointeeTy->isVoidType() || RCanPointeeTy->isVoidType())) {
+        // Valid unless comparison between non-null pointer and function pointer
+        // This is a gcc extension compatibility comparison.
+        if ((LCanPointeeTy->isFunctionType() || RCanPointeeTy->isFunctionType())
+            && !LHSIsNull && !RHSIsNull) {
+          Diag(Loc, diag::ext_typecheck_comparison_of_fptr_to_void)
+            << lType << rType << lex->getSourceRange() << rex->getSourceRange();
+          ImpCastExprToType(rex, lType, CastExpr::CK_BitCast);
+          return ResultTy;
+        }
+      }
+      // C++ [expr.rel]p2:
+      //   [...] Pointer conversions (4.10) and qualification
+      //   conversions (4.4) are performed on pointer operands (or on
+      //   a pointer operand and a null pointer constant) to bring
+      //   them to their composite pointer type. [...]
+      //
+      // C++ [expr.eq]p1 uses the same notion for (in)equality
+      // comparisons of pointers.
+      bool NonStandardCompositeType = false;
+      QualType T = FindCompositePointerType(Loc, lex, rex,
+                              isSFINAEContext()? 0 : &NonStandardCompositeType);
+      if (T.isNull()) {
+        Diag(Loc, diag::err_typecheck_comparison_of_distinct_pointers)
+          << lType << rType << lex->getSourceRange() << rex->getSourceRange();
+        return QualType();
+      } else if (NonStandardCompositeType) {
+        Diag(Loc,
+             diag::ext_typecheck_comparison_of_distinct_pointers_nonstandard)
+          << lType << rType << T
+          << lex->getSourceRange() << rex->getSourceRange();
+      }
+
+      ImpCastExprToType(lex, T, CastExpr::CK_BitCast);
+      ImpCastExprToType(rex, T, CastExpr::CK_BitCast);
+      return ResultTy;
+    }
+    // C99 6.5.9p2 and C99 6.5.8p2
+    if (Context.typesAreCompatible(LCanPointeeTy.getUnqualifiedType(),
+                                   RCanPointeeTy.getUnqualifiedType())) {
+      // Valid unless a relational comparison of function pointers
+      if (isRelational && LCanPointeeTy->isFunctionType()) {
+        Diag(Loc, diag::ext_typecheck_ordered_comparison_of_function_pointers)
+          << lType << rType << lex->getSourceRange() << rex->getSourceRange();
+      }
+    } else if (!isRelational &&
+               (LCanPointeeTy->isVoidType() || RCanPointeeTy->isVoidType())) {
+      // Valid unless comparison between non-null pointer and function pointer
+      if ((LCanPointeeTy->isFunctionType() || RCanPointeeTy->isFunctionType())
+          && !LHSIsNull && !RHSIsNull) {
+        Diag(Loc, diag::ext_typecheck_comparison_of_fptr_to_void)
+          << lType << rType << lex->getSourceRange() << rex->getSourceRange();
+      }
+    } else {
+      // Invalid
+      Diag(Loc, diag::ext_typecheck_comparison_of_distinct_pointers)
+        << lType << rType << lex->getSourceRange() << rex->getSourceRange();
+    }
+    if (LCanPointeeTy != RCanPointeeTy)
+      ImpCastExprToType(rex, lType, CastExpr::CK_BitCast);
+    return ResultTy;
+  }
+
+  if (getLangOptions().CPlusPlus) {
+    // Comparison of pointers with null pointer constants and equality
+    // comparisons of member pointers to null pointer constants.
+    if (RHSIsNull &&
+        (lType->isPointerType() ||
+         (!isRelational && lType->isMemberPointerType()))) {
+      ImpCastExprToType(rex, lType, CastExpr::CK_NullToMemberPointer);
+      return ResultTy;
+    }
+    if (LHSIsNull &&
+        (rType->isPointerType() ||
+         (!isRelational && rType->isMemberPointerType()))) {
+      ImpCastExprToType(lex, rType, CastExpr::CK_NullToMemberPointer);
+      return ResultTy;
+    }
+
+    // Comparison of member pointers.
+    if (!isRelational &&
+        lType->isMemberPointerType() && rType->isMemberPointerType()) {
+      // C++ [expr.eq]p2:
+      //   In addition, pointers to members can be compared, or a pointer to
+      //   member and a null pointer constant. Pointer to member conversions
+      //   (4.11) and qualification conversions (4.4) are performed to bring
+      //   them to a common type. If one operand is a null pointer constant,
+      //   the common type is the type of the other operand. Otherwise, the
+      //   common type is a pointer to member type similar (4.4) to the type
+      //   of one of the operands, with a cv-qualification signature (4.4)
+      //   that is the union of the cv-qualification signatures of the operand
+      //   types.
+      bool NonStandardCompositeType = false;
+      QualType T = FindCompositePointerType(Loc, lex, rex,
+                              isSFINAEContext()? 0 : &NonStandardCompositeType);
+      if (T.isNull()) {
+        Diag(Loc, diag::err_typecheck_comparison_of_distinct_pointers)
+          << lType << rType << lex->getSourceRange() << rex->getSourceRange();
+        return QualType();
+      } else if (NonStandardCompositeType) {
+        Diag(Loc,
+             diag::ext_typecheck_comparison_of_distinct_pointers_nonstandard)
+          << lType << rType << T
+          << lex->getSourceRange() << rex->getSourceRange();
+      }
+
+      ImpCastExprToType(lex, T, CastExpr::CK_BitCast);
+      ImpCastExprToType(rex, T, CastExpr::CK_BitCast);
+      return ResultTy;
+    }
+
+    // Comparison of nullptr_t with itself.
+    if (lType->isNullPtrType() && rType->isNullPtrType())
+      return ResultTy;
+  }
+
+  // Handle block pointer types.
+  if (!isRelational && lType->isBlockPointerType() && rType->isBlockPointerType()) {
+    QualType lpointee = lType->getAs<BlockPointerType>()->getPointeeType();
+    QualType rpointee = rType->getAs<BlockPointerType>()->getPointeeType();
+
+    if (!LHSIsNull && !RHSIsNull &&
+        !Context.typesAreCompatible(lpointee, rpointee)) {
+      Diag(Loc, diag::err_typecheck_comparison_of_distinct_blocks)
+        << lType << rType << lex->getSourceRange() << rex->getSourceRange();
+    }
+    ImpCastExprToType(rex, lType, CastExpr::CK_BitCast);
+    return ResultTy;
+  }
+  // Allow block pointers to be compared with null pointer constants.
+  if (!isRelational
+      && ((lType->isBlockPointerType() && rType->isPointerType())
+          || (lType->isPointerType() && rType->isBlockPointerType()))) {
+    if (!LHSIsNull && !RHSIsNull) {
+      if (!((rType->isPointerType() && rType->getAs<PointerType>()
+             ->getPointeeType()->isVoidType())
+            || (lType->isPointerType() && lType->getAs<PointerType>()
+                ->getPointeeType()->isVoidType())))
+        Diag(Loc, diag::err_typecheck_comparison_of_distinct_blocks)
+          << lType << rType << lex->getSourceRange() << rex->getSourceRange();
+    }
+    ImpCastExprToType(rex, lType, CastExpr::CK_BitCast);
+    return ResultTy;
+  }
+
+  if ((lType->isObjCObjectPointerType() || rType->isObjCObjectPointerType())) {
+    if (lType->isPointerType() || rType->isPointerType()) {
+      const PointerType *LPT = lType->getAs<PointerType>();
+      const PointerType *RPT = rType->getAs<PointerType>();
+      bool LPtrToVoid = LPT ?
+        Context.getCanonicalType(LPT->getPointeeType())->isVoidType() : false;
+      bool RPtrToVoid = RPT ?
+        Context.getCanonicalType(RPT->getPointeeType())->isVoidType() : false;
+
+      if (!LPtrToVoid && !RPtrToVoid &&
+          !Context.typesAreCompatible(lType, rType)) {
+        Diag(Loc, diag::ext_typecheck_comparison_of_distinct_pointers)
+          << lType << rType << lex->getSourceRange() << rex->getSourceRange();
+      }
+      ImpCastExprToType(rex, lType, CastExpr::CK_BitCast);
+      return ResultTy;
+    }
+    if (lType->isObjCObjectPointerType() && rType->isObjCObjectPointerType()) {
+      if (!Context.areComparableObjCPointerTypes(lType, rType))
+        Diag(Loc, diag::ext_typecheck_comparison_of_distinct_pointers)
+          << lType << rType << lex->getSourceRange() << rex->getSourceRange();
+      ImpCastExprToType(rex, lType, CastExpr::CK_BitCast);
+      return ResultTy;
+    }
+  }
+  if (lType->isAnyPointerType() && rType->isIntegerType()) {
+    unsigned DiagID = 0;
+    if (RHSIsNull) {
+      if (isRelational)
+        DiagID = diag::ext_typecheck_ordered_comparison_of_pointer_and_zero;
+    } else if (isRelational)
+      DiagID = diag::ext_typecheck_ordered_comparison_of_pointer_integer;
+    else
+      DiagID = diag::ext_typecheck_comparison_of_pointer_integer;
+
+    if (DiagID) {
+      Diag(Loc, DiagID)
+        << lType << rType << lex->getSourceRange() << rex->getSourceRange();
+    }
+    ImpCastExprToType(rex, lType, CastExpr::CK_IntegralToPointer);
+    return ResultTy;
+  }
+  if (lType->isIntegerType() && rType->isAnyPointerType()) {
+    unsigned DiagID = 0;
+    if (LHSIsNull) {
+      if (isRelational)
+        DiagID = diag::ext_typecheck_ordered_comparison_of_pointer_and_zero;
+    } else if (isRelational)
+      DiagID = diag::ext_typecheck_ordered_comparison_of_pointer_integer;
+    else
+      DiagID = diag::ext_typecheck_comparison_of_pointer_integer;
+
+    if (DiagID) {
+      Diag(Loc, DiagID)
+        << lType << rType << lex->getSourceRange() << rex->getSourceRange();
+    }
+    ImpCastExprToType(lex, rType, CastExpr::CK_IntegralToPointer);
+    return ResultTy;
+  }
+  // Handle block pointers.
+  if (!isRelational && RHSIsNull
+      && lType->isBlockPointerType() && rType->isIntegerType()) {
+    ImpCastExprToType(rex, lType, CastExpr::CK_IntegralToPointer);
+    return ResultTy;
+  }
+  if (!isRelational && LHSIsNull
+      && lType->isIntegerType() && rType->isBlockPointerType()) {
+    ImpCastExprToType(lex, rType, CastExpr::CK_IntegralToPointer);
+    return ResultTy;
+  }
+  return InvalidOperands(Loc, lex, rex);
+}
+
+/// CheckVectorCompareOperands - vector comparisons are a clang extension that
+/// operates on extended vector types.  Instead of producing an IntTy result,
+/// like a scalar comparison, a vector comparison produces a vector of integer
+/// types.
+QualType Sema::CheckVectorCompareOperands(Expr *&lex, Expr *&rex,
+                                          SourceLocation Loc,
+                                          bool isRelational) {
+  // Check to make sure we're operating on vectors of the same type and width,
+  // Allowing one side to be a scalar of element type.
+  QualType vType = CheckVectorOperands(Loc, lex, rex);
+  if (vType.isNull())
+    return vType;
+
+  QualType lType = lex->getType();
+  QualType rType = rex->getType();
+
+  // For non-floating point types, check for self-comparisons of the form
+  // x == x, x != x, x < x, etc.  These always evaluate to a constant, and
+  // often indicate logic errors in the program.
+  if (!lType->isFloatingType()) {
+    if (DeclRefExpr* DRL = dyn_cast<DeclRefExpr>(lex->IgnoreParens()))
+      if (DeclRefExpr* DRR = dyn_cast<DeclRefExpr>(rex->IgnoreParens()))
+        if (DRL->getDecl() == DRR->getDecl())
+          DiagRuntimeBehavior(Loc, PDiag(diag::warn_selfcomparison));
+  }
+
+  // Check for comparisons of floating point operands using != and ==.
+  if (!isRelational && lType->isFloatingType()) {
+    assert (rType->isFloatingType());
+    CheckFloatComparison(Loc,lex,rex);
+  }
+
+  // Return the type for the comparison, which is the same as vector type for
+  // integer vectors, or an integer type of identical size and number of
+  // elements for floating point vectors.
+  if (lType->isIntegerType())
+    return lType;
+
+  const VectorType *VTy = lType->getAs<VectorType>();
+  unsigned TypeSize = Context.getTypeSize(VTy->getElementType());
+  if (TypeSize == Context.getTypeSize(Context.IntTy))
+    return Context.getExtVectorType(Context.IntTy, VTy->getNumElements());
+  if (TypeSize == Context.getTypeSize(Context.LongTy))
+    return Context.getExtVectorType(Context.LongTy, VTy->getNumElements());
+
+  assert(TypeSize == Context.getTypeSize(Context.LongLongTy) &&
+         "Unhandled vector element size in vector compare");
+  return Context.getExtVectorType(Context.LongLongTy, VTy->getNumElements());
+}
+
+inline QualType Sema::CheckBitwiseOperands(
+  Expr *&lex, Expr *&rex, SourceLocation Loc, bool isCompAssign) {
+  if (lex->getType()->isVectorType() || rex->getType()->isVectorType())
+    return CheckVectorOperands(Loc, lex, rex);
+
+  QualType compType = UsualArithmeticConversions(lex, rex, isCompAssign);
+
+  if (lex->getType()->isIntegerType() && rex->getType()->isIntegerType())
+    return compType;
+  return InvalidOperands(Loc, lex, rex);
+}
+
+inline QualType Sema::CheckLogicalOperands( // C99 6.5.[13,14]
+  Expr *&lex, Expr *&rex, SourceLocation Loc) {
+  if (!Context.getLangOptions().CPlusPlus) {
+    UsualUnaryConversions(lex);
+    UsualUnaryConversions(rex);
+
+    if (!lex->getType()->isScalarType() || !rex->getType()->isScalarType())
+      return InvalidOperands(Loc, lex, rex);
+
+    return Context.IntTy;
+  }
+
+  // C++ [expr.log.and]p1
+  // C++ [expr.log.or]p1
+  // The operands are both implicitly converted to type bool (clause 4).
+  StandardConversionSequence LHS;
+  if (!IsStandardConversion(lex, Context.BoolTy,
+                            /*InOverloadResolution=*/false, LHS))
+    return InvalidOperands(Loc, lex, rex);
+
+  if (PerformImplicitConversion(lex, Context.BoolTy, LHS,
+                                AA_Passing, /*IgnoreBaseAccess=*/false))
+    return InvalidOperands(Loc, lex, rex);
+
+  StandardConversionSequence RHS;
+  if (!IsStandardConversion(rex, Context.BoolTy,
+                            /*InOverloadResolution=*/false, RHS))
+    return InvalidOperands(Loc, lex, rex);
+
+  if (PerformImplicitConversion(rex, Context.BoolTy, RHS,
+                                AA_Passing, /*IgnoreBaseAccess=*/false))
+    return InvalidOperands(Loc, lex, rex);
+
+  // C++ [expr.log.and]p2
+  // C++ [expr.log.or]p2
+  // The result is a bool.
+  return Context.BoolTy;
+}
+
+/// IsReadonlyProperty - Verify that otherwise a valid l-value expression
+/// is a read-only property; return true if so. A readonly property expression
+/// depends on various declarations and thus must be treated specially.
+///
+static bool IsReadonlyProperty(Expr *E, Sema &S) {
+  if (E->getStmtClass() == Expr::ObjCPropertyRefExprClass) {
+    const ObjCPropertyRefExpr* PropExpr = cast<ObjCPropertyRefExpr>(E);
+    if (ObjCPropertyDecl *PDecl = PropExpr->getProperty()) {
+      QualType BaseType = PropExpr->getBase()->getType();
+      if (const ObjCObjectPointerType *OPT =
+            BaseType->getAsObjCInterfacePointerType())
+        if (ObjCInterfaceDecl *IFace = OPT->getInterfaceDecl())
+          if (S.isPropertyReadonly(PDecl, IFace))
+            return true;
+    }
+  }
+  return false;
+}
+
+/// CheckForModifiableLvalue - Verify that E is a modifiable lvalue.  If not,
+/// emit an error and return true.  If so, return false.
+static bool CheckForModifiableLvalue(Expr *E, SourceLocation Loc, Sema &S) {
+  SourceLocation OrigLoc = Loc;
+  Expr::isModifiableLvalueResult IsLV = E->isModifiableLvalue(S.Context,
+                                                              &Loc);
+  if (IsLV == Expr::MLV_Valid && IsReadonlyProperty(E, S))
+    IsLV = Expr::MLV_ReadonlyProperty;
+  if (IsLV == Expr::MLV_Valid)
+    return false;
+
+  unsigned Diag = 0;
+  bool NeedType = false;
+  switch (IsLV) { // C99 6.5.16p2
+  case Expr::MLV_ConstQualified: Diag = diag::err_typecheck_assign_const; break;
+  case Expr::MLV_ArrayType:
+    Diag = diag::err_typecheck_array_not_modifiable_lvalue;
+    NeedType = true;
+    break;
+  case Expr::MLV_NotObjectType:
+    Diag = diag::err_typecheck_non_object_not_modifiable_lvalue;
+    NeedType = true;
+    break;
+  case Expr::MLV_LValueCast:
+    Diag = diag::err_typecheck_lvalue_casts_not_supported;
+    break;
+  case Expr::MLV_Valid:
+    llvm_unreachable("did not take early return for MLV_Valid");
+  case Expr::MLV_InvalidExpression:
+  case Expr::MLV_MemberFunction:
+  case Expr::MLV_ClassTemporary:
+    Diag = diag::err_typecheck_expression_not_modifiable_lvalue;
+    break;
+  case Expr::MLV_IncompleteType:
+  case Expr::MLV_IncompleteVoidType:
+    return S.RequireCompleteType(Loc, E->getType(),
+              S.PDiag(diag::err_typecheck_incomplete_type_not_modifiable_lvalue)
+                  << E->getSourceRange());
+  case Expr::MLV_DuplicateVectorComponents:
+    Diag = diag::err_typecheck_duplicate_vector_components_not_mlvalue;
+    break;
+  case Expr::MLV_NotBlockQualified:
+    Diag = diag::err_block_decl_ref_not_modifiable_lvalue;
+    break;
+  case Expr::MLV_ReadonlyProperty:
+    Diag = diag::error_readonly_property_assignment;
+    break;
+  case Expr::MLV_NoSetterProperty:
+    Diag = diag::error_nosetter_property_assignment;
+    break;
+  case Expr::MLV_SubObjCPropertySetting:
+    Diag = diag::error_no_subobject_property_setting;
+    break;
+  }
+
+  SourceRange Assign;
+  if (Loc != OrigLoc)
+    Assign = SourceRange(OrigLoc, OrigLoc);
+  if (NeedType)
+    S.Diag(Loc, Diag) << E->getType() << E->getSourceRange() << Assign;
+  else
+    S.Diag(Loc, Diag) << E->getSourceRange() << Assign;
+  return true;
+}
+
+
+
+// C99 6.5.16.1
+QualType Sema::CheckAssignmentOperands(Expr *LHS, Expr *&RHS,
+                                       SourceLocation Loc,
+                                       QualType CompoundType) {
+  // Verify that LHS is a modifiable lvalue, and emit error if not.
+  if (CheckForModifiableLvalue(LHS, Loc, *this))
+    return QualType();
+
+  QualType LHSType = LHS->getType();
+  QualType RHSType = CompoundType.isNull() ? RHS->getType() : CompoundType;
+
+  AssignConvertType ConvTy;
+  if (CompoundType.isNull()) {
+    // Simple assignment "x = y".
+    ConvTy = CheckSingleAssignmentConstraints(LHSType, RHS);
+    // Special case of NSObject attributes on c-style pointer types.
+    if (ConvTy == IncompatiblePointer &&
+        ((Context.isObjCNSObjectType(LHSType) &&
+          RHSType->isObjCObjectPointerType()) ||
+         (Context.isObjCNSObjectType(RHSType) &&
+          LHSType->isObjCObjectPointerType())))
+      ConvTy = Compatible;
+
+    // If the RHS is a unary plus or minus, check to see if they = and + are
+    // right next to each other.  If so, the user may have typo'd "x =+ 4"
+    // instead of "x += 4".
+    Expr *RHSCheck = RHS;
+    if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(RHSCheck))
+      RHSCheck = ICE->getSubExpr();
+    if (UnaryOperator *UO = dyn_cast<UnaryOperator>(RHSCheck)) {
+      if ((UO->getOpcode() == UnaryOperator::Plus ||
+           UO->getOpcode() == UnaryOperator::Minus) &&
+          Loc.isFileID() && UO->getOperatorLoc().isFileID() &&
+          // Only if the two operators are exactly adjacent.
+          Loc.getFileLocWithOffset(1) == UO->getOperatorLoc() &&
+          // And there is a space or other character before the subexpr of the
+          // unary +/-.  We don't want to warn on "x=-1".
+          Loc.getFileLocWithOffset(2) != UO->getSubExpr()->getLocStart() &&
+          UO->getSubExpr()->getLocStart().isFileID()) {
+        Diag(Loc, diag::warn_not_compound_assign)
+          << (UO->getOpcode() == UnaryOperator::Plus ? "+" : "-")
+          << SourceRange(UO->getOperatorLoc(), UO->getOperatorLoc());
+      }
+    }
+  } else {
+    // Compound assignment "x += y"
+    ConvTy = CheckAssignmentConstraints(LHSType, RHSType);
+  }
+
+  if (DiagnoseAssignmentResult(ConvTy, Loc, LHSType, RHSType,
+                               RHS, AA_Assigning))
+    return QualType();
+
+  // C99 6.5.16p3: The type of an assignment expression is the type of the
+  // left operand unless the left operand has qualified type, in which case
+  // it is the unqualified version of the type of the left operand.
+  // C99 6.5.16.1p2: In simple assignment, the value of the right operand
+  // is converted to the type of the assignment expression (above).
+  // C++ 5.17p1: the type of the assignment expression is that of its left
+  // operand.
+  return LHSType.getUnqualifiedType();
+}
+
+// C99 6.5.17
+QualType Sema::CheckCommaOperands(Expr *LHS, Expr *&RHS, SourceLocation Loc) {
+  // Comma performs lvalue conversion (C99 6.3.2.1), but not unary conversions.
+  // C++ does not perform this conversion (C++ [expr.comma]p1).
+  if (!getLangOptions().CPlusPlus)
+    DefaultFunctionArrayLvalueConversion(RHS);
+
+  // FIXME: Check that RHS type is complete in C mode (it's legal for it to be
+  // incomplete in C++).
+
+  return RHS->getType();
+}
+
+/// CheckIncrementDecrementOperand - unlike most "Check" methods, this routine
+/// doesn't need to call UsualUnaryConversions or UsualArithmeticConversions.
+QualType Sema::CheckIncrementDecrementOperand(Expr *Op, SourceLocation OpLoc,
+                                              bool isInc) {
+  if (Op->isTypeDependent())
+    return Context.DependentTy;
+
+  QualType ResType = Op->getType();
+  assert(!ResType.isNull() && "no type for increment/decrement expression");
+
+  if (getLangOptions().CPlusPlus && ResType->isBooleanType()) {
+    // Decrement of bool is not allowed.
+    if (!isInc) {
+      Diag(OpLoc, diag::err_decrement_bool) << Op->getSourceRange();
+      return QualType();
+    }
+    // Increment of bool sets it to true, but is deprecated.
+    Diag(OpLoc, diag::warn_increment_bool) << Op->getSourceRange();
+  } else if (ResType->isRealType()) {
+    // OK!
+  } else if (ResType->isAnyPointerType()) {
+    QualType PointeeTy = ResType->getPointeeType();
+
+    // C99 6.5.2.4p2, 6.5.6p2
+    if (PointeeTy->isVoidType()) {
+      if (getLangOptions().CPlusPlus) {
+        Diag(OpLoc, diag::err_typecheck_pointer_arith_void_type)
+          << Op->getSourceRange();
+        return QualType();
+      }
+
+      // Pointer to void is a GNU extension in C.
+      Diag(OpLoc, diag::ext_gnu_void_ptr) << Op->getSourceRange();
+    } else if (PointeeTy->isFunctionType()) {
+      if (getLangOptions().CPlusPlus) {
+        Diag(OpLoc, diag::err_typecheck_pointer_arith_function_type)
+          << Op->getType() << Op->getSourceRange();
+        return QualType();
+      }
+
+      Diag(OpLoc, diag::ext_gnu_ptr_func_arith)
+        << ResType << Op->getSourceRange();
+    } else if (RequireCompleteType(OpLoc, PointeeTy,
+                           PDiag(diag::err_typecheck_arithmetic_incomplete_type)
+                             << Op->getSourceRange()
+                             << ResType))
+      return QualType();
+    // Diagnose bad cases where we step over interface counts.
+    else if (PointeeTy->isObjCInterfaceType() && LangOpts.ObjCNonFragileABI) {
+      Diag(OpLoc, diag::err_arithmetic_nonfragile_interface)
+        << PointeeTy << Op->getSourceRange();
+      return QualType();
+    }
+  } else if (ResType->isAnyComplexType()) {
+    // C99 does not support ++/-- on complex types, we allow as an extension.
+    Diag(OpLoc, diag::ext_integer_increment_complex)
+      << ResType << Op->getSourceRange();
+  } else {
+    Diag(OpLoc, diag::err_typecheck_illegal_increment_decrement)
+      << ResType << int(isInc) << Op->getSourceRange();
+    return QualType();
+  }
+  // At this point, we know we have a real, complex or pointer type.
+  // Now make sure the operand is a modifiable lvalue.
+  if (CheckForModifiableLvalue(Op, OpLoc, *this))
+    return QualType();
+  return ResType;
+}
+
+/// getPrimaryDecl - Helper function for CheckAddressOfOperand().
+/// This routine allows us to typecheck complex/recursive expressions
+/// where the declaration is needed for type checking. We only need to
+/// handle cases when the expression references a function designator
+/// or is an lvalue. Here are some examples:
+///  - &(x) => x
+///  - &*****f => f for f a function designator.
+///  - &s.xx => s
+///  - &s.zz[1].yy -> s, if zz is an array
+///  - *(x + 1) -> x, if x is an array
+///  - &"123"[2] -> 0
+///  - & __real__ x -> x
+static NamedDecl *getPrimaryDecl(Expr *E) {
+  switch (E->getStmtClass()) {
+  case Stmt::DeclRefExprClass:
+    return cast<DeclRefExpr>(E)->getDecl();
+  case Stmt::MemberExprClass:
+    // If this is an arrow operator, the address is an offset from
+    // the base's value, so the object the base refers to is
+    // irrelevant.
+    if (cast<MemberExpr>(E)->isArrow())
+      return 0;
+    // Otherwise, the expression refers to a part of the base
+    return getPrimaryDecl(cast<MemberExpr>(E)->getBase());
+  case Stmt::ArraySubscriptExprClass: {
+    // FIXME: This code shouldn't be necessary!  We should catch the implicit
+    // promotion of register arrays earlier.
+    Expr* Base = cast<ArraySubscriptExpr>(E)->getBase();
+    if (ImplicitCastExpr* ICE = dyn_cast<ImplicitCastExpr>(Base)) {
+      if (ICE->getSubExpr()->getType()->isArrayType())
+        return getPrimaryDecl(ICE->getSubExpr());
+    }
+    return 0;
+  }
+  case Stmt::UnaryOperatorClass: {
+    UnaryOperator *UO = cast<UnaryOperator>(E);
+
+    switch(UO->getOpcode()) {
+    case UnaryOperator::Real:
+    case UnaryOperator::Imag:
+    case UnaryOperator::Extension:
+      return getPrimaryDecl(UO->getSubExpr());
+    default:
+      return 0;
+    }
+  }
+  case Stmt::ParenExprClass:
+    return getPrimaryDecl(cast<ParenExpr>(E)->getSubExpr());
+  case Stmt::ImplicitCastExprClass:
+    // If the result of an implicit cast is an l-value, we care about
+    // the sub-expression; otherwise, the result here doesn't matter.
+    return getPrimaryDecl(cast<ImplicitCastExpr>(E)->getSubExpr());
+  default:
+    return 0;
+  }
+}
+
+/// CheckAddressOfOperand - The operand of & must be either a function
+/// designator or an lvalue designating an object. If it is an lvalue, the
+/// object cannot be declared with storage class register or be a bit field.
+/// Note: The usual conversions are *not* applied to the operand of the &
+/// operator (C99 6.3.2.1p[2-4]), and its result is never an lvalue.
+/// In C++, the operand might be an overloaded function name, in which case
+/// we allow the '&' but retain the overloaded-function type.
+QualType Sema::CheckAddressOfOperand(Expr *op, SourceLocation OpLoc) {
+  // Make sure to ignore parentheses in subsequent checks
+  op = op->IgnoreParens();
+
+  if (op->isTypeDependent())
+    return Context.DependentTy;
+
+  if (getLangOptions().C99) {
+    // Implement C99-only parts of addressof rules.
+    if (UnaryOperator* uOp = dyn_cast<UnaryOperator>(op)) {
+      if (uOp->getOpcode() == UnaryOperator::Deref)
+        // Per C99 6.5.3.2, the address of a deref always returns a valid result
+        // (assuming the deref expression is valid).
+        return uOp->getSubExpr()->getType();
+    }
+    // Technically, there should be a check for array subscript
+    // expressions here, but the result of one is always an lvalue anyway.
+  }
+  NamedDecl *dcl = getPrimaryDecl(op);
+  Expr::isLvalueResult lval = op->isLvalue(Context);
+
+  MemberExpr *ME = dyn_cast<MemberExpr>(op);
+  if (lval == Expr::LV_MemberFunction && ME &&
+      isa<CXXMethodDecl>(ME->getMemberDecl())) {
+    ValueDecl *dcl = cast<MemberExpr>(op)->getMemberDecl();
+    // &f where f is a member of the current object, or &o.f, or &p->f
+    // All these are not allowed, and we need to catch them before the dcl
+    // branch of the if, below.
+    Diag(OpLoc, diag::err_unqualified_pointer_member_function)
+        << dcl;
+    // FIXME: Improve this diagnostic and provide a fixit.
+
+    // Now recover by acting as if the function had been accessed qualified.
+    return Context.getMemberPointerType(op->getType(),
+                Context.getTypeDeclType(cast<RecordDecl>(dcl->getDeclContext()))
+                       .getTypePtr());
+  } else if (lval == Expr::LV_ClassTemporary) {
+    Diag(OpLoc, isSFINAEContext()? diag::err_typecheck_addrof_class_temporary
+                                 : diag::ext_typecheck_addrof_class_temporary)
+      << op->getType() << op->getSourceRange();
+    if (isSFINAEContext())
+      return QualType();
+  } else if (lval != Expr::LV_Valid && lval != Expr::LV_IncompleteVoidType) {
+    // C99 6.5.3.2p1
+    // The operand must be either an l-value or a function designator
+    if (!op->getType()->isFunctionType()) {
+      // FIXME: emit more specific diag...
+      Diag(OpLoc, diag::err_typecheck_invalid_lvalue_addrof)
+        << op->getSourceRange();
+      return QualType();
+    }
+  } else if (op->getBitField()) { // C99 6.5.3.2p1
+    // The operand cannot be a bit-field
+    Diag(OpLoc, diag::err_typecheck_address_of)
+      << "bit-field" << op->getSourceRange();
+        return QualType();
+  } else if (op->refersToVectorElement()) {
+    // The operand cannot be an element of a vector
+    Diag(OpLoc, diag::err_typecheck_address_of)
+      << "vector element" << op->getSourceRange();
+    return QualType();
+  } else if (isa<ObjCPropertyRefExpr>(op)) {
+    // cannot take address of a property expression.
+    Diag(OpLoc, diag::err_typecheck_address_of)
+      << "property expression" << op->getSourceRange();
+    return QualType();
+  } else if (ConditionalOperator *CO = dyn_cast<ConditionalOperator>(op)) {
+    // FIXME: Can LHS ever be null here?
+    if (!CheckAddressOfOperand(CO->getTrueExpr(), OpLoc).isNull())
+      return CheckAddressOfOperand(CO->getFalseExpr(), OpLoc);
+  } else if (isa<UnresolvedLookupExpr>(op)) {
+    return Context.OverloadTy;
+  } else if (dcl) { // C99 6.5.3.2p1
+    // We have an lvalue with a decl. Make sure the decl is not declared
+    // with the register storage-class specifier.
+    if (const VarDecl *vd = dyn_cast<VarDecl>(dcl)) {
+      if (vd->getStorageClass() == VarDecl::Register) {
+        Diag(OpLoc, diag::err_typecheck_address_of)
+          << "register variable" << op->getSourceRange();
+        return QualType();
+      }
+    } else if (isa<FunctionTemplateDecl>(dcl)) {
+      return Context.OverloadTy;
+    } else if (FieldDecl *FD = dyn_cast<FieldDecl>(dcl)) {
+      // Okay: we can take the address of a field.
+      // Could be a pointer to member, though, if there is an explicit
+      // scope qualifier for the class.
+      if (isa<DeclRefExpr>(op) && cast<DeclRefExpr>(op)->getQualifier()) {
+        DeclContext *Ctx = dcl->getDeclContext();
+        if (Ctx && Ctx->isRecord()) {
+          if (FD->getType()->isReferenceType()) {
+            Diag(OpLoc,
+                 diag::err_cannot_form_pointer_to_member_of_reference_type)
+              << FD->getDeclName() << FD->getType();
+            return QualType();
+          }
+
+          return Context.getMemberPointerType(op->getType(),
+                Context.getTypeDeclType(cast<RecordDecl>(Ctx)).getTypePtr());
+        }
+      }
+    } else if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(dcl)) {
+      // Okay: we can take the address of a function.
+      // As above.
+      if (isa<DeclRefExpr>(op) && cast<DeclRefExpr>(op)->getQualifier() &&
+          MD->isInstance())
+        return Context.getMemberPointerType(op->getType(),
+              Context.getTypeDeclType(MD->getParent()).getTypePtr());
+    } else if (!isa<FunctionDecl>(dcl))
+      assert(0 && "Unknown/unexpected decl type");
+  }
+
+  if (lval == Expr::LV_IncompleteVoidType) {
+    // Taking the address of a void variable is technically illegal, but we
+    // allow it in cases which are otherwise valid.
+    // Example: "extern void x; void* y = &x;".
+    Diag(OpLoc, diag::ext_typecheck_addrof_void) << op->getSourceRange();
+  }
+
+  // If the operand has type "type", the result has type "pointer to type".
+  return Context.getPointerType(op->getType());
+}
+
+QualType Sema::CheckIndirectionOperand(Expr *Op, SourceLocation OpLoc) {
+  if (Op->isTypeDependent())
+    return Context.DependentTy;
+
+  UsualUnaryConversions(Op);
+  QualType Ty = Op->getType();
+
+  // Note that per both C89 and C99, this is always legal, even if ptype is an
+  // incomplete type or void.  It would be possible to warn about dereferencing
+  // a void pointer, but it's completely well-defined, and such a warning is
+  // unlikely to catch any mistakes.
+  if (const PointerType *PT = Ty->getAs<PointerType>())
+    return PT->getPointeeType();
+
+  if (const ObjCObjectPointerType *OPT = Ty->getAs<ObjCObjectPointerType>())
+    return OPT->getPointeeType();
+
+  Diag(OpLoc, diag::err_typecheck_indirection_requires_pointer)
+    << Ty << Op->getSourceRange();
+  return QualType();
+}
+
+static inline BinaryOperator::Opcode ConvertTokenKindToBinaryOpcode(
+  tok::TokenKind Kind) {
+  BinaryOperator::Opcode Opc;
+  switch (Kind) {
+  default: assert(0 && "Unknown binop!");
+  case tok::periodstar:           Opc = BinaryOperator::PtrMemD; break;
+  case tok::arrowstar:            Opc = BinaryOperator::PtrMemI; break;
+  case tok::star:                 Opc = BinaryOperator::Mul; break;
+  case tok::slash:                Opc = BinaryOperator::Div; break;
+  case tok::percent:              Opc = BinaryOperator::Rem; break;
+  case tok::plus:                 Opc = BinaryOperator::Add; break;
+  case tok::minus:                Opc = BinaryOperator::Sub; break;
+  case tok::lessless:             Opc = BinaryOperator::Shl; break;
+  case tok::greatergreater:       Opc = BinaryOperator::Shr; break;
+  case tok::lessequal:            Opc = BinaryOperator::LE; break;
+  case tok::less:                 Opc = BinaryOperator::LT; break;
+  case tok::greaterequal:         Opc = BinaryOperator::GE; break;
+  case tok::greater:              Opc = BinaryOperator::GT; break;
+  case tok::exclaimequal:         Opc = BinaryOperator::NE; break;
+  case tok::equalequal:           Opc = BinaryOperator::EQ; break;
+  case tok::amp:                  Opc = BinaryOperator::And; break;
+  case tok::caret:                Opc = BinaryOperator::Xor; break;
+  case tok::pipe:                 Opc = BinaryOperator::Or; break;
+  case tok::ampamp:               Opc = BinaryOperator::LAnd; break;
+  case tok::pipepipe:             Opc = BinaryOperator::LOr; break;
+  case tok::equal:                Opc = BinaryOperator::Assign; break;
+  case tok::starequal:            Opc = BinaryOperator::MulAssign; break;
+  case tok::slashequal:           Opc = BinaryOperator::DivAssign; break;
+  case tok::percentequal:         Opc = BinaryOperator::RemAssign; break;
+  case tok::plusequal:            Opc = BinaryOperator::AddAssign; break;
+  case tok::minusequal:           Opc = BinaryOperator::SubAssign; break;
+  case tok::lesslessequal:        Opc = BinaryOperator::ShlAssign; break;
+  case tok::greatergreaterequal:  Opc = BinaryOperator::ShrAssign; break;
+  case tok::ampequal:             Opc = BinaryOperator::AndAssign; break;
+  case tok::caretequal:           Opc = BinaryOperator::XorAssign; break;
+  case tok::pipeequal:            Opc = BinaryOperator::OrAssign; break;
+  case tok::comma:                Opc = BinaryOperator::Comma; break;
+  }
+  return Opc;
+}
+
+static inline UnaryOperator::Opcode ConvertTokenKindToUnaryOpcode(
+  tok::TokenKind Kind) {
+  UnaryOperator::Opcode Opc;
+  switch (Kind) {
+  default: assert(0 && "Unknown unary op!");
+  case tok::plusplus:     Opc = UnaryOperator::PreInc; break;
+  case tok::minusminus:   Opc = UnaryOperator::PreDec; break;
+  case tok::amp:          Opc = UnaryOperator::AddrOf; break;
+  case tok::star:         Opc = UnaryOperator::Deref; break;
+  case tok::plus:         Opc = UnaryOperator::Plus; break;
+  case tok::minus:        Opc = UnaryOperator::Minus; break;
+  case tok::tilde:        Opc = UnaryOperator::Not; break;
+  case tok::exclaim:      Opc = UnaryOperator::LNot; break;
+  case tok::kw___real:    Opc = UnaryOperator::Real; break;
+  case tok::kw___imag:    Opc = UnaryOperator::Imag; break;
+  case tok::kw___extension__: Opc = UnaryOperator::Extension; break;
+  }
+  return Opc;
+}
+
+/// CreateBuiltinBinOp - Creates a new built-in binary operation with
+/// operator @p Opc at location @c TokLoc. This routine only supports
+/// built-in operations; ActOnBinOp handles overloaded operators.
+Action::OwningExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc,
+                                                  unsigned Op,
+                                                  Expr *lhs, Expr *rhs) {
+  QualType ResultTy;     // Result type of the binary operator.
+  BinaryOperator::Opcode Opc = (BinaryOperator::Opcode)Op;
+  // The following two variables are used for compound assignment operators
+  QualType CompLHSTy;    // Type of LHS after promotions for computation
+  QualType CompResultTy; // Type of computation result
+
+  switch (Opc) {
+  case BinaryOperator::Assign:
+    ResultTy = CheckAssignmentOperands(lhs, rhs, OpLoc, QualType());
+    break;
+  case BinaryOperator::PtrMemD:
+  case BinaryOperator::PtrMemI:
+    ResultTy = CheckPointerToMemberOperands(lhs, rhs, OpLoc,
+                                            Opc == BinaryOperator::PtrMemI);
+    break;
+  case BinaryOperator::Mul:
+  case BinaryOperator::Div:
+    ResultTy = CheckMultiplyDivideOperands(lhs, rhs, OpLoc, false,
+                                           Opc == BinaryOperator::Div);
+    break;
+  case BinaryOperator::Rem:
+    ResultTy = CheckRemainderOperands(lhs, rhs, OpLoc);
+    break;
+  case BinaryOperator::Add:
+    ResultTy = CheckAdditionOperands(lhs, rhs, OpLoc);
+    break;
+  case BinaryOperator::Sub:
+    ResultTy = CheckSubtractionOperands(lhs, rhs, OpLoc);
+    break;
+  case BinaryOperator::Shl:
+  case BinaryOperator::Shr:
+    ResultTy = CheckShiftOperands(lhs, rhs, OpLoc);
+    break;
+  case BinaryOperator::LE:
+  case BinaryOperator::LT:
+  case BinaryOperator::GE:
+  case BinaryOperator::GT:
+    ResultTy = CheckCompareOperands(lhs, rhs, OpLoc, Opc, true);
+    break;
+  case BinaryOperator::EQ:
+  case BinaryOperator::NE:
+    ResultTy = CheckCompareOperands(lhs, rhs, OpLoc, Opc, false);
+    break;
+  case BinaryOperator::And:
+  case BinaryOperator::Xor:
+  case BinaryOperator::Or:
+    ResultTy = CheckBitwiseOperands(lhs, rhs, OpLoc);
+    break;
+  case BinaryOperator::LAnd:
+  case BinaryOperator::LOr:
+    ResultTy = CheckLogicalOperands(lhs, rhs, OpLoc);
+    break;
+  case BinaryOperator::MulAssign:
+  case BinaryOperator::DivAssign:
+    CompResultTy = CheckMultiplyDivideOperands(lhs, rhs, OpLoc, true,
+                                              Opc == BinaryOperator::DivAssign);
+    CompLHSTy = CompResultTy;
+    if (!CompResultTy.isNull())
+      ResultTy = CheckAssignmentOperands(lhs, rhs, OpLoc, CompResultTy);
+    break;
+  case BinaryOperator::RemAssign:
+    CompResultTy = CheckRemainderOperands(lhs, rhs, OpLoc, true);
+    CompLHSTy = CompResultTy;
+    if (!CompResultTy.isNull())
+      ResultTy = CheckAssignmentOperands(lhs, rhs, OpLoc, CompResultTy);
+    break;
+  case BinaryOperator::AddAssign:
+    CompResultTy = CheckAdditionOperands(lhs, rhs, OpLoc, &CompLHSTy);
+    if (!CompResultTy.isNull())
+      ResultTy = CheckAssignmentOperands(lhs, rhs, OpLoc, CompResultTy);
+    break;
+  case BinaryOperator::SubAssign:
+    CompResultTy = CheckSubtractionOperands(lhs, rhs, OpLoc, &CompLHSTy);
+    if (!CompResultTy.isNull())
+      ResultTy = CheckAssignmentOperands(lhs, rhs, OpLoc, CompResultTy);
+    break;
+  case BinaryOperator::ShlAssign:
+  case BinaryOperator::ShrAssign:
+    CompResultTy = CheckShiftOperands(lhs, rhs, OpLoc, true);
+    CompLHSTy = CompResultTy;
+    if (!CompResultTy.isNull())
+      ResultTy = CheckAssignmentOperands(lhs, rhs, OpLoc, CompResultTy);
+    break;
+  case BinaryOperator::AndAssign:
+  case BinaryOperator::XorAssign:
+  case BinaryOperator::OrAssign:
+    CompResultTy = CheckBitwiseOperands(lhs, rhs, OpLoc, true);
+    CompLHSTy = CompResultTy;
+    if (!CompResultTy.isNull())
+      ResultTy = CheckAssignmentOperands(lhs, rhs, OpLoc, CompResultTy);
+    break;
+  case BinaryOperator::Comma:
+    ResultTy = CheckCommaOperands(lhs, rhs, OpLoc);
+    break;
+  }
+  if (ResultTy.isNull())
+    return ExprError();
+  if (CompResultTy.isNull())
+    return Owned(new (Context) BinaryOperator(lhs, rhs, Opc, ResultTy, OpLoc));
+  else
+    return Owned(new (Context) CompoundAssignOperator(lhs, rhs, Opc, ResultTy,
+                                                      CompLHSTy, CompResultTy,
+                                                      OpLoc));
+}
+
+/// SuggestParentheses - Emit a diagnostic together with a fixit hint that wraps
+/// ParenRange in parentheses.
+static void SuggestParentheses(Sema &Self, SourceLocation Loc,
+                               const PartialDiagnostic &PD,
+                               const PartialDiagnostic &FirstNote,
+                               SourceRange FirstParenRange,
+                               const PartialDiagnostic &SecondNote,
+                               SourceRange SecondParenRange) {
+  Self.Diag(Loc, PD);
+
+  if (!FirstNote.getDiagID())
+    return;
+
+  SourceLocation EndLoc = Self.PP.getLocForEndOfToken(FirstParenRange.getEnd());
+  if (!FirstParenRange.getEnd().isFileID() || EndLoc.isInvalid()) {
+    // We can't display the parentheses, so just return.
+    return;
+  }
+
+  Self.Diag(Loc, FirstNote)
+    << FixItHint::CreateInsertion(FirstParenRange.getBegin(), "(")
+    << FixItHint::CreateInsertion(EndLoc, ")");
+
+  if (!SecondNote.getDiagID())
+    return;
+
+  EndLoc = Self.PP.getLocForEndOfToken(SecondParenRange.getEnd());
+  if (!SecondParenRange.getEnd().isFileID() || EndLoc.isInvalid()) {
+    // We can't display the parentheses, so just dig the
+    // warning/error and return.
+    Self.Diag(Loc, SecondNote);
+    return;
+  }
+
+  Self.Diag(Loc, SecondNote)
+    << FixItHint::CreateInsertion(SecondParenRange.getBegin(), "(")
+    << FixItHint::CreateInsertion(EndLoc, ")");
+}
+
+/// DiagnoseBitwisePrecedence - Emit a warning when bitwise and comparison
+/// operators are mixed in a way that suggests that the programmer forgot that
+/// comparison operators have higher precedence. The most typical example of
+/// such code is "flags & 0x0020 != 0", which is equivalent to "flags & 1".
+static void DiagnoseBitwisePrecedence(Sema &Self, BinaryOperator::Opcode Opc,
+                                      SourceLocation OpLoc,Expr *lhs,Expr *rhs){
+  typedef BinaryOperator BinOp;
+  BinOp::Opcode lhsopc = static_cast<BinOp::Opcode>(-1),
+                rhsopc = static_cast<BinOp::Opcode>(-1);
+  if (BinOp *BO = dyn_cast<BinOp>(lhs))
+    lhsopc = BO->getOpcode();
+  if (BinOp *BO = dyn_cast<BinOp>(rhs))
+    rhsopc = BO->getOpcode();
+
+  // Subs are not binary operators.
+  if (lhsopc == -1 && rhsopc == -1)
+    return;
+
+  // Bitwise operations are sometimes used as eager logical ops.
+  // Don't diagnose this.
+  if ((BinOp::isComparisonOp(lhsopc) || BinOp::isBitwiseOp(lhsopc)) &&
+      (BinOp::isComparisonOp(rhsopc) || BinOp::isBitwiseOp(rhsopc)))
+    return;
+
+  if (BinOp::isComparisonOp(lhsopc))
+    SuggestParentheses(Self, OpLoc,
+      Self.PDiag(diag::warn_precedence_bitwise_rel)
+          << SourceRange(lhs->getLocStart(), OpLoc)
+          << BinOp::getOpcodeStr(Opc) << BinOp::getOpcodeStr(lhsopc),
+      Self.PDiag(diag::note_precedence_bitwise_first)
+          << BinOp::getOpcodeStr(Opc),
+      SourceRange(cast<BinOp>(lhs)->getRHS()->getLocStart(), rhs->getLocEnd()),
+      Self.PDiag(diag::note_precedence_bitwise_silence)
+          << BinOp::getOpcodeStr(lhsopc),
+                       lhs->getSourceRange());
+  else if (BinOp::isComparisonOp(rhsopc))
+    SuggestParentheses(Self, OpLoc,
+      Self.PDiag(diag::warn_precedence_bitwise_rel)
+          << SourceRange(OpLoc, rhs->getLocEnd())
+          << BinOp::getOpcodeStr(Opc) << BinOp::getOpcodeStr(rhsopc),
+      Self.PDiag(diag::note_precedence_bitwise_first)
+        << BinOp::getOpcodeStr(Opc),
+      SourceRange(lhs->getLocEnd(), cast<BinOp>(rhs)->getLHS()->getLocStart()),
+      Self.PDiag(diag::note_precedence_bitwise_silence)
+        << BinOp::getOpcodeStr(rhsopc),
+                       rhs->getSourceRange());
+}
+
+/// DiagnoseBinOpPrecedence - Emit warnings for expressions with tricky
+/// precedence. This currently diagnoses only "arg1 'bitwise' arg2 'eq' arg3".
+/// But it could also warn about arg1 && arg2 || arg3, as GCC 4.3+ does.
+static void DiagnoseBinOpPrecedence(Sema &Self, BinaryOperator::Opcode Opc,
+                                    SourceLocation OpLoc, Expr *lhs, Expr *rhs){
+  if (BinaryOperator::isBitwiseOp(Opc))
+    DiagnoseBitwisePrecedence(Self, Opc, OpLoc, lhs, rhs);
+}
+
+// Binary Operators.  'Tok' is the token for the operator.
+Action::OwningExprResult Sema::ActOnBinOp(Scope *S, SourceLocation TokLoc,
+                                          tok::TokenKind Kind,
+                                          ExprArg LHS, ExprArg RHS) {
+  BinaryOperator::Opcode Opc = ConvertTokenKindToBinaryOpcode(Kind);
+  Expr *lhs = LHS.takeAs<Expr>(), *rhs = RHS.takeAs<Expr>();
+
+  assert((lhs != 0) && "ActOnBinOp(): missing left expression");
+  assert((rhs != 0) && "ActOnBinOp(): missing right expression");
+
+  // Emit warnings for tricky precedence issues, e.g. "bitfield & 0x4 == 0"
+  DiagnoseBinOpPrecedence(*this, Opc, TokLoc, lhs, rhs);
+
+  return BuildBinOp(S, TokLoc, Opc, lhs, rhs);
+}
+
+Action::OwningExprResult Sema::BuildBinOp(Scope *S, SourceLocation OpLoc,
+                                          BinaryOperator::Opcode Opc,
+                                          Expr *lhs, Expr *rhs) {
+  if (getLangOptions().CPlusPlus &&
+      (lhs->getType()->isOverloadableType() ||
+       rhs->getType()->isOverloadableType())) {
+    // Find all of the overloaded operators visible from this
+    // point. We perform both an operator-name lookup from the local
+    // scope and an argument-dependent lookup based on the types of
+    // the arguments.
+    UnresolvedSet<16> Functions;
+    OverloadedOperatorKind OverOp = BinaryOperator::getOverloadedOperator(Opc);
+    if (S && OverOp != OO_None)
+      LookupOverloadedOperatorName(OverOp, S, lhs->getType(), rhs->getType(),
+                                   Functions);
+
+    // Build the (potentially-overloaded, potentially-dependent)
+    // binary operation.
+    return CreateOverloadedBinOp(OpLoc, Opc, Functions, lhs, rhs);
+  }
+
+  // Build a built-in binary operation.
+  return CreateBuiltinBinOp(OpLoc, Opc, lhs, rhs);
+}
+
+Action::OwningExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc,
+                                                    unsigned OpcIn,
+                                                    ExprArg InputArg) {
+  UnaryOperator::Opcode Opc = static_cast<UnaryOperator::Opcode>(OpcIn);
+
+  // FIXME: Input is modified below, but InputArg is not updated appropriately.
+  Expr *Input = (Expr *)InputArg.get();
+  QualType resultType;
+  switch (Opc) {
+  case UnaryOperator::OffsetOf:
+    assert(false && "Invalid unary operator");
+    break;
+
+  case UnaryOperator::PreInc:
+  case UnaryOperator::PreDec:
+  case UnaryOperator::PostInc:
+  case UnaryOperator::PostDec:
+    resultType = CheckIncrementDecrementOperand(Input, OpLoc,
+                                                Opc == UnaryOperator::PreInc ||
+                                                Opc == UnaryOperator::PostInc);
+    break;
+  case UnaryOperator::AddrOf:
+    resultType = CheckAddressOfOperand(Input, OpLoc);
+    break;
+  case UnaryOperator::Deref:
+    DefaultFunctionArrayLvalueConversion(Input);
+    resultType = CheckIndirectionOperand(Input, OpLoc);
+    break;
+  case UnaryOperator::Plus:
+  case UnaryOperator::Minus:
+    UsualUnaryConversions(Input);
+    resultType = Input->getType();
+    if (resultType->isDependentType())
+      break;
+    if (resultType->isArithmeticType()) // C99 6.5.3.3p1
+      break;
+    else if (getLangOptions().CPlusPlus && // C++ [expr.unary.op]p6-7
+             resultType->isEnumeralType())
+      break;
+    else if (getLangOptions().CPlusPlus && // C++ [expr.unary.op]p6
+             Opc == UnaryOperator::Plus &&
+             resultType->isPointerType())
+      break;
+
+    return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr)
+      << resultType << Input->getSourceRange());
+  case UnaryOperator::Not: // bitwise complement
+    UsualUnaryConversions(Input);
+    resultType = Input->getType();
+    if (resultType->isDependentType())
+      break;
+    // C99 6.5.3.3p1. We allow complex int and float as a GCC extension.
+    if (resultType->isComplexType() || resultType->isComplexIntegerType())
+      // C99 does not support '~' for complex conjugation.
+      Diag(OpLoc, diag::ext_integer_complement_complex)
+        << resultType << Input->getSourceRange();
+    else if (!resultType->isIntegerType())
+      return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr)
+        << resultType << Input->getSourceRange());
+    break;
+  case UnaryOperator::LNot: // logical negation
+    // Unlike +/-/~, integer promotions aren't done here (C99 6.5.3.3p5).
+    DefaultFunctionArrayLvalueConversion(Input);
+    resultType = Input->getType();
+    if (resultType->isDependentType())
+      break;
+    if (!resultType->isScalarType()) // C99 6.5.3.3p1
+      return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr)
+        << resultType << Input->getSourceRange());
+    // LNot always has type int. C99 6.5.3.3p5.
+    // In C++, it's bool. C++ 5.3.1p8
+    resultType = getLangOptions().CPlusPlus ? Context.BoolTy : Context.IntTy;
+    break;
+  case UnaryOperator::Real:
+  case UnaryOperator::Imag:
+    resultType = CheckRealImagOperand(Input, OpLoc, Opc == UnaryOperator::Real);
+    break;
+  case UnaryOperator::Extension:
+    resultType = Input->getType();
+    break;
+  }
+  if (resultType.isNull())
+    return ExprError();
+
+  InputArg.release();
+  return Owned(new (Context) UnaryOperator(Input, Opc, resultType, OpLoc));
+}
+
+Action::OwningExprResult Sema::BuildUnaryOp(Scope *S, SourceLocation OpLoc,
+                                            UnaryOperator::Opcode Opc,
+                                            ExprArg input) {
+  Expr *Input = (Expr*)input.get();
+  if (getLangOptions().CPlusPlus && Input->getType()->isOverloadableType() &&
+      Opc != UnaryOperator::Extension) {
+    // Find all of the overloaded operators visible from this
+    // point. We perform both an operator-name lookup from the local
+    // scope and an argument-dependent lookup based on the types of
+    // the arguments.
+    UnresolvedSet<16> Functions;
+    OverloadedOperatorKind OverOp = UnaryOperator::getOverloadedOperator(Opc);
+    if (S && OverOp != OO_None)
+      LookupOverloadedOperatorName(OverOp, S, Input->getType(), QualType(),
+                                   Functions);
+
+    return CreateOverloadedUnaryOp(OpLoc, Opc, Functions, move(input));
+  }
+
+  return CreateBuiltinUnaryOp(OpLoc, Opc, move(input));
+}
+
+// Unary Operators.  'Tok' is the token for the operator.
+Action::OwningExprResult Sema::ActOnUnaryOp(Scope *S, SourceLocation OpLoc,
+                                            tok::TokenKind Op, ExprArg input) {
+  return BuildUnaryOp(S, OpLoc, ConvertTokenKindToUnaryOpcode(Op), move(input));
+}
+
+/// ActOnAddrLabel - Parse the GNU address of label extension: "&&foo".
+Sema::OwningExprResult Sema::ActOnAddrLabel(SourceLocation OpLoc,
+                                            SourceLocation LabLoc,
+                                            IdentifierInfo *LabelII) {
+  // Look up the record for this label identifier.
+  LabelStmt *&LabelDecl = getLabelMap()[LabelII];
+
+  // If we haven't seen this label yet, create a forward reference. It
+  // will be validated and/or cleaned up in ActOnFinishFunctionBody.
+  if (LabelDecl == 0)
+    LabelDecl = new (Context) LabelStmt(LabLoc, LabelII, 0);
+
+  // Create the AST node.  The address of a label always has type 'void*'.
+  return Owned(new (Context) AddrLabelExpr(OpLoc, LabLoc, LabelDecl,
+                                       Context.getPointerType(Context.VoidTy)));
+}
+
+Sema::OwningExprResult
+Sema::ActOnStmtExpr(SourceLocation LPLoc, StmtArg substmt,
+                    SourceLocation RPLoc) { // "({..})"
+  Stmt *SubStmt = static_cast<Stmt*>(substmt.get());
+  assert(SubStmt && isa<CompoundStmt>(SubStmt) && "Invalid action invocation!");
+  CompoundStmt *Compound = cast<CompoundStmt>(SubStmt);
+
+  bool isFileScope
+    = (getCurFunctionOrMethodDecl() == 0) && (getCurBlock() == 0);
+  if (isFileScope)
+    return ExprError(Diag(LPLoc, diag::err_stmtexpr_file_scope));
+
+  // FIXME: there are a variety of strange constraints to enforce here, for
+  // example, it is not possible to goto into a stmt expression apparently.
+  // More semantic analysis is needed.
+
+  // If there are sub stmts in the compound stmt, take the type of the last one
+  // as the type of the stmtexpr.
+  QualType Ty = Context.VoidTy;
+
+  if (!Compound->body_empty()) {
+    Stmt *LastStmt = Compound->body_back();
+    // If LastStmt is a label, skip down through into the body.
+    while (LabelStmt *Label = dyn_cast<LabelStmt>(LastStmt))
+      LastStmt = Label->getSubStmt();
+
+    if (Expr *LastExpr = dyn_cast<Expr>(LastStmt))
+      Ty = LastExpr->getType();
+  }
+
+  // FIXME: Check that expression type is complete/non-abstract; statement
+  // expressions are not lvalues.
+
+  substmt.release();
+  return Owned(new (Context) StmtExpr(Compound, Ty, LPLoc, RPLoc));
+}
+
+Sema::OwningExprResult Sema::ActOnBuiltinOffsetOf(Scope *S,
+                                                  SourceLocation BuiltinLoc,
+                                                  SourceLocation TypeLoc,
+                                                  TypeTy *argty,
+                                                  OffsetOfComponent *CompPtr,
+                                                  unsigned NumComponents,
+                                                  SourceLocation RPLoc) {
+  // FIXME: This function leaks all expressions in the offset components on
+  // error.
+  // FIXME: Preserve type source info.
+  QualType ArgTy = GetTypeFromParser(argty);
+  assert(!ArgTy.isNull() && "Missing type argument!");
+
+  bool Dependent = ArgTy->isDependentType();
+
+  // We must have at least one component that refers to the type, and the first
+  // one is known to be a field designator.  Verify that the ArgTy represents
+  // a struct/union/class.
+  if (!Dependent && !ArgTy->isRecordType())
+    return ExprError(Diag(TypeLoc, diag::err_offsetof_record_type) << ArgTy);
+
+  // FIXME: Type must be complete per C99 7.17p3 because a declaring a variable
+  // with an incomplete type would be illegal.
+
+  // Otherwise, create a null pointer as the base, and iteratively process
+  // the offsetof designators.
+  QualType ArgTyPtr = Context.getPointerType(ArgTy);
+  Expr* Res = new (Context) ImplicitValueInitExpr(ArgTyPtr);
+  Res = new (Context) UnaryOperator(Res, UnaryOperator::Deref,
+                                    ArgTy, SourceLocation());
+
+  // offsetof with non-identifier designators (e.g. "offsetof(x, a.b[c])") are a
+  // GCC extension, diagnose them.
+  // FIXME: This diagnostic isn't actually visible because the location is in
+  // a system header!
+  if (NumComponents != 1)
+    Diag(BuiltinLoc, diag::ext_offsetof_extended_field_designator)
+      << SourceRange(CompPtr[1].LocStart, CompPtr[NumComponents-1].LocEnd);
+
+  if (!Dependent) {
+    bool DidWarnAboutNonPOD = false;
+
+    if (RequireCompleteType(TypeLoc, Res->getType(),
+                            diag::err_offsetof_incomplete_type))
+      return ExprError();
+
+    // FIXME: Dependent case loses a lot of information here. And probably
+    // leaks like a sieve.
+    for (unsigned i = 0; i != NumComponents; ++i) {
+      const OffsetOfComponent &OC = CompPtr[i];
+      if (OC.isBrackets) {
+        // Offset of an array sub-field.  TODO: Should we allow vector elements?
+        const ArrayType *AT = Context.getAsArrayType(Res->getType());
+        if (!AT) {
+          Res->Destroy(Context);
+          return ExprError(Diag(OC.LocEnd, diag::err_offsetof_array_type)
+            << Res->getType());
+        }
+
+        // FIXME: C++: Verify that operator[] isn't overloaded.
+
+        // Promote the array so it looks more like a normal array subscript
+        // expression.
+        DefaultFunctionArrayLvalueConversion(Res);
+
+        // C99 6.5.2.1p1
+        Expr *Idx = static_cast<Expr*>(OC.U.E);
+        // FIXME: Leaks Res
+        if (!Idx->isTypeDependent() && !Idx->getType()->isIntegerType())
+          return ExprError(Diag(Idx->getLocStart(),
+                                diag::err_typecheck_subscript_not_integer)
+            << Idx->getSourceRange());
+
+        Res = new (Context) ArraySubscriptExpr(Res, Idx, AT->getElementType(),
+                                               OC.LocEnd);
+        continue;
+      }
+
+      const RecordType *RC = Res->getType()->getAs<RecordType>();
+      if (!RC) {
+        Res->Destroy(Context);
+        return ExprError(Diag(OC.LocEnd, diag::err_offsetof_record_type)
+          << Res->getType());
+      }
+
+      // Get the decl corresponding to this.
+      RecordDecl *RD = RC->getDecl();
+      if (CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(RD)) {
+        if (!CRD->isPOD() && !DidWarnAboutNonPOD &&
+            DiagRuntimeBehavior(BuiltinLoc,
+                                PDiag(diag::warn_offsetof_non_pod_type)
+                                  << SourceRange(CompPtr[0].LocStart, OC.LocEnd)
+                                  << Res->getType()))
+          DidWarnAboutNonPOD = true;
+      }
+
+      LookupResult R(*this, OC.U.IdentInfo, OC.LocStart, LookupMemberName);
+      LookupQualifiedName(R, RD);
+
+      FieldDecl *MemberDecl = R.getAsSingle<FieldDecl>();
+      // FIXME: Leaks Res
+      if (!MemberDecl)
+        return ExprError(Diag(BuiltinLoc, diag::err_no_member)
+         << OC.U.IdentInfo << RD << SourceRange(OC.LocStart, OC.LocEnd));
+
+      // FIXME: C++: Verify that MemberDecl isn't a static field.
+      // FIXME: Verify that MemberDecl isn't a bitfield.
+      if (cast<RecordDecl>(MemberDecl->getDeclContext())->isAnonymousStructOrUnion()) {
+        Res = BuildAnonymousStructUnionMemberReference(
+            OC.LocEnd, MemberDecl, Res, OC.LocEnd).takeAs<Expr>();
+      } else {
+        PerformObjectMemberConversion(Res, /*Qualifier=*/0,
+                                      *R.begin(), MemberDecl);
+        // MemberDecl->getType() doesn't get the right qualifiers, but it
+        // doesn't matter here.
+        Res = new (Context) MemberExpr(Res, false, MemberDecl, OC.LocEnd,
+                MemberDecl->getType().getNonReferenceType());
+      }
+    }
+  }
+
+  return Owned(new (Context) UnaryOperator(Res, UnaryOperator::OffsetOf,
+                                           Context.getSizeType(), BuiltinLoc));
+}
+
+
+Sema::OwningExprResult Sema::ActOnTypesCompatibleExpr(SourceLocation BuiltinLoc,
+                                                      TypeTy *arg1,TypeTy *arg2,
+                                                      SourceLocation RPLoc) {
+  // FIXME: Preserve type source info.
+  QualType argT1 = GetTypeFromParser(arg1);
+  QualType argT2 = GetTypeFromParser(arg2);
+
+  assert((!argT1.isNull() && !argT2.isNull()) && "Missing type argument(s)");
+
+  if (getLangOptions().CPlusPlus) {
+    Diag(BuiltinLoc, diag::err_types_compatible_p_in_cplusplus)
+      << SourceRange(BuiltinLoc, RPLoc);
+    return ExprError();
+  }
+
+  return Owned(new (Context) TypesCompatibleExpr(Context.IntTy, BuiltinLoc,
+                                                 argT1, argT2, RPLoc));
+}
+
+Sema::OwningExprResult Sema::ActOnChooseExpr(SourceLocation BuiltinLoc,
+                                             ExprArg cond,
+                                             ExprArg expr1, ExprArg expr2,
+                                             SourceLocation RPLoc) {
+  Expr *CondExpr = static_cast<Expr*>(cond.get());
+  Expr *LHSExpr = static_cast<Expr*>(expr1.get());
+  Expr *RHSExpr = static_cast<Expr*>(expr2.get());
+
+  assert((CondExpr && LHSExpr && RHSExpr) && "Missing type argument(s)");
+
+  QualType resType;
+  bool ValueDependent = false;
+  if (CondExpr->isTypeDependent() || CondExpr->isValueDependent()) {
+    resType = Context.DependentTy;
+    ValueDependent = true;
+  } else {
+    // The conditional expression is required to be a constant expression.
+    llvm::APSInt condEval(32);
+    SourceLocation ExpLoc;
+    if (!CondExpr->isIntegerConstantExpr(condEval, Context, &ExpLoc))
+      return ExprError(Diag(ExpLoc,
+                       diag::err_typecheck_choose_expr_requires_constant)
+        << CondExpr->getSourceRange());
+
+    // If the condition is > zero, then the AST type is the same as the LSHExpr.
+    resType = condEval.getZExtValue() ? LHSExpr->getType() : RHSExpr->getType();
+    ValueDependent = condEval.getZExtValue() ? LHSExpr->isValueDependent()
+                                             : RHSExpr->isValueDependent();
+  }
+
+  cond.release(); expr1.release(); expr2.release();
+  return Owned(new (Context) ChooseExpr(BuiltinLoc, CondExpr, LHSExpr, RHSExpr,
+                                        resType, RPLoc,
+                                        resType->isDependentType(),
+                                        ValueDependent));
+}
+
+//===----------------------------------------------------------------------===//
+// Clang Extensions.
+//===----------------------------------------------------------------------===//
+
+/// ActOnBlockStart - This callback is invoked when a block literal is started.
+void Sema::ActOnBlockStart(SourceLocation CaretLoc, Scope *BlockScope) {
+  BlockDecl *Block = BlockDecl::Create(Context, CurContext, CaretLoc);
+  PushBlockScope(BlockScope, Block);
+  CurContext->addDecl(Block);
+  PushDeclContext(BlockScope, Block);
+}
+
+void Sema::ActOnBlockArguments(Declarator &ParamInfo, Scope *CurScope) {
+  assert(ParamInfo.getIdentifier()==0 && "block-id should have no identifier!");
+  BlockScopeInfo *CurBlock = getCurBlock();
+
+  if (ParamInfo.getNumTypeObjects() == 0
+      || ParamInfo.getTypeObject(0).Kind != DeclaratorChunk::Function) {
+    ProcessDeclAttributes(CurScope, CurBlock->TheDecl, ParamInfo);
+    QualType T = GetTypeForDeclarator(ParamInfo, CurScope);
+
+    if (T->isArrayType()) {
+      Diag(ParamInfo.getSourceRange().getBegin(),
+           diag::err_block_returns_array);
+      return;
+    }
+
+    // The parameter list is optional, if there was none, assume ().
+    if (!T->isFunctionType())
+      T = Context.getFunctionType(T, 0, 0, false, 0, false, false, 0, 0,
+                                  FunctionType::ExtInfo());
+
+    CurBlock->hasPrototype = true;
+    CurBlock->isVariadic = false;
+    // Check for a valid sentinel attribute on this block.
+    if (CurBlock->TheDecl->getAttr<SentinelAttr>()) {
+      Diag(ParamInfo.getAttributes()->getLoc(),
+           diag::warn_attribute_sentinel_not_variadic) << 1;
+      // FIXME: remove the attribute.
+    }
+    QualType RetTy = T.getTypePtr()->getAs<FunctionType>()->getResultType();
+
+    // Do not allow returning a objc interface by-value.
+    if (RetTy->isObjCInterfaceType()) {
+      Diag(ParamInfo.getSourceRange().getBegin(),
+           diag::err_object_cannot_be_passed_returned_by_value) << 0 << RetTy;
+      return;
+    }
+
+    CurBlock->ReturnType = RetTy;
+    return;
+  }
+
+  // Analyze arguments to block.
+  assert(ParamInfo.getTypeObject(0).Kind == DeclaratorChunk::Function &&
+         "Not a function declarator!");
+  DeclaratorChunk::FunctionTypeInfo &FTI = ParamInfo.getTypeObject(0).Fun;
+
+  CurBlock->hasPrototype = FTI.hasPrototype;
+  CurBlock->isVariadic = true;
+
+  // Check for C99 6.7.5.3p10 - foo(void) is a non-varargs function that takes
+  // no arguments, not a function that takes a single void argument.
+  if (FTI.hasPrototype &&
+      FTI.NumArgs == 1 && !FTI.isVariadic && FTI.ArgInfo[0].Ident == 0 &&
+     (!FTI.ArgInfo[0].Param.getAs<ParmVarDecl>()->getType().getCVRQualifiers()&&
+        FTI.ArgInfo[0].Param.getAs<ParmVarDecl>()->getType()->isVoidType())) {
+    // empty arg list, don't push any params.
+    CurBlock->isVariadic = false;
+  } else if (FTI.hasPrototype) {
+    for (unsigned i = 0, e = FTI.NumArgs; i != e; ++i) {
+      ParmVarDecl *Param = FTI.ArgInfo[i].Param.getAs<ParmVarDecl>();
+      if (Param->getIdentifier() == 0 &&
+          !Param->isImplicit() &&
+          !Param->isInvalidDecl() &&
+          !getLangOptions().CPlusPlus)
+        Diag(Param->getLocation(), diag::err_parameter_name_omitted);
+      CurBlock->Params.push_back(Param);
+    }
+    CurBlock->isVariadic = FTI.isVariadic;
+  }
+  CurBlock->TheDecl->setParams(CurBlock->Params.data(),
+                               CurBlock->Params.size());
+  CurBlock->TheDecl->setIsVariadic(CurBlock->isVariadic);
+  ProcessDeclAttributes(CurScope, CurBlock->TheDecl, ParamInfo);
+
+  bool ShouldCheckShadow =
+    Diags.getDiagnosticLevel(diag::warn_decl_shadow) != Diagnostic::Ignored;
+
+  for (BlockDecl::param_iterator AI = CurBlock->TheDecl->param_begin(),
+         E = CurBlock->TheDecl->param_end(); AI != E; ++AI) {
+    (*AI)->setOwningFunction(CurBlock->TheDecl);
+
+    // If this has an identifier, add it to the scope stack.
+    if ((*AI)->getIdentifier()) {
+      if (ShouldCheckShadow)
+        CheckShadow(CurBlock->TheScope, *AI);
+
+      PushOnScopeChains(*AI, CurBlock->TheScope);
+    }
+  }
+
+  // Check for a valid sentinel attribute on this block.
+  if (!CurBlock->isVariadic &&
+      CurBlock->TheDecl->getAttr<SentinelAttr>()) {
+    Diag(ParamInfo.getAttributes()->getLoc(),
+         diag::warn_attribute_sentinel_not_variadic) << 1;
+    // FIXME: remove the attribute.
+  }
+
+  // Analyze the return type.
+  QualType T = GetTypeForDeclarator(ParamInfo, CurScope);
+  QualType RetTy = T->getAs<FunctionType>()->getResultType();
+
+  // Do not allow returning a objc interface by-value.
+  if (RetTy->isObjCInterfaceType()) {
+    Diag(ParamInfo.getSourceRange().getBegin(),
+         diag::err_object_cannot_be_passed_returned_by_value) << 0 << RetTy;
+  } else if (!RetTy->isDependentType())
+    CurBlock->ReturnType = RetTy;
+}
+
+/// ActOnBlockError - If there is an error parsing a block, this callback
+/// is invoked to pop the information about the block from the action impl.
+void Sema::ActOnBlockError(SourceLocation CaretLoc, Scope *CurScope) {
+  // Pop off CurBlock, handle nested blocks.
+  PopDeclContext();
+  PopFunctionOrBlockScope();
+  // FIXME: Delete the ParmVarDecl objects as well???
+}
+
+/// ActOnBlockStmtExpr - This is called when the body of a block statement
+/// literal was successfully completed.  ^(int x){...}
+Sema::OwningExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc,
+                                                StmtArg body, Scope *CurScope) {
+  // If blocks are disabled, emit an error.
+  if (!LangOpts.Blocks)
+    Diag(CaretLoc, diag::err_blocks_disable);
+
+  BlockScopeInfo *BSI = cast<BlockScopeInfo>(FunctionScopes.back());
+
+  PopDeclContext();
+
+  QualType RetTy = Context.VoidTy;
+  if (!BSI->ReturnType.isNull())
+    RetTy = BSI->ReturnType;
+
+  llvm::SmallVector<QualType, 8> ArgTypes;
+  for (unsigned i = 0, e = BSI->Params.size(); i != e; ++i)
+    ArgTypes.push_back(BSI->Params[i]->getType());
+
+  bool NoReturn = BSI->TheDecl->getAttr<NoReturnAttr>();
+  QualType BlockTy;
+  if (!BSI->hasPrototype)
+    BlockTy = Context.getFunctionType(RetTy, 0, 0, false, 0, false, false, 0, 0,
+                                FunctionType::ExtInfo(NoReturn, 0, CC_Default));
+  else
+    BlockTy = Context.getFunctionType(RetTy, ArgTypes.data(), ArgTypes.size(),
+                                      BSI->isVariadic, 0, false, false, 0, 0,
+                                FunctionType::ExtInfo(NoReturn, 0, CC_Default));
+
+  // FIXME: Check that return/parameter types are complete/non-abstract
+  DiagnoseUnusedParameters(BSI->Params.begin(), BSI->Params.end());
+  BlockTy = Context.getBlockPointerType(BlockTy);
+
+  // If needed, diagnose invalid gotos and switches in the block.
+  if (FunctionNeedsScopeChecking() && !hasAnyErrorsInThisFunction())
+    DiagnoseInvalidJumps(static_cast<CompoundStmt*>(body.get()));
+
+  BSI->TheDecl->setBody(body.takeAs<CompoundStmt>());
+
+  bool Good = true;
+  // Check goto/label use.
+  for (llvm::DenseMap<IdentifierInfo*, LabelStmt*>::iterator
+         I = BSI->LabelMap.begin(), E = BSI->LabelMap.end(); I != E; ++I) {
+    LabelStmt *L = I->second;
+
+    // Verify that we have no forward references left.  If so, there was a goto
+    // or address of a label taken, but no definition of it.
+    if (L->getSubStmt() != 0)
+      continue;
+
+    // Emit error.
+    Diag(L->getIdentLoc(), diag::err_undeclared_label_use) << L->getName();
+    Good = false;
+  }
+  if (!Good) {
+    PopFunctionOrBlockScope();
+    return ExprError();
+  }
+
+  // Issue any analysis-based warnings.
+  const sema::AnalysisBasedWarnings::Policy &WP =
+    AnalysisWarnings.getDefaultPolicy();
+  AnalysisWarnings.IssueWarnings(WP, BSI->TheDecl, BlockTy);
+
+  Expr *Result = new (Context) BlockExpr(BSI->TheDecl, BlockTy,
+                                         BSI->hasBlockDeclRefExprs);
+  PopFunctionOrBlockScope();
+  return Owned(Result);
+}
+
+Sema::OwningExprResult Sema::ActOnVAArg(SourceLocation BuiltinLoc,
+                                        ExprArg expr, TypeTy *type,
+                                        SourceLocation RPLoc) {
+  QualType T = GetTypeFromParser(type);
+  Expr *E = static_cast<Expr*>(expr.get());
+  Expr *OrigExpr = E;
+
+  InitBuiltinVaListType();
+
+  // Get the va_list type
+  QualType VaListType = Context.getBuiltinVaListType();
+  if (VaListType->isArrayType()) {
+    // Deal with implicit array decay; for example, on x86-64,
+    // va_list is an array, but it's supposed to decay to
+    // a pointer for va_arg.
+    VaListType = Context.getArrayDecayedType(VaListType);
+    // Make sure the input expression also decays appropriately.
+    UsualUnaryConversions(E);
+  } else {
+    // Otherwise, the va_list argument must be an l-value because
+    // it is modified by va_arg.
+    if (!E->isTypeDependent() &&
+        CheckForModifiableLvalue(E, BuiltinLoc, *this))
+      return ExprError();
+  }
+
+  if (!E->isTypeDependent() &&
+      !Context.hasSameType(VaListType, E->getType())) {
+    return ExprError(Diag(E->getLocStart(),
+                         diag::err_first_argument_to_va_arg_not_of_type_va_list)
+      << OrigExpr->getType() << E->getSourceRange());
+  }
+
+  // FIXME: Check that type is complete/non-abstract
+  // FIXME: Warn if a non-POD type is passed in.
+
+  expr.release();
+  return Owned(new (Context) VAArgExpr(BuiltinLoc, E, T.getNonReferenceType(),
+                                       RPLoc));
+}
+
+Sema::OwningExprResult Sema::ActOnGNUNullExpr(SourceLocation TokenLoc) {
+  // The type of __null will be int or long, depending on the size of
+  // pointers on the target.
+  QualType Ty;
+  if (Context.Target.getPointerWidth(0) == Context.Target.getIntWidth())
+    Ty = Context.IntTy;
+  else
+    Ty = Context.LongTy;
+
+  return Owned(new (Context) GNUNullExpr(Ty, TokenLoc));
+}
+
+static void MakeObjCStringLiteralFixItHint(Sema& SemaRef, QualType DstType, 
+                                           Expr *SrcExpr, FixItHint &Hint) {
+  if (!SemaRef.getLangOptions().ObjC1)
+    return;
+
+  const ObjCObjectPointerType *PT = DstType->getAs<ObjCObjectPointerType>();
+  if (!PT)
+    return;
+
+  // Check if the destination is of type 'id'.
+  if (!PT->isObjCIdType()) {
+    // Check if the destination is the 'NSString' interface.
+    const ObjCInterfaceDecl *ID = PT->getInterfaceDecl();
+    if (!ID || !ID->getIdentifier()->isStr("NSString"))
+      return;
+  }
+
+  // Strip off any parens and casts.
+  StringLiteral *SL = dyn_cast<StringLiteral>(SrcExpr->IgnoreParenCasts());
+  if (!SL || SL->isWide())
+    return;
+
+  Hint = FixItHint::CreateInsertion(SL->getLocStart(), "@");
+}
+
+bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
+                                    SourceLocation Loc,
+                                    QualType DstType, QualType SrcType,
+                                    Expr *SrcExpr, AssignmentAction Action,
+                                    bool *Complained) {
+  if (Complained)
+    *Complained = false;
+
+  // Decode the result (notice that AST's are still created for extensions).
+  bool isInvalid = false;
+  unsigned DiagKind;
+  FixItHint Hint;
+
+  switch (ConvTy) {
+  default: assert(0 && "Unknown conversion type");
+  case Compatible: return false;
+  case PointerToInt:
+    DiagKind = diag::ext_typecheck_convert_pointer_int;
+    break;
+  case IntToPointer:
+    DiagKind = diag::ext_typecheck_convert_int_pointer;
+    break;
+  case IncompatiblePointer:
+    MakeObjCStringLiteralFixItHint(*this, DstType, SrcExpr, Hint);
+    DiagKind = diag::ext_typecheck_convert_incompatible_pointer;
+    break;
+  case IncompatiblePointerSign:
+    DiagKind = diag::ext_typecheck_convert_incompatible_pointer_sign;
+    break;
+  case FunctionVoidPointer:
+    DiagKind = diag::ext_typecheck_convert_pointer_void_func;
+    break;
+  case CompatiblePointerDiscardsQualifiers:
+    // If the qualifiers lost were because we were applying the
+    // (deprecated) C++ conversion from a string literal to a char*
+    // (or wchar_t*), then there was no error (C++ 4.2p2).  FIXME:
+    // Ideally, this check would be performed in
+    // CheckPointerTypesForAssignment. However, that would require a
+    // bit of refactoring (so that the second argument is an
+    // expression, rather than a type), which should be done as part
+    // of a larger effort to fix CheckPointerTypesForAssignment for
+    // C++ semantics.
+    if (getLangOptions().CPlusPlus &&
+        IsStringLiteralToNonConstPointerConversion(SrcExpr, DstType))
+      return false;
+    DiagKind = diag::ext_typecheck_convert_discards_qualifiers;
+    break;
+  case IncompatibleNestedPointerQualifiers:
+    DiagKind = diag::ext_nested_pointer_qualifier_mismatch;
+    break;
+  case IntToBlockPointer:
+    DiagKind = diag::err_int_to_block_pointer;
+    break;
+  case IncompatibleBlockPointer:
+    DiagKind = diag::err_typecheck_convert_incompatible_block_pointer;
+    break;
+  case IncompatibleObjCQualifiedId:
+    // FIXME: Diagnose the problem in ObjCQualifiedIdTypesAreCompatible, since
+    // it can give a more specific diagnostic.
+    DiagKind = diag::warn_incompatible_qualified_id;
+    break;
+  case IncompatibleVectors:
+    DiagKind = diag::warn_incompatible_vectors;
+    break;
+  case Incompatible:
+    DiagKind = diag::err_typecheck_convert_incompatible;
+    isInvalid = true;
+    break;
+  }
+
+  QualType FirstType, SecondType;
+  switch (Action) {
+  case AA_Assigning:
+  case AA_Initializing:
+    // The destination type comes first.
+    FirstType = DstType;
+    SecondType = SrcType;
+    break;
+      
+  case AA_Returning:
+  case AA_Passing:
+  case AA_Converting:
+  case AA_Sending:
+  case AA_Casting:
+    // The source type comes first.
+    FirstType = SrcType;
+    SecondType = DstType;
+    break;
+  }
+  
+  Diag(Loc, DiagKind) << FirstType << SecondType << Action
+    << SrcExpr->getSourceRange() << Hint;
+  if (Complained)
+    *Complained = true;
+  return isInvalid;
+}
+
+bool Sema::VerifyIntegerConstantExpression(const Expr *E, llvm::APSInt *Result){
+  llvm::APSInt ICEResult;
+  if (E->isIntegerConstantExpr(ICEResult, Context)) {
+    if (Result)
+      *Result = ICEResult;
+    return false;
+  }
+
+  Expr::EvalResult EvalResult;
+
+  if (!E->Evaluate(EvalResult, Context) || !EvalResult.Val.isInt() ||
+      EvalResult.HasSideEffects) {
+    Diag(E->getExprLoc(), diag::err_expr_not_ice) << E->getSourceRange();
+
+    if (EvalResult.Diag) {
+      // We only show the note if it's not the usual "invalid subexpression"
+      // or if it's actually in a subexpression.
+      if (EvalResult.Diag != diag::note_invalid_subexpr_in_ice ||
+          E->IgnoreParens() != EvalResult.DiagExpr->IgnoreParens())
+        Diag(EvalResult.DiagLoc, EvalResult.Diag);
+    }
+
+    return true;
+  }
+
+  Diag(E->getExprLoc(), diag::ext_expr_not_ice) <<
+    E->getSourceRange();
+
+  if (EvalResult.Diag &&
+      Diags.getDiagnosticLevel(diag::ext_expr_not_ice) != Diagnostic::Ignored)
+    Diag(EvalResult.DiagLoc, EvalResult.Diag);
+
+  if (Result)
+    *Result = EvalResult.Val.getInt();
+  return false;
+}
+
+void
+Sema::PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext) {
+  ExprEvalContexts.push_back(
+        ExpressionEvaluationContextRecord(NewContext, ExprTemporaries.size()));
+}
+
+void
+Sema::PopExpressionEvaluationContext() {
+  // Pop the current expression evaluation context off the stack.
+  ExpressionEvaluationContextRecord Rec = ExprEvalContexts.back();
+  ExprEvalContexts.pop_back();
+
+  if (Rec.Context == PotentiallyPotentiallyEvaluated) {
+    if (Rec.PotentiallyReferenced) {
+      // Mark any remaining declarations in the current position of the stack
+      // as "referenced". If they were not meant to be referenced, semantic
+      // analysis would have eliminated them (e.g., in ActOnCXXTypeId).
+      for (PotentiallyReferencedDecls::iterator
+             I = Rec.PotentiallyReferenced->begin(),
+             IEnd = Rec.PotentiallyReferenced->end();
+           I != IEnd; ++I)
+        MarkDeclarationReferenced(I->first, I->second);
+    }
+
+    if (Rec.PotentiallyDiagnosed) {
+      // Emit any pending diagnostics.
+      for (PotentiallyEmittedDiagnostics::iterator
+                I = Rec.PotentiallyDiagnosed->begin(),
+             IEnd = Rec.PotentiallyDiagnosed->end();
+           I != IEnd; ++I)
+        Diag(I->first, I->second);
+    }
+  }
+
+  // When are coming out of an unevaluated context, clear out any
+  // temporaries that we may have created as part of the evaluation of
+  // the expression in that context: they aren't relevant because they
+  // will never be constructed.
+  if (Rec.Context == Unevaluated &&
+      ExprTemporaries.size() > Rec.NumTemporaries)
+    ExprTemporaries.erase(ExprTemporaries.begin() + Rec.NumTemporaries,
+                          ExprTemporaries.end());
+
+  // Destroy the popped expression evaluation record.
+  Rec.Destroy();
+}
+
+/// \brief Note that the given declaration was referenced in the source code.
+///
+/// This routine should be invoke whenever a given declaration is referenced
+/// in the source code, and where that reference occurred. If this declaration
+/// reference means that the the declaration is used (C++ [basic.def.odr]p2,
+/// C99 6.9p3), then the declaration will be marked as used.
+///
+/// \param Loc the location where the declaration was referenced.
+///
+/// \param D the declaration that has been referenced by the source code.
+void Sema::MarkDeclarationReferenced(SourceLocation Loc, Decl *D) {
+  assert(D && "No declaration?");
+
+  if (D->isUsed())
+    return;
+
+  // Mark a parameter or variable declaration "used", regardless of whether we're in a
+  // template or not. The reason for this is that unevaluated expressions
+  // (e.g. (void)sizeof()) constitute a use for warning purposes (-Wunused-variables and
+  // -Wunused-parameters)
+  if (isa<ParmVarDecl>(D) ||
+      (isa<VarDecl>(D) && D->getDeclContext()->isFunctionOrMethod())) {
+    D->setUsed(true);
+    return;
+  }
+  
+  if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D))
+    return;
+  
+  // Do not mark anything as "used" within a dependent context; wait for
+  // an instantiation.
+  if (CurContext->isDependentContext())
+    return;
+
+  switch (ExprEvalContexts.back().Context) {
+    case Unevaluated:
+      // We are in an expression that is not potentially evaluated; do nothing.
+      return;
+
+    case PotentiallyEvaluated:
+      // We are in a potentially-evaluated expression, so this declaration is
+      // "used"; handle this below.
+      break;
+
+    case PotentiallyPotentiallyEvaluated:
+      // We are in an expression that may be potentially evaluated; queue this
+      // declaration reference until we know whether the expression is
+      // potentially evaluated.
+      ExprEvalContexts.back().addReferencedDecl(Loc, D);
+      return;
+  }
+
+  // Note that this declaration has been used.
+  if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(D)) {
+    unsigned TypeQuals;
+    if (Constructor->isImplicit() && Constructor->isDefaultConstructor()) {
+        if (!Constructor->isUsed())
+          DefineImplicitDefaultConstructor(Loc, Constructor);
+    } else if (Constructor->isImplicit() &&
+               Constructor->isCopyConstructor(TypeQuals)) {
+      if (!Constructor->isUsed())
+        DefineImplicitCopyConstructor(Loc, Constructor, TypeQuals);
+    }
+
+    MaybeMarkVirtualMembersReferenced(Loc, Constructor);
+  } else if (CXXDestructorDecl *Destructor = dyn_cast<CXXDestructorDecl>(D)) {
+    if (Destructor->isImplicit() && !Destructor->isUsed())
+      DefineImplicitDestructor(Loc, Destructor);
+
+  } else if (CXXMethodDecl *MethodDecl = dyn_cast<CXXMethodDecl>(D)) {
+    if (MethodDecl->isImplicit() && MethodDecl->isOverloadedOperator() &&
+        MethodDecl->getOverloadedOperator() == OO_Equal) {
+      if (!MethodDecl->isUsed())
+        DefineImplicitOverloadedAssign(Loc, MethodDecl);
+    }
+  }
+  if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
+    // Implicit instantiation of function templates and member functions of
+    // class templates.
+    if (!Function->getBody() && Function->isImplicitlyInstantiable()) {
+      bool AlreadyInstantiated = false;
+      if (FunctionTemplateSpecializationInfo *SpecInfo
+                                = Function->getTemplateSpecializationInfo()) {
+        if (SpecInfo->getPointOfInstantiation().isInvalid())
+          SpecInfo->setPointOfInstantiation(Loc);
+        else if (SpecInfo->getTemplateSpecializationKind()
+                   == TSK_ImplicitInstantiation)
+          AlreadyInstantiated = true;
+      } else if (MemberSpecializationInfo *MSInfo
+                                  = Function->getMemberSpecializationInfo()) {
+        if (MSInfo->getPointOfInstantiation().isInvalid())
+          MSInfo->setPointOfInstantiation(Loc);
+        else if (MSInfo->getTemplateSpecializationKind()
+                   == TSK_ImplicitInstantiation)
+          AlreadyInstantiated = true;
+      }
+
+      if (!AlreadyInstantiated) {
+        if (isa<CXXRecordDecl>(Function->getDeclContext()) &&
+            cast<CXXRecordDecl>(Function->getDeclContext())->isLocalClass())
+          PendingLocalImplicitInstantiations.push_back(std::make_pair(Function,
+                                                                      Loc));
+        else
+          PendingImplicitInstantiations.push_back(std::make_pair(Function,
+                                                                 Loc));
+      }
+    }
+
+    // FIXME: keep track of references to static functions
+    Function->setUsed(true);
+
+    return;
+  }
+
+  if (VarDecl *Var = dyn_cast<VarDecl>(D)) {
+    // Implicit instantiation of static data members of class templates.
+    if (Var->isStaticDataMember() &&
+        Var->getInstantiatedFromStaticDataMember()) {
+      MemberSpecializationInfo *MSInfo = Var->getMemberSpecializationInfo();
+      assert(MSInfo && "Missing member specialization information?");
+      if (MSInfo->getPointOfInstantiation().isInvalid() &&
+          MSInfo->getTemplateSpecializationKind()== TSK_ImplicitInstantiation) {
+        MSInfo->setPointOfInstantiation(Loc);
+        PendingImplicitInstantiations.push_back(std::make_pair(Var, Loc));
+      }
+    }
+
+    // FIXME: keep track of references to static data?
+
+    D->setUsed(true);
+    return;
+  }
+}
+
+/// \brief Emit a diagnostic that describes an effect on the run-time behavior
+/// of the program being compiled.
+///
+/// This routine emits the given diagnostic when the code currently being
+/// type-checked is "potentially evaluated", meaning that there is a
+/// possibility that the code will actually be executable. Code in sizeof()
+/// expressions, code used only during overload resolution, etc., are not
+/// potentially evaluated. This routine will suppress such diagnostics or,
+/// in the absolutely nutty case of potentially potentially evaluated
+/// expressions (C++ typeid), queue the diagnostic to potentially emit it
+/// later.
+///
+/// This routine should be used for all diagnostics that describe the run-time
+/// behavior of a program, such as passing a non-POD value through an ellipsis.
+/// Failure to do so will likely result in spurious diagnostics or failures
+/// during overload resolution or within sizeof/alignof/typeof/typeid.
+bool Sema::DiagRuntimeBehavior(SourceLocation Loc,
+                               const PartialDiagnostic &PD) {
+  switch (ExprEvalContexts.back().Context ) {
+  case Unevaluated:
+    // The argument will never be evaluated, so don't complain.
+    break;
+
+  case PotentiallyEvaluated:
+    Diag(Loc, PD);
+    return true;
+
+  case PotentiallyPotentiallyEvaluated:
+    ExprEvalContexts.back().addDiagnostic(Loc, PD);
+    break;
+  }
+
+  return false;
+}
+
+bool Sema::CheckCallReturnType(QualType ReturnType, SourceLocation Loc,
+                               CallExpr *CE, FunctionDecl *FD) {
+  if (ReturnType->isVoidType() || !ReturnType->isIncompleteType())
+    return false;
+
+  PartialDiagnostic Note =
+    FD ? PDiag(diag::note_function_with_incomplete_return_type_declared_here)
+    << FD->getDeclName() : PDiag();
+  SourceLocation NoteLoc = FD ? FD->getLocation() : SourceLocation();
+
+  if (RequireCompleteType(Loc, ReturnType,
+                          FD ?
+                          PDiag(diag::err_call_function_incomplete_return)
+                            << CE->getSourceRange() << FD->getDeclName() :
+                          PDiag(diag::err_call_incomplete_return)
+                            << CE->getSourceRange(),
+                          std::make_pair(NoteLoc, Note)))
+    return true;
+
+  return false;
+}
+
+// Diagnose the common s/=/==/ typo.  Note that adding parentheses
+// will prevent this condition from triggering, which is what we want.
+void Sema::DiagnoseAssignmentAsCondition(Expr *E) {
+  SourceLocation Loc;
+
+  unsigned diagnostic = diag::warn_condition_is_assignment;
+
+  if (isa<BinaryOperator>(E)) {
+    BinaryOperator *Op = cast<BinaryOperator>(E);
+    if (Op->getOpcode() != BinaryOperator::Assign)
+      return;
+
+    // Greylist some idioms by putting them into a warning subcategory.
+    if (ObjCMessageExpr *ME
+          = dyn_cast<ObjCMessageExpr>(Op->getRHS()->IgnoreParenCasts())) {
+      Selector Sel = ME->getSelector();
+
+      // self = [<foo> init...]
+      if (isSelfExpr(Op->getLHS())
+          && Sel.getIdentifierInfoForSlot(0)->getName().startswith("init"))
+        diagnostic = diag::warn_condition_is_idiomatic_assignment;
+
+      // <foo> = [<bar> nextObject]
+      else if (Sel.isUnarySelector() &&
+               Sel.getIdentifierInfoForSlot(0)->getName() == "nextObject")
+        diagnostic = diag::warn_condition_is_idiomatic_assignment;
+    }
+
+    Loc = Op->getOperatorLoc();
+  } else if (isa<CXXOperatorCallExpr>(E)) {
+    CXXOperatorCallExpr *Op = cast<CXXOperatorCallExpr>(E);
+    if (Op->getOperator() != OO_Equal)
+      return;
+
+    Loc = Op->getOperatorLoc();
+  } else {
+    // Not an assignment.
+    return;
+  }
+
+  SourceLocation Open = E->getSourceRange().getBegin();
+  SourceLocation Close = PP.getLocForEndOfToken(E->getSourceRange().getEnd());
+
+  Diag(Loc, diagnostic) << E->getSourceRange();
+  Diag(Loc, diag::note_condition_assign_to_comparison)
+    << FixItHint::CreateReplacement(Loc, "==");
+  Diag(Loc, diag::note_condition_assign_silence)
+    << FixItHint::CreateInsertion(Open, "(")
+    << FixItHint::CreateInsertion(Close, ")");
+}
+
+bool Sema::CheckBooleanCondition(Expr *&E, SourceLocation Loc) {
+  DiagnoseAssignmentAsCondition(E);
+
+  if (!E->isTypeDependent()) {
+    DefaultFunctionArrayLvalueConversion(E);
+
+    QualType T = E->getType();
+
+    if (getLangOptions().CPlusPlus) {
+      if (CheckCXXBooleanCondition(E)) // C++ 6.4p4
+        return true;
+    } else if (!T->isScalarType()) { // C99 6.8.4.1p1
+      Diag(Loc, diag::err_typecheck_statement_requires_scalar)
+        << T << E->getSourceRange();
+      return true;
+    }
+  }
+
+  return false;
+}
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
new file mode 100644
index 0000000..7c32423
--- /dev/null
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -0,0 +1,2943 @@
+//===--- SemaExprCXX.cpp - Semantic Analysis for Expressions --------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements semantic analysis for C++ expressions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Sema.h"
+#include "SemaInit.h"
+#include "Lookup.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/CXXInheritance.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/TypeLoc.h"
+#include "clang/Basic/PartialDiagnostic.h"
+#include "clang/Basic/TargetInfo.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Parse/DeclSpec.h"
+#include "clang/Parse/Template.h"
+#include "llvm/ADT/STLExtras.h"
+using namespace clang;
+
+Action::TypeTy *Sema::getDestructorName(SourceLocation TildeLoc,
+                                        IdentifierInfo &II, 
+                                        SourceLocation NameLoc,
+                                        Scope *S, CXXScopeSpec &SS,
+                                        TypeTy *ObjectTypePtr,
+                                        bool EnteringContext) {
+  // Determine where to perform name lookup.
+
+  // FIXME: This area of the standard is very messy, and the current
+  // wording is rather unclear about which scopes we search for the
+  // destructor name; see core issues 399 and 555. Issue 399 in
+  // particular shows where the current description of destructor name
+  // lookup is completely out of line with existing practice, e.g.,
+  // this appears to be ill-formed:
+  //
+  //   namespace N {
+  //     template <typename T> struct S {
+  //       ~S();
+  //     };
+  //   }
+  //
+  //   void f(N::S<int>* s) {
+  //     s->N::S<int>::~S();
+  //   }
+  //
+  // See also PR6358 and PR6359.
+  QualType SearchType;
+  DeclContext *LookupCtx = 0;
+  bool isDependent = false;
+  bool LookInScope = false;
+
+  // If we have an object type, it's because we are in a
+  // pseudo-destructor-expression or a member access expression, and
+  // we know what type we're looking for.
+  if (ObjectTypePtr)
+    SearchType = GetTypeFromParser(ObjectTypePtr);
+
+  if (SS.isSet()) {
+    NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
+    
+    bool AlreadySearched = false;
+    bool LookAtPrefix = true;
+    if (!getLangOptions().CPlusPlus0x) {
+      // C++ [basic.lookup.qual]p6:
+      //   If a pseudo-destructor-name (5.2.4) contains a nested-name-specifier, 
+      //   the type-names are looked up as types in the scope designated by the
+      //   nested-name-specifier. In a qualified-id of the form:
+      // 
+      //     ::[opt] nested-name-specifier  ̃ class-name 
+      //
+      //   where the nested-name-specifier designates a namespace scope, and in
+      //   a qualified-id of the form:
+      //
+      //     ::opt nested-name-specifier class-name ::  ̃ class-name 
+      //
+      //   the class-names are looked up as types in the scope designated by 
+      //   the nested-name-specifier.
+      //
+      // Here, we check the first case (completely) and determine whether the
+      // code below is permitted to look at the prefix of the 
+      // nested-name-specifier (as we do in C++0x).
+      DeclContext *DC = computeDeclContext(SS, EnteringContext);
+      if (DC && DC->isFileContext()) {
+        AlreadySearched = true;
+        LookupCtx = DC;
+        isDependent = false;
+      } else if (DC && isa<CXXRecordDecl>(DC))
+        LookAtPrefix = false;
+    }
+    
+    // C++0x [basic.lookup.qual]p6:
+    //   If a pseudo-destructor-name (5.2.4) contains a
+    //   nested-name-specifier, the type-names are looked up as types
+    //   in the scope designated by the nested-name-specifier. Similarly, in 
+    //   a qualified-id of the form:
+    //
+    //     :: [opt] nested-name-specifier[opt] class-name :: ~class-name 
+    //
+    //   the second class-name is looked up in the same scope as the first.
+    //
+    // To implement this, we look at the prefix of the
+    // nested-name-specifier we were given, and determine the lookup
+    // context from that.
+    //
+    // We also fold in the second case from the C++03 rules quoted further 
+    // above.
+    NestedNameSpecifier *Prefix = 0;
+    if (AlreadySearched) {
+      // Nothing left to do.
+    } else if (LookAtPrefix && (Prefix = NNS->getPrefix())) {
+      CXXScopeSpec PrefixSS;
+      PrefixSS.setScopeRep(Prefix);
+      LookupCtx = computeDeclContext(PrefixSS, EnteringContext);
+      isDependent = isDependentScopeSpecifier(PrefixSS);
+    } else if (getLangOptions().CPlusPlus0x &&
+               (LookupCtx = computeDeclContext(SS, EnteringContext))) {
+      if (!LookupCtx->isTranslationUnit())
+        LookupCtx = LookupCtx->getParent();
+      isDependent = LookupCtx && LookupCtx->isDependentContext();
+    } else if (ObjectTypePtr) {
+      LookupCtx = computeDeclContext(SearchType);
+      isDependent = SearchType->isDependentType();
+    } else {
+      LookupCtx = computeDeclContext(SS, EnteringContext);
+      isDependent = LookupCtx && LookupCtx->isDependentContext();
+    }
+    
+    LookInScope = false;
+  } else if (ObjectTypePtr) {
+    // C++ [basic.lookup.classref]p3:
+    //   If the unqualified-id is ~type-name, the type-name is looked up
+    //   in the context of the entire postfix-expression. If the type T
+    //   of the object expression is of a class type C, the type-name is
+    //   also looked up in the scope of class C. At least one of the
+    //   lookups shall find a name that refers to (possibly
+    //   cv-qualified) T.
+    LookupCtx = computeDeclContext(SearchType);
+    isDependent = SearchType->isDependentType();
+    assert((isDependent || !SearchType->isIncompleteType()) && 
+           "Caller should have completed object type");
+
+    LookInScope = true;
+  } else {
+    // Perform lookup into the current scope (only).
+    LookInScope = true;
+  }
+
+  LookupResult Found(*this, &II, NameLoc, LookupOrdinaryName);
+  for (unsigned Step = 0; Step != 2; ++Step) {
+    // Look for the name first in the computed lookup context (if we
+    // have one) and, if that fails to find a match, in the sope (if
+    // we're allowed to look there).
+    Found.clear();
+    if (Step == 0 && LookupCtx)
+      LookupQualifiedName(Found, LookupCtx);
+    else if (Step == 1 && LookInScope && S)
+      LookupName(Found, S);
+    else
+      continue;
+
+    // FIXME: Should we be suppressing ambiguities here?
+    if (Found.isAmbiguous())
+      return 0;
+
+    if (TypeDecl *Type = Found.getAsSingle<TypeDecl>()) {
+      QualType T = Context.getTypeDeclType(Type);
+
+      if (SearchType.isNull() || SearchType->isDependentType() ||
+          Context.hasSameUnqualifiedType(T, SearchType)) {
+        // We found our type!
+
+        return T.getAsOpaquePtr();
+      }
+    }
+
+    // If the name that we found is a class template name, and it is
+    // the same name as the template name in the last part of the
+    // nested-name-specifier (if present) or the object type, then
+    // this is the destructor for that class.
+    // FIXME: This is a workaround until we get real drafting for core
+    // issue 399, for which there isn't even an obvious direction. 
+    if (ClassTemplateDecl *Template = Found.getAsSingle<ClassTemplateDecl>()) {
+      QualType MemberOfType;
+      if (SS.isSet()) {
+        if (DeclContext *Ctx = computeDeclContext(SS, EnteringContext)) {
+          // Figure out the type of the context, if it has one.
+          if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(Ctx))
+            MemberOfType = Context.getTypeDeclType(Record);
+        }
+      }
+      if (MemberOfType.isNull())
+        MemberOfType = SearchType;
+      
+      if (MemberOfType.isNull())
+        continue;
+
+      // We're referring into a class template specialization. If the
+      // class template we found is the same as the template being
+      // specialized, we found what we are looking for.
+      if (const RecordType *Record = MemberOfType->getAs<RecordType>()) {
+        if (ClassTemplateSpecializationDecl *Spec
+              = dyn_cast<ClassTemplateSpecializationDecl>(Record->getDecl())) {
+          if (Spec->getSpecializedTemplate()->getCanonicalDecl() ==
+                Template->getCanonicalDecl())
+            return MemberOfType.getAsOpaquePtr();
+        }
+
+        continue;
+      }
+      
+      // We're referring to an unresolved class template
+      // specialization. Determine whether we class template we found
+      // is the same as the template being specialized or, if we don't
+      // know which template is being specialized, that it at least
+      // has the same name.
+      if (const TemplateSpecializationType *SpecType
+            = MemberOfType->getAs<TemplateSpecializationType>()) {
+        TemplateName SpecName = SpecType->getTemplateName();
+
+        // The class template we found is the same template being
+        // specialized.
+        if (TemplateDecl *SpecTemplate = SpecName.getAsTemplateDecl()) {
+          if (SpecTemplate->getCanonicalDecl() == Template->getCanonicalDecl())
+            return MemberOfType.getAsOpaquePtr();
+
+          continue;
+        }
+
+        // The class template we found has the same name as the
+        // (dependent) template name being specialized.
+        if (DependentTemplateName *DepTemplate 
+                                    = SpecName.getAsDependentTemplateName()) {
+          if (DepTemplate->isIdentifier() &&
+              DepTemplate->getIdentifier() == Template->getIdentifier())
+            return MemberOfType.getAsOpaquePtr();
+
+          continue;
+        }
+      }
+    }
+  }
+
+  if (isDependent) {
+    // We didn't find our type, but that's okay: it's dependent
+    // anyway.
+    NestedNameSpecifier *NNS = 0;
+    SourceRange Range;
+    if (SS.isSet()) {
+      NNS = (NestedNameSpecifier *)SS.getScopeRep();
+      Range = SourceRange(SS.getRange().getBegin(), NameLoc);
+    } else {
+      NNS = NestedNameSpecifier::Create(Context, &II);
+      Range = SourceRange(NameLoc);
+    }
+
+    return CheckTypenameType(ETK_None, NNS, II, Range).getAsOpaquePtr();
+  }
+
+  if (ObjectTypePtr)
+    Diag(NameLoc, diag::err_ident_in_pseudo_dtor_not_a_type)
+      << &II;        
+  else
+    Diag(NameLoc, diag::err_destructor_class_name);
+
+  return 0;
+}
+
+/// \brief Build a C++ typeid expression with a type operand.
+Sema::OwningExprResult Sema::BuildCXXTypeId(QualType TypeInfoType,
+                                            SourceLocation TypeidLoc,
+                                            TypeSourceInfo *Operand,
+                                            SourceLocation RParenLoc) {
+  // C++ [expr.typeid]p4:
+  //   The top-level cv-qualifiers of the lvalue expression or the type-id 
+  //   that is the operand of typeid are always ignored.
+  //   If the type of the type-id is a class type or a reference to a class 
+  //   type, the class shall be completely-defined.
+  QualType T = Operand->getType().getNonReferenceType();
+  if (T->getAs<RecordType>() &&
+      RequireCompleteType(TypeidLoc, T, diag::err_incomplete_typeid))
+    return ExprError();
+  
+  return Owned(new (Context) CXXTypeidExpr(TypeInfoType.withConst(),
+                                           Operand,
+                                           SourceRange(TypeidLoc, RParenLoc)));
+}
+
+/// \brief Build a C++ typeid expression with an expression operand.
+Sema::OwningExprResult Sema::BuildCXXTypeId(QualType TypeInfoType,
+                                            SourceLocation TypeidLoc,
+                                            ExprArg Operand,
+                                            SourceLocation RParenLoc) {
+  bool isUnevaluatedOperand = true;
+  Expr *E = static_cast<Expr *>(Operand.get());
+  if (E && !E->isTypeDependent()) {
+    QualType T = E->getType();
+    if (const RecordType *RecordT = T->getAs<RecordType>()) {
+      CXXRecordDecl *RecordD = cast<CXXRecordDecl>(RecordT->getDecl());
+      // C++ [expr.typeid]p3:
+      //   [...] If the type of the expression is a class type, the class
+      //   shall be completely-defined.
+      if (RequireCompleteType(TypeidLoc, T, diag::err_incomplete_typeid))
+        return ExprError();
+      
+      // C++ [expr.typeid]p3:
+      //   When typeid is applied to an expression other than an lvalue of a
+      //   polymorphic class type [...] [the] expression is an unevaluated
+      //   operand. [...]
+      if (RecordD->isPolymorphic() && E->isLvalue(Context) == Expr::LV_Valid)
+        isUnevaluatedOperand = false;
+    }
+    
+    // C++ [expr.typeid]p4:
+    //   [...] If the type of the type-id is a reference to a possibly
+    //   cv-qualified type, the result of the typeid expression refers to a 
+    //   std::type_info object representing the cv-unqualified referenced 
+    //   type.
+    if (T.hasQualifiers()) {
+      ImpCastExprToType(E, T.getUnqualifiedType(), CastExpr::CK_NoOp,
+                        E->isLvalue(Context));
+      Operand.release();
+      Operand = Owned(E);
+    }
+  }
+  
+  // If this is an unevaluated operand, clear out the set of
+  // declaration references we have been computing and eliminate any
+  // temporaries introduced in its computation.
+  if (isUnevaluatedOperand)
+    ExprEvalContexts.back().Context = Unevaluated;
+  
+  return Owned(new (Context) CXXTypeidExpr(TypeInfoType.withConst(),
+                                           Operand.takeAs<Expr>(),
+                                           SourceRange(TypeidLoc, RParenLoc)));  
+}
+
+/// ActOnCXXTypeidOfType - Parse typeid( type-id ) or typeid (expression);
+Action::OwningExprResult
+Sema::ActOnCXXTypeid(SourceLocation OpLoc, SourceLocation LParenLoc,
+                     bool isType, void *TyOrExpr, SourceLocation RParenLoc) {
+  // Find the std::type_info type.
+  if (!StdNamespace)
+    return ExprError(Diag(OpLoc, diag::err_need_header_before_typeid));
+
+  IdentifierInfo *TypeInfoII = &PP.getIdentifierTable().get("type_info");
+  LookupResult R(*this, TypeInfoII, SourceLocation(), LookupTagName);
+  LookupQualifiedName(R, StdNamespace);
+  RecordDecl *TypeInfoRecordDecl = R.getAsSingle<RecordDecl>();
+  if (!TypeInfoRecordDecl)
+    return ExprError(Diag(OpLoc, diag::err_need_header_before_typeid));
+  
+  QualType TypeInfoType = Context.getTypeDeclType(TypeInfoRecordDecl);
+  
+  if (isType) {
+    // The operand is a type; handle it as such.
+    TypeSourceInfo *TInfo = 0;
+    QualType T = GetTypeFromParser(TyOrExpr, &TInfo);
+    if (T.isNull())
+      return ExprError();
+    
+    if (!TInfo)
+      TInfo = Context.getTrivialTypeSourceInfo(T, OpLoc);
+
+    return BuildCXXTypeId(TypeInfoType, OpLoc, TInfo, RParenLoc);
+  }
+
+  // The operand is an expression.  
+  return BuildCXXTypeId(TypeInfoType, OpLoc, Owned((Expr*)TyOrExpr), RParenLoc);
+}
+
+/// ActOnCXXBoolLiteral - Parse {true,false} literals.
+Action::OwningExprResult
+Sema::ActOnCXXBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind) {
+  assert((Kind == tok::kw_true || Kind == tok::kw_false) &&
+         "Unknown C++ Boolean value!");
+  return Owned(new (Context) CXXBoolLiteralExpr(Kind == tok::kw_true,
+                                                Context.BoolTy, OpLoc));
+}
+
+/// ActOnCXXNullPtrLiteral - Parse 'nullptr'.
+Action::OwningExprResult
+Sema::ActOnCXXNullPtrLiteral(SourceLocation Loc) {
+  return Owned(new (Context) CXXNullPtrLiteralExpr(Context.NullPtrTy, Loc));
+}
+
+/// ActOnCXXThrow - Parse throw expressions.
+Action::OwningExprResult
+Sema::ActOnCXXThrow(SourceLocation OpLoc, ExprArg E) {
+  Expr *Ex = E.takeAs<Expr>();
+  if (Ex && !Ex->isTypeDependent() && CheckCXXThrowOperand(OpLoc, Ex))
+    return ExprError();
+  return Owned(new (Context) CXXThrowExpr(Ex, Context.VoidTy, OpLoc));
+}
+
+/// CheckCXXThrowOperand - Validate the operand of a throw.
+bool Sema::CheckCXXThrowOperand(SourceLocation ThrowLoc, Expr *&E) {
+  // C++ [except.throw]p3:
+  //   A throw-expression initializes a temporary object, called the exception
+  //   object, the type of which is determined by removing any top-level
+  //   cv-qualifiers from the static type of the operand of throw and adjusting
+  //   the type from "array of T" or "function returning T" to "pointer to T" 
+  //   or "pointer to function returning T", [...]
+  if (E->getType().hasQualifiers())
+    ImpCastExprToType(E, E->getType().getUnqualifiedType(), CastExpr::CK_NoOp,
+                      E->isLvalue(Context) == Expr::LV_Valid);
+  
+  DefaultFunctionArrayConversion(E);
+
+  //   If the type of the exception would be an incomplete type or a pointer
+  //   to an incomplete type other than (cv) void the program is ill-formed.
+  QualType Ty = E->getType();
+  bool isPointer = false;
+  if (const PointerType* Ptr = Ty->getAs<PointerType>()) {
+    Ty = Ptr->getPointeeType();
+    isPointer = true;
+  }
+  if (!isPointer || !Ty->isVoidType()) {
+    if (RequireCompleteType(ThrowLoc, Ty,
+                            PDiag(isPointer ? diag::err_throw_incomplete_ptr
+                                            : diag::err_throw_incomplete)
+                              << E->getSourceRange()))
+      return true;
+
+    if (RequireNonAbstractType(ThrowLoc, E->getType(),
+                               PDiag(diag::err_throw_abstract_type)
+                                 << E->getSourceRange()))
+      return true;
+  }
+
+  // Initialize the exception result.  This implicitly weeds out
+  // abstract types or types with inaccessible copy constructors.
+  InitializedEntity Entity =
+    InitializedEntity::InitializeException(ThrowLoc, E->getType());
+  OwningExprResult Res = PerformCopyInitialization(Entity,
+                                                   SourceLocation(),
+                                                   Owned(E));
+  if (Res.isInvalid())
+    return true;
+  E = Res.takeAs<Expr>();
+  return false;
+}
+
+Action::OwningExprResult Sema::ActOnCXXThis(SourceLocation ThisLoc) {
+  /// C++ 9.3.2: In the body of a non-static member function, the keyword this
+  /// is a non-lvalue expression whose value is the address of the object for
+  /// which the function is called.
+
+  if (!isa<FunctionDecl>(CurContext))
+    return ExprError(Diag(ThisLoc, diag::err_invalid_this_use));
+
+  if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(CurContext))
+    if (MD->isInstance())
+      return Owned(new (Context) CXXThisExpr(ThisLoc,
+                                             MD->getThisType(Context),
+                                             /*isImplicit=*/false));
+
+  return ExprError(Diag(ThisLoc, diag::err_invalid_this_use));
+}
+
+/// ActOnCXXTypeConstructExpr - Parse construction of a specified type.
+/// Can be interpreted either as function-style casting ("int(x)")
+/// or class type construction ("ClassType(x,y,z)")
+/// or creation of a value-initialized type ("int()").
+Action::OwningExprResult
+Sema::ActOnCXXTypeConstructExpr(SourceRange TypeRange, TypeTy *TypeRep,
+                                SourceLocation LParenLoc,
+                                MultiExprArg exprs,
+                                SourceLocation *CommaLocs,
+                                SourceLocation RParenLoc) {
+  if (!TypeRep)
+    return ExprError();
+
+  TypeSourceInfo *TInfo;
+  QualType Ty = GetTypeFromParser(TypeRep, &TInfo);
+  if (!TInfo)
+    TInfo = Context.getTrivialTypeSourceInfo(Ty, SourceLocation());
+  unsigned NumExprs = exprs.size();
+  Expr **Exprs = (Expr**)exprs.get();
+  SourceLocation TyBeginLoc = TypeRange.getBegin();
+  SourceRange FullRange = SourceRange(TyBeginLoc, RParenLoc);
+
+  if (Ty->isDependentType() ||
+      CallExpr::hasAnyTypeDependentArguments(Exprs, NumExprs)) {
+    exprs.release();
+
+    return Owned(CXXUnresolvedConstructExpr::Create(Context,
+                                                    TypeRange.getBegin(), Ty,
+                                                    LParenLoc,
+                                                    Exprs, NumExprs,
+                                                    RParenLoc));
+  }
+
+  if (Ty->isArrayType())
+    return ExprError(Diag(TyBeginLoc,
+                          diag::err_value_init_for_array_type) << FullRange);
+  if (!Ty->isVoidType() &&
+      RequireCompleteType(TyBeginLoc, Ty,
+                          PDiag(diag::err_invalid_incomplete_type_use)
+                            << FullRange))
+    return ExprError();
+  
+  if (RequireNonAbstractType(TyBeginLoc, Ty,
+                             diag::err_allocation_of_abstract_type))
+    return ExprError();
+
+
+  // C++ [expr.type.conv]p1:
+  // If the expression list is a single expression, the type conversion
+  // expression is equivalent (in definedness, and if defined in meaning) to the
+  // corresponding cast expression.
+  //
+  if (NumExprs == 1) {
+    CastExpr::CastKind Kind = CastExpr::CK_Unknown;
+    CXXBaseSpecifierArray BasePath;
+    if (CheckCastTypes(TypeRange, Ty, Exprs[0], Kind, BasePath,
+                       /*FunctionalStyle=*/true))
+      return ExprError();
+
+    exprs.release();
+
+    return Owned(new (Context) CXXFunctionalCastExpr(Ty.getNonReferenceType(),
+                                                     TInfo, TyBeginLoc, Kind,
+                                                     Exprs[0], BasePath,
+                                                     RParenLoc));
+  }
+
+  if (const RecordType *RT = Ty->getAs<RecordType>()) {
+    CXXRecordDecl *Record = cast<CXXRecordDecl>(RT->getDecl());
+
+    if (NumExprs > 1 || !Record->hasTrivialConstructor() ||
+        !Record->hasTrivialDestructor()) {
+      InitializedEntity Entity = InitializedEntity::InitializeTemporary(Ty);
+      InitializationKind Kind
+        = NumExprs ? InitializationKind::CreateDirect(TypeRange.getBegin(), 
+                                                      LParenLoc, RParenLoc)
+                   : InitializationKind::CreateValue(TypeRange.getBegin(), 
+                                                     LParenLoc, RParenLoc);
+      InitializationSequence InitSeq(*this, Entity, Kind, Exprs, NumExprs);
+      OwningExprResult Result = InitSeq.Perform(*this, Entity, Kind,
+                                                move(exprs));
+
+      // FIXME: Improve AST representation?
+      return move(Result);
+    }
+
+    // Fall through to value-initialize an object of class type that
+    // doesn't have a user-declared default constructor.
+  }
+
+  // C++ [expr.type.conv]p1:
+  // If the expression list specifies more than a single value, the type shall
+  // be a class with a suitably declared constructor.
+  //
+  if (NumExprs > 1)
+    return ExprError(Diag(CommaLocs[0],
+                          diag::err_builtin_func_cast_more_than_one_arg)
+      << FullRange);
+
+  assert(NumExprs == 0 && "Expected 0 expressions");
+  // C++ [expr.type.conv]p2:
+  // The expression T(), where T is a simple-type-specifier for a non-array
+  // complete object type or the (possibly cv-qualified) void type, creates an
+  // rvalue of the specified type, which is value-initialized.
+  //
+  exprs.release();
+  return Owned(new (Context) CXXZeroInitValueExpr(Ty, TyBeginLoc, RParenLoc));
+}
+
+
+/// ActOnCXXNew - Parsed a C++ 'new' expression (C++ 5.3.4), as in e.g.:
+/// @code new (memory) int[size][4] @endcode
+/// or
+/// @code ::new Foo(23, "hello") @endcode
+/// For the interpretation of this heap of arguments, consult the base version.
+Action::OwningExprResult
+Sema::ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal,
+                  SourceLocation PlacementLParen, MultiExprArg PlacementArgs,
+                  SourceLocation PlacementRParen, bool ParenTypeId,
+                  Declarator &D, SourceLocation ConstructorLParen,
+                  MultiExprArg ConstructorArgs,
+                  SourceLocation ConstructorRParen) {
+  Expr *ArraySize = 0;
+  // If the specified type is an array, unwrap it and save the expression.
+  if (D.getNumTypeObjects() > 0 &&
+      D.getTypeObject(0).Kind == DeclaratorChunk::Array) {
+    DeclaratorChunk &Chunk = D.getTypeObject(0);
+    if (Chunk.Arr.hasStatic)
+      return ExprError(Diag(Chunk.Loc, diag::err_static_illegal_in_new)
+        << D.getSourceRange());
+    if (!Chunk.Arr.NumElts)
+      return ExprError(Diag(Chunk.Loc, diag::err_array_new_needs_size)
+        << D.getSourceRange());
+
+    if (ParenTypeId) {
+      // Can't have dynamic array size when the type-id is in parentheses.
+      Expr *NumElts = (Expr *)Chunk.Arr.NumElts;
+      if (!NumElts->isTypeDependent() && !NumElts->isValueDependent() &&
+          !NumElts->isIntegerConstantExpr(Context)) {
+        Diag(D.getTypeObject(0).Loc, diag::err_new_paren_array_nonconst)
+          << NumElts->getSourceRange();
+        return ExprError();
+      }
+    }
+
+    ArraySize = static_cast<Expr*>(Chunk.Arr.NumElts);
+    D.DropFirstTypeObject();
+  }
+
+  // Every dimension shall be of constant size.
+  if (ArraySize) {
+    for (unsigned I = 0, N = D.getNumTypeObjects(); I < N; ++I) {
+      if (D.getTypeObject(I).Kind != DeclaratorChunk::Array)
+        break;
+
+      DeclaratorChunk::ArrayTypeInfo &Array = D.getTypeObject(I).Arr;
+      if (Expr *NumElts = (Expr *)Array.NumElts) {
+        if (!NumElts->isTypeDependent() && !NumElts->isValueDependent() &&
+            !NumElts->isIntegerConstantExpr(Context)) {
+          Diag(D.getTypeObject(I).Loc, diag::err_new_array_nonconst)
+            << NumElts->getSourceRange();
+          return ExprError();
+        }
+      }
+    }
+  }
+
+  //FIXME: Store TypeSourceInfo in CXXNew expression.
+  TypeSourceInfo *TInfo = 0;
+  QualType AllocType = GetTypeForDeclarator(D, /*Scope=*/0, &TInfo);
+  if (D.isInvalidType())
+    return ExprError();
+    
+  return BuildCXXNew(StartLoc, UseGlobal,
+                     PlacementLParen,
+                     move(PlacementArgs),
+                     PlacementRParen,
+                     ParenTypeId,
+                     AllocType,
+                     D.getSourceRange().getBegin(),
+                     D.getSourceRange(),
+                     Owned(ArraySize),
+                     ConstructorLParen,
+                     move(ConstructorArgs),
+                     ConstructorRParen);
+}
+
+Sema::OwningExprResult
+Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal,
+                  SourceLocation PlacementLParen,
+                  MultiExprArg PlacementArgs,
+                  SourceLocation PlacementRParen,
+                  bool ParenTypeId,
+                  QualType AllocType,
+                  SourceLocation TypeLoc,
+                  SourceRange TypeRange,
+                  ExprArg ArraySizeE,
+                  SourceLocation ConstructorLParen,
+                  MultiExprArg ConstructorArgs,
+                  SourceLocation ConstructorRParen) {
+  if (CheckAllocatedType(AllocType, TypeLoc, TypeRange))
+    return ExprError();
+
+  QualType ResultType = Context.getPointerType(AllocType);
+
+  // That every array dimension except the first is constant was already
+  // checked by the type check above.
+
+  // C++ 5.3.4p6: "The expression in a direct-new-declarator shall have integral
+  //   or enumeration type with a non-negative value."
+  Expr *ArraySize = (Expr *)ArraySizeE.get();
+  if (ArraySize && !ArraySize->isTypeDependent()) {
+    QualType SizeType = ArraySize->getType();
+    if (!SizeType->isIntegralType() && !SizeType->isEnumeralType())
+      return ExprError(Diag(ArraySize->getSourceRange().getBegin(),
+                            diag::err_array_size_not_integral)
+        << SizeType << ArraySize->getSourceRange());
+    // Let's see if this is a constant < 0. If so, we reject it out of hand.
+    // We don't care about special rules, so we tell the machinery it's not
+    // evaluated - it gives us a result in more cases.
+    if (!ArraySize->isValueDependent()) {
+      llvm::APSInt Value;
+      if (ArraySize->isIntegerConstantExpr(Value, Context, 0, false)) {
+        if (Value < llvm::APSInt(
+                        llvm::APInt::getNullValue(Value.getBitWidth()), 
+                                 Value.isUnsigned()))
+          return ExprError(Diag(ArraySize->getSourceRange().getBegin(),
+                           diag::err_typecheck_negative_array_size)
+            << ArraySize->getSourceRange());
+      }
+    }
+    
+    ImpCastExprToType(ArraySize, Context.getSizeType(),
+                      CastExpr::CK_IntegralCast);
+  }
+
+  FunctionDecl *OperatorNew = 0;
+  FunctionDecl *OperatorDelete = 0;
+  Expr **PlaceArgs = (Expr**)PlacementArgs.get();
+  unsigned NumPlaceArgs = PlacementArgs.size();
+  
+  if (!AllocType->isDependentType() &&
+      !Expr::hasAnyTypeDependentArguments(PlaceArgs, NumPlaceArgs) &&
+      FindAllocationFunctions(StartLoc,
+                              SourceRange(PlacementLParen, PlacementRParen),
+                              UseGlobal, AllocType, ArraySize, PlaceArgs,
+                              NumPlaceArgs, OperatorNew, OperatorDelete))
+    return ExprError();
+  llvm::SmallVector<Expr *, 8> AllPlaceArgs;
+  if (OperatorNew) {
+    // Add default arguments, if any.
+    const FunctionProtoType *Proto = 
+      OperatorNew->getType()->getAs<FunctionProtoType>();
+    VariadicCallType CallType = 
+      Proto->isVariadic() ? VariadicFunction : VariadicDoesNotApply;
+    bool Invalid = GatherArgumentsForCall(PlacementLParen, OperatorNew,
+                                          Proto, 1, PlaceArgs, NumPlaceArgs, 
+                                          AllPlaceArgs, CallType);
+    if (Invalid)
+      return ExprError();
+    
+    NumPlaceArgs = AllPlaceArgs.size();
+    if (NumPlaceArgs > 0)
+      PlaceArgs = &AllPlaceArgs[0];
+  }
+  
+  bool Init = ConstructorLParen.isValid();
+  // --- Choosing a constructor ---
+  CXXConstructorDecl *Constructor = 0;
+  Expr **ConsArgs = (Expr**)ConstructorArgs.get();
+  unsigned NumConsArgs = ConstructorArgs.size();
+  ASTOwningVector<&ActionBase::DeleteExpr> ConvertedConstructorArgs(*this);
+
+  if (!AllocType->isDependentType() &&
+      !Expr::hasAnyTypeDependentArguments(ConsArgs, NumConsArgs)) {
+    // C++0x [expr.new]p15:
+    //   A new-expression that creates an object of type T initializes that
+    //   object as follows:
+    InitializationKind Kind
+    //     - If the new-initializer is omitted, the object is default-
+    //       initialized (8.5); if no initialization is performed,
+    //       the object has indeterminate value
+      = !Init? InitializationKind::CreateDefault(TypeLoc)
+    //     - Otherwise, the new-initializer is interpreted according to the 
+    //       initialization rules of 8.5 for direct-initialization.
+             : InitializationKind::CreateDirect(TypeLoc,
+                                                ConstructorLParen, 
+                                                ConstructorRParen);
+    
+    InitializedEntity Entity
+      = InitializedEntity::InitializeNew(StartLoc, AllocType);
+    InitializationSequence InitSeq(*this, Entity, Kind, ConsArgs, NumConsArgs);
+    OwningExprResult FullInit = InitSeq.Perform(*this, Entity, Kind, 
+                                                move(ConstructorArgs));
+    if (FullInit.isInvalid())
+      return ExprError();
+    
+    // FullInit is our initializer; walk through it to determine if it's a 
+    // constructor call, which CXXNewExpr handles directly.
+    if (Expr *FullInitExpr = (Expr *)FullInit.get()) {
+      if (CXXBindTemporaryExpr *Binder
+            = dyn_cast<CXXBindTemporaryExpr>(FullInitExpr))
+        FullInitExpr = Binder->getSubExpr();
+      if (CXXConstructExpr *Construct
+                    = dyn_cast<CXXConstructExpr>(FullInitExpr)) {
+        Constructor = Construct->getConstructor();
+        for (CXXConstructExpr::arg_iterator A = Construct->arg_begin(),
+                                         AEnd = Construct->arg_end();
+             A != AEnd; ++A)
+          ConvertedConstructorArgs.push_back(A->Retain());
+      } else {
+        // Take the converted initializer.
+        ConvertedConstructorArgs.push_back(FullInit.release());
+      }
+    } else {
+      // No initialization required.
+    }
+    
+    // Take the converted arguments and use them for the new expression.
+    NumConsArgs = ConvertedConstructorArgs.size();
+    ConsArgs = (Expr **)ConvertedConstructorArgs.take();
+  }
+  
+  // Mark the new and delete operators as referenced.
+  if (OperatorNew)
+    MarkDeclarationReferenced(StartLoc, OperatorNew);
+  if (OperatorDelete)
+    MarkDeclarationReferenced(StartLoc, OperatorDelete);
+
+  // FIXME: Also check that the destructor is accessible. (C++ 5.3.4p16)
+  
+  PlacementArgs.release();
+  ConstructorArgs.release();
+  ArraySizeE.release();
+  return Owned(new (Context) CXXNewExpr(Context, UseGlobal, OperatorNew,
+                                        PlaceArgs, NumPlaceArgs, ParenTypeId,
+                                        ArraySize, Constructor, Init,
+                                        ConsArgs, NumConsArgs, OperatorDelete,
+                                        ResultType, StartLoc,
+                                        Init ? ConstructorRParen :
+                                               SourceLocation()));
+}
+
+/// CheckAllocatedType - Checks that a type is suitable as the allocated type
+/// in a new-expression.
+/// dimension off and stores the size expression in ArraySize.
+bool Sema::CheckAllocatedType(QualType AllocType, SourceLocation Loc,
+                              SourceRange R) {
+  // C++ 5.3.4p1: "[The] type shall be a complete object type, but not an
+  //   abstract class type or array thereof.
+  if (AllocType->isFunctionType())
+    return Diag(Loc, diag::err_bad_new_type)
+      << AllocType << 0 << R;
+  else if (AllocType->isReferenceType())
+    return Diag(Loc, diag::err_bad_new_type)
+      << AllocType << 1 << R;
+  else if (!AllocType->isDependentType() &&
+           RequireCompleteType(Loc, AllocType,
+                               PDiag(diag::err_new_incomplete_type)
+                                 << R))
+    return true;
+  else if (RequireNonAbstractType(Loc, AllocType,
+                                  diag::err_allocation_of_abstract_type))
+    return true;
+
+  return false;
+}
+
+/// \brief Determine whether the given function is a non-placement
+/// deallocation function.
+static bool isNonPlacementDeallocationFunction(FunctionDecl *FD) {
+  if (FD->isInvalidDecl())
+    return false;
+
+  if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(FD))
+    return Method->isUsualDeallocationFunction();
+
+  return ((FD->getOverloadedOperator() == OO_Delete ||
+           FD->getOverloadedOperator() == OO_Array_Delete) &&
+          FD->getNumParams() == 1);
+}
+
+/// FindAllocationFunctions - Finds the overloads of operator new and delete
+/// that are appropriate for the allocation.
+bool Sema::FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range,
+                                   bool UseGlobal, QualType AllocType,
+                                   bool IsArray, Expr **PlaceArgs,
+                                   unsigned NumPlaceArgs,
+                                   FunctionDecl *&OperatorNew,
+                                   FunctionDecl *&OperatorDelete) {
+  // --- Choosing an allocation function ---
+  // C++ 5.3.4p8 - 14 & 18
+  // 1) If UseGlobal is true, only look in the global scope. Else, also look
+  //   in the scope of the allocated class.
+  // 2) If an array size is given, look for operator new[], else look for
+  //   operator new.
+  // 3) The first argument is always size_t. Append the arguments from the
+  //   placement form.
+
+  llvm::SmallVector<Expr*, 8> AllocArgs(1 + NumPlaceArgs);
+  // We don't care about the actual value of this argument.
+  // FIXME: Should the Sema create the expression and embed it in the syntax
+  // tree? Or should the consumer just recalculate the value?
+  IntegerLiteral Size(llvm::APInt::getNullValue(
+                      Context.Target.getPointerWidth(0)),
+                      Context.getSizeType(),
+                      SourceLocation());
+  AllocArgs[0] = &Size;
+  std::copy(PlaceArgs, PlaceArgs + NumPlaceArgs, AllocArgs.begin() + 1);
+
+  // C++ [expr.new]p8:
+  //   If the allocated type is a non-array type, the allocation
+  //   function’s name is operator new and the deallocation function’s
+  //   name is operator delete. If the allocated type is an array
+  //   type, the allocation function’s name is operator new[] and the
+  //   deallocation function’s name is operator delete[].
+  DeclarationName NewName = Context.DeclarationNames.getCXXOperatorName(
+                                        IsArray ? OO_Array_New : OO_New);
+  DeclarationName DeleteName = Context.DeclarationNames.getCXXOperatorName(
+                                        IsArray ? OO_Array_Delete : OO_Delete);
+
+  if (AllocType->isRecordType() && !UseGlobal) {
+    CXXRecordDecl *Record
+      = cast<CXXRecordDecl>(AllocType->getAs<RecordType>()->getDecl());
+    if (FindAllocationOverload(StartLoc, Range, NewName, &AllocArgs[0],
+                          AllocArgs.size(), Record, /*AllowMissing=*/true,
+                          OperatorNew))
+      return true;
+  }
+  if (!OperatorNew) {
+    // Didn't find a member overload. Look for a global one.
+    DeclareGlobalNewDelete();
+    DeclContext *TUDecl = Context.getTranslationUnitDecl();
+    if (FindAllocationOverload(StartLoc, Range, NewName, &AllocArgs[0],
+                          AllocArgs.size(), TUDecl, /*AllowMissing=*/false,
+                          OperatorNew))
+      return true;
+  }
+
+  // We don't need an operator delete if we're running under
+  // -fno-exceptions.
+  if (!getLangOptions().Exceptions) {
+    OperatorDelete = 0;
+    return false;
+  }
+
+  // FindAllocationOverload can change the passed in arguments, so we need to
+  // copy them back.
+  if (NumPlaceArgs > 0)
+    std::copy(&AllocArgs[1], AllocArgs.end(), PlaceArgs);
+
+  // C++ [expr.new]p19:
+  //
+  //   If the new-expression begins with a unary :: operator, the
+  //   deallocation function’s name is looked up in the global
+  //   scope. Otherwise, if the allocated type is a class type T or an
+  //   array thereof, the deallocation function’s name is looked up in
+  //   the scope of T. If this lookup fails to find the name, or if
+  //   the allocated type is not a class type or array thereof, the
+  //   deallocation function’s name is looked up in the global scope.
+  LookupResult FoundDelete(*this, DeleteName, StartLoc, LookupOrdinaryName);
+  if (AllocType->isRecordType() && !UseGlobal) {
+    CXXRecordDecl *RD
+      = cast<CXXRecordDecl>(AllocType->getAs<RecordType>()->getDecl());
+    LookupQualifiedName(FoundDelete, RD);
+  }
+  if (FoundDelete.isAmbiguous())
+    return true; // FIXME: clean up expressions?
+
+  if (FoundDelete.empty()) {
+    DeclareGlobalNewDelete();
+    LookupQualifiedName(FoundDelete, Context.getTranslationUnitDecl());
+  }
+
+  FoundDelete.suppressDiagnostics();
+
+  llvm::SmallVector<std::pair<DeclAccessPair,FunctionDecl*>, 2> Matches;
+
+  if (NumPlaceArgs > 0) {
+    // C++ [expr.new]p20:
+    //   A declaration of a placement deallocation function matches the
+    //   declaration of a placement allocation function if it has the
+    //   same number of parameters and, after parameter transformations
+    //   (8.3.5), all parameter types except the first are
+    //   identical. [...]
+    // 
+    // To perform this comparison, we compute the function type that
+    // the deallocation function should have, and use that type both
+    // for template argument deduction and for comparison purposes.
+    QualType ExpectedFunctionType;
+    {
+      const FunctionProtoType *Proto
+        = OperatorNew->getType()->getAs<FunctionProtoType>();
+      llvm::SmallVector<QualType, 4> ArgTypes;
+      ArgTypes.push_back(Context.VoidPtrTy); 
+      for (unsigned I = 1, N = Proto->getNumArgs(); I < N; ++I)
+        ArgTypes.push_back(Proto->getArgType(I));
+
+      ExpectedFunctionType
+        = Context.getFunctionType(Context.VoidTy, ArgTypes.data(),
+                                  ArgTypes.size(),
+                                  Proto->isVariadic(),
+                                  0, false, false, 0, 0,
+                                  FunctionType::ExtInfo());
+    }
+
+    for (LookupResult::iterator D = FoundDelete.begin(), 
+                             DEnd = FoundDelete.end();
+         D != DEnd; ++D) {
+      FunctionDecl *Fn = 0;
+      if (FunctionTemplateDecl *FnTmpl 
+            = dyn_cast<FunctionTemplateDecl>((*D)->getUnderlyingDecl())) {
+        // Perform template argument deduction to try to match the
+        // expected function type.
+        TemplateDeductionInfo Info(Context, StartLoc);
+        if (DeduceTemplateArguments(FnTmpl, 0, ExpectedFunctionType, Fn, Info))
+          continue;
+      } else
+        Fn = cast<FunctionDecl>((*D)->getUnderlyingDecl());
+
+      if (Context.hasSameType(Fn->getType(), ExpectedFunctionType))
+        Matches.push_back(std::make_pair(D.getPair(), Fn));
+    }
+  } else {
+    // C++ [expr.new]p20:
+    //   [...] Any non-placement deallocation function matches a
+    //   non-placement allocation function. [...]
+    for (LookupResult::iterator D = FoundDelete.begin(), 
+                             DEnd = FoundDelete.end();
+         D != DEnd; ++D) {
+      if (FunctionDecl *Fn = dyn_cast<FunctionDecl>((*D)->getUnderlyingDecl()))
+        if (isNonPlacementDeallocationFunction(Fn))
+          Matches.push_back(std::make_pair(D.getPair(), Fn));
+    }
+  }
+
+  // C++ [expr.new]p20:
+  //   [...] If the lookup finds a single matching deallocation
+  //   function, that function will be called; otherwise, no
+  //   deallocation function will be called.
+  if (Matches.size() == 1) {
+    OperatorDelete = Matches[0].second;
+
+    // C++0x [expr.new]p20:
+    //   If the lookup finds the two-parameter form of a usual
+    //   deallocation function (3.7.4.2) and that function, considered
+    //   as a placement deallocation function, would have been
+    //   selected as a match for the allocation function, the program
+    //   is ill-formed.
+    if (NumPlaceArgs && getLangOptions().CPlusPlus0x &&
+        isNonPlacementDeallocationFunction(OperatorDelete)) {
+      Diag(StartLoc, diag::err_placement_new_non_placement_delete)
+        << SourceRange(PlaceArgs[0]->getLocStart(), 
+                       PlaceArgs[NumPlaceArgs - 1]->getLocEnd());
+      Diag(OperatorDelete->getLocation(), diag::note_previous_decl)
+        << DeleteName;
+    } else {
+      CheckAllocationAccess(StartLoc, Range, FoundDelete.getNamingClass(),
+                            Matches[0].first);
+    }
+  }
+
+  return false;
+}
+
+/// FindAllocationOverload - Find an fitting overload for the allocation
+/// function in the specified scope.
+bool Sema::FindAllocationOverload(SourceLocation StartLoc, SourceRange Range,
+                                  DeclarationName Name, Expr** Args,
+                                  unsigned NumArgs, DeclContext *Ctx,
+                                  bool AllowMissing, FunctionDecl *&Operator) {
+  LookupResult R(*this, Name, StartLoc, LookupOrdinaryName);
+  LookupQualifiedName(R, Ctx);
+  if (R.empty()) {
+    if (AllowMissing)
+      return false;
+    return Diag(StartLoc, diag::err_ovl_no_viable_function_in_call)
+      << Name << Range;
+  }
+
+  if (R.isAmbiguous())
+    return true;
+
+  R.suppressDiagnostics();
+
+  OverloadCandidateSet Candidates(StartLoc);
+  for (LookupResult::iterator Alloc = R.begin(), AllocEnd = R.end(); 
+       Alloc != AllocEnd; ++Alloc) {
+    // Even member operator new/delete are implicitly treated as
+    // static, so don't use AddMemberCandidate.
+    NamedDecl *D = (*Alloc)->getUnderlyingDecl();
+
+    if (FunctionTemplateDecl *FnTemplate = dyn_cast<FunctionTemplateDecl>(D)) {
+      AddTemplateOverloadCandidate(FnTemplate, Alloc.getPair(),
+                                   /*ExplicitTemplateArgs=*/0, Args, NumArgs,
+                                   Candidates,
+                                   /*SuppressUserConversions=*/false);
+      continue;
+    }
+
+    FunctionDecl *Fn = cast<FunctionDecl>(D);
+    AddOverloadCandidate(Fn, Alloc.getPair(), Args, NumArgs, Candidates,
+                         /*SuppressUserConversions=*/false);
+  }
+
+  // Do the resolution.
+  OverloadCandidateSet::iterator Best;
+  switch(BestViableFunction(Candidates, StartLoc, Best)) {
+  case OR_Success: {
+    // Got one!
+    FunctionDecl *FnDecl = Best->Function;
+    // The first argument is size_t, and the first parameter must be size_t,
+    // too. This is checked on declaration and can be assumed. (It can't be
+    // asserted on, though, since invalid decls are left in there.)
+    // Watch out for variadic allocator function.
+    unsigned NumArgsInFnDecl = FnDecl->getNumParams();
+    for (unsigned i = 0; (i < NumArgs && i < NumArgsInFnDecl); ++i) {
+      OwningExprResult Result
+        = PerformCopyInitialization(InitializedEntity::InitializeParameter(
+                                                       FnDecl->getParamDecl(i)),
+                                    SourceLocation(),
+                                    Owned(Args[i]->Retain()));
+      if (Result.isInvalid())
+        return true;
+      
+      Args[i] = Result.takeAs<Expr>();
+    }
+    Operator = FnDecl;
+    CheckAllocationAccess(StartLoc, Range, R.getNamingClass(), Best->FoundDecl);
+    return false;
+  }
+
+  case OR_No_Viable_Function:
+    Diag(StartLoc, diag::err_ovl_no_viable_function_in_call)
+      << Name << Range;
+    PrintOverloadCandidates(Candidates, OCD_AllCandidates, Args, NumArgs);
+    return true;
+
+  case OR_Ambiguous:
+    Diag(StartLoc, diag::err_ovl_ambiguous_call)
+      << Name << Range;
+    PrintOverloadCandidates(Candidates, OCD_ViableCandidates, Args, NumArgs);
+    return true;
+
+  case OR_Deleted:
+    Diag(StartLoc, diag::err_ovl_deleted_call)
+      << Best->Function->isDeleted()
+      << Name << Range;
+    PrintOverloadCandidates(Candidates, OCD_AllCandidates, Args, NumArgs);
+    return true;
+  }
+  assert(false && "Unreachable, bad result from BestViableFunction");
+  return true;
+}
+
+
+/// DeclareGlobalNewDelete - Declare the global forms of operator new and
+/// delete. These are:
+/// @code
+///   void* operator new(std::size_t) throw(std::bad_alloc);
+///   void* operator new[](std::size_t) throw(std::bad_alloc);
+///   void operator delete(void *) throw();
+///   void operator delete[](void *) throw();
+/// @endcode
+/// Note that the placement and nothrow forms of new are *not* implicitly
+/// declared. Their use requires including \<new\>.
+void Sema::DeclareGlobalNewDelete() {
+  if (GlobalNewDeleteDeclared)
+    return;
+  
+  // C++ [basic.std.dynamic]p2:
+  //   [...] The following allocation and deallocation functions (18.4) are 
+  //   implicitly declared in global scope in each translation unit of a 
+  //   program
+  //   
+  //     void* operator new(std::size_t) throw(std::bad_alloc);
+  //     void* operator new[](std::size_t) throw(std::bad_alloc); 
+  //     void  operator delete(void*) throw(); 
+  //     void  operator delete[](void*) throw();
+  //
+  //   These implicit declarations introduce only the function names operator 
+  //   new, operator new[], operator delete, operator delete[].
+  //
+  // Here, we need to refer to std::bad_alloc, so we will implicitly declare
+  // "std" or "bad_alloc" as necessary to form the exception specification.
+  // However, we do not make these implicit declarations visible to name
+  // lookup.
+  if (!StdNamespace) {
+    // The "std" namespace has not yet been defined, so build one implicitly.
+    StdNamespace = NamespaceDecl::Create(Context, 
+                                         Context.getTranslationUnitDecl(),
+                                         SourceLocation(),
+                                         &PP.getIdentifierTable().get("std"));
+    StdNamespace->setImplicit(true);
+  }
+  
+  if (!StdBadAlloc) {
+    // The "std::bad_alloc" class has not yet been declared, so build it
+    // implicitly.
+    StdBadAlloc = CXXRecordDecl::Create(Context, TagDecl::TK_class, 
+                                        StdNamespace, 
+                                        SourceLocation(), 
+                                      &PP.getIdentifierTable().get("bad_alloc"), 
+                                        SourceLocation(), 0);
+    StdBadAlloc->setImplicit(true);
+  }
+  
+  GlobalNewDeleteDeclared = true;
+
+  QualType VoidPtr = Context.getPointerType(Context.VoidTy);
+  QualType SizeT = Context.getSizeType();
+  bool AssumeSaneOperatorNew = getLangOptions().AssumeSaneOperatorNew;
+
+  DeclareGlobalAllocationFunction(
+      Context.DeclarationNames.getCXXOperatorName(OO_New),
+      VoidPtr, SizeT, AssumeSaneOperatorNew);
+  DeclareGlobalAllocationFunction(
+      Context.DeclarationNames.getCXXOperatorName(OO_Array_New),
+      VoidPtr, SizeT, AssumeSaneOperatorNew);
+  DeclareGlobalAllocationFunction(
+      Context.DeclarationNames.getCXXOperatorName(OO_Delete),
+      Context.VoidTy, VoidPtr);
+  DeclareGlobalAllocationFunction(
+      Context.DeclarationNames.getCXXOperatorName(OO_Array_Delete),
+      Context.VoidTy, VoidPtr);
+}
+
+/// DeclareGlobalAllocationFunction - Declares a single implicit global
+/// allocation function if it doesn't already exist.
+void Sema::DeclareGlobalAllocationFunction(DeclarationName Name,
+                                           QualType Return, QualType Argument,
+                                           bool AddMallocAttr) {
+  DeclContext *GlobalCtx = Context.getTranslationUnitDecl();
+
+  // Check if this function is already declared.
+  {
+    DeclContext::lookup_iterator Alloc, AllocEnd;
+    for (llvm::tie(Alloc, AllocEnd) = GlobalCtx->lookup(Name);
+         Alloc != AllocEnd; ++Alloc) {
+      // Only look at non-template functions, as it is the predefined,
+      // non-templated allocation function we are trying to declare here.
+      if (FunctionDecl *Func = dyn_cast<FunctionDecl>(*Alloc)) {
+        QualType InitialParamType =
+          Context.getCanonicalType(
+            Func->getParamDecl(0)->getType().getUnqualifiedType());
+        // FIXME: Do we need to check for default arguments here?
+        if (Func->getNumParams() == 1 && InitialParamType == Argument)
+          return;
+      }
+    }
+  }
+
+  QualType BadAllocType;
+  bool HasBadAllocExceptionSpec 
+    = (Name.getCXXOverloadedOperator() == OO_New ||
+       Name.getCXXOverloadedOperator() == OO_Array_New);
+  if (HasBadAllocExceptionSpec) {
+    assert(StdBadAlloc && "Must have std::bad_alloc declared");
+    BadAllocType = Context.getTypeDeclType(StdBadAlloc);
+  }
+  
+  QualType FnType = Context.getFunctionType(Return, &Argument, 1, false, 0,
+                                            true, false,
+                                            HasBadAllocExceptionSpec? 1 : 0,
+                                            &BadAllocType,
+                                            FunctionType::ExtInfo());
+  FunctionDecl *Alloc =
+    FunctionDecl::Create(Context, GlobalCtx, SourceLocation(), Name,
+                         FnType, /*TInfo=*/0, FunctionDecl::None,
+                         FunctionDecl::None, false, true);
+  Alloc->setImplicit();
+  
+  if (AddMallocAttr)
+    Alloc->addAttr(::new (Context) MallocAttr());
+  
+  ParmVarDecl *Param = ParmVarDecl::Create(Context, Alloc, SourceLocation(),
+                                           0, Argument, /*TInfo=*/0,
+                                           VarDecl::None,
+                                           VarDecl::None, 0);
+  Alloc->setParams(&Param, 1);
+
+  // FIXME: Also add this declaration to the IdentifierResolver, but
+  // make sure it is at the end of the chain to coincide with the
+  // global scope.
+  ((DeclContext *)TUScope->getEntity())->addDecl(Alloc);
+}
+
+bool Sema::FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD,
+                                    DeclarationName Name,
+                                    FunctionDecl* &Operator) {
+  LookupResult Found(*this, Name, StartLoc, LookupOrdinaryName);
+  // Try to find operator delete/operator delete[] in class scope.
+  LookupQualifiedName(Found, RD);
+  
+  if (Found.isAmbiguous())
+    return true;
+
+  for (LookupResult::iterator F = Found.begin(), FEnd = Found.end();
+       F != FEnd; ++F) {
+    if (CXXMethodDecl *Delete = dyn_cast<CXXMethodDecl>(*F))
+      if (Delete->isUsualDeallocationFunction()) {
+        Operator = Delete;
+        return false;
+      }
+  }
+
+  // We did find operator delete/operator delete[] declarations, but
+  // none of them were suitable.
+  if (!Found.empty()) {
+    Diag(StartLoc, diag::err_no_suitable_delete_member_function_found)
+      << Name << RD;
+        
+    for (LookupResult::iterator F = Found.begin(), FEnd = Found.end();
+         F != FEnd; ++F) {
+      Diag((*F)->getLocation(), diag::note_member_declared_here)
+        << Name;
+    }
+
+    return true;
+  }
+
+  // Look for a global declaration.
+  DeclareGlobalNewDelete();
+  DeclContext *TUDecl = Context.getTranslationUnitDecl();
+  
+  CXXNullPtrLiteralExpr Null(Context.VoidPtrTy, SourceLocation());
+  Expr* DeallocArgs[1];
+  DeallocArgs[0] = &Null;
+  if (FindAllocationOverload(StartLoc, SourceRange(), Name,
+                             DeallocArgs, 1, TUDecl, /*AllowMissing=*/false,
+                             Operator))
+    return true;
+
+  assert(Operator && "Did not find a deallocation function!");
+  return false;
+}
+
+/// ActOnCXXDelete - Parsed a C++ 'delete' expression (C++ 5.3.5), as in:
+/// @code ::delete ptr; @endcode
+/// or
+/// @code delete [] ptr; @endcode
+Action::OwningExprResult
+Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal,
+                     bool ArrayForm, ExprArg Operand) {
+  // C++ [expr.delete]p1:
+  //   The operand shall have a pointer type, or a class type having a single
+  //   conversion function to a pointer type. The result has type void.
+  //
+  // DR599 amends "pointer type" to "pointer to object type" in both cases.
+
+  FunctionDecl *OperatorDelete = 0;
+
+  Expr *Ex = (Expr *)Operand.get();
+  if (!Ex->isTypeDependent()) {
+    QualType Type = Ex->getType();
+
+    if (const RecordType *Record = Type->getAs<RecordType>()) {
+      llvm::SmallVector<CXXConversionDecl*, 4> ObjectPtrConversions;
+
+      CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getDecl());
+      const UnresolvedSetImpl *Conversions = RD->getVisibleConversionFunctions();      
+      for (UnresolvedSetImpl::iterator I = Conversions->begin(),
+             E = Conversions->end(); I != E; ++I) {
+        NamedDecl *D = I.getDecl();
+        if (isa<UsingShadowDecl>(D))
+          D = cast<UsingShadowDecl>(D)->getTargetDecl();
+
+        // Skip over templated conversion functions; they aren't considered.
+        if (isa<FunctionTemplateDecl>(D))
+          continue;
+        
+        CXXConversionDecl *Conv = cast<CXXConversionDecl>(D);
+        
+        QualType ConvType = Conv->getConversionType().getNonReferenceType();
+        if (const PointerType *ConvPtrType = ConvType->getAs<PointerType>())
+          if (ConvPtrType->getPointeeType()->isObjectType())
+            ObjectPtrConversions.push_back(Conv);
+      }
+      if (ObjectPtrConversions.size() == 1) {
+        // We have a single conversion to a pointer-to-object type. Perform
+        // that conversion.
+        // TODO: don't redo the conversion calculation.
+        Operand.release();
+        if (!PerformImplicitConversion(Ex,
+                            ObjectPtrConversions.front()->getConversionType(),
+                                      AA_Converting)) {
+          Operand = Owned(Ex);
+          Type = Ex->getType();
+        }
+      }
+      else if (ObjectPtrConversions.size() > 1) {
+        Diag(StartLoc, diag::err_ambiguous_delete_operand)
+              << Type << Ex->getSourceRange();
+        for (unsigned i= 0; i < ObjectPtrConversions.size(); i++)
+          NoteOverloadCandidate(ObjectPtrConversions[i]);
+        return ExprError();
+      }
+    }
+
+    if (!Type->isPointerType())
+      return ExprError(Diag(StartLoc, diag::err_delete_operand)
+        << Type << Ex->getSourceRange());
+
+    QualType Pointee = Type->getAs<PointerType>()->getPointeeType();
+    if (Pointee->isFunctionType() || Pointee->isVoidType())
+      return ExprError(Diag(StartLoc, diag::err_delete_operand)
+        << Type << Ex->getSourceRange());
+    else if (!Pointee->isDependentType() &&
+             RequireCompleteType(StartLoc, Pointee,
+                                 PDiag(diag::warn_delete_incomplete)
+                                   << Ex->getSourceRange()))
+      return ExprError();
+
+    // C++ [expr.delete]p2:
+    //   [Note: a pointer to a const type can be the operand of a 
+    //   delete-expression; it is not necessary to cast away the constness 
+    //   (5.2.11) of the pointer expression before it is used as the operand 
+    //   of the delete-expression. ]
+    ImpCastExprToType(Ex, Context.getPointerType(Context.VoidTy), 
+                      CastExpr::CK_NoOp);
+    
+    // Update the operand.
+    Operand.take();
+    Operand = ExprArg(*this, Ex);
+    
+    DeclarationName DeleteName = Context.DeclarationNames.getCXXOperatorName(
+                                      ArrayForm ? OO_Array_Delete : OO_Delete);
+
+    if (const RecordType *RT = Pointee->getAs<RecordType>()) {
+      CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
+
+      if (!UseGlobal && 
+          FindDeallocationFunction(StartLoc, RD, DeleteName, OperatorDelete))
+        return ExprError();
+      
+      if (!RD->hasTrivialDestructor())
+        if (const CXXDestructorDecl *Dtor = RD->getDestructor(Context))
+          MarkDeclarationReferenced(StartLoc,
+                                    const_cast<CXXDestructorDecl*>(Dtor));
+    }
+    
+    if (!OperatorDelete) {
+      // Look for a global declaration.
+      DeclareGlobalNewDelete();
+      DeclContext *TUDecl = Context.getTranslationUnitDecl();
+      if (FindAllocationOverload(StartLoc, SourceRange(), DeleteName,
+                                 &Ex, 1, TUDecl, /*AllowMissing=*/false,
+                                 OperatorDelete))
+        return ExprError();
+    }
+
+    MarkDeclarationReferenced(StartLoc, OperatorDelete);
+
+    // FIXME: Check access and ambiguity of operator delete and destructor.
+  }
+
+  Operand.release();
+  return Owned(new (Context) CXXDeleteExpr(Context.VoidTy, UseGlobal, ArrayForm,
+                                           OperatorDelete, Ex, StartLoc));
+}
+
+/// \brief Check the use of the given variable as a C++ condition in an if,
+/// while, do-while, or switch statement.
+Action::OwningExprResult Sema::CheckConditionVariable(VarDecl *ConditionVar) {
+  QualType T = ConditionVar->getType();
+  
+  // C++ [stmt.select]p2:
+  //   The declarator shall not specify a function or an array.
+  if (T->isFunctionType())
+    return ExprError(Diag(ConditionVar->getLocation(), 
+                          diag::err_invalid_use_of_function_type)
+                       << ConditionVar->getSourceRange());
+  else if (T->isArrayType())
+    return ExprError(Diag(ConditionVar->getLocation(), 
+                          diag::err_invalid_use_of_array_type)
+                     << ConditionVar->getSourceRange());
+
+  return Owned(DeclRefExpr::Create(Context, 0, SourceRange(), ConditionVar,
+                                   ConditionVar->getLocation(), 
+                                ConditionVar->getType().getNonReferenceType()));
+}
+
+/// CheckCXXBooleanCondition - Returns true if a conversion to bool is invalid.
+bool Sema::CheckCXXBooleanCondition(Expr *&CondExpr) {
+  // C++ 6.4p4:
+  // The value of a condition that is an initialized declaration in a statement
+  // other than a switch statement is the value of the declared variable
+  // implicitly converted to type bool. If that conversion is ill-formed, the
+  // program is ill-formed.
+  // The value of a condition that is an expression is the value of the
+  // expression, implicitly converted to bool.
+  //
+  return PerformContextuallyConvertToBool(CondExpr);
+}
+
+/// Helper function to determine whether this is the (deprecated) C++
+/// conversion from a string literal to a pointer to non-const char or
+/// non-const wchar_t (for narrow and wide string literals,
+/// respectively).
+bool
+Sema::IsStringLiteralToNonConstPointerConversion(Expr *From, QualType ToType) {
+  // Look inside the implicit cast, if it exists.
+  if (ImplicitCastExpr *Cast = dyn_cast<ImplicitCastExpr>(From))
+    From = Cast->getSubExpr();
+
+  // A string literal (2.13.4) that is not a wide string literal can
+  // be converted to an rvalue of type "pointer to char"; a wide
+  // string literal can be converted to an rvalue of type "pointer
+  // to wchar_t" (C++ 4.2p2).
+  if (StringLiteral *StrLit = dyn_cast<StringLiteral>(From))
+    if (const PointerType *ToPtrType = ToType->getAs<PointerType>())
+      if (const BuiltinType *ToPointeeType
+          = ToPtrType->getPointeeType()->getAs<BuiltinType>()) {
+        // This conversion is considered only when there is an
+        // explicit appropriate pointer target type (C++ 4.2p2).
+        if (!ToPtrType->getPointeeType().hasQualifiers() &&
+            ((StrLit->isWide() && ToPointeeType->isWideCharType()) ||
+             (!StrLit->isWide() &&
+              (ToPointeeType->getKind() == BuiltinType::Char_U ||
+               ToPointeeType->getKind() == BuiltinType::Char_S))))
+          return true;
+      }
+
+  return false;
+}
+
+static Sema::OwningExprResult BuildCXXCastArgument(Sema &S, 
+                                                   SourceLocation CastLoc,
+                                                   QualType Ty,
+                                                   CastExpr::CastKind Kind,
+                                                   CXXMethodDecl *Method,
+                                                   Sema::ExprArg Arg) {
+  Expr *From = Arg.takeAs<Expr>();
+  
+  switch (Kind) {
+  default: assert(0 && "Unhandled cast kind!");
+  case CastExpr::CK_ConstructorConversion: {
+    ASTOwningVector<&ActionBase::DeleteExpr> ConstructorArgs(S);
+    
+    if (S.CompleteConstructorCall(cast<CXXConstructorDecl>(Method),
+                                  Sema::MultiExprArg(S, (void **)&From, 1),
+                                  CastLoc, ConstructorArgs))
+      return S.ExprError();
+    
+    Sema::OwningExprResult Result = 
+    S.BuildCXXConstructExpr(CastLoc, Ty, cast<CXXConstructorDecl>(Method), 
+                            move_arg(ConstructorArgs));
+    if (Result.isInvalid())
+      return S.ExprError();
+    
+    return S.MaybeBindToTemporary(Result.takeAs<Expr>());
+  }
+    
+  case CastExpr::CK_UserDefinedConversion: {
+    assert(!From->getType()->isPointerType() && "Arg can't have pointer type!");
+    
+    // Create an implicit call expr that calls it.
+    // FIXME: pass the FoundDecl for the user-defined conversion here
+    CXXMemberCallExpr *CE = S.BuildCXXMemberCallExpr(From, Method, Method);
+    return S.MaybeBindToTemporary(CE);
+  }
+  }
+}    
+
+/// PerformImplicitConversion - Perform an implicit conversion of the
+/// expression From to the type ToType using the pre-computed implicit
+/// conversion sequence ICS. Returns true if there was an error, false
+/// otherwise. The expression From is replaced with the converted
+/// expression. Action is the kind of conversion we're performing,
+/// used in the error message.
+bool
+Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
+                                const ImplicitConversionSequence &ICS,
+                                AssignmentAction Action, bool IgnoreBaseAccess) {
+  switch (ICS.getKind()) {
+  case ImplicitConversionSequence::StandardConversion:
+    if (PerformImplicitConversion(From, ToType, ICS.Standard, Action,
+                                  IgnoreBaseAccess))
+      return true;
+    break;
+
+  case ImplicitConversionSequence::UserDefinedConversion: {
+    
+      FunctionDecl *FD = ICS.UserDefined.ConversionFunction;
+      CastExpr::CastKind CastKind = CastExpr::CK_Unknown;
+      QualType BeforeToType;
+      if (const CXXConversionDecl *Conv = dyn_cast<CXXConversionDecl>(FD)) {
+        CastKind = CastExpr::CK_UserDefinedConversion;
+        
+        // If the user-defined conversion is specified by a conversion function,
+        // the initial standard conversion sequence converts the source type to
+        // the implicit object parameter of the conversion function.
+        BeforeToType = Context.getTagDeclType(Conv->getParent());
+      } else if (const CXXConstructorDecl *Ctor = 
+                  dyn_cast<CXXConstructorDecl>(FD)) {
+        CastKind = CastExpr::CK_ConstructorConversion;
+        // Do no conversion if dealing with ... for the first conversion.
+        if (!ICS.UserDefined.EllipsisConversion) {
+          // If the user-defined conversion is specified by a constructor, the 
+          // initial standard conversion sequence converts the source type to the
+          // type required by the argument of the constructor
+          BeforeToType = Ctor->getParamDecl(0)->getType().getNonReferenceType();
+        }
+      }    
+      else
+        assert(0 && "Unknown conversion function kind!");
+      // Whatch out for elipsis conversion.
+      if (!ICS.UserDefined.EllipsisConversion) {
+        if (PerformImplicitConversion(From, BeforeToType, 
+                                      ICS.UserDefined.Before, AA_Converting,
+                                      IgnoreBaseAccess))
+          return true;
+      }
+    
+      OwningExprResult CastArg 
+        = BuildCXXCastArgument(*this,
+                               From->getLocStart(),
+                               ToType.getNonReferenceType(),
+                               CastKind, cast<CXXMethodDecl>(FD), 
+                               Owned(From));
+
+      if (CastArg.isInvalid())
+        return true;
+
+      From = CastArg.takeAs<Expr>();
+
+      return PerformImplicitConversion(From, ToType, ICS.UserDefined.After,
+                                       AA_Converting, IgnoreBaseAccess);
+  }
+
+  case ImplicitConversionSequence::AmbiguousConversion:
+    DiagnoseAmbiguousConversion(ICS, From->getExprLoc(),
+                          PDiag(diag::err_typecheck_ambiguous_condition)
+                            << From->getSourceRange());
+     return true;
+      
+  case ImplicitConversionSequence::EllipsisConversion:
+    assert(false && "Cannot perform an ellipsis conversion");
+    return false;
+
+  case ImplicitConversionSequence::BadConversion:
+    return true;
+  }
+
+  // Everything went well.
+  return false;
+}
+
+/// PerformImplicitConversion - Perform an implicit conversion of the
+/// expression From to the type ToType by following the standard
+/// conversion sequence SCS. Returns true if there was an error, false
+/// otherwise. The expression From is replaced with the converted
+/// expression. Flavor is the context in which we're performing this
+/// conversion, for use in error messages.
+bool
+Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
+                                const StandardConversionSequence& SCS,
+                                AssignmentAction Action, bool IgnoreBaseAccess) {
+  // Overall FIXME: we are recomputing too many types here and doing far too
+  // much extra work. What this means is that we need to keep track of more
+  // information that is computed when we try the implicit conversion initially,
+  // so that we don't need to recompute anything here.
+  QualType FromType = From->getType();
+
+  if (SCS.CopyConstructor) {
+    // FIXME: When can ToType be a reference type?
+    assert(!ToType->isReferenceType());
+    if (SCS.Second == ICK_Derived_To_Base) {
+      ASTOwningVector<&ActionBase::DeleteExpr> ConstructorArgs(*this);
+      if (CompleteConstructorCall(cast<CXXConstructorDecl>(SCS.CopyConstructor),
+                                  MultiExprArg(*this, (void **)&From, 1),
+                                  /*FIXME:ConstructLoc*/SourceLocation(), 
+                                  ConstructorArgs))
+        return true;
+      OwningExprResult FromResult =
+        BuildCXXConstructExpr(/*FIXME:ConstructLoc*/SourceLocation(),
+                              ToType, SCS.CopyConstructor,
+                              move_arg(ConstructorArgs));
+      if (FromResult.isInvalid())
+        return true;
+      From = FromResult.takeAs<Expr>();
+      return false;
+    }
+    OwningExprResult FromResult =
+      BuildCXXConstructExpr(/*FIXME:ConstructLoc*/SourceLocation(),
+                            ToType, SCS.CopyConstructor,
+                            MultiExprArg(*this, (void**)&From, 1));
+
+    if (FromResult.isInvalid())
+      return true;
+
+    From = FromResult.takeAs<Expr>();
+    return false;
+  }
+
+  // Perform the first implicit conversion.
+  switch (SCS.First) {
+  case ICK_Identity:
+  case ICK_Lvalue_To_Rvalue:
+    // Nothing to do.
+    break;
+
+  case ICK_Array_To_Pointer:
+    FromType = Context.getArrayDecayedType(FromType);
+    ImpCastExprToType(From, FromType, CastExpr::CK_ArrayToPointerDecay);
+    break;
+
+  case ICK_Function_To_Pointer:
+    if (Context.getCanonicalType(FromType) == Context.OverloadTy) {
+      DeclAccessPair Found;
+      FunctionDecl *Fn = ResolveAddressOfOverloadedFunction(From, ToType,
+                                                            true, Found);
+      if (!Fn)
+        return true;
+
+      if (DiagnoseUseOfDecl(Fn, From->getSourceRange().getBegin()))
+        return true;
+
+      From = FixOverloadedFunctionReference(From, Found, Fn);
+      FromType = From->getType();
+        
+      // If there's already an address-of operator in the expression, we have
+      // the right type already, and the code below would just introduce an
+      // invalid additional pointer level.
+      if (FromType->isPointerType() || FromType->isMemberFunctionPointerType())
+        break;
+    }
+    FromType = Context.getPointerType(FromType);
+    ImpCastExprToType(From, FromType, CastExpr::CK_FunctionToPointerDecay);
+    break;
+
+  default:
+    assert(false && "Improper first standard conversion");
+    break;
+  }
+
+  // Perform the second implicit conversion
+  switch (SCS.Second) {
+  case ICK_Identity:
+    // If both sides are functions (or pointers/references to them), there could
+    // be incompatible exception declarations.
+    if (CheckExceptionSpecCompatibility(From, ToType))
+      return true;
+    // Nothing else to do.
+    break;
+
+  case ICK_NoReturn_Adjustment:
+    // If both sides are functions (or pointers/references to them), there could
+    // be incompatible exception declarations.
+    if (CheckExceptionSpecCompatibility(From, ToType))
+      return true;      
+      
+    ImpCastExprToType(From, Context.getNoReturnType(From->getType(), false),
+                      CastExpr::CK_NoOp);
+    break;
+      
+  case ICK_Integral_Promotion:
+  case ICK_Integral_Conversion:
+    ImpCastExprToType(From, ToType, CastExpr::CK_IntegralCast);
+    break;
+
+  case ICK_Floating_Promotion:
+  case ICK_Floating_Conversion:
+    ImpCastExprToType(From, ToType, CastExpr::CK_FloatingCast);
+    break;
+
+  case ICK_Complex_Promotion:
+  case ICK_Complex_Conversion:
+    ImpCastExprToType(From, ToType, CastExpr::CK_Unknown);
+    break;
+
+  case ICK_Floating_Integral:
+    if (ToType->isFloatingType())
+      ImpCastExprToType(From, ToType, CastExpr::CK_IntegralToFloating);
+    else
+      ImpCastExprToType(From, ToType, CastExpr::CK_FloatingToIntegral);
+    break;
+
+  case ICK_Complex_Real:
+    ImpCastExprToType(From, ToType, CastExpr::CK_Unknown);
+    break;
+
+  case ICK_Compatible_Conversion:
+    ImpCastExprToType(From, ToType, CastExpr::CK_NoOp);
+    break;
+
+  case ICK_Pointer_Conversion: {
+    if (SCS.IncompatibleObjC) {
+      // Diagnose incompatible Objective-C conversions
+      Diag(From->getSourceRange().getBegin(),
+           diag::ext_typecheck_convert_incompatible_pointer)
+        << From->getType() << ToType << Action
+        << From->getSourceRange();
+    }
+
+    
+    CastExpr::CastKind Kind = CastExpr::CK_Unknown;
+    CXXBaseSpecifierArray BasePath;
+    if (CheckPointerConversion(From, ToType, Kind, BasePath, IgnoreBaseAccess))
+      return true;
+    ImpCastExprToType(From, ToType, Kind, /*isLvalue=*/false, BasePath);
+    break;
+  }
+  
+  case ICK_Pointer_Member: {
+    CastExpr::CastKind Kind = CastExpr::CK_Unknown;
+    CXXBaseSpecifierArray BasePath;
+    if (CheckMemberPointerConversion(From, ToType, Kind, BasePath,
+                                     IgnoreBaseAccess))
+      return true;
+    if (CheckExceptionSpecCompatibility(From, ToType))
+      return true;
+    ImpCastExprToType(From, ToType, Kind, /*isLvalue=*/false, BasePath);
+    break;
+  }
+  case ICK_Boolean_Conversion: {
+    CastExpr::CastKind Kind = CastExpr::CK_Unknown;
+    if (FromType->isMemberPointerType())
+      Kind = CastExpr::CK_MemberPointerToBoolean;
+    
+    ImpCastExprToType(From, Context.BoolTy, Kind);
+    break;
+  }
+
+  case ICK_Derived_To_Base:
+    if (CheckDerivedToBaseConversion(From->getType(), 
+                                     ToType.getNonReferenceType(),
+                                     From->getLocStart(),
+                                     From->getSourceRange(), 0,
+                                     IgnoreBaseAccess))
+      return true;
+    ImpCastExprToType(From, ToType.getNonReferenceType(), 
+                      CastExpr::CK_DerivedToBase);
+    break;
+      
+  default:
+    assert(false && "Improper second standard conversion");
+    break;
+  }
+
+  switch (SCS.Third) {
+  case ICK_Identity:
+    // Nothing to do.
+    break;
+
+  case ICK_Qualification:
+    // FIXME: Not sure about lvalue vs rvalue here in the presence of rvalue
+    // references.
+    ImpCastExprToType(From, ToType.getNonReferenceType(),
+                      CastExpr::CK_NoOp, ToType->isLValueReferenceType());
+
+    if (SCS.DeprecatedStringLiteralToCharPtr)
+      Diag(From->getLocStart(), diag::warn_deprecated_string_literal_conversion)
+        << ToType.getNonReferenceType();
+
+    break;
+      
+  default:
+    assert(false && "Improper second standard conversion");
+    break;
+  }
+
+  return false;
+}
+
+Sema::OwningExprResult Sema::ActOnUnaryTypeTrait(UnaryTypeTrait OTT,
+                                                 SourceLocation KWLoc,
+                                                 SourceLocation LParen,
+                                                 TypeTy *Ty,
+                                                 SourceLocation RParen) {
+  QualType T = GetTypeFromParser(Ty);
+
+  // According to http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html
+  // all traits except __is_class, __is_enum and __is_union require a the type
+  // to be complete.
+  if (OTT != UTT_IsClass && OTT != UTT_IsEnum && OTT != UTT_IsUnion) {
+    if (RequireCompleteType(KWLoc, T,
+                            diag::err_incomplete_type_used_in_type_trait_expr))
+      return ExprError();
+  }
+
+  // There is no point in eagerly computing the value. The traits are designed
+  // to be used from type trait templates, so Ty will be a template parameter
+  // 99% of the time.
+  return Owned(new (Context) UnaryTypeTraitExpr(KWLoc, OTT, T,
+                                                RParen, Context.BoolTy));
+}
+
+QualType Sema::CheckPointerToMemberOperands(
+  Expr *&lex, Expr *&rex, SourceLocation Loc, bool isIndirect) {
+  const char *OpSpelling = isIndirect ? "->*" : ".*";
+  // C++ 5.5p2
+  //   The binary operator .* [p3: ->*] binds its second operand, which shall
+  //   be of type "pointer to member of T" (where T is a completely-defined
+  //   class type) [...]
+  QualType RType = rex->getType();
+  const MemberPointerType *MemPtr = RType->getAs<MemberPointerType>();
+  if (!MemPtr) {
+    Diag(Loc, diag::err_bad_memptr_rhs)
+      << OpSpelling << RType << rex->getSourceRange();
+    return QualType();
+  }
+
+  QualType Class(MemPtr->getClass(), 0);
+
+  if (RequireCompleteType(Loc, Class, diag::err_memptr_rhs_to_incomplete))
+    return QualType();
+
+  // C++ 5.5p2
+  //   [...] to its first operand, which shall be of class T or of a class of
+  //   which T is an unambiguous and accessible base class. [p3: a pointer to
+  //   such a class]
+  QualType LType = lex->getType();
+  if (isIndirect) {
+    if (const PointerType *Ptr = LType->getAs<PointerType>())
+      LType = Ptr->getPointeeType().getNonReferenceType();
+    else {
+      Diag(Loc, diag::err_bad_memptr_lhs)
+        << OpSpelling << 1 << LType
+        << FixItHint::CreateReplacement(SourceRange(Loc), ".*");
+      return QualType();
+    }
+  }
+
+  if (!Context.hasSameUnqualifiedType(Class, LType)) {
+    // If we want to check the hierarchy, we need a complete type.
+    if (RequireCompleteType(Loc, LType, PDiag(diag::err_bad_memptr_lhs)
+        << OpSpelling << (int)isIndirect)) {
+      return QualType();
+    }
+    CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
+                       /*DetectVirtual=*/false);
+    // FIXME: Would it be useful to print full ambiguity paths, or is that
+    // overkill?
+    if (!IsDerivedFrom(LType, Class, Paths) ||
+        Paths.isAmbiguous(Context.getCanonicalType(Class))) {
+      Diag(Loc, diag::err_bad_memptr_lhs) << OpSpelling
+        << (int)isIndirect << lex->getType();
+      return QualType();
+    }
+    // Cast LHS to type of use.
+    QualType UseType = isIndirect ? Context.getPointerType(Class) : Class;
+    bool isLValue = !isIndirect && lex->isLvalue(Context) == Expr::LV_Valid;
+    
+    CXXBaseSpecifierArray BasePath;
+    BuildBasePathArray(Paths, BasePath);
+    ImpCastExprToType(lex, UseType, CastExpr::CK_DerivedToBase, isLValue,
+                      BasePath);
+  }
+
+  if (isa<CXXZeroInitValueExpr>(rex->IgnoreParens())) {
+    // Diagnose use of pointer-to-member type which when used as
+    // the functional cast in a pointer-to-member expression.
+    Diag(Loc, diag::err_pointer_to_member_type) << isIndirect;
+     return QualType();
+  }
+  // C++ 5.5p2
+  //   The result is an object or a function of the type specified by the
+  //   second operand.
+  // The cv qualifiers are the union of those in the pointer and the left side,
+  // in accordance with 5.5p5 and 5.2.5.
+  // FIXME: This returns a dereferenced member function pointer as a normal
+  // function type. However, the only operation valid on such functions is
+  // calling them. There's also a GCC extension to get a function pointer to the
+  // thing, which is another complication, because this type - unlike the type
+  // that is the result of this expression - takes the class as the first
+  // argument.
+  // We probably need a "MemberFunctionClosureType" or something like that.
+  QualType Result = MemPtr->getPointeeType();
+  Result = Context.getCVRQualifiedType(Result, LType.getCVRQualifiers());
+  return Result;
+}
+
+/// \brief Try to convert a type to another according to C++0x 5.16p3.
+///
+/// This is part of the parameter validation for the ? operator. If either
+/// value operand is a class type, the two operands are attempted to be
+/// converted to each other. This function does the conversion in one direction.
+/// It returns true if the program is ill-formed and has already been diagnosed
+/// as such.
+static bool TryClassUnification(Sema &Self, Expr *From, Expr *To,
+                                SourceLocation QuestionLoc,
+                                bool &HaveConversion,
+                                QualType &ToType) {
+  HaveConversion = false;
+  ToType = To->getType();
+  
+  InitializationKind Kind = InitializationKind::CreateCopy(To->getLocStart(), 
+                                                           SourceLocation());
+  // C++0x 5.16p3
+  //   The process for determining whether an operand expression E1 of type T1
+  //   can be converted to match an operand expression E2 of type T2 is defined
+  //   as follows:
+  //   -- If E2 is an lvalue:
+  bool ToIsLvalue = (To->isLvalue(Self.Context) == Expr::LV_Valid);
+  if (ToIsLvalue) {
+    //   E1 can be converted to match E2 if E1 can be implicitly converted to
+    //   type "lvalue reference to T2", subject to the constraint that in the
+    //   conversion the reference must bind directly to E1.
+    QualType T = Self.Context.getLValueReferenceType(ToType);
+    InitializedEntity Entity = InitializedEntity::InitializeTemporary(T);
+    
+    InitializationSequence InitSeq(Self, Entity, Kind, &From, 1);
+    if (InitSeq.isDirectReferenceBinding()) {
+      ToType = T;
+      HaveConversion = true;
+      return false;
+    }
+    
+    if (InitSeq.isAmbiguous())
+      return InitSeq.Diagnose(Self, Entity, Kind, &From, 1);
+  }
+
+  //   -- If E2 is an rvalue, or if the conversion above cannot be done:
+  //      -- if E1 and E2 have class type, and the underlying class types are
+  //         the same or one is a base class of the other:
+  QualType FTy = From->getType();
+  QualType TTy = To->getType();
+  const RecordType *FRec = FTy->getAs<RecordType>();
+  const RecordType *TRec = TTy->getAs<RecordType>();
+  bool FDerivedFromT = FRec && TRec && FRec != TRec && 
+                       Self.IsDerivedFrom(FTy, TTy);
+  if (FRec && TRec && 
+      (FRec == TRec || FDerivedFromT || Self.IsDerivedFrom(TTy, FTy))) {
+    //         E1 can be converted to match E2 if the class of T2 is the
+    //         same type as, or a base class of, the class of T1, and
+    //         [cv2 > cv1].
+    if (FRec == TRec || FDerivedFromT) {
+      if (TTy.isAtLeastAsQualifiedAs(FTy)) {
+        InitializedEntity Entity = InitializedEntity::InitializeTemporary(TTy);
+        InitializationSequence InitSeq(Self, Entity, Kind, &From, 1);
+        if (InitSeq.getKind() != InitializationSequence::FailedSequence) {
+          HaveConversion = true;
+          return false;
+        }
+        
+        if (InitSeq.isAmbiguous())
+          return InitSeq.Diagnose(Self, Entity, Kind, &From, 1);
+      } 
+    }
+    
+    return false;
+  }
+  
+  //     -- Otherwise: E1 can be converted to match E2 if E1 can be
+  //        implicitly converted to the type that expression E2 would have
+  //        if E2 were converted to an rvalue (or the type it has, if E2 is 
+  //        an rvalue).
+  //
+  // This actually refers very narrowly to the lvalue-to-rvalue conversion, not
+  // to the array-to-pointer or function-to-pointer conversions.
+  if (!TTy->getAs<TagType>())
+    TTy = TTy.getUnqualifiedType();
+  
+  InitializedEntity Entity = InitializedEntity::InitializeTemporary(TTy);
+  InitializationSequence InitSeq(Self, Entity, Kind, &From, 1);
+  HaveConversion = InitSeq.getKind() != InitializationSequence::FailedSequence;  
+  ToType = TTy;
+  if (InitSeq.isAmbiguous())
+    return InitSeq.Diagnose(Self, Entity, Kind, &From, 1);
+
+  return false;
+}
+
+/// \brief Try to find a common type for two according to C++0x 5.16p5.
+///
+/// This is part of the parameter validation for the ? operator. If either
+/// value operand is a class type, overload resolution is used to find a
+/// conversion to a common type.
+static bool FindConditionalOverload(Sema &Self, Expr *&LHS, Expr *&RHS,
+                                    SourceLocation Loc) {
+  Expr *Args[2] = { LHS, RHS };
+  OverloadCandidateSet CandidateSet(Loc);
+  Self.AddBuiltinOperatorCandidates(OO_Conditional, Loc, Args, 2, CandidateSet);
+
+  OverloadCandidateSet::iterator Best;
+  switch (Self.BestViableFunction(CandidateSet, Loc, Best)) {
+    case OR_Success:
+      // We found a match. Perform the conversions on the arguments and move on.
+      if (Self.PerformImplicitConversion(LHS, Best->BuiltinTypes.ParamTypes[0],
+                                         Best->Conversions[0], Sema::AA_Converting) ||
+          Self.PerformImplicitConversion(RHS, Best->BuiltinTypes.ParamTypes[1],
+                                         Best->Conversions[1], Sema::AA_Converting))
+        break;
+      return false;
+
+    case OR_No_Viable_Function:
+      Self.Diag(Loc, diag::err_typecheck_cond_incompatible_operands)
+        << LHS->getType() << RHS->getType()
+        << LHS->getSourceRange() << RHS->getSourceRange();
+      return true;
+
+    case OR_Ambiguous:
+      Self.Diag(Loc, diag::err_conditional_ambiguous_ovl)
+        << LHS->getType() << RHS->getType()
+        << LHS->getSourceRange() << RHS->getSourceRange();
+      // FIXME: Print the possible common types by printing the return types of
+      // the viable candidates.
+      break;
+
+    case OR_Deleted:
+      assert(false && "Conditional operator has only built-in overloads");
+      break;
+  }
+  return true;
+}
+
+/// \brief Perform an "extended" implicit conversion as returned by
+/// TryClassUnification.
+static bool ConvertForConditional(Sema &Self, Expr *&E, QualType T) {
+  InitializedEntity Entity = InitializedEntity::InitializeTemporary(T);
+  InitializationKind Kind = InitializationKind::CreateCopy(E->getLocStart(),
+                                                           SourceLocation());
+  InitializationSequence InitSeq(Self, Entity, Kind, &E, 1);
+  Sema::OwningExprResult Result = InitSeq.Perform(Self, Entity, Kind, 
+                                    Sema::MultiExprArg(Self, (void **)&E, 1));
+  if (Result.isInvalid())
+    return true;
+  
+  E = Result.takeAs<Expr>();
+  return false;
+}
+
+/// \brief Check the operands of ?: under C++ semantics.
+///
+/// See C++ [expr.cond]. Note that LHS is never null, even for the GNU x ?: y
+/// extension. In this case, LHS == Cond. (But they're not aliases.)
+QualType Sema::CXXCheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS,
+                                           SourceLocation QuestionLoc) {
+  // FIXME: Handle C99's complex types, vector types, block pointers and Obj-C++
+  // interface pointers.
+
+  // C++0x 5.16p1
+  //   The first expression is contextually converted to bool.
+  if (!Cond->isTypeDependent()) {
+    if (CheckCXXBooleanCondition(Cond))
+      return QualType();
+  }
+
+  // Either of the arguments dependent?
+  if (LHS->isTypeDependent() || RHS->isTypeDependent())
+    return Context.DependentTy;
+
+  CheckSignCompare(LHS, RHS, QuestionLoc);
+
+  // C++0x 5.16p2
+  //   If either the second or the third operand has type (cv) void, ...
+  QualType LTy = LHS->getType();
+  QualType RTy = RHS->getType();
+  bool LVoid = LTy->isVoidType();
+  bool RVoid = RTy->isVoidType();
+  if (LVoid || RVoid) {
+    //   ... then the [l2r] conversions are performed on the second and third
+    //   operands ...
+    DefaultFunctionArrayLvalueConversion(LHS);
+    DefaultFunctionArrayLvalueConversion(RHS);
+    LTy = LHS->getType();
+    RTy = RHS->getType();
+
+    //   ... and one of the following shall hold:
+    //   -- The second or the third operand (but not both) is a throw-
+    //      expression; the result is of the type of the other and is an rvalue.
+    bool LThrow = isa<CXXThrowExpr>(LHS);
+    bool RThrow = isa<CXXThrowExpr>(RHS);
+    if (LThrow && !RThrow)
+      return RTy;
+    if (RThrow && !LThrow)
+      return LTy;
+
+    //   -- Both the second and third operands have type void; the result is of
+    //      type void and is an rvalue.
+    if (LVoid && RVoid)
+      return Context.VoidTy;
+
+    // Neither holds, error.
+    Diag(QuestionLoc, diag::err_conditional_void_nonvoid)
+      << (LVoid ? RTy : LTy) << (LVoid ? 0 : 1)
+      << LHS->getSourceRange() << RHS->getSourceRange();
+    return QualType();
+  }
+
+  // Neither is void.
+
+  // C++0x 5.16p3
+  //   Otherwise, if the second and third operand have different types, and
+  //   either has (cv) class type, and attempt is made to convert each of those
+  //   operands to the other.
+  if (!Context.hasSameType(LTy, RTy) && 
+      (LTy->isRecordType() || RTy->isRecordType())) {
+    ImplicitConversionSequence ICSLeftToRight, ICSRightToLeft;
+    // These return true if a single direction is already ambiguous.
+    QualType L2RType, R2LType;
+    bool HaveL2R, HaveR2L;
+    if (TryClassUnification(*this, LHS, RHS, QuestionLoc, HaveL2R, L2RType))
+      return QualType();
+    if (TryClassUnification(*this, RHS, LHS, QuestionLoc, HaveR2L, R2LType))
+      return QualType();
+    
+    //   If both can be converted, [...] the program is ill-formed.
+    if (HaveL2R && HaveR2L) {
+      Diag(QuestionLoc, diag::err_conditional_ambiguous)
+        << LTy << RTy << LHS->getSourceRange() << RHS->getSourceRange();
+      return QualType();
+    }
+
+    //   If exactly one conversion is possible, that conversion is applied to
+    //   the chosen operand and the converted operands are used in place of the
+    //   original operands for the remainder of this section.
+    if (HaveL2R) {
+      if (ConvertForConditional(*this, LHS, L2RType))
+        return QualType();
+      LTy = LHS->getType();
+    } else if (HaveR2L) {
+      if (ConvertForConditional(*this, RHS, R2LType))
+        return QualType();
+      RTy = RHS->getType();
+    }
+  }
+
+  // C++0x 5.16p4
+  //   If the second and third operands are lvalues and have the same type,
+  //   the result is of that type [...]
+  bool Same = Context.hasSameType(LTy, RTy);
+  if (Same && LHS->isLvalue(Context) == Expr::LV_Valid &&
+      RHS->isLvalue(Context) == Expr::LV_Valid)
+    return LTy;
+
+  // C++0x 5.16p5
+  //   Otherwise, the result is an rvalue. If the second and third operands
+  //   do not have the same type, and either has (cv) class type, ...
+  if (!Same && (LTy->isRecordType() || RTy->isRecordType())) {
+    //   ... overload resolution is used to determine the conversions (if any)
+    //   to be applied to the operands. If the overload resolution fails, the
+    //   program is ill-formed.
+    if (FindConditionalOverload(*this, LHS, RHS, QuestionLoc))
+      return QualType();
+  }
+
+  // C++0x 5.16p6
+  //   LValue-to-rvalue, array-to-pointer, and function-to-pointer standard
+  //   conversions are performed on the second and third operands.
+  DefaultFunctionArrayLvalueConversion(LHS);
+  DefaultFunctionArrayLvalueConversion(RHS);
+  LTy = LHS->getType();
+  RTy = RHS->getType();
+
+  //   After those conversions, one of the following shall hold:
+  //   -- The second and third operands have the same type; the result
+  //      is of that type.
+  if (Context.getCanonicalType(LTy) == Context.getCanonicalType(RTy))
+    return LTy;
+
+  //   -- The second and third operands have arithmetic or enumeration type;
+  //      the usual arithmetic conversions are performed to bring them to a
+  //      common type, and the result is of that type.
+  if (LTy->isArithmeticType() && RTy->isArithmeticType()) {
+    UsualArithmeticConversions(LHS, RHS);
+    return LHS->getType();
+  }
+
+  //   -- The second and third operands have pointer type, or one has pointer
+  //      type and the other is a null pointer constant; pointer conversions
+  //      and qualification conversions are performed to bring them to their
+  //      composite pointer type. The result is of the composite pointer type.
+  //   -- The second and third operands have pointer to member type, or one has
+  //      pointer to member type and the other is a null pointer constant;
+  //      pointer to member conversions and qualification conversions are
+  //      performed to bring them to a common type, whose cv-qualification
+  //      shall match the cv-qualification of either the second or the third
+  //      operand. The result is of the common type.
+  bool NonStandardCompositeType = false;
+  QualType Composite = FindCompositePointerType(QuestionLoc, LHS, RHS,
+                              isSFINAEContext()? 0 : &NonStandardCompositeType);
+  if (!Composite.isNull()) {
+    if (NonStandardCompositeType)
+      Diag(QuestionLoc, 
+           diag::ext_typecheck_cond_incompatible_operands_nonstandard)
+        << LTy << RTy << Composite
+        << LHS->getSourceRange() << RHS->getSourceRange();
+      
+    return Composite;
+  }
+  
+  // Similarly, attempt to find composite type of two objective-c pointers.
+  Composite = FindCompositeObjCPointerType(LHS, RHS, QuestionLoc);
+  if (!Composite.isNull())
+    return Composite;
+
+  Diag(QuestionLoc, diag::err_typecheck_cond_incompatible_operands)
+    << LHS->getType() << RHS->getType()
+    << LHS->getSourceRange() << RHS->getSourceRange();
+  return QualType();
+}
+
+/// \brief Find a merged pointer type and convert the two expressions to it.
+///
+/// This finds the composite pointer type (or member pointer type) for @p E1
+/// and @p E2 according to C++0x 5.9p2. It converts both expressions to this
+/// type and returns it.
+/// It does not emit diagnostics.
+///
+/// \param Loc The location of the operator requiring these two expressions to
+/// be converted to the composite pointer type.
+///
+/// If \p NonStandardCompositeType is non-NULL, then we are permitted to find
+/// a non-standard (but still sane) composite type to which both expressions
+/// can be converted. When such a type is chosen, \c *NonStandardCompositeType
+/// will be set true.
+QualType Sema::FindCompositePointerType(SourceLocation Loc, 
+                                        Expr *&E1, Expr *&E2,
+                                        bool *NonStandardCompositeType) {
+  if (NonStandardCompositeType)
+    *NonStandardCompositeType = false;
+  
+  assert(getLangOptions().CPlusPlus && "This function assumes C++");
+  QualType T1 = E1->getType(), T2 = E2->getType();
+
+  if (!T1->isAnyPointerType() && !T1->isMemberPointerType() &&
+      !T2->isAnyPointerType() && !T2->isMemberPointerType())
+   return QualType();
+
+  // C++0x 5.9p2
+  //   Pointer conversions and qualification conversions are performed on
+  //   pointer operands to bring them to their composite pointer type. If
+  //   one operand is a null pointer constant, the composite pointer type is
+  //   the type of the other operand.
+  if (E1->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) {
+    if (T2->isMemberPointerType())
+      ImpCastExprToType(E1, T2, CastExpr::CK_NullToMemberPointer);
+    else
+      ImpCastExprToType(E1, T2, CastExpr::CK_IntegralToPointer);
+    return T2;
+  }
+  if (E2->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) {
+    if (T1->isMemberPointerType())
+      ImpCastExprToType(E2, T1, CastExpr::CK_NullToMemberPointer);
+    else
+      ImpCastExprToType(E2, T1, CastExpr::CK_IntegralToPointer);
+    return T1;
+  }
+
+  // Now both have to be pointers or member pointers.
+  if ((!T1->isPointerType() && !T1->isMemberPointerType()) ||
+      (!T2->isPointerType() && !T2->isMemberPointerType()))
+    return QualType();
+
+  //   Otherwise, of one of the operands has type "pointer to cv1 void," then
+  //   the other has type "pointer to cv2 T" and the composite pointer type is
+  //   "pointer to cv12 void," where cv12 is the union of cv1 and cv2.
+  //   Otherwise, the composite pointer type is a pointer type similar to the
+  //   type of one of the operands, with a cv-qualification signature that is
+  //   the union of the cv-qualification signatures of the operand types.
+  // In practice, the first part here is redundant; it's subsumed by the second.
+  // What we do here is, we build the two possible composite types, and try the
+  // conversions in both directions. If only one works, or if the two composite
+  // types are the same, we have succeeded.
+  // FIXME: extended qualifiers?
+  typedef llvm::SmallVector<unsigned, 4> QualifierVector;
+  QualifierVector QualifierUnion;
+  typedef llvm::SmallVector<std::pair<const Type *, const Type *>, 4>
+      ContainingClassVector;
+  ContainingClassVector MemberOfClass;
+  QualType Composite1 = Context.getCanonicalType(T1),
+           Composite2 = Context.getCanonicalType(T2);
+  unsigned NeedConstBefore = 0;  
+  do {
+    const PointerType *Ptr1, *Ptr2;
+    if ((Ptr1 = Composite1->getAs<PointerType>()) &&
+        (Ptr2 = Composite2->getAs<PointerType>())) {
+      Composite1 = Ptr1->getPointeeType();
+      Composite2 = Ptr2->getPointeeType();
+      
+      // If we're allowed to create a non-standard composite type, keep track
+      // of where we need to fill in additional 'const' qualifiers. 
+      if (NonStandardCompositeType &&
+          Composite1.getCVRQualifiers() != Composite2.getCVRQualifiers())
+        NeedConstBefore = QualifierUnion.size();
+      
+      QualifierUnion.push_back(
+                 Composite1.getCVRQualifiers() | Composite2.getCVRQualifiers());
+      MemberOfClass.push_back(std::make_pair((const Type *)0, (const Type *)0));
+      continue;
+    }
+
+    const MemberPointerType *MemPtr1, *MemPtr2;
+    if ((MemPtr1 = Composite1->getAs<MemberPointerType>()) &&
+        (MemPtr2 = Composite2->getAs<MemberPointerType>())) {
+      Composite1 = MemPtr1->getPointeeType();
+      Composite2 = MemPtr2->getPointeeType();
+      
+      // If we're allowed to create a non-standard composite type, keep track
+      // of where we need to fill in additional 'const' qualifiers. 
+      if (NonStandardCompositeType &&
+          Composite1.getCVRQualifiers() != Composite2.getCVRQualifiers())
+        NeedConstBefore = QualifierUnion.size();
+      
+      QualifierUnion.push_back(
+                 Composite1.getCVRQualifiers() | Composite2.getCVRQualifiers());
+      MemberOfClass.push_back(std::make_pair(MemPtr1->getClass(),
+                                             MemPtr2->getClass()));
+      continue;
+    }
+
+    // FIXME: block pointer types?
+
+    // Cannot unwrap any more types.
+    break;
+  } while (true);
+
+  if (NeedConstBefore && NonStandardCompositeType) {
+    // Extension: Add 'const' to qualifiers that come before the first qualifier
+    // mismatch, so that our (non-standard!) composite type meets the 
+    // requirements of C++ [conv.qual]p4 bullet 3.
+    for (unsigned I = 0; I != NeedConstBefore; ++I) {
+      if ((QualifierUnion[I] & Qualifiers::Const) == 0) {
+        QualifierUnion[I] = QualifierUnion[I] | Qualifiers::Const;
+        *NonStandardCompositeType = true;
+      }
+    }
+  }
+  
+  // Rewrap the composites as pointers or member pointers with the union CVRs.
+  ContainingClassVector::reverse_iterator MOC
+    = MemberOfClass.rbegin();
+  for (QualifierVector::reverse_iterator
+         I = QualifierUnion.rbegin(),
+         E = QualifierUnion.rend();
+       I != E; (void)++I, ++MOC) {
+    Qualifiers Quals = Qualifiers::fromCVRMask(*I);
+    if (MOC->first && MOC->second) {
+      // Rebuild member pointer type
+      Composite1 = Context.getMemberPointerType(
+                                    Context.getQualifiedType(Composite1, Quals),
+                                    MOC->first);
+      Composite2 = Context.getMemberPointerType(
+                                    Context.getQualifiedType(Composite2, Quals),
+                                    MOC->second);
+    } else {
+      // Rebuild pointer type
+      Composite1
+        = Context.getPointerType(Context.getQualifiedType(Composite1, Quals));
+      Composite2
+        = Context.getPointerType(Context.getQualifiedType(Composite2, Quals));
+    }
+  }
+
+  // Try to convert to the first composite pointer type.
+  InitializedEntity Entity1
+    = InitializedEntity::InitializeTemporary(Composite1);
+  InitializationKind Kind
+    = InitializationKind::CreateCopy(Loc, SourceLocation());
+  InitializationSequence E1ToC1(*this, Entity1, Kind, &E1, 1);
+  InitializationSequence E2ToC1(*this, Entity1, Kind, &E2, 1);
+
+  if (E1ToC1 && E2ToC1) {
+    // Conversion to Composite1 is viable.
+    if (!Context.hasSameType(Composite1, Composite2)) {
+      // Composite2 is a different type from Composite1. Check whether
+      // Composite2 is also viable.
+      InitializedEntity Entity2
+        = InitializedEntity::InitializeTemporary(Composite2);
+      InitializationSequence E1ToC2(*this, Entity2, Kind, &E1, 1);
+      InitializationSequence E2ToC2(*this, Entity2, Kind, &E2, 1);
+      if (E1ToC2 && E2ToC2) {
+        // Both Composite1 and Composite2 are viable and are different;
+        // this is an ambiguity.
+        return QualType();
+      }
+    }
+
+    // Convert E1 to Composite1
+    OwningExprResult E1Result
+      = E1ToC1.Perform(*this, Entity1, Kind, MultiExprArg(*this,(void**)&E1,1));
+    if (E1Result.isInvalid())
+      return QualType();
+    E1 = E1Result.takeAs<Expr>();
+
+    // Convert E2 to Composite1
+    OwningExprResult E2Result
+      = E2ToC1.Perform(*this, Entity1, Kind, MultiExprArg(*this,(void**)&E2,1));
+    if (E2Result.isInvalid())
+      return QualType();
+    E2 = E2Result.takeAs<Expr>();
+    
+    return Composite1;
+  }
+
+  // Check whether Composite2 is viable.
+  InitializedEntity Entity2
+    = InitializedEntity::InitializeTemporary(Composite2);
+  InitializationSequence E1ToC2(*this, Entity2, Kind, &E1, 1);
+  InitializationSequence E2ToC2(*this, Entity2, Kind, &E2, 1);
+  if (!E1ToC2 || !E2ToC2)
+    return QualType();
+  
+  // Convert E1 to Composite2
+  OwningExprResult E1Result
+    = E1ToC2.Perform(*this, Entity2, Kind, MultiExprArg(*this, (void**)&E1, 1));
+  if (E1Result.isInvalid())
+    return QualType();
+  E1 = E1Result.takeAs<Expr>();
+  
+  // Convert E2 to Composite2
+  OwningExprResult E2Result
+    = E2ToC2.Perform(*this, Entity2, Kind, MultiExprArg(*this, (void**)&E2, 1));
+  if (E2Result.isInvalid())
+    return QualType();
+  E2 = E2Result.takeAs<Expr>();
+  
+  return Composite2;
+}
+
+Sema::OwningExprResult Sema::MaybeBindToTemporary(Expr *E) {
+  if (!Context.getLangOptions().CPlusPlus)
+    return Owned(E);
+
+  assert(!isa<CXXBindTemporaryExpr>(E) && "Double-bound temporary?");
+
+  const RecordType *RT = E->getType()->getAs<RecordType>();
+  if (!RT)
+    return Owned(E);
+
+  // If this is the result of a call expression, our source might
+  // actually be a reference, in which case we shouldn't bind.
+  if (CallExpr *CE = dyn_cast<CallExpr>(E)) {
+    QualType Ty = CE->getCallee()->getType();
+    if (const PointerType *PT = Ty->getAs<PointerType>())
+      Ty = PT->getPointeeType();
+    else if (const BlockPointerType *BPT = Ty->getAs<BlockPointerType>())
+      Ty = BPT->getPointeeType();
+
+    const FunctionType *FTy = Ty->getAs<FunctionType>();
+    if (FTy->getResultType()->isReferenceType())
+      return Owned(E);
+  }
+
+  // That should be enough to guarantee that this type is complete.
+  // If it has a trivial destructor, we can avoid the extra copy.
+  CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
+  if (RD->hasTrivialDestructor())
+    return Owned(E);
+
+  CXXTemporary *Temp = CXXTemporary::Create(Context,
+                                            RD->getDestructor(Context));
+  ExprTemporaries.push_back(Temp);
+  if (CXXDestructorDecl *Destructor =
+        const_cast<CXXDestructorDecl*>(RD->getDestructor(Context))) {
+    MarkDeclarationReferenced(E->getExprLoc(), Destructor);
+    CheckDestructorAccess(E->getExprLoc(), Destructor,
+                          PDiag(diag::err_access_dtor_temp)
+                            << E->getType());
+  }
+  // FIXME: Add the temporary to the temporaries vector.
+  return Owned(CXXBindTemporaryExpr::Create(Context, Temp, E));
+}
+
+Expr *Sema::MaybeCreateCXXExprWithTemporaries(Expr *SubExpr) {
+  assert(SubExpr && "sub expression can't be null!");
+
+  unsigned FirstTemporary = ExprEvalContexts.back().NumTemporaries;
+  assert(ExprTemporaries.size() >= FirstTemporary);
+  if (ExprTemporaries.size() == FirstTemporary)
+    return SubExpr;
+
+  Expr *E = CXXExprWithTemporaries::Create(Context, SubExpr,
+                                           &ExprTemporaries[FirstTemporary],
+                                       ExprTemporaries.size() - FirstTemporary);
+  ExprTemporaries.erase(ExprTemporaries.begin() + FirstTemporary,
+                        ExprTemporaries.end());
+
+  return E;
+}
+
+Sema::OwningExprResult 
+Sema::MaybeCreateCXXExprWithTemporaries(OwningExprResult SubExpr) {
+  if (SubExpr.isInvalid())
+    return ExprError();
+  
+  return Owned(MaybeCreateCXXExprWithTemporaries(SubExpr.takeAs<Expr>()));
+}
+
+FullExpr Sema::CreateFullExpr(Expr *SubExpr) {
+  unsigned FirstTemporary = ExprEvalContexts.back().NumTemporaries;
+  assert(ExprTemporaries.size() >= FirstTemporary);
+  
+  unsigned NumTemporaries = ExprTemporaries.size() - FirstTemporary;
+  CXXTemporary **Temporaries = 
+    NumTemporaries == 0 ? 0 : &ExprTemporaries[FirstTemporary];
+  
+  FullExpr E = FullExpr::Create(Context, SubExpr, Temporaries, NumTemporaries);
+
+  ExprTemporaries.erase(ExprTemporaries.begin() + FirstTemporary,
+                        ExprTemporaries.end());
+
+  return E;
+}
+
+Sema::OwningExprResult
+Sema::ActOnStartCXXMemberReference(Scope *S, ExprArg Base, SourceLocation OpLoc,
+                                   tok::TokenKind OpKind, TypeTy *&ObjectType,
+                                   bool &MayBePseudoDestructor) {
+  // Since this might be a postfix expression, get rid of ParenListExprs.
+  Base = MaybeConvertParenListExprToParenExpr(S, move(Base));
+
+  Expr *BaseExpr = (Expr*)Base.get();
+  assert(BaseExpr && "no record expansion");
+
+  QualType BaseType = BaseExpr->getType();
+  MayBePseudoDestructor = false;
+  if (BaseType->isDependentType()) {
+    // If we have a pointer to a dependent type and are using the -> operator,
+    // the object type is the type that the pointer points to. We might still
+    // have enough information about that type to do something useful.
+    if (OpKind == tok::arrow)
+      if (const PointerType *Ptr = BaseType->getAs<PointerType>())
+        BaseType = Ptr->getPointeeType();
+    
+    ObjectType = BaseType.getAsOpaquePtr();
+    MayBePseudoDestructor = true;
+    return move(Base);
+  }
+
+  // C++ [over.match.oper]p8:
+  //   [...] When operator->returns, the operator-> is applied  to the value
+  //   returned, with the original second operand.
+  if (OpKind == tok::arrow) {
+    // The set of types we've considered so far.
+    llvm::SmallPtrSet<CanQualType,8> CTypes;
+    llvm::SmallVector<SourceLocation, 8> Locations;
+    CTypes.insert(Context.getCanonicalType(BaseType));
+    
+    while (BaseType->isRecordType()) {
+      Base = BuildOverloadedArrowExpr(S, move(Base), OpLoc);
+      BaseExpr = (Expr*)Base.get();
+      if (BaseExpr == NULL)
+        return ExprError();
+      if (CXXOperatorCallExpr *OpCall = dyn_cast<CXXOperatorCallExpr>(BaseExpr))
+        Locations.push_back(OpCall->getDirectCallee()->getLocation());
+      BaseType = BaseExpr->getType();
+      CanQualType CBaseType = Context.getCanonicalType(BaseType);
+      if (!CTypes.insert(CBaseType)) {
+        Diag(OpLoc, diag::err_operator_arrow_circular);
+        for (unsigned i = 0; i < Locations.size(); i++)
+          Diag(Locations[i], diag::note_declared_at);
+        return ExprError();
+      }
+    }
+
+    if (BaseType->isPointerType())
+      BaseType = BaseType->getPointeeType();
+  }
+
+  // We could end up with various non-record types here, such as extended
+  // vector types or Objective-C interfaces. Just return early and let
+  // ActOnMemberReferenceExpr do the work.
+  if (!BaseType->isRecordType()) {
+    // C++ [basic.lookup.classref]p2:
+    //   [...] If the type of the object expression is of pointer to scalar
+    //   type, the unqualified-id is looked up in the context of the complete
+    //   postfix-expression.
+    //
+    // This also indicates that we should be parsing a
+    // pseudo-destructor-name.
+    ObjectType = 0;
+    MayBePseudoDestructor = true;
+    return move(Base);
+  }
+
+  // The object type must be complete (or dependent).
+  if (!BaseType->isDependentType() &&
+      RequireCompleteType(OpLoc, BaseType, 
+                          PDiag(diag::err_incomplete_member_access)))
+    return ExprError();
+  
+  // C++ [basic.lookup.classref]p2:
+  //   If the id-expression in a class member access (5.2.5) is an
+  //   unqualified-id, and the type of the object expression is of a class
+  //   type C (or of pointer to a class type C), the unqualified-id is looked
+  //   up in the scope of class C. [...]
+  ObjectType = BaseType.getAsOpaquePtr();
+  return move(Base);
+}
+
+Sema::OwningExprResult Sema::DiagnoseDtorReference(SourceLocation NameLoc,
+                                                   ExprArg MemExpr) {
+  Expr *E = (Expr *) MemExpr.get();
+  SourceLocation ExpectedLParenLoc = PP.getLocForEndOfToken(NameLoc);
+  Diag(E->getLocStart(), diag::err_dtor_expr_without_call)
+    << isa<CXXPseudoDestructorExpr>(E)
+    << FixItHint::CreateInsertion(ExpectedLParenLoc, "()");
+  
+  return ActOnCallExpr(/*Scope*/ 0,
+                       move(MemExpr),
+                       /*LPLoc*/ ExpectedLParenLoc,
+                       Sema::MultiExprArg(*this, 0, 0),
+                       /*CommaLocs*/ 0,
+                       /*RPLoc*/ ExpectedLParenLoc);
+}
+
+Sema::OwningExprResult Sema::BuildPseudoDestructorExpr(ExprArg Base,
+                                                       SourceLocation OpLoc,
+                                                       tok::TokenKind OpKind,
+                                                       const CXXScopeSpec &SS,
+                                                 TypeSourceInfo *ScopeTypeInfo,
+                                                       SourceLocation CCLoc,
+                                                       SourceLocation TildeLoc,
+                                         PseudoDestructorTypeStorage Destructed,
+                                                       bool HasTrailingLParen) {
+  TypeSourceInfo *DestructedTypeInfo = Destructed.getTypeSourceInfo();
+  
+  // C++ [expr.pseudo]p2:
+  //   The left-hand side of the dot operator shall be of scalar type. The 
+  //   left-hand side of the arrow operator shall be of pointer to scalar type.
+  //   This scalar type is the object type. 
+  Expr *BaseE = (Expr *)Base.get();
+  QualType ObjectType = BaseE->getType();
+  if (OpKind == tok::arrow) {
+    if (const PointerType *Ptr = ObjectType->getAs<PointerType>()) {
+      ObjectType = Ptr->getPointeeType();
+    } else if (!BaseE->isTypeDependent()) {
+      // The user wrote "p->" when she probably meant "p."; fix it.
+      Diag(OpLoc, diag::err_typecheck_member_reference_suggestion)
+        << ObjectType << true
+        << FixItHint::CreateReplacement(OpLoc, ".");
+      if (isSFINAEContext())
+        return ExprError();
+      
+      OpKind = tok::period;
+    }
+  }
+  
+  if (!ObjectType->isDependentType() && !ObjectType->isScalarType()) {
+    Diag(OpLoc, diag::err_pseudo_dtor_base_not_scalar)
+      << ObjectType << BaseE->getSourceRange();
+    return ExprError();
+  }
+
+  // C++ [expr.pseudo]p2:
+  //   [...] The cv-unqualified versions of the object type and of the type 
+  //   designated by the pseudo-destructor-name shall be the same type.
+  if (DestructedTypeInfo) {
+    QualType DestructedType = DestructedTypeInfo->getType();
+    SourceLocation DestructedTypeStart
+      = DestructedTypeInfo->getTypeLoc().getSourceRange().getBegin();
+    if (!DestructedType->isDependentType() && !ObjectType->isDependentType() &&
+        !Context.hasSameUnqualifiedType(DestructedType, ObjectType)) {
+      Diag(DestructedTypeStart, diag::err_pseudo_dtor_type_mismatch)
+        << ObjectType << DestructedType << BaseE->getSourceRange()
+        << DestructedTypeInfo->getTypeLoc().getSourceRange();
+      
+      // Recover by setting the destructed type to the object type.
+      DestructedType = ObjectType;
+      DestructedTypeInfo = Context.getTrivialTypeSourceInfo(ObjectType,
+                                                           DestructedTypeStart);
+      Destructed = PseudoDestructorTypeStorage(DestructedTypeInfo);
+    }
+  }
+  
+  // C++ [expr.pseudo]p2:
+  //   [...] Furthermore, the two type-names in a pseudo-destructor-name of the
+  //   form
+  //
+  //     ::[opt] nested-name-specifier[opt] type-name :: ~ type-name 
+  //
+  //   shall designate the same scalar type.
+  if (ScopeTypeInfo) {
+    QualType ScopeType = ScopeTypeInfo->getType();
+    if (!ScopeType->isDependentType() && !ObjectType->isDependentType() &&
+        !Context.hasSameType(ScopeType, ObjectType)) {
+      
+      Diag(ScopeTypeInfo->getTypeLoc().getSourceRange().getBegin(),
+           diag::err_pseudo_dtor_type_mismatch)
+        << ObjectType << ScopeType << BaseE->getSourceRange()
+        << ScopeTypeInfo->getTypeLoc().getSourceRange();
+  
+      ScopeType = QualType();
+      ScopeTypeInfo = 0;
+    }
+  }
+  
+  OwningExprResult Result
+    = Owned(new (Context) CXXPseudoDestructorExpr(Context, 
+                                                  Base.takeAs<Expr>(),
+                                                  OpKind == tok::arrow,
+                                                  OpLoc,
+                                       (NestedNameSpecifier *) SS.getScopeRep(),
+                                                  SS.getRange(),
+                                                  ScopeTypeInfo,
+                                                  CCLoc,
+                                                  TildeLoc,
+                                                  Destructed));
+            
+  if (HasTrailingLParen)
+    return move(Result);
+  
+  return DiagnoseDtorReference(Destructed.getLocation(), move(Result));
+}
+
+Sema::OwningExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, ExprArg Base,
+                                                       SourceLocation OpLoc,
+                                                       tok::TokenKind OpKind,
+                                                       CXXScopeSpec &SS,
+                                                  UnqualifiedId &FirstTypeName,
+                                                       SourceLocation CCLoc,
+                                                       SourceLocation TildeLoc,
+                                                 UnqualifiedId &SecondTypeName,
+                                                       bool HasTrailingLParen) {
+  assert((FirstTypeName.getKind() == UnqualifiedId::IK_TemplateId ||
+          FirstTypeName.getKind() == UnqualifiedId::IK_Identifier) &&
+         "Invalid first type name in pseudo-destructor");
+  assert((SecondTypeName.getKind() == UnqualifiedId::IK_TemplateId ||
+          SecondTypeName.getKind() == UnqualifiedId::IK_Identifier) &&
+         "Invalid second type name in pseudo-destructor");
+
+  Expr *BaseE = (Expr *)Base.get();
+  
+  // C++ [expr.pseudo]p2:
+  //   The left-hand side of the dot operator shall be of scalar type. The 
+  //   left-hand side of the arrow operator shall be of pointer to scalar type.
+  //   This scalar type is the object type. 
+  QualType ObjectType = BaseE->getType();
+  if (OpKind == tok::arrow) {
+    if (const PointerType *Ptr = ObjectType->getAs<PointerType>()) {
+      ObjectType = Ptr->getPointeeType();
+    } else if (!ObjectType->isDependentType()) {
+      // The user wrote "p->" when she probably meant "p."; fix it.
+      Diag(OpLoc, diag::err_typecheck_member_reference_suggestion)
+        << ObjectType << true
+        << FixItHint::CreateReplacement(OpLoc, ".");
+      if (isSFINAEContext())
+        return ExprError();
+      
+      OpKind = tok::period;
+    }
+  }
+
+  // Compute the object type that we should use for name lookup purposes. Only
+  // record types and dependent types matter.
+  void *ObjectTypePtrForLookup = 0;
+  if (!SS.isSet()) {
+    ObjectTypePtrForLookup = (void *)ObjectType->getAs<RecordType>();
+    if (!ObjectTypePtrForLookup && ObjectType->isDependentType())
+      ObjectTypePtrForLookup = Context.DependentTy.getAsOpaquePtr();
+  }
+  
+  // Convert the name of the type being destructed (following the ~) into a 
+  // type (with source-location information).
+  QualType DestructedType;
+  TypeSourceInfo *DestructedTypeInfo = 0;
+  PseudoDestructorTypeStorage Destructed;
+  if (SecondTypeName.getKind() == UnqualifiedId::IK_Identifier) {
+    TypeTy *T = getTypeName(*SecondTypeName.Identifier, 
+                            SecondTypeName.StartLocation,
+                            S, &SS, true, ObjectTypePtrForLookup);
+    if (!T && 
+        ((SS.isSet() && !computeDeclContext(SS, false)) ||
+         (!SS.isSet() && ObjectType->isDependentType()))) {
+      // The name of the type being destroyed is a dependent name, and we 
+      // couldn't find anything useful in scope. Just store the identifier and
+      // it's location, and we'll perform (qualified) name lookup again at
+      // template instantiation time.
+      Destructed = PseudoDestructorTypeStorage(SecondTypeName.Identifier,
+                                               SecondTypeName.StartLocation);
+    } else if (!T) {
+      Diag(SecondTypeName.StartLocation, 
+           diag::err_pseudo_dtor_destructor_non_type)
+        << SecondTypeName.Identifier << ObjectType;
+      if (isSFINAEContext())
+        return ExprError();
+      
+      // Recover by assuming we had the right type all along.
+      DestructedType = ObjectType;
+    } else
+      DestructedType = GetTypeFromParser(T, &DestructedTypeInfo);
+  } else {
+    // Resolve the template-id to a type.
+    TemplateIdAnnotation *TemplateId = SecondTypeName.TemplateId;
+    ASTTemplateArgsPtr TemplateArgsPtr(*this,
+                                       TemplateId->getTemplateArgs(),
+                                       TemplateId->NumArgs);
+    TypeResult T = ActOnTemplateIdType(TemplateTy::make(TemplateId->Template),
+                                       TemplateId->TemplateNameLoc,
+                                       TemplateId->LAngleLoc,
+                                       TemplateArgsPtr,
+                                       TemplateId->RAngleLoc);
+    if (T.isInvalid() || !T.get()) {
+      // Recover by assuming we had the right type all along.
+      DestructedType = ObjectType;
+    } else
+      DestructedType = GetTypeFromParser(T.get(), &DestructedTypeInfo);
+  }
+  
+  // If we've performed some kind of recovery, (re-)build the type source 
+  // information.
+  if (!DestructedType.isNull()) {
+    if (!DestructedTypeInfo)
+      DestructedTypeInfo = Context.getTrivialTypeSourceInfo(DestructedType,
+                                                  SecondTypeName.StartLocation);
+    Destructed = PseudoDestructorTypeStorage(DestructedTypeInfo);
+  }
+  
+  // Convert the name of the scope type (the type prior to '::') into a type.
+  TypeSourceInfo *ScopeTypeInfo = 0;
+  QualType ScopeType;
+  if (FirstTypeName.getKind() == UnqualifiedId::IK_TemplateId || 
+      FirstTypeName.Identifier) {
+    if (FirstTypeName.getKind() == UnqualifiedId::IK_Identifier) {
+      TypeTy *T = getTypeName(*FirstTypeName.Identifier, 
+                              FirstTypeName.StartLocation,
+                              S, &SS, false, ObjectTypePtrForLookup);
+      if (!T) {
+        Diag(FirstTypeName.StartLocation, 
+             diag::err_pseudo_dtor_destructor_non_type)
+          << FirstTypeName.Identifier << ObjectType;
+        
+        if (isSFINAEContext())
+          return ExprError();
+        
+        // Just drop this type. It's unnecessary anyway.
+        ScopeType = QualType();
+      } else
+        ScopeType = GetTypeFromParser(T, &ScopeTypeInfo);
+    } else {
+      // Resolve the template-id to a type.
+      TemplateIdAnnotation *TemplateId = FirstTypeName.TemplateId;
+      ASTTemplateArgsPtr TemplateArgsPtr(*this,
+                                         TemplateId->getTemplateArgs(),
+                                         TemplateId->NumArgs);
+      TypeResult T = ActOnTemplateIdType(TemplateTy::make(TemplateId->Template),
+                                         TemplateId->TemplateNameLoc,
+                                         TemplateId->LAngleLoc,
+                                         TemplateArgsPtr,
+                                         TemplateId->RAngleLoc);
+      if (T.isInvalid() || !T.get()) {
+        // Recover by dropping this type.
+        ScopeType = QualType();
+      } else
+        ScopeType = GetTypeFromParser(T.get(), &ScopeTypeInfo);      
+    }
+  }
+      
+  if (!ScopeType.isNull() && !ScopeTypeInfo)
+    ScopeTypeInfo = Context.getTrivialTypeSourceInfo(ScopeType,
+                                                  FirstTypeName.StartLocation);
+
+    
+  return BuildPseudoDestructorExpr(move(Base), OpLoc, OpKind, SS,
+                                   ScopeTypeInfo, CCLoc, TildeLoc,
+                                   Destructed, HasTrailingLParen);
+}
+
+CXXMemberCallExpr *Sema::BuildCXXMemberCallExpr(Expr *Exp, 
+                                                NamedDecl *FoundDecl,
+                                                CXXMethodDecl *Method) {
+  if (PerformObjectArgumentInitialization(Exp, /*Qualifier=*/0,
+                                          FoundDecl, Method))
+    assert(0 && "Calling BuildCXXMemberCallExpr with invalid call?");
+
+  MemberExpr *ME = 
+      new (Context) MemberExpr(Exp, /*IsArrow=*/false, Method, 
+                               SourceLocation(), Method->getType());
+  QualType ResultType = Method->getResultType().getNonReferenceType();
+  MarkDeclarationReferenced(Exp->getLocStart(), Method);
+  CXXMemberCallExpr *CE =
+    new (Context) CXXMemberCallExpr(Context, ME, 0, 0, ResultType,
+                                    Exp->getLocEnd());
+  return CE;
+}
+
+Sema::OwningExprResult Sema::ActOnFinishFullExpr(ExprArg Arg) {
+  Expr *FullExpr = Arg.takeAs<Expr>();
+  if (FullExpr)
+    FullExpr = MaybeCreateCXXExprWithTemporaries(FullExpr);
+
+  return Owned(FullExpr);
+}
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp
new file mode 100644
index 0000000..db9a2e2
--- /dev/null
+++ b/lib/Sema/SemaExprObjC.cpp
@@ -0,0 +1,1025 @@
+//===--- SemaExprObjC.cpp - Semantic Analysis for ObjC Expressions --------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements semantic analysis for Objective-C expressions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Sema.h"
+#include "Lookup.h"
+#include "SemaInit.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/ExprObjC.h"
+#include "clang/AST/TypeLoc.h"
+#include "llvm/ADT/SmallString.h"
+#include "clang/Lex/Preprocessor.h"
+
+using namespace clang;
+
+Sema::ExprResult Sema::ParseObjCStringLiteral(SourceLocation *AtLocs,
+                                              ExprTy **strings,
+                                              unsigned NumStrings) {
+  StringLiteral **Strings = reinterpret_cast<StringLiteral**>(strings);
+
+  // Most ObjC strings are formed out of a single piece.  However, we *can*
+  // have strings formed out of multiple @ strings with multiple pptokens in
+  // each one, e.g. @"foo" "bar" @"baz" "qux"   which need to be turned into one
+  // StringLiteral for ObjCStringLiteral to hold onto.
+  StringLiteral *S = Strings[0];
+
+  // If we have a multi-part string, merge it all together.
+  if (NumStrings != 1) {
+    // Concatenate objc strings.
+    llvm::SmallString<128> StrBuf;
+    llvm::SmallVector<SourceLocation, 8> StrLocs;
+
+    for (unsigned i = 0; i != NumStrings; ++i) {
+      S = Strings[i];
+
+      // ObjC strings can't be wide.
+      if (S->isWide()) {
+        Diag(S->getLocStart(), diag::err_cfstring_literal_not_string_constant)
+          << S->getSourceRange();
+        return true;
+      }
+
+      // Get the string data.
+      StrBuf.append(S->getStrData(), S->getStrData()+S->getByteLength());
+
+      // Get the locations of the string tokens.
+      StrLocs.append(S->tokloc_begin(), S->tokloc_end());
+
+      // Free the temporary string.
+      S->Destroy(Context);
+    }
+
+    // Create the aggregate string with the appropriate content and location
+    // information.
+    S = StringLiteral::Create(Context, &StrBuf[0], StrBuf.size(), false,
+                              Context.getPointerType(Context.CharTy),
+                              &StrLocs[0], StrLocs.size());
+  }
+
+  // Verify that this composite string is acceptable for ObjC strings.
+  if (CheckObjCString(S))
+    return true;
+
+  // Initialize the constant string interface lazily. This assumes
+  // the NSString interface is seen in this translation unit. Note: We
+  // don't use NSConstantString, since the runtime team considers this
+  // interface private (even though it appears in the header files).
+  QualType Ty = Context.getObjCConstantStringInterface();
+  if (!Ty.isNull()) {
+    Ty = Context.getObjCObjectPointerType(Ty);
+  } else if (getLangOptions().NoConstantCFStrings) {
+    IdentifierInfo *NSIdent = &Context.Idents.get("NSConstantString");
+    NamedDecl *IF = LookupSingleName(TUScope, NSIdent, AtLocs[0],
+                                     LookupOrdinaryName);
+    if (ObjCInterfaceDecl *StrIF = dyn_cast_or_null<ObjCInterfaceDecl>(IF)) {
+      Context.setObjCConstantStringInterface(StrIF);
+      Ty = Context.getObjCConstantStringInterface();
+      Ty = Context.getObjCObjectPointerType(Ty);
+    } else {
+      // If there is no NSConstantString interface defined then treat this
+      // as error and recover from it.
+      Diag(S->getLocStart(), diag::err_no_nsconstant_string_class) << NSIdent
+        << S->getSourceRange();
+      Ty = Context.getObjCIdType();
+    }
+  } else {
+    IdentifierInfo *NSIdent = &Context.Idents.get("NSString");
+    NamedDecl *IF = LookupSingleName(TUScope, NSIdent, AtLocs[0],
+                                     LookupOrdinaryName);
+    if (ObjCInterfaceDecl *StrIF = dyn_cast_or_null<ObjCInterfaceDecl>(IF)) {
+      Context.setObjCConstantStringInterface(StrIF);
+      Ty = Context.getObjCConstantStringInterface();
+      Ty = Context.getObjCObjectPointerType(Ty);
+    } else {
+      // If there is no NSString interface defined then treat constant
+      // strings as untyped objects and let the runtime figure it out later.
+      Ty = Context.getObjCIdType();
+    }
+  }
+
+  return new (Context) ObjCStringLiteral(S, Ty, AtLocs[0]);
+}
+
+Expr *Sema::BuildObjCEncodeExpression(SourceLocation AtLoc,
+                                      TypeSourceInfo *EncodedTypeInfo,
+                                      SourceLocation RParenLoc) {
+  QualType EncodedType = EncodedTypeInfo->getType();
+  QualType StrTy;
+  if (EncodedType->isDependentType())
+    StrTy = Context.DependentTy;
+  else {
+    std::string Str;
+    Context.getObjCEncodingForType(EncodedType, Str);
+
+    // The type of @encode is the same as the type of the corresponding string,
+    // which is an array type.
+    StrTy = Context.CharTy;
+    // A C++ string literal has a const-qualified element type (C++ 2.13.4p1).
+    if (getLangOptions().CPlusPlus || getLangOptions().ConstStrings)
+      StrTy.addConst();
+    StrTy = Context.getConstantArrayType(StrTy, llvm::APInt(32, Str.size()+1),
+                                         ArrayType::Normal, 0);
+  }
+
+  return new (Context) ObjCEncodeExpr(StrTy, EncodedTypeInfo, AtLoc, RParenLoc);
+}
+
+Sema::ExprResult Sema::ParseObjCEncodeExpression(SourceLocation AtLoc,
+                                                 SourceLocation EncodeLoc,
+                                                 SourceLocation LParenLoc,
+                                                 TypeTy *ty,
+                                                 SourceLocation RParenLoc) {
+  // FIXME: Preserve type source info ?
+  TypeSourceInfo *TInfo;
+  QualType EncodedType = GetTypeFromParser(ty, &TInfo);
+  if (!TInfo)
+    TInfo = Context.getTrivialTypeSourceInfo(EncodedType,
+                                             PP.getLocForEndOfToken(LParenLoc));
+
+  return BuildObjCEncodeExpression(AtLoc, TInfo, RParenLoc);
+}
+
+Sema::ExprResult Sema::ParseObjCSelectorExpression(Selector Sel,
+                                                   SourceLocation AtLoc,
+                                                   SourceLocation SelLoc,
+                                                   SourceLocation LParenLoc,
+                                                   SourceLocation RParenLoc) {
+  ObjCMethodDecl *Method = LookupInstanceMethodInGlobalPool(Sel,
+                             SourceRange(LParenLoc, RParenLoc), false);
+  if (!Method)
+    Method = LookupFactoryMethodInGlobalPool(Sel,
+                                          SourceRange(LParenLoc, RParenLoc));
+  if (!Method)
+    Diag(SelLoc, diag::warn_undeclared_selector) << Sel;
+
+  QualType Ty = Context.getObjCSelType();
+  return new (Context) ObjCSelectorExpr(Ty, Sel, AtLoc, RParenLoc);
+}
+
+Sema::ExprResult Sema::ParseObjCProtocolExpression(IdentifierInfo *ProtocolId,
+                                                   SourceLocation AtLoc,
+                                                   SourceLocation ProtoLoc,
+                                                   SourceLocation LParenLoc,
+                                                   SourceLocation RParenLoc) {
+  ObjCProtocolDecl* PDecl = LookupProtocol(ProtocolId, ProtoLoc);
+  if (!PDecl) {
+    Diag(ProtoLoc, diag::err_undeclared_protocol) << ProtocolId;
+    return true;
+  }
+
+  QualType Ty = Context.getObjCProtoType();
+  if (Ty.isNull())
+    return true;
+  Ty = Context.getObjCObjectPointerType(Ty);
+  return new (Context) ObjCProtocolExpr(Ty, PDecl, AtLoc, RParenLoc);
+}
+
+bool Sema::CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs,
+                                     Selector Sel, ObjCMethodDecl *Method,
+                                     bool isClassMessage,
+                                     SourceLocation lbrac, SourceLocation rbrac,
+                                     QualType &ReturnType) {
+  if (!Method) {
+    // Apply default argument promotion as for (C99 6.5.2.2p6).
+    for (unsigned i = 0; i != NumArgs; i++) {
+      if (Args[i]->isTypeDependent())
+        continue;
+
+      DefaultArgumentPromotion(Args[i]);
+    }
+
+    unsigned DiagID = isClassMessage ? diag::warn_class_method_not_found :
+                                       diag::warn_inst_method_not_found;
+    Diag(lbrac, DiagID)
+      << Sel << isClassMessage << SourceRange(lbrac, rbrac);
+    ReturnType = Context.getObjCIdType();
+    return false;
+  }
+
+  ReturnType = Method->getResultType().getNonReferenceType();
+
+  unsigned NumNamedArgs = Sel.getNumArgs();
+  // Method might have more arguments than selector indicates. This is due
+  // to addition of c-style arguments in method.
+  if (Method->param_size() > Sel.getNumArgs())
+    NumNamedArgs = Method->param_size();
+  // FIXME. This need be cleaned up.
+  if (NumArgs < NumNamedArgs) {
+    Diag(lbrac, diag::err_typecheck_call_too_few_args) << 2
+    << NumNamedArgs << NumArgs;
+    return false;
+  }
+
+  bool IsError = false;
+  for (unsigned i = 0; i < NumNamedArgs; i++) {
+    // We can't do any type-checking on a type-dependent argument.
+    if (Args[i]->isTypeDependent())
+      continue;
+
+    Expr *argExpr = Args[i];
+
+    ParmVarDecl *Param = Method->param_begin()[i];
+    assert(argExpr && "CheckMessageArgumentTypes(): missing expression");
+
+    if (RequireCompleteType(argExpr->getSourceRange().getBegin(),
+                            Param->getType(),
+                            PDiag(diag::err_call_incomplete_argument)
+                              << argExpr->getSourceRange()))
+      return true;
+
+    InitializedEntity Entity = InitializedEntity::InitializeParameter(Param);
+    OwningExprResult ArgE = PerformCopyInitialization(Entity,
+                                                      SourceLocation(),
+                                                      Owned(argExpr->Retain()));
+    if (ArgE.isInvalid())
+      IsError = true;
+    else
+      Args[i] = ArgE.takeAs<Expr>();
+  }
+
+  // Promote additional arguments to variadic methods.
+  if (Method->isVariadic()) {
+    for (unsigned i = NumNamedArgs; i < NumArgs; ++i) {
+      if (Args[i]->isTypeDependent())
+        continue;
+
+      IsError |= DefaultVariadicArgumentPromotion(Args[i], VariadicMethod);
+    }
+  } else {
+    // Check for extra arguments to non-variadic methods.
+    if (NumArgs != NumNamedArgs) {
+      Diag(Args[NumNamedArgs]->getLocStart(),
+           diag::err_typecheck_call_too_many_args)
+        << 2 /*method*/ << NumNamedArgs << NumArgs
+        << Method->getSourceRange()
+        << SourceRange(Args[NumNamedArgs]->getLocStart(),
+                       Args[NumArgs-1]->getLocEnd());
+    }
+  }
+
+  DiagnoseSentinelCalls(Method, lbrac, Args, NumArgs);
+  return IsError;
+}
+
+bool Sema::isSelfExpr(Expr *RExpr) {
+  if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(RExpr))
+    if (DRE->getDecl()->getIdentifier() == &Context.Idents.get("self"))
+      return true;
+  return false;
+}
+
+// Helper method for ActOnClassMethod/ActOnInstanceMethod.
+// Will search "local" class/category implementations for a method decl.
+// If failed, then we search in class's root for an instance method.
+// Returns 0 if no method is found.
+ObjCMethodDecl *Sema::LookupPrivateClassMethod(Selector Sel,
+                                          ObjCInterfaceDecl *ClassDecl) {
+  ObjCMethodDecl *Method = 0;
+  // lookup in class and all superclasses
+  while (ClassDecl && !Method) {
+    if (ObjCImplementationDecl *ImpDecl = ClassDecl->getImplementation())
+      Method = ImpDecl->getClassMethod(Sel);
+
+    // Look through local category implementations associated with the class.
+    if (!Method)
+      Method = ClassDecl->getCategoryClassMethod(Sel);
+
+    // Before we give up, check if the selector is an instance method.
+    // But only in the root. This matches gcc's behaviour and what the
+    // runtime expects.
+    if (!Method && !ClassDecl->getSuperClass()) {
+      Method = ClassDecl->lookupInstanceMethod(Sel);
+      // Look through local category implementations associated
+      // with the root class.
+      if (!Method)
+        Method = LookupPrivateInstanceMethod(Sel, ClassDecl);
+    }
+
+    ClassDecl = ClassDecl->getSuperClass();
+  }
+  return Method;
+}
+
+ObjCMethodDecl *Sema::LookupPrivateInstanceMethod(Selector Sel,
+                                              ObjCInterfaceDecl *ClassDecl) {
+  ObjCMethodDecl *Method = 0;
+  while (ClassDecl && !Method) {
+    // If we have implementations in scope, check "private" methods.
+    if (ObjCImplementationDecl *ImpDecl = ClassDecl->getImplementation())
+      Method = ImpDecl->getInstanceMethod(Sel);
+
+    // Look through local category implementations associated with the class.
+    if (!Method)
+      Method = ClassDecl->getCategoryInstanceMethod(Sel);
+    ClassDecl = ClassDecl->getSuperClass();
+  }
+  return Method;
+}
+
+/// HandleExprPropertyRefExpr - Handle foo.bar where foo is a pointer to an
+/// objective C interface.  This is a property reference expression.
+Action::OwningExprResult Sema::
+HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT,
+                          Expr *BaseExpr, DeclarationName MemberName,
+                          SourceLocation MemberLoc) {
+  const ObjCInterfaceType *IFaceT = OPT->getInterfaceType();
+  ObjCInterfaceDecl *IFace = IFaceT->getDecl();
+  IdentifierInfo *Member = MemberName.getAsIdentifierInfo();
+
+  // Search for a declared property first.
+  if (ObjCPropertyDecl *PD = IFace->FindPropertyDeclaration(Member)) {
+    // Check whether we can reference this property.
+    if (DiagnoseUseOfDecl(PD, MemberLoc))
+      return ExprError();
+    QualType ResTy = PD->getType();
+    Selector Sel = PP.getSelectorTable().getNullarySelector(Member);
+    ObjCMethodDecl *Getter = IFace->lookupInstanceMethod(Sel);
+    if (DiagnosePropertyAccessorMismatch(PD, Getter, MemberLoc))
+      ResTy = Getter->getResultType();
+    return Owned(new (Context) ObjCPropertyRefExpr(PD, ResTy,
+                                                   MemberLoc, BaseExpr));
+  }
+  // Check protocols on qualified interfaces.
+  for (ObjCObjectPointerType::qual_iterator I = OPT->qual_begin(),
+       E = OPT->qual_end(); I != E; ++I)
+    if (ObjCPropertyDecl *PD = (*I)->FindPropertyDeclaration(Member)) {
+      // Check whether we can reference this property.
+      if (DiagnoseUseOfDecl(PD, MemberLoc))
+        return ExprError();
+
+      return Owned(new (Context) ObjCPropertyRefExpr(PD, PD->getType(),
+                                                     MemberLoc, BaseExpr));
+    }
+  // If that failed, look for an "implicit" property by seeing if the nullary
+  // selector is implemented.
+
+  // FIXME: The logic for looking up nullary and unary selectors should be
+  // shared with the code in ActOnInstanceMessage.
+
+  Selector Sel = PP.getSelectorTable().getNullarySelector(Member);
+  ObjCMethodDecl *Getter = IFace->lookupInstanceMethod(Sel);
+
+  // If this reference is in an @implementation, check for 'private' methods.
+  if (!Getter)
+    Getter = IFace->lookupPrivateInstanceMethod(Sel);
+
+  // Look through local category implementations associated with the class.
+  if (!Getter)
+    Getter = IFace->getCategoryInstanceMethod(Sel);
+  if (Getter) {
+    // Check if we can reference this property.
+    if (DiagnoseUseOfDecl(Getter, MemberLoc))
+      return ExprError();
+  }
+  // If we found a getter then this may be a valid dot-reference, we
+  // will look for the matching setter, in case it is needed.
+  Selector SetterSel =
+    SelectorTable::constructSetterName(PP.getIdentifierTable(),
+                                       PP.getSelectorTable(), Member);
+  ObjCMethodDecl *Setter = IFace->lookupInstanceMethod(SetterSel);
+  if (!Setter) {
+    // If this reference is in an @implementation, also check for 'private'
+    // methods.
+    Setter = IFace->lookupPrivateInstanceMethod(SetterSel);
+  }
+  // Look through local category implementations associated with the class.
+  if (!Setter)
+    Setter = IFace->getCategoryInstanceMethod(SetterSel);
+
+  if (Setter && DiagnoseUseOfDecl(Setter, MemberLoc))
+    return ExprError();
+
+  if (Getter) {
+    QualType PType;
+    PType = Getter->getResultType();
+    return Owned(new (Context) ObjCImplicitSetterGetterRefExpr(Getter, PType,
+                                    Setter, MemberLoc, BaseExpr));
+  }
+
+  // Attempt to correct for typos in property names.
+  LookupResult Res(*this, MemberName, MemberLoc, LookupOrdinaryName);
+  if (CorrectTypo(Res, 0, 0, IFace, false, CTC_NoKeywords, OPT) &&
+      Res.getAsSingle<ObjCPropertyDecl>()) {
+    DeclarationName TypoResult = Res.getLookupName();
+    Diag(MemberLoc, diag::err_property_not_found_suggest)
+      << MemberName << QualType(OPT, 0) << TypoResult
+      << FixItHint::CreateReplacement(MemberLoc, TypoResult.getAsString());
+    ObjCPropertyDecl *Property = Res.getAsSingle<ObjCPropertyDecl>();
+    Diag(Property->getLocation(), diag::note_previous_decl)
+      << Property->getDeclName();
+    return HandleExprPropertyRefExpr(OPT, BaseExpr, TypoResult, MemberLoc);
+  }
+  
+  Diag(MemberLoc, diag::err_property_not_found)
+    << MemberName << QualType(OPT, 0);
+  if (Setter && !Getter)
+    Diag(Setter->getLocation(), diag::note_getter_unavailable)
+      << MemberName << BaseExpr->getSourceRange();
+  return ExprError();
+}
+
+
+
+Action::OwningExprResult Sema::
+ActOnClassPropertyRefExpr(IdentifierInfo &receiverName,
+                          IdentifierInfo &propertyName,
+                          SourceLocation receiverNameLoc,
+                          SourceLocation propertyNameLoc) {
+
+  IdentifierInfo *receiverNamePtr = &receiverName;
+  ObjCInterfaceDecl *IFace = getObjCInterfaceDecl(receiverNamePtr,
+                                                  receiverNameLoc);
+  if (IFace == 0) {
+    // If the "receiver" is 'super' in a method, handle it as an expression-like
+    // property reference.
+    if (ObjCMethodDecl *CurMethod = getCurMethodDecl())
+      if (receiverNamePtr->isStr("super")) {
+        if (CurMethod->isInstanceMethod()) {
+          QualType T = 
+            Context.getObjCInterfaceType(CurMethod->getClassInterface());
+          T = Context.getObjCObjectPointerType(T);
+          Expr *SuperExpr = new (Context) ObjCSuperExpr(receiverNameLoc, T);
+        
+          return HandleExprPropertyRefExpr(T->getAsObjCInterfacePointerType(),
+                                           SuperExpr, &propertyName,
+                                           propertyNameLoc);
+        }
+
+        // Otherwise, if this is a class method, try dispatching to our
+        // superclass.
+        IFace = CurMethod->getClassInterface()->getSuperClass();
+      }
+    
+    if (IFace == 0) {
+      Diag(receiverNameLoc, diag::err_expected_ident_or_lparen);
+      return ExprError();
+    }
+  }
+
+  // Search for a declared property first.
+  Selector Sel = PP.getSelectorTable().getNullarySelector(&propertyName);
+  ObjCMethodDecl *Getter = IFace->lookupClassMethod(Sel);
+
+  // If this reference is in an @implementation, check for 'private' methods.
+  if (!Getter)
+    if (ObjCMethodDecl *CurMeth = getCurMethodDecl())
+      if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface())
+        if (ObjCImplementationDecl *ImpDecl = ClassDecl->getImplementation())
+          Getter = ImpDecl->getClassMethod(Sel);
+
+  if (Getter) {
+    // FIXME: refactor/share with ActOnMemberReference().
+    // Check if we can reference this property.
+    if (DiagnoseUseOfDecl(Getter, propertyNameLoc))
+      return ExprError();
+  }
+
+  // Look for the matching setter, in case it is needed.
+  Selector SetterSel =
+    SelectorTable::constructSetterName(PP.getIdentifierTable(),
+                                       PP.getSelectorTable(), &propertyName);
+
+  ObjCMethodDecl *Setter = IFace->lookupClassMethod(SetterSel);
+  if (!Setter) {
+    // If this reference is in an @implementation, also check for 'private'
+    // methods.
+    if (ObjCMethodDecl *CurMeth = getCurMethodDecl())
+      if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface())
+        if (ObjCImplementationDecl *ImpDecl = ClassDecl->getImplementation())
+          Setter = ImpDecl->getClassMethod(SetterSel);
+  }
+  // Look through local category implementations associated with the class.
+  if (!Setter)
+    Setter = IFace->getCategoryClassMethod(SetterSel);
+
+  if (Setter && DiagnoseUseOfDecl(Setter, propertyNameLoc))
+    return ExprError();
+
+  if (Getter || Setter) {
+    QualType PType;
+
+    if (Getter)
+      PType = Getter->getResultType();
+    else {
+      for (ObjCMethodDecl::param_iterator PI = Setter->param_begin(),
+           E = Setter->param_end(); PI != E; ++PI)
+        PType = (*PI)->getType();
+    }
+    return Owned(new (Context) ObjCImplicitSetterGetterRefExpr(
+                                  Getter, PType, Setter,
+                                  propertyNameLoc, IFace, receiverNameLoc));
+  }
+  return ExprError(Diag(propertyNameLoc, diag::err_property_not_found)
+                     << &propertyName << Context.getObjCInterfaceType(IFace));
+}
+
+Sema::ObjCMessageKind Sema::getObjCMessageKind(Scope *S,
+                                               IdentifierInfo *Name,
+                                               SourceLocation NameLoc,
+                                               bool IsSuper,
+                                               bool HasTrailingDot,
+                                               TypeTy *&ReceiverType) {
+  ReceiverType = 0;
+
+  // If the identifier is "super" and there is no trailing dot, we're
+  // messaging super.
+  if (IsSuper && !HasTrailingDot && S->isInObjcMethodScope())
+    return ObjCSuperMessage;
+  
+  LookupResult Result(*this, Name, NameLoc, LookupOrdinaryName);
+  LookupName(Result, S);
+  
+  switch (Result.getResultKind()) {
+  case LookupResult::NotFound:
+    // Normal name lookup didn't find anything. If we're in an
+    // Objective-C method, look for ivars. If we find one, we're done!
+    // FIXME: This is a hack. Ivar lookup should be part of normal lookup.
+    if (ObjCMethodDecl *Method = getCurMethodDecl()) {
+      ObjCInterfaceDecl *ClassDeclared;
+      if (Method->getClassInterface()->lookupInstanceVariable(Name, 
+                                                              ClassDeclared))
+        return ObjCInstanceMessage;
+    }
+      
+    // Break out; we'll perform typo correction below.
+    break;
+
+  case LookupResult::NotFoundInCurrentInstantiation:
+  case LookupResult::FoundOverloaded:
+  case LookupResult::FoundUnresolvedValue:
+  case LookupResult::Ambiguous:
+    Result.suppressDiagnostics();
+    return ObjCInstanceMessage;
+
+  case LookupResult::Found: {
+    // We found something. If it's a type, then we have a class
+    // message. Otherwise, it's an instance message.
+    NamedDecl *ND = Result.getFoundDecl();
+    QualType T;
+    if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(ND))
+      T = Context.getObjCInterfaceType(Class);
+    else if (TypeDecl *Type = dyn_cast<TypeDecl>(ND))
+      T = Context.getTypeDeclType(Type);
+    else 
+      return ObjCInstanceMessage;
+
+    //  We have a class message, and T is the type we're
+    //  messaging. Build source-location information for it.
+    TypeSourceInfo *TSInfo = Context.getTrivialTypeSourceInfo(T, NameLoc);
+    ReceiverType = CreateLocInfoType(T, TSInfo).getAsOpaquePtr();
+    return ObjCClassMessage;
+  }
+  }
+
+  // Determine our typo-correction context.
+  CorrectTypoContext CTC = CTC_Expression;
+  if (ObjCMethodDecl *Method = getCurMethodDecl())
+    if (Method->getClassInterface() &&
+        Method->getClassInterface()->getSuperClass())
+      CTC = CTC_ObjCMessageReceiver;
+      
+  if (DeclarationName Corrected = CorrectTypo(Result, S, 0, 0, false, CTC)) {
+    if (Result.isSingleResult()) {
+      // If we found a declaration, correct when it refers to an Objective-C
+      // class.
+      NamedDecl *ND = Result.getFoundDecl();
+      if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(ND)) {
+        Diag(NameLoc, diag::err_unknown_receiver_suggest)
+          << Name << Result.getLookupName()
+          << FixItHint::CreateReplacement(SourceRange(NameLoc),
+                                          ND->getNameAsString());
+        Diag(ND->getLocation(), diag::note_previous_decl)
+          << Corrected;
+
+        QualType T = Context.getObjCInterfaceType(Class);
+        TypeSourceInfo *TSInfo = Context.getTrivialTypeSourceInfo(T, NameLoc);
+        ReceiverType = CreateLocInfoType(T, TSInfo).getAsOpaquePtr();
+        return ObjCClassMessage;
+      }
+    } else if (Result.empty() && Corrected.getAsIdentifierInfo() &&
+               Corrected.getAsIdentifierInfo()->isStr("super")) {
+      // If we've found the keyword "super", this is a send to super.
+      Diag(NameLoc, diag::err_unknown_receiver_suggest)
+        << Name << Corrected
+        << FixItHint::CreateReplacement(SourceRange(NameLoc), "super");
+      Name = Corrected.getAsIdentifierInfo();
+      return ObjCSuperMessage;
+    }
+  }
+  
+  // Fall back: let the parser try to parse it as an instance message.
+  return ObjCInstanceMessage;
+}
+
+Sema::OwningExprResult Sema::ActOnSuperMessage(Scope *S, 
+                                               SourceLocation SuperLoc,
+                                               Selector Sel,
+                                               SourceLocation LBracLoc,
+                                               SourceLocation SelectorLoc,
+                                               SourceLocation RBracLoc,
+                                               MultiExprArg Args) {
+  // Determine whether we are inside a method or not.
+  ObjCMethodDecl *Method = getCurMethodDecl();
+  if (!Method) {
+    Diag(SuperLoc, diag::err_invalid_receiver_to_message_super);
+    return ExprError();
+  }
+
+  ObjCInterfaceDecl *Class = Method->getClassInterface();
+  if (!Class) {
+    Diag(SuperLoc, diag::error_no_super_class_message)
+      << Method->getDeclName();
+    return ExprError();
+  }
+
+  ObjCInterfaceDecl *Super = Class->getSuperClass();
+  if (!Super) {
+    // The current class does not have a superclass.
+    Diag(SuperLoc, diag::error_no_super_class) << Class->getIdentifier();
+    return ExprError();
+  }
+
+  // We are in a method whose class has a superclass, so 'super'
+  // is acting as a keyword.
+  if (Method->isInstanceMethod()) {
+    // Since we are in an instance method, this is an instance
+    // message to the superclass instance.
+    QualType SuperTy = Context.getObjCInterfaceType(Super);
+    SuperTy = Context.getObjCObjectPointerType(SuperTy);
+    return BuildInstanceMessage(ExprArg(*this), SuperTy, SuperLoc,
+                                Sel, /*Method=*/0, LBracLoc, RBracLoc, 
+                                move(Args));
+  }
+  
+  // Since we are in a class method, this is a class message to
+  // the superclass.
+  return BuildClassMessage(/*ReceiverTypeInfo=*/0,
+                           Context.getObjCInterfaceType(Super),
+                           SuperLoc, Sel, /*Method=*/0, LBracLoc, RBracLoc, 
+                           move(Args));
+}
+
+/// \brief Build an Objective-C class message expression.
+///
+/// This routine takes care of both normal class messages and
+/// class messages to the superclass.
+///
+/// \param ReceiverTypeInfo Type source information that describes the
+/// receiver of this message. This may be NULL, in which case we are
+/// sending to the superclass and \p SuperLoc must be a valid source
+/// location.
+
+/// \param ReceiverType The type of the object receiving the
+/// message. When \p ReceiverTypeInfo is non-NULL, this is the same
+/// type as that refers to. For a superclass send, this is the type of
+/// the superclass.
+///
+/// \param SuperLoc The location of the "super" keyword in a
+/// superclass message.
+///
+/// \param Sel The selector to which the message is being sent.
+///
+/// \param Method The method that this class message is invoking, if
+/// already known.
+///
+/// \param LBracLoc The location of the opening square bracket ']'.
+///
+/// \param RBrac The location of the closing square bracket ']'.
+///
+/// \param Args The message arguments.
+Sema::OwningExprResult Sema::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo,
+                                               QualType ReceiverType,
+                                               SourceLocation SuperLoc,
+                                               Selector Sel,
+                                               ObjCMethodDecl *Method,
+                                               SourceLocation LBracLoc, 
+                                               SourceLocation RBracLoc,
+                                               MultiExprArg ArgsIn) {
+  if (ReceiverType->isDependentType()) {
+    // If the receiver type is dependent, we can't type-check anything
+    // at this point. Build a dependent expression.
+    unsigned NumArgs = ArgsIn.size();
+    Expr **Args = reinterpret_cast<Expr **>(ArgsIn.release());
+    assert(SuperLoc.isInvalid() && "Message to super with dependent type");
+    return Owned(ObjCMessageExpr::Create(Context, ReceiverType, LBracLoc,
+                                         ReceiverTypeInfo, Sel, /*Method=*/0, 
+                                         Args, NumArgs, RBracLoc));
+  }
+  
+  SourceLocation Loc = SuperLoc.isValid()? SuperLoc
+             : ReceiverTypeInfo->getTypeLoc().getSourceRange().getBegin();
+
+  // Find the class to which we are sending this message.
+  ObjCInterfaceDecl *Class = 0;
+  if (const ObjCInterfaceType *ClassType
+                                 = ReceiverType->getAs<ObjCInterfaceType>())
+    Class = ClassType->getDecl();
+  else {
+    Diag(Loc, diag::err_invalid_receiver_class_message)
+      << ReceiverType;
+    return ExprError();
+  }
+  assert(Class && "We don't know which class we're messaging?");
+
+  // Find the method we are messaging.
+  if (!Method) {
+    if (Class->isForwardDecl()) {
+      // A forward class used in messaging is treated as a 'Class'
+      Diag(Loc, diag::warn_receiver_forward_class) << Class->getDeclName();
+      Method = LookupFactoryMethodInGlobalPool(Sel, 
+                                               SourceRange(LBracLoc, RBracLoc));
+      if (Method)
+        Diag(Method->getLocation(), diag::note_method_sent_forward_class)
+          << Method->getDeclName();
+    }
+    if (!Method)
+      Method = Class->lookupClassMethod(Sel);
+
+    // If we have an implementation in scope, check "private" methods.
+    if (!Method)
+      Method = LookupPrivateClassMethod(Sel, Class);
+
+    if (Method && DiagnoseUseOfDecl(Method, Loc))
+      return ExprError();
+  }
+
+  // Check the argument types and determine the result type.
+  QualType ReturnType;
+  unsigned NumArgs = ArgsIn.size();
+  Expr **Args = reinterpret_cast<Expr **>(ArgsIn.release());
+  if (CheckMessageArgumentTypes(Args, NumArgs, Sel, Method, true,
+                                LBracLoc, RBracLoc, ReturnType)) {
+    for (unsigned I = 0; I != NumArgs; ++I)
+      Args[I]->Destroy(Context);
+    return ExprError();
+  }
+
+  // Construct the appropriate ObjCMessageExpr.
+  if (SuperLoc.isValid())
+    return Owned(ObjCMessageExpr::Create(Context, ReturnType, LBracLoc, 
+                                         SuperLoc, /*IsInstanceSuper=*/false, 
+                                         ReceiverType, Sel, Method, Args, 
+                                         NumArgs, RBracLoc));
+
+  return Owned(ObjCMessageExpr::Create(Context, ReturnType, LBracLoc, 
+                                       ReceiverTypeInfo, Sel, Method, Args, 
+                                       NumArgs, RBracLoc));
+}
+
+// ActOnClassMessage - used for both unary and keyword messages.
+// ArgExprs is optional - if it is present, the number of expressions
+// is obtained from Sel.getNumArgs().
+Sema::OwningExprResult Sema::ActOnClassMessage(Scope *S, 
+                                               TypeTy *Receiver,
+                                               Selector Sel,
+                                               SourceLocation LBracLoc,
+                                               SourceLocation SelectorLoc,
+                                               SourceLocation RBracLoc,
+                                               MultiExprArg Args) {
+  TypeSourceInfo *ReceiverTypeInfo;
+  QualType ReceiverType = GetTypeFromParser(Receiver, &ReceiverTypeInfo);
+  if (ReceiverType.isNull())
+    return ExprError();
+
+
+  if (!ReceiverTypeInfo)
+    ReceiverTypeInfo = Context.getTrivialTypeSourceInfo(ReceiverType, LBracLoc);
+
+  return BuildClassMessage(ReceiverTypeInfo, ReceiverType, 
+                           /*SuperLoc=*/SourceLocation(), Sel, /*Method=*/0,
+                           LBracLoc, RBracLoc, move(Args));
+}
+
+/// \brief Build an Objective-C instance message expression.
+///
+/// This routine takes care of both normal instance messages and
+/// instance messages to the superclass instance.
+///
+/// \param Receiver The expression that computes the object that will
+/// receive this message. This may be empty, in which case we are
+/// sending to the superclass instance and \p SuperLoc must be a valid
+/// source location.
+///
+/// \param ReceiverType The (static) type of the object receiving the
+/// message. When a \p Receiver expression is provided, this is the
+/// same type as that expression. For a superclass instance send, this
+/// is a pointer to the type of the superclass.
+///
+/// \param SuperLoc The location of the "super" keyword in a
+/// superclass instance message.
+///
+/// \param Sel The selector to which the message is being sent.
+///
+/// \param Method The method that this instance message is invoking, if
+/// already known.
+///
+/// \param LBracLoc The location of the opening square bracket ']'.
+///
+/// \param RBrac The location of the closing square bracket ']'.
+///
+/// \param Args The message arguments.
+Sema::OwningExprResult Sema::BuildInstanceMessage(ExprArg ReceiverE,
+                                                  QualType ReceiverType,
+                                                  SourceLocation SuperLoc,
+                                                  Selector Sel,
+                                                  ObjCMethodDecl *Method,
+                                                  SourceLocation LBracLoc, 
+                                                  SourceLocation RBracLoc,
+                                                  MultiExprArg ArgsIn) {
+  // If we have a receiver expression, perform appropriate promotions
+  // and determine receiver type.
+  Expr *Receiver = ReceiverE.takeAs<Expr>();
+  if (Receiver) {
+    if (Receiver->isTypeDependent()) {
+      // If the receiver is type-dependent, we can't type-check anything
+      // at this point. Build a dependent expression.
+      unsigned NumArgs = ArgsIn.size();
+      Expr **Args = reinterpret_cast<Expr **>(ArgsIn.release());
+      assert(SuperLoc.isInvalid() && "Message to super with dependent type");
+      return Owned(ObjCMessageExpr::Create(Context, Context.DependentTy,
+                                           LBracLoc, Receiver, Sel, 
+                                           /*Method=*/0, Args, NumArgs, 
+                                           RBracLoc));
+    }
+
+    // If necessary, apply function/array conversion to the receiver.
+    // C99 6.7.5.3p[7,8].
+    DefaultFunctionArrayLvalueConversion(Receiver);
+    ReceiverType = Receiver->getType();
+  }
+
+  // The location of the receiver.
+  SourceLocation Loc = SuperLoc.isValid()? SuperLoc : Receiver->getLocStart();
+
+  if (!Method) {
+    // Handle messages to id.
+    if (ReceiverType->isObjCIdType() || ReceiverType->isBlockPointerType() ||
+        (Receiver && Context.isObjCNSObjectType(Receiver->getType()))) {
+      Method = LookupInstanceMethodInGlobalPool(Sel, 
+                                              SourceRange(LBracLoc, RBracLoc));
+      if (!Method)
+        Method = LookupFactoryMethodInGlobalPool(Sel, 
+                                               SourceRange(LBracLoc, RBracLoc));
+    } else if (ReceiverType->isObjCClassType() ||
+               ReceiverType->isObjCQualifiedClassType()) {
+      // Handle messages to Class.
+      if (ObjCMethodDecl *CurMeth = getCurMethodDecl()) {
+        if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface()) {
+          // First check the public methods in the class interface.
+          Method = ClassDecl->lookupClassMethod(Sel);
+
+          if (!Method)
+            Method = LookupPrivateClassMethod(Sel, ClassDecl);
+
+          // FIXME: if we still haven't found a method, we need to look in
+          // protocols (if we have qualifiers).
+        }
+        if (Method && DiagnoseUseOfDecl(Method, Loc))
+          return ExprError();
+      }
+      if (!Method) {
+        // If not messaging 'self', look for any factory method named 'Sel'.
+        if (!Receiver || !isSelfExpr(Receiver)) {
+          Method = LookupFactoryMethodInGlobalPool(Sel, 
+                                               SourceRange(LBracLoc, RBracLoc));
+          if (!Method) {
+            // If no class (factory) method was found, check if an _instance_
+            // method of the same name exists in the root class only.
+            Method = LookupInstanceMethodInGlobalPool(Sel,
+                                               SourceRange(LBracLoc, RBracLoc));
+            if (Method)
+                if (const ObjCInterfaceDecl *ID =
+                  dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext())) {
+                if (ID->getSuperClass())
+                  Diag(Loc, diag::warn_root_inst_method_not_found)
+                    << Sel << SourceRange(LBracLoc, RBracLoc);
+              }
+          }
+        }
+      }
+    } else {
+      ObjCInterfaceDecl* ClassDecl = 0;
+
+      // We allow sending a message to a qualified ID ("id<foo>"), which is ok as
+      // long as one of the protocols implements the selector (if not, warn).
+      if (const ObjCObjectPointerType *QIdTy 
+                                   = ReceiverType->getAsObjCQualifiedIdType()) {
+        // Search protocols for instance methods.
+        for (ObjCObjectPointerType::qual_iterator I = QIdTy->qual_begin(),
+               E = QIdTy->qual_end(); I != E; ++I) {
+          ObjCProtocolDecl *PDecl = *I;
+          if (PDecl && (Method = PDecl->lookupInstanceMethod(Sel)))
+            break;
+          // Since we aren't supporting "Class<foo>", look for a class method.
+          if (PDecl && (Method = PDecl->lookupClassMethod(Sel)))
+            break;
+        }
+      } else if (const ObjCObjectPointerType *OCIType
+                   = ReceiverType->getAsObjCInterfacePointerType()) {
+        // We allow sending a message to a pointer to an interface (an object).
+        ClassDecl = OCIType->getInterfaceDecl();
+        // FIXME: consider using LookupInstanceMethodInGlobalPool, since it will be
+        // faster than the following method (which can do *many* linear searches).
+        // The idea is to add class info to InstanceMethodPool.
+        Method = ClassDecl->lookupInstanceMethod(Sel);
+
+        if (!Method) {
+          // Search protocol qualifiers.
+          for (ObjCObjectPointerType::qual_iterator QI = OCIType->qual_begin(),
+                 E = OCIType->qual_end(); QI != E; ++QI) {
+            if ((Method = (*QI)->lookupInstanceMethod(Sel)))
+              break;
+          }
+        }
+        if (!Method) {
+          // If we have implementations in scope, check "private" methods.
+          Method = LookupPrivateInstanceMethod(Sel, ClassDecl);
+
+          if (!Method && (!Receiver || !isSelfExpr(Receiver))) {
+            // If we still haven't found a method, look in the global pool. This
+            // behavior isn't very desirable, however we need it for GCC
+            // compatibility. FIXME: should we deviate??
+            if (OCIType->qual_empty()) {
+              Method = LookupInstanceMethodInGlobalPool(Sel,
+                                                 SourceRange(LBracLoc, RBracLoc));
+              if (Method && !OCIType->getInterfaceDecl()->isForwardDecl())
+                Diag(Loc, diag::warn_maynot_respond)
+                  << OCIType->getInterfaceDecl()->getIdentifier() << Sel;
+            }
+          }
+        }
+        if (Method && DiagnoseUseOfDecl(Method, Loc))
+          return ExprError();
+      } else if (!Context.getObjCIdType().isNull() &&
+                 (ReceiverType->isPointerType() ||
+                  (ReceiverType->isIntegerType() &&
+                   ReceiverType->isScalarType()))) {
+        // Implicitly convert integers and pointers to 'id' but emit a warning.
+        Diag(Loc, diag::warn_bad_receiver_type)
+          << ReceiverType 
+          << Receiver->getSourceRange();
+        if (ReceiverType->isPointerType())
+          ImpCastExprToType(Receiver, Context.getObjCIdType(), 
+                            CastExpr::CK_BitCast);
+        else
+          ImpCastExprToType(Receiver, Context.getObjCIdType(),
+                            CastExpr::CK_IntegralToPointer);
+        ReceiverType = Receiver->getType();
+      } else {
+        // Reject other random receiver types (e.g. structs).
+        Diag(Loc, diag::err_bad_receiver_type)
+          << ReceiverType << Receiver->getSourceRange();
+        return ExprError();
+      }
+    }
+  }
+
+  // Check the message arguments.
+  unsigned NumArgs = ArgsIn.size();
+  Expr **Args = reinterpret_cast<Expr **>(ArgsIn.release());
+  QualType ReturnType;
+  if (CheckMessageArgumentTypes(Args, NumArgs, Sel, Method, false,
+                                LBracLoc, RBracLoc, ReturnType))
+    return ExprError();
+
+  // Construct the appropriate ObjCMessageExpr instance.
+  if (SuperLoc.isValid())
+    return Owned(ObjCMessageExpr::Create(Context, ReturnType, LBracLoc,
+                                         SuperLoc,  /*IsInstanceSuper=*/true,
+                                         ReceiverType, Sel, Method, 
+                                         Args, NumArgs, RBracLoc));
+
+  return Owned(ObjCMessageExpr::Create(Context, ReturnType, LBracLoc, Receiver, 
+                                       Sel, Method, Args, NumArgs, RBracLoc));
+}
+
+// ActOnInstanceMessage - used for both unary and keyword messages.
+// ArgExprs is optional - if it is present, the number of expressions
+// is obtained from Sel.getNumArgs().
+Sema::OwningExprResult Sema::ActOnInstanceMessage(Scope *S,
+                                                  ExprArg ReceiverE, 
+                                                  Selector Sel,
+                                                  SourceLocation LBracLoc,
+                                                  SourceLocation SelectorLoc,
+                                                  SourceLocation RBracLoc,
+                                                  MultiExprArg Args) {
+  Expr *Receiver = static_cast<Expr *>(ReceiverE.get());
+  if (!Receiver)
+    return ExprError();
+
+  return BuildInstanceMessage(move(ReceiverE), Receiver->getType(),
+                              /*SuperLoc=*/SourceLocation(), Sel, /*Method=*/0, 
+                              LBracLoc, RBracLoc, move(Args));
+}
+
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp
new file mode 100644
index 0000000..1caa94b
--- /dev/null
+++ b/lib/Sema/SemaInit.cpp
@@ -0,0 +1,4301 @@
+//===--- SemaInit.cpp - Semantic Analysis for Initializers ----------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements semantic analysis for initializers. The main entry
+// point is Sema::CheckInitList(), but all of the work is performed
+// within the InitListChecker class.
+//
+// This file also implements Sema::CheckInitializerTypes.
+//
+//===----------------------------------------------------------------------===//
+
+#include "SemaInit.h"
+#include "Lookup.h"
+#include "Sema.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Parse/Designator.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/ExprObjC.h"
+#include "clang/AST/TypeLoc.h"
+#include "llvm/Support/ErrorHandling.h"
+#include <map>
+using namespace clang;
+
+//===----------------------------------------------------------------------===//
+// Sema Initialization Checking
+//===----------------------------------------------------------------------===//
+
+static Expr *IsStringInit(Expr *Init, QualType DeclType, ASTContext &Context) {
+  const ArrayType *AT = Context.getAsArrayType(DeclType);
+  if (!AT) return 0;
+
+  if (!isa<ConstantArrayType>(AT) && !isa<IncompleteArrayType>(AT))
+    return 0;
+
+  // See if this is a string literal or @encode.
+  Init = Init->IgnoreParens();
+
+  // Handle @encode, which is a narrow string.
+  if (isa<ObjCEncodeExpr>(Init) && AT->getElementType()->isCharType())
+    return Init;
+
+  // Otherwise we can only handle string literals.
+  StringLiteral *SL = dyn_cast<StringLiteral>(Init);
+  if (SL == 0) return 0;
+
+  QualType ElemTy = Context.getCanonicalType(AT->getElementType());
+  // char array can be initialized with a narrow string.
+  // Only allow char x[] = "foo";  not char x[] = L"foo";
+  if (!SL->isWide())
+    return ElemTy->isCharType() ? Init : 0;
+
+  // wchar_t array can be initialized with a wide string: C99 6.7.8p15 (with
+  // correction from DR343): "An array with element type compatible with a
+  // qualified or unqualified version of wchar_t may be initialized by a wide
+  // string literal, optionally enclosed in braces."
+  if (Context.typesAreCompatible(Context.getWCharType(),
+                                 ElemTy.getUnqualifiedType()))
+    return Init;
+
+  return 0;
+}
+
+static void CheckStringInit(Expr *Str, QualType &DeclT, Sema &S) {
+  // Get the length of the string as parsed.
+  uint64_t StrLength =
+    cast<ConstantArrayType>(Str->getType())->getSize().getZExtValue();
+
+
+  const ArrayType *AT = S.Context.getAsArrayType(DeclT);
+  if (const IncompleteArrayType *IAT = dyn_cast<IncompleteArrayType>(AT)) {
+    // C99 6.7.8p14. We have an array of character type with unknown size
+    // being initialized to a string literal.
+    llvm::APSInt ConstVal(32);
+    ConstVal = StrLength;
+    // Return a new array type (C99 6.7.8p22).
+    DeclT = S.Context.getConstantArrayType(IAT->getElementType(),
+                                           ConstVal,
+                                           ArrayType::Normal, 0);
+    return;
+  }
+
+  const ConstantArrayType *CAT = cast<ConstantArrayType>(AT);
+
+  // C99 6.7.8p14. We have an array of character type with known size.  However,
+  // the size may be smaller or larger than the string we are initializing.
+  // FIXME: Avoid truncation for 64-bit length strings.
+  if (StrLength-1 > CAT->getSize().getZExtValue())
+    S.Diag(Str->getSourceRange().getBegin(),
+           diag::warn_initializer_string_for_char_array_too_long)
+      << Str->getSourceRange();
+
+  // Set the type to the actual size that we are initializing.  If we have
+  // something like:
+  //   char x[1] = "foo";
+  // then this will set the string literal's type to char[1].
+  Str->setType(DeclT);
+}
+
+//===----------------------------------------------------------------------===//
+// Semantic checking for initializer lists.
+//===----------------------------------------------------------------------===//
+
+/// @brief Semantic checking for initializer lists.
+///
+/// The InitListChecker class contains a set of routines that each
+/// handle the initialization of a certain kind of entity, e.g.,
+/// arrays, vectors, struct/union types, scalars, etc. The
+/// InitListChecker itself performs a recursive walk of the subobject
+/// structure of the type to be initialized, while stepping through
+/// the initializer list one element at a time. The IList and Index
+/// parameters to each of the Check* routines contain the active
+/// (syntactic) initializer list and the index into that initializer
+/// list that represents the current initializer. Each routine is
+/// responsible for moving that Index forward as it consumes elements.
+///
+/// Each Check* routine also has a StructuredList/StructuredIndex
+/// arguments, which contains the current the "structured" (semantic)
+/// initializer list and the index into that initializer list where we
+/// are copying initializers as we map them over to the semantic
+/// list. Once we have completed our recursive walk of the subobject
+/// structure, we will have constructed a full semantic initializer
+/// list.
+///
+/// C99 designators cause changes in the initializer list traversal,
+/// because they make the initialization "jump" into a specific
+/// subobject and then continue the initialization from that
+/// point. CheckDesignatedInitializer() recursively steps into the
+/// designated subobject and manages backing out the recursion to
+/// initialize the subobjects after the one designated.
+namespace {
+class InitListChecker {
+  Sema &SemaRef;
+  bool hadError;
+  std::map<InitListExpr *, InitListExpr *> SyntacticToSemantic;
+  InitListExpr *FullyStructuredList;
+
+  void CheckImplicitInitList(const InitializedEntity &Entity,
+                             InitListExpr *ParentIList, QualType T,
+                             unsigned &Index, InitListExpr *StructuredList,
+                             unsigned &StructuredIndex,
+                             bool TopLevelObject = false);
+  void CheckExplicitInitList(const InitializedEntity &Entity,
+                             InitListExpr *IList, QualType &T,
+                             unsigned &Index, InitListExpr *StructuredList,
+                             unsigned &StructuredIndex,
+                             bool TopLevelObject = false);
+  void CheckListElementTypes(const InitializedEntity &Entity,
+                             InitListExpr *IList, QualType &DeclType,
+                             bool SubobjectIsDesignatorContext,
+                             unsigned &Index,
+                             InitListExpr *StructuredList,
+                             unsigned &StructuredIndex,
+                             bool TopLevelObject = false);
+  void CheckSubElementType(const InitializedEntity &Entity,
+                           InitListExpr *IList, QualType ElemType,
+                           unsigned &Index,
+                           InitListExpr *StructuredList,
+                           unsigned &StructuredIndex);
+  void CheckScalarType(const InitializedEntity &Entity,
+                       InitListExpr *IList, QualType DeclType,
+                       unsigned &Index,
+                       InitListExpr *StructuredList,
+                       unsigned &StructuredIndex);
+  void CheckReferenceType(const InitializedEntity &Entity,
+                          InitListExpr *IList, QualType DeclType,
+                          unsigned &Index,
+                          InitListExpr *StructuredList,
+                          unsigned &StructuredIndex);
+  void CheckVectorType(const InitializedEntity &Entity,
+                       InitListExpr *IList, QualType DeclType, unsigned &Index,
+                       InitListExpr *StructuredList,
+                       unsigned &StructuredIndex);
+  void CheckStructUnionTypes(const InitializedEntity &Entity,
+                             InitListExpr *IList, QualType DeclType,
+                             RecordDecl::field_iterator Field,
+                             bool SubobjectIsDesignatorContext, unsigned &Index,
+                             InitListExpr *StructuredList,
+                             unsigned &StructuredIndex,
+                             bool TopLevelObject = false);
+  void CheckArrayType(const InitializedEntity &Entity,
+                      InitListExpr *IList, QualType &DeclType,
+                      llvm::APSInt elementIndex,
+                      bool SubobjectIsDesignatorContext, unsigned &Index,
+                      InitListExpr *StructuredList,
+                      unsigned &StructuredIndex);
+  bool CheckDesignatedInitializer(const InitializedEntity &Entity,
+                                  InitListExpr *IList, DesignatedInitExpr *DIE,
+                                  unsigned DesigIdx,
+                                  QualType &CurrentObjectType,
+                                  RecordDecl::field_iterator *NextField,
+                                  llvm::APSInt *NextElementIndex,
+                                  unsigned &Index,
+                                  InitListExpr *StructuredList,
+                                  unsigned &StructuredIndex,
+                                  bool FinishSubobjectInit,
+                                  bool TopLevelObject);
+  InitListExpr *getStructuredSubobjectInit(InitListExpr *IList, unsigned Index,
+                                           QualType CurrentObjectType,
+                                           InitListExpr *StructuredList,
+                                           unsigned StructuredIndex,
+                                           SourceRange InitRange);
+  void UpdateStructuredListElement(InitListExpr *StructuredList,
+                                   unsigned &StructuredIndex,
+                                   Expr *expr);
+  int numArrayElements(QualType DeclType);
+  int numStructUnionElements(QualType DeclType);
+
+  void FillInValueInitForField(unsigned Init, FieldDecl *Field,
+                               const InitializedEntity &ParentEntity,
+                               InitListExpr *ILE, bool &RequiresSecondPass);
+  void FillInValueInitializations(const InitializedEntity &Entity,
+                                  InitListExpr *ILE, bool &RequiresSecondPass);
+public:
+  InitListChecker(Sema &S, const InitializedEntity &Entity,
+                  InitListExpr *IL, QualType &T);
+  bool HadError() { return hadError; }
+
+  // @brief Retrieves the fully-structured initializer list used for
+  // semantic analysis and code generation.
+  InitListExpr *getFullyStructuredList() const { return FullyStructuredList; }
+};
+} // end anonymous namespace
+
+void InitListChecker::FillInValueInitForField(unsigned Init, FieldDecl *Field,
+                                        const InitializedEntity &ParentEntity,
+                                              InitListExpr *ILE, 
+                                              bool &RequiresSecondPass) {
+  SourceLocation Loc = ILE->getSourceRange().getBegin();
+  unsigned NumInits = ILE->getNumInits();
+  InitializedEntity MemberEntity 
+    = InitializedEntity::InitializeMember(Field, &ParentEntity);
+  if (Init >= NumInits || !ILE->getInit(Init)) {
+    // FIXME: We probably don't need to handle references
+    // specially here, since value-initialization of references is
+    // handled in InitializationSequence.
+    if (Field->getType()->isReferenceType()) {
+      // C++ [dcl.init.aggr]p9:
+      //   If an incomplete or empty initializer-list leaves a
+      //   member of reference type uninitialized, the program is
+      //   ill-formed.
+      SemaRef.Diag(Loc, diag::err_init_reference_member_uninitialized)
+        << Field->getType()
+        << ILE->getSyntacticForm()->getSourceRange();
+      SemaRef.Diag(Field->getLocation(),
+                   diag::note_uninit_reference_member);
+      hadError = true;
+      return;
+    }
+    
+    InitializationKind Kind = InitializationKind::CreateValue(Loc, Loc, Loc,
+                                                              true);
+    InitializationSequence InitSeq(SemaRef, MemberEntity, Kind, 0, 0);
+    if (!InitSeq) {
+      InitSeq.Diagnose(SemaRef, MemberEntity, Kind, 0, 0);
+      hadError = true;
+      return;
+    }
+    
+    Sema::OwningExprResult MemberInit
+      = InitSeq.Perform(SemaRef, MemberEntity, Kind, 
+                        Sema::MultiExprArg(SemaRef, 0, 0));
+    if (MemberInit.isInvalid()) {
+      hadError = true;
+      return;
+    }
+    
+    if (hadError) {
+      // Do nothing
+    } else if (Init < NumInits) {
+      ILE->setInit(Init, MemberInit.takeAs<Expr>());
+    } else if (InitSeq.getKind()
+                 == InitializationSequence::ConstructorInitialization) {
+      // Value-initialization requires a constructor call, so
+      // extend the initializer list to include the constructor
+      // call and make a note that we'll need to take another pass
+      // through the initializer list.
+      ILE->updateInit(SemaRef.Context, Init, MemberInit.takeAs<Expr>());
+      RequiresSecondPass = true;
+    }
+  } else if (InitListExpr *InnerILE
+               = dyn_cast<InitListExpr>(ILE->getInit(Init)))
+    FillInValueInitializations(MemberEntity, InnerILE, 
+                               RequiresSecondPass);  
+}
+
+/// Recursively replaces NULL values within the given initializer list
+/// with expressions that perform value-initialization of the
+/// appropriate type.
+void 
+InitListChecker::FillInValueInitializations(const InitializedEntity &Entity,
+                                            InitListExpr *ILE,
+                                            bool &RequiresSecondPass) {
+  assert((ILE->getType() != SemaRef.Context.VoidTy) &&
+         "Should not have void type");
+  SourceLocation Loc = ILE->getSourceRange().getBegin();
+  if (ILE->getSyntacticForm())
+    Loc = ILE->getSyntacticForm()->getSourceRange().getBegin();
+
+  if (const RecordType *RType = ILE->getType()->getAs<RecordType>()) {
+    if (RType->getDecl()->isUnion() &&
+        ILE->getInitializedFieldInUnion())
+      FillInValueInitForField(0, ILE->getInitializedFieldInUnion(),
+                              Entity, ILE, RequiresSecondPass);
+    else {
+      unsigned Init = 0;
+      for (RecordDecl::field_iterator
+             Field = RType->getDecl()->field_begin(),
+             FieldEnd = RType->getDecl()->field_end();
+           Field != FieldEnd; ++Field) {
+        if (Field->isUnnamedBitfield())
+          continue;
+
+        if (hadError)
+          return;
+
+        FillInValueInitForField(Init, *Field, Entity, ILE, RequiresSecondPass);
+        if (hadError)
+          return;
+
+        ++Init;
+
+        // Only look at the first initialization of a union.
+        if (RType->getDecl()->isUnion())
+          break;
+      }
+    }
+
+    return;
+  }
+
+  QualType ElementType;
+
+  InitializedEntity ElementEntity = Entity;
+  unsigned NumInits = ILE->getNumInits();
+  unsigned NumElements = NumInits;
+  if (const ArrayType *AType = SemaRef.Context.getAsArrayType(ILE->getType())) {
+    ElementType = AType->getElementType();
+    if (const ConstantArrayType *CAType = dyn_cast<ConstantArrayType>(AType))
+      NumElements = CAType->getSize().getZExtValue();
+    ElementEntity = InitializedEntity::InitializeElement(SemaRef.Context, 
+                                                         0, Entity);
+  } else if (const VectorType *VType = ILE->getType()->getAs<VectorType>()) {
+    ElementType = VType->getElementType();
+    NumElements = VType->getNumElements();
+    ElementEntity = InitializedEntity::InitializeElement(SemaRef.Context, 
+                                                         0, Entity);
+  } else
+    ElementType = ILE->getType();
+
+  
+  for (unsigned Init = 0; Init != NumElements; ++Init) {
+    if (hadError)
+      return;
+
+    if (ElementEntity.getKind() == InitializedEntity::EK_ArrayElement ||
+        ElementEntity.getKind() == InitializedEntity::EK_VectorElement)
+      ElementEntity.setElementIndex(Init);
+
+    if (Init >= NumInits || !ILE->getInit(Init)) {
+      InitializationKind Kind = InitializationKind::CreateValue(Loc, Loc, Loc,
+                                                                true);
+      InitializationSequence InitSeq(SemaRef, ElementEntity, Kind, 0, 0);
+      if (!InitSeq) {
+        InitSeq.Diagnose(SemaRef, ElementEntity, Kind, 0, 0);
+        hadError = true;
+        return;
+      }
+
+      Sema::OwningExprResult ElementInit
+        = InitSeq.Perform(SemaRef, ElementEntity, Kind, 
+                          Sema::MultiExprArg(SemaRef, 0, 0));
+      if (ElementInit.isInvalid()) {
+        hadError = true;
+        return;
+      }
+
+      if (hadError) {
+        // Do nothing
+      } else if (Init < NumInits) {
+        ILE->setInit(Init, ElementInit.takeAs<Expr>());
+      } else if (InitSeq.getKind()
+                   == InitializationSequence::ConstructorInitialization) {
+        // Value-initialization requires a constructor call, so
+        // extend the initializer list to include the constructor
+        // call and make a note that we'll need to take another pass
+        // through the initializer list.
+        ILE->updateInit(SemaRef.Context, Init, ElementInit.takeAs<Expr>());
+        RequiresSecondPass = true;
+      }
+    } else if (InitListExpr *InnerILE
+                 = dyn_cast<InitListExpr>(ILE->getInit(Init)))
+      FillInValueInitializations(ElementEntity, InnerILE, RequiresSecondPass);
+  }
+}
+
+
+InitListChecker::InitListChecker(Sema &S, const InitializedEntity &Entity,
+                                 InitListExpr *IL, QualType &T)
+  : SemaRef(S) {
+  hadError = false;
+
+  unsigned newIndex = 0;
+  unsigned newStructuredIndex = 0;
+  FullyStructuredList
+    = getStructuredSubobjectInit(IL, newIndex, T, 0, 0, IL->getSourceRange());
+  CheckExplicitInitList(Entity, IL, T, newIndex, 
+                        FullyStructuredList, newStructuredIndex,
+                        /*TopLevelObject=*/true);
+
+  if (!hadError) {
+    bool RequiresSecondPass = false;
+    FillInValueInitializations(Entity, FullyStructuredList, RequiresSecondPass);
+    if (RequiresSecondPass && !hadError)
+      FillInValueInitializations(Entity, FullyStructuredList, 
+                                 RequiresSecondPass);
+  }
+}
+
+int InitListChecker::numArrayElements(QualType DeclType) {
+  // FIXME: use a proper constant
+  int maxElements = 0x7FFFFFFF;
+  if (const ConstantArrayType *CAT =
+        SemaRef.Context.getAsConstantArrayType(DeclType)) {
+    maxElements = static_cast<int>(CAT->getSize().getZExtValue());
+  }
+  return maxElements;
+}
+
+int InitListChecker::numStructUnionElements(QualType DeclType) {
+  RecordDecl *structDecl = DeclType->getAs<RecordType>()->getDecl();
+  int InitializableMembers = 0;
+  for (RecordDecl::field_iterator
+         Field = structDecl->field_begin(),
+         FieldEnd = structDecl->field_end();
+       Field != FieldEnd; ++Field) {
+    if ((*Field)->getIdentifier() || !(*Field)->isBitField())
+      ++InitializableMembers;
+  }
+  if (structDecl->isUnion())
+    return std::min(InitializableMembers, 1);
+  return InitializableMembers - structDecl->hasFlexibleArrayMember();
+}
+
+void InitListChecker::CheckImplicitInitList(const InitializedEntity &Entity,
+                                            InitListExpr *ParentIList,
+                                            QualType T, unsigned &Index,
+                                            InitListExpr *StructuredList,
+                                            unsigned &StructuredIndex,
+                                            bool TopLevelObject) {
+  int maxElements = 0;
+
+  if (T->isArrayType())
+    maxElements = numArrayElements(T);
+  else if (T->isRecordType())
+    maxElements = numStructUnionElements(T);
+  else if (T->isVectorType())
+    maxElements = T->getAs<VectorType>()->getNumElements();
+  else
+    assert(0 && "CheckImplicitInitList(): Illegal type");
+
+  if (maxElements == 0) {
+    SemaRef.Diag(ParentIList->getInit(Index)->getLocStart(),
+                  diag::err_implicit_empty_initializer);
+    ++Index;
+    hadError = true;
+    return;
+  }
+
+  // Build a structured initializer list corresponding to this subobject.
+  InitListExpr *StructuredSubobjectInitList
+    = getStructuredSubobjectInit(ParentIList, Index, T, StructuredList,
+                                 StructuredIndex,
+          SourceRange(ParentIList->getInit(Index)->getSourceRange().getBegin(),
+                      ParentIList->getSourceRange().getEnd()));
+  unsigned StructuredSubobjectInitIndex = 0;
+
+  // Check the element types and build the structural subobject.
+  unsigned StartIndex = Index;
+  CheckListElementTypes(Entity, ParentIList, T, 
+                        /*SubobjectIsDesignatorContext=*/false, Index,
+                        StructuredSubobjectInitList,
+                        StructuredSubobjectInitIndex,
+                        TopLevelObject);
+  unsigned EndIndex = (Index == StartIndex? StartIndex : Index - 1);
+  StructuredSubobjectInitList->setType(T);
+
+  // Update the structured sub-object initializer so that it's ending
+  // range corresponds with the end of the last initializer it used.
+  if (EndIndex < ParentIList->getNumInits()) {
+    SourceLocation EndLoc
+      = ParentIList->getInit(EndIndex)->getSourceRange().getEnd();
+    StructuredSubobjectInitList->setRBraceLoc(EndLoc);
+  }
+  
+  // Warn about missing braces.
+  if (T->isArrayType() || T->isRecordType()) {
+    SemaRef.Diag(StructuredSubobjectInitList->getLocStart(),
+                 diag::warn_missing_braces)
+    << StructuredSubobjectInitList->getSourceRange()
+    << FixItHint::CreateInsertion(StructuredSubobjectInitList->getLocStart(), 
+                                  "{")
+    << FixItHint::CreateInsertion(SemaRef.PP.getLocForEndOfToken(
+                                      StructuredSubobjectInitList->getLocEnd()), 
+                                  "}");
+  }
+}
+
+void InitListChecker::CheckExplicitInitList(const InitializedEntity &Entity,
+                                            InitListExpr *IList, QualType &T,
+                                            unsigned &Index,
+                                            InitListExpr *StructuredList,
+                                            unsigned &StructuredIndex,
+                                            bool TopLevelObject) {
+  assert(IList->isExplicit() && "Illegal Implicit InitListExpr");
+  SyntacticToSemantic[IList] = StructuredList;
+  StructuredList->setSyntacticForm(IList);
+  CheckListElementTypes(Entity, IList, T, /*SubobjectIsDesignatorContext=*/true, 
+                        Index, StructuredList, StructuredIndex, TopLevelObject);
+  IList->setType(T.getNonReferenceType());
+  StructuredList->setType(T.getNonReferenceType());
+  if (hadError)
+    return;
+
+  if (Index < IList->getNumInits()) {
+    // We have leftover initializers
+    if (StructuredIndex == 1 &&
+        IsStringInit(StructuredList->getInit(0), T, SemaRef.Context)) {
+      unsigned DK = diag::warn_excess_initializers_in_char_array_initializer;
+      if (SemaRef.getLangOptions().CPlusPlus) {
+        DK = diag::err_excess_initializers_in_char_array_initializer;
+        hadError = true;
+      }
+      // Special-case
+      SemaRef.Diag(IList->getInit(Index)->getLocStart(), DK)
+        << IList->getInit(Index)->getSourceRange();
+    } else if (!T->isIncompleteType()) {
+      // Don't complain for incomplete types, since we'll get an error
+      // elsewhere
+      QualType CurrentObjectType = StructuredList->getType();
+      int initKind =
+        CurrentObjectType->isArrayType()? 0 :
+        CurrentObjectType->isVectorType()? 1 :
+        CurrentObjectType->isScalarType()? 2 :
+        CurrentObjectType->isUnionType()? 3 :
+        4;
+
+      unsigned DK = diag::warn_excess_initializers;
+      if (SemaRef.getLangOptions().CPlusPlus) {
+        DK = diag::err_excess_initializers;
+        hadError = true;
+      }
+      if (SemaRef.getLangOptions().OpenCL && initKind == 1) {
+        DK = diag::err_excess_initializers;
+        hadError = true;
+      }
+
+      SemaRef.Diag(IList->getInit(Index)->getLocStart(), DK)
+        << initKind << IList->getInit(Index)->getSourceRange();
+    }
+  }
+
+  if (T->isScalarType() && !TopLevelObject)
+    SemaRef.Diag(IList->getLocStart(), diag::warn_braces_around_scalar_init)
+      << IList->getSourceRange()
+      << FixItHint::CreateRemoval(IList->getLocStart())
+      << FixItHint::CreateRemoval(IList->getLocEnd());
+}
+
+void InitListChecker::CheckListElementTypes(const InitializedEntity &Entity,
+                                            InitListExpr *IList,
+                                            QualType &DeclType,
+                                            bool SubobjectIsDesignatorContext,
+                                            unsigned &Index,
+                                            InitListExpr *StructuredList,
+                                            unsigned &StructuredIndex,
+                                            bool TopLevelObject) {
+  if (DeclType->isScalarType()) {
+    CheckScalarType(Entity, IList, DeclType, Index,
+                    StructuredList, StructuredIndex);
+  } else if (DeclType->isVectorType()) {
+    CheckVectorType(Entity, IList, DeclType, Index, 
+                    StructuredList, StructuredIndex);
+  } else if (DeclType->isAggregateType()) {
+    if (DeclType->isRecordType()) {
+      RecordDecl *RD = DeclType->getAs<RecordType>()->getDecl();
+      CheckStructUnionTypes(Entity, IList, DeclType, RD->field_begin(),
+                            SubobjectIsDesignatorContext, Index,
+                            StructuredList, StructuredIndex,
+                            TopLevelObject);
+    } else if (DeclType->isArrayType()) {
+      llvm::APSInt Zero(
+                      SemaRef.Context.getTypeSize(SemaRef.Context.getSizeType()),
+                      false);
+      CheckArrayType(Entity, IList, DeclType, Zero, 
+                     SubobjectIsDesignatorContext, Index,
+                     StructuredList, StructuredIndex);
+    } else
+      assert(0 && "Aggregate that isn't a structure or array?!");
+  } else if (DeclType->isVoidType() || DeclType->isFunctionType()) {
+    // This type is invalid, issue a diagnostic.
+    ++Index;
+    SemaRef.Diag(IList->getLocStart(), diag::err_illegal_initializer_type)
+      << DeclType;
+    hadError = true;
+  } else if (DeclType->isRecordType()) {
+    // C++ [dcl.init]p14:
+    //   [...] If the class is an aggregate (8.5.1), and the initializer
+    //   is a brace-enclosed list, see 8.5.1.
+    //
+    // Note: 8.5.1 is handled below; here, we diagnose the case where
+    // we have an initializer list and a destination type that is not
+    // an aggregate.
+    // FIXME: In C++0x, this is yet another form of initialization.
+    SemaRef.Diag(IList->getLocStart(), diag::err_init_non_aggr_init_list)
+      << DeclType << IList->getSourceRange();
+    hadError = true;
+  } else if (DeclType->isReferenceType()) {
+    CheckReferenceType(Entity, IList, DeclType, Index,
+                       StructuredList, StructuredIndex);
+  } else {
+    // In C, all types are either scalars or aggregates, but
+    // additional handling is needed here for C++ (and possibly others?).
+    assert(0 && "Unsupported initializer type");
+  }
+}
+
+void InitListChecker::CheckSubElementType(const InitializedEntity &Entity,
+                                          InitListExpr *IList,
+                                          QualType ElemType,
+                                          unsigned &Index,
+                                          InitListExpr *StructuredList,
+                                          unsigned &StructuredIndex) {
+  Expr *expr = IList->getInit(Index);
+  if (InitListExpr *SubInitList = dyn_cast<InitListExpr>(expr)) {
+    unsigned newIndex = 0;
+    unsigned newStructuredIndex = 0;
+    InitListExpr *newStructuredList
+      = getStructuredSubobjectInit(IList, Index, ElemType,
+                                   StructuredList, StructuredIndex,
+                                   SubInitList->getSourceRange());
+    CheckExplicitInitList(Entity, SubInitList, ElemType, newIndex,
+                          newStructuredList, newStructuredIndex);
+    ++StructuredIndex;
+    ++Index;
+  } else if (Expr *Str = IsStringInit(expr, ElemType, SemaRef.Context)) {
+    CheckStringInit(Str, ElemType, SemaRef);
+    UpdateStructuredListElement(StructuredList, StructuredIndex, Str);
+    ++Index;
+  } else if (ElemType->isScalarType()) {
+    CheckScalarType(Entity, IList, ElemType, Index, 
+                    StructuredList, StructuredIndex);
+  } else if (ElemType->isReferenceType()) {
+    CheckReferenceType(Entity, IList, ElemType, Index,
+                       StructuredList, StructuredIndex);
+  } else {
+    if (SemaRef.getLangOptions().CPlusPlus) {
+      // C++ [dcl.init.aggr]p12:
+      //   All implicit type conversions (clause 4) are considered when
+      //   initializing the aggregate member with an ini- tializer from
+      //   an initializer-list. If the initializer can initialize a
+      //   member, the member is initialized. [...]
+
+      // FIXME: Better EqualLoc?
+      InitializationKind Kind = 
+        InitializationKind::CreateCopy(expr->getLocStart(), SourceLocation());
+      InitializationSequence Seq(SemaRef, Entity, Kind, &expr, 1);
+      
+      if (Seq) {
+        Sema::OwningExprResult Result = 
+          Seq.Perform(SemaRef, Entity, Kind,
+                      Sema::MultiExprArg(SemaRef, (void **)&expr, 1));
+        if (Result.isInvalid())
+          hadError = true;
+        
+        UpdateStructuredListElement(StructuredList, StructuredIndex, 
+                                    Result.takeAs<Expr>());
+        ++Index;
+        return;
+      }
+
+      // Fall through for subaggregate initialization
+    } else {
+      // C99 6.7.8p13:
+      //
+      //   The initializer for a structure or union object that has
+      //   automatic storage duration shall be either an initializer
+      //   list as described below, or a single expression that has
+      //   compatible structure or union type. In the latter case, the
+      //   initial value of the object, including unnamed members, is
+      //   that of the expression.
+      if ((ElemType->isRecordType() || ElemType->isVectorType()) &&
+          SemaRef.Context.hasSameUnqualifiedType(expr->getType(), ElemType)) {
+        UpdateStructuredListElement(StructuredList, StructuredIndex, expr);
+        ++Index;
+        return;
+      }
+
+      // Fall through for subaggregate initialization
+    }
+
+    // C++ [dcl.init.aggr]p12:
+    //
+    //   [...] Otherwise, if the member is itself a non-empty
+    //   subaggregate, brace elision is assumed and the initializer is
+    //   considered for the initialization of the first member of
+    //   the subaggregate.
+    if (ElemType->isAggregateType() || ElemType->isVectorType()) {
+      CheckImplicitInitList(Entity, IList, ElemType, Index, StructuredList,
+                            StructuredIndex);
+      ++StructuredIndex;
+    } else {
+      // We cannot initialize this element, so let
+      // PerformCopyInitialization produce the appropriate diagnostic.
+      SemaRef.PerformCopyInitialization(Entity, SourceLocation(), 
+                                        SemaRef.Owned(expr));
+      IList->setInit(Index, 0);
+      hadError = true;
+      ++Index;
+      ++StructuredIndex;
+    }
+  }
+}
+
+void InitListChecker::CheckScalarType(const InitializedEntity &Entity,
+                                      InitListExpr *IList, QualType DeclType,
+                                      unsigned &Index,
+                                      InitListExpr *StructuredList,
+                                      unsigned &StructuredIndex) {
+  if (Index < IList->getNumInits()) {
+    Expr *expr = IList->getInit(Index);
+    if (isa<InitListExpr>(expr)) {
+      SemaRef.Diag(IList->getLocStart(),
+                    diag::err_many_braces_around_scalar_init)
+        << IList->getSourceRange();
+      hadError = true;
+      ++Index;
+      ++StructuredIndex;
+      return;
+    } else if (isa<DesignatedInitExpr>(expr)) {
+      SemaRef.Diag(expr->getSourceRange().getBegin(),
+                    diag::err_designator_for_scalar_init)
+        << DeclType << expr->getSourceRange();
+      hadError = true;
+      ++Index;
+      ++StructuredIndex;
+      return;
+    }
+
+    Sema::OwningExprResult Result =
+      SemaRef.PerformCopyInitialization(Entity, expr->getLocStart(),
+                                        SemaRef.Owned(expr));
+
+    Expr *ResultExpr = 0;
+
+    if (Result.isInvalid())
+      hadError = true; // types weren't compatible.
+    else {
+      ResultExpr = Result.takeAs<Expr>();
+      
+      if (ResultExpr != expr) {
+        // The type was promoted, update initializer list.
+        IList->setInit(Index, ResultExpr);
+      }
+    }
+    if (hadError)
+      ++StructuredIndex;
+    else
+      UpdateStructuredListElement(StructuredList, StructuredIndex, ResultExpr);
+    ++Index;
+  } else {
+    SemaRef.Diag(IList->getLocStart(), diag::err_empty_scalar_initializer)
+      << IList->getSourceRange();
+    hadError = true;
+    ++Index;
+    ++StructuredIndex;
+    return;
+  }
+}
+
+void InitListChecker::CheckReferenceType(const InitializedEntity &Entity,
+                                         InitListExpr *IList, QualType DeclType,
+                                         unsigned &Index,
+                                         InitListExpr *StructuredList,
+                                         unsigned &StructuredIndex) {
+  if (Index < IList->getNumInits()) {
+    Expr *expr = IList->getInit(Index);
+    if (isa<InitListExpr>(expr)) {
+      SemaRef.Diag(IList->getLocStart(), diag::err_init_non_aggr_init_list)
+        << DeclType << IList->getSourceRange();
+      hadError = true;
+      ++Index;
+      ++StructuredIndex;
+      return;
+    }
+
+    Sema::OwningExprResult Result =
+      SemaRef.PerformCopyInitialization(Entity, expr->getLocStart(),
+                                        SemaRef.Owned(expr));
+
+    if (Result.isInvalid())
+      hadError = true;
+
+    expr = Result.takeAs<Expr>();
+    IList->setInit(Index, expr);
+
+    if (hadError)
+      ++StructuredIndex;
+    else
+      UpdateStructuredListElement(StructuredList, StructuredIndex, expr);
+    ++Index;
+  } else {
+    // FIXME: It would be wonderful if we could point at the actual member. In
+    // general, it would be useful to pass location information down the stack,
+    // so that we know the location (or decl) of the "current object" being
+    // initialized.
+    SemaRef.Diag(IList->getLocStart(),
+                  diag::err_init_reference_member_uninitialized)
+      << DeclType
+      << IList->getSourceRange();
+    hadError = true;
+    ++Index;
+    ++StructuredIndex;
+    return;
+  }
+}
+
+void InitListChecker::CheckVectorType(const InitializedEntity &Entity,
+                                      InitListExpr *IList, QualType DeclType,
+                                      unsigned &Index,
+                                      InitListExpr *StructuredList,
+                                      unsigned &StructuredIndex) {
+  if (Index < IList->getNumInits()) {
+    const VectorType *VT = DeclType->getAs<VectorType>();
+    unsigned maxElements = VT->getNumElements();
+    unsigned numEltsInit = 0;
+    QualType elementType = VT->getElementType();
+
+    if (!SemaRef.getLangOptions().OpenCL) {
+      InitializedEntity ElementEntity =
+        InitializedEntity::InitializeElement(SemaRef.Context, 0, Entity);
+
+      for (unsigned i = 0; i < maxElements; ++i, ++numEltsInit) {
+        // Don't attempt to go past the end of the init list
+        if (Index >= IList->getNumInits())
+          break;
+        
+        ElementEntity.setElementIndex(Index);
+        CheckSubElementType(ElementEntity, IList, elementType, Index,
+                            StructuredList, StructuredIndex);
+      }
+    } else {
+      InitializedEntity ElementEntity =
+        InitializedEntity::InitializeElement(SemaRef.Context, 0, Entity);
+      
+      // OpenCL initializers allows vectors to be constructed from vectors.
+      for (unsigned i = 0; i < maxElements; ++i) {
+        // Don't attempt to go past the end of the init list
+        if (Index >= IList->getNumInits())
+          break;
+        
+        ElementEntity.setElementIndex(Index);
+
+        QualType IType = IList->getInit(Index)->getType();
+        if (!IType->isVectorType()) {
+          CheckSubElementType(ElementEntity, IList, elementType, Index,
+                              StructuredList, StructuredIndex);
+          ++numEltsInit;
+        } else {
+          const VectorType *IVT = IType->getAs<VectorType>();
+          unsigned numIElts = IVT->getNumElements();
+          QualType VecType = SemaRef.Context.getExtVectorType(elementType,
+                                                              numIElts);
+          CheckSubElementType(ElementEntity, IList, VecType, Index,
+                              StructuredList, StructuredIndex);
+          numEltsInit += numIElts;
+        }
+      }
+    }
+
+    // OpenCL requires all elements to be initialized.
+    if (numEltsInit != maxElements)
+      if (SemaRef.getLangOptions().OpenCL)
+        SemaRef.Diag(IList->getSourceRange().getBegin(),
+                     diag::err_vector_incorrect_num_initializers)
+          << (numEltsInit < maxElements) << maxElements << numEltsInit;
+  }
+}
+
+void InitListChecker::CheckArrayType(const InitializedEntity &Entity,
+                                     InitListExpr *IList, QualType &DeclType,
+                                     llvm::APSInt elementIndex,
+                                     bool SubobjectIsDesignatorContext,
+                                     unsigned &Index,
+                                     InitListExpr *StructuredList,
+                                     unsigned &StructuredIndex) {
+  // Check for the special-case of initializing an array with a string.
+  if (Index < IList->getNumInits()) {
+    if (Expr *Str = IsStringInit(IList->getInit(Index), DeclType,
+                                 SemaRef.Context)) {
+      CheckStringInit(Str, DeclType, SemaRef);
+      // We place the string literal directly into the resulting
+      // initializer list. This is the only place where the structure
+      // of the structured initializer list doesn't match exactly,
+      // because doing so would involve allocating one character
+      // constant for each string.
+      UpdateStructuredListElement(StructuredList, StructuredIndex, Str);
+      StructuredList->resizeInits(SemaRef.Context, StructuredIndex);
+      ++Index;
+      return;
+    }
+  }
+  if (const VariableArrayType *VAT =
+        SemaRef.Context.getAsVariableArrayType(DeclType)) {
+    // Check for VLAs; in standard C it would be possible to check this
+    // earlier, but I don't know where clang accepts VLAs (gcc accepts
+    // them in all sorts of strange places).
+    SemaRef.Diag(VAT->getSizeExpr()->getLocStart(),
+                  diag::err_variable_object_no_init)
+      << VAT->getSizeExpr()->getSourceRange();
+    hadError = true;
+    ++Index;
+    ++StructuredIndex;
+    return;
+  }
+
+  // We might know the maximum number of elements in advance.
+  llvm::APSInt maxElements(elementIndex.getBitWidth(),
+                           elementIndex.isUnsigned());
+  bool maxElementsKnown = false;
+  if (const ConstantArrayType *CAT =
+        SemaRef.Context.getAsConstantArrayType(DeclType)) {
+    maxElements = CAT->getSize();
+    elementIndex.extOrTrunc(maxElements.getBitWidth());
+    elementIndex.setIsUnsigned(maxElements.isUnsigned());
+    maxElementsKnown = true;
+  }
+
+  QualType elementType = SemaRef.Context.getAsArrayType(DeclType)
+                             ->getElementType();
+  while (Index < IList->getNumInits()) {
+    Expr *Init = IList->getInit(Index);
+    if (DesignatedInitExpr *DIE = dyn_cast<DesignatedInitExpr>(Init)) {
+      // If we're not the subobject that matches up with the '{' for
+      // the designator, we shouldn't be handling the
+      // designator. Return immediately.
+      if (!SubobjectIsDesignatorContext)
+        return;
+
+      // Handle this designated initializer. elementIndex will be
+      // updated to be the next array element we'll initialize.
+      if (CheckDesignatedInitializer(Entity, IList, DIE, 0,
+                                     DeclType, 0, &elementIndex, Index,
+                                     StructuredList, StructuredIndex, true,
+                                     false)) {
+        hadError = true;
+        continue;
+      }
+
+      if (elementIndex.getBitWidth() > maxElements.getBitWidth())
+        maxElements.extend(elementIndex.getBitWidth());
+      else if (elementIndex.getBitWidth() < maxElements.getBitWidth())
+        elementIndex.extend(maxElements.getBitWidth());
+      elementIndex.setIsUnsigned(maxElements.isUnsigned());
+
+      // If the array is of incomplete type, keep track of the number of
+      // elements in the initializer.
+      if (!maxElementsKnown && elementIndex > maxElements)
+        maxElements = elementIndex;
+
+      continue;
+    }
+
+    // If we know the maximum number of elements, and we've already
+    // hit it, stop consuming elements in the initializer list.
+    if (maxElementsKnown && elementIndex == maxElements)
+      break;
+
+    InitializedEntity ElementEntity =
+      InitializedEntity::InitializeElement(SemaRef.Context, StructuredIndex, 
+                                           Entity);
+    // Check this element.
+    CheckSubElementType(ElementEntity, IList, elementType, Index,
+                        StructuredList, StructuredIndex);
+    ++elementIndex;
+
+    // If the array is of incomplete type, keep track of the number of
+    // elements in the initializer.
+    if (!maxElementsKnown && elementIndex > maxElements)
+      maxElements = elementIndex;
+  }
+  if (!hadError && DeclType->isIncompleteArrayType()) {
+    // If this is an incomplete array type, the actual type needs to
+    // be calculated here.
+    llvm::APSInt Zero(maxElements.getBitWidth(), maxElements.isUnsigned());
+    if (maxElements == Zero) {
+      // Sizing an array implicitly to zero is not allowed by ISO C,
+      // but is supported by GNU.
+      SemaRef.Diag(IList->getLocStart(),
+                    diag::ext_typecheck_zero_array_size);
+    }
+
+    DeclType = SemaRef.Context.getConstantArrayType(elementType, maxElements,
+                                                     ArrayType::Normal, 0);
+  }
+}
+
+void InitListChecker::CheckStructUnionTypes(const InitializedEntity &Entity,
+                                            InitListExpr *IList,
+                                            QualType DeclType,
+                                            RecordDecl::field_iterator Field,
+                                            bool SubobjectIsDesignatorContext,
+                                            unsigned &Index,
+                                            InitListExpr *StructuredList,
+                                            unsigned &StructuredIndex,
+                                            bool TopLevelObject) {
+  RecordDecl* structDecl = DeclType->getAs<RecordType>()->getDecl();
+
+  // If the record is invalid, some of it's members are invalid. To avoid
+  // confusion, we forgo checking the intializer for the entire record.
+  if (structDecl->isInvalidDecl()) {
+    hadError = true;
+    return;
+  }
+
+  if (DeclType->isUnionType() && IList->getNumInits() == 0) {
+    // Value-initialize the first named member of the union.
+    RecordDecl *RD = DeclType->getAs<RecordType>()->getDecl();
+    for (RecordDecl::field_iterator FieldEnd = RD->field_end();
+         Field != FieldEnd; ++Field) {
+      if (Field->getDeclName()) {
+        StructuredList->setInitializedFieldInUnion(*Field);
+        break;
+      }
+    }
+    return;
+  }
+
+  // If structDecl is a forward declaration, this loop won't do
+  // anything except look at designated initializers; That's okay,
+  // because an error should get printed out elsewhere. It might be
+  // worthwhile to skip over the rest of the initializer, though.
+  RecordDecl *RD = DeclType->getAs<RecordType>()->getDecl();
+  RecordDecl::field_iterator FieldEnd = RD->field_end();
+  bool InitializedSomething = false;
+  bool CheckForMissingFields = true;
+  while (Index < IList->getNumInits()) {
+    Expr *Init = IList->getInit(Index);
+
+    if (DesignatedInitExpr *DIE = dyn_cast<DesignatedInitExpr>(Init)) {
+      // If we're not the subobject that matches up with the '{' for
+      // the designator, we shouldn't be handling the
+      // designator. Return immediately.
+      if (!SubobjectIsDesignatorContext)
+        return;
+
+      // Handle this designated initializer. Field will be updated to
+      // the next field that we'll be initializing.
+      if (CheckDesignatedInitializer(Entity, IList, DIE, 0,
+                                     DeclType, &Field, 0, Index,
+                                     StructuredList, StructuredIndex,
+                                     true, TopLevelObject))
+        hadError = true;
+
+      InitializedSomething = true;
+
+      // Disable check for missing fields when designators are used.
+      // This matches gcc behaviour.
+      CheckForMissingFields = false;
+      continue;
+    }
+
+    if (Field == FieldEnd) {
+      // We've run out of fields. We're done.
+      break;
+    }
+
+    // We've already initialized a member of a union. We're done.
+    if (InitializedSomething && DeclType->isUnionType())
+      break;
+
+    // If we've hit the flexible array member at the end, we're done.
+    if (Field->getType()->isIncompleteArrayType())
+      break;
+
+    if (Field->isUnnamedBitfield()) {
+      // Don't initialize unnamed bitfields, e.g. "int : 20;"
+      ++Field;
+      continue;
+    }
+
+    InitializedEntity MemberEntity =
+      InitializedEntity::InitializeMember(*Field, &Entity);
+    CheckSubElementType(MemberEntity, IList, Field->getType(), Index,
+                        StructuredList, StructuredIndex);
+    InitializedSomething = true;
+
+    if (DeclType->isUnionType()) {
+      // Initialize the first field within the union.
+      StructuredList->setInitializedFieldInUnion(*Field);
+    }
+
+    ++Field;
+  }
+
+  // Emit warnings for missing struct field initializers.
+  if (CheckForMissingFields && Field != FieldEnd && 
+      !Field->getType()->isIncompleteArrayType() && !DeclType->isUnionType()) {
+    // It is possible we have one or more unnamed bitfields remaining.
+    // Find first (if any) named field and emit warning.
+    for (RecordDecl::field_iterator it = Field, end = RD->field_end();
+         it != end; ++it) {
+      if (!it->isUnnamedBitfield()) {
+        SemaRef.Diag(IList->getSourceRange().getEnd(),
+                     diag::warn_missing_field_initializers) << it->getName();
+        break;
+      }
+    }
+  }
+
+  if (Field == FieldEnd || !Field->getType()->isIncompleteArrayType() ||
+      Index >= IList->getNumInits())
+    return;
+
+  // Handle GNU flexible array initializers.
+  if (!TopLevelObject &&
+      (!isa<InitListExpr>(IList->getInit(Index)) ||
+       cast<InitListExpr>(IList->getInit(Index))->getNumInits() > 0)) {
+    SemaRef.Diag(IList->getInit(Index)->getSourceRange().getBegin(),
+                  diag::err_flexible_array_init_nonempty)
+      << IList->getInit(Index)->getSourceRange().getBegin();
+    SemaRef.Diag(Field->getLocation(), diag::note_flexible_array_member)
+      << *Field;
+    hadError = true;
+    ++Index;
+    return;
+  } else {
+    SemaRef.Diag(IList->getInit(Index)->getSourceRange().getBegin(),
+                 diag::ext_flexible_array_init)
+      << IList->getInit(Index)->getSourceRange().getBegin();
+    SemaRef.Diag(Field->getLocation(), diag::note_flexible_array_member)
+      << *Field;
+  }
+
+  InitializedEntity MemberEntity =
+    InitializedEntity::InitializeMember(*Field, &Entity);
+    
+  if (isa<InitListExpr>(IList->getInit(Index)))
+    CheckSubElementType(MemberEntity, IList, Field->getType(), Index, 
+                        StructuredList, StructuredIndex);
+  else
+    CheckImplicitInitList(MemberEntity, IList, Field->getType(), Index, 
+                          StructuredList, StructuredIndex);
+}
+
+/// \brief Expand a field designator that refers to a member of an
+/// anonymous struct or union into a series of field designators that
+/// refers to the field within the appropriate subobject.
+///
+/// Field/FieldIndex will be updated to point to the (new)
+/// currently-designated field.
+static void ExpandAnonymousFieldDesignator(Sema &SemaRef,
+                                           DesignatedInitExpr *DIE,
+                                           unsigned DesigIdx,
+                                           FieldDecl *Field,
+                                        RecordDecl::field_iterator &FieldIter,
+                                           unsigned &FieldIndex) {
+  typedef DesignatedInitExpr::Designator Designator;
+
+  // Build the path from the current object to the member of the
+  // anonymous struct/union (backwards).
+  llvm::SmallVector<FieldDecl *, 4> Path;
+  SemaRef.BuildAnonymousStructUnionMemberPath(Field, Path);
+
+  // Build the replacement designators.
+  llvm::SmallVector<Designator, 4> Replacements;
+  for (llvm::SmallVector<FieldDecl *, 4>::reverse_iterator
+         FI = Path.rbegin(), FIEnd = Path.rend();
+       FI != FIEnd; ++FI) {
+    if (FI + 1 == FIEnd)
+      Replacements.push_back(Designator((IdentifierInfo *)0,
+                                    DIE->getDesignator(DesigIdx)->getDotLoc(),
+                                DIE->getDesignator(DesigIdx)->getFieldLoc()));
+    else
+      Replacements.push_back(Designator((IdentifierInfo *)0, SourceLocation(),
+                                        SourceLocation()));
+    Replacements.back().setField(*FI);
+  }
+
+  // Expand the current designator into the set of replacement
+  // designators, so we have a full subobject path down to where the
+  // member of the anonymous struct/union is actually stored.
+  DIE->ExpandDesignator(SemaRef.Context, DesigIdx, &Replacements[0],
+                        &Replacements[0] + Replacements.size());
+
+  // Update FieldIter/FieldIndex;
+  RecordDecl *Record = cast<RecordDecl>(Path.back()->getDeclContext());
+  FieldIter = Record->field_begin();
+  FieldIndex = 0;
+  for (RecordDecl::field_iterator FEnd = Record->field_end();
+       FieldIter != FEnd; ++FieldIter) {
+    if (FieldIter->isUnnamedBitfield())
+        continue;
+
+    if (*FieldIter == Path.back())
+      return;
+
+    ++FieldIndex;
+  }
+
+  assert(false && "Unable to find anonymous struct/union field");
+}
+
+/// @brief Check the well-formedness of a C99 designated initializer.
+///
+/// Determines whether the designated initializer @p DIE, which
+/// resides at the given @p Index within the initializer list @p
+/// IList, is well-formed for a current object of type @p DeclType
+/// (C99 6.7.8). The actual subobject that this designator refers to
+/// within the current subobject is returned in either
+/// @p NextField or @p NextElementIndex (whichever is appropriate).
+///
+/// @param IList  The initializer list in which this designated
+/// initializer occurs.
+///
+/// @param DIE The designated initializer expression.
+///
+/// @param DesigIdx  The index of the current designator.
+///
+/// @param DeclType  The type of the "current object" (C99 6.7.8p17),
+/// into which the designation in @p DIE should refer.
+///
+/// @param NextField  If non-NULL and the first designator in @p DIE is
+/// a field, this will be set to the field declaration corresponding
+/// to the field named by the designator.
+///
+/// @param NextElementIndex  If non-NULL and the first designator in @p
+/// DIE is an array designator or GNU array-range designator, this
+/// will be set to the last index initialized by this designator.
+///
+/// @param Index  Index into @p IList where the designated initializer
+/// @p DIE occurs.
+///
+/// @param StructuredList  The initializer list expression that
+/// describes all of the subobject initializers in the order they'll
+/// actually be initialized.
+///
+/// @returns true if there was an error, false otherwise.
+bool
+InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity,
+                                            InitListExpr *IList,
+                                      DesignatedInitExpr *DIE,
+                                      unsigned DesigIdx,
+                                      QualType &CurrentObjectType,
+                                      RecordDecl::field_iterator *NextField,
+                                      llvm::APSInt *NextElementIndex,
+                                      unsigned &Index,
+                                      InitListExpr *StructuredList,
+                                      unsigned &StructuredIndex,
+                                            bool FinishSubobjectInit,
+                                            bool TopLevelObject) {
+  if (DesigIdx == DIE->size()) {
+    // Check the actual initialization for the designated object type.
+    bool prevHadError = hadError;
+
+    // Temporarily remove the designator expression from the
+    // initializer list that the child calls see, so that we don't try
+    // to re-process the designator.
+    unsigned OldIndex = Index;
+    IList->setInit(OldIndex, DIE->getInit());
+
+    CheckSubElementType(Entity, IList, CurrentObjectType, Index,
+                        StructuredList, StructuredIndex);
+
+    // Restore the designated initializer expression in the syntactic
+    // form of the initializer list.
+    if (IList->getInit(OldIndex) != DIE->getInit())
+      DIE->setInit(IList->getInit(OldIndex));
+    IList->setInit(OldIndex, DIE);
+
+    return hadError && !prevHadError;
+  }
+
+  bool IsFirstDesignator = (DesigIdx == 0);
+  assert((IsFirstDesignator || StructuredList) &&
+         "Need a non-designated initializer list to start from");
+
+  DesignatedInitExpr::Designator *D = DIE->getDesignator(DesigIdx);
+  // Determine the structural initializer list that corresponds to the
+  // current subobject.
+  StructuredList = IsFirstDesignator? SyntacticToSemantic[IList]
+    : getStructuredSubobjectInit(IList, Index, CurrentObjectType,
+                                 StructuredList, StructuredIndex,
+                                 SourceRange(D->getStartLocation(),
+                                             DIE->getSourceRange().getEnd()));
+  assert(StructuredList && "Expected a structured initializer list");
+
+  if (D->isFieldDesignator()) {
+    // C99 6.7.8p7:
+    //
+    //   If a designator has the form
+    //
+    //      . identifier
+    //
+    //   then the current object (defined below) shall have
+    //   structure or union type and the identifier shall be the
+    //   name of a member of that type.
+    const RecordType *RT = CurrentObjectType->getAs<RecordType>();
+    if (!RT) {
+      SourceLocation Loc = D->getDotLoc();
+      if (Loc.isInvalid())
+        Loc = D->getFieldLoc();
+      SemaRef.Diag(Loc, diag::err_field_designator_non_aggr)
+        << SemaRef.getLangOptions().CPlusPlus << CurrentObjectType;
+      ++Index;
+      return true;
+    }
+
+    // Note: we perform a linear search of the fields here, despite
+    // the fact that we have a faster lookup method, because we always
+    // need to compute the field's index.
+    FieldDecl *KnownField = D->getField();
+    IdentifierInfo *FieldName = D->getFieldName();
+    unsigned FieldIndex = 0;
+    RecordDecl::field_iterator
+      Field = RT->getDecl()->field_begin(),
+      FieldEnd = RT->getDecl()->field_end();
+    for (; Field != FieldEnd; ++Field) {
+      if (Field->isUnnamedBitfield())
+        continue;
+
+      if (KnownField == *Field || Field->getIdentifier() == FieldName)
+        break;
+
+      ++FieldIndex;
+    }
+
+    if (Field == FieldEnd) {
+      // There was no normal field in the struct with the designated
+      // name. Perform another lookup for this name, which may find
+      // something that we can't designate (e.g., a member function),
+      // may find nothing, or may find a member of an anonymous
+      // struct/union.
+      DeclContext::lookup_result Lookup = RT->getDecl()->lookup(FieldName);
+      FieldDecl *ReplacementField = 0;
+      if (Lookup.first == Lookup.second) {
+        // Name lookup didn't find anything. Determine whether this
+        // was a typo for another field name.
+        LookupResult R(SemaRef, FieldName, D->getFieldLoc(), 
+                       Sema::LookupMemberName);
+        if (SemaRef.CorrectTypo(R, /*Scope=*/0, /*SS=*/0, RT->getDecl(), false,
+                                Sema::CTC_NoKeywords) && 
+            (ReplacementField = R.getAsSingle<FieldDecl>()) &&
+            ReplacementField->getDeclContext()->getLookupContext()
+                                                      ->Equals(RT->getDecl())) {
+          SemaRef.Diag(D->getFieldLoc(), 
+                       diag::err_field_designator_unknown_suggest)
+            << FieldName << CurrentObjectType << R.getLookupName()
+            << FixItHint::CreateReplacement(D->getFieldLoc(),
+                                            R.getLookupName().getAsString());
+          SemaRef.Diag(ReplacementField->getLocation(), 
+                       diag::note_previous_decl)
+            << ReplacementField->getDeclName();
+        } else {
+          SemaRef.Diag(D->getFieldLoc(), diag::err_field_designator_unknown)
+            << FieldName << CurrentObjectType;
+          ++Index;
+          return true;
+        }
+      } else if (!KnownField) {
+        // Determine whether we found a field at all.
+        ReplacementField = dyn_cast<FieldDecl>(*Lookup.first);
+      }
+
+      if (!ReplacementField) {
+        // Name lookup found something, but it wasn't a field.
+        SemaRef.Diag(D->getFieldLoc(), diag::err_field_designator_nonfield)
+          << FieldName;
+        SemaRef.Diag((*Lookup.first)->getLocation(),
+                      diag::note_field_designator_found);
+        ++Index;
+        return true;
+      }
+
+      if (!KnownField && 
+          cast<RecordDecl>((ReplacementField)->getDeclContext())
+                                                 ->isAnonymousStructOrUnion()) {
+        // Handle an field designator that refers to a member of an
+        // anonymous struct or union.
+        ExpandAnonymousFieldDesignator(SemaRef, DIE, DesigIdx,
+                                       ReplacementField,
+                                       Field, FieldIndex);
+        D = DIE->getDesignator(DesigIdx);
+      } else if (!KnownField) {
+        // The replacement field comes from typo correction; find it
+        // in the list of fields.
+        FieldIndex = 0;
+        Field = RT->getDecl()->field_begin();
+        for (; Field != FieldEnd; ++Field) {
+          if (Field->isUnnamedBitfield())
+            continue;
+
+          if (ReplacementField == *Field || 
+              Field->getIdentifier() == ReplacementField->getIdentifier())
+            break;
+
+          ++FieldIndex;
+        }
+      }
+    } else if (!KnownField &&
+               cast<RecordDecl>((*Field)->getDeclContext())
+                 ->isAnonymousStructOrUnion()) {
+      ExpandAnonymousFieldDesignator(SemaRef, DIE, DesigIdx, *Field,
+                                     Field, FieldIndex);
+      D = DIE->getDesignator(DesigIdx);
+    }
+
+    // All of the fields of a union are located at the same place in
+    // the initializer list.
+    if (RT->getDecl()->isUnion()) {
+      FieldIndex = 0;
+      StructuredList->setInitializedFieldInUnion(*Field);
+    }
+
+    // Update the designator with the field declaration.
+    D->setField(*Field);
+
+    // Make sure that our non-designated initializer list has space
+    // for a subobject corresponding to this field.
+    if (FieldIndex >= StructuredList->getNumInits())
+      StructuredList->resizeInits(SemaRef.Context, FieldIndex + 1);
+
+    // This designator names a flexible array member.
+    if (Field->getType()->isIncompleteArrayType()) {
+      bool Invalid = false;
+      if ((DesigIdx + 1) != DIE->size()) {
+        // We can't designate an object within the flexible array
+        // member (because GCC doesn't allow it).
+        DesignatedInitExpr::Designator *NextD
+          = DIE->getDesignator(DesigIdx + 1);
+        SemaRef.Diag(NextD->getStartLocation(),
+                      diag::err_designator_into_flexible_array_member)
+          << SourceRange(NextD->getStartLocation(),
+                         DIE->getSourceRange().getEnd());
+        SemaRef.Diag(Field->getLocation(), diag::note_flexible_array_member)
+          << *Field;
+        Invalid = true;
+      }
+
+      if (!hadError && !isa<InitListExpr>(DIE->getInit())) {
+        // The initializer is not an initializer list.
+        SemaRef.Diag(DIE->getInit()->getSourceRange().getBegin(),
+                      diag::err_flexible_array_init_needs_braces)
+          << DIE->getInit()->getSourceRange();
+        SemaRef.Diag(Field->getLocation(), diag::note_flexible_array_member)
+          << *Field;
+        Invalid = true;
+      }
+
+      // Handle GNU flexible array initializers.
+      if (!Invalid && !TopLevelObject &&
+          cast<InitListExpr>(DIE->getInit())->getNumInits() > 0) {
+        SemaRef.Diag(DIE->getSourceRange().getBegin(),
+                      diag::err_flexible_array_init_nonempty)
+          << DIE->getSourceRange().getBegin();
+        SemaRef.Diag(Field->getLocation(), diag::note_flexible_array_member)
+          << *Field;
+        Invalid = true;
+      }
+
+      if (Invalid) {
+        ++Index;
+        return true;
+      }
+
+      // Initialize the array.
+      bool prevHadError = hadError;
+      unsigned newStructuredIndex = FieldIndex;
+      unsigned OldIndex = Index;
+      IList->setInit(Index, DIE->getInit());
+
+      InitializedEntity MemberEntity =
+        InitializedEntity::InitializeMember(*Field, &Entity);
+      CheckSubElementType(MemberEntity, IList, Field->getType(), Index,
+                          StructuredList, newStructuredIndex);
+
+      IList->setInit(OldIndex, DIE);
+      if (hadError && !prevHadError) {
+        ++Field;
+        ++FieldIndex;
+        if (NextField)
+          *NextField = Field;
+        StructuredIndex = FieldIndex;
+        return true;
+      }
+    } else {
+      // Recurse to check later designated subobjects.
+      QualType FieldType = (*Field)->getType();
+      unsigned newStructuredIndex = FieldIndex;
+      
+      InitializedEntity MemberEntity =
+        InitializedEntity::InitializeMember(*Field, &Entity);
+      if (CheckDesignatedInitializer(MemberEntity, IList, DIE, DesigIdx + 1, 
+                                     FieldType, 0, 0, Index, 
+                                     StructuredList, newStructuredIndex,
+                                     true, false))
+        return true;
+    }
+
+    // Find the position of the next field to be initialized in this
+    // subobject.
+    ++Field;
+    ++FieldIndex;
+
+    // If this the first designator, our caller will continue checking
+    // the rest of this struct/class/union subobject.
+    if (IsFirstDesignator) {
+      if (NextField)
+        *NextField = Field;
+      StructuredIndex = FieldIndex;
+      return false;
+    }
+
+    if (!FinishSubobjectInit)
+      return false;
+
+    // We've already initialized something in the union; we're done.
+    if (RT->getDecl()->isUnion())
+      return hadError;
+
+    // Check the remaining fields within this class/struct/union subobject.
+    bool prevHadError = hadError;
+    
+    CheckStructUnionTypes(Entity, IList, CurrentObjectType, Field, false, Index,
+                          StructuredList, FieldIndex);
+    return hadError && !prevHadError;
+  }
+
+  // C99 6.7.8p6:
+  //
+  //   If a designator has the form
+  //
+  //      [ constant-expression ]
+  //
+  //   then the current object (defined below) shall have array
+  //   type and the expression shall be an integer constant
+  //   expression. If the array is of unknown size, any
+  //   nonnegative value is valid.
+  //
+  // Additionally, cope with the GNU extension that permits
+  // designators of the form
+  //
+  //      [ constant-expression ... constant-expression ]
+  const ArrayType *AT = SemaRef.Context.getAsArrayType(CurrentObjectType);
+  if (!AT) {
+    SemaRef.Diag(D->getLBracketLoc(), diag::err_array_designator_non_array)
+      << CurrentObjectType;
+    ++Index;
+    return true;
+  }
+
+  Expr *IndexExpr = 0;
+  llvm::APSInt DesignatedStartIndex, DesignatedEndIndex;
+  if (D->isArrayDesignator()) {
+    IndexExpr = DIE->getArrayIndex(*D);
+    DesignatedStartIndex = IndexExpr->EvaluateAsInt(SemaRef.Context);
+    DesignatedEndIndex = DesignatedStartIndex;
+  } else {
+    assert(D->isArrayRangeDesignator() && "Need array-range designator");
+
+
+    DesignatedStartIndex =
+      DIE->getArrayRangeStart(*D)->EvaluateAsInt(SemaRef.Context);
+    DesignatedEndIndex =
+      DIE->getArrayRangeEnd(*D)->EvaluateAsInt(SemaRef.Context);
+    IndexExpr = DIE->getArrayRangeEnd(*D);
+
+    if (DesignatedStartIndex.getZExtValue() !=DesignatedEndIndex.getZExtValue())
+      FullyStructuredList->sawArrayRangeDesignator();
+  }
+
+  if (isa<ConstantArrayType>(AT)) {
+    llvm::APSInt MaxElements(cast<ConstantArrayType>(AT)->getSize(), false);
+    DesignatedStartIndex.extOrTrunc(MaxElements.getBitWidth());
+    DesignatedStartIndex.setIsUnsigned(MaxElements.isUnsigned());
+    DesignatedEndIndex.extOrTrunc(MaxElements.getBitWidth());
+    DesignatedEndIndex.setIsUnsigned(MaxElements.isUnsigned());
+    if (DesignatedEndIndex >= MaxElements) {
+      SemaRef.Diag(IndexExpr->getSourceRange().getBegin(),
+                    diag::err_array_designator_too_large)
+        << DesignatedEndIndex.toString(10) << MaxElements.toString(10)
+        << IndexExpr->getSourceRange();
+      ++Index;
+      return true;
+    }
+  } else {
+    // Make sure the bit-widths and signedness match.
+    if (DesignatedStartIndex.getBitWidth() > DesignatedEndIndex.getBitWidth())
+      DesignatedEndIndex.extend(DesignatedStartIndex.getBitWidth());
+    else if (DesignatedStartIndex.getBitWidth() <
+             DesignatedEndIndex.getBitWidth())
+      DesignatedStartIndex.extend(DesignatedEndIndex.getBitWidth());
+    DesignatedStartIndex.setIsUnsigned(true);
+    DesignatedEndIndex.setIsUnsigned(true);
+  }
+
+  // Make sure that our non-designated initializer list has space
+  // for a subobject corresponding to this array element.
+  if (DesignatedEndIndex.getZExtValue() >= StructuredList->getNumInits())
+    StructuredList->resizeInits(SemaRef.Context,
+                                DesignatedEndIndex.getZExtValue() + 1);
+
+  // Repeatedly perform subobject initializations in the range
+  // [DesignatedStartIndex, DesignatedEndIndex].
+
+  // Move to the next designator
+  unsigned ElementIndex = DesignatedStartIndex.getZExtValue();
+  unsigned OldIndex = Index;
+  
+  InitializedEntity ElementEntity =
+    InitializedEntity::InitializeElement(SemaRef.Context, 0, Entity);
+
+  while (DesignatedStartIndex <= DesignatedEndIndex) {
+    // Recurse to check later designated subobjects.
+    QualType ElementType = AT->getElementType();
+    Index = OldIndex;
+    
+    ElementEntity.setElementIndex(ElementIndex);
+    if (CheckDesignatedInitializer(ElementEntity, IList, DIE, DesigIdx + 1, 
+                                   ElementType, 0, 0, Index, 
+                                   StructuredList, ElementIndex,
+                                   (DesignatedStartIndex == DesignatedEndIndex),
+                                   false))
+      return true;
+
+    // Move to the next index in the array that we'll be initializing.
+    ++DesignatedStartIndex;
+    ElementIndex = DesignatedStartIndex.getZExtValue();
+  }
+
+  // If this the first designator, our caller will continue checking
+  // the rest of this array subobject.
+  if (IsFirstDesignator) {
+    if (NextElementIndex)
+      *NextElementIndex = DesignatedStartIndex;
+    StructuredIndex = ElementIndex;
+    return false;
+  }
+
+  if (!FinishSubobjectInit)
+    return false;
+
+  // Check the remaining elements within this array subobject.
+  bool prevHadError = hadError;
+  CheckArrayType(Entity, IList, CurrentObjectType, DesignatedStartIndex, 
+                 /*SubobjectIsDesignatorContext=*/false, Index,
+                 StructuredList, ElementIndex);
+  return hadError && !prevHadError;
+}
+
+// Get the structured initializer list for a subobject of type
+// @p CurrentObjectType.
+InitListExpr *
+InitListChecker::getStructuredSubobjectInit(InitListExpr *IList, unsigned Index,
+                                            QualType CurrentObjectType,
+                                            InitListExpr *StructuredList,
+                                            unsigned StructuredIndex,
+                                            SourceRange InitRange) {
+  Expr *ExistingInit = 0;
+  if (!StructuredList)
+    ExistingInit = SyntacticToSemantic[IList];
+  else if (StructuredIndex < StructuredList->getNumInits())
+    ExistingInit = StructuredList->getInit(StructuredIndex);
+
+  if (InitListExpr *Result = dyn_cast_or_null<InitListExpr>(ExistingInit))
+    return Result;
+
+  if (ExistingInit) {
+    // We are creating an initializer list that initializes the
+    // subobjects of the current object, but there was already an
+    // initialization that completely initialized the current
+    // subobject, e.g., by a compound literal:
+    //
+    // struct X { int a, b; };
+    // struct X xs[] = { [0] = (struct X) { 1, 2 }, [0].b = 3 };
+    //
+    // Here, xs[0].a == 0 and xs[0].b == 3, since the second,
+    // designated initializer re-initializes the whole
+    // subobject [0], overwriting previous initializers.
+    SemaRef.Diag(InitRange.getBegin(),
+                 diag::warn_subobject_initializer_overrides)
+      << InitRange;
+    SemaRef.Diag(ExistingInit->getSourceRange().getBegin(),
+                  diag::note_previous_initializer)
+      << /*FIXME:has side effects=*/0
+      << ExistingInit->getSourceRange();
+  }
+
+  InitListExpr *Result
+    = new (SemaRef.Context) InitListExpr(SemaRef.Context,
+                                         InitRange.getBegin(), 0, 0,
+                                         InitRange.getEnd());
+
+  Result->setType(CurrentObjectType.getNonReferenceType());
+
+  // Pre-allocate storage for the structured initializer list.
+  unsigned NumElements = 0;
+  unsigned NumInits = 0;
+  if (!StructuredList)
+    NumInits = IList->getNumInits();
+  else if (Index < IList->getNumInits()) {
+    if (InitListExpr *SubList = dyn_cast<InitListExpr>(IList->getInit(Index)))
+      NumInits = SubList->getNumInits();
+  }
+
+  if (const ArrayType *AType
+      = SemaRef.Context.getAsArrayType(CurrentObjectType)) {
+    if (const ConstantArrayType *CAType = dyn_cast<ConstantArrayType>(AType)) {
+      NumElements = CAType->getSize().getZExtValue();
+      // Simple heuristic so that we don't allocate a very large
+      // initializer with many empty entries at the end.
+      if (NumInits && NumElements > NumInits)
+        NumElements = 0;
+    }
+  } else if (const VectorType *VType = CurrentObjectType->getAs<VectorType>())
+    NumElements = VType->getNumElements();
+  else if (const RecordType *RType = CurrentObjectType->getAs<RecordType>()) {
+    RecordDecl *RDecl = RType->getDecl();
+    if (RDecl->isUnion())
+      NumElements = 1;
+    else
+      NumElements = std::distance(RDecl->field_begin(),
+                                  RDecl->field_end());
+  }
+
+  if (NumElements < NumInits)
+    NumElements = IList->getNumInits();
+
+  Result->reserveInits(SemaRef.Context, NumElements);
+
+  // Link this new initializer list into the structured initializer
+  // lists.
+  if (StructuredList)
+    StructuredList->updateInit(SemaRef.Context, StructuredIndex, Result);
+  else {
+    Result->setSyntacticForm(IList);
+    SyntacticToSemantic[IList] = Result;
+  }
+
+  return Result;
+}
+
+/// Update the initializer at index @p StructuredIndex within the
+/// structured initializer list to the value @p expr.
+void InitListChecker::UpdateStructuredListElement(InitListExpr *StructuredList,
+                                                  unsigned &StructuredIndex,
+                                                  Expr *expr) {
+  // No structured initializer list to update
+  if (!StructuredList)
+    return;
+
+  if (Expr *PrevInit = StructuredList->updateInit(SemaRef.Context,
+                                                  StructuredIndex, expr)) {
+    // This initializer overwrites a previous initializer. Warn.
+    SemaRef.Diag(expr->getSourceRange().getBegin(),
+                  diag::warn_initializer_overrides)
+      << expr->getSourceRange();
+    SemaRef.Diag(PrevInit->getSourceRange().getBegin(),
+                  diag::note_previous_initializer)
+      << /*FIXME:has side effects=*/0
+      << PrevInit->getSourceRange();
+  }
+
+  ++StructuredIndex;
+}
+
+/// Check that the given Index expression is a valid array designator
+/// value. This is essentailly just a wrapper around
+/// VerifyIntegerConstantExpression that also checks for negative values
+/// and produces a reasonable diagnostic if there is a
+/// failure. Returns true if there was an error, false otherwise.  If
+/// everything went okay, Value will receive the value of the constant
+/// expression.
+static bool
+CheckArrayDesignatorExpr(Sema &S, Expr *Index, llvm::APSInt &Value) {
+  SourceLocation Loc = Index->getSourceRange().getBegin();
+
+  // Make sure this is an integer constant expression.
+  if (S.VerifyIntegerConstantExpression(Index, &Value))
+    return true;
+
+  if (Value.isSigned() && Value.isNegative())
+    return S.Diag(Loc, diag::err_array_designator_negative)
+      << Value.toString(10) << Index->getSourceRange();
+
+  Value.setIsUnsigned(true);
+  return false;
+}
+
+Sema::OwningExprResult Sema::ActOnDesignatedInitializer(Designation &Desig,
+                                                        SourceLocation Loc,
+                                                        bool GNUSyntax,
+                                                        OwningExprResult Init) {
+  typedef DesignatedInitExpr::Designator ASTDesignator;
+
+  bool Invalid = false;
+  llvm::SmallVector<ASTDesignator, 32> Designators;
+  llvm::SmallVector<Expr *, 32> InitExpressions;
+
+  // Build designators and check array designator expressions.
+  for (unsigned Idx = 0; Idx < Desig.getNumDesignators(); ++Idx) {
+    const Designator &D = Desig.getDesignator(Idx);
+    switch (D.getKind()) {
+    case Designator::FieldDesignator:
+      Designators.push_back(ASTDesignator(D.getField(), D.getDotLoc(),
+                                          D.getFieldLoc()));
+      break;
+
+    case Designator::ArrayDesignator: {
+      Expr *Index = static_cast<Expr *>(D.getArrayIndex());
+      llvm::APSInt IndexValue;
+      if (!Index->isTypeDependent() &&
+          !Index->isValueDependent() &&
+          CheckArrayDesignatorExpr(*this, Index, IndexValue))
+        Invalid = true;
+      else {
+        Designators.push_back(ASTDesignator(InitExpressions.size(),
+                                            D.getLBracketLoc(),
+                                            D.getRBracketLoc()));
+        InitExpressions.push_back(Index);
+      }
+      break;
+    }
+
+    case Designator::ArrayRangeDesignator: {
+      Expr *StartIndex = static_cast<Expr *>(D.getArrayRangeStart());
+      Expr *EndIndex = static_cast<Expr *>(D.getArrayRangeEnd());
+      llvm::APSInt StartValue;
+      llvm::APSInt EndValue;
+      bool StartDependent = StartIndex->isTypeDependent() ||
+                            StartIndex->isValueDependent();
+      bool EndDependent = EndIndex->isTypeDependent() ||
+                          EndIndex->isValueDependent();
+      if ((!StartDependent &&
+           CheckArrayDesignatorExpr(*this, StartIndex, StartValue)) ||
+          (!EndDependent &&
+           CheckArrayDesignatorExpr(*this, EndIndex, EndValue)))
+        Invalid = true;
+      else {
+        // Make sure we're comparing values with the same bit width.
+        if (StartDependent || EndDependent) {
+          // Nothing to compute.
+        } else if (StartValue.getBitWidth() > EndValue.getBitWidth())
+          EndValue.extend(StartValue.getBitWidth());
+        else if (StartValue.getBitWidth() < EndValue.getBitWidth())
+          StartValue.extend(EndValue.getBitWidth());
+
+        if (!StartDependent && !EndDependent && EndValue < StartValue) {
+          Diag(D.getEllipsisLoc(), diag::err_array_designator_empty_range)
+            << StartValue.toString(10) << EndValue.toString(10)
+            << StartIndex->getSourceRange() << EndIndex->getSourceRange();
+          Invalid = true;
+        } else {
+          Designators.push_back(ASTDesignator(InitExpressions.size(),
+                                              D.getLBracketLoc(),
+                                              D.getEllipsisLoc(),
+                                              D.getRBracketLoc()));
+          InitExpressions.push_back(StartIndex);
+          InitExpressions.push_back(EndIndex);
+        }
+      }
+      break;
+    }
+    }
+  }
+
+  if (Invalid || Init.isInvalid())
+    return ExprError();
+
+  // Clear out the expressions within the designation.
+  Desig.ClearExprs(*this);
+
+  DesignatedInitExpr *DIE
+    = DesignatedInitExpr::Create(Context,
+                                 Designators.data(), Designators.size(),
+                                 InitExpressions.data(), InitExpressions.size(),
+                                 Loc, GNUSyntax, Init.takeAs<Expr>());
+  return Owned(DIE);
+}
+
+bool Sema::CheckInitList(const InitializedEntity &Entity,
+                         InitListExpr *&InitList, QualType &DeclType) {
+  InitListChecker CheckInitList(*this, Entity, InitList, DeclType);
+  if (!CheckInitList.HadError())
+    InitList = CheckInitList.getFullyStructuredList();
+
+  return CheckInitList.HadError();
+}
+
+//===----------------------------------------------------------------------===//
+// Initialization entity
+//===----------------------------------------------------------------------===//
+
+InitializedEntity::InitializedEntity(ASTContext &Context, unsigned Index, 
+                                     const InitializedEntity &Parent)
+  : Parent(&Parent), Index(Index) 
+{
+  if (const ArrayType *AT = Context.getAsArrayType(Parent.getType())) {
+    Kind = EK_ArrayElement;
+    Type = AT->getElementType();
+  } else {
+    Kind = EK_VectorElement;
+    Type = Parent.getType()->getAs<VectorType>()->getElementType();
+  }
+}
+
+InitializedEntity InitializedEntity::InitializeBase(ASTContext &Context, 
+                                                    CXXBaseSpecifier *Base,
+                                                    bool IsInheritedVirtualBase)
+{
+  InitializedEntity Result;
+  Result.Kind = EK_Base;
+  Result.Base = reinterpret_cast<uintptr_t>(Base);
+  if (IsInheritedVirtualBase)
+    Result.Base |= 0x01;
+  
+  Result.Type = Base->getType();
+  return Result;
+}
+
+DeclarationName InitializedEntity::getName() const {
+  switch (getKind()) {
+  case EK_Parameter:
+    if (!VariableOrMember)
+      return DeclarationName();
+    // Fall through
+
+  case EK_Variable:
+  case EK_Member:
+    return VariableOrMember->getDeclName();
+
+  case EK_Result:
+  case EK_Exception:
+  case EK_New:
+  case EK_Temporary:
+  case EK_Base:
+  case EK_ArrayElement:
+  case EK_VectorElement:
+    return DeclarationName();
+  }
+  
+  // Silence GCC warning
+  return DeclarationName();
+}
+
+DeclaratorDecl *InitializedEntity::getDecl() const {
+  switch (getKind()) {
+  case EK_Variable:
+  case EK_Parameter:
+  case EK_Member:
+    return VariableOrMember;
+
+  case EK_Result:
+  case EK_Exception:
+  case EK_New:
+  case EK_Temporary:
+  case EK_Base:
+  case EK_ArrayElement:
+  case EK_VectorElement:
+    return 0;
+  }
+  
+  // Silence GCC warning
+  return 0;
+}
+
+//===----------------------------------------------------------------------===//
+// Initialization sequence
+//===----------------------------------------------------------------------===//
+
+void InitializationSequence::Step::Destroy() {
+  switch (Kind) {
+  case SK_ResolveAddressOfOverloadedFunction:
+  case SK_CastDerivedToBaseRValue:
+  case SK_CastDerivedToBaseLValue:
+  case SK_BindReference:
+  case SK_BindReferenceToTemporary:
+  case SK_ExtraneousCopyToTemporary:
+  case SK_UserConversion:
+  case SK_QualificationConversionRValue:
+  case SK_QualificationConversionLValue:
+  case SK_ListInitialization:
+  case SK_ConstructorInitialization:
+  case SK_ZeroInitialization:
+  case SK_CAssignment:
+  case SK_StringInit:
+    break;
+    
+  case SK_ConversionSequence:
+    delete ICS;
+  }
+}
+
+bool InitializationSequence::isDirectReferenceBinding() const {
+  return getKind() == ReferenceBinding && Steps.back().Kind == SK_BindReference;
+}
+
+bool InitializationSequence::isAmbiguous() const {
+  if (getKind() != FailedSequence)
+    return false;
+  
+  switch (getFailureKind()) {
+  case FK_TooManyInitsForReference:
+  case FK_ArrayNeedsInitList:
+  case FK_ArrayNeedsInitListOrStringLiteral:
+  case FK_AddressOfOverloadFailed: // FIXME: Could do better
+  case FK_NonConstLValueReferenceBindingToTemporary:
+  case FK_NonConstLValueReferenceBindingToUnrelated:
+  case FK_RValueReferenceBindingToLValue:
+  case FK_ReferenceInitDropsQualifiers:
+  case FK_ReferenceInitFailed:
+  case FK_ConversionFailed:
+  case FK_TooManyInitsForScalar:
+  case FK_ReferenceBindingToInitList:
+  case FK_InitListBadDestinationType:
+  case FK_DefaultInitOfConst:
+    return false;
+    
+  case FK_ReferenceInitOverloadFailed:
+  case FK_UserConversionOverloadFailed:
+  case FK_ConstructorOverloadFailed:
+    return FailedOverloadResult == OR_Ambiguous;
+  }
+  
+  return false;
+}
+
+bool InitializationSequence::isConstructorInitialization() const {
+  return !Steps.empty() && Steps.back().Kind == SK_ConstructorInitialization;
+}
+
+void InitializationSequence::AddAddressOverloadResolutionStep(
+                                                      FunctionDecl *Function,
+                                                      DeclAccessPair Found) {
+  Step S;
+  S.Kind = SK_ResolveAddressOfOverloadedFunction;
+  S.Type = Function->getType();
+  S.Function.Function = Function;
+  S.Function.FoundDecl = Found;
+  Steps.push_back(S);
+}
+
+void InitializationSequence::AddDerivedToBaseCastStep(QualType BaseType, 
+                                                      bool IsLValue) {
+  Step S;
+  S.Kind = IsLValue? SK_CastDerivedToBaseLValue : SK_CastDerivedToBaseRValue;
+  S.Type = BaseType;
+  Steps.push_back(S);
+}
+
+void InitializationSequence::AddReferenceBindingStep(QualType T, 
+                                                     bool BindingTemporary) {
+  Step S;
+  S.Kind = BindingTemporary? SK_BindReferenceToTemporary : SK_BindReference;
+  S.Type = T;
+  Steps.push_back(S);
+}
+
+void InitializationSequence::AddExtraneousCopyToTemporary(QualType T) {
+  Step S;
+  S.Kind = SK_ExtraneousCopyToTemporary;
+  S.Type = T;
+  Steps.push_back(S);
+}
+
+void InitializationSequence::AddUserConversionStep(FunctionDecl *Function,
+                                                   DeclAccessPair FoundDecl,
+                                                   QualType T) {
+  Step S;
+  S.Kind = SK_UserConversion;
+  S.Type = T;
+  S.Function.Function = Function;
+  S.Function.FoundDecl = FoundDecl;
+  Steps.push_back(S);
+}
+
+void InitializationSequence::AddQualificationConversionStep(QualType Ty,
+                                                            bool IsLValue) {
+  Step S;
+  S.Kind = IsLValue? SK_QualificationConversionLValue 
+                   : SK_QualificationConversionRValue;
+  S.Type = Ty;
+  Steps.push_back(S);
+}
+
+void InitializationSequence::AddConversionSequenceStep(
+                                       const ImplicitConversionSequence &ICS,
+                                                       QualType T) {
+  Step S;
+  S.Kind = SK_ConversionSequence;
+  S.Type = T;
+  S.ICS = new ImplicitConversionSequence(ICS);
+  Steps.push_back(S);
+}
+
+void InitializationSequence::AddListInitializationStep(QualType T) {
+  Step S;
+  S.Kind = SK_ListInitialization;
+  S.Type = T;
+  Steps.push_back(S);
+}
+
+void 
+InitializationSequence::AddConstructorInitializationStep(
+                                              CXXConstructorDecl *Constructor,
+                                                       AccessSpecifier Access,
+                                                         QualType T) {
+  Step S;
+  S.Kind = SK_ConstructorInitialization;
+  S.Type = T;
+  S.Function.Function = Constructor;
+  S.Function.FoundDecl = DeclAccessPair::make(Constructor, Access);
+  Steps.push_back(S);
+}
+
+void InitializationSequence::AddZeroInitializationStep(QualType T) {
+  Step S;
+  S.Kind = SK_ZeroInitialization;
+  S.Type = T;
+  Steps.push_back(S);
+}
+
+void InitializationSequence::AddCAssignmentStep(QualType T) {
+  Step S;
+  S.Kind = SK_CAssignment;
+  S.Type = T;
+  Steps.push_back(S);
+}
+
+void InitializationSequence::AddStringInitStep(QualType T) {
+  Step S;
+  S.Kind = SK_StringInit;
+  S.Type = T;
+  Steps.push_back(S);
+}
+
+void InitializationSequence::SetOverloadFailure(FailureKind Failure, 
+                                                OverloadingResult Result) {
+  SequenceKind = FailedSequence;
+  this->Failure = Failure;
+  this->FailedOverloadResult = Result;
+}
+
+//===----------------------------------------------------------------------===//
+// Attempt initialization
+//===----------------------------------------------------------------------===//
+
+/// \brief Attempt list initialization (C++0x [dcl.init.list]) 
+static void TryListInitialization(Sema &S, 
+                                  const InitializedEntity &Entity,
+                                  const InitializationKind &Kind,
+                                  InitListExpr *InitList,
+                                  InitializationSequence &Sequence) {
+  // FIXME: We only perform rudimentary checking of list
+  // initializations at this point, then assume that any list
+  // initialization of an array, aggregate, or scalar will be
+  // well-formed. We we actually "perform" list initialization, we'll
+  // do all of the necessary checking.  C++0x initializer lists will
+  // force us to perform more checking here.
+  Sequence.setSequenceKind(InitializationSequence::ListInitialization);
+
+  QualType DestType = Entity.getType();
+
+  // C++ [dcl.init]p13:
+  //   If T is a scalar type, then a declaration of the form 
+  //
+  //     T x = { a };
+  //
+  //   is equivalent to
+  //
+  //     T x = a;
+  if (DestType->isScalarType()) {
+    if (InitList->getNumInits() > 1 && S.getLangOptions().CPlusPlus) {
+      Sequence.SetFailed(InitializationSequence::FK_TooManyInitsForScalar);
+      return;
+    }
+
+    // Assume scalar initialization from a single value works.
+  } else if (DestType->isAggregateType()) {
+    // Assume aggregate initialization works.
+  } else if (DestType->isVectorType()) {
+    // Assume vector initialization works.
+  } else if (DestType->isReferenceType()) {
+    // FIXME: C++0x defines behavior for this.
+    Sequence.SetFailed(InitializationSequence::FK_ReferenceBindingToInitList);
+    return;
+  } else if (DestType->isRecordType()) {
+    // FIXME: C++0x defines behavior for this
+    Sequence.SetFailed(InitializationSequence::FK_InitListBadDestinationType);
+  }
+
+  // Add a general "list initialization" step.
+  Sequence.AddListInitializationStep(DestType);
+}
+
+/// \brief Try a reference initialization that involves calling a conversion
+/// function.
+///
+/// FIXME: look intos DRs 656, 896
+static OverloadingResult TryRefInitWithConversionFunction(Sema &S,
+                                             const InitializedEntity &Entity,
+                                             const InitializationKind &Kind,
+                                                          Expr *Initializer,
+                                                          bool AllowRValues,
+                                             InitializationSequence &Sequence) {
+  QualType DestType = Entity.getType();
+  QualType cv1T1 = DestType->getAs<ReferenceType>()->getPointeeType();
+  QualType T1 = cv1T1.getUnqualifiedType();
+  QualType cv2T2 = Initializer->getType();
+  QualType T2 = cv2T2.getUnqualifiedType();
+
+  bool DerivedToBase;
+  assert(!S.CompareReferenceRelationship(Initializer->getLocStart(), 
+                                         T1, T2, DerivedToBase) &&
+         "Must have incompatible references when binding via conversion");
+  (void)DerivedToBase;
+
+  // Build the candidate set directly in the initialization sequence
+  // structure, so that it will persist if we fail.
+  OverloadCandidateSet &CandidateSet = Sequence.getFailedCandidateSet();
+  CandidateSet.clear();
+
+  // Determine whether we are allowed to call explicit constructors or
+  // explicit conversion operators.
+  bool AllowExplicit = Kind.getKind() == InitializationKind::IK_Direct;
+  
+  const RecordType *T1RecordType = 0;
+  if (AllowRValues && (T1RecordType = T1->getAs<RecordType>())) {
+    // The type we're converting to is a class type. Enumerate its constructors
+    // to see if there is a suitable conversion.
+    CXXRecordDecl *T1RecordDecl = cast<CXXRecordDecl>(T1RecordType->getDecl());
+    
+    DeclarationName ConstructorName
+      = S.Context.DeclarationNames.getCXXConstructorName(
+                           S.Context.getCanonicalType(T1).getUnqualifiedType());
+    DeclContext::lookup_iterator Con, ConEnd;
+    for (llvm::tie(Con, ConEnd) = T1RecordDecl->lookup(ConstructorName);
+         Con != ConEnd; ++Con) {
+      NamedDecl *D = *Con;
+      DeclAccessPair FoundDecl = DeclAccessPair::make(D, D->getAccess());
+
+      // Find the constructor (which may be a template).
+      CXXConstructorDecl *Constructor = 0;
+      FunctionTemplateDecl *ConstructorTmpl = dyn_cast<FunctionTemplateDecl>(D);
+      if (ConstructorTmpl)
+        Constructor = cast<CXXConstructorDecl>(
+                                         ConstructorTmpl->getTemplatedDecl());
+      else
+        Constructor = cast<CXXConstructorDecl>(D);
+      
+      if (!Constructor->isInvalidDecl() &&
+          Constructor->isConvertingConstructor(AllowExplicit)) {
+        if (ConstructorTmpl)
+          S.AddTemplateOverloadCandidate(ConstructorTmpl, FoundDecl,
+                                         /*ExplicitArgs*/ 0,
+                                         &Initializer, 1, CandidateSet);
+        else
+          S.AddOverloadCandidate(Constructor, FoundDecl,
+                                 &Initializer, 1, CandidateSet);
+      }
+    }    
+  }
+  
+  if (const RecordType *T2RecordType = T2->getAs<RecordType>()) {
+    // The type we're converting from is a class type, enumerate its conversion
+    // functions.
+    CXXRecordDecl *T2RecordDecl = cast<CXXRecordDecl>(T2RecordType->getDecl());
+
+    // Determine the type we are converting to. If we are allowed to
+    // convert to an rvalue, take the type that the destination type
+    // refers to.
+    QualType ToType = AllowRValues? cv1T1 : DestType;
+
+    const UnresolvedSetImpl *Conversions
+      = T2RecordDecl->getVisibleConversionFunctions();
+    for (UnresolvedSetImpl::const_iterator I = Conversions->begin(),
+           E = Conversions->end(); I != E; ++I) {
+      NamedDecl *D = *I;
+      CXXRecordDecl *ActingDC = cast<CXXRecordDecl>(D->getDeclContext());
+      if (isa<UsingShadowDecl>(D))
+        D = cast<UsingShadowDecl>(D)->getTargetDecl();
+      
+      FunctionTemplateDecl *ConvTemplate = dyn_cast<FunctionTemplateDecl>(D);
+      CXXConversionDecl *Conv;
+      if (ConvTemplate)
+        Conv = cast<CXXConversionDecl>(ConvTemplate->getTemplatedDecl());
+      else
+        Conv = cast<CXXConversionDecl>(*I);
+      
+      // If the conversion function doesn't return a reference type,
+      // it can't be considered for this conversion unless we're allowed to
+      // consider rvalues.
+      // FIXME: Do we need to make sure that we only consider conversion 
+      // candidates with reference-compatible results? That might be needed to 
+      // break recursion.
+      if ((AllowExplicit || !Conv->isExplicit()) &&
+          (AllowRValues || Conv->getConversionType()->isLValueReferenceType())){
+        if (ConvTemplate)
+          S.AddTemplateConversionCandidate(ConvTemplate, I.getPair(),
+                                           ActingDC, Initializer,
+                                           ToType, CandidateSet);
+        else
+          S.AddConversionCandidate(Conv, I.getPair(), ActingDC,
+                                   Initializer, ToType, CandidateSet);
+      }
+    }
+  }
+  
+  SourceLocation DeclLoc = Initializer->getLocStart();
+
+  // Perform overload resolution. If it fails, return the failed result.  
+  OverloadCandidateSet::iterator Best;
+  if (OverloadingResult Result 
+        = S.BestViableFunction(CandidateSet, DeclLoc, Best))
+    return Result;
+
+  FunctionDecl *Function = Best->Function;
+
+  // Compute the returned type of the conversion.
+  if (isa<CXXConversionDecl>(Function))
+    T2 = Function->getResultType();
+  else
+    T2 = cv1T1;
+
+  // Add the user-defined conversion step.
+  Sequence.AddUserConversionStep(Function, Best->FoundDecl,
+                                 T2.getNonReferenceType());
+
+  // Determine whether we need to perform derived-to-base or 
+  // cv-qualification adjustments.
+  bool NewDerivedToBase = false;
+  Sema::ReferenceCompareResult NewRefRelationship
+    = S.CompareReferenceRelationship(DeclLoc, T1, T2.getNonReferenceType(),
+                                     NewDerivedToBase);
+  if (NewRefRelationship == Sema::Ref_Incompatible) {
+    // If the type we've converted to is not reference-related to the
+    // type we're looking for, then there is another conversion step
+    // we need to perform to produce a temporary of the right type
+    // that we'll be binding to.
+    ImplicitConversionSequence ICS;
+    ICS.setStandard();
+    ICS.Standard = Best->FinalConversion;
+    T2 = ICS.Standard.getToType(2);
+    Sequence.AddConversionSequenceStep(ICS, T2);
+  } else if (NewDerivedToBase)
+    Sequence.AddDerivedToBaseCastStep(
+                                S.Context.getQualifiedType(T1,
+                                  T2.getNonReferenceType().getQualifiers()), 
+                                  /*isLValue=*/true);
+  
+  if (cv1T1.getQualifiers() != T2.getNonReferenceType().getQualifiers())
+    Sequence.AddQualificationConversionStep(cv1T1, T2->isReferenceType());
+  
+  Sequence.AddReferenceBindingStep(cv1T1, !T2->isReferenceType());
+  return OR_Success;
+}
+  
+/// \brief Attempt reference initialization (C++0x [dcl.init.list]) 
+static void TryReferenceInitialization(Sema &S, 
+                                       const InitializedEntity &Entity,
+                                       const InitializationKind &Kind,
+                                       Expr *Initializer,
+                                       InitializationSequence &Sequence) {
+  Sequence.setSequenceKind(InitializationSequence::ReferenceBinding);
+  
+  QualType DestType = Entity.getType();
+  QualType cv1T1 = DestType->getAs<ReferenceType>()->getPointeeType();
+  Qualifiers T1Quals;
+  QualType T1 = S.Context.getUnqualifiedArrayType(cv1T1, T1Quals);
+  QualType cv2T2 = Initializer->getType();
+  Qualifiers T2Quals;
+  QualType T2 = S.Context.getUnqualifiedArrayType(cv2T2, T2Quals);
+  SourceLocation DeclLoc = Initializer->getLocStart();
+  
+  // If the initializer is the address of an overloaded function, try
+  // to resolve the overloaded function. If all goes well, T2 is the
+  // type of the resulting function.
+  if (S.Context.getCanonicalType(T2) == S.Context.OverloadTy) {
+    DeclAccessPair Found;
+    FunctionDecl *Fn = S.ResolveAddressOfOverloadedFunction(Initializer, 
+                                                            T1,
+                                                            false,
+                                                            Found);
+    if (!Fn) {
+      Sequence.SetFailed(InitializationSequence::FK_AddressOfOverloadFailed);
+      return;
+    }
+    
+    Sequence.AddAddressOverloadResolutionStep(Fn, Found);
+    cv2T2 = Fn->getType();
+    T2 = cv2T2.getUnqualifiedType();
+  }
+  
+  // Compute some basic properties of the types and the initializer.
+  bool isLValueRef = DestType->isLValueReferenceType();
+  bool isRValueRef = !isLValueRef;
+  bool DerivedToBase = false;
+  Expr::isLvalueResult InitLvalue = Initializer->isLvalue(S.Context);
+  Sema::ReferenceCompareResult RefRelationship
+    = S.CompareReferenceRelationship(DeclLoc, cv1T1, cv2T2, DerivedToBase);
+  
+  // C++0x [dcl.init.ref]p5:
+  //   A reference to type "cv1 T1" is initialized by an expression of type 
+  //   "cv2 T2" as follows:
+  //
+  //     - If the reference is an lvalue reference and the initializer 
+  //       expression
+  OverloadingResult ConvOvlResult = OR_Success;
+  if (isLValueRef) {
+    if (InitLvalue == Expr::LV_Valid && 
+        RefRelationship >= Sema::Ref_Compatible_With_Added_Qualification) {
+      //   - is an lvalue (but is not a bit-field), and "cv1 T1" is 
+      //     reference-compatible with "cv2 T2," or
+      //
+      // Per C++ [over.best.ics]p2, we don't diagnose whether the lvalue is a 
+      // bit-field when we're determining whether the reference initialization
+      // can occur. However, we do pay attention to whether it is a bit-field
+      // to decide whether we're actually binding to a temporary created from
+      // the bit-field.
+      if (DerivedToBase)
+        Sequence.AddDerivedToBaseCastStep(
+                         S.Context.getQualifiedType(T1, T2Quals), 
+                         /*isLValue=*/true);
+      if (T1Quals != T2Quals)
+        Sequence.AddQualificationConversionStep(cv1T1, /*IsLValue=*/true);
+      bool BindingTemporary = T1Quals.hasConst() && !T1Quals.hasVolatile() &&
+        (Initializer->getBitField() || Initializer->refersToVectorElement());
+      Sequence.AddReferenceBindingStep(cv1T1, BindingTemporary);
+      return;
+    }
+    
+    //     - has a class type (i.e., T2 is a class type), where T1 is not 
+    //       reference-related to T2, and can be implicitly converted to an 
+    //       lvalue of type "cv3 T3," where "cv1 T1" is reference-compatible 
+    //       with "cv3 T3" (this conversion is selected by enumerating the 
+    //       applicable conversion functions (13.3.1.6) and choosing the best
+    //       one through overload resolution (13.3)),
+    if (RefRelationship == Sema::Ref_Incompatible && T2->isRecordType()) {
+      ConvOvlResult = TryRefInitWithConversionFunction(S, Entity, Kind, 
+                                                       Initializer,
+                                                       /*AllowRValues=*/false,
+                                                       Sequence);
+      if (ConvOvlResult == OR_Success)
+        return;
+      if (ConvOvlResult != OR_No_Viable_Function) {
+        Sequence.SetOverloadFailure(
+                      InitializationSequence::FK_ReferenceInitOverloadFailed,
+                                    ConvOvlResult);
+      }
+    }
+  }
+  
+  //     - Otherwise, the reference shall be an lvalue reference to a 
+  //       non-volatile const type (i.e., cv1 shall be const), or the reference
+  //       shall be an rvalue reference and the initializer expression shall 
+  //       be an rvalue.
+  if (!((isLValueRef && T1Quals.hasConst() && !T1Quals.hasVolatile()) ||
+        (isRValueRef && InitLvalue != Expr::LV_Valid))) {
+    if (ConvOvlResult && !Sequence.getFailedCandidateSet().empty())
+      Sequence.SetOverloadFailure(
+                        InitializationSequence::FK_ReferenceInitOverloadFailed,
+                                  ConvOvlResult);
+    else if (isLValueRef)
+      Sequence.SetFailed(InitLvalue == Expr::LV_Valid
+        ? (RefRelationship == Sema::Ref_Related
+             ? InitializationSequence::FK_ReferenceInitDropsQualifiers
+             : InitializationSequence::FK_NonConstLValueReferenceBindingToUnrelated)
+        : InitializationSequence::FK_NonConstLValueReferenceBindingToTemporary);
+    else
+      Sequence.SetFailed(
+                    InitializationSequence::FK_RValueReferenceBindingToLValue);
+    
+    return;
+  }
+  
+  //       - If T1 and T2 are class types and
+  if (T1->isRecordType() && T2->isRecordType()) {
+    //       - the initializer expression is an rvalue and "cv1 T1" is 
+    //         reference-compatible with "cv2 T2", or
+    if (InitLvalue != Expr::LV_Valid && 
+        RefRelationship >= Sema::Ref_Compatible_With_Added_Qualification) {
+      // The corresponding bullet in C++03 [dcl.init.ref]p5 gives the
+      // compiler the freedom to perform a copy here or bind to the
+      // object, while C++0x requires that we bind directly to the
+      // object. Hence, we always bind to the object without making an
+      // extra copy. However, in C++03 requires that we check for the
+      // presence of a suitable copy constructor:
+      //
+      //   The constructor that would be used to make the copy shall
+      //   be callable whether or not the copy is actually done.
+      if (!S.getLangOptions().CPlusPlus0x)
+        Sequence.AddExtraneousCopyToTemporary(cv2T2);
+
+      if (DerivedToBase)
+        Sequence.AddDerivedToBaseCastStep(
+                         S.Context.getQualifiedType(T1, T2Quals), 
+                         /*isLValue=*/false);
+      if (T1Quals != T2Quals)
+        Sequence.AddQualificationConversionStep(cv1T1, /*IsLValue=*/false);
+      Sequence.AddReferenceBindingStep(cv1T1, /*bindingTemporary=*/true);
+      return;
+    }
+    
+    //       - T1 is not reference-related to T2 and the initializer expression
+    //         can be implicitly converted to an rvalue of type "cv3 T3" (this
+    //         conversion is selected by enumerating the applicable conversion
+    //         functions (13.3.1.6) and choosing the best one through overload 
+    //         resolution (13.3)),
+    if (RefRelationship == Sema::Ref_Incompatible) {
+      ConvOvlResult = TryRefInitWithConversionFunction(S, Entity,
+                                                       Kind, Initializer,
+                                                       /*AllowRValues=*/true,
+                                                       Sequence);
+      if (ConvOvlResult)
+        Sequence.SetOverloadFailure(
+                      InitializationSequence::FK_ReferenceInitOverloadFailed,
+                                    ConvOvlResult);
+        
+      return;
+    }
+    
+    Sequence.SetFailed(InitializationSequence::FK_ReferenceInitDropsQualifiers);
+    return;
+  }
+  
+  //      - If the initializer expression is an rvalue, with T2 an array type,
+  //        and "cv1 T1" is reference-compatible with "cv2 T2," the reference
+  //        is bound to the object represented by the rvalue (see 3.10).
+  // FIXME: How can an array type be reference-compatible with anything?
+  // Don't we mean the element types of T1 and T2?
+  
+  //      - Otherwise, a temporary of type “cv1 T1” is created and initialized
+  //        from the initializer expression using the rules for a non-reference
+  //        copy initialization (8.5). The reference is then bound to the 
+  //        temporary. [...]
+  // Determine whether we are allowed to call explicit constructors or
+  // explicit conversion operators.
+  bool AllowExplicit = (Kind.getKind() == InitializationKind::IK_Direct);
+  ImplicitConversionSequence ICS
+    = S.TryImplicitConversion(Initializer, cv1T1,
+                              /*SuppressUserConversions=*/false, AllowExplicit, 
+                              /*FIXME:InOverloadResolution=*/false);
+            
+  if (ICS.isBad()) {
+    // FIXME: Use the conversion function set stored in ICS to turn
+    // this into an overloading ambiguity diagnostic. However, we need
+    // to keep that set as an OverloadCandidateSet rather than as some
+    // other kind of set.
+    if (ConvOvlResult && !Sequence.getFailedCandidateSet().empty())
+      Sequence.SetOverloadFailure(
+                        InitializationSequence::FK_ReferenceInitOverloadFailed,
+                                  ConvOvlResult);
+    else
+      Sequence.SetFailed(InitializationSequence::FK_ReferenceInitFailed);
+    return;
+  }
+
+  //        [...] If T1 is reference-related to T2, cv1 must be the
+  //        same cv-qualification as, or greater cv-qualification
+  //        than, cv2; otherwise, the program is ill-formed.
+  unsigned T1CVRQuals = T1Quals.getCVRQualifiers();
+  unsigned T2CVRQuals = T2Quals.getCVRQualifiers();
+  if (RefRelationship == Sema::Ref_Related && 
+      (T1CVRQuals | T2CVRQuals) != T1CVRQuals) {
+    Sequence.SetFailed(InitializationSequence::FK_ReferenceInitDropsQualifiers);
+    return;
+  }
+
+  // Perform the actual conversion.
+  Sequence.AddConversionSequenceStep(ICS, cv1T1);
+  Sequence.AddReferenceBindingStep(cv1T1, /*bindingTemporary=*/true);
+  return;
+}
+
+/// \brief Attempt character array initialization from a string literal
+/// (C++ [dcl.init.string], C99 6.7.8). 
+static void TryStringLiteralInitialization(Sema &S, 
+                                           const InitializedEntity &Entity,
+                                           const InitializationKind &Kind,
+                                           Expr *Initializer,
+                                       InitializationSequence &Sequence) {
+  Sequence.setSequenceKind(InitializationSequence::StringInit);
+  Sequence.AddStringInitStep(Entity.getType());
+}
+
+/// \brief Attempt initialization by constructor (C++ [dcl.init]), which
+/// enumerates the constructors of the initialized entity and performs overload
+/// resolution to select the best.
+static void TryConstructorInitialization(Sema &S, 
+                                         const InitializedEntity &Entity,
+                                         const InitializationKind &Kind,
+                                         Expr **Args, unsigned NumArgs,
+                                         QualType DestType,
+                                         InitializationSequence &Sequence) {
+  Sequence.setSequenceKind(InitializationSequence::ConstructorInitialization);
+  
+  // Build the candidate set directly in the initialization sequence
+  // structure, so that it will persist if we fail.
+  OverloadCandidateSet &CandidateSet = Sequence.getFailedCandidateSet();
+  CandidateSet.clear();
+  
+  // Determine whether we are allowed to call explicit constructors or
+  // explicit conversion operators.
+  bool AllowExplicit = (Kind.getKind() == InitializationKind::IK_Direct ||
+                        Kind.getKind() == InitializationKind::IK_Value ||
+                        Kind.getKind() == InitializationKind::IK_Default);
+
+  // The type we're constructing needs to be complete.
+  if (S.RequireCompleteType(Kind.getLocation(), DestType, 0)) {
+    Sequence.SetFailed(InitializationSequence::FK_ConversionFailed);
+    return;
+  }
+  
+  // The type we're converting to is a class type. Enumerate its constructors
+  // to see if one is suitable.
+  const RecordType *DestRecordType = DestType->getAs<RecordType>();
+  assert(DestRecordType && "Constructor initialization requires record type");  
+  CXXRecordDecl *DestRecordDecl
+    = cast<CXXRecordDecl>(DestRecordType->getDecl());
+    
+  DeclarationName ConstructorName
+    = S.Context.DeclarationNames.getCXXConstructorName(
+                     S.Context.getCanonicalType(DestType).getUnqualifiedType());
+  DeclContext::lookup_iterator Con, ConEnd;
+  for (llvm::tie(Con, ConEnd) = DestRecordDecl->lookup(ConstructorName);
+       Con != ConEnd; ++Con) {
+    NamedDecl *D = *Con;
+    DeclAccessPair FoundDecl = DeclAccessPair::make(D, D->getAccess());
+    bool SuppressUserConversions = false;
+    
+    // Find the constructor (which may be a template).
+    CXXConstructorDecl *Constructor = 0;
+    FunctionTemplateDecl *ConstructorTmpl = dyn_cast<FunctionTemplateDecl>(D);
+    if (ConstructorTmpl)
+      Constructor = cast<CXXConstructorDecl>(
+                                           ConstructorTmpl->getTemplatedDecl());
+    else {
+      Constructor = cast<CXXConstructorDecl>(D);
+
+      // If we're performing copy initialization using a copy constructor, we 
+      // suppress user-defined conversions on the arguments.
+      // FIXME: Move constructors?
+      if (Kind.getKind() == InitializationKind::IK_Copy &&
+          Constructor->isCopyConstructor())
+        SuppressUserConversions = true;
+    }
+    
+    if (!Constructor->isInvalidDecl() &&
+        (AllowExplicit || !Constructor->isExplicit())) {
+      if (ConstructorTmpl)
+        S.AddTemplateOverloadCandidate(ConstructorTmpl, FoundDecl,
+                                       /*ExplicitArgs*/ 0,
+                                       Args, NumArgs, CandidateSet,
+                                       SuppressUserConversions);
+      else
+        S.AddOverloadCandidate(Constructor, FoundDecl,
+                               Args, NumArgs, CandidateSet,
+                               SuppressUserConversions);
+    }
+  }    
+    
+  SourceLocation DeclLoc = Kind.getLocation();
+  
+  // Perform overload resolution. If it fails, return the failed result.  
+  OverloadCandidateSet::iterator Best;
+  if (OverloadingResult Result 
+        = S.BestViableFunction(CandidateSet, DeclLoc, Best)) {
+    Sequence.SetOverloadFailure(
+                          InitializationSequence::FK_ConstructorOverloadFailed, 
+                                Result);
+    return;
+  }
+
+  // C++0x [dcl.init]p6:
+  //   If a program calls for the default initialization of an object
+  //   of a const-qualified type T, T shall be a class type with a
+  //   user-provided default constructor.
+  if (Kind.getKind() == InitializationKind::IK_Default &&
+      Entity.getType().isConstQualified() &&
+      cast<CXXConstructorDecl>(Best->Function)->isImplicit()) {
+    Sequence.SetFailed(InitializationSequence::FK_DefaultInitOfConst);
+    return;
+  }
+
+  // Add the constructor initialization step. Any cv-qualification conversion is
+  // subsumed by the initialization.
+  Sequence.AddConstructorInitializationStep(
+                                      cast<CXXConstructorDecl>(Best->Function), 
+                                      Best->FoundDecl.getAccess(),
+                                      DestType);
+}
+
+/// \brief Attempt value initialization (C++ [dcl.init]p7).
+static void TryValueInitialization(Sema &S, 
+                                   const InitializedEntity &Entity,
+                                   const InitializationKind &Kind,
+                                   InitializationSequence &Sequence) {
+  // C++ [dcl.init]p5:
+  //
+  //   To value-initialize an object of type T means:
+  QualType T = Entity.getType();
+  
+  //     -- if T is an array type, then each element is value-initialized;
+  while (const ArrayType *AT = S.Context.getAsArrayType(T))
+    T = AT->getElementType();
+  
+  if (const RecordType *RT = T->getAs<RecordType>()) {
+    if (CXXRecordDecl *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
+      // -- if T is a class type (clause 9) with a user-declared
+      //    constructor (12.1), then the default constructor for T is
+      //    called (and the initialization is ill-formed if T has no
+      //    accessible default constructor);
+      //
+      // FIXME: we really want to refer to a single subobject of the array,
+      // but Entity doesn't have a way to capture that (yet).
+      if (ClassDecl->hasUserDeclaredConstructor())
+        return TryConstructorInitialization(S, Entity, Kind, 0, 0, T, Sequence);
+      
+      // -- if T is a (possibly cv-qualified) non-union class type
+      //    without a user-provided constructor, then the object is
+      //    zero-initialized and, if T’s implicitly-declared default
+      //    constructor is non-trivial, that constructor is called.
+      if ((ClassDecl->getTagKind() == TagDecl::TK_class ||
+           ClassDecl->getTagKind() == TagDecl::TK_struct) &&
+          !ClassDecl->hasTrivialConstructor()) {
+        Sequence.AddZeroInitializationStep(Entity.getType());
+        return TryConstructorInitialization(S, Entity, Kind, 0, 0, T, Sequence);        
+      }
+    }
+  }
+
+  Sequence.AddZeroInitializationStep(Entity.getType());
+  Sequence.setSequenceKind(InitializationSequence::ZeroInitialization);
+}
+
+/// \brief Attempt default initialization (C++ [dcl.init]p6).
+static void TryDefaultInitialization(Sema &S,
+                                     const InitializedEntity &Entity,
+                                     const InitializationKind &Kind,
+                                     InitializationSequence &Sequence) {
+  assert(Kind.getKind() == InitializationKind::IK_Default);
+  
+  // C++ [dcl.init]p6:
+  //   To default-initialize an object of type T means:
+  //     - if T is an array type, each element is default-initialized;
+  QualType DestType = Entity.getType();
+  while (const ArrayType *Array = S.Context.getAsArrayType(DestType))
+    DestType = Array->getElementType();
+         
+  //     - if T is a (possibly cv-qualified) class type (Clause 9), the default
+  //       constructor for T is called (and the initialization is ill-formed if
+  //       T has no accessible default constructor);
+  if (DestType->isRecordType() && S.getLangOptions().CPlusPlus) {
+    return TryConstructorInitialization(S, Entity, Kind, 0, 0, DestType,
+                                        Sequence);
+  }
+  
+  //     - otherwise, no initialization is performed.
+  Sequence.setSequenceKind(InitializationSequence::NoInitialization);
+  
+  //   If a program calls for the default initialization of an object of
+  //   a const-qualified type T, T shall be a class type with a user-provided 
+  //   default constructor.
+  if (DestType.isConstQualified() && S.getLangOptions().CPlusPlus)
+    Sequence.SetFailed(InitializationSequence::FK_DefaultInitOfConst);
+}
+
+/// \brief Attempt a user-defined conversion between two types (C++ [dcl.init]),
+/// which enumerates all conversion functions and performs overload resolution
+/// to select the best.
+static void TryUserDefinedConversion(Sema &S, 
+                                     const InitializedEntity &Entity,
+                                     const InitializationKind &Kind,
+                                     Expr *Initializer,
+                                     InitializationSequence &Sequence) {
+  Sequence.setSequenceKind(InitializationSequence::UserDefinedConversion);
+  
+  QualType DestType = Entity.getType();
+  assert(!DestType->isReferenceType() && "References are handled elsewhere");
+  QualType SourceType = Initializer->getType();
+  assert((DestType->isRecordType() || SourceType->isRecordType()) &&
+         "Must have a class type to perform a user-defined conversion");
+  
+  // Build the candidate set directly in the initialization sequence
+  // structure, so that it will persist if we fail.
+  OverloadCandidateSet &CandidateSet = Sequence.getFailedCandidateSet();
+  CandidateSet.clear();
+  
+  // Determine whether we are allowed to call explicit constructors or
+  // explicit conversion operators.
+  bool AllowExplicit = Kind.getKind() == InitializationKind::IK_Direct;
+  
+  if (const RecordType *DestRecordType = DestType->getAs<RecordType>()) {
+    // The type we're converting to is a class type. Enumerate its constructors
+    // to see if there is a suitable conversion.
+    CXXRecordDecl *DestRecordDecl
+      = cast<CXXRecordDecl>(DestRecordType->getDecl());
+    
+    // Try to complete the type we're converting to.
+    if (!S.RequireCompleteType(Kind.getLocation(), DestType, 0)) {    
+      DeclarationName ConstructorName
+        = S.Context.DeclarationNames.getCXXConstructorName(
+                     S.Context.getCanonicalType(DestType).getUnqualifiedType());
+      DeclContext::lookup_iterator Con, ConEnd;
+      for (llvm::tie(Con, ConEnd) = DestRecordDecl->lookup(ConstructorName);
+           Con != ConEnd; ++Con) {
+        NamedDecl *D = *Con;
+        DeclAccessPair FoundDecl = DeclAccessPair::make(D, D->getAccess());
+        bool SuppressUserConversions = false;
+        
+        // Find the constructor (which may be a template).
+        CXXConstructorDecl *Constructor = 0;
+        FunctionTemplateDecl *ConstructorTmpl
+          = dyn_cast<FunctionTemplateDecl>(D);
+        if (ConstructorTmpl)
+          Constructor = cast<CXXConstructorDecl>(
+                                           ConstructorTmpl->getTemplatedDecl());
+        else {
+          Constructor = cast<CXXConstructorDecl>(D);
+          
+          // If we're performing copy initialization using a copy constructor, 
+          // we suppress user-defined conversions on the arguments.
+          // FIXME: Move constructors?
+          if (Kind.getKind() == InitializationKind::IK_Copy &&
+              Constructor->isCopyConstructor())
+            SuppressUserConversions = true;
+          
+        }
+        
+        if (!Constructor->isInvalidDecl() &&
+            Constructor->isConvertingConstructor(AllowExplicit)) {
+          if (ConstructorTmpl)
+            S.AddTemplateOverloadCandidate(ConstructorTmpl, FoundDecl,
+                                           /*ExplicitArgs*/ 0,
+                                           &Initializer, 1, CandidateSet,
+                                           SuppressUserConversions);
+          else
+            S.AddOverloadCandidate(Constructor, FoundDecl,
+                                   &Initializer, 1, CandidateSet,
+                                   SuppressUserConversions);
+        }
+      }    
+    }
+  }
+
+  SourceLocation DeclLoc = Initializer->getLocStart();
+
+  if (const RecordType *SourceRecordType = SourceType->getAs<RecordType>()) {
+    // The type we're converting from is a class type, enumerate its conversion
+    // functions.
+
+    // We can only enumerate the conversion functions for a complete type; if
+    // the type isn't complete, simply skip this step.
+    if (!S.RequireCompleteType(DeclLoc, SourceType, 0)) {
+      CXXRecordDecl *SourceRecordDecl
+        = cast<CXXRecordDecl>(SourceRecordType->getDecl());
+      
+      const UnresolvedSetImpl *Conversions
+        = SourceRecordDecl->getVisibleConversionFunctions();
+      for (UnresolvedSetImpl::const_iterator I = Conversions->begin(),
+           E = Conversions->end(); 
+           I != E; ++I) {
+        NamedDecl *D = *I;
+        CXXRecordDecl *ActingDC = cast<CXXRecordDecl>(D->getDeclContext());
+        if (isa<UsingShadowDecl>(D))
+          D = cast<UsingShadowDecl>(D)->getTargetDecl();
+        
+        FunctionTemplateDecl *ConvTemplate = dyn_cast<FunctionTemplateDecl>(D);
+        CXXConversionDecl *Conv;
+        if (ConvTemplate)
+          Conv = cast<CXXConversionDecl>(ConvTemplate->getTemplatedDecl());
+        else
+          Conv = cast<CXXConversionDecl>(D);
+        
+        if (AllowExplicit || !Conv->isExplicit()) {
+          if (ConvTemplate)
+            S.AddTemplateConversionCandidate(ConvTemplate, I.getPair(),
+                                             ActingDC, Initializer, DestType,
+                                             CandidateSet);
+          else
+            S.AddConversionCandidate(Conv, I.getPair(), ActingDC,
+                                     Initializer, DestType, CandidateSet);
+        }
+      }
+    }
+  }
+  
+  // Perform overload resolution. If it fails, return the failed result.  
+  OverloadCandidateSet::iterator Best;
+  if (OverloadingResult Result
+        = S.BestViableFunction(CandidateSet, DeclLoc, Best)) {
+    Sequence.SetOverloadFailure(
+                        InitializationSequence::FK_UserConversionOverloadFailed, 
+                                Result);
+    return;
+  }
+
+  FunctionDecl *Function = Best->Function;
+  
+  if (isa<CXXConstructorDecl>(Function)) {
+    // Add the user-defined conversion step. Any cv-qualification conversion is
+    // subsumed by the initialization.
+    Sequence.AddUserConversionStep(Function, Best->FoundDecl, DestType);
+    return;
+  }
+
+  // Add the user-defined conversion step that calls the conversion function.
+  QualType ConvType = Function->getResultType().getNonReferenceType();
+  if (ConvType->getAs<RecordType>()) {
+    // If we're converting to a class type, there may be an copy if
+    // the resulting temporary object (possible to create an object of
+    // a base class type). That copy is not a separate conversion, so
+    // we just make a note of the actual destination type (possibly a
+    // base class of the type returned by the conversion function) and
+    // let the user-defined conversion step handle the conversion.
+    Sequence.AddUserConversionStep(Function, Best->FoundDecl, DestType);
+    return;
+  }
+
+  Sequence.AddUserConversionStep(Function, Best->FoundDecl, ConvType);
+    
+  // If the conversion following the call to the conversion function
+  // is interesting, add it as a separate step.
+  if (Best->FinalConversion.First || Best->FinalConversion.Second ||
+      Best->FinalConversion.Third) {
+    ImplicitConversionSequence ICS;
+    ICS.setStandard();
+    ICS.Standard = Best->FinalConversion;
+    Sequence.AddConversionSequenceStep(ICS, DestType);
+  }
+}
+
+/// \brief Attempt an implicit conversion (C++ [conv]) converting from one
+/// non-class type to another.
+static void TryImplicitConversion(Sema &S, 
+                                  const InitializedEntity &Entity,
+                                  const InitializationKind &Kind,
+                                  Expr *Initializer,
+                                  InitializationSequence &Sequence) {
+  ImplicitConversionSequence ICS
+    = S.TryImplicitConversion(Initializer, Entity.getType(),
+                              /*SuppressUserConversions=*/true, 
+                              /*AllowExplicit=*/false,
+                              /*InOverloadResolution=*/false);
+  
+  if (ICS.isBad()) {
+    Sequence.SetFailed(InitializationSequence::FK_ConversionFailed);
+    return;
+  }
+  
+  Sequence.AddConversionSequenceStep(ICS, Entity.getType());
+}
+
+InitializationSequence::InitializationSequence(Sema &S,
+                                               const InitializedEntity &Entity,
+                                               const InitializationKind &Kind,
+                                               Expr **Args,
+                                               unsigned NumArgs)
+    : FailedCandidateSet(Kind.getLocation()) {
+  ASTContext &Context = S.Context;
+  
+  // C++0x [dcl.init]p16:
+  //   The semantics of initializers are as follows. The destination type is 
+  //   the type of the object or reference being initialized and the source 
+  //   type is the type of the initializer expression. The source type is not
+  //   defined when the initializer is a braced-init-list or when it is a 
+  //   parenthesized list of expressions.
+  QualType DestType = Entity.getType();
+
+  if (DestType->isDependentType() ||
+      Expr::hasAnyTypeDependentArguments(Args, NumArgs)) {
+    SequenceKind = DependentSequence;
+    return;
+  }
+
+  QualType SourceType;
+  Expr *Initializer = 0;
+  if (NumArgs == 1) {
+    Initializer = Args[0];
+    if (!isa<InitListExpr>(Initializer))
+      SourceType = Initializer->getType();
+  }
+  
+  //     - If the initializer is a braced-init-list, the object is 
+  //       list-initialized (8.5.4).
+  if (InitListExpr *InitList = dyn_cast_or_null<InitListExpr>(Initializer)) {
+    TryListInitialization(S, Entity, Kind, InitList, *this);
+    return;
+  }
+  
+  //     - If the destination type is a reference type, see 8.5.3.
+  if (DestType->isReferenceType()) {
+    // C++0x [dcl.init.ref]p1:
+    //   A variable declared to be a T& or T&&, that is, "reference to type T"
+    //   (8.3.2), shall be initialized by an object, or function, of type T or
+    //   by an object that can be converted into a T.
+    // (Therefore, multiple arguments are not permitted.)
+    if (NumArgs != 1)
+      SetFailed(FK_TooManyInitsForReference);
+    else
+      TryReferenceInitialization(S, Entity, Kind, Args[0], *this);
+    return;
+  }
+  
+  //     - If the destination type is an array of characters, an array of 
+  //       char16_t, an array of char32_t, or an array of wchar_t, and the 
+  //       initializer is a string literal, see 8.5.2.
+  if (Initializer && IsStringInit(Initializer, DestType, Context)) {
+    TryStringLiteralInitialization(S, Entity, Kind, Initializer, *this);
+    return;
+  }
+  
+  //     - If the initializer is (), the object is value-initialized.
+  if (Kind.getKind() == InitializationKind::IK_Value ||
+      (Kind.getKind() == InitializationKind::IK_Direct && NumArgs == 0)) {
+    TryValueInitialization(S, Entity, Kind, *this);
+    return;
+  }
+  
+  // Handle default initialization.
+  if (Kind.getKind() == InitializationKind::IK_Default){
+    TryDefaultInitialization(S, Entity, Kind, *this);
+    return;
+  }
+
+  //     - Otherwise, if the destination type is an array, the program is 
+  //       ill-formed.
+  if (const ArrayType *AT = Context.getAsArrayType(DestType)) {
+    if (AT->getElementType()->isAnyCharacterType())
+      SetFailed(FK_ArrayNeedsInitListOrStringLiteral);
+    else
+      SetFailed(FK_ArrayNeedsInitList);
+    
+    return;
+  }
+
+  // Handle initialization in C
+  if (!S.getLangOptions().CPlusPlus) {
+    setSequenceKind(CAssignment);
+    AddCAssignmentStep(DestType);
+    return;
+  }
+  
+  //     - If the destination type is a (possibly cv-qualified) class type:
+  if (DestType->isRecordType()) {
+    //     - If the initialization is direct-initialization, or if it is 
+    //       copy-initialization where the cv-unqualified version of the 
+    //       source type is the same class as, or a derived class of, the 
+    //       class of the destination, constructors are considered. [...]
+    if (Kind.getKind() == InitializationKind::IK_Direct ||
+        (Kind.getKind() == InitializationKind::IK_Copy &&
+         (Context.hasSameUnqualifiedType(SourceType, DestType) ||
+          S.IsDerivedFrom(SourceType, DestType))))
+      TryConstructorInitialization(S, Entity, Kind, Args, NumArgs, 
+                                   Entity.getType(), *this);
+    //     - Otherwise (i.e., for the remaining copy-initialization cases), 
+    //       user-defined conversion sequences that can convert from the source
+    //       type to the destination type or (when a conversion function is 
+    //       used) to a derived class thereof are enumerated as described in
+    //       13.3.1.4, and the best one is chosen through overload resolution
+    //       (13.3).
+    else
+      TryUserDefinedConversion(S, Entity, Kind, Initializer, *this);
+    return;
+  }
+  
+  if (NumArgs > 1) {
+    SetFailed(FK_TooManyInitsForScalar);
+    return;
+  }
+  assert(NumArgs == 1 && "Zero-argument case handled above");
+  
+  //    - Otherwise, if the source type is a (possibly cv-qualified) class 
+  //      type, conversion functions are considered.
+  if (!SourceType.isNull() && SourceType->isRecordType()) {
+    TryUserDefinedConversion(S, Entity, Kind, Initializer, *this);
+    return;
+  }
+  
+  //    - Otherwise, the initial value of the object being initialized is the
+  //      (possibly converted) value of the initializer expression. Standard
+  //      conversions (Clause 4) will be used, if necessary, to convert the
+  //      initializer expression to the cv-unqualified version of the 
+  //      destination type; no user-defined conversions are considered.
+  setSequenceKind(StandardConversion);
+  TryImplicitConversion(S, Entity, Kind, Initializer, *this);
+}
+
+InitializationSequence::~InitializationSequence() {
+  for (llvm::SmallVectorImpl<Step>::iterator Step = Steps.begin(),
+                                          StepEnd = Steps.end();
+       Step != StepEnd; ++Step)
+    Step->Destroy();
+}
+
+//===----------------------------------------------------------------------===//
+// Perform initialization
+//===----------------------------------------------------------------------===//
+static Sema::AssignmentAction 
+getAssignmentAction(const InitializedEntity &Entity) {
+  switch(Entity.getKind()) {
+  case InitializedEntity::EK_Variable:
+  case InitializedEntity::EK_New:
+    return Sema::AA_Initializing;
+
+  case InitializedEntity::EK_Parameter:
+    if (Entity.getDecl() && 
+        isa<ObjCMethodDecl>(Entity.getDecl()->getDeclContext()))
+      return Sema::AA_Sending;
+
+    return Sema::AA_Passing;
+
+  case InitializedEntity::EK_Result:
+    return Sema::AA_Returning;
+
+  case InitializedEntity::EK_Exception:
+  case InitializedEntity::EK_Base:
+    llvm_unreachable("No assignment action for C++-specific initialization");
+    break;
+
+  case InitializedEntity::EK_Temporary:
+    // FIXME: Can we tell apart casting vs. converting?
+    return Sema::AA_Casting;
+    
+  case InitializedEntity::EK_Member:
+  case InitializedEntity::EK_ArrayElement:
+  case InitializedEntity::EK_VectorElement:
+    return Sema::AA_Initializing;
+  }
+
+  return Sema::AA_Converting;
+}
+
+/// \brief Whether we should binding a created object as a temporary when
+/// initializing the given entity.
+static bool shouldBindAsTemporary(const InitializedEntity &Entity) {
+  switch (Entity.getKind()) {
+  case InitializedEntity::EK_ArrayElement:
+  case InitializedEntity::EK_Member:
+  case InitializedEntity::EK_Result:
+  case InitializedEntity::EK_New:
+  case InitializedEntity::EK_Variable:
+  case InitializedEntity::EK_Base:
+  case InitializedEntity::EK_VectorElement:
+  case InitializedEntity::EK_Exception:
+    return false;
+    
+  case InitializedEntity::EK_Parameter:
+  case InitializedEntity::EK_Temporary:
+    return true;
+  }
+  
+  llvm_unreachable("missed an InitializedEntity kind?");
+}
+
+/// \brief Whether the given entity, when initialized with an object
+/// created for that initialization, requires destruction.
+static bool shouldDestroyTemporary(const InitializedEntity &Entity) {
+  switch (Entity.getKind()) {
+    case InitializedEntity::EK_Member:
+    case InitializedEntity::EK_Result:
+    case InitializedEntity::EK_New:
+    case InitializedEntity::EK_Base:
+    case InitializedEntity::EK_VectorElement:
+      return false;
+      
+    case InitializedEntity::EK_Variable:
+    case InitializedEntity::EK_Parameter:
+    case InitializedEntity::EK_Temporary:
+    case InitializedEntity::EK_ArrayElement:
+    case InitializedEntity::EK_Exception:
+      return true;
+  }
+  
+  llvm_unreachable("missed an InitializedEntity kind?");  
+}
+
+/// \brief Make a (potentially elidable) temporary copy of the object
+/// provided by the given initializer by calling the appropriate copy
+/// constructor.
+///
+/// \param S The Sema object used for type-checking.
+///
+/// \param T The type of the temporary object, which must either by
+/// the type of the initializer expression or a superclass thereof.
+///
+/// \param Enter The entity being initialized.
+///
+/// \param CurInit The initializer expression.
+///
+/// \param IsExtraneousCopy Whether this is an "extraneous" copy that
+/// is permitted in C++03 (but not C++0x) when binding a reference to
+/// an rvalue.
+///
+/// \returns An expression that copies the initializer expression into
+/// a temporary object, or an error expression if a copy could not be
+/// created.
+static Sema::OwningExprResult CopyObject(Sema &S,
+                                         QualType T,
+                                         const InitializedEntity &Entity,
+                                         Sema::OwningExprResult CurInit,
+                                         bool IsExtraneousCopy) {
+  // Determine which class type we're copying to.
+  Expr *CurInitExpr = (Expr *)CurInit.get();
+  CXXRecordDecl *Class = 0; 
+  if (const RecordType *Record = T->getAs<RecordType>())
+    Class = cast<CXXRecordDecl>(Record->getDecl());
+  if (!Class)
+    return move(CurInit);
+
+  // C++0x [class.copy]p34:
+  //   When certain criteria are met, an implementation is allowed to
+  //   omit the copy/move construction of a class object, even if the
+  //   copy/move constructor and/or destructor for the object have
+  //   side effects. [...]
+  //     - when a temporary class object that has not been bound to a
+  //       reference (12.2) would be copied/moved to a class object
+  //       with the same cv-unqualified type, the copy/move operation
+  //       can be omitted by constructing the temporary object
+  //       directly into the target of the omitted copy/move
+  // 
+  // Note that the other three bullets are handled elsewhere. Copy
+  // elision for return statements and throw expressions are (FIXME:
+  // not yet) handled as part of constructor initialization, while
+  // copy elision for exception handlers is handled by the run-time.
+  bool Elidable = CurInitExpr->isTemporaryObject() &&
+     S.Context.hasSameUnqualifiedType(T, CurInitExpr->getType());
+  SourceLocation Loc;
+  switch (Entity.getKind()) {
+  case InitializedEntity::EK_Result:
+    Loc = Entity.getReturnLoc();
+    break;
+      
+  case InitializedEntity::EK_Exception:
+    Loc = Entity.getThrowLoc();
+    break;
+    
+  case InitializedEntity::EK_Variable:
+    Loc = Entity.getDecl()->getLocation();
+    break;
+
+  case InitializedEntity::EK_ArrayElement:
+  case InitializedEntity::EK_Member:
+  case InitializedEntity::EK_Parameter:
+  case InitializedEntity::EK_Temporary:
+  case InitializedEntity::EK_New:
+  case InitializedEntity::EK_Base:
+  case InitializedEntity::EK_VectorElement:
+    Loc = CurInitExpr->getLocStart();
+    break;
+  }
+
+  // Make sure that the type we are copying is complete.   
+  if (S.RequireCompleteType(Loc, T, S.PDiag(diag::err_temp_copy_incomplete)))
+    return move(CurInit);
+
+  // Perform overload resolution using the class's copy constructors.
+  DeclarationName ConstructorName
+    = S.Context.DeclarationNames.getCXXConstructorName(
+                  S.Context.getCanonicalType(S.Context.getTypeDeclType(Class)));
+  DeclContext::lookup_iterator Con, ConEnd;
+  OverloadCandidateSet CandidateSet(Loc);
+  for (llvm::tie(Con, ConEnd) = Class->lookup(ConstructorName);
+       Con != ConEnd; ++Con) {
+    // Only consider copy constructors.
+    CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(*Con);
+    if (!Constructor || Constructor->isInvalidDecl() ||
+        !Constructor->isCopyConstructor() ||
+        !Constructor->isConvertingConstructor(/*AllowExplicit=*/false))
+      continue;
+
+    DeclAccessPair FoundDecl
+      = DeclAccessPair::make(Constructor, Constructor->getAccess());
+    S.AddOverloadCandidate(Constructor, FoundDecl,
+                           &CurInitExpr, 1, CandidateSet);
+  }
+  
+  OverloadCandidateSet::iterator Best;
+  switch (S.BestViableFunction(CandidateSet, Loc, Best)) {
+  case OR_Success:
+    break;
+      
+  case OR_No_Viable_Function:
+    S.Diag(Loc, diag::err_temp_copy_no_viable)
+      << (int)Entity.getKind() << CurInitExpr->getType()
+      << CurInitExpr->getSourceRange();
+    S.PrintOverloadCandidates(CandidateSet, Sema::OCD_AllCandidates,
+                              &CurInitExpr, 1);
+    return S.ExprError();
+      
+  case OR_Ambiguous:
+    S.Diag(Loc, diag::err_temp_copy_ambiguous)
+      << (int)Entity.getKind() << CurInitExpr->getType()
+      << CurInitExpr->getSourceRange();
+    S.PrintOverloadCandidates(CandidateSet, Sema::OCD_ViableCandidates,
+                              &CurInitExpr, 1);
+    return S.ExprError();
+    
+  case OR_Deleted:
+    S.Diag(Loc, diag::err_temp_copy_deleted)
+      << (int)Entity.getKind() << CurInitExpr->getType()
+      << CurInitExpr->getSourceRange();
+    S.Diag(Best->Function->getLocation(), diag::note_unavailable_here)
+      << Best->Function->isDeleted();
+    return S.ExprError();
+  }
+
+  CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(Best->Function);
+  ASTOwningVector<&ActionBase::DeleteExpr> ConstructorArgs(S);
+  CurInit.release(); // Ownership transferred into MultiExprArg, below.
+
+  S.CheckConstructorAccess(Loc, Constructor, Entity,
+                           Best->FoundDecl.getAccess());
+
+  if (IsExtraneousCopy) {
+    // If this is a totally extraneous copy for C++03 reference
+    // binding purposes, just return the original initialization
+    // expression. We don't generate an (elided) copy operation here
+    // because doing so would require us to pass down a flag to avoid
+    // infinite recursion, where each step adds another extraneous,
+    // elidable copy.
+
+    // Instantiate the default arguments of any extra parameters in
+    // the selected copy constructor, as if we were going to create a
+    // proper call to the copy constructor.
+    for (unsigned I = 1, N = Constructor->getNumParams(); I != N; ++I) {
+      ParmVarDecl *Parm = Constructor->getParamDecl(I);
+      if (S.RequireCompleteType(Loc, Parm->getType(),
+                                S.PDiag(diag::err_call_incomplete_argument)))
+        break;
+
+      // Build the default argument expression; we don't actually care
+      // if this succeeds or not, because this routine will complain
+      // if there was a problem.
+      S.BuildCXXDefaultArgExpr(Loc, Constructor, Parm);
+    }
+
+    return S.Owned(CurInitExpr);
+  }
+  
+  // Determine the arguments required to actually perform the
+  // constructor call (we might have derived-to-base conversions, or
+  // the copy constructor may have default arguments).
+  if (S.CompleteConstructorCall(Constructor,
+                                Sema::MultiExprArg(S, 
+                                                   (void **)&CurInitExpr,
+                                                   1),
+                                Loc, ConstructorArgs))
+    return S.ExprError();
+
+  // Actually perform the constructor call.
+  CurInit = S.BuildCXXConstructExpr(Loc, T, Constructor, Elidable,
+                                    move_arg(ConstructorArgs));
+  
+  // If we're supposed to bind temporaries, do so.
+  if (!CurInit.isInvalid() && shouldBindAsTemporary(Entity))
+    CurInit = S.MaybeBindToTemporary(CurInit.takeAs<Expr>());
+  return move(CurInit);
+}
+
+void InitializationSequence::PrintInitLocationNote(Sema &S,
+                                              const InitializedEntity &Entity) {
+  if (Entity.getKind() == InitializedEntity::EK_Parameter && Entity.getDecl()) {
+    if (Entity.getDecl()->getLocation().isInvalid())
+      return;
+
+    if (Entity.getDecl()->getDeclName())
+      S.Diag(Entity.getDecl()->getLocation(), diag::note_parameter_named_here)
+        << Entity.getDecl()->getDeclName();
+    else
+      S.Diag(Entity.getDecl()->getLocation(), diag::note_parameter_here);
+  }
+}
+
+Action::OwningExprResult 
+InitializationSequence::Perform(Sema &S,
+                                const InitializedEntity &Entity,
+                                const InitializationKind &Kind,
+                                Action::MultiExprArg Args,
+                                QualType *ResultType) {
+  if (SequenceKind == FailedSequence) {
+    unsigned NumArgs = Args.size();
+    Diagnose(S, Entity, Kind, (Expr **)Args.release(), NumArgs);
+    return S.ExprError();
+  }
+  
+  if (SequenceKind == DependentSequence) {
+    // If the declaration is a non-dependent, incomplete array type
+    // that has an initializer, then its type will be completed once
+    // the initializer is instantiated.
+    if (ResultType && !Entity.getType()->isDependentType() &&
+        Args.size() == 1) {
+      QualType DeclType = Entity.getType();
+      if (const IncompleteArrayType *ArrayT
+                           = S.Context.getAsIncompleteArrayType(DeclType)) {
+        // FIXME: We don't currently have the ability to accurately
+        // compute the length of an initializer list without
+        // performing full type-checking of the initializer list
+        // (since we have to determine where braces are implicitly
+        // introduced and such).  So, we fall back to making the array
+        // type a dependently-sized array type with no specified
+        // bound.
+        if (isa<InitListExpr>((Expr *)Args.get()[0])) {
+          SourceRange Brackets;
+
+          // Scavange the location of the brackets from the entity, if we can.
+          if (DeclaratorDecl *DD = Entity.getDecl()) {
+            if (TypeSourceInfo *TInfo = DD->getTypeSourceInfo()) {
+              TypeLoc TL = TInfo->getTypeLoc();
+              if (IncompleteArrayTypeLoc *ArrayLoc
+                                      = dyn_cast<IncompleteArrayTypeLoc>(&TL))
+              Brackets = ArrayLoc->getBracketsRange();
+            }
+          }
+
+          *ResultType
+            = S.Context.getDependentSizedArrayType(ArrayT->getElementType(),
+                                                   /*NumElts=*/0,
+                                                   ArrayT->getSizeModifier(),
+                                       ArrayT->getIndexTypeCVRQualifiers(),
+                                                   Brackets);
+        }
+
+      }
+    }
+
+    if (Kind.getKind() == InitializationKind::IK_Copy || Kind.isExplicitCast())
+      return Sema::OwningExprResult(S, Args.release()[0]);
+
+    if (Args.size() == 0)
+      return S.Owned((Expr *)0);
+
+    unsigned NumArgs = Args.size();
+    return S.Owned(new (S.Context) ParenListExpr(S.Context,
+                                                 SourceLocation(),
+                                                 (Expr **)Args.release(), 
+                                                 NumArgs,
+                                                 SourceLocation()));
+  }
+
+  if (SequenceKind == NoInitialization)
+    return S.Owned((Expr *)0);
+  
+  QualType DestType = Entity.getType().getNonReferenceType();
+  // FIXME: Ugly hack around the fact that Entity.getType() is not
+  // the same as Entity.getDecl()->getType() in cases involving type merging,
+  //  and we want latter when it makes sense.
+  if (ResultType)
+    *ResultType = Entity.getDecl() ? Entity.getDecl()->getType() :
+                                     Entity.getType();
+
+  Sema::OwningExprResult CurInit = S.Owned((Expr *)0);
+  
+  assert(!Steps.empty() && "Cannot have an empty initialization sequence");
+  
+  // For initialization steps that start with a single initializer, 
+  // grab the only argument out the Args and place it into the "current"
+  // initializer.
+  switch (Steps.front().Kind) {
+  case SK_ResolveAddressOfOverloadedFunction:
+  case SK_CastDerivedToBaseRValue:
+  case SK_CastDerivedToBaseLValue:
+  case SK_BindReference:
+  case SK_BindReferenceToTemporary:
+  case SK_ExtraneousCopyToTemporary:
+  case SK_UserConversion:
+  case SK_QualificationConversionLValue:
+  case SK_QualificationConversionRValue:
+  case SK_ConversionSequence:
+  case SK_ListInitialization:
+  case SK_CAssignment:
+  case SK_StringInit:
+    assert(Args.size() == 1);
+    CurInit = Sema::OwningExprResult(S, ((Expr **)(Args.get()))[0]->Retain());
+    if (CurInit.isInvalid())
+      return S.ExprError();
+    break;
+    
+  case SK_ConstructorInitialization:
+  case SK_ZeroInitialization:
+    break;
+  }
+    
+  // Walk through the computed steps for the initialization sequence, 
+  // performing the specified conversions along the way.
+  bool ConstructorInitRequiresZeroInit = false;
+  for (step_iterator Step = step_begin(), StepEnd = step_end();
+       Step != StepEnd; ++Step) {
+    if (CurInit.isInvalid())
+      return S.ExprError();
+    
+    Expr *CurInitExpr = (Expr *)CurInit.get();
+    QualType SourceType = CurInitExpr? CurInitExpr->getType() : QualType();
+    
+    switch (Step->Kind) {
+    case SK_ResolveAddressOfOverloadedFunction:
+      // Overload resolution determined which function invoke; update the 
+      // initializer to reflect that choice.
+      S.CheckAddressOfMemberAccess(CurInitExpr, Step->Function.FoundDecl);
+      CurInit = S.FixOverloadedFunctionReference(move(CurInit),
+                                                 Step->Function.FoundDecl,
+                                                 Step->Function.Function);
+      break;
+        
+    case SK_CastDerivedToBaseRValue:
+    case SK_CastDerivedToBaseLValue: {
+      // We have a derived-to-base cast that produces either an rvalue or an
+      // lvalue. Perform that cast.
+      
+      CXXBaseSpecifierArray BasePath;
+
+      // Casts to inaccessible base classes are allowed with C-style casts.
+      bool IgnoreBaseAccess = Kind.isCStyleOrFunctionalCast();
+      if (S.CheckDerivedToBaseConversion(SourceType, Step->Type,
+                                         CurInitExpr->getLocStart(),
+                                         CurInitExpr->getSourceRange(), 
+                                         &BasePath, IgnoreBaseAccess))
+        return S.ExprError();
+        
+      CurInit = S.Owned(new (S.Context) ImplicitCastExpr(Step->Type,
+                                                    CastExpr::CK_DerivedToBase,
+                                                    (Expr*)CurInit.release(),
+                                                    BasePath,
+                                     Step->Kind == SK_CastDerivedToBaseLValue));
+      break;
+    }
+        
+    case SK_BindReference:
+      if (FieldDecl *BitField = CurInitExpr->getBitField()) {
+        // References cannot bind to bit fields (C++ [dcl.init.ref]p5).
+        S.Diag(Kind.getLocation(), diag::err_reference_bind_to_bitfield)
+          << Entity.getType().isVolatileQualified()
+          << BitField->getDeclName()
+          << CurInitExpr->getSourceRange();
+        S.Diag(BitField->getLocation(), diag::note_bitfield_decl);
+        return S.ExprError();
+      }
+
+      if (CurInitExpr->refersToVectorElement()) {
+        // References cannot bind to vector elements.
+        S.Diag(Kind.getLocation(), diag::err_reference_bind_to_vector_element)
+          << Entity.getType().isVolatileQualified()
+          << CurInitExpr->getSourceRange();
+        PrintInitLocationNote(S, Entity);
+        return S.ExprError();
+      }
+        
+      // Reference binding does not have any corresponding ASTs.
+
+      // Check exception specifications
+      if (S.CheckExceptionSpecCompatibility(CurInitExpr, DestType))
+        return S.ExprError();
+
+      break;
+
+    case SK_BindReferenceToTemporary:
+      // Reference binding does not have any corresponding ASTs.
+
+      // Check exception specifications
+      if (S.CheckExceptionSpecCompatibility(CurInitExpr, DestType))
+        return S.ExprError();
+
+      break;
+        
+    case SK_ExtraneousCopyToTemporary:
+      CurInit = CopyObject(S, Step->Type, Entity, move(CurInit), 
+                           /*IsExtraneousCopy=*/true);
+      break;
+
+    case SK_UserConversion: {
+      // We have a user-defined conversion that invokes either a constructor
+      // or a conversion function.
+      CastExpr::CastKind CastKind = CastExpr::CK_Unknown;
+      bool IsCopy = false;
+      FunctionDecl *Fn = Step->Function.Function;
+      DeclAccessPair FoundFn = Step->Function.FoundDecl;
+      bool CreatedObject = false;
+      bool IsLvalue = false;
+      if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(Fn)) {
+        // Build a call to the selected constructor.
+        ASTOwningVector<&ActionBase::DeleteExpr> ConstructorArgs(S);
+        SourceLocation Loc = CurInitExpr->getLocStart();
+        CurInit.release(); // Ownership transferred into MultiExprArg, below.
+
+        // Determine the arguments required to actually perform the constructor
+        // call.
+        if (S.CompleteConstructorCall(Constructor,
+                                      Sema::MultiExprArg(S, 
+                                                         (void **)&CurInitExpr,
+                                                         1),
+                                      Loc, ConstructorArgs))
+          return S.ExprError();
+        
+        // Build the an expression that constructs a temporary.
+        CurInit = S.BuildCXXConstructExpr(Loc, Step->Type, Constructor, 
+                                          move_arg(ConstructorArgs));
+        if (CurInit.isInvalid())
+          return S.ExprError();
+
+        S.CheckConstructorAccess(Kind.getLocation(), Constructor, Entity,
+                                 FoundFn.getAccess());
+        
+        CastKind = CastExpr::CK_ConstructorConversion;
+        QualType Class = S.Context.getTypeDeclType(Constructor->getParent());
+        if (S.Context.hasSameUnqualifiedType(SourceType, Class) ||
+            S.IsDerivedFrom(SourceType, Class))
+          IsCopy = true;
+        
+        CreatedObject = true;
+      } else {
+        // Build a call to the conversion function.
+        CXXConversionDecl *Conversion = cast<CXXConversionDecl>(Fn);
+        IsLvalue = Conversion->getResultType()->isLValueReferenceType();
+        S.CheckMemberOperatorAccess(Kind.getLocation(), CurInitExpr, 0,
+                                    FoundFn);
+        
+        // FIXME: Should we move this initialization into a separate 
+        // derived-to-base conversion? I believe the answer is "no", because
+        // we don't want to turn off access control here for c-style casts.
+        if (S.PerformObjectArgumentInitialization(CurInitExpr, /*Qualifier=*/0,
+                                                  FoundFn, Conversion))
+          return S.ExprError();
+
+        // Do a little dance to make sure that CurInit has the proper
+        // pointer.
+        CurInit.release();
+        
+        // Build the actual call to the conversion function.
+        CurInit = S.Owned(S.BuildCXXMemberCallExpr(CurInitExpr, FoundFn,
+                                                   Conversion));
+        if (CurInit.isInvalid() || !CurInit.get())
+          return S.ExprError();
+        
+        CastKind = CastExpr::CK_UserDefinedConversion;
+        
+        CreatedObject = Conversion->getResultType()->isRecordType();
+      }
+      
+      bool RequiresCopy = !IsCopy && 
+        getKind() != InitializationSequence::ReferenceBinding;
+      if (RequiresCopy || shouldBindAsTemporary(Entity))
+        CurInit = S.MaybeBindToTemporary(CurInit.takeAs<Expr>());
+      else if (CreatedObject && shouldDestroyTemporary(Entity)) {
+        CurInitExpr = static_cast<Expr *>(CurInit.get());
+        QualType T = CurInitExpr->getType();
+        if (const RecordType *Record = T->getAs<RecordType>()) {
+          CXXDestructorDecl *Destructor
+            = cast<CXXRecordDecl>(Record->getDecl())->getDestructor(S.Context);
+          S.CheckDestructorAccess(CurInitExpr->getLocStart(), Destructor, 
+                                  S.PDiag(diag::err_access_dtor_temp) << T);
+          S.MarkDeclarationReferenced(CurInitExpr->getLocStart(), Destructor);
+        }
+      }
+      
+      CurInitExpr = CurInit.takeAs<Expr>();
+      CurInit = S.Owned(new (S.Context) ImplicitCastExpr(CurInitExpr->getType(),
+                                                         CastKind, 
+                                                         CurInitExpr,
+                                                        CXXBaseSpecifierArray(),
+                                                         IsLvalue));
+      
+      if (RequiresCopy)
+        CurInit = CopyObject(S, Entity.getType().getNonReferenceType(), Entity,
+                             move(CurInit), /*IsExtraneousCopy=*/false);
+      
+      break;
+    }
+        
+    case SK_QualificationConversionLValue:
+    case SK_QualificationConversionRValue:
+      // Perform a qualification conversion; these can never go wrong.
+      S.ImpCastExprToType(CurInitExpr, Step->Type,
+                          CastExpr::CK_NoOp,
+                          Step->Kind == SK_QualificationConversionLValue);
+      CurInit.release();
+      CurInit = S.Owned(CurInitExpr);
+      break;
+        
+    case SK_ConversionSequence: {
+      bool IgnoreBaseAccess = Kind.isCStyleOrFunctionalCast();
+
+      if (S.PerformImplicitConversion(CurInitExpr, Step->Type, *Step->ICS,
+                                      Sema::AA_Converting, IgnoreBaseAccess))
+        return S.ExprError();
+        
+      CurInit.release();
+      CurInit = S.Owned(CurInitExpr);
+      break;
+    }
+        
+    case SK_ListInitialization: {
+      InitListExpr *InitList = cast<InitListExpr>(CurInitExpr);
+      QualType Ty = Step->Type;
+      if (S.CheckInitList(Entity, InitList, ResultType? *ResultType : Ty))
+        return S.ExprError();
+
+      CurInit.release();
+      CurInit = S.Owned(InitList);
+      break;
+    }
+
+    case SK_ConstructorInitialization: {
+      unsigned NumArgs = Args.size();
+      CXXConstructorDecl *Constructor
+        = cast<CXXConstructorDecl>(Step->Function.Function);
+
+      // Build a call to the selected constructor.
+      ASTOwningVector<&ActionBase::DeleteExpr> ConstructorArgs(S);
+      SourceLocation Loc = Kind.getLocation();
+          
+      // Determine the arguments required to actually perform the constructor
+      // call.
+      if (S.CompleteConstructorCall(Constructor, move(Args), 
+                                    Loc, ConstructorArgs))
+        return S.ExprError();
+          
+      // Build the expression that constructs a temporary.
+      if (Entity.getKind() == InitializedEntity::EK_Temporary &&
+          NumArgs != 1 && // FIXME: Hack to work around cast weirdness
+          (Kind.getKind() == InitializationKind::IK_Direct ||
+           Kind.getKind() == InitializationKind::IK_Value)) {
+        // An explicitly-constructed temporary, e.g., X(1, 2).
+        unsigned NumExprs = ConstructorArgs.size();
+        Expr **Exprs = (Expr **)ConstructorArgs.take();
+        S.MarkDeclarationReferenced(Kind.getLocation(), Constructor);
+        CurInit = S.Owned(new (S.Context) CXXTemporaryObjectExpr(S.Context,
+                                                                 Constructor,
+                                                              Entity.getType(),
+                                                            Kind.getLocation(),
+                                                                 Exprs, 
+                                                                 NumExprs,
+                                                Kind.getParenRange().getEnd()));
+      } else
+        CurInit = S.BuildCXXConstructExpr(Loc, Entity.getType(),
+                                          Constructor, 
+                                          move_arg(ConstructorArgs),
+                                          ConstructorInitRequiresZeroInit,
+                               Entity.getKind() == InitializedEntity::EK_Base);
+      if (CurInit.isInvalid())
+        return S.ExprError();
+
+      // Only check access if all of that succeeded.
+      S.CheckConstructorAccess(Loc, Constructor, Entity,
+                               Step->Function.FoundDecl.getAccess());
+      
+      if (shouldBindAsTemporary(Entity))
+        CurInit = S.MaybeBindToTemporary(CurInit.takeAs<Expr>());
+      
+      break;
+    }
+        
+    case SK_ZeroInitialization: {
+      step_iterator NextStep = Step;
+      ++NextStep;
+      if (NextStep != StepEnd && 
+          NextStep->Kind == SK_ConstructorInitialization) {
+        // The need for zero-initialization is recorded directly into
+        // the call to the object's constructor within the next step.
+        ConstructorInitRequiresZeroInit = true;
+      } else if (Kind.getKind() == InitializationKind::IK_Value &&
+                 S.getLangOptions().CPlusPlus &&
+                 !Kind.isImplicitValueInit()) {
+        CurInit = S.Owned(new (S.Context) CXXZeroInitValueExpr(Step->Type,
+                                                   Kind.getRange().getBegin(),
+                                                    Kind.getRange().getEnd()));
+      } else {
+        CurInit = S.Owned(new (S.Context) ImplicitValueInitExpr(Step->Type));
+      }
+      break;
+    }
+
+    case SK_CAssignment: {
+      QualType SourceType = CurInitExpr->getType();
+      Sema::AssignConvertType ConvTy =
+        S.CheckSingleAssignmentConstraints(Step->Type, CurInitExpr);
+
+      // If this is a call, allow conversion to a transparent union.
+      if (ConvTy != Sema::Compatible &&
+          Entity.getKind() == InitializedEntity::EK_Parameter &&
+          S.CheckTransparentUnionArgumentConstraints(Step->Type, CurInitExpr)
+            == Sema::Compatible)
+        ConvTy = Sema::Compatible;
+
+      bool Complained;
+      if (S.DiagnoseAssignmentResult(ConvTy, Kind.getLocation(),
+                                     Step->Type, SourceType,
+                                     CurInitExpr, 
+                                     getAssignmentAction(Entity),
+                                     &Complained)) {
+        PrintInitLocationNote(S, Entity);
+        return S.ExprError();
+      } else if (Complained)
+        PrintInitLocationNote(S, Entity);
+
+      CurInit.release();
+      CurInit = S.Owned(CurInitExpr);
+      break;
+    }
+
+    case SK_StringInit: {
+      QualType Ty = Step->Type;
+      CheckStringInit(CurInitExpr, ResultType ? *ResultType : Ty, S);
+      break;
+    }
+    }
+  }
+  
+  return move(CurInit);
+}
+
+//===----------------------------------------------------------------------===//
+// Diagnose initialization failures
+//===----------------------------------------------------------------------===//
+bool InitializationSequence::Diagnose(Sema &S, 
+                                      const InitializedEntity &Entity,
+                                      const InitializationKind &Kind,
+                                      Expr **Args, unsigned NumArgs) {
+  if (SequenceKind != FailedSequence)
+    return false;
+  
+  QualType DestType = Entity.getType();
+  switch (Failure) {
+  case FK_TooManyInitsForReference:
+    // FIXME: Customize for the initialized entity?
+    if (NumArgs == 0)
+      S.Diag(Kind.getLocation(), diag::err_reference_without_init)
+        << DestType.getNonReferenceType();
+    else  // FIXME: diagnostic below could be better!
+      S.Diag(Kind.getLocation(), diag::err_reference_has_multiple_inits)
+        << SourceRange(Args[0]->getLocStart(), Args[NumArgs - 1]->getLocEnd());
+    break;
+    
+  case FK_ArrayNeedsInitList:
+  case FK_ArrayNeedsInitListOrStringLiteral:
+    S.Diag(Kind.getLocation(), diag::err_array_init_not_init_list)
+      << (Failure == FK_ArrayNeedsInitListOrStringLiteral);
+    break;
+      
+  case FK_AddressOfOverloadFailed: {
+    DeclAccessPair Found;
+    S.ResolveAddressOfOverloadedFunction(Args[0], 
+                                         DestType.getNonReferenceType(),
+                                         true,
+                                         Found);
+    break;
+  }
+      
+  case FK_ReferenceInitOverloadFailed:
+  case FK_UserConversionOverloadFailed:
+    switch (FailedOverloadResult) {
+    case OR_Ambiguous:
+      if (Failure == FK_UserConversionOverloadFailed)
+        S.Diag(Kind.getLocation(), diag::err_typecheck_ambiguous_condition)
+          << Args[0]->getType() << DestType
+          << Args[0]->getSourceRange();
+      else
+        S.Diag(Kind.getLocation(), diag::err_ref_init_ambiguous)
+          << DestType << Args[0]->getType()
+          << Args[0]->getSourceRange();
+
+      S.PrintOverloadCandidates(FailedCandidateSet, Sema::OCD_ViableCandidates,
+                                Args, NumArgs);
+      break;
+        
+    case OR_No_Viable_Function:
+      S.Diag(Kind.getLocation(), diag::err_typecheck_nonviable_condition)
+        << Args[0]->getType() << DestType.getNonReferenceType()
+        << Args[0]->getSourceRange();
+      S.PrintOverloadCandidates(FailedCandidateSet, Sema::OCD_AllCandidates,
+                                Args, NumArgs);
+      break;
+        
+    case OR_Deleted: {
+      S.Diag(Kind.getLocation(), diag::err_typecheck_deleted_function)
+        << Args[0]->getType() << DestType.getNonReferenceType()
+        << Args[0]->getSourceRange();
+      OverloadCandidateSet::iterator Best;
+      OverloadingResult Ovl = S.BestViableFunction(FailedCandidateSet,
+                                                   Kind.getLocation(),
+                                                   Best);
+      if (Ovl == OR_Deleted) {
+        S.Diag(Best->Function->getLocation(), diag::note_unavailable_here)
+          << Best->Function->isDeleted();
+      } else {
+        llvm_unreachable("Inconsistent overload resolution?");
+      }
+      break;
+    }
+        
+    case OR_Success:
+      llvm_unreachable("Conversion did not fail!");
+      break;
+    }
+    break;
+      
+  case FK_NonConstLValueReferenceBindingToTemporary:
+  case FK_NonConstLValueReferenceBindingToUnrelated:
+    S.Diag(Kind.getLocation(), 
+           Failure == FK_NonConstLValueReferenceBindingToTemporary
+             ? diag::err_lvalue_reference_bind_to_temporary
+             : diag::err_lvalue_reference_bind_to_unrelated)
+      << DestType.getNonReferenceType().isVolatileQualified()
+      << DestType.getNonReferenceType()
+      << Args[0]->getType()
+      << Args[0]->getSourceRange();
+    break;
+      
+  case FK_RValueReferenceBindingToLValue:
+    S.Diag(Kind.getLocation(), diag::err_lvalue_to_rvalue_ref)
+      << Args[0]->getSourceRange();
+    break;
+      
+  case FK_ReferenceInitDropsQualifiers:
+    S.Diag(Kind.getLocation(), diag::err_reference_bind_drops_quals)
+      << DestType.getNonReferenceType()
+      << Args[0]->getType()
+      << Args[0]->getSourceRange();
+    break;
+      
+  case FK_ReferenceInitFailed:
+    S.Diag(Kind.getLocation(), diag::err_reference_bind_failed)
+      << DestType.getNonReferenceType()
+      << (Args[0]->isLvalue(S.Context) == Expr::LV_Valid)
+      << Args[0]->getType()
+      << Args[0]->getSourceRange();
+    break;
+      
+  case FK_ConversionFailed:
+    S.Diag(Kind.getLocation(), diag::err_init_conversion_failed)
+      << (int)Entity.getKind()
+      << DestType
+      << (Args[0]->isLvalue(S.Context) == Expr::LV_Valid)
+      << Args[0]->getType()
+      << Args[0]->getSourceRange();
+    break;
+
+  case FK_TooManyInitsForScalar: {
+    SourceRange R;
+
+    if (InitListExpr *InitList = dyn_cast<InitListExpr>(Args[0]))
+      R = SourceRange(InitList->getInit(1)->getLocStart(),
+                      InitList->getLocEnd());
+    else
+      R = SourceRange(Args[0]->getLocStart(), Args[NumArgs - 1]->getLocEnd());
+
+    S.Diag(Kind.getLocation(), diag::err_excess_initializers)
+      << /*scalar=*/2 << R;
+    break;
+  }
+
+  case FK_ReferenceBindingToInitList:
+    S.Diag(Kind.getLocation(), diag::err_reference_bind_init_list)
+      << DestType.getNonReferenceType() << Args[0]->getSourceRange();
+    break;
+
+  case FK_InitListBadDestinationType:
+    S.Diag(Kind.getLocation(), diag::err_init_list_bad_dest_type)
+      << (DestType->isRecordType()) << DestType << Args[0]->getSourceRange();
+    break;
+      
+  case FK_ConstructorOverloadFailed: {
+    SourceRange ArgsRange;
+    if (NumArgs)
+      ArgsRange = SourceRange(Args[0]->getLocStart(), 
+                              Args[NumArgs - 1]->getLocEnd());
+    
+    // FIXME: Using "DestType" for the entity we're printing is probably
+    // bad.
+    switch (FailedOverloadResult) {
+      case OR_Ambiguous:
+        S.Diag(Kind.getLocation(), diag::err_ovl_ambiguous_init)
+          << DestType << ArgsRange;
+        S.PrintOverloadCandidates(FailedCandidateSet,
+                                  Sema::OCD_ViableCandidates, Args, NumArgs);
+        break;
+        
+      case OR_No_Viable_Function:
+        if (Kind.getKind() == InitializationKind::IK_Default &&
+            (Entity.getKind() == InitializedEntity::EK_Base ||
+             Entity.getKind() == InitializedEntity::EK_Member) &&
+            isa<CXXConstructorDecl>(S.CurContext)) {
+          // This is implicit default initialization of a member or
+          // base within a constructor. If no viable function was
+          // found, notify the user that she needs to explicitly
+          // initialize this base/member.
+          CXXConstructorDecl *Constructor
+            = cast<CXXConstructorDecl>(S.CurContext);
+          if (Entity.getKind() == InitializedEntity::EK_Base) {
+            S.Diag(Kind.getLocation(), diag::err_missing_default_ctor)
+              << Constructor->isImplicit()
+              << S.Context.getTypeDeclType(Constructor->getParent())
+              << /*base=*/0
+              << Entity.getType();
+
+            RecordDecl *BaseDecl
+              = Entity.getBaseSpecifier()->getType()->getAs<RecordType>()
+                                                                  ->getDecl();
+            S.Diag(BaseDecl->getLocation(), diag::note_previous_decl)
+              << S.Context.getTagDeclType(BaseDecl);
+          } else {
+            S.Diag(Kind.getLocation(), diag::err_missing_default_ctor)
+              << Constructor->isImplicit()
+              << S.Context.getTypeDeclType(Constructor->getParent())
+              << /*member=*/1
+              << Entity.getName();
+            S.Diag(Entity.getDecl()->getLocation(), diag::note_field_decl);
+
+            if (const RecordType *Record
+                                 = Entity.getType()->getAs<RecordType>())
+              S.Diag(Record->getDecl()->getLocation(), 
+                     diag::note_previous_decl)
+                << S.Context.getTagDeclType(Record->getDecl());
+          }
+          break;
+        }
+
+        S.Diag(Kind.getLocation(), diag::err_ovl_no_viable_function_in_init)
+          << DestType << ArgsRange;
+        S.PrintOverloadCandidates(FailedCandidateSet, Sema::OCD_AllCandidates,
+                                  Args, NumArgs);
+        break;
+        
+      case OR_Deleted: {
+        S.Diag(Kind.getLocation(), diag::err_ovl_deleted_init)
+          << true << DestType << ArgsRange;
+        OverloadCandidateSet::iterator Best;
+        OverloadingResult Ovl = S.BestViableFunction(FailedCandidateSet,
+                                                     Kind.getLocation(),
+                                                     Best);
+        if (Ovl == OR_Deleted) {
+          S.Diag(Best->Function->getLocation(), diag::note_unavailable_here)
+            << Best->Function->isDeleted();
+        } else {
+          llvm_unreachable("Inconsistent overload resolution?");
+        }
+        break;
+      }
+        
+      case OR_Success:
+        llvm_unreachable("Conversion did not fail!");
+        break;
+    }
+    break;
+  }
+      
+  case FK_DefaultInitOfConst:
+    if (Entity.getKind() == InitializedEntity::EK_Member &&
+        isa<CXXConstructorDecl>(S.CurContext)) {
+      // This is implicit default-initialization of a const member in
+      // a constructor. Complain that it needs to be explicitly
+      // initialized.
+      CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(S.CurContext);
+      S.Diag(Kind.getLocation(), diag::err_uninitialized_member_in_ctor)
+        << Constructor->isImplicit()
+        << S.Context.getTypeDeclType(Constructor->getParent())
+        << /*const=*/1
+        << Entity.getName();
+      S.Diag(Entity.getDecl()->getLocation(), diag::note_previous_decl)
+        << Entity.getName();
+    } else {
+      S.Diag(Kind.getLocation(), diag::err_default_init_const)
+        << DestType << (bool)DestType->getAs<RecordType>();
+    }
+    break;
+  }
+  
+  PrintInitLocationNote(S, Entity);
+  return true;
+}
+
+void InitializationSequence::dump(llvm::raw_ostream &OS) const {
+  switch (SequenceKind) {
+  case FailedSequence: {
+    OS << "Failed sequence: ";
+    switch (Failure) {
+    case FK_TooManyInitsForReference:
+      OS << "too many initializers for reference";
+      break;
+      
+    case FK_ArrayNeedsInitList:
+      OS << "array requires initializer list";
+      break;
+      
+    case FK_ArrayNeedsInitListOrStringLiteral:
+      OS << "array requires initializer list or string literal";
+      break;
+      
+    case FK_AddressOfOverloadFailed:
+      OS << "address of overloaded function failed";
+      break;
+      
+    case FK_ReferenceInitOverloadFailed:
+      OS << "overload resolution for reference initialization failed";
+      break;
+      
+    case FK_NonConstLValueReferenceBindingToTemporary:
+      OS << "non-const lvalue reference bound to temporary";
+      break;
+      
+    case FK_NonConstLValueReferenceBindingToUnrelated:
+      OS << "non-const lvalue reference bound to unrelated type";
+      break;
+      
+    case FK_RValueReferenceBindingToLValue:
+      OS << "rvalue reference bound to an lvalue";
+      break;
+      
+    case FK_ReferenceInitDropsQualifiers:
+      OS << "reference initialization drops qualifiers";
+      break;
+      
+    case FK_ReferenceInitFailed:
+      OS << "reference initialization failed";
+      break;
+      
+    case FK_ConversionFailed:
+      OS << "conversion failed";
+      break;
+      
+    case FK_TooManyInitsForScalar:
+      OS << "too many initializers for scalar";
+      break;
+      
+    case FK_ReferenceBindingToInitList:
+      OS << "referencing binding to initializer list";
+      break;
+      
+    case FK_InitListBadDestinationType:
+      OS << "initializer list for non-aggregate, non-scalar type";
+      break;
+      
+    case FK_UserConversionOverloadFailed:
+      OS << "overloading failed for user-defined conversion";
+      break;
+      
+    case FK_ConstructorOverloadFailed:
+      OS << "constructor overloading failed";
+      break;
+      
+    case FK_DefaultInitOfConst:
+      OS << "default initialization of a const variable";
+      break;
+    }   
+    OS << '\n';
+    return;
+  }
+      
+  case DependentSequence:
+    OS << "Dependent sequence: ";
+    return;
+      
+  case UserDefinedConversion:
+    OS << "User-defined conversion sequence: ";
+    break;
+      
+  case ConstructorInitialization:
+    OS << "Constructor initialization sequence: ";
+    break;
+      
+  case ReferenceBinding:
+    OS << "Reference binding: ";
+    break;
+      
+  case ListInitialization:
+    OS << "List initialization: ";
+    break;
+
+  case ZeroInitialization:
+    OS << "Zero initialization\n";
+    return;
+      
+  case NoInitialization:
+    OS << "No initialization\n";
+    return;
+      
+  case StandardConversion:
+    OS << "Standard conversion: ";
+    break;
+      
+  case CAssignment:
+    OS << "C assignment: ";
+    break;
+      
+  case StringInit:
+    OS << "String initialization: ";
+    break;
+  }
+  
+  for (step_iterator S = step_begin(), SEnd = step_end(); S != SEnd; ++S) {
+    if (S != step_begin()) {
+      OS << " -> ";
+    }
+    
+    switch (S->Kind) {
+    case SK_ResolveAddressOfOverloadedFunction:
+      OS << "resolve address of overloaded function";
+      break;
+      
+    case SK_CastDerivedToBaseRValue:
+      OS << "derived-to-base case (rvalue" << S->Type.getAsString() << ")";
+      break;
+      
+    case SK_CastDerivedToBaseLValue:
+      OS << "derived-to-base case (lvalue" << S->Type.getAsString() << ")";
+      break;
+      
+    case SK_BindReference:
+      OS << "bind reference to lvalue";
+      break;
+      
+    case SK_BindReferenceToTemporary:
+      OS << "bind reference to a temporary";
+      break;
+      
+    case SK_ExtraneousCopyToTemporary:
+      OS << "extraneous C++03 copy to temporary";
+      break;
+
+    case SK_UserConversion:
+      OS << "user-defined conversion via " << S->Function.Function;
+      break;
+      
+    case SK_QualificationConversionRValue:
+      OS << "qualification conversion (rvalue)";
+
+    case SK_QualificationConversionLValue:
+      OS << "qualification conversion (lvalue)";
+      break;
+      
+    case SK_ConversionSequence:
+      OS << "implicit conversion sequence (";
+      S->ICS->DebugPrint(); // FIXME: use OS
+      OS << ")";
+      break;
+      
+    case SK_ListInitialization:
+      OS << "list initialization";
+      break;
+      
+    case SK_ConstructorInitialization:
+      OS << "constructor initialization";
+      break;
+      
+    case SK_ZeroInitialization:
+      OS << "zero initialization";
+      break;
+      
+    case SK_CAssignment:
+      OS << "C assignment";
+      break;
+      
+    case SK_StringInit:
+      OS << "string initialization";
+      break;
+    }
+  }
+}
+
+void InitializationSequence::dump() const {
+  dump(llvm::errs());
+}
+
+//===----------------------------------------------------------------------===//
+// Initialization helper functions
+//===----------------------------------------------------------------------===//
+Sema::OwningExprResult 
+Sema::PerformCopyInitialization(const InitializedEntity &Entity,
+                                SourceLocation EqualLoc,
+                                OwningExprResult Init) {
+  if (Init.isInvalid())
+    return ExprError();
+
+  Expr *InitE = (Expr *)Init.get();
+  assert(InitE && "No initialization expression?");
+
+  if (EqualLoc.isInvalid())
+    EqualLoc = InitE->getLocStart();
+
+  InitializationKind Kind = InitializationKind::CreateCopy(InitE->getLocStart(),
+                                                           EqualLoc);
+  InitializationSequence Seq(*this, Entity, Kind, &InitE, 1);
+  Init.release();
+  return Seq.Perform(*this, Entity, Kind, 
+                     MultiExprArg(*this, (void**)&InitE, 1));
+}
diff --git a/lib/Sema/SemaInit.h b/lib/Sema/SemaInit.h
new file mode 100644
index 0000000..5f2592f
--- /dev/null
+++ b/lib/Sema/SemaInit.h
@@ -0,0 +1,741 @@
+//===--- SemaInit.h - Semantic Analysis for Initializers --------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides supporting data types for initialization of objects.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_SEMA_INIT_H
+#define LLVM_CLANG_SEMA_INIT_H
+
+#include "SemaOverload.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/UnresolvedSet.h"
+#include "clang/Parse/Action.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/SmallVector.h"
+#include <cassert>
+
+namespace llvm {
+  class raw_ostream;
+}
+
+namespace clang {
+  
+class CXXBaseSpecifier;
+class DeclaratorDecl;
+class DeclaratorInfo;
+class FieldDecl;
+class FunctionDecl;
+class ParmVarDecl;
+class Sema;
+class TypeLoc;
+class VarDecl;
+  
+/// \brief Describes an entity that is being initialized.
+class InitializedEntity {
+public:
+  /// \brief Specifies the kind of entity being initialized.
+  enum EntityKind {
+    /// \brief The entity being initialized is a variable.
+    EK_Variable,
+    /// \brief The entity being initialized is a function parameter.
+    EK_Parameter,
+    /// \brief The entity being initialized is the result of a function call.
+    EK_Result,
+    /// \brief The entity being initialized is an exception object that
+    /// is being thrown.
+    EK_Exception,
+    /// \brief The entity being initialized is a non-static data member 
+    /// subobject.
+    EK_Member,
+    /// \brief The entity being initialized is an element of an array.
+    EK_ArrayElement,
+    /// \brief The entity being initialized is an object (or array of
+    /// objects) allocated via new.
+    EK_New,
+    /// \brief The entity being initialized is a temporary object.
+    EK_Temporary,
+    /// \brief The entity being initialized is a base member subobject.
+    EK_Base,
+    /// \brief The entity being initialized is an element of a vector.
+    /// or vector.
+    EK_VectorElement
+  };
+  
+private:
+  /// \brief The kind of entity being initialized.
+  EntityKind Kind;
+
+  /// \brief If non-NULL, the parent entity in which this
+  /// initialization occurs.
+  const InitializedEntity *Parent;
+
+  /// \brief The type of the object or reference being initialized.
+  QualType Type;
+  
+  union {
+    /// \brief When Kind == EK_Variable, EK_Parameter, or EK_Member, 
+    /// the VarDecl, ParmVarDecl, or FieldDecl, respectively.
+    DeclaratorDecl *VariableOrMember;
+    
+    /// \brief When Kind == EK_Result, EK_Exception, or EK_New, the
+    /// location of the 'return', 'throw', or 'new' keyword,
+    /// respectively. When Kind == EK_Temporary, the location where
+    /// the temporary is being created.
+    unsigned Location;
+    
+    /// \brief When Kind == EK_Base, the base specifier that provides the 
+    /// base class. The lower bit specifies whether the base is an inherited
+    /// virtual base.
+    uintptr_t Base;
+
+    /// \brief When Kind == EK_ArrayElement or EK_VectorElement, the
+    /// index of the array or vector element being initialized. 
+    unsigned Index;
+  };
+
+  InitializedEntity() { }
+
+  /// \brief Create the initialization entity for a variable.
+  InitializedEntity(VarDecl *Var)
+    : Kind(EK_Variable), Parent(0), Type(Var->getType()),
+      VariableOrMember(reinterpret_cast<DeclaratorDecl*>(Var)) { }
+  
+  /// \brief Create the initialization entity for a parameter.
+  InitializedEntity(ParmVarDecl *Parm)
+    : Kind(EK_Parameter), Parent(0), Type(Parm->getType().getUnqualifiedType()),
+      VariableOrMember(reinterpret_cast<DeclaratorDecl*>(Parm)) { }
+  
+  /// \brief Create the initialization entity for the result of a
+  /// function, throwing an object, performing an explicit cast, or
+  /// initializing a parameter for which there is no declaration.
+  InitializedEntity(EntityKind Kind, SourceLocation Loc, QualType Type)
+    : Kind(Kind), Parent(0), Type(Type), Location(Loc.getRawEncoding()) { }
+  
+  /// \brief Create the initialization entity for a member subobject.
+  InitializedEntity(FieldDecl *Member, const InitializedEntity *Parent) 
+    : Kind(EK_Member), Parent(Parent), Type(Member->getType()),
+      VariableOrMember(reinterpret_cast<DeclaratorDecl*>(Member)) { }
+  
+  /// \brief Create the initialization entity for an array element.
+  InitializedEntity(ASTContext &Context, unsigned Index, 
+                    const InitializedEntity &Parent);
+
+public:
+  /// \brief Create the initialization entity for a variable.
+  static InitializedEntity InitializeVariable(VarDecl *Var) {
+    return InitializedEntity(Var);
+  }
+  
+  /// \brief Create the initialization entity for a parameter.
+  static InitializedEntity InitializeParameter(ParmVarDecl *Parm) {
+    return InitializedEntity(Parm);
+  }
+
+  /// \brief Create the initialization entity for a parameter that is
+  /// only known by its type.
+  static InitializedEntity InitializeParameter(QualType Type) {
+    InitializedEntity Entity;
+    Entity.Kind = EK_Parameter;
+    Entity.Type = Type;
+    Entity.Parent = 0;
+    Entity.VariableOrMember = 0;
+    return Entity;
+  }
+
+  /// \brief Create the initialization entity for the result of a function.
+  static InitializedEntity InitializeResult(SourceLocation ReturnLoc,
+                                            QualType Type) {
+    return InitializedEntity(EK_Result, ReturnLoc, Type);
+  }
+
+  /// \brief Create the initialization entity for an exception object.
+  static InitializedEntity InitializeException(SourceLocation ThrowLoc,
+                                               QualType Type) {
+    return InitializedEntity(EK_Exception, ThrowLoc, Type);
+  }
+
+  /// \brief Create the initialization entity for an object allocated via new.
+  static InitializedEntity InitializeNew(SourceLocation NewLoc, QualType Type) {
+    return InitializedEntity(EK_New, NewLoc, Type);
+  }
+  
+  /// \brief Create the initialization entity for a temporary.
+  static InitializedEntity InitializeTemporary(QualType Type) {
+    return InitializedEntity(EK_Temporary, SourceLocation(), Type);
+  }
+  
+  /// \brief Create the initialization entity for a base class subobject.
+  static InitializedEntity InitializeBase(ASTContext &Context,
+                                          CXXBaseSpecifier *Base,
+                                          bool IsInheritedVirtualBase);
+  
+  /// \brief Create the initialization entity for a member subobject.
+  static InitializedEntity InitializeMember(FieldDecl *Member,
+                                          const InitializedEntity *Parent = 0) {
+    return InitializedEntity(Member, Parent);
+  }
+  
+  /// \brief Create the initialization entity for an array element.
+  static InitializedEntity InitializeElement(ASTContext &Context, 
+                                             unsigned Index, 
+                                             const InitializedEntity &Parent) {
+    return InitializedEntity(Context, Index, Parent);
+  }
+
+  /// \brief Determine the kind of initialization.
+  EntityKind getKind() const { return Kind; }
+  
+  /// \brief Retrieve the parent of the entity being initialized, when
+  /// the initialization itself is occuring within the context of a
+  /// larger initialization.
+  const InitializedEntity *getParent() const { return Parent; }
+
+  /// \brief Retrieve type being initialized.
+  QualType getType() const { return Type; }
+  
+  /// \brief Retrieve the name of the entity being initialized.
+  DeclarationName getName() const;
+
+  /// \brief Retrieve the variable, parameter, or field being
+  /// initialized.
+  DeclaratorDecl *getDecl() const;
+
+  /// \brief Retrieve the base specifier.
+  CXXBaseSpecifier *getBaseSpecifier() const {
+    assert(getKind() == EK_Base && "Not a base specifier");
+    return reinterpret_cast<CXXBaseSpecifier *>(Base & ~0x1);
+  }
+
+  /// \brief Return whether the base is an inherited virtual base.
+  bool isInheritedVirtualBase() const {
+    assert(getKind() == EK_Base && "Not a base specifier");
+    return Base & 0x1;
+  }
+
+  /// \brief Determine the location of the 'return' keyword when initializing
+  /// the result of a function call.
+  SourceLocation getReturnLoc() const {
+    assert(getKind() == EK_Result && "No 'return' location!");
+    return SourceLocation::getFromRawEncoding(Location);
+  }
+  
+  /// \brief Determine the location of the 'throw' keyword when initializing
+  /// an exception object.
+  SourceLocation getThrowLoc() const {
+    assert(getKind() == EK_Exception && "No 'throw' location!");
+    return SourceLocation::getFromRawEncoding(Location);
+  }
+
+  /// \brief If this is already the initializer for an array or vector
+  /// element, sets the element index.
+  void setElementIndex(unsigned Index) {
+    assert(getKind() == EK_ArrayElement || getKind() == EK_VectorElement);
+    this->Index = Index;
+  }
+};
+  
+/// \brief Describes the kind of initialization being performed, along with 
+/// location information for tokens related to the initialization (equal sign,
+/// parentheses).
+class InitializationKind {
+public:
+  /// \brief The kind of initialization being performed.
+  enum InitKind {
+    IK_Direct,  ///< Direct initialization
+    IK_Copy,    ///< Copy initialization
+    IK_Default, ///< Default initialization
+    IK_Value    ///< Value initialization
+  };
+  
+private:
+  /// \brief The kind of initialization that we're storing.
+  enum StoredInitKind {
+    SIK_Direct = IK_Direct,   ///< Direct initialization
+    SIK_Copy = IK_Copy,       ///< Copy initialization
+    SIK_Default = IK_Default, ///< Default initialization
+    SIK_Value = IK_Value,     ///< Value initialization
+    SIK_ImplicitValue,        ///< Implicit value initialization
+    SIK_DirectCast,  ///< Direct initialization due to a cast
+    /// \brief Direct initialization due to a C-style or functional cast.
+    SIK_DirectCStyleOrFunctionalCast
+  };
+  
+  /// \brief The kind of initialization being performed.
+  StoredInitKind Kind;
+  
+  /// \brief The source locations involved in the initialization.
+  SourceLocation Locations[3];
+  
+  InitializationKind(StoredInitKind Kind, SourceLocation Loc1, 
+                     SourceLocation Loc2, SourceLocation Loc3)
+    : Kind(Kind) 
+  {
+    Locations[0] = Loc1;
+    Locations[1] = Loc2;
+    Locations[2] = Loc3;
+  }
+  
+public:
+  /// \brief Create a direct initialization.
+  static InitializationKind CreateDirect(SourceLocation InitLoc,
+                                         SourceLocation LParenLoc,
+                                         SourceLocation RParenLoc) {
+    return InitializationKind(SIK_Direct, InitLoc, LParenLoc, RParenLoc);
+  }
+
+  /// \brief Create a direct initialization due to a cast.
+  static InitializationKind CreateCast(SourceRange TypeRange,
+                                       bool IsCStyleCast) {
+    return InitializationKind(IsCStyleCast? SIK_DirectCStyleOrFunctionalCast
+                                          : SIK_DirectCast,
+                              TypeRange.getBegin(), TypeRange.getBegin(), 
+                              TypeRange.getEnd());
+  }
+  
+  /// \brief Create a copy initialization.
+  static InitializationKind CreateCopy(SourceLocation InitLoc,
+                                       SourceLocation EqualLoc) {
+    return InitializationKind(SIK_Copy, InitLoc, EqualLoc, EqualLoc);
+  }
+  
+  /// \brief Create a default initialization.
+  static InitializationKind CreateDefault(SourceLocation InitLoc) {
+    return InitializationKind(SIK_Default, InitLoc, InitLoc, InitLoc);
+  }
+  
+  /// \brief Create a value initialization.
+  static InitializationKind CreateValue(SourceLocation InitLoc,
+                                        SourceLocation LParenLoc,
+                                        SourceLocation RParenLoc,
+                                        bool isImplicit = false) {
+    return InitializationKind(isImplicit? SIK_ImplicitValue : SIK_Value, 
+                              InitLoc, LParenLoc, RParenLoc);
+  }
+  
+  /// \brief Determine the initialization kind.
+  InitKind getKind() const {
+    if (Kind > SIK_ImplicitValue)
+      return IK_Direct;
+    if (Kind == SIK_ImplicitValue)
+      return IK_Value;
+
+    return (InitKind)Kind;
+  }
+  
+  /// \brief Determine whether this initialization is an explicit cast.
+  bool isExplicitCast() const {
+    return Kind == SIK_DirectCast || Kind == SIK_DirectCStyleOrFunctionalCast;
+  }
+  
+  /// \brief Determine whether this initialization is a C-style cast.
+  bool isCStyleOrFunctionalCast() const { 
+    return Kind == SIK_DirectCStyleOrFunctionalCast; 
+  }
+
+  /// \brief Determine whether this initialization is an implicit
+  /// value-initialization, e.g., as occurs during aggregate
+  /// initialization.
+  bool isImplicitValueInit() const { return Kind == SIK_ImplicitValue; }
+
+  /// \brief Retrieve the location at which initialization is occurring.
+  SourceLocation getLocation() const { return Locations[0]; }
+  
+  /// \brief Retrieve the source range that covers the initialization.
+  SourceRange getRange() const { 
+    return SourceRange(Locations[0], Locations[2]);
+  }
+  
+  /// \brief Retrieve the location of the equal sign for copy initialization
+  /// (if present).
+  SourceLocation getEqualLoc() const {
+    assert(Kind == SIK_Copy && "Only copy initialization has an '='");
+    return Locations[1];
+  }
+  
+  /// \brief Retrieve the source range containing the locations of the open
+  /// and closing parentheses for value and direct initializations.
+  SourceRange getParenRange() const {
+    assert((getKind() == IK_Direct || Kind == SIK_Value) &&
+           "Only direct- and value-initialization have parentheses");
+    return SourceRange(Locations[1], Locations[2]);
+  }
+};
+
+/// \brief Describes the sequence of initializations required to initialize
+/// a given object or reference with a set of arguments.
+class InitializationSequence {
+public:
+  /// \brief Describes the kind of initialization sequence computed.
+  ///
+  /// FIXME: Much of this information is in the initialization steps... why is
+  /// it duplicated here?
+  enum SequenceKind {
+    /// \brief A failed initialization sequence. The failure kind tells what
+    /// happened.
+    FailedSequence = 0,
+    
+    /// \brief A dependent initialization, which could not be
+    /// type-checked due to the presence of dependent types or
+    /// dependently-type expressions.
+    DependentSequence,
+
+    /// \brief A user-defined conversion sequence.
+    UserDefinedConversion,
+    
+    /// \brief A constructor call.
+    ConstructorInitialization,
+    
+    /// \brief A reference binding.
+    ReferenceBinding,
+
+    /// \brief List initialization
+    ListInitialization,
+    
+    /// \brief Zero-initialization.
+    ZeroInitialization,
+    
+    /// \brief No initialization required.
+    NoInitialization,
+    
+    /// \brief Standard conversion sequence.
+    StandardConversion,
+
+    /// \brief C conversion sequence.
+    CAssignment,
+
+    /// \brief String initialization
+    StringInit
+  };
+  
+  /// \brief Describes the kind of a particular step in an initialization
+  /// sequence.
+  enum StepKind {
+    /// \brief Resolve the address of an overloaded function to a specific
+    /// function declaration.
+    SK_ResolveAddressOfOverloadedFunction,
+    /// \brief Perform a derived-to-base cast, producing an rvalue.
+    SK_CastDerivedToBaseRValue,
+    /// \brief Perform a derived-to-base cast, producing an lvalue.
+    SK_CastDerivedToBaseLValue,
+    /// \brief Reference binding to an lvalue.
+    SK_BindReference,
+    /// \brief Reference binding to a temporary.
+    SK_BindReferenceToTemporary,
+    /// \brief An optional copy of a temporary object to another
+    /// temporary object, which is permitted (but not required) by
+    /// C++98/03 but not C++0x.
+    SK_ExtraneousCopyToTemporary,
+    /// \brief Perform a user-defined conversion, either via a conversion
+    /// function or via a constructor.
+    SK_UserConversion,
+    /// \brief Perform a qualification conversion, producing an rvalue.
+    SK_QualificationConversionRValue,
+    /// \brief Perform a qualification conversion, producing an lvalue.
+    SK_QualificationConversionLValue,
+    /// \brief Perform an implicit conversion sequence.
+    SK_ConversionSequence,
+    /// \brief Perform list-initialization
+    SK_ListInitialization,
+    /// \brief Perform initialization via a constructor.
+    SK_ConstructorInitialization,
+    /// \brief Zero-initialize the object
+    SK_ZeroInitialization,
+    /// \brief C assignment
+    SK_CAssignment,
+    /// \brief Initialization by string
+    SK_StringInit
+  };
+  
+  /// \brief A single step in the initialization sequence.
+  class Step {
+  public:
+    /// \brief The kind of conversion or initialization step we are taking.
+    StepKind Kind;
+    
+    // \brief The type that results from this initialization.
+    QualType Type;
+    
+    union {
+      /// \brief When Kind == SK_ResolvedOverloadedFunction or Kind ==
+      /// SK_UserConversion, the function that the expression should be 
+      /// resolved to or the conversion function to call, respectively.
+      ///
+      /// Always a FunctionDecl.
+      /// For conversion decls, the naming class is the source type.
+      /// For construct decls, the naming class is the target type.
+      struct {
+        FunctionDecl *Function;
+        DeclAccessPair FoundDecl;
+      } Function;
+      
+      /// \brief When Kind = SK_ConversionSequence, the implicit conversion
+      /// sequence 
+      ImplicitConversionSequence *ICS;
+    };
+    
+    void Destroy();
+  };
+  
+private:
+  /// \brief The kind of initialization sequence computed.
+  enum SequenceKind SequenceKind;
+  
+  /// \brief Steps taken by this initialization.
+  llvm::SmallVector<Step, 4> Steps;
+  
+public:
+  /// \brief Describes why initialization failed.
+  enum FailureKind {
+    /// \brief Too many initializers provided for a reference.
+    FK_TooManyInitsForReference,
+    /// \brief Array must be initialized with an initializer list.
+    FK_ArrayNeedsInitList,
+    /// \brief Array must be initialized with an initializer list or a 
+    /// string literal.
+    FK_ArrayNeedsInitListOrStringLiteral,
+    /// \brief Cannot resolve the address of an overloaded function.
+    FK_AddressOfOverloadFailed,
+    /// \brief Overloading due to reference initialization failed.
+    FK_ReferenceInitOverloadFailed,
+    /// \brief Non-const lvalue reference binding to a temporary.
+    FK_NonConstLValueReferenceBindingToTemporary,
+    /// \brief Non-const lvalue reference binding to an lvalue of unrelated
+    /// type.
+    FK_NonConstLValueReferenceBindingToUnrelated,
+    /// \brief Rvalue reference binding to an lvalue.
+    FK_RValueReferenceBindingToLValue,
+    /// \brief Reference binding drops qualifiers.
+    FK_ReferenceInitDropsQualifiers,
+    /// \brief Reference binding failed.
+    FK_ReferenceInitFailed,
+    /// \brief Implicit conversion failed.
+    FK_ConversionFailed,
+    /// \brief Too many initializers for scalar
+    FK_TooManyInitsForScalar,
+    /// \brief Reference initialization from an initializer list
+    FK_ReferenceBindingToInitList,
+    /// \brief Initialization of some unused destination type with an
+    /// initializer list.
+    FK_InitListBadDestinationType,
+    /// \brief Overloading for a user-defined conversion failed.
+    FK_UserConversionOverloadFailed,
+    /// \brief Overloaded for initialization by constructor failed.
+    FK_ConstructorOverloadFailed,
+    /// \brief Default-initialization of a 'const' object.
+    FK_DefaultInitOfConst
+  };
+  
+private:
+  /// \brief The reason why initialization failued.
+  FailureKind Failure;
+
+  /// \brief The failed result of overload resolution.
+  OverloadingResult FailedOverloadResult;
+  
+  /// \brief The candidate set created when initialization failed.
+  OverloadCandidateSet FailedCandidateSet;
+
+  /// \brief Prints a follow-up note that highlights the location of
+  /// the initialized entity, if it's remote.
+  void PrintInitLocationNote(Sema &S, const InitializedEntity &Entity);
+
+public:
+  /// \brief Try to perform initialization of the given entity, creating a 
+  /// record of the steps required to perform the initialization.
+  ///
+  /// The generated initialization sequence will either contain enough
+  /// information to diagnose 
+  ///
+  /// \param S the semantic analysis object.
+  ///
+  /// \param Entity the entity being initialized.
+  ///
+  /// \param Kind the kind of initialization being performed.
+  ///
+  /// \param Args the argument(s) provided for initialization.
+  ///
+  /// \param NumArgs the number of arguments provided for initialization.
+  InitializationSequence(Sema &S, 
+                         const InitializedEntity &Entity,
+                         const InitializationKind &Kind,
+                         Expr **Args,
+                         unsigned NumArgs);
+  
+  ~InitializationSequence();
+  
+  /// \brief Perform the actual initialization of the given entity based on
+  /// the computed initialization sequence.
+  ///
+  /// \param S the semantic analysis object.
+  ///
+  /// \param Entity the entity being initialized.
+  ///
+  /// \param Kind the kind of initialization being performed.
+  ///
+  /// \param Args the argument(s) provided for initialization, ownership of
+  /// which is transfered into the routine.
+  ///
+  /// \param ResultType if non-NULL, will be set to the type of the
+  /// initialized object, which is the type of the declaration in most
+  /// cases. However, when the initialized object is a variable of
+  /// incomplete array type and the initializer is an initializer
+  /// list, this type will be set to the completed array type.
+  ///
+  /// \returns an expression that performs the actual object initialization, if
+  /// the initialization is well-formed. Otherwise, emits diagnostics
+  /// and returns an invalid expression.
+  Action::OwningExprResult Perform(Sema &S,
+                                   const InitializedEntity &Entity,
+                                   const InitializationKind &Kind,
+                                   Action::MultiExprArg Args,
+                                   QualType *ResultType = 0);
+  
+  /// \brief Diagnose an potentially-invalid initialization sequence.
+  ///
+  /// \returns true if the initialization sequence was ill-formed, 
+  /// false otherwise.
+  bool Diagnose(Sema &S, 
+                const InitializedEntity &Entity,
+                const InitializationKind &Kind,
+                Expr **Args, unsigned NumArgs);
+  
+  /// \brief Determine the kind of initialization sequence computed.
+  enum SequenceKind getKind() const { return SequenceKind; }
+  
+  /// \brief Set the kind of sequence computed.
+  void setSequenceKind(enum SequenceKind SK) { SequenceKind = SK; }
+  
+  /// \brief Determine whether the initialization sequence is valid.
+  operator bool() const { return SequenceKind != FailedSequence; }
+  
+  typedef llvm::SmallVector<Step, 4>::const_iterator step_iterator;
+  step_iterator step_begin() const { return Steps.begin(); }
+  step_iterator step_end()   const { return Steps.end(); }
+
+  /// \brief Determine whether this initialization is a direct reference 
+  /// binding (C++ [dcl.init.ref]).
+  bool isDirectReferenceBinding() const;
+  
+  /// \brief Determine whether this initialization failed due to an ambiguity.
+  bool isAmbiguous() const;
+  
+  /// \brief Determine whether this initialization is direct call to a 
+  /// constructor.
+  bool isConstructorInitialization() const;
+  
+  /// \brief Add a new step in the initialization that resolves the address
+  /// of an overloaded function to a specific function declaration.
+  ///
+  /// \param Function the function to which the overloaded function reference
+  /// resolves.
+  void AddAddressOverloadResolutionStep(FunctionDecl *Function,
+                                        DeclAccessPair Found);
+  
+  /// \brief Add a new step in the initialization that performs a derived-to-
+  /// base cast.
+  ///
+  /// \param BaseType the base type to which we will be casting.
+  ///
+  /// \param IsLValue true if the result of this cast will be treated as 
+  /// an lvalue.
+  void AddDerivedToBaseCastStep(QualType BaseType, bool IsLValue);
+     
+  /// \brief Add a new step binding a reference to an object.
+  ///
+  /// \param BindingTemporary True if we are binding a reference to a temporary
+  /// object (thereby extending its lifetime); false if we are binding to an
+  /// lvalue or an lvalue treated as an rvalue.
+  ///
+  /// \param UnnecessaryCopy True if we should check for a copy
+  /// constructor for a completely unnecessary but
+  void AddReferenceBindingStep(QualType T, bool BindingTemporary);
+
+  /// \brief Add a new step that makes an extraneous copy of the input
+  /// to a temporary of the same class type.
+  ///
+  /// This extraneous copy only occurs during reference binding in
+  /// C++98/03, where we are permitted (but not required) to introduce
+  /// an extra copy. At a bare minimum, we must check that we could
+  /// call the copy constructor, and produce a diagnostic if the copy
+  /// constructor is inaccessible or no copy constructor matches.
+  //
+  /// \param T The type of the temporary being created.
+  void AddExtraneousCopyToTemporary(QualType T);
+
+  /// \brief Add a new step invoking a conversion function, which is either
+  /// a constructor or a conversion function.
+  void AddUserConversionStep(FunctionDecl *Function,
+                             DeclAccessPair FoundDecl,
+                             QualType T);
+  
+  /// \brief Add a new step that performs a qualification conversion to the
+  /// given type.
+  void AddQualificationConversionStep(QualType Ty, bool IsLValue);
+  
+  /// \brief Add a new step that applies an implicit conversion sequence.
+  void AddConversionSequenceStep(const ImplicitConversionSequence &ICS,
+                                 QualType T);
+
+  /// \brief Add a list-initialiation step  
+  void AddListInitializationStep(QualType T);
+
+  /// \brief Add a constructor-initialization step.
+  void AddConstructorInitializationStep(CXXConstructorDecl *Constructor,
+                                        AccessSpecifier Access,
+                                        QualType T);
+
+  /// \brief Add a zero-initialization step.
+  void AddZeroInitializationStep(QualType T);
+  
+  /// \brief Add a C assignment step.
+  //
+  // FIXME: It isn't clear whether this should ever be needed;
+  // ideally, we would handle everything needed in C in the common
+  // path. However, that isn't the case yet.
+  void AddCAssignmentStep(QualType T);
+
+  /// \brief Add a string init step.
+  void AddStringInitStep(QualType T);
+
+  /// \brief Note that this initialization sequence failed.
+  void SetFailed(FailureKind Failure) {
+    SequenceKind = FailedSequence;
+    this->Failure = Failure;
+  }
+  
+  /// \brief Note that this initialization sequence failed due to failed
+  /// overload resolution.
+  void SetOverloadFailure(FailureKind Failure, OverloadingResult Result);
+  
+  /// \brief Retrieve a reference to the candidate set when overload
+  /// resolution fails.
+  OverloadCandidateSet &getFailedCandidateSet() {
+    return FailedCandidateSet;
+  }
+
+  /// \brief Determine why initialization failed.
+  FailureKind getFailureKind() const {
+    assert(getKind() == FailedSequence && "Not an initialization failure!");
+    return Failure;
+  }
+  
+  /// \brief Dump a representation of this initialization sequence to 
+  /// the given stream, for debugging purposes.
+  void dump(llvm::raw_ostream &OS) const;
+  
+  /// \brief Dump a representation of this initialization sequence to 
+  /// standard error, for debugging purposes.
+  void dump() const;
+};
+  
+} // end namespace clang
+
+#endif // LLVM_CLANG_SEMA_INIT_H
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp
new file mode 100644
index 0000000..1b2401a
--- /dev/null
+++ b/lib/Sema/SemaLookup.cpp
@@ -0,0 +1,2831 @@
+//===--------------------- SemaLookup.cpp - Name Lookup  ------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements name lookup for C, C++, Objective-C, and
+//  Objective-C++.
+//
+//===----------------------------------------------------------------------===//
+#include "Sema.h"
+#include "Lookup.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/CXXInheritance.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/Parse/DeclSpec.h"
+#include "clang/Basic/Builtins.h"
+#include "clang/Basic/LangOptions.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/Support/ErrorHandling.h"
+#include <list>
+#include <set>
+#include <vector>
+#include <iterator>
+#include <utility>
+#include <algorithm>
+
+using namespace clang;
+
+namespace {
+  class UnqualUsingEntry {
+    const DeclContext *Nominated;
+    const DeclContext *CommonAncestor;
+
+  public:
+    UnqualUsingEntry(const DeclContext *Nominated,
+                     const DeclContext *CommonAncestor)
+      : Nominated(Nominated), CommonAncestor(CommonAncestor) {
+    }
+
+    const DeclContext *getCommonAncestor() const {
+      return CommonAncestor;
+    }
+
+    const DeclContext *getNominatedNamespace() const {
+      return Nominated;
+    }
+
+    // Sort by the pointer value of the common ancestor.
+    struct Comparator {
+      bool operator()(const UnqualUsingEntry &L, const UnqualUsingEntry &R) {
+        return L.getCommonAncestor() < R.getCommonAncestor();
+      }
+
+      bool operator()(const UnqualUsingEntry &E, const DeclContext *DC) {
+        return E.getCommonAncestor() < DC;
+      }
+
+      bool operator()(const DeclContext *DC, const UnqualUsingEntry &E) {
+        return DC < E.getCommonAncestor();
+      }
+    };
+  };
+
+  /// A collection of using directives, as used by C++ unqualified
+  /// lookup.
+  class UnqualUsingDirectiveSet {
+    typedef llvm::SmallVector<UnqualUsingEntry, 8> ListTy;
+
+    ListTy list;
+    llvm::SmallPtrSet<DeclContext*, 8> visited;
+
+  public:
+    UnqualUsingDirectiveSet() {}
+
+    void visitScopeChain(Scope *S, Scope *InnermostFileScope) {
+      // C++ [namespace.udir]p1: 
+      //   During unqualified name lookup, the names appear as if they
+      //   were declared in the nearest enclosing namespace which contains
+      //   both the using-directive and the nominated namespace.
+      DeclContext *InnermostFileDC
+        = static_cast<DeclContext*>(InnermostFileScope->getEntity());
+      assert(InnermostFileDC && InnermostFileDC->isFileContext());
+
+      for (; S; S = S->getParent()) {
+        if (DeclContext *Ctx = static_cast<DeclContext*>(S->getEntity())) {
+          DeclContext *EffectiveDC = (Ctx->isFileContext() ? Ctx : InnermostFileDC);
+          visit(Ctx, EffectiveDC);
+        } else {
+          Scope::udir_iterator I = S->using_directives_begin(),
+                             End = S->using_directives_end();
+          
+          for (; I != End; ++I)
+            visit(I->getAs<UsingDirectiveDecl>(), InnermostFileDC);
+        }
+      }
+    }
+
+    // Visits a context and collect all of its using directives
+    // recursively.  Treats all using directives as if they were
+    // declared in the context.
+    //
+    // A given context is only every visited once, so it is important
+    // that contexts be visited from the inside out in order to get
+    // the effective DCs right.
+    void visit(DeclContext *DC, DeclContext *EffectiveDC) {
+      if (!visited.insert(DC))
+        return;
+
+      addUsingDirectives(DC, EffectiveDC);
+    }
+
+    // Visits a using directive and collects all of its using
+    // directives recursively.  Treats all using directives as if they
+    // were declared in the effective DC.
+    void visit(UsingDirectiveDecl *UD, DeclContext *EffectiveDC) {
+      DeclContext *NS = UD->getNominatedNamespace();
+      if (!visited.insert(NS))
+        return;
+
+      addUsingDirective(UD, EffectiveDC);
+      addUsingDirectives(NS, EffectiveDC);
+    }
+
+    // Adds all the using directives in a context (and those nominated
+    // by its using directives, transitively) as if they appeared in
+    // the given effective context.
+    void addUsingDirectives(DeclContext *DC, DeclContext *EffectiveDC) {
+      llvm::SmallVector<DeclContext*,4> queue;
+      while (true) {
+        DeclContext::udir_iterator I, End;
+        for (llvm::tie(I, End) = DC->getUsingDirectives(); I != End; ++I) {
+          UsingDirectiveDecl *UD = *I;
+          DeclContext *NS = UD->getNominatedNamespace();
+          if (visited.insert(NS)) {
+            addUsingDirective(UD, EffectiveDC);
+            queue.push_back(NS);
+          }
+        }
+
+        if (queue.empty())
+          return;
+
+        DC = queue.back();
+        queue.pop_back();
+      }
+    }
+
+    // Add a using directive as if it had been declared in the given
+    // context.  This helps implement C++ [namespace.udir]p3:
+    //   The using-directive is transitive: if a scope contains a
+    //   using-directive that nominates a second namespace that itself
+    //   contains using-directives, the effect is as if the
+    //   using-directives from the second namespace also appeared in
+    //   the first.
+    void addUsingDirective(UsingDirectiveDecl *UD, DeclContext *EffectiveDC) {
+      // Find the common ancestor between the effective context and
+      // the nominated namespace.
+      DeclContext *Common = UD->getNominatedNamespace();
+      while (!Common->Encloses(EffectiveDC))
+        Common = Common->getParent();
+      Common = Common->getPrimaryContext();
+      
+      list.push_back(UnqualUsingEntry(UD->getNominatedNamespace(), Common));
+    }
+
+    void done() {
+      std::sort(list.begin(), list.end(), UnqualUsingEntry::Comparator());
+    }
+
+    typedef ListTy::iterator iterator;
+    typedef ListTy::const_iterator const_iterator;
+    
+    iterator begin() { return list.begin(); }
+    iterator end() { return list.end(); }
+    const_iterator begin() const { return list.begin(); }
+    const_iterator end() const { return list.end(); }
+
+    std::pair<const_iterator,const_iterator>
+    getNamespacesFor(DeclContext *DC) const {
+      return std::equal_range(begin(), end(), DC->getPrimaryContext(),
+                              UnqualUsingEntry::Comparator());
+    }
+  };
+}
+
+// Retrieve the set of identifier namespaces that correspond to a
+// specific kind of name lookup.
+static inline unsigned getIDNS(Sema::LookupNameKind NameKind,
+                               bool CPlusPlus,
+                               bool Redeclaration) {
+  unsigned IDNS = 0;
+  switch (NameKind) {
+  case Sema::LookupOrdinaryName:
+  case Sema::LookupRedeclarationWithLinkage:
+    IDNS = Decl::IDNS_Ordinary;
+    if (CPlusPlus) {
+      IDNS |= Decl::IDNS_Tag | Decl::IDNS_Member | Decl::IDNS_Namespace;
+      if (Redeclaration) IDNS |= Decl::IDNS_TagFriend | Decl::IDNS_OrdinaryFriend;
+    }
+    break;
+
+  case Sema::LookupOperatorName:
+    // Operator lookup is its own crazy thing;  it is not the same
+    // as (e.g.) looking up an operator name for redeclaration.
+    assert(!Redeclaration && "cannot do redeclaration operator lookup");
+    IDNS = Decl::IDNS_NonMemberOperator;
+    break;
+
+  case Sema::LookupTagName:
+    if (CPlusPlus) {
+      IDNS = Decl::IDNS_Type;
+
+      // When looking for a redeclaration of a tag name, we add:
+      // 1) TagFriend to find undeclared friend decls
+      // 2) Namespace because they can't "overload" with tag decls.
+      // 3) Tag because it includes class templates, which can't
+      //    "overload" with tag decls.
+      if (Redeclaration)
+        IDNS |= Decl::IDNS_Tag | Decl::IDNS_TagFriend | Decl::IDNS_Namespace;
+    } else {
+      IDNS = Decl::IDNS_Tag;
+    }
+    break;
+
+  case Sema::LookupMemberName:
+    IDNS = Decl::IDNS_Member;
+    if (CPlusPlus)
+      IDNS |= Decl::IDNS_Tag | Decl::IDNS_Ordinary;
+    break;
+
+  case Sema::LookupNestedNameSpecifierName:
+    IDNS = Decl::IDNS_Type | Decl::IDNS_Namespace;
+    break;
+
+  case Sema::LookupNamespaceName:
+    IDNS = Decl::IDNS_Namespace;
+    break;
+
+  case Sema::LookupUsingDeclName:
+    IDNS = Decl::IDNS_Ordinary | Decl::IDNS_Tag
+         | Decl::IDNS_Member | Decl::IDNS_Using;
+    break;
+
+  case Sema::LookupObjCProtocolName:
+    IDNS = Decl::IDNS_ObjCProtocol;
+    break;
+  }
+  return IDNS;
+}
+
+void LookupResult::configure() {
+  IDNS = getIDNS(LookupKind,
+                 SemaRef.getLangOptions().CPlusPlus,
+                 isForRedeclaration());
+
+  // If we're looking for one of the allocation or deallocation
+  // operators, make sure that the implicitly-declared new and delete
+  // operators can be found.
+  if (!isForRedeclaration()) {
+    switch (Name.getCXXOverloadedOperator()) {
+    case OO_New:
+    case OO_Delete:
+    case OO_Array_New:
+    case OO_Array_Delete:
+      SemaRef.DeclareGlobalNewDelete();
+      break;
+
+    default:
+      break;
+    }
+  }
+}
+
+// Necessary because CXXBasePaths is not complete in Sema.h
+void LookupResult::deletePaths(CXXBasePaths *Paths) {
+  delete Paths;
+}
+
+/// Resolves the result kind of this lookup.
+void LookupResult::resolveKind() {
+  unsigned N = Decls.size();
+ 
+  // Fast case: no possible ambiguity.
+  if (N == 0) {
+    assert(ResultKind == NotFound || ResultKind == NotFoundInCurrentInstantiation);
+    return;
+  }
+
+  // If there's a single decl, we need to examine it to decide what
+  // kind of lookup this is.
+  if (N == 1) {
+    NamedDecl *D = (*Decls.begin())->getUnderlyingDecl();
+    if (isa<FunctionTemplateDecl>(D))
+      ResultKind = FoundOverloaded;
+    else if (isa<UnresolvedUsingValueDecl>(D))
+      ResultKind = FoundUnresolvedValue;
+    return;
+  }
+
+  // Don't do any extra resolution if we've already resolved as ambiguous.
+  if (ResultKind == Ambiguous) return;
+
+  llvm::SmallPtrSet<NamedDecl*, 16> Unique;
+
+  bool Ambiguous = false;
+  bool HasTag = false, HasFunction = false, HasNonFunction = false;
+  bool HasFunctionTemplate = false, HasUnresolved = false;
+
+  unsigned UniqueTagIndex = 0;
+  
+  unsigned I = 0;
+  while (I < N) {
+    NamedDecl *D = Decls[I]->getUnderlyingDecl();
+    D = cast<NamedDecl>(D->getCanonicalDecl());
+
+    if (!Unique.insert(D)) {
+      // If it's not unique, pull something off the back (and
+      // continue at this index).
+      Decls[I] = Decls[--N];
+    } else {
+      // Otherwise, do some decl type analysis and then continue.
+
+      if (isa<UnresolvedUsingValueDecl>(D)) {
+        HasUnresolved = true;
+      } else if (isa<TagDecl>(D)) {
+        if (HasTag)
+          Ambiguous = true;
+        UniqueTagIndex = I;
+        HasTag = true;
+      } else if (isa<FunctionTemplateDecl>(D)) {
+        HasFunction = true;
+        HasFunctionTemplate = true;
+      } else if (isa<FunctionDecl>(D)) {
+        HasFunction = true;
+      } else {
+        if (HasNonFunction)
+          Ambiguous = true;
+        HasNonFunction = true;
+      }
+      I++;
+    }
+  }
+
+  // C++ [basic.scope.hiding]p2:
+  //   A class name or enumeration name can be hidden by the name of
+  //   an object, function, or enumerator declared in the same
+  //   scope. If a class or enumeration name and an object, function,
+  //   or enumerator are declared in the same scope (in any order)
+  //   with the same name, the class or enumeration name is hidden
+  //   wherever the object, function, or enumerator name is visible.
+  // But it's still an error if there are distinct tag types found,
+  // even if they're not visible. (ref?)
+  if (HideTags && HasTag && !Ambiguous &&
+      (HasFunction || HasNonFunction || HasUnresolved))
+    Decls[UniqueTagIndex] = Decls[--N];
+
+  Decls.set_size(N);
+
+  if (HasNonFunction && (HasFunction || HasUnresolved))
+    Ambiguous = true;
+
+  if (Ambiguous)
+    setAmbiguous(LookupResult::AmbiguousReference);
+  else if (HasUnresolved)
+    ResultKind = LookupResult::FoundUnresolvedValue;
+  else if (N > 1 || HasFunctionTemplate)
+    ResultKind = LookupResult::FoundOverloaded;
+  else
+    ResultKind = LookupResult::Found;
+}
+
+void LookupResult::addDeclsFromBasePaths(const CXXBasePaths &P) {
+  CXXBasePaths::const_paths_iterator I, E;
+  DeclContext::lookup_iterator DI, DE;
+  for (I = P.begin(), E = P.end(); I != E; ++I)
+    for (llvm::tie(DI,DE) = I->Decls; DI != DE; ++DI)
+      addDecl(*DI);
+}
+
+void LookupResult::setAmbiguousBaseSubobjects(CXXBasePaths &P) {
+  Paths = new CXXBasePaths;
+  Paths->swap(P);
+  addDeclsFromBasePaths(*Paths);
+  resolveKind();
+  setAmbiguous(AmbiguousBaseSubobjects);
+}
+
+void LookupResult::setAmbiguousBaseSubobjectTypes(CXXBasePaths &P) {
+  Paths = new CXXBasePaths;
+  Paths->swap(P);
+  addDeclsFromBasePaths(*Paths);
+  resolveKind();
+  setAmbiguous(AmbiguousBaseSubobjectTypes);
+}
+
+void LookupResult::print(llvm::raw_ostream &Out) {
+  Out << Decls.size() << " result(s)";
+  if (isAmbiguous()) Out << ", ambiguous";
+  if (Paths) Out << ", base paths present";
+  
+  for (iterator I = begin(), E = end(); I != E; ++I) {
+    Out << "\n";
+    (*I)->print(Out, 2);
+  }
+}
+
+/// \brief Lookup a builtin function, when name lookup would otherwise
+/// fail.
+static bool LookupBuiltin(Sema &S, LookupResult &R) {
+  Sema::LookupNameKind NameKind = R.getLookupKind();
+
+  // If we didn't find a use of this identifier, and if the identifier
+  // corresponds to a compiler builtin, create the decl object for the builtin
+  // now, injecting it into translation unit scope, and return it.
+  if (NameKind == Sema::LookupOrdinaryName ||
+      NameKind == Sema::LookupRedeclarationWithLinkage) {
+    IdentifierInfo *II = R.getLookupName().getAsIdentifierInfo();
+    if (II) {
+      // If this is a builtin on this (or all) targets, create the decl.
+      if (unsigned BuiltinID = II->getBuiltinID()) {
+        // In C++, we don't have any predefined library functions like
+        // 'malloc'. Instead, we'll just error.
+        if (S.getLangOptions().CPlusPlus &&
+            S.Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID))
+          return false;
+
+        NamedDecl *D = S.LazilyCreateBuiltin((IdentifierInfo *)II, BuiltinID,
+                                             S.TUScope, R.isForRedeclaration(),
+                                             R.getNameLoc());
+        if (D) 
+          R.addDecl(D);
+        return (D != NULL);
+      }
+    }
+  }
+
+  return false;
+}
+
+// Adds all qualifying matches for a name within a decl context to the
+// given lookup result.  Returns true if any matches were found.
+static bool LookupDirect(Sema &S, LookupResult &R, const DeclContext *DC) {
+  bool Found = false;
+
+  DeclContext::lookup_const_iterator I, E;
+  for (llvm::tie(I, E) = DC->lookup(R.getLookupName()); I != E; ++I) {
+    NamedDecl *D = *I;
+    if (R.isAcceptableDecl(D)) {
+      R.addDecl(D);
+      Found = true;
+    }
+  }
+
+  if (!Found && DC->isTranslationUnit() && LookupBuiltin(S, R))
+    return true;
+
+  if (R.getLookupName().getNameKind()
+        != DeclarationName::CXXConversionFunctionName ||
+      R.getLookupName().getCXXNameType()->isDependentType() ||
+      !isa<CXXRecordDecl>(DC))
+    return Found;
+
+  // C++ [temp.mem]p6:
+  //   A specialization of a conversion function template is not found by 
+  //   name lookup. Instead, any conversion function templates visible in the
+  //   context of the use are considered. [...]
+  const CXXRecordDecl *Record = cast<CXXRecordDecl>(DC);
+  if (!Record->isDefinition())
+    return Found;
+
+  const UnresolvedSetImpl *Unresolved = Record->getConversionFunctions();
+  for (UnresolvedSetImpl::iterator U = Unresolved->begin(), 
+         UEnd = Unresolved->end(); U != UEnd; ++U) {
+    FunctionTemplateDecl *ConvTemplate = dyn_cast<FunctionTemplateDecl>(*U);
+    if (!ConvTemplate)
+      continue;
+    
+    // When we're performing lookup for the purposes of redeclaration, just
+    // add the conversion function template. When we deduce template 
+    // arguments for specializations, we'll end up unifying the return 
+    // type of the new declaration with the type of the function template.
+    if (R.isForRedeclaration()) {
+      R.addDecl(ConvTemplate);
+      Found = true;
+      continue;
+    }
+    
+    // C++ [temp.mem]p6:
+    //   [...] For each such operator, if argument deduction succeeds 
+    //   (14.9.2.3), the resulting specialization is used as if found by 
+    //   name lookup.
+    //
+    // When referencing a conversion function for any purpose other than
+    // a redeclaration (such that we'll be building an expression with the
+    // result), perform template argument deduction and place the 
+    // specialization into the result set. We do this to avoid forcing all
+    // callers to perform special deduction for conversion functions.
+    Sema::TemplateDeductionInfo Info(R.getSema().Context, R.getNameLoc());
+    FunctionDecl *Specialization = 0;
+    
+    const FunctionProtoType *ConvProto        
+      = ConvTemplate->getTemplatedDecl()->getType()->getAs<FunctionProtoType>();
+    assert(ConvProto && "Nonsensical conversion function template type");
+
+    // Compute the type of the function that we would expect the conversion
+    // function to have, if it were to match the name given.
+    // FIXME: Calling convention!
+    FunctionType::ExtInfo ConvProtoInfo = ConvProto->getExtInfo();
+    QualType ExpectedType
+      = R.getSema().Context.getFunctionType(R.getLookupName().getCXXNameType(),
+                                            0, 0, ConvProto->isVariadic(),
+                                            ConvProto->getTypeQuals(),
+                                            false, false, 0, 0,
+                                    ConvProtoInfo.withCallingConv(CC_Default));
+ 
+    // Perform template argument deduction against the type that we would
+    // expect the function to have.
+    if (R.getSema().DeduceTemplateArguments(ConvTemplate, 0, ExpectedType,
+                                            Specialization, Info)
+          == Sema::TDK_Success) {
+      R.addDecl(Specialization);
+      Found = true;
+    }
+  }
+
+  return Found;
+}
+
+// Performs C++ unqualified lookup into the given file context.
+static bool
+CppNamespaceLookup(Sema &S, LookupResult &R, ASTContext &Context, 
+                   DeclContext *NS, UnqualUsingDirectiveSet &UDirs) {
+
+  assert(NS && NS->isFileContext() && "CppNamespaceLookup() requires namespace!");
+
+  // Perform direct name lookup into the LookupCtx.
+  bool Found = LookupDirect(S, R, NS);
+
+  // Perform direct name lookup into the namespaces nominated by the
+  // using directives whose common ancestor is this namespace.
+  UnqualUsingDirectiveSet::const_iterator UI, UEnd;
+  llvm::tie(UI, UEnd) = UDirs.getNamespacesFor(NS);
+
+  for (; UI != UEnd; ++UI)
+    if (LookupDirect(S, R, UI->getNominatedNamespace()))
+      Found = true;
+
+  R.resolveKind();
+
+  return Found;
+}
+
+static bool isNamespaceOrTranslationUnitScope(Scope *S) {
+  if (DeclContext *Ctx = static_cast<DeclContext*>(S->getEntity()))
+    return Ctx->isFileContext();
+  return false;
+}
+
+// Find the next outer declaration context from this scope. This
+// routine actually returns the semantic outer context, which may
+// differ from the lexical context (encoded directly in the Scope
+// stack) when we are parsing a member of a class template. In this
+// case, the second element of the pair will be true, to indicate that
+// name lookup should continue searching in this semantic context when
+// it leaves the current template parameter scope.
+static std::pair<DeclContext *, bool> findOuterContext(Scope *S) {
+  DeclContext *DC = static_cast<DeclContext *>(S->getEntity());
+  DeclContext *Lexical = 0;
+  for (Scope *OuterS = S->getParent(); OuterS; 
+       OuterS = OuterS->getParent()) {
+    if (OuterS->getEntity()) {
+      Lexical = static_cast<DeclContext *>(OuterS->getEntity());
+      break;
+    }
+  }
+
+  // C++ [temp.local]p8:
+  //   In the definition of a member of a class template that appears
+  //   outside of the namespace containing the class template
+  //   definition, the name of a template-parameter hides the name of
+  //   a member of this namespace.
+  //
+  // Example:
+  //
+  //   namespace N { 
+  //     class C { }; 
+  //
+  //     template<class T> class B {
+  //       void f(T);
+  //     }; 
+  //   }
+  //
+  //   template<class C> void N::B<C>::f(C) {
+  //     C b;  // C is the template parameter, not N::C
+  //   }
+  //
+  // In this example, the lexical context we return is the
+  // TranslationUnit, while the semantic context is the namespace N.
+  if (!Lexical || !DC || !S->getParent() || 
+      !S->getParent()->isTemplateParamScope())
+    return std::make_pair(Lexical, false);
+
+  // Find the outermost template parameter scope. 
+  // For the example, this is the scope for the template parameters of
+  // template<class C>.
+  Scope *OutermostTemplateScope = S->getParent();
+  while (OutermostTemplateScope->getParent() &&
+         OutermostTemplateScope->getParent()->isTemplateParamScope())
+    OutermostTemplateScope = OutermostTemplateScope->getParent();
+  
+  // Find the namespace context in which the original scope occurs. In
+  // the example, this is namespace N.
+  DeclContext *Semantic = DC;
+  while (!Semantic->isFileContext())
+    Semantic = Semantic->getParent();
+  
+  // Find the declaration context just outside of the template
+  // parameter scope. This is the context in which the template is
+  // being lexically declaration (a namespace context). In the
+  // example, this is the global scope.
+  if (Lexical->isFileContext() && !Lexical->Equals(Semantic) &&
+      Lexical->Encloses(Semantic))
+    return std::make_pair(Semantic, true);
+
+  return std::make_pair(Lexical, false);
+}
+
+bool Sema::CppLookupName(LookupResult &R, Scope *S) {
+  assert(getLangOptions().CPlusPlus && "Can perform only C++ lookup");
+
+  DeclarationName Name = R.getLookupName();
+
+  Scope *Initial = S;
+  IdentifierResolver::iterator
+    I = IdResolver.begin(Name),
+    IEnd = IdResolver.end();
+
+  // First we lookup local scope.
+  // We don't consider using-directives, as per 7.3.4.p1 [namespace.udir]
+  // ...During unqualified name lookup (3.4.1), the names appear as if
+  // they were declared in the nearest enclosing namespace which contains
+  // both the using-directive and the nominated namespace.
+  // [Note: in this context, "contains" means "contains directly or
+  // indirectly".
+  //
+  // For example:
+  // namespace A { int i; }
+  // void foo() {
+  //   int i;
+  //   {
+  //     using namespace A;
+  //     ++i; // finds local 'i', A::i appears at global scope
+  //   }
+  // }
+  //
+  DeclContext *OutsideOfTemplateParamDC = 0;
+  for (; S && !isNamespaceOrTranslationUnitScope(S); S = S->getParent()) {
+    // Check whether the IdResolver has anything in this scope.
+    bool Found = false;
+    for (; I != IEnd && S->isDeclScope(DeclPtrTy::make(*I)); ++I) {
+      if (R.isAcceptableDecl(*I)) {
+        Found = true;
+        R.addDecl(*I);
+      }
+    }
+    if (Found) {
+      R.resolveKind();
+      return true;
+    }
+
+    DeclContext *Ctx = static_cast<DeclContext*>(S->getEntity());
+    if (!Ctx && S->isTemplateParamScope() && OutsideOfTemplateParamDC &&
+        S->getParent() && !S->getParent()->isTemplateParamScope()) {
+      // We've just searched the last template parameter scope and
+      // found nothing, so look into the the contexts between the
+      // lexical and semantic declaration contexts returned by
+      // findOuterContext(). This implements the name lookup behavior
+      // of C++ [temp.local]p8.
+      Ctx = OutsideOfTemplateParamDC;
+      OutsideOfTemplateParamDC = 0;
+    }
+
+    if (Ctx) {
+      DeclContext *OuterCtx;
+      bool SearchAfterTemplateScope;
+      llvm::tie(OuterCtx, SearchAfterTemplateScope) = findOuterContext(S);
+      if (SearchAfterTemplateScope)
+        OutsideOfTemplateParamDC = OuterCtx;
+
+      for (; Ctx && !Ctx->Equals(OuterCtx); Ctx = Ctx->getLookupParent()) {
+        // We do not directly look into transparent contexts, since
+        // those entities will be found in the nearest enclosing
+        // non-transparent context.
+        if (Ctx->isTransparentContext())
+          continue;
+
+        // We do not look directly into function or method contexts,
+        // since all of the local variables and parameters of the
+        // function/method are present within the Scope.
+        if (Ctx->isFunctionOrMethod()) {
+          // If we have an Objective-C instance method, look for ivars
+          // in the corresponding interface.
+          if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(Ctx)) {
+            if (Method->isInstanceMethod() && Name.getAsIdentifierInfo())
+              if (ObjCInterfaceDecl *Class = Method->getClassInterface()) {
+                ObjCInterfaceDecl *ClassDeclared;
+                if (ObjCIvarDecl *Ivar = Class->lookupInstanceVariable(
+                                                 Name.getAsIdentifierInfo(), 
+                                                             ClassDeclared)) {
+                  if (R.isAcceptableDecl(Ivar)) {
+                    R.addDecl(Ivar);
+                    R.resolveKind();
+                    return true;
+                  }
+                }
+              }
+          }
+
+          continue;
+        }
+
+        // Perform qualified name lookup into this context.
+        // FIXME: In some cases, we know that every name that could be found by
+        // this qualified name lookup will also be on the identifier chain. For
+        // example, inside a class without any base classes, we never need to
+        // perform qualified lookup because all of the members are on top of the
+        // identifier chain.
+        if (LookupQualifiedName(R, Ctx, /*InUnqualifiedLookup=*/true))
+          return true;
+      }
+    }
+  }
+
+  // Stop if we ran out of scopes.
+  // FIXME:  This really, really shouldn't be happening.
+  if (!S) return false;
+
+  // Collect UsingDirectiveDecls in all scopes, and recursively all
+  // nominated namespaces by those using-directives.
+  //
+  // FIXME: Cache this sorted list in Scope structure, and DeclContext, so we
+  // don't build it for each lookup!
+
+  UnqualUsingDirectiveSet UDirs;
+  UDirs.visitScopeChain(Initial, S);
+  UDirs.done();
+
+  // Lookup namespace scope, and global scope.
+  // Unqualified name lookup in C++ requires looking into scopes
+  // that aren't strictly lexical, and therefore we walk through the
+  // context as well as walking through the scopes.
+
+  for (; S; S = S->getParent()) {
+    DeclContext *Ctx = static_cast<DeclContext *>(S->getEntity());
+    if (Ctx && Ctx->isTransparentContext())
+      continue;
+
+    // Check whether the IdResolver has anything in this scope.
+    bool Found = false;
+    for (; I != IEnd && S->isDeclScope(DeclPtrTy::make(*I)); ++I) {
+      if (R.isAcceptableDecl(*I)) {
+        // We found something.  Look for anything else in our scope
+        // with this same name and in an acceptable identifier
+        // namespace, so that we can construct an overload set if we
+        // need to.
+        Found = true;
+        R.addDecl(*I);
+      }
+    }
+
+    // If we have a context, and it's not a context stashed in the
+    // template parameter scope for an out-of-line definition, also
+    // look into that context.
+    if (Ctx && !(Found && S && S->isTemplateParamScope())) {
+      assert(Ctx->isFileContext() &&
+             "We should have been looking only at file context here already.");
+
+      // Look into context considering using-directives.
+      if (CppNamespaceLookup(*this, R, Context, Ctx, UDirs))
+        Found = true;
+    }
+
+    if (Found) {
+      R.resolveKind();
+      return true;
+    }
+
+    if (R.isForRedeclaration() && Ctx && !Ctx->isTransparentContext())
+      return false;
+  }
+
+  return !R.empty();
+}
+
+/// @brief Perform unqualified name lookup starting from a given
+/// scope.
+///
+/// Unqualified name lookup (C++ [basic.lookup.unqual], C99 6.2.1) is
+/// used to find names within the current scope. For example, 'x' in
+/// @code
+/// int x;
+/// int f() {
+///   return x; // unqualified name look finds 'x' in the global scope
+/// }
+/// @endcode
+///
+/// Different lookup criteria can find different names. For example, a
+/// particular scope can have both a struct and a function of the same
+/// name, and each can be found by certain lookup criteria. For more
+/// information about lookup criteria, see the documentation for the
+/// class LookupCriteria.
+///
+/// @param S        The scope from which unqualified name lookup will
+/// begin. If the lookup criteria permits, name lookup may also search
+/// in the parent scopes.
+///
+/// @param Name     The name of the entity that we are searching for.
+///
+/// @param Loc      If provided, the source location where we're performing
+/// name lookup. At present, this is only used to produce diagnostics when
+/// C library functions (like "malloc") are implicitly declared.
+///
+/// @returns The result of name lookup, which includes zero or more
+/// declarations and possibly additional information used to diagnose
+/// ambiguities.
+bool Sema::LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation) {
+  DeclarationName Name = R.getLookupName();
+  if (!Name) return false;
+
+  LookupNameKind NameKind = R.getLookupKind();
+
+  if (!getLangOptions().CPlusPlus) {
+    // Unqualified name lookup in C/Objective-C is purely lexical, so
+    // search in the declarations attached to the name.
+
+    if (NameKind == Sema::LookupRedeclarationWithLinkage) {
+      // Find the nearest non-transparent declaration scope.
+      while (!(S->getFlags() & Scope::DeclScope) ||
+             (S->getEntity() &&
+              static_cast<DeclContext *>(S->getEntity())
+                ->isTransparentContext()))
+        S = S->getParent();
+    }
+
+    unsigned IDNS = R.getIdentifierNamespace();
+
+    // Scan up the scope chain looking for a decl that matches this
+    // identifier that is in the appropriate namespace.  This search
+    // should not take long, as shadowing of names is uncommon, and
+    // deep shadowing is extremely uncommon.
+    bool LeftStartingScope = false;
+
+    for (IdentifierResolver::iterator I = IdResolver.begin(Name),
+                                   IEnd = IdResolver.end();
+         I != IEnd; ++I)
+      if ((*I)->isInIdentifierNamespace(IDNS)) {
+        if (NameKind == LookupRedeclarationWithLinkage) {
+          // Determine whether this (or a previous) declaration is
+          // out-of-scope.
+          if (!LeftStartingScope && !S->isDeclScope(DeclPtrTy::make(*I)))
+            LeftStartingScope = true;
+
+          // If we found something outside of our starting scope that
+          // does not have linkage, skip it.
+          if (LeftStartingScope && !((*I)->hasLinkage()))
+            continue;
+        }
+
+        R.addDecl(*I);
+
+        if ((*I)->getAttr<OverloadableAttr>()) {
+          // If this declaration has the "overloadable" attribute, we
+          // might have a set of overloaded functions.
+
+          // Figure out what scope the identifier is in.
+          while (!(S->getFlags() & Scope::DeclScope) ||
+                 !S->isDeclScope(DeclPtrTy::make(*I)))
+            S = S->getParent();
+
+          // Find the last declaration in this scope (with the same
+          // name, naturally).
+          IdentifierResolver::iterator LastI = I;
+          for (++LastI; LastI != IEnd; ++LastI) {
+            if (!S->isDeclScope(DeclPtrTy::make(*LastI)))
+              break;
+            R.addDecl(*LastI);
+          }
+        }
+
+        R.resolveKind();
+
+        return true;
+      }
+  } else {
+    // Perform C++ unqualified name lookup.
+    if (CppLookupName(R, S))
+      return true;
+  }
+
+  // If we didn't find a use of this identifier, and if the identifier
+  // corresponds to a compiler builtin, create the decl object for the builtin
+  // now, injecting it into translation unit scope, and return it.
+  if (AllowBuiltinCreation)
+    return LookupBuiltin(*this, R);
+
+  return false;
+}
+
+/// @brief Perform qualified name lookup in the namespaces nominated by
+/// using directives by the given context.
+///
+/// C++98 [namespace.qual]p2:
+///   Given X::m (where X is a user-declared namespace), or given ::m
+///   (where X is the global namespace), let S be the set of all
+///   declarations of m in X and in the transitive closure of all
+///   namespaces nominated by using-directives in X and its used
+///   namespaces, except that using-directives are ignored in any
+///   namespace, including X, directly containing one or more
+///   declarations of m. No namespace is searched more than once in
+///   the lookup of a name. If S is the empty set, the program is
+///   ill-formed. Otherwise, if S has exactly one member, or if the
+///   context of the reference is a using-declaration
+///   (namespace.udecl), S is the required set of declarations of
+///   m. Otherwise if the use of m is not one that allows a unique
+///   declaration to be chosen from S, the program is ill-formed.
+/// C++98 [namespace.qual]p5:
+///   During the lookup of a qualified namespace member name, if the
+///   lookup finds more than one declaration of the member, and if one
+///   declaration introduces a class name or enumeration name and the
+///   other declarations either introduce the same object, the same
+///   enumerator or a set of functions, the non-type name hides the
+///   class or enumeration name if and only if the declarations are
+///   from the same namespace; otherwise (the declarations are from
+///   different namespaces), the program is ill-formed.
+static bool LookupQualifiedNameInUsingDirectives(Sema &S, LookupResult &R,
+                                                 DeclContext *StartDC) {
+  assert(StartDC->isFileContext() && "start context is not a file context");
+
+  DeclContext::udir_iterator I = StartDC->using_directives_begin();
+  DeclContext::udir_iterator E = StartDC->using_directives_end();
+
+  if (I == E) return false;
+
+  // We have at least added all these contexts to the queue.
+  llvm::DenseSet<DeclContext*> Visited;
+  Visited.insert(StartDC);
+
+  // We have not yet looked into these namespaces, much less added
+  // their "using-children" to the queue.
+  llvm::SmallVector<NamespaceDecl*, 8> Queue;
+
+  // We have already looked into the initial namespace; seed the queue
+  // with its using-children.
+  for (; I != E; ++I) {
+    NamespaceDecl *ND = (*I)->getNominatedNamespace()->getOriginalNamespace();
+    if (Visited.insert(ND).second)
+      Queue.push_back(ND);
+  }
+
+  // The easiest way to implement the restriction in [namespace.qual]p5
+  // is to check whether any of the individual results found a tag
+  // and, if so, to declare an ambiguity if the final result is not
+  // a tag.
+  bool FoundTag = false;
+  bool FoundNonTag = false;
+
+  LookupResult LocalR(LookupResult::Temporary, R);
+
+  bool Found = false;
+  while (!Queue.empty()) {
+    NamespaceDecl *ND = Queue.back();
+    Queue.pop_back();
+
+    // We go through some convolutions here to avoid copying results
+    // between LookupResults.
+    bool UseLocal = !R.empty();
+    LookupResult &DirectR = UseLocal ? LocalR : R;
+    bool FoundDirect = LookupDirect(S, DirectR, ND);
+
+    if (FoundDirect) {
+      // First do any local hiding.
+      DirectR.resolveKind();
+
+      // If the local result is a tag, remember that.
+      if (DirectR.isSingleTagDecl())
+        FoundTag = true;
+      else
+        FoundNonTag = true;
+
+      // Append the local results to the total results if necessary.
+      if (UseLocal) {
+        R.addAllDecls(LocalR);
+        LocalR.clear();
+      }
+    }
+
+    // If we find names in this namespace, ignore its using directives.
+    if (FoundDirect) {
+      Found = true;
+      continue;
+    }
+
+    for (llvm::tie(I,E) = ND->getUsingDirectives(); I != E; ++I) {
+      NamespaceDecl *Nom = (*I)->getNominatedNamespace();
+      if (Visited.insert(Nom).second)
+        Queue.push_back(Nom);
+    }
+  }
+
+  if (Found) {
+    if (FoundTag && FoundNonTag)
+      R.setAmbiguousQualifiedTagHiding();
+    else
+      R.resolveKind();
+  }
+
+  return Found;
+}
+
+/// \brief Perform qualified name lookup into a given context.
+///
+/// Qualified name lookup (C++ [basic.lookup.qual]) is used to find
+/// names when the context of those names is explicit specified, e.g.,
+/// "std::vector" or "x->member", or as part of unqualified name lookup.
+///
+/// Different lookup criteria can find different names. For example, a
+/// particular scope can have both a struct and a function of the same
+/// name, and each can be found by certain lookup criteria. For more
+/// information about lookup criteria, see the documentation for the
+/// class LookupCriteria.
+///
+/// \param R captures both the lookup criteria and any lookup results found.
+///
+/// \param LookupCtx The context in which qualified name lookup will
+/// search. If the lookup criteria permits, name lookup may also search
+/// in the parent contexts or (for C++ classes) base classes.
+///
+/// \param InUnqualifiedLookup true if this is qualified name lookup that 
+/// occurs as part of unqualified name lookup.
+///
+/// \returns true if lookup succeeded, false if it failed.
+bool Sema::LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx,
+                               bool InUnqualifiedLookup) {
+  assert(LookupCtx && "Sema::LookupQualifiedName requires a lookup context");
+
+  if (!R.getLookupName())
+    return false;
+
+  // Make sure that the declaration context is complete.
+  assert((!isa<TagDecl>(LookupCtx) ||
+          LookupCtx->isDependentContext() ||
+          cast<TagDecl>(LookupCtx)->isDefinition() ||
+          Context.getTypeDeclType(cast<TagDecl>(LookupCtx))->getAs<TagType>()
+            ->isBeingDefined()) &&
+         "Declaration context must already be complete!");
+
+  // Perform qualified name lookup into the LookupCtx.
+  if (LookupDirect(*this, R, LookupCtx)) {
+    R.resolveKind();
+    if (isa<CXXRecordDecl>(LookupCtx))
+      R.setNamingClass(cast<CXXRecordDecl>(LookupCtx));
+    return true;
+  }
+
+  // Don't descend into implied contexts for redeclarations.
+  // C++98 [namespace.qual]p6:
+  //   In a declaration for a namespace member in which the
+  //   declarator-id is a qualified-id, given that the qualified-id
+  //   for the namespace member has the form
+  //     nested-name-specifier unqualified-id
+  //   the unqualified-id shall name a member of the namespace
+  //   designated by the nested-name-specifier.
+  // See also [class.mfct]p5 and [class.static.data]p2.
+  if (R.isForRedeclaration())
+    return false;
+
+  // If this is a namespace, look it up in the implied namespaces.
+  if (LookupCtx->isFileContext())
+    return LookupQualifiedNameInUsingDirectives(*this, R, LookupCtx);
+
+  // If this isn't a C++ class, we aren't allowed to look into base
+  // classes, we're done.
+  CXXRecordDecl *LookupRec = dyn_cast<CXXRecordDecl>(LookupCtx);
+  if (!LookupRec)
+    return false;
+
+  // If we're performing qualified name lookup into a dependent class,
+  // then we are actually looking into a current instantiation. If we have any
+  // dependent base classes, then we either have to delay lookup until 
+  // template instantiation time (at which point all bases will be available)
+  // or we have to fail.
+  if (!InUnqualifiedLookup && LookupRec->isDependentContext() &&
+      LookupRec->hasAnyDependentBases()) {
+    R.setNotFoundInCurrentInstantiation();
+    return false;
+  }
+    
+  // Perform lookup into our base classes.
+  CXXBasePaths Paths;
+  Paths.setOrigin(LookupRec);
+
+  // Look for this member in our base classes
+  CXXRecordDecl::BaseMatchesCallback *BaseCallback = 0;
+  switch (R.getLookupKind()) {
+    case LookupOrdinaryName:
+    case LookupMemberName:
+    case LookupRedeclarationWithLinkage:
+      BaseCallback = &CXXRecordDecl::FindOrdinaryMember;
+      break;
+      
+    case LookupTagName:
+      BaseCallback = &CXXRecordDecl::FindTagMember;
+      break;
+
+    case LookupUsingDeclName:
+      // This lookup is for redeclarations only.
+      
+    case LookupOperatorName:
+    case LookupNamespaceName:
+    case LookupObjCProtocolName:
+      // These lookups will never find a member in a C++ class (or base class).
+      return false;
+      
+    case LookupNestedNameSpecifierName:
+      BaseCallback = &CXXRecordDecl::FindNestedNameSpecifierMember;
+      break;
+  }
+  
+  if (!LookupRec->lookupInBases(BaseCallback,
+                                R.getLookupName().getAsOpaquePtr(), Paths))
+    return false;
+
+  R.setNamingClass(LookupRec);
+
+  // C++ [class.member.lookup]p2:
+  //   [...] If the resulting set of declarations are not all from
+  //   sub-objects of the same type, or the set has a nonstatic member
+  //   and includes members from distinct sub-objects, there is an
+  //   ambiguity and the program is ill-formed. Otherwise that set is
+  //   the result of the lookup.
+  // FIXME: support using declarations!
+  QualType SubobjectType;
+  int SubobjectNumber = 0;
+  AccessSpecifier SubobjectAccess = AS_none;
+  for (CXXBasePaths::paths_iterator Path = Paths.begin(), PathEnd = Paths.end();
+       Path != PathEnd; ++Path) {
+    const CXXBasePathElement &PathElement = Path->back();
+
+    // Pick the best (i.e. most permissive i.e. numerically lowest) access
+    // across all paths.
+    SubobjectAccess = std::min(SubobjectAccess, Path->Access);
+    
+    // Determine whether we're looking at a distinct sub-object or not.
+    if (SubobjectType.isNull()) {
+      // This is the first subobject we've looked at. Record its type.
+      SubobjectType = Context.getCanonicalType(PathElement.Base->getType());
+      SubobjectNumber = PathElement.SubobjectNumber;
+    } else if (SubobjectType
+                 != Context.getCanonicalType(PathElement.Base->getType())) {
+      // We found members of the given name in two subobjects of
+      // different types. This lookup is ambiguous.
+      R.setAmbiguousBaseSubobjectTypes(Paths);
+      return true;
+    } else if (SubobjectNumber != PathElement.SubobjectNumber) {
+      // We have a different subobject of the same type.
+
+      // C++ [class.member.lookup]p5:
+      //   A static member, a nested type or an enumerator defined in
+      //   a base class T can unambiguously be found even if an object
+      //   has more than one base class subobject of type T.
+      Decl *FirstDecl = *Path->Decls.first;
+      if (isa<VarDecl>(FirstDecl) ||
+          isa<TypeDecl>(FirstDecl) ||
+          isa<EnumConstantDecl>(FirstDecl))
+        continue;
+
+      if (isa<CXXMethodDecl>(FirstDecl)) {
+        // Determine whether all of the methods are static.
+        bool AllMethodsAreStatic = true;
+        for (DeclContext::lookup_iterator Func = Path->Decls.first;
+             Func != Path->Decls.second; ++Func) {
+          if (!isa<CXXMethodDecl>(*Func)) {
+            assert(isa<TagDecl>(*Func) && "Non-function must be a tag decl");
+            break;
+          }
+
+          if (!cast<CXXMethodDecl>(*Func)->isStatic()) {
+            AllMethodsAreStatic = false;
+            break;
+          }
+        }
+
+        if (AllMethodsAreStatic)
+          continue;
+      }
+
+      // We have found a nonstatic member name in multiple, distinct
+      // subobjects. Name lookup is ambiguous.
+      R.setAmbiguousBaseSubobjects(Paths);
+      return true;
+    }
+  }
+
+  // Lookup in a base class succeeded; return these results.
+
+  DeclContext::lookup_iterator I, E;
+  for (llvm::tie(I,E) = Paths.front().Decls; I != E; ++I) {
+    NamedDecl *D = *I;
+    AccessSpecifier AS = CXXRecordDecl::MergeAccess(SubobjectAccess,
+                                                    D->getAccess());
+    R.addDecl(D, AS);
+  }
+  R.resolveKind();
+  return true;
+}
+
+/// @brief Performs name lookup for a name that was parsed in the
+/// source code, and may contain a C++ scope specifier.
+///
+/// This routine is a convenience routine meant to be called from
+/// contexts that receive a name and an optional C++ scope specifier
+/// (e.g., "N::M::x"). It will then perform either qualified or
+/// unqualified name lookup (with LookupQualifiedName or LookupName,
+/// respectively) on the given name and return those results.
+///
+/// @param S        The scope from which unqualified name lookup will
+/// begin.
+///
+/// @param SS       An optional C++ scope-specifier, e.g., "::N::M".
+///
+/// @param Name     The name of the entity that name lookup will
+/// search for.
+///
+/// @param Loc      If provided, the source location where we're performing
+/// name lookup. At present, this is only used to produce diagnostics when
+/// C library functions (like "malloc") are implicitly declared.
+///
+/// @param EnteringContext Indicates whether we are going to enter the
+/// context of the scope-specifier SS (if present).
+///
+/// @returns True if any decls were found (but possibly ambiguous)
+bool Sema::LookupParsedName(LookupResult &R, Scope *S, CXXScopeSpec *SS,
+                            bool AllowBuiltinCreation, bool EnteringContext) {
+  if (SS && SS->isInvalid()) {
+    // When the scope specifier is invalid, don't even look for
+    // anything.
+    return false;
+  }
+
+  if (SS && SS->isSet()) {
+    if (DeclContext *DC = computeDeclContext(*SS, EnteringContext)) {
+      // We have resolved the scope specifier to a particular declaration
+      // contex, and will perform name lookup in that context.
+      if (!DC->isDependentContext() && RequireCompleteDeclContext(*SS))
+        return false;
+
+      R.setContextRange(SS->getRange());
+
+      return LookupQualifiedName(R, DC);
+    }
+
+    // We could not resolve the scope specified to a specific declaration
+    // context, which means that SS refers to an unknown specialization.
+    // Name lookup can't find anything in this case.
+    return false;
+  }
+
+  // Perform unqualified name lookup starting in the given scope.
+  return LookupName(R, S, AllowBuiltinCreation);
+}
+
+
+/// @brief Produce a diagnostic describing the ambiguity that resulted
+/// from name lookup.
+///
+/// @param Result       The ambiguous name lookup result.
+///
+/// @param Name         The name of the entity that name lookup was
+/// searching for.
+///
+/// @param NameLoc      The location of the name within the source code.
+///
+/// @param LookupRange  A source range that provides more
+/// source-location information concerning the lookup itself. For
+/// example, this range might highlight a nested-name-specifier that
+/// precedes the name.
+///
+/// @returns true
+bool Sema::DiagnoseAmbiguousLookup(LookupResult &Result) {
+  assert(Result.isAmbiguous() && "Lookup result must be ambiguous");
+
+  DeclarationName Name = Result.getLookupName();
+  SourceLocation NameLoc = Result.getNameLoc();
+  SourceRange LookupRange = Result.getContextRange();
+
+  switch (Result.getAmbiguityKind()) {
+  case LookupResult::AmbiguousBaseSubobjects: {
+    CXXBasePaths *Paths = Result.getBasePaths();
+    QualType SubobjectType = Paths->front().back().Base->getType();
+    Diag(NameLoc, diag::err_ambiguous_member_multiple_subobjects)
+      << Name << SubobjectType << getAmbiguousPathsDisplayString(*Paths)
+      << LookupRange;
+    
+    DeclContext::lookup_iterator Found = Paths->front().Decls.first;
+    while (isa<CXXMethodDecl>(*Found) &&
+           cast<CXXMethodDecl>(*Found)->isStatic())
+      ++Found;
+    
+    Diag((*Found)->getLocation(), diag::note_ambiguous_member_found);
+    
+    return true;
+  }
+
+  case LookupResult::AmbiguousBaseSubobjectTypes: {
+    Diag(NameLoc, diag::err_ambiguous_member_multiple_subobject_types)
+      << Name << LookupRange;
+    
+    CXXBasePaths *Paths = Result.getBasePaths();
+    std::set<Decl *> DeclsPrinted;
+    for (CXXBasePaths::paths_iterator Path = Paths->begin(),
+                                      PathEnd = Paths->end();
+         Path != PathEnd; ++Path) {
+      Decl *D = *Path->Decls.first;
+      if (DeclsPrinted.insert(D).second)
+        Diag(D->getLocation(), diag::note_ambiguous_member_found);
+    }
+
+    return true;
+  }
+
+  case LookupResult::AmbiguousTagHiding: {
+    Diag(NameLoc, diag::err_ambiguous_tag_hiding) << Name << LookupRange;
+
+    llvm::SmallPtrSet<NamedDecl*,8> TagDecls;
+
+    LookupResult::iterator DI, DE = Result.end();
+    for (DI = Result.begin(); DI != DE; ++DI)
+      if (TagDecl *TD = dyn_cast<TagDecl>(*DI)) {
+        TagDecls.insert(TD);
+        Diag(TD->getLocation(), diag::note_hidden_tag);
+      }
+
+    for (DI = Result.begin(); DI != DE; ++DI)
+      if (!isa<TagDecl>(*DI))
+        Diag((*DI)->getLocation(), diag::note_hiding_object);
+
+    // For recovery purposes, go ahead and implement the hiding.
+    LookupResult::Filter F = Result.makeFilter();
+    while (F.hasNext()) {
+      if (TagDecls.count(F.next()))
+        F.erase();
+    }
+    F.done();
+
+    return true;
+  }
+
+  case LookupResult::AmbiguousReference: {
+    Diag(NameLoc, diag::err_ambiguous_reference) << Name << LookupRange;
+  
+    LookupResult::iterator DI = Result.begin(), DE = Result.end();
+    for (; DI != DE; ++DI)
+      Diag((*DI)->getLocation(), diag::note_ambiguous_candidate) << *DI;
+
+    return true;
+  }
+  }
+
+  llvm_unreachable("unknown ambiguity kind");
+  return true;
+}
+
+static void
+addAssociatedClassesAndNamespaces(QualType T,
+                                  ASTContext &Context,
+                          Sema::AssociatedNamespaceSet &AssociatedNamespaces,
+                                  Sema::AssociatedClassSet &AssociatedClasses);
+
+static void CollectNamespace(Sema::AssociatedNamespaceSet &Namespaces,
+                             DeclContext *Ctx) {
+  if (Ctx->isFileContext())
+    Namespaces.insert(Ctx);
+}
+
+// \brief Add the associated classes and namespaces for argument-dependent
+// lookup that involves a template argument (C++ [basic.lookup.koenig]p2).
+static void
+addAssociatedClassesAndNamespaces(const TemplateArgument &Arg,
+                                  ASTContext &Context,
+                           Sema::AssociatedNamespaceSet &AssociatedNamespaces,
+                                  Sema::AssociatedClassSet &AssociatedClasses) {
+  // C++ [basic.lookup.koenig]p2, last bullet:
+  //   -- [...] ;
+  switch (Arg.getKind()) {
+    case TemplateArgument::Null:
+      break;
+
+    case TemplateArgument::Type:
+      // [...] the namespaces and classes associated with the types of the
+      // template arguments provided for template type parameters (excluding
+      // template template parameters)
+      addAssociatedClassesAndNamespaces(Arg.getAsType(), Context,
+                                        AssociatedNamespaces,
+                                        AssociatedClasses);
+      break;
+
+    case TemplateArgument::Template: {
+      // [...] the namespaces in which any template template arguments are
+      // defined; and the classes in which any member templates used as
+      // template template arguments are defined.
+      TemplateName Template = Arg.getAsTemplate();
+      if (ClassTemplateDecl *ClassTemplate
+                 = dyn_cast<ClassTemplateDecl>(Template.getAsTemplateDecl())) {
+        DeclContext *Ctx = ClassTemplate->getDeclContext();
+        if (CXXRecordDecl *EnclosingClass = dyn_cast<CXXRecordDecl>(Ctx))
+          AssociatedClasses.insert(EnclosingClass);
+        // Add the associated namespace for this class.
+        while (Ctx->isRecord())
+          Ctx = Ctx->getParent();
+        CollectNamespace(AssociatedNamespaces, Ctx);
+      }
+      break;
+    }
+      
+    case TemplateArgument::Declaration:
+    case TemplateArgument::Integral:
+    case TemplateArgument::Expression:
+      // [Note: non-type template arguments do not contribute to the set of
+      //  associated namespaces. ]
+      break;
+
+    case TemplateArgument::Pack:
+      for (TemplateArgument::pack_iterator P = Arg.pack_begin(),
+                                        PEnd = Arg.pack_end();
+           P != PEnd; ++P)
+        addAssociatedClassesAndNamespaces(*P, Context,
+                                          AssociatedNamespaces,
+                                          AssociatedClasses);
+      break;
+  }
+}
+
+// \brief Add the associated classes and namespaces for
+// argument-dependent lookup with an argument of class type
+// (C++ [basic.lookup.koenig]p2).
+static void
+addAssociatedClassesAndNamespaces(CXXRecordDecl *Class,
+                                  ASTContext &Context,
+                            Sema::AssociatedNamespaceSet &AssociatedNamespaces,
+                            Sema::AssociatedClassSet &AssociatedClasses) {
+  // C++ [basic.lookup.koenig]p2:
+  //   [...]
+  //     -- If T is a class type (including unions), its associated
+  //        classes are: the class itself; the class of which it is a
+  //        member, if any; and its direct and indirect base
+  //        classes. Its associated namespaces are the namespaces in
+  //        which its associated classes are defined.
+
+  // Add the class of which it is a member, if any.
+  DeclContext *Ctx = Class->getDeclContext();
+  if (CXXRecordDecl *EnclosingClass = dyn_cast<CXXRecordDecl>(Ctx))
+    AssociatedClasses.insert(EnclosingClass);
+  // Add the associated namespace for this class.
+  while (Ctx->isRecord())
+    Ctx = Ctx->getParent();
+  CollectNamespace(AssociatedNamespaces, Ctx);
+
+  // Add the class itself. If we've already seen this class, we don't
+  // need to visit base classes.
+  if (!AssociatedClasses.insert(Class))
+    return;
+
+  // -- If T is a template-id, its associated namespaces and classes are
+  //    the namespace in which the template is defined; for member
+  //    templates, the member template’s class; the namespaces and classes
+  //    associated with the types of the template arguments provided for
+  //    template type parameters (excluding template template parameters); the
+  //    namespaces in which any template template arguments are defined; and
+  //    the classes in which any member templates used as template template
+  //    arguments are defined. [Note: non-type template arguments do not
+  //    contribute to the set of associated namespaces. ]
+  if (ClassTemplateSpecializationDecl *Spec
+        = dyn_cast<ClassTemplateSpecializationDecl>(Class)) {
+    DeclContext *Ctx = Spec->getSpecializedTemplate()->getDeclContext();
+    if (CXXRecordDecl *EnclosingClass = dyn_cast<CXXRecordDecl>(Ctx))
+      AssociatedClasses.insert(EnclosingClass);
+    // Add the associated namespace for this class.
+    while (Ctx->isRecord())
+      Ctx = Ctx->getParent();
+    CollectNamespace(AssociatedNamespaces, Ctx);
+
+    const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
+    for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
+      addAssociatedClassesAndNamespaces(TemplateArgs[I], Context,
+                                        AssociatedNamespaces,
+                                        AssociatedClasses);
+  }
+
+  // Only recurse into base classes for complete types.
+  if (!Class->hasDefinition()) {
+    // FIXME: we might need to instantiate templates here
+    return;
+  }
+
+  // Add direct and indirect base classes along with their associated
+  // namespaces.
+  llvm::SmallVector<CXXRecordDecl *, 32> Bases;
+  Bases.push_back(Class);
+  while (!Bases.empty()) {
+    // Pop this class off the stack.
+    Class = Bases.back();
+    Bases.pop_back();
+
+    // Visit the base classes.
+    for (CXXRecordDecl::base_class_iterator Base = Class->bases_begin(),
+                                         BaseEnd = Class->bases_end();
+         Base != BaseEnd; ++Base) {
+      const RecordType *BaseType = Base->getType()->getAs<RecordType>();
+      // In dependent contexts, we do ADL twice, and the first time around,
+      // the base type might be a dependent TemplateSpecializationType, or a
+      // TemplateTypeParmType. If that happens, simply ignore it.
+      // FIXME: If we want to support export, we probably need to add the
+      // namespace of the template in a TemplateSpecializationType, or even
+      // the classes and namespaces of known non-dependent arguments.
+      if (!BaseType)
+        continue;
+      CXXRecordDecl *BaseDecl = cast<CXXRecordDecl>(BaseType->getDecl());
+      if (AssociatedClasses.insert(BaseDecl)) {
+        // Find the associated namespace for this base class.
+        DeclContext *BaseCtx = BaseDecl->getDeclContext();
+        while (BaseCtx->isRecord())
+          BaseCtx = BaseCtx->getParent();
+        CollectNamespace(AssociatedNamespaces, BaseCtx);
+
+        // Make sure we visit the bases of this base class.
+        if (BaseDecl->bases_begin() != BaseDecl->bases_end())
+          Bases.push_back(BaseDecl);
+      }
+    }
+  }
+}
+
+// \brief Add the associated classes and namespaces for
+// argument-dependent lookup with an argument of type T
+// (C++ [basic.lookup.koenig]p2).
+static void
+addAssociatedClassesAndNamespaces(QualType T,
+                                  ASTContext &Context,
+                            Sema::AssociatedNamespaceSet &AssociatedNamespaces,
+                                  Sema::AssociatedClassSet &AssociatedClasses) {
+  // C++ [basic.lookup.koenig]p2:
+  //
+  //   For each argument type T in the function call, there is a set
+  //   of zero or more associated namespaces and a set of zero or more
+  //   associated classes to be considered. The sets of namespaces and
+  //   classes is determined entirely by the types of the function
+  //   arguments (and the namespace of any template template
+  //   argument). Typedef names and using-declarations used to specify
+  //   the types do not contribute to this set. The sets of namespaces
+  //   and classes are determined in the following way:
+  T = Context.getCanonicalType(T).getUnqualifiedType();
+
+  //    -- If T is a pointer to U or an array of U, its associated
+  //       namespaces and classes are those associated with U.
+  //
+  // We handle this by unwrapping pointer and array types immediately,
+  // to avoid unnecessary recursion.
+  while (true) {
+    if (const PointerType *Ptr = T->getAs<PointerType>())
+      T = Ptr->getPointeeType();
+    else if (const ArrayType *Ptr = Context.getAsArrayType(T))
+      T = Ptr->getElementType();
+    else
+      break;
+  }
+
+  //     -- If T is a fundamental type, its associated sets of
+  //        namespaces and classes are both empty.
+  if (T->getAs<BuiltinType>())
+    return;
+
+  //     -- If T is a class type (including unions), its associated
+  //        classes are: the class itself; the class of which it is a
+  //        member, if any; and its direct and indirect base
+  //        classes. Its associated namespaces are the namespaces in
+  //        which its associated classes are defined.
+  if (const RecordType *ClassType = T->getAs<RecordType>())
+    if (CXXRecordDecl *ClassDecl
+        = dyn_cast<CXXRecordDecl>(ClassType->getDecl())) {
+      addAssociatedClassesAndNamespaces(ClassDecl, Context,
+                                        AssociatedNamespaces,
+                                        AssociatedClasses);
+      return;
+    }
+
+  //     -- If T is an enumeration type, its associated namespace is
+  //        the namespace in which it is defined. If it is class
+  //        member, its associated class is the member’s class; else
+  //        it has no associated class.
+  if (const EnumType *EnumT = T->getAs<EnumType>()) {
+    EnumDecl *Enum = EnumT->getDecl();
+
+    DeclContext *Ctx = Enum->getDeclContext();
+    if (CXXRecordDecl *EnclosingClass = dyn_cast<CXXRecordDecl>(Ctx))
+      AssociatedClasses.insert(EnclosingClass);
+
+    // Add the associated namespace for this class.
+    while (Ctx->isRecord())
+      Ctx = Ctx->getParent();
+    CollectNamespace(AssociatedNamespaces, Ctx);
+
+    return;
+  }
+
+  //     -- If T is a function type, its associated namespaces and
+  //        classes are those associated with the function parameter
+  //        types and those associated with the return type.
+  if (const FunctionType *FnType = T->getAs<FunctionType>()) {
+    // Return type
+    addAssociatedClassesAndNamespaces(FnType->getResultType(),
+                                      Context,
+                                      AssociatedNamespaces, AssociatedClasses);
+
+    const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FnType);
+    if (!Proto)
+      return;
+
+    // Argument types
+    for (FunctionProtoType::arg_type_iterator Arg = Proto->arg_type_begin(),
+                                           ArgEnd = Proto->arg_type_end();
+         Arg != ArgEnd; ++Arg)
+      addAssociatedClassesAndNamespaces(*Arg, Context,
+                                        AssociatedNamespaces, AssociatedClasses);
+
+    return;
+  }
+
+  //     -- If T is a pointer to a member function of a class X, its
+  //        associated namespaces and classes are those associated
+  //        with the function parameter types and return type,
+  //        together with those associated with X.
+  //
+  //     -- If T is a pointer to a data member of class X, its
+  //        associated namespaces and classes are those associated
+  //        with the member type together with those associated with
+  //        X.
+  if (const MemberPointerType *MemberPtr = T->getAs<MemberPointerType>()) {
+    // Handle the type that the pointer to member points to.
+    addAssociatedClassesAndNamespaces(MemberPtr->getPointeeType(),
+                                      Context,
+                                      AssociatedNamespaces,
+                                      AssociatedClasses);
+
+    // Handle the class type into which this points.
+    if (const RecordType *Class = MemberPtr->getClass()->getAs<RecordType>())
+      addAssociatedClassesAndNamespaces(cast<CXXRecordDecl>(Class->getDecl()),
+                                        Context,
+                                        AssociatedNamespaces,
+                                        AssociatedClasses);
+
+    return;
+  }
+
+  // FIXME: What about block pointers?
+  // FIXME: What about Objective-C message sends?
+}
+
+/// \brief Find the associated classes and namespaces for
+/// argument-dependent lookup for a call with the given set of
+/// arguments.
+///
+/// This routine computes the sets of associated classes and associated
+/// namespaces searched by argument-dependent lookup
+/// (C++ [basic.lookup.argdep]) for a given set of arguments.
+void
+Sema::FindAssociatedClassesAndNamespaces(Expr **Args, unsigned NumArgs,
+                                 AssociatedNamespaceSet &AssociatedNamespaces,
+                                 AssociatedClassSet &AssociatedClasses) {
+  AssociatedNamespaces.clear();
+  AssociatedClasses.clear();
+
+  // C++ [basic.lookup.koenig]p2:
+  //   For each argument type T in the function call, there is a set
+  //   of zero or more associated namespaces and a set of zero or more
+  //   associated classes to be considered. The sets of namespaces and
+  //   classes is determined entirely by the types of the function
+  //   arguments (and the namespace of any template template
+  //   argument).
+  for (unsigned ArgIdx = 0; ArgIdx != NumArgs; ++ArgIdx) {
+    Expr *Arg = Args[ArgIdx];
+
+    if (Arg->getType() != Context.OverloadTy) {
+      addAssociatedClassesAndNamespaces(Arg->getType(), Context,
+                                        AssociatedNamespaces,
+                                        AssociatedClasses);
+      continue;
+    }
+
+    // [...] In addition, if the argument is the name or address of a
+    // set of overloaded functions and/or function templates, its
+    // associated classes and namespaces are the union of those
+    // associated with each of the members of the set: the namespace
+    // in which the function or function template is defined and the
+    // classes and namespaces associated with its (non-dependent)
+    // parameter types and return type.
+    Arg = Arg->IgnoreParens();
+    if (UnaryOperator *unaryOp = dyn_cast<UnaryOperator>(Arg))
+      if (unaryOp->getOpcode() == UnaryOperator::AddrOf)
+        Arg = unaryOp->getSubExpr();
+
+    // TODO: avoid the copies.  This should be easy when the cases
+    // share a storage implementation.
+    llvm::SmallVector<NamedDecl*, 8> Functions;
+
+    if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Arg))
+      Functions.append(ULE->decls_begin(), ULE->decls_end());
+    else
+      continue;
+
+    for (llvm::SmallVectorImpl<NamedDecl*>::iterator I = Functions.begin(),
+           E = Functions.end(); I != E; ++I) {
+      // Look through any using declarations to find the underlying function.
+      NamedDecl *Fn = (*I)->getUnderlyingDecl();
+
+      FunctionDecl *FDecl = dyn_cast<FunctionDecl>(Fn);
+      if (!FDecl)
+        FDecl = cast<FunctionTemplateDecl>(Fn)->getTemplatedDecl();
+
+      // Add the classes and namespaces associated with the parameter
+      // types and return type of this function.
+      addAssociatedClassesAndNamespaces(FDecl->getType(), Context,
+                                        AssociatedNamespaces,
+                                        AssociatedClasses);
+    }
+  }
+}
+
+/// IsAcceptableNonMemberOperatorCandidate - Determine whether Fn is
+/// an acceptable non-member overloaded operator for a call whose
+/// arguments have types T1 (and, if non-empty, T2). This routine
+/// implements the check in C++ [over.match.oper]p3b2 concerning
+/// enumeration types.
+static bool
+IsAcceptableNonMemberOperatorCandidate(FunctionDecl *Fn,
+                                       QualType T1, QualType T2,
+                                       ASTContext &Context) {
+  if (T1->isDependentType() || (!T2.isNull() && T2->isDependentType()))
+    return true;
+
+  if (T1->isRecordType() || (!T2.isNull() && T2->isRecordType()))
+    return true;
+
+  const FunctionProtoType *Proto = Fn->getType()->getAs<FunctionProtoType>();
+  if (Proto->getNumArgs() < 1)
+    return false;
+
+  if (T1->isEnumeralType()) {
+    QualType ArgType = Proto->getArgType(0).getNonReferenceType();
+    if (Context.hasSameUnqualifiedType(T1, ArgType))
+      return true;
+  }
+
+  if (Proto->getNumArgs() < 2)
+    return false;
+
+  if (!T2.isNull() && T2->isEnumeralType()) {
+    QualType ArgType = Proto->getArgType(1).getNonReferenceType();
+    if (Context.hasSameUnqualifiedType(T2, ArgType))
+      return true;
+  }
+
+  return false;
+}
+
+NamedDecl *Sema::LookupSingleName(Scope *S, DeclarationName Name,
+                                  SourceLocation Loc,
+                                  LookupNameKind NameKind,
+                                  RedeclarationKind Redecl) {
+  LookupResult R(*this, Name, Loc, NameKind, Redecl);
+  LookupName(R, S);
+  return R.getAsSingle<NamedDecl>();
+}
+
+/// \brief Find the protocol with the given name, if any.
+ObjCProtocolDecl *Sema::LookupProtocol(IdentifierInfo *II, 
+                                       SourceLocation IdLoc) {
+  Decl *D = LookupSingleName(TUScope, II, IdLoc,
+                             LookupObjCProtocolName);
+  return cast_or_null<ObjCProtocolDecl>(D);
+}
+
+void Sema::LookupOverloadedOperatorName(OverloadedOperatorKind Op, Scope *S,
+                                        QualType T1, QualType T2,
+                                        UnresolvedSetImpl &Functions) {
+  // C++ [over.match.oper]p3:
+  //     -- The set of non-member candidates is the result of the
+  //        unqualified lookup of operator@ in the context of the
+  //        expression according to the usual rules for name lookup in
+  //        unqualified function calls (3.4.2) except that all member
+  //        functions are ignored. However, if no operand has a class
+  //        type, only those non-member functions in the lookup set
+  //        that have a first parameter of type T1 or "reference to
+  //        (possibly cv-qualified) T1", when T1 is an enumeration
+  //        type, or (if there is a right operand) a second parameter
+  //        of type T2 or "reference to (possibly cv-qualified) T2",
+  //        when T2 is an enumeration type, are candidate functions.
+  DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(Op);
+  LookupResult Operators(*this, OpName, SourceLocation(), LookupOperatorName);
+  LookupName(Operators, S);
+
+  assert(!Operators.isAmbiguous() && "Operator lookup cannot be ambiguous");
+
+  if (Operators.empty())
+    return;
+
+  for (LookupResult::iterator Op = Operators.begin(), OpEnd = Operators.end();
+       Op != OpEnd; ++Op) {
+    NamedDecl *Found = (*Op)->getUnderlyingDecl();
+    if (FunctionDecl *FD = dyn_cast<FunctionDecl>(Found)) {
+      if (IsAcceptableNonMemberOperatorCandidate(FD, T1, T2, Context))
+        Functions.addDecl(*Op, Op.getAccess()); // FIXME: canonical FD
+    } else if (FunctionTemplateDecl *FunTmpl
+                 = dyn_cast<FunctionTemplateDecl>(Found)) {
+      // FIXME: friend operators?
+      // FIXME: do we need to check IsAcceptableNonMemberOperatorCandidate,
+      // later?
+      if (!FunTmpl->getDeclContext()->isRecord())
+        Functions.addDecl(*Op, Op.getAccess());
+    }
+  }
+}
+
+void ADLResult::insert(NamedDecl *New) {
+  NamedDecl *&Old = Decls[cast<NamedDecl>(New->getCanonicalDecl())];
+
+  // If we haven't yet seen a decl for this key, or the last decl
+  // was exactly this one, we're done.
+  if (Old == 0 || Old == New) {
+    Old = New;
+    return;
+  }
+
+  // Otherwise, decide which is a more recent redeclaration.
+  FunctionDecl *OldFD, *NewFD;
+  if (isa<FunctionTemplateDecl>(New)) {
+    OldFD = cast<FunctionTemplateDecl>(Old)->getTemplatedDecl();
+    NewFD = cast<FunctionTemplateDecl>(New)->getTemplatedDecl();
+  } else {
+    OldFD = cast<FunctionDecl>(Old);
+    NewFD = cast<FunctionDecl>(New);
+  }
+
+  FunctionDecl *Cursor = NewFD;
+  while (true) {
+    Cursor = Cursor->getPreviousDeclaration();
+
+    // If we got to the end without finding OldFD, OldFD is the newer
+    // declaration;  leave things as they are.
+    if (!Cursor) return;
+
+    // If we do find OldFD, then NewFD is newer.
+    if (Cursor == OldFD) break;
+
+    // Otherwise, keep looking.
+  }
+
+  Old = New;
+}
+
+void Sema::ArgumentDependentLookup(DeclarationName Name, bool Operator,
+                                   Expr **Args, unsigned NumArgs,
+                                   ADLResult &Result) {
+  // Find all of the associated namespaces and classes based on the
+  // arguments we have.
+  AssociatedNamespaceSet AssociatedNamespaces;
+  AssociatedClassSet AssociatedClasses;
+  FindAssociatedClassesAndNamespaces(Args, NumArgs,
+                                     AssociatedNamespaces,
+                                     AssociatedClasses);
+
+  QualType T1, T2;
+  if (Operator) {
+    T1 = Args[0]->getType();
+    if (NumArgs >= 2)
+      T2 = Args[1]->getType();
+  }
+
+  // C++ [basic.lookup.argdep]p3:
+  //   Let X be the lookup set produced by unqualified lookup (3.4.1)
+  //   and let Y be the lookup set produced by argument dependent
+  //   lookup (defined as follows). If X contains [...] then Y is
+  //   empty. Otherwise Y is the set of declarations found in the
+  //   namespaces associated with the argument types as described
+  //   below. The set of declarations found by the lookup of the name
+  //   is the union of X and Y.
+  //
+  // Here, we compute Y and add its members to the overloaded
+  // candidate set.
+  for (AssociatedNamespaceSet::iterator NS = AssociatedNamespaces.begin(),
+                                     NSEnd = AssociatedNamespaces.end();
+       NS != NSEnd; ++NS) {
+    //   When considering an associated namespace, the lookup is the
+    //   same as the lookup performed when the associated namespace is
+    //   used as a qualifier (3.4.3.2) except that:
+    //
+    //     -- Any using-directives in the associated namespace are
+    //        ignored.
+    //
+    //     -- Any namespace-scope friend functions declared in
+    //        associated classes are visible within their respective
+    //        namespaces even if they are not visible during an ordinary
+    //        lookup (11.4).
+    DeclContext::lookup_iterator I, E;
+    for (llvm::tie(I, E) = (*NS)->lookup(Name); I != E; ++I) {
+      NamedDecl *D = *I;
+      // If the only declaration here is an ordinary friend, consider
+      // it only if it was declared in an associated classes.
+      if (D->getIdentifierNamespace() == Decl::IDNS_OrdinaryFriend) {
+        DeclContext *LexDC = D->getLexicalDeclContext();
+        if (!AssociatedClasses.count(cast<CXXRecordDecl>(LexDC)))
+          continue;
+      }
+
+      if (isa<UsingShadowDecl>(D))
+        D = cast<UsingShadowDecl>(D)->getTargetDecl();
+
+      if (isa<FunctionDecl>(D)) {
+        if (Operator &&
+            !IsAcceptableNonMemberOperatorCandidate(cast<FunctionDecl>(D),
+                                                    T1, T2, Context))
+          continue;
+      } else if (!isa<FunctionTemplateDecl>(D))
+        continue;
+
+      Result.insert(D);
+    }
+  }
+}
+
+//----------------------------------------------------------------------------
+// Search for all visible declarations.
+//----------------------------------------------------------------------------
+VisibleDeclConsumer::~VisibleDeclConsumer() { }
+
+namespace {
+
+class ShadowContextRAII;
+
+class VisibleDeclsRecord {
+public:
+  /// \brief An entry in the shadow map, which is optimized to store a
+  /// single declaration (the common case) but can also store a list
+  /// of declarations.
+  class ShadowMapEntry {
+    typedef llvm::SmallVector<NamedDecl *, 4> DeclVector;
+    
+    /// \brief Contains either the solitary NamedDecl * or a vector
+    /// of declarations.
+    llvm::PointerUnion<NamedDecl *, DeclVector*> DeclOrVector;
+
+  public:
+    ShadowMapEntry() : DeclOrVector() { }
+
+    void Add(NamedDecl *ND);
+    void Destroy();
+
+    // Iteration.
+    typedef NamedDecl **iterator;
+    iterator begin();
+    iterator end();
+  };
+
+private:
+  /// \brief A mapping from declaration names to the declarations that have
+  /// this name within a particular scope.
+  typedef llvm::DenseMap<DeclarationName, ShadowMapEntry> ShadowMap;
+
+  /// \brief A list of shadow maps, which is used to model name hiding.
+  std::list<ShadowMap> ShadowMaps;
+
+  /// \brief The declaration contexts we have already visited.
+  llvm::SmallPtrSet<DeclContext *, 8> VisitedContexts;
+
+  friend class ShadowContextRAII;
+
+public:
+  /// \brief Determine whether we have already visited this context
+  /// (and, if not, note that we are going to visit that context now).
+  bool visitedContext(DeclContext *Ctx) {
+    return !VisitedContexts.insert(Ctx);
+  }
+
+  /// \brief Determine whether the given declaration is hidden in the
+  /// current scope.
+  ///
+  /// \returns the declaration that hides the given declaration, or
+  /// NULL if no such declaration exists.
+  NamedDecl *checkHidden(NamedDecl *ND);
+
+  /// \brief Add a declaration to the current shadow map.
+  void add(NamedDecl *ND) { ShadowMaps.back()[ND->getDeclName()].Add(ND); }
+};
+
+/// \brief RAII object that records when we've entered a shadow context.
+class ShadowContextRAII {
+  VisibleDeclsRecord &Visible;
+
+  typedef VisibleDeclsRecord::ShadowMap ShadowMap;
+
+public:
+  ShadowContextRAII(VisibleDeclsRecord &Visible) : Visible(Visible) {
+    Visible.ShadowMaps.push_back(ShadowMap());
+  }
+
+  ~ShadowContextRAII() {
+    for (ShadowMap::iterator E = Visible.ShadowMaps.back().begin(),
+                          EEnd = Visible.ShadowMaps.back().end();
+         E != EEnd;
+         ++E)
+      E->second.Destroy();
+
+    Visible.ShadowMaps.pop_back();
+  }
+};
+
+} // end anonymous namespace
+
+void VisibleDeclsRecord::ShadowMapEntry::Add(NamedDecl *ND) {
+  if (DeclOrVector.isNull()) {
+    // 0 - > 1 elements: just set the single element information.
+    DeclOrVector = ND;
+    return;
+  }
+  
+  if (NamedDecl *PrevND = DeclOrVector.dyn_cast<NamedDecl *>()) {
+    // 1 -> 2 elements: create the vector of results and push in the
+    // existing declaration.
+    DeclVector *Vec = new DeclVector;
+    Vec->push_back(PrevND);
+    DeclOrVector = Vec;
+  }
+
+  // Add the new element to the end of the vector.
+  DeclOrVector.get<DeclVector*>()->push_back(ND);
+}
+
+void VisibleDeclsRecord::ShadowMapEntry::Destroy() {
+  if (DeclVector *Vec = DeclOrVector.dyn_cast<DeclVector *>()) {
+    delete Vec;
+    DeclOrVector = ((NamedDecl *)0);
+  }
+}
+
+VisibleDeclsRecord::ShadowMapEntry::iterator 
+VisibleDeclsRecord::ShadowMapEntry::begin() {
+  if (DeclOrVector.isNull())
+    return 0;
+
+  if (DeclOrVector.dyn_cast<NamedDecl *>())
+    return &reinterpret_cast<NamedDecl*&>(DeclOrVector);
+
+  return DeclOrVector.get<DeclVector *>()->begin();
+}
+
+VisibleDeclsRecord::ShadowMapEntry::iterator 
+VisibleDeclsRecord::ShadowMapEntry::end() {
+  if (DeclOrVector.isNull())
+    return 0;
+
+  if (DeclOrVector.dyn_cast<NamedDecl *>())
+    return &reinterpret_cast<NamedDecl*&>(DeclOrVector) + 1;
+
+  return DeclOrVector.get<DeclVector *>()->end();
+}
+
+NamedDecl *VisibleDeclsRecord::checkHidden(NamedDecl *ND) {
+  // Look through using declarations.
+  ND = ND->getUnderlyingDecl();
+  
+  unsigned IDNS = ND->getIdentifierNamespace();
+  std::list<ShadowMap>::reverse_iterator SM = ShadowMaps.rbegin();
+  for (std::list<ShadowMap>::reverse_iterator SMEnd = ShadowMaps.rend();
+       SM != SMEnd; ++SM) {
+    ShadowMap::iterator Pos = SM->find(ND->getDeclName());
+    if (Pos == SM->end())
+      continue;
+
+    for (ShadowMapEntry::iterator I = Pos->second.begin(), 
+                               IEnd = Pos->second.end();
+         I != IEnd; ++I) {
+      // A tag declaration does not hide a non-tag declaration.
+      if ((*I)->hasTagIdentifierNamespace() &&
+          (IDNS & (Decl::IDNS_Member | Decl::IDNS_Ordinary | 
+                   Decl::IDNS_ObjCProtocol)))
+        continue;
+
+      // Protocols are in distinct namespaces from everything else.
+      if ((((*I)->getIdentifierNamespace() & Decl::IDNS_ObjCProtocol)
+           || (IDNS & Decl::IDNS_ObjCProtocol)) &&
+          (*I)->getIdentifierNamespace() != IDNS)
+        continue;
+
+      // Functions and function templates in the same scope overload
+      // rather than hide.  FIXME: Look for hiding based on function
+      // signatures!
+      if ((*I)->isFunctionOrFunctionTemplate() &&
+          ND->isFunctionOrFunctionTemplate() &&
+          SM == ShadowMaps.rbegin())
+        continue;
+          
+      // We've found a declaration that hides this one.
+      return *I;
+    }
+  }
+
+  return 0;
+}
+
+static void LookupVisibleDecls(DeclContext *Ctx, LookupResult &Result,
+                               bool QualifiedNameLookup,
+                               bool InBaseClass,
+                               VisibleDeclConsumer &Consumer,
+                               VisibleDeclsRecord &Visited) {
+  if (!Ctx)
+    return;
+
+  // Make sure we don't visit the same context twice.
+  if (Visited.visitedContext(Ctx->getPrimaryContext()))
+    return;
+  
+  // Enumerate all of the results in this context.
+  for (DeclContext *CurCtx = Ctx->getPrimaryContext(); CurCtx; 
+       CurCtx = CurCtx->getNextContext()) {
+    for (DeclContext::decl_iterator D = CurCtx->decls_begin(), 
+                                 DEnd = CurCtx->decls_end();
+         D != DEnd; ++D) {
+      if (NamedDecl *ND = dyn_cast<NamedDecl>(*D))
+        if (Result.isAcceptableDecl(ND)) {
+          Consumer.FoundDecl(ND, Visited.checkHidden(ND), InBaseClass);
+          Visited.add(ND);
+        }
+
+      // Visit transparent contexts inside this context.
+      if (DeclContext *InnerCtx = dyn_cast<DeclContext>(*D)) {
+        if (InnerCtx->isTransparentContext())
+          LookupVisibleDecls(InnerCtx, Result, QualifiedNameLookup, InBaseClass,
+                             Consumer, Visited);
+      }
+    }
+  }
+
+  // Traverse using directives for qualified name lookup.
+  if (QualifiedNameLookup) {
+    ShadowContextRAII Shadow(Visited);
+    DeclContext::udir_iterator I, E;
+    for (llvm::tie(I, E) = Ctx->getUsingDirectives(); I != E; ++I) {
+      LookupVisibleDecls((*I)->getNominatedNamespace(), Result, 
+                         QualifiedNameLookup, InBaseClass, Consumer, Visited);
+    }
+  }
+
+  // Traverse the contexts of inherited C++ classes.
+  if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(Ctx)) {
+    if (!Record->hasDefinition())
+      return;
+
+    for (CXXRecordDecl::base_class_iterator B = Record->bases_begin(),
+                                         BEnd = Record->bases_end();
+         B != BEnd; ++B) {
+      QualType BaseType = B->getType();
+      
+      // Don't look into dependent bases, because name lookup can't look
+      // there anyway.
+      if (BaseType->isDependentType())
+        continue;
+      
+      const RecordType *Record = BaseType->getAs<RecordType>();
+      if (!Record)
+        continue;
+      
+      // FIXME: It would be nice to be able to determine whether referencing
+      // a particular member would be ambiguous. For example, given
+      //
+      //   struct A { int member; };
+      //   struct B { int member; };
+      //   struct C : A, B { };
+      //
+      //   void f(C *c) { c->### }
+      //
+      // accessing 'member' would result in an ambiguity. However, we
+      // could be smart enough to qualify the member with the base
+      // class, e.g.,
+      //
+      //   c->B::member
+      //
+      // or
+      //
+      //   c->A::member
+      
+      // Find results in this base class (and its bases).
+      ShadowContextRAII Shadow(Visited);
+      LookupVisibleDecls(Record->getDecl(), Result, QualifiedNameLookup,
+                         true, Consumer, Visited);
+    }
+  }
+  
+  // Traverse the contexts of Objective-C classes.
+  if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Ctx)) {
+    // Traverse categories.
+    for (ObjCCategoryDecl *Category = IFace->getCategoryList();
+         Category; Category = Category->getNextClassCategory()) {
+      ShadowContextRAII Shadow(Visited);
+      LookupVisibleDecls(Category, Result, QualifiedNameLookup, false, 
+                         Consumer, Visited);
+    }
+
+    // Traverse protocols.
+    for (ObjCInterfaceDecl::protocol_iterator I = IFace->protocol_begin(),
+         E = IFace->protocol_end(); I != E; ++I) {
+      ShadowContextRAII Shadow(Visited);
+      LookupVisibleDecls(*I, Result, QualifiedNameLookup, false, Consumer, 
+                         Visited);
+    }
+
+    // Traverse the superclass.
+    if (IFace->getSuperClass()) {
+      ShadowContextRAII Shadow(Visited);
+      LookupVisibleDecls(IFace->getSuperClass(), Result, QualifiedNameLookup,
+                         true, Consumer, Visited);
+    }
+    
+    // If there is an implementation, traverse it. We do this to find
+    // synthesized ivars.
+    if (IFace->getImplementation()) {
+      ShadowContextRAII Shadow(Visited);
+      LookupVisibleDecls(IFace->getImplementation(), Result, 
+                         QualifiedNameLookup, true, Consumer, Visited);
+    }
+  } else if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Ctx)) {
+    for (ObjCProtocolDecl::protocol_iterator I = Protocol->protocol_begin(),
+           E = Protocol->protocol_end(); I != E; ++I) {
+      ShadowContextRAII Shadow(Visited);
+      LookupVisibleDecls(*I, Result, QualifiedNameLookup, false, Consumer, 
+                         Visited);
+    }
+  } else if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Ctx)) {
+    for (ObjCCategoryDecl::protocol_iterator I = Category->protocol_begin(),
+           E = Category->protocol_end(); I != E; ++I) {
+      ShadowContextRAII Shadow(Visited);
+      LookupVisibleDecls(*I, Result, QualifiedNameLookup, false, Consumer, 
+                         Visited);
+    }
+    
+    // If there is an implementation, traverse it.
+    if (Category->getImplementation()) {
+      ShadowContextRAII Shadow(Visited);
+      LookupVisibleDecls(Category->getImplementation(), Result, 
+                         QualifiedNameLookup, true, Consumer, Visited);
+    }    
+  }
+}
+
+static void LookupVisibleDecls(Scope *S, LookupResult &Result,
+                               UnqualUsingDirectiveSet &UDirs,
+                               VisibleDeclConsumer &Consumer,
+                               VisibleDeclsRecord &Visited) {
+  if (!S)
+    return;
+
+  if (!S->getEntity() || !S->getParent() ||
+      ((DeclContext *)S->getEntity())->isFunctionOrMethod()) {
+    // Walk through the declarations in this Scope.
+    for (Scope::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
+         D != DEnd; ++D) {
+      if (NamedDecl *ND = dyn_cast<NamedDecl>((Decl *)((*D).get())))
+        if (Result.isAcceptableDecl(ND)) {
+          Consumer.FoundDecl(ND, Visited.checkHidden(ND), false);
+          Visited.add(ND);
+        }
+    }
+  }
+  
+  // FIXME: C++ [temp.local]p8
+  DeclContext *Entity = 0;
+  if (S->getEntity()) {
+    // Look into this scope's declaration context, along with any of its
+    // parent lookup contexts (e.g., enclosing classes), up to the point
+    // where we hit the context stored in the next outer scope.
+    Entity = (DeclContext *)S->getEntity();
+    DeclContext *OuterCtx = findOuterContext(S).first; // FIXME
+    
+    for (DeclContext *Ctx = Entity; Ctx && !Ctx->Equals(OuterCtx);
+         Ctx = Ctx->getLookupParent()) {
+      if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(Ctx)) {
+        if (Method->isInstanceMethod()) {
+          // For instance methods, look for ivars in the method's interface.
+          LookupResult IvarResult(Result.getSema(), Result.getLookupName(),
+                                  Result.getNameLoc(), Sema::LookupMemberName);
+          if (ObjCInterfaceDecl *IFace = Method->getClassInterface())
+            LookupVisibleDecls(IFace, IvarResult, /*QualifiedNameLookup=*/false, 
+                               /*InBaseClass=*/false, Consumer, Visited);
+        }
+
+        // We've already performed all of the name lookup that we need
+        // to for Objective-C methods; the next context will be the
+        // outer scope.
+        break;
+      }
+
+      if (Ctx->isFunctionOrMethod())
+        continue;
+      
+      LookupVisibleDecls(Ctx, Result, /*QualifiedNameLookup=*/false, 
+                         /*InBaseClass=*/false, Consumer, Visited);
+    }
+  } else if (!S->getParent()) {
+    // Look into the translation unit scope. We walk through the translation
+    // unit's declaration context, because the Scope itself won't have all of
+    // the declarations if we loaded a precompiled header.
+    // FIXME: We would like the translation unit's Scope object to point to the
+    // translation unit, so we don't need this special "if" branch. However,
+    // doing so would force the normal C++ name-lookup code to look into the
+    // translation unit decl when the IdentifierInfo chains would suffice. 
+    // Once we fix that problem (which is part of a more general "don't look
+    // in DeclContexts unless we have to" optimization), we can eliminate this.
+    Entity = Result.getSema().Context.getTranslationUnitDecl();
+    LookupVisibleDecls(Entity, Result, /*QualifiedNameLookup=*/false, 
+                       /*InBaseClass=*/false, Consumer, Visited);
+  } 
+  
+  if (Entity) {
+    // Lookup visible declarations in any namespaces found by using
+    // directives.
+    UnqualUsingDirectiveSet::const_iterator UI, UEnd;
+    llvm::tie(UI, UEnd) = UDirs.getNamespacesFor(Entity);
+    for (; UI != UEnd; ++UI)
+      LookupVisibleDecls(const_cast<DeclContext *>(UI->getNominatedNamespace()),
+                         Result, /*QualifiedNameLookup=*/false, 
+                         /*InBaseClass=*/false, Consumer, Visited);
+  }
+
+  // Lookup names in the parent scope.
+  ShadowContextRAII Shadow(Visited);
+  LookupVisibleDecls(S->getParent(), Result, UDirs, Consumer, Visited);
+}
+
+void Sema::LookupVisibleDecls(Scope *S, LookupNameKind Kind,
+                              VisibleDeclConsumer &Consumer) {
+  // Determine the set of using directives available during
+  // unqualified name lookup.
+  Scope *Initial = S;
+  UnqualUsingDirectiveSet UDirs;
+  if (getLangOptions().CPlusPlus) {
+    // Find the first namespace or translation-unit scope.
+    while (S && !isNamespaceOrTranslationUnitScope(S))
+      S = S->getParent();
+
+    UDirs.visitScopeChain(Initial, S);
+  }
+  UDirs.done();
+
+  // Look for visible declarations.
+  LookupResult Result(*this, DeclarationName(), SourceLocation(), Kind);
+  VisibleDeclsRecord Visited;
+  ShadowContextRAII Shadow(Visited);
+  ::LookupVisibleDecls(Initial, Result, UDirs, Consumer, Visited);
+}
+
+void Sema::LookupVisibleDecls(DeclContext *Ctx, LookupNameKind Kind,
+                              VisibleDeclConsumer &Consumer) {
+  LookupResult Result(*this, DeclarationName(), SourceLocation(), Kind);
+  VisibleDeclsRecord Visited;
+  ShadowContextRAII Shadow(Visited);
+  ::LookupVisibleDecls(Ctx, Result, /*QualifiedNameLookup=*/true, 
+                       /*InBaseClass=*/false, Consumer, Visited);
+}
+
+//----------------------------------------------------------------------------
+// Typo correction
+//----------------------------------------------------------------------------
+
+namespace {
+class TypoCorrectionConsumer : public VisibleDeclConsumer {
+  /// \brief The name written that is a typo in the source.
+  llvm::StringRef Typo;
+
+  /// \brief The results found that have the smallest edit distance
+  /// found (so far) with the typo name.
+  llvm::SmallVector<NamedDecl *, 4> BestResults;
+
+  /// \brief The keywords that have the smallest edit distance.
+  llvm::SmallVector<IdentifierInfo *, 4> BestKeywords;
+  
+  /// \brief The best edit distance found so far.
+  unsigned BestEditDistance;
+  
+public:
+  explicit TypoCorrectionConsumer(IdentifierInfo *Typo)
+    : Typo(Typo->getName()) { }
+
+  virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, bool InBaseClass);
+  void addKeywordResult(ASTContext &Context, llvm::StringRef Keyword);
+
+  typedef llvm::SmallVector<NamedDecl *, 4>::const_iterator iterator;
+  iterator begin() const { return BestResults.begin(); }
+  iterator end() const { return BestResults.end(); }
+  void clear_decls() { BestResults.clear(); }
+  
+  bool empty() const { return BestResults.empty() && BestKeywords.empty(); }
+
+  typedef llvm::SmallVector<IdentifierInfo *, 4>::const_iterator
+    keyword_iterator;
+  keyword_iterator keyword_begin() const { return BestKeywords.begin(); }
+  keyword_iterator keyword_end() const { return BestKeywords.end(); }
+  bool keyword_empty() const { return BestKeywords.empty(); }
+  unsigned keyword_size() const { return BestKeywords.size(); }
+  
+  unsigned getBestEditDistance() const { return BestEditDistance; }  
+};
+
+}
+
+void TypoCorrectionConsumer::FoundDecl(NamedDecl *ND, NamedDecl *Hiding, 
+                                       bool InBaseClass) {
+  // Don't consider hidden names for typo correction.
+  if (Hiding)
+    return;
+  
+  // Only consider entities with identifiers for names, ignoring
+  // special names (constructors, overloaded operators, selectors,
+  // etc.).
+  IdentifierInfo *Name = ND->getIdentifier();
+  if (!Name)
+    return;
+
+  // Compute the edit distance between the typo and the name of this
+  // entity. If this edit distance is not worse than the best edit
+  // distance we've seen so far, add it to the list of results.
+  unsigned ED = Typo.edit_distance(Name->getName());
+  if (!BestResults.empty() || !BestKeywords.empty()) {
+    if (ED < BestEditDistance) {
+      // This result is better than any we've seen before; clear out
+      // the previous results.
+      BestResults.clear();
+      BestKeywords.clear();
+      BestEditDistance = ED;
+    } else if (ED > BestEditDistance) {
+      // This result is worse than the best results we've seen so far;
+      // ignore it.
+      return;
+    }
+  } else
+    BestEditDistance = ED;
+
+  BestResults.push_back(ND);
+}
+
+void TypoCorrectionConsumer::addKeywordResult(ASTContext &Context, 
+                                              llvm::StringRef Keyword) {
+  // Compute the edit distance between the typo and this keyword.
+  // If this edit distance is not worse than the best edit
+  // distance we've seen so far, add it to the list of results.
+  unsigned ED = Typo.edit_distance(Keyword);
+  if (!BestResults.empty() || !BestKeywords.empty()) {
+    if (ED < BestEditDistance) {
+      BestResults.clear();
+      BestKeywords.clear();
+      BestEditDistance = ED;
+    } else if (ED > BestEditDistance) {
+      // This result is worse than the best results we've seen so far;
+      // ignore it.
+      return;
+    }
+  } else
+    BestEditDistance = ED;
+  
+  BestKeywords.push_back(&Context.Idents.get(Keyword));
+}
+
+/// \brief Try to "correct" a typo in the source code by finding
+/// visible declarations whose names are similar to the name that was
+/// present in the source code.
+///
+/// \param Res the \c LookupResult structure that contains the name
+/// that was present in the source code along with the name-lookup
+/// criteria used to search for the name. On success, this structure
+/// will contain the results of name lookup.
+///
+/// \param S the scope in which name lookup occurs.
+///
+/// \param SS the nested-name-specifier that precedes the name we're
+/// looking for, if present.
+///
+/// \param MemberContext if non-NULL, the context in which to look for
+/// a member access expression.
+///
+/// \param EnteringContext whether we're entering the context described by 
+/// the nested-name-specifier SS.
+///
+/// \param CTC The context in which typo correction occurs, which impacts the
+/// set of keywords permitted.
+///
+/// \param OPT when non-NULL, the search for visible declarations will
+/// also walk the protocols in the qualified interfaces of \p OPT.
+///
+/// \returns the corrected name if the typo was corrected, otherwise returns an
+/// empty \c DeclarationName. When a typo was corrected, the result structure
+/// may contain the results of name lookup for the correct name or it may be
+/// empty.
+DeclarationName Sema::CorrectTypo(LookupResult &Res, Scope *S, CXXScopeSpec *SS,
+                                  DeclContext *MemberContext, 
+                                  bool EnteringContext,
+                                  CorrectTypoContext CTC,
+                                  const ObjCObjectPointerType *OPT) {
+  if (Diags.hasFatalErrorOccurred())
+    return DeclarationName();
+
+  // Provide a stop gap for files that are just seriously broken.  Trying
+  // to correct all typos can turn into a HUGE performance penalty, causing
+  // some files to take minutes to get rejected by the parser.
+  // FIXME: Is this the right solution?
+  if (TyposCorrected == 20)
+    return DeclarationName();
+  ++TyposCorrected;
+  
+  // We only attempt to correct typos for identifiers.
+  IdentifierInfo *Typo = Res.getLookupName().getAsIdentifierInfo();
+  if (!Typo)
+    return DeclarationName();
+
+  // If the scope specifier itself was invalid, don't try to correct
+  // typos.
+  if (SS && SS->isInvalid())
+    return DeclarationName();
+
+  // Never try to correct typos during template deduction or
+  // instantiation.
+  if (!ActiveTemplateInstantiations.empty())
+    return DeclarationName();
+  
+  TypoCorrectionConsumer Consumer(Typo);
+  
+  // Perform name lookup to find visible, similarly-named entities.
+  if (MemberContext) {
+    LookupVisibleDecls(MemberContext, Res.getLookupKind(), Consumer);
+
+    // Look in qualified interfaces.
+    if (OPT) {
+      for (ObjCObjectPointerType::qual_iterator 
+             I = OPT->qual_begin(), E = OPT->qual_end(); 
+           I != E; ++I)
+        LookupVisibleDecls(*I, Res.getLookupKind(), Consumer);
+    }
+  } else if (SS && SS->isSet()) {
+    DeclContext *DC = computeDeclContext(*SS, EnteringContext);
+    if (!DC)
+      return DeclarationName();
+    
+    LookupVisibleDecls(DC, Res.getLookupKind(), Consumer);
+  } else {
+    LookupVisibleDecls(S, Res.getLookupKind(), Consumer);
+  }
+
+  // Add context-dependent keywords.
+  bool WantTypeSpecifiers = false;
+  bool WantExpressionKeywords = false;
+  bool WantCXXNamedCasts = false;
+  bool WantRemainingKeywords = false;
+  switch (CTC) {
+    case CTC_Unknown:
+      WantTypeSpecifiers = true;
+      WantExpressionKeywords = true;
+      WantCXXNamedCasts = true;
+      WantRemainingKeywords = true;
+      break;
+  
+    case CTC_NoKeywords:
+      break;
+  
+    case CTC_Type:
+      WantTypeSpecifiers = true;
+      break;
+      
+    case CTC_ObjCMessageReceiver:
+      Consumer.addKeywordResult(Context, "super");
+      // Fall through to handle message receivers like expressions.
+      
+    case CTC_Expression:
+      if (getLangOptions().CPlusPlus)
+        WantTypeSpecifiers = true;
+      WantExpressionKeywords = true;
+      // Fall through to get C++ named casts.
+      
+    case CTC_CXXCasts:
+      WantCXXNamedCasts = true;
+      break;
+      
+    case CTC_MemberLookup:
+      if (getLangOptions().CPlusPlus)
+        Consumer.addKeywordResult(Context, "template");
+      break;
+  }
+
+  if (WantTypeSpecifiers) {
+    // Add type-specifier keywords to the set of results.
+    const char *CTypeSpecs[] = {
+      "char", "const", "double", "enum", "float", "int", "long", "short",
+      "signed", "struct", "union", "unsigned", "void", "volatile", "_Bool",
+      "_Complex", "_Imaginary",
+      // storage-specifiers as well
+      "extern", "inline", "static", "typedef"
+    };
+    
+    const unsigned NumCTypeSpecs = sizeof(CTypeSpecs) / sizeof(CTypeSpecs[0]);
+    for (unsigned I = 0; I != NumCTypeSpecs; ++I)
+      Consumer.addKeywordResult(Context, CTypeSpecs[I]);
+    
+    if (getLangOptions().C99)
+      Consumer.addKeywordResult(Context, "restrict");
+    if (getLangOptions().Bool || getLangOptions().CPlusPlus)
+      Consumer.addKeywordResult(Context, "bool");
+    
+    if (getLangOptions().CPlusPlus) {
+      Consumer.addKeywordResult(Context, "class");
+      Consumer.addKeywordResult(Context, "typename");
+      Consumer.addKeywordResult(Context, "wchar_t");
+      
+      if (getLangOptions().CPlusPlus0x) {
+        Consumer.addKeywordResult(Context, "char16_t");
+        Consumer.addKeywordResult(Context, "char32_t");
+        Consumer.addKeywordResult(Context, "constexpr");
+        Consumer.addKeywordResult(Context, "decltype");
+        Consumer.addKeywordResult(Context, "thread_local");
+      }      
+    }
+        
+    if (getLangOptions().GNUMode)
+      Consumer.addKeywordResult(Context, "typeof");
+  }
+  
+  if (WantCXXNamedCasts) {
+    Consumer.addKeywordResult(Context, "const_cast");
+    Consumer.addKeywordResult(Context, "dynamic_cast");
+    Consumer.addKeywordResult(Context, "reinterpret_cast");
+    Consumer.addKeywordResult(Context, "static_cast");
+  }
+  
+  if (WantExpressionKeywords) {
+    Consumer.addKeywordResult(Context, "sizeof");
+    if (getLangOptions().Bool || getLangOptions().CPlusPlus) {
+      Consumer.addKeywordResult(Context, "false");
+      Consumer.addKeywordResult(Context, "true");
+    }
+    
+    if (getLangOptions().CPlusPlus) {
+      const char *CXXExprs[] = { 
+        "delete", "new", "operator", "throw", "typeid" 
+      };
+      const unsigned NumCXXExprs = sizeof(CXXExprs) / sizeof(CXXExprs[0]);
+      for (unsigned I = 0; I != NumCXXExprs; ++I)
+        Consumer.addKeywordResult(Context, CXXExprs[I]);
+      
+      if (isa<CXXMethodDecl>(CurContext) &&
+          cast<CXXMethodDecl>(CurContext)->isInstance())
+        Consumer.addKeywordResult(Context, "this");
+      
+      if (getLangOptions().CPlusPlus0x) {
+        Consumer.addKeywordResult(Context, "alignof");
+        Consumer.addKeywordResult(Context, "nullptr");
+      }
+    }
+  }
+  
+  if (WantRemainingKeywords) {
+    if (getCurFunctionOrMethodDecl() || getCurBlock()) {
+      // Statements.
+      const char *CStmts[] = {
+        "do", "else", "for", "goto", "if", "return", "switch", "while" };
+      const unsigned NumCStmts = sizeof(CStmts) / sizeof(CStmts[0]);
+      for (unsigned I = 0; I != NumCStmts; ++I)
+        Consumer.addKeywordResult(Context, CStmts[I]);
+      
+      if (getLangOptions().CPlusPlus) {
+        Consumer.addKeywordResult(Context, "catch");
+        Consumer.addKeywordResult(Context, "try");
+      }
+      
+      if (S && S->getBreakParent())
+        Consumer.addKeywordResult(Context, "break");
+      
+      if (S && S->getContinueParent())
+        Consumer.addKeywordResult(Context, "continue");
+      
+      if (!getSwitchStack().empty()) {
+        Consumer.addKeywordResult(Context, "case");
+        Consumer.addKeywordResult(Context, "default");
+      }
+    } else {
+      if (getLangOptions().CPlusPlus) {
+        Consumer.addKeywordResult(Context, "namespace");
+        Consumer.addKeywordResult(Context, "template");
+      }
+
+      if (S && S->isClassScope()) {
+        Consumer.addKeywordResult(Context, "explicit");
+        Consumer.addKeywordResult(Context, "friend");
+        Consumer.addKeywordResult(Context, "mutable");
+        Consumer.addKeywordResult(Context, "private");
+        Consumer.addKeywordResult(Context, "protected");
+        Consumer.addKeywordResult(Context, "public");
+        Consumer.addKeywordResult(Context, "virtual");
+      }
+    }
+        
+    if (getLangOptions().CPlusPlus) {
+      Consumer.addKeywordResult(Context, "using");
+
+      if (getLangOptions().CPlusPlus0x)
+        Consumer.addKeywordResult(Context, "static_assert");
+    }
+  }
+  
+  // If we haven't found anything, we're done.
+  if (Consumer.empty())
+    return DeclarationName();
+
+  // Only allow a single, closest name in the result set (it's okay to
+  // have overloads of that name, though).
+  DeclarationName BestName;
+  NamedDecl *BestIvarOrPropertyDecl = 0;
+  bool FoundIvarOrPropertyDecl = false;
+  
+  // Check all of the declaration results to find the best name so far.
+  for (TypoCorrectionConsumer::iterator I = Consumer.begin(), 
+                                     IEnd = Consumer.end();
+       I != IEnd; ++I) {
+    if (!BestName)
+      BestName = (*I)->getDeclName();
+    else if (BestName != (*I)->getDeclName())
+      return DeclarationName();
+
+    // \brief Keep track of either an Objective-C ivar or a property, but not
+    // both.
+    if (isa<ObjCIvarDecl>(*I) || isa<ObjCPropertyDecl>(*I)) {
+      if (FoundIvarOrPropertyDecl)
+        BestIvarOrPropertyDecl = 0;
+      else {
+        BestIvarOrPropertyDecl = *I;
+        FoundIvarOrPropertyDecl = true;
+      }
+    }
+  }
+
+  // Now check all of the keyword results to find the best name. 
+  switch (Consumer.keyword_size()) {
+    case 0:
+      // No keywords matched.
+      break;
+      
+    case 1:
+      // If we already have a name
+      if (!BestName) {
+        // We did not have anything previously, 
+        BestName = *Consumer.keyword_begin();
+      } else if (BestName.getAsIdentifierInfo() == *Consumer.keyword_begin()) {
+        // We have a declaration with the same name as a context-sensitive
+        // keyword. The keyword takes precedence.
+        BestIvarOrPropertyDecl = 0;
+        FoundIvarOrPropertyDecl = false;
+        Consumer.clear_decls();
+      } else {
+        // Name collision; we will not correct typos.
+        return DeclarationName();
+      }
+      break;
+      
+    default:
+      // Name collision; we will not correct typos.
+      return DeclarationName();
+  }
+  
+  // BestName is the closest viable name to what the user
+  // typed. However, to make sure that we don't pick something that's
+  // way off, make sure that the user typed at least 3 characters for
+  // each correction.
+  unsigned ED = Consumer.getBestEditDistance();
+  if (ED == 0 || !BestName.getAsIdentifierInfo() ||
+      (BestName.getAsIdentifierInfo()->getName().size() / ED) < 3)
+    return DeclarationName();
+
+  // Perform name lookup again with the name we chose, and declare
+  // success if we found something that was not ambiguous.
+  Res.clear();
+  Res.setLookupName(BestName);
+
+  // If we found an ivar or property, add that result; no further
+  // lookup is required.
+  if (BestIvarOrPropertyDecl)
+    Res.addDecl(BestIvarOrPropertyDecl);  
+  // If we're looking into the context of a member, perform qualified
+  // name lookup on the best name.
+  else if (!Consumer.keyword_empty()) {
+    // The best match was a keyword. Return it.
+    return BestName;
+  } else if (MemberContext)
+    LookupQualifiedName(Res, MemberContext);
+  // Perform lookup as if we had just parsed the best name.
+  else
+    LookupParsedName(Res, S, SS, /*AllowBuiltinCreation=*/false, 
+                     EnteringContext);
+
+  if (Res.isAmbiguous()) {
+    Res.suppressDiagnostics();
+    return DeclarationName();
+  }
+
+  if (Res.getResultKind() != LookupResult::NotFound)
+    return BestName;
+  
+  return DeclarationName();
+}
diff --git a/lib/Sema/SemaObjCProperty.cpp b/lib/Sema/SemaObjCProperty.cpp
new file mode 100644
index 0000000..1d27e44
--- /dev/null
+++ b/lib/Sema/SemaObjCProperty.cpp
@@ -0,0 +1,1069 @@
+//===--- SemaObjCProperty.cpp - Semantic Analysis for ObjC @property ------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements semantic analysis for Objective C @property and
+//  @synthesize declarations.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Sema.h"
+
+using namespace clang;
+
+//===----------------------------------------------------------------------===//
+// Grammar actions.
+//===----------------------------------------------------------------------===//
+
+Sema::DeclPtrTy Sema::ActOnProperty(Scope *S, SourceLocation AtLoc,
+                                    FieldDeclarator &FD,
+                                    ObjCDeclSpec &ODS,
+                                    Selector GetterSel,
+                                    Selector SetterSel,
+                                    DeclPtrTy ClassCategory,
+                                    bool *isOverridingProperty,
+                                    tok::ObjCKeywordKind MethodImplKind) {
+  unsigned Attributes = ODS.getPropertyAttributes();
+  bool isReadWrite = ((Attributes & ObjCDeclSpec::DQ_PR_readwrite) ||
+                      // default is readwrite!
+                      !(Attributes & ObjCDeclSpec::DQ_PR_readonly));
+  // property is defaulted to 'assign' if it is readwrite and is
+  // not retain or copy
+  bool isAssign = ((Attributes & ObjCDeclSpec::DQ_PR_assign) ||
+                   (isReadWrite &&
+                    !(Attributes & ObjCDeclSpec::DQ_PR_retain) &&
+                    !(Attributes & ObjCDeclSpec::DQ_PR_copy)));
+
+  QualType T = GetTypeForDeclarator(FD.D, S);
+  if (T->isReferenceType()) {
+    Diag(AtLoc, diag::error_reference_property);
+    return DeclPtrTy();
+  }
+  // Proceed with constructing the ObjCPropertDecls.
+  ObjCContainerDecl *ClassDecl =
+    cast<ObjCContainerDecl>(ClassCategory.getAs<Decl>());
+
+  if (ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(ClassDecl))
+    if (CDecl->IsClassExtension())
+      return HandlePropertyInClassExtension(S, CDecl, AtLoc,
+                                            FD, GetterSel, SetterSel,
+                                            isAssign, isReadWrite,
+                                            Attributes,
+                                            isOverridingProperty, T,
+                                            MethodImplKind);
+
+  DeclPtrTy Res =  DeclPtrTy::make(CreatePropertyDecl(S, ClassDecl, AtLoc, FD,
+                                            GetterSel, SetterSel,
+                                            isAssign, isReadWrite,
+                                            Attributes, T, MethodImplKind));
+  // Validate the attributes on the @property.
+  CheckObjCPropertyAttributes(Res, AtLoc, Attributes);
+  return Res;
+}
+
+Sema::DeclPtrTy
+Sema::HandlePropertyInClassExtension(Scope *S, ObjCCategoryDecl *CDecl,
+                                     SourceLocation AtLoc, FieldDeclarator &FD,
+                                     Selector GetterSel, Selector SetterSel,
+                                     const bool isAssign,
+                                     const bool isReadWrite,
+                                     const unsigned Attributes,
+                                     bool *isOverridingProperty,
+                                     QualType T,
+                                     tok::ObjCKeywordKind MethodImplKind) {
+
+  // Diagnose if this property is already in continuation class.
+  DeclContext *DC = cast<DeclContext>(CDecl);
+  IdentifierInfo *PropertyId = FD.D.getIdentifier();
+
+  if (ObjCPropertyDecl *prevDecl =
+        ObjCPropertyDecl::findPropertyDecl(DC, PropertyId)) {
+    Diag(AtLoc, diag::err_duplicate_property);
+    Diag(prevDecl->getLocation(), diag::note_property_declare);
+    return DeclPtrTy();
+  }
+
+  // Create a new ObjCPropertyDecl with the DeclContext being
+  // the class extension.
+  ObjCPropertyDecl *PDecl =
+    ObjCPropertyDecl::Create(Context, DC, FD.D.getIdentifierLoc(),
+                             PropertyId, AtLoc, T);
+  if (Attributes & ObjCDeclSpec::DQ_PR_readonly)
+    PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readonly);
+  if (Attributes & ObjCDeclSpec::DQ_PR_readwrite)
+    PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readwrite);
+
+  DC->addDecl(PDecl);
+
+  // We need to look in the @interface to see if the @property was
+  // already declared.
+  ObjCInterfaceDecl *CCPrimary = CDecl->getClassInterface();
+  if (!CCPrimary) {
+    Diag(CDecl->getLocation(), diag::err_continuation_class);
+    *isOverridingProperty = true;
+    return DeclPtrTy();
+  }
+
+  // Find the property in continuation class's primary class only.
+  ObjCPropertyDecl *PIDecl =
+    CCPrimary->FindPropertyVisibleInPrimaryClass(PropertyId);
+
+  if (!PIDecl) {
+    // No matching property found in the primary class. Just fall thru
+    // and add property to continuation class's primary class.
+    ObjCPropertyDecl *PDecl =
+      CreatePropertyDecl(S, CCPrimary, AtLoc,
+                         FD, GetterSel, SetterSel, isAssign, isReadWrite,
+                         Attributes, T, MethodImplKind);
+
+    // A case of continuation class adding a new property in the class. This
+    // is not what it was meant for. However, gcc supports it and so should we.
+    // Make sure setter/getters are declared here.
+    ProcessPropertyDecl(PDecl, CCPrimary);
+    return DeclPtrTy::make(PDecl);
+
+  }
+
+  // The property 'PIDecl's readonly attribute will be over-ridden
+  // with continuation class's readwrite property attribute!
+  unsigned PIkind = PIDecl->getPropertyAttributes();
+  if (isReadWrite && (PIkind & ObjCPropertyDecl::OBJC_PR_readonly)) {
+    unsigned retainCopyNonatomic =
+    (ObjCPropertyDecl::OBJC_PR_retain |
+     ObjCPropertyDecl::OBJC_PR_copy |
+     ObjCPropertyDecl::OBJC_PR_nonatomic);
+    if ((Attributes & retainCopyNonatomic) !=
+        (PIkind & retainCopyNonatomic)) {
+      Diag(AtLoc, diag::warn_property_attr_mismatch);
+      Diag(PIDecl->getLocation(), diag::note_property_declare);
+    }
+    DeclContext *DC = cast<DeclContext>(CCPrimary);
+    if (!ObjCPropertyDecl::findPropertyDecl(DC,
+                                 PIDecl->getDeclName().getAsIdentifierInfo())) {
+      // Protocol is not in the primary class. Must build one for it.
+      ObjCDeclSpec ProtocolPropertyODS;
+      // FIXME. Assuming that ObjCDeclSpec::ObjCPropertyAttributeKind
+      // and ObjCPropertyDecl::PropertyAttributeKind have identical
+      // values.  Should consolidate both into one enum type.
+      ProtocolPropertyODS.
+      setPropertyAttributes((ObjCDeclSpec::ObjCPropertyAttributeKind)
+                            PIkind);
+
+      DeclPtrTy ProtocolPtrTy =
+        ActOnProperty(S, AtLoc, FD, ProtocolPropertyODS,
+                      PIDecl->getGetterName(),
+                      PIDecl->getSetterName(),
+                      DeclPtrTy::make(CCPrimary), isOverridingProperty,
+                      MethodImplKind);
+      PIDecl = cast<ObjCPropertyDecl>(ProtocolPtrTy.getAs<Decl>());
+    }
+    PIDecl->makeitReadWriteAttribute();
+    if (Attributes & ObjCDeclSpec::DQ_PR_retain)
+      PIDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_retain);
+    if (Attributes & ObjCDeclSpec::DQ_PR_copy)
+      PIDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_copy);
+    PIDecl->setSetterName(SetterSel);
+  } else {
+    Diag(AtLoc, diag::err_use_continuation_class)
+      << CCPrimary->getDeclName();
+    Diag(PIDecl->getLocation(), diag::note_property_declare);
+  }
+  *isOverridingProperty = true;
+  // Make sure setter decl is synthesized, and added to primary class's list.
+  ProcessPropertyDecl(PIDecl, CCPrimary);
+  return DeclPtrTy();
+}
+
+ObjCPropertyDecl *Sema::CreatePropertyDecl(Scope *S,
+                                           ObjCContainerDecl *CDecl,
+                                           SourceLocation AtLoc,
+                                           FieldDeclarator &FD,
+                                           Selector GetterSel,
+                                           Selector SetterSel,
+                                           const bool isAssign,
+                                           const bool isReadWrite,
+                                           const unsigned Attributes,
+                                           QualType T,
+                                           tok::ObjCKeywordKind MethodImplKind){
+
+  IdentifierInfo *PropertyId = FD.D.getIdentifier();
+
+  // Issue a warning if property is 'assign' as default and its object, which is
+  // gc'able conforms to NSCopying protocol
+  if (getLangOptions().getGCMode() != LangOptions::NonGC &&
+      isAssign && !(Attributes & ObjCDeclSpec::DQ_PR_assign))
+    if (T->isObjCObjectPointerType()) {
+      QualType InterfaceTy = T->getPointeeType();
+      if (const ObjCInterfaceType *OIT =
+          InterfaceTy->getAs<ObjCInterfaceType>()) {
+        ObjCInterfaceDecl *IDecl = OIT->getDecl();
+        if (IDecl)
+          if (ObjCProtocolDecl* PNSCopying =
+              LookupProtocol(&Context.Idents.get("NSCopying"), AtLoc))
+            if (IDecl->ClassImplementsProtocol(PNSCopying, true))
+              Diag(AtLoc, diag::warn_implements_nscopying) << PropertyId;
+      }
+    }
+  if (T->isObjCInterfaceType())
+    Diag(FD.D.getIdentifierLoc(), diag::err_statically_allocated_object);
+
+  DeclContext *DC = cast<DeclContext>(CDecl);
+  ObjCPropertyDecl *PDecl = ObjCPropertyDecl::Create(Context, DC,
+                                                     FD.D.getIdentifierLoc(),
+                                                     PropertyId, AtLoc, T);
+
+  if (ObjCPropertyDecl *prevDecl =
+        ObjCPropertyDecl::findPropertyDecl(DC, PropertyId)) {
+    Diag(PDecl->getLocation(), diag::err_duplicate_property);
+    Diag(prevDecl->getLocation(), diag::note_property_declare);
+    PDecl->setInvalidDecl();
+  }
+  else
+    DC->addDecl(PDecl);
+
+  if (T->isArrayType() || T->isFunctionType()) {
+    Diag(AtLoc, diag::err_property_type) << T;
+    PDecl->setInvalidDecl();
+  }
+
+  ProcessDeclAttributes(S, PDecl, FD.D);
+
+  // Regardless of setter/getter attribute, we save the default getter/setter
+  // selector names in anticipation of declaration of setter/getter methods.
+  PDecl->setGetterName(GetterSel);
+  PDecl->setSetterName(SetterSel);
+
+  if (Attributes & ObjCDeclSpec::DQ_PR_readonly)
+    PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readonly);
+
+  if (Attributes & ObjCDeclSpec::DQ_PR_getter)
+    PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_getter);
+
+  if (Attributes & ObjCDeclSpec::DQ_PR_setter)
+    PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_setter);
+
+  if (isReadWrite)
+    PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readwrite);
+
+  if (Attributes & ObjCDeclSpec::DQ_PR_retain)
+    PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_retain);
+
+  if (Attributes & ObjCDeclSpec::DQ_PR_copy)
+    PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_copy);
+
+  if (isAssign)
+    PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_assign);
+
+  if (Attributes & ObjCDeclSpec::DQ_PR_nonatomic)
+    PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_nonatomic);
+
+  if (MethodImplKind == tok::objc_required)
+    PDecl->setPropertyImplementation(ObjCPropertyDecl::Required);
+  else if (MethodImplKind == tok::objc_optional)
+    PDecl->setPropertyImplementation(ObjCPropertyDecl::Optional);
+
+  return PDecl;
+}
+
+
+/// ActOnPropertyImplDecl - This routine performs semantic checks and
+/// builds the AST node for a property implementation declaration; declared
+/// as @synthesize or @dynamic.
+///
+Sema::DeclPtrTy Sema::ActOnPropertyImplDecl(SourceLocation AtLoc,
+                                            SourceLocation PropertyLoc,
+                                            bool Synthesize,
+                                            DeclPtrTy ClassCatImpDecl,
+                                            IdentifierInfo *PropertyId,
+                                            IdentifierInfo *PropertyIvar) {
+  ObjCContainerDecl *ClassImpDecl =
+    cast_or_null<ObjCContainerDecl>(ClassCatImpDecl.getAs<Decl>());
+  // Make sure we have a context for the property implementation declaration.
+  if (!ClassImpDecl) {
+    Diag(AtLoc, diag::error_missing_property_context);
+    return DeclPtrTy();
+  }
+  ObjCPropertyDecl *property = 0;
+  ObjCInterfaceDecl* IDecl = 0;
+  // Find the class or category class where this property must have
+  // a declaration.
+  ObjCImplementationDecl *IC = 0;
+  ObjCCategoryImplDecl* CatImplClass = 0;
+  if ((IC = dyn_cast<ObjCImplementationDecl>(ClassImpDecl))) {
+    IDecl = IC->getClassInterface();
+    // We always synthesize an interface for an implementation
+    // without an interface decl. So, IDecl is always non-zero.
+    assert(IDecl &&
+           "ActOnPropertyImplDecl - @implementation without @interface");
+
+    // Look for this property declaration in the @implementation's @interface
+    property = IDecl->FindPropertyDeclaration(PropertyId);
+    if (!property) {
+      Diag(PropertyLoc, diag::error_bad_property_decl) << IDecl->getDeclName();
+      return DeclPtrTy();
+    }
+    if (const ObjCCategoryDecl *CD =
+        dyn_cast<ObjCCategoryDecl>(property->getDeclContext())) {
+      if (!CD->IsClassExtension()) {
+        Diag(PropertyLoc, diag::error_category_property) << CD->getDeclName();
+        Diag(property->getLocation(), diag::note_property_declare);
+        return DeclPtrTy();
+      }
+    }
+  } else if ((CatImplClass = dyn_cast<ObjCCategoryImplDecl>(ClassImpDecl))) {
+    if (Synthesize) {
+      Diag(AtLoc, diag::error_synthesize_category_decl);
+      return DeclPtrTy();
+    }
+    IDecl = CatImplClass->getClassInterface();
+    if (!IDecl) {
+      Diag(AtLoc, diag::error_missing_property_interface);
+      return DeclPtrTy();
+    }
+    ObjCCategoryDecl *Category =
+    IDecl->FindCategoryDeclaration(CatImplClass->getIdentifier());
+
+    // If category for this implementation not found, it is an error which
+    // has already been reported eralier.
+    if (!Category)
+      return DeclPtrTy();
+    // Look for this property declaration in @implementation's category
+    property = Category->FindPropertyDeclaration(PropertyId);
+    if (!property) {
+      Diag(PropertyLoc, diag::error_bad_category_property_decl)
+      << Category->getDeclName();
+      return DeclPtrTy();
+    }
+  } else {
+    Diag(AtLoc, diag::error_bad_property_context);
+    return DeclPtrTy();
+  }
+  ObjCIvarDecl *Ivar = 0;
+  // Check that we have a valid, previously declared ivar for @synthesize
+  if (Synthesize) {
+    // @synthesize
+    if (!PropertyIvar)
+      PropertyIvar = PropertyId;
+    QualType PropType = Context.getCanonicalType(property->getType());
+    // Check that this is a previously declared 'ivar' in 'IDecl' interface
+    ObjCInterfaceDecl *ClassDeclared;
+    Ivar = IDecl->lookupInstanceVariable(PropertyIvar, ClassDeclared);
+    if (!Ivar) {
+      Ivar = ObjCIvarDecl::Create(Context, ClassImpDecl, PropertyLoc,
+                                  PropertyIvar, PropType, /*Dinfo=*/0,
+                                  ObjCIvarDecl::Protected,
+                                  (Expr *)0);
+      ClassImpDecl->addDecl(Ivar);
+      IDecl->makeDeclVisibleInContext(Ivar, false);
+      property->setPropertyIvarDecl(Ivar);
+
+      if (!getLangOptions().ObjCNonFragileABI)
+        Diag(PropertyLoc, diag::error_missing_property_ivar_decl) << PropertyId;
+      // Note! I deliberately want it to fall thru so, we have a
+      // a property implementation and to avoid future warnings.
+    } else if (getLangOptions().ObjCNonFragileABI &&
+               ClassDeclared != IDecl) {
+      Diag(PropertyLoc, diag::error_ivar_in_superclass_use)
+      << property->getDeclName() << Ivar->getDeclName()
+      << ClassDeclared->getDeclName();
+      Diag(Ivar->getLocation(), diag::note_previous_access_declaration)
+      << Ivar << Ivar->getNameAsCString();
+      // Note! I deliberately want it to fall thru so more errors are caught.
+    }
+    QualType IvarType = Context.getCanonicalType(Ivar->getType());
+
+    // Check that type of property and its ivar are type compatible.
+    if (PropType != IvarType) {
+      if (CheckAssignmentConstraints(PropType, IvarType) != Compatible) {
+        Diag(PropertyLoc, diag::error_property_ivar_type)
+          << property->getDeclName() << PropType
+          << Ivar->getDeclName() << IvarType;
+        Diag(Ivar->getLocation(), diag::note_ivar_decl);
+        // Note! I deliberately want it to fall thru so, we have a
+        // a property implementation and to avoid future warnings.
+      }
+
+      // FIXME! Rules for properties are somewhat different that those
+      // for assignments. Use a new routine to consolidate all cases;
+      // specifically for property redeclarations as well as for ivars.
+      QualType lhsType =Context.getCanonicalType(PropType).getUnqualifiedType();
+      QualType rhsType =Context.getCanonicalType(IvarType).getUnqualifiedType();
+      if (lhsType != rhsType &&
+          lhsType->isArithmeticType()) {
+        Diag(PropertyLoc, diag::error_property_ivar_type)
+          << property->getDeclName() << PropType
+          << Ivar->getDeclName() << IvarType;
+        Diag(Ivar->getLocation(), diag::note_ivar_decl);
+        // Fall thru - see previous comment
+      }
+      // __weak is explicit. So it works on Canonical type.
+      if (PropType.isObjCGCWeak() && !IvarType.isObjCGCWeak() &&
+          getLangOptions().getGCMode() != LangOptions::NonGC) {
+        Diag(PropertyLoc, diag::error_weak_property)
+        << property->getDeclName() << Ivar->getDeclName();
+        // Fall thru - see previous comment
+      }
+      if ((property->getType()->isObjCObjectPointerType() ||
+           PropType.isObjCGCStrong()) && IvarType.isObjCGCWeak() &&
+          getLangOptions().getGCMode() != LangOptions::NonGC) {
+        Diag(PropertyLoc, diag::error_strong_property)
+        << property->getDeclName() << Ivar->getDeclName();
+        // Fall thru - see previous comment
+      }
+    }
+  } else if (PropertyIvar)
+    // @dynamic
+    Diag(PropertyLoc, diag::error_dynamic_property_ivar_decl);
+  assert (property && "ActOnPropertyImplDecl - property declaration missing");
+  ObjCPropertyImplDecl *PIDecl =
+  ObjCPropertyImplDecl::Create(Context, CurContext, AtLoc, PropertyLoc,
+                               property,
+                               (Synthesize ?
+                                ObjCPropertyImplDecl::Synthesize
+                                : ObjCPropertyImplDecl::Dynamic),
+                               Ivar);
+  if (IC) {
+    if (Synthesize)
+      if (ObjCPropertyImplDecl *PPIDecl =
+          IC->FindPropertyImplIvarDecl(PropertyIvar)) {
+        Diag(PropertyLoc, diag::error_duplicate_ivar_use)
+        << PropertyId << PPIDecl->getPropertyDecl()->getIdentifier()
+        << PropertyIvar;
+        Diag(PPIDecl->getLocation(), diag::note_previous_use);
+      }
+
+    if (ObjCPropertyImplDecl *PPIDecl
+        = IC->FindPropertyImplDecl(PropertyId)) {
+      Diag(PropertyLoc, diag::error_property_implemented) << PropertyId;
+      Diag(PPIDecl->getLocation(), diag::note_previous_declaration);
+      return DeclPtrTy();
+    }
+    IC->addPropertyImplementation(PIDecl);
+  } else {
+    if (Synthesize)
+      if (ObjCPropertyImplDecl *PPIDecl =
+          CatImplClass->FindPropertyImplIvarDecl(PropertyIvar)) {
+        Diag(PropertyLoc, diag::error_duplicate_ivar_use)
+        << PropertyId << PPIDecl->getPropertyDecl()->getIdentifier()
+        << PropertyIvar;
+        Diag(PPIDecl->getLocation(), diag::note_previous_use);
+      }
+
+    if (ObjCPropertyImplDecl *PPIDecl =
+        CatImplClass->FindPropertyImplDecl(PropertyId)) {
+      Diag(PropertyLoc, diag::error_property_implemented) << PropertyId;
+      Diag(PPIDecl->getLocation(), diag::note_previous_declaration);
+      return DeclPtrTy();
+    }
+    CatImplClass->addPropertyImplementation(PIDecl);
+  }
+
+  return DeclPtrTy::make(PIDecl);
+}
+
+//===----------------------------------------------------------------------===//
+// Helper methods.
+//===----------------------------------------------------------------------===//
+
+/// DiagnosePropertyMismatch - Compares two properties for their
+/// attributes and types and warns on a variety of inconsistencies.
+///
+void
+Sema::DiagnosePropertyMismatch(ObjCPropertyDecl *Property,
+                               ObjCPropertyDecl *SuperProperty,
+                               const IdentifierInfo *inheritedName) {
+  ObjCPropertyDecl::PropertyAttributeKind CAttr =
+  Property->getPropertyAttributes();
+  ObjCPropertyDecl::PropertyAttributeKind SAttr =
+  SuperProperty->getPropertyAttributes();
+  if ((CAttr & ObjCPropertyDecl::OBJC_PR_readonly)
+      && (SAttr & ObjCPropertyDecl::OBJC_PR_readwrite))
+    Diag(Property->getLocation(), diag::warn_readonly_property)
+      << Property->getDeclName() << inheritedName;
+  if ((CAttr & ObjCPropertyDecl::OBJC_PR_copy)
+      != (SAttr & ObjCPropertyDecl::OBJC_PR_copy))
+    Diag(Property->getLocation(), diag::warn_property_attribute)
+      << Property->getDeclName() << "copy" << inheritedName;
+  else if ((CAttr & ObjCPropertyDecl::OBJC_PR_retain)
+           != (SAttr & ObjCPropertyDecl::OBJC_PR_retain))
+    Diag(Property->getLocation(), diag::warn_property_attribute)
+      << Property->getDeclName() << "retain" << inheritedName;
+
+  if ((CAttr & ObjCPropertyDecl::OBJC_PR_nonatomic)
+      != (SAttr & ObjCPropertyDecl::OBJC_PR_nonatomic))
+    Diag(Property->getLocation(), diag::warn_property_attribute)
+      << Property->getDeclName() << "atomic" << inheritedName;
+  if (Property->getSetterName() != SuperProperty->getSetterName())
+    Diag(Property->getLocation(), diag::warn_property_attribute)
+      << Property->getDeclName() << "setter" << inheritedName;
+  if (Property->getGetterName() != SuperProperty->getGetterName())
+    Diag(Property->getLocation(), diag::warn_property_attribute)
+      << Property->getDeclName() << "getter" << inheritedName;
+
+  QualType LHSType =
+    Context.getCanonicalType(SuperProperty->getType());
+  QualType RHSType =
+    Context.getCanonicalType(Property->getType());
+
+  if (!Context.typesAreCompatible(LHSType, RHSType)) {
+    // FIXME: Incorporate this test with typesAreCompatible.
+    if (LHSType->isObjCQualifiedIdType() && RHSType->isObjCQualifiedIdType())
+      if (Context.ObjCQualifiedIdTypesAreCompatible(LHSType, RHSType, false))
+        return;
+    Diag(Property->getLocation(), diag::warn_property_types_are_incompatible)
+      << Property->getType() << SuperProperty->getType() << inheritedName;
+  }
+}
+
+bool Sema::DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *property,
+                                            ObjCMethodDecl *GetterMethod,
+                                            SourceLocation Loc) {
+  if (GetterMethod &&
+      GetterMethod->getResultType() != property->getType()) {
+    AssignConvertType result = Incompatible;
+    if (property->getType()->isObjCObjectPointerType())
+      result = CheckAssignmentConstraints(GetterMethod->getResultType(),
+                                          property->getType());
+    if (result != Compatible) {
+      Diag(Loc, diag::warn_accessor_property_type_mismatch)
+      << property->getDeclName()
+      << GetterMethod->getSelector();
+      Diag(GetterMethod->getLocation(), diag::note_declared_at);
+      return true;
+    }
+  }
+  return false;
+}
+
+/// ComparePropertiesInBaseAndSuper - This routine compares property
+/// declarations in base and its super class, if any, and issues
+/// diagnostics in a variety of inconsistant situations.
+///
+void Sema::ComparePropertiesInBaseAndSuper(ObjCInterfaceDecl *IDecl) {
+  ObjCInterfaceDecl *SDecl = IDecl->getSuperClass();
+  if (!SDecl)
+    return;
+  // FIXME: O(N^2)
+  for (ObjCInterfaceDecl::prop_iterator S = SDecl->prop_begin(),
+       E = SDecl->prop_end(); S != E; ++S) {
+    ObjCPropertyDecl *SuperPDecl = (*S);
+    // Does property in super class has declaration in current class?
+    for (ObjCInterfaceDecl::prop_iterator I = IDecl->prop_begin(),
+         E = IDecl->prop_end(); I != E; ++I) {
+      ObjCPropertyDecl *PDecl = (*I);
+      if (SuperPDecl->getIdentifier() == PDecl->getIdentifier())
+          DiagnosePropertyMismatch(PDecl, SuperPDecl,
+                                   SDecl->getIdentifier());
+    }
+  }
+}
+
+/// MatchOneProtocolPropertiesInClass - This routine goes thru the list
+/// of properties declared in a protocol and compares their attribute against
+/// the same property declared in the class or category.
+void
+Sema::MatchOneProtocolPropertiesInClass(Decl *CDecl,
+                                          ObjCProtocolDecl *PDecl) {
+  ObjCInterfaceDecl *IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(CDecl);
+  if (!IDecl) {
+    // Category
+    ObjCCategoryDecl *CatDecl = static_cast<ObjCCategoryDecl*>(CDecl);
+    assert (CatDecl && "MatchOneProtocolPropertiesInClass");
+    if (!CatDecl->IsClassExtension())
+      for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(),
+           E = PDecl->prop_end(); P != E; ++P) {
+        ObjCPropertyDecl *Pr = (*P);
+        ObjCCategoryDecl::prop_iterator CP, CE;
+        // Is this property already in  category's list of properties?
+        for (CP = CatDecl->prop_begin(), CE = CatDecl->prop_end(); CP!=CE; ++CP)
+          if ((*CP)->getIdentifier() == Pr->getIdentifier())
+            break;
+        if (CP != CE)
+          // Property protocol already exist in class. Diagnose any mismatch.
+          DiagnosePropertyMismatch((*CP), Pr, PDecl->getIdentifier());
+      }
+    return;
+  }
+  for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(),
+       E = PDecl->prop_end(); P != E; ++P) {
+    ObjCPropertyDecl *Pr = (*P);
+    ObjCInterfaceDecl::prop_iterator CP, CE;
+    // Is this property already in  class's list of properties?
+    for (CP = IDecl->prop_begin(), CE = IDecl->prop_end(); CP != CE; ++CP)
+      if ((*CP)->getIdentifier() == Pr->getIdentifier())
+        break;
+    if (CP != CE)
+      // Property protocol already exist in class. Diagnose any mismatch.
+      DiagnosePropertyMismatch((*CP), Pr, PDecl->getIdentifier());
+    }
+}
+
+/// CompareProperties - This routine compares properties
+/// declared in 'ClassOrProtocol' objects (which can be a class or an
+/// inherited protocol with the list of properties for class/category 'CDecl'
+///
+void Sema::CompareProperties(Decl *CDecl,
+                             DeclPtrTy ClassOrProtocol) {
+  Decl *ClassDecl = ClassOrProtocol.getAs<Decl>();
+  ObjCInterfaceDecl *IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(CDecl);
+
+  if (!IDecl) {
+    // Category
+    ObjCCategoryDecl *CatDecl = static_cast<ObjCCategoryDecl*>(CDecl);
+    assert (CatDecl && "CompareProperties");
+    if (ObjCCategoryDecl *MDecl = dyn_cast<ObjCCategoryDecl>(ClassDecl)) {
+      for (ObjCCategoryDecl::protocol_iterator P = MDecl->protocol_begin(),
+           E = MDecl->protocol_end(); P != E; ++P)
+      // Match properties of category with those of protocol (*P)
+      MatchOneProtocolPropertiesInClass(CatDecl, *P);
+
+      // Go thru the list of protocols for this category and recursively match
+      // their properties with those in the category.
+      for (ObjCCategoryDecl::protocol_iterator P = CatDecl->protocol_begin(),
+           E = CatDecl->protocol_end(); P != E; ++P)
+        CompareProperties(CatDecl, DeclPtrTy::make(*P));
+    } else {
+      ObjCProtocolDecl *MD = cast<ObjCProtocolDecl>(ClassDecl);
+      for (ObjCProtocolDecl::protocol_iterator P = MD->protocol_begin(),
+           E = MD->protocol_end(); P != E; ++P)
+        MatchOneProtocolPropertiesInClass(CatDecl, *P);
+    }
+    return;
+  }
+
+  if (ObjCInterfaceDecl *MDecl = dyn_cast<ObjCInterfaceDecl>(ClassDecl)) {
+    for (ObjCInterfaceDecl::protocol_iterator P = MDecl->protocol_begin(),
+         E = MDecl->protocol_end(); P != E; ++P)
+      // Match properties of class IDecl with those of protocol (*P).
+      MatchOneProtocolPropertiesInClass(IDecl, *P);
+
+    // Go thru the list of protocols for this class and recursively match
+    // their properties with those declared in the class.
+    for (ObjCInterfaceDecl::protocol_iterator P = IDecl->protocol_begin(),
+         E = IDecl->protocol_end(); P != E; ++P)
+      CompareProperties(IDecl, DeclPtrTy::make(*P));
+  } else {
+    ObjCProtocolDecl *MD = cast<ObjCProtocolDecl>(ClassDecl);
+    for (ObjCProtocolDecl::protocol_iterator P = MD->protocol_begin(),
+         E = MD->protocol_end(); P != E; ++P)
+      MatchOneProtocolPropertiesInClass(IDecl, *P);
+  }
+}
+
+/// isPropertyReadonly - Return true if property is readonly, by searching
+/// for the property in the class and in its categories and implementations
+///
+bool Sema::isPropertyReadonly(ObjCPropertyDecl *PDecl,
+                              ObjCInterfaceDecl *IDecl) {
+  // by far the most common case.
+  if (!PDecl->isReadOnly())
+    return false;
+  // Even if property is ready only, if interface has a user defined setter,
+  // it is not considered read only.
+  if (IDecl->getInstanceMethod(PDecl->getSetterName()))
+    return false;
+
+  // Main class has the property as 'readonly'. Must search
+  // through the category list to see if the property's
+  // attribute has been over-ridden to 'readwrite'.
+  for (ObjCCategoryDecl *Category = IDecl->getCategoryList();
+       Category; Category = Category->getNextClassCategory()) {
+    // Even if property is ready only, if a category has a user defined setter,
+    // it is not considered read only.
+    if (Category->getInstanceMethod(PDecl->getSetterName()))
+      return false;
+    ObjCPropertyDecl *P =
+      Category->FindPropertyDeclaration(PDecl->getIdentifier());
+    if (P && !P->isReadOnly())
+      return false;
+  }
+
+  // Also, check for definition of a setter method in the implementation if
+  // all else failed.
+  if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(CurContext)) {
+    if (ObjCImplementationDecl *IMD =
+        dyn_cast<ObjCImplementationDecl>(OMD->getDeclContext())) {
+      if (IMD->getInstanceMethod(PDecl->getSetterName()))
+        return false;
+    } else if (ObjCCategoryImplDecl *CIMD =
+               dyn_cast<ObjCCategoryImplDecl>(OMD->getDeclContext())) {
+      if (CIMD->getInstanceMethod(PDecl->getSetterName()))
+        return false;
+    }
+  }
+  // Lastly, look through the implementation (if one is in scope).
+  if (ObjCImplementationDecl *ImpDecl = IDecl->getImplementation())
+    if (ImpDecl->getInstanceMethod(PDecl->getSetterName()))
+      return false;
+  // If all fails, look at the super class.
+  if (ObjCInterfaceDecl *SIDecl = IDecl->getSuperClass())
+    return isPropertyReadonly(PDecl, SIDecl);
+  return true;
+}
+
+/// CollectImmediateProperties - This routine collects all properties in
+/// the class and its conforming protocols; but not those it its super class.
+void Sema::CollectImmediateProperties(ObjCContainerDecl *CDecl,
+                llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>& PropMap) {
+  if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl)) {
+    for (ObjCContainerDecl::prop_iterator P = IDecl->prop_begin(),
+         E = IDecl->prop_end(); P != E; ++P) {
+      ObjCPropertyDecl *Prop = (*P);
+      PropMap[Prop->getIdentifier()] = Prop;
+    }
+    // scan through class's protocols.
+    for (ObjCInterfaceDecl::protocol_iterator PI = IDecl->protocol_begin(),
+         E = IDecl->protocol_end(); PI != E; ++PI)
+      CollectImmediateProperties((*PI), PropMap);
+  }
+  if (ObjCCategoryDecl *CATDecl = dyn_cast<ObjCCategoryDecl>(CDecl)) {
+    if (!CATDecl->IsClassExtension())
+      for (ObjCContainerDecl::prop_iterator P = CATDecl->prop_begin(),
+           E = CATDecl->prop_end(); P != E; ++P) {
+        ObjCPropertyDecl *Prop = (*P);
+        PropMap[Prop->getIdentifier()] = Prop;
+      }
+    // scan through class's protocols.
+    for (ObjCInterfaceDecl::protocol_iterator PI = CATDecl->protocol_begin(),
+         E = CATDecl->protocol_end(); PI != E; ++PI)
+      CollectImmediateProperties((*PI), PropMap);
+  }
+  else if (ObjCProtocolDecl *PDecl = dyn_cast<ObjCProtocolDecl>(CDecl)) {
+    for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(),
+         E = PDecl->prop_end(); P != E; ++P) {
+      ObjCPropertyDecl *Prop = (*P);
+      ObjCPropertyDecl *&PropEntry = PropMap[Prop->getIdentifier()];
+      if (!PropEntry)
+        PropEntry = Prop;
+    }
+    // scan through protocol's protocols.
+    for (ObjCProtocolDecl::protocol_iterator PI = PDecl->protocol_begin(),
+         E = PDecl->protocol_end(); PI != E; ++PI)
+      CollectImmediateProperties((*PI), PropMap);
+  }
+}
+
+/// LookupPropertyDecl - Looks up a property in the current class and all
+/// its protocols.
+ObjCPropertyDecl *Sema::LookupPropertyDecl(const ObjCContainerDecl *CDecl,
+                                     IdentifierInfo *II) {
+  if (const ObjCInterfaceDecl *IDecl =
+        dyn_cast<ObjCInterfaceDecl>(CDecl)) {
+    for (ObjCContainerDecl::prop_iterator P = IDecl->prop_begin(),
+         E = IDecl->prop_end(); P != E; ++P) {
+      ObjCPropertyDecl *Prop = (*P);
+      if (Prop->getIdentifier() == II)
+        return Prop;
+    }
+    // scan through class's protocols.
+    for (ObjCInterfaceDecl::protocol_iterator PI = IDecl->protocol_begin(),
+         E = IDecl->protocol_end(); PI != E; ++PI) {
+      ObjCPropertyDecl *Prop = LookupPropertyDecl((*PI), II);
+      if (Prop)
+        return Prop;
+    }
+  }
+  else if (const ObjCProtocolDecl *PDecl =
+            dyn_cast<ObjCProtocolDecl>(CDecl)) {
+    for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(),
+         E = PDecl->prop_end(); P != E; ++P) {
+      ObjCPropertyDecl *Prop = (*P);
+      if (Prop->getIdentifier() == II)
+        return Prop;
+    }
+    // scan through protocol's protocols.
+    for (ObjCProtocolDecl::protocol_iterator PI = PDecl->protocol_begin(),
+         E = PDecl->protocol_end(); PI != E; ++PI) {
+      ObjCPropertyDecl *Prop = LookupPropertyDecl((*PI), II);
+      if (Prop)
+        return Prop;
+    }
+  }
+  return 0;
+}
+
+
+void Sema::DiagnoseUnimplementedProperties(ObjCImplDecl* IMPDecl,
+                                      ObjCContainerDecl *CDecl,
+                                      const llvm::DenseSet<Selector>& InsMap) {
+  llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*> PropMap;
+  CollectImmediateProperties(CDecl, PropMap);
+  if (PropMap.empty())
+    return;
+
+  llvm::DenseSet<ObjCPropertyDecl *> PropImplMap;
+  for (ObjCImplDecl::propimpl_iterator
+       I = IMPDecl->propimpl_begin(),
+       EI = IMPDecl->propimpl_end(); I != EI; ++I)
+    PropImplMap.insert((*I)->getPropertyDecl());
+
+  for (llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>::iterator
+       P = PropMap.begin(), E = PropMap.end(); P != E; ++P) {
+    ObjCPropertyDecl *Prop = P->second;
+    // Is there a matching propery synthesize/dynamic?
+    if (Prop->isInvalidDecl() ||
+        Prop->getPropertyImplementation() == ObjCPropertyDecl::Optional ||
+        PropImplMap.count(Prop))
+      continue;
+    if (LangOpts.ObjCNonFragileABI2) {
+      ActOnPropertyImplDecl(IMPDecl->getLocation(),
+                            IMPDecl->getLocation(),
+                            true, DeclPtrTy::make(IMPDecl),
+                            Prop->getIdentifier(),
+                            Prop->getIdentifier());
+      continue;
+    }
+    if (!InsMap.count(Prop->getGetterName())) {
+      Diag(Prop->getLocation(),
+           isa<ObjCCategoryDecl>(CDecl) ?
+            diag::warn_setter_getter_impl_required_in_category :
+            diag::warn_setter_getter_impl_required)
+      << Prop->getDeclName() << Prop->getGetterName();
+      Diag(IMPDecl->getLocation(),
+           diag::note_property_impl_required);
+    }
+
+    if (!Prop->isReadOnly() && !InsMap.count(Prop->getSetterName())) {
+      Diag(Prop->getLocation(),
+           isa<ObjCCategoryDecl>(CDecl) ?
+           diag::warn_setter_getter_impl_required_in_category :
+           diag::warn_setter_getter_impl_required)
+      << Prop->getDeclName() << Prop->getSetterName();
+      Diag(IMPDecl->getLocation(),
+           diag::note_property_impl_required);
+    }
+  }
+}
+
+void
+Sema::AtomicPropertySetterGetterRules (ObjCImplDecl* IMPDecl,
+                                       ObjCContainerDecl* IDecl) {
+  // Rules apply in non-GC mode only
+  if (getLangOptions().getGCMode() != LangOptions::NonGC)
+    return;
+  for (ObjCContainerDecl::prop_iterator I = IDecl->prop_begin(),
+       E = IDecl->prop_end();
+       I != E; ++I) {
+    ObjCPropertyDecl *Property = (*I);
+    unsigned Attributes = Property->getPropertyAttributes();
+    // We only care about readwrite atomic property.
+    if ((Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic) ||
+        !(Attributes & ObjCPropertyDecl::OBJC_PR_readwrite))
+      continue;
+    if (const ObjCPropertyImplDecl *PIDecl
+         = IMPDecl->FindPropertyImplDecl(Property->getIdentifier())) {
+      if (PIDecl->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
+        continue;
+      ObjCMethodDecl *GetterMethod =
+        IMPDecl->getInstanceMethod(Property->getGetterName());
+      ObjCMethodDecl *SetterMethod =
+        IMPDecl->getInstanceMethod(Property->getSetterName());
+      if ((GetterMethod && !SetterMethod) || (!GetterMethod && SetterMethod)) {
+        SourceLocation MethodLoc =
+          (GetterMethod ? GetterMethod->getLocation()
+                        : SetterMethod->getLocation());
+        Diag(MethodLoc, diag::warn_atomic_property_rule)
+          << Property->getIdentifier();
+        Diag(Property->getLocation(), diag::note_property_declare);
+      }
+    }
+  }
+}
+
+/// ProcessPropertyDecl - Make sure that any user-defined setter/getter methods
+/// have the property type and issue diagnostics if they don't.
+/// Also synthesize a getter/setter method if none exist (and update the
+/// appropriate lookup tables. FIXME: Should reconsider if adding synthesized
+/// methods is the "right" thing to do.
+void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property,
+                               ObjCContainerDecl *CD) {
+  ObjCMethodDecl *GetterMethod, *SetterMethod;
+
+  GetterMethod = CD->getInstanceMethod(property->getGetterName());
+  SetterMethod = CD->getInstanceMethod(property->getSetterName());
+  DiagnosePropertyAccessorMismatch(property, GetterMethod,
+                                   property->getLocation());
+
+  if (SetterMethod) {
+    ObjCPropertyDecl::PropertyAttributeKind CAttr =
+      property->getPropertyAttributes();
+    if ((!(CAttr & ObjCPropertyDecl::OBJC_PR_readonly)) &&
+        Context.getCanonicalType(SetterMethod->getResultType()) !=
+          Context.VoidTy)
+      Diag(SetterMethod->getLocation(), diag::err_setter_type_void);
+    if (SetterMethod->param_size() != 1 ||
+        ((*SetterMethod->param_begin())->getType() != property->getType())) {
+      Diag(property->getLocation(),
+           diag::warn_accessor_property_type_mismatch)
+        << property->getDeclName()
+        << SetterMethod->getSelector();
+      Diag(SetterMethod->getLocation(), diag::note_declared_at);
+    }
+  }
+
+  // Synthesize getter/setter methods if none exist.
+  // Find the default getter and if one not found, add one.
+  // FIXME: The synthesized property we set here is misleading. We almost always
+  // synthesize these methods unless the user explicitly provided prototypes
+  // (which is odd, but allowed). Sema should be typechecking that the
+  // declarations jive in that situation (which it is not currently).
+  if (!GetterMethod) {
+    // No instance method of same name as property getter name was found.
+    // Declare a getter method and add it to the list of methods
+    // for this class.
+    GetterMethod = ObjCMethodDecl::Create(Context, property->getLocation(),
+                             property->getLocation(), property->getGetterName(),
+                             property->getType(), 0, CD, true, false, true,
+                             (property->getPropertyImplementation() ==
+                              ObjCPropertyDecl::Optional) ?
+                             ObjCMethodDecl::Optional :
+                             ObjCMethodDecl::Required);
+    CD->addDecl(GetterMethod);
+  } else
+    // A user declared getter will be synthesize when @synthesize of
+    // the property with the same name is seen in the @implementation
+    GetterMethod->setSynthesized(true);
+  property->setGetterMethodDecl(GetterMethod);
+
+  // Skip setter if property is read-only.
+  if (!property->isReadOnly()) {
+    // Find the default setter and if one not found, add one.
+    if (!SetterMethod) {
+      // No instance method of same name as property setter name was found.
+      // Declare a setter method and add it to the list of methods
+      // for this class.
+      SetterMethod = ObjCMethodDecl::Create(Context, property->getLocation(),
+                               property->getLocation(),
+                               property->getSetterName(),
+                               Context.VoidTy, 0, CD, true, false, true,
+                               (property->getPropertyImplementation() ==
+                                ObjCPropertyDecl::Optional) ?
+                               ObjCMethodDecl::Optional :
+                               ObjCMethodDecl::Required);
+      // Invent the arguments for the setter. We don't bother making a
+      // nice name for the argument.
+      ParmVarDecl *Argument = ParmVarDecl::Create(Context, SetterMethod,
+                                                  property->getLocation(),
+                                                  property->getIdentifier(),
+                                                  property->getType(),
+                                                  /*TInfo=*/0,
+                                                  VarDecl::None,
+                                                  VarDecl::None,
+                                                  0);
+      SetterMethod->setMethodParams(Context, &Argument, 1, 1);
+      CD->addDecl(SetterMethod);
+    } else
+      // A user declared setter will be synthesize when @synthesize of
+      // the property with the same name is seen in the @implementation
+      SetterMethod->setSynthesized(true);
+    property->setSetterMethodDecl(SetterMethod);
+  }
+  // Add any synthesized methods to the global pool. This allows us to
+  // handle the following, which is supported by GCC (and part of the design).
+  //
+  // @interface Foo
+  // @property double bar;
+  // @end
+  //
+  // void thisIsUnfortunate() {
+  //   id foo;
+  //   double bar = [foo bar];
+  // }
+  //
+  if (GetterMethod)
+    AddInstanceMethodToGlobalPool(GetterMethod);
+  if (SetterMethod)
+    AddInstanceMethodToGlobalPool(SetterMethod);
+}
+
+void Sema::CheckObjCPropertyAttributes(DeclPtrTy PropertyPtrTy,
+                                       SourceLocation Loc,
+                                       unsigned &Attributes) {
+  // FIXME: Improve the reported location.
+  Decl *PDecl = PropertyPtrTy.getAs<Decl>();
+  if (!PDecl)
+    return;
+
+  ObjCPropertyDecl *PropertyDecl = cast<ObjCPropertyDecl>(PDecl);
+  QualType PropertyTy = PropertyDecl->getType(); 
+
+  // readonly and readwrite/assign/retain/copy conflict.
+  if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
+      (Attributes & (ObjCDeclSpec::DQ_PR_readwrite |
+                     ObjCDeclSpec::DQ_PR_assign |
+                     ObjCDeclSpec::DQ_PR_copy |
+                     ObjCDeclSpec::DQ_PR_retain))) {
+    const char * which = (Attributes & ObjCDeclSpec::DQ_PR_readwrite) ?
+                          "readwrite" :
+                         (Attributes & ObjCDeclSpec::DQ_PR_assign) ?
+                          "assign" :
+                         (Attributes & ObjCDeclSpec::DQ_PR_copy) ?
+                          "copy" : "retain";
+
+    Diag(Loc, (Attributes & (ObjCDeclSpec::DQ_PR_readwrite)) ?
+                 diag::err_objc_property_attr_mutually_exclusive :
+                 diag::warn_objc_property_attr_mutually_exclusive)
+      << "readonly" << which;
+  }
+
+  // Check for copy or retain on non-object types.
+  if ((Attributes & (ObjCDeclSpec::DQ_PR_copy | ObjCDeclSpec::DQ_PR_retain)) &&
+      !PropertyTy->isObjCObjectPointerType() &&
+      !PropertyTy->isBlockPointerType() &&
+      !Context.isObjCNSObjectType(PropertyTy) &&
+      !PropertyDecl->getAttr<ObjCNSObjectAttr>()) {
+    Diag(Loc, diag::err_objc_property_requires_object)
+      << (Attributes & ObjCDeclSpec::DQ_PR_copy ? "copy" : "retain");
+    Attributes &= ~(ObjCDeclSpec::DQ_PR_copy | ObjCDeclSpec::DQ_PR_retain);
+  }
+
+  // Check for more than one of { assign, copy, retain }.
+  if (Attributes & ObjCDeclSpec::DQ_PR_assign) {
+    if (Attributes & ObjCDeclSpec::DQ_PR_copy) {
+      Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
+        << "assign" << "copy";
+      Attributes &= ~ObjCDeclSpec::DQ_PR_copy;
+    }
+    if (Attributes & ObjCDeclSpec::DQ_PR_retain) {
+      Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
+        << "assign" << "retain";
+      Attributes &= ~ObjCDeclSpec::DQ_PR_retain;
+    }
+  } else if (Attributes & ObjCDeclSpec::DQ_PR_copy) {
+    if (Attributes & ObjCDeclSpec::DQ_PR_retain) {
+      Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
+        << "copy" << "retain";
+      Attributes &= ~ObjCDeclSpec::DQ_PR_retain;
+    }
+  }
+
+  // Warn if user supplied no assignment attribute, property is
+  // readwrite, and this is an object type.
+  if (!(Attributes & (ObjCDeclSpec::DQ_PR_assign | ObjCDeclSpec::DQ_PR_copy |
+                      ObjCDeclSpec::DQ_PR_retain)) &&
+      !(Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
+      PropertyTy->isObjCObjectPointerType()) {
+    // Skip this warning in gc-only mode.
+    if (getLangOptions().getGCMode() != LangOptions::GCOnly)
+      Diag(Loc, diag::warn_objc_property_no_assignment_attribute);
+
+    // If non-gc code warn that this is likely inappropriate.
+    if (getLangOptions().getGCMode() == LangOptions::NonGC)
+      Diag(Loc, diag::warn_objc_property_default_assign_on_object);
+
+    // FIXME: Implement warning dependent on NSCopying being
+    // implemented. See also:
+    // <rdar://5168496&4855821&5607453&5096644&4947311&5698469&4947014&5168496>
+    // (please trim this list while you are at it).
+  }
+
+  if (!(Attributes & ObjCDeclSpec::DQ_PR_copy)
+      && getLangOptions().getGCMode() == LangOptions::GCOnly
+      && PropertyTy->isBlockPointerType())
+    Diag(Loc, diag::warn_objc_property_copy_missing_on_block);
+}
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
new file mode 100644
index 0000000..06b5fcb
--- /dev/null
+++ b/lib/Sema/SemaOverload.cpp
@@ -0,0 +1,6981 @@
+//===--- SemaOverload.cpp - C++ Overloading ---------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides Sema routines for C++ overloading.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Sema.h"
+#include "Lookup.h"
+#include "SemaInit.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/CXXInheritance.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/TypeOrdering.h"
+#include "clang/Basic/PartialDiagnostic.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/STLExtras.h"
+#include <algorithm>
+
+namespace clang {
+
+/// GetConversionCategory - Retrieve the implicit conversion
+/// category corresponding to the given implicit conversion kind.
+ImplicitConversionCategory
+GetConversionCategory(ImplicitConversionKind Kind) {
+  static const ImplicitConversionCategory
+    Category[(int)ICK_Num_Conversion_Kinds] = {
+    ICC_Identity,
+    ICC_Lvalue_Transformation,
+    ICC_Lvalue_Transformation,
+    ICC_Lvalue_Transformation,
+    ICC_Identity,
+    ICC_Qualification_Adjustment,
+    ICC_Promotion,
+    ICC_Promotion,
+    ICC_Promotion,
+    ICC_Conversion,
+    ICC_Conversion,
+    ICC_Conversion,
+    ICC_Conversion,
+    ICC_Conversion,
+    ICC_Conversion,
+    ICC_Conversion,
+    ICC_Conversion,
+    ICC_Conversion,
+    ICC_Conversion
+  };
+  return Category[(int)Kind];
+}
+
+/// GetConversionRank - Retrieve the implicit conversion rank
+/// corresponding to the given implicit conversion kind.
+ImplicitConversionRank GetConversionRank(ImplicitConversionKind Kind) {
+  static const ImplicitConversionRank
+    Rank[(int)ICK_Num_Conversion_Kinds] = {
+    ICR_Exact_Match,
+    ICR_Exact_Match,
+    ICR_Exact_Match,
+    ICR_Exact_Match,
+    ICR_Exact_Match,
+    ICR_Exact_Match,
+    ICR_Promotion,
+    ICR_Promotion,
+    ICR_Promotion,
+    ICR_Conversion,
+    ICR_Conversion,
+    ICR_Conversion,
+    ICR_Conversion,
+    ICR_Conversion,
+    ICR_Conversion,
+    ICR_Conversion,
+    ICR_Conversion,
+    ICR_Conversion,
+    ICR_Complex_Real_Conversion
+  };
+  return Rank[(int)Kind];
+}
+
+/// GetImplicitConversionName - Return the name of this kind of
+/// implicit conversion.
+const char* GetImplicitConversionName(ImplicitConversionKind Kind) {
+  static const char* const Name[(int)ICK_Num_Conversion_Kinds] = {
+    "No conversion",
+    "Lvalue-to-rvalue",
+    "Array-to-pointer",
+    "Function-to-pointer",
+    "Noreturn adjustment",
+    "Qualification",
+    "Integral promotion",
+    "Floating point promotion",
+    "Complex promotion",
+    "Integral conversion",
+    "Floating conversion",
+    "Complex conversion",
+    "Floating-integral conversion",
+    "Complex-real conversion",
+    "Pointer conversion",
+    "Pointer-to-member conversion",
+    "Boolean conversion",
+    "Compatible-types conversion",
+    "Derived-to-base conversion"
+  };
+  return Name[Kind];
+}
+
+/// StandardConversionSequence - Set the standard conversion
+/// sequence to the identity conversion.
+void StandardConversionSequence::setAsIdentityConversion() {
+  First = ICK_Identity;
+  Second = ICK_Identity;
+  Third = ICK_Identity;
+  DeprecatedStringLiteralToCharPtr = false;
+  ReferenceBinding = false;
+  DirectBinding = false;
+  RRefBinding = false;
+  CopyConstructor = 0;
+}
+
+/// getRank - Retrieve the rank of this standard conversion sequence
+/// (C++ 13.3.3.1.1p3). The rank is the largest rank of each of the
+/// implicit conversions.
+ImplicitConversionRank StandardConversionSequence::getRank() const {
+  ImplicitConversionRank Rank = ICR_Exact_Match;
+  if  (GetConversionRank(First) > Rank)
+    Rank = GetConversionRank(First);
+  if  (GetConversionRank(Second) > Rank)
+    Rank = GetConversionRank(Second);
+  if  (GetConversionRank(Third) > Rank)
+    Rank = GetConversionRank(Third);
+  return Rank;
+}
+
+/// isPointerConversionToBool - Determines whether this conversion is
+/// a conversion of a pointer or pointer-to-member to bool. This is
+/// used as part of the ranking of standard conversion sequences
+/// (C++ 13.3.3.2p4).
+bool StandardConversionSequence::isPointerConversionToBool() const {
+  // Note that FromType has not necessarily been transformed by the
+  // array-to-pointer or function-to-pointer implicit conversions, so
+  // check for their presence as well as checking whether FromType is
+  // a pointer.
+  if (getToType(1)->isBooleanType() &&
+      (getFromType()->isPointerType() || getFromType()->isBlockPointerType() ||
+       First == ICK_Array_To_Pointer || First == ICK_Function_To_Pointer))
+    return true;
+
+  return false;
+}
+
+/// isPointerConversionToVoidPointer - Determines whether this
+/// conversion is a conversion of a pointer to a void pointer. This is
+/// used as part of the ranking of standard conversion sequences (C++
+/// 13.3.3.2p4).
+bool
+StandardConversionSequence::
+isPointerConversionToVoidPointer(ASTContext& Context) const {
+  QualType FromType = getFromType();
+  QualType ToType = getToType(1);
+
+  // Note that FromType has not necessarily been transformed by the
+  // array-to-pointer implicit conversion, so check for its presence
+  // and redo the conversion to get a pointer.
+  if (First == ICK_Array_To_Pointer)
+    FromType = Context.getArrayDecayedType(FromType);
+
+  if (Second == ICK_Pointer_Conversion && FromType->isPointerType())
+    if (const PointerType* ToPtrType = ToType->getAs<PointerType>())
+      return ToPtrType->getPointeeType()->isVoidType();
+
+  return false;
+}
+
+/// DebugPrint - Print this standard conversion sequence to standard
+/// error. Useful for debugging overloading issues.
+void StandardConversionSequence::DebugPrint() const {
+  llvm::raw_ostream &OS = llvm::errs();
+  bool PrintedSomething = false;
+  if (First != ICK_Identity) {
+    OS << GetImplicitConversionName(First);
+    PrintedSomething = true;
+  }
+
+  if (Second != ICK_Identity) {
+    if (PrintedSomething) {
+      OS << " -> ";
+    }
+    OS << GetImplicitConversionName(Second);
+
+    if (CopyConstructor) {
+      OS << " (by copy constructor)";
+    } else if (DirectBinding) {
+      OS << " (direct reference binding)";
+    } else if (ReferenceBinding) {
+      OS << " (reference binding)";
+    }
+    PrintedSomething = true;
+  }
+
+  if (Third != ICK_Identity) {
+    if (PrintedSomething) {
+      OS << " -> ";
+    }
+    OS << GetImplicitConversionName(Third);
+    PrintedSomething = true;
+  }
+
+  if (!PrintedSomething) {
+    OS << "No conversions required";
+  }
+}
+
+/// DebugPrint - Print this user-defined conversion sequence to standard
+/// error. Useful for debugging overloading issues.
+void UserDefinedConversionSequence::DebugPrint() const {
+  llvm::raw_ostream &OS = llvm::errs();
+  if (Before.First || Before.Second || Before.Third) {
+    Before.DebugPrint();
+    OS << " -> ";
+  }
+  OS << '\'' << ConversionFunction << '\'';
+  if (After.First || After.Second || After.Third) {
+    OS << " -> ";
+    After.DebugPrint();
+  }
+}
+
+/// DebugPrint - Print this implicit conversion sequence to standard
+/// error. Useful for debugging overloading issues.
+void ImplicitConversionSequence::DebugPrint() const {
+  llvm::raw_ostream &OS = llvm::errs();
+  switch (ConversionKind) {
+  case StandardConversion:
+    OS << "Standard conversion: ";
+    Standard.DebugPrint();
+    break;
+  case UserDefinedConversion:
+    OS << "User-defined conversion: ";
+    UserDefined.DebugPrint();
+    break;
+  case EllipsisConversion:
+    OS << "Ellipsis conversion";
+    break;
+  case AmbiguousConversion:
+    OS << "Ambiguous conversion";
+    break;
+  case BadConversion:
+    OS << "Bad conversion";
+    break;
+  }
+
+  OS << "\n";
+}
+
+void AmbiguousConversionSequence::construct() {
+  new (&conversions()) ConversionSet();
+}
+
+void AmbiguousConversionSequence::destruct() {
+  conversions().~ConversionSet();
+}
+
+void
+AmbiguousConversionSequence::copyFrom(const AmbiguousConversionSequence &O) {
+  FromTypePtr = O.FromTypePtr;
+  ToTypePtr = O.ToTypePtr;
+  new (&conversions()) ConversionSet(O.conversions());
+}
+
+
+// IsOverload - Determine whether the given New declaration is an
+// overload of the declarations in Old. This routine returns false if
+// New and Old cannot be overloaded, e.g., if New has the same
+// signature as some function in Old (C++ 1.3.10) or if the Old
+// declarations aren't functions (or function templates) at all. When
+// it does return false, MatchedDecl will point to the decl that New
+// cannot be overloaded with.  This decl may be a UsingShadowDecl on
+// top of the underlying declaration.
+//
+// Example: Given the following input:
+//
+//   void f(int, float); // #1
+//   void f(int, int); // #2
+//   int f(int, int); // #3
+//
+// When we process #1, there is no previous declaration of "f",
+// so IsOverload will not be used.
+//
+// When we process #2, Old contains only the FunctionDecl for #1.  By
+// comparing the parameter types, we see that #1 and #2 are overloaded
+// (since they have different signatures), so this routine returns
+// false; MatchedDecl is unchanged.
+//
+// When we process #3, Old is an overload set containing #1 and #2. We
+// compare the signatures of #3 to #1 (they're overloaded, so we do
+// nothing) and then #3 to #2. Since the signatures of #3 and #2 are
+// identical (return types of functions are not part of the
+// signature), IsOverload returns false and MatchedDecl will be set to
+// point to the FunctionDecl for #2.
+Sema::OverloadKind
+Sema::CheckOverload(FunctionDecl *New, const LookupResult &Old,
+                    NamedDecl *&Match) {
+  for (LookupResult::iterator I = Old.begin(), E = Old.end();
+         I != E; ++I) {
+    NamedDecl *OldD = (*I)->getUnderlyingDecl();
+    if (FunctionTemplateDecl *OldT = dyn_cast<FunctionTemplateDecl>(OldD)) {
+      if (!IsOverload(New, OldT->getTemplatedDecl())) {
+        Match = *I;
+        return Ovl_Match;
+      }
+    } else if (FunctionDecl *OldF = dyn_cast<FunctionDecl>(OldD)) {
+      if (!IsOverload(New, OldF)) {
+        Match = *I;
+        return Ovl_Match;
+      }
+    } else if (isa<UsingDecl>(OldD) || isa<TagDecl>(OldD)) {
+      // We can overload with these, which can show up when doing
+      // redeclaration checks for UsingDecls.
+      assert(Old.getLookupKind() == LookupUsingDeclName);
+    } else if (isa<UnresolvedUsingValueDecl>(OldD)) {
+      // Optimistically assume that an unresolved using decl will
+      // overload; if it doesn't, we'll have to diagnose during
+      // template instantiation.
+    } else {
+      // (C++ 13p1):
+      //   Only function declarations can be overloaded; object and type
+      //   declarations cannot be overloaded.
+      Match = *I;
+      return Ovl_NonFunction;
+    }
+  }
+
+  return Ovl_Overload;
+}
+
+bool Sema::IsOverload(FunctionDecl *New, FunctionDecl *Old) {
+  FunctionTemplateDecl *OldTemplate = Old->getDescribedFunctionTemplate();
+  FunctionTemplateDecl *NewTemplate = New->getDescribedFunctionTemplate();
+
+  // C++ [temp.fct]p2:
+  //   A function template can be overloaded with other function templates
+  //   and with normal (non-template) functions.
+  if ((OldTemplate == 0) != (NewTemplate == 0))
+    return true;
+
+  // Is the function New an overload of the function Old?
+  QualType OldQType = Context.getCanonicalType(Old->getType());
+  QualType NewQType = Context.getCanonicalType(New->getType());
+
+  // Compare the signatures (C++ 1.3.10) of the two functions to
+  // determine whether they are overloads. If we find any mismatch
+  // in the signature, they are overloads.
+
+  // If either of these functions is a K&R-style function (no
+  // prototype), then we consider them to have matching signatures.
+  if (isa<FunctionNoProtoType>(OldQType.getTypePtr()) ||
+      isa<FunctionNoProtoType>(NewQType.getTypePtr()))
+    return false;
+
+  FunctionProtoType* OldType = cast<FunctionProtoType>(OldQType);
+  FunctionProtoType* NewType = cast<FunctionProtoType>(NewQType);
+
+  // The signature of a function includes the types of its
+  // parameters (C++ 1.3.10), which includes the presence or absence
+  // of the ellipsis; see C++ DR 357).
+  if (OldQType != NewQType &&
+      (OldType->getNumArgs() != NewType->getNumArgs() ||
+       OldType->isVariadic() != NewType->isVariadic() ||
+       !std::equal(OldType->arg_type_begin(), OldType->arg_type_end(),
+                   NewType->arg_type_begin())))
+    return true;
+
+  // C++ [temp.over.link]p4:
+  //   The signature of a function template consists of its function
+  //   signature, its return type and its template parameter list. The names
+  //   of the template parameters are significant only for establishing the
+  //   relationship between the template parameters and the rest of the
+  //   signature.
+  //
+  // We check the return type and template parameter lists for function
+  // templates first; the remaining checks follow.
+  if (NewTemplate &&
+      (!TemplateParameterListsAreEqual(NewTemplate->getTemplateParameters(),
+                                       OldTemplate->getTemplateParameters(),
+                                       false, TPL_TemplateMatch) ||
+       OldType->getResultType() != NewType->getResultType()))
+    return true;
+
+  // If the function is a class member, its signature includes the
+  // cv-qualifiers (if any) on the function itself.
+  //
+  // As part of this, also check whether one of the member functions
+  // is static, in which case they are not overloads (C++
+  // 13.1p2). While not part of the definition of the signature,
+  // this check is important to determine whether these functions
+  // can be overloaded.
+  CXXMethodDecl* OldMethod = dyn_cast<CXXMethodDecl>(Old);
+  CXXMethodDecl* NewMethod = dyn_cast<CXXMethodDecl>(New);
+  if (OldMethod && NewMethod &&
+      !OldMethod->isStatic() && !NewMethod->isStatic() &&
+      OldMethod->getTypeQualifiers() != NewMethod->getTypeQualifiers())
+    return true;
+  
+  // The signatures match; this is not an overload.
+  return false;
+}
+
+/// TryImplicitConversion - Attempt to perform an implicit conversion
+/// from the given expression (Expr) to the given type (ToType). This
+/// function returns an implicit conversion sequence that can be used
+/// to perform the initialization. Given
+///
+///   void f(float f);
+///   void g(int i) { f(i); }
+///
+/// this routine would produce an implicit conversion sequence to
+/// describe the initialization of f from i, which will be a standard
+/// conversion sequence containing an lvalue-to-rvalue conversion (C++
+/// 4.1) followed by a floating-integral conversion (C++ 4.9).
+//
+/// Note that this routine only determines how the conversion can be
+/// performed; it does not actually perform the conversion. As such,
+/// it will not produce any diagnostics if no conversion is available,
+/// but will instead return an implicit conversion sequence of kind
+/// "BadConversion".
+///
+/// If @p SuppressUserConversions, then user-defined conversions are
+/// not permitted.
+/// If @p AllowExplicit, then explicit user-defined conversions are
+/// permitted.
+ImplicitConversionSequence
+Sema::TryImplicitConversion(Expr* From, QualType ToType,
+                            bool SuppressUserConversions,
+                            bool AllowExplicit, 
+                            bool InOverloadResolution) {
+  ImplicitConversionSequence ICS;
+  if (IsStandardConversion(From, ToType, InOverloadResolution, ICS.Standard)) {
+    ICS.setStandard();
+    return ICS;
+  }
+
+  if (!getLangOptions().CPlusPlus) {
+    ICS.setBad(BadConversionSequence::no_conversion, From, ToType);
+    return ICS;
+  }
+
+  if (SuppressUserConversions) {
+    // C++ [over.ics.user]p4:
+    //   A conversion of an expression of class type to the same class
+    //   type is given Exact Match rank, and a conversion of an
+    //   expression of class type to a base class of that type is
+    //   given Conversion rank, in spite of the fact that a copy/move
+    //   constructor (i.e., a user-defined conversion function) is
+    //   called for those cases.
+    QualType FromType = From->getType();
+    if (!ToType->getAs<RecordType>() || !FromType->getAs<RecordType>() ||
+        !(Context.hasSameUnqualifiedType(FromType, ToType) ||
+          IsDerivedFrom(FromType, ToType))) {
+      // We're not in the case above, so there is no conversion that
+      // we can perform.
+      ICS.setBad(BadConversionSequence::no_conversion, From, ToType);
+      return ICS;
+    }
+
+    ICS.setStandard();
+    ICS.Standard.setAsIdentityConversion();
+    ICS.Standard.setFromType(FromType);
+    ICS.Standard.setAllToTypes(ToType);
+    
+    // We don't actually check at this point whether there is a valid
+    // copy/move constructor, since overloading just assumes that it
+    // exists. When we actually perform initialization, we'll find the
+    // appropriate constructor to copy the returned object, if needed.
+    ICS.Standard.CopyConstructor = 0;
+
+    // Determine whether this is considered a derived-to-base conversion.
+    if (!Context.hasSameUnqualifiedType(FromType, ToType))
+      ICS.Standard.Second = ICK_Derived_To_Base;
+
+    return ICS;
+  }
+
+  // Attempt user-defined conversion.
+  OverloadCandidateSet Conversions(From->getExprLoc());
+  OverloadingResult UserDefResult
+    = IsUserDefinedConversion(From, ToType, ICS.UserDefined, Conversions,
+                              AllowExplicit);
+
+  if (UserDefResult == OR_Success) {
+    ICS.setUserDefined();
+    // C++ [over.ics.user]p4:
+    //   A conversion of an expression of class type to the same class
+    //   type is given Exact Match rank, and a conversion of an
+    //   expression of class type to a base class of that type is
+    //   given Conversion rank, in spite of the fact that a copy
+    //   constructor (i.e., a user-defined conversion function) is
+    //   called for those cases.
+    if (CXXConstructorDecl *Constructor
+          = dyn_cast<CXXConstructorDecl>(ICS.UserDefined.ConversionFunction)) {
+      QualType FromCanon
+        = Context.getCanonicalType(From->getType().getUnqualifiedType());
+      QualType ToCanon = Context.getCanonicalType(ToType).getUnqualifiedType();
+      if (Constructor->isCopyConstructor() &&
+          (FromCanon == ToCanon || IsDerivedFrom(FromCanon, ToCanon))) {
+        // Turn this into a "standard" conversion sequence, so that it
+        // gets ranked with standard conversion sequences.
+        ICS.setStandard();
+        ICS.Standard.setAsIdentityConversion();
+        ICS.Standard.setFromType(From->getType());
+        ICS.Standard.setAllToTypes(ToType);
+        ICS.Standard.CopyConstructor = Constructor;
+        if (ToCanon != FromCanon)
+          ICS.Standard.Second = ICK_Derived_To_Base;
+      }
+    }
+
+    // C++ [over.best.ics]p4:
+    //   However, when considering the argument of a user-defined
+    //   conversion function that is a candidate by 13.3.1.3 when
+    //   invoked for the copying of the temporary in the second step
+    //   of a class copy-initialization, or by 13.3.1.4, 13.3.1.5, or
+    //   13.3.1.6 in all cases, only standard conversion sequences and
+    //   ellipsis conversion sequences are allowed.
+    if (SuppressUserConversions && ICS.isUserDefined()) {
+      ICS.setBad(BadConversionSequence::suppressed_user, From, ToType);
+    }
+  } else if (UserDefResult == OR_Ambiguous && !SuppressUserConversions) {
+    ICS.setAmbiguous();
+    ICS.Ambiguous.setFromType(From->getType());
+    ICS.Ambiguous.setToType(ToType);
+    for (OverloadCandidateSet::iterator Cand = Conversions.begin();
+         Cand != Conversions.end(); ++Cand)
+      if (Cand->Viable)
+        ICS.Ambiguous.addConversion(Cand->Function);
+  } else {
+    ICS.setBad(BadConversionSequence::no_conversion, From, ToType);
+  }
+
+  return ICS;
+}
+
+/// PerformImplicitConversion - Perform an implicit conversion of the
+/// expression From to the type ToType. Returns true if there was an
+/// error, false otherwise. The expression From is replaced with the
+/// converted expression. Flavor is the kind of conversion we're
+/// performing, used in the error message. If @p AllowExplicit,
+/// explicit user-defined conversions are permitted.
+bool
+Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
+                                AssignmentAction Action, bool AllowExplicit) {
+  ImplicitConversionSequence ICS;
+  return PerformImplicitConversion(From, ToType, Action, AllowExplicit, ICS);
+}
+
+bool
+Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
+                                AssignmentAction Action, bool AllowExplicit,
+                                ImplicitConversionSequence& ICS) {
+  ICS = TryImplicitConversion(From, ToType,
+                              /*SuppressUserConversions=*/false,
+                              AllowExplicit,
+                              /*InOverloadResolution=*/false);
+  return PerformImplicitConversion(From, ToType, ICS, Action);
+}
+  
+/// \brief Determine whether the conversion from FromType to ToType is a valid 
+/// conversion that strips "noreturn" off the nested function type.
+static bool IsNoReturnConversion(ASTContext &Context, QualType FromType, 
+                                 QualType ToType, QualType &ResultTy) {
+  if (Context.hasSameUnqualifiedType(FromType, ToType))
+    return false;
+  
+  // Strip the noreturn off the type we're converting from; noreturn can
+  // safely be removed.
+  FromType = Context.getNoReturnType(FromType, false);
+  if (!Context.hasSameUnqualifiedType(FromType, ToType))
+    return false;
+
+  ResultTy = FromType;
+  return true;
+}
+  
+/// IsStandardConversion - Determines whether there is a standard
+/// conversion sequence (C++ [conv], C++ [over.ics.scs]) from the
+/// expression From to the type ToType. Standard conversion sequences
+/// only consider non-class types; for conversions that involve class
+/// types, use TryImplicitConversion. If a conversion exists, SCS will
+/// contain the standard conversion sequence required to perform this
+/// conversion and this routine will return true. Otherwise, this
+/// routine will return false and the value of SCS is unspecified.
+bool
+Sema::IsStandardConversion(Expr* From, QualType ToType,
+                           bool InOverloadResolution,
+                           StandardConversionSequence &SCS) {
+  QualType FromType = From->getType();
+
+  // Standard conversions (C++ [conv])
+  SCS.setAsIdentityConversion();
+  SCS.DeprecatedStringLiteralToCharPtr = false;
+  SCS.IncompatibleObjC = false;
+  SCS.setFromType(FromType);
+  SCS.CopyConstructor = 0;
+
+  // There are no standard conversions for class types in C++, so
+  // abort early. When overloading in C, however, we do permit
+  if (FromType->isRecordType() || ToType->isRecordType()) {
+    if (getLangOptions().CPlusPlus)
+      return false;
+
+    // When we're overloading in C, we allow, as standard conversions,
+  }
+
+  // The first conversion can be an lvalue-to-rvalue conversion,
+  // array-to-pointer conversion, or function-to-pointer conversion
+  // (C++ 4p1).
+
+  DeclAccessPair AccessPair;
+
+  // Lvalue-to-rvalue conversion (C++ 4.1):
+  //   An lvalue (3.10) of a non-function, non-array type T can be
+  //   converted to an rvalue.
+  Expr::isLvalueResult argIsLvalue = From->isLvalue(Context);
+  if (argIsLvalue == Expr::LV_Valid &&
+      !FromType->isFunctionType() && !FromType->isArrayType() &&
+      Context.getCanonicalType(FromType) != Context.OverloadTy) {
+    SCS.First = ICK_Lvalue_To_Rvalue;
+
+    // If T is a non-class type, the type of the rvalue is the
+    // cv-unqualified version of T. Otherwise, the type of the rvalue
+    // is T (C++ 4.1p1). C++ can't get here with class types; in C, we
+    // just strip the qualifiers because they don't matter.
+    FromType = FromType.getUnqualifiedType();
+  } else if (FromType->isArrayType()) {
+    // Array-to-pointer conversion (C++ 4.2)
+    SCS.First = ICK_Array_To_Pointer;
+
+    // An lvalue or rvalue of type "array of N T" or "array of unknown
+    // bound of T" can be converted to an rvalue of type "pointer to
+    // T" (C++ 4.2p1).
+    FromType = Context.getArrayDecayedType(FromType);
+
+    if (IsStringLiteralToNonConstPointerConversion(From, ToType)) {
+      // This conversion is deprecated. (C++ D.4).
+      SCS.DeprecatedStringLiteralToCharPtr = true;
+
+      // For the purpose of ranking in overload resolution
+      // (13.3.3.1.1), this conversion is considered an
+      // array-to-pointer conversion followed by a qualification
+      // conversion (4.4). (C++ 4.2p2)
+      SCS.Second = ICK_Identity;
+      SCS.Third = ICK_Qualification;
+      SCS.setAllToTypes(FromType);
+      return true;
+    }
+  } else if (FromType->isFunctionType() && argIsLvalue == Expr::LV_Valid) {
+    // Function-to-pointer conversion (C++ 4.3).
+    SCS.First = ICK_Function_To_Pointer;
+
+    // An lvalue of function type T can be converted to an rvalue of
+    // type "pointer to T." The result is a pointer to the
+    // function. (C++ 4.3p1).
+    FromType = Context.getPointerType(FromType);
+  } else if (From->getType() == Context.OverloadTy) {
+    if (FunctionDecl *Fn
+          = ResolveAddressOfOverloadedFunction(From, ToType, false, 
+                                               AccessPair)) {
+      // Address of overloaded function (C++ [over.over]).
+      SCS.First = ICK_Function_To_Pointer;
+
+      // We were able to resolve the address of the overloaded function,
+      // so we can convert to the type of that function.
+      FromType = Fn->getType();
+      if (ToType->isLValueReferenceType())
+        FromType = Context.getLValueReferenceType(FromType);
+      else if (ToType->isRValueReferenceType())
+        FromType = Context.getRValueReferenceType(FromType);
+      else if (ToType->isMemberPointerType()) {
+        // Resolve address only succeeds if both sides are member pointers,
+        // but it doesn't have to be the same class. See DR 247.
+        // Note that this means that the type of &Derived::fn can be
+        // Ret (Base::*)(Args) if the fn overload actually found is from the
+        // base class, even if it was brought into the derived class via a
+        // using declaration. The standard isn't clear on this issue at all.
+        CXXMethodDecl *M = cast<CXXMethodDecl>(Fn);
+        FromType = Context.getMemberPointerType(FromType,
+                      Context.getTypeDeclType(M->getParent()).getTypePtr());
+      } else {
+        FromType = Context.getPointerType(FromType);
+      }
+    } else {
+      return false;
+    }
+  } else {
+    // We don't require any conversions for the first step.
+    SCS.First = ICK_Identity;
+  }
+  SCS.setToType(0, FromType);
+
+  // The second conversion can be an integral promotion, floating
+  // point promotion, integral conversion, floating point conversion,
+  // floating-integral conversion, pointer conversion,
+  // pointer-to-member conversion, or boolean conversion (C++ 4p1).
+  // For overloading in C, this can also be a "compatible-type"
+  // conversion.
+  bool IncompatibleObjC = false;
+  if (Context.hasSameUnqualifiedType(FromType, ToType)) {
+    // The unqualified versions of the types are the same: there's no
+    // conversion to do.
+    SCS.Second = ICK_Identity;
+  } else if (IsIntegralPromotion(From, FromType, ToType)) {
+    // Integral promotion (C++ 4.5).
+    SCS.Second = ICK_Integral_Promotion;
+    FromType = ToType.getUnqualifiedType();
+  } else if (IsFloatingPointPromotion(FromType, ToType)) {
+    // Floating point promotion (C++ 4.6).
+    SCS.Second = ICK_Floating_Promotion;
+    FromType = ToType.getUnqualifiedType();
+  } else if (IsComplexPromotion(FromType, ToType)) {
+    // Complex promotion (Clang extension)
+    SCS.Second = ICK_Complex_Promotion;
+    FromType = ToType.getUnqualifiedType();
+  } else if ((FromType->isIntegralType() || FromType->isEnumeralType()) &&
+           (ToType->isIntegralType() && !ToType->isEnumeralType())) {
+    // Integral conversions (C++ 4.7).
+    SCS.Second = ICK_Integral_Conversion;
+    FromType = ToType.getUnqualifiedType();
+  } else if (FromType->isComplexType() && ToType->isComplexType()) {
+    // Complex conversions (C99 6.3.1.6)
+    SCS.Second = ICK_Complex_Conversion;
+    FromType = ToType.getUnqualifiedType();
+  } else if ((FromType->isComplexType() && ToType->isArithmeticType()) ||
+             (ToType->isComplexType() && FromType->isArithmeticType())) {
+    // Complex-real conversions (C99 6.3.1.7)
+    SCS.Second = ICK_Complex_Real;
+    FromType = ToType.getUnqualifiedType();
+  } else if (FromType->isFloatingType() && ToType->isFloatingType()) {
+    // Floating point conversions (C++ 4.8).
+    SCS.Second = ICK_Floating_Conversion;
+    FromType = ToType.getUnqualifiedType();
+  } else if ((FromType->isFloatingType() &&
+              ToType->isIntegralType() && (!ToType->isBooleanType() &&
+                                           !ToType->isEnumeralType())) ||
+             ((FromType->isIntegralType() || FromType->isEnumeralType()) &&
+              ToType->isFloatingType())) {
+    // Floating-integral conversions (C++ 4.9).
+    SCS.Second = ICK_Floating_Integral;
+    FromType = ToType.getUnqualifiedType();
+  } else if (IsPointerConversion(From, FromType, ToType, InOverloadResolution,
+                                 FromType, IncompatibleObjC)) {
+    // Pointer conversions (C++ 4.10).
+    SCS.Second = ICK_Pointer_Conversion;
+    SCS.IncompatibleObjC = IncompatibleObjC;
+  } else if (IsMemberPointerConversion(From, FromType, ToType, 
+                                       InOverloadResolution, FromType)) {
+    // Pointer to member conversions (4.11).
+    SCS.Second = ICK_Pointer_Member;
+  } else if (ToType->isBooleanType() &&
+             (FromType->isArithmeticType() ||
+              FromType->isEnumeralType() ||
+              FromType->isAnyPointerType() ||
+              FromType->isBlockPointerType() ||
+              FromType->isMemberPointerType() ||
+              FromType->isNullPtrType())) {
+    // Boolean conversions (C++ 4.12).
+    SCS.Second = ICK_Boolean_Conversion;
+    FromType = Context.BoolTy;
+  } else if (!getLangOptions().CPlusPlus &&
+             Context.typesAreCompatible(ToType, FromType)) {
+    // Compatible conversions (Clang extension for C function overloading)
+    SCS.Second = ICK_Compatible_Conversion;
+  } else if (IsNoReturnConversion(Context, FromType, ToType, FromType)) {
+    // Treat a conversion that strips "noreturn" as an identity conversion.
+    SCS.Second = ICK_NoReturn_Adjustment;
+  } else {
+    // No second conversion required.
+    SCS.Second = ICK_Identity;
+  }
+  SCS.setToType(1, FromType);
+
+  QualType CanonFrom;
+  QualType CanonTo;
+  // The third conversion can be a qualification conversion (C++ 4p1).
+  if (IsQualificationConversion(FromType, ToType)) {
+    SCS.Third = ICK_Qualification;
+    FromType = ToType;
+    CanonFrom = Context.getCanonicalType(FromType);
+    CanonTo = Context.getCanonicalType(ToType);
+  } else {
+    // No conversion required
+    SCS.Third = ICK_Identity;
+
+    // C++ [over.best.ics]p6:
+    //   [...] Any difference in top-level cv-qualification is
+    //   subsumed by the initialization itself and does not constitute
+    //   a conversion. [...]
+    CanonFrom = Context.getCanonicalType(FromType);
+    CanonTo = Context.getCanonicalType(ToType);
+    if (CanonFrom.getLocalUnqualifiedType() 
+                                       == CanonTo.getLocalUnqualifiedType() &&
+        CanonFrom.getLocalCVRQualifiers() != CanonTo.getLocalCVRQualifiers()) {
+      FromType = ToType;
+      CanonFrom = CanonTo;
+    }
+  }
+  SCS.setToType(2, FromType);
+
+  // If we have not converted the argument type to the parameter type,
+  // this is a bad conversion sequence.
+  if (CanonFrom != CanonTo)
+    return false;
+
+  return true;
+}
+
+/// IsIntegralPromotion - Determines whether the conversion from the
+/// expression From (whose potentially-adjusted type is FromType) to
+/// ToType is an integral promotion (C++ 4.5). If so, returns true and
+/// sets PromotedType to the promoted type.
+bool Sema::IsIntegralPromotion(Expr *From, QualType FromType, QualType ToType) {
+  const BuiltinType *To = ToType->getAs<BuiltinType>();
+  // All integers are built-in.
+  if (!To) {
+    return false;
+  }
+
+  // An rvalue of type char, signed char, unsigned char, short int, or
+  // unsigned short int can be converted to an rvalue of type int if
+  // int can represent all the values of the source type; otherwise,
+  // the source rvalue can be converted to an rvalue of type unsigned
+  // int (C++ 4.5p1).
+  if (FromType->isPromotableIntegerType() && !FromType->isBooleanType() &&
+      !FromType->isEnumeralType()) {
+    if (// We can promote any signed, promotable integer type to an int
+        (FromType->isSignedIntegerType() ||
+         // We can promote any unsigned integer type whose size is
+         // less than int to an int.
+         (!FromType->isSignedIntegerType() &&
+          Context.getTypeSize(FromType) < Context.getTypeSize(ToType)))) {
+      return To->getKind() == BuiltinType::Int;
+    }
+
+    return To->getKind() == BuiltinType::UInt;
+  }
+
+  // An rvalue of type wchar_t (3.9.1) or an enumeration type (7.2)
+  // can be converted to an rvalue of the first of the following types
+  // that can represent all the values of its underlying type: int,
+  // unsigned int, long, or unsigned long (C++ 4.5p2).
+
+  // We pre-calculate the promotion type for enum types.
+  if (const EnumType *FromEnumType = FromType->getAs<EnumType>())
+    if (ToType->isIntegerType())
+      return Context.hasSameUnqualifiedType(ToType,
+                                FromEnumType->getDecl()->getPromotionType());
+
+  if (FromType->isWideCharType() && ToType->isIntegerType()) {
+    // Determine whether the type we're converting from is signed or
+    // unsigned.
+    bool FromIsSigned;
+    uint64_t FromSize = Context.getTypeSize(FromType);
+    
+    // FIXME: Is wchar_t signed or unsigned? We assume it's signed for now.
+    FromIsSigned = true;
+
+    // The types we'll try to promote to, in the appropriate
+    // order. Try each of these types.
+    QualType PromoteTypes[6] = {
+      Context.IntTy, Context.UnsignedIntTy,
+      Context.LongTy, Context.UnsignedLongTy ,
+      Context.LongLongTy, Context.UnsignedLongLongTy
+    };
+    for (int Idx = 0; Idx < 6; ++Idx) {
+      uint64_t ToSize = Context.getTypeSize(PromoteTypes[Idx]);
+      if (FromSize < ToSize ||
+          (FromSize == ToSize &&
+           FromIsSigned == PromoteTypes[Idx]->isSignedIntegerType())) {
+        // We found the type that we can promote to. If this is the
+        // type we wanted, we have a promotion. Otherwise, no
+        // promotion.
+        return Context.hasSameUnqualifiedType(ToType, PromoteTypes[Idx]);
+      }
+    }
+  }
+
+  // An rvalue for an integral bit-field (9.6) can be converted to an
+  // rvalue of type int if int can represent all the values of the
+  // bit-field; otherwise, it can be converted to unsigned int if
+  // unsigned int can represent all the values of the bit-field. If
+  // the bit-field is larger yet, no integral promotion applies to
+  // it. If the bit-field has an enumerated type, it is treated as any
+  // other value of that type for promotion purposes (C++ 4.5p3).
+  // FIXME: We should delay checking of bit-fields until we actually perform the
+  // conversion.
+  using llvm::APSInt;
+  if (From)
+    if (FieldDecl *MemberDecl = From->getBitField()) {
+      APSInt BitWidth;
+      if (FromType->isIntegralType() && !FromType->isEnumeralType() &&
+          MemberDecl->getBitWidth()->isIntegerConstantExpr(BitWidth, Context)) {
+        APSInt ToSize(BitWidth.getBitWidth(), BitWidth.isUnsigned());
+        ToSize = Context.getTypeSize(ToType);
+
+        // Are we promoting to an int from a bitfield that fits in an int?
+        if (BitWidth < ToSize ||
+            (FromType->isSignedIntegerType() && BitWidth <= ToSize)) {
+          return To->getKind() == BuiltinType::Int;
+        }
+
+        // Are we promoting to an unsigned int from an unsigned bitfield
+        // that fits into an unsigned int?
+        if (FromType->isUnsignedIntegerType() && BitWidth <= ToSize) {
+          return To->getKind() == BuiltinType::UInt;
+        }
+
+        return false;
+      }
+    }
+
+  // An rvalue of type bool can be converted to an rvalue of type int,
+  // with false becoming zero and true becoming one (C++ 4.5p4).
+  if (FromType->isBooleanType() && To->getKind() == BuiltinType::Int) {
+    return true;
+  }
+
+  return false;
+}
+
+/// IsFloatingPointPromotion - Determines whether the conversion from
+/// FromType to ToType is a floating point promotion (C++ 4.6). If so,
+/// returns true and sets PromotedType to the promoted type.
+bool Sema::IsFloatingPointPromotion(QualType FromType, QualType ToType) {
+  /// An rvalue of type float can be converted to an rvalue of type
+  /// double. (C++ 4.6p1).
+  if (const BuiltinType *FromBuiltin = FromType->getAs<BuiltinType>())
+    if (const BuiltinType *ToBuiltin = ToType->getAs<BuiltinType>()) {
+      if (FromBuiltin->getKind() == BuiltinType::Float &&
+          ToBuiltin->getKind() == BuiltinType::Double)
+        return true;
+
+      // C99 6.3.1.5p1:
+      //   When a float is promoted to double or long double, or a
+      //   double is promoted to long double [...].
+      if (!getLangOptions().CPlusPlus &&
+          (FromBuiltin->getKind() == BuiltinType::Float ||
+           FromBuiltin->getKind() == BuiltinType::Double) &&
+          (ToBuiltin->getKind() == BuiltinType::LongDouble))
+        return true;
+    }
+
+  return false;
+}
+
+/// \brief Determine if a conversion is a complex promotion.
+///
+/// A complex promotion is defined as a complex -> complex conversion
+/// where the conversion between the underlying real types is a
+/// floating-point or integral promotion.
+bool Sema::IsComplexPromotion(QualType FromType, QualType ToType) {
+  const ComplexType *FromComplex = FromType->getAs<ComplexType>();
+  if (!FromComplex)
+    return false;
+
+  const ComplexType *ToComplex = ToType->getAs<ComplexType>();
+  if (!ToComplex)
+    return false;
+
+  return IsFloatingPointPromotion(FromComplex->getElementType(),
+                                  ToComplex->getElementType()) ||
+    IsIntegralPromotion(0, FromComplex->getElementType(),
+                        ToComplex->getElementType());
+}
+
+/// BuildSimilarlyQualifiedPointerType - In a pointer conversion from
+/// the pointer type FromPtr to a pointer to type ToPointee, with the
+/// same type qualifiers as FromPtr has on its pointee type. ToType,
+/// if non-empty, will be a pointer to ToType that may or may not have
+/// the right set of qualifiers on its pointee.
+static QualType
+BuildSimilarlyQualifiedPointerType(const PointerType *FromPtr,
+                                   QualType ToPointee, QualType ToType,
+                                   ASTContext &Context) {
+  QualType CanonFromPointee = Context.getCanonicalType(FromPtr->getPointeeType());
+  QualType CanonToPointee = Context.getCanonicalType(ToPointee);
+  Qualifiers Quals = CanonFromPointee.getQualifiers();
+
+  // Exact qualifier match -> return the pointer type we're converting to.
+  if (CanonToPointee.getLocalQualifiers() == Quals) {
+    // ToType is exactly what we need. Return it.
+    if (!ToType.isNull())
+      return ToType;
+
+    // Build a pointer to ToPointee. It has the right qualifiers
+    // already.
+    return Context.getPointerType(ToPointee);
+  }
+
+  // Just build a canonical type that has the right qualifiers.
+  return Context.getPointerType(
+         Context.getQualifiedType(CanonToPointee.getLocalUnqualifiedType(), 
+                                  Quals));
+}
+
+/// BuildSimilarlyQualifiedObjCObjectPointerType - In a pointer conversion from
+/// the FromType, which is an objective-c pointer, to ToType, which may or may
+/// not have the right set of qualifiers.
+static QualType
+BuildSimilarlyQualifiedObjCObjectPointerType(QualType FromType,
+                                             QualType ToType,
+                                             ASTContext &Context) {
+  QualType CanonFromType = Context.getCanonicalType(FromType);
+  QualType CanonToType = Context.getCanonicalType(ToType);
+  Qualifiers Quals = CanonFromType.getQualifiers();
+    
+  // Exact qualifier match -> return the pointer type we're converting to.
+  if (CanonToType.getLocalQualifiers() == Quals)
+    return ToType;
+  
+  // Just build a canonical type that has the right qualifiers.
+  return Context.getQualifiedType(CanonToType.getLocalUnqualifiedType(), Quals);
+}
+  
+static bool isNullPointerConstantForConversion(Expr *Expr,
+                                               bool InOverloadResolution,
+                                               ASTContext &Context) {
+  // Handle value-dependent integral null pointer constants correctly.
+  // http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#903
+  if (Expr->isValueDependent() && !Expr->isTypeDependent() &&
+      Expr->getType()->isIntegralType())
+    return !InOverloadResolution;
+
+  return Expr->isNullPointerConstant(Context,
+                    InOverloadResolution? Expr::NPC_ValueDependentIsNotNull
+                                        : Expr::NPC_ValueDependentIsNull);
+}
+
+/// IsPointerConversion - Determines whether the conversion of the
+/// expression From, which has the (possibly adjusted) type FromType,
+/// can be converted to the type ToType via a pointer conversion (C++
+/// 4.10). If so, returns true and places the converted type (that
+/// might differ from ToType in its cv-qualifiers at some level) into
+/// ConvertedType.
+///
+/// This routine also supports conversions to and from block pointers
+/// and conversions with Objective-C's 'id', 'id<protocols...>', and
+/// pointers to interfaces. FIXME: Once we've determined the
+/// appropriate overloading rules for Objective-C, we may want to
+/// split the Objective-C checks into a different routine; however,
+/// GCC seems to consider all of these conversions to be pointer
+/// conversions, so for now they live here. IncompatibleObjC will be
+/// set if the conversion is an allowed Objective-C conversion that
+/// should result in a warning.
+bool Sema::IsPointerConversion(Expr *From, QualType FromType, QualType ToType,
+                               bool InOverloadResolution,
+                               QualType& ConvertedType,
+                               bool &IncompatibleObjC) {
+  IncompatibleObjC = false;
+  if (isObjCPointerConversion(FromType, ToType, ConvertedType, IncompatibleObjC))
+    return true;
+
+  // Conversion from a null pointer constant to any Objective-C pointer type.
+  if (ToType->isObjCObjectPointerType() &&
+      isNullPointerConstantForConversion(From, InOverloadResolution, Context)) {
+    ConvertedType = ToType;
+    return true;
+  }
+
+  // Blocks: Block pointers can be converted to void*.
+  if (FromType->isBlockPointerType() && ToType->isPointerType() &&
+      ToType->getAs<PointerType>()->getPointeeType()->isVoidType()) {
+    ConvertedType = ToType;
+    return true;
+  }
+  // Blocks: A null pointer constant can be converted to a block
+  // pointer type.
+  if (ToType->isBlockPointerType() &&
+      isNullPointerConstantForConversion(From, InOverloadResolution, Context)) {
+    ConvertedType = ToType;
+    return true;
+  }
+
+  // If the left-hand-side is nullptr_t, the right side can be a null
+  // pointer constant.
+  if (ToType->isNullPtrType() &&
+      isNullPointerConstantForConversion(From, InOverloadResolution, Context)) {
+    ConvertedType = ToType;
+    return true;
+  }
+
+  const PointerType* ToTypePtr = ToType->getAs<PointerType>();
+  if (!ToTypePtr)
+    return false;
+
+  // A null pointer constant can be converted to a pointer type (C++ 4.10p1).
+  if (isNullPointerConstantForConversion(From, InOverloadResolution, Context)) {
+    ConvertedType = ToType;
+    return true;
+  }
+
+  // Beyond this point, both types need to be pointers 
+  // , including objective-c pointers.
+  QualType ToPointeeType = ToTypePtr->getPointeeType();
+  if (FromType->isObjCObjectPointerType() && ToPointeeType->isVoidType()) {
+    ConvertedType = BuildSimilarlyQualifiedObjCObjectPointerType(FromType,
+                                                       ToType, Context);
+    return true;
+    
+  }
+  const PointerType *FromTypePtr = FromType->getAs<PointerType>();
+  if (!FromTypePtr)
+    return false;
+
+  QualType FromPointeeType = FromTypePtr->getPointeeType();
+
+  // An rvalue of type "pointer to cv T," where T is an object type,
+  // can be converted to an rvalue of type "pointer to cv void" (C++
+  // 4.10p2).
+  if (FromPointeeType->isObjectType() && ToPointeeType->isVoidType()) {
+    ConvertedType = BuildSimilarlyQualifiedPointerType(FromTypePtr,
+                                                       ToPointeeType,
+                                                       ToType, Context);
+    return true;
+  }
+
+  // When we're overloading in C, we allow a special kind of pointer
+  // conversion for compatible-but-not-identical pointee types.
+  if (!getLangOptions().CPlusPlus &&
+      Context.typesAreCompatible(FromPointeeType, ToPointeeType)) {
+    ConvertedType = BuildSimilarlyQualifiedPointerType(FromTypePtr,
+                                                       ToPointeeType,
+                                                       ToType, Context);
+    return true;
+  }
+
+  // C++ [conv.ptr]p3:
+  //
+  //   An rvalue of type "pointer to cv D," where D is a class type,
+  //   can be converted to an rvalue of type "pointer to cv B," where
+  //   B is a base class (clause 10) of D. If B is an inaccessible
+  //   (clause 11) or ambiguous (10.2) base class of D, a program that
+  //   necessitates this conversion is ill-formed. The result of the
+  //   conversion is a pointer to the base class sub-object of the
+  //   derived class object. The null pointer value is converted to
+  //   the null pointer value of the destination type.
+  //
+  // Note that we do not check for ambiguity or inaccessibility
+  // here. That is handled by CheckPointerConversion.
+  if (getLangOptions().CPlusPlus &&
+      FromPointeeType->isRecordType() && ToPointeeType->isRecordType() &&
+      !Context.hasSameUnqualifiedType(FromPointeeType, ToPointeeType) &&
+      !RequireCompleteType(From->getLocStart(), FromPointeeType, PDiag()) &&
+      IsDerivedFrom(FromPointeeType, ToPointeeType)) {
+    ConvertedType = BuildSimilarlyQualifiedPointerType(FromTypePtr,
+                                                       ToPointeeType,
+                                                       ToType, Context);
+    return true;
+  }
+
+  return false;
+}
+
+/// isObjCPointerConversion - Determines whether this is an
+/// Objective-C pointer conversion. Subroutine of IsPointerConversion,
+/// with the same arguments and return values.
+bool Sema::isObjCPointerConversion(QualType FromType, QualType ToType,
+                                   QualType& ConvertedType,
+                                   bool &IncompatibleObjC) {
+  if (!getLangOptions().ObjC1)
+    return false;
+ 
+  // First, we handle all conversions on ObjC object pointer types.
+  const ObjCObjectPointerType* ToObjCPtr = ToType->getAs<ObjCObjectPointerType>();
+  const ObjCObjectPointerType *FromObjCPtr =
+    FromType->getAs<ObjCObjectPointerType>();
+
+  if (ToObjCPtr && FromObjCPtr) {
+    // Objective C++: We're able to convert between "id" or "Class" and a
+    // pointer to any interface (in both directions).
+    if (ToObjCPtr->isObjCBuiltinType() && FromObjCPtr->isObjCBuiltinType()) {
+      ConvertedType = ToType;
+      return true;
+    }
+    // Conversions with Objective-C's id<...>.
+    if ((FromObjCPtr->isObjCQualifiedIdType() ||
+         ToObjCPtr->isObjCQualifiedIdType()) &&
+        Context.ObjCQualifiedIdTypesAreCompatible(ToType, FromType,
+                                                  /*compare=*/false)) {
+      ConvertedType = ToType;
+      return true;
+    }
+    // Objective C++: We're able to convert from a pointer to an
+    // interface to a pointer to a different interface.
+    if (Context.canAssignObjCInterfaces(ToObjCPtr, FromObjCPtr)) {
+      const ObjCInterfaceType* LHS = ToObjCPtr->getInterfaceType();
+      const ObjCInterfaceType* RHS = FromObjCPtr->getInterfaceType();
+      if (getLangOptions().CPlusPlus && LHS && RHS &&
+          !ToObjCPtr->getPointeeType().isAtLeastAsQualifiedAs(
+                                                FromObjCPtr->getPointeeType()))
+        return false;
+      ConvertedType = ToType;
+      return true;
+    }
+
+    if (Context.canAssignObjCInterfaces(FromObjCPtr, ToObjCPtr)) {
+      // Okay: this is some kind of implicit downcast of Objective-C
+      // interfaces, which is permitted. However, we're going to
+      // complain about it.
+      IncompatibleObjC = true;
+      ConvertedType = FromType;
+      return true;
+    }
+  }
+  // Beyond this point, both types need to be C pointers or block pointers.
+  QualType ToPointeeType;
+  if (const PointerType *ToCPtr = ToType->getAs<PointerType>())
+    ToPointeeType = ToCPtr->getPointeeType();
+  else if (const BlockPointerType *ToBlockPtr = 
+            ToType->getAs<BlockPointerType>()) {
+    // Objective C++: We're able to convert from a pointer to any object
+    // to a block pointer type.
+    if (FromObjCPtr && FromObjCPtr->isObjCBuiltinType()) {
+      ConvertedType = ToType;
+      return true;
+    }
+    ToPointeeType = ToBlockPtr->getPointeeType();
+  }
+  else if (FromType->getAs<BlockPointerType>() && 
+           ToObjCPtr && ToObjCPtr->isObjCBuiltinType()) {
+    // Objective C++: We're able to convert from a block pointer type to a 
+    // pointer to any object.
+    ConvertedType = ToType;
+    return true;
+  }
+  else
+    return false;
+
+  QualType FromPointeeType;
+  if (const PointerType *FromCPtr = FromType->getAs<PointerType>())
+    FromPointeeType = FromCPtr->getPointeeType();
+  else if (const BlockPointerType *FromBlockPtr = FromType->getAs<BlockPointerType>())
+    FromPointeeType = FromBlockPtr->getPointeeType();
+  else
+    return false;
+
+  // If we have pointers to pointers, recursively check whether this
+  // is an Objective-C conversion.
+  if (FromPointeeType->isPointerType() && ToPointeeType->isPointerType() &&
+      isObjCPointerConversion(FromPointeeType, ToPointeeType, ConvertedType,
+                              IncompatibleObjC)) {
+    // We always complain about this conversion.
+    IncompatibleObjC = true;
+    ConvertedType = ToType;
+    return true;
+  }
+  // Allow conversion of pointee being objective-c pointer to another one;
+  // as in I* to id.
+  if (FromPointeeType->getAs<ObjCObjectPointerType>() &&
+      ToPointeeType->getAs<ObjCObjectPointerType>() &&
+      isObjCPointerConversion(FromPointeeType, ToPointeeType, ConvertedType,
+                              IncompatibleObjC)) {
+    ConvertedType = ToType;
+    return true;
+  }
+  
+  // If we have pointers to functions or blocks, check whether the only
+  // differences in the argument and result types are in Objective-C
+  // pointer conversions. If so, we permit the conversion (but
+  // complain about it).
+  const FunctionProtoType *FromFunctionType
+    = FromPointeeType->getAs<FunctionProtoType>();
+  const FunctionProtoType *ToFunctionType
+    = ToPointeeType->getAs<FunctionProtoType>();
+  if (FromFunctionType && ToFunctionType) {
+    // If the function types are exactly the same, this isn't an
+    // Objective-C pointer conversion.
+    if (Context.getCanonicalType(FromPointeeType)
+          == Context.getCanonicalType(ToPointeeType))
+      return false;
+
+    // Perform the quick checks that will tell us whether these
+    // function types are obviously different.
+    if (FromFunctionType->getNumArgs() != ToFunctionType->getNumArgs() ||
+        FromFunctionType->isVariadic() != ToFunctionType->isVariadic() ||
+        FromFunctionType->getTypeQuals() != ToFunctionType->getTypeQuals())
+      return false;
+
+    bool HasObjCConversion = false;
+    if (Context.getCanonicalType(FromFunctionType->getResultType())
+          == Context.getCanonicalType(ToFunctionType->getResultType())) {
+      // Okay, the types match exactly. Nothing to do.
+    } else if (isObjCPointerConversion(FromFunctionType->getResultType(),
+                                       ToFunctionType->getResultType(),
+                                       ConvertedType, IncompatibleObjC)) {
+      // Okay, we have an Objective-C pointer conversion.
+      HasObjCConversion = true;
+    } else {
+      // Function types are too different. Abort.
+      return false;
+    }
+
+    // Check argument types.
+    for (unsigned ArgIdx = 0, NumArgs = FromFunctionType->getNumArgs();
+         ArgIdx != NumArgs; ++ArgIdx) {
+      QualType FromArgType = FromFunctionType->getArgType(ArgIdx);
+      QualType ToArgType = ToFunctionType->getArgType(ArgIdx);
+      if (Context.getCanonicalType(FromArgType)
+            == Context.getCanonicalType(ToArgType)) {
+        // Okay, the types match exactly. Nothing to do.
+      } else if (isObjCPointerConversion(FromArgType, ToArgType,
+                                         ConvertedType, IncompatibleObjC)) {
+        // Okay, we have an Objective-C pointer conversion.
+        HasObjCConversion = true;
+      } else {
+        // Argument types are too different. Abort.
+        return false;
+      }
+    }
+
+    if (HasObjCConversion) {
+      // We had an Objective-C conversion. Allow this pointer
+      // conversion, but complain about it.
+      ConvertedType = ToType;
+      IncompatibleObjC = true;
+      return true;
+    }
+  }
+
+  return false;
+}
+
+/// CheckPointerConversion - Check the pointer conversion from the
+/// expression From to the type ToType. This routine checks for
+/// ambiguous or inaccessible derived-to-base pointer
+/// conversions for which IsPointerConversion has already returned
+/// true. It returns true and produces a diagnostic if there was an
+/// error, or returns false otherwise.
+bool Sema::CheckPointerConversion(Expr *From, QualType ToType,
+                                  CastExpr::CastKind &Kind,
+                                  CXXBaseSpecifierArray& BasePath,
+                                  bool IgnoreBaseAccess) {
+  QualType FromType = From->getType();
+
+  if (const PointerType *FromPtrType = FromType->getAs<PointerType>())
+    if (const PointerType *ToPtrType = ToType->getAs<PointerType>()) {
+      QualType FromPointeeType = FromPtrType->getPointeeType(),
+               ToPointeeType   = ToPtrType->getPointeeType();
+
+      if (FromPointeeType->isRecordType() && ToPointeeType->isRecordType() &&
+          !Context.hasSameUnqualifiedType(FromPointeeType, ToPointeeType)) {
+        // We must have a derived-to-base conversion. Check an
+        // ambiguous or inaccessible conversion.
+        if (CheckDerivedToBaseConversion(FromPointeeType, ToPointeeType,
+                                         From->getExprLoc(),
+                                         From->getSourceRange(), &BasePath,
+                                         IgnoreBaseAccess))
+          return true;
+        
+        // The conversion was successful.
+        Kind = CastExpr::CK_DerivedToBase;
+      }
+    }
+  if (const ObjCObjectPointerType *FromPtrType =
+        FromType->getAs<ObjCObjectPointerType>())
+    if (const ObjCObjectPointerType *ToPtrType =
+          ToType->getAs<ObjCObjectPointerType>()) {
+      // Objective-C++ conversions are always okay.
+      // FIXME: We should have a different class of conversions for the
+      // Objective-C++ implicit conversions.
+      if (FromPtrType->isObjCBuiltinType() || ToPtrType->isObjCBuiltinType())
+        return false;
+
+  }
+  return false;
+}
+
+/// IsMemberPointerConversion - Determines whether the conversion of the
+/// expression From, which has the (possibly adjusted) type FromType, can be
+/// converted to the type ToType via a member pointer conversion (C++ 4.11).
+/// If so, returns true and places the converted type (that might differ from
+/// ToType in its cv-qualifiers at some level) into ConvertedType.
+bool Sema::IsMemberPointerConversion(Expr *From, QualType FromType,
+                                     QualType ToType, 
+                                     bool InOverloadResolution,
+                                     QualType &ConvertedType) {
+  const MemberPointerType *ToTypePtr = ToType->getAs<MemberPointerType>();
+  if (!ToTypePtr)
+    return false;
+
+  // A null pointer constant can be converted to a member pointer (C++ 4.11p1)
+  if (From->isNullPointerConstant(Context,
+                    InOverloadResolution? Expr::NPC_ValueDependentIsNotNull
+                                        : Expr::NPC_ValueDependentIsNull)) {
+    ConvertedType = ToType;
+    return true;
+  }
+
+  // Otherwise, both types have to be member pointers.
+  const MemberPointerType *FromTypePtr = FromType->getAs<MemberPointerType>();
+  if (!FromTypePtr)
+    return false;
+
+  // A pointer to member of B can be converted to a pointer to member of D,
+  // where D is derived from B (C++ 4.11p2).
+  QualType FromClass(FromTypePtr->getClass(), 0);
+  QualType ToClass(ToTypePtr->getClass(), 0);
+  // FIXME: What happens when these are dependent? Is this function even called?
+
+  if (IsDerivedFrom(ToClass, FromClass)) {
+    ConvertedType = Context.getMemberPointerType(FromTypePtr->getPointeeType(),
+                                                 ToClass.getTypePtr());
+    return true;
+  }
+
+  return false;
+}
+  
+/// CheckMemberPointerConversion - Check the member pointer conversion from the
+/// expression From to the type ToType. This routine checks for ambiguous or
+/// virtual or inaccessible base-to-derived member pointer conversions
+/// for which IsMemberPointerConversion has already returned true. It returns
+/// true and produces a diagnostic if there was an error, or returns false
+/// otherwise.
+bool Sema::CheckMemberPointerConversion(Expr *From, QualType ToType,
+                                        CastExpr::CastKind &Kind,
+                                        CXXBaseSpecifierArray &BasePath,
+                                        bool IgnoreBaseAccess) {
+  QualType FromType = From->getType();
+  const MemberPointerType *FromPtrType = FromType->getAs<MemberPointerType>();
+  if (!FromPtrType) {
+    // This must be a null pointer to member pointer conversion
+    assert(From->isNullPointerConstant(Context, 
+                                       Expr::NPC_ValueDependentIsNull) &&
+           "Expr must be null pointer constant!");
+    Kind = CastExpr::CK_NullToMemberPointer;
+    return false;
+  }
+
+  const MemberPointerType *ToPtrType = ToType->getAs<MemberPointerType>();
+  assert(ToPtrType && "No member pointer cast has a target type "
+                      "that is not a member pointer.");
+
+  QualType FromClass = QualType(FromPtrType->getClass(), 0);
+  QualType ToClass   = QualType(ToPtrType->getClass(), 0);
+
+  // FIXME: What about dependent types?
+  assert(FromClass->isRecordType() && "Pointer into non-class.");
+  assert(ToClass->isRecordType() && "Pointer into non-class.");
+
+  CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
+                     /*DetectVirtual=*/true);
+  bool DerivationOkay = IsDerivedFrom(ToClass, FromClass, Paths);
+  assert(DerivationOkay &&
+         "Should not have been called if derivation isn't OK.");
+  (void)DerivationOkay;
+
+  if (Paths.isAmbiguous(Context.getCanonicalType(FromClass).
+                                  getUnqualifiedType())) {
+    std::string PathDisplayStr = getAmbiguousPathsDisplayString(Paths);
+    Diag(From->getExprLoc(), diag::err_ambiguous_memptr_conv)
+      << 0 << FromClass << ToClass << PathDisplayStr << From->getSourceRange();
+    return true;
+  }
+
+  if (const RecordType *VBase = Paths.getDetectedVirtual()) {
+    Diag(From->getExprLoc(), diag::err_memptr_conv_via_virtual)
+      << FromClass << ToClass << QualType(VBase, 0)
+      << From->getSourceRange();
+    return true;
+  }
+
+  if (!IgnoreBaseAccess)
+    CheckBaseClassAccess(From->getExprLoc(), FromClass, ToClass,
+                         Paths.front(),
+                         diag::err_downcast_from_inaccessible_base);
+
+  // Must be a base to derived member conversion.
+  BuildBasePathArray(Paths, BasePath);
+  Kind = CastExpr::CK_BaseToDerivedMemberPointer;
+  return false;
+}
+
+/// IsQualificationConversion - Determines whether the conversion from
+/// an rvalue of type FromType to ToType is a qualification conversion
+/// (C++ 4.4).
+bool
+Sema::IsQualificationConversion(QualType FromType, QualType ToType) {
+  FromType = Context.getCanonicalType(FromType);
+  ToType = Context.getCanonicalType(ToType);
+
+  // If FromType and ToType are the same type, this is not a
+  // qualification conversion.
+  if (FromType.getUnqualifiedType() == ToType.getUnqualifiedType())
+    return false;
+
+  // (C++ 4.4p4):
+  //   A conversion can add cv-qualifiers at levels other than the first
+  //   in multi-level pointers, subject to the following rules: [...]
+  bool PreviousToQualsIncludeConst = true;
+  bool UnwrappedAnyPointer = false;
+  while (UnwrapSimilarPointerTypes(FromType, ToType)) {
+    // Within each iteration of the loop, we check the qualifiers to
+    // determine if this still looks like a qualification
+    // conversion. Then, if all is well, we unwrap one more level of
+    // pointers or pointers-to-members and do it all again
+    // until there are no more pointers or pointers-to-members left to
+    // unwrap.
+    UnwrappedAnyPointer = true;
+
+    //   -- for every j > 0, if const is in cv 1,j then const is in cv
+    //      2,j, and similarly for volatile.
+    if (!ToType.isAtLeastAsQualifiedAs(FromType))
+      return false;
+
+    //   -- if the cv 1,j and cv 2,j are different, then const is in
+    //      every cv for 0 < k < j.
+    if (FromType.getCVRQualifiers() != ToType.getCVRQualifiers()
+        && !PreviousToQualsIncludeConst)
+      return false;
+
+    // Keep track of whether all prior cv-qualifiers in the "to" type
+    // include const.
+    PreviousToQualsIncludeConst
+      = PreviousToQualsIncludeConst && ToType.isConstQualified();
+  }
+
+  // We are left with FromType and ToType being the pointee types
+  // after unwrapping the original FromType and ToType the same number
+  // of types. If we unwrapped any pointers, and if FromType and
+  // ToType have the same unqualified type (since we checked
+  // qualifiers above), then this is a qualification conversion.
+  return UnwrappedAnyPointer && Context.hasSameUnqualifiedType(FromType,ToType);
+}
+
+/// Determines whether there is a user-defined conversion sequence
+/// (C++ [over.ics.user]) that converts expression From to the type
+/// ToType. If such a conversion exists, User will contain the
+/// user-defined conversion sequence that performs such a conversion
+/// and this routine will return true. Otherwise, this routine returns
+/// false and User is unspecified.
+///
+/// \param AllowExplicit  true if the conversion should consider C++0x
+/// "explicit" conversion functions as well as non-explicit conversion
+/// functions (C++0x [class.conv.fct]p2).
+OverloadingResult Sema::IsUserDefinedConversion(Expr *From, QualType ToType,
+                                          UserDefinedConversionSequence& User,
+                                           OverloadCandidateSet& CandidateSet,
+                                                bool AllowExplicit) {
+  // Whether we will only visit constructors.
+  bool ConstructorsOnly = false;
+
+  // If the type we are conversion to is a class type, enumerate its
+  // constructors.
+  if (const RecordType *ToRecordType = ToType->getAs<RecordType>()) {
+    // C++ [over.match.ctor]p1:
+    //   When objects of class type are direct-initialized (8.5), or
+    //   copy-initialized from an expression of the same or a
+    //   derived class type (8.5), overload resolution selects the
+    //   constructor. [...] For copy-initialization, the candidate
+    //   functions are all the converting constructors (12.3.1) of
+    //   that class. The argument list is the expression-list within
+    //   the parentheses of the initializer.
+    if (Context.hasSameUnqualifiedType(ToType, From->getType()) ||
+        (From->getType()->getAs<RecordType>() &&
+         IsDerivedFrom(From->getType(), ToType)))
+      ConstructorsOnly = true;
+
+    if (RequireCompleteType(From->getLocStart(), ToType, PDiag())) {
+      // We're not going to find any constructors.
+    } else if (CXXRecordDecl *ToRecordDecl
+                 = dyn_cast<CXXRecordDecl>(ToRecordType->getDecl())) {
+      DeclarationName ConstructorName
+        = Context.DeclarationNames.getCXXConstructorName(
+                       Context.getCanonicalType(ToType).getUnqualifiedType());
+      DeclContext::lookup_iterator Con, ConEnd;
+      for (llvm::tie(Con, ConEnd)
+             = ToRecordDecl->lookup(ConstructorName);
+           Con != ConEnd; ++Con) {
+        NamedDecl *D = *Con;
+        DeclAccessPair FoundDecl = DeclAccessPair::make(D, D->getAccess());
+
+        // Find the constructor (which may be a template).
+        CXXConstructorDecl *Constructor = 0;
+        FunctionTemplateDecl *ConstructorTmpl
+          = dyn_cast<FunctionTemplateDecl>(D);
+        if (ConstructorTmpl)
+          Constructor
+            = cast<CXXConstructorDecl>(ConstructorTmpl->getTemplatedDecl());
+        else
+          Constructor = cast<CXXConstructorDecl>(D);
+        
+        if (!Constructor->isInvalidDecl() &&
+            Constructor->isConvertingConstructor(AllowExplicit)) {
+          if (ConstructorTmpl)
+            AddTemplateOverloadCandidate(ConstructorTmpl, FoundDecl,
+                                         /*ExplicitArgs*/ 0,
+                                         &From, 1, CandidateSet, 
+                                 /*SuppressUserConversions=*/!ConstructorsOnly);
+          else
+            // Allow one user-defined conversion when user specifies a
+            // From->ToType conversion via an static cast (c-style, etc).
+            AddOverloadCandidate(Constructor, FoundDecl,
+                                 &From, 1, CandidateSet,
+                                 /*SuppressUserConversions=*/!ConstructorsOnly);
+        }
+      }
+    }
+  }
+
+  // Enumerate conversion functions, if we're allowed to.
+  if (ConstructorsOnly) {
+  } else if (RequireCompleteType(From->getLocStart(), From->getType(),
+                          PDiag(0) << From->getSourceRange())) {
+    // No conversion functions from incomplete types.
+  } else if (const RecordType *FromRecordType
+                                   = From->getType()->getAs<RecordType>()) {
+    if (CXXRecordDecl *FromRecordDecl
+         = dyn_cast<CXXRecordDecl>(FromRecordType->getDecl())) {
+      // Add all of the conversion functions as candidates.
+      const UnresolvedSetImpl *Conversions
+        = FromRecordDecl->getVisibleConversionFunctions();
+      for (UnresolvedSetImpl::iterator I = Conversions->begin(),
+             E = Conversions->end(); I != E; ++I) {
+        DeclAccessPair FoundDecl = I.getPair();
+        NamedDecl *D = FoundDecl.getDecl();
+        CXXRecordDecl *ActingContext = cast<CXXRecordDecl>(D->getDeclContext());
+        if (isa<UsingShadowDecl>(D))
+          D = cast<UsingShadowDecl>(D)->getTargetDecl();
+
+        CXXConversionDecl *Conv;
+        FunctionTemplateDecl *ConvTemplate;
+        if ((ConvTemplate = dyn_cast<FunctionTemplateDecl>(D)))
+          Conv = cast<CXXConversionDecl>(ConvTemplate->getTemplatedDecl());
+        else
+          Conv = cast<CXXConversionDecl>(D);
+
+        if (AllowExplicit || !Conv->isExplicit()) {
+          if (ConvTemplate)
+            AddTemplateConversionCandidate(ConvTemplate, FoundDecl,
+                                           ActingContext, From, ToType,
+                                           CandidateSet);
+          else
+            AddConversionCandidate(Conv, FoundDecl, ActingContext,
+                                   From, ToType, CandidateSet);
+        }
+      }
+    }
+  }
+
+  OverloadCandidateSet::iterator Best;
+  switch (BestViableFunction(CandidateSet, From->getLocStart(), Best)) {
+    case OR_Success:
+      // Record the standard conversion we used and the conversion function.
+      if (CXXConstructorDecl *Constructor
+            = dyn_cast<CXXConstructorDecl>(Best->Function)) {
+        // C++ [over.ics.user]p1:
+        //   If the user-defined conversion is specified by a
+        //   constructor (12.3.1), the initial standard conversion
+        //   sequence converts the source type to the type required by
+        //   the argument of the constructor.
+        //
+        QualType ThisType = Constructor->getThisType(Context);
+        if (Best->Conversions[0].isEllipsis())
+          User.EllipsisConversion = true;
+        else {
+          User.Before = Best->Conversions[0].Standard;
+          User.EllipsisConversion = false;
+        }
+        User.ConversionFunction = Constructor;
+        User.After.setAsIdentityConversion();
+        User.After.setFromType(
+          ThisType->getAs<PointerType>()->getPointeeType());
+        User.After.setAllToTypes(ToType);
+        return OR_Success;
+      } else if (CXXConversionDecl *Conversion
+                   = dyn_cast<CXXConversionDecl>(Best->Function)) {
+        // C++ [over.ics.user]p1:
+        //
+        //   [...] If the user-defined conversion is specified by a
+        //   conversion function (12.3.2), the initial standard
+        //   conversion sequence converts the source type to the
+        //   implicit object parameter of the conversion function.
+        User.Before = Best->Conversions[0].Standard;
+        User.ConversionFunction = Conversion;
+        User.EllipsisConversion = false;
+
+        // C++ [over.ics.user]p2:
+        //   The second standard conversion sequence converts the
+        //   result of the user-defined conversion to the target type
+        //   for the sequence. Since an implicit conversion sequence
+        //   is an initialization, the special rules for
+        //   initialization by user-defined conversion apply when
+        //   selecting the best user-defined conversion for a
+        //   user-defined conversion sequence (see 13.3.3 and
+        //   13.3.3.1).
+        User.After = Best->FinalConversion;
+        return OR_Success;
+      } else {
+        assert(false && "Not a constructor or conversion function?");
+        return OR_No_Viable_Function;
+      }
+
+    case OR_No_Viable_Function:
+      return OR_No_Viable_Function;
+    case OR_Deleted:
+      // No conversion here! We're done.
+      return OR_Deleted;
+
+    case OR_Ambiguous:
+      return OR_Ambiguous;
+    }
+
+  return OR_No_Viable_Function;
+}
+  
+bool
+Sema::DiagnoseMultipleUserDefinedConversion(Expr *From, QualType ToType) {
+  ImplicitConversionSequence ICS;
+  OverloadCandidateSet CandidateSet(From->getExprLoc());
+  OverloadingResult OvResult = 
+    IsUserDefinedConversion(From, ToType, ICS.UserDefined,
+                            CandidateSet, false);
+  if (OvResult == OR_Ambiguous)
+    Diag(From->getSourceRange().getBegin(),
+         diag::err_typecheck_ambiguous_condition)
+          << From->getType() << ToType << From->getSourceRange();
+  else if (OvResult == OR_No_Viable_Function && !CandidateSet.empty())
+    Diag(From->getSourceRange().getBegin(),
+         diag::err_typecheck_nonviable_condition)
+    << From->getType() << ToType << From->getSourceRange();
+  else
+    return false;
+  PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, &From, 1);
+  return true;  
+}
+
+/// CompareImplicitConversionSequences - Compare two implicit
+/// conversion sequences to determine whether one is better than the
+/// other or if they are indistinguishable (C++ 13.3.3.2).
+ImplicitConversionSequence::CompareKind
+Sema::CompareImplicitConversionSequences(const ImplicitConversionSequence& ICS1,
+                                         const ImplicitConversionSequence& ICS2)
+{
+  // (C++ 13.3.3.2p2): When comparing the basic forms of implicit
+  // conversion sequences (as defined in 13.3.3.1)
+  //   -- a standard conversion sequence (13.3.3.1.1) is a better
+  //      conversion sequence than a user-defined conversion sequence or
+  //      an ellipsis conversion sequence, and
+  //   -- a user-defined conversion sequence (13.3.3.1.2) is a better
+  //      conversion sequence than an ellipsis conversion sequence
+  //      (13.3.3.1.3).
+  //
+  // C++0x [over.best.ics]p10:
+  //   For the purpose of ranking implicit conversion sequences as
+  //   described in 13.3.3.2, the ambiguous conversion sequence is
+  //   treated as a user-defined sequence that is indistinguishable
+  //   from any other user-defined conversion sequence.
+  if (ICS1.getKindRank() < ICS2.getKindRank())
+    return ImplicitConversionSequence::Better;
+  else if (ICS2.getKindRank() < ICS1.getKindRank())
+    return ImplicitConversionSequence::Worse;
+
+  // The following checks require both conversion sequences to be of
+  // the same kind.
+  if (ICS1.getKind() != ICS2.getKind())
+    return ImplicitConversionSequence::Indistinguishable;
+
+  // Two implicit conversion sequences of the same form are
+  // indistinguishable conversion sequences unless one of the
+  // following rules apply: (C++ 13.3.3.2p3):
+  if (ICS1.isStandard())
+    return CompareStandardConversionSequences(ICS1.Standard, ICS2.Standard);
+  else if (ICS1.isUserDefined()) {
+    // User-defined conversion sequence U1 is a better conversion
+    // sequence than another user-defined conversion sequence U2 if
+    // they contain the same user-defined conversion function or
+    // constructor and if the second standard conversion sequence of
+    // U1 is better than the second standard conversion sequence of
+    // U2 (C++ 13.3.3.2p3).
+    if (ICS1.UserDefined.ConversionFunction ==
+          ICS2.UserDefined.ConversionFunction)
+      return CompareStandardConversionSequences(ICS1.UserDefined.After,
+                                                ICS2.UserDefined.After);
+  }
+
+  return ImplicitConversionSequence::Indistinguishable;
+}
+
+// Per 13.3.3.2p3, compare the given standard conversion sequences to
+// determine if one is a proper subset of the other.
+static ImplicitConversionSequence::CompareKind
+compareStandardConversionSubsets(ASTContext &Context,
+                                 const StandardConversionSequence& SCS1,
+                                 const StandardConversionSequence& SCS2) {
+  ImplicitConversionSequence::CompareKind Result
+    = ImplicitConversionSequence::Indistinguishable;
+
+  if (SCS1.Second != SCS2.Second) {
+    if (SCS1.Second == ICK_Identity)
+      Result = ImplicitConversionSequence::Better;
+    else if (SCS2.Second == ICK_Identity)
+      Result = ImplicitConversionSequence::Worse;
+    else
+      return ImplicitConversionSequence::Indistinguishable;
+  } else if (!Context.hasSameType(SCS1.getToType(1), SCS2.getToType(1)))
+    return ImplicitConversionSequence::Indistinguishable;
+
+  if (SCS1.Third == SCS2.Third) {
+    return Context.hasSameType(SCS1.getToType(2), SCS2.getToType(2))? Result
+                             : ImplicitConversionSequence::Indistinguishable;
+  }
+
+  if (SCS1.Third == ICK_Identity)
+    return Result == ImplicitConversionSequence::Worse
+             ? ImplicitConversionSequence::Indistinguishable
+             : ImplicitConversionSequence::Better;
+
+  if (SCS2.Third == ICK_Identity)
+    return Result == ImplicitConversionSequence::Better
+             ? ImplicitConversionSequence::Indistinguishable
+             : ImplicitConversionSequence::Worse;
+       
+  return ImplicitConversionSequence::Indistinguishable;
+}
+
+/// CompareStandardConversionSequences - Compare two standard
+/// conversion sequences to determine whether one is better than the
+/// other or if they are indistinguishable (C++ 13.3.3.2p3).
+ImplicitConversionSequence::CompareKind
+Sema::CompareStandardConversionSequences(const StandardConversionSequence& SCS1,
+                                         const StandardConversionSequence& SCS2)
+{
+  // Standard conversion sequence S1 is a better conversion sequence
+  // than standard conversion sequence S2 if (C++ 13.3.3.2p3):
+
+  //  -- S1 is a proper subsequence of S2 (comparing the conversion
+  //     sequences in the canonical form defined by 13.3.3.1.1,
+  //     excluding any Lvalue Transformation; the identity conversion
+  //     sequence is considered to be a subsequence of any
+  //     non-identity conversion sequence) or, if not that,
+  if (ImplicitConversionSequence::CompareKind CK
+        = compareStandardConversionSubsets(Context, SCS1, SCS2))
+    return CK;
+
+  //  -- the rank of S1 is better than the rank of S2 (by the rules
+  //     defined below), or, if not that,
+  ImplicitConversionRank Rank1 = SCS1.getRank();
+  ImplicitConversionRank Rank2 = SCS2.getRank();
+  if (Rank1 < Rank2)
+    return ImplicitConversionSequence::Better;
+  else if (Rank2 < Rank1)
+    return ImplicitConversionSequence::Worse;
+
+  // (C++ 13.3.3.2p4): Two conversion sequences with the same rank
+  // are indistinguishable unless one of the following rules
+  // applies:
+
+  //   A conversion that is not a conversion of a pointer, or
+  //   pointer to member, to bool is better than another conversion
+  //   that is such a conversion.
+  if (SCS1.isPointerConversionToBool() != SCS2.isPointerConversionToBool())
+    return SCS2.isPointerConversionToBool()
+             ? ImplicitConversionSequence::Better
+             : ImplicitConversionSequence::Worse;
+
+  // C++ [over.ics.rank]p4b2:
+  //
+  //   If class B is derived directly or indirectly from class A,
+  //   conversion of B* to A* is better than conversion of B* to
+  //   void*, and conversion of A* to void* is better than conversion
+  //   of B* to void*.
+  bool SCS1ConvertsToVoid
+    = SCS1.isPointerConversionToVoidPointer(Context);
+  bool SCS2ConvertsToVoid
+    = SCS2.isPointerConversionToVoidPointer(Context);
+  if (SCS1ConvertsToVoid != SCS2ConvertsToVoid) {
+    // Exactly one of the conversion sequences is a conversion to
+    // a void pointer; it's the worse conversion.
+    return SCS2ConvertsToVoid ? ImplicitConversionSequence::Better
+                              : ImplicitConversionSequence::Worse;
+  } else if (!SCS1ConvertsToVoid && !SCS2ConvertsToVoid) {
+    // Neither conversion sequence converts to a void pointer; compare
+    // their derived-to-base conversions.
+    if (ImplicitConversionSequence::CompareKind DerivedCK
+          = CompareDerivedToBaseConversions(SCS1, SCS2))
+      return DerivedCK;
+  } else if (SCS1ConvertsToVoid && SCS2ConvertsToVoid) {
+    // Both conversion sequences are conversions to void
+    // pointers. Compare the source types to determine if there's an
+    // inheritance relationship in their sources.
+    QualType FromType1 = SCS1.getFromType();
+    QualType FromType2 = SCS2.getFromType();
+
+    // Adjust the types we're converting from via the array-to-pointer
+    // conversion, if we need to.
+    if (SCS1.First == ICK_Array_To_Pointer)
+      FromType1 = Context.getArrayDecayedType(FromType1);
+    if (SCS2.First == ICK_Array_To_Pointer)
+      FromType2 = Context.getArrayDecayedType(FromType2);
+
+    QualType FromPointee1
+      = FromType1->getAs<PointerType>()->getPointeeType().getUnqualifiedType();
+    QualType FromPointee2
+      = FromType2->getAs<PointerType>()->getPointeeType().getUnqualifiedType();
+
+    if (IsDerivedFrom(FromPointee2, FromPointee1))
+      return ImplicitConversionSequence::Better;
+    else if (IsDerivedFrom(FromPointee1, FromPointee2))
+      return ImplicitConversionSequence::Worse;
+
+    // Objective-C++: If one interface is more specific than the
+    // other, it is the better one.
+    const ObjCInterfaceType* FromIface1 = FromPointee1->getAs<ObjCInterfaceType>();
+    const ObjCInterfaceType* FromIface2 = FromPointee2->getAs<ObjCInterfaceType>();
+    if (FromIface1 && FromIface1) {
+      if (Context.canAssignObjCInterfaces(FromIface2, FromIface1))
+        return ImplicitConversionSequence::Better;
+      else if (Context.canAssignObjCInterfaces(FromIface1, FromIface2))
+        return ImplicitConversionSequence::Worse;
+    }
+  }
+
+  // Compare based on qualification conversions (C++ 13.3.3.2p3,
+  // bullet 3).
+  if (ImplicitConversionSequence::CompareKind QualCK
+        = CompareQualificationConversions(SCS1, SCS2))
+    return QualCK;
+
+  if (SCS1.ReferenceBinding && SCS2.ReferenceBinding) {
+    // C++0x [over.ics.rank]p3b4:
+    //   -- S1 and S2 are reference bindings (8.5.3) and neither refers to an
+    //      implicit object parameter of a non-static member function declared
+    //      without a ref-qualifier, and S1 binds an rvalue reference to an
+    //      rvalue and S2 binds an lvalue reference.
+    // FIXME: We don't know if we're dealing with the implicit object parameter,
+    // or if the member function in this case has a ref qualifier.
+    // (Of course, we don't have ref qualifiers yet.)
+    if (SCS1.RRefBinding != SCS2.RRefBinding)
+      return SCS1.RRefBinding ? ImplicitConversionSequence::Better
+                              : ImplicitConversionSequence::Worse;
+
+    // C++ [over.ics.rank]p3b4:
+    //   -- S1 and S2 are reference bindings (8.5.3), and the types to
+    //      which the references refer are the same type except for
+    //      top-level cv-qualifiers, and the type to which the reference
+    //      initialized by S2 refers is more cv-qualified than the type
+    //      to which the reference initialized by S1 refers.
+    QualType T1 = SCS1.getToType(2);
+    QualType T2 = SCS2.getToType(2);
+    T1 = Context.getCanonicalType(T1);
+    T2 = Context.getCanonicalType(T2);
+    Qualifiers T1Quals, T2Quals;
+    QualType UnqualT1 = Context.getUnqualifiedArrayType(T1, T1Quals);
+    QualType UnqualT2 = Context.getUnqualifiedArrayType(T2, T2Quals);
+    if (UnqualT1 == UnqualT2) {
+      // If the type is an array type, promote the element qualifiers to the type
+      // for comparison.
+      if (isa<ArrayType>(T1) && T1Quals)
+        T1 = Context.getQualifiedType(UnqualT1, T1Quals);
+      if (isa<ArrayType>(T2) && T2Quals)
+        T2 = Context.getQualifiedType(UnqualT2, T2Quals);
+      if (T2.isMoreQualifiedThan(T1))
+        return ImplicitConversionSequence::Better;
+      else if (T1.isMoreQualifiedThan(T2))
+        return ImplicitConversionSequence::Worse;
+    }
+  }
+
+  return ImplicitConversionSequence::Indistinguishable;
+}
+
+/// CompareQualificationConversions - Compares two standard conversion
+/// sequences to determine whether they can be ranked based on their
+/// qualification conversions (C++ 13.3.3.2p3 bullet 3).
+ImplicitConversionSequence::CompareKind
+Sema::CompareQualificationConversions(const StandardConversionSequence& SCS1,
+                                      const StandardConversionSequence& SCS2) {
+  // C++ 13.3.3.2p3:
+  //  -- S1 and S2 differ only in their qualification conversion and
+  //     yield similar types T1 and T2 (C++ 4.4), respectively, and the
+  //     cv-qualification signature of type T1 is a proper subset of
+  //     the cv-qualification signature of type T2, and S1 is not the
+  //     deprecated string literal array-to-pointer conversion (4.2).
+  if (SCS1.First != SCS2.First || SCS1.Second != SCS2.Second ||
+      SCS1.Third != SCS2.Third || SCS1.Third != ICK_Qualification)
+    return ImplicitConversionSequence::Indistinguishable;
+
+  // FIXME: the example in the standard doesn't use a qualification
+  // conversion (!)
+  QualType T1 = SCS1.getToType(2);
+  QualType T2 = SCS2.getToType(2);
+  T1 = Context.getCanonicalType(T1);
+  T2 = Context.getCanonicalType(T2);
+  Qualifiers T1Quals, T2Quals;
+  QualType UnqualT1 = Context.getUnqualifiedArrayType(T1, T1Quals);
+  QualType UnqualT2 = Context.getUnqualifiedArrayType(T2, T2Quals);
+
+  // If the types are the same, we won't learn anything by unwrapped
+  // them.
+  if (UnqualT1 == UnqualT2)
+    return ImplicitConversionSequence::Indistinguishable;
+
+  // If the type is an array type, promote the element qualifiers to the type
+  // for comparison.
+  if (isa<ArrayType>(T1) && T1Quals)
+    T1 = Context.getQualifiedType(UnqualT1, T1Quals);
+  if (isa<ArrayType>(T2) && T2Quals)
+    T2 = Context.getQualifiedType(UnqualT2, T2Quals);
+
+  ImplicitConversionSequence::CompareKind Result
+    = ImplicitConversionSequence::Indistinguishable;
+  while (UnwrapSimilarPointerTypes(T1, T2)) {
+    // Within each iteration of the loop, we check the qualifiers to
+    // determine if this still looks like a qualification
+    // conversion. Then, if all is well, we unwrap one more level of
+    // pointers or pointers-to-members and do it all again
+    // until there are no more pointers or pointers-to-members left
+    // to unwrap. This essentially mimics what
+    // IsQualificationConversion does, but here we're checking for a
+    // strict subset of qualifiers.
+    if (T1.getCVRQualifiers() == T2.getCVRQualifiers())
+      // The qualifiers are the same, so this doesn't tell us anything
+      // about how the sequences rank.
+      ;
+    else if (T2.isMoreQualifiedThan(T1)) {
+      // T1 has fewer qualifiers, so it could be the better sequence.
+      if (Result == ImplicitConversionSequence::Worse)
+        // Neither has qualifiers that are a subset of the other's
+        // qualifiers.
+        return ImplicitConversionSequence::Indistinguishable;
+
+      Result = ImplicitConversionSequence::Better;
+    } else if (T1.isMoreQualifiedThan(T2)) {
+      // T2 has fewer qualifiers, so it could be the better sequence.
+      if (Result == ImplicitConversionSequence::Better)
+        // Neither has qualifiers that are a subset of the other's
+        // qualifiers.
+        return ImplicitConversionSequence::Indistinguishable;
+
+      Result = ImplicitConversionSequence::Worse;
+    } else {
+      // Qualifiers are disjoint.
+      return ImplicitConversionSequence::Indistinguishable;
+    }
+
+    // If the types after this point are equivalent, we're done.
+    if (Context.hasSameUnqualifiedType(T1, T2))
+      break;
+  }
+
+  // Check that the winning standard conversion sequence isn't using
+  // the deprecated string literal array to pointer conversion.
+  switch (Result) {
+  case ImplicitConversionSequence::Better:
+    if (SCS1.DeprecatedStringLiteralToCharPtr)
+      Result = ImplicitConversionSequence::Indistinguishable;
+    break;
+
+  case ImplicitConversionSequence::Indistinguishable:
+    break;
+
+  case ImplicitConversionSequence::Worse:
+    if (SCS2.DeprecatedStringLiteralToCharPtr)
+      Result = ImplicitConversionSequence::Indistinguishable;
+    break;
+  }
+
+  return Result;
+}
+
+/// CompareDerivedToBaseConversions - Compares two standard conversion
+/// sequences to determine whether they can be ranked based on their
+/// various kinds of derived-to-base conversions (C++
+/// [over.ics.rank]p4b3).  As part of these checks, we also look at
+/// conversions between Objective-C interface types.
+ImplicitConversionSequence::CompareKind
+Sema::CompareDerivedToBaseConversions(const StandardConversionSequence& SCS1,
+                                      const StandardConversionSequence& SCS2) {
+  QualType FromType1 = SCS1.getFromType();
+  QualType ToType1 = SCS1.getToType(1);
+  QualType FromType2 = SCS2.getFromType();
+  QualType ToType2 = SCS2.getToType(1);
+
+  // Adjust the types we're converting from via the array-to-pointer
+  // conversion, if we need to.
+  if (SCS1.First == ICK_Array_To_Pointer)
+    FromType1 = Context.getArrayDecayedType(FromType1);
+  if (SCS2.First == ICK_Array_To_Pointer)
+    FromType2 = Context.getArrayDecayedType(FromType2);
+
+  // Canonicalize all of the types.
+  FromType1 = Context.getCanonicalType(FromType1);
+  ToType1 = Context.getCanonicalType(ToType1);
+  FromType2 = Context.getCanonicalType(FromType2);
+  ToType2 = Context.getCanonicalType(ToType2);
+
+  // C++ [over.ics.rank]p4b3:
+  //
+  //   If class B is derived directly or indirectly from class A and
+  //   class C is derived directly or indirectly from B,
+  //
+  // For Objective-C, we let A, B, and C also be Objective-C
+  // interfaces.
+
+  // Compare based on pointer conversions.
+  if (SCS1.Second == ICK_Pointer_Conversion &&
+      SCS2.Second == ICK_Pointer_Conversion &&
+      /*FIXME: Remove if Objective-C id conversions get their own rank*/
+      FromType1->isPointerType() && FromType2->isPointerType() &&
+      ToType1->isPointerType() && ToType2->isPointerType()) {
+    QualType FromPointee1
+      = FromType1->getAs<PointerType>()->getPointeeType().getUnqualifiedType();
+    QualType ToPointee1
+      = ToType1->getAs<PointerType>()->getPointeeType().getUnqualifiedType();
+    QualType FromPointee2
+      = FromType2->getAs<PointerType>()->getPointeeType().getUnqualifiedType();
+    QualType ToPointee2
+      = ToType2->getAs<PointerType>()->getPointeeType().getUnqualifiedType();
+
+    const ObjCInterfaceType* FromIface1 = FromPointee1->getAs<ObjCInterfaceType>();
+    const ObjCInterfaceType* FromIface2 = FromPointee2->getAs<ObjCInterfaceType>();
+    const ObjCInterfaceType* ToIface1 = ToPointee1->getAs<ObjCInterfaceType>();
+    const ObjCInterfaceType* ToIface2 = ToPointee2->getAs<ObjCInterfaceType>();
+
+    //   -- conversion of C* to B* is better than conversion of C* to A*,
+    if (FromPointee1 == FromPointee2 && ToPointee1 != ToPointee2) {
+      if (IsDerivedFrom(ToPointee1, ToPointee2))
+        return ImplicitConversionSequence::Better;
+      else if (IsDerivedFrom(ToPointee2, ToPointee1))
+        return ImplicitConversionSequence::Worse;
+
+      if (ToIface1 && ToIface2) {
+        if (Context.canAssignObjCInterfaces(ToIface2, ToIface1))
+          return ImplicitConversionSequence::Better;
+        else if (Context.canAssignObjCInterfaces(ToIface1, ToIface2))
+          return ImplicitConversionSequence::Worse;
+      }
+    }
+
+    //   -- conversion of B* to A* is better than conversion of C* to A*,
+    if (FromPointee1 != FromPointee2 && ToPointee1 == ToPointee2) {
+      if (IsDerivedFrom(FromPointee2, FromPointee1))
+        return ImplicitConversionSequence::Better;
+      else if (IsDerivedFrom(FromPointee1, FromPointee2))
+        return ImplicitConversionSequence::Worse;
+
+      if (FromIface1 && FromIface2) {
+        if (Context.canAssignObjCInterfaces(FromIface1, FromIface2))
+          return ImplicitConversionSequence::Better;
+        else if (Context.canAssignObjCInterfaces(FromIface2, FromIface1))
+          return ImplicitConversionSequence::Worse;
+      }
+    }
+  }
+
+  // Ranking of member-pointer types.
+  if (SCS1.Second == ICK_Pointer_Member && SCS2.Second == ICK_Pointer_Member &&
+      FromType1->isMemberPointerType() && FromType2->isMemberPointerType() &&
+      ToType1->isMemberPointerType() && ToType2->isMemberPointerType()) {
+    const MemberPointerType * FromMemPointer1 = 
+                                        FromType1->getAs<MemberPointerType>();
+    const MemberPointerType * ToMemPointer1 = 
+                                          ToType1->getAs<MemberPointerType>();
+    const MemberPointerType * FromMemPointer2 = 
+                                          FromType2->getAs<MemberPointerType>();
+    const MemberPointerType * ToMemPointer2 = 
+                                          ToType2->getAs<MemberPointerType>();
+    const Type *FromPointeeType1 = FromMemPointer1->getClass();
+    const Type *ToPointeeType1 = ToMemPointer1->getClass();
+    const Type *FromPointeeType2 = FromMemPointer2->getClass();
+    const Type *ToPointeeType2 = ToMemPointer2->getClass();
+    QualType FromPointee1 = QualType(FromPointeeType1, 0).getUnqualifiedType();
+    QualType ToPointee1 = QualType(ToPointeeType1, 0).getUnqualifiedType();
+    QualType FromPointee2 = QualType(FromPointeeType2, 0).getUnqualifiedType();
+    QualType ToPointee2 = QualType(ToPointeeType2, 0).getUnqualifiedType();
+    // conversion of A::* to B::* is better than conversion of A::* to C::*,
+    if (FromPointee1 == FromPointee2 && ToPointee1 != ToPointee2) {
+      if (IsDerivedFrom(ToPointee1, ToPointee2))
+        return ImplicitConversionSequence::Worse;
+      else if (IsDerivedFrom(ToPointee2, ToPointee1))
+        return ImplicitConversionSequence::Better;
+    }
+    // conversion of B::* to C::* is better than conversion of A::* to C::*
+    if (ToPointee1 == ToPointee2 && FromPointee1 != FromPointee2) {
+      if (IsDerivedFrom(FromPointee1, FromPointee2))
+        return ImplicitConversionSequence::Better;
+      else if (IsDerivedFrom(FromPointee2, FromPointee1))
+        return ImplicitConversionSequence::Worse;
+    }
+  }
+  
+  if (SCS1.Second == ICK_Derived_To_Base) {
+    //   -- conversion of C to B is better than conversion of C to A,
+    //   -- binding of an expression of type C to a reference of type
+    //      B& is better than binding an expression of type C to a
+    //      reference of type A&,
+    if (Context.hasSameUnqualifiedType(FromType1, FromType2) &&
+        !Context.hasSameUnqualifiedType(ToType1, ToType2)) {
+      if (IsDerivedFrom(ToType1, ToType2))
+        return ImplicitConversionSequence::Better;
+      else if (IsDerivedFrom(ToType2, ToType1))
+        return ImplicitConversionSequence::Worse;
+    }
+
+    //   -- conversion of B to A is better than conversion of C to A.
+    //   -- binding of an expression of type B to a reference of type
+    //      A& is better than binding an expression of type C to a
+    //      reference of type A&,
+    if (!Context.hasSameUnqualifiedType(FromType1, FromType2) &&
+        Context.hasSameUnqualifiedType(ToType1, ToType2)) {
+      if (IsDerivedFrom(FromType2, FromType1))
+        return ImplicitConversionSequence::Better;
+      else if (IsDerivedFrom(FromType1, FromType2))
+        return ImplicitConversionSequence::Worse;
+    }
+  }
+
+  return ImplicitConversionSequence::Indistinguishable;
+}
+
+/// CompareReferenceRelationship - Compare the two types T1 and T2 to
+/// determine whether they are reference-related,
+/// reference-compatible, reference-compatible with added
+/// qualification, or incompatible, for use in C++ initialization by
+/// reference (C++ [dcl.ref.init]p4). Neither type can be a reference
+/// type, and the first type (T1) is the pointee type of the reference
+/// type being initialized.
+Sema::ReferenceCompareResult
+Sema::CompareReferenceRelationship(SourceLocation Loc,
+                                   QualType OrigT1, QualType OrigT2,
+                                   bool& DerivedToBase) {
+  assert(!OrigT1->isReferenceType() &&
+    "T1 must be the pointee type of the reference type");
+  assert(!OrigT2->isReferenceType() && "T2 cannot be a reference type");
+
+  QualType T1 = Context.getCanonicalType(OrigT1);
+  QualType T2 = Context.getCanonicalType(OrigT2);
+  Qualifiers T1Quals, T2Quals;
+  QualType UnqualT1 = Context.getUnqualifiedArrayType(T1, T1Quals);
+  QualType UnqualT2 = Context.getUnqualifiedArrayType(T2, T2Quals);
+
+  // C++ [dcl.init.ref]p4:
+  //   Given types "cv1 T1" and "cv2 T2," "cv1 T1" is
+  //   reference-related to "cv2 T2" if T1 is the same type as T2, or
+  //   T1 is a base class of T2.
+  if (UnqualT1 == UnqualT2)
+    DerivedToBase = false;
+  else if (!RequireCompleteType(Loc, OrigT1, PDiag()) &&
+           !RequireCompleteType(Loc, OrigT2, PDiag()) &&
+           IsDerivedFrom(UnqualT2, UnqualT1))
+    DerivedToBase = true;
+  else
+    return Ref_Incompatible;
+
+  // At this point, we know that T1 and T2 are reference-related (at
+  // least).
+
+  // If the type is an array type, promote the element qualifiers to the type
+  // for comparison.
+  if (isa<ArrayType>(T1) && T1Quals)
+    T1 = Context.getQualifiedType(UnqualT1, T1Quals);
+  if (isa<ArrayType>(T2) && T2Quals)
+    T2 = Context.getQualifiedType(UnqualT2, T2Quals);
+
+  // C++ [dcl.init.ref]p4:
+  //   "cv1 T1" is reference-compatible with "cv2 T2" if T1 is
+  //   reference-related to T2 and cv1 is the same cv-qualification
+  //   as, or greater cv-qualification than, cv2. For purposes of
+  //   overload resolution, cases for which cv1 is greater
+  //   cv-qualification than cv2 are identified as
+  //   reference-compatible with added qualification (see 13.3.3.2).
+  if (T1Quals.getCVRQualifiers() == T2Quals.getCVRQualifiers())
+    return Ref_Compatible;
+  else if (T1.isMoreQualifiedThan(T2))
+    return Ref_Compatible_With_Added_Qualification;
+  else
+    return Ref_Related;
+}
+
+/// \brief Compute an implicit conversion sequence for reference
+/// initialization.
+static ImplicitConversionSequence
+TryReferenceInit(Sema &S, Expr *&Init, QualType DeclType,
+                 SourceLocation DeclLoc,
+                 bool SuppressUserConversions,
+                 bool AllowExplicit) {
+  assert(DeclType->isReferenceType() && "Reference init needs a reference");
+
+  // Most paths end in a failed conversion.
+  ImplicitConversionSequence ICS;
+  ICS.setBad(BadConversionSequence::no_conversion, Init, DeclType);
+
+  QualType T1 = DeclType->getAs<ReferenceType>()->getPointeeType();
+  QualType T2 = Init->getType();
+
+  // If the initializer is the address of an overloaded function, try
+  // to resolve the overloaded function. If all goes well, T2 is the
+  // type of the resulting function.
+  if (S.Context.getCanonicalType(T2) == S.Context.OverloadTy) {
+    DeclAccessPair Found;
+    if (FunctionDecl *Fn = S.ResolveAddressOfOverloadedFunction(Init, DeclType,
+                                                                false, Found))
+      T2 = Fn->getType();
+  }
+
+  // Compute some basic properties of the types and the initializer.
+  bool isRValRef = DeclType->isRValueReferenceType();
+  bool DerivedToBase = false;
+  Expr::isLvalueResult InitLvalue = Init->isLvalue(S.Context);
+  Sema::ReferenceCompareResult RefRelationship
+    = S.CompareReferenceRelationship(DeclLoc, T1, T2, DerivedToBase);
+
+
+  // C++ [over.ics.ref]p3:
+  //   Except for an implicit object parameter, for which see 13.3.1,
+  //   a standard conversion sequence cannot be formed if it requires
+  //   binding an lvalue reference to non-const to an rvalue or
+  //   binding an rvalue reference to an lvalue.
+  //
+  // FIXME: DPG doesn't trust this code. It seems far too early to
+  // abort because of a binding of an rvalue reference to an lvalue.
+  if (isRValRef && InitLvalue == Expr::LV_Valid)
+    return ICS;
+
+  // C++0x [dcl.init.ref]p16:
+  //   A reference to type "cv1 T1" is initialized by an expression
+  //   of type "cv2 T2" as follows:
+
+  //     -- If the initializer expression
+  //       -- is an lvalue (but is not a bit-field), and "cv1 T1" is
+  //          reference-compatible with "cv2 T2," or
+  //
+  // Per C++ [over.ics.ref]p4, we don't check the bit-field property here.
+  if (InitLvalue == Expr::LV_Valid &&
+      RefRelationship >= Sema::Ref_Compatible_With_Added_Qualification) {
+    // C++ [over.ics.ref]p1:
+    //   When a parameter of reference type binds directly (8.5.3)
+    //   to an argument expression, the implicit conversion sequence
+    //   is the identity conversion, unless the argument expression
+    //   has a type that is a derived class of the parameter type,
+    //   in which case the implicit conversion sequence is a
+    //   derived-to-base Conversion (13.3.3.1).
+    ICS.setStandard();
+    ICS.Standard.First = ICK_Identity;
+    ICS.Standard.Second = DerivedToBase? ICK_Derived_To_Base : ICK_Identity;
+    ICS.Standard.Third = ICK_Identity;
+    ICS.Standard.FromTypePtr = T2.getAsOpaquePtr();
+    ICS.Standard.setToType(0, T2);
+    ICS.Standard.setToType(1, T1);
+    ICS.Standard.setToType(2, T1);
+    ICS.Standard.ReferenceBinding = true;
+    ICS.Standard.DirectBinding = true;
+    ICS.Standard.RRefBinding = false;
+    ICS.Standard.CopyConstructor = 0;
+
+    // Nothing more to do: the inaccessibility/ambiguity check for
+    // derived-to-base conversions is suppressed when we're
+    // computing the implicit conversion sequence (C++
+    // [over.best.ics]p2).
+    return ICS;
+  }
+
+  //       -- has a class type (i.e., T2 is a class type), where T1 is
+  //          not reference-related to T2, and can be implicitly
+  //          converted to an lvalue of type "cv3 T3," where "cv1 T1"
+  //          is reference-compatible with "cv3 T3" 92) (this
+  //          conversion is selected by enumerating the applicable
+  //          conversion functions (13.3.1.6) and choosing the best
+  //          one through overload resolution (13.3)),
+  if (!isRValRef && !SuppressUserConversions && T2->isRecordType() &&
+      !S.RequireCompleteType(DeclLoc, T2, 0) && 
+      RefRelationship == Sema::Ref_Incompatible) {
+    CXXRecordDecl *T2RecordDecl
+      = dyn_cast<CXXRecordDecl>(T2->getAs<RecordType>()->getDecl());
+
+    OverloadCandidateSet CandidateSet(DeclLoc);
+    const UnresolvedSetImpl *Conversions
+      = T2RecordDecl->getVisibleConversionFunctions();
+    for (UnresolvedSetImpl::iterator I = Conversions->begin(),
+           E = Conversions->end(); I != E; ++I) {
+      NamedDecl *D = *I;
+      CXXRecordDecl *ActingDC = cast<CXXRecordDecl>(D->getDeclContext());
+      if (isa<UsingShadowDecl>(D))
+        D = cast<UsingShadowDecl>(D)->getTargetDecl();
+
+      FunctionTemplateDecl *ConvTemplate
+        = dyn_cast<FunctionTemplateDecl>(D);
+      CXXConversionDecl *Conv;
+      if (ConvTemplate)
+        Conv = cast<CXXConversionDecl>(ConvTemplate->getTemplatedDecl());
+      else
+        Conv = cast<CXXConversionDecl>(D);
+      
+      // If the conversion function doesn't return a reference type,
+      // it can't be considered for this conversion.
+      if (Conv->getConversionType()->isLValueReferenceType() &&
+          (AllowExplicit || !Conv->isExplicit())) {
+        if (ConvTemplate)
+          S.AddTemplateConversionCandidate(ConvTemplate, I.getPair(), ActingDC,
+                                         Init, DeclType, CandidateSet);
+        else
+          S.AddConversionCandidate(Conv, I.getPair(), ActingDC, Init,
+                                 DeclType, CandidateSet);
+      }
+    }
+
+    OverloadCandidateSet::iterator Best;
+    switch (S.BestViableFunction(CandidateSet, DeclLoc, Best)) {
+    case OR_Success:
+      // C++ [over.ics.ref]p1:
+      //
+      //   [...] If the parameter binds directly to the result of
+      //   applying a conversion function to the argument
+      //   expression, the implicit conversion sequence is a
+      //   user-defined conversion sequence (13.3.3.1.2), with the
+      //   second standard conversion sequence either an identity
+      //   conversion or, if the conversion function returns an
+      //   entity of a type that is a derived class of the parameter
+      //   type, a derived-to-base Conversion.
+      if (!Best->FinalConversion.DirectBinding)
+        break;
+
+      ICS.setUserDefined();
+      ICS.UserDefined.Before = Best->Conversions[0].Standard;
+      ICS.UserDefined.After = Best->FinalConversion;
+      ICS.UserDefined.ConversionFunction = Best->Function;
+      ICS.UserDefined.EllipsisConversion = false;
+      assert(ICS.UserDefined.After.ReferenceBinding &&
+             ICS.UserDefined.After.DirectBinding &&
+             "Expected a direct reference binding!");
+      return ICS;
+
+    case OR_Ambiguous:
+      ICS.setAmbiguous();
+      for (OverloadCandidateSet::iterator Cand = CandidateSet.begin();
+           Cand != CandidateSet.end(); ++Cand)
+        if (Cand->Viable)
+          ICS.Ambiguous.addConversion(Cand->Function);
+      return ICS;
+
+    case OR_No_Viable_Function:
+    case OR_Deleted:
+      // There was no suitable conversion, or we found a deleted
+      // conversion; continue with other checks.
+      break;
+    }
+  }
+
+  //     -- Otherwise, the reference shall be to a non-volatile const
+  //        type (i.e., cv1 shall be const), or the reference shall be an
+  //        rvalue reference and the initializer expression shall be an rvalue.
+  // 
+  // We actually handle one oddity of C++ [over.ics.ref] at this
+  // point, which is that, due to p2 (which short-circuits reference
+  // binding by only attempting a simple conversion for non-direct
+  // bindings) and p3's strange wording, we allow a const volatile
+  // reference to bind to an rvalue. Hence the check for the presence
+  // of "const" rather than checking for "const" being the only
+  // qualifier.
+  if (!isRValRef && !T1.isConstQualified())
+    return ICS;
+
+  //       -- if T2 is a class type and
+  //          -- the initializer expression is an rvalue and "cv1 T1"
+  //             is reference-compatible with "cv2 T2," or
+  //
+  //          -- T1 is not reference-related to T2 and the initializer
+  //             expression can be implicitly converted to an rvalue
+  //             of type "cv3 T3" (this conversion is selected by
+  //             enumerating the applicable conversion functions
+  //             (13.3.1.6) and choosing the best one through overload
+  //             resolution (13.3)),
+  //
+  //          then the reference is bound to the initializer
+  //          expression rvalue in the first case and to the object
+  //          that is the result of the conversion in the second case
+  //          (or, in either case, to the appropriate base class
+  //          subobject of the object).
+  //
+  // We're only checking the first case here, which is a direct
+  // binding in C++0x but not in C++03.
+  if (InitLvalue != Expr::LV_Valid && T2->isRecordType() &&
+      RefRelationship >= Sema::Ref_Compatible_With_Added_Qualification) {
+    ICS.setStandard();
+    ICS.Standard.First = ICK_Identity;
+    ICS.Standard.Second = DerivedToBase? ICK_Derived_To_Base : ICK_Identity;
+    ICS.Standard.Third = ICK_Identity;
+    ICS.Standard.FromTypePtr = T2.getAsOpaquePtr();
+    ICS.Standard.setToType(0, T2);
+    ICS.Standard.setToType(1, T1);
+    ICS.Standard.setToType(2, T1);
+    ICS.Standard.ReferenceBinding = true;
+    ICS.Standard.DirectBinding = S.getLangOptions().CPlusPlus0x;
+    ICS.Standard.RRefBinding = isRValRef;
+    ICS.Standard.CopyConstructor = 0;
+    return ICS;
+  }
+
+  //       -- Otherwise, a temporary of type "cv1 T1" is created and
+  //          initialized from the initializer expression using the
+  //          rules for a non-reference copy initialization (8.5). The
+  //          reference is then bound to the temporary. If T1 is
+  //          reference-related to T2, cv1 must be the same
+  //          cv-qualification as, or greater cv-qualification than,
+  //          cv2; otherwise, the program is ill-formed.
+  if (RefRelationship == Sema::Ref_Related) {
+    // If cv1 == cv2 or cv1 is a greater cv-qualified than cv2, then
+    // we would be reference-compatible or reference-compatible with
+    // added qualification. But that wasn't the case, so the reference
+    // initialization fails.
+    return ICS;
+  }
+
+  // If at least one of the types is a class type, the types are not
+  // related, and we aren't allowed any user conversions, the
+  // reference binding fails. This case is important for breaking
+  // recursion, since TryImplicitConversion below will attempt to
+  // create a temporary through the use of a copy constructor.
+  if (SuppressUserConversions && RefRelationship == Sema::Ref_Incompatible &&
+      (T1->isRecordType() || T2->isRecordType()))
+    return ICS;
+
+  // C++ [over.ics.ref]p2:
+  //   When a parameter of reference type is not bound directly to
+  //   an argument expression, the conversion sequence is the one
+  //   required to convert the argument expression to the
+  //   underlying type of the reference according to
+  //   13.3.3.1. Conceptually, this conversion sequence corresponds
+  //   to copy-initializing a temporary of the underlying type with
+  //   the argument expression. Any difference in top-level
+  //   cv-qualification is subsumed by the initialization itself
+  //   and does not constitute a conversion.
+  ICS = S.TryImplicitConversion(Init, T1, SuppressUserConversions,
+                                /*AllowExplicit=*/false,
+                                /*InOverloadResolution=*/false);
+
+  // Of course, that's still a reference binding.
+  if (ICS.isStandard()) {
+    ICS.Standard.ReferenceBinding = true;
+    ICS.Standard.RRefBinding = isRValRef;
+  } else if (ICS.isUserDefined()) {
+    ICS.UserDefined.After.ReferenceBinding = true;
+    ICS.UserDefined.After.RRefBinding = isRValRef;
+  }
+  return ICS;
+}
+
+/// TryCopyInitialization - Try to copy-initialize a value of type
+/// ToType from the expression From. Return the implicit conversion
+/// sequence required to pass this argument, which may be a bad
+/// conversion sequence (meaning that the argument cannot be passed to
+/// a parameter of this type). If @p SuppressUserConversions, then we
+/// do not permit any user-defined conversion sequences.
+static ImplicitConversionSequence
+TryCopyInitialization(Sema &S, Expr *From, QualType ToType,
+                      bool SuppressUserConversions, 
+                      bool InOverloadResolution) {
+  if (ToType->isReferenceType())
+    return TryReferenceInit(S, From, ToType,
+                            /*FIXME:*/From->getLocStart(),
+                            SuppressUserConversions,
+                            /*AllowExplicit=*/false);
+
+  return S.TryImplicitConversion(From, ToType,
+                                 SuppressUserConversions,
+                                 /*AllowExplicit=*/false,
+                                 InOverloadResolution);
+}
+
+/// TryObjectArgumentInitialization - Try to initialize the object
+/// parameter of the given member function (@c Method) from the
+/// expression @p From.
+ImplicitConversionSequence
+Sema::TryObjectArgumentInitialization(QualType OrigFromType,
+                                      CXXMethodDecl *Method,
+                                      CXXRecordDecl *ActingContext) {
+  QualType ClassType = Context.getTypeDeclType(ActingContext);
+  // [class.dtor]p2: A destructor can be invoked for a const, volatile or
+  //                 const volatile object.
+  unsigned Quals = isa<CXXDestructorDecl>(Method) ?
+    Qualifiers::Const | Qualifiers::Volatile : Method->getTypeQualifiers();
+  QualType ImplicitParamType =  Context.getCVRQualifiedType(ClassType, Quals);
+
+  // Set up the conversion sequence as a "bad" conversion, to allow us
+  // to exit early.
+  ImplicitConversionSequence ICS;
+
+  // We need to have an object of class type.
+  QualType FromType = OrigFromType;
+  if (const PointerType *PT = FromType->getAs<PointerType>())
+    FromType = PT->getPointeeType();
+
+  assert(FromType->isRecordType());
+
+  // The implicit object parameter is has the type "reference to cv X",
+  // where X is the class of which the function is a member
+  // (C++ [over.match.funcs]p4). However, when finding an implicit
+  // conversion sequence for the argument, we are not allowed to
+  // create temporaries or perform user-defined conversions
+  // (C++ [over.match.funcs]p5). We perform a simplified version of
+  // reference binding here, that allows class rvalues to bind to
+  // non-constant references.
+
+  // First check the qualifiers. We don't care about lvalue-vs-rvalue
+  // with the implicit object parameter (C++ [over.match.funcs]p5).
+  QualType FromTypeCanon = Context.getCanonicalType(FromType);
+  if (ImplicitParamType.getCVRQualifiers() 
+                                    != FromTypeCanon.getLocalCVRQualifiers() &&
+      !ImplicitParamType.isAtLeastAsQualifiedAs(FromTypeCanon)) {
+    ICS.setBad(BadConversionSequence::bad_qualifiers,
+               OrigFromType, ImplicitParamType);
+    return ICS;
+  }
+
+  // Check that we have either the same type or a derived type. It
+  // affects the conversion rank.
+  QualType ClassTypeCanon = Context.getCanonicalType(ClassType);
+  ImplicitConversionKind SecondKind;
+  if (ClassTypeCanon == FromTypeCanon.getLocalUnqualifiedType()) {
+    SecondKind = ICK_Identity;
+  } else if (IsDerivedFrom(FromType, ClassType))
+    SecondKind = ICK_Derived_To_Base;
+  else {
+    ICS.setBad(BadConversionSequence::unrelated_class,
+               FromType, ImplicitParamType);
+    return ICS;
+  }
+
+  // Success. Mark this as a reference binding.
+  ICS.setStandard();
+  ICS.Standard.setAsIdentityConversion();
+  ICS.Standard.Second = SecondKind;
+  ICS.Standard.setFromType(FromType);
+  ICS.Standard.setAllToTypes(ImplicitParamType);
+  ICS.Standard.ReferenceBinding = true;
+  ICS.Standard.DirectBinding = true;
+  ICS.Standard.RRefBinding = false;
+  return ICS;
+}
+
+/// PerformObjectArgumentInitialization - Perform initialization of
+/// the implicit object parameter for the given Method with the given
+/// expression.
+bool
+Sema::PerformObjectArgumentInitialization(Expr *&From, 
+                                          NestedNameSpecifier *Qualifier, 
+                                          NamedDecl *FoundDecl,
+                                          CXXMethodDecl *Method) {
+  QualType FromRecordType, DestType;
+  QualType ImplicitParamRecordType  =
+    Method->getThisType(Context)->getAs<PointerType>()->getPointeeType();
+
+  if (const PointerType *PT = From->getType()->getAs<PointerType>()) {
+    FromRecordType = PT->getPointeeType();
+    DestType = Method->getThisType(Context);
+  } else {
+    FromRecordType = From->getType();
+    DestType = ImplicitParamRecordType;
+  }
+
+  // Note that we always use the true parent context when performing
+  // the actual argument initialization.
+  ImplicitConversionSequence ICS
+    = TryObjectArgumentInitialization(From->getType(), Method,
+                                      Method->getParent());
+  if (ICS.isBad())
+    return Diag(From->getSourceRange().getBegin(),
+                diag::err_implicit_object_parameter_init)
+       << ImplicitParamRecordType << FromRecordType << From->getSourceRange();
+
+  if (ICS.Standard.Second == ICK_Derived_To_Base)
+    return PerformObjectMemberConversion(From, Qualifier, FoundDecl, Method);
+
+  if (!Context.hasSameType(From->getType(), DestType))
+    ImpCastExprToType(From, DestType, CastExpr::CK_NoOp,
+                      /*isLvalue=*/!From->getType()->isPointerType());
+  return false;
+}
+
+/// TryContextuallyConvertToBool - Attempt to contextually convert the
+/// expression From to bool (C++0x [conv]p3).
+ImplicitConversionSequence Sema::TryContextuallyConvertToBool(Expr *From) {
+  return TryImplicitConversion(From, Context.BoolTy,
+                               // FIXME: Are these flags correct?
+                               /*SuppressUserConversions=*/false,
+                               /*AllowExplicit=*/true,
+                               /*InOverloadResolution=*/false);
+}
+
+/// PerformContextuallyConvertToBool - Perform a contextual conversion
+/// of the expression From to bool (C++0x [conv]p3).
+bool Sema::PerformContextuallyConvertToBool(Expr *&From) {
+  ImplicitConversionSequence ICS = TryContextuallyConvertToBool(From);
+  if (!ICS.isBad())
+    return PerformImplicitConversion(From, Context.BoolTy, ICS, AA_Converting);
+  
+  if (!DiagnoseMultipleUserDefinedConversion(From, Context.BoolTy))
+    return  Diag(From->getSourceRange().getBegin(),
+                 diag::err_typecheck_bool_condition)
+                  << From->getType() << From->getSourceRange();
+  return true;
+}
+
+/// AddOverloadCandidate - Adds the given function to the set of
+/// candidate functions, using the given function call arguments.  If
+/// @p SuppressUserConversions, then don't allow user-defined
+/// conversions via constructors or conversion operators.
+///
+/// \para PartialOverloading true if we are performing "partial" overloading
+/// based on an incomplete set of function arguments. This feature is used by
+/// code completion.
+void
+Sema::AddOverloadCandidate(FunctionDecl *Function,
+                           DeclAccessPair FoundDecl,
+                           Expr **Args, unsigned NumArgs,
+                           OverloadCandidateSet& CandidateSet,
+                           bool SuppressUserConversions,
+                           bool PartialOverloading) {
+  const FunctionProtoType* Proto
+    = dyn_cast<FunctionProtoType>(Function->getType()->getAs<FunctionType>());
+  assert(Proto && "Functions without a prototype cannot be overloaded");
+  assert(!Function->getDescribedFunctionTemplate() &&
+         "Use AddTemplateOverloadCandidate for function templates");
+
+  if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Function)) {
+    if (!isa<CXXConstructorDecl>(Method)) {
+      // If we get here, it's because we're calling a member function
+      // that is named without a member access expression (e.g.,
+      // "this->f") that was either written explicitly or created
+      // implicitly. This can happen with a qualified call to a member
+      // function, e.g., X::f(). We use an empty type for the implied
+      // object argument (C++ [over.call.func]p3), and the acting context
+      // is irrelevant.
+      AddMethodCandidate(Method, FoundDecl, Method->getParent(),
+                         QualType(), Args, NumArgs, CandidateSet,
+                         SuppressUserConversions);
+      return;
+    }
+    // We treat a constructor like a non-member function, since its object
+    // argument doesn't participate in overload resolution.
+  }
+
+  if (!CandidateSet.isNewCandidate(Function))
+    return;
+
+  // Overload resolution is always an unevaluated context.
+  EnterExpressionEvaluationContext Unevaluated(*this, Action::Unevaluated);
+
+  if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(Function)){
+    // C++ [class.copy]p3:
+    //   A member function template is never instantiated to perform the copy
+    //   of a class object to an object of its class type.
+    QualType ClassType = Context.getTypeDeclType(Constructor->getParent());
+    if (NumArgs == 1 && 
+        Constructor->isCopyConstructorLikeSpecialization() &&
+        (Context.hasSameUnqualifiedType(ClassType, Args[0]->getType()) ||
+         IsDerivedFrom(Args[0]->getType(), ClassType)))
+      return;
+  }
+  
+  // Add this candidate
+  CandidateSet.push_back(OverloadCandidate());
+  OverloadCandidate& Candidate = CandidateSet.back();
+  Candidate.FoundDecl = FoundDecl;
+  Candidate.Function = Function;
+  Candidate.Viable = true;
+  Candidate.IsSurrogate = false;
+  Candidate.IgnoreObjectArgument = false;
+
+  unsigned NumArgsInProto = Proto->getNumArgs();
+
+  // (C++ 13.3.2p2): A candidate function having fewer than m
+  // parameters is viable only if it has an ellipsis in its parameter
+  // list (8.3.5).
+  if ((NumArgs + (PartialOverloading && NumArgs)) > NumArgsInProto && 
+      !Proto->isVariadic()) {
+    Candidate.Viable = false;
+    Candidate.FailureKind = ovl_fail_too_many_arguments;
+    return;
+  }
+
+  // (C++ 13.3.2p2): A candidate function having more than m parameters
+  // is viable only if the (m+1)st parameter has a default argument
+  // (8.3.6). For the purposes of overload resolution, the
+  // parameter list is truncated on the right, so that there are
+  // exactly m parameters.
+  unsigned MinRequiredArgs = Function->getMinRequiredArguments();
+  if (NumArgs < MinRequiredArgs && !PartialOverloading) {
+    // Not enough arguments.
+    Candidate.Viable = false;
+    Candidate.FailureKind = ovl_fail_too_few_arguments;
+    return;
+  }
+
+  // Determine the implicit conversion sequences for each of the
+  // arguments.
+  Candidate.Conversions.resize(NumArgs);
+  for (unsigned ArgIdx = 0; ArgIdx < NumArgs; ++ArgIdx) {
+    if (ArgIdx < NumArgsInProto) {
+      // (C++ 13.3.2p3): for F to be a viable function, there shall
+      // exist for each argument an implicit conversion sequence
+      // (13.3.3.1) that converts that argument to the corresponding
+      // parameter of F.
+      QualType ParamType = Proto->getArgType(ArgIdx);
+      Candidate.Conversions[ArgIdx]
+        = TryCopyInitialization(*this, Args[ArgIdx], ParamType,
+                                SuppressUserConversions, 
+                                /*InOverloadResolution=*/true);
+      if (Candidate.Conversions[ArgIdx].isBad()) {
+        Candidate.Viable = false;
+        Candidate.FailureKind = ovl_fail_bad_conversion;
+        break;
+      }
+    } else {
+      // (C++ 13.3.2p2): For the purposes of overload resolution, any
+      // argument for which there is no corresponding parameter is
+      // considered to ""match the ellipsis" (C+ 13.3.3.1.3).
+      Candidate.Conversions[ArgIdx].setEllipsis();
+    }
+  }
+}
+
+/// \brief Add all of the function declarations in the given function set to
+/// the overload canddiate set.
+void Sema::AddFunctionCandidates(const UnresolvedSetImpl &Fns,
+                                 Expr **Args, unsigned NumArgs,
+                                 OverloadCandidateSet& CandidateSet,
+                                 bool SuppressUserConversions) {
+  for (UnresolvedSetIterator F = Fns.begin(), E = Fns.end(); F != E; ++F) {
+    NamedDecl *D = F.getDecl()->getUnderlyingDecl();
+    if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+      if (isa<CXXMethodDecl>(FD) && !cast<CXXMethodDecl>(FD)->isStatic())
+        AddMethodCandidate(cast<CXXMethodDecl>(FD), F.getPair(),
+                           cast<CXXMethodDecl>(FD)->getParent(),
+                           Args[0]->getType(), Args + 1, NumArgs - 1, 
+                           CandidateSet, SuppressUserConversions);
+      else
+        AddOverloadCandidate(FD, F.getPair(), Args, NumArgs, CandidateSet,
+                             SuppressUserConversions);
+    } else {
+      FunctionTemplateDecl *FunTmpl = cast<FunctionTemplateDecl>(D);
+      if (isa<CXXMethodDecl>(FunTmpl->getTemplatedDecl()) &&
+          !cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl())->isStatic())
+        AddMethodTemplateCandidate(FunTmpl, F.getPair(),
+                              cast<CXXRecordDecl>(FunTmpl->getDeclContext()),
+                                   /*FIXME: explicit args */ 0,
+                                   Args[0]->getType(), Args + 1, NumArgs - 1,
+                                   CandidateSet,
+                                   SuppressUserConversions);
+      else
+        AddTemplateOverloadCandidate(FunTmpl, F.getPair(),
+                                     /*FIXME: explicit args */ 0,
+                                     Args, NumArgs, CandidateSet,
+                                     SuppressUserConversions);
+    }
+  }
+}
+
+/// AddMethodCandidate - Adds a named decl (which is some kind of
+/// method) as a method candidate to the given overload set.
+void Sema::AddMethodCandidate(DeclAccessPair FoundDecl,
+                              QualType ObjectType,
+                              Expr **Args, unsigned NumArgs,
+                              OverloadCandidateSet& CandidateSet,
+                              bool SuppressUserConversions) {
+  NamedDecl *Decl = FoundDecl.getDecl();
+  CXXRecordDecl *ActingContext = cast<CXXRecordDecl>(Decl->getDeclContext());
+
+  if (isa<UsingShadowDecl>(Decl))
+    Decl = cast<UsingShadowDecl>(Decl)->getTargetDecl();
+  
+  if (FunctionTemplateDecl *TD = dyn_cast<FunctionTemplateDecl>(Decl)) {
+    assert(isa<CXXMethodDecl>(TD->getTemplatedDecl()) &&
+           "Expected a member function template");
+    AddMethodTemplateCandidate(TD, FoundDecl, ActingContext,
+                               /*ExplicitArgs*/ 0,
+                               ObjectType, Args, NumArgs,
+                               CandidateSet,
+                               SuppressUserConversions);
+  } else {
+    AddMethodCandidate(cast<CXXMethodDecl>(Decl), FoundDecl, ActingContext,
+                       ObjectType, Args, NumArgs,
+                       CandidateSet, SuppressUserConversions);
+  }
+}
+
+/// AddMethodCandidate - Adds the given C++ member function to the set
+/// of candidate functions, using the given function call arguments
+/// and the object argument (@c Object). For example, in a call
+/// @c o.f(a1,a2), @c Object will contain @c o and @c Args will contain
+/// both @c a1 and @c a2. If @p SuppressUserConversions, then don't
+/// allow user-defined conversions via constructors or conversion
+/// operators.
+void
+Sema::AddMethodCandidate(CXXMethodDecl *Method, DeclAccessPair FoundDecl,
+                         CXXRecordDecl *ActingContext, QualType ObjectType,
+                         Expr **Args, unsigned NumArgs,
+                         OverloadCandidateSet& CandidateSet,
+                         bool SuppressUserConversions) {
+  const FunctionProtoType* Proto
+    = dyn_cast<FunctionProtoType>(Method->getType()->getAs<FunctionType>());
+  assert(Proto && "Methods without a prototype cannot be overloaded");
+  assert(!isa<CXXConstructorDecl>(Method) &&
+         "Use AddOverloadCandidate for constructors");
+
+  if (!CandidateSet.isNewCandidate(Method))
+    return;
+
+  // Overload resolution is always an unevaluated context.
+  EnterExpressionEvaluationContext Unevaluated(*this, Action::Unevaluated);
+
+  // Add this candidate
+  CandidateSet.push_back(OverloadCandidate());
+  OverloadCandidate& Candidate = CandidateSet.back();
+  Candidate.FoundDecl = FoundDecl;
+  Candidate.Function = Method;
+  Candidate.IsSurrogate = false;
+  Candidate.IgnoreObjectArgument = false;
+
+  unsigned NumArgsInProto = Proto->getNumArgs();
+
+  // (C++ 13.3.2p2): A candidate function having fewer than m
+  // parameters is viable only if it has an ellipsis in its parameter
+  // list (8.3.5).
+  if (NumArgs > NumArgsInProto && !Proto->isVariadic()) {
+    Candidate.Viable = false;
+    Candidate.FailureKind = ovl_fail_too_many_arguments;
+    return;
+  }
+
+  // (C++ 13.3.2p2): A candidate function having more than m parameters
+  // is viable only if the (m+1)st parameter has a default argument
+  // (8.3.6). For the purposes of overload resolution, the
+  // parameter list is truncated on the right, so that there are
+  // exactly m parameters.
+  unsigned MinRequiredArgs = Method->getMinRequiredArguments();
+  if (NumArgs < MinRequiredArgs) {
+    // Not enough arguments.
+    Candidate.Viable = false;
+    Candidate.FailureKind = ovl_fail_too_few_arguments;
+    return;
+  }
+
+  Candidate.Viable = true;
+  Candidate.Conversions.resize(NumArgs + 1);
+
+  if (Method->isStatic() || ObjectType.isNull())
+    // The implicit object argument is ignored.
+    Candidate.IgnoreObjectArgument = true;
+  else {
+    // Determine the implicit conversion sequence for the object
+    // parameter.
+    Candidate.Conversions[0]
+      = TryObjectArgumentInitialization(ObjectType, Method, ActingContext);
+    if (Candidate.Conversions[0].isBad()) {
+      Candidate.Viable = false;
+      Candidate.FailureKind = ovl_fail_bad_conversion;
+      return;
+    }
+  }
+
+  // Determine the implicit conversion sequences for each of the
+  // arguments.
+  for (unsigned ArgIdx = 0; ArgIdx < NumArgs; ++ArgIdx) {
+    if (ArgIdx < NumArgsInProto) {
+      // (C++ 13.3.2p3): for F to be a viable function, there shall
+      // exist for each argument an implicit conversion sequence
+      // (13.3.3.1) that converts that argument to the corresponding
+      // parameter of F.
+      QualType ParamType = Proto->getArgType(ArgIdx);
+      Candidate.Conversions[ArgIdx + 1]
+        = TryCopyInitialization(*this, Args[ArgIdx], ParamType,
+                                SuppressUserConversions, 
+                                /*InOverloadResolution=*/true);
+      if (Candidate.Conversions[ArgIdx + 1].isBad()) {
+        Candidate.Viable = false;
+        Candidate.FailureKind = ovl_fail_bad_conversion;
+        break;
+      }
+    } else {
+      // (C++ 13.3.2p2): For the purposes of overload resolution, any
+      // argument for which there is no corresponding parameter is
+      // considered to ""match the ellipsis" (C+ 13.3.3.1.3).
+      Candidate.Conversions[ArgIdx + 1].setEllipsis();
+    }
+  }
+}
+
+/// \brief Add a C++ member function template as a candidate to the candidate
+/// set, using template argument deduction to produce an appropriate member
+/// function template specialization.
+void
+Sema::AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl,
+                                 DeclAccessPair FoundDecl,
+                                 CXXRecordDecl *ActingContext,
+                        const TemplateArgumentListInfo *ExplicitTemplateArgs,
+                                 QualType ObjectType,
+                                 Expr **Args, unsigned NumArgs,
+                                 OverloadCandidateSet& CandidateSet,
+                                 bool SuppressUserConversions) {
+  if (!CandidateSet.isNewCandidate(MethodTmpl))
+    return;
+
+  // C++ [over.match.funcs]p7:
+  //   In each case where a candidate is a function template, candidate
+  //   function template specializations are generated using template argument
+  //   deduction (14.8.3, 14.8.2). Those candidates are then handled as
+  //   candidate functions in the usual way.113) A given name can refer to one
+  //   or more function templates and also to a set of overloaded non-template
+  //   functions. In such a case, the candidate functions generated from each
+  //   function template are combined with the set of non-template candidate
+  //   functions.
+  TemplateDeductionInfo Info(Context, CandidateSet.getLocation());
+  FunctionDecl *Specialization = 0;
+  if (TemplateDeductionResult Result
+      = DeduceTemplateArguments(MethodTmpl, ExplicitTemplateArgs,
+                                Args, NumArgs, Specialization, Info)) {
+        // FIXME: Record what happened with template argument deduction, so
+        // that we can give the user a beautiful diagnostic.
+        (void)Result;
+        return;
+      }
+
+  // Add the function template specialization produced by template argument
+  // deduction as a candidate.
+  assert(Specialization && "Missing member function template specialization?");
+  assert(isa<CXXMethodDecl>(Specialization) &&
+         "Specialization is not a member function?");
+  AddMethodCandidate(cast<CXXMethodDecl>(Specialization), FoundDecl,
+                     ActingContext, ObjectType, Args, NumArgs,
+                     CandidateSet, SuppressUserConversions);
+}
+
+/// \brief Add a C++ function template specialization as a candidate
+/// in the candidate set, using template argument deduction to produce
+/// an appropriate function template specialization.
+void
+Sema::AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate,
+                                   DeclAccessPair FoundDecl,
+                        const TemplateArgumentListInfo *ExplicitTemplateArgs,
+                                   Expr **Args, unsigned NumArgs,
+                                   OverloadCandidateSet& CandidateSet,
+                                   bool SuppressUserConversions) {
+  if (!CandidateSet.isNewCandidate(FunctionTemplate))
+    return;
+
+  // C++ [over.match.funcs]p7:
+  //   In each case where a candidate is a function template, candidate
+  //   function template specializations are generated using template argument
+  //   deduction (14.8.3, 14.8.2). Those candidates are then handled as
+  //   candidate functions in the usual way.113) A given name can refer to one
+  //   or more function templates and also to a set of overloaded non-template
+  //   functions. In such a case, the candidate functions generated from each
+  //   function template are combined with the set of non-template candidate
+  //   functions.
+  TemplateDeductionInfo Info(Context, CandidateSet.getLocation());
+  FunctionDecl *Specialization = 0;
+  if (TemplateDeductionResult Result
+        = DeduceTemplateArguments(FunctionTemplate, ExplicitTemplateArgs,
+                                  Args, NumArgs, Specialization, Info)) {
+    CandidateSet.push_back(OverloadCandidate());
+    OverloadCandidate &Candidate = CandidateSet.back();
+    Candidate.FoundDecl = FoundDecl;
+    Candidate.Function = FunctionTemplate->getTemplatedDecl();
+    Candidate.Viable = false;
+    Candidate.FailureKind = ovl_fail_bad_deduction;
+    Candidate.IsSurrogate = false;
+    Candidate.IgnoreObjectArgument = false;
+
+    // TODO: record more information about failed template arguments
+    Candidate.DeductionFailure.Result = Result;
+    Candidate.DeductionFailure.TemplateParameter = Info.Param.getOpaqueValue();
+    return;
+  }
+
+  // Add the function template specialization produced by template argument
+  // deduction as a candidate.
+  assert(Specialization && "Missing function template specialization?");
+  AddOverloadCandidate(Specialization, FoundDecl, Args, NumArgs, CandidateSet,
+                       SuppressUserConversions);
+}
+
+/// AddConversionCandidate - Add a C++ conversion function as a
+/// candidate in the candidate set (C++ [over.match.conv],
+/// C++ [over.match.copy]). From is the expression we're converting from,
+/// and ToType is the type that we're eventually trying to convert to
+/// (which may or may not be the same type as the type that the
+/// conversion function produces).
+void
+Sema::AddConversionCandidate(CXXConversionDecl *Conversion,
+                             DeclAccessPair FoundDecl,
+                             CXXRecordDecl *ActingContext,
+                             Expr *From, QualType ToType,
+                             OverloadCandidateSet& CandidateSet) {
+  assert(!Conversion->getDescribedFunctionTemplate() &&
+         "Conversion function templates use AddTemplateConversionCandidate");
+  QualType ConvType = Conversion->getConversionType().getNonReferenceType();
+  if (!CandidateSet.isNewCandidate(Conversion))
+    return;
+
+  // Overload resolution is always an unevaluated context.
+  EnterExpressionEvaluationContext Unevaluated(*this, Action::Unevaluated);
+
+  // Add this candidate
+  CandidateSet.push_back(OverloadCandidate());
+  OverloadCandidate& Candidate = CandidateSet.back();
+  Candidate.FoundDecl = FoundDecl;
+  Candidate.Function = Conversion;
+  Candidate.IsSurrogate = false;
+  Candidate.IgnoreObjectArgument = false;
+  Candidate.FinalConversion.setAsIdentityConversion();
+  Candidate.FinalConversion.setFromType(ConvType);
+  Candidate.FinalConversion.setAllToTypes(ToType);
+
+  // Determine the implicit conversion sequence for the implicit
+  // object parameter.
+  Candidate.Viable = true;
+  Candidate.Conversions.resize(1);
+  Candidate.Conversions[0]
+    = TryObjectArgumentInitialization(From->getType(), Conversion,
+                                      ActingContext);
+  // Conversion functions to a different type in the base class is visible in 
+  // the derived class.  So, a derived to base conversion should not participate
+  // in overload resolution. 
+  if (Candidate.Conversions[0].Standard.Second == ICK_Derived_To_Base)
+    Candidate.Conversions[0].Standard.Second = ICK_Identity;
+  if (Candidate.Conversions[0].isBad()) {
+    Candidate.Viable = false;
+    Candidate.FailureKind = ovl_fail_bad_conversion;
+    return;
+  }
+  
+  // We won't go through a user-define type conversion function to convert a 
+  // derived to base as such conversions are given Conversion Rank. They only
+  // go through a copy constructor. 13.3.3.1.2-p4 [over.ics.user]
+  QualType FromCanon
+    = Context.getCanonicalType(From->getType().getUnqualifiedType());
+  QualType ToCanon = Context.getCanonicalType(ToType).getUnqualifiedType();
+  if (FromCanon == ToCanon || IsDerivedFrom(FromCanon, ToCanon)) {
+    Candidate.Viable = false;
+    Candidate.FailureKind = ovl_fail_trivial_conversion;
+    return;
+  }
+  
+  // To determine what the conversion from the result of calling the
+  // conversion function to the type we're eventually trying to
+  // convert to (ToType), we need to synthesize a call to the
+  // conversion function and attempt copy initialization from it. This
+  // makes sure that we get the right semantics with respect to
+  // lvalues/rvalues and the type. Fortunately, we can allocate this
+  // call on the stack and we don't need its arguments to be
+  // well-formed.
+  DeclRefExpr ConversionRef(Conversion, Conversion->getType(),
+                            From->getLocStart());
+  ImplicitCastExpr ConversionFn(Context.getPointerType(Conversion->getType()),
+                                CastExpr::CK_FunctionToPointerDecay,
+                                &ConversionRef, CXXBaseSpecifierArray(), false);
+
+  // Note that it is safe to allocate CallExpr on the stack here because
+  // there are 0 arguments (i.e., nothing is allocated using ASTContext's
+  // allocator).
+  CallExpr Call(Context, &ConversionFn, 0, 0,
+                Conversion->getConversionType().getNonReferenceType(),
+                From->getLocStart());
+  ImplicitConversionSequence ICS =
+    TryCopyInitialization(*this, &Call, ToType,
+                          /*SuppressUserConversions=*/true,
+                          /*InOverloadResolution=*/false);
+
+  switch (ICS.getKind()) {
+  case ImplicitConversionSequence::StandardConversion:
+    Candidate.FinalConversion = ICS.Standard;
+      
+    // C++ [over.ics.user]p3:
+    //   If the user-defined conversion is specified by a specialization of a
+    //   conversion function template, the second standard conversion sequence 
+    //   shall have exact match rank.
+    if (Conversion->getPrimaryTemplate() &&
+        GetConversionRank(ICS.Standard.Second) != ICR_Exact_Match) {
+      Candidate.Viable = false;
+      Candidate.FailureKind = ovl_fail_final_conversion_not_exact;
+    }
+      
+    break;
+
+  case ImplicitConversionSequence::BadConversion:
+    Candidate.Viable = false;
+    Candidate.FailureKind = ovl_fail_bad_final_conversion;
+    break;
+
+  default:
+    assert(false &&
+           "Can only end up with a standard conversion sequence or failure");
+  }
+}
+
+/// \brief Adds a conversion function template specialization
+/// candidate to the overload set, using template argument deduction
+/// to deduce the template arguments of the conversion function
+/// template from the type that we are converting to (C++
+/// [temp.deduct.conv]).
+void
+Sema::AddTemplateConversionCandidate(FunctionTemplateDecl *FunctionTemplate,
+                                     DeclAccessPair FoundDecl,
+                                     CXXRecordDecl *ActingDC,
+                                     Expr *From, QualType ToType,
+                                     OverloadCandidateSet &CandidateSet) {
+  assert(isa<CXXConversionDecl>(FunctionTemplate->getTemplatedDecl()) &&
+         "Only conversion function templates permitted here");
+
+  if (!CandidateSet.isNewCandidate(FunctionTemplate))
+    return;
+
+  TemplateDeductionInfo Info(Context, CandidateSet.getLocation());
+  CXXConversionDecl *Specialization = 0;
+  if (TemplateDeductionResult Result
+        = DeduceTemplateArguments(FunctionTemplate, ToType,
+                                  Specialization, Info)) {
+    // FIXME: Record what happened with template argument deduction, so
+    // that we can give the user a beautiful diagnostic.
+    (void)Result;
+    return;
+  }
+
+  // Add the conversion function template specialization produced by
+  // template argument deduction as a candidate.
+  assert(Specialization && "Missing function template specialization?");
+  AddConversionCandidate(Specialization, FoundDecl, ActingDC, From, ToType,
+                         CandidateSet);
+}
+
+/// AddSurrogateCandidate - Adds a "surrogate" candidate function that
+/// converts the given @c Object to a function pointer via the
+/// conversion function @c Conversion, and then attempts to call it
+/// with the given arguments (C++ [over.call.object]p2-4). Proto is
+/// the type of function that we'll eventually be calling.
+void Sema::AddSurrogateCandidate(CXXConversionDecl *Conversion,
+                                 DeclAccessPair FoundDecl,
+                                 CXXRecordDecl *ActingContext,
+                                 const FunctionProtoType *Proto,
+                                 QualType ObjectType,
+                                 Expr **Args, unsigned NumArgs,
+                                 OverloadCandidateSet& CandidateSet) {
+  if (!CandidateSet.isNewCandidate(Conversion))
+    return;
+
+  // Overload resolution is always an unevaluated context.
+  EnterExpressionEvaluationContext Unevaluated(*this, Action::Unevaluated);
+
+  CandidateSet.push_back(OverloadCandidate());
+  OverloadCandidate& Candidate = CandidateSet.back();
+  Candidate.FoundDecl = FoundDecl;
+  Candidate.Function = 0;
+  Candidate.Surrogate = Conversion;
+  Candidate.Viable = true;
+  Candidate.IsSurrogate = true;
+  Candidate.IgnoreObjectArgument = false;
+  Candidate.Conversions.resize(NumArgs + 1);
+
+  // Determine the implicit conversion sequence for the implicit
+  // object parameter.
+  ImplicitConversionSequence ObjectInit
+    = TryObjectArgumentInitialization(ObjectType, Conversion, ActingContext);
+  if (ObjectInit.isBad()) {
+    Candidate.Viable = false;
+    Candidate.FailureKind = ovl_fail_bad_conversion;
+    Candidate.Conversions[0] = ObjectInit;
+    return;
+  }
+
+  // The first conversion is actually a user-defined conversion whose
+  // first conversion is ObjectInit's standard conversion (which is
+  // effectively a reference binding). Record it as such.
+  Candidate.Conversions[0].setUserDefined();
+  Candidate.Conversions[0].UserDefined.Before = ObjectInit.Standard;
+  Candidate.Conversions[0].UserDefined.EllipsisConversion = false;
+  Candidate.Conversions[0].UserDefined.ConversionFunction = Conversion;
+  Candidate.Conversions[0].UserDefined.After
+    = Candidate.Conversions[0].UserDefined.Before;
+  Candidate.Conversions[0].UserDefined.After.setAsIdentityConversion();
+
+  // Find the
+  unsigned NumArgsInProto = Proto->getNumArgs();
+
+  // (C++ 13.3.2p2): A candidate function having fewer than m
+  // parameters is viable only if it has an ellipsis in its parameter
+  // list (8.3.5).
+  if (NumArgs > NumArgsInProto && !Proto->isVariadic()) {
+    Candidate.Viable = false;
+    Candidate.FailureKind = ovl_fail_too_many_arguments;
+    return;
+  }
+
+  // Function types don't have any default arguments, so just check if
+  // we have enough arguments.
+  if (NumArgs < NumArgsInProto) {
+    // Not enough arguments.
+    Candidate.Viable = false;
+    Candidate.FailureKind = ovl_fail_too_few_arguments;
+    return;
+  }
+
+  // Determine the implicit conversion sequences for each of the
+  // arguments.
+  for (unsigned ArgIdx = 0; ArgIdx < NumArgs; ++ArgIdx) {
+    if (ArgIdx < NumArgsInProto) {
+      // (C++ 13.3.2p3): for F to be a viable function, there shall
+      // exist for each argument an implicit conversion sequence
+      // (13.3.3.1) that converts that argument to the corresponding
+      // parameter of F.
+      QualType ParamType = Proto->getArgType(ArgIdx);
+      Candidate.Conversions[ArgIdx + 1]
+        = TryCopyInitialization(*this, Args[ArgIdx], ParamType,
+                                /*SuppressUserConversions=*/false,
+                                /*InOverloadResolution=*/false);
+      if (Candidate.Conversions[ArgIdx + 1].isBad()) {
+        Candidate.Viable = false;
+        Candidate.FailureKind = ovl_fail_bad_conversion;
+        break;
+      }
+    } else {
+      // (C++ 13.3.2p2): For the purposes of overload resolution, any
+      // argument for which there is no corresponding parameter is
+      // considered to ""match the ellipsis" (C+ 13.3.3.1.3).
+      Candidate.Conversions[ArgIdx + 1].setEllipsis();
+    }
+  }
+}
+
+/// \brief Add overload candidates for overloaded operators that are
+/// member functions.
+///
+/// Add the overloaded operator candidates that are member functions
+/// for the operator Op that was used in an operator expression such
+/// as "x Op y". , Args/NumArgs provides the operator arguments, and
+/// CandidateSet will store the added overload candidates. (C++
+/// [over.match.oper]).
+void Sema::AddMemberOperatorCandidates(OverloadedOperatorKind Op,
+                                       SourceLocation OpLoc,
+                                       Expr **Args, unsigned NumArgs,
+                                       OverloadCandidateSet& CandidateSet,
+                                       SourceRange OpRange) {
+  DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(Op);
+
+  // C++ [over.match.oper]p3:
+  //   For a unary operator @ with an operand of a type whose
+  //   cv-unqualified version is T1, and for a binary operator @ with
+  //   a left operand of a type whose cv-unqualified version is T1 and
+  //   a right operand of a type whose cv-unqualified version is T2,
+  //   three sets of candidate functions, designated member
+  //   candidates, non-member candidates and built-in candidates, are
+  //   constructed as follows:
+  QualType T1 = Args[0]->getType();
+  QualType T2;
+  if (NumArgs > 1)
+    T2 = Args[1]->getType();
+
+  //     -- If T1 is a class type, the set of member candidates is the
+  //        result of the qualified lookup of T1::operator@
+  //        (13.3.1.1.1); otherwise, the set of member candidates is
+  //        empty.
+  if (const RecordType *T1Rec = T1->getAs<RecordType>()) {
+    // Complete the type if it can be completed. Otherwise, we're done.
+    if (RequireCompleteType(OpLoc, T1, PDiag()))
+      return;
+
+    LookupResult Operators(*this, OpName, OpLoc, LookupOrdinaryName);
+    LookupQualifiedName(Operators, T1Rec->getDecl());
+    Operators.suppressDiagnostics();
+
+    for (LookupResult::iterator Oper = Operators.begin(),
+                             OperEnd = Operators.end();
+         Oper != OperEnd;
+         ++Oper)
+      AddMethodCandidate(Oper.getPair(), Args[0]->getType(),
+                         Args + 1, NumArgs - 1, CandidateSet,
+                         /* SuppressUserConversions = */ false);
+  }
+}
+
+/// AddBuiltinCandidate - Add a candidate for a built-in
+/// operator. ResultTy and ParamTys are the result and parameter types
+/// of the built-in candidate, respectively. Args and NumArgs are the
+/// arguments being passed to the candidate. IsAssignmentOperator
+/// should be true when this built-in candidate is an assignment
+/// operator. NumContextualBoolArguments is the number of arguments
+/// (at the beginning of the argument list) that will be contextually
+/// converted to bool.
+void Sema::AddBuiltinCandidate(QualType ResultTy, QualType *ParamTys,
+                               Expr **Args, unsigned NumArgs,
+                               OverloadCandidateSet& CandidateSet,
+                               bool IsAssignmentOperator,
+                               unsigned NumContextualBoolArguments) {
+  // Overload resolution is always an unevaluated context.
+  EnterExpressionEvaluationContext Unevaluated(*this, Action::Unevaluated);
+
+  // Add this candidate
+  CandidateSet.push_back(OverloadCandidate());
+  OverloadCandidate& Candidate = CandidateSet.back();
+  Candidate.FoundDecl = DeclAccessPair::make(0, AS_none);
+  Candidate.Function = 0;
+  Candidate.IsSurrogate = false;
+  Candidate.IgnoreObjectArgument = false;
+  Candidate.BuiltinTypes.ResultTy = ResultTy;
+  for (unsigned ArgIdx = 0; ArgIdx < NumArgs; ++ArgIdx)
+    Candidate.BuiltinTypes.ParamTypes[ArgIdx] = ParamTys[ArgIdx];
+
+  // Determine the implicit conversion sequences for each of the
+  // arguments.
+  Candidate.Viable = true;
+  Candidate.Conversions.resize(NumArgs);
+  for (unsigned ArgIdx = 0; ArgIdx < NumArgs; ++ArgIdx) {
+    // C++ [over.match.oper]p4:
+    //   For the built-in assignment operators, conversions of the
+    //   left operand are restricted as follows:
+    //     -- no temporaries are introduced to hold the left operand, and
+    //     -- no user-defined conversions are applied to the left
+    //        operand to achieve a type match with the left-most
+    //        parameter of a built-in candidate.
+    //
+    // We block these conversions by turning off user-defined
+    // conversions, since that is the only way that initialization of
+    // a reference to a non-class type can occur from something that
+    // is not of the same type.
+    if (ArgIdx < NumContextualBoolArguments) {
+      assert(ParamTys[ArgIdx] == Context.BoolTy &&
+             "Contextual conversion to bool requires bool type");
+      Candidate.Conversions[ArgIdx] = TryContextuallyConvertToBool(Args[ArgIdx]);
+    } else {
+      Candidate.Conversions[ArgIdx]
+        = TryCopyInitialization(*this, Args[ArgIdx], ParamTys[ArgIdx],
+                                ArgIdx == 0 && IsAssignmentOperator,
+                                /*InOverloadResolution=*/false);
+    }
+    if (Candidate.Conversions[ArgIdx].isBad()) {
+      Candidate.Viable = false;
+      Candidate.FailureKind = ovl_fail_bad_conversion;
+      break;
+    }
+  }
+}
+
+/// BuiltinCandidateTypeSet - A set of types that will be used for the
+/// candidate operator functions for built-in operators (C++
+/// [over.built]). The types are separated into pointer types and
+/// enumeration types.
+class BuiltinCandidateTypeSet  {
+  /// TypeSet - A set of types.
+  typedef llvm::SmallPtrSet<QualType, 8> TypeSet;
+
+  /// PointerTypes - The set of pointer types that will be used in the
+  /// built-in candidates.
+  TypeSet PointerTypes;
+
+  /// MemberPointerTypes - The set of member pointer types that will be
+  /// used in the built-in candidates.
+  TypeSet MemberPointerTypes;
+
+  /// EnumerationTypes - The set of enumeration types that will be
+  /// used in the built-in candidates.
+  TypeSet EnumerationTypes;
+
+  /// Sema - The semantic analysis instance where we are building the
+  /// candidate type set.
+  Sema &SemaRef;
+
+  /// Context - The AST context in which we will build the type sets.
+  ASTContext &Context;
+
+  bool AddPointerWithMoreQualifiedTypeVariants(QualType Ty,
+                                               const Qualifiers &VisibleQuals);
+  bool AddMemberPointerWithMoreQualifiedTypeVariants(QualType Ty);
+
+public:
+  /// iterator - Iterates through the types that are part of the set.
+  typedef TypeSet::iterator iterator;
+
+  BuiltinCandidateTypeSet(Sema &SemaRef)
+    : SemaRef(SemaRef), Context(SemaRef.Context) { }
+
+  void AddTypesConvertedFrom(QualType Ty, 
+                             SourceLocation Loc,
+                             bool AllowUserConversions,
+                             bool AllowExplicitConversions,
+                             const Qualifiers &VisibleTypeConversionsQuals);
+
+  /// pointer_begin - First pointer type found;
+  iterator pointer_begin() { return PointerTypes.begin(); }
+
+  /// pointer_end - Past the last pointer type found;
+  iterator pointer_end() { return PointerTypes.end(); }
+
+  /// member_pointer_begin - First member pointer type found;
+  iterator member_pointer_begin() { return MemberPointerTypes.begin(); }
+
+  /// member_pointer_end - Past the last member pointer type found;
+  iterator member_pointer_end() { return MemberPointerTypes.end(); }
+
+  /// enumeration_begin - First enumeration type found;
+  iterator enumeration_begin() { return EnumerationTypes.begin(); }
+
+  /// enumeration_end - Past the last enumeration type found;
+  iterator enumeration_end() { return EnumerationTypes.end(); }
+};
+
+/// AddPointerWithMoreQualifiedTypeVariants - Add the pointer type @p Ty to
+/// the set of pointer types along with any more-qualified variants of
+/// that type. For example, if @p Ty is "int const *", this routine
+/// will add "int const *", "int const volatile *", "int const
+/// restrict *", and "int const volatile restrict *" to the set of
+/// pointer types. Returns true if the add of @p Ty itself succeeded,
+/// false otherwise.
+///
+/// FIXME: what to do about extended qualifiers?
+bool
+BuiltinCandidateTypeSet::AddPointerWithMoreQualifiedTypeVariants(QualType Ty,
+                                             const Qualifiers &VisibleQuals) {
+
+  // Insert this type.
+  if (!PointerTypes.insert(Ty))
+    return false;
+
+  const PointerType *PointerTy = Ty->getAs<PointerType>();
+  assert(PointerTy && "type was not a pointer type!");
+
+  QualType PointeeTy = PointerTy->getPointeeType();
+  // Don't add qualified variants of arrays. For one, they're not allowed
+  // (the qualifier would sink to the element type), and for another, the
+  // only overload situation where it matters is subscript or pointer +- int,
+  // and those shouldn't have qualifier variants anyway.
+  if (PointeeTy->isArrayType())
+    return true;
+  unsigned BaseCVR = PointeeTy.getCVRQualifiers();
+  if (const ConstantArrayType *Array =Context.getAsConstantArrayType(PointeeTy))
+    BaseCVR = Array->getElementType().getCVRQualifiers();
+  bool hasVolatile = VisibleQuals.hasVolatile();
+  bool hasRestrict = VisibleQuals.hasRestrict();
+  
+  // Iterate through all strict supersets of BaseCVR.
+  for (unsigned CVR = BaseCVR+1; CVR <= Qualifiers::CVRMask; ++CVR) {
+    if ((CVR | BaseCVR) != CVR) continue;
+    // Skip over Volatile/Restrict if no Volatile/Restrict found anywhere
+    // in the types.
+    if ((CVR & Qualifiers::Volatile) && !hasVolatile) continue;
+    if ((CVR & Qualifiers::Restrict) && !hasRestrict) continue;
+    QualType QPointeeTy = Context.getCVRQualifiedType(PointeeTy, CVR);
+    PointerTypes.insert(Context.getPointerType(QPointeeTy));
+  }
+
+  return true;
+}
+
+/// AddMemberPointerWithMoreQualifiedTypeVariants - Add the pointer type @p Ty
+/// to the set of pointer types along with any more-qualified variants of
+/// that type. For example, if @p Ty is "int const *", this routine
+/// will add "int const *", "int const volatile *", "int const
+/// restrict *", and "int const volatile restrict *" to the set of
+/// pointer types. Returns true if the add of @p Ty itself succeeded,
+/// false otherwise.
+///
+/// FIXME: what to do about extended qualifiers?
+bool
+BuiltinCandidateTypeSet::AddMemberPointerWithMoreQualifiedTypeVariants(
+    QualType Ty) {
+  // Insert this type.
+  if (!MemberPointerTypes.insert(Ty))
+    return false;
+
+  const MemberPointerType *PointerTy = Ty->getAs<MemberPointerType>();
+  assert(PointerTy && "type was not a member pointer type!");
+
+  QualType PointeeTy = PointerTy->getPointeeType();
+  // Don't add qualified variants of arrays. For one, they're not allowed
+  // (the qualifier would sink to the element type), and for another, the
+  // only overload situation where it matters is subscript or pointer +- int,
+  // and those shouldn't have qualifier variants anyway.
+  if (PointeeTy->isArrayType())
+    return true;
+  const Type *ClassTy = PointerTy->getClass();
+
+  // Iterate through all strict supersets of the pointee type's CVR
+  // qualifiers.
+  unsigned BaseCVR = PointeeTy.getCVRQualifiers();
+  for (unsigned CVR = BaseCVR+1; CVR <= Qualifiers::CVRMask; ++CVR) {
+    if ((CVR | BaseCVR) != CVR) continue;
+    
+    QualType QPointeeTy = Context.getCVRQualifiedType(PointeeTy, CVR);
+    MemberPointerTypes.insert(Context.getMemberPointerType(QPointeeTy, ClassTy));
+  }
+
+  return true;
+}
+
+/// AddTypesConvertedFrom - Add each of the types to which the type @p
+/// Ty can be implicit converted to the given set of @p Types. We're
+/// primarily interested in pointer types and enumeration types. We also
+/// take member pointer types, for the conditional operator.
+/// AllowUserConversions is true if we should look at the conversion
+/// functions of a class type, and AllowExplicitConversions if we
+/// should also include the explicit conversion functions of a class
+/// type.
+void
+BuiltinCandidateTypeSet::AddTypesConvertedFrom(QualType Ty,
+                                               SourceLocation Loc,
+                                               bool AllowUserConversions,
+                                               bool AllowExplicitConversions,
+                                               const Qualifiers &VisibleQuals) {
+  // Only deal with canonical types.
+  Ty = Context.getCanonicalType(Ty);
+
+  // Look through reference types; they aren't part of the type of an
+  // expression for the purposes of conversions.
+  if (const ReferenceType *RefTy = Ty->getAs<ReferenceType>())
+    Ty = RefTy->getPointeeType();
+
+  // We don't care about qualifiers on the type.
+  Ty = Ty.getLocalUnqualifiedType();
+
+  // If we're dealing with an array type, decay to the pointer.
+  if (Ty->isArrayType())
+    Ty = SemaRef.Context.getArrayDecayedType(Ty);
+
+  if (const PointerType *PointerTy = Ty->getAs<PointerType>()) {
+    QualType PointeeTy = PointerTy->getPointeeType();
+
+    // Insert our type, and its more-qualified variants, into the set
+    // of types.
+    if (!AddPointerWithMoreQualifiedTypeVariants(Ty, VisibleQuals))
+      return;
+  } else if (Ty->isMemberPointerType()) {
+    // Member pointers are far easier, since the pointee can't be converted.
+    if (!AddMemberPointerWithMoreQualifiedTypeVariants(Ty))
+      return;
+  } else if (Ty->isEnumeralType()) {
+    EnumerationTypes.insert(Ty);
+  } else if (AllowUserConversions) {
+    if (const RecordType *TyRec = Ty->getAs<RecordType>()) {
+      if (SemaRef.RequireCompleteType(Loc, Ty, 0)) {
+        // No conversion functions in incomplete types.
+        return;
+      }
+
+      CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(TyRec->getDecl());
+      const UnresolvedSetImpl *Conversions
+        = ClassDecl->getVisibleConversionFunctions();
+      for (UnresolvedSetImpl::iterator I = Conversions->begin(),
+             E = Conversions->end(); I != E; ++I) {
+        NamedDecl *D = I.getDecl();
+        if (isa<UsingShadowDecl>(D))
+          D = cast<UsingShadowDecl>(D)->getTargetDecl();
+
+        // Skip conversion function templates; they don't tell us anything
+        // about which builtin types we can convert to.
+        if (isa<FunctionTemplateDecl>(D))
+          continue;
+
+        CXXConversionDecl *Conv = cast<CXXConversionDecl>(D);
+        if (AllowExplicitConversions || !Conv->isExplicit()) {
+          AddTypesConvertedFrom(Conv->getConversionType(), Loc, false, false, 
+                                VisibleQuals);
+        }
+      }
+    }
+  }
+}
+
+/// \brief Helper function for AddBuiltinOperatorCandidates() that adds
+/// the volatile- and non-volatile-qualified assignment operators for the
+/// given type to the candidate set.
+static void AddBuiltinAssignmentOperatorCandidates(Sema &S,
+                                                   QualType T,
+                                                   Expr **Args,
+                                                   unsigned NumArgs,
+                                    OverloadCandidateSet &CandidateSet) {
+  QualType ParamTypes[2];
+
+  // T& operator=(T&, T)
+  ParamTypes[0] = S.Context.getLValueReferenceType(T);
+  ParamTypes[1] = T;
+  S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2, CandidateSet,
+                        /*IsAssignmentOperator=*/true);
+
+  if (!S.Context.getCanonicalType(T).isVolatileQualified()) {
+    // volatile T& operator=(volatile T&, T)
+    ParamTypes[0]
+      = S.Context.getLValueReferenceType(S.Context.getVolatileType(T));
+    ParamTypes[1] = T;
+    S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2, CandidateSet,
+                          /*IsAssignmentOperator=*/true);
+  }
+}
+
+/// CollectVRQualifiers - This routine returns Volatile/Restrict qualifiers,
+/// if any, found in visible type conversion functions found in ArgExpr's type.
+static  Qualifiers CollectVRQualifiers(ASTContext &Context, Expr* ArgExpr) {
+    Qualifiers VRQuals;
+    const RecordType *TyRec;
+    if (const MemberPointerType *RHSMPType =
+        ArgExpr->getType()->getAs<MemberPointerType>())
+      TyRec = RHSMPType->getClass()->getAs<RecordType>();
+    else
+      TyRec = ArgExpr->getType()->getAs<RecordType>();
+    if (!TyRec) {
+      // Just to be safe, assume the worst case.
+      VRQuals.addVolatile();
+      VRQuals.addRestrict();
+      return VRQuals;
+    }
+    
+    CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(TyRec->getDecl());
+    if (!ClassDecl->hasDefinition())
+      return VRQuals;
+
+    const UnresolvedSetImpl *Conversions =
+      ClassDecl->getVisibleConversionFunctions();
+    
+    for (UnresolvedSetImpl::iterator I = Conversions->begin(),
+           E = Conversions->end(); I != E; ++I) {
+      NamedDecl *D = I.getDecl();
+      if (isa<UsingShadowDecl>(D))
+        D = cast<UsingShadowDecl>(D)->getTargetDecl();
+      if (CXXConversionDecl *Conv = dyn_cast<CXXConversionDecl>(D)) {
+        QualType CanTy = Context.getCanonicalType(Conv->getConversionType());
+        if (const ReferenceType *ResTypeRef = CanTy->getAs<ReferenceType>())
+          CanTy = ResTypeRef->getPointeeType();
+        // Need to go down the pointer/mempointer chain and add qualifiers
+        // as see them.
+        bool done = false;
+        while (!done) {
+          if (const PointerType *ResTypePtr = CanTy->getAs<PointerType>())
+            CanTy = ResTypePtr->getPointeeType();
+          else if (const MemberPointerType *ResTypeMPtr = 
+                CanTy->getAs<MemberPointerType>())
+            CanTy = ResTypeMPtr->getPointeeType();
+          else
+            done = true;
+          if (CanTy.isVolatileQualified())
+            VRQuals.addVolatile();
+          if (CanTy.isRestrictQualified())
+            VRQuals.addRestrict();
+          if (VRQuals.hasRestrict() && VRQuals.hasVolatile())
+            return VRQuals;
+        }
+      }
+    }
+    return VRQuals;
+}
+  
+/// AddBuiltinOperatorCandidates - Add the appropriate built-in
+/// operator overloads to the candidate set (C++ [over.built]), based
+/// on the operator @p Op and the arguments given. For example, if the
+/// operator is a binary '+', this routine might add "int
+/// operator+(int, int)" to cover integer addition.
+void
+Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
+                                   SourceLocation OpLoc,
+                                   Expr **Args, unsigned NumArgs,
+                                   OverloadCandidateSet& CandidateSet) {
+  // The set of "promoted arithmetic types", which are the arithmetic
+  // types are that preserved by promotion (C++ [over.built]p2). Note
+  // that the first few of these types are the promoted integral
+  // types; these types need to be first.
+  // FIXME: What about complex?
+  const unsigned FirstIntegralType = 0;
+  const unsigned LastIntegralType = 13;
+  const unsigned FirstPromotedIntegralType = 7,
+                 LastPromotedIntegralType = 13;
+  const unsigned FirstPromotedArithmeticType = 7,
+                 LastPromotedArithmeticType = 16;
+  const unsigned NumArithmeticTypes = 16;
+  QualType ArithmeticTypes[NumArithmeticTypes] = {
+    Context.BoolTy, Context.CharTy, Context.WCharTy,
+// FIXME:   Context.Char16Ty, Context.Char32Ty,
+    Context.SignedCharTy, Context.ShortTy,
+    Context.UnsignedCharTy, Context.UnsignedShortTy,
+    Context.IntTy, Context.LongTy, Context.LongLongTy,
+    Context.UnsignedIntTy, Context.UnsignedLongTy, Context.UnsignedLongLongTy,
+    Context.FloatTy, Context.DoubleTy, Context.LongDoubleTy
+  };
+  assert(ArithmeticTypes[FirstPromotedIntegralType] == Context.IntTy &&
+         "Invalid first promoted integral type");
+  assert(ArithmeticTypes[LastPromotedIntegralType - 1] 
+           == Context.UnsignedLongLongTy &&
+         "Invalid last promoted integral type");
+  assert(ArithmeticTypes[FirstPromotedArithmeticType] == Context.IntTy &&
+         "Invalid first promoted arithmetic type");
+  assert(ArithmeticTypes[LastPromotedArithmeticType - 1] 
+            == Context.LongDoubleTy &&
+         "Invalid last promoted arithmetic type");
+         
+  // Find all of the types that the arguments can convert to, but only
+  // if the operator we're looking at has built-in operator candidates
+  // that make use of these types.
+  Qualifiers VisibleTypeConversionsQuals;
+  VisibleTypeConversionsQuals.addConst();
+  for (unsigned ArgIdx = 0; ArgIdx < NumArgs; ++ArgIdx)
+    VisibleTypeConversionsQuals += CollectVRQualifiers(Context, Args[ArgIdx]);
+  
+  BuiltinCandidateTypeSet CandidateTypes(*this);
+  if (Op == OO_Less || Op == OO_Greater || Op == OO_LessEqual ||
+      Op == OO_GreaterEqual || Op == OO_EqualEqual || Op == OO_ExclaimEqual ||
+      Op == OO_Plus || (Op == OO_Minus && NumArgs == 2) || Op == OO_Equal ||
+      Op == OO_PlusEqual || Op == OO_MinusEqual || Op == OO_Subscript ||
+      Op == OO_ArrowStar || Op == OO_PlusPlus || Op == OO_MinusMinus ||
+      (Op == OO_Star && NumArgs == 1) || Op == OO_Conditional) {
+    for (unsigned ArgIdx = 0; ArgIdx < NumArgs; ++ArgIdx)
+      CandidateTypes.AddTypesConvertedFrom(Args[ArgIdx]->getType(),
+                                           OpLoc,
+                                           true,
+                                           (Op == OO_Exclaim ||
+                                            Op == OO_AmpAmp ||
+                                            Op == OO_PipePipe),
+                                           VisibleTypeConversionsQuals);
+  }
+
+  bool isComparison = false;
+  switch (Op) {
+  case OO_None:
+  case NUM_OVERLOADED_OPERATORS:
+    assert(false && "Expected an overloaded operator");
+    break;
+
+  case OO_Star: // '*' is either unary or binary
+    if (NumArgs == 1)
+      goto UnaryStar;
+    else
+      goto BinaryStar;
+    break;
+
+  case OO_Plus: // '+' is either unary or binary
+    if (NumArgs == 1)
+      goto UnaryPlus;
+    else
+      goto BinaryPlus;
+    break;
+
+  case OO_Minus: // '-' is either unary or binary
+    if (NumArgs == 1)
+      goto UnaryMinus;
+    else
+      goto BinaryMinus;
+    break;
+
+  case OO_Amp: // '&' is either unary or binary
+    if (NumArgs == 1)
+      goto UnaryAmp;
+    else
+      goto BinaryAmp;
+
+  case OO_PlusPlus:
+  case OO_MinusMinus:
+    // C++ [over.built]p3:
+    //
+    //   For every pair (T, VQ), where T is an arithmetic type, and VQ
+    //   is either volatile or empty, there exist candidate operator
+    //   functions of the form
+    //
+    //       VQ T&      operator++(VQ T&);
+    //       T          operator++(VQ T&, int);
+    //
+    // C++ [over.built]p4:
+    //
+    //   For every pair (T, VQ), where T is an arithmetic type other
+    //   than bool, and VQ is either volatile or empty, there exist
+    //   candidate operator functions of the form
+    //
+    //       VQ T&      operator--(VQ T&);
+    //       T          operator--(VQ T&, int);
+    for (unsigned Arith = (Op == OO_PlusPlus? 0 : 1);
+         Arith < NumArithmeticTypes; ++Arith) {
+      QualType ArithTy = ArithmeticTypes[Arith];
+      QualType ParamTypes[2]
+        = { Context.getLValueReferenceType(ArithTy), Context.IntTy };
+
+      // Non-volatile version.
+      if (NumArgs == 1)
+        AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 1, CandidateSet);
+      else
+        AddBuiltinCandidate(ArithTy, ParamTypes, Args, 2, CandidateSet);
+      // heuristic to reduce number of builtin candidates in the set.
+      // Add volatile version only if there are conversions to a volatile type.
+      if (VisibleTypeConversionsQuals.hasVolatile()) {
+        // Volatile version
+        ParamTypes[0]
+          = Context.getLValueReferenceType(Context.getVolatileType(ArithTy));
+        if (NumArgs == 1)
+          AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 1, CandidateSet);
+        else
+          AddBuiltinCandidate(ArithTy, ParamTypes, Args, 2, CandidateSet);
+      }
+    }
+
+    // C++ [over.built]p5:
+    //
+    //   For every pair (T, VQ), where T is a cv-qualified or
+    //   cv-unqualified object type, and VQ is either volatile or
+    //   empty, there exist candidate operator functions of the form
+    //
+    //       T*VQ&      operator++(T*VQ&);
+    //       T*VQ&      operator--(T*VQ&);
+    //       T*         operator++(T*VQ&, int);
+    //       T*         operator--(T*VQ&, int);
+    for (BuiltinCandidateTypeSet::iterator Ptr = CandidateTypes.pointer_begin();
+         Ptr != CandidateTypes.pointer_end(); ++Ptr) {
+      // Skip pointer types that aren't pointers to object types.
+      if (!(*Ptr)->getAs<PointerType>()->getPointeeType()->isObjectType())
+        continue;
+
+      QualType ParamTypes[2] = {
+        Context.getLValueReferenceType(*Ptr), Context.IntTy
+      };
+
+      // Without volatile
+      if (NumArgs == 1)
+        AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 1, CandidateSet);
+      else
+        AddBuiltinCandidate(*Ptr, ParamTypes, Args, 2, CandidateSet);
+
+      if (!Context.getCanonicalType(*Ptr).isVolatileQualified() &&
+          VisibleTypeConversionsQuals.hasVolatile()) {
+        // With volatile
+        ParamTypes[0]
+          = Context.getLValueReferenceType(Context.getVolatileType(*Ptr));
+        if (NumArgs == 1)
+          AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 1, CandidateSet);
+        else
+          AddBuiltinCandidate(*Ptr, ParamTypes, Args, 2, CandidateSet);
+      }
+    }
+    break;
+
+  UnaryStar:
+    // C++ [over.built]p6:
+    //   For every cv-qualified or cv-unqualified object type T, there
+    //   exist candidate operator functions of the form
+    //
+    //       T&         operator*(T*);
+    //
+    // C++ [over.built]p7:
+    //   For every function type T, there exist candidate operator
+    //   functions of the form
+    //       T&         operator*(T*);
+    for (BuiltinCandidateTypeSet::iterator Ptr = CandidateTypes.pointer_begin();
+         Ptr != CandidateTypes.pointer_end(); ++Ptr) {
+      QualType ParamTy = *Ptr;
+      QualType PointeeTy = ParamTy->getAs<PointerType>()->getPointeeType();
+      AddBuiltinCandidate(Context.getLValueReferenceType(PointeeTy),
+                          &ParamTy, Args, 1, CandidateSet);
+    }
+    break;
+
+  UnaryPlus:
+    // C++ [over.built]p8:
+    //   For every type T, there exist candidate operator functions of
+    //   the form
+    //
+    //       T*         operator+(T*);
+    for (BuiltinCandidateTypeSet::iterator Ptr = CandidateTypes.pointer_begin();
+         Ptr != CandidateTypes.pointer_end(); ++Ptr) {
+      QualType ParamTy = *Ptr;
+      AddBuiltinCandidate(ParamTy, &ParamTy, Args, 1, CandidateSet);
+    }
+
+    // Fall through
+
+  UnaryMinus:
+    // C++ [over.built]p9:
+    //  For every promoted arithmetic type T, there exist candidate
+    //  operator functions of the form
+    //
+    //       T         operator+(T);
+    //       T         operator-(T);
+    for (unsigned Arith = FirstPromotedArithmeticType;
+         Arith < LastPromotedArithmeticType; ++Arith) {
+      QualType ArithTy = ArithmeticTypes[Arith];
+      AddBuiltinCandidate(ArithTy, &ArithTy, Args, 1, CandidateSet);
+    }
+    break;
+
+  case OO_Tilde:
+    // C++ [over.built]p10:
+    //   For every promoted integral type T, there exist candidate
+    //   operator functions of the form
+    //
+    //        T         operator~(T);
+    for (unsigned Int = FirstPromotedIntegralType;
+         Int < LastPromotedIntegralType; ++Int) {
+      QualType IntTy = ArithmeticTypes[Int];
+      AddBuiltinCandidate(IntTy, &IntTy, Args, 1, CandidateSet);
+    }
+    break;
+
+  case OO_New:
+  case OO_Delete:
+  case OO_Array_New:
+  case OO_Array_Delete:
+  case OO_Call:
+    assert(false && "Special operators don't use AddBuiltinOperatorCandidates");
+    break;
+
+  case OO_Comma:
+  UnaryAmp:
+  case OO_Arrow:
+    // C++ [over.match.oper]p3:
+    //   -- For the operator ',', the unary operator '&', or the
+    //      operator '->', the built-in candidates set is empty.
+    break;
+
+  case OO_EqualEqual:
+  case OO_ExclaimEqual:
+    // C++ [over.match.oper]p16:
+    //   For every pointer to member type T, there exist candidate operator
+    //   functions of the form
+    //
+    //        bool operator==(T,T);
+    //        bool operator!=(T,T);
+    for (BuiltinCandidateTypeSet::iterator
+           MemPtr = CandidateTypes.member_pointer_begin(),
+           MemPtrEnd = CandidateTypes.member_pointer_end();
+         MemPtr != MemPtrEnd;
+         ++MemPtr) {
+      QualType ParamTypes[2] = { *MemPtr, *MemPtr };
+      AddBuiltinCandidate(Context.BoolTy, ParamTypes, Args, 2, CandidateSet);
+    }
+
+    // Fall through
+
+  case OO_Less:
+  case OO_Greater:
+  case OO_LessEqual:
+  case OO_GreaterEqual:
+    // C++ [over.built]p15:
+    //
+    //   For every pointer or enumeration type T, there exist
+    //   candidate operator functions of the form
+    //
+    //        bool       operator<(T, T);
+    //        bool       operator>(T, T);
+    //        bool       operator<=(T, T);
+    //        bool       operator>=(T, T);
+    //        bool       operator==(T, T);
+    //        bool       operator!=(T, T);
+    for (BuiltinCandidateTypeSet::iterator Ptr = CandidateTypes.pointer_begin();
+         Ptr != CandidateTypes.pointer_end(); ++Ptr) {
+      QualType ParamTypes[2] = { *Ptr, *Ptr };
+      AddBuiltinCandidate(Context.BoolTy, ParamTypes, Args, 2, CandidateSet);
+    }
+    for (BuiltinCandidateTypeSet::iterator Enum
+           = CandidateTypes.enumeration_begin();
+         Enum != CandidateTypes.enumeration_end(); ++Enum) {
+      QualType ParamTypes[2] = { *Enum, *Enum };
+      AddBuiltinCandidate(Context.BoolTy, ParamTypes, Args, 2, CandidateSet);
+    }
+
+    // Fall through.
+    isComparison = true;
+
+  BinaryPlus:
+  BinaryMinus:
+    if (!isComparison) {
+      // We didn't fall through, so we must have OO_Plus or OO_Minus.
+
+      // C++ [over.built]p13:
+      //
+      //   For every cv-qualified or cv-unqualified object type T
+      //   there exist candidate operator functions of the form
+      //
+      //      T*         operator+(T*, ptrdiff_t);
+      //      T&         operator[](T*, ptrdiff_t);    [BELOW]
+      //      T*         operator-(T*, ptrdiff_t);
+      //      T*         operator+(ptrdiff_t, T*);
+      //      T&         operator[](ptrdiff_t, T*);    [BELOW]
+      //
+      // C++ [over.built]p14:
+      //
+      //   For every T, where T is a pointer to object type, there
+      //   exist candidate operator functions of the form
+      //
+      //      ptrdiff_t  operator-(T, T);
+      for (BuiltinCandidateTypeSet::iterator Ptr
+             = CandidateTypes.pointer_begin();
+           Ptr != CandidateTypes.pointer_end(); ++Ptr) {
+        QualType ParamTypes[2] = { *Ptr, Context.getPointerDiffType() };
+
+        // operator+(T*, ptrdiff_t) or operator-(T*, ptrdiff_t)
+        AddBuiltinCandidate(*Ptr, ParamTypes, Args, 2, CandidateSet);
+
+        if (Op == OO_Plus) {
+          // T* operator+(ptrdiff_t, T*);
+          ParamTypes[0] = ParamTypes[1];
+          ParamTypes[1] = *Ptr;
+          AddBuiltinCandidate(*Ptr, ParamTypes, Args, 2, CandidateSet);
+        } else {
+          // ptrdiff_t operator-(T, T);
+          ParamTypes[1] = *Ptr;
+          AddBuiltinCandidate(Context.getPointerDiffType(), ParamTypes,
+                              Args, 2, CandidateSet);
+        }
+      }
+    }
+    // Fall through
+
+  case OO_Slash:
+  BinaryStar:
+  Conditional:
+    // C++ [over.built]p12:
+    //
+    //   For every pair of promoted arithmetic types L and R, there
+    //   exist candidate operator functions of the form
+    //
+    //        LR         operator*(L, R);
+    //        LR         operator/(L, R);
+    //        LR         operator+(L, R);
+    //        LR         operator-(L, R);
+    //        bool       operator<(L, R);
+    //        bool       operator>(L, R);
+    //        bool       operator<=(L, R);
+    //        bool       operator>=(L, R);
+    //        bool       operator==(L, R);
+    //        bool       operator!=(L, R);
+    //
+    //   where LR is the result of the usual arithmetic conversions
+    //   between types L and R.
+    //
+    // C++ [over.built]p24:
+    //
+    //   For every pair of promoted arithmetic types L and R, there exist
+    //   candidate operator functions of the form
+    //
+    //        LR       operator?(bool, L, R);
+    //
+    //   where LR is the result of the usual arithmetic conversions
+    //   between types L and R.
+    // Our candidates ignore the first parameter.
+    for (unsigned Left = FirstPromotedArithmeticType;
+         Left < LastPromotedArithmeticType; ++Left) {
+      for (unsigned Right = FirstPromotedArithmeticType;
+           Right < LastPromotedArithmeticType; ++Right) {
+        QualType LandR[2] = { ArithmeticTypes[Left], ArithmeticTypes[Right] };
+        QualType Result
+          = isComparison
+          ? Context.BoolTy
+          : Context.UsualArithmeticConversionsType(LandR[0], LandR[1]);
+        AddBuiltinCandidate(Result, LandR, Args, 2, CandidateSet);
+      }
+    }
+    break;
+
+  case OO_Percent:
+  BinaryAmp:
+  case OO_Caret:
+  case OO_Pipe:
+  case OO_LessLess:
+  case OO_GreaterGreater:
+    // C++ [over.built]p17:
+    //
+    //   For every pair of promoted integral types L and R, there
+    //   exist candidate operator functions of the form
+    //
+    //      LR         operator%(L, R);
+    //      LR         operator&(L, R);
+    //      LR         operator^(L, R);
+    //      LR         operator|(L, R);
+    //      L          operator<<(L, R);
+    //      L          operator>>(L, R);
+    //
+    //   where LR is the result of the usual arithmetic conversions
+    //   between types L and R.
+    for (unsigned Left = FirstPromotedIntegralType;
+         Left < LastPromotedIntegralType; ++Left) {
+      for (unsigned Right = FirstPromotedIntegralType;
+           Right < LastPromotedIntegralType; ++Right) {
+        QualType LandR[2] = { ArithmeticTypes[Left], ArithmeticTypes[Right] };
+        QualType Result = (Op == OO_LessLess || Op == OO_GreaterGreater)
+            ? LandR[0]
+            : Context.UsualArithmeticConversionsType(LandR[0], LandR[1]);
+        AddBuiltinCandidate(Result, LandR, Args, 2, CandidateSet);
+      }
+    }
+    break;
+
+  case OO_Equal:
+    // C++ [over.built]p20:
+    //
+    //   For every pair (T, VQ), where T is an enumeration or
+    //   pointer to member type and VQ is either volatile or
+    //   empty, there exist candidate operator functions of the form
+    //
+    //        VQ T&      operator=(VQ T&, T);
+    for (BuiltinCandidateTypeSet::iterator
+           Enum = CandidateTypes.enumeration_begin(),
+           EnumEnd = CandidateTypes.enumeration_end();
+         Enum != EnumEnd; ++Enum)
+      AddBuiltinAssignmentOperatorCandidates(*this, *Enum, Args, 2,
+                                             CandidateSet);
+    for (BuiltinCandidateTypeSet::iterator
+           MemPtr = CandidateTypes.member_pointer_begin(),
+         MemPtrEnd = CandidateTypes.member_pointer_end();
+         MemPtr != MemPtrEnd; ++MemPtr)
+      AddBuiltinAssignmentOperatorCandidates(*this, *MemPtr, Args, 2,
+                                             CandidateSet);
+      // Fall through.
+
+  case OO_PlusEqual:
+  case OO_MinusEqual:
+    // C++ [over.built]p19:
+    //
+    //   For every pair (T, VQ), where T is any type and VQ is either
+    //   volatile or empty, there exist candidate operator functions
+    //   of the form
+    //
+    //        T*VQ&      operator=(T*VQ&, T*);
+    //
+    // C++ [over.built]p21:
+    //
+    //   For every pair (T, VQ), where T is a cv-qualified or
+    //   cv-unqualified object type and VQ is either volatile or
+    //   empty, there exist candidate operator functions of the form
+    //
+    //        T*VQ&      operator+=(T*VQ&, ptrdiff_t);
+    //        T*VQ&      operator-=(T*VQ&, ptrdiff_t);
+    for (BuiltinCandidateTypeSet::iterator Ptr = CandidateTypes.pointer_begin();
+         Ptr != CandidateTypes.pointer_end(); ++Ptr) {
+      QualType ParamTypes[2];
+      ParamTypes[1] = (Op == OO_Equal)? *Ptr : Context.getPointerDiffType();
+
+      // non-volatile version
+      ParamTypes[0] = Context.getLValueReferenceType(*Ptr);
+      AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2, CandidateSet,
+                          /*IsAssigmentOperator=*/Op == OO_Equal);
+
+      if (!Context.getCanonicalType(*Ptr).isVolatileQualified() &&
+          VisibleTypeConversionsQuals.hasVolatile()) {
+        // volatile version
+        ParamTypes[0]
+          = Context.getLValueReferenceType(Context.getVolatileType(*Ptr));
+        AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2, CandidateSet,
+                            /*IsAssigmentOperator=*/Op == OO_Equal);
+      }
+    }
+    // Fall through.
+
+  case OO_StarEqual:
+  case OO_SlashEqual:
+    // C++ [over.built]p18:
+    //
+    //   For every triple (L, VQ, R), where L is an arithmetic type,
+    //   VQ is either volatile or empty, and R is a promoted
+    //   arithmetic type, there exist candidate operator functions of
+    //   the form
+    //
+    //        VQ L&      operator=(VQ L&, R);
+    //        VQ L&      operator*=(VQ L&, R);
+    //        VQ L&      operator/=(VQ L&, R);
+    //        VQ L&      operator+=(VQ L&, R);
+    //        VQ L&      operator-=(VQ L&, R);
+    for (unsigned Left = 0; Left < NumArithmeticTypes; ++Left) {
+      for (unsigned Right = FirstPromotedArithmeticType;
+           Right < LastPromotedArithmeticType; ++Right) {
+        QualType ParamTypes[2];
+        ParamTypes[1] = ArithmeticTypes[Right];
+
+        // Add this built-in operator as a candidate (VQ is empty).
+        ParamTypes[0] = Context.getLValueReferenceType(ArithmeticTypes[Left]);
+        AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2, CandidateSet,
+                            /*IsAssigmentOperator=*/Op == OO_Equal);
+
+        // Add this built-in operator as a candidate (VQ is 'volatile').
+        if (VisibleTypeConversionsQuals.hasVolatile()) {
+          ParamTypes[0] = Context.getVolatileType(ArithmeticTypes[Left]);
+          ParamTypes[0] = Context.getLValueReferenceType(ParamTypes[0]);
+          AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2, CandidateSet,
+                              /*IsAssigmentOperator=*/Op == OO_Equal);
+        }
+      }
+    }
+    break;
+
+  case OO_PercentEqual:
+  case OO_LessLessEqual:
+  case OO_GreaterGreaterEqual:
+  case OO_AmpEqual:
+  case OO_CaretEqual:
+  case OO_PipeEqual:
+    // C++ [over.built]p22:
+    //
+    //   For every triple (L, VQ, R), where L is an integral type, VQ
+    //   is either volatile or empty, and R is a promoted integral
+    //   type, there exist candidate operator functions of the form
+    //
+    //        VQ L&       operator%=(VQ L&, R);
+    //        VQ L&       operator<<=(VQ L&, R);
+    //        VQ L&       operator>>=(VQ L&, R);
+    //        VQ L&       operator&=(VQ L&, R);
+    //        VQ L&       operator^=(VQ L&, R);
+    //        VQ L&       operator|=(VQ L&, R);
+    for (unsigned Left = FirstIntegralType; Left < LastIntegralType; ++Left) {
+      for (unsigned Right = FirstPromotedIntegralType;
+           Right < LastPromotedIntegralType; ++Right) {
+        QualType ParamTypes[2];
+        ParamTypes[1] = ArithmeticTypes[Right];
+
+        // Add this built-in operator as a candidate (VQ is empty).
+        ParamTypes[0] = Context.getLValueReferenceType(ArithmeticTypes[Left]);
+        AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2, CandidateSet);
+        if (VisibleTypeConversionsQuals.hasVolatile()) {
+          // Add this built-in operator as a candidate (VQ is 'volatile').
+          ParamTypes[0] = ArithmeticTypes[Left];
+          ParamTypes[0] = Context.getVolatileType(ParamTypes[0]);
+          ParamTypes[0] = Context.getLValueReferenceType(ParamTypes[0]);
+          AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2, CandidateSet);
+        }
+      }
+    }
+    break;
+
+  case OO_Exclaim: {
+    // C++ [over.operator]p23:
+    //
+    //   There also exist candidate operator functions of the form
+    //
+    //        bool        operator!(bool);
+    //        bool        operator&&(bool, bool);     [BELOW]
+    //        bool        operator||(bool, bool);     [BELOW]
+    QualType ParamTy = Context.BoolTy;
+    AddBuiltinCandidate(ParamTy, &ParamTy, Args, 1, CandidateSet,
+                        /*IsAssignmentOperator=*/false,
+                        /*NumContextualBoolArguments=*/1);
+    break;
+  }
+
+  case OO_AmpAmp:
+  case OO_PipePipe: {
+    // C++ [over.operator]p23:
+    //
+    //   There also exist candidate operator functions of the form
+    //
+    //        bool        operator!(bool);            [ABOVE]
+    //        bool        operator&&(bool, bool);
+    //        bool        operator||(bool, bool);
+    QualType ParamTypes[2] = { Context.BoolTy, Context.BoolTy };
+    AddBuiltinCandidate(Context.BoolTy, ParamTypes, Args, 2, CandidateSet,
+                        /*IsAssignmentOperator=*/false,
+                        /*NumContextualBoolArguments=*/2);
+    break;
+  }
+
+  case OO_Subscript:
+    // C++ [over.built]p13:
+    //
+    //   For every cv-qualified or cv-unqualified object type T there
+    //   exist candidate operator functions of the form
+    //
+    //        T*         operator+(T*, ptrdiff_t);     [ABOVE]
+    //        T&         operator[](T*, ptrdiff_t);
+    //        T*         operator-(T*, ptrdiff_t);     [ABOVE]
+    //        T*         operator+(ptrdiff_t, T*);     [ABOVE]
+    //        T&         operator[](ptrdiff_t, T*);
+    for (BuiltinCandidateTypeSet::iterator Ptr = CandidateTypes.pointer_begin();
+         Ptr != CandidateTypes.pointer_end(); ++Ptr) {
+      QualType ParamTypes[2] = { *Ptr, Context.getPointerDiffType() };
+      QualType PointeeType = (*Ptr)->getAs<PointerType>()->getPointeeType();
+      QualType ResultTy = Context.getLValueReferenceType(PointeeType);
+
+      // T& operator[](T*, ptrdiff_t)
+      AddBuiltinCandidate(ResultTy, ParamTypes, Args, 2, CandidateSet);
+
+      // T& operator[](ptrdiff_t, T*);
+      ParamTypes[0] = ParamTypes[1];
+      ParamTypes[1] = *Ptr;
+      AddBuiltinCandidate(ResultTy, ParamTypes, Args, 2, CandidateSet);
+    }
+    break;
+
+  case OO_ArrowStar:
+    // C++ [over.built]p11:
+    //    For every quintuple (C1, C2, T, CV1, CV2), where C2 is a class type, 
+    //    C1 is the same type as C2 or is a derived class of C2, T is an object 
+    //    type or a function type, and CV1 and CV2 are cv-qualifier-seqs, 
+    //    there exist candidate operator functions of the form 
+    //    CV12 T& operator->*(CV1 C1*, CV2 T C2::*); 
+    //    where CV12 is the union of CV1 and CV2.
+    {
+      for (BuiltinCandidateTypeSet::iterator Ptr = 
+             CandidateTypes.pointer_begin();
+           Ptr != CandidateTypes.pointer_end(); ++Ptr) {
+        QualType C1Ty = (*Ptr);
+        QualType C1;
+        QualifierCollector Q1;
+        if (const PointerType *PointerTy = C1Ty->getAs<PointerType>()) {
+          C1 = QualType(Q1.strip(PointerTy->getPointeeType()), 0);
+          if (!isa<RecordType>(C1))
+            continue;
+          // heuristic to reduce number of builtin candidates in the set.
+          // Add volatile/restrict version only if there are conversions to a
+          // volatile/restrict type.
+          if (!VisibleTypeConversionsQuals.hasVolatile() && Q1.hasVolatile())
+            continue;
+          if (!VisibleTypeConversionsQuals.hasRestrict() && Q1.hasRestrict())
+            continue;
+        }
+        for (BuiltinCandidateTypeSet::iterator
+             MemPtr = CandidateTypes.member_pointer_begin(),
+             MemPtrEnd = CandidateTypes.member_pointer_end();
+             MemPtr != MemPtrEnd; ++MemPtr) {
+          const MemberPointerType *mptr = cast<MemberPointerType>(*MemPtr);
+          QualType C2 = QualType(mptr->getClass(), 0);
+          C2 = C2.getUnqualifiedType();
+          if (C1 != C2 && !IsDerivedFrom(C1, C2))
+            break;
+          QualType ParamTypes[2] = { *Ptr, *MemPtr };
+          // build CV12 T&
+          QualType T = mptr->getPointeeType();
+          if (!VisibleTypeConversionsQuals.hasVolatile() && 
+              T.isVolatileQualified())
+            continue;
+          if (!VisibleTypeConversionsQuals.hasRestrict() && 
+              T.isRestrictQualified())
+            continue;
+          T = Q1.apply(T);
+          QualType ResultTy = Context.getLValueReferenceType(T);
+          AddBuiltinCandidate(ResultTy, ParamTypes, Args, 2, CandidateSet);
+        }
+      }
+    }
+    break;
+
+  case OO_Conditional:
+    // Note that we don't consider the first argument, since it has been
+    // contextually converted to bool long ago. The candidates below are
+    // therefore added as binary.
+    //
+    // C++ [over.built]p24:
+    //   For every type T, where T is a pointer or pointer-to-member type,
+    //   there exist candidate operator functions of the form
+    //
+    //        T        operator?(bool, T, T);
+    //
+    for (BuiltinCandidateTypeSet::iterator Ptr = CandidateTypes.pointer_begin(),
+         E = CandidateTypes.pointer_end(); Ptr != E; ++Ptr) {
+      QualType ParamTypes[2] = { *Ptr, *Ptr };
+      AddBuiltinCandidate(*Ptr, ParamTypes, Args, 2, CandidateSet);
+    }
+    for (BuiltinCandidateTypeSet::iterator Ptr =
+           CandidateTypes.member_pointer_begin(),
+         E = CandidateTypes.member_pointer_end(); Ptr != E; ++Ptr) {
+      QualType ParamTypes[2] = { *Ptr, *Ptr };
+      AddBuiltinCandidate(*Ptr, ParamTypes, Args, 2, CandidateSet);
+    }
+    goto Conditional;
+  }
+}
+
+/// \brief Add function candidates found via argument-dependent lookup
+/// to the set of overloading candidates.
+///
+/// This routine performs argument-dependent name lookup based on the
+/// given function name (which may also be an operator name) and adds
+/// all of the overload candidates found by ADL to the overload
+/// candidate set (C++ [basic.lookup.argdep]).
+void
+Sema::AddArgumentDependentLookupCandidates(DeclarationName Name,
+                                           bool Operator,
+                                           Expr **Args, unsigned NumArgs,
+                       const TemplateArgumentListInfo *ExplicitTemplateArgs,
+                                           OverloadCandidateSet& CandidateSet,
+                                           bool PartialOverloading) {
+  ADLResult Fns;
+
+  // FIXME: This approach for uniquing ADL results (and removing
+  // redundant candidates from the set) relies on pointer-equality,
+  // which means we need to key off the canonical decl.  However,
+  // always going back to the canonical decl might not get us the
+  // right set of default arguments.  What default arguments are
+  // we supposed to consider on ADL candidates, anyway?
+
+  // FIXME: Pass in the explicit template arguments?
+  ArgumentDependentLookup(Name, Operator, Args, NumArgs, Fns);
+
+  // Erase all of the candidates we already knew about.
+  for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
+                                   CandEnd = CandidateSet.end();
+       Cand != CandEnd; ++Cand)
+    if (Cand->Function) {
+      Fns.erase(Cand->Function);
+      if (FunctionTemplateDecl *FunTmpl = Cand->Function->getPrimaryTemplate())
+        Fns.erase(FunTmpl);
+    }
+
+  // For each of the ADL candidates we found, add it to the overload
+  // set.
+  for (ADLResult::iterator I = Fns.begin(), E = Fns.end(); I != E; ++I) {
+    DeclAccessPair FoundDecl = DeclAccessPair::make(*I, AS_none);
+    if (FunctionDecl *FD = dyn_cast<FunctionDecl>(*I)) {
+      if (ExplicitTemplateArgs)
+        continue;
+      
+      AddOverloadCandidate(FD, FoundDecl, Args, NumArgs, CandidateSet,
+                           false, PartialOverloading);
+    } else
+      AddTemplateOverloadCandidate(cast<FunctionTemplateDecl>(*I),
+                                   FoundDecl, ExplicitTemplateArgs,
+                                   Args, NumArgs, CandidateSet);
+  }
+}
+
+/// isBetterOverloadCandidate - Determines whether the first overload
+/// candidate is a better candidate than the second (C++ 13.3.3p1).
+bool
+Sema::isBetterOverloadCandidate(const OverloadCandidate& Cand1,
+                                const OverloadCandidate& Cand2,
+                                SourceLocation Loc) {
+  // Define viable functions to be better candidates than non-viable
+  // functions.
+  if (!Cand2.Viable)
+    return Cand1.Viable;
+  else if (!Cand1.Viable)
+    return false;
+
+  // C++ [over.match.best]p1:
+  //
+  //   -- if F is a static member function, ICS1(F) is defined such
+  //      that ICS1(F) is neither better nor worse than ICS1(G) for
+  //      any function G, and, symmetrically, ICS1(G) is neither
+  //      better nor worse than ICS1(F).
+  unsigned StartArg = 0;
+  if (Cand1.IgnoreObjectArgument || Cand2.IgnoreObjectArgument)
+    StartArg = 1;
+
+  // C++ [over.match.best]p1:
+  //   A viable function F1 is defined to be a better function than another
+  //   viable function F2 if for all arguments i, ICSi(F1) is not a worse
+  //   conversion sequence than ICSi(F2), and then...
+  unsigned NumArgs = Cand1.Conversions.size();
+  assert(Cand2.Conversions.size() == NumArgs && "Overload candidate mismatch");
+  bool HasBetterConversion = false;
+  for (unsigned ArgIdx = StartArg; ArgIdx < NumArgs; ++ArgIdx) {
+    switch (CompareImplicitConversionSequences(Cand1.Conversions[ArgIdx],
+                                               Cand2.Conversions[ArgIdx])) {
+    case ImplicitConversionSequence::Better:
+      // Cand1 has a better conversion sequence.
+      HasBetterConversion = true;
+      break;
+
+    case ImplicitConversionSequence::Worse:
+      // Cand1 can't be better than Cand2.
+      return false;
+
+    case ImplicitConversionSequence::Indistinguishable:
+      // Do nothing.
+      break;
+    }
+  }
+
+  //    -- for some argument j, ICSj(F1) is a better conversion sequence than
+  //       ICSj(F2), or, if not that,
+  if (HasBetterConversion)
+    return true;
+
+  //     - F1 is a non-template function and F2 is a function template
+  //       specialization, or, if not that,
+  if (Cand1.Function && !Cand1.Function->getPrimaryTemplate() &&
+      Cand2.Function && Cand2.Function->getPrimaryTemplate())
+    return true;
+
+  //   -- F1 and F2 are function template specializations, and the function
+  //      template for F1 is more specialized than the template for F2
+  //      according to the partial ordering rules described in 14.5.5.2, or,
+  //      if not that,
+  if (Cand1.Function && Cand1.Function->getPrimaryTemplate() &&
+      Cand2.Function && Cand2.Function->getPrimaryTemplate())
+    if (FunctionTemplateDecl *BetterTemplate
+          = getMoreSpecializedTemplate(Cand1.Function->getPrimaryTemplate(),
+                                       Cand2.Function->getPrimaryTemplate(),
+                                       Loc,
+                       isa<CXXConversionDecl>(Cand1.Function)? TPOC_Conversion 
+                                                             : TPOC_Call))
+      return BetterTemplate == Cand1.Function->getPrimaryTemplate();
+
+  //   -- the context is an initialization by user-defined conversion
+  //      (see 8.5, 13.3.1.5) and the standard conversion sequence
+  //      from the return type of F1 to the destination type (i.e.,
+  //      the type of the entity being initialized) is a better
+  //      conversion sequence than the standard conversion sequence
+  //      from the return type of F2 to the destination type.
+  if (Cand1.Function && Cand2.Function &&
+      isa<CXXConversionDecl>(Cand1.Function) &&
+      isa<CXXConversionDecl>(Cand2.Function)) {
+    switch (CompareStandardConversionSequences(Cand1.FinalConversion,
+                                               Cand2.FinalConversion)) {
+    case ImplicitConversionSequence::Better:
+      // Cand1 has a better conversion sequence.
+      return true;
+
+    case ImplicitConversionSequence::Worse:
+      // Cand1 can't be better than Cand2.
+      return false;
+
+    case ImplicitConversionSequence::Indistinguishable:
+      // Do nothing
+      break;
+    }
+  }
+
+  return false;
+}
+
+/// \brief Computes the best viable function (C++ 13.3.3)
+/// within an overload candidate set.
+///
+/// \param CandidateSet the set of candidate functions.
+///
+/// \param Loc the location of the function name (or operator symbol) for
+/// which overload resolution occurs.
+///
+/// \param Best f overload resolution was successful or found a deleted
+/// function, Best points to the candidate function found.
+///
+/// \returns The result of overload resolution.
+OverloadingResult Sema::BestViableFunction(OverloadCandidateSet& CandidateSet,
+                                           SourceLocation Loc,
+                                        OverloadCandidateSet::iterator& Best) {
+  // Find the best viable function.
+  Best = CandidateSet.end();
+  for (OverloadCandidateSet::iterator Cand = CandidateSet.begin();
+       Cand != CandidateSet.end(); ++Cand) {
+    if (Cand->Viable) {
+      if (Best == CandidateSet.end() ||
+          isBetterOverloadCandidate(*Cand, *Best, Loc))
+        Best = Cand;
+    }
+  }
+
+  // If we didn't find any viable functions, abort.
+  if (Best == CandidateSet.end())
+    return OR_No_Viable_Function;
+
+  // Make sure that this function is better than every other viable
+  // function. If not, we have an ambiguity.
+  for (OverloadCandidateSet::iterator Cand = CandidateSet.begin();
+       Cand != CandidateSet.end(); ++Cand) {
+    if (Cand->Viable &&
+        Cand != Best &&
+        !isBetterOverloadCandidate(*Best, *Cand, Loc)) {
+      Best = CandidateSet.end();
+      return OR_Ambiguous;
+    }
+  }
+
+  // Best is the best viable function.
+  if (Best->Function &&
+      (Best->Function->isDeleted() ||
+       Best->Function->getAttr<UnavailableAttr>()))
+    return OR_Deleted;
+
+  // C++ [basic.def.odr]p2:
+  //   An overloaded function is used if it is selected by overload resolution
+  //   when referred to from a potentially-evaluated expression. [Note: this
+  //   covers calls to named functions (5.2.2), operator overloading
+  //   (clause 13), user-defined conversions (12.3.2), allocation function for
+  //   placement new (5.3.4), as well as non-default initialization (8.5).
+  if (Best->Function)
+    MarkDeclarationReferenced(Loc, Best->Function);
+  return OR_Success;
+}
+
+namespace {
+
+enum OverloadCandidateKind {
+  oc_function,
+  oc_method,
+  oc_constructor,
+  oc_function_template,
+  oc_method_template,
+  oc_constructor_template,
+  oc_implicit_default_constructor,
+  oc_implicit_copy_constructor,
+  oc_implicit_copy_assignment
+};
+
+OverloadCandidateKind ClassifyOverloadCandidate(Sema &S,
+                                                FunctionDecl *Fn,
+                                                std::string &Description) {
+  bool isTemplate = false;
+
+  if (FunctionTemplateDecl *FunTmpl = Fn->getPrimaryTemplate()) {
+    isTemplate = true;
+    Description = S.getTemplateArgumentBindingsText(
+      FunTmpl->getTemplateParameters(), *Fn->getTemplateSpecializationArgs());
+  }
+
+  if (CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(Fn)) {
+    if (!Ctor->isImplicit())
+      return isTemplate ? oc_constructor_template : oc_constructor;
+
+    return Ctor->isCopyConstructor() ? oc_implicit_copy_constructor
+                                     : oc_implicit_default_constructor;
+  }
+
+  if (CXXMethodDecl *Meth = dyn_cast<CXXMethodDecl>(Fn)) {
+    // This actually gets spelled 'candidate function' for now, but
+    // it doesn't hurt to split it out.
+    if (!Meth->isImplicit())
+      return isTemplate ? oc_method_template : oc_method;
+
+    assert(Meth->isCopyAssignment()
+           && "implicit method is not copy assignment operator?");
+    return oc_implicit_copy_assignment;
+  }
+
+  return isTemplate ? oc_function_template : oc_function;
+}
+
+} // end anonymous namespace
+
+// Notes the location of an overload candidate.
+void Sema::NoteOverloadCandidate(FunctionDecl *Fn) {
+  std::string FnDesc;
+  OverloadCandidateKind K = ClassifyOverloadCandidate(*this, Fn, FnDesc);
+  Diag(Fn->getLocation(), diag::note_ovl_candidate)
+    << (unsigned) K << FnDesc;
+}
+
+/// Diagnoses an ambiguous conversion.  The partial diagnostic is the
+/// "lead" diagnostic; it will be given two arguments, the source and
+/// target types of the conversion.
+void Sema::DiagnoseAmbiguousConversion(const ImplicitConversionSequence &ICS,
+                                       SourceLocation CaretLoc,
+                                       const PartialDiagnostic &PDiag) {
+  Diag(CaretLoc, PDiag)
+    << ICS.Ambiguous.getFromType() << ICS.Ambiguous.getToType();
+  for (AmbiguousConversionSequence::const_iterator
+         I = ICS.Ambiguous.begin(), E = ICS.Ambiguous.end(); I != E; ++I) {
+    NoteOverloadCandidate(*I);
+  }
+}
+
+namespace {
+
+void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand, unsigned I) {
+  const ImplicitConversionSequence &Conv = Cand->Conversions[I];
+  assert(Conv.isBad());
+  assert(Cand->Function && "for now, candidate must be a function");
+  FunctionDecl *Fn = Cand->Function;
+
+  // There's a conversion slot for the object argument if this is a
+  // non-constructor method.  Note that 'I' corresponds the
+  // conversion-slot index.
+  bool isObjectArgument = false;
+  if (isa<CXXMethodDecl>(Fn) && !isa<CXXConstructorDecl>(Fn)) {
+    if (I == 0)
+      isObjectArgument = true;
+    else
+      I--;
+  }
+
+  std::string FnDesc;
+  OverloadCandidateKind FnKind = ClassifyOverloadCandidate(S, Fn, FnDesc);
+
+  Expr *FromExpr = Conv.Bad.FromExpr;
+  QualType FromTy = Conv.Bad.getFromType();
+  QualType ToTy = Conv.Bad.getToType();
+
+  if (FromTy == S.Context.OverloadTy) {
+    assert(FromExpr && "overload set argument came from implicit argument?");
+    Expr *E = FromExpr->IgnoreParens();
+    if (isa<UnaryOperator>(E))
+      E = cast<UnaryOperator>(E)->getSubExpr()->IgnoreParens();
+    DeclarationName Name = cast<OverloadExpr>(E)->getName();
+
+    S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_overload)
+      << (unsigned) FnKind << FnDesc
+      << (FromExpr ? FromExpr->getSourceRange() : SourceRange())
+      << ToTy << Name << I+1;
+    return;
+  }
+
+  // Do some hand-waving analysis to see if the non-viability is due
+  // to a qualifier mismatch.
+  CanQualType CFromTy = S.Context.getCanonicalType(FromTy);
+  CanQualType CToTy = S.Context.getCanonicalType(ToTy);
+  if (CanQual<ReferenceType> RT = CToTy->getAs<ReferenceType>())
+    CToTy = RT->getPointeeType();
+  else {
+    // TODO: detect and diagnose the full richness of const mismatches.
+    if (CanQual<PointerType> FromPT = CFromTy->getAs<PointerType>())
+      if (CanQual<PointerType> ToPT = CToTy->getAs<PointerType>())
+        CFromTy = FromPT->getPointeeType(), CToTy = ToPT->getPointeeType();
+  }
+
+  if (CToTy.getUnqualifiedType() == CFromTy.getUnqualifiedType() &&
+      !CToTy.isAtLeastAsQualifiedAs(CFromTy)) {
+    // It is dumb that we have to do this here.
+    while (isa<ArrayType>(CFromTy))
+      CFromTy = CFromTy->getAs<ArrayType>()->getElementType();
+    while (isa<ArrayType>(CToTy))
+      CToTy = CFromTy->getAs<ArrayType>()->getElementType();
+
+    Qualifiers FromQs = CFromTy.getQualifiers();
+    Qualifiers ToQs = CToTy.getQualifiers();
+
+    if (FromQs.getAddressSpace() != ToQs.getAddressSpace()) {
+      S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_addrspace)
+        << (unsigned) FnKind << FnDesc
+        << (FromExpr ? FromExpr->getSourceRange() : SourceRange())
+        << FromTy
+        << FromQs.getAddressSpace() << ToQs.getAddressSpace()
+        << (unsigned) isObjectArgument << I+1;
+      return;
+    }
+
+    unsigned CVR = FromQs.getCVRQualifiers() & ~ToQs.getCVRQualifiers();
+    assert(CVR && "unexpected qualifiers mismatch");
+
+    if (isObjectArgument) {
+      S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_cvr_this)
+        << (unsigned) FnKind << FnDesc
+        << (FromExpr ? FromExpr->getSourceRange() : SourceRange())
+        << FromTy << (CVR - 1);
+    } else {
+      S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_cvr)
+        << (unsigned) FnKind << FnDesc
+        << (FromExpr ? FromExpr->getSourceRange() : SourceRange())
+        << FromTy << (CVR - 1) << I+1;
+    }
+    return;
+  }
+
+  // Diagnose references or pointers to incomplete types differently,
+  // since it's far from impossible that the incompleteness triggered
+  // the failure.
+  QualType TempFromTy = FromTy.getNonReferenceType();
+  if (const PointerType *PTy = TempFromTy->getAs<PointerType>())
+    TempFromTy = PTy->getPointeeType();
+  if (TempFromTy->isIncompleteType()) {
+    S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_conv_incomplete)
+      << (unsigned) FnKind << FnDesc
+      << (FromExpr ? FromExpr->getSourceRange() : SourceRange())
+      << FromTy << ToTy << (unsigned) isObjectArgument << I+1;
+    return;
+  }
+
+  // TODO: specialize more based on the kind of mismatch
+  S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_conv)
+    << (unsigned) FnKind << FnDesc
+    << (FromExpr ? FromExpr->getSourceRange() : SourceRange())
+    << FromTy << ToTy << (unsigned) isObjectArgument << I+1;
+}
+
+void DiagnoseArityMismatch(Sema &S, OverloadCandidate *Cand,
+                           unsigned NumFormalArgs) {
+  // TODO: treat calls to a missing default constructor as a special case
+
+  FunctionDecl *Fn = Cand->Function;
+  const FunctionProtoType *FnTy = Fn->getType()->getAs<FunctionProtoType>();
+
+  unsigned MinParams = Fn->getMinRequiredArguments();
+  
+  // at least / at most / exactly
+  unsigned mode, modeCount;
+  if (NumFormalArgs < MinParams) {
+    assert(Cand->FailureKind == ovl_fail_too_few_arguments);
+    if (MinParams != FnTy->getNumArgs() || FnTy->isVariadic())
+      mode = 0; // "at least"
+    else
+      mode = 2; // "exactly"
+    modeCount = MinParams;
+  } else {
+    assert(Cand->FailureKind == ovl_fail_too_many_arguments);
+    if (MinParams != FnTy->getNumArgs())
+      mode = 1; // "at most"
+    else
+      mode = 2; // "exactly"
+    modeCount = FnTy->getNumArgs();
+  }
+
+  std::string Description;
+  OverloadCandidateKind FnKind = ClassifyOverloadCandidate(S, Fn, Description);
+
+  S.Diag(Fn->getLocation(), diag::note_ovl_candidate_arity)
+    << (unsigned) FnKind << Description << mode << modeCount << NumFormalArgs;
+}
+
+/// Diagnose a failed template-argument deduction.
+void DiagnoseBadDeduction(Sema &S, OverloadCandidate *Cand,
+                          Expr **Args, unsigned NumArgs) {
+  FunctionDecl *Fn = Cand->Function; // pattern
+
+  TemplateParameter Param = TemplateParameter::getFromOpaqueValue(
+                                   Cand->DeductionFailure.TemplateParameter);
+
+  switch (Cand->DeductionFailure.Result) {
+  case Sema::TDK_Success:
+    llvm_unreachable("TDK_success while diagnosing bad deduction");
+
+  case Sema::TDK_Incomplete: {
+    NamedDecl *ParamD;
+    (ParamD = Param.dyn_cast<TemplateTypeParmDecl*>()) ||
+    (ParamD = Param.dyn_cast<NonTypeTemplateParmDecl*>()) ||
+    (ParamD = Param.dyn_cast<TemplateTemplateParmDecl*>());
+    assert(ParamD && "no parameter found for incomplete deduction result");
+    S.Diag(Fn->getLocation(), diag::note_ovl_candidate_incomplete_deduction)
+      << ParamD->getDeclName();
+    return;
+  }
+
+  // TODO: diagnose these individually, then kill off
+  // note_ovl_candidate_bad_deduction, which is uselessly vague.
+  case Sema::TDK_InstantiationDepth:
+  case Sema::TDK_Inconsistent:
+  case Sema::TDK_InconsistentQuals:
+  case Sema::TDK_SubstitutionFailure:
+  case Sema::TDK_NonDeducedMismatch:
+  case Sema::TDK_TooManyArguments:
+  case Sema::TDK_TooFewArguments:
+  case Sema::TDK_InvalidExplicitArguments:
+  case Sema::TDK_FailedOverloadResolution:
+    S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_deduction);
+    return;
+  }
+}
+
+/// Generates a 'note' diagnostic for an overload candidate.  We've
+/// already generated a primary error at the call site.
+///
+/// It really does need to be a single diagnostic with its caret
+/// pointed at the candidate declaration.  Yes, this creates some
+/// major challenges of technical writing.  Yes, this makes pointing
+/// out problems with specific arguments quite awkward.  It's still
+/// better than generating twenty screens of text for every failed
+/// overload.
+///
+/// It would be great to be able to express per-candidate problems
+/// more richly for those diagnostic clients that cared, but we'd
+/// still have to be just as careful with the default diagnostics.
+void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand,
+                           Expr **Args, unsigned NumArgs) {
+  FunctionDecl *Fn = Cand->Function;
+
+  // Note deleted candidates, but only if they're viable.
+  if (Cand->Viable && (Fn->isDeleted() || Fn->hasAttr<UnavailableAttr>())) {
+    std::string FnDesc;
+    OverloadCandidateKind FnKind = ClassifyOverloadCandidate(S, Fn, FnDesc);
+
+    S.Diag(Fn->getLocation(), diag::note_ovl_candidate_deleted)
+      << FnKind << FnDesc << Fn->isDeleted();
+    return;
+  }
+
+  // We don't really have anything else to say about viable candidates.
+  if (Cand->Viable) {
+    S.NoteOverloadCandidate(Fn);
+    return;
+  }
+
+  switch (Cand->FailureKind) {
+  case ovl_fail_too_many_arguments:
+  case ovl_fail_too_few_arguments:
+    return DiagnoseArityMismatch(S, Cand, NumArgs);
+
+  case ovl_fail_bad_deduction:
+    return DiagnoseBadDeduction(S, Cand, Args, NumArgs);
+
+  case ovl_fail_trivial_conversion:
+  case ovl_fail_bad_final_conversion:
+  case ovl_fail_final_conversion_not_exact:
+    return S.NoteOverloadCandidate(Fn);
+
+  case ovl_fail_bad_conversion: {
+    unsigned I = (Cand->IgnoreObjectArgument ? 1 : 0);
+    for (unsigned N = Cand->Conversions.size(); I != N; ++I)
+      if (Cand->Conversions[I].isBad())
+        return DiagnoseBadConversion(S, Cand, I);
+    
+    // FIXME: this currently happens when we're called from SemaInit
+    // when user-conversion overload fails.  Figure out how to handle
+    // those conditions and diagnose them well.
+    return S.NoteOverloadCandidate(Fn);
+  }
+  }
+}
+
+void NoteSurrogateCandidate(Sema &S, OverloadCandidate *Cand) {
+  // Desugar the type of the surrogate down to a function type,
+  // retaining as many typedefs as possible while still showing
+  // the function type (and, therefore, its parameter types).
+  QualType FnType = Cand->Surrogate->getConversionType();
+  bool isLValueReference = false;
+  bool isRValueReference = false;
+  bool isPointer = false;
+  if (const LValueReferenceType *FnTypeRef =
+        FnType->getAs<LValueReferenceType>()) {
+    FnType = FnTypeRef->getPointeeType();
+    isLValueReference = true;
+  } else if (const RValueReferenceType *FnTypeRef =
+               FnType->getAs<RValueReferenceType>()) {
+    FnType = FnTypeRef->getPointeeType();
+    isRValueReference = true;
+  }
+  if (const PointerType *FnTypePtr = FnType->getAs<PointerType>()) {
+    FnType = FnTypePtr->getPointeeType();
+    isPointer = true;
+  }
+  // Desugar down to a function type.
+  FnType = QualType(FnType->getAs<FunctionType>(), 0);
+  // Reconstruct the pointer/reference as appropriate.
+  if (isPointer) FnType = S.Context.getPointerType(FnType);
+  if (isRValueReference) FnType = S.Context.getRValueReferenceType(FnType);
+  if (isLValueReference) FnType = S.Context.getLValueReferenceType(FnType);
+
+  S.Diag(Cand->Surrogate->getLocation(), diag::note_ovl_surrogate_cand)
+    << FnType;
+}
+
+void NoteBuiltinOperatorCandidate(Sema &S,
+                                  const char *Opc,
+                                  SourceLocation OpLoc,
+                                  OverloadCandidate *Cand) {
+  assert(Cand->Conversions.size() <= 2 && "builtin operator is not binary");
+  std::string TypeStr("operator");
+  TypeStr += Opc;
+  TypeStr += "(";
+  TypeStr += Cand->BuiltinTypes.ParamTypes[0].getAsString();
+  if (Cand->Conversions.size() == 1) {
+    TypeStr += ")";
+    S.Diag(OpLoc, diag::note_ovl_builtin_unary_candidate) << TypeStr;
+  } else {
+    TypeStr += ", ";
+    TypeStr += Cand->BuiltinTypes.ParamTypes[1].getAsString();
+    TypeStr += ")";
+    S.Diag(OpLoc, diag::note_ovl_builtin_binary_candidate) << TypeStr;
+  }
+}
+
+void NoteAmbiguousUserConversions(Sema &S, SourceLocation OpLoc,
+                                  OverloadCandidate *Cand) {
+  unsigned NoOperands = Cand->Conversions.size();
+  for (unsigned ArgIdx = 0; ArgIdx < NoOperands; ++ArgIdx) {
+    const ImplicitConversionSequence &ICS = Cand->Conversions[ArgIdx];
+    if (ICS.isBad()) break; // all meaningless after first invalid
+    if (!ICS.isAmbiguous()) continue;
+
+    S.DiagnoseAmbiguousConversion(ICS, OpLoc,
+                              S.PDiag(diag::note_ambiguous_type_conversion));
+  }
+}
+
+SourceLocation GetLocationForCandidate(const OverloadCandidate *Cand) {
+  if (Cand->Function)
+    return Cand->Function->getLocation();
+  if (Cand->IsSurrogate)
+    return Cand->Surrogate->getLocation();
+  return SourceLocation();
+}
+
+struct CompareOverloadCandidatesForDisplay {
+  Sema &S;
+  CompareOverloadCandidatesForDisplay(Sema &S) : S(S) {}
+
+  bool operator()(const OverloadCandidate *L,
+                  const OverloadCandidate *R) {
+    // Fast-path this check.
+    if (L == R) return false;
+
+    // Order first by viability.
+    if (L->Viable) {
+      if (!R->Viable) return true;
+
+      // TODO: introduce a tri-valued comparison for overload
+      // candidates.  Would be more worthwhile if we had a sort
+      // that could exploit it.
+      if (S.isBetterOverloadCandidate(*L, *R, SourceLocation())) return true;
+      if (S.isBetterOverloadCandidate(*R, *L, SourceLocation())) return false;
+    } else if (R->Viable)
+      return false;
+
+    assert(L->Viable == R->Viable);
+
+    // Criteria by which we can sort non-viable candidates:
+    if (!L->Viable) {
+      // 1. Arity mismatches come after other candidates.
+      if (L->FailureKind == ovl_fail_too_many_arguments ||
+          L->FailureKind == ovl_fail_too_few_arguments)
+        return false;
+      if (R->FailureKind == ovl_fail_too_many_arguments ||
+          R->FailureKind == ovl_fail_too_few_arguments)
+        return true;
+
+      // 2. Bad conversions come first and are ordered by the number
+      // of bad conversions and quality of good conversions.
+      if (L->FailureKind == ovl_fail_bad_conversion) {
+        if (R->FailureKind != ovl_fail_bad_conversion)
+          return true;
+
+        // If there's any ordering between the defined conversions...
+        // FIXME: this might not be transitive.
+        assert(L->Conversions.size() == R->Conversions.size());
+
+        int leftBetter = 0;
+        unsigned I = (L->IgnoreObjectArgument || R->IgnoreObjectArgument);
+        for (unsigned E = L->Conversions.size(); I != E; ++I) {
+          switch (S.CompareImplicitConversionSequences(L->Conversions[I],
+                                                       R->Conversions[I])) {
+          case ImplicitConversionSequence::Better:
+            leftBetter++;
+            break;
+
+          case ImplicitConversionSequence::Worse:
+            leftBetter--;
+            break;
+
+          case ImplicitConversionSequence::Indistinguishable:
+            break;
+          }
+        }
+        if (leftBetter > 0) return true;
+        if (leftBetter < 0) return false;
+
+      } else if (R->FailureKind == ovl_fail_bad_conversion)
+        return false;
+
+      // TODO: others?
+    }
+
+    // Sort everything else by location.
+    SourceLocation LLoc = GetLocationForCandidate(L);
+    SourceLocation RLoc = GetLocationForCandidate(R);
+
+    // Put candidates without locations (e.g. builtins) at the end.
+    if (LLoc.isInvalid()) return false;
+    if (RLoc.isInvalid()) return true;
+
+    return S.SourceMgr.isBeforeInTranslationUnit(LLoc, RLoc);
+  }
+};
+
+/// CompleteNonViableCandidate - Normally, overload resolution only
+/// computes up to the first
+void CompleteNonViableCandidate(Sema &S, OverloadCandidate *Cand,
+                                Expr **Args, unsigned NumArgs) {
+  assert(!Cand->Viable);
+
+  // Don't do anything on failures other than bad conversion.
+  if (Cand->FailureKind != ovl_fail_bad_conversion) return;
+
+  // Skip forward to the first bad conversion.
+  unsigned ConvIdx = (Cand->IgnoreObjectArgument ? 1 : 0);
+  unsigned ConvCount = Cand->Conversions.size();
+  while (true) {
+    assert(ConvIdx != ConvCount && "no bad conversion in candidate");
+    ConvIdx++;
+    if (Cand->Conversions[ConvIdx - 1].isBad())
+      break;
+  }
+
+  if (ConvIdx == ConvCount)
+    return;
+
+  assert(!Cand->Conversions[ConvIdx].isInitialized() &&
+         "remaining conversion is initialized?");
+
+  // FIXME: this should probably be preserved from the overload
+  // operation somehow.
+  bool SuppressUserConversions = false;
+
+  const FunctionProtoType* Proto;
+  unsigned ArgIdx = ConvIdx;
+
+  if (Cand->IsSurrogate) {
+    QualType ConvType
+      = Cand->Surrogate->getConversionType().getNonReferenceType();
+    if (const PointerType *ConvPtrType = ConvType->getAs<PointerType>())
+      ConvType = ConvPtrType->getPointeeType();
+    Proto = ConvType->getAs<FunctionProtoType>();
+    ArgIdx--;
+  } else if (Cand->Function) {
+    Proto = Cand->Function->getType()->getAs<FunctionProtoType>();
+    if (isa<CXXMethodDecl>(Cand->Function) &&
+        !isa<CXXConstructorDecl>(Cand->Function))
+      ArgIdx--;
+  } else {
+    // Builtin binary operator with a bad first conversion.
+    assert(ConvCount <= 3);
+    for (; ConvIdx != ConvCount; ++ConvIdx)
+      Cand->Conversions[ConvIdx]
+        = TryCopyInitialization(S, Args[ConvIdx],
+                                Cand->BuiltinTypes.ParamTypes[ConvIdx],
+                                SuppressUserConversions, 
+                                /*InOverloadResolution*/ true);
+    return;
+  }
+
+  // Fill in the rest of the conversions.
+  unsigned NumArgsInProto = Proto->getNumArgs();
+  for (; ConvIdx != ConvCount; ++ConvIdx, ++ArgIdx) {
+    if (ArgIdx < NumArgsInProto)
+      Cand->Conversions[ConvIdx]
+        = TryCopyInitialization(S, Args[ArgIdx], Proto->getArgType(ArgIdx),
+                                SuppressUserConversions, 
+                                /*InOverloadResolution=*/true);
+    else
+      Cand->Conversions[ConvIdx].setEllipsis();
+  }
+}
+
+} // end anonymous namespace
+
+/// PrintOverloadCandidates - When overload resolution fails, prints
+/// diagnostic messages containing the candidates in the candidate
+/// set.
+void
+Sema::PrintOverloadCandidates(OverloadCandidateSet& CandidateSet,
+                              OverloadCandidateDisplayKind OCD,
+                              Expr **Args, unsigned NumArgs,
+                              const char *Opc,
+                              SourceLocation OpLoc) {
+  // Sort the candidates by viability and position.  Sorting directly would
+  // be prohibitive, so we make a set of pointers and sort those.
+  llvm::SmallVector<OverloadCandidate*, 32> Cands;
+  if (OCD == OCD_AllCandidates) Cands.reserve(CandidateSet.size());
+  for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
+                                  LastCand = CandidateSet.end();
+       Cand != LastCand; ++Cand) {
+    if (Cand->Viable)
+      Cands.push_back(Cand);
+    else if (OCD == OCD_AllCandidates) {
+      CompleteNonViableCandidate(*this, Cand, Args, NumArgs);
+      Cands.push_back(Cand);
+    }
+  }
+
+  std::sort(Cands.begin(), Cands.end(),
+            CompareOverloadCandidatesForDisplay(*this));
+  
+  bool ReportedAmbiguousConversions = false;
+
+  llvm::SmallVectorImpl<OverloadCandidate*>::iterator I, E;
+  for (I = Cands.begin(), E = Cands.end(); I != E; ++I) {
+    OverloadCandidate *Cand = *I;
+
+    if (Cand->Function)
+      NoteFunctionCandidate(*this, Cand, Args, NumArgs);
+    else if (Cand->IsSurrogate)
+      NoteSurrogateCandidate(*this, Cand);
+
+    // This a builtin candidate.  We do not, in general, want to list
+    // every possible builtin candidate.
+    else if (Cand->Viable) {
+      // Generally we only see ambiguities including viable builtin
+      // operators if overload resolution got screwed up by an
+      // ambiguous user-defined conversion.
+      //
+      // FIXME: It's quite possible for different conversions to see
+      // different ambiguities, though.
+      if (!ReportedAmbiguousConversions) {
+        NoteAmbiguousUserConversions(*this, OpLoc, Cand);
+        ReportedAmbiguousConversions = true;
+      }
+
+      // If this is a viable builtin, print it.
+      NoteBuiltinOperatorCandidate(*this, Opc, OpLoc, Cand);
+    }
+  }
+}
+
+static bool CheckUnresolvedAccess(Sema &S, OverloadExpr *E, DeclAccessPair D) {
+  if (isa<UnresolvedLookupExpr>(E))
+    return S.CheckUnresolvedLookupAccess(cast<UnresolvedLookupExpr>(E), D);
+
+  return S.CheckUnresolvedMemberAccess(cast<UnresolvedMemberExpr>(E), D);
+}
+
+/// ResolveAddressOfOverloadedFunction - Try to resolve the address of
+/// an overloaded function (C++ [over.over]), where @p From is an
+/// expression with overloaded function type and @p ToType is the type
+/// we're trying to resolve to. For example:
+///
+/// @code
+/// int f(double);
+/// int f(int);
+///
+/// int (*pfd)(double) = f; // selects f(double)
+/// @endcode
+///
+/// This routine returns the resulting FunctionDecl if it could be
+/// resolved, and NULL otherwise. When @p Complain is true, this
+/// routine will emit diagnostics if there is an error.
+FunctionDecl *
+Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
+                                         bool Complain,
+                                         DeclAccessPair &FoundResult) {
+  QualType FunctionType = ToType;
+  bool IsMember = false;
+  if (const PointerType *ToTypePtr = ToType->getAs<PointerType>())
+    FunctionType = ToTypePtr->getPointeeType();
+  else if (const ReferenceType *ToTypeRef = ToType->getAs<ReferenceType>())
+    FunctionType = ToTypeRef->getPointeeType();
+  else if (const MemberPointerType *MemTypePtr =
+                    ToType->getAs<MemberPointerType>()) {
+    FunctionType = MemTypePtr->getPointeeType();
+    IsMember = true;
+  }
+
+  // C++ [over.over]p1:
+  //   [...] [Note: any redundant set of parentheses surrounding the
+  //   overloaded function name is ignored (5.1). ]
+  // C++ [over.over]p1:
+  //   [...] The overloaded function name can be preceded by the &
+  //   operator.
+  OverloadExpr *OvlExpr = OverloadExpr::find(From).getPointer();
+  TemplateArgumentListInfo ETABuffer, *ExplicitTemplateArgs = 0;
+  if (OvlExpr->hasExplicitTemplateArgs()) {
+    OvlExpr->getExplicitTemplateArgs().copyInto(ETABuffer);
+    ExplicitTemplateArgs = &ETABuffer;
+  }
+  
+  // We expect a pointer or reference to function, or a function pointer.
+  FunctionType = Context.getCanonicalType(FunctionType).getUnqualifiedType();
+  if (!FunctionType->isFunctionType()) {
+    if (Complain)
+      Diag(From->getLocStart(), diag::err_addr_ovl_not_func_ptrref)
+        << OvlExpr->getName() << ToType;
+    
+    return 0;
+  }
+
+  assert(From->getType() == Context.OverloadTy);
+
+  // Look through all of the overloaded functions, searching for one
+  // whose type matches exactly.
+  llvm::SmallVector<std::pair<DeclAccessPair, FunctionDecl*>, 4> Matches;
+  llvm::SmallVector<FunctionDecl *, 4> NonMatches;
+
+  bool FoundNonTemplateFunction = false;
+  for (UnresolvedSetIterator I = OvlExpr->decls_begin(),
+         E = OvlExpr->decls_end(); I != E; ++I) {
+    // Look through any using declarations to find the underlying function.
+    NamedDecl *Fn = (*I)->getUnderlyingDecl();
+
+    // C++ [over.over]p3:
+    //   Non-member functions and static member functions match
+    //   targets of type "pointer-to-function" or "reference-to-function."
+    //   Nonstatic member functions match targets of
+    //   type "pointer-to-member-function."
+    // Note that according to DR 247, the containing class does not matter.
+
+    if (FunctionTemplateDecl *FunctionTemplate
+          = dyn_cast<FunctionTemplateDecl>(Fn)) {
+      if (CXXMethodDecl *Method
+            = dyn_cast<CXXMethodDecl>(FunctionTemplate->getTemplatedDecl())) {
+        // Skip non-static function templates when converting to pointer, and
+        // static when converting to member pointer.
+        if (Method->isStatic() == IsMember)
+          continue;
+      } else if (IsMember)
+        continue;
+
+      // C++ [over.over]p2:
+      //   If the name is a function template, template argument deduction is
+      //   done (14.8.2.2), and if the argument deduction succeeds, the
+      //   resulting template argument list is used to generate a single
+      //   function template specialization, which is added to the set of
+      //   overloaded functions considered.
+      // FIXME: We don't really want to build the specialization here, do we?
+      FunctionDecl *Specialization = 0;
+      TemplateDeductionInfo Info(Context, OvlExpr->getNameLoc());
+      if (TemplateDeductionResult Result
+            = DeduceTemplateArguments(FunctionTemplate, ExplicitTemplateArgs,
+                                      FunctionType, Specialization, Info)) {
+        // FIXME: make a note of the failed deduction for diagnostics.
+        (void)Result;
+      } else {
+        // FIXME: If the match isn't exact, shouldn't we just drop this as
+        // a candidate? Find a testcase before changing the code.
+        assert(FunctionType
+                 == Context.getCanonicalType(Specialization->getType()));
+        Matches.push_back(std::make_pair(I.getPair(),
+                    cast<FunctionDecl>(Specialization->getCanonicalDecl())));
+      }
+
+      continue;
+    }
+
+    if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Fn)) {
+      // Skip non-static functions when converting to pointer, and static
+      // when converting to member pointer.
+      if (Method->isStatic() == IsMember)
+        continue;
+      
+      // If we have explicit template arguments, skip non-templates.
+      if (OvlExpr->hasExplicitTemplateArgs())
+        continue;
+    } else if (IsMember)
+      continue;
+
+    if (FunctionDecl *FunDecl = dyn_cast<FunctionDecl>(Fn)) {
+      QualType ResultTy;
+      if (Context.hasSameUnqualifiedType(FunctionType, FunDecl->getType()) ||
+          IsNoReturnConversion(Context, FunDecl->getType(), FunctionType, 
+                               ResultTy)) {
+        Matches.push_back(std::make_pair(I.getPair(),
+                           cast<FunctionDecl>(FunDecl->getCanonicalDecl())));
+        FoundNonTemplateFunction = true;
+      }
+    }
+  }
+
+  // If there were 0 or 1 matches, we're done.
+  if (Matches.empty()) {
+    if (Complain) {
+      Diag(From->getLocStart(), diag::err_addr_ovl_no_viable)
+        << OvlExpr->getName() << FunctionType;
+      for (UnresolvedSetIterator I = OvlExpr->decls_begin(),
+                                 E = OvlExpr->decls_end(); 
+           I != E; ++I)
+        if (FunctionDecl *F = dyn_cast<FunctionDecl>((*I)->getUnderlyingDecl()))
+          NoteOverloadCandidate(F);
+    }
+    
+    return 0;
+  } else if (Matches.size() == 1) {
+    FunctionDecl *Result = Matches[0].second;
+    FoundResult = Matches[0].first;
+    MarkDeclarationReferenced(From->getLocStart(), Result);
+    if (Complain)
+      CheckAddressOfMemberAccess(OvlExpr, Matches[0].first);
+    return Result;
+  }
+
+  // C++ [over.over]p4:
+  //   If more than one function is selected, [...]
+  if (!FoundNonTemplateFunction) {
+    //   [...] and any given function template specialization F1 is
+    //   eliminated if the set contains a second function template
+    //   specialization whose function template is more specialized
+    //   than the function template of F1 according to the partial
+    //   ordering rules of 14.5.5.2.
+
+    // The algorithm specified above is quadratic. We instead use a
+    // two-pass algorithm (similar to the one used to identify the
+    // best viable function in an overload set) that identifies the
+    // best function template (if it exists).
+
+    UnresolvedSet<4> MatchesCopy; // TODO: avoid!
+    for (unsigned I = 0, E = Matches.size(); I != E; ++I)
+      MatchesCopy.addDecl(Matches[I].second, Matches[I].first.getAccess());
+    
+    UnresolvedSetIterator Result =
+        getMostSpecialized(MatchesCopy.begin(), MatchesCopy.end(),
+                           TPOC_Other, From->getLocStart(),
+                           PDiag(),
+                           PDiag(diag::err_addr_ovl_ambiguous)
+                               << Matches[0].second->getDeclName(),
+                           PDiag(diag::note_ovl_candidate)
+                               << (unsigned) oc_function_template);
+    assert(Result != MatchesCopy.end() && "no most-specialized template");
+    MarkDeclarationReferenced(From->getLocStart(), *Result);
+    FoundResult = Matches[Result - MatchesCopy.begin()].first;
+    if (Complain)
+      CheckUnresolvedAccess(*this, OvlExpr, FoundResult);
+    return cast<FunctionDecl>(*Result);
+  }
+
+  //   [...] any function template specializations in the set are
+  //   eliminated if the set also contains a non-template function, [...]
+  for (unsigned I = 0, N = Matches.size(); I != N; ) {
+    if (Matches[I].second->getPrimaryTemplate() == 0)
+      ++I;
+    else {
+      Matches[I] = Matches[--N];
+      Matches.set_size(N);
+    }
+  }
+  
+  // [...] After such eliminations, if any, there shall remain exactly one
+  // selected function.
+  if (Matches.size() == 1) {
+    MarkDeclarationReferenced(From->getLocStart(), Matches[0].second);
+    FoundResult = Matches[0].first;
+    if (Complain)
+      CheckUnresolvedAccess(*this, OvlExpr, Matches[0].first);
+    return cast<FunctionDecl>(Matches[0].second);
+  }
+
+  // FIXME: We should probably return the same thing that BestViableFunction
+  // returns (even if we issue the diagnostics here).
+  Diag(From->getLocStart(), diag::err_addr_ovl_ambiguous)
+    << Matches[0].second->getDeclName();
+  for (unsigned I = 0, E = Matches.size(); I != E; ++I)
+    NoteOverloadCandidate(Matches[I].second);
+  return 0;
+}
+
+/// \brief Given an expression that refers to an overloaded function, try to 
+/// resolve that overloaded function expression down to a single function.
+///
+/// This routine can only resolve template-ids that refer to a single function
+/// template, where that template-id refers to a single template whose template
+/// arguments are either provided by the template-id or have defaults, 
+/// as described in C++0x [temp.arg.explicit]p3.
+FunctionDecl *Sema::ResolveSingleFunctionTemplateSpecialization(Expr *From) {
+  // C++ [over.over]p1:
+  //   [...] [Note: any redundant set of parentheses surrounding the
+  //   overloaded function name is ignored (5.1). ]
+  // C++ [over.over]p1:
+  //   [...] The overloaded function name can be preceded by the &
+  //   operator.
+
+  if (From->getType() != Context.OverloadTy)
+    return 0;
+
+  OverloadExpr *OvlExpr = OverloadExpr::find(From).getPointer();
+  
+  // If we didn't actually find any template-ids, we're done.
+  if (!OvlExpr->hasExplicitTemplateArgs())
+    return 0;
+
+  TemplateArgumentListInfo ExplicitTemplateArgs;
+  OvlExpr->getExplicitTemplateArgs().copyInto(ExplicitTemplateArgs);
+  
+  // Look through all of the overloaded functions, searching for one
+  // whose type matches exactly.
+  FunctionDecl *Matched = 0;
+  for (UnresolvedSetIterator I = OvlExpr->decls_begin(),
+         E = OvlExpr->decls_end(); I != E; ++I) {
+    // C++0x [temp.arg.explicit]p3:
+    //   [...] In contexts where deduction is done and fails, or in contexts
+    //   where deduction is not done, if a template argument list is 
+    //   specified and it, along with any default template arguments, 
+    //   identifies a single function template specialization, then the 
+    //   template-id is an lvalue for the function template specialization.
+    FunctionTemplateDecl *FunctionTemplate = cast<FunctionTemplateDecl>(*I);
+    
+    // C++ [over.over]p2:
+    //   If the name is a function template, template argument deduction is
+    //   done (14.8.2.2), and if the argument deduction succeeds, the
+    //   resulting template argument list is used to generate a single
+    //   function template specialization, which is added to the set of
+    //   overloaded functions considered.
+    FunctionDecl *Specialization = 0;
+    TemplateDeductionInfo Info(Context, OvlExpr->getNameLoc());
+    if (TemplateDeductionResult Result
+          = DeduceTemplateArguments(FunctionTemplate, &ExplicitTemplateArgs,
+                                    Specialization, Info)) {
+      // FIXME: make a note of the failed deduction for diagnostics.
+      (void)Result;
+      continue;
+    } 
+    
+    // Multiple matches; we can't resolve to a single declaration.
+    if (Matched)
+      return 0;
+
+    Matched = Specialization;
+  }
+
+  return Matched;
+}
+    
+/// \brief Add a single candidate to the overload set.
+static void AddOverloadedCallCandidate(Sema &S,
+                                       DeclAccessPair FoundDecl,
+                       const TemplateArgumentListInfo *ExplicitTemplateArgs,
+                                       Expr **Args, unsigned NumArgs,
+                                       OverloadCandidateSet &CandidateSet,
+                                       bool PartialOverloading) {
+  NamedDecl *Callee = FoundDecl.getDecl();
+  if (isa<UsingShadowDecl>(Callee))
+    Callee = cast<UsingShadowDecl>(Callee)->getTargetDecl();
+
+  if (FunctionDecl *Func = dyn_cast<FunctionDecl>(Callee)) {
+    assert(!ExplicitTemplateArgs && "Explicit template arguments?");
+    S.AddOverloadCandidate(Func, FoundDecl, Args, NumArgs, CandidateSet,
+                           false, PartialOverloading);
+    return;
+  }
+
+  if (FunctionTemplateDecl *FuncTemplate
+      = dyn_cast<FunctionTemplateDecl>(Callee)) {
+    S.AddTemplateOverloadCandidate(FuncTemplate, FoundDecl,
+                                   ExplicitTemplateArgs,
+                                   Args, NumArgs, CandidateSet);
+    return;
+  }
+
+  assert(false && "unhandled case in overloaded call candidate");
+
+  // do nothing?
+}
+  
+/// \brief Add the overload candidates named by callee and/or found by argument
+/// dependent lookup to the given overload set.
+void Sema::AddOverloadedCallCandidates(UnresolvedLookupExpr *ULE,
+                                       Expr **Args, unsigned NumArgs,
+                                       OverloadCandidateSet &CandidateSet,
+                                       bool PartialOverloading) {
+
+#ifndef NDEBUG
+  // Verify that ArgumentDependentLookup is consistent with the rules
+  // in C++0x [basic.lookup.argdep]p3:
+  //
+  //   Let X be the lookup set produced by unqualified lookup (3.4.1)
+  //   and let Y be the lookup set produced by argument dependent
+  //   lookup (defined as follows). If X contains
+  //
+  //     -- a declaration of a class member, or
+  //
+  //     -- a block-scope function declaration that is not a
+  //        using-declaration, or
+  //
+  //     -- a declaration that is neither a function or a function
+  //        template
+  //
+  //   then Y is empty.
+
+  if (ULE->requiresADL()) {
+    for (UnresolvedLookupExpr::decls_iterator I = ULE->decls_begin(),
+           E = ULE->decls_end(); I != E; ++I) {
+      assert(!(*I)->getDeclContext()->isRecord());
+      assert(isa<UsingShadowDecl>(*I) ||
+             !(*I)->getDeclContext()->isFunctionOrMethod());
+      assert((*I)->getUnderlyingDecl()->isFunctionOrFunctionTemplate());
+    }
+  }
+#endif
+
+  // It would be nice to avoid this copy.
+  TemplateArgumentListInfo TABuffer;
+  const TemplateArgumentListInfo *ExplicitTemplateArgs = 0;
+  if (ULE->hasExplicitTemplateArgs()) {
+    ULE->copyTemplateArgumentsInto(TABuffer);
+    ExplicitTemplateArgs = &TABuffer;
+  }
+
+  for (UnresolvedLookupExpr::decls_iterator I = ULE->decls_begin(),
+         E = ULE->decls_end(); I != E; ++I)
+    AddOverloadedCallCandidate(*this, I.getPair(), ExplicitTemplateArgs,
+                               Args, NumArgs, CandidateSet, 
+                               PartialOverloading);
+
+  if (ULE->requiresADL())
+    AddArgumentDependentLookupCandidates(ULE->getName(), /*Operator*/ false,
+                                         Args, NumArgs,
+                                         ExplicitTemplateArgs,
+                                         CandidateSet,
+                                         PartialOverloading);  
+}
+
+static Sema::OwningExprResult Destroy(Sema &SemaRef, Expr *Fn,
+                                      Expr **Args, unsigned NumArgs) {
+  Fn->Destroy(SemaRef.Context);
+  for (unsigned Arg = 0; Arg < NumArgs; ++Arg)
+    Args[Arg]->Destroy(SemaRef.Context);
+  return SemaRef.ExprError();
+}
+
+/// Attempts to recover from a call where no functions were found.
+///
+/// Returns true if new candidates were found.
+static Sema::OwningExprResult
+BuildRecoveryCallExpr(Sema &SemaRef, Scope *S, Expr *Fn,
+                      UnresolvedLookupExpr *ULE,
+                      SourceLocation LParenLoc,
+                      Expr **Args, unsigned NumArgs,
+                      SourceLocation *CommaLocs,
+                      SourceLocation RParenLoc) {
+
+  CXXScopeSpec SS;
+  if (ULE->getQualifier()) {
+    SS.setScopeRep(ULE->getQualifier());
+    SS.setRange(ULE->getQualifierRange());
+  }
+
+  TemplateArgumentListInfo TABuffer;
+  const TemplateArgumentListInfo *ExplicitTemplateArgs = 0;
+  if (ULE->hasExplicitTemplateArgs()) {
+    ULE->copyTemplateArgumentsInto(TABuffer);
+    ExplicitTemplateArgs = &TABuffer;
+  }
+
+  LookupResult R(SemaRef, ULE->getName(), ULE->getNameLoc(),
+                 Sema::LookupOrdinaryName);
+  if (SemaRef.DiagnoseEmptyLookup(S, SS, R))
+    return Destroy(SemaRef, Fn, Args, NumArgs);
+
+  assert(!R.empty() && "lookup results empty despite recovery");
+
+  // Build an implicit member call if appropriate.  Just drop the
+  // casts and such from the call, we don't really care.
+  Sema::OwningExprResult NewFn = SemaRef.ExprError();
+  if ((*R.begin())->isCXXClassMember())
+    NewFn = SemaRef.BuildPossibleImplicitMemberExpr(SS, R, ExplicitTemplateArgs);
+  else if (ExplicitTemplateArgs)
+    NewFn = SemaRef.BuildTemplateIdExpr(SS, R, false, *ExplicitTemplateArgs);
+  else
+    NewFn = SemaRef.BuildDeclarationNameExpr(SS, R, false);
+
+  if (NewFn.isInvalid())
+    return Destroy(SemaRef, Fn, Args, NumArgs);
+
+  Fn->Destroy(SemaRef.Context);
+
+  // This shouldn't cause an infinite loop because we're giving it
+  // an expression with non-empty lookup results, which should never
+  // end up here.
+  return SemaRef.ActOnCallExpr(/*Scope*/ 0, move(NewFn), LParenLoc,
+                         Sema::MultiExprArg(SemaRef, (void**) Args, NumArgs),
+                               CommaLocs, RParenLoc);
+}
+  
+/// ResolveOverloadedCallFn - Given the call expression that calls Fn
+/// (which eventually refers to the declaration Func) and the call
+/// arguments Args/NumArgs, attempt to resolve the function call down
+/// to a specific function. If overload resolution succeeds, returns
+/// the function declaration produced by overload
+/// resolution. Otherwise, emits diagnostics, deletes all of the
+/// arguments and Fn, and returns NULL.
+Sema::OwningExprResult
+Sema::BuildOverloadedCallExpr(Scope *S, Expr *Fn, UnresolvedLookupExpr *ULE,
+                              SourceLocation LParenLoc,
+                              Expr **Args, unsigned NumArgs,
+                              SourceLocation *CommaLocs,
+                              SourceLocation RParenLoc) {
+#ifndef NDEBUG
+  if (ULE->requiresADL()) {
+    // To do ADL, we must have found an unqualified name.
+    assert(!ULE->getQualifier() && "qualified name with ADL");
+
+    // We don't perform ADL for implicit declarations of builtins.
+    // Verify that this was correctly set up.
+    FunctionDecl *F;
+    if (ULE->decls_begin() + 1 == ULE->decls_end() &&
+        (F = dyn_cast<FunctionDecl>(*ULE->decls_begin())) &&
+        F->getBuiltinID() && F->isImplicit())
+      assert(0 && "performing ADL for builtin");
+      
+    // We don't perform ADL in C.
+    assert(getLangOptions().CPlusPlus && "ADL enabled in C");
+  }
+#endif
+
+  OverloadCandidateSet CandidateSet(Fn->getExprLoc());
+
+  // Add the functions denoted by the callee to the set of candidate
+  // functions, including those from argument-dependent lookup.
+  AddOverloadedCallCandidates(ULE, Args, NumArgs, CandidateSet);
+
+  // If we found nothing, try to recover.
+  // AddRecoveryCallCandidates diagnoses the error itself, so we just
+  // bailout out if it fails.
+  if (CandidateSet.empty())
+    return BuildRecoveryCallExpr(*this, S, Fn, ULE, LParenLoc, Args, NumArgs,
+                                 CommaLocs, RParenLoc);
+
+  OverloadCandidateSet::iterator Best;
+  switch (BestViableFunction(CandidateSet, Fn->getLocStart(), Best)) {
+  case OR_Success: {
+    FunctionDecl *FDecl = Best->Function;
+    CheckUnresolvedLookupAccess(ULE, Best->FoundDecl);
+    Fn = FixOverloadedFunctionReference(Fn, Best->FoundDecl, FDecl);
+    return BuildResolvedCallExpr(Fn, FDecl, LParenLoc, Args, NumArgs, RParenLoc);
+  }
+
+  case OR_No_Viable_Function:
+    Diag(Fn->getSourceRange().getBegin(),
+         diag::err_ovl_no_viable_function_in_call)
+      << ULE->getName() << Fn->getSourceRange();
+    PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, Args, NumArgs);
+    break;
+
+  case OR_Ambiguous:
+    Diag(Fn->getSourceRange().getBegin(), diag::err_ovl_ambiguous_call)
+      << ULE->getName() << Fn->getSourceRange();
+    PrintOverloadCandidates(CandidateSet, OCD_ViableCandidates, Args, NumArgs);
+    break;
+
+  case OR_Deleted:
+    Diag(Fn->getSourceRange().getBegin(), diag::err_ovl_deleted_call)
+      << Best->Function->isDeleted()
+      << ULE->getName()
+      << Fn->getSourceRange();
+    PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, Args, NumArgs);
+    break;
+  }
+
+  // Overload resolution failed. Destroy all of the subexpressions and
+  // return NULL.
+  Fn->Destroy(Context);
+  for (unsigned Arg = 0; Arg < NumArgs; ++Arg)
+    Args[Arg]->Destroy(Context);
+  return ExprError();
+}
+
+static bool IsOverloaded(const UnresolvedSetImpl &Functions) {
+  return Functions.size() > 1 ||
+    (Functions.size() == 1 && isa<FunctionTemplateDecl>(*Functions.begin()));
+}
+
+/// \brief Create a unary operation that may resolve to an overloaded
+/// operator.
+///
+/// \param OpLoc The location of the operator itself (e.g., '*').
+///
+/// \param OpcIn The UnaryOperator::Opcode that describes this
+/// operator.
+///
+/// \param Functions The set of non-member functions that will be
+/// considered by overload resolution. The caller needs to build this
+/// set based on the context using, e.g.,
+/// LookupOverloadedOperatorName() and ArgumentDependentLookup(). This
+/// set should not contain any member functions; those will be added
+/// by CreateOverloadedUnaryOp().
+///
+/// \param input The input argument.
+Sema::OwningExprResult
+Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn,
+                              const UnresolvedSetImpl &Fns,
+                              ExprArg input) {
+  UnaryOperator::Opcode Opc = static_cast<UnaryOperator::Opcode>(OpcIn);
+  Expr *Input = (Expr *)input.get();
+
+  OverloadedOperatorKind Op = UnaryOperator::getOverloadedOperator(Opc);
+  assert(Op != OO_None && "Invalid opcode for overloaded unary operator");
+  DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(Op);
+
+  Expr *Args[2] = { Input, 0 };
+  unsigned NumArgs = 1;
+
+  // For post-increment and post-decrement, add the implicit '0' as
+  // the second argument, so that we know this is a post-increment or
+  // post-decrement.
+  if (Opc == UnaryOperator::PostInc || Opc == UnaryOperator::PostDec) {
+    llvm::APSInt Zero(Context.getTypeSize(Context.IntTy), false);
+    Args[1] = new (Context) IntegerLiteral(Zero, Context.IntTy,
+                                           SourceLocation());
+    NumArgs = 2;
+  }
+
+  if (Input->isTypeDependent()) {
+    CXXRecordDecl *NamingClass = 0; // because lookup ignores member operators
+    UnresolvedLookupExpr *Fn
+      = UnresolvedLookupExpr::Create(Context, /*Dependent*/ true, NamingClass,
+                                     0, SourceRange(), OpName, OpLoc,
+                                     /*ADL*/ true, IsOverloaded(Fns));
+    Fn->addDecls(Fns.begin(), Fns.end());
+
+    input.release();
+    return Owned(new (Context) CXXOperatorCallExpr(Context, Op, Fn,
+                                                   &Args[0], NumArgs,
+                                                   Context.DependentTy,
+                                                   OpLoc));
+  }
+
+  // Build an empty overload set.
+  OverloadCandidateSet CandidateSet(OpLoc);
+
+  // Add the candidates from the given function set.
+  AddFunctionCandidates(Fns, &Args[0], NumArgs, CandidateSet, false);
+
+  // Add operator candidates that are member functions.
+  AddMemberOperatorCandidates(Op, OpLoc, &Args[0], NumArgs, CandidateSet);
+
+  // Add candidates from ADL.
+  AddArgumentDependentLookupCandidates(OpName, /*Operator*/ true,
+                                       Args, NumArgs,
+                                       /*ExplicitTemplateArgs*/ 0,
+                                       CandidateSet);
+
+  // Add builtin operator candidates.
+  AddBuiltinOperatorCandidates(Op, OpLoc, &Args[0], NumArgs, CandidateSet);
+
+  // Perform overload resolution.
+  OverloadCandidateSet::iterator Best;
+  switch (BestViableFunction(CandidateSet, OpLoc, Best)) {
+  case OR_Success: {
+    // We found a built-in operator or an overloaded operator.
+    FunctionDecl *FnDecl = Best->Function;
+
+    if (FnDecl) {
+      // We matched an overloaded operator. Build a call to that
+      // operator.
+
+      // Convert the arguments.
+      if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(FnDecl)) {
+        CheckMemberOperatorAccess(OpLoc, Args[0], 0, Best->FoundDecl);
+
+        if (PerformObjectArgumentInitialization(Input, /*Qualifier=*/0,
+                                                Best->FoundDecl, Method))
+          return ExprError();
+      } else {
+        // Convert the arguments.
+        OwningExprResult InputInit
+          = PerformCopyInitialization(InitializedEntity::InitializeParameter(
+                                                      FnDecl->getParamDecl(0)),
+                                      SourceLocation(), 
+                                      move(input));
+        if (InputInit.isInvalid())
+          return ExprError();
+        
+        input = move(InputInit);
+        Input = (Expr *)input.get();
+      }
+
+      // Determine the result type
+      QualType ResultTy = FnDecl->getResultType().getNonReferenceType();
+
+      // Build the actual expression node.
+      Expr *FnExpr = new (Context) DeclRefExpr(FnDecl, FnDecl->getType(),
+                                               SourceLocation());
+      UsualUnaryConversions(FnExpr);
+
+      input.release();
+      Args[0] = Input;
+      ExprOwningPtr<CallExpr> TheCall(this,
+        new (Context) CXXOperatorCallExpr(Context, Op, FnExpr,
+                                          Args, NumArgs, ResultTy, OpLoc));
+      
+      if (CheckCallReturnType(FnDecl->getResultType(), OpLoc, TheCall.get(), 
+                              FnDecl))
+        return ExprError();
+
+      return MaybeBindToTemporary(TheCall.release());
+    } else {
+      // We matched a built-in operator. Convert the arguments, then
+      // break out so that we will build the appropriate built-in
+      // operator node.
+        if (PerformImplicitConversion(Input, Best->BuiltinTypes.ParamTypes[0],
+                                      Best->Conversions[0], AA_Passing))
+          return ExprError();
+
+        break;
+      }
+    }
+
+    case OR_No_Viable_Function:
+      // No viable function; fall through to handling this as a
+      // built-in operator, which will produce an error message for us.
+      break;
+
+    case OR_Ambiguous:
+      Diag(OpLoc,  diag::err_ovl_ambiguous_oper)
+          << UnaryOperator::getOpcodeStr(Opc)
+          << Input->getSourceRange();
+      PrintOverloadCandidates(CandidateSet, OCD_ViableCandidates, Args, NumArgs,
+                              UnaryOperator::getOpcodeStr(Opc), OpLoc);
+      return ExprError();
+
+    case OR_Deleted:
+      Diag(OpLoc, diag::err_ovl_deleted_oper)
+        << Best->Function->isDeleted()
+        << UnaryOperator::getOpcodeStr(Opc)
+        << Input->getSourceRange();
+      PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, Args, NumArgs);
+      return ExprError();
+    }
+
+  // Either we found no viable overloaded operator or we matched a
+  // built-in operator. In either case, fall through to trying to
+  // build a built-in operation.
+  input.release();
+  return CreateBuiltinUnaryOp(OpLoc, Opc, Owned(Input));
+}
+
+/// \brief Create a binary operation that may resolve to an overloaded
+/// operator.
+///
+/// \param OpLoc The location of the operator itself (e.g., '+').
+///
+/// \param OpcIn The BinaryOperator::Opcode that describes this
+/// operator.
+///
+/// \param Functions The set of non-member functions that will be
+/// considered by overload resolution. The caller needs to build this
+/// set based on the context using, e.g.,
+/// LookupOverloadedOperatorName() and ArgumentDependentLookup(). This
+/// set should not contain any member functions; those will be added
+/// by CreateOverloadedBinOp().
+///
+/// \param LHS Left-hand argument.
+/// \param RHS Right-hand argument.
+Sema::OwningExprResult
+Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
+                            unsigned OpcIn,
+                            const UnresolvedSetImpl &Fns,
+                            Expr *LHS, Expr *RHS) {
+  Expr *Args[2] = { LHS, RHS };
+  LHS=RHS=0; //Please use only Args instead of LHS/RHS couple
+
+  BinaryOperator::Opcode Opc = static_cast<BinaryOperator::Opcode>(OpcIn);
+  OverloadedOperatorKind Op = BinaryOperator::getOverloadedOperator(Opc);
+  DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(Op);
+
+  // If either side is type-dependent, create an appropriate dependent
+  // expression.
+  if (Args[0]->isTypeDependent() || Args[1]->isTypeDependent()) {
+    if (Fns.empty()) {
+      // If there are no functions to store, just build a dependent 
+      // BinaryOperator or CompoundAssignment.
+      if (Opc <= BinaryOperator::Assign || Opc > BinaryOperator::OrAssign)
+        return Owned(new (Context) BinaryOperator(Args[0], Args[1], Opc,
+                                                  Context.DependentTy, OpLoc));
+      
+      return Owned(new (Context) CompoundAssignOperator(Args[0], Args[1], Opc,
+                                                        Context.DependentTy,
+                                                        Context.DependentTy,
+                                                        Context.DependentTy,
+                                                        OpLoc));
+    }
+
+    // FIXME: save results of ADL from here?
+    CXXRecordDecl *NamingClass = 0; // because lookup ignores member operators
+    UnresolvedLookupExpr *Fn
+      = UnresolvedLookupExpr::Create(Context, /*Dependent*/ true, NamingClass,
+                                     0, SourceRange(), OpName, OpLoc,
+                                     /*ADL*/ true, IsOverloaded(Fns));
+
+    Fn->addDecls(Fns.begin(), Fns.end());
+    return Owned(new (Context) CXXOperatorCallExpr(Context, Op, Fn,
+                                                   Args, 2,
+                                                   Context.DependentTy,
+                                                   OpLoc));
+  }
+
+  // If this is the .* operator, which is not overloadable, just
+  // create a built-in binary operator.
+  if (Opc == BinaryOperator::PtrMemD)
+    return CreateBuiltinBinOp(OpLoc, Opc, Args[0], Args[1]);
+
+  // If this is the assignment operator, we only perform overload resolution
+  // if the left-hand side is a class or enumeration type. This is actually
+  // a hack. The standard requires that we do overload resolution between the
+  // various built-in candidates, but as DR507 points out, this can lead to
+  // problems. So we do it this way, which pretty much follows what GCC does.
+  // Note that we go the traditional code path for compound assignment forms.
+  if (Opc==BinaryOperator::Assign && !Args[0]->getType()->isOverloadableType())
+    return CreateBuiltinBinOp(OpLoc, Opc, Args[0], Args[1]);
+
+  // Build an empty overload set.
+  OverloadCandidateSet CandidateSet(OpLoc);
+
+  // Add the candidates from the given function set.
+  AddFunctionCandidates(Fns, Args, 2, CandidateSet, false);
+
+  // Add operator candidates that are member functions.
+  AddMemberOperatorCandidates(Op, OpLoc, Args, 2, CandidateSet);
+
+  // Add candidates from ADL.
+  AddArgumentDependentLookupCandidates(OpName, /*Operator*/ true,
+                                       Args, 2,
+                                       /*ExplicitTemplateArgs*/ 0,
+                                       CandidateSet);
+
+  // Add builtin operator candidates.
+  AddBuiltinOperatorCandidates(Op, OpLoc, Args, 2, CandidateSet);
+
+  // Perform overload resolution.
+  OverloadCandidateSet::iterator Best;
+  switch (BestViableFunction(CandidateSet, OpLoc, Best)) {
+    case OR_Success: {
+      // We found a built-in operator or an overloaded operator.
+      FunctionDecl *FnDecl = Best->Function;
+
+      if (FnDecl) {
+        // We matched an overloaded operator. Build a call to that
+        // operator.
+
+        // Convert the arguments.
+        if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(FnDecl)) {
+          // Best->Access is only meaningful for class members.
+          CheckMemberOperatorAccess(OpLoc, Args[0], Args[1], Best->FoundDecl);
+
+          OwningExprResult Arg1
+            = PerformCopyInitialization(
+                                        InitializedEntity::InitializeParameter(
+                                                        FnDecl->getParamDecl(0)),
+                                        SourceLocation(),
+                                        Owned(Args[1]));
+          if (Arg1.isInvalid())
+            return ExprError();
+
+          if (PerformObjectArgumentInitialization(Args[0], /*Qualifier=*/0, 
+                                                  Best->FoundDecl, Method))
+            return ExprError();
+
+          Args[1] = RHS = Arg1.takeAs<Expr>();
+        } else {
+          // Convert the arguments.
+          OwningExprResult Arg0
+            = PerformCopyInitialization(
+                                        InitializedEntity::InitializeParameter(
+                                                        FnDecl->getParamDecl(0)),
+                                        SourceLocation(),
+                                        Owned(Args[0]));
+          if (Arg0.isInvalid())
+            return ExprError();
+
+          OwningExprResult Arg1
+            = PerformCopyInitialization(
+                                        InitializedEntity::InitializeParameter(
+                                                        FnDecl->getParamDecl(1)),
+                                        SourceLocation(),
+                                        Owned(Args[1]));
+          if (Arg1.isInvalid())
+            return ExprError();
+          Args[0] = LHS = Arg0.takeAs<Expr>();
+          Args[1] = RHS = Arg1.takeAs<Expr>();
+        }
+
+        // Determine the result type
+        QualType ResultTy
+          = FnDecl->getType()->getAs<FunctionType>()->getResultType();
+        ResultTy = ResultTy.getNonReferenceType();
+
+        // Build the actual expression node.
+        Expr *FnExpr = new (Context) DeclRefExpr(FnDecl, FnDecl->getType(),
+                                                 OpLoc);
+        UsualUnaryConversions(FnExpr);
+
+        ExprOwningPtr<CXXOperatorCallExpr> 
+          TheCall(this, new (Context) CXXOperatorCallExpr(Context, Op, FnExpr,
+                                                          Args, 2, ResultTy, 
+                                                          OpLoc));
+        
+        if (CheckCallReturnType(FnDecl->getResultType(), OpLoc, TheCall.get(), 
+                                FnDecl))
+          return ExprError();
+
+        return MaybeBindToTemporary(TheCall.release());
+      } else {
+        // We matched a built-in operator. Convert the arguments, then
+        // break out so that we will build the appropriate built-in
+        // operator node.
+        if (PerformImplicitConversion(Args[0], Best->BuiltinTypes.ParamTypes[0],
+                                      Best->Conversions[0], AA_Passing) ||
+            PerformImplicitConversion(Args[1], Best->BuiltinTypes.ParamTypes[1],
+                                      Best->Conversions[1], AA_Passing))
+          return ExprError();
+
+        break;
+      }
+    }
+
+    case OR_No_Viable_Function: {
+      // C++ [over.match.oper]p9:
+      //   If the operator is the operator , [...] and there are no
+      //   viable functions, then the operator is assumed to be the
+      //   built-in operator and interpreted according to clause 5.
+      if (Opc == BinaryOperator::Comma)
+        break;
+
+      // For class as left operand for assignment or compound assigment operator
+      // do not fall through to handling in built-in, but report that no overloaded
+      // assignment operator found
+      OwningExprResult Result = ExprError();
+      if (Args[0]->getType()->isRecordType() && 
+          Opc >= BinaryOperator::Assign && Opc <= BinaryOperator::OrAssign) {
+        Diag(OpLoc,  diag::err_ovl_no_viable_oper)
+             << BinaryOperator::getOpcodeStr(Opc)
+             << Args[0]->getSourceRange() << Args[1]->getSourceRange();
+      } else {
+        // No viable function; try to create a built-in operation, which will
+        // produce an error. Then, show the non-viable candidates.
+        Result = CreateBuiltinBinOp(OpLoc, Opc, Args[0], Args[1]);
+      }
+      assert(Result.isInvalid() && 
+             "C++ binary operator overloading is missing candidates!");
+      if (Result.isInvalid())
+        PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, Args, 2,
+                                BinaryOperator::getOpcodeStr(Opc), OpLoc);
+      return move(Result);
+    }
+
+    case OR_Ambiguous:
+      Diag(OpLoc,  diag::err_ovl_ambiguous_oper)
+          << BinaryOperator::getOpcodeStr(Opc)
+          << Args[0]->getSourceRange() << Args[1]->getSourceRange();
+      PrintOverloadCandidates(CandidateSet, OCD_ViableCandidates, Args, 2,
+                              BinaryOperator::getOpcodeStr(Opc), OpLoc);
+      return ExprError();
+
+    case OR_Deleted:
+      Diag(OpLoc, diag::err_ovl_deleted_oper)
+        << Best->Function->isDeleted()
+        << BinaryOperator::getOpcodeStr(Opc)
+        << Args[0]->getSourceRange() << Args[1]->getSourceRange();
+      PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, Args, 2);
+      return ExprError();
+  }
+
+  // We matched a built-in operator; build it.
+  return CreateBuiltinBinOp(OpLoc, Opc, Args[0], Args[1]);
+}
+
+Action::OwningExprResult
+Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc,
+                                         SourceLocation RLoc,
+                                         ExprArg Base, ExprArg Idx) {
+  Expr *Args[2] = { static_cast<Expr*>(Base.get()),
+                    static_cast<Expr*>(Idx.get()) };
+  DeclarationName OpName =
+      Context.DeclarationNames.getCXXOperatorName(OO_Subscript);
+
+  // If either side is type-dependent, create an appropriate dependent
+  // expression.
+  if (Args[0]->isTypeDependent() || Args[1]->isTypeDependent()) {
+
+    CXXRecordDecl *NamingClass = 0; // because lookup ignores member operators
+    UnresolvedLookupExpr *Fn
+      = UnresolvedLookupExpr::Create(Context, /*Dependent*/ true, NamingClass,
+                                     0, SourceRange(), OpName, LLoc,
+                                     /*ADL*/ true, /*Overloaded*/ false);
+    // Can't add any actual overloads yet
+
+    Base.release();
+    Idx.release();
+    return Owned(new (Context) CXXOperatorCallExpr(Context, OO_Subscript, Fn,
+                                                   Args, 2,
+                                                   Context.DependentTy,
+                                                   RLoc));
+  }
+
+  // Build an empty overload set.
+  OverloadCandidateSet CandidateSet(LLoc);
+
+  // Subscript can only be overloaded as a member function.
+
+  // Add operator candidates that are member functions.
+  AddMemberOperatorCandidates(OO_Subscript, LLoc, Args, 2, CandidateSet);
+
+  // Add builtin operator candidates.
+  AddBuiltinOperatorCandidates(OO_Subscript, LLoc, Args, 2, CandidateSet);
+
+  // Perform overload resolution.
+  OverloadCandidateSet::iterator Best;
+  switch (BestViableFunction(CandidateSet, LLoc, Best)) {
+    case OR_Success: {
+      // We found a built-in operator or an overloaded operator.
+      FunctionDecl *FnDecl = Best->Function;
+
+      if (FnDecl) {
+        // We matched an overloaded operator. Build a call to that
+        // operator.
+
+        CheckMemberOperatorAccess(LLoc, Args[0], Args[1], Best->FoundDecl);
+
+        // Convert the arguments.
+        CXXMethodDecl *Method = cast<CXXMethodDecl>(FnDecl);
+        if (PerformObjectArgumentInitialization(Args[0], /*Qualifier=*/0, 
+                                                Best->FoundDecl, Method))
+          return ExprError();
+
+        // Convert the arguments.
+        OwningExprResult InputInit
+          = PerformCopyInitialization(InitializedEntity::InitializeParameter(
+                                                      FnDecl->getParamDecl(0)),
+                                      SourceLocation(), 
+                                      Owned(Args[1]));
+        if (InputInit.isInvalid())
+          return ExprError();
+
+        Args[1] = InputInit.takeAs<Expr>();
+
+        // Determine the result type
+        QualType ResultTy
+          = FnDecl->getType()->getAs<FunctionType>()->getResultType();
+        ResultTy = ResultTy.getNonReferenceType();
+
+        // Build the actual expression node.
+        Expr *FnExpr = new (Context) DeclRefExpr(FnDecl, FnDecl->getType(),
+                                                 LLoc);
+        UsualUnaryConversions(FnExpr);
+
+        Base.release();
+        Idx.release();
+        ExprOwningPtr<CXXOperatorCallExpr>
+          TheCall(this, new (Context) CXXOperatorCallExpr(Context, OO_Subscript,
+                                                          FnExpr, Args, 2,
+                                                          ResultTy, RLoc));
+
+        if (CheckCallReturnType(FnDecl->getResultType(), LLoc, TheCall.get(),
+                                FnDecl))
+          return ExprError();
+
+        return MaybeBindToTemporary(TheCall.release());
+      } else {
+        // We matched a built-in operator. Convert the arguments, then
+        // break out so that we will build the appropriate built-in
+        // operator node.
+        if (PerformImplicitConversion(Args[0], Best->BuiltinTypes.ParamTypes[0],
+                                      Best->Conversions[0], AA_Passing) ||
+            PerformImplicitConversion(Args[1], Best->BuiltinTypes.ParamTypes[1],
+                                      Best->Conversions[1], AA_Passing))
+          return ExprError();
+
+        break;
+      }
+    }
+
+    case OR_No_Viable_Function: {
+      if (CandidateSet.empty())
+        Diag(LLoc, diag::err_ovl_no_oper)
+          << Args[0]->getType() << /*subscript*/ 0
+          << Args[0]->getSourceRange() << Args[1]->getSourceRange();
+      else
+        Diag(LLoc, diag::err_ovl_no_viable_subscript)
+          << Args[0]->getType()
+          << Args[0]->getSourceRange() << Args[1]->getSourceRange();
+      PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, Args, 2,
+                              "[]", LLoc);
+      return ExprError();
+    }
+
+    case OR_Ambiguous:
+      Diag(LLoc,  diag::err_ovl_ambiguous_oper)
+          << "[]" << Args[0]->getSourceRange() << Args[1]->getSourceRange();
+      PrintOverloadCandidates(CandidateSet, OCD_ViableCandidates, Args, 2,
+                              "[]", LLoc);
+      return ExprError();
+
+    case OR_Deleted:
+      Diag(LLoc, diag::err_ovl_deleted_oper)
+        << Best->Function->isDeleted() << "[]"
+        << Args[0]->getSourceRange() << Args[1]->getSourceRange();
+      PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, Args, 2,
+                              "[]", LLoc);
+      return ExprError();
+    }
+
+  // We matched a built-in operator; build it.
+  Base.release();
+  Idx.release();
+  return CreateBuiltinArraySubscriptExpr(Owned(Args[0]), LLoc,
+                                         Owned(Args[1]), RLoc);
+}
+
+/// BuildCallToMemberFunction - Build a call to a member
+/// function. MemExpr is the expression that refers to the member
+/// function (and includes the object parameter), Args/NumArgs are the
+/// arguments to the function call (not including the object
+/// parameter). The caller needs to validate that the member
+/// expression refers to a member function or an overloaded member
+/// function.
+Sema::OwningExprResult
+Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
+                                SourceLocation LParenLoc, Expr **Args,
+                                unsigned NumArgs, SourceLocation *CommaLocs,
+                                SourceLocation RParenLoc) {
+  // Dig out the member expression. This holds both the object
+  // argument and the member function we're referring to.
+  Expr *NakedMemExpr = MemExprE->IgnoreParens();
+  
+  MemberExpr *MemExpr;
+  CXXMethodDecl *Method = 0;
+  DeclAccessPair FoundDecl = DeclAccessPair::make(0, AS_public);
+  NestedNameSpecifier *Qualifier = 0;
+  if (isa<MemberExpr>(NakedMemExpr)) {
+    MemExpr = cast<MemberExpr>(NakedMemExpr);
+    Method = cast<CXXMethodDecl>(MemExpr->getMemberDecl());
+    FoundDecl = MemExpr->getFoundDecl();
+    Qualifier = MemExpr->getQualifier();
+  } else {
+    UnresolvedMemberExpr *UnresExpr = cast<UnresolvedMemberExpr>(NakedMemExpr);
+    Qualifier = UnresExpr->getQualifier();
+    
+    QualType ObjectType = UnresExpr->getBaseType();
+
+    // Add overload candidates
+    OverloadCandidateSet CandidateSet(UnresExpr->getMemberLoc());
+
+    // FIXME: avoid copy.
+    TemplateArgumentListInfo TemplateArgsBuffer, *TemplateArgs = 0;
+    if (UnresExpr->hasExplicitTemplateArgs()) {
+      UnresExpr->copyTemplateArgumentsInto(TemplateArgsBuffer);
+      TemplateArgs = &TemplateArgsBuffer;
+    }
+
+    for (UnresolvedMemberExpr::decls_iterator I = UnresExpr->decls_begin(),
+           E = UnresExpr->decls_end(); I != E; ++I) {
+
+      NamedDecl *Func = *I;
+      CXXRecordDecl *ActingDC = cast<CXXRecordDecl>(Func->getDeclContext());
+      if (isa<UsingShadowDecl>(Func))
+        Func = cast<UsingShadowDecl>(Func)->getTargetDecl();
+
+      if ((Method = dyn_cast<CXXMethodDecl>(Func))) {
+        // If explicit template arguments were provided, we can't call a
+        // non-template member function.
+        if (TemplateArgs)
+          continue;
+        
+        AddMethodCandidate(Method, I.getPair(), ActingDC, ObjectType,
+                           Args, NumArgs,
+                           CandidateSet, /*SuppressUserConversions=*/false);
+      } else {
+        AddMethodTemplateCandidate(cast<FunctionTemplateDecl>(Func),
+                                   I.getPair(), ActingDC, TemplateArgs,
+                                   ObjectType, Args, NumArgs,
+                                   CandidateSet,
+                                   /*SuppressUsedConversions=*/false);
+      }
+    }
+
+    DeclarationName DeclName = UnresExpr->getMemberName();
+
+    OverloadCandidateSet::iterator Best;
+    switch (BestViableFunction(CandidateSet, UnresExpr->getLocStart(), Best)) {
+    case OR_Success:
+      Method = cast<CXXMethodDecl>(Best->Function);
+      FoundDecl = Best->FoundDecl;
+      CheckUnresolvedMemberAccess(UnresExpr, Best->FoundDecl);
+      break;
+
+    case OR_No_Viable_Function:
+      Diag(UnresExpr->getMemberLoc(),
+           diag::err_ovl_no_viable_member_function_in_call)
+        << DeclName << MemExprE->getSourceRange();
+      PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, Args, NumArgs);
+      // FIXME: Leaking incoming expressions!
+      return ExprError();
+
+    case OR_Ambiguous:
+      Diag(UnresExpr->getMemberLoc(), diag::err_ovl_ambiguous_member_call)
+        << DeclName << MemExprE->getSourceRange();
+      PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, Args, NumArgs);
+      // FIXME: Leaking incoming expressions!
+      return ExprError();
+
+    case OR_Deleted:
+      Diag(UnresExpr->getMemberLoc(), diag::err_ovl_deleted_member_call)
+        << Best->Function->isDeleted()
+        << DeclName << MemExprE->getSourceRange();
+      PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, Args, NumArgs);
+      // FIXME: Leaking incoming expressions!
+      return ExprError();
+    }
+
+    MemExprE = FixOverloadedFunctionReference(MemExprE, FoundDecl, Method);
+
+    // If overload resolution picked a static member, build a
+    // non-member call based on that function.
+    if (Method->isStatic()) {
+      return BuildResolvedCallExpr(MemExprE, Method, LParenLoc,
+                                   Args, NumArgs, RParenLoc);
+    }
+
+    MemExpr = cast<MemberExpr>(MemExprE->IgnoreParens());
+  }
+
+  assert(Method && "Member call to something that isn't a method?");
+  ExprOwningPtr<CXXMemberCallExpr>
+    TheCall(this, new (Context) CXXMemberCallExpr(Context, MemExprE, Args,
+                                                  NumArgs,
+                                  Method->getResultType().getNonReferenceType(),
+                                  RParenLoc));
+
+  // Check for a valid return type.
+  if (CheckCallReturnType(Method->getResultType(), MemExpr->getMemberLoc(), 
+                          TheCall.get(), Method))
+    return ExprError();
+  
+  // Convert the object argument (for a non-static member function call).
+  // We only need to do this if there was actually an overload; otherwise
+  // it was done at lookup.
+  Expr *ObjectArg = MemExpr->getBase();
+  if (!Method->isStatic() &&
+      PerformObjectArgumentInitialization(ObjectArg, Qualifier,
+                                          FoundDecl, Method))
+    return ExprError();
+  MemExpr->setBase(ObjectArg);
+
+  // Convert the rest of the arguments
+  const FunctionProtoType *Proto = cast<FunctionProtoType>(Method->getType());
+  if (ConvertArgumentsForCall(&*TheCall, MemExpr, Method, Proto, Args, NumArgs,
+                              RParenLoc))
+    return ExprError();
+
+  if (CheckFunctionCall(Method, TheCall.get()))
+    return ExprError();
+
+  return MaybeBindToTemporary(TheCall.release());
+}
+
+/// BuildCallToObjectOfClassType - Build a call to an object of class
+/// type (C++ [over.call.object]), which can end up invoking an
+/// overloaded function call operator (@c operator()) or performing a
+/// user-defined conversion on the object argument.
+Sema::ExprResult
+Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
+                                   SourceLocation LParenLoc,
+                                   Expr **Args, unsigned NumArgs,
+                                   SourceLocation *CommaLocs,
+                                   SourceLocation RParenLoc) {
+  assert(Object->getType()->isRecordType() && "Requires object type argument");
+  const RecordType *Record = Object->getType()->getAs<RecordType>();
+
+  // C++ [over.call.object]p1:
+  //  If the primary-expression E in the function call syntax
+  //  evaluates to a class object of type "cv T", then the set of
+  //  candidate functions includes at least the function call
+  //  operators of T. The function call operators of T are obtained by
+  //  ordinary lookup of the name operator() in the context of
+  //  (E).operator().
+  OverloadCandidateSet CandidateSet(LParenLoc);
+  DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(OO_Call);
+
+  if (RequireCompleteType(LParenLoc, Object->getType(), 
+                          PDiag(diag::err_incomplete_object_call)
+                          << Object->getSourceRange()))
+    return true;
+  
+  LookupResult R(*this, OpName, LParenLoc, LookupOrdinaryName);
+  LookupQualifiedName(R, Record->getDecl());
+  R.suppressDiagnostics();
+
+  for (LookupResult::iterator Oper = R.begin(), OperEnd = R.end();
+       Oper != OperEnd; ++Oper) {
+    AddMethodCandidate(Oper.getPair(), Object->getType(),
+                       Args, NumArgs, CandidateSet,
+                       /*SuppressUserConversions=*/ false);
+  }
+  
+  // C++ [over.call.object]p2:
+  //   In addition, for each conversion function declared in T of the
+  //   form
+  //
+  //        operator conversion-type-id () cv-qualifier;
+  //
+  //   where cv-qualifier is the same cv-qualification as, or a
+  //   greater cv-qualification than, cv, and where conversion-type-id
+  //   denotes the type "pointer to function of (P1,...,Pn) returning
+  //   R", or the type "reference to pointer to function of
+  //   (P1,...,Pn) returning R", or the type "reference to function
+  //   of (P1,...,Pn) returning R", a surrogate call function [...]
+  //   is also considered as a candidate function. Similarly,
+  //   surrogate call functions are added to the set of candidate
+  //   functions for each conversion function declared in an
+  //   accessible base class provided the function is not hidden
+  //   within T by another intervening declaration.
+  const UnresolvedSetImpl *Conversions
+    = cast<CXXRecordDecl>(Record->getDecl())->getVisibleConversionFunctions();
+  for (UnresolvedSetImpl::iterator I = Conversions->begin(),
+         E = Conversions->end(); I != E; ++I) {
+    NamedDecl *D = *I;
+    CXXRecordDecl *ActingContext = cast<CXXRecordDecl>(D->getDeclContext());
+    if (isa<UsingShadowDecl>(D))
+      D = cast<UsingShadowDecl>(D)->getTargetDecl();
+    
+    // Skip over templated conversion functions; they aren't
+    // surrogates.
+    if (isa<FunctionTemplateDecl>(D))
+      continue;
+
+    CXXConversionDecl *Conv = cast<CXXConversionDecl>(D);
+
+    // Strip the reference type (if any) and then the pointer type (if
+    // any) to get down to what might be a function type.
+    QualType ConvType = Conv->getConversionType().getNonReferenceType();
+    if (const PointerType *ConvPtrType = ConvType->getAs<PointerType>())
+      ConvType = ConvPtrType->getPointeeType();
+
+    if (const FunctionProtoType *Proto = ConvType->getAs<FunctionProtoType>())
+      AddSurrogateCandidate(Conv, I.getPair(), ActingContext, Proto,
+                            Object->getType(), Args, NumArgs,
+                            CandidateSet);
+  }
+
+  // Perform overload resolution.
+  OverloadCandidateSet::iterator Best;
+  switch (BestViableFunction(CandidateSet, Object->getLocStart(), Best)) {
+  case OR_Success:
+    // Overload resolution succeeded; we'll build the appropriate call
+    // below.
+    break;
+
+  case OR_No_Viable_Function:
+    if (CandidateSet.empty())
+      Diag(Object->getSourceRange().getBegin(), diag::err_ovl_no_oper)
+        << Object->getType() << /*call*/ 1
+        << Object->getSourceRange();
+    else
+      Diag(Object->getSourceRange().getBegin(),
+           diag::err_ovl_no_viable_object_call)
+        << Object->getType() << Object->getSourceRange();
+    PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, Args, NumArgs);
+    break;
+
+  case OR_Ambiguous:
+    Diag(Object->getSourceRange().getBegin(),
+         diag::err_ovl_ambiguous_object_call)
+      << Object->getType() << Object->getSourceRange();
+    PrintOverloadCandidates(CandidateSet, OCD_ViableCandidates, Args, NumArgs);
+    break;
+
+  case OR_Deleted:
+    Diag(Object->getSourceRange().getBegin(),
+         diag::err_ovl_deleted_object_call)
+      << Best->Function->isDeleted()
+      << Object->getType() << Object->getSourceRange();
+    PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, Args, NumArgs);
+    break;
+  }
+
+  if (Best == CandidateSet.end()) {
+    // We had an error; delete all of the subexpressions and return
+    // the error.
+    Object->Destroy(Context);
+    for (unsigned ArgIdx = 0; ArgIdx < NumArgs; ++ArgIdx)
+      Args[ArgIdx]->Destroy(Context);
+    return true;
+  }
+
+  if (Best->Function == 0) {
+    // Since there is no function declaration, this is one of the
+    // surrogate candidates. Dig out the conversion function.
+    CXXConversionDecl *Conv
+      = cast<CXXConversionDecl>(
+                         Best->Conversions[0].UserDefined.ConversionFunction);
+
+    CheckMemberOperatorAccess(LParenLoc, Object, 0, Best->FoundDecl);
+
+    // We selected one of the surrogate functions that converts the
+    // object parameter to a function pointer. Perform the conversion
+    // on the object argument, then let ActOnCallExpr finish the job.
+    
+    // Create an implicit member expr to refer to the conversion operator.
+    // and then call it.
+    CXXMemberCallExpr *CE = BuildCXXMemberCallExpr(Object, Best->FoundDecl,
+                                                   Conv);
+      
+    return ActOnCallExpr(S, ExprArg(*this, CE), LParenLoc,
+                         MultiExprArg(*this, (ExprTy**)Args, NumArgs),
+                         CommaLocs, RParenLoc).result();
+  }
+
+  CheckMemberOperatorAccess(LParenLoc, Object, 0, Best->FoundDecl);
+
+  // We found an overloaded operator(). Build a CXXOperatorCallExpr
+  // that calls this method, using Object for the implicit object
+  // parameter and passing along the remaining arguments.
+  CXXMethodDecl *Method = cast<CXXMethodDecl>(Best->Function);
+  const FunctionProtoType *Proto = Method->getType()->getAs<FunctionProtoType>();
+
+  unsigned NumArgsInProto = Proto->getNumArgs();
+  unsigned NumArgsToCheck = NumArgs;
+
+  // Build the full argument list for the method call (the
+  // implicit object parameter is placed at the beginning of the
+  // list).
+  Expr **MethodArgs;
+  if (NumArgs < NumArgsInProto) {
+    NumArgsToCheck = NumArgsInProto;
+    MethodArgs = new Expr*[NumArgsInProto + 1];
+  } else {
+    MethodArgs = new Expr*[NumArgs + 1];
+  }
+  MethodArgs[0] = Object;
+  for (unsigned ArgIdx = 0; ArgIdx < NumArgs; ++ArgIdx)
+    MethodArgs[ArgIdx + 1] = Args[ArgIdx];
+
+  Expr *NewFn = new (Context) DeclRefExpr(Method, Method->getType(),
+                                          SourceLocation());
+  UsualUnaryConversions(NewFn);
+
+  // Once we've built TheCall, all of the expressions are properly
+  // owned.
+  QualType ResultTy = Method->getResultType().getNonReferenceType();
+  ExprOwningPtr<CXXOperatorCallExpr>
+    TheCall(this, new (Context) CXXOperatorCallExpr(Context, OO_Call, NewFn,
+                                                    MethodArgs, NumArgs + 1,
+                                                    ResultTy, RParenLoc));
+  delete [] MethodArgs;
+
+  if (CheckCallReturnType(Method->getResultType(), LParenLoc, TheCall.get(), 
+                          Method))
+    return true;
+  
+  // We may have default arguments. If so, we need to allocate more
+  // slots in the call for them.
+  if (NumArgs < NumArgsInProto)
+    TheCall->setNumArgs(Context, NumArgsInProto + 1);
+  else if (NumArgs > NumArgsInProto)
+    NumArgsToCheck = NumArgsInProto;
+
+  bool IsError = false;
+
+  // Initialize the implicit object parameter.
+  IsError |= PerformObjectArgumentInitialization(Object, /*Qualifier=*/0, 
+                                                 Best->FoundDecl, Method);
+  TheCall->setArg(0, Object);
+
+
+  // Check the argument types.
+  for (unsigned i = 0; i != NumArgsToCheck; i++) {
+    Expr *Arg;
+    if (i < NumArgs) {
+      Arg = Args[i];
+
+      // Pass the argument.
+
+      OwningExprResult InputInit
+        = PerformCopyInitialization(InitializedEntity::InitializeParameter(
+                                                    Method->getParamDecl(i)),
+                                    SourceLocation(), Owned(Arg));
+      
+      IsError |= InputInit.isInvalid();
+      Arg = InputInit.takeAs<Expr>();
+    } else {
+      OwningExprResult DefArg
+        = BuildCXXDefaultArgExpr(LParenLoc, Method, Method->getParamDecl(i));
+      if (DefArg.isInvalid()) {
+        IsError = true;
+        break;
+      }
+      
+      Arg = DefArg.takeAs<Expr>();
+    }
+
+    TheCall->setArg(i + 1, Arg);
+  }
+
+  // If this is a variadic call, handle args passed through "...".
+  if (Proto->isVariadic()) {
+    // Promote the arguments (C99 6.5.2.2p7).
+    for (unsigned i = NumArgsInProto; i != NumArgs; i++) {
+      Expr *Arg = Args[i];
+      IsError |= DefaultVariadicArgumentPromotion(Arg, VariadicMethod);
+      TheCall->setArg(i + 1, Arg);
+    }
+  }
+
+  if (IsError) return true;
+
+  if (CheckFunctionCall(Method, TheCall.get()))
+    return true;
+
+  return MaybeBindToTemporary(TheCall.release()).result();
+}
+
+/// BuildOverloadedArrowExpr - Build a call to an overloaded @c operator->
+///  (if one exists), where @c Base is an expression of class type and
+/// @c Member is the name of the member we're trying to find.
+Sema::OwningExprResult
+Sema::BuildOverloadedArrowExpr(Scope *S, ExprArg BaseIn, SourceLocation OpLoc) {
+  Expr *Base = static_cast<Expr *>(BaseIn.get());
+  assert(Base->getType()->isRecordType() && "left-hand side must have class type");
+
+  SourceLocation Loc = Base->getExprLoc();
+
+  // C++ [over.ref]p1:
+  //
+  //   [...] An expression x->m is interpreted as (x.operator->())->m
+  //   for a class object x of type T if T::operator->() exists and if
+  //   the operator is selected as the best match function by the
+  //   overload resolution mechanism (13.3).
+  DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(OO_Arrow);
+  OverloadCandidateSet CandidateSet(Loc);
+  const RecordType *BaseRecord = Base->getType()->getAs<RecordType>();
+
+  if (RequireCompleteType(Loc, Base->getType(),
+                          PDiag(diag::err_typecheck_incomplete_tag)
+                            << Base->getSourceRange()))
+    return ExprError();
+
+  LookupResult R(*this, OpName, OpLoc, LookupOrdinaryName);
+  LookupQualifiedName(R, BaseRecord->getDecl());
+  R.suppressDiagnostics();
+
+  for (LookupResult::iterator Oper = R.begin(), OperEnd = R.end();
+       Oper != OperEnd; ++Oper) {
+    AddMethodCandidate(Oper.getPair(), Base->getType(), 0, 0, CandidateSet,
+                       /*SuppressUserConversions=*/false);
+  }
+
+  // Perform overload resolution.
+  OverloadCandidateSet::iterator Best;
+  switch (BestViableFunction(CandidateSet, OpLoc, Best)) {
+  case OR_Success:
+    // Overload resolution succeeded; we'll build the call below.
+    break;
+
+  case OR_No_Viable_Function:
+    if (CandidateSet.empty())
+      Diag(OpLoc, diag::err_typecheck_member_reference_arrow)
+        << Base->getType() << Base->getSourceRange();
+    else
+      Diag(OpLoc, diag::err_ovl_no_viable_oper)
+        << "operator->" << Base->getSourceRange();
+    PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, &Base, 1);
+    return ExprError();
+
+  case OR_Ambiguous:
+    Diag(OpLoc,  diag::err_ovl_ambiguous_oper)
+      << "->" << Base->getSourceRange();
+    PrintOverloadCandidates(CandidateSet, OCD_ViableCandidates, &Base, 1);
+    return ExprError();
+
+  case OR_Deleted:
+    Diag(OpLoc,  diag::err_ovl_deleted_oper)
+      << Best->Function->isDeleted()
+      << "->" << Base->getSourceRange();
+    PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, &Base, 1);
+    return ExprError();
+  }
+
+  CheckMemberOperatorAccess(OpLoc, Base, 0, Best->FoundDecl);
+
+  // Convert the object parameter.
+  CXXMethodDecl *Method = cast<CXXMethodDecl>(Best->Function);
+  if (PerformObjectArgumentInitialization(Base, /*Qualifier=*/0,
+                                          Best->FoundDecl, Method))
+    return ExprError();
+
+  // No concerns about early exits now.
+  BaseIn.release();
+
+  // Build the operator call.
+  Expr *FnExpr = new (Context) DeclRefExpr(Method, Method->getType(),
+                                           SourceLocation());
+  UsualUnaryConversions(FnExpr);
+  
+  QualType ResultTy = Method->getResultType().getNonReferenceType();
+  ExprOwningPtr<CXXOperatorCallExpr> 
+    TheCall(this, new (Context) CXXOperatorCallExpr(Context, OO_Arrow, FnExpr, 
+                                                    &Base, 1, ResultTy, OpLoc));
+
+  if (CheckCallReturnType(Method->getResultType(), OpLoc, TheCall.get(), 
+                          Method))
+          return ExprError();
+  return move(TheCall);
+}
+
+/// FixOverloadedFunctionReference - E is an expression that refers to
+/// a C++ overloaded function (possibly with some parentheses and
+/// perhaps a '&' around it). We have resolved the overloaded function
+/// to the function declaration Fn, so patch up the expression E to
+/// refer (possibly indirectly) to Fn. Returns the new expr.
+Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found,
+                                           FunctionDecl *Fn) {
+  if (ParenExpr *PE = dyn_cast<ParenExpr>(E)) {
+    Expr *SubExpr = FixOverloadedFunctionReference(PE->getSubExpr(),
+                                                   Found, Fn);
+    if (SubExpr == PE->getSubExpr())
+      return PE->Retain();
+    
+    return new (Context) ParenExpr(PE->getLParen(), PE->getRParen(), SubExpr);
+  } 
+  
+  if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) {
+    Expr *SubExpr = FixOverloadedFunctionReference(ICE->getSubExpr(),
+                                                   Found, Fn);
+    assert(Context.hasSameType(ICE->getSubExpr()->getType(), 
+                               SubExpr->getType()) &&
+           "Implicit cast type cannot be determined from overload");
+    if (SubExpr == ICE->getSubExpr())
+      return ICE->Retain();
+    
+    return new (Context) ImplicitCastExpr(ICE->getType(), 
+                                          ICE->getCastKind(),
+                                          SubExpr, CXXBaseSpecifierArray(),
+                                          ICE->isLvalueCast());
+  } 
+  
+  if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(E)) {
+    assert(UnOp->getOpcode() == UnaryOperator::AddrOf &&
+           "Can only take the address of an overloaded function");
+    if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Fn)) {
+      if (Method->isStatic()) {
+        // Do nothing: static member functions aren't any different
+        // from non-member functions.
+      } else {
+        // Fix the sub expression, which really has to be an
+        // UnresolvedLookupExpr holding an overloaded member function
+        // or template.
+        Expr *SubExpr = FixOverloadedFunctionReference(UnOp->getSubExpr(),
+                                                       Found, Fn);
+        if (SubExpr == UnOp->getSubExpr())
+          return UnOp->Retain();
+
+        assert(isa<DeclRefExpr>(SubExpr)
+               && "fixed to something other than a decl ref");
+        assert(cast<DeclRefExpr>(SubExpr)->getQualifier()
+               && "fixed to a member ref with no nested name qualifier");
+
+        // We have taken the address of a pointer to member
+        // function. Perform the computation here so that we get the
+        // appropriate pointer to member type.
+        QualType ClassType
+          = Context.getTypeDeclType(cast<RecordDecl>(Method->getDeclContext()));
+        QualType MemPtrType
+          = Context.getMemberPointerType(Fn->getType(), ClassType.getTypePtr());
+
+        return new (Context) UnaryOperator(SubExpr, UnaryOperator::AddrOf,
+                                           MemPtrType, UnOp->getOperatorLoc());
+      }
+    }
+    Expr *SubExpr = FixOverloadedFunctionReference(UnOp->getSubExpr(),
+                                                   Found, Fn);
+    if (SubExpr == UnOp->getSubExpr())
+      return UnOp->Retain();
+    
+    return new (Context) UnaryOperator(SubExpr, UnaryOperator::AddrOf,
+                                     Context.getPointerType(SubExpr->getType()),
+                                       UnOp->getOperatorLoc());
+  } 
+
+  if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(E)) {
+    // FIXME: avoid copy.
+    TemplateArgumentListInfo TemplateArgsBuffer, *TemplateArgs = 0;
+    if (ULE->hasExplicitTemplateArgs()) {
+      ULE->copyTemplateArgumentsInto(TemplateArgsBuffer);
+      TemplateArgs = &TemplateArgsBuffer;
+    }
+
+    return DeclRefExpr::Create(Context,
+                               ULE->getQualifier(),
+                               ULE->getQualifierRange(),
+                               Fn,
+                               ULE->getNameLoc(),
+                               Fn->getType(),
+                               TemplateArgs);
+  }
+
+  if (UnresolvedMemberExpr *MemExpr = dyn_cast<UnresolvedMemberExpr>(E)) {
+    // FIXME: avoid copy.
+    TemplateArgumentListInfo TemplateArgsBuffer, *TemplateArgs = 0;
+    if (MemExpr->hasExplicitTemplateArgs()) {
+      MemExpr->copyTemplateArgumentsInto(TemplateArgsBuffer);
+      TemplateArgs = &TemplateArgsBuffer;
+    }
+
+    Expr *Base;
+
+    // If we're filling in 
+    if (MemExpr->isImplicitAccess()) {
+      if (cast<CXXMethodDecl>(Fn)->isStatic()) {
+        return DeclRefExpr::Create(Context,
+                                   MemExpr->getQualifier(),
+                                   MemExpr->getQualifierRange(),
+                                   Fn,
+                                   MemExpr->getMemberLoc(),
+                                   Fn->getType(),
+                                   TemplateArgs);
+      } else {
+        SourceLocation Loc = MemExpr->getMemberLoc();
+        if (MemExpr->getQualifier())
+          Loc = MemExpr->getQualifierRange().getBegin();
+        Base = new (Context) CXXThisExpr(Loc,
+                                         MemExpr->getBaseType(),
+                                         /*isImplicit=*/true);
+      }
+    } else
+      Base = MemExpr->getBase()->Retain();
+
+    return MemberExpr::Create(Context, Base,
+                              MemExpr->isArrow(), 
+                              MemExpr->getQualifier(), 
+                              MemExpr->getQualifierRange(),
+                              Fn, 
+                              Found,
+                              MemExpr->getMemberLoc(),
+                              TemplateArgs,
+                              Fn->getType());
+  }
+  
+  assert(false && "Invalid reference to overloaded function");
+  return E->Retain();
+}
+
+Sema::OwningExprResult Sema::FixOverloadedFunctionReference(OwningExprResult E, 
+                                                          DeclAccessPair Found,
+                                                            FunctionDecl *Fn) {
+  return Owned(FixOverloadedFunctionReference((Expr *)E.get(), Found, Fn));
+}
+
+} // end namespace clang
diff --git a/lib/Sema/SemaOverload.h b/lib/Sema/SemaOverload.h
new file mode 100644
index 0000000..5e61111
--- /dev/null
+++ b/lib/Sema/SemaOverload.h
@@ -0,0 +1,584 @@
+//===--- Overload.h - C++ Overloading ---------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the data structures and types used in C++
+// overload resolution.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SEMA_OVERLOAD_H
+#define LLVM_CLANG_SEMA_OVERLOAD_H
+
+#include "clang/AST/Decl.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/UnresolvedSet.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace clang {
+  class ASTContext;
+  class CXXConstructorDecl;
+  class CXXConversionDecl;
+  class FunctionDecl;
+
+  /// OverloadingResult - Capture the result of performing overload
+  /// resolution.
+  enum OverloadingResult {
+    OR_Success,             ///< Overload resolution succeeded.
+    OR_No_Viable_Function,  ///< No viable function found.
+    OR_Ambiguous,           ///< Ambiguous candidates found.
+    OR_Deleted              ///< Succeeded, but refers to a deleted function.
+  };
+    
+  /// ImplicitConversionKind - The kind of implicit conversion used to
+  /// convert an argument to a parameter's type. The enumerator values
+  /// match with Table 9 of (C++ 13.3.3.1.1) and are listed such that
+  /// better conversion kinds have smaller values.
+  enum ImplicitConversionKind {
+    ICK_Identity = 0,          ///< Identity conversion (no conversion)
+    ICK_Lvalue_To_Rvalue,      ///< Lvalue-to-rvalue conversion (C++ 4.1)
+    ICK_Array_To_Pointer,      ///< Array-to-pointer conversion (C++ 4.2)
+    ICK_Function_To_Pointer,   ///< Function-to-pointer (C++ 4.3)
+    ICK_NoReturn_Adjustment,   ///< Removal of noreturn from a type (Clang)
+    ICK_Qualification,         ///< Qualification conversions (C++ 4.4)
+    ICK_Integral_Promotion,    ///< Integral promotions (C++ 4.5)
+    ICK_Floating_Promotion,    ///< Floating point promotions (C++ 4.6)
+    ICK_Complex_Promotion,     ///< Complex promotions (Clang extension)
+    ICK_Integral_Conversion,   ///< Integral conversions (C++ 4.7)
+    ICK_Floating_Conversion,   ///< Floating point conversions (C++ 4.8)
+    ICK_Complex_Conversion,    ///< Complex conversions (C99 6.3.1.6)
+    ICK_Floating_Integral,     ///< Floating-integral conversions (C++ 4.9)
+    ICK_Pointer_Conversion,    ///< Pointer conversions (C++ 4.10)
+    ICK_Pointer_Member,        ///< Pointer-to-member conversions (C++ 4.11)
+    ICK_Boolean_Conversion,    ///< Boolean conversions (C++ 4.12)
+    ICK_Compatible_Conversion, ///< Conversions between compatible types in C99
+    ICK_Derived_To_Base,       ///< Derived-to-base (C++ [over.best.ics])
+    ICK_Complex_Real,          ///< Complex-real conversions (C99 6.3.1.7)
+    ICK_Num_Conversion_Kinds   ///< The number of conversion kinds
+  };
+
+  /// ImplicitConversionCategory - The category of an implicit
+  /// conversion kind. The enumerator values match with Table 9 of
+  /// (C++ 13.3.3.1.1) and are listed such that better conversion
+  /// categories have smaller values.
+  enum ImplicitConversionCategory {
+    ICC_Identity = 0,              ///< Identity
+    ICC_Lvalue_Transformation,     ///< Lvalue transformation
+    ICC_Qualification_Adjustment,  ///< Qualification adjustment
+    ICC_Promotion,                 ///< Promotion
+    ICC_Conversion                 ///< Conversion
+  };
+
+  ImplicitConversionCategory
+  GetConversionCategory(ImplicitConversionKind Kind);
+
+  /// ImplicitConversionRank - The rank of an implicit conversion
+  /// kind. The enumerator values match with Table 9 of (C++
+  /// 13.3.3.1.1) and are listed such that better conversion ranks
+  /// have smaller values.
+  enum ImplicitConversionRank {
+    ICR_Exact_Match = 0,        ///< Exact Match
+    ICR_Promotion,              ///< Promotion
+    ICR_Conversion,             ///< Conversion
+    ICR_Complex_Real_Conversion ///< Complex <-> Real conversion
+  };
+
+  ImplicitConversionRank GetConversionRank(ImplicitConversionKind Kind);
+
+  /// StandardConversionSequence - represents a standard conversion
+  /// sequence (C++ 13.3.3.1.1). A standard conversion sequence
+  /// contains between zero and three conversions. If a particular
+  /// conversion is not needed, it will be set to the identity conversion
+  /// (ICK_Identity). Note that the three conversions are
+  /// specified as separate members (rather than in an array) so that
+  /// we can keep the size of a standard conversion sequence to a
+  /// single word.
+  struct StandardConversionSequence {
+    /// First -- The first conversion can be an lvalue-to-rvalue
+    /// conversion, array-to-pointer conversion, or
+    /// function-to-pointer conversion.
+    ImplicitConversionKind First : 8;
+
+    /// Second - The second conversion can be an integral promotion,
+    /// floating point promotion, integral conversion, floating point
+    /// conversion, floating-integral conversion, pointer conversion,
+    /// pointer-to-member conversion, or boolean conversion.
+    ImplicitConversionKind Second : 8;
+
+    /// Third - The third conversion can be a qualification conversion.
+    ImplicitConversionKind Third : 8;
+
+    /// Deprecated - Whether this the deprecated conversion of a
+    /// string literal to a pointer to non-const character data
+    /// (C++ 4.2p2).
+    bool DeprecatedStringLiteralToCharPtr : 1;
+
+    /// IncompatibleObjC - Whether this is an Objective-C conversion
+    /// that we should warn about (if we actually use it).
+    bool IncompatibleObjC : 1;
+
+    /// ReferenceBinding - True when this is a reference binding
+    /// (C++ [over.ics.ref]).
+    bool ReferenceBinding : 1;
+
+    /// DirectBinding - True when this is a reference binding that is a
+    /// direct binding (C++ [dcl.init.ref]).
+    bool DirectBinding : 1;
+
+    /// RRefBinding - True when this is a reference binding of an rvalue
+    /// reference to an rvalue (C++0x [over.ics.rank]p3b4).
+    bool RRefBinding : 1;
+
+    /// FromType - The type that this conversion is converting
+    /// from. This is an opaque pointer that can be translated into a
+    /// QualType.
+    void *FromTypePtr;
+
+    /// ToType - The types that this conversion is converting to in
+    /// each step. This is an opaque pointer that can be translated
+    /// into a QualType.
+    void *ToTypePtrs[3];
+
+    /// CopyConstructor - The copy constructor that is used to perform
+    /// this conversion, when the conversion is actually just the
+    /// initialization of an object via copy constructor. Such
+    /// conversions are either identity conversions or derived-to-base
+    /// conversions.
+    CXXConstructorDecl *CopyConstructor;
+
+    void setFromType(QualType T) { FromTypePtr = T.getAsOpaquePtr(); }
+    void setToType(unsigned Idx, QualType T) { 
+      assert(Idx < 3 && "To type index is out of range");
+      ToTypePtrs[Idx] = T.getAsOpaquePtr(); 
+    }
+    void setAllToTypes(QualType T) {
+      ToTypePtrs[0] = T.getAsOpaquePtr(); 
+      ToTypePtrs[1] = ToTypePtrs[0];
+      ToTypePtrs[2] = ToTypePtrs[0];
+    }
+
+    QualType getFromType() const {
+      return QualType::getFromOpaquePtr(FromTypePtr);
+    }
+    QualType getToType(unsigned Idx) const {
+      assert(Idx < 3 && "To type index is out of range");
+      return QualType::getFromOpaquePtr(ToTypePtrs[Idx]);
+    }
+
+    void setAsIdentityConversion();
+    ImplicitConversionRank getRank() const;
+    bool isPointerConversionToBool() const;
+    bool isPointerConversionToVoidPointer(ASTContext& Context) const;
+    void DebugPrint() const;
+  };
+
+  /// UserDefinedConversionSequence - Represents a user-defined
+  /// conversion sequence (C++ 13.3.3.1.2).
+  struct UserDefinedConversionSequence {
+    /// Before - Represents the standard conversion that occurs before
+    /// the actual user-defined conversion. (C++ 13.3.3.1.2p1):
+    ///
+    ///   If the user-defined conversion is specified by a constructor
+    ///   (12.3.1), the initial standard conversion sequence converts
+    ///   the source type to the type required by the argument of the
+    ///   constructor. If the user-defined conversion is specified by
+    ///   a conversion function (12.3.2), the initial standard
+    ///   conversion sequence converts the source type to the implicit
+    ///   object parameter of the conversion function.
+    StandardConversionSequence Before;
+
+    /// EllipsisConversion - When this is true, it means user-defined
+    /// conversion sequence starts with a ... (elipsis) conversion, instead of 
+    /// a standard conversion. In this case, 'Before' field must be ignored.
+    // FIXME. I much rather put this as the first field. But there seems to be
+    // a gcc code gen. bug which causes a crash in a test. Putting it here seems
+    // to work around the crash.
+    bool EllipsisConversion : 1;
+    
+    /// After - Represents the standard conversion that occurs after
+    /// the actual user-defined conversion.
+    StandardConversionSequence After;
+
+    /// ConversionFunction - The function that will perform the
+    /// user-defined conversion.
+    FunctionDecl* ConversionFunction;
+
+    void DebugPrint() const;
+  };
+
+  /// Represents an ambiguous user-defined conversion sequence.
+  struct AmbiguousConversionSequence {
+    typedef llvm::SmallVector<FunctionDecl*, 4> ConversionSet;
+
+    void *FromTypePtr;
+    void *ToTypePtr;
+    char Buffer[sizeof(ConversionSet)];
+
+    QualType getFromType() const {
+      return QualType::getFromOpaquePtr(FromTypePtr);
+    }
+    QualType getToType() const {
+      return QualType::getFromOpaquePtr(ToTypePtr);
+    }
+    void setFromType(QualType T) { FromTypePtr = T.getAsOpaquePtr(); }
+    void setToType(QualType T) { ToTypePtr = T.getAsOpaquePtr(); }
+
+    ConversionSet &conversions() {
+      return *reinterpret_cast<ConversionSet*>(Buffer);
+    }
+
+    const ConversionSet &conversions() const {
+      return *reinterpret_cast<const ConversionSet*>(Buffer);
+    }
+
+    void addConversion(FunctionDecl *D) {
+      conversions().push_back(D);
+    }
+
+    typedef ConversionSet::iterator iterator;
+    iterator begin() { return conversions().begin(); }
+    iterator end() { return conversions().end(); }
+
+    typedef ConversionSet::const_iterator const_iterator;
+    const_iterator begin() const { return conversions().begin(); }
+    const_iterator end() const { return conversions().end(); }
+
+    void construct();
+    void destruct();
+    void copyFrom(const AmbiguousConversionSequence &);
+  };
+
+  /// BadConversionSequence - Records information about an invalid
+  /// conversion sequence.
+  struct BadConversionSequence {
+    enum FailureKind {
+      no_conversion,
+      unrelated_class,
+      suppressed_user,
+      bad_qualifiers
+    };
+
+    // This can be null, e.g. for implicit object arguments.
+    Expr *FromExpr;
+
+    FailureKind Kind;
+
+  private:
+    // The type we're converting from (an opaque QualType).
+    void *FromTy;
+
+    // The type we're converting to (an opaque QualType).
+    void *ToTy;
+
+  public:
+    void init(FailureKind K, Expr *From, QualType To) {
+      init(K, From->getType(), To);
+      FromExpr = From;
+    }
+    void init(FailureKind K, QualType From, QualType To) {
+      Kind = K;
+      FromExpr = 0;
+      setFromType(From);
+      setToType(To);
+    }
+
+    QualType getFromType() const { return QualType::getFromOpaquePtr(FromTy); }
+    QualType getToType() const { return QualType::getFromOpaquePtr(ToTy); }
+
+    void setFromExpr(Expr *E) {
+      FromExpr = E;
+      setFromType(E->getType());
+    }
+    void setFromType(QualType T) { FromTy = T.getAsOpaquePtr(); }
+    void setToType(QualType T) { ToTy = T.getAsOpaquePtr(); }
+  };
+
+  /// ImplicitConversionSequence - Represents an implicit conversion
+  /// sequence, which may be a standard conversion sequence
+  /// (C++ 13.3.3.1.1), user-defined conversion sequence (C++ 13.3.3.1.2),
+  /// or an ellipsis conversion sequence (C++ 13.3.3.1.3).
+  struct ImplicitConversionSequence {
+    /// Kind - The kind of implicit conversion sequence. BadConversion
+    /// specifies that there is no conversion from the source type to
+    /// the target type.  AmbiguousConversion represents the unique
+    /// ambiguous conversion (C++0x [over.best.ics]p10).
+    enum Kind {
+      StandardConversion = 0,
+      UserDefinedConversion,
+      AmbiguousConversion,
+      EllipsisConversion,
+      BadConversion
+    };
+
+  private:
+    enum {
+      Uninitialized = BadConversion + 1
+    };
+
+    /// ConversionKind - The kind of implicit conversion sequence.
+    unsigned ConversionKind;
+
+    void setKind(Kind K) {
+      destruct();
+      ConversionKind = K;
+    }
+
+    void destruct() {
+      if (ConversionKind == AmbiguousConversion) Ambiguous.destruct();
+    }
+
+  public:
+    union {
+      /// When ConversionKind == StandardConversion, provides the
+      /// details of the standard conversion sequence.
+      StandardConversionSequence Standard;
+
+      /// When ConversionKind == UserDefinedConversion, provides the
+      /// details of the user-defined conversion sequence.
+      UserDefinedConversionSequence UserDefined;
+
+      /// When ConversionKind == AmbiguousConversion, provides the
+      /// details of the ambiguous conversion.
+      AmbiguousConversionSequence Ambiguous;
+
+      /// When ConversionKind == BadConversion, provides the details
+      /// of the bad conversion.
+      BadConversionSequence Bad;
+    };
+
+    ImplicitConversionSequence() : ConversionKind(Uninitialized) {}
+    ~ImplicitConversionSequence() {
+      destruct();
+    }
+    ImplicitConversionSequence(const ImplicitConversionSequence &Other)
+      : ConversionKind(Other.ConversionKind)
+    {
+      switch (ConversionKind) {
+      case Uninitialized: break;
+      case StandardConversion: Standard = Other.Standard; break;
+      case UserDefinedConversion: UserDefined = Other.UserDefined; break;
+      case AmbiguousConversion: Ambiguous.copyFrom(Other.Ambiguous); break;
+      case EllipsisConversion: break;
+      case BadConversion: Bad = Other.Bad; break;
+      }
+    }
+
+    ImplicitConversionSequence &
+        operator=(const ImplicitConversionSequence &Other) {
+      destruct();
+      new (this) ImplicitConversionSequence(Other);
+      return *this;
+    }
+    
+    Kind getKind() const {
+      assert(isInitialized() && "querying uninitialized conversion");
+      return Kind(ConversionKind);
+    }
+    
+    /// \brief Return a ranking of the implicit conversion sequence
+    /// kind, where smaller ranks represent better conversion
+    /// sequences.
+    ///
+    /// In particular, this routine gives user-defined conversion
+    /// sequences and ambiguous conversion sequences the same rank,
+    /// per C++ [over.best.ics]p10.
+    unsigned getKindRank() const {
+      switch (getKind()) {
+      case StandardConversion: 
+        return 0;
+
+      case UserDefinedConversion:
+      case AmbiguousConversion: 
+        return 1;
+
+      case EllipsisConversion:
+        return 2;
+
+      case BadConversion:
+        return 3;
+      }
+
+      return 3;
+    }
+
+    bool isBad() const { return getKind() == BadConversion; }
+    bool isStandard() const { return getKind() == StandardConversion; }
+    bool isEllipsis() const { return getKind() == EllipsisConversion; }
+    bool isAmbiguous() const { return getKind() == AmbiguousConversion; }
+    bool isUserDefined() const { return getKind() == UserDefinedConversion; }
+
+    /// Determines whether this conversion sequence has been
+    /// initialized.  Most operations should never need to query
+    /// uninitialized conversions and should assert as above.
+    bool isInitialized() const { return ConversionKind != Uninitialized; }
+
+    /// Sets this sequence as a bad conversion for an explicit argument.
+    void setBad(BadConversionSequence::FailureKind Failure,
+                Expr *FromExpr, QualType ToType) {
+      setKind(BadConversion);
+      Bad.init(Failure, FromExpr, ToType);
+    }
+
+    /// Sets this sequence as a bad conversion for an implicit argument.
+    void setBad(BadConversionSequence::FailureKind Failure,
+                QualType FromType, QualType ToType) {
+      setKind(BadConversion);
+      Bad.init(Failure, FromType, ToType);
+    }
+
+    void setStandard() { setKind(StandardConversion); }
+    void setEllipsis() { setKind(EllipsisConversion); }
+    void setUserDefined() { setKind(UserDefinedConversion); }
+    void setAmbiguous() {
+      if (ConversionKind == AmbiguousConversion) return;
+      ConversionKind = AmbiguousConversion;
+      Ambiguous.construct();
+    }
+
+    // The result of a comparison between implicit conversion
+    // sequences. Use Sema::CompareImplicitConversionSequences to
+    // actually perform the comparison.
+    enum CompareKind {
+      Better = -1,
+      Indistinguishable = 0,
+      Worse = 1
+    };
+
+    void DebugPrint() const;
+  };
+
+  enum OverloadFailureKind {
+    ovl_fail_too_many_arguments,
+    ovl_fail_too_few_arguments,
+    ovl_fail_bad_conversion,
+    ovl_fail_bad_deduction,
+
+    /// This conversion candidate was not considered because it
+    /// duplicates the work of a trivial or derived-to-base
+    /// conversion.
+    ovl_fail_trivial_conversion,
+
+    /// This conversion candidate is not viable because its result
+    /// type is not implicitly convertible to the desired type.
+    ovl_fail_bad_final_conversion,
+    
+    /// This conversion function template specialization candidate is not 
+    /// viable because the final conversion was not an exact match.
+    ovl_fail_final_conversion_not_exact
+  };
+
+  /// OverloadCandidate - A single candidate in an overload set (C++ 13.3).
+  struct OverloadCandidate {
+    /// Function - The actual function that this candidate
+    /// represents. When NULL, this is a built-in candidate
+    /// (C++ [over.oper]) or a surrogate for a conversion to a
+    /// function pointer or reference (C++ [over.call.object]).
+    FunctionDecl *Function;
+
+    /// FoundDecl - The original declaration that was looked up /
+    /// invented / otherwise found, together with its access.
+    /// Might be a UsingShadowDecl or a FunctionTemplateDecl.
+    DeclAccessPair FoundDecl;
+
+    // BuiltinTypes - Provides the return and parameter types of a
+    // built-in overload candidate. Only valid when Function is NULL.
+    struct {
+      QualType ResultTy;
+      QualType ParamTypes[3];
+    } BuiltinTypes;
+
+    /// Surrogate - The conversion function for which this candidate
+    /// is a surrogate, but only if IsSurrogate is true.
+    CXXConversionDecl *Surrogate;
+
+    /// Conversions - The conversion sequences used to convert the
+    /// function arguments to the function parameters.
+    llvm::SmallVector<ImplicitConversionSequence, 4> Conversions;
+
+    /// Viable - True to indicate that this overload candidate is viable.
+    bool Viable;
+
+    /// IsSurrogate - True to indicate that this candidate is a
+    /// surrogate for a conversion to a function pointer or reference
+    /// (C++ [over.call.object]).
+    bool IsSurrogate;
+
+    /// IgnoreObjectArgument - True to indicate that the first
+    /// argument's conversion, which for this function represents the
+    /// implicit object argument, should be ignored. This will be true
+    /// when the candidate is a static member function (where the
+    /// implicit object argument is just a placeholder) or a
+    /// non-static member function when the call doesn't have an
+    /// object argument.
+    bool IgnoreObjectArgument;
+
+    /// FailureKind - The reason why this candidate is not viable.
+    /// Actually an OverloadFailureKind.
+    unsigned char FailureKind;
+
+    /// A structure used to record information about a failed
+    /// template argument deduction.
+    struct DeductionFailureInfo {
+      // A Sema::TemplateDeductionResult.
+      unsigned Result;
+
+      // A TemplateParameter.
+      void *TemplateParameter;
+    };
+
+    union {
+      DeductionFailureInfo DeductionFailure;
+      
+      /// FinalConversion - For a conversion function (where Function is
+      /// a CXXConversionDecl), the standard conversion that occurs
+      /// after the call to the overload candidate to convert the result
+      /// of calling the conversion function to the required type.
+      StandardConversionSequence FinalConversion;
+    };
+
+    /// hasAmbiguousConversion - Returns whether this overload
+    /// candidate requires an ambiguous conversion or not.
+    bool hasAmbiguousConversion() const {
+      for (llvm::SmallVectorImpl<ImplicitConversionSequence>::const_iterator
+             I = Conversions.begin(), E = Conversions.end(); I != E; ++I) {
+        if (!I->isInitialized()) return false;
+        if (I->isAmbiguous()) return true;
+      }
+      return false;
+    }
+  };
+
+  /// OverloadCandidateSet - A set of overload candidates, used in C++
+  /// overload resolution (C++ 13.3).
+  class OverloadCandidateSet : public llvm::SmallVector<OverloadCandidate, 16> {
+    typedef llvm::SmallVector<OverloadCandidate, 16> inherited;
+    llvm::SmallPtrSet<Decl *, 16> Functions;
+
+    SourceLocation Loc;    
+  public:
+    OverloadCandidateSet(SourceLocation Loc) : Loc(Loc) {}
+
+    SourceLocation getLocation() const { return Loc; }
+
+    /// \brief Determine when this overload candidate will be new to the
+    /// overload set.
+    bool isNewCandidate(Decl *F) { 
+      return Functions.insert(F->getCanonicalDecl()); 
+    }
+
+    /// \brief Clear out all of the candidates.
+    void clear() {
+      inherited::clear();
+      Functions.clear();
+    }
+  };
+} // end namespace clang
+
+#endif // LLVM_CLANG_SEMA_OVERLOAD_H
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
new file mode 100644
index 0000000..9d6132d
--- /dev/null
+++ b/lib/Sema/SemaStmt.cpp
@@ -0,0 +1,1708 @@
+//===--- SemaStmt.cpp - Semantic Analysis for Statements ------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements semantic analysis for statements.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Sema.h"
+#include "SemaInit.h"
+#include "clang/AST/APValue.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/ExprObjC.h"
+#include "clang/AST/StmtObjC.h"
+#include "clang/AST/StmtCXX.h"
+#include "clang/AST/TypeLoc.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Basic/TargetInfo.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
+using namespace clang;
+
+Sema::OwningStmtResult Sema::ActOnExprStmt(FullExprArg expr) {
+  Expr *E = expr->takeAs<Expr>();
+  assert(E && "ActOnExprStmt(): missing expression");
+  if (E->getType()->isObjCInterfaceType()) {
+    if (LangOpts.ObjCNonFragileABI)
+      Diag(E->getLocEnd(), diag::err_indirection_requires_nonfragile_object)
+             << E->getType();
+    else
+      Diag(E->getLocEnd(), diag::err_direct_interface_unsupported)
+             << E->getType();
+    return StmtError();
+  }
+  // C99 6.8.3p2: The expression in an expression statement is evaluated as a
+  // void expression for its side effects.  Conversion to void allows any
+  // operand, even incomplete types.
+
+  // Same thing in for stmt first clause (when expr) and third clause.
+  return Owned(static_cast<Stmt*>(E));
+}
+
+
+Sema::OwningStmtResult Sema::ActOnNullStmt(SourceLocation SemiLoc) {
+  return Owned(new (Context) NullStmt(SemiLoc));
+}
+
+Sema::OwningStmtResult Sema::ActOnDeclStmt(DeclGroupPtrTy dg,
+                                           SourceLocation StartLoc,
+                                           SourceLocation EndLoc) {
+  DeclGroupRef DG = dg.getAsVal<DeclGroupRef>();
+
+  // If we have an invalid decl, just return an error.
+  if (DG.isNull()) return StmtError();
+
+  return Owned(new (Context) DeclStmt(DG, StartLoc, EndLoc));
+}
+
+void Sema::ActOnForEachDeclStmt(DeclGroupPtrTy dg) {
+  DeclGroupRef DG = dg.getAsVal<DeclGroupRef>();
+  
+  // If we have an invalid decl, just return.
+  if (DG.isNull() || !DG.isSingleDecl()) return;
+  // suppress any potential 'unused variable' warning.
+  DG.getSingleDecl()->setUsed();
+}
+
+void Sema::DiagnoseUnusedExprResult(const Stmt *S) {
+  const Expr *E = dyn_cast_or_null<Expr>(S);
+  if (!E)
+    return;
+
+  SourceLocation Loc;
+  SourceRange R1, R2;
+  if (!E->isUnusedResultAWarning(Loc, R1, R2, Context))
+    return;
+
+  // Okay, we have an unused result.  Depending on what the base expression is,
+  // we might want to make a more specific diagnostic.  Check for one of these
+  // cases now.
+  unsigned DiagID = diag::warn_unused_expr;
+  E = E->IgnoreParens();
+  if (isa<ObjCImplicitSetterGetterRefExpr>(E))
+    DiagID = diag::warn_unused_property_expr;
+  
+  if (const CXXExprWithTemporaries *Temps = dyn_cast<CXXExprWithTemporaries>(E))
+    E = Temps->getSubExpr();
+  if (const CXXZeroInitValueExpr *Zero = dyn_cast<CXXZeroInitValueExpr>(E)) {
+    if (const RecordType *RecordT = Zero->getType()->getAs<RecordType>())
+      if (CXXRecordDecl *RecordD = dyn_cast<CXXRecordDecl>(RecordT->getDecl()))
+        if (!RecordD->hasTrivialDestructor())
+          return;
+  }
+      
+  if (const CallExpr *CE = dyn_cast<CallExpr>(E)) {
+    if (E->getType()->isVoidType())
+      return;
+
+    // If the callee has attribute pure, const, or warn_unused_result, warn with
+    // a more specific message to make it clear what is happening.
+    if (const Decl *FD = CE->getCalleeDecl()) {
+      if (FD->getAttr<WarnUnusedResultAttr>()) {
+        Diag(Loc, diag::warn_unused_call) << R1 << R2 << "warn_unused_result";
+        return;
+      }
+      if (FD->getAttr<PureAttr>()) {
+        Diag(Loc, diag::warn_unused_call) << R1 << R2 << "pure";
+        return;
+      }
+      if (FD->getAttr<ConstAttr>()) {
+        Diag(Loc, diag::warn_unused_call) << R1 << R2 << "const";
+        return;
+      }
+    }        
+  }
+  else if (const ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(E)) {
+    const ObjCMethodDecl *MD = ME->getMethodDecl();
+    if (MD && MD->getAttr<WarnUnusedResultAttr>()) {
+      Diag(Loc, diag::warn_unused_call) << R1 << R2 << "warn_unused_result";
+      return;
+    }
+  } else if (const CXXFunctionalCastExpr *FC
+                                       = dyn_cast<CXXFunctionalCastExpr>(E)) {
+    if (isa<CXXConstructExpr>(FC->getSubExpr()) ||
+        isa<CXXTemporaryObjectExpr>(FC->getSubExpr()))
+      return;
+  }
+  // Diagnose "(void*) blah" as a typo for "(void) blah".
+  else if (const CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(E)) {
+    TypeSourceInfo *TI = CE->getTypeInfoAsWritten();
+    QualType T = TI->getType();
+
+    // We really do want to use the non-canonical type here.
+    if (T == Context.VoidPtrTy) {
+      PointerTypeLoc TL = cast<PointerTypeLoc>(TI->getTypeLoc());
+
+      Diag(Loc, diag::warn_unused_voidptr)
+        << FixItHint::CreateRemoval(TL.getStarLoc());
+      return;
+    }
+  }
+
+  Diag(Loc, DiagID) << R1 << R2;
+}
+
+Action::OwningStmtResult
+Sema::ActOnCompoundStmt(SourceLocation L, SourceLocation R,
+                        MultiStmtArg elts, bool isStmtExpr) {
+  unsigned NumElts = elts.size();
+  Stmt **Elts = reinterpret_cast<Stmt**>(elts.release());
+  // If we're in C89 mode, check that we don't have any decls after stmts.  If
+  // so, emit an extension diagnostic.
+  if (!getLangOptions().C99 && !getLangOptions().CPlusPlus) {
+    // Note that __extension__ can be around a decl.
+    unsigned i = 0;
+    // Skip over all declarations.
+    for (; i != NumElts && isa<DeclStmt>(Elts[i]); ++i)
+      /*empty*/;
+
+    // We found the end of the list or a statement.  Scan for another declstmt.
+    for (; i != NumElts && !isa<DeclStmt>(Elts[i]); ++i)
+      /*empty*/;
+
+    if (i != NumElts) {
+      Decl *D = *cast<DeclStmt>(Elts[i])->decl_begin();
+      Diag(D->getLocation(), diag::ext_mixed_decls_code);
+    }
+  }
+  // Warn about unused expressions in statements.
+  for (unsigned i = 0; i != NumElts; ++i) {
+    // Ignore statements that are last in a statement expression.
+    if (isStmtExpr && i == NumElts - 1)
+      continue;
+
+    DiagnoseUnusedExprResult(Elts[i]);
+  }
+
+  return Owned(new (Context) CompoundStmt(Context, Elts, NumElts, L, R));
+}
+
+Action::OwningStmtResult
+Sema::ActOnCaseStmt(SourceLocation CaseLoc, ExprArg lhsval,
+                    SourceLocation DotDotDotLoc, ExprArg rhsval,
+                    SourceLocation ColonLoc) {
+  assert((lhsval.get() != 0) && "missing expression in case statement");
+
+  // C99 6.8.4.2p3: The expression shall be an integer constant.
+  // However, GCC allows any evaluatable integer expression.
+  Expr *LHSVal = static_cast<Expr*>(lhsval.get());
+  if (!LHSVal->isTypeDependent() && !LHSVal->isValueDependent() &&
+      VerifyIntegerConstantExpression(LHSVal))
+    return StmtError();
+
+  // GCC extension: The expression shall be an integer constant.
+
+  Expr *RHSVal = static_cast<Expr*>(rhsval.get());
+  if (RHSVal && !RHSVal->isTypeDependent() && !RHSVal->isValueDependent() &&
+      VerifyIntegerConstantExpression(RHSVal)) {
+    RHSVal = 0;  // Recover by just forgetting about it.
+    rhsval = 0;
+  }
+
+  if (getSwitchStack().empty()) {
+    Diag(CaseLoc, diag::err_case_not_in_switch);
+    return StmtError();
+  }
+
+  // Only now release the smart pointers.
+  lhsval.release();
+  rhsval.release();
+  CaseStmt *CS = new (Context) CaseStmt(LHSVal, RHSVal, CaseLoc, DotDotDotLoc,
+                                        ColonLoc);
+  getSwitchStack().back()->addSwitchCase(CS);
+  return Owned(CS);
+}
+
+/// ActOnCaseStmtBody - This installs a statement as the body of a case.
+void Sema::ActOnCaseStmtBody(StmtTy *caseStmt, StmtArg subStmt) {
+  CaseStmt *CS = static_cast<CaseStmt*>(caseStmt);
+  Stmt *SubStmt = subStmt.takeAs<Stmt>();
+  CS->setSubStmt(SubStmt);
+}
+
+Action::OwningStmtResult
+Sema::ActOnDefaultStmt(SourceLocation DefaultLoc, SourceLocation ColonLoc,
+                       StmtArg subStmt, Scope *CurScope) {
+  Stmt *SubStmt = subStmt.takeAs<Stmt>();
+
+  if (getSwitchStack().empty()) {
+    Diag(DefaultLoc, diag::err_default_not_in_switch);
+    return Owned(SubStmt);
+  }
+
+  DefaultStmt *DS = new (Context) DefaultStmt(DefaultLoc, ColonLoc, SubStmt);
+  getSwitchStack().back()->addSwitchCase(DS);
+  return Owned(DS);
+}
+
+Action::OwningStmtResult
+Sema::ActOnLabelStmt(SourceLocation IdentLoc, IdentifierInfo *II,
+                     SourceLocation ColonLoc, StmtArg subStmt) {
+  Stmt *SubStmt = subStmt.takeAs<Stmt>();
+  // Look up the record for this label identifier.
+  LabelStmt *&LabelDecl = getLabelMap()[II];
+
+  // If not forward referenced or defined already, just create a new LabelStmt.
+  if (LabelDecl == 0)
+    return Owned(LabelDecl = new (Context) LabelStmt(IdentLoc, II, SubStmt));
+
+  assert(LabelDecl->getID() == II && "Label mismatch!");
+
+  // Otherwise, this label was either forward reference or multiply defined.  If
+  // multiply defined, reject it now.
+  if (LabelDecl->getSubStmt()) {
+    Diag(IdentLoc, diag::err_redefinition_of_label) << LabelDecl->getID();
+    Diag(LabelDecl->getIdentLoc(), diag::note_previous_definition);
+    return Owned(SubStmt);
+  }
+
+  // Otherwise, this label was forward declared, and we just found its real
+  // definition.  Fill in the forward definition and return it.
+  LabelDecl->setIdentLoc(IdentLoc);
+  LabelDecl->setSubStmt(SubStmt);
+  return Owned(LabelDecl);
+}
+
+Action::OwningStmtResult
+Sema::ActOnIfStmt(SourceLocation IfLoc, FullExprArg CondVal, DeclPtrTy CondVar,
+                  StmtArg ThenVal, SourceLocation ElseLoc,
+                  StmtArg ElseVal) {
+  OwningExprResult CondResult(CondVal.release());
+
+  VarDecl *ConditionVar = 0;
+  if (CondVar.get()) {
+    ConditionVar = CondVar.getAs<VarDecl>();
+    CondResult = CheckConditionVariable(ConditionVar);
+    if (CondResult.isInvalid())
+      return StmtError();
+  }
+  Expr *ConditionExpr = CondResult.takeAs<Expr>();
+  if (!ConditionExpr)
+    return StmtError();
+  
+  if (CheckBooleanCondition(ConditionExpr, IfLoc)) {
+    CondResult = ConditionExpr;
+    return StmtError();
+  }
+
+  Stmt *thenStmt = ThenVal.takeAs<Stmt>();
+  DiagnoseUnusedExprResult(thenStmt);
+
+  // Warn if the if block has a null body without an else value.
+  // this helps prevent bugs due to typos, such as
+  // if (condition);
+  //   do_stuff();
+  if (!ElseVal.get()) {
+    if (NullStmt* stmt = dyn_cast<NullStmt>(thenStmt))
+      Diag(stmt->getSemiLoc(), diag::warn_empty_if_body);
+  }
+
+  Stmt *elseStmt = ElseVal.takeAs<Stmt>();
+  DiagnoseUnusedExprResult(elseStmt);
+
+  CondResult.release();
+  return Owned(new (Context) IfStmt(IfLoc, ConditionVar, ConditionExpr, 
+                                    thenStmt, ElseLoc, elseStmt));
+}
+
+Action::OwningStmtResult
+Sema::ActOnStartOfSwitchStmt(FullExprArg cond, DeclPtrTy CondVar) {
+  OwningExprResult CondResult(cond.release());
+  
+  VarDecl *ConditionVar = 0;
+  if (CondVar.get()) {
+    ConditionVar = CondVar.getAs<VarDecl>();
+    CondResult = CheckConditionVariable(ConditionVar);
+    if (CondResult.isInvalid())
+      return StmtError();
+  }
+  SwitchStmt *SS = new (Context) SwitchStmt(ConditionVar, 
+                                            CondResult.takeAs<Expr>());
+  getSwitchStack().push_back(SS);
+  return Owned(SS);
+}
+
+/// ConvertIntegerToTypeWarnOnOverflow - Convert the specified APInt to have
+/// the specified width and sign.  If an overflow occurs, detect it and emit
+/// the specified diagnostic.
+void Sema::ConvertIntegerToTypeWarnOnOverflow(llvm::APSInt &Val,
+                                              unsigned NewWidth, bool NewSign,
+                                              SourceLocation Loc,
+                                              unsigned DiagID) {
+  // Perform a conversion to the promoted condition type if needed.
+  if (NewWidth > Val.getBitWidth()) {
+    // If this is an extension, just do it.
+    Val.extend(NewWidth);
+    Val.setIsSigned(NewSign);
+
+    // If the input was signed and negative and the output is
+    // unsigned, don't bother to warn: this is implementation-defined
+    // behavior.
+    // FIXME: Introduce a second, default-ignored warning for this case?
+  } else if (NewWidth < Val.getBitWidth()) {
+    // If this is a truncation, check for overflow.
+    llvm::APSInt ConvVal(Val);
+    ConvVal.trunc(NewWidth);
+    ConvVal.setIsSigned(NewSign);
+    ConvVal.extend(Val.getBitWidth());
+    ConvVal.setIsSigned(Val.isSigned());
+    if (ConvVal != Val)
+      Diag(Loc, DiagID) << Val.toString(10) << ConvVal.toString(10);
+
+    // Regardless of whether a diagnostic was emitted, really do the
+    // truncation.
+    Val.trunc(NewWidth);
+    Val.setIsSigned(NewSign);
+  } else if (NewSign != Val.isSigned()) {
+    // Convert the sign to match the sign of the condition.  This can cause
+    // overflow as well: unsigned(INTMIN)
+    // We don't diagnose this overflow, because it is implementation-defined 
+    // behavior.
+    // FIXME: Introduce a second, default-ignored warning for this case?
+    llvm::APSInt OldVal(Val);
+    Val.setIsSigned(NewSign);
+  }
+}
+
+namespace {
+  struct CaseCompareFunctor {
+    bool operator()(const std::pair<llvm::APSInt, CaseStmt*> &LHS,
+                    const llvm::APSInt &RHS) {
+      return LHS.first < RHS;
+    }
+    bool operator()(const std::pair<llvm::APSInt, CaseStmt*> &LHS,
+                    const std::pair<llvm::APSInt, CaseStmt*> &RHS) {
+      return LHS.first < RHS.first;
+    }
+    bool operator()(const llvm::APSInt &LHS,
+                    const std::pair<llvm::APSInt, CaseStmt*> &RHS) {
+      return LHS < RHS.first;
+    }
+  };
+}
+
+/// CmpCaseVals - Comparison predicate for sorting case values.
+///
+static bool CmpCaseVals(const std::pair<llvm::APSInt, CaseStmt*>& lhs,
+                        const std::pair<llvm::APSInt, CaseStmt*>& rhs) {
+  if (lhs.first < rhs.first)
+    return true;
+
+  if (lhs.first == rhs.first &&
+      lhs.second->getCaseLoc().getRawEncoding()
+       < rhs.second->getCaseLoc().getRawEncoding())
+    return true;
+  return false;
+}
+
+/// CmpEnumVals - Comparison predicate for sorting enumeration values.
+///
+static bool CmpEnumVals(const std::pair<llvm::APSInt, EnumConstantDecl*>& lhs,
+                        const std::pair<llvm::APSInt, EnumConstantDecl*>& rhs)
+{
+  return lhs.first < rhs.first;
+}
+
+/// EqEnumVals - Comparison preficate for uniqing enumeration values.
+///
+static bool EqEnumVals(const std::pair<llvm::APSInt, EnumConstantDecl*>& lhs,
+                       const std::pair<llvm::APSInt, EnumConstantDecl*>& rhs)
+{
+  return lhs.first == rhs.first;
+}
+
+/// GetTypeBeforeIntegralPromotion - Returns the pre-promotion type of
+/// potentially integral-promoted expression @p expr.
+static QualType GetTypeBeforeIntegralPromotion(const Expr* expr) {
+  const ImplicitCastExpr *ImplicitCast =
+      dyn_cast_or_null<ImplicitCastExpr>(expr);
+  if (ImplicitCast != NULL) {
+    const Expr *ExprBeforePromotion = ImplicitCast->getSubExpr();
+    QualType TypeBeforePromotion = ExprBeforePromotion->getType();
+    if (TypeBeforePromotion->isIntegralType()) {
+      return TypeBeforePromotion;
+    }
+  }
+  return expr->getType();
+}
+
+/// \brief Check (and possibly convert) the condition in a switch
+/// statement in C++.
+static bool CheckCXXSwitchCondition(Sema &S, SourceLocation SwitchLoc,
+                                    Expr *&CondExpr) {
+  if (CondExpr->isTypeDependent())
+    return false;
+
+  QualType CondType = CondExpr->getType();
+
+  // C++ 6.4.2.p2:
+  // The condition shall be of integral type, enumeration type, or of a class
+  // type for which a single conversion function to integral or enumeration
+  // type exists (12.3). If the condition is of class type, the condition is
+  // converted by calling that conversion function, and the result of the
+  // conversion is used in place of the original condition for the remainder
+  // of this section. Integral promotions are performed.
+
+  // Make sure that the condition expression has a complete type,
+  // otherwise we'll never find any conversions.
+  if (S.RequireCompleteType(SwitchLoc, CondType,
+                            S.PDiag(diag::err_switch_incomplete_class_type)
+                              << CondExpr->getSourceRange()))
+    return true;
+
+  UnresolvedSet<4> ViableConversions;
+  UnresolvedSet<4> ExplicitConversions;
+  if (const RecordType *RecordTy = CondType->getAs<RecordType>()) {
+    const UnresolvedSetImpl *Conversions
+      = cast<CXXRecordDecl>(RecordTy->getDecl())
+                                             ->getVisibleConversionFunctions();
+    for (UnresolvedSetImpl::iterator I = Conversions->begin(),
+           E = Conversions->end(); I != E; ++I) {
+      if (CXXConversionDecl *Conversion
+            = dyn_cast<CXXConversionDecl>((*I)->getUnderlyingDecl()))
+        if (Conversion->getConversionType().getNonReferenceType()
+              ->isIntegralType()) {
+          if (Conversion->isExplicit())
+            ExplicitConversions.addDecl(I.getDecl(), I.getAccess());
+          else
+            ViableConversions.addDecl(I.getDecl(), I.getAccess());
+        }
+    }
+
+    switch (ViableConversions.size()) {
+    case 0:
+      if (ExplicitConversions.size() == 1) {
+        DeclAccessPair Found = ExplicitConversions[0];
+        CXXConversionDecl *Conversion =
+          cast<CXXConversionDecl>(Found->getUnderlyingDecl());
+        // The user probably meant to invoke the given explicit
+        // conversion; use it.
+        QualType ConvTy
+          = Conversion->getConversionType().getNonReferenceType();
+        std::string TypeStr;
+        ConvTy.getAsStringInternal(TypeStr, S.Context.PrintingPolicy);
+
+        S.Diag(SwitchLoc, diag::err_switch_explicit_conversion)
+          << CondType << ConvTy << CondExpr->getSourceRange()
+          << FixItHint::CreateInsertion(CondExpr->getLocStart(),
+                                        "static_cast<" + TypeStr + ">(")
+          << FixItHint::CreateInsertion(
+                            S.PP.getLocForEndOfToken(CondExpr->getLocEnd()),
+                               ")");
+        S.Diag(Conversion->getLocation(), diag::note_switch_conversion)
+          << ConvTy->isEnumeralType() << ConvTy;
+
+        // If we aren't in a SFINAE context, build a call to the 
+        // explicit conversion function.
+        if (S.isSFINAEContext())
+          return true;
+
+        S.CheckMemberOperatorAccess(CondExpr->getExprLoc(),
+                                    CondExpr, 0, Found);
+        CondExpr = S.BuildCXXMemberCallExpr(CondExpr, Found, Conversion);
+      }
+
+      // We'll complain below about a non-integral condition type.
+      break;
+
+    case 1: {
+      // Apply this conversion.
+      DeclAccessPair Found = ViableConversions[0];
+      S.CheckMemberOperatorAccess(CondExpr->getExprLoc(),
+                                  CondExpr, 0, Found);
+      CondExpr = S.BuildCXXMemberCallExpr(CondExpr, Found,
+                        cast<CXXConversionDecl>(Found->getUnderlyingDecl()));
+      break;
+    }
+
+    default:
+      S.Diag(SwitchLoc, diag::err_switch_multiple_conversions)
+        << CondType << CondExpr->getSourceRange();
+      for (unsigned I = 0, N = ViableConversions.size(); I != N; ++I) {
+        CXXConversionDecl *Conv
+          = cast<CXXConversionDecl>(ViableConversions[I]->getUnderlyingDecl());
+        QualType ConvTy = Conv->getConversionType().getNonReferenceType();
+        S.Diag(Conv->getLocation(), diag::note_switch_conversion)
+          << ConvTy->isEnumeralType() << ConvTy;
+      }
+      return true;
+    }
+  } 
+
+  return false;
+}
+
+/// ActOnSwitchBodyError - This is called if there is an error parsing the
+/// body of the switch stmt instead of ActOnFinishSwitchStmt.
+void Sema::ActOnSwitchBodyError(SourceLocation SwitchLoc, StmtArg Switch,
+                                StmtArg Body) {
+  // Keep the switch stack balanced.
+  assert(getSwitchStack().back() == (SwitchStmt*)Switch.get() &&
+         "switch stack missing push/pop!");
+  getSwitchStack().pop_back();
+}
+
+Action::OwningStmtResult
+Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, StmtArg Switch,
+                            StmtArg Body) {
+  Stmt *BodyStmt = Body.takeAs<Stmt>();
+
+  SwitchStmt *SS = getSwitchStack().back();
+  assert(SS == (SwitchStmt*)Switch.get() && "switch stack missing push/pop!");
+
+  SS->setBody(BodyStmt, SwitchLoc);
+  getSwitchStack().pop_back();
+
+  if (SS->getCond() == 0) {
+    SS->Destroy(Context);
+    return StmtError();
+  }
+    
+  Expr *CondExpr = SS->getCond();
+  QualType CondTypeBeforePromotion =
+      GetTypeBeforeIntegralPromotion(CondExpr);
+
+  if (getLangOptions().CPlusPlus &&
+      CheckCXXSwitchCondition(*this, SwitchLoc, CondExpr))
+    return StmtError();
+
+  // C99 6.8.4.2p5 - Integer promotions are performed on the controlling expr.
+  UsualUnaryConversions(CondExpr);
+  QualType CondType = CondExpr->getType();
+  SS->setCond(CondExpr);
+
+  // C++ 6.4.2.p2:
+  // Integral promotions are performed (on the switch condition).
+  //
+  // A case value unrepresentable by the original switch condition
+  // type (before the promotion) doesn't make sense, even when it can
+  // be represented by the promoted type.  Therefore we need to find
+  // the pre-promotion type of the switch condition.
+  if (!CondExpr->isTypeDependent()) {
+    if (!CondType->isIntegerType()) { // C99 6.8.4.2p1
+      Diag(SwitchLoc, diag::err_typecheck_statement_requires_integer)
+          << CondType << CondExpr->getSourceRange();
+      return StmtError();
+    }
+
+    if (CondExpr->isKnownToHaveBooleanValue()) {
+      // switch(bool_expr) {...} is often a programmer error, e.g.
+      //   switch(n && mask) { ... }  // Doh - should be "n & mask".
+      // One can always use an if statement instead of switch(bool_expr).
+      Diag(SwitchLoc, diag::warn_bool_switch_condition)
+          << CondExpr->getSourceRange();
+    }
+  }
+
+  // Get the bitwidth of the switched-on value before promotions.  We must
+  // convert the integer case values to this width before comparison.
+  bool HasDependentValue
+    = CondExpr->isTypeDependent() || CondExpr->isValueDependent();
+  unsigned CondWidth
+    = HasDependentValue? 0
+      : static_cast<unsigned>(Context.getTypeSize(CondTypeBeforePromotion));
+  bool CondIsSigned = CondTypeBeforePromotion->isSignedIntegerType();
+
+  // Accumulate all of the case values in a vector so that we can sort them
+  // and detect duplicates.  This vector contains the APInt for the case after
+  // it has been converted to the condition type.
+  typedef llvm::SmallVector<std::pair<llvm::APSInt, CaseStmt*>, 64> CaseValsTy;
+  CaseValsTy CaseVals;
+
+  // Keep track of any GNU case ranges we see.  The APSInt is the low value.
+  typedef std::vector<std::pair<llvm::APSInt, CaseStmt*> > CaseRangesTy;
+  CaseRangesTy CaseRanges;
+
+  DefaultStmt *TheDefaultStmt = 0;
+
+  bool CaseListIsErroneous = false;
+
+  for (SwitchCase *SC = SS->getSwitchCaseList(); SC && !HasDependentValue;
+       SC = SC->getNextSwitchCase()) {
+
+    if (DefaultStmt *DS = dyn_cast<DefaultStmt>(SC)) {
+      if (TheDefaultStmt) {
+        Diag(DS->getDefaultLoc(), diag::err_multiple_default_labels_defined);
+        Diag(TheDefaultStmt->getDefaultLoc(), diag::note_duplicate_case_prev);
+
+        // FIXME: Remove the default statement from the switch block so that
+        // we'll return a valid AST.  This requires recursing down the AST and
+        // finding it, not something we are set up to do right now.  For now,
+        // just lop the entire switch stmt out of the AST.
+        CaseListIsErroneous = true;
+      }
+      TheDefaultStmt = DS;
+
+    } else {
+      CaseStmt *CS = cast<CaseStmt>(SC);
+
+      // We already verified that the expression has a i-c-e value (C99
+      // 6.8.4.2p3) - get that value now.
+      Expr *Lo = CS->getLHS();
+
+      if (Lo->isTypeDependent() || Lo->isValueDependent()) {
+        HasDependentValue = true;
+        break;
+      }
+
+      llvm::APSInt LoVal = Lo->EvaluateAsInt(Context);
+
+      // Convert the value to the same width/sign as the condition.
+      ConvertIntegerToTypeWarnOnOverflow(LoVal, CondWidth, CondIsSigned,
+                                         CS->getLHS()->getLocStart(),
+                                         diag::warn_case_value_overflow);
+
+      // If the LHS is not the same type as the condition, insert an implicit
+      // cast.
+      ImpCastExprToType(Lo, CondType, CastExpr::CK_IntegralCast);
+      CS->setLHS(Lo);
+
+      // If this is a case range, remember it in CaseRanges, otherwise CaseVals.
+      if (CS->getRHS()) {
+        if (CS->getRHS()->isTypeDependent() ||
+            CS->getRHS()->isValueDependent()) {
+          HasDependentValue = true;
+          break;
+        }
+        CaseRanges.push_back(std::make_pair(LoVal, CS));
+      } else
+        CaseVals.push_back(std::make_pair(LoVal, CS));
+    }
+  }
+
+  if (!HasDependentValue) {
+    // Sort all the scalar case values so we can easily detect duplicates.
+    std::stable_sort(CaseVals.begin(), CaseVals.end(), CmpCaseVals);
+
+    if (!CaseVals.empty()) {
+      for (unsigned i = 0, e = CaseVals.size()-1; i != e; ++i) {
+        if (CaseVals[i].first == CaseVals[i+1].first) {
+          // If we have a duplicate, report it.
+          Diag(CaseVals[i+1].second->getLHS()->getLocStart(),
+               diag::err_duplicate_case) << CaseVals[i].first.toString(10);
+          Diag(CaseVals[i].second->getLHS()->getLocStart(),
+               diag::note_duplicate_case_prev);
+          // FIXME: We really want to remove the bogus case stmt from the
+          // substmt, but we have no way to do this right now.
+          CaseListIsErroneous = true;
+        }
+      }
+    }
+
+    // Detect duplicate case ranges, which usually don't exist at all in
+    // the first place.
+    if (!CaseRanges.empty()) {
+      // Sort all the case ranges by their low value so we can easily detect
+      // overlaps between ranges.
+      std::stable_sort(CaseRanges.begin(), CaseRanges.end());
+
+      // Scan the ranges, computing the high values and removing empty ranges.
+      std::vector<llvm::APSInt> HiVals;
+      for (unsigned i = 0, e = CaseRanges.size(); i != e; ++i) {
+        CaseStmt *CR = CaseRanges[i].second;
+        Expr *Hi = CR->getRHS();
+        llvm::APSInt HiVal = Hi->EvaluateAsInt(Context);
+
+        // Convert the value to the same width/sign as the condition.
+        ConvertIntegerToTypeWarnOnOverflow(HiVal, CondWidth, CondIsSigned,
+                                           CR->getRHS()->getLocStart(),
+                                           diag::warn_case_value_overflow);
+
+        // If the LHS is not the same type as the condition, insert an implicit
+        // cast.
+        ImpCastExprToType(Hi, CondType, CastExpr::CK_IntegralCast);
+        CR->setRHS(Hi);
+
+        // If the low value is bigger than the high value, the case is empty.
+        if (CaseRanges[i].first > HiVal) {
+          Diag(CR->getLHS()->getLocStart(), diag::warn_case_empty_range)
+            << SourceRange(CR->getLHS()->getLocStart(),
+                           CR->getRHS()->getLocEnd());
+          CaseRanges.erase(CaseRanges.begin()+i);
+          --i, --e;
+          continue;
+        }
+        HiVals.push_back(HiVal);
+      }
+
+      // Rescan the ranges, looking for overlap with singleton values and other
+      // ranges.  Since the range list is sorted, we only need to compare case
+      // ranges with their neighbors.
+      for (unsigned i = 0, e = CaseRanges.size(); i != e; ++i) {
+        llvm::APSInt &CRLo = CaseRanges[i].first;
+        llvm::APSInt &CRHi = HiVals[i];
+        CaseStmt *CR = CaseRanges[i].second;
+
+        // Check to see whether the case range overlaps with any
+        // singleton cases.
+        CaseStmt *OverlapStmt = 0;
+        llvm::APSInt OverlapVal(32);
+
+        // Find the smallest value >= the lower bound.  If I is in the
+        // case range, then we have overlap.
+        CaseValsTy::iterator I = std::lower_bound(CaseVals.begin(),
+                                                  CaseVals.end(), CRLo,
+                                                  CaseCompareFunctor());
+        if (I != CaseVals.end() && I->first < CRHi) {
+          OverlapVal  = I->first;   // Found overlap with scalar.
+          OverlapStmt = I->second;
+        }
+
+        // Find the smallest value bigger than the upper bound.
+        I = std::upper_bound(I, CaseVals.end(), CRHi, CaseCompareFunctor());
+        if (I != CaseVals.begin() && (I-1)->first >= CRLo) {
+          OverlapVal  = (I-1)->first;      // Found overlap with scalar.
+          OverlapStmt = (I-1)->second;
+        }
+
+        // Check to see if this case stmt overlaps with the subsequent
+        // case range.
+        if (i && CRLo <= HiVals[i-1]) {
+          OverlapVal  = HiVals[i-1];       // Found overlap with range.
+          OverlapStmt = CaseRanges[i-1].second;
+        }
+
+        if (OverlapStmt) {
+          // If we have a duplicate, report it.
+          Diag(CR->getLHS()->getLocStart(), diag::err_duplicate_case)
+            << OverlapVal.toString(10);
+          Diag(OverlapStmt->getLHS()->getLocStart(),
+               diag::note_duplicate_case_prev);
+          // FIXME: We really want to remove the bogus case stmt from the
+          // substmt, but we have no way to do this right now.
+          CaseListIsErroneous = true;
+        }
+      }
+    }
+
+    // Check to see if switch is over an Enum and handles all of its 
+    // values  
+    const EnumType* ET = CondTypeBeforePromotion->getAs<EnumType>();
+    // If switch has default case, then ignore it.
+    if (!CaseListIsErroneous && !TheDefaultStmt && ET) {
+      const EnumDecl *ED = ET->getDecl();
+      typedef llvm::SmallVector<std::pair<llvm::APSInt, EnumConstantDecl*>, 64> EnumValsTy;
+      EnumValsTy EnumVals;
+
+      // Gather all enum values, set their type and sort them, allowing easier comparison 
+      // with CaseVals.
+      for (EnumDecl::enumerator_iterator EDI = ED->enumerator_begin(); EDI != ED->enumerator_end(); EDI++) {
+        llvm::APSInt Val = (*EDI)->getInitVal();
+        if(Val.getBitWidth() < CondWidth)
+          Val.extend(CondWidth);
+        Val.setIsSigned(CondIsSigned);
+        EnumVals.push_back(std::make_pair(Val, (*EDI)));
+      }
+      std::stable_sort(EnumVals.begin(), EnumVals.end(), CmpEnumVals);
+      EnumValsTy::iterator EIend = std::unique(EnumVals.begin(), EnumVals.end(), EqEnumVals);
+      // See which case values aren't in enum 
+      EnumValsTy::const_iterator EI = EnumVals.begin();
+      for (CaseValsTy::const_iterator CI = CaseVals.begin(); CI != CaseVals.end(); CI++) {
+        while (EI != EIend && EI->first < CI->first)
+          EI++;
+        if (EI == EIend || EI->first > CI->first)
+            Diag(CI->second->getLHS()->getExprLoc(), diag::not_in_enum) << ED->getDeclName();
+      }
+      // See which of case ranges aren't in enum
+      EI = EnumVals.begin();
+      for (CaseRangesTy::const_iterator RI = CaseRanges.begin(); RI != CaseRanges.end() && EI != EIend; RI++) {
+        while (EI != EIend && EI->first < RI->first)
+          EI++;
+        
+        if (EI == EIend || EI->first != RI->first) {
+          Diag(RI->second->getLHS()->getExprLoc(), diag::not_in_enum) << ED->getDeclName();
+        }
+
+        llvm::APSInt Hi = RI->second->getRHS()->EvaluateAsInt(Context);
+        while (EI != EIend && EI->first < Hi)
+          EI++;
+        if (EI == EIend || EI->first != Hi)
+          Diag(RI->second->getRHS()->getExprLoc(), diag::not_in_enum) << ED->getDeclName();
+      }
+      //Check which enum vals aren't in switch
+      CaseValsTy::const_iterator CI = CaseVals.begin();
+      CaseRangesTy::const_iterator RI = CaseRanges.begin();
+      EI = EnumVals.begin();
+      for (; EI != EIend; EI++) {
+        //Drop unneeded case values
+        llvm::APSInt CIVal;
+        while (CI != CaseVals.end() && CI->first < EI->first)
+          CI++;
+        
+        if (CI != CaseVals.end() && CI->first == EI->first)
+          continue;
+
+        //Drop unneeded case ranges
+        for (; RI != CaseRanges.end(); RI++) {
+          llvm::APSInt Hi = RI->second->getRHS()->EvaluateAsInt(Context);
+          if (EI->first <= Hi)
+            break;
+        }
+
+        if (RI == CaseRanges.end() || EI->first < RI->first)
+          Diag(CondExpr->getExprLoc(), diag::warn_missing_cases) << EI->second->getDeclName();
+      }
+    }
+  }
+
+  // FIXME: If the case list was broken is some way, we don't have a good system
+  // to patch it up.  Instead, just return the whole substmt as broken.
+  if (CaseListIsErroneous)
+    return StmtError();
+
+  Switch.release();
+  return Owned(SS);
+}
+
+Action::OwningStmtResult
+Sema::ActOnWhileStmt(SourceLocation WhileLoc, FullExprArg Cond, 
+                     DeclPtrTy CondVar, StmtArg Body) {
+  OwningExprResult CondResult(Cond.release());
+  
+  VarDecl *ConditionVar = 0;
+  if (CondVar.get()) {
+    ConditionVar = CondVar.getAs<VarDecl>();
+    CondResult = CheckConditionVariable(ConditionVar);
+    if (CondResult.isInvalid())
+      return StmtError();
+  }
+  Expr *ConditionExpr = CondResult.takeAs<Expr>();
+  if (!ConditionExpr)
+    return StmtError();
+  
+  if (CheckBooleanCondition(ConditionExpr, WhileLoc)) {
+    CondResult = ConditionExpr;
+    return StmtError();
+  }
+
+  Stmt *bodyStmt = Body.takeAs<Stmt>();
+  DiagnoseUnusedExprResult(bodyStmt);
+
+  CondResult.release();
+  return Owned(new (Context) WhileStmt(ConditionVar, ConditionExpr, bodyStmt, 
+                                       WhileLoc));
+}
+
+Action::OwningStmtResult
+Sema::ActOnDoStmt(SourceLocation DoLoc, StmtArg Body,
+                  SourceLocation WhileLoc, SourceLocation CondLParen,
+                  ExprArg Cond, SourceLocation CondRParen) {
+  Expr *condExpr = Cond.takeAs<Expr>();
+  assert(condExpr && "ActOnDoStmt(): missing expression");
+
+  if (CheckBooleanCondition(condExpr, DoLoc)) {
+    Cond = condExpr;
+    return StmtError();
+  }
+
+  Stmt *bodyStmt = Body.takeAs<Stmt>();
+  DiagnoseUnusedExprResult(bodyStmt);
+
+  Cond.release();
+  return Owned(new (Context) DoStmt(bodyStmt, condExpr, DoLoc,
+                                    WhileLoc, CondRParen));
+}
+
+Action::OwningStmtResult
+Sema::ActOnForStmt(SourceLocation ForLoc, SourceLocation LParenLoc,
+                   StmtArg first, FullExprArg second, DeclPtrTy secondVar,
+                   FullExprArg third,
+                   SourceLocation RParenLoc, StmtArg body) {
+  Stmt *First  = static_cast<Stmt*>(first.get());
+
+  if (!getLangOptions().CPlusPlus) {
+    if (DeclStmt *DS = dyn_cast_or_null<DeclStmt>(First)) {
+      // C99 6.8.5p3: The declaration part of a 'for' statement shall only
+      // declare identifiers for objects having storage class 'auto' or
+      // 'register'.
+      for (DeclStmt::decl_iterator DI=DS->decl_begin(), DE=DS->decl_end();
+           DI!=DE; ++DI) {
+        VarDecl *VD = dyn_cast<VarDecl>(*DI);
+        if (VD && VD->isBlockVarDecl() && !VD->hasLocalStorage())
+          VD = 0;
+        if (VD == 0)
+          Diag((*DI)->getLocation(), diag::err_non_variable_decl_in_for);
+        // FIXME: mark decl erroneous!
+      }
+    }
+  }
+
+  OwningExprResult SecondResult(second.release());
+  VarDecl *ConditionVar = 0;
+  if (secondVar.get()) {
+    ConditionVar = secondVar.getAs<VarDecl>();
+    SecondResult = CheckConditionVariable(ConditionVar);
+    if (SecondResult.isInvalid())
+      return StmtError();
+  }
+  
+  Expr *Second = SecondResult.takeAs<Expr>();
+  if (Second && CheckBooleanCondition(Second, ForLoc)) {
+    SecondResult = Second;
+    return StmtError();
+  }
+
+  Expr *Third  = third.release().takeAs<Expr>();
+  Stmt *Body  = static_cast<Stmt*>(body.get());
+  
+  DiagnoseUnusedExprResult(First);
+  DiagnoseUnusedExprResult(Third);
+  DiagnoseUnusedExprResult(Body);
+
+  first.release();
+  body.release();
+  return Owned(new (Context) ForStmt(First, Second, ConditionVar, Third, Body, 
+                                     ForLoc, LParenLoc, RParenLoc));
+}
+
+Action::OwningStmtResult
+Sema::ActOnObjCForCollectionStmt(SourceLocation ForLoc,
+                                 SourceLocation LParenLoc,
+                                 StmtArg first, ExprArg second,
+                                 SourceLocation RParenLoc, StmtArg body) {
+  Stmt *First  = static_cast<Stmt*>(first.get());
+  Expr *Second = static_cast<Expr*>(second.get());
+  Stmt *Body  = static_cast<Stmt*>(body.get());
+  if (First) {
+    QualType FirstType;
+    if (DeclStmt *DS = dyn_cast<DeclStmt>(First)) {
+      if (!DS->isSingleDecl())
+        return StmtError(Diag((*DS->decl_begin())->getLocation(),
+                         diag::err_toomany_element_decls));
+
+      Decl *D = DS->getSingleDecl();
+      FirstType = cast<ValueDecl>(D)->getType();
+      // C99 6.8.5p3: The declaration part of a 'for' statement shall only
+      // declare identifiers for objects having storage class 'auto' or
+      // 'register'.
+      VarDecl *VD = cast<VarDecl>(D);
+      if (VD->isBlockVarDecl() && !VD->hasLocalStorage())
+        return StmtError(Diag(VD->getLocation(),
+                              diag::err_non_variable_decl_in_for));
+    } else {
+      Expr *FirstE = cast<Expr>(First);
+      if (!FirstE->isTypeDependent() &&
+          FirstE->isLvalue(Context) != Expr::LV_Valid)
+        return StmtError(Diag(First->getLocStart(),
+                   diag::err_selector_element_not_lvalue)
+          << First->getSourceRange());
+
+      FirstType = static_cast<Expr*>(First)->getType();
+    }
+    if (!FirstType->isDependentType() &&
+        !FirstType->isObjCObjectPointerType() &&
+        !FirstType->isBlockPointerType())
+        Diag(ForLoc, diag::err_selector_element_type)
+          << FirstType << First->getSourceRange();
+  }
+  if (Second && !Second->isTypeDependent()) {
+    DefaultFunctionArrayLvalueConversion(Second);
+    QualType SecondType = Second->getType();
+    if (!SecondType->isObjCObjectPointerType())
+      Diag(ForLoc, diag::err_collection_expr_type)
+        << SecondType << Second->getSourceRange();
+  }
+  first.release();
+  second.release();
+  body.release();
+  return Owned(new (Context) ObjCForCollectionStmt(First, Second, Body,
+                                                   ForLoc, RParenLoc));
+}
+
+Action::OwningStmtResult
+Sema::ActOnGotoStmt(SourceLocation GotoLoc, SourceLocation LabelLoc,
+                    IdentifierInfo *LabelII) {
+  // Look up the record for this label identifier.
+  LabelStmt *&LabelDecl = getLabelMap()[LabelII];
+
+  // If we haven't seen this label yet, create a forward reference.
+  if (LabelDecl == 0)
+    LabelDecl = new (Context) LabelStmt(LabelLoc, LabelII, 0);
+
+  return Owned(new (Context) GotoStmt(LabelDecl, GotoLoc, LabelLoc));
+}
+
+Action::OwningStmtResult
+Sema::ActOnIndirectGotoStmt(SourceLocation GotoLoc, SourceLocation StarLoc,
+                            ExprArg DestExp) {
+  // Convert operand to void*
+  Expr* E = DestExp.takeAs<Expr>();
+  if (!E->isTypeDependent()) {
+    QualType ETy = E->getType();
+    QualType DestTy = Context.getPointerType(Context.VoidTy.withConst());
+    AssignConvertType ConvTy =
+      CheckSingleAssignmentConstraints(DestTy, E);
+    if (DiagnoseAssignmentResult(ConvTy, StarLoc, DestTy, ETy, E, AA_Passing))
+      return StmtError();
+  }
+  return Owned(new (Context) IndirectGotoStmt(GotoLoc, StarLoc, E));
+}
+
+Action::OwningStmtResult
+Sema::ActOnContinueStmt(SourceLocation ContinueLoc, Scope *CurScope) {
+  Scope *S = CurScope->getContinueParent();
+  if (!S) {
+    // C99 6.8.6.2p1: A break shall appear only in or as a loop body.
+    return StmtError(Diag(ContinueLoc, diag::err_continue_not_in_loop));
+  }
+
+  return Owned(new (Context) ContinueStmt(ContinueLoc));
+}
+
+Action::OwningStmtResult
+Sema::ActOnBreakStmt(SourceLocation BreakLoc, Scope *CurScope) {
+  Scope *S = CurScope->getBreakParent();
+  if (!S) {
+    // C99 6.8.6.3p1: A break shall appear only in or as a switch/loop body.
+    return StmtError(Diag(BreakLoc, diag::err_break_not_in_loop_or_switch));
+  }
+
+  return Owned(new (Context) BreakStmt(BreakLoc));
+}
+
+/// ActOnBlockReturnStmt - Utility routine to figure out block's return type.
+///
+Action::OwningStmtResult
+Sema::ActOnBlockReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
+  // If this is the first return we've seen in the block, infer the type of
+  // the block from it.
+  BlockScopeInfo *CurBlock = getCurBlock();
+  if (CurBlock->ReturnType.isNull()) {
+    if (RetValExp) {
+      // Don't call UsualUnaryConversions(), since we don't want to do
+      // integer promotions here.
+      DefaultFunctionArrayLvalueConversion(RetValExp);
+      CurBlock->ReturnType = RetValExp->getType();
+      if (BlockDeclRefExpr *CDRE = dyn_cast<BlockDeclRefExpr>(RetValExp)) {
+        // We have to remove a 'const' added to copied-in variable which was
+        // part of the implementation spec. and not the actual qualifier for
+        // the variable.
+        if (CDRE->isConstQualAdded())
+           CurBlock->ReturnType.removeConst();
+      }
+    } else
+      CurBlock->ReturnType = Context.VoidTy;
+  }
+  QualType FnRetType = CurBlock->ReturnType;
+
+  if (CurBlock->TheDecl->hasAttr<NoReturnAttr>()) {
+    Diag(ReturnLoc, diag::err_noreturn_block_has_return_expr)
+      << getCurFunctionOrMethodDecl()->getDeclName();
+    return StmtError();
+  }
+
+  // Otherwise, verify that this result type matches the previous one.  We are
+  // pickier with blocks than for normal functions because we don't have GCC
+  // compatibility to worry about here.
+  if (CurBlock->ReturnType->isVoidType()) {
+    if (RetValExp) {
+      Diag(ReturnLoc, diag::err_return_block_has_expr);
+      RetValExp->Destroy(Context);
+      RetValExp = 0;
+    }
+    return Owned(new (Context) ReturnStmt(ReturnLoc, RetValExp));
+  }
+
+  if (!RetValExp)
+    return StmtError(Diag(ReturnLoc, diag::err_block_return_missing_expr));
+
+  if (!FnRetType->isDependentType() && !RetValExp->isTypeDependent()) {
+    // we have a non-void block with an expression, continue checking
+
+    // C99 6.8.6.4p3(136): The return statement is not an assignment. The
+    // overlap restriction of subclause 6.5.16.1 does not apply to the case of
+    // function return.
+
+    // In C++ the return statement is handled via a copy initialization.
+    // the C version of which boils down to CheckSingleAssignmentConstraints.
+    OwningExprResult Res = PerformCopyInitialization(
+                             InitializedEntity::InitializeResult(ReturnLoc, 
+                                                                 FnRetType),
+                             SourceLocation(),
+                             Owned(RetValExp));
+    if (Res.isInvalid()) {
+      // FIXME: Cleanup temporaries here, anyway?
+      return StmtError();
+    }
+    
+    RetValExp = Res.takeAs<Expr>();
+    if (RetValExp) 
+      CheckReturnStackAddr(RetValExp, FnRetType, ReturnLoc);
+  }
+
+  return Owned(new (Context) ReturnStmt(ReturnLoc, RetValExp));
+}
+
+/// IsReturnCopyElidable - Whether returning @p RetExpr from a function that
+/// returns a @p RetType fulfills the criteria for copy elision (C++0x 12.8p15).
+static bool IsReturnCopyElidable(ASTContext &Ctx, QualType RetType,
+                                 Expr *RetExpr) {
+  QualType ExprType = RetExpr->getType();
+  // - in a return statement in a function with ...
+  // ... a class return type ...
+  if (!RetType->isRecordType())
+    return false;
+  // ... the same cv-unqualified type as the function return type ...
+  if (!Ctx.hasSameUnqualifiedType(RetType, ExprType))
+    return false;
+  // ... the expression is the name of a non-volatile automatic object ...
+  // We ignore parentheses here.
+  // FIXME: Is this compliant?
+  const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(RetExpr->IgnoreParens());
+  if (!DR)
+    return false;
+  const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl());
+  if (!VD)
+    return false;
+  return VD->hasLocalStorage() && !VD->getType()->isReferenceType()
+    && !VD->getType().isVolatileQualified();
+}
+
+Action::OwningStmtResult
+Sema::ActOnReturnStmt(SourceLocation ReturnLoc, ExprArg rex) {
+  Expr *RetValExp = rex.takeAs<Expr>();
+  if (getCurBlock())
+    return ActOnBlockReturnStmt(ReturnLoc, RetValExp);
+
+  QualType FnRetType;
+  if (const FunctionDecl *FD = getCurFunctionDecl()) {
+    FnRetType = FD->getResultType();
+    if (FD->hasAttr<NoReturnAttr>() ||
+        FD->getType()->getAs<FunctionType>()->getNoReturnAttr())
+      Diag(ReturnLoc, diag::warn_noreturn_function_has_return_expr)
+        << getCurFunctionOrMethodDecl()->getDeclName();
+  } else if (ObjCMethodDecl *MD = getCurMethodDecl())
+    FnRetType = MD->getResultType();
+  else // If we don't have a function/method context, bail.
+    return StmtError();
+
+  if (FnRetType->isVoidType()) {
+    if (RetValExp && !RetValExp->isTypeDependent()) {
+      // C99 6.8.6.4p1 (ext_ since GCC warns)
+      unsigned D = diag::ext_return_has_expr;
+      if (RetValExp->getType()->isVoidType())
+        D = diag::ext_return_has_void_expr;
+
+      // return (some void expression); is legal in C++.
+      if (D != diag::ext_return_has_void_expr ||
+          !getLangOptions().CPlusPlus) {
+        NamedDecl *CurDecl = getCurFunctionOrMethodDecl();
+        Diag(ReturnLoc, D)
+          << CurDecl->getDeclName() << isa<ObjCMethodDecl>(CurDecl)
+          << RetValExp->getSourceRange();
+      }
+
+      RetValExp = MaybeCreateCXXExprWithTemporaries(RetValExp);
+    }
+    return Owned(new (Context) ReturnStmt(ReturnLoc, RetValExp));
+  }
+
+  if (!RetValExp && !FnRetType->isDependentType()) {
+    unsigned DiagID = diag::warn_return_missing_expr;  // C90 6.6.6.4p4
+    // C99 6.8.6.4p1 (ext_ since GCC warns)
+    if (getLangOptions().C99) DiagID = diag::ext_return_missing_expr;
+
+    if (FunctionDecl *FD = getCurFunctionDecl())
+      Diag(ReturnLoc, DiagID) << FD->getIdentifier() << 0/*fn*/;
+    else
+      Diag(ReturnLoc, DiagID) << getCurMethodDecl()->getDeclName() << 1/*meth*/;
+    return Owned(new (Context) ReturnStmt(ReturnLoc, (Expr*)0));
+  }
+
+  if (!FnRetType->isDependentType() && !RetValExp->isTypeDependent()) {
+    // we have a non-void function with an expression, continue checking
+
+    // C99 6.8.6.4p3(136): The return statement is not an assignment. The
+    // overlap restriction of subclause 6.5.16.1 does not apply to the case of
+    // function return.
+
+    // C++0x 12.8p15: When certain criteria are met, an implementation is
+    //   allowed to omit the copy construction of a class object, [...]
+    //   - in a return statement in a function with a class return type, when
+    //     the expression is the name of a non-volatile automatic object with
+    //     the same cv-unqualified type as the function return type, the copy
+    //     operation can be omitted [...]
+    // C++0x 12.8p16: When the criteria for elision of a copy operation are met
+    //   and the object to be copied is designated by an lvalue, overload
+    //   resolution to select the constructor for the copy is first performed
+    //   as if the object were designated by an rvalue.
+    // Note that we only compute Elidable if we're in C++0x, since we don't
+    // care otherwise.
+    bool Elidable = getLangOptions().CPlusPlus0x ?
+                      IsReturnCopyElidable(Context, FnRetType, RetValExp) :
+                      false;
+    // FIXME: Elidable
+    (void)Elidable;
+
+    // In C++ the return statement is handled via a copy initialization.
+    // the C version of which boils down to CheckSingleAssignmentConstraints.
+    OwningExprResult Res = PerformCopyInitialization(
+                             InitializedEntity::InitializeResult(ReturnLoc, 
+                                                                 FnRetType),
+                             SourceLocation(),
+                             Owned(RetValExp));
+    if (Res.isInvalid()) {
+      // FIXME: Cleanup temporaries here, anyway?
+      return StmtError();
+    }
+
+    RetValExp = Res.takeAs<Expr>();
+    if (RetValExp) 
+      CheckReturnStackAddr(RetValExp, FnRetType, ReturnLoc);
+  }
+
+  if (RetValExp)
+    RetValExp = MaybeCreateCXXExprWithTemporaries(RetValExp);
+  return Owned(new (Context) ReturnStmt(ReturnLoc, RetValExp));
+}
+
+/// CheckAsmLValue - GNU C has an extremely ugly extension whereby they silently
+/// ignore "noop" casts in places where an lvalue is required by an inline asm.
+/// We emulate this behavior when -fheinous-gnu-extensions is specified, but
+/// provide a strong guidance to not use it.
+///
+/// This method checks to see if the argument is an acceptable l-value and
+/// returns false if it is a case we can handle.
+static bool CheckAsmLValue(const Expr *E, Sema &S) {
+  // Type dependent expressions will be checked during instantiation.
+  if (E->isTypeDependent())
+    return false;
+  
+  if (E->isLvalue(S.Context) == Expr::LV_Valid)
+    return false;  // Cool, this is an lvalue.
+
+  // Okay, this is not an lvalue, but perhaps it is the result of a cast that we
+  // are supposed to allow.
+  const Expr *E2 = E->IgnoreParenNoopCasts(S.Context);
+  if (E != E2 && E2->isLvalue(S.Context) == Expr::LV_Valid) {
+    if (!S.getLangOptions().HeinousExtensions)
+      S.Diag(E2->getLocStart(), diag::err_invalid_asm_cast_lvalue)
+        << E->getSourceRange();
+    else
+      S.Diag(E2->getLocStart(), diag::warn_invalid_asm_cast_lvalue)
+        << E->getSourceRange();
+    // Accept, even if we emitted an error diagnostic.
+    return false;
+  }
+
+  // None of the above, just randomly invalid non-lvalue.
+  return true;
+}
+
+
+Sema::OwningStmtResult Sema::ActOnAsmStmt(SourceLocation AsmLoc,
+                                          bool IsSimple,
+                                          bool IsVolatile,
+                                          unsigned NumOutputs,
+                                          unsigned NumInputs,
+                                          IdentifierInfo **Names,
+                                          MultiExprArg constraints,
+                                          MultiExprArg exprs,
+                                          ExprArg asmString,
+                                          MultiExprArg clobbers,
+                                          SourceLocation RParenLoc,
+                                          bool MSAsm) {
+  unsigned NumClobbers = clobbers.size();
+  StringLiteral **Constraints =
+    reinterpret_cast<StringLiteral**>(constraints.get());
+  Expr **Exprs = reinterpret_cast<Expr **>(exprs.get());
+  StringLiteral *AsmString = cast<StringLiteral>((Expr *)asmString.get());
+  StringLiteral **Clobbers = reinterpret_cast<StringLiteral**>(clobbers.get());
+
+  llvm::SmallVector<TargetInfo::ConstraintInfo, 4> OutputConstraintInfos;
+
+  // The parser verifies that there is a string literal here.
+  if (AsmString->isWide())
+    return StmtError(Diag(AsmString->getLocStart(),diag::err_asm_wide_character)
+      << AsmString->getSourceRange());
+
+  for (unsigned i = 0; i != NumOutputs; i++) {
+    StringLiteral *Literal = Constraints[i];
+    if (Literal->isWide())
+      return StmtError(Diag(Literal->getLocStart(),diag::err_asm_wide_character)
+        << Literal->getSourceRange());
+
+    llvm::StringRef OutputName;
+    if (Names[i])
+      OutputName = Names[i]->getName();
+
+    TargetInfo::ConstraintInfo Info(Literal->getString(), OutputName);
+    if (!Context.Target.validateOutputConstraint(Info))
+      return StmtError(Diag(Literal->getLocStart(),
+                            diag::err_asm_invalid_output_constraint)
+                       << Info.getConstraintStr());
+
+    // Check that the output exprs are valid lvalues.
+    Expr *OutputExpr = Exprs[i];
+    if (CheckAsmLValue(OutputExpr, *this)) {
+      return StmtError(Diag(OutputExpr->getLocStart(),
+                  diag::err_asm_invalid_lvalue_in_output)
+        << OutputExpr->getSourceRange());
+    }
+
+    OutputConstraintInfos.push_back(Info);
+  }
+
+  llvm::SmallVector<TargetInfo::ConstraintInfo, 4> InputConstraintInfos;
+
+  for (unsigned i = NumOutputs, e = NumOutputs + NumInputs; i != e; i++) {
+    StringLiteral *Literal = Constraints[i];
+    if (Literal->isWide())
+      return StmtError(Diag(Literal->getLocStart(),diag::err_asm_wide_character)
+        << Literal->getSourceRange());
+
+    llvm::StringRef InputName;
+    if (Names[i])
+      InputName = Names[i]->getName();
+
+    TargetInfo::ConstraintInfo Info(Literal->getString(), InputName);
+    if (!Context.Target.validateInputConstraint(OutputConstraintInfos.data(),
+                                                NumOutputs, Info)) {
+      return StmtError(Diag(Literal->getLocStart(),
+                            diag::err_asm_invalid_input_constraint)
+                       << Info.getConstraintStr());
+    }
+
+    Expr *InputExpr = Exprs[i];
+
+    // Only allow void types for memory constraints.
+    if (Info.allowsMemory() && !Info.allowsRegister()) {
+      if (CheckAsmLValue(InputExpr, *this))
+        return StmtError(Diag(InputExpr->getLocStart(),
+                              diag::err_asm_invalid_lvalue_in_input)
+                         << Info.getConstraintStr()
+                         << InputExpr->getSourceRange());
+    }
+
+    if (Info.allowsRegister()) {
+      if (InputExpr->getType()->isVoidType()) {
+        return StmtError(Diag(InputExpr->getLocStart(),
+                              diag::err_asm_invalid_type_in_input)
+          << InputExpr->getType() << Info.getConstraintStr()
+          << InputExpr->getSourceRange());
+      }
+    }
+
+    DefaultFunctionArrayLvalueConversion(Exprs[i]);
+
+    InputConstraintInfos.push_back(Info);
+  }
+
+  // Check that the clobbers are valid.
+  for (unsigned i = 0; i != NumClobbers; i++) {
+    StringLiteral *Literal = Clobbers[i];
+    if (Literal->isWide())
+      return StmtError(Diag(Literal->getLocStart(),diag::err_asm_wide_character)
+        << Literal->getSourceRange());
+
+    llvm::StringRef Clobber = Literal->getString();
+
+    if (!Context.Target.isValidGCCRegisterName(Clobber))
+      return StmtError(Diag(Literal->getLocStart(),
+                  diag::err_asm_unknown_register_name) << Clobber);
+  }
+
+  constraints.release();
+  exprs.release();
+  asmString.release();
+  clobbers.release();
+  AsmStmt *NS =
+    new (Context) AsmStmt(Context, AsmLoc, IsSimple, IsVolatile, MSAsm, 
+                          NumOutputs, NumInputs, Names, Constraints, Exprs, 
+                          AsmString, NumClobbers, Clobbers, RParenLoc);
+  // Validate the asm string, ensuring it makes sense given the operands we
+  // have.
+  llvm::SmallVector<AsmStmt::AsmStringPiece, 8> Pieces;
+  unsigned DiagOffs;
+  if (unsigned DiagID = NS->AnalyzeAsmString(Pieces, Context, DiagOffs)) {
+    Diag(getLocationOfStringLiteralByte(AsmString, DiagOffs), DiagID)
+           << AsmString->getSourceRange();
+    DeleteStmt(NS);
+    return StmtError();
+  }
+
+  // Validate tied input operands for type mismatches.
+  for (unsigned i = 0, e = InputConstraintInfos.size(); i != e; ++i) {
+    TargetInfo::ConstraintInfo &Info = InputConstraintInfos[i];
+
+    // If this is a tied constraint, verify that the output and input have
+    // either exactly the same type, or that they are int/ptr operands with the
+    // same size (int/long, int*/long, are ok etc).
+    if (!Info.hasTiedOperand()) continue;
+
+    unsigned TiedTo = Info.getTiedOperand();
+    Expr *OutputExpr = Exprs[TiedTo];
+    Expr *InputExpr = Exprs[i+NumOutputs];
+    QualType InTy = InputExpr->getType();
+    QualType OutTy = OutputExpr->getType();
+    if (Context.hasSameType(InTy, OutTy))
+      continue;  // All types can be tied to themselves.
+
+    // Decide if the input and output are in the same domain (integer/ptr or
+    // floating point.
+    enum AsmDomain {
+      AD_Int, AD_FP, AD_Other
+    } InputDomain, OutputDomain;
+    
+    if (InTy->isIntegerType() || InTy->isPointerType())
+      InputDomain = AD_Int;
+    else if (InTy->isFloatingType())
+      InputDomain = AD_FP;
+    else
+      InputDomain = AD_Other;
+
+    if (OutTy->isIntegerType() || OutTy->isPointerType())
+      OutputDomain = AD_Int;
+    else if (OutTy->isFloatingType())
+      OutputDomain = AD_FP;
+    else
+      OutputDomain = AD_Other;
+    
+    // They are ok if they are the same size and in the same domain.  This
+    // allows tying things like:
+    //   void* to int*
+    //   void* to int            if they are the same size.
+    //   double to long double   if they are the same size.
+    // 
+    uint64_t OutSize = Context.getTypeSize(OutTy);
+    uint64_t InSize = Context.getTypeSize(InTy);
+    if (OutSize == InSize && InputDomain == OutputDomain &&
+        InputDomain != AD_Other)
+      continue;
+    
+    // If the smaller input/output operand is not mentioned in the asm string,
+    // then we can promote it and the asm string won't notice.  Check this
+    // case now.
+    bool SmallerValueMentioned = false;
+    for (unsigned p = 0, e = Pieces.size(); p != e; ++p) {
+      AsmStmt::AsmStringPiece &Piece = Pieces[p];
+      if (!Piece.isOperand()) continue;
+
+      // If this is a reference to the input and if the input was the smaller
+      // one, then we have to reject this asm.
+      if (Piece.getOperandNo() == i+NumOutputs) {
+        if (InSize < OutSize) {
+          SmallerValueMentioned = true;
+          break;
+        }
+      }
+
+      // If this is a reference to the input and if the input was the smaller
+      // one, then we have to reject this asm.
+      if (Piece.getOperandNo() == TiedTo) {
+        if (InSize > OutSize) {
+          SmallerValueMentioned = true;
+          break;
+        }
+      }
+    }
+
+    // If the smaller value wasn't mentioned in the asm string, and if the
+    // output was a register, just extend the shorter one to the size of the
+    // larger one.
+    if (!SmallerValueMentioned && InputDomain != AD_Other &&
+        OutputConstraintInfos[TiedTo].allowsRegister())
+      continue;
+
+    Diag(InputExpr->getLocStart(),
+         diag::err_asm_tying_incompatible_types)
+      << InTy << OutTy << OutputExpr->getSourceRange()
+      << InputExpr->getSourceRange();
+    DeleteStmt(NS);
+    return StmtError();
+  }
+
+  return Owned(NS);
+}
+
+Action::OwningStmtResult
+Sema::ActOnObjCAtCatchStmt(SourceLocation AtLoc,
+                           SourceLocation RParen, DeclPtrTy Parm,
+                           StmtArg Body) {
+  VarDecl *Var = cast_or_null<VarDecl>(Parm.getAs<Decl>());
+  if (Var && Var->isInvalidDecl())
+    return StmtError();
+  
+  return Owned(new (Context) ObjCAtCatchStmt(AtLoc, RParen, Var, 
+                                             Body.takeAs<Stmt>()));
+}
+
+Action::OwningStmtResult
+Sema::ActOnObjCAtFinallyStmt(SourceLocation AtLoc, StmtArg Body) {
+  return Owned(new (Context) ObjCAtFinallyStmt(AtLoc,
+                                           static_cast<Stmt*>(Body.release())));
+}
+
+Action::OwningStmtResult
+Sema::ActOnObjCAtTryStmt(SourceLocation AtLoc, StmtArg Try, 
+                         MultiStmtArg CatchStmts, StmtArg Finally) {
+  FunctionNeedsScopeChecking() = true;
+  unsigned NumCatchStmts = CatchStmts.size();
+  return Owned(ObjCAtTryStmt::Create(Context, AtLoc, Try.takeAs<Stmt>(),
+                                     (Stmt **)CatchStmts.release(),
+                                     NumCatchStmts,
+                                     Finally.takeAs<Stmt>()));
+}
+
+Sema::OwningStmtResult Sema::BuildObjCAtThrowStmt(SourceLocation AtLoc,
+                                                  ExprArg ThrowE) {
+  Expr *Throw = static_cast<Expr *>(ThrowE.get());
+  if (Throw) {
+    QualType ThrowType = Throw->getType();
+    // Make sure the expression type is an ObjC pointer or "void *".
+    if (!ThrowType->isDependentType() &&
+        !ThrowType->isObjCObjectPointerType()) {
+      const PointerType *PT = ThrowType->getAs<PointerType>();
+      if (!PT || !PT->getPointeeType()->isVoidType())
+        return StmtError(Diag(AtLoc, diag::error_objc_throw_expects_object)
+                         << Throw->getType() << Throw->getSourceRange());
+    }
+  }
+  
+  return Owned(new (Context) ObjCAtThrowStmt(AtLoc, ThrowE.takeAs<Expr>()));
+}
+
+Action::OwningStmtResult
+Sema::ActOnObjCAtThrowStmt(SourceLocation AtLoc, ExprArg Throw, 
+                           Scope *CurScope) {
+  if (!Throw.get()) {
+    // @throw without an expression designates a rethrow (which much occur
+    // in the context of an @catch clause).
+    Scope *AtCatchParent = CurScope;
+    while (AtCatchParent && !AtCatchParent->isAtCatchScope())
+      AtCatchParent = AtCatchParent->getParent();
+    if (!AtCatchParent)
+      return StmtError(Diag(AtLoc, diag::error_rethrow_used_outside_catch));
+  } 
+  
+  return BuildObjCAtThrowStmt(AtLoc, move(Throw));
+}
+
+Action::OwningStmtResult
+Sema::ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc, ExprArg SynchExpr,
+                                  StmtArg SynchBody) {
+  FunctionNeedsScopeChecking() = true;
+
+  // Make sure the expression type is an ObjC pointer or "void *".
+  Expr *SyncExpr = static_cast<Expr*>(SynchExpr.get());
+  if (!SyncExpr->getType()->isDependentType() &&
+      !SyncExpr->getType()->isObjCObjectPointerType()) {
+    const PointerType *PT = SyncExpr->getType()->getAs<PointerType>();
+    if (!PT || !PT->getPointeeType()->isVoidType())
+      return StmtError(Diag(AtLoc, diag::error_objc_synchronized_expects_object)
+                       << SyncExpr->getType() << SyncExpr->getSourceRange());
+  }
+
+  return Owned(new (Context) ObjCAtSynchronizedStmt(AtLoc,
+                                                    SynchExpr.takeAs<Stmt>(),
+                                                    SynchBody.takeAs<Stmt>()));
+}
+
+/// ActOnCXXCatchBlock - Takes an exception declaration and a handler block
+/// and creates a proper catch handler from them.
+Action::OwningStmtResult
+Sema::ActOnCXXCatchBlock(SourceLocation CatchLoc, DeclPtrTy ExDecl,
+                         StmtArg HandlerBlock) {
+  // There's nothing to test that ActOnExceptionDecl didn't already test.
+  return Owned(new (Context) CXXCatchStmt(CatchLoc,
+                                  cast_or_null<VarDecl>(ExDecl.getAs<Decl>()),
+                                          HandlerBlock.takeAs<Stmt>()));
+}
+
+class TypeWithHandler {
+  QualType t;
+  CXXCatchStmt *stmt;
+public:
+  TypeWithHandler(const QualType &type, CXXCatchStmt *statement)
+  : t(type), stmt(statement) {}
+
+  // An arbitrary order is fine as long as it places identical
+  // types next to each other.
+  bool operator<(const TypeWithHandler &y) const {
+    if (t.getAsOpaquePtr() < y.t.getAsOpaquePtr())
+      return true;
+    if (t.getAsOpaquePtr() > y.t.getAsOpaquePtr())
+      return false;
+    else
+      return getTypeSpecStartLoc() < y.getTypeSpecStartLoc();
+  }
+
+  bool operator==(const TypeWithHandler& other) const {
+    return t == other.t;
+  }
+
+  QualType getQualType() const { return t; }
+  CXXCatchStmt *getCatchStmt() const { return stmt; }
+  SourceLocation getTypeSpecStartLoc() const {
+    return stmt->getExceptionDecl()->getTypeSpecStartLoc();
+  }
+};
+
+/// ActOnCXXTryBlock - Takes a try compound-statement and a number of
+/// handlers and creates a try statement from them.
+Action::OwningStmtResult
+Sema::ActOnCXXTryBlock(SourceLocation TryLoc, StmtArg TryBlock,
+                       MultiStmtArg RawHandlers) {
+  unsigned NumHandlers = RawHandlers.size();
+  assert(NumHandlers > 0 &&
+         "The parser shouldn't call this if there are no handlers.");
+  Stmt **Handlers = reinterpret_cast<Stmt**>(RawHandlers.get());
+
+  llvm::SmallVector<TypeWithHandler, 8> TypesWithHandlers;
+
+  for (unsigned i = 0; i < NumHandlers; ++i) {
+    CXXCatchStmt *Handler = llvm::cast<CXXCatchStmt>(Handlers[i]);
+    if (!Handler->getExceptionDecl()) {
+      if (i < NumHandlers - 1)
+        return StmtError(Diag(Handler->getLocStart(),
+                              diag::err_early_catch_all));
+
+      continue;
+    }
+
+    const QualType CaughtType = Handler->getCaughtType();
+    const QualType CanonicalCaughtType = Context.getCanonicalType(CaughtType);
+    TypesWithHandlers.push_back(TypeWithHandler(CanonicalCaughtType, Handler));
+  }
+
+  // Detect handlers for the same type as an earlier one.
+  if (NumHandlers > 1) {
+    llvm::array_pod_sort(TypesWithHandlers.begin(), TypesWithHandlers.end());
+
+    TypeWithHandler prev = TypesWithHandlers[0];
+    for (unsigned i = 1; i < TypesWithHandlers.size(); ++i) {
+      TypeWithHandler curr = TypesWithHandlers[i];
+
+      if (curr == prev) {
+        Diag(curr.getTypeSpecStartLoc(),
+             diag::warn_exception_caught_by_earlier_handler)
+          << curr.getCatchStmt()->getCaughtType().getAsString();
+        Diag(prev.getTypeSpecStartLoc(),
+             diag::note_previous_exception_handler)
+          << prev.getCatchStmt()->getCaughtType().getAsString();
+      }
+
+      prev = curr;
+    }
+  }
+
+  // FIXME: We should detect handlers that cannot catch anything because an
+  // earlier handler catches a superclass. Need to find a method that is not
+  // quadratic for this.
+  // Neither of these are explicitly forbidden, but every compiler detects them
+  // and warns.
+
+  FunctionNeedsScopeChecking() = true;
+  RawHandlers.release();
+  return Owned(CXXTryStmt::Create(Context, TryLoc,
+                                  static_cast<Stmt*>(TryBlock.release()),
+                                  Handlers, NumHandlers));
+}
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
new file mode 100644
index 0000000..731836b
--- /dev/null
+++ b/lib/Sema/SemaTemplate.cpp
@@ -0,0 +1,5535 @@
+//===------- SemaTemplate.cpp - Semantic Analysis for C++ Templates -------===/
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//===----------------------------------------------------------------------===/
+//
+//  This file implements semantic analysis for C++ templates.
+//===----------------------------------------------------------------------===/
+
+#include "Sema.h"
+#include "Lookup.h"
+#include "TreeTransform.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/DeclFriend.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/Parse/DeclSpec.h"
+#include "clang/Parse/Template.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/PartialDiagnostic.h"
+#include "llvm/ADT/StringExtras.h"
+using namespace clang;
+
+/// \brief Determine whether the declaration found is acceptable as the name
+/// of a template and, if so, return that template declaration. Otherwise,
+/// returns NULL.
+static NamedDecl *isAcceptableTemplateName(ASTContext &Context, NamedDecl *D) {
+  if (!D)
+    return 0;
+
+  if (isa<TemplateDecl>(D))
+    return D;
+
+  if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(D)) {
+    // C++ [temp.local]p1:
+    //   Like normal (non-template) classes, class templates have an
+    //   injected-class-name (Clause 9). The injected-class-name
+    //   can be used with or without a template-argument-list. When
+    //   it is used without a template-argument-list, it is
+    //   equivalent to the injected-class-name followed by the
+    //   template-parameters of the class template enclosed in
+    //   <>. When it is used with a template-argument-list, it
+    //   refers to the specified class template specialization,
+    //   which could be the current specialization or another
+    //   specialization.
+    if (Record->isInjectedClassName()) {
+      Record = cast<CXXRecordDecl>(Record->getDeclContext());
+      if (Record->getDescribedClassTemplate())
+        return Record->getDescribedClassTemplate();
+
+      if (ClassTemplateSpecializationDecl *Spec
+            = dyn_cast<ClassTemplateSpecializationDecl>(Record))
+        return Spec->getSpecializedTemplate();
+    }
+
+    return 0;
+  }
+
+  return 0;
+}
+
+static void FilterAcceptableTemplateNames(ASTContext &C, LookupResult &R) {
+  // The set of class templates we've already seen.
+  llvm::SmallPtrSet<ClassTemplateDecl *, 8> ClassTemplates;
+  LookupResult::Filter filter = R.makeFilter();
+  while (filter.hasNext()) {
+    NamedDecl *Orig = filter.next();
+    NamedDecl *Repl = isAcceptableTemplateName(C, Orig->getUnderlyingDecl());
+    if (!Repl)
+      filter.erase();
+    else if (Repl != Orig) {
+
+      // C++ [temp.local]p3:
+      //   A lookup that finds an injected-class-name (10.2) can result in an 
+      //   ambiguity in certain cases (for example, if it is found in more than
+      //   one base class). If all of the injected-class-names that are found 
+      //   refer to specializations of the same class template, and if the name 
+      //   is followed by a template-argument-list, the reference refers to the 
+      //   class template itself and not a specialization thereof, and is not 
+      //   ambiguous.
+      //
+      // FIXME: Will we eventually have to do the same for alias templates?
+      if (ClassTemplateDecl *ClassTmpl = dyn_cast<ClassTemplateDecl>(Repl))
+        if (!ClassTemplates.insert(ClassTmpl)) {
+          filter.erase();
+          continue;
+        }
+          
+      filter.replace(Repl);
+    }
+  }
+  filter.done();
+}
+
+TemplateNameKind Sema::isTemplateName(Scope *S,
+                                      CXXScopeSpec &SS,
+                                      UnqualifiedId &Name,
+                                      TypeTy *ObjectTypePtr,
+                                      bool EnteringContext,
+                                      TemplateTy &TemplateResult) {
+  assert(getLangOptions().CPlusPlus && "No template names in C!");
+
+  DeclarationName TName;
+  
+  switch (Name.getKind()) {
+  case UnqualifiedId::IK_Identifier:
+    TName = DeclarationName(Name.Identifier);
+    break;
+      
+  case UnqualifiedId::IK_OperatorFunctionId:
+    TName = Context.DeclarationNames.getCXXOperatorName(
+                                              Name.OperatorFunctionId.Operator);
+    break;
+
+  case UnqualifiedId::IK_LiteralOperatorId:
+    TName = Context.DeclarationNames.getCXXLiteralOperatorName(Name.Identifier);
+    break;
+
+  default:
+    return TNK_Non_template;
+  }
+
+  QualType ObjectType = QualType::getFromOpaquePtr(ObjectTypePtr);
+
+  LookupResult R(*this, TName, Name.getSourceRange().getBegin(), 
+                 LookupOrdinaryName);
+  R.suppressDiagnostics();
+  LookupTemplateName(R, S, SS, ObjectType, EnteringContext);
+  if (R.empty() || R.isAmbiguous())
+    return TNK_Non_template;
+
+  TemplateName Template;
+  TemplateNameKind TemplateKind;
+
+  unsigned ResultCount = R.end() - R.begin();
+  if (ResultCount > 1) {
+    // We assume that we'll preserve the qualifier from a function
+    // template name in other ways.
+    Template = Context.getOverloadedTemplateName(R.begin(), R.end());
+    TemplateKind = TNK_Function_template;
+  } else {
+    TemplateDecl *TD = cast<TemplateDecl>((*R.begin())->getUnderlyingDecl());
+
+    if (SS.isSet() && !SS.isInvalid()) {
+      NestedNameSpecifier *Qualifier
+        = static_cast<NestedNameSpecifier *>(SS.getScopeRep());
+      Template = Context.getQualifiedTemplateName(Qualifier, false, TD);
+    } else {
+      Template = TemplateName(TD);
+    }
+
+    if (isa<FunctionTemplateDecl>(TD))
+      TemplateKind = TNK_Function_template;
+    else {
+      assert(isa<ClassTemplateDecl>(TD) || isa<TemplateTemplateParmDecl>(TD));
+      TemplateKind = TNK_Type_template;
+    }
+  }
+
+  TemplateResult = TemplateTy::make(Template);
+  return TemplateKind;
+}
+
+bool Sema::DiagnoseUnknownTemplateName(const IdentifierInfo &II, 
+                                       SourceLocation IILoc,
+                                       Scope *S,
+                                       const CXXScopeSpec *SS,
+                                       TemplateTy &SuggestedTemplate,
+                                       TemplateNameKind &SuggestedKind) {
+  // We can't recover unless there's a dependent scope specifier preceding the
+  // template name.
+  if (!SS || !SS->isSet() || !isDependentScopeSpecifier(*SS) ||
+      computeDeclContext(*SS))
+    return false;
+  
+  // The code is missing a 'template' keyword prior to the dependent template
+  // name.
+  NestedNameSpecifier *Qualifier = (NestedNameSpecifier*)SS->getScopeRep();
+  Diag(IILoc, diag::err_template_kw_missing)
+    << Qualifier << II.getName()
+    << FixItHint::CreateInsertion(IILoc, "template ");
+  SuggestedTemplate 
+    = TemplateTy::make(Context.getDependentTemplateName(Qualifier, &II));
+  SuggestedKind = TNK_Dependent_template_name;
+  return true;
+}
+
+void Sema::LookupTemplateName(LookupResult &Found,
+                              Scope *S, CXXScopeSpec &SS,
+                              QualType ObjectType,
+                              bool EnteringContext) {
+  // Determine where to perform name lookup
+  DeclContext *LookupCtx = 0;
+  bool isDependent = false;
+  if (!ObjectType.isNull()) {
+    // This nested-name-specifier occurs in a member access expression, e.g.,
+    // x->B::f, and we are looking into the type of the object.
+    assert(!SS.isSet() && "ObjectType and scope specifier cannot coexist");
+    LookupCtx = computeDeclContext(ObjectType);
+    isDependent = ObjectType->isDependentType();
+    assert((isDependent || !ObjectType->isIncompleteType()) && 
+           "Caller should have completed object type");
+  } else if (SS.isSet()) {
+    // This nested-name-specifier occurs after another nested-name-specifier,
+    // so long into the context associated with the prior nested-name-specifier.
+    LookupCtx = computeDeclContext(SS, EnteringContext);
+    isDependent = isDependentScopeSpecifier(SS);
+    
+    // The declaration context must be complete.
+    if (LookupCtx && RequireCompleteDeclContext(SS))
+      return;
+  }
+
+  bool ObjectTypeSearchedInScope = false;
+  if (LookupCtx) {
+    // Perform "qualified" name lookup into the declaration context we
+    // computed, which is either the type of the base of a member access
+    // expression or the declaration context associated with a prior
+    // nested-name-specifier.
+    LookupQualifiedName(Found, LookupCtx);
+
+    if (!ObjectType.isNull() && Found.empty()) {
+      // C++ [basic.lookup.classref]p1:
+      //   In a class member access expression (5.2.5), if the . or -> token is
+      //   immediately followed by an identifier followed by a <, the
+      //   identifier must be looked up to determine whether the < is the
+      //   beginning of a template argument list (14.2) or a less-than operator.
+      //   The identifier is first looked up in the class of the object
+      //   expression. If the identifier is not found, it is then looked up in
+      //   the context of the entire postfix-expression and shall name a class
+      //   or function template.
+      //
+      // FIXME: When we're instantiating a template, do we actually have to
+      // look in the scope of the template? Seems fishy...
+      if (S) LookupName(Found, S);
+      ObjectTypeSearchedInScope = true;
+    }
+  } else if (isDependent) {
+    // We cannot look into a dependent object type or nested nme
+    // specifier.
+    return;
+  } else {
+    // Perform unqualified name lookup in the current scope.
+    LookupName(Found, S);
+  }
+
+  if (Found.empty() && !isDependent) {
+    // If we did not find any names, attempt to correct any typos.
+    DeclarationName Name = Found.getLookupName();
+    if (DeclarationName Corrected = CorrectTypo(Found, S, &SS, LookupCtx, 
+                                                 false, CTC_CXXCasts)) {
+      FilterAcceptableTemplateNames(Context, Found);
+      if (!Found.empty() && isa<TemplateDecl>(*Found.begin())) {
+        if (LookupCtx)
+          Diag(Found.getNameLoc(), diag::err_no_member_template_suggest)
+            << Name << LookupCtx << Found.getLookupName() << SS.getRange()
+            << FixItHint::CreateReplacement(Found.getNameLoc(),
+                                          Found.getLookupName().getAsString());
+        else
+          Diag(Found.getNameLoc(), diag::err_no_template_suggest)
+            << Name << Found.getLookupName()
+            << FixItHint::CreateReplacement(Found.getNameLoc(),
+                                          Found.getLookupName().getAsString());
+        if (TemplateDecl *Template = Found.getAsSingle<TemplateDecl>())
+          Diag(Template->getLocation(), diag::note_previous_decl)
+            << Template->getDeclName();
+      } else
+        Found.clear();
+    } else {
+      Found.clear();
+    }
+  }
+
+  FilterAcceptableTemplateNames(Context, Found);
+  if (Found.empty())
+    return;
+
+  if (S && !ObjectType.isNull() && !ObjectTypeSearchedInScope) {
+    // C++ [basic.lookup.classref]p1:
+    //   [...] If the lookup in the class of the object expression finds a
+    //   template, the name is also looked up in the context of the entire
+    //   postfix-expression and [...]
+    //
+    LookupResult FoundOuter(*this, Found.getLookupName(), Found.getNameLoc(),
+                            LookupOrdinaryName);
+    LookupName(FoundOuter, S);
+    FilterAcceptableTemplateNames(Context, FoundOuter);
+    
+    if (FoundOuter.empty()) {
+      //   - if the name is not found, the name found in the class of the
+      //     object expression is used, otherwise
+    } else if (!FoundOuter.getAsSingle<ClassTemplateDecl>()) {
+      //   - if the name is found in the context of the entire
+      //     postfix-expression and does not name a class template, the name
+      //     found in the class of the object expression is used, otherwise
+    } else {
+      //   - if the name found is a class template, it must refer to the same
+      //     entity as the one found in the class of the object expression,
+      //     otherwise the program is ill-formed.
+      if (!Found.isSingleResult() ||
+          Found.getFoundDecl()->getCanonicalDecl()
+            != FoundOuter.getFoundDecl()->getCanonicalDecl()) {
+        Diag(Found.getNameLoc(), 
+             diag::err_nested_name_member_ref_lookup_ambiguous)
+          << Found.getLookupName();
+        Diag(Found.getRepresentativeDecl()->getLocation(),
+             diag::note_ambig_member_ref_object_type)
+          << ObjectType;
+        Diag(FoundOuter.getFoundDecl()->getLocation(),
+             diag::note_ambig_member_ref_scope);
+
+        // Recover by taking the template that we found in the object
+        // expression's type.
+      }
+    }
+  }
+}
+
+/// ActOnDependentIdExpression - Handle a dependent id-expression that
+/// was just parsed.  This is only possible with an explicit scope
+/// specifier naming a dependent type.
+Sema::OwningExprResult
+Sema::ActOnDependentIdExpression(const CXXScopeSpec &SS,
+                                 DeclarationName Name,
+                                 SourceLocation NameLoc,
+                                 bool isAddressOfOperand,
+                           const TemplateArgumentListInfo *TemplateArgs) {
+  NestedNameSpecifier *Qualifier
+    = static_cast<NestedNameSpecifier*>(SS.getScopeRep());
+    
+  if (!isAddressOfOperand &&
+      isa<CXXMethodDecl>(CurContext) &&
+      cast<CXXMethodDecl>(CurContext)->isInstance()) {
+    QualType ThisType = cast<CXXMethodDecl>(CurContext)->getThisType(Context);
+    
+    // Since the 'this' expression is synthesized, we don't need to
+    // perform the double-lookup check.
+    NamedDecl *FirstQualifierInScope = 0;
+
+    return Owned(CXXDependentScopeMemberExpr::Create(Context,
+                                                     /*This*/ 0, ThisType,
+                                                     /*IsArrow*/ true,
+                                                     /*Op*/ SourceLocation(),
+                                                     Qualifier, SS.getRange(),
+                                                     FirstQualifierInScope,
+                                                     Name, NameLoc,
+                                                     TemplateArgs));
+  }
+
+  return BuildDependentDeclRefExpr(SS, Name, NameLoc, TemplateArgs);
+}
+
+Sema::OwningExprResult
+Sema::BuildDependentDeclRefExpr(const CXXScopeSpec &SS,
+                                DeclarationName Name,
+                                SourceLocation NameLoc,
+                                const TemplateArgumentListInfo *TemplateArgs) {
+  return Owned(DependentScopeDeclRefExpr::Create(Context,
+               static_cast<NestedNameSpecifier*>(SS.getScopeRep()),
+                                                 SS.getRange(),
+                                                 Name, NameLoc,
+                                                 TemplateArgs));
+}
+
+/// DiagnoseTemplateParameterShadow - Produce a diagnostic complaining
+/// that the template parameter 'PrevDecl' is being shadowed by a new
+/// declaration at location Loc. Returns true to indicate that this is
+/// an error, and false otherwise.
+bool Sema::DiagnoseTemplateParameterShadow(SourceLocation Loc, Decl *PrevDecl) {
+  assert(PrevDecl->isTemplateParameter() && "Not a template parameter");
+
+  // Microsoft Visual C++ permits template parameters to be shadowed.
+  if (getLangOptions().Microsoft)
+    return false;
+
+  // C++ [temp.local]p4:
+  //   A template-parameter shall not be redeclared within its
+  //   scope (including nested scopes).
+  Diag(Loc, diag::err_template_param_shadow)
+    << cast<NamedDecl>(PrevDecl)->getDeclName();
+  Diag(PrevDecl->getLocation(), diag::note_template_param_here);
+  return true;
+}
+
+/// AdjustDeclIfTemplate - If the given decl happens to be a template, reset
+/// the parameter D to reference the templated declaration and return a pointer
+/// to the template declaration. Otherwise, do nothing to D and return null.
+TemplateDecl *Sema::AdjustDeclIfTemplate(DeclPtrTy &D) {
+  if (TemplateDecl *Temp = dyn_cast_or_null<TemplateDecl>(D.getAs<Decl>())) {
+    D = DeclPtrTy::make(Temp->getTemplatedDecl());
+    return Temp;
+  }
+  return 0;
+}
+
+static TemplateArgumentLoc translateTemplateArgument(Sema &SemaRef,
+                                            const ParsedTemplateArgument &Arg) {
+  
+  switch (Arg.getKind()) {
+  case ParsedTemplateArgument::Type: {
+    TypeSourceInfo *DI;
+    QualType T = SemaRef.GetTypeFromParser(Arg.getAsType(), &DI);
+    if (!DI) 
+      DI = SemaRef.Context.getTrivialTypeSourceInfo(T, Arg.getLocation());
+    return TemplateArgumentLoc(TemplateArgument(T), DI);
+  }
+    
+  case ParsedTemplateArgument::NonType: {
+    Expr *E = static_cast<Expr *>(Arg.getAsExpr());
+    return TemplateArgumentLoc(TemplateArgument(E), E);
+  }
+    
+  case ParsedTemplateArgument::Template: {
+    TemplateName Template
+      = TemplateName::getFromVoidPointer(Arg.getAsTemplate().get());
+    return TemplateArgumentLoc(TemplateArgument(Template),
+                               Arg.getScopeSpec().getRange(),
+                               Arg.getLocation());
+  }
+  }
+  
+  llvm_unreachable("Unhandled parsed template argument");
+  return TemplateArgumentLoc();
+}
+                                                     
+/// \brief Translates template arguments as provided by the parser
+/// into template arguments used by semantic analysis.
+void Sema::translateTemplateArguments(const ASTTemplateArgsPtr &TemplateArgsIn,
+                                      TemplateArgumentListInfo &TemplateArgs) {
+ for (unsigned I = 0, Last = TemplateArgsIn.size(); I != Last; ++I)
+   TemplateArgs.addArgument(translateTemplateArgument(*this,
+                                                      TemplateArgsIn[I]));
+}
+                                                     
+/// ActOnTypeParameter - Called when a C++ template type parameter
+/// (e.g., "typename T") has been parsed. Typename specifies whether
+/// the keyword "typename" was used to declare the type parameter
+/// (otherwise, "class" was used), and KeyLoc is the location of the
+/// "class" or "typename" keyword. ParamName is the name of the
+/// parameter (NULL indicates an unnamed template parameter) and
+/// ParamName is the location of the parameter name (if any).
+/// If the type parameter has a default argument, it will be added
+/// later via ActOnTypeParameterDefault.
+Sema::DeclPtrTy Sema::ActOnTypeParameter(Scope *S, bool Typename, bool Ellipsis,
+                                         SourceLocation EllipsisLoc,
+                                         SourceLocation KeyLoc,
+                                         IdentifierInfo *ParamName,
+                                         SourceLocation ParamNameLoc,
+                                         unsigned Depth, unsigned Position) {
+  assert(S->isTemplateParamScope() &&
+         "Template type parameter not in template parameter scope!");
+  bool Invalid = false;
+
+  if (ParamName) {
+    NamedDecl *PrevDecl = LookupSingleName(S, ParamName, ParamNameLoc,
+                                           LookupOrdinaryName,
+                                           ForRedeclaration);
+    if (PrevDecl && PrevDecl->isTemplateParameter())
+      Invalid = Invalid || DiagnoseTemplateParameterShadow(ParamNameLoc,
+                                                           PrevDecl);
+  }
+
+  SourceLocation Loc = ParamNameLoc;
+  if (!ParamName)
+    Loc = KeyLoc;
+
+  TemplateTypeParmDecl *Param
+    = TemplateTypeParmDecl::Create(Context, Context.getTranslationUnitDecl(),
+                                   Loc, Depth, Position, ParamName, Typename,
+                                   Ellipsis);
+  if (Invalid)
+    Param->setInvalidDecl();
+
+  if (ParamName) {
+    // Add the template parameter into the current scope.
+    S->AddDecl(DeclPtrTy::make(Param));
+    IdResolver.AddDecl(Param);
+  }
+
+  return DeclPtrTy::make(Param);
+}
+
+/// ActOnTypeParameterDefault - Adds a default argument (the type
+/// Default) to the given template type parameter (TypeParam).
+void Sema::ActOnTypeParameterDefault(DeclPtrTy TypeParam,
+                                     SourceLocation EqualLoc,
+                                     SourceLocation DefaultLoc,
+                                     TypeTy *DefaultT) {
+  TemplateTypeParmDecl *Parm
+    = cast<TemplateTypeParmDecl>(TypeParam.getAs<Decl>());
+
+  TypeSourceInfo *DefaultTInfo;
+  GetTypeFromParser(DefaultT, &DefaultTInfo);
+
+  assert(DefaultTInfo && "expected source information for type");
+
+  // C++0x [temp.param]p9:
+  // A default template-argument may be specified for any kind of
+  // template-parameter that is not a template parameter pack.
+  if (Parm->isParameterPack()) {
+    Diag(DefaultLoc, diag::err_template_param_pack_default_arg);
+    return;
+  }
+
+  // C++ [temp.param]p14:
+  //   A template-parameter shall not be used in its own default argument.
+  // FIXME: Implement this check! Needs a recursive walk over the types.
+
+  // Check the template argument itself.
+  if (CheckTemplateArgument(Parm, DefaultTInfo)) {
+    Parm->setInvalidDecl();
+    return;
+  }
+
+  Parm->setDefaultArgument(DefaultTInfo, false);
+}
+
+/// \brief Check that the type of a non-type template parameter is
+/// well-formed.
+///
+/// \returns the (possibly-promoted) parameter type if valid;
+/// otherwise, produces a diagnostic and returns a NULL type.
+QualType
+Sema::CheckNonTypeTemplateParameterType(QualType T, SourceLocation Loc) {
+  // C++ [temp.param]p4:
+  //
+  // A non-type template-parameter shall have one of the following
+  // (optionally cv-qualified) types:
+  //
+  //       -- integral or enumeration type,
+  if (T->isIntegralType() || T->isEnumeralType() ||
+      //   -- pointer to object or pointer to function,
+      (T->isPointerType() &&
+       (T->getAs<PointerType>()->getPointeeType()->isObjectType() ||
+        T->getAs<PointerType>()->getPointeeType()->isFunctionType())) ||
+      //   -- reference to object or reference to function,
+      T->isReferenceType() ||
+      //   -- pointer to member.
+      T->isMemberPointerType() ||
+      // If T is a dependent type, we can't do the check now, so we
+      // assume that it is well-formed.
+      T->isDependentType())
+    return T;
+  // C++ [temp.param]p8:
+  //
+  //   A non-type template-parameter of type "array of T" or
+  //   "function returning T" is adjusted to be of type "pointer to
+  //   T" or "pointer to function returning T", respectively.
+  else if (T->isArrayType())
+    // FIXME: Keep the type prior to promotion?
+    return Context.getArrayDecayedType(T);
+  else if (T->isFunctionType())
+    // FIXME: Keep the type prior to promotion?
+    return Context.getPointerType(T);
+
+  Diag(Loc, diag::err_template_nontype_parm_bad_type)
+    << T;
+
+  return QualType();
+}
+
+/// ActOnNonTypeTemplateParameter - Called when a C++ non-type
+/// template parameter (e.g., "int Size" in "template<int Size>
+/// class Array") has been parsed. S is the current scope and D is
+/// the parsed declarator.
+Sema::DeclPtrTy Sema::ActOnNonTypeTemplateParameter(Scope *S, Declarator &D,
+                                                    unsigned Depth,
+                                                    unsigned Position) {
+  TypeSourceInfo *TInfo = 0;
+  QualType T = GetTypeForDeclarator(D, S, &TInfo);
+
+  assert(S->isTemplateParamScope() &&
+         "Non-type template parameter not in template parameter scope!");
+  bool Invalid = false;
+
+  IdentifierInfo *ParamName = D.getIdentifier();
+  if (ParamName) {
+    NamedDecl *PrevDecl = LookupSingleName(S, ParamName, D.getIdentifierLoc(),
+                                           LookupOrdinaryName,
+                                           ForRedeclaration);
+    if (PrevDecl && PrevDecl->isTemplateParameter())
+      Invalid = Invalid || DiagnoseTemplateParameterShadow(D.getIdentifierLoc(),
+                                                           PrevDecl);
+  }
+
+  T = CheckNonTypeTemplateParameterType(T, D.getIdentifierLoc());
+  if (T.isNull()) {
+    T = Context.IntTy; // Recover with an 'int' type.
+    Invalid = true;
+  }
+
+  NonTypeTemplateParmDecl *Param
+    = NonTypeTemplateParmDecl::Create(Context, Context.getTranslationUnitDecl(),
+                                      D.getIdentifierLoc(),
+                                      Depth, Position, ParamName, T, TInfo);
+  if (Invalid)
+    Param->setInvalidDecl();
+
+  if (D.getIdentifier()) {
+    // Add the template parameter into the current scope.
+    S->AddDecl(DeclPtrTy::make(Param));
+    IdResolver.AddDecl(Param);
+  }
+  return DeclPtrTy::make(Param);
+}
+
+/// \brief Adds a default argument to the given non-type template
+/// parameter.
+void Sema::ActOnNonTypeTemplateParameterDefault(DeclPtrTy TemplateParamD,
+                                                SourceLocation EqualLoc,
+                                                ExprArg DefaultE) {
+  NonTypeTemplateParmDecl *TemplateParm
+    = cast<NonTypeTemplateParmDecl>(TemplateParamD.getAs<Decl>());
+  Expr *Default = static_cast<Expr *>(DefaultE.get());
+
+  // C++ [temp.param]p14:
+  //   A template-parameter shall not be used in its own default argument.
+  // FIXME: Implement this check! Needs a recursive walk over the types.
+
+  // Check the well-formedness of the default template argument.
+  TemplateArgument Converted;
+  if (CheckTemplateArgument(TemplateParm, TemplateParm->getType(), Default,
+                            Converted)) {
+    TemplateParm->setInvalidDecl();
+    return;
+  }
+
+  TemplateParm->setDefaultArgument(DefaultE.takeAs<Expr>());
+}
+
+
+/// ActOnTemplateTemplateParameter - Called when a C++ template template
+/// parameter (e.g. T in template <template <typename> class T> class array)
+/// has been parsed. S is the current scope.
+Sema::DeclPtrTy Sema::ActOnTemplateTemplateParameter(Scope* S,
+                                                     SourceLocation TmpLoc,
+                                                     TemplateParamsTy *Params,
+                                                     IdentifierInfo *Name,
+                                                     SourceLocation NameLoc,
+                                                     unsigned Depth,
+                                                     unsigned Position) {
+  assert(S->isTemplateParamScope() &&
+         "Template template parameter not in template parameter scope!");
+
+  // Construct the parameter object.
+  TemplateTemplateParmDecl *Param =
+    TemplateTemplateParmDecl::Create(Context, Context.getTranslationUnitDecl(),
+                                     TmpLoc, Depth, Position, Name,
+                                     (TemplateParameterList*)Params);
+
+  // Make sure the parameter is valid.
+  // FIXME: Decl object is not currently invalidated anywhere so this doesn't
+  // do anything yet. However, if the template parameter list or (eventual)
+  // default value is ever invalidated, that will propagate here.
+  bool Invalid = false;
+  if (Invalid) {
+    Param->setInvalidDecl();
+  }
+
+  // If the tt-param has a name, then link the identifier into the scope
+  // and lookup mechanisms.
+  if (Name) {
+    S->AddDecl(DeclPtrTy::make(Param));
+    IdResolver.AddDecl(Param);
+  }
+
+  return DeclPtrTy::make(Param);
+}
+
+/// \brief Adds a default argument to the given template template
+/// parameter.
+void Sema::ActOnTemplateTemplateParameterDefault(DeclPtrTy TemplateParamD,
+                                                 SourceLocation EqualLoc,
+                                        const ParsedTemplateArgument &Default) {
+  TemplateTemplateParmDecl *TemplateParm
+    = cast<TemplateTemplateParmDecl>(TemplateParamD.getAs<Decl>());
+  
+  // C++ [temp.param]p14:
+  //   A template-parameter shall not be used in its own default argument.
+  // FIXME: Implement this check! Needs a recursive walk over the types.
+
+  // Check only that we have a template template argument. We don't want to
+  // try to check well-formedness now, because our template template parameter
+  // might have dependent types in its template parameters, which we wouldn't
+  // be able to match now.
+  //
+  // If none of the template template parameter's template arguments mention
+  // other template parameters, we could actually perform more checking here.
+  // However, it isn't worth doing.
+  TemplateArgumentLoc DefaultArg = translateTemplateArgument(*this, Default);
+  if (DefaultArg.getArgument().getAsTemplate().isNull()) {
+    Diag(DefaultArg.getLocation(), diag::err_template_arg_not_class_template)
+      << DefaultArg.getSourceRange();
+    return;
+  }
+  
+  TemplateParm->setDefaultArgument(DefaultArg);
+}
+
+/// ActOnTemplateParameterList - Builds a TemplateParameterList that
+/// contains the template parameters in Params/NumParams.
+Sema::TemplateParamsTy *
+Sema::ActOnTemplateParameterList(unsigned Depth,
+                                 SourceLocation ExportLoc,
+                                 SourceLocation TemplateLoc,
+                                 SourceLocation LAngleLoc,
+                                 DeclPtrTy *Params, unsigned NumParams,
+                                 SourceLocation RAngleLoc) {
+  if (ExportLoc.isValid())
+    Diag(ExportLoc, diag::warn_template_export_unsupported);
+
+  return TemplateParameterList::Create(Context, TemplateLoc, LAngleLoc,
+                                       (NamedDecl**)Params, NumParams, 
+                                       RAngleLoc);
+}
+
+static void SetNestedNameSpecifier(TagDecl *T, const CXXScopeSpec &SS) {
+  if (SS.isSet())
+    T->setQualifierInfo(static_cast<NestedNameSpecifier*>(SS.getScopeRep()),
+                        SS.getRange());
+}
+
+Sema::DeclResult
+Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK,
+                         SourceLocation KWLoc, CXXScopeSpec &SS,
+                         IdentifierInfo *Name, SourceLocation NameLoc,
+                         AttributeList *Attr,
+                         TemplateParameterList *TemplateParams,
+                         AccessSpecifier AS) {
+  assert(TemplateParams && TemplateParams->size() > 0 &&
+         "No template parameters");
+  assert(TUK != TUK_Reference && "Can only declare or define class templates");
+  bool Invalid = false;
+
+  // Check that we can declare a template here.
+  if (CheckTemplateDeclScope(S, TemplateParams))
+    return true;
+
+  TagDecl::TagKind Kind = TagDecl::getTagKindForTypeSpec(TagSpec);
+  assert(Kind != TagDecl::TK_enum && "can't build template of enumerated type");
+
+  // There is no such thing as an unnamed class template.
+  if (!Name) {
+    Diag(KWLoc, diag::err_template_unnamed_class);
+    return true;
+  }
+
+  // Find any previous declaration with this name.
+  DeclContext *SemanticContext;
+  LookupResult Previous(*this, Name, NameLoc, LookupOrdinaryName,
+                        ForRedeclaration);
+  if (SS.isNotEmpty() && !SS.isInvalid()) {
+    if (RequireCompleteDeclContext(SS))
+      return true;
+
+    SemanticContext = computeDeclContext(SS, true);
+    if (!SemanticContext) {
+      // FIXME: Produce a reasonable diagnostic here
+      return true;
+    }
+
+    LookupQualifiedName(Previous, SemanticContext);
+  } else {
+    SemanticContext = CurContext;
+    LookupName(Previous, S);
+  }
+
+  if (Previous.isAmbiguous())
+    return true;
+  
+  NamedDecl *PrevDecl = 0;
+  if (Previous.begin() != Previous.end())
+    PrevDecl = (*Previous.begin())->getUnderlyingDecl();
+
+  // If there is a previous declaration with the same name, check
+  // whether this is a valid redeclaration.
+  ClassTemplateDecl *PrevClassTemplate
+    = dyn_cast_or_null<ClassTemplateDecl>(PrevDecl);
+
+  // We may have found the injected-class-name of a class template,
+  // class template partial specialization, or class template specialization. 
+  // In these cases, grab the template that is being defined or specialized.
+  if (!PrevClassTemplate && PrevDecl && isa<CXXRecordDecl>(PrevDecl) && 
+      cast<CXXRecordDecl>(PrevDecl)->isInjectedClassName()) {
+    PrevDecl = cast<CXXRecordDecl>(PrevDecl->getDeclContext());
+    PrevClassTemplate 
+      = cast<CXXRecordDecl>(PrevDecl)->getDescribedClassTemplate();
+    if (!PrevClassTemplate && isa<ClassTemplateSpecializationDecl>(PrevDecl)) {
+      PrevClassTemplate
+        = cast<ClassTemplateSpecializationDecl>(PrevDecl)
+            ->getSpecializedTemplate();
+    }
+  }
+
+  if (TUK == TUK_Friend) {
+    // C++ [namespace.memdef]p3:
+    //   [...] When looking for a prior declaration of a class or a function 
+    //   declared as a friend, and when the name of the friend class or 
+    //   function is neither a qualified name nor a template-id, scopes outside
+    //   the innermost enclosing namespace scope are not considered.
+    if (!SS.isSet()) {
+      DeclContext *OutermostContext = CurContext;
+      while (!OutermostContext->isFileContext())
+        OutermostContext = OutermostContext->getLookupParent();
+
+      if (PrevDecl &&
+          (OutermostContext->Equals(PrevDecl->getDeclContext()) ||
+           OutermostContext->Encloses(PrevDecl->getDeclContext()))) {
+        SemanticContext = PrevDecl->getDeclContext();
+      } else {
+        // Declarations in outer scopes don't matter. However, the outermost
+        // context we computed is the semantic context for our new 
+        // declaration.
+        PrevDecl = PrevClassTemplate = 0;
+        SemanticContext = OutermostContext;
+      }
+    }
+
+    if (CurContext->isDependentContext()) {
+      // If this is a dependent context, we don't want to link the friend
+      // class template to the template in scope, because that would perform
+      // checking of the template parameter lists that can't be performed
+      // until the outer context is instantiated.
+      PrevDecl = PrevClassTemplate = 0;
+    }
+  } else if (PrevDecl && !isDeclInScope(PrevDecl, SemanticContext, S))
+    PrevDecl = PrevClassTemplate = 0;
+  
+  if (PrevClassTemplate) {
+    // Ensure that the template parameter lists are compatible.
+    if (!TemplateParameterListsAreEqual(TemplateParams,
+                                   PrevClassTemplate->getTemplateParameters(),
+                                        /*Complain=*/true,
+                                        TPL_TemplateMatch))
+      return true;
+
+    // C++ [temp.class]p4:
+    //   In a redeclaration, partial specialization, explicit
+    //   specialization or explicit instantiation of a class template,
+    //   the class-key shall agree in kind with the original class
+    //   template declaration (7.1.5.3).
+    RecordDecl *PrevRecordDecl = PrevClassTemplate->getTemplatedDecl();
+    if (!isAcceptableTagRedeclaration(PrevRecordDecl, Kind, KWLoc, *Name)) {
+      Diag(KWLoc, diag::err_use_with_wrong_tag)
+        << Name
+        << FixItHint::CreateReplacement(KWLoc, PrevRecordDecl->getKindName());
+      Diag(PrevRecordDecl->getLocation(), diag::note_previous_use);
+      Kind = PrevRecordDecl->getTagKind();
+    }
+
+    // Check for redefinition of this class template.
+    if (TUK == TUK_Definition) {
+      if (TagDecl *Def = PrevRecordDecl->getDefinition()) {
+        Diag(NameLoc, diag::err_redefinition) << Name;
+        Diag(Def->getLocation(), diag::note_previous_definition);
+        // FIXME: Would it make sense to try to "forget" the previous
+        // definition, as part of error recovery?
+        return true;
+      }
+    }
+  } else if (PrevDecl && PrevDecl->isTemplateParameter()) {
+    // Maybe we will complain about the shadowed template parameter.
+    DiagnoseTemplateParameterShadow(NameLoc, PrevDecl);
+    // Just pretend that we didn't see the previous declaration.
+    PrevDecl = 0;
+  } else if (PrevDecl) {
+    // C++ [temp]p5:
+    //   A class template shall not have the same name as any other
+    //   template, class, function, object, enumeration, enumerator,
+    //   namespace, or type in the same scope (3.3), except as specified
+    //   in (14.5.4).
+    Diag(NameLoc, diag::err_redefinition_different_kind) << Name;
+    Diag(PrevDecl->getLocation(), diag::note_previous_definition);
+    return true;
+  }
+
+  // Check the template parameter list of this declaration, possibly
+  // merging in the template parameter list from the previous class
+  // template declaration.
+  if (CheckTemplateParameterList(TemplateParams,
+            PrevClassTemplate? PrevClassTemplate->getTemplateParameters() : 0,
+                                 TPC_ClassTemplate))
+    Invalid = true;
+
+  if (SS.isSet()) {
+    // If the name of the template was qualified, we must be defining the 
+    // template out-of-line.
+    if (!SS.isInvalid() && !Invalid && !PrevClassTemplate &&
+        !(TUK == TUK_Friend && CurContext->isDependentContext()))
+      Diag(NameLoc, diag::err_member_def_does_not_match)
+        << Name << SemanticContext << SS.getRange();
+  } 
+  
+  CXXRecordDecl *NewClass =
+    CXXRecordDecl::Create(Context, Kind, SemanticContext, NameLoc, Name, KWLoc,
+                          PrevClassTemplate?
+                            PrevClassTemplate->getTemplatedDecl() : 0,
+                          /*DelayTypeCreation=*/true);
+  SetNestedNameSpecifier(NewClass, SS);
+
+  ClassTemplateDecl *NewTemplate
+    = ClassTemplateDecl::Create(Context, SemanticContext, NameLoc,
+                                DeclarationName(Name), TemplateParams,
+                                NewClass, PrevClassTemplate);
+  NewClass->setDescribedClassTemplate(NewTemplate);
+
+  // Build the type for the class template declaration now.
+  QualType T = NewTemplate->getInjectedClassNameSpecialization(Context);
+  T = Context.getInjectedClassNameType(NewClass, T);
+  assert(T->isDependentType() && "Class template type is not dependent?");
+  (void)T;
+
+  // If we are providing an explicit specialization of a member that is a 
+  // class template, make a note of that.
+  if (PrevClassTemplate && 
+      PrevClassTemplate->getInstantiatedFromMemberTemplate())
+    PrevClassTemplate->setMemberSpecialization();
+  
+  // Set the access specifier.
+  if (!Invalid && TUK != TUK_Friend)
+    SetMemberAccessSpecifier(NewTemplate, PrevClassTemplate, AS);
+
+  // Set the lexical context of these templates
+  NewClass->setLexicalDeclContext(CurContext);
+  NewTemplate->setLexicalDeclContext(CurContext);
+
+  if (TUK == TUK_Definition)
+    NewClass->startDefinition();
+
+  if (Attr)
+    ProcessDeclAttributeList(S, NewClass, Attr);
+
+  if (TUK != TUK_Friend)
+    PushOnScopeChains(NewTemplate, S);
+  else {
+    if (PrevClassTemplate && PrevClassTemplate->getAccess() != AS_none) {
+      NewTemplate->setAccess(PrevClassTemplate->getAccess());
+      NewClass->setAccess(PrevClassTemplate->getAccess());
+    }
+
+    NewTemplate->setObjectOfFriendDecl(/* PreviouslyDeclared = */
+                                       PrevClassTemplate != NULL);
+    
+    // Friend templates are visible in fairly strange ways.
+    if (!CurContext->isDependentContext()) {
+      DeclContext *DC = SemanticContext->getLookupContext();
+      DC->makeDeclVisibleInContext(NewTemplate, /* Recoverable = */ false);
+      if (Scope *EnclosingScope = getScopeForDeclContext(S, DC))
+        PushOnScopeChains(NewTemplate, EnclosingScope,
+                          /* AddToContext = */ false);      
+    }
+    
+    FriendDecl *Friend = FriendDecl::Create(Context, CurContext,
+                                            NewClass->getLocation(),
+                                            NewTemplate,
+                                    /*FIXME:*/NewClass->getLocation());
+    Friend->setAccess(AS_public);
+    CurContext->addDecl(Friend);
+  }
+
+  if (Invalid) {
+    NewTemplate->setInvalidDecl();
+    NewClass->setInvalidDecl();
+  }
+  return DeclPtrTy::make(NewTemplate);
+}
+
+/// \brief Diagnose the presence of a default template argument on a
+/// template parameter, which is ill-formed in certain contexts.
+///
+/// \returns true if the default template argument should be dropped.
+static bool DiagnoseDefaultTemplateArgument(Sema &S, 
+                                            Sema::TemplateParamListContext TPC,
+                                            SourceLocation ParamLoc,
+                                            SourceRange DefArgRange) {
+  switch (TPC) {
+  case Sema::TPC_ClassTemplate:
+    return false;
+
+  case Sema::TPC_FunctionTemplate:
+    // C++ [temp.param]p9: 
+    //   A default template-argument shall not be specified in a
+    //   function template declaration or a function template
+    //   definition [...]
+    // (This sentence is not in C++0x, per DR226).
+    if (!S.getLangOptions().CPlusPlus0x)
+      S.Diag(ParamLoc, 
+             diag::err_template_parameter_default_in_function_template)
+        << DefArgRange;
+    return false;
+
+  case Sema::TPC_ClassTemplateMember:
+    // C++0x [temp.param]p9:
+    //   A default template-argument shall not be specified in the
+    //   template-parameter-lists of the definition of a member of a
+    //   class template that appears outside of the member's class.
+    S.Diag(ParamLoc, diag::err_template_parameter_default_template_member)
+      << DefArgRange;
+    return true;
+
+  case Sema::TPC_FriendFunctionTemplate:
+    // C++ [temp.param]p9:
+    //   A default template-argument shall not be specified in a
+    //   friend template declaration.
+    S.Diag(ParamLoc, diag::err_template_parameter_default_friend_template)
+      << DefArgRange;
+    return true;
+
+    // FIXME: C++0x [temp.param]p9 allows default template-arguments
+    // for friend function templates if there is only a single
+    // declaration (and it is a definition). Strange!
+  }
+
+  return false;
+}
+
+/// \brief Checks the validity of a template parameter list, possibly
+/// considering the template parameter list from a previous
+/// declaration.
+///
+/// If an "old" template parameter list is provided, it must be
+/// equivalent (per TemplateParameterListsAreEqual) to the "new"
+/// template parameter list.
+///
+/// \param NewParams Template parameter list for a new template
+/// declaration. This template parameter list will be updated with any
+/// default arguments that are carried through from the previous
+/// template parameter list.
+///
+/// \param OldParams If provided, template parameter list from a
+/// previous declaration of the same template. Default template
+/// arguments will be merged from the old template parameter list to
+/// the new template parameter list.
+///
+/// \param TPC Describes the context in which we are checking the given
+/// template parameter list.
+///
+/// \returns true if an error occurred, false otherwise.
+bool Sema::CheckTemplateParameterList(TemplateParameterList *NewParams,
+                                      TemplateParameterList *OldParams,
+                                      TemplateParamListContext TPC) {
+  bool Invalid = false;
+
+  // C++ [temp.param]p10:
+  //   The set of default template-arguments available for use with a
+  //   template declaration or definition is obtained by merging the
+  //   default arguments from the definition (if in scope) and all
+  //   declarations in scope in the same way default function
+  //   arguments are (8.3.6).
+  bool SawDefaultArgument = false;
+  SourceLocation PreviousDefaultArgLoc;
+
+  bool SawParameterPack = false;
+  SourceLocation ParameterPackLoc;
+
+  // Dummy initialization to avoid warnings.
+  TemplateParameterList::iterator OldParam = NewParams->end();
+  if (OldParams)
+    OldParam = OldParams->begin();
+
+  for (TemplateParameterList::iterator NewParam = NewParams->begin(),
+                                    NewParamEnd = NewParams->end();
+       NewParam != NewParamEnd; ++NewParam) {
+    // Variables used to diagnose redundant default arguments
+    bool RedundantDefaultArg = false;
+    SourceLocation OldDefaultLoc;
+    SourceLocation NewDefaultLoc;
+
+    // Variables used to diagnose missing default arguments
+    bool MissingDefaultArg = false;
+
+    // C++0x [temp.param]p11:
+    // If a template parameter of a class template is a template parameter pack,
+    // it must be the last template parameter.
+    if (SawParameterPack) {
+      Diag(ParameterPackLoc,
+           diag::err_template_param_pack_must_be_last_template_parameter);
+      Invalid = true;
+    }
+
+    if (TemplateTypeParmDecl *NewTypeParm
+          = dyn_cast<TemplateTypeParmDecl>(*NewParam)) {
+      // Check the presence of a default argument here.
+      if (NewTypeParm->hasDefaultArgument() && 
+          DiagnoseDefaultTemplateArgument(*this, TPC, 
+                                          NewTypeParm->getLocation(), 
+               NewTypeParm->getDefaultArgumentInfo()->getTypeLoc()
+                                                       .getFullSourceRange()))
+        NewTypeParm->removeDefaultArgument();
+
+      // Merge default arguments for template type parameters.
+      TemplateTypeParmDecl *OldTypeParm
+          = OldParams? cast<TemplateTypeParmDecl>(*OldParam) : 0;
+
+      if (NewTypeParm->isParameterPack()) {
+        assert(!NewTypeParm->hasDefaultArgument() &&
+               "Parameter packs can't have a default argument!");
+        SawParameterPack = true;
+        ParameterPackLoc = NewTypeParm->getLocation();
+      } else if (OldTypeParm && OldTypeParm->hasDefaultArgument() &&
+                 NewTypeParm->hasDefaultArgument()) {
+        OldDefaultLoc = OldTypeParm->getDefaultArgumentLoc();
+        NewDefaultLoc = NewTypeParm->getDefaultArgumentLoc();
+        SawDefaultArgument = true;
+        RedundantDefaultArg = true;
+        PreviousDefaultArgLoc = NewDefaultLoc;
+      } else if (OldTypeParm && OldTypeParm->hasDefaultArgument()) {
+        // Merge the default argument from the old declaration to the
+        // new declaration.
+        SawDefaultArgument = true;
+        NewTypeParm->setDefaultArgument(OldTypeParm->getDefaultArgumentInfo(),
+                                        true);
+        PreviousDefaultArgLoc = OldTypeParm->getDefaultArgumentLoc();
+      } else if (NewTypeParm->hasDefaultArgument()) {
+        SawDefaultArgument = true;
+        PreviousDefaultArgLoc = NewTypeParm->getDefaultArgumentLoc();
+      } else if (SawDefaultArgument)
+        MissingDefaultArg = true;
+    } else if (NonTypeTemplateParmDecl *NewNonTypeParm
+               = dyn_cast<NonTypeTemplateParmDecl>(*NewParam)) {
+      // Check the presence of a default argument here.
+      if (NewNonTypeParm->hasDefaultArgument() && 
+          DiagnoseDefaultTemplateArgument(*this, TPC, 
+                                          NewNonTypeParm->getLocation(), 
+                    NewNonTypeParm->getDefaultArgument()->getSourceRange())) {
+        NewNonTypeParm->getDefaultArgument()->Destroy(Context);
+        NewNonTypeParm->setDefaultArgument(0);
+      }
+
+      // Merge default arguments for non-type template parameters
+      NonTypeTemplateParmDecl *OldNonTypeParm
+        = OldParams? cast<NonTypeTemplateParmDecl>(*OldParam) : 0;
+      if (OldNonTypeParm && OldNonTypeParm->hasDefaultArgument() &&
+          NewNonTypeParm->hasDefaultArgument()) {
+        OldDefaultLoc = OldNonTypeParm->getDefaultArgumentLoc();
+        NewDefaultLoc = NewNonTypeParm->getDefaultArgumentLoc();
+        SawDefaultArgument = true;
+        RedundantDefaultArg = true;
+        PreviousDefaultArgLoc = NewDefaultLoc;
+      } else if (OldNonTypeParm && OldNonTypeParm->hasDefaultArgument()) {
+        // Merge the default argument from the old declaration to the
+        // new declaration.
+        SawDefaultArgument = true;
+        // FIXME: We need to create a new kind of "default argument"
+        // expression that points to a previous template template
+        // parameter.
+        NewNonTypeParm->setDefaultArgument(
+                                        OldNonTypeParm->getDefaultArgument());
+        PreviousDefaultArgLoc = OldNonTypeParm->getDefaultArgumentLoc();
+      } else if (NewNonTypeParm->hasDefaultArgument()) {
+        SawDefaultArgument = true;
+        PreviousDefaultArgLoc = NewNonTypeParm->getDefaultArgumentLoc();
+      } else if (SawDefaultArgument)
+        MissingDefaultArg = true;
+    } else {
+      // Check the presence of a default argument here.
+      TemplateTemplateParmDecl *NewTemplateParm
+        = cast<TemplateTemplateParmDecl>(*NewParam);
+      if (NewTemplateParm->hasDefaultArgument() && 
+          DiagnoseDefaultTemplateArgument(*this, TPC, 
+                                          NewTemplateParm->getLocation(), 
+                     NewTemplateParm->getDefaultArgument().getSourceRange()))
+        NewTemplateParm->setDefaultArgument(TemplateArgumentLoc());
+
+      // Merge default arguments for template template parameters
+      TemplateTemplateParmDecl *OldTemplateParm
+        = OldParams? cast<TemplateTemplateParmDecl>(*OldParam) : 0;
+      if (OldTemplateParm && OldTemplateParm->hasDefaultArgument() &&
+          NewTemplateParm->hasDefaultArgument()) {
+        OldDefaultLoc = OldTemplateParm->getDefaultArgument().getLocation();
+        NewDefaultLoc = NewTemplateParm->getDefaultArgument().getLocation();
+        SawDefaultArgument = true;
+        RedundantDefaultArg = true;
+        PreviousDefaultArgLoc = NewDefaultLoc;
+      } else if (OldTemplateParm && OldTemplateParm->hasDefaultArgument()) {
+        // Merge the default argument from the old declaration to the
+        // new declaration.
+        SawDefaultArgument = true;
+        // FIXME: We need to create a new kind of "default argument" expression
+        // that points to a previous template template parameter.
+        NewTemplateParm->setDefaultArgument(
+                                        OldTemplateParm->getDefaultArgument());
+        PreviousDefaultArgLoc
+          = OldTemplateParm->getDefaultArgument().getLocation();
+      } else if (NewTemplateParm->hasDefaultArgument()) {
+        SawDefaultArgument = true;
+        PreviousDefaultArgLoc
+          = NewTemplateParm->getDefaultArgument().getLocation();
+      } else if (SawDefaultArgument)
+        MissingDefaultArg = true;
+    }
+
+    if (RedundantDefaultArg) {
+      // C++ [temp.param]p12:
+      //   A template-parameter shall not be given default arguments
+      //   by two different declarations in the same scope.
+      Diag(NewDefaultLoc, diag::err_template_param_default_arg_redefinition);
+      Diag(OldDefaultLoc, diag::note_template_param_prev_default_arg);
+      Invalid = true;
+    } else if (MissingDefaultArg) {
+      // C++ [temp.param]p11:
+      //   If a template-parameter has a default template-argument,
+      //   all subsequent template-parameters shall have a default
+      //   template-argument supplied.
+      Diag((*NewParam)->getLocation(),
+           diag::err_template_param_default_arg_missing);
+      Diag(PreviousDefaultArgLoc, diag::note_template_param_prev_default_arg);
+      Invalid = true;
+    }
+
+    // If we have an old template parameter list that we're merging
+    // in, move on to the next parameter.
+    if (OldParams)
+      ++OldParam;
+  }
+
+  return Invalid;
+}
+
+/// \brief Match the given template parameter lists to the given scope
+/// specifier, returning the template parameter list that applies to the
+/// name.
+///
+/// \param DeclStartLoc the start of the declaration that has a scope
+/// specifier or a template parameter list.
+///
+/// \param SS the scope specifier that will be matched to the given template
+/// parameter lists. This scope specifier precedes a qualified name that is
+/// being declared.
+///
+/// \param ParamLists the template parameter lists, from the outermost to the
+/// innermost template parameter lists.
+///
+/// \param NumParamLists the number of template parameter lists in ParamLists.
+///
+/// \param IsFriend Whether to apply the slightly different rules for
+/// matching template parameters to scope specifiers in friend
+/// declarations.
+///
+/// \param IsExplicitSpecialization will be set true if the entity being
+/// declared is an explicit specialization, false otherwise.
+///
+/// \returns the template parameter list, if any, that corresponds to the
+/// name that is preceded by the scope specifier @p SS. This template
+/// parameter list may be have template parameters (if we're declaring a
+/// template) or may have no template parameters (if we're declaring a
+/// template specialization), or may be NULL (if we were's declaring isn't
+/// itself a template).
+TemplateParameterList *
+Sema::MatchTemplateParametersToScopeSpecifier(SourceLocation DeclStartLoc,
+                                              const CXXScopeSpec &SS,
+                                          TemplateParameterList **ParamLists,
+                                              unsigned NumParamLists,
+                                              bool IsFriend,
+                                              bool &IsExplicitSpecialization) {
+  IsExplicitSpecialization = false;
+  
+  // Find the template-ids that occur within the nested-name-specifier. These
+  // template-ids will match up with the template parameter lists.
+  llvm::SmallVector<const TemplateSpecializationType *, 4>
+    TemplateIdsInSpecifier;
+  llvm::SmallVector<ClassTemplateSpecializationDecl *, 4>
+    ExplicitSpecializationsInSpecifier;
+  for (NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
+       NNS; NNS = NNS->getPrefix()) {
+    const Type *T = NNS->getAsType();
+    if (!T) break;
+
+    // C++0x [temp.expl.spec]p17:
+    //   A member or a member template may be nested within many
+    //   enclosing class templates. In an explicit specialization for
+    //   such a member, the member declaration shall be preceded by a
+    //   template<> for each enclosing class template that is
+    //   explicitly specialized.
+    //
+    // Following the existing practice of GNU and EDG, we allow a typedef of a
+    // template specialization type.
+    if (const TypedefType *TT = dyn_cast<TypedefType>(T))
+      T = TT->LookThroughTypedefs().getTypePtr();
+
+    if (const TemplateSpecializationType *SpecType
+                                  = dyn_cast<TemplateSpecializationType>(T)) {
+      TemplateDecl *Template = SpecType->getTemplateName().getAsTemplateDecl();
+      if (!Template)
+        continue; // FIXME: should this be an error? probably...
+
+      if (const RecordType *Record = SpecType->getAs<RecordType>()) {
+        ClassTemplateSpecializationDecl *SpecDecl
+          = cast<ClassTemplateSpecializationDecl>(Record->getDecl());
+        // If the nested name specifier refers to an explicit specialization,
+        // we don't need a template<> header.
+        if (SpecDecl->getSpecializationKind() == TSK_ExplicitSpecialization) {
+          ExplicitSpecializationsInSpecifier.push_back(SpecDecl);
+          continue;
+        }
+      }
+
+      TemplateIdsInSpecifier.push_back(SpecType);
+    }
+  }
+
+  // Reverse the list of template-ids in the scope specifier, so that we can
+  // more easily match up the template-ids and the template parameter lists.
+  std::reverse(TemplateIdsInSpecifier.begin(), TemplateIdsInSpecifier.end());
+
+  SourceLocation FirstTemplateLoc = DeclStartLoc;
+  if (NumParamLists)
+    FirstTemplateLoc = ParamLists[0]->getTemplateLoc();
+
+  // Match the template-ids found in the specifier to the template parameter
+  // lists.
+  unsigned Idx = 0;
+  for (unsigned NumTemplateIds = TemplateIdsInSpecifier.size();
+       Idx != NumTemplateIds; ++Idx) {
+    QualType TemplateId = QualType(TemplateIdsInSpecifier[Idx], 0);
+    bool DependentTemplateId = TemplateId->isDependentType();
+    if (Idx >= NumParamLists) {
+      // We have a template-id without a corresponding template parameter
+      // list.
+
+      // ...which is fine if this is a friend declaration.
+      if (IsFriend) {
+        IsExplicitSpecialization = true;
+        break;
+      }
+
+      if (DependentTemplateId) {
+        // FIXME: the location information here isn't great.
+        Diag(SS.getRange().getBegin(),
+             diag::err_template_spec_needs_template_parameters)
+          << TemplateId
+          << SS.getRange();
+      } else {
+        Diag(SS.getRange().getBegin(), diag::err_template_spec_needs_header)
+          << SS.getRange()
+          << FixItHint::CreateInsertion(FirstTemplateLoc, "template<> ");
+        IsExplicitSpecialization = true;
+      }
+      return 0;
+    }
+
+    // Check the template parameter list against its corresponding template-id.
+    if (DependentTemplateId) {
+      TemplateParameterList *ExpectedTemplateParams = 0;
+
+      // Are there cases in (e.g.) friends where this won't match?
+      if (const InjectedClassNameType *Injected
+            = TemplateId->getAs<InjectedClassNameType>()) {
+        CXXRecordDecl *Record = Injected->getDecl();
+        if (ClassTemplatePartialSpecializationDecl *Partial =
+              dyn_cast<ClassTemplatePartialSpecializationDecl>(Record))
+          ExpectedTemplateParams = Partial->getTemplateParameters();
+        else
+          ExpectedTemplateParams = Record->getDescribedClassTemplate()
+            ->getTemplateParameters();
+      }
+
+      if (ExpectedTemplateParams)
+        TemplateParameterListsAreEqual(ParamLists[Idx],
+                                       ExpectedTemplateParams,
+                                       true, TPL_TemplateMatch);
+
+      CheckTemplateParameterList(ParamLists[Idx], 0, TPC_ClassTemplateMember);
+    } else if (ParamLists[Idx]->size() > 0)
+      Diag(ParamLists[Idx]->getTemplateLoc(),
+           diag::err_template_param_list_matches_nontemplate)
+        << TemplateId
+        << ParamLists[Idx]->getSourceRange();
+    else
+      IsExplicitSpecialization = true;
+  }
+
+  // If there were at least as many template-ids as there were template
+  // parameter lists, then there are no template parameter lists remaining for
+  // the declaration itself.
+  if (Idx >= NumParamLists)
+    return 0;
+
+  // If there were too many template parameter lists, complain about that now.
+  if (Idx != NumParamLists - 1) {
+    while (Idx < NumParamLists - 1) {
+      bool isExplicitSpecHeader = ParamLists[Idx]->size() == 0;
+      Diag(ParamLists[Idx]->getTemplateLoc(),
+           isExplicitSpecHeader? diag::warn_template_spec_extra_headers
+                               : diag::err_template_spec_extra_headers)
+        << SourceRange(ParamLists[Idx]->getTemplateLoc(),
+                       ParamLists[Idx]->getRAngleLoc());
+
+      if (isExplicitSpecHeader && !ExplicitSpecializationsInSpecifier.empty()) {
+        Diag(ExplicitSpecializationsInSpecifier.back()->getLocation(),
+             diag::note_explicit_template_spec_does_not_need_header)
+          << ExplicitSpecializationsInSpecifier.back();
+        ExplicitSpecializationsInSpecifier.pop_back();
+      }
+        
+      ++Idx;
+    }
+  }
+
+  // Return the last template parameter list, which corresponds to the
+  // entity being declared.
+  return ParamLists[NumParamLists - 1];
+}
+
+QualType Sema::CheckTemplateIdType(TemplateName Name,
+                                   SourceLocation TemplateLoc,
+                              const TemplateArgumentListInfo &TemplateArgs) {
+  TemplateDecl *Template = Name.getAsTemplateDecl();
+  if (!Template) {
+    // The template name does not resolve to a template, so we just
+    // build a dependent template-id type.
+    return Context.getTemplateSpecializationType(Name, TemplateArgs);
+  }
+
+  // Check that the template argument list is well-formed for this
+  // template.
+  TemplateArgumentListBuilder Converted(Template->getTemplateParameters(),
+                                        TemplateArgs.size());
+  if (CheckTemplateArgumentList(Template, TemplateLoc, TemplateArgs,
+                                false, Converted))
+    return QualType();
+
+  assert((Converted.structuredSize() ==
+            Template->getTemplateParameters()->size()) &&
+         "Converted template argument list is too short!");
+
+  QualType CanonType;
+  bool IsCurrentInstantiation = false;
+
+  if (Name.isDependent() ||
+      TemplateSpecializationType::anyDependentTemplateArguments(
+                                                      TemplateArgs)) {
+    // This class template specialization is a dependent
+    // type. Therefore, its canonical type is another class template
+    // specialization type that contains all of the converted
+    // arguments in canonical form. This ensures that, e.g., A<T> and
+    // A<T, T> have identical types when A is declared as:
+    //
+    //   template<typename T, typename U = T> struct A;
+    TemplateName CanonName = Context.getCanonicalTemplateName(Name);
+    CanonType = Context.getTemplateSpecializationType(CanonName,
+                                                   Converted.getFlatArguments(),
+                                                   Converted.flatSize());
+
+    // FIXME: CanonType is not actually the canonical type, and unfortunately
+    // it is a TemplateSpecializationType that we will never use again.
+    // In the future, we need to teach getTemplateSpecializationType to only
+    // build the canonical type and return that to us.
+    CanonType = Context.getCanonicalType(CanonType);
+
+    // This might work out to be a current instantiation, in which
+    // case the canonical type needs to be the InjectedClassNameType.
+    //
+    // TODO: in theory this could be a simple hashtable lookup; most
+    // changes to CurContext don't change the set of current
+    // instantiations.
+    if (isa<ClassTemplateDecl>(Template)) {
+      for (DeclContext *Ctx = CurContext; Ctx; Ctx = Ctx->getLookupParent()) {
+        // If we get out to a namespace, we're done.
+        if (Ctx->isFileContext()) break;
+
+        // If this isn't a record, keep looking.
+        CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(Ctx);
+        if (!Record) continue;
+
+        // Look for one of the two cases with InjectedClassNameTypes
+        // and check whether it's the same template.
+        if (!isa<ClassTemplatePartialSpecializationDecl>(Record) &&
+            !Record->getDescribedClassTemplate())
+          continue;
+          
+        // Fetch the injected class name type and check whether its
+        // injected type is equal to the type we just built.
+        QualType ICNT = Context.getTypeDeclType(Record);
+        QualType Injected = cast<InjectedClassNameType>(ICNT)
+          ->getInjectedSpecializationType();
+
+        if (CanonType != Injected->getCanonicalTypeInternal())
+          continue;
+
+        // If so, the canonical type of this TST is the injected
+        // class name type of the record we just found.
+        assert(ICNT.isCanonical());
+        CanonType = ICNT;
+        IsCurrentInstantiation = true;
+        break;
+      }
+    }
+  } else if (ClassTemplateDecl *ClassTemplate
+               = dyn_cast<ClassTemplateDecl>(Template)) {
+    // Find the class template specialization declaration that
+    // corresponds to these arguments.
+    llvm::FoldingSetNodeID ID;
+    ClassTemplateSpecializationDecl::Profile(ID,
+                                             Converted.getFlatArguments(),
+                                             Converted.flatSize(),
+                                             Context);
+    void *InsertPos = 0;
+    ClassTemplateSpecializationDecl *Decl
+      = ClassTemplate->getSpecializations().FindNodeOrInsertPos(ID, InsertPos);
+    if (!Decl) {
+      // This is the first time we have referenced this class template
+      // specialization. Create the canonical declaration and add it to
+      // the set of specializations.
+      Decl = ClassTemplateSpecializationDecl::Create(Context,
+                                    ClassTemplate->getDeclContext(),
+                                    ClassTemplate->getLocation(),
+                                    ClassTemplate,
+                                    Converted, 0);
+      ClassTemplate->getSpecializations().InsertNode(Decl, InsertPos);
+      Decl->setLexicalDeclContext(CurContext);
+    }
+
+    CanonType = Context.getTypeDeclType(Decl);
+    assert(isa<RecordType>(CanonType) &&
+           "type of non-dependent specialization is not a RecordType");
+  }
+
+  // Build the fully-sugared type for this class template
+  // specialization, which refers back to the class template
+  // specialization we created or found.
+  return Context.getTemplateSpecializationType(Name, TemplateArgs, CanonType,
+                                               IsCurrentInstantiation);
+}
+
+Action::TypeResult
+Sema::ActOnTemplateIdType(TemplateTy TemplateD, SourceLocation TemplateLoc,
+                          SourceLocation LAngleLoc,
+                          ASTTemplateArgsPtr TemplateArgsIn,
+                          SourceLocation RAngleLoc) {
+  TemplateName Template = TemplateD.getAsVal<TemplateName>();
+
+  // Translate the parser's template argument list in our AST format.
+  TemplateArgumentListInfo TemplateArgs(LAngleLoc, RAngleLoc);
+  translateTemplateArguments(TemplateArgsIn, TemplateArgs);
+
+  QualType Result = CheckTemplateIdType(Template, TemplateLoc, TemplateArgs);
+  TemplateArgsIn.release();
+
+  if (Result.isNull())
+    return true;
+
+  TypeSourceInfo *DI = Context.CreateTypeSourceInfo(Result);
+  TemplateSpecializationTypeLoc TL
+    = cast<TemplateSpecializationTypeLoc>(DI->getTypeLoc());
+  TL.setTemplateNameLoc(TemplateLoc);
+  TL.setLAngleLoc(LAngleLoc);
+  TL.setRAngleLoc(RAngleLoc);
+  for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i)
+    TL.setArgLocInfo(i, TemplateArgs[i].getLocInfo());
+
+  return CreateLocInfoType(Result, DI).getAsOpaquePtr();
+}
+
+Sema::TypeResult Sema::ActOnTagTemplateIdType(TypeResult TypeResult,
+                                              TagUseKind TUK,
+                                              DeclSpec::TST TagSpec,
+                                              SourceLocation TagLoc) {
+  if (TypeResult.isInvalid())
+    return Sema::TypeResult();
+
+  // FIXME: preserve source info, ideally without copying the DI.
+  TypeSourceInfo *DI;
+  QualType Type = GetTypeFromParser(TypeResult.get(), &DI);
+
+  // Verify the tag specifier.
+  TagDecl::TagKind TagKind = TagDecl::getTagKindForTypeSpec(TagSpec);
+
+  if (const RecordType *RT = Type->getAs<RecordType>()) {
+    RecordDecl *D = RT->getDecl();
+
+    IdentifierInfo *Id = D->getIdentifier();
+    assert(Id && "templated class must have an identifier");
+
+    if (!isAcceptableTagRedeclaration(D, TagKind, TagLoc, *Id)) {
+      Diag(TagLoc, diag::err_use_with_wrong_tag)
+        << Type
+        << FixItHint::CreateReplacement(SourceRange(TagLoc), D->getKindName());
+      Diag(D->getLocation(), diag::note_previous_use);
+    }
+  }
+
+  QualType ElabType = Context.getElaboratedType(Type, TagKind);
+
+  return ElabType.getAsOpaquePtr();
+}
+
+Sema::OwningExprResult Sema::BuildTemplateIdExpr(const CXXScopeSpec &SS,
+                                                 LookupResult &R,
+                                                 bool RequiresADL,
+                                 const TemplateArgumentListInfo &TemplateArgs) {
+  // FIXME: Can we do any checking at this point? I guess we could check the
+  // template arguments that we have against the template name, if the template
+  // name refers to a single template. That's not a terribly common case,
+  // though.
+
+  // These should be filtered out by our callers.
+  assert(!R.empty() && "empty lookup results when building templateid");
+  assert(!R.isAmbiguous() && "ambiguous lookup when building templateid");
+
+  NestedNameSpecifier *Qualifier = 0;
+  SourceRange QualifierRange;
+  if (SS.isSet()) {
+    Qualifier = static_cast<NestedNameSpecifier*>(SS.getScopeRep());
+    QualifierRange = SS.getRange();
+  }
+
+  // We don't want lookup warnings at this point.
+  R.suppressDiagnostics();
+  
+  bool Dependent
+    = UnresolvedLookupExpr::ComputeDependence(R.begin(), R.end(),
+                                              &TemplateArgs);
+  UnresolvedLookupExpr *ULE
+    = UnresolvedLookupExpr::Create(Context, Dependent, R.getNamingClass(),
+                                   Qualifier, QualifierRange,
+                                   R.getLookupName(), R.getNameLoc(),
+                                   RequiresADL, TemplateArgs);
+  ULE->addDecls(R.begin(), R.end());
+
+  return Owned(ULE);
+}
+
+// We actually only call this from template instantiation.
+Sema::OwningExprResult
+Sema::BuildQualifiedTemplateIdExpr(CXXScopeSpec &SS,
+                                   DeclarationName Name,
+                                   SourceLocation NameLoc,
+                             const TemplateArgumentListInfo &TemplateArgs) {
+  DeclContext *DC;
+  if (!(DC = computeDeclContext(SS, false)) ||
+      DC->isDependentContext() ||
+      RequireCompleteDeclContext(SS))
+    return BuildDependentDeclRefExpr(SS, Name, NameLoc, &TemplateArgs);
+
+  LookupResult R(*this, Name, NameLoc, LookupOrdinaryName);
+  LookupTemplateName(R, (Scope*) 0, SS, QualType(), /*Entering*/ false);
+
+  if (R.isAmbiguous())
+    return ExprError();
+  
+  if (R.empty()) {
+    Diag(NameLoc, diag::err_template_kw_refers_to_non_template)
+      << Name << SS.getRange();
+    return ExprError();
+  }
+
+  if (ClassTemplateDecl *Temp = R.getAsSingle<ClassTemplateDecl>()) {
+    Diag(NameLoc, diag::err_template_kw_refers_to_class_template)
+      << (NestedNameSpecifier*) SS.getScopeRep() << Name << SS.getRange();
+    Diag(Temp->getLocation(), diag::note_referenced_class_template);
+    return ExprError();
+  }
+
+  return BuildTemplateIdExpr(SS, R, /* ADL */ false, TemplateArgs);
+}
+
+/// \brief Form a dependent template name.
+///
+/// This action forms a dependent template name given the template
+/// name and its (presumably dependent) scope specifier. For
+/// example, given "MetaFun::template apply", the scope specifier \p
+/// SS will be "MetaFun::", \p TemplateKWLoc contains the location
+/// of the "template" keyword, and "apply" is the \p Name.
+Sema::TemplateTy
+Sema::ActOnDependentTemplateName(SourceLocation TemplateKWLoc,
+                                 CXXScopeSpec &SS,
+                                 UnqualifiedId &Name,
+                                 TypeTy *ObjectType,
+                                 bool EnteringContext) {
+  DeclContext *LookupCtx = 0;
+  if (SS.isSet())
+    LookupCtx = computeDeclContext(SS, EnteringContext);
+  if (!LookupCtx && ObjectType)
+    LookupCtx = computeDeclContext(QualType::getFromOpaquePtr(ObjectType));
+  if (LookupCtx) {
+    // C++0x [temp.names]p5:
+    //   If a name prefixed by the keyword template is not the name of
+    //   a template, the program is ill-formed. [Note: the keyword
+    //   template may not be applied to non-template members of class
+    //   templates. -end note ] [ Note: as is the case with the
+    //   typename prefix, the template prefix is allowed in cases
+    //   where it is not strictly necessary; i.e., when the
+    //   nested-name-specifier or the expression on the left of the ->
+    //   or . is not dependent on a template-parameter, or the use
+    //   does not appear in the scope of a template. -end note]
+    //
+    // Note: C++03 was more strict here, because it banned the use of
+    // the "template" keyword prior to a template-name that was not a
+    // dependent name. C++ DR468 relaxed this requirement (the
+    // "template" keyword is now permitted). We follow the C++0x
+    // rules, even in C++03 mode, retroactively applying the DR.
+    TemplateTy Template;
+    TemplateNameKind TNK = isTemplateName(0, SS, Name, ObjectType,
+                                          EnteringContext, Template);
+    if (TNK == TNK_Non_template && LookupCtx->isDependentContext() &&
+        isa<CXXRecordDecl>(LookupCtx) &&
+        cast<CXXRecordDecl>(LookupCtx)->hasAnyDependentBases()) {
+      // This is a dependent template.
+    } else if (TNK == TNK_Non_template) {
+      Diag(Name.getSourceRange().getBegin(), 
+           diag::err_template_kw_refers_to_non_template)
+        << GetNameFromUnqualifiedId(Name)
+        << Name.getSourceRange();
+      return TemplateTy();
+    } else {
+      // We found something; return it.
+      return Template;
+    }
+  }
+
+  NestedNameSpecifier *Qualifier
+    = static_cast<NestedNameSpecifier *>(SS.getScopeRep());
+  
+  switch (Name.getKind()) {
+  case UnqualifiedId::IK_Identifier:
+    return TemplateTy::make(Context.getDependentTemplateName(Qualifier, 
+                                                             Name.Identifier));
+    
+  case UnqualifiedId::IK_OperatorFunctionId:
+    return TemplateTy::make(Context.getDependentTemplateName(Qualifier,
+                                             Name.OperatorFunctionId.Operator));
+
+  case UnqualifiedId::IK_LiteralOperatorId:
+    assert(false && "We don't support these; Parse shouldn't have allowed propagation");
+
+  default:
+    break;
+  }
+  
+  Diag(Name.getSourceRange().getBegin(), 
+       diag::err_template_kw_refers_to_non_template)
+    << GetNameFromUnqualifiedId(Name)
+    << Name.getSourceRange();
+  return TemplateTy();
+}
+
+bool Sema::CheckTemplateTypeArgument(TemplateTypeParmDecl *Param,
+                                     const TemplateArgumentLoc &AL,
+                                     TemplateArgumentListBuilder &Converted) {
+  const TemplateArgument &Arg = AL.getArgument();
+
+  // Check template type parameter.
+  switch(Arg.getKind()) {
+  case TemplateArgument::Type:
+    // C++ [temp.arg.type]p1:
+    //   A template-argument for a template-parameter which is a
+    //   type shall be a type-id.
+    break;
+  case TemplateArgument::Template: {
+    // We have a template type parameter but the template argument
+    // is a template without any arguments.
+    SourceRange SR = AL.getSourceRange();
+    TemplateName Name = Arg.getAsTemplate();
+    Diag(SR.getBegin(), diag::err_template_missing_args)
+      << Name << SR;
+    if (TemplateDecl *Decl = Name.getAsTemplateDecl())
+      Diag(Decl->getLocation(), diag::note_template_decl_here);
+
+    return true;
+  }
+  default: {
+    // We have a template type parameter but the template argument
+    // is not a type.
+    SourceRange SR = AL.getSourceRange();
+    Diag(SR.getBegin(), diag::err_template_arg_must_be_type) << SR;
+    Diag(Param->getLocation(), diag::note_template_param_here);
+
+    return true;
+  }
+  }
+
+  if (CheckTemplateArgument(Param, AL.getTypeSourceInfo()))
+    return true;
+
+  // Add the converted template type argument.
+  Converted.Append(
+                 TemplateArgument(Context.getCanonicalType(Arg.getAsType())));
+  return false;
+}
+
+/// \brief Substitute template arguments into the default template argument for
+/// the given template type parameter.
+///
+/// \param SemaRef the semantic analysis object for which we are performing
+/// the substitution.
+///
+/// \param Template the template that we are synthesizing template arguments 
+/// for.
+///
+/// \param TemplateLoc the location of the template name that started the
+/// template-id we are checking.
+///
+/// \param RAngleLoc the location of the right angle bracket ('>') that
+/// terminates the template-id.
+///
+/// \param Param the template template parameter whose default we are
+/// substituting into.
+///
+/// \param Converted the list of template arguments provided for template
+/// parameters that precede \p Param in the template parameter list.
+///
+/// \returns the substituted template argument, or NULL if an error occurred.
+static TypeSourceInfo *
+SubstDefaultTemplateArgument(Sema &SemaRef,
+                             TemplateDecl *Template,
+                             SourceLocation TemplateLoc,
+                             SourceLocation RAngleLoc,
+                             TemplateTypeParmDecl *Param,
+                             TemplateArgumentListBuilder &Converted) {
+  TypeSourceInfo *ArgType = Param->getDefaultArgumentInfo();
+
+  // If the argument type is dependent, instantiate it now based
+  // on the previously-computed template arguments.
+  if (ArgType->getType()->isDependentType()) {
+    TemplateArgumentList TemplateArgs(SemaRef.Context, Converted,
+                                      /*TakeArgs=*/false);
+    
+    MultiLevelTemplateArgumentList AllTemplateArgs
+      = SemaRef.getTemplateInstantiationArgs(Template, &TemplateArgs);
+
+    Sema::InstantiatingTemplate Inst(SemaRef, TemplateLoc,
+                                     Template, Converted.getFlatArguments(),
+                                     Converted.flatSize(),
+                                     SourceRange(TemplateLoc, RAngleLoc));
+    
+    ArgType = SemaRef.SubstType(ArgType, AllTemplateArgs,
+                                Param->getDefaultArgumentLoc(),
+                                Param->getDeclName());
+  }
+
+  return ArgType;
+}
+
+/// \brief Substitute template arguments into the default template argument for
+/// the given non-type template parameter.
+///
+/// \param SemaRef the semantic analysis object for which we are performing
+/// the substitution.
+///
+/// \param Template the template that we are synthesizing template arguments 
+/// for.
+///
+/// \param TemplateLoc the location of the template name that started the
+/// template-id we are checking.
+///
+/// \param RAngleLoc the location of the right angle bracket ('>') that
+/// terminates the template-id.
+///
+/// \param Param the non-type template parameter whose default we are
+/// substituting into.
+///
+/// \param Converted the list of template arguments provided for template
+/// parameters that precede \p Param in the template parameter list.
+///
+/// \returns the substituted template argument, or NULL if an error occurred.
+static Sema::OwningExprResult
+SubstDefaultTemplateArgument(Sema &SemaRef,
+                             TemplateDecl *Template,
+                             SourceLocation TemplateLoc,
+                             SourceLocation RAngleLoc,
+                             NonTypeTemplateParmDecl *Param,
+                             TemplateArgumentListBuilder &Converted) {
+  TemplateArgumentList TemplateArgs(SemaRef.Context, Converted,
+                                    /*TakeArgs=*/false);
+    
+  MultiLevelTemplateArgumentList AllTemplateArgs
+    = SemaRef.getTemplateInstantiationArgs(Template, &TemplateArgs);
+    
+  Sema::InstantiatingTemplate Inst(SemaRef, TemplateLoc,
+                                   Template, Converted.getFlatArguments(),
+                                   Converted.flatSize(),
+                                   SourceRange(TemplateLoc, RAngleLoc));
+
+  return SemaRef.SubstExpr(Param->getDefaultArgument(), AllTemplateArgs);
+}
+
+/// \brief Substitute template arguments into the default template argument for
+/// the given template template parameter.
+///
+/// \param SemaRef the semantic analysis object for which we are performing
+/// the substitution.
+///
+/// \param Template the template that we are synthesizing template arguments 
+/// for.
+///
+/// \param TemplateLoc the location of the template name that started the
+/// template-id we are checking.
+///
+/// \param RAngleLoc the location of the right angle bracket ('>') that
+/// terminates the template-id.
+///
+/// \param Param the template template parameter whose default we are
+/// substituting into.
+///
+/// \param Converted the list of template arguments provided for template
+/// parameters that precede \p Param in the template parameter list.
+///
+/// \returns the substituted template argument, or NULL if an error occurred.
+static TemplateName
+SubstDefaultTemplateArgument(Sema &SemaRef,
+                             TemplateDecl *Template,
+                             SourceLocation TemplateLoc,
+                             SourceLocation RAngleLoc,
+                             TemplateTemplateParmDecl *Param,
+                             TemplateArgumentListBuilder &Converted) {
+  TemplateArgumentList TemplateArgs(SemaRef.Context, Converted,
+                                    /*TakeArgs=*/false);
+  
+  MultiLevelTemplateArgumentList AllTemplateArgs
+    = SemaRef.getTemplateInstantiationArgs(Template, &TemplateArgs);
+  
+  Sema::InstantiatingTemplate Inst(SemaRef, TemplateLoc,
+                                   Template, Converted.getFlatArguments(),
+                                   Converted.flatSize(),
+                                   SourceRange(TemplateLoc, RAngleLoc));
+  
+  return SemaRef.SubstTemplateName(
+                      Param->getDefaultArgument().getArgument().getAsTemplate(),
+                              Param->getDefaultArgument().getTemplateNameLoc(), 
+                                   AllTemplateArgs);
+}
+
+/// \brief If the given template parameter has a default template
+/// argument, substitute into that default template argument and
+/// return the corresponding template argument.
+TemplateArgumentLoc 
+Sema::SubstDefaultTemplateArgumentIfAvailable(TemplateDecl *Template,
+                                              SourceLocation TemplateLoc,
+                                              SourceLocation RAngleLoc,
+                                              Decl *Param,
+                                     TemplateArgumentListBuilder &Converted) {
+  if (TemplateTypeParmDecl *TypeParm = dyn_cast<TemplateTypeParmDecl>(Param)) {
+    if (!TypeParm->hasDefaultArgument())
+      return TemplateArgumentLoc();
+
+    TypeSourceInfo *DI = SubstDefaultTemplateArgument(*this, Template,
+                                                      TemplateLoc,
+                                                      RAngleLoc,
+                                                      TypeParm,
+                                                      Converted);
+    if (DI)
+      return TemplateArgumentLoc(TemplateArgument(DI->getType()), DI);
+
+    return TemplateArgumentLoc();
+  }
+
+  if (NonTypeTemplateParmDecl *NonTypeParm
+        = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
+    if (!NonTypeParm->hasDefaultArgument())
+      return TemplateArgumentLoc();
+
+    OwningExprResult Arg = SubstDefaultTemplateArgument(*this, Template,
+                                                        TemplateLoc,
+                                                        RAngleLoc,
+                                                        NonTypeParm,
+                                                        Converted);
+    if (Arg.isInvalid())
+      return TemplateArgumentLoc();
+
+    Expr *ArgE = Arg.takeAs<Expr>();
+    return TemplateArgumentLoc(TemplateArgument(ArgE), ArgE);
+  }
+
+  TemplateTemplateParmDecl *TempTempParm
+    = cast<TemplateTemplateParmDecl>(Param);
+  if (!TempTempParm->hasDefaultArgument())
+    return TemplateArgumentLoc();
+
+  TemplateName TName = SubstDefaultTemplateArgument(*this, Template,
+                                                    TemplateLoc, 
+                                                    RAngleLoc,
+                                                    TempTempParm,
+                                                    Converted);
+  if (TName.isNull())
+    return TemplateArgumentLoc();
+
+  return TemplateArgumentLoc(TemplateArgument(TName), 
+                TempTempParm->getDefaultArgument().getTemplateQualifierRange(),
+                TempTempParm->getDefaultArgument().getTemplateNameLoc());
+}
+
+/// \brief Check that the given template argument corresponds to the given
+/// template parameter.
+bool Sema::CheckTemplateArgument(NamedDecl *Param,
+                                 const TemplateArgumentLoc &Arg,
+                                 TemplateDecl *Template,
+                                 SourceLocation TemplateLoc,
+                                 SourceLocation RAngleLoc,
+                                 TemplateArgumentListBuilder &Converted,
+                                 CheckTemplateArgumentKind CTAK) {
+  // Check template type parameters.
+  if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
+    return CheckTemplateTypeArgument(TTP, Arg, Converted);
+  
+  // Check non-type template parameters.
+  if (NonTypeTemplateParmDecl *NTTP =dyn_cast<NonTypeTemplateParmDecl>(Param)) {    
+    // Do substitution on the type of the non-type template parameter
+    // with the template arguments we've seen thus far.
+    QualType NTTPType = NTTP->getType();
+    if (NTTPType->isDependentType()) {
+      // Do substitution on the type of the non-type template parameter.
+      InstantiatingTemplate Inst(*this, TemplateLoc, Template,
+                                 NTTP, Converted.getFlatArguments(),
+                                 Converted.flatSize(),
+                                 SourceRange(TemplateLoc, RAngleLoc));
+      
+      TemplateArgumentList TemplateArgs(Context, Converted,
+                                        /*TakeArgs=*/false);
+      NTTPType = SubstType(NTTPType,
+                           MultiLevelTemplateArgumentList(TemplateArgs),
+                           NTTP->getLocation(),
+                           NTTP->getDeclName());
+      // If that worked, check the non-type template parameter type
+      // for validity.
+      if (!NTTPType.isNull())
+        NTTPType = CheckNonTypeTemplateParameterType(NTTPType,
+                                                     NTTP->getLocation());
+      if (NTTPType.isNull())
+        return true;
+    }
+    
+    switch (Arg.getArgument().getKind()) {
+    case TemplateArgument::Null:
+      assert(false && "Should never see a NULL template argument here");
+      return true;
+      
+    case TemplateArgument::Expression: {
+      Expr *E = Arg.getArgument().getAsExpr();
+      TemplateArgument Result;
+      if (CheckTemplateArgument(NTTP, NTTPType, E, Result, CTAK))
+        return true;
+      
+      Converted.Append(Result);
+      break;
+    }
+      
+    case TemplateArgument::Declaration:
+    case TemplateArgument::Integral:
+      // We've already checked this template argument, so just copy
+      // it to the list of converted arguments.
+      Converted.Append(Arg.getArgument());
+      break;
+      
+    case TemplateArgument::Template:
+      // We were given a template template argument. It may not be ill-formed;
+      // see below.
+      if (DependentTemplateName *DTN
+            = Arg.getArgument().getAsTemplate().getAsDependentTemplateName()) {
+        // We have a template argument such as \c T::template X, which we
+        // parsed as a template template argument. However, since we now
+        // know that we need a non-type template argument, convert this
+        // template name into an expression.          
+        Expr *E = DependentScopeDeclRefExpr::Create(Context,
+                                                    DTN->getQualifier(),
+                                               Arg.getTemplateQualifierRange(),
+                                                    DTN->getIdentifier(),
+                                                    Arg.getTemplateNameLoc());
+        
+        TemplateArgument Result;
+        if (CheckTemplateArgument(NTTP, NTTPType, E, Result))
+          return true;
+        
+        Converted.Append(Result);
+        break;
+      }
+      
+      // We have a template argument that actually does refer to a class
+      // template, template alias, or template template parameter, and
+      // therefore cannot be a non-type template argument.
+      Diag(Arg.getLocation(), diag::err_template_arg_must_be_expr)
+        << Arg.getSourceRange();
+      
+      Diag(Param->getLocation(), diag::note_template_param_here);
+      return true;
+      
+    case TemplateArgument::Type: {
+      // We have a non-type template parameter but the template
+      // argument is a type.
+      
+      // C++ [temp.arg]p2:
+      //   In a template-argument, an ambiguity between a type-id and
+      //   an expression is resolved to a type-id, regardless of the
+      //   form of the corresponding template-parameter.
+      //
+      // We warn specifically about this case, since it can be rather
+      // confusing for users.
+      QualType T = Arg.getArgument().getAsType();
+      SourceRange SR = Arg.getSourceRange();
+      if (T->isFunctionType())
+        Diag(SR.getBegin(), diag::err_template_arg_nontype_ambig) << SR << T;
+      else
+        Diag(SR.getBegin(), diag::err_template_arg_must_be_expr) << SR;
+      Diag(Param->getLocation(), diag::note_template_param_here);
+      return true;
+    }
+      
+    case TemplateArgument::Pack:
+      llvm_unreachable("Caller must expand template argument packs");
+      break;
+    }
+    
+    return false;
+  } 
+  
+  
+  // Check template template parameters.
+  TemplateTemplateParmDecl *TempParm = cast<TemplateTemplateParmDecl>(Param);
+    
+  // Substitute into the template parameter list of the template
+  // template parameter, since previously-supplied template arguments
+  // may appear within the template template parameter.
+  {
+    // Set up a template instantiation context.
+    LocalInstantiationScope Scope(*this);
+    InstantiatingTemplate Inst(*this, TemplateLoc, Template,
+                               TempParm, Converted.getFlatArguments(),
+                               Converted.flatSize(),
+                               SourceRange(TemplateLoc, RAngleLoc));
+    
+    TemplateArgumentList TemplateArgs(Context, Converted,
+                                      /*TakeArgs=*/false);
+    TempParm = cast_or_null<TemplateTemplateParmDecl>(
+                      SubstDecl(TempParm, CurContext, 
+                                MultiLevelTemplateArgumentList(TemplateArgs)));
+    if (!TempParm)
+      return true;
+    
+    // FIXME: TempParam is leaked.
+  }
+    
+  switch (Arg.getArgument().getKind()) {
+  case TemplateArgument::Null:
+    assert(false && "Should never see a NULL template argument here");
+    return true;
+    
+  case TemplateArgument::Template:
+    if (CheckTemplateArgument(TempParm, Arg))
+      return true;
+      
+    Converted.Append(Arg.getArgument());
+    break;
+    
+  case TemplateArgument::Expression:
+  case TemplateArgument::Type:
+    // We have a template template parameter but the template
+    // argument does not refer to a template.
+    Diag(Arg.getLocation(), diag::err_template_arg_must_be_template);
+    return true;
+      
+  case TemplateArgument::Declaration:
+    llvm_unreachable(
+                       "Declaration argument with template template parameter");
+    break;
+  case TemplateArgument::Integral:
+    llvm_unreachable(
+                          "Integral argument with template template parameter");
+    break;
+    
+  case TemplateArgument::Pack:
+    llvm_unreachable("Caller must expand template argument packs");
+    break;
+  }
+  
+  return false;
+}
+
+/// \brief Check that the given template argument list is well-formed
+/// for specializing the given template.
+bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
+                                     SourceLocation TemplateLoc,
+                                const TemplateArgumentListInfo &TemplateArgs,
+                                     bool PartialTemplateArgs,
+                                     TemplateArgumentListBuilder &Converted) {
+  TemplateParameterList *Params = Template->getTemplateParameters();
+  unsigned NumParams = Params->size();
+  unsigned NumArgs = TemplateArgs.size();
+  bool Invalid = false;
+
+  SourceLocation RAngleLoc = TemplateArgs.getRAngleLoc();
+
+  bool HasParameterPack =
+    NumParams > 0 && Params->getParam(NumParams - 1)->isTemplateParameterPack();
+
+  if ((NumArgs > NumParams && !HasParameterPack) ||
+      (NumArgs < Params->getMinRequiredArguments() &&
+       !PartialTemplateArgs)) {
+    // FIXME: point at either the first arg beyond what we can handle,
+    // or the '>', depending on whether we have too many or too few
+    // arguments.
+    SourceRange Range;
+    if (NumArgs > NumParams)
+      Range = SourceRange(TemplateArgs[NumParams].getLocation(), RAngleLoc);
+    Diag(TemplateLoc, diag::err_template_arg_list_different_arity)
+      << (NumArgs > NumParams)
+      << (isa<ClassTemplateDecl>(Template)? 0 :
+          isa<FunctionTemplateDecl>(Template)? 1 :
+          isa<TemplateTemplateParmDecl>(Template)? 2 : 3)
+      << Template << Range;
+    Diag(Template->getLocation(), diag::note_template_decl_here)
+      << Params->getSourceRange();
+    Invalid = true;
+  }
+
+  // C++ [temp.arg]p1:
+  //   [...] The type and form of each template-argument specified in
+  //   a template-id shall match the type and form specified for the
+  //   corresponding parameter declared by the template in its
+  //   template-parameter-list.
+  unsigned ArgIdx = 0;
+  for (TemplateParameterList::iterator Param = Params->begin(),
+                                       ParamEnd = Params->end();
+       Param != ParamEnd; ++Param, ++ArgIdx) {
+    if (ArgIdx > NumArgs && PartialTemplateArgs)
+      break;
+
+    // If we have a template parameter pack, check every remaining template
+    // argument against that template parameter pack.
+    if ((*Param)->isTemplateParameterPack()) {
+      Converted.BeginPack();
+      for (; ArgIdx < NumArgs; ++ArgIdx) {
+        if (CheckTemplateArgument(*Param, TemplateArgs[ArgIdx], Template,
+                                  TemplateLoc, RAngleLoc, Converted)) {
+          Invalid = true;
+          break;
+        }
+      }
+      Converted.EndPack();
+      continue;
+    }
+    
+    if (ArgIdx < NumArgs) {
+      // Check the template argument we were given.
+      if (CheckTemplateArgument(*Param, TemplateArgs[ArgIdx], Template, 
+                                TemplateLoc, RAngleLoc, Converted))
+        return true;
+      
+      continue;
+    }
+    
+    // We have a default template argument that we will use.
+    TemplateArgumentLoc Arg;
+    
+    // Retrieve the default template argument from the template
+    // parameter. For each kind of template parameter, we substitute the
+    // template arguments provided thus far and any "outer" template arguments
+    // (when the template parameter was part of a nested template) into 
+    // the default argument.
+    if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*Param)) {
+      if (!TTP->hasDefaultArgument()) {
+        assert((Invalid || PartialTemplateArgs) && "Missing default argument");
+        break;
+      }
+
+      TypeSourceInfo *ArgType = SubstDefaultTemplateArgument(*this, 
+                                                             Template,
+                                                             TemplateLoc,
+                                                             RAngleLoc,
+                                                             TTP,
+                                                             Converted);
+      if (!ArgType)
+        return true;
+                                                             
+      Arg = TemplateArgumentLoc(TemplateArgument(ArgType->getType()),
+                                ArgType);
+    } else if (NonTypeTemplateParmDecl *NTTP
+                 = dyn_cast<NonTypeTemplateParmDecl>(*Param)) {
+      if (!NTTP->hasDefaultArgument()) {
+        assert((Invalid || PartialTemplateArgs) && "Missing default argument");
+        break;
+      }
+
+      Sema::OwningExprResult E = SubstDefaultTemplateArgument(*this, Template,
+                                                              TemplateLoc, 
+                                                              RAngleLoc, 
+                                                              NTTP, 
+                                                              Converted);
+      if (E.isInvalid())
+        return true;
+
+      Expr *Ex = E.takeAs<Expr>();
+      Arg = TemplateArgumentLoc(TemplateArgument(Ex), Ex);
+    } else {
+      TemplateTemplateParmDecl *TempParm
+        = cast<TemplateTemplateParmDecl>(*Param);
+
+      if (!TempParm->hasDefaultArgument()) {
+        assert((Invalid || PartialTemplateArgs) && "Missing default argument");
+        break;
+      }
+
+      TemplateName Name = SubstDefaultTemplateArgument(*this, Template,
+                                                       TemplateLoc, 
+                                                       RAngleLoc, 
+                                                       TempParm,
+                                                       Converted);
+      if (Name.isNull())
+        return true;
+      
+      Arg = TemplateArgumentLoc(TemplateArgument(Name), 
+                  TempParm->getDefaultArgument().getTemplateQualifierRange(),
+                  TempParm->getDefaultArgument().getTemplateNameLoc());
+    }
+    
+    // Introduce an instantiation record that describes where we are using
+    // the default template argument.
+    InstantiatingTemplate Instantiating(*this, RAngleLoc, Template, *Param,
+                                        Converted.getFlatArguments(),
+                                        Converted.flatSize(),
+                                        SourceRange(TemplateLoc, RAngleLoc));    
+    
+    // Check the default template argument.
+    if (CheckTemplateArgument(*Param, Arg, Template, TemplateLoc,
+                              RAngleLoc, Converted))
+      return true;
+  }
+
+  return Invalid;
+}
+
+/// \brief Check a template argument against its corresponding
+/// template type parameter.
+///
+/// This routine implements the semantics of C++ [temp.arg.type]. It
+/// returns true if an error occurred, and false otherwise.
+bool Sema::CheckTemplateArgument(TemplateTypeParmDecl *Param,
+                                 TypeSourceInfo *ArgInfo) {
+  assert(ArgInfo && "invalid TypeSourceInfo");
+  QualType Arg = ArgInfo->getType();
+
+  // C++ [temp.arg.type]p2:
+  //   A local type, a type with no linkage, an unnamed type or a type
+  //   compounded from any of these types shall not be used as a
+  //   template-argument for a template type-parameter.
+  //
+  // FIXME: Perform the recursive and no-linkage type checks.
+  const TagType *Tag = 0;
+  if (const EnumType *EnumT = Arg->getAs<EnumType>())
+    Tag = EnumT;
+  else if (const RecordType *RecordT = Arg->getAs<RecordType>())
+    Tag = RecordT;
+  if (Tag && Tag->getDecl()->getDeclContext()->isFunctionOrMethod()) {
+    SourceRange SR = ArgInfo->getTypeLoc().getFullSourceRange();
+    return Diag(SR.getBegin(), diag::err_template_arg_local_type)
+      << QualType(Tag, 0) << SR;
+  } else if (Tag && !Tag->getDecl()->getDeclName() &&
+           !Tag->getDecl()->getTypedefForAnonDecl()) {
+    SourceRange SR = ArgInfo->getTypeLoc().getFullSourceRange();
+    Diag(SR.getBegin(), diag::err_template_arg_unnamed_type) << SR;
+    Diag(Tag->getDecl()->getLocation(), diag::note_template_unnamed_type_here);
+    return true;
+  } else if (Context.hasSameUnqualifiedType(Arg, Context.OverloadTy)) {
+    SourceRange SR = ArgInfo->getTypeLoc().getFullSourceRange();
+    return Diag(SR.getBegin(), diag::err_template_arg_overload_type) << SR;
+  }
+
+  return false;
+}
+
+/// \brief Checks whether the given template argument is the address
+/// of an object or function according to C++ [temp.arg.nontype]p1.
+static bool 
+CheckTemplateArgumentAddressOfObjectOrFunction(Sema &S,
+                                               NonTypeTemplateParmDecl *Param,
+                                               QualType ParamType,
+                                               Expr *ArgIn,
+                                               TemplateArgument &Converted) {
+  bool Invalid = false;
+  Expr *Arg = ArgIn;
+  QualType ArgType = Arg->getType();
+
+  // See through any implicit casts we added to fix the type.
+  while (ImplicitCastExpr *Cast = dyn_cast<ImplicitCastExpr>(Arg))
+    Arg = Cast->getSubExpr();
+
+  // C++ [temp.arg.nontype]p1:
+  //
+  //   A template-argument for a non-type, non-template
+  //   template-parameter shall be one of: [...]
+  //
+  //     -- the address of an object or function with external
+  //        linkage, including function templates and function
+  //        template-ids but excluding non-static class members,
+  //        expressed as & id-expression where the & is optional if
+  //        the name refers to a function or array, or if the
+  //        corresponding template-parameter is a reference; or
+  DeclRefExpr *DRE = 0;
+
+  // Ignore (and complain about) any excess parentheses.
+  while (ParenExpr *Parens = dyn_cast<ParenExpr>(Arg)) {
+    if (!Invalid) {
+      S.Diag(Arg->getSourceRange().getBegin(),
+             diag::err_template_arg_extra_parens)
+        << Arg->getSourceRange();
+      Invalid = true;
+    }
+
+    Arg = Parens->getSubExpr();
+  }
+
+  bool AddressTaken = false;
+  SourceLocation AddrOpLoc;
+  if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(Arg)) {
+    if (UnOp->getOpcode() == UnaryOperator::AddrOf) {
+      DRE = dyn_cast<DeclRefExpr>(UnOp->getSubExpr());
+      AddressTaken = true;
+      AddrOpLoc = UnOp->getOperatorLoc();
+    }
+  } else
+    DRE = dyn_cast<DeclRefExpr>(Arg);
+
+  if (!DRE) {
+    S.Diag(Arg->getLocStart(), diag::err_template_arg_not_decl_ref)
+      << Arg->getSourceRange();
+    S.Diag(Param->getLocation(), diag::note_template_param_here);
+    return true;
+  }
+
+  // Stop checking the precise nature of the argument if it is value dependent,
+  // it should be checked when instantiated.
+  if (Arg->isValueDependent()) {
+    Converted = TemplateArgument(ArgIn->Retain());
+    return false;
+  }
+
+  if (!isa<ValueDecl>(DRE->getDecl())) {
+    S.Diag(Arg->getSourceRange().getBegin(),
+           diag::err_template_arg_not_object_or_func_form)
+      << Arg->getSourceRange();
+    S.Diag(Param->getLocation(), diag::note_template_param_here);
+    return true;
+  }
+
+  NamedDecl *Entity = 0;
+
+  // Cannot refer to non-static data members
+  if (FieldDecl *Field = dyn_cast<FieldDecl>(DRE->getDecl())) {
+    S.Diag(Arg->getSourceRange().getBegin(), diag::err_template_arg_field)
+      << Field << Arg->getSourceRange();
+    S.Diag(Param->getLocation(), diag::note_template_param_here);
+    return true;
+  }
+
+  // Cannot refer to non-static member functions
+  if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(DRE->getDecl()))
+    if (!Method->isStatic()) {
+      S.Diag(Arg->getSourceRange().getBegin(), diag::err_template_arg_method)
+        << Method << Arg->getSourceRange();
+      S.Diag(Param->getLocation(), diag::note_template_param_here);
+      return true;
+    }
+
+  // Functions must have external linkage.
+  if (FunctionDecl *Func = dyn_cast<FunctionDecl>(DRE->getDecl())) {
+    if (!isExternalLinkage(Func->getLinkage())) {
+      S.Diag(Arg->getSourceRange().getBegin(),
+             diag::err_template_arg_function_not_extern)
+        << Func << Arg->getSourceRange();
+      S.Diag(Func->getLocation(), diag::note_template_arg_internal_object)
+        << true;
+      return true;
+    }
+
+    // Okay: we've named a function with external linkage.
+    Entity = Func;
+
+    // If the template parameter has pointer type, the function decays.
+    if (ParamType->isPointerType() && !AddressTaken)
+      ArgType = S.Context.getPointerType(Func->getType());
+    else if (AddressTaken && ParamType->isReferenceType()) {
+      // If we originally had an address-of operator, but the
+      // parameter has reference type, complain and (if things look
+      // like they will work) drop the address-of operator.
+      if (!S.Context.hasSameUnqualifiedType(Func->getType(),
+                                            ParamType.getNonReferenceType())) {
+        S.Diag(AddrOpLoc, diag::err_template_arg_address_of_non_pointer)
+          << ParamType;
+        S.Diag(Param->getLocation(), diag::note_template_param_here);
+        return true;
+      }
+
+      S.Diag(AddrOpLoc, diag::err_template_arg_address_of_non_pointer)
+        << ParamType
+        << FixItHint::CreateRemoval(AddrOpLoc);
+      S.Diag(Param->getLocation(), diag::note_template_param_here);
+
+      ArgType = Func->getType();
+    }
+  } else if (VarDecl *Var = dyn_cast<VarDecl>(DRE->getDecl())) {
+    if (!isExternalLinkage(Var->getLinkage())) {
+      S.Diag(Arg->getSourceRange().getBegin(),
+             diag::err_template_arg_object_not_extern)
+        << Var << Arg->getSourceRange();
+      S.Diag(Var->getLocation(), diag::note_template_arg_internal_object)
+        << true;
+      return true;
+    }
+
+    // A value of reference type is not an object.
+    if (Var->getType()->isReferenceType()) {
+      S.Diag(Arg->getSourceRange().getBegin(), 
+             diag::err_template_arg_reference_var)
+        << Var->getType() << Arg->getSourceRange();
+      S.Diag(Param->getLocation(), diag::note_template_param_here);
+      return true;
+    }
+
+    // Okay: we've named an object with external linkage
+    Entity = Var;
+
+    // If the template parameter has pointer type, we must have taken
+    // the address of this object.
+    if (ParamType->isReferenceType()) {
+      if (AddressTaken) {
+        // If we originally had an address-of operator, but the
+        // parameter has reference type, complain and (if things look
+        // like they will work) drop the address-of operator.
+        if (!S.Context.hasSameUnqualifiedType(Var->getType(),
+                                            ParamType.getNonReferenceType())) {
+          S.Diag(AddrOpLoc, diag::err_template_arg_address_of_non_pointer)
+            << ParamType;
+          S.Diag(Param->getLocation(), diag::note_template_param_here);
+          return true;
+        }
+
+        S.Diag(AddrOpLoc, diag::err_template_arg_address_of_non_pointer)
+          << ParamType
+          << FixItHint::CreateRemoval(AddrOpLoc);
+        S.Diag(Param->getLocation(), diag::note_template_param_here);
+
+        ArgType = Var->getType();
+      }
+    } else if (!AddressTaken && ParamType->isPointerType()) {
+      if (Var->getType()->isArrayType()) {
+        // Array-to-pointer decay.
+        ArgType = S.Context.getArrayDecayedType(Var->getType());
+      } else {
+        // If the template parameter has pointer type but the address of
+        // this object was not taken, complain and (possibly) recover by
+        // taking the address of the entity.
+        ArgType = S.Context.getPointerType(Var->getType());
+        if (!S.Context.hasSameUnqualifiedType(ArgType, ParamType)) {
+          S.Diag(Arg->getLocStart(), diag::err_template_arg_not_address_of)
+            << ParamType;
+          S.Diag(Param->getLocation(), diag::note_template_param_here);
+          return true;
+        }
+
+        S.Diag(Arg->getLocStart(), diag::err_template_arg_not_address_of)
+          << ParamType
+          << FixItHint::CreateInsertion(Arg->getLocStart(), "&");
+
+        S.Diag(Param->getLocation(), diag::note_template_param_here);
+      }
+    }
+  } else {
+    // We found something else, but we don't know specifically what it is.
+    S.Diag(Arg->getSourceRange().getBegin(),
+           diag::err_template_arg_not_object_or_func)
+      << Arg->getSourceRange();
+    S.Diag(DRE->getDecl()->getLocation(), diag::note_template_arg_refers_here);
+    return true;
+  }
+
+  if (ParamType->isPointerType() && 
+      !ParamType->getAs<PointerType>()->getPointeeType()->isFunctionType() &&
+      S.IsQualificationConversion(ArgType, ParamType)) {
+    // For pointer-to-object types, qualification conversions are
+    // permitted.
+  } else {
+    if (const ReferenceType *ParamRef = ParamType->getAs<ReferenceType>()) {
+      if (!ParamRef->getPointeeType()->isFunctionType()) {
+        // C++ [temp.arg.nontype]p5b3:
+        //   For a non-type template-parameter of type reference to
+        //   object, no conversions apply. The type referred to by the
+        //   reference may be more cv-qualified than the (otherwise
+        //   identical) type of the template- argument. The
+        //   template-parameter is bound directly to the
+        //   template-argument, which shall be an lvalue.
+
+        // FIXME: Other qualifiers?
+        unsigned ParamQuals = ParamRef->getPointeeType().getCVRQualifiers();
+        unsigned ArgQuals = ArgType.getCVRQualifiers();
+
+        if ((ParamQuals | ArgQuals) != ParamQuals) {
+          S.Diag(Arg->getSourceRange().getBegin(),
+                 diag::err_template_arg_ref_bind_ignores_quals)
+            << ParamType << Arg->getType()
+            << Arg->getSourceRange();
+          S.Diag(Param->getLocation(), diag::note_template_param_here);
+          return true;
+        }     
+      }
+    }
+
+    // At this point, the template argument refers to an object or
+    // function with external linkage. We now need to check whether the
+    // argument and parameter types are compatible.
+    if (!S.Context.hasSameUnqualifiedType(ArgType,
+                                          ParamType.getNonReferenceType())) {
+      // We can't perform this conversion or binding.
+      if (ParamType->isReferenceType())
+        S.Diag(Arg->getLocStart(), diag::err_template_arg_no_ref_bind)
+          << ParamType << Arg->getType() << Arg->getSourceRange();
+      else
+        S.Diag(Arg->getLocStart(),  diag::err_template_arg_not_convertible)
+          << Arg->getType() << ParamType << Arg->getSourceRange();
+      S.Diag(Param->getLocation(), diag::note_template_param_here);
+      return true;
+    }
+  }
+
+  // Create the template argument.
+  Converted = TemplateArgument(Entity->getCanonicalDecl());
+  S.MarkDeclarationReferenced(Arg->getLocStart(), Entity);
+  return false;
+}
+
+/// \brief Checks whether the given template argument is a pointer to
+/// member constant according to C++ [temp.arg.nontype]p1.
+bool Sema::CheckTemplateArgumentPointerToMember(Expr *Arg, 
+                                                TemplateArgument &Converted) {
+  bool Invalid = false;
+
+  // See through any implicit casts we added to fix the type.
+  while (ImplicitCastExpr *Cast = dyn_cast<ImplicitCastExpr>(Arg))
+    Arg = Cast->getSubExpr();
+
+  // C++ [temp.arg.nontype]p1:
+  //
+  //   A template-argument for a non-type, non-template
+  //   template-parameter shall be one of: [...]
+  //
+  //     -- a pointer to member expressed as described in 5.3.1.
+  DeclRefExpr *DRE = 0;
+
+  // Ignore (and complain about) any excess parentheses.
+  while (ParenExpr *Parens = dyn_cast<ParenExpr>(Arg)) {
+    if (!Invalid) {
+      Diag(Arg->getSourceRange().getBegin(),
+           diag::err_template_arg_extra_parens)
+        << Arg->getSourceRange();
+      Invalid = true;
+    }
+
+    Arg = Parens->getSubExpr();
+  }
+
+  // A pointer-to-member constant written &Class::member.
+  if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(Arg)) {
+    if (UnOp->getOpcode() == UnaryOperator::AddrOf) {
+      DRE = dyn_cast<DeclRefExpr>(UnOp->getSubExpr());
+      if (DRE && !DRE->getQualifier())
+        DRE = 0;
+    }
+  } 
+  // A constant of pointer-to-member type.
+  else if ((DRE = dyn_cast<DeclRefExpr>(Arg))) {
+    if (ValueDecl *VD = dyn_cast<ValueDecl>(DRE->getDecl())) {
+      if (VD->getType()->isMemberPointerType()) {
+        if (isa<NonTypeTemplateParmDecl>(VD) ||
+            (isa<VarDecl>(VD) && 
+             Context.getCanonicalType(VD->getType()).isConstQualified())) {
+          if (Arg->isTypeDependent() || Arg->isValueDependent())
+            Converted = TemplateArgument(Arg->Retain());
+          else
+            Converted = TemplateArgument(VD->getCanonicalDecl());
+          return Invalid;
+        }
+      }
+    }
+    
+    DRE = 0;
+  }
+  
+  if (!DRE)
+    return Diag(Arg->getSourceRange().getBegin(),
+                diag::err_template_arg_not_pointer_to_member_form)
+      << Arg->getSourceRange();
+
+  if (isa<FieldDecl>(DRE->getDecl()) || isa<CXXMethodDecl>(DRE->getDecl())) {
+    assert((isa<FieldDecl>(DRE->getDecl()) ||
+            !cast<CXXMethodDecl>(DRE->getDecl())->isStatic()) &&
+           "Only non-static member pointers can make it here");
+
+    // Okay: this is the address of a non-static member, and therefore
+    // a member pointer constant.
+    if (Arg->isTypeDependent() || Arg->isValueDependent())
+      Converted = TemplateArgument(Arg->Retain());
+    else
+      Converted = TemplateArgument(DRE->getDecl()->getCanonicalDecl());
+    return Invalid;
+  }
+
+  // We found something else, but we don't know specifically what it is.
+  Diag(Arg->getSourceRange().getBegin(),
+       diag::err_template_arg_not_pointer_to_member_form)
+      << Arg->getSourceRange();
+  Diag(DRE->getDecl()->getLocation(),
+       diag::note_template_arg_refers_here);
+  return true;
+}
+
+/// \brief Check a template argument against its corresponding
+/// non-type template parameter.
+///
+/// This routine implements the semantics of C++ [temp.arg.nontype].
+/// It returns true if an error occurred, and false otherwise. \p
+/// InstantiatedParamType is the type of the non-type template
+/// parameter after it has been instantiated.
+///
+/// If no error was detected, Converted receives the converted template argument.
+bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
+                                 QualType InstantiatedParamType, Expr *&Arg,
+                                 TemplateArgument &Converted,
+                                 CheckTemplateArgumentKind CTAK) {
+  SourceLocation StartLoc = Arg->getSourceRange().getBegin();
+
+  // If either the parameter has a dependent type or the argument is
+  // type-dependent, there's nothing we can check now.
+  if (InstantiatedParamType->isDependentType() || Arg->isTypeDependent()) {
+    // FIXME: Produce a cloned, canonical expression?
+    Converted = TemplateArgument(Arg);
+    return false;
+  }
+
+  // C++ [temp.arg.nontype]p5:
+  //   The following conversions are performed on each expression used
+  //   as a non-type template-argument. If a non-type
+  //   template-argument cannot be converted to the type of the
+  //   corresponding template-parameter then the program is
+  //   ill-formed.
+  //
+  //     -- for a non-type template-parameter of integral or
+  //        enumeration type, integral promotions (4.5) and integral
+  //        conversions (4.7) are applied.
+  QualType ParamType = InstantiatedParamType;
+  QualType ArgType = Arg->getType();
+  if (ParamType->isIntegralType() || ParamType->isEnumeralType()) {
+    // C++ [temp.arg.nontype]p1:
+    //   A template-argument for a non-type, non-template
+    //   template-parameter shall be one of:
+    //
+    //     -- an integral constant-expression of integral or enumeration
+    //        type; or
+    //     -- the name of a non-type template-parameter; or
+    SourceLocation NonConstantLoc;
+    llvm::APSInt Value;
+    if (!ArgType->isIntegralType() && !ArgType->isEnumeralType()) {
+      Diag(Arg->getSourceRange().getBegin(),
+           diag::err_template_arg_not_integral_or_enumeral)
+        << ArgType << Arg->getSourceRange();
+      Diag(Param->getLocation(), diag::note_template_param_here);
+      return true;
+    } else if (!Arg->isValueDependent() &&
+               !Arg->isIntegerConstantExpr(Value, Context, &NonConstantLoc)) {
+      Diag(NonConstantLoc, diag::err_template_arg_not_ice)
+        << ArgType << Arg->getSourceRange();
+      return true;
+    }
+
+    // From here on out, all we care about are the unqualified forms
+    // of the parameter and argument types.
+    ParamType = ParamType.getUnqualifiedType();
+    ArgType = ArgType.getUnqualifiedType();
+
+    // Try to convert the argument to the parameter's type.
+    if (Context.hasSameType(ParamType, ArgType)) {
+      // Okay: no conversion necessary
+    } else if (CTAK == CTAK_Deduced) {
+      // C++ [temp.deduct.type]p17:
+      //   If, in the declaration of a function template with a non-type
+      //   template-parameter, the non-type template- parameter is used
+      //   in an expression in the function parameter-list and, if the
+      //   corresponding template-argument is deduced, the
+      //   template-argument type shall match the type of the
+      //   template-parameter exactly, except that a template-argument
+      //   deduced from an array bound may be of any integral type.
+      Diag(StartLoc, diag::err_deduced_non_type_template_arg_type_mismatch)
+        << ArgType << ParamType;
+      Diag(Param->getLocation(), diag::note_template_param_here);
+      return true;      
+    } else if (IsIntegralPromotion(Arg, ArgType, ParamType) ||
+               !ParamType->isEnumeralType()) {
+      // This is an integral promotion or conversion.
+      ImpCastExprToType(Arg, ParamType, CastExpr::CK_IntegralCast);
+    } else {
+      // We can't perform this conversion.
+      Diag(Arg->getSourceRange().getBegin(),
+           diag::err_template_arg_not_convertible)
+        << Arg->getType() << InstantiatedParamType << Arg->getSourceRange();
+      Diag(Param->getLocation(), diag::note_template_param_here);
+      return true;
+    }
+
+    QualType IntegerType = Context.getCanonicalType(ParamType);
+    if (const EnumType *Enum = IntegerType->getAs<EnumType>())
+      IntegerType = Context.getCanonicalType(Enum->getDecl()->getIntegerType());
+
+    if (!Arg->isValueDependent()) {
+      llvm::APSInt OldValue = Value;
+      
+      // Coerce the template argument's value to the value it will have 
+      // based on the template parameter's type.
+      unsigned AllowedBits = Context.getTypeSize(IntegerType);
+      if (Value.getBitWidth() != AllowedBits)
+        Value.extOrTrunc(AllowedBits);
+      Value.setIsSigned(IntegerType->isSignedIntegerType());
+
+      // Complain if an unsigned parameter received a negative value.
+      if (IntegerType->isUnsignedIntegerType()
+          && (OldValue.isSigned() && OldValue.isNegative())) {
+        Diag(Arg->getSourceRange().getBegin(), diag::warn_template_arg_negative)
+          << OldValue.toString(10) << Value.toString(10) << Param->getType()
+          << Arg->getSourceRange();
+        Diag(Param->getLocation(), diag::note_template_param_here);
+      }
+
+      // Complain if we overflowed the template parameter's type.
+      unsigned RequiredBits;
+      if (IntegerType->isUnsignedIntegerType())
+        RequiredBits = OldValue.getActiveBits();
+      else if (OldValue.isUnsigned())
+        RequiredBits = OldValue.getActiveBits() + 1;
+      else
+        RequiredBits = OldValue.getMinSignedBits();
+      if (RequiredBits > AllowedBits) {
+        Diag(Arg->getSourceRange().getBegin(),
+             diag::warn_template_arg_too_large)
+          << OldValue.toString(10) << Value.toString(10) << Param->getType()
+          << Arg->getSourceRange();
+        Diag(Param->getLocation(), diag::note_template_param_here);
+      }
+    }
+
+    // Add the value of this argument to the list of converted
+    // arguments. We use the bitwidth and signedness of the template
+    // parameter.
+    if (Arg->isValueDependent()) {
+      // The argument is value-dependent. Create a new
+      // TemplateArgument with the converted expression.
+      Converted = TemplateArgument(Arg);
+      return false;
+    }
+
+    Converted = TemplateArgument(Value,
+                                 ParamType->isEnumeralType() ? ParamType
+                                                             : IntegerType);
+    return false;
+  }
+
+  DeclAccessPair FoundResult; // temporary for ResolveOverloadedFunction
+
+  // C++0x [temp.arg.nontype]p5 bullets 2, 4 and 6 permit conversion
+  // from a template argument of type std::nullptr_t to a non-type
+  // template parameter of type pointer to object, pointer to
+  // function, or pointer-to-member, respectively.
+  if (ArgType->isNullPtrType() && 
+      (ParamType->isPointerType() || ParamType->isMemberPointerType())) {
+    Converted = TemplateArgument((NamedDecl *)0);
+    return false;
+  }
+
+  // Handle pointer-to-function, reference-to-function, and
+  // pointer-to-member-function all in (roughly) the same way.
+  if (// -- For a non-type template-parameter of type pointer to
+      //    function, only the function-to-pointer conversion (4.3) is
+      //    applied. If the template-argument represents a set of
+      //    overloaded functions (or a pointer to such), the matching
+      //    function is selected from the set (13.4).
+      (ParamType->isPointerType() &&
+       ParamType->getAs<PointerType>()->getPointeeType()->isFunctionType()) ||
+      // -- For a non-type template-parameter of type reference to
+      //    function, no conversions apply. If the template-argument
+      //    represents a set of overloaded functions, the matching
+      //    function is selected from the set (13.4).
+      (ParamType->isReferenceType() &&
+       ParamType->getAs<ReferenceType>()->getPointeeType()->isFunctionType()) ||
+      // -- For a non-type template-parameter of type pointer to
+      //    member function, no conversions apply. If the
+      //    template-argument represents a set of overloaded member
+      //    functions, the matching member function is selected from
+      //    the set (13.4).
+      (ParamType->isMemberPointerType() &&
+       ParamType->getAs<MemberPointerType>()->getPointeeType()
+         ->isFunctionType())) {
+
+    if (Arg->getType() == Context.OverloadTy) {
+      if (FunctionDecl *Fn = ResolveAddressOfOverloadedFunction(Arg, ParamType, 
+                                                                true,
+                                                                FoundResult)) {
+        if (DiagnoseUseOfDecl(Fn, Arg->getSourceRange().getBegin()))
+          return true;
+
+        Arg = FixOverloadedFunctionReference(Arg, FoundResult, Fn);
+        ArgType = Arg->getType();
+      } else
+        return true;
+    }
+        
+    if (!ParamType->isMemberPointerType())
+      return CheckTemplateArgumentAddressOfObjectOrFunction(*this, Param,
+                                                            ParamType, 
+                                                            Arg, Converted);
+
+    if (IsQualificationConversion(ArgType, ParamType.getNonReferenceType())) {
+      ImpCastExprToType(Arg, ParamType, CastExpr::CK_NoOp,
+                        Arg->isLvalue(Context) == Expr::LV_Valid);
+    } else if (!Context.hasSameUnqualifiedType(ArgType,
+                                           ParamType.getNonReferenceType())) {
+      // We can't perform this conversion.
+      Diag(Arg->getSourceRange().getBegin(),
+           diag::err_template_arg_not_convertible)
+        << Arg->getType() << InstantiatedParamType << Arg->getSourceRange();
+      Diag(Param->getLocation(), diag::note_template_param_here);
+      return true;
+    }
+
+    return CheckTemplateArgumentPointerToMember(Arg, Converted);
+  }
+
+  if (ParamType->isPointerType()) {
+    //   -- for a non-type template-parameter of type pointer to
+    //      object, qualification conversions (4.4) and the
+    //      array-to-pointer conversion (4.2) are applied.
+    // C++0x also allows a value of std::nullptr_t.
+    assert(ParamType->getAs<PointerType>()->getPointeeType()->isObjectType() &&
+           "Only object pointers allowed here");
+
+    return CheckTemplateArgumentAddressOfObjectOrFunction(*this, Param, 
+                                                          ParamType,
+                                                          Arg, Converted);
+  }
+
+  if (const ReferenceType *ParamRefType = ParamType->getAs<ReferenceType>()) {
+    //   -- For a non-type template-parameter of type reference to
+    //      object, no conversions apply. The type referred to by the
+    //      reference may be more cv-qualified than the (otherwise
+    //      identical) type of the template-argument. The
+    //      template-parameter is bound directly to the
+    //      template-argument, which must be an lvalue.
+    assert(ParamRefType->getPointeeType()->isObjectType() &&
+           "Only object references allowed here");
+
+    if (Arg->getType() == Context.OverloadTy) {
+      if (FunctionDecl *Fn = ResolveAddressOfOverloadedFunction(Arg, 
+                                                 ParamRefType->getPointeeType(), 
+                                                                true,
+                                                                FoundResult)) {
+        if (DiagnoseUseOfDecl(Fn, Arg->getSourceRange().getBegin()))
+          return true;
+
+        Arg = FixOverloadedFunctionReference(Arg, FoundResult, Fn);
+        ArgType = Arg->getType();
+      } else
+        return true;
+    }
+    
+    return CheckTemplateArgumentAddressOfObjectOrFunction(*this, Param, 
+                                                          ParamType,
+                                                          Arg, Converted);
+  }
+
+  //     -- For a non-type template-parameter of type pointer to data
+  //        member, qualification conversions (4.4) are applied.
+  assert(ParamType->isMemberPointerType() && "Only pointers to members remain");
+
+  if (Context.hasSameUnqualifiedType(ParamType, ArgType)) {
+    // Types match exactly: nothing more to do here.
+  } else if (IsQualificationConversion(ArgType, ParamType)) {
+    ImpCastExprToType(Arg, ParamType, CastExpr::CK_NoOp,
+                      Arg->isLvalue(Context) == Expr::LV_Valid);
+  } else {
+    // We can't perform this conversion.
+    Diag(Arg->getSourceRange().getBegin(),
+         diag::err_template_arg_not_convertible)
+      << Arg->getType() << InstantiatedParamType << Arg->getSourceRange();
+    Diag(Param->getLocation(), diag::note_template_param_here);
+    return true;
+  }
+
+  return CheckTemplateArgumentPointerToMember(Arg, Converted);
+}
+
+/// \brief Check a template argument against its corresponding
+/// template template parameter.
+///
+/// This routine implements the semantics of C++ [temp.arg.template].
+/// It returns true if an error occurred, and false otherwise.
+bool Sema::CheckTemplateArgument(TemplateTemplateParmDecl *Param,
+                                 const TemplateArgumentLoc &Arg) {
+  TemplateName Name = Arg.getArgument().getAsTemplate();
+  TemplateDecl *Template = Name.getAsTemplateDecl();
+  if (!Template) {
+    // Any dependent template name is fine.
+    assert(Name.isDependent() && "Non-dependent template isn't a declaration?");
+    return false;
+  }
+
+  // C++ [temp.arg.template]p1:
+  //   A template-argument for a template template-parameter shall be
+  //   the name of a class template, expressed as id-expression. Only
+  //   primary class templates are considered when matching the
+  //   template template argument with the corresponding parameter;
+  //   partial specializations are not considered even if their
+  //   parameter lists match that of the template template parameter.
+  //
+  // Note that we also allow template template parameters here, which
+  // will happen when we are dealing with, e.g., class template
+  // partial specializations.
+  if (!isa<ClassTemplateDecl>(Template) &&
+      !isa<TemplateTemplateParmDecl>(Template)) {
+    assert(isa<FunctionTemplateDecl>(Template) &&
+           "Only function templates are possible here");
+    Diag(Arg.getLocation(), diag::err_template_arg_not_class_template);
+    Diag(Template->getLocation(), diag::note_template_arg_refers_here_func)
+      << Template;
+  }
+
+  return !TemplateParameterListsAreEqual(Template->getTemplateParameters(),
+                                         Param->getTemplateParameters(),
+                                         true, 
+                                         TPL_TemplateTemplateArgumentMatch,
+                                         Arg.getLocation());
+}
+
+/// \brief Given a non-type template argument that refers to a
+/// declaration and the type of its corresponding non-type template
+/// parameter, produce an expression that properly refers to that
+/// declaration.
+Sema::OwningExprResult 
+Sema::BuildExpressionFromDeclTemplateArgument(const TemplateArgument &Arg,
+                                              QualType ParamType,
+                                              SourceLocation Loc) {
+  assert(Arg.getKind() == TemplateArgument::Declaration &&
+         "Only declaration template arguments permitted here");
+  ValueDecl *VD = cast<ValueDecl>(Arg.getAsDecl());
+
+  if (VD->getDeclContext()->isRecord() && 
+      (isa<CXXMethodDecl>(VD) || isa<FieldDecl>(VD))) {
+    // If the value is a class member, we might have a pointer-to-member.
+    // Determine whether the non-type template template parameter is of
+    // pointer-to-member type. If so, we need to build an appropriate
+    // expression for a pointer-to-member, since a "normal" DeclRefExpr
+    // would refer to the member itself.
+    if (ParamType->isMemberPointerType()) {
+      QualType ClassType
+        = Context.getTypeDeclType(cast<RecordDecl>(VD->getDeclContext()));
+      NestedNameSpecifier *Qualifier
+        = NestedNameSpecifier::Create(Context, 0, false, ClassType.getTypePtr());
+      CXXScopeSpec SS;
+      SS.setScopeRep(Qualifier);
+      OwningExprResult RefExpr = BuildDeclRefExpr(VD, 
+                                           VD->getType().getNonReferenceType(), 
+                                                  Loc,
+                                                  &SS);
+      if (RefExpr.isInvalid())
+        return ExprError();
+      
+      RefExpr = CreateBuiltinUnaryOp(Loc, UnaryOperator::AddrOf, move(RefExpr));
+      assert(!RefExpr.isInvalid() &&
+             Context.hasSameType(((Expr*) RefExpr.get())->getType(),
+                                 ParamType));
+      return move(RefExpr);
+    }
+  }
+  
+  QualType T = VD->getType().getNonReferenceType();
+  if (ParamType->isPointerType()) {
+    // When the non-type template parameter is a pointer, take the
+    // address of the declaration.
+    OwningExprResult RefExpr = BuildDeclRefExpr(VD, T, Loc);
+    if (RefExpr.isInvalid())
+      return ExprError();
+
+    if (T->isFunctionType() || T->isArrayType()) {
+      // Decay functions and arrays.
+      Expr *RefE = (Expr *)RefExpr.get();
+      DefaultFunctionArrayConversion(RefE);
+      if (RefE != RefExpr.get()) {
+        RefExpr.release();
+        RefExpr = Owned(RefE);
+      }
+
+      return move(RefExpr);
+    }
+    
+    // Take the address of everything else
+    return CreateBuiltinUnaryOp(Loc, UnaryOperator::AddrOf, move(RefExpr));
+  }
+
+  // If the non-type template parameter has reference type, qualify the
+  // resulting declaration reference with the extra qualifiers on the
+  // type that the reference refers to.
+  if (const ReferenceType *TargetRef = ParamType->getAs<ReferenceType>())
+    T = Context.getQualifiedType(T, TargetRef->getPointeeType().getQualifiers());
+    
+  return BuildDeclRefExpr(VD, T, Loc);
+}
+
+/// \brief Construct a new expression that refers to the given
+/// integral template argument with the given source-location
+/// information.
+///
+/// This routine takes care of the mapping from an integral template
+/// argument (which may have any integral type) to the appropriate
+/// literal value.
+Sema::OwningExprResult 
+Sema::BuildExpressionFromIntegralTemplateArgument(const TemplateArgument &Arg,
+                                                  SourceLocation Loc) {
+  assert(Arg.getKind() == TemplateArgument::Integral &&
+         "Operation is only value for integral template arguments");
+  QualType T = Arg.getIntegralType();
+  if (T->isCharType() || T->isWideCharType())
+    return Owned(new (Context) CharacterLiteral(
+                                             Arg.getAsIntegral()->getZExtValue(),
+                                             T->isWideCharType(),
+                                             T,
+                                             Loc));
+  if (T->isBooleanType())
+    return Owned(new (Context) CXXBoolLiteralExpr(
+                                            Arg.getAsIntegral()->getBoolValue(),
+                                            T,
+                                            Loc));
+
+  return Owned(new (Context) IntegerLiteral(*Arg.getAsIntegral(), T, Loc));
+}
+
+
+/// \brief Determine whether the given template parameter lists are
+/// equivalent.
+///
+/// \param New  The new template parameter list, typically written in the
+/// source code as part of a new template declaration.
+///
+/// \param Old  The old template parameter list, typically found via
+/// name lookup of the template declared with this template parameter
+/// list.
+///
+/// \param Complain  If true, this routine will produce a diagnostic if
+/// the template parameter lists are not equivalent.
+///
+/// \param Kind describes how we are to match the template parameter lists.
+///
+/// \param TemplateArgLoc If this source location is valid, then we
+/// are actually checking the template parameter list of a template
+/// argument (New) against the template parameter list of its
+/// corresponding template template parameter (Old). We produce
+/// slightly different diagnostics in this scenario.
+///
+/// \returns True if the template parameter lists are equal, false
+/// otherwise.
+bool
+Sema::TemplateParameterListsAreEqual(TemplateParameterList *New,
+                                     TemplateParameterList *Old,
+                                     bool Complain,
+                                     TemplateParameterListEqualKind Kind,
+                                     SourceLocation TemplateArgLoc) {
+  if (Old->size() != New->size()) {
+    if (Complain) {
+      unsigned NextDiag = diag::err_template_param_list_different_arity;
+      if (TemplateArgLoc.isValid()) {
+        Diag(TemplateArgLoc, diag::err_template_arg_template_params_mismatch);
+        NextDiag = diag::note_template_param_list_different_arity;
+      }
+      Diag(New->getTemplateLoc(), NextDiag)
+          << (New->size() > Old->size())
+          << (Kind != TPL_TemplateMatch)
+          << SourceRange(New->getTemplateLoc(), New->getRAngleLoc());
+      Diag(Old->getTemplateLoc(), diag::note_template_prev_declaration)
+        << (Kind != TPL_TemplateMatch)
+        << SourceRange(Old->getTemplateLoc(), Old->getRAngleLoc());
+    }
+
+    return false;
+  }
+
+  for (TemplateParameterList::iterator OldParm = Old->begin(),
+         OldParmEnd = Old->end(), NewParm = New->begin();
+       OldParm != OldParmEnd; ++OldParm, ++NewParm) {
+    if ((*OldParm)->getKind() != (*NewParm)->getKind()) {
+      if (Complain) {
+        unsigned NextDiag = diag::err_template_param_different_kind;
+        if (TemplateArgLoc.isValid()) {
+          Diag(TemplateArgLoc, diag::err_template_arg_template_params_mismatch);
+          NextDiag = diag::note_template_param_different_kind;
+        }
+        Diag((*NewParm)->getLocation(), NextDiag)
+          << (Kind != TPL_TemplateMatch);
+        Diag((*OldParm)->getLocation(), diag::note_template_prev_declaration)
+          << (Kind != TPL_TemplateMatch);
+      }
+      return false;
+    }
+
+    if (isa<TemplateTypeParmDecl>(*OldParm)) {
+      // Okay; all template type parameters are equivalent (since we
+      // know we're at the same index).
+    } else if (NonTypeTemplateParmDecl *OldNTTP
+                 = dyn_cast<NonTypeTemplateParmDecl>(*OldParm)) {
+      // The types of non-type template parameters must agree.
+      NonTypeTemplateParmDecl *NewNTTP
+        = cast<NonTypeTemplateParmDecl>(*NewParm);
+      
+      // If we are matching a template template argument to a template
+      // template parameter and one of the non-type template parameter types
+      // is dependent, then we must wait until template instantiation time
+      // to actually compare the arguments.
+      if (Kind == TPL_TemplateTemplateArgumentMatch &&
+          (OldNTTP->getType()->isDependentType() ||
+           NewNTTP->getType()->isDependentType()))
+        continue;
+      
+      if (Context.getCanonicalType(OldNTTP->getType()) !=
+            Context.getCanonicalType(NewNTTP->getType())) {
+        if (Complain) {
+          unsigned NextDiag = diag::err_template_nontype_parm_different_type;
+          if (TemplateArgLoc.isValid()) {
+            Diag(TemplateArgLoc,
+                 diag::err_template_arg_template_params_mismatch);
+            NextDiag = diag::note_template_nontype_parm_different_type;
+          }
+          Diag(NewNTTP->getLocation(), NextDiag)
+            << NewNTTP->getType()
+            << (Kind != TPL_TemplateMatch);
+          Diag(OldNTTP->getLocation(),
+               diag::note_template_nontype_parm_prev_declaration)
+            << OldNTTP->getType();
+        }
+        return false;
+      }
+    } else {
+      // The template parameter lists of template template
+      // parameters must agree.
+      assert(isa<TemplateTemplateParmDecl>(*OldParm) &&
+             "Only template template parameters handled here");
+      TemplateTemplateParmDecl *OldTTP
+        = cast<TemplateTemplateParmDecl>(*OldParm);
+      TemplateTemplateParmDecl *NewTTP
+        = cast<TemplateTemplateParmDecl>(*NewParm);
+      if (!TemplateParameterListsAreEqual(NewTTP->getTemplateParameters(),
+                                          OldTTP->getTemplateParameters(),
+                                          Complain,
+              (Kind == TPL_TemplateMatch? TPL_TemplateTemplateParmMatch : Kind),
+                                          TemplateArgLoc))
+        return false;
+    }
+  }
+
+  return true;
+}
+
+/// \brief Check whether a template can be declared within this scope.
+///
+/// If the template declaration is valid in this scope, returns
+/// false. Otherwise, issues a diagnostic and returns true.
+bool
+Sema::CheckTemplateDeclScope(Scope *S, TemplateParameterList *TemplateParams) {
+  // Find the nearest enclosing declaration scope.
+  while ((S->getFlags() & Scope::DeclScope) == 0 ||
+         (S->getFlags() & Scope::TemplateParamScope) != 0)
+    S = S->getParent();
+
+  // C++ [temp]p2:
+  //   A template-declaration can appear only as a namespace scope or
+  //   class scope declaration.
+  DeclContext *Ctx = static_cast<DeclContext *>(S->getEntity());
+  if (Ctx && isa<LinkageSpecDecl>(Ctx) &&
+      cast<LinkageSpecDecl>(Ctx)->getLanguage() != LinkageSpecDecl::lang_cxx)
+    return Diag(TemplateParams->getTemplateLoc(), diag::err_template_linkage)
+             << TemplateParams->getSourceRange();
+
+  while (Ctx && isa<LinkageSpecDecl>(Ctx))
+    Ctx = Ctx->getParent();
+
+  if (Ctx && (Ctx->isFileContext() || Ctx->isRecord()))
+    return false;
+
+  return Diag(TemplateParams->getTemplateLoc(),
+              diag::err_template_outside_namespace_or_class_scope)
+    << TemplateParams->getSourceRange();
+}
+
+/// \brief Determine what kind of template specialization the given declaration
+/// is.
+static TemplateSpecializationKind getTemplateSpecializationKind(NamedDecl *D) {
+  if (!D)
+    return TSK_Undeclared;
+  
+  if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(D))
+    return Record->getTemplateSpecializationKind();
+  if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D))
+    return Function->getTemplateSpecializationKind();
+  if (VarDecl *Var = dyn_cast<VarDecl>(D))
+    return Var->getTemplateSpecializationKind();
+  
+  return TSK_Undeclared;
+}
+
+/// \brief Check whether a specialization is well-formed in the current 
+/// context.
+///
+/// This routine determines whether a template specialization can be declared
+/// in the current context (C++ [temp.expl.spec]p2).
+///
+/// \param S the semantic analysis object for which this check is being
+/// performed.
+///
+/// \param Specialized the entity being specialized or instantiated, which
+/// may be a kind of template (class template, function template, etc.) or
+/// a member of a class template (member function, static data member, 
+/// member class).
+///
+/// \param PrevDecl the previous declaration of this entity, if any.
+///
+/// \param Loc the location of the explicit specialization or instantiation of
+/// this entity.
+///
+/// \param IsPartialSpecialization whether this is a partial specialization of
+/// a class template.
+///
+/// \returns true if there was an error that we cannot recover from, false
+/// otherwise.
+static bool CheckTemplateSpecializationScope(Sema &S,
+                                             NamedDecl *Specialized,
+                                             NamedDecl *PrevDecl,
+                                             SourceLocation Loc,
+                                             bool IsPartialSpecialization) {
+  // Keep these "kind" numbers in sync with the %select statements in the
+  // various diagnostics emitted by this routine.
+  int EntityKind = 0;
+  bool isTemplateSpecialization = false;
+  if (isa<ClassTemplateDecl>(Specialized)) {
+    EntityKind = IsPartialSpecialization? 1 : 0;
+    isTemplateSpecialization = true;
+  } else if (isa<FunctionTemplateDecl>(Specialized)) {
+    EntityKind = 2;
+    isTemplateSpecialization = true;
+  } else if (isa<CXXMethodDecl>(Specialized))
+    EntityKind = 3;
+  else if (isa<VarDecl>(Specialized))
+    EntityKind = 4;
+  else if (isa<RecordDecl>(Specialized))
+    EntityKind = 5;
+  else {
+    S.Diag(Loc, diag::err_template_spec_unknown_kind);
+    S.Diag(Specialized->getLocation(), diag::note_specialized_entity);
+    return true;
+  }
+
+  // C++ [temp.expl.spec]p2:
+  //   An explicit specialization shall be declared in the namespace
+  //   of which the template is a member, or, for member templates, in
+  //   the namespace of which the enclosing class or enclosing class
+  //   template is a member. An explicit specialization of a member
+  //   function, member class or static data member of a class
+  //   template shall be declared in the namespace of which the class
+  //   template is a member. Such a declaration may also be a
+  //   definition. If the declaration is not a definition, the
+  //   specialization may be defined later in the name- space in which
+  //   the explicit specialization was declared, or in a namespace
+  //   that encloses the one in which the explicit specialization was
+  //   declared.
+  if (S.CurContext->getLookupContext()->isFunctionOrMethod()) {
+    S.Diag(Loc, diag::err_template_spec_decl_function_scope)
+      << Specialized;
+    return true;
+  }
+
+  if (S.CurContext->isRecord() && !IsPartialSpecialization) {
+    S.Diag(Loc, diag::err_template_spec_decl_class_scope)
+      << Specialized;
+    return true;
+  }
+  
+  // C++ [temp.class.spec]p6:
+  //   A class template partial specialization may be declared or redeclared
+  //   in any namespace scope in which its definition may be defined (14.5.1 
+  //   and 14.5.2).  
+  bool ComplainedAboutScope = false;
+  DeclContext *SpecializedContext 
+    = Specialized->getDeclContext()->getEnclosingNamespaceContext();
+  DeclContext *DC = S.CurContext->getEnclosingNamespaceContext();
+  if ((!PrevDecl || 
+       getTemplateSpecializationKind(PrevDecl) == TSK_Undeclared ||
+       getTemplateSpecializationKind(PrevDecl) == TSK_ImplicitInstantiation)){
+    // There is no prior declaration of this entity, so this
+    // specialization must be in the same context as the template
+    // itself.
+    if (!DC->Equals(SpecializedContext)) {
+      if (isa<TranslationUnitDecl>(SpecializedContext))
+        S.Diag(Loc, diag::err_template_spec_decl_out_of_scope_global)
+        << EntityKind << Specialized;
+      else if (isa<NamespaceDecl>(SpecializedContext))
+        S.Diag(Loc, diag::err_template_spec_decl_out_of_scope)
+        << EntityKind << Specialized
+        << cast<NamedDecl>(SpecializedContext);
+      
+      S.Diag(Specialized->getLocation(), diag::note_specialized_entity);
+      ComplainedAboutScope = true;
+    }
+  }
+  
+  // Make sure that this redeclaration (or definition) occurs in an enclosing 
+  // namespace.
+  // Note that HandleDeclarator() performs this check for explicit 
+  // specializations of function templates, static data members, and member
+  // functions, so we skip the check here for those kinds of entities.
+  // FIXME: HandleDeclarator's diagnostics aren't quite as good, though.
+  // Should we refactor that check, so that it occurs later?
+  if (!ComplainedAboutScope && !DC->Encloses(SpecializedContext) &&
+      !(isa<FunctionTemplateDecl>(Specialized) || isa<VarDecl>(Specialized) ||
+        isa<FunctionDecl>(Specialized))) {
+    if (isa<TranslationUnitDecl>(SpecializedContext))
+      S.Diag(Loc, diag::err_template_spec_redecl_global_scope)
+        << EntityKind << Specialized;
+    else if (isa<NamespaceDecl>(SpecializedContext))
+      S.Diag(Loc, diag::err_template_spec_redecl_out_of_scope)
+        << EntityKind << Specialized
+        << cast<NamedDecl>(SpecializedContext);
+  
+    S.Diag(Specialized->getLocation(), diag::note_specialized_entity);
+  }
+  
+  // FIXME: check for specialization-after-instantiation errors and such.
+  
+  return false;
+}
+                                             
+/// \brief Check the non-type template arguments of a class template
+/// partial specialization according to C++ [temp.class.spec]p9.
+///
+/// \param TemplateParams the template parameters of the primary class
+/// template.
+///
+/// \param TemplateArg the template arguments of the class template
+/// partial specialization.
+///
+/// \param MirrorsPrimaryTemplate will be set true if the class
+/// template partial specialization arguments are identical to the
+/// implicit template arguments of the primary template. This is not
+/// necessarily an error (C++0x), and it is left to the caller to diagnose
+/// this condition when it is an error.
+///
+/// \returns true if there was an error, false otherwise.
+bool Sema::CheckClassTemplatePartialSpecializationArgs(
+                                        TemplateParameterList *TemplateParams,
+                             const TemplateArgumentListBuilder &TemplateArgs,
+                                        bool &MirrorsPrimaryTemplate) {
+  // FIXME: the interface to this function will have to change to
+  // accommodate variadic templates.
+  MirrorsPrimaryTemplate = true;
+
+  const TemplateArgument *ArgList = TemplateArgs.getFlatArguments();
+
+  for (unsigned I = 0, N = TemplateParams->size(); I != N; ++I) {
+    // Determine whether the template argument list of the partial
+    // specialization is identical to the implicit argument list of
+    // the primary template. The caller may need to diagnostic this as
+    // an error per C++ [temp.class.spec]p9b3.
+    if (MirrorsPrimaryTemplate) {
+      if (TemplateTypeParmDecl *TTP
+            = dyn_cast<TemplateTypeParmDecl>(TemplateParams->getParam(I))) {
+        if (Context.getCanonicalType(Context.getTypeDeclType(TTP)) !=
+              Context.getCanonicalType(ArgList[I].getAsType()))
+          MirrorsPrimaryTemplate = false;
+      } else if (TemplateTemplateParmDecl *TTP
+                   = dyn_cast<TemplateTemplateParmDecl>(
+                                                 TemplateParams->getParam(I))) {
+        TemplateName Name = ArgList[I].getAsTemplate();
+        TemplateTemplateParmDecl *ArgDecl
+          = dyn_cast_or_null<TemplateTemplateParmDecl>(Name.getAsTemplateDecl());
+        if (!ArgDecl ||
+            ArgDecl->getIndex() != TTP->getIndex() ||
+            ArgDecl->getDepth() != TTP->getDepth())
+          MirrorsPrimaryTemplate = false;
+      }
+    }
+
+    NonTypeTemplateParmDecl *Param
+      = dyn_cast<NonTypeTemplateParmDecl>(TemplateParams->getParam(I));
+    if (!Param) {
+      continue;
+    }
+
+    Expr *ArgExpr = ArgList[I].getAsExpr();
+    if (!ArgExpr) {
+      MirrorsPrimaryTemplate = false;
+      continue;
+    }
+
+    // C++ [temp.class.spec]p8:
+    //   A non-type argument is non-specialized if it is the name of a
+    //   non-type parameter. All other non-type arguments are
+    //   specialized.
+    //
+    // Below, we check the two conditions that only apply to
+    // specialized non-type arguments, so skip any non-specialized
+    // arguments.
+    if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(ArgExpr))
+      if (NonTypeTemplateParmDecl *NTTP
+            = dyn_cast<NonTypeTemplateParmDecl>(DRE->getDecl())) {
+        if (MirrorsPrimaryTemplate &&
+            (Param->getIndex() != NTTP->getIndex() ||
+             Param->getDepth() != NTTP->getDepth()))
+          MirrorsPrimaryTemplate = false;
+
+        continue;
+      }
+
+    // C++ [temp.class.spec]p9:
+    //   Within the argument list of a class template partial
+    //   specialization, the following restrictions apply:
+    //     -- A partially specialized non-type argument expression
+    //        shall not involve a template parameter of the partial
+    //        specialization except when the argument expression is a
+    //        simple identifier.
+    if (ArgExpr->isTypeDependent() || ArgExpr->isValueDependent()) {
+      Diag(ArgExpr->getLocStart(),
+           diag::err_dependent_non_type_arg_in_partial_spec)
+        << ArgExpr->getSourceRange();
+      return true;
+    }
+
+    //     -- The type of a template parameter corresponding to a
+    //        specialized non-type argument shall not be dependent on a
+    //        parameter of the specialization.
+    if (Param->getType()->isDependentType()) {
+      Diag(ArgExpr->getLocStart(),
+           diag::err_dependent_typed_non_type_arg_in_partial_spec)
+        << Param->getType()
+        << ArgExpr->getSourceRange();
+      Diag(Param->getLocation(), diag::note_template_param_here);
+      return true;
+    }
+
+    MirrorsPrimaryTemplate = false;
+  }
+
+  return false;
+}
+
+/// \brief Retrieve the previous declaration of the given declaration.
+static NamedDecl *getPreviousDecl(NamedDecl *ND) {
+  if (VarDecl *VD = dyn_cast<VarDecl>(ND))
+    return VD->getPreviousDeclaration();
+  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND))
+    return FD->getPreviousDeclaration();
+  if (TagDecl *TD = dyn_cast<TagDecl>(ND))
+    return TD->getPreviousDeclaration();
+  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(ND))
+    return TD->getPreviousDeclaration();
+  if (FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(ND))
+    return FTD->getPreviousDeclaration();
+  if (ClassTemplateDecl *CTD = dyn_cast<ClassTemplateDecl>(ND))
+    return CTD->getPreviousDeclaration();
+  return 0;
+}
+
+Sema::DeclResult
+Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
+                                       TagUseKind TUK,
+                                       SourceLocation KWLoc,
+                                       CXXScopeSpec &SS,
+                                       TemplateTy TemplateD,
+                                       SourceLocation TemplateNameLoc,
+                                       SourceLocation LAngleLoc,
+                                       ASTTemplateArgsPtr TemplateArgsIn,
+                                       SourceLocation RAngleLoc,
+                                       AttributeList *Attr,
+                               MultiTemplateParamsArg TemplateParameterLists) {
+  assert(TUK != TUK_Reference && "References are not specializations");
+
+  // Find the class template we're specializing
+  TemplateName Name = TemplateD.getAsVal<TemplateName>();
+  ClassTemplateDecl *ClassTemplate
+    = dyn_cast_or_null<ClassTemplateDecl>(Name.getAsTemplateDecl());
+
+  if (!ClassTemplate) {
+    Diag(TemplateNameLoc, diag::err_not_class_template_specialization)
+      << (Name.getAsTemplateDecl() && 
+          isa<TemplateTemplateParmDecl>(Name.getAsTemplateDecl()));
+    return true;
+  }
+
+  bool isExplicitSpecialization = false;
+  bool isPartialSpecialization = false;
+
+  // Check the validity of the template headers that introduce this
+  // template.
+  // FIXME: We probably shouldn't complain about these headers for
+  // friend declarations.
+  TemplateParameterList *TemplateParams
+    = MatchTemplateParametersToScopeSpecifier(TemplateNameLoc, SS,
+                        (TemplateParameterList**)TemplateParameterLists.get(),
+                                              TemplateParameterLists.size(),
+                                              TUK == TUK_Friend,
+                                              isExplicitSpecialization);
+  if (TemplateParams && TemplateParams->size() > 0) {
+    isPartialSpecialization = true;
+
+    // C++ [temp.class.spec]p10:
+    //   The template parameter list of a specialization shall not
+    //   contain default template argument values.
+    for (unsigned I = 0, N = TemplateParams->size(); I != N; ++I) {
+      Decl *Param = TemplateParams->getParam(I);
+      if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
+        if (TTP->hasDefaultArgument()) {
+          Diag(TTP->getDefaultArgumentLoc(),
+               diag::err_default_arg_in_partial_spec);
+          TTP->removeDefaultArgument();
+        }
+      } else if (NonTypeTemplateParmDecl *NTTP
+                   = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
+        if (Expr *DefArg = NTTP->getDefaultArgument()) {
+          Diag(NTTP->getDefaultArgumentLoc(),
+               diag::err_default_arg_in_partial_spec)
+            << DefArg->getSourceRange();
+          NTTP->setDefaultArgument(0);
+          DefArg->Destroy(Context);
+        }
+      } else {
+        TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(Param);
+        if (TTP->hasDefaultArgument()) {
+          Diag(TTP->getDefaultArgument().getLocation(),
+               diag::err_default_arg_in_partial_spec)
+            << TTP->getDefaultArgument().getSourceRange();
+          TTP->setDefaultArgument(TemplateArgumentLoc());
+        }
+      }
+    }
+  } else if (TemplateParams) {
+    if (TUK == TUK_Friend)
+      Diag(KWLoc, diag::err_template_spec_friend)
+        << FixItHint::CreateRemoval(
+                                SourceRange(TemplateParams->getTemplateLoc(),
+                                            TemplateParams->getRAngleLoc()))
+        << SourceRange(LAngleLoc, RAngleLoc);
+    else
+      isExplicitSpecialization = true;
+  } else if (TUK != TUK_Friend) {
+    Diag(KWLoc, diag::err_template_spec_needs_header)
+      << FixItHint::CreateInsertion(KWLoc, "template<> ");
+    isExplicitSpecialization = true;
+  }
+
+  // Check that the specialization uses the same tag kind as the
+  // original template.
+  TagDecl::TagKind Kind;
+  switch (TagSpec) {
+  default: assert(0 && "Unknown tag type!");
+  case DeclSpec::TST_struct: Kind = TagDecl::TK_struct; break;
+  case DeclSpec::TST_union:  Kind = TagDecl::TK_union; break;
+  case DeclSpec::TST_class:  Kind = TagDecl::TK_class; break;
+  }
+  if (!isAcceptableTagRedeclaration(ClassTemplate->getTemplatedDecl(),
+                                    Kind, KWLoc,
+                                    *ClassTemplate->getIdentifier())) {
+    Diag(KWLoc, diag::err_use_with_wrong_tag)
+      << ClassTemplate
+      << FixItHint::CreateReplacement(KWLoc,
+                            ClassTemplate->getTemplatedDecl()->getKindName());
+    Diag(ClassTemplate->getTemplatedDecl()->getLocation(),
+         diag::note_previous_use);
+    Kind = ClassTemplate->getTemplatedDecl()->getTagKind();
+  }
+
+  // Translate the parser's template argument list in our AST format.
+  TemplateArgumentListInfo TemplateArgs;
+  TemplateArgs.setLAngleLoc(LAngleLoc);
+  TemplateArgs.setRAngleLoc(RAngleLoc);
+  translateTemplateArguments(TemplateArgsIn, TemplateArgs);
+
+  // Check that the template argument list is well-formed for this
+  // template.
+  TemplateArgumentListBuilder Converted(ClassTemplate->getTemplateParameters(),
+                                        TemplateArgs.size());
+  if (CheckTemplateArgumentList(ClassTemplate, TemplateNameLoc,
+                                TemplateArgs, false, Converted))
+    return true;
+
+  assert((Converted.structuredSize() ==
+            ClassTemplate->getTemplateParameters()->size()) &&
+         "Converted template argument list is too short!");
+
+  // Find the class template (partial) specialization declaration that
+  // corresponds to these arguments.
+  llvm::FoldingSetNodeID ID;
+  if (isPartialSpecialization) {
+    bool MirrorsPrimaryTemplate;
+    if (CheckClassTemplatePartialSpecializationArgs(
+                                         ClassTemplate->getTemplateParameters(),
+                                         Converted, MirrorsPrimaryTemplate))
+      return true;
+
+    if (MirrorsPrimaryTemplate) {
+      // C++ [temp.class.spec]p9b3:
+      //
+      //   -- The argument list of the specialization shall not be identical
+      //      to the implicit argument list of the primary template.
+      Diag(TemplateNameLoc, diag::err_partial_spec_args_match_primary_template)
+        << (TUK == TUK_Definition)
+        << FixItHint::CreateRemoval(SourceRange(LAngleLoc, RAngleLoc));
+      return CheckClassTemplate(S, TagSpec, TUK, KWLoc, SS,
+                                ClassTemplate->getIdentifier(),
+                                TemplateNameLoc,
+                                Attr,
+                                TemplateParams,
+                                AS_none);
+    }
+
+    // FIXME: Diagnose friend partial specializations
+
+    if (!Name.isDependent() && 
+        !TemplateSpecializationType::anyDependentTemplateArguments(
+                                             TemplateArgs.getArgumentArray(), 
+                                                         TemplateArgs.size())) {
+      Diag(TemplateNameLoc, diag::err_partial_spec_fully_specialized)
+        << ClassTemplate->getDeclName();
+      isPartialSpecialization = false;
+    } else {
+      // FIXME: Template parameter list matters, too
+      ClassTemplatePartialSpecializationDecl::Profile(ID,
+                                                  Converted.getFlatArguments(),
+                                                      Converted.flatSize(),
+                                                      Context);
+    }
+  }
+  
+  if (!isPartialSpecialization)
+    ClassTemplateSpecializationDecl::Profile(ID,
+                                             Converted.getFlatArguments(),
+                                             Converted.flatSize(),
+                                             Context);
+  void *InsertPos = 0;
+  ClassTemplateSpecializationDecl *PrevDecl = 0;
+
+  if (isPartialSpecialization)
+    PrevDecl
+      = ClassTemplate->getPartialSpecializations().FindNodeOrInsertPos(ID,
+                                                                    InsertPos);
+  else
+    PrevDecl
+      = ClassTemplate->getSpecializations().FindNodeOrInsertPos(ID, InsertPos);
+
+  ClassTemplateSpecializationDecl *Specialization = 0;
+
+  // Check whether we can declare a class template specialization in
+  // the current scope.
+  if (TUK != TUK_Friend &&
+      CheckTemplateSpecializationScope(*this, ClassTemplate, PrevDecl, 
+                                       TemplateNameLoc, 
+                                       isPartialSpecialization))
+    return true;
+  
+  // The canonical type
+  QualType CanonType;
+  if (PrevDecl && 
+      (PrevDecl->getSpecializationKind() == TSK_Undeclared ||
+               TUK == TUK_Friend)) {
+    // Since the only prior class template specialization with these
+    // arguments was referenced but not declared, or we're only
+    // referencing this specialization as a friend, reuse that
+    // declaration node as our own, updating its source location to
+    // reflect our new declaration.
+    Specialization = PrevDecl;
+    Specialization->setLocation(TemplateNameLoc);
+    PrevDecl = 0;
+    CanonType = Context.getTypeDeclType(Specialization);
+  } else if (isPartialSpecialization) {
+    // Build the canonical type that describes the converted template
+    // arguments of the class template partial specialization.
+    TemplateName CanonTemplate = Context.getCanonicalTemplateName(Name);
+    CanonType = Context.getTemplateSpecializationType(CanonTemplate,
+                                                  Converted.getFlatArguments(),
+                                                  Converted.flatSize());
+
+    // Create a new class template partial specialization declaration node.
+    ClassTemplatePartialSpecializationDecl *PrevPartial
+      = cast_or_null<ClassTemplatePartialSpecializationDecl>(PrevDecl);
+    ClassTemplatePartialSpecializationDecl *Partial
+      = ClassTemplatePartialSpecializationDecl::Create(Context,
+                                             ClassTemplate->getDeclContext(),
+                                                       TemplateNameLoc,
+                                                       TemplateParams,
+                                                       ClassTemplate,
+                                                       Converted,
+                                                       TemplateArgs,
+                                                       CanonType,
+                                                       PrevPartial);
+    SetNestedNameSpecifier(Partial, SS);
+
+    if (PrevPartial) {
+      ClassTemplate->getPartialSpecializations().RemoveNode(PrevPartial);
+      ClassTemplate->getPartialSpecializations().GetOrInsertNode(Partial);
+    } else {
+      ClassTemplate->getPartialSpecializations().InsertNode(Partial, InsertPos);
+    }
+    Specialization = Partial;
+
+    // If we are providing an explicit specialization of a member class 
+    // template specialization, make a note of that.
+    if (PrevPartial && PrevPartial->getInstantiatedFromMember())
+      PrevPartial->setMemberSpecialization();
+    
+    // Check that all of the template parameters of the class template
+    // partial specialization are deducible from the template
+    // arguments. If not, this class template partial specialization
+    // will never be used.
+    llvm::SmallVector<bool, 8> DeducibleParams;
+    DeducibleParams.resize(TemplateParams->size());
+    MarkUsedTemplateParameters(Partial->getTemplateArgs(), true, 
+                               TemplateParams->getDepth(),
+                               DeducibleParams);
+    unsigned NumNonDeducible = 0;
+    for (unsigned I = 0, N = DeducibleParams.size(); I != N; ++I)
+      if (!DeducibleParams[I])
+        ++NumNonDeducible;
+
+    if (NumNonDeducible) {
+      Diag(TemplateNameLoc, diag::warn_partial_specs_not_deducible)
+        << (NumNonDeducible > 1)
+        << SourceRange(TemplateNameLoc, RAngleLoc);
+      for (unsigned I = 0, N = DeducibleParams.size(); I != N; ++I) {
+        if (!DeducibleParams[I]) {
+          NamedDecl *Param = cast<NamedDecl>(TemplateParams->getParam(I));
+          if (Param->getDeclName())
+            Diag(Param->getLocation(),
+                 diag::note_partial_spec_unused_parameter)
+              << Param->getDeclName();
+          else
+            Diag(Param->getLocation(),
+                 diag::note_partial_spec_unused_parameter)
+              << std::string("<anonymous>");
+        }
+      }
+    }
+  } else {
+    // Create a new class template specialization declaration node for
+    // this explicit specialization or friend declaration.
+    Specialization
+      = ClassTemplateSpecializationDecl::Create(Context,
+                                             ClassTemplate->getDeclContext(),
+                                                TemplateNameLoc,
+                                                ClassTemplate,
+                                                Converted,
+                                                PrevDecl);
+    SetNestedNameSpecifier(Specialization, SS);
+
+    if (PrevDecl) {
+      ClassTemplate->getSpecializations().RemoveNode(PrevDecl);
+      ClassTemplate->getSpecializations().GetOrInsertNode(Specialization);
+    } else {
+      ClassTemplate->getSpecializations().InsertNode(Specialization,
+                                                     InsertPos);
+    }
+
+    CanonType = Context.getTypeDeclType(Specialization);
+  }
+
+  // C++ [temp.expl.spec]p6:
+  //   If a template, a member template or the member of a class template is
+  //   explicitly specialized then that specialization shall be declared 
+  //   before the first use of that specialization that would cause an implicit
+  //   instantiation to take place, in every translation unit in which such a 
+  //   use occurs; no diagnostic is required.
+  if (PrevDecl && PrevDecl->getPointOfInstantiation().isValid()) {
+    bool Okay = false;
+    for (NamedDecl *Prev = PrevDecl; Prev; Prev = getPreviousDecl(Prev)) {
+      // Is there any previous explicit specialization declaration?
+      if (getTemplateSpecializationKind(Prev) == TSK_ExplicitSpecialization) {
+        Okay = true;
+        break;
+      }
+    }
+
+    if (!Okay) {
+      SourceRange Range(TemplateNameLoc, RAngleLoc);
+      Diag(TemplateNameLoc, diag::err_specialization_after_instantiation)
+        << Context.getTypeDeclType(Specialization) << Range;
+
+      Diag(PrevDecl->getPointOfInstantiation(), 
+           diag::note_instantiation_required_here)
+        << (PrevDecl->getTemplateSpecializationKind() 
+                                                != TSK_ImplicitInstantiation);
+      return true;
+    }
+  }
+  
+  // If this is not a friend, note that this is an explicit specialization.
+  if (TUK != TUK_Friend)
+    Specialization->setSpecializationKind(TSK_ExplicitSpecialization);
+
+  // Check that this isn't a redefinition of this specialization.
+  if (TUK == TUK_Definition) {
+    if (RecordDecl *Def = Specialization->getDefinition()) {
+      SourceRange Range(TemplateNameLoc, RAngleLoc);
+      Diag(TemplateNameLoc, diag::err_redefinition)
+        << Context.getTypeDeclType(Specialization) << Range;
+      Diag(Def->getLocation(), diag::note_previous_definition);
+      Specialization->setInvalidDecl();
+      return true;
+    }
+  }
+
+  // Build the fully-sugared type for this class template
+  // specialization as the user wrote in the specialization
+  // itself. This means that we'll pretty-print the type retrieved
+  // from the specialization's declaration the way that the user
+  // actually wrote the specialization, rather than formatting the
+  // name based on the "canonical" representation used to store the
+  // template arguments in the specialization.
+  TypeSourceInfo *WrittenTy
+    = Context.getTemplateSpecializationTypeInfo(Name, TemplateNameLoc,
+                                                TemplateArgs, CanonType);
+  if (TUK != TUK_Friend)
+    Specialization->setTypeAsWritten(WrittenTy);
+  TemplateArgsIn.release();
+
+  // C++ [temp.expl.spec]p9:
+  //   A template explicit specialization is in the scope of the
+  //   namespace in which the template was defined.
+  //
+  // We actually implement this paragraph where we set the semantic
+  // context (in the creation of the ClassTemplateSpecializationDecl),
+  // but we also maintain the lexical context where the actual
+  // definition occurs.
+  Specialization->setLexicalDeclContext(CurContext);
+
+  // We may be starting the definition of this specialization.
+  if (TUK == TUK_Definition)
+    Specialization->startDefinition();
+
+  if (TUK == TUK_Friend) {
+    FriendDecl *Friend = FriendDecl::Create(Context, CurContext,
+                                            TemplateNameLoc,
+                                            WrittenTy,
+                                            /*FIXME:*/KWLoc);
+    Friend->setAccess(AS_public);
+    CurContext->addDecl(Friend);
+  } else {
+    // Add the specialization into its lexical context, so that it can
+    // be seen when iterating through the list of declarations in that
+    // context. However, specializations are not found by name lookup.
+    CurContext->addDecl(Specialization);
+  }
+  return DeclPtrTy::make(Specialization);
+}
+
+Sema::DeclPtrTy
+Sema::ActOnTemplateDeclarator(Scope *S,
+                              MultiTemplateParamsArg TemplateParameterLists,
+                              Declarator &D) {
+  return HandleDeclarator(S, D, move(TemplateParameterLists), false);
+}
+
+Sema::DeclPtrTy
+Sema::ActOnStartOfFunctionTemplateDef(Scope *FnBodyScope,
+                               MultiTemplateParamsArg TemplateParameterLists,
+                                      Declarator &D) {
+  assert(getCurFunctionDecl() == 0 && "Function parsing confused");
+  assert(D.getTypeObject(0).Kind == DeclaratorChunk::Function &&
+         "Not a function declarator!");
+  DeclaratorChunk::FunctionTypeInfo &FTI = D.getTypeObject(0).Fun;
+
+  if (FTI.hasPrototype) {
+    // FIXME: Diagnose arguments without names in C.
+  }
+
+  Scope *ParentScope = FnBodyScope->getParent();
+
+  DeclPtrTy DP = HandleDeclarator(ParentScope, D,
+                                  move(TemplateParameterLists),
+                                  /*IsFunctionDefinition=*/true);
+  if (FunctionTemplateDecl *FunctionTemplate
+        = dyn_cast_or_null<FunctionTemplateDecl>(DP.getAs<Decl>()))
+    return ActOnStartOfFunctionDef(FnBodyScope,
+                      DeclPtrTy::make(FunctionTemplate->getTemplatedDecl()));
+  if (FunctionDecl *Function = dyn_cast_or_null<FunctionDecl>(DP.getAs<Decl>()))
+    return ActOnStartOfFunctionDef(FnBodyScope, DeclPtrTy::make(Function));
+  return DeclPtrTy();
+}
+
+/// \brief Strips various properties off an implicit instantiation
+/// that has just been explicitly specialized.
+static void StripImplicitInstantiation(NamedDecl *D) {
+  D->invalidateAttrs();
+
+  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+    FD->setInlineSpecified(false);
+  }
+}
+
+/// \brief Diagnose cases where we have an explicit template specialization 
+/// before/after an explicit template instantiation, producing diagnostics
+/// for those cases where they are required and determining whether the 
+/// new specialization/instantiation will have any effect.
+///
+/// \param NewLoc the location of the new explicit specialization or 
+/// instantiation.
+///
+/// \param NewTSK the kind of the new explicit specialization or instantiation.
+///
+/// \param PrevDecl the previous declaration of the entity.
+///
+/// \param PrevTSK the kind of the old explicit specialization or instantiatin.
+///
+/// \param PrevPointOfInstantiation if valid, indicates where the previus 
+/// declaration was instantiated (either implicitly or explicitly).
+///
+/// \param SuppressNew will be set to true to indicate that the new 
+/// specialization or instantiation has no effect and should be ignored.
+///
+/// \returns true if there was an error that should prevent the introduction of
+/// the new declaration into the AST, false otherwise.
+bool
+Sema::CheckSpecializationInstantiationRedecl(SourceLocation NewLoc,
+                                             TemplateSpecializationKind NewTSK,
+                                             NamedDecl *PrevDecl,
+                                             TemplateSpecializationKind PrevTSK,
+                                        SourceLocation PrevPointOfInstantiation,
+                                             bool &SuppressNew) {
+  SuppressNew = false;
+  
+  switch (NewTSK) {
+  case TSK_Undeclared:
+  case TSK_ImplicitInstantiation:
+    assert(false && "Don't check implicit instantiations here");
+    return false;
+    
+  case TSK_ExplicitSpecialization:
+    switch (PrevTSK) {
+    case TSK_Undeclared:
+    case TSK_ExplicitSpecialization:
+      // Okay, we're just specializing something that is either already 
+      // explicitly specialized or has merely been mentioned without any
+      // instantiation.
+      return false;
+
+    case TSK_ImplicitInstantiation:
+      if (PrevPointOfInstantiation.isInvalid()) {
+        // The declaration itself has not actually been instantiated, so it is
+        // still okay to specialize it.
+        StripImplicitInstantiation(PrevDecl);
+        return false;
+      }
+      // Fall through
+        
+    case TSK_ExplicitInstantiationDeclaration:
+    case TSK_ExplicitInstantiationDefinition:
+      assert((PrevTSK == TSK_ImplicitInstantiation || 
+              PrevPointOfInstantiation.isValid()) && 
+             "Explicit instantiation without point of instantiation?");
+        
+      // C++ [temp.expl.spec]p6:
+      //   If a template, a member template or the member of a class template 
+      //   is explicitly specialized then that specialization shall be declared
+      //   before the first use of that specialization that would cause an 
+      //   implicit instantiation to take place, in every translation unit in
+      //   which such a use occurs; no diagnostic is required.
+      for (NamedDecl *Prev = PrevDecl; Prev; Prev = getPreviousDecl(Prev)) {
+        // Is there any previous explicit specialization declaration?
+        if (getTemplateSpecializationKind(Prev) == TSK_ExplicitSpecialization)
+          return false;
+      }
+
+      Diag(NewLoc, diag::err_specialization_after_instantiation)
+        << PrevDecl;
+      Diag(PrevPointOfInstantiation, diag::note_instantiation_required_here)
+        << (PrevTSK != TSK_ImplicitInstantiation);
+      
+      return true;
+    }
+    break;
+      
+  case TSK_ExplicitInstantiationDeclaration:
+    switch (PrevTSK) {
+    case TSK_ExplicitInstantiationDeclaration:
+      // This explicit instantiation declaration is redundant (that's okay).
+      SuppressNew = true;
+      return false;
+        
+    case TSK_Undeclared:
+    case TSK_ImplicitInstantiation:
+      // We're explicitly instantiating something that may have already been
+      // implicitly instantiated; that's fine.
+      return false;
+        
+    case TSK_ExplicitSpecialization:
+      // C++0x [temp.explicit]p4:
+      //   For a given set of template parameters, if an explicit instantiation
+      //   of a template appears after a declaration of an explicit 
+      //   specialization for that template, the explicit instantiation has no
+      //   effect.
+      SuppressNew = true;
+      return false;
+        
+    case TSK_ExplicitInstantiationDefinition:
+      // C++0x [temp.explicit]p10:
+      //   If an entity is the subject of both an explicit instantiation 
+      //   declaration and an explicit instantiation definition in the same 
+      //   translation unit, the definition shall follow the declaration.
+      Diag(NewLoc, 
+           diag::err_explicit_instantiation_declaration_after_definition);
+      Diag(PrevPointOfInstantiation, 
+           diag::note_explicit_instantiation_definition_here);
+      assert(PrevPointOfInstantiation.isValid() &&
+             "Explicit instantiation without point of instantiation?");
+      SuppressNew = true;
+      return false;
+    }
+    break;
+      
+  case TSK_ExplicitInstantiationDefinition:
+    switch (PrevTSK) {
+    case TSK_Undeclared:
+    case TSK_ImplicitInstantiation:
+      // We're explicitly instantiating something that may have already been
+      // implicitly instantiated; that's fine.
+      return false;
+        
+    case TSK_ExplicitSpecialization:
+      // C++ DR 259, C++0x [temp.explicit]p4:
+      //   For a given set of template parameters, if an explicit
+      //   instantiation of a template appears after a declaration of
+      //   an explicit specialization for that template, the explicit
+      //   instantiation has no effect.
+      //
+      // In C++98/03 mode, we only give an extension warning here, because it 
+      // is not harmful to try to explicitly instantiate something that
+      // has been explicitly specialized.
+      if (!getLangOptions().CPlusPlus0x) {
+        Diag(NewLoc, diag::ext_explicit_instantiation_after_specialization)
+          << PrevDecl;
+        Diag(PrevDecl->getLocation(),
+             diag::note_previous_template_specialization);
+      }
+      SuppressNew = true;
+      return false;
+        
+    case TSK_ExplicitInstantiationDeclaration:
+      // We're explicity instantiating a definition for something for which we
+      // were previously asked to suppress instantiations. That's fine. 
+      return false;
+        
+    case TSK_ExplicitInstantiationDefinition:
+      // C++0x [temp.spec]p5:
+      //   For a given template and a given set of template-arguments,
+      //     - an explicit instantiation definition shall appear at most once
+      //       in a program,
+      Diag(NewLoc, diag::err_explicit_instantiation_duplicate)
+        << PrevDecl;
+      Diag(PrevPointOfInstantiation, 
+           diag::note_previous_explicit_instantiation);
+      SuppressNew = true;
+      return false;        
+    }
+    break;
+  }
+  
+  assert(false && "Missing specialization/instantiation case?");
+         
+  return false;
+}
+
+/// \brief Perform semantic analysis for the given dependent function
+/// template specialization.  The only possible way to get a dependent
+/// function template specialization is with a friend declaration,
+/// like so:
+///
+///   template <class T> void foo(T);
+///   template <class T> class A {
+///     friend void foo<>(T);
+///   };
+///
+/// There really isn't any useful analysis we can do here, so we
+/// just store the information.
+bool
+Sema::CheckDependentFunctionTemplateSpecialization(FunctionDecl *FD,
+                   const TemplateArgumentListInfo &ExplicitTemplateArgs,
+                                                   LookupResult &Previous) {
+  // Remove anything from Previous that isn't a function template in
+  // the correct context.
+  DeclContext *FDLookupContext = FD->getDeclContext()->getLookupContext();
+  LookupResult::Filter F = Previous.makeFilter();
+  while (F.hasNext()) {
+    NamedDecl *D = F.next()->getUnderlyingDecl();
+    if (!isa<FunctionTemplateDecl>(D) ||
+        !FDLookupContext->Equals(D->getDeclContext()->getLookupContext()))
+      F.erase();
+  }
+  F.done();
+
+  // Should this be diagnosed here?
+  if (Previous.empty()) return true;
+
+  FD->setDependentTemplateSpecialization(Context, Previous.asUnresolvedSet(),
+                                         ExplicitTemplateArgs);
+  return false;
+}
+
+/// \brief Perform semantic analysis for the given function template 
+/// specialization.
+///
+/// This routine performs all of the semantic analysis required for an 
+/// explicit function template specialization. On successful completion,
+/// the function declaration \p FD will become a function template
+/// specialization.
+///
+/// \param FD the function declaration, which will be updated to become a
+/// function template specialization.
+///
+/// \param HasExplicitTemplateArgs whether any template arguments were
+/// explicitly provided.
+///
+/// \param LAngleLoc the location of the left angle bracket ('<'), if
+/// template arguments were explicitly provided.
+///
+/// \param ExplicitTemplateArgs the explicitly-provided template arguments, 
+/// if any.
+///
+/// \param NumExplicitTemplateArgs the number of explicitly-provided template
+/// arguments. This number may be zero even when HasExplicitTemplateArgs is
+/// true as in, e.g., \c void sort<>(char*, char*);
+///
+/// \param RAngleLoc the location of the right angle bracket ('>'), if
+/// template arguments were explicitly provided.
+/// 
+/// \param PrevDecl the set of declarations that 
+bool 
+Sema::CheckFunctionTemplateSpecialization(FunctionDecl *FD,
+                        const TemplateArgumentListInfo *ExplicitTemplateArgs,
+                                          LookupResult &Previous) {
+  // The set of function template specializations that could match this
+  // explicit function template specialization.
+  UnresolvedSet<8> Candidates;
+  
+  DeclContext *FDLookupContext = FD->getDeclContext()->getLookupContext();
+  for (LookupResult::iterator I = Previous.begin(), E = Previous.end();
+         I != E; ++I) {
+    NamedDecl *Ovl = (*I)->getUnderlyingDecl();
+    if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(Ovl)) {
+      // Only consider templates found within the same semantic lookup scope as 
+      // FD.
+      if (!FDLookupContext->Equals(Ovl->getDeclContext()->getLookupContext()))
+        continue;
+      
+      // C++ [temp.expl.spec]p11:
+      //   A trailing template-argument can be left unspecified in the 
+      //   template-id naming an explicit function template specialization 
+      //   provided it can be deduced from the function argument type.
+      // Perform template argument deduction to determine whether we may be
+      // specializing this template.
+      // FIXME: It is somewhat wasteful to build
+      TemplateDeductionInfo Info(Context, FD->getLocation());
+      FunctionDecl *Specialization = 0;
+      if (TemplateDeductionResult TDK
+            = DeduceTemplateArguments(FunTmpl, ExplicitTemplateArgs,
+                                      FD->getType(),
+                                      Specialization,
+                                      Info)) {
+        // FIXME: Template argument deduction failed; record why it failed, so
+        // that we can provide nifty diagnostics.
+        (void)TDK;
+        continue;
+      }
+      
+      // Record this candidate.
+      Candidates.addDecl(Specialization, I.getAccess());
+    }
+  }
+  
+  // Find the most specialized function template.
+  UnresolvedSetIterator Result
+    = getMostSpecialized(Candidates.begin(), Candidates.end(),
+                         TPOC_Other, FD->getLocation(),
+                  PDiag(diag::err_function_template_spec_no_match) 
+                    << FD->getDeclName(),
+                  PDiag(diag::err_function_template_spec_ambiguous)
+                    << FD->getDeclName() << (ExplicitTemplateArgs != 0),
+                  PDiag(diag::note_function_template_spec_matched));
+  if (Result == Candidates.end())
+    return true;
+
+  // Ignore access information;  it doesn't figure into redeclaration checking.
+  FunctionDecl *Specialization = cast<FunctionDecl>(*Result);
+  Specialization->setLocation(FD->getLocation());
+  
+  // FIXME: Check if the prior specialization has a point of instantiation.
+  // If so, we have run afoul of .
+
+  // If this is a friend declaration, then we're not really declaring
+  // an explicit specialization.
+  bool isFriend = (FD->getFriendObjectKind() != Decl::FOK_None);
+  
+  // Check the scope of this explicit specialization.
+  if (!isFriend &&
+      CheckTemplateSpecializationScope(*this, 
+                                       Specialization->getPrimaryTemplate(),
+                                       Specialization, FD->getLocation(), 
+                                       false))
+    return true;
+
+  // C++ [temp.expl.spec]p6:
+  //   If a template, a member template or the member of a class template is
+  //   explicitly specialized then that specialization shall be declared 
+  //   before the first use of that specialization that would cause an implicit
+  //   instantiation to take place, in every translation unit in which such a 
+  //   use occurs; no diagnostic is required.
+  FunctionTemplateSpecializationInfo *SpecInfo
+    = Specialization->getTemplateSpecializationInfo();
+  assert(SpecInfo && "Function template specialization info missing?");
+
+  bool SuppressNew = false;
+  if (!isFriend &&
+      CheckSpecializationInstantiationRedecl(FD->getLocation(),
+                                             TSK_ExplicitSpecialization,
+                                             Specialization,
+                                   SpecInfo->getTemplateSpecializationKind(),
+                                         SpecInfo->getPointOfInstantiation(),
+                                             SuppressNew))
+    return true;
+  
+  // Mark the prior declaration as an explicit specialization, so that later
+  // clients know that this is an explicit specialization.
+  if (!isFriend)
+    SpecInfo->setTemplateSpecializationKind(TSK_ExplicitSpecialization);
+  
+  // Turn the given function declaration into a function template
+  // specialization, with the template arguments from the previous
+  // specialization.
+  FD->setFunctionTemplateSpecialization(Specialization->getPrimaryTemplate(),
+                         new (Context) TemplateArgumentList(
+                             *Specialization->getTemplateSpecializationArgs()), 
+                                        /*InsertPos=*/0, 
+                                    SpecInfo->getTemplateSpecializationKind());
+  
+  // The "previous declaration" for this function template specialization is
+  // the prior function template specialization.
+  Previous.clear();
+  Previous.addDecl(Specialization);
+  return false;
+}
+
+/// \brief Perform semantic analysis for the given non-template member
+/// specialization.
+///
+/// This routine performs all of the semantic analysis required for an 
+/// explicit member function specialization. On successful completion,
+/// the function declaration \p FD will become a member function
+/// specialization.
+///
+/// \param Member the member declaration, which will be updated to become a
+/// specialization.
+///
+/// \param Previous the set of declarations, one of which may be specialized
+/// by this function specialization;  the set will be modified to contain the
+/// redeclared member.
+bool 
+Sema::CheckMemberSpecialization(NamedDecl *Member, LookupResult &Previous) {
+  assert(!isa<TemplateDecl>(Member) && "Only for non-template members");
+
+  // Try to find the member we are instantiating.
+  NamedDecl *Instantiation = 0;
+  NamedDecl *InstantiatedFrom = 0;
+  MemberSpecializationInfo *MSInfo = 0;
+
+  if (Previous.empty()) {
+    // Nowhere to look anyway.
+  } else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(Member)) {
+    for (LookupResult::iterator I = Previous.begin(), E = Previous.end();
+           I != E; ++I) {
+      NamedDecl *D = (*I)->getUnderlyingDecl();
+      if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) {
+        if (Context.hasSameType(Function->getType(), Method->getType())) {
+          Instantiation = Method;
+          InstantiatedFrom = Method->getInstantiatedFromMemberFunction();
+          MSInfo = Method->getMemberSpecializationInfo();
+          break;
+        }
+      }
+    }
+  } else if (isa<VarDecl>(Member)) {
+    VarDecl *PrevVar;
+    if (Previous.isSingleResult() &&
+        (PrevVar = dyn_cast<VarDecl>(Previous.getFoundDecl())))
+      if (PrevVar->isStaticDataMember()) {
+        Instantiation = PrevVar;
+        InstantiatedFrom = PrevVar->getInstantiatedFromStaticDataMember();
+        MSInfo = PrevVar->getMemberSpecializationInfo();
+      }
+  } else if (isa<RecordDecl>(Member)) {
+    CXXRecordDecl *PrevRecord;
+    if (Previous.isSingleResult() &&
+        (PrevRecord = dyn_cast<CXXRecordDecl>(Previous.getFoundDecl()))) {
+      Instantiation = PrevRecord;
+      InstantiatedFrom = PrevRecord->getInstantiatedFromMemberClass();
+      MSInfo = PrevRecord->getMemberSpecializationInfo();
+    }
+  }
+  
+  if (!Instantiation) {
+    // There is no previous declaration that matches. Since member
+    // specializations are always out-of-line, the caller will complain about
+    // this mismatch later.
+    return false;
+  }
+
+  // If this is a friend, just bail out here before we start turning
+  // things into explicit specializations.
+  if (Member->getFriendObjectKind() != Decl::FOK_None) {
+    // Preserve instantiation information.
+    if (InstantiatedFrom && isa<CXXMethodDecl>(Member)) {
+      cast<CXXMethodDecl>(Member)->setInstantiationOfMemberFunction(
+                                      cast<CXXMethodDecl>(InstantiatedFrom),
+        cast<CXXMethodDecl>(Instantiation)->getTemplateSpecializationKind());
+    } else if (InstantiatedFrom && isa<CXXRecordDecl>(Member)) {
+      cast<CXXRecordDecl>(Member)->setInstantiationOfMemberClass(
+                                      cast<CXXRecordDecl>(InstantiatedFrom),
+        cast<CXXRecordDecl>(Instantiation)->getTemplateSpecializationKind());
+    }
+
+    Previous.clear();
+    Previous.addDecl(Instantiation);
+    return false;
+  }
+  
+  // Make sure that this is a specialization of a member.
+  if (!InstantiatedFrom) {
+    Diag(Member->getLocation(), diag::err_spec_member_not_instantiated)
+      << Member;
+    Diag(Instantiation->getLocation(), diag::note_specialized_decl);
+    return true;
+  }
+  
+  // C++ [temp.expl.spec]p6:
+  //   If a template, a member template or the member of a class template is
+  //   explicitly specialized then that spe- cialization shall be declared 
+  //   before the first use of that specialization that would cause an implicit
+  //   instantiation to take place, in every translation unit in which such a 
+  //   use occurs; no diagnostic is required.
+  assert(MSInfo && "Member specialization info missing?");
+
+  bool SuppressNew = false;
+  if (CheckSpecializationInstantiationRedecl(Member->getLocation(),
+                                             TSK_ExplicitSpecialization,
+                                             Instantiation,
+                                     MSInfo->getTemplateSpecializationKind(),
+                                           MSInfo->getPointOfInstantiation(),
+                                             SuppressNew))
+    return true;
+  
+  // Check the scope of this explicit specialization.
+  if (CheckTemplateSpecializationScope(*this, 
+                                       InstantiatedFrom,
+                                       Instantiation, Member->getLocation(), 
+                                       false))
+    return true;
+
+  // Note that this is an explicit instantiation of a member.
+  // the original declaration to note that it is an explicit specialization
+  // (if it was previously an implicit instantiation). This latter step
+  // makes bookkeeping easier.
+  if (isa<FunctionDecl>(Member)) {
+    FunctionDecl *InstantiationFunction = cast<FunctionDecl>(Instantiation);
+    if (InstantiationFunction->getTemplateSpecializationKind() ==
+          TSK_ImplicitInstantiation) {
+      InstantiationFunction->setTemplateSpecializationKind(
+                                                  TSK_ExplicitSpecialization);
+      InstantiationFunction->setLocation(Member->getLocation());
+    }
+    
+    cast<FunctionDecl>(Member)->setInstantiationOfMemberFunction(
+                                        cast<CXXMethodDecl>(InstantiatedFrom),
+                                                  TSK_ExplicitSpecialization);
+  } else if (isa<VarDecl>(Member)) {
+    VarDecl *InstantiationVar = cast<VarDecl>(Instantiation);
+    if (InstantiationVar->getTemplateSpecializationKind() ==
+          TSK_ImplicitInstantiation) {
+      InstantiationVar->setTemplateSpecializationKind(
+                                                  TSK_ExplicitSpecialization);
+      InstantiationVar->setLocation(Member->getLocation());
+    }
+    
+    Context.setInstantiatedFromStaticDataMember(cast<VarDecl>(Member),
+                                                cast<VarDecl>(InstantiatedFrom),
+                                                TSK_ExplicitSpecialization);
+  } else {
+    assert(isa<CXXRecordDecl>(Member) && "Only member classes remain");
+    CXXRecordDecl *InstantiationClass = cast<CXXRecordDecl>(Instantiation);
+    if (InstantiationClass->getTemplateSpecializationKind() ==
+          TSK_ImplicitInstantiation) {
+      InstantiationClass->setTemplateSpecializationKind(
+                                                   TSK_ExplicitSpecialization);
+      InstantiationClass->setLocation(Member->getLocation());
+    }
+    
+    cast<CXXRecordDecl>(Member)->setInstantiationOfMemberClass(
+                                        cast<CXXRecordDecl>(InstantiatedFrom),
+                                                   TSK_ExplicitSpecialization);
+  }
+             
+  // Save the caller the trouble of having to figure out which declaration
+  // this specialization matches.
+  Previous.clear();
+  Previous.addDecl(Instantiation);
+  return false;
+}
+
+/// \brief Check the scope of an explicit instantiation.
+static void CheckExplicitInstantiationScope(Sema &S, NamedDecl *D,
+                                            SourceLocation InstLoc,
+                                            bool WasQualifiedName) {
+  DeclContext *ExpectedContext
+    = D->getDeclContext()->getEnclosingNamespaceContext()->getLookupContext();
+  DeclContext *CurContext = S.CurContext->getLookupContext();
+  
+  // C++0x [temp.explicit]p2:
+  //   An explicit instantiation shall appear in an enclosing namespace of its 
+  //   template.
+  //
+  // This is DR275, which we do not retroactively apply to C++98/03.
+  if (S.getLangOptions().CPlusPlus0x && 
+      !CurContext->Encloses(ExpectedContext)) {
+    if (NamespaceDecl *NS = dyn_cast<NamespaceDecl>(ExpectedContext))
+      S.Diag(InstLoc, diag::err_explicit_instantiation_out_of_scope)
+        << D << NS;
+    else
+      S.Diag(InstLoc, diag::err_explicit_instantiation_must_be_global)
+        << D;
+    S.Diag(D->getLocation(), diag::note_explicit_instantiation_here);
+    return;
+  }
+  
+  // C++0x [temp.explicit]p2:
+  //   If the name declared in the explicit instantiation is an unqualified 
+  //   name, the explicit instantiation shall appear in the namespace where 
+  //   its template is declared or, if that namespace is inline (7.3.1), any
+  //   namespace from its enclosing namespace set.
+  if (WasQualifiedName)
+    return;
+  
+  if (CurContext->Equals(ExpectedContext))
+    return;
+  
+  S.Diag(InstLoc, diag::err_explicit_instantiation_unqualified_wrong_namespace)
+    << D << ExpectedContext;
+  S.Diag(D->getLocation(), diag::note_explicit_instantiation_here);
+}
+
+/// \brief Determine whether the given scope specifier has a template-id in it.
+static bool ScopeSpecifierHasTemplateId(const CXXScopeSpec &SS) {
+  if (!SS.isSet())
+    return false;
+  
+  // C++0x [temp.explicit]p2:
+  //   If the explicit instantiation is for a member function, a member class 
+  //   or a static data member of a class template specialization, the name of
+  //   the class template specialization in the qualified-id for the member
+  //   name shall be a simple-template-id.
+  //
+  // C++98 has the same restriction, just worded differently.
+  for (NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
+       NNS; NNS = NNS->getPrefix())
+    if (Type *T = NNS->getAsType())
+      if (isa<TemplateSpecializationType>(T))
+        return true;
+
+  return false;
+}
+
+// Explicit instantiation of a class template specialization
+// FIXME: Implement extern template semantics
+Sema::DeclResult
+Sema::ActOnExplicitInstantiation(Scope *S,
+                                 SourceLocation ExternLoc,
+                                 SourceLocation TemplateLoc,
+                                 unsigned TagSpec,
+                                 SourceLocation KWLoc,
+                                 const CXXScopeSpec &SS,
+                                 TemplateTy TemplateD,
+                                 SourceLocation TemplateNameLoc,
+                                 SourceLocation LAngleLoc,
+                                 ASTTemplateArgsPtr TemplateArgsIn,
+                                 SourceLocation RAngleLoc,
+                                 AttributeList *Attr) {
+  // Find the class template we're specializing
+  TemplateName Name = TemplateD.getAsVal<TemplateName>();
+  ClassTemplateDecl *ClassTemplate
+    = cast<ClassTemplateDecl>(Name.getAsTemplateDecl());
+
+  // Check that the specialization uses the same tag kind as the
+  // original template.
+  TagDecl::TagKind Kind;
+  switch (TagSpec) {
+  default: assert(0 && "Unknown tag type!");
+  case DeclSpec::TST_struct: Kind = TagDecl::TK_struct; break;
+  case DeclSpec::TST_union:  Kind = TagDecl::TK_union; break;
+  case DeclSpec::TST_class:  Kind = TagDecl::TK_class; break;
+  }
+  if (!isAcceptableTagRedeclaration(ClassTemplate->getTemplatedDecl(),
+                                    Kind, KWLoc,
+                                    *ClassTemplate->getIdentifier())) {
+    Diag(KWLoc, diag::err_use_with_wrong_tag)
+      << ClassTemplate
+      << FixItHint::CreateReplacement(KWLoc,
+                            ClassTemplate->getTemplatedDecl()->getKindName());
+    Diag(ClassTemplate->getTemplatedDecl()->getLocation(),
+         diag::note_previous_use);
+    Kind = ClassTemplate->getTemplatedDecl()->getTagKind();
+  }
+
+  // C++0x [temp.explicit]p2:
+  //   There are two forms of explicit instantiation: an explicit instantiation
+  //   definition and an explicit instantiation declaration. An explicit 
+  //   instantiation declaration begins with the extern keyword. [...]  
+  TemplateSpecializationKind TSK
+    = ExternLoc.isInvalid()? TSK_ExplicitInstantiationDefinition
+                           : TSK_ExplicitInstantiationDeclaration;
+  
+  // Translate the parser's template argument list in our AST format.
+  TemplateArgumentListInfo TemplateArgs(LAngleLoc, RAngleLoc);
+  translateTemplateArguments(TemplateArgsIn, TemplateArgs);
+
+  // Check that the template argument list is well-formed for this
+  // template.
+  TemplateArgumentListBuilder Converted(ClassTemplate->getTemplateParameters(),
+                                        TemplateArgs.size());
+  if (CheckTemplateArgumentList(ClassTemplate, TemplateNameLoc,
+                                TemplateArgs, false, Converted))
+    return true;
+
+  assert((Converted.structuredSize() ==
+            ClassTemplate->getTemplateParameters()->size()) &&
+         "Converted template argument list is too short!");
+
+  // Find the class template specialization declaration that
+  // corresponds to these arguments.
+  llvm::FoldingSetNodeID ID;
+  ClassTemplateSpecializationDecl::Profile(ID,
+                                           Converted.getFlatArguments(),
+                                           Converted.flatSize(),
+                                           Context);
+  void *InsertPos = 0;
+  ClassTemplateSpecializationDecl *PrevDecl
+    = ClassTemplate->getSpecializations().FindNodeOrInsertPos(ID, InsertPos);
+
+  // C++0x [temp.explicit]p2:
+  //   [...] An explicit instantiation shall appear in an enclosing
+  //   namespace of its template. [...]
+  //
+  // This is C++ DR 275.
+  CheckExplicitInstantiationScope(*this, ClassTemplate, TemplateNameLoc,
+                                  SS.isSet());
+  
+  ClassTemplateSpecializationDecl *Specialization = 0;
+
+  bool ReusedDecl = false;
+  if (PrevDecl) {
+    bool SuppressNew = false;
+    if (CheckSpecializationInstantiationRedecl(TemplateNameLoc, TSK,
+                                               PrevDecl, 
+                                              PrevDecl->getSpecializationKind(), 
+                                            PrevDecl->getPointOfInstantiation(),
+                                               SuppressNew))
+      return DeclPtrTy::make(PrevDecl);
+
+    if (SuppressNew)
+      return DeclPtrTy::make(PrevDecl);
+    
+    if (PrevDecl->getSpecializationKind() == TSK_ImplicitInstantiation ||
+        PrevDecl->getSpecializationKind() == TSK_Undeclared) {
+      // Since the only prior class template specialization with these
+      // arguments was referenced but not declared, reuse that
+      // declaration node as our own, updating its source location to
+      // reflect our new declaration.
+      Specialization = PrevDecl;
+      Specialization->setLocation(TemplateNameLoc);
+      PrevDecl = 0;
+      ReusedDecl = true;
+    }
+  }
+  
+  if (!Specialization) {
+    // Create a new class template specialization declaration node for
+    // this explicit specialization.
+    Specialization
+      = ClassTemplateSpecializationDecl::Create(Context,
+                                             ClassTemplate->getDeclContext(),
+                                                TemplateNameLoc,
+                                                ClassTemplate,
+                                                Converted, PrevDecl);
+    SetNestedNameSpecifier(Specialization, SS);
+
+    if (PrevDecl) {
+      // Remove the previous declaration from the folding set, since we want
+      // to introduce a new declaration.
+      ClassTemplate->getSpecializations().RemoveNode(PrevDecl);
+      ClassTemplate->getSpecializations().FindNodeOrInsertPos(ID, InsertPos);
+    } 
+    
+    // Insert the new specialization.
+    ClassTemplate->getSpecializations().InsertNode(Specialization, InsertPos);
+  }
+
+  // Build the fully-sugared type for this explicit instantiation as
+  // the user wrote in the explicit instantiation itself. This means
+  // that we'll pretty-print the type retrieved from the
+  // specialization's declaration the way that the user actually wrote
+  // the explicit instantiation, rather than formatting the name based
+  // on the "canonical" representation used to store the template
+  // arguments in the specialization.
+  TypeSourceInfo *WrittenTy
+    = Context.getTemplateSpecializationTypeInfo(Name, TemplateNameLoc,
+                                                TemplateArgs,
+                                  Context.getTypeDeclType(Specialization));
+  Specialization->setTypeAsWritten(WrittenTy);
+  TemplateArgsIn.release();
+
+  if (!ReusedDecl) {
+    // Add the explicit instantiation into its lexical context. However,
+    // since explicit instantiations are never found by name lookup, we
+    // just put it into the declaration context directly.
+    Specialization->setLexicalDeclContext(CurContext);
+    CurContext->addDecl(Specialization);
+  }
+
+  // C++ [temp.explicit]p3:
+  //   A definition of a class template or class member template
+  //   shall be in scope at the point of the explicit instantiation of
+  //   the class template or class member template.
+  //
+  // This check comes when we actually try to perform the
+  // instantiation.
+  ClassTemplateSpecializationDecl *Def
+    = cast_or_null<ClassTemplateSpecializationDecl>(
+                                              Specialization->getDefinition());
+  if (!Def)
+    InstantiateClassTemplateSpecialization(TemplateNameLoc, Specialization, TSK);
+  
+  // Instantiate the members of this class template specialization.
+  Def = cast_or_null<ClassTemplateSpecializationDecl>(
+                                       Specialization->getDefinition());
+  if (Def) {
+    TemplateSpecializationKind Old_TSK = Def->getTemplateSpecializationKind();
+
+    // Fix a TSK_ExplicitInstantiationDeclaration followed by a
+    // TSK_ExplicitInstantiationDefinition
+    if (Old_TSK == TSK_ExplicitInstantiationDeclaration &&
+        TSK == TSK_ExplicitInstantiationDefinition)
+      Def->setTemplateSpecializationKind(TSK);
+
+    InstantiateClassTemplateSpecializationMembers(TemplateNameLoc, Def, TSK);
+  }
+
+  return DeclPtrTy::make(Specialization);
+}
+
+// Explicit instantiation of a member class of a class template.
+Sema::DeclResult
+Sema::ActOnExplicitInstantiation(Scope *S,
+                                 SourceLocation ExternLoc,
+                                 SourceLocation TemplateLoc,
+                                 unsigned TagSpec,
+                                 SourceLocation KWLoc,
+                                 CXXScopeSpec &SS,
+                                 IdentifierInfo *Name,
+                                 SourceLocation NameLoc,
+                                 AttributeList *Attr) {
+
+  bool Owned = false;
+  bool IsDependent = false;
+  DeclPtrTy TagD = ActOnTag(S, TagSpec, Action::TUK_Reference,
+                            KWLoc, SS, Name, NameLoc, Attr, AS_none,
+                            MultiTemplateParamsArg(*this, 0, 0),
+                            Owned, IsDependent);
+  assert(!IsDependent && "explicit instantiation of dependent name not yet handled");
+
+  if (!TagD)
+    return true;
+
+  TagDecl *Tag = cast<TagDecl>(TagD.getAs<Decl>());
+  if (Tag->isEnum()) {
+    Diag(TemplateLoc, diag::err_explicit_instantiation_enum)
+      << Context.getTypeDeclType(Tag);
+    return true;
+  }
+
+  if (Tag->isInvalidDecl())
+    return true;
+    
+  CXXRecordDecl *Record = cast<CXXRecordDecl>(Tag);
+  CXXRecordDecl *Pattern = Record->getInstantiatedFromMemberClass();
+  if (!Pattern) {
+    Diag(TemplateLoc, diag::err_explicit_instantiation_nontemplate_type)
+      << Context.getTypeDeclType(Record);
+    Diag(Record->getLocation(), diag::note_nontemplate_decl_here);
+    return true;
+  }
+
+  // C++0x [temp.explicit]p2:
+  //   If the explicit instantiation is for a class or member class, the 
+  //   elaborated-type-specifier in the declaration shall include a 
+  //   simple-template-id.
+  //
+  // C++98 has the same restriction, just worded differently.
+  if (!ScopeSpecifierHasTemplateId(SS))
+    Diag(TemplateLoc, diag::err_explicit_instantiation_without_qualified_id)
+      << Record << SS.getRange();
+           
+  // C++0x [temp.explicit]p2:
+  //   There are two forms of explicit instantiation: an explicit instantiation
+  //   definition and an explicit instantiation declaration. An explicit 
+  //   instantiation declaration begins with the extern keyword. [...]
+  TemplateSpecializationKind TSK
+    = ExternLoc.isInvalid()? TSK_ExplicitInstantiationDefinition
+                           : TSK_ExplicitInstantiationDeclaration;
+  
+  // C++0x [temp.explicit]p2:
+  //   [...] An explicit instantiation shall appear in an enclosing
+  //   namespace of its template. [...]
+  //
+  // This is C++ DR 275.
+  CheckExplicitInstantiationScope(*this, Record, NameLoc, true);
+  
+  // Verify that it is okay to explicitly instantiate here.
+  CXXRecordDecl *PrevDecl 
+    = cast_or_null<CXXRecordDecl>(Record->getPreviousDeclaration());
+  if (!PrevDecl && Record->getDefinition())
+    PrevDecl = Record;
+  if (PrevDecl) {
+    MemberSpecializationInfo *MSInfo = PrevDecl->getMemberSpecializationInfo();
+    bool SuppressNew = false;
+    assert(MSInfo && "No member specialization information?");
+    if (CheckSpecializationInstantiationRedecl(TemplateLoc, TSK, 
+                                               PrevDecl,
+                                        MSInfo->getTemplateSpecializationKind(),
+                                             MSInfo->getPointOfInstantiation(), 
+                                               SuppressNew))
+      return true;
+    if (SuppressNew)
+      return TagD;
+  }
+  
+  CXXRecordDecl *RecordDef
+    = cast_or_null<CXXRecordDecl>(Record->getDefinition());
+  if (!RecordDef) {
+    // C++ [temp.explicit]p3:
+    //   A definition of a member class of a class template shall be in scope 
+    //   at the point of an explicit instantiation of the member class.
+    CXXRecordDecl *Def 
+      = cast_or_null<CXXRecordDecl>(Pattern->getDefinition());
+    if (!Def) {
+      Diag(TemplateLoc, diag::err_explicit_instantiation_undefined_member)
+        << 0 << Record->getDeclName() << Record->getDeclContext();
+      Diag(Pattern->getLocation(), diag::note_forward_declaration)
+        << Pattern;
+      return true;
+    } else {
+      if (InstantiateClass(NameLoc, Record, Def,
+                           getTemplateInstantiationArgs(Record),
+                           TSK))
+        return true;
+
+      RecordDef = cast_or_null<CXXRecordDecl>(Record->getDefinition());
+      if (!RecordDef)
+        return true;
+    }
+  } 
+  
+  // Instantiate all of the members of the class.
+  InstantiateClassMembers(NameLoc, RecordDef,
+                          getTemplateInstantiationArgs(Record), TSK);
+
+  // FIXME: We don't have any representation for explicit instantiations of
+  // member classes. Such a representation is not needed for compilation, but it
+  // should be available for clients that want to see all of the declarations in
+  // the source code.
+  return TagD;
+}
+
+Sema::DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
+                                                  SourceLocation ExternLoc,
+                                                  SourceLocation TemplateLoc,
+                                                  Declarator &D) {
+  // Explicit instantiations always require a name.
+  DeclarationName Name = GetNameForDeclarator(D);
+  if (!Name) {
+    if (!D.isInvalidType())
+      Diag(D.getDeclSpec().getSourceRange().getBegin(),
+           diag::err_explicit_instantiation_requires_name)
+        << D.getDeclSpec().getSourceRange()
+        << D.getSourceRange();
+    
+    return true;
+  }
+
+  // The scope passed in may not be a decl scope.  Zip up the scope tree until
+  // we find one that is.
+  while ((S->getFlags() & Scope::DeclScope) == 0 ||
+         (S->getFlags() & Scope::TemplateParamScope) != 0)
+    S = S->getParent();
+
+  // Determine the type of the declaration.
+  QualType R = GetTypeForDeclarator(D, S, 0);
+  if (R.isNull())
+    return true;
+  
+  if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef) {
+    // Cannot explicitly instantiate a typedef.
+    Diag(D.getIdentifierLoc(), diag::err_explicit_instantiation_of_typedef)
+      << Name;
+    return true;
+  }
+
+  // C++0x [temp.explicit]p1:
+  //   [...] An explicit instantiation of a function template shall not use the
+  //   inline or constexpr specifiers.
+  // Presumably, this also applies to member functions of class templates as
+  // well.
+  if (D.getDeclSpec().isInlineSpecified() && getLangOptions().CPlusPlus0x)
+    Diag(D.getDeclSpec().getInlineSpecLoc(), 
+         diag::err_explicit_instantiation_inline)
+      <<FixItHint::CreateRemoval(D.getDeclSpec().getInlineSpecLoc());
+  
+  // FIXME: check for constexpr specifier.
+  
+  // C++0x [temp.explicit]p2:
+  //   There are two forms of explicit instantiation: an explicit instantiation
+  //   definition and an explicit instantiation declaration. An explicit 
+  //   instantiation declaration begins with the extern keyword. [...]  
+  TemplateSpecializationKind TSK
+    = ExternLoc.isInvalid()? TSK_ExplicitInstantiationDefinition
+                           : TSK_ExplicitInstantiationDeclaration;
+    
+  LookupResult Previous(*this, Name, D.getIdentifierLoc(), LookupOrdinaryName);
+  LookupParsedName(Previous, S, &D.getCXXScopeSpec());
+
+  if (!R->isFunctionType()) {
+    // C++ [temp.explicit]p1:
+    //   A [...] static data member of a class template can be explicitly 
+    //   instantiated from the member definition associated with its class 
+    //   template.
+    if (Previous.isAmbiguous())
+      return true;
+    
+    VarDecl *Prev = Previous.getAsSingle<VarDecl>();
+    if (!Prev || !Prev->isStaticDataMember()) {
+      // We expect to see a data data member here.
+      Diag(D.getIdentifierLoc(), diag::err_explicit_instantiation_not_known)
+        << Name;
+      for (LookupResult::iterator P = Previous.begin(), PEnd = Previous.end();
+           P != PEnd; ++P)
+        Diag((*P)->getLocation(), diag::note_explicit_instantiation_here);
+      return true;
+    }
+    
+    if (!Prev->getInstantiatedFromStaticDataMember()) {
+      // FIXME: Check for explicit specialization?
+      Diag(D.getIdentifierLoc(), 
+           diag::err_explicit_instantiation_data_member_not_instantiated)
+        << Prev;
+      Diag(Prev->getLocation(), diag::note_explicit_instantiation_here);
+      // FIXME: Can we provide a note showing where this was declared?
+      return true;
+    }
+    
+    // C++0x [temp.explicit]p2:
+    //   If the explicit instantiation is for a member function, a member class 
+    //   or a static data member of a class template specialization, the name of
+    //   the class template specialization in the qualified-id for the member
+    //   name shall be a simple-template-id.
+    //
+    // C++98 has the same restriction, just worded differently.
+    if (!ScopeSpecifierHasTemplateId(D.getCXXScopeSpec()))
+      Diag(D.getIdentifierLoc(), 
+           diag::err_explicit_instantiation_without_qualified_id)
+        << Prev << D.getCXXScopeSpec().getRange();
+    
+    // Check the scope of this explicit instantiation.
+    CheckExplicitInstantiationScope(*this, Prev, D.getIdentifierLoc(), true);
+    
+    // Verify that it is okay to explicitly instantiate here.
+    MemberSpecializationInfo *MSInfo = Prev->getMemberSpecializationInfo();
+    assert(MSInfo && "Missing static data member specialization info?");
+    bool SuppressNew = false;
+    if (CheckSpecializationInstantiationRedecl(D.getIdentifierLoc(), TSK, Prev,
+                                        MSInfo->getTemplateSpecializationKind(),
+                                              MSInfo->getPointOfInstantiation(), 
+                                               SuppressNew))
+      return true;
+    if (SuppressNew)
+      return DeclPtrTy();
+    
+    // Instantiate static data member.
+    Prev->setTemplateSpecializationKind(TSK, D.getIdentifierLoc());
+    if (TSK == TSK_ExplicitInstantiationDefinition)
+      InstantiateStaticDataMemberDefinition(D.getIdentifierLoc(), Prev, false,
+                                            /*DefinitionRequired=*/true);
+    
+    // FIXME: Create an ExplicitInstantiation node?
+    return DeclPtrTy();
+  }
+  
+  // If the declarator is a template-id, translate the parser's template 
+  // argument list into our AST format.
+  bool HasExplicitTemplateArgs = false;
+  TemplateArgumentListInfo TemplateArgs;
+  if (D.getName().getKind() == UnqualifiedId::IK_TemplateId) {
+    TemplateIdAnnotation *TemplateId = D.getName().TemplateId;
+    TemplateArgs.setLAngleLoc(TemplateId->LAngleLoc);
+    TemplateArgs.setRAngleLoc(TemplateId->RAngleLoc);
+    ASTTemplateArgsPtr TemplateArgsPtr(*this,
+                                       TemplateId->getTemplateArgs(),
+                                       TemplateId->NumArgs);
+    translateTemplateArguments(TemplateArgsPtr, TemplateArgs);
+    HasExplicitTemplateArgs = true;
+    TemplateArgsPtr.release();
+  }
+    
+  // C++ [temp.explicit]p1:
+  //   A [...] function [...] can be explicitly instantiated from its template. 
+  //   A member function [...] of a class template can be explicitly 
+  //  instantiated from the member definition associated with its class 
+  //  template.
+  UnresolvedSet<8> Matches;
+  for (LookupResult::iterator P = Previous.begin(), PEnd = Previous.end();
+       P != PEnd; ++P) {
+    NamedDecl *Prev = *P;
+    if (!HasExplicitTemplateArgs) {
+      if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Prev)) {
+        if (Context.hasSameUnqualifiedType(Method->getType(), R)) {
+          Matches.clear();
+
+          Matches.addDecl(Method, P.getAccess());
+          if (Method->getTemplateSpecializationKind() == TSK_Undeclared)
+            break;
+        }
+      }
+    }
+    
+    FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(Prev);
+    if (!FunTmpl)
+      continue;
+
+    TemplateDeductionInfo Info(Context, D.getIdentifierLoc());
+    FunctionDecl *Specialization = 0;
+    if (TemplateDeductionResult TDK
+          = DeduceTemplateArguments(FunTmpl, 
+                               (HasExplicitTemplateArgs ? &TemplateArgs : 0),
+                                    R, Specialization, Info)) {
+      // FIXME: Keep track of almost-matches?
+      (void)TDK;
+      continue;
+    }
+    
+    Matches.addDecl(Specialization, P.getAccess());
+  }
+  
+  // Find the most specialized function template specialization.
+  UnresolvedSetIterator Result
+    = getMostSpecialized(Matches.begin(), Matches.end(), TPOC_Other, 
+                         D.getIdentifierLoc(), 
+                     PDiag(diag::err_explicit_instantiation_not_known) << Name,
+                     PDiag(diag::err_explicit_instantiation_ambiguous) << Name,
+                         PDiag(diag::note_explicit_instantiation_candidate));
+
+  if (Result == Matches.end())
+    return true;
+
+  // Ignore access control bits, we don't need them for redeclaration checking.
+  FunctionDecl *Specialization = cast<FunctionDecl>(*Result);
+  
+  if (Specialization->getTemplateSpecializationKind() == TSK_Undeclared) {
+    Diag(D.getIdentifierLoc(), 
+         diag::err_explicit_instantiation_member_function_not_instantiated)
+      << Specialization
+      << (Specialization->getTemplateSpecializationKind() ==
+          TSK_ExplicitSpecialization);
+    Diag(Specialization->getLocation(), diag::note_explicit_instantiation_here);
+    return true;
+  } 
+  
+  FunctionDecl *PrevDecl = Specialization->getPreviousDeclaration();
+  if (!PrevDecl && Specialization->isThisDeclarationADefinition())
+    PrevDecl = Specialization;
+
+  if (PrevDecl) {
+    bool SuppressNew = false;
+    if (CheckSpecializationInstantiationRedecl(D.getIdentifierLoc(), TSK,
+                                               PrevDecl, 
+                                     PrevDecl->getTemplateSpecializationKind(), 
+                                          PrevDecl->getPointOfInstantiation(),
+                                               SuppressNew))
+      return true;
+    
+    // FIXME: We may still want to build some representation of this
+    // explicit specialization.
+    if (SuppressNew)
+      return DeclPtrTy();
+  }
+
+  Specialization->setTemplateSpecializationKind(TSK, D.getIdentifierLoc());
+  
+  if (TSK == TSK_ExplicitInstantiationDefinition)
+    InstantiateFunctionDefinition(D.getIdentifierLoc(), Specialization, 
+                                  false, /*DefinitionRequired=*/true);
+ 
+  // C++0x [temp.explicit]p2:
+  //   If the explicit instantiation is for a member function, a member class 
+  //   or a static data member of a class template specialization, the name of
+  //   the class template specialization in the qualified-id for the member
+  //   name shall be a simple-template-id.
+  //
+  // C++98 has the same restriction, just worded differently.
+  FunctionTemplateDecl *FunTmpl = Specialization->getPrimaryTemplate();
+  if (D.getName().getKind() != UnqualifiedId::IK_TemplateId && !FunTmpl &&
+      D.getCXXScopeSpec().isSet() && 
+      !ScopeSpecifierHasTemplateId(D.getCXXScopeSpec()))
+    Diag(D.getIdentifierLoc(), 
+         diag::err_explicit_instantiation_without_qualified_id)
+    << Specialization << D.getCXXScopeSpec().getRange();
+  
+  CheckExplicitInstantiationScope(*this,
+                   FunTmpl? (NamedDecl *)FunTmpl 
+                          : Specialization->getInstantiatedFromMemberFunction(),
+                                  D.getIdentifierLoc(), 
+                                  D.getCXXScopeSpec().isSet());
+  
+  // FIXME: Create some kind of ExplicitInstantiationDecl here.
+  return DeclPtrTy();
+}
+
+Sema::TypeResult
+Sema::ActOnDependentTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
+                        const CXXScopeSpec &SS, IdentifierInfo *Name,
+                        SourceLocation TagLoc, SourceLocation NameLoc) {
+  // This has to hold, because SS is expected to be defined.
+  assert(Name && "Expected a name in a dependent tag");
+
+  NestedNameSpecifier *NNS
+    = static_cast<NestedNameSpecifier *>(SS.getScopeRep());
+  if (!NNS)
+    return true;
+
+  ElaboratedTypeKeyword Keyword = ETK_None;
+  switch (TagDecl::getTagKindForTypeSpec(TagSpec)) {
+  case TagDecl::TK_struct: Keyword = ETK_Struct; break;
+  case TagDecl::TK_class: Keyword = ETK_Class; break;
+  case TagDecl::TK_union: Keyword = ETK_Union; break;
+  case TagDecl::TK_enum: Keyword = ETK_Enum; break;
+  }
+  assert(Keyword != ETK_None && "Invalid tag kind!");
+
+  if (TUK == TUK_Declaration || TUK == TUK_Definition) {
+    Diag(NameLoc, diag::err_dependent_tag_decl)
+      << (TUK == TUK_Definition) << TagDecl::getTagKindForTypeSpec(TagSpec)
+      << SS.getRange();
+    return true;
+  }
+  
+  return Context.getDependentNameType(Keyword, NNS, Name).getAsOpaquePtr();
+}
+
+Sema::TypeResult
+Sema::ActOnTypenameType(SourceLocation TypenameLoc, const CXXScopeSpec &SS,
+                        const IdentifierInfo &II, SourceLocation IdLoc) {
+  NestedNameSpecifier *NNS
+    = static_cast<NestedNameSpecifier *>(SS.getScopeRep());
+  if (!NNS)
+    return true;
+
+  QualType T = CheckTypenameType(ETK_Typename, NNS, II,
+                                 SourceRange(TypenameLoc, IdLoc));
+  if (T.isNull())
+    return true;
+  return T.getAsOpaquePtr();
+}
+
+Sema::TypeResult
+Sema::ActOnTypenameType(SourceLocation TypenameLoc, const CXXScopeSpec &SS,
+                        SourceLocation TemplateLoc, TypeTy *Ty) {
+  QualType T = GetTypeFromParser(Ty);
+  NestedNameSpecifier *NNS
+    = static_cast<NestedNameSpecifier *>(SS.getScopeRep());
+  const TemplateSpecializationType *TemplateId
+    = T->getAs<TemplateSpecializationType>();
+  assert(TemplateId && "Expected a template specialization type");
+
+  if (computeDeclContext(SS, false)) {
+    // If we can compute a declaration context, then the "typename"
+    // keyword was superfluous. Just build a QualifiedNameType to keep
+    // track of the nested-name-specifier.
+
+    // FIXME: Note that the QualifiedNameType had the "typename" keyword!
+    return Context.getQualifiedNameType(NNS, T).getAsOpaquePtr();
+  }
+
+  return Context.getDependentNameType(ETK_Typename, NNS, TemplateId)
+                                                            .getAsOpaquePtr();
+}
+
+/// \brief Build the type that describes a C++ typename specifier,
+/// e.g., "typename T::type".
+QualType
+Sema::CheckTypenameType(ElaboratedTypeKeyword Keyword,
+                        NestedNameSpecifier *NNS, const IdentifierInfo &II,
+                        SourceRange Range) {
+  CXXRecordDecl *CurrentInstantiation = 0;
+  if (NNS->isDependent()) {
+    CurrentInstantiation = getCurrentInstantiationOf(NNS);
+
+    // If the nested-name-specifier does not refer to the current
+    // instantiation, then build a typename type.
+    if (!CurrentInstantiation)
+      return Context.getDependentNameType(Keyword, NNS, &II);
+
+    // The nested-name-specifier refers to the current instantiation, so the
+    // "typename" keyword itself is superfluous. In C++03, the program is
+    // actually ill-formed. However, DR 382 (in C++0x CD1) allows such
+    // extraneous "typename" keywords, and we retroactively apply this DR to
+    // C++03 code.
+  }
+
+  DeclContext *Ctx = 0;
+
+  if (CurrentInstantiation)
+    Ctx = CurrentInstantiation;
+  else {
+    CXXScopeSpec SS;
+    SS.setScopeRep(NNS);
+    SS.setRange(Range);
+    if (RequireCompleteDeclContext(SS))
+      return QualType();
+
+    Ctx = computeDeclContext(SS);
+  }
+  assert(Ctx && "No declaration context?");
+
+  DeclarationName Name(&II);
+  LookupResult Result(*this, Name, Range.getEnd(), LookupOrdinaryName);
+  LookupQualifiedName(Result, Ctx);
+  unsigned DiagID = 0;
+  Decl *Referenced = 0;
+  switch (Result.getResultKind()) {
+  case LookupResult::NotFound:
+    DiagID = diag::err_typename_nested_not_found;
+    break;
+      
+  case LookupResult::NotFoundInCurrentInstantiation:
+    // Okay, it's a member of an unknown instantiation.
+    return Context.getDependentNameType(Keyword, NNS, &II);
+
+  case LookupResult::Found:
+    if (TypeDecl *Type = dyn_cast<TypeDecl>(Result.getFoundDecl())) {
+      // We found a type. Build a QualifiedNameType, since the
+      // typename-specifier was just sugar. FIXME: Tell
+      // QualifiedNameType that it has a "typename" prefix.
+      return Context.getQualifiedNameType(NNS, Context.getTypeDeclType(Type));
+    }
+
+    DiagID = diag::err_typename_nested_not_type;
+    Referenced = Result.getFoundDecl();
+    break;
+
+  case LookupResult::FoundUnresolvedValue:
+    llvm_unreachable("unresolved using decl in non-dependent context");
+    return QualType();
+
+  case LookupResult::FoundOverloaded:
+    DiagID = diag::err_typename_nested_not_type;
+    Referenced = *Result.begin();
+    break;
+
+  case LookupResult::Ambiguous:
+    return QualType();
+  }
+
+  // If we get here, it's because name lookup did not find a
+  // type. Emit an appropriate diagnostic and return an error.
+  Diag(Range.getEnd(), DiagID) << Range << Name << Ctx;
+  if (Referenced)
+    Diag(Referenced->getLocation(), diag::note_typename_refers_here)
+      << Name;
+  return QualType();
+}
+
+namespace {
+  // See Sema::RebuildTypeInCurrentInstantiation
+  class CurrentInstantiationRebuilder
+    : public TreeTransform<CurrentInstantiationRebuilder> {
+    SourceLocation Loc;
+    DeclarationName Entity;
+
+  public:
+    CurrentInstantiationRebuilder(Sema &SemaRef,
+                                  SourceLocation Loc,
+                                  DeclarationName Entity)
+    : TreeTransform<CurrentInstantiationRebuilder>(SemaRef),
+      Loc(Loc), Entity(Entity) { }
+
+    /// \brief Determine whether the given type \p T has already been
+    /// transformed.
+    ///
+    /// For the purposes of type reconstruction, a type has already been
+    /// transformed if it is NULL or if it is not dependent.
+    bool AlreadyTransformed(QualType T) {
+      return T.isNull() || !T->isDependentType();
+    }
+
+    /// \brief Returns the location of the entity whose type is being
+    /// rebuilt.
+    SourceLocation getBaseLocation() { return Loc; }
+
+    /// \brief Returns the name of the entity whose type is being rebuilt.
+    DeclarationName getBaseEntity() { return Entity; }
+
+    /// \brief Sets the "base" location and entity when that
+    /// information is known based on another transformation.
+    void setBase(SourceLocation Loc, DeclarationName Entity) {
+      this->Loc = Loc;
+      this->Entity = Entity;
+    }
+      
+    /// \brief Transforms an expression by returning the expression itself
+    /// (an identity function).
+    ///
+    /// FIXME: This is completely unsafe; we will need to actually clone the
+    /// expressions.
+    Sema::OwningExprResult TransformExpr(Expr *E) {
+      return getSema().Owned(E);
+    }
+
+    /// \brief Transforms a typename type by determining whether the type now
+    /// refers to a member of the current instantiation, and then
+    /// type-checking and building a QualifiedNameType (when possible).
+    QualType TransformDependentNameType(TypeLocBuilder &TLB, DependentNameTypeLoc TL, 
+                                   QualType ObjectType);
+  };
+}
+
+QualType
+CurrentInstantiationRebuilder::TransformDependentNameType(TypeLocBuilder &TLB,
+                                                     DependentNameTypeLoc TL, 
+                                                     QualType ObjectType) {
+  DependentNameType *T = TL.getTypePtr();
+
+  NestedNameSpecifier *NNS
+    = TransformNestedNameSpecifier(T->getQualifier(),
+                                   /*FIXME:*/SourceRange(getBaseLocation()),
+                                   ObjectType);
+  if (!NNS)
+    return QualType();
+
+  // If the nested-name-specifier did not change, and we cannot compute the
+  // context corresponding to the nested-name-specifier, then this
+  // typename type will not change; exit early.
+  CXXScopeSpec SS;
+  SS.setRange(SourceRange(getBaseLocation()));
+  SS.setScopeRep(NNS);
+
+  QualType Result;
+  if (NNS == T->getQualifier() && getSema().computeDeclContext(SS) == 0)
+    Result = QualType(T, 0);
+
+  // Rebuild the typename type, which will probably turn into a
+  // QualifiedNameType.
+  else if (const TemplateSpecializationType *TemplateId = T->getTemplateId()) {
+    QualType NewTemplateId
+      = TransformType(QualType(TemplateId, 0));
+    if (NewTemplateId.isNull())
+      return QualType();
+
+    if (NNS == T->getQualifier() &&
+        NewTemplateId == QualType(TemplateId, 0))
+      Result = QualType(T, 0);
+    else
+      Result = getDerived().RebuildDependentNameType(T->getKeyword(), 
+                                                     NNS, NewTemplateId);
+  } else
+    Result = getDerived().RebuildDependentNameType(T->getKeyword(),
+                                                   NNS, T->getIdentifier(),
+                                                  SourceRange(TL.getNameLoc()));
+
+  if (Result.isNull())
+    return QualType();
+
+  DependentNameTypeLoc NewTL = TLB.push<DependentNameTypeLoc>(Result);
+  NewTL.setNameLoc(TL.getNameLoc());
+  return Result;
+}
+
+/// \brief Rebuilds a type within the context of the current instantiation.
+///
+/// The type \p T is part of the type of an out-of-line member definition of
+/// a class template (or class template partial specialization) that was parsed
+/// and constructed before we entered the scope of the class template (or
+/// partial specialization thereof). This routine will rebuild that type now
+/// that we have entered the declarator's scope, which may produce different
+/// canonical types, e.g.,
+///
+/// \code
+/// template<typename T>
+/// struct X {
+///   typedef T* pointer;
+///   pointer data();
+/// };
+///
+/// template<typename T>
+/// typename X<T>::pointer X<T>::data() { ... }
+/// \endcode
+///
+/// Here, the type "typename X<T>::pointer" will be created as a DependentNameType,
+/// since we do not know that we can look into X<T> when we parsed the type.
+/// This function will rebuild the type, performing the lookup of "pointer"
+/// in X<T> and returning a QualifiedNameType whose canonical type is the same
+/// as the canonical type of T*, allowing the return types of the out-of-line
+/// definition and the declaration to match.
+QualType Sema::RebuildTypeInCurrentInstantiation(QualType T, SourceLocation Loc,
+                                                 DeclarationName Name) {
+  if (T.isNull() || !T->isDependentType())
+    return T;
+
+  CurrentInstantiationRebuilder Rebuilder(*this, Loc, Name);
+  return Rebuilder.TransformType(T);
+}
+
+void Sema::RebuildNestedNameSpecifierInCurrentInstantiation(CXXScopeSpec &SS) {
+  if (SS.isInvalid()) return;
+
+  NestedNameSpecifier *NNS = static_cast<NestedNameSpecifier*>(SS.getScopeRep());
+  CurrentInstantiationRebuilder Rebuilder(*this, SS.getRange().getBegin(),
+                                          DeclarationName());
+  NestedNameSpecifier *Rebuilt = 
+    Rebuilder.TransformNestedNameSpecifier(NNS, SS.getRange());
+  if (Rebuilt) SS.setScopeRep(Rebuilt);
+}
+
+/// \brief Produces a formatted string that describes the binding of
+/// template parameters to template arguments.
+std::string
+Sema::getTemplateArgumentBindingsText(const TemplateParameterList *Params,
+                                      const TemplateArgumentList &Args) {
+  // FIXME: For variadic templates, we'll need to get the structured list.
+  return getTemplateArgumentBindingsText(Params, Args.getFlatArgumentList(),
+                                         Args.flat_size());
+}
+
+std::string
+Sema::getTemplateArgumentBindingsText(const TemplateParameterList *Params,
+                                      const TemplateArgument *Args,
+                                      unsigned NumArgs) {
+  std::string Result;
+
+  if (!Params || Params->size() == 0 || NumArgs == 0)
+    return Result;
+  
+  for (unsigned I = 0, N = Params->size(); I != N; ++I) {
+    if (I >= NumArgs)
+      break;
+    
+    if (I == 0)
+      Result += "[with ";
+    else
+      Result += ", ";
+    
+    if (const IdentifierInfo *Id = Params->getParam(I)->getIdentifier()) {
+      Result += Id->getName();
+    } else {
+      Result += '$';
+      Result += llvm::utostr(I);
+    }
+    
+    Result += " = ";
+    
+    switch (Args[I].getKind()) {
+      case TemplateArgument::Null:
+        Result += "<no value>";
+        break;
+        
+      case TemplateArgument::Type: {
+        std::string TypeStr;
+        Args[I].getAsType().getAsStringInternal(TypeStr, 
+                                                Context.PrintingPolicy);
+        Result += TypeStr;
+        break;
+      }
+        
+      case TemplateArgument::Declaration: {
+        bool Unnamed = true;
+        if (NamedDecl *ND = dyn_cast_or_null<NamedDecl>(Args[I].getAsDecl())) {
+          if (ND->getDeclName()) {
+            Unnamed = false;
+            Result += ND->getNameAsString();
+          }
+        }
+        
+        if (Unnamed) {
+          Result += "<anonymous>";
+        }
+        break;
+      }
+        
+      case TemplateArgument::Template: {
+        std::string Str;
+        llvm::raw_string_ostream OS(Str);
+        Args[I].getAsTemplate().print(OS, Context.PrintingPolicy);
+        Result += OS.str();
+        break;
+      }
+        
+      case TemplateArgument::Integral: {
+        Result += Args[I].getAsIntegral()->toString(10);
+        break;
+      }
+        
+      case TemplateArgument::Expression: {
+        assert(false && "No expressions in deduced template arguments!");
+        Result += "<expression>";
+        break;
+      }
+        
+      case TemplateArgument::Pack:
+        // FIXME: Format template argument packs
+        Result += "<template argument pack>";
+        break;        
+    }
+  }
+  
+  Result += ']';
+  return Result;
+}
diff --git a/lib/Sema/SemaTemplate.h b/lib/Sema/SemaTemplate.h
new file mode 100644
index 0000000..ca59e27
--- /dev/null
+++ b/lib/Sema/SemaTemplate.h
@@ -0,0 +1,138 @@
+//===------- SemaTemplate.h - C++ Templates ---------------------*- C++ -*-===/
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//===----------------------------------------------------------------------===/
+//
+//  This file provides types used in the semantic analysis of C++ templates.
+//
+//===----------------------------------------------------------------------===/
+#ifndef LLVM_CLANG_SEMA_TEMPLATE_H
+#define LLVM_CLANG_SEMA_TEMPLATE_H
+
+#include "clang/AST/DeclTemplate.h"
+#include "llvm/ADT/SmallVector.h"
+#include <cassert>
+
+namespace clang {
+  /// \brief Data structure that captures multiple levels of template argument
+  /// lists for use in template instantiation.
+  ///
+  /// Multiple levels of template arguments occur when instantiating the 
+  /// definitions of member templates. For example:
+  ///
+  /// \code
+  /// template<typename T>
+  /// struct X {
+  ///   template<T Value>
+  ///   struct Y {
+  ///     void f();
+  ///   };
+  /// };
+  /// \endcode
+  ///
+  /// When instantiating X<int>::Y<17>::f, the multi-level template argument
+  /// list will contain a template argument list (int) at depth 0 and a
+  /// template argument list (17) at depth 1.
+  struct MultiLevelTemplateArgumentList {
+    /// \brief The template argument lists, stored from the innermost template
+    /// argument list (first) to the outermost template argument list (last).
+    llvm::SmallVector<const TemplateArgumentList *, 4> TemplateArgumentLists;
+    
+  public:
+    /// \brief Construct an empty set of template argument lists.
+    MultiLevelTemplateArgumentList() { }
+    
+    /// \brief Construct a single-level template argument list.
+    explicit 
+    MultiLevelTemplateArgumentList(const TemplateArgumentList &TemplateArgs) {
+      TemplateArgumentLists.push_back(&TemplateArgs);
+    }
+    
+    /// \brief Determine the number of levels in this template argument
+    /// list.
+    unsigned getNumLevels() const { return TemplateArgumentLists.size(); }
+    
+    /// \brief Retrieve the template argument at a given depth and index.
+    const TemplateArgument &operator()(unsigned Depth, unsigned Index) const {
+      assert(Depth < TemplateArgumentLists.size());
+      assert(Index < TemplateArgumentLists[getNumLevels() - Depth - 1]->size());
+      return TemplateArgumentLists[getNumLevels() - Depth - 1]->get(Index);
+    }
+    
+    /// \brief Determine whether there is a non-NULL template argument at the
+    /// given depth and index.
+    ///
+    /// There must exist a template argument list at the given depth.
+    bool hasTemplateArgument(unsigned Depth, unsigned Index) const {
+      assert(Depth < TemplateArgumentLists.size());
+      
+      if (Index >= TemplateArgumentLists[getNumLevels() - Depth - 1]->size())
+        return false;
+      
+      return !(*this)(Depth, Index).isNull();
+    }
+    
+    /// \brief Add a new outermost level to the multi-level template argument 
+    /// list.
+    void addOuterTemplateArguments(const TemplateArgumentList *TemplateArgs) {
+      TemplateArgumentLists.push_back(TemplateArgs);
+    }
+    
+    /// \brief Retrieve the innermost template argument list.
+    const TemplateArgumentList &getInnermost() const {
+      return *TemplateArgumentLists.front();
+    }
+  };
+  
+  /// \brief The context in which partial ordering of function templates occurs.
+  enum TemplatePartialOrderingContext {
+    /// \brief Partial ordering of function templates for a function call.
+    TPOC_Call,
+    /// \brief Partial ordering of function templates for a call to a 
+    /// conversion function.
+    TPOC_Conversion,
+    /// \brief Partial ordering of function templates in other contexts, e.g.,
+    /// taking the address of a function template or matching a function 
+    /// template specialization to a function template.
+    TPOC_Other
+  };
+
+  /// \brief Captures a template argument whose value has been deduced
+  /// via c++ template argument deduction.
+  class DeducedTemplateArgument : public TemplateArgument {
+    /// \brief For a non-type template argument, whether the value was
+    /// deduced from an array bound.
+    bool DeducedFromArrayBound;
+
+  public:
+    DeducedTemplateArgument()
+      : TemplateArgument(), DeducedFromArrayBound(false) { }
+
+    DeducedTemplateArgument(const TemplateArgument &Arg,
+                            bool DeducedFromArrayBound = false)
+      : TemplateArgument(Arg), DeducedFromArrayBound(DeducedFromArrayBound) { }
+
+    /// \brief Construct an integral non-type template argument that
+    /// has been deduced, possible from an array bound.
+    DeducedTemplateArgument(const llvm::APSInt &Value,
+                            QualType ValueType,
+                            bool DeducedFromArrayBound)
+      : TemplateArgument(Value, ValueType), 
+        DeducedFromArrayBound(DeducedFromArrayBound) { }
+
+    /// \brief For a non-type template argument, determine whether the
+    /// template argument was deduced from an array bound.
+    bool wasDeducedFromArrayBound() const { return DeducedFromArrayBound; }
+
+    /// \brief Specify whether the given non-type template argument
+    /// was deduced from an array bound.
+    void setDeducedFromArrayBound(bool Deduced) {
+      DeducedFromArrayBound = Deduced;
+    }
+  };
+}
+
+#endif // LLVM_CLANG_SEMA_TEMPLATE_H
diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp
new file mode 100644
index 0000000..7154d62
--- /dev/null
+++ b/lib/Sema/SemaTemplateDeduction.cpp
@@ -0,0 +1,2682 @@
+//===------- SemaTemplateDeduction.cpp - Template Argument Deduction ------===/
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//===----------------------------------------------------------------------===/
+//
+//  This file implements C++ template argument deduction.
+//
+//===----------------------------------------------------------------------===/
+
+#include "Sema.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/StmtVisitor.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/Parse/DeclSpec.h"
+#include <algorithm>
+
+namespace clang {
+  /// \brief Various flags that control template argument deduction.
+  ///
+  /// These flags can be bitwise-OR'd together.
+  enum TemplateDeductionFlags {
+    /// \brief No template argument deduction flags, which indicates the
+    /// strictest results for template argument deduction (as used for, e.g.,
+    /// matching class template partial specializations).
+    TDF_None = 0,
+    /// \brief Within template argument deduction from a function call, we are
+    /// matching with a parameter type for which the original parameter was
+    /// a reference.
+    TDF_ParamWithReferenceType = 0x1,
+    /// \brief Within template argument deduction from a function call, we
+    /// are matching in a case where we ignore cv-qualifiers.
+    TDF_IgnoreQualifiers = 0x02,
+    /// \brief Within template argument deduction from a function call,
+    /// we are matching in a case where we can perform template argument
+    /// deduction from a template-id of a derived class of the argument type.
+    TDF_DerivedClass = 0x04,
+    /// \brief Allow non-dependent types to differ, e.g., when performing
+    /// template argument deduction from a function call where conversions
+    /// may apply.
+    TDF_SkipNonDependent = 0x08
+  };
+}
+
+using namespace clang;
+
+/// \brief Compare two APSInts, extending and switching the sign as
+/// necessary to compare their values regardless of underlying type.
+static bool hasSameExtendedValue(llvm::APSInt X, llvm::APSInt Y) {
+  if (Y.getBitWidth() > X.getBitWidth())
+    X.extend(Y.getBitWidth());
+  else if (Y.getBitWidth() < X.getBitWidth())
+    Y.extend(X.getBitWidth());
+
+  // If there is a signedness mismatch, correct it.
+  if (X.isSigned() != Y.isSigned()) {
+    // If the signed value is negative, then the values cannot be the same.
+    if ((Y.isSigned() && Y.isNegative()) || (X.isSigned() && X.isNegative()))
+      return false;
+
+    Y.setIsSigned(true);
+    X.setIsSigned(true);
+  }
+
+  return X == Y;
+}
+
+static Sema::TemplateDeductionResult
+DeduceTemplateArguments(Sema &S,
+                        TemplateParameterList *TemplateParams,
+                        const TemplateArgument &Param,
+                        const TemplateArgument &Arg,
+                        Sema::TemplateDeductionInfo &Info,
+                    llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced);
+
+/// \brief If the given expression is of a form that permits the deduction
+/// of a non-type template parameter, return the declaration of that
+/// non-type template parameter.
+static NonTypeTemplateParmDecl *getDeducedParameterFromExpr(Expr *E) {
+  if (ImplicitCastExpr *IC = dyn_cast<ImplicitCastExpr>(E))
+    E = IC->getSubExpr();
+
+  if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
+    return dyn_cast<NonTypeTemplateParmDecl>(DRE->getDecl());
+
+  return 0;
+}
+
+/// \brief Deduce the value of the given non-type template parameter
+/// from the given constant.
+static Sema::TemplateDeductionResult
+DeduceNonTypeTemplateArgument(Sema &S,
+                              NonTypeTemplateParmDecl *NTTP,
+                              llvm::APSInt Value, QualType ValueType,
+                              bool DeducedFromArrayBound,
+                              Sema::TemplateDeductionInfo &Info,
+                    llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
+  assert(NTTP->getDepth() == 0 &&
+         "Cannot deduce non-type template argument with depth > 0");
+
+  if (Deduced[NTTP->getIndex()].isNull()) {
+    Deduced[NTTP->getIndex()] = DeducedTemplateArgument(Value, ValueType,
+                                                        DeducedFromArrayBound);
+    return Sema::TDK_Success;
+  }
+
+  if (Deduced[NTTP->getIndex()].getKind() != TemplateArgument::Integral) {
+    Info.Param = NTTP;
+    Info.FirstArg = Deduced[NTTP->getIndex()];
+    Info.SecondArg = TemplateArgument(Value, ValueType);
+    return Sema::TDK_Inconsistent;    
+  }
+
+  // Extent the smaller of the two values.
+  llvm::APSInt PrevValue = *Deduced[NTTP->getIndex()].getAsIntegral();
+  if (!hasSameExtendedValue(PrevValue, Value)) {
+    Info.Param = NTTP;
+    Info.FirstArg = Deduced[NTTP->getIndex()];
+    Info.SecondArg = TemplateArgument(Value, ValueType);
+    return Sema::TDK_Inconsistent;
+  }
+
+  if (!DeducedFromArrayBound)
+    Deduced[NTTP->getIndex()].setDeducedFromArrayBound(false);
+
+  return Sema::TDK_Success;
+}
+
+/// \brief Deduce the value of the given non-type template parameter
+/// from the given type- or value-dependent expression.
+///
+/// \returns true if deduction succeeded, false otherwise.
+static Sema::TemplateDeductionResult
+DeduceNonTypeTemplateArgument(Sema &S,
+                              NonTypeTemplateParmDecl *NTTP,
+                              Expr *Value,
+                              Sema::TemplateDeductionInfo &Info,
+                    llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
+  assert(NTTP->getDepth() == 0 &&
+         "Cannot deduce non-type template argument with depth > 0");
+  assert((Value->isTypeDependent() || Value->isValueDependent()) &&
+         "Expression template argument must be type- or value-dependent.");
+
+  if (Deduced[NTTP->getIndex()].isNull()) {
+    Deduced[NTTP->getIndex()] = TemplateArgument(Value->Retain());
+    return Sema::TDK_Success;
+  }
+
+  if (Deduced[NTTP->getIndex()].getKind() == TemplateArgument::Integral) {
+    // Okay, we deduced a constant in one case and a dependent expression
+    // in another case. FIXME: Later, we will check that instantiating the
+    // dependent expression gives us the constant value.
+    return Sema::TDK_Success;
+  }
+
+  if (Deduced[NTTP->getIndex()].getKind() == TemplateArgument::Expression) {
+    // Compare the expressions for equality
+    llvm::FoldingSetNodeID ID1, ID2;
+    Deduced[NTTP->getIndex()].getAsExpr()->Profile(ID1, S.Context, true);
+    Value->Profile(ID2, S.Context, true);
+    if (ID1 == ID2)
+      return Sema::TDK_Success;
+   
+    // FIXME: Fill in argument mismatch information
+    return Sema::TDK_NonDeducedMismatch;
+  }
+
+  return Sema::TDK_Success;
+}
+
+/// \brief Deduce the value of the given non-type template parameter
+/// from the given declaration.
+///
+/// \returns true if deduction succeeded, false otherwise.
+static Sema::TemplateDeductionResult
+DeduceNonTypeTemplateArgument(Sema &S,
+                              NonTypeTemplateParmDecl *NTTP,
+                              Decl *D,
+                              Sema::TemplateDeductionInfo &Info,
+                    llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
+  assert(NTTP->getDepth() == 0 &&
+         "Cannot deduce non-type template argument with depth > 0");
+  
+  if (Deduced[NTTP->getIndex()].isNull()) {
+    Deduced[NTTP->getIndex()] = TemplateArgument(D->getCanonicalDecl());
+    return Sema::TDK_Success;
+  }
+  
+  if (Deduced[NTTP->getIndex()].getKind() == TemplateArgument::Expression) {
+    // Okay, we deduced a declaration in one case and a dependent expression
+    // in another case.
+    return Sema::TDK_Success;
+  }
+  
+  if (Deduced[NTTP->getIndex()].getKind() == TemplateArgument::Declaration) {
+    // Compare the declarations for equality
+    if (Deduced[NTTP->getIndex()].getAsDecl()->getCanonicalDecl() ==
+          D->getCanonicalDecl())
+      return Sema::TDK_Success;
+    
+    // FIXME: Fill in argument mismatch information
+    return Sema::TDK_NonDeducedMismatch;
+  }
+  
+  return Sema::TDK_Success;
+}
+
+static Sema::TemplateDeductionResult
+DeduceTemplateArguments(Sema &S,
+                        TemplateParameterList *TemplateParams,
+                        TemplateName Param,
+                        TemplateName Arg,
+                        Sema::TemplateDeductionInfo &Info,
+                    llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
+  TemplateDecl *ParamDecl = Param.getAsTemplateDecl();
+  if (!ParamDecl) {
+    // The parameter type is dependent and is not a template template parameter,
+    // so there is nothing that we can deduce.
+    return Sema::TDK_Success;
+  }
+  
+  if (TemplateTemplateParmDecl *TempParam
+        = dyn_cast<TemplateTemplateParmDecl>(ParamDecl)) {
+    // Bind the template template parameter to the given template name.
+    TemplateArgument &ExistingArg = Deduced[TempParam->getIndex()];
+    if (ExistingArg.isNull()) {
+      // This is the first deduction for this template template parameter.
+      ExistingArg = TemplateArgument(S.Context.getCanonicalTemplateName(Arg));
+      return Sema::TDK_Success;
+    }
+    
+    // Verify that the previous binding matches this deduction.
+    assert(ExistingArg.getKind() == TemplateArgument::Template);
+    if (S.Context.hasSameTemplateName(ExistingArg.getAsTemplate(), Arg))
+      return Sema::TDK_Success;
+    
+    // Inconsistent deduction.
+    Info.Param = TempParam;
+    Info.FirstArg = ExistingArg;
+    Info.SecondArg = TemplateArgument(Arg);
+    return Sema::TDK_Inconsistent;
+  }
+  
+  // Verify that the two template names are equivalent.
+  if (S.Context.hasSameTemplateName(Param, Arg))
+    return Sema::TDK_Success;
+  
+  // Mismatch of non-dependent template parameter to argument.
+  Info.FirstArg = TemplateArgument(Param);
+  Info.SecondArg = TemplateArgument(Arg);
+  return Sema::TDK_NonDeducedMismatch;
+}
+
+/// \brief Deduce the template arguments by comparing the template parameter
+/// type (which is a template-id) with the template argument type.
+///
+/// \param S the Sema
+///
+/// \param TemplateParams the template parameters that we are deducing
+///
+/// \param Param the parameter type
+///
+/// \param Arg the argument type
+///
+/// \param Info information about the template argument deduction itself
+///
+/// \param Deduced the deduced template arguments
+///
+/// \returns the result of template argument deduction so far. Note that a
+/// "success" result means that template argument deduction has not yet failed,
+/// but it may still fail, later, for other reasons.
+static Sema::TemplateDeductionResult
+DeduceTemplateArguments(Sema &S,
+                        TemplateParameterList *TemplateParams,
+                        const TemplateSpecializationType *Param,
+                        QualType Arg,
+                        Sema::TemplateDeductionInfo &Info,
+                    llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
+  assert(Arg.isCanonical() && "Argument type must be canonical");
+
+  // Check whether the template argument is a dependent template-id.
+  if (const TemplateSpecializationType *SpecArg
+        = dyn_cast<TemplateSpecializationType>(Arg)) {
+    // Perform template argument deduction for the template name.
+    if (Sema::TemplateDeductionResult Result
+          = DeduceTemplateArguments(S, TemplateParams,
+                                    Param->getTemplateName(),
+                                    SpecArg->getTemplateName(),
+                                    Info, Deduced))
+      return Result;
+
+
+    // Perform template argument deduction on each template
+    // argument.
+    unsigned NumArgs = std::min(SpecArg->getNumArgs(), Param->getNumArgs());
+    for (unsigned I = 0; I != NumArgs; ++I)
+      if (Sema::TemplateDeductionResult Result
+            = DeduceTemplateArguments(S, TemplateParams,
+                                      Param->getArg(I),
+                                      SpecArg->getArg(I),
+                                      Info, Deduced))
+        return Result;
+
+    return Sema::TDK_Success;
+  }
+
+  // If the argument type is a class template specialization, we
+  // perform template argument deduction using its template
+  // arguments.
+  const RecordType *RecordArg = dyn_cast<RecordType>(Arg);
+  if (!RecordArg)
+    return Sema::TDK_NonDeducedMismatch;
+
+  ClassTemplateSpecializationDecl *SpecArg
+    = dyn_cast<ClassTemplateSpecializationDecl>(RecordArg->getDecl());
+  if (!SpecArg)
+    return Sema::TDK_NonDeducedMismatch;
+
+  // Perform template argument deduction for the template name.
+  if (Sema::TemplateDeductionResult Result
+        = DeduceTemplateArguments(S,
+                                  TemplateParams,
+                                  Param->getTemplateName(),
+                               TemplateName(SpecArg->getSpecializedTemplate()),
+                                  Info, Deduced))
+    return Result;
+
+  unsigned NumArgs = Param->getNumArgs();
+  const TemplateArgumentList &ArgArgs = SpecArg->getTemplateArgs();
+  if (NumArgs != ArgArgs.size())
+    return Sema::TDK_NonDeducedMismatch;
+
+  for (unsigned I = 0; I != NumArgs; ++I)
+    if (Sema::TemplateDeductionResult Result
+          = DeduceTemplateArguments(S, TemplateParams,
+                                    Param->getArg(I),
+                                    ArgArgs.get(I),
+                                    Info, Deduced))
+      return Result;
+
+  return Sema::TDK_Success;
+}
+
+/// \brief Deduce the template arguments by comparing the parameter type and
+/// the argument type (C++ [temp.deduct.type]).
+///
+/// \param S the semantic analysis object within which we are deducing
+///
+/// \param TemplateParams the template parameters that we are deducing
+///
+/// \param ParamIn the parameter type
+///
+/// \param ArgIn the argument type
+///
+/// \param Info information about the template argument deduction itself
+///
+/// \param Deduced the deduced template arguments
+///
+/// \param TDF bitwise OR of the TemplateDeductionFlags bits that describe
+/// how template argument deduction is performed.
+///
+/// \returns the result of template argument deduction so far. Note that a
+/// "success" result means that template argument deduction has not yet failed,
+/// but it may still fail, later, for other reasons.
+static Sema::TemplateDeductionResult
+DeduceTemplateArguments(Sema &S,
+                        TemplateParameterList *TemplateParams,
+                        QualType ParamIn, QualType ArgIn,
+                        Sema::TemplateDeductionInfo &Info,
+                     llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced,
+                        unsigned TDF) {
+  // We only want to look at the canonical types, since typedefs and
+  // sugar are not part of template argument deduction.
+  QualType Param = S.Context.getCanonicalType(ParamIn);
+  QualType Arg = S.Context.getCanonicalType(ArgIn);
+
+  // C++0x [temp.deduct.call]p4 bullet 1:
+  //   - If the original P is a reference type, the deduced A (i.e., the type
+  //     referred to by the reference) can be more cv-qualified than the
+  //     transformed A.
+  if (TDF & TDF_ParamWithReferenceType) {
+    Qualifiers Quals;
+    QualType UnqualParam = S.Context.getUnqualifiedArrayType(Param, Quals);
+    Quals.setCVRQualifiers(Quals.getCVRQualifiers() &
+                           Arg.getCVRQualifiersThroughArrayTypes());
+    Param = S.Context.getQualifiedType(UnqualParam, Quals);
+  }
+
+  // If the parameter type is not dependent, there is nothing to deduce.
+  if (!Param->isDependentType()) {
+    if (!(TDF & TDF_SkipNonDependent) && Param != Arg) {
+      
+      return Sema::TDK_NonDeducedMismatch;
+    }
+    
+    return Sema::TDK_Success;
+  }
+
+  // C++ [temp.deduct.type]p9:
+  //   A template type argument T, a template template argument TT or a
+  //   template non-type argument i can be deduced if P and A have one of
+  //   the following forms:
+  //
+  //     T
+  //     cv-list T
+  if (const TemplateTypeParmType *TemplateTypeParm
+        = Param->getAs<TemplateTypeParmType>()) {
+    unsigned Index = TemplateTypeParm->getIndex();
+    bool RecanonicalizeArg = false;
+
+    // If the argument type is an array type, move the qualifiers up to the
+    // top level, so they can be matched with the qualifiers on the parameter.
+    // FIXME: address spaces, ObjC GC qualifiers
+    if (isa<ArrayType>(Arg)) {
+      Qualifiers Quals;
+      Arg = S.Context.getUnqualifiedArrayType(Arg, Quals);
+      if (Quals) {
+        Arg = S.Context.getQualifiedType(Arg, Quals);
+        RecanonicalizeArg = true;
+      }
+    }
+
+    // The argument type can not be less qualified than the parameter
+    // type.
+    if (Param.isMoreQualifiedThan(Arg) && !(TDF & TDF_IgnoreQualifiers)) {
+      Info.Param = cast<TemplateTypeParmDecl>(TemplateParams->getParam(Index));
+      Info.FirstArg = Deduced[Index];
+      Info.SecondArg = TemplateArgument(Arg);
+      return Sema::TDK_InconsistentQuals;
+    }
+
+    assert(TemplateTypeParm->getDepth() == 0 && "Can't deduce with depth > 0");
+    assert(Arg != S.Context.OverloadTy && "Unresolved overloaded function");
+    QualType DeducedType = Arg;
+    DeducedType.removeCVRQualifiers(Param.getCVRQualifiers());
+    if (RecanonicalizeArg)
+      DeducedType = S.Context.getCanonicalType(DeducedType);
+
+    if (Deduced[Index].isNull())
+      Deduced[Index] = TemplateArgument(DeducedType);
+    else {
+      // C++ [temp.deduct.type]p2:
+      //   [...] If type deduction cannot be done for any P/A pair, or if for
+      //   any pair the deduction leads to more than one possible set of
+      //   deduced values, or if different pairs yield different deduced
+      //   values, or if any template argument remains neither deduced nor
+      //   explicitly specified, template argument deduction fails.
+      if (Deduced[Index].getAsType() != DeducedType) {
+        Info.Param
+          = cast<TemplateTypeParmDecl>(TemplateParams->getParam(Index));
+        Info.FirstArg = Deduced[Index];
+        Info.SecondArg = TemplateArgument(Arg);
+        return Sema::TDK_Inconsistent;
+      }
+    }
+    return Sema::TDK_Success;
+  }
+
+  // Set up the template argument deduction information for a failure.
+  Info.FirstArg = TemplateArgument(ParamIn);
+  Info.SecondArg = TemplateArgument(ArgIn);
+
+  // Check the cv-qualifiers on the parameter and argument types.
+  if (!(TDF & TDF_IgnoreQualifiers)) {
+    if (TDF & TDF_ParamWithReferenceType) {
+      if (Param.isMoreQualifiedThan(Arg))
+        return Sema::TDK_NonDeducedMismatch;
+    } else {
+      if (Param.getCVRQualifiers() != Arg.getCVRQualifiers())
+        return Sema::TDK_NonDeducedMismatch;
+    }
+  }
+
+  switch (Param->getTypeClass()) {
+    // No deduction possible for these types
+    case Type::Builtin:
+      return Sema::TDK_NonDeducedMismatch;
+
+    //     T *
+    case Type::Pointer: {
+      const PointerType *PointerArg = Arg->getAs<PointerType>();
+      if (!PointerArg)
+        return Sema::TDK_NonDeducedMismatch;
+
+      unsigned SubTDF = TDF & (TDF_IgnoreQualifiers | TDF_DerivedClass);
+      return DeduceTemplateArguments(S, TemplateParams,
+                                   cast<PointerType>(Param)->getPointeeType(),
+                                     PointerArg->getPointeeType(),
+                                     Info, Deduced, SubTDF);
+    }
+
+    //     T &
+    case Type::LValueReference: {
+      const LValueReferenceType *ReferenceArg = Arg->getAs<LValueReferenceType>();
+      if (!ReferenceArg)
+        return Sema::TDK_NonDeducedMismatch;
+
+      return DeduceTemplateArguments(S, TemplateParams,
+                           cast<LValueReferenceType>(Param)->getPointeeType(),
+                                     ReferenceArg->getPointeeType(),
+                                     Info, Deduced, 0);
+    }
+
+    //     T && [C++0x]
+    case Type::RValueReference: {
+      const RValueReferenceType *ReferenceArg = Arg->getAs<RValueReferenceType>();
+      if (!ReferenceArg)
+        return Sema::TDK_NonDeducedMismatch;
+
+      return DeduceTemplateArguments(S, TemplateParams,
+                           cast<RValueReferenceType>(Param)->getPointeeType(),
+                                     ReferenceArg->getPointeeType(),
+                                     Info, Deduced, 0);
+    }
+
+    //     T [] (implied, but not stated explicitly)
+    case Type::IncompleteArray: {
+      const IncompleteArrayType *IncompleteArrayArg =
+        S.Context.getAsIncompleteArrayType(Arg);
+      if (!IncompleteArrayArg)
+        return Sema::TDK_NonDeducedMismatch;
+
+      return DeduceTemplateArguments(S, TemplateParams,
+                     S.Context.getAsIncompleteArrayType(Param)->getElementType(),
+                                     IncompleteArrayArg->getElementType(),
+                                     Info, Deduced, 0);
+    }
+
+    //     T [integer-constant]
+    case Type::ConstantArray: {
+      const ConstantArrayType *ConstantArrayArg =
+        S.Context.getAsConstantArrayType(Arg);
+      if (!ConstantArrayArg)
+        return Sema::TDK_NonDeducedMismatch;
+
+      const ConstantArrayType *ConstantArrayParm =
+        S.Context.getAsConstantArrayType(Param);
+      if (ConstantArrayArg->getSize() != ConstantArrayParm->getSize())
+        return Sema::TDK_NonDeducedMismatch;
+
+      return DeduceTemplateArguments(S, TemplateParams,
+                                     ConstantArrayParm->getElementType(),
+                                     ConstantArrayArg->getElementType(),
+                                     Info, Deduced, 0);
+    }
+
+    //     type [i]
+    case Type::DependentSizedArray: {
+      const ArrayType *ArrayArg = S.Context.getAsArrayType(Arg);
+      if (!ArrayArg)
+        return Sema::TDK_NonDeducedMismatch;
+
+      // Check the element type of the arrays
+      const DependentSizedArrayType *DependentArrayParm
+        = S.Context.getAsDependentSizedArrayType(Param);
+      if (Sema::TemplateDeductionResult Result
+            = DeduceTemplateArguments(S, TemplateParams,
+                                      DependentArrayParm->getElementType(),
+                                      ArrayArg->getElementType(),
+                                      Info, Deduced, 0))
+        return Result;
+
+      // Determine the array bound is something we can deduce.
+      NonTypeTemplateParmDecl *NTTP
+        = getDeducedParameterFromExpr(DependentArrayParm->getSizeExpr());
+      if (!NTTP)
+        return Sema::TDK_Success;
+
+      // We can perform template argument deduction for the given non-type
+      // template parameter.
+      assert(NTTP->getDepth() == 0 &&
+             "Cannot deduce non-type template argument at depth > 0");
+      if (const ConstantArrayType *ConstantArrayArg
+            = dyn_cast<ConstantArrayType>(ArrayArg)) {
+        llvm::APSInt Size(ConstantArrayArg->getSize());
+        return DeduceNonTypeTemplateArgument(S, NTTP, Size, 
+                                             S.Context.getSizeType(),
+                                             /*ArrayBound=*/true,
+                                             Info, Deduced);
+      }
+      if (const DependentSizedArrayType *DependentArrayArg
+            = dyn_cast<DependentSizedArrayType>(ArrayArg))
+        return DeduceNonTypeTemplateArgument(S, NTTP,
+                                             DependentArrayArg->getSizeExpr(),
+                                             Info, Deduced);
+
+      // Incomplete type does not match a dependently-sized array type
+      return Sema::TDK_NonDeducedMismatch;
+    }
+
+    //     type(*)(T)
+    //     T(*)()
+    //     T(*)(T)
+    case Type::FunctionProto: {
+      const FunctionProtoType *FunctionProtoArg =
+        dyn_cast<FunctionProtoType>(Arg);
+      if (!FunctionProtoArg)
+        return Sema::TDK_NonDeducedMismatch;
+
+      const FunctionProtoType *FunctionProtoParam =
+        cast<FunctionProtoType>(Param);
+
+      if (FunctionProtoParam->getTypeQuals() !=
+          FunctionProtoArg->getTypeQuals())
+        return Sema::TDK_NonDeducedMismatch;
+
+      if (FunctionProtoParam->getNumArgs() != FunctionProtoArg->getNumArgs())
+        return Sema::TDK_NonDeducedMismatch;
+
+      if (FunctionProtoParam->isVariadic() != FunctionProtoArg->isVariadic())
+        return Sema::TDK_NonDeducedMismatch;
+
+      // Check return types.
+      if (Sema::TemplateDeductionResult Result
+            = DeduceTemplateArguments(S, TemplateParams,
+                                      FunctionProtoParam->getResultType(),
+                                      FunctionProtoArg->getResultType(),
+                                      Info, Deduced, 0))
+        return Result;
+
+      for (unsigned I = 0, N = FunctionProtoParam->getNumArgs(); I != N; ++I) {
+        // Check argument types.
+        if (Sema::TemplateDeductionResult Result
+              = DeduceTemplateArguments(S, TemplateParams,
+                                        FunctionProtoParam->getArgType(I),
+                                        FunctionProtoArg->getArgType(I),
+                                        Info, Deduced, 0))
+          return Result;
+      }
+
+      return Sema::TDK_Success;
+    }
+
+    case Type::InjectedClassName: {
+      // Treat a template's injected-class-name as if the template
+      // specialization type had been used.
+      Param = cast<InjectedClassNameType>(Param)
+        ->getInjectedSpecializationType();
+      assert(isa<TemplateSpecializationType>(Param) &&
+             "injected class name is not a template specialization type");
+      // fall through
+    }
+
+    //     template-name<T> (where template-name refers to a class template)
+    //     template-name<i>
+    //     TT<T>
+    //     TT<i>
+    //     TT<>
+    case Type::TemplateSpecialization: {
+      const TemplateSpecializationType *SpecParam
+        = cast<TemplateSpecializationType>(Param);
+
+      // Try to deduce template arguments from the template-id.
+      Sema::TemplateDeductionResult Result
+        = DeduceTemplateArguments(S, TemplateParams, SpecParam, Arg,
+                                  Info, Deduced);
+
+      if (Result && (TDF & TDF_DerivedClass)) {
+        // C++ [temp.deduct.call]p3b3:
+        //   If P is a class, and P has the form template-id, then A can be a
+        //   derived class of the deduced A. Likewise, if P is a pointer to a
+        //   class of the form template-id, A can be a pointer to a derived
+        //   class pointed to by the deduced A.
+        //
+        // More importantly:
+        //   These alternatives are considered only if type deduction would
+        //   otherwise fail.
+        if (const RecordType *RecordT = Arg->getAs<RecordType>()) {
+          // We cannot inspect base classes as part of deduction when the type
+          // is incomplete, so either instantiate any templates necessary to
+          // complete the type, or skip over it if it cannot be completed.
+          if (S.RequireCompleteType(Info.getLocation(), Arg, 0))
+            return Result;
+
+          // Use data recursion to crawl through the list of base classes.
+          // Visited contains the set of nodes we have already visited, while
+          // ToVisit is our stack of records that we still need to visit.
+          llvm::SmallPtrSet<const RecordType *, 8> Visited;
+          llvm::SmallVector<const RecordType *, 8> ToVisit;
+          ToVisit.push_back(RecordT);
+          bool Successful = false;
+          while (!ToVisit.empty()) {
+            // Retrieve the next class in the inheritance hierarchy.
+            const RecordType *NextT = ToVisit.back();
+            ToVisit.pop_back();
+
+            // If we have already seen this type, skip it.
+            if (!Visited.insert(NextT))
+              continue;
+
+            // If this is a base class, try to perform template argument
+            // deduction from it.
+            if (NextT != RecordT) {
+              Sema::TemplateDeductionResult BaseResult
+                = DeduceTemplateArguments(S, TemplateParams, SpecParam,
+                                          QualType(NextT, 0), Info, Deduced);
+
+              // If template argument deduction for this base was successful,
+              // note that we had some success.
+              if (BaseResult == Sema::TDK_Success)
+                Successful = true;
+            }
+
+            // Visit base classes
+            CXXRecordDecl *Next = cast<CXXRecordDecl>(NextT->getDecl());
+            for (CXXRecordDecl::base_class_iterator Base = Next->bases_begin(),
+                                                 BaseEnd = Next->bases_end();
+                 Base != BaseEnd; ++Base) {
+              assert(Base->getType()->isRecordType() &&
+                     "Base class that isn't a record?");
+              ToVisit.push_back(Base->getType()->getAs<RecordType>());
+            }
+          }
+
+          if (Successful)
+            return Sema::TDK_Success;
+        }
+
+      }
+
+      return Result;
+    }
+
+    //     T type::*
+    //     T T::*
+    //     T (type::*)()
+    //     type (T::*)()
+    //     type (type::*)(T)
+    //     type (T::*)(T)
+    //     T (type::*)(T)
+    //     T (T::*)()
+    //     T (T::*)(T)
+    case Type::MemberPointer: {
+      const MemberPointerType *MemPtrParam = cast<MemberPointerType>(Param);
+      const MemberPointerType *MemPtrArg = dyn_cast<MemberPointerType>(Arg);
+      if (!MemPtrArg)
+        return Sema::TDK_NonDeducedMismatch;
+
+      if (Sema::TemplateDeductionResult Result
+            = DeduceTemplateArguments(S, TemplateParams,
+                                      MemPtrParam->getPointeeType(),
+                                      MemPtrArg->getPointeeType(),
+                                      Info, Deduced,
+                                      TDF & TDF_IgnoreQualifiers))
+        return Result;
+
+      return DeduceTemplateArguments(S, TemplateParams,
+                                     QualType(MemPtrParam->getClass(), 0),
+                                     QualType(MemPtrArg->getClass(), 0),
+                                     Info, Deduced, 0);
+    }
+
+    //     (clang extension)
+    //
+    //     type(^)(T)
+    //     T(^)()
+    //     T(^)(T)
+    case Type::BlockPointer: {
+      const BlockPointerType *BlockPtrParam = cast<BlockPointerType>(Param);
+      const BlockPointerType *BlockPtrArg = dyn_cast<BlockPointerType>(Arg);
+
+      if (!BlockPtrArg)
+        return Sema::TDK_NonDeducedMismatch;
+
+      return DeduceTemplateArguments(S, TemplateParams,
+                                     BlockPtrParam->getPointeeType(),
+                                     BlockPtrArg->getPointeeType(), Info,
+                                     Deduced, 0);
+    }
+
+    case Type::TypeOfExpr:
+    case Type::TypeOf:
+    case Type::DependentName:
+      // No template argument deduction for these types
+      return Sema::TDK_Success;
+
+    default:
+      break;
+  }
+
+  // FIXME: Many more cases to go (to go).
+  return Sema::TDK_Success;
+}
+
+static Sema::TemplateDeductionResult
+DeduceTemplateArguments(Sema &S,
+                        TemplateParameterList *TemplateParams,
+                        const TemplateArgument &Param,
+                        const TemplateArgument &Arg,
+                        Sema::TemplateDeductionInfo &Info,
+                    llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
+  switch (Param.getKind()) {
+  case TemplateArgument::Null:
+    assert(false && "Null template argument in parameter list");
+    break;
+
+  case TemplateArgument::Type:
+    if (Arg.getKind() == TemplateArgument::Type)
+      return DeduceTemplateArguments(S, TemplateParams, Param.getAsType(),
+                                     Arg.getAsType(), Info, Deduced, 0);
+    Info.FirstArg = Param;
+    Info.SecondArg = Arg;
+    return Sema::TDK_NonDeducedMismatch;
+      
+  case TemplateArgument::Template:
+    if (Arg.getKind() == TemplateArgument::Template)
+      return DeduceTemplateArguments(S, TemplateParams, 
+                                     Param.getAsTemplate(),
+                                     Arg.getAsTemplate(), Info, Deduced);
+    Info.FirstArg = Param;
+    Info.SecondArg = Arg;
+    return Sema::TDK_NonDeducedMismatch;
+      
+  case TemplateArgument::Declaration:
+    if (Arg.getKind() == TemplateArgument::Declaration &&
+        Param.getAsDecl()->getCanonicalDecl() ==
+          Arg.getAsDecl()->getCanonicalDecl())
+      return Sema::TDK_Success;
+      
+    Info.FirstArg = Param;
+    Info.SecondArg = Arg;
+    return Sema::TDK_NonDeducedMismatch;
+
+  case TemplateArgument::Integral:
+    if (Arg.getKind() == TemplateArgument::Integral) {
+      if (hasSameExtendedValue(*Param.getAsIntegral(), *Arg.getAsIntegral()))
+        return Sema::TDK_Success;
+
+      Info.FirstArg = Param;
+      Info.SecondArg = Arg;
+      return Sema::TDK_NonDeducedMismatch;
+    }
+
+    if (Arg.getKind() == TemplateArgument::Expression) {
+      Info.FirstArg = Param;
+      Info.SecondArg = Arg;
+      return Sema::TDK_NonDeducedMismatch;
+    }
+
+    assert(false && "Type/value mismatch");
+    Info.FirstArg = Param;
+    Info.SecondArg = Arg;
+    return Sema::TDK_NonDeducedMismatch;
+
+  case TemplateArgument::Expression: {
+    if (NonTypeTemplateParmDecl *NTTP
+          = getDeducedParameterFromExpr(Param.getAsExpr())) {
+      if (Arg.getKind() == TemplateArgument::Integral)
+        return DeduceNonTypeTemplateArgument(S, NTTP,
+                                             *Arg.getAsIntegral(),
+                                             Arg.getIntegralType(),
+                                             /*ArrayBound=*/false,
+                                             Info, Deduced);
+      if (Arg.getKind() == TemplateArgument::Expression)
+        return DeduceNonTypeTemplateArgument(S, NTTP, Arg.getAsExpr(),
+                                             Info, Deduced);
+      if (Arg.getKind() == TemplateArgument::Declaration)
+        return DeduceNonTypeTemplateArgument(S, NTTP, Arg.getAsDecl(),
+                                             Info, Deduced);
+      
+      assert(false && "Type/value mismatch");
+      Info.FirstArg = Param;
+      Info.SecondArg = Arg;
+      return Sema::TDK_NonDeducedMismatch;
+    }
+
+    // Can't deduce anything, but that's okay.
+    return Sema::TDK_Success;
+  }
+  case TemplateArgument::Pack:
+    assert(0 && "FIXME: Implement!");
+    break;
+  }
+
+  return Sema::TDK_Success;
+}
+
+static Sema::TemplateDeductionResult
+DeduceTemplateArguments(Sema &S,
+                        TemplateParameterList *TemplateParams,
+                        const TemplateArgumentList &ParamList,
+                        const TemplateArgumentList &ArgList,
+                        Sema::TemplateDeductionInfo &Info,
+                    llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
+  assert(ParamList.size() == ArgList.size());
+  for (unsigned I = 0, N = ParamList.size(); I != N; ++I) {
+    if (Sema::TemplateDeductionResult Result
+          = DeduceTemplateArguments(S, TemplateParams,
+                                    ParamList[I], ArgList[I],
+                                    Info, Deduced))
+      return Result;
+  }
+  return Sema::TDK_Success;
+}
+
+/// \brief Determine whether two template arguments are the same.
+static bool isSameTemplateArg(ASTContext &Context,
+                              const TemplateArgument &X,
+                              const TemplateArgument &Y) {
+  if (X.getKind() != Y.getKind())
+    return false;
+
+  switch (X.getKind()) {
+    case TemplateArgument::Null:
+      assert(false && "Comparing NULL template argument");
+      break;
+
+    case TemplateArgument::Type:
+      return Context.getCanonicalType(X.getAsType()) ==
+             Context.getCanonicalType(Y.getAsType());
+
+    case TemplateArgument::Declaration:
+      return X.getAsDecl()->getCanonicalDecl() ==
+             Y.getAsDecl()->getCanonicalDecl();
+
+    case TemplateArgument::Template:
+      return Context.getCanonicalTemplateName(X.getAsTemplate())
+               .getAsVoidPointer() ==
+             Context.getCanonicalTemplateName(Y.getAsTemplate())
+               .getAsVoidPointer();
+      
+    case TemplateArgument::Integral:
+      return *X.getAsIntegral() == *Y.getAsIntegral();
+
+    case TemplateArgument::Expression: {
+      llvm::FoldingSetNodeID XID, YID;
+      X.getAsExpr()->Profile(XID, Context, true);
+      Y.getAsExpr()->Profile(YID, Context, true);      
+      return XID == YID;
+    }
+
+    case TemplateArgument::Pack:
+      if (X.pack_size() != Y.pack_size())
+        return false;
+
+      for (TemplateArgument::pack_iterator XP = X.pack_begin(),
+                                        XPEnd = X.pack_end(),
+                                           YP = Y.pack_begin();
+           XP != XPEnd; ++XP, ++YP)
+        if (!isSameTemplateArg(Context, *XP, *YP))
+          return false;
+
+      return true;
+  }
+
+  return false;
+}
+
+/// \brief Helper function to build a TemplateParameter when we don't
+/// know its type statically.
+static TemplateParameter makeTemplateParameter(Decl *D) {
+  if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(D))
+    return TemplateParameter(TTP);
+  else if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D))
+    return TemplateParameter(NTTP);
+
+  return TemplateParameter(cast<TemplateTemplateParmDecl>(D));
+}
+
+/// \brief Perform template argument deduction to determine whether
+/// the given template arguments match the given class template
+/// partial specialization per C++ [temp.class.spec.match].
+Sema::TemplateDeductionResult
+Sema::DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial,
+                              const TemplateArgumentList &TemplateArgs,
+                              TemplateDeductionInfo &Info) {
+  // C++ [temp.class.spec.match]p2:
+  //   A partial specialization matches a given actual template
+  //   argument list if the template arguments of the partial
+  //   specialization can be deduced from the actual template argument
+  //   list (14.8.2).
+  SFINAETrap Trap(*this);
+  llvm::SmallVector<DeducedTemplateArgument, 4> Deduced;
+  Deduced.resize(Partial->getTemplateParameters()->size());
+  if (TemplateDeductionResult Result
+        = ::DeduceTemplateArguments(*this,
+                                    Partial->getTemplateParameters(),
+                                    Partial->getTemplateArgs(),
+                                    TemplateArgs, Info, Deduced))
+    return Result;
+
+  InstantiatingTemplate Inst(*this, Partial->getLocation(), Partial,
+                             Deduced.data(), Deduced.size());
+  if (Inst)
+    return TDK_InstantiationDepth;
+
+  // C++ [temp.deduct.type]p2:
+  //   [...] or if any template argument remains neither deduced nor
+  //   explicitly specified, template argument deduction fails.
+  TemplateArgumentListBuilder Builder(Partial->getTemplateParameters(),
+                                      Deduced.size());
+  for (unsigned I = 0, N = Deduced.size(); I != N; ++I) {
+    if (Deduced[I].isNull()) {
+      Decl *Param
+        = const_cast<NamedDecl *>(
+                                Partial->getTemplateParameters()->getParam(I));
+      Info.Param = makeTemplateParameter(Param);
+      return TDK_Incomplete;
+    }
+
+    Builder.Append(Deduced[I]);
+  }
+
+  // Form the template argument list from the deduced template arguments.
+  TemplateArgumentList *DeducedArgumentList
+    = new (Context) TemplateArgumentList(Context, Builder, /*TakeArgs=*/true);
+  Info.reset(DeducedArgumentList);
+
+  // Substitute the deduced template arguments into the template
+  // arguments of the class template partial specialization, and
+  // verify that the instantiated template arguments are both valid
+  // and are equivalent to the template arguments originally provided
+  // to the class template.
+  // FIXME: Do we have to correct the types of deduced non-type template 
+  // arguments (in particular, integral non-type template arguments?).
+  Sema::LocalInstantiationScope InstScope(*this);
+  ClassTemplateDecl *ClassTemplate = Partial->getSpecializedTemplate();
+  const TemplateArgumentLoc *PartialTemplateArgs
+    = Partial->getTemplateArgsAsWritten();
+  unsigned N = Partial->getNumTemplateArgsAsWritten();
+
+  // Note that we don't provide the langle and rangle locations.
+  TemplateArgumentListInfo InstArgs;
+
+  for (unsigned I = 0; I != N; ++I) {
+    Decl *Param = const_cast<NamedDecl *>(
+                    ClassTemplate->getTemplateParameters()->getParam(I));
+    TemplateArgumentLoc InstArg;
+    if (Subst(PartialTemplateArgs[I], InstArg,
+              MultiLevelTemplateArgumentList(*DeducedArgumentList))) {
+      Info.Param = makeTemplateParameter(Param);
+      Info.FirstArg = PartialTemplateArgs[I].getArgument();
+      return TDK_SubstitutionFailure;
+    }
+    InstArgs.addArgument(InstArg);
+  }
+
+  TemplateArgumentListBuilder ConvertedInstArgs(
+                                  ClassTemplate->getTemplateParameters(), N);
+
+  if (CheckTemplateArgumentList(ClassTemplate, Partial->getLocation(),
+                                InstArgs, false, ConvertedInstArgs)) {
+    // FIXME: fail with more useful information?
+    return TDK_SubstitutionFailure;
+  }
+  
+  for (unsigned I = 0, E = ConvertedInstArgs.flatSize(); I != E; ++I) {
+    TemplateArgument InstArg = ConvertedInstArgs.getFlatArguments()[I];
+
+    Decl *Param = const_cast<NamedDecl *>(
+                    ClassTemplate->getTemplateParameters()->getParam(I));
+
+    if (InstArg.getKind() == TemplateArgument::Expression) {
+      // When the argument is an expression, check the expression result
+      // against the actual template parameter to get down to the canonical
+      // template argument.
+      Expr *InstExpr = InstArg.getAsExpr();
+      if (NonTypeTemplateParmDecl *NTTP
+            = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
+        if (CheckTemplateArgument(NTTP, NTTP->getType(), InstExpr, InstArg)) {
+          Info.Param = makeTemplateParameter(Param);
+          Info.FirstArg = Partial->getTemplateArgs()[I];
+          return TDK_SubstitutionFailure;
+        }
+      }
+    }
+
+    if (!isSameTemplateArg(Context, TemplateArgs[I], InstArg)) {
+      Info.Param = makeTemplateParameter(Param);
+      Info.FirstArg = TemplateArgs[I];
+      Info.SecondArg = InstArg;
+      return TDK_NonDeducedMismatch;
+    }
+  }
+
+  if (Trap.hasErrorOccurred())
+    return TDK_SubstitutionFailure;
+
+  return TDK_Success;
+}
+
+/// \brief Determine whether the given type T is a simple-template-id type.
+static bool isSimpleTemplateIdType(QualType T) {
+  if (const TemplateSpecializationType *Spec
+        = T->getAs<TemplateSpecializationType>())
+    return Spec->getTemplateName().getAsTemplateDecl() != 0;
+
+  return false;
+}
+
+/// \brief Substitute the explicitly-provided template arguments into the
+/// given function template according to C++ [temp.arg.explicit].
+///
+/// \param FunctionTemplate the function template into which the explicit
+/// template arguments will be substituted.
+///
+/// \param ExplicitTemplateArguments the explicitly-specified template
+/// arguments.
+///
+/// \param Deduced the deduced template arguments, which will be populated
+/// with the converted and checked explicit template arguments.
+///
+/// \param ParamTypes will be populated with the instantiated function
+/// parameters.
+///
+/// \param FunctionType if non-NULL, the result type of the function template
+/// will also be instantiated and the pointed-to value will be updated with
+/// the instantiated function type.
+///
+/// \param Info if substitution fails for any reason, this object will be
+/// populated with more information about the failure.
+///
+/// \returns TDK_Success if substitution was successful, or some failure
+/// condition.
+Sema::TemplateDeductionResult
+Sema::SubstituteExplicitTemplateArguments(
+                                      FunctionTemplateDecl *FunctionTemplate,
+                        const TemplateArgumentListInfo &ExplicitTemplateArgs,
+                       llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced,
+                                 llvm::SmallVectorImpl<QualType> &ParamTypes,
+                                          QualType *FunctionType,
+                                          TemplateDeductionInfo &Info) {
+  FunctionDecl *Function = FunctionTemplate->getTemplatedDecl();
+  TemplateParameterList *TemplateParams
+    = FunctionTemplate->getTemplateParameters();
+
+  if (ExplicitTemplateArgs.size() == 0) {
+    // No arguments to substitute; just copy over the parameter types and
+    // fill in the function type.
+    for (FunctionDecl::param_iterator P = Function->param_begin(),
+                                   PEnd = Function->param_end();
+         P != PEnd;
+         ++P)
+      ParamTypes.push_back((*P)->getType());
+
+    if (FunctionType)
+      *FunctionType = Function->getType();
+    return TDK_Success;
+  }
+
+  // Substitution of the explicit template arguments into a function template
+  /// is a SFINAE context. Trap any errors that might occur.
+  SFINAETrap Trap(*this);
+
+  // C++ [temp.arg.explicit]p3:
+  //   Template arguments that are present shall be specified in the
+  //   declaration order of their corresponding template-parameters. The
+  //   template argument list shall not specify more template-arguments than
+  //   there are corresponding template-parameters.
+  TemplateArgumentListBuilder Builder(TemplateParams,
+                                      ExplicitTemplateArgs.size());
+
+  // Enter a new template instantiation context where we check the
+  // explicitly-specified template arguments against this function template,
+  // and then substitute them into the function parameter types.
+  InstantiatingTemplate Inst(*this, FunctionTemplate->getLocation(),
+                             FunctionTemplate, Deduced.data(), Deduced.size(),
+           ActiveTemplateInstantiation::ExplicitTemplateArgumentSubstitution);
+  if (Inst)
+    return TDK_InstantiationDepth;
+
+  if (CheckTemplateArgumentList(FunctionTemplate,
+                                SourceLocation(),
+                                ExplicitTemplateArgs,
+                                true,
+                                Builder) || Trap.hasErrorOccurred())
+    return TDK_InvalidExplicitArguments;
+
+  // Form the template argument list from the explicitly-specified
+  // template arguments.
+  TemplateArgumentList *ExplicitArgumentList
+    = new (Context) TemplateArgumentList(Context, Builder, /*TakeArgs=*/true);
+  Info.reset(ExplicitArgumentList);
+
+  // Instantiate the types of each of the function parameters given the
+  // explicitly-specified template arguments.
+  for (FunctionDecl::param_iterator P = Function->param_begin(),
+                                PEnd = Function->param_end();
+       P != PEnd;
+       ++P) {
+    QualType ParamType
+      = SubstType((*P)->getType(),
+                  MultiLevelTemplateArgumentList(*ExplicitArgumentList),
+                  (*P)->getLocation(), (*P)->getDeclName());
+    if (ParamType.isNull() || Trap.hasErrorOccurred())
+      return TDK_SubstitutionFailure;
+
+    ParamTypes.push_back(ParamType);
+  }
+
+  // If the caller wants a full function type back, instantiate the return
+  // type and form that function type.
+  if (FunctionType) {
+    // FIXME: exception-specifications?
+    const FunctionProtoType *Proto
+      = Function->getType()->getAs<FunctionProtoType>();
+    assert(Proto && "Function template does not have a prototype?");
+
+    QualType ResultType
+      = SubstType(Proto->getResultType(),
+                  MultiLevelTemplateArgumentList(*ExplicitArgumentList),
+                  Function->getTypeSpecStartLoc(),
+                  Function->getDeclName());
+    if (ResultType.isNull() || Trap.hasErrorOccurred())
+      return TDK_SubstitutionFailure;
+
+    *FunctionType = BuildFunctionType(ResultType,
+                                      ParamTypes.data(), ParamTypes.size(),
+                                      Proto->isVariadic(),
+                                      Proto->getTypeQuals(),
+                                      Function->getLocation(),
+                                      Function->getDeclName());
+    if (FunctionType->isNull() || Trap.hasErrorOccurred())
+      return TDK_SubstitutionFailure;
+  }
+
+  // C++ [temp.arg.explicit]p2:
+  //   Trailing template arguments that can be deduced (14.8.2) may be
+  //   omitted from the list of explicit template-arguments. If all of the
+  //   template arguments can be deduced, they may all be omitted; in this
+  //   case, the empty template argument list <> itself may also be omitted.
+  //
+  // Take all of the explicitly-specified arguments and put them into the
+  // set of deduced template arguments.
+  Deduced.reserve(TemplateParams->size());
+  for (unsigned I = 0, N = ExplicitArgumentList->size(); I != N; ++I)
+    Deduced.push_back(ExplicitArgumentList->get(I));
+
+  return TDK_Success;
+}
+
+/// \brief Allocate a TemplateArgumentLoc where all locations have
+/// been initialized to the given location.
+///
+/// \param S The semantic analysis object.
+///
+/// \param The template argument we are producing template argument
+/// location information for.
+///
+/// \param NTTPType For a declaration template argument, the type of
+/// the non-type template parameter that corresponds to this template
+/// argument.
+///
+/// \param Loc The source location to use for the resulting template
+/// argument.
+static TemplateArgumentLoc 
+getTrivialTemplateArgumentLoc(Sema &S,
+                              const TemplateArgument &Arg, 
+                              QualType NTTPType,
+                              SourceLocation Loc) {
+  switch (Arg.getKind()) {
+  case TemplateArgument::Null:
+    llvm_unreachable("Can't get a NULL template argument here");
+    break;
+
+  case TemplateArgument::Type:
+    return TemplateArgumentLoc(Arg, 
+                    S.Context.getTrivialTypeSourceInfo(Arg.getAsType(), Loc));
+
+  case TemplateArgument::Declaration: {
+    Expr *E
+      = S.BuildExpressionFromDeclTemplateArgument(Arg, NTTPType, Loc)
+                                                              .takeAs<Expr>();
+    return TemplateArgumentLoc(TemplateArgument(E), E);
+  }
+
+  case TemplateArgument::Integral: {
+    Expr *E
+      = S.BuildExpressionFromIntegralTemplateArgument(Arg, Loc).takeAs<Expr>();
+    return TemplateArgumentLoc(TemplateArgument(E), E);
+  }
+
+  case TemplateArgument::Template:
+    return TemplateArgumentLoc(Arg, SourceRange(), Loc);
+
+  case TemplateArgument::Expression:
+    return TemplateArgumentLoc(Arg, Arg.getAsExpr());
+
+  case TemplateArgument::Pack:
+    llvm_unreachable("Template parameter packs are not yet supported");
+  }
+
+  return TemplateArgumentLoc();
+}
+
+/// \brief Finish template argument deduction for a function template,
+/// checking the deduced template arguments for completeness and forming
+/// the function template specialization.
+Sema::TemplateDeductionResult
+Sema::FinishTemplateArgumentDeduction(FunctionTemplateDecl *FunctionTemplate,
+                       llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced,
+                                      unsigned NumExplicitlySpecified,
+                                      FunctionDecl *&Specialization,
+                                      TemplateDeductionInfo &Info) {
+  TemplateParameterList *TemplateParams
+    = FunctionTemplate->getTemplateParameters();
+
+  // Template argument deduction for function templates in a SFINAE context.
+  // Trap any errors that might occur.
+  SFINAETrap Trap(*this);
+
+  // Enter a new template instantiation context while we instantiate the
+  // actual function declaration.
+  InstantiatingTemplate Inst(*this, FunctionTemplate->getLocation(),
+                             FunctionTemplate, Deduced.data(), Deduced.size(),
+              ActiveTemplateInstantiation::DeducedTemplateArgumentSubstitution);
+  if (Inst)
+    return TDK_InstantiationDepth;
+
+  // C++ [temp.deduct.type]p2:
+  //   [...] or if any template argument remains neither deduced nor
+  //   explicitly specified, template argument deduction fails.
+  TemplateArgumentListBuilder Builder(TemplateParams, Deduced.size());
+  for (unsigned I = 0, N = Deduced.size(); I != N; ++I) {
+    NamedDecl *Param = FunctionTemplate->getTemplateParameters()->getParam(I);
+    if (!Deduced[I].isNull()) {
+      if (I < NumExplicitlySpecified || 
+          Deduced[I].getKind() == TemplateArgument::Type) {
+        // We have already fully type-checked and converted this
+        // argument (because it was explicitly-specified) or no
+        // additional checking is necessary (because it's a template
+        // type parameter). Just record the presence of this
+        // parameter.
+        Builder.Append(Deduced[I]);
+        continue;
+      }
+
+      // We have deduced this argument, so it still needs to be
+      // checked and converted.
+
+      // First, for a non-type template parameter type that is
+      // initialized by a declaration, we need the type of the
+      // corresponding non-type template parameter.
+      QualType NTTPType;
+      if (NonTypeTemplateParmDecl *NTTP 
+                                = dyn_cast<NonTypeTemplateParmDecl>(Param)) { 
+        if (Deduced[I].getKind() == TemplateArgument::Declaration) {
+          NTTPType = NTTP->getType();
+          if (NTTPType->isDependentType()) {
+            TemplateArgumentList TemplateArgs(Context, Builder, 
+                                              /*TakeArgs=*/false);
+            NTTPType = SubstType(NTTPType,
+                                 MultiLevelTemplateArgumentList(TemplateArgs),
+                                 NTTP->getLocation(),
+                                 NTTP->getDeclName());
+            if (NTTPType.isNull()) {
+              Info.Param = makeTemplateParameter(Param);
+              return TDK_SubstitutionFailure;
+            }
+          }
+        }
+      }
+
+      // Convert the deduced template argument into a template
+      // argument that we can check, almost as if the user had written
+      // the template argument explicitly.
+      TemplateArgumentLoc Arg = getTrivialTemplateArgumentLoc(*this,
+                                                              Deduced[I],
+                                                              NTTPType,
+                                                           SourceLocation());
+
+      // Check the template argument, converting it as necessary.
+      if (CheckTemplateArgument(Param, Arg,
+                                FunctionTemplate,
+                                FunctionTemplate->getLocation(),
+                                FunctionTemplate->getSourceRange().getEnd(),
+                                Builder,
+                                Deduced[I].wasDeducedFromArrayBound()
+                                  ? CTAK_DeducedFromArrayBound 
+                                  : CTAK_Deduced)) {
+        Info.Param = makeTemplateParameter(
+                         const_cast<NamedDecl *>(TemplateParams->getParam(I)));
+        return TDK_SubstitutionFailure;
+      }
+
+      continue;
+    }
+
+    // Substitute into the default template argument, if available. 
+    TemplateArgumentLoc DefArg
+      = SubstDefaultTemplateArgumentIfAvailable(FunctionTemplate,
+                                              FunctionTemplate->getLocation(),
+                                  FunctionTemplate->getSourceRange().getEnd(),
+                                                Param,
+                                                Builder);
+
+    // If there was no default argument, deduction is incomplete.
+    if (DefArg.getArgument().isNull()) {
+      Info.Param = makeTemplateParameter(
+                         const_cast<NamedDecl *>(TemplateParams->getParam(I)));
+      return TDK_Incomplete;
+    }
+    
+    // Check whether we can actually use the default argument.
+    if (CheckTemplateArgument(Param, DefArg,
+                              FunctionTemplate,
+                              FunctionTemplate->getLocation(),
+                              FunctionTemplate->getSourceRange().getEnd(),
+                              Builder,
+                              CTAK_Deduced)) {
+      Info.Param = makeTemplateParameter(
+                         const_cast<NamedDecl *>(TemplateParams->getParam(I)));
+      return TDK_SubstitutionFailure;
+    }
+
+    // If we get here, we successfully used the default template argument.
+  }
+
+  // Form the template argument list from the deduced template arguments.
+  TemplateArgumentList *DeducedArgumentList
+    = new (Context) TemplateArgumentList(Context, Builder, /*TakeArgs=*/true);
+  Info.reset(DeducedArgumentList);
+
+  // Substitute the deduced template arguments into the function template
+  // declaration to produce the function template specialization.
+  Specialization = cast_or_null<FunctionDecl>(
+                      SubstDecl(FunctionTemplate->getTemplatedDecl(),
+                                FunctionTemplate->getDeclContext(),
+                         MultiLevelTemplateArgumentList(*DeducedArgumentList)));
+  if (!Specialization)
+    return TDK_SubstitutionFailure;
+
+  assert(Specialization->getPrimaryTemplate()->getCanonicalDecl() == 
+         FunctionTemplate->getCanonicalDecl());
+  
+  // If the template argument list is owned by the function template
+  // specialization, release it.
+  if (Specialization->getTemplateSpecializationArgs() == DeducedArgumentList)
+    Info.take();
+
+  // There may have been an error that did not prevent us from constructing a
+  // declaration. Mark the declaration invalid and return with a substitution
+  // failure.
+  if (Trap.hasErrorOccurred()) {
+    Specialization->setInvalidDecl(true);
+    return TDK_SubstitutionFailure;
+  }
+
+  return TDK_Success;
+}
+
+static QualType GetTypeOfFunction(ASTContext &Context,
+                                  bool isAddressOfOperand,
+                                  FunctionDecl *Fn) {
+  if (!isAddressOfOperand) return Fn->getType();
+  if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Fn))
+    if (Method->isInstance())
+      return Context.getMemberPointerType(Fn->getType(),
+               Context.getTypeDeclType(Method->getParent()).getTypePtr());
+  return Context.getPointerType(Fn->getType());
+}
+
+/// Apply the deduction rules for overload sets.
+///
+/// \return the null type if this argument should be treated as an
+/// undeduced context
+static QualType
+ResolveOverloadForDeduction(Sema &S, TemplateParameterList *TemplateParams,
+                            Expr *Arg, QualType ParamType) {
+  llvm::PointerIntPair<OverloadExpr*,1> R = OverloadExpr::find(Arg);
+
+  bool isAddressOfOperand = bool(R.getInt());
+  OverloadExpr *Ovl = R.getPointer();
+
+  // If there were explicit template arguments, we can only find
+  // something via C++ [temp.arg.explicit]p3, i.e. if the arguments
+  // unambiguously name a full specialization.
+  if (Ovl->hasExplicitTemplateArgs()) {
+    // But we can still look for an explicit specialization.
+    if (FunctionDecl *ExplicitSpec
+          = S.ResolveSingleFunctionTemplateSpecialization(Ovl))
+      return GetTypeOfFunction(S.Context, isAddressOfOperand, ExplicitSpec);
+    return QualType();
+  }
+
+  // C++0x [temp.deduct.call]p6:
+  //   When P is a function type, pointer to function type, or pointer
+  //   to member function type:
+
+  if (!ParamType->isFunctionType() &&
+      !ParamType->isFunctionPointerType() &&
+      !ParamType->isMemberFunctionPointerType())
+    return QualType();
+
+  QualType Match;
+  for (UnresolvedSetIterator I = Ovl->decls_begin(),
+         E = Ovl->decls_end(); I != E; ++I) {
+    NamedDecl *D = (*I)->getUnderlyingDecl();
+
+    //   - If the argument is an overload set containing one or more
+    //     function templates, the parameter is treated as a
+    //     non-deduced context.
+    if (isa<FunctionTemplateDecl>(D))
+      return QualType();
+
+    FunctionDecl *Fn = cast<FunctionDecl>(D);
+    QualType ArgType = GetTypeOfFunction(S.Context, isAddressOfOperand, Fn);
+
+    //   - If the argument is an overload set (not containing function
+    //     templates), trial argument deduction is attempted using each
+    //     of the members of the set. If deduction succeeds for only one
+    //     of the overload set members, that member is used as the
+    //     argument value for the deduction. If deduction succeeds for
+    //     more than one member of the overload set the parameter is
+    //     treated as a non-deduced context.
+
+    // We do all of this in a fresh context per C++0x [temp.deduct.type]p2:
+    //   Type deduction is done independently for each P/A pair, and
+    //   the deduced template argument values are then combined.
+    // So we do not reject deductions which were made elsewhere.
+    llvm::SmallVector<DeducedTemplateArgument, 8> 
+      Deduced(TemplateParams->size());
+    Sema::TemplateDeductionInfo Info(S.Context, Ovl->getNameLoc());
+    unsigned TDF = 0;
+
+    Sema::TemplateDeductionResult Result
+      = DeduceTemplateArguments(S, TemplateParams,
+                                ParamType, ArgType,
+                                Info, Deduced, TDF);
+    if (Result) continue;
+    if (!Match.isNull()) return QualType();
+    Match = ArgType;
+  }
+
+  return Match;
+}
+
+/// \brief Perform template argument deduction from a function call
+/// (C++ [temp.deduct.call]).
+///
+/// \param FunctionTemplate the function template for which we are performing
+/// template argument deduction.
+///
+/// \param ExplicitTemplateArguments the explicit template arguments provided
+/// for this call.
+///
+/// \param Args the function call arguments
+///
+/// \param NumArgs the number of arguments in Args
+///
+/// \param Name the name of the function being called. This is only significant
+/// when the function template is a conversion function template, in which
+/// case this routine will also perform template argument deduction based on
+/// the function to which 
+///
+/// \param Specialization if template argument deduction was successful,
+/// this will be set to the function template specialization produced by
+/// template argument deduction.
+///
+/// \param Info the argument will be updated to provide additional information
+/// about template argument deduction.
+///
+/// \returns the result of template argument deduction.
+Sema::TemplateDeductionResult
+Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
+                          const TemplateArgumentListInfo *ExplicitTemplateArgs,
+                              Expr **Args, unsigned NumArgs,
+                              FunctionDecl *&Specialization,
+                              TemplateDeductionInfo &Info) {
+  FunctionDecl *Function = FunctionTemplate->getTemplatedDecl();
+
+  // C++ [temp.deduct.call]p1:
+  //   Template argument deduction is done by comparing each function template
+  //   parameter type (call it P) with the type of the corresponding argument
+  //   of the call (call it A) as described below.
+  unsigned CheckArgs = NumArgs;
+  if (NumArgs < Function->getMinRequiredArguments())
+    return TDK_TooFewArguments;
+  else if (NumArgs > Function->getNumParams()) {
+    const FunctionProtoType *Proto
+      = Function->getType()->getAs<FunctionProtoType>();
+    if (!Proto->isVariadic())
+      return TDK_TooManyArguments;
+
+    CheckArgs = Function->getNumParams();
+  }
+
+  // The types of the parameters from which we will perform template argument
+  // deduction.
+  Sema::LocalInstantiationScope InstScope(*this);
+  TemplateParameterList *TemplateParams
+    = FunctionTemplate->getTemplateParameters();
+  llvm::SmallVector<DeducedTemplateArgument, 4> Deduced;
+  llvm::SmallVector<QualType, 4> ParamTypes;
+  unsigned NumExplicitlySpecified = 0;
+  if (ExplicitTemplateArgs) {
+    TemplateDeductionResult Result =
+      SubstituteExplicitTemplateArguments(FunctionTemplate,
+                                          *ExplicitTemplateArgs,
+                                          Deduced,
+                                          ParamTypes,
+                                          0,
+                                          Info);
+    if (Result)
+      return Result;
+
+    NumExplicitlySpecified = Deduced.size();
+  } else {
+    // Just fill in the parameter types from the function declaration.
+    for (unsigned I = 0; I != CheckArgs; ++I)
+      ParamTypes.push_back(Function->getParamDecl(I)->getType());
+  }
+
+  // Deduce template arguments from the function parameters.
+  Deduced.resize(TemplateParams->size());
+  for (unsigned I = 0; I != CheckArgs; ++I) {
+    QualType ParamType = ParamTypes[I];
+    QualType ArgType = Args[I]->getType();
+
+    // Overload sets usually make this parameter an undeduced
+    // context, but there are sometimes special circumstances.
+    if (ArgType == Context.OverloadTy) {
+      ArgType = ResolveOverloadForDeduction(*this, TemplateParams,
+                                            Args[I], ParamType);
+      if (ArgType.isNull())
+        continue;
+    }
+
+    // C++ [temp.deduct.call]p2:
+    //   If P is not a reference type:
+    QualType CanonParamType = Context.getCanonicalType(ParamType);
+    bool ParamWasReference = isa<ReferenceType>(CanonParamType);
+    if (!ParamWasReference) {
+      //   - If A is an array type, the pointer type produced by the
+      //     array-to-pointer standard conversion (4.2) is used in place of
+      //     A for type deduction; otherwise,
+      if (ArgType->isArrayType())
+        ArgType = Context.getArrayDecayedType(ArgType);
+      //   - If A is a function type, the pointer type produced by the
+      //     function-to-pointer standard conversion (4.3) is used in place
+      //     of A for type deduction; otherwise,
+      else if (ArgType->isFunctionType())
+        ArgType = Context.getPointerType(ArgType);
+      else {
+        // - If A is a cv-qualified type, the top level cv-qualifiers of A’s
+        //   type are ignored for type deduction.
+        QualType CanonArgType = Context.getCanonicalType(ArgType);
+        if (CanonArgType.getLocalCVRQualifiers())
+          ArgType = CanonArgType.getLocalUnqualifiedType();
+      }
+    }
+
+    // C++0x [temp.deduct.call]p3:
+    //   If P is a cv-qualified type, the top level cv-qualifiers of P’s type
+    //   are ignored for type deduction.
+    if (CanonParamType.getLocalCVRQualifiers())
+      ParamType = CanonParamType.getLocalUnqualifiedType();
+    if (const ReferenceType *ParamRefType = ParamType->getAs<ReferenceType>()) {
+      //   [...] If P is a reference type, the type referred to by P is used
+      //   for type deduction.
+      ParamType = ParamRefType->getPointeeType();
+
+      //   [...] If P is of the form T&&, where T is a template parameter, and
+      //   the argument is an lvalue, the type A& is used in place of A for
+      //   type deduction.
+      if (isa<RValueReferenceType>(ParamRefType) &&
+          ParamRefType->getAs<TemplateTypeParmType>() &&
+          Args[I]->isLvalue(Context) == Expr::LV_Valid)
+        ArgType = Context.getLValueReferenceType(ArgType);
+    }
+
+    // C++0x [temp.deduct.call]p4:
+    //   In general, the deduction process attempts to find template argument
+    //   values that will make the deduced A identical to A (after the type A
+    //   is transformed as described above). [...]
+    unsigned TDF = TDF_SkipNonDependent;
+
+    //     - If the original P is a reference type, the deduced A (i.e., the
+    //       type referred to by the reference) can be more cv-qualified than
+    //       the transformed A.
+    if (ParamWasReference)
+      TDF |= TDF_ParamWithReferenceType;
+    //     - The transformed A can be another pointer or pointer to member
+    //       type that can be converted to the deduced A via a qualification
+    //       conversion (4.4).
+    if (ArgType->isPointerType() || ArgType->isMemberPointerType())
+      TDF |= TDF_IgnoreQualifiers;
+    //     - If P is a class and P has the form simple-template-id, then the
+    //       transformed A can be a derived class of the deduced A. Likewise,
+    //       if P is a pointer to a class of the form simple-template-id, the
+    //       transformed A can be a pointer to a derived class pointed to by
+    //       the deduced A.
+    if (isSimpleTemplateIdType(ParamType) ||
+        (isa<PointerType>(ParamType) &&
+         isSimpleTemplateIdType(
+                              ParamType->getAs<PointerType>()->getPointeeType())))
+      TDF |= TDF_DerivedClass;
+
+    if (TemplateDeductionResult Result
+        = ::DeduceTemplateArguments(*this, TemplateParams,
+                                    ParamType, ArgType, Info, Deduced,
+                                    TDF))
+      return Result;
+
+    // FIXME: we need to check that the deduced A is the same as A,
+    // modulo the various allowed differences.
+  }
+
+  return FinishTemplateArgumentDeduction(FunctionTemplate, Deduced,
+                                         NumExplicitlySpecified,
+                                         Specialization, Info);
+}
+
+/// \brief Deduce template arguments when taking the address of a function
+/// template (C++ [temp.deduct.funcaddr]) or matching a specialization to
+/// a template.
+///
+/// \param FunctionTemplate the function template for which we are performing
+/// template argument deduction.
+///
+/// \param ExplicitTemplateArguments the explicitly-specified template 
+/// arguments.
+///
+/// \param ArgFunctionType the function type that will be used as the
+/// "argument" type (A) when performing template argument deduction from the
+/// function template's function type. This type may be NULL, if there is no
+/// argument type to compare against, in C++0x [temp.arg.explicit]p3.
+///
+/// \param Specialization if template argument deduction was successful,
+/// this will be set to the function template specialization produced by
+/// template argument deduction.
+///
+/// \param Info the argument will be updated to provide additional information
+/// about template argument deduction.
+///
+/// \returns the result of template argument deduction.
+Sema::TemplateDeductionResult
+Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
+                        const TemplateArgumentListInfo *ExplicitTemplateArgs,
+                              QualType ArgFunctionType,
+                              FunctionDecl *&Specialization,
+                              TemplateDeductionInfo &Info) {
+  FunctionDecl *Function = FunctionTemplate->getTemplatedDecl();
+  TemplateParameterList *TemplateParams
+    = FunctionTemplate->getTemplateParameters();
+  QualType FunctionType = Function->getType();
+
+  // Substitute any explicit template arguments.
+  Sema::LocalInstantiationScope InstScope(*this);
+  llvm::SmallVector<DeducedTemplateArgument, 4> Deduced;
+  unsigned NumExplicitlySpecified = 0;
+  llvm::SmallVector<QualType, 4> ParamTypes;
+  if (ExplicitTemplateArgs) {
+    if (TemplateDeductionResult Result
+          = SubstituteExplicitTemplateArguments(FunctionTemplate,
+                                                *ExplicitTemplateArgs,
+                                                Deduced, ParamTypes,
+                                                &FunctionType, Info))
+      return Result;
+
+    NumExplicitlySpecified = Deduced.size();
+  }
+
+  // Template argument deduction for function templates in a SFINAE context.
+  // Trap any errors that might occur.
+  SFINAETrap Trap(*this);
+
+  Deduced.resize(TemplateParams->size());
+
+  if (!ArgFunctionType.isNull()) {
+    // Deduce template arguments from the function type.
+    if (TemplateDeductionResult Result
+          = ::DeduceTemplateArguments(*this, TemplateParams,
+                                      FunctionType, ArgFunctionType, Info,
+                                      Deduced, 0))
+      return Result;
+  }
+  
+  return FinishTemplateArgumentDeduction(FunctionTemplate, Deduced,
+                                         NumExplicitlySpecified,
+                                         Specialization, Info);
+}
+
+/// \brief Deduce template arguments for a templated conversion
+/// function (C++ [temp.deduct.conv]) and, if successful, produce a
+/// conversion function template specialization.
+Sema::TemplateDeductionResult
+Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
+                              QualType ToType,
+                              CXXConversionDecl *&Specialization,
+                              TemplateDeductionInfo &Info) {
+  CXXConversionDecl *Conv
+    = cast<CXXConversionDecl>(FunctionTemplate->getTemplatedDecl());
+  QualType FromType = Conv->getConversionType();
+
+  // Canonicalize the types for deduction.
+  QualType P = Context.getCanonicalType(FromType);
+  QualType A = Context.getCanonicalType(ToType);
+
+  // C++0x [temp.deduct.conv]p3:
+  //   If P is a reference type, the type referred to by P is used for
+  //   type deduction.
+  if (const ReferenceType *PRef = P->getAs<ReferenceType>())
+    P = PRef->getPointeeType();
+
+  // C++0x [temp.deduct.conv]p3:
+  //   If A is a reference type, the type referred to by A is used
+  //   for type deduction.
+  if (const ReferenceType *ARef = A->getAs<ReferenceType>())
+    A = ARef->getPointeeType();
+  // C++ [temp.deduct.conv]p2:
+  //
+  //   If A is not a reference type:
+  else {
+    assert(!A->isReferenceType() && "Reference types were handled above");
+
+    //   - If P is an array type, the pointer type produced by the
+    //     array-to-pointer standard conversion (4.2) is used in place
+    //     of P for type deduction; otherwise,
+    if (P->isArrayType())
+      P = Context.getArrayDecayedType(P);
+    //   - If P is a function type, the pointer type produced by the
+    //     function-to-pointer standard conversion (4.3) is used in
+    //     place of P for type deduction; otherwise,
+    else if (P->isFunctionType())
+      P = Context.getPointerType(P);
+    //   - If P is a cv-qualified type, the top level cv-qualifiers of
+    //     P’s type are ignored for type deduction.
+    else
+      P = P.getUnqualifiedType();
+
+    // C++0x [temp.deduct.conv]p3:
+    //   If A is a cv-qualified type, the top level cv-qualifiers of A’s
+    //   type are ignored for type deduction.
+    A = A.getUnqualifiedType();
+  }
+
+  // Template argument deduction for function templates in a SFINAE context.
+  // Trap any errors that might occur.
+  SFINAETrap Trap(*this);
+
+  // C++ [temp.deduct.conv]p1:
+  //   Template argument deduction is done by comparing the return
+  //   type of the template conversion function (call it P) with the
+  //   type that is required as the result of the conversion (call it
+  //   A) as described in 14.8.2.4.
+  TemplateParameterList *TemplateParams
+    = FunctionTemplate->getTemplateParameters();
+  llvm::SmallVector<DeducedTemplateArgument, 4> Deduced;
+  Deduced.resize(TemplateParams->size());
+
+  // C++0x [temp.deduct.conv]p4:
+  //   In general, the deduction process attempts to find template
+  //   argument values that will make the deduced A identical to
+  //   A. However, there are two cases that allow a difference:
+  unsigned TDF = 0;
+  //     - If the original A is a reference type, A can be more
+  //       cv-qualified than the deduced A (i.e., the type referred to
+  //       by the reference)
+  if (ToType->isReferenceType())
+    TDF |= TDF_ParamWithReferenceType;
+  //     - The deduced A can be another pointer or pointer to member
+  //       type that can be converted to A via a qualification
+  //       conversion.
+  //
+  // (C++0x [temp.deduct.conv]p6 clarifies that this only happens when
+  // both P and A are pointers or member pointers. In this case, we
+  // just ignore cv-qualifiers completely).
+  if ((P->isPointerType() && A->isPointerType()) ||
+      (P->isMemberPointerType() && P->isMemberPointerType()))
+    TDF |= TDF_IgnoreQualifiers;
+  if (TemplateDeductionResult Result
+        = ::DeduceTemplateArguments(*this, TemplateParams,
+                                    P, A, Info, Deduced, TDF))
+    return Result;
+
+  // FIXME: we need to check that the deduced A is the same as A,
+  // modulo the various allowed differences.
+
+  // Finish template argument deduction.
+  Sema::LocalInstantiationScope InstScope(*this);
+  FunctionDecl *Spec = 0;
+  TemplateDeductionResult Result
+    = FinishTemplateArgumentDeduction(FunctionTemplate, Deduced, 0, Spec, 
+                                      Info);
+  Specialization = cast_or_null<CXXConversionDecl>(Spec);
+  return Result;
+}
+
+/// \brief Deduce template arguments for a function template when there is
+/// nothing to deduce against (C++0x [temp.arg.explicit]p3).
+///
+/// \param FunctionTemplate the function template for which we are performing
+/// template argument deduction.
+///
+/// \param ExplicitTemplateArguments the explicitly-specified template 
+/// arguments.
+///
+/// \param Specialization if template argument deduction was successful,
+/// this will be set to the function template specialization produced by
+/// template argument deduction.
+///
+/// \param Info the argument will be updated to provide additional information
+/// about template argument deduction.
+///
+/// \returns the result of template argument deduction.
+Sema::TemplateDeductionResult
+Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
+                           const TemplateArgumentListInfo *ExplicitTemplateArgs,
+                              FunctionDecl *&Specialization,
+                              TemplateDeductionInfo &Info) {
+  return DeduceTemplateArguments(FunctionTemplate, ExplicitTemplateArgs,
+                                 QualType(), Specialization, Info);
+}
+
+/// \brief Stores the result of comparing the qualifiers of two types.
+enum DeductionQualifierComparison { 
+  NeitherMoreQualified = 0, 
+  ParamMoreQualified, 
+  ArgMoreQualified 
+};
+
+/// \brief Deduce the template arguments during partial ordering by comparing 
+/// the parameter type and the argument type (C++0x [temp.deduct.partial]).
+///
+/// \param S the semantic analysis object within which we are deducing
+///
+/// \param TemplateParams the template parameters that we are deducing
+///
+/// \param ParamIn the parameter type
+///
+/// \param ArgIn the argument type
+///
+/// \param Info information about the template argument deduction itself
+///
+/// \param Deduced the deduced template arguments
+///
+/// \returns the result of template argument deduction so far. Note that a
+/// "success" result means that template argument deduction has not yet failed,
+/// but it may still fail, later, for other reasons.
+static Sema::TemplateDeductionResult
+DeduceTemplateArgumentsDuringPartialOrdering(Sema &S,
+                                        TemplateParameterList *TemplateParams,
+                                             QualType ParamIn, QualType ArgIn,
+                                             Sema::TemplateDeductionInfo &Info,
+                      llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced,
+   llvm::SmallVectorImpl<DeductionQualifierComparison> *QualifierComparisons) {
+  CanQualType Param = S.Context.getCanonicalType(ParamIn);
+  CanQualType Arg = S.Context.getCanonicalType(ArgIn);
+
+  // C++0x [temp.deduct.partial]p5:
+  //   Before the partial ordering is done, certain transformations are 
+  //   performed on the types used for partial ordering: 
+  //     - If P is a reference type, P is replaced by the type referred to. 
+  CanQual<ReferenceType> ParamRef = Param->getAs<ReferenceType>();
+  if (!ParamRef.isNull())
+    Param = ParamRef->getPointeeType();
+  
+  //     - If A is a reference type, A is replaced by the type referred to.
+  CanQual<ReferenceType> ArgRef = Arg->getAs<ReferenceType>();
+  if (!ArgRef.isNull())
+    Arg = ArgRef->getPointeeType();
+  
+  if (QualifierComparisons && !ParamRef.isNull() && !ArgRef.isNull()) {
+    // C++0x [temp.deduct.partial]p6:
+    //   If both P and A were reference types (before being replaced with the 
+    //   type referred to above), determine which of the two types (if any) is 
+    //   more cv-qualified than the other; otherwise the types are considered to 
+    //   be equally cv-qualified for partial ordering purposes. The result of this
+    //   determination will be used below.
+    //
+    // We save this information for later, using it only when deduction 
+    // succeeds in both directions.
+    DeductionQualifierComparison QualifierResult = NeitherMoreQualified;
+    if (Param.isMoreQualifiedThan(Arg))
+      QualifierResult = ParamMoreQualified;
+    else if (Arg.isMoreQualifiedThan(Param))
+      QualifierResult = ArgMoreQualified;
+    QualifierComparisons->push_back(QualifierResult);
+  }
+  
+  // C++0x [temp.deduct.partial]p7:
+  //   Remove any top-level cv-qualifiers:
+  //     - If P is a cv-qualified type, P is replaced by the cv-unqualified 
+  //       version of P.
+  Param = Param.getUnqualifiedType();
+  //     - If A is a cv-qualified type, A is replaced by the cv-unqualified 
+  //       version of A.
+  Arg = Arg.getUnqualifiedType();
+  
+  // C++0x [temp.deduct.partial]p8:
+  //   Using the resulting types P and A the deduction is then done as 
+  //   described in 14.9.2.5. If deduction succeeds for a given type, the type
+  //   from the argument template is considered to be at least as specialized
+  //   as the type from the parameter template.
+  return DeduceTemplateArguments(S, TemplateParams, Param, Arg, Info,
+                                 Deduced, TDF_None);
+}
+
+static void
+MarkUsedTemplateParameters(Sema &SemaRef, QualType T,
+                           bool OnlyDeduced,
+                           unsigned Level,
+                           llvm::SmallVectorImpl<bool> &Deduced);
+  
+/// \brief Determine whether the function template \p FT1 is at least as
+/// specialized as \p FT2.
+static bool isAtLeastAsSpecializedAs(Sema &S,
+                                     SourceLocation Loc,
+                                     FunctionTemplateDecl *FT1,
+                                     FunctionTemplateDecl *FT2,
+                                     TemplatePartialOrderingContext TPOC,
+    llvm::SmallVectorImpl<DeductionQualifierComparison> *QualifierComparisons) {
+  FunctionDecl *FD1 = FT1->getTemplatedDecl();
+  FunctionDecl *FD2 = FT2->getTemplatedDecl();  
+  const FunctionProtoType *Proto1 = FD1->getType()->getAs<FunctionProtoType>();
+  const FunctionProtoType *Proto2 = FD2->getType()->getAs<FunctionProtoType>();
+  
+  assert(Proto1 && Proto2 && "Function templates must have prototypes");
+  TemplateParameterList *TemplateParams = FT2->getTemplateParameters();
+  llvm::SmallVector<DeducedTemplateArgument, 4> Deduced;
+  Deduced.resize(TemplateParams->size());
+
+  // C++0x [temp.deduct.partial]p3:
+  //   The types used to determine the ordering depend on the context in which
+  //   the partial ordering is done:
+  Sema::TemplateDeductionInfo Info(S.Context, Loc);
+  switch (TPOC) {
+  case TPOC_Call: {
+    //   - In the context of a function call, the function parameter types are
+    //     used.
+    unsigned NumParams = std::min(Proto1->getNumArgs(), Proto2->getNumArgs());
+    for (unsigned I = 0; I != NumParams; ++I)
+      if (DeduceTemplateArgumentsDuringPartialOrdering(S,
+                                                       TemplateParams,
+                                                       Proto2->getArgType(I),
+                                                       Proto1->getArgType(I),
+                                                       Info,
+                                                       Deduced,
+                                                       QualifierComparisons))
+        return false;
+    
+    break;
+  }
+    
+  case TPOC_Conversion:
+    //   - In the context of a call to a conversion operator, the return types
+    //     of the conversion function templates are used.
+    if (DeduceTemplateArgumentsDuringPartialOrdering(S,
+                                                     TemplateParams,
+                                                     Proto2->getResultType(),
+                                                     Proto1->getResultType(),
+                                                     Info,
+                                                     Deduced,
+                                                     QualifierComparisons))
+      return false;
+    break;
+    
+  case TPOC_Other:
+    //   - In other contexts (14.6.6.2) the function template’s function type 
+    //     is used.
+    if (DeduceTemplateArgumentsDuringPartialOrdering(S,
+                                                     TemplateParams,
+                                                     FD2->getType(),
+                                                     FD1->getType(),
+                                                     Info,
+                                                     Deduced,
+                                                     QualifierComparisons))
+      return false;
+    break;
+  }
+  
+  // C++0x [temp.deduct.partial]p11:
+  //   In most cases, all template parameters must have values in order for 
+  //   deduction to succeed, but for partial ordering purposes a template 
+  //   parameter may remain without a value provided it is not used in the 
+  //   types being used for partial ordering. [ Note: a template parameter used
+  //   in a non-deduced context is considered used. -end note]
+  unsigned ArgIdx = 0, NumArgs = Deduced.size();
+  for (; ArgIdx != NumArgs; ++ArgIdx)
+    if (Deduced[ArgIdx].isNull())
+      break;
+
+  if (ArgIdx == NumArgs) {
+    // All template arguments were deduced. FT1 is at least as specialized 
+    // as FT2.
+    return true;
+  }
+
+  // Figure out which template parameters were used.
+  llvm::SmallVector<bool, 4> UsedParameters;
+  UsedParameters.resize(TemplateParams->size());
+  switch (TPOC) {
+  case TPOC_Call: {
+    unsigned NumParams = std::min(Proto1->getNumArgs(), Proto2->getNumArgs());
+    for (unsigned I = 0; I != NumParams; ++I)
+      ::MarkUsedTemplateParameters(S, Proto2->getArgType(I), false, 
+                                   TemplateParams->getDepth(),
+                                   UsedParameters);
+    break;
+  }
+    
+  case TPOC_Conversion:
+    ::MarkUsedTemplateParameters(S, Proto2->getResultType(), false, 
+                                 TemplateParams->getDepth(),
+                                 UsedParameters);
+    break;
+    
+  case TPOC_Other:
+    ::MarkUsedTemplateParameters(S, FD2->getType(), false, 
+                                 TemplateParams->getDepth(),
+                                 UsedParameters);
+    break;
+  }
+  
+  for (; ArgIdx != NumArgs; ++ArgIdx)
+    // If this argument had no value deduced but was used in one of the types
+    // used for partial ordering, then deduction fails.
+    if (Deduced[ArgIdx].isNull() && UsedParameters[ArgIdx])
+      return false;
+  
+  return true;
+}
+                                    
+                                     
+/// \brief Returns the more specialized function template according
+/// to the rules of function template partial ordering (C++ [temp.func.order]).
+///
+/// \param FT1 the first function template
+///
+/// \param FT2 the second function template
+///
+/// \param TPOC the context in which we are performing partial ordering of
+/// function templates.
+///
+/// \returns the more specialized function template. If neither
+/// template is more specialized, returns NULL.
+FunctionTemplateDecl *
+Sema::getMoreSpecializedTemplate(FunctionTemplateDecl *FT1,
+                                 FunctionTemplateDecl *FT2,
+                                 SourceLocation Loc,
+                                 TemplatePartialOrderingContext TPOC) {
+  llvm::SmallVector<DeductionQualifierComparison, 4> QualifierComparisons;
+  bool Better1 = isAtLeastAsSpecializedAs(*this, Loc, FT1, FT2, TPOC, 0);
+  bool Better2 = isAtLeastAsSpecializedAs(*this, Loc, FT2, FT1, TPOC, 
+                                          &QualifierComparisons);
+  
+  if (Better1 != Better2) // We have a clear winner
+    return Better1? FT1 : FT2;
+  
+  if (!Better1 && !Better2) // Neither is better than the other
+    return 0;
+
+
+  // C++0x [temp.deduct.partial]p10:
+  //   If for each type being considered a given template is at least as 
+  //   specialized for all types and more specialized for some set of types and
+  //   the other template is not more specialized for any types or is not at 
+  //   least as specialized for any types, then the given template is more
+  //   specialized than the other template. Otherwise, neither template is more
+  //   specialized than the other.
+  Better1 = false;
+  Better2 = false;
+  for (unsigned I = 0, N = QualifierComparisons.size(); I != N; ++I) {
+    // C++0x [temp.deduct.partial]p9:
+    //   If, for a given type, deduction succeeds in both directions (i.e., the
+    //   types are identical after the transformations above) and if the type
+    //   from the argument template is more cv-qualified than the type from the
+    //   parameter template (as described above) that type is considered to be
+    //   more specialized than the other. If neither type is more cv-qualified 
+    //   than the other then neither type is more specialized than the other.
+    switch (QualifierComparisons[I]) {
+      case NeitherMoreQualified:
+        break;
+        
+      case ParamMoreQualified:
+        Better1 = true;
+        if (Better2)
+          return 0;
+        break;
+        
+      case ArgMoreQualified:
+        Better2 = true;
+        if (Better1)
+          return 0;
+        break;
+    }
+  }
+   
+  assert(!(Better1 && Better2) && "Should have broken out in the loop above");
+  if (Better1)
+    return FT1;
+  else if (Better2)
+    return FT2;
+  else
+    return 0;
+}
+
+/// \brief Determine if the two templates are equivalent.
+static bool isSameTemplate(TemplateDecl *T1, TemplateDecl *T2) {
+  if (T1 == T2)
+    return true;
+  
+  if (!T1 || !T2)
+    return false;
+  
+  return T1->getCanonicalDecl() == T2->getCanonicalDecl();
+}
+
+/// \brief Retrieve the most specialized of the given function template
+/// specializations.
+///
+/// \param SpecBegin the start iterator of the function template
+/// specializations that we will be comparing.
+///
+/// \param SpecEnd the end iterator of the function template
+/// specializations, paired with \p SpecBegin.
+///
+/// \param TPOC the partial ordering context to use to compare the function
+/// template specializations.
+///
+/// \param Loc the location where the ambiguity or no-specializations 
+/// diagnostic should occur.
+///
+/// \param NoneDiag partial diagnostic used to diagnose cases where there are
+/// no matching candidates.
+///
+/// \param AmbigDiag partial diagnostic used to diagnose an ambiguity, if one
+/// occurs.
+///
+/// \param CandidateDiag partial diagnostic used for each function template
+/// specialization that is a candidate in the ambiguous ordering. One parameter
+/// in this diagnostic should be unbound, which will correspond to the string
+/// describing the template arguments for the function template specialization.
+///
+/// \param Index if non-NULL and the result of this function is non-nULL, 
+/// receives the index corresponding to the resulting function template
+/// specialization.
+///
+/// \returns the most specialized function template specialization, if 
+/// found. Otherwise, returns SpecEnd.
+///
+/// \todo FIXME: Consider passing in the "also-ran" candidates that failed 
+/// template argument deduction.
+UnresolvedSetIterator
+Sema::getMostSpecialized(UnresolvedSetIterator SpecBegin,
+                         UnresolvedSetIterator SpecEnd,
+                         TemplatePartialOrderingContext TPOC,
+                         SourceLocation Loc,
+                         const PartialDiagnostic &NoneDiag,
+                         const PartialDiagnostic &AmbigDiag,
+                         const PartialDiagnostic &CandidateDiag) {
+  if (SpecBegin == SpecEnd) {
+    Diag(Loc, NoneDiag);
+    return SpecEnd;
+  }
+  
+  if (SpecBegin + 1 == SpecEnd)    
+    return SpecBegin;
+  
+  // Find the function template that is better than all of the templates it
+  // has been compared to.
+  UnresolvedSetIterator Best = SpecBegin;
+  FunctionTemplateDecl *BestTemplate 
+    = cast<FunctionDecl>(*Best)->getPrimaryTemplate();
+  assert(BestTemplate && "Not a function template specialization?");
+  for (UnresolvedSetIterator I = SpecBegin + 1; I != SpecEnd; ++I) {
+    FunctionTemplateDecl *Challenger
+      = cast<FunctionDecl>(*I)->getPrimaryTemplate();
+    assert(Challenger && "Not a function template specialization?");
+    if (isSameTemplate(getMoreSpecializedTemplate(BestTemplate, Challenger,
+                                                  Loc, TPOC),
+                       Challenger)) {
+      Best = I;
+      BestTemplate = Challenger;
+    }
+  }
+  
+  // Make sure that the "best" function template is more specialized than all
+  // of the others.
+  bool Ambiguous = false;
+  for (UnresolvedSetIterator I = SpecBegin; I != SpecEnd; ++I) {
+    FunctionTemplateDecl *Challenger
+      = cast<FunctionDecl>(*I)->getPrimaryTemplate();
+    if (I != Best &&
+        !isSameTemplate(getMoreSpecializedTemplate(BestTemplate, Challenger, 
+                                                   Loc, TPOC),
+                        BestTemplate)) {
+      Ambiguous = true;
+      break;
+    }
+  }
+  
+  if (!Ambiguous) {
+    // We found an answer. Return it.
+    return Best;
+  }
+  
+  // Diagnose the ambiguity.
+  Diag(Loc, AmbigDiag);
+  
+  // FIXME: Can we order the candidates in some sane way?
+  for (UnresolvedSetIterator I = SpecBegin; I != SpecEnd; ++I)
+    Diag((*I)->getLocation(), CandidateDiag)
+      << getTemplateArgumentBindingsText(
+        cast<FunctionDecl>(*I)->getPrimaryTemplate()->getTemplateParameters(),
+                    *cast<FunctionDecl>(*I)->getTemplateSpecializationArgs());
+  
+  return SpecEnd;
+}
+
+/// \brief Returns the more specialized class template partial specialization
+/// according to the rules of partial ordering of class template partial
+/// specializations (C++ [temp.class.order]).
+///
+/// \param PS1 the first class template partial specialization
+///
+/// \param PS2 the second class template partial specialization
+///
+/// \returns the more specialized class template partial specialization. If
+/// neither partial specialization is more specialized, returns NULL.
+ClassTemplatePartialSpecializationDecl *
+Sema::getMoreSpecializedPartialSpecialization(
+                                  ClassTemplatePartialSpecializationDecl *PS1,
+                                  ClassTemplatePartialSpecializationDecl *PS2,
+                                              SourceLocation Loc) {
+  // C++ [temp.class.order]p1:
+  //   For two class template partial specializations, the first is at least as
+  //   specialized as the second if, given the following rewrite to two 
+  //   function templates, the first function template is at least as 
+  //   specialized as the second according to the ordering rules for function 
+  //   templates (14.6.6.2):
+  //     - the first function template has the same template parameters as the
+  //       first partial specialization and has a single function parameter 
+  //       whose type is a class template specialization with the template 
+  //       arguments of the first partial specialization, and
+  //     - the second function template has the same template parameters as the
+  //       second partial specialization and has a single function parameter 
+  //       whose type is a class template specialization with the template 
+  //       arguments of the second partial specialization.
+  //
+  // Rather than synthesize function templates, we merely perform the 
+  // equivalent partial ordering by performing deduction directly on the
+  // template arguments of the class template partial specializations. This
+  // computation is slightly simpler than the general problem of function
+  // template partial ordering, because class template partial specializations
+  // are more constrained. We know that every template parameter is deduc
+  llvm::SmallVector<DeducedTemplateArgument, 4> Deduced;
+  Sema::TemplateDeductionInfo Info(Context, Loc);
+
+  QualType PT1 = PS1->getInjectedSpecializationType();
+  QualType PT2 = PS2->getInjectedSpecializationType();
+  
+  // Determine whether PS1 is at least as specialized as PS2
+  Deduced.resize(PS2->getTemplateParameters()->size());
+  bool Better1 = !DeduceTemplateArgumentsDuringPartialOrdering(*this,
+                                                  PS2->getTemplateParameters(),
+                                                               PT2,
+                                                               PT1,
+                                                               Info,
+                                                               Deduced,
+                                                               0);
+
+  // Determine whether PS2 is at least as specialized as PS1
+  Deduced.clear();
+  Deduced.resize(PS1->getTemplateParameters()->size());
+  bool Better2 = !DeduceTemplateArgumentsDuringPartialOrdering(*this,
+                                                  PS1->getTemplateParameters(),
+                                                               PT1,
+                                                               PT2,
+                                                               Info,
+                                                               Deduced,
+                                                               0);
+  
+  if (Better1 == Better2)
+    return 0;
+  
+  return Better1? PS1 : PS2;
+}
+
+static void
+MarkUsedTemplateParameters(Sema &SemaRef,
+                           const TemplateArgument &TemplateArg,
+                           bool OnlyDeduced,
+                           unsigned Depth,
+                           llvm::SmallVectorImpl<bool> &Used);
+
+/// \brief Mark the template parameters that are used by the given
+/// expression.
+static void
+MarkUsedTemplateParameters(Sema &SemaRef,
+                           const Expr *E,
+                           bool OnlyDeduced,
+                           unsigned Depth,
+                           llvm::SmallVectorImpl<bool> &Used) {
+  // FIXME: if !OnlyDeduced, we have to walk the whole subexpression to 
+  // find other occurrences of template parameters.
+  const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E);
+  if (!DRE)
+    return;
+
+  const NonTypeTemplateParmDecl *NTTP
+    = dyn_cast<NonTypeTemplateParmDecl>(DRE->getDecl());
+  if (!NTTP)
+    return;
+
+  if (NTTP->getDepth() == Depth)
+    Used[NTTP->getIndex()] = true;
+}
+
+/// \brief Mark the template parameters that are used by the given
+/// nested name specifier.
+static void
+MarkUsedTemplateParameters(Sema &SemaRef,
+                           NestedNameSpecifier *NNS,
+                           bool OnlyDeduced,
+                           unsigned Depth,
+                           llvm::SmallVectorImpl<bool> &Used) {
+  if (!NNS)
+    return;
+  
+  MarkUsedTemplateParameters(SemaRef, NNS->getPrefix(), OnlyDeduced, Depth,
+                             Used);
+  MarkUsedTemplateParameters(SemaRef, QualType(NNS->getAsType(), 0), 
+                             OnlyDeduced, Depth, Used);
+}
+  
+/// \brief Mark the template parameters that are used by the given
+/// template name.
+static void
+MarkUsedTemplateParameters(Sema &SemaRef,
+                           TemplateName Name,
+                           bool OnlyDeduced,
+                           unsigned Depth,
+                           llvm::SmallVectorImpl<bool> &Used) {
+  if (TemplateDecl *Template = Name.getAsTemplateDecl()) {
+    if (TemplateTemplateParmDecl *TTP
+          = dyn_cast<TemplateTemplateParmDecl>(Template)) {
+      if (TTP->getDepth() == Depth)
+        Used[TTP->getIndex()] = true;
+    }
+    return;
+  }
+  
+  if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName())
+    MarkUsedTemplateParameters(SemaRef, QTN->getQualifier(), OnlyDeduced, 
+                               Depth, Used);
+  if (DependentTemplateName *DTN = Name.getAsDependentTemplateName())
+    MarkUsedTemplateParameters(SemaRef, DTN->getQualifier(), OnlyDeduced, 
+                               Depth, Used);
+}
+
+/// \brief Mark the template parameters that are used by the given
+/// type.
+static void
+MarkUsedTemplateParameters(Sema &SemaRef, QualType T,
+                           bool OnlyDeduced,
+                           unsigned Depth,
+                           llvm::SmallVectorImpl<bool> &Used) {
+  if (T.isNull())
+    return;
+  
+  // Non-dependent types have nothing deducible
+  if (!T->isDependentType())
+    return;
+
+  T = SemaRef.Context.getCanonicalType(T);
+  switch (T->getTypeClass()) {
+  case Type::Pointer:
+    MarkUsedTemplateParameters(SemaRef,
+                               cast<PointerType>(T)->getPointeeType(),
+                               OnlyDeduced,
+                               Depth,
+                               Used);
+    break;
+
+  case Type::BlockPointer:
+    MarkUsedTemplateParameters(SemaRef,
+                               cast<BlockPointerType>(T)->getPointeeType(),
+                               OnlyDeduced,
+                               Depth,
+                               Used);
+    break;
+
+  case Type::LValueReference:
+  case Type::RValueReference:
+    MarkUsedTemplateParameters(SemaRef,
+                               cast<ReferenceType>(T)->getPointeeType(),
+                               OnlyDeduced,
+                               Depth,
+                               Used);
+    break;
+
+  case Type::MemberPointer: {
+    const MemberPointerType *MemPtr = cast<MemberPointerType>(T.getTypePtr());
+    MarkUsedTemplateParameters(SemaRef, MemPtr->getPointeeType(), OnlyDeduced,
+                               Depth, Used);
+    MarkUsedTemplateParameters(SemaRef, QualType(MemPtr->getClass(), 0),
+                               OnlyDeduced, Depth, Used);
+    break;
+  }
+
+  case Type::DependentSizedArray:
+    MarkUsedTemplateParameters(SemaRef,
+                               cast<DependentSizedArrayType>(T)->getSizeExpr(),
+                               OnlyDeduced, Depth, Used);
+    // Fall through to check the element type
+
+  case Type::ConstantArray:
+  case Type::IncompleteArray:
+    MarkUsedTemplateParameters(SemaRef,
+                               cast<ArrayType>(T)->getElementType(),
+                               OnlyDeduced, Depth, Used);
+    break;
+
+  case Type::Vector:
+  case Type::ExtVector:
+    MarkUsedTemplateParameters(SemaRef,
+                               cast<VectorType>(T)->getElementType(),
+                               OnlyDeduced, Depth, Used);
+    break;
+
+  case Type::DependentSizedExtVector: {
+    const DependentSizedExtVectorType *VecType
+      = cast<DependentSizedExtVectorType>(T);
+    MarkUsedTemplateParameters(SemaRef, VecType->getElementType(), OnlyDeduced,
+                               Depth, Used);
+    MarkUsedTemplateParameters(SemaRef, VecType->getSizeExpr(), OnlyDeduced, 
+                               Depth, Used);
+    break;
+  }
+
+  case Type::FunctionProto: {
+    const FunctionProtoType *Proto = cast<FunctionProtoType>(T);
+    MarkUsedTemplateParameters(SemaRef, Proto->getResultType(), OnlyDeduced,
+                               Depth, Used);
+    for (unsigned I = 0, N = Proto->getNumArgs(); I != N; ++I)
+      MarkUsedTemplateParameters(SemaRef, Proto->getArgType(I), OnlyDeduced,
+                                 Depth, Used);
+    break;
+  }
+
+  case Type::TemplateTypeParm: {
+    const TemplateTypeParmType *TTP = cast<TemplateTypeParmType>(T);
+    if (TTP->getDepth() == Depth)
+      Used[TTP->getIndex()] = true;
+    break;
+  }
+
+  case Type::InjectedClassName:
+    T = cast<InjectedClassNameType>(T)->getInjectedSpecializationType();
+    // fall through
+
+  case Type::TemplateSpecialization: {
+    const TemplateSpecializationType *Spec
+      = cast<TemplateSpecializationType>(T);
+    MarkUsedTemplateParameters(SemaRef, Spec->getTemplateName(), OnlyDeduced,
+                               Depth, Used);
+    for (unsigned I = 0, N = Spec->getNumArgs(); I != N; ++I)
+      MarkUsedTemplateParameters(SemaRef, Spec->getArg(I), OnlyDeduced, Depth,
+                                 Used);
+    break;
+  }
+
+  case Type::Complex:
+    if (!OnlyDeduced)
+      MarkUsedTemplateParameters(SemaRef, 
+                                 cast<ComplexType>(T)->getElementType(),
+                                 OnlyDeduced, Depth, Used);
+    break;
+
+  case Type::DependentName:
+    if (!OnlyDeduced)
+      MarkUsedTemplateParameters(SemaRef,
+                                 cast<DependentNameType>(T)->getQualifier(),
+                                 OnlyDeduced, Depth, Used);
+    break;
+
+  case Type::TypeOf:
+    if (!OnlyDeduced)
+      MarkUsedTemplateParameters(SemaRef,
+                                 cast<TypeOfType>(T)->getUnderlyingType(),
+                                 OnlyDeduced, Depth, Used);
+    break;
+
+  case Type::TypeOfExpr:
+    if (!OnlyDeduced)
+      MarkUsedTemplateParameters(SemaRef,
+                                 cast<TypeOfExprType>(T)->getUnderlyingExpr(),
+                                 OnlyDeduced, Depth, Used);
+    break;
+
+  case Type::Decltype:
+    if (!OnlyDeduced)
+      MarkUsedTemplateParameters(SemaRef,
+                                 cast<DecltypeType>(T)->getUnderlyingExpr(),
+                                 OnlyDeduced, Depth, Used);
+    break;
+
+  // None of these types have any template parameters in them.
+  case Type::Builtin:
+  case Type::VariableArray:
+  case Type::FunctionNoProto:
+  case Type::Record:
+  case Type::Enum:
+  case Type::ObjCInterface:
+  case Type::ObjCObjectPointer:
+  case Type::UnresolvedUsing:
+#define TYPE(Class, Base)
+#define ABSTRACT_TYPE(Class, Base)
+#define DEPENDENT_TYPE(Class, Base)
+#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
+#include "clang/AST/TypeNodes.def"
+    break;
+  }
+}
+
+/// \brief Mark the template parameters that are used by this
+/// template argument.
+static void
+MarkUsedTemplateParameters(Sema &SemaRef,
+                           const TemplateArgument &TemplateArg,
+                           bool OnlyDeduced,
+                           unsigned Depth,
+                           llvm::SmallVectorImpl<bool> &Used) {
+  switch (TemplateArg.getKind()) {
+  case TemplateArgument::Null:
+  case TemplateArgument::Integral:
+    case TemplateArgument::Declaration:
+    break;
+
+  case TemplateArgument::Type:
+    MarkUsedTemplateParameters(SemaRef, TemplateArg.getAsType(), OnlyDeduced,
+                               Depth, Used);
+    break;
+
+  case TemplateArgument::Template:
+    MarkUsedTemplateParameters(SemaRef, TemplateArg.getAsTemplate(), 
+                               OnlyDeduced, Depth, Used);
+    break;
+
+  case TemplateArgument::Expression:
+    MarkUsedTemplateParameters(SemaRef, TemplateArg.getAsExpr(), OnlyDeduced, 
+                               Depth, Used);
+    break;
+      
+  case TemplateArgument::Pack:
+    for (TemplateArgument::pack_iterator P = TemplateArg.pack_begin(),
+                                      PEnd = TemplateArg.pack_end();
+         P != PEnd; ++P)
+      MarkUsedTemplateParameters(SemaRef, *P, OnlyDeduced, Depth, Used);
+    break;
+  }
+}
+
+/// \brief Mark the template parameters can be deduced by the given
+/// template argument list.
+///
+/// \param TemplateArgs the template argument list from which template
+/// parameters will be deduced.
+///
+/// \param Deduced a bit vector whose elements will be set to \c true
+/// to indicate when the corresponding template parameter will be
+/// deduced.
+void
+Sema::MarkUsedTemplateParameters(const TemplateArgumentList &TemplateArgs,
+                                 bool OnlyDeduced, unsigned Depth,
+                                 llvm::SmallVectorImpl<bool> &Used) {
+  for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
+    ::MarkUsedTemplateParameters(*this, TemplateArgs[I], OnlyDeduced, 
+                                 Depth, Used);
+}
+
+/// \brief Marks all of the template parameters that will be deduced by a
+/// call to the given function template.
+void 
+Sema::MarkDeducedTemplateParameters(FunctionTemplateDecl *FunctionTemplate,
+                                    llvm::SmallVectorImpl<bool> &Deduced) {
+  TemplateParameterList *TemplateParams 
+    = FunctionTemplate->getTemplateParameters();
+  Deduced.clear();
+  Deduced.resize(TemplateParams->size());
+  
+  FunctionDecl *Function = FunctionTemplate->getTemplatedDecl();
+  for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I)
+    ::MarkUsedTemplateParameters(*this, Function->getParamDecl(I)->getType(),
+                                 true, TemplateParams->getDepth(), Deduced);
+}
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp
new file mode 100644
index 0000000..6fdf243
--- /dev/null
+++ b/lib/Sema/SemaTemplateInstantiate.cpp
@@ -0,0 +1,1604 @@
+//===------- SemaTemplateInstantiate.cpp - C++ Template Instantiation ------===/
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//===----------------------------------------------------------------------===/
+//
+//  This file implements C++ template instantiation.
+//
+//===----------------------------------------------------------------------===/
+
+#include "Sema.h"
+#include "TreeTransform.h"
+#include "Lookup.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/Parse/DeclSpec.h"
+#include "clang/Basic/LangOptions.h"
+
+using namespace clang;
+
+//===----------------------------------------------------------------------===/
+// Template Instantiation Support
+//===----------------------------------------------------------------------===/
+
+/// \brief Retrieve the template argument list(s) that should be used to
+/// instantiate the definition of the given declaration.
+///
+/// \param D the declaration for which we are computing template instantiation
+/// arguments.
+///
+/// \param Innermost if non-NULL, the innermost template argument list.
+///
+/// \param RelativeToPrimary true if we should get the template
+/// arguments relative to the primary template, even when we're
+/// dealing with a specialization. This is only relevant for function
+/// template specializations.
+MultiLevelTemplateArgumentList
+Sema::getTemplateInstantiationArgs(NamedDecl *D, 
+                                   const TemplateArgumentList *Innermost,
+                                   bool RelativeToPrimary) {
+  // Accumulate the set of template argument lists in this structure.
+  MultiLevelTemplateArgumentList Result;
+
+  if (Innermost)
+    Result.addOuterTemplateArguments(Innermost);
+  
+  DeclContext *Ctx = dyn_cast<DeclContext>(D);
+  if (!Ctx)
+    Ctx = D->getDeclContext();
+
+  while (!Ctx->isFileContext()) {
+    // Add template arguments from a class template instantiation.
+    if (ClassTemplateSpecializationDecl *Spec
+          = dyn_cast<ClassTemplateSpecializationDecl>(Ctx)) {
+      // We're done when we hit an explicit specialization.
+      if (Spec->getSpecializationKind() == TSK_ExplicitSpecialization)
+        break;
+
+      Result.addOuterTemplateArguments(&Spec->getTemplateInstantiationArgs());
+      
+      // If this class template specialization was instantiated from a 
+      // specialized member that is a class template, we're done.
+      assert(Spec->getSpecializedTemplate() && "No class template?");
+      if (Spec->getSpecializedTemplate()->isMemberSpecialization())
+        break;
+    }
+    // Add template arguments from a function template specialization.
+    else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(Ctx)) {
+      if (!RelativeToPrimary &&
+          Function->getTemplateSpecializationKind() 
+                                                  == TSK_ExplicitSpecialization)
+        break;
+          
+      if (const TemplateArgumentList *TemplateArgs
+            = Function->getTemplateSpecializationArgs()) {
+        // Add the template arguments for this specialization.
+        Result.addOuterTemplateArguments(TemplateArgs);
+
+        // If this function was instantiated from a specialized member that is
+        // a function template, we're done.
+        assert(Function->getPrimaryTemplate() && "No function template?");
+        if (Function->getPrimaryTemplate()->isMemberSpecialization())
+          break;
+      }
+      
+      // If this is a friend declaration and it declares an entity at
+      // namespace scope, take arguments from its lexical parent
+      // instead of its semantic parent.
+      if (Function->getFriendObjectKind() &&
+          Function->getDeclContext()->isFileContext()) {
+        Ctx = Function->getLexicalDeclContext();
+        RelativeToPrimary = false;
+        continue;
+      }
+    }
+
+    Ctx = Ctx->getParent();
+    RelativeToPrimary = false;
+  }
+
+  return Result;
+}
+
+bool Sema::ActiveTemplateInstantiation::isInstantiationRecord() const {
+  switch (Kind) {
+  case TemplateInstantiation:
+  case DefaultTemplateArgumentInstantiation:
+  case DefaultFunctionArgumentInstantiation:
+    return true;
+      
+  case ExplicitTemplateArgumentSubstitution:
+  case DeducedTemplateArgumentSubstitution:
+  case PriorTemplateArgumentSubstitution:
+  case DefaultTemplateArgumentChecking:
+    return false;
+  }
+  
+  return true;
+}
+
+Sema::InstantiatingTemplate::
+InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
+                      Decl *Entity,
+                      SourceRange InstantiationRange)
+  :  SemaRef(SemaRef) {
+
+  Invalid = CheckInstantiationDepth(PointOfInstantiation,
+                                    InstantiationRange);
+  if (!Invalid) {
+    ActiveTemplateInstantiation Inst;
+    Inst.Kind = ActiveTemplateInstantiation::TemplateInstantiation;
+    Inst.PointOfInstantiation = PointOfInstantiation;
+    Inst.Entity = reinterpret_cast<uintptr_t>(Entity);
+    Inst.TemplateArgs = 0;
+    Inst.NumTemplateArgs = 0;
+    Inst.InstantiationRange = InstantiationRange;
+    SemaRef.ActiveTemplateInstantiations.push_back(Inst);
+  }
+}
+
+Sema::InstantiatingTemplate::InstantiatingTemplate(Sema &SemaRef,
+                                         SourceLocation PointOfInstantiation,
+                                         TemplateDecl *Template,
+                                         const TemplateArgument *TemplateArgs,
+                                         unsigned NumTemplateArgs,
+                                         SourceRange InstantiationRange)
+  : SemaRef(SemaRef) {
+
+  Invalid = CheckInstantiationDepth(PointOfInstantiation,
+                                    InstantiationRange);
+  if (!Invalid) {
+    ActiveTemplateInstantiation Inst;
+    Inst.Kind
+      = ActiveTemplateInstantiation::DefaultTemplateArgumentInstantiation;
+    Inst.PointOfInstantiation = PointOfInstantiation;
+    Inst.Entity = reinterpret_cast<uintptr_t>(Template);
+    Inst.TemplateArgs = TemplateArgs;
+    Inst.NumTemplateArgs = NumTemplateArgs;
+    Inst.InstantiationRange = InstantiationRange;
+    SemaRef.ActiveTemplateInstantiations.push_back(Inst);
+  }
+}
+
+Sema::InstantiatingTemplate::InstantiatingTemplate(Sema &SemaRef,
+                                         SourceLocation PointOfInstantiation,
+                                      FunctionTemplateDecl *FunctionTemplate,
+                                        const TemplateArgument *TemplateArgs,
+                                                   unsigned NumTemplateArgs,
+                         ActiveTemplateInstantiation::InstantiationKind Kind,
+                                              SourceRange InstantiationRange)
+: SemaRef(SemaRef) {
+
+  Invalid = CheckInstantiationDepth(PointOfInstantiation,
+                                    InstantiationRange);
+  if (!Invalid) {
+    ActiveTemplateInstantiation Inst;
+    Inst.Kind = Kind;
+    Inst.PointOfInstantiation = PointOfInstantiation;
+    Inst.Entity = reinterpret_cast<uintptr_t>(FunctionTemplate);
+    Inst.TemplateArgs = TemplateArgs;
+    Inst.NumTemplateArgs = NumTemplateArgs;
+    Inst.InstantiationRange = InstantiationRange;
+    SemaRef.ActiveTemplateInstantiations.push_back(Inst);
+    
+    if (!Inst.isInstantiationRecord())
+      ++SemaRef.NonInstantiationEntries;
+  }
+}
+
+Sema::InstantiatingTemplate::InstantiatingTemplate(Sema &SemaRef,
+                                         SourceLocation PointOfInstantiation,
+                          ClassTemplatePartialSpecializationDecl *PartialSpec,
+                                         const TemplateArgument *TemplateArgs,
+                                         unsigned NumTemplateArgs,
+                                         SourceRange InstantiationRange)
+  : SemaRef(SemaRef) {
+
+  Invalid = false;
+    
+  ActiveTemplateInstantiation Inst;
+  Inst.Kind = ActiveTemplateInstantiation::DeducedTemplateArgumentSubstitution;
+  Inst.PointOfInstantiation = PointOfInstantiation;
+  Inst.Entity = reinterpret_cast<uintptr_t>(PartialSpec);
+  Inst.TemplateArgs = TemplateArgs;
+  Inst.NumTemplateArgs = NumTemplateArgs;
+  Inst.InstantiationRange = InstantiationRange;
+  SemaRef.ActiveTemplateInstantiations.push_back(Inst);
+      
+  assert(!Inst.isInstantiationRecord());
+  ++SemaRef.NonInstantiationEntries;
+}
+
+Sema::InstantiatingTemplate::InstantiatingTemplate(Sema &SemaRef,
+                                          SourceLocation PointOfInstantiation,
+                                          ParmVarDecl *Param,
+                                          const TemplateArgument *TemplateArgs,
+                                          unsigned NumTemplateArgs,
+                                          SourceRange InstantiationRange)
+  : SemaRef(SemaRef) {
+
+  Invalid = CheckInstantiationDepth(PointOfInstantiation, InstantiationRange);
+
+  if (!Invalid) {
+    ActiveTemplateInstantiation Inst;
+    Inst.Kind
+      = ActiveTemplateInstantiation::DefaultFunctionArgumentInstantiation;
+    Inst.PointOfInstantiation = PointOfInstantiation;
+    Inst.Entity = reinterpret_cast<uintptr_t>(Param);
+    Inst.TemplateArgs = TemplateArgs;
+    Inst.NumTemplateArgs = NumTemplateArgs;
+    Inst.InstantiationRange = InstantiationRange;
+    SemaRef.ActiveTemplateInstantiations.push_back(Inst);
+  }
+}
+
+Sema::InstantiatingTemplate::
+InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
+                      TemplateDecl *Template,
+                      NonTypeTemplateParmDecl *Param,
+                      const TemplateArgument *TemplateArgs,
+                      unsigned NumTemplateArgs,
+                      SourceRange InstantiationRange) : SemaRef(SemaRef) {
+  Invalid = false;
+  
+  ActiveTemplateInstantiation Inst;
+  Inst.Kind = ActiveTemplateInstantiation::PriorTemplateArgumentSubstitution;
+  Inst.PointOfInstantiation = PointOfInstantiation;
+  Inst.Template = Template;
+  Inst.Entity = reinterpret_cast<uintptr_t>(Param);
+  Inst.TemplateArgs = TemplateArgs;
+  Inst.NumTemplateArgs = NumTemplateArgs;
+  Inst.InstantiationRange = InstantiationRange;
+  SemaRef.ActiveTemplateInstantiations.push_back(Inst);
+  
+  assert(!Inst.isInstantiationRecord());
+  ++SemaRef.NonInstantiationEntries;
+}
+
+Sema::InstantiatingTemplate::
+InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
+                      TemplateDecl *Template,
+                      TemplateTemplateParmDecl *Param,
+                      const TemplateArgument *TemplateArgs,
+                      unsigned NumTemplateArgs,
+                      SourceRange InstantiationRange) : SemaRef(SemaRef) {
+  Invalid = false;
+  ActiveTemplateInstantiation Inst;
+  Inst.Kind = ActiveTemplateInstantiation::PriorTemplateArgumentSubstitution;
+  Inst.PointOfInstantiation = PointOfInstantiation;
+  Inst.Template = Template;
+  Inst.Entity = reinterpret_cast<uintptr_t>(Param);
+  Inst.TemplateArgs = TemplateArgs;
+  Inst.NumTemplateArgs = NumTemplateArgs;
+  Inst.InstantiationRange = InstantiationRange;
+  SemaRef.ActiveTemplateInstantiations.push_back(Inst);
+  
+  assert(!Inst.isInstantiationRecord());
+  ++SemaRef.NonInstantiationEntries;
+}
+
+Sema::InstantiatingTemplate::
+InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
+                      TemplateDecl *Template,
+                      NamedDecl *Param,
+                      const TemplateArgument *TemplateArgs,
+                      unsigned NumTemplateArgs,
+                      SourceRange InstantiationRange) : SemaRef(SemaRef) {
+  Invalid = false;
+  
+  ActiveTemplateInstantiation Inst;
+  Inst.Kind = ActiveTemplateInstantiation::DefaultTemplateArgumentChecking;
+  Inst.PointOfInstantiation = PointOfInstantiation;
+  Inst.Template = Template;
+  Inst.Entity = reinterpret_cast<uintptr_t>(Param);
+  Inst.TemplateArgs = TemplateArgs;
+  Inst.NumTemplateArgs = NumTemplateArgs;
+  Inst.InstantiationRange = InstantiationRange;
+  SemaRef.ActiveTemplateInstantiations.push_back(Inst);
+  
+  assert(!Inst.isInstantiationRecord());
+  ++SemaRef.NonInstantiationEntries;
+}
+
+void Sema::InstantiatingTemplate::Clear() {
+  if (!Invalid) {
+    if (!SemaRef.ActiveTemplateInstantiations.back().isInstantiationRecord()) {
+      assert(SemaRef.NonInstantiationEntries > 0);
+      --SemaRef.NonInstantiationEntries;
+    }
+    
+    SemaRef.ActiveTemplateInstantiations.pop_back();
+    Invalid = true;
+  }
+}
+
+bool Sema::InstantiatingTemplate::CheckInstantiationDepth(
+                                        SourceLocation PointOfInstantiation,
+                                           SourceRange InstantiationRange) {
+  assert(SemaRef.NonInstantiationEntries <=
+                                   SemaRef.ActiveTemplateInstantiations.size());
+  if ((SemaRef.ActiveTemplateInstantiations.size() - 
+          SemaRef.NonInstantiationEntries)
+        <= SemaRef.getLangOptions().InstantiationDepth)
+    return false;
+
+  SemaRef.Diag(PointOfInstantiation,
+               diag::err_template_recursion_depth_exceeded)
+    << SemaRef.getLangOptions().InstantiationDepth
+    << InstantiationRange;
+  SemaRef.Diag(PointOfInstantiation, diag::note_template_recursion_depth)
+    << SemaRef.getLangOptions().InstantiationDepth;
+  return true;
+}
+
+/// \brief Prints the current instantiation stack through a series of
+/// notes.
+void Sema::PrintInstantiationStack() {
+  // Determine which template instantiations to skip, if any.
+  unsigned SkipStart = ActiveTemplateInstantiations.size(), SkipEnd = SkipStart;
+  unsigned Limit = Diags.getTemplateBacktraceLimit();
+  if (Limit && Limit < ActiveTemplateInstantiations.size()) {
+    SkipStart = Limit / 2 + Limit % 2;
+    SkipEnd = ActiveTemplateInstantiations.size() - Limit / 2;
+  }
+
+  // FIXME: In all of these cases, we need to show the template arguments
+  unsigned InstantiationIdx = 0;
+  for (llvm::SmallVector<ActiveTemplateInstantiation, 16>::reverse_iterator
+         Active = ActiveTemplateInstantiations.rbegin(),
+         ActiveEnd = ActiveTemplateInstantiations.rend();
+       Active != ActiveEnd;
+       ++Active, ++InstantiationIdx) {
+    // Skip this instantiation?
+    if (InstantiationIdx >= SkipStart && InstantiationIdx < SkipEnd) {
+      if (InstantiationIdx == SkipStart) {
+        // Note that we're skipping instantiations.
+        Diags.Report(FullSourceLoc(Active->PointOfInstantiation, SourceMgr),
+                     diag::note_instantiation_contexts_suppressed)
+          << unsigned(ActiveTemplateInstantiations.size() - Limit);
+      }
+      continue;
+    }
+
+    switch (Active->Kind) {
+    case ActiveTemplateInstantiation::TemplateInstantiation: {
+      Decl *D = reinterpret_cast<Decl *>(Active->Entity);
+      if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(D)) {
+        unsigned DiagID = diag::note_template_member_class_here;
+        if (isa<ClassTemplateSpecializationDecl>(Record))
+          DiagID = diag::note_template_class_instantiation_here;
+        Diags.Report(FullSourceLoc(Active->PointOfInstantiation, SourceMgr),
+                     DiagID)
+          << Context.getTypeDeclType(Record)
+          << Active->InstantiationRange;
+      } else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
+        unsigned DiagID;
+        if (Function->getPrimaryTemplate())
+          DiagID = diag::note_function_template_spec_here;
+        else
+          DiagID = diag::note_template_member_function_here;
+        Diags.Report(FullSourceLoc(Active->PointOfInstantiation, SourceMgr),
+                     DiagID)
+          << Function
+          << Active->InstantiationRange;
+      } else {
+        Diags.Report(FullSourceLoc(Active->PointOfInstantiation, SourceMgr),
+                     diag::note_template_static_data_member_def_here)
+          << cast<VarDecl>(D)
+          << Active->InstantiationRange;
+      }
+      break;
+    }
+
+    case ActiveTemplateInstantiation::DefaultTemplateArgumentInstantiation: {
+      TemplateDecl *Template = cast<TemplateDecl>((Decl *)Active->Entity);
+      std::string TemplateArgsStr
+        = TemplateSpecializationType::PrintTemplateArgumentList(
+                                                         Active->TemplateArgs,
+                                                      Active->NumTemplateArgs,
+                                                      Context.PrintingPolicy);
+      Diags.Report(FullSourceLoc(Active->PointOfInstantiation, SourceMgr),
+                   diag::note_default_arg_instantiation_here)
+        << (Template->getNameAsString() + TemplateArgsStr)
+        << Active->InstantiationRange;
+      break;
+    }
+
+    case ActiveTemplateInstantiation::ExplicitTemplateArgumentSubstitution: {
+      FunctionTemplateDecl *FnTmpl
+        = cast<FunctionTemplateDecl>((Decl *)Active->Entity);
+      Diags.Report(FullSourceLoc(Active->PointOfInstantiation, SourceMgr),
+                   diag::note_explicit_template_arg_substitution_here)
+        << FnTmpl 
+        << getTemplateArgumentBindingsText(FnTmpl->getTemplateParameters(), 
+                                           Active->TemplateArgs, 
+                                           Active->NumTemplateArgs)
+        << Active->InstantiationRange;
+      break;
+    }
+
+    case ActiveTemplateInstantiation::DeducedTemplateArgumentSubstitution:
+      if (ClassTemplatePartialSpecializationDecl *PartialSpec
+            = dyn_cast<ClassTemplatePartialSpecializationDecl>(
+                                                    (Decl *)Active->Entity)) {
+        Diags.Report(FullSourceLoc(Active->PointOfInstantiation, SourceMgr),
+                     diag::note_partial_spec_deduct_instantiation_here)
+          << Context.getTypeDeclType(PartialSpec)
+          << getTemplateArgumentBindingsText(
+                                         PartialSpec->getTemplateParameters(), 
+                                             Active->TemplateArgs, 
+                                             Active->NumTemplateArgs)
+          << Active->InstantiationRange;
+      } else {
+        FunctionTemplateDecl *FnTmpl
+          = cast<FunctionTemplateDecl>((Decl *)Active->Entity);
+        Diags.Report(FullSourceLoc(Active->PointOfInstantiation, SourceMgr),
+                     diag::note_function_template_deduction_instantiation_here)
+          << FnTmpl
+          << getTemplateArgumentBindingsText(FnTmpl->getTemplateParameters(), 
+                                             Active->TemplateArgs, 
+                                             Active->NumTemplateArgs)
+          << Active->InstantiationRange;
+      }
+      break;
+
+    case ActiveTemplateInstantiation::DefaultFunctionArgumentInstantiation: {
+      ParmVarDecl *Param = cast<ParmVarDecl>((Decl *)Active->Entity);
+      FunctionDecl *FD = cast<FunctionDecl>(Param->getDeclContext());
+
+      std::string TemplateArgsStr
+        = TemplateSpecializationType::PrintTemplateArgumentList(
+                                                         Active->TemplateArgs,
+                                                      Active->NumTemplateArgs,
+                                                      Context.PrintingPolicy);
+      Diags.Report(FullSourceLoc(Active->PointOfInstantiation, SourceMgr),
+                   diag::note_default_function_arg_instantiation_here)
+        << (FD->getNameAsString() + TemplateArgsStr)
+        << Active->InstantiationRange;
+      break;
+    }
+
+    case ActiveTemplateInstantiation::PriorTemplateArgumentSubstitution: {
+      NamedDecl *Parm = cast<NamedDecl>((Decl *)Active->Entity);
+      std::string Name;
+      if (!Parm->getName().empty())
+        Name = std::string(" '") + Parm->getName().str() + "'";
+                                        
+      Diags.Report(FullSourceLoc(Active->PointOfInstantiation, SourceMgr),
+                   diag::note_prior_template_arg_substitution)
+        << isa<TemplateTemplateParmDecl>(Parm)
+        << Name
+        << getTemplateArgumentBindingsText(
+                                    Active->Template->getTemplateParameters(), 
+                                           Active->TemplateArgs, 
+                                           Active->NumTemplateArgs)
+        << Active->InstantiationRange;
+      break;
+    }
+
+    case ActiveTemplateInstantiation::DefaultTemplateArgumentChecking: {
+      Diags.Report(FullSourceLoc(Active->PointOfInstantiation, SourceMgr),
+                   diag::note_template_default_arg_checking)
+        << getTemplateArgumentBindingsText(
+                                     Active->Template->getTemplateParameters(), 
+                                           Active->TemplateArgs, 
+                                           Active->NumTemplateArgs)
+        << Active->InstantiationRange;
+      break;
+    }
+    }
+  }
+}
+
+bool Sema::isSFINAEContext() const {
+  using llvm::SmallVector;
+  for (SmallVector<ActiveTemplateInstantiation, 16>::const_reverse_iterator
+         Active = ActiveTemplateInstantiations.rbegin(),
+         ActiveEnd = ActiveTemplateInstantiations.rend();
+       Active != ActiveEnd;
+       ++Active) 
+  {
+    switch(Active->Kind) {
+    case ActiveTemplateInstantiation::TemplateInstantiation:
+    case ActiveTemplateInstantiation::DefaultFunctionArgumentInstantiation:
+      // This is a template instantiation, so there is no SFINAE.
+      return false;
+
+    case ActiveTemplateInstantiation::DefaultTemplateArgumentInstantiation:
+    case ActiveTemplateInstantiation::PriorTemplateArgumentSubstitution:
+    case ActiveTemplateInstantiation::DefaultTemplateArgumentChecking:
+      // A default template argument instantiation and substitution into
+      // template parameters with arguments for prior parameters may or may 
+      // not be a SFINAE context; look further up the stack.
+      break;
+
+    case ActiveTemplateInstantiation::ExplicitTemplateArgumentSubstitution:
+    case ActiveTemplateInstantiation::DeducedTemplateArgumentSubstitution:
+      // We're either substitution explicitly-specified template arguments
+      // or deduced template arguments, so SFINAE applies.
+      return true;
+    }
+  }
+
+  return false;
+}
+
+//===----------------------------------------------------------------------===/
+// Template Instantiation for Types
+//===----------------------------------------------------------------------===/
+namespace {
+  class TemplateInstantiator
+    : public TreeTransform<TemplateInstantiator> {
+    const MultiLevelTemplateArgumentList &TemplateArgs;
+    SourceLocation Loc;
+    DeclarationName Entity;
+
+  public:
+    typedef TreeTransform<TemplateInstantiator> inherited;
+
+    TemplateInstantiator(Sema &SemaRef,
+                         const MultiLevelTemplateArgumentList &TemplateArgs,
+                         SourceLocation Loc,
+                         DeclarationName Entity)
+      : inherited(SemaRef), TemplateArgs(TemplateArgs), Loc(Loc),
+        Entity(Entity) { }
+
+    /// \brief Determine whether the given type \p T has already been
+    /// transformed.
+    ///
+    /// For the purposes of template instantiation, a type has already been
+    /// transformed if it is NULL or if it is not dependent.
+    bool AlreadyTransformed(QualType T) {
+      return T.isNull() || !T->isDependentType();
+    }
+
+    /// \brief Returns the location of the entity being instantiated, if known.
+    SourceLocation getBaseLocation() { return Loc; }
+
+    /// \brief Returns the name of the entity being instantiated, if any.
+    DeclarationName getBaseEntity() { return Entity; }
+
+    /// \brief Sets the "base" location and entity when that
+    /// information is known based on another transformation.
+    void setBase(SourceLocation Loc, DeclarationName Entity) {
+      this->Loc = Loc;
+      this->Entity = Entity;
+    }
+      
+    /// \brief Transform the given declaration by instantiating a reference to
+    /// this declaration.
+    Decl *TransformDecl(SourceLocation Loc, Decl *D);
+
+    /// \brief Transform the definition of the given declaration by
+    /// instantiating it.
+    Decl *TransformDefinition(SourceLocation Loc, Decl *D);
+
+    /// \bried Transform the first qualifier within a scope by instantiating the
+    /// declaration.
+    NamedDecl *TransformFirstQualifierInScope(NamedDecl *D, SourceLocation Loc);
+      
+    /// \brief Rebuild the exception declaration and register the declaration
+    /// as an instantiated local.
+    VarDecl *RebuildExceptionDecl(VarDecl *ExceptionDecl, QualType T,
+                                  TypeSourceInfo *Declarator,
+                                  IdentifierInfo *Name,
+                                  SourceLocation Loc, SourceRange TypeRange);
+
+    /// \brief Rebuild the Objective-C exception declaration and register the 
+    /// declaration as an instantiated local.
+    VarDecl *RebuildObjCExceptionDecl(VarDecl *ExceptionDecl, 
+                                      TypeSourceInfo *TSInfo, QualType T);
+      
+    /// \brief Check for tag mismatches when instantiating an
+    /// elaborated type.
+    QualType RebuildElaboratedType(QualType T, ElaboratedType::TagKind Tag);
+
+    Sema::OwningExprResult TransformPredefinedExpr(PredefinedExpr *E);
+    Sema::OwningExprResult TransformDeclRefExpr(DeclRefExpr *E);
+    Sema::OwningExprResult TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E);
+    Sema::OwningExprResult TransformTemplateParmRefExpr(DeclRefExpr *E,
+                                                NonTypeTemplateParmDecl *D);
+
+    /// \brief Transforms a function proto type by performing
+    /// substitution in the function parameters, possibly adjusting
+    /// their types and marking default arguments as uninstantiated.
+    bool TransformFunctionTypeParams(FunctionProtoTypeLoc TL,
+                                     llvm::SmallVectorImpl<QualType> &PTypes,
+                                  llvm::SmallVectorImpl<ParmVarDecl*> &PVars);
+
+    ParmVarDecl *TransformFunctionTypeParam(ParmVarDecl *OldParm);
+
+    /// \brief Transforms a template type parameter type by performing
+    /// substitution of the corresponding template type argument.
+    QualType TransformTemplateTypeParmType(TypeLocBuilder &TLB,
+                                           TemplateTypeParmTypeLoc TL,
+                                           QualType ObjectType);
+  };
+}
+
+Decl *TemplateInstantiator::TransformDecl(SourceLocation Loc, Decl *D) {
+  if (!D)
+    return 0;
+
+  if (TemplateTemplateParmDecl *TTP = dyn_cast<TemplateTemplateParmDecl>(D)) {
+    if (TTP->getDepth() < TemplateArgs.getNumLevels()) {
+      // If the corresponding template argument is NULL or non-existent, it's
+      // because we are performing instantiation from explicitly-specified
+      // template arguments in a function template, but there were some
+      // arguments left unspecified.
+      if (!TemplateArgs.hasTemplateArgument(TTP->getDepth(),
+                                            TTP->getPosition()))
+        return D;
+
+      TemplateName Template
+        = TemplateArgs(TTP->getDepth(), TTP->getPosition()).getAsTemplate();
+      assert(!Template.isNull() && Template.getAsTemplateDecl() &&
+             "Wrong kind of template template argument");
+      return Template.getAsTemplateDecl();
+    }
+
+    // Fall through to find the instantiated declaration for this template
+    // template parameter.
+  }
+
+  return SemaRef.FindInstantiatedDecl(Loc, cast<NamedDecl>(D), TemplateArgs);
+}
+
+Decl *TemplateInstantiator::TransformDefinition(SourceLocation Loc, Decl *D) {
+  Decl *Inst = getSema().SubstDecl(D, getSema().CurContext, TemplateArgs);
+  if (!Inst)
+    return 0;
+
+  getSema().CurrentInstantiationScope->InstantiatedLocal(D, Inst);
+  return Inst;
+}
+
+NamedDecl *
+TemplateInstantiator::TransformFirstQualifierInScope(NamedDecl *D, 
+                                                     SourceLocation Loc) {
+  // If the first part of the nested-name-specifier was a template type 
+  // parameter, instantiate that type parameter down to a tag type.
+  if (TemplateTypeParmDecl *TTPD = dyn_cast_or_null<TemplateTypeParmDecl>(D)) {
+    const TemplateTypeParmType *TTP 
+      = cast<TemplateTypeParmType>(getSema().Context.getTypeDeclType(TTPD));
+    if (TTP->getDepth() < TemplateArgs.getNumLevels()) {
+      QualType T = TemplateArgs(TTP->getDepth(), TTP->getIndex()).getAsType();
+      if (T.isNull())
+        return cast_or_null<NamedDecl>(TransformDecl(Loc, D));
+      
+      if (const TagType *Tag = T->getAs<TagType>())
+        return Tag->getDecl();
+      
+      // The resulting type is not a tag; complain.
+      getSema().Diag(Loc, diag::err_nested_name_spec_non_tag) << T;
+      return 0;
+    }
+  }
+  
+  return cast_or_null<NamedDecl>(TransformDecl(Loc, D));
+}
+
+VarDecl *
+TemplateInstantiator::RebuildExceptionDecl(VarDecl *ExceptionDecl,
+                                           QualType T,
+                                           TypeSourceInfo *Declarator,
+                                           IdentifierInfo *Name,
+                                           SourceLocation Loc,
+                                           SourceRange TypeRange) {
+  VarDecl *Var = inherited::RebuildExceptionDecl(ExceptionDecl, T, Declarator,
+                                                 Name, Loc, TypeRange);
+  if (Var)
+    getSema().CurrentInstantiationScope->InstantiatedLocal(ExceptionDecl, Var);
+  return Var;
+}
+
+VarDecl *TemplateInstantiator::RebuildObjCExceptionDecl(VarDecl *ExceptionDecl, 
+                                                        TypeSourceInfo *TSInfo, 
+                                                        QualType T) {
+  VarDecl *Var = inherited::RebuildObjCExceptionDecl(ExceptionDecl, TSInfo, T);
+  if (Var)
+    getSema().CurrentInstantiationScope->InstantiatedLocal(ExceptionDecl, Var);
+  return Var;
+}
+
+QualType
+TemplateInstantiator::RebuildElaboratedType(QualType T,
+                                            ElaboratedType::TagKind Tag) {
+  if (const TagType *TT = T->getAs<TagType>()) {
+    TagDecl* TD = TT->getDecl();
+
+    // FIXME: this location is very wrong;  we really need typelocs.
+    SourceLocation TagLocation = TD->getTagKeywordLoc();
+
+    // FIXME: type might be anonymous.
+    IdentifierInfo *Id = TD->getIdentifier();
+
+    // TODO: should we even warn on struct/class mismatches for this?  Seems
+    // like it's likely to produce a lot of spurious errors.
+    if (!SemaRef.isAcceptableTagRedeclaration(TD, Tag, TagLocation, *Id)) {
+      SemaRef.Diag(TagLocation, diag::err_use_with_wrong_tag)
+        << Id
+        << FixItHint::CreateReplacement(SourceRange(TagLocation),
+                                        TD->getKindName());
+      SemaRef.Diag(TD->getLocation(), diag::note_previous_use);
+    }
+  }
+
+  return TreeTransform<TemplateInstantiator>::RebuildElaboratedType(T, Tag);
+}
+
+Sema::OwningExprResult 
+TemplateInstantiator::TransformPredefinedExpr(PredefinedExpr *E) {
+  if (!E->isTypeDependent())
+    return SemaRef.Owned(E->Retain());
+
+  FunctionDecl *currentDecl = getSema().getCurFunctionDecl();
+  assert(currentDecl && "Must have current function declaration when "
+                        "instantiating.");
+
+  PredefinedExpr::IdentType IT = E->getIdentType();
+
+  unsigned Length = PredefinedExpr::ComputeName(IT, currentDecl).length();
+
+  llvm::APInt LengthI(32, Length + 1);
+  QualType ResTy = getSema().Context.CharTy.withConst();
+  ResTy = getSema().Context.getConstantArrayType(ResTy, LengthI, 
+                                                 ArrayType::Normal, 0);
+  PredefinedExpr *PE =
+    new (getSema().Context) PredefinedExpr(E->getLocation(), ResTy, IT);
+  return getSema().Owned(PE);
+}
+
+Sema::OwningExprResult
+TemplateInstantiator::TransformTemplateParmRefExpr(DeclRefExpr *E,
+                                               NonTypeTemplateParmDecl *NTTP) {
+  // If the corresponding template argument is NULL or non-existent, it's
+  // because we are performing instantiation from explicitly-specified
+  // template arguments in a function template, but there were some
+  // arguments left unspecified.
+  if (!TemplateArgs.hasTemplateArgument(NTTP->getDepth(),
+                                        NTTP->getPosition()))
+    return SemaRef.Owned(E->Retain());
+
+  const TemplateArgument &Arg = TemplateArgs(NTTP->getDepth(),
+                                             NTTP->getPosition());
+
+  // The template argument itself might be an expression, in which
+  // case we just return that expression.
+  if (Arg.getKind() == TemplateArgument::Expression)
+    return SemaRef.Owned(Arg.getAsExpr()->Retain());
+
+  if (Arg.getKind() == TemplateArgument::Declaration) {
+    ValueDecl *VD = cast<ValueDecl>(Arg.getAsDecl());
+
+    // Find the instantiation of the template argument.  This is
+    // required for nested templates.
+    VD = cast_or_null<ValueDecl>(
+                            getSema().FindInstantiatedDecl(E->getLocation(),
+                                                           VD, TemplateArgs));
+    if (!VD)
+      return SemaRef.ExprError();
+
+    // Derive the type we want the substituted decl to have.  This had
+    // better be non-dependent, or these checks will have serious problems.
+    QualType TargetType = SemaRef.SubstType(NTTP->getType(), TemplateArgs,
+                                            E->getLocation(), 
+                                            DeclarationName());
+    assert(!TargetType.isNull() && "type substitution failed for param type");
+    assert(!TargetType->isDependentType() && "param type still dependent");
+    return SemaRef.BuildExpressionFromDeclTemplateArgument(Arg,
+                                                           TargetType,
+                                                           E->getLocation());
+  }
+
+  return SemaRef.BuildExpressionFromIntegralTemplateArgument(Arg, 
+                                                E->getSourceRange().getBegin());
+}
+                                                   
+
+Sema::OwningExprResult
+TemplateInstantiator::TransformDeclRefExpr(DeclRefExpr *E) {
+  NamedDecl *D = E->getDecl();
+  if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D)) {
+    if (NTTP->getDepth() < TemplateArgs.getNumLevels())
+      return TransformTemplateParmRefExpr(E, NTTP);
+    
+    // We have a non-type template parameter that isn't fully substituted;
+    // FindInstantiatedDecl will find it in the local instantiation scope.
+  }
+
+  return TreeTransform<TemplateInstantiator>::TransformDeclRefExpr(E);
+}
+
+Sema::OwningExprResult TemplateInstantiator::TransformCXXDefaultArgExpr(
+    CXXDefaultArgExpr *E) {
+  assert(!cast<FunctionDecl>(E->getParam()->getDeclContext())->
+             getDescribedFunctionTemplate() &&
+         "Default arg expressions are never formed in dependent cases.");
+  return SemaRef.BuildCXXDefaultArgExpr(E->getUsedLocation(),
+                           cast<FunctionDecl>(E->getParam()->getDeclContext()), 
+                                        E->getParam());
+}
+
+
+bool
+TemplateInstantiator::TransformFunctionTypeParams(FunctionProtoTypeLoc TL,
+                                  llvm::SmallVectorImpl<QualType> &PTypes,
+                               llvm::SmallVectorImpl<ParmVarDecl*> &PVars) {
+  // Create a local instantiation scope for the parameters.
+  // FIXME: When we implement the C++0x late-specified return type, 
+  // we will need to move this scope out to the function type itself.
+  bool IsTemporaryScope = (SemaRef.CurrentInstantiationScope != 0);
+  Sema::LocalInstantiationScope Scope(SemaRef, IsTemporaryScope, 
+                                      IsTemporaryScope);
+
+  if (TreeTransform<TemplateInstantiator>::
+        TransformFunctionTypeParams(TL, PTypes, PVars))
+    return true;
+
+  return false;
+}
+
+ParmVarDecl *
+TemplateInstantiator::TransformFunctionTypeParam(ParmVarDecl *OldParm) {
+  return SemaRef.SubstParmVarDecl(OldParm, TemplateArgs);
+}
+
+QualType
+TemplateInstantiator::TransformTemplateTypeParmType(TypeLocBuilder &TLB,
+                                                TemplateTypeParmTypeLoc TL, 
+                                                    QualType ObjectType) {
+  TemplateTypeParmType *T = TL.getTypePtr();
+  if (T->getDepth() < TemplateArgs.getNumLevels()) {
+    // Replace the template type parameter with its corresponding
+    // template argument.
+
+    // If the corresponding template argument is NULL or doesn't exist, it's
+    // because we are performing instantiation from explicitly-specified
+    // template arguments in a function template class, but there were some
+    // arguments left unspecified.
+    if (!TemplateArgs.hasTemplateArgument(T->getDepth(), T->getIndex())) {
+      TemplateTypeParmTypeLoc NewTL
+        = TLB.push<TemplateTypeParmTypeLoc>(TL.getType());
+      NewTL.setNameLoc(TL.getNameLoc());
+      return TL.getType();
+    }
+
+    assert(TemplateArgs(T->getDepth(), T->getIndex()).getKind()
+             == TemplateArgument::Type &&
+           "Template argument kind mismatch");
+
+    QualType Replacement
+      = TemplateArgs(T->getDepth(), T->getIndex()).getAsType();
+
+    // TODO: only do this uniquing once, at the start of instantiation.
+    QualType Result
+      = getSema().Context.getSubstTemplateTypeParmType(T, Replacement);
+    SubstTemplateTypeParmTypeLoc NewTL
+      = TLB.push<SubstTemplateTypeParmTypeLoc>(Result);
+    NewTL.setNameLoc(TL.getNameLoc());
+    return Result;
+  }
+
+  // The template type parameter comes from an inner template (e.g.,
+  // the template parameter list of a member template inside the
+  // template we are instantiating). Create a new template type
+  // parameter with the template "level" reduced by one.
+  QualType Result
+    = getSema().Context.getTemplateTypeParmType(T->getDepth()
+                                                 - TemplateArgs.getNumLevels(),
+                                                T->getIndex(),
+                                                T->isParameterPack(),
+                                                T->getName());
+  TemplateTypeParmTypeLoc NewTL = TLB.push<TemplateTypeParmTypeLoc>(Result);
+  NewTL.setNameLoc(TL.getNameLoc());
+  return Result;
+}
+
+/// \brief Perform substitution on the type T with a given set of template
+/// arguments.
+///
+/// This routine substitutes the given template arguments into the
+/// type T and produces the instantiated type.
+///
+/// \param T the type into which the template arguments will be
+/// substituted. If this type is not dependent, it will be returned
+/// immediately.
+///
+/// \param TemplateArgs the template arguments that will be
+/// substituted for the top-level template parameters within T.
+///
+/// \param Loc the location in the source code where this substitution
+/// is being performed. It will typically be the location of the
+/// declarator (if we're instantiating the type of some declaration)
+/// or the location of the type in the source code (if, e.g., we're
+/// instantiating the type of a cast expression).
+///
+/// \param Entity the name of the entity associated with a declaration
+/// being instantiated (if any). May be empty to indicate that there
+/// is no such entity (if, e.g., this is a type that occurs as part of
+/// a cast expression) or that the entity has no name (e.g., an
+/// unnamed function parameter).
+///
+/// \returns If the instantiation succeeds, the instantiated
+/// type. Otherwise, produces diagnostics and returns a NULL type.
+TypeSourceInfo *Sema::SubstType(TypeSourceInfo *T,
+                                const MultiLevelTemplateArgumentList &Args,
+                                SourceLocation Loc,
+                                DeclarationName Entity) {
+  assert(!ActiveTemplateInstantiations.empty() &&
+         "Cannot perform an instantiation without some context on the "
+         "instantiation stack");
+  
+  if (!T->getType()->isDependentType())
+    return T;
+
+  TemplateInstantiator Instantiator(*this, Args, Loc, Entity);
+  return Instantiator.TransformType(T);
+}
+
+/// Deprecated form of the above.
+QualType Sema::SubstType(QualType T,
+                         const MultiLevelTemplateArgumentList &TemplateArgs,
+                         SourceLocation Loc, DeclarationName Entity) {
+  assert(!ActiveTemplateInstantiations.empty() &&
+         "Cannot perform an instantiation without some context on the "
+         "instantiation stack");
+
+  // If T is not a dependent type, there is nothing to do.
+  if (!T->isDependentType())
+    return T;
+
+  TemplateInstantiator Instantiator(*this, TemplateArgs, Loc, Entity);
+  return Instantiator.TransformType(T);
+}
+
+static bool NeedsInstantiationAsFunctionType(TypeSourceInfo *T) {
+  if (T->getType()->isDependentType())
+    return true;
+
+  TypeLoc TL = T->getTypeLoc();
+  if (!isa<FunctionProtoTypeLoc>(TL))
+    return false;
+
+  FunctionProtoTypeLoc FP = cast<FunctionProtoTypeLoc>(TL);
+  for (unsigned I = 0, E = FP.getNumArgs(); I != E; ++I) {
+    ParmVarDecl *P = FP.getArg(I);
+
+    // TODO: currently we always rebuild expressions.  When we
+    // properly get lazier about this, we should use the same
+    // logic to avoid rebuilding prototypes here.
+    if (P->hasInit())
+      return true;
+  }
+
+  return false;
+}
+
+/// A form of SubstType intended specifically for instantiating the
+/// type of a FunctionDecl.  Its purpose is solely to force the
+/// instantiation of default-argument expressions.
+TypeSourceInfo *Sema::SubstFunctionDeclType(TypeSourceInfo *T,
+                                const MultiLevelTemplateArgumentList &Args,
+                                SourceLocation Loc,
+                                DeclarationName Entity) {
+  assert(!ActiveTemplateInstantiations.empty() &&
+         "Cannot perform an instantiation without some context on the "
+         "instantiation stack");
+  
+  if (!NeedsInstantiationAsFunctionType(T))
+    return T;
+
+  TemplateInstantiator Instantiator(*this, Args, Loc, Entity);
+
+  TypeLocBuilder TLB;
+
+  TypeLoc TL = T->getTypeLoc();
+  TLB.reserve(TL.getFullDataSize());
+
+  QualType Result = Instantiator.TransformType(TLB, TL, QualType());
+  if (Result.isNull())
+    return 0;
+
+  return TLB.getTypeSourceInfo(Context, Result);
+}
+
+ParmVarDecl *Sema::SubstParmVarDecl(ParmVarDecl *OldParm, 
+                          const MultiLevelTemplateArgumentList &TemplateArgs) {
+  TypeSourceInfo *OldDI = OldParm->getTypeSourceInfo();
+  TypeSourceInfo *NewDI = SubstType(OldDI, TemplateArgs, OldParm->getLocation(),
+                                    OldParm->getDeclName());
+  if (!NewDI)
+    return 0;
+
+  if (NewDI->getType()->isVoidType()) {
+    Diag(OldParm->getLocation(), diag::err_param_with_void_type);
+    return 0;
+  }
+
+  ParmVarDecl *NewParm = CheckParameter(Context.getTranslationUnitDecl(),
+                                        NewDI, NewDI->getType(),
+                                        OldParm->getIdentifier(),
+                                        OldParm->getLocation(),
+                                        OldParm->getStorageClass(),
+                                        OldParm->getStorageClassAsWritten());
+  if (!NewParm)
+    return 0;
+                                                
+  // Mark the (new) default argument as uninstantiated (if any).
+  if (OldParm->hasUninstantiatedDefaultArg()) {
+    Expr *Arg = OldParm->getUninstantiatedDefaultArg();
+    NewParm->setUninstantiatedDefaultArg(Arg);
+  } else if (Expr *Arg = OldParm->getDefaultArg())
+    NewParm->setUninstantiatedDefaultArg(Arg);
+
+  NewParm->setHasInheritedDefaultArg(OldParm->hasInheritedDefaultArg());
+
+  CurrentInstantiationScope->InstantiatedLocal(OldParm, NewParm);
+  return NewParm;  
+}
+
+/// \brief Perform substitution on the base class specifiers of the
+/// given class template specialization.
+///
+/// Produces a diagnostic and returns true on error, returns false and
+/// attaches the instantiated base classes to the class template
+/// specialization if successful.
+bool
+Sema::SubstBaseSpecifiers(CXXRecordDecl *Instantiation,
+                          CXXRecordDecl *Pattern,
+                          const MultiLevelTemplateArgumentList &TemplateArgs) {
+  bool Invalid = false;
+  llvm::SmallVector<CXXBaseSpecifier*, 4> InstantiatedBases;
+  for (ClassTemplateSpecializationDecl::base_class_iterator
+         Base = Pattern->bases_begin(), BaseEnd = Pattern->bases_end();
+       Base != BaseEnd; ++Base) {
+    if (!Base->getType()->isDependentType()) {
+      const CXXRecordDecl *BaseDecl =
+        cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
+      
+      // Make sure to set the attributes from the base.
+      SetClassDeclAttributesFromBase(Instantiation, BaseDecl, 
+                                     Base->isVirtual());
+      
+      InstantiatedBases.push_back(new (Context) CXXBaseSpecifier(*Base));
+      continue;
+    }
+
+    QualType BaseType = SubstType(Base->getType(),
+                                  TemplateArgs,
+                                  Base->getSourceRange().getBegin(),
+                                  DeclarationName());
+    if (BaseType.isNull()) {
+      Invalid = true;
+      continue;
+    }
+
+    if (CXXBaseSpecifier *InstantiatedBase
+          = CheckBaseSpecifier(Instantiation,
+                               Base->getSourceRange(),
+                               Base->isVirtual(),
+                               Base->getAccessSpecifierAsWritten(),
+                               BaseType,
+                               /*FIXME: Not totally accurate */
+                               Base->getSourceRange().getBegin()))
+      InstantiatedBases.push_back(InstantiatedBase);
+    else
+      Invalid = true;
+  }
+
+  if (!Invalid &&
+      AttachBaseSpecifiers(Instantiation, InstantiatedBases.data(),
+                           InstantiatedBases.size()))
+    Invalid = true;
+
+  return Invalid;
+}
+
+/// \brief Instantiate the definition of a class from a given pattern.
+///
+/// \param PointOfInstantiation The point of instantiation within the
+/// source code.
+///
+/// \param Instantiation is the declaration whose definition is being
+/// instantiated. This will be either a class template specialization
+/// or a member class of a class template specialization.
+///
+/// \param Pattern is the pattern from which the instantiation
+/// occurs. This will be either the declaration of a class template or
+/// the declaration of a member class of a class template.
+///
+/// \param TemplateArgs The template arguments to be substituted into
+/// the pattern.
+///
+/// \param TSK the kind of implicit or explicit instantiation to perform.
+///
+/// \param Complain whether to complain if the class cannot be instantiated due
+/// to the lack of a definition.
+///
+/// \returns true if an error occurred, false otherwise.
+bool
+Sema::InstantiateClass(SourceLocation PointOfInstantiation,
+                       CXXRecordDecl *Instantiation, CXXRecordDecl *Pattern,
+                       const MultiLevelTemplateArgumentList &TemplateArgs,
+                       TemplateSpecializationKind TSK,
+                       bool Complain) {
+  bool Invalid = false;
+
+  CXXRecordDecl *PatternDef
+    = cast_or_null<CXXRecordDecl>(Pattern->getDefinition());
+  if (!PatternDef) {
+    if (!Complain) {
+      // Say nothing
+    } else if (Pattern == Instantiation->getInstantiatedFromMemberClass()) {
+      Diag(PointOfInstantiation,
+           diag::err_implicit_instantiate_member_undefined)
+        << Context.getTypeDeclType(Instantiation);
+      Diag(Pattern->getLocation(), diag::note_member_of_template_here);
+    } else {
+      Diag(PointOfInstantiation, diag::err_template_instantiate_undefined)
+        << (TSK != TSK_ImplicitInstantiation)
+        << Context.getTypeDeclType(Instantiation);
+      Diag(Pattern->getLocation(), diag::note_template_decl_here);
+    }
+    return true;
+  }
+  Pattern = PatternDef;
+
+  // \brief Record the point of instantiation.
+  if (MemberSpecializationInfo *MSInfo 
+        = Instantiation->getMemberSpecializationInfo()) {
+    MSInfo->setTemplateSpecializationKind(TSK);
+    MSInfo->setPointOfInstantiation(PointOfInstantiation);
+  } else if (ClassTemplateSpecializationDecl *Spec 
+               = dyn_cast<ClassTemplateSpecializationDecl>(Instantiation)) {
+    Spec->setTemplateSpecializationKind(TSK);
+    Spec->setPointOfInstantiation(PointOfInstantiation);
+  }
+  
+  InstantiatingTemplate Inst(*this, PointOfInstantiation, Instantiation);
+  if (Inst)
+    return true;
+
+  // Enter the scope of this instantiation. We don't use
+  // PushDeclContext because we don't have a scope.
+  DeclContext *PreviousContext = CurContext;
+  CurContext = Instantiation;
+
+  // If this is an instantiation of a local class, merge this local
+  // instantiation scope with the enclosing scope. Otherwise, every
+  // instantiation of a class has its own local instantiation scope.
+  bool MergeWithParentScope = !Instantiation->isDefinedOutsideFunctionOrMethod();
+  Sema::LocalInstantiationScope Scope(*this, MergeWithParentScope);
+
+  // Start the definition of this instantiation.
+  Instantiation->startDefinition();
+
+  // Do substitution on the base class specifiers.
+  if (SubstBaseSpecifiers(Instantiation, Pattern, TemplateArgs))
+    Invalid = true;
+
+  llvm::SmallVector<DeclPtrTy, 4> Fields;
+  for (RecordDecl::decl_iterator Member = Pattern->decls_begin(),
+         MemberEnd = Pattern->decls_end();
+       Member != MemberEnd; ++Member) {
+    Decl *NewMember = SubstDecl(*Member, Instantiation, TemplateArgs);
+    if (NewMember) {
+      if (FieldDecl *Field = dyn_cast<FieldDecl>(NewMember))
+        Fields.push_back(DeclPtrTy::make(Field));
+      else if (NewMember->isInvalidDecl())
+        Invalid = true;
+    } else {
+      // FIXME: Eventually, a NULL return will mean that one of the
+      // instantiations was a semantic disaster, and we'll want to set Invalid =
+      // true. For now, we expect to skip some members that we can't yet handle.
+    }
+  }
+
+  // Finish checking fields.
+  ActOnFields(0, Instantiation->getLocation(), DeclPtrTy::make(Instantiation),
+              Fields.data(), Fields.size(), SourceLocation(), SourceLocation(),
+              0);
+  CheckCompletedCXXClass(/*Scope=*/0, Instantiation);
+  if (Instantiation->isInvalidDecl())
+    Invalid = true;
+  
+  // Exit the scope of this instantiation.
+  CurContext = PreviousContext;
+
+  // If this is a polymorphic C++ class without a key function, we'll
+  // have to mark all of the virtual members to allow emission of a vtable
+  // in this translation unit.
+  if (Instantiation->isDynamicClass() &&
+      !Context.getKeyFunction(Instantiation)) {
+    // Local classes need to have their methods instantiated immediately in
+    // order to have the correct instantiation scope.
+    if (Instantiation->isLocalClass()) {
+      MarkVirtualMembersReferenced(PointOfInstantiation,
+                                   Instantiation);
+    } else {
+      ClassesWithUnmarkedVirtualMembers.push_back(std::make_pair(Instantiation,
+                                                       PointOfInstantiation));
+    }
+  }
+
+  if (!Invalid)
+    Consumer.HandleTagDeclDefinition(Instantiation);
+
+  return Invalid;
+}
+
+bool
+Sema::InstantiateClassTemplateSpecialization(
+                           SourceLocation PointOfInstantiation,
+                           ClassTemplateSpecializationDecl *ClassTemplateSpec,
+                           TemplateSpecializationKind TSK,
+                           bool Complain) {
+  // Perform the actual instantiation on the canonical declaration.
+  ClassTemplateSpec = cast<ClassTemplateSpecializationDecl>(
+                                         ClassTemplateSpec->getCanonicalDecl());
+
+  // Check whether we have already instantiated or specialized this class
+  // template specialization.
+  if (ClassTemplateSpec->getSpecializationKind() != TSK_Undeclared) {
+    if (ClassTemplateSpec->getSpecializationKind() == 
+          TSK_ExplicitInstantiationDeclaration &&
+        TSK == TSK_ExplicitInstantiationDefinition) {
+      // An explicit instantiation definition follows an explicit instantiation
+      // declaration (C++0x [temp.explicit]p10); go ahead and perform the
+      // explicit instantiation.
+      ClassTemplateSpec->setSpecializationKind(TSK);
+      return false;
+    }
+    
+    // We can only instantiate something that hasn't already been
+    // instantiated or specialized. Fail without any diagnostics: our
+    // caller will provide an error message.    
+    return true;
+  }
+
+  if (ClassTemplateSpec->isInvalidDecl())
+    return true;
+  
+  ClassTemplateDecl *Template = ClassTemplateSpec->getSpecializedTemplate();
+  CXXRecordDecl *Pattern = 0;
+
+  // C++ [temp.class.spec.match]p1:
+  //   When a class template is used in a context that requires an
+  //   instantiation of the class, it is necessary to determine
+  //   whether the instantiation is to be generated using the primary
+  //   template or one of the partial specializations. This is done by
+  //   matching the template arguments of the class template
+  //   specialization with the template argument lists of the partial
+  //   specializations.
+  typedef std::pair<ClassTemplatePartialSpecializationDecl *,
+                    TemplateArgumentList *> MatchResult;
+  llvm::SmallVector<MatchResult, 4> Matched;
+  for (llvm::FoldingSet<ClassTemplatePartialSpecializationDecl>::iterator
+         Partial = Template->getPartialSpecializations().begin(),
+         PartialEnd = Template->getPartialSpecializations().end();
+       Partial != PartialEnd;
+       ++Partial) {
+    TemplateDeductionInfo Info(Context, PointOfInstantiation);
+    if (TemplateDeductionResult Result
+          = DeduceTemplateArguments(&*Partial,
+                                    ClassTemplateSpec->getTemplateArgs(),
+                                    Info)) {
+      // FIXME: Store the failed-deduction information for use in
+      // diagnostics, later.
+      (void)Result;
+    } else {
+      Matched.push_back(std::make_pair(&*Partial, Info.take()));
+    }
+  }
+
+  if (Matched.size() >= 1) {
+    llvm::SmallVector<MatchResult, 4>::iterator Best = Matched.begin();
+    if (Matched.size() == 1) {
+      //   -- If exactly one matching specialization is found, the
+      //      instantiation is generated from that specialization.
+      // We don't need to do anything for this.
+    } else {
+      //   -- If more than one matching specialization is found, the
+      //      partial order rules (14.5.4.2) are used to determine
+      //      whether one of the specializations is more specialized
+      //      than the others. If none of the specializations is more
+      //      specialized than all of the other matching
+      //      specializations, then the use of the class template is
+      //      ambiguous and the program is ill-formed.
+      for (llvm::SmallVector<MatchResult, 4>::iterator P = Best + 1,
+                                                    PEnd = Matched.end();
+           P != PEnd; ++P) {
+        if (getMoreSpecializedPartialSpecialization(P->first, Best->first,
+                                                    PointOfInstantiation) 
+              == P->first)
+          Best = P;
+      }
+      
+      // Determine if the best partial specialization is more specialized than
+      // the others.
+      bool Ambiguous = false;
+      for (llvm::SmallVector<MatchResult, 4>::iterator P = Matched.begin(),
+                                                    PEnd = Matched.end();
+           P != PEnd; ++P) {
+        if (P != Best &&
+            getMoreSpecializedPartialSpecialization(P->first, Best->first,
+                                                    PointOfInstantiation)
+              != Best->first) {
+          Ambiguous = true;
+          break;
+        }
+      }
+       
+      if (Ambiguous) {
+        // Partial ordering did not produce a clear winner. Complain.
+        ClassTemplateSpec->setInvalidDecl();
+        Diag(PointOfInstantiation, diag::err_partial_spec_ordering_ambiguous)
+          << ClassTemplateSpec;
+        
+        // Print the matching partial specializations.
+        for (llvm::SmallVector<MatchResult, 4>::iterator P = Matched.begin(),
+                                                      PEnd = Matched.end();
+             P != PEnd; ++P)
+          Diag(P->first->getLocation(), diag::note_partial_spec_match)
+            << getTemplateArgumentBindingsText(P->first->getTemplateParameters(),
+                                               *P->second);
+
+        return true;
+      }
+    }
+    
+    // Instantiate using the best class template partial specialization.
+    ClassTemplatePartialSpecializationDecl *OrigPartialSpec = Best->first;
+    while (OrigPartialSpec->getInstantiatedFromMember()) {
+      // If we've found an explicit specialization of this class template,
+      // stop here and use that as the pattern.
+      if (OrigPartialSpec->isMemberSpecialization())
+        break;
+      
+      OrigPartialSpec = OrigPartialSpec->getInstantiatedFromMember();
+    }
+    
+    Pattern = OrigPartialSpec;
+    ClassTemplateSpec->setInstantiationOf(Best->first, Best->second);
+  } else {
+    //   -- If no matches are found, the instantiation is generated
+    //      from the primary template.
+    ClassTemplateDecl *OrigTemplate = Template;
+    while (OrigTemplate->getInstantiatedFromMemberTemplate()) {
+      // If we've found an explicit specialization of this class template,
+      // stop here and use that as the pattern.
+      if (OrigTemplate->isMemberSpecialization())
+        break;
+      
+      OrigTemplate = OrigTemplate->getInstantiatedFromMemberTemplate();
+    }
+    
+    Pattern = OrigTemplate->getTemplatedDecl();
+  }
+
+  bool Result = InstantiateClass(PointOfInstantiation, ClassTemplateSpec, 
+                                 Pattern,
+                                getTemplateInstantiationArgs(ClassTemplateSpec),
+                                 TSK,
+                                 Complain);
+
+  for (unsigned I = 0, N = Matched.size(); I != N; ++I) {
+    // FIXME: Implement TemplateArgumentList::Destroy!
+    //    if (Matched[I].first != Pattern)
+    //      Matched[I].second->Destroy(Context);
+  }
+
+  return Result;
+}
+
+/// \brief Instantiates the definitions of all of the member
+/// of the given class, which is an instantiation of a class template
+/// or a member class of a template.
+void
+Sema::InstantiateClassMembers(SourceLocation PointOfInstantiation,
+                              CXXRecordDecl *Instantiation,
+                        const MultiLevelTemplateArgumentList &TemplateArgs,
+                              TemplateSpecializationKind TSK) {
+  for (DeclContext::decl_iterator D = Instantiation->decls_begin(),
+                               DEnd = Instantiation->decls_end();
+       D != DEnd; ++D) {
+    bool SuppressNew = false;
+    if (FunctionDecl *Function = dyn_cast<FunctionDecl>(*D)) {
+      if (FunctionDecl *Pattern
+            = Function->getInstantiatedFromMemberFunction()) {
+        MemberSpecializationInfo *MSInfo 
+          = Function->getMemberSpecializationInfo();
+        assert(MSInfo && "No member specialization information?");
+        if (MSInfo->getTemplateSpecializationKind()
+                                                 == TSK_ExplicitSpecialization)
+          continue;
+        
+        if (CheckSpecializationInstantiationRedecl(PointOfInstantiation, TSK, 
+                                                   Function, 
+                                        MSInfo->getTemplateSpecializationKind(),
+                                              MSInfo->getPointOfInstantiation(), 
+                                                   SuppressNew) ||
+            SuppressNew)
+          continue;
+        
+        if (Function->getBody())
+          continue;
+
+        if (TSK == TSK_ExplicitInstantiationDefinition) {
+          // C++0x [temp.explicit]p8:
+          //   An explicit instantiation definition that names a class template
+          //   specialization explicitly instantiates the class template 
+          //   specialization and is only an explicit instantiation definition 
+          //   of members whose definition is visible at the point of 
+          //   instantiation.
+          if (!Pattern->getBody())
+            continue;
+        
+          Function->setTemplateSpecializationKind(TSK, PointOfInstantiation);
+                      
+          InstantiateFunctionDefinition(PointOfInstantiation, Function);
+        } else {
+          Function->setTemplateSpecializationKind(TSK, PointOfInstantiation);
+        }
+      }
+    } else if (VarDecl *Var = dyn_cast<VarDecl>(*D)) {
+      if (Var->isStaticDataMember()) {
+        MemberSpecializationInfo *MSInfo = Var->getMemberSpecializationInfo();
+        assert(MSInfo && "No member specialization information?");
+        if (MSInfo->getTemplateSpecializationKind()
+                                                 == TSK_ExplicitSpecialization)
+          continue;
+        
+        if (CheckSpecializationInstantiationRedecl(PointOfInstantiation, TSK, 
+                                                   Var, 
+                                        MSInfo->getTemplateSpecializationKind(),
+                                              MSInfo->getPointOfInstantiation(), 
+                                                   SuppressNew) ||
+            SuppressNew)
+          continue;
+        
+        if (TSK == TSK_ExplicitInstantiationDefinition) {
+          // C++0x [temp.explicit]p8:
+          //   An explicit instantiation definition that names a class template
+          //   specialization explicitly instantiates the class template 
+          //   specialization and is only an explicit instantiation definition 
+          //   of members whose definition is visible at the point of 
+          //   instantiation.
+          if (!Var->getInstantiatedFromStaticDataMember()
+                                                     ->getOutOfLineDefinition())
+            continue;
+          
+          Var->setTemplateSpecializationKind(TSK, PointOfInstantiation);
+          InstantiateStaticDataMemberDefinition(PointOfInstantiation, Var);
+        } else {
+          Var->setTemplateSpecializationKind(TSK, PointOfInstantiation);
+        }
+      }      
+    } else if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(*D)) {
+      // Always skip the injected-class-name, along with any
+      // redeclarations of nested classes, since both would cause us
+      // to try to instantiate the members of a class twice.
+      if (Record->isInjectedClassName() || Record->getPreviousDeclaration())
+        continue;
+      
+      MemberSpecializationInfo *MSInfo = Record->getMemberSpecializationInfo();
+      assert(MSInfo && "No member specialization information?");
+      
+      if (MSInfo->getTemplateSpecializationKind()
+                                                == TSK_ExplicitSpecialization)
+        continue;
+      
+      if (CheckSpecializationInstantiationRedecl(PointOfInstantiation, TSK, 
+                                                 Record, 
+                                        MSInfo->getTemplateSpecializationKind(),
+                                              MSInfo->getPointOfInstantiation(), 
+                                                 SuppressNew) ||
+          SuppressNew)
+        continue;
+      
+      CXXRecordDecl *Pattern = Record->getInstantiatedFromMemberClass();
+      assert(Pattern && "Missing instantiated-from-template information");
+      
+      if (!Record->getDefinition()) {
+        if (!Pattern->getDefinition()) {
+          // C++0x [temp.explicit]p8:
+          //   An explicit instantiation definition that names a class template
+          //   specialization explicitly instantiates the class template 
+          //   specialization and is only an explicit instantiation definition 
+          //   of members whose definition is visible at the point of 
+          //   instantiation.
+          if (TSK == TSK_ExplicitInstantiationDeclaration) {
+            MSInfo->setTemplateSpecializationKind(TSK);
+            MSInfo->setPointOfInstantiation(PointOfInstantiation);
+          }
+          
+          continue;
+        }
+        
+        InstantiateClass(PointOfInstantiation, Record, Pattern,
+                         TemplateArgs,
+                         TSK);
+      }
+      
+      Pattern = cast_or_null<CXXRecordDecl>(Record->getDefinition());
+      if (Pattern)
+        InstantiateClassMembers(PointOfInstantiation, Pattern, TemplateArgs, 
+                                TSK);
+    }
+  }
+}
+
+/// \brief Instantiate the definitions of all of the members of the
+/// given class template specialization, which was named as part of an
+/// explicit instantiation.
+void
+Sema::InstantiateClassTemplateSpecializationMembers(
+                                           SourceLocation PointOfInstantiation,
+                            ClassTemplateSpecializationDecl *ClassTemplateSpec,
+                                               TemplateSpecializationKind TSK) {
+  // C++0x [temp.explicit]p7:
+  //   An explicit instantiation that names a class template
+  //   specialization is an explicit instantion of the same kind
+  //   (declaration or definition) of each of its members (not
+  //   including members inherited from base classes) that has not
+  //   been previously explicitly specialized in the translation unit
+  //   containing the explicit instantiation, except as described
+  //   below.
+  InstantiateClassMembers(PointOfInstantiation, ClassTemplateSpec,
+                          getTemplateInstantiationArgs(ClassTemplateSpec),
+                          TSK);
+}
+
+Sema::OwningStmtResult
+Sema::SubstStmt(Stmt *S, const MultiLevelTemplateArgumentList &TemplateArgs) {
+  if (!S)
+    return Owned(S);
+
+  TemplateInstantiator Instantiator(*this, TemplateArgs,
+                                    SourceLocation(),
+                                    DeclarationName());
+  return Instantiator.TransformStmt(S);
+}
+
+Sema::OwningExprResult
+Sema::SubstExpr(Expr *E, const MultiLevelTemplateArgumentList &TemplateArgs) {
+  if (!E)
+    return Owned(E);
+
+  TemplateInstantiator Instantiator(*this, TemplateArgs,
+                                    SourceLocation(),
+                                    DeclarationName());
+  return Instantiator.TransformExpr(E);
+}
+
+/// \brief Do template substitution on a nested-name-specifier.
+NestedNameSpecifier *
+Sema::SubstNestedNameSpecifier(NestedNameSpecifier *NNS,
+                               SourceRange Range,
+                         const MultiLevelTemplateArgumentList &TemplateArgs) {
+  TemplateInstantiator Instantiator(*this, TemplateArgs, Range.getBegin(),
+                                    DeclarationName());
+  return Instantiator.TransformNestedNameSpecifier(NNS, Range);
+}
+
+TemplateName
+Sema::SubstTemplateName(TemplateName Name, SourceLocation Loc,
+                        const MultiLevelTemplateArgumentList &TemplateArgs) {
+  TemplateInstantiator Instantiator(*this, TemplateArgs, Loc,
+                                    DeclarationName());
+  return Instantiator.TransformTemplateName(Name);
+}
+
+bool Sema::Subst(const TemplateArgumentLoc &Input, TemplateArgumentLoc &Output,
+                 const MultiLevelTemplateArgumentList &TemplateArgs) {
+  TemplateInstantiator Instantiator(*this, TemplateArgs, SourceLocation(),
+                                    DeclarationName());
+
+  return Instantiator.TransformTemplateArgument(Input, Output);
+}
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
new file mode 100644
index 0000000..4575d47
--- /dev/null
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -0,0 +1,2684 @@
+//===--- SemaTemplateInstantiateDecl.cpp - C++ Template Decl Instantiation ===/
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//===----------------------------------------------------------------------===/
+//
+//  This file implements C++ template instantiation for declarations.
+//
+//===----------------------------------------------------------------------===/
+#include "Sema.h"
+#include "Lookup.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/DeclVisitor.h"
+#include "clang/AST/DependentDiagnostic.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/TypeLoc.h"
+#include "clang/Basic/PrettyStackTrace.h"
+#include "clang/Lex/Preprocessor.h"
+
+using namespace clang;
+
+namespace {
+  class TemplateDeclInstantiator
+    : public DeclVisitor<TemplateDeclInstantiator, Decl *> {
+    Sema &SemaRef;
+    DeclContext *Owner;
+    const MultiLevelTemplateArgumentList &TemplateArgs;
+
+    void InstantiateAttrs(Decl *Tmpl, Decl *New);
+      
+  public:
+    typedef Sema::OwningExprResult OwningExprResult;
+
+    TemplateDeclInstantiator(Sema &SemaRef, DeclContext *Owner,
+                             const MultiLevelTemplateArgumentList &TemplateArgs)
+      : SemaRef(SemaRef), Owner(Owner), TemplateArgs(TemplateArgs) { }
+
+    // FIXME: Once we get closer to completion, replace these manually-written
+    // declarations with automatically-generated ones from
+    // clang/AST/DeclNodes.def.
+    Decl *VisitTranslationUnitDecl(TranslationUnitDecl *D);
+    Decl *VisitNamespaceDecl(NamespaceDecl *D);
+    Decl *VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
+    Decl *VisitTypedefDecl(TypedefDecl *D);
+    Decl *VisitVarDecl(VarDecl *D);
+    Decl *VisitFieldDecl(FieldDecl *D);
+    Decl *VisitStaticAssertDecl(StaticAssertDecl *D);
+    Decl *VisitEnumDecl(EnumDecl *D);
+    Decl *VisitEnumConstantDecl(EnumConstantDecl *D);
+    Decl *VisitFriendDecl(FriendDecl *D);
+    Decl *VisitFunctionDecl(FunctionDecl *D,
+                            TemplateParameterList *TemplateParams = 0);
+    Decl *VisitCXXRecordDecl(CXXRecordDecl *D);
+    Decl *VisitCXXMethodDecl(CXXMethodDecl *D,
+                             TemplateParameterList *TemplateParams = 0);
+    Decl *VisitCXXConstructorDecl(CXXConstructorDecl *D);
+    Decl *VisitCXXDestructorDecl(CXXDestructorDecl *D);
+    Decl *VisitCXXConversionDecl(CXXConversionDecl *D);
+    ParmVarDecl *VisitParmVarDecl(ParmVarDecl *D);
+    Decl *VisitClassTemplateDecl(ClassTemplateDecl *D);
+    Decl *VisitClassTemplatePartialSpecializationDecl(
+                                    ClassTemplatePartialSpecializationDecl *D);
+    Decl *VisitFunctionTemplateDecl(FunctionTemplateDecl *D);
+    Decl *VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D);
+    Decl *VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
+    Decl *VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D);
+    Decl *VisitUsingDirectiveDecl(UsingDirectiveDecl *D);
+    Decl *VisitUsingDecl(UsingDecl *D);
+    Decl *VisitUsingShadowDecl(UsingShadowDecl *D);
+    Decl *VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D);
+    Decl *VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D);
+
+    // Base case. FIXME: Remove once we can instantiate everything.
+    Decl *VisitDecl(Decl *D) {
+      unsigned DiagID = SemaRef.getDiagnostics().getCustomDiagID(
+                                                            Diagnostic::Error,
+                                                   "cannot instantiate %0 yet");
+      SemaRef.Diag(D->getLocation(), DiagID)
+        << D->getDeclKindName();
+      
+      return 0;
+    }
+
+    const LangOptions &getLangOptions() {
+      return SemaRef.getLangOptions();
+    }
+
+    // Helper functions for instantiating methods.
+    TypeSourceInfo *SubstFunctionType(FunctionDecl *D,
+                             llvm::SmallVectorImpl<ParmVarDecl *> &Params);
+    bool InitFunctionInstantiation(FunctionDecl *New, FunctionDecl *Tmpl);
+    bool InitMethodInstantiation(CXXMethodDecl *New, CXXMethodDecl *Tmpl);
+
+    TemplateParameterList *
+      SubstTemplateParams(TemplateParameterList *List);
+
+    bool SubstQualifier(const DeclaratorDecl *OldDecl,
+                        DeclaratorDecl *NewDecl);
+    bool SubstQualifier(const TagDecl *OldDecl,
+                        TagDecl *NewDecl);
+      
+    bool InstantiateClassTemplatePartialSpecialization(
+                                              ClassTemplateDecl *ClassTemplate,
+                           ClassTemplatePartialSpecializationDecl *PartialSpec);
+  };
+}
+
+bool TemplateDeclInstantiator::SubstQualifier(const DeclaratorDecl *OldDecl,
+                                              DeclaratorDecl *NewDecl) {
+  NestedNameSpecifier *OldQual = OldDecl->getQualifier();
+  if (!OldQual) return false;
+
+  SourceRange QualRange = OldDecl->getQualifierRange();
+
+  NestedNameSpecifier *NewQual
+    = SemaRef.SubstNestedNameSpecifier(OldQual, QualRange, TemplateArgs);
+  if (!NewQual)
+    return true;
+
+  NewDecl->setQualifierInfo(NewQual, QualRange);
+  return false;
+}
+
+bool TemplateDeclInstantiator::SubstQualifier(const TagDecl *OldDecl,
+                                              TagDecl *NewDecl) {
+  NestedNameSpecifier *OldQual = OldDecl->getQualifier();
+  if (!OldQual) return false;
+
+  SourceRange QualRange = OldDecl->getQualifierRange();
+
+  NestedNameSpecifier *NewQual
+    = SemaRef.SubstNestedNameSpecifier(OldQual, QualRange, TemplateArgs);
+  if (!NewQual)
+    return true;
+
+  NewDecl->setQualifierInfo(NewQual, QualRange);
+  return false;
+}
+
+// FIXME: Is this too simple?
+void TemplateDeclInstantiator::InstantiateAttrs(Decl *Tmpl, Decl *New) {
+  for (const Attr *TmplAttr = Tmpl->getAttrs(); TmplAttr; 
+       TmplAttr = TmplAttr->getNext()) {
+    
+    // FIXME: Is cloning correct for all attributes?
+    Attr *NewAttr = TmplAttr->clone(SemaRef.Context);
+    
+    New->addAttr(NewAttr);
+  }
+}
+
+Decl *
+TemplateDeclInstantiator::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
+  assert(false && "Translation units cannot be instantiated");
+  return D;
+}
+
+Decl *
+TemplateDeclInstantiator::VisitNamespaceDecl(NamespaceDecl *D) {
+  assert(false && "Namespaces cannot be instantiated");
+  return D;
+}
+
+Decl *
+TemplateDeclInstantiator::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
+  NamespaceAliasDecl *Inst
+    = NamespaceAliasDecl::Create(SemaRef.Context, Owner,
+                                 D->getNamespaceLoc(),
+                                 D->getAliasLoc(),
+                                 D->getNamespace()->getIdentifier(),
+                                 D->getQualifierRange(),
+                                 D->getQualifier(),
+                                 D->getTargetNameLoc(),
+                                 D->getNamespace());
+  Owner->addDecl(Inst);
+  return Inst;
+}
+
+Decl *TemplateDeclInstantiator::VisitTypedefDecl(TypedefDecl *D) {
+  bool Invalid = false;
+  TypeSourceInfo *DI = D->getTypeSourceInfo();
+  if (DI->getType()->isDependentType()) {
+    DI = SemaRef.SubstType(DI, TemplateArgs,
+                           D->getLocation(), D->getDeclName());
+    if (!DI) {
+      Invalid = true;
+      DI = SemaRef.Context.getTrivialTypeSourceInfo(SemaRef.Context.IntTy);
+    }
+  }
+
+  // Create the new typedef
+  TypedefDecl *Typedef
+    = TypedefDecl::Create(SemaRef.Context, Owner, D->getLocation(),
+                          D->getIdentifier(), DI);
+  if (Invalid)
+    Typedef->setInvalidDecl();
+
+  if (const TagType *TT = DI->getType()->getAs<TagType>()) {
+    TagDecl *TD = TT->getDecl();
+    
+    // If the TagDecl that the TypedefDecl points to is an anonymous decl
+    // keep track of the TypedefDecl.
+    if (!TD->getIdentifier() && !TD->getTypedefForAnonDecl())
+      TD->setTypedefForAnonDecl(Typedef);
+  }
+  
+  if (TypedefDecl *Prev = D->getPreviousDeclaration()) {
+    NamedDecl *InstPrev = SemaRef.FindInstantiatedDecl(D->getLocation(), Prev,
+                                                       TemplateArgs);
+    Typedef->setPreviousDeclaration(cast<TypedefDecl>(InstPrev));
+  }
+
+
+  Typedef->setAccess(D->getAccess());
+  Owner->addDecl(Typedef);
+
+  return Typedef;
+}
+
+/// \brief Instantiate the arguments provided as part of initialization.
+///
+/// \returns true if an error occurred, false otherwise.
+static bool InstantiateInitializationArguments(Sema &SemaRef,
+                                               Expr **Args, unsigned NumArgs,
+                           const MultiLevelTemplateArgumentList &TemplateArgs,
+                         llvm::SmallVectorImpl<SourceLocation> &FakeCommaLocs,
+                           ASTOwningVector<&ActionBase::DeleteExpr> &InitArgs) {
+  for (unsigned I = 0; I != NumArgs; ++I) {
+    // When we hit the first defaulted argument, break out of the loop:
+    // we don't pass those default arguments on.
+    if (Args[I]->isDefaultArgument())
+      break;
+  
+    Sema::OwningExprResult Arg = SemaRef.SubstExpr(Args[I], TemplateArgs);
+    if (Arg.isInvalid())
+      return true;
+  
+    Expr *ArgExpr = (Expr *)Arg.get();
+    InitArgs.push_back(Arg.release());
+    
+    // FIXME: We're faking all of the comma locations. Do we need them?
+    FakeCommaLocs.push_back(
+                          SemaRef.PP.getLocForEndOfToken(ArgExpr->getLocEnd()));
+  }
+  
+  return false;
+}
+
+/// \brief Instantiate an initializer, breaking it into separate
+/// initialization arguments.
+///
+/// \param S The semantic analysis object.
+///
+/// \param Init The initializer to instantiate.
+///
+/// \param TemplateArgs Template arguments to be substituted into the
+/// initializer.
+///
+/// \param NewArgs Will be filled in with the instantiation arguments.
+///
+/// \returns true if an error occurred, false otherwise
+static bool InstantiateInitializer(Sema &S, Expr *Init,
+                            const MultiLevelTemplateArgumentList &TemplateArgs,
+                                   SourceLocation &LParenLoc,
+                               llvm::SmallVector<SourceLocation, 4> &CommaLocs,
+                             ASTOwningVector<&ActionBase::DeleteExpr> &NewArgs,
+                                   SourceLocation &RParenLoc) {
+  NewArgs.clear();
+  LParenLoc = SourceLocation();
+  RParenLoc = SourceLocation();
+
+  if (!Init)
+    return false;
+
+  if (CXXExprWithTemporaries *ExprTemp = dyn_cast<CXXExprWithTemporaries>(Init))
+    Init = ExprTemp->getSubExpr();
+
+  while (CXXBindTemporaryExpr *Binder = dyn_cast<CXXBindTemporaryExpr>(Init))
+    Init = Binder->getSubExpr();
+
+  if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Init))
+    Init = ICE->getSubExprAsWritten();
+
+  if (ParenListExpr *ParenList = dyn_cast<ParenListExpr>(Init)) {
+    LParenLoc = ParenList->getLParenLoc();
+    RParenLoc = ParenList->getRParenLoc();
+    return InstantiateInitializationArguments(S, ParenList->getExprs(),
+                                              ParenList->getNumExprs(),
+                                              TemplateArgs, CommaLocs, 
+                                              NewArgs);
+  }
+
+  if (CXXConstructExpr *Construct = dyn_cast<CXXConstructExpr>(Init)) {
+    if (!isa<CXXTemporaryObjectExpr>(Construct)) {
+      if (InstantiateInitializationArguments(S,
+                                             Construct->getArgs(),
+                                             Construct->getNumArgs(),
+                                             TemplateArgs,
+                                             CommaLocs, NewArgs))
+        return true;
+
+      // FIXME: Fake locations!
+      LParenLoc = S.PP.getLocForEndOfToken(Init->getLocStart());
+      RParenLoc = CommaLocs.empty()? LParenLoc : CommaLocs.back();
+      return false;
+    }
+  }
+ 
+  Sema::OwningExprResult Result = S.SubstExpr(Init, TemplateArgs);
+  if (Result.isInvalid())
+    return true;
+
+  NewArgs.push_back(Result.takeAs<Expr>());
+  return false;
+}
+
+Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) {
+  // Do substitution on the type of the declaration
+  TypeSourceInfo *DI = SemaRef.SubstType(D->getTypeSourceInfo(),
+                                         TemplateArgs,
+                                         D->getTypeSpecStartLoc(),
+                                         D->getDeclName());
+  if (!DI)
+    return 0;
+
+  // Build the instantiated declaration
+  VarDecl *Var = VarDecl::Create(SemaRef.Context, Owner,
+                                 D->getLocation(), D->getIdentifier(),
+                                 DI->getType(), DI,
+                                 D->getStorageClass(),
+                                 D->getStorageClassAsWritten());
+  Var->setThreadSpecified(D->isThreadSpecified());
+  Var->setCXXDirectInitializer(D->hasCXXDirectInitializer());
+  Var->setDeclaredInCondition(D->isDeclaredInCondition());
+
+  // Substitute the nested name specifier, if any.
+  if (SubstQualifier(D, Var))
+    return 0;
+
+  // If we are instantiating a static data member defined
+  // out-of-line, the instantiation will have the same lexical
+  // context (which will be a namespace scope) as the template.
+  if (D->isOutOfLine())
+    Var->setLexicalDeclContext(D->getLexicalDeclContext());
+
+  Var->setAccess(D->getAccess());
+
+  // FIXME: In theory, we could have a previous declaration for variables that
+  // are not static data members.
+  bool Redeclaration = false;
+  // FIXME: having to fake up a LookupResult is dumb.
+  LookupResult Previous(SemaRef, Var->getDeclName(), Var->getLocation(),
+                        Sema::LookupOrdinaryName, Sema::ForRedeclaration);
+  if (D->isStaticDataMember())
+    SemaRef.LookupQualifiedName(Previous, Owner, false);
+  SemaRef.CheckVariableDeclaration(Var, Previous, Redeclaration);
+
+  if (D->isOutOfLine()) {
+    D->getLexicalDeclContext()->addDecl(Var);
+    Owner->makeDeclVisibleInContext(Var);
+  } else {
+    Owner->addDecl(Var);
+  }
+
+  // Link instantiations of static data members back to the template from
+  // which they were instantiated.
+  if (Var->isStaticDataMember())
+    SemaRef.Context.setInstantiatedFromStaticDataMember(Var, D, 
+                                                     TSK_ImplicitInstantiation);
+  
+  if (Var->getAnyInitializer()) {
+    // We already have an initializer in the class.
+  } else if (D->getInit()) {
+    if (Var->isStaticDataMember() && !D->isOutOfLine())
+      SemaRef.PushExpressionEvaluationContext(Sema::Unevaluated);
+    else
+      SemaRef.PushExpressionEvaluationContext(Sema::PotentiallyEvaluated);
+
+    // Instantiate the initializer.
+    SourceLocation LParenLoc, RParenLoc;
+    llvm::SmallVector<SourceLocation, 4> CommaLocs;
+    ASTOwningVector<&ActionBase::DeleteExpr> InitArgs(SemaRef);
+    if (!InstantiateInitializer(SemaRef, D->getInit(), TemplateArgs, LParenLoc,
+                                CommaLocs, InitArgs, RParenLoc)) {
+      // Attach the initializer to the declaration.
+      if (D->hasCXXDirectInitializer()) {
+        // Add the direct initializer to the declaration.
+        SemaRef.AddCXXDirectInitializerToDecl(Sema::DeclPtrTy::make(Var),
+                                              LParenLoc,
+                                              move_arg(InitArgs),
+                                              CommaLocs.data(),
+                                              RParenLoc);
+      } else if (InitArgs.size() == 1) {
+        Expr *Init = (Expr*)(InitArgs.take()[0]);
+        SemaRef.AddInitializerToDecl(Sema::DeclPtrTy::make(Var), 
+                                     SemaRef.Owned(Init),
+                                     false);        
+      } else {
+        assert(InitArgs.size() == 0);
+        SemaRef.ActOnUninitializedDecl(Sema::DeclPtrTy::make(Var), false);    
+      }
+    } else {
+      // FIXME: Not too happy about invalidating the declaration
+      // because of a bogus initializer.
+      Var->setInvalidDecl();
+    }
+    
+    SemaRef.PopExpressionEvaluationContext();
+  } else if (!Var->isStaticDataMember() || Var->isOutOfLine())
+    SemaRef.ActOnUninitializedDecl(Sema::DeclPtrTy::make(Var), false);
+
+  return Var;
+}
+
+Decl *TemplateDeclInstantiator::VisitFieldDecl(FieldDecl *D) {
+  bool Invalid = false;
+  TypeSourceInfo *DI = D->getTypeSourceInfo();
+  if (DI->getType()->isDependentType())  {
+    DI = SemaRef.SubstType(DI, TemplateArgs,
+                           D->getLocation(), D->getDeclName());
+    if (!DI) {
+      DI = D->getTypeSourceInfo();
+      Invalid = true;
+    } else if (DI->getType()->isFunctionType()) {
+      // C++ [temp.arg.type]p3:
+      //   If a declaration acquires a function type through a type
+      //   dependent on a template-parameter and this causes a
+      //   declaration that does not use the syntactic form of a
+      //   function declarator to have function type, the program is
+      //   ill-formed.
+      SemaRef.Diag(D->getLocation(), diag::err_field_instantiates_to_function)
+        << DI->getType();
+      Invalid = true;
+    }
+  }
+
+  Expr *BitWidth = D->getBitWidth();
+  if (Invalid)
+    BitWidth = 0;
+  else if (BitWidth) {
+    // The bit-width expression is not potentially evaluated.
+    EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
+
+    OwningExprResult InstantiatedBitWidth
+      = SemaRef.SubstExpr(BitWidth, TemplateArgs);
+    if (InstantiatedBitWidth.isInvalid()) {
+      Invalid = true;
+      BitWidth = 0;
+    } else
+      BitWidth = InstantiatedBitWidth.takeAs<Expr>();
+  }
+
+  FieldDecl *Field = SemaRef.CheckFieldDecl(D->getDeclName(),
+                                            DI->getType(), DI,
+                                            cast<RecordDecl>(Owner),
+                                            D->getLocation(),
+                                            D->isMutable(),
+                                            BitWidth,
+                                            D->getTypeSpecStartLoc(),
+                                            D->getAccess(),
+                                            0);
+  if (!Field) {
+    cast<Decl>(Owner)->setInvalidDecl();
+    return 0;
+  }
+
+  InstantiateAttrs(D, Field);
+  
+  if (Invalid)
+    Field->setInvalidDecl();
+
+  if (!Field->getDeclName()) {
+    // Keep track of where this decl came from.
+    SemaRef.Context.setInstantiatedFromUnnamedFieldDecl(Field, D);
+  }
+
+  Field->setImplicit(D->isImplicit());
+  Field->setAccess(D->getAccess());
+  Owner->addDecl(Field);
+
+  return Field;
+}
+
+Decl *TemplateDeclInstantiator::VisitFriendDecl(FriendDecl *D) {
+  // Handle friend type expressions by simply substituting template
+  // parameters into the pattern type and checking the result.
+  if (TypeSourceInfo *Ty = D->getFriendType()) {
+    TypeSourceInfo *InstTy = 
+      SemaRef.SubstType(Ty, TemplateArgs,
+                        D->getLocation(), DeclarationName());
+    if (!InstTy) 
+      return 0;
+
+    FriendDecl *FD = SemaRef.CheckFriendTypeDecl(D->getFriendLoc(), InstTy);
+    if (!FD)
+      return 0;
+    
+    FD->setAccess(AS_public);
+    Owner->addDecl(FD);
+    return FD;
+  } 
+  
+  NamedDecl *ND = D->getFriendDecl();
+  assert(ND && "friend decl must be a decl or a type!");
+
+  // All of the Visit implementations for the various potential friend
+  // declarations have to be carefully written to work for friend
+  // objects, with the most important detail being that the target
+  // decl should almost certainly not be placed in Owner.
+  Decl *NewND = Visit(ND);
+  if (!NewND) return 0;
+
+  FriendDecl *FD =
+    FriendDecl::Create(SemaRef.Context, Owner, D->getLocation(), 
+                       cast<NamedDecl>(NewND), D->getFriendLoc());
+  FD->setAccess(AS_public);
+  Owner->addDecl(FD);
+  return FD;
+}
+
+Decl *TemplateDeclInstantiator::VisitStaticAssertDecl(StaticAssertDecl *D) {
+  Expr *AssertExpr = D->getAssertExpr();
+
+  // The expression in a static assertion is not potentially evaluated.
+  EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
+
+  OwningExprResult InstantiatedAssertExpr
+    = SemaRef.SubstExpr(AssertExpr, TemplateArgs);
+  if (InstantiatedAssertExpr.isInvalid())
+    return 0;
+
+  OwningExprResult Message(SemaRef, D->getMessage());
+  D->getMessage()->Retain();
+  Decl *StaticAssert
+    = SemaRef.ActOnStaticAssertDeclaration(D->getLocation(),
+                                           move(InstantiatedAssertExpr),
+                                           move(Message)).getAs<Decl>();
+  return StaticAssert;
+}
+
+Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) {
+  EnumDecl *Enum = EnumDecl::Create(SemaRef.Context, Owner,
+                                    D->getLocation(), D->getIdentifier(),
+                                    D->getTagKeywordLoc(),
+                                    /*PrevDecl=*/0);
+  Enum->setInstantiationOfMemberEnum(D);
+  Enum->setAccess(D->getAccess());
+  if (SubstQualifier(D, Enum)) return 0;
+  Owner->addDecl(Enum);
+  Enum->startDefinition();
+
+  if (D->getDeclContext()->isFunctionOrMethod())
+    SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Enum);
+    
+  llvm::SmallVector<Sema::DeclPtrTy, 4> Enumerators;
+
+  EnumConstantDecl *LastEnumConst = 0;
+  for (EnumDecl::enumerator_iterator EC = D->enumerator_begin(),
+         ECEnd = D->enumerator_end();
+       EC != ECEnd; ++EC) {
+    // The specified value for the enumerator.
+    OwningExprResult Value = SemaRef.Owned((Expr *)0);
+    if (Expr *UninstValue = EC->getInitExpr()) {
+      // The enumerator's value expression is not potentially evaluated.
+      EnterExpressionEvaluationContext Unevaluated(SemaRef,
+                                                   Action::Unevaluated);
+
+      Value = SemaRef.SubstExpr(UninstValue, TemplateArgs);
+    }
+
+    // Drop the initial value and continue.
+    bool isInvalid = false;
+    if (Value.isInvalid()) {
+      Value = SemaRef.Owned((Expr *)0);
+      isInvalid = true;
+    }
+
+    EnumConstantDecl *EnumConst
+      = SemaRef.CheckEnumConstant(Enum, LastEnumConst,
+                                  EC->getLocation(), EC->getIdentifier(),
+                                  move(Value));
+
+    if (isInvalid) {
+      if (EnumConst)
+        EnumConst->setInvalidDecl();
+      Enum->setInvalidDecl();
+    }
+
+    if (EnumConst) {
+      EnumConst->setAccess(Enum->getAccess());
+      Enum->addDecl(EnumConst);
+      Enumerators.push_back(Sema::DeclPtrTy::make(EnumConst));
+      LastEnumConst = EnumConst;
+      
+      if (D->getDeclContext()->isFunctionOrMethod()) {
+        // If the enumeration is within a function or method, record the enum
+        // constant as a local.
+        SemaRef.CurrentInstantiationScope->InstantiatedLocal(*EC, EnumConst);
+      }
+    }
+  }
+
+  // FIXME: Fixup LBraceLoc and RBraceLoc
+  // FIXME: Empty Scope and AttributeList (required to handle attribute packed).
+  SemaRef.ActOnEnumBody(Enum->getLocation(), SourceLocation(), SourceLocation(),
+                        Sema::DeclPtrTy::make(Enum),
+                        &Enumerators[0], Enumerators.size(),
+                        0, 0);
+
+  return Enum;
+}
+
+Decl *TemplateDeclInstantiator::VisitEnumConstantDecl(EnumConstantDecl *D) {
+  assert(false && "EnumConstantDecls can only occur within EnumDecls.");
+  return 0;
+}
+
+namespace {
+  class SortDeclByLocation {
+    SourceManager &SourceMgr;
+    
+  public:
+    explicit SortDeclByLocation(SourceManager &SourceMgr) 
+      : SourceMgr(SourceMgr) { }
+    
+    bool operator()(const Decl *X, const Decl *Y) const {
+      return SourceMgr.isBeforeInTranslationUnit(X->getLocation(),
+                                                 Y->getLocation());
+    }
+  };
+}
+
+Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) {
+  bool isFriend = (D->getFriendObjectKind() != Decl::FOK_None);
+
+  // Create a local instantiation scope for this class template, which
+  // will contain the instantiations of the template parameters.
+  Sema::LocalInstantiationScope Scope(SemaRef);
+  TemplateParameterList *TempParams = D->getTemplateParameters();
+  TemplateParameterList *InstParams = SubstTemplateParams(TempParams);
+  if (!InstParams)
+    return NULL;
+
+  CXXRecordDecl *Pattern = D->getTemplatedDecl();
+
+  // Instantiate the qualifier.  We have to do this first in case
+  // we're a friend declaration, because if we are then we need to put
+  // the new declaration in the appropriate context.
+  NestedNameSpecifier *Qualifier = Pattern->getQualifier();
+  if (Qualifier) {
+    Qualifier = SemaRef.SubstNestedNameSpecifier(Qualifier,
+                                                 Pattern->getQualifierRange(),
+                                                 TemplateArgs);
+    if (!Qualifier) return 0;
+  }
+
+  CXXRecordDecl *PrevDecl = 0;
+  ClassTemplateDecl *PrevClassTemplate = 0;
+
+  // If this isn't a friend, then it's a member template, in which
+  // case we just want to build the instantiation in the
+  // specialization.  If it is a friend, we want to build it in
+  // the appropriate context.
+  DeclContext *DC = Owner;
+  if (isFriend) {
+    if (Qualifier) {
+      CXXScopeSpec SS;
+      SS.setScopeRep(Qualifier);
+      SS.setRange(Pattern->getQualifierRange());
+      DC = SemaRef.computeDeclContext(SS);
+      if (!DC) return 0;
+    } else {
+      DC = SemaRef.FindInstantiatedContext(Pattern->getLocation(),
+                                           Pattern->getDeclContext(),
+                                           TemplateArgs);
+    }
+
+    // Look for a previous declaration of the template in the owning
+    // context.
+    LookupResult R(SemaRef, Pattern->getDeclName(), Pattern->getLocation(),
+                   Sema::LookupOrdinaryName, Sema::ForRedeclaration);
+    SemaRef.LookupQualifiedName(R, DC);
+
+    if (R.isSingleResult()) {
+      PrevClassTemplate = R.getAsSingle<ClassTemplateDecl>();
+      if (PrevClassTemplate)
+        PrevDecl = PrevClassTemplate->getTemplatedDecl();
+    }
+
+    if (!PrevClassTemplate && Qualifier) {
+      SemaRef.Diag(Pattern->getLocation(), diag::err_not_tag_in_scope)
+        << D->getTemplatedDecl()->getTagKind() << Pattern->getDeclName() << DC
+        << Pattern->getQualifierRange();
+      return 0;
+    }
+
+    bool AdoptedPreviousTemplateParams = false;
+    if (PrevClassTemplate) {
+      bool Complain = true;
+
+      // HACK: libstdc++ 4.2.1 contains an ill-formed friend class
+      // template for struct std::tr1::__detail::_Map_base, where the
+      // template parameters of the friend declaration don't match the
+      // template parameters of the original declaration. In this one
+      // case, we don't complain about the ill-formed friend
+      // declaration.
+      if (isFriend && Pattern->getIdentifier() && 
+          Pattern->getIdentifier()->isStr("_Map_base") &&
+          DC->isNamespace() &&
+          cast<NamespaceDecl>(DC)->getIdentifier() &&
+          cast<NamespaceDecl>(DC)->getIdentifier()->isStr("__detail")) {
+        DeclContext *DCParent = DC->getParent();
+        if (DCParent->isNamespace() &&
+            cast<NamespaceDecl>(DCParent)->getIdentifier() &&
+            cast<NamespaceDecl>(DCParent)->getIdentifier()->isStr("tr1")) {
+          DeclContext *DCParent2 = DCParent->getParent();
+          if (DCParent2->isNamespace() &&
+              cast<NamespaceDecl>(DCParent2)->getIdentifier() &&
+              cast<NamespaceDecl>(DCParent2)->getIdentifier()->isStr("std") &&
+              DCParent2->getParent()->isTranslationUnit())
+            Complain = false;
+        }
+      }
+
+      TemplateParameterList *PrevParams
+        = PrevClassTemplate->getTemplateParameters();
+
+      // Make sure the parameter lists match.
+      if (!SemaRef.TemplateParameterListsAreEqual(InstParams, PrevParams,
+                                                  Complain, 
+                                                  Sema::TPL_TemplateMatch)) {
+        if (Complain)
+          return 0;
+
+        AdoptedPreviousTemplateParams = true;
+        InstParams = PrevParams;
+      }
+
+      // Do some additional validation, then merge default arguments
+      // from the existing declarations.
+      if (!AdoptedPreviousTemplateParams &&
+          SemaRef.CheckTemplateParameterList(InstParams, PrevParams,
+                                             Sema::TPC_ClassTemplate))
+        return 0;
+    }
+  }
+
+  CXXRecordDecl *RecordInst
+    = CXXRecordDecl::Create(SemaRef.Context, Pattern->getTagKind(), DC,
+                            Pattern->getLocation(), Pattern->getIdentifier(),
+                            Pattern->getTagKeywordLoc(), PrevDecl,
+                            /*DelayTypeCreation=*/true);
+
+  if (Qualifier)
+    RecordInst->setQualifierInfo(Qualifier, Pattern->getQualifierRange());
+
+  ClassTemplateDecl *Inst
+    = ClassTemplateDecl::Create(SemaRef.Context, DC, D->getLocation(),
+                                D->getIdentifier(), InstParams, RecordInst,
+                                PrevClassTemplate);
+  RecordInst->setDescribedClassTemplate(Inst);
+
+  if (isFriend) {
+    if (PrevClassTemplate)
+      Inst->setAccess(PrevClassTemplate->getAccess());
+    else
+      Inst->setAccess(D->getAccess());
+
+    Inst->setObjectOfFriendDecl(PrevClassTemplate != 0);
+    // TODO: do we want to track the instantiation progeny of this
+    // friend target decl?
+  } else {
+    Inst->setAccess(D->getAccess());
+    Inst->setInstantiatedFromMemberTemplate(D);
+  }
+  
+  // Trigger creation of the type for the instantiation.
+  SemaRef.Context.getInjectedClassNameType(RecordInst,
+                  Inst->getInjectedClassNameSpecialization(SemaRef.Context));
+
+  // Finish handling of friends.
+  if (isFriend) {
+    DC->makeDeclVisibleInContext(Inst, /*Recoverable*/ false);
+    return Inst;
+  }
+  
+  Owner->addDecl(Inst);
+  
+  // First, we sort the partial specializations by location, so 
+  // that we instantiate them in the order they were declared.
+  llvm::SmallVector<ClassTemplatePartialSpecializationDecl *, 4> PartialSpecs;
+  for (llvm::FoldingSet<ClassTemplatePartialSpecializationDecl>::iterator
+         P = D->getPartialSpecializations().begin(), 
+         PEnd = D->getPartialSpecializations().end();
+       P != PEnd; ++P)
+    PartialSpecs.push_back(&*P);
+  std::sort(PartialSpecs.begin(), PartialSpecs.end(),
+            SortDeclByLocation(SemaRef.SourceMgr));
+  
+  // Instantiate all of the partial specializations of this member class 
+  // template.
+  for (unsigned I = 0, N = PartialSpecs.size(); I != N; ++I)
+    InstantiateClassTemplatePartialSpecialization(Inst, PartialSpecs[I]);
+  
+  return Inst;
+}
+
+Decl *
+TemplateDeclInstantiator::VisitClassTemplatePartialSpecializationDecl(
+                                   ClassTemplatePartialSpecializationDecl *D) {
+  ClassTemplateDecl *ClassTemplate = D->getSpecializedTemplate();
+  
+  // Lookup the already-instantiated declaration in the instantiation
+  // of the class template and return that.
+  DeclContext::lookup_result Found
+    = Owner->lookup(ClassTemplate->getDeclName());
+  if (Found.first == Found.second)
+    return 0;
+  
+  ClassTemplateDecl *InstClassTemplate
+    = dyn_cast<ClassTemplateDecl>(*Found.first);
+  if (!InstClassTemplate)
+    return 0;
+  
+  Decl *DCanon = D->getCanonicalDecl();
+  for (llvm::FoldingSet<ClassTemplatePartialSpecializationDecl>::iterator
+            P = InstClassTemplate->getPartialSpecializations().begin(),
+         PEnd = InstClassTemplate->getPartialSpecializations().end();
+       P != PEnd; ++P) {
+    if (P->getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
+      return &*P;
+  }
+  
+  return 0;
+}
+
+Decl *
+TemplateDeclInstantiator::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
+  // Create a local instantiation scope for this function template, which
+  // will contain the instantiations of the template parameters and then get
+  // merged with the local instantiation scope for the function template 
+  // itself.
+  Sema::LocalInstantiationScope Scope(SemaRef);
+  
+  TemplateParameterList *TempParams = D->getTemplateParameters();
+  TemplateParameterList *InstParams = SubstTemplateParams(TempParams);
+  if (!InstParams)
+    return NULL;
+  
+  FunctionDecl *Instantiated = 0;
+  if (CXXMethodDecl *DMethod = dyn_cast<CXXMethodDecl>(D->getTemplatedDecl()))
+    Instantiated = cast_or_null<FunctionDecl>(VisitCXXMethodDecl(DMethod, 
+                                                                 InstParams));
+  else
+    Instantiated = cast_or_null<FunctionDecl>(VisitFunctionDecl(
+                                                          D->getTemplatedDecl(), 
+                                                                InstParams));
+  
+  if (!Instantiated)
+    return 0;
+
+  Instantiated->setAccess(D->getAccess());
+
+  // Link the instantiated function template declaration to the function
+  // template from which it was instantiated.
+  FunctionTemplateDecl *InstTemplate 
+    = Instantiated->getDescribedFunctionTemplate();
+  InstTemplate->setAccess(D->getAccess());
+  assert(InstTemplate && 
+         "VisitFunctionDecl/CXXMethodDecl didn't create a template!");
+
+  bool isFriend = (InstTemplate->getFriendObjectKind() != Decl::FOK_None);
+
+  // Link the instantiation back to the pattern *unless* this is a
+  // non-definition friend declaration.
+  if (!InstTemplate->getInstantiatedFromMemberTemplate() &&
+      !(isFriend && !D->getTemplatedDecl()->isThisDeclarationADefinition()))
+    InstTemplate->setInstantiatedFromMemberTemplate(D);
+  
+  // Make declarations visible in the appropriate context.
+  if (!isFriend)
+    Owner->addDecl(InstTemplate);
+
+  return InstTemplate;
+}
+
+Decl *TemplateDeclInstantiator::VisitCXXRecordDecl(CXXRecordDecl *D) {
+  CXXRecordDecl *PrevDecl = 0;
+  if (D->isInjectedClassName())
+    PrevDecl = cast<CXXRecordDecl>(Owner);
+  else if (D->getPreviousDeclaration()) {
+    NamedDecl *Prev = SemaRef.FindInstantiatedDecl(D->getLocation(),
+                                                   D->getPreviousDeclaration(),
+                                                   TemplateArgs);
+    if (!Prev) return 0;
+    PrevDecl = cast<CXXRecordDecl>(Prev);
+  }
+
+  CXXRecordDecl *Record
+    = CXXRecordDecl::Create(SemaRef.Context, D->getTagKind(), Owner,
+                            D->getLocation(), D->getIdentifier(),
+                            D->getTagKeywordLoc(), PrevDecl);
+
+  // Substitute the nested name specifier, if any.
+  if (SubstQualifier(D, Record))
+    return 0;
+
+  Record->setImplicit(D->isImplicit());
+  // FIXME: Check against AS_none is an ugly hack to work around the issue that
+  // the tag decls introduced by friend class declarations don't have an access
+  // specifier. Remove once this area of the code gets sorted out.
+  if (D->getAccess() != AS_none)
+    Record->setAccess(D->getAccess());
+  if (!D->isInjectedClassName())
+    Record->setInstantiationOfMemberClass(D, TSK_ImplicitInstantiation);
+
+  // If the original function was part of a friend declaration,
+  // inherit its namespace state.
+  if (Decl::FriendObjectKind FOK = D->getFriendObjectKind())
+    Record->setObjectOfFriendDecl(FOK == Decl::FOK_Declared);
+
+  Record->setAnonymousStructOrUnion(D->isAnonymousStructOrUnion());
+
+  Owner->addDecl(Record);
+  return Record;
+}
+
+/// Normal class members are of more specific types and therefore
+/// don't make it here.  This function serves two purposes:
+///   1) instantiating function templates
+///   2) substituting friend declarations
+/// FIXME: preserve function definitions in case #2
+Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
+                                       TemplateParameterList *TemplateParams) {
+  // Check whether there is already a function template specialization for
+  // this declaration.
+  FunctionTemplateDecl *FunctionTemplate = D->getDescribedFunctionTemplate();
+  void *InsertPos = 0;
+  if (FunctionTemplate && !TemplateParams) {
+    llvm::FoldingSetNodeID ID;
+    FunctionTemplateSpecializationInfo::Profile(ID,
+                             TemplateArgs.getInnermost().getFlatArgumentList(),
+                                       TemplateArgs.getInnermost().flat_size(),
+                                                SemaRef.Context);
+
+    FunctionTemplateSpecializationInfo *Info
+      = FunctionTemplate->getSpecializations().FindNodeOrInsertPos(ID,
+                                                                   InsertPos);
+
+    // If we already have a function template specialization, return it.
+    if (Info)
+      return Info->Function;
+  }
+
+  bool isFriend;
+  if (FunctionTemplate)
+    isFriend = (FunctionTemplate->getFriendObjectKind() != Decl::FOK_None);
+  else
+    isFriend = (D->getFriendObjectKind() != Decl::FOK_None);
+
+  bool MergeWithParentScope = (TemplateParams != 0) ||
+    !(isa<Decl>(Owner) && 
+      cast<Decl>(Owner)->isDefinedOutsideFunctionOrMethod());
+  Sema::LocalInstantiationScope Scope(SemaRef, MergeWithParentScope);
+
+  llvm::SmallVector<ParmVarDecl *, 4> Params;
+  TypeSourceInfo *TInfo = D->getTypeSourceInfo();
+  TInfo = SubstFunctionType(D, Params);
+  if (!TInfo)
+    return 0;
+  QualType T = TInfo->getType();
+
+  NestedNameSpecifier *Qualifier = D->getQualifier();
+  if (Qualifier) {
+    Qualifier = SemaRef.SubstNestedNameSpecifier(Qualifier,
+                                                 D->getQualifierRange(),
+                                                 TemplateArgs);
+    if (!Qualifier) return 0;
+  }
+
+  // If we're instantiating a local function declaration, put the result
+  // in the owner;  otherwise we need to find the instantiated context.
+  DeclContext *DC;
+  if (D->getDeclContext()->isFunctionOrMethod())
+    DC = Owner;
+  else if (isFriend && Qualifier) {
+    CXXScopeSpec SS;
+    SS.setScopeRep(Qualifier);
+    SS.setRange(D->getQualifierRange());
+    DC = SemaRef.computeDeclContext(SS);
+    if (!DC) return 0;
+  } else {
+    DC = SemaRef.FindInstantiatedContext(D->getLocation(), D->getDeclContext(), 
+                                         TemplateArgs);
+  }
+
+  FunctionDecl *Function =
+      FunctionDecl::Create(SemaRef.Context, DC, D->getLocation(),
+                           D->getDeclName(), T, TInfo,
+                           D->getStorageClass(), D->getStorageClassAsWritten(),
+                           D->isInlineSpecified(), D->hasWrittenPrototype());
+
+  if (Qualifier)
+    Function->setQualifierInfo(Qualifier, D->getQualifierRange());
+
+  DeclContext *LexicalDC = Owner;
+  if (!isFriend && D->isOutOfLine()) {
+    assert(D->getDeclContext()->isFileContext());
+    LexicalDC = D->getDeclContext();
+  }
+
+  Function->setLexicalDeclContext(LexicalDC);
+
+  // Attach the parameters
+  for (unsigned P = 0; P < Params.size(); ++P)
+    Params[P]->setOwningFunction(Function);
+  Function->setParams(Params.data(), Params.size());
+
+  if (TemplateParams) {
+    // Our resulting instantiation is actually a function template, since we
+    // are substituting only the outer template parameters. For example, given
+    //
+    //   template<typename T>
+    //   struct X {
+    //     template<typename U> friend void f(T, U);
+    //   };
+    //
+    //   X<int> x;
+    //
+    // We are instantiating the friend function template "f" within X<int>, 
+    // which means substituting int for T, but leaving "f" as a friend function
+    // template.
+    // Build the function template itself.
+    FunctionTemplate = FunctionTemplateDecl::Create(SemaRef.Context, DC,
+                                                    Function->getLocation(),
+                                                    Function->getDeclName(),
+                                                    TemplateParams, Function);
+    Function->setDescribedFunctionTemplate(FunctionTemplate);
+
+    FunctionTemplate->setLexicalDeclContext(LexicalDC);
+
+    if (isFriend && D->isThisDeclarationADefinition()) {
+      // TODO: should we remember this connection regardless of whether
+      // the friend declaration provided a body?
+      FunctionTemplate->setInstantiatedFromMemberTemplate(
+                                           D->getDescribedFunctionTemplate());
+    }
+  } else if (FunctionTemplate) {
+    // Record this function template specialization.
+    Function->setFunctionTemplateSpecialization(FunctionTemplate,
+                                                &TemplateArgs.getInnermost(),
+                                                InsertPos);
+  } else if (isFriend && D->isThisDeclarationADefinition()) {
+    // TODO: should we remember this connection regardless of whether
+    // the friend declaration provided a body?
+    Function->setInstantiationOfMemberFunction(D, TSK_ImplicitInstantiation);
+  }
+    
+  if (InitFunctionInstantiation(Function, D))
+    Function->setInvalidDecl();
+
+  bool Redeclaration = false;
+  bool OverloadableAttrRequired = false;
+  bool isExplicitSpecialization = false;
+    
+  LookupResult Previous(SemaRef, Function->getDeclName(), SourceLocation(),
+                        Sema::LookupOrdinaryName, Sema::ForRedeclaration);
+
+  if (DependentFunctionTemplateSpecializationInfo *Info
+        = D->getDependentSpecializationInfo()) {
+    assert(isFriend && "non-friend has dependent specialization info?");
+
+    // This needs to be set now for future sanity.
+    Function->setObjectOfFriendDecl(/*HasPrevious*/ true);
+
+    // Instantiate the explicit template arguments.
+    TemplateArgumentListInfo ExplicitArgs(Info->getLAngleLoc(),
+                                          Info->getRAngleLoc());
+    for (unsigned I = 0, E = Info->getNumTemplateArgs(); I != E; ++I) {
+      TemplateArgumentLoc Loc;
+      if (SemaRef.Subst(Info->getTemplateArg(I), Loc, TemplateArgs))
+        return 0;
+
+      ExplicitArgs.addArgument(Loc);
+    }
+
+    // Map the candidate templates to their instantiations.
+    for (unsigned I = 0, E = Info->getNumTemplates(); I != E; ++I) {
+      Decl *Temp = SemaRef.FindInstantiatedDecl(D->getLocation(),
+                                                Info->getTemplate(I),
+                                                TemplateArgs);
+      if (!Temp) return 0;
+
+      Previous.addDecl(cast<FunctionTemplateDecl>(Temp));
+    }
+
+    if (SemaRef.CheckFunctionTemplateSpecialization(Function,
+                                                    &ExplicitArgs,
+                                                    Previous))
+      Function->setInvalidDecl();
+                                          
+    isExplicitSpecialization = true;
+
+  } else if (TemplateParams || !FunctionTemplate) {
+    // Look only into the namespace where the friend would be declared to 
+    // find a previous declaration. This is the innermost enclosing namespace, 
+    // as described in ActOnFriendFunctionDecl.
+    SemaRef.LookupQualifiedName(Previous, DC);
+    
+    // In C++, the previous declaration we find might be a tag type
+    // (class or enum). In this case, the new declaration will hide the
+    // tag type. Note that this does does not apply if we're declaring a
+    // typedef (C++ [dcl.typedef]p4).
+    if (Previous.isSingleTagDecl())
+      Previous.clear();
+  }
+  
+  SemaRef.CheckFunctionDeclaration(/*Scope*/ 0, Function, Previous,
+                                   isExplicitSpecialization, Redeclaration,
+                                   /*FIXME:*/OverloadableAttrRequired);
+
+  NamedDecl *PrincipalDecl = (TemplateParams
+                              ? cast<NamedDecl>(FunctionTemplate)
+                              : Function);
+
+  // If the original function was part of a friend declaration,
+  // inherit its namespace state and add it to the owner.
+  if (isFriend) {
+    NamedDecl *PrevDecl;
+    if (TemplateParams)
+      PrevDecl = FunctionTemplate->getPreviousDeclaration();
+    else
+      PrevDecl = Function->getPreviousDeclaration();
+
+    PrincipalDecl->setObjectOfFriendDecl(PrevDecl != 0);
+    DC->makeDeclVisibleInContext(PrincipalDecl, /*Recoverable=*/ false);
+  }
+
+  if (Function->isOverloadedOperator() && !DC->isRecord() &&
+      PrincipalDecl->isInIdentifierNamespace(Decl::IDNS_Ordinary))
+    PrincipalDecl->setNonMemberOperator();
+
+  return Function;
+}
+
+Decl *
+TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
+                                      TemplateParameterList *TemplateParams) {
+  FunctionTemplateDecl *FunctionTemplate = D->getDescribedFunctionTemplate();
+  void *InsertPos = 0;
+  if (FunctionTemplate && !TemplateParams) {
+    // We are creating a function template specialization from a function
+    // template. Check whether there is already a function template
+    // specialization for this particular set of template arguments.
+    llvm::FoldingSetNodeID ID;
+    FunctionTemplateSpecializationInfo::Profile(ID,
+                            TemplateArgs.getInnermost().getFlatArgumentList(),
+                                      TemplateArgs.getInnermost().flat_size(),
+                                                SemaRef.Context);
+
+    FunctionTemplateSpecializationInfo *Info
+      = FunctionTemplate->getSpecializations().FindNodeOrInsertPos(ID,
+                                                                   InsertPos);
+
+    // If we already have a function template specialization, return it.
+    if (Info)
+      return Info->Function;
+  }
+
+  bool isFriend;
+  if (FunctionTemplate)
+    isFriend = (FunctionTemplate->getFriendObjectKind() != Decl::FOK_None);
+  else
+    isFriend = (D->getFriendObjectKind() != Decl::FOK_None);
+
+  bool MergeWithParentScope = (TemplateParams != 0) ||
+    !(isa<Decl>(Owner) && 
+      cast<Decl>(Owner)->isDefinedOutsideFunctionOrMethod());
+  Sema::LocalInstantiationScope Scope(SemaRef, MergeWithParentScope);
+
+  llvm::SmallVector<ParmVarDecl *, 4> Params;
+  TypeSourceInfo *TInfo = D->getTypeSourceInfo();
+  TInfo = SubstFunctionType(D, Params);
+  if (!TInfo)
+    return 0;
+  QualType T = TInfo->getType();
+
+  NestedNameSpecifier *Qualifier = D->getQualifier();
+  if (Qualifier) {
+    Qualifier = SemaRef.SubstNestedNameSpecifier(Qualifier,
+                                                 D->getQualifierRange(),
+                                                 TemplateArgs);
+    if (!Qualifier) return 0;
+  }
+
+  DeclContext *DC = Owner;
+  if (isFriend) {
+    if (Qualifier) {
+      CXXScopeSpec SS;
+      SS.setScopeRep(Qualifier);
+      SS.setRange(D->getQualifierRange());
+      DC = SemaRef.computeDeclContext(SS);
+    } else {
+      DC = SemaRef.FindInstantiatedContext(D->getLocation(),
+                                           D->getDeclContext(),
+                                           TemplateArgs);
+    }
+    if (!DC) return 0;
+  }
+
+  // Build the instantiated method declaration.
+  CXXRecordDecl *Record = cast<CXXRecordDecl>(DC);
+  CXXMethodDecl *Method = 0;
+
+  DeclarationName Name = D->getDeclName();
+  if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(D)) {
+    QualType ClassTy = SemaRef.Context.getTypeDeclType(Record);
+    Name = SemaRef.Context.DeclarationNames.getCXXConstructorName(
+                                    SemaRef.Context.getCanonicalType(ClassTy));
+    Method = CXXConstructorDecl::Create(SemaRef.Context, Record,
+                                        Constructor->getLocation(),
+                                        Name, T, TInfo,
+                                        Constructor->isExplicit(),
+                                        Constructor->isInlineSpecified(),
+                                        false);
+  } else if (CXXDestructorDecl *Destructor = dyn_cast<CXXDestructorDecl>(D)) {
+    QualType ClassTy = SemaRef.Context.getTypeDeclType(Record);
+    Name = SemaRef.Context.DeclarationNames.getCXXDestructorName(
+                                   SemaRef.Context.getCanonicalType(ClassTy));
+    Method = CXXDestructorDecl::Create(SemaRef.Context, Record,
+                                       Destructor->getLocation(), Name,
+                                       T, Destructor->isInlineSpecified(),
+                                       false);
+  } else if (CXXConversionDecl *Conversion = dyn_cast<CXXConversionDecl>(D)) {
+    CanQualType ConvTy
+      = SemaRef.Context.getCanonicalType(
+                                      T->getAs<FunctionType>()->getResultType());
+    Name = SemaRef.Context.DeclarationNames.getCXXConversionFunctionName(
+                                                                      ConvTy);
+    Method = CXXConversionDecl::Create(SemaRef.Context, Record,
+                                       Conversion->getLocation(), Name,
+                                       T, TInfo,
+                                       Conversion->isInlineSpecified(),
+                                       Conversion->isExplicit());
+  } else {
+    Method = CXXMethodDecl::Create(SemaRef.Context, Record, D->getLocation(),
+                                   D->getDeclName(), T, TInfo,
+                                   D->isStatic(),
+                                   D->getStorageClassAsWritten(),
+                                   D->isInlineSpecified());
+  }
+
+  if (Qualifier)
+    Method->setQualifierInfo(Qualifier, D->getQualifierRange());
+
+  if (TemplateParams) {
+    // Our resulting instantiation is actually a function template, since we
+    // are substituting only the outer template parameters. For example, given
+    //
+    //   template<typename T>
+    //   struct X {
+    //     template<typename U> void f(T, U);
+    //   };
+    //
+    //   X<int> x;
+    //
+    // We are instantiating the member template "f" within X<int>, which means
+    // substituting int for T, but leaving "f" as a member function template.
+    // Build the function template itself.
+    FunctionTemplate = FunctionTemplateDecl::Create(SemaRef.Context, Record,
+                                                    Method->getLocation(),
+                                                    Method->getDeclName(),
+                                                    TemplateParams, Method);
+    if (isFriend) {
+      FunctionTemplate->setLexicalDeclContext(Owner);
+      FunctionTemplate->setObjectOfFriendDecl(true);
+    } else if (D->isOutOfLine())
+      FunctionTemplate->setLexicalDeclContext(D->getLexicalDeclContext());
+    Method->setDescribedFunctionTemplate(FunctionTemplate);
+  } else if (FunctionTemplate) {
+    // Record this function template specialization.
+    Method->setFunctionTemplateSpecialization(FunctionTemplate,
+                                              &TemplateArgs.getInnermost(),
+                                              InsertPos);
+  } else if (!isFriend) {
+    // Record that this is an instantiation of a member function.
+    Method->setInstantiationOfMemberFunction(D, TSK_ImplicitInstantiation);
+  }
+  
+  // If we are instantiating a member function defined
+  // out-of-line, the instantiation will have the same lexical
+  // context (which will be a namespace scope) as the template.
+  if (isFriend) {
+    Method->setLexicalDeclContext(Owner);
+    Method->setObjectOfFriendDecl(true);
+  } else if (D->isOutOfLine())
+    Method->setLexicalDeclContext(D->getLexicalDeclContext());
+
+  // Attach the parameters
+  for (unsigned P = 0; P < Params.size(); ++P)
+    Params[P]->setOwningFunction(Method);
+  Method->setParams(Params.data(), Params.size());
+
+  if (InitMethodInstantiation(Method, D))
+    Method->setInvalidDecl();
+
+  LookupResult Previous(SemaRef, Name, SourceLocation(),
+                        Sema::LookupOrdinaryName, Sema::ForRedeclaration);
+
+  if (!FunctionTemplate || TemplateParams || isFriend) {
+    SemaRef.LookupQualifiedName(Previous, Record);
+
+    // In C++, the previous declaration we find might be a tag type
+    // (class or enum). In this case, the new declaration will hide the
+    // tag type. Note that this does does not apply if we're declaring a
+    // typedef (C++ [dcl.typedef]p4).
+    if (Previous.isSingleTagDecl())
+      Previous.clear();
+  }
+
+  bool Redeclaration = false;
+  bool OverloadableAttrRequired = false;
+  SemaRef.CheckFunctionDeclaration(0, Method, Previous, false, Redeclaration,
+                                   /*FIXME:*/OverloadableAttrRequired);
+
+  if (D->isPure())
+    SemaRef.CheckPureMethod(Method, SourceRange());
+
+  Method->setAccess(D->getAccess());
+
+  if (FunctionTemplate) {
+    // If there's a function template, let our caller handle it.
+  } else if (Method->isInvalidDecl() && !Previous.empty()) {
+    // Don't hide a (potentially) valid declaration with an invalid one.
+  } else {
+    NamedDecl *DeclToAdd = (TemplateParams
+                            ? cast<NamedDecl>(FunctionTemplate)
+                            : Method);
+    if (isFriend)
+      Record->makeDeclVisibleInContext(DeclToAdd);
+    else
+      Owner->addDecl(DeclToAdd);
+  }
+
+  return Method;
+}
+
+Decl *TemplateDeclInstantiator::VisitCXXConstructorDecl(CXXConstructorDecl *D) {
+  return VisitCXXMethodDecl(D);
+}
+
+Decl *TemplateDeclInstantiator::VisitCXXDestructorDecl(CXXDestructorDecl *D) {
+  return VisitCXXMethodDecl(D);
+}
+
+Decl *TemplateDeclInstantiator::VisitCXXConversionDecl(CXXConversionDecl *D) {
+  return VisitCXXMethodDecl(D);
+}
+
+ParmVarDecl *TemplateDeclInstantiator::VisitParmVarDecl(ParmVarDecl *D) {
+  return SemaRef.SubstParmVarDecl(D, TemplateArgs);
+}
+
+Decl *TemplateDeclInstantiator::VisitTemplateTypeParmDecl(
+                                                    TemplateTypeParmDecl *D) {
+  // TODO: don't always clone when decls are refcounted.
+  const Type* T = D->getTypeForDecl();
+  assert(T->isTemplateTypeParmType());
+  const TemplateTypeParmType *TTPT = T->getAs<TemplateTypeParmType>();
+
+  TemplateTypeParmDecl *Inst =
+    TemplateTypeParmDecl::Create(SemaRef.Context, Owner, D->getLocation(),
+                                 TTPT->getDepth() - 1, TTPT->getIndex(),
+                                 TTPT->getName(),
+                                 D->wasDeclaredWithTypename(),
+                                 D->isParameterPack());
+
+  if (D->hasDefaultArgument())
+    Inst->setDefaultArgument(D->getDefaultArgumentInfo(), false);  
+
+  // Introduce this template parameter's instantiation into the instantiation 
+  // scope.
+  SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Inst);
+  
+  return Inst;
+}
+
+Decl *TemplateDeclInstantiator::VisitNonTypeTemplateParmDecl(
+                                                 NonTypeTemplateParmDecl *D) {
+  // Substitute into the type of the non-type template parameter.
+  QualType T;
+  TypeSourceInfo *DI = D->getTypeSourceInfo();
+  if (DI) {
+    DI = SemaRef.SubstType(DI, TemplateArgs, D->getLocation(),
+                           D->getDeclName());
+    if (DI) T = DI->getType();
+  } else {
+    T = SemaRef.SubstType(D->getType(), TemplateArgs, D->getLocation(),
+                          D->getDeclName());
+    DI = 0;
+  }
+  if (T.isNull())
+    return 0;
+  
+  // Check that this type is acceptable for a non-type template parameter.
+  bool Invalid = false;
+  T = SemaRef.CheckNonTypeTemplateParameterType(T, D->getLocation());
+  if (T.isNull()) {
+    T = SemaRef.Context.IntTy;
+    Invalid = true;
+  }
+  
+  NonTypeTemplateParmDecl *Param
+    = NonTypeTemplateParmDecl::Create(SemaRef.Context, Owner, D->getLocation(),
+                                      D->getDepth() - 1, D->getPosition(),
+                                      D->getIdentifier(), T, DI);
+  if (Invalid)
+    Param->setInvalidDecl();
+  
+  Param->setDefaultArgument(D->getDefaultArgument());
+  
+  // Introduce this template parameter's instantiation into the instantiation 
+  // scope.
+  SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Param);
+  return Param;
+}
+
+Decl *
+TemplateDeclInstantiator::VisitTemplateTemplateParmDecl(
+                                                  TemplateTemplateParmDecl *D) {
+  // Instantiate the template parameter list of the template template parameter.
+  TemplateParameterList *TempParams = D->getTemplateParameters();
+  TemplateParameterList *InstParams;
+  {
+    // Perform the actual substitution of template parameters within a new,
+    // local instantiation scope.
+    Sema::LocalInstantiationScope Scope(SemaRef);
+    InstParams = SubstTemplateParams(TempParams);
+    if (!InstParams)
+      return NULL;
+  }  
+  
+  // Build the template template parameter.
+  TemplateTemplateParmDecl *Param
+    = TemplateTemplateParmDecl::Create(SemaRef.Context, Owner, D->getLocation(),
+                                       D->getDepth() - 1, D->getPosition(),
+                                       D->getIdentifier(), InstParams);
+  Param->setDefaultArgument(D->getDefaultArgument());
+  
+  // Introduce this template parameter's instantiation into the instantiation 
+  // scope.
+  SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Param);
+  
+  return Param;
+}
+
+Decl *TemplateDeclInstantiator::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
+  // Using directives are never dependent, so they require no explicit
+  
+  UsingDirectiveDecl *Inst
+    = UsingDirectiveDecl::Create(SemaRef.Context, Owner, D->getLocation(),
+                                 D->getNamespaceKeyLocation(), 
+                                 D->getQualifierRange(), D->getQualifier(), 
+                                 D->getIdentLocation(), 
+                                 D->getNominatedNamespace(), 
+                                 D->getCommonAncestor());
+  Owner->addDecl(Inst);
+  return Inst;
+}
+
+Decl *TemplateDeclInstantiator::VisitUsingDecl(UsingDecl *D) {
+  // The nested name specifier is non-dependent, so no transformation
+  // is required.
+
+  // We only need to do redeclaration lookups if we're in a class
+  // scope (in fact, it's not really even possible in non-class
+  // scopes).
+  bool CheckRedeclaration = Owner->isRecord();
+
+  LookupResult Prev(SemaRef, D->getDeclName(), D->getLocation(),
+                    Sema::LookupUsingDeclName, Sema::ForRedeclaration);
+
+  UsingDecl *NewUD = UsingDecl::Create(SemaRef.Context, Owner,
+                                       D->getLocation(),
+                                       D->getNestedNameRange(),
+                                       D->getUsingLocation(),
+                                       D->getTargetNestedNameDecl(),
+                                       D->getDeclName(),
+                                       D->isTypeName());
+
+  CXXScopeSpec SS;
+  SS.setScopeRep(D->getTargetNestedNameDecl());
+  SS.setRange(D->getNestedNameRange());
+
+  if (CheckRedeclaration) {
+    Prev.setHideTags(false);
+    SemaRef.LookupQualifiedName(Prev, Owner);
+
+    // Check for invalid redeclarations.
+    if (SemaRef.CheckUsingDeclRedeclaration(D->getUsingLocation(),
+                                            D->isTypeName(), SS,
+                                            D->getLocation(), Prev))
+      NewUD->setInvalidDecl();
+
+  }
+
+  if (!NewUD->isInvalidDecl() &&
+      SemaRef.CheckUsingDeclQualifier(D->getUsingLocation(), SS,
+                                      D->getLocation()))
+    NewUD->setInvalidDecl();
+
+  SemaRef.Context.setInstantiatedFromUsingDecl(NewUD, D);
+  NewUD->setAccess(D->getAccess());
+  Owner->addDecl(NewUD);
+
+  // Don't process the shadow decls for an invalid decl.
+  if (NewUD->isInvalidDecl())
+    return NewUD;
+
+  bool isFunctionScope = Owner->isFunctionOrMethod();
+
+  // Process the shadow decls.
+  for (UsingDecl::shadow_iterator I = D->shadow_begin(), E = D->shadow_end();
+         I != E; ++I) {
+    UsingShadowDecl *Shadow = *I;
+    NamedDecl *InstTarget =
+      cast<NamedDecl>(SemaRef.FindInstantiatedDecl(Shadow->getLocation(),
+                                                   Shadow->getTargetDecl(),
+                                                   TemplateArgs));
+
+    if (CheckRedeclaration &&
+        SemaRef.CheckUsingShadowDecl(NewUD, InstTarget, Prev))
+      continue;
+
+    UsingShadowDecl *InstShadow
+      = SemaRef.BuildUsingShadowDecl(/*Scope*/ 0, NewUD, InstTarget);
+    SemaRef.Context.setInstantiatedFromUsingShadowDecl(InstShadow, Shadow);
+
+    if (isFunctionScope)
+      SemaRef.CurrentInstantiationScope->InstantiatedLocal(Shadow, InstShadow);
+  }
+
+  return NewUD;
+}
+
+Decl *TemplateDeclInstantiator::VisitUsingShadowDecl(UsingShadowDecl *D) {
+  // Ignore these;  we handle them in bulk when processing the UsingDecl.
+  return 0;
+}
+
+Decl * TemplateDeclInstantiator
+    ::VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D) {
+  NestedNameSpecifier *NNS =
+    SemaRef.SubstNestedNameSpecifier(D->getTargetNestedNameSpecifier(),
+                                     D->getTargetNestedNameRange(),
+                                     TemplateArgs);
+  if (!NNS)
+    return 0;
+
+  CXXScopeSpec SS;
+  SS.setRange(D->getTargetNestedNameRange());
+  SS.setScopeRep(NNS);
+
+  NamedDecl *UD =
+    SemaRef.BuildUsingDeclaration(/*Scope*/ 0, D->getAccess(),
+                                  D->getUsingLoc(), SS, D->getLocation(),
+                                  D->getDeclName(), 0,
+                                  /*instantiation*/ true,
+                                  /*typename*/ true, D->getTypenameLoc());
+  if (UD)
+    SemaRef.Context.setInstantiatedFromUsingDecl(cast<UsingDecl>(UD), D);
+
+  return UD;
+}
+
+Decl * TemplateDeclInstantiator
+    ::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
+  NestedNameSpecifier *NNS =
+    SemaRef.SubstNestedNameSpecifier(D->getTargetNestedNameSpecifier(),
+                                     D->getTargetNestedNameRange(),
+                                     TemplateArgs);
+  if (!NNS)
+    return 0;
+
+  CXXScopeSpec SS;
+  SS.setRange(D->getTargetNestedNameRange());
+  SS.setScopeRep(NNS);
+
+  NamedDecl *UD =
+    SemaRef.BuildUsingDeclaration(/*Scope*/ 0, D->getAccess(),
+                                  D->getUsingLoc(), SS, D->getLocation(),
+                                  D->getDeclName(), 0,
+                                  /*instantiation*/ true,
+                                  /*typename*/ false, SourceLocation());
+  if (UD)
+    SemaRef.Context.setInstantiatedFromUsingDecl(cast<UsingDecl>(UD), D);
+
+  return UD;
+}
+
+Decl *Sema::SubstDecl(Decl *D, DeclContext *Owner,
+                      const MultiLevelTemplateArgumentList &TemplateArgs) {
+  TemplateDeclInstantiator Instantiator(*this, Owner, TemplateArgs);
+  if (D->isInvalidDecl())
+    return 0;
+
+  return Instantiator.Visit(D);
+}
+
+/// \brief Instantiates a nested template parameter list in the current
+/// instantiation context.
+///
+/// \param L The parameter list to instantiate
+///
+/// \returns NULL if there was an error
+TemplateParameterList *
+TemplateDeclInstantiator::SubstTemplateParams(TemplateParameterList *L) {
+  // Get errors for all the parameters before bailing out.
+  bool Invalid = false;
+
+  unsigned N = L->size();
+  typedef llvm::SmallVector<NamedDecl *, 8> ParamVector;
+  ParamVector Params;
+  Params.reserve(N);
+  for (TemplateParameterList::iterator PI = L->begin(), PE = L->end();
+       PI != PE; ++PI) {
+    NamedDecl *D = cast_or_null<NamedDecl>(Visit(*PI));
+    Params.push_back(D);
+    Invalid = Invalid || !D || D->isInvalidDecl();
+  }
+
+  // Clean up if we had an error.
+  if (Invalid) {
+    for (ParamVector::iterator PI = Params.begin(), PE = Params.end();
+         PI != PE; ++PI)
+      if (*PI)
+        (*PI)->Destroy(SemaRef.Context);
+    return NULL;
+  }
+
+  TemplateParameterList *InstL
+    = TemplateParameterList::Create(SemaRef.Context, L->getTemplateLoc(),
+                                    L->getLAngleLoc(), &Params.front(), N,
+                                    L->getRAngleLoc());
+  return InstL;
+}
+
+/// \brief Instantiate the declaration of a class template partial 
+/// specialization.
+///
+/// \param ClassTemplate the (instantiated) class template that is partially
+// specialized by the instantiation of \p PartialSpec.
+///
+/// \param PartialSpec the (uninstantiated) class template partial 
+/// specialization that we are instantiating.
+///
+/// \returns true if there was an error, false otherwise.
+bool 
+TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization(
+                                            ClassTemplateDecl *ClassTemplate,
+                          ClassTemplatePartialSpecializationDecl *PartialSpec) {
+  // Create a local instantiation scope for this class template partial
+  // specialization, which will contain the instantiations of the template
+  // parameters.
+  Sema::LocalInstantiationScope Scope(SemaRef);
+  
+  // Substitute into the template parameters of the class template partial
+  // specialization.
+  TemplateParameterList *TempParams = PartialSpec->getTemplateParameters();
+  TemplateParameterList *InstParams = SubstTemplateParams(TempParams);
+  if (!InstParams)
+    return true;
+  
+  // Substitute into the template arguments of the class template partial
+  // specialization.
+  const TemplateArgumentLoc *PartialSpecTemplateArgs
+    = PartialSpec->getTemplateArgsAsWritten();
+  unsigned N = PartialSpec->getNumTemplateArgsAsWritten();
+
+  TemplateArgumentListInfo InstTemplateArgs; // no angle locations
+  for (unsigned I = 0; I != N; ++I) {
+    TemplateArgumentLoc Loc;
+    if (SemaRef.Subst(PartialSpecTemplateArgs[I], Loc, TemplateArgs))
+      return true;
+    InstTemplateArgs.addArgument(Loc);
+  }
+  
+
+  // Check that the template argument list is well-formed for this
+  // class template.
+  TemplateArgumentListBuilder Converted(ClassTemplate->getTemplateParameters(), 
+                                        InstTemplateArgs.size());
+  if (SemaRef.CheckTemplateArgumentList(ClassTemplate, 
+                                        PartialSpec->getLocation(),
+                                        InstTemplateArgs, 
+                                        false,
+                                        Converted))
+    return true;
+
+  // Figure out where to insert this class template partial specialization
+  // in the member template's set of class template partial specializations.
+  llvm::FoldingSetNodeID ID;
+  ClassTemplatePartialSpecializationDecl::Profile(ID,
+                                                  Converted.getFlatArguments(),
+                                                  Converted.flatSize(),
+                                                  SemaRef.Context);
+  void *InsertPos = 0;
+  ClassTemplateSpecializationDecl *PrevDecl
+    = ClassTemplate->getPartialSpecializations().FindNodeOrInsertPos(ID,
+                                                                     InsertPos);
+  
+  // Build the canonical type that describes the converted template
+  // arguments of the class template partial specialization.
+  QualType CanonType 
+    = SemaRef.Context.getTemplateSpecializationType(TemplateName(ClassTemplate),
+                                                  Converted.getFlatArguments(),
+                                                    Converted.flatSize());
+
+  // Build the fully-sugared type for this class template
+  // specialization as the user wrote in the specialization
+  // itself. This means that we'll pretty-print the type retrieved
+  // from the specialization's declaration the way that the user
+  // actually wrote the specialization, rather than formatting the
+  // name based on the "canonical" representation used to store the
+  // template arguments in the specialization.
+  TypeSourceInfo *WrittenTy
+    = SemaRef.Context.getTemplateSpecializationTypeInfo(
+                                                    TemplateName(ClassTemplate),
+                                                    PartialSpec->getLocation(),
+                                                    InstTemplateArgs,
+                                                    CanonType);
+  
+  if (PrevDecl) {
+    // We've already seen a partial specialization with the same template
+    // parameters and template arguments. This can happen, for example, when
+    // substituting the outer template arguments ends up causing two
+    // class template partial specializations of a member class template
+    // to have identical forms, e.g.,
+    //
+    //   template<typename T, typename U>
+    //   struct Outer {
+    //     template<typename X, typename Y> struct Inner;
+    //     template<typename Y> struct Inner<T, Y>;
+    //     template<typename Y> struct Inner<U, Y>;
+    //   };
+    //
+    //   Outer<int, int> outer; // error: the partial specializations of Inner
+    //                          // have the same signature.
+    SemaRef.Diag(PartialSpec->getLocation(), diag::err_partial_spec_redeclared)
+      << WrittenTy;
+    SemaRef.Diag(PrevDecl->getLocation(), diag::note_prev_partial_spec_here)
+      << SemaRef.Context.getTypeDeclType(PrevDecl);
+    return true;
+  }
+  
+  
+  // Create the class template partial specialization declaration.
+  ClassTemplatePartialSpecializationDecl *InstPartialSpec
+    = ClassTemplatePartialSpecializationDecl::Create(SemaRef.Context, Owner, 
+                                                     PartialSpec->getLocation(), 
+                                                     InstParams,
+                                                     ClassTemplate, 
+                                                     Converted,
+                                                     InstTemplateArgs,
+                                                     CanonType,
+                                                     0);
+  // Substitute the nested name specifier, if any.
+  if (SubstQualifier(PartialSpec, InstPartialSpec))
+    return 0;
+
+  InstPartialSpec->setInstantiatedFromMember(PartialSpec);
+  InstPartialSpec->setTypeAsWritten(WrittenTy);
+  
+  // Add this partial specialization to the set of class template partial
+  // specializations.
+  ClassTemplate->getPartialSpecializations().InsertNode(InstPartialSpec,
+                                                        InsertPos);
+  return false;
+}
+
+TypeSourceInfo*
+TemplateDeclInstantiator::SubstFunctionType(FunctionDecl *D,
+                              llvm::SmallVectorImpl<ParmVarDecl *> &Params) {
+  TypeSourceInfo *OldTInfo = D->getTypeSourceInfo();
+  assert(OldTInfo && "substituting function without type source info");
+  assert(Params.empty() && "parameter vector is non-empty at start");
+  TypeSourceInfo *NewTInfo
+    = SemaRef.SubstFunctionDeclType(OldTInfo, TemplateArgs,
+                                    D->getTypeSpecStartLoc(),
+                                    D->getDeclName());
+  if (!NewTInfo)
+    return 0;
+
+  if (NewTInfo != OldTInfo) {
+    // Get parameters from the new type info.
+    TypeLoc NewTL = NewTInfo->getTypeLoc();
+    FunctionProtoTypeLoc *NewProtoLoc = cast<FunctionProtoTypeLoc>(&NewTL);
+    assert(NewProtoLoc && "Missing prototype?");
+    for (unsigned i = 0, i_end = NewProtoLoc->getNumArgs(); i != i_end; ++i)
+      Params.push_back(NewProtoLoc->getArg(i));
+  } else {
+    // The function type itself was not dependent and therefore no
+    // substitution occurred. However, we still need to instantiate
+    // the function parameters themselves.
+    TypeLoc OldTL = OldTInfo->getTypeLoc();
+    FunctionProtoTypeLoc *OldProtoLoc = cast<FunctionProtoTypeLoc>(&OldTL);
+    for (unsigned i = 0, i_end = OldProtoLoc->getNumArgs(); i != i_end; ++i) {
+      ParmVarDecl *Parm = VisitParmVarDecl(OldProtoLoc->getArg(i));
+      if (!Parm)
+        return 0;
+      Params.push_back(Parm);
+    }
+  }
+  return NewTInfo;
+}
+
+/// \brief Initializes the common fields of an instantiation function
+/// declaration (New) from the corresponding fields of its template (Tmpl).
+///
+/// \returns true if there was an error
+bool
+TemplateDeclInstantiator::InitFunctionInstantiation(FunctionDecl *New,
+                                                    FunctionDecl *Tmpl) {
+  if (Tmpl->isDeleted())
+    New->setDeleted();
+
+  // If we are performing substituting explicitly-specified template arguments
+  // or deduced template arguments into a function template and we reach this
+  // point, we are now past the point where SFINAE applies and have committed
+  // to keeping the new function template specialization. We therefore
+  // convert the active template instantiation for the function template
+  // into a template instantiation for this specific function template
+  // specialization, which is not a SFINAE context, so that we diagnose any
+  // further errors in the declaration itself.
+  typedef Sema::ActiveTemplateInstantiation ActiveInstType;
+  ActiveInstType &ActiveInst = SemaRef.ActiveTemplateInstantiations.back();
+  if (ActiveInst.Kind == ActiveInstType::ExplicitTemplateArgumentSubstitution ||
+      ActiveInst.Kind == ActiveInstType::DeducedTemplateArgumentSubstitution) {
+    if (FunctionTemplateDecl *FunTmpl
+          = dyn_cast<FunctionTemplateDecl>((Decl *)ActiveInst.Entity)) {
+      assert(FunTmpl->getTemplatedDecl() == Tmpl &&
+             "Deduction from the wrong function template?");
+      (void) FunTmpl;
+      ActiveInst.Kind = ActiveInstType::TemplateInstantiation;
+      ActiveInst.Entity = reinterpret_cast<uintptr_t>(New);
+      --SemaRef.NonInstantiationEntries;
+    }
+  }
+
+  const FunctionProtoType *Proto = Tmpl->getType()->getAs<FunctionProtoType>();
+  assert(Proto && "Function template without prototype?");
+
+  if (Proto->hasExceptionSpec() || Proto->hasAnyExceptionSpec() ||
+      Proto->getNoReturnAttr()) {
+    // The function has an exception specification or a "noreturn"
+    // attribute. Substitute into each of the exception types.
+    llvm::SmallVector<QualType, 4> Exceptions;
+    for (unsigned I = 0, N = Proto->getNumExceptions(); I != N; ++I) {
+      // FIXME: Poor location information!
+      QualType T
+        = SemaRef.SubstType(Proto->getExceptionType(I), TemplateArgs,
+                            New->getLocation(), New->getDeclName());
+      if (T.isNull() || 
+          SemaRef.CheckSpecifiedExceptionType(T, New->getLocation()))
+        continue;
+
+      Exceptions.push_back(T);
+    }
+
+    // Rebuild the function type 
+
+    const FunctionProtoType *NewProto
+      = New->getType()->getAs<FunctionProtoType>();
+    assert(NewProto && "Template instantiation without function prototype?");
+    New->setType(SemaRef.Context.getFunctionType(NewProto->getResultType(),
+                                                 NewProto->arg_type_begin(),
+                                                 NewProto->getNumArgs(),
+                                                 NewProto->isVariadic(),
+                                                 NewProto->getTypeQuals(),
+                                                 Proto->hasExceptionSpec(),
+                                                 Proto->hasAnyExceptionSpec(),
+                                                 Exceptions.size(),
+                                                 Exceptions.data(),
+                                                 Proto->getExtInfo()));
+  }
+
+  return false;
+}
+
+/// \brief Initializes common fields of an instantiated method
+/// declaration (New) from the corresponding fields of its template
+/// (Tmpl).
+///
+/// \returns true if there was an error
+bool
+TemplateDeclInstantiator::InitMethodInstantiation(CXXMethodDecl *New,
+                                                  CXXMethodDecl *Tmpl) {
+  if (InitFunctionInstantiation(New, Tmpl))
+    return true;
+
+  CXXRecordDecl *Record = cast<CXXRecordDecl>(Owner);
+  New->setAccess(Tmpl->getAccess());
+  if (Tmpl->isVirtualAsWritten())
+    Record->setMethodAsVirtual(New);
+
+  // FIXME: attributes
+  // FIXME: New needs a pointer to Tmpl
+  return false;
+}
+
+/// \brief Instantiate the definition of the given function from its
+/// template.
+///
+/// \param PointOfInstantiation the point at which the instantiation was
+/// required. Note that this is not precisely a "point of instantiation"
+/// for the function, but it's close.
+///
+/// \param Function the already-instantiated declaration of a
+/// function template specialization or member function of a class template
+/// specialization.
+///
+/// \param Recursive if true, recursively instantiates any functions that
+/// are required by this instantiation.
+///
+/// \param DefinitionRequired if true, then we are performing an explicit
+/// instantiation where the body of the function is required. Complain if
+/// there is no such body.
+void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
+                                         FunctionDecl *Function,
+                                         bool Recursive,
+                                         bool DefinitionRequired) {
+  if (Function->isInvalidDecl())
+    return;
+
+  assert(!Function->getBody() && "Already instantiated!");
+
+  // Never instantiate an explicit specialization.
+  if (Function->getTemplateSpecializationKind() == TSK_ExplicitSpecialization)
+    return;
+  
+  // Find the function body that we'll be substituting.
+  const FunctionDecl *PatternDecl = Function->getTemplateInstantiationPattern();
+  Stmt *Pattern = 0;
+  if (PatternDecl)
+    Pattern = PatternDecl->getBody(PatternDecl);
+
+  if (!Pattern) {
+    if (DefinitionRequired) {
+      if (Function->getPrimaryTemplate())
+        Diag(PointOfInstantiation, 
+             diag::err_explicit_instantiation_undefined_func_template)
+          << Function->getPrimaryTemplate();
+      else
+        Diag(PointOfInstantiation, 
+             diag::err_explicit_instantiation_undefined_member)
+          << 1 << Function->getDeclName() << Function->getDeclContext();
+      
+      if (PatternDecl)
+        Diag(PatternDecl->getLocation(), 
+             diag::note_explicit_instantiation_here);
+    }
+      
+    return;
+  }
+
+  // C++0x [temp.explicit]p9:
+  //   Except for inline functions, other explicit instantiation declarations
+  //   have the effect of suppressing the implicit instantiation of the entity
+  //   to which they refer.
+  if (Function->getTemplateSpecializationKind()
+        == TSK_ExplicitInstantiationDeclaration &&
+      !PatternDecl->isInlined())
+    return;
+
+  InstantiatingTemplate Inst(*this, PointOfInstantiation, Function);
+  if (Inst)
+    return;
+
+  // If we're performing recursive template instantiation, create our own
+  // queue of pending implicit instantiations that we will instantiate later,
+  // while we're still within our own instantiation context.
+  std::deque<PendingImplicitInstantiation> SavedPendingImplicitInstantiations;
+  if (Recursive)
+    PendingImplicitInstantiations.swap(SavedPendingImplicitInstantiations);
+
+  ActOnStartOfFunctionDef(0, DeclPtrTy::make(Function));
+
+  // Introduce a new scope where local variable instantiations will be
+  // recorded, unless we're actually a member function within a local
+  // class, in which case we need to merge our results with the parent
+  // scope (of the enclosing function).
+  bool MergeWithParentScope = false;
+  if (CXXRecordDecl *Rec = dyn_cast<CXXRecordDecl>(Function->getDeclContext()))
+    MergeWithParentScope = Rec->isLocalClass();
+
+  LocalInstantiationScope Scope(*this, MergeWithParentScope);
+
+  // Introduce the instantiated function parameters into the local
+  // instantiation scope.
+  for (unsigned I = 0, N = PatternDecl->getNumParams(); I != N; ++I)
+    Scope.InstantiatedLocal(PatternDecl->getParamDecl(I),
+                            Function->getParamDecl(I));
+
+  // Enter the scope of this instantiation. We don't use
+  // PushDeclContext because we don't have a scope.
+  DeclContext *PreviousContext = CurContext;
+  CurContext = Function;
+
+  MultiLevelTemplateArgumentList TemplateArgs =
+    getTemplateInstantiationArgs(Function);
+
+  // If this is a constructor, instantiate the member initializers.
+  if (const CXXConstructorDecl *Ctor =
+        dyn_cast<CXXConstructorDecl>(PatternDecl)) {
+    InstantiateMemInitializers(cast<CXXConstructorDecl>(Function), Ctor,
+                               TemplateArgs);
+  }
+
+  // Instantiate the function body.
+  OwningStmtResult Body = SubstStmt(Pattern, TemplateArgs);
+
+  if (Body.isInvalid())
+    Function->setInvalidDecl();
+  
+  ActOnFinishFunctionBody(DeclPtrTy::make(Function), move(Body),
+                          /*IsInstantiation=*/true);
+
+  PerformDependentDiagnostics(PatternDecl, TemplateArgs);
+
+  CurContext = PreviousContext;
+
+  DeclGroupRef DG(Function);
+  Consumer.HandleTopLevelDecl(DG);
+
+  // This class may have local implicit instantiations that need to be
+  // instantiation within this scope.
+  PerformPendingImplicitInstantiations(/*LocalOnly=*/true);
+  Scope.Exit();
+
+  if (Recursive) {
+    // Instantiate any pending implicit instantiations found during the
+    // instantiation of this template.
+    PerformPendingImplicitInstantiations();
+
+    // Restore the set of pending implicit instantiations.
+    PendingImplicitInstantiations.swap(SavedPendingImplicitInstantiations);
+  }
+}
+
+/// \brief Instantiate the definition of the given variable from its
+/// template.
+///
+/// \param PointOfInstantiation the point at which the instantiation was
+/// required. Note that this is not precisely a "point of instantiation"
+/// for the function, but it's close.
+///
+/// \param Var the already-instantiated declaration of a static member
+/// variable of a class template specialization.
+///
+/// \param Recursive if true, recursively instantiates any functions that
+/// are required by this instantiation.
+///
+/// \param DefinitionRequired if true, then we are performing an explicit
+/// instantiation where an out-of-line definition of the member variable
+/// is required. Complain if there is no such definition.
+void Sema::InstantiateStaticDataMemberDefinition(
+                                          SourceLocation PointOfInstantiation,
+                                                 VarDecl *Var,
+                                                 bool Recursive,
+                                                 bool DefinitionRequired) {
+  if (Var->isInvalidDecl())
+    return;
+
+  // Find the out-of-line definition of this static data member.
+  VarDecl *Def = Var->getInstantiatedFromStaticDataMember();
+  assert(Def && "This data member was not instantiated from a template?");
+  assert(Def->isStaticDataMember() && "Not a static data member?");  
+  Def = Def->getOutOfLineDefinition();
+
+  if (!Def) {
+    // We did not find an out-of-line definition of this static data member,
+    // so we won't perform any instantiation. Rather, we rely on the user to
+    // instantiate this definition (or provide a specialization for it) in
+    // another translation unit.
+    if (DefinitionRequired) {
+      Def = Var->getInstantiatedFromStaticDataMember();
+      Diag(PointOfInstantiation, 
+           diag::err_explicit_instantiation_undefined_member)
+        << 2 << Var->getDeclName() << Var->getDeclContext();
+      Diag(Def->getLocation(), diag::note_explicit_instantiation_here);
+    }    
+    
+    return;
+  }
+
+  // Never instantiate an explicit specialization.
+  if (Var->getTemplateSpecializationKind() == TSK_ExplicitSpecialization)
+    return;
+  
+  // C++0x [temp.explicit]p9:
+  //   Except for inline functions, other explicit instantiation declarations
+  //   have the effect of suppressing the implicit instantiation of the entity
+  //   to which they refer.
+  if (Var->getTemplateSpecializationKind() 
+        == TSK_ExplicitInstantiationDeclaration)
+    return;
+
+  InstantiatingTemplate Inst(*this, PointOfInstantiation, Var);
+  if (Inst)
+    return;
+
+  // If we're performing recursive template instantiation, create our own
+  // queue of pending implicit instantiations that we will instantiate later,
+  // while we're still within our own instantiation context.
+  std::deque<PendingImplicitInstantiation> SavedPendingImplicitInstantiations;
+  if (Recursive)
+    PendingImplicitInstantiations.swap(SavedPendingImplicitInstantiations);
+
+  // Enter the scope of this instantiation. We don't use
+  // PushDeclContext because we don't have a scope.
+  DeclContext *PreviousContext = CurContext;
+  CurContext = Var->getDeclContext();
+
+  VarDecl *OldVar = Var;
+  Var = cast_or_null<VarDecl>(SubstDecl(Def, Var->getDeclContext(),
+                                          getTemplateInstantiationArgs(Var)));
+  CurContext = PreviousContext;
+
+  if (Var) {
+    MemberSpecializationInfo *MSInfo = OldVar->getMemberSpecializationInfo();
+    assert(MSInfo && "Missing member specialization information?");
+    Var->setTemplateSpecializationKind(MSInfo->getTemplateSpecializationKind(),
+                                       MSInfo->getPointOfInstantiation());
+    DeclGroupRef DG(Var);
+    Consumer.HandleTopLevelDecl(DG);
+  }
+
+  if (Recursive) {
+    // Instantiate any pending implicit instantiations found during the
+    // instantiation of this template.
+    PerformPendingImplicitInstantiations();
+
+    // Restore the set of pending implicit instantiations.
+    PendingImplicitInstantiations.swap(SavedPendingImplicitInstantiations);
+  }
+}
+
+void
+Sema::InstantiateMemInitializers(CXXConstructorDecl *New,
+                                 const CXXConstructorDecl *Tmpl,
+                           const MultiLevelTemplateArgumentList &TemplateArgs) {
+
+  llvm::SmallVector<MemInitTy*, 4> NewInits;
+  bool AnyErrors = false;
+  
+  // Instantiate all the initializers.
+  for (CXXConstructorDecl::init_const_iterator Inits = Tmpl->init_begin(),
+                                            InitsEnd = Tmpl->init_end();
+       Inits != InitsEnd; ++Inits) {
+    CXXBaseOrMemberInitializer *Init = *Inits;
+
+    SourceLocation LParenLoc, RParenLoc;
+    ASTOwningVector<&ActionBase::DeleteExpr> NewArgs(*this);
+    llvm::SmallVector<SourceLocation, 4> CommaLocs;
+
+    // Instantiate the initializer.
+    if (InstantiateInitializer(*this, Init->getInit(), TemplateArgs, 
+                               LParenLoc, CommaLocs, NewArgs, RParenLoc)) {
+      AnyErrors = true;
+      continue;
+    }
+    
+    MemInitResult NewInit;
+    if (Init->isBaseInitializer()) {
+      TypeSourceInfo *BaseTInfo = SubstType(Init->getBaseClassInfo(), 
+                                            TemplateArgs, 
+                                            Init->getSourceLocation(), 
+                                            New->getDeclName());
+      if (!BaseTInfo) {
+        AnyErrors = true;
+        New->setInvalidDecl();
+        continue;
+      }
+      
+      NewInit = BuildBaseInitializer(BaseTInfo->getType(), BaseTInfo,
+                                     (Expr **)NewArgs.data(),
+                                     NewArgs.size(),
+                                     Init->getLParenLoc(),
+                                     Init->getRParenLoc(),
+                                     New->getParent());
+    } else if (Init->isMemberInitializer()) {
+      FieldDecl *Member;
+
+      // Is this an anonymous union?
+      if (FieldDecl *UnionInit = Init->getAnonUnionMember())
+        Member = cast<FieldDecl>(FindInstantiatedDecl(Init->getMemberLocation(),
+                                                      UnionInit, TemplateArgs));
+      else
+        Member = cast<FieldDecl>(FindInstantiatedDecl(Init->getMemberLocation(),
+                                                      Init->getMember(),
+                                                      TemplateArgs));
+
+      NewInit = BuildMemberInitializer(Member, (Expr **)NewArgs.data(),
+                                       NewArgs.size(),
+                                       Init->getSourceLocation(),
+                                       Init->getLParenLoc(),
+                                       Init->getRParenLoc());
+    }
+
+    if (NewInit.isInvalid()) {
+      AnyErrors = true;
+      New->setInvalidDecl();
+    } else {
+      // FIXME: It would be nice if ASTOwningVector had a release function.
+      NewArgs.take();
+
+      NewInits.push_back((MemInitTy *)NewInit.get());
+    }
+  }
+
+  // Assign all the initializers to the new constructor.
+  ActOnMemInitializers(DeclPtrTy::make(New),
+                       /*FIXME: ColonLoc */
+                       SourceLocation(),
+                       NewInits.data(), NewInits.size(),
+                       AnyErrors);
+}
+
+// TODO: this could be templated if the various decl types used the
+// same method name.
+static bool isInstantiationOf(ClassTemplateDecl *Pattern,
+                              ClassTemplateDecl *Instance) {
+  Pattern = Pattern->getCanonicalDecl();
+
+  do {
+    Instance = Instance->getCanonicalDecl();
+    if (Pattern == Instance) return true;
+    Instance = Instance->getInstantiatedFromMemberTemplate();
+  } while (Instance);
+
+  return false;
+}
+
+static bool isInstantiationOf(FunctionTemplateDecl *Pattern,
+                              FunctionTemplateDecl *Instance) {
+  Pattern = Pattern->getCanonicalDecl();
+  
+  do {
+    Instance = Instance->getCanonicalDecl();
+    if (Pattern == Instance) return true;
+    Instance = Instance->getInstantiatedFromMemberTemplate();
+  } while (Instance);
+  
+  return false;
+}
+
+static bool 
+isInstantiationOf(ClassTemplatePartialSpecializationDecl *Pattern,
+                  ClassTemplatePartialSpecializationDecl *Instance) {
+  Pattern 
+    = cast<ClassTemplatePartialSpecializationDecl>(Pattern->getCanonicalDecl());
+  do {
+    Instance = cast<ClassTemplatePartialSpecializationDecl>(
+                                                Instance->getCanonicalDecl());
+    if (Pattern == Instance)
+      return true;
+    Instance = Instance->getInstantiatedFromMember();
+  } while (Instance);
+  
+  return false;
+}
+
+static bool isInstantiationOf(CXXRecordDecl *Pattern,
+                              CXXRecordDecl *Instance) {
+  Pattern = Pattern->getCanonicalDecl();
+
+  do {
+    Instance = Instance->getCanonicalDecl();
+    if (Pattern == Instance) return true;
+    Instance = Instance->getInstantiatedFromMemberClass();
+  } while (Instance);
+
+  return false;
+}
+
+static bool isInstantiationOf(FunctionDecl *Pattern,
+                              FunctionDecl *Instance) {
+  Pattern = Pattern->getCanonicalDecl();
+
+  do {
+    Instance = Instance->getCanonicalDecl();
+    if (Pattern == Instance) return true;
+    Instance = Instance->getInstantiatedFromMemberFunction();
+  } while (Instance);
+
+  return false;
+}
+
+static bool isInstantiationOf(EnumDecl *Pattern,
+                              EnumDecl *Instance) {
+  Pattern = Pattern->getCanonicalDecl();
+
+  do {
+    Instance = Instance->getCanonicalDecl();
+    if (Pattern == Instance) return true;
+    Instance = Instance->getInstantiatedFromMemberEnum();
+  } while (Instance);
+
+  return false;
+}
+
+static bool isInstantiationOf(UsingShadowDecl *Pattern,
+                              UsingShadowDecl *Instance,
+                              ASTContext &C) {
+  return C.getInstantiatedFromUsingShadowDecl(Instance) == Pattern;
+}
+
+static bool isInstantiationOf(UsingDecl *Pattern,
+                              UsingDecl *Instance,
+                              ASTContext &C) {
+  return C.getInstantiatedFromUsingDecl(Instance) == Pattern;
+}
+
+static bool isInstantiationOf(UnresolvedUsingValueDecl *Pattern,
+                              UsingDecl *Instance,
+                              ASTContext &C) {
+  return C.getInstantiatedFromUsingDecl(Instance) == Pattern;
+}
+
+static bool isInstantiationOf(UnresolvedUsingTypenameDecl *Pattern,
+                              UsingDecl *Instance,
+                              ASTContext &C) {
+  return C.getInstantiatedFromUsingDecl(Instance) == Pattern;
+}
+
+static bool isInstantiationOfStaticDataMember(VarDecl *Pattern,
+                                              VarDecl *Instance) {
+  assert(Instance->isStaticDataMember());
+
+  Pattern = Pattern->getCanonicalDecl();
+
+  do {
+    Instance = Instance->getCanonicalDecl();
+    if (Pattern == Instance) return true;
+    Instance = Instance->getInstantiatedFromStaticDataMember();
+  } while (Instance);
+
+  return false;
+}
+
+// Other is the prospective instantiation
+// D is the prospective pattern
+static bool isInstantiationOf(ASTContext &Ctx, NamedDecl *D, Decl *Other) {
+  if (D->getKind() != Other->getKind()) {
+    if (UnresolvedUsingTypenameDecl *UUD
+          = dyn_cast<UnresolvedUsingTypenameDecl>(D)) {
+      if (UsingDecl *UD = dyn_cast<UsingDecl>(Other)) {
+        return isInstantiationOf(UUD, UD, Ctx);
+      }
+    }
+
+    if (UnresolvedUsingValueDecl *UUD
+          = dyn_cast<UnresolvedUsingValueDecl>(D)) {
+      if (UsingDecl *UD = dyn_cast<UsingDecl>(Other)) {
+        return isInstantiationOf(UUD, UD, Ctx);
+      }
+    }
+
+    return false;
+  }
+
+  if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(Other))
+    return isInstantiationOf(cast<CXXRecordDecl>(D), Record);
+
+  if (FunctionDecl *Function = dyn_cast<FunctionDecl>(Other))
+    return isInstantiationOf(cast<FunctionDecl>(D), Function);
+
+  if (EnumDecl *Enum = dyn_cast<EnumDecl>(Other))
+    return isInstantiationOf(cast<EnumDecl>(D), Enum);
+
+  if (VarDecl *Var = dyn_cast<VarDecl>(Other))
+    if (Var->isStaticDataMember())
+      return isInstantiationOfStaticDataMember(cast<VarDecl>(D), Var);
+
+  if (ClassTemplateDecl *Temp = dyn_cast<ClassTemplateDecl>(Other))
+    return isInstantiationOf(cast<ClassTemplateDecl>(D), Temp);
+
+  if (FunctionTemplateDecl *Temp = dyn_cast<FunctionTemplateDecl>(Other))
+    return isInstantiationOf(cast<FunctionTemplateDecl>(D), Temp);
+
+  if (ClassTemplatePartialSpecializationDecl *PartialSpec
+        = dyn_cast<ClassTemplatePartialSpecializationDecl>(Other))
+    return isInstantiationOf(cast<ClassTemplatePartialSpecializationDecl>(D),
+                             PartialSpec);
+
+  if (FieldDecl *Field = dyn_cast<FieldDecl>(Other)) {
+    if (!Field->getDeclName()) {
+      // This is an unnamed field.
+      return Ctx.getInstantiatedFromUnnamedFieldDecl(Field) ==
+        cast<FieldDecl>(D);
+    }
+  }
+
+  if (UsingDecl *Using = dyn_cast<UsingDecl>(Other))
+    return isInstantiationOf(cast<UsingDecl>(D), Using, Ctx);
+
+  if (UsingShadowDecl *Shadow = dyn_cast<UsingShadowDecl>(Other))
+    return isInstantiationOf(cast<UsingShadowDecl>(D), Shadow, Ctx);
+
+  return D->getDeclName() && isa<NamedDecl>(Other) &&
+    D->getDeclName() == cast<NamedDecl>(Other)->getDeclName();
+}
+
+template<typename ForwardIterator>
+static NamedDecl *findInstantiationOf(ASTContext &Ctx,
+                                      NamedDecl *D,
+                                      ForwardIterator first,
+                                      ForwardIterator last) {
+  for (; first != last; ++first)
+    if (isInstantiationOf(Ctx, D, *first))
+      return cast<NamedDecl>(*first);
+
+  return 0;
+}
+
+/// \brief Finds the instantiation of the given declaration context
+/// within the current instantiation.
+///
+/// \returns NULL if there was an error
+DeclContext *Sema::FindInstantiatedContext(SourceLocation Loc, DeclContext* DC,
+                          const MultiLevelTemplateArgumentList &TemplateArgs) {
+  if (NamedDecl *D = dyn_cast<NamedDecl>(DC)) {
+    Decl* ID = FindInstantiatedDecl(Loc, D, TemplateArgs);
+    return cast_or_null<DeclContext>(ID);
+  } else return DC;
+}
+
+/// \brief Find the instantiation of the given declaration within the
+/// current instantiation.
+///
+/// This routine is intended to be used when \p D is a declaration
+/// referenced from within a template, that needs to mapped into the
+/// corresponding declaration within an instantiation. For example,
+/// given:
+///
+/// \code
+/// template<typename T>
+/// struct X {
+///   enum Kind {
+///     KnownValue = sizeof(T)
+///   };
+///
+///   bool getKind() const { return KnownValue; }
+/// };
+///
+/// template struct X<int>;
+/// \endcode
+///
+/// In the instantiation of X<int>::getKind(), we need to map the
+/// EnumConstantDecl for KnownValue (which refers to
+/// X<T>::<Kind>::KnownValue) to its instantiation
+/// (X<int>::<Kind>::KnownValue). InstantiateCurrentDeclRef() performs
+/// this mapping from within the instantiation of X<int>.
+NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D,
+                          const MultiLevelTemplateArgumentList &TemplateArgs) {
+  DeclContext *ParentDC = D->getDeclContext();
+  if (isa<ParmVarDecl>(D) || isa<NonTypeTemplateParmDecl>(D) ||
+      isa<TemplateTypeParmDecl>(D) || isa<TemplateTemplateParmDecl>(D) ||
+      ParentDC->isFunctionOrMethod()) {
+    // D is a local of some kind. Look into the map of local
+    // declarations to their instantiations.
+    return cast<NamedDecl>(CurrentInstantiationScope->getInstantiationOf(D));
+  }
+
+  if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(D)) {
+    if (!Record->isDependentContext())
+      return D;
+    
+    // If the RecordDecl is actually the injected-class-name or a
+    // "templated" declaration for a class template, class template
+    // partial specialization, or a member class of a class template,
+    // substitute into the injected-class-name of the class template
+    // or partial specialization to find the new DeclContext.
+    QualType T;
+    ClassTemplateDecl *ClassTemplate = Record->getDescribedClassTemplate();
+    
+    if (ClassTemplate) {
+      T = ClassTemplate->getInjectedClassNameSpecialization(Context);
+    } else if (ClassTemplatePartialSpecializationDecl *PartialSpec
+                 = dyn_cast<ClassTemplatePartialSpecializationDecl>(Record)) {
+      ClassTemplate = PartialSpec->getSpecializedTemplate();
+
+      // If we call SubstType with an InjectedClassNameType here we
+      // can end up in an infinite loop.
+      T = Context.getTypeDeclType(Record);
+      assert(isa<InjectedClassNameType>(T) &&
+             "type of partial specialization is not an InjectedClassNameType");
+      T = cast<InjectedClassNameType>(T)->getInjectedSpecializationType();
+    }  
+    
+    if (!T.isNull()) {
+      // Substitute into the injected-class-name to get the type
+      // corresponding to the instantiation we want, which may also be
+      // the current instantiation (if we're in a template
+      // definition). This substitution should never fail, since we
+      // know we can instantiate the injected-class-name or we
+      // wouldn't have gotten to the injected-class-name!  
+
+      // FIXME: Can we use the CurrentInstantiationScope to avoid this
+      // extra instantiation in the common case?
+      T = SubstType(T, TemplateArgs, SourceLocation(), DeclarationName());
+      assert(!T.isNull() && "Instantiation of injected-class-name cannot fail.");
+    
+      if (!T->isDependentType()) {
+        assert(T->isRecordType() && "Instantiation must produce a record type");
+        return T->getAs<RecordType>()->getDecl();
+      }
+    
+      // We are performing "partial" template instantiation to create
+      // the member declarations for the members of a class template
+      // specialization. Therefore, D is actually referring to something
+      // in the current instantiation. Look through the current
+      // context, which contains actual instantiations, to find the
+      // instantiation of the "current instantiation" that D refers
+      // to.
+      bool SawNonDependentContext = false;
+      for (DeclContext *DC = CurContext; !DC->isFileContext();
+           DC = DC->getParent()) {
+        if (ClassTemplateSpecializationDecl *Spec
+                          = dyn_cast<ClassTemplateSpecializationDecl>(DC))
+          if (isInstantiationOf(ClassTemplate, 
+                                Spec->getSpecializedTemplate()))
+            return Spec;
+
+        if (!DC->isDependentContext())
+          SawNonDependentContext = true;
+      }
+
+      // We're performing "instantiation" of a member of the current
+      // instantiation while we are type-checking the
+      // definition. Compute the declaration context and return that.
+      assert(!SawNonDependentContext && 
+             "No dependent context while instantiating record");
+      DeclContext *DC = computeDeclContext(T);
+      assert(DC && 
+             "Unable to find declaration for the current instantiation");
+      return cast<CXXRecordDecl>(DC);
+    }
+
+    // Fall through to deal with other dependent record types (e.g.,
+    // anonymous unions in class templates).
+  }
+
+  if (!ParentDC->isDependentContext())
+    return D;
+  
+  ParentDC = FindInstantiatedContext(Loc, ParentDC, TemplateArgs);
+  if (!ParentDC)
+    return 0;
+
+  if (ParentDC != D->getDeclContext()) {
+    // We performed some kind of instantiation in the parent context,
+    // so now we need to look into the instantiated parent context to
+    // find the instantiation of the declaration D.
+
+    // If our context used to be dependent, we may need to instantiate
+    // it before performing lookup into that context.
+    if (CXXRecordDecl *Spec = dyn_cast<CXXRecordDecl>(ParentDC)) {
+      if (!Spec->isDependentContext()) {
+        QualType T = Context.getTypeDeclType(Spec);
+        const RecordType *Tag = T->getAs<RecordType>();
+        assert(Tag && "type of non-dependent record is not a RecordType");
+        if (!Tag->isBeingDefined() &&
+            RequireCompleteType(Loc, T, diag::err_incomplete_type))
+          return 0;
+      }
+    }
+
+    NamedDecl *Result = 0;
+    if (D->getDeclName()) {
+      DeclContext::lookup_result Found = ParentDC->lookup(D->getDeclName());
+      Result = findInstantiationOf(Context, D, Found.first, Found.second);
+    } else {
+      // Since we don't have a name for the entity we're looking for,
+      // our only option is to walk through all of the declarations to
+      // find that name. This will occur in a few cases:
+      //
+      //   - anonymous struct/union within a template
+      //   - unnamed class/struct/union/enum within a template
+      //
+      // FIXME: Find a better way to find these instantiations!
+      Result = findInstantiationOf(Context, D,
+                                   ParentDC->decls_begin(),
+                                   ParentDC->decls_end());
+    }
+
+    // UsingShadowDecls can instantiate to nothing because of using hiding.
+    assert((Result || isa<UsingShadowDecl>(D) || D->isInvalidDecl() ||
+            cast<Decl>(ParentDC)->isInvalidDecl())
+           && "Unable to find instantiation of declaration!");
+
+    D = Result;
+  }
+
+  return D;
+}
+
+/// \brief Performs template instantiation for all implicit template
+/// instantiations we have seen until this point.
+void Sema::PerformPendingImplicitInstantiations(bool LocalOnly) {
+  while (!PendingLocalImplicitInstantiations.empty() ||
+         (!LocalOnly && !PendingImplicitInstantiations.empty())) {
+    PendingImplicitInstantiation Inst;
+
+    if (PendingLocalImplicitInstantiations.empty()) {
+      Inst = PendingImplicitInstantiations.front();
+      PendingImplicitInstantiations.pop_front();
+    } else {
+      Inst = PendingLocalImplicitInstantiations.front();
+      PendingLocalImplicitInstantiations.pop_front();
+    }
+
+    // Instantiate function definitions
+    if (FunctionDecl *Function = dyn_cast<FunctionDecl>(Inst.first)) {
+      PrettyStackTraceActionsDecl CrashInfo(DeclPtrTy::make(Function),
+                                            Function->getLocation(), *this,
+                                            Context.getSourceManager(),
+                                           "instantiating function definition");
+
+      if (!Function->getBody())
+        InstantiateFunctionDefinition(/*FIXME:*/Inst.second, Function, true);
+      continue;
+    }
+
+    // Instantiate static data member definitions.
+    VarDecl *Var = cast<VarDecl>(Inst.first);
+    assert(Var->isStaticDataMember() && "Not a static data member?");
+
+    // Don't try to instantiate declarations if the most recent redeclaration
+    // is invalid.
+    if (Var->getMostRecentDeclaration()->isInvalidDecl())
+      continue;
+
+    // Check if the most recent declaration has changed the specialization kind
+    // and removed the need for implicit instantiation.
+    switch (Var->getMostRecentDeclaration()->getTemplateSpecializationKind()) {
+    case TSK_Undeclared:
+      assert(false && "Cannot instantitiate an undeclared specialization.");
+    case TSK_ExplicitInstantiationDeclaration:
+    case TSK_ExplicitInstantiationDefinition:
+    case TSK_ExplicitSpecialization:
+      continue;  // No longer need implicit instantiation.
+    case TSK_ImplicitInstantiation:
+      break;
+    }
+
+    PrettyStackTraceActionsDecl CrashInfo(DeclPtrTy::make(Var),
+                                          Var->getLocation(), *this,
+                                          Context.getSourceManager(),
+                                          "instantiating static data member "
+                                          "definition");
+
+    InstantiateStaticDataMemberDefinition(/*FIXME:*/Inst.second, Var, true);
+  }
+}
+
+void Sema::PerformDependentDiagnostics(const DeclContext *Pattern,
+                       const MultiLevelTemplateArgumentList &TemplateArgs) {
+  for (DeclContext::ddiag_iterator I = Pattern->ddiag_begin(),
+         E = Pattern->ddiag_end(); I != E; ++I) {
+    DependentDiagnostic *DD = *I;
+
+    switch (DD->getKind()) {
+    case DependentDiagnostic::Access:
+      HandleDependentAccessCheck(*DD, TemplateArgs);
+      break;
+    }
+  }
+}
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
new file mode 100644
index 0000000..4f1bea1
--- /dev/null
+++ b/lib/Sema/SemaType.cpp
@@ -0,0 +1,2100 @@
+//===--- SemaType.cpp - Semantic Analysis for Types -----------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements type-related semantic analysis.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Sema.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/CXXInheritance.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/TypeLoc.h"
+#include "clang/AST/TypeLocVisitor.h"
+#include "clang/AST/Expr.h"
+#include "clang/Basic/PartialDiagnostic.h"
+#include "clang/Parse/DeclSpec.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/Support/ErrorHandling.h"
+using namespace clang;
+
+/// \brief Perform adjustment on the parameter type of a function.
+///
+/// This routine adjusts the given parameter type @p T to the actual
+/// parameter type used by semantic analysis (C99 6.7.5.3p[7,8],
+/// C++ [dcl.fct]p3). The adjusted parameter type is returned.
+QualType Sema::adjustParameterType(QualType T) {
+  // C99 6.7.5.3p7:
+  //   A declaration of a parameter as "array of type" shall be
+  //   adjusted to "qualified pointer to type", where the type
+  //   qualifiers (if any) are those specified within the [ and ] of
+  //   the array type derivation.
+  if (T->isArrayType())
+    return Context.getArrayDecayedType(T);
+  
+  // C99 6.7.5.3p8:
+  //   A declaration of a parameter as "function returning type"
+  //   shall be adjusted to "pointer to function returning type", as
+  //   in 6.3.2.1.
+  if (T->isFunctionType())
+    return Context.getPointerType(T);
+
+  return T;
+}
+
+
+
+/// isOmittedBlockReturnType - Return true if this declarator is missing a
+/// return type because this is a omitted return type on a block literal. 
+static bool isOmittedBlockReturnType(const Declarator &D) {
+  if (D.getContext() != Declarator::BlockLiteralContext ||
+      D.getDeclSpec().hasTypeSpecifier())
+    return false;
+  
+  if (D.getNumTypeObjects() == 0)
+    return true;   // ^{ ... }
+  
+  if (D.getNumTypeObjects() == 1 &&
+      D.getTypeObject(0).Kind == DeclaratorChunk::Function)
+    return true;   // ^(int X, float Y) { ... }
+  
+  return false;
+}
+
+typedef std::pair<const AttributeList*,QualType> DelayedAttribute;
+typedef llvm::SmallVectorImpl<DelayedAttribute> DelayedAttributeSet;
+
+static void ProcessTypeAttributeList(Sema &S, QualType &Type,
+                                     bool IsDeclSpec,
+                                     const AttributeList *Attrs,
+                                     DelayedAttributeSet &DelayedFnAttrs);
+static bool ProcessFnAttr(Sema &S, QualType &Type, const AttributeList &Attr);
+
+static void ProcessDelayedFnAttrs(Sema &S, QualType &Type,
+                                  DelayedAttributeSet &Attrs) {
+  for (DelayedAttributeSet::iterator I = Attrs.begin(),
+         E = Attrs.end(); I != E; ++I)
+    if (ProcessFnAttr(S, Type, *I->first))
+      S.Diag(I->first->getLoc(), diag::warn_function_attribute_wrong_type)
+        << I->first->getName() << I->second;
+  Attrs.clear();
+}
+
+static void DiagnoseDelayedFnAttrs(Sema &S, DelayedAttributeSet &Attrs) {
+  for (DelayedAttributeSet::iterator I = Attrs.begin(),
+         E = Attrs.end(); I != E; ++I) {
+    S.Diag(I->first->getLoc(), diag::warn_function_attribute_wrong_type)
+      << I->first->getName() << I->second;
+  }
+  Attrs.clear();
+}
+
+/// \brief Convert the specified declspec to the appropriate type
+/// object.
+/// \param D  the declarator containing the declaration specifier.
+/// \returns The type described by the declaration specifiers.  This function
+/// never returns null.
+static QualType ConvertDeclSpecToType(Sema &TheSema,
+                                      Declarator &TheDeclarator,
+                                      DelayedAttributeSet &Delayed) {
+  // FIXME: Should move the logic from DeclSpec::Finish to here for validity
+  // checking.
+  const DeclSpec &DS = TheDeclarator.getDeclSpec();
+  SourceLocation DeclLoc = TheDeclarator.getIdentifierLoc();
+  if (DeclLoc.isInvalid())
+    DeclLoc = DS.getSourceRange().getBegin();
+  
+  ASTContext &Context = TheSema.Context;
+
+  QualType Result;
+  switch (DS.getTypeSpecType()) {
+  case DeclSpec::TST_void:
+    Result = Context.VoidTy;
+    break;
+  case DeclSpec::TST_char:
+    if (DS.getTypeSpecSign() == DeclSpec::TSS_unspecified)
+      Result = Context.CharTy;
+    else if (DS.getTypeSpecSign() == DeclSpec::TSS_signed)
+      Result = Context.SignedCharTy;
+    else {
+      assert(DS.getTypeSpecSign() == DeclSpec::TSS_unsigned &&
+             "Unknown TSS value");
+      Result = Context.UnsignedCharTy;
+    }
+    break;
+  case DeclSpec::TST_wchar:
+    if (DS.getTypeSpecSign() == DeclSpec::TSS_unspecified)
+      Result = Context.WCharTy;
+    else if (DS.getTypeSpecSign() == DeclSpec::TSS_signed) {
+      TheSema.Diag(DS.getTypeSpecSignLoc(), diag::ext_invalid_sign_spec)
+        << DS.getSpecifierName(DS.getTypeSpecType());
+      Result = Context.getSignedWCharType();
+    } else {
+      assert(DS.getTypeSpecSign() == DeclSpec::TSS_unsigned &&
+        "Unknown TSS value");
+      TheSema.Diag(DS.getTypeSpecSignLoc(), diag::ext_invalid_sign_spec)
+        << DS.getSpecifierName(DS.getTypeSpecType());
+      Result = Context.getUnsignedWCharType();
+    }
+    break;
+  case DeclSpec::TST_char16:
+      assert(DS.getTypeSpecSign() == DeclSpec::TSS_unspecified &&
+        "Unknown TSS value");
+      Result = Context.Char16Ty;
+    break;
+  case DeclSpec::TST_char32:
+      assert(DS.getTypeSpecSign() == DeclSpec::TSS_unspecified &&
+        "Unknown TSS value");
+      Result = Context.Char32Ty;
+    break;
+  case DeclSpec::TST_unspecified:
+    // "<proto1,proto2>" is an objc qualified ID with a missing id.
+    if (DeclSpec::ProtocolQualifierListTy PQ = DS.getProtocolQualifiers()) {
+      Result = Context.getObjCObjectPointerType(Context.ObjCBuiltinIdTy,
+                                                (ObjCProtocolDecl**)PQ,
+                                                DS.getNumProtocolQualifiers());
+      break;
+    }
+    
+    // If this is a missing declspec in a block literal return context, then it
+    // is inferred from the return statements inside the block.
+    if (isOmittedBlockReturnType(TheDeclarator)) {
+      Result = Context.DependentTy;
+      break;
+    }
+
+    // Unspecified typespec defaults to int in C90.  However, the C90 grammar
+    // [C90 6.5] only allows a decl-spec if there was *some* type-specifier,
+    // type-qualifier, or storage-class-specifier.  If not, emit an extwarn.
+    // Note that the one exception to this is function definitions, which are
+    // allowed to be completely missing a declspec.  This is handled in the
+    // parser already though by it pretending to have seen an 'int' in this
+    // case.
+    if (TheSema.getLangOptions().ImplicitInt) {
+      // In C89 mode, we only warn if there is a completely missing declspec
+      // when one is not allowed.
+      if (DS.isEmpty()) {
+        TheSema.Diag(DeclLoc, diag::ext_missing_declspec)
+          << DS.getSourceRange()
+        << FixItHint::CreateInsertion(DS.getSourceRange().getBegin(), "int");
+      }
+    } else if (!DS.hasTypeSpecifier()) {
+      // C99 and C++ require a type specifier.  For example, C99 6.7.2p2 says:
+      // "At least one type specifier shall be given in the declaration
+      // specifiers in each declaration, and in the specifier-qualifier list in
+      // each struct declaration and type name."
+      // FIXME: Does Microsoft really have the implicit int extension in C++?
+      if (TheSema.getLangOptions().CPlusPlus &&
+          !TheSema.getLangOptions().Microsoft) {
+        TheSema.Diag(DeclLoc, diag::err_missing_type_specifier)
+          << DS.getSourceRange();
+
+        // When this occurs in C++ code, often something is very broken with the
+        // value being declared, poison it as invalid so we don't get chains of
+        // errors.
+        TheDeclarator.setInvalidType(true);
+      } else {
+        TheSema.Diag(DeclLoc, diag::ext_missing_type_specifier)
+          << DS.getSourceRange();
+      }
+    }
+
+    // FALL THROUGH.
+  case DeclSpec::TST_int: {
+    if (DS.getTypeSpecSign() != DeclSpec::TSS_unsigned) {
+      switch (DS.getTypeSpecWidth()) {
+      case DeclSpec::TSW_unspecified: Result = Context.IntTy; break;
+      case DeclSpec::TSW_short:       Result = Context.ShortTy; break;
+      case DeclSpec::TSW_long:        Result = Context.LongTy; break;
+      case DeclSpec::TSW_longlong:
+        Result = Context.LongLongTy;
+          
+        // long long is a C99 feature.
+        if (!TheSema.getLangOptions().C99 &&
+            !TheSema.getLangOptions().CPlusPlus0x)
+          TheSema.Diag(DS.getTypeSpecWidthLoc(), diag::ext_longlong);
+        break;
+      }
+    } else {
+      switch (DS.getTypeSpecWidth()) {
+      case DeclSpec::TSW_unspecified: Result = Context.UnsignedIntTy; break;
+      case DeclSpec::TSW_short:       Result = Context.UnsignedShortTy; break;
+      case DeclSpec::TSW_long:        Result = Context.UnsignedLongTy; break;
+      case DeclSpec::TSW_longlong:
+        Result = Context.UnsignedLongLongTy;
+          
+        // long long is a C99 feature.
+        if (!TheSema.getLangOptions().C99 &&
+            !TheSema.getLangOptions().CPlusPlus0x)
+          TheSema.Diag(DS.getTypeSpecWidthLoc(), diag::ext_longlong);
+        break;
+      }
+    }
+    break;
+  }
+  case DeclSpec::TST_float: Result = Context.FloatTy; break;
+  case DeclSpec::TST_double:
+    if (DS.getTypeSpecWidth() == DeclSpec::TSW_long)
+      Result = Context.LongDoubleTy;
+    else
+      Result = Context.DoubleTy;
+    break;
+  case DeclSpec::TST_bool: Result = Context.BoolTy; break; // _Bool or bool
+  case DeclSpec::TST_decimal32:    // _Decimal32
+  case DeclSpec::TST_decimal64:    // _Decimal64
+  case DeclSpec::TST_decimal128:   // _Decimal128
+    TheSema.Diag(DS.getTypeSpecTypeLoc(), diag::err_decimal_unsupported);
+    Result = Context.IntTy;
+    TheDeclarator.setInvalidType(true);
+    break;
+  case DeclSpec::TST_class:
+  case DeclSpec::TST_enum:
+  case DeclSpec::TST_union:
+  case DeclSpec::TST_struct: {
+    TypeDecl *D 
+      = dyn_cast_or_null<TypeDecl>(static_cast<Decl *>(DS.getTypeRep()));
+    if (!D) {
+      // This can happen in C++ with ambiguous lookups.
+      Result = Context.IntTy;
+      TheDeclarator.setInvalidType(true);
+      break;
+    }
+
+    // If the type is deprecated or unavailable, diagnose it.
+    TheSema.DiagnoseUseOfDecl(D, DS.getTypeSpecTypeLoc());
+    
+    assert(DS.getTypeSpecWidth() == 0 && DS.getTypeSpecComplex() == 0 &&
+           DS.getTypeSpecSign() == 0 && "No qualifiers on tag names!");
+    
+    // TypeQuals handled by caller.
+    Result = Context.getTypeDeclType(D);
+
+    // In C++, make an ElaboratedType.
+    if (TheSema.getLangOptions().CPlusPlus) {
+      TagDecl::TagKind Tag
+        = TagDecl::getTagKindForTypeSpec(DS.getTypeSpecType());
+      Result = TheSema.getQualifiedNameType(DS.getTypeSpecScope(), Result);
+      Result = Context.getElaboratedType(Result, Tag);
+    }
+
+    if (D->isInvalidDecl())
+      TheDeclarator.setInvalidType(true);
+    break;
+  }
+  case DeclSpec::TST_typename: {
+    assert(DS.getTypeSpecWidth() == 0 && DS.getTypeSpecComplex() == 0 &&
+           DS.getTypeSpecSign() == 0 &&
+           "Can't handle qualifiers on typedef names yet!");
+    Result = TheSema.GetTypeFromParser(DS.getTypeRep());
+
+    if (DeclSpec::ProtocolQualifierListTy PQ = DS.getProtocolQualifiers()) {
+      if (const ObjCInterfaceType *
+            Interface = Result->getAs<ObjCInterfaceType>()) {
+        // It would be nice if protocol qualifiers were only stored with the
+        // ObjCObjectPointerType. Unfortunately, this isn't possible due
+        // to the following typedef idiom (which is uncommon, but allowed):
+        //
+        // typedef Foo<P> T;
+        // static void func() {
+        //   Foo<P> *yy;
+        //   T *zz;
+        // }
+        Result = Context.getObjCInterfaceType(Interface->getDecl(),
+                                              (ObjCProtocolDecl**)PQ,
+                                              DS.getNumProtocolQualifiers());
+      } else if (Result->isObjCIdType())
+        // id<protocol-list>
+        Result = Context.getObjCObjectPointerType(Context.ObjCBuiltinIdTy,
+                        (ObjCProtocolDecl**)PQ, DS.getNumProtocolQualifiers());
+      else if (Result->isObjCClassType()) {
+        // Class<protocol-list>
+        Result = Context.getObjCObjectPointerType(Context.ObjCBuiltinClassTy,
+                        (ObjCProtocolDecl**)PQ, DS.getNumProtocolQualifiers());
+      } else {
+        TheSema.Diag(DeclLoc, diag::err_invalid_protocol_qualifiers)
+          << DS.getSourceRange();
+        TheDeclarator.setInvalidType(true);
+      }
+    }
+
+    // TypeQuals handled by caller.
+    break;
+  }
+  case DeclSpec::TST_typeofType:
+    // FIXME: Preserve type source info.
+    Result = TheSema.GetTypeFromParser(DS.getTypeRep());
+    assert(!Result.isNull() && "Didn't get a type for typeof?");
+    // TypeQuals handled by caller.
+    Result = Context.getTypeOfType(Result);
+    break;
+  case DeclSpec::TST_typeofExpr: {
+    Expr *E = static_cast<Expr *>(DS.getTypeRep());
+    assert(E && "Didn't get an expression for typeof?");
+    // TypeQuals handled by caller.
+    Result = TheSema.BuildTypeofExprType(E);
+    if (Result.isNull()) {
+      Result = Context.IntTy;
+      TheDeclarator.setInvalidType(true);
+    }
+    break;
+  }
+  case DeclSpec::TST_decltype: {
+    Expr *E = static_cast<Expr *>(DS.getTypeRep());
+    assert(E && "Didn't get an expression for decltype?");
+    // TypeQuals handled by caller.
+    Result = TheSema.BuildDecltypeType(E);
+    if (Result.isNull()) {
+      Result = Context.IntTy;
+      TheDeclarator.setInvalidType(true);
+    }
+    break;
+  }
+  case DeclSpec::TST_auto: {
+    // TypeQuals handled by caller.
+    Result = Context.UndeducedAutoTy;
+    break;
+  }
+
+  case DeclSpec::TST_error:
+    Result = Context.IntTy;
+    TheDeclarator.setInvalidType(true);
+    break;
+  }
+
+  // Handle complex types.
+  if (DS.getTypeSpecComplex() == DeclSpec::TSC_complex) {
+    if (TheSema.getLangOptions().Freestanding)
+      TheSema.Diag(DS.getTypeSpecComplexLoc(), diag::ext_freestanding_complex);
+    Result = Context.getComplexType(Result);
+  } else if (DS.isTypeAltiVecVector()) {
+    unsigned typeSize = static_cast<unsigned>(Context.getTypeSize(Result));
+    assert(typeSize > 0 && "type size for vector must be greater than 0 bits");
+    Result = Context.getVectorType(Result, 128/typeSize, true,
+      DS.isTypeAltiVecPixel());
+  }
+
+  assert(DS.getTypeSpecComplex() != DeclSpec::TSC_imaginary &&
+         "FIXME: imaginary types not supported yet!");
+
+  // See if there are any attributes on the declspec that apply to the type (as
+  // opposed to the decl).
+  if (const AttributeList *AL = DS.getAttributes())
+    ProcessTypeAttributeList(TheSema, Result, true, AL, Delayed);
+
+  // Apply const/volatile/restrict qualifiers to T.
+  if (unsigned TypeQuals = DS.getTypeQualifiers()) {
+
+    // Enforce C99 6.7.3p2: "Types other than pointer types derived from object
+    // or incomplete types shall not be restrict-qualified."  C++ also allows
+    // restrict-qualified references.
+    if (TypeQuals & DeclSpec::TQ_restrict) {
+      if (Result->isAnyPointerType() || Result->isReferenceType()) {
+        QualType EltTy;
+        if (Result->isObjCObjectPointerType())
+          EltTy = Result;
+        else
+          EltTy = Result->isPointerType() ?
+                    Result->getAs<PointerType>()->getPointeeType() :
+                    Result->getAs<ReferenceType>()->getPointeeType();
+
+        // If we have a pointer or reference, the pointee must have an object
+        // incomplete type.
+        if (!EltTy->isIncompleteOrObjectType()) {
+          TheSema.Diag(DS.getRestrictSpecLoc(),
+               diag::err_typecheck_invalid_restrict_invalid_pointee)
+            << EltTy << DS.getSourceRange();
+          TypeQuals &= ~DeclSpec::TQ_restrict; // Remove the restrict qualifier.
+        }
+      } else {
+        TheSema.Diag(DS.getRestrictSpecLoc(),
+             diag::err_typecheck_invalid_restrict_not_pointer)
+          << Result << DS.getSourceRange();
+        TypeQuals &= ~DeclSpec::TQ_restrict; // Remove the restrict qualifier.
+      }
+    }
+
+    // Warn about CV qualifiers on functions: C99 6.7.3p8: "If the specification
+    // of a function type includes any type qualifiers, the behavior is
+    // undefined."
+    if (Result->isFunctionType() && TypeQuals) {
+      // Get some location to point at, either the C or V location.
+      SourceLocation Loc;
+      if (TypeQuals & DeclSpec::TQ_const)
+        Loc = DS.getConstSpecLoc();
+      else if (TypeQuals & DeclSpec::TQ_volatile)
+        Loc = DS.getVolatileSpecLoc();
+      else {
+        assert((TypeQuals & DeclSpec::TQ_restrict) &&
+               "Has CVR quals but not C, V, or R?");
+        Loc = DS.getRestrictSpecLoc();
+      }
+      TheSema.Diag(Loc, diag::warn_typecheck_function_qualifiers)
+        << Result << DS.getSourceRange();
+    }
+
+    // C++ [dcl.ref]p1:
+    //   Cv-qualified references are ill-formed except when the
+    //   cv-qualifiers are introduced through the use of a typedef
+    //   (7.1.3) or of a template type argument (14.3), in which
+    //   case the cv-qualifiers are ignored.
+    // FIXME: Shouldn't we be checking SCS_typedef here?
+    if (DS.getTypeSpecType() == DeclSpec::TST_typename &&
+        TypeQuals && Result->isReferenceType()) {
+      TypeQuals &= ~DeclSpec::TQ_const;
+      TypeQuals &= ~DeclSpec::TQ_volatile;
+    }
+
+    Qualifiers Quals = Qualifiers::fromCVRMask(TypeQuals);
+    Result = Context.getQualifiedType(Result, Quals);
+  }
+
+  return Result;
+}
+
+static std::string getPrintableNameForEntity(DeclarationName Entity) {
+  if (Entity)
+    return Entity.getAsString();
+
+  return "type name";
+}
+
+/// \brief Build a pointer type.
+///
+/// \param T The type to which we'll be building a pointer.
+///
+/// \param Quals The cvr-qualifiers to be applied to the pointer type.
+///
+/// \param Loc The location of the entity whose type involves this
+/// pointer type or, if there is no such entity, the location of the
+/// type that will have pointer type.
+///
+/// \param Entity The name of the entity that involves the pointer
+/// type, if known.
+///
+/// \returns A suitable pointer type, if there are no
+/// errors. Otherwise, returns a NULL type.
+QualType Sema::BuildPointerType(QualType T, unsigned Quals,
+                                SourceLocation Loc, DeclarationName Entity) {
+  if (T->isReferenceType()) {
+    // C++ 8.3.2p4: There shall be no ... pointers to references ...
+    Diag(Loc, diag::err_illegal_decl_pointer_to_reference)
+      << getPrintableNameForEntity(Entity) << T;
+    return QualType();
+  }
+
+  Qualifiers Qs = Qualifiers::fromCVRMask(Quals);
+
+  // Enforce C99 6.7.3p2: "Types other than pointer types derived from
+  // object or incomplete types shall not be restrict-qualified."
+  if (Qs.hasRestrict() && !T->isIncompleteOrObjectType()) {
+    Diag(Loc, diag::err_typecheck_invalid_restrict_invalid_pointee)
+      << T;
+    Qs.removeRestrict();
+  }
+
+  assert(!T->isObjCInterfaceType() && "Should build ObjCObjectPointerType");
+
+  // Build the pointer type.
+  return Context.getQualifiedType(Context.getPointerType(T), Qs);
+}
+
+/// \brief Build a reference type.
+///
+/// \param T The type to which we'll be building a reference.
+///
+/// \param CVR The cvr-qualifiers to be applied to the reference type.
+///
+/// \param Loc The location of the entity whose type involves this
+/// reference type or, if there is no such entity, the location of the
+/// type that will have reference type.
+///
+/// \param Entity The name of the entity that involves the reference
+/// type, if known.
+///
+/// \returns A suitable reference type, if there are no
+/// errors. Otherwise, returns a NULL type.
+QualType Sema::BuildReferenceType(QualType T, bool SpelledAsLValue,
+                                  unsigned CVR, SourceLocation Loc,
+                                  DeclarationName Entity) {
+  Qualifiers Quals = Qualifiers::fromCVRMask(CVR);
+
+  bool LValueRef = SpelledAsLValue || T->getAs<LValueReferenceType>();
+
+  // C++0x [dcl.typedef]p9: If a typedef TD names a type that is a
+  //   reference to a type T, and attempt to create the type "lvalue
+  //   reference to cv TD" creates the type "lvalue reference to T".
+  // We use the qualifiers (restrict or none) of the original reference,
+  // not the new ones. This is consistent with GCC.
+
+  // C++ [dcl.ref]p4: There shall be no references to references.
+  //
+  // According to C++ DR 106, references to references are only
+  // diagnosed when they are written directly (e.g., "int & &"),
+  // but not when they happen via a typedef:
+  //
+  //   typedef int& intref;
+  //   typedef intref& intref2;
+  //
+  // Parser::ParseDeclaratorInternal diagnoses the case where
+  // references are written directly; here, we handle the
+  // collapsing of references-to-references as described in C++
+  // DR 106 and amended by C++ DR 540.
+
+  // C++ [dcl.ref]p1:
+  //   A declarator that specifies the type "reference to cv void"
+  //   is ill-formed.
+  if (T->isVoidType()) {
+    Diag(Loc, diag::err_reference_to_void);
+    return QualType();
+  }
+
+  // Enforce C99 6.7.3p2: "Types other than pointer types derived from
+  // object or incomplete types shall not be restrict-qualified."
+  if (Quals.hasRestrict() && !T->isIncompleteOrObjectType()) {
+    Diag(Loc, diag::err_typecheck_invalid_restrict_invalid_pointee)
+      << T;
+    Quals.removeRestrict();
+  }
+
+  // C++ [dcl.ref]p1:
+  //   [...] Cv-qualified references are ill-formed except when the
+  //   cv-qualifiers are introduced through the use of a typedef
+  //   (7.1.3) or of a template type argument (14.3), in which case
+  //   the cv-qualifiers are ignored.
+  //
+  // We diagnose extraneous cv-qualifiers for the non-typedef,
+  // non-template type argument case within the parser. Here, we just
+  // ignore any extraneous cv-qualifiers.
+  Quals.removeConst();
+  Quals.removeVolatile();
+
+  // Handle restrict on references.
+  if (LValueRef)
+    return Context.getQualifiedType(
+               Context.getLValueReferenceType(T, SpelledAsLValue), Quals);
+  return Context.getQualifiedType(Context.getRValueReferenceType(T), Quals);
+}
+
+/// \brief Build an array type.
+///
+/// \param T The type of each element in the array.
+///
+/// \param ASM C99 array size modifier (e.g., '*', 'static').
+///
+/// \param ArraySize Expression describing the size of the array.
+///
+/// \param Quals The cvr-qualifiers to be applied to the array's
+/// element type.
+///
+/// \param Loc The location of the entity whose type involves this
+/// array type or, if there is no such entity, the location of the
+/// type that will have array type.
+///
+/// \param Entity The name of the entity that involves the array
+/// type, if known.
+///
+/// \returns A suitable array type, if there are no errors. Otherwise,
+/// returns a NULL type.
+QualType Sema::BuildArrayType(QualType T, ArrayType::ArraySizeModifier ASM,
+                              Expr *ArraySize, unsigned Quals,
+                              SourceRange Brackets, DeclarationName Entity) {
+
+  SourceLocation Loc = Brackets.getBegin();
+  // C99 6.7.5.2p1: If the element type is an incomplete or function type,
+  // reject it (e.g. void ary[7], struct foo ary[7], void ary[7]())
+  // Not in C++, though. There we only dislike void.
+  if (getLangOptions().CPlusPlus) {
+    if (T->isVoidType()) {
+      Diag(Loc, diag::err_illegal_decl_array_incomplete_type) << T;
+      return QualType();
+    }
+  } else {
+    if (RequireCompleteType(Loc, T,
+                            diag::err_illegal_decl_array_incomplete_type))
+      return QualType();
+  }
+
+  if (T->isFunctionType()) {
+    Diag(Loc, diag::err_illegal_decl_array_of_functions)
+      << getPrintableNameForEntity(Entity) << T;
+    return QualType();
+  }
+
+  // C++ 8.3.2p4: There shall be no ... arrays of references ...
+  if (T->isReferenceType()) {
+    Diag(Loc, diag::err_illegal_decl_array_of_references)
+      << getPrintableNameForEntity(Entity) << T;
+    return QualType();
+  }
+
+  if (Context.getCanonicalType(T) == Context.UndeducedAutoTy) {
+    Diag(Loc,  diag::err_illegal_decl_array_of_auto)
+      << getPrintableNameForEntity(Entity);
+    return QualType();
+  }
+
+  if (const RecordType *EltTy = T->getAs<RecordType>()) {
+    // If the element type is a struct or union that contains a variadic
+    // array, accept it as a GNU extension: C99 6.7.2.1p2.
+    if (EltTy->getDecl()->hasFlexibleArrayMember())
+      Diag(Loc, diag::ext_flexible_array_in_array) << T;
+  } else if (T->isObjCInterfaceType()) {
+    Diag(Loc, diag::err_objc_array_of_interfaces) << T;
+    return QualType();
+  }
+
+  // C99 6.7.5.2p1: The size expression shall have integer type.
+  if (ArraySize && !ArraySize->isTypeDependent() &&
+      !ArraySize->getType()->isIntegerType()) {
+    Diag(ArraySize->getLocStart(), diag::err_array_size_non_int)
+      << ArraySize->getType() << ArraySize->getSourceRange();
+    ArraySize->Destroy(Context);
+    return QualType();
+  }
+  llvm::APSInt ConstVal(32);
+  if (!ArraySize) {
+    if (ASM == ArrayType::Star)
+      T = Context.getVariableArrayType(T, 0, ASM, Quals, Brackets);
+    else
+      T = Context.getIncompleteArrayType(T, ASM, Quals);
+  } else if (ArraySize->isValueDependent()) {
+    T = Context.getDependentSizedArrayType(T, ArraySize, ASM, Quals, Brackets);
+  } else if (!ArraySize->isIntegerConstantExpr(ConstVal, Context) ||
+             (!T->isDependentType() && !T->isIncompleteType() &&
+              !T->isConstantSizeType())) {
+    // Per C99, a variable array is an array with either a non-constant
+    // size or an element type that has a non-constant-size
+    T = Context.getVariableArrayType(T, ArraySize, ASM, Quals, Brackets);
+  } else {
+    // C99 6.7.5.2p1: If the expression is a constant expression, it shall
+    // have a value greater than zero.
+    if (ConstVal.isSigned() && ConstVal.isNegative()) {
+      Diag(ArraySize->getLocStart(),
+           diag::err_typecheck_negative_array_size)
+        << ArraySize->getSourceRange();
+      return QualType();
+    }
+    if (ConstVal == 0) {
+      // GCC accepts zero sized static arrays. We allow them when
+      // we're not in a SFINAE context.
+      Diag(ArraySize->getLocStart(), 
+           isSFINAEContext()? diag::err_typecheck_zero_array_size
+                            : diag::ext_typecheck_zero_array_size)
+        << ArraySize->getSourceRange();
+    }
+    T = Context.getConstantArrayType(T, ConstVal, ASM, Quals);
+  }
+  // If this is not C99, extwarn about VLA's and C99 array size modifiers.
+  if (!getLangOptions().C99) {
+    if (ArraySize && !ArraySize->isTypeDependent() &&
+        !ArraySize->isValueDependent() &&
+        !ArraySize->isIntegerConstantExpr(Context))
+      Diag(Loc, getLangOptions().CPlusPlus? diag::err_vla_cxx : diag::ext_vla);
+    else if (ASM != ArrayType::Normal || Quals != 0)
+      Diag(Loc, 
+           getLangOptions().CPlusPlus? diag::err_c99_array_usage_cxx
+                                     : diag::ext_c99_array_usage);
+  }
+
+  return T;
+}
+
+/// \brief Build an ext-vector type.
+///
+/// Run the required checks for the extended vector type.
+QualType Sema::BuildExtVectorType(QualType T, ExprArg ArraySize,
+                                  SourceLocation AttrLoc) {
+
+  Expr *Arg = (Expr *)ArraySize.get();
+
+  // unlike gcc's vector_size attribute, we do not allow vectors to be defined
+  // in conjunction with complex types (pointers, arrays, functions, etc.).
+  if (!T->isDependentType() &&
+      !T->isIntegerType() && !T->isRealFloatingType()) {
+    Diag(AttrLoc, diag::err_attribute_invalid_vector_type) << T;
+    return QualType();
+  }
+
+  if (!Arg->isTypeDependent() && !Arg->isValueDependent()) {
+    llvm::APSInt vecSize(32);
+    if (!Arg->isIntegerConstantExpr(vecSize, Context)) {
+      Diag(AttrLoc, diag::err_attribute_argument_not_int)
+      << "ext_vector_type" << Arg->getSourceRange();
+      return QualType();
+    }
+
+    // unlike gcc's vector_size attribute, the size is specified as the
+    // number of elements, not the number of bytes.
+    unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue());
+
+    if (vectorSize == 0) {
+      Diag(AttrLoc, diag::err_attribute_zero_size)
+      << Arg->getSourceRange();
+      return QualType();
+    }
+
+    if (!T->isDependentType())
+      return Context.getExtVectorType(T, vectorSize);
+  }
+
+  return Context.getDependentSizedExtVectorType(T, ArraySize.takeAs<Expr>(),
+                                                AttrLoc);
+}
+
+/// \brief Build a function type.
+///
+/// This routine checks the function type according to C++ rules and
+/// under the assumption that the result type and parameter types have
+/// just been instantiated from a template. It therefore duplicates
+/// some of the behavior of GetTypeForDeclarator, but in a much
+/// simpler form that is only suitable for this narrow use case.
+///
+/// \param T The return type of the function.
+///
+/// \param ParamTypes The parameter types of the function. This array
+/// will be modified to account for adjustments to the types of the
+/// function parameters.
+///
+/// \param NumParamTypes The number of parameter types in ParamTypes.
+///
+/// \param Variadic Whether this is a variadic function type.
+///
+/// \param Quals The cvr-qualifiers to be applied to the function type.
+///
+/// \param Loc The location of the entity whose type involves this
+/// function type or, if there is no such entity, the location of the
+/// type that will have function type.
+///
+/// \param Entity The name of the entity that involves the function
+/// type, if known.
+///
+/// \returns A suitable function type, if there are no
+/// errors. Otherwise, returns a NULL type.
+QualType Sema::BuildFunctionType(QualType T,
+                                 QualType *ParamTypes,
+                                 unsigned NumParamTypes,
+                                 bool Variadic, unsigned Quals,
+                                 SourceLocation Loc, DeclarationName Entity) {
+  if (T->isArrayType() || T->isFunctionType()) {
+    Diag(Loc, diag::err_func_returning_array_function) 
+      << T->isFunctionType() << T;
+    return QualType();
+  }
+
+  bool Invalid = false;
+  for (unsigned Idx = 0; Idx < NumParamTypes; ++Idx) {
+    QualType ParamType = adjustParameterType(ParamTypes[Idx]);
+    if (ParamType->isVoidType()) {
+      Diag(Loc, diag::err_param_with_void_type);
+      Invalid = true;
+    }
+
+    ParamTypes[Idx] = ParamType;
+  }
+
+  if (Invalid)
+    return QualType();
+
+  return Context.getFunctionType(T, ParamTypes, NumParamTypes, Variadic,
+                                 Quals, false, false, 0, 0,
+                                 FunctionType::ExtInfo());
+}
+
+/// \brief Build a member pointer type \c T Class::*.
+///
+/// \param T the type to which the member pointer refers.
+/// \param Class the class type into which the member pointer points.
+/// \param CVR Qualifiers applied to the member pointer type
+/// \param Loc the location where this type begins
+/// \param Entity the name of the entity that will have this member pointer type
+///
+/// \returns a member pointer type, if successful, or a NULL type if there was
+/// an error.
+QualType Sema::BuildMemberPointerType(QualType T, QualType Class,
+                                      unsigned CVR, SourceLocation Loc,
+                                      DeclarationName Entity) {
+  Qualifiers Quals = Qualifiers::fromCVRMask(CVR);
+
+  // Verify that we're not building a pointer to pointer to function with
+  // exception specification.
+  if (CheckDistantExceptionSpec(T)) {
+    Diag(Loc, diag::err_distant_exception_spec);
+
+    // FIXME: If we're doing this as part of template instantiation,
+    // we should return immediately.
+
+    // Build the type anyway, but use the canonical type so that the
+    // exception specifiers are stripped off.
+    T = Context.getCanonicalType(T);
+  }
+
+  // C++ 8.3.3p3: A pointer to member shall not pointer to ... a member
+  //   with reference type, or "cv void."
+  if (T->isReferenceType()) {
+    Diag(Loc, diag::err_illegal_decl_mempointer_to_reference)
+      << (Entity? Entity.getAsString() : "type name") << T;
+    return QualType();
+  }
+
+  if (T->isVoidType()) {
+    Diag(Loc, diag::err_illegal_decl_mempointer_to_void)
+      << (Entity? Entity.getAsString() : "type name");
+    return QualType();
+  }
+
+  // Enforce C99 6.7.3p2: "Types other than pointer types derived from
+  // object or incomplete types shall not be restrict-qualified."
+  if (Quals.hasRestrict() && !T->isIncompleteOrObjectType()) {
+    Diag(Loc, diag::err_typecheck_invalid_restrict_invalid_pointee)
+      << T;
+
+    // FIXME: If we're doing this as part of template instantiation,
+    // we should return immediately.
+    Quals.removeRestrict();
+  }
+
+  if (!Class->isDependentType() && !Class->isRecordType()) {
+    Diag(Loc, diag::err_mempointer_in_nonclass_type) << Class;
+    return QualType();
+  }
+
+  return Context.getQualifiedType(
+           Context.getMemberPointerType(T, Class.getTypePtr()), Quals);
+}
+
+/// \brief Build a block pointer type.
+///
+/// \param T The type to which we'll be building a block pointer.
+///
+/// \param CVR The cvr-qualifiers to be applied to the block pointer type.
+///
+/// \param Loc The location of the entity whose type involves this
+/// block pointer type or, if there is no such entity, the location of the
+/// type that will have block pointer type.
+///
+/// \param Entity The name of the entity that involves the block pointer
+/// type, if known.
+///
+/// \returns A suitable block pointer type, if there are no
+/// errors. Otherwise, returns a NULL type.
+QualType Sema::BuildBlockPointerType(QualType T, unsigned CVR,
+                                     SourceLocation Loc,
+                                     DeclarationName Entity) {
+  if (!T->isFunctionType()) {
+    Diag(Loc, diag::err_nonfunction_block_type);
+    return QualType();
+  }
+
+  Qualifiers Quals = Qualifiers::fromCVRMask(CVR);
+  return Context.getQualifiedType(Context.getBlockPointerType(T), Quals);
+}
+
+QualType Sema::GetTypeFromParser(TypeTy *Ty, TypeSourceInfo **TInfo) {
+  QualType QT = QualType::getFromOpaquePtr(Ty);
+  if (QT.isNull()) {
+    if (TInfo) *TInfo = 0;
+    return QualType();
+  }
+
+  TypeSourceInfo *DI = 0;
+  if (LocInfoType *LIT = dyn_cast<LocInfoType>(QT)) {
+    QT = LIT->getType();
+    DI = LIT->getTypeSourceInfo();
+  }
+
+  if (TInfo) *TInfo = DI;
+  return QT;
+}
+
+/// GetTypeForDeclarator - Convert the type for the specified
+/// declarator to Type instances.
+///
+/// If OwnedDecl is non-NULL, and this declarator's decl-specifier-seq
+/// owns the declaration of a type (e.g., the definition of a struct
+/// type), then *OwnedDecl will receive the owned declaration.
+QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S,
+                                    TypeSourceInfo **TInfo,
+                                    TagDecl **OwnedDecl) {
+  // Determine the type of the declarator. Not all forms of declarator
+  // have a type.
+  QualType T;
+  TypeSourceInfo *ReturnTypeInfo = 0;
+  
+  llvm::SmallVector<DelayedAttribute,4> FnAttrsFromDeclSpec;
+
+  switch (D.getName().getKind()) {
+  case UnqualifiedId::IK_Identifier:
+  case UnqualifiedId::IK_OperatorFunctionId:
+  case UnqualifiedId::IK_LiteralOperatorId:
+  case UnqualifiedId::IK_TemplateId:
+    T = ConvertDeclSpecToType(*this, D, FnAttrsFromDeclSpec);
+    
+    if (!D.isInvalidType() && D.getDeclSpec().isTypeSpecOwned()) {
+      TagDecl* Owned = cast<TagDecl>((Decl *)D.getDeclSpec().getTypeRep());
+      // Owned is embedded if it was defined here, or if it is the
+      // very first (i.e., canonical) declaration of this tag type.
+      Owned->setEmbeddedInDeclarator(Owned->isDefinition() ||
+                                     Owned->isCanonicalDecl());
+      if (OwnedDecl) *OwnedDecl = Owned;
+    }
+    break;
+
+  case UnqualifiedId::IK_ConstructorName:
+  case UnqualifiedId::IK_ConstructorTemplateId:
+  case UnqualifiedId::IK_DestructorName:
+    // Constructors and destructors don't have return types. Use
+    // "void" instead. 
+    T = Context.VoidTy;
+      
+    if (TInfo)
+      ReturnTypeInfo = Context.getTrivialTypeSourceInfo(T, 
+                                                    D.getName().StartLocation);
+    break;
+
+  case UnqualifiedId::IK_ConversionFunctionId:
+    // The result type of a conversion function is the type that it
+    // converts to.
+    T = GetTypeFromParser(D.getName().ConversionFunctionId, 
+                          TInfo? &ReturnTypeInfo : 0);
+    break;
+  }
+  
+  if (T.isNull())
+    return T;
+
+  if (T == Context.UndeducedAutoTy) {
+    int Error = -1;
+
+    switch (D.getContext()) {
+    case Declarator::KNRTypeListContext:
+      assert(0 && "K&R type lists aren't allowed in C++");
+      break;
+    case Declarator::PrototypeContext:
+      Error = 0; // Function prototype
+      break;
+    case Declarator::MemberContext:
+      switch (cast<TagDecl>(CurContext)->getTagKind()) {
+      case TagDecl::TK_enum: assert(0 && "unhandled tag kind"); break;
+      case TagDecl::TK_struct: Error = 1; /* Struct member */ break;
+      case TagDecl::TK_union:  Error = 2; /* Union member */ break;
+      case TagDecl::TK_class:  Error = 3; /* Class member */ break;
+      }
+      break;
+    case Declarator::CXXCatchContext:
+      Error = 4; // Exception declaration
+      break;
+    case Declarator::TemplateParamContext:
+      Error = 5; // Template parameter
+      break;
+    case Declarator::BlockLiteralContext:
+      Error = 6;  // Block literal
+      break;
+    case Declarator::FileContext:
+    case Declarator::BlockContext:
+    case Declarator::ForContext:
+    case Declarator::ConditionContext:
+    case Declarator::TypeNameContext:
+      break;
+    }
+
+    if (Error != -1) {
+      Diag(D.getDeclSpec().getTypeSpecTypeLoc(), diag::err_auto_not_allowed)
+        << Error;
+      T = Context.IntTy;
+      D.setInvalidType(true);
+    }
+  }
+
+  // The name we're declaring, if any.
+  DeclarationName Name;
+  if (D.getIdentifier())
+    Name = D.getIdentifier();
+
+  llvm::SmallVector<DelayedAttribute,4> FnAttrsFromPreviousChunk;
+
+  // Walk the DeclTypeInfo, building the recursive type as we go.
+  // DeclTypeInfos are ordered from the identifier out, which is
+  // opposite of what we want :).
+  for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i) {
+    DeclaratorChunk &DeclType = D.getTypeObject(e-i-1);
+    switch (DeclType.Kind) {
+    default: assert(0 && "Unknown decltype!");
+    case DeclaratorChunk::BlockPointer:
+      // If blocks are disabled, emit an error.
+      if (!LangOpts.Blocks)
+        Diag(DeclType.Loc, diag::err_blocks_disable);
+
+      T = BuildBlockPointerType(T, DeclType.Cls.TypeQuals, D.getIdentifierLoc(),
+                                Name);
+      break;
+    case DeclaratorChunk::Pointer:
+      // Verify that we're not building a pointer to pointer to function with
+      // exception specification.
+      if (getLangOptions().CPlusPlus && CheckDistantExceptionSpec(T)) {
+        Diag(D.getIdentifierLoc(), diag::err_distant_exception_spec);
+        D.setInvalidType(true);
+        // Build the type anyway.
+      }
+      if (getLangOptions().ObjC1 && T->isObjCInterfaceType()) {
+        const ObjCInterfaceType *OIT = T->getAs<ObjCInterfaceType>();
+        T = Context.getObjCObjectPointerType(T,
+                                         const_cast<ObjCProtocolDecl **>(
+                                           OIT->qual_begin()),
+                                         OIT->getNumProtocols(),
+                                         DeclType.Ptr.TypeQuals);
+        break;
+      }
+      T = BuildPointerType(T, DeclType.Ptr.TypeQuals, DeclType.Loc, Name);
+      break;
+    case DeclaratorChunk::Reference: {
+      Qualifiers Quals;
+      if (DeclType.Ref.HasRestrict) Quals.addRestrict();
+
+      // Verify that we're not building a reference to pointer to function with
+      // exception specification.
+      if (getLangOptions().CPlusPlus && CheckDistantExceptionSpec(T)) {
+        Diag(D.getIdentifierLoc(), diag::err_distant_exception_spec);
+        D.setInvalidType(true);
+        // Build the type anyway.
+      }
+      T = BuildReferenceType(T, DeclType.Ref.LValueRef, Quals,
+                             DeclType.Loc, Name);
+      break;
+    }
+    case DeclaratorChunk::Array: {
+      // Verify that we're not building an array of pointers to function with
+      // exception specification.
+      if (getLangOptions().CPlusPlus && CheckDistantExceptionSpec(T)) {
+        Diag(D.getIdentifierLoc(), diag::err_distant_exception_spec);
+        D.setInvalidType(true);
+        // Build the type anyway.
+      }
+      DeclaratorChunk::ArrayTypeInfo &ATI = DeclType.Arr;
+      Expr *ArraySize = static_cast<Expr*>(ATI.NumElts);
+      ArrayType::ArraySizeModifier ASM;
+      if (ATI.isStar)
+        ASM = ArrayType::Star;
+      else if (ATI.hasStatic)
+        ASM = ArrayType::Static;
+      else
+        ASM = ArrayType::Normal;
+      if (ASM == ArrayType::Star &&
+          D.getContext() != Declarator::PrototypeContext) {
+        // FIXME: This check isn't quite right: it allows star in prototypes
+        // for function definitions, and disallows some edge cases detailed
+        // in http://gcc.gnu.org/ml/gcc-patches/2009-02/msg00133.html
+        Diag(DeclType.Loc, diag::err_array_star_outside_prototype);
+        ASM = ArrayType::Normal;
+        D.setInvalidType(true);
+      }
+      T = BuildArrayType(T, ASM, ArraySize,
+                         Qualifiers::fromCVRMask(ATI.TypeQuals),
+                         SourceRange(DeclType.Loc, DeclType.EndLoc), Name);
+      break;
+    }
+    case DeclaratorChunk::Function: {
+      // If the function declarator has a prototype (i.e. it is not () and
+      // does not have a K&R-style identifier list), then the arguments are part
+      // of the type, otherwise the argument list is ().
+      const DeclaratorChunk::FunctionTypeInfo &FTI = DeclType.Fun;
+
+      // C99 6.7.5.3p1: The return type may not be a function or array type.
+      // For conversion functions, we'll diagnose this particular error later.
+      if ((T->isArrayType() || T->isFunctionType()) &&
+          (D.getName().getKind() != UnqualifiedId::IK_ConversionFunctionId)) {
+        Diag(DeclType.Loc, diag::err_func_returning_array_function) 
+          << T->isFunctionType() << T;
+        T = Context.IntTy;
+        D.setInvalidType(true);
+      }
+
+      if (getLangOptions().CPlusPlus && D.getDeclSpec().isTypeSpecOwned()) {
+        // C++ [dcl.fct]p6:
+        //   Types shall not be defined in return or parameter types.
+        TagDecl *Tag = cast<TagDecl>((Decl *)D.getDeclSpec().getTypeRep());
+        if (Tag->isDefinition())
+          Diag(Tag->getLocation(), diag::err_type_defined_in_result_type)
+            << Context.getTypeDeclType(Tag);
+      }
+
+      // Exception specs are not allowed in typedefs. Complain, but add it
+      // anyway.
+      if (FTI.hasExceptionSpec &&
+          D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef)
+        Diag(FTI.getThrowLoc(), diag::err_exception_spec_in_typedef);
+
+      if (FTI.NumArgs == 0) {
+        if (getLangOptions().CPlusPlus) {
+          // C++ 8.3.5p2: If the parameter-declaration-clause is empty, the
+          // function takes no arguments.
+          llvm::SmallVector<QualType, 4> Exceptions;
+          Exceptions.reserve(FTI.NumExceptions);
+          for (unsigned ei = 0, ee = FTI.NumExceptions; ei != ee; ++ei) {
+            // FIXME: Preserve type source info.
+            QualType ET = GetTypeFromParser(FTI.Exceptions[ei].Ty);
+            // Check that the type is valid for an exception spec, and drop it
+            // if not.
+            if (!CheckSpecifiedExceptionType(ET, FTI.Exceptions[ei].Range))
+              Exceptions.push_back(ET);
+          }
+          T = Context.getFunctionType(T, NULL, 0, FTI.isVariadic, FTI.TypeQuals,
+                                      FTI.hasExceptionSpec,
+                                      FTI.hasAnyExceptionSpec,
+                                      Exceptions.size(), Exceptions.data(),
+                                      FunctionType::ExtInfo());
+        } else if (FTI.isVariadic) {
+          // We allow a zero-parameter variadic function in C if the
+          // function is marked with the "overloadable"
+          // attribute. Scan for this attribute now.
+          bool Overloadable = false;
+          for (const AttributeList *Attrs = D.getAttributes();
+               Attrs; Attrs = Attrs->getNext()) {
+            if (Attrs->getKind() == AttributeList::AT_overloadable) {
+              Overloadable = true;
+              break;
+            }
+          }
+
+          if (!Overloadable)
+            Diag(FTI.getEllipsisLoc(), diag::err_ellipsis_first_arg);
+          T = Context.getFunctionType(T, NULL, 0, FTI.isVariadic, 0, 
+                                      false, false, 0, 0,
+                                      FunctionType::ExtInfo());
+        } else {
+          // Simple void foo(), where the incoming T is the result type.
+          T = Context.getFunctionNoProtoType(T);
+        }
+      } else if (FTI.ArgInfo[0].Param == 0) {
+        // C99 6.7.5.3p3: Reject int(x,y,z) when it's not a function definition.
+        Diag(FTI.ArgInfo[0].IdentLoc, diag::err_ident_list_in_fn_declaration);
+        D.setInvalidType(true);
+      } else {
+        // Otherwise, we have a function with an argument list that is
+        // potentially variadic.
+        llvm::SmallVector<QualType, 16> ArgTys;
+
+        for (unsigned i = 0, e = FTI.NumArgs; i != e; ++i) {
+          ParmVarDecl *Param =
+            cast<ParmVarDecl>(FTI.ArgInfo[i].Param.getAs<Decl>());
+          QualType ArgTy = Param->getType();
+          assert(!ArgTy.isNull() && "Couldn't parse type?");
+
+          // Adjust the parameter type.
+          assert((ArgTy == adjustParameterType(ArgTy)) && "Unadjusted type?");
+
+          // Look for 'void'.  void is allowed only as a single argument to a
+          // function with no other parameters (C99 6.7.5.3p10).  We record
+          // int(void) as a FunctionProtoType with an empty argument list.
+          if (ArgTy->isVoidType()) {
+            // If this is something like 'float(int, void)', reject it.  'void'
+            // is an incomplete type (C99 6.2.5p19) and function decls cannot
+            // have arguments of incomplete type.
+            if (FTI.NumArgs != 1 || FTI.isVariadic) {
+              Diag(DeclType.Loc, diag::err_void_only_param);
+              ArgTy = Context.IntTy;
+              Param->setType(ArgTy);
+            } else if (FTI.ArgInfo[i].Ident) {
+              // Reject, but continue to parse 'int(void abc)'.
+              Diag(FTI.ArgInfo[i].IdentLoc,
+                   diag::err_param_with_void_type);
+              ArgTy = Context.IntTy;
+              Param->setType(ArgTy);
+            } else {
+              // Reject, but continue to parse 'float(const void)'.
+              if (ArgTy.hasQualifiers())
+                Diag(DeclType.Loc, diag::err_void_param_qualified);
+
+              // Do not add 'void' to the ArgTys list.
+              break;
+            }
+          } else if (!FTI.hasPrototype) {
+            if (ArgTy->isPromotableIntegerType()) {
+              ArgTy = Context.getPromotedIntegerType(ArgTy);
+            } else if (const BuiltinType* BTy = ArgTy->getAs<BuiltinType>()) {
+              if (BTy->getKind() == BuiltinType::Float)
+                ArgTy = Context.DoubleTy;
+            }
+          }
+
+          ArgTys.push_back(ArgTy);
+        }
+
+        llvm::SmallVector<QualType, 4> Exceptions;
+        Exceptions.reserve(FTI.NumExceptions);
+        for (unsigned ei = 0, ee = FTI.NumExceptions; ei != ee; ++ei) {
+          // FIXME: Preserve type source info.
+          QualType ET = GetTypeFromParser(FTI.Exceptions[ei].Ty);
+          // Check that the type is valid for an exception spec, and drop it if
+          // not.
+          if (!CheckSpecifiedExceptionType(ET, FTI.Exceptions[ei].Range))
+            Exceptions.push_back(ET);
+        }
+
+        T = Context.getFunctionType(T, ArgTys.data(), ArgTys.size(),
+                                    FTI.isVariadic, FTI.TypeQuals,
+                                    FTI.hasExceptionSpec,
+                                    FTI.hasAnyExceptionSpec,
+                                    Exceptions.size(), Exceptions.data(),
+                                    FunctionType::ExtInfo());
+      }
+
+      // For GCC compatibility, we allow attributes that apply only to
+      // function types to be placed on a function's return type
+      // instead (as long as that type doesn't happen to be function
+      // or function-pointer itself).
+      ProcessDelayedFnAttrs(*this, T, FnAttrsFromPreviousChunk);
+
+      break;
+    }
+    case DeclaratorChunk::MemberPointer:
+      // Verify that we're not building a pointer to pointer to function with
+      // exception specification.
+      if (getLangOptions().CPlusPlus && CheckDistantExceptionSpec(T)) {
+        Diag(D.getIdentifierLoc(), diag::err_distant_exception_spec);
+        D.setInvalidType(true);
+        // Build the type anyway.
+      }
+      // The scope spec must refer to a class, or be dependent.
+      QualType ClsType;
+      if (DeclType.Mem.Scope().isInvalid()) {
+        // Avoid emitting extra errors if we already errored on the scope.
+        D.setInvalidType(true);
+      } else if (isDependentScopeSpecifier(DeclType.Mem.Scope())
+                 || dyn_cast_or_null<CXXRecordDecl>(
+                                   computeDeclContext(DeclType.Mem.Scope()))) {
+        NestedNameSpecifier *NNS
+          = (NestedNameSpecifier *)DeclType.Mem.Scope().getScopeRep();
+        NestedNameSpecifier *NNSPrefix = NNS->getPrefix();
+        switch (NNS->getKind()) {
+        case NestedNameSpecifier::Identifier:
+          ClsType = Context.getDependentNameType(ETK_None, NNSPrefix, 
+                                                 NNS->getAsIdentifier());
+          break;
+
+        case NestedNameSpecifier::Namespace:
+        case NestedNameSpecifier::Global:
+          llvm_unreachable("Nested-name-specifier must name a type");
+          break;
+            
+        case NestedNameSpecifier::TypeSpec:
+        case NestedNameSpecifier::TypeSpecWithTemplate:
+          ClsType = QualType(NNS->getAsType(), 0);
+          if (NNSPrefix)
+            ClsType = Context.getQualifiedNameType(NNSPrefix, ClsType);
+          break;
+        }
+      } else {
+        Diag(DeclType.Mem.Scope().getBeginLoc(),
+             diag::err_illegal_decl_mempointer_in_nonclass)
+          << (D.getIdentifier() ? D.getIdentifier()->getName() : "type name")
+          << DeclType.Mem.Scope().getRange();
+        D.setInvalidType(true);
+      }
+
+      if (!ClsType.isNull())
+        T = BuildMemberPointerType(T, ClsType, DeclType.Mem.TypeQuals,
+                                   DeclType.Loc, D.getIdentifier());
+      if (T.isNull()) {
+        T = Context.IntTy;
+        D.setInvalidType(true);
+      }
+      break;
+    }
+
+    if (T.isNull()) {
+      D.setInvalidType(true);
+      T = Context.IntTy;
+    }
+
+    DiagnoseDelayedFnAttrs(*this, FnAttrsFromPreviousChunk);
+
+    // See if there are any attributes on this declarator chunk.
+    if (const AttributeList *AL = DeclType.getAttrs())
+      ProcessTypeAttributeList(*this, T, false, AL, FnAttrsFromPreviousChunk);
+  }
+
+  if (getLangOptions().CPlusPlus && T->isFunctionType()) {
+    const FunctionProtoType *FnTy = T->getAs<FunctionProtoType>();
+    assert(FnTy && "Why oh why is there not a FunctionProtoType here?");
+
+    // C++ 8.3.5p4: A cv-qualifier-seq shall only be part of the function type
+    // for a nonstatic member function, the function type to which a pointer
+    // to member refers, or the top-level function type of a function typedef
+    // declaration.
+    if (FnTy->getTypeQuals() != 0 &&
+        D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_typedef &&
+        ((D.getContext() != Declarator::MemberContext &&
+          (!D.getCXXScopeSpec().isSet() ||
+           !computeDeclContext(D.getCXXScopeSpec(), /*FIXME:*/true)
+              ->isRecord())) ||
+         D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_static)) {
+      if (D.isFunctionDeclarator())
+        Diag(D.getIdentifierLoc(), diag::err_invalid_qualified_function_type);
+      else
+        Diag(D.getIdentifierLoc(),
+             diag::err_invalid_qualified_typedef_function_type_use);
+
+      // Strip the cv-quals from the type.
+      T = Context.getFunctionType(FnTy->getResultType(), FnTy->arg_type_begin(),
+                                  FnTy->getNumArgs(), FnTy->isVariadic(), 0, 
+                                  false, false, 0, 0, FunctionType::ExtInfo());
+    }
+  }
+
+  // Process any function attributes we might have delayed from the
+  // declaration-specifiers.
+  ProcessDelayedFnAttrs(*this, T, FnAttrsFromDeclSpec);
+
+  // If there were any type attributes applied to the decl itself, not
+  // the type, apply them to the result type.  But don't do this for
+  // block-literal expressions, which are parsed wierdly.
+  if (D.getContext() != Declarator::BlockLiteralContext)
+    if (const AttributeList *Attrs = D.getAttributes())
+      ProcessTypeAttributeList(*this, T, false, Attrs,
+                               FnAttrsFromPreviousChunk);
+
+  DiagnoseDelayedFnAttrs(*this, FnAttrsFromPreviousChunk);
+
+  if (TInfo) {
+    if (D.isInvalidType())
+      *TInfo = 0;
+    else
+      *TInfo = GetTypeSourceInfoForDeclarator(D, T, ReturnTypeInfo);
+  }
+
+  return T;
+}
+
+namespace {
+  class TypeSpecLocFiller : public TypeLocVisitor<TypeSpecLocFiller> {
+    const DeclSpec &DS;
+
+  public:
+    TypeSpecLocFiller(const DeclSpec &DS) : DS(DS) {}
+
+    void VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
+      Visit(TL.getUnqualifiedLoc());
+    }
+    void VisitTypedefTypeLoc(TypedefTypeLoc TL) {
+      TL.setNameLoc(DS.getTypeSpecTypeLoc());
+    }
+    void VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
+      TL.setNameLoc(DS.getTypeSpecTypeLoc());
+
+      if (DS.getProtocolQualifiers()) {
+        assert(TL.getNumProtocols() > 0);
+        assert(TL.getNumProtocols() == DS.getNumProtocolQualifiers());
+        TL.setLAngleLoc(DS.getProtocolLAngleLoc());
+        TL.setRAngleLoc(DS.getSourceRange().getEnd());
+        for (unsigned i = 0, e = DS.getNumProtocolQualifiers(); i != e; ++i)
+          TL.setProtocolLoc(i, DS.getProtocolLocs()[i]);
+      } else {
+        assert(TL.getNumProtocols() == 0);
+        TL.setLAngleLoc(SourceLocation());
+        TL.setRAngleLoc(SourceLocation());
+      }
+    }
+    void VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
+      assert(TL.getNumProtocols() == DS.getNumProtocolQualifiers());
+
+      TL.setStarLoc(SourceLocation());
+
+      if (DS.getProtocolQualifiers()) {
+        assert(TL.getNumProtocols() > 0);
+        assert(TL.getNumProtocols() == DS.getNumProtocolQualifiers());
+        TL.setHasProtocolsAsWritten(true);
+        TL.setLAngleLoc(DS.getProtocolLAngleLoc());
+        TL.setRAngleLoc(DS.getSourceRange().getEnd());
+        for (unsigned i = 0, e = DS.getNumProtocolQualifiers(); i != e; ++i)
+          TL.setProtocolLoc(i, DS.getProtocolLocs()[i]);
+
+      } else {
+        assert(TL.getNumProtocols() == 0);
+        TL.setHasProtocolsAsWritten(false);
+        TL.setLAngleLoc(SourceLocation());
+        TL.setRAngleLoc(SourceLocation());
+      }
+
+      // This might not have been written with an inner type.
+      if (DS.getTypeSpecType() == DeclSpec::TST_unspecified) {
+        TL.setHasBaseTypeAsWritten(false);
+        TL.getBaseTypeLoc().initialize(SourceLocation());
+      } else {
+        TL.setHasBaseTypeAsWritten(true);
+        Visit(TL.getBaseTypeLoc());
+      }
+    }
+    void VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL) {
+      TypeSourceInfo *TInfo = 0;
+      Sema::GetTypeFromParser(DS.getTypeRep(), &TInfo);
+
+      // If we got no declarator info from previous Sema routines,
+      // just fill with the typespec loc.
+      if (!TInfo) {
+        TL.initialize(DS.getTypeSpecTypeLoc());
+        return;
+      }
+
+      TemplateSpecializationTypeLoc OldTL =
+        cast<TemplateSpecializationTypeLoc>(TInfo->getTypeLoc());
+      TL.copy(OldTL);
+    }
+    void VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
+      assert(DS.getTypeSpecType() == DeclSpec::TST_typeofExpr);
+      TL.setTypeofLoc(DS.getTypeSpecTypeLoc());
+      TL.setParensRange(DS.getTypeofParensRange());
+    }
+    void VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
+      assert(DS.getTypeSpecType() == DeclSpec::TST_typeofType);
+      TL.setTypeofLoc(DS.getTypeSpecTypeLoc());
+      TL.setParensRange(DS.getTypeofParensRange());
+      assert(DS.getTypeRep());
+      TypeSourceInfo *TInfo = 0;
+      Sema::GetTypeFromParser(DS.getTypeRep(), &TInfo);
+      TL.setUnderlyingTInfo(TInfo);
+    }
+    void VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
+      // By default, use the source location of the type specifier.
+      TL.setBuiltinLoc(DS.getTypeSpecTypeLoc());
+      if (TL.needsExtraLocalData()) {
+        // Set info for the written builtin specifiers.
+        TL.getWrittenBuiltinSpecs() = DS.getWrittenBuiltinSpecs();
+        // Try to have a meaningful source location.
+        if (TL.getWrittenSignSpec() != TSS_unspecified)
+          // Sign spec loc overrides the others (e.g., 'unsigned long').
+          TL.setBuiltinLoc(DS.getTypeSpecSignLoc());
+        else if (TL.getWrittenWidthSpec() != TSW_unspecified)
+          // Width spec loc overrides type spec loc (e.g., 'short int').
+          TL.setBuiltinLoc(DS.getTypeSpecWidthLoc());
+      }
+    }
+    void VisitTypeLoc(TypeLoc TL) {
+      // FIXME: add other typespec types and change this to an assert.
+      TL.initialize(DS.getTypeSpecTypeLoc());
+    }
+  };
+
+  class DeclaratorLocFiller : public TypeLocVisitor<DeclaratorLocFiller> {
+    const DeclaratorChunk &Chunk;
+
+  public:
+    DeclaratorLocFiller(const DeclaratorChunk &Chunk) : Chunk(Chunk) {}
+
+    void VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
+      llvm_unreachable("qualified type locs not expected here!");
+    }
+
+    void VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
+      assert(Chunk.Kind == DeclaratorChunk::BlockPointer);
+      TL.setCaretLoc(Chunk.Loc);
+    }
+    void VisitPointerTypeLoc(PointerTypeLoc TL) {
+      assert(Chunk.Kind == DeclaratorChunk::Pointer);
+      TL.setStarLoc(Chunk.Loc);
+    }
+    void VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
+      assert(Chunk.Kind == DeclaratorChunk::Pointer);
+      TL.setStarLoc(Chunk.Loc);
+      TL.setHasBaseTypeAsWritten(true);
+      TL.setHasProtocolsAsWritten(false);
+      TL.setLAngleLoc(SourceLocation());
+      TL.setRAngleLoc(SourceLocation());
+    }
+    void VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
+      assert(Chunk.Kind == DeclaratorChunk::MemberPointer);
+      TL.setStarLoc(Chunk.Loc);
+      // FIXME: nested name specifier
+    }
+    void VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
+      assert(Chunk.Kind == DeclaratorChunk::Reference);
+      // 'Amp' is misleading: this might have been originally
+      /// spelled with AmpAmp.
+      TL.setAmpLoc(Chunk.Loc);
+    }
+    void VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
+      assert(Chunk.Kind == DeclaratorChunk::Reference);
+      assert(!Chunk.Ref.LValueRef);
+      TL.setAmpAmpLoc(Chunk.Loc);
+    }
+    void VisitArrayTypeLoc(ArrayTypeLoc TL) {
+      assert(Chunk.Kind == DeclaratorChunk::Array);
+      TL.setLBracketLoc(Chunk.Loc);
+      TL.setRBracketLoc(Chunk.EndLoc);
+      TL.setSizeExpr(static_cast<Expr*>(Chunk.Arr.NumElts));
+    }
+    void VisitFunctionTypeLoc(FunctionTypeLoc TL) {
+      assert(Chunk.Kind == DeclaratorChunk::Function);
+      TL.setLParenLoc(Chunk.Loc);
+      TL.setRParenLoc(Chunk.EndLoc);
+
+      const DeclaratorChunk::FunctionTypeInfo &FTI = Chunk.Fun;
+      for (unsigned i = 0, e = TL.getNumArgs(), tpi = 0; i != e; ++i) {
+        ParmVarDecl *Param = FTI.ArgInfo[i].Param.getAs<ParmVarDecl>();
+        TL.setArg(tpi++, Param);
+      }
+      // FIXME: exception specs
+    }
+
+    void VisitTypeLoc(TypeLoc TL) {
+      llvm_unreachable("unsupported TypeLoc kind in declarator!");
+    }
+  };
+}
+
+/// \brief Create and instantiate a TypeSourceInfo with type source information.
+///
+/// \param T QualType referring to the type as written in source code.
+///
+/// \param ReturnTypeInfo For declarators whose return type does not show
+/// up in the normal place in the declaration specifiers (such as a C++
+/// conversion function), this pointer will refer to a type source information
+/// for that return type.
+TypeSourceInfo *
+Sema::GetTypeSourceInfoForDeclarator(Declarator &D, QualType T,
+                                     TypeSourceInfo *ReturnTypeInfo) {
+  TypeSourceInfo *TInfo = Context.CreateTypeSourceInfo(T);
+  UnqualTypeLoc CurrTL = TInfo->getTypeLoc().getUnqualifiedLoc();
+
+  for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i) {
+    DeclaratorLocFiller(D.getTypeObject(i)).Visit(CurrTL);
+    CurrTL = CurrTL.getNextTypeLoc().getUnqualifiedLoc();
+  }
+  
+  TypeSpecLocFiller(D.getDeclSpec()).Visit(CurrTL);
+  
+  // We have source information for the return type that was not in the
+  // declaration specifiers; copy that information into the current type
+  // location so that it will be retained. This occurs, for example, with 
+  // a C++ conversion function, where the return type occurs within the
+  // declarator-id rather than in the declaration specifiers.
+  if (ReturnTypeInfo && D.getDeclSpec().getTypeSpecType() == TST_unspecified) {
+    TypeLoc TL = ReturnTypeInfo->getTypeLoc();
+    assert(TL.getFullDataSize() == CurrTL.getFullDataSize());
+    memcpy(CurrTL.getOpaqueData(), TL.getOpaqueData(), TL.getFullDataSize());
+  }
+      
+  return TInfo;
+}
+
+/// \brief Create a LocInfoType to hold the given QualType and TypeSourceInfo.
+QualType Sema::CreateLocInfoType(QualType T, TypeSourceInfo *TInfo) {
+  // FIXME: LocInfoTypes are "transient", only needed for passing to/from Parser
+  // and Sema during declaration parsing. Try deallocating/caching them when
+  // it's appropriate, instead of allocating them and keeping them around.
+  LocInfoType *LocT = (LocInfoType*)BumpAlloc.Allocate(sizeof(LocInfoType), 8);
+  new (LocT) LocInfoType(T, TInfo);
+  assert(LocT->getTypeClass() != T->getTypeClass() &&
+         "LocInfoType's TypeClass conflicts with an existing Type class");
+  return QualType(LocT, 0);
+}
+
+void LocInfoType::getAsStringInternal(std::string &Str,
+                                      const PrintingPolicy &Policy) const {
+  assert(false && "LocInfoType leaked into the type system; an opaque TypeTy*"
+         " was used directly instead of getting the QualType through"
+         " GetTypeFromParser");
+}
+
+/// UnwrapSimilarPointerTypes - If T1 and T2 are pointer types  that
+/// may be similar (C++ 4.4), replaces T1 and T2 with the type that
+/// they point to and return true. If T1 and T2 aren't pointer types
+/// or pointer-to-member types, or if they are not similar at this
+/// level, returns false and leaves T1 and T2 unchanged. Top-level
+/// qualifiers on T1 and T2 are ignored. This function will typically
+/// be called in a loop that successively "unwraps" pointer and
+/// pointer-to-member types to compare them at each level.
+bool Sema::UnwrapSimilarPointerTypes(QualType& T1, QualType& T2) {
+  const PointerType *T1PtrType = T1->getAs<PointerType>(),
+                    *T2PtrType = T2->getAs<PointerType>();
+  if (T1PtrType && T2PtrType) {
+    T1 = T1PtrType->getPointeeType();
+    T2 = T2PtrType->getPointeeType();
+    return true;
+  }
+
+  const MemberPointerType *T1MPType = T1->getAs<MemberPointerType>(),
+                          *T2MPType = T2->getAs<MemberPointerType>();
+  if (T1MPType && T2MPType &&
+      Context.getCanonicalType(T1MPType->getClass()) ==
+      Context.getCanonicalType(T2MPType->getClass())) {
+    T1 = T1MPType->getPointeeType();
+    T2 = T2MPType->getPointeeType();
+    return true;
+  }
+  return false;
+}
+
+Sema::TypeResult Sema::ActOnTypeName(Scope *S, Declarator &D) {
+  // C99 6.7.6: Type names have no identifier.  This is already validated by
+  // the parser.
+  assert(D.getIdentifier() == 0 && "Type name should have no identifier!");
+
+  TypeSourceInfo *TInfo = 0;
+  TagDecl *OwnedTag = 0;
+  QualType T = GetTypeForDeclarator(D, S, &TInfo, &OwnedTag);
+  if (D.isInvalidType())
+    return true;
+
+  if (getLangOptions().CPlusPlus) {
+    // Check that there are no default arguments (C++ only).
+    CheckExtraCXXDefaultArguments(D);
+
+    // C++0x [dcl.type]p3:
+    //   A type-specifier-seq shall not define a class or enumeration
+    //   unless it appears in the type-id of an alias-declaration
+    //   (7.1.3).
+    if (OwnedTag && OwnedTag->isDefinition())
+      Diag(OwnedTag->getLocation(), diag::err_type_defined_in_type_specifier)
+        << Context.getTypeDeclType(OwnedTag);
+  }
+
+  if (TInfo)
+    T = CreateLocInfoType(T, TInfo);
+
+  return T.getAsOpaquePtr();
+}
+
+
+
+//===----------------------------------------------------------------------===//
+// Type Attribute Processing
+//===----------------------------------------------------------------------===//
+
+/// HandleAddressSpaceTypeAttribute - Process an address_space attribute on the
+/// specified type.  The attribute contains 1 argument, the id of the address
+/// space for the type.
+static void HandleAddressSpaceTypeAttribute(QualType &Type,
+                                            const AttributeList &Attr, Sema &S){
+
+  // If this type is already address space qualified, reject it.
+  // Clause 6.7.3 - Type qualifiers: "No type shall be qualified by qualifiers
+  // for two or more different address spaces."
+  if (Type.getAddressSpace()) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_address_multiple_qualifiers);
+    return;
+  }
+
+  // Check the attribute arguments.
+  if (Attr.getNumArgs() != 1) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
+    return;
+  }
+  Expr *ASArgExpr = static_cast<Expr *>(Attr.getArg(0));
+  llvm::APSInt addrSpace(32);
+  if (!ASArgExpr->isIntegerConstantExpr(addrSpace, S.Context)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_address_space_not_int)
+      << ASArgExpr->getSourceRange();
+    return;
+  }
+
+  // Bounds checking.
+  if (addrSpace.isSigned()) {
+    if (addrSpace.isNegative()) {
+      S.Diag(Attr.getLoc(), diag::err_attribute_address_space_negative)
+        << ASArgExpr->getSourceRange();
+      return;
+    }
+    addrSpace.setIsSigned(false);
+  }
+  llvm::APSInt max(addrSpace.getBitWidth());
+  max = Qualifiers::MaxAddressSpace;
+  if (addrSpace > max) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_address_space_too_high)
+      << Qualifiers::MaxAddressSpace << ASArgExpr->getSourceRange();
+    return;
+  }
+
+  unsigned ASIdx = static_cast<unsigned>(addrSpace.getZExtValue());
+  Type = S.Context.getAddrSpaceQualType(Type, ASIdx);
+}
+
+/// HandleObjCGCTypeAttribute - Process an objc's gc attribute on the
+/// specified type.  The attribute contains 1 argument, weak or strong.
+static void HandleObjCGCTypeAttribute(QualType &Type,
+                                      const AttributeList &Attr, Sema &S) {
+  if (Type.getObjCGCAttr() != Qualifiers::GCNone) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_multiple_objc_gc);
+    return;
+  }
+
+  // Check the attribute arguments.
+  if (!Attr.getParameterName()) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
+      << "objc_gc" << 1;
+    return;
+  }
+  Qualifiers::GC GCAttr;
+  if (Attr.getNumArgs() != 0) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
+    return;
+  }
+  if (Attr.getParameterName()->isStr("weak"))
+    GCAttr = Qualifiers::Weak;
+  else if (Attr.getParameterName()->isStr("strong"))
+    GCAttr = Qualifiers::Strong;
+  else {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
+      << "objc_gc" << Attr.getParameterName();
+    return;
+  }
+
+  Type = S.Context.getObjCGCQualType(Type, GCAttr);
+}
+
+/// Process an individual function attribute.  Returns true if the
+/// attribute does not make sense to apply to this type.
+bool ProcessFnAttr(Sema &S, QualType &Type, const AttributeList &Attr) {
+  if (Attr.getKind() == AttributeList::AT_noreturn) {
+    // Complain immediately if the arg count is wrong.
+    if (Attr.getNumArgs() != 0) {
+      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+      return false;
+    }
+
+    // Delay if this is not a function or pointer to block.
+    if (!Type->isFunctionPointerType()
+        && !Type->isBlockPointerType()
+        && !Type->isFunctionType())
+      return true;
+
+    // Otherwise we can process right away.
+    Type = S.Context.getNoReturnType(Type);
+    return false;
+  }
+
+  if (Attr.getKind() == AttributeList::AT_regparm) {
+    // The warning is emitted elsewhere
+    if (Attr.getNumArgs() != 1) {
+      return false;
+    }
+
+    // Delay if this is not a function or pointer to block.
+    if (!Type->isFunctionPointerType()
+        && !Type->isBlockPointerType()
+        && !Type->isFunctionType())
+      return true;
+
+    // Otherwise we can process right away.
+    Expr *NumParamsExpr = static_cast<Expr *>(Attr.getArg(0));
+    llvm::APSInt NumParams(32);
+
+    // The warning is emitted elsewhere
+    if (!NumParamsExpr->isIntegerConstantExpr(NumParams, S.Context))
+      return false;
+
+    Type = S.Context.getRegParmType(Type, NumParams.getZExtValue());
+    return false;
+  }
+
+  // Otherwise, a calling convention.
+  if (Attr.getNumArgs() != 0) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+    return false;
+  }
+
+  QualType T = Type;
+  if (const PointerType *PT = Type->getAs<PointerType>())
+    T = PT->getPointeeType();
+  const FunctionType *Fn = T->getAs<FunctionType>();
+
+  // Delay if the type didn't work out to a function.
+  if (!Fn) return true;
+
+  // TODO: diagnose uses of these conventions on the wrong target.
+  CallingConv CC;
+  switch (Attr.getKind()) {
+  case AttributeList::AT_cdecl: CC = CC_C; break;
+  case AttributeList::AT_fastcall: CC = CC_X86FastCall; break;
+  case AttributeList::AT_stdcall: CC = CC_X86StdCall; break;
+  default: llvm_unreachable("unexpected attribute kind"); return false;
+  }
+
+  CallingConv CCOld = Fn->getCallConv();
+  if (S.Context.getCanonicalCallConv(CC) ==
+      S.Context.getCanonicalCallConv(CCOld)) return false;
+
+  if (CCOld != CC_Default) {
+    // Should we diagnose reapplications of the same convention?
+    S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible)
+      << FunctionType::getNameForCallConv(CC)
+      << FunctionType::getNameForCallConv(CCOld);
+    return false;
+  }
+
+  // Diagnose the use of X86 fastcall on varargs or unprototyped functions.
+  if (CC == CC_X86FastCall) {
+    if (isa<FunctionNoProtoType>(Fn)) {
+      S.Diag(Attr.getLoc(), diag::err_cconv_knr)
+        << FunctionType::getNameForCallConv(CC);
+      return false;
+    }
+
+    const FunctionProtoType *FnP = cast<FunctionProtoType>(Fn);
+    if (FnP->isVariadic()) {
+      S.Diag(Attr.getLoc(), diag::err_cconv_varargs)
+        << FunctionType::getNameForCallConv(CC);
+      return false;
+    }
+  }
+
+  Type = S.Context.getCallConvType(Type, CC);
+  return false;
+}
+
+/// HandleVectorSizeAttribute - this attribute is only applicable to integral
+/// and float scalars, although arrays, pointers, and function return values are
+/// allowed in conjunction with this construct. Aggregates with this attribute
+/// are invalid, even if they are of the same size as a corresponding scalar.
+/// The raw attribute should contain precisely 1 argument, the vector size for
+/// the variable, measured in bytes. If curType and rawAttr are well formed,
+/// this routine will return a new vector type.
+static void HandleVectorSizeAttr(QualType& CurType, const AttributeList &Attr, Sema &S) {
+  // Check the attribute arugments.
+  if (Attr.getNumArgs() != 1) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
+    return;
+  }
+  Expr *sizeExpr = static_cast<Expr *>(Attr.getArg(0));
+  llvm::APSInt vecSize(32);
+  if (!sizeExpr->isIntegerConstantExpr(vecSize, S.Context)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
+      << "vector_size" << sizeExpr->getSourceRange();
+    return;
+  }
+  // the base type must be integer or float, and can't already be a vector.
+  if (CurType->isVectorType() ||
+      (!CurType->isIntegerType() && !CurType->isRealFloatingType())) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type) << CurType;
+    return;
+  }
+  unsigned typeSize = static_cast<unsigned>(S.Context.getTypeSize(CurType));
+  // vecSize is specified in bytes - convert to bits.
+  unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue() * 8);
+
+  // the vector size needs to be an integral multiple of the type size.
+  if (vectorSize % typeSize) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_invalid_size)
+      << sizeExpr->getSourceRange();
+    return;
+  }
+  if (vectorSize == 0) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_zero_size)
+      << sizeExpr->getSourceRange();
+    return;
+  }
+
+  // Success! Instantiate the vector type, the number of elements is > 0, and
+  // not required to be a power of 2, unlike GCC.
+  CurType = S.Context.getVectorType(CurType, vectorSize/typeSize, false, false);
+}
+
+void ProcessTypeAttributeList(Sema &S, QualType &Result,
+                              bool IsDeclSpec, const AttributeList *AL,
+                              DelayedAttributeSet &FnAttrs) {
+  // Scan through and apply attributes to this type where it makes sense.  Some
+  // attributes (such as __address_space__, __vector_size__, etc) apply to the
+  // type, but others can be present in the type specifiers even though they
+  // apply to the decl.  Here we apply type attributes and ignore the rest.
+  for (; AL; AL = AL->getNext()) {
+    // If this is an attribute we can handle, do so now, otherwise, add it to
+    // the LeftOverAttrs list for rechaining.
+    switch (AL->getKind()) {
+    default: break;
+
+    case AttributeList::AT_address_space:
+      HandleAddressSpaceTypeAttribute(Result, *AL, S);
+      break;
+    case AttributeList::AT_objc_gc:
+      HandleObjCGCTypeAttribute(Result, *AL, S);
+      break;
+    case AttributeList::AT_vector_size:
+      HandleVectorSizeAttr(Result, *AL, S);
+      break;
+
+    case AttributeList::AT_noreturn:
+    case AttributeList::AT_cdecl:
+    case AttributeList::AT_fastcall:
+    case AttributeList::AT_stdcall:
+    case AttributeList::AT_regparm:
+      // Don't process these on the DeclSpec.
+      if (IsDeclSpec ||
+          ProcessFnAttr(S, Result, *AL))
+        FnAttrs.push_back(DelayedAttribute(AL, Result));
+      break;
+    }
+  }
+}
+
+/// @brief Ensure that the type T is a complete type.
+///
+/// This routine checks whether the type @p T is complete in any
+/// context where a complete type is required. If @p T is a complete
+/// type, returns false. If @p T is a class template specialization,
+/// this routine then attempts to perform class template
+/// instantiation. If instantiation fails, or if @p T is incomplete
+/// and cannot be completed, issues the diagnostic @p diag (giving it
+/// the type @p T) and returns true.
+///
+/// @param Loc  The location in the source that the incomplete type
+/// diagnostic should refer to.
+///
+/// @param T  The type that this routine is examining for completeness.
+///
+/// @param PD The partial diagnostic that will be printed out if T is not a
+/// complete type.
+///
+/// @returns @c true if @p T is incomplete and a diagnostic was emitted,
+/// @c false otherwise.
+bool Sema::RequireCompleteType(SourceLocation Loc, QualType T,
+                               const PartialDiagnostic &PD,
+                               std::pair<SourceLocation, 
+                                         PartialDiagnostic> Note) {
+  unsigned diag = PD.getDiagID();
+
+  // FIXME: Add this assertion to make sure we always get instantiation points.
+  //  assert(!Loc.isInvalid() && "Invalid location in RequireCompleteType");
+  // FIXME: Add this assertion to help us flush out problems with
+  // checking for dependent types and type-dependent expressions.
+  //
+  //  assert(!T->isDependentType() &&
+  //         "Can't ask whether a dependent type is complete");
+
+  // If we have a complete type, we're done.
+  if (!T->isIncompleteType())
+    return false;
+
+  // If we have a class template specialization or a class member of a
+  // class template specialization, or an array with known size of such,
+  // try to instantiate it.
+  QualType MaybeTemplate = T;
+  if (const ConstantArrayType *Array = Context.getAsConstantArrayType(T))
+    MaybeTemplate = Array->getElementType();
+  if (const RecordType *Record = MaybeTemplate->getAs<RecordType>()) {
+    if (ClassTemplateSpecializationDecl *ClassTemplateSpec
+          = dyn_cast<ClassTemplateSpecializationDecl>(Record->getDecl())) {
+      if (ClassTemplateSpec->getSpecializationKind() == TSK_Undeclared)
+        return InstantiateClassTemplateSpecialization(Loc, ClassTemplateSpec,
+                                                      TSK_ImplicitInstantiation,
+                                                      /*Complain=*/diag != 0);
+    } else if (CXXRecordDecl *Rec
+                 = dyn_cast<CXXRecordDecl>(Record->getDecl())) {
+      if (CXXRecordDecl *Pattern = Rec->getInstantiatedFromMemberClass()) {
+        MemberSpecializationInfo *MSInfo = Rec->getMemberSpecializationInfo();
+        assert(MSInfo && "Missing member specialization information?");
+        // This record was instantiated from a class within a template.
+        if (MSInfo->getTemplateSpecializationKind() 
+                                               != TSK_ExplicitSpecialization)
+          return InstantiateClass(Loc, Rec, Pattern,
+                                  getTemplateInstantiationArgs(Rec),
+                                  TSK_ImplicitInstantiation,
+                                  /*Complain=*/diag != 0);
+      }
+    }
+  }
+
+  if (diag == 0)
+    return true;
+
+  const TagType *Tag = 0;
+  if (const RecordType *Record = T->getAs<RecordType>())
+    Tag = Record;
+  else if (const EnumType *Enum = T->getAs<EnumType>())
+    Tag = Enum;
+
+  // Avoid diagnosing invalid decls as incomplete.
+  if (Tag && Tag->getDecl()->isInvalidDecl())
+    return true;
+
+  // We have an incomplete type. Produce a diagnostic.
+  Diag(Loc, PD) << T;
+
+  // If we have a note, produce it.
+  if (!Note.first.isInvalid())
+    Diag(Note.first, Note.second);
+    
+  // If the type was a forward declaration of a class/struct/union
+  // type, produce a note.
+  if (Tag && !Tag->getDecl()->isInvalidDecl())
+    Diag(Tag->getDecl()->getLocation(),
+         Tag->isBeingDefined() ? diag::note_type_being_defined
+                               : diag::note_forward_declaration)
+        << QualType(Tag, 0);
+
+  return true;
+}
+
+bool Sema::RequireCompleteType(SourceLocation Loc, QualType T,
+                               const PartialDiagnostic &PD) {
+  return RequireCompleteType(Loc, T, PD, 
+                             std::make_pair(SourceLocation(), PDiag(0)));
+}
+  
+bool Sema::RequireCompleteType(SourceLocation Loc, QualType T,
+                               unsigned DiagID) {
+  return RequireCompleteType(Loc, T, PDiag(DiagID),
+                             std::make_pair(SourceLocation(), PDiag(0)));
+}
+
+/// \brief Retrieve a version of the type 'T' that is qualified by the
+/// nested-name-specifier contained in SS.
+QualType Sema::getQualifiedNameType(const CXXScopeSpec &SS, QualType T) {
+  if (!SS.isSet() || SS.isInvalid() || T.isNull())
+    return T;
+
+  NestedNameSpecifier *NNS
+    = static_cast<NestedNameSpecifier *>(SS.getScopeRep());
+  return Context.getQualifiedNameType(NNS, T);
+}
+
+QualType Sema::BuildTypeofExprType(Expr *E) {
+  if (E->getType() == Context.OverloadTy) {
+    // C++ [temp.arg.explicit]p3 allows us to resolve a template-id to a 
+    // function template specialization wherever deduction cannot occur.
+    if (FunctionDecl *Specialization
+        = ResolveSingleFunctionTemplateSpecialization(E)) {
+      // The access doesn't really matter in this case.
+      DeclAccessPair Found = DeclAccessPair::make(Specialization,
+                                                  Specialization->getAccess());
+      E = FixOverloadedFunctionReference(E, Found, Specialization);
+      if (!E)
+        return QualType();      
+    } else {
+      Diag(E->getLocStart(),
+           diag::err_cannot_determine_declared_type_of_overloaded_function)
+        << false << E->getSourceRange();
+      return QualType();
+    }
+  }
+  
+  return Context.getTypeOfExprType(E);
+}
+
+QualType Sema::BuildDecltypeType(Expr *E) {
+  if (E->getType() == Context.OverloadTy) {
+    // C++ [temp.arg.explicit]p3 allows us to resolve a template-id to a 
+    // function template specialization wherever deduction cannot occur.
+    if (FunctionDecl *Specialization
+          = ResolveSingleFunctionTemplateSpecialization(E)) {
+      // The access doesn't really matter in this case.
+      DeclAccessPair Found = DeclAccessPair::make(Specialization,
+                                                  Specialization->getAccess());
+      E = FixOverloadedFunctionReference(E, Found, Specialization);
+      if (!E)
+        return QualType();      
+    } else {
+      Diag(E->getLocStart(),
+           diag::err_cannot_determine_declared_type_of_overloaded_function)
+        << true << E->getSourceRange();
+      return QualType();
+    }
+  }
+  
+  return Context.getDecltypeType(E);
+}
diff --git a/lib/Sema/TargetAttributesSema.cpp b/lib/Sema/TargetAttributesSema.cpp
new file mode 100644
index 0000000..87e7b9d
--- /dev/null
+++ b/lib/Sema/TargetAttributesSema.cpp
@@ -0,0 +1,226 @@
+//===-- TargetAttributesSema.cpp - Encapsulate target attributes-*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains semantic analysis implementation for target-specific
+// attributes.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Sema.h"
+#include "TargetAttributesSema.h"
+#include "clang/Basic/TargetInfo.h"
+#include "llvm/ADT/Triple.h"
+
+using namespace clang;
+
+TargetAttributesSema::~TargetAttributesSema() {}
+bool TargetAttributesSema::ProcessDeclAttribute(Scope *scope, Decl *D,
+                                    const AttributeList &Attr, Sema &S) const {
+  return false;
+}
+
+static void HandleMSP430InterruptAttr(Decl *d,
+                                      const AttributeList &Attr, Sema &S) {
+    // Check the attribute arguments.
+    if (Attr.getNumArgs() != 1) {
+      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
+      return;
+    }
+
+    // FIXME: Check for decl - it should be void ()(void).
+
+    Expr *NumParamsExpr = static_cast<Expr *>(Attr.getArg(0));
+    llvm::APSInt NumParams(32);
+    if (!NumParamsExpr->isIntegerConstantExpr(NumParams, S.Context)) {
+      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
+        << "interrupt" << NumParamsExpr->getSourceRange();
+      return;
+    }
+
+    unsigned Num = NumParams.getLimitedValue(255);
+    if ((Num & 1) || Num > 30) {
+      S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
+        << "interrupt" << (int)NumParams.getSExtValue()
+        << NumParamsExpr->getSourceRange();
+      return;
+    }
+
+    d->addAttr(::new (S.Context) MSP430InterruptAttr(Num));
+    d->addAttr(::new (S.Context) UsedAttr());
+  }
+
+namespace {
+  class MSP430AttributesSema : public TargetAttributesSema {
+  public:
+    MSP430AttributesSema() { }
+    bool ProcessDeclAttribute(Scope *scope, Decl *D,
+                              const AttributeList &Attr, Sema &S) const {
+      if (Attr.getName()->getName() == "interrupt") {
+        HandleMSP430InterruptAttr(D, Attr, S);
+        return true;
+      }
+      return false;
+    }
+  };
+}
+
+static void HandleX86ForceAlignArgPointerAttr(Decl *D,
+                                              const AttributeList& Attr,
+                                              Sema &S) {
+  // Check the attribute arguments.
+  if (Attr.getNumArgs() != 0) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+    return;
+  }
+
+  // If we try to apply it to a function pointer, don't warn, but don't
+  // do anything, either. It doesn't matter anyway, because there's nothing
+  // special about calling a force_align_arg_pointer function.
+  ValueDecl *VD = dyn_cast<ValueDecl>(D);
+  if (VD && VD->getType()->isFunctionPointerType())
+    return;
+  // Also don't warn on function pointer typedefs.
+  TypedefDecl *TD = dyn_cast<TypedefDecl>(D);
+  if (TD && (TD->getUnderlyingType()->isFunctionPointerType() ||
+             TD->getUnderlyingType()->isFunctionType()))
+    return;
+  // Attribute can only be applied to function types.
+  if (!isa<FunctionDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << /* function */0;
+    return;
+  }
+
+  D->addAttr(::new (S.Context) X86ForceAlignArgPointerAttr());
+}
+
+static void HandleDLLImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
+  // check the attribute arguments.
+  if (Attr.getNumArgs() != 0) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+    return;
+  }
+
+  // Attribute can be applied only to functions or variables.
+  if (isa<VarDecl>(D)) {
+    D->addAttr(::new (S.Context) DLLImportAttr());
+    return;
+  }
+
+  FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
+  if (!FD) {
+    // Apparently Visual C++ thinks it is okay to not emit a warning
+    // in this case, so only emit a warning when -fms-extensions is not
+    // specified.
+    if (!S.getLangOptions().Microsoft)
+      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+        << Attr.getName() << 2 /*variable and function*/;
+    return;
+  }
+
+  // Currently, the dllimport attribute is ignored for inlined functions.
+  // Warning is emitted.
+  if (FD->isInlineSpecified()) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport";
+    return;
+  }
+
+  // The attribute is also overridden by a subsequent declaration as dllexport.
+  // Warning is emitted.
+  for (AttributeList *nextAttr = Attr.getNext(); nextAttr;
+       nextAttr = nextAttr->getNext()) {
+    if (nextAttr->getKind() == AttributeList::AT_dllexport) {
+      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport";
+      return;
+    }
+  }
+
+  if (D->getAttr<DLLExportAttr>()) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport";
+    return;
+  }
+
+  D->addAttr(::new (S.Context) DLLImportAttr());
+}
+
+static void HandleDLLExportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
+  // check the attribute arguments.
+  if (Attr.getNumArgs() != 0) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+    return;
+  }
+
+  // Attribute can be applied only to functions or variables.
+  if (isa<VarDecl>(D)) {
+    D->addAttr(::new (S.Context) DLLExportAttr());
+    return;
+  }
+
+  FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
+  if (!FD) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << 2 /*variable and function*/;
+    return;
+  }
+
+  // Currently, the dllexport attribute is ignored for inlined functions, unless
+  // the -fkeep-inline-functions flag has been used. Warning is emitted;
+  if (FD->isInlineSpecified()) {
+    // FIXME: ... unless the -fkeep-inline-functions flag has been used.
+    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllexport";
+    return;
+  }
+
+  D->addAttr(::new (S.Context) DLLExportAttr());
+}
+
+namespace {
+  class X86AttributesSema : public TargetAttributesSema {
+  public:
+    X86AttributesSema() { }
+    bool ProcessDeclAttribute(Scope *scope, Decl *D,
+                              const AttributeList &Attr, Sema &S) const {
+      const llvm::Triple &Triple(S.Context.Target.getTriple());
+      if (Triple.getOS() == llvm::Triple::Win32 ||
+          Triple.getOS() == llvm::Triple::MinGW32 ||
+          Triple.getOS() == llvm::Triple::MinGW64) {
+        switch (Attr.getKind()) {
+        case AttributeList::AT_dllimport: HandleDLLImportAttr(D, Attr, S);
+                                          return true;
+        case AttributeList::AT_dllexport: HandleDLLExportAttr(D, Attr, S);
+                                          return true;
+        default:                          break;
+        }
+      }
+      if (Attr.getName()->getName() == "force_align_arg_pointer" ||
+          Attr.getName()->getName() == "__force_align_arg_pointer__") {
+        HandleX86ForceAlignArgPointerAttr(D, Attr, S);
+        return true;
+      }
+      return false;
+    }
+  };
+}
+
+const TargetAttributesSema &Sema::getTargetAttributesSema() const {
+  if (TheTargetAttributesSema)
+    return *TheTargetAttributesSema;
+
+  const llvm::Triple &Triple(Context.Target.getTriple());
+  switch (Triple.getArch()) {
+  default:
+    return *(TheTargetAttributesSema = new TargetAttributesSema);
+
+  case llvm::Triple::msp430:
+    return *(TheTargetAttributesSema = new MSP430AttributesSema);
+  case llvm::Triple::x86:
+    return *(TheTargetAttributesSema = new X86AttributesSema);
+  }
+}
+
diff --git a/lib/Sema/TargetAttributesSema.h b/lib/Sema/TargetAttributesSema.h
new file mode 100644
index 0000000..8794e40
--- /dev/null
+++ b/lib/Sema/TargetAttributesSema.h
@@ -0,0 +1,27 @@
+//===--- TargetAttributesSema.h - Semantic Analysis For Target Attributes -===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_SEMA_TARGETSEMA_H
+#define CLANG_SEMA_TARGETSEMA_H
+
+namespace clang {
+  class Scope;
+  class Decl;
+  class Attr;
+  class Sema;
+
+  class TargetAttributesSema {
+  public:
+    virtual ~TargetAttributesSema();
+    virtual bool ProcessDeclAttribute(Scope *scope, Decl *D,
+                                      const AttributeList &Attr, Sema &S) const;
+  };
+}
+
+#endif
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
new file mode 100644
index 0000000..f80747b
--- /dev/null
+++ b/lib/Sema/TreeTransform.h
@@ -0,0 +1,6462 @@
+//===------- TreeTransform.h - Semantic Tree Transformation -----*- C++ -*-===/
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//===----------------------------------------------------------------------===/
+//
+//  This file implements a semantic tree transformation that takes a given
+//  AST and rebuilds it, possibly transforming some nodes in the process.
+//
+//===----------------------------------------------------------------------===/
+#ifndef LLVM_CLANG_SEMA_TREETRANSFORM_H
+#define LLVM_CLANG_SEMA_TREETRANSFORM_H
+
+#include "Sema.h"
+#include "Lookup.h"
+#include "clang/Sema/SemaDiagnostic.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/ExprObjC.h"
+#include "clang/AST/Stmt.h"
+#include "clang/AST/StmtCXX.h"
+#include "clang/AST/StmtObjC.h"
+#include "clang/AST/TypeLocBuilder.h"
+#include "clang/Parse/Ownership.h"
+#include "clang/Parse/Designator.h"
+#include "clang/Lex/Preprocessor.h"
+#include "llvm/Support/ErrorHandling.h"
+#include <algorithm>
+
+namespace clang {
+
+/// \brief A semantic tree transformation that allows one to transform one
+/// abstract syntax tree into another.
+///
+/// A new tree transformation is defined by creating a new subclass \c X of
+/// \c TreeTransform<X> and then overriding certain operations to provide
+/// behavior specific to that transformation. For example, template
+/// instantiation is implemented as a tree transformation where the
+/// transformation of TemplateTypeParmType nodes involves substituting the
+/// template arguments for their corresponding template parameters; a similar
+/// transformation is performed for non-type template parameters and
+/// template template parameters.
+///
+/// This tree-transformation template uses static polymorphism to allow
+/// subclasses to customize any of its operations. Thus, a subclass can
+/// override any of the transformation or rebuild operators by providing an
+/// operation with the same signature as the default implementation. The
+/// overridding function should not be virtual.
+///
+/// Semantic tree transformations are split into two stages, either of which
+/// can be replaced by a subclass. The "transform" step transforms an AST node
+/// or the parts of an AST node using the various transformation functions,
+/// then passes the pieces on to the "rebuild" step, which constructs a new AST
+/// node of the appropriate kind from the pieces. The default transformation
+/// routines recursively transform the operands to composite AST nodes (e.g.,
+/// the pointee type of a PointerType node) and, if any of those operand nodes
+/// were changed by the transformation, invokes the rebuild operation to create
+/// a new AST node.
+///
+/// Subclasses can customize the transformation at various levels. The
+/// most coarse-grained transformations involve replacing TransformType(),
+/// TransformExpr(), TransformDecl(), TransformNestedNameSpecifier(),
+/// TransformTemplateName(), or TransformTemplateArgument() with entirely
+/// new implementations.
+///
+/// For more fine-grained transformations, subclasses can replace any of the
+/// \c TransformXXX functions (where XXX is the name of an AST node, e.g.,
+/// PointerType, StmtExpr) to alter the transformation. As mentioned previously,
+/// replacing TransformTemplateTypeParmType() allows template instantiation
+/// to substitute template arguments for their corresponding template
+/// parameters. Additionally, subclasses can override the \c RebuildXXX
+/// functions to control how AST nodes are rebuilt when their operands change.
+/// By default, \c TreeTransform will invoke semantic analysis to rebuild
+/// AST nodes. However, certain other tree transformations (e.g, cloning) may
+/// be able to use more efficient rebuild steps.
+///
+/// There are a handful of other functions that can be overridden, allowing one
+/// to avoid traversing nodes that don't need any transformation
+/// (\c AlreadyTransformed()), force rebuilding AST nodes even when their
+/// operands have not changed (\c AlwaysRebuild()), and customize the
+/// default locations and entity names used for type-checking
+/// (\c getBaseLocation(), \c getBaseEntity()).
+template<typename Derived>
+class TreeTransform {
+protected:
+  Sema &SemaRef;
+
+public:
+  typedef Sema::OwningStmtResult OwningStmtResult;
+  typedef Sema::OwningExprResult OwningExprResult;
+  typedef Sema::StmtArg StmtArg;
+  typedef Sema::ExprArg ExprArg;
+  typedef Sema::MultiExprArg MultiExprArg;
+  typedef Sema::MultiStmtArg MultiStmtArg;
+  typedef Sema::DeclPtrTy DeclPtrTy;
+  
+  /// \brief Initializes a new tree transformer.
+  TreeTransform(Sema &SemaRef) : SemaRef(SemaRef) { }
+
+  /// \brief Retrieves a reference to the derived class.
+  Derived &getDerived() { return static_cast<Derived&>(*this); }
+
+  /// \brief Retrieves a reference to the derived class.
+  const Derived &getDerived() const {
+    return static_cast<const Derived&>(*this);
+  }
+
+  /// \brief Retrieves a reference to the semantic analysis object used for
+  /// this tree transform.
+  Sema &getSema() const { return SemaRef; }
+
+  /// \brief Whether the transformation should always rebuild AST nodes, even
+  /// if none of the children have changed.
+  ///
+  /// Subclasses may override this function to specify when the transformation
+  /// should rebuild all AST nodes.
+  bool AlwaysRebuild() { return false; }
+
+  /// \brief Returns the location of the entity being transformed, if that
+  /// information was not available elsewhere in the AST.
+  ///
+  /// By default, returns no source-location information. Subclasses can
+  /// provide an alternative implementation that provides better location
+  /// information.
+  SourceLocation getBaseLocation() { return SourceLocation(); }
+
+  /// \brief Returns the name of the entity being transformed, if that
+  /// information was not available elsewhere in the AST.
+  ///
+  /// By default, returns an empty name. Subclasses can provide an alternative
+  /// implementation with a more precise name.
+  DeclarationName getBaseEntity() { return DeclarationName(); }
+
+  /// \brief Sets the "base" location and entity when that
+  /// information is known based on another transformation.
+  ///
+  /// By default, the source location and entity are ignored. Subclasses can
+  /// override this function to provide a customized implementation.
+  void setBase(SourceLocation Loc, DeclarationName Entity) { }
+
+  /// \brief RAII object that temporarily sets the base location and entity
+  /// used for reporting diagnostics in types.
+  class TemporaryBase {
+    TreeTransform &Self;
+    SourceLocation OldLocation;
+    DeclarationName OldEntity;
+
+  public:
+    TemporaryBase(TreeTransform &Self, SourceLocation Location,
+                  DeclarationName Entity) : Self(Self) {
+      OldLocation = Self.getDerived().getBaseLocation();
+      OldEntity = Self.getDerived().getBaseEntity();
+      Self.getDerived().setBase(Location, Entity);
+    }
+
+    ~TemporaryBase() {
+      Self.getDerived().setBase(OldLocation, OldEntity);
+    }
+  };
+
+  /// \brief Determine whether the given type \p T has already been
+  /// transformed.
+  ///
+  /// Subclasses can provide an alternative implementation of this routine
+  /// to short-circuit evaluation when it is known that a given type will
+  /// not change. For example, template instantiation need not traverse
+  /// non-dependent types.
+  bool AlreadyTransformed(QualType T) {
+    return T.isNull();
+  }
+
+  /// \brief Determine whether the given call argument should be dropped, e.g.,
+  /// because it is a default argument.
+  ///
+  /// Subclasses can provide an alternative implementation of this routine to
+  /// determine which kinds of call arguments get dropped. By default,
+  /// CXXDefaultArgument nodes are dropped (prior to transformation).
+  bool DropCallArgument(Expr *E) {
+    return E->isDefaultArgument();
+  }
+  
+  /// \brief Transforms the given type into another type.
+  ///
+  /// By default, this routine transforms a type by creating a
+  /// TypeSourceInfo for it and delegating to the appropriate
+  /// function.  This is expensive, but we don't mind, because
+  /// this method is deprecated anyway;  all users should be
+  /// switched to storing TypeSourceInfos.
+  ///
+  /// \returns the transformed type.
+  QualType TransformType(QualType T, QualType ObjectType = QualType());
+
+  /// \brief Transforms the given type-with-location into a new
+  /// type-with-location.
+  ///
+  /// By default, this routine transforms a type by delegating to the
+  /// appropriate TransformXXXType to build a new type.  Subclasses
+  /// may override this function (to take over all type
+  /// transformations) or some set of the TransformXXXType functions
+  /// to alter the transformation.
+  TypeSourceInfo *TransformType(TypeSourceInfo *DI, 
+                                QualType ObjectType = QualType());
+
+  /// \brief Transform the given type-with-location into a new
+  /// type, collecting location information in the given builder
+  /// as necessary.
+  ///
+  QualType TransformType(TypeLocBuilder &TLB, TypeLoc TL, 
+                         QualType ObjectType = QualType());
+
+  /// \brief Transform the given statement.
+  ///
+  /// By default, this routine transforms a statement by delegating to the
+  /// appropriate TransformXXXStmt function to transform a specific kind of
+  /// statement or the TransformExpr() function to transform an expression.
+  /// Subclasses may override this function to transform statements using some
+  /// other mechanism.
+  ///
+  /// \returns the transformed statement.
+  OwningStmtResult TransformStmt(Stmt *S);
+
+  /// \brief Transform the given expression.
+  ///
+  /// By default, this routine transforms an expression by delegating to the
+  /// appropriate TransformXXXExpr function to build a new expression.
+  /// Subclasses may override this function to transform expressions using some
+  /// other mechanism.
+  ///
+  /// \returns the transformed expression.
+  OwningExprResult TransformExpr(Expr *E);
+
+  /// \brief Transform the given declaration, which is referenced from a type
+  /// or expression.
+  ///
+  /// By default, acts as the identity function on declarations. Subclasses
+  /// may override this function to provide alternate behavior.
+  Decl *TransformDecl(SourceLocation Loc, Decl *D) { return D; }
+
+  /// \brief Transform the definition of the given declaration.
+  ///
+  /// By default, invokes TransformDecl() to transform the declaration.
+  /// Subclasses may override this function to provide alternate behavior.
+  Decl *TransformDefinition(SourceLocation Loc, Decl *D) { 
+    return getDerived().TransformDecl(Loc, D); 
+  }
+
+  /// \brief Transform the given declaration, which was the first part of a
+  /// nested-name-specifier in a member access expression.
+  ///
+  /// This specific declaration transformation only applies to the first 
+  /// identifier in a nested-name-specifier of a member access expression, e.g.,
+  /// the \c T in \c x->T::member
+  ///
+  /// By default, invokes TransformDecl() to transform the declaration.
+  /// Subclasses may override this function to provide alternate behavior.
+  NamedDecl *TransformFirstQualifierInScope(NamedDecl *D, SourceLocation Loc) { 
+    return cast_or_null<NamedDecl>(getDerived().TransformDecl(Loc, D)); 
+  }
+  
+  /// \brief Transform the given nested-name-specifier.
+  ///
+  /// By default, transforms all of the types and declarations within the
+  /// nested-name-specifier. Subclasses may override this function to provide
+  /// alternate behavior.
+  NestedNameSpecifier *TransformNestedNameSpecifier(NestedNameSpecifier *NNS,
+                                                    SourceRange Range,
+                                              QualType ObjectType = QualType(),
+                                          NamedDecl *FirstQualifierInScope = 0);
+
+  /// \brief Transform the given declaration name.
+  ///
+  /// By default, transforms the types of conversion function, constructor,
+  /// and destructor names and then (if needed) rebuilds the declaration name.
+  /// Identifiers and selectors are returned unmodified. Sublcasses may
+  /// override this function to provide alternate behavior.
+  DeclarationName TransformDeclarationName(DeclarationName Name,
+                                           SourceLocation Loc,
+                                           QualType ObjectType = QualType());
+
+  /// \brief Transform the given template name.
+  ///
+  /// By default, transforms the template name by transforming the declarations
+  /// and nested-name-specifiers that occur within the template name.
+  /// Subclasses may override this function to provide alternate behavior.
+  TemplateName TransformTemplateName(TemplateName Name,
+                                     QualType ObjectType = QualType());
+
+  /// \brief Transform the given template argument.
+  ///
+  /// By default, this operation transforms the type, expression, or
+  /// declaration stored within the template argument and constructs a
+  /// new template argument from the transformed result. Subclasses may
+  /// override this function to provide alternate behavior.
+  ///
+  /// Returns true if there was an error.
+  bool TransformTemplateArgument(const TemplateArgumentLoc &Input,
+                                 TemplateArgumentLoc &Output);
+
+  /// \brief Fakes up a TemplateArgumentLoc for a given TemplateArgument.
+  void InventTemplateArgumentLoc(const TemplateArgument &Arg,
+                                 TemplateArgumentLoc &ArgLoc);
+
+  /// \brief Fakes up a TypeSourceInfo for a type.
+  TypeSourceInfo *InventTypeSourceInfo(QualType T) {
+    return SemaRef.Context.getTrivialTypeSourceInfo(T,
+                       getDerived().getBaseLocation());
+  }
+
+#define ABSTRACT_TYPELOC(CLASS, PARENT)
+#define TYPELOC(CLASS, PARENT)                                   \
+  QualType Transform##CLASS##Type(TypeLocBuilder &TLB, CLASS##TypeLoc T, \
+                                  QualType ObjectType = QualType());
+#include "clang/AST/TypeLocNodes.def"
+
+  /// \brief Transforms the parameters of a function type into the
+  /// given vectors.
+  ///
+  /// The result vectors should be kept in sync; null entries in the
+  /// variables vector are acceptable.
+  ///
+  /// Return true on error.
+  bool TransformFunctionTypeParams(FunctionProtoTypeLoc TL,
+                                   llvm::SmallVectorImpl<QualType> &PTypes,
+                                   llvm::SmallVectorImpl<ParmVarDecl*> &PVars);
+
+  /// \brief Transforms a single function-type parameter.  Return null
+  /// on error.
+  ParmVarDecl *TransformFunctionTypeParam(ParmVarDecl *OldParm);
+
+  QualType TransformReferenceType(TypeLocBuilder &TLB, ReferenceTypeLoc TL, 
+                                  QualType ObjectType);
+
+  QualType 
+  TransformTemplateSpecializationType(const TemplateSpecializationType *T,
+                                      QualType ObjectType);
+
+  OwningStmtResult TransformCompoundStmt(CompoundStmt *S, bool IsStmtExpr);
+  OwningExprResult TransformCXXNamedCastExpr(CXXNamedCastExpr *E);
+
+#define STMT(Node, Parent)                        \
+  OwningStmtResult Transform##Node(Node *S);
+#define EXPR(Node, Parent)                        \
+  OwningExprResult Transform##Node(Node *E);
+#define ABSTRACT_EXPR(Node, Parent)
+#include "clang/AST/StmtNodes.def"
+
+  /// \brief Build a new pointer type given its pointee type.
+  ///
+  /// By default, performs semantic analysis when building the pointer type.
+  /// Subclasses may override this routine to provide different behavior.
+  QualType RebuildPointerType(QualType PointeeType, SourceLocation Sigil);
+
+  /// \brief Build a new block pointer type given its pointee type.
+  ///
+  /// By default, performs semantic analysis when building the block pointer
+  /// type. Subclasses may override this routine to provide different behavior.
+  QualType RebuildBlockPointerType(QualType PointeeType, SourceLocation Sigil);
+
+  /// \brief Build a new reference type given the type it references.
+  ///
+  /// By default, performs semantic analysis when building the
+  /// reference type. Subclasses may override this routine to provide
+  /// different behavior.
+  ///
+  /// \param LValue whether the type was written with an lvalue sigil
+  /// or an rvalue sigil.
+  QualType RebuildReferenceType(QualType ReferentType,
+                                bool LValue,
+                                SourceLocation Sigil);
+
+  /// \brief Build a new member pointer type given the pointee type and the
+  /// class type it refers into.
+  ///
+  /// By default, performs semantic analysis when building the member pointer
+  /// type. Subclasses may override this routine to provide different behavior.
+  QualType RebuildMemberPointerType(QualType PointeeType, QualType ClassType,
+                                    SourceLocation Sigil);
+
+  /// \brief Build a new array type given the element type, size
+  /// modifier, size of the array (if known), size expression, and index type
+  /// qualifiers.
+  ///
+  /// By default, performs semantic analysis when building the array type.
+  /// Subclasses may override this routine to provide different behavior.
+  /// Also by default, all of the other Rebuild*Array
+  QualType RebuildArrayType(QualType ElementType,
+                            ArrayType::ArraySizeModifier SizeMod,
+                            const llvm::APInt *Size,
+                            Expr *SizeExpr,
+                            unsigned IndexTypeQuals,
+                            SourceRange BracketsRange);
+
+  /// \brief Build a new constant array type given the element type, size
+  /// modifier, (known) size of the array, and index type qualifiers.
+  ///
+  /// By default, performs semantic analysis when building the array type.
+  /// Subclasses may override this routine to provide different behavior.
+  QualType RebuildConstantArrayType(QualType ElementType,
+                                    ArrayType::ArraySizeModifier SizeMod,
+                                    const llvm::APInt &Size,
+                                    unsigned IndexTypeQuals,
+                                    SourceRange BracketsRange);
+
+  /// \brief Build a new incomplete array type given the element type, size
+  /// modifier, and index type qualifiers.
+  ///
+  /// By default, performs semantic analysis when building the array type.
+  /// Subclasses may override this routine to provide different behavior.
+  QualType RebuildIncompleteArrayType(QualType ElementType,
+                                      ArrayType::ArraySizeModifier SizeMod,
+                                      unsigned IndexTypeQuals,
+                                      SourceRange BracketsRange);
+
+  /// \brief Build a new variable-length array type given the element type,
+  /// size modifier, size expression, and index type qualifiers.
+  ///
+  /// By default, performs semantic analysis when building the array type.
+  /// Subclasses may override this routine to provide different behavior.
+  QualType RebuildVariableArrayType(QualType ElementType,
+                                    ArrayType::ArraySizeModifier SizeMod,
+                                    ExprArg SizeExpr,
+                                    unsigned IndexTypeQuals,
+                                    SourceRange BracketsRange);
+
+  /// \brief Build a new dependent-sized array type given the element type,
+  /// size modifier, size expression, and index type qualifiers.
+  ///
+  /// By default, performs semantic analysis when building the array type.
+  /// Subclasses may override this routine to provide different behavior.
+  QualType RebuildDependentSizedArrayType(QualType ElementType,
+                                          ArrayType::ArraySizeModifier SizeMod,
+                                          ExprArg SizeExpr,
+                                          unsigned IndexTypeQuals,
+                                          SourceRange BracketsRange);
+
+  /// \brief Build a new vector type given the element type and
+  /// number of elements.
+  ///
+  /// By default, performs semantic analysis when building the vector type.
+  /// Subclasses may override this routine to provide different behavior.
+  QualType RebuildVectorType(QualType ElementType, unsigned NumElements,
+    bool IsAltiVec, bool IsPixel);
+
+  /// \brief Build a new extended vector type given the element type and
+  /// number of elements.
+  ///
+  /// By default, performs semantic analysis when building the vector type.
+  /// Subclasses may override this routine to provide different behavior.
+  QualType RebuildExtVectorType(QualType ElementType, unsigned NumElements,
+                                SourceLocation AttributeLoc);
+
+  /// \brief Build a new potentially dependently-sized extended vector type
+  /// given the element type and number of elements.
+  ///
+  /// By default, performs semantic analysis when building the vector type.
+  /// Subclasses may override this routine to provide different behavior.
+  QualType RebuildDependentSizedExtVectorType(QualType ElementType,
+                                              ExprArg SizeExpr,
+                                              SourceLocation AttributeLoc);
+
+  /// \brief Build a new function type.
+  ///
+  /// By default, performs semantic analysis when building the function type.
+  /// Subclasses may override this routine to provide different behavior.
+  QualType RebuildFunctionProtoType(QualType T,
+                                    QualType *ParamTypes,
+                                    unsigned NumParamTypes,
+                                    bool Variadic, unsigned Quals);
+
+  /// \brief Build a new unprototyped function type.
+  QualType RebuildFunctionNoProtoType(QualType ResultType);
+
+  /// \brief Rebuild an unresolved typename type, given the decl that
+  /// the UnresolvedUsingTypenameDecl was transformed to.
+  QualType RebuildUnresolvedUsingType(Decl *D);
+
+  /// \brief Build a new typedef type.
+  QualType RebuildTypedefType(TypedefDecl *Typedef) {
+    return SemaRef.Context.getTypeDeclType(Typedef);
+  }
+
+  /// \brief Build a new class/struct/union type.
+  QualType RebuildRecordType(RecordDecl *Record) {
+    return SemaRef.Context.getTypeDeclType(Record);
+  }
+
+  /// \brief Build a new Enum type.
+  QualType RebuildEnumType(EnumDecl *Enum) {
+    return SemaRef.Context.getTypeDeclType(Enum);
+  }
+
+  /// \brief Build a new elaborated type.
+  QualType RebuildElaboratedType(QualType T, ElaboratedType::TagKind Tag) {
+    return SemaRef.Context.getElaboratedType(T, Tag);
+  }
+
+  /// \brief Build a new typeof(expr) type.
+  ///
+  /// By default, performs semantic analysis when building the typeof type.
+  /// Subclasses may override this routine to provide different behavior.
+  QualType RebuildTypeOfExprType(ExprArg Underlying);
+
+  /// \brief Build a new typeof(type) type.
+  ///
+  /// By default, builds a new TypeOfType with the given underlying type.
+  QualType RebuildTypeOfType(QualType Underlying);
+
+  /// \brief Build a new C++0x decltype type.
+  ///
+  /// By default, performs semantic analysis when building the decltype type.
+  /// Subclasses may override this routine to provide different behavior.
+  QualType RebuildDecltypeType(ExprArg Underlying);
+
+  /// \brief Build a new template specialization type.
+  ///
+  /// By default, performs semantic analysis when building the template
+  /// specialization type. Subclasses may override this routine to provide
+  /// different behavior.
+  QualType RebuildTemplateSpecializationType(TemplateName Template,
+                                             SourceLocation TemplateLoc,
+                                       const TemplateArgumentListInfo &Args);
+
+  /// \brief Build a new qualified name type.
+  ///
+  /// By default, builds a new QualifiedNameType type from the
+  /// nested-name-specifier and the named type. Subclasses may override
+  /// this routine to provide different behavior.
+  QualType RebuildQualifiedNameType(NestedNameSpecifier *NNS, QualType Named) {
+    return SemaRef.Context.getQualifiedNameType(NNS, Named);
+  }
+
+  /// \brief Build a new typename type that refers to a template-id.
+  ///
+  /// By default, builds a new DependentNameType type from the 
+  /// nested-name-specifier
+  /// and the given type. Subclasses may override this routine to provide
+  /// different behavior.
+  QualType RebuildDependentNameType(ElaboratedTypeKeyword Keyword,
+                                    NestedNameSpecifier *NNS, QualType T) {
+    if (NNS->isDependent()) {
+      // If the name is still dependent, just build a new dependent name type.
+      CXXScopeSpec SS;
+      SS.setScopeRep(NNS);
+      if (!SemaRef.computeDeclContext(SS))
+        return SemaRef.Context.getDependentNameType(Keyword, NNS,
+                                          cast<TemplateSpecializationType>(T));
+    }
+    
+    // FIXME: Handle elaborated-type-specifiers separately.
+    return SemaRef.Context.getQualifiedNameType(NNS, T);
+  }
+
+  /// \brief Build a new typename type that refers to an identifier.
+  ///
+  /// By default, performs semantic analysis when building the typename type
+  /// (or qualified name type). Subclasses may override this routine to provide
+  /// different behavior.
+  QualType RebuildDependentNameType(ElaboratedTypeKeyword Keyword, 
+                                    NestedNameSpecifier *NNS,
+                                    const IdentifierInfo *Id,
+                                    SourceRange SR) {
+    CXXScopeSpec SS;
+    SS.setScopeRep(NNS);
+    
+    if (NNS->isDependent()) {
+      // If the name is still dependent, just build a new dependent name type.
+      if (!SemaRef.computeDeclContext(SS))
+        return SemaRef.Context.getDependentNameType(Keyword, NNS, Id);
+    }
+
+    TagDecl::TagKind Kind = TagDecl::TK_enum;
+    switch (Keyword) {
+      case ETK_None:
+        // Fall through.
+      case ETK_Typename:
+        return SemaRef.CheckTypenameType(Keyword, NNS, *Id, SR);
+        
+      case ETK_Class: Kind = TagDecl::TK_class; break;
+      case ETK_Struct: Kind = TagDecl::TK_struct; break;
+      case ETK_Union: Kind = TagDecl::TK_union; break;
+      case ETK_Enum: Kind = TagDecl::TK_enum; break;
+    }
+    
+    // We had a dependent elaborated-type-specifier that as been transformed
+    // into a non-dependent elaborated-type-specifier. Find the tag we're
+    // referring to.
+    LookupResult Result(SemaRef, Id, SR.getEnd(), Sema::LookupTagName);
+    DeclContext *DC = SemaRef.computeDeclContext(SS, false);
+    if (!DC)
+      return QualType();
+
+    TagDecl *Tag = 0;
+    SemaRef.LookupQualifiedName(Result, DC);
+    switch (Result.getResultKind()) {
+      case LookupResult::NotFound:
+      case LookupResult::NotFoundInCurrentInstantiation:
+        break;
+        
+      case LookupResult::Found:
+        Tag = Result.getAsSingle<TagDecl>();
+        break;
+        
+      case LookupResult::FoundOverloaded:
+      case LookupResult::FoundUnresolvedValue:
+        llvm_unreachable("Tag lookup cannot find non-tags");
+        return QualType();
+        
+      case LookupResult::Ambiguous:
+        // Let the LookupResult structure handle ambiguities.
+        return QualType();
+    }
+
+    if (!Tag) {
+      // FIXME: Would be nice to highlight just the source range.
+      SemaRef.Diag(SR.getEnd(), diag::err_not_tag_in_scope)
+        << Kind << Id << DC;
+      return QualType();
+    }
+    
+    // FIXME: Terrible location information
+    if (!SemaRef.isAcceptableTagRedeclaration(Tag, Kind, SR.getEnd(), *Id)) {
+      SemaRef.Diag(SR.getBegin(), diag::err_use_with_wrong_tag) << Id;
+      SemaRef.Diag(Tag->getLocation(), diag::note_previous_use);
+      return QualType();
+    }
+
+    // Build the elaborated-type-specifier type.
+    QualType T = SemaRef.Context.getTypeDeclType(Tag);
+    T = SemaRef.Context.getQualifiedNameType(NNS, T);
+    return SemaRef.Context.getElaboratedType(T, Kind);
+  }
+
+  /// \brief Build a new nested-name-specifier given the prefix and an
+  /// identifier that names the next step in the nested-name-specifier.
+  ///
+  /// By default, performs semantic analysis when building the new
+  /// nested-name-specifier. Subclasses may override this routine to provide
+  /// different behavior.
+  NestedNameSpecifier *RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
+                                                  SourceRange Range,
+                                                  IdentifierInfo &II,
+                                                  QualType ObjectType,
+                                              NamedDecl *FirstQualifierInScope);
+
+  /// \brief Build a new nested-name-specifier given the prefix and the
+  /// namespace named in the next step in the nested-name-specifier.
+  ///
+  /// By default, performs semantic analysis when building the new
+  /// nested-name-specifier. Subclasses may override this routine to provide
+  /// different behavior.
+  NestedNameSpecifier *RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
+                                                  SourceRange Range,
+                                                  NamespaceDecl *NS);
+
+  /// \brief Build a new nested-name-specifier given the prefix and the
+  /// type named in the next step in the nested-name-specifier.
+  ///
+  /// By default, performs semantic analysis when building the new
+  /// nested-name-specifier. Subclasses may override this routine to provide
+  /// different behavior.
+  NestedNameSpecifier *RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
+                                                  SourceRange Range,
+                                                  bool TemplateKW,
+                                                  QualType T);
+
+  /// \brief Build a new template name given a nested name specifier, a flag
+  /// indicating whether the "template" keyword was provided, and the template
+  /// that the template name refers to.
+  ///
+  /// By default, builds the new template name directly. Subclasses may override
+  /// this routine to provide different behavior.
+  TemplateName RebuildTemplateName(NestedNameSpecifier *Qualifier,
+                                   bool TemplateKW,
+                                   TemplateDecl *Template);
+
+  /// \brief Build a new template name given a nested name specifier and the
+  /// name that is referred to as a template.
+  ///
+  /// By default, performs semantic analysis to determine whether the name can
+  /// be resolved to a specific template, then builds the appropriate kind of
+  /// template name. Subclasses may override this routine to provide different
+  /// behavior.
+  TemplateName RebuildTemplateName(NestedNameSpecifier *Qualifier,
+                                   const IdentifierInfo &II,
+                                   QualType ObjectType);
+
+  /// \brief Build a new template name given a nested name specifier and the
+  /// overloaded operator name that is referred to as a template.
+  ///
+  /// By default, performs semantic analysis to determine whether the name can
+  /// be resolved to a specific template, then builds the appropriate kind of
+  /// template name. Subclasses may override this routine to provide different
+  /// behavior.
+  TemplateName RebuildTemplateName(NestedNameSpecifier *Qualifier,
+                                   OverloadedOperatorKind Operator,
+                                   QualType ObjectType);
+  
+  /// \brief Build a new compound statement.
+  ///
+  /// By default, performs semantic analysis to build the new statement.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningStmtResult RebuildCompoundStmt(SourceLocation LBraceLoc,
+                                       MultiStmtArg Statements,
+                                       SourceLocation RBraceLoc,
+                                       bool IsStmtExpr) {
+    return getSema().ActOnCompoundStmt(LBraceLoc, RBraceLoc, move(Statements),
+                                       IsStmtExpr);
+  }
+
+  /// \brief Build a new case statement.
+  ///
+  /// By default, performs semantic analysis to build the new statement.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningStmtResult RebuildCaseStmt(SourceLocation CaseLoc,
+                                   ExprArg LHS,
+                                   SourceLocation EllipsisLoc,
+                                   ExprArg RHS,
+                                   SourceLocation ColonLoc) {
+    return getSema().ActOnCaseStmt(CaseLoc, move(LHS), EllipsisLoc, move(RHS),
+                                   ColonLoc);
+  }
+
+  /// \brief Attach the body to a new case statement.
+  ///
+  /// By default, performs semantic analysis to build the new statement.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningStmtResult RebuildCaseStmtBody(StmtArg S, StmtArg Body) {
+    getSema().ActOnCaseStmtBody(S.get(), move(Body));
+    return move(S);
+  }
+
+  /// \brief Build a new default statement.
+  ///
+  /// By default, performs semantic analysis to build the new statement.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningStmtResult RebuildDefaultStmt(SourceLocation DefaultLoc,
+                                      SourceLocation ColonLoc,
+                                      StmtArg SubStmt) {
+    return getSema().ActOnDefaultStmt(DefaultLoc, ColonLoc, move(SubStmt),
+                                      /*CurScope=*/0);
+  }
+
+  /// \brief Build a new label statement.
+  ///
+  /// By default, performs semantic analysis to build the new statement.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningStmtResult RebuildLabelStmt(SourceLocation IdentLoc,
+                                    IdentifierInfo *Id,
+                                    SourceLocation ColonLoc,
+                                    StmtArg SubStmt) {
+    return SemaRef.ActOnLabelStmt(IdentLoc, Id, ColonLoc, move(SubStmt));
+  }
+
+  /// \brief Build a new "if" statement.
+  ///
+  /// By default, performs semantic analysis to build the new statement.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningStmtResult RebuildIfStmt(SourceLocation IfLoc, Sema::FullExprArg Cond,
+                                 VarDecl *CondVar, StmtArg Then, 
+                                 SourceLocation ElseLoc, StmtArg Else) {
+    return getSema().ActOnIfStmt(IfLoc, Cond, DeclPtrTy::make(CondVar), 
+                                 move(Then), ElseLoc, move(Else));
+  }
+
+  /// \brief Start building a new switch statement.
+  ///
+  /// By default, performs semantic analysis to build the new statement.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningStmtResult RebuildSwitchStmtStart(Sema::FullExprArg Cond, 
+                                          VarDecl *CondVar) {
+    return getSema().ActOnStartOfSwitchStmt(Cond, DeclPtrTy::make(CondVar));
+  }
+
+  /// \brief Attach the body to the switch statement.
+  ///
+  /// By default, performs semantic analysis to build the new statement.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningStmtResult RebuildSwitchStmtBody(SourceLocation SwitchLoc,
+                                         StmtArg Switch, StmtArg Body) {
+    return getSema().ActOnFinishSwitchStmt(SwitchLoc, move(Switch),
+                                         move(Body));
+  }
+
+  /// \brief Build a new while statement.
+  ///
+  /// By default, performs semantic analysis to build the new statement.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningStmtResult RebuildWhileStmt(SourceLocation WhileLoc,
+                                    Sema::FullExprArg Cond,
+                                    VarDecl *CondVar,
+                                    StmtArg Body) {
+    return getSema().ActOnWhileStmt(WhileLoc, Cond, DeclPtrTy::make(CondVar),
+                                    move(Body));
+  }
+
+  /// \brief Build a new do-while statement.
+  ///
+  /// By default, performs semantic analysis to build the new statement.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningStmtResult RebuildDoStmt(SourceLocation DoLoc, StmtArg Body,
+                                 SourceLocation WhileLoc,
+                                 SourceLocation LParenLoc,
+                                 ExprArg Cond,
+                                 SourceLocation RParenLoc) {
+    return getSema().ActOnDoStmt(DoLoc, move(Body), WhileLoc, LParenLoc,
+                                 move(Cond), RParenLoc);
+  }
+
+  /// \brief Build a new for statement.
+  ///
+  /// By default, performs semantic analysis to build the new statement.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningStmtResult RebuildForStmt(SourceLocation ForLoc,
+                                  SourceLocation LParenLoc,
+                                  StmtArg Init, Sema::FullExprArg Cond, 
+                                  VarDecl *CondVar, Sema::FullExprArg Inc,
+                                  SourceLocation RParenLoc, StmtArg Body) {
+    return getSema().ActOnForStmt(ForLoc, LParenLoc, move(Init), Cond, 
+                                  DeclPtrTy::make(CondVar),
+                                  Inc, RParenLoc, move(Body));
+  }
+
+  /// \brief Build a new goto statement.
+  ///
+  /// By default, performs semantic analysis to build the new statement.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningStmtResult RebuildGotoStmt(SourceLocation GotoLoc,
+                                   SourceLocation LabelLoc,
+                                   LabelStmt *Label) {
+    return getSema().ActOnGotoStmt(GotoLoc, LabelLoc, Label->getID());
+  }
+
+  /// \brief Build a new indirect goto statement.
+  ///
+  /// By default, performs semantic analysis to build the new statement.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningStmtResult RebuildIndirectGotoStmt(SourceLocation GotoLoc,
+                                           SourceLocation StarLoc,
+                                           ExprArg Target) {
+    return getSema().ActOnIndirectGotoStmt(GotoLoc, StarLoc, move(Target));
+  }
+
+  /// \brief Build a new return statement.
+  ///
+  /// By default, performs semantic analysis to build the new statement.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningStmtResult RebuildReturnStmt(SourceLocation ReturnLoc,
+                                     ExprArg Result) {
+
+    return getSema().ActOnReturnStmt(ReturnLoc, move(Result));
+  }
+
+  /// \brief Build a new declaration statement.
+  ///
+  /// By default, performs semantic analysis to build the new statement.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningStmtResult RebuildDeclStmt(Decl **Decls, unsigned NumDecls,
+                                   SourceLocation StartLoc,
+                                   SourceLocation EndLoc) {
+    return getSema().Owned(
+             new (getSema().Context) DeclStmt(
+                                        DeclGroupRef::Create(getSema().Context,
+                                                             Decls, NumDecls),
+                                              StartLoc, EndLoc));
+  }
+
+  /// \brief Build a new inline asm statement.
+  ///
+  /// By default, performs semantic analysis to build the new statement.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningStmtResult RebuildAsmStmt(SourceLocation AsmLoc,
+                                  bool IsSimple,
+                                  bool IsVolatile,
+                                  unsigned NumOutputs,
+                                  unsigned NumInputs,
+                                  IdentifierInfo **Names,
+                                  MultiExprArg Constraints,
+                                  MultiExprArg Exprs,
+                                  ExprArg AsmString,
+                                  MultiExprArg Clobbers,
+                                  SourceLocation RParenLoc,
+                                  bool MSAsm) {
+    return getSema().ActOnAsmStmt(AsmLoc, IsSimple, IsVolatile, NumOutputs, 
+                                  NumInputs, Names, move(Constraints),
+                                  move(Exprs), move(AsmString), move(Clobbers),
+                                  RParenLoc, MSAsm);
+  }
+
+  /// \brief Build a new Objective-C @try statement.
+  ///
+  /// By default, performs semantic analysis to build the new statement.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningStmtResult RebuildObjCAtTryStmt(SourceLocation AtLoc,
+                                        StmtArg TryBody,
+                                        MultiStmtArg CatchStmts,
+                                        StmtArg Finally) {
+    return getSema().ActOnObjCAtTryStmt(AtLoc, move(TryBody), move(CatchStmts),
+                                        move(Finally));
+  }
+
+  /// \brief Rebuild an Objective-C exception declaration.
+  ///
+  /// By default, performs semantic analysis to build the new declaration.
+  /// Subclasses may override this routine to provide different behavior.
+  VarDecl *RebuildObjCExceptionDecl(VarDecl *ExceptionDecl,
+                                    TypeSourceInfo *TInfo, QualType T) {
+    return getSema().BuildObjCExceptionDecl(TInfo, T, 
+                                            ExceptionDecl->getIdentifier(), 
+                                            ExceptionDecl->getLocation());
+  }
+  
+  /// \brief Build a new Objective-C @catch statement.
+  ///
+  /// By default, performs semantic analysis to build the new statement.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningStmtResult RebuildObjCAtCatchStmt(SourceLocation AtLoc,
+                                          SourceLocation RParenLoc,
+                                          VarDecl *Var,
+                                          StmtArg Body) {
+    return getSema().ActOnObjCAtCatchStmt(AtLoc, RParenLoc,
+                                          Sema::DeclPtrTy::make(Var),
+                                          move(Body));
+  }
+  
+  /// \brief Build a new Objective-C @finally statement.
+  ///
+  /// By default, performs semantic analysis to build the new statement.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningStmtResult RebuildObjCAtFinallyStmt(SourceLocation AtLoc,
+                                            StmtArg Body) {
+    return getSema().ActOnObjCAtFinallyStmt(AtLoc, move(Body));
+  }
+  
+  /// \brief Build a new Objective-C @throw statement.
+  ///
+  /// By default, performs semantic analysis to build the new statement.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningStmtResult RebuildObjCAtThrowStmt(SourceLocation AtLoc,
+                                          ExprArg Operand) {
+    return getSema().BuildObjCAtThrowStmt(AtLoc, move(Operand));
+  }
+  
+  /// \brief Build a new Objective-C @synchronized statement.
+  ///
+  /// By default, performs semantic analysis to build the new statement.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningStmtResult RebuildObjCAtSynchronizedStmt(SourceLocation AtLoc,
+                                                 ExprArg Object,
+                                                 StmtArg Body) {
+    return getSema().ActOnObjCAtSynchronizedStmt(AtLoc, move(Object),
+                                                 move(Body));
+  }
+
+  /// \brief Build a new Objective-C fast enumeration statement.
+  ///
+  /// By default, performs semantic analysis to build the new statement.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningStmtResult RebuildObjCForCollectionStmt(SourceLocation ForLoc,
+                                                SourceLocation LParenLoc,
+                                                StmtArg Element,
+                                                ExprArg Collection,
+                                                SourceLocation RParenLoc,
+                                                StmtArg Body) {
+    return getSema().ActOnObjCForCollectionStmt(ForLoc, LParenLoc,
+                                                move(Element), 
+                                                move(Collection),
+                                                RParenLoc,
+                                                move(Body));
+  }
+  
+  /// \brief Build a new C++ exception declaration.
+  ///
+  /// By default, performs semantic analysis to build the new decaration.
+  /// Subclasses may override this routine to provide different behavior.
+  VarDecl *RebuildExceptionDecl(VarDecl *ExceptionDecl, QualType T,
+                                TypeSourceInfo *Declarator,
+                                IdentifierInfo *Name,
+                                SourceLocation Loc,
+                                SourceRange TypeRange) {
+    return getSema().BuildExceptionDeclaration(0, T, Declarator, Name, Loc,
+                                               TypeRange);
+  }
+
+  /// \brief Build a new C++ catch statement.
+  ///
+  /// By default, performs semantic analysis to build the new statement.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningStmtResult RebuildCXXCatchStmt(SourceLocation CatchLoc,
+                                       VarDecl *ExceptionDecl,
+                                       StmtArg Handler) {
+    return getSema().Owned(
+             new (getSema().Context) CXXCatchStmt(CatchLoc, ExceptionDecl,
+                                                  Handler.takeAs<Stmt>()));
+  }
+
+  /// \brief Build a new C++ try statement.
+  ///
+  /// By default, performs semantic analysis to build the new statement.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningStmtResult RebuildCXXTryStmt(SourceLocation TryLoc,
+                                     StmtArg TryBlock,
+                                     MultiStmtArg Handlers) {
+    return getSema().ActOnCXXTryBlock(TryLoc, move(TryBlock), move(Handlers));
+  }
+
+  /// \brief Build a new expression that references a declaration.
+  ///
+  /// By default, performs semantic analysis to build the new expression.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningExprResult RebuildDeclarationNameExpr(const CXXScopeSpec &SS,
+                                              LookupResult &R,
+                                              bool RequiresADL) {
+    return getSema().BuildDeclarationNameExpr(SS, R, RequiresADL);
+  }
+
+
+  /// \brief Build a new expression that references a declaration.
+  ///
+  /// By default, performs semantic analysis to build the new expression.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningExprResult RebuildDeclRefExpr(NestedNameSpecifier *Qualifier,
+                                      SourceRange QualifierRange,
+                                      ValueDecl *VD, SourceLocation Loc,
+                                      TemplateArgumentListInfo *TemplateArgs) {
+    CXXScopeSpec SS;
+    SS.setScopeRep(Qualifier);
+    SS.setRange(QualifierRange);
+
+    // FIXME: loses template args.
+    
+    return getSema().BuildDeclarationNameExpr(SS, Loc, VD);
+  }
+
+  /// \brief Build a new expression in parentheses.
+  ///
+  /// By default, performs semantic analysis to build the new expression.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningExprResult RebuildParenExpr(ExprArg SubExpr, SourceLocation LParen,
+                                    SourceLocation RParen) {
+    return getSema().ActOnParenExpr(LParen, RParen, move(SubExpr));
+  }
+
+  /// \brief Build a new pseudo-destructor expression.
+  ///
+  /// By default, performs semantic analysis to build the new expression.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningExprResult RebuildCXXPseudoDestructorExpr(ExprArg Base,
+                                                  SourceLocation OperatorLoc,
+                                                  bool isArrow,
+                                                NestedNameSpecifier *Qualifier,
+                                                  SourceRange QualifierRange,
+                                                  TypeSourceInfo *ScopeType,
+                                                  SourceLocation CCLoc,
+                                                  SourceLocation TildeLoc,
+                                        PseudoDestructorTypeStorage Destroyed);
+
+  /// \brief Build a new unary operator expression.
+  ///
+  /// By default, performs semantic analysis to build the new expression.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningExprResult RebuildUnaryOperator(SourceLocation OpLoc,
+                                        UnaryOperator::Opcode Opc,
+                                        ExprArg SubExpr) {
+    return getSema().BuildUnaryOp(/*Scope=*/0, OpLoc, Opc, move(SubExpr));
+  }
+
+  /// \brief Build a new sizeof or alignof expression with a type argument.
+  ///
+  /// By default, performs semantic analysis to build the new expression.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningExprResult RebuildSizeOfAlignOf(TypeSourceInfo *TInfo,
+                                        SourceLocation OpLoc,
+                                        bool isSizeOf, SourceRange R) {
+    return getSema().CreateSizeOfAlignOfExpr(TInfo, OpLoc, isSizeOf, R);
+  }
+
+  /// \brief Build a new sizeof or alignof expression with an expression
+  /// argument.
+  ///
+  /// By default, performs semantic analysis to build the new expression.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningExprResult RebuildSizeOfAlignOf(ExprArg SubExpr, SourceLocation OpLoc,
+                                        bool isSizeOf, SourceRange R) {
+    OwningExprResult Result
+      = getSema().CreateSizeOfAlignOfExpr((Expr *)SubExpr.get(),
+                                          OpLoc, isSizeOf, R);
+    if (Result.isInvalid())
+      return getSema().ExprError();
+
+    SubExpr.release();
+    return move(Result);
+  }
+
+  /// \brief Build a new array subscript expression.
+  ///
+  /// By default, performs semantic analysis to build the new expression.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningExprResult RebuildArraySubscriptExpr(ExprArg LHS,
+                                             SourceLocation LBracketLoc,
+                                             ExprArg RHS,
+                                             SourceLocation RBracketLoc) {
+    return getSema().ActOnArraySubscriptExpr(/*Scope=*/0, move(LHS),
+                                             LBracketLoc, move(RHS),
+                                             RBracketLoc);
+  }
+
+  /// \brief Build a new call expression.
+  ///
+  /// By default, performs semantic analysis to build the new expression.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningExprResult RebuildCallExpr(ExprArg Callee, SourceLocation LParenLoc,
+                                   MultiExprArg Args,
+                                   SourceLocation *CommaLocs,
+                                   SourceLocation RParenLoc) {
+    return getSema().ActOnCallExpr(/*Scope=*/0, move(Callee), LParenLoc,
+                                   move(Args), CommaLocs, RParenLoc);
+  }
+
+  /// \brief Build a new member access expression.
+  ///
+  /// By default, performs semantic analysis to build the new expression.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningExprResult RebuildMemberExpr(ExprArg Base, SourceLocation OpLoc,
+                                     bool isArrow,
+                                     NestedNameSpecifier *Qualifier,
+                                     SourceRange QualifierRange,
+                                     SourceLocation MemberLoc,
+                                     ValueDecl *Member,
+                                     NamedDecl *FoundDecl,
+                        const TemplateArgumentListInfo *ExplicitTemplateArgs,
+                                     NamedDecl *FirstQualifierInScope) {
+    if (!Member->getDeclName()) {
+      // We have a reference to an unnamed field.
+      assert(!Qualifier && "Can't have an unnamed field with a qualifier!");
+
+      Expr *BaseExpr = Base.takeAs<Expr>();
+      if (getSema().PerformObjectMemberConversion(BaseExpr, Qualifier,
+                                                  FoundDecl, Member))
+        return getSema().ExprError();
+
+      MemberExpr *ME =
+        new (getSema().Context) MemberExpr(BaseExpr, isArrow,
+                                           Member, MemberLoc,
+                                           cast<FieldDecl>(Member)->getType());
+      return getSema().Owned(ME);
+    }
+
+    CXXScopeSpec SS;
+    if (Qualifier) {
+      SS.setRange(QualifierRange);
+      SS.setScopeRep(Qualifier);
+    }
+
+    QualType BaseType = ((Expr*) Base.get())->getType();
+
+    // FIXME: this involves duplicating earlier analysis in a lot of
+    // cases; we should avoid this when possible.
+    LookupResult R(getSema(), Member->getDeclName(), MemberLoc,
+                   Sema::LookupMemberName);
+    R.addDecl(FoundDecl);
+    R.resolveKind();
+
+    return getSema().BuildMemberReferenceExpr(move(Base), BaseType,
+                                              OpLoc, isArrow,
+                                              SS, FirstQualifierInScope,
+                                              R, ExplicitTemplateArgs);
+  }
+
+  /// \brief Build a new binary operator expression.
+  ///
+  /// By default, performs semantic analysis to build the new expression.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningExprResult RebuildBinaryOperator(SourceLocation OpLoc,
+                                         BinaryOperator::Opcode Opc,
+                                         ExprArg LHS, ExprArg RHS) {
+    return getSema().BuildBinOp(/*Scope=*/0, OpLoc, Opc, 
+                                LHS.takeAs<Expr>(), RHS.takeAs<Expr>());
+  }
+
+  /// \brief Build a new conditional operator expression.
+  ///
+  /// By default, performs semantic analysis to build the new expression.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningExprResult RebuildConditionalOperator(ExprArg Cond,
+                                              SourceLocation QuestionLoc,
+                                              ExprArg LHS,
+                                              SourceLocation ColonLoc,
+                                              ExprArg RHS) {
+    return getSema().ActOnConditionalOp(QuestionLoc, ColonLoc, move(Cond),
+                                        move(LHS), move(RHS));
+  }
+
+  /// \brief Build a new C-style cast expression.
+  ///
+  /// By default, performs semantic analysis to build the new expression.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningExprResult RebuildCStyleCastExpr(SourceLocation LParenLoc,
+                                         TypeSourceInfo *TInfo,
+                                         SourceLocation RParenLoc,
+                                         ExprArg SubExpr) {
+    return getSema().BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc,
+                                         move(SubExpr));
+  }
+
+  /// \brief Build a new compound literal expression.
+  ///
+  /// By default, performs semantic analysis to build the new expression.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningExprResult RebuildCompoundLiteralExpr(SourceLocation LParenLoc,
+                                              TypeSourceInfo *TInfo,
+                                              SourceLocation RParenLoc,
+                                              ExprArg Init) {
+    return getSema().BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc,
+                                              move(Init));
+  }
+
+  /// \brief Build a new extended vector element access expression.
+  ///
+  /// By default, performs semantic analysis to build the new expression.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningExprResult RebuildExtVectorElementExpr(ExprArg Base,
+                                               SourceLocation OpLoc,
+                                               SourceLocation AccessorLoc,
+                                               IdentifierInfo &Accessor) {
+
+    CXXScopeSpec SS;
+    QualType BaseType = ((Expr*) Base.get())->getType();
+    return getSema().BuildMemberReferenceExpr(move(Base), BaseType,
+                                              OpLoc, /*IsArrow*/ false,
+                                              SS, /*FirstQualifierInScope*/ 0,
+                                              DeclarationName(&Accessor),
+                                              AccessorLoc,
+                                              /* TemplateArgs */ 0);
+  }
+
+  /// \brief Build a new initializer list expression.
+  ///
+  /// By default, performs semantic analysis to build the new expression.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningExprResult RebuildInitList(SourceLocation LBraceLoc,
+                                   MultiExprArg Inits,
+                                   SourceLocation RBraceLoc,
+                                   QualType ResultTy) {
+    OwningExprResult Result
+      = SemaRef.ActOnInitList(LBraceLoc, move(Inits), RBraceLoc);
+    if (Result.isInvalid() || ResultTy->isDependentType())
+      return move(Result);
+    
+    // Patch in the result type we were given, which may have been computed
+    // when the initial InitListExpr was built.
+    InitListExpr *ILE = cast<InitListExpr>((Expr *)Result.get());
+    ILE->setType(ResultTy);
+    return move(Result);
+  }
+
+  /// \brief Build a new designated initializer expression.
+  ///
+  /// By default, performs semantic analysis to build the new expression.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningExprResult RebuildDesignatedInitExpr(Designation &Desig,
+                                             MultiExprArg ArrayExprs,
+                                             SourceLocation EqualOrColonLoc,
+                                             bool GNUSyntax,
+                                             ExprArg Init) {
+    OwningExprResult Result
+      = SemaRef.ActOnDesignatedInitializer(Desig, EqualOrColonLoc, GNUSyntax,
+                                           move(Init));
+    if (Result.isInvalid())
+      return SemaRef.ExprError();
+
+    ArrayExprs.release();
+    return move(Result);
+  }
+
+  /// \brief Build a new value-initialized expression.
+  ///
+  /// By default, builds the implicit value initialization without performing
+  /// any semantic analysis. Subclasses may override this routine to provide
+  /// different behavior.
+  OwningExprResult RebuildImplicitValueInitExpr(QualType T) {
+    return SemaRef.Owned(new (SemaRef.Context) ImplicitValueInitExpr(T));
+  }
+
+  /// \brief Build a new \c va_arg expression.
+  ///
+  /// By default, performs semantic analysis to build the new expression.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningExprResult RebuildVAArgExpr(SourceLocation BuiltinLoc, ExprArg SubExpr,
+                                    QualType T, SourceLocation RParenLoc) {
+    return getSema().ActOnVAArg(BuiltinLoc, move(SubExpr), T.getAsOpaquePtr(),
+                                RParenLoc);
+  }
+
+  /// \brief Build a new expression list in parentheses.
+  ///
+  /// By default, performs semantic analysis to build the new expression.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningExprResult RebuildParenListExpr(SourceLocation LParenLoc,
+                                        MultiExprArg SubExprs,
+                                        SourceLocation RParenLoc) {
+    return getSema().ActOnParenOrParenListExpr(LParenLoc, RParenLoc, 
+                                               move(SubExprs));
+  }
+
+  /// \brief Build a new address-of-label expression.
+  ///
+  /// By default, performs semantic analysis, using the name of the label
+  /// rather than attempting to map the label statement itself.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningExprResult RebuildAddrLabelExpr(SourceLocation AmpAmpLoc,
+                                        SourceLocation LabelLoc,
+                                        LabelStmt *Label) {
+    return getSema().ActOnAddrLabel(AmpAmpLoc, LabelLoc, Label->getID());
+  }
+
+  /// \brief Build a new GNU statement expression.
+  ///
+  /// By default, performs semantic analysis to build the new expression.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningExprResult RebuildStmtExpr(SourceLocation LParenLoc,
+                                   StmtArg SubStmt,
+                                   SourceLocation RParenLoc) {
+    return getSema().ActOnStmtExpr(LParenLoc, move(SubStmt), RParenLoc);
+  }
+
+  /// \brief Build a new __builtin_types_compatible_p expression.
+  ///
+  /// By default, performs semantic analysis to build the new expression.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningExprResult RebuildTypesCompatibleExpr(SourceLocation BuiltinLoc,
+                                              QualType T1, QualType T2,
+                                              SourceLocation RParenLoc) {
+    return getSema().ActOnTypesCompatibleExpr(BuiltinLoc,
+                                              T1.getAsOpaquePtr(),
+                                              T2.getAsOpaquePtr(),
+                                              RParenLoc);
+  }
+
+  /// \brief Build a new __builtin_choose_expr expression.
+  ///
+  /// By default, performs semantic analysis to build the new expression.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningExprResult RebuildChooseExpr(SourceLocation BuiltinLoc,
+                                     ExprArg Cond, ExprArg LHS, ExprArg RHS,
+                                     SourceLocation RParenLoc) {
+    return SemaRef.ActOnChooseExpr(BuiltinLoc,
+                                   move(Cond), move(LHS), move(RHS),
+                                   RParenLoc);
+  }
+
+  /// \brief Build a new overloaded operator call expression.
+  ///
+  /// By default, performs semantic analysis to build the new expression.
+  /// The semantic analysis provides the behavior of template instantiation,
+  /// copying with transformations that turn what looks like an overloaded
+  /// operator call into a use of a builtin operator, performing
+  /// argument-dependent lookup, etc. Subclasses may override this routine to
+  /// provide different behavior.
+  OwningExprResult RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
+                                              SourceLocation OpLoc,
+                                              ExprArg Callee,
+                                              ExprArg First,
+                                              ExprArg Second);
+
+  /// \brief Build a new C++ "named" cast expression, such as static_cast or
+  /// reinterpret_cast.
+  ///
+  /// By default, this routine dispatches to one of the more-specific routines
+  /// for a particular named case, e.g., RebuildCXXStaticCastExpr().
+  /// Subclasses may override this routine to provide different behavior.
+  OwningExprResult RebuildCXXNamedCastExpr(SourceLocation OpLoc,
+                                           Stmt::StmtClass Class,
+                                           SourceLocation LAngleLoc,
+                                           TypeSourceInfo *TInfo,
+                                           SourceLocation RAngleLoc,
+                                           SourceLocation LParenLoc,
+                                           ExprArg SubExpr,
+                                           SourceLocation RParenLoc) {
+    switch (Class) {
+    case Stmt::CXXStaticCastExprClass:
+      return getDerived().RebuildCXXStaticCastExpr(OpLoc, LAngleLoc, TInfo,
+                                                   RAngleLoc, LParenLoc,
+                                                   move(SubExpr), RParenLoc);
+
+    case Stmt::CXXDynamicCastExprClass:
+      return getDerived().RebuildCXXDynamicCastExpr(OpLoc, LAngleLoc, TInfo,
+                                                    RAngleLoc, LParenLoc,
+                                                    move(SubExpr), RParenLoc);
+
+    case Stmt::CXXReinterpretCastExprClass:
+      return getDerived().RebuildCXXReinterpretCastExpr(OpLoc, LAngleLoc, TInfo,
+                                                        RAngleLoc, LParenLoc,
+                                                        move(SubExpr),
+                                                        RParenLoc);
+
+    case Stmt::CXXConstCastExprClass:
+      return getDerived().RebuildCXXConstCastExpr(OpLoc, LAngleLoc, TInfo,
+                                                   RAngleLoc, LParenLoc,
+                                                   move(SubExpr), RParenLoc);
+
+    default:
+      assert(false && "Invalid C++ named cast");
+      break;
+    }
+
+    return getSema().ExprError();
+  }
+
+  /// \brief Build a new C++ static_cast expression.
+  ///
+  /// By default, performs semantic analysis to build the new expression.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningExprResult RebuildCXXStaticCastExpr(SourceLocation OpLoc,
+                                            SourceLocation LAngleLoc,
+                                            TypeSourceInfo *TInfo,
+                                            SourceLocation RAngleLoc,
+                                            SourceLocation LParenLoc,
+                                            ExprArg SubExpr,
+                                            SourceLocation RParenLoc) {
+    return getSema().BuildCXXNamedCast(OpLoc, tok::kw_static_cast,
+                                       TInfo, move(SubExpr),
+                                       SourceRange(LAngleLoc, RAngleLoc),
+                                       SourceRange(LParenLoc, RParenLoc));
+  }
+
+  /// \brief Build a new C++ dynamic_cast expression.
+  ///
+  /// By default, performs semantic analysis to build the new expression.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningExprResult RebuildCXXDynamicCastExpr(SourceLocation OpLoc,
+                                             SourceLocation LAngleLoc,
+                                             TypeSourceInfo *TInfo,
+                                             SourceLocation RAngleLoc,
+                                             SourceLocation LParenLoc,
+                                             ExprArg SubExpr,
+                                             SourceLocation RParenLoc) {
+    return getSema().BuildCXXNamedCast(OpLoc, tok::kw_dynamic_cast,
+                                       TInfo, move(SubExpr),
+                                       SourceRange(LAngleLoc, RAngleLoc),
+                                       SourceRange(LParenLoc, RParenLoc));
+  }
+
+  /// \brief Build a new C++ reinterpret_cast expression.
+  ///
+  /// By default, performs semantic analysis to build the new expression.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningExprResult RebuildCXXReinterpretCastExpr(SourceLocation OpLoc,
+                                                 SourceLocation LAngleLoc,
+                                                 TypeSourceInfo *TInfo,
+                                                 SourceLocation RAngleLoc,
+                                                 SourceLocation LParenLoc,
+                                                 ExprArg SubExpr,
+                                                 SourceLocation RParenLoc) {
+    return getSema().BuildCXXNamedCast(OpLoc, tok::kw_reinterpret_cast,
+                                       TInfo, move(SubExpr),
+                                       SourceRange(LAngleLoc, RAngleLoc),
+                                       SourceRange(LParenLoc, RParenLoc));
+  }
+
+  /// \brief Build a new C++ const_cast expression.
+  ///
+  /// By default, performs semantic analysis to build the new expression.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningExprResult RebuildCXXConstCastExpr(SourceLocation OpLoc,
+                                           SourceLocation LAngleLoc,
+                                           TypeSourceInfo *TInfo,
+                                           SourceLocation RAngleLoc,
+                                           SourceLocation LParenLoc,
+                                           ExprArg SubExpr,
+                                           SourceLocation RParenLoc) {
+    return getSema().BuildCXXNamedCast(OpLoc, tok::kw_const_cast,
+                                       TInfo, move(SubExpr),
+                                       SourceRange(LAngleLoc, RAngleLoc),
+                                       SourceRange(LParenLoc, RParenLoc));
+  }
+
+  /// \brief Build a new C++ functional-style cast expression.
+  ///
+  /// By default, performs semantic analysis to build the new expression.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningExprResult RebuildCXXFunctionalCastExpr(SourceRange TypeRange,
+                                                TypeSourceInfo *TInfo,
+                                                SourceLocation LParenLoc,
+                                                ExprArg SubExpr,
+                                                SourceLocation RParenLoc) {
+    void *Sub = SubExpr.takeAs<Expr>();
+    return getSema().ActOnCXXTypeConstructExpr(TypeRange,
+                                               TInfo->getType().getAsOpaquePtr(),
+                                               LParenLoc,
+                                         Sema::MultiExprArg(getSema(), &Sub, 1),
+                                               /*CommaLocs=*/0,
+                                               RParenLoc);
+  }
+
+  /// \brief Build a new C++ typeid(type) expression.
+  ///
+  /// By default, performs semantic analysis to build the new expression.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningExprResult RebuildCXXTypeidExpr(QualType TypeInfoType,
+                                        SourceLocation TypeidLoc,
+                                        TypeSourceInfo *Operand,
+                                        SourceLocation RParenLoc) {
+    return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand, 
+                                    RParenLoc);
+  }
+
+  /// \brief Build a new C++ typeid(expr) expression.
+  ///
+  /// By default, performs semantic analysis to build the new expression.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningExprResult RebuildCXXTypeidExpr(QualType TypeInfoType,
+                                        SourceLocation TypeidLoc,
+                                        ExprArg Operand,
+                                        SourceLocation RParenLoc) {
+    return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, move(Operand),
+                                    RParenLoc);
+  }
+
+  /// \brief Build a new C++ "this" expression.
+  ///
+  /// By default, builds a new "this" expression without performing any
+  /// semantic analysis. Subclasses may override this routine to provide
+  /// different behavior.
+  OwningExprResult RebuildCXXThisExpr(SourceLocation ThisLoc,
+                                      QualType ThisType,
+                                      bool isImplicit) {
+    return getSema().Owned(
+                      new (getSema().Context) CXXThisExpr(ThisLoc, ThisType,
+                                                          isImplicit));
+  }
+
+  /// \brief Build a new C++ throw expression.
+  ///
+  /// By default, performs semantic analysis to build the new expression.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningExprResult RebuildCXXThrowExpr(SourceLocation ThrowLoc, ExprArg Sub) {
+    return getSema().ActOnCXXThrow(ThrowLoc, move(Sub));
+  }
+
+  /// \brief Build a new C++ default-argument expression.
+  ///
+  /// By default, builds a new default-argument expression, which does not
+  /// require any semantic analysis. Subclasses may override this routine to
+  /// provide different behavior.
+  OwningExprResult RebuildCXXDefaultArgExpr(SourceLocation Loc, 
+                                            ParmVarDecl *Param) {
+    return getSema().Owned(CXXDefaultArgExpr::Create(getSema().Context, Loc,
+                                                     Param));
+  }
+
+  /// \brief Build a new C++ zero-initialization expression.
+  ///
+  /// By default, performs semantic analysis to build the new expression.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningExprResult RebuildCXXZeroInitValueExpr(SourceLocation TypeStartLoc,
+                                               SourceLocation LParenLoc,
+                                               QualType T,
+                                               SourceLocation RParenLoc) {
+    return getSema().ActOnCXXTypeConstructExpr(SourceRange(TypeStartLoc),
+                                               T.getAsOpaquePtr(), LParenLoc,
+                                               MultiExprArg(getSema(), 0, 0),
+                                               0, RParenLoc);
+  }
+
+  /// \brief Build a new C++ "new" expression.
+  ///
+  /// By default, performs semantic analysis to build the new expression.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningExprResult RebuildCXXNewExpr(SourceLocation StartLoc,
+                                     bool UseGlobal,
+                                     SourceLocation PlacementLParen,
+                                     MultiExprArg PlacementArgs,
+                                     SourceLocation PlacementRParen,
+                                     bool ParenTypeId,
+                                     QualType AllocType,
+                                     SourceLocation TypeLoc,
+                                     SourceRange TypeRange,
+                                     ExprArg ArraySize,
+                                     SourceLocation ConstructorLParen,
+                                     MultiExprArg ConstructorArgs,
+                                     SourceLocation ConstructorRParen) {
+    return getSema().BuildCXXNew(StartLoc, UseGlobal,
+                                 PlacementLParen,
+                                 move(PlacementArgs),
+                                 PlacementRParen,
+                                 ParenTypeId,
+                                 AllocType,
+                                 TypeLoc,
+                                 TypeRange,
+                                 move(ArraySize),
+                                 ConstructorLParen,
+                                 move(ConstructorArgs),
+                                 ConstructorRParen);
+  }
+
+  /// \brief Build a new C++ "delete" expression.
+  ///
+  /// By default, performs semantic analysis to build the new expression.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningExprResult RebuildCXXDeleteExpr(SourceLocation StartLoc,
+                                        bool IsGlobalDelete,
+                                        bool IsArrayForm,
+                                        ExprArg Operand) {
+    return getSema().ActOnCXXDelete(StartLoc, IsGlobalDelete, IsArrayForm,
+                                    move(Operand));
+  }
+
+  /// \brief Build a new unary type trait expression.
+  ///
+  /// By default, performs semantic analysis to build the new expression.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningExprResult RebuildUnaryTypeTrait(UnaryTypeTrait Trait,
+                                         SourceLocation StartLoc,
+                                         SourceLocation LParenLoc,
+                                         QualType T,
+                                         SourceLocation RParenLoc) {
+    return getSema().ActOnUnaryTypeTrait(Trait, StartLoc, LParenLoc,
+                                         T.getAsOpaquePtr(), RParenLoc);
+  }
+
+  /// \brief Build a new (previously unresolved) declaration reference
+  /// expression.
+  ///
+  /// By default, performs semantic analysis to build the new expression.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningExprResult RebuildDependentScopeDeclRefExpr(NestedNameSpecifier *NNS,
+                                                SourceRange QualifierRange,
+                                                DeclarationName Name,
+                                                SourceLocation Location,
+                              const TemplateArgumentListInfo *TemplateArgs) {
+    CXXScopeSpec SS;
+    SS.setRange(QualifierRange);
+    SS.setScopeRep(NNS);
+
+    if (TemplateArgs)
+      return getSema().BuildQualifiedTemplateIdExpr(SS, Name, Location,
+                                                    *TemplateArgs);
+
+    return getSema().BuildQualifiedDeclarationNameExpr(SS, Name, Location);
+  }
+
+  /// \brief Build a new template-id expression.
+  ///
+  /// By default, performs semantic analysis to build the new expression.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningExprResult RebuildTemplateIdExpr(const CXXScopeSpec &SS,
+                                         LookupResult &R,
+                                         bool RequiresADL,
+                              const TemplateArgumentListInfo &TemplateArgs) {
+    return getSema().BuildTemplateIdExpr(SS, R, RequiresADL, TemplateArgs);
+  }
+
+  /// \brief Build a new object-construction expression.
+  ///
+  /// By default, performs semantic analysis to build the new expression.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningExprResult RebuildCXXConstructExpr(QualType T,
+                                           SourceLocation Loc,
+                                           CXXConstructorDecl *Constructor,
+                                           bool IsElidable,
+                                           MultiExprArg Args) {
+    ASTOwningVector<&ActionBase::DeleteExpr> ConvertedArgs(SemaRef);
+    if (getSema().CompleteConstructorCall(Constructor, move(Args), Loc, 
+                                          ConvertedArgs))
+      return getSema().ExprError();
+    
+    return getSema().BuildCXXConstructExpr(Loc, T, Constructor, IsElidable,
+                                           move_arg(ConvertedArgs));
+  }
+
+  /// \brief Build a new object-construction expression.
+  ///
+  /// By default, performs semantic analysis to build the new expression.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningExprResult RebuildCXXTemporaryObjectExpr(SourceLocation TypeBeginLoc,
+                                                 QualType T,
+                                                 SourceLocation LParenLoc,
+                                                 MultiExprArg Args,
+                                                 SourceLocation *Commas,
+                                                 SourceLocation RParenLoc) {
+    return getSema().ActOnCXXTypeConstructExpr(SourceRange(TypeBeginLoc),
+                                               T.getAsOpaquePtr(),
+                                               LParenLoc,
+                                               move(Args),
+                                               Commas,
+                                               RParenLoc);
+  }
+
+  /// \brief Build a new object-construction expression.
+  ///
+  /// By default, performs semantic analysis to build the new expression.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningExprResult RebuildCXXUnresolvedConstructExpr(SourceLocation TypeBeginLoc,
+                                                     QualType T,
+                                                     SourceLocation LParenLoc,
+                                                     MultiExprArg Args,
+                                                     SourceLocation *Commas,
+                                                     SourceLocation RParenLoc) {
+    return getSema().ActOnCXXTypeConstructExpr(SourceRange(TypeBeginLoc,
+                                                           /*FIXME*/LParenLoc),
+                                               T.getAsOpaquePtr(),
+                                               LParenLoc,
+                                               move(Args),
+                                               Commas,
+                                               RParenLoc);
+  }
+
+  /// \brief Build a new member reference expression.
+  ///
+  /// By default, performs semantic analysis to build the new expression.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningExprResult RebuildCXXDependentScopeMemberExpr(ExprArg BaseE,
+                                                  QualType BaseType,
+                                                  bool IsArrow,
+                                                  SourceLocation OperatorLoc,
+                                              NestedNameSpecifier *Qualifier,
+                                                  SourceRange QualifierRange,
+                                            NamedDecl *FirstQualifierInScope,
+                                                  DeclarationName Name,
+                                                  SourceLocation MemberLoc,
+                              const TemplateArgumentListInfo *TemplateArgs) {
+    CXXScopeSpec SS;
+    SS.setRange(QualifierRange);
+    SS.setScopeRep(Qualifier);
+
+    return SemaRef.BuildMemberReferenceExpr(move(BaseE), BaseType,
+                                            OperatorLoc, IsArrow,
+                                            SS, FirstQualifierInScope,
+                                            Name, MemberLoc, TemplateArgs);
+  }
+
+  /// \brief Build a new member reference expression.
+  ///
+  /// By default, performs semantic analysis to build the new expression.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningExprResult RebuildUnresolvedMemberExpr(ExprArg BaseE,
+                                               QualType BaseType,
+                                               SourceLocation OperatorLoc,
+                                               bool IsArrow,
+                                               NestedNameSpecifier *Qualifier,
+                                               SourceRange QualifierRange,
+                                               NamedDecl *FirstQualifierInScope,
+                                               LookupResult &R,
+                                const TemplateArgumentListInfo *TemplateArgs) {
+    CXXScopeSpec SS;
+    SS.setRange(QualifierRange);
+    SS.setScopeRep(Qualifier);
+
+    return SemaRef.BuildMemberReferenceExpr(move(BaseE), BaseType,
+                                            OperatorLoc, IsArrow,
+                                            SS, FirstQualifierInScope,
+                                            R, TemplateArgs);
+  }
+
+  /// \brief Build a new Objective-C @encode expression.
+  ///
+  /// By default, performs semantic analysis to build the new expression.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningExprResult RebuildObjCEncodeExpr(SourceLocation AtLoc,
+                                         TypeSourceInfo *EncodeTypeInfo,
+                                         SourceLocation RParenLoc) {
+    return SemaRef.Owned(SemaRef.BuildObjCEncodeExpression(AtLoc, EncodeTypeInfo,
+                                                           RParenLoc));
+  }
+
+  /// \brief Build a new Objective-C class message.
+  OwningExprResult RebuildObjCMessageExpr(TypeSourceInfo *ReceiverTypeInfo,
+                                          Selector Sel,
+                                          ObjCMethodDecl *Method,
+                                          SourceLocation LBracLoc, 
+                                          MultiExprArg Args,
+                                          SourceLocation RBracLoc) {
+    return SemaRef.BuildClassMessage(ReceiverTypeInfo,
+                                     ReceiverTypeInfo->getType(),
+                                     /*SuperLoc=*/SourceLocation(),
+                                     Sel, Method, LBracLoc, RBracLoc,
+                                     move(Args));
+  }
+
+  /// \brief Build a new Objective-C instance message.
+  OwningExprResult RebuildObjCMessageExpr(ExprArg Receiver,
+                                          Selector Sel,
+                                          ObjCMethodDecl *Method,
+                                          SourceLocation LBracLoc, 
+                                          MultiExprArg Args,
+                                          SourceLocation RBracLoc) {
+    QualType ReceiverType = static_cast<Expr *>(Receiver.get())->getType();
+    return SemaRef.BuildInstanceMessage(move(Receiver),
+                                        ReceiverType,
+                                        /*SuperLoc=*/SourceLocation(),
+                                        Sel, Method, LBracLoc, RBracLoc,
+                                        move(Args));
+  }
+
+  /// \brief Build a new Objective-C ivar reference expression.
+  ///
+  /// By default, performs semantic analysis to build the new expression.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningExprResult RebuildObjCIvarRefExpr(ExprArg BaseArg, ObjCIvarDecl *Ivar,
+                                          SourceLocation IvarLoc,
+                                          bool IsArrow, bool IsFreeIvar) {
+    // FIXME: We lose track of the IsFreeIvar bit.
+    CXXScopeSpec SS;
+    Expr *Base = BaseArg.takeAs<Expr>();
+    LookupResult R(getSema(), Ivar->getDeclName(), IvarLoc,
+                   Sema::LookupMemberName);
+    OwningExprResult Result = getSema().LookupMemberExpr(R, Base, IsArrow,
+                                                         /*FIME:*/IvarLoc,
+                                                         SS, DeclPtrTy());
+    if (Result.isInvalid())
+      return getSema().ExprError();
+    
+    if (Result.get())
+      return move(Result);
+    
+    return getSema().BuildMemberReferenceExpr(getSema().Owned(Base), 
+                                              Base->getType(),
+                                              /*FIXME:*/IvarLoc, IsArrow, SS, 
+                                              /*FirstQualifierInScope=*/0,
+                                              R, 
+                                              /*TemplateArgs=*/0);
+  }
+
+  /// \brief Build a new Objective-C property reference expression.
+  ///
+  /// By default, performs semantic analysis to build the new expression.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningExprResult RebuildObjCPropertyRefExpr(ExprArg BaseArg, 
+                                              ObjCPropertyDecl *Property,
+                                              SourceLocation PropertyLoc) {
+    CXXScopeSpec SS;
+    Expr *Base = BaseArg.takeAs<Expr>();
+    LookupResult R(getSema(), Property->getDeclName(), PropertyLoc,
+                   Sema::LookupMemberName);
+    bool IsArrow = false;
+    OwningExprResult Result = getSema().LookupMemberExpr(R, Base, IsArrow,
+                                                         /*FIME:*/PropertyLoc,
+                                                         SS, DeclPtrTy());
+    if (Result.isInvalid())
+      return getSema().ExprError();
+    
+    if (Result.get())
+      return move(Result);
+    
+    return getSema().BuildMemberReferenceExpr(getSema().Owned(Base), 
+                                              Base->getType(),
+                                              /*FIXME:*/PropertyLoc, IsArrow, 
+                                              SS, 
+                                              /*FirstQualifierInScope=*/0,
+                                              R, 
+                                              /*TemplateArgs=*/0);
+  }
+  
+  /// \brief Build a new Objective-C implicit setter/getter reference 
+  /// expression.
+  ///
+  /// By default, performs semantic analysis to build the new expression.
+  /// Subclasses may override this routine to provide different behavior.  
+  OwningExprResult RebuildObjCImplicitSetterGetterRefExpr(
+                                                        ObjCMethodDecl *Getter,
+                                                          QualType T,
+                                                        ObjCMethodDecl *Setter,
+                                                        SourceLocation NameLoc,
+                                                          ExprArg Base) {
+    // Since these expressions can only be value-dependent, we do not need to
+    // perform semantic analysis again.
+    return getSema().Owned(
+             new (getSema().Context) ObjCImplicitSetterGetterRefExpr(Getter, T,
+                                                                     Setter,
+                                                                     NameLoc,
+                                                          Base.takeAs<Expr>()));
+  }
+
+  /// \brief Build a new Objective-C "isa" expression.
+  ///
+  /// By default, performs semantic analysis to build the new expression.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningExprResult RebuildObjCIsaExpr(ExprArg BaseArg, SourceLocation IsaLoc,
+                                      bool IsArrow) {
+    CXXScopeSpec SS;
+    Expr *Base = BaseArg.takeAs<Expr>();
+    LookupResult R(getSema(), &getSema().Context.Idents.get("isa"), IsaLoc,
+                   Sema::LookupMemberName);
+    OwningExprResult Result = getSema().LookupMemberExpr(R, Base, IsArrow,
+                                                         /*FIME:*/IsaLoc,
+                                                         SS, DeclPtrTy());
+    if (Result.isInvalid())
+      return getSema().ExprError();
+    
+    if (Result.get())
+      return move(Result);
+    
+    return getSema().BuildMemberReferenceExpr(getSema().Owned(Base), 
+                                              Base->getType(),
+                                              /*FIXME:*/IsaLoc, IsArrow, SS, 
+                                              /*FirstQualifierInScope=*/0,
+                                              R, 
+                                              /*TemplateArgs=*/0);
+  }
+  
+  /// \brief Build a new shuffle vector expression.
+  ///
+  /// By default, performs semantic analysis to build the new expression.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningExprResult RebuildShuffleVectorExpr(SourceLocation BuiltinLoc,
+                                            MultiExprArg SubExprs,
+                                            SourceLocation RParenLoc) {
+    // Find the declaration for __builtin_shufflevector
+    const IdentifierInfo &Name
+      = SemaRef.Context.Idents.get("__builtin_shufflevector");
+    TranslationUnitDecl *TUDecl = SemaRef.Context.getTranslationUnitDecl();
+    DeclContext::lookup_result Lookup = TUDecl->lookup(DeclarationName(&Name));
+    assert(Lookup.first != Lookup.second && "No __builtin_shufflevector?");
+
+    // Build a reference to the __builtin_shufflevector builtin
+    FunctionDecl *Builtin = cast<FunctionDecl>(*Lookup.first);
+    Expr *Callee
+      = new (SemaRef.Context) DeclRefExpr(Builtin, Builtin->getType(),
+                                          BuiltinLoc);
+    SemaRef.UsualUnaryConversions(Callee);
+
+    // Build the CallExpr
+    unsigned NumSubExprs = SubExprs.size();
+    Expr **Subs = (Expr **)SubExprs.release();
+    CallExpr *TheCall = new (SemaRef.Context) CallExpr(SemaRef.Context, Callee,
+                                                       Subs, NumSubExprs,
+                                                       Builtin->getResultType(),
+                                                       RParenLoc);
+    OwningExprResult OwnedCall(SemaRef.Owned(TheCall));
+
+    // Type-check the __builtin_shufflevector expression.
+    OwningExprResult Result = SemaRef.SemaBuiltinShuffleVector(TheCall);
+    if (Result.isInvalid())
+      return SemaRef.ExprError();
+
+    OwnedCall.release();
+    return move(Result);
+  }
+};
+
+template<typename Derived>
+Sema::OwningStmtResult TreeTransform<Derived>::TransformStmt(Stmt *S) {
+  if (!S)
+    return SemaRef.Owned(S);
+
+  switch (S->getStmtClass()) {
+  case Stmt::NoStmtClass: break;
+
+  // Transform individual statement nodes
+#define STMT(Node, Parent)                                              \
+  case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(S));
+#define EXPR(Node, Parent)
+#include "clang/AST/StmtNodes.def"
+
+  // Transform expressions by calling TransformExpr.
+#define STMT(Node, Parent)
+#define ABSTRACT_EXPR(Node, Parent)
+#define EXPR(Node, Parent) case Stmt::Node##Class:
+#include "clang/AST/StmtNodes.def"
+    {
+      Sema::OwningExprResult E = getDerived().TransformExpr(cast<Expr>(S));
+      if (E.isInvalid())
+        return getSema().StmtError();
+
+      return getSema().ActOnExprStmt(getSema().MakeFullExpr(E));
+    }
+  }
+
+  return SemaRef.Owned(S->Retain());
+}
+
+
+template<typename Derived>
+Sema::OwningExprResult TreeTransform<Derived>::TransformExpr(Expr *E) {
+  if (!E)
+    return SemaRef.Owned(E);
+
+  switch (E->getStmtClass()) {
+    case Stmt::NoStmtClass: break;
+#define STMT(Node, Parent) case Stmt::Node##Class: break;
+#define ABSTRACT_EXPR(Node, Parent)
+#define EXPR(Node, Parent)                                              \
+    case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(E));
+#include "clang/AST/StmtNodes.def"
+  }
+
+  return SemaRef.Owned(E->Retain());
+}
+
+template<typename Derived>
+NestedNameSpecifier *
+TreeTransform<Derived>::TransformNestedNameSpecifier(NestedNameSpecifier *NNS,
+                                                     SourceRange Range,
+                                                     QualType ObjectType,
+                                             NamedDecl *FirstQualifierInScope) {
+  if (!NNS)
+    return 0;
+
+  // Transform the prefix of this nested name specifier.
+  NestedNameSpecifier *Prefix = NNS->getPrefix();
+  if (Prefix) {
+    Prefix = getDerived().TransformNestedNameSpecifier(Prefix, Range,
+                                                       ObjectType,
+                                                       FirstQualifierInScope);
+    if (!Prefix)
+      return 0;
+
+    // Clear out the object type and the first qualifier in scope; they only
+    // apply to the first element in the nested-name-specifier.
+    ObjectType = QualType();
+    FirstQualifierInScope = 0;
+  }
+
+  switch (NNS->getKind()) {
+  case NestedNameSpecifier::Identifier:
+    assert((Prefix || !ObjectType.isNull()) &&
+            "Identifier nested-name-specifier with no prefix or object type");
+    if (!getDerived().AlwaysRebuild() && Prefix == NNS->getPrefix() &&
+        ObjectType.isNull())
+      return NNS;
+
+    return getDerived().RebuildNestedNameSpecifier(Prefix, Range,
+                                                   *NNS->getAsIdentifier(),
+                                                   ObjectType,
+                                                   FirstQualifierInScope);
+
+  case NestedNameSpecifier::Namespace: {
+    NamespaceDecl *NS
+      = cast_or_null<NamespaceDecl>(
+                                    getDerived().TransformDecl(Range.getBegin(),
+                                                       NNS->getAsNamespace()));
+    if (!getDerived().AlwaysRebuild() &&
+        Prefix == NNS->getPrefix() &&
+        NS == NNS->getAsNamespace())
+      return NNS;
+
+    return getDerived().RebuildNestedNameSpecifier(Prefix, Range, NS);
+  }
+
+  case NestedNameSpecifier::Global:
+    // There is no meaningful transformation that one could perform on the
+    // global scope.
+    return NNS;
+
+  case NestedNameSpecifier::TypeSpecWithTemplate:
+  case NestedNameSpecifier::TypeSpec: {
+    TemporaryBase Rebase(*this, Range.getBegin(), DeclarationName());
+    QualType T = getDerived().TransformType(QualType(NNS->getAsType(), 0),
+                                            ObjectType);
+    if (T.isNull())
+      return 0;
+
+    if (!getDerived().AlwaysRebuild() &&
+        Prefix == NNS->getPrefix() &&
+        T == QualType(NNS->getAsType(), 0))
+      return NNS;
+
+    return getDerived().RebuildNestedNameSpecifier(Prefix, Range,
+                  NNS->getKind() == NestedNameSpecifier::TypeSpecWithTemplate,
+                                                   T);
+  }
+  }
+
+  // Required to silence a GCC warning
+  return 0;
+}
+
+template<typename Derived>
+DeclarationName
+TreeTransform<Derived>::TransformDeclarationName(DeclarationName Name,
+                                                 SourceLocation Loc,
+                                                 QualType ObjectType) {
+  if (!Name)
+    return Name;
+
+  switch (Name.getNameKind()) {
+  case DeclarationName::Identifier:
+  case DeclarationName::ObjCZeroArgSelector:
+  case DeclarationName::ObjCOneArgSelector:
+  case DeclarationName::ObjCMultiArgSelector:
+  case DeclarationName::CXXOperatorName:
+  case DeclarationName::CXXLiteralOperatorName:
+  case DeclarationName::CXXUsingDirective:
+    return Name;
+
+  case DeclarationName::CXXConstructorName:
+  case DeclarationName::CXXDestructorName:
+  case DeclarationName::CXXConversionFunctionName: {
+    TemporaryBase Rebase(*this, Loc, Name);
+    QualType T = getDerived().TransformType(Name.getCXXNameType(), 
+                                            ObjectType);
+    if (T.isNull())
+      return DeclarationName();
+
+    return SemaRef.Context.DeclarationNames.getCXXSpecialName(
+                                                           Name.getNameKind(),
+                                          SemaRef.Context.getCanonicalType(T));
+  }
+  }
+
+  return DeclarationName();
+}
+
+template<typename Derived>
+TemplateName
+TreeTransform<Derived>::TransformTemplateName(TemplateName Name,
+                                              QualType ObjectType) {
+  SourceLocation Loc = getDerived().getBaseLocation();
+
+  if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {
+    NestedNameSpecifier *NNS
+      = getDerived().TransformNestedNameSpecifier(QTN->getQualifier(),
+                        /*FIXME:*/SourceRange(getDerived().getBaseLocation()),
+                                                  ObjectType);
+    if (!NNS)
+      return TemplateName();
+
+    if (TemplateDecl *Template = QTN->getTemplateDecl()) {
+      TemplateDecl *TransTemplate
+        = cast_or_null<TemplateDecl>(getDerived().TransformDecl(Loc, Template));
+      if (!TransTemplate)
+        return TemplateName();
+
+      if (!getDerived().AlwaysRebuild() &&
+          NNS == QTN->getQualifier() &&
+          TransTemplate == Template)
+        return Name;
+
+      return getDerived().RebuildTemplateName(NNS, QTN->hasTemplateKeyword(),
+                                              TransTemplate);
+    }
+
+    // These should be getting filtered out before they make it into the AST.
+    assert(false && "overloaded template name survived to here");
+  }
+
+  if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) {
+    NestedNameSpecifier *NNS
+      = getDerived().TransformNestedNameSpecifier(DTN->getQualifier(),
+                        /*FIXME:*/SourceRange(getDerived().getBaseLocation()),
+                                                  ObjectType);
+    if (!NNS && DTN->getQualifier())
+      return TemplateName();
+
+    if (!getDerived().AlwaysRebuild() &&
+        NNS == DTN->getQualifier() &&
+        ObjectType.isNull())
+      return Name;
+
+    if (DTN->isIdentifier())
+      return getDerived().RebuildTemplateName(NNS, *DTN->getIdentifier(), 
+                                              ObjectType);
+    
+    return getDerived().RebuildTemplateName(NNS, DTN->getOperator(), 
+                                            ObjectType);
+  }
+
+  if (TemplateDecl *Template = Name.getAsTemplateDecl()) {
+    TemplateDecl *TransTemplate
+      = cast_or_null<TemplateDecl>(getDerived().TransformDecl(Loc, Template));
+    if (!TransTemplate)
+      return TemplateName();
+
+    if (!getDerived().AlwaysRebuild() &&
+        TransTemplate == Template)
+      return Name;
+
+    return TemplateName(TransTemplate);
+  }
+
+  // These should be getting filtered out before they reach the AST.
+  assert(false && "overloaded function decl survived to here");
+  return TemplateName();
+}
+
+template<typename Derived>
+void TreeTransform<Derived>::InventTemplateArgumentLoc(
+                                         const TemplateArgument &Arg,
+                                         TemplateArgumentLoc &Output) {
+  SourceLocation Loc = getDerived().getBaseLocation();
+  switch (Arg.getKind()) {
+  case TemplateArgument::Null:
+    llvm_unreachable("null template argument in TreeTransform");
+    break;
+
+  case TemplateArgument::Type:
+    Output = TemplateArgumentLoc(Arg,
+               SemaRef.Context.getTrivialTypeSourceInfo(Arg.getAsType(), Loc));
+                                            
+    break;
+
+  case TemplateArgument::Template:
+    Output = TemplateArgumentLoc(Arg, SourceRange(), Loc);
+    break;
+      
+  case TemplateArgument::Expression:
+    Output = TemplateArgumentLoc(Arg, Arg.getAsExpr());
+    break;
+
+  case TemplateArgument::Declaration:
+  case TemplateArgument::Integral:
+  case TemplateArgument::Pack:
+    Output = TemplateArgumentLoc(Arg, TemplateArgumentLocInfo());
+    break;
+  }
+}
+
+template<typename Derived>
+bool TreeTransform<Derived>::TransformTemplateArgument(
+                                         const TemplateArgumentLoc &Input,
+                                         TemplateArgumentLoc &Output) {
+  const TemplateArgument &Arg = Input.getArgument();
+  switch (Arg.getKind()) {
+  case TemplateArgument::Null:
+  case TemplateArgument::Integral:
+    Output = Input;
+    return false;
+
+  case TemplateArgument::Type: {
+    TypeSourceInfo *DI = Input.getTypeSourceInfo();
+    if (DI == NULL)
+      DI = InventTypeSourceInfo(Input.getArgument().getAsType());
+
+    DI = getDerived().TransformType(DI);
+    if (!DI) return true;
+
+    Output = TemplateArgumentLoc(TemplateArgument(DI->getType()), DI);
+    return false;
+  }
+
+  case TemplateArgument::Declaration: {
+    // FIXME: we should never have to transform one of these.
+    DeclarationName Name;
+    if (NamedDecl *ND = dyn_cast<NamedDecl>(Arg.getAsDecl()))
+      Name = ND->getDeclName();
+    TemporaryBase Rebase(*this, Input.getLocation(), Name);
+    Decl *D = getDerived().TransformDecl(Input.getLocation(), Arg.getAsDecl());
+    if (!D) return true;
+
+    Expr *SourceExpr = Input.getSourceDeclExpression();
+    if (SourceExpr) {
+      EnterExpressionEvaluationContext Unevaluated(getSema(),
+                                                   Action::Unevaluated);
+      Sema::OwningExprResult E = getDerived().TransformExpr(SourceExpr);
+      if (E.isInvalid())
+        SourceExpr = NULL;
+      else {
+        SourceExpr = E.takeAs<Expr>();
+        SourceExpr->Retain();
+      }
+    }
+
+    Output = TemplateArgumentLoc(TemplateArgument(D), SourceExpr);
+    return false;
+  }
+
+  case TemplateArgument::Template: {
+    TemporaryBase Rebase(*this, Input.getLocation(), DeclarationName());    
+    TemplateName Template
+      = getDerived().TransformTemplateName(Arg.getAsTemplate());
+    if (Template.isNull())
+      return true;
+    
+    Output = TemplateArgumentLoc(TemplateArgument(Template),
+                                 Input.getTemplateQualifierRange(),
+                                 Input.getTemplateNameLoc());
+    return false;
+  }
+      
+  case TemplateArgument::Expression: {
+    // Template argument expressions are not potentially evaluated.
+    EnterExpressionEvaluationContext Unevaluated(getSema(),
+                                                 Action::Unevaluated);
+
+    Expr *InputExpr = Input.getSourceExpression();
+    if (!InputExpr) InputExpr = Input.getArgument().getAsExpr();
+
+    Sema::OwningExprResult E
+      = getDerived().TransformExpr(InputExpr);
+    if (E.isInvalid()) return true;
+
+    Expr *ETaken = E.takeAs<Expr>();
+    ETaken->Retain();
+    Output = TemplateArgumentLoc(TemplateArgument(ETaken), ETaken);
+    return false;
+  }
+
+  case TemplateArgument::Pack: {
+    llvm::SmallVector<TemplateArgument, 4> TransformedArgs;
+    TransformedArgs.reserve(Arg.pack_size());
+    for (TemplateArgument::pack_iterator A = Arg.pack_begin(),
+                                      AEnd = Arg.pack_end();
+         A != AEnd; ++A) {
+
+      // FIXME: preserve source information here when we start
+      // caring about parameter packs.
+
+      TemplateArgumentLoc InputArg;
+      TemplateArgumentLoc OutputArg;
+      getDerived().InventTemplateArgumentLoc(*A, InputArg);
+      if (getDerived().TransformTemplateArgument(InputArg, OutputArg))
+        return true;
+
+      TransformedArgs.push_back(OutputArg.getArgument());
+    }
+    TemplateArgument Result;
+    Result.setArgumentPack(TransformedArgs.data(), TransformedArgs.size(),
+                           true);
+    Output = TemplateArgumentLoc(Result, Input.getLocInfo());
+    return false;
+  }
+  }
+
+  // Work around bogus GCC warning
+  return true;
+}
+
+//===----------------------------------------------------------------------===//
+// Type transformation
+//===----------------------------------------------------------------------===//
+
+template<typename Derived>
+QualType TreeTransform<Derived>::TransformType(QualType T, 
+                                               QualType ObjectType) {
+  if (getDerived().AlreadyTransformed(T))
+    return T;
+
+  // Temporary workaround.  All of these transformations should
+  // eventually turn into transformations on TypeLocs.
+  TypeSourceInfo *DI = getSema().Context.CreateTypeSourceInfo(T);
+  DI->getTypeLoc().initialize(getDerived().getBaseLocation());
+  
+  TypeSourceInfo *NewDI = getDerived().TransformType(DI, ObjectType);
+
+  if (!NewDI)
+    return QualType();
+
+  return NewDI->getType();
+}
+
+template<typename Derived>
+TypeSourceInfo *TreeTransform<Derived>::TransformType(TypeSourceInfo *DI,
+                                                      QualType ObjectType) {
+  if (getDerived().AlreadyTransformed(DI->getType()))
+    return DI;
+
+  TypeLocBuilder TLB;
+
+  TypeLoc TL = DI->getTypeLoc();
+  TLB.reserve(TL.getFullDataSize());
+
+  QualType Result = getDerived().TransformType(TLB, TL, ObjectType);
+  if (Result.isNull())
+    return 0;
+
+  return TLB.getTypeSourceInfo(SemaRef.Context, Result);
+}
+
+template<typename Derived>
+QualType
+TreeTransform<Derived>::TransformType(TypeLocBuilder &TLB, TypeLoc T,
+                                      QualType ObjectType) {
+  switch (T.getTypeLocClass()) {
+#define ABSTRACT_TYPELOC(CLASS, PARENT)
+#define TYPELOC(CLASS, PARENT) \
+  case TypeLoc::CLASS: \
+    return getDerived().Transform##CLASS##Type(TLB, cast<CLASS##TypeLoc>(T), \
+                                               ObjectType);
+#include "clang/AST/TypeLocNodes.def"
+  }
+
+  llvm_unreachable("unhandled type loc!");
+  return QualType();
+}
+
+/// FIXME: By default, this routine adds type qualifiers only to types
+/// that can have qualifiers, and silently suppresses those qualifiers
+/// that are not permitted (e.g., qualifiers on reference or function
+/// types). This is the right thing for template instantiation, but
+/// probably not for other clients.
+template<typename Derived>
+QualType
+TreeTransform<Derived>::TransformQualifiedType(TypeLocBuilder &TLB,
+                                               QualifiedTypeLoc T,
+                                               QualType ObjectType) {
+  Qualifiers Quals = T.getType().getLocalQualifiers();
+
+  QualType Result = getDerived().TransformType(TLB, T.getUnqualifiedLoc(),
+                                               ObjectType);
+  if (Result.isNull())
+    return QualType();
+
+  // Silently suppress qualifiers if the result type can't be qualified.
+  // FIXME: this is the right thing for template instantiation, but
+  // probably not for other clients.
+  if (Result->isFunctionType() || Result->isReferenceType())
+    return Result;
+
+  Result = SemaRef.Context.getQualifiedType(Result, Quals);
+
+  TLB.push<QualifiedTypeLoc>(Result);
+
+  // No location information to preserve.
+
+  return Result;
+}
+
+template <class TyLoc> static inline
+QualType TransformTypeSpecType(TypeLocBuilder &TLB, TyLoc T) {
+  TyLoc NewT = TLB.push<TyLoc>(T.getType());
+  NewT.setNameLoc(T.getNameLoc());
+  return T.getType();
+}
+
+template<typename Derived>
+QualType TreeTransform<Derived>::TransformBuiltinType(TypeLocBuilder &TLB,
+                                                      BuiltinTypeLoc T,
+                                                      QualType ObjectType) {
+  BuiltinTypeLoc NewT = TLB.push<BuiltinTypeLoc>(T.getType());
+  NewT.setBuiltinLoc(T.getBuiltinLoc());
+  if (T.needsExtraLocalData())
+    NewT.getWrittenBuiltinSpecs() = T.getWrittenBuiltinSpecs();
+  return T.getType();
+}
+
+template<typename Derived>
+QualType TreeTransform<Derived>::TransformComplexType(TypeLocBuilder &TLB,
+                                                      ComplexTypeLoc T,
+                                                      QualType ObjectType) {
+  // FIXME: recurse?
+  return TransformTypeSpecType(TLB, T);
+}
+
+template<typename Derived>
+QualType TreeTransform<Derived>::TransformPointerType(TypeLocBuilder &TLB,
+                                                      PointerTypeLoc TL, 
+                                                      QualType ObjectType) {
+  QualType PointeeType                                      
+    = getDerived().TransformType(TLB, TL.getPointeeLoc());  
+  if (PointeeType.isNull())
+    return QualType();
+
+  QualType Result = TL.getType();
+  if (PointeeType->isObjCInterfaceType()) {
+    // A dependent pointer type 'T *' has is being transformed such
+    // that an Objective-C class type is being replaced for 'T'. The
+    // resulting pointer type is an ObjCObjectPointerType, not a
+    // PointerType.
+    const ObjCInterfaceType *IFace = PointeeType->getAs<ObjCInterfaceType>();
+    Result = SemaRef.Context.getObjCObjectPointerType(PointeeType,
+                                              const_cast<ObjCProtocolDecl **>(
+                                                           IFace->qual_begin()),
+                                              IFace->getNumProtocols());
+    
+    ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(Result);   
+    NewT.setStarLoc(TL.getSigilLoc());       
+    NewT.setHasProtocolsAsWritten(false);
+    NewT.setLAngleLoc(SourceLocation());
+    NewT.setRAngleLoc(SourceLocation());
+    NewT.setHasBaseTypeAsWritten(true);
+    return Result;
+  }
+                                                            
+  if (getDerived().AlwaysRebuild() ||
+      PointeeType != TL.getPointeeLoc().getType()) {
+    Result = getDerived().RebuildPointerType(PointeeType, TL.getSigilLoc());
+    if (Result.isNull())
+      return QualType();
+  }
+                                                            
+  PointerTypeLoc NewT = TLB.push<PointerTypeLoc>(Result);
+  NewT.setSigilLoc(TL.getSigilLoc());
+  return Result;  
+}
+
+template<typename Derived>
+QualType
+TreeTransform<Derived>::TransformBlockPointerType(TypeLocBuilder &TLB,
+                                                  BlockPointerTypeLoc TL,
+                                                  QualType ObjectType) {
+  QualType PointeeType
+    = getDerived().TransformType(TLB, TL.getPointeeLoc());  
+  if (PointeeType.isNull())                                 
+    return QualType();                                      
+  
+  QualType Result = TL.getType();                           
+  if (getDerived().AlwaysRebuild() ||                       
+      PointeeType != TL.getPointeeLoc().getType()) {        
+    Result = getDerived().RebuildBlockPointerType(PointeeType, 
+                                                  TL.getSigilLoc());
+    if (Result.isNull())
+      return QualType();
+  }
+
+  BlockPointerTypeLoc NewT = TLB.push<BlockPointerTypeLoc>(Result);
+  NewT.setSigilLoc(TL.getSigilLoc());
+  return Result;
+}
+
+/// Transforms a reference type.  Note that somewhat paradoxically we
+/// don't care whether the type itself is an l-value type or an r-value
+/// type;  we only care if the type was *written* as an l-value type
+/// or an r-value type.
+template<typename Derived>
+QualType
+TreeTransform<Derived>::TransformReferenceType(TypeLocBuilder &TLB,
+                                               ReferenceTypeLoc TL,
+                                               QualType ObjectType) {
+  const ReferenceType *T = TL.getTypePtr();
+
+  // Note that this works with the pointee-as-written.
+  QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
+  if (PointeeType.isNull())
+    return QualType();
+
+  QualType Result = TL.getType();
+  if (getDerived().AlwaysRebuild() ||
+      PointeeType != T->getPointeeTypeAsWritten()) {
+    Result = getDerived().RebuildReferenceType(PointeeType,
+                                               T->isSpelledAsLValue(),
+                                               TL.getSigilLoc());
+    if (Result.isNull())
+      return QualType();
+  }
+
+  // r-value references can be rebuilt as l-value references.
+  ReferenceTypeLoc NewTL;
+  if (isa<LValueReferenceType>(Result))
+    NewTL = TLB.push<LValueReferenceTypeLoc>(Result);
+  else
+    NewTL = TLB.push<RValueReferenceTypeLoc>(Result);
+  NewTL.setSigilLoc(TL.getSigilLoc());
+
+  return Result;
+}
+
+template<typename Derived>
+QualType
+TreeTransform<Derived>::TransformLValueReferenceType(TypeLocBuilder &TLB,
+                                                 LValueReferenceTypeLoc TL,
+                                                     QualType ObjectType) {
+  return TransformReferenceType(TLB, TL, ObjectType);
+}
+
+template<typename Derived>
+QualType
+TreeTransform<Derived>::TransformRValueReferenceType(TypeLocBuilder &TLB,
+                                                 RValueReferenceTypeLoc TL,
+                                                     QualType ObjectType) {
+  return TransformReferenceType(TLB, TL, ObjectType);
+}
+
+template<typename Derived>
+QualType
+TreeTransform<Derived>::TransformMemberPointerType(TypeLocBuilder &TLB,
+                                                   MemberPointerTypeLoc TL,
+                                                   QualType ObjectType) {
+  MemberPointerType *T = TL.getTypePtr();
+
+  QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
+  if (PointeeType.isNull())
+    return QualType();
+
+  // TODO: preserve source information for this.
+  QualType ClassType
+    = getDerived().TransformType(QualType(T->getClass(), 0));
+  if (ClassType.isNull())
+    return QualType();
+
+  QualType Result = TL.getType();
+  if (getDerived().AlwaysRebuild() ||
+      PointeeType != T->getPointeeType() ||
+      ClassType != QualType(T->getClass(), 0)) {
+    Result = getDerived().RebuildMemberPointerType(PointeeType, ClassType,
+                                                   TL.getStarLoc());
+    if (Result.isNull())
+      return QualType();
+  }
+
+  MemberPointerTypeLoc NewTL = TLB.push<MemberPointerTypeLoc>(Result);
+  NewTL.setSigilLoc(TL.getSigilLoc());
+
+  return Result;
+}
+
+template<typename Derived>
+QualType
+TreeTransform<Derived>::TransformConstantArrayType(TypeLocBuilder &TLB,
+                                                   ConstantArrayTypeLoc TL,
+                                                   QualType ObjectType) {
+  ConstantArrayType *T = TL.getTypePtr();
+  QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
+  if (ElementType.isNull())
+    return QualType();
+
+  QualType Result = TL.getType();
+  if (getDerived().AlwaysRebuild() ||
+      ElementType != T->getElementType()) {
+    Result = getDerived().RebuildConstantArrayType(ElementType,
+                                                   T->getSizeModifier(),
+                                                   T->getSize(),
+                                             T->getIndexTypeCVRQualifiers(),
+                                                   TL.getBracketsRange());
+    if (Result.isNull())
+      return QualType();
+  }
+  
+  ConstantArrayTypeLoc NewTL = TLB.push<ConstantArrayTypeLoc>(Result);
+  NewTL.setLBracketLoc(TL.getLBracketLoc());
+  NewTL.setRBracketLoc(TL.getRBracketLoc());
+
+  Expr *Size = TL.getSizeExpr();
+  if (Size) {
+    EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
+    Size = getDerived().TransformExpr(Size).template takeAs<Expr>();
+  }
+  NewTL.setSizeExpr(Size);
+
+  return Result;
+}
+
+template<typename Derived>
+QualType TreeTransform<Derived>::TransformIncompleteArrayType(
+                                              TypeLocBuilder &TLB,
+                                              IncompleteArrayTypeLoc TL,
+                                              QualType ObjectType) {
+  IncompleteArrayType *T = TL.getTypePtr();
+  QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
+  if (ElementType.isNull())
+    return QualType();
+
+  QualType Result = TL.getType();
+  if (getDerived().AlwaysRebuild() ||
+      ElementType != T->getElementType()) {
+    Result = getDerived().RebuildIncompleteArrayType(ElementType,
+                                                     T->getSizeModifier(),
+                                           T->getIndexTypeCVRQualifiers(),
+                                                     TL.getBracketsRange());
+    if (Result.isNull())
+      return QualType();
+  }
+  
+  IncompleteArrayTypeLoc NewTL = TLB.push<IncompleteArrayTypeLoc>(Result);
+  NewTL.setLBracketLoc(TL.getLBracketLoc());
+  NewTL.setRBracketLoc(TL.getRBracketLoc());
+  NewTL.setSizeExpr(0);
+
+  return Result;
+}
+
+template<typename Derived>
+QualType
+TreeTransform<Derived>::TransformVariableArrayType(TypeLocBuilder &TLB,
+                                                   VariableArrayTypeLoc TL,
+                                                   QualType ObjectType) {
+  VariableArrayType *T = TL.getTypePtr();
+  QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
+  if (ElementType.isNull())
+    return QualType();
+
+  // Array bounds are not potentially evaluated contexts
+  EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
+
+  Sema::OwningExprResult SizeResult
+    = getDerived().TransformExpr(T->getSizeExpr());
+  if (SizeResult.isInvalid())
+    return QualType();
+
+  Expr *Size = static_cast<Expr*>(SizeResult.get());
+
+  QualType Result = TL.getType();
+  if (getDerived().AlwaysRebuild() ||
+      ElementType != T->getElementType() ||
+      Size != T->getSizeExpr()) {
+    Result = getDerived().RebuildVariableArrayType(ElementType,
+                                                   T->getSizeModifier(),
+                                                   move(SizeResult),
+                                             T->getIndexTypeCVRQualifiers(),
+                                                   TL.getBracketsRange());
+    if (Result.isNull())
+      return QualType();
+  }
+  else SizeResult.take();
+  
+  VariableArrayTypeLoc NewTL = TLB.push<VariableArrayTypeLoc>(Result);
+  NewTL.setLBracketLoc(TL.getLBracketLoc());
+  NewTL.setRBracketLoc(TL.getRBracketLoc());
+  NewTL.setSizeExpr(Size);
+
+  return Result;
+}
+
+template<typename Derived>
+QualType
+TreeTransform<Derived>::TransformDependentSizedArrayType(TypeLocBuilder &TLB,
+                                             DependentSizedArrayTypeLoc TL,
+                                                        QualType ObjectType) {
+  DependentSizedArrayType *T = TL.getTypePtr();
+  QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
+  if (ElementType.isNull())
+    return QualType();
+
+  // Array bounds are not potentially evaluated contexts
+  EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
+
+  Sema::OwningExprResult SizeResult
+    = getDerived().TransformExpr(T->getSizeExpr());
+  if (SizeResult.isInvalid())
+    return QualType();
+
+  Expr *Size = static_cast<Expr*>(SizeResult.get());
+
+  QualType Result = TL.getType();
+  if (getDerived().AlwaysRebuild() ||
+      ElementType != T->getElementType() ||
+      Size != T->getSizeExpr()) {
+    Result = getDerived().RebuildDependentSizedArrayType(ElementType,
+                                                         T->getSizeModifier(),
+                                                         move(SizeResult),
+                                                T->getIndexTypeCVRQualifiers(),
+                                                        TL.getBracketsRange());
+    if (Result.isNull())
+      return QualType();
+  }
+  else SizeResult.take();
+
+  // We might have any sort of array type now, but fortunately they
+  // all have the same location layout.
+  ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result);
+  NewTL.setLBracketLoc(TL.getLBracketLoc());
+  NewTL.setRBracketLoc(TL.getRBracketLoc());
+  NewTL.setSizeExpr(Size);
+
+  return Result;
+}
+
+template<typename Derived>
+QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType(
+                                      TypeLocBuilder &TLB,
+                                      DependentSizedExtVectorTypeLoc TL,
+                                      QualType ObjectType) {
+  DependentSizedExtVectorType *T = TL.getTypePtr();
+
+  // FIXME: ext vector locs should be nested
+  QualType ElementType = getDerived().TransformType(T->getElementType());
+  if (ElementType.isNull())
+    return QualType();
+
+  // Vector sizes are not potentially evaluated contexts
+  EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
+
+  Sema::OwningExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
+  if (Size.isInvalid())
+    return QualType();
+
+  QualType Result = TL.getType();
+  if (getDerived().AlwaysRebuild() ||
+      ElementType != T->getElementType() ||
+      Size.get() != T->getSizeExpr()) {
+    Result = getDerived().RebuildDependentSizedExtVectorType(ElementType,
+                                                         move(Size),
+                                                         T->getAttributeLoc());
+    if (Result.isNull())
+      return QualType();
+  }
+  else Size.take();
+
+  // Result might be dependent or not.
+  if (isa<DependentSizedExtVectorType>(Result)) {
+    DependentSizedExtVectorTypeLoc NewTL
+      = TLB.push<DependentSizedExtVectorTypeLoc>(Result);
+    NewTL.setNameLoc(TL.getNameLoc());
+  } else {
+    ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result);
+    NewTL.setNameLoc(TL.getNameLoc());
+  }
+
+  return Result;
+}
+
+template<typename Derived>
+QualType TreeTransform<Derived>::TransformVectorType(TypeLocBuilder &TLB,
+                                                     VectorTypeLoc TL,
+                                                     QualType ObjectType) {
+  VectorType *T = TL.getTypePtr();
+  QualType ElementType = getDerived().TransformType(T->getElementType());
+  if (ElementType.isNull())
+    return QualType();
+
+  QualType Result = TL.getType();
+  if (getDerived().AlwaysRebuild() ||
+      ElementType != T->getElementType()) {
+    Result = getDerived().RebuildVectorType(ElementType, T->getNumElements(),
+      T->isAltiVec(), T->isPixel());
+    if (Result.isNull())
+      return QualType();
+  }
+  
+  VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(Result);
+  NewTL.setNameLoc(TL.getNameLoc());
+
+  return Result;
+}
+
+template<typename Derived>
+QualType TreeTransform<Derived>::TransformExtVectorType(TypeLocBuilder &TLB,
+                                                        ExtVectorTypeLoc TL,
+                                                        QualType ObjectType) {
+  VectorType *T = TL.getTypePtr();
+  QualType ElementType = getDerived().TransformType(T->getElementType());
+  if (ElementType.isNull())
+    return QualType();
+
+  QualType Result = TL.getType();
+  if (getDerived().AlwaysRebuild() ||
+      ElementType != T->getElementType()) {
+    Result = getDerived().RebuildExtVectorType(ElementType,
+                                               T->getNumElements(),
+                                               /*FIXME*/ SourceLocation());
+    if (Result.isNull())
+      return QualType();
+  }
+  
+  ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result);
+  NewTL.setNameLoc(TL.getNameLoc());
+
+  return Result;
+}
+
+template<typename Derived>
+ParmVarDecl *
+TreeTransform<Derived>::TransformFunctionTypeParam(ParmVarDecl *OldParm) {
+  TypeSourceInfo *OldDI = OldParm->getTypeSourceInfo();
+  TypeSourceInfo *NewDI = getDerived().TransformType(OldDI);
+  if (!NewDI)
+    return 0;
+
+  if (NewDI == OldDI)
+    return OldParm;
+  else
+    return ParmVarDecl::Create(SemaRef.Context,
+                               OldParm->getDeclContext(),
+                               OldParm->getLocation(),
+                               OldParm->getIdentifier(),
+                               NewDI->getType(),
+                               NewDI,
+                               OldParm->getStorageClass(),
+                               OldParm->getStorageClassAsWritten(),
+                               /* DefArg */ NULL);
+}
+
+template<typename Derived>
+bool TreeTransform<Derived>::
+  TransformFunctionTypeParams(FunctionProtoTypeLoc TL,
+                              llvm::SmallVectorImpl<QualType> &PTypes,
+                              llvm::SmallVectorImpl<ParmVarDecl*> &PVars) {
+  FunctionProtoType *T = TL.getTypePtr();
+
+  for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) {
+    ParmVarDecl *OldParm = TL.getArg(i);
+
+    QualType NewType;
+    ParmVarDecl *NewParm;
+
+    if (OldParm) {
+      NewParm = getDerived().TransformFunctionTypeParam(OldParm);
+      if (!NewParm)
+        return true;
+      NewType = NewParm->getType();
+
+    // Deal with the possibility that we don't have a parameter
+    // declaration for this parameter.
+    } else {
+      NewParm = 0;
+
+      QualType OldType = T->getArgType(i);
+      NewType = getDerived().TransformType(OldType);
+      if (NewType.isNull())
+        return true;
+    }
+
+    PTypes.push_back(NewType);
+    PVars.push_back(NewParm);
+  }
+
+  return false;
+}
+
+template<typename Derived>
+QualType
+TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB,
+                                                   FunctionProtoTypeLoc TL,
+                                                   QualType ObjectType) {
+  FunctionProtoType *T = TL.getTypePtr();
+  QualType ResultType = getDerived().TransformType(TLB, TL.getResultLoc());
+  if (ResultType.isNull())
+    return QualType();
+
+  // Transform the parameters.
+  llvm::SmallVector<QualType, 4> ParamTypes;
+  llvm::SmallVector<ParmVarDecl*, 4> ParamDecls;
+  if (getDerived().TransformFunctionTypeParams(TL, ParamTypes, ParamDecls))
+    return QualType();
+
+  QualType Result = TL.getType();
+  if (getDerived().AlwaysRebuild() ||
+      ResultType != T->getResultType() ||
+      !std::equal(T->arg_type_begin(), T->arg_type_end(), ParamTypes.begin())) {
+    Result = getDerived().RebuildFunctionProtoType(ResultType,
+                                                   ParamTypes.data(),
+                                                   ParamTypes.size(),
+                                                   T->isVariadic(),
+                                                   T->getTypeQuals());
+    if (Result.isNull())
+      return QualType();
+  }
+
+  FunctionProtoTypeLoc NewTL = TLB.push<FunctionProtoTypeLoc>(Result);
+  NewTL.setLParenLoc(TL.getLParenLoc());
+  NewTL.setRParenLoc(TL.getRParenLoc());
+  for (unsigned i = 0, e = NewTL.getNumArgs(); i != e; ++i)
+    NewTL.setArg(i, ParamDecls[i]);
+
+  return Result;
+}
+
+template<typename Derived>
+QualType TreeTransform<Derived>::TransformFunctionNoProtoType(
+                                                 TypeLocBuilder &TLB,
+                                                 FunctionNoProtoTypeLoc TL,
+                                                 QualType ObjectType) {
+  FunctionNoProtoType *T = TL.getTypePtr();
+  QualType ResultType = getDerived().TransformType(TLB, TL.getResultLoc());
+  if (ResultType.isNull())
+    return QualType();
+
+  QualType Result = TL.getType();
+  if (getDerived().AlwaysRebuild() ||
+      ResultType != T->getResultType())
+    Result = getDerived().RebuildFunctionNoProtoType(ResultType);
+
+  FunctionNoProtoTypeLoc NewTL = TLB.push<FunctionNoProtoTypeLoc>(Result);
+  NewTL.setLParenLoc(TL.getLParenLoc());
+  NewTL.setRParenLoc(TL.getRParenLoc());
+
+  return Result;
+}
+
+template<typename Derived> QualType
+TreeTransform<Derived>::TransformUnresolvedUsingType(TypeLocBuilder &TLB,
+                                                 UnresolvedUsingTypeLoc TL,
+                                                     QualType ObjectType) {
+  UnresolvedUsingType *T = TL.getTypePtr();
+  Decl *D = getDerived().TransformDecl(TL.getNameLoc(), T->getDecl());
+  if (!D)
+    return QualType();
+
+  QualType Result = TL.getType();
+  if (getDerived().AlwaysRebuild() || D != T->getDecl()) {
+    Result = getDerived().RebuildUnresolvedUsingType(D);
+    if (Result.isNull())
+      return QualType();
+  }
+
+  // We might get an arbitrary type spec type back.  We should at
+  // least always get a type spec type, though.
+  TypeSpecTypeLoc NewTL = TLB.pushTypeSpec(Result);
+  NewTL.setNameLoc(TL.getNameLoc());
+
+  return Result;
+}
+
+template<typename Derived>
+QualType TreeTransform<Derived>::TransformTypedefType(TypeLocBuilder &TLB,
+                                                      TypedefTypeLoc TL,
+                                                      QualType ObjectType) {
+  TypedefType *T = TL.getTypePtr();
+  TypedefDecl *Typedef
+    = cast_or_null<TypedefDecl>(getDerived().TransformDecl(TL.getNameLoc(),
+                                                           T->getDecl()));
+  if (!Typedef)
+    return QualType();
+
+  QualType Result = TL.getType();
+  if (getDerived().AlwaysRebuild() ||
+      Typedef != T->getDecl()) {
+    Result = getDerived().RebuildTypedefType(Typedef);
+    if (Result.isNull())
+      return QualType();
+  }
+
+  TypedefTypeLoc NewTL = TLB.push<TypedefTypeLoc>(Result);
+  NewTL.setNameLoc(TL.getNameLoc());
+
+  return Result;
+}
+
+template<typename Derived>
+QualType TreeTransform<Derived>::TransformTypeOfExprType(TypeLocBuilder &TLB,
+                                                      TypeOfExprTypeLoc TL,
+                                                       QualType ObjectType) {
+  // typeof expressions are not potentially evaluated contexts
+  EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
+
+  Sema::OwningExprResult E = getDerived().TransformExpr(TL.getUnderlyingExpr());
+  if (E.isInvalid())
+    return QualType();
+
+  QualType Result = TL.getType();
+  if (getDerived().AlwaysRebuild() ||
+      E.get() != TL.getUnderlyingExpr()) {
+    Result = getDerived().RebuildTypeOfExprType(move(E));
+    if (Result.isNull())
+      return QualType();
+  }
+  else E.take();
+
+  TypeOfExprTypeLoc NewTL = TLB.push<TypeOfExprTypeLoc>(Result);
+  NewTL.setTypeofLoc(TL.getTypeofLoc());
+  NewTL.setLParenLoc(TL.getLParenLoc());
+  NewTL.setRParenLoc(TL.getRParenLoc());
+
+  return Result;
+}
+
+template<typename Derived>
+QualType TreeTransform<Derived>::TransformTypeOfType(TypeLocBuilder &TLB,
+                                                     TypeOfTypeLoc TL,
+                                                     QualType ObjectType) {
+  TypeSourceInfo* Old_Under_TI = TL.getUnderlyingTInfo();
+  TypeSourceInfo* New_Under_TI = getDerived().TransformType(Old_Under_TI);
+  if (!New_Under_TI)
+    return QualType();
+
+  QualType Result = TL.getType();
+  if (getDerived().AlwaysRebuild() || New_Under_TI != Old_Under_TI) {
+    Result = getDerived().RebuildTypeOfType(New_Under_TI->getType());
+    if (Result.isNull())
+      return QualType();
+  }
+
+  TypeOfTypeLoc NewTL = TLB.push<TypeOfTypeLoc>(Result);
+  NewTL.setTypeofLoc(TL.getTypeofLoc());
+  NewTL.setLParenLoc(TL.getLParenLoc());
+  NewTL.setRParenLoc(TL.getRParenLoc());
+  NewTL.setUnderlyingTInfo(New_Under_TI);
+
+  return Result;
+}
+
+template<typename Derived>
+QualType TreeTransform<Derived>::TransformDecltypeType(TypeLocBuilder &TLB,
+                                                       DecltypeTypeLoc TL,
+                                                       QualType ObjectType) {
+  DecltypeType *T = TL.getTypePtr();
+
+  // decltype expressions are not potentially evaluated contexts
+  EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
+
+  Sema::OwningExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
+  if (E.isInvalid())
+    return QualType();
+
+  QualType Result = TL.getType();
+  if (getDerived().AlwaysRebuild() ||
+      E.get() != T->getUnderlyingExpr()) {
+    Result = getDerived().RebuildDecltypeType(move(E));
+    if (Result.isNull())
+      return QualType();
+  }
+  else E.take();
+
+  DecltypeTypeLoc NewTL = TLB.push<DecltypeTypeLoc>(Result);
+  NewTL.setNameLoc(TL.getNameLoc());
+
+  return Result;
+}
+
+template<typename Derived>
+QualType TreeTransform<Derived>::TransformRecordType(TypeLocBuilder &TLB,
+                                                     RecordTypeLoc TL,
+                                                     QualType ObjectType) {
+  RecordType *T = TL.getTypePtr();
+  RecordDecl *Record
+    = cast_or_null<RecordDecl>(getDerived().TransformDecl(TL.getNameLoc(),
+                                                          T->getDecl()));
+  if (!Record)
+    return QualType();
+
+  QualType Result = TL.getType();
+  if (getDerived().AlwaysRebuild() ||
+      Record != T->getDecl()) {
+    Result = getDerived().RebuildRecordType(Record);
+    if (Result.isNull())
+      return QualType();
+  }
+
+  RecordTypeLoc NewTL = TLB.push<RecordTypeLoc>(Result);
+  NewTL.setNameLoc(TL.getNameLoc());
+
+  return Result;
+}
+
+template<typename Derived>
+QualType TreeTransform<Derived>::TransformEnumType(TypeLocBuilder &TLB,
+                                                   EnumTypeLoc TL,
+                                                   QualType ObjectType) {
+  EnumType *T = TL.getTypePtr();
+  EnumDecl *Enum
+    = cast_or_null<EnumDecl>(getDerived().TransformDecl(TL.getNameLoc(),
+                                                        T->getDecl()));
+  if (!Enum)
+    return QualType();
+
+  QualType Result = TL.getType();
+  if (getDerived().AlwaysRebuild() ||
+      Enum != T->getDecl()) {
+    Result = getDerived().RebuildEnumType(Enum);
+    if (Result.isNull())
+      return QualType();
+  }
+
+  EnumTypeLoc NewTL = TLB.push<EnumTypeLoc>(Result);
+  NewTL.setNameLoc(TL.getNameLoc());
+
+  return Result;
+}
+
+template <typename Derived>
+QualType TreeTransform<Derived>::TransformElaboratedType(TypeLocBuilder &TLB,
+                                                         ElaboratedTypeLoc TL,
+                                                       QualType ObjectType) {
+  ElaboratedType *T = TL.getTypePtr();
+
+  // FIXME: this should be a nested type.
+  QualType Underlying = getDerived().TransformType(T->getUnderlyingType());
+  if (Underlying.isNull())
+    return QualType();
+
+  QualType Result = TL.getType();
+  if (getDerived().AlwaysRebuild() ||
+      Underlying != T->getUnderlyingType()) {
+    Result = getDerived().RebuildElaboratedType(Underlying, T->getTagKind());
+    if (Result.isNull())
+      return QualType();
+  }
+
+  ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
+  NewTL.setNameLoc(TL.getNameLoc());
+
+  return Result;
+}
+
+template<typename Derived>
+QualType TreeTransform<Derived>::TransformInjectedClassNameType(
+                                         TypeLocBuilder &TLB,
+                                         InjectedClassNameTypeLoc TL,
+                                         QualType ObjectType) {
+  Decl *D = getDerived().TransformDecl(TL.getNameLoc(),
+                                       TL.getTypePtr()->getDecl());
+  if (!D) return QualType();
+
+  QualType T = SemaRef.Context.getTypeDeclType(cast<TypeDecl>(D));
+  TLB.pushTypeSpec(T).setNameLoc(TL.getNameLoc());
+  return T;
+}
+
+
+template<typename Derived>
+QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
+                                                TypeLocBuilder &TLB,
+                                                TemplateTypeParmTypeLoc TL,
+                                                QualType ObjectType) {
+  return TransformTypeSpecType(TLB, TL);
+}
+
+template<typename Derived>
+QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmType(
+                                         TypeLocBuilder &TLB,
+                                         SubstTemplateTypeParmTypeLoc TL,
+                                         QualType ObjectType) {
+  return TransformTypeSpecType(TLB, TL);
+}
+
+template<typename Derived>
+QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
+                                      const TemplateSpecializationType *TST,
+                                                        QualType ObjectType) {
+  // FIXME: this entire method is a temporary workaround; callers
+  // should be rewritten to provide real type locs.
+
+  // Fake up a TemplateSpecializationTypeLoc.
+  TypeLocBuilder TLB;
+  TemplateSpecializationTypeLoc TL
+    = TLB.push<TemplateSpecializationTypeLoc>(QualType(TST, 0));
+
+  SourceLocation BaseLoc = getDerived().getBaseLocation();
+
+  TL.setTemplateNameLoc(BaseLoc);
+  TL.setLAngleLoc(BaseLoc);
+  TL.setRAngleLoc(BaseLoc);
+  for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) {
+    const TemplateArgument &TA = TST->getArg(i);
+    TemplateArgumentLoc TAL;
+    getDerived().InventTemplateArgumentLoc(TA, TAL);
+    TL.setArgLocInfo(i, TAL.getLocInfo());
+  }
+
+  TypeLocBuilder IgnoredTLB;
+  return TransformTemplateSpecializationType(IgnoredTLB, TL, ObjectType);
+}
+  
+template<typename Derived>
+QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
+                                                        TypeLocBuilder &TLB,
+                                           TemplateSpecializationTypeLoc TL,
+                                                        QualType ObjectType) {
+  const TemplateSpecializationType *T = TL.getTypePtr();
+
+  TemplateName Template
+    = getDerived().TransformTemplateName(T->getTemplateName(), ObjectType);
+  if (Template.isNull())
+    return QualType();
+
+  TemplateArgumentListInfo NewTemplateArgs;
+  NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
+  NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
+
+  for (unsigned i = 0, e = T->getNumArgs(); i != e; ++i) {
+    TemplateArgumentLoc Loc;
+    if (getDerived().TransformTemplateArgument(TL.getArgLoc(i), Loc))
+      return QualType();
+    NewTemplateArgs.addArgument(Loc);
+  }
+
+  // FIXME: maybe don't rebuild if all the template arguments are the same.
+
+  QualType Result =
+    getDerived().RebuildTemplateSpecializationType(Template,
+                                                   TL.getTemplateNameLoc(),
+                                                   NewTemplateArgs);
+
+  if (!Result.isNull()) {
+    TemplateSpecializationTypeLoc NewTL
+      = TLB.push<TemplateSpecializationTypeLoc>(Result);
+    NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
+    NewTL.setLAngleLoc(TL.getLAngleLoc());
+    NewTL.setRAngleLoc(TL.getRAngleLoc());
+    for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
+      NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo());
+  }
+
+  return Result;
+}
+
+template<typename Derived>
+QualType
+TreeTransform<Derived>::TransformQualifiedNameType(TypeLocBuilder &TLB,
+                                                   QualifiedNameTypeLoc TL,
+                                                   QualType ObjectType) {
+  QualifiedNameType *T = TL.getTypePtr();
+  NestedNameSpecifier *NNS
+    = getDerived().TransformNestedNameSpecifier(T->getQualifier(),
+                                                SourceRange(),
+                                                ObjectType);
+  if (!NNS)
+    return QualType();
+
+  QualType Named = getDerived().TransformType(T->getNamedType());
+  if (Named.isNull())
+    return QualType();
+
+  QualType Result = TL.getType();
+  if (getDerived().AlwaysRebuild() ||
+      NNS != T->getQualifier() ||
+      Named != T->getNamedType()) {
+    Result = getDerived().RebuildQualifiedNameType(NNS, Named);
+    if (Result.isNull())
+      return QualType();
+  }
+
+  QualifiedNameTypeLoc NewTL = TLB.push<QualifiedNameTypeLoc>(Result);
+  NewTL.setNameLoc(TL.getNameLoc());
+
+  return Result;
+}
+
+template<typename Derived>
+QualType TreeTransform<Derived>::TransformDependentNameType(TypeLocBuilder &TLB,
+                                                       DependentNameTypeLoc TL,
+                                                       QualType ObjectType) {
+  DependentNameType *T = TL.getTypePtr();
+
+  /* FIXME: preserve source information better than this */
+  SourceRange SR(TL.getNameLoc());
+
+  NestedNameSpecifier *NNS
+    = getDerived().TransformNestedNameSpecifier(T->getQualifier(), SR,
+                                                ObjectType);
+  if (!NNS)
+    return QualType();
+
+  QualType Result;
+
+  if (const TemplateSpecializationType *TemplateId = T->getTemplateId()) {
+    QualType NewTemplateId
+      = getDerived().TransformType(QualType(TemplateId, 0));
+    if (NewTemplateId.isNull())
+      return QualType();
+
+    if (!getDerived().AlwaysRebuild() &&
+        NNS == T->getQualifier() &&
+        NewTemplateId == QualType(TemplateId, 0))
+      return QualType(T, 0);
+
+    Result = getDerived().RebuildDependentNameType(T->getKeyword(), NNS, 
+                                                   NewTemplateId);
+  } else {
+    Result = getDerived().RebuildDependentNameType(T->getKeyword(), NNS, 
+                                                   T->getIdentifier(), SR);
+  }
+  if (Result.isNull())
+    return QualType();
+
+  DependentNameTypeLoc NewTL = TLB.push<DependentNameTypeLoc>(Result);
+  NewTL.setNameLoc(TL.getNameLoc());
+
+  return Result;
+}
+
+template<typename Derived>
+QualType
+TreeTransform<Derived>::TransformObjCInterfaceType(TypeLocBuilder &TLB,
+                                                   ObjCInterfaceTypeLoc TL,
+                                                   QualType ObjectType) {
+  // ObjCInterfaceType is never dependent.
+  return TL.getType();
+}
+
+template<typename Derived>
+QualType
+TreeTransform<Derived>::TransformObjCObjectPointerType(TypeLocBuilder &TLB,
+                                               ObjCObjectPointerTypeLoc TL,
+                                                       QualType ObjectType) {
+  // ObjCObjectPointerType is never dependent.
+  return TL.getType();
+}
+
+//===----------------------------------------------------------------------===//
+// Statement transformation
+//===----------------------------------------------------------------------===//
+template<typename Derived>
+Sema::OwningStmtResult
+TreeTransform<Derived>::TransformNullStmt(NullStmt *S) {
+  return SemaRef.Owned(S->Retain());
+}
+
+template<typename Derived>
+Sema::OwningStmtResult
+TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S) {
+  return getDerived().TransformCompoundStmt(S, false);
+}
+
+template<typename Derived>
+Sema::OwningStmtResult
+TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S,
+                                              bool IsStmtExpr) {
+  bool SubStmtChanged = false;
+  ASTOwningVector<&ActionBase::DeleteStmt> Statements(getSema());
+  for (CompoundStmt::body_iterator B = S->body_begin(), BEnd = S->body_end();
+       B != BEnd; ++B) {
+    OwningStmtResult Result = getDerived().TransformStmt(*B);
+    if (Result.isInvalid())
+      return getSema().StmtError();
+
+    SubStmtChanged = SubStmtChanged || Result.get() != *B;
+    Statements.push_back(Result.takeAs<Stmt>());
+  }
+
+  if (!getDerived().AlwaysRebuild() &&
+      !SubStmtChanged)
+    return SemaRef.Owned(S->Retain());
+
+  return getDerived().RebuildCompoundStmt(S->getLBracLoc(),
+                                          move_arg(Statements),
+                                          S->getRBracLoc(),
+                                          IsStmtExpr);
+}
+
+template<typename Derived>
+Sema::OwningStmtResult
+TreeTransform<Derived>::TransformCaseStmt(CaseStmt *S) {
+  OwningExprResult LHS(SemaRef), RHS(SemaRef);
+  {
+    // The case value expressions are not potentially evaluated.
+    EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
+
+    // Transform the left-hand case value.
+    LHS = getDerived().TransformExpr(S->getLHS());
+    if (LHS.isInvalid())
+      return SemaRef.StmtError();
+
+    // Transform the right-hand case value (for the GNU case-range extension).
+    RHS = getDerived().TransformExpr(S->getRHS());
+    if (RHS.isInvalid())
+      return SemaRef.StmtError();
+  }
+
+  // Build the case statement.
+  // Case statements are always rebuilt so that they will attached to their
+  // transformed switch statement.
+  OwningStmtResult Case = getDerived().RebuildCaseStmt(S->getCaseLoc(),
+                                                       move(LHS),
+                                                       S->getEllipsisLoc(),
+                                                       move(RHS),
+                                                       S->getColonLoc());
+  if (Case.isInvalid())
+    return SemaRef.StmtError();
+
+  // Transform the statement following the case
+  OwningStmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
+  if (SubStmt.isInvalid())
+    return SemaRef.StmtError();
+
+  // Attach the body to the case statement
+  return getDerived().RebuildCaseStmtBody(move(Case), move(SubStmt));
+}
+
+template<typename Derived>
+Sema::OwningStmtResult
+TreeTransform<Derived>::TransformDefaultStmt(DefaultStmt *S) {
+  // Transform the statement following the default case
+  OwningStmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
+  if (SubStmt.isInvalid())
+    return SemaRef.StmtError();
+
+  // Default statements are always rebuilt
+  return getDerived().RebuildDefaultStmt(S->getDefaultLoc(), S->getColonLoc(),
+                                         move(SubStmt));
+}
+
+template<typename Derived>
+Sema::OwningStmtResult
+TreeTransform<Derived>::TransformLabelStmt(LabelStmt *S) {
+  OwningStmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
+  if (SubStmt.isInvalid())
+    return SemaRef.StmtError();
+
+  // FIXME: Pass the real colon location in.
+  SourceLocation ColonLoc = SemaRef.PP.getLocForEndOfToken(S->getIdentLoc());
+  return getDerived().RebuildLabelStmt(S->getIdentLoc(), S->getID(), ColonLoc,
+                                       move(SubStmt));
+}
+
+template<typename Derived>
+Sema::OwningStmtResult
+TreeTransform<Derived>::TransformIfStmt(IfStmt *S) {
+  // Transform the condition
+  OwningExprResult Cond(SemaRef);
+  VarDecl *ConditionVar = 0;
+  if (S->getConditionVariable()) {
+    ConditionVar 
+      = cast_or_null<VarDecl>(
+                   getDerived().TransformDefinition(
+                                      S->getConditionVariable()->getLocation(),
+                                                    S->getConditionVariable()));
+    if (!ConditionVar)
+      return SemaRef.StmtError();
+  } else {
+    Cond = getDerived().TransformExpr(S->getCond());
+  
+    if (Cond.isInvalid())
+      return SemaRef.StmtError();
+  }
+  
+  Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond));
+
+  // Transform the "then" branch.
+  OwningStmtResult Then = getDerived().TransformStmt(S->getThen());
+  if (Then.isInvalid())
+    return SemaRef.StmtError();
+
+  // Transform the "else" branch.
+  OwningStmtResult Else = getDerived().TransformStmt(S->getElse());
+  if (Else.isInvalid())
+    return SemaRef.StmtError();
+
+  if (!getDerived().AlwaysRebuild() &&
+      FullCond->get() == S->getCond() &&
+      ConditionVar == S->getConditionVariable() &&
+      Then.get() == S->getThen() &&
+      Else.get() == S->getElse())
+    return SemaRef.Owned(S->Retain());
+
+  return getDerived().RebuildIfStmt(S->getIfLoc(), FullCond, ConditionVar,
+                                    move(Then),
+                                    S->getElseLoc(), move(Else));
+}
+
+template<typename Derived>
+Sema::OwningStmtResult
+TreeTransform<Derived>::TransformSwitchStmt(SwitchStmt *S) {
+  // Transform the condition.
+  OwningExprResult Cond(SemaRef);
+  VarDecl *ConditionVar = 0;
+  if (S->getConditionVariable()) {
+    ConditionVar 
+      = cast_or_null<VarDecl>(
+                   getDerived().TransformDefinition(
+                                      S->getConditionVariable()->getLocation(),
+                                                    S->getConditionVariable()));
+    if (!ConditionVar)
+      return SemaRef.StmtError();
+  } else {
+    Cond = getDerived().TransformExpr(S->getCond());
+    
+    if (Cond.isInvalid())
+      return SemaRef.StmtError();
+  }
+
+  Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond));
+  
+  // Rebuild the switch statement.
+  OwningStmtResult Switch = getDerived().RebuildSwitchStmtStart(FullCond,
+                                                                ConditionVar);
+  if (Switch.isInvalid())
+    return SemaRef.StmtError();
+
+  // Transform the body of the switch statement.
+  OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
+  if (Body.isInvalid())
+    return SemaRef.StmtError();
+
+  // Complete the switch statement.
+  return getDerived().RebuildSwitchStmtBody(S->getSwitchLoc(), move(Switch),
+                                            move(Body));
+}
+
+template<typename Derived>
+Sema::OwningStmtResult
+TreeTransform<Derived>::TransformWhileStmt(WhileStmt *S) {
+  // Transform the condition
+  OwningExprResult Cond(SemaRef);
+  VarDecl *ConditionVar = 0;
+  if (S->getConditionVariable()) {
+    ConditionVar 
+      = cast_or_null<VarDecl>(
+                   getDerived().TransformDefinition(
+                                      S->getConditionVariable()->getLocation(),
+                                                    S->getConditionVariable()));
+    if (!ConditionVar)
+      return SemaRef.StmtError();
+  } else {
+    Cond = getDerived().TransformExpr(S->getCond());
+    
+    if (Cond.isInvalid())
+      return SemaRef.StmtError();
+  }
+
+  Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond));
+
+  // Transform the body
+  OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
+  if (Body.isInvalid())
+    return SemaRef.StmtError();
+
+  if (!getDerived().AlwaysRebuild() &&
+      FullCond->get() == S->getCond() &&
+      ConditionVar == S->getConditionVariable() &&
+      Body.get() == S->getBody())
+    return SemaRef.Owned(S->Retain());
+
+  return getDerived().RebuildWhileStmt(S->getWhileLoc(), FullCond, ConditionVar,
+                                       move(Body));
+}
+
+template<typename Derived>
+Sema::OwningStmtResult
+TreeTransform<Derived>::TransformDoStmt(DoStmt *S) {
+  // Transform the condition
+  OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
+  if (Cond.isInvalid())
+    return SemaRef.StmtError();
+
+  // Transform the body
+  OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
+  if (Body.isInvalid())
+    return SemaRef.StmtError();
+
+  if (!getDerived().AlwaysRebuild() &&
+      Cond.get() == S->getCond() &&
+      Body.get() == S->getBody())
+    return SemaRef.Owned(S->Retain());
+
+  return getDerived().RebuildDoStmt(S->getDoLoc(), move(Body), S->getWhileLoc(),
+                                    /*FIXME:*/S->getWhileLoc(), move(Cond),
+                                    S->getRParenLoc());
+}
+
+template<typename Derived>
+Sema::OwningStmtResult
+TreeTransform<Derived>::TransformForStmt(ForStmt *S) {
+  // Transform the initialization statement
+  OwningStmtResult Init = getDerived().TransformStmt(S->getInit());
+  if (Init.isInvalid())
+    return SemaRef.StmtError();
+
+  // Transform the condition
+  OwningExprResult Cond(SemaRef);
+  VarDecl *ConditionVar = 0;
+  if (S->getConditionVariable()) {
+    ConditionVar 
+      = cast_or_null<VarDecl>(
+                   getDerived().TransformDefinition(
+                                      S->getConditionVariable()->getLocation(),
+                                                    S->getConditionVariable()));
+    if (!ConditionVar)
+      return SemaRef.StmtError();
+  } else {
+    Cond = getDerived().TransformExpr(S->getCond());
+    
+    if (Cond.isInvalid())
+      return SemaRef.StmtError();
+  }
+
+  // Transform the increment
+  OwningExprResult Inc = getDerived().TransformExpr(S->getInc());
+  if (Inc.isInvalid())
+    return SemaRef.StmtError();
+
+  // Transform the body
+  OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
+  if (Body.isInvalid())
+    return SemaRef.StmtError();
+
+  if (!getDerived().AlwaysRebuild() &&
+      Init.get() == S->getInit() &&
+      Cond.get() == S->getCond() &&
+      Inc.get() == S->getInc() &&
+      Body.get() == S->getBody())
+    return SemaRef.Owned(S->Retain());
+
+  return getDerived().RebuildForStmt(S->getForLoc(), S->getLParenLoc(),
+                                     move(Init), getSema().MakeFullExpr(Cond),
+                                     ConditionVar,
+                                     getSema().MakeFullExpr(Inc),
+                                     S->getRParenLoc(), move(Body));
+}
+
+template<typename Derived>
+Sema::OwningStmtResult
+TreeTransform<Derived>::TransformGotoStmt(GotoStmt *S) {
+  // Goto statements must always be rebuilt, to resolve the label.
+  return getDerived().RebuildGotoStmt(S->getGotoLoc(), S->getLabelLoc(),
+                                      S->getLabel());
+}
+
+template<typename Derived>
+Sema::OwningStmtResult
+TreeTransform<Derived>::TransformIndirectGotoStmt(IndirectGotoStmt *S) {
+  OwningExprResult Target = getDerived().TransformExpr(S->getTarget());
+  if (Target.isInvalid())
+    return SemaRef.StmtError();
+
+  if (!getDerived().AlwaysRebuild() &&
+      Target.get() == S->getTarget())
+    return SemaRef.Owned(S->Retain());
+
+  return getDerived().RebuildIndirectGotoStmt(S->getGotoLoc(), S->getStarLoc(),
+                                              move(Target));
+}
+
+template<typename Derived>
+Sema::OwningStmtResult
+TreeTransform<Derived>::TransformContinueStmt(ContinueStmt *S) {
+  return SemaRef.Owned(S->Retain());
+}
+
+template<typename Derived>
+Sema::OwningStmtResult
+TreeTransform<Derived>::TransformBreakStmt(BreakStmt *S) {
+  return SemaRef.Owned(S->Retain());
+}
+
+template<typename Derived>
+Sema::OwningStmtResult
+TreeTransform<Derived>::TransformReturnStmt(ReturnStmt *S) {
+  Sema::OwningExprResult Result = getDerived().TransformExpr(S->getRetValue());
+  if (Result.isInvalid())
+    return SemaRef.StmtError();
+
+  // FIXME: We always rebuild the return statement because there is no way
+  // to tell whether the return type of the function has changed.
+  return getDerived().RebuildReturnStmt(S->getReturnLoc(), move(Result));
+}
+
+template<typename Derived>
+Sema::OwningStmtResult
+TreeTransform<Derived>::TransformDeclStmt(DeclStmt *S) {
+  bool DeclChanged = false;
+  llvm::SmallVector<Decl *, 4> Decls;
+  for (DeclStmt::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
+       D != DEnd; ++D) {
+    Decl *Transformed = getDerived().TransformDefinition((*D)->getLocation(),
+                                                         *D);
+    if (!Transformed)
+      return SemaRef.StmtError();
+
+    if (Transformed != *D)
+      DeclChanged = true;
+
+    Decls.push_back(Transformed);
+  }
+
+  if (!getDerived().AlwaysRebuild() && !DeclChanged)
+    return SemaRef.Owned(S->Retain());
+
+  return getDerived().RebuildDeclStmt(Decls.data(), Decls.size(),
+                                      S->getStartLoc(), S->getEndLoc());
+}
+
+template<typename Derived>
+Sema::OwningStmtResult
+TreeTransform<Derived>::TransformSwitchCase(SwitchCase *S) {
+  assert(false && "SwitchCase is abstract and cannot be transformed");
+  return SemaRef.Owned(S->Retain());
+}
+
+template<typename Derived>
+Sema::OwningStmtResult
+TreeTransform<Derived>::TransformAsmStmt(AsmStmt *S) {
+  
+  ASTOwningVector<&ActionBase::DeleteExpr> Constraints(getSema());
+  ASTOwningVector<&ActionBase::DeleteExpr> Exprs(getSema());
+  llvm::SmallVector<IdentifierInfo *, 4> Names;
+
+  OwningExprResult AsmString(SemaRef);
+  ASTOwningVector<&ActionBase::DeleteExpr> Clobbers(getSema());
+
+  bool ExprsChanged = false;
+  
+  // Go through the outputs.
+  for (unsigned I = 0, E = S->getNumOutputs(); I != E; ++I) {
+    Names.push_back(S->getOutputIdentifier(I));
+    
+    // No need to transform the constraint literal.
+    Constraints.push_back(S->getOutputConstraintLiteral(I)->Retain());
+    
+    // Transform the output expr.
+    Expr *OutputExpr = S->getOutputExpr(I);
+    OwningExprResult Result = getDerived().TransformExpr(OutputExpr);
+    if (Result.isInvalid())
+      return SemaRef.StmtError();
+    
+    ExprsChanged |= Result.get() != OutputExpr;
+    
+    Exprs.push_back(Result.takeAs<Expr>());
+  }
+  
+  // Go through the inputs.
+  for (unsigned I = 0, E = S->getNumInputs(); I != E; ++I) {
+    Names.push_back(S->getInputIdentifier(I));
+    
+    // No need to transform the constraint literal.
+    Constraints.push_back(S->getInputConstraintLiteral(I)->Retain());
+    
+    // Transform the input expr.
+    Expr *InputExpr = S->getInputExpr(I);
+    OwningExprResult Result = getDerived().TransformExpr(InputExpr);
+    if (Result.isInvalid())
+      return SemaRef.StmtError();
+    
+    ExprsChanged |= Result.get() != InputExpr;
+    
+    Exprs.push_back(Result.takeAs<Expr>());
+  }
+  
+  if (!getDerived().AlwaysRebuild() && !ExprsChanged)
+    return SemaRef.Owned(S->Retain());
+
+  // Go through the clobbers.
+  for (unsigned I = 0, E = S->getNumClobbers(); I != E; ++I)
+    Clobbers.push_back(S->getClobber(I)->Retain());
+
+  // No need to transform the asm string literal.
+  AsmString = SemaRef.Owned(S->getAsmString());
+
+  return getDerived().RebuildAsmStmt(S->getAsmLoc(),
+                                     S->isSimple(),
+                                     S->isVolatile(),
+                                     S->getNumOutputs(),
+                                     S->getNumInputs(),
+                                     Names.data(),
+                                     move_arg(Constraints),
+                                     move_arg(Exprs),
+                                     move(AsmString),
+                                     move_arg(Clobbers),
+                                     S->getRParenLoc(),
+                                     S->isMSAsm());
+}
+
+
+template<typename Derived>
+Sema::OwningStmtResult
+TreeTransform<Derived>::TransformObjCAtTryStmt(ObjCAtTryStmt *S) {
+  // Transform the body of the @try.
+  OwningStmtResult TryBody = getDerived().TransformStmt(S->getTryBody());
+  if (TryBody.isInvalid())
+    return SemaRef.StmtError();
+  
+  // Transform the @catch statements (if present).
+  bool AnyCatchChanged = false;
+  ASTOwningVector<&ActionBase::DeleteStmt> CatchStmts(SemaRef);
+  for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I) {
+    OwningStmtResult Catch = getDerived().TransformStmt(S->getCatchStmt(I));
+    if (Catch.isInvalid())
+      return SemaRef.StmtError();
+    if (Catch.get() != S->getCatchStmt(I))
+      AnyCatchChanged = true;
+    CatchStmts.push_back(Catch.release());
+  }
+  
+  // Transform the @finally statement (if present).
+  OwningStmtResult Finally(SemaRef);
+  if (S->getFinallyStmt()) {
+    Finally = getDerived().TransformStmt(S->getFinallyStmt());
+    if (Finally.isInvalid())
+      return SemaRef.StmtError();
+  }
+
+  // If nothing changed, just retain this statement.
+  if (!getDerived().AlwaysRebuild() &&
+      TryBody.get() == S->getTryBody() &&
+      !AnyCatchChanged &&
+      Finally.get() == S->getFinallyStmt())
+    return SemaRef.Owned(S->Retain());
+  
+  // Build a new statement.
+  return getDerived().RebuildObjCAtTryStmt(S->getAtTryLoc(), move(TryBody),
+                                           move_arg(CatchStmts), move(Finally));
+}
+
+template<typename Derived>
+Sema::OwningStmtResult
+TreeTransform<Derived>::TransformObjCAtCatchStmt(ObjCAtCatchStmt *S) {
+  // Transform the @catch parameter, if there is one.
+  VarDecl *Var = 0;
+  if (VarDecl *FromVar = S->getCatchParamDecl()) {
+    TypeSourceInfo *TSInfo = 0;
+    if (FromVar->getTypeSourceInfo()) {
+      TSInfo = getDerived().TransformType(FromVar->getTypeSourceInfo());
+      if (!TSInfo)
+        return SemaRef.StmtError();
+    }
+    
+    QualType T;
+    if (TSInfo)
+      T = TSInfo->getType();
+    else {
+      T = getDerived().TransformType(FromVar->getType());
+      if (T.isNull())
+        return SemaRef.StmtError();        
+    }
+    
+    Var = getDerived().RebuildObjCExceptionDecl(FromVar, TSInfo, T);
+    if (!Var)
+      return SemaRef.StmtError();
+  }
+  
+  OwningStmtResult Body = getDerived().TransformStmt(S->getCatchBody());
+  if (Body.isInvalid())
+    return SemaRef.StmtError();
+  
+  return getDerived().RebuildObjCAtCatchStmt(S->getAtCatchLoc(), 
+                                             S->getRParenLoc(),
+                                             Var, move(Body));
+}
+
+template<typename Derived>
+Sema::OwningStmtResult
+TreeTransform<Derived>::TransformObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
+  // Transform the body.
+  OwningStmtResult Body = getDerived().TransformStmt(S->getFinallyBody());
+  if (Body.isInvalid())
+    return SemaRef.StmtError();
+  
+  // If nothing changed, just retain this statement.
+  if (!getDerived().AlwaysRebuild() &&
+      Body.get() == S->getFinallyBody())
+    return SemaRef.Owned(S->Retain());
+
+  // Build a new statement.
+  return getDerived().RebuildObjCAtFinallyStmt(S->getAtFinallyLoc(),
+                                               move(Body));
+}
+
+template<typename Derived>
+Sema::OwningStmtResult
+TreeTransform<Derived>::TransformObjCAtThrowStmt(ObjCAtThrowStmt *S) {
+  OwningExprResult Operand(SemaRef);
+  if (S->getThrowExpr()) {
+    Operand = getDerived().TransformExpr(S->getThrowExpr());
+    if (Operand.isInvalid())
+      return getSema().StmtError();
+  }
+  
+  if (!getDerived().AlwaysRebuild() &&
+      Operand.get() == S->getThrowExpr())
+    return getSema().Owned(S->Retain());
+    
+  return getDerived().RebuildObjCAtThrowStmt(S->getThrowLoc(), move(Operand));
+}
+
+template<typename Derived>
+Sema::OwningStmtResult
+TreeTransform<Derived>::TransformObjCAtSynchronizedStmt(
+                                                  ObjCAtSynchronizedStmt *S) {
+  // Transform the object we are locking.
+  OwningExprResult Object = getDerived().TransformExpr(S->getSynchExpr());
+  if (Object.isInvalid())
+    return SemaRef.StmtError();
+  
+  // Transform the body.
+  OwningStmtResult Body = getDerived().TransformStmt(S->getSynchBody());
+  if (Body.isInvalid())
+    return SemaRef.StmtError();
+  
+  // If nothing change, just retain the current statement.
+  if (!getDerived().AlwaysRebuild() &&
+      Object.get() == S->getSynchExpr() &&
+      Body.get() == S->getSynchBody())
+    return SemaRef.Owned(S->Retain());
+
+  // Build a new statement.
+  return getDerived().RebuildObjCAtSynchronizedStmt(S->getAtSynchronizedLoc(),
+                                                    move(Object), move(Body));
+}
+
+template<typename Derived>
+Sema::OwningStmtResult
+TreeTransform<Derived>::TransformObjCForCollectionStmt(
+                                                  ObjCForCollectionStmt *S) {
+  // Transform the element statement.
+  OwningStmtResult Element = getDerived().TransformStmt(S->getElement());
+  if (Element.isInvalid())
+    return SemaRef.StmtError();
+  
+  // Transform the collection expression.
+  OwningExprResult Collection = getDerived().TransformExpr(S->getCollection());
+  if (Collection.isInvalid())
+    return SemaRef.StmtError();
+  
+  // Transform the body.
+  OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
+  if (Body.isInvalid())
+    return SemaRef.StmtError();
+  
+  // If nothing changed, just retain this statement.
+  if (!getDerived().AlwaysRebuild() &&
+      Element.get() == S->getElement() &&
+      Collection.get() == S->getCollection() &&
+      Body.get() == S->getBody())
+    return SemaRef.Owned(S->Retain());
+  
+  // Build a new statement.
+  return getDerived().RebuildObjCForCollectionStmt(S->getForLoc(),
+                                                   /*FIXME:*/S->getForLoc(),
+                                                   move(Element),
+                                                   move(Collection),
+                                                   S->getRParenLoc(),
+                                                   move(Body));
+}
+
+
+template<typename Derived>
+Sema::OwningStmtResult
+TreeTransform<Derived>::TransformCXXCatchStmt(CXXCatchStmt *S) {
+  // Transform the exception declaration, if any.
+  VarDecl *Var = 0;
+  if (S->getExceptionDecl()) {
+    VarDecl *ExceptionDecl = S->getExceptionDecl();
+    TemporaryBase Rebase(*this, ExceptionDecl->getLocation(),
+                         ExceptionDecl->getDeclName());
+
+    QualType T = getDerived().TransformType(ExceptionDecl->getType());
+    if (T.isNull())
+      return SemaRef.StmtError();
+
+    Var = getDerived().RebuildExceptionDecl(ExceptionDecl,
+                                            T,
+                                            ExceptionDecl->getTypeSourceInfo(),
+                                            ExceptionDecl->getIdentifier(),
+                                            ExceptionDecl->getLocation(),
+                                            /*FIXME: Inaccurate*/
+                                    SourceRange(ExceptionDecl->getLocation()));
+    if (!Var || Var->isInvalidDecl()) {
+      if (Var)
+        Var->Destroy(SemaRef.Context);
+      return SemaRef.StmtError();
+    }
+  }
+
+  // Transform the actual exception handler.
+  OwningStmtResult Handler = getDerived().TransformStmt(S->getHandlerBlock());
+  if (Handler.isInvalid()) {
+    if (Var)
+      Var->Destroy(SemaRef.Context);
+    return SemaRef.StmtError();
+  }
+
+  if (!getDerived().AlwaysRebuild() &&
+      !Var &&
+      Handler.get() == S->getHandlerBlock())
+    return SemaRef.Owned(S->Retain());
+
+  return getDerived().RebuildCXXCatchStmt(S->getCatchLoc(),
+                                          Var,
+                                          move(Handler));
+}
+
+template<typename Derived>
+Sema::OwningStmtResult
+TreeTransform<Derived>::TransformCXXTryStmt(CXXTryStmt *S) {
+  // Transform the try block itself.
+  OwningStmtResult TryBlock
+    = getDerived().TransformCompoundStmt(S->getTryBlock());
+  if (TryBlock.isInvalid())
+    return SemaRef.StmtError();
+
+  // Transform the handlers.
+  bool HandlerChanged = false;
+  ASTOwningVector<&ActionBase::DeleteStmt> Handlers(SemaRef);
+  for (unsigned I = 0, N = S->getNumHandlers(); I != N; ++I) {
+    OwningStmtResult Handler
+      = getDerived().TransformCXXCatchStmt(S->getHandler(I));
+    if (Handler.isInvalid())
+      return SemaRef.StmtError();
+
+    HandlerChanged = HandlerChanged || Handler.get() != S->getHandler(I);
+    Handlers.push_back(Handler.takeAs<Stmt>());
+  }
+
+  if (!getDerived().AlwaysRebuild() &&
+      TryBlock.get() == S->getTryBlock() &&
+      !HandlerChanged)
+    return SemaRef.Owned(S->Retain());
+
+  return getDerived().RebuildCXXTryStmt(S->getTryLoc(), move(TryBlock),
+                                        move_arg(Handlers));
+}
+
+//===----------------------------------------------------------------------===//
+// Expression transformation
+//===----------------------------------------------------------------------===//
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformPredefinedExpr(PredefinedExpr *E) {
+  return SemaRef.Owned(E->Retain());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformDeclRefExpr(DeclRefExpr *E) {
+  NestedNameSpecifier *Qualifier = 0;
+  if (E->getQualifier()) {
+    Qualifier = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
+                                                       E->getQualifierRange());
+    if (!Qualifier)
+      return SemaRef.ExprError();
+  }
+
+  ValueDecl *ND
+    = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getLocation(),
+                                                         E->getDecl()));
+  if (!ND)
+    return SemaRef.ExprError();
+
+  if (!getDerived().AlwaysRebuild() && 
+      Qualifier == E->getQualifier() &&
+      ND == E->getDecl() &&
+      !E->hasExplicitTemplateArgumentList()) {
+
+    // Mark it referenced in the new context regardless.
+    // FIXME: this is a bit instantiation-specific.
+    SemaRef.MarkDeclarationReferenced(E->getLocation(), ND);
+
+    return SemaRef.Owned(E->Retain());
+  }
+
+  TemplateArgumentListInfo TransArgs, *TemplateArgs = 0;
+  if (E->hasExplicitTemplateArgumentList()) {
+    TemplateArgs = &TransArgs;
+    TransArgs.setLAngleLoc(E->getLAngleLoc());
+    TransArgs.setRAngleLoc(E->getRAngleLoc());
+    for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
+      TemplateArgumentLoc Loc;
+      if (getDerived().TransformTemplateArgument(E->getTemplateArgs()[I], Loc))
+        return SemaRef.ExprError();
+      TransArgs.addArgument(Loc);
+    }
+  }
+
+  return getDerived().RebuildDeclRefExpr(Qualifier, E->getQualifierRange(),
+                                         ND, E->getLocation(), TemplateArgs);
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformIntegerLiteral(IntegerLiteral *E) {
+  return SemaRef.Owned(E->Retain());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformFloatingLiteral(FloatingLiteral *E) {
+  return SemaRef.Owned(E->Retain());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformImaginaryLiteral(ImaginaryLiteral *E) {
+  return SemaRef.Owned(E->Retain());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformStringLiteral(StringLiteral *E) {
+  return SemaRef.Owned(E->Retain());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformCharacterLiteral(CharacterLiteral *E) {
+  return SemaRef.Owned(E->Retain());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformParenExpr(ParenExpr *E) {
+  OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
+  if (SubExpr.isInvalid())
+    return SemaRef.ExprError();
+
+  if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
+    return SemaRef.Owned(E->Retain());
+
+  return getDerived().RebuildParenExpr(move(SubExpr), E->getLParen(),
+                                       E->getRParen());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformUnaryOperator(UnaryOperator *E) {
+  OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
+  if (SubExpr.isInvalid())
+    return SemaRef.ExprError();
+
+  if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
+    return SemaRef.Owned(E->Retain());
+
+  return getDerived().RebuildUnaryOperator(E->getOperatorLoc(),
+                                           E->getOpcode(),
+                                           move(SubExpr));
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) {
+  if (E->isArgumentType()) {
+    TypeSourceInfo *OldT = E->getArgumentTypeInfo();
+
+    TypeSourceInfo *NewT = getDerived().TransformType(OldT);
+    if (!NewT)
+      return SemaRef.ExprError();
+
+    if (!getDerived().AlwaysRebuild() && OldT == NewT)
+      return SemaRef.Owned(E->Retain());
+
+    return getDerived().RebuildSizeOfAlignOf(NewT, E->getOperatorLoc(),
+                                             E->isSizeOf(),
+                                             E->getSourceRange());
+  }
+
+  Sema::OwningExprResult SubExpr(SemaRef);
+  {
+    // C++0x [expr.sizeof]p1:
+    //   The operand is either an expression, which is an unevaluated operand
+    //   [...]
+    EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
+
+    SubExpr = getDerived().TransformExpr(E->getArgumentExpr());
+    if (SubExpr.isInvalid())
+      return SemaRef.ExprError();
+
+    if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getArgumentExpr())
+      return SemaRef.Owned(E->Retain());
+  }
+
+  return getDerived().RebuildSizeOfAlignOf(move(SubExpr), E->getOperatorLoc(),
+                                           E->isSizeOf(),
+                                           E->getSourceRange());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformArraySubscriptExpr(ArraySubscriptExpr *E) {
+  OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
+  if (LHS.isInvalid())
+    return SemaRef.ExprError();
+
+  OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
+  if (RHS.isInvalid())
+    return SemaRef.ExprError();
+
+
+  if (!getDerived().AlwaysRebuild() &&
+      LHS.get() == E->getLHS() &&
+      RHS.get() == E->getRHS())
+    return SemaRef.Owned(E->Retain());
+
+  return getDerived().RebuildArraySubscriptExpr(move(LHS),
+                                           /*FIXME:*/E->getLHS()->getLocStart(),
+                                                move(RHS),
+                                                E->getRBracketLoc());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformCallExpr(CallExpr *E) {
+  // Transform the callee.
+  OwningExprResult Callee = getDerived().TransformExpr(E->getCallee());
+  if (Callee.isInvalid())
+    return SemaRef.ExprError();
+
+  // Transform arguments.
+  bool ArgChanged = false;
+  ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
+  llvm::SmallVector<SourceLocation, 4> FakeCommaLocs;
+  for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
+    OwningExprResult Arg = getDerived().TransformExpr(E->getArg(I));
+    if (Arg.isInvalid())
+      return SemaRef.ExprError();
+
+    // FIXME: Wrong source location information for the ','.
+    FakeCommaLocs.push_back(
+       SemaRef.PP.getLocForEndOfToken(E->getArg(I)->getSourceRange().getEnd()));
+
+    ArgChanged = ArgChanged || Arg.get() != E->getArg(I);
+    Args.push_back(Arg.takeAs<Expr>());
+  }
+
+  if (!getDerived().AlwaysRebuild() &&
+      Callee.get() == E->getCallee() &&
+      !ArgChanged)
+    return SemaRef.Owned(E->Retain());
+
+  // FIXME: Wrong source location information for the '('.
+  SourceLocation FakeLParenLoc
+    = ((Expr *)Callee.get())->getSourceRange().getBegin();
+  return getDerived().RebuildCallExpr(move(Callee), FakeLParenLoc,
+                                      move_arg(Args),
+                                      FakeCommaLocs.data(),
+                                      E->getRParenLoc());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) {
+  OwningExprResult Base = getDerived().TransformExpr(E->getBase());
+  if (Base.isInvalid())
+    return SemaRef.ExprError();
+
+  NestedNameSpecifier *Qualifier = 0;
+  if (E->hasQualifier()) {
+    Qualifier
+      = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
+                                                  E->getQualifierRange());
+    if (Qualifier == 0)
+      return SemaRef.ExprError();
+  }
+
+  ValueDecl *Member
+    = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getMemberLoc(),
+                                                         E->getMemberDecl()));
+  if (!Member)
+    return SemaRef.ExprError();
+
+  NamedDecl *FoundDecl = E->getFoundDecl();
+  if (FoundDecl == E->getMemberDecl()) {
+    FoundDecl = Member;
+  } else {
+    FoundDecl = cast_or_null<NamedDecl>(
+                   getDerived().TransformDecl(E->getMemberLoc(), FoundDecl));
+    if (!FoundDecl)
+      return SemaRef.ExprError();
+  }
+
+  if (!getDerived().AlwaysRebuild() &&
+      Base.get() == E->getBase() &&
+      Qualifier == E->getQualifier() &&
+      Member == E->getMemberDecl() &&
+      FoundDecl == E->getFoundDecl() &&
+      !E->hasExplicitTemplateArgumentList()) {
+    
+    // Mark it referenced in the new context regardless.
+    // FIXME: this is a bit instantiation-specific.
+    SemaRef.MarkDeclarationReferenced(E->getMemberLoc(), Member);
+    return SemaRef.Owned(E->Retain());
+  }
+
+  TemplateArgumentListInfo TransArgs;
+  if (E->hasExplicitTemplateArgumentList()) {
+    TransArgs.setLAngleLoc(E->getLAngleLoc());
+    TransArgs.setRAngleLoc(E->getRAngleLoc());
+    for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
+      TemplateArgumentLoc Loc;
+      if (getDerived().TransformTemplateArgument(E->getTemplateArgs()[I], Loc))
+        return SemaRef.ExprError();
+      TransArgs.addArgument(Loc);
+    }
+  }
+  
+  // FIXME: Bogus source location for the operator
+  SourceLocation FakeOperatorLoc
+    = SemaRef.PP.getLocForEndOfToken(E->getBase()->getSourceRange().getEnd());
+
+  // FIXME: to do this check properly, we will need to preserve the
+  // first-qualifier-in-scope here, just in case we had a dependent
+  // base (and therefore couldn't do the check) and a
+  // nested-name-qualifier (and therefore could do the lookup).
+  NamedDecl *FirstQualifierInScope = 0;
+
+  return getDerived().RebuildMemberExpr(move(Base), FakeOperatorLoc,
+                                        E->isArrow(),
+                                        Qualifier,
+                                        E->getQualifierRange(),
+                                        E->getMemberLoc(),
+                                        Member,
+                                        FoundDecl,
+                                        (E->hasExplicitTemplateArgumentList()
+                                           ? &TransArgs : 0),
+                                        FirstQualifierInScope);
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformBinaryOperator(BinaryOperator *E) {
+  OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
+  if (LHS.isInvalid())
+    return SemaRef.ExprError();
+
+  OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
+  if (RHS.isInvalid())
+    return SemaRef.ExprError();
+
+  if (!getDerived().AlwaysRebuild() &&
+      LHS.get() == E->getLHS() &&
+      RHS.get() == E->getRHS())
+    return SemaRef.Owned(E->Retain());
+
+  return getDerived().RebuildBinaryOperator(E->getOperatorLoc(), E->getOpcode(),
+                                            move(LHS), move(RHS));
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformCompoundAssignOperator(
+                                                      CompoundAssignOperator *E) {
+  return getDerived().TransformBinaryOperator(E);
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformConditionalOperator(ConditionalOperator *E) {
+  OwningExprResult Cond = getDerived().TransformExpr(E->getCond());
+  if (Cond.isInvalid())
+    return SemaRef.ExprError();
+
+  OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
+  if (LHS.isInvalid())
+    return SemaRef.ExprError();
+
+  OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
+  if (RHS.isInvalid())
+    return SemaRef.ExprError();
+
+  if (!getDerived().AlwaysRebuild() &&
+      Cond.get() == E->getCond() &&
+      LHS.get() == E->getLHS() &&
+      RHS.get() == E->getRHS())
+    return SemaRef.Owned(E->Retain());
+
+  return getDerived().RebuildConditionalOperator(move(Cond),
+                                                 E->getQuestionLoc(),
+                                                 move(LHS),
+                                                 E->getColonLoc(),
+                                                 move(RHS));
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformImplicitCastExpr(ImplicitCastExpr *E) {
+  // Implicit casts are eliminated during transformation, since they
+  // will be recomputed by semantic analysis after transformation.
+  return getDerived().TransformExpr(E->getSubExprAsWritten());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformCStyleCastExpr(CStyleCastExpr *E) {
+  TypeSourceInfo *OldT;
+  TypeSourceInfo *NewT;
+  {
+    // FIXME: Source location isn't quite accurate.
+    SourceLocation TypeStartLoc
+      = SemaRef.PP.getLocForEndOfToken(E->getLParenLoc());
+    TemporaryBase Rebase(*this, TypeStartLoc, DeclarationName());
+
+    OldT = E->getTypeInfoAsWritten();
+    NewT = getDerived().TransformType(OldT);
+    if (!NewT)
+      return SemaRef.ExprError();
+  }
+
+  OwningExprResult SubExpr
+    = getDerived().TransformExpr(E->getSubExprAsWritten());
+  if (SubExpr.isInvalid())
+    return SemaRef.ExprError();
+
+  if (!getDerived().AlwaysRebuild() &&
+      OldT == NewT &&
+      SubExpr.get() == E->getSubExpr())
+    return SemaRef.Owned(E->Retain());
+
+  return getDerived().RebuildCStyleCastExpr(E->getLParenLoc(),
+                                            NewT,
+                                            E->getRParenLoc(),
+                                            move(SubExpr));
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformCompoundLiteralExpr(CompoundLiteralExpr *E) {
+  TypeSourceInfo *OldT = E->getTypeSourceInfo();
+  TypeSourceInfo *NewT = getDerived().TransformType(OldT);
+  if (!NewT)
+    return SemaRef.ExprError();
+
+  OwningExprResult Init = getDerived().TransformExpr(E->getInitializer());
+  if (Init.isInvalid())
+    return SemaRef.ExprError();
+
+  if (!getDerived().AlwaysRebuild() &&
+      OldT == NewT &&
+      Init.get() == E->getInitializer())
+    return SemaRef.Owned(E->Retain());
+
+  // Note: the expression type doesn't necessarily match the
+  // type-as-written, but that's okay, because it should always be
+  // derivable from the initializer.
+
+  return getDerived().RebuildCompoundLiteralExpr(E->getLParenLoc(), NewT,
+                                   /*FIXME:*/E->getInitializer()->getLocEnd(),
+                                                 move(Init));
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformExtVectorElementExpr(ExtVectorElementExpr *E) {
+  OwningExprResult Base = getDerived().TransformExpr(E->getBase());
+  if (Base.isInvalid())
+    return SemaRef.ExprError();
+
+  if (!getDerived().AlwaysRebuild() &&
+      Base.get() == E->getBase())
+    return SemaRef.Owned(E->Retain());
+
+  // FIXME: Bad source location
+  SourceLocation FakeOperatorLoc
+    = SemaRef.PP.getLocForEndOfToken(E->getBase()->getLocEnd());
+  return getDerived().RebuildExtVectorElementExpr(move(Base), FakeOperatorLoc,
+                                                  E->getAccessorLoc(),
+                                                  E->getAccessor());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformInitListExpr(InitListExpr *E) {
+  bool InitChanged = false;
+
+  ASTOwningVector<&ActionBase::DeleteExpr, 4> Inits(SemaRef);
+  for (unsigned I = 0, N = E->getNumInits(); I != N; ++I) {
+    OwningExprResult Init = getDerived().TransformExpr(E->getInit(I));
+    if (Init.isInvalid())
+      return SemaRef.ExprError();
+
+    InitChanged = InitChanged || Init.get() != E->getInit(I);
+    Inits.push_back(Init.takeAs<Expr>());
+  }
+
+  if (!getDerived().AlwaysRebuild() && !InitChanged)
+    return SemaRef.Owned(E->Retain());
+
+  return getDerived().RebuildInitList(E->getLBraceLoc(), move_arg(Inits),
+                                      E->getRBraceLoc(), E->getType());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E) {
+  Designation Desig;
+
+  // transform the initializer value
+  OwningExprResult Init = getDerived().TransformExpr(E->getInit());
+  if (Init.isInvalid())
+    return SemaRef.ExprError();
+
+  // transform the designators.
+  ASTOwningVector<&ActionBase::DeleteExpr, 4> ArrayExprs(SemaRef);
+  bool ExprChanged = false;
+  for (DesignatedInitExpr::designators_iterator D = E->designators_begin(),
+                                             DEnd = E->designators_end();
+       D != DEnd; ++D) {
+    if (D->isFieldDesignator()) {
+      Desig.AddDesignator(Designator::getField(D->getFieldName(),
+                                               D->getDotLoc(),
+                                               D->getFieldLoc()));
+      continue;
+    }
+
+    if (D->isArrayDesignator()) {
+      OwningExprResult Index = getDerived().TransformExpr(E->getArrayIndex(*D));
+      if (Index.isInvalid())
+        return SemaRef.ExprError();
+
+      Desig.AddDesignator(Designator::getArray(Index.get(),
+                                               D->getLBracketLoc()));
+
+      ExprChanged = ExprChanged || Init.get() != E->getArrayIndex(*D);
+      ArrayExprs.push_back(Index.release());
+      continue;
+    }
+
+    assert(D->isArrayRangeDesignator() && "New kind of designator?");
+    OwningExprResult Start
+      = getDerived().TransformExpr(E->getArrayRangeStart(*D));
+    if (Start.isInvalid())
+      return SemaRef.ExprError();
+
+    OwningExprResult End = getDerived().TransformExpr(E->getArrayRangeEnd(*D));
+    if (End.isInvalid())
+      return SemaRef.ExprError();
+
+    Desig.AddDesignator(Designator::getArrayRange(Start.get(),
+                                                  End.get(),
+                                                  D->getLBracketLoc(),
+                                                  D->getEllipsisLoc()));
+
+    ExprChanged = ExprChanged || Start.get() != E->getArrayRangeStart(*D) ||
+      End.get() != E->getArrayRangeEnd(*D);
+
+    ArrayExprs.push_back(Start.release());
+    ArrayExprs.push_back(End.release());
+  }
+
+  if (!getDerived().AlwaysRebuild() &&
+      Init.get() == E->getInit() &&
+      !ExprChanged)
+    return SemaRef.Owned(E->Retain());
+
+  return getDerived().RebuildDesignatedInitExpr(Desig, move_arg(ArrayExprs),
+                                                E->getEqualOrColonLoc(),
+                                                E->usesGNUSyntax(), move(Init));
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformImplicitValueInitExpr(
+                                                     ImplicitValueInitExpr *E) {
+  TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
+  
+  // FIXME: Will we ever have proper type location here? Will we actually
+  // need to transform the type?
+  QualType T = getDerived().TransformType(E->getType());
+  if (T.isNull())
+    return SemaRef.ExprError();
+
+  if (!getDerived().AlwaysRebuild() &&
+      T == E->getType())
+    return SemaRef.Owned(E->Retain());
+
+  return getDerived().RebuildImplicitValueInitExpr(T);
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformVAArgExpr(VAArgExpr *E) {
+  // FIXME: Do we want the type as written?
+  QualType T;
+
+  {
+    // FIXME: Source location isn't quite accurate.
+    TemporaryBase Rebase(*this, E->getBuiltinLoc(), DeclarationName());
+    T = getDerived().TransformType(E->getType());
+    if (T.isNull())
+      return SemaRef.ExprError();
+  }
+
+  OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
+  if (SubExpr.isInvalid())
+    return SemaRef.ExprError();
+
+  if (!getDerived().AlwaysRebuild() &&
+      T == E->getType() &&
+      SubExpr.get() == E->getSubExpr())
+    return SemaRef.Owned(E->Retain());
+
+  return getDerived().RebuildVAArgExpr(E->getBuiltinLoc(), move(SubExpr),
+                                       T, E->getRParenLoc());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformParenListExpr(ParenListExpr *E) {
+  bool ArgumentChanged = false;
+  ASTOwningVector<&ActionBase::DeleteExpr, 4> Inits(SemaRef);
+  for (unsigned I = 0, N = E->getNumExprs(); I != N; ++I) {
+    OwningExprResult Init = getDerived().TransformExpr(E->getExpr(I));
+    if (Init.isInvalid())
+      return SemaRef.ExprError();
+
+    ArgumentChanged = ArgumentChanged || Init.get() != E->getExpr(I);
+    Inits.push_back(Init.takeAs<Expr>());
+  }
+
+  return getDerived().RebuildParenListExpr(E->getLParenLoc(),
+                                           move_arg(Inits),
+                                           E->getRParenLoc());
+}
+
+/// \brief Transform an address-of-label expression.
+///
+/// By default, the transformation of an address-of-label expression always
+/// rebuilds the expression, so that the label identifier can be resolved to
+/// the corresponding label statement by semantic analysis.
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformAddrLabelExpr(AddrLabelExpr *E) {
+  return getDerived().RebuildAddrLabelExpr(E->getAmpAmpLoc(), E->getLabelLoc(),
+                                           E->getLabel());
+}
+
+template<typename Derived>
+Sema::OwningExprResult 
+TreeTransform<Derived>::TransformStmtExpr(StmtExpr *E) {
+  OwningStmtResult SubStmt
+    = getDerived().TransformCompoundStmt(E->getSubStmt(), true);
+  if (SubStmt.isInvalid())
+    return SemaRef.ExprError();
+
+  if (!getDerived().AlwaysRebuild() &&
+      SubStmt.get() == E->getSubStmt())
+    return SemaRef.Owned(E->Retain());
+
+  return getDerived().RebuildStmtExpr(E->getLParenLoc(),
+                                      move(SubStmt),
+                                      E->getRParenLoc());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformTypesCompatibleExpr(TypesCompatibleExpr *E) {
+  QualType T1, T2;
+  {
+    // FIXME: Source location isn't quite accurate.
+    TemporaryBase Rebase(*this, E->getBuiltinLoc(), DeclarationName());
+
+    T1 = getDerived().TransformType(E->getArgType1());
+    if (T1.isNull())
+      return SemaRef.ExprError();
+
+    T2 = getDerived().TransformType(E->getArgType2());
+    if (T2.isNull())
+      return SemaRef.ExprError();
+  }
+
+  if (!getDerived().AlwaysRebuild() &&
+      T1 == E->getArgType1() &&
+      T2 == E->getArgType2())
+    return SemaRef.Owned(E->Retain());
+
+  return getDerived().RebuildTypesCompatibleExpr(E->getBuiltinLoc(),
+                                                 T1, T2, E->getRParenLoc());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformChooseExpr(ChooseExpr *E) {
+  OwningExprResult Cond = getDerived().TransformExpr(E->getCond());
+  if (Cond.isInvalid())
+    return SemaRef.ExprError();
+
+  OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
+  if (LHS.isInvalid())
+    return SemaRef.ExprError();
+
+  OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
+  if (RHS.isInvalid())
+    return SemaRef.ExprError();
+
+  if (!getDerived().AlwaysRebuild() &&
+      Cond.get() == E->getCond() &&
+      LHS.get() == E->getLHS() &&
+      RHS.get() == E->getRHS())
+    return SemaRef.Owned(E->Retain());
+
+  return getDerived().RebuildChooseExpr(E->getBuiltinLoc(),
+                                        move(Cond), move(LHS), move(RHS),
+                                        E->getRParenLoc());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformGNUNullExpr(GNUNullExpr *E) {
+  return SemaRef.Owned(E->Retain());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
+  switch (E->getOperator()) {
+  case OO_New:
+  case OO_Delete:
+  case OO_Array_New:
+  case OO_Array_Delete:
+    llvm_unreachable("new and delete operators cannot use CXXOperatorCallExpr");
+    return SemaRef.ExprError();
+    
+  case OO_Call: {
+    // This is a call to an object's operator().
+    assert(E->getNumArgs() >= 1 && "Object call is missing arguments");
+
+    // Transform the object itself.
+    OwningExprResult Object = getDerived().TransformExpr(E->getArg(0));
+    if (Object.isInvalid())
+      return SemaRef.ExprError();
+
+    // FIXME: Poor location information
+    SourceLocation FakeLParenLoc
+      = SemaRef.PP.getLocForEndOfToken(
+                              static_cast<Expr *>(Object.get())->getLocEnd());
+
+    // Transform the call arguments.
+    ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
+    llvm::SmallVector<SourceLocation, 4> FakeCommaLocs;
+    for (unsigned I = 1, N = E->getNumArgs(); I != N; ++I) {
+      if (getDerived().DropCallArgument(E->getArg(I)))
+        break;
+      
+      OwningExprResult Arg = getDerived().TransformExpr(E->getArg(I));
+      if (Arg.isInvalid())
+        return SemaRef.ExprError();
+
+      // FIXME: Poor source location information.
+      SourceLocation FakeCommaLoc
+        = SemaRef.PP.getLocForEndOfToken(
+                                 static_cast<Expr *>(Arg.get())->getLocEnd());
+      FakeCommaLocs.push_back(FakeCommaLoc);
+      Args.push_back(Arg.release());
+    }
+
+    return getDerived().RebuildCallExpr(move(Object), FakeLParenLoc,
+                                        move_arg(Args),
+                                        FakeCommaLocs.data(),
+                                        E->getLocEnd());
+  }
+
+#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
+  case OO_##Name:
+#define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly)
+#include "clang/Basic/OperatorKinds.def"
+  case OO_Subscript:
+    // Handled below.
+    break;
+
+  case OO_Conditional:
+    llvm_unreachable("conditional operator is not actually overloadable");
+    return SemaRef.ExprError();
+
+  case OO_None:
+  case NUM_OVERLOADED_OPERATORS:
+    llvm_unreachable("not an overloaded operator?");
+    return SemaRef.ExprError();
+  }
+
+  OwningExprResult Callee = getDerived().TransformExpr(E->getCallee());
+  if (Callee.isInvalid())
+    return SemaRef.ExprError();
+
+  OwningExprResult First = getDerived().TransformExpr(E->getArg(0));
+  if (First.isInvalid())
+    return SemaRef.ExprError();
+
+  OwningExprResult Second(SemaRef);
+  if (E->getNumArgs() == 2) {
+    Second = getDerived().TransformExpr(E->getArg(1));
+    if (Second.isInvalid())
+      return SemaRef.ExprError();
+  }
+
+  if (!getDerived().AlwaysRebuild() &&
+      Callee.get() == E->getCallee() &&
+      First.get() == E->getArg(0) &&
+      (E->getNumArgs() != 2 || Second.get() == E->getArg(1)))
+    return SemaRef.Owned(E->Retain());
+
+  return getDerived().RebuildCXXOperatorCallExpr(E->getOperator(),
+                                                 E->getOperatorLoc(),
+                                                 move(Callee),
+                                                 move(First),
+                                                 move(Second));
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformCXXMemberCallExpr(CXXMemberCallExpr *E) {
+  return getDerived().TransformCallExpr(E);
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformCXXNamedCastExpr(CXXNamedCastExpr *E) {
+  TypeSourceInfo *OldT;
+  TypeSourceInfo *NewT;
+  {
+    // FIXME: Source location isn't quite accurate.
+    SourceLocation TypeStartLoc
+      = SemaRef.PP.getLocForEndOfToken(E->getOperatorLoc());
+    TemporaryBase Rebase(*this, TypeStartLoc, DeclarationName());
+
+    OldT = E->getTypeInfoAsWritten();
+    NewT = getDerived().TransformType(OldT);
+    if (!NewT)
+      return SemaRef.ExprError();
+  }
+
+  OwningExprResult SubExpr
+    = getDerived().TransformExpr(E->getSubExprAsWritten());
+  if (SubExpr.isInvalid())
+    return SemaRef.ExprError();
+
+  if (!getDerived().AlwaysRebuild() &&
+      OldT == NewT &&
+      SubExpr.get() == E->getSubExpr())
+    return SemaRef.Owned(E->Retain());
+
+  // FIXME: Poor source location information here.
+  SourceLocation FakeLAngleLoc
+    = SemaRef.PP.getLocForEndOfToken(E->getOperatorLoc());
+  SourceLocation FakeRAngleLoc = E->getSubExpr()->getSourceRange().getBegin();
+  SourceLocation FakeRParenLoc
+    = SemaRef.PP.getLocForEndOfToken(
+                                  E->getSubExpr()->getSourceRange().getEnd());
+  return getDerived().RebuildCXXNamedCastExpr(E->getOperatorLoc(),
+                                              E->getStmtClass(),
+                                              FakeLAngleLoc,
+                                              NewT,
+                                              FakeRAngleLoc,
+                                              FakeRAngleLoc,
+                                              move(SubExpr),
+                                              FakeRParenLoc);
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformCXXStaticCastExpr(CXXStaticCastExpr *E) {
+  return getDerived().TransformCXXNamedCastExpr(E);
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
+  return getDerived().TransformCXXNamedCastExpr(E);
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformCXXReinterpretCastExpr(
+                                                      CXXReinterpretCastExpr *E) {
+  return getDerived().TransformCXXNamedCastExpr(E);
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformCXXConstCastExpr(CXXConstCastExpr *E) {
+  return getDerived().TransformCXXNamedCastExpr(E);
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformCXXFunctionalCastExpr(
+                                                     CXXFunctionalCastExpr *E) {
+  TypeSourceInfo *OldT;
+  TypeSourceInfo *NewT;
+  {
+    TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
+
+    OldT = E->getTypeInfoAsWritten();
+    NewT = getDerived().TransformType(OldT);
+    if (!NewT)
+      return SemaRef.ExprError();
+  }
+
+  OwningExprResult SubExpr
+    = getDerived().TransformExpr(E->getSubExprAsWritten());
+  if (SubExpr.isInvalid())
+    return SemaRef.ExprError();
+
+  if (!getDerived().AlwaysRebuild() &&
+      OldT == NewT &&
+      SubExpr.get() == E->getSubExpr())
+    return SemaRef.Owned(E->Retain());
+
+  // FIXME: The end of the type's source range is wrong
+  return getDerived().RebuildCXXFunctionalCastExpr(
+                                  /*FIXME:*/SourceRange(E->getTypeBeginLoc()),
+                                                   NewT,
+                                      /*FIXME:*/E->getSubExpr()->getLocStart(),
+                                                   move(SubExpr),
+                                                   E->getRParenLoc());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformCXXTypeidExpr(CXXTypeidExpr *E) {
+  if (E->isTypeOperand()) {
+    TypeSourceInfo *TInfo
+      = getDerived().TransformType(E->getTypeOperandSourceInfo());
+    if (!TInfo)
+      return SemaRef.ExprError();
+
+    if (!getDerived().AlwaysRebuild() &&
+        TInfo == E->getTypeOperandSourceInfo())
+      return SemaRef.Owned(E->Retain());
+
+    return getDerived().RebuildCXXTypeidExpr(E->getType(),
+                                             E->getLocStart(),
+                                             TInfo,
+                                             E->getLocEnd());
+  }
+
+  // We don't know whether the expression is potentially evaluated until
+  // after we perform semantic analysis, so the expression is potentially
+  // potentially evaluated.
+  EnterExpressionEvaluationContext Unevaluated(SemaRef,
+                                      Action::PotentiallyPotentiallyEvaluated);
+
+  OwningExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand());
+  if (SubExpr.isInvalid())
+    return SemaRef.ExprError();
+
+  if (!getDerived().AlwaysRebuild() &&
+      SubExpr.get() == E->getExprOperand())
+    return SemaRef.Owned(E->Retain());
+
+  return getDerived().RebuildCXXTypeidExpr(E->getType(),
+                                           E->getLocStart(),
+                                           move(SubExpr),
+                                           E->getLocEnd());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
+  return SemaRef.Owned(E->Retain());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformCXXNullPtrLiteralExpr(
+                                                     CXXNullPtrLiteralExpr *E) {
+  return SemaRef.Owned(E->Retain());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformCXXThisExpr(CXXThisExpr *E) {
+  TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
+
+  QualType T = getDerived().TransformType(E->getType());
+  if (T.isNull())
+    return SemaRef.ExprError();
+
+  if (!getDerived().AlwaysRebuild() &&
+      T == E->getType())
+    return SemaRef.Owned(E->Retain());
+
+  return getDerived().RebuildCXXThisExpr(E->getLocStart(), T, E->isImplicit());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformCXXThrowExpr(CXXThrowExpr *E) {
+  OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
+  if (SubExpr.isInvalid())
+    return SemaRef.ExprError();
+
+  if (!getDerived().AlwaysRebuild() &&
+      SubExpr.get() == E->getSubExpr())
+    return SemaRef.Owned(E->Retain());
+
+  return getDerived().RebuildCXXThrowExpr(E->getThrowLoc(), move(SubExpr));
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
+  ParmVarDecl *Param
+    = cast_or_null<ParmVarDecl>(getDerived().TransformDecl(E->getLocStart(),
+                                                           E->getParam()));
+  if (!Param)
+    return SemaRef.ExprError();
+
+  if (!getDerived().AlwaysRebuild() &&
+      Param == E->getParam())
+    return SemaRef.Owned(E->Retain());
+
+  return getDerived().RebuildCXXDefaultArgExpr(E->getUsedLocation(), Param);
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) {
+  TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
+
+  QualType T = getDerived().TransformType(E->getType());
+  if (T.isNull())
+    return SemaRef.ExprError();
+
+  if (!getDerived().AlwaysRebuild() &&
+      T == E->getType())
+    return SemaRef.Owned(E->Retain());
+
+  return getDerived().RebuildCXXZeroInitValueExpr(E->getTypeBeginLoc(),
+                                                /*FIXME:*/E->getTypeBeginLoc(),
+                                                  T,
+                                                  E->getRParenLoc());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
+  // Transform the type that we're allocating
+  TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
+  QualType AllocType = getDerived().TransformType(E->getAllocatedType());
+  if (AllocType.isNull())
+    return SemaRef.ExprError();
+
+  // Transform the size of the array we're allocating (if any).
+  OwningExprResult ArraySize = getDerived().TransformExpr(E->getArraySize());
+  if (ArraySize.isInvalid())
+    return SemaRef.ExprError();
+
+  // Transform the placement arguments (if any).
+  bool ArgumentChanged = false;
+  ASTOwningVector<&ActionBase::DeleteExpr> PlacementArgs(SemaRef);
+  for (unsigned I = 0, N = E->getNumPlacementArgs(); I != N; ++I) {
+    OwningExprResult Arg = getDerived().TransformExpr(E->getPlacementArg(I));
+    if (Arg.isInvalid())
+      return SemaRef.ExprError();
+
+    ArgumentChanged = ArgumentChanged || Arg.get() != E->getPlacementArg(I);
+    PlacementArgs.push_back(Arg.take());
+  }
+
+  // transform the constructor arguments (if any).
+  ASTOwningVector<&ActionBase::DeleteExpr> ConstructorArgs(SemaRef);
+  for (unsigned I = 0, N = E->getNumConstructorArgs(); I != N; ++I) {
+    OwningExprResult Arg = getDerived().TransformExpr(E->getConstructorArg(I));
+    if (Arg.isInvalid())
+      return SemaRef.ExprError();
+
+    ArgumentChanged = ArgumentChanged || Arg.get() != E->getConstructorArg(I);
+    ConstructorArgs.push_back(Arg.take());
+  }
+
+  // Transform constructor, new operator, and delete operator.
+  CXXConstructorDecl *Constructor = 0;
+  if (E->getConstructor()) {
+    Constructor = cast_or_null<CXXConstructorDecl>(
+                                   getDerived().TransformDecl(E->getLocStart(),
+                                                         E->getConstructor()));
+    if (!Constructor)
+      return SemaRef.ExprError();
+  }
+
+  FunctionDecl *OperatorNew = 0;
+  if (E->getOperatorNew()) {
+    OperatorNew = cast_or_null<FunctionDecl>(
+                                 getDerived().TransformDecl(E->getLocStart(),
+                                                         E->getOperatorNew()));
+    if (!OperatorNew)
+      return SemaRef.ExprError();
+  }
+
+  FunctionDecl *OperatorDelete = 0;
+  if (E->getOperatorDelete()) {
+    OperatorDelete = cast_or_null<FunctionDecl>(
+                                   getDerived().TransformDecl(E->getLocStart(),
+                                                       E->getOperatorDelete()));
+    if (!OperatorDelete)
+      return SemaRef.ExprError();
+  }
+  
+  if (!getDerived().AlwaysRebuild() &&
+      AllocType == E->getAllocatedType() &&
+      ArraySize.get() == E->getArraySize() &&
+      Constructor == E->getConstructor() &&
+      OperatorNew == E->getOperatorNew() &&
+      OperatorDelete == E->getOperatorDelete() &&
+      !ArgumentChanged) {
+    // Mark any declarations we need as referenced.
+    // FIXME: instantiation-specific.
+    if (Constructor)
+      SemaRef.MarkDeclarationReferenced(E->getLocStart(), Constructor);
+    if (OperatorNew)
+      SemaRef.MarkDeclarationReferenced(E->getLocStart(), OperatorNew);
+    if (OperatorDelete)
+      SemaRef.MarkDeclarationReferenced(E->getLocStart(), OperatorDelete);
+    return SemaRef.Owned(E->Retain());
+  }
+
+  if (!ArraySize.get()) {
+    // If no array size was specified, but the new expression was
+    // instantiated with an array type (e.g., "new T" where T is
+    // instantiated with "int[4]"), extract the outer bound from the
+    // array type as our array size. We do this with constant and
+    // dependently-sized array types.
+    const ArrayType *ArrayT = SemaRef.Context.getAsArrayType(AllocType);
+    if (!ArrayT) {
+      // Do nothing
+    } else if (const ConstantArrayType *ConsArrayT
+                                     = dyn_cast<ConstantArrayType>(ArrayT)) {
+      ArraySize 
+        = SemaRef.Owned(new (SemaRef.Context) IntegerLiteral(
+                                                  ConsArrayT->getSize(), 
+                                                  SemaRef.Context.getSizeType(),
+                                                  /*FIXME:*/E->getLocStart()));
+      AllocType = ConsArrayT->getElementType();
+    } else if (const DependentSizedArrayType *DepArrayT
+                              = dyn_cast<DependentSizedArrayType>(ArrayT)) {
+      if (DepArrayT->getSizeExpr()) {
+        ArraySize = SemaRef.Owned(DepArrayT->getSizeExpr()->Retain());
+        AllocType = DepArrayT->getElementType();
+      }
+    }
+  }
+  return getDerived().RebuildCXXNewExpr(E->getLocStart(),
+                                        E->isGlobalNew(),
+                                        /*FIXME:*/E->getLocStart(),
+                                        move_arg(PlacementArgs),
+                                        /*FIXME:*/E->getLocStart(),
+                                        E->isParenTypeId(),
+                                        AllocType,
+                                        /*FIXME:*/E->getLocStart(),
+                                        /*FIXME:*/SourceRange(),
+                                        move(ArraySize),
+                                        /*FIXME:*/E->getLocStart(),
+                                        move_arg(ConstructorArgs),
+                                        E->getLocEnd());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformCXXDeleteExpr(CXXDeleteExpr *E) {
+  OwningExprResult Operand = getDerived().TransformExpr(E->getArgument());
+  if (Operand.isInvalid())
+    return SemaRef.ExprError();
+
+  // Transform the delete operator, if known.
+  FunctionDecl *OperatorDelete = 0;
+  if (E->getOperatorDelete()) {
+    OperatorDelete = cast_or_null<FunctionDecl>(
+                                   getDerived().TransformDecl(E->getLocStart(),
+                                                       E->getOperatorDelete()));
+    if (!OperatorDelete)
+      return SemaRef.ExprError();
+  }
+  
+  if (!getDerived().AlwaysRebuild() &&
+      Operand.get() == E->getArgument() &&
+      OperatorDelete == E->getOperatorDelete()) {
+    // Mark any declarations we need as referenced.
+    // FIXME: instantiation-specific.
+    if (OperatorDelete)
+      SemaRef.MarkDeclarationReferenced(E->getLocStart(), OperatorDelete);
+    return SemaRef.Owned(E->Retain());
+  }
+
+  return getDerived().RebuildCXXDeleteExpr(E->getLocStart(),
+                                           E->isGlobalDelete(),
+                                           E->isArrayForm(),
+                                           move(Operand));
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformCXXPseudoDestructorExpr(
+                                                     CXXPseudoDestructorExpr *E) {
+  OwningExprResult Base = getDerived().TransformExpr(E->getBase());
+  if (Base.isInvalid())
+    return SemaRef.ExprError();
+
+  Sema::TypeTy *ObjectTypePtr = 0;
+  bool MayBePseudoDestructor = false;
+  Base = SemaRef.ActOnStartCXXMemberReference(0, move(Base), 
+                                              E->getOperatorLoc(),
+                                        E->isArrow()? tok::arrow : tok::period,
+                                              ObjectTypePtr,
+                                              MayBePseudoDestructor);
+  if (Base.isInvalid())
+    return SemaRef.ExprError();
+                                              
+  QualType ObjectType = QualType::getFromOpaquePtr(ObjectTypePtr);
+  NestedNameSpecifier *Qualifier
+    = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
+                                                E->getQualifierRange(),
+                                                ObjectType);
+  if (E->getQualifier() && !Qualifier)
+    return SemaRef.ExprError();
+
+  PseudoDestructorTypeStorage Destroyed;
+  if (E->getDestroyedTypeInfo()) {
+    TypeSourceInfo *DestroyedTypeInfo
+      = getDerived().TransformType(E->getDestroyedTypeInfo(), ObjectType);
+    if (!DestroyedTypeInfo)
+      return SemaRef.ExprError();
+    Destroyed = DestroyedTypeInfo;
+  } else if (ObjectType->isDependentType()) {
+    // We aren't likely to be able to resolve the identifier down to a type
+    // now anyway, so just retain the identifier.
+    Destroyed = PseudoDestructorTypeStorage(E->getDestroyedTypeIdentifier(),
+                                            E->getDestroyedTypeLoc());
+  } else {
+    // Look for a destructor known with the given name.
+    CXXScopeSpec SS;
+    if (Qualifier) {
+      SS.setScopeRep(Qualifier);
+      SS.setRange(E->getQualifierRange());
+    }
+    
+    Sema::TypeTy *T = SemaRef.getDestructorName(E->getTildeLoc(),
+                                              *E->getDestroyedTypeIdentifier(),
+                                                E->getDestroyedTypeLoc(),
+                                                /*Scope=*/0,
+                                                SS, ObjectTypePtr,
+                                                false);
+    if (!T)
+      return SemaRef.ExprError();
+    
+    Destroyed
+      = SemaRef.Context.getTrivialTypeSourceInfo(SemaRef.GetTypeFromParser(T),
+                                                 E->getDestroyedTypeLoc());
+  }
+
+  TypeSourceInfo *ScopeTypeInfo = 0;
+  if (E->getScopeTypeInfo()) {
+    ScopeTypeInfo = getDerived().TransformType(E->getScopeTypeInfo(), 
+                                               ObjectType);
+    if (!ScopeTypeInfo)
+      return SemaRef.ExprError();
+  }
+  
+  return getDerived().RebuildCXXPseudoDestructorExpr(move(Base),
+                                                     E->getOperatorLoc(),
+                                                     E->isArrow(),
+                                                     Qualifier,
+                                                     E->getQualifierRange(),
+                                                     ScopeTypeInfo,
+                                                     E->getColonColonLoc(),
+                                                     E->getTildeLoc(),
+                                                     Destroyed);
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformUnresolvedLookupExpr(
+                                                  UnresolvedLookupExpr *Old) {
+  TemporaryBase Rebase(*this, Old->getNameLoc(), DeclarationName());
+
+  LookupResult R(SemaRef, Old->getName(), Old->getNameLoc(),
+                 Sema::LookupOrdinaryName);
+
+  // Transform all the decls.
+  for (UnresolvedLookupExpr::decls_iterator I = Old->decls_begin(),
+         E = Old->decls_end(); I != E; ++I) {
+    NamedDecl *InstD = static_cast<NamedDecl*>(
+                                 getDerived().TransformDecl(Old->getNameLoc(),
+                                                            *I));
+    if (!InstD) {
+      // Silently ignore these if a UsingShadowDecl instantiated to nothing.
+      // This can happen because of dependent hiding.
+      if (isa<UsingShadowDecl>(*I))
+        continue;
+      else
+        return SemaRef.ExprError();
+    }
+
+    // Expand using declarations.
+    if (isa<UsingDecl>(InstD)) {
+      UsingDecl *UD = cast<UsingDecl>(InstD);
+      for (UsingDecl::shadow_iterator I = UD->shadow_begin(),
+             E = UD->shadow_end(); I != E; ++I)
+        R.addDecl(*I);
+      continue;
+    }
+
+    R.addDecl(InstD);
+  }
+
+  // Resolve a kind, but don't do any further analysis.  If it's
+  // ambiguous, the callee needs to deal with it.
+  R.resolveKind();
+
+  // Rebuild the nested-name qualifier, if present.
+  CXXScopeSpec SS;
+  NestedNameSpecifier *Qualifier = 0;
+  if (Old->getQualifier()) {
+    Qualifier = getDerived().TransformNestedNameSpecifier(Old->getQualifier(),
+                                                    Old->getQualifierRange());
+    if (!Qualifier)
+      return SemaRef.ExprError();
+    
+    SS.setScopeRep(Qualifier);
+    SS.setRange(Old->getQualifierRange());
+  }
+
+  // If we have no template arguments, it's a normal declaration name.
+  if (!Old->hasExplicitTemplateArgs())
+    return getDerived().RebuildDeclarationNameExpr(SS, R, Old->requiresADL());
+
+  // If we have template arguments, rebuild them, then rebuild the
+  // templateid expression.
+  TemplateArgumentListInfo TransArgs(Old->getLAngleLoc(), Old->getRAngleLoc());
+  for (unsigned I = 0, N = Old->getNumTemplateArgs(); I != N; ++I) {
+    TemplateArgumentLoc Loc;
+    if (getDerived().TransformTemplateArgument(Old->getTemplateArgs()[I], Loc))
+      return SemaRef.ExprError();
+    TransArgs.addArgument(Loc);
+  }
+
+  return getDerived().RebuildTemplateIdExpr(SS, R, Old->requiresADL(),
+                                            TransArgs);
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
+  TemporaryBase Rebase(*this, /*FIXME*/E->getLocStart(), DeclarationName());
+
+  QualType T = getDerived().TransformType(E->getQueriedType());
+  if (T.isNull())
+    return SemaRef.ExprError();
+
+  if (!getDerived().AlwaysRebuild() &&
+      T == E->getQueriedType())
+    return SemaRef.Owned(E->Retain());
+
+  // FIXME: Bad location information
+  SourceLocation FakeLParenLoc
+    = SemaRef.PP.getLocForEndOfToken(E->getLocStart());
+
+  return getDerived().RebuildUnaryTypeTrait(E->getTrait(),
+                                            E->getLocStart(),
+                                            /*FIXME:*/FakeLParenLoc,
+                                            T,
+                                            E->getLocEnd());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
+                                                  DependentScopeDeclRefExpr *E) {
+  NestedNameSpecifier *NNS
+    = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
+                                                E->getQualifierRange());
+  if (!NNS)
+    return SemaRef.ExprError();
+
+  DeclarationName Name
+    = getDerived().TransformDeclarationName(E->getDeclName(), E->getLocation());
+  if (!Name)
+    return SemaRef.ExprError();
+
+  if (!E->hasExplicitTemplateArgs()) {
+    if (!getDerived().AlwaysRebuild() &&
+        NNS == E->getQualifier() &&
+        Name == E->getDeclName())
+      return SemaRef.Owned(E->Retain());
+
+    return getDerived().RebuildDependentScopeDeclRefExpr(NNS,
+                                                         E->getQualifierRange(),
+                                                         Name, E->getLocation(),
+                                                         /*TemplateArgs*/ 0);
+  }
+
+  TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
+  for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
+    TemplateArgumentLoc Loc;
+    if (getDerived().TransformTemplateArgument(E->getTemplateArgs()[I], Loc))
+      return SemaRef.ExprError();
+    TransArgs.addArgument(Loc);
+  }
+
+  return getDerived().RebuildDependentScopeDeclRefExpr(NNS,
+                                                       E->getQualifierRange(),
+                                                       Name, E->getLocation(),
+                                                       &TransArgs);
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) {
+  // CXXConstructExprs are always implicit, so when we have a
+  // 1-argument construction we just transform that argument.
+  if (E->getNumArgs() == 1 ||
+      (E->getNumArgs() > 1 && getDerived().DropCallArgument(E->getArg(1))))
+    return getDerived().TransformExpr(E->getArg(0));
+
+  TemporaryBase Rebase(*this, /*FIXME*/E->getLocStart(), DeclarationName());
+
+  QualType T = getDerived().TransformType(E->getType());
+  if (T.isNull())
+    return SemaRef.ExprError();
+
+  CXXConstructorDecl *Constructor
+    = cast_or_null<CXXConstructorDecl>(
+                                getDerived().TransformDecl(E->getLocStart(),
+                                                         E->getConstructor()));
+  if (!Constructor)
+    return SemaRef.ExprError();
+
+  bool ArgumentChanged = false;
+  ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
+  for (CXXConstructExpr::arg_iterator Arg = E->arg_begin(),
+       ArgEnd = E->arg_end();
+       Arg != ArgEnd; ++Arg) {
+    if (getDerived().DropCallArgument(*Arg)) {
+      ArgumentChanged = true;
+      break;
+    }
+
+    OwningExprResult TransArg = getDerived().TransformExpr(*Arg);
+    if (TransArg.isInvalid())
+      return SemaRef.ExprError();
+
+    ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg;
+    Args.push_back(TransArg.takeAs<Expr>());
+  }
+
+  if (!getDerived().AlwaysRebuild() &&
+      T == E->getType() &&
+      Constructor == E->getConstructor() &&
+      !ArgumentChanged) {
+    // Mark the constructor as referenced.
+    // FIXME: Instantiation-specific
+    SemaRef.MarkDeclarationReferenced(E->getLocStart(), Constructor);
+    return SemaRef.Owned(E->Retain());
+  }
+
+  return getDerived().RebuildCXXConstructExpr(T, /*FIXME:*/E->getLocStart(),
+                                              Constructor, E->isElidable(),
+                                              move_arg(Args));
+}
+
+/// \brief Transform a C++ temporary-binding expression.
+///
+/// Since CXXBindTemporaryExpr nodes are implicitly generated, we just
+/// transform the subexpression and return that.
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
+  return getDerived().TransformExpr(E->getSubExpr());
+}
+
+/// \brief Transform a C++ reference-binding expression.
+///
+/// Since CXXBindReferenceExpr nodes are implicitly generated, we just
+/// transform the subexpression and return that.
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformCXXBindReferenceExpr(CXXBindReferenceExpr *E) {
+  return getDerived().TransformExpr(E->getSubExpr());
+}
+
+/// \brief Transform a C++ expression that contains temporaries that should
+/// be destroyed after the expression is evaluated.
+///
+/// Since CXXExprWithTemporaries nodes are implicitly generated, we
+/// just transform the subexpression and return that.
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformCXXExprWithTemporaries(
+                                                    CXXExprWithTemporaries *E) {
+  return getDerived().TransformExpr(E->getSubExpr());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformCXXTemporaryObjectExpr(
+                                                      CXXTemporaryObjectExpr *E) {
+  TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
+  QualType T = getDerived().TransformType(E->getType());
+  if (T.isNull())
+    return SemaRef.ExprError();
+
+  CXXConstructorDecl *Constructor
+    = cast_or_null<CXXConstructorDecl>(
+                                  getDerived().TransformDecl(E->getLocStart(), 
+                                                         E->getConstructor()));
+  if (!Constructor)
+    return SemaRef.ExprError();
+
+  bool ArgumentChanged = false;
+  ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
+  Args.reserve(E->getNumArgs());
+  for (CXXTemporaryObjectExpr::arg_iterator Arg = E->arg_begin(),
+                                         ArgEnd = E->arg_end();
+       Arg != ArgEnd; ++Arg) {
+    if (getDerived().DropCallArgument(*Arg)) {
+      ArgumentChanged = true;
+      break;
+    }
+
+    OwningExprResult TransArg = getDerived().TransformExpr(*Arg);
+    if (TransArg.isInvalid())
+      return SemaRef.ExprError();
+
+    ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg;
+    Args.push_back((Expr *)TransArg.release());
+  }
+
+  if (!getDerived().AlwaysRebuild() &&
+      T == E->getType() &&
+      Constructor == E->getConstructor() &&
+      !ArgumentChanged) {
+    // FIXME: Instantiation-specific
+    SemaRef.MarkDeclarationReferenced(E->getTypeBeginLoc(), Constructor);
+    return SemaRef.MaybeBindToTemporary(E->Retain());
+  }
+
+  // FIXME: Bogus location information
+  SourceLocation CommaLoc;
+  if (Args.size() > 1) {
+    Expr *First = (Expr *)Args[0];
+    CommaLoc
+      = SemaRef.PP.getLocForEndOfToken(First->getSourceRange().getEnd());
+  }
+  return getDerived().RebuildCXXTemporaryObjectExpr(E->getTypeBeginLoc(),
+                                                    T,
+                                                /*FIXME:*/E->getTypeBeginLoc(),
+                                                    move_arg(Args),
+                                                    &CommaLoc,
+                                                    E->getLocEnd());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformCXXUnresolvedConstructExpr(
+                                                  CXXUnresolvedConstructExpr *E) {
+  TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
+  QualType T = getDerived().TransformType(E->getTypeAsWritten());
+  if (T.isNull())
+    return SemaRef.ExprError();
+
+  bool ArgumentChanged = false;
+  ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
+  llvm::SmallVector<SourceLocation, 8> FakeCommaLocs;
+  for (CXXUnresolvedConstructExpr::arg_iterator Arg = E->arg_begin(),
+                                             ArgEnd = E->arg_end();
+       Arg != ArgEnd; ++Arg) {
+    OwningExprResult TransArg = getDerived().TransformExpr(*Arg);
+    if (TransArg.isInvalid())
+      return SemaRef.ExprError();
+
+    ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg;
+    FakeCommaLocs.push_back(
+                        SemaRef.PP.getLocForEndOfToken((*Arg)->getLocEnd()));
+    Args.push_back(TransArg.takeAs<Expr>());
+  }
+
+  if (!getDerived().AlwaysRebuild() &&
+      T == E->getTypeAsWritten() &&
+      !ArgumentChanged)
+    return SemaRef.Owned(E->Retain());
+
+  // FIXME: we're faking the locations of the commas
+  return getDerived().RebuildCXXUnresolvedConstructExpr(E->getTypeBeginLoc(),
+                                                        T,
+                                                        E->getLParenLoc(),
+                                                        move_arg(Args),
+                                                        FakeCommaLocs.data(),
+                                                        E->getRParenLoc());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformCXXDependentScopeMemberExpr(
+                                                     CXXDependentScopeMemberExpr *E) {
+  // Transform the base of the expression.
+  OwningExprResult Base(SemaRef, (Expr*) 0);
+  Expr *OldBase;
+  QualType BaseType;
+  QualType ObjectType;
+  if (!E->isImplicitAccess()) {
+    OldBase = E->getBase();
+    Base = getDerived().TransformExpr(OldBase);
+    if (Base.isInvalid())
+      return SemaRef.ExprError();
+
+    // Start the member reference and compute the object's type.
+    Sema::TypeTy *ObjectTy = 0;
+    bool MayBePseudoDestructor = false;
+    Base = SemaRef.ActOnStartCXXMemberReference(0, move(Base),
+                                                E->getOperatorLoc(),
+                                      E->isArrow()? tok::arrow : tok::period,
+                                                ObjectTy,
+                                                MayBePseudoDestructor);
+    if (Base.isInvalid())
+      return SemaRef.ExprError();
+
+    ObjectType = QualType::getFromOpaquePtr(ObjectTy);
+    BaseType = ((Expr*) Base.get())->getType();
+  } else {
+    OldBase = 0;
+    BaseType = getDerived().TransformType(E->getBaseType());
+    ObjectType = BaseType->getAs<PointerType>()->getPointeeType();
+  }
+
+  // Transform the first part of the nested-name-specifier that qualifies
+  // the member name.
+  NamedDecl *FirstQualifierInScope
+    = getDerived().TransformFirstQualifierInScope(
+                                          E->getFirstQualifierFoundInScope(),
+                                          E->getQualifierRange().getBegin());
+
+  NestedNameSpecifier *Qualifier = 0;
+  if (E->getQualifier()) {
+    Qualifier = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
+                                                      E->getQualifierRange(),
+                                                      ObjectType,
+                                                      FirstQualifierInScope);
+    if (!Qualifier)
+      return SemaRef.ExprError();
+  }
+
+  DeclarationName Name
+    = getDerived().TransformDeclarationName(E->getMember(), E->getMemberLoc(),
+                                            ObjectType);
+  if (!Name)
+    return SemaRef.ExprError();
+
+  if (!E->hasExplicitTemplateArgs()) {
+    // This is a reference to a member without an explicitly-specified
+    // template argument list. Optimize for this common case.
+    if (!getDerived().AlwaysRebuild() &&
+        Base.get() == OldBase &&
+        BaseType == E->getBaseType() &&
+        Qualifier == E->getQualifier() &&
+        Name == E->getMember() &&
+        FirstQualifierInScope == E->getFirstQualifierFoundInScope())
+      return SemaRef.Owned(E->Retain());
+
+    return getDerived().RebuildCXXDependentScopeMemberExpr(move(Base),
+                                                       BaseType,
+                                                       E->isArrow(),
+                                                       E->getOperatorLoc(),
+                                                       Qualifier,
+                                                       E->getQualifierRange(),
+                                                       FirstQualifierInScope,
+                                                       Name,
+                                                       E->getMemberLoc(),
+                                                       /*TemplateArgs*/ 0);
+  }
+
+  TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
+  for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
+    TemplateArgumentLoc Loc;
+    if (getDerived().TransformTemplateArgument(E->getTemplateArgs()[I], Loc))
+      return SemaRef.ExprError();
+    TransArgs.addArgument(Loc);
+  }
+
+  return getDerived().RebuildCXXDependentScopeMemberExpr(move(Base),
+                                                     BaseType,
+                                                     E->isArrow(),
+                                                     E->getOperatorLoc(),
+                                                     Qualifier,
+                                                     E->getQualifierRange(),
+                                                     FirstQualifierInScope,
+                                                     Name,
+                                                     E->getMemberLoc(),
+                                                     &TransArgs);
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformUnresolvedMemberExpr(UnresolvedMemberExpr *Old) {
+  // Transform the base of the expression.
+  OwningExprResult Base(SemaRef, (Expr*) 0);
+  QualType BaseType;
+  if (!Old->isImplicitAccess()) {
+    Base = getDerived().TransformExpr(Old->getBase());
+    if (Base.isInvalid())
+      return SemaRef.ExprError();
+    BaseType = ((Expr*) Base.get())->getType();
+  } else {
+    BaseType = getDerived().TransformType(Old->getBaseType());
+  }
+
+  NestedNameSpecifier *Qualifier = 0;
+  if (Old->getQualifier()) {
+    Qualifier
+      = getDerived().TransformNestedNameSpecifier(Old->getQualifier(),
+                                                  Old->getQualifierRange());
+    if (Qualifier == 0)
+      return SemaRef.ExprError();
+  }
+
+  LookupResult R(SemaRef, Old->getMemberName(), Old->getMemberLoc(),
+                 Sema::LookupOrdinaryName);
+
+  // Transform all the decls.
+  for (UnresolvedMemberExpr::decls_iterator I = Old->decls_begin(),
+         E = Old->decls_end(); I != E; ++I) {
+    NamedDecl *InstD = static_cast<NamedDecl*>(
+                                getDerived().TransformDecl(Old->getMemberLoc(),
+                                                           *I));
+    if (!InstD) {
+      // Silently ignore these if a UsingShadowDecl instantiated to nothing.
+      // This can happen because of dependent hiding.
+      if (isa<UsingShadowDecl>(*I))
+        continue;
+      else
+        return SemaRef.ExprError();
+    }
+
+    // Expand using declarations.
+    if (isa<UsingDecl>(InstD)) {
+      UsingDecl *UD = cast<UsingDecl>(InstD);
+      for (UsingDecl::shadow_iterator I = UD->shadow_begin(),
+             E = UD->shadow_end(); I != E; ++I)
+        R.addDecl(*I);
+      continue;
+    }
+
+    R.addDecl(InstD);
+  }
+
+  R.resolveKind();
+
+  TemplateArgumentListInfo TransArgs;
+  if (Old->hasExplicitTemplateArgs()) {
+    TransArgs.setLAngleLoc(Old->getLAngleLoc());
+    TransArgs.setRAngleLoc(Old->getRAngleLoc());
+    for (unsigned I = 0, N = Old->getNumTemplateArgs(); I != N; ++I) {
+      TemplateArgumentLoc Loc;
+      if (getDerived().TransformTemplateArgument(Old->getTemplateArgs()[I],
+                                                 Loc))
+        return SemaRef.ExprError();
+      TransArgs.addArgument(Loc);
+    }
+  }
+
+  // FIXME: to do this check properly, we will need to preserve the
+  // first-qualifier-in-scope here, just in case we had a dependent
+  // base (and therefore couldn't do the check) and a
+  // nested-name-qualifier (and therefore could do the lookup).
+  NamedDecl *FirstQualifierInScope = 0;
+  
+  return getDerived().RebuildUnresolvedMemberExpr(move(Base),
+                                                  BaseType,
+                                                  Old->getOperatorLoc(),
+                                                  Old->isArrow(),
+                                                  Qualifier,
+                                                  Old->getQualifierRange(),
+                                                  FirstQualifierInScope,
+                                                  R,
+                                              (Old->hasExplicitTemplateArgs()
+                                                  ? &TransArgs : 0));
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformObjCStringLiteral(ObjCStringLiteral *E) {
+  return SemaRef.Owned(E->Retain());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformObjCEncodeExpr(ObjCEncodeExpr *E) {
+  TypeSourceInfo *EncodedTypeInfo
+    = getDerived().TransformType(E->getEncodedTypeSourceInfo());
+  if (!EncodedTypeInfo)
+    return SemaRef.ExprError();
+
+  if (!getDerived().AlwaysRebuild() &&
+      EncodedTypeInfo == E->getEncodedTypeSourceInfo())
+    return SemaRef.Owned(E->Retain());
+
+  return getDerived().RebuildObjCEncodeExpr(E->getAtLoc(),
+                                            EncodedTypeInfo,
+                                            E->getRParenLoc());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformObjCMessageExpr(ObjCMessageExpr *E) {
+  // Transform arguments.
+  bool ArgChanged = false;
+  ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
+  for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
+    OwningExprResult Arg = getDerived().TransformExpr(E->getArg(I));
+    if (Arg.isInvalid())
+      return SemaRef.ExprError();
+    
+    ArgChanged = ArgChanged || Arg.get() != E->getArg(I);
+    Args.push_back(Arg.takeAs<Expr>());
+  }
+
+  if (E->getReceiverKind() == ObjCMessageExpr::Class) {
+    // Class message: transform the receiver type.
+    TypeSourceInfo *ReceiverTypeInfo
+      = getDerived().TransformType(E->getClassReceiverTypeInfo());
+    if (!ReceiverTypeInfo)
+      return SemaRef.ExprError();
+    
+    // If nothing changed, just retain the existing message send.
+    if (!getDerived().AlwaysRebuild() &&
+        ReceiverTypeInfo == E->getClassReceiverTypeInfo() && !ArgChanged)
+      return SemaRef.Owned(E->Retain());
+
+    // Build a new class message send.
+    return getDerived().RebuildObjCMessageExpr(ReceiverTypeInfo,
+                                               E->getSelector(),
+                                               E->getMethodDecl(),
+                                               E->getLeftLoc(),
+                                               move_arg(Args),
+                                               E->getRightLoc());
+  }
+
+  // Instance message: transform the receiver
+  assert(E->getReceiverKind() == ObjCMessageExpr::Instance &&
+         "Only class and instance messages may be instantiated");
+  OwningExprResult Receiver
+    = getDerived().TransformExpr(E->getInstanceReceiver());
+  if (Receiver.isInvalid())
+    return SemaRef.ExprError();
+
+  // If nothing changed, just retain the existing message send.
+  if (!getDerived().AlwaysRebuild() &&
+      Receiver.get() == E->getInstanceReceiver() && !ArgChanged)
+    return SemaRef.Owned(E->Retain());
+  
+  // Build a new instance message send.
+  return getDerived().RebuildObjCMessageExpr(move(Receiver),
+                                             E->getSelector(),
+                                             E->getMethodDecl(),
+                                             E->getLeftLoc(),
+                                             move_arg(Args),
+                                             E->getRightLoc());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformObjCSelectorExpr(ObjCSelectorExpr *E) {
+  return SemaRef.Owned(E->Retain());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformObjCProtocolExpr(ObjCProtocolExpr *E) {
+  return SemaRef.Owned(E->Retain());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformObjCIvarRefExpr(ObjCIvarRefExpr *E) {
+  // Transform the base expression.
+  OwningExprResult Base = getDerived().TransformExpr(E->getBase());
+  if (Base.isInvalid())
+    return SemaRef.ExprError();
+
+  // We don't need to transform the ivar; it will never change.
+  
+  // If nothing changed, just retain the existing expression.
+  if (!getDerived().AlwaysRebuild() &&
+      Base.get() == E->getBase())
+    return SemaRef.Owned(E->Retain());
+  
+  return getDerived().RebuildObjCIvarRefExpr(move(Base), E->getDecl(),
+                                             E->getLocation(),
+                                             E->isArrow(), E->isFreeIvar());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
+  // Transform the base expression.
+  OwningExprResult Base = getDerived().TransformExpr(E->getBase());
+  if (Base.isInvalid())
+    return SemaRef.ExprError();
+  
+  // We don't need to transform the property; it will never change.
+  
+  // If nothing changed, just retain the existing expression.
+  if (!getDerived().AlwaysRebuild() &&
+      Base.get() == E->getBase())
+    return SemaRef.Owned(E->Retain());
+  
+  return getDerived().RebuildObjCPropertyRefExpr(move(Base), E->getProperty(),
+                                                 E->getLocation());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformObjCImplicitSetterGetterRefExpr(
+                                          ObjCImplicitSetterGetterRefExpr *E) {
+  // If this implicit setter/getter refers to class methods, it cannot have any
+  // dependent parts. Just retain the existing declaration.
+  if (E->getInterfaceDecl())
+    return SemaRef.Owned(E->Retain());
+  
+  // Transform the base expression.
+  OwningExprResult Base = getDerived().TransformExpr(E->getBase());
+  if (Base.isInvalid())
+    return SemaRef.ExprError();
+  
+  // We don't need to transform the getters/setters; they will never change.
+  
+  // If nothing changed, just retain the existing expression.
+  if (!getDerived().AlwaysRebuild() &&
+      Base.get() == E->getBase())
+    return SemaRef.Owned(E->Retain());
+  
+  return getDerived().RebuildObjCImplicitSetterGetterRefExpr(
+                                                          E->getGetterMethod(),
+                                                             E->getType(),
+                                                          E->getSetterMethod(),
+                                                             E->getLocation(),
+                                                             move(Base));
+                                                             
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformObjCSuperExpr(ObjCSuperExpr *E) {
+  // Can never occur in a dependent context.
+  return SemaRef.Owned(E->Retain());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformObjCIsaExpr(ObjCIsaExpr *E) {
+  // Transform the base expression.
+  OwningExprResult Base = getDerived().TransformExpr(E->getBase());
+  if (Base.isInvalid())
+    return SemaRef.ExprError();
+  
+  // If nothing changed, just retain the existing expression.
+  if (!getDerived().AlwaysRebuild() &&
+      Base.get() == E->getBase())
+    return SemaRef.Owned(E->Retain());
+  
+  return getDerived().RebuildObjCIsaExpr(move(Base), E->getIsaMemberLoc(),
+                                         E->isArrow());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformShuffleVectorExpr(ShuffleVectorExpr *E) {
+  bool ArgumentChanged = false;
+  ASTOwningVector<&ActionBase::DeleteExpr> SubExprs(SemaRef);
+  for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I) {
+    OwningExprResult SubExpr = getDerived().TransformExpr(E->getExpr(I));
+    if (SubExpr.isInvalid())
+      return SemaRef.ExprError();
+
+    ArgumentChanged = ArgumentChanged || SubExpr.get() != E->getExpr(I);
+    SubExprs.push_back(SubExpr.takeAs<Expr>());
+  }
+
+  if (!getDerived().AlwaysRebuild() &&
+      !ArgumentChanged)
+    return SemaRef.Owned(E->Retain());
+
+  return getDerived().RebuildShuffleVectorExpr(E->getBuiltinLoc(),
+                                               move_arg(SubExprs),
+                                               E->getRParenLoc());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) {
+  // FIXME: Implement this!
+  assert(false && "Cannot transform block expressions yet");
+  return SemaRef.Owned(E->Retain());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformBlockDeclRefExpr(BlockDeclRefExpr *E) {
+  // FIXME: Implement this!
+  assert(false && "Cannot transform block-related expressions yet");
+  return SemaRef.Owned(E->Retain());
+}
+
+//===----------------------------------------------------------------------===//
+// Type reconstruction
+//===----------------------------------------------------------------------===//
+
+template<typename Derived>
+QualType TreeTransform<Derived>::RebuildPointerType(QualType PointeeType,
+                                                    SourceLocation Star) {
+  return SemaRef.BuildPointerType(PointeeType, Qualifiers(), Star,
+                                  getDerived().getBaseEntity());
+}
+
+template<typename Derived>
+QualType TreeTransform<Derived>::RebuildBlockPointerType(QualType PointeeType,
+                                                         SourceLocation Star) {
+  return SemaRef.BuildBlockPointerType(PointeeType, Qualifiers(), Star,
+                                       getDerived().getBaseEntity());
+}
+
+template<typename Derived>
+QualType
+TreeTransform<Derived>::RebuildReferenceType(QualType ReferentType,
+                                             bool WrittenAsLValue,
+                                             SourceLocation Sigil) {
+  return SemaRef.BuildReferenceType(ReferentType, WrittenAsLValue, Qualifiers(),
+                                    Sigil, getDerived().getBaseEntity());
+}
+
+template<typename Derived>
+QualType
+TreeTransform<Derived>::RebuildMemberPointerType(QualType PointeeType,
+                                                 QualType ClassType,
+                                                 SourceLocation Sigil) {
+  return SemaRef.BuildMemberPointerType(PointeeType, ClassType, Qualifiers(),
+                                        Sigil, getDerived().getBaseEntity());
+}
+
+template<typename Derived>
+QualType
+TreeTransform<Derived>::RebuildArrayType(QualType ElementType,
+                                         ArrayType::ArraySizeModifier SizeMod,
+                                         const llvm::APInt *Size,
+                                         Expr *SizeExpr,
+                                         unsigned IndexTypeQuals,
+                                         SourceRange BracketsRange) {
+  if (SizeExpr || !Size)
+    return SemaRef.BuildArrayType(ElementType, SizeMod, SizeExpr,
+                                  IndexTypeQuals, BracketsRange,
+                                  getDerived().getBaseEntity());
+
+  QualType Types[] = {
+    SemaRef.Context.UnsignedCharTy, SemaRef.Context.UnsignedShortTy,
+    SemaRef.Context.UnsignedIntTy, SemaRef.Context.UnsignedLongTy,
+    SemaRef.Context.UnsignedLongLongTy, SemaRef.Context.UnsignedInt128Ty
+  };
+  const unsigned NumTypes = sizeof(Types) / sizeof(QualType);
+  QualType SizeType;
+  for (unsigned I = 0; I != NumTypes; ++I)
+    if (Size->getBitWidth() == SemaRef.Context.getIntWidth(Types[I])) {
+      SizeType = Types[I];
+      break;
+    }
+
+  IntegerLiteral ArraySize(*Size, SizeType, /*FIXME*/BracketsRange.getBegin());
+  return SemaRef.BuildArrayType(ElementType, SizeMod, &ArraySize,
+                                IndexTypeQuals, BracketsRange,
+                                getDerived().getBaseEntity());
+}
+
+template<typename Derived>
+QualType
+TreeTransform<Derived>::RebuildConstantArrayType(QualType ElementType,
+                                                 ArrayType::ArraySizeModifier SizeMod,
+                                                 const llvm::APInt &Size,
+                                                 unsigned IndexTypeQuals,
+                                                 SourceRange BracketsRange) {
+  return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, 0,
+                                        IndexTypeQuals, BracketsRange);
+}
+
+template<typename Derived>
+QualType
+TreeTransform<Derived>::RebuildIncompleteArrayType(QualType ElementType,
+                                          ArrayType::ArraySizeModifier SizeMod,
+                                                 unsigned IndexTypeQuals,
+                                                   SourceRange BracketsRange) {
+  return getDerived().RebuildArrayType(ElementType, SizeMod, 0, 0,
+                                       IndexTypeQuals, BracketsRange);
+}
+
+template<typename Derived>
+QualType
+TreeTransform<Derived>::RebuildVariableArrayType(QualType ElementType,
+                                          ArrayType::ArraySizeModifier SizeMod,
+                                                 ExprArg SizeExpr,
+                                                 unsigned IndexTypeQuals,
+                                                 SourceRange BracketsRange) {
+  return getDerived().RebuildArrayType(ElementType, SizeMod, 0,
+                                       SizeExpr.takeAs<Expr>(),
+                                       IndexTypeQuals, BracketsRange);
+}
+
+template<typename Derived>
+QualType
+TreeTransform<Derived>::RebuildDependentSizedArrayType(QualType ElementType,
+                                          ArrayType::ArraySizeModifier SizeMod,
+                                                       ExprArg SizeExpr,
+                                                       unsigned IndexTypeQuals,
+                                                   SourceRange BracketsRange) {
+  return getDerived().RebuildArrayType(ElementType, SizeMod, 0,
+                                       SizeExpr.takeAs<Expr>(),
+                                       IndexTypeQuals, BracketsRange);
+}
+
+template<typename Derived>
+QualType TreeTransform<Derived>::RebuildVectorType(QualType ElementType,
+                                       unsigned NumElements,
+                                       bool IsAltiVec, bool IsPixel) {
+  // FIXME: semantic checking!
+  return SemaRef.Context.getVectorType(ElementType, NumElements,
+                                       IsAltiVec, IsPixel);
+}
+
+template<typename Derived>
+QualType TreeTransform<Derived>::RebuildExtVectorType(QualType ElementType,
+                                                      unsigned NumElements,
+                                                 SourceLocation AttributeLoc) {
+  llvm::APInt numElements(SemaRef.Context.getIntWidth(SemaRef.Context.IntTy),
+                          NumElements, true);
+  IntegerLiteral *VectorSize
+    = new (SemaRef.Context) IntegerLiteral(numElements, SemaRef.Context.IntTy,
+                                           AttributeLoc);
+  return SemaRef.BuildExtVectorType(ElementType, SemaRef.Owned(VectorSize),
+                                    AttributeLoc);
+}
+
+template<typename Derived>
+QualType
+TreeTransform<Derived>::RebuildDependentSizedExtVectorType(QualType ElementType,
+                                                           ExprArg SizeExpr,
+                                                  SourceLocation AttributeLoc) {
+  return SemaRef.BuildExtVectorType(ElementType, move(SizeExpr), AttributeLoc);
+}
+
+template<typename Derived>
+QualType TreeTransform<Derived>::RebuildFunctionProtoType(QualType T,
+                                                          QualType *ParamTypes,
+                                                        unsigned NumParamTypes,
+                                                          bool Variadic,
+                                                          unsigned Quals) {
+  return SemaRef.BuildFunctionType(T, ParamTypes, NumParamTypes, Variadic,
+                                   Quals,
+                                   getDerived().getBaseLocation(),
+                                   getDerived().getBaseEntity());
+}
+
+template<typename Derived>
+QualType TreeTransform<Derived>::RebuildFunctionNoProtoType(QualType T) {
+  return SemaRef.Context.getFunctionNoProtoType(T);
+}
+
+template<typename Derived>
+QualType TreeTransform<Derived>::RebuildUnresolvedUsingType(Decl *D) {
+  assert(D && "no decl found");
+  if (D->isInvalidDecl()) return QualType();
+
+  // FIXME: Doesn't account for ObjCInterfaceDecl!
+  TypeDecl *Ty;
+  if (isa<UsingDecl>(D)) {
+    UsingDecl *Using = cast<UsingDecl>(D);
+    assert(Using->isTypeName() &&
+           "UnresolvedUsingTypenameDecl transformed to non-typename using");
+
+    // A valid resolved using typename decl points to exactly one type decl.
+    assert(++Using->shadow_begin() == Using->shadow_end());
+    Ty = cast<TypeDecl>((*Using->shadow_begin())->getTargetDecl());
+    
+  } else {
+    assert(isa<UnresolvedUsingTypenameDecl>(D) &&
+           "UnresolvedUsingTypenameDecl transformed to non-using decl");
+    Ty = cast<UnresolvedUsingTypenameDecl>(D);
+  }
+
+  return SemaRef.Context.getTypeDeclType(Ty);
+}
+
+template<typename Derived>
+QualType TreeTransform<Derived>::RebuildTypeOfExprType(ExprArg E) {
+  return SemaRef.BuildTypeofExprType(E.takeAs<Expr>());
+}
+
+template<typename Derived>
+QualType TreeTransform<Derived>::RebuildTypeOfType(QualType Underlying) {
+  return SemaRef.Context.getTypeOfType(Underlying);
+}
+
+template<typename Derived>
+QualType TreeTransform<Derived>::RebuildDecltypeType(ExprArg E) {
+  return SemaRef.BuildDecltypeType(E.takeAs<Expr>());
+}
+
+template<typename Derived>
+QualType TreeTransform<Derived>::RebuildTemplateSpecializationType(
+                                                      TemplateName Template,
+                                             SourceLocation TemplateNameLoc,
+                               const TemplateArgumentListInfo &TemplateArgs) {
+  return SemaRef.CheckTemplateIdType(Template, TemplateNameLoc, TemplateArgs);
+}
+
+template<typename Derived>
+NestedNameSpecifier *
+TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
+                                                   SourceRange Range,
+                                                   IdentifierInfo &II,
+                                                   QualType ObjectType,
+                                                   NamedDecl *FirstQualifierInScope) {
+  CXXScopeSpec SS;
+  // FIXME: The source location information is all wrong.
+  SS.setRange(Range);
+  SS.setScopeRep(Prefix);
+  return static_cast<NestedNameSpecifier *>(
+                    SemaRef.BuildCXXNestedNameSpecifier(0, SS, Range.getEnd(),
+                                                        Range.getEnd(), II,
+                                                        ObjectType,
+                                                        FirstQualifierInScope,
+                                                        false, false));
+}
+
+template<typename Derived>
+NestedNameSpecifier *
+TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
+                                                   SourceRange Range,
+                                                   NamespaceDecl *NS) {
+  return NestedNameSpecifier::Create(SemaRef.Context, Prefix, NS);
+}
+
+template<typename Derived>
+NestedNameSpecifier *
+TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
+                                                   SourceRange Range,
+                                                   bool TemplateKW,
+                                                   QualType T) {
+  if (T->isDependentType() || T->isRecordType() ||
+      (SemaRef.getLangOptions().CPlusPlus0x && T->isEnumeralType())) {
+    assert(!T.hasLocalQualifiers() && "Can't get cv-qualifiers here");
+    return NestedNameSpecifier::Create(SemaRef.Context, Prefix, TemplateKW,
+                                       T.getTypePtr());
+  }
+
+  SemaRef.Diag(Range.getBegin(), diag::err_nested_name_spec_non_tag) << T;
+  return 0;
+}
+
+template<typename Derived>
+TemplateName
+TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
+                                            bool TemplateKW,
+                                            TemplateDecl *Template) {
+  return SemaRef.Context.getQualifiedTemplateName(Qualifier, TemplateKW,
+                                                  Template);
+}
+
+template<typename Derived>
+TemplateName
+TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
+                                            const IdentifierInfo &II,
+                                            QualType ObjectType) {
+  CXXScopeSpec SS;
+  SS.setRange(SourceRange(getDerived().getBaseLocation()));
+  SS.setScopeRep(Qualifier);
+  UnqualifiedId Name;
+  Name.setIdentifier(&II, /*FIXME:*/getDerived().getBaseLocation());
+  return getSema().ActOnDependentTemplateName(
+                                      /*FIXME:*/getDerived().getBaseLocation(),
+                                              SS,
+                                              Name,
+                                              ObjectType.getAsOpaquePtr(),
+                                              /*EnteringContext=*/false)
+           .template getAsVal<TemplateName>();
+}
+
+template<typename Derived>
+TemplateName
+TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
+                                            OverloadedOperatorKind Operator,
+                                            QualType ObjectType) {
+  CXXScopeSpec SS;
+  SS.setRange(SourceRange(getDerived().getBaseLocation()));
+  SS.setScopeRep(Qualifier);
+  UnqualifiedId Name;
+  SourceLocation SymbolLocations[3]; // FIXME: Bogus location information.
+  Name.setOperatorFunctionId(/*FIXME:*/getDerived().getBaseLocation(),
+                             Operator, SymbolLocations);
+  return getSema().ActOnDependentTemplateName(
+                                       /*FIXME:*/getDerived().getBaseLocation(),
+                                              SS,
+                                              Name,
+                                              ObjectType.getAsOpaquePtr(),
+                                              /*EnteringContext=*/false)
+           .template getAsVal<TemplateName>();
+}
+  
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
+                                                   SourceLocation OpLoc,
+                                                   ExprArg Callee,
+                                                   ExprArg First,
+                                                   ExprArg Second) {
+  Expr *FirstExpr = (Expr *)First.get();
+  Expr *SecondExpr = (Expr *)Second.get();
+  Expr *CalleeExpr = ((Expr *)Callee.get())->IgnoreParenCasts();
+  bool isPostIncDec = SecondExpr && (Op == OO_PlusPlus || Op == OO_MinusMinus);
+
+  // Determine whether this should be a builtin operation.
+  if (Op == OO_Subscript) {
+    if (!FirstExpr->getType()->isOverloadableType() &&
+        !SecondExpr->getType()->isOverloadableType())
+      return getSema().CreateBuiltinArraySubscriptExpr(move(First),
+                                                 CalleeExpr->getLocStart(),
+                                                       move(Second), OpLoc);
+  } else if (Op == OO_Arrow) {
+    // -> is never a builtin operation.
+    return SemaRef.BuildOverloadedArrowExpr(0, move(First), OpLoc);
+  } else if (SecondExpr == 0 || isPostIncDec) {
+    if (!FirstExpr->getType()->isOverloadableType()) {
+      // The argument is not of overloadable type, so try to create a
+      // built-in unary operation.
+      UnaryOperator::Opcode Opc
+        = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
+
+      return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, move(First));
+    }
+  } else {
+    if (!FirstExpr->getType()->isOverloadableType() &&
+        !SecondExpr->getType()->isOverloadableType()) {
+      // Neither of the arguments is an overloadable type, so try to
+      // create a built-in binary operation.
+      BinaryOperator::Opcode Opc = BinaryOperator::getOverloadedOpcode(Op);
+      OwningExprResult Result
+        = SemaRef.CreateBuiltinBinOp(OpLoc, Opc, FirstExpr, SecondExpr);
+      if (Result.isInvalid())
+        return SemaRef.ExprError();
+
+      First.release();
+      Second.release();
+      return move(Result);
+    }
+  }
+
+  // Compute the transformed set of functions (and function templates) to be
+  // used during overload resolution.
+  UnresolvedSet<16> Functions;
+
+  if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(CalleeExpr)) {
+    assert(ULE->requiresADL());
+
+    // FIXME: Do we have to check
+    // IsAcceptableNonMemberOperatorCandidate for each of these?
+    Functions.append(ULE->decls_begin(), ULE->decls_end());
+  } else {
+    Functions.addDecl(cast<DeclRefExpr>(CalleeExpr)->getDecl());
+  }
+
+  // Add any functions found via argument-dependent lookup.
+  Expr *Args[2] = { FirstExpr, SecondExpr };
+  unsigned NumArgs = 1 + (SecondExpr != 0);
+
+  // Create the overloaded operator invocation for unary operators.
+  if (NumArgs == 1 || isPostIncDec) {
+    UnaryOperator::Opcode Opc
+      = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
+    return SemaRef.CreateOverloadedUnaryOp(OpLoc, Opc, Functions, move(First));
+  }
+
+  if (Op == OO_Subscript)
+    return SemaRef.CreateOverloadedArraySubscriptExpr(CalleeExpr->getLocStart(),
+                                                      OpLoc,
+                                                      move(First),
+                                                      move(Second));
+
+  // Create the overloaded operator invocation for binary operators.
+  BinaryOperator::Opcode Opc =
+    BinaryOperator::getOverloadedOpcode(Op);
+  OwningExprResult Result
+    = SemaRef.CreateOverloadedBinOp(OpLoc, Opc, Functions, Args[0], Args[1]);
+  if (Result.isInvalid())
+    return SemaRef.ExprError();
+
+  First.release();
+  Second.release();
+  return move(Result);
+}
+
+template<typename Derived>
+Sema::OwningExprResult 
+TreeTransform<Derived>::RebuildCXXPseudoDestructorExpr(ExprArg Base,
+                                                     SourceLocation OperatorLoc,
+                                                       bool isArrow,
+                                                 NestedNameSpecifier *Qualifier,
+                                                     SourceRange QualifierRange,
+                                                     TypeSourceInfo *ScopeType,
+                                                       SourceLocation CCLoc,
+                                                       SourceLocation TildeLoc,
+                                        PseudoDestructorTypeStorage Destroyed) {
+  CXXScopeSpec SS;
+  if (Qualifier) {
+    SS.setRange(QualifierRange);
+    SS.setScopeRep(Qualifier);
+  }
+
+  Expr *BaseE = (Expr *)Base.get();
+  QualType BaseType = BaseE->getType();
+  if (BaseE->isTypeDependent() || Destroyed.getIdentifier() ||
+      (!isArrow && !BaseType->getAs<RecordType>()) ||
+      (isArrow && BaseType->getAs<PointerType>() && 
+       !BaseType->getAs<PointerType>()->getPointeeType()
+                                              ->template getAs<RecordType>())){
+    // This pseudo-destructor expression is still a pseudo-destructor.
+    return SemaRef.BuildPseudoDestructorExpr(move(Base), OperatorLoc,
+                                             isArrow? tok::arrow : tok::period,
+                                             SS, ScopeType, CCLoc, TildeLoc,
+                                             Destroyed,
+                                             /*FIXME?*/true);
+  }
+  
+  TypeSourceInfo *DestroyedType = Destroyed.getTypeSourceInfo();
+  DeclarationName Name
+    = SemaRef.Context.DeclarationNames.getCXXDestructorName(
+                SemaRef.Context.getCanonicalType(DestroyedType->getType()));
+  
+  // FIXME: the ScopeType should be tacked onto SS.
+  
+  return getSema().BuildMemberReferenceExpr(move(Base), BaseType,
+                                            OperatorLoc, isArrow,
+                                            SS, /*FIXME: FirstQualifier*/ 0,
+                                            Name, Destroyed.getLocation(),
+                                            /*TemplateArgs*/ 0);
+}
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_SEMA_TREETRANSFORM_H
diff --git a/test/ASTMerge/Inputs/category1.m b/test/ASTMerge/Inputs/category1.m
new file mode 100644
index 0000000..ade1c6c
--- /dev/null
+++ b/test/ASTMerge/Inputs/category1.m
@@ -0,0 +1,25 @@
+@interface I1 
+@end
+
+// Matching category
+@interface I1 (Cat1)
+- (int)method0;
+@end
+
+// Matching class extension
+@interface I1 ()
+- (int)method1;
+@end
+
+// Mismatched category
+@interface I1 (Cat2)
+- (int)method2;
+@end
+
+@interface I2
+@end
+
+// Mismatched class extension
+@interface I2 ()
+- (int)method3;
+@end
diff --git a/test/ASTMerge/Inputs/category2.m b/test/ASTMerge/Inputs/category2.m
new file mode 100644
index 0000000..f66c208
--- /dev/null
+++ b/test/ASTMerge/Inputs/category2.m
@@ -0,0 +1,27 @@
+typedef int Int;
+
+@interface I1 
+@end
+
+// Matching category
+@interface I1 (Cat1)
+- (Int)method0;
+@end
+
+// Matching class extension
+@interface I1 ()
+- (Int)method1;
+@end
+
+// Mismatched category
+@interface I1 (Cat2)
+- (float)method2;
+@end
+
+@interface I2
+@end
+
+// Mismatched class extension
+@interface I2 ()
+- (float)method3;
+@end
diff --git a/test/ASTMerge/Inputs/enum1.c b/test/ASTMerge/Inputs/enum1.c
new file mode 100644
index 0000000..f2b9c5c
--- /dev/null
+++ b/test/ASTMerge/Inputs/enum1.c
@@ -0,0 +1,42 @@
+// Matching
+enum E1 {
+  E1Enumerator1,
+  E1Enumerator2 = 3,
+  E1Enumerator3
+} x1;
+
+// Value mismatch
+enum E2 {
+  E2Enumerator1,
+  E2Enumerator2 = 3,
+  E2Enumerator3
+} x2;
+
+// Name mismatch
+enum E3 {
+  E3Enumerator1,
+  E3Enumerator2 = 3,
+  E3Enumerator3
+} x3;
+
+// Missing enumerator
+enum E4 {
+  E4Enumerator1,
+  E4Enumerator2,
+  E4Enumerator3
+} x4;
+
+// Extra enumerator
+enum E5 {
+  E5Enumerator1,
+  E5Enumerator2,
+  E5Enumerator3
+} x5;
+
+// Matching, with typedef
+typedef enum {
+  E6Enumerator1,
+  E6Enumerator2
+} E6;
+
+E6 x6;
diff --git a/test/ASTMerge/Inputs/enum2.c b/test/ASTMerge/Inputs/enum2.c
new file mode 100644
index 0000000..315b4dc
--- /dev/null
+++ b/test/ASTMerge/Inputs/enum2.c
@@ -0,0 +1,42 @@
+// Matching
+enum E1 {
+  E1Enumerator1,
+  E1Enumerator2 = 3,
+  E1Enumerator3
+} x1;
+
+// Value mismatch
+enum E2 {
+  E2Enumerator1,
+  E2Enumerator2 = 4,
+  E2Enumerator3
+} x2;
+
+// Name mismatch
+enum E3 {
+  E3Enumerator1,
+  E3Enumerator = 3,
+  E3Enumerator3
+} x3;
+
+// Missing enumerator
+enum E4 {
+  E4Enumerator1,
+  E4Enumerator2
+} x4;
+
+// Extra enumerator
+enum E5 {
+  E5Enumerator1,
+  E5Enumerator2,
+  E5Enumerator3,
+  E5Enumerator4
+} x5;
+
+// Matching, with typedef
+typedef enum {
+  E6Enumerator1,
+  E6Enumerator2
+} E6;
+
+E6 x6;
diff --git a/test/ASTMerge/Inputs/exprs1.c b/test/ASTMerge/Inputs/exprs1.c
new file mode 100644
index 0000000..1c268da
--- /dev/null
+++ b/test/ASTMerge/Inputs/exprs1.c
@@ -0,0 +1,10 @@
+// Matching
+enum E0 {
+  E0_Val0 = 'a',
+  E0_Val1 = (17),
+  E0_Val2 = (1 << 2),
+  E0_Val3 = E0_Val2,
+  E0_Val4 = sizeof(int*),
+  E0_Val5 = (unsigned int)-1
+};
+
diff --git a/test/ASTMerge/Inputs/exprs2.c b/test/ASTMerge/Inputs/exprs2.c
new file mode 100644
index 0000000..1c268da
--- /dev/null
+++ b/test/ASTMerge/Inputs/exprs2.c
@@ -0,0 +1,10 @@
+// Matching
+enum E0 {
+  E0_Val0 = 'a',
+  E0_Val1 = (17),
+  E0_Val2 = (1 << 2),
+  E0_Val3 = E0_Val2,
+  E0_Val4 = sizeof(int*),
+  E0_Val5 = (unsigned int)-1
+};
+
diff --git a/test/ASTMerge/Inputs/function1.c b/test/ASTMerge/Inputs/function1.c
new file mode 100644
index 0000000..4523bd3
--- /dev/null
+++ b/test/ASTMerge/Inputs/function1.c
@@ -0,0 +1,6 @@
+void f0(int);
+void f1(int, float);
+void f2();
+void f3(void);
+void f4(int, int);
+int f5(int) __attribute__((const));
diff --git a/test/ASTMerge/Inputs/function2.c b/test/ASTMerge/Inputs/function2.c
new file mode 100644
index 0000000..6ca810a
--- /dev/null
+++ b/test/ASTMerge/Inputs/function2.c
@@ -0,0 +1,7 @@
+typedef int Int;
+void f0(Int);
+void f1(Int, double);
+void f2(int, int);
+void f3(int);
+static void f4(float, float);
+int f5(int) __attribute__((const));
diff --git a/test/ASTMerge/Inputs/interface1.m b/test/ASTMerge/Inputs/interface1.m
new file mode 100644
index 0000000..7e9935d
--- /dev/null
+++ b/test/ASTMerge/Inputs/interface1.m
@@ -0,0 +1,81 @@
+// Matches
+@interface I1 {
+  int ivar1;
+}
+@end
+
+// Matches
+@interface I2 : I1 {
+  float ivar2;
+}
+@end
+
+// Ivar mismatch
+@interface I3 {
+  int ivar1;
+  int ivar2;
+}
+@end
+
+// Superclass mismatch
+@interface I4 : I2 {
+}
+@end
+
+// Methods match
+@interface I5
+- (int)foo;
++ (float)bar;
+@end
+
+// Method mismatch
+@interface I6
+- (int)foo;
++ (int)foo;
+@end
+
+// Method mismatch
+@interface I7
+- (int)foo;
++ (int)bar:(int)x;
+@end
+
+// Method mismatch
+@interface I8
+- (int)foo;
++ (int)bar:(float)x;
+@end
+
+// Matching protocol
+@protocol P0
++ (int)foo;
+- (int)bar:(float)x;
+@end
+
+// Protocol with mismatching method
+@protocol P1
++ (int)foo;
+- (int)bar:(float)x;
+@end
+
+// Interface with protocol
+@interface I9 <P0>
++ (int)foo;
+- (int)bar:(float)x;
+@end
+
+// Protocol with protocol
+@protocol P2 <P0>
+- (float)wibble:(int)a1 second:(int)a2;
+@end
+
+// Forward-declared interfaces
+@class I10, I11;
+@interface I12
+@end
+
+// Forward-declared protocols
+@protocol P3, P5;
+@protocol P4
+- (double)honk:(int)a;
+@end
diff --git a/test/ASTMerge/Inputs/interface2.m b/test/ASTMerge/Inputs/interface2.m
new file mode 100644
index 0000000..bef7fb8
--- /dev/null
+++ b/test/ASTMerge/Inputs/interface2.m
@@ -0,0 +1,80 @@
+// Matches
+@interface I1 {
+  int ivar1;
+}
+@end
+
+// Matches
+@interface I2 : I1 {
+  float ivar2;
+}
+@end
+
+// Ivar mismatch
+@interface I3 {
+  int ivar1;
+  float ivar2;
+}
+@end
+
+// Superclass mismatch
+@interface I4 : I1 {
+}
+@end
+
+// Methods match
+@interface I5
++ (float)bar;
+- (int)foo;
+@end
+
+// Method mismatch
+@interface I6
++ (float)foo;
+@end
+
+// Method mismatch
+@interface I7
+- (int)foo;
++ (int)bar:(float)x;
+@end
+
+// Method mismatch
+@interface I8
+- (int)foo;
++ (int)bar:(float)x, ...;
+@end
+
+// Matching protocol
+@protocol P0
++ (int)foo;
+- (int)bar:(float)x;
+@end
+
+// Protocol with mismatching method
+@protocol P1
++ (int)foo;
+- (int)bar:(double)x;
+@end
+
+// Interface with protocol
+@interface I9 <P0>
++ (int)foo;
+- (int)bar:(float)x;
+@end
+
+// Protocol with protocol
+@protocol P2 <P0>
+- (float)wibble:(int)a1 second:(int)a2;
+@end
+
+// Forward-declared interface
+@class I12, I10;
+@interface I11
+@end
+
+// Forward-declared protocols
+@protocol P3, P4;
+@protocol P5
+- (double)honk:(int)a;
+@end
diff --git a/test/ASTMerge/Inputs/lit.local.cfg b/test/ASTMerge/Inputs/lit.local.cfg
new file mode 100644
index 0000000..e6f55ee
--- /dev/null
+++ b/test/ASTMerge/Inputs/lit.local.cfg
@@ -0,0 +1 @@
+config.suffixes = []
diff --git a/test/ASTMerge/Inputs/namespace1.cpp b/test/ASTMerge/Inputs/namespace1.cpp
new file mode 100644
index 0000000..1ff84f3
--- /dev/null
+++ b/test/ASTMerge/Inputs/namespace1.cpp
@@ -0,0 +1,17 @@
+// Merge success
+namespace N1 {
+  int x;
+}
+
+// Merge multiple namespaces
+namespace N2 {
+  extern int x;
+}
+namespace N2 {
+  extern float y;
+}
+
+// Merge namespace with conflict
+namespace N3 {
+  extern float z;
+}
diff --git a/test/ASTMerge/Inputs/namespace2.cpp b/test/ASTMerge/Inputs/namespace2.cpp
new file mode 100644
index 0000000..80429f7
--- /dev/null
+++ b/test/ASTMerge/Inputs/namespace2.cpp
@@ -0,0 +1,17 @@
+// Merge success
+namespace N1 {
+  extern int x0;
+}
+
+// Merge multiple namespaces
+namespace N2 {
+  extern int x;
+}
+namespace N2 {
+  extern float y;
+}
+
+// Merge namespace with conflict
+namespace N3 {
+  extern double z;
+}
diff --git a/test/ASTMerge/Inputs/property1.m b/test/ASTMerge/Inputs/property1.m
new file mode 100644
index 0000000..37887a3
--- /dev/null
+++ b/test/ASTMerge/Inputs/property1.m
@@ -0,0 +1,12 @@
+// Matching properties
+@interface I1 {
+}
+- (int)getProp2;
+- (void)setProp2:(int)value;
+@end
+
+// Mismatched property
+@interface I2
+@property (readonly) float Prop1;
+@end
+
diff --git a/test/ASTMerge/Inputs/property2.m b/test/ASTMerge/Inputs/property2.m
new file mode 100644
index 0000000..6039f10
--- /dev/null
+++ b/test/ASTMerge/Inputs/property2.m
@@ -0,0 +1,13 @@
+// Matching properties
+@interface I1 {
+}
+- (int)getProp2;
+- (void)setProp2:(int)value;
+@property (readonly) int Prop1;
+@property (getter = getProp2, setter = setProp2:) int Prop2;
+@end
+
+// Mismatched property
+@interface I2
+@property (readonly) int Prop1;
+@end
diff --git a/test/ASTMerge/Inputs/struct1.c b/test/ASTMerge/Inputs/struct1.c
new file mode 100644
index 0000000..af2af8a
--- /dev/null
+++ b/test/ASTMerge/Inputs/struct1.c
@@ -0,0 +1,63 @@
+typedef int Int;
+typedef float Float;
+
+// Matches
+struct S0 {
+  Int field1;
+  Float field2;
+};
+
+struct S0 x0;
+
+// Mismatch in field type
+struct S1 {
+  Int field1;
+  int field2;
+};
+
+struct S1 x1;
+
+// Mismatch in tag kind.
+struct S2 { int i; float f; } x2;
+
+// Missing fields
+struct S3 { int i; float f; double d; } x3;
+
+// Extra fields
+struct S4 { int i; } x4;
+
+// Bit-field matches
+struct S5 { int i : 8; unsigned j : 8; } x5;
+
+// Bit-field mismatch
+struct S6 { int i : 8; unsigned j : 8; } x6;
+
+// Bit-field mismatch
+struct S7 { int i : 8; unsigned j : 8; } x7;
+
+// Incomplete type
+struct S8 *x8;
+
+// Incomplete type
+struct S9 { int i; float f; } *x9;
+
+// Incomplete type
+struct S10 *x10;
+
+// Matches
+struct ListNode {
+  int value;
+  struct ListNode *Next;
+} xList;
+
+// Mismatch due to struct used internally
+struct DeepError {
+  int value;
+  struct DeeperError { int i; int f; } *Deeper;
+} xDeep;
+
+// Matches
+struct {
+  Int i;
+  float f;
+} x11;
diff --git a/test/ASTMerge/Inputs/struct2.c b/test/ASTMerge/Inputs/struct2.c
new file mode 100644
index 0000000..4b43df7
--- /dev/null
+++ b/test/ASTMerge/Inputs/struct2.c
@@ -0,0 +1,60 @@
+// Matches
+struct S0 {
+  int field1;
+  float field2;
+};
+
+struct S0 x0;
+
+// Mismatch in field type
+struct S1 {
+  int field1;
+  float field2;
+};
+
+struct S1 x1;
+
+// Mismatch in tag kind.
+union S2 { int i; float f; } x2;
+
+// Missing fields
+struct S3 { int i; float f; } x3;
+
+// Extra fields
+struct S4 { int i; float f; } x4;
+
+// Bit-field matches
+struct S5 { int i : 8; unsigned j : 8; } x5;
+
+// Bit-field mismatch
+struct S6 { int i : 8; unsigned j; } x6;
+
+// Bit-field mismatch
+struct S7 { int i : 8; unsigned j : 16; } x7;
+
+// Incomplete type
+struct S8 { int i; float f; } *x8;
+
+// Incomplete type
+struct S9 *x9;
+
+// Incomplete type
+struct S10 *x10;
+
+// Matches
+struct ListNode {
+  int value;
+  struct ListNode *Next;
+} xList;
+
+// Mismatch due to struct used internally
+struct DeepError {
+  int value;
+  struct DeeperError { int i; float f; } *Deeper;
+} xDeep;
+
+// Matches
+struct {
+  int i;
+  float f;
+} x11;
diff --git a/test/ASTMerge/Inputs/typedef1.c b/test/ASTMerge/Inputs/typedef1.c
new file mode 100644
index 0000000..5657675
--- /dev/null
+++ b/test/ASTMerge/Inputs/typedef1.c
@@ -0,0 +1,4 @@
+typedef int Typedef1;
+typedef int Typedef2;
+Typedef1 x1;
+Typedef2 x2;
diff --git a/test/ASTMerge/Inputs/typedef2.c b/test/ASTMerge/Inputs/typedef2.c
new file mode 100644
index 0000000..129d710
--- /dev/null
+++ b/test/ASTMerge/Inputs/typedef2.c
@@ -0,0 +1,4 @@
+typedef int Typedef1;
+typedef double Typedef2;
+Typedef1 x1;
+Typedef2 x2;
diff --git a/test/ASTMerge/Inputs/var1.c b/test/ASTMerge/Inputs/var1.c
new file mode 100644
index 0000000..4f5cbe1
--- /dev/null
+++ b/test/ASTMerge/Inputs/var1.c
@@ -0,0 +1,7 @@
+int *x0;
+float **x1;
+#include "var1.h"
+int xarray0[17];
+int xarray1[];
+int xarray2[18];
+int xarray3[18];
diff --git a/test/ASTMerge/Inputs/var1.h b/test/ASTMerge/Inputs/var1.h
new file mode 100644
index 0000000..1518e17
--- /dev/null
+++ b/test/ASTMerge/Inputs/var1.h
@@ -0,0 +1 @@
+double x2;
diff --git a/test/ASTMerge/Inputs/var2.c b/test/ASTMerge/Inputs/var2.c
new file mode 100644
index 0000000..01986e4
--- /dev/null
+++ b/test/ASTMerge/Inputs/var2.c
@@ -0,0 +1,7 @@
+int *x0;
+double *x1;
+int x2;
+int xarray0[17];
+int xarray1[17];
+int xarray2[];
+int xarray3[17];
diff --git a/test/ASTMerge/category.m b/test/ASTMerge/category.m
new file mode 100644
index 0000000..6ba2292
--- /dev/null
+++ b/test/ASTMerge/category.m
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/category1.m
+// RUN: %clang_cc1 -emit-pch -o %t.2.ast %S/Inputs/category2.m
+// RUN: %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s
+
+// CHECK: category2.m:18:1: error: instance method 'method2' has incompatible result types in different translation units ('float' vs. 'int')
+// CHECK: category1.m:16:1: note: instance method 'method2' also declared here
+// CHECK: category2.m:26:1: error: instance method 'method3' has incompatible result types in different translation units ('float' vs. 'int')
+// CHECK: category1.m:24:1: note: instance method 'method3' also declared here
+// CHECK: 2 errors generated.
diff --git a/test/ASTMerge/enum.c b/test/ASTMerge/enum.c
new file mode 100644
index 0000000..4380d19
--- /dev/null
+++ b/test/ASTMerge/enum.c
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/enum1.c
+// RUN: %clang_cc1 -emit-pch -o %t.2.ast %S/Inputs/enum2.c
+// RUN: %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s
+
+// CHECK: enum1.c:9:6: warning: type 'enum E2' has incompatible definitions in different translation units
+// CHECK: enum1.c:11:3: note: enumerator 'E2Enumerator2' with value 3 here
+// CHECK: enum2.c:11:3: note: enumerator 'E2Enumerator2' with value 4 here
+// CHECK: enum2.c:13:3: error: external variable 'x2' declared with incompatible types in different translation units ('enum E2' vs. 'enum E2')
+// CHECK: enum1.c:13:3: note: declared here with type 'enum E2'
+// CHECK: enum1.c:16:6: warning: type 'enum E3' has incompatible definitions in different translation units
+// CHECK: enum1.c:18:3: note: enumerator 'E3Enumerator2' with value 3 here
+// CHECK: enum2.c:18:3: note: enumerator 'E3Enumerator' with value 3 here
+// CHECK: enum2.c:20:3: error: external variable 'x3' declared with incompatible types in different translation units ('enum E3' vs. 'enum E3')
+// CHECK: enum1.c:20:3: note: declared here with type 'enum E3'
+// CHECK: enum1.c:23:6: warning: type 'enum E4' has incompatible definitions in different translation units
+// CHECK: enum1.c:26:3: note: enumerator 'E4Enumerator3' with value 2 here
+// CHECK: enum2.c:23:6: note: no corresponding enumerator here
+// CHECK: enum2.c:26:3: error: external variable 'x4' declared with incompatible types in different translation units ('enum E4' vs. 'enum E4')
+// CHECK: enum1.c:27:3: note: declared here with type 'enum E4'
+// CHECK: enum1.c:30:6: warning: type 'enum E5' has incompatible definitions in different translation units
+// CHECK: enum2.c:33:3: note: enumerator 'E5Enumerator4' with value 3 here
+// CHECK: enum1.c:30:6: note: no corresponding enumerator here
+// CHECK: enum2.c:34:3: error: external variable 'x5' declared with incompatible types in different translation units ('enum E5' vs. 'enum E5')
+// CHECK: enum1.c:34:3: note: declared here with type 'enum E5'
+// CHECK: 4 warnings and 4 errors generated
diff --git a/test/ASTMerge/exprs.c b/test/ASTMerge/exprs.c
new file mode 100644
index 0000000..0a4e1e5
--- /dev/null
+++ b/test/ASTMerge/exprs.c
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/exprs1.c
+// RUN: %clang_cc1 -emit-pch -o %t.2.ast %S/Inputs/exprs2.c
+// RUN: %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only -verify %s
+
diff --git a/test/ASTMerge/function.c b/test/ASTMerge/function.c
new file mode 100644
index 0000000..f97ecee
--- /dev/null
+++ b/test/ASTMerge/function.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/function1.c
+// RUN: %clang_cc1 -emit-pch -o %t.2.ast %S/Inputs/function2.c
+// RUN: %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s
+
+// CHECK: function2.c:3:6: error: external function 'f1' declared with incompatible types in different translation units ('void (Int, double)' vs. 'void (int, float)')
+// CHECK: function1.c:2:6: note: declared here with type 'void (int, float)'
+// CHECK: function2.c:5:6: error: external function 'f3' declared with incompatible types in different translation units ('void (int)' vs. 'void (void)')
+// CHECK: function1.c:4:6: note: declared here with type 'void (void)'
+// CHECK: 2 errors generated
diff --git a/test/ASTMerge/interface.m b/test/ASTMerge/interface.m
new file mode 100644
index 0000000..420ae38
--- /dev/null
+++ b/test/ASTMerge/interface.m
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/interface1.m
+// RUN: %clang_cc1 -emit-pch -o %t.2.ast %S/Inputs/interface2.m
+// RUN: %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s
+
+// CHECK: interface2.m:16:9: error: instance variable 'ivar2' declared with incompatible types in different translation units ('float' vs. 'int')
+// CHECK: interface1.m:16:7: note: declared here with type 'int'
+// CHECK: interface1.m:21:1: error: class 'I4' has incompatible superclasses
+// CHECK: interface1.m:21:17: note: inherits from superclass 'I2' here
+// CHECK: interface2.m:21:17: note: inherits from superclass 'I1' here
+// CHECK: interface2.m:33:1: error: class method 'foo' has incompatible result types in different translation units ('float' vs. 'int')
+// CHECK: interface1.m:34:1: note: class method 'foo' also declared here
+// CHECK: interface2.m:39:19: error: class method 'bar:' has a parameter with a different types in different translation units ('float' vs. 'int')
+// CHECK: interface1.m:40:17: note: declared here with type 'int'
+// CHECK: interface2.m:45:1: error: class method 'bar:' is variadic in one translation unit and not variadic in another
+// CHECK: interface1.m:46:1: note: class method 'bar:' also declared here
+// CHECK: interface2.m:57:20: error: instance method 'bar:' has a parameter with a different types in different translation units ('double' vs. 'float')
+// CHECK: interface1.m:58:19: note: declared here with type 'float'
+// CHECK: 6 errors generated
+
diff --git a/test/ASTMerge/namespace.cpp b/test/ASTMerge/namespace.cpp
new file mode 100644
index 0000000..6c46f0a
--- /dev/null
+++ b/test/ASTMerge/namespace.cpp
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/namespace1.cpp
+// RUN: %clang_cc1 -emit-pch -o %t.2.ast %S/Inputs/namespace2.cpp
+// RUN: %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s
+
+// CHECK: namespace2.cpp:16:17: error: external variable 'z' declared with incompatible types in different translation units ('double' vs. 'float')
+// CHECK: namespace1.cpp:16:16: note: declared here with type 'float'
diff --git a/test/ASTMerge/property.m b/test/ASTMerge/property.m
new file mode 100644
index 0000000..5f7a730
--- /dev/null
+++ b/test/ASTMerge/property.m
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/property1.m
+// RUN: %clang_cc1 -emit-pch -o %t.2.ast %S/Inputs/property2.m
+// RUN: %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s
+
+// CHECK: property2.m:12:26: error: property 'Prop1' declared with incompatible types in different translation units ('int' vs. 'float')
+// CHECK: property1.m:10:28: note: declared here with type 'float'
+// CHECK: property2.m:12:26: error: instance method 'Prop1' has incompatible result types in different translation units ('int' vs. 'float')
+// CHECK: property1.m:10:28: note: instance method 'Prop1' also declared here
+// CHECK: 2 errors generated.
diff --git a/test/ASTMerge/struct.c b/test/ASTMerge/struct.c
new file mode 100644
index 0000000..7217222
--- /dev/null
+++ b/test/ASTMerge/struct.c
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/struct1.c
+// RUN: %clang_cc1 -emit-pch -o %t.2.ast %S/Inputs/struct2.c
+// RUN: %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s
+
+// CHECK: struct1.c:13:8: warning: type 'struct S1' has incompatible definitions in different translation units
+// CHECK: struct1.c:15:7: note: field 'field2' has type 'int' here
+// CHECK: struct2.c:12:9: note: field 'field2' has type 'float' here
+// CHECK: struct2.c:15:11: error: external variable 'x1' declared with incompatible types in different translation units ('struct S1' vs. 'struct S1')
+// CHECK: struct1.c:18:11: note: declared here with type 'struct S1'
+// CHECK: struct1.c:21:8: warning: type 'struct S2' has incompatible definitions in different translation units
+// CHECK: struct2.c:18:7: note: 'S2' is a union here
+// CHECK: struct2.c:18:30: error: external variable 'x2' declared with incompatible types in different translation units ('union S2' vs. 'struct S2')
+// CHECK: struct1.c:21:31: note: declared here with type 'struct S2'
+// CHECK: struct1.c:24:8: warning: type 'struct S3' has incompatible definitions in different translation units
+// CHECK: struct1.c:24:36: note: field 'd' has type 'double' here
+// CHECK: struct2.c:21:8: note: no corresponding field here
+// CHECK: struct2.c:21:31: error: external variable 'x3' declared with incompatible types in different translation units ('struct S3' vs. 'struct S3')
+// CHECK: struct1.c:24:41: note: declared here with type 'struct S3'
+// CHECK: struct1.c:27:8: warning: type 'struct S4' has incompatible definitions in different translation units
+// CHECK: struct2.c:24:26: note: field 'f' has type 'float' here
+// CHECK: struct1.c:27:8: note: no corresponding field here
+// CHECK: struct2.c:24:31: error: external variable 'x4' declared with incompatible types in different translation units ('struct S4' vs. 'struct S4')
+// CHECK: struct1.c:27:22: note: declared here with type 'struct S4'
+// CHECK: struct1.c:33:8: warning: type 'struct S6' has incompatible definitions in different translation units
+// CHECK: struct1.c:33:33: note: bit-field 'j' with type 'unsigned int' and length 8 here
+// CHECK: struct2.c:30:33: note: field 'j' is not a bit-field
+// CHECK: struct2.c:30:38: error: external variable 'x6' declared with incompatible types in different translation units ('struct S6' vs. 'struct S6')
+// CHECK: struct1.c:33:42: note: declared here with type 'struct S6'
+// CHECK: struct1.c:36:8: warning: type 'struct S7' has incompatible definitions in different translation units
+// CHECK: struct1.c:36:33: note: bit-field 'j' with type 'unsigned int' and length 8 here
+// CHECK: struct2.c:33:33: note: bit-field 'j' with type 'unsigned int' and length 16 here
+// CHECK: struct2.c:33:43: error: external variable 'x7' declared with incompatible types in different translation units ('struct S7' vs. 'struct S7')
+// CHECK: struct1.c:36:42: note: declared here with type 'struct S7'
+// CHECK: struct1.c:56:10: warning: type 'struct DeeperError' has incompatible definitions in different translation units
+// CHECK: struct1.c:56:35: note: field 'f' has type 'int' here
+// CHECK: struct2.c:53:37: note: field 'f' has type 'float' here
+// CHECK: struct1.c:54:8: warning: type 'struct DeepError' has incompatible definitions in different translation units
+// CHECK: struct1.c:56:41: note: field 'Deeper' has type 'struct DeeperError *' here
+// CHECK: struct2.c:53:43: note: field 'Deeper' has type 'struct DeeperError *' here
+// CHECK: struct2.c:54:3: error: external variable 'xDeep' declared with incompatible types in different translation units ('struct DeepError' vs. 'struct DeepError')
+// CHECK: struct1.c:57:3: note: declared here with type 'struct DeepError'
+// CHECK: 8 warnings and 7 errors generated
diff --git a/test/ASTMerge/typedef.c b/test/ASTMerge/typedef.c
new file mode 100644
index 0000000..6f91129
--- /dev/null
+++ b/test/ASTMerge/typedef.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/typedef1.c
+// RUN: %clang_cc1 -emit-pch -o %t.2.ast %S/Inputs/typedef2.c
+// RUN: %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s
+
+// CHECK: typedef2.c:4:10: error: external variable 'x2' declared with incompatible types in different translation units ('Typedef2' (aka 'double') vs. 'Typedef2' (aka 'int'))
+// CHECK: typedef1.c:4:10: note: declared here with type 'Typedef2' (aka 'int')
+// CHECK: 1 error
diff --git a/test/ASTMerge/var.c b/test/ASTMerge/var.c
new file mode 100644
index 0000000..7f23b9f
--- /dev/null
+++ b/test/ASTMerge/var.c
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/var1.c
+// RUN: %clang_cc1 -emit-pch -o %t.2.ast %S/Inputs/var2.c
+// RUN: %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s
+
+// CHECK: var2.c:2:9: error: external variable 'x1' declared with incompatible types in different translation units ('double *' vs. 'float **')
+// CHECK: var1.c:2:9: note: declared here with type 'float **'
+// CHECK: var2.c:3:5: error: external variable 'x2' declared with incompatible types in different translation units ('int' vs. 'double')
+// CHECK: In file included from{{.*}}var1.c:3:
+// CHECK: var1.h:1:8: note: declared here with type 'double'
+// CHECK: error: external variable 'xarray3' declared with incompatible types in different translation units ('int [17]' vs. 'int [18]')
+// CHECK: var1.c:7:5: note: declared here with type 'int [18]'
+// CHECK: 3 errors
diff --git a/test/Analysis/CFDateGC.m b/test/Analysis/CFDateGC.m
new file mode 100644
index 0000000..abcefde
--- /dev/null
+++ b/test/Analysis/CFDateGC.m
@@ -0,0 +1,89 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -verify -fobjc-gc -analyzer-constraints=basic %s  -Wno-implicit-function-declaration
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -verify -fobjc-gc -analyzer-constraints=range %s  -Wno-implicit-function-declaration
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -verify -fobjc-gc -disable-free %s  -Wno-implicit-function-declaration
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=basic -verify -fobjc-gc %s  -Wno-implicit-function-declaration
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -verify -fobjc-gc %s  -Wno-implicit-function-declaration
+
+//===----------------------------------------------------------------------===//
+// The following code is reduced using delta-debugging from
+// Foundation.h and CoreFoundation.h (Mac OS X).
+//
+// It includes the basic definitions for the test cases below.
+// Not directly including [Core]Foundation.h directly makes this test case 
+// both svelte and portable to non-Mac platforms.
+//===----------------------------------------------------------------------===//
+
+typedef const void * CFTypeRef;
+void CFRelease(CFTypeRef cf);
+CFTypeRef CFRetain(CFTypeRef cf);
+CFTypeRef CFMakeCollectable(CFTypeRef cf);
+typedef const struct __CFAllocator * CFAllocatorRef;
+typedef double CFTimeInterval;
+typedef CFTimeInterval CFAbsoluteTime;
+typedef const struct __CFDate * CFDateRef;
+extern CFDateRef CFDateCreate(CFAllocatorRef allocator, CFAbsoluteTime at);
+extern CFAbsoluteTime CFDateGetAbsoluteTime(CFDateRef theDate);
+typedef struct objc_object {} *id;
+typedef signed char BOOL;
+static __inline__ __attribute__((always_inline)) id NSMakeCollectable(CFTypeRef cf) { return 0; }
+@protocol NSObject  - (BOOL)isEqual:(id)object;
+- (oneway void)release;
+- (id)retain;
+@end
+@class NSArray;
+
+//===----------------------------------------------------------------------===//
+// Test cases.
+//===----------------------------------------------------------------------===//
+
+CFAbsoluteTime CFAbsoluteTimeGetCurrent();
+
+CFAbsoluteTime f1_use_after_release() {
+  CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
+  CFDateRef date = CFDateCreate(0, t);
+  CFRetain(date);
+  [NSMakeCollectable(date) release];
+  CFDateGetAbsoluteTime(date); // no-warning
+  CFRelease(date);
+  t = CFDateGetAbsoluteTime(date);   // expected-warning{{Reference-counted object is used after it is released.}}
+  return t;
+}
+
+// The following two test cases verifies that CFMakeCollectable is a no-op
+// in non-GC mode and a "release" in GC mode.
+CFAbsoluteTime f2_use_after_release() {
+  CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
+  CFDateRef date = CFDateCreate(0, t);
+  CFRetain(date);
+  [(id) CFMakeCollectable(date) release];
+  CFDateGetAbsoluteTime(date); // no-warning
+  CFRelease(date);
+  t = CFDateGetAbsoluteTime(date);   // expected-warning{{Reference-counted object is used after it is released.}}
+  return t;
+}
+
+CFAbsoluteTime f2_noleak() {
+  CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
+  CFDateRef date = CFDateCreate(0, t);
+  CFRetain(date);
+  [(id) CFMakeCollectable(date) release];
+  CFDateGetAbsoluteTime(date); // no-warning
+  t = CFDateGetAbsoluteTime(date);  // no-warning
+  CFRelease(date); // no-warning
+  return t;
+}
+
+void f3_leak_with_gc() {
+  CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); // expected-warning 2 {{leak}}
+  [[(id) date retain] release];
+}
+
+// The following test case verifies that we "stop tracking" a retained object
+// when it is passed as an argument to an implicitly defined function.
+CFAbsoluteTime f4() {
+  CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
+  CFDateRef date = CFDateCreate(0, t);
+  CFRetain(date);
+  some_implicitly_defined_function_stop_tracking(date); // no-warning
+  return t;
+}
diff --git a/test/Analysis/CFNumber.c b/test/Analysis/CFNumber.c
new file mode 100644
index 0000000..544644a
--- /dev/null
+++ b/test/Analysis/CFNumber.c
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=basic -verify -triple x86_64-apple-darwin9 %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=range -verify -triple x86_64-apple-darwin9 %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=basic -verify -triple x86_64-apple-darwin9 %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -verify -triple x86_64-apple-darwin9 %s
+
+typedef signed long CFIndex;
+typedef const struct __CFAllocator * CFAllocatorRef;
+enum { kCFNumberSInt8Type = 1, kCFNumberSInt16Type = 2,
+       kCFNumberSInt32Type = 3, kCFNumberSInt64Type = 4,
+       kCFNumberFloat32Type = 5, kCFNumberFloat64Type = 6,
+       kCFNumberCharType = 7, kCFNumberShortType = 8,
+       kCFNumberIntType = 9, kCFNumberLongType = 10,
+       kCFNumberLongLongType = 11, kCFNumberFloatType = 12,
+       kCFNumberDoubleType = 13, kCFNumberCFIndexType = 14,
+       kCFNumberNSIntegerType = 15, kCFNumberCGFloatType = 16,
+       kCFNumberMaxType = 16 };
+typedef CFIndex CFNumberType;
+typedef const struct __CFNumber * CFNumberRef;
+extern CFNumberRef CFNumberCreate(CFAllocatorRef allocator, CFNumberType theType, const void *valuePtr);
+
+CFNumberRef f1(unsigned char x) {
+  return CFNumberCreate(0, kCFNumberSInt16Type, &x);  // expected-warning{{An 8 bit integer is used to initialize a CFNumber object that represents a 16 bit integer. 8 bits of the CFNumber value will be garbage.}}
+}
+
+CFNumberRef f2(unsigned short x) {
+  return CFNumberCreate(0, kCFNumberSInt8Type, &x); // expected-warning{{A 16 bit integer is used to initialize a CFNumber object that represents an 8 bit integer. 8 bits of the input integer will be lost.}}
+}
+
+CFNumberRef f3(unsigned i) {
+  return CFNumberCreate(0, kCFNumberLongType, &i); // expected-warning{{A 32 bit integer is used to initialize a CFNumber object that represents a 64 bit integer.}}
+}
diff --git a/test/Analysis/CFRetainRelease_NSAssertionHandler.m b/test/Analysis/CFRetainRelease_NSAssertionHandler.m
new file mode 100644
index 0000000..ce9e6ff
--- /dev/null
+++ b/test/Analysis/CFRetainRelease_NSAssertionHandler.m
@@ -0,0 +1,67 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -verify %s -analyzer-constraints=basic -analyzer-store=basic
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -verify %s -analyzer-constraints=range -analyzer-store=basic
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -verify %s -analyzer-constraints=basic -analyzer-store=region
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -verify %s -analyzer-constraints=range -analyzer-store=region
+
+typedef struct objc_selector *SEL;
+typedef signed char BOOL;
+typedef int NSInteger;
+typedef unsigned int NSUInteger;
+typedef struct _NSZone NSZone;
+@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+@protocol NSObject  - (BOOL)isEqual:(id)object; @end
+@protocol NSCopying  - (id)copyWithZone:(NSZone *)zone; @end
+@protocol NSMutableCopying  - (id)mutableCopyWithZone:(NSZone *)zone; @end
+@protocol NSCoding  - (void)encodeWithCoder:(NSCoder *)aCoder; @end
+@interface NSObject <NSObject> {} - (id)init; @end
+extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone);
+@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding>
+- (NSUInteger)length;
++ (id)stringWithUTF8String:(const char *)nullTerminatedCString;
+@end extern NSString * const NSBundleDidLoadNotification;
+@interface NSAssertionHandler : NSObject {}
++ (NSAssertionHandler *)currentHandler;
+- (void)handleFailureInMethod:(SEL)selector object:(id)object file:(NSString *)fileName lineNumber:(NSInteger)line description:(NSString *)format,...;
+@end
+extern NSString * const NSConnectionReplyMode;
+
+//----------------------------------------------------------------------------//
+// The following test case was filed in PR 2593:
+//   http://llvm.org/bugs/show_bug.cgi?id=2593
+//
+// There should be no null dereference flagged by the checker because of
+// NSParameterAssert and NSAssert.
+
+
+@interface TestAssert : NSObject {}
+@end
+
+@implementation TestAssert
+
+- (id)initWithPointer: (int*)x
+{
+  // Expansion of: NSParameterAssert( x != 0 );
+  do { if (!((x != 0))) { [[NSAssertionHandler currentHandler] handleFailureInMethod:_cmd object:self file:[NSString stringWithUTF8String:"CFRetainRelease_NSAssertionHandler.m"] lineNumber:21 description:(@"Invalid parameter not satisfying: %s"), ("x != 0"), (0), (0), (0), (0)]; } } while(0);
+
+  if( (self = [super init]) != 0 )
+  {
+    *x = 1; // no-warning
+  }
+
+  return self;
+}
+
+- (id)initWithPointer2: (int*)x
+{
+  // Expansion of: NSAssert( x != 0, @"" );
+  do { if (!((x != 0))) { [[NSAssertionHandler currentHandler] handleFailureInMethod:_cmd object:self file:[NSString stringWithUTF8String:"CFRetainRelease_NSAssertionHandler.m"] lineNumber:33 description:((@"")), (0), (0), (0), (0), (0)]; } } while(0);  
+
+  if( (self = [super init]) != 0 )
+  {
+    *x = 1; // no-warning
+  }
+
+  return self;
+}
+
+@end
diff --git a/test/Analysis/CGColorSpace.c b/test/Analysis/CGColorSpace.c
new file mode 100644
index 0000000..737f1a3
--- /dev/null
+++ b/test/Analysis/CGColorSpace.c
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=range -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -verify %s
+
+typedef struct CGColorSpace *CGColorSpaceRef;
+extern CGColorSpaceRef CGColorSpaceCreateDeviceRGB(void);
+extern CGColorSpaceRef CGColorSpaceRetain(CGColorSpaceRef space);
+extern void CGColorSpaceRelease(CGColorSpaceRef space);
+
+void f() {
+  CGColorSpaceRef X = CGColorSpaceCreateDeviceRGB(); // expected-warning{{leak}}
+  CGColorSpaceRetain(X);
+}
+
+void fb() {
+  CGColorSpaceRef X = CGColorSpaceCreateDeviceRGB();
+  CGColorSpaceRetain(X);
+  CGColorSpaceRelease(X);
+  CGColorSpaceRelease(X);  // no-warning
+}
diff --git a/test/Analysis/CheckNSError.m b/test/Analysis/CheckNSError.m
new file mode 100644
index 0000000..6bf299d
--- /dev/null
+++ b/test/Analysis/CheckNSError.m
@@ -0,0 +1,59 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=range -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -verify %s
+
+
+typedef signed char BOOL;
+typedef int NSInteger;
+typedef struct _NSZone NSZone;
+@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+@protocol NSObject  - (BOOL)isEqual:(id)object; @end
+@protocol NSCopying  - (id)copyWithZone:(NSZone *)zone; @end
+@protocol NSCoding  - (void)encodeWithCoder:(NSCoder *)aCoder; @end
+@interface NSObject <NSObject> {} @end
+@class NSDictionary;
+@interface NSError : NSObject <NSCopying, NSCoding> {}
++ (id)errorWithDomain:(NSString *)domain code:(NSInteger)code userInfo:(NSDictionary *)dict;
+@end
+extern NSString * const NSXMLParserErrorDomain ;
+
+@interface A
+- (void)myMethodWhichMayFail:(NSError **)error;
+- (BOOL)myMethodWhichMayFail2:(NSError **)error;
+@end
+
+@implementation A
+- (void)myMethodWhichMayFail:(NSError **)error {   // expected-warning {{Method accepting NSError** should have a non-void return value to indicate whether or not an error occurred}}
+  *error = [NSError errorWithDomain:@"domain" code:1 userInfo:0]; // expected-warning {{Potential null dereference.}}
+}
+
+- (BOOL)myMethodWhichMayFail2:(NSError **)error {  // no-warning
+  if (error) *error = [NSError errorWithDomain:@"domain" code:1 userInfo:0]; // no-warning
+  return 0;
+}
+@end
+
+struct __CFError {};
+typedef struct __CFError* CFErrorRef;
+
+void foo(CFErrorRef* error) { // expected-warning {{Function accepting CFErrorRef* should have a non-void return value to indicate whether or not an error occurred}}
+  *error = 0;  // expected-warning {{Potential null dereference.}}
+}
+
+int f1(CFErrorRef* error) {
+  if (error) *error = 0; // no-warning
+  return 0;
+}
+
+int f2(CFErrorRef* error) {
+  if (0 != error) *error = 0; // no-warning
+  return 0;
+}
+
+int f3(CFErrorRef* error) {
+  if (error != 0) *error = 0; // no-warning
+  return 0;
+}
+
+
diff --git a/test/Analysis/MissingDealloc.m b/test/Analysis/MissingDealloc.m
new file mode 100644
index 0000000..bfd968a
--- /dev/null
+++ b/test/Analysis/MissingDealloc.m
@@ -0,0 +1,117 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-missing-dealloc '-DIBOutlet=__attribute__((iboutlet))' %s -verify
+typedef signed char BOOL;
+@protocol NSObject
+- (BOOL)isEqual:(id)object;
+- (Class)class;
+@end
+
+@interface NSObject <NSObject> {}
+- (void)dealloc;
+- (id)init;
+@end
+
+typedef struct objc_selector *SEL;
+
+// <rdar://problem/6380411>: 'myproperty' has kind 'assign' and thus the
+//  assignment through the setter does not perform a release.
+
+@interface MyObject : NSObject {
+  id _myproperty;  
+}
+@property(assign) id myproperty;
+@end
+
+@implementation MyObject
+@synthesize myproperty=_myproperty; // no-warning
+- (void)dealloc {
+  self.myproperty = 0;
+  [super dealloc]; 
+}
+@end
+
+//===------------------------------------------------------------------------===
+//  Don't warn about iVars that are selectors.
+
+@interface TestSELs : NSObject {
+  SEL a;
+  SEL b;
+}
+
+@end
+
+@implementation TestSELs
+- (id)init {
+  if( (self = [super init]) ) {
+    a = @selector(a);
+    b = @selector(b);
+  }
+
+  return self;
+}
+@end
+
+//===------------------------------------------------------------------------===
+//  Don't warn about iVars that are IBOutlets.
+
+#ifndef IBOutlet
+#define IBOutlet
+#endif
+
+@class NSWindow;
+
+@interface HasOutlet : NSObject {
+IBOutlet NSWindow *window;
+}
+@end
+
+@implementation HasOutlet // no-warning
+@end
+
+//===------------------------------------------------------------------------===
+// <rdar://problem/6380411>
+// Was bogus warning: "The '_myproperty' instance variable was not retained by a
+//  synthesized property but was released in 'dealloc'"
+
+@interface MyObject_rdar6380411 : NSObject {
+    id _myproperty;
+}
+@property(assign) id myproperty;
+@end
+
+@implementation MyObject_rdar6380411
+@synthesize myproperty=_myproperty;
+- (void)dealloc {
+    // Don't claim that myproperty is released since it the property
+    // has the 'assign' attribute.
+    self.myproperty = 0; // no-warning
+    [super dealloc];
+}
+@end
+
+//===------------------------------------------------------------------------===
+// PR 3187: http://llvm.org/bugs/show_bug.cgi?id=3187
+// - Disable the missing -dealloc check for classes that subclass SenTestCase
+
+@class NSString;
+
+@interface SenTestCase : NSObject {}
+@end
+
+@interface MyClassTest : SenTestCase {
+  NSString *resourcePath;
+}
+@end
+
+@interface NSBundle : NSObject {}
++ (NSBundle *)bundleForClass:(Class)aClass;
+- (NSString *)resourcePath;
+@end
+
+@implementation MyClassTest
+- (void)setUp {
+  resourcePath = [[NSBundle bundleForClass:[self class]] resourcePath];
+}
+- (void)testXXX {
+  // do something which uses resourcepath
+}
+@end
diff --git a/test/Analysis/NSPanel.m b/test/Analysis/NSPanel.m
new file mode 100644
index 0000000..7ebe18f
--- /dev/null
+++ b/test/Analysis/NSPanel.m
@@ -0,0 +1,90 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=range -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -verify %s
+
+// BEGIN delta-debugging reduced header stuff
+
+typedef struct objc_selector *SEL;
+typedef signed char BOOL;
+typedef unsigned int NSUInteger;
+typedef struct _NSZone NSZone;
+@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+@protocol NSObject
+- (BOOL)isEqual:(id)object;
+- (oneway void)release;
+@end
+@protocol NSCopying
+- (id)copyWithZone:(NSZone *)zone;
+@end
+@protocol NSMutableCopying
+- (id)mutableCopyWithZone:(NSZone *)zone;
+@end
+@protocol NSCoding
+- (void)encodeWithCoder:(NSCoder *)aCoder;
+@end
+@interface NSObject <NSObject> {}
++ (id)alloc;
+@end
+typedef float CGFloat;
+typedef struct _NSPoint {} NSRect;
+static __inline__ __attribute__((always_inline)) NSRect NSMakeRect(CGFloat x, CGFloat y, CGFloat w, CGFloat h) { NSRect r; return r; }
+typedef struct {} NSFastEnumerationState;
+@protocol NSFastEnumeration 
+- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len;
+@end
+@class NSString;
+@interface NSArray : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration>
+- (NSUInteger)count;
+@end
+@interface NSMutableArray : NSArray
+- (void)addObject:(id)anObject;
+@end @class NSAppleEventDescriptor;
+enum { NSBackingStoreRetained = 0,     NSBackingStoreNonretained = 1,     NSBackingStoreBuffered = 2 };
+typedef NSUInteger NSBackingStoreType;
+@interface NSResponder : NSObject <NSCoding> {} @end
+@protocol NSAnimatablePropertyContainer
+- (id)animator;
+@end
+@protocol NSValidatedUserInterfaceItem
+- (SEL)action;
+@end
+@protocol NSUserInterfaceValidations
+- (BOOL)validateUserInterfaceItem:(id <NSValidatedUserInterfaceItem>)anItem;
+@end  @class NSDate, NSDictionary, NSError, NSException, NSNotification;
+enum { NSBorderlessWindowMask = 0,     NSTitledWindowMask = 1 << 0,     NSClosableWindowMask = 1 << 1,     NSMiniaturizableWindowMask = 1 << 2,     NSResizableWindowMask = 1 << 3  };
+@interface NSWindow : NSResponder  <NSAnimatablePropertyContainer, NSUserInterfaceValidations>    {}
+- (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)aStyle backing:(NSBackingStoreType)bufferingType defer:(BOOL)flag;
+@end
+extern NSString *NSWindowDidBecomeKeyNotification;
+@interface NSPanel : NSWindow {}
+@end
+@class NSTableHeaderView;
+
+// END delta-debugging reduced header stuff
+
+@interface MyClass
+{
+	NSMutableArray *panels;
+}
+- (void)myMethod;
+- (void)myMethod2;
+@end
+
+@implementation MyClass // no-warning
+- (void)myMethod
+{
+  NSPanel *panel = [[NSPanel alloc] initWithContentRect:NSMakeRect(0, 0, 200, 200) styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:(BOOL)1];
+
+  [panels addObject:panel];
+
+  [panel release]; // no-warning
+}
+- (void)myMethod2
+{
+  NSPanel *panel = [[NSPanel alloc] initWithContentRect:NSMakeRect(0, 0, 200, 200) styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:(BOOL)1]; // no-warning
+
+  [panels addObject:panel];  
+}
+@end
+
diff --git a/test/Analysis/NSString.m b/test/Analysis/NSString.m
new file mode 100644
index 0000000..fa81b3d
--- /dev/null
+++ b/test/Analysis/NSString.m
@@ -0,0 +1,406 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=basic -verify %s
+// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -verify %s
+// RUN: %clang_cc1 -DTEST_64 -triple x86_64-apple-darwin10 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=basic -verify %s
+// RUN: %clang_cc1 -DTEST_64 -triple x86_64-apple-darwin10 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -verify %s
+
+// ==-- FIXME: -analyzer-store=basic fails on this file (false negatives). --==
+// NOTWORK: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=range -verify %s &&
+// NOTWORK: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=basic -verify %s &&
+// NOTWORK: %clang_cc1 -DTEST_64 -triple x86_64-apple-darwin10 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=basic -verify %s &&
+// NOTWORK: %clang_cc1 -DTEST_64 -triple x86_64-apple-darwin10 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=range -verify %s
+
+//===----------------------------------------------------------------------===//
+// The following code is reduced using delta-debugging from
+// Foundation.h (Mac OS X).
+//
+// It includes the basic definitions for the test cases below.
+// Not directly including Foundation.h directly makes this test case 
+// both svelte and portable to non-Mac platforms.
+//===----------------------------------------------------------------------===//
+
+#ifdef TEST_64
+typedef long long int64_t;
+_Bool OSAtomicCompareAndSwap64Barrier( int64_t __oldValue, int64_t __newValue, volatile int64_t *__theValue );
+#define COMPARE_SWAP_BARRIER OSAtomicCompareAndSwap64Barrier
+typedef int64_t intptr_t;
+#else
+typedef int int32_t;
+_Bool OSAtomicCompareAndSwap32Barrier( int32_t __oldValue, int32_t __newValue, volatile int32_t *__theValue );
+#define COMPARE_SWAP_BARRIER OSAtomicCompareAndSwap32Barrier
+typedef int32_t intptr_t;
+#endif
+
+typedef const void * CFTypeRef;
+typedef const struct __CFString * CFStringRef;
+typedef const struct __CFAllocator * CFAllocatorRef;
+extern const CFAllocatorRef kCFAllocatorDefault;
+extern CFTypeRef CFRetain(CFTypeRef cf);
+void CFRelease(CFTypeRef cf);
+typedef const struct __CFDictionary * CFDictionaryRef;
+const void *CFDictionaryGetValue(CFDictionaryRef theDict, const void *key);
+extern CFStringRef CFStringCreateWithFormat(CFAllocatorRef alloc, CFDictionaryRef formatOptions, CFStringRef format, ...);
+typedef signed char BOOL;
+typedef int NSInteger;
+typedef unsigned int NSUInteger;
+@class NSString, Protocol;
+extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, 2)));
+typedef NSInteger NSComparisonResult;
+typedef struct _NSZone NSZone;
+@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+@protocol NSObject
+- (BOOL)isEqual:(id)object;
+- (oneway void)release;
+- (id)retain;
+- (id)autorelease;
+@end
+@protocol NSCopying
+- (id)copyWithZone:(NSZone *)zone;
+@end
+@protocol NSMutableCopying
+- (id)mutableCopyWithZone:(NSZone *)zone;
+@end
+@protocol NSCoding
+- (void)encodeWithCoder:(NSCoder *)aCoder;
+@end
+@interface NSObject <NSObject> {}
+- (id)init;
++ (id)alloc;
+@end
+extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone);
+typedef struct {} NSFastEnumerationState;
+@protocol NSFastEnumeration
+- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len;
+@end
+@class NSString;
+typedef struct _NSRange {} NSRange;
+@interface NSArray : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration>
+- (NSUInteger)count;
+@end
+@interface NSMutableArray : NSArray
+- (void)addObject:(id)anObject;
+- (id)initWithCapacity:(NSUInteger)numItems;
+@end
+typedef unsigned short unichar;
+@class NSData, NSArray, NSDictionary, NSCharacterSet, NSData, NSURL, NSError, NSLocale;
+typedef NSUInteger NSStringCompareOptions;
+@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding>    - (NSUInteger)length;
+- (NSComparisonResult)compare:(NSString *)string;
+- (NSComparisonResult)compare:(NSString *)string options:(NSStringCompareOptions)mask;
+- (NSComparisonResult)compare:(NSString *)string options:(NSStringCompareOptions)mask range:(NSRange)compareRange;
+- (NSComparisonResult)compare:(NSString *)string options:(NSStringCompareOptions)mask range:(NSRange)compareRange locale:(id)locale;
+- (NSComparisonResult)caseInsensitiveCompare:(NSString *)string;
+- (NSArray *)componentsSeparatedByCharactersInSet:(NSCharacterSet *)separator;
++ (id)stringWithFormat:(NSString *)format, ... __attribute__((format(__NSString__, 1, 2)));
+@end
+@interface NSSimpleCString : NSString {} @end
+@interface NSConstantString : NSSimpleCString @end
+extern void *_NSConstantStringClassReference;
+
+//===----------------------------------------------------------------------===//
+// Test cases.
+//===----------------------------------------------------------------------===//
+
+NSComparisonResult f1(NSString* s) {
+  NSString *aString = 0;
+  return [s compare:aString]; // expected-warning {{Argument to 'NSString' method 'compare:' cannot be nil.}}
+}
+
+NSComparisonResult f2(NSString* s) {
+  NSString *aString = 0;
+  return [s caseInsensitiveCompare:aString]; // expected-warning {{Argument to 'NSString' method 'caseInsensitiveCompare:' cannot be nil.}}
+}
+
+NSComparisonResult f3(NSString* s, NSStringCompareOptions op) {
+  NSString *aString = 0;
+  return [s compare:aString options:op]; // expected-warning {{Argument to 'NSString' method 'compare:options:' cannot be nil.}}
+}
+
+NSComparisonResult f4(NSString* s, NSStringCompareOptions op, NSRange R) {
+  NSString *aString = 0;
+  return [s compare:aString options:op range:R]; // expected-warning {{Argument to 'NSString' method 'compare:options:range:' cannot be nil.}}
+}
+
+NSComparisonResult f5(NSString* s, NSStringCompareOptions op, NSRange R) {
+  NSString *aString = 0;
+  return [s compare:aString options:op range:R locale:0]; // expected-warning {{Argument to 'NSString' method 'compare:options:range:locale:' cannot be nil.}}
+}
+
+NSArray *f6(NSString* s) {
+  return [s componentsSeparatedByCharactersInSet:0]; // expected-warning {{Argument to 'NSString' method 'componentsSeparatedByCharactersInSet:' cannot be nil.}}
+}
+
+NSString* f7(NSString* s1, NSString* s2, NSString* s3) {
+
+  NSString* s4 = (NSString*)
+    CFStringCreateWithFormat(kCFAllocatorDefault, 0,  // expected-warning{{leak}}
+                             (CFStringRef) __builtin___CFStringMakeConstantString("%@ %@ (%@)"), 
+                             s1, s2, s3);
+
+  CFRetain(s4);
+  return s4;
+}
+
+NSMutableArray* f8() {
+  
+  NSString* s = [[NSString alloc] init];
+  NSMutableArray* a = [[NSMutableArray alloc] initWithCapacity:2];
+  [a addObject:s];
+  [s release]; // no-warning
+  return a;
+}
+
+void f9() {
+  
+  NSString* s = [[NSString alloc] init];
+  NSString* q = s;
+  [s release];
+  [q release]; // expected-warning {{used after it is released}}
+}
+
+NSString* f10() {
+  static NSString* s = 0;
+  if (!s) s = [[NSString alloc] init];
+  return s; // no-warning
+}
+
+// Test case for regression reported in <rdar://problem/6452745>.
+// Essentially 's' should not be considered allocated on the false branch.
+// This exercises the 'EvalAssume' logic in GRTransferFuncs (CFRefCount.cpp).
+NSString* f11(CFDictionaryRef dict, const char* key) {
+  NSString* s = (NSString*) CFDictionaryGetValue(dict, key);
+  [s retain];
+  if (s) {
+    [s release];
+  }
+  return 0;
+}
+
+// Test case for passing a tracked object by-reference to a function we
+// don't understand.
+void unknown_function_f12(NSString** s);
+void f12() {
+  NSString *string = [[NSString alloc] init];
+  unknown_function_f12(&string); // no-warning
+}
+
+// Test double release of CFString (PR 4014).
+void f13(void) {
+  CFStringRef ref = CFStringCreateWithFormat(kCFAllocatorDefault, ((void*)0), ((CFStringRef) __builtin___CFStringMakeConstantString ("" "%d" "")), 100);
+  CFRelease(ref);
+  CFRelease(ref); // expected-warning{{Reference-counted object is used after it is released}}
+}
+
+// Test regular use of -autorelease
+@interface TestAutorelease
+-(NSString*) getString;
+@end
+@implementation TestAutorelease
+-(NSString*) getString {
+  NSString *str = [[NSString alloc] init];
+  return [str autorelease]; // no-warning
+}
+- (void)m1
+{
+ NSString *s = [[NSString alloc] init]; // expected-warning{{leak}}
+ [s retain];
+ [s autorelease];
+}
+- (void)m2
+{
+ NSString *s = [[[NSString alloc] init] autorelease]; // expected-warning{{leak}}
+ [s retain];
+}
+- (void)m3
+{
+ NSString *s = [[[NSString alloc] init] autorelease];
+ [s retain];
+ [s autorelease];
+}
+- (void)m4
+{
+ NSString *s = [[NSString alloc] init]; // expected-warning{{leak}}
+ [s retain];
+}
+- (void)m5
+{
+ NSString *s = [[NSString alloc] init];
+ [s autorelease];
+}
+@end
+
+@interface C1 : NSObject {}
+- (NSString*) getShared;
++ (C1*) sharedInstance;
+@end
+@implementation C1 : NSObject {}
+- (NSString*) getShared {
+  static NSString* s = 0;
+  if (!s) s = [[NSString alloc] init];    
+  return s; // no-warning  
+}
++ (C1 *)sharedInstance {
+  static C1 *sharedInstance = 0;
+  if (!sharedInstance) {
+    sharedInstance = [[C1 alloc] init];
+  }
+  return sharedInstance; // no-warning
+}
+@end
+
+@interface SharedClass : NSObject
++ (id)sharedInstance;
+- (id)notShared;
+@end
+
+@implementation SharedClass
+
+- (id)_init {
+    if ((self = [super init])) {
+        NSLog(@"Bar");
+    }
+    return self;
+}
+
+- (id)notShared {
+  return [[SharedClass alloc] _init]; // expected-warning{{leak}}
+}
+
++ (id)sharedInstance {
+    static SharedClass *_sharedInstance = 0;
+    if (!_sharedInstance) {
+        _sharedInstance = [[SharedClass alloc] _init];
+    }
+    return _sharedInstance; // no-warning
+}
+@end
+
+id testSharedClassFromFunction() {
+  return [[SharedClass alloc] _init]; // no-warning
+}
+
+// Test OSCompareAndSwap
+_Bool OSAtomicCompareAndSwapPtr( void *__oldValue, void *__newValue, void * volatile *__theValue );
+extern BOOL objc_atomicCompareAndSwapPtr(id predicate, id replacement, volatile id *objectLocation);
+
+void testOSCompareAndSwap() {
+  NSString *old = 0;
+  NSString *s = [[NSString alloc] init]; // no-warning
+  if (!OSAtomicCompareAndSwapPtr(0, s, (void**) &old))
+    [s release];
+  else    
+    [old release];
+}
+
+void testOSCompareAndSwapXXBarrier_local() {
+  NSString *old = 0;
+  NSString *s = [[NSString alloc] init]; // no-warning
+  if (!COMPARE_SWAP_BARRIER((intptr_t) 0, (intptr_t) s, (intptr_t*) &old))
+    [s release];
+  else    
+    [old release];
+}
+
+void testOSCompareAndSwapXXBarrier_local_no_direct_release() {
+  NSString *old = 0;
+  NSString *s = [[NSString alloc] init]; // no-warning
+  if (!COMPARE_SWAP_BARRIER((intptr_t) 0, (intptr_t) s, (intptr_t*) &old))
+    return;
+  else    
+    [old release];
+}
+
+int testOSCompareAndSwapXXBarrier_id(Class myclass, id xclass) {
+  if (COMPARE_SWAP_BARRIER(0, (intptr_t) myclass, (intptr_t*) &xclass))
+    return 1;
+  return 0;
+}
+
+void test_objc_atomicCompareAndSwap_local() {
+  NSString *old = 0;
+  NSString *s = [[NSString alloc] init]; // no-warning
+  if (!objc_atomicCompareAndSwapPtr(0, s, &old))
+    [s release];
+  else    
+    [old release];
+}
+
+void test_objc_atomicCompareAndSwap_local_no_direct_release() {
+  NSString *old = 0;
+  NSString *s = [[NSString alloc] init]; // no-warning
+  if (!objc_atomicCompareAndSwapPtr(0, s, &old))
+    return;
+  else    
+    [old release];
+}
+
+void test_objc_atomicCompareAndSwap_parameter(NSString **old) {
+  NSString *s = [[NSString alloc] init]; // no-warning
+  if (!objc_atomicCompareAndSwapPtr(0, s, old))
+    [s release];
+  else    
+    [*old release];
+}
+
+void test_objc_atomicCompareAndSwap_parameter_no_direct_release(NSString **old) {
+  NSString *s = [[NSString alloc] init]; // expected-warning{{leak}}
+  if (!objc_atomicCompareAndSwapPtr(0, s, old))
+    return;
+  else    
+    [*old release];
+}
+
+
+// Test stringWithFormat (<rdar://problem/6815234>)
+void test_stringWithFormat() {  
+  NSString *string = [[NSString stringWithFormat:@"%ld", (long) 100] retain];
+  [string release];
+  [string release]; // expected-warning{{Incorrect decrement of the reference count}}
+}
+
+// Test isTrackedObjectType().
+typedef NSString* WonkyTypedef;
+@interface TestIsTracked
++ (WonkyTypedef)newString;
+@end
+
+void test_isTrackedObjectType(void) {
+  NSString *str = [TestIsTracked newString]; // expected-warning{{Potential leak}}
+}
+
+// Test isTrackedCFObjectType().
+@interface TestIsCFTracked
++ (CFStringRef) badNewCFString;
++ (CFStringRef) newCFString;
+@end
+
+@implementation TestIsCFTracked
++ (CFStringRef) newCFString {
+  return CFStringCreateWithFormat(kCFAllocatorDefault, ((void*)0), ((CFStringRef) __builtin___CFStringMakeConstantString ("" "%d" "")), 100); // no-warning
+}
++ (CFStringRef) badNewCFString {
+  return CFStringCreateWithFormat(kCFAllocatorDefault, ((void*)0), ((CFStringRef) __builtin___CFStringMakeConstantString ("" "%d" "")), 100); // expected-warning{{leak}}
+}
+
+// Test @synchronized
+void test_synchronized(id x) {
+  @synchronized(x) {
+    NSString *string = [[NSString stringWithFormat:@"%ld", (long) 100] retain]; // expected-warning {{leak}}
+  }
+}
+@end
+
+void testOSCompareAndSwapXXBarrier_parameter(NSString **old) {
+  NSString *s = [[NSString alloc] init]; // no-warning
+  if (!COMPARE_SWAP_BARRIER((intptr_t) 0, (intptr_t) s, (intptr_t*) old))
+    [s release];
+  else    
+    [*old release];
+}
+
+void testOSCompareAndSwapXXBarrier_parameter_no_direct_release(NSString **old) {
+  NSString *s = [[NSString alloc] init]; // no-warning
+  if (!COMPARE_SWAP_BARRIER((intptr_t) 0, (intptr_t) s, (intptr_t*) old))
+    [s release];
+  else    
+    return;
+}
diff --git a/test/Analysis/NSWindow.m b/test/Analysis/NSWindow.m
new file mode 100644
index 0000000..34e6c68
--- /dev/null
+++ b/test/Analysis/NSWindow.m
@@ -0,0 +1,89 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-check-dead-stores -analyzer-store=basic -analyzer-constraints=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-check-dead-stores -analyzer-store=basic -analyzer-constraints=range -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-check-dead-stores -analyzer-store=region -analyzer-constraints=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-check-dead-stores -analyzer-store=region -analyzer-constraints=range -verify %s
+
+// These declarations were reduced using Delta-Debugging from Foundation.h
+// on Mac OS X.  The test cases are below.
+
+typedef struct objc_selector *SEL;
+typedef signed char BOOL;
+typedef unsigned int NSUInteger;
+@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+@protocol NSObject
+- (BOOL)isEqual:(id)object;
+- (id)retain;
+@end
+@protocol NSCoding  - (void)encodeWithCoder:(NSCoder *)aCoder;
+@end
+@interface NSObject <NSObject> {}
+  + (id)alloc;
+@end
+typedef float CGFloat;
+typedef struct _NSPoint {} NSRect;
+NSRect NSMakeRect(CGFloat x, CGFloat y, CGFloat w, CGFloat h);
+enum { NSBackingStoreRetained = 0,     NSBackingStoreNonretained = 1,     NSBackingStoreBuffered = 2 };
+typedef NSUInteger NSBackingStoreType;
+@interface NSResponder : NSObject <NSCoding> {}
+@end
+@protocol NSAnimatablePropertyContainer
+- (id)animator;
+@end
+extern NSString *NSAnimationTriggerOrderIn ;
+@class CIFilter, CALayer, NSDictionary, NSScreen, NSShadow, NSTrackingArea;
+@interface NSView : NSResponder  <NSAnimatablePropertyContainer>  {} @end
+@protocol NSValidatedUserInterfaceItem - (SEL)action; @end
+@protocol NSUserInterfaceValidations - (BOOL)validateUserInterfaceItem:(id <NSValidatedUserInterfaceItem>)anItem; @end   @class NSNotification, NSText, NSView, NSMutableSet, NSSet, NSDate;
+enum { NSBorderlessWindowMask = 0,     NSTitledWindowMask = 1 << 0,     NSClosableWindowMask = 1 << 1,     NSMiniaturizableWindowMask = 1 << 2,     NSResizableWindowMask = 1 << 3  };
+@interface NSWindow : NSResponder  <NSAnimatablePropertyContainer, NSUserInterfaceValidations>    {
+  struct __wFlags {} _wFlags;
+}
+- (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)aStyle backing:(NSBackingStoreType)bufferingType defer:(BOOL)flag;
+- (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)aStyle backing:(NSBackingStoreType)bufferingType defer:(BOOL)flag screen:(NSScreen *)screen;
+- (void)orderFrontRegardless;
+@end
+
+extern NSString *NSWindowDidBecomeKeyNotification;
+
+// Test cases.
+
+void f1() {
+  NSWindow *window = [[NSWindow alloc]
+                      initWithContentRect:NSMakeRect(0,0,100,100) 
+                        styleMask:NSTitledWindowMask|NSClosableWindowMask
+                        backing:NSBackingStoreBuffered
+                        defer:0]; 
+
+  [window orderFrontRegardless]; // no-warning
+}
+
+void f2() {
+  NSWindow *window = [[NSWindow alloc]
+                      initWithContentRect:NSMakeRect(0,0,100,100) 
+                        styleMask:NSTitledWindowMask|NSClosableWindowMask
+                        backing:NSBackingStoreBuffered
+                        defer:0
+                        screen:0]; 
+
+  [window orderFrontRegardless]; // no-warning
+}
+
+void f2b() {
+  // FIXME: NSWindow doesn't own itself until it is displayed.
+  NSWindow *window = [[NSWindow alloc] // no-warning
+                      initWithContentRect:NSMakeRect(0,0,100,100) 
+                        styleMask:NSTitledWindowMask|NSClosableWindowMask
+                        backing:NSBackingStoreBuffered
+                        defer:0
+                        screen:0]; 
+
+  [window orderFrontRegardless];
+  
+  [window retain];
+}
+
+
+void f3() {
+  // FIXME: For now we don't track NSWindow.
+  NSWindow *window = [NSWindow alloc];  // expected-warning{{never read}}
+}
diff --git a/test/Analysis/NoReturn.m b/test/Analysis/NoReturn.m
new file mode 100644
index 0000000..a02c93c
--- /dev/null
+++ b/test/Analysis/NoReturn.m
@@ -0,0 +1,80 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=range -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -verify %s
+
+#include <stdarg.h>
+
+//===----------------------------------------------------------------------===//
+// The following code is reduced using delta-debugging from
+// Foundation.h (Mac OS X).
+//
+// It includes the basic definitions for the test cases below.
+// Not directly including Foundation.h directly makes this test case 
+// both svelte and portable to non-Mac platforms.
+//===----------------------------------------------------------------------===//
+
+typedef signed char BOOL;
+typedef unsigned int NSUInteger;
+typedef struct _NSZone NSZone;
+@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+@protocol NSObject  - (BOOL)isEqual:(id)object;
+@end  @protocol NSCopying  - (id)copyWithZone:(NSZone *)zone;
+@end  @protocol NSMutableCopying  - (id)mutableCopyWithZone:(NSZone *)zone; @end
+@protocol NSCoding  - (void)encodeWithCoder:(NSCoder *)aCoder; @end
+@interface NSObject <NSObject> {} @end
+extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone);
+@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding>
+- (NSUInteger)length;
++ (id)stringWithFormat:(NSString *)format, ...;
+@end
+@interface NSSimpleCString : NSString {} @end
+@interface NSConstantString : NSSimpleCString @end
+extern void *_NSConstantStringClassReference;
+typedef double NSTimeInterval;
+@interface NSDate : NSObject <NSCopying, NSCoding>  - (NSTimeInterval)timeIntervalSinceReferenceDate; @end
+@class NSString, NSDictionary, NSArray;
+@interface NSException : NSObject <NSCopying, NSCoding> {}
++ (NSException *)exceptionWithName:(NSString *)name reason:(NSString *)reason userInfo:(NSDictionary *)userInfo;
+- (void)raise;
+@end
+@interface NSException (NSExceptionRaisingConveniences)
++ (void)raise:(NSString *)name format:(NSString *)format, ...;
++ (void)raise:(NSString *)name format:(NSString *)format arguments:(va_list)argList;
+@end
+
+enum {NSPointerFunctionsStrongMemory = (0 << 0),     NSPointerFunctionsZeroingWeakMemory = (1 << 0),     NSPointerFunctionsOpaqueMemory = (2 << 0),     NSPointerFunctionsMallocMemory = (3 << 0),     NSPointerFunctionsMachVirtualMemory = (4 << 0),        NSPointerFunctionsObjectPersonality = (0 << 8),     NSPointerFunctionsOpaquePersonality = (1 << 8),     NSPointerFunctionsObjectPointerPersonality = (2 << 8),     NSPointerFunctionsCStringPersonality = (3 << 8),     NSPointerFunctionsStructPersonality = (4 << 8),     NSPointerFunctionsIntegerPersonality = (5 << 8),      NSPointerFunctionsCopyIn = (1 << 16), };
+
+//===----------------------------------------------------------------------===//
+// Test cases.
+//===----------------------------------------------------------------------===//
+
+int f1(int *x, NSString* s) {
+  
+  if (x) ++x;
+  
+  [NSException raise:@"Blah" format:[NSString stringWithFormat:@"Blah %@", s]];
+  
+  return *x; // no-warning
+}
+
+int f2(int *x, ...) {
+  
+  if (x) ++x;
+  va_list alist;
+  va_start(alist, x);
+  
+  [NSException raise:@"Blah" format:@"Blah %@" arguments:alist];
+  
+  return *x; // no-warning
+}
+
+int f3(int* x) {
+  
+  if (x) ++x;
+  
+  [[NSException exceptionWithName:@"My Exception" reason:@"Want to test exceptions." userInfo:0] raise];
+
+  return *x; // no-warning
+}
+
diff --git a/test/Analysis/ObjCProperties.m b/test/Analysis/ObjCProperties.m
new file mode 100644
index 0000000..72f3d38
--- /dev/null
+++ b/test/Analysis/ObjCProperties.m
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=basic %s -verify
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=range %s -verify
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=basic %s -verify
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range %s -verify
+
+// The point of this test cases is to exercise properties in the static
+// analyzer
+
+@interface MyClass {
+@private
+    id _X;
+}
+- (id)initWithY:(id)Y;
+@property(copy, readwrite) id X;
+@end
+
+@implementation MyClass
+@synthesize X = _X;
+- (id)initWithY:(id)Y {
+  self.X = Y;
+  return self;
+}
+@end
diff --git a/test/Analysis/ObjCRetSigs.m b/test/Analysis/ObjCRetSigs.m
new file mode 100644
index 0000000..a76d7b9
--- /dev/null
+++ b/test/Analysis/ObjCRetSigs.m
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-methodsigs -verify %s
+
+int printf(const char *, ...);
+
+@interface MyBase
+-(long long)length;
+@end
+
+@interface MySub : MyBase{}
+-(double)length;
+@end
+
+@implementation MyBase
+-(long long)length{
+   printf("Called MyBase -length;\n");
+   return 3;
+}
+@end
+
+@implementation MySub
+-(double)length{  // expected-warning{{types are incompatible}}
+   printf("Called MySub -length;\n");
+   return 3.3;
+}
+@end
diff --git a/test/Analysis/PR2599.m b/test/Analysis/PR2599.m
new file mode 100644
index 0000000..68c8c06
--- /dev/null
+++ b/test/Analysis/PR2599.m
@@ -0,0 +1,66 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-constraints=basic -analyzer-store=basic -analyzer-check-objc-mem -fobjc-gc -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-constraints=range -analyzer-store=basic -analyzer-check-objc-mem -fobjc-gc -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-constraints=basic -analyzer-store=basic -analyzer-check-objc-mem -fobjc-gc -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-constraints=range -analyzer-store=region -analyzer-check-objc-mem -fobjc-gc -verify %s
+
+typedef const void * CFTypeRef;
+typedef const struct __CFString * CFStringRef;
+typedef const struct __CFAllocator * CFAllocatorRef;
+typedef const struct __CFDictionary * CFDictionaryRef;
+CFTypeRef CFMakeCollectable(CFTypeRef cf) ;
+extern CFStringRef CFStringCreateWithFormat(CFAllocatorRef alloc, CFDictionaryRef formatOptions, CFStringRef format, ...);
+typedef signed char BOOL;
+typedef unsigned int NSUInteger;
+typedef struct _NSZone NSZone;
+@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+@protocol NSObject
+- (BOOL)isEqual:(id)object;
+- (id)autorelease;
+@end
+@protocol NSCopying
+- (id)copyWithZone:(NSZone *)zone;
+@end  @protocol NSMutableCopying
+- (id)mutableCopyWithZone:(NSZone *)zone;
+@end
+@protocol
+NSCoding
+- (void)encodeWithCoder:(NSCoder *)aCoder;
+@end
+@interface NSObject <NSObject> {}
+- (id)init;
++ (id)alloc;
+@end
+enum { NSASCIIStringEncoding = 1,     NSNEXTSTEPStringEncoding = 2,     NSJapaneseEUCStringEncoding = 3,     NSUTF8StringEncoding = 4,     NSISOLatin1StringEncoding = 5,     NSSymbolStringEncoding = 6,     NSNonLossyASCIIStringEncoding = 7,     NSShiftJISStringEncoding = 8,     NSISOLatin2StringEncoding = 9,     NSUnicodeStringEncoding = 10,     NSWindowsCP1251StringEncoding = 11,     NSWindowsCP1252StringEncoding = 12,     NSWindowsCP1253StringEncoding = 13,     NSWindowsCP1254StringEncoding = 14,     NSWindowsCP1250StringEncoding = 15,     NSISO2022JPStringEncoding = 21,     NSMacOSRomanStringEncoding = 30,      NSUTF16StringEncoding = NSUnicodeStringEncoding,       NSUTF16BigEndianStringEncoding = 0x90000100,     NSUTF16LittleEndianStringEncoding = 0x94000100,      NSUTF32StringEncoding = 0x8c000100,     NSUTF32BigEndianStringEncoding = 0x98000100,     NSUTF32LittleEndianStringEncoding = 0x9c000100  };
+typedef NSUInteger NSStringEncoding;
+@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding>
+- (NSUInteger)length;
+- (id)initWithBytesNoCopy:(void *)bytes length:(NSUInteger)len encoding:(NSStringEncoding)encoding freeWhenDone:(BOOL)freeBuffer;
+@end
+@interface NSAutoreleasePool : NSObject {}
+- (void)drain;
+@end
+extern NSString * const NSXMLParserErrorDomain ;
+
+// The actual test case.  UTIL_AUTORELEASE_CF_AS_ID is a macro that doesn't
+// actually do what it was intended to.
+
+#define NSSTRINGWRAPPER(bytes,len) \
+  [[[NSString alloc] initWithBytesNoCopy: (void*)(bytes) length: (len) encoding: NSUTF8StringEncoding freeWhenDone: (BOOL)0] autorelease]
+
+#define UTIL_AUTORELEASE_CF_AS_ID(cf) ( (((void*)0) == (cf)) ? ((void*)0) : [(id) CFMakeCollectable( (CFTypeRef) cf) autorelease] )
+
+#define UTIL_AUTORELEASE_CF_AS_ID_WITHOUT_TEST(cf) ( [(id) CFMakeCollectable( (CFTypeRef) cf) autorelease] )
+
+static char *lorem = "fooBarBaz";
+
+void NSLog(NSString *, ...);
+
+int main (int argc, const char * argv[]) {
+  NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+  NSString *tmp1 = NSSTRINGWRAPPER(lorem, 6); // no-warning
+  NSString *tmp2 = UTIL_AUTORELEASE_CF_AS_ID( CFStringCreateWithFormat(((void*)0), ((void*)0), ((CFStringRef) __builtin___CFStringMakeConstantString ("" "lorem: %@" "")), tmp1) );  // expected-warning 2 {{leak}}
+  NSString *tmp3 = UTIL_AUTORELEASE_CF_AS_ID_WITHOUT_TEST( CFStringCreateWithFormat(((void*)0), ((void*)0), ((CFStringRef) __builtin___CFStringMakeConstantString ("" "lorem: %@" "")), tmp1) );
+  NSLog(@"tmp2: %@ tmp3: %@", tmp2, tmp3);
+  [pool drain];
+  return 0;
+}
diff --git a/test/Analysis/PR2978.m b/test/Analysis/PR2978.m
new file mode 100644
index 0000000..1ed138e
--- /dev/null
+++ b/test/Analysis/PR2978.m
@@ -0,0 +1,62 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-missing-dealloc %s -verify
+
+// Tests for the checker which checks missing/extra ivar 'release' calls 
+// in dealloc.
+
+@interface NSObject
+- (void)release;
+- dealloc;
+@end
+
+@interface MyClass : NSObject {
+@private
+  id _X;
+  id _Y;
+  id _Z;
+  id _K;
+  id _N;
+  id _M;
+  id _V;
+  id _W;
+}
+@property(retain) id X;
+@property(retain) id Y;
+@property(assign) id Z;
+@property(assign) id K;
+@property(readonly) id N;
+@property(retain) id M;
+@property(retain) id V;
+@property(retain) id W;
+-(id) O;
+-(void) setO: (id) arg;
+@end
+
+@implementation MyClass
+@synthesize X = _X;
+@synthesize Y = _Y; // expected-warning{{The '_Y' instance variable was retained by a synthesized property but wasn't released in 'dealloc'}}
+@synthesize Z = _Z; // expected-warning{{The '_Z' instance variable was not retained by a synthesized property but was released in 'dealloc'}}
+@synthesize K = _K;
+@synthesize N = _N;
+@synthesize M = _M;
+@synthesize V = _V;
+@synthesize W = _W; // expected-warning{{The '_W' instance variable was retained by a synthesized property but wasn't released in 'dealloc'}}
+
+-(id) O{ return 0; }
+-(void) setO:(id)arg { }
+
+- (id)dealloc
+{
+  [_X release];
+  [_Z release];
+  [_N release];
+  
+  self.M = 0; // This will release '_M'
+  [self setV:0]; // This will release '_V'
+  [self setW:@"newW"]; // This will release '_W', but retain the new value
+  self.O = 0; // no-warning  
+  [super dealloc];
+  return 0;
+}
+
+@end
+
diff --git a/test/Analysis/PR3991.m b/test/Analysis/PR3991.m
new file mode 100644
index 0000000..c1f238c
--- /dev/null
+++ b/test/Analysis/PR3991.m
@@ -0,0 +1,71 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=basic -verify -triple x86_64-apple-darwin9 %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=range -verify -triple x86_64-apple-darwin9 %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=basic -verify -triple x86_64-apple-darwin9 %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -verify -triple x86_64-apple-darwin9 %s
+
+//===----------------------------------------------------------------------===//
+// Delta-debugging produced forward declarations.
+//===----------------------------------------------------------------------===//
+
+typedef signed char BOOL;
+typedef struct _NSZone NSZone;
+@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+@protocol NSObject  - (BOOL)isEqual:(id)object;
+@end  @protocol NSCopying  - (id)copyWithZone:(NSZone *)zone;
+@end  @protocol NSMutableCopying  - (id)mutableCopyWithZone:(NSZone *)zone;
+@end  @protocol NSCoding  - (void)encodeWithCoder:(NSCoder *)aCoder;
+@end    @interface NSObject <NSObject> {
+}
+@end    extern id <NSObject> NSAllocateObject(Class aClass, unsigned extraBytes, NSZone *zone);
+@interface NSArray : NSObject <NSCopying, NSMutableCopying, NSCoding>  - (unsigned)count;
+@end   @class NSTimer, NSPort, NSArray;
+@class NSURLHandle, NSMutableArray, NSMutableData, NSData, NSURL;
+@interface NSResponder : NSObject <NSCoding> {
+}
+@end      @class NSBitmapImageRep, NSCursor, NSGraphicsContext, NSImage, NSPasteboard, NSScrollView, NSWindow, NSAttributedString;
+@interface NSView : NSResponder {
+  struct __VFlags2 {
+  }
+  _vFlags2;
+}
+@end @class NSTextField, NSPanel, NSArray, NSWindow, NSImage, NSButton, NSError;
+@interface NSBox : NSView {
+}
+@end @class GDataFeedDocList, GDataServiceTicket, GDataServiceTicket, IHGoogleDocsAdapter;
+@protocol IHGoogleDocsAdapterDelegate  - (void)googleDocsAdapter:(IHGoogleDocsAdapter*)inGoogleDocsAdapter accountVerifyIsValid:(BOOL)inIsValid error:(NSError *)inError;
+@end   @interface IHGoogleDocsAdapter : NSObject {
+}
+- (NSArray *)entries; // expected-note {{method definition for 'entries' not found}}
+@end extern Class const kGDataUseRegisteredClass ;
+@interface IHGoogleDocsAdapter ()  - (GDataFeedDocList *)feedDocList; // expected-note {{method definition for 'feedDocList' not found}}
+- (NSArray *)directoryPathComponents; // expected-note {{method definition for 'directoryPathComponents' not found}}
+- (unsigned int)currentPathComponentIndex; // expected-note {{method definition for 'currentPathComponentIndex' not found}}
+- (void)setCurrentPathComponentIndex:(unsigned int)aCurrentPathComponentIndex; // expected-note {{method definition for 'setCurrentPathComponentIndex:' not found}}
+- (NSURL *)folderFeedURL; // expected-note {{method definition for 'folderFeedURL' not found}}
+@end  
+
+@implementation IHGoogleDocsAdapter    - (id)initWithUsername:(NSString *)inUsername password:(NSString *)inPassword owner:(NSObject <IHGoogleDocsAdapterDelegate> *)owner {	// expected-warning {{incomplete implementation}}
+  return 0;
+}
+
+//===----------------------------------------------------------------------===//
+// Actual test case:
+//
+// The analyzer currently doesn't reason about ObjCKVCRefExpr.  Have both
+// GRExprEngine::Visit and GRExprEngine::VisitLValue have such expressions
+// evaluate to UnknownVal.
+//===----------------------------------------------------------------------===//
+
+- (void)docListListFetchTicket:(GDataServiceTicket *)ticket               finishedWithFeed:(GDataFeedDocList *)feed {
+  BOOL doGetDir = self.directoryPathComponents != 0 && self.currentPathComponentIndex < [self.directoryPathComponents count];
+  if (doGetDir)  {
+    BOOL isDirExisting = [[self.feedDocList entries] count] > 0;
+    if (isDirExisting)   {
+      if (self.folderFeedURL != 0)    {
+        if (++self.currentPathComponentIndex == [self.directoryPathComponents count])     {
+        }
+      }
+    }
+  }
+}
+@end
diff --git a/test/Analysis/array-struct.c b/test/Analysis/array-struct.c
new file mode 100644
index 0000000..3e46a0a
--- /dev/null
+++ b/test/Analysis/array-struct.c
@@ -0,0 +1,180 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=range -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -verify %s
+
+struct s {
+  int data;
+  int data_array[10];
+};
+
+typedef struct {
+  int data;
+} STYPE;
+
+void g(char *p);
+void g1(struct s* p);
+
+// Array to pointer conversion. Array in the struct field.
+void f(void) {
+  int a[10];
+  int (*p)[10];
+  p = &a;
+  (*p)[3] = 1;
+  
+  struct s d;
+  struct s *q;
+  q = &d;
+  q->data = 3;
+  d.data_array[9] = 17;
+}
+
+// StringLiteral in lvalue context and pointer to array type.
+// p: ElementRegion, q: StringRegion
+void f2() {
+  char *p = "/usr/local";
+  char (*q)[4];
+  q = &"abc";
+}
+
+// Typedef'ed struct definition.
+void f3() {
+  STYPE s;
+}
+
+// Initialize array with InitExprList.
+void f4() {
+  int a[] = { 1, 2, 3};
+  int b[3] = { 1, 2 };
+  struct s c[] = {{1,{1}}};
+}
+
+// Struct variable in lvalue context.
+// Assign UnknownVal to the whole struct.
+void f5() {
+  struct s data;
+  g1(&data);
+}
+
+// AllocaRegion test.
+void f6() {
+  char *p;
+  p = __builtin_alloca(10); 
+  g(p);
+  char c = *p;
+  p[1] = 'a';
+  // Test if RegionStore::EvalBinOp converts the alloca region to element
+  // region.
+  p += 2;
+}
+
+struct s2;
+
+void g2(struct s2 *p);
+
+// Incomplete struct pointer used as function argument.
+void f7() {
+  struct s2 *p = __builtin_alloca(10);
+  g2(p);
+}
+
+// sizeof() is unsigned while -1 is signed in array index.
+void f8() {
+  int a[10];
+  a[sizeof(a)/sizeof(int) - 1] = 1; // no-warning
+}
+
+// Initialization of struct array elements.
+void f9() {
+  struct s a[10];
+}
+
+// Initializing array with string literal.
+void f10() {
+  char a1[4] = "abc";
+  char a3[6] = "abc";
+}
+
+// Retrieve the default value of element/field region.
+void f11() {
+  struct s a;
+  g1(&a);
+  if (a.data == 0) // no-warning
+    a.data = 1;
+}
+
+// Convert unsigned offset to signed when creating ElementRegion from 
+// SymbolicRegion.
+void f12(int *list) {
+  unsigned i = 0;
+  list[i] = 1;
+}
+
+struct s1 {
+  struct s2 {
+    int d;
+  } e;
+};
+
+// The binding of a.e.d should not be removed. Test recursive subregion map
+// building: a->e, e->d. Only then 'a' could be added to live region roots.
+void f13(double timeout) {
+  struct s1 a;
+  a.e.d = (int) timeout;
+  if (a.e.d == 10)
+    a.e.d = 4;
+}
+
+struct s3 {
+  int a[2];
+};
+
+static struct s3 opt;
+
+// Test if the embedded array is retrieved correctly.
+void f14() {
+  struct s3 my_opt = opt;
+}
+
+void bar(int*);
+
+// Test if the array is correctly invalidated.
+void f15() {
+  int a[10];
+  bar(a);
+  if (a[1]) // no-warning
+    (void)1;
+}
+
+struct s3 p[1];
+
+// Code from postgresql.
+// Current cast logic of region store mistakenly leaves the final result region
+// an ElementRegion of type 'char'. Then load a nonloc::SymbolVal from it and
+// assigns to 'a'. 
+void f16(struct s3 *p) {
+  struct s3 a = *((struct s3*) ((char*) &p[0])); // expected-warning{{Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption.}}
+}
+
+void inv(struct s1 *);
+
+// Invalidate the struct field.
+void f17() {
+  struct s1 t;
+  int x;
+  inv(&t);
+  if (t.e.d)
+    x = 1;
+}
+
+void read(char*);
+
+void f18() {
+  char *q;
+  char *p = (char *) __builtin_alloca(10);
+  read(p);
+  q = p;
+  q++;
+  if (*q) { // no-warning
+  }
+}
diff --git a/test/Analysis/blocks.m b/test/Analysis/blocks.m
new file mode 100644
index 0000000..b05b198
--- /dev/null
+++ b/test/Analysis/blocks.m
@@ -0,0 +1,90 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-check-objc-mem -analyzer-store=region -fblocks -verify %s
+
+//===----------------------------------------------------------------------===//
+// The following code is reduced using delta-debugging from Mac OS X headers:
+//===----------------------------------------------------------------------===//
+
+typedef __builtin_va_list va_list;
+typedef unsigned int uint32_t;
+typedef struct dispatch_queue_s *dispatch_queue_t;
+typedef struct dispatch_queue_attr_s *dispatch_queue_attr_t;
+typedef void (^dispatch_block_t)(void);
+void dispatch_async(dispatch_queue_t queue, dispatch_block_t block);
+__attribute__((visibility("default"))) __attribute__((__malloc__)) __attribute__((__warn_unused_result__)) __attribute__((__nothrow__)) dispatch_queue_t dispatch_queue_create(const char *label, dispatch_queue_attr_t attr);
+typedef long dispatch_once_t;
+void dispatch_once(dispatch_once_t *predicate, dispatch_block_t block);
+typedef signed char BOOL;
+typedef unsigned long NSUInteger;
+typedef struct _NSZone NSZone;
+@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+@protocol NSObject
+- (BOOL)isEqual:(id)object;
+- (oneway void)release;
+@end
+@protocol NSCopying  - (id)copyWithZone:(NSZone *)zone; @end
+@protocol NSMutableCopying  - (id)mutableCopyWithZone:(NSZone *)zone; @end
+@protocol NSCoding  - (void)encodeWithCoder:(NSCoder *)aCoder; @end
+@interface NSObject <NSObject> {}
++ (id)alloc;
+@end
+extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone);
+@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding>    - (NSUInteger)length;
+- ( const char *)UTF8String;
+- (id)initWithFormat:(NSString *)format arguments:(va_list)argList __attribute__((format(__NSString__, 1, 0)));
+@end
+@class NSString, NSData;
+typedef struct cssm_sample {} CSSM_SAMPLEGROUP, *CSSM_SAMPLEGROUP_PTR;
+typedef struct __aslclient *aslclient;
+typedef struct __aslmsg *aslmsg;
+aslclient asl_open(const char *ident, const char *facility, uint32_t opts);
+int asl_log(aslclient asl, aslmsg msg, int level, const char *format, ...) __attribute__((__format__ (__printf__, 4, 5)));
+
+//===----------------------------------------------------------------------===//
+// Begin actual test cases.
+//===----------------------------------------------------------------------===//
+
+// test1 - This test case exposed logic that caused the analyzer to crash because of a memory bug
+//  in BlockDataRegion.  It represents real code that contains two block literals.  Eventually
+//  via IPA 'logQueue' and 'client' should be updated after the call to 'dispatch_once'.
+void test1(NSString *format, ...) {
+  static dispatch_queue_t logQueue;
+  static aslclient client;
+  static dispatch_once_t pred;
+  do {
+    if (__builtin_expect(*(&pred), ~0l) != ~0l)
+      dispatch_once(&pred, ^{
+        logQueue = dispatch_queue_create("com.mycompany.myproduct.asl", ((void*)0));
+        client = asl_open(((void*)0), "com.mycompany.myproduct", 0);
+      });
+  } while (0);
+
+  va_list args;
+  __builtin_va_start(args, format);
+
+  NSString *str = [[NSString alloc] initWithFormat:format arguments:args];
+  dispatch_async(logQueue, ^{ asl_log(client, ((void*)0), 4, "%s", [str UTF8String]); });
+  [str release];
+
+  __builtin_va_end(args);
+}
+
+// test2 - Test that captured variables that are uninitialized are flagged
+// as such.
+void test2() {
+  static int y = 0;
+  int x;
+  ^{ y = x + 1; }();  // expected-warning{{Variable 'x' is captured by block with a garbage value}}
+}
+
+void test2_b() {
+  static int y = 0;
+  __block int x;
+  // This is also a bug, but should be found not by checking the value
+  // 'x' is bound at block creation.
+  ^{ y = x + 1; }(); // no-warning
+}
+
+void test2_c() {
+  typedef void (^myblock)(void);
+  myblock f = ^() { f(); }; // expected-warning{{Variable 'f' is captured by block with a garbage value}}
+}
\ No newline at end of file
diff --git a/test/Analysis/casts.c b/test/Analysis/casts.c
new file mode 100644
index 0000000..1cb88e6
--- /dev/null
+++ b/test/Analysis/casts.c
@@ -0,0 +1,67 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -verify %s
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -verify %s
+
+// Test if the 'storage' region gets properly initialized after it is cast to
+// 'struct sockaddr *'. 
+
+typedef unsigned char __uint8_t;
+typedef unsigned int __uint32_t;
+typedef __uint32_t __darwin_socklen_t;
+typedef __uint8_t sa_family_t;
+typedef __darwin_socklen_t socklen_t;
+struct sockaddr { sa_family_t sa_family; };
+struct sockaddr_storage {};
+
+void getsockname();
+
+void f(int sock) {
+  struct sockaddr_storage storage;
+  struct sockaddr* sockaddr = (struct sockaddr*)&storage;
+  socklen_t addrlen = sizeof(storage);
+  getsockname(sock, sockaddr, &addrlen);
+  switch (sockaddr->sa_family) { // no-warning
+  default:
+    ;
+  }
+}
+
+struct s {
+  struct s *value;
+};
+
+void f1(struct s **pval) {
+  int *tbool = ((void*)0);
+  struct s *t = *pval;
+  pval = &(t->value);
+  tbool = (int *)pval; // use the cast-to type 'int *' to create element region.
+  char c = (unsigned char) *tbool; // Should use cast-to type to create symbol.
+  if (*tbool == -1) // here load the element region with the correct type 'int'
+    (void)3;
+}
+
+void f2(const char *str) {
+ unsigned char ch, cl, *p;
+
+ p = (unsigned char *)str;
+ ch = *p++; // use cast-to type 'unsigned char' to create element region.
+ cl = *p++;
+ if(!cl)
+    cl = 'a';
+}
+
+// Test cast VariableSizeArray to pointer does not crash.
+void *memcpy(void *, void const *, unsigned long);
+typedef unsigned char Byte;
+void doit(char *data, int len) {
+    if (len) {
+        Byte buf[len];
+        memcpy(buf, data, len);
+    }
+}
+
+// PR 6013 and 6035 - Test that a cast of a pointer to long and then to int does not crash SValuator.
+void pr6013_6035_test(void *p) {
+  unsigned int foo;
+  foo = ((long)(p));
+  (void) foo;
+}
diff --git a/test/Analysis/casts.m b/test/Analysis/casts.m
new file mode 100644
index 0000000..c99b4d6
--- /dev/null
+++ b/test/Analysis/casts.m
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -verify %s
+
+// Test function pointer casts.  Currently we track function addresses using
+// loc::FunctionVal.  Because casts can be arbitrary, do we need to model
+// functions with regions?
+typedef void* (*MyFuncTest1)(void);
+
+MyFuncTest1 test1_aux(void);
+void test1(void) {
+  void *x;
+  void* (*p)(void);
+  p = ((void*) test1_aux());
+  if (p != ((void*) 0)) x = (*p)();
+}
+
+// Test casts from void* to function pointers.  Same issue as above:
+// should we eventually model function pointers using regions?
+void* test2(void *p) {
+  MyFuncTest1 fp = (MyFuncTest1) p;
+  return (*fp)();
+}
diff --git a/test/Analysis/cfref_PR2519.c b/test/Analysis/cfref_PR2519.c
new file mode 100644
index 0000000..ebf3544
--- /dev/null
+++ b/test/Analysis/cfref_PR2519.c
@@ -0,0 +1,48 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=range -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -verify %s
+
+typedef unsigned char Boolean;
+typedef signed long CFIndex;
+typedef const void * CFTypeRef;
+typedef const struct __CFString * CFStringRef;
+typedef const struct __CFAllocator * CFAllocatorRef;
+extern const CFAllocatorRef kCFAllocatorDefault;
+typedef struct {} CFAllocatorContext;
+extern void CFRelease(CFTypeRef cf);
+typedef struct {}
+CFDictionaryKeyCallBacks;
+extern const CFDictionaryKeyCallBacks kCFTypeDictionaryKeyCallBacks;
+typedef struct {}
+CFDictionaryValueCallBacks;
+extern const CFDictionaryValueCallBacks kCFTypeDictionaryValueCallBacks;
+typedef const struct __CFDictionary * CFDictionaryRef;
+extern CFDictionaryRef CFDictionaryCreate(CFAllocatorRef allocator, const void **keys, const void **values, CFIndex numValues, const CFDictionaryKeyCallBacks *keyCallBacks, const CFDictionaryValueCallBacks *valueCallBacks);
+enum { kCFNumberSInt8Type = 1,     kCFNumberSInt16Type = 2,     kCFNumberSInt32Type = 3,     kCFNumberSInt64Type = 4,     kCFNumberFloat32Type = 5,     kCFNumberFloat64Type = 6,      kCFNumberCharType = 7,     kCFNumberShortType = 8,     kCFNumberIntType = 9,     kCFNumberLongType = 10,     kCFNumberLongLongType = 11,     kCFNumberFloatType = 12,     kCFNumberDoubleType = 13,      kCFNumberCFIndexType = 14,      kCFNumberNSIntegerType = 15,     kCFNumberCGFloatType = 16,     kCFNumberMaxType = 16    };
+typedef CFIndex CFNumberType;
+typedef const struct __CFNumber * CFNumberRef;
+extern CFNumberRef CFNumberCreate(CFAllocatorRef allocator, CFNumberType theType, const void *valuePtr);
+typedef struct __CFNotificationCenter * CFNotificationCenterRef;
+extern CFNotificationCenterRef CFNotificationCenterGetDistributedCenter(void);
+extern void CFNotificationCenterPostNotification(CFNotificationCenterRef center, CFStringRef name, const void *object, CFDictionaryRef userInfo, Boolean deliverImmediately);
+
+// This test case was reported in PR2519 as a false positive (_value was
+// reported as being leaked).
+
+int main(int argc, char **argv) {
+ CFStringRef _key = ((CFStringRef) __builtin___CFStringMakeConstantString ("" "Process identifier" ""));
+ int pid = 42;
+
+ CFNumberRef _value = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &pid);
+ CFDictionaryRef userInfo = CFDictionaryCreate(kCFAllocatorDefault, (const void **)&_key, (const void **)&_value, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ CFRelease(_value); // no-warning
+ CFNotificationCenterPostNotification(CFNotificationCenterGetDistributedCenter(),
+           ((CFStringRef) __builtin___CFStringMakeConstantString ("" "GrowlPreferencesChanged" "")),
+           ((CFStringRef) __builtin___CFStringMakeConstantString ("" "GrowlUserDefaults" "")),
+           userInfo, 0);
+ CFRelease(userInfo); // no-warning
+
+ return 0;
+}
+
diff --git a/test/Analysis/cfref_rdar6080742.c b/test/Analysis/cfref_rdar6080742.c
new file mode 100644
index 0000000..12b0819
--- /dev/null
+++ b/test/Analysis/cfref_rdar6080742.c
@@ -0,0 +1,58 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=range -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -verify %s
+
+// This test case was reported in <rdar:problem/6080742>.
+// It tests path-sensitivity with respect to '!(cfstring != 0)' (negation of inequality).
+
+int printf(const char *restrict,...);
+typedef unsigned long UInt32;
+typedef signed long SInt32;
+typedef SInt32  OSStatus;
+typedef unsigned char Boolean;
+enum { noErr = 0};
+typedef const void *CFTypeRef;
+typedef const struct __CFString *CFStringRef;
+typedef const struct __CFAllocator *CFAllocatorRef;
+extern void     CFRelease(CFTypeRef cf);
+typedef UInt32  CFStringEncoding;
+enum { kCFStringEncodingMacRoman = 0, kCFStringEncodingWindowsLatin1 = 0x0500,
+       kCFStringEncodingISOLatin1 = 0x0201, kCFStringEncodingNextStepLatin = 0x0B01,
+       kCFStringEncodingASCII = 0x0600, kCFStringEncodingUnicode = 0x0100,
+       kCFStringEncodingUTF8 = 0x08000100, kCFStringEncodingNonLossyASCII = 0x0BFF,
+       kCFStringEncodingUTF16 = 0x0100, kCFStringEncodingUTF16BE = 0x10000100,
+       kCFStringEncodingUTF16LE = 0x14000100, kCFStringEncodingUTF32 = 0x0c000100,
+       kCFStringEncodingUTF32BE = 0x18000100, kCFStringEncodingUTF32LE = 0x1c000100};
+extern CFStringRef CFStringCreateWithCString(CFAllocatorRef alloc, const char *cStr, CFStringEncoding encoding);
+
+enum { memROZWarn = -99, memROZError = -99, memROZErr = -99, memFullErr = -108,
+       nilHandleErr = -109, memWZErr = -111, memPurErr = -112, memAdrErr = -110,
+       memAZErr = -113, memPCErr = -114, memBCErr = -115, memSCErr = -116, memLockedErr = -117};
+
+#define DEBUG1
+
+void            DebugStop(const char *format,...);
+void            DebugTraceIf(unsigned int condition, const char *format,...);
+Boolean         DebugDisplayOSStatusMsg(OSStatus status, const char *statusStr, const char *fileName, unsigned long lineNumber);
+
+#define Assert(condition)if (!(condition)) { DebugStop("Assertion failure: %s [File: %s, Line: %lu]", #condition, __FILE__, __LINE__); }
+#define AssertMsg(condition, message)if (!(condition)) { DebugStop("Assertion failure: %s (%s) [File: %s, Line: %lu]", #condition, message, __FILE__, __LINE__); }
+#define Require(condition)if (!(condition)) { DebugStop("Assertion failure: %s [File: %s, Line: %lu]", #condition, __FILE__, __LINE__); }
+#define RequireAction(condition, action)if (!(condition)) { DebugStop("Assertion failure: %s [File: %s, Line: %lu]", #condition, __FILE__, __LINE__); action }
+#define RequireActionSilent(condition, action)if (!(condition)) { action }
+#define AssertNoErr(err){ DebugDisplayOSStatusMsg((err), #err, __FILE__, __LINE__); }
+#define RequireNoErr(err, action){ if( DebugDisplayOSStatusMsg((err), #err, __FILE__, __LINE__) ) { action }}
+
+void DebugStop(const char *format,...); /* Not an abort function. */
+
+int main(int argc, char *argv[]) {
+  CFStringRef     cfString;
+  OSStatus        status = noErr;
+  cfString = CFStringCreateWithCString(0, "hello", kCFStringEncodingUTF8);
+  RequireAction(cfString != 0, return memFullErr;) //no - warning
+    printf("cfstring %p\n", cfString);
+  Exit:
+  CFRelease(cfString);
+  return 0;
+}
diff --git a/test/Analysis/complex.c b/test/Analysis/complex.c
new file mode 100644
index 0000000..bb2b2fe
--- /dev/null
+++ b/test/Analysis/complex.c
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=basic -verify -Wno-unreachable-code %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=range -verify -Wno-unreachable-code %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=basic -verify -Wno-unreachable-code %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -verify -Wno-unreachable-code %s
+
+#include <stdint.h>
+
+void f1(int * p) {
+  
+  // This branch should be infeasible
+  // because __imag__ p is 0.
+  if (!p && __imag__ (intptr_t) p)
+    *p = 1; // no-warning
+
+  // If p != 0 then this branch is feasible; otherwise it is not.
+  if (__real__ (intptr_t) p)
+    *p = 1; // no-warning
+    
+  *p = 2; // expected-warning{{Dereference of null pointer}}
+}
diff --git a/test/Analysis/concrete-address.c b/test/Analysis/concrete-address.c
new file mode 100644
index 0000000..07ca713
--- /dev/null
+++ b/test/Analysis/concrete-address.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -verify %s
+
+void foo() {
+  int *p = (int*) 0x10000; // Should not crash here.
+  *p = 3;
+}
diff --git a/test/Analysis/conditional-op-missing-lhs.c b/test/Analysis/conditional-op-missing-lhs.c
new file mode 100644
index 0000000..86882a5
--- /dev/null
+++ b/test/Analysis/conditional-op-missing-lhs.c
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-dead-stores -warn-uninit-values -verify %s
+
+void f1()
+{
+  int i;
+  
+  int j = i ? : 1; // expected-warning{{use of uninitialized variable}} //expected-warning{{Value stored to 'j' during its initialization is never read}}
+}
+
+void *f2(int *i)
+{
+  return i ? : 0;
+}
+
+void *f3(int *i)
+{
+  int a;
+  
+  return &a ? : i;
+}
+
+void f4()
+{
+  char c[1 ? : 2];
+}
+
diff --git a/test/Analysis/dead-stores.c b/test/Analysis/dead-stores.c
new file mode 100644
index 0000000..209ca65
--- /dev/null
+++ b/test/Analysis/dead-stores.c
@@ -0,0 +1,452 @@
+// RUN: %clang_cc1 -Wunused-variable -analyze -analyzer-experimental-internal-checks -analyzer-check-dead-stores -fblocks -verify -Wno-unreachable-code -analyzer-opt-analyze-nested-blocks %s
+// RUN: %clang_cc1 -Wunused-variable -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=basic -analyzer-check-dead-stores -fblocks -verify -Wno-unreachable-code -analyzer-opt-analyze-nested-blocks %s
+// RUN: %clang_cc1 -Wunused-variable -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=range -analyzer-check-dead-stores -fblocks -verify -Wno-unreachable-code -analyzer-opt-analyze-nested-blocks %s
+// RUN: %clang_cc1 -Wunused-variable -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=basic -analyzer-check-dead-stores -fblocks -verify -Wno-unreachable-code -analyzer-opt-analyze-nested-blocks %s
+// RUN: %clang_cc1 -Wunused-variable -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -analyzer-check-dead-stores -fblocks -verify -Wno-unreachable-code -analyzer-opt-analyze-nested-blocks %s
+
+void f1() {
+  int k, y; // expected-warning{{unused variable 'k'}} expected-warning{{unused variable 'y'}}
+  int abc=1;
+  long idx=abc+3*5; // expected-warning {{never read}} expected-warning{{unused variable 'idx'}}
+}
+
+void f2(void *b) {
+ char *c = (char*)b; // no-warning
+ char *d = b+1; // expected-warning {{never read}} expected-warning{{unused variable 'd'}}
+ printf("%s", c); // expected-warning{{implicitly declaring C library function 'printf' with type 'int (char const *, ...)'}} \
+ // expected-note{{please include the header <stdio.h> or explicitly provide a declaration for 'printf'}}
+}
+
+int f();
+
+void f3() {
+  int r;
+  if ((r = f()) != 0) { // no-warning
+    int y = r; // no-warning
+    printf("the error is: %d\n", y);
+  }
+}
+
+void f4(int k) {
+  
+  k = 1;
+  
+  if (k)
+    f1();
+    
+  k = 2;  // expected-warning {{never read}}
+}
+  
+void f5() {
+
+  int x = 4; // no-warning
+  int *p = &x; // expected-warning{{never read}} expected-warning{{unused variable 'p'}}
+
+}
+
+int f6() {
+  
+  int x = 4;
+  ++x; // expected-warning{{never read}}
+  return 1;
+}
+
+int f7(int *p) {  
+  // This is allowed for defensive programming.
+  p = 0; // no-warning  
+  return 1;
+}
+
+int f7b(int *p) {  
+  // This is allowed for defensive programming.
+  p = (0); // no-warning  
+  return 1;
+}
+
+int f7c(int *p) {  
+  // This is allowed for defensive programming.
+  p = (void*) 0; // no-warning  
+  return 1;
+}
+
+int f7d(int *p) {  
+  // This is allowed for defensive programming.
+  p = (void*) (0); // no-warning  
+  return 1;
+}
+
+int f8(int *p) {
+  extern int *baz();
+  if ((p = baz())) // expected-warning{{Although the value}}
+    return 1;
+  return 0;
+}
+
+int f9() {
+  int x = 4;
+  x = x + 10; // expected-warning{{never read}}
+  return 1;
+}
+
+int f10() {
+  int x = 4;
+  x = 10 + x; // expected-warning{{never read}}
+  return 1;
+}
+
+int f11() {
+  int x = 4;
+  return x++; // expected-warning{{never read}}
+}
+
+int f11b() {
+  int x = 4;
+  return ((((++x)))); // no-warning
+}
+
+int f12a(int y) {
+  int x = y;  // expected-warning{{unused variable 'x'}}
+  return 1;
+}
+int f12b(int y) {
+  int x __attribute__((unused)) = y;  // no-warning
+  return 1;
+}
+int f12c(int y) {
+  // Allow initialiation of scalar variables by parameters as a form of
+  // defensive programming.
+  int x = y;  // no-warning
+  x = 1;
+  return x;
+}
+
+// Filed with PR 2630.  This code should produce no warnings.
+int f13(void)
+{
+  int a = 1;
+  int b, c = b = a + a;
+
+  if (b > 0)
+    return (0);
+
+  return (a + b + c);
+}
+
+// Filed with PR 2763.
+int f14(int count) {
+  int index, nextLineIndex;
+  for (index = 0; index < count; index = nextLineIndex+1) {
+    nextLineIndex = index+1;  // no-warning
+    continue;
+  }
+  return index;
+}
+
+// Test case for <rdar://problem/6248086>
+void f15(unsigned x, unsigned y) {
+  int count = x * y;   // no-warning
+  int z[count]; // expected-warning{{unused variable 'z'}}
+}
+
+int f16(int x) {
+  x = x * 2;
+  x = sizeof(int [x = (x || x + 1) * 2]) // expected-warning{{Although the value stored to 'x' is used}}
+      ? 5 : 8;
+  return x;
+}
+
+// Self-assignments should not be flagged as dead stores.
+void f17() {
+  int x = 1;
+  x = x; // no-warning
+}
+
+// <rdar://problem/6506065>
+// The values of dead stores are only "consumed" in an enclosing expression
+// what that value is actually used.  In other words, don't say "Although the
+// value stored to 'x' is used...".
+int f18() {
+   int x = 0; // no-warning
+   if (1)
+      x = 10;  // expected-warning{{Value stored to 'x' is never read}}
+   while (1)
+      x = 10;  // expected-warning{{Value stored to 'x' is never read}}
+   do
+      x = 10;   // expected-warning{{Value stored to 'x' is never read}}
+   while (1);
+
+   return (x = 10); // expected-warning{{Although the value stored to 'x' is used in the enclosing expression, the value is never actually read from 'x'}}
+}
+
+// PR 3514: false positive `dead initialization` warning for init to global
+//  http://llvm.org/bugs/show_bug.cgi?id=3514
+extern const int MyConstant;
+int f19(void) {
+  int x = MyConstant;  // no-warning
+  x = 1;
+  return x;
+}
+
+int f19b(void) { // This case is the same as f19.
+  const int MyConstant = 0;
+  int x = MyConstant; // no-warning
+  x = 1;
+  return x;  
+}
+
+void f20(void) {
+  int x = 1; // no-warning
+#pragma unused(x)
+}
+
+void halt() __attribute__((noreturn));
+int f21() {
+  int x = 4;
+  
+  ++x; // expected-warning{{never read}}
+  if (1) {
+    halt();
+    (void)x;
+  }
+  return 1;
+}
+
+int j;
+void f22() {
+  int x = 4;
+  int y1 = 4;
+  int y2 = 4;
+  int y3 = 4;
+  int y4 = 4;
+  int y5 = 4;
+  int y6 = 4;
+  int y7 = 4;
+  int y8 = 4;
+  int y9 = 4;
+  int y10 = 4;
+  int y11 = 4;
+  int y12 = 4;
+  int y13 = 4;
+  int y14 = 4;
+  int y15 = 4;
+  int y16 = 4;
+  int y17 = 4;
+  int y18 = 4;
+  int y19 = 4;
+  int y20 = 4;
+
+  ++x; // expected-warning{{never read}}
+  ++y1;
+  ++y2;
+  ++y3;
+  ++y4;
+  ++y5;
+  ++y6;
+  ++y7;
+  ++y8;
+  ++y9;
+  ++y10;
+  ++y11;
+  ++y12;
+  ++y13;
+  ++y14;
+  ++y15;
+  ++y16;
+  ++y17;
+  ++y18;
+  ++y19;
+  ++y20;
+
+  switch (j) {
+  case 1:
+    if (0)
+      (void)x;
+    if (1) {
+      (void)y1;
+      return;
+    }
+    (void)x;
+    break;
+  case 2:
+    if (0)
+      (void)x;
+    else {
+      (void)y2;
+      return;
+    }
+    (void)x;
+    break;
+  case 3:
+    if (1) {
+      (void)y3;
+      return;
+    } else
+      (void)x;
+    (void)x;
+  break;
+  case 4:
+    0 ? : ((void)y4, ({ return; }));
+    (void)x;
+    break;
+  case 5:
+    1 ? : (void)x;
+    0 ? (void)x : ((void)y5, ({ return; }));
+    (void)x;
+    break;
+  case 6:
+    1 ? ((void)y6, ({ return; })) : (void)x;
+    (void)x;
+    break;
+  case 7:
+    (void)(0 && x);
+    (void)y7;
+    (void)(0 || (y8, ({ return; }), 1));
+    (void)x;
+    break;
+  case 8:
+    (void)(1 && (y9, ({ return; }), 1));
+    (void)x;
+    break;
+  case 9:
+    (void)(1 || x);
+    (void)y10;
+    break;
+  case 10:
+    while (0) {
+      (void)x;
+    }
+    (void)y11;
+    break;
+  case 11:
+    while (1) {
+      (void)y12;
+    }
+    (void)x;
+    break;
+  case 12:
+    do {
+      (void)y13;
+    } while (0);
+    (void)y14;
+    break;
+  case 13:
+    do {
+      (void)y15;
+    } while (1);
+    (void)x;
+    break;
+  case 14:
+    for (;;) {
+      (void)y16;
+    }
+    (void)x;    
+    break;
+  case 15:
+    for (;1;) {
+      (void)y17;
+    }
+    (void)x;
+    break;
+  case 16:
+    for (;0;) {
+      (void)x;
+    }
+    (void)y18;
+    break;
+  case 17:
+    __builtin_choose_expr(0, (void)x, ((void)y19, ({ return; })));
+    (void)x;
+    break;
+  case 19:
+    __builtin_choose_expr(1, ((void)y20, ({ return; })), (void)x);
+    (void)x;
+    break;
+  }
+}
+
+void f23_aux(const char* s);
+void f23(int argc, char **argv) {
+  int shouldLog = (argc > 1); // no-warning
+  ^{ 
+     if (shouldLog) f23_aux("I did too use it!\n");
+     else f23_aux("I shouldn't log.  Wait.. d'oh!\n");
+  }();
+}
+
+void f23_pos(int argc, char **argv) {
+  int shouldLog = (argc > 1); // expected-warning{{Value stored to 'shouldLog' during its initialization is never read}} expected-warning{{unused variable 'shouldLog'}}
+  ^{ 
+     f23_aux("I did too use it!\n");
+  }();  
+}
+
+void f24_A(int y) {
+  // FIXME: One day this should be reported as dead since 'z = x + y' is dead.
+  int x = (y > 2); // no-warning
+  ^ {
+      int z = x + y; // expected-warning{{Value stored to 'z' during its initialization is never read}} expected-warning{{unused variable 'z'}}
+  }();  
+}
+
+void f24_B(int y) {
+  // FIXME: One day this should be reported as dead since 'x' is just overwritten.
+  __block int x = (y > 2); // no-warning
+  ^{
+    // FIXME: This should eventually be a dead store since it is never read either.
+    x = 5; // no-warning
+  }();
+}
+
+int f24_C(int y) {
+  // FIXME: One day this should be reported as dead since 'x' is just overwritten.
+  __block int x = (y > 2); // no-warning
+  ^{ 
+    x = 5; // no-warning
+  }();
+  return x;
+}
+
+int f24_D(int y) {
+  __block int x = (y > 2); // no-warning
+  ^{ 
+    if (y > 4)
+      x = 5; // no-warning
+  }();
+  return x;
+}
+
+// This example shows that writing to a variable captured by a block means that it might
+// not be dead.
+int f25(int y) {
+  __block int x = (y > 2);
+  __block int z = 0;
+  void (^foo)() = ^{ z = x + y; };
+  x = 4; // no-warning
+  foo();
+  return z; 
+}
+
+// This test is mostly the same as 'f25', but shows that the heuristic of pruning out dead
+// stores for variables that are just marked '__block' is overly conservative.
+int f25_b(int y) {
+  // FIXME: we should eventually report a dead store here.
+  __block int x = (y > 2);
+  __block int z = 0;
+  x = 4; // no-warning
+  return z; 
+}
+
+int f26_nestedblocks() {
+  int z;
+  z = 1;
+  __block int y = 0;
+  ^{
+    int k;
+    k = 1; // expected-warning{{Value stored to 'k' is never read}}
+    ^{
+        y = z + 1;
+     }();
+  }();
+  return y;
+}
+
diff --git a/test/Analysis/dead-stores.cpp b/test/Analysis/dead-stores.cpp
new file mode 100644
index 0000000..22d446e
--- /dev/null
+++ b/test/Analysis/dead-stores.cpp
@@ -0,0 +1,94 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-dead-stores -verify -Wno-unreachable-code %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=basic -analyzer-check-dead-stores -verify -Wno-unreachable-code %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=range -analyzer-check-dead-stores -verify -Wno-unreachable-code %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=basic -analyzer-check-dead-stores -verify -Wno-unreachable-code %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -analyzer-check-dead-stores -verify -Wno-unreachable-code %s
+
+//===----------------------------------------------------------------------===//
+// Basic dead store checking (but in C++ mode).
+//===----------------------------------------------------------------------===//
+
+int j;
+void test1() {
+  int x = 4;
+
+  ++x; // expected-warning{{never read}}
+
+  switch (j) {
+  case 1:
+    throw 1;
+    (void)x;
+    break;
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// Dead store checking involving constructors.
+//===----------------------------------------------------------------------===//
+
+class Test2 {
+  int &x;
+public:
+  Test2(int &y) : x(y) {}
+  ~Test2() { ++x; }
+};
+
+int test2(int x) {
+  { Test2 a(x); } // no-warning
+  return x;
+}
+
+//===----------------------------------------------------------------------===//
+// Dead store checking involving CXXTemporaryExprs
+//===----------------------------------------------------------------------===//
+
+namespace TestTemp {
+  template<typename _Tp>
+  class pencil {
+  public:
+    ~pencil() throw() {}
+  };
+  template<typename _Tp, typename _Number2> struct _Row_base {
+    _Row_base(const pencil<_Tp>& x) {}
+  };
+  template<typename _Tp, typename _Number2 = TestTemp::pencil<_Tp> >
+  class row : protected _Row_base<_Tp, _Number2>     {
+    typedef _Row_base<_Tp, _Number2> _Base;
+    typedef _Number2 pencil_type;
+  public:
+    explicit row(const pencil_type& __a = pencil_type()) : _Base(__a) {}
+  };
+}
+
+void test2_b() {
+  TestTemp::row<const char*> x; // no-warning
+}
+
+//===----------------------------------------------------------------------===//
+// Test references.
+//===----------------------------------------------------------------------===//
+
+void test3_a(int x) {
+  ++x; // expected-warning{{never read}}
+}
+
+void test3_b(int &x) {
+  ++x; // no-warninge
+}
+
+void test3_c(int x) {
+  int &y = x;
+  // Shows the limitation of dead stores tracking.  The write is really
+  // dead since the value cannot escape the function.
+  ++y; // no-warning
+}
+
+void test3_d(int &x) {
+  int &y = x;
+  ++y; // no-warning
+}
+
+void test3_e(int &x) {
+  int &y = x;
+}
+
diff --git a/test/Analysis/dead-stores.m b/test/Analysis/dead-stores.m
new file mode 100644
index 0000000..701e580
--- /dev/null
+++ b/test/Analysis/dead-stores.m
@@ -0,0 +1,43 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-dead-stores -verify %s
+
+typedef signed char BOOL;
+typedef unsigned int NSUInteger;
+typedef struct _NSZone NSZone;
+@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+@protocol NSObject  - (BOOL)isEqual:(id)object; @end
+@protocol NSCopying  - (id)copyWithZone:(NSZone *)zone; @end
+@protocol NSCoding  - (void)encodeWithCoder:(NSCoder *)aCoder; @end
+@interface NSObject <NSObject> {} @end
+extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone);
+@interface NSValue : NSObject <NSCopying, NSCoding>  - (void)getValue:(void *)value; @end
+typedef float CGFloat;
+typedef struct _NSPoint {} NSRange;
+@interface NSValue (NSValueRangeExtensions)  + (NSValue *)valueWithRange:(NSRange)range;
+- (BOOL)containsObject:(id)anObject;
+@end
+@class NSURLAuthenticationChallenge;
+@interface NSResponder : NSObject <NSCoding> {} @end
+@class NSArray, NSDictionary, NSString;
+@interface NSObject (NSKeyValueBindingCreation)
++ (void)exposeBinding:(NSString *)binding;
+- (NSArray *)exposedBindings;
+@end
+extern NSString *NSAlignmentBinding;
+
+// This test case was reported as a false positive due to a bug in the
+// LiveVariables <-> DeadStores interplay.  We should not flag a warning
+// here.  The test case was reported in:
+//  http://lists.cs.uiuc.edu/pipermail/cfe-dev/2008-July/002157.html
+void DeadStoreTest(NSObject *anObject) {
+  NSArray *keys;
+  if ((keys = [anObject exposedBindings]) &&   // no-warning
+      ([keys containsObject:@"name"] && [keys containsObject:@"icon"])) {}
+}
+
+// This test case was a false positive due to how clang models
+// pointer types and ObjC object pointer types differently.  Here
+// we don't warn about a dead store because 'nil' is assigned to
+// an object pointer for the sake of defensive programming.
+void rdar_7631278(NSObject *x) {
+  x = ((void*)0);
+}
diff --git a/test/Analysis/delegates.m b/test/Analysis/delegates.m
new file mode 100644
index 0000000..18b4241
--- /dev/null
+++ b/test/Analysis/delegates.m
@@ -0,0 +1,114 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -verify %s
+
+
+//===----------------------------------------------------------------------===//
+// The following code is reduced using delta-debugging from
+// Foundation.h (Mac OS X).
+//
+// It includes the basic definitions for the test cases below.
+// Not directly including Foundation.h directly makes this test case 
+// both svelte and portable to non-Mac platforms.
+//===----------------------------------------------------------------------===//
+
+typedef const void * CFTypeRef;
+typedef const struct __CFString * CFStringRef;
+typedef const struct __CFAllocator * CFAllocatorRef;
+extern const CFAllocatorRef kCFAllocatorDefault;
+extern CFTypeRef CFRetain(CFTypeRef cf);
+void CFRelease(CFTypeRef cf);
+typedef const struct __CFDictionary * CFDictionaryRef;
+const void *CFDictionaryGetValue(CFDictionaryRef theDict, const void *key);
+extern CFStringRef CFStringCreateWithFormat(CFAllocatorRef alloc, CFDictionaryRef formatOptions, CFStringRef format, ...);
+typedef signed char BOOL;
+typedef int NSInteger;
+typedef unsigned int NSUInteger;
+typedef struct objc_selector *SEL;
+@class NSString, Protocol;
+extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, 2)));
+typedef NSInteger NSComparisonResult;
+typedef struct _NSZone NSZone;
+@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+@protocol NSObject
+- (BOOL)isEqual:(id)object;
+- (oneway void)release;
+- (Class)class;
+- (id)retain;
+@end
+@protocol NSCopying
+- (id)copyWithZone:(NSZone *)zone;
+@end
+@protocol NSMutableCopying
+- (id)mutableCopyWithZone:(NSZone *)zone;
+@end
+@protocol NSCoding
+- (void)encodeWithCoder:(NSCoder *)aCoder;
+@end
+@interface NSObject <NSObject> {}
+- (id)init;
++ (id)alloc;
++ (Class)class;
+- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;
+@end
+extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone);
+typedef struct {} NSFastEnumerationState;
+@protocol NSFastEnumeration
+- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len;
+@end
+@class NSString;
+typedef struct _NSRange {} NSRange;
+@interface NSArray : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration>
+- (NSUInteger)count;
+@end
+@interface NSMutableArray : NSArray
+- (void)addObject:(id)anObject;
+- (id)initWithCapacity:(NSUInteger)numItems;
+@end
+typedef unsigned short unichar;
+@class NSData, NSArray, NSDictionary, NSCharacterSet, NSData, NSURL, NSError, NSLocale;
+typedef NSUInteger NSStringCompareOptions;
+@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding>    - (NSUInteger)length;
+- (NSComparisonResult)compare:(NSString *)string;
+- (NSComparisonResult)compare:(NSString *)string options:(NSStringCompareOptions)mask;
+- (NSComparisonResult)compare:(NSString *)string options:(NSStringCompareOptions)mask range:(NSRange)compareRange;
+- (NSComparisonResult)compare:(NSString *)string options:(NSStringCompareOptions)mask range:(NSRange)compareRange locale:(id)locale;
+- (NSComparisonResult)caseInsensitiveCompare:(NSString *)string;
+- (NSArray *)componentsSeparatedByCharactersInSet:(NSCharacterSet *)separator;
+@end
+@interface NSSimpleCString : NSString {} @end
+@interface NSConstantString : NSSimpleCString @end
+extern void *_NSConstantStringClassReference;
+
+//===----------------------------------------------------------------------===//
+// Test cases.
+//===----------------------------------------------------------------------===//
+
+//  <rdar://problem/6062730>
+// The analyzer doesn't perform any inter-procedural analysis, so delegates
+// involving [NSObject performSelector...] tend to lead to false positives.
+// For now the analyzer just stops tracking the reference count of the
+// receiver until we have better support for delegates.
+
+@interface test_6062730 : NSObject
++ (void)postNotification:(NSString *)str;
+- (void)foo;
+- (void)bar;
+@end
+
+@implementation test_6062730
+- (void) foo {
+  NSString *str = [[NSString alloc] init];
+  [test_6062730 performSelectorOnMainThread:@selector(postNotification:) withObject:str waitUntilDone:1];
+}
+
+- (void) bar {
+  NSString *str = [[NSString alloc] init]; // expected-warning{{leak}}
+  // FIXME: We need to resolve [self class] to 'test_6062730'.
+  [[self class] performSelectorOnMainThread:@selector(postNotification:) withObject:str waitUntilDone:1];
+}
+
++ (void) postNotification:(NSString *)str {
+  [str release]; // no-warning
+}
+@end
+
diff --git a/test/Analysis/elementtype.c b/test/Analysis/elementtype.c
new file mode 100644
index 0000000..08ffe32
--- /dev/null
+++ b/test/Analysis/elementtype.c
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region %s
+
+typedef struct added_obj_st {
+  int type;
+} ADDED_OBJ;
+
+// Test if we are using the canonical type for ElementRegion.
+void f() {
+  ADDED_OBJ *ao[4]={((void*)0),((void*)0),((void*)0),((void*)0)};
+  if (ao[0] != ((void*)0))   {
+    ao[0]->type=0;
+  }
+}
diff --git a/test/Analysis/exercise-ps.c b/test/Analysis/exercise-ps.c
new file mode 100644
index 0000000..0a95b70
--- /dev/null
+++ b/test/Analysis/exercise-ps.c
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -verify %s
+//
+// Just exercise the analyzer on code that has at one point caused issues
+// (i.e., no assertions or crashes).
+
+
+static void f1(const char *x, char *y) {
+  while (*x != 0) {
+    *y++ = *x++;
+  }
+}
+
+// This following case checks that we properly handle typedefs when getting
+// the RvalueType of an ElementRegion.
+typedef struct F12_struct {} F12_typedef;
+typedef void* void_typedef;
+void_typedef f2_helper();
+static void f2(void *buf) {
+  F12_typedef* x;
+  x = f2_helper();
+  memcpy((&x[1]), (buf), 1); // expected-warning{{implicitly declaring C library function 'memcpy' with type 'void *(void *, void const *}} \
+  // expected-note{{please include the header <string.h> or explicitly provide a declaration for 'memcpy'}}
+}
diff --git a/test/Analysis/fields.c b/test/Analysis/fields.c
new file mode 100644
index 0000000..c97d4f8
--- /dev/null
+++ b/test/Analysis/fields.c
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem %s -analyzer-store=basic -verify
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem %s -analyzer-store=region -verify
+
+unsigned foo();
+typedef struct bf { unsigned x:2; } bf;
+void bar() {
+  bf y;
+  *(unsigned*)&y = foo();
+  y.x = 1;
+}
+
+struct s {
+  int n;
+};
+
+void f() {
+  struct s a;
+  int *p = &(a.n) + 1;
+}
diff --git a/test/Analysis/func.c b/test/Analysis/func.c
new file mode 100644
index 0000000..53c873d
--- /dev/null
+++ b/test/Analysis/func.c
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -verify %s
+
+void f(void) {
+  void (*p)(void);
+  p = f;
+  p = &f;
+  p();
+  (*p)();
+}
+
+void g(void (*fp)(void));
+
+void f2() {
+  g(f);
+}
diff --git a/test/Analysis/inline.c b/test/Analysis/inline.c
new file mode 100644
index 0000000..952de73
--- /dev/null
+++ b/test/Analysis/inline.c
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -analyze -inline-call -analyzer-store region -analyze-function f2 -verify %s
+
+int f1() {
+  int y = 1;
+  y++;
+  return y;
+}
+
+void f2() {
+  int x = 1;
+  x = f1();
+  if (x == 1) {
+    int *p = 0;
+    *p = 3; // no-warning
+  }
+  if (x == 2) {
+    int *p = 0;
+    *p = 3; // expected-warning{{Dereference of null pointer (loaded from variable 'p')}}
+  }
+}
diff --git a/test/Analysis/inline2.c b/test/Analysis/inline2.c
new file mode 100644
index 0000000..e2758c1
--- /dev/null
+++ b/test/Analysis/inline2.c
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -analyze -inline-call -analyzer-store region -analyze-function f2 -verify %s
+
+// Test parameter 'a' is registered to LiveVariables analysis data although it
+// is not referenced in the function body. 
+// Before processing 'return 1;', in RemoveDeadBindings(), we query the liveness
+// of 'a', because we have a binding for it due to parameter passing.
+int f1(int a) {
+  return 1;
+}
+
+void f2() {
+  int x;
+  x = f1(1);
+}
diff --git a/test/Analysis/inline3.c b/test/Analysis/inline3.c
new file mode 100644
index 0000000..3661263
--- /dev/null
+++ b/test/Analysis/inline3.c
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -analyze -inline-call -analyzer-store region -analyze-function f2 -verify %s
+
+
+// Test when entering f1(), we set the right AnalysisContext to Environment.
+// Otherwise, block-level expr '1 && a' would not be block-level.
+int a;
+
+void f1() {
+  if (1 && a)
+    return;
+}
+
+void f2() {
+  f1();
+}
diff --git a/test/Analysis/inline4.c b/test/Analysis/inline4.c
new file mode 100644
index 0000000..dd2379f
--- /dev/null
+++ b/test/Analysis/inline4.c
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -analyze -inline-call -analyzer-store region -analyze-function f -verify %s
+
+int g(int a) {    
+  return a;
+}
+
+int f(int a) {
+  // Do not remove block-level expression bindings of caller when analyzing 
+  // in the callee.
+  if (1 && g(a)) // The binding of '1 && g(a)' which is an UndefinedVal 
+                 // carries important information.
+    return 1;
+  return 0;
+}
diff --git a/test/Analysis/malloc.c b/test/Analysis/malloc.c
new file mode 100644
index 0000000..21b6d46
--- /dev/null
+++ b/test/Analysis/malloc.c
@@ -0,0 +1,69 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-experimental-checks -analyzer-store=region -verify %s
+typedef __typeof(sizeof(int)) size_t;
+void *malloc(size_t);
+void free(void *);
+void *realloc(void *ptr, size_t size);
+void *calloc(size_t nmemb, size_t size);
+
+void f1() {
+  int *p = malloc(10);
+  return; // expected-warning{{Allocated memory never released. Potential memory leak.}}
+}
+
+void f1_b() {
+  int *p = malloc(10); // expected-warning{{Allocated memory never released. Potential memory leak.}}
+}
+
+void f2() {
+  int *p = malloc(10);
+  free(p);
+  free(p); // expected-warning{{Try to free a memory block that has been released}}
+}
+
+// This case tests that storing malloc'ed memory to a static variable which is
+// then returned is not leaked.  In the absence of known contracts for functions
+// or inter-procedural analysis, this is a conservative answer.
+int *f3() {
+  static int *p = 0;
+  p = malloc(10); 
+  return p; // no-warning
+}
+
+// This case tests that storing malloc'ed memory to a static global variable
+// which is then returned is not leaked.  In the absence of known contracts for
+// functions or inter-procedural analysis, this is a conservative answer.
+static int *p_f4 = 0;
+int *f4() {
+  p_f4 = malloc(10); 
+  return p_f4; // no-warning
+}
+
+int *f5() {
+  int *q = malloc(10);
+  q = realloc(q, 20);
+  return q; // no-warning
+}
+
+void f6() {
+  int *p = malloc(10);
+  if (!p)
+    return; // no-warning
+  else
+    free(p);
+}
+
+char *doit2();
+void pr6069() {
+  char *buf = doit2();
+  free(buf);
+}
+
+void pr6293() {
+  free(0);
+}
+
+void f7() {
+  char *x = (char*) malloc(4);
+  free(x);
+  x[0] = 'a'; // expected-warning{{Use dynamically allocated memory after it is freed.}}
+}
diff --git a/test/Analysis/method-call.cpp b/test/Analysis/method-call.cpp
new file mode 100644
index 0000000..dd89159
--- /dev/null
+++ b/test/Analysis/method-call.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-store region -verify %s
+struct A {
+  int x;
+  A(int a) { x = a; }
+  int getx() { return x; }
+};
+
+void f1() {
+  A x(3);
+  if (x.getx() == 3) {
+    int *p = 0;
+    *p = 3;  // expected-warning{{Dereference of null pointer}}
+  } else {
+    int *p = 0;
+    *p = 3;  // no-warning
+  }
+}
+
diff --git a/test/Analysis/misc-ps-64.m b/test/Analysis/misc-ps-64.m
new file mode 100644
index 0000000..0dbd6cb
--- /dev/null
+++ b/test/Analysis/misc-ps-64.m
@@ -0,0 +1,49 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=basic -verify -fblocks %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=range -verify -fblocks %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=basic -verify -fblocks %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -verify -fblocks %s
+
+// <rdar://problem/6440393> - A bunch of misc. failures involving evaluating
+//  these expressions and building CFGs.  These tests are here to prevent
+//  regressions.
+typedef long long int64_t;
+@class NSString, NSDictionary;
+typedef long NSInteger;
+typedef unsigned long NSUInteger;
+typedef unsigned char Boolean;
+typedef const struct __CFDictionary * CFDictionaryRef;
+
+extern Boolean CFDictionaryGetValueIfPresent(CFDictionaryRef theDict, const void *key, const void **value);
+static void shazam(NSUInteger i, unsigned char **out);
+
+void rdar_6440393_1(NSDictionary *dict) {
+  NSInteger x = 0;
+  unsigned char buf[10], *bufptr = buf;
+  if (!CFDictionaryGetValueIfPresent(0, dict, (void *)&x))
+    return;
+  shazam(x, &bufptr);
+}
+
+// <rdar://problem/6845148> - In this example we got a signedness
+// mismatch between the literal '0' and the value of 'scrooge'.  The
+// trick is to have the evaluator convert the literal to an unsigned
+// integer when doing a comparison with the pointer.  This happens
+// because of the transfer function logic of
+// OSAtomicCompareAndSwap64Barrier, which doesn't have special casts
+// in place to do this for us.
+_Bool OSAtomicCompareAndSwap64Barrier( int64_t __oldValue, int64_t __newValue, volatile int64_t *__theValue );
+extern id objc_lookUpClass(const char *name);
+void rdar_6845148(id debug_yourself) {
+  if (!debug_yourself) {
+    const char *wacky = ((void *)0);  
+    Class scrooge = wacky ? (Class)objc_lookUpClass(wacky) : ((void *)0);  
+    OSAtomicCompareAndSwap64Barrier(0, (int64_t)scrooge, (int64_t*)&debug_yourself);
+  }
+}
+void rdar_6845148_b(id debug_yourself) {
+  if (!debug_yourself) {
+    const char *wacky = ((void *)0);  
+    Class scrooge = wacky ? (Class)objc_lookUpClass(wacky) : ((void *)0);  
+    OSAtomicCompareAndSwap64Barrier((int64_t)scrooge, 0, (int64_t*)&debug_yourself);
+  }
+}
diff --git a/test/Analysis/misc-ps-basic-store.m b/test/Analysis/misc-ps-basic-store.m
new file mode 100644
index 0000000..4f8e4f6
--- /dev/null
+++ b/test/Analysis/misc-ps-basic-store.m
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -verify -fblocks %s
+
+//---------------------------------------------------------------------------
+// Test case 'checkaccess_union' differs for region store and basic store.
+// The basic store doesn't reason about compound literals, so the code
+// below won't fire an "uninitialized value" warning.
+//---------------------------------------------------------------------------
+
+// PR 2948 (testcase; crash on VisitLValue for union types)
+// http://llvm.org/bugs/show_bug.cgi?id=2948
+
+void checkaccess_union() {
+  int ret = 0, status;
+  if (((((__extension__ (((union {  // no-warning
+    __typeof (status) __in; int __i;}
+    )
+    {
+      .__in = (status)}
+      ).__i))) & 0xff00) >> 8) == 1)
+        ret = 1;
+}
+
+// BasicStore handles this case incorrectly because it doesn't reason about
+// the value pointed to by 'x' and thus creates different symbolic values
+// at the declarations of 'a' and 'b' respectively.  See the companion test
+// in 'misc-ps-region-store.m'.
+void test_trivial_symbolic_comparison_pointer_parameter(int *x) {
+  int a = *x;
+  int b = *x;
+  if (a != b) {
+    int *p = 0;
+    *p = 0xDEADBEEF;     // expected-warning{{null}}
+  }
+}
+
diff --git a/test/Analysis/misc-ps-eager-assume.m b/test/Analysis/misc-ps-eager-assume.m
new file mode 100644
index 0000000..a986b8e
--- /dev/null
+++ b/test/Analysis/misc-ps-eager-assume.m
@@ -0,0 +1,145 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -verify -fblocks %s -analyzer-eagerly-assume
+
+// Delta-reduced header stuff (needed for test cases).
+typedef signed char BOOL;
+typedef unsigned int NSUInteger;
+typedef struct _NSZone NSZone;
+@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+@protocol NSObject  - (BOOL)isEqual:(id)object;
+- (oneway void)release;
+@end  @protocol NSCopying  - (id)copyWithZone:(NSZone *)zone;
+@end  @protocol NSMutableCopying  - (id)mutableCopyWithZone:(NSZone *)zone;
+@end  @protocol NSCoding  - (void)encodeWithCoder:(NSCoder *)aCoder;
+@end    @interface NSObject <NSObject> {}
++ (id)alloc;
+@end  typedef struct {}
+NSFastEnumerationState;
+@protocol NSFastEnumeration  - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len;
+@end      @interface NSArray : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration>  - (NSUInteger)count;
+@end    @interface NSMutableArray : NSArray  - (void)addObject:(id)anObject;
+- (BOOL)isEqualToString:(NSString *)aString;
+@end        @interface NSAutoreleasePool : NSObject {}
+- (void)drain;
+- (id)init;
+@end
+
+// This test case tests that (x != 0) is eagerly evaluated before stored to
+// 'y'.  This test case complements recoverCastedSymbol (see below) because
+// the symbolic expression is stored to 'y' (which is a short instead of an
+// int).  recoverCastedSymbol() only recovers path-sensitivity when the
+// symbolic expression is literally the branch condition.
+//
+void handle_assign_of_condition(int x) {
+  // The cast to 'short' causes us to lose symbolic constraint.
+  short y = (x != 0);
+  char *p = 0;
+  if (y) {
+    // This should be infeasible.
+    if (!(x != 0)) {
+      *p = 1;  // no-warning
+    }
+  }
+}
+
+// From <rdar://problem/6619921>
+//
+// In this test case, 'needsAnArray' is a signed char.  The analyzer tracks
+// a symbolic value for this variable, but in the branch condition it is
+// promoted to 'int'.  Currently the analyzer doesn't reason well about
+// promotions of symbolic values, so this test case tests the logic in
+// 'recoverCastedSymbol()' (GRExprEngine.cpp) to test that we recover
+// path-sensitivity and use the symbol for 'needsAnArray' in the branch
+// condition.
+//
+void handle_symbolic_cast_in_condition(void) {
+  NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+
+  BOOL needsAnArray = [@"aString" isEqualToString:@"anotherString"];
+  NSMutableArray* array = needsAnArray ? [[NSMutableArray alloc] init] : 0;
+  if(needsAnArray)
+    [array release];
+
+  [pool drain];
+}
+
+// From PR 3836 (http://llvm.org/bugs/show_bug.cgi?id=3836)
+//
+// In this test case, the double '!' works fine with our symbolic constraints,
+// but we don't support comparing SymConstraint != SymConstraint.  By eagerly
+// assuming the truth of !!a or !!b, we can compare these values directly.
+//
+void pr3836(int *a, int *b) {
+  if (!!a != !!b) /* one of them is NULL */
+    return;
+  if (!a && !b) /* both are NULL */
+    return;
+      
+  *a = 1; // no-warning
+  *b = 1; // no-warning
+}
+
+
+//===---------------------------------------------------------------------===//
+// <rdar://problem/7342806>
+// This false positive occured because the symbolic constraint on a short was
+// not maintained via sign extension.  The analyzer doesn't properly handle
+// the sign extension, but now tracks the constraint.  This particular
+// case relies on -analyzer-eagerly-assume because of the expression
+// 'Flag1 != Count > 0'.
+//===---------------------------------------------------------------------===//
+
+void rdar7342806_aux(short x);
+
+void rdar7342806() {
+  extern short Count;
+  extern short Flag1;
+
+  short *Pointer = 0;
+  short  Flag2   = !!Pointer;   // Flag2 is false (0).
+  short  Ok      = 1;
+  short  Which;
+
+  if( Flag1 != Count > 0 )
+    // Static analyzer skips this so either
+    //   Flag1 is true and Count > 0
+    // or
+    //   Flag1 is false and Count <= 0
+    Ok = 0;
+
+  if( Flag1 != Flag2 )
+    // Analyzer skips this so Flag1 and Flag2 have the
+    // same value, both are false because Flag2 is false. And
+    // from that we know Count must be <= 0.
+    Ok = 0;
+
+  for( Which = 0;
+         Which < Count && Ok;
+           Which++ )
+    // This statement can only execute if Count > 0 which can only
+    // happen when Flag1 and Flag2 are both true and Flag2 will only
+    // be true when Pointer is not NULL.
+    rdar7342806_aux(*Pointer); // no-warning
+}
+
+//===---------------------------------------------------------------------===//
+// PR 5627 - http://llvm.org/bugs/show_bug.cgi?id=5627
+//  This test case depends on using -analyzer-eagerly-assume and
+//  -analyzer-store=region.  The '-analyzer-eagerly-assume' causes the path
+//  to bifurcate when evaluating the function call argument, and a state
+//  caching bug in GRExprEngine::CheckerVisit (and friends) caused the store
+//  to 'p' to not be evaluated along one path, but then an autotransition caused
+//  the path to keep on propagating with 'p' still set to an undefined value.
+//  We would then get a bogus report of returning uninitialized memory.
+//  Note: CheckerVisit mistakenly cleared an existing node, and the cleared
+//  node was resurrected by GRStmtNodeBuilder::~GRStmtNodeBuilder(), where
+//  'p' was not assigned.
+//===---------------------------------------------------------------------===//
+
+float *pr5627_f(int y);
+
+float *pr5627_g(int x) {
+  float *p;
+  p = pr5627_f(!x);
+  return p; // no-warning
+}
+
diff --git a/test/Analysis/misc-ps-flat-store.c b/test/Analysis/misc-ps-flat-store.c
new file mode 100644
index 0000000..8cbcecf
--- /dev/null
+++ b/test/Analysis/misc-ps-flat-store.c
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-store=flat -verify %s
+
+void f1() {
+  int x;
+  int *p;
+  x = 1;
+  p = 0;
+  if (x != 1)
+    *p = 1; // no-warning
+}
diff --git a/test/Analysis/misc-ps-ranges.m b/test/Analysis/misc-ps-ranges.m
new file mode 100644
index 0000000..b1afc3d
--- /dev/null
+++ b/test/Analysis/misc-ps-ranges.m
@@ -0,0 +1,60 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=range -verify -fblocks %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -verify -fblocks %s
+
+// <rdar://problem/6776949>
+// main's 'argc' argument is always > 0
+int main(int argc, char* argv[]) {
+  int *p = 0;
+
+  if (argc == 0)
+    *p = 1;
+
+  if (argc == 1)
+    return 1;
+
+  int x = 1;
+  int i;
+  
+  for(i=1;i<argc;i++){
+    p = &x;
+  }
+
+  return *p; // no-warning
+}
+
+// PR 5969: the comparison of argc < 3 || argc > 4 should constraint the switch
+//  statement from having the 'default' branch taken.  This previously reported a false
+//  positive with the use of 'v'.
+
+int pr5969(int argc, char *argv[]) {
+
+  int v;
+
+  if ((argc < 3) || (argc > 4)) return 0;
+
+  switch(argc) {
+    case 3:
+      v = 33;
+      break;
+    case 4:
+      v = 44;
+      break;
+  }
+
+  return v; // no-warning
+}
+
+int pr5969_positive(int argc, char *argv[]) {
+
+  int v;
+
+  if ((argc < 3) || (argc > 4)) return 0;
+
+  switch(argc) {
+    case 3:
+      v = 33;
+      break;
+  }
+
+  return v; // expected-warning{{Undefined or garbage value returned to caller}}
+}
diff --git a/test/Analysis/misc-ps-region-store-i386.m b/test/Analysis/misc-ps-region-store-i386.m
new file mode 100644
index 0000000..026d4f5
--- /dev/null
+++ b/test/Analysis/misc-ps-region-store-i386.m
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -verify -fblocks %s
+
+// Here is a case where a pointer is treated as integer, invalidated as an
+// integer, and then used again as a pointer.   This test just makes sure
+// we don't crash.
+typedef unsigned uintptr_t;
+void test_pointer_invalidated_as_int_aux(uintptr_t* ptr);
+void test_pointer_invalidated_as_int() {
+  void *x;
+  test_pointer_invalidated_as_int_aux((uintptr_t*) &x);
+  // Here we have a pointer to integer cast.
+  uintptr_t y = (uintptr_t) x;
+}
+
diff --git a/test/Analysis/misc-ps-region-store-x86_64.m b/test/Analysis/misc-ps-region-store-x86_64.m
new file mode 100644
index 0000000..e3c6d47
--- /dev/null
+++ b/test/Analysis/misc-ps-region-store-x86_64.m
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -verify -fblocks %s
+
+// Here is a case where a pointer is treated as integer, invalidated as an
+// integer, and then used again as a pointer.   This test just makes sure
+// we don't crash.
+typedef unsigned long uintptr_t;
+void test_pointer_invalidated_as_int_aux(uintptr_t* ptr);
+void test_pointer_invalidated_as_int() {
+  void *x;
+  test_pointer_invalidated_as_int_aux((uintptr_t*) &x);
+  // Here we have a pointer to integer cast.
+  uintptr_t y = (uintptr_t) x;
+}
+
diff --git a/test/Analysis/misc-ps-region-store.cpp b/test/Analysis/misc-ps-region-store.cpp
new file mode 100644
index 0000000..6794d48
--- /dev/null
+++ b/test/Analysis/misc-ps-region-store.cpp
@@ -0,0 +1,134 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -verify -fblocks   -analyzer-opt-analyze-nested-blocks %s
+
+// Test basic handling of references.
+char &test1_aux();
+char *test1() {
+  return &test1_aux();
+}
+
+// Test test1_aux() evaluates to char &.
+char test1_as_rvalue() {
+  return test1_aux();
+}
+
+// Test passing a value as a reference.  The 'const' in test2_aux() adds
+// an ImplicitCastExpr, which is evaluated as an lvalue.
+int test2_aux(const int &n);
+int test2(int n) {
+  return test2_aux(n);
+}
+
+int test2_b_aux(const short &n);
+int test2_b(int n) {
+  return test2_b_aux(n);
+}
+
+// Test getting the lvalue of a derived and converting it to a base.  This
+// previously crashed.
+class Test3_Base {};
+class Test3_Derived : public Test3_Base {};
+
+int test3_aux(Test3_Base &x);
+int test3(Test3_Derived x) {
+  return test3_aux(x);
+}
+
+//===---------------------------------------------------------------------===//
+// Test CFG support for C++ condition variables.
+//===---------------------------------------------------------------------===//
+
+int test_init_in_condition_aux();
+int test_init_in_condition() {
+  if (int x = test_init_in_condition_aux()) { // no-warning
+    return 1;
+  }
+  return 0;
+}
+
+int test_init_in_condition_switch() {
+  switch (int x = test_init_in_condition_aux()) { // no-warning
+    case 1:
+      return 0;
+    case 2:
+      if (x == 2)
+        return 0;
+      else {
+        // Unreachable.
+        int *p = 0;
+        *p = 0xDEADBEEF; // no-warning
+      }
+    default:
+      break;
+  }
+  return 0;
+}
+
+int test_init_in_condition_while() {
+  int z = 0;
+  while (int x = ++z) { // no-warning
+    if (x == 2)
+      break;
+  }
+  
+  if (z == 2)
+    return 0;
+  
+  int *p = 0;
+  *p = 0xDEADBEEF; // no-warning
+  return 0;
+}
+
+
+int test_init_in_condition_for() {
+  int z = 0;
+  for (int x = 0; int y = ++z; ++x) {
+    if (x == y) // no-warning
+      break;
+  }
+  if (z == 1)
+    return 0;
+    
+  int *p = 0;
+  *p = 0xDEADBEEF; // no-warning
+  return 0;
+}
+
+//===---------------------------------------------------------------------===//
+// Test handling of 'this' pointer.
+//===---------------------------------------------------------------------===//
+
+class TestHandleThis {
+  int x;
+
+  TestHandleThis();  
+  int foo();
+  int null_deref_negative();
+  int null_deref_positive();  
+};
+
+int TestHandleThis::foo() {
+  // Assume that 'x' is initialized.
+  return x + 1; // no-warning
+}
+
+int TestHandleThis::null_deref_negative() {
+  x = 10;
+  if (x == 10) {
+    return 1;
+  }
+  int *p = 0;
+  *p = 0xDEADBEEF; // no-warning
+  return 0;  
+}
+
+int TestHandleThis::null_deref_positive() {
+  x = 10;
+  if (x == 9) {
+    return 1;
+  }
+  int *p = 0;
+  *p = 0xDEADBEEF; // expected-warning{{null pointer}}
+  return 0;  
+}
+
diff --git a/test/Analysis/misc-ps-region-store.m b/test/Analysis/misc-ps-region-store.m
new file mode 100644
index 0000000..4255141
--- /dev/null
+++ b/test/Analysis/misc-ps-region-store.m
@@ -0,0 +1,1016 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -DTEST_64 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -verify -fblocks   -analyzer-opt-analyze-nested-blocks %s
+
+typedef long unsigned int size_t;
+void *memcpy(void *, const void *, size_t);
+void *alloca(size_t);
+
+typedef struct objc_selector *SEL;
+typedef signed char BOOL;
+typedef int NSInteger;
+typedef unsigned int NSUInteger;
+typedef struct _NSZone NSZone;
+@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+@protocol NSObject  - (BOOL)isEqual:(id)object; @end
+@protocol NSCopying  - (id)copyWithZone:(NSZone *)zone; @end
+@protocol NSMutableCopying  - (id)mutableCopyWithZone:(NSZone *)zone; @end
+@protocol NSCoding  - (void)encodeWithCoder:(NSCoder *)aCoder; @end
+@interface NSObject <NSObject> {} - (id)init; @end
+extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone);
+@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding>
+- (NSUInteger)length;
++ (id)stringWithUTF8String:(const char *)nullTerminatedCString;
+@end extern NSString * const NSBundleDidLoadNotification;
+@interface NSAssertionHandler : NSObject {}
++ (NSAssertionHandler *)currentHandler;
+- (void)handleFailureInMethod:(SEL)selector object:(id)object file:(NSString *)fileName lineNumber:(NSInteger)line description:(NSString *)format,...;
+@end
+extern NSString * const NSConnectionReplyMode;
+
+#ifdef TEST_64
+typedef long long int64_t;
+typedef int64_t intptr_t;
+#else
+typedef int int32_t;
+typedef int32_t intptr_t;
+#endif
+
+//---------------------------------------------------------------------------
+// Test case 'checkaccess_union' differs for region store and basic store.
+// The basic store doesn't reason about compound literals, so the code
+// below won't fire an "uninitialized value" warning.
+//---------------------------------------------------------------------------
+
+// PR 2948 (testcase; crash on VisitLValue for union types)
+// http://llvm.org/bugs/show_bug.cgi?id=2948
+void checkaccess_union() {
+  int ret = 0, status;
+  // Since RegionStore doesn't handle unions yet,
+  // this branch condition won't be triggered
+  // as involving an uninitialized value.  
+  if (((((__extension__ (((union {  // no-warning
+    __typeof (status) __in; int __i;}
+    )
+    {
+      .__in = (status)}
+      ).__i))) & 0xff00) >> 8) == 1)
+        ret = 1;
+}
+
+// Check our handling of fields being invalidated by function calls.
+struct test2_struct { int x; int y; char* s; };
+void test2_help(struct test2_struct* p);
+
+char test2() {
+  struct test2_struct s;
+  test2_help(&s);
+  char *p = 0;
+  
+  if (s.x > 1) {
+    if (s.s != 0) {
+      p = "hello";
+    }
+  }
+  
+  if (s.x > 1) {
+    if (s.s != 0) {
+      return *p;
+    }
+  }
+
+  return 'a';
+}
+
+// BasicStore handles this case incorrectly because it doesn't reason about
+// the value pointed to by 'x' and thus creates different symbolic values
+// at the declarations of 'a' and 'b' respectively.  RegionStore handles
+// it correctly. See the companion test in 'misc-ps-basic-store.m'.
+void test_trivial_symbolic_comparison_pointer_parameter(int *x) {
+  int a = *x;
+  int b = *x;
+  if (a != b) {
+    int *p = 0;
+    *p = 0xDEADBEEF;     // no-warning
+  }
+}
+
+// This is a modified test from 'misc-ps.m'.  Here we have the extra
+// NULL dereferences which are pruned out by RegionStore's symbolic reasoning
+// of fields.
+typedef struct _BStruct { void *grue; } BStruct;
+void testB_aux(void *ptr);
+
+void testB(BStruct *b) {
+  {
+    int *__gruep__ = ((int *)&((b)->grue));
+    int __gruev__ = *__gruep__;
+    int __gruev2__ = *__gruep__;
+    if (__gruev__ != __gruev2__) {
+      int *p = 0;
+      *p = 0xDEADBEEF; // no-warning
+    }
+
+    testB_aux(__gruep__);
+  }
+  {
+    int *__gruep__ = ((int *)&((b)->grue));
+    int __gruev__ = *__gruep__;
+    int __gruev2__ = *__gruep__;
+    if (__gruev__ != __gruev2__) {
+      int *p = 0;
+      *p = 0xDEADBEEF; // no-warning
+    }
+
+    if (~0 != __gruev__) {}
+  }
+}
+
+void testB_2(BStruct *b) {
+  {
+    int **__gruep__ = ((int **)&((b)->grue));
+    int *__gruev__ = *__gruep__;
+    testB_aux(__gruep__);
+  }
+  {
+    int **__gruep__ = ((int **)&((b)->grue));
+    int *__gruev__ = *__gruep__;
+    if ((int*)~0 != __gruev__) {}
+  }
+}
+
+// This test case is a reduced case of a caching bug discovered by an
+// assertion failure in RegionStoreManager::BindArray.  Essentially the
+// DeclStmt is evaluated twice, but on the second loop iteration the
+// engine caches out.  Previously a false transition would cause UnknownVal
+// to bind to the variable, firing an assertion failure.  This bug was fixed
+// in r76262.
+void test_declstmt_caching() {
+again:
+  {
+    const char a[] = "I like to crash";
+    goto again;
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// Reduced test case from <rdar://problem/7114618>.
+// Basically a null check is performed on the field value, which is then
+// assigned to a variable and then checked again.
+//===----------------------------------------------------------------------===//
+struct s_7114618 { int *p; };
+void test_rdar_7114618(struct s_7114618 *s) {
+  if (s->p) {
+    int *p = s->p;
+    if (!p) {
+      // Infeasible
+      int *dead = 0;
+      *dead = 0xDEADBEEF; // no-warning
+    }
+  }
+}
+
+// Test pointers increment correctly.
+void f() {
+  int a[2];
+  a[1] = 3;
+  int *p = a;
+  p++;
+  if (*p != 3) {
+    int *q = 0;
+    *q = 3; // no-warning
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/7185607>
+// Bit-fields of a struct should be invalidated when blasting the entire
+// struct with an integer constant.
+//===----------------------------------------------------------------------===//
+struct test_7185607 {
+  int x : 10;
+  int y : 22;
+};
+int rdar_test_7185607() {
+  struct test_7185607 s; // Uninitialized.
+  *((unsigned *) &s) = 0U;
+  return s.x; // no-warning
+}
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/7242006> [RegionStore] compound literal assignment with
+//  floats not honored
+// This test case is mirrored in misc-ps.m, but this case is a negative.
+//===----------------------------------------------------------------------===//
+typedef float CGFloat;
+typedef struct _NSSize {
+    CGFloat width;
+    CGFloat height;
+} NSSize;
+
+CGFloat rdar7242006_negative(CGFloat x) {
+  NSSize y;
+  return y.width; // expected-warning{{garbage}}
+}
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/7249340> - Allow binding of values to symbolic regions.
+// This test case shows how RegionStore tracks the value bound to 'x'
+// after the assignment.
+//===----------------------------------------------------------------------===//
+typedef int* ptr_rdar_7249340;
+void rdar_7249340(ptr_rdar_7249340 x) {
+  *x = 1;
+  if (*x)
+    return;
+  int *p = 0;   // This is unreachable.
+  *p = 0xDEADBEEF; // no-warning
+}
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/7249327> - This test case tests both value tracking of
+// array values and that we handle symbolic values that are casted
+// between different integer types.  Note the assignment 'n = *a++'; here
+// 'n' is and 'int' and '*a' is 'unsigned'.  Previously we got a false positive
+// at 'x += *b++' (undefined value) because we got a false path.
+//===----------------------------------------------------------------------===//
+int rdar_7249327_aux(void);
+
+void rdar_7249327(unsigned int A[2*32]) {
+  int B[2*32];
+  int *b;
+  unsigned int *a;
+  int x = 0;
+  
+  int n;
+  
+  a = A;
+  b = B;
+  
+  n = *a++;
+  if (n)
+    *b++ = rdar_7249327_aux();
+
+  a = A;
+  b = B;
+  
+  n = *a++;
+  if (n)
+    x += *b++; // no-warning
+}
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/6914474> - Check that 'x' is invalidated because its
+// address is passed in as a value to a struct.
+//===----------------------------------------------------------------------===//
+struct doodad_6914474 { int *v; };
+extern void prod_6914474(struct doodad_6914474 *d);
+int rdar_6914474(void) {
+  int x;
+  struct doodad_6914474 d;
+  d.v = &x;
+  prod_6914474(&d);
+  return x; // no-warning
+}
+
+// Test invalidation of a single field.
+struct s_test_field_invalidate {
+  int x;
+};
+extern void test_invalidate_field(int *x);
+int test_invalidate_field_test() {
+  struct s_test_field_invalidate y;
+  test_invalidate_field(&y.x);
+  return y.x; // no-warning
+}
+int test_invalidate_field_test_positive() {
+  struct s_test_field_invalidate y;
+  return y.x; // expected-warning{{garbage}}
+}
+
+// This test case illustrates how a typeless array of bytes casted to a
+// struct should be treated as initialized.  RemoveDeadBindings previously
+// had a bug that caused 'x' to lose its default symbolic value after the
+// assignment to 'p', thus causing 'p->z' to evaluate to "undefined".
+struct ArrayWrapper { unsigned char y[16]; };
+struct WrappedStruct { unsigned z; };
+
+int test_handle_array_wrapper() {
+  struct ArrayWrapper x;
+  test_handle_array_wrapper(&x);
+  struct WrappedStruct *p = (struct WrappedStruct*) x.y; // expected-warning{{Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption.}}
+  return p->z;  // no-warning
+}
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/7261075> [RegionStore] crash when 
+//   handling load: '*((unsigned int *)"????")'
+//===----------------------------------------------------------------------===//
+
+int rdar_7261075(void) {
+  unsigned int var = 0;
+  if (var == *((unsigned int *)"????"))
+    return 1;
+  return 0;
+}
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/7275774> false path due to limited pointer 
+//                          arithmetic constraints
+//===----------------------------------------------------------------------===//
+
+void rdar_7275774(void *data, unsigned n) {
+  if (!(data || n == 0))
+    return;
+  
+  unsigned short *p = (unsigned short*) data;
+  unsigned short *q = p + (n / 2);
+
+  if (p < q) {
+    // If we reach here, 'p' cannot be null.  If 'p' is null, then 'n' must
+    // be '0', meaning that this branch is not feasible.
+    *p = *q; // no-warning
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/7312221>
+//
+//  Test that Objective-C instance variables aren't prematurely pruned
+//  from the analysis state.
+//===----------------------------------------------------------------------===//
+
+struct rdar_7312221_value { int x; };
+
+@interface RDar7312221
+{
+  struct rdar_7312221_value *y;
+}
+- (void) doSomething_7312221;
+@end
+
+extern struct rdar_7312221_value *rdar_7312221_helper();
+extern int rdar_7312221_helper_2(id o);
+extern void rdar_7312221_helper_3(int z);
+
+@implementation RDar7312221
+- (void) doSomething_7312221 {
+  if (y == 0) {
+    y = rdar_7312221_helper();
+    if (y != 0) {
+      y->x = rdar_7312221_helper_2(self);
+      // The following use of 'y->x' previously triggered a null dereference, as the value of 'y'
+      // before 'y = rdar_7312221_helper()' would be used.
+      rdar_7312221_helper_3(y->x); // no-warning
+    }
+  }
+}
+@end
+
+struct rdar_7312221_container {
+  struct rdar_7312221_value *y;
+};
+
+extern int rdar_7312221_helper_4(struct rdar_7312221_container *s);
+
+// This test case essentially matches the one in [RDar7312221 doSomething_7312221].
+void doSomething_7312221_with_struct(struct rdar_7312221_container *Self) {
+  if (Self->y == 0) {
+    Self->y = rdar_7312221_helper();
+    if (Self->y != 0) {
+      Self->y->x = rdar_7312221_helper_4(Self);
+      rdar_7312221_helper_3(Self->y->x); // no-warning
+    }
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/7332673> - Just more tests cases for regions
+//===----------------------------------------------------------------------===//
+
+void rdar_7332673_test1() {
+    char value[1];
+    if ( *(value) != 1 ) {} // expected-warning{{The left operand of '!=' is a garbage value}}
+}
+int rdar_7332673_test2_aux(char *x);
+void rdar_7332673_test2() {
+    char *value;
+    if ( rdar_7332673_test2_aux(value) != 1 ) {} // expected-warning{{Pass-by-value argument in function call is undefined}}
+}
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/7347252>: Because of a bug in
+//   RegionStoreManager::RemoveDeadBindings(), the symbol for s->session->p
+//   would incorrectly be pruned from the state after the call to
+//   rdar7347252_malloc1(), and would incorrectly result in a warning about
+//   passing a null pointer to rdar7347252_memcpy().
+//===----------------------------------------------------------------------===//
+
+struct rdar7347252_AA { char *p;};
+typedef struct {
+ struct rdar7347252_AA *session;
+ int t;
+ char *q;
+} rdar7347252_SSL1;
+
+int rdar7347252_f(rdar7347252_SSL1 *s);
+char *rdar7347252_malloc1(int);
+char *rdar7347252_memcpy1(char *d, char *s, int n) __attribute__((nonnull (1,2)));
+
+int rdar7347252(rdar7347252_SSL1 *s) {
+ rdar7347252_f(s);  // the SymbolicRegion of 's' is set a default binding of conjured symbol
+ if (s->session->p == ((void*)0)) {
+   if ((s->session->p = rdar7347252_malloc1(10)) == ((void*)0)) {
+     return 0;
+   }
+   rdar7347252_memcpy1(s->session->p, "aa", 2); // no-warning
+ }
+ return 0;
+}
+
+//===----------------------------------------------------------------------===//
+// PR 5316 - "crash when accessing field of lazy compound value"
+//  Previously this caused a crash at the MemberExpr '.chr' when loading
+//  a field value from a LazyCompoundVal
+//===----------------------------------------------------------------------===//
+
+typedef unsigned int pr5316_wint_t;
+typedef pr5316_wint_t pr5316_REFRESH_CHAR;
+typedef struct {
+  pr5316_REFRESH_CHAR chr;
+}
+pr5316_REFRESH_ELEMENT;
+static void pr5316(pr5316_REFRESH_ELEMENT *dst, const pr5316_REFRESH_ELEMENT *src) {
+  while ((*dst++ = *src++).chr != L'\0')  ;
+}
+
+//===----------------------------------------------------------------------===//
+// Exercise creating ElementRegion with symbolic super region.
+//===----------------------------------------------------------------------===//
+void element_region_with_symbolic_superregion(int* p) {
+  int *x;
+  int a;
+  if (p[0] == 1)
+    x = &a;
+  if (p[0] == 1)
+    (void)*x; // no-warning
+}
+
+//===----------------------------------------------------------------------===//
+// Test returning an out-of-bounds pointer (CWE-466)
+//===----------------------------------------------------------------------===//
+
+static int test_cwe466_return_outofbounds_pointer_a[10];
+int *test_cwe466_return_outofbounds_pointer() {
+  int *p = test_cwe466_return_outofbounds_pointer_a+10;
+  return p; // expected-warning{{Returned pointer value points outside the original object}}
+}
+
+//===----------------------------------------------------------------------===//
+// PR 3135 - Test case that shows that a variable may get invalidated when its
+// address is included in a structure that is passed-by-value to an unknown function.
+//===----------------------------------------------------------------------===//
+
+typedef struct { int *a; } pr3135_structure;
+int pr3135_bar(pr3135_structure *x);
+int pr3135() {
+  int x;
+  pr3135_structure y = { &x };
+  // the call to pr3135_bar may initialize x
+  if (pr3135_bar(&y) && x) // no-warning
+    return 1;
+  return 0;
+}
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/7403269> - Test that we handle compound initializers with
+// partially unspecified array values. Previously this caused a crash.
+//===----------------------------------------------------------------------===//
+
+typedef struct RDar7403269 {
+  unsigned x[10];
+  unsigned y;
+} RDar7403269;
+
+void rdar7403269() {
+  RDar7403269 z = { .y = 0 };
+  if (z.x[4] == 0)
+    return;
+  int *p = 0;
+  *p = 0xDEADBEEF; // no-warning  
+}
+
+typedef struct RDar7403269_b {
+  struct zorg { int w; int k; } x[10];
+  unsigned y;
+} RDar7403269_b;
+
+void rdar7403269_b() {
+  RDar7403269_b z = { .y = 0 };
+  if (z.x[5].w == 0)
+    return;
+  int *p = 0;
+  *p = 0xDEADBEEF; // no-warning
+}
+
+void rdar7403269_b_pos() {
+  RDar7403269_b z = { .y = 0 };
+  if (z.x[5].w == 1)
+    return;
+  int *p = 0;
+  *p = 0xDEADBEEF; // expected-warning{{Dereference of null pointer}}
+}
+
+
+//===----------------------------------------------------------------------===//
+// Test that incrementing a non-null pointer results in a non-null pointer.
+// (<rdar://problem/7191542>)
+//===----------------------------------------------------------------------===//
+
+void test_increment_nonnull_rdar_7191542(const char *path) {
+  const char *alf = 0;
+  
+  for (;;) {
+    // When using basic-store, we get a null dereference here because we lose information
+    // about path after the pointer increment.
+    char c = *path++; // no-warning
+    if (c == 'a') {
+      alf = path;
+    }
+    
+    if (alf)
+      return;
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// Test that the store (implicitly) tracks values for doubles/floats that are
+// uninitialized (<rdar://problem/6811085>)
+//===----------------------------------------------------------------------===//
+
+double rdar_6811085(void) {
+  double u;
+  return u + 10; // expected-warning{{The left operand of '+' is a garbage value}}
+}
+
+//===----------------------------------------------------------------------===//
+// Path-sensitive tests for blocks.
+//===----------------------------------------------------------------------===//
+
+void indirect_block_call(void (^f)());
+
+int blocks_1(int *p, int z) {
+  __block int *q = 0;
+  void (^bar)() = ^{ q = p; };
+  
+  if (z == 1) {
+    // The call to 'bar' might cause 'q' to be invalidated.
+    bar();
+    *q = 0x1; // no-warning
+  }
+  else if (z == 2) {
+    // The function 'indirect_block_call' might invoke bar, thus causing
+    // 'q' to possibly be invalidated.
+    indirect_block_call(bar);
+    *q = 0x1; // no-warning
+  }
+  else {
+    *q = 0xDEADBEEF; // expected-warning{{Dereference of null pointer}}
+  }
+  return z;
+}
+
+int blocks_2(int *p, int z) {
+  int *q = 0;
+  void (^bar)(int **) = ^(int **r){ *r = p; };
+  
+  if (z) {
+    // The call to 'bar' might cause 'q' to be invalidated.
+    bar(&q);
+    *q = 0x1; // no-warning
+  }
+  else {
+    *q = 0xDEADBEEF; // expected-warning{{Dereference of null pointer}}
+  }
+  return z;
+}
+
+// Test that the value of 'x' is considered invalidated after the block
+// is passed as an argument to the message expression.
+typedef void (^RDar7582031CB)(void);
+@interface RDar7582031
+- rdar7582031:RDar7582031CB;
+- rdar7582031_b:RDar7582031CB;
+@end
+
+// Test with one block.
+unsigned rdar7582031(RDar7582031 *o) {
+  __block unsigned x;
+  [o rdar7582031:^{ x = 1; }];
+  return x; // no-warning
+}
+
+// Test with two blocks.
+unsigned long rdar7582031_b(RDar7582031 *o) {
+  __block unsigned y;
+  __block unsigned long x;
+  [o rdar7582031:^{ y = 1; }];
+  [o rdar7582031_b:^{ x = 1LL; }];
+  return x + (unsigned long) y; // no-warning
+}
+
+// Show we get an error when 'o' is null because the message
+// expression has no effect.
+unsigned long rdar7582031_b2(RDar7582031 *o) {
+  __block unsigned y;
+  __block unsigned long x;
+  if (o)
+    return 1;
+  [o rdar7582031:^{ y = 1; }];
+  [o rdar7582031_b:^{ x = 1LL; }];
+  return x + (unsigned long) y; // expected-warning{{The left operand of '+' is a garbage value}}
+}
+
+// Show that we handle static variables also getting invalidated.
+void rdar7582031_aux(void (^)(void));
+RDar7582031 *rdar7582031_aux_2();
+
+unsigned rdar7582031_static() {  
+  static RDar7582031 *o = 0;
+  rdar7582031_aux(^{ o = rdar7582031_aux_2(); });
+  
+  __block unsigned x;
+  [o rdar7582031:^{ x = 1; }];
+  return x; // no-warning
+}
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/7462324> - Test that variables passed using __blocks
+//  are not treated as being uninitialized.
+//===----------------------------------------------------------------------===//
+
+typedef void (^RDar_7462324_Callback)(id obj);
+
+@interface RDar7462324
+- (void) foo:(id)target;
+- (void) foo_positive:(id)target;
+
+@end
+
+@implementation RDar7462324
+- (void) foo:(id)target {
+  __block RDar_7462324_Callback builder = ((void*) 0);
+  builder = ^(id object) {
+    if (object) {
+      builder(self); // no-warning
+    }
+  };
+  builder(target);
+}
+- (void) foo_positive:(id)target {
+  __block RDar_7462324_Callback builder = ((void*) 0);
+  builder = ^(id object) {
+    id x;
+    if (object) {
+      builder(x); // expected-warning{{Pass-by-value argument in function call is undefined}}
+    }
+  };
+  builder(target);
+}
+@end
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/7468209> - Scanning for live variables within a block should
+//  not crash on variables passed by reference via __block.
+//===----------------------------------------------------------------------===//
+
+int rdar7468209_aux();
+void rdar7468209_aux_2();
+
+void rdar7468209() {
+  __block int x = 0;
+  ^{
+    x = rdar7468209_aux();
+    // We need a second statement so that 'x' would be removed from the store if it wasn't
+    // passed by reference.
+    rdar7468209_aux_2();
+  }();
+}
+
+//===----------------------------------------------------------------------===//
+// PR 5857 - Test loading an integer from a byte array that has also been
+//  reinterpreted to be loaded as a field.
+//===----------------------------------------------------------------------===//
+
+typedef struct { int x; } TestFieldLoad;
+int pr5857(char *src) {
+  TestFieldLoad *tfl = (TestFieldLoad *) (intptr_t) src;
+  int y = tfl->x;
+  long long *z = (long long *) (intptr_t) src;
+  long long w = 0;
+  int n = 0;
+  for (n = 0; n < y; ++n) {
+    // Previously we crashed analyzing this statement.
+    w = *z++;
+  }
+  return 1;
+}
+
+//===----------------------------------------------------------------------===//
+// PR 4358 - Without field-sensitivity, this code previously triggered
+//  a false positive that 'uninit' could be uninitialized at the call
+//  to pr4358_aux().
+//===----------------------------------------------------------------------===//
+
+struct pr4358 {
+  int bar;
+  int baz;
+};
+void pr4358_aux(int x);
+void pr4358(struct pr4358 *pnt) {
+  int uninit;
+  if (pnt->bar < 3) {
+    uninit = 1;
+  } else if (pnt->baz > 2) {
+    uninit = 3;
+  } else if (pnt->baz <= 2) {
+    uninit = 2;
+  }
+  pr4358_aux(uninit); // no-warning
+}
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/7526777>
+// Test handling fields of values returned from function calls or
+// message expressions.
+//===----------------------------------------------------------------------===//
+
+typedef struct testReturn_rdar_7526777 {
+  int x;
+  int y;
+} testReturn_rdar_7526777;
+
+@interface TestReturnStruct_rdar_7526777
+- (testReturn_rdar_7526777) foo;
+@end
+
+int test_return_struct(TestReturnStruct_rdar_7526777 *x) {
+  return [x foo].x;
+}
+
+testReturn_rdar_7526777 test_return_struct_2_aux_rdar_7526777();
+
+int test_return_struct_2_rdar_7526777() {
+  return test_return_struct_2_aux_rdar_7526777().x;
+}
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/7527292> Assertion failed: (Op == BinaryOperator::Add || 
+//                                             Op == BinaryOperator::Sub)
+// This test case previously triggered an assertion failure due to a discrepancy
+// been the loaded/stored value in the array
+//===----------------------------------------------------------------------===//
+
+_Bool OSAtomicCompareAndSwapPtrBarrier( void *__oldValue, void *__newValue, void * volatile *__theValue );
+
+void rdar_7527292() {
+  static id Cache7527292[32];
+  for (signed long idx = 0;
+       idx < 32;
+       idx++) {
+    id v = Cache7527292[idx];
+    if (v && OSAtomicCompareAndSwapPtrBarrier(v, ((void*)0), (void * volatile *)(Cache7527292 + idx))) { 
+    }
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/7515938> - Handle initialization of incomplete arrays
+//  in structures using a compound value.  Previously this crashed.
+//===----------------------------------------------------------------------===//
+
+struct rdar_7515938 {
+  int x;
+  int y[];
+};
+
+const struct rdar_7515938 *rdar_7515938() {
+  static const struct rdar_7515938 z = { 0, { 1, 2 } };
+  if (z.y[0] != 1) {
+    int *p = 0;
+    *p = 0xDEADBEEF; // no-warning
+  }
+  return &z;
+}
+
+struct rdar_7515938_str {
+  int x;
+  char y[];
+};
+
+const struct rdar_7515938_str *rdar_7515938_str() {
+  static const struct rdar_7515938_str z = { 0, "hello" };
+  return &z;
+}
+
+//===----------------------------------------------------------------------===//
+// Assorted test cases from PR 4172.
+//===----------------------------------------------------------------------===//
+
+struct PR4172A_s { int *a; };
+
+void PR4172A_f2(struct PR4172A_s *p);
+
+int PR4172A_f1(void) {
+    struct PR4172A_s m;
+    int b[4];
+    m.a = b;
+    PR4172A_f2(&m);
+    return b[3]; // no-warning
+}
+
+struct PR4172B_s { int *a; };
+
+void PR4172B_f2(struct PR4172B_s *p);
+
+int PR4172B_f1(void) {
+    struct PR4172B_s m;
+    int x;
+    m.a = &x;
+    PR4172B_f2(&m);
+    return x; // no-warning
+}
+
+//===----------------------------------------------------------------------===//
+// Test invalidation of values in struct literals.
+//===----------------------------------------------------------------------===//
+
+struct s_rev96062 { int *x; int *y; };
+struct s_rev96062_nested { struct s_rev96062 z; };
+
+void test_a_rev96062_aux(struct s_rev96062 *s);
+void test_a_rev96062_aux2(struct s_rev96062_nested *s);
+
+int test_a_rev96062() {
+  int a, b;
+  struct s_rev96062 x = { &a, &b };
+  test_a_rev96062_aux(&x);
+  return a + b; // no-warning
+}
+int test_b_rev96062() {
+  int a, b;
+  struct s_rev96062 x = { &a, &b };
+  struct s_rev96062 z = x;
+  test_a_rev96062_aux(&z);
+  return a + b; // no-warning
+}
+int test_c_rev96062() {
+  int a, b;
+  struct s_rev96062 x = { &a, &b };
+  struct s_rev96062_nested w = { x };
+  struct s_rev96062_nested z = w;
+  test_a_rev96062_aux2(&z);
+  return a + b; // no-warning
+}
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/7242010> - The access to y[0] at the bottom previously
+//  was reported as an uninitialized value.
+//===----------------------------------------------------------------------===//
+
+char *rdar_7242010(int count, char **y) {
+  char **x = alloca((count + 4) * sizeof(*x));
+  x[0] = "hi";
+  x[1] = "there";
+  x[2] = "every";
+  x[3] = "body";
+  memcpy(x + 4, y, count * sizeof(*x));
+  y = x;
+  return y[0]; // no-warning
+}
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/7770737>
+//===----------------------------------------------------------------------===//
+
+struct rdar_7770737_s { intptr_t p; };
+void rdar_7770737_aux(struct rdar_7770737_s *p);
+int rdar_7770737(void)
+{ 
+  int x;
+
+  // Previously 'f' was not properly invalidated, causing the use of
+  // an uninitailized value below.
+  struct rdar_7770737_s f = { .p = (intptr_t)&x };
+  rdar_7770737_aux(&f);
+  return x; // no-warning
+}
+int rdar_7770737_pos(void)
+{
+  int x;
+  struct rdar_7770737_s f = { .p = (intptr_t)&x };
+  return x; // expected-warning{{Undefined or garbage value returned to caller}}
+}
+
+//===----------------------------------------------------------------------===//
+// Test handling of the implicit 'isa' field.  For now we don't do anything
+// interesting.
+//===----------------------------------------------------------------------===//
+
+void pr6302(id x, Class y) {
+  // This previously crashed the analyzer (reported in PR 6302)
+  x->isa  = y;
+}
+
+//===----------------------------------------------------------------------===//
+// Specially handle global variables that are declared constant.  In the
+// example below, this forces the loop to take exactly 2 iterations.
+//===----------------------------------------------------------------------===//
+
+const int pr6288_L_N = 2;
+void pr6288_(void) {
+  int x[2];
+  int *px[2];
+  int i;
+  for (i = 0; i < pr6288_L_N; i++)
+    px[i] = &x[i];
+  *(px[0]) = 0; // no-warning
+}
+
+void pr6288_pos(int z) {
+  int x[2];
+  int *px[2];
+  int i;
+  for (i = 0; i < z; i++)
+    px[i] = &x[i]; // expected-warning{{Access out-of-bound array element (buffer overflow)}}
+  *(px[0]) = 0; // expected-warning{{Dereference of undefined pointer value}}
+}
+
+void pr6288_b(void) {
+  const int L_N = 2;
+  int x[2];
+  int *px[2];
+  int i;
+  for (i = 0; i < L_N; i++)
+    px[i] = &x[i];
+  *(px[0]) = 0; // no-warning
+}
+
+// <rdar://problem/7817800> - A bug in RemoveDeadBindings was causing instance variable bindings
+//  to get prematurely pruned from the state.
+@interface Rdar7817800 {
+  char *x;
+}
+- (void) rdar7817800_baz;
+@end
+
+char *rdar7817800_foobar();
+void rdar7817800_qux(void*);
+
+@implementation Rdar7817800
+- (void) rdar7817800_baz {
+  if (x)
+    rdar7817800_qux(x);
+  x = rdar7817800_foobar();
+  // Previously this triggered a bogus null dereference warning.
+  x[1] = 'a'; // no-warning
+}
+@end
+
+// PR 6036 - This test case triggered a crash inside StoreManager::CastRegion because the size
+// of 'unsigned long (*)[0]' is 0.
+struct pr6036_a { int pr6036_b; };
+struct pr6036_c;
+void u132monitk (struct pr6036_c *pr6036_d) {
+  (void) ((struct pr6036_a *) (unsigned long (*)[0]) ((char *) pr6036_d - 1))->pr6036_b; // expected-warning{{Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption}}
+}
+
+// <rdar://problem/7813989> - ?-expressions used as a base of a member expression should be treated as an lvalue
+typedef struct rdar7813989_NestedVal { int w; } rdar7813989_NestedVal;
+typedef struct rdar7813989_Val { rdar7813989_NestedVal nv; } rdar7813989_Val;
+
+int rdar7813989(int x, rdar7813989_Val *a, rdar7813989_Val *b) {
+  // This previously crashed with an assertion failure.
+  int z = (x ? a->nv : b->nv).w;
+  return z + 1;
+}
+
+// PR 6844 - Don't crash on vaarg expression.
+typedef __builtin_va_list va_list;
+void map(int srcID, ...) {
+  va_list ap;
+  int i;
+  for (i = 0; i < srcID; i++) {
+    int v = __builtin_va_arg(ap, int);
+  }
+}
+
+// PR 6854 - crash when casting symbolic memory address to a float
+// Handle casting from a symbolic region to a 'float'.  This isn't
+// really all that intelligent, but previously this caused a crash
+// in SimpleSValuator.
+void pr6854(void * arg) {
+  void * a = arg;
+  *(void**)a = arg;
+  float f = *(float*) a;
+}
+
diff --git a/test/Analysis/misc-ps-region-store.mm b/test/Analysis/misc-ps-region-store.mm
new file mode 100644
index 0000000..92addd1
--- /dev/null
+++ b/test/Analysis/misc-ps-region-store.mm
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -verify -fblocks   -analyzer-opt-analyze-nested-blocks %s
+
+//===------------------------------------------------------------------------------------------===//
+// This files tests our path-sensitive handling of Objective-c++ files.
+//===------------------------------------------------------------------------------------------===//
+
+// Test basic handling of references.
+char &test1_aux();
+char *test1() {
+  return &test1_aux();
+}
+
+// Test test1_aux() evaluates to char &.
+char test1_as_rvalue() {
+  return test1_aux();
+}
+
+// Test basic handling of references with Objective-C classes.
+@interface Test1
+- (char&) foo;
+@end
+
+char* Test1_harness(Test1 *p) {
+  return &[p foo];
+}
+
+char Test1_harness_b(Test1 *p) {
+  return [p foo];
+}
+
diff --git a/test/Analysis/misc-ps.m b/test/Analysis/misc-ps.m
new file mode 100644
index 0000000..fa05f6f
--- /dev/null
+++ b/test/Analysis/misc-ps.m
@@ -0,0 +1,935 @@
+// NOTE: Use '-fobjc-gc' to test the analysis being run twice, and multiple reports are not issued.
+// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -fobjc-gc -analyzer-constraints=basic -verify -fblocks -Wno-unreachable-code %s
+// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=range -verify -fblocks -Wno-unreachable-code %s
+// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=basic -verify -fblocks -Wno-unreachable-code %s
+// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -verify -fblocks -Wno-unreachable-code %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -fobjc-gc -analyzer-constraints=basic -verify -fblocks -Wno-unreachable-code %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=range -verify -fblocks -Wno-unreachable-code %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=basic -verify -fblocks -Wno-unreachable-code %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -verify -fblocks -Wno-unreachable-code %s
+
+typedef struct objc_ivar *Ivar;
+typedef struct objc_selector *SEL;
+typedef signed char BOOL;
+typedef int NSInteger;
+typedef unsigned int NSUInteger;
+typedef struct _NSZone NSZone;
+@class NSInvocation, NSArray, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+@protocol NSObject
+- (BOOL)isEqual:(id)object;
+- (id)autorelease;
+@end
+@protocol NSCopying
+- (id)copyWithZone:(NSZone *)zone;
+@end
+@protocol NSMutableCopying  - (id)mutableCopyWithZone:(NSZone *)zone; @end
+@protocol NSCoding
+- (void)encodeWithCoder:(NSCoder *)aCoder;
+@end
+@interface NSObject <NSObject> {}
+- (id)init;
++ (id)allocWithZone:(NSZone *)zone;
+@end
+extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone);
+@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding>
+- (NSUInteger)length;
++ (id)stringWithUTF8String:(const char *)nullTerminatedCString;
+@end extern NSString * const NSBundleDidLoadNotification;
+@interface NSValue : NSObject <NSCopying, NSCoding>
+- (void)getValue:(void *)value;
+@end
+@interface NSNumber : NSValue
+- (char)charValue;
+- (id)initWithBool:(BOOL)value;
+@end
+@interface NSAssertionHandler : NSObject {}
++ (NSAssertionHandler *)currentHandler;
+- (void)handleFailureInMethod:(SEL)selector object:(id)object file:(NSString *)fileName lineNumber:(NSInteger)line description:(NSString *)format,...;
+@end
+extern NSString * const NSConnectionReplyMode;
+typedef float CGFloat;
+typedef struct _NSPoint {
+    CGFloat x;
+    CGFloat y;
+} NSPoint;
+typedef struct _NSSize {
+    CGFloat width;
+    CGFloat height;
+} NSSize;
+typedef struct _NSRect {
+    NSPoint origin;
+    NSSize size;
+} NSRect;
+
+// Reduced test case from crash in <rdar://problem/6253157>
+@interface A @end
+@implementation A
+- (void)foo:(void (^)(NSObject *x))block {
+  if (!((block != ((void *)0)))) {}
+}
+@end
+
+// Reduced test case from crash in PR 2796;
+//  http://llvm.org/bugs/show_bug.cgi?id=2796
+
+unsigned foo(unsigned x) { return __alignof__((x)) + sizeof(x); }
+
+// Improvement to path-sensitivity involving compound assignments.
+//  Addresses false positive in <rdar://problem/6268365>
+//
+
+unsigned r6268365Aux();
+
+void r6268365() {
+  unsigned x = 0;
+  x &= r6268365Aux();
+  unsigned j = 0;
+    
+  if (x == 0) ++j;
+  if (x == 0) x = x / j; // no-warning
+}
+
+void divzeroassume(unsigned x, unsigned j) {  
+  x /= j;  
+  if (j == 0) x /= 0;     // no static-analyzer warning    expected-warning {{division by zero is undefined}}
+  if (j == 0) x /= j;     // no static-analyzer warning
+  if (j == 0) x = x / 0;  // no static-analyzer warning    expected-warning {{division by zero is undefined}}
+}
+
+void divzeroassumeB(unsigned x, unsigned j) {  
+  x = x / j;  
+  if (j == 0) x /= 0;     // no static-analyzer warning     expected-warning {{division by zero is undefined}}
+  if (j == 0) x /= j;     // no static-analyzer warning
+  if (j == 0) x = x / 0;  // no static-analyzer warning     expected-warning {{division by zero is undefined}}
+}
+
+// InitListExpr processing
+
+typedef float __m128 __attribute__((__vector_size__(16), __may_alias__));
+__m128 return128() {
+  // This compound literal has a Vector type.  We currently just
+  // return UnknownVal.
+  return __extension__(__m128) { 0.0f, 0.0f, 0.0f, 0.0f };
+}
+
+typedef long long __v2di __attribute__ ((__vector_size__ (16)));
+typedef long long __m128i __attribute__ ((__vector_size__ (16), __may_alias__));
+__m128i vec128i(long long __q1, long long __q0) {
+  // This compound literal returns true for both isVectorType() and 
+  // isIntegerType().
+  return __extension__ (__m128i)(__v2di){ __q0, __q1 };
+}
+
+// Zero-sized VLAs.
+void check_zero_sized_VLA(int x) {
+  if (x)
+    return;
+
+  int vla[x]; // expected-warning{{Declared variable-length array (VLA) has zero size}}
+}
+
+void check_uninit_sized_VLA() {
+  int x;
+  int vla[x]; // expected-warning{{Declared variable-length array (VLA) uses a garbage value as its size}}
+}
+
+// sizeof(void)
+// - Tests a regression reported in PR 3211: http://llvm.org/bugs/show_bug.cgi?id=3211
+void handle_sizeof_void(unsigned flag) {
+  int* p = 0;
+
+  if (flag) {
+    if (sizeof(void) == 1)
+      return;
+    // Infeasible.
+    *p = 1; // no-warning
+  }
+  
+  void* q;
+  
+  if (!flag) {
+    if (sizeof(*q) == 1)
+      return;
+    // Infeasibe.
+    *p = 1; // no-warning
+  }
+    
+  // Infeasible.
+  *p = 1; // no-warning
+}
+
+// check deference of undefined values
+void check_deref_undef(void) {
+  int *p;
+  *p = 0xDEADBEEF; // expected-warning{{Dereference of undefined pointer value}}
+}
+
+// PR 3422
+void pr3422_helper(char *p);
+void pr3422() {
+  char buf[100];
+  char *q = &buf[10];
+  pr3422_helper(&q[1]);
+}
+
+// PR 3543 (handle empty statement expressions)
+void pr_3543(void) {
+  ({});
+}
+
+// <rdar://problem/6611677>
+// This test case test the use of a vector type within an array subscript
+// expression.
+typedef long long __a64vector __attribute__((__vector_size__(8)));
+typedef long long __a128vector __attribute__((__vector_size__(16)));
+static inline __a64vector __attribute__((__always_inline__, __nodebug__))  
+my_test_mm_movepi64_pi64(__a128vector a) {
+  return (__a64vector)a[0];
+}
+
+// Test basic tracking of ivars associated with 'self'.
+@interface SelfIvarTest : NSObject {
+  int flag;
+}
+- (void)test_self_tracking;
+@end
+
+@implementation SelfIvarTest
+- (void)test_self_tracking {
+  char *p = 0;
+  char c;
+
+  if (flag)
+    p = "hello";
+
+  if (flag)
+    c = *p; // no-warning
+}
+@end
+
+// PR 3770
+char pr3770(int x) {
+  int y = x & 0x2;
+  char *p = 0;
+  if (y == 1)
+    p = "hello";
+
+  if (y == 1)
+    return p[0]; // no-warning
+    
+  return 'a';
+}
+
+// PR 3772
+// - We just want to test that this doesn't crash the analyzer.
+typedef struct st ST;
+struct st { char *name; };
+extern ST *Cur_Pu;
+
+void pr3772(void)
+{
+  static ST *last_Cur_Pu;
+  if (last_Cur_Pu == Cur_Pu) {
+    return;
+  } 
+}
+
+// PR 3780 - This tests that StmtIterator isn't broken for VLAs in DeclGroups.
+void pr3780(int sz) { typedef double MAT[sz][sz]; }
+
+// <rdar://problem/6695527> - Test that we don't symbolicate doubles before
+// we are ready to do something with them.
+int rdar6695527(double x) {
+  if (!x) { return 0; }
+  return 1;
+}
+
+// <rdar://problem/6708148> - Test that we properly invalidate structs
+//  passed-by-reference to a function.
+void pr6708148_invalidate(NSRect *x);
+void pr6708148_use(NSRect x);
+void pr6708148_test(void) {
+  NSRect x;
+  pr6708148_invalidate(&x);
+  pr6708148_use(x); // no-warning
+}
+
+// Handle both kinds of noreturn attributes for pruning paths.
+void rdar_6777003_noret() __attribute__((noreturn));
+void rdar_6777003_analyzer_noret() __attribute__((analyzer_noreturn));
+
+void rdar_6777003(int x) {
+  int *p = 0;
+  
+  if (x == 1) {
+    rdar_6777003_noret();
+    *p = 1; // no-warning;    
+  }
+  
+  if (x == 2) {
+    rdar_6777003_analyzer_noret();
+    *p = 1; // no-warning;
+  }
+  
+  *p = 1; // expected-warning{{Dereference of null pointer}}  
+}
+
+// For pointer arithmetic, --/++ should be treated as preserving non-nullness,
+// regardless of how well the underlying StoreManager reasons about pointer
+// arithmetic.
+// <rdar://problem/6777209>
+void rdar_6777209(char *p) {
+  if (p == 0)
+    return;
+  
+  ++p;
+  
+  // This branch should always be infeasible.
+  if (p == 0)
+    *p = 'c'; // no-warning
+}
+
+// PR 4033.  A symbolic 'void *' pointer can be used as the address for a
+// computed goto.
+typedef void *Opcode;
+Opcode pr_4033_getOpcode();
+void pr_4033(void) {
+next_opcode:
+  {
+    Opcode op = pr_4033_getOpcode();
+    if (op) goto *op;
+  }
+}
+
+// Test invalidating pointers-to-pointers with slightly different types.  This
+// example came from a recent false positive due to a regression where the
+// branch condition was falsely reported as being uninitialized.
+void invalidate_by_ref(char **x);
+int test_invalidate_by_ref() {
+  unsigned short y;
+  invalidate_by_ref((char**) &y);
+  if (y) // no-warning
+    return 1;
+  return 0;  
+}
+
+// Test for <rdar://problem/7027684>.  This just tests that the CFG is
+// constructed correctly.  Previously, the successor block of the entrance
+// was the block containing the merge for '?', which would trigger an
+// assertion failure.
+int rdar_7027684_aux();
+int rdar_7027684_aux_2() __attribute__((noreturn));
+void rdar_7027684(int x, int y) {
+  {}; // this empty compound statement is critical.
+  (rdar_7027684_aux() ? rdar_7027684_aux_2() : (void) 0);
+}
+
+// Test that we handle casts of string literals to arbitrary types.
+unsigned const char *string_literal_test1() {
+  return (const unsigned char*) "hello";
+}
+
+const float *string_literal_test2() {
+  return (const float*) "hello";
+}
+
+// Test that we handle casts *from* incomplete struct types.
+extern const struct _FooAssertStruct _cmd;
+void test_cast_from_incomplete_struct_aux(volatile const void *x);
+void test_cast_from_incomplete_struct() {
+  test_cast_from_incomplete_struct_aux(&_cmd);
+}
+
+// Test for <rdar://problem/7034511> 
+//  "ValueManager::makeIntVal(uint64_t X, QualType T) should return a 'Loc' 
+//   when 'T' is a pointer"
+//
+// Previously this case would crash.
+void test_rdar_7034511(NSArray *y) {
+  NSObject *x;
+  for (x in y) {}
+  if (x == ((void*) 0)) {}
+}
+
+// Handle casts of function pointers (CodeTextRegions) to arbitrary pointer
+// types. This was previously causing a crash in CastRegion.
+void handle_funcptr_voidptr_casts() {
+  void **ptr;
+  typedef void *PVOID;
+  typedef void *PCHAR;  
+  typedef long INT_PTR, *PINT_PTR;
+  typedef INT_PTR (*FARPROC)();
+  FARPROC handle_funcptr_voidptr_casts_aux();
+  PVOID handle_funcptr_voidptr_casts_aux_2(PVOID volatile *x);
+  PVOID handle_funcptr_voidptr_casts_aux_3(PCHAR volatile *x);  
+  
+  ptr = (void**) handle_funcptr_voidptr_casts_aux();
+  handle_funcptr_voidptr_casts_aux_2(ptr);
+  handle_funcptr_voidptr_casts_aux_3(ptr);
+}
+
+// RegionStore::Retrieve previously crashed on this example.  This example
+// was previously in the test file 'xfail_regionstore_wine_crash.c'.
+void testA() {
+  long x = 0;
+  char *y = (char *) &x;
+  if (!*y)
+    return;
+}
+
+// RegionStoreManager previously crashed on this example.  The problem is that
+// the value bound to the field of b->grue after the call to testB_aux is
+// a symbolic region.  The second '*__gruep__' involves performing a load
+// from a 'int*' that really is a 'void**'.  The loaded location must be
+// implicitly converted to an integer that wraps a location.  Previosly we would
+// get a crash here due to an assertion failure.
+typedef struct _BStruct { void *grue; } BStruct;
+void testB_aux(void *ptr);
+void testB(BStruct *b) {
+  {
+    int *__gruep__ = ((int *)&((b)->grue));
+    int __gruev__ = *__gruep__;
+    testB_aux(__gruep__);
+  }
+  {
+    int *__gruep__ = ((int *)&((b)->grue));
+    int __gruev__ = *__gruep__;
+    if (~0 != __gruev__) {}
+  }
+}
+
+void test_trivial_symbolic_comparison(int *x) {
+  int test_trivial_symbolic_comparison_aux();
+  int a = test_trivial_symbolic_comparison_aux();
+  int b = a;
+  if (a != b) {
+    int *p = 0;
+    *p = 0xDEADBEEF;     // no-warning
+  }
+  
+  a = a == 1;
+  b = b == 1;
+  if (a != b) {
+    int *p = 0;
+    *p = 0xDEADBEEF;     // no-warning
+  }
+}
+
+// Test for:
+//  <rdar://problem/7062158> false positive null dereference due to
+//   BasicStoreManager not tracking *static* globals
+//
+// This just tests the proper tracking of symbolic values for globals (both 
+// static and non-static).
+//
+static int* x_rdar_7062158;
+void rdar_7062158() {
+  int *current = x_rdar_7062158;
+  if (current == x_rdar_7062158)
+    return;
+    
+  int *p = 0;
+  *p = 0xDEADBEEF; // no-warning  
+}
+
+int* x_rdar_7062158_2;
+void rdar_7062158_2() {
+  int *current = x_rdar_7062158_2;
+  if (current == x_rdar_7062158_2)
+    return;
+    
+  int *p = 0;
+  *p = 0xDEADBEEF; // no-warning  
+}
+
+// This test reproduces a case for a crash when analyzing ClamAV using
+// RegionStoreManager (the crash doesn't exhibit in BasicStoreManager because
+// it isn't doing anything smart about arrays).  The problem is that on the
+// second line, 'p = &p[i]', p is assigned an ElementRegion whose index
+// is a 16-bit integer.  On the third line, a new ElementRegion is created
+// based on the previous region, but there the region uses a 32-bit integer,
+// resulting in a clash of values (an assertion failure at best).  We resolve
+// this problem by implicitly converting index values to 'int' when the
+// ElementRegion is created.
+unsigned char test_array_index_bitwidth(const unsigned char *p) {
+  unsigned short i = 0;
+  for (i = 0; i < 2; i++) p = &p[i];  
+  return p[i+1];
+}
+
+// This case tests that CastRegion handles casts involving BlockPointerTypes.
+// It should not crash.
+void test_block_cast() {
+  id test_block_cast_aux();
+  (void (^)(void *))test_block_cast_aux(); // expected-warning{{expression result unused}}
+}
+
+int OSAtomicCompareAndSwap32Barrier();
+
+// Test comparison of 'id' instance variable to a null void* constant after
+// performing an OSAtomicCompareAndSwap32Barrier.
+// This previously was a crash in RegionStoreManager.
+@interface TestIdNull {
+  id x;
+}
+-(int)foo;
+@end
+@implementation TestIdNull
+-(int)foo {
+  OSAtomicCompareAndSwap32Barrier(0, (signed)2, (signed*)&x);  
+  if (x == (void*) 0) { return 0; }
+  return 1;
+}
+@end
+
+// PR 4594 - This was a crash when handling casts in SimpleSValuator.
+void PR4594() {
+  char *buf[1];
+  char **foo = buf;
+  *foo = "test";
+}
+
+// Test invalidation logic where an integer is casted to an array with a
+// different sign and then invalidated.
+void test_invalidate_cast_int() {
+  void test_invalidate_cast_int_aux(unsigned *i);
+  signed i;  
+  test_invalidate_cast_int_aux((unsigned*) &i);
+  if (i < 0)
+    return;
+}
+
+int ivar_getOffset();
+
+// Reduced from a crash involving the cast of an Objective-C symbolic region to
+// 'char *'
+static NSNumber *test_ivar_offset(id self, SEL _cmd, Ivar inIvar) {
+  return [[[NSNumber allocWithZone:((void*)0)] initWithBool:*(_Bool *)((char *)self + ivar_getOffset(inIvar))] autorelease];
+}
+
+// Reduced from a crash in StoreManager::CastRegion involving a divide-by-zero.
+// This resulted from not properly handling region casts to 'const void*'.
+void test_cast_const_voidptr() {
+  char x[10];
+  char *p = &x[1];
+  const void* q = p;
+}
+
+// Reduced from a crash when analyzing Wine.  This test handles loads from
+// function addresses.
+typedef long (*FARPROC)();
+FARPROC test_load_func(FARPROC origfun) {
+  if (!*(unsigned char*) origfun)
+    return origfun;
+  return 0;
+}
+
+// Test passing-by-value an initialized struct variable.
+struct test_pass_val {
+  int x;
+  int y;
+};
+void test_pass_val_aux(struct test_pass_val s);
+void test_pass_val() {
+  struct test_pass_val s;
+  s.x = 1;
+  s.y = 2;
+  test_pass_val_aux(s);
+}
+
+// This is a reduced test case of a false positive that previously appeared
+// in RegionStoreManager.  Previously the array access resulted in dereferencing
+// an undefined value.
+int test_array_compound(int *q, int *r, int *z) {
+  int *array[] = { q, r, z };
+  int j = 0;
+  for (unsigned i = 0; i < 3 ; ++i)
+    if (*array[i]) ++j; // no-warning
+  return j;
+}
+
+// This test case previously crashed with -analyzer-store=basic because the
+// symbolic value stored in 'x' wouldn't be implicitly casted to a signed value
+// during the comparison.
+int rdar_7124210(unsigned int x) {
+  enum { SOME_CONSTANT = 123 };
+  int compare = ((signed) SOME_CONSTANT) == *((signed *) &x);
+  return compare ? 0 : 1; // Forces the evaluation of the symbolic constraint.
+}
+
+void pr4781(unsigned long *raw1) {
+  unsigned long *cook, *raw0;
+  unsigned long dough[32];
+  int i;
+  cook = dough;
+  for( i = 0; i < 16; i++, raw1++ ) {
+    raw0 = raw1++;
+    *cook = (*raw0 & 0x00fc0000L) << 6;
+    *cook |= (*raw0 & 0x00000fc0L) << 10;
+  }
+}
+
+// <rdar://problem/7185647> - 'self' should be treated as being non-null
+// upon entry to an objective-c method.
+@interface RDar7185647
+- (id)foo;
+@end
+@implementation RDar7185647
+- (id) foo {
+  if (self)
+    return self;
+  *((int *) 0x0) = 0xDEADBEEF; // no-warning
+  return self;
+}
+@end
+
+// Test reasoning of __builtin_offsetof;
+struct test_offsetof_A {
+  int x;
+  int y;
+};
+struct test_offsetof_B {
+  int w;
+  int z;
+};
+void test_offsetof_1() {
+  if (__builtin_offsetof(struct test_offsetof_A, x) ==
+      __builtin_offsetof(struct test_offsetof_B, w))
+    return;
+  int *p = 0;
+  *p = 0xDEADBEEF; // no-warning
+}
+void test_offsetof_2() {
+  if (__builtin_offsetof(struct test_offsetof_A, y) ==
+      __builtin_offsetof(struct test_offsetof_B, z))
+    return;
+  int *p = 0;
+  *p = 0xDEADBEEF; // no-warning
+}
+void test_offsetof_3() {
+  if (__builtin_offsetof(struct test_offsetof_A, y) -
+      __builtin_offsetof(struct test_offsetof_A, x)
+      ==
+      __builtin_offsetof(struct test_offsetof_B, z) -
+      __builtin_offsetof(struct test_offsetof_B, w))
+    return;
+  int *p = 0;
+  *p = 0xDEADBEEF; // no-warning
+}
+void test_offsetof_4() {
+  if (__builtin_offsetof(struct test_offsetof_A, y) ==
+      __builtin_offsetof(struct test_offsetof_B, w))
+    return;
+  int *p = 0;
+  *p = 0xDEADBEEF; // expected-warning{{Dereference of null pointer}}
+}
+
+// <rdar://problem/6829164> "nil receiver" false positive: make tracking 
+// of the MemRegion for 'self' path-sensitive
+@interface RDar6829164 : NSObject {
+  double x; int y;
+}
+- (id) init;
+@end
+
+id rdar_6829164_1();
+double rdar_6829164_2();
+
+@implementation RDar6829164
+- (id) init {
+  if((self = [super init]) != 0) {
+    id z = rdar_6829164_1();
+    y = (z != 0);
+    if (y)
+      x = rdar_6829164_2();
+  }
+  return self;
+}
+@end
+
+// <rdar://problem/7242015> - Invalidate values passed-by-reference
+// to functions when the pointer to the value is passed as an integer.
+void test_7242015_aux(unsigned long);
+int rdar_7242015() {
+  int x;
+  test_7242015_aux((unsigned long) &x); // no-warning
+  return x; // Previously we return and uninitialized value when
+            // using RegionStore.
+}
+
+// <rdar://problem/7242006> [RegionStore] compound literal assignment with
+//  floats not honored
+CGFloat rdar7242006(CGFloat x) {
+  NSSize y = (NSSize){x, 10};
+  return y.width; // no-warning
+}
+
+// PR 4988 - This test exhibits a case where a function can be referenced
+//  when not explicitly used in an "lvalue" context (as far as the analyzer is
+//  concerned). This previously triggered a crash due to an invalid assertion.
+void pr_4988(void) {
+  pr_4988; // expected-warning{{expression result unused}}
+}
+
+// <rdar://problem/7152418> - A 'signed char' is used as a flag, which is
+//  implicitly converted to an int.
+void *rdar7152418_bar();
+@interface RDar7152418 {
+  signed char x;
+}
+-(char)foo;
+@end;
+@implementation RDar7152418
+-(char)foo {
+  char *p = 0;
+  void *result = 0;
+  if (x) {
+    result = rdar7152418_bar();
+    p = "hello";
+  }
+  if (!result) {
+    result = rdar7152418_bar();
+    if (result && x)
+      return *p; // no-warning
+  }
+  return 1;
+}
+
+//===----------------------------------------------------------------------===//
+// Test constant-folding of symbolic values, automatically handling type
+// conversions of the symbol as necessary.
+//===----------------------------------------------------------------------===//
+
+// Previously this would crash once we started eagerly evaluating symbols whose 
+// values were constrained to a single value.
+void test_symbol_fold_1(signed char x) {
+  while (1) {
+    if (x == ((signed char) 0)) {}
+  }
+}
+
+// This previously caused a crash because it triggered an assertion in APSInt.
+void test_symbol_fold_2(unsigned int * p, unsigned int n,
+                        const unsigned int * grumpkin, unsigned int dn) {
+  unsigned int i;
+  unsigned int tempsub[8];
+  unsigned int *solgrumpkin = tempsub + n;
+  for (i = 0; i < n; i++)
+    solgrumpkin[i] = (i < dn) ? ~grumpkin[i] : 0xFFFFFFFF;
+  for (i <<= 5; i < (n << 5); i++) {}
+}
+
+// This previously caused a crash because it triggered an assertion in APSInt.
+// 'x' would evaluate to a 8-bit constant (because of the return value of
+// test_symbol_fold_3_aux()) which would not get properly promoted to an
+// integer.
+char test_symbol_fold_3_aux(void);
+unsigned test_symbol_fold_3(void) {
+  unsigned x = test_symbol_fold_3_aux();
+  if (x == 54)
+    return (x << 8) | 0x5;
+  return 0;
+} 
+
+//===----------------------------------------------------------------------===//
+// Tests for the warning of casting a non-struct type to a struct type
+//===----------------------------------------------------------------------===//
+
+typedef struct {unsigned int v;} NSSwappedFloat;
+
+NSSwappedFloat test_cast_nonstruct_to_struct(float x) {
+  struct hodor {
+    float number;
+    NSSwappedFloat sf;
+  };
+  return ((struct hodor *)&x)->sf; // expected-warning{{Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption}}
+}
+
+NSSwappedFloat test_cast_nonstruct_to_union(float x) {
+  union bran {
+    float number;
+    NSSwappedFloat sf;
+  };
+  return ((union bran *)&x)->sf; // no-warning
+}
+
+void test_undefined_array_subscript() {
+  int i, a[10];
+  int *p = &a[i]; // expected-warning{{Array subscript is undefined}}
+}
+@end
+
+//===----------------------------------------------------------------------===//
+// Test using an uninitialized value as a branch condition.
+//===----------------------------------------------------------------------===//
+
+int test_uninit_branch(void) {
+  int x;
+  if (x) // expected-warning{{Branch condition evaluates to a garbage value}}
+    return 1;
+  return 0; 
+}
+
+int test_uninit_branch_b(void) {
+  int x;
+  return x ? 1 : 0; // expected-warning{{Branch condition evaluates to a garbage value}}
+}
+
+int test_uninit_branch_c(void) {
+  int x;
+  if ((short)x) // expected-warning{{Branch condition evaluates to a garbage value}}
+    return 1;
+  return 0; 
+}
+
+//===----------------------------------------------------------------------===//
+// Test passing an undefined value in a message or function call.
+//===----------------------------------------------------------------------===//
+
+void test_bad_call_aux(int x);
+void test_bad_call(void) {
+  int y;
+  test_bad_call_aux(y); // expected-warning{{Pass-by-value argument in function call is undefined}}
+}
+
+@interface TestBadArg {}
+- (void) testBadArg:(int) x;
+@end
+
+void test_bad_msg(TestBadArg *p) {
+  int y;
+  [p testBadArg:y]; // expected-warning{{Pass-by-value argument in message expression is undefined}}
+}
+
+//===----------------------------------------------------------------------===//
+// PR 6033 - Test emitting the correct output in a warning where we use '%'
+//  with operands that are undefined.
+//===----------------------------------------------------------------------===//
+
+int pr6033(int x) {
+  int y;
+  return x % y; // expected-warning{{The right operand of '%' is a garbage value}}
+}
+
+struct trie {
+  struct trie* next;
+};
+
+struct kwset {
+  struct trie *trie;
+  unsigned char delta[10];
+  struct trie* next[10];
+  int d;
+};
+
+typedef struct trie trie_t;
+typedef struct kwset kwset_t;
+
+void f(kwset_t *kws, char const *p, char const *q) {
+  struct trie const *trie;
+  struct trie * const *next = kws->next;
+  register unsigned char c;
+  register char const *end = p;
+  register char const *lim = q;
+  register int d = 1;
+  register unsigned char const *delta = kws->delta;
+
+  d = delta[c = (end+=d)[-1]]; // no-warning
+  trie = next[c];
+}
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/7593875> When handling sizeof(VLA) it leads to a hole in
+// the ExplodedGraph (causing a false positive)
+//===----------------------------------------------------------------------===//
+
+int rdar_7593875_aux(int x);
+int rdar_7593875(int n) {
+  int z[n > 10 ? 10 : n]; // VLA.
+  int v;
+  v = rdar_7593875_aux(sizeof(z));
+  // Previously we got a false positive about 'v' being uninitialized.
+  return v; // no-warning
+}
+
+//===----------------------------------------------------------------------===//
+// Handle casts from symbolic regions (packaged as integers) to doubles.
+// Previously this caused an assertion failure.
+//===----------------------------------------------------------------------===//
+
+void *foo_rev95119();
+void baz_rev95119(double x);
+void bar_rev95119() {
+  // foo_rev95119() returns a symbolic pointer.  It is then 
+  // cast to an int which is then cast to a double.
+  int value = (int) foo_rev95119();
+  baz_rev95119((double)value);
+}
+
+//===----------------------------------------------------------------------===//
+// Handle loading a symbolic pointer from a symbolic region that was
+// invalidated by a call to an unknown function.
+//===----------------------------------------------------------------------===//
+
+void bar_rev95192(int **x);
+void foo_rev95192(int **x) {
+  *x = 0;
+  bar_rev95192(x);
+  // Not a null dereference.
+  **x = 1; // no-warning
+}
+
+//===----------------------------------------------------------------------===//
+// Handle casts of a function to a function pointer with a different return
+// value.  We don't yet emit an error for such cases, but we now we at least
+// don't crash when the return value gets interpreted in a way that
+// violates our invariants.
+//===----------------------------------------------------------------------===//
+
+void *foo_rev95267();
+int bar_rev95267() {
+  char (*Callback_rev95267)(void) = (char (*)(void)) foo_rev95267;
+  if ((*Callback_rev95267)() == (char) 0)
+    return 1;
+  return 0;
+}
+
+// Same as previous case, but handle casts to 'void'.
+int bar_rev95274() {
+  void (*Callback_rev95274)(void) = (void (*)(void)) foo_rev95267;
+  (*Callback_rev95274)();
+  return 0;
+}
+
+void rdar7582031_test_static_init_zero() {
+  static unsigned x;
+  if (x == 0)
+    return;
+  int *p = 0;
+  *p = 0xDEADBEEF;
+}
+void rdar7582031_test_static_init_zero_b() {
+  static void* x;
+  if (x == 0)
+    return;
+  int *p = 0;
+  *p = 0xDEADBEEF;
+}
+
+//===----------------------------------------------------------------------===//
+// Test handling of parameters that are structs that contain floats and       //
+// nested fields.                                                             //
+//===----------------------------------------------------------------------===//
+
+struct s_rev95547_nested { float x, y; };
+struct s_rev95547 {
+  struct s_rev95547_nested z1;
+  struct s_rev95547_nested z2;
+};
+float foo_rev95547(struct s_rev95547 w) {
+  return w.z1.x + 20.0; // no-warning
+}
+void foo_rev95547_b(struct s_rev95547 w) {
+  struct s_rev95547 w2 = w;
+  w2.z1.x += 20.0; // no-warning
+}
diff --git a/test/Analysis/new.cpp b/test/Analysis/new.cpp
new file mode 100644
index 0000000..f26eecd
--- /dev/null
+++ b/test/Analysis/new.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-store region -verify %s
+
+void f1() {
+  int *n = new int;
+  if (*n) { // expected-warning {{Branch condition evaluates to a garbage value}}
+  }
+}
+
+void f2() {
+  int *n = new int(3);
+  if (*n) { // no-warning
+  }
+}
+
diff --git a/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m b/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m
new file mode 100644
index 0000000..2e9c528
--- /dev/null
+++ b/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m
@@ -0,0 +1,82 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin8 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-constraints=basic -analyzer-store=basic %s  2>&1 | FileCheck -check-prefix=darwin8 %s
+// RUN: %clang_cc1 -triple i386-apple-darwin8 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-constraints=basic -analyzer-store=region %s 2>&1 | FileCheck -check-prefix=darwin8 %s
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-constraints=basic -analyzer-store=basic %s 2>&1 | FileCheck -check-prefix=darwin9 %s
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-constraints=basic -analyzer-store=region %s 2>&1 | FileCheck -check-prefix=darwin9 %s
+
+@interface MyClass {}
+- (void *)voidPtrM;
+- (int)intM;
+- (long long)longlongM;
+- (double)doubleM;
+- (long double)longDoubleM;
+- (void)voidM;
+@end
+@implementation MyClass
+- (void *)voidPtrM { return (void *)0; }
+- (int)intM { return 0; }
+- (long long)longlongM { return 0; }
+- (double)doubleM { return 0.0; }
+- (long double)longDoubleM { return 0.0; }
+- (void)voidM {}
+@end
+
+void createFoo() {
+  MyClass *obj = 0;  
+  
+  void *v = [obj voidPtrM]; // no-warning
+  int i = [obj intM]; // no-warning
+}
+
+void createFoo2() {
+  MyClass *obj = 0;  
+  
+  long double ld = [obj longDoubleM]; // expected-warning{{The receiver of message 'longDoubleM' is nil and returns a value of type 'long double' that will be garbage}}
+}
+
+void createFoo3() {
+  MyClass *obj;
+  obj = 0;  
+  
+  long long ll = [obj longlongM]; // expected-warning{{The receiver of message 'longlongM' is nil and returns a value of type 'long long' that will be garbage}}
+}
+
+void createFoo4() {
+  MyClass *obj = 0;  
+  
+  double d = [obj doubleM]; // expected-warning{{The receiver of message 'doubleM' is nil and returns a value of type 'double' that will be garbage}}
+}
+
+void createFoo5() {
+  MyClass *obj = @"";  
+  
+  double d = [obj doubleM]; // no-warning
+}
+
+void handleNilPruneLoop(MyClass *obj) {
+  if (!!obj)
+    return;
+  
+  // Test if [obj intM] evaluates to 0, thus pruning the entire loop.
+  for (int i = 0; i < [obj intM]; i++) {
+    long long j = [obj longlongM]; // no-warning
+  }
+  
+  long long j = [obj longlongM]; // expected-warning{{The receiver of message 'longlongM' is nil and returns a value of type 'long long' that will be garbage}}
+}
+
+int handleVoidInComma() {
+  MyClass *obj = 0;
+  return [obj voidM], 0;
+}
+
+int marker(void) { // control reaches end of non-void function
+}
+
+// CHECK-darwin8: warning: The receiver of message 'longDoubleM' is nil and returns a value of type 'long double' that will be garbage
+// CHECK-darwin8: warning: The receiver of message 'longlongM' is nil and returns a value of type 'long long' that will be garbage
+// CHECK-darwin8: warning: The receiver of message 'doubleM' is nil and returns a value of type 'double' that will be garbage
+// CHECK-darwin8: warning: The receiver of message 'longlongM' is nil and returns a value of type 'long long' that will be garbage
+// CHECK-darwin8: control reaches end of non-void function
+// CHECK-darwin8: 5 warnings generated
+// CHECK-darwin9: control reaches end of non-void function
+// CHECK-darwin9: 1 warning generated
diff --git a/test/Analysis/no-exit-cfg.c b/test/Analysis/no-exit-cfg.c
new file mode 100644
index 0000000..659f675
--- /dev/null
+++ b/test/Analysis/no-exit-cfg.c
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -verify %s 
+
+// This is a test case for the issue reported in PR 2819:
+//  http://llvm.org/bugs/show_bug.cgi?id=2819
+// The flow-sensitive dataflow solver should work even when no block in
+// the CFG reaches the exit block.
+
+int g(int x);
+void h(int x);
+
+int f(int x)
+{
+out_err:
+  if (g(x)) {
+    h(x);
+  }
+  goto out_err;
+}
diff --git a/test/Analysis/no-outofbounds.c b/test/Analysis/no-outofbounds.c
new file mode 100644
index 0000000..771323b
--- /dev/null
+++ b/test/Analysis/no-outofbounds.c
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -analyzer-check-objc-mem -analyze -analyzer-experimental-internal-checks -analyzer-store=basic -verify %s
+// RUN: %clang_cc1 -analyzer-check-objc-mem -analyze -analyzer-experimental-internal-checks -analyzer-store=region -verify %s
+
+//===----------------------------------------------------------------------===//
+// This file tests cases where we should not flag out-of-bounds warnings.
+//===----------------------------------------------------------------------===//
+
+void f() {
+  long x = 0;
+  char *y = (char*) &x;
+  char c = y[0] + y[1] + y[2]; // no-warning
+  short *z = (short*) &x;
+  short s = z[0] + z[1]; // no-warning
+}
diff --git a/test/Analysis/null-deref-ps-region.c b/test/Analysis/null-deref-ps-region.c
new file mode 100644
index 0000000..0199d20
--- /dev/null
+++ b/test/Analysis/null-deref-ps-region.c
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -std=gnu99 -analyzer-check-objc-mem -analyzer-store=region -verify %s
+
+
+// The store for 'a[1]' should not be removed mistakenly. SymbolicRegions may
+// also be live roots.
+void f14(int *a) {
+  int i;
+  a[1] = 1;
+  i = a[1];
+  if (i != 1) {
+    int *p = 0;
+    i = *p; // no-warning
+  }
+}
diff --git a/test/Analysis/null-deref-ps.c b/test/Analysis/null-deref-ps.c
new file mode 100644
index 0000000..5a1049c
--- /dev/null
+++ b/test/Analysis/null-deref-ps.c
@@ -0,0 +1,290 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-experimental-internal-checks -std=gnu99 -analyzer-check-objc-mem -verify %s -analyzer-constraints=basic -analyzer-store=basic
+// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-experimental-internal-checks -std=gnu99 -analyzer-check-objc-mem -verify %s -analyzer-constraints=range -analyzer-store=basic
+// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-experimental-internal-checks -std=gnu99 -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -analyzer-no-purge-dead -verify %s
+// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-experimental-internal-checks -std=gnu99 -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -verify %s
+
+typedef unsigned uintptr_t;
+
+extern void __assert_fail (__const char *__assertion, __const char *__file,
+    unsigned int __line, __const char *__function)
+     __attribute__ ((__noreturn__));
+
+#define assert(expr) \
+  ((expr)  ? (void)(0)  : __assert_fail (#expr, __FILE__, __LINE__, __func__))
+
+void f1(int *p) {  
+  if (p) *p = 1;
+  else *p = 0; // expected-warning{{ereference}}
+}
+
+struct foo_struct {
+  int x;
+};
+
+int f2(struct foo_struct* p) {
+  
+  if (p)
+    p->x = 1;
+    
+  return p->x++; // expected-warning{{Field access results in a dereference of a null pointer (loaded from variable 'p')}}
+}
+
+int f3(char* x) {
+  
+  int i = 2;
+  
+  if (x)
+    return x[i - 1];
+  
+  return x[i+1]; // expected-warning{{Dereference of null pointer}}
+}
+
+int f3_b(char* x) {
+  
+  int i = 2;
+  
+  if (x)
+    return x[i - 1];
+  
+  return x[i+1]++; // expected-warning{{Dereference of null pointer}}
+}
+
+int f4(int *p) {
+  
+  uintptr_t x = (uintptr_t) p;
+  
+  if (x)
+    return 1;
+    
+  int *q = (int*) x;
+  return *q; // expected-warning{{Dereference of null pointer (loaded from variable 'q')}}
+}
+
+int f4_b() {
+  short array[2];
+  uintptr_t x = array; // expected-warning{{incompatible pointer to integer conversion}}
+  short *p = x; // expected-warning{{incompatible integer to pointer conversion}}
+  
+  // The following branch should be infeasible.
+  if (!(p = &array[0])) {
+    p = 0;
+    *p = 1; // no-warning
+  }
+  
+  if (p) {
+    *p = 5; // no-warning
+    p = 0;
+  }
+  else return; // expected-warning {{non-void function 'f4_b' should return a value}}
+
+  *p += 10; // expected-warning{{Dereference of null pointer}}
+  return 0;
+}
+
+
+int f5() {
+  
+  char *s = "hello world";
+  return s[0]; // no-warning
+}
+
+int bar(int* p, int q) __attribute__((nonnull));
+
+int f6(int *p) { 
+  return !p ? bar(p, 1) // expected-warning {{Null pointer passed as an argument to a 'nonnull' parameter}}
+         : bar(p, 0);   // no-warning
+}
+
+int bar2(int* p, int q) __attribute__((nonnull(1)));
+
+int f6b(int *p) { 
+  return !p ? bar2(p, 1) // expected-warning {{Null pointer passed as an argument to a 'nonnull' parameter}}
+         : bar2(p, 0);   // no-warning
+}
+
+int bar3(int*p, int q, int *r) __attribute__((nonnull(1,3)));
+
+int f6c(int *p, int *q) {
+   return !p ? bar3(q, 2, p) // expected-warning {{Null pointer passed as an argument to a 'nonnull' parameter}}
+             : bar3(p, 2, q); // no-warning
+}
+
+void f6d(int *p) {
+  bar(p, 0);
+  // At this point, 'p' cannot be null.
+  if (!p) {
+    int *q = 0;
+    *q = 0xDEADBEEF; // no-warning    
+  }  
+}
+
+int* qux();
+
+int f7(int x) {
+  
+  int* p = 0;
+  
+  if (0 == x)
+    p = qux();
+  
+  if (0 == x)
+    *p = 1; // no-warning
+    
+  return x;
+}
+
+int* f7b(int *x) {
+  
+  int* p = 0;
+  
+  if (((void*)0) == x)
+    p = qux();
+  
+  if (((void*)0) == x)
+    *p = 1; // no-warning
+    
+  return x;
+}
+
+int* f7c(int *x) {
+  
+  int* p = 0;
+  
+  if (((void*)0) == x)
+    p = qux();
+  
+  if (((void*)0) != x)
+    return x;
+
+  // If we reach here then 'p' is not null.
+  *p = 1; // no-warning
+  return x;
+}
+
+int* f7c2(int *x) {
+  
+  int* p = 0;
+  
+  if (((void*)0) == x)
+    p = qux();
+  
+  if (((void*)0) == x)
+    return x;
+    
+  *p = 1; // expected-warning{{null}}
+  return x;
+}
+
+
+void f8(int *p, int *q) {
+  if (!p)
+    if (p)
+      *p = 1; // no-warning
+  
+  if (q)
+    if (!q)
+      *q = 1; // no-warning
+}
+
+int* qux();
+
+int f9(unsigned len) {
+  assert (len != 0);
+  int *p = 0;
+  unsigned i;
+
+  for (i = 0; i < len; ++i)
+   p = qux(i);
+
+  return *p++; // no-warning
+}
+
+int f9b(unsigned len) {
+  assert (len > 0);  // note use of '>'
+  int *p = 0;
+  unsigned i;
+
+  for (i = 0; i < len; ++i)
+   p = qux(i);
+
+  return *p++; // no-warning
+}
+
+int* f10(int* p, signed char x, int y) {
+  // This line tests symbolication with compound assignments where the
+  // LHS and RHS have different bitwidths.  The new symbolic value
+  // for 'x' should have a bitwidth of 8.
+  x &= y;
+  
+  // This tests that our symbolication worked, and that we correctly test
+  // x against 0 (with the same bitwidth).
+  if (!x) {
+    if (!p) return; // expected-warning {{non-void function 'f10' should return a value}}
+    *p = 10;
+  }
+  else p = 0;
+
+  if (!x)
+    *p = 5; // no-warning
+
+  return p;
+}
+
+// Test case from <rdar://problem/6407949>
+void f11(unsigned i) {
+  int *x = 0;
+  if (i >= 0) {
+    // always true
+  } else {
+    *x = 42; // no-warning
+  }
+}
+
+void f11b(unsigned i) {
+  int *x = 0;
+  if (i <= ~(unsigned)0) {
+    // always true
+  } else {
+    *x = 42; // no-warning
+  }
+}
+
+// Test case for switch statements with weird case arms.
+typedef int     BOOL, *PBOOL, *LPBOOL;
+typedef long    LONG_PTR, *PLONG_PTR;
+typedef unsigned long ULONG_PTR, *PULONG_PTR;
+typedef ULONG_PTR DWORD_PTR, *PDWORD_PTR;
+typedef LONG_PTR LRESULT;
+typedef struct _F12ITEM *HF12ITEM;
+
+void f12(HF12ITEM i, char *q) {
+  char *p = 0;
+  switch ((DWORD_PTR) i) {
+  case 0 ... 10:
+    p = q;
+    break;
+  case (DWORD_PTR) ((HF12ITEM) - 65535):
+    return;
+  default:
+    return;
+  }
+  
+  *p = 1; // no-warning
+}
+
+// Test handling of translating between integer "pointers" and back.
+void f13() {
+  int *x = 0;
+  if (((((int) x) << 2) + 1) >> 1) *x = 1; // no-warning
+}
+
+// PR 4759 - Attribute non-null checking by the analyzer was not correctly
+// handling pointer values that were undefined.
+void pr4759_aux(int *p) __attribute__((nonnull));
+
+void pr4759() {
+  int *p;
+  pr4759_aux(p); // expected-warning{{undefined}}
+}
+
+
diff --git a/test/Analysis/outofbound.c b/test/Analysis/outofbound.c
new file mode 100644
index 0000000..e1ff66c
--- /dev/null
+++ b/test/Analysis/outofbound.c
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-experimental-checks -analyzer-check-objc-mem -analyzer-store=region -verify %s
+
+typedef __typeof(sizeof(int)) size_t;
+void *malloc(size_t);
+
+char f1() {
+  char* s = "abcd";
+  char c = s[4]; // no-warning
+  return s[5] + c; // expected-warning{{Access out-of-bound array element (buffer overflow)}}
+}
+
+void f2() {
+  int *p = malloc(12);
+  p[3] = 4; // expected-warning{{Access out-of-bound array element (buffer overflow)}}
+}
+
+struct three_words {
+  int c[3];
+};
+
+struct seven_words {
+  int c[7];
+};
+
+void f3() {
+  struct three_words a, *p;
+  p = &a;
+  p[0] = a; // no-warning
+  p[1] = a; // expected-warning{{Access out-of-bound array element (buffer overflow)}}
+}
+
+void f4() {
+  struct seven_words c;
+  struct three_words a, *p = (struct three_words *)&c;
+  p[0] = a; // no-warning
+  p[1] = a; // no-warning
+  p[2] = a; // expected-warning{{Access out-of-bound array element (buffer overflow)}}
+}
diff --git a/test/Analysis/override-werror.c b/test/Analysis/override-werror.c
new file mode 100644
index 0000000..f4854bb
--- /dev/null
+++ b/test/Analysis/override-werror.c
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -Werror %s -analyzer-store=basic -verify
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -Werror %s -analyzer-store=region -verify
+
+// This test case illustrates that using '-analyze' overrides the effect of
+// -Werror.  This allows basic warnings not to interfere with producing
+// analyzer results.
+
+char* f(int *p) { 
+  return p; // expected-warning{{incompatible pointer types}}
+}
+
+void g(int *p) {
+  if (!p) *p = 0; // expected-warning{{null}}  
+}
+
diff --git a/test/Analysis/plist-output.m b/test/Analysis/plist-output.m
new file mode 100644
index 0000000..aa866de
--- /dev/null
+++ b/test/Analysis/plist-output.m
@@ -0,0 +1,851 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -fblocks -analyzer-output=plist -o - %s | FileCheck %s
+
+void test_null_init(void) {
+  int *p = 0;
+  *p = 0xDEADBEEF;
+}
+
+void test_null_assign(void) {
+  int *p;
+  p = 0;
+  *p = 0xDEADBEEF;
+}
+
+void test_null_assign_transitive(void) {
+  int *p;
+  p = 0;
+  int *q = p;
+  *q = 0xDEADBEEF;
+}
+
+void test_null_cond(int *p) {
+  if (!p) {
+    *p = 0xDEADBEEF;
+  }
+}
+
+void test_null_cond_transitive(int *q) {
+  if (!q) {
+    int *p = q;
+    *p = 0xDEADBEEF;
+  }
+}
+
+void test_null_field(void) {
+  struct s { int *p; } x;
+  x.p = 0;
+  *(x.p) = 0xDEADBEEF;
+}
+
+// CHECK: <?xml version="1.0" encoding="UTF-8"?>
+// CHECK: <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+// CHECK: <plist version="1.0">
+// CHECK: <dict>
+// CHECK:  <key>files</key>
+// CHECK:  <array>
+// CHECK:  </array>
+// CHECK:  <key>diagnostics</key>
+// CHECK:  <array>
+// CHECK:   <dict>
+// CHECK:    <key>path</key>
+// CHECK:    <array>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>4</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>4</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>4</integer>
+// CHECK:          <key>col</key><integer>8</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Variable &apos;p&apos; initialized to a null pointer value</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Variable &apos;p&apos; initialized to a null pointer value</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>4</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>4</integer>
+// CHECK:            <key>col</key><integer>8</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>5</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>5</integer>
+// CHECK:            <key>col</key><integer>4</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>5</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>5</integer>
+// CHECK:          <key>col</key><integer>4</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>5</integer>
+// CHECK:          <key>col</key><integer>4</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Dereference of null pointer (loaded from variable &apos;p&apos;)</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Dereference of null pointer (loaded from variable &apos;p&apos;)</string>
+// CHECK:     </dict>
+// CHECK:    </array>
+// CHECK:    <key>description</key><string>Dereference of null pointer (loaded from variable &apos;p&apos;)</string>
+// CHECK:    <key>category</key><string>Logic error</string>
+// CHECK:    <key>type</key><string>Dereference of null pointer</string>
+// CHECK:   <key>location</key>
+// CHECK:   <dict>
+// CHECK:    <key>line</key><integer>5</integer>
+// CHECK:    <key>col</key><integer>3</integer>
+// CHECK:    <key>file</key><integer>0</integer>
+// CHECK:   </dict>
+// CHECK:   </dict>
+// CHECK:   <dict>
+// CHECK:    <key>path</key>
+// CHECK:    <array>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>9</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>9</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>10</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>10</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>10</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>10</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>10</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Null pointer value stored to &apos;p&apos;</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Null pointer value stored to &apos;p&apos;</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>10</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>10</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>11</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>11</integer>
+// CHECK:            <key>col</key><integer>4</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>11</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>11</integer>
+// CHECK:          <key>col</key><integer>4</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>11</integer>
+// CHECK:          <key>col</key><integer>4</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Dereference of null pointer (loaded from variable &apos;p&apos;)</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Dereference of null pointer (loaded from variable &apos;p&apos;)</string>
+// CHECK:     </dict>
+// CHECK:    </array>
+// CHECK:    <key>description</key><string>Dereference of null pointer (loaded from variable &apos;p&apos;)</string>
+// CHECK:    <key>category</key><string>Logic error</string>
+// CHECK:    <key>type</key><string>Dereference of null pointer</string>
+// CHECK:   <key>location</key>
+// CHECK:   <dict>
+// CHECK:    <key>line</key><integer>11</integer>
+// CHECK:    <key>col</key><integer>3</integer>
+// CHECK:    <key>file</key><integer>0</integer>
+// CHECK:   </dict>
+// CHECK:   </dict>
+// CHECK:   <dict>
+// CHECK:    <key>path</key>
+// CHECK:    <array>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>15</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>15</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>17</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>17</integer>
+// CHECK:            <key>col</key><integer>8</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>17</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>17</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>17</integer>
+// CHECK:          <key>col</key><integer>8</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Variable &apos;q&apos; initialized to a null pointer value</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Variable &apos;q&apos; initialized to a null pointer value</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>17</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>17</integer>
+// CHECK:            <key>col</key><integer>8</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>18</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>18</integer>
+// CHECK:            <key>col</key><integer>4</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>18</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>18</integer>
+// CHECK:          <key>col</key><integer>4</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>18</integer>
+// CHECK:          <key>col</key><integer>4</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Dereference of null pointer (loaded from variable &apos;q&apos;)</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Dereference of null pointer (loaded from variable &apos;q&apos;)</string>
+// CHECK:     </dict>
+// CHECK:    </array>
+// CHECK:    <key>description</key><string>Dereference of null pointer (loaded from variable &apos;q&apos;)</string>
+// CHECK:    <key>category</key><string>Logic error</string>
+// CHECK:    <key>type</key><string>Dereference of null pointer</string>
+// CHECK:   <key>location</key>
+// CHECK:   <dict>
+// CHECK:    <key>line</key><integer>18</integer>
+// CHECK:    <key>col</key><integer>3</integer>
+// CHECK:    <key>file</key><integer>0</integer>
+// CHECK:   </dict>
+// CHECK:   </dict>
+// CHECK:   <dict>
+// CHECK:    <key>path</key>
+// CHECK:    <array>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>22</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>22</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>22</integer>
+// CHECK:            <key>col</key><integer>7</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>22</integer>
+// CHECK:            <key>col</key><integer>8</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>22</integer>
+// CHECK:       <key>col</key><integer>7</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>22</integer>
+// CHECK:          <key>col</key><integer>7</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>22</integer>
+// CHECK:          <key>col</key><integer>8</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Assuming pointer value is null</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Assuming pointer value is null</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>22</integer>
+// CHECK:            <key>col</key><integer>7</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>22</integer>
+// CHECK:            <key>col</key><integer>8</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>23</integer>
+// CHECK:            <key>col</key><integer>5</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>23</integer>
+// CHECK:            <key>col</key><integer>6</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>23</integer>
+// CHECK:       <key>col</key><integer>5</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>23</integer>
+// CHECK:          <key>col</key><integer>6</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>23</integer>
+// CHECK:          <key>col</key><integer>6</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Dereference of null pointer (loaded from variable &apos;p&apos;)</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Dereference of null pointer (loaded from variable &apos;p&apos;)</string>
+// CHECK:     </dict>
+// CHECK:    </array>
+// CHECK:    <key>description</key><string>Dereference of null pointer (loaded from variable &apos;p&apos;)</string>
+// CHECK:    <key>category</key><string>Logic error</string>
+// CHECK:    <key>type</key><string>Dereference of null pointer</string>
+// CHECK:   <key>location</key>
+// CHECK:   <dict>
+// CHECK:    <key>line</key><integer>23</integer>
+// CHECK:    <key>col</key><integer>5</integer>
+// CHECK:    <key>file</key><integer>0</integer>
+// CHECK:   </dict>
+// CHECK:   </dict>
+// CHECK:   <dict>
+// CHECK:    <key>path</key>
+// CHECK:    <array>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>28</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>28</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>28</integer>
+// CHECK:            <key>col</key><integer>7</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>28</integer>
+// CHECK:            <key>col</key><integer>8</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>28</integer>
+// CHECK:       <key>col</key><integer>7</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>28</integer>
+// CHECK:          <key>col</key><integer>7</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>28</integer>
+// CHECK:          <key>col</key><integer>8</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Assuming pointer value is null</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Assuming pointer value is null</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>28</integer>
+// CHECK:            <key>col</key><integer>7</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>28</integer>
+// CHECK:            <key>col</key><integer>8</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>29</integer>
+// CHECK:            <key>col</key><integer>5</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>29</integer>
+// CHECK:            <key>col</key><integer>5</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>29</integer>
+// CHECK:            <key>col</key><integer>5</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>29</integer>
+// CHECK:            <key>col</key><integer>5</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>30</integer>
+// CHECK:            <key>col</key><integer>5</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>30</integer>
+// CHECK:            <key>col</key><integer>6</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>30</integer>
+// CHECK:       <key>col</key><integer>5</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>30</integer>
+// CHECK:          <key>col</key><integer>6</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>30</integer>
+// CHECK:          <key>col</key><integer>6</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Dereference of null pointer (loaded from variable &apos;p&apos;)</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Dereference of null pointer (loaded from variable &apos;p&apos;)</string>
+// CHECK:     </dict>
+// CHECK:    </array>
+// CHECK:    <key>description</key><string>Dereference of null pointer (loaded from variable &apos;p&apos;)</string>
+// CHECK:    <key>category</key><string>Logic error</string>
+// CHECK:    <key>type</key><string>Dereference of null pointer</string>
+// CHECK:   <key>location</key>
+// CHECK:   <dict>
+// CHECK:    <key>line</key><integer>30</integer>
+// CHECK:    <key>col</key><integer>5</integer>
+// CHECK:    <key>file</key><integer>0</integer>
+// CHECK:   </dict>
+// CHECK:   </dict>
+// CHECK:   <dict>
+// CHECK:    <key>path</key>
+// CHECK:    <array>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>35</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>35</integer>
+// CHECK:            <key>col</key><integer>8</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>35</integer>
+// CHECK:            <key>col</key><integer>10</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>35</integer>
+// CHECK:            <key>col</key><integer>10</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>35</integer>
+// CHECK:            <key>col</key><integer>10</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>35</integer>
+// CHECK:            <key>col</key><integer>10</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>37</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>37</integer>
+// CHECK:            <key>col</key><integer>8</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>37</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>37</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>37</integer>
+// CHECK:          <key>col</key><integer>8</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Dereference of null pointer</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Dereference of null pointer</string>
+// CHECK:     </dict>
+// CHECK:    </array>
+// CHECK:    <key>description</key><string>Dereference of null pointer</string>
+// CHECK:    <key>category</key><string>Logic error</string>
+// CHECK:    <key>type</key><string>Dereference of null pointer</string>
+// CHECK:   <key>location</key>
+// CHECK:   <dict>
+// CHECK:    <key>line</key><integer>37</integer>
+// CHECK:    <key>col</key><integer>3</integer>
+// CHECK:    <key>file</key><integer>0</integer>
+// CHECK:   </dict>
+// CHECK:   </dict>
+// CHECK:  </array>
+// CHECK: </dict>
+// CHECK: </plist>
diff --git a/test/Analysis/pr4209.m b/test/Analysis/pr4209.m
new file mode 100644
index 0000000..dc1ef7b
--- /dev/null
+++ b/test/Analysis/pr4209.m
@@ -0,0 +1,73 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -verify %s
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -verify %s
+
+// This test case was crashing due to how CFRefCount.cpp resolved the
+// ObjCInterfaceDecl* and ClassName in EvalObjCMessageExpr.
+
+typedef signed char BOOL;
+typedef unsigned int NSUInteger;
+typedef struct _NSZone NSZone;
+@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+@protocol NSObject  - (BOOL)isEqual:(id)object;
+@end  @protocol NSCopying  - (id)copyWithZone:(NSZone *)zone;
+@end  @protocol NSMutableCopying  - (id)mutableCopyWithZone:(NSZone *)zone;
+@end  @protocol NSCoding  - (void)encodeWithCoder:(NSCoder *)aCoder;
+@end    @interface NSObject <NSObject> {
+}
+@end  typedef float CGFloat;
+typedef struct _NSPoint {
+}
+NSFastEnumerationState;
+@protocol NSFastEnumeration  - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len;
+@end        @class NSString;
+@interface NSArray : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration>  - (NSUInteger)count;
+@end    @interface NSMutableArray : NSArray  - (void)addObject:(id)anObject;
+@end         typedef unsigned short unichar;
+@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding>    - (NSUInteger)length;
+- (int)intValue;
+@end @interface NSSimpleCString : NSString {
+}
+@end  @interface NSConstantString : NSSimpleCString @end   extern void *_NSConstantStringClassReference;
+@interface NSDictionary : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration>  - (NSUInteger)count;
+@end    @interface NSMutableDictionary : NSDictionary  - (void)removeObjectForKey:(id)aKey;
+@end       typedef struct {
+}
+CMProfileLocation;
+@interface NSResponder : NSObject <NSCoding> {
+}
+@end  @class NSAttributedString, NSEvent, NSFont, NSFormatter, NSImage, NSMenu, NSText, NSView;
+@interface NSCell : NSObject <NSCopying, NSCoding> {
+}
+@end  extern NSString *NSControlTintDidChangeNotification;
+@interface NSActionCell : NSCell {
+}
+@end  @class NSArray, NSDocument, NSWindow;
+@interface NSWindowController : NSResponder <NSCoding> {
+}
+@end         @class EBayCategoryType, GSEbayCategory, GBSearchRequest;
+@interface GBCategoryChooserPanelController : NSWindowController {
+  GSEbayCategory *rootCategory;
+}
+- (NSMutableDictionary*)categoryDictionaryForCategoryID:(int)inID inRootTreeCategories:(NSMutableArray*)inRootTreeCategories; // expected-note {{method definition for 'categoryDictionaryForCategoryID:inRootTreeCategories:' not found}}
+-(NSString*) categoryID;  // expected-note {{method definition for 'categoryID' not found}}
+@end @interface GSEbayCategory : NSObject <NSCoding> {
+}
+- (int) categoryID;
+- (GSEbayCategory *) parent;
+- (GSEbayCategory*) subcategoryWithID:(int) inID;
+@end   @implementation GBCategoryChooserPanelController  + (int) chooseCategoryIDFromCategories:(NSArray*) inCategories        searchRequest:(GBSearchRequest*)inRequest         parentWindow:(NSWindow*) inParent { // expected-warning {{incomplete implementation}}
+  return 0;
+}
+- (void) addCategory:(EBayCategoryType*)inCategory toRootTreeCategory:(NSMutableArray*)inRootTreeCategories {
+  GSEbayCategory *category = [rootCategory subcategoryWithID:[[inCategory categoryID] intValue]]; 
+
+  if (rootCategory != category)  {
+    GSEbayCategory *parent = category;
+    while ((((void*)0) != (parent = [parent parent])) && ([parent categoryID] != 0))   {
+      NSMutableDictionary *treeCategoryDict = [self categoryDictionaryForCategoryID:[parent categoryID] inRootTreeCategories:inRootTreeCategories];
+      if (((void*)0) == treeCategoryDict)    {
+      }
+    }
+  }
+}
+@end
diff --git a/test/Analysis/pr_2542_rdar_6793404.m b/test/Analysis/pr_2542_rdar_6793404.m
new file mode 100644
index 0000000..feafe2a
--- /dev/null
+++ b/test/Analysis/pr_2542_rdar_6793404.m
@@ -0,0 +1,68 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -pedantic -analyzer-store=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -pedantic -analyzer-store=region -verify %s
+
+// BEGIN delta-debugging reduced header stuff
+
+typedef signed char BOOL;
+typedef unsigned int NSUInteger;
+typedef struct _NSZone NSZone;
+@class NSCoder;
+@protocol NSObject
+- (BOOL)isEqual:(id)object;
+- (id)retain;
+- (oneway void)release;
+@end
+@protocol NSCopying
+- (id)copyWithZone:(NSZone *)zone;
+@end
+@protocol NSCoding
+- (void)encodeWithCoder:(NSCoder *)aCoder;
+@end
+@interface NSObject <NSObject> {}
+- (id)init;
++ (id)alloc;
+@end
+typedef double NSTimeInterval;
+enum { NSAnimationEaseInOut, NSAnimationEaseIn, NSAnimationEaseOut, NSAnimationLinear };
+typedef NSUInteger NSAnimationCurve;
+@interface NSAnimation : NSObject <NSCopying, NSCoding> {}
+- (id)initWithDuration:(NSTimeInterval)duration animationCurve:(NSAnimationCurve)animationCurve;
+- (void)startAnimation;
+- (void)setDelegate:(id)delegate;
+@end
+
+// END delta-debugging reduced header stuff
+
+// From NSAnimation Class Reference
+// -(void)startAnimation
+// The receiver retains itself and is then autoreleased at the end 
+// of the animation or when it receives stopAnimation.
+
+@interface MyClass { }
+- (void)animationDidEnd:(NSAnimation *)animation;
+@end
+
+@implementation MyClass
+- (void)f1 {  
+  // NOTE: The analyzer doesn't really handle this; it just stops tracking
+  // 'animation' when it is sent the message 'setDelegate:'.
+  NSAnimation *animation = [[NSAnimation alloc]   // no-warning
+                            initWithDuration:1.0 
+                            animationCurve:NSAnimationEaseInOut];
+  
+  [animation setDelegate:self];
+  [animation startAnimation]; 
+}
+
+- (void)f2 {
+  NSAnimation *animation = [[NSAnimation alloc]  // expected-warning{{leak}}
+                            initWithDuration:1.0 
+                            animationCurve:NSAnimationEaseInOut];
+
+  [animation startAnimation]; 
+}
+
+- (void)animationDidEnd:(NSAnimation *)animation {
+  [animation release];
+}
+@end
diff --git a/test/Analysis/pr_4164.c b/test/Analysis/pr_4164.c
new file mode 100644
index 0000000..e8a410f
--- /dev/null
+++ b/test/Analysis/pr_4164.c
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -verify %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -verify %s
+
+// PR 4164: http://llvm.org/bugs/show_bug.cgi?id=4164
+//
+// Eventually this should be pulled into misc-ps.m.  This is in a separate test
+// file for now to play around with the specific issues for BasicStoreManager
+// and StoreManager (i.e., we can make a copy of this file for either
+// StoreManager should one start to fail in the near future).
+//
+// The basic issue is that the VarRegion for 'size' is casted to (char*),
+// resulting in an ElementRegion.  'getsockopt' is an unknown function that
+// takes a void*, which means the ElementRegion should get stripped off.
+typedef unsigned int __uint32_t;
+typedef __uint32_t __darwin_socklen_t;
+typedef __darwin_socklen_t socklen_t;
+int getsockopt(int, int, int, void * restrict, socklen_t * restrict);
+
+int test1() {
+  int s = -1;
+  int size;
+  socklen_t size_len = sizeof(size);
+  if (getsockopt(s, 0xffff, 0x1001, (char *)&size, &size_len) < 0)
+          return -1;
+
+  return size; // no-warning
+}
+
+// Similar case: instead of passing a 'void*', we pass 'char*'.  In this
+// case we pass an ElementRegion to the invalidation logic.  Since it is
+// an ElementRegion that just layers on top of another typed region and the
+// ElementRegion itself has elements whose type are integral (essentially raw
+// data) we strip off the ElementRegion when doing the invalidation.
+int takes_charptr(char* p);
+int test2() {
+  int size;
+  if (takes_charptr((char*)&size))
+    return -1;
+  return size; // no-warning
+}
+
diff --git a/test/Analysis/ptr-arith.c b/test/Analysis/ptr-arith.c
new file mode 100644
index 0000000..f6bd61c
--- /dev/null
+++ b/test/Analysis/ptr-arith.c
@@ -0,0 +1,62 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -verify -triple x86_64-apple-darwin9 %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -verify -triple i686-apple-darwin9 %s
+
+void f1() {
+  int a[10];
+  int *p = a;
+  ++p;
+}
+
+char* foo();
+
+void f2() {
+  char *p = foo();
+  ++p;
+}
+
+// This test case checks if we get the right rvalue type of a TypedViewRegion.
+// The ElementRegion's type depends on the array region's rvalue type. If it was
+// a pointer type, we would get a loc::SymbolVal for '*p'.
+void* memchr();
+static int
+domain_port (const char *domain_b, const char *domain_e,
+             const char **domain_e_ptr)
+{
+  int port = 0;
+  
+  const char *p;
+  const char *colon = memchr (domain_b, ':', domain_e - domain_b);
+  
+  for (p = colon + 1; p < domain_e ; p++)
+    port = 10 * port + (*p - '0');
+  return port;
+}
+
+void f3() {
+  int x, y;
+  int d = &y - &x; // expected-warning{{Subtraction of two pointers that do not point to the same memory chunk may cause incorrect result.}}
+
+  int a[10];
+  int *p = &a[2];
+  int *q = &a[8];
+  d = q-p; // no-warning
+}
+
+void f4() {
+  int *p;
+  p = (int*) 0x10000; // expected-warning{{Using a fixed address is not portable because that address will probably not be valid in all environments or platforms.}}
+}
+
+void f5() {
+  int x, y;
+  int *p;
+  p = &x + 1;  // expected-warning{{Pointer arithmetic done on non-array variables means reliance on memory layout, which is dangerous.}}
+
+  int a[10];
+  p = a + 1; // no-warning
+}
+
+// Allow arithmetic on different symbolic regions.
+void f6(int *p, int *q) {
+  int d = q - p; // no-warning
+}
diff --git a/test/Analysis/rdar-6442306-1.m b/test/Analysis/rdar-6442306-1.m
new file mode 100644
index 0000000..a2af946
--- /dev/null
+++ b/test/Analysis/rdar-6442306-1.m
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem %s -analyzer-store=basic -verify
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem %s -analyzer-store=region -verify
+
+typedef int bar_return_t;
+typedef struct {
+  unsigned char int_rep;
+} Foo_record_t;
+extern Foo_record_t Foo_record;
+struct QuxSize {};
+typedef struct QuxSize QuxSize;
+typedef struct {
+  Foo_record_t Foo;
+  QuxSize size;
+} __Request__SetPortalSize_t;
+
+double __Foo_READSWAP__double(double*);
+
+static __inline__ bar_return_t
+__Beeble_check__Request__SetPortalSize_t(__attribute__((__unused__)) __Request__SetPortalSize_t *In0P) {
+  if (In0P->Foo.int_rep != Foo_record.int_rep) {
+    do {
+      int __i__, __C__ = (2);
+      for (__i__ = 0;
+           __i__ < __C__;
+           __i__++) do {
+        *(&((double *)(&In0P->size))[__i__]) =
+          __Foo_READSWAP__double(&((double *)(&In0P->size))[__i__]);
+      }
+      while (0);
+    }
+    while (0);
+  }
+  return 0;
+}
diff --git a/test/Analysis/rdar-6540084.m b/test/Analysis/rdar-6540084.m
new file mode 100644
index 0000000..dd01810
--- /dev/null
+++ b/test/Analysis/rdar-6540084.m
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-dead-stores -verify %s
+//
+// This test exercises the live variables analysis (LiveVariables.cpp).
+// The case originally identified a non-termination bug.
+//
+typedef signed char BOOL;
+typedef unsigned int NSUInteger;
+typedef struct _NSZone NSZone;
+@protocol NSObject  - (BOOL)isEqual:(id)object; @end
+@interface NSObject <NSObject> {} @end
+extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone);
+@class NSArray;
+@class NSMutableArray, NSIndexSet, NSView, NSPredicate, NSString, NSViewAnimation, NSTimer;
+@interface FooBazController : NSObject {}
+@end
+typedef struct {} TazVersion;
+@class TazNode;
+@interface TazGuttenberg : NSObject {} typedef NSUInteger BugsBunnyType; @end
+@interface FooBaz : NSObject {}
+@property (nonatomic) BugsBunnyType matchType;
+@property (nonatomic, retain) NSArray *papyrus; @end
+@implementation FooBazController
+- (NSArray *)excitingStuff:(FooBaz *)options {
+  BugsBunnyType matchType = options.matchType;
+  NSPredicate *isSearchablePredicate = [NSPredicate predicateWithFormat:@"isSearchable == YES"]; // expected-warning{{receiver 'NSPredicate' is a forward class and corresponding}} // expected-warning{{return type defaults to 'id'}}
+  for (TazGuttenberg *Guttenberg in options.papyrus) {
+    NSArray *GuttenbergNodes = [Guttenberg nodes]; // expected-warning{{return type defaults to 'id'}}
+    NSArray *searchableNodes = [GuttenbergNodes filteredArrayUsingPredicate:isSearchablePredicate]; // expected-warning{{return type defaults to 'id'}}
+    for (TazNode *node in searchableNodes) {
+      switch (matchType) {
+        default: break;
+      }
+    }
+  }
+  while (1) {}
+}
+@end
diff --git a/test/Analysis/rdar-6541136-region.c b/test/Analysis/rdar-6541136-region.c
new file mode 100644
index 0000000..82232c6
--- /dev/null
+++ b/test/Analysis/rdar-6541136-region.c
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -verify -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region %s
+
+struct tea_cheese { unsigned magic; };
+typedef struct tea_cheese kernel_tea_cheese_t;
+extern kernel_tea_cheese_t _wonky_gesticulate_cheese;
+
+// This test case exercises the ElementRegion::getRValueType() logic.
+
+void test1( void ) {
+  kernel_tea_cheese_t *wonky = &_wonky_gesticulate_cheese;
+  struct load_wine *cmd = (void*) &wonky[1];
+  cmd = cmd;
+  char *p = (void*) &wonky[1];
+  kernel_tea_cheese_t *q = &wonky[1];
+  // This test case tests both the RegionStore logic (doesn't crash) and
+  // the out-of-bounds checking.  We don't expect the warning for now since
+  // out-of-bound checking is temporarily disabled.
+  kernel_tea_cheese_t r = *q; // expected-warning{{Access out-of-bound array element (buffer overflow)}}
+}
+
+void test1_b( void ) {
+  kernel_tea_cheese_t *wonky = &_wonky_gesticulate_cheese;
+  struct load_wine *cmd = (void*) &wonky[1];
+  cmd = cmd;
+  char *p = (void*) &wonky[1];
+  *p = 1;  // expected-warning{{Access out-of-bound array element (buffer overflow)}}
+}
diff --git a/test/Analysis/rdar-6541136.c b/test/Analysis/rdar-6541136.c
new file mode 100644
index 0000000..844a936
--- /dev/null
+++ b/test/Analysis/rdar-6541136.c
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -verify -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic %s
+
+struct tea_cheese { unsigned magic; };
+typedef struct tea_cheese kernel_tea_cheese_t;
+extern kernel_tea_cheese_t _wonky_gesticulate_cheese;
+
+// This test case exercises the ElementRegion::getRValueType() logic.
+// All it tests is that it does not crash or do anything weird.
+// The out-of-bounds-access on line 19 is caught using the region store variant.
+
+void foo( void )
+{
+  kernel_tea_cheese_t *wonky = &_wonky_gesticulate_cheese;
+  struct load_wine *cmd = (void*) &wonky[1];
+  cmd = cmd;
+  char *p = (void*) &wonky[1];
+  *p = 1;
+  kernel_tea_cheese_t *q = &wonky[1];
+  kernel_tea_cheese_t r = *q; // no-warning
+}
diff --git a/test/Analysis/rdar-6562655.m b/test/Analysis/rdar-6562655.m
new file mode 100644
index 0000000..2aa2229
--- /dev/null
+++ b/test/Analysis/rdar-6562655.m
@@ -0,0 +1,65 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-constraints=basic -analyzer-store=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-constraints=basic -analyzer-store=region -verify %s
+//
+// This test case mainly checks that the retain/release checker doesn't crash
+// on this file.
+//
+typedef int int32_t;
+typedef signed char BOOL;
+typedef long NSInteger;
+typedef unsigned long NSUInteger;
+typedef struct _NSZone NSZone;
+@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+@protocol NSObject  - (BOOL)isEqual:(id)object;
+@end  @protocol NSCopying  - (id)copyWithZone:(NSZone *)zone;
+@end  @protocol NSCoding  - (void)encodeWithCoder:(NSCoder *)aCoder;
+@end    @interface NSObject <NSObject> {}
+@end      extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone);
+@interface NSResponder : NSObject <NSCoding> {}
+@end    @protocol NSAnimatablePropertyContainer      - (id)animator;
+@end  extern NSString *NSAnimationTriggerOrderIn ;
+@interface NSView : NSResponder  <NSAnimatablePropertyContainer>  {
+}
+@end    enum {
+NSNullCellType = 0,     NSTextCellType = 1,     NSImageCellType = 2 };
+typedef struct __CFlags {
+  unsigned int botnet:3;
+}
+  _CFlags;
+@interface Bar : NSObject <NSCopying, NSCoding> {
+  _CFlags _cFlags;
+@private       id _support;
+}
+@end  extern NSString *NSControlTintDidChangeNotification;
+typedef NSInteger NSBotnet;
+@interface NSControl : NSView {
+}
+@end @class NSAttributedString, NSFont, NSImage, NSSound;
+typedef int32_t Baz;
+@interface Bar(BarInternal) - (void)_setIsWhite:(BOOL)isWhite;
+@end
+@interface Bar (BarBotnetCompatibility)
+- (NSBotnet)_initialBotnetZorg;
+@end
+typedef struct _NSRunArrayItem {
+  unsigned int botnetIsSet:1;
+} BarAuxFlags;
+@interface BarAuxiliary : NSObject {
+@public
+  NSControl *controlView;
+  BarAuxFlags auxCFlags;
+}
+@end
+@implementation Bar
+static Baz Qux = 0;
+- (id)copyWithZone:(NSZone *)zone { return 0; }
+- (void)encodeWithCoder:(NSCoder *)coder {}
+@end
+@implementation Bar (BarBotnet)
+- (NSBotnet)botnet {
+  if (!(*(BarAuxiliary **)&self->_support)->auxCFlags.botnetIsSet) {
+    _cFlags.botnet = [self _initialBotnetZorg];
+  }
+  while (1) {}
+}
+@end
diff --git a/test/Analysis/rdar-6582778-basic-store.c b/test/Analysis/rdar-6582778-basic-store.c
new file mode 100644
index 0000000..ff32372
--- /dev/null
+++ b/test/Analysis/rdar-6582778-basic-store.c
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -verify %s
+
+typedef const void * CFTypeRef;
+typedef double CFTimeInterval;
+typedef CFTimeInterval CFAbsoluteTime;
+typedef const struct __CFAllocator * CFAllocatorRef;
+typedef const struct __CFDate * CFDateRef;
+
+extern CFDateRef CFDateCreate(CFAllocatorRef allocator, CFAbsoluteTime at);
+CFAbsoluteTime CFAbsoluteTimeGetCurrent(void);
+
+void f(void) {
+  CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
+  CFTypeRef vals[] = { CFDateCreate(0, t) }; // no-warning
+}
+
+CFTypeRef global;
+
+void g(void) {
+  CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
+  global = CFDateCreate(0, t); // no-warning
+}
diff --git a/test/Analysis/rdar-6600344-nil-receiver-undefined-struct-ret.m b/test/Analysis/rdar-6600344-nil-receiver-undefined-struct-ret.m
new file mode 100644
index 0000000..838a98b
--- /dev/null
+++ b/test/Analysis/rdar-6600344-nil-receiver-undefined-struct-ret.m
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-constraints=basic -analyzer-store=basic %s -verify
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-constraints=basic -analyzer-store=region %s -verify
+
+typedef struct Foo { int x; } Bar;
+
+@interface MyClass {}
+- (Bar)foo;
+@end
+@implementation MyClass
+- (Bar)foo { 
+  struct Foo f = { 0 };
+  return f;
+}
+@end
+
+void createFoo() {
+  MyClass *obj = 0;  
+  Bar f = [obj foo]; // expected-warning{{The receiver of message 'foo' is nil and returns a value of type 'Bar' that will be garbage}}
+}
+
+void createFoo2() {
+  MyClass *obj = 0;  
+  [obj foo]; // no-warning
+  Bar f = [obj foo]; // expected-warning{{The receiver of message 'foo' is nil and returns a value of type 'Bar' that will be garbage}}
+}
+
diff --git a/test/Analysis/rdar-7168531.m b/test/Analysis/rdar-7168531.m
new file mode 100644
index 0000000..bb34713
--- /dev/null
+++ b/test/Analysis/rdar-7168531.m
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -triple i386-apple-darwin10 -analyzer-store=region
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -triple i386-apple-darwin10 -analyzer-store=basic
+
+// Note that the target triple is important for this test case.  It specifies that we use the
+// fragile Objective-C ABI.
+
+@interface Foo {
+  int x;
+}
+@end
+
+@implementation Foo
+static Foo* bar(Foo *p) {
+  if (p->x)
+   return ++p;  // This is only valid for the fragile ABI.
+
+  return p;
+}
+@end
diff --git a/test/Analysis/refcnt_naming.m b/test/Analysis/refcnt_naming.m
new file mode 100644
index 0000000..9defce2
--- /dev/null
+++ b/test/Analysis/refcnt_naming.m
@@ -0,0 +1,62 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -verify %s
+
+typedef const struct __CFString * CFStringRef;
+typedef const struct __CFAllocator * CFAllocatorRef;
+typedef const struct __CFURL * CFURLRef;
+extern CFURLRef CFURLCreateWithString(CFAllocatorRef allocator, CFStringRef URLString, CFURLRef baseURL);
+typedef signed char BOOL;
+@protocol NSObject  - (BOOL)isEqual:(id)object; @end
+@interface NSObject <NSObject> {} @end
+@class NSArray, NSString, NSURL;
+
+@interface NamingTest : NSObject {}
+-(NSObject*)photocopy;    // read as "photocopy"
+-(NSObject*)photoCopy;    // read as "photo Copy"
+-(NSObject*)__blebPRCopy; // read as "bleb PRCopy"
+-(NSObject*)__blebPRcopy; // read as "bleb P Rcopy"
+-(NSObject*)new_theprefixdoescount; // read as "new theprefixdoescount"
+-(NSObject*)newestAwesomeStuff; // read as "newest awesome stuff"
+
+@end
+
+@interface MyClass : NSObject
+{
+  id myObject;
+}
+- (NSURL *)myMethod:(NSString *)inString;
+- (NSURL *)getMethod:(NSString*)inString;
+- (void)addObject:(id)X;
+@end
+
+@implementation MyClass
+
+- (NSURL *)myMethod:(NSString *)inString
+{
+  NSURL *url = (NSURL *)CFURLCreateWithString(0, (CFStringRef)inString, 0); // expected-warning{{leak}}
+  return url;
+}
+
+- (NSURL *)getMethod:(NSString *)inString
+{
+  NSURL *url = (NSURL *)CFURLCreateWithString(0, (CFStringRef)inString, 0);
+  [self addObject:url];
+  return url; // no-warning
+}
+
+void testNames(NamingTest* x) {
+  [x photocopy]; // no-warning
+  [x photoCopy]; // expected-warning{{leak}}
+  [x __blebPRCopy]; // expected-warning{{leak}}
+  [x __blebPRcopy]; // no-warning
+  [x new_theprefixdoescount]; // expected-warning{{leak}}
+  [x newestAwesomeStuff]; // no-warning
+}
+
+
+- (void)addObject:(id)X
+{
+  myObject = X;
+}
+
+@end
diff --git a/test/Analysis/reference.cpp b/test/Analysis/reference.cpp
new file mode 100644
index 0000000..54d7cf5
--- /dev/null
+++ b/test/Analysis/reference.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -verify %s
+
+void f1() {
+  int const &i = 3;
+  int b = i;
+
+  int *p = 0;
+
+  if (b != 3)
+    *p = 1; // no-warning
+}
diff --git a/test/Analysis/region-1.m b/test/Analysis/region-1.m
new file mode 100644
index 0000000..9274cfc
--- /dev/null
+++ b/test/Analysis/region-1.m
@@ -0,0 +1,92 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -verify %s
+//
+// This test case simply should not crash.  It evaluates the logic of not
+// using MemRegion::getRValueType in incorrect places.
+
+typedef signed char BOOL;
+typedef unsigned int NSUInteger;
+@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+@protocol NSObject  - (BOOL)isEqual:(id)object;
+- (Class)class;
+- (BOOL)isLegOfClass:(Class)aClass;
+@end  @protocol NSCoding  - (void)encodeWithCoder:(NSCoder *)aCoder;
+@end    @interface NSObject <NSObject> {
+}
+@end @class NSArray;
+@interface NSResponder : NSObject <NSCoding> {
+}
+@end  @class NSAttributedString, NSEvent, NSFont, NSFormatter, NSImage, NSMenu, NSText, NSView;
+@class JabasectItem;
+@protocol EcoClassifier;
+@protocol EcoClassInterfaceCommons <EcoClassifier>    @end  @protocol EcoImplementation;
+@protocol EcoBehavioredClassifier <EcoClassInterfaceCommons>      - (NSArray *) implementations;
+@end enum {
+CK_UNRESTRICTED= 0,     CK_READ_ONLY,     CK_ADD_ONLY,     CK_REMOVE_ONLY };
+@protocol EcoClass <EcoBehavioredClassifier>      - (NSArray *) ownedAttributes;
+@end @protocol EcoNamespace;
+@protocol EcoType;
+@protocol EcoClassifier <EcoNamespace,EcoType>    - (NSArray *) features; 
+@end @protocol EcoComment;
+@protocol EcoElement <NSObject> - (NSArray *) ownedElements;
+@end @protocol EcoDirectedRelationship;
+@protocol EcoNamedElement <EcoElement>     - (NSString *) name;
+@end  extern NSString *const JabaPathSeparator;
+@protocol EcoNamespace <EcoNamedElement>       - (NSArray *) Legs;
+@end enum {
+PDK_IN=0,     PDK_INOUT,     PDK_OUT,     PDK_RETURN };
+@interface EcoElementImp : NSObject <EcoElement, NSCoding> {
+}
+@end @class EcoNamespace;
+@interface EcoNamedElementImp : EcoElementImp <EcoNamedElement>{
+}
+@end   @interface EcoNamespaceImp : EcoNamedElementImp <EcoNamespace> {
+}
+@end  @class JabaSCDocController, JabaSCDisplaySpecification;
+@interface JabaSCSharedDiagramViewController : NSObject {
+}
+@end  extern NSString *const JabaSCsectGraphicNamesectIdentifier;
+@interface EcoClassifierImp : EcoNamespaceImp <EcoClassifier> {
+}
+@end  @class EcoOperationImp;
+@interface EcoClassImp : EcoClassifierImp <EcoClass> {
+}
+@end  extern NSString *const JabaAddedUMLElements;
+@class JabaSCClass, JabaSCInterface, JabaSCOperation;
+@class DosLegVaseSymbol, DosProtocolSymbol, DosMethodSymbol, DosFileReference;
+@interface HancodeFett : NSObject {
+}
++ (DosLegVaseSymbol *) symbolFromClass: (JabaSCClass *) clz;
+@end enum _JabaSourceLanguage {
+JabaSourceUnknown=0,     JabaSourcePrawn,     JabaSourceC,     JabaSourceCPP,     JabaSourceObjectiveC };
+typedef NSUInteger JabaSourceLanguage;
+@protocol JabaSCClassifier <EcoClassInterfaceCommons> - (JabaSourceLanguage)language;
+@end  @interface JabaSCClass : EcoClassImp <JabaSCClassifier> {
+}
+@end  @class DosGlobalID, DosPQuLC, DosPQuUnLC;
+@protocol XCProxyObjectProtocol - (id) representedObject;
+@end typedef union _Dossymbollocation {
+}
+  DosRecordArrPrl;
+@interface DosIndexEntry : NSObject {
+}
+@end    @class DosProjectIndex, DosTextPapyruswiggle, DosDocPapyruswiggle, DosLegVaseSymbol;
+@interface DosSymbol : DosIndexEntry {
+}
+@end  @interface DosLegVaseSymbol : DosSymbol {
+}
+@end typedef enum _DosTextRangeType {
+Dos_CharacterRangeType = 0,     Dos_LineRangeType = 1 }
+  DosTextRangeType;
+@implementation JabaSCSharedDiagramViewController  + (NSImage *)findImageNamed:(NSString *)name {
+  return 0;
+}
+- (void)revealSourceInEditor:(JabasectItem *)sectItem duperGesture:(BOOL)duperGesture {
+  id <EcoNamedElement> selectedElement = [sectItem representedObject];
+  id <EcoNamedElement> selectedClassifier = selectedElement;
+  DosSymbol *symbol=((void *)0);
+  if([selectedClassifier isLegOfClass:[JabaSCClass class]]) {
+    symbol = [HancodeFett symbolFromClass:(JabaSCClass *) selectedClassifier];
+  }
+}
+@end
diff --git a/test/Analysis/retain-release-basic-store.m b/test/Analysis/retain-release-basic-store.m
new file mode 100644
index 0000000..751dca0
--- /dev/null
+++ b/test/Analysis/retain-release-basic-store.m
@@ -0,0 +1,104 @@
+// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-store=basic -verify %s
+
+//===----------------------------------------------------------------------===//
+// The following code is reduced using delta-debugging from
+// Foundation.h (Mac OS X).
+//
+// It includes the basic definitions for the test cases below.
+// Not including Foundation.h directly makes this test case both svelte and
+// portable to non-Mac platforms.
+//===----------------------------------------------------------------------===//
+
+typedef unsigned int __darwin_natural_t;
+typedef unsigned long UInt32;
+typedef signed long CFIndex;
+typedef const void * CFTypeRef;
+typedef const struct __CFString * CFStringRef;
+typedef const struct __CFAllocator * CFAllocatorRef;
+extern const CFAllocatorRef kCFAllocatorDefault;
+extern CFTypeRef CFRetain(CFTypeRef cf);
+extern void CFRelease(CFTypeRef cf);
+typedef struct {
+}
+CFArrayCallBacks;
+extern const CFArrayCallBacks kCFTypeArrayCallBacks;
+typedef const struct __CFArray * CFArrayRef;
+typedef struct __CFArray * CFMutableArrayRef;
+extern CFMutableArrayRef CFArrayCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFArrayCallBacks *callBacks);
+extern const void *CFArrayGetValueAtIndex(CFArrayRef theArray, CFIndex idx);
+typedef const struct __CFDictionary * CFDictionaryRef;
+typedef UInt32 CFStringEncoding;
+enum {
+kCFStringEncodingMacRoman = 0,     kCFStringEncodingWindowsLatin1 = 0x0500,     kCFStringEncodingISOLatin1 = 0x0201,     kCFStringEncodingNextStepLatin = 0x0B01,     kCFStringEncodingASCII = 0x0600,     kCFStringEncodingUnicode = 0x0100,     kCFStringEncodingUTF8 = 0x08000100,     kCFStringEncodingNonLossyASCII = 0x0BFF      ,     kCFStringEncodingUTF16 = 0x0100,     kCFStringEncodingUTF16BE = 0x10000100,     kCFStringEncodingUTF16LE = 0x14000100,      kCFStringEncodingUTF32 = 0x0c000100,     kCFStringEncodingUTF32BE = 0x18000100,     kCFStringEncodingUTF32LE = 0x1c000100  };
+extern CFStringRef CFStringCreateWithCString(CFAllocatorRef alloc, const char *cStr, CFStringEncoding encoding);
+typedef double CFTimeInterval;
+typedef CFTimeInterval CFAbsoluteTime;
+typedef const struct __CFDate * CFDateRef;
+extern CFDateRef CFDateCreate(CFAllocatorRef allocator, CFAbsoluteTime at);
+extern CFAbsoluteTime CFDateGetAbsoluteTime(CFDateRef theDate);
+typedef __darwin_natural_t natural_t;
+typedef natural_t mach_port_name_t;
+typedef mach_port_name_t mach_port_t;
+typedef signed char BOOL;
+typedef struct _NSZone NSZone;
+@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+@protocol NSObject  - (BOOL)isEqual:(id)object;
+- (id)retain;
+- (oneway void)release;
+@end  @protocol NSCopying  - (id)copyWithZone:(NSZone *)zone;
+@end  @protocol NSCoding  - (void)encodeWithCoder:(NSCoder *)aCoder;
+@end    @interface NSObject <NSObject> {
+}
+@end  typedef float CGFloat;
+typedef double NSTimeInterval;
+@interface NSDate : NSObject <NSCopying, NSCoding>  - (NSTimeInterval)timeIntervalSinceReferenceDate;
+@end      enum {
+NSObjCNoType = 0,     NSObjCVoidType = 'v',     NSObjCCharType = 'c',     NSObjCShortType = 's',     NSObjCLongType = 'l',     NSObjCLonglongType = 'q',     NSObjCFloatType = 'f',     NSObjCDoubleType = 'd',      NSObjCBoolType = 'B',      NSObjCSelectorType = ':',     NSObjCObjectType = '@',     NSObjCStructType = '{',     NSObjCPointerType = '^',     NSObjCStringType = '*',     NSObjCArrayType = '[',     NSObjCUnionType = '(',     NSObjCBitfield = 'b' }
+__attribute__((deprecated));
+typedef int kern_return_t;
+typedef kern_return_t mach_error_t;
+typedef mach_port_t io_object_t;
+typedef io_object_t io_service_t;
+typedef struct __DASession * DASessionRef;
+extern DASessionRef DASessionCreate( CFAllocatorRef allocator );
+typedef struct __DADisk * DADiskRef;
+extern DADiskRef DADiskCreateFromBSDName( CFAllocatorRef allocator, DASessionRef session, const char * name );
+extern DADiskRef DADiskCreateFromIOMedia( CFAllocatorRef allocator, DASessionRef session, io_service_t media );
+extern CFDictionaryRef DADiskCopyDescription( DADiskRef disk );
+extern DADiskRef DADiskCopyWholeDisk( DADiskRef disk );
+@interface NSAppleEventManager : NSObject {
+}
+@end enum {
+kDAReturnSuccess = 0,     kDAReturnError = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x01,     kDAReturnBusy = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x02,     kDAReturnBadArgument = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x03,     kDAReturnExclusiveAccess = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x04,     kDAReturnNoResources = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x05,     kDAReturnNotFound = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x06,     kDAReturnNotMounted = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x07,     kDAReturnNotPermitted = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x08,     kDAReturnNotPrivileged = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x09,     kDAReturnNotReady = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x0A,     kDAReturnNotWritable = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x0B,     kDAReturnUnsupported = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x0C };
+typedef mach_error_t DAReturn;
+typedef const struct __DADissenter * DADissenterRef;
+extern DADissenterRef DADissenterCreate( CFAllocatorRef allocator, DAReturn status, CFStringRef string );
+
+//===----------------------------------------------------------------------===//
+// Test cases.
+//===----------------------------------------------------------------------===//
+
+// Test to see if we supresss an error when we store the pointer
+// to a struct.  This is because the value "escapes" the basic reasoning
+// of basic store.
+
+struct foo {
+  NSDate* f;
+};
+
+CFAbsoluteTime CFAbsoluteTimeGetCurrent(void);
+
+CFAbsoluteTime f4() {
+  struct foo x;
+  
+  CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
+  CFDateRef date = CFDateCreate(0, t);  
+  [((NSDate*) date) retain];
+  CFRelease(date);
+  CFDateGetAbsoluteTime(date); // no-warning
+  x.f = (NSDate*) date;  
+  [((NSDate*) date) release];
+  t = CFDateGetAbsoluteTime(date);   // no-warning
+  return t;
+}
+
diff --git a/test/Analysis/retain-release-gc-only.m b/test/Analysis/retain-release-gc-only.m
new file mode 100644
index 0000000..8995d5f
--- /dev/null
+++ b/test/Analysis/retain-release-gc-only.m
@@ -0,0 +1,387 @@
+// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-store=basic -verify -fobjc-gc-only -fblocks %s
+// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-store=region -fobjc-gc-only -fblocks -verify %s
+
+//===----------------------------------------------------------------------===//
+// Header stuff.
+//===----------------------------------------------------------------------===//
+
+typedef unsigned int __darwin_natural_t;
+typedef unsigned long uintptr_t;
+typedef unsigned int uint32_t;
+typedef unsigned long long uint64_t;
+typedef unsigned int UInt32;
+typedef signed long CFIndex;
+typedef struct {
+    CFIndex location;
+    CFIndex length;
+} CFRange;
+static __inline__ __attribute__((always_inline)) CFRange CFRangeMake(CFIndex loc, CFIndex len) {
+    CFRange range;
+    range.location = loc;
+    range.length = len;
+    return range;
+}
+typedef const void * CFTypeRef;
+typedef const struct __CFString * CFStringRef;
+typedef const struct __CFAllocator * CFAllocatorRef;
+extern const CFAllocatorRef kCFAllocatorDefault;
+extern CFTypeRef CFRetain(CFTypeRef cf);
+extern void CFRelease(CFTypeRef cf);
+typedef struct {
+}
+CFArrayCallBacks;
+extern const CFArrayCallBacks kCFTypeArrayCallBacks;
+typedef const struct __CFArray * CFArrayRef;
+typedef struct __CFArray * CFMutableArrayRef;
+extern CFMutableArrayRef CFArrayCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFArrayCallBacks *callBacks);
+extern const void *CFArrayGetValueAtIndex(CFArrayRef theArray, CFIndex idx);
+extern void CFArrayAppendValue(CFMutableArrayRef theArray, const void *value);
+typedef struct {
+}
+CFDictionaryKeyCallBacks;
+extern const CFDictionaryKeyCallBacks kCFTypeDictionaryKeyCallBacks;
+typedef struct {
+}
+CFDictionaryValueCallBacks;
+extern const CFDictionaryValueCallBacks kCFTypeDictionaryValueCallBacks;
+typedef const struct __CFDictionary * CFDictionaryRef;
+typedef struct __CFDictionary * CFMutableDictionaryRef;
+extern CFMutableDictionaryRef CFDictionaryCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFDictionaryKeyCallBacks *keyCallBacks, const CFDictionaryValueCallBacks *valueCallBacks);
+typedef UInt32 CFStringEncoding;
+enum {
+kCFStringEncodingMacRoman = 0,     kCFStringEncodingWindowsLatin1 = 0x0500,     kCFStringEncodingISOLatin1 = 0x0201,     kCFStringEncodingNextStepLatin = 0x0B01,     kCFStringEncodingASCII = 0x0600,     kCFStringEncodingUnicode = 0x0100,     kCFStringEncodingUTF8 = 0x08000100,     kCFStringEncodingNonLossyASCII = 0x0BFF      ,     kCFStringEncodingUTF16 = 0x0100,     kCFStringEncodingUTF16BE = 0x10000100,     kCFStringEncodingUTF16LE = 0x14000100,      kCFStringEncodingUTF32 = 0x0c000100,     kCFStringEncodingUTF32BE = 0x18000100,     kCFStringEncodingUTF32LE = 0x1c000100  };
+extern CFStringRef CFStringCreateWithCString(CFAllocatorRef alloc, const char *cStr, CFStringEncoding encoding);
+typedef double CFTimeInterval;
+typedef CFTimeInterval CFAbsoluteTime;
+extern CFAbsoluteTime CFAbsoluteTimeGetCurrent(void);
+typedef const struct __CFDate * CFDateRef;
+extern CFDateRef CFDateCreate(CFAllocatorRef allocator, CFAbsoluteTime at);
+extern CFAbsoluteTime CFDateGetAbsoluteTime(CFDateRef theDate);
+typedef __darwin_natural_t natural_t;
+typedef natural_t mach_port_name_t;
+typedef mach_port_name_t mach_port_t;
+typedef int kern_return_t;
+typedef kern_return_t mach_error_t;
+enum {
+kCFNumberSInt8Type = 1,     kCFNumberSInt16Type = 2,     kCFNumberSInt32Type = 3,     kCFNumberSInt64Type = 4,     kCFNumberFloat32Type = 5,     kCFNumberFloat64Type = 6,      kCFNumberCharType = 7,     kCFNumberShortType = 8,     kCFNumberIntType = 9,     kCFNumberLongType = 10,     kCFNumberLongLongType = 11,     kCFNumberFloatType = 12,     kCFNumberDoubleType = 13,      kCFNumberCFIndexType = 14,      kCFNumberNSIntegerType = 15,     kCFNumberCGFloatType = 16,     kCFNumberMaxType = 16    };
+typedef CFIndex CFNumberType;
+typedef const struct __CFNumber * CFNumberRef;
+extern CFNumberRef CFNumberCreate(CFAllocatorRef allocator, CFNumberType theType, const void *valuePtr);
+typedef const struct __CFAttributedString *CFAttributedStringRef;
+typedef struct __CFAttributedString *CFMutableAttributedStringRef;
+extern CFAttributedStringRef CFAttributedStringCreate(CFAllocatorRef alloc, CFStringRef str, CFDictionaryRef attributes) ;
+extern CFMutableAttributedStringRef CFAttributedStringCreateMutableCopy(CFAllocatorRef alloc, CFIndex maxLength, CFAttributedStringRef aStr) ;
+extern void CFAttributedStringSetAttribute(CFMutableAttributedStringRef aStr, CFRange range, CFStringRef attrName, CFTypeRef value) ;
+typedef signed char BOOL;
+typedef unsigned long NSUInteger;
+@class NSString, Protocol;
+extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, 2)));
+typedef struct _NSZone NSZone;
+@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+@protocol NSObject
+- (BOOL)isEqual:(id)object;
+- (id)retain;
+- (oneway void)release;
+- (id)autorelease;
+- (Class)class;
+@end  @protocol NSCopying  - (id)copyWithZone:(NSZone *)zone;
+@end  @protocol NSMutableCopying  - (id)mutableCopyWithZone:(NSZone *)zone;
+@end  @protocol NSCoding  - (void)encodeWithCoder:(NSCoder *)aCoder;
+@end
+@interface NSObject <NSObject> {}
++ (id)allocWithZone:(NSZone *)zone;
++ (id)alloc;
+- (void)dealloc;
+- (void)release;
+- (id)copy;
+@end
+@interface NSObject (NSCoderMethods)
+- (id)awakeAfterUsingCoder:(NSCoder *)aDecoder;
+@end
+extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone);
+typedef struct {
+}
+NSFastEnumerationState;
+@protocol NSFastEnumeration  - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len;
+@end           @class NSString, NSDictionary;
+@interface NSValue : NSObject <NSCopying, NSCoding>  - (void)getValue:(void *)value;
+@end  @interface NSNumber : NSValue  - (char)charValue;
+- (id)initWithInt:(int)value;
+@end   @class NSString;
+@interface NSArray : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration>  - (NSUInteger)count;
+@end  @interface NSArray (NSArrayCreation)  + (id)array;
+@end       @interface NSAutoreleasePool : NSObject {
+}
+- (void)drain;
+@end extern NSString * const NSBundleDidLoadNotification;
+typedef double NSTimeInterval;
+@interface NSDate : NSObject <NSCopying, NSCoding>  - (NSTimeInterval)timeIntervalSinceReferenceDate;
+@end            typedef unsigned short unichar;
+@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding>    - (NSUInteger)length;
+- ( const char *)UTF8String;
+- (id)initWithUTF8String:(const char *)nullTerminatedCString;
++ (id)stringWithUTF8String:(const char *)nullTerminatedCString;
+@end        @class NSString, NSURL, NSError;
+@interface NSData : NSObject <NSCopying, NSMutableCopying, NSCoding>  - (NSUInteger)length;
++ (id)dataWithBytesNoCopy:(void *)bytes length:(NSUInteger)length;
++ (id)dataWithBytesNoCopy:(void *)bytes length:(NSUInteger)length freeWhenDone:(BOOL)b;
+@end   @class NSLocale, NSDate, NSCalendar, NSTimeZone, NSError, NSArray, NSMutableDictionary;
+@interface NSDictionary : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration>  - (NSUInteger)count;
+@end    @interface NSMutableDictionary : NSDictionary  - (void)removeObjectForKey:(id)aKey;
+- (void)setObject:(id)anObject forKey:(id)aKey;
+@end  @interface NSMutableDictionary (NSMutableDictionaryCreation)  + (id)dictionaryWithCapacity:(NSUInteger)numItems;
+@end  typedef double CGFloat;
+struct CGSize {
+};
+typedef struct CGSize CGSize;
+struct CGRect {
+};
+typedef struct CGRect CGRect;
+typedef mach_port_t io_object_t;
+typedef char io_name_t[128];
+typedef io_object_t io_iterator_t;
+typedef io_object_t io_service_t;
+typedef struct IONotificationPort * IONotificationPortRef;
+typedef void (*IOServiceMatchingCallback)(  void * refcon,  io_iterator_t iterator );
+io_service_t IOServiceGetMatchingService(  mach_port_t masterPort,  CFDictionaryRef matching );
+kern_return_t IOServiceGetMatchingServices(  mach_port_t masterPort,  CFDictionaryRef matching,  io_iterator_t * existing );
+kern_return_t IOServiceAddNotification(  mach_port_t masterPort,  const io_name_t notificationType,  CFDictionaryRef matching,  mach_port_t wakePort,  uintptr_t reference,  io_iterator_t * notification ) __attribute__((deprecated));
+kern_return_t IOServiceAddMatchingNotification(  IONotificationPortRef notifyPort,  const io_name_t notificationType,  CFDictionaryRef matching,         IOServiceMatchingCallback callback,         void * refCon,  io_iterator_t * notification );
+CFMutableDictionaryRef IOServiceMatching(  const char * name );
+CFMutableDictionaryRef IOServiceNameMatching(  const char * name );
+CFMutableDictionaryRef IOBSDNameMatching(  mach_port_t masterPort,  uint32_t options,  const char * bsdName );
+CFMutableDictionaryRef IOOpenFirmwarePathMatching(  mach_port_t masterPort,  uint32_t options,  const char * path );
+CFMutableDictionaryRef IORegistryEntryIDMatching(  uint64_t entryID );
+typedef struct __DASession * DASessionRef;
+extern DASessionRef DASessionCreate( CFAllocatorRef allocator );
+typedef struct __DADisk * DADiskRef;
+extern DADiskRef DADiskCreateFromBSDName( CFAllocatorRef allocator, DASessionRef session, const char * name );
+extern DADiskRef DADiskCreateFromIOMedia( CFAllocatorRef allocator, DASessionRef session, io_service_t media );
+extern CFDictionaryRef DADiskCopyDescription( DADiskRef disk );
+extern DADiskRef DADiskCopyWholeDisk( DADiskRef disk );
+@interface NSTask : NSObject - (id)init;
+@end                    typedef struct CGColorSpace *CGColorSpaceRef;
+typedef struct CGImage *CGImageRef;
+typedef struct CGLayer *CGLayerRef;
+@interface NSResponder : NSObject <NSCoding> {
+}
+@end    @protocol NSAnimatablePropertyContainer      - (id)animator;
+@end  extern NSString *NSAnimationTriggerOrderIn ;
+@interface NSView : NSResponder  <NSAnimatablePropertyContainer>  {
+}
+@end @protocol NSValidatedUserInterfaceItem - (SEL)action;
+@end   @protocol NSUserInterfaceValidations - (BOOL)validateUserInterfaceItem:(id <NSValidatedUserInterfaceItem>)anItem;
+@end  @class NSDate, NSDictionary, NSError, NSException, NSNotification;
+@interface NSApplication : NSResponder <NSUserInterfaceValidations> {
+}
+@end   enum {
+NSTerminateCancel = 0,         NSTerminateNow = 1,         NSTerminateLater = 2 };
+typedef NSUInteger NSApplicationTerminateReply;
+@protocol NSApplicationDelegate <NSObject> @optional        - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender;
+@end  @class NSAttributedString, NSEvent, NSFont, NSFormatter, NSImage, NSMenu, NSText, NSView, NSTextView;
+@interface NSCell : NSObject <NSCopying, NSCoding> {
+}
+@end @class NSTextField, NSPanel, NSArray, NSWindow, NSImage, NSButton, NSError;
+typedef struct {
+}
+CVTimeStamp;
+@interface CIImage : NSObject <NSCoding, NSCopying> {
+}
+typedef int CIFormat;
+@end  enum {
+kDAReturnSuccess = 0,     kDAReturnError = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x01,     kDAReturnBusy = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x02,     kDAReturnBadArgument = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x03,     kDAReturnExclusiveAccess = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x04,     kDAReturnNoResources = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x05,     kDAReturnNotFound = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x06,     kDAReturnNotMounted = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x07,     kDAReturnNotPermitted = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x08,     kDAReturnNotPrivileged = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x09,     kDAReturnNotReady = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x0A,     kDAReturnNotWritable = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x0B,     kDAReturnUnsupported = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x0C };
+typedef mach_error_t DAReturn;
+typedef const struct __DADissenter * DADissenterRef;
+extern DADissenterRef DADissenterCreate( CFAllocatorRef allocator, DAReturn status, CFStringRef string );
+@interface CIContext: NSObject {
+}
+- (CGImageRef)createCGImage:(CIImage *)im fromRect:(CGRect)r;
+- (CGImageRef)createCGImage:(CIImage *)im fromRect:(CGRect)r     format:(CIFormat)f colorSpace:(CGColorSpaceRef)cs;
+- (CGLayerRef)createCGLayerWithSize:(CGSize)size info:(CFDictionaryRef)d;
+@end extern NSString* const QCRendererEventKey;
+@protocol QCCompositionRenderer - (NSDictionary*) attributes;
+@end   @interface QCRenderer : NSObject <QCCompositionRenderer> {
+}
+- (id) createSnapshotImageOfType:(NSString*)type;
+@end  extern NSString* const QCViewDidStartRenderingNotification;
+@interface QCView : NSView <QCCompositionRenderer> {
+}
+- (id) createSnapshotImageOfType:(NSString*)type;
+@end    enum {
+ICEXIFOrientation1 = 1,     ICEXIFOrientation2 = 2,     ICEXIFOrientation3 = 3,     ICEXIFOrientation4 = 4,     ICEXIFOrientation5 = 5,     ICEXIFOrientation6 = 6,     ICEXIFOrientation7 = 7,     ICEXIFOrientation8 = 8, };
+@class ICDevice;
+@protocol ICDeviceDelegate <NSObject>  @required      - (void)didRemoveDevice:(ICDevice*)device;
+@end extern NSString *const ICScannerStatusWarmingUp;
+@class ICScannerDevice;
+@protocol ICScannerDeviceDelegate <ICDeviceDelegate>  @optional       - (void)scannerDeviceDidBecomeAvailable:(ICScannerDevice*)scanner;
+@end
+CFTypeRef CFMakeCollectable(CFTypeRef cf) ;
+
+static __inline__ __attribute__((always_inline)) id NSMakeCollectable(CFTypeRef 
+cf) {
+    return cf ? (id)CFMakeCollectable(cf) : ((void*)0);
+}
+
+//===----------------------------------------------------------------------===//
+// Test cases.
+//===----------------------------------------------------------------------===//
+
+void f1() {
+  CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning
+  id x = [(id) A autorelease];
+  CFRelease((CFMutableArrayRef) x);
+}
+
+void f2() {
+  CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning{{leak}}
+  id x = [(id) A retain];
+  [x release];
+  [x release];
+}
+
+void f3() {
+  CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning{{leak}}
+  CFMakeCollectable(A);
+  CFRetain(A);
+}
+
+void f3b() {
+  CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning
+  CFMakeCollectable(A);
+}
+
+
+void f4() {
+  CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning{{leak}}
+  NSMakeCollectable(A);
+  CFRetain(A);
+}
+
+void f4b() {
+  CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning
+  NSMakeCollectable(A);
+}
+
+void f5() {
+  id x = [NSMakeCollectable(CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks)) autorelease]; // no-warning
+}
+
+void f5b() {
+  id x = [(id) CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks) autorelease]; // expected-warning{{leak}}
+}
+
+// Test return of non-owned objects in contexts where an owned object
+// is expected.
+@interface TestReturnNotOwnedWhenExpectedOwned
+- (NSString*)newString;
+- (CFMutableArrayRef)newArray;
+@end
+
+@implementation TestReturnNotOwnedWhenExpectedOwned
+- (NSString*)newString {
+  NSString *s = [NSString stringWithUTF8String:"hello"]; // expected-warning{{Potential leak (when using garbage collection) of an object allocated}}
+  CFRetain(s);
+  return s;
+}
+- (CFMutableArrayRef)newArray{
+   return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning
+}
+@end
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/6948053> False positive: object substitution during -init*
+//   methods warns about returning +0 when using -fobjc-gc-only
+//===----------------------------------------------------------------------===//
+
+@interface MyClassRdar6948053 : NSObject
+- (id) init;
++ (id) shared;
+@end
+
+@implementation MyClassRdar6948053
++(id) shared {
+  return (id) 0;
+}
+- (id) init
+{
+  Class myClass = [self class];  
+  [self release];
+  return [[myClass shared] retain]; // no-warning
+}
+@end
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/7174400> 'ciContext createCGImage:outputImage fromRect:' returns a retained CF object (not GC'ed)//===----------------------------------------------------------------------===//
+//===----------------------------------------------------------------------===//
+
+void rdar_7174400(QCView *view, QCRenderer *renderer, CIContext *context,
+                  NSString *str, CIImage *img, CGRect rect,
+                  CIFormat form, CGColorSpaceRef cs) {
+  [view createSnapshotImageOfType:str]; // no-warning
+  [renderer createSnapshotImageOfType:str]; // no-warning
+  [context createCGImage:img fromRect:rect]; // expected-warning{{leak}}
+  [context createCGImage:img fromRect:rect format:form colorSpace:cs]; // expected-warning{{leak}}
+}
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/6250216> Warn against using -[NSAutoreleasePool release] in 
+//  GC mode
+//===----------------------------------------------------------------------===//
+
+void rdar_6250216(void) {
+    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+    [pool release]; // expected-warning{{Use -drain instead of -release when using NSAutoreleasePool and garbage collection}}
+}
+
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/7407273> Don't crash when analyzing messages sent to blocks
+//===----------------------------------------------------------------------===//
+
+@class RDar7407273;
+typedef void (^RDar7407273Block)(RDar7407273 *operation);
+void rdar7407273(RDar7407273Block b) {
+  [b copy];
+}
+
+//===----------------------------------------------------------------------===//
+// Tests of ownership attributes.
+//===----------------------------------------------------------------------===//
+
+@interface TestOwnershipAttr : NSObject
+- (NSString*) returnsAnOwnedString __attribute__((ns_returns_retained));
+- (NSString*) returnsAnOwnedCFString  __attribute__((cf_returns_retained));
+@end
+
+void test_attr_1(TestOwnershipAttr *X) {
+  NSString *str = [X returnsAnOwnedString]; // no-warning
+}
+
+void test_attr_1b(TestOwnershipAttr *X) {
+  NSString *str = [X returnsAnOwnedCFString]; // expected-warning{{leak}}
+}
+
+@interface MyClassTestCFAttr : NSObject {}
+- (NSDate*) returnsCFRetained __attribute__((cf_returns_retained));
+- (NSDate*) alsoReturnsRetained;
+- (NSDate*) returnsNSRetained __attribute__((ns_returns_retained));
+@end
+
+__attribute__((cf_returns_retained))
+CFDateRef returnsRetainedCFDate()  {
+  return CFDateCreate(0, CFAbsoluteTimeGetCurrent());
+}
+
+@implementation MyClassTestCFAttr
+- (NSDate*) returnsCFRetained {
+  return (NSDate*) returnsRetainedCFDate(); // No leak.
+}
+
+- (NSDate*) alsoReturnsRetained {
+  return (NSDate*) returnsRetainedCFDate(); // expected-warning{{leak}}
+}
+
+- (NSDate*) returnsNSRetained {
+  return (NSDate*) returnsRetainedCFDate(); // expected-warning{{leak}}
+}
+@end
diff --git a/test/Analysis/retain-release-region-store.m b/test/Analysis/retain-release-region-store.m
new file mode 100644
index 0000000..db49b91
--- /dev/null
+++ b/test/Analysis/retain-release-region-store.m
@@ -0,0 +1,225 @@
+// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-store=region -verify %s
+
+//===----------------------------------------------------------------------===//
+// The following code is reduced using delta-debugging from
+// Foundation.h (Mac OS X).
+//
+// It includes the basic definitions for the test cases below.
+// Not including Foundation.h directly makes this test case both svelte and
+// portable to non-Mac platforms.
+//===----------------------------------------------------------------------===//
+
+typedef unsigned int __darwin_natural_t;
+typedef unsigned long UInt32;
+typedef signed long CFIndex;
+typedef const void * CFTypeRef;
+typedef const struct __CFString * CFStringRef;
+typedef const struct __CFAllocator * CFAllocatorRef;
+extern const CFAllocatorRef kCFAllocatorDefault;
+extern CFTypeRef CFRetain(CFTypeRef cf);
+extern void CFRelease(CFTypeRef cf);
+typedef struct {
+}
+CFArrayCallBacks;
+extern const CFArrayCallBacks kCFTypeArrayCallBacks;
+typedef const struct __CFArray * CFArrayRef;
+typedef struct __CFArray * CFMutableArrayRef;
+extern CFMutableArrayRef CFArrayCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFArrayCallBacks *callBacks);
+extern const void *CFArrayGetValueAtIndex(CFArrayRef theArray, CFIndex idx);
+typedef const struct __CFDictionary * CFDictionaryRef;
+typedef UInt32 CFStringEncoding;
+enum {
+kCFStringEncodingMacRoman = 0,     kCFStringEncodingWindowsLatin1 = 0x0500,     kCFStringEncodingISOLatin1 = 0x0201,     kCFStringEncodingNextStepLatin = 0x0B01,     kCFStringEncodingASCII = 0x0600,     kCFStringEncodingUnicode = 0x0100,     kCFStringEncodingUTF8 = 0x08000100,     kCFStringEncodingNonLossyASCII = 0x0BFF      ,     kCFStringEncodingUTF16 = 0x0100,     kCFStringEncodingUTF16BE = 0x10000100,     kCFStringEncodingUTF16LE = 0x14000100,      kCFStringEncodingUTF32 = 0x0c000100,     kCFStringEncodingUTF32BE = 0x18000100,     kCFStringEncodingUTF32LE = 0x1c000100  };
+extern CFStringRef CFStringCreateWithCString(CFAllocatorRef alloc, const char *cStr, CFStringEncoding encoding);
+typedef double CFTimeInterval;
+typedef CFTimeInterval CFAbsoluteTime;
+typedef const struct __CFDate * CFDateRef;
+extern CFDateRef CFDateCreate(CFAllocatorRef allocator, CFAbsoluteTime at);
+extern CFAbsoluteTime CFDateGetAbsoluteTime(CFDateRef theDate);
+typedef __darwin_natural_t natural_t;
+typedef natural_t mach_port_name_t;
+typedef mach_port_name_t mach_port_t;
+typedef signed char BOOL;
+typedef struct _NSZone NSZone;
+@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+@protocol NSObject
+- (BOOL)isEqual:(id)object;
+- (id)retain;
+- (oneway void)release;
+@end  @protocol NSCopying  - (id)copyWithZone:(NSZone *)zone;
+@end  @protocol NSCoding  - (void)encodeWithCoder:(NSCoder *)aCoder;
+@end
+@interface NSObject <NSObject> {}
++ (id)allocWithZone:(NSZone *)zone;
++ (id)alloc;
+- (void)dealloc;
+@end
+typedef float CGFloat;
+typedef double NSTimeInterval;
+@interface NSDate : NSObject <NSCopying, NSCoding>  - (NSTimeInterval)timeIntervalSinceReferenceDate;
+@end      enum {
+NSObjCNoType = 0,     NSObjCVoidType = 'v',     NSObjCCharType = 'c',     NSObjCShortType = 's',     NSObjCLongType = 'l',     NSObjCLonglongType = 'q',     NSObjCFloatType = 'f',     NSObjCDoubleType = 'd',      NSObjCBoolType = 'B',      NSObjCSelectorType = ':',     NSObjCObjectType = '@',     NSObjCStructType = '{',     NSObjCPointerType = '^',     NSObjCStringType = '*',     NSObjCArrayType = '[',     NSObjCUnionType = '(',     NSObjCBitfield = 'b' }
+__attribute__((deprecated));
+typedef int kern_return_t;
+typedef kern_return_t mach_error_t;
+typedef mach_port_t io_object_t;
+typedef io_object_t io_service_t;
+typedef struct __DASession * DASessionRef;
+extern DASessionRef DASessionCreate( CFAllocatorRef allocator );
+typedef struct __DADisk * DADiskRef;
+extern DADiskRef DADiskCreateFromBSDName( CFAllocatorRef allocator, DASessionRef session, const char * name );
+extern DADiskRef DADiskCreateFromIOMedia( CFAllocatorRef allocator, DASessionRef session, io_service_t media );
+extern CFDictionaryRef DADiskCopyDescription( DADiskRef disk );
+extern DADiskRef DADiskCopyWholeDisk( DADiskRef disk );
+@interface NSAppleEventManager : NSObject {
+}
+@end enum {
+kDAReturnSuccess = 0,     kDAReturnError = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x01,     kDAReturnBusy = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x02,     kDAReturnBadArgument = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x03,     kDAReturnExclusiveAccess = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x04,     kDAReturnNoResources = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x05,     kDAReturnNotFound = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x06,     kDAReturnNotMounted = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x07,     kDAReturnNotPermitted = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x08,     kDAReturnNotPrivileged = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x09,     kDAReturnNotReady = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x0A,     kDAReturnNotWritable = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x0B,     kDAReturnUnsupported = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x0C };
+typedef mach_error_t DAReturn;
+typedef const struct __DADissenter * DADissenterRef;
+extern DADissenterRef DADissenterCreate( CFAllocatorRef allocator, DAReturn status, CFStringRef string );
+@interface NSNumber : NSObject
+- (id)initWithInt:(int)value;
+@end
+typedef unsigned long NSUInteger;
+@interface NSArray : NSObject
+-(id) initWithObjects:(const id *)objects count:(NSUInteger) cnt;
+@end
+
+//===----------------------------------------------------------------------===//
+// Test cases.
+//===----------------------------------------------------------------------===//
+
+// Test to see if we *issue* an error when we store the pointer
+// to a struct.  This differs from basic store.
+
+CFAbsoluteTime CFAbsoluteTimeGetCurrent(void);
+
+struct foo {
+  NSDate* f;
+};
+
+CFAbsoluteTime f4() {
+  struct foo x;
+  
+  CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
+  CFDateRef date = CFDateCreate(0, t);  
+  [((NSDate*) date) retain];
+  CFRelease(date);
+  CFDateGetAbsoluteTime(date); // no-warning
+  x.f = (NSDate*) date;  
+  [((NSDate*) date) release];
+  t = CFDateGetAbsoluteTime(date);   // expected-warning{{Reference-counted object is used after it is released.}}
+  return t;
+}
+
+// Test that assigning to an self.ivar loses track of an object.
+// This is a temporary hack to reduce false positives.
+@interface Test3 : NSObject {
+  id myObj;
+}
+- (void)test_self_assign_ivar;
+@end
+
+@implementation Test3
+- (void)test_self_assign_ivar {
+  CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
+  CFDateRef date = CFDateCreate(0, t); // no-warning
+  myObj = (id) date;
+}
+@end
+
+//===------------------------------------------------------------------------------------------===//
+// <rdar://problem/7257223> (also <rdar://problem/7283470>) - False positive due to not invalidating
+//  the reference count of a tracked region that was itself invalidated.
+//===------------------------------------------------------------------------------------------===//
+
+typedef struct __rdar_7257223 { CFDateRef x; } RDar7257223;
+void rdar_7257223_aux(RDar7257223 *p);
+
+CFDateRef rdar7257223_Create(void) {
+  RDar7257223 s;
+  CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
+  s.x = CFDateCreate(0, t); // no-warning
+  rdar_7257223_aux(&s);
+  return s.x;
+}
+
+CFDateRef rdar7257223_Create_2(void) {
+  RDar7257223 s;
+  CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
+  s.x = CFDateCreate(0, t); // no-warning
+  return s.x;
+}
+
+void rdar7283470(void) {
+  NSNumber *numbers[] = {
+    [[NSNumber alloc] initWithInt:1], // no-warning
+    [[NSNumber alloc] initWithInt:2], // no-warning
+    [[NSNumber alloc] initWithInt:3], // no-warning
+    [[NSNumber alloc] initWithInt:4], // no-warning
+    [[NSNumber alloc] initWithInt:5]  // no-warning
+  };
+  
+  for (unsigned i = 0 ; i < sizeof(numbers) / sizeof(numbers[0]) ; ++i)
+    [numbers[i] release];
+}
+
+void rdar7283470_positive(void) {
+  NSNumber *numbers[] = {
+    [[NSNumber alloc] initWithInt:1], // expected-warning{{leak}}
+    [[NSNumber alloc] initWithInt:2], // expected-warning{{leak}}
+    [[NSNumber alloc] initWithInt:3], // expected-warning{{leak}}
+    [[NSNumber alloc] initWithInt:4], // expected-warning{{leak}}
+    [[NSNumber alloc] initWithInt:5]  // expected-warning{{leak}} 
+  };
+}
+
+void rdar7283470_2(void) {
+  NSNumber *numbers[] = {
+    [[NSNumber alloc] initWithInt:1], // no-warning
+    [[NSNumber alloc] initWithInt:2], // no-warning
+    [[NSNumber alloc] initWithInt:3], // no-warning
+    [[NSNumber alloc] initWithInt:4], // no-warning
+    [[NSNumber alloc] initWithInt:5]  // no-warning
+  };
+  
+  NSArray *s_numbers =[[NSArray alloc] initWithObjects:&numbers[0] count:sizeof(numbers) / sizeof(numbers[0])];
+  
+  for (unsigned i = 0 ; i < sizeof(numbers) / sizeof(numbers[0]) ; ++i)
+    [numbers[i] release];
+  
+  [s_numbers release];
+}
+
+void rdar7283470_2_positive(void) {
+  NSNumber *numbers[] = {
+    [[NSNumber alloc] initWithInt:1], // no-warning
+    [[NSNumber alloc] initWithInt:2], // no-warning
+    [[NSNumber alloc] initWithInt:3], // no-warning
+    [[NSNumber alloc] initWithInt:4], // no-warning
+    [[NSNumber alloc] initWithInt:5]  // no-warning
+  };
+  
+  NSArray *s_numbers =[[NSArray alloc] initWithObjects: &numbers[0] count:sizeof(numbers) / sizeof(numbers[0])]; // expected-warning{{leak}}
+  
+  for (unsigned i = 0 ; i < sizeof(numbers) / sizeof(numbers[0]) ; ++i)
+    [numbers[i] release];
+}
+
+void pr6699(int x) {
+  CFDateRef values[2];
+  values[0] = values[1] = 0;
+
+  if (x) {
+    CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
+    values[1] = CFDateCreate(0, t);
+  }
+
+  if (values[1]) {
+    // A bug in RegionStore::RemoveDeadBindings caused 'values[1]' to get prematurely
+    // pruned from the store.
+    CFRelease(values[1]); // no-warning
+  }
+}
+
diff --git a/test/Analysis/retain-release.m b/test/Analysis/retain-release.m
new file mode 100644
index 0000000..3f79c0c
--- /dev/null
+++ b/test/Analysis/retain-release.m
@@ -0,0 +1,1334 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-check-objc-mem -analyzer-store=basic -fblocks -verify %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-check-objc-mem -analyzer-store=region -fblocks -verify %s
+
+#if __has_feature(attribute_ns_returns_retained)
+#define NS_RETURNS_RETAINED __attribute__((ns_returns_retained))
+#endif
+#if __has_feature(attribute_cf_returns_retained)
+#define CF_RETURNS_RETAINED __attribute__((cf_returns_retained))
+#endif
+#if __has_feature(attribute_ns_returns_not_retained)
+#define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained))
+#endif
+#if __has_feature(attribute_cf_returns_not_retained)
+#define CF_RETURNS_NOT_RETAINED __attribute__((cf_returns_not_retained))
+#endif
+
+//===----------------------------------------------------------------------===//
+// The following code is reduced using delta-debugging from Mac OS X headers:
+//
+// #include <Cocoa/Cocoa.h>
+// #include <CoreFoundation/CoreFoundation.h>
+// #include <DiskArbitration/DiskArbitration.h>
+// #include <QuartzCore/QuartzCore.h>
+// #include <Quartz/Quartz.h>
+// #include <IOKit/IOKitLib.h>
+//
+// It includes the basic definitions for the test cases below.
+//===----------------------------------------------------------------------===//
+
+typedef unsigned int __darwin_natural_t;
+typedef unsigned long uintptr_t;
+typedef unsigned int uint32_t;
+typedef unsigned long long uint64_t;
+typedef unsigned int UInt32;
+typedef signed long CFIndex;
+typedef struct {
+    CFIndex location;
+    CFIndex length;
+} CFRange;
+static __inline__ __attribute__((always_inline)) CFRange CFRangeMake(CFIndex loc, CFIndex len) {
+    CFRange range;
+    range.location = loc;
+    range.length = len;
+    return range;
+}
+typedef const void * CFTypeRef;
+typedef const struct __CFString * CFStringRef;
+typedef const struct __CFAllocator * CFAllocatorRef;
+extern const CFAllocatorRef kCFAllocatorDefault;
+extern CFTypeRef CFRetain(CFTypeRef cf);
+extern void CFRelease(CFTypeRef cf);
+typedef struct {
+}
+CFArrayCallBacks;
+extern const CFArrayCallBacks kCFTypeArrayCallBacks;
+typedef const struct __CFArray * CFArrayRef;
+typedef struct __CFArray * CFMutableArrayRef;
+extern CFMutableArrayRef CFArrayCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFArrayCallBacks *callBacks);
+extern const void *CFArrayGetValueAtIndex(CFArrayRef theArray, CFIndex idx);
+extern void CFArrayAppendValue(CFMutableArrayRef theArray, const void *value);
+typedef struct {
+}
+CFDictionaryKeyCallBacks;
+extern const CFDictionaryKeyCallBacks kCFTypeDictionaryKeyCallBacks;
+typedef struct {
+}
+CFDictionaryValueCallBacks;
+extern const CFDictionaryValueCallBacks kCFTypeDictionaryValueCallBacks;
+typedef const struct __CFDictionary * CFDictionaryRef;
+typedef struct __CFDictionary * CFMutableDictionaryRef;
+extern CFMutableDictionaryRef CFDictionaryCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFDictionaryKeyCallBacks *keyCallBacks, const CFDictionaryValueCallBacks *valueCallBacks);
+typedef UInt32 CFStringEncoding;
+enum {
+kCFStringEncodingMacRoman = 0,     kCFStringEncodingWindowsLatin1 = 0x0500,     kCFStringEncodingISOLatin1 = 0x0201,     kCFStringEncodingNextStepLatin = 0x0B01,     kCFStringEncodingASCII = 0x0600,     kCFStringEncodingUnicode = 0x0100,     kCFStringEncodingUTF8 = 0x08000100,     kCFStringEncodingNonLossyASCII = 0x0BFF      ,     kCFStringEncodingUTF16 = 0x0100,     kCFStringEncodingUTF16BE = 0x10000100,     kCFStringEncodingUTF16LE = 0x14000100,      kCFStringEncodingUTF32 = 0x0c000100,     kCFStringEncodingUTF32BE = 0x18000100,     kCFStringEncodingUTF32LE = 0x1c000100  };
+extern CFStringRef CFStringCreateWithCString(CFAllocatorRef alloc, const char *cStr, CFStringEncoding encoding);
+typedef double CFTimeInterval;
+typedef CFTimeInterval CFAbsoluteTime;
+extern CFAbsoluteTime CFAbsoluteTimeGetCurrent(void);
+typedef const struct __CFDate * CFDateRef;
+extern CFDateRef CFDateCreate(CFAllocatorRef allocator, CFAbsoluteTime at);
+extern CFAbsoluteTime CFDateGetAbsoluteTime(CFDateRef theDate);
+typedef __darwin_natural_t natural_t;
+typedef natural_t mach_port_name_t;
+typedef mach_port_name_t mach_port_t;
+typedef int kern_return_t;
+typedef kern_return_t mach_error_t;
+enum {
+kCFNumberSInt8Type = 1,     kCFNumberSInt16Type = 2,     kCFNumberSInt32Type = 3,     kCFNumberSInt64Type = 4,     kCFNumberFloat32Type = 5,     kCFNumberFloat64Type = 6,      kCFNumberCharType = 7,     kCFNumberShortType = 8,     kCFNumberIntType = 9,     kCFNumberLongType = 10,     kCFNumberLongLongType = 11,     kCFNumberFloatType = 12,     kCFNumberDoubleType = 13,      kCFNumberCFIndexType = 14,      kCFNumberNSIntegerType = 15,     kCFNumberCGFloatType = 16,     kCFNumberMaxType = 16    };
+typedef CFIndex CFNumberType;
+typedef const struct __CFNumber * CFNumberRef;
+extern CFNumberRef CFNumberCreate(CFAllocatorRef allocator, CFNumberType theType, const void *valuePtr);
+typedef const struct __CFAttributedString *CFAttributedStringRef;
+typedef struct __CFAttributedString *CFMutableAttributedStringRef;
+extern CFAttributedStringRef CFAttributedStringCreate(CFAllocatorRef alloc, CFStringRef str, CFDictionaryRef attributes) ;
+extern CFMutableAttributedStringRef CFAttributedStringCreateMutableCopy(CFAllocatorRef alloc, CFIndex maxLength, CFAttributedStringRef aStr) ;
+extern void CFAttributedStringSetAttribute(CFMutableAttributedStringRef aStr, CFRange range, CFStringRef attrName, CFTypeRef value) ;
+typedef signed char BOOL;
+typedef unsigned long NSUInteger;
+@class NSString, Protocol;
+extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, 2)));
+typedef struct _NSZone NSZone;
+@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+@protocol NSObject
+- (BOOL)isEqual:(id)object;
+- (id)retain;
+- (oneway void)release;
+- (id)autorelease;
+@end  @protocol NSCopying  - (id)copyWithZone:(NSZone *)zone;
+@end  @protocol NSMutableCopying  - (id)mutableCopyWithZone:(NSZone *)zone;
+@end  @protocol NSCoding  - (void)encodeWithCoder:(NSCoder *)aCoder;
+@end
+@interface NSObject <NSObject> {}
++ (id)allocWithZone:(NSZone *)zone;
++ (id)alloc;
+- (void)dealloc;
+@end
+@interface NSObject (NSCoderMethods)
+- (id)awakeAfterUsingCoder:(NSCoder *)aDecoder;
+@end
+extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone);
+typedef struct {
+}
+NSFastEnumerationState;
+@protocol NSFastEnumeration  - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len;
+@end           @class NSString, NSDictionary;
+@interface NSValue : NSObject <NSCopying, NSCoding>  - (void)getValue:(void *)value;
+@end  @interface NSNumber : NSValue  - (char)charValue;
+- (id)initWithInt:(int)value;
+@end   @class NSString;
+@interface NSArray : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration>  - (NSUInteger)count;
+@end  @interface NSArray (NSArrayCreation)  + (id)array;
+@end       @interface NSAutoreleasePool : NSObject {
+}
+- (void)drain;
+@end extern NSString * const NSBundleDidLoadNotification;
+typedef double NSTimeInterval;
+@interface NSDate : NSObject <NSCopying, NSCoding>  - (NSTimeInterval)timeIntervalSinceReferenceDate;
+@end            typedef unsigned short unichar;
+@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding>    - (NSUInteger)length;
+- ( const char *)UTF8String;
+- (id)initWithUTF8String:(const char *)nullTerminatedCString;
++ (id)stringWithUTF8String:(const char *)nullTerminatedCString;
+@end        @class NSString, NSURL, NSError;
+@interface NSData : NSObject <NSCopying, NSMutableCopying, NSCoding>  - (NSUInteger)length;
++ (id)dataWithBytesNoCopy:(void *)bytes length:(NSUInteger)length;
++ (id)dataWithBytesNoCopy:(void *)bytes length:(NSUInteger)length freeWhenDone:(BOOL)b;
+@end   @class NSLocale, NSDate, NSCalendar, NSTimeZone, NSError, NSArray, NSMutableDictionary;
+@interface NSDictionary : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration>  - (NSUInteger)count;
+@end    @interface NSMutableDictionary : NSDictionary  - (void)removeObjectForKey:(id)aKey;
+- (void)setObject:(id)anObject forKey:(id)aKey;
+@end  @interface NSMutableDictionary (NSMutableDictionaryCreation)  + (id)dictionaryWithCapacity:(NSUInteger)numItems;
+@end  typedef double CGFloat;
+struct CGSize {
+};
+typedef struct CGSize CGSize;
+struct CGRect {
+};
+typedef struct CGRect CGRect;
+typedef mach_port_t io_object_t;
+typedef char io_name_t[128];
+typedef io_object_t io_iterator_t;
+typedef io_object_t io_service_t;
+typedef struct IONotificationPort * IONotificationPortRef;
+typedef void (*IOServiceMatchingCallback)(  void * refcon,  io_iterator_t iterator );
+io_service_t IOServiceGetMatchingService(  mach_port_t masterPort,  CFDictionaryRef matching );
+kern_return_t IOServiceGetMatchingServices(  mach_port_t masterPort,  CFDictionaryRef matching,  io_iterator_t * existing );
+kern_return_t IOServiceAddNotification(  mach_port_t masterPort,  const io_name_t notificationType,  CFDictionaryRef matching,  mach_port_t wakePort,  uintptr_t reference,  io_iterator_t * notification ) __attribute__((deprecated));
+kern_return_t IOServiceAddMatchingNotification(  IONotificationPortRef notifyPort,  const io_name_t notificationType,  CFDictionaryRef matching,         IOServiceMatchingCallback callback,         void * refCon,  io_iterator_t * notification );
+CFMutableDictionaryRef IOServiceMatching(  const char * name );
+CFMutableDictionaryRef IOServiceNameMatching(  const char * name );
+CFMutableDictionaryRef IOBSDNameMatching(  mach_port_t masterPort,  uint32_t options,  const char * bsdName );
+CFMutableDictionaryRef IOOpenFirmwarePathMatching(  mach_port_t masterPort,  uint32_t options,  const char * path );
+CFMutableDictionaryRef IORegistryEntryIDMatching(  uint64_t entryID );
+typedef struct __DASession * DASessionRef;
+extern DASessionRef DASessionCreate( CFAllocatorRef allocator );
+typedef struct __DADisk * DADiskRef;
+extern DADiskRef DADiskCreateFromBSDName( CFAllocatorRef allocator, DASessionRef session, const char * name );
+extern DADiskRef DADiskCreateFromIOMedia( CFAllocatorRef allocator, DASessionRef session, io_service_t media );
+extern CFDictionaryRef DADiskCopyDescription( DADiskRef disk );
+extern DADiskRef DADiskCopyWholeDisk( DADiskRef disk );
+@interface NSTask : NSObject - (id)init;
+@end                    typedef struct CGColorSpace *CGColorSpaceRef;
+typedef struct CGImage *CGImageRef;
+typedef struct CGLayer *CGLayerRef;
+@interface NSResponder : NSObject <NSCoding> {
+}
+@end    @protocol NSAnimatablePropertyContainer      - (id)animator;
+@end  extern NSString *NSAnimationTriggerOrderIn ;
+@interface NSView : NSResponder  <NSAnimatablePropertyContainer>  {
+}
+@end @protocol NSValidatedUserInterfaceItem - (SEL)action;
+@end   @protocol NSUserInterfaceValidations - (BOOL)validateUserInterfaceItem:(id <NSValidatedUserInterfaceItem>)anItem;
+@end  @class NSDate, NSDictionary, NSError, NSException, NSNotification;
+@interface NSApplication : NSResponder <NSUserInterfaceValidations> {
+}
+@end   enum {
+NSTerminateCancel = 0,         NSTerminateNow = 1,         NSTerminateLater = 2 };
+typedef NSUInteger NSApplicationTerminateReply;
+@protocol NSApplicationDelegate <NSObject> @optional        - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender;
+@end  @class NSAttributedString, NSEvent, NSFont, NSFormatter, NSImage, NSMenu, NSText, NSView, NSTextView;
+@interface NSCell : NSObject <NSCopying, NSCoding> {
+}
+@end @class NSTextField, NSPanel, NSArray, NSWindow, NSImage, NSButton, NSError;
+typedef struct {
+}
+CVTimeStamp;
+@interface CIImage : NSObject <NSCoding, NSCopying> {
+}
+typedef int CIFormat;
+@end  enum {
+kDAReturnSuccess = 0,     kDAReturnError = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x01,     kDAReturnBusy = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x02,     kDAReturnBadArgument = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x03,     kDAReturnExclusiveAccess = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x04,     kDAReturnNoResources = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x05,     kDAReturnNotFound = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x06,     kDAReturnNotMounted = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x07,     kDAReturnNotPermitted = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x08,     kDAReturnNotPrivileged = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x09,     kDAReturnNotReady = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x0A,     kDAReturnNotWritable = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x0B,     kDAReturnUnsupported = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x0C };
+typedef mach_error_t DAReturn;
+typedef const struct __DADissenter * DADissenterRef;
+extern DADissenterRef DADissenterCreate( CFAllocatorRef allocator, DAReturn status, CFStringRef string );
+@interface CIContext: NSObject {
+}
+- (CGImageRef)createCGImage:(CIImage *)im fromRect:(CGRect)r;
+- (CGImageRef)createCGImage:(CIImage *)im fromRect:(CGRect)r     format:(CIFormat)f colorSpace:(CGColorSpaceRef)cs;
+- (CGLayerRef)createCGLayerWithSize:(CGSize)size info:(CFDictionaryRef)d;
+@end extern NSString* const QCRendererEventKey;
+@protocol QCCompositionRenderer - (NSDictionary*) attributes;
+@end   @interface QCRenderer : NSObject <QCCompositionRenderer> {
+}
+- (id) createSnapshotImageOfType:(NSString*)type;
+@end  extern NSString* const QCViewDidStartRenderingNotification;
+@interface QCView : NSView <QCCompositionRenderer> {
+}
+- (id) createSnapshotImageOfType:(NSString*)type;
+@end    enum {
+ICEXIFOrientation1 = 1,     ICEXIFOrientation2 = 2,     ICEXIFOrientation3 = 3,     ICEXIFOrientation4 = 4,     ICEXIFOrientation5 = 5,     ICEXIFOrientation6 = 6,     ICEXIFOrientation7 = 7,     ICEXIFOrientation8 = 8, };
+@class ICDevice;
+@protocol ICDeviceDelegate <NSObject>  @required      - (void)didRemoveDevice:(ICDevice*)device;
+@end extern NSString *const ICScannerStatusWarmingUp;
+@class ICScannerDevice;
+@protocol ICScannerDeviceDelegate <ICDeviceDelegate>  @optional       - (void)scannerDeviceDidBecomeAvailable:(ICScannerDevice*)scanner;
+@end
+
+typedef long unsigned int __darwin_size_t;
+typedef __darwin_size_t size_t;
+typedef unsigned long CFTypeID;
+struct CGPoint {
+  CGFloat x;
+  CGFloat y;
+};
+typedef struct CGPoint CGPoint;
+typedef struct CGGradient *CGGradientRef;
+typedef uint32_t CGGradientDrawingOptions;
+extern CFTypeID CGGradientGetTypeID(void);
+extern CGGradientRef CGGradientCreateWithColorComponents(CGColorSpaceRef
+  space, const CGFloat components[], const CGFloat locations[], size_t count);
+extern CGGradientRef CGGradientCreateWithColors(CGColorSpaceRef space,
+  CFArrayRef colors, const CGFloat locations[]);
+extern CGGradientRef CGGradientRetain(CGGradientRef gradient);
+extern void CGGradientRelease(CGGradientRef gradient);
+typedef struct CGContext *CGContextRef;
+extern void CGContextDrawLinearGradient(CGContextRef context,
+    CGGradientRef gradient, CGPoint startPoint, CGPoint endPoint,
+    CGGradientDrawingOptions options);
+extern CGColorSpaceRef CGColorSpaceCreateDeviceRGB(void);
+
+//===----------------------------------------------------------------------===//
+// Test cases.
+//===----------------------------------------------------------------------===//
+
+CFAbsoluteTime f1() {
+  CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
+  CFDateRef date = CFDateCreate(0, t);
+  CFRetain(date);
+  CFRelease(date);
+  CFDateGetAbsoluteTime(date); // no-warning
+  CFRelease(date);
+  t = CFDateGetAbsoluteTime(date);   // expected-warning{{Reference-counted object is used after it is released.}}
+  return t;
+}
+
+CFAbsoluteTime f2() {
+  CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
+  CFDateRef date = CFDateCreate(0, t);  
+  [((NSDate*) date) retain];
+  CFRelease(date);
+  CFDateGetAbsoluteTime(date); // no-warning
+  [((NSDate*) date) release];
+  t = CFDateGetAbsoluteTime(date);   // expected-warning{{Reference-counted object is used after it is released.}}
+  return t;
+}
+
+
+NSDate* global_x;
+
+// Test to see if we supresss an error when we store the pointer
+// to a global.
+
+CFAbsoluteTime f3() {
+  CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
+  CFDateRef date = CFDateCreate(0, t);  
+  [((NSDate*) date) retain];
+  CFRelease(date);
+  CFDateGetAbsoluteTime(date); // no-warning
+  global_x = (NSDate*) date;  
+  [((NSDate*) date) release];
+  t = CFDateGetAbsoluteTime(date);   // no-warning
+  return t;
+}
+
+//---------------------------------------------------------------------------
+// Test case 'f4' differs for region store and basic store.  See
+// retain-release-region-store.m and retain-release-basic-store.m.
+//---------------------------------------------------------------------------
+
+// Test a leak.
+
+CFAbsoluteTime f5(int x) {  
+  CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
+  CFDateRef date = CFDateCreate(0, t); // expected-warning{{leak}}
+  
+  if (x)
+    CFRelease(date);
+  
+  return t;
+}
+
+// Test a leak involving the return.
+
+CFDateRef f6(int x) {  
+  CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent());  // expected-warning{{leak}}
+  CFRetain(date);
+  return date;
+}
+
+// Test a leak involving an overwrite.
+
+CFDateRef f7() {
+  CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent());  //expected-warning{{leak}}
+  CFRetain(date);
+  date = CFDateCreate(0, CFAbsoluteTimeGetCurrent());
+  return date;
+}
+
+// Generalization of Create rule.  MyDateCreate returns a CFXXXTypeRef, and
+// has the word create.
+CFDateRef MyDateCreate();
+
+CFDateRef f8() {
+  CFDateRef date = MyDateCreate(); // expected-warning{{leak}}
+  CFRetain(date);  
+  return date;
+}
+
+CFDateRef f9() {
+  CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent());
+  int *p = 0;
+  // When allocations fail, CFDateCreate can return null.
+  if (!date) *p = 1; // expected-warning{{null}}
+  return date;
+}
+
+// Handle DiskArbitration API:
+//
+// http://developer.apple.com/DOCUMENTATION/DARWIN/Reference/DiscArbitrationFramework/
+//
+void f10(io_service_t media, DADiskRef d, CFStringRef s) {
+  DADiskRef disk = DADiskCreateFromBSDName(kCFAllocatorDefault, 0, "hello"); // expected-warning{{leak}}
+  if (disk) NSLog(@"ok");
+  
+  disk = DADiskCreateFromIOMedia(kCFAllocatorDefault, 0, media); // expected-warning{{leak}}
+  if (disk) NSLog(@"ok");
+
+  CFDictionaryRef dict = DADiskCopyDescription(d);  // expected-warning{{leak}}
+  if (dict) NSLog(@"ok"); 
+  
+  disk = DADiskCopyWholeDisk(d); // expected-warning{{leak}}
+  if (disk) NSLog(@"ok");
+    
+  DADissenterRef dissenter = DADissenterCreate(kCFAllocatorDefault,   // expected-warning{{leak}}
+                                                kDAReturnSuccess, s);
+  if (dissenter) NSLog(@"ok");
+  
+  DASessionRef session = DASessionCreate(kCFAllocatorDefault);  // expected-warning{{leak}}
+  if (session) NSLog(@"ok");
+}
+
+// Test retain/release checker with CFString and CFMutableArray.
+void f11() {
+  // Create the array.
+  CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks);
+
+  // Create a string.
+  CFStringRef s1 = CFStringCreateWithCString(0, "hello world",
+                                             kCFStringEncodingUTF8);
+
+  // Add the string to the array.
+  CFArrayAppendValue(A, s1);
+  
+  // Decrement the reference count.
+  CFRelease(s1); // no-warning
+  
+  // Get the string.  We don't own it.
+  s1 = (CFStringRef) CFArrayGetValueAtIndex(A, 0);
+  
+  // Release the array.
+  CFRelease(A); // no-warning
+  
+  // Release the string.  This is a bug.
+  CFRelease(s1); // expected-warning{{Incorrect decrement of the reference count}}
+}
+
+// PR 3337: Handle functions declared using typedefs.
+typedef CFTypeRef CREATEFUN();
+CREATEFUN MyCreateFun;
+
+void f12() {
+  CFTypeRef o = MyCreateFun(); // expected-warning {{leak}}
+}
+
+void f13_autorelease() {
+  CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning
+  [(id) A autorelease]; // no-warning
+}
+
+void f13_autorelease_b() {
+  CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks);
+  [(id) A autorelease];
+  [(id) A autorelease]; // expected-warning{{Object sent -autorelease too many times}}
+}
+
+CFMutableArrayRef f13_autorelease_c() {
+  CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks);
+  [(id) A autorelease];
+  [(id) A autorelease]; 
+  return A; // expected-warning{{Object sent -autorelease too many times}}
+}
+
+CFMutableArrayRef f13_autorelease_d() {
+  CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks);
+  [(id) A autorelease];
+  [(id) A autorelease]; 
+  CFMutableArrayRef B = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning{{Object sent -autorelease too many times}}
+  CFRelease(B); // no-warning
+  while (1) {}
+}
+
+
+// This case exercises the logic where the leak site is the same as the allocation site.
+void f14_leakimmediately() {
+  CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning{{leak}}
+}
+
+// Test that we track an allocated object beyond the point where the *name*
+// of the variable storing the reference is no longer live.
+void f15() {
+  // Create the array.
+  CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks);
+  CFMutableArrayRef *B = &A;
+  // At this point, the name 'A' is no longer live.
+  CFRelease(*B);  // no-warning
+}
+
+// Test when we pass NULL to CFRetain/CFRelease.
+void f16(int x, CFTypeRef p) {
+  if (p)
+    return;
+
+  if (x) {
+    CFRelease(p); // expected-warning{{Null pointer argument in call to CFRelease}}
+  }
+  else {
+    CFRetain(p); // expected-warning{{Null pointer argument in call to CFRetain}}
+  }
+}
+
+// Test basic tracking of ivars associated with 'self'.  For the retain/release
+// checker we currently do not want to flag leaks associated with stores
+// of tracked objects to ivars.
+@interface SelfIvarTest : NSObject {
+  id myObj;
+}
+- (void)test_self_tracking;
+@end
+
+@implementation SelfIvarTest
+- (void)test_self_tracking {
+  myObj = (id) CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning
+}
+@end
+
+// Test return of non-owned objects in contexts where an owned object
+// is expected.
+@interface TestReturnNotOwnedWhenExpectedOwned
+- (NSString*)newString;
+@end
+
+@implementation TestReturnNotOwnedWhenExpectedOwned
+- (NSString*)newString {
+  NSString *s = [NSString stringWithUTF8String:"hello"];
+  return s; // expected-warning{{Object with +0 retain counts returned to caller where a +1 (owning) retain count is expected}}
+}
+@end
+
+// <rdar://problem/6659160>
+int isFoo(char c);
+
+static void rdar_6659160(char *inkind, char *inname)
+{
+  // We currently expect that [NSObject alloc] cannot fail.  This
+  // will be a toggled flag in the future.  It can indeed return null, but
+  // Cocoa programmers generally aren't expected to reason about out-of-memory
+  // conditions.
+  NSString *kind = [[NSString alloc] initWithUTF8String:inkind];  // expected-warning{{leak}}
+  
+  // We do allow stringWithUTF8String to fail.  This isn't really correct, as
+  // far as returning 0.  In most error conditions it will throw an exception.
+  // If allocation fails it could return 0, but again this
+  // isn't expected.
+  NSString *name = [NSString stringWithUTF8String:inname];
+  if(!name)
+    return;
+
+  const char *kindC = 0;
+  const char *nameC = 0;
+  
+  // In both cases, we cannot reach a point down below where we
+  // dereference kindC or nameC with either being null.  This is because
+  // we assume that [NSObject alloc] doesn't fail and that we have the guard
+  // up above.
+  
+  if(kind)
+    kindC = [kind UTF8String];
+  if(name)
+    nameC = [name UTF8String];
+  if(!isFoo(kindC[0])) // expected-warning{{null}}
+    return;
+  if(!isFoo(nameC[0])) // no-warning
+    return;
+
+  [kind release];
+  [name release]; // expected-warning{{Incorrect decrement of the reference count}}
+}
+
+// PR 3677 - 'allocWithZone' should be treated as following the Cocoa naming
+//  conventions with respect to 'return'ing ownership.
+@interface PR3677: NSObject @end
+@implementation PR3677
++ (id)allocWithZone:(NSZone *)inZone {
+  return [super allocWithZone:inZone];  // no-warning
+}
+@end
+
+// PR 3820 - Reason about calls to -dealloc
+void pr3820_DeallocInsteadOfRelease(void)
+{
+  id foo = [[NSString alloc] init]; // no-warning
+  [foo dealloc];
+  // foo is not leaked, since it has been deallocated.
+}
+
+void pr3820_ReleaseAfterDealloc(void)
+{
+  id foo = [[NSString alloc] init];
+  [foo dealloc];
+  [foo release];  // expected-warning{{used after it is release}}
+  // NSInternalInconsistencyException: message sent to deallocated object
+}
+
+void pr3820_DeallocAfterRelease(void)
+{
+  NSLog(@"\n\n[%s]", __FUNCTION__);
+  id foo = [[NSString alloc] init];
+  [foo release];
+  [foo dealloc]; // expected-warning{{used after it is released}}
+  // message sent to released object
+}
+
+// From <rdar://problem/6704930>.  The problem here is that 'length' binds to
+// '($0 - 1)' after '--length', but SimpleConstraintManager doesn't know how to
+// reason about '($0 - 1) > constant'.  As a temporary hack, we drop the value
+// of '($0 - 1)' and conjure a new symbol.
+void rdar6704930(unsigned char *s, unsigned int length) {
+  NSString* name = 0;
+  if (s != 0) {
+    if (length > 0) {
+      while (length > 0) {
+        if (*s == ':') {
+          ++s;
+          --length;
+          name = [[NSString alloc] init]; // no-warning
+          break;
+        }
+        ++s;
+        --length;
+      }
+      if ((length == 0) && (name != 0)) {
+        [name release];
+        name = 0;
+      }
+      if (length == 0) { // no ':' found -> use it all as name
+        name = [[NSString alloc] init]; // no-warning
+      }
+    }
+  }
+
+  if (name != 0) {
+    [name release];
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/6833332>
+// One build of the analyzer accidentally stopped tracking the allocated
+// object after the 'retain'.
+//===----------------------------------------------------------------------===//
+
+@interface rdar_6833332 : NSObject <NSApplicationDelegate> {
+    NSWindow *window;
+}
+@property (nonatomic, retain) NSWindow *window;
+@end
+
+@implementation rdar_6833332
+@synthesize window;
+- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
+ NSMutableDictionary *dict = [[NSMutableDictionary dictionaryWithCapacity:4] retain]; // expected-warning{{leak}}
+
+ [dict setObject:@"foo" forKey:@"bar"];
+
+ NSLog(@"%@", dict);
+}
+- (void)dealloc {
+    [window release];
+    [super dealloc];
+}
+@end
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/6257780> clang checker fails to catch use-after-release
+//===----------------------------------------------------------------------===//
+                                 
+int rdar_6257780_Case1() {
+  NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+  NSArray *array = [NSArray array];
+  [array release]; // expected-warning{{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}}
+  [pool drain];
+  return 0;
+}
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/6866843> Checker should understand new/setObject:/release constructs
+//===----------------------------------------------------------------------===//
+
+void rdar_6866843() {
+ NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+ NSMutableDictionary* dictionary = [[NSMutableDictionary alloc] init];
+ NSArray* array = [[NSArray alloc] init];
+ [dictionary setObject:array forKey:@"key"];
+ [array release];
+ // Using 'array' here should be fine
+ NSLog(@"array = %@\n", array); // no-warning
+ // Now the array is released
+ [dictionary release];
+ [pool drain];
+}
+
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/6877235> Classes typedef-ed to CF objects should get the same treatment as CF objects
+//===----------------------------------------------------------------------===//
+
+typedef CFTypeRef OtherRef;
+
+@interface RDar6877235 : NSObject {}
+- (CFTypeRef)_copyCFTypeRef;
+- (OtherRef)_copyOtherRef;
+@end
+
+@implementation RDar6877235
+- (CFTypeRef)_copyCFTypeRef {
+  return [[NSString alloc] init]; // no-warning
+}
+- (OtherRef)_copyOtherRef {
+  return [[NSString alloc] init]; // no-warning
+}
+@end
+
+//===----------------------------------------------------------------------===//
+//<rdar://problem/6320065> false positive - init method returns an object
+// owned by caller
+//===----------------------------------------------------------------------===//
+
+@interface RDar6320065 : NSObject {
+  NSString *_foo;
+}
+- (id)initReturningNewClass;
+- (id)initReturningNewClassBad;
+- (id)initReturningNewClassBad2;
+@end
+
+@interface RDar6320065Subclass : RDar6320065
+@end
+
+@implementation RDar6320065
+- (id)initReturningNewClass {
+  [self release];
+  self = [[RDar6320065Subclass alloc] init]; // no-warning
+  return self;
+}
+- (id)initReturningNewClassBad {
+  [self release];
+  [[RDar6320065Subclass alloc] init]; // expected-warning {{leak}}
+  return self;
+}
+- (id)initReturningNewClassBad2 {
+  [self release];
+  self = [[RDar6320065Subclass alloc] init];
+  return [self autorelease]; // expected-warning{{Object with +0 retain counts returned to caller where a +1 (owning) retain count is expected}}
+}
+
+@end
+
+@implementation RDar6320065Subclass
+@end
+
+int RDar6320065_test() {
+  RDar6320065 *test = [[RDar6320065 alloc] init]; // no-warning
+  [test release];
+  return 0;
+}
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/7129086> -awakeAfterUsingCoder: returns an owned object 
+//  and claims the receiver
+//===----------------------------------------------------------------------===//
+
+@interface RDar7129086 : NSObject {} @end
+@implementation RDar7129086
+- (id)awakeAfterUsingCoder:(NSCoder *)aDecoder {
+  [self release]; // no-warning
+  return [NSString alloc];  // no-warning
+}
+@end
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/6859457> [NSData dataWithBytesNoCopy] does not return a
+//  retained object
+//===----------------------------------------------------------------------===//
+
+@interface RDar6859457 : NSObject {}
+- (NSString*) NoCopyString;
+- (NSString*) noCopyString;
+@end
+
+@implementation RDar6859457 
+- (NSString*) NoCopyString { return [[NSString alloc] init]; } // no-warning
+- (NSString*) noCopyString { return [[NSString alloc] init]; } // no-warning
+@end
+
+void test_RDar6859457(RDar6859457 *x, void *bytes, NSUInteger dataLength) {
+  [x NoCopyString]; // expected-warning{{leak}}
+  [x noCopyString]; // expected-warning{{leak}}
+  [NSData dataWithBytesNoCopy:bytes length:dataLength];  // no-warning
+  [NSData dataWithBytesNoCopy:bytes length:dataLength freeWhenDone:1]; // no-warning
+}
+
+//===----------------------------------------------------------------------===//
+// PR 4230 - an autorelease pool is not necessarily leaked during a premature
+//  return
+//===----------------------------------------------------------------------===//
+
+static void PR4230(void)
+{
+  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // no-warning
+  NSString *object = [[[NSString alloc] init] autorelease]; // no-warning
+  return;
+}
+
+//===----------------------------------------------------------------------===//
+// Method name that has a null IdentifierInfo* for its first selector slot.
+// This test just makes sure that we handle it.
+//===----------------------------------------------------------------------===//
+
+@interface TestNullIdentifier
+@end
+
+@implementation TestNullIdentifier
++ (id):(int)x, ... {
+  return [[NSString alloc] init]; // expected-warning{{leak}}
+}
+@end
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/6893565> don't flag leaks for return types that cannot be 
+//                          determined to be CF types
+//===----------------------------------------------------------------------===//
+
+// We don't know if 'struct s6893565' represents a Core Foundation type, so
+// we shouldn't emit an error here.
+typedef struct s6893565* TD6893565;
+
+@interface RDar6893565 {}
+-(TD6893565)newThing;
+@end
+
+@implementation RDar6893565
+-(TD6893565)newThing {  
+  return (TD6893565) [[NSString alloc] init]; // no-warning
+}
+@end
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/6902710> clang: false positives w/QC and CoreImage methods
+//===----------------------------------------------------------------------===//
+
+void rdar6902710(QCView *view, QCRenderer *renderer, CIContext *context,
+                 NSString *str, CIImage *img, CGRect rect,
+                 CIFormat form, CGColorSpaceRef cs) {
+  [view createSnapshotImageOfType:str]; // expected-warning{{leak}}
+  [renderer createSnapshotImageOfType:str]; // expected-warning{{leak}}
+  [context createCGImage:img fromRect:rect]; // expected-warning{{leak}}
+  [context createCGImage:img fromRect:rect format:form colorSpace:cs]; // expected-warning{{leak}}
+}
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/6945561> -[CIContext createCGLayerWithSize:info:]
+//                           misinterpreted by clang scan-build
+//===----------------------------------------------------------------------===//
+
+void rdar6945561(CIContext *context, CGSize size, CFDictionaryRef d) {
+  [context createCGLayerWithSize:size info:d]; // expected-warning{{leak}}
+}
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/6961230> add knowledge of IOKit functions to retain/release 
+//                          checker
+//===----------------------------------------------------------------------===//
+
+void IOBSDNameMatching_wrapper(mach_port_t masterPort, uint32_t options,  const char * bsdName) {  
+  IOBSDNameMatching(masterPort, options, bsdName); // expected-warning{{leak}}
+}
+
+void IOServiceMatching_wrapper(const char * name) {
+  IOServiceMatching(name); // expected-warning{{leak}}
+}
+
+void IOServiceNameMatching_wrapper(const char * name) {
+  IOServiceNameMatching(name); // expected-warning{{leak}}
+}
+
+CF_RETURNS_RETAINED CFDictionaryRef CreateDict();
+
+void IOServiceAddNotification_wrapper(mach_port_t masterPort, const io_name_t notificationType,
+  mach_port_t wakePort, uintptr_t reference, io_iterator_t * notification ) {
+
+  CFDictionaryRef matching = CreateDict();
+  CFRelease(matching);
+  IOServiceAddNotification(masterPort, notificationType, matching, // expected-warning{{used after it is released}} expected-warning{{deprecated}}
+                           wakePort, reference, notification);
+}
+
+void IORegistryEntryIDMatching_wrapper(uint64_t entryID ) {
+  IORegistryEntryIDMatching(entryID); // expected-warning{{leak}}
+}
+
+void IOOpenFirmwarePathMatching_wrapper(mach_port_t masterPort, uint32_t options,
+                                        const char * path) {
+  IOOpenFirmwarePathMatching(masterPort, options, path); // expected-warning{{leak}}
+}
+
+void IOServiceGetMatchingService_wrapper(mach_port_t masterPort) {
+  CFDictionaryRef matching = CreateDict();
+  IOServiceGetMatchingService(masterPort, matching);
+  CFRelease(matching); // expected-warning{{used after it is released}}
+}
+
+void IOServiceGetMatchingServices_wrapper(mach_port_t masterPort, io_iterator_t *existing) {
+  CFDictionaryRef matching = CreateDict();
+  IOServiceGetMatchingServices(masterPort, matching, existing);
+  CFRelease(matching); // expected-warning{{used after it is released}}
+}
+
+void IOServiceAddMatchingNotification_wrapper(IONotificationPortRef notifyPort, const io_name_t notificationType, 
+  IOServiceMatchingCallback callback, void * refCon, io_iterator_t * notification) {
+    
+  CFDictionaryRef matching = CreateDict();
+  IOServiceAddMatchingNotification(notifyPort, notificationType, matching, callback, refCon, notification);
+  CFRelease(matching); // expected-warning{{used after it is released}}
+}
+
+//===----------------------------------------------------------------------===//
+// Test of handling objects whose references "escape" to containers.
+//===----------------------------------------------------------------------===//
+
+void CFDictionaryAddValue();
+
+// <rdar://problem/6539791>
+void rdar_6539791(CFMutableDictionaryRef y, void* key, void* val_key) {
+  CFMutableDictionaryRef x = CFDictionaryCreateMutable(kCFAllocatorDefault, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+  CFDictionaryAddValue(y, key, x);
+  CFRelease(x); // the dictionary keeps a reference, so the object isn't deallocated yet
+  signed z = 1;
+  CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z);
+  if (value) {
+    CFDictionaryAddValue(x, val_key, value); // no-warning
+    CFRelease(value);
+    CFDictionaryAddValue(y, val_key, value); // no-warning
+  }
+}
+
+// <rdar://problem/6560661>
+// Same issue, except with "AppendValue" functions.
+void rdar_6560661(CFMutableArrayRef x) {
+  signed z = 1;
+  CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z);
+  // CFArrayAppendValue keeps a reference to value.
+  CFArrayAppendValue(x, value);
+  CFRelease(value);
+  CFRetain(value);
+  CFRelease(value); // no-warning
+}
+
+// <rdar://problem/7152619>
+// Same issue, excwept with "CFAttributeStringSetAttribute".
+void rdar_7152619(CFStringRef str) {
+  CFAttributedStringRef string = CFAttributedStringCreate(kCFAllocatorDefault, str, 0);
+  CFMutableAttributedStringRef attrString = CFAttributedStringCreateMutableCopy(kCFAllocatorDefault, 100, string);
+  CFRelease(string);
+  NSNumber *number = [[NSNumber alloc] initWithInt:5]; // expected-warning{{leak}}
+  CFAttributedStringSetAttribute(attrString, CFRangeMake(0, 1), str, number);
+  [number release];
+  [number retain];
+  CFRelease(attrString);  
+}
+
+//===----------------------------------------------------------------------===//
+// Test of handling CGGradientXXX functions.
+//===----------------------------------------------------------------------===//
+
+void rdar_7184450(CGContextRef myContext, CGFloat x, CGPoint myStartPoint,
+                  CGPoint myEndPoint) {
+  size_t num_locations = 6;
+  CGFloat locations[6] = { 0.0, 0.265, 0.28, 0.31, 0.36, 1.0 };
+  CGFloat components[28] = { 239.0/256.0, 167.0/256.0, 170.0/256.0,
+     x,  // Start color
+    207.0/255.0, 39.0/255.0, 39.0/255.0, x,
+    147.0/255.0, 21.0/255.0, 22.0/255.0, x,
+    175.0/255.0, 175.0/255.0, 175.0/255.0, x,
+    255.0/255.0,255.0/255.0, 255.0/255.0, x,
+    255.0/255.0,255.0/255.0, 255.0/255.0, x
+  }; // End color
+  
+  CGGradientRef myGradient =
+    CGGradientCreateWithColorComponents(CGColorSpaceCreateDeviceRGB(), // expected-warning{{leak}}
+      components, locations, num_locations);
+
+  CGContextDrawLinearGradient(myContext, myGradient, myStartPoint, myEndPoint,
+                              0);
+  CGGradientRelease(myGradient);
+}
+
+void rdar_7184450_pos(CGContextRef myContext, CGFloat x, CGPoint myStartPoint,
+                  CGPoint myEndPoint) {
+  size_t num_locations = 6;
+  CGFloat locations[6] = { 0.0, 0.265, 0.28, 0.31, 0.36, 1.0 };
+  CGFloat components[28] = { 239.0/256.0, 167.0/256.0, 170.0/256.0,
+     x,  // Start color
+    207.0/255.0, 39.0/255.0, 39.0/255.0, x,
+    147.0/255.0, 21.0/255.0, 22.0/255.0, x,
+    175.0/255.0, 175.0/255.0, 175.0/255.0, x,
+    255.0/255.0,255.0/255.0, 255.0/255.0, x,
+    255.0/255.0,255.0/255.0, 255.0/255.0, x
+  }; // End color
+  
+  CGGradientRef myGradient =
+   CGGradientCreateWithColorComponents(CGColorSpaceCreateDeviceRGB(), components, locations, num_locations); // expected-warning 2 {{leak}}
+
+  CGContextDrawLinearGradient(myContext, myGradient, myStartPoint, myEndPoint,
+                              0);
+}
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/7299394> clang false positive: retained instance passed to
+//                          thread in pthread_create marked as leak
+//
+// Until we have full IPA, the analyzer should stop tracking the reference
+// count of objects passed to pthread_create.
+//
+//===----------------------------------------------------------------------===//
+
+struct _opaque_pthread_t {};
+struct _opaque_pthread_attr_t {};
+typedef struct _opaque_pthread_t *__darwin_pthread_t;
+typedef struct _opaque_pthread_attr_t __darwin_pthread_attr_t;
+typedef __darwin_pthread_t pthread_t;
+typedef __darwin_pthread_attr_t pthread_attr_t;
+
+int pthread_create(pthread_t * restrict, const pthread_attr_t * restrict,
+                   void *(*)(void *), void * restrict);
+
+void *rdar_7299394_start_routine(void *p) {
+  [((id) p) release];
+  return 0;
+}
+void rdar_7299394(pthread_attr_t *attr, pthread_t *thread, void *args) {
+  NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning
+  pthread_create(thread, attr, rdar_7299394_start_routine, number);
+}
+void rdar_7299394_positive(pthread_attr_t *attr, pthread_t *thread) {
+  NSNumber *number = [[NSNumber alloc] initWithInt:5]; // expected-warning{{leak}}
+}
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/7283567> False leak associated with call to 
+//                          CVPixelBufferCreateWithBytes ()
+//
+// According to the Core Video Reference (ADC), CVPixelBufferCreateWithBytes and
+// CVPixelBufferCreateWithPlanarBytes can release (via a callback) the
+// pixel buffer object.  These test cases show how the analyzer stops tracking
+// the reference count for the objects passed for this argument.  This
+// could be made smarter.
+//===----------------------------------------------------------------------===//
+
+typedef int int32_t;
+typedef UInt32 FourCharCode;
+typedef FourCharCode OSType;
+typedef uint64_t CVOptionFlags;
+typedef int32_t CVReturn;
+typedef struct __CVBuffer *CVBufferRef;
+typedef CVBufferRef CVImageBufferRef;
+typedef CVImageBufferRef CVPixelBufferRef;
+typedef void (*CVPixelBufferReleaseBytesCallback)( void *releaseRefCon, const void *baseAddress );
+
+extern CVReturn CVPixelBufferCreateWithBytes(CFAllocatorRef allocator,
+            size_t width,
+            size_t height,
+            OSType pixelFormatType,
+            void *baseAddress,
+            size_t bytesPerRow,
+            CVPixelBufferReleaseBytesCallback releaseCallback,
+            void *releaseRefCon,
+            CFDictionaryRef pixelBufferAttributes,
+                   CVPixelBufferRef *pixelBufferOut) ;
+
+typedef void (*CVPixelBufferReleasePlanarBytesCallback)( void *releaseRefCon, const void *dataPtr, size_t dataSize, size_t numberOfPlanes, const void *planeAddresses[] );
+
+extern CVReturn CVPixelBufferCreateWithPlanarBytes(CFAllocatorRef allocator,
+        size_t width,
+        size_t height,
+        OSType pixelFormatType,
+        void *dataPtr,
+        size_t dataSize,
+        size_t numberOfPlanes,
+        void *planeBaseAddress[],
+        size_t planeWidth[],
+        size_t planeHeight[],
+        size_t planeBytesPerRow[],
+        CVPixelBufferReleasePlanarBytesCallback releaseCallback,
+        void *releaseRefCon,
+        CFDictionaryRef pixelBufferAttributes,
+        CVPixelBufferRef *pixelBufferOut) ;
+
+extern CVReturn CVPixelBufferCreateWithBytes(CFAllocatorRef allocator,
+            size_t width,
+            size_t height,
+            OSType pixelFormatType,
+            void *baseAddress,
+            size_t bytesPerRow,
+            CVPixelBufferReleaseBytesCallback releaseCallback,
+            void *releaseRefCon,
+            CFDictionaryRef pixelBufferAttributes,
+                   CVPixelBufferRef *pixelBufferOut) ;
+
+CVReturn rdar_7283567(CFAllocatorRef allocator, size_t width, size_t height,
+                      OSType pixelFormatType, void *baseAddress,
+                      size_t bytesPerRow,
+                      CVPixelBufferReleaseBytesCallback releaseCallback,
+                      CFDictionaryRef pixelBufferAttributes,
+                      CVPixelBufferRef *pixelBufferOut) {
+
+  // For the allocated object, it doesn't really matter what type it is
+  // for the purpose of this test.  All we want to show is that
+  // this is freed later by the callback.
+  NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning
+  
+  return CVPixelBufferCreateWithBytes(allocator, width, height, pixelFormatType,
+                                baseAddress, bytesPerRow, releaseCallback,
+                                number, // potentially released by callback
+                                pixelBufferAttributes, pixelBufferOut) ;
+}
+
+CVReturn rdar_7283567_2(CFAllocatorRef allocator, size_t width, size_t height,
+        OSType pixelFormatType, void *dataPtr, size_t dataSize,
+        size_t numberOfPlanes, void *planeBaseAddress[],
+        size_t planeWidth[], size_t planeHeight[], size_t planeBytesPerRow[],
+        CVPixelBufferReleasePlanarBytesCallback releaseCallback,
+        CFDictionaryRef pixelBufferAttributes,
+        CVPixelBufferRef *pixelBufferOut) {
+    
+    // For the allocated object, it doesn't really matter what type it is
+    // for the purpose of this test.  All we want to show is that
+    // this is freed later by the callback.
+    NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning
+
+    return CVPixelBufferCreateWithPlanarBytes(allocator,
+              width, height, pixelFormatType, dataPtr, dataSize,
+              numberOfPlanes, planeBaseAddress, planeWidth,
+              planeHeight, planeBytesPerRow, releaseCallback,
+              number, // potentially released by callback
+              pixelBufferAttributes, pixelBufferOut) ;
+}
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/7358899> False leak associated with 
+//  CGBitmapContextCreateWithData
+//===----------------------------------------------------------------------===//
+typedef uint32_t CGBitmapInfo;
+typedef void (*CGBitmapContextReleaseDataCallback)(void *releaseInfo, void *data);
+    
+CGContextRef CGBitmapContextCreateWithData(void *data,
+    size_t width, size_t height, size_t bitsPerComponent,
+    size_t bytesPerRow, CGColorSpaceRef space, CGBitmapInfo bitmapInfo,
+    CGBitmapContextReleaseDataCallback releaseCallback, void *releaseInfo);
+
+void rdar_7358899(void *data,
+      size_t width, size_t height, size_t bitsPerComponent,
+      size_t bytesPerRow, CGColorSpaceRef space, CGBitmapInfo bitmapInfo,
+      CGBitmapContextReleaseDataCallback releaseCallback) {
+
+    // For the allocated object, it doesn't really matter what type it is
+    // for the purpose of this test.  All we want to show is that
+    // this is freed later by the callback.
+    NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning
+
+  CGBitmapContextCreateWithData(data, width, height, bitsPerComponent, // expected-warning{{leak}}
+    bytesPerRow, space, bitmapInfo, releaseCallback, number);
+}
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/7265711> allow 'new', 'copy', 'alloc', 'init' prefix to
+//  start before '_' when determining Cocoa fundamental rule
+//
+// Previously the retain/release checker just skipped prefixes before the
+// first '_' entirely.  Now the checker honors the prefix if it results in a
+// recognizable naming convention (e.g., 'new', 'init').
+//===----------------------------------------------------------------------===//
+
+@interface RDar7265711 {}
+- (id) new_stuff;
+@end
+
+void rdar7265711_a(RDar7265711 *x) {
+  id y = [x new_stuff]; // expected-warning{{leak}}
+}
+
+void rdar7265711_b(RDar7265711 *x) {
+  id y = [x new_stuff]; // no-warning
+  [y release];
+}
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/7306898> clang thinks [NSCursor dragCopyCursor] returns a
+//                          retained reference
+//===----------------------------------------------------------------------===//
+
+@interface NSCursor : NSObject
++ (NSCursor *)dragCopyCursor;
+@end
+
+void rdar7306898(void) {
+  // 'dragCopyCursor' does not follow Cocoa's fundamental rule.  It is a noun, not an sentence
+  // implying a 'copy' of something.
+  NSCursor *c =  [NSCursor dragCopyCursor]; // no-warning
+  NSNumber *number = [[NSNumber alloc] initWithInt:5]; // expected-warning{{leak}}
+}
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/7252064> sending 'release', 'retain', etc. to a Class
+// directly is not likely what the user intended
+//===----------------------------------------------------------------------===//
+
+@interface RDar7252064 : NSObject @end
+void rdar7252064(void) {
+  [RDar7252064 release]; // expected-warning{{The 'release' message should be sent to instances of class 'RDar7252064' and not the class directly}}
+  [RDar7252064 retain]; // expected-warning{{The 'retain' message should be sent to instances of class 'RDar7252064' and not the class directly}}
+  [RDar7252064 autorelease]; // expected-warning{{The 'autorelease' message should be sent to instances of class 'RDar7252064' and not the class directly}}
+  [NSAutoreleasePool drain]; // expected-warning{{method '+drain' not found}} expected-warning{{The 'drain' message should be sent to instances of class 'NSAutoreleasePool' and not the class directly}}
+}
+
+//===----------------------------------------------------------------------===//
+// Tests of ownership attributes.
+//===----------------------------------------------------------------------===//
+
+typedef NSString* MyStringTy;
+
+@protocol FooP;
+
+@interface TestOwnershipAttr : NSObject
+- (NSString*) returnsAnOwnedString  NS_RETURNS_RETAINED; // no-warning
+- (NSString*) returnsAnOwnedCFString  CF_RETURNS_RETAINED; // no-warning
+- (MyStringTy) returnsAnOwnedTypedString NS_RETURNS_RETAINED; // no-warning
+- (NSString*) newString NS_RETURNS_NOT_RETAINED; // no-warning
+- (NSString*) newStringNoAttr;
+- (int) returnsAnOwnedInt NS_RETURNS_RETAINED; // expected-warning{{'ns_returns_retained' attribute only applies to functions or methods that return a pointer or Objective-C object}}
+@end
+
+static int ownership_attribute_doesnt_go_here NS_RETURNS_RETAINED; // expected-warning{{'ns_returns_retained' attribute only applies to function or method types}}
+
+void test_attr_1(TestOwnershipAttr *X) {
+  NSString *str = [X returnsAnOwnedString]; // expected-warning{{leak}}
+}
+
+void test_attr_1b(TestOwnershipAttr *X) {
+  NSString *str = [X returnsAnOwnedCFString]; // expected-warning{{leak}}
+}
+
+void test_attr1c(TestOwnershipAttr *X) {
+  NSString *str = [X newString]; // no-warning
+  NSString *str2 = [X newStringNoAttr]; // expected-warning{{leak}}
+}
+
+@interface MyClassTestCFAttr : NSObject {}
+- (NSDate*) returnsCFRetained CF_RETURNS_RETAINED;
+- (CFDateRef) returnsCFRetainedAsCF CF_RETURNS_RETAINED;
+- (CFDateRef) newCFRetainedAsCF CF_RETURNS_NOT_RETAINED;
+- (CFDateRef) newCFRetainedAsCFNoAttr;
+- (NSDate*) alsoReturnsRetained;
+- (CFDateRef) alsoReturnsRetainedAsCF;
+- (NSDate*) returnsNSRetained NS_RETURNS_RETAINED;
+@end
+
+CF_RETURNS_RETAINED
+CFDateRef returnsRetainedCFDate()  {
+  return CFDateCreate(0, CFAbsoluteTimeGetCurrent());
+}
+
+@implementation MyClassTestCFAttr
+- (NSDate*) returnsCFRetained {
+  return (NSDate*) returnsRetainedCFDate(); // No leak.
+}
+
+- (CFDateRef) returnsCFRetainedAsCF {
+  return returnsRetainedCFDate(); // No leak.
+}
+
+- (CFDateRef) newCFRetainedAsCF {
+  return (CFDateRef)[(id)[self returnsCFRetainedAsCF] autorelease];
+}
+
+- (CFDateRef) newCFRetainedAsCFNoAttr {
+  return (CFDateRef)[(id)[self returnsCFRetainedAsCF] autorelease]; // expected-warning{{Object with +0 retain counts returned to caller where a +1 (owning) retain count is expected}}
+}
+
+- (NSDate*) alsoReturnsRetained {
+  return (NSDate*) returnsRetainedCFDate(); // expected-warning{{leak}}
+}
+
+- (CFDateRef) alsoReturnsRetainedAsCF {
+  return returnsRetainedCFDate(); // expected-warning{{leak}}
+}
+
+
+- (NSDate*) returnsNSRetained {
+  return (NSDate*) returnsRetainedCFDate(); // no-warning
+}
+@end
+
+//===----------------------------------------------------------------------===//
+// Test that leaks post-dominated by "panic" functions are not reported.
+//
+// <rdar://problem/5905851> do not report a leak when post-dominated by a call
+// to a noreturn or panic function
+//===----------------------------------------------------------------------===//
+
+void panic() __attribute__((noreturn));
+void panic_not_in_hardcoded_list() __attribute__((noreturn));
+
+void test_panic_negative() {
+  signed z = 1;
+  CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z);  // expected-warning{{leak}}
+}
+
+void test_panic_positive() {
+  signed z = 1;
+  CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); // no-warning
+  panic();
+}
+
+void test_panic_neg_2(int x) {
+  signed z = 1;
+  CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); // expected-warning{{leak}}
+  if (x)
+    panic();
+}
+
+void test_panic_pos_2(int x) {
+  signed z = 1;
+  CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); // no-warning
+  if (x)
+    panic();
+  if (!x) {
+    // This showed up in <rdar://problem/7796563>, where we silently missed checking
+    // the function type for noreturn.  "panic()" is a hard-coded known panic function
+    // that isn't always noreturn.
+    panic_not_in_hardcoded_list();
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// Test uses of blocks (closures)
+//===----------------------------------------------------------------------===//
+
+void test_blocks_1_pos(void) {
+  NSNumber *number = [[NSNumber alloc] initWithInt:5]; // expected-warning{{leak}}
+  ^{}();
+}
+
+void test_blocks_1_indirect_release(void) {
+  NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning
+  ^{ [number release]; }();
+}
+
+void test_blocks_1_indirect_retain(void) {
+  // Eventually this should be reported as a leak.
+  NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning
+  ^{ [number retain]; }();
+}
+
+void test_blocks_1_indirect_release_via_call(void) {
+  NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning
+  ^(NSObject *o){ [o release]; }(number);
+}
+
+void test_blocks_1_indirect_retain_via_call(void) {
+  // Eventually this should be reported as a leak.
+  NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning
+  ^(NSObject *o){ [o retain]; }(number);
+}
+
diff --git a/test/Analysis/security-syntax-checks-no-emit.c b/test/Analysis/security-syntax-checks-no-emit.c
new file mode 100644
index 0000000..7a71235
--- /dev/null
+++ b/test/Analysis/security-syntax-checks-no-emit.c
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -triple i686-pc-linux-gnu -analyze -analyzer-check-security-syntactic %s -verify
+
+// This file complements 'security-syntax-checks.m', but tests that we omit
+// specific checks on platforms where they don't make sense.
+
+// Omit the 'rand' check since 'arc4random' is not available on Linux.
+int      rand(void);
+double   drand48(void);
+double   erand48(unsigned short[3]);
+long     jrand48(unsigned short[3]);
+void     lcong48(unsigned short[7]);
+long     lrand48(void);
+long     mrand48(void);
+long     nrand48(unsigned short[3]);
+long     random(void);
+int      rand_r(unsigned *);
+
+void test_rand()
+{
+  unsigned short a[7];
+  unsigned b;
+  
+  rand();	// no-warning
+  drand48();	// no-warning
+  erand48(a);	// no-warning
+  jrand48(a);	// no-warning
+  lcong48(a);	// no-warning
+  lrand48();	// no-warning
+  mrand48();	// no-warning
+  nrand48(a);	// no-warning
+  rand_r(&b);	// no-warning
+  random();	// no-warning
+}
diff --git a/test/Analysis/security-syntax-checks.m b/test/Analysis/security-syntax-checks.m
new file mode 100644
index 0000000..8dd859a
--- /dev/null
+++ b/test/Analysis/security-syntax-checks.m
@@ -0,0 +1,105 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-check-security-syntactic %s -verify
+
+// <rdar://problem/6336718> rule request: floating point used as loop 
+//  condition (FLP30-C, FLP-30-CPP)
+//
+// For reference: https://www.securecoding.cert.org/confluence/display/seccode/FLP30-C.+Do+not+use+floating+point+variables+as+loop+counters
+//
+void test_float_condition() {
+  for (float x = 0.1f; x <= 1.0f; x += 0.1f) {} // expected-warning{{Variable 'x' with floating point type 'float'}}
+  for (float x = 100000001.0f; x <= 100000010.0f; x += 1.0f) {} // expected-warning{{Variable 'x' with floating point type 'float'}}
+  for (float x = 100000001.0f; x <= 100000010.0f; x++ ) {} // expected-warning{{Variable 'x' with floating point type 'float'}}
+  for (double x = 100000001.0; x <= 100000010.0; x++ ) {} // expected-warning{{Variable 'x' with floating point type 'double'}}
+  for (double x = 100000001.0; ((x)) <= 100000010.0; ((x))++ ) {} // expected-warning{{Variable 'x' with floating point type 'double'}}
+  
+  for (double x = 100000001.0; 100000010.0 >= x; x = x + 1.0 ) {} // expected-warning{{Variable 'x' with floating point type 'double'}}
+  
+  int i = 0;
+  for (double x = 100000001.0; ((x)) <= 100000010.0; ((x))++, ++i ) {} // expected-warning{{Variable 'x' with floating point type 'double'}}
+  
+  typedef float FooType;
+  for (FooType x = 100000001.0f; x <= 100000010.0f; x++ ) {} // expected-warning{{Variable 'x' with floating point type 'FooType'}}
+}
+
+// <rdar://problem/6335715> rule request: gets() buffer overflow
+// Part of recommendation: 300-BSI (buildsecurityin.us-cert.gov)
+char* gets(char *buf);
+
+void test_gets() {
+  char buff[1024];
+  gets(buff); // expected-warning{{Call to function 'gets' is extremely insecure as it can always result in a buffer overflow}}
+}
+
+int getpw(unsigned int uid, char *buf);
+
+void test_getpw() {
+  char buff[1024];
+  getpw(2, buff); // expected-warning{{The getpw() function is dangerous as it may overflow the provided buffer. It is obsoleted by getpwuid().}}
+}
+
+// <rdar://problem/6337132> CWE-273: Failure to Check Whether Privileges Were
+//  Dropped Successfully
+typedef unsigned int __uint32_t;
+typedef __uint32_t __darwin_uid_t;
+typedef __uint32_t __darwin_gid_t;
+typedef __darwin_uid_t uid_t;
+typedef __darwin_gid_t gid_t;
+int setuid(uid_t);
+int setregid(gid_t, gid_t);
+int setreuid(uid_t, uid_t);
+extern void check(int);
+void abort(void);
+
+void test_setuid() 
+{
+  setuid(2); // expected-warning{{The return value from the call to 'setuid' is not checked.  If an error occurs in 'setuid', the following code may execute with unexpected privileges}}
+  setuid(0); // expected-warning{{The return value from the call to 'setuid' is not checked.  If an error occurs in 'setuid', the following code may execute with unexpected privileges}}
+  if (setuid (2) != 0)
+    abort();
+
+  // Currently the 'setuid' check is not flow-sensitive, and only looks
+  // at whether the function was called in a compound statement.  This
+  // will lead to false negatives, but there should be no false positives.
+  int t = setuid(2);  // no-warning
+  (void)setuid (2); // no-warning
+
+  check(setuid (2)); // no-warning
+
+  setreuid(2,2); // expected-warning{{The return value from the call to 'setreuid' is not checked.  If an error occurs in 'setreuid', the following code may execute with unexpected privileges}}
+  setregid(2,2); // expected-warning{{The return value from the call to 'setregid' is not checked.  If an error occurs in 'setregid', the following code may execute with unexpected privileges}}
+}
+
+// <rdar://problem/6337100> CWE-338: Use of cryptographically weak prng
+int      rand(void);
+double   drand48(void);
+double   erand48(unsigned short[3]);
+long     jrand48(unsigned short[3]);
+void     lcong48(unsigned short[7]);
+long     lrand48(void);
+long     mrand48(void);
+long     nrand48(unsigned short[3]);
+long     random(void);
+int      rand_r(unsigned *);
+
+void test_rand()
+{
+  unsigned short a[7];
+  unsigned b;
+  
+  rand();	// expected-warning{{Function 'rand' is obsolete because it implements a poor random number generator.  Use 'arc4random' instead}}
+  drand48();	// expected-warning{{Function 'drand48' is obsolete because it implements a poor random number generator.  Use 'arc4random' instead}}
+  erand48(a);	// expected-warning{{Function 'erand48' is obsolete because it implements a poor random number generator.  Use 'arc4random' instead}}
+  jrand48(a);	// expected-warning{{Function 'jrand48' is obsolete because it implements a poor random number generator.  Use 'arc4random' instead}}
+  lcong48(a);	// expected-warning{{Function 'lcong48' is obsolete because it implements a poor random number generator.  Use 'arc4random' instead}}
+  lrand48();	// expected-warning{{Function 'lrand48' is obsolete because it implements a poor random number generator.  Use 'arc4random' instead}}
+  mrand48();	// expected-warning{{Function 'mrand48' is obsolete because it implements a poor random number generator.  Use 'arc4random' instead}}
+  nrand48(a);	// expected-warning{{Function 'nrand48' is obsolete because it implements a poor random number generator.  Use 'arc4random' instead}}
+  rand_r(&b);	// expected-warning{{Function 'rand_r' is obsolete because it implements a poor random number generator.  Use 'arc4random' instead}}
+  random();	// expected-warning{{The 'random' function produces a sequence of values that an adversary may be able to predict.  Use 'arc4random' instead}}
+}
+
+char *mktemp(char *buf);
+
+void test_mktemp() {
+  char *x = mktemp("/tmp/zxcv"); // expected-warning{{Call to function 'mktemp' is insecure as it always creates or uses insecure temporary file}}
+}
diff --git a/test/Analysis/sizeofpointer.c b/test/Analysis/sizeofpointer.c
new file mode 100644
index 0000000..82fda04
--- /dev/null
+++ b/test/Analysis/sizeofpointer.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -analyze -warn-sizeof-pointer -verify %s
+
+struct s {
+};
+
+int f(struct s *p) {
+  return sizeof(p); // expected-warning{{The code calls sizeof() on a pointer type. This can produce an unexpected result.}}
+}
diff --git a/test/Analysis/stack-addr-ps.c b/test/Analysis/stack-addr-ps.c
new file mode 100644
index 0000000..f8cadbe
--- /dev/null
+++ b/test/Analysis/stack-addr-ps.c
@@ -0,0 +1,77 @@
+// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-store=basic -fblocks -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-store=region -fblocks -verify %s
+
+int* f1() {
+  int x = 0;
+  return &x; // expected-warning{{Address of stack memory associated with local variable 'x' returned.}} expected-warning{{address of stack memory associated with local variable 'x' returned}}
+}
+
+int* f2(int y) {
+  return &y;  // expected-warning{{Address of stack memory associated with local variable 'y' returned.}} expected-warning{{address of stack memory associated with local variable 'y' returned}}
+}
+
+int* f3(int x, int *y) {
+  int w = 0;
+  
+  if (x)
+    y = &w;
+    
+  return y; // expected-warning{{Address of stack memory associated with local variable 'w' returned.}}
+}
+
+void* compound_literal(int x, int y) {
+  if (x)
+    return &(unsigned short){((unsigned short)0x22EF)}; // expected-warning{{Address of stack memory}}
+
+  int* array[] = {};
+  struct s { int z; double y; int w; };
+  
+  if (y)
+    return &((struct s){ 2, 0.4, 5 * 8 }); // expected-warning{{Address of stack memory}}
+    
+  
+  void* p = &((struct s){ 42, 0.4, x ? 42 : 0 });
+  return p; // expected-warning{{Address of stack memory}}
+}
+
+void* alloca_test() {
+  void* p = __builtin_alloca(10);
+  return p; // expected-warning{{Address of stack memory}}
+}
+
+int array_test(int x[2]) {
+  return x[0]; // no-warning
+}
+
+struct baz {
+  int x;
+  int y[2];
+};
+
+int struct_test(struct baz byVal, int flag) {
+  if (flag)  
+    return byVal.x; // no-warning
+  else {
+    return byVal.y[0]; // no-warning
+  }
+}
+
+typedef int (^ComparatorBlock)(int a, int b);
+ComparatorBlock test_return_block(void) {
+  ComparatorBlock b = ^int(int a, int b){ return a > b; };
+  return b; // expected-warning{{Address of stack-allocated block declared on line 61 returned to caller}}
+}
+
+ComparatorBlock test_return_block_neg_aux(void);
+ComparatorBlock test_return_block_neg(void) {
+  ComparatorBlock b = test_return_block_neg_aux();
+  return b; // no-warning
+}
+
+// <rdar://problem/7523821>
+int *rdar_7523821_f2() {
+  int a[3];
+  return a; // expected-warning 2 {{ddress of stack memory associated with local variable 'a' returned}}
+};
+
+
diff --git a/test/Analysis/uninit-msg-expr.m b/test/Analysis/uninit-msg-expr.m
new file mode 100644
index 0000000..4061150
--- /dev/null
+++ b/test/Analysis/uninit-msg-expr.m
@@ -0,0 +1,57 @@
+// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-store=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-store=region -verify %s
+
+//===----------------------------------------------------------------------===//
+// The following code is reduced using delta-debugging from
+// Foundation.h (Mac OS X).
+//
+// It includes the basic definitions for the test cases below.
+// Not directly including Foundation.h directly makes this test case 
+// both svelte and portable to non-Mac platforms.
+//===----------------------------------------------------------------------===//
+
+typedef signed char BOOL;
+typedef unsigned int NSUInteger;
+typedef struct _NSZone NSZone;
+@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+@protocol NSObject  - (BOOL)isEqual:(id)object; @end
+@protocol NSCopying  - (id)copyWithZone:(NSZone *)zone; @end
+@protocol NSMutableCopying  - (id)mutableCopyWithZone:(NSZone *)zone; @end
+@protocol NSCoding  - (void)encodeWithCoder:(NSCoder *)aCoder; @end
+@interface NSObject <NSObject> {} @end
+@class NSString, NSData;
+@class NSString, NSData, NSMutableData, NSMutableDictionary, NSMutableArray;
+typedef struct {} NSFastEnumerationState;
+@protocol NSFastEnumeration
+- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len;
+@end
+@class NSData, NSIndexSet, NSString, NSURL;
+@interface NSArray : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration>
+- (NSUInteger)count;
+@end
+@interface NSArray (NSArrayCreation)
++ (id)array;
+- (NSUInteger)length;
+- (void)addObject:(id)object;
+@end
+extern NSString * const NSUndoManagerCheckpointNotification;
+
+//===----------------------------------------------------------------------===//
+// Test cases.
+//===----------------------------------------------------------------------===//
+
+unsigned f1() {
+  NSString *aString;
+  return [aString length]; // expected-warning {{Receiver in message expression is a garbage value}}
+}
+
+unsigned f2() {
+  NSString *aString = 0;
+  return [aString length]; // no-warning
+}
+
+void f3() {
+  NSMutableArray *aArray = [NSArray array];
+  NSString *aString;
+  [aArray addObject:aString]; // expected-warning {{Pass-by-value argument in message expression is undefined.}}
+}
diff --git a/test/Analysis/uninit-ps-rdar6145427.m b/test/Analysis/uninit-ps-rdar6145427.m
new file mode 100644
index 0000000..1409dbd
--- /dev/null
+++ b/test/Analysis/uninit-ps-rdar6145427.m
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 -analyze -verify -analyzer-store=basic -analyzer-check-objc-mem %s
+// RUN: %clang_cc1 -analyze -verify -analyzer-store=region -analyzer-check-objc-mem %s
+
+// Delta-Debugging reduced preamble.
+typedef signed char BOOL;
+typedef unsigned int NSUInteger;
+@class NSString, Protocol;
+extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, 2)));
+typedef struct _NSZone NSZone;
+@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+@protocol NSObject  - (BOOL)isEqual:(id)object; @end
+@protocol NSCopying  - (id)copyWithZone:(NSZone *)zone; @end
+@protocol NSCoding  - (void)encodeWithCoder:(NSCoder *)aCoder; @end
+@interface NSObject <NSObject> {} + (id)alloc; @end
+extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone);
+@interface NSValue : NSObject <NSCopying, NSCoding>  - (void)getValue:(void *)value; @end
+@class NSString, NSData;
+typedef struct _NSPoint {} NSRange;
+@interface NSValue (NSValueRangeExtensions) 
++ (NSValue *)valueWithRange:(NSRange)range;
+- (id)objectAtIndex:(NSUInteger)index;
+@end
+@interface NSAutoreleasePool : NSObject {} - (void)drain; @end
+extern NSString * const NSBundleDidLoadNotification;
+typedef struct {} NSDecimal;
+@interface NSNetService : NSObject {} - (id)init; @end
+extern NSString * const NSUndoManagerCheckpointNotification;
+
+// Test case: <rdar://problem/6145427>
+
+int main (int argc, const char * argv[]) {
+  NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+  id someUnintializedPointer = [someUnintializedPointer objectAtIndex:0]; // expected-warning{{Receiver in message expression is a garbage value}}
+  NSLog(@"%@", someUnintializedPointer);    
+  [pool drain];
+  return 0;
+}
diff --git a/test/Analysis/uninit-vals-ps-region.m b/test/Analysis/uninit-vals-ps-region.m
new file mode 100644
index 0000000..69c1ecd
--- /dev/null
+++ b/test/Analysis/uninit-vals-ps-region.m
@@ -0,0 +1,69 @@
+// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-store=region -verify %s
+
+struct s {
+  int data;
+};
+
+struct s global;
+
+void g(int);
+
+void f4() {
+  int a;
+  if (global.data == 0)
+    a = 3;
+  if (global.data == 0) // When the true branch is feasible 'a = 3'.
+    g(a); // no-warning
+}
+
+
+// Test uninitialized value due to part of the structure being uninitialized.
+struct TestUninit { int x; int y; };
+struct TestUninit test_uninit_aux();
+void test_unit_aux2(int);
+void test_uninit_pos() {
+  struct TestUninit v1 = { 0, 0 };
+  struct TestUninit v2 = test_uninit_aux();
+  int z;
+  v1.y = z; // expected-warning{{Assigned value is garbage or undefined}}
+  test_unit_aux2(v2.x + v1.y);
+}
+void test_uninit_pos_2() {
+  struct TestUninit v1 = { 0, 0 };
+  struct TestUninit v2;
+  test_unit_aux2(v2.x + v1.y);  // expected-warning{{The left operand of '+' is a garbage value}}
+}
+void test_uninit_pos_3() {
+  struct TestUninit v1 = { 0, 0 };
+  struct TestUninit v2;
+  test_unit_aux2(v1.y + v2.x);  // expected-warning{{The right operand of '+' is a garbage value}}
+}
+
+void test_uninit_neg() {
+  struct TestUninit v1 = { 0, 0 };
+  struct TestUninit v2 = test_uninit_aux();
+  test_unit_aux2(v2.x + v1.y); // no-warning
+}
+
+extern void test_uninit_struct_arg_aux(struct TestUninit arg);
+void test_uninit_struct_arg() {
+  struct TestUninit x;
+  test_uninit_struct_arg_aux(x); // expected-warning{{Passed-by-value struct argument contains uninitialized data (e.g., field: 'x')}}
+}
+
+@interface Foo
+- (void) passVal:(struct TestUninit)arg;
+@end
+void testFoo(Foo *o) {
+  struct TestUninit x;
+  [o passVal:x]; // expected-warning{{Passed-by-value struct argument contains uninitialized data (e.g., field: 'x')}}
+}
+
+// Test case from <rdar://problem/7780304>.  That shows an uninitialized value
+// being used in the LHS of a compound assignment.
+void rdar_7780304() {
+  typedef struct s_r7780304 { int x; } s_r7780304;
+  s_r7780304 b;
+  b.x |= 1; // expected-warning{{The left expression of the compound assignment is an uninitialized value. The computed value will also be garbage}}
+}
+
diff --git a/test/Analysis/uninit-vals-ps.c b/test/Analysis/uninit-vals-ps.c
new file mode 100644
index 0000000..4abd413
--- /dev/null
+++ b/test/Analysis/uninit-vals-ps.c
@@ -0,0 +1,125 @@
+// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-store=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-store=region -verify %s
+
+struct FPRec {
+  void (*my_func)(int * x);  
+};
+
+int bar(int x);
+
+int f1_a(struct FPRec* foo) {
+  int x;
+  (*foo->my_func)(&x);
+  return bar(x)+1; // no-warning
+}
+
+int f1_b() {
+  int x;
+  return bar(x)+1;  // expected-warning{{Pass-by-value argument in function call is undefined.}}
+}
+
+int f2() {
+  
+  int x;
+  
+  if (x+1)  // expected-warning{{The left operand of '+' is a garbage value}}
+    return 1;
+    
+  return 2;  
+}
+
+int f2_b() {
+  int x;
+  
+  return ((1+x)+2+((x))) + 1 ? 1 : 2; // expected-warning{{The right operand of '+' is a garbage value}}
+}
+
+int f3(void) {
+  int i;
+  int *p = &i;
+  if (*p > 0) // expected-warning{{The left operand of '>' is a garbage value}}
+    return 0;
+  else
+    return 1;
+}
+
+void f4_aux(float* x);
+float f4(void) {
+  float x;
+  f4_aux(&x);
+  return x;  // no-warning
+}
+
+struct f5_struct { int x; };
+void f5_aux(struct f5_struct* s);
+int f5(void) {
+  struct f5_struct s;
+  f5_aux(&s);
+  return s.x; // no-warning
+}
+
+int ret_uninit() {
+  int i;
+  int *p = &i;
+  return *p;  // expected-warning{{Undefined or garbage value returned to caller}}
+}
+
+// <rdar://problem/6451816>
+typedef unsigned char Boolean;
+typedef const struct __CFNumber * CFNumberRef;
+typedef signed long CFIndex;
+typedef CFIndex CFNumberType;
+typedef unsigned long UInt32;
+typedef UInt32 CFStringEncoding;
+typedef const struct __CFString * CFStringRef;
+extern Boolean CFNumberGetValue(CFNumberRef number, CFNumberType theType, void *valuePtr);
+extern CFStringRef CFStringConvertEncodingToIANACharSetName(CFStringEncoding encoding);
+
+CFStringRef rdar_6451816(CFNumberRef nr) {
+  CFStringEncoding encoding;
+  // &encoding is casted to void*.  This test case tests whether or not
+  // we properly invalidate the value of 'encoding'.
+  CFNumberGetValue(nr, 9, &encoding);
+  return CFStringConvertEncodingToIANACharSetName(encoding); // no-warning
+}
+
+// PR 4630 - false warning with nonnull attribute
+//  This false positive (due to a regression) caused the analyzer to falsely
+//  flag a "return of uninitialized value" warning in the first branch due to
+//  the nonnull attribute.
+void pr_4630_aux(char *x, int *y) __attribute__ ((nonnull (1)));
+void pr_4630_aux_2(char *x, int *y);
+int pr_4630(char *a, int y) {
+  int x;
+  if (y) {
+    pr_4630_aux(a, &x);
+    return x;   // no-warning
+  }
+  else {
+    pr_4630_aux_2(a, &x);
+    return x;   // no-warning
+  }
+}
+
+// PR 4631 - False positive with union initializer
+//  Previously the analyzer didn't examine the compound initializers of unions,
+//  resulting in some false positives for initializers with side-effects.
+union u_4631 { int a; };
+struct s_4631 { int a; };
+int pr4631_f2(int *p);
+int pr4631_f3(void *q);
+int pr4631_f1(void)
+{
+  int x;
+  union u_4631 m = { pr4631_f2(&x) };
+  pr4631_f3(&m); // tell analyzer that we use m
+  return x;  // no-warning
+}
+int pr4631_f1_b(void)
+{
+  int x;
+  struct s_4631 m = { pr4631_f2(&x) };
+  pr4631_f3(&m); // tell analyzer that we use m
+  return x;  // no-warning
+}
+
diff --git a/test/Analysis/uninit-vals.c b/test/Analysis/uninit-vals.c
new file mode 100644
index 0000000..b0769ba
--- /dev/null
+++ b/test/Analysis/uninit-vals.c
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 -analyze -warn-uninit-values -verify %s
+
+int f1() {
+  int x;
+  return x; // expected-warning {{use of uninitialized variable}}
+}
+
+int f2(int x) {
+  int y;
+  int z = x + y; // expected-warning {{use of uninitialized variable}}
+  return z;
+}
+
+
+int f3(int x) {
+  int y;
+  return x ? 1 : y; // expected-warning {{use of uninitialized variable}}
+}
+
+int f4(int x) {
+  int y;
+  if (x) y = 1;
+  return y; // expected-warning {{use of uninitialized variable}}
+}
+
+void f5() {
+  int a;
+  a = 30; // no-warning
+}
+
+void f6(int i) {
+  int x;
+  for (i = 0 ; i < 10; i++)
+    printf("%d",x++); // expected-warning {{use of uninitialized variable}} \
+  // expected-warning{{implicitly declaring C library function 'printf' with type 'int (char const *, ...)'}} \
+  // expected-note{{please include the header <stdio.h> or explicitly provide a declaration for 'printf'}}
+}
+
+void f7(int i) {
+  int x = i;
+  int y;
+  for (i = 0; i < 10; i++ ) {
+    printf("%d",x++); // no-warning
+    x += y; // expected-warning {{use of uninitialized variable}}
+  }
+}
+
+int f8(int j) {
+  int x = 1, y = x + 1;
+  if (y) // no-warning
+    return x;
+  return y;
+}
diff --git a/test/Analysis/uninit-vals.m b/test/Analysis/uninit-vals.m
new file mode 100644
index 0000000..2f7f29c
--- /dev/null
+++ b/test/Analysis/uninit-vals.m
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-store=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-store=region -verify %s
+
+typedef unsigned int NSUInteger;
+
+@interface A
+- (NSUInteger)foo;
+@end
+
+NSUInteger f8(A* x){
+  const NSUInteger n = [x foo];
+  int* bogus;  
+
+  if (n > 0) {    // tests const cast transfer function logic
+    NSUInteger i;
+    
+    for (i = 0; i < n; ++i)
+      bogus = 0;
+
+    if (bogus)  // no-warning
+      return n+1;
+  }
+  
+  return n;
+}
diff --git a/test/Analysis/unions-region.m b/test/Analysis/unions-region.m
new file mode 100644
index 0000000..180faf8
--- /dev/null
+++ b/test/Analysis/unions-region.m
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range %s -verify
+
+//===-- unions-region.m ---------------------------------------------------===//
+//
+// This file tests the analyzer's reasoning about unions.
+//
+//===----------------------------------------------------------------------===//
+
+// [testA] When using RegionStore, this test case previously had a
+// false positive of a 'pass-by-value argument is uninitialized'
+// warning at the call to 'testA_aux' and 'testA_aux_2'.
+union u_testA {
+  unsigned i;
+  float f;
+};
+ 
+float testA(float f) {
+  int testA_aux(unsigned x);
+  int testA_aux_2(union u_testA z);
+  
+  union u_testA swap;
+  swap.f = f;
+
+  if (testA_aux(swap.i))  // no-warning
+    swap.i = ((swap.i & 0xffff0000) >> 16) | ((swap.i & 0x0000fffff) << 16);
+
+  testA_aux_2(swap); // no-warning
+
+  return swap.f;  
+}
+
+// [testB] When using RegionStore, this test case previously had a
+// false positive of a 'pass-by-value argument is uninitialized'
+// warning at the call to 'testB_aux'.
+void testB(int i) {
+  void testB_aux(short z);
+  union { short x[2]; unsigned y; } val;  
+  val.y = 10;
+  testB_aux(val.x[1]); // no-warning
+}
+
diff --git a/test/Analysis/unix-fns.c b/test/Analysis/unix-fns.c
new file mode 100644
index 0000000..9d036ac
--- /dev/null
+++ b/test/Analysis/unix-fns.c
@@ -0,0 +1,52 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-check-objc-mem %s -analyzer-store=region -fblocks -verify
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-check-objc-mem %s -analyzer-store=basic -fblocks -verify
+
+struct _opaque_pthread_once_t {
+  long __sig;
+  char __opaque[8];
+};
+typedef struct _opaque_pthread_once_t    __darwin_pthread_once_t;
+typedef __darwin_pthread_once_t pthread_once_t;
+int pthread_once(pthread_once_t *, void (*)(void));
+
+typedef void (^dispatch_block_t)(void);
+typedef long dispatch_once_t;
+void dispatch_once(dispatch_once_t *predicate, dispatch_block_t block);
+
+#ifndef O_CREAT
+#define O_CREAT 0x0200
+#define O_RDONLY 0x0000
+#endif
+int open(const char *, int, ...);
+int close(int fildes);
+
+void test_open(const char *path) {
+  int fd;
+  fd = open(path, O_RDONLY); // no-warning
+  if (!fd)
+    close(fd);
+
+  fd = open(path, O_CREAT); // expected-warning{{Call to 'open' requires a third argument when the 'O_CREAT' flag is set}}
+  if (!fd)
+    close(fd);
+} 
+
+void test_dispatch_once() {
+  dispatch_once_t pred = 0;
+  do { if (__builtin_expect(*(&pred), ~0l) != ~0l) dispatch_once((&pred), (^() {})); } while (0); // expected-warning{{Call to 'dispatch_once' uses the local variable 'pred' for the predicate value}}
+}
+void test_dispatch_once_neg() {
+  static dispatch_once_t pred = 0;
+  do { if (__builtin_expect(*(&pred), ~0l) != ~0l) dispatch_once((&pred), (^() {})); } while (0); // no-warning
+}
+
+void test_pthread_once_aux();
+
+void test_pthread_once() {
+  pthread_once_t pred = {0x30B1BCBA, {0}};
+  pthread_once(&pred, test_pthread_once_aux); // expected-warning{{Call to 'pthread_once' uses the local variable 'pred' for the "control" value}}
+}
+void test_pthread_once_neg() {
+  static pthread_once_t pred = {0x30B1BCBA, {0}};
+  pthread_once(&pred, test_pthread_once_aux); // no-warning
+}
diff --git a/test/Analysis/unused-ivars.m b/test/Analysis/unused-ivars.m
new file mode 100644
index 0000000..14c43a8
--- /dev/null
+++ b/test/Analysis/unused-ivars.m
@@ -0,0 +1,98 @@
+// RUN: %clang_cc1 -fblocks -analyze -analyzer-check-objc-unused-ivars %s -verify
+
+//===--- BEGIN: Delta-debugging reduced headers. --------------------------===//
+
+@protocol NSObject
+- (id)retain;
+- (oneway void)release;
+@end
+@interface NSObject <NSObject> {}
+- (id)init;
++ (id)alloc;
+@end
+
+//===--- END: Delta-debugging reduced headers. ----------------------------===//
+
+// This test case tests the basic functionality of the unused ivar test.
+@interface TestA {
+@private
+  int x; // expected-warning {{Instance variable 'x' in class 'TestA' is never used}}
+}
+@end
+@implementation TestA @end
+
+// This test case tests whether the unused ivar check handles blocks that
+// reference an instance variable. (<rdar://problem/7075531>)
+@interface TestB : NSObject {
+@private
+  id _ivar; // no-warning
+}
+@property (readwrite,retain) id ivar;
+@end
+
+@implementation TestB
+- (id)ivar {
+  __attribute__((__blocks__(byref))) id value = ((void*)0);
+  void (^b)() = ^{ value = _ivar; };
+  b();
+  return value;
+}
+
+- (void)setIvar:(id)newValue {
+  void (^b)() = ^{ [_ivar release]; _ivar = [newValue retain]; };
+  b();
+}
+@end
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/6260004> Detect that ivar is in use, if used in category 
+//  in the same file as the implementation
+//===----------------------------------------------------------------------===//
+
+@protocol Protocol6260004
+- (id) getId;
+@end
+
+@interface RDar6260004 {
+@private
+  id x; // no-warning
+}
+@end
+@implementation RDar6260004 @end
+@implementation RDar6260004 (Protocol6260004)
+- (id) getId {
+  return x;
+}
+@end
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/7254495> - ivars referenced by lexically nested functions
+//  should not be flagged as unused
+//===----------------------------------------------------------------------===//
+
+@interface RDar7254495 {
+@private
+  int x; // no-warning
+}
+@end
+
+@implementation RDar7254495
+int radar_7254495(RDar7254495 *a) {
+  return a->x;
+}
+@end
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/7353683> - consult attribute((unused)) to silence warnings
+// about unused instance variables
+//===----------------------------------------------------------------------===//
+
+@interface RDar7353683 {
+@private
+  id x __attribute__((unused));
+}
+@end
+
+@implementation RDar7353683
+@end
+
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
new file mode 100644
index 0000000..6bb5b6c
--- /dev/null
+++ b/test/CMakeLists.txt
@@ -0,0 +1,80 @@
+set(CLANG_TEST_DIRECTORIES
+  "Analysis"
+  "CodeCompletion"
+  "CodeGen"
+  "CodeGenCXX"
+  "CodeGenObjC"
+  "Coverage"
+  "CXX"
+  "Driver"
+  "FixIt"
+  "Frontend"
+  "Headers"
+  "Index"
+  "Lexer"
+  "Misc"
+  "PCH"
+  "Parser"
+  "Preprocessor"
+  "Rewriter"
+  "Sema"
+  "SemaCXX"
+  "SemaObjC"
+  "SemaObjCXX"
+  "SemaTemplate")
+
+set(LLVM_SOURCE_DIR "${LLVM_MAIN_SRC_DIR}")
+set(LLVM_BINARY_DIR "${LLVM_BINARY_DIR}")
+set(LLVM_TOOLS_DIR "${LLVM_TOOLS_BINARY_DIR}/%(build_config)s")
+set(LLVM_LIBS_DIR "${LLVM_BINARY_DIR}/lib/%(build_config)s")
+set(CLANG_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/..")
+set(CLANG_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/..")
+
+configure_file(
+  ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in
+  ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg)
+
+include(FindPythonInterp)
+if(PYTHONINTERP_FOUND)
+  set(CLANG_TEST_EXTRA_ARGS)
+  if (MSVC OR XCODE)
+    set(CLANG_TEST_EXTRA_ARGS "--no-progress-bar")
+  endif()
+
+  option(CLANG_TEST_USE_VG "Run Clang tests under Valgrind" OFF)
+  if(CLANG_TEST_USE_VG)
+    set(CLANG_TEST_EXTRA_ARGS ${CLANG_TEST_EXTRA_ARGS} "--vg")
+  endif ()
+
+  foreach(testdir ${CLANG_TEST_DIRECTORIES})
+    add_custom_target(clang-test-${testdir}
+      COMMAND ${PYTHON_EXECUTABLE}
+                  ${LLVM_SOURCE_DIR}/utils/lit/lit.py
+                  --param clang_site_config=${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg
+                  --param build_config=${CMAKE_CFG_INTDIR}
+                  -sv ${CLANG_TEST_EXTRA_ARGS}
+                  ${CMAKE_CURRENT_BINARY_DIR}/${testdir}
+                  DEPENDS clang c-index-test
+                  COMMENT "Running Clang regression tests in ${testdir}")
+  endforeach()
+
+  add_custom_target(clang-test
+    COMMAND ${PYTHON_EXECUTABLE}
+                ${LLVM_SOURCE_DIR}/utils/lit/lit.py
+                --param clang_site_config=${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg
+                --param build_config=${CMAKE_CFG_INTDIR}
+                -sv ${CLANG_TEST_EXTRA_ARGS}
+                ${CMAKE_CURRENT_BINARY_DIR}
+                DEPENDS clang c-index-test
+                COMMENT "Running Clang regression tests")
+
+  add_custom_target(clang-c++tests
+    COMMAND ${PYTHON_EXECUTABLE}
+                ${LLVM_SOURCE_DIR}/utils/lit/lit.py
+                --param clang_site_config=${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg
+                --param build_config=${CMAKE_CFG_INTDIR}
+                -sv ${CLANG_TEST_EXTRA_ARGS}
+                ${CMAKE_CURRENT_SOURCE_DIR}/../utils/C++Tests
+                DEPENDS clang c-index-test
+                COMMENT "Running Clang regression tests")
+endif()
diff --git a/test/CXX/basic/basic.def.odr/p1-var.cpp b/test/CXX/basic/basic.def.odr/p1-var.cpp
new file mode 100644
index 0000000..892f546
--- /dev/null
+++ b/test/CXX/basic/basic.def.odr/p1-var.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// C++ [basic.def.odr]p1:
+//   No translation unit shall contain more than one definition of any
+//   variable, [...].
+
+// Bad: in C++, these are both definitions. None of that C99 tentative stuff.
+int i; // expected-note {{previous}}
+int i; // expected-error {{redefinition}}
+
+// OK: decl + def
+extern int j;
+int j;
+
+// OK: def + decl
+int k;
+extern int k;
+
+// Bad. The important thing here is that we don't emit the diagnostic twice.
+int l = 1; // expected-note {{previous}}
+int l = 2; // expected-error {{redefinition}}
diff --git a/test/CXX/basic/basic.def.odr/p2-typeid.cpp b/test/CXX/basic/basic.def.odr/p2-typeid.cpp
new file mode 100644
index 0000000..55debe3
--- /dev/null
+++ b/test/CXX/basic/basic.def.odr/p2-typeid.cpp
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// C++ [basic.def.odr]p2:
+//   An expression is potentially evaluated unless it [...] is the
+//   operand of the typeid operator and the expression does not
+//   designate an lvalue of polymorphic class type.
+
+// FIXME: This should really include <typeinfo>, but we don't have that yet.
+namespace std {
+  class type_info;
+}
+
+struct Poly {
+  virtual ~Poly();
+};
+
+struct NonPoly { };
+
+template<typename T, typename Result = T> 
+struct X {
+  Result f(T t) { return t + t; } // expected-error{{invalid operands}}
+
+  void g(T t) {
+    (void)typeid(f(t)); // expected-note{{here}}
+  }
+};
+
+void test(X<Poly> xp, X<Poly, Poly&> xpr, X<NonPoly> xnp, X<NonPoly, NonPoly&> xnpr) {
+  // These are okay (although GCC and EDG get them wrong).
+  xp.g(Poly());
+  xnp.g(NonPoly());
+  xnpr.g(NonPoly());
+
+  // Triggers an error (as it should);
+  xpr.g(Poly()); // expected-note{{instantiation of member function}}
+}
diff --git a/test/CXX/basic/basic.link/p9.cpp b/test/CXX/basic/basic.link/p9.cpp
new file mode 100644
index 0000000..bd16b02
--- /dev/null
+++ b/test/CXX/basic/basic.link/p9.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// FIXME: This test is woefully incomplete.
+namespace N { } // expected-note{{here}}
+
+// First bullet: two names with external linkage that refer to
+// different kinds of entities.
+void f() {
+  int N(); // expected-error{{redefinition}}
+}
+
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2-template-id.cpp b/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2-template-id.cpp
new file mode 100644
index 0000000..f650ad5
--- /dev/null
+++ b/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2-template-id.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace N1 {
+  struct X { };
+  int& f(void*);
+}
+
+namespace N2 {
+  template<typename T> struct Y { };
+}
+
+namespace N3 {
+  void test() {
+    int &ir = f((N2::Y<N1::X>*)0);
+  }
+}
+
+int g(void *);
+long g(N1::X);
+
+namespace N1 {
+  void h(int (*)(void *));
+}
+
+void test() {
+  h((&g));
+}
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2.cpp b/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2.cpp
new file mode 100644
index 0000000..ee01416
--- /dev/null
+++ b/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2.cpp
@@ -0,0 +1,73 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace N {
+  struct X { };
+  
+  X operator+(X, X);
+
+  void f(X);
+  void g(X); // expected-note{{candidate function}}
+
+  void test_multiadd(X x) {
+    (void)(x + x);
+  }
+}
+
+namespace M {
+  struct Y : N::X { };
+}
+
+void f();
+
+void test_operator_adl(N::X x, M::Y y) {
+  (void)(x + x);
+  (void)(y + y);
+}
+
+void test_func_adl(N::X x, M::Y y) {
+  f(x);
+  f(y);
+  (f)(x); // expected-error{{too many arguments to function call}}
+  ::f(x); // expected-error{{too many arguments to function call}}
+}
+
+namespace N {
+  void test_multiadd2(X x) {
+    (void)(x + x);
+  }
+}
+
+
+void test_func_adl_only(N::X x) {
+  g(x);
+}
+
+namespace M {
+  int g(N::X); // expected-note{{candidate function}}
+
+  void test(N::X x) {
+    g(x); // expected-error{{call to 'g' is ambiguous; candidates are:}}
+    int i = (g)(x);
+
+    int g(N::X);
+    g(x); // okay; calls locally-declared function, no ADL
+  }
+}
+
+
+void test_operator_name_adl(N::X x) {
+  (void)operator+(x, x);
+}
+
+struct Z { };
+int& f(Z);
+
+namespace O {
+  char &f();
+  void test_global_scope_adl(Z z) {
+    {
+      int& ir = f(z);
+    }
+  }
+}
+
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.argdep/p3.cpp b/test/CXX/basic/basic.lookup/basic.lookup.argdep/p3.cpp
new file mode 100644
index 0000000..c4c2c8d
--- /dev/null
+++ b/test/CXX/basic/basic.lookup/basic.lookup.argdep/p3.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// FIXME: embellish
+
+namespace test0 {
+  namespace A {
+    class Foo {
+    };
+
+    void foo(const Foo &foo);
+  }
+
+  class Test {
+    enum E { foo = 0 };
+
+    void test() {
+      foo(A::Foo()); // expected-error {{not a function}}
+    }
+  };
+}
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.argdep/p4.cpp b/test/CXX/basic/basic.lookup/basic.lookup.argdep/p4.cpp
new file mode 100644
index 0000000..df3429e
--- /dev/null
+++ b/test/CXX/basic/basic.lookup/basic.lookup.argdep/p4.cpp
@@ -0,0 +1,54 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace A {
+  class A {
+    friend void func(A);
+    friend A operator+(A,A);
+  };
+}
+
+namespace B {
+  class B {
+    static void func(B);
+  };
+  B operator+(B,B);
+}
+
+namespace D {
+  class D {};
+}
+
+namespace C {
+  class C {};
+  void func(C);
+  C operator+(C,C);
+  D::D operator+(D::D,D::D);
+}
+
+namespace D {
+  using namespace C;
+}
+
+namespace Test {
+  void test() {
+    func(A::A());
+    func(B::B()); // expected-error {{use of undeclared identifier 'func'}}
+    func(C::C());
+    A::A() + A::A();
+    B::B() + B::B();
+    C::C() + C::C();
+    D::D() + D::D(); // expected-error {{ invalid operands to binary expression ('D::D' and 'D::D') }}
+  }
+}
+
+// PR6716
+namespace test1 {
+  template <class T> class A {
+    template <class U> friend void foo(A &, U); // expected-note {{not viable: 1st argument ('A<int> const') would lose const qualifier}}
+  };
+
+  void test() {
+    const A<int> a;
+    foo(a, 10); // expected-error {{no matching function for call to 'foo'}}
+  }
+}
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.classref/p3.cpp b/test/CXX/basic/basic.lookup/basic.lookup.classref/p3.cpp
new file mode 100644
index 0000000..4a0b387
--- /dev/null
+++ b/test/CXX/basic/basic.lookup/basic.lookup.classref/p3.cpp
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// C++0x [basic.lookup.classref]p3:
+//   If the unqualified-id is ∼type-name, the type-name is looked up in the 
+//   context of the entire postfix-expression. If the type T of the object 
+//   expression is of a class type C, the type-name is also looked up in the 
+//   scope of class C. At least one of the lookups shall find a name that 
+//   refers to (possibly cv-qualified) T.
+
+// From core issue 305
+struct A {
+};
+
+struct C {
+  struct A {};
+  void f ();
+};
+
+void C::f () {
+  ::A *a;
+  a->~A ();
+}
+
+// From core issue 414
+struct X {};
+void f() {
+  X x;
+  struct X {};
+  x.~X();
+}
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.elab/p2.cpp b/test/CXX/basic/basic.lookup/basic.lookup.elab/p2.cpp
new file mode 100644
index 0000000..004d1e4
--- /dev/null
+++ b/test/CXX/basic/basic.lookup/basic.lookup.elab/p2.cpp
@@ -0,0 +1,60 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace test0 {
+  struct A {
+    static int foo;
+  };
+  
+  namespace i0 {
+    typedef int A; // expected-note {{declared here}}
+
+    int test() {
+      struct A a; // expected-error {{elaborated type refers to a typedef}}
+      return a.foo;
+    }
+  }
+
+  namespace i1 {
+    template <class> class A; // expected-note {{declared here}}
+
+    int test() {
+      struct A a; // expected-error {{elaborated type refers to a template}}
+      return a.foo;
+    }
+  }
+
+  namespace i2 {
+    int A;
+
+    int test() {
+      struct A a;
+      return a.foo;
+    }
+  }
+
+  namespace i3 {
+    void A();
+
+    int test() {
+      struct A a;
+      return a.foo;
+    }
+  }
+
+  namespace i4 {
+    template <class T> void A();
+
+    int test() {
+      struct A a;
+      return a.foo;
+    }
+  }
+
+  // This should magically be okay;  see comment in SemaDecl.cpp.
+  // rdar://problem/7898108
+  typedef struct A A;
+  int test() {
+    struct A a;
+    return a.foo;
+  }
+}
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.elab/templateid.cpp b/test/CXX/basic/basic.lookup/basic.lookup.elab/templateid.cpp
new file mode 100644
index 0000000..8126d28
--- /dev/null
+++ b/test/CXX/basic/basic.lookup/basic.lookup.elab/templateid.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// elaborated-type-specifier:
+//   class-key '::'? nested-name-specifier? 'template'? simple-template-id
+// Tests that this form is accepted by the compiler but does not follow
+// the elaborated lookup rules of [basic.lookup.elab].
+
+template <typename> class Ident {}; // expected-note {{previous use is here}}
+
+namespace A {
+  template <typename> void Ident();
+
+  class Ident<int> AIdent; // expected-error {{refers to a function template}}
+  class ::Ident<int> AnotherIdent;
+}
+
+class Ident<int> GlobalIdent;
+union Ident<int> GlobalIdent2; // expected-error {{ tag type that does not match }}
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp b/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp
new file mode 100644
index 0000000..7ecedd5
--- /dev/null
+++ b/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+struct X0 {
+  X0 f1();
+  X0 f2();
+};
+
+template<typename T>
+struct X1 {
+  X1<T>(int);
+  (X1<T>)(float);
+  X1 f2();
+  X1 f2(int);
+  X1 f2(float);
+};
+
+// Error recovery: out-of-line constructors whose names have template arguments.
+template<typename T> X1<T>::X1<T>(int) { } // expected-error{{out-of-line constructor for 'X1' cannot have template arguments}}
+template<typename T> (X1<T>::X1<T>)(float) { } // expected-error{{out-of-line constructor for 'X1' cannot have template arguments}}
+
+// Error recovery: out-of-line constructor names intended to be types
+X0::X0 X0::f1() { return X0(); } // expected-error{{qualified reference to 'X0' is a constructor name rather than a type wherever a constructor can be declared}}
+
+struct X0::X0 X0::f2() { return X0(); }
+
+template<typename T> X1<T>::X1<T> X1<T>::f2() { } // expected-error{{qualified reference to 'X1' is a constructor name rather than a template name wherever a constructor can be declared}}
+template<typename T> X1<T>::X1<T> (X1<T>::f2)(int) { } // expected-error{{qualified reference to 'X1' is a constructor name rather than a template name wherever a constructor can be declared}}
+template<typename T> struct X1<T>::X1<T> (X1<T>::f2)(float) { }
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p2.cpp b/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p2.cpp
new file mode 100644
index 0000000..3039396
--- /dev/null
+++ b/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p2.cpp
@@ -0,0 +1,65 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace Ints {
+  int zero = 0; // expected-note {{candidate found by name lookup is 'Ints::zero'}}
+  void f(int); // expected-note 3 {{candidate function}}
+  void g(int);
+}
+
+namespace Floats {
+  float zero = 0.0f; // expected-note {{candidate found by name lookup is 'Floats::zero'}}
+  void f(float); // expected-note 3 {{candidate function}}
+  void g(float);
+}
+
+namespace Numbers {
+  using namespace Ints;
+  using namespace Floats;
+}
+
+void test() {
+  int i = Ints::zero;
+  Ints::f(i);
+  
+  float f = Floats::zero;
+  Floats::f(f);
+  
+  double n = Numbers::zero; // expected-error {{reference to 'zero' is ambiguous}}
+  Numbers::f(n); // expected-error{{call to 'f' is ambiguous}}
+  Numbers::f(i);
+  Numbers::f(f);
+}
+
+namespace Numbers {
+  struct Number {	// expected-note 2 {{candidate}}
+    explicit Number(double d) : d(d) {}
+    double d;
+  };
+  Number zero(0.0f);
+  void g(Number); // expected-note 2{{passing argument to parameter here}}
+}
+
+void test2() {
+  Numbers::Number n = Numbers::zero;
+  Numbers::f(n); // expected-error {{no matching function for call to 'f'}}
+  Numbers::g(n);
+}
+
+namespace Numbers2 {
+  using Numbers::f;
+  using Numbers::g;
+}
+
+void test3() {
+  Numbers::Number n = Numbers::zero;
+  Numbers2::f(n); // expected-error {{no matching function for call to 'f'}}
+  Numbers2::g(n);
+
+  int i = Ints::zero;
+  Numbers2::f(i);
+  Numbers2::g(i); // expected-error {{no viable conversion from 'int' to 'Numbers::Number'}}
+
+  float f = Floats::zero;
+  Numbers2::f(f);
+  Numbers2::g(f); // expected-error {{no viable conversion from 'float' to 'Numbers::Number'}}
+}
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p3.cpp b/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p3.cpp
new file mode 100644
index 0000000..dc0f8b4
--- /dev/null
+++ b/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p3.cpp
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// This is basically paraphrased from the standard.
+
+namespace Root {
+  int i = 0;
+  void f();
+}
+
+namespace A {
+  using namespace Root;
+}
+
+namespace B {
+  using namespace Root;
+}
+
+namespace AB {
+  using namespace A;
+  using namespace B;
+}
+
+void test() {
+  if (AB::i)
+    AB::f();
+}
+
+namespace C {
+  using Root::i;
+  using Root::f;
+}
+
+namespace AC {
+  using namespace A;
+  using namespace C;
+}
+
+void test2() {
+  if (AC::i)
+    AC::f();
+}
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p4.cpp b/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p4.cpp
new file mode 100644
index 0000000..38eccfa
--- /dev/null
+++ b/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p4.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace A {
+  int a;
+}
+
+namespace C {
+  int c;
+}
+
+namespace B {
+  using namespace C;
+  int b;
+}
+
+namespace C {
+  using namespace B;
+  using namespace A;
+}
+
+void test() {
+  C::a++;
+  C::b++;
+  C::c++;
+}
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p5.cpp b/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p5.cpp
new file mode 100644
index 0000000..5045bac
--- /dev/null
+++ b/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p5.cpp
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace A {
+  struct x {}; // expected-note {{candidate found by name lookup is 'A::x'}}
+  int x; // expected-note {{candidate found by name lookup is 'A::x'}}
+
+  struct y {}; // expected-note {{type declaration hidden}}
+
+  struct z;
+  void z(float);
+}
+
+namespace B {
+  struct x {}; // expected-note {{candidate found by name lookup is 'B::x'}}
+  float x; // expected-note {{candidate found by name lookup is 'B::x'}}
+
+  float y; // expected-note {{declaration hides type}}
+
+  void z(int);
+}
+
+namespace AB {
+  using namespace A;
+  using namespace B;
+}
+
+void test() {
+  struct AB::x foo; // expected-error {{reference to 'x' is ambiguous}}
+  int i = AB::x; // expected-error {{reference to 'x' is ambiguous}}
+
+  struct AB::y bar;
+  float f = AB::y; // expected-error {{a type named 'y' is hidden by a declaration in a different namespace}}
+  AB::z(i);
+  AB::z(f);
+}
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.qual/p6-0x.cpp b/test/CXX/basic/basic.lookup/basic.lookup.qual/p6-0x.cpp
new file mode 100644
index 0000000..35efba5
--- /dev/null
+++ b/test/CXX/basic/basic.lookup/basic.lookup.qual/p6-0x.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+struct C { 
+  typedef int I;
+}; 
+
+typedef int I1, I2; 
+extern int* p; 
+extern int* q; 
+
+void f() {
+  p->C::I::~I(); 
+  q->I1::~I2();
+}
+
+struct A { 
+  ~A();
+}; 
+
+typedef A AB; 
+int main() {
+  AB *p; 
+  p->AB::~AB();
+}
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.qual/p6.cpp b/test/CXX/basic/basic.lookup/basic.lookup.qual/p6.cpp
new file mode 100644
index 0000000..633d5cd
--- /dev/null
+++ b/test/CXX/basic/basic.lookup/basic.lookup.qual/p6.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct C { 
+  typedef int I;
+}; 
+
+typedef int I1, I2; 
+extern int* p; 
+extern int* q; 
+
+void f() {
+  p->C::I::~I(); 
+  q->I1::~I2();
+}
+
+struct A { 
+  ~A();
+}; 
+
+typedef A AB; 
+int main() {
+  AB *p; 
+  p->AB::~AB(); // expected-error{{identifier 'AB' in pseudo-destructor expression does not name a type}}
+}
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.udir/p1.cpp b/test/CXX/basic/basic.lookup/basic.lookup.udir/p1.cpp
new file mode 100644
index 0000000..ab0dc24
--- /dev/null
+++ b/test/CXX/basic/basic.lookup/basic.lookup.udir/p1.cpp
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// When looking up a namespace-name in a using-directive or
+// namespace-alias-definition, only namespace names are considered.
+
+struct ns1 {};
+void ns2();
+int ns3 = 0;
+
+namespace ns0 {
+  namespace ns1 {
+    struct test0 {};
+  }
+  namespace ns2 {
+    struct test1 {};
+  }
+  namespace ns3 {
+    struct test2 {};
+  }
+}
+
+using namespace ns0;
+
+namespace test3 = ns1;
+namespace test4 = ns2;
+namespace test5 = ns3;
+
+using namespace ns1;
+using namespace ns2;
+using namespace ns3;
+
+test0 a;
+test1 b;
+test2 c;
+
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.unqual/p11.cpp b/test/CXX/basic/basic.lookup/basic.lookup.unqual/p11.cpp
new file mode 100644
index 0000000..a1cf529
--- /dev/null
+++ b/test/CXX/basic/basic.lookup/basic.lookup.unqual/p11.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+static const int a = 10;
+
+void f0(int a, 
+        int b = a) { // expected-error {{default argument references parameter 'a'}}
+}
+
+template<int a, 
+         int b = a>
+class A {
+};
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.unqual/p12.cpp b/test/CXX/basic/basic.lookup/basic.lookup.unqual/p12.cpp
new file mode 100644
index 0000000..878ff07
--- /dev/null
+++ b/test/CXX/basic/basic.lookup/basic.lookup.unqual/p12.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct S {};
+S E0;
+
+namespace {
+  enum {
+    E0 = 1,
+    E1 = E0 + 1
+  };
+}
+
+
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.unqual/p13.cpp b/test/CXX/basic/basic.lookup/basic.lookup.unqual/p13.cpp
new file mode 100644
index 0000000..58d7ff4
--- /dev/null
+++ b/test/CXX/basic/basic.lookup/basic.lookup.unqual/p13.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct S {
+  static const int f0 = 0;
+  static int f1;
+};
+
+int S::f1 = f0;
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.unqual/p14.cpp b/test/CXX/basic/basic.lookup/basic.lookup.unqual/p14.cpp
new file mode 100644
index 0000000..0fa4f65
--- /dev/null
+++ b/test/CXX/basic/basic.lookup/basic.lookup.unqual/p14.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// C++0x [basic.lookup.unqual]p14:
+//   If a variable member of a namespace is defined outside of the
+//   scope of its namespace then any name used in the definition of
+//   the variable member (after the declarator-id) is looked up as if
+//   the definition of the variable member occurred in its namespace.
+
+namespace N { 
+  struct S {};
+  S i; 
+  extern S j;
+  extern S j2;
+} 
+
+int i = 2; 
+N::S N::j = i;
+N::S N::j2(i);
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.unqual/p15.cpp b/test/CXX/basic/basic.lookup/basic.lookup.unqual/p15.cpp
new file mode 100644
index 0000000..253d15e
--- /dev/null
+++ b/test/CXX/basic/basic.lookup/basic.lookup.unqual/p15.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// XFAIL: *
+
+class C {
+public:
+  C(int a, int b);
+};
+
+C::C(int a, // expected-note {{previous definition}}
+     int b) // expected-note {{previous definition}}
+try {
+  int c;
+
+} catch (int a) { // expected-error {{redefinition of 'a'}}
+  int b; // expected-error {{redefinition of 'b'}}
+  ++c; // expected-error {{use of undeclared identifier 'c'}}
+}
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.unqual/p3.cpp b/test/CXX/basic/basic.lookup/basic.lookup.unqual/p3.cpp
new file mode 100644
index 0000000..20a7ae0
--- /dev/null
+++ b/test/CXX/basic/basic.lookup/basic.lookup.unqual/p3.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+typedef int f; 
+
+namespace N0 {
+  struct A { 
+    friend void f(); 
+    void g() {
+      int i = f(1);
+    }
+  };
+}
+
+namespace N1 {
+  struct A { 
+    friend void f(A &);
+    operator int();
+    void g(A a) {
+      // ADL should not apply to the lookup of 'f', it refers to the typedef
+      // above.
+      int i = f(a);
+    }
+  };
+}
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.unqual/p7.cpp b/test/CXX/basic/basic.lookup/basic.lookup.unqual/p7.cpp
new file mode 100644
index 0000000..d2afd5d
--- /dev/null
+++ b/test/CXX/basic/basic.lookup/basic.lookup.unqual/p7.cpp
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// PR5741
+namespace test0 {
+  struct A {
+    struct B { };
+    struct C;
+  };
+
+  struct A::C : B { };
+}
+
+// Test that successive base specifiers don't screw with each other.
+namespace test1 {
+  struct Opaque1 {};
+  struct Opaque2 {};
+
+  struct A {
+    struct B { B(Opaque1); };
+  };
+  struct B {
+    B(Opaque2);
+  };
+
+  struct C : A, B {
+    // Apparently the base-or-member lookup is actually ambiguous
+    // without this qualification.
+    C() : A(), test1::B(Opaque2()) {}
+  };
+}
+
+// Test that we don't find the injected class name when parsing base
+// specifiers.
+namespace test2 {
+  template <class T> struct bar {};
+  template <class T> struct foo : bar<foo> {}; // expected-error {{use of class template foo requires template arguments}} expected-note {{template is declared here}}
+}
diff --git a/test/CXX/basic/basic.start/basic.start.main/p2a.cpp b/test/CXX/basic/basic.start/basic.start.main/p2a.cpp
new file mode 100644
index 0000000..b8dfbe7
--- /dev/null
+++ b/test/CXX/basic/basic.start/basic.start.main/p2a.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s 
+
+typedef int Int;
+typedef char Char;
+typedef Char* Carp;
+
+Int main(Int argc, Carp argv[]) {
+}
diff --git a/test/CXX/basic/basic.start/basic.start.main/p2b.cpp b/test/CXX/basic/basic.start/basic.start.main/p2b.cpp
new file mode 100644
index 0000000..785382c
--- /dev/null
+++ b/test/CXX/basic/basic.start/basic.start.main/p2b.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s 
+
+typedef int Int;
+typedef char Char;
+typedef Char* Carp;
+
+Int main(Int argc, Carp argv[], Char *env[]) {
+}
diff --git a/test/CXX/basic/basic.start/basic.start.main/p2c.cpp b/test/CXX/basic/basic.start/basic.start.main/p2c.cpp
new file mode 100644
index 0000000..81b08b9
--- /dev/null
+++ b/test/CXX/basic/basic.start/basic.start.main/p2c.cpp
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s 
+
+int main() {
+}
diff --git a/test/CXX/basic/basic.start/basic.start.main/p2d.cpp b/test/CXX/basic/basic.start/basic.start.main/p2d.cpp
new file mode 100644
index 0000000..bcdbdb2
--- /dev/null
+++ b/test/CXX/basic/basic.start/basic.start.main/p2d.cpp
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s 
+
+static int main() { // expected-error {{'main' is not allowed to be declared static}}
+}
diff --git a/test/CXX/basic/basic.start/basic.start.main/p2e.cpp b/test/CXX/basic/basic.start/basic.start.main/p2e.cpp
new file mode 100644
index 0000000..954fdbd
--- /dev/null
+++ b/test/CXX/basic/basic.start/basic.start.main/p2e.cpp
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s 
+
+inline int main() { // expected-error {{'main' is not allowed to be declared inline}}
+}
diff --git a/test/CXX/basic/basic.start/basic.start.main/p2f.cpp b/test/CXX/basic/basic.start/basic.start.main/p2f.cpp
new file mode 100644
index 0000000..a3d6a79
--- /dev/null
+++ b/test/CXX/basic/basic.start/basic.start.main/p2f.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s 
+
+void  // expected-error {{error: 'main' must return 'int'}}
+main( // expected-error {{error: first parameter of 'main' (argument count) must be of type 'int'}}
+     float a
+) {
+}
diff --git a/test/CXX/basic/basic.start/basic.start.main/p2g.cpp b/test/CXX/basic/basic.start/basic.start.main/p2g.cpp
new file mode 100644
index 0000000..e3209fd
--- /dev/null
+++ b/test/CXX/basic/basic.start/basic.start.main/p2g.cpp
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s 
+
+int main(int argc, const char* const* argv) {
+}
diff --git a/test/CXX/basic/basic.stc/basic.stc.dynamic/basic.stc.dynamic.allocation/p1.cpp b/test/CXX/basic/basic.stc/basic.stc.dynamic/basic.stc.dynamic.allocation/p1.cpp
new file mode 100644
index 0000000..8a62ae8
--- /dev/null
+++ b/test/CXX/basic/basic.stc/basic.stc.dynamic/basic.stc.dynamic.allocation/p1.cpp
@@ -0,0 +1,44 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+#include <stddef.h>
+
+struct A {
+  void *operator new(size_t);
+};
+
+namespace NS {
+  void *operator new(size_t);; // expected-error {{'operator new' cannot be declared inside a namespace}}
+}
+
+static void *operator new(size_t); // expected-error {{'operator new' cannot be declared static in global scope}}
+
+struct B {
+  void operator new(size_t);  // expected-error {{'operator new' must return type 'void *'}}
+};
+
+struct C {
+  void *operator new(); // expected-error {{'operator new' must have at least one parameter}}
+};
+
+struct D {
+  void *operator new(bool); // expected-error {{'operator new' takes type size_t}}
+};
+
+struct E {
+  void *operator new(size_t = 0); // expected-error {{parameter of 'operator new' cannot have a default argument}}
+};
+
+struct F {
+  template<typename T> void *operator new(size_t, int);
+};
+
+struct G {
+  template<typename T> T operator new(size_t, int); // expected-error {{'operator new' cannot have a dependent return type; use 'void *' instead}}
+};
+
+struct H {
+  template<typename T> void *operator new(T, int); // expected-error {{'operator new' cannot take a dependent type as first parameter; use size_t}}
+};
+
+struct I {
+  template<typename T> void *operator new(size_t); // expected-error {{'operator new' template must have at least two parameters}}
+};
diff --git a/test/CXX/basic/basic.stc/basic.stc.dynamic/basic.stc.dynamic.deallocation/p1.cpp b/test/CXX/basic/basic.stc/basic.stc.dynamic/basic.stc.dynamic.deallocation/p1.cpp
new file mode 100644
index 0000000..e00e948
--- /dev/null
+++ b/test/CXX/basic/basic.stc/basic.stc.dynamic/basic.stc.dynamic.deallocation/p1.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct A {
+  void operator delete(void*);
+};
+
+namespace NS {
+  void operator delete(void *); // expected-error {{'operator delete' cannot be declared inside a namespace}}
+}
+
+static void operator delete(void *); // expected-error {{'operator delete' cannot be declared static in global scope}}
diff --git a/test/CXX/basic/basic.stc/basic.stc.dynamic/p2-nodef.cpp b/test/CXX/basic/basic.stc/basic.stc.dynamic/p2-nodef.cpp
new file mode 100644
index 0000000..6cd587c
--- /dev/null
+++ b/test/CXX/basic/basic.stc/basic.stc.dynamic/p2-nodef.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+int *use_new(int N) {
+  return new int [N];
+}
+
+int std = 17;
diff --git a/test/CXX/basic/basic.stc/basic.stc.dynamic/p2-noexceptions.cpp b/test/CXX/basic/basic.stc/basic.stc.dynamic/p2-noexceptions.cpp
new file mode 100644
index 0000000..4567c46
--- /dev/null
+++ b/test/CXX/basic/basic.stc/basic.stc.dynamic/p2-noexceptions.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+namespace std {
+  class bad_alloc { };
+  
+  typedef __SIZE_TYPE__ size_t;
+}
+
+class foo { virtual ~foo(); };
+
+void* operator new(std::size_t); 
+void* operator new[](std::size_t);
+void operator delete(void*);
+void operator delete[](void*);
diff --git a/test/CXX/basic/basic.stc/basic.stc.dynamic/p2.cpp b/test/CXX/basic/basic.stc/basic.stc.dynamic/p2.cpp
new file mode 100644
index 0000000..37a4f97
--- /dev/null
+++ b/test/CXX/basic/basic.stc/basic.stc.dynamic/p2.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -fsyntax-only -fexceptions -verify %s
+int *use_new(int N) {
+  if (N == 1)
+    return new int;
+  
+  return new int [N];
+}
+
+void use_delete(int* ip, int N) {
+  if (N == 1)
+    delete ip;
+  else
+    delete [] ip;
+}
+
+namespace std {
+  class bad_alloc { };
+  
+  typedef __SIZE_TYPE__ size_t;
+}
+
+void* operator new(std::size_t) throw(std::bad_alloc); // expected-note{{previous declaration}}
+void* operator new[](std::size_t) throw(std::bad_alloc); 
+void operator delete(void*) throw(); // expected-note{{previous declaration}}
+void operator delete[](void*) throw();
+
+void* operator new(std::size_t); // expected-warning{{'operator new' is missing exception specification 'throw(std::bad_alloc)'}}
+void operator delete(void*); // expected-warning{{'operator delete' is missing exception specification 'throw()'}}
diff --git a/test/CXX/class.access/class.access.base/p1.cpp b/test/CXX/class.access/class.access.base/p1.cpp
new file mode 100644
index 0000000..0988431
--- /dev/null
+++ b/test/CXX/class.access/class.access.base/p1.cpp
@@ -0,0 +1,151 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// C++0x [class.access.base]p1(a):
+//   If a class is declared to be a base class for another class using
+//   the public access specifier, the public members of the base class
+//   are accessible as public members of the derived class and protected
+//   members of the base class are accessible as protected members of
+//   the derived class.
+namespace test0 {
+  class Base {
+  public: int pub; static int spub;
+  protected: int prot; static int sprot; // expected-note 4 {{declared protected here}}
+  private: int priv; static int spriv; // expected-note 8 {{declared private here}}
+  };
+
+  class Test : public Base {
+    void test() {
+      pub++;
+      spub++;
+      prot++;
+      sprot++;
+      priv++; // expected-error {{private member}}
+      spriv++; // expected-error {{private member}}
+
+      Base::pub++;
+      Base::spub++;
+      Base::prot++;
+      Base::sprot++;
+      Base::priv++; // expected-error {{private member}}
+      Base::spriv++; // expected-error {{private member}}
+    }
+  };
+
+  void test(Test *t) {
+    t->pub++;
+    t->spub++;
+    t->prot++; // expected-error {{protected member}}
+    t->sprot++; // expected-error {{protected member}}
+    t->priv++; // expected-error {{private member}}
+    t->spriv++; // expected-error {{private member}}
+
+    t->Base::pub++;
+    t->Base::spub++;
+    t->Base::prot++; // expected-error {{protected member}}
+    t->Base::sprot++; // expected-error {{protected member}}
+    t->Base::priv++; // expected-error {{private member}}
+    t->Base::spriv++; // expected-error {{private member}}
+  }
+}
+
+// C++0x [class.access.base]p1(b):
+//   If a class is declared to be a base class for another class using
+//   the protected access specifier, the public and protected members
+//   of the base class are accessible as protected members of the
+//   derived class.
+namespace test1 {
+  class Base {
+  public: int pub; static int spub;
+  protected: int prot; static int sprot; // expected-note 4 {{declared protected here}}
+  private: int priv; static int spriv; // expected-note 8 {{declared private here}}
+  };
+
+  class Test : protected Base { // expected-note 6 {{declared protected here}} expected-note 8 {{constrained by protected inheritance here}}
+    void test() {
+      pub++;
+      spub++;
+      prot++;
+      sprot++;
+      priv++; // expected-error {{private member}}
+      spriv++; // expected-error {{private member}}
+
+      Base::pub++;
+      Base::spub++;
+      Base::prot++;
+      Base::sprot++;
+      Base::priv++; // expected-error {{private member}}
+      Base::spriv++; // expected-error {{private member}}
+    }
+  };
+
+  void test(Test *t) {
+    t->pub++; // expected-error {{protected member}} expected-error {{protected base class}}
+    t->spub++; // expected-error {{protected member}}
+    t->prot++; // expected-error {{protected member}} expected-error {{protected base class}}
+    t->sprot++; // expected-error {{protected member}}
+    t->priv++; // expected-error {{private member}} expected-error {{protected base class}}
+    t->spriv++; // expected-error {{private member}}
+
+    // Two possible errors here: one for Base, one for the member
+    t->Base::pub++; // expected-error {{protected member}} expected-error {{protected base class}}
+    t->Base::spub++; // expected-error {{protected member}}
+    t->Base::prot++; // expected-error 2 {{protected member}} expected-error {{protected base class}}
+    t->Base::sprot++; // expected-error 2 {{protected member}}
+    t->Base::priv++; // expected-error {{protected member}} expected-error {{private member}} expected-error {{protected base class}}
+    t->Base::spriv++; // expected-error {{protected member}} expected-error {{private member}}
+  }
+}
+
+// C++0x [class.access.base]p1(b):
+//   If a class is declared to be a base class for another class using
+//   the private access specifier, the public and protected members of
+//   the base class are accessible as private members of the derived
+//   class.
+namespace test2 {
+  class Base {
+  public:
+    int pub;
+    static int spub;
+  protected:
+    int prot; // expected-note {{declared protected here}}
+    static int sprot; // expected-note {{declared protected here}}
+  private:
+    int priv; // expected-note 4 {{declared private here}}
+    static int spriv; // expected-note 4 {{declared private here}}
+  };
+
+  class Test : private Base { // expected-note 6 {{declared private here}} \
+                              // expected-note 10 {{constrained by private inheritance here}}
+    void test() {
+      pub++;
+      spub++;
+      prot++;
+      sprot++;
+      priv++; // expected-error {{private member}}
+      spriv++; // expected-error {{private member}}
+
+      Base::pub++;
+      Base::spub++;
+      Base::prot++;
+      Base::sprot++;
+      Base::priv++; // expected-error {{private member}}
+      Base::spriv++; // expected-error {{private member}}
+    }
+  };
+
+  void test(Test *t) {
+    t->pub++; // expected-error {{private member}} expected-error {{private base class}}
+    t->spub++; // expected-error {{private member}}
+    t->prot++; // expected-error {{private member}} expected-error {{private base class}}
+    t->sprot++; // expected-error {{private member}}
+    t->priv++; // expected-error {{private member}} expected-error {{private base class}}
+    t->spriv++; // expected-error {{private member}}
+
+    t->Base::pub++; // expected-error {{private member}} expected-error {{private base class}}
+    t->Base::spub++; // expected-error {{private member}}
+    t->Base::prot++; // expected-error {{protected member}} expected-error {{private member}} expected-error {{private base class}}
+    t->Base::sprot++; // expected-error {{protected member}} expected-error {{private member}}
+    t->Base::priv++; // expected-error 2 {{private member}} expected-error {{private base class}}
+    t->Base::spriv++; // expected-error 2 {{private member}}
+  }
+}
diff --git a/test/CXX/class.access/class.access.base/p5.cpp b/test/CXX/class.access/class.access.base/p5.cpp
new file mode 100644
index 0000000..938d9fb
--- /dev/null
+++ b/test/CXX/class.access/class.access.base/p5.cpp
@@ -0,0 +1,75 @@
+// RUN: %clang_cc1 -verify %s
+
+namespace test0 {
+  struct A {
+    static int x;
+  };
+  struct B : A {};
+  struct C : B {};
+
+  int test() {
+    return A::x
+         + B::x
+         + C::x;
+  }
+}
+
+namespace test1 {
+  struct A {
+    private: static int x; // expected-note 5 {{declared private here}}
+    static int test() { return x; }
+  };
+  struct B : public A {
+    static int test() { return x; } // expected-error {{private member}}
+  };
+  struct C : private A {
+    static int test() { return x; } // expected-error {{private member}}
+  };
+
+  struct D {
+    public: static int x;
+    static int test() { return x; }
+  };
+  struct E : private D { // expected-note{{constrained by private inheritance}}
+    static int test() { return x; }
+  };
+
+  int test() {
+    return A::x // expected-error {{private member}}
+         + B::x // expected-error {{private member}}
+         + C::x // expected-error {{private member}}
+         + D::x
+         + E::x; // expected-error {{private member}}
+  }
+}
+
+namespace test2 {
+  class A {
+  protected: static int x;
+  };
+
+  class B : private A {}; // expected-note {{private inheritance}}
+  class C : private A {
+    int test(B *b) {
+      return b->x; // expected-error {{private member}}
+    }
+  };
+}
+
+namespace test3 {
+  class A {
+  protected: static int x;
+  };
+
+  class B : public A {};
+  class C : private A {
+    int test(B *b) {
+      // x is accessible at C when named in A.
+      // A is an accessible base of B at C.
+      // Therefore this succeeds.
+      return b->x;
+    }
+  };
+}
+
+// TODO: flesh out these cases
diff --git a/test/CXX/class.access/class.access.dcl/p1.cpp b/test/CXX/class.access/class.access.dcl/p1.cpp
new file mode 100644
index 0000000..5d7905f
--- /dev/null
+++ b/test/CXX/class.access/class.access.dcl/p1.cpp
@@ -0,0 +1,199 @@
+// RUN: %clang_cc1 -fsyntax-only -verify
+
+// This is just the test for [namespace.udecl]p4 with 'using'
+// uniformly stripped out.
+
+// C++03 [namespace.udecl]p4:
+//   A using-declaration used as a member-declaration shall refer to a
+//   member of a base class of the class being defined, shall refer to
+//   a member of an anonymous union that is a member of a base class
+//   of the class being defined, or shall refer to an enumerator for
+//   an enumeration type that is a member of a base class of the class
+//   being defined.
+
+// There is no directly analogous paragraph in C++0x, and the feature
+// works sufficiently differently there that it needs a separate test.
+
+namespace test0 {
+  namespace NonClass {
+    typedef int type;
+    struct hiding {};
+    int hiding;
+    static union { double union_member; };
+    enum tagname { enumerator };
+  }
+
+  class Test0 {
+    NonClass::type; // expected-error {{not a class}} expected-warning {{access declarations are deprecated}}
+    NonClass::hiding; // expected-error {{not a class}} expected-warning {{access declarations are deprecated}}
+    NonClass::union_member; // expected-error {{not a class}} expected-warning {{access declarations are deprecated}}
+    NonClass::enumerator; // expected-error {{not a class}} expected-warning {{access declarations are deprecated}}
+  };
+}
+
+struct Opaque0 {};
+
+namespace test1 {
+  struct A {
+    typedef int type;
+    struct hiding {}; // expected-note {{previous use is here}}
+    Opaque0 hiding;
+    union { double union_member; };
+    enum tagname { enumerator };
+  };
+
+  struct B : A {
+    A::type; // expected-warning {{access declarations are deprecated}}
+    A::hiding; // expected-warning {{access declarations are deprecated}}
+    A::union_member; // expected-warning {{access declarations are deprecated}}
+    A::enumerator; // expected-warning {{access declarations are deprecated}}
+    A::tagname; // expected-warning {{access declarations are deprecated}}
+
+    void test0() {
+      type t = 0;
+    }
+
+    void test1() {
+      typedef struct A::hiding local;
+      struct hiding _ = local();
+    }
+
+    void test2() {
+      union hiding _; // expected-error {{tag type that does not match previous}}
+    }
+
+    void test3() {
+      char array[sizeof(union_member) == sizeof(double) ? 1 : -1];
+    }
+
+    void test4() {
+      enum tagname _ = enumerator;
+    }
+
+    void test5() {
+      Opaque0 _ = hiding;
+    }
+  };
+}
+
+namespace test2 {
+  struct A {
+    typedef int type;
+    struct hiding {}; // expected-note {{previous use is here}}
+    int hiding;
+    union { double union_member; };
+    enum tagname { enumerator };
+  };
+
+  template <class T> struct B : A {
+    A::type; // expected-warning {{access declarations are deprecated}}
+    A::hiding; // expected-warning {{access declarations are deprecated}}
+    A::union_member; // expected-warning {{access declarations are deprecated}}
+    A::enumerator; // expected-warning {{access declarations are deprecated}}
+    A::tagname; // expected-warning {{access declarations are deprecated}}
+
+    void test0() {
+      type t = 0;
+    }
+
+    void test1() {
+      typedef struct A::hiding local;
+      struct hiding _ = local();
+    }
+
+    void test2() {
+      union hiding _; // expected-error {{tag type that does not match previous}}
+    }
+
+    void test3() {
+      char array[sizeof(union_member) == sizeof(double) ? 1 : -1];
+    }
+
+    void test4() {
+      enum tagname _ = enumerator;
+    }
+
+    void test5() {
+      Opaque0 _ = hiding;
+    }
+  };
+}
+
+namespace test3 {
+  struct hiding {};
+
+  template <class T> struct A {
+    typedef int type; // expected-note {{target of using declaration}}
+    struct hiding {};
+    Opaque0 hiding;
+    union { double union_member; };
+    enum tagname { enumerator }; // expected-note {{target of using declaration}}
+  };
+
+  template <class T> struct B : A<T> {
+    A<T>::type; // expected-error {{dependent using declaration resolved to type without 'typename'}} // expected-warning {{access declarations are deprecated}}
+    A<T>::hiding; // expected-warning {{access declarations are deprecated}}
+    A<T>::union_member; // expected-warning {{access declarations are deprecated}}
+    A<T>::enumerator; // expected-warning {{access declarations are deprecated}}
+    A<T>::tagname; // expected-error {{dependent using declaration resolved to type without 'typename'}} // expected-warning {{access declarations are deprecated}}
+
+    // FIXME: re-enable these when the various bugs involving tags are fixed
+#if 0
+    void test1() {
+      typedef struct A<T>::hiding local;
+      struct hiding _ = local();
+    }
+
+    void test2() {
+      typedef struct A<T>::hiding local;
+      union hiding _ = local();
+    }
+#endif
+
+    void test3() {
+      char array[sizeof(union_member) == sizeof(double) ? 1 : -1];
+    }
+
+#if 0
+    void test4() {
+      enum tagname _ = enumerator;
+    }
+#endif
+
+    void test5() {
+      Opaque0 _ = hiding;
+    }
+  };
+
+  template struct B<int>; // expected-note {{in instantiation}}
+}
+
+namespace test4 {
+  struct Base {
+    int foo();
+  };
+
+  struct Unrelated {
+    int foo();
+  };
+
+  struct Subclass : Base {
+  };
+
+  namespace InnerNS {
+    int foo();
+  }
+
+  // We should be able to diagnose these without instantiation.
+  template <class T> struct C : Base {
+    InnerNS::foo; // expected-error {{not a class}} expected-warning {{access declarations are deprecated}}
+    Base::bar; // expected-error {{no member named 'bar'}} expected-warning {{access declarations are deprecated}}
+    Unrelated::foo; // expected-error {{not a base class}} expected-warning {{access declarations are deprecated}}
+    C::foo; // legal in C++03 // expected-warning {{access declarations are deprecated}}
+    Subclass::foo; // legal in C++03 // expected-warning {{access declarations are deprecated}}
+
+    int bar(); //expected-note {{target of using declaration}}
+    C::bar; // expected-error {{refers to its own class}} expected-warning {{access declarations are deprecated}}
+  };
+}
+
diff --git a/test/CXX/class.access/class.access.nest/p1.cpp b/test/CXX/class.access/class.access.nest/p1.cpp
new file mode 100644
index 0000000..eceffcf
--- /dev/null
+++ b/test/CXX/class.access/class.access.nest/p1.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// Derived from GNU's std::string
+namespace test0 {
+  class A {
+    struct B {
+      unsigned long length;
+    };
+    struct C : B {
+      static const unsigned long max_length;
+    };
+  };
+  
+  const unsigned long A::C::max_length = sizeof(B);
+}
+
+// Example from the standard.
+namespace test1 {
+  class E {
+    int x;
+    class B {};
+
+    class I {
+      B b;
+      int y; // expected-note {{declared private here}}
+      void f(E* p, int i) {
+        p->x = i;
+      }
+    };
+
+    int g(I* p) { return p->y; } // expected-error {{'y' is a private member of 'test1::E::I'}}
+  };
+}
diff --git a/test/CXX/class.access/class.friend/p1.cpp b/test/CXX/class.access/class.friend/p1.cpp
new file mode 100644
index 0000000..991698d
--- /dev/null
+++ b/test/CXX/class.access/class.friend/p1.cpp
@@ -0,0 +1,289 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// C++'0x [class.friend] p1:
+//   A friend of a class is a function or class that is given permission to use
+//   the private and protected member names from the class. A class specifies
+//   its friends, if any, by way of friend declarations. Such declarations give
+//   special access rights to the friends, but they do not make the nominated
+//   friends members of the befriending class.
+//
+// FIXME: Add tests for access control when implemented. Currently we only test
+// for parsing.
+
+struct S { static void f(); };
+S* g() { return 0; }
+
+struct X {
+  friend struct S;
+  friend S* g();
+};
+
+void test1() {
+  S s;
+  g()->f();
+  S::f();
+  X::g(); // expected-error{{no member named 'g' in 'X'}}
+  X::S x_s; // expected-error{{no member named 'S' in 'X'}}
+  X x;
+  x.g(); // expected-error{{no member named 'g' in 'X'}}
+}
+
+// Test that we recurse through namespaces to find already declared names, but
+// new names are declared within the enclosing namespace.
+namespace N {
+  struct X {
+    friend struct S;
+    friend S* g();
+
+    friend struct S2;
+    friend struct S2* g2();
+  };
+
+  struct S2 { static void f2(); };
+  S2* g2() { return 0; }
+
+  void test() {
+    g()->f();
+    S s;
+    S::f();
+    X::g(); // expected-error{{no member named 'g' in 'N::X'}}
+    X::S x_s; // expected-error{{no member named 'S' in 'N::X'}}
+    X x;
+    x.g(); // expected-error{{no member named 'g' in 'N::X'}}
+
+    g2();
+    S2 s2;
+    ::g2(); // expected-error{{no member named 'g2' in the global namespace}}
+    ::S2 g_s2; // expected-error{{no member named 'S2' in the global namespace}}
+    X::g2(); // expected-error{{no member named 'g2' in 'N::X'}}
+    X::S2 x_s2; // expected-error{{no member named 'S2' in 'N::X'}}
+    x.g2(); // expected-error{{no member named 'g2' in 'N::X'}}
+  }
+}
+
+namespace test0 {
+  class ClassFriend {
+    void test();
+  };
+
+  class MemberFriend {
+    void test();
+  };
+
+  void declared_test();
+
+  class Class {
+    static void member(); // expected-note 2 {{declared private here}}
+
+    friend class ClassFriend;
+    friend class UndeclaredClassFriend;
+
+    friend void undeclared_test();
+    friend void declared_test();
+    friend void MemberFriend::test();
+  };
+
+  void declared_test() {
+    Class::member();
+  }
+
+  void undeclared_test() {
+    Class::member();
+  }
+
+  void unfriended_test() {
+    Class::member(); // expected-error {{'member' is a private member of 'test0::Class'}}
+  }
+
+  void ClassFriend::test() {
+    Class::member();
+  }
+
+  void MemberFriend::test() {
+    Class::member();
+  }
+
+  class UndeclaredClassFriend {
+    void test() {
+      Class::member();
+    }
+  };
+
+  class ClassNonFriend {
+    void test() {
+      Class::member(); // expected-error {{'member' is a private member of 'test0::Class'}}
+    }
+  };
+}
+
+// Make sure that friends have access to inherited protected members.
+namespace test2 {
+  struct X;
+
+  class ilist_half_node {
+    friend struct ilist_walker_bad;
+    X *Prev;
+  protected:
+    X *getPrev() { return Prev; }
+  };
+
+  class ilist_node : private ilist_half_node { // expected-note {{declared private here}} expected-note {{constrained by private inheritance here}}
+    friend struct ilist_walker;
+    X *Next;
+    X *getNext() { return Next; } // expected-note {{declared private here}}
+  };
+
+  struct X : ilist_node {};
+
+  struct ilist_walker {
+    static X *getPrev(X *N) { return N->getPrev(); }
+    static X *getNext(X *N) { return N->getNext(); }
+  };  
+
+  struct ilist_walker_bad {
+    static X *getPrev(X *N) { return N->getPrev(); } // \
+    // expected-error {{'getPrev' is a private member of 'test2::ilist_half_node'}} \
+    // expected-error {{cannot cast 'test2::X' to its private base class 'test2::ilist_half_node'}}
+
+    static X *getNext(X *N) { return N->getNext(); } // \
+    // expected-error {{'getNext' is a private member of 'test2::ilist_node'}}
+  };  
+}
+
+namespace test3 {
+  class A { protected: int x; }; // expected-note {{declared protected here}}
+
+  class B : public A {
+    friend int foo(B*);
+  };
+
+  int foo(B *p) {
+    return p->x;
+  }
+
+  int foo(const B *p) {
+    return p->x; // expected-error {{'x' is a protected member of 'test3::A'}}
+  }
+}
+
+namespace test3a {
+  class A { protected: int x; };
+
+  class B : public A {
+    friend int foo(B*);
+  };
+
+  int foo(B * const p) {
+    return p->x;
+  }
+}
+
+namespace test4 {
+  template <class T> class Holder {
+    T object;
+    friend bool operator==(Holder &a, Holder &b) {
+      return a.object == b.object; // expected-error {{invalid operands to binary expression}}
+    }
+  };
+
+  struct Inequal {};
+  bool test() {
+    Holder<Inequal> a, b;
+    return a == b; // expected-note {{requested here}}
+  }
+}
+
+
+// PR6174
+namespace test5 {
+  namespace ns {
+    class A;
+  }
+
+  class ns::A {
+  private: int x;
+    friend class B;
+  };
+
+  namespace ns {
+    class B {
+      int test(A *p) { return p->x; }
+    };
+  }
+}
+
+// PR6207
+namespace test6 {
+  struct A {};
+
+  struct B {
+    friend A::A();
+    friend A::~A();
+    friend A &A::operator=(const A&);
+  };
+}
+
+namespace test7 {
+  template <class T> struct X {
+    X();
+    ~X();
+    void foo();
+    void bar();
+  };
+
+  class A {
+    friend void X<int>::foo();
+    friend X<int>::X();
+    friend X<int>::X(const X&);
+
+  private:
+    A(); // expected-note 2 {{declared private here}}
+  };
+
+  template<> void X<int>::foo() {
+    A a;
+  }
+
+  template<> void X<int>::bar() {
+    A a; // expected-error {{calling a private constructor}}
+  }
+
+  template<> X<int>::X() {
+    A a;
+  }
+
+  template<> X<int>::~X() {
+    A a; // expected-error {{calling a private constructor}}
+  }
+}
+
+// Return types, parameters and default arguments to friend functions.
+namespace test8 {
+  class A {
+    typedef int I; // expected-note 4 {{declared private here}}
+    static const I x = 0;
+    friend I f(I i);
+    template<typename T> friend I g(I i);
+  };
+
+  // FIXME: This should be on line 264.
+  const A::I A::x; // expected-note {{declared private here}}
+  A::I f(A::I i = A::x) {}
+  template<typename T> A::I g(A::I i) {
+    T t;
+  }
+  template A::I g<A::I>(A::I i);
+
+  A::I f2(A::I i = A::x) {} // expected-error 3 {{is a private member of}}
+  template<typename T> A::I g2(A::I i) { // expected-error 2 {{is a private member of}}
+    T t;
+  }
+  template A::I g2<A::I>(A::I i);
+}
+
+// PR6885
+namespace test9 {
+  class B {
+    friend class test9;
+  };
+}
diff --git a/test/CXX/class.access/class.friend/p2-cxx03.cpp b/test/CXX/class.access/class.friend/p2-cxx03.cpp
new file mode 100644
index 0000000..0391c4b
--- /dev/null
+++ b/test/CXX/class.access/class.friend/p2-cxx03.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename T>
+class X0 {
+  friend T; // expected-warning{{non-class type 'T' cannot be a friend}}
+};
+
+class X1 { };
+enum E1 { };
+X0<X1> x0a;
+X0<X1 *> x0b;
+X0<int> x0c;
+X0<E1> x0d;
+
diff --git a/test/CXX/class.access/class.friend/p3-cxx0x.cpp b/test/CXX/class.access/class.friend/p3-cxx0x.cpp
new file mode 100644
index 0000000..4f55e53
--- /dev/null
+++ b/test/CXX/class.access/class.friend/p3-cxx0x.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++0x -verify %s
+template<typename T>
+class X0 {
+  friend T;
+};
+
+class Y1 { };
+enum E1 { };
+X0<Y1> x0a;
+X0<Y1 *> x0b;
+X0<int> x0c;
+X0<E1> x0d;
+
+template<typename T>
+class X1 {
+  friend typename T::type; // expected-error{{no type named 'type' in 'Y1'}}
+};
+
+struct Y2 {
+  struct type { };
+};
+
+struct Y3 {
+  typedef int type;
+};
+
+X1<Y2> x1a;
+X1<Y3> x1b;
+X1<Y1> x1c; // expected-note{{in instantiation of template class 'X1<Y1>' requested here}}
diff --git a/test/CXX/class.access/class.protected/p1.cpp b/test/CXX/class.access/class.protected/p1.cpp
new file mode 100644
index 0000000..6ff630c
--- /dev/null
+++ b/test/CXX/class.access/class.protected/p1.cpp
@@ -0,0 +1,387 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace test0 {
+  class A {
+    protected: int x; // expected-note 3 {{declared}}
+    static int sx; // expected-note 3 {{declared}}
+  };
+  class B : public A {
+  };
+  class C : protected A { // expected-note {{declared}}
+  };
+  class D : private B { // expected-note 3 {{constrained}}
+  };
+
+  void test(A &a) {
+    (void) a.x; // expected-error {{'x' is a protected member}}
+    (void) a.sx; // expected-error {{'sx' is a protected member}}
+  }
+  void test(B &b) {
+    (void) b.x; // expected-error {{'x' is a protected member}}
+    (void) b.sx; // expected-error {{'sx' is a protected member}}
+  }
+  void test(C &c) {
+    (void) c.x; // expected-error {{'x' is a protected member}} expected-error {{protected base class}}
+    (void) c.sx; // expected-error {{'sx' is a protected member}}
+  }
+  void test(D &d) {
+    (void) d.x; // expected-error {{'x' is a private member}} expected-error {{private base class}}
+    (void) d.sx; // expected-error {{'sx' is a private member}}
+  }
+}
+
+namespace test1 {
+  class A {
+    protected: int x;
+    static int sx;
+    static void test(A&);
+  };
+  class B : public A {
+    static void test(B&);
+  };
+  class C : protected A {
+    static void test(C&);
+  };
+  class D : private B {
+    static void test(D&);
+  };
+
+  void A::test(A &a) {
+    (void) a.x;
+    (void) a.sx;
+  }
+  void B::test(B &b) {
+    (void) b.x;
+    (void) b.sx;
+  }
+  void C::test(C &c) {
+    (void) c.x;
+    (void) c.sx;
+  }
+  void D::test(D &d) {
+    (void) d.x;
+    (void) d.sx;
+  }
+}
+
+namespace test2 {
+  class A {
+    protected: int x; // expected-note 3 {{declared}}
+    static int sx;
+    static void test(A&);
+  };
+  class B : public A {
+    static void test(A&);
+  };
+  class C : protected A {
+    static void test(A&);
+  };
+  class D : private B {
+    static void test(A&);
+  };
+
+  void A::test(A &a) {
+    (void) a.x;
+    (void) a.sx;
+  }
+  void B::test(A &a) {
+    (void) a.x; // expected-error {{'x' is a protected member}}
+    (void) a.sx;
+  }
+  void C::test(A &a) {
+    (void) a.x; // expected-error {{'x' is a protected member}}
+    (void) a.sx;
+  }
+  void D::test(A &a) {
+    (void) a.x; // expected-error {{'x' is a protected member}}
+    (void) a.sx;
+  }
+}
+
+namespace test3 {
+  class B;
+  class A {
+    protected: int x; // expected-note {{declared}}
+    static int sx;
+    static void test(B&);
+  };
+  class B : public A {
+    static void test(B&);
+  };
+  class C : protected A {
+    static void test(B&);
+  };
+  class D : private B {
+    static void test(B&);
+  };
+
+  void A::test(B &b) {
+    (void) b.x;
+    (void) b.sx;
+  }
+  void B::test(B &b) {
+    (void) b.x;
+    (void) b.sx;
+  }
+  void C::test(B &b) {
+    (void) b.x; // expected-error {{'x' is a protected member}}
+    (void) b.sx;
+  }
+  void D::test(B &b) {
+    (void) b.x;
+    (void) b.sx;
+  }
+}
+
+namespace test4 {
+  class C;
+  class A {
+    protected: int x; // expected-note 2 {{declared}}
+    static int sx;
+    static void test(C&);
+  };
+  class B : public A {
+    static void test(C&);
+  };
+  class C : protected A { // expected-note 4 {{constrained}} expected-note 3 {{declared}}
+    static void test(C&);
+  };
+  class D : private B {
+    static void test(C&);
+  };
+
+  void A::test(C &c) {
+    (void) c.x;  // expected-error {{'x' is a protected member}} \
+                 // expected-error {{protected base class}}
+    (void) c.sx; // expected-error {{'sx' is a protected member}}
+  }
+  void B::test(C &c) {
+    (void) c.x;  // expected-error {{'x' is a protected member}} \
+                 // expected-error {{protected base class}}
+    (void) c.sx; // expected-error {{'sx' is a protected member}}
+  }
+  void C::test(C &c) {
+    (void) c.x;
+    (void) c.sx;
+  }
+  void D::test(C &c) {
+    (void) c.x;  // expected-error {{'x' is a protected member}} \
+                 // expected-error {{protected base class}}
+    (void) c.sx; // expected-error {{'sx' is a protected member}}
+  }
+}
+
+namespace test5 {
+  class D;
+  class A {
+    protected: int x;
+    static int sx;
+    static void test(D&);
+  };
+  class B : public A {
+    static void test(D&);
+  };
+  class C : protected A {
+    static void test(D&);
+  };
+  class D : private B { // expected-note 9 {{constrained}}
+    static void test(D&);
+  };
+
+  void A::test(D &d) {
+    (void) d.x;  // expected-error {{'x' is a private member}} \
+                 // expected-error {{cannot cast}}
+    (void) d.sx; // expected-error {{'sx' is a private member}}
+  }
+  void B::test(D &d) {
+    (void) d.x;  // expected-error {{'x' is a private member}} \
+                 // expected-error {{cannot cast}}
+    (void) d.sx; // expected-error {{'sx' is a private member}}
+  }
+  void C::test(D &d) {
+    (void) d.x;  // expected-error {{'x' is a private member}} \
+                 // expected-error {{cannot cast}}
+    (void) d.sx; // expected-error {{'sx' is a private member}}
+  }
+  void D::test(D &d) {
+    (void) d.x;
+    (void) d.sx;
+  }
+}
+
+namespace test6 {
+  class Static {};
+  class A {
+  protected:
+    void foo(int); // expected-note 3 {{declared}}
+    void foo(long);
+    static void foo(Static);
+
+    static void test(A&);
+  };
+  class B : public A {
+    static void test(A&);
+  };
+  class C : protected A {
+    static void test(A&);
+  };
+  class D : private B {
+    static void test(A&);
+  };
+
+  void A::test(A &a) {
+    a.foo(10);
+    a.foo(Static());
+  }
+  void B::test(A &a) {
+    a.foo(10); // expected-error {{'foo' is a protected member}}
+    a.foo(Static());
+  }
+  void C::test(A &a) {
+    a.foo(10); // expected-error {{'foo' is a protected member}}
+    a.foo(Static());
+  }
+  void D::test(A &a) {
+    a.foo(10); // expected-error {{'foo' is a protected member}}
+    a.foo(Static());
+  }
+}
+
+namespace test7 {
+  class Static {};
+  class A {
+    protected:
+    void foo(int); // expected-note 3 {{declared}}
+    void foo(long);
+    static void foo(Static);
+
+    static void test();
+  };
+  class B : public A {
+    static void test();
+  };
+  class C : protected A {
+    static void test();
+  };
+  class D : private B {
+    static void test();
+  };
+
+  void A::test() {
+    void (A::*x)(int) = &A::foo;
+    void (*sx)(Static) = &A::foo;
+  }
+  void B::test() {
+    void (A::*x)(int) = &A::foo; // expected-error {{'foo' is a protected member}}
+    void (*sx)(Static) = &A::foo;
+  }
+  void C::test() {
+    void (A::*x)(int) = &A::foo; // expected-error {{'foo' is a protected member}}
+    void (*sx)(Static) = &A::foo;
+  }
+  void D::test() {
+    void (A::*x)(int) = &A::foo; // expected-error {{'foo' is a protected member}}
+    void (*sx)(Static) = &A::foo;
+  }
+}
+
+namespace test8 {
+  class Static {};
+  class A {
+    protected:
+    void foo(int); // expected-note 3 {{declared}}
+    void foo(long);
+    static void foo(Static);
+
+    static void test();
+  };
+  class B : public A {
+    static void test();
+  };
+  class C : protected A {
+    static void test();
+  };
+  class D : private B {
+    static void test();
+  };
+  void call(void (A::*)(int));
+  void calls(void (*)(Static));
+
+  void A::test() {
+    call(&A::foo);
+    calls(&A::foo);
+  }
+  void B::test() {
+    call(&A::foo); // expected-error {{'foo' is a protected member}}
+    calls(&A::foo);
+  }
+  void C::test() {
+    call(&A::foo); // expected-error {{'foo' is a protected member}}
+    calls(&A::foo);
+  }
+  void D::test() {
+    call(&A::foo); // expected-error {{'foo' is a protected member}}
+    calls(&A::foo);
+  }
+}
+
+namespace test9 {
+  class A {
+  protected: int foo(); // expected-note 8 {{declared}}
+  };
+
+  class B : public A {
+    friend class D;
+  };
+
+  class C : protected B { // expected-note {{declared}} \
+                          // expected-note 6 {{constrained}}
+  };
+
+  class D : public A {
+    static void test(A &a) {
+      a.foo(); // expected-error {{'foo' is a protected member}}
+      a.A::foo(); // expected-error {{'foo' is a protected member}}
+      a.B::foo();
+      a.C::foo(); // expected-error {{'foo' is a protected member}}
+    }
+
+    static void test(B &b) {
+      b.foo();
+      b.A::foo(); // expected-error {{'foo' is a protected member}}
+      b.B::foo();
+      b.C::foo(); // expected-error {{'foo' is a protected member}}
+    }
+
+    static void test(C &c) {
+      c.foo();    // expected-error {{'foo' is a protected member}} \
+                  // expected-error {{cannot cast}}
+      c.A::foo(); // expected-error {{'foo' is a protected member}} \
+                  // expected-error {{'A' is a protected member}} \
+                  // expected-error {{cannot cast}}
+      c.B::foo(); // expected-error {{'B' is a protected member}} \
+                  // expected-error {{cannot cast}}
+      c.C::foo(); // expected-error {{'foo' is a protected member}} \
+                  // expected-error {{cannot cast}}
+    }
+
+    static void test(D &d) {
+      d.foo();
+      d.A::foo();
+      d.B::foo();
+      d.C::foo(); // expected-error {{'foo' is a protected member}}
+    }
+  };
+}
+
+namespace test10 {
+  template<typename T> class A {
+  protected:
+    int foo();
+    int foo() const;
+
+    ~A() { foo(); }
+  };
+
+  template class A<int>;
+}
diff --git a/test/CXX/class.access/p4.cpp b/test/CXX/class.access/p4.cpp
new file mode 100644
index 0000000..2786aef
--- /dev/null
+++ b/test/CXX/class.access/p4.cpp
@@ -0,0 +1,365 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// C++0x [class.access]p4:
+
+//   Access control is applied uniformly to all names, whether the
+//   names are referred to from declarations or expressions.  In the
+//   case of overloaded function names, access control is applied to
+//   the function selected by overload resolution.
+
+class Public {} PublicInst;
+class Protected {} ProtectedInst;
+class Private {} PrivateInst;
+
+namespace test0 {
+  class A {
+  public:
+    void foo(Public&);
+  protected:
+    void foo(Protected&); // expected-note 2 {{declared protected here}}
+  private:
+    void foo(Private&); // expected-note 2 {{declared private here}}
+  };
+
+  void test(A *op) {
+    op->foo(PublicInst);
+    op->foo(ProtectedInst); // expected-error {{'foo' is a protected member}}
+    op->foo(PrivateInst); // expected-error {{'foo' is a private member}}
+
+    void (A::*a)(Public&) = &A::foo;
+    void (A::*b)(Protected&) = &A::foo; // expected-error {{'foo' is a protected member}}
+    void (A::*c)(Private&) = &A::foo; // expected-error {{'foo' is a private member}}
+  }
+}
+
+// Member operators.
+namespace test1 {
+  class A {
+  public:
+    void operator+(Public&);
+    void operator[](Public&);
+    void operator()(Public&);
+    typedef void (*PublicSurrogate)(Public&);
+    operator PublicSurrogate() const;
+  protected:
+    void operator+(Protected&); // expected-note {{declared protected here}}
+    void operator[](Protected&); // expected-note {{declared protected here}}
+    void operator()(Protected&); // expected-note {{declared protected here}}
+    typedef void (*ProtectedSurrogate)(Protected&);
+    operator ProtectedSurrogate() const; // expected-note {{declared protected here}}
+  private:
+    void operator+(Private&); // expected-note {{declared private here}}
+    void operator[](Private&); // expected-note {{declared private here}}
+    void operator()(Private&); // expected-note {{declared private here}}
+    void operator-(); // expected-note {{declared private here}}
+    typedef void (*PrivateSurrogate)(Private&);
+    operator PrivateSurrogate() const; // expected-note {{declared private here}}
+  };
+  void operator+(const A &, Public&);
+  void operator+(const A &, Protected&);
+  void operator+(const A &, Private&);
+  void operator-(const A &);
+
+  void test(A &a, Public &pub, Protected &prot, Private &priv) {
+    a + pub;
+    a + prot; // expected-error {{'operator+' is a protected member}}
+    a + priv; // expected-error {{'operator+' is a private member}}
+    a[pub];
+    a[prot]; // expected-error {{'operator[]' is a protected member}}
+    a[priv]; // expected-error {{'operator[]' is a private member}}
+    a(pub);
+    a(prot); // expected-error {{'operator()' is a protected member}}
+    a(priv); // expected-error {{'operator()' is a private member}}
+    -a;       // expected-error {{'operator-' is a private member}}
+
+    const A &ca = a;
+    ca + pub;
+    ca + prot;
+    ca + priv;
+    -ca;
+    // These are all surrogate calls
+    ca(pub);
+    ca(prot); // expected-error {{'operator void (*)(class Protected &)' is a protected member}}
+    ca(priv); // expected-error {{'operator void (*)(class Private &)' is a private member}}
+  }
+}
+
+// Implicit constructor calls.
+namespace test2 {
+  class A {
+  private:
+    A(); // expected-note 3 {{declared private here}}
+
+    static A foo;
+  };
+
+  A a; // expected-error {{calling a private constructor}}
+  A A::foo; // okay
+  
+  class B : A { }; // expected-error {{base class 'test2::A' has private constructor}}
+  B b;
+  
+  class C : virtual A { 
+  public:
+    C();
+  };
+
+  class D : C { }; // expected-error {{inherited virtual base class 'test2::A' has private constructor}}
+  D d;
+}
+
+// Implicit destructor calls.
+namespace test3 {
+  class A {
+  private:
+    ~A(); // expected-note 2 {{declared private here}}
+    static A foo;
+  };
+
+  A a; // expected-error {{variable of type 'test3::A' has private destructor}}
+  A A::foo;
+
+  void foo(A param) { // okay
+    A local; // expected-error {{variable of type 'test3::A' has private destructor}}
+  }
+
+  template <unsigned N> class Base { ~Base(); }; // expected-note 14 {{declared private here}}
+  class Base2 : virtual Base<2> { ~Base2(); }; // expected-note 3 {{declared private here}} \
+                                               // expected-error {{base class 'Base<2>' has private destructor}}
+  class Base3 : virtual Base<3> { public: ~Base3(); }; // expected-error {{base class 'Base<3>' has private destructor}}
+
+  // These don't cause diagnostics because we don't need the destructor.
+  class Derived0 : Base<0> { ~Derived0(); };
+  class Derived1 : Base<1> { };
+
+  class Derived2 : // expected-error {{inherited virtual base class 'Base<2>' has private destructor}} \
+                   // expected-error {{inherited virtual base class 'Base<3>' has private destructor}}
+    Base<0>,  // expected-error {{base class 'Base<0>' has private destructor}}
+    virtual Base<1>, // expected-error {{base class 'Base<1>' has private destructor}}
+    Base2, // expected-error {{base class 'test3::Base2' has private destructor}}
+    virtual Base3
+  {
+    ~Derived2() {}
+  };
+
+  class Derived3 : // expected-error 2 {{inherited virtual base class 'Base<2>' has private destructor}} \
+                   // expected-error 2 {{inherited virtual base class 'Base<3>' has private destructor}}
+    Base<0>,  // expected-error 2 {{base class 'Base<0>' has private destructor}}
+    virtual Base<1>, // expected-error 2 {{base class 'Base<1>' has private destructor}}
+    Base2, // expected-error 2 {{base class 'test3::Base2' has private destructor}}
+    virtual Base3
+  {};
+  Derived3 d3;
+}
+
+// Conversion functions.
+namespace test4 {
+  class Base {
+  private:
+    operator Private(); // expected-note 4 {{declared private here}}
+  public:
+    operator Public();
+  };
+
+  class Derived1 : private Base { // expected-note 2 {{declared private here}} \
+                                  // expected-note {{constrained by private inheritance}}
+    Private test1() { return *this; } // expected-error {{'operator Private' is a private member}}
+    Public test2() { return *this; }
+  };
+  Private test1(Derived1 &d) { return d; } // expected-error {{'operator Private' is a private member}} \
+                                           // expected-error {{cannot cast 'test4::Derived1' to its private base class}}
+  Public test2(Derived1 &d) { return d; } // expected-error {{cannot cast 'test4::Derived1' to its private base class}} \
+                                          // expected-error {{'operator Public' is a private member}}
+
+
+  class Derived2 : public Base {
+    Private test1() { return *this; } // expected-error {{'operator Private' is a private member}}
+    Public test2() { return *this; }
+  };
+  Private test1(Derived2 &d) { return d; } // expected-error {{'operator Private' is a private member}}
+  Public test2(Derived2 &d) { return d; }
+
+  class Derived3 : private Base { // expected-note {{constrained by private inheritance here}} \
+                                  // expected-note {{declared private here}}
+  public:
+    operator Private();
+  };
+  Private test1(Derived3 &d) { return d; }
+  Public test2(Derived3 &d) { return d; } // expected-error {{'operator Public' is a private member of 'test4::Base'}} \
+                                          // expected-error {{cannot cast 'test4::Derived3' to its private base class}}
+
+  class Derived4 : public Base {
+  public:
+    operator Private();
+  };
+  Private test1(Derived4 &d) { return d; }
+  Public test2(Derived4 &d) { return d; }
+}
+
+// Implicit copy assignment operator uses.
+namespace test5 {
+  class A {
+    void operator=(const A &); // expected-note 2 {{declared private here}}
+  };
+
+  class Test1 { A a; }; // expected-error {{field of type 'test5::A' has private copy assignment operator}}
+  void test1() {
+    Test1 a;
+    a = Test1();
+  }
+
+  class Test2 : A {}; // expected-error {{base class 'test5::A' has private copy assignment operator}}
+  void test2() {
+    Test2 a;
+    a = Test2();
+  }
+}
+
+// Implicit copy constructor uses.
+namespace test6 {
+  class A {
+    public: A();
+    private: A(const A &); // expected-note 2 {{declared private here}}
+  };
+
+  class Test1 { A a; }; // expected-error {{field of type 'test6::A' has private copy constructor}}
+  void test1(const Test1 &t) {
+    Test1 a = t;
+  }
+
+  class Test2 : A {}; // expected-error {{base class 'test6::A' has private copy constructor}}
+  void test2(const Test2 &t) {
+    Test2 a = t;
+  }
+}
+
+// Redeclaration lookups are not accesses.
+namespace test7 {
+  class A {
+    int private_member;
+  };
+  class B : A {
+    int foo(int private_member) {
+      return 0;
+    }
+  };
+}
+
+// Ignored operator new and delete overloads are not 
+namespace test8 {
+  typedef __typeof__(sizeof(int)) size_t;
+
+  class A {
+    void *operator new(size_t s);
+    void operator delete(void *p);
+  public:
+    void *operator new(size_t s, int n);
+    void operator delete(void *p, int n);
+  };
+
+  void test() {
+    new (2) A();
+  }
+}
+
+// Don't silently upgrade forbidden-access paths to private.
+namespace test9 {
+  class A {
+    public: static int x;
+  };
+  class B : private A { // expected-note {{constrained by private inheritance here}}
+  };
+  class C : public B {
+    static int getX() { return x; } // expected-error {{'x' is a private member of 'test9::A'}}
+  };
+}
+
+namespace test10 {
+  class A {
+    enum {
+      value = 10 // expected-note {{declared private here}}
+    };
+    friend class C;
+  };
+
+  class B {
+    enum {
+      value = A::value // expected-error {{'value' is a private member of 'test10::A'}}
+    };
+  };
+
+  class C {
+    enum {
+      value = A::value
+    };
+  };
+}
+
+namespace test11 {
+  class A {
+    protected: virtual ~A();
+  };
+
+  class B : public A {
+    ~B();
+  };
+
+  B::~B() {};
+}
+
+namespace test12 {
+  class A {
+    int x;
+
+    void foo() {
+      class Local {
+        int foo(A *a) {
+          return a->x;
+        }
+      };
+    }
+  };
+}
+
+namespace test13 {
+  struct A {
+    int x;
+    unsigned foo() const;
+  };
+
+  struct B : protected A {
+    using A::foo;
+    using A::x;
+  };
+
+  void test() {
+    A *d;
+    d->foo();
+    (void) d->x;
+  }
+}
+
+// Destructors for temporaries.
+namespace test14 {
+  class A {
+  private: ~A(); // expected-note {{declared private here}}
+  };
+  A foo();
+
+  void test() {
+    foo(); // expected-error {{temporary of type 'test14::A' has private destructor}}
+  }
+
+  class X {
+    ~X(); // expected-note {{declared private here}}
+  };
+  
+  struct Y1 {
+    operator X();
+  };
+  
+  void g() {
+    const X &xr = Y1(); // expected-error{{temporary of type 'test14::X' has private destructor}}
+  }
+}
+
diff --git a/test/CXX/class.access/p6.cpp b/test/CXX/class.access/p6.cpp
new file mode 100644
index 0000000..d51d75d
--- /dev/null
+++ b/test/CXX/class.access/p6.cpp
@@ -0,0 +1,54 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// C++0x [class.access]p6:
+//   All access controls in [class.access] affect the ability to
+//   access a class member name from a particular scope. For purposes
+//   of access control, the base-specifiers of a class and the
+//   definitions of class members that appear outside of the class
+//   definition are considered to be within the scope of that
+//   class. In particular, access controls apply as usual to member
+//   names accessed as part of a function return type, even though it
+//   is not possible to determine the access privileges of that use
+//   without first parsing the rest of the function
+//   declarator. Similarly, access control for implicit calls to the
+//   constructors, the conversion functions, or the destructor called
+//   to create and destroy a static data member is performed as if
+//   these calls appeared in the scope of the member's class.
+
+struct Public {}; struct Protected {}; struct Private {};
+
+namespace test0 {
+  class A {
+    typedef int type; // expected-note {{declared private here}}
+    type foo();
+  };
+
+  A::type foo() { } // expected-error {{'type' is a private member}}
+  A::type A::foo() { }
+}
+
+// conversion decls
+namespace test1 {
+  class A {
+  public:
+    A();
+    operator Public ();
+    A(Public);
+  protected:
+    operator Protected (); // expected-note {{declared protected here}}
+    A(Protected); // expected-note {{declared protected here}}
+  private:
+    operator Private (); // expected-note {{declared private here}}
+    A(Private); // expected-note {{declared private here}}
+  };
+
+  void test() {
+    A a;
+    Public pub = a;
+    Protected prot = a; // expected-error {{'operator Protected' is a protected member}}
+    Private priv = a; // expected-error {{'operator Private' is a private member}}
+    A apub = pub;
+    A aprot = prot; // expected-error {{protected constructor}}
+    A apriv = priv; // expected-error {{private constructor}}
+  }
+}
diff --git a/test/CXX/class.derived/class.abstract/p4.cpp b/test/CXX/class.derived/class.abstract/p4.cpp
new file mode 100644
index 0000000..ca99bf7
--- /dev/null
+++ b/test/CXX/class.derived/class.abstract/p4.cpp
@@ -0,0 +1,80 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace PR6631 {
+  struct A { 
+    virtual void f() = 0;
+  };
+
+  struct B : virtual A { };
+
+  struct C : virtual A { 
+    virtual void f();
+  };
+
+  struct D : public B, public C { 
+    virtual void f();
+  };
+
+  void f() {
+    (void)new D; // okay
+  }
+}
+
+// Check cases where we have a virtual function that is pure in one
+// subobject but not pure in another subobject.
+namespace PartlyPure {
+  struct A { 
+    virtual void f() = 0; // expected-note{{pure virtual function}}
+  };
+
+  struct B : A {
+    virtual void f();
+  };
+
+  struct C : virtual A { };
+
+  struct D : B, C { };
+
+  void f() {
+    (void) new D; // expected-error{{abstract type}}
+  }
+}
+
+namespace NonPureAlongOnePath {
+  struct A { 
+    virtual void f() = 0;
+  };
+
+  struct B : virtual A {
+    virtual void f();
+  };
+
+  struct C : virtual A { };
+
+  struct D : B, C { };
+
+  void f() {
+    (void) new D; // okay
+  }  
+}
+
+namespace NonPureAlongOnePath2 {
+  struct Aprime { 
+    virtual void f() = 0;
+  };
+
+  struct A : Aprime {
+  };
+
+  struct B : virtual A {
+    virtual void f();
+  };
+
+  struct C : virtual A { };
+
+  struct D : B, C { };
+
+  void f() {
+    (void) new D; // okay
+  }  
+}
diff --git a/test/CXX/class.derived/class.abstract/p5.cpp b/test/CXX/class.derived/class.abstract/p5.cpp
new file mode 100644
index 0000000..207519d
--- /dev/null
+++ b/test/CXX/class.derived/class.abstract/p5.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct A {
+  virtual void f() = 0; // expected-note{{pure virtual function}}
+};
+
+struct B : A {
+  virtual void f();
+};
+
+struct C : B {
+  virtual void f() = 0; // expected-note 2{{pure virtual function}}
+};
+
+struct D : C {
+};
+
+void test() {
+  (void)new A; // expected-error{{object of abstract type}}
+  (void)new B;
+  (void)new C; // expected-error{{object of abstract type}}
+  (void)new D; // expected-error{{object of abstract type}}
+}
diff --git a/test/CXX/class.derived/class.member.lookup/p6.cpp b/test/CXX/class.derived/class.member.lookup/p6.cpp
new file mode 100644
index 0000000..5f4b2a7
--- /dev/null
+++ b/test/CXX/class.derived/class.member.lookup/p6.cpp
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+class V { 
+public: 
+  int f(); 
+  int x; 
+};
+
+class W { 
+public: 
+  int g(); // expected-note{{member found by ambiguous name lookup}}
+  int y; // expected-note{{member found by ambiguous name lookup}}
+};
+
+class B : public virtual V, public W
+{
+public:
+  int f(); 
+  int x;
+  int g();  // expected-note{{member found by ambiguous name lookup}}
+  int y; // expected-note{{member found by ambiguous name lookup}}
+};
+
+class C : public virtual V, public W { };
+
+class D : public B, public C { void glorp(); };
+
+void D::glorp() {
+  x++;
+  f();
+  y++; // expected-error{{member 'y' found in multiple base classes of different types}}
+  g(); // expected-error{{error: member 'g' found in multiple base classes of different types}}
+}
+
+// PR6462
+struct BaseIO { BaseIO* rdbuf() { return 0; } };
+struct Pcommon : virtual BaseIO { int rdbuf() { return 0; } };
+struct P : virtual BaseIO, Pcommon {};
+
+void f() { P p; p.rdbuf(); }
diff --git a/test/CXX/class.derived/class.member.lookup/p8.cpp b/test/CXX/class.derived/class.member.lookup/p8.cpp
new file mode 100644
index 0000000..4d4acc3
--- /dev/null
+++ b/test/CXX/class.derived/class.member.lookup/p8.cpp
@@ -0,0 +1,63 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// FIXME: Access control checks
+
+namespace PR5820 {
+  // also <rdar://problem/7535045>
+  struct Base {
+    void Foo();
+    int Member;
+  };
+
+  struct D1 : public Base {};
+  struct D2 : public Base {};
+
+  struct Derived : public D1, public D2 {
+    void Inner();
+  };
+
+  void Test() {
+    Derived d;
+    d.D1::Foo();
+    d.D1::Member = 17;
+  }
+
+  void Derived::Inner() {
+    D1::Foo();
+    D1::Member = 42;
+    this->D1::Foo();
+    this->D1::Member = 42;
+  }
+}
+
+template<typename T>
+struct BaseT {
+  void Foo(); // expected-note{{found by ambiguous name lookup}}
+  int Member;
+};
+
+template<typename T> struct Derived1T : BaseT<T> { };
+template<typename T> struct Derived2T : BaseT<T> { };
+
+template<typename T>
+struct DerivedT : public Derived1T<T>, public Derived2T<T> {
+  void Inner();
+};
+
+template<typename T>
+void DerivedT<T>::Inner() {
+  Derived1T<T>::Foo();
+  Derived2T<T>::Member = 42;
+  this->Derived1T<T>::Foo();
+  this->Derived2T<T>::Member = 42;
+  this->Foo(); // expected-error{{non-static member 'Foo' found in multiple base-class subobjects of type 'BaseT<int>'}}
+}
+
+template<typename T>
+void Test(DerivedT<T> d) {
+  d.template Derived1T<T>::Foo();
+  d.template Derived2T<T>::Member = 17;
+  d.Inner(); // expected-note{{in instantiation}}
+}
+
+template void Test(DerivedT<int>);
diff --git a/test/CXX/class.derived/class.virtual/p12.cpp b/test/CXX/class.derived/class.virtual/p12.cpp
new file mode 100644
index 0000000..208a0d1
--- /dev/null
+++ b/test/CXX/class.derived/class.virtual/p12.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -ast-print %s | FileCheck %s
+
+// CHECK: test12_A::foo()
+struct test12_A {
+  virtual void foo();
+  
+  void bar() {
+    test12_A::foo();
+  }
+};
+
+// CHECK: xp->test24_B::wibble()
+struct test24_B {
+  virtual void wibble();
+};
+
+void foo(test24_B *xp) {
+  xp->test24_B::wibble();
+}
diff --git a/test/CXX/class.derived/class.virtual/p2.cpp b/test/CXX/class.derived/class.virtual/p2.cpp
new file mode 100644
index 0000000..64d93c8
--- /dev/null
+++ b/test/CXX/class.derived/class.virtual/p2.cpp
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+struct A {
+  virtual void f() = 0; // expected-note 2{{overridden virtual function}}
+};
+
+struct Aprime : virtual A {
+  virtual void f();
+};
+
+struct B : Aprime {
+  virtual void f(); // expected-note 3{{final overrider of 'A::f'}}
+};
+
+struct C : virtual A {
+  virtual void f(); // expected-note{{final overrider of 'A::f'}}
+};
+
+struct D : B, C { }; // expected-error{{virtual function 'A::f' has more than one final overrider in 'D'}}
+
+struct B2 : B { };
+
+struct E : B, B2 { }; //expected-error{{virtual function 'A::f' has more than one final overrider in 'E'}}
+
+struct F : B, B2 {
+  virtual void f(); // okay
+};
+
+struct G : F { }; // okay
+
+struct H : G, A { }; // okay
+
+namespace MultipleSubobjects {
+  struct A { virtual void f(); };
+  struct B : A { virtual void f(); };
+  struct C : A { virtual void f(); };
+  struct D : B, C { }; // okay
+}
diff --git a/test/CXX/class.derived/p2.cpp b/test/CXX/class.derived/p2.cpp
new file mode 100644
index 0000000..7ef53d3
--- /dev/null
+++ b/test/CXX/class.derived/p2.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify
+
+// "During the lookup for a base class name, non-type names are ignored"
+namespace PR5840 {
+  struct Base {};
+  int Base = 10;
+  struct Derived : Base {};
+}
diff --git a/test/CXX/class/class.friend/p1-ambiguous.cpp b/test/CXX/class/class.friend/p1-ambiguous.cpp
new file mode 100644
index 0000000..a9dca4f
--- /dev/null
+++ b/test/CXX/class/class.friend/p1-ambiguous.cpp
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// Make sure that friend declarations don't introduce ambiguous
+// declarations.
+
+// Test case courtesy of Shantonu Sen.
+// Bug 4784.
+
+class foo;
+
+extern "C" {
+  int c_func(foo *a);
+};
+int cpp_func(foo *a);
+
+class foo {
+public:
+  friend int c_func(foo *a);
+  friend int cpp_func(foo *a);
+  int caller();
+private:
+  int x;
+};
+
+int c_func(foo *a) {
+  return a->x;
+}
+
+int cpp_func(foo *a) {
+  return a->x;
+}
+
+int foo::caller() {
+    c_func(this);
+    cpp_func(this);
+    return 0;
+}
diff --git a/test/CXX/class/class.friend/p1.cpp b/test/CXX/class/class.friend/p1.cpp
new file mode 100644
index 0000000..3ad4a5f
--- /dev/null
+++ b/test/CXX/class/class.friend/p1.cpp
@@ -0,0 +1,76 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct Outer {
+  struct Inner {
+    int intfield;
+  };
+};
+
+struct Base {
+  void base_member();
+  
+  typedef int Int;
+  Int typedeffed_member();
+};
+
+struct Derived : public Base {
+};
+
+int myglobal;
+
+void global_function();
+extern "C" {
+  void global_c_function();
+}
+
+class A {
+  class AInner {
+  };
+
+  friend class PreDeclared;
+  friend class Outer::Inner;
+  friend int Outer::Inner::intfield; // expected-error {{ friends can only be classes or functions }}
+  friend int Outer::Inner::missing_field; //expected-error {{ friends can only be classes or functions }}
+  friend int myoperation(float); // okay
+  friend int myglobal;   // expected-error {{ friends can only be classes or functions }}
+
+  friend void global_function();
+  friend void global_c_function();
+
+  friend class UndeclaredSoFar;
+  UndeclaredSoFar x; // expected-error {{ unknown type name 'UndeclaredSoFar' }}
+
+  void a_member();
+  friend void A::a_member(); // expected-error {{ friends cannot be members of the declaring class }}
+  friend void a_member(); // okay (because we ignore class scopes when looking up friends)
+  friend class A::AInner; // this is okay as an extension
+  friend class AInner; // okay, refers to ::AInner
+
+  friend void Derived::missing_member(); // expected-error {{ no function named 'missing_member' with type 'void ()' was found in the specified scope }}
+
+  friend void Derived::base_member(); // expected-error {{ no function named 'base_member' with type 'void ()' was found in the specified scope }}
+
+  friend int Base::typedeffed_member(); // okay: should look through typedef
+
+  // These test that the friend is properly not being treated as a
+  // member function.
+  friend A operator|(const A& l, const A& r); // okay
+  friend A operator|(const A& r); // expected-error {{ overloaded 'operator|' must be a binary operator (has 1 parameter) }}
+
+  friend operator bool() const; // expected-error {{ must use a qualified name when declaring a conversion operator as a friend }}
+
+  typedef void ftypedef();
+  friend ftypedef typedeffed_function; // okay (because it's not declared as a member)
+
+  class facet;
+  friend class facet;  // should not assert
+  class facet {};
+};
+
+A::UndeclaredSoFar y; // expected-error {{no type named 'UndeclaredSoFar' in 'A'}}
+
+class PreDeclared;
+
+int myoperation(float f) {
+  return (int) f;
+}
diff --git a/test/CXX/class/class.friend/p2.cpp b/test/CXX/class/class.friend/p2.cpp
new file mode 100644
index 0000000..eb5036f
--- /dev/null
+++ b/test/CXX/class/class.friend/p2.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct B0;
+
+class A {
+  friend class B {}; // expected-error {{cannot define a type in a friend declaration}}
+  friend int; // expected-warning {{non-class type 'int' cannot be a friend}}
+  friend B0; // expected-warning {{must specify 'struct' to befriend}}
+  friend class C; // okay
+};
diff --git a/test/CXX/class/class.friend/p6.cpp b/test/CXX/class/class.friend/p6.cpp
new file mode 100644
index 0000000..bd4630e
--- /dev/null
+++ b/test/CXX/class/class.friend/p6.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+class A {
+  friend static class B; // expected-error {{'static' is invalid in friend declarations}}
+  friend extern class C; // expected-error {{'extern' is invalid in friend declarations}}
+  friend auto class D; // expected-error {{'auto' is invalid in friend declarations}}
+  friend register class E; // expected-error {{'register' is invalid in friend declarations}}
+  friend mutable class F; // expected-error {{'mutable' is invalid in friend declarations}}
+  friend typedef class G; // expected-error {{'typedef' is invalid in friend declarations}}
+};
diff --git a/test/CXX/class/class.local/p1.cpp b/test/CXX/class/class.local/p1.cpp
new file mode 100644
index 0000000..05ae5c7
--- /dev/null
+++ b/test/CXX/class/class.local/p1.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s 
+
+int x;
+void f()
+{
+  static int s;
+  int x; // expected-note{{'x' declared here}}
+  extern int g();
+  
+  struct local {
+    int g() { return x; } // expected-error{{reference to local variable 'x' declared in enclosed function 'f'}}
+    int h() { return s; }
+    int k() { return :: x; }
+    int l() { return g(); }
+  };
+}
+
+local* p = 0; // expected-error{{unknown type name 'local'}}
diff --git a/test/CXX/class/class.local/p2.cpp b/test/CXX/class/class.local/p2.cpp
new file mode 100644
index 0000000..db4c90f
--- /dev/null
+++ b/test/CXX/class/class.local/p2.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct A { };
+
+void f() {
+  struct B : private A {}; // expected-note{{declared private here}}
+  
+  B b;
+  
+  A *a = &b; // expected-error{{cannot cast 'B' to its private base class 'A'}}
+}
diff --git a/test/CXX/class/class.local/p3.cpp b/test/CXX/class/class.local/p3.cpp
new file mode 100644
index 0000000..c24d5d8
--- /dev/null
+++ b/test/CXX/class/class.local/p3.cpp
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s 
+
+void f1() {
+  struct X {
+    struct Y;
+  };
+  
+  struct X::Y {
+    void f() {}
+  };
+}
+
+void f2() {
+  struct X {
+    struct Y;
+    
+    struct Y {
+      void f() {}
+    };
+  };
+}
+
+// A class nested within a local class is a local class.
+void f3(int a) { // expected-note{{'a' declared here}}
+  struct X {
+    struct Y {
+      int f() { return a; } // expected-error{{reference to local variable 'a' declared in enclosed function 'f3'}}
+    };
+  };
+}
diff --git a/test/CXX/class/class.local/p4.cpp b/test/CXX/class/class.local/p4.cpp
new file mode 100644
index 0000000..d780744
--- /dev/null
+++ b/test/CXX/class/class.local/p4.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s 
+
+void f() {
+  struct X {
+    static int a; // expected-error {{static data member 'a' not allowed in local class 'X'}}
+    int b;
+    
+    static void f() { }
+  };
+}
diff --git a/test/CXX/class/class.mfct/class.mfct.non-static/p3.cpp b/test/CXX/class/class.mfct/class.mfct.non-static/p3.cpp
new file mode 100644
index 0000000..c81e4ef
--- /dev/null
+++ b/test/CXX/class/class.mfct/class.mfct.non-static/p3.cpp
@@ -0,0 +1,93 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// [class.mfct.non-static]p3:
+//   When an id-expression (5.1) that is not part of a class member
+//   access syntax (5.2.5) and not used to form a pointer to member
+//   (5.3.1) is used in the body of a non-static member function of
+//   class X, if name lookup (3.4.1) resolves the name in the
+//   id-expression to a non-static non-type member of some class C,
+//   the id-expression is transformed into a class member access
+//   expression (5.2.5) using (*this) (9.3.2) as the
+//   postfix-expression to the left of the . operator. [ Note: if C is
+//   not X or a base class of X, the class member access expression is
+//   ill-formed. --end note] Similarly during name lookup, when an
+//   unqualified-id (5.1) used in the definition of a member function
+//   for class X resolves to a static member, an enumerator or a
+//   nested type of class X or of a base class of X, the
+//   unqualified-id is transformed into a qualified-id (5.1) in which
+//   the nested-name-specifier names the class of the member function.
+
+namespace test0 {
+  class A {
+    int data_member;
+    int instance_method();
+    static int static_method();
+
+    bool test() {
+      return data_member + instance_method() < static_method();
+    }
+  };
+}
+
+namespace test1 {
+  struct Opaque1 {}; struct Opaque2 {}; struct Opaque3 {};
+
+  struct A {
+    void foo(Opaque1); // expected-note {{candidate}}
+    void foo(Opaque2); // expected-note {{candidate}}
+    void test();
+  };
+
+  struct B : A {
+    
+  };
+
+  void A::test() {
+    B::foo(Opaque1());
+    B::foo(Opaque2());
+    B::foo(Opaque3()); // expected-error {{no matching member function}}
+  }
+}
+
+namespace test2 {
+  struct Unrelated {
+    void foo();
+  };
+
+  template <class T> struct B;
+  template <class T> struct C;
+
+  template <class T> struct A {
+    void foo();
+
+    void test0() {
+      Unrelated::foo(); // expected-error {{call to non-static member function without an object argument}}
+    }
+
+    void test1() {
+      B<T>::foo();
+    }
+
+    static void test2() {
+      B<T>::foo(); // expected-error {{call to non-static member function without an object argument}}
+    }
+
+    void test3() {
+      C<T>::foo(); // expected-error {{no member named 'foo'}}
+    }
+  };
+
+  template <class T> struct B : A<T> {
+  };
+
+  template <class T> struct C {
+  };
+
+  int test() {
+    A<int> a;
+    a.test0(); // no instantiation note here, decl is ill-formed
+    a.test1();
+    a.test2(); // expected-note {{in instantiation}}
+    a.test3(); // expected-note {{in instantiation}}
+  }
+}
diff --git a/test/CXX/class/class.nest/p1.cpp b/test/CXX/class/class.nest/p1.cpp
new file mode 100644
index 0000000..f1f5496
--- /dev/null
+++ b/test/CXX/class/class.nest/p1.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+class Outer {
+  int x;
+  static int sx;
+
+  // C++0x will likely relax this rule in this specific case, but
+  // we'll still need to enforce it in C++03 mode.  See N2253 (or
+  // successor).
+  class Inner {
+    static char a[sizeof(x)]; // expected-error {{ invalid use of nonstatic data member 'x' }}
+    static char b[sizeof(sx)]; // okay
+  };
+};
diff --git a/test/CXX/class/class.nest/p3.cpp b/test/CXX/class/class.nest/p3.cpp
new file mode 100644
index 0000000..c4c4ca7
--- /dev/null
+++ b/test/CXX/class/class.nest/p3.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// C++0x [class.nest] p3:
+//   If class X is defined in a namespace scope, a nested class Y may be
+//   declared in class X and later defined in the definition of class X or be
+//   later defined in a namespace scope enclosing the definition of class X.
+
+namespace example {
+  class E {
+    class I1;
+    class I2;
+    class I1 { };
+  };
+  class E::I2 { };
+}
+
+// Don't insert out-of-line inner class definitions into the namespace scope.
+namespace PR6107 {
+  struct S1 { };
+  struct S2 {
+    struct S1;
+  };
+  struct S2::S1 { };
+  S1 s1;
+}
diff --git a/test/CXX/class/class.nested.type/p1.cpp b/test/CXX/class/class.nested.type/p1.cpp
new file mode 100644
index 0000000..4a04a44
--- /dev/null
+++ b/test/CXX/class/class.nested.type/p1.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+class X {
+public:
+  typedef int I;
+  class Y { };
+  I a;
+};
+
+I b; // expected-error{{unknown type name 'I'}}
+Y c; // expected-error{{unknown type name 'Y'}}
+X::Y d;
+X::I e;
diff --git a/test/CXX/class/class.union/p1.cpp b/test/CXX/class/class.union/p1.cpp
new file mode 100644
index 0000000..e974d82
--- /dev/null
+++ b/test/CXX/class/class.union/p1.cpp
@@ -0,0 +1,114 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s 
+
+void abort() __attribute__((noreturn));
+
+class Okay {
+  int a_;
+};
+
+class Virtual {
+  virtual void foo() { abort(); } // expected-note 3 {{because type 'Virtual' has a virtual member function}}
+};
+
+class VirtualBase : virtual Okay { // expected-note 3 {{because type 'VirtualBase' has a virtual base class}}
+};
+
+class Ctor {
+  Ctor() { abort(); } // expected-note 3 {{because type 'Ctor' has a user-declared constructor}}
+};
+class Ctor2 {
+  Ctor2(); // expected-note 3 {{because type 'Ctor2' has a user-declared constructor}}
+};
+
+class CopyCtor {
+  CopyCtor(CopyCtor &cc) { abort(); } // expected-note 3 {{because type 'CopyCtor' has a user-declared copy constructor}}
+};
+
+// FIXME: this should eventually trigger on the operator's declaration line
+class CopyAssign { // expected-note 3 {{because type 'CopyAssign' has a user-declared copy assignment operator}}
+  CopyAssign& operator=(CopyAssign& CA) { abort(); }
+};
+
+class Dtor {
+  ~Dtor() { abort(); } // expected-note 3 {{because type 'Dtor' has a user-declared destructor}}
+};
+
+union U1 {
+  Virtual v; // expected-error {{union member 'v' has a non-trivial copy constructor}}
+  VirtualBase vbase; // expected-error {{union member 'vbase' has a non-trivial copy constructor}}
+  Ctor ctor; // expected-error {{union member 'ctor' has a non-trivial constructor}}
+  Ctor2 ctor2; // expected-error {{union member 'ctor2' has a non-trivial constructor}}
+  CopyCtor copyctor; // expected-error {{union member 'copyctor' has a non-trivial copy constructor}}
+  CopyAssign copyassign; // expected-error {{union member 'copyassign' has a non-trivial copy assignment operator}}
+  Dtor dtor; // expected-error {{union member 'dtor' has a non-trivial destructor}}
+  Okay okay;
+};
+
+union U2 {
+  struct {
+    Virtual v; // expected-note {{because type 'U2::<anonymous struct}}
+  } m1; // expected-error {{union member 'm1' has a non-trivial copy constructor}}
+  struct {
+    VirtualBase vbase; // expected-note {{because type 'U2::<anonymous struct}}
+  } m2; // expected-error {{union member 'm2' has a non-trivial copy constructor}}
+  struct {
+    Ctor ctor; // expected-note {{because type 'U2::<anonymous struct}}
+  } m3; // expected-error {{union member 'm3' has a non-trivial constructor}}
+  struct {
+    Ctor2 ctor2; // expected-note {{because type 'U2::<anonymous struct}}
+  } m3a; // expected-error {{union member 'm3a' has a non-trivial constructor}}
+  struct {
+    CopyCtor copyctor; // expected-note {{because type 'U2::<anonymous struct}}
+  } m4; // expected-error {{union member 'm4' has a non-trivial copy constructor}}
+  struct {
+    CopyAssign copyassign; // expected-note {{because type 'U2::<anonymous struct}}
+  } m5; // expected-error {{union member 'm5' has a non-trivial copy assignment operator}}
+  struct {
+    Dtor dtor; // expected-note {{because type 'U2::<anonymous struct}}
+  } m6; // expected-error {{union member 'm6' has a non-trivial destructor}}
+  struct {
+    Okay okay;
+  } m7;
+};
+
+union U3 {
+  struct s1 : Virtual { // expected-note {{because type 'U3::s1' has a base class with a non-trivial copy constructor}}
+  } m1; // expected-error {{union member 'm1' has a non-trivial copy constructor}}
+  struct s2 : VirtualBase { // expected-note {{because type 'U3::s2' has a base class with a non-trivial copy constructor}}
+  } m2; // expected-error {{union member 'm2' has a non-trivial copy constructor}}
+  struct s3 : Ctor { // expected-note {{because type 'U3::s3' has a base class with a non-trivial constructor}}
+  } m3; // expected-error {{union member 'm3' has a non-trivial constructor}}
+  struct s3a : Ctor2 { // expected-note {{because type 'U3::s3a' has a base class with a non-trivial constructor}}
+  } m3a; // expected-error {{union member 'm3a' has a non-trivial constructor}}
+  struct s4 : CopyCtor { // expected-note {{because type 'U3::s4' has a base class with a non-trivial copy constructor}}
+  } m4; // expected-error {{union member 'm4' has a non-trivial copy constructor}}
+  struct s5 : CopyAssign { // expected-note {{because type 'U3::s5' has a base class with a non-trivial copy assignment operator}}
+  } m5; // expected-error {{union member 'm5' has a non-trivial copy assignment operator}}
+  struct s6 : Dtor { // expected-note {{because type 'U3::s6' has a base class with a non-trivial destructor}}
+  } m6; // expected-error {{union member 'm6' has a non-trivial destructor}}
+  struct s7 : Okay {
+  } m7;
+};
+
+template <class A, class B> struct Either {
+  bool tag;
+  union {
+    A a;
+    B b;
+  };
+
+  Either(A& a) : tag(true), a(a) {}
+  Either(B& b) : tag(false), b(b) {}
+};
+
+/* FIXME: this should work, but crashes in template code.
+void fred() {
+  Either<int,Virtual> virt(0);
+  Either<int,VirtualBase> vbase(0);
+  Either<int,Ctor> ctor(0);
+  Either<int,CopyCtor> copyctor(0);
+  Either<int,CopyAssign> copyassign(0);
+  Either<int,Dtor> dtor(0);
+  Either<int,Okay> okay(0);
+}
+ */
diff --git a/test/CXX/conv/conv.mem/p4.cpp b/test/CXX/conv/conv.mem/p4.cpp
new file mode 100644
index 0000000..e0748d8
--- /dev/null
+++ b/test/CXX/conv/conv.mem/p4.cpp
@@ -0,0 +1,65 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct Base {
+  int data;
+  int method();
+};
+int (Base::*data_ptr) = &Base::data;
+int (Base::*method_ptr)() = &Base::method;
+
+namespace test0 {
+  struct Derived : Base {};
+  void test() {
+    int (Derived::*d) = data_ptr;
+    int (Derived::*m)() = method_ptr;
+  }
+}
+
+// Can't be inaccessible.
+namespace test1 {
+  struct Derived : private Base {}; // expected-note 2 {{declared private here}}
+  void test() {
+    int (Derived::*d) = data_ptr; // expected-error {{cannot cast private base class 'Base' to 'test1::Derived'}}
+    int (Derived::*m)() = method_ptr; // expected-error {{cannot cast private base class 'Base' to 'test1::Derived'}}
+  }
+};
+
+// Can't be ambiguous.
+namespace test2 {
+  struct A : Base {};
+  struct B : Base {};
+  struct Derived : A, B {};
+  void test() {
+    int (Derived::*d) = data_ptr; // expected-error {{ambiguous conversion from pointer to member of base class 'Base' to pointer to member of derived class 'test2::Derived':}}
+    int (Derived::*m)() = method_ptr; // expected-error {{ambiguous conversion from pointer to member of base class 'Base' to pointer to member of derived class 'test2::Derived':}}
+  }
+}
+
+// Can't be virtual.
+namespace test3 {
+  struct Derived : virtual Base {};
+  void test() {
+    int (Derived::*d) = data_ptr;  // expected-error {{conversion from pointer to member of class 'Base' to pointer to member of class 'test3::Derived' via virtual base 'Base' is not allowed}}
+    int (Derived::*m)() = method_ptr; // expected-error {{conversion from pointer to member of class 'Base' to pointer to member of class 'test3::Derived' via virtual base 'Base' is not allowed}}
+  }
+}
+
+// Can't be virtual even if there's a non-virtual path.
+namespace test4 {
+  struct A : Base {};
+  struct Derived : Base, virtual A {};
+  void test() {
+    int (Derived::*d) = data_ptr; // expected-error {{ambiguous conversion from pointer to member of base class 'Base' to pointer to member of derived class 'test4::Derived':}}
+    int (Derived::*m)() = method_ptr; // expected-error {{ambiguous conversion from pointer to member of base class 'Base' to pointer to member of derived class 'test4::Derived':}}
+  }
+}
+
+// PR6254: don't get thrown off by a virtual base.
+namespace test5 {
+  struct A {};
+  struct Derived : Base, virtual A {};
+  void test() {
+    int (Derived::*d) = data_ptr;
+    int (Derived::*m)() = method_ptr;
+  }
+}
diff --git a/test/CXX/conv/conv.qual/pr6089.cpp b/test/CXX/conv/conv.qual/pr6089.cpp
new file mode 100644
index 0000000..ae75ec4
--- /dev/null
+++ b/test/CXX/conv/conv.qual/pr6089.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+bool is_char_ptr( const char* );
+
+template< class T >
+        long is_char_ptr( T /* r */ );
+
+// Note: the const here does not lead to a qualification conversion
+template< class T >
+        void    make_range( T* const r, bool );
+
+template< class T >
+        void make_range( T& r, long );
+
+void first_finder( const char*& Search )
+{
+        make_range( Search, is_char_ptr(Search) );
+}
diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.def/namespace.memdef/p3.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.def/namespace.memdef/p3.cpp
new file mode 100644
index 0000000..ddcbe78
--- /dev/null
+++ b/test/CXX/dcl.dcl/basic.namespace/namespace.def/namespace.memdef/p3.cpp
@@ -0,0 +1,68 @@
+// RUN: %clang_cc1 -fsyntax-only %s
+
+// C++'0x [namespace.memdef] p3:
+//   Every name first declared in a namespace is a member of that namespace. If
+//   a friend declaration in a non-local class first declares a class or
+//   function the friend class or function is a member of the innermost
+//   enclosing namespace.
+
+namespace N {
+  struct S0 {
+    friend struct F0;
+    friend void f0(int);
+    struct F0 member_func();
+  };
+  struct F0 { };
+  F0 f0() { return S0().member_func(); }
+}
+N::F0 f0_var = N::f0();
+
+// Ensure we can handle attaching friend declarations to an enclosing namespace
+// with multiple contexts.
+namespace N { struct S1 { struct IS1; }; }
+namespace N {
+  struct S1::IS1 {
+    friend struct F1;
+    friend void f1(int);
+    struct F1 member_func();
+  };
+  struct F1 { };
+  F1 f1() { return S1::IS1().member_func(); }
+}
+N::F1 f1_var = N::f1();
+
+//   The name of the friend is not found by unqualified lookup (3.4.1) or by
+//   qualified lookup (3.4.3) until a matching declaration is provided in that
+//   namespace scope (either before or after the class definition granting
+//   friendship). If a friend function is called, its name may be found by the
+//   name lookup that considers functions from namespaces and classes
+//   associated with the types of the function arguments (3.4.2). If the name
+//   in a friend declaration is neither qualified nor a template-id and the
+//   declaration is a function or an elaborated-type-specifier, the lookup to
+//   determine whether the entity has been previously declared shall not
+//   consider any scopes outside the innermost enclosing namespace.
+
+template<typename T> struct X0 { };
+struct X1 { };
+
+struct Y {
+  template<typename T> union X0;
+  template<typename T> friend union X0;
+  
+  union X1;
+  friend union X1;
+};
+
+namespace N {
+  namespace M {
+    template<typename T> class X;
+  }
+}
+
+namespace N3 {
+  class Y {
+    template<typename T> friend class N::M::X;
+  };
+}
+
+// FIXME: Woefully inadequate for testing
diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.def/namespace.unnamed/p1.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.def/namespace.unnamed/p1.cpp
new file mode 100644
index 0000000..b4ec585
--- /dev/null
+++ b/test/CXX/dcl.dcl/basic.namespace/namespace.def/namespace.unnamed/p1.cpp
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -emit-llvm-only -verify %s
+
+// This lame little test was ripped straight from the standard.
+namespace {
+  int i; // expected-note {{candidate}}
+}
+void test0() { i++; }
+
+namespace A {
+  namespace {
+    int i; // expected-note {{candidate}}
+    int j;
+  }
+  void test1() { i++; }
+}
+
+using namespace A;
+
+void test2() {
+  i++; // expected-error {{reference to 'i' is ambiguous}}
+  A::i++;
+  j++;
+}
+
+
+// Test that all anonymous namespaces in a translation unit are
+// considered the same context.
+namespace {
+  class Test3 {}; // expected-note {{previous definition}}
+}
+namespace {
+  class Test3 {}; // expected-error {{redefinition of 'Test3'}}
+}
+
+namespace test4 {
+  namespace {
+    class Test4 {}; // expected-note {{previous definition}}
+  }
+  namespace {
+    class Test4 {}; // expected-error {{redefinition of 'Test4'}}
+  }
+}
diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p1.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p1.cpp
new file mode 100644
index 0000000..bb1d67f
--- /dev/null
+++ b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p1.cpp
@@ -0,0 +1,109 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// We have to avoid ADL for this test.
+
+template <unsigned N> class test {};
+
+class foo {};	// expected-note {{candidate}}
+test<0> foo(foo); // expected-note {{candidate}}
+
+namespace Test0 {
+  class foo { int x; };
+  test<1> foo(class foo);
+
+  namespace A {
+    test<2> foo(class ::foo); // expected-note {{candidate}} \
+    // expected-note{{passing argument to parameter here}}
+
+    void test0() {
+      using ::foo;
+
+      class foo a;
+      test<0> _ = (foo)(a);
+    }
+
+    void test1() {
+      using Test0::foo;
+
+      class foo a;
+      test<1> _ = (foo)(a);
+    };
+
+    void test2() {
+      class ::foo a;
+      
+      // Argument-dependent lookup is ambiguous between B:: and ::.
+      test<0> _0 = foo(a); // expected-error {{call to 'foo' is ambiguous}}
+
+      // But basic unqualified lookup is not.
+      test<2> _1 = (foo)(a);
+
+      class Test0::foo b;
+      test<2> _2 = (foo)(b); // expected-error {{no viable conversion from 'class Test0::foo' to 'class ::foo' is possible}}
+    }
+  }
+}
+
+namespace Test1 {
+  namespace A {
+    class a {};
+  }
+
+  namespace B {
+    typedef class {} b;
+  }
+
+  namespace C {
+    int c(); // expected-note {{target of using declaration}}
+  }
+
+  namespace D {
+    using typename A::a;
+    using typename B::b;
+    using typename C::c; // expected-error {{'typename' keyword used on a non-type}}
+
+    a _1 = A::a();
+    b _2 = B::b();
+  }
+}
+
+namespace test2 {
+  class A {
+  protected:
+    operator int();
+    operator bool();
+  };
+
+  class B : private A {
+  protected:
+    using A::operator int; // expected-note {{'declared protected here'}}
+  public:
+    using A::operator bool;
+  };
+
+  int test() {
+    bool b = B();
+    return B(); // expected-error {{'operator int' is a protected member of 'test2::B'}}
+  }
+}
+
+namespace test3 {
+  class A {
+    ~A();
+  };
+
+  class B {
+    friend class C;
+  private:
+    operator A*();
+  };
+
+  class C : public B {
+  public:
+    using B::operator A*;
+  };
+
+  void test() {
+    delete C();
+  }
+}
diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p10.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p10.cpp
new file mode 100644
index 0000000..1aa163a
--- /dev/null
+++ b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p10.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang -fsyntax-only -verify %s
+
+namespace test0 {
+  namespace ns0 {
+    class tag;
+    int tag();
+  }
+
+  namespace ns1 {
+    using ns0::tag;
+  }
+
+  namespace ns2 {
+    using ns0::tag;
+  }
+
+  using ns1::tag;
+  using ns2::tag;
+}
+
+// PR 5752
+namespace test1 {
+  namespace ns {
+    void foo();
+  }
+
+  using ns::foo;
+  void foo(int);
+
+  namespace ns {
+    using test1::foo;
+  }
+}
diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p11.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p11.cpp
new file mode 100644
index 0000000..63b3022
--- /dev/null
+++ b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p11.cpp
@@ -0,0 +1,94 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// C++03 [namespace.udecl]p11:
+//   If a function declaration in namespace scope or block scope has
+//   the same name and the same parameter types as a function
+//   introduced by a using-declaration, the program is
+//   ill-formed. [Note: two using-declarations may introduce functions
+//   with the same name and the same parameter types. If, for a call
+//   to an unqualified function name, function overload resolution
+//   selects the functions introduced by such using-declarations, the
+//   function call is ill-formed.
+
+namespace test0 {
+  namespace ns { void foo(); } // expected-note {{target of using declaration}}
+  int foo(); // expected-note {{conflicting declaration}}
+  using ns::foo; // expected-error {{target of using declaration conflicts with declaration already in scope}}
+}
+
+namespace test1 {
+  namespace ns { void foo(); } // expected-note {{target of using declaration}}
+  using ns::foo; //expected-note {{using declaration}}
+  int foo(); // expected-error {{declaration conflicts with target of using declaration already in scope}}
+}
+
+namespace test2 {
+  namespace ns { void foo(); } // expected-note 2 {{target of using declaration}}
+  void test0() {
+    int foo(); // expected-note {{conflicting declaration}}
+    using ns::foo; // expected-error {{target of using declaration conflicts with declaration already in scope}}
+  }
+
+  void test1() {
+    using ns::foo; //expected-note {{using declaration}}
+    int foo(); // expected-error {{declaration conflicts with target of using declaration already in scope}}
+  }
+}
+
+namespace test3 {
+  namespace ns { void foo(); } // expected-note 2 {{target of using declaration}}
+  class Test0 {
+    void test() {
+      int foo(); // expected-note {{conflicting declaration}}
+      using ns::foo; // expected-error {{target of using declaration conflicts with declaration already in scope}}
+    }
+  };
+
+  class Test1 {
+    void test() {
+      using ns::foo; //expected-note {{using declaration}}
+      int foo(); // expected-error {{declaration conflicts with target of using declaration already in scope}}
+    }
+  };
+}
+
+namespace test4 {
+  namespace ns { void foo(); } // expected-note 2 {{target of using declaration}}
+  template <typename> class Test0 {
+    void test() {
+      int foo(); // expected-note {{conflicting declaration}}
+      using ns::foo; // expected-error {{target of using declaration conflicts with declaration already in scope}}
+    }
+  };
+
+  template <typename> class Test1 {
+    void test() {
+      using ns::foo; //expected-note {{using declaration}}
+      int foo(); // expected-error {{declaration conflicts with target of using declaration already in scope}}
+    }
+  };
+}
+
+// FIXME: we should be able to diagnose both of these, but we can't.
+// ...I'm actually not sure why we can diagnose either of them; it's
+// probably a bug.
+namespace test5 {
+  namespace ns { void foo(int); } // expected-note {{target of using declaration}}
+  template <typename T> class Test0 {
+    void test() {
+      int foo(T);
+      using ns::foo;
+    }
+  };
+
+  template <typename T> class Test1 {
+    void test() {
+      using ns::foo; // expected-note {{using declaration}}
+      int foo(T); // expected-error {{declaration conflicts with target of using declaration already in scope}}
+    }
+  };
+
+  template class Test0<int>;
+  template class Test1<int>; // expected-note {{in instantiation of member function}}
+}
+
diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp
new file mode 100644
index 0000000..25371c7
--- /dev/null
+++ b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp
@@ -0,0 +1,144 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// C++03 [namespace.udecl]p12:
+//   When a using-declaration brings names from a base class into a
+//   derived class scope, member functions in the derived class
+//   override and/or hide member functions with the same name and
+//   parameter types in a base class (rather than conflicting).
+
+template <unsigned n> struct Opaque {};
+template <unsigned n> void expect(Opaque<n> _) {}
+
+// PR5727
+// This just shouldn't crash.
+namespace test0 {
+  template<typename> struct RefPtr { };
+  template<typename> struct PtrHash {
+    static void f() { }
+  };
+  template<typename T> struct PtrHash<RefPtr<T> > : PtrHash<T*> {
+    using PtrHash<T*>::f;
+    static void f() { f(); }
+  };
+}
+
+// Simple hiding.
+namespace test1 {
+  struct Base {
+    Opaque<0> foo(Opaque<0>);
+    Opaque<0> foo(Opaque<1>);
+    Opaque<0> foo(Opaque<2>);
+  };
+
+  // using before decls
+  struct Test0 : Base {
+    using Base::foo;
+    Opaque<1> foo(Opaque<1>);
+    Opaque<1> foo(Opaque<3>);
+
+    void test0() { Opaque<0> _ = foo(Opaque<0>()); }
+    void test1() { Opaque<1> _ = foo(Opaque<1>()); }
+    void test2() { Opaque<0> _ = foo(Opaque<2>()); }
+    void test3() { Opaque<1> _ = foo(Opaque<3>()); }
+  };
+
+  // using after decls
+  struct Test1 : Base {
+    Opaque<1> foo(Opaque<1>);
+    Opaque<1> foo(Opaque<3>);
+    using Base::foo;
+
+    void test0() { Opaque<0> _ = foo(Opaque<0>()); }
+    void test1() { Opaque<1> _ = foo(Opaque<1>()); }
+    void test2() { Opaque<0> _ = foo(Opaque<2>()); }
+    void test3() { Opaque<1> _ = foo(Opaque<3>()); }
+  };
+
+  // using between decls
+  struct Test2 : Base {
+    Opaque<1> foo(Opaque<0>);
+    using Base::foo;
+    Opaque<1> foo(Opaque<2>);
+    Opaque<1> foo(Opaque<3>);
+
+    void test0() { Opaque<1> _ = foo(Opaque<0>()); }
+    void test1() { Opaque<0> _ = foo(Opaque<1>()); }
+    void test2() { Opaque<1> _ = foo(Opaque<2>()); }
+    void test3() { Opaque<1> _ = foo(Opaque<3>()); }
+  };
+}
+
+// Crazy dependent hiding.
+namespace test2 {
+  struct Base {
+    void foo(int);
+  };
+
+  template <typename T> struct Derived1 : Base {
+    using Base::foo;
+    void foo(T);
+
+    void testUnresolved(int i) { foo(i); }
+  };
+
+  void test0(int i) {
+    Derived1<int> d1;
+    d1.foo(i);
+    d1.testUnresolved(i);
+  }
+
+  // Same thing, except with the order of members reversed.
+  template <typename T> struct Derived2 : Base {
+    void foo(T);
+    using Base::foo;
+
+    void testUnresolved(int i) { foo(i); }
+  };
+
+  void test1(int i) {
+    Derived2<int> d2;
+    d2.foo(i);
+    d2.testUnresolved(i);
+  }
+}
+
+// Hiding of member templates.
+namespace test3 {
+  struct Base {
+    template <class T> Opaque<0> foo() { return Opaque<0>(); }
+    template <int n> Opaque<1> foo() { return Opaque<1>(); }
+  };
+
+  struct Derived1 : Base {
+    using Base::foo;
+    template <int n> Opaque<2> foo() { return Opaque<2>(); }
+  };
+
+  struct Derived2 : Base {
+    template <int n> Opaque<2> foo() { return Opaque<2>(); }
+    using Base::foo;
+  };
+
+  struct Derived3 : Base {
+    using Base::foo;
+    template <class T> Opaque<3> foo() { return Opaque<3>(); }
+  };
+
+  struct Derived4 : Base {
+    template <class T> Opaque<3> foo() { return Opaque<3>(); }
+    using Base::foo;
+  };
+
+  void test() {
+    expect<0>(Base().foo<int>());
+    expect<1>(Base().foo<0>());
+    expect<0>(Derived1().foo<int>());
+    expect<2>(Derived1().foo<0>());
+    expect<0>(Derived2().foo<int>());
+    expect<2>(Derived2().foo<0>());
+    expect<3>(Derived3().foo<int>());
+    expect<1>(Derived3().foo<0>());
+    expect<3>(Derived4().foo<int>());
+    expect<1>(Derived4().foo<0>());
+  }
+}
diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p13.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p13.cpp
new file mode 100644
index 0000000..ec814b1
--- /dev/null
+++ b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p13.cpp
@@ -0,0 +1,63 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// C++03 [namespace.udecl]p3:
+//   For the purpose of overload resolution, the functions which are
+//   introduced by a using-declaration into a derived class will be
+//   treated as though they were members of the derived class. In
+//   particular, the implicit this parameter shall be treated as if it
+//   were a pointer to the derived class rather than to the base
+//   class. This has no effect on the type of the function, and in all
+//   other respects the function remains a member of the base class.
+
+namespace test0 {
+  struct Opaque0 {};
+  struct Opaque1 {};
+
+  struct Base {
+    Opaque0 test0(int*);
+    Opaque0 test1(const int*);
+    Opaque0 test2(int*);
+    Opaque0 test3(int*) const;
+  };
+
+  struct Derived : Base {
+    using Base::test0;
+    Opaque1 test0(const int*);
+
+    using Base::test1;
+    Opaque1 test1(int*);
+
+    using Base::test2;
+    Opaque1 test2(int*) const;
+
+    using Base::test3;
+    Opaque1 test3(int*);
+  };
+
+  void test0() {
+    Opaque0 a = Derived().test0((int*) 0);
+    Opaque1 b = Derived().test0((const int*) 0);
+  }
+
+  void test1() {
+    Opaque1 a = Derived().test1((int*) 0);
+    Opaque0 b = Derived().test1((const int*) 0);
+  }
+
+  void test2() {
+    Opaque0 a = ((Derived*) 0)->test2((int*) 0);
+    Opaque1 b = ((const Derived*) 0)->test2((int*) 0);
+  }
+
+  void test3() {
+    Opaque1 a = ((Derived*) 0)->test3((int*) 0);
+    Opaque0 b = ((const Derived*) 0)->test3((int*) 0);
+  }
+}
+
+// Things to test:
+//   member operators
+//   conversion operators
+//   call operators
+//   call-surrogate conversion operators
+//   everything, but in dependent contexts
diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p3-cxx0x.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p3-cxx0x.cpp
new file mode 100644
index 0000000..3f3bf4a
--- /dev/null
+++ b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p3-cxx0x.cpp
@@ -0,0 +1,46 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+// C++0x N2914.
+
+struct B {
+  void f(char);
+  void g(char);
+  enum E { e };
+  union { int x; };
+};
+
+class C {
+  int g();
+};
+
+class D2 : public B {
+  using B::f;
+  using B::e;
+  using B::x;
+  using C::g; // expected-error{{using declaration refers into 'C::', which is not a base class of 'D2'}}
+};
+
+namespace test1 {
+  struct Base {
+    int foo();
+  };
+
+  struct Unrelated {
+    int foo();
+  };
+
+  struct Subclass : Base {
+  };
+
+  namespace InnerNS {
+    int foo();
+  }
+
+  // We should be able to diagnose these without instantiation.
+  template <class T> struct C : Base {
+    using InnerNS::foo; // expected-error {{not a class}}
+    using Base::bar; // expected-error {{no member named 'bar'}}
+    using Unrelated::foo; // expected-error {{not a base class}}
+    using C::foo; // expected-error {{refers to its own class}}
+    using Subclass::foo; // expected-error {{not a base class}}
+  };
+}
diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p4.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p4.cpp
new file mode 100644
index 0000000..a43d9e0
--- /dev/null
+++ b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p4.cpp
@@ -0,0 +1,213 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// C++03 [namespace.udecl]p4:
+//   A using-declaration used as a member-declaration shall refer to a
+//   member of a base class of the class being defined, shall refer to
+//   a member of an anonymous union that is a member of a base class
+//   of the class being defined, or shall refer to an enumerator for
+//   an enumeration type that is a member of a base class of the class
+//   being defined.
+
+// There is no directly analogous paragraph in C++0x, and the feature
+// works sufficiently differently there that it needs a separate test.
+
+namespace test0 {
+  namespace NonClass {
+    typedef int type;
+    struct hiding {};
+    int hiding;
+    static union { double union_member; };
+    enum tagname { enumerator };
+  }
+
+  class Test0 {
+    using NonClass::type; // expected-error {{not a class}}
+    using NonClass::hiding; // expected-error {{not a class}}
+    using NonClass::union_member; // expected-error {{not a class}}
+    using NonClass::enumerator; // expected-error {{not a class}}
+  };
+}
+
+struct Opaque0 {};
+
+namespace test1 {
+  struct A {
+    typedef int type;
+    struct hiding {}; // expected-note {{previous use is here}}
+    Opaque0 hiding;
+    union { double union_member; };
+    enum tagname { enumerator };
+  };
+
+  struct B : A {
+    using A::type;
+    using A::hiding;
+    using A::union_member;
+    using A::enumerator;
+    using A::tagname;
+
+    void test0() {
+      type t = 0;
+    }
+
+    void test1() {
+      typedef struct A::hiding local;
+      struct hiding _ = local();
+    }
+
+    void test2() {
+      union hiding _; // expected-error {{tag type that does not match previous}}
+    }
+
+    void test3() {
+      char array[sizeof(union_member) == sizeof(double) ? 1 : -1];
+    }
+
+    void test4() {
+      enum tagname _ = enumerator;
+    }
+
+    void test5() {
+      Opaque0 _ = hiding;
+    }
+  };
+}
+
+namespace test2 {
+  struct A {
+    typedef int type;
+    struct hiding {}; // expected-note {{previous use is here}}
+    int hiding;
+    union { double union_member; };
+    enum tagname { enumerator };
+  };
+
+  template <class T> struct B : A {
+    using A::type;
+    using A::hiding;
+    using A::union_member;
+    using A::enumerator;
+    using A::tagname;
+
+    void test0() {
+      type t = 0;
+    }
+
+    void test1() {
+      typedef struct A::hiding local;
+      struct hiding _ = local();
+    }
+
+    void test2() {
+      union hiding _; // expected-error {{tag type that does not match previous}}
+    }
+
+    void test3() {
+      char array[sizeof(union_member) == sizeof(double) ? 1 : -1];
+    }
+
+    void test4() {
+      enum tagname _ = enumerator;
+    }
+
+    void test5() {
+      Opaque0 _ = hiding;
+    }
+  };
+}
+
+namespace test3 {
+  struct hiding {};
+
+  template <class T> struct A {
+    typedef int type; // expected-note {{target of using declaration}}
+    struct hiding {};
+    Opaque0 hiding; // expected-note {{target of using declaration}}
+    union { double union_member; }; // expected-note {{target of using declaration}}
+    enum tagname { enumerator }; // expected-note 2 {{target of using declaration}}
+  };
+
+  template <class T> struct B : A<T> {
+    using A<T>::type; // expected-error {{dependent using declaration resolved to type without 'typename'}}
+    using A<T>::hiding;
+    using A<T>::union_member;
+    using A<T>::enumerator;
+    using A<T>::tagname; // expected-error {{dependent using declaration resolved to type without 'typename'}}
+
+    // FIXME: re-enable these when the various bugs involving tags are fixed
+#if 0
+    void test1() {
+      typedef struct A<T>::hiding local;
+      struct hiding _ = local();
+    }
+
+    void test2() {
+      typedef struct A<T>::hiding local;
+      union hiding _ = local();
+    }
+#endif
+
+    void test3() {
+      char array[sizeof(union_member) == sizeof(double) ? 1 : -1];
+    }
+
+#if 0
+    void test4() {
+      enum tagname _ = enumerator;
+    }
+#endif
+
+    void test5() {
+      Opaque0 _ = hiding;
+    }
+  };
+
+  template struct B<int>; // expected-note {{in instantiation}}
+
+  template <class T> struct C : A<T> {
+    using typename A<T>::type;
+    using typename A<T>::hiding; // expected-note {{declared here}} \
+                                 // expected-error {{'typename' keyword used on a non-type}}
+    using typename A<T>::union_member; // expected-error {{'typename' keyword used on a non-type}}
+    using typename A<T>::enumerator; // expected-error {{'typename' keyword used on a non-type}}
+
+    void test6() {
+      type t = 0;
+    }
+
+    void test7() {
+      Opaque0 _ = hiding; // expected-error {{does not refer to a value}}
+    }
+  };
+
+  template struct C<int>; // expected-note {{in instantiation}}
+}
+
+namespace test4 {
+  struct Base {
+    int foo();
+  };
+
+  struct Unrelated {
+    int foo();
+  };
+
+  struct Subclass : Base {
+  };
+
+  namespace InnerNS {
+    int foo();
+  }
+
+  // We should be able to diagnose these without instantiation.
+  template <class T> struct C : Base {
+    using InnerNS::foo; // expected-error {{not a class}}
+    using Base::bar; // expected-error {{no member named 'bar'}}
+    using Unrelated::foo; // expected-error {{not a base class}}
+    using C::foo; // legal in C++03
+    using Subclass::foo; // legal in C++03
+
+    int bar(); //expected-note {{target of using declaration}}
+    using C::bar; // expected-error {{refers to its own class}}
+  };
+}
diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p5-cxx0x.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p5-cxx0x.cpp
new file mode 100644
index 0000000..edaa975
--- /dev/null
+++ b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p5-cxx0x.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// C++0x N2914.
+
+struct A {
+  template<class T> void f(T);
+  template<class T> struct X { };
+};
+
+struct B : A {
+  using A::f<double>; // expected-error{{using declaration can not refer to a template specialization}}
+  using A::X<int>; // expected-error{{using declaration can not refer to a template specialization}}
+};
diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p6-cxx0x.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p6-cxx0x.cpp
new file mode 100644
index 0000000..c4b8849
--- /dev/null
+++ b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p6-cxx0x.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// C++0x N2914.
+
+namespace A {
+  namespace B { }
+}
+
+using A::B; // expected-error{{using declaration can not refer to namespace}}
diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p8-cxx0x.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p8-cxx0x.cpp
new file mode 100644
index 0000000..78b5a41
--- /dev/null
+++ b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p8-cxx0x.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// C++0x N2914.
+
+struct X {
+  int i;
+  static int a;
+};
+
+using X::i; // expected-error{{using declaration can not refer to class member}}
+using X::s; // expected-error{{using declaration can not refer to class member}}
+
+void f() {
+  using X::i; // expected-error{{using declaration can not refer to class member}}
+  using X::s; // expected-error{{using declaration can not refer to class member}}
+}
diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p8.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p8.cpp
new file mode 100644
index 0000000..fd2df01
--- /dev/null
+++ b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p8.cpp
@@ -0,0 +1,83 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct Opaque0 {};
+struct Opaque1 {};
+
+// Redeclarations are okay in a namespace.
+namespace test0 {
+  namespace ns {
+    void foo(Opaque0); // expected-note 2 {{candidate function}}
+  }
+
+  using ns::foo;
+  using ns::foo;
+
+  void test0() {
+    foo(Opaque1()); // expected-error {{no matching function for call}}
+  }
+
+  namespace ns {
+    void foo(Opaque1);
+  }
+
+  void test1() {
+    foo(Opaque1()); // expected-error {{no matching function for call}}
+  }
+
+  using ns::foo;
+
+  void test2() {
+    foo(Opaque1());
+  }
+
+  using ns::foo;
+}
+
+// Make sure we handle transparent contexts the same way.
+namespace test1 {
+  namespace ns {
+    void foo(Opaque0); // expected-note 2 {{candidate function}}
+  }
+
+  extern "C++" {
+    using ns::foo;
+  }
+
+  void test0() {
+    foo(Opaque1()); // expected-error {{no matching function for call}}
+  }
+
+  namespace ns {
+    void foo(Opaque1);
+  }
+
+  void test1() {
+    foo(Opaque1()); // expected-error {{no matching function for call}}
+  }
+
+  extern "C++" {
+    using ns::foo;
+  }
+
+  void test2() {
+    foo(Opaque1());
+  }
+}
+
+// Make sure we detect invalid redeclarations that can't be detected
+// until template instantiation.
+namespace test2 {
+  template <class T> struct Base {
+    typedef Base type;
+    void foo();
+  };
+
+  template <class T> struct Derived : Base<T> {
+    // These are invalid redeclarations, detectable only after
+    // instantiation.
+    using Base<T>::foo; // expected-note {{previous using decl}}
+    using Base<T>::type::foo; //expected-error {{redeclaration of using decl}}
+  };
+
+  template struct Derived<int>; // expected-note {{in instantiation of template class}}
+}
diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.udir/p1.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.udir/p1.cpp
new file mode 100644
index 0000000..20a19ab
--- /dev/null
+++ b/test/CXX/dcl.dcl/basic.namespace/namespace.udir/p1.cpp
@@ -0,0 +1,141 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// (this actually occurs before paragraph 1)
+namespace test0 {
+  namespace A {}
+  class B {
+    using namespace A; // expected-error {{'using namespace' is not allowed in classes}}
+  };
+}
+
+
+struct opaque0 {};
+struct opaque1 {};
+
+// Test that names appear as if in deepest common ancestor.
+namespace test1 {
+  namespace A {
+    namespace B {
+      opaque0 foo(); // expected-note {{candidate}}
+    }
+  }
+
+  namespace C {
+    opaque1 foo(); // expected-note {{candidate}}
+
+    opaque1 test() {
+      using namespace A::B;
+      return foo(); // C::foo
+    }
+  }
+
+  opaque1 test() {
+    using namespace A::B;
+    using namespace C;
+    return foo(); // expected-error {{call to 'foo' is ambiguous}}
+  }
+}
+
+// Same thing, but with the directives in namespaces.
+namespace test2 {
+  namespace A {
+    namespace B {
+      opaque0 foo(); // expected-note {{candidate}}
+    }
+  }
+
+  namespace C {
+    opaque1 foo(); // expected-note {{candidate}}
+
+    namespace test {
+      using namespace A::B;
+
+      opaque1 test() {
+        return foo(); // C::foo
+      }
+    }
+  }
+
+  namespace test {
+    using namespace A::B;
+    using namespace C;
+    
+    opaque1 test() {
+      return foo(); // expected-error {{call to 'foo' is ambiguous}}
+    }
+  }
+}
+
+// Transitivity.
+namespace test3 {
+  namespace A {
+    namespace B {
+      opaque0 foo();
+    }
+  }
+  namespace C {
+    using namespace A;
+  }
+
+  opaque0 test0() {
+    using namespace C;
+    using namespace B;
+    return foo();
+  }
+
+  namespace D {
+    using namespace C;
+  }
+  namespace A {
+    opaque1 foo();
+  }
+
+  opaque1 test1() {
+    using namespace D;
+    return foo();
+  }
+}
+
+// Transitivity acts like synthetic using directives.
+namespace test4 {
+  namespace A {
+    namespace B {
+      opaque0 foo(); // expected-note {{candidate}}
+    }
+  }
+  
+  namespace C {
+    using namespace A::B;
+  }
+
+  opaque1 foo(); // expected-note {{candidate}}
+
+  namespace A {
+    namespace D {
+      using namespace C;
+    }
+
+    opaque0 test() {
+      using namespace D;
+      return foo();
+    }
+  }
+
+  opaque0 test() {
+    using namespace A::D;
+    return foo(); // expected-error {{call to 'foo' is ambiguous}}
+  }
+}
+
+// Bug: using directives should be followed when parsing default
+// arguments in scoped declarations.
+class test5 {
+  int inc(int x);
+};
+namespace Test5 {
+  int default_x = 0;
+}
+using namespace Test5;
+int test5::inc(int x = default_x) {
+  return x+1;
+}
diff --git a/test/CXX/dcl.dcl/dcl.enum/p5.cpp b/test/CXX/dcl.dcl/dcl.enum/p5.cpp
new file mode 100644
index 0000000..f260624
--- /dev/null
+++ b/test/CXX/dcl.dcl/dcl.enum/p5.cpp
@@ -0,0 +1,56 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10.0.0 -fsyntax-only -verify %s
+template<typename T> int force_same(T, T);
+
+// C++ [dcl.enum]p5:
+//   [...] If the underlying type is not fixed, the type of each enumerator is 
+//   the type of its initializing value:
+//     - If an initializer is specified for an enumerator, the initializing 
+//       value has the same type as the expression.
+enum Bullet1 {
+  Bullet1Val1 = 'a',
+  Bullet1Val2 = 10u,
+  Bullet1Val1IsChar = sizeof(force_same(Bullet1Val1, char(0))),
+  Bullet1Val2IsUnsigned = sizeof(force_same(Bullet1Val2, unsigned(0)))
+};
+
+//    - If no initializer is specified for the first enumerator, the 
+//      initializing value has an unspecified integral type.
+enum Bullet2 {
+  Bullet2Val,
+  Bullet2ValIsInt = sizeof(force_same(Bullet2Val, int(0)))
+};
+
+//    - Otherwise the type of the initializing value is the same as the type
+//      of the initializing value of the preceding enumerator unless the 
+//      incremented value is not representable in that type, in which case the
+//      type is an unspecified integral type sufficient to contain the 
+//      incremented value. If no such type exists, the program is ill-formed.
+enum Bullet3a {
+  Bullet3aVal1 = 17,
+  Bullet3aVal2,
+  Bullet3aVal2IsInt = sizeof(force_same(Bullet3aVal2, int(0))),
+  Bullet3aVal3 = 2147483647,
+  Bullet3aVal3IsInt = sizeof(force_same(Bullet3aVal3, int(0))),
+  Bullet3aVal4,
+  Bullet3aVal4IsUnsigned = sizeof(force_same(Bullet3aVal4, 0ul))
+};
+
+enum Bullet3b {
+  Bullet3bVal1 = 17u,
+  Bullet3bVal2,
+  Bullet3bVal2IsInt = sizeof(force_same(Bullet3bVal2, 0u)),
+  Bullet3bVal3 = 2147483647u,
+  Bullet3bVal3IsInt = sizeof(force_same(Bullet3bVal3, 0u)),
+  Bullet3bVal4,
+  Bullet3bVal4IsUnsigned = sizeof(force_same(Bullet3bVal4, 0ul))
+};
+
+enum Bullet3c {
+  Bullet3cVal1 = 0xFFFFFFFFFFFFFFFEull,
+  Bullet3cVal2,
+  Bullet3cVal3 // expected-warning{{not representable}}
+};
+
+//   Following the closing brace of an enum-specifier, each enumerator has the
+//   type of its enumeration.
+int array0[sizeof(force_same(Bullet3bVal3, Bullet3b(0)))? 1 : -1];
diff --git a/test/CXX/dcl.dcl/dcl.link/p7.cpp b/test/CXX/dcl.dcl/dcl.link/p7.cpp
new file mode 100644
index 0000000..bd9ff3c
--- /dev/null
+++ b/test/CXX/dcl.dcl/dcl.link/p7.cpp
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+
+struct X { };
+
+// CHECK: @x1 = global %struct.X zeroinitializer
+// CHECK: @x4 = global %struct.X zeroinitializer
+// CHECK: @x2 = external global %struct.X
+// CHECK: @x3 = external global %struct.X
+extern "C" {
+
+
+  X x1;
+}
+
+extern "C" X x2;
+
+extern X x3;
+
+X x4;
+
+X& get(int i) {
+  if (i == 1)
+    return x1;
+  else if (i == 2)
+    return x2;
+  else if (i == 3)
+    return x3;
+  else
+    return x4;
+}
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p3.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p3.cpp
new file mode 100644
index 0000000..99a4f7a
--- /dev/null
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p3.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -verify %s
+// XFAIL: *
+
+void f0(void) {
+  inline void f1(); // expected-error {{'inline' is not allowed on block scope function declaration}}
+}
+
+// FIXME: Add test for "If the inline specifier is used in a friend declaration,
+// that declaration shall be a definition or the function shall have previously
+// been declared inline.
+
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p4.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p4.cpp
new file mode 100644
index 0000000..15efd72
--- /dev/null
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p4.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -verify %s
+// XFAIL: *
+
+void f0() {
+}
+
+inline void f0(); // expected-error {{function definition cannot preceed inline declaration}}
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p6.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p6.cpp
new file mode 100644
index 0000000..fcc1334
--- /dev/null
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p6.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -verify %s
+
+class A {
+public:
+  explicit A();
+  
+  explicit operator int(); // expected-warning {{explicit conversion functions are a C++0x extension}}
+
+  explicit void f0(); // expected-error {{'explicit' can only be applied to a constructor or conversion function}}
+  
+  operator bool();
+};
+
+explicit A::A() { } // expected-error {{'explicit' can only be specified inside the class definition}}
+explicit A::operator bool() { return false; }  // expected-warning {{explicit conversion functions are a C++0x extension}}\
+                                               // expected-error {{'explicit' can only be specified inside the class definition}}
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p10.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p10.cpp
new file mode 100644
index 0000000..fd86276
--- /dev/null
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p10.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -verify %s
+// XFAIL: *
+
+typedef const int T0;
+typedef int& T1;
+
+struct s0 {
+  mutable const int f0; // expected-error{{'mutable' and 'const' cannot be mixed}}
+  mutable T0 f1; // expected-error{{'mutable' and 'const' cannot be mixed}}
+  mutable int &f2; // expected-error{{'mutable' cannot be applied to references}}
+  mutable T1 f3; // expected-error{{'mutable' cannot be applied to references}}
+  mutable struct s1 {}; // expected-error{{'mutable' cannot be applied to non-data members}}
+  mutable void im0(); // expected-error{{'mutable' cannot be applied to functions}}
+};
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p9.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p9.cpp
new file mode 100644
index 0000000..f507eec
--- /dev/null
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p9.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -verify %s
+
+struct S; // expected-note {{forward declaration of 'S'}}
+extern S a;
+extern S f(); // expected-note {{'f' declared here}}
+extern void g(S a); // expected-note {{candidate function}}
+
+void h() {
+  // FIXME: This diagnostic could be better.
+  g(a); // expected-error {{no matching function for call to 'g'}}
+  f(); // expected-error {{calling 'f' with incomplete return type 'S'}}
+}
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3.cpp
new file mode 100644
index 0000000..082a32d
--- /dev/null
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
+void f() {
+  auto a = a; // expected-error{{variable 'a' declared with 'auto' type cannot appear in its own initializer}}
+}
+
+void g() {
+  auto a; // expected-error{{declaration of variable 'a' with type 'auto' requires an initializer}}
+  
+  auto *b; // expected-error{{declaration of variable 'b' with type 'auto *' requires an initializer}}
+}
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp
new file mode 100644
index 0000000..e739254
--- /dev/null
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
+void f() {
+  auto a = a; // expected-error{{variable 'a' declared with 'auto' type cannot appear in its own initializer}}
+}
+
+struct S { auto a; }; // expected-error{{'auto' not allowed in struct member}}
+
+void f(auto a) // expected-error{{'auto' not allowed in function prototype}}
+{
+  try { } catch (auto a) {  } // expected-error{{'auto' not allowed in exception declaration}}
+}
+
+template <auto a = 10> class C { }; // expected-error{{'auto' not allowed in template parameter}}
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p3.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p3.cpp
new file mode 100644
index 0000000..b04e869
--- /dev/null
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p3.cpp
@@ -0,0 +1,60 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+class A {}; // expected-note 3 {{previous use is here}}
+
+void a1(struct A);
+void a2(class A);
+void a3(union A); // expected-error {{use of 'A' with tag type that does not match previous declaration}}
+void a4(enum A); // expected-error {{use of 'A' with tag type that does not match previous declaration}}
+
+class A1 {
+  friend struct A;
+  friend class A;
+  friend union A; // expected-error {{use of 'A' with tag type that does not match previous declaration}}
+
+  friend enum A; // expected-error {{ISO C++ forbids forward references to 'enum' types}} \
+                 // expected-warning {{cannot be a friend}}
+};
+
+template <class T> struct B { // expected-note {{previous use is here}}
+  class Member {}; // expected-note 2 {{previous use is here}}
+};
+
+template <> class B<int> {
+  // no type Member
+};
+
+template <> struct B<A> {
+  union Member { // expected-note 4 {{previous use is here}}
+    void* a;
+  };
+};
+
+void b1(struct B<float>);
+void b2(class B<float>);
+void b3(union B<float>); // expected-error {{use of 'B<float>' with tag type that does not match previous declaration}}
+//void b4(enum B<float>); // this just doesn't parse; you can't template an enum directly
+
+void c1(struct B<float>::Member);
+void c2(class B<float>::Member);
+void c3(union B<float>::Member); // expected-error {{use of 'Member' with tag type that does not match previous declaration}}
+void c4(enum B<float>::Member); // expected-error {{use of 'Member' with tag type that does not match previous declaration}}
+
+void d1(struct B<int>::Member); // expected-error {{no struct named 'Member' in 'B<int>'}}
+void d2(class B<int>::Member); // expected-error {{no class named 'Member' in 'B<int>'}}
+void d3(union B<int>::Member); // expected-error {{no union named 'Member' in 'B<int>'}}
+void d4(enum B<int>::Member); // expected-error {{no enum named 'Member' in 'B<int>'}}
+
+void e1(struct B<A>::Member); // expected-error {{use of 'Member' with tag type that does not match previous declaration}}
+void e2(class B<A>::Member); // expected-error {{use of 'Member' with tag type that does not match previous declaration}}
+void e3(union B<A>::Member);
+void e4(enum B<A>::Member); // expected-error {{use of 'Member' with tag type that does not match previous declaration}}
+
+template <class T> struct C {
+  void foo(class B<T>::Member); // expected-error{{no class named 'Member' in 'B<int>'}} \
+                                // expected-error{{use of 'Member' with tag type that does not match previous declaration}}
+};
+
+C<float> f1;
+C<int> f2; // expected-note {{in instantiation of template class}}
+C<A> f3; // expected-note {{in instantiation of template class}}
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p4-cxx0x.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p4-cxx0x.cpp
new file mode 100644
index 0000000..19159e1
--- /dev/null
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p4-cxx0x.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++0x -verify %s
+
+template<typename T, typename U>
+struct is_same {
+  static const bool value = false;
+};
+
+template<typename T>
+struct is_same<T, T> {
+  static const bool value = true;
+};
+
+const int&& foo();
+int i;
+struct A { double x; };
+const A* a = new A();
+
+static_assert(is_same<decltype(foo()), const int&&>::value, "");
+static_assert(is_same<decltype(i), int>::value, "");
+static_assert(is_same<decltype(a->x), double>::value, "");
+static_assert(is_same<decltype((a->x)), const double&>::value, "");
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p3.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p3.cpp
new file mode 100644
index 0000000..28f49d08
--- /dev/null
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p3.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -verify %s
+
+typedef struct s { int x; } s;
+typedef int I;
+typedef int I2;
+typedef I2 I; // expected-note {{previous definition is here}}
+
+typedef char I; // expected-error {{typedef redefinition with different types}}
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p4.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p4.cpp
new file mode 100644
index 0000000..c16ba20
--- /dev/null
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p4.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -verify %s
+
+struct S {
+  typedef struct A {} A; // expected-note {{previous definition is here}}
+  typedef struct B B;
+  typedef A A; // expected-error {{redefinition of 'A'}}
+
+  struct C { };
+  typedef struct C OtherC;
+  typedef OtherC C;
+
+  typedef struct D { } D2;
+  typedef D2 D;
+};
+
diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p4.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p4.cpp
new file mode 100644
index 0000000..c38bd29
--- /dev/null
+++ b/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p4.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 -pedantic -Werror  %s
+int a1[] = { 1, 3, 5 };
+void f() {
+  int a2[] = { 1, 3, 5 };
+}
+template <typename T>
+void tf() {
+  T t;
+  // Element type may be dependent
+  T a3[] = { 1, 3, 5 };
+  // As might be the initializer list, value
+  int a5[] = { sizeof(T) };
+  // or even type.
+  int a6[] = { t.get() };
+}
+
+// Allowed by GNU extension
+int a4[] = {}; // expected-warning {{zero size arrays}}
diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.list/basic.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.list/basic.cpp
new file mode 100644
index 0000000..5ebc22f
--- /dev/null
+++ b/test/CXX/dcl.decl/dcl.init/dcl.init.list/basic.cpp
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+void f0() {
+  int &ir = { 17 }; // expected-error{{reference to type 'int' cannot bind to an initializer list}}
+}
diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/basic.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/basic.cpp
new file mode 100644
index 0000000..885d11b
--- /dev/null
+++ b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/basic.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// PR5787
+class C {
+ public:
+  ~C() {}
+};
+
+template <typename T>
+class E {
+ public:
+  E& Foo(const C&);
+  E& Bar() { return Foo(C()); }
+};
+
+void Test() {
+  E<int> e;
+  e.Bar();
+}
diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p1.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p1.cpp
new file mode 100644
index 0000000..bd08ab5
--- /dev/null
+++ b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p1.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s
+int g(int);
+void f() {
+  int i; 
+  int& r = i;
+  r = 1; 
+  int* p = &r;
+  int &rr=r; 
+  int (&rg)(int) = g; 
+  rg(i); 
+  int a[3]; 
+  int (&ra)[3] = a; 
+  ra[1] = i;
+}
diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p16-cxx0x-no-extra-copy.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p16-cxx0x-no-extra-copy.cpp
new file mode 100644
index 0000000..5a342d4
--- /dev/null
+++ b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p16-cxx0x-no-extra-copy.cpp
@@ -0,0 +1,50 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s
+
+// C++03 requires that we check for a copy constructor when binding a
+// reference to a reference-compatible rvalue, since we are allowed to
+// make a copy. C++0x does not permit the copy, so ensure that we
+// don't diagnose cases where the copy constructor is unavailable.
+
+struct X1 {
+  X1();
+  explicit X1(const X1&);
+};
+
+struct X2 {
+  X2();
+
+private:
+  X2(const X2&);
+};
+
+struct X3 {
+  X3();
+
+private:
+  X3(X3&);
+};
+
+template<typename T>
+T get_value_badly() {
+  double *dp = 0;
+  T *tp = dp;
+  return T();
+}
+
+template<typename T>
+struct X4 {
+  X4();
+  X4(const X4&, T = get_value_badly<T>());
+};
+
+void g1(const X1&);
+void g2(const X2&);
+void g3(const X3&);
+void g4(const X4<int>&);
+
+void test() {
+  g1(X1());
+  g2(X2());
+  g3(X3());
+  g4(X4<int>());
+}
diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p3.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p3.cpp
new file mode 100644
index 0000000..47e215a
--- /dev/null
+++ b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p3.cpp
@@ -0,0 +1,3 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+int& r1;	// expected-error{{declaration of reference variable 'r1' requires an initializer}}
+extern int& r2;
diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx03-extra-copy.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx03-extra-copy.cpp
new file mode 100644
index 0000000..1639411
--- /dev/null
+++ b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx03-extra-copy.cpp
@@ -0,0 +1,61 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// C++03 requires that we check for a copy constructor when binding a
+// reference to a temporary, since we are allowed to make a copy, Even
+// though we don't actually make that copy, make sure that we diagnose
+// cases where that copy constructor is somehow unavailable.
+
+struct X1 {
+  X1();
+  explicit X1(const X1&);
+};
+
+struct X2 {
+  X2();
+
+private:
+  X2(const X2&); // expected-note{{declared private here}}
+};
+
+struct X3 {
+  X3();
+
+private:
+  X3(X3&); // expected-note{{candidate constructor not viable: no known conversion from 'X3' to 'X3 &' for 1st argument}}
+};
+
+// Check for instantiation of default arguments
+template<typename T>
+T get_value_badly() {
+  double *dp = 0;
+  T *tp = dp; // expected-error{{ cannot initialize a variable of type 'int *' with an lvalue of type 'double *'}}
+  return T();
+}
+
+template<typename T>
+struct X4 {
+  X4();
+  X4(const X4&, T = get_value_badly<T>()); // expected-note{{in instantiation of}}
+}; 
+
+// Check for "dangerous" default arguments that could cause recursion.
+struct X5 {
+  X5();
+  X5(const X5&, const X5& = X5()); // expected-error{{no viable constructor copying parameter of type 'X5'}}
+};
+
+void g1(const X1&);
+void g2(const X2&);
+void g3(const X3&);
+void g4(const X4<int>&);
+void g5(const X5&);
+
+void test() {
+  g1(X1()); // expected-error{{no viable constructor copying parameter of type 'X1'}}
+  g2(X2()); // expected-error{{calling a private constructor of class 'X2'}}
+  g3(X3()); // expected-error{{no viable constructor copying parameter of type 'X3'}}
+  g4(X4<int>());
+  g5(X5()); // expected-error{{no viable constructor copying parameter of type 'X5'}}
+}
+
+// Check for dangerous recursion in default arguments.
diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp
new file mode 100644
index 0000000..9b39259
--- /dev/null
+++ b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 -ast-dump %s 2>&1 | FileCheck %s
+
+// CHECK: example0
+void example0() {
+  double d = 2.0;
+  // CHECK: double &rd =
+  // CHECK-NEXT: DeclRefExpr
+  double &rd = d;
+  // CHECK: double const &rcd =
+  // CHECK-NEXT: ImplicitCastExpr{{.*}}'double const' <NoOp>
+  const double &rcd = d;
+}
+
+struct A { };
+struct B : A { } b;
+
+// CHECK: example1
+void example1() {
+  // CHECK: A &ra =
+  // CHECK: ImplicitCastExpr{{.*}}'struct A' <DerivedToBase (A)> lvalue
+  A &ra = b;
+  // CHECK: A const &rca =
+  // CHECK: ImplicitCastExpr{{.*}}'struct A const' <NoOp>
+  // CHECK: ImplicitCastExpr{{.*}}'struct A' <DerivedToBase (A)>
+  const A& rca = b;
+}
+
+extern B f();
+
+struct X {
+  operator B();
+} x;
+
+// CHECK: example2
+void example2() {
+  // CHECK: A const &rca =
+  // CHECK: ImplicitCastExpr{{.*}}'struct A const' <NoOp>
+  // CHECK: ImplicitCastExpr{{.*}}'struct A' <DerivedToBase (A)>
+  // CHECK: CallExpr{{.*}}B
+  const A &rca = f(); 
+  // CHECK: A const &r =
+  // CHECK: ImplicitCastExpr{{.*}}'struct A const' <NoOp>
+  // CHECK: ImplicitCastExpr{{.*}}'struct A' <DerivedToBase (A)>
+  // CHECK: CXXMemberCallExpr{{.*}}'struct B'
+  const A& r = x;
+}
+
+// CHECK: example3
+void example3() {
+  // CHECK: double const &rcd2 =
+  // CHECK: ImplicitCastExpr{{.*}}<IntegralToFloating>
+  const double& rcd2 = 2; 
+}
diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-var.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-var.cpp
new file mode 100644
index 0000000..6a039b9
--- /dev/null
+++ b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-var.cpp
@@ -0,0 +1,135 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct Base { }; // expected-note{{candidate is the implicit copy constructor}}
+struct Derived : Base { }; // expected-note{{candidate constructor (the implicit copy constructor) not viable}}
+struct Unrelated { };
+struct Derived2 : Base { };
+struct Diamond : Derived, Derived2 { };
+
+struct ConvertibleToBaseRef {
+  operator Base&() const;
+};
+
+struct ConvertibleToDerivedRef {
+  operator Derived&() const;
+};
+
+struct ConvertibleToBothDerivedRef {
+  operator Derived&(); // expected-note{{candidate function}}
+  operator Derived2&(); // expected-note{{candidate function}}
+};
+
+struct ConvertibleToIntRef {
+  operator int&();
+};
+
+struct ConvertibleToBase {
+  operator Base() const;
+};
+
+struct ConvertibleToDerived {
+  operator Derived() const;
+};
+
+struct ConvertibleToBothDerived {
+  operator Derived(); // expected-note{{candidate function}}
+  operator Derived2(); // expected-note{{candidate function}}
+};
+
+struct ConvertibleToInt {
+  operator int();
+};
+
+template<typename T> T create();
+
+// First bullet: lvalue references binding to lvalues (the simple cases).
+void bind_lvalue_to_lvalue(Base b, Derived d, 
+                           const Base bc, const Derived dc,
+                           Diamond diamond,
+                           int i) {
+  // Reference-compatible
+  Base &br1 = b;
+  Base &br2 = d;
+  Derived &dr1 = d;
+  Derived &dr2 = b; // expected-error{{non-const lvalue reference to type 'Derived' cannot bind to a value of unrelated type 'Base'}}
+  Base &br3 = bc; // expected-error{{drops qualifiers}}
+  Base &br4 = dc; // expected-error{{drops qualifiers}}
+  Base &br5 = diamond; // expected-error{{ambiguous conversion from derived class 'Diamond' to base class 'Base':}}
+  int &ir = i;
+  long &lr = i; // expected-error{{non-const lvalue reference to type 'long' cannot bind to a value of unrelated type 'int'}}
+}
+
+void bind_lvalue_quals(volatile Base b, volatile Derived d,
+                       volatile const Base bvc, volatile const Derived dvc,
+                       volatile const int ivc) {
+  volatile Base &bvr1 = b;
+  volatile Base &bvr2 = d;
+  volatile Base &bvr3 = bvc; // expected-error{{binding of reference to type 'Base volatile' to a value of type 'Base const volatile' drops qualifiers}}
+  volatile Base &bvr4 = dvc; // expected-error{{binding of reference to type 'Base volatile' to a value of type 'Derived const volatile' drops qualifiers}}
+  
+  volatile int &ir = ivc; // expected-error{{binding of reference to type 'int volatile' to a value of type 'int const volatile' drops qualifiers}}
+
+  const volatile Base &bcvr1 = b;
+  const volatile Base &bcvr2 = d;
+}
+
+void bind_lvalue_to_rvalue() {
+  Base &br1 = Base(); // expected-error{{non-const lvalue reference to type 'Base' cannot bind to a temporary of type 'Base'}}
+  Base &br2 = Derived(); // expected-error{{non-const lvalue reference to type 'Base' cannot bind to a temporary of type 'Derived'}}
+  const volatile Base &br3 = Base(); // expected-error{{volatile lvalue reference to type 'Base const volatile' cannot bind to a temporary of type 'Base'}}
+  const volatile Base &br4 = Derived(); // expected-error{{volatile lvalue reference to type 'Base const volatile' cannot bind to a temporary of type 'Derived'}}
+
+  int &ir = 17; // expected-error{{non-const lvalue reference to type 'int' cannot bind to a temporary of type 'int'}}
+}
+
+void bind_lvalue_to_unrelated(Unrelated ur) {
+  Base &br1 = ur; // expected-error{{non-const lvalue reference to type 'Base' cannot bind to a value of unrelated type 'Unrelated'}}
+  const volatile Base &br2 = ur; // expected-error{{volatile lvalue reference to type 'Base const volatile' cannot bind to a value of unrelated type 'Unrelated'}}
+}
+
+void bind_lvalue_to_conv_lvalue() {
+  // Not reference-related, but convertible
+  Base &nbr1 = ConvertibleToBaseRef();
+  Base &nbr2 = ConvertibleToDerivedRef();
+  Derived &ndr1 = ConvertibleToDerivedRef();
+  int &ir = ConvertibleToIntRef();
+}
+
+void bind_lvalue_to_conv_lvalue_ambig(ConvertibleToBothDerivedRef both) {
+  Derived &dr1 = both;
+  Base &br1 = both; // expected-error{{reference initialization of type 'Base &' with initializer of type 'ConvertibleToBothDerivedRef' is ambiguous}}
+}
+
+struct IntBitfield {
+  int i : 17; // expected-note{{bit-field is declared here}}
+};
+
+void test_bitfield(IntBitfield ib) {
+  int & ir1 = (ib.i); // expected-error{{non-const reference cannot bind to bit-field 'i'}}
+}
+
+// Second bullet: const lvalue reference binding to an rvalue with
+// similar type (both of which are class types).
+void bind_const_lvalue_to_rvalue() {
+  const Base &br1 = create<Base>();
+  const Base &br2 = create<Derived>();
+  const Derived &dr1 = create<Base>(); // expected-error{{no viable conversion}}
+
+  const Base &br3 = create<const Base>();
+  const Base &br4 = create<const Derived>();
+
+  const Base &br5 = create<const volatile Base>(); // expected-error{{binding of reference to type 'Base const' to a value of type 'Base const volatile' drops qualifiers}}
+  const Base &br6 = create<const volatile Derived>(); // expected-error{{binding of reference to type 'Base const' to a value of type 'Derived const volatile' drops qualifiers}}
+
+  const int &ir = create<int>();
+}
+
+// Second bullet: const lvalue reference binds to the result of a conversion.
+void bind_const_lvalue_to_class_conv_temporary() {
+  const Base &br1 = ConvertibleToBase();
+  const Base &br2 = ConvertibleToDerived();
+}
+void bind_lvalue_to_conv_rvalue_ambig(ConvertibleToBothDerived both) {
+  const Derived &dr1 = both;
+  const Base &br1 = both; // expected-error{{reference initialization of type 'Base const &' with initializer of type 'ConvertibleToBothDerived' is ambiguous}}
+}
diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5.cpp
new file mode 100644
index 0000000..51d61a5
--- /dev/null
+++ b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5.cpp
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace PR5909 {
+  struct Foo {
+    int x : 20;
+  };
+  
+  bool Test(const int& foo);
+  
+  const Foo f = { 0 };  // It compiles without the 'const'.
+  bool z = Test(f.x);
+}
+
+namespace PR6264 {
+  typedef int (&T)[3];
+  struct S
+  {
+    operator T ();
+  };
+  void f()
+  {
+    T bar = S();
+  }
+}
+
+namespace PR6066 {
+  struct B { };
+  struct A : B {
+    operator B*();
+    operator B&(); // expected-warning{{conversion function converting 'PR6066::A' to its base class 'PR6066::B' will never be used}}
+  };
+
+  void f(B&); // no rvalues accepted
+  void f(B*);
+
+  int g() {
+    f(A()); // calls f(B*)
+    return 0;
+  }
+}
diff --git a/test/CXX/dcl.decl/dcl.init/p6.cpp b/test/CXX/dcl.decl/dcl.init/p6.cpp
new file mode 100644
index 0000000..c542dac
--- /dev/null
+++ b/test/CXX/dcl.decl/dcl.init/p6.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// FIXME: Very incomplete!
+
+// If a program calls for the default initialization of an object of a
+// const-qualified type T, T shall be a class type with a
+// user-provided default constructor.
+struct MakeNonPOD { MakeNonPOD(); };
+struct NoUserDefault : public MakeNonPOD { };
+struct HasUserDefault { HasUserDefault(); };
+
+void test_const_default_init() {
+  const NoUserDefault x1; // expected-error{{default initialization of an object of const type 'NoUserDefault const' requires a user-provided default constructor}}
+  const HasUserDefault x2;
+  const int x3; // expected-error{{default initialization of an object of const type 'int const'}}
+}
diff --git a/test/CXX/dcl.decl/dcl.meaning/dcl.array/p1-cxx0x.cpp b/test/CXX/dcl.decl/dcl.meaning/dcl.array/p1-cxx0x.cpp
new file mode 100644
index 0000000..00e59e0
--- /dev/null
+++ b/test/CXX/dcl.decl/dcl.meaning/dcl.array/p1-cxx0x.cpp
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
+
+void f() {
+  int b[5];
+  auto a[5] = b; // expected-error{{'a' declared as array of 'auto'}}
+}
diff --git a/test/CXX/dcl.decl/dcl.meaning/dcl.array/p1.cpp b/test/CXX/dcl.decl/dcl.meaning/dcl.array/p1.cpp
new file mode 100644
index 0000000..ac0ec85
--- /dev/null
+++ b/test/CXX/dcl.decl/dcl.meaning/dcl.array/p1.cpp
@@ -0,0 +1,44 @@
+// RUN: %clang_cc1 -fsyntax-only -pedantic -verify %s
+
+// Simple form
+int ar1[10];
+
+// Element type cannot be:
+// - (cv) void
+volatile void ar2[10]; // expected-error {{incomplete element type 'void volatile'}}
+// - a reference
+int& ar3[10]; // expected-error {{array of references}}
+// - a function type
+typedef void Fn();
+Fn ar4[10]; // expected-error {{array of functions}}
+// - an abstract class
+struct Abstract { virtual void fn() = 0; }; // expected-note {{pure virtual}}
+Abstract ar5[10]; // expected-error {{abstract class}}
+
+// If we have a size, it must be greater than zero.
+int ar6[-1]; // expected-error {{array size is negative}}
+int ar7[0u]; // expected-warning {{zero size arrays are an extension}}
+
+// An array with unknown bound is incomplete.
+int ar8[]; // expected-error {{needs an explicit size or an initializer}}
+// So is an array with an incomplete element type.
+struct Incomplete; // expected-note {{forward declaration}}
+Incomplete ar9[10]; // expected-error {{incomplete type}}
+// Neither of which should be a problem in situations where no complete type
+// is required. (PR5048)
+void fun(int p1[], Incomplete p2[10]);
+extern int ear1[];
+extern Incomplete ear2[10];
+
+// cv migrates to element type
+typedef const int cint;
+extern cint car1[10];
+typedef int intar[10];
+// thus this is a valid redeclaration
+extern const intar car1;
+
+// Check that instantiation works properly when the element type is a template.
+template <typename T> struct S {
+  typename T::type x; // expected-error {{has no members}}
+};
+S<int> ar10[10]; // expected-note {{requested here}}
diff --git a/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p10.cpp b/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p10.cpp
new file mode 100644
index 0000000..9d26561
--- /dev/null
+++ b/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p10.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct A { 
+  virtual void f(int a = 7);
+}; 
+
+struct B : public A {
+  void f(int a);
+}; 
+
+void m() {
+  B* pb = new B; 
+  A* pa = pb; 
+  pa->f(); // OK, calls pa->B::f(7) 
+  pb->f(); // expected-error{{too few arguments}}
+}
diff --git a/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p2.cpp b/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p2.cpp
new file mode 100644
index 0000000..0a107eb
--- /dev/null
+++ b/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p2.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+void point(int = 3, int = 4);
+
+void test_point() {
+  point(1,2); 
+  point(1); 
+  point();
+}
diff --git a/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p3.cpp b/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p3.cpp
new file mode 100644
index 0000000..e9c5e0c
--- /dev/null
+++ b/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p3.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+void nondecl(int (*f)(int x = 5)) // {expected-error {{default arguments can only be specified}}}
+{
+  void (*f2)(int = 17)  // {expected-error {{default arguments can only be specified}}}
+  = (void (*)(int = 42))f; // {expected-error {{default arguments can only be specified}}}
+}
+
+struct X0 {
+  int (*f)(int = 17); // expected-error{{default arguments can only be specified for parameters in a function declaration}}
+  
+  void mem8(int (*fp)(int) = (int (*)(int = 17))0); // expected-error{{default arguments can only be specified for parameters in a function declaration}}  
+};
diff --git a/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p4.cpp b/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p4.cpp
new file mode 100644
index 0000000..b2129b2
--- /dev/null
+++ b/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p4.cpp
@@ -0,0 +1,55 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+void f0(int i, int j, int k = 3);
+void f0(int i, int j, int k);
+void f0(int i, int j = 2, int k);
+void f0(int i, int j, int k);
+void f0(int i = 1, // expected-note{{previous definition}}
+        int j, int k);
+void f0(int i, int j, int k);
+
+namespace N0 {
+  void f0(int, int, int); // expected-note{{candidate}}
+
+  void test_f0_inner_scope() {
+    f0(); // expected-error{{no matching}}
+  }
+}
+
+void test_f0_outer_scope() {
+  f0(); // okay
+}
+
+void f0(int i = 1, // expected-error{{redefinition of default argument}}
+        int, int); 
+
+template<typename T> void f1(T); // expected-note{{previous}}
+
+template<typename T>
+void f1(T = T()); // expected-error{{cannot be added}}
+
+
+namespace N1 {
+  // example from C++03 standard
+  // FIXME: make these "f2"s into "f"s, then fix our scoping issues
+  void f2(int, int); 
+  void f2(int, int = 7); 
+  void h() {
+    f2(3); // OK, calls f(3, 7) 
+    void f(int = 1, int);	// expected-error{{missing default argument}}
+  }
+  
+  void m()
+  {
+    void f(int, int);
+    f(4);  // expected-error{{too few arguments to function call}}
+    void f(int, int = 5); // expected-note{{previous definition}}
+    f(4); // okay
+    void f(int, int = 5); // expected-error{{redefinition of default argument}}
+  }
+  
+  void n()
+  {
+    f2(6); // okay
+  }
+}
diff --git a/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p5.cpp b/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p5.cpp
new file mode 100644
index 0000000..3100e56
--- /dev/null
+++ b/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p5.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+float global_f;
+
+void f0(int *ip = &global_f); // expected-error{{cannot initialize}} \
+// expected-note{{passing argument to parameter 'ip' here}}
+
+// Example from C++03 standard
+int a = 1; 
+int f(int); 
+int g(int x = f(a));
+
+void h() { 
+  a = 2;
+  {
+    int *a = 0;
+    g(); // FIXME: check that a is called with a value of 2
+  }
+}
diff --git a/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p6.cpp b/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p6.cpp
new file mode 100644
index 0000000..9ab0b48
--- /dev/null
+++ b/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p6.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+class C { 
+public:
+  void f(int i = 3); // expected-note{{here}}
+  void g(int i, int j = 99);
+};
+
+void C::f(int i = 3) { } // expected-error{{redefinition of default argument}}
+
+void C::g(int i = 88, int j) { }
+
+void test_C(C c) {
+  c.f();
+  c.g();
+}
+
+template<typename T>
+struct X0 {
+  void f(int);
+  
+  struct Inner {
+    void g(int);
+  };
+};
+
+// DR217
+template<typename T>
+void X0<T>::f(int = 17) { } // expected-error{{cannot be added}}
+
+// DR217 + DR205 (reading tea leaves)
+template<typename T>
+void X0<T>::Inner::g(int = 17) { } // expected-error{{cannot be added}}
diff --git a/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p7.cpp b/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p7.cpp
new file mode 100644
index 0000000..164eb36
--- /dev/null
+++ b/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p7.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+void h()
+{
+  int i;
+  extern void h2(int x = sizeof(i)); // expected-error {{default argument references local variable 'i' of enclosing function}}
+}
diff --git a/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p8.cpp b/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p8.cpp
new file mode 100644
index 0000000..1a08ab7
--- /dev/null
+++ b/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p8.cpp
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+class A { 
+  void f(A* p = this) { }	// expected-error{{invalid use of 'this'}}
+};
diff --git a/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p3.cpp b/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p3.cpp
new file mode 100644
index 0000000..ad827fb
--- /dev/null
+++ b/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p3.cpp
@@ -0,0 +1,3 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s 
+void f(int) { } // expected-note {{previous definition is here}}
+void f(const int) { } // expected-error {{redefinition of 'f'}}
diff --git a/test/CXX/dcl.decl/dcl.meaning/dcl.mptr/p3.cpp b/test/CXX/dcl.decl/dcl.meaning/dcl.mptr/p3.cpp
new file mode 100644
index 0000000..7e35788
--- /dev/null
+++ b/test/CXX/dcl.decl/dcl.meaning/dcl.mptr/p3.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+class A { 
+public:
+  int& i; 
+
+  A(int& i) : i(i) { }
+  
+  static int s;
+}; 
+
+template<typename T> void ft(T& t) {
+  t.*&T::i = 10; // expected-error{{cannot form a pointer-to-member to member 'i' of reference type 'int &'}}
+}
+
+void f() {
+  int b;
+  A a(b); 
+  
+  int A::*ip = &A::s; // expected-error {{cannot initialize a variable of type 'int A::*' with an rvalue of type 'int *'}}
+  a.*&A::s = 10; // expected-error{{right hand operand to .* has non pointer-to-member type 'int *'}}
+  
+  a.*&A::i = 10; // expected-error{{cannot form a pointer-to-member to member 'i' of reference type 'int &'}}
+  ft(a); // expected-note{{in instantiation of function template specialization 'ft<A>' requested here}}
+  
+  void A::*p = 0; // expected-error{{'p' declared as a member pointer to void}}
+}
diff --git a/test/CXX/dcl.decl/dcl.meaning/dcl.ref/p5.cpp b/test/CXX/dcl.decl/dcl.meaning/dcl.ref/p5.cpp
new file mode 100644
index 0000000..aaf7451
--- /dev/null
+++ b/test/CXX/dcl.decl/dcl.meaning/dcl.ref/p5.cpp
@@ -0,0 +1,145 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// C++ [dcl.ref]p5:
+//   There shall be no references to references, no arrays of
+//   references, and no pointers to references.
+
+// The crazy formatting in here is to enforce the exact report locations.
+
+typedef int &intref;
+typedef intref &intrefref;
+
+template <class T> class RefMem { // expected-warning{{class 'RefMem<int &>' does not declare any constructor to initialize its non-modifiable members}}
+  T
+    &
+      member; // expected-note{{ reference member 'member' will never be initialized}}
+};
+
+struct RefRef {
+  int
+      &
+        &             // expected-error {{declared as a reference to a reference}}
+          refref0;
+
+  intref
+         &
+           refref1; // collapses
+
+  intrefref
+            &
+              refref2; // collapses
+
+  RefMem
+        <
+         int
+            &
+             >
+               refref3; // collapses expected-note{{in instantiation of template class 'RefMem<int &>' requested here}}
+};
+
+
+template <class T> class PtrMem {
+  T
+    *                   // expected-error {{declared as a pointer to a reference}}
+      member;
+};
+
+struct RefPtr {
+  typedef
+          int
+              &
+                *       // expected-error {{declared as a pointer to a reference}}
+                  intrefptr;
+
+  typedef
+          intref
+                 *      // expected-error {{declared as a pointer to a reference}}
+                   intrefptr2;
+
+  int
+      &
+        *               // expected-error {{declared as a pointer to a reference}}
+          refptr0;
+
+  intref
+         *              // expected-error {{declared as a pointer to a reference}}
+           refptr1;
+
+  PtrMem
+        <
+         int
+            &
+             >
+               refptr2; // expected-note {{in instantiation}}
+};
+
+template <class T> class ArrMem {
+  T
+    member
+           [ // expected-error {{declared as array of references}}
+            10
+              ];
+};
+template <class T, unsigned N> class DepArrMem {
+  T
+    member
+           [ // expected-error {{declared as array of references}}
+            N
+             ];
+};
+
+struct RefArr {
+  typedef 
+          int
+              &
+                intrefarr
+                         [ // expected-error {{declared as array of references}}
+                          2
+                           ];
+
+  typedef
+          intref
+                 intrefarr
+                          [ // expected-error {{declared as array of references}}
+                           2
+                            ];
+
+  int
+      &
+        refarr0
+               [ // expected-error {{declared as array of references}}
+                2
+                 ];
+  intref
+         refarr1
+                [ // expected-error {{declared as array of references}}
+                 2
+                  ];
+  ArrMem
+        <
+         int
+            &
+             >
+               refarr2; // expected-note {{in instantiation}}
+  DepArrMem
+           <
+            int
+               &,
+                  10
+                    >
+                      refarr3; // expected-note {{in instantiation}}
+};
+
+
+//   The declaration of a reference shall contain an initializer
+//   (8.5.3) except when the declaration contains an explicit extern
+//   specifier (7.1.1), is a class member (9.2) declaration within a
+//   class definition, or is the declaration of a parameter or a
+//   return type (8.3.5); see 3.1. A reference shall be initialized to
+//   refer to a valid object or function. [ Note: in particular, a
+//   null reference cannot exist in a well-defined program, because
+//   the only way to create such a reference would be to bind it to
+//   the "object" obtained by dereferencing a null pointer, which
+//   causes undefined behavior. As described in 9.6, a reference
+//   cannot be bound directly to a bit-field.
+
diff --git a/test/CXX/dcl.decl/dcl.name/p1.cpp b/test/CXX/dcl.decl/dcl.name/p1.cpp
new file mode 100644
index 0000000..7586007
--- /dev/null
+++ b/test/CXX/dcl.decl/dcl.name/p1.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace pr6200 {
+  struct v {};
+  struct s {
+    int i;
+    operator struct v() { return v(); };
+  };
+
+  void f()
+  {
+    // Neither of these is a declaration.
+    (void)new struct s;
+    (void)&s::operator struct v;
+  }
+}
diff --git a/test/CXX/except/except.handle/p16.cpp b/test/CXX/except/except.handle/p16.cpp
new file mode 100644
index 0000000..4950a2f
--- /dev/null
+++ b/test/CXX/except/except.handle/p16.cpp
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// The object declared in an exception-declaration or, if the
+// exception-declaration does not specify a name, a temporary (12.2)
+// is copy-initialized (8.5) from the exception object.
+//
+template<typename T>
+class X {
+  T* ptr;
+
+public:
+  X(const X<T> &) {
+    int *ip = 0;
+    ptr = ip; // expected-error{{assigning to 'float *' from incompatible type 'int *'}}
+  }
+
+  ~X() {
+    float *fp = 0;
+    ptr = fp; // expected-error{{assigning to 'int *' from incompatible type 'float *'}}
+  }
+};
+
+void f() {
+  try {
+  } catch (X<float>) { // expected-note{{instantiation}}
+    // copy constructor
+  } catch (X<int> xi) { // expected-note{{instantiation}}
+    // destructor
+  }
+}
+
+struct Abstract {
+  virtual void f() = 0; // expected-note{{pure virtual}}
+};
+
+void g() {
+  try {
+  } catch (Abstract) { // expected-error{{variable type 'Abstract' is an abstract class}}
+  }
+}
diff --git a/test/CXX/expr/expr.unary/expr.delete/p5.cpp b/test/CXX/expr/expr.unary/expr.delete/p5.cpp
new file mode 100644
index 0000000..2fa30e5
--- /dev/null
+++ b/test/CXX/expr/expr.unary/expr.delete/p5.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -verify %s
+
+// If the object being deleted has incomplete class type at the point of
+// deletion and the complete class has a non-trivial destructor or a
+// deallocation function, the behavior is undefined.
+
+// The trivial case.
+class T0; // expected-note {{forward declaration}}
+void f0(T0 *a) { delete a; } // expected-warning {{deleting pointer to incomplete type}}
+class T0 { ~T0(); };
+
+// The trivial case, inside a template instantiation.
+template<typename T>
+struct T1_A { T *x; ~T1_A() { delete x; } }; // expected-warning {{deleting pointer to incomplete type}}
+class T1_B; // expected-note {{forward declaration}}
+void f0() { T1_A<T1_B> x; } // expected-note {{in instantiation of member function}}
+
+// This case depends on when we check T2_C::f0.
+class T2_A;
+template<typename T>
+struct T2_B { void f0(T *a) { delete a; } };
+struct T2_C { T2_B<T2_A> x; void f0(T2_A *a) { x.f0(a); } };
+void f0(T2_A *a) { T2_C x; x.f0(a); }
+class T2_A { };
+
+// An alternate version of the same.
+//
+// FIXME: Revisit this case when we have access control.
+class T3_A;
+template<typename T>
+struct T3_B { void f0(T *a) { delete a; } };
+struct T3_C { T3_B<T3_A> x; void f0(T3_A *a) { x.f0(a); } };
+void f0(T3_A *a) { T3_C x; x.f0(a); }
+class T3_A { private: ~T3_A(); };
diff --git a/test/CXX/expr/expr.unary/expr.new/p19.cpp b/test/CXX/expr/expr.unary/expr.new/p19.cpp
new file mode 100644
index 0000000..bb69fd5
--- /dev/null
+++ b/test/CXX/expr/expr.unary/expr.new/p19.cpp
@@ -0,0 +1,46 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -fexceptions %s
+typedef __SIZE_TYPE__ size_t;
+
+// Operator delete template for placement new with global lookup
+template<int I>
+struct X0 {
+  X0();
+
+  static void* operator new(size_t) {
+    return I; // expected-error{{cannot initialize}}
+  }
+
+  static void operator delete(void*) {
+    int *ip = I; // expected-error{{cannot initialize}}
+  }
+};
+
+void test_X0() {
+  // Using the global operator new suppresses the search for a
+  // operator delete in the class.
+  ::new X0<2>;
+
+  new X0<3>; // expected-note 2{{instantiation}}
+}
+
+// Operator delete template for placement new[] with global lookup
+template<int I>
+struct X1 {
+  X1();
+
+  static void* operator new[](size_t) {
+    return I; // expected-error{{cannot initialize}}
+  }
+
+  static void operator delete[](void*) {
+    int *ip = I; // expected-error{{cannot initialize}}
+  }
+};
+
+void test_X1() {
+  // Using the global operator new suppresses the search for a
+  // operator delete in the class.
+  ::new X1<2> [17];
+
+  new X1<3> [17]; // expected-note 2{{instantiation}}
+}
diff --git a/test/CXX/expr/expr.unary/expr.new/p20-0x.cpp b/test/CXX/expr/expr.unary/expr.new/p20-0x.cpp
new file mode 100644
index 0000000..4c924b1
--- /dev/null
+++ b/test/CXX/expr/expr.unary/expr.new/p20-0x.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x -fexceptions %s
+typedef __SIZE_TYPE__ size_t;
+
+struct S {
+  // Placement allocation function:
+  static void* operator new(size_t, size_t);
+  // Usual (non-placement) deallocation function:
+  static void operator delete(void*, size_t); // expected-note{{declared here}}
+};
+
+void testS() {
+  S* p = new (0) S;	// expected-error{{'new' expression with placement arguments refers to non-placement 'operator delete'}}
+}
diff --git a/test/CXX/expr/expr.unary/expr.new/p20.cpp b/test/CXX/expr/expr.unary/expr.new/p20.cpp
new file mode 100644
index 0000000..8cbe2b9
--- /dev/null
+++ b/test/CXX/expr/expr.unary/expr.new/p20.cpp
@@ -0,0 +1,141 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -fexceptions %s
+typedef __SIZE_TYPE__ size_t;
+
+// Overloaded operator delete with two arguments
+template<int I>
+struct X0 {
+  X0();
+  static void* operator new(size_t);
+  static void operator delete(void*, size_t) {
+    int *ip = I; // expected-error{{cannot initialize}}
+  }
+};
+
+void test_X0() {
+  new X0<1>; // expected-note{{instantiation}}
+}
+
+// Overloaded operator delete with one argument
+template<int I>
+struct X1 {
+  X1();
+
+  static void* operator new(size_t);
+  static void operator delete(void*) {
+    int *ip = I; // expected-error{{cannot initialize}}
+  }
+};
+
+void test_X1() {
+  new X1<1>; // expected-note{{instantiation}}
+}
+
+// Overloaded operator delete for placement new
+template<int I>
+struct X2 {
+  X2();
+
+  static void* operator new(size_t, double, double);
+  static void* operator new(size_t, int, int);
+
+  static void operator delete(void*, const int, int) {
+    int *ip = I; // expected-error{{cannot initialize}}
+  }
+
+  static void operator delete(void*, double, double);
+};
+
+void test_X2() {
+  new (0, 0) X2<1>; // expected-note{{instantiation}}
+}
+
+// Operator delete template for placement new
+struct X3 {
+  X3();
+
+  static void* operator new(size_t, double, double);
+
+  template<typename T>
+  static void operator delete(void*, T x, T) {
+    double *dp = &x;
+    int *ip = &x; // expected-error{{cannot initialize}}
+  }
+};
+
+void test_X3() {
+  new (0, 0) X3; // expected-note{{instantiation}}
+}
+
+// Operator delete template for placement new in global scope.
+struct X4 {
+  X4();
+  static void* operator new(size_t, double, double);
+};
+
+template<typename T>
+void operator delete(void*, T x, T) {
+  double *dp = &x;
+  int *ip = &x; // expected-error{{cannot initialize}}
+}
+
+void test_X4() {
+  new (0, 0) X4; // expected-note{{instantiation}}
+}
+
+// Useless operator delete hides global operator delete template.
+struct X5 {
+  X5();
+  static void* operator new(size_t, double, double);
+  void operator delete(void*, double*, double*);
+};
+
+void test_X5() {
+  new (0, 0) X5; // okay, we found X5::operator delete but didn't pick it
+}
+
+// Operator delete template for placement new
+template<int I>
+struct X6 {
+  X6();
+
+  static void* operator new(size_t) {
+    return I; // expected-error{{cannot initialize}}
+  }
+
+  static void operator delete(void*) {
+    int *ip = I; // expected-error{{cannot initialize}}
+  }
+};
+
+void test_X6() {
+  new X6<3>; // expected-note 2{{instantiation}}
+}
+
+void *operator new(size_t, double, double, double);
+
+template<typename T>
+void operator delete(void*, T x, T, T) {
+  double *dp = &x;
+  int *ip = &x; // expected-error{{cannot initialize}}
+}
+void test_int_new() {
+  new (1.0, 1.0, 1.0) int; // expected-note{{instantiation}}
+}
+
+// We don't need an operator delete if the type has a trivial
+// constructor, since we know that constructor cannot throw.
+// FIXME: Is this within the standard? Seems fishy, but both EDG+GCC do it.
+#if 0
+template<int I>
+struct X7 {
+  static void* operator new(size_t);
+  static void operator delete(void*, size_t) {
+    int *ip = I; // okay, since it isn't instantiated.
+  }
+};
+
+void test_X7() {
+  new X7<1>;
+}
+#endif
+
diff --git a/test/CXX/expr/p3.cpp b/test/CXX/expr/p3.cpp
new file mode 100644
index 0000000..6b243c2
--- /dev/null
+++ b/test/CXX/expr/p3.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+double operator +(double, double); // expected-error{{overloaded 'operator+' must have at least one parameter of class or enumeration type}}
+
+struct A
+{
+  operator int();
+};
+
+int main()
+{
+  A a, b;
+  int i0 = a + 1;
+  int i1 = a + b;
+}
diff --git a/test/CXX/expr/p8.cpp b/test/CXX/expr/p8.cpp
new file mode 100644
index 0000000..2f6c094
--- /dev/null
+++ b/test/CXX/expr/p8.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+int a0;
+const volatile int a1 = 2;
+int a2[16];
+int a3();
+
+void f0(int);
+void f1(int *);
+void f2(int (*)());
+
+int main()
+{
+  f0(a0);
+  f0(a1);
+  f1(a2);
+  f2(a3);
+}
diff --git a/test/CXX/expr/p9.cpp b/test/CXX/expr/p9.cpp
new file mode 100644
index 0000000..803b0cc
--- /dev/null
+++ b/test/CXX/expr/p9.cpp
@@ -0,0 +1,50 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// floating-point overloads
+
+__typeof__(0 + 0.0L) ld0;
+long double &ldr = ld0;
+
+__typeof__(0 + 0.0) d0;
+double &dr = d0;
+
+__typeof__(0 + 0.0f) f0;
+float &fr = f0;
+
+// integral promotions
+
+signed char c0;
+__typeof__(c0 + c0) c1;
+int &cr = c1;
+
+unsigned char uc0;
+__typeof__(uc0 + uc0) uc1;
+int &ucr = uc1;
+
+short s0;
+__typeof__(s0 + s0) s1;
+int &sr = s1;
+
+unsigned short us0;
+__typeof__(us0 + us0) us1;
+int &usr = us1;
+
+// integral overloads
+
+__typeof__(0 + 0UL) ul0;
+unsigned long &ulr = ul0;
+
+template<bool T> struct selector;
+template<> struct selector<true> { typedef long type; };
+template<> struct selector<false> {typedef unsigned long type; };
+__typeof__(0U + 0L) ui_l0;
+selector<(sizeof(long) > sizeof(unsigned int))>::type &ui_lr = ui_l0;
+
+__typeof__(0 + 0L) l0;
+long &lr = l0;
+
+__typeof__(0 + 0U) u0;
+unsigned &ur = u0;
+
+__typeof__(0 + 0) i0;
+int &ir = i0;
diff --git a/test/CXX/lex/lex.literal/lex.ccon/p1.cpp b/test/CXX/lex/lex.literal/lex.ccon/p1.cpp
new file mode 100644
index 0000000..7b65f7e
--- /dev/null
+++ b/test/CXX/lex/lex.literal/lex.ccon/p1.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// Check types of char literals
+extern char a;
+extern __typeof('a') a;
+extern int b;
+extern __typeof('asdf') b;
+extern wchar_t c;
+extern __typeof(L'a') c;
diff --git a/test/CXX/lex/lex.trigraph/p1.cpp b/test/CXX/lex/lex.trigraph/p1.cpp
new file mode 100644
index 0000000..aacbc55
--- /dev/null
+++ b/test/CXX/lex/lex.trigraph/p1.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -fsyntax-only -trigraphs -Wtrigraphs -verify %s
+
+??=pragma // expected-warning {{trigraph converted to '#' character}}
+
+int a = '??/0'; // expected-warning {{trigraph converted to '\' character}}
+
+int b = 1 ??' 0; // expected-warning {{trigraph converted to '^' character}}
+
+int c ??(1]; // expected-warning {{trigraph converted to '[' character}}
+
+int d [1??); // expected-warning {{trigraph converted to ']' character}}
+
+int e = 1 ??! 0; // expected-warning {{trigraph converted to '|' character}}
+
+void f() ??<} // expected-warning {{trigraph converted to '{' character}}
+
+void g() {??> // expected-warning {{trigraph converted to '}' character}}
+
+int h = ??- 0; // expected-warning {{trigraph converted to '~' character}}
diff --git a/test/CXX/lex/lex.trigraph/p2.cpp b/test/CXX/lex/lex.trigraph/p2.cpp
new file mode 100644
index 0000000..7d11d5b
--- /dev/null
+++ b/test/CXX/lex/lex.trigraph/p2.cpp
@@ -0,0 +1,3 @@
+// RUN: %clang_cc1 -fsyntax-only -trigraphs -Wtrigraphs -verify %s
+
+??=define arraycheck(a,b) a??(b??) ??!??! b??(a??) // expected-warning {{trigraph converted to '#' character}} expected-warning {{trigraph converted to '[' character}} expected-warning {{trigraph converted to ']' character}} expected-warning {{trigraph converted to '|' character}} expected-warning {{trigraph converted to '|' character}} expected-warning {{trigraph converted to '[' character}} expected-warning {{trigraph converted to ']' character}}
diff --git a/test/CXX/lex/lex.trigraph/p3.cpp b/test/CXX/lex/lex.trigraph/p3.cpp
new file mode 100644
index 0000000..2be0328
--- /dev/null
+++ b/test/CXX/lex/lex.trigraph/p3.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only -trigraphs -Wtrigraphs -verify %s
+
+char a[] =
+"?? ??\"??#??$??%??&??*??+??,??.??0??1??2??3??4??5??6"
+"??7??8??9??:??;?????@??A??B??C??D??E??F??G??H??I??J"
+"??K??L??M??N??O??P??Q??R??S??T??U??V??W??X??Y??Z??["
+"??\\??]??^??_??`??a??b??c??d??e??f??g??h??i??j??k??l"
+"??m??n??o??p??q??r??s??t??u??v??w??x??y??z??{??|??}??~";
diff --git a/test/CXX/over/over.match/over.match.best/over.best.ics/over.ics.user/p3-0x.cpp b/test/CXX/over/over.match/over.match.best/over.best.ics/over.ics.user/p3-0x.cpp
new file mode 100644
index 0000000..d9e0ff8
--- /dev/null
+++ b/test/CXX/over/over.match/over.match.best/over.best.ics/over.ics.user/p3-0x.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++0x -verify %s
+
+namespace PR6285 {
+  template<typename T> struct identity 
+  { typedef T type; };
+
+  struct D { 
+    template<typename T = short> 
+    operator typename identity<T>::type(); // expected-note{{candidate}}
+  }; 
+
+  int f() { return D(); } // expected-error{{no viable conversion}}
+}
+
diff --git a/test/CXX/over/over.match/over.match.best/p1.cpp b/test/CXX/over/over.match/over.match.best/p1.cpp
new file mode 100644
index 0000000..5c315a7
--- /dev/null
+++ b/test/CXX/over/over.match/over.match.best/p1.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T> int &f0(T*, int);
+float &f0(void*, int);
+
+void test_f0(int* ip, void *vp) {
+  // One argument is better...
+  int &ir = f0(ip, 0);
+  
+  // Prefer non-templates to templates
+  float &fr = f0(vp, 0);
+}
+
+// Partial ordering of function template specializations will be tested 
+// elsewhere
+// FIXME: Initialization by user-defined conversion is tested elsewhere
diff --git a/test/CXX/over/over.over/p1.cpp b/test/CXX/over/over.over/p1.cpp
new file mode 100644
index 0000000..10c60da
--- /dev/null
+++ b/test/CXX/over/over.over/p1.cpp
@@ -0,0 +1,94 @@
+// RUN: %clang_cc1 -fsyntax-only %s
+
+template<typename T> T f0(T);
+int f0(int);
+
+// -- an object or reference being initialized 
+struct S {
+  int (*f0)(int);
+  float (*f1)(float);
+};
+
+void test_init_f0() {
+  int (*f0a)(int) = f0;
+  int (*f0b)(int) = &f0;
+  int (*f0c)(int) = (f0);
+  float (*f0d)(float) = f0;
+  float (*f0e)(float) = &f0;
+  float (*f0f)(float) = (f0);
+  int (&f0g)(int) = f0;
+  int (&f0h)(int) = (f0);
+  float (&f0i)(float) = f0;
+  float (&f0j)(float) = (f0);
+  S s = { f0, f0 };
+}
+
+// -- the left side of an assignment (5.17),
+void test_assign_f0() {
+  int (*f0a)(int) = 0;
+  float (*f0b)(float) = 0;
+  
+  f0a = f0;
+  f0a = &f0;
+  f0a = (f0);
+  f0b = f0;
+  f0b = &f0;
+  f0b = (f0);  
+}
+
+// -- a parameter of a function (5.2.2),
+void eat_f0(int a(int), float (*b)(float), int (&c)(int), float (&d)(float));
+
+void test_pass_f0() {
+  eat_f0(f0, f0, f0, f0);
+  eat_f0(&f0, &f0, (f0), (f0));
+}
+
+// -- a parameter of a user-defined operator (13.5),
+struct X { };
+void operator+(X, int(int));
+void operator-(X, float(*)(float));
+void operator*(X, int (&)(int));
+void operator/(X, float (&)(float));
+
+void test_operator_pass_f0(X x) {
+  x + f0;
+  x + &f0;
+  x - f0;
+  x - &f0;
+  x * f0;
+  x * (f0);
+  x / f0;
+  x / (f0);
+}
+
+// -- the return value of a function, operator function, or conversion (6.6.3),
+int (*test_return_f0_a())(int) { return f0; }
+int (*test_return_f0_b())(int) { return &f0; }
+int (*test_return_f0_c())(int) { return (f0); }
+float (*test_return_f0_d())(float) { return f0; }
+float (*test_return_f0_e())(float) { return &f0; }
+float (*test_return_f0_f())(float) { return (f0); }
+
+// -- an explicit type conversion (5.2.3, 5.2.9, 5.4), or
+void test_convert_f0() {
+  (void)((int (*)(int))f0);
+  (void)((int (*)(int))&f0);
+  (void)((int (*)(int))(f0));
+  (void)((float (*)(float))f0);
+  (void)((float (*)(float))&f0);
+  (void)((float (*)(float))(f0));
+}
+
+// -- a non-type template-parameter(14.3.2).
+template<int(int)> struct Y0 { };
+template<float(float)> struct Y1 { };
+template<int (&)(int)> struct Y2 { };
+template<float (&)(float)> struct Y3 { };
+
+Y0<f0> y0;
+Y0<&f0> y0a;
+Y1<f0> y1;
+Y1<&f0> y1a;
+Y2<f0> y2;
+Y3<f0> y3;
diff --git a/test/CXX/over/over.over/p2.cpp b/test/CXX/over/over.over/p2.cpp
new file mode 100644
index 0000000..e8840d2
--- /dev/null
+++ b/test/CXX/over/over.over/p2.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T> T f0(T, T);
+
+void test_f0() {
+  int (*f0a)(int, int) = f0;
+  int (*f0b)(int, int) = &f0;
+  int (*f0c)(int, float) = f0; // expected-error{{cannot initialize}}
+  // FIXME: poor error message above!
+}
diff --git a/test/CXX/over/over.over/p4.cpp b/test/CXX/over/over.over/p4.cpp
new file mode 100644
index 0000000..4189218
--- /dev/null
+++ b/test/CXX/over/over.over/p4.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T> T f0(T);
+int f0(int); // expected-note{{candidate function}}
+
+void test_f0() {
+  int (*fp0)(int) = f0;
+  int (*fp1)(int) = &f0;
+  float (*fp2)(float) = &f0;
+}
+
+namespace N {
+  int f0(int); // expected-note{{candidate function}}
+}
+
+int f0(int);
+
+void test_f0_2() {
+  using namespace N;
+  int (*fp0)(int) = f0; // expected-error{{ambiguous}} \ 
+                        // expected-error{{cannot initialize}}
+  float (*fp1)(float) = f0;
+}
diff --git a/test/CXX/special/class.copy/p3.cpp b/test/CXX/special/class.copy/p3.cpp
new file mode 100644
index 0000000..3d87266
--- /dev/null
+++ b/test/CXX/special/class.copy/p3.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
+
+// PR6141
+template<typename T>
+struct X {
+  X();
+  template<typename U> X(X<U>);
+  X(const X<T>&);
+};
+
+void f(X<int>) { }
+
+struct Y : X<int> { };
+struct Z : X<float> { };
+
+// CHECK: define i32 @main()
+int main() {
+  // CHECK: call void @_ZN1YC1Ev
+  // CHECK: call void @_ZN1XIiEC1ERKS0_
+  // CHECK: call void @_Z1f1XIiE
+  f(Y());
+  // CHECK: call void @_ZN1ZC1Ev
+  // CHECK: call void @_ZN1XIfEC1ERKS0_
+  // CHECK: call void @_ZN1XIiEC1IfEES_IT_E
+  // CHECK: call void @_Z1f1XIiE
+  f(Z());
+}
diff --git a/test/CXX/special/class.ctor/p1.cpp b/test/CXX/special/class.ctor/p1.cpp
new file mode 100644
index 0000000..9500a7d
--- /dev/null
+++ b/test/CXX/special/class.ctor/p1.cpp
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+struct X0 {
+  struct type { };
+
+  X0();
+  X0(int);
+  (X0)(float);
+  X0 (f0)(int);
+  X0 (f0)(type);
+  
+  X0 f1();
+  X0 f1(double);
+};
+
+X0::X0() { }
+(X0::X0)(int) { }
+
+X0 (X0::f0)(int) { return X0(); }
+
+template<typename T>
+struct X1 {
+  struct type { };
+
+  X1<T>();
+  X1<T>(int);
+  (X1<T>)(float);
+  X1(float, float);
+  (X1)(double);
+  X1<T> (f0)(int);
+  X1<T> (f0)(type);
+  X1 (f1)(int);
+  X1 (f1)(type);
+
+  template<typename U> X1(U);
+  X1 f2();
+  X1 f2(int);
+};
+
+template<typename T> X1<T>::X1() { }
+template<typename T> (X1<T>::X1)(double) { }
+template<typename T> X1<T> X1<T>::f1(int) { return 0; }
+template<typename T> X1<T> (X1<T>::f1)(type) { return 0; }
diff --git a/test/CXX/special/class.dtor/p2.cpp b/test/CXX/special/class.dtor/p2.cpp
new file mode 100644
index 0000000..b05c992
--- /dev/null
+++ b/test/CXX/special/class.dtor/p2.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// PR5548
+struct A {~A();};
+void a(const A* x) {
+  x->~A();
+}
diff --git a/test/CXX/special/class.free/p1.cpp b/test/CXX/special/class.free/p1.cpp
new file mode 100644
index 0000000..e4fe127
--- /dev/null
+++ b/test/CXX/special/class.free/p1.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+#include <stddef.h>
+
+struct A {
+  void *operator new(size_t) {
+    return this; // expected-error {{invalid use of 'this' outside of a nonstatic member function}}
+  }
+  void *operator new[](size_t) {
+    return this; // expected-error {{invalid use of 'this' outside of a nonstatic member function}}
+  }
+};
diff --git a/test/CXX/special/class.free/p6.cpp b/test/CXX/special/class.free/p6.cpp
new file mode 100644
index 0000000..555d4e9
--- /dev/null
+++ b/test/CXX/special/class.free/p6.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+#include <stddef.h>
+
+struct A {
+  void operator delete(void*) {
+    (void)this; // expected-error {{invalid use of 'this' outside of a nonstatic member function}}
+  }
+  void operator delete[](void*) {
+    (void)this; // expected-error {{invalid use of 'this' outside of a nonstatic member function}}
+  }
+};
diff --git a/test/CXX/stmt.stmt/stmt.select/p3.cpp b/test/CXX/stmt.stmt/stmt.select/p3.cpp
new file mode 100644
index 0000000..31de685
--- /dev/null
+++ b/test/CXX/stmt.stmt/stmt.select/p3.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+int f();
+
+void g() {
+  if (int x = f()) { // expected-note 2{{previous definition}}
+    int x; // expected-error{{redefinition of 'x'}}
+  } else {
+    int x; // expected-error{{redefinition of 'x'}}
+  }
+}
+
+
+void h() {
+  if (int x = f()) // expected-note 2{{previous definition}}
+    int x; // expected-error{{redefinition of 'x'}}
+  else
+    int x; // expected-error{{redefinition of 'x'}}
+}
\ No newline at end of file
diff --git a/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp b/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp
new file mode 100644
index 0000000..14dace8
--- /dev/null
+++ b/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp
@@ -0,0 +1,57 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// C++0x [temp.arg.nontype]p1:
+//
+//   A template-argument for a non-type, non-template template-parameter shall
+//   be one of:
+//   -- an integral constant expression; or
+//   -- the name of a non-type template-parameter ; or
+namespace non_type_tmpl_param {
+  template <int N> struct X0 { X0(); };
+  template <int N> X0<N>::X0() { }
+  template <int* N> struct X1 { X1(); };
+  template <int* N> X1<N>::X1() { }
+  template <int& N> struct X3 { X3(); };
+  template <int& N> X3<N>::X3() { }
+  template <int (*F)(int)> struct X4 { X4(); };
+  template <int (*F)(int)> X4<F>::X4() { }
+  template <typename T, int (T::* M)(int)> struct X5 { X5(); };
+  template <typename T, int (T::* M)(int)> X5<T, M>::X5() { }
+}
+
+//   -- the address of an object or function with external linkage, including
+//      function templates and function template-ids but excluding non-static
+//      class members, expressed as & id-expression where the & is optional if
+//      the name refers to a function or array, or if the corresponding
+//      template-parameter is a reference; or
+namespace addr_of_obj_or_func {
+  template <int* p> struct X0 { };
+  template <int (*fp)(int)> struct X1 { };
+  // FIXME: Add reference template parameter tests.
+
+  int i = 42;
+  int iarr[10];
+  int f(int i);
+  template <typename T> T f_tmpl(T t);
+  void test() {
+    X0<&i> x0a;
+    X0<iarr> x0b;
+    X1<&f> x1a;
+    X1<f> x1b;
+    X1<f_tmpl> x1c;
+    X1<f_tmpl<int> > x1d;
+  }
+}
+
+//   -- a constant expression that evaluates to a null pointer value (4.10); or
+//   -- a constant expression that evaluates to a null member pointer value
+//      (4.11); or
+//   -- a pointer to member expressed as described in 5.3.1.
+
+namespace bad_args {
+  template <int* N> struct X0 { }; // expected-note 2{{template parameter is declared here}}
+  int i = 42;
+  X0<&i + 2> x0a; // expected-error{{non-type template argument does not refer to any declaration}}
+  int* iptr = &i;
+  X0<iptr> x0b; // expected-error{{non-type template argument for template parameter of pointer type 'int *' must have its address taken}}
+}
diff --git a/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp b/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp
new file mode 100644
index 0000000..b0f1c46
--- /dev/null
+++ b/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp
@@ -0,0 +1,205 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// C++0x [temp.arg.nontype] p5:
+//   The following conversions are performed on each expression used as
+//   a non-type template-argument. If a non-type template-argument cannot be
+//   converted to the type of the corresponding template-parameter then the
+//   program is ill-formed.
+//     -- for a non-type template-parameter of integral or enumeration type,
+//        integral promotions (4.5) and integral conversions (4.7) are applied.
+namespace integral_parameters {
+  template<short s> struct X0 { };
+  X0<17> x0i;
+  X0<'a'> x0c;
+  template<char c> struct X1 { };
+  X1<100l> x1l;
+}
+
+//     -- for a non-type template-parameter of type pointer to object,
+//        qualification conversions (4.4) and the array-to-pointer conversion
+//        (4.2) are applied; if the template-argument is of type
+//        std::nullptr_t, the null pointer conversion (4.10) is applied.
+namespace pointer_to_object_parameters {
+  // PR6226
+  struct Str {
+    Str(const char *);
+  };
+
+  template<const char *s>
+  struct A {
+    Str get() { return s; }
+  };
+
+  char hello[6] = "Hello";
+  extern const char world[6];
+  const char world[6] = "world";
+  void test() {
+    (void)A<hello>().get();
+    (void)A<world>().get();
+  }
+
+  class X {
+  public:
+    X();
+    X(int, int);
+    operator int() const;
+  };
+  
+  template<X const *Ptr> struct A2; // expected-note{{template parameter is declared here}}
+  
+  X *X_ptr;
+  X an_X;
+  X array_of_Xs[10];
+  A2<X_ptr> *a12; // expected-error{{must have its address taken}}
+  A2<array_of_Xs> *a13;
+  A2<&an_X> *a13_2;
+  A2<(&an_X)> *a13_3; // expected-error{{non-type template argument cannot be surrounded by parentheses}}
+
+  // PR6244
+  struct X1 {} X1v;
+  template <X1*> struct X2 { };
+  template <X1* Value> struct X3 : X2<Value> { };
+  struct X4 : X3<&X1v> { };
+
+  // PR6563
+  int *bar;
+  template <int *> struct zed {}; // expected-note 2{{template parameter is declared here}}
+  void g(zed<bar>*); // expected-error{{must have its address taken}}
+
+  int baz;
+  void g2(zed<baz>*); // expected-error{{must have its address taken}}
+
+  void g3(zed<&baz>*); // okay
+}
+
+//     -- For a non-type template-parameter of type reference to object, no
+//        conversions apply. The type referred to by the reference may be more
+//        cv-qualified than the (otherwise identical) type of the
+//        template-argument. The template-parameter is bound directly to the
+//        template-argument, which shall be an lvalue.
+namespace reference_parameters {
+  template <int& N> struct S0 { }; // expected-note 3 {{template parameter is declared here}}
+  template <const int& N> struct S1 { }; // expected-note 2 {{template parameter is declared here}}
+  template <volatile int& N> struct S2 { }; // expected-note 2 {{template parameter is declared here}}
+  template <const volatile int& N> struct S3 { };
+  int i;
+  extern const int ci;
+  volatile int vi;
+  extern const volatile int cvi;
+  void test() {
+    S0<i> s0;
+    S0<ci> s0c; // expected-error{{reference binding of non-type template parameter of type 'int &' to template argument of type 'int const' ignores qualifiers}}
+    S0<vi> s0v; // expected-error{{reference binding of non-type template parameter of type 'int &' to template argument of type 'int volatile' ignores qualifiers}}
+    S0<cvi> s0cv; // expected-error{{reference binding of non-type template parameter of type 'int &' to template argument of type 'int const volatile' ignores qualifiers}}
+
+    S1<i> s1;
+    S1<ci> s1c;
+    S1<vi> s1v; // expected-error{{reference binding of non-type template parameter of type 'int const &' to template argument of type 'int volatile' ignores qualifiers}}
+    S1<cvi> s1cv; // expected-error{{reference binding of non-type template parameter of type 'int const &' to template argument of type 'int const volatile' ignores qualifiers}}
+
+    S2<i> s2;
+    S2<ci> s2c; // expected-error{{reference binding of non-type template parameter of type 'int volatile &' to template argument of type 'int const' ignores qualifiers}}
+    S2<vi> s2v;
+    S2<cvi> s2cv; // expected-error{{reference binding of non-type template parameter of type 'int volatile &' to template argument of type 'int const volatile' ignores qualifiers}}
+
+    S3<i> s3;
+    S3<ci> s3c;
+    S3<vi> s3v;
+    S3<cvi> s3cv;
+  }
+  
+  namespace PR6250 {
+    template <typename T, const T &ref> void inc() {
+      ref++; // expected-error{{read-only variable is not assignable}}
+    }
+  
+    template<typename T, const T &ref> void bind() {
+      T &ref2 = ref; // expected-error{{drops qualifiers}}
+    }
+    
+    int counter;
+    void test() {
+      inc<int, counter>(); // expected-note{{instantiation of}}
+      bind<int, counter>(); // expected-note{{instantiation of}}
+    }
+  }
+
+  namespace PR6749 {
+    template <int& i> struct foo {}; // expected-note{{template parameter is declared here}}
+    int x, &y = x;
+    foo<y> f; // expected-error{{is not an object}}
+  }
+}
+
+//     -- For a non-type template-parameter of type pointer to function, the
+//        function-to-pointer conversion (4.3) is applied; if the
+//        template-argument is of type std::nullptr_t, the null pointer
+//        conversion (4.10) is applied. If the template-argument represents
+//        a set of overloaded functions (or a pointer to such), the matching
+//        function is selected from the set (13.4).
+namespace pointer_to_function {
+  template<int (*)(int)> struct X0 { }; // expected-note 3{{template parameter is declared here}}
+  int f(int);
+  int f(float);
+  int g(float);
+  int (*funcptr)(int);
+  void x0a(X0<f>);
+  void x0b(X0<&f>);
+  void x0c(X0<g>); // expected-error{{non-type template argument of type 'int (float)' cannot be converted to a value of type 'int (*)(int)'}}
+  void x0d(X0<&g>); // expected-error{{non-type template argument of type 'int (*)(float)' cannot be converted to a value of type 'int (*)(int)'}}
+  void x0e(X0<funcptr>); // expected-error{{must have its address taken}}
+}
+
+//     -- For a non-type template-parameter of type reference to function, no
+//        conversions apply. If the template-argument represents a set of
+//        overloaded functions, the matching function is selected from the set
+//        (13.4).
+namespace reference_to_function {
+  template<int (&)(int)> struct X0 { }; // expected-note 4{{template parameter is declared here}}
+  int f(int);
+  int f(float);
+  int g(float);
+  int (*funcptr)(int);
+  void x0a(X0<f>);
+  void x0b(X0<&f>); // expected-error{{address taken in non-type template argument for template parameter of reference type 'int (&)(int)'}}
+  void x0c(X0<g>); // expected-error{{non-type template parameter of reference type 'int (&)(int)' cannot bind to template argument of type 'int (float)'}}
+  void x0d(X0<&g>); // expected-error{{address taken in non-type template argument for template parameter of reference type 'int (&)(int)'}}
+  void x0e(X0<funcptr>); // expected-error{{non-type template parameter of reference type 'int (&)(int)' cannot bind to template argument of type 'int (*)(int)'}}
+}
+//     -- For a non-type template-parameter of type pointer to member function,
+//        if the template-argument is of type std::nullptr_t, the null member
+//        pointer conversion (4.11) is applied; otherwise, no conversions
+//        apply. If the template-argument represents a set of overloaded member
+//        functions, the matching member function is selected from the set
+//        (13.4).
+namespace pointer_to_member_function {
+  struct X { };
+  struct Y : X { 
+    int f(int);
+    int g(int);
+    int g(float);
+    float h(float);
+  };
+
+  template<int (Y::*)(int)> struct X0 {}; // expected-note{{template parameter is declared here}}
+  X0<&Y::f> x0a;
+  X0<&Y::g> x0b;
+  X0<&Y::h> x0c; // expected-error{{non-type template argument of type 'float (pointer_to_member_function::Y::*)(float)' cannot be converted to a value of type 'int (pointer_to_member_function::Y::*)(int)'}}
+}
+
+//     -- For a non-type template-parameter of type pointer to data member,
+//        qualification conversions (4.4) are applied; if the template-argument
+//        is of type std::nullptr_t, the null member pointer conversion (4.11)
+//        is applied.
+namespace pointer_to_member_data {
+  struct X { int x; };
+  struct Y : X { int y; };
+
+  template<int Y::*> struct X0 {}; // expected-note{{template parameter is declared here}}
+  X0<&Y::y> x0a;
+  X0<&Y::x> x0b;  // expected-error{{non-type template argument of type 'int pointer_to_member_data::X::*' cannot be converted to a value of type 'int pointer_to_member_data::Y::*'}}
+
+  // Test qualification conversions
+  template<const int Y::*> struct X1 {};
+  X1<&Y::y> x1a;
+}
diff --git a/test/CXX/temp/temp.decls/temp.class.spec/p6.cpp b/test/CXX/temp/temp.decls/temp.class.spec/p6.cpp
new file mode 100644
index 0000000..a93249e
--- /dev/null
+++ b/test/CXX/temp/temp.decls/temp.class.spec/p6.cpp
@@ -0,0 +1,55 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// Test class template partial specializations of member templates.
+template<typename T>
+struct X0 {
+  template<typename U> struct Inner0 {
+    static const unsigned value = 0;
+  };
+  
+  template<typename U> struct Inner0<U*> { 
+    static const unsigned value = 1;
+  };
+};
+
+template<typename T> template<typename U>
+struct X0<T>::Inner0<const U*> {
+  static const unsigned value = 2;
+};
+
+int array0[X0<int>::Inner0<int>::value == 0? 1 : -1];
+int array1[X0<int>::Inner0<int*>::value == 1? 1 : -1];
+int array2[X0<int>::Inner0<const int*>::value == 2? 1 : -1];
+
+// Make sure we can provide out-of-line class template partial specializations
+// for member templates (and instantiate them).
+template<class T> struct A { 
+  struct C {
+    template<class T2> struct B;
+  };
+};
+
+// partial specialization of A<T>::C::B<T2> 
+template<class T> template<class T2> struct A<T>::C::B<T2*> { }; 
+
+A<short>::C::B<int*> absip;
+
+// Check for conflicts during template instantiation. 
+template<typename T, typename U>
+struct Outer {
+  template<typename X, typename Y> struct Inner;
+  template<typename Y> struct Inner<T, Y> {}; // expected-note{{previous}}
+  template<typename Y> struct Inner<U, Y> {}; // expected-error{{cannot be redeclared}}
+};
+
+Outer<int, int> outer; // expected-note{{instantiation}}
+
+// Test specialization of class template partial specialization members.
+template<> template<typename Z>
+struct X0<float>::Inner0<Z*> {
+  static const unsigned value = 3;
+};
+
+int array3[X0<float>::Inner0<int>::value == 0? 1 : -1];
+int array4[X0<float>::Inner0<int*>::value == 3? 1 : -1];
+int array5[X0<float>::Inner0<const int*>::value == 2? 1 : -1];
diff --git a/test/CXX/temp/temp.decls/temp.class.spec/temp.class.order/p2.cpp b/test/CXX/temp/temp.decls/temp.class.spec/temp.class.order/p2.cpp
new file mode 100644
index 0000000..e344eed
--- /dev/null
+++ b/test/CXX/temp/temp.decls/temp.class.spec/temp.class.order/p2.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<int I, int J, class T> struct X { 
+  static const int value = 0;
+};
+
+template<int I, int J> struct X<I, J, int> { 
+  static const int value = 1;
+};
+
+template<int I> struct X<I, I, int> { 
+  static const int value = 2;
+};
+
+int array0[X<0, 0, float>::value == 0? 1 : -1];
+int array1[X<0, 1, int>::value == 1? 1 : -1];
+int array2[X<0, 0, int>::value == 2? 1 : -1];
diff --git a/test/CXX/temp/temp.decls/temp.class.spec/temp.class.spec.mfunc/p1-neg.cpp b/test/CXX/temp/temp.decls/temp.class.spec/temp.class.spec.mfunc/p1-neg.cpp
new file mode 100644
index 0000000..59253db
--- /dev/null
+++ b/test/CXX/temp/temp.decls/temp.class.spec/temp.class.spec.mfunc/p1-neg.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T, int N>
+struct A;
+
+template<typename T> // expected-note{{previous template declaration}}
+struct A<T*, 2> {
+  void f0();
+  void f1();
+  void f2();
+};
+
+template<>
+struct A<int, 1> {
+  void g0();
+};
+
+// FIXME: We should probably give more precise diagnostics here, but the
+// diagnostics we give aren't terrible.
+// FIXME: why not point to the first parameter that's "too many"?
+template<typename T, int N> // expected-error{{too many template parameters}}
+void A<T*, 2>::f0() { }
+
+template<typename T, int N>
+void A<T, N>::f1() { } // expected-error{{out-of-line definition}}
diff --git a/test/CXX/temp/temp.decls/temp.class.spec/temp.class.spec.mfunc/p1.cpp b/test/CXX/temp/temp.decls/temp.class.spec/temp.class.spec.mfunc/p1.cpp
new file mode 100644
index 0000000..87e21e4
--- /dev/null
+++ b/test/CXX/temp/temp.decls/temp.class.spec/temp.class.spec.mfunc/p1.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename T, int N>
+struct A;
+
+template<typename T>
+struct A<T*, 2> {
+  A(T);
+  ~A();
+  
+  void f(T*);
+  
+  operator T*();
+  
+  static T value;
+};
+
+template<class X> void A<X*, 2>::f(X*) { }
+
+template<class X> X A<X*, 2>::value;
+
+template<class X> A<X*, 2>::A(X) { value = 0; }
+
+template<class X> A<X*, 2>::~A() { }
+
+template<class X> A<X*, 2>::operator X*() { return 0; }
diff --git a/test/CXX/temp/temp.decls/temp.class/temp.mem.class/p1.cpp b/test/CXX/temp/temp.decls/temp.class/temp.mem.class/p1.cpp
new file mode 100644
index 0000000..b65e1d0
--- /dev/null
+++ b/test/CXX/temp/temp.decls/temp.class/temp.mem.class/p1.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T, typename U>
+struct X0 {
+  struct Inner;
+};
+
+template<typename T, typename U>
+struct X0<T, U>::Inner {
+  T x;
+  U y;
+  
+  void f() { x = y; } // expected-error{{incompatible}}
+};
+
+
+void test(int i, float f) {
+  X0<int, float>::Inner inner;
+  inner.x = 5;
+  inner.y = 3.4;
+  inner.f();
+  
+  X0<int*, float *>::Inner inner2;
+  inner2.x = &i;
+  inner2.y = &f;
+  inner2.f(); // expected-note{{instantiation}}
+}
diff --git a/test/CXX/temp/temp.decls/temp.class/temp.mem.func/p1-retmem.cpp b/test/CXX/temp/temp.decls/temp.class/temp.mem.func/p1-retmem.cpp
new file mode 100644
index 0000000..4c05c62
--- /dev/null
+++ b/test/CXX/temp/temp.decls/temp.class/temp.mem.func/p1-retmem.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T> struct X1 { };
+
+template<typename T>
+struct X0 {
+  typedef int size_type;
+  typedef T value_type;
+  
+  size_type f0() const;
+  value_type *f1();
+  X1<value_type*> f2();
+};
+
+template<typename T>
+typename X0<T>::size_type X0<T>::f0() const { 
+  return 0;
+}
+
+template<typename U>
+typename X0<U>::value_type *X0<U>::f1() { 
+  return 0;
+};
+
+template<typename U>
+X1<typename X0<U>::value_type*> X0<U>::f2() { 
+  return 0;
+};
diff --git a/test/CXX/temp/temp.decls/temp.class/temp.mem.func/p1.cpp b/test/CXX/temp/temp.decls/temp.class/temp.mem.func/p1.cpp
new file mode 100644
index 0000000..1764563
--- /dev/null
+++ b/test/CXX/temp/temp.decls/temp.class/temp.mem.func/p1.cpp
@@ -0,0 +1,100 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename T, typename U> // expected-note{{previous template}}
+class X0 {
+public:
+  typedef int size_type;
+  
+  X0(int);
+  ~X0();
+  
+  void f0(const T&, const U&);
+  
+  T& operator[](int i) const;
+  
+  void f1(size_type) const;
+  void f2(size_type) const;
+  void f3(size_type) const;
+  void f4() ;
+  
+  operator T*() const;
+  
+  T value;
+};
+
+template<typename T, typename U>
+void X0<T, U>::f0(const T&, const U&) { // expected-note{{previous definition}}
+}
+
+template<class X, class Y>
+X& X0<X, Y>::operator[](int i) const {
+  (void)i;
+  return value;
+}
+
+template<class X, class Y>
+void X0<X, Y>::f1(int) const { }
+
+template<class X, class Y>
+void X0<X, Y>::f2(size_type) const { }
+
+template<class X, class Y, class Z> // expected-error{{too many template parameters}}
+void X0<X, Y>::f3(size_type) const {
+}
+
+template<class X, class Y> 
+void X0<Y, X>::f4() { } // expected-error{{does not refer}}
+
+// FIXME: error message should probably say, "redefinition of 'X0<T, U>::f0'"
+// rather than just "redefinition of 'f0'"
+template<typename T, typename U>
+void X0<T, U>::f0(const T&, const U&) { // expected-error{{redefinition}}
+}
+
+// Test out-of-line constructors, destructors
+template<typename T, typename U>
+X0<T, U>::X0(int x) : value(x) { }
+
+template<typename T, typename U>
+X0<T, U>::~X0() { }
+
+// Test out-of-line conversion functions.
+template<typename T, typename U>
+X0<T, U>::operator T*() const {
+  return &value;
+}
+
+namespace N { template <class X> class A {void a();}; }
+namespace N { template <class X> void A<X>::a() {} }
+
+// PR5566
+template<typename T>
+struct X1 { 
+  template<typename U>
+  struct B { void f(); };
+};
+
+template<typename T>
+template<typename U>
+void X1<T>::template B<U>::f() { }
+
+// PR5527
+template <template <class> class T>
+class X2 {
+  template <class F>
+  class Bar {
+    void Func();
+  };
+};
+
+template <template <class> class T>
+template <class F>
+void X2<T>::Bar<F>::Func() {}
+
+// PR5528
+template <template <class> class T>
+class X3 {
+  void F();
+};
+
+template <template <class> class T>
+void X3<T>::F() {}
diff --git a/test/CXX/temp/temp.decls/temp.class/temp.mem.func/p1inst.cpp b/test/CXX/temp/temp.decls/temp.class/temp.mem.func/p1inst.cpp
new file mode 100644
index 0000000..f09faa9
--- /dev/null
+++ b/test/CXX/temp/temp.decls/temp.class/temp.mem.func/p1inst.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// Test instantiation of member functions of class templates defined out-of-line
+template<typename T, typename U>
+struct X0 {
+  void f(T *t, const U &u);
+  void f(T *);
+};
+
+template<typename T, typename U>
+void X0<T, U>::f(T *t, const U &u) {
+  *t = u; // expected-error{{not assignable}}
+}
+
+void test_f(X0<float, int> xfi, X0<void, int> xvi, float *fp, void *vp, int i) {
+  xfi.f(fp, i);
+  xvi.f(vp, i); // expected-note{{instantiation}}
+}
diff --git a/test/CXX/temp/temp.decls/temp.class/temp.mem.func/pr5056.cpp b/test/CXX/temp/temp.decls/temp.class/temp.mem.func/pr5056.cpp
new file mode 100644
index 0000000..70c9c70
--- /dev/null
+++ b/test/CXX/temp/temp.decls/temp.class/temp.mem.func/pr5056.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+extern "C" void * malloc(int);
+
+template <typename T> struct A {
+  void *malloc(int);
+};
+
+template <typename T>
+inline void *A<T>::malloc(int)
+{
+  return 0;
+}
+
+void f() {
+  malloc(10);
+}
diff --git a/test/CXX/temp/temp.decls/temp.class/temp.static/p1-inst.cpp b/test/CXX/temp/temp.decls/temp.class/temp.static/p1-inst.cpp
new file mode 100644
index 0000000..9fc4a58
--- /dev/null
+++ b/test/CXX/temp/temp.decls/temp.class/temp.static/p1-inst.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// Test instantiation of static data members declared out-of-line.
+
+template<typename T>
+struct X {
+  static T value;
+};
+
+template<typename T> 
+  T X<T>::value = 17; // expected-error{{no viable conversion}}
+
+struct InitOkay {
+  InitOkay(int) { }
+};
+
+struct CannotInit { }; // expected-note{{candidate constructor (the implicit copy constructor) not viable}}
+
+int &returnInt() { return X<int>::value; }
+float &returnFloat() { return X<float>::value; }
+
+InitOkay &returnInitOkay() { return X<InitOkay>::value; }
+
+unsigned long sizeOkay() { return sizeof(X<CannotInit>::value); }
+  
+CannotInit &returnError() {
+  return X<CannotInit>::value; // expected-note{{instantiation}}
+}
diff --git a/test/CXX/temp/temp.decls/temp.class/temp.static/p1.cpp b/test/CXX/temp/temp.decls/temp.class/temp.static/p1.cpp
new file mode 100644
index 0000000..2eae112
--- /dev/null
+++ b/test/CXX/temp/temp.decls/temp.class/temp.static/p1.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T>
+struct X0 {
+  static T value;
+};
+
+template<typename T>
+T X0<T>::value = 0; // expected-error{{no viable conversion}}
+
+struct X1 { 
+  X1(int);
+};
+
+struct X2 { }; // expected-note{{candidate constructor (the implicit copy constructor) not viable}}
+
+int& get_int() { return X0<int>::value; }
+X1& get_X1() { return X0<X1>::value; }
+
+double*& get_double_ptr() { return X0<int*>::value; } // expected-error{{non-const lvalue reference to type 'double *' cannot bind to a value of unrelated type 'int *'}}
+
+X2& get_X2() { 
+  return X0<X2>::value; // expected-note{{instantiation}}
+}
+  
+template<typename T> T x; // expected-error{{variable 'x' declared as a template}}
diff --git a/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p4.cpp b/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p4.cpp
new file mode 100644
index 0000000..b2a6219
--- /dev/null
+++ b/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p4.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<class T> struct A { A(); };
+template<class T> int &f(T); 
+template<class T> float &f(T*); 
+template<class T> double &f(const T*);
+
+template<class T> void g(T); // expected-note{{candidate}}
+template<class T> void g(T&); // expected-note{{candidate}}
+
+template<class T> int &h(const T&); 
+template<class T> float &h(A<T>&);
+
+void m() { 
+  const int *p; 
+  double &dr1 = f(p); 
+  float x; 
+  g(x); // expected-error{{ambiguous}}
+  A<int> z; 
+  float &fr1 = h(z);
+  const A<int> z2; 
+  int &ir1 = h(z2);
+}
diff --git a/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p5.cpp b/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p5.cpp
new file mode 100644
index 0000000..4d34968
--- /dev/null
+++ b/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p5.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<class T> int &f(T); 
+template<class T> float &f(T*, int=1); 
+
+template<class T> int &g(T); 
+template<class T> float &g(T*, ...);
+
+int main() { 
+  int* ip; 
+  float &fr1 = f(ip); 
+  float &fr2 = g(ip);
+}
diff --git a/test/CXX/temp/temp.decls/temp.fct/temp.over.link/p4-neg.cpp b/test/CXX/temp/temp.decls/temp.fct/temp.over.link/p4-neg.cpp
new file mode 100644
index 0000000..e9a3eaa
--- /dev/null
+++ b/test/CXX/temp/temp.decls/temp.fct/temp.over.link/p4-neg.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T> void f0(T) { } // expected-note{{previous}}
+template<class U> void f0(U) { } // expected-error{{redefinition}}
+
+template<int I> void f0() { } // expected-note{{previous}}
+template<int> void f0() { } // expected-error{{redefinition}}
+
+typedef int INT;
+
+template<template<class T, T Value1, INT> class X> 
+  void f0() { } // expected-note{{previous}}
+template<template<typename T, T Value1, int> class> 
+  void f0() { } // expected-error{{redefinition}}
+
+template<typename T>
+struct MetaFun;
+
+template<typename T>
+  typename MetaFun<T*>::type f0(const T&) { while (1) {} } // expected-note{{previous}}
+template<class U>
+  typename MetaFun<U*>::type f0(const U&) { while (1) {} } // expected-error{{redefinition}}
+
+// FIXME: We need canonicalization of expressions for this to work
+// template<int> struct A { };
+// template<int I> void f0(A<I>) { } // Xpected-note{{previous}}
+// template<int J> void f0(A<J>) { } // Xpected-error{{redefinition}}
diff --git a/test/CXX/temp/temp.decls/temp.fct/temp.over.link/p4.cpp b/test/CXX/temp/temp.decls/temp.fct/temp.over.link/p4.cpp
new file mode 100644
index 0000000..f42b94a
--- /dev/null
+++ b/test/CXX/temp/temp.decls/temp.fct/temp.over.link/p4.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// All of these function templates are distinct.
+template<typename T> void f0(T) { }
+template<typename T, typename U> void f0(T) { }
+template<typename T, typename U> void f0(U) { }
+void f0();
+template<typename T> void f0(T*);
+void f0(int);
+template<int I> void f0();
+template<typename T> void f0();
+
+
diff --git a/test/CXX/temp/temp.decls/temp.fct/temp.over.link/p6.cpp b/test/CXX/temp/temp.decls/temp.fct/temp.over.link/p6.cpp
new file mode 100644
index 0000000..a668ada
--- /dev/null
+++ b/test/CXX/temp/temp.decls/temp.fct/temp.over.link/p6.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<int N, int M>
+struct A0 {
+  void g0();
+};
+
+template<int X, int Y> void f0(A0<X, Y>) { } // expected-note{{previous}}
+template<int N, int M> void f0(A0<M, N>) { }
+template<int V1, int V2> void f0(A0<V1, V2>) { } // expected-error{{redefinition}}
+
+template<int X, int Y> void f1(A0<0, (X + Y)>) { } // expected-note{{previous}}
+template<int X, int Y> void f1(A0<0, (X - Y)>) { }
+template<int A, int B> void f1(A0<0, (A + B)>) { } // expected-error{{redefinition}}
+
+template<int X, int Y> void A0<X, Y>::g0() { }
diff --git a/test/CXX/temp/temp.decls/temp.friend/p1.cpp b/test/CXX/temp/temp.decls/temp.friend/p1.cpp
new file mode 100644
index 0000000..073b2a1
--- /dev/null
+++ b/test/CXX/temp/temp.decls/temp.friend/p1.cpp
@@ -0,0 +1,295 @@
+// RUN: %clang_cc1 -verify -emit-llvm-only %s
+
+namespace test0 {
+template <typename T> struct Num {
+  T value_;
+
+public:
+  Num(T value) : value_(value) {}
+  T get() const { return value_; }
+
+  template <typename U> struct Rep {
+    U count_;
+    Rep(U count) : count_(count) {}
+
+    friend Num operator*(const Num &a, const Rep &n) {
+      Num x = 0;
+      for (U count = n.count_; count; --count)
+        x += a;
+      return x;
+    } 
+  };
+
+  friend Num operator+(const Num &a, const Num &b) {
+    return a.value_ + b.value_;
+  }
+
+  Num& operator+=(const Num& b) {
+    value_ += b.value_;
+    return *this;
+  }
+
+  class Representation {};
+  friend class Representation;
+};
+
+class A {
+  template <typename T> friend bool iszero(const A &a) throw();
+};
+
+template <class T> class B_iterator;
+template <class T> class B {
+  friend class B_iterator<T>;
+};
+
+int calc1() {
+  Num<int> left = -1;
+  Num<int> right = 1;
+  Num<int> result = left + right;
+  return result.get();
+}
+
+int calc2() {
+  Num<int> x = 3;
+  Num<int>::Rep<char> n = (char) 10;
+  Num<int> result = x * n;
+  return result.get();
+}
+}
+
+// Reduced from GNU <locale>
+namespace test1 {
+  class A {
+    bool b; // expected-note {{declared private here}}
+    template <typename T> friend bool has(const A&);
+  };
+  template <typename T> bool has(const A &x) {
+    return x.b;
+  }
+  template <typename T> bool hasnot(const A &x) {
+    return x.b; // expected-error {{'b' is a private member of 'test1::A'}}
+  }
+}
+
+namespace test2 {
+  class A {
+    bool b; // expected-note {{declared private here}}
+    template <typename T> friend class HasChecker;
+  };
+  template <typename T> class HasChecker {
+    bool check(A *a) {
+      return a->b;
+    }
+  };
+  template <typename T> class HasNotChecker {
+    bool check(A *a) {
+      return a->b; // expected-error {{'b' is a private member of 'test2::A'}}
+    }
+  };
+}
+
+namespace test3 {
+  class Bool;
+  template <class T> class User;
+  template <class T> T transform(class Bool, T);
+
+  class Bool {
+    friend class User<bool>;
+    friend bool transform<>(Bool, bool);
+
+    bool value; // expected-note 2 {{declared private here}}
+  };
+
+  template <class T> class User {
+    static T compute(Bool b) {
+      return b.value; // expected-error {{'value' is a private member of 'test3::Bool'}}
+    }
+  };
+
+  template <class T> T transform(Bool b, T value) {
+    if (b.value) // expected-error {{'value' is a private member of 'test3::Bool'}}
+      return value;
+    return value + 1;
+  }
+
+  template bool transform(Bool, bool);
+  template int transform(Bool, int); // expected-note {{requested here}}
+
+  template class User<bool>;
+  template class User<int>; // expected-note {{requested here}}
+}
+
+namespace test4 {
+  template <class T> class A {
+    template <class T0> friend class B;
+    bool foo(const A<T> *) const;
+  };
+
+  template <class T> class B {
+    bool bar(const A<T> *a, const A<T> *b) {
+      return a->foo(b);
+    }
+  };
+
+  template class B<int>;
+}
+
+namespace test5 {
+  template <class T, class U=int> class A {};
+  template <class T> class B {
+    template <class X, class Y> friend class A;
+  };
+  template class B<int>;
+  template class A<int>;
+}
+
+namespace Dependent {
+  template<typename T, typename Traits> class X;
+  template<typename T, typename Traits> 
+  X<T, Traits> operator+(const X<T, Traits>&, const T*);
+
+  template<typename T, typename Traits> class X {
+    typedef typename Traits::value_type value_type;
+    friend X operator+<>(const X&, const value_type*);
+  };
+}
+
+namespace test7 {
+  template <class T> class A { // expected-note {{declared here}}
+    friend class B;
+    int x; // expected-note {{declared private here}}
+  };
+
+  class B {
+    int foo(A<int> &a) {
+      return a.x;
+    }
+  };
+
+  class C {
+    int foo(A<int> &a) {
+      return a.x; // expected-error {{'x' is a private member of 'test7::A<int>'}}
+    }
+  };
+
+  // This shouldn't crash.
+  template <class T> class D {
+    friend class A; // expected-error {{elaborated type refers to a template}}
+  };
+  template class D<int>;
+}
+
+namespace test8 {
+  template <class N> class A {
+    static int x;
+    template <class T> friend void foo();
+  };
+  template class A<int>;
+
+  template <class T> void foo() {
+    A<int>::x = 0;
+  }
+  template void foo<int>();
+}
+
+namespace test9 {
+  template <class T> class A {
+    class B; class C;
+
+    int foo(B *b) {
+      return b->x;
+    }
+
+    int foo(C *c) {
+      return c->x; // expected-error {{'x' is a private member}}
+    }
+
+    class B {
+      int x;
+      friend int A::foo(B*);
+    };
+
+    class C {
+      int x; // expected-note {{declared private here}}
+    };
+  };
+
+  template class A<int>; // expected-note {{in instantiation}}
+}
+
+namespace test10 {
+  template <class T> class A;
+  template <class T> A<T> bar(const T*, const A<T>&);
+  template <class T> class A {
+  private:
+    void foo(); // expected-note {{declared private here}}
+    friend A bar<>(const T*, const A<T>&);
+  };
+
+  template <class T> A<T> bar(const T *l, const A<T> &r) {
+    A<T> l1;
+    l1.foo();
+
+    A<char> l2;
+    l2.foo(); // expected-error {{'foo' is a private member of 'test10::A<char>'}}
+
+    return l1;
+  }
+
+  template A<int> bar<int>(const int *, const A<int> &); // expected-note {{in instantiation}}
+}
+
+// PR6752: this shouldn't crash.
+namespace test11 {
+  struct Foo {
+    template<class A>
+    struct IteratorImpl {
+      template<class T> friend class IteratorImpl;
+    };
+  };
+
+  template struct Foo::IteratorImpl<int>;
+  template struct Foo::IteratorImpl<long>;  
+}
+
+// PR6827
+namespace test12 {
+  template <typename T> class Foo;
+  template <typename T> Foo<T> foo(T* t){ return Foo<T>(t, true); }
+
+  template <typename T> class Foo {
+  public:
+    Foo(T*);
+    friend Foo<T> foo<T>(T*);
+  private:
+    Foo(T*, bool); // expected-note {{declared private here}}
+  };
+
+  // Should work.
+  int globalInt;
+  Foo<int> f = foo(&globalInt);
+
+  // Shouldn't work.
+  long globalLong;
+  template <> Foo<long> foo(long *t) {
+    Foo<int> s(&globalInt, false); // expected-error {{calling a private constructor}}
+    return Foo<long>(t, true);
+  }
+}
+
+// PR6514
+namespace test13 {
+  template <int N, template <int> class Temp>
+  class Role : public Temp<N> {
+    friend class Temp<N>;
+    int x;
+  };
+
+  template <int N> class Foo {
+    void foo(Role<N, test13::Foo> &role) {
+      (void) role.x;
+    }
+  };
+
+  template class Foo<0>;
+}
diff --git a/test/CXX/temp/temp.decls/temp.friend/p3.cpp b/test/CXX/temp/temp.decls/temp.friend/p3.cpp
new file mode 100644
index 0000000..d116e01
--- /dev/null
+++ b/test/CXX/temp/temp.decls/temp.friend/p3.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template <class T> class A {
+  typedef int Member;
+};
+
+class B {
+  template <class T> friend class A;
+  template <class T> friend class Undeclared;
+  
+  template <class T> friend typename A<T>::Member; // expected-warning {{non-class type 'typename A<T>::Member' cannot be a friend}}
+};
diff --git a/test/CXX/temp/temp.decls/temp.friend/p5.cpp b/test/CXX/temp/temp.decls/temp.friend/p5.cpp
new file mode 100644
index 0000000..f23611b
--- /dev/null
+++ b/test/CXX/temp/temp.decls/temp.friend/p5.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template <class T> class A {
+  class Member {
+  };
+};
+
+class B {
+  template <class T> friend class A<T>::Member;
+};
+
+A<int> a;
+B b;
diff --git a/test/CXX/temp/temp.decls/temp.mem/p1.cpp b/test/CXX/temp/temp.decls/temp.mem/p1.cpp
new file mode 100644
index 0000000..f5f1205
--- /dev/null
+++ b/test/CXX/temp/temp.decls/temp.mem/p1.cpp
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template <class T> struct A {
+  static T cond;
+  
+  template <class U> struct B {
+    static T twice(U value) {
+      return (cond ? value + value : value);
+    }
+  };
+};
+
+int foo() {
+  A<bool>::cond = true;
+  return A<bool>::B<int>::twice(4);
+}
+
+namespace PR6376 {
+  template<typename T>
+  struct X {
+    template<typename Y>
+    struct Y1 { }; //
+  };
+
+  template<>
+  struct X<float> {
+    template<typename Y>
+    struct Y1 { };
+  };
+
+  template<typename T, typename U>
+  struct Z : public X<T>::template Y1<U> { };
+
+  Z<float, int> z0;
+}
diff --git a/test/CXX/temp/temp.decls/temp.mem/p5.cpp b/test/CXX/temp/temp.decls/temp.mem/p5.cpp
new file mode 100644
index 0000000..b0078d4
--- /dev/null
+++ b/test/CXX/temp/temp.decls/temp.mem/p5.cpp
@@ -0,0 +1,78 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+struct A { 
+  template <class T> operator T*();
+}; 
+
+template <class T> A::operator T*() { return 0; }
+template <> A::operator char*(){ return 0; } // specialization
+template A::operator void*(); // explicit instantiation
+
+int main() { 
+  A a;
+  int *ip; 
+  ip = a.operator int*();
+}
+
+// PR5742
+namespace PR5742 {
+  template <class T> struct A { };
+  template <class T> struct B { };
+
+  struct S {
+    template <class T> operator T();
+  } s;
+
+  void f() {
+    s.operator A<A<int> >();
+    s.operator A<B<int> >();
+    s.operator A<B<A<int> > >();
+  }
+}
+
+// PR5762
+class Foo {
+ public:
+  template <typename T> operator T();
+  
+  template <typename T>
+  T As() {
+    return this->operator T();
+  }
+
+  template <typename T>
+  T As2() {
+    return operator T();
+  }
+  
+  int AsInt() {
+    return this->operator int();
+  }
+};
+
+template float Foo::As();
+template double Foo::As2();
+
+// Partial ordering with conversion function templates.
+struct X0 {
+  template<typename T> operator T*() {
+    T x = 1;
+    x = 17; // expected-error{{read-only variable is not assignable}}
+  }
+  
+  template<typename T> operator T*() const; // expected-note{{explicit instantiation refers here}}
+  
+  template<typename T> operator const T*() const {
+    T x = T();
+    return x; // expected-error{{cannot initialize return object of type 'char const *' with an lvalue of type 'char'}}
+  }
+};
+
+template X0::operator const char*() const; // expected-note{{'X0::operator char const *<char>' requested here}}
+template X0::operator const int*(); // expected-note{{'X0::operator int const *<int const>' requested here}}
+template X0::operator float*() const; // expected-error{{explicit instantiation of undefined function template}}
+
+void test_X0(X0 x0, const X0 &x0c) {
+  x0.operator const int*();
+  x0.operator float *();
+  x0c.operator const char*();
+}
diff --git a/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p1.cpp b/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p1.cpp
new file mode 100644
index 0000000..0aef6ad
--- /dev/null
+++ b/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p1.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fsyntax-only %s
+
+template<typename T> struct A { };
+
+template<typename T> T make();
+template<typename T> T make2(const T&);
+
+void test_make() {
+  int& ir0 = make<int&>();
+  A<int> a0 = make< A<int> >();
+  A<int> a1 = make2< A<int> >(A<int>());
+}
diff --git a/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-nodeduct.cpp b/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-nodeduct.cpp
new file mode 100644
index 0000000..eb5465c
--- /dev/null
+++ b/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-nodeduct.cpp
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// PR5811
+template <class F> void Call(F f) { f(1); }
+template <typename T> void f(T);
+void a() { Call(f<int>); }
+
+// Check the conversion of a template-id to a pointer
+template<typename T, T* Address> struct Constant { };
+Constant<void(int), &f<int> > constant0;
+
+template<typename T, T* Address> void constant_func();
+void test_constant_func() {
+  constant_func<void(int), &f<int> >();
+}
+
+
+// Check typeof() on a template-id referring to a single function
+template<typename T, typename U>
+struct is_same {
+  static const bool value = false;
+};
+
+template<typename T>
+struct is_same<T, T> {
+  static const bool value = true;
+};
+
+int typeof0[is_same<__typeof__(f<int>), void (int)>::value? 1 : -1];
+int typeof1[is_same<__typeof__(&f<int>), void (*)(int)>::value? 1 : -1];
+
+template <typename T> void g(T);
+template <typename T> void g(T, T);
+
+int typeof2[is_same<__typeof__(g<float>), void (int)>::value? 1 : -1]; // \
+     // expected-error{{cannot determine the type of an overloaded function}}
diff --git a/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3.cpp b/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3.cpp
new file mode 100644
index 0000000..dc79300
--- /dev/null
+++ b/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3.cpp
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<class X, class Y, class Z> X f(Y,Z); // expected-note {{candidate template ignored: couldn't infer template argument 'X'}}
+
+void g() {
+  f<int,char*,double>("aa",3.0); // expected-warning{{conversion from string literal to 'char *' is deprecated}}
+  f<int,char*>("aa",3.0); // Z is deduced to be double  \
+                          // expected-warning{{conversion from string literal to 'char *' is deprecated}}
+  f<int>("aa",3.0);       // Y is deduced to be char*, and
+                          // Z is deduced to be double 
+  f("aa",3.0); // expected-error{{no matching}}
+}
+
+// PR5910
+namespace PR5910 {
+  template <typename T>
+  void Func() {}
+  
+  template <typename R>
+  void Foo(R (*fp)());
+  
+  void Test() {
+    Foo(Func<int>);
+  }
+}
+
+// PR5949
+namespace PR5949 {
+  struct Bar;
+
+  template <class Container>
+  void quuz(const Container &cont) {
+  }
+
+  template<typename T>
+  int Foo(Bar *b, void (*Baz)(const T &t), T * = 0) {
+    return 0;
+  }
+
+  template<typename T>
+  int Quux(Bar *b, T * = 0)
+  {
+    return Foo<T>(b, quuz);
+  }
+}
diff --git a/test/CXX/temp/temp.fct.spec/temp.deduct/p9.cpp b/test/CXX/temp/temp.fct.spec/temp.deduct/p9.cpp
new file mode 100644
index 0000000..c27261c
--- /dev/null
+++ b/test/CXX/temp/temp.fct.spec/temp.deduct/p9.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template <int> int f(int);  // expected-note 2{{candidate}}
+template <signed char> int f(int); // expected-note 2{{candidate}}
+int i1 = f<1>(0); // expected-error{{ambiguous}}
+int i2 = f<1000>(0); // expected-error{{ambiguous}}
+
+namespace PR6707 {
+  template<typename T, T Value>
+  struct X { };
+
+  template<typename T, T Value>
+  void f(X<T, Value>);
+
+  void g(X<int, 10> x) {
+    f(x);
+  }
+
+  static const unsigned char ten = 10;
+  template<typename T, T Value, typename U>
+  void f2(X<T, Value>, X<U, Value>);
+
+  void g2() {
+    f2(X<int, 10>(), X<char, ten>());
+  }
+}
diff --git a/test/CXX/temp/temp.fct.spec/temp.deduct/sfinae-1.cpp b/test/CXX/temp/temp.fct.spec/temp.deduct/sfinae-1.cpp
new file mode 100644
index 0000000..f6121b3
--- /dev/null
+++ b/test/CXX/temp/temp.fct.spec/temp.deduct/sfinae-1.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 %s
+
+typedef char one_byte;
+struct two_bytes { char data[2]; };
+
+template<typename T> one_byte __is_class_check(int T::*);
+template<typename T> two_bytes __is_class_check(...);
+
+template<typename T> struct is_class {
+  static const bool value = sizeof(__is_class_check<T>(0)) == 1;
+};
+
+struct X { };
+
+int array0[is_class<X>::value? 1 : -1];
+int array1[is_class<int>::value? -1 : 1];
+int array2[is_class<char[3]>::value? -1 : 1];
diff --git a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/basic.cpp b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/basic.cpp
new file mode 100644
index 0000000..1b7310f
--- /dev/null
+++ b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/basic.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T> struct A { };
+
+template<typename T> A<T> f0(T*);
+
+void test_f0(int *ip, float const *cfp) {
+  A<int> a0 = f0(ip);
+  A<const float> a1 = f0(cfp);
+}
+
+template<typename T> void f1(T*, int);
+
+void test_f1(int *ip, float fv) {
+  f1(ip, fv);
+}
+
+// TODO: this diagnostic can and should improve
+template<typename T> void f2(T*, T*); // expected-note 2 {{candidate template ignored: failed template argument deduction}}
+
+struct ConvToIntPtr {
+  operator int*() const;
+};
+
+void test_f2(int *ip, float *fp) {
+  f2(ip, ConvToIntPtr()); // expected-error{{no matching function}}
+  f2(ip, ip); // okay
+  f2(ip, fp); // expected-error{{no matching function}}
+}
diff --git a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p2.cpp b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p2.cpp
new file mode 100644
index 0000000..c165c45
--- /dev/null
+++ b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p2.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename T> struct A { };
+
+// bullet 1
+template<typename T> A<T> f0(T* ptr);
+
+void test_f0_bullet1() {
+  int arr0[6];
+  A<int> a0 = f0(arr0);
+  const int arr1[] = { 1, 2, 3, 4, 5 };
+  A<const int> a1 = f0(arr1);
+}
+
+// bullet 2
+int g0(int, int);
+float g1(float);
+
+void test_f0_bullet2() {
+  A<int(int, int)> a0 = f0(g0);
+  A<float(float)> a1 = f0(g1);
+}
+
+// bullet 3
+struct X { };
+const X get_X();
+
+template<typename T> A<T> f1(T);
+
+void test_f1_bullet3() {
+  A<X> a0 = f1(get_X());
+}
diff --git a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3.cpp b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3.cpp
new file mode 100644
index 0000000..19962c5
--- /dev/null
+++ b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3.cpp
@@ -0,0 +1,103 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T> struct A { };
+
+// Top-level cv-qualifiers of P's type are ignored for type deduction.
+template<typename T> A<T> f0(const T);
+
+void test_f0(int i, const int ci) {
+  A<int> a0 = f0(i);
+  A<int> a1 = f0(ci);
+}
+
+// If P is a reference type, the type referred to by P is used for type 
+// deduction.
+template<typename T> A<T> f1(T&);
+
+void test_f1(int i, const int ci, volatile int vi) {
+  A<int> a0 = f1(i);
+  A<const int> a1 = f1(ci);
+  A<volatile int> a2 = f1(vi);
+}
+
+template<typename T, unsigned N> struct B { };
+template<typename T, unsigned N> B<T, N> g0(T (&array)[N]);
+template<typename T, unsigned N> B<T, N> g0b(const T (&array)[N]);
+
+void test_g0() {
+  int array0[5];
+  B<int, 5> b0 = g0(array0);
+  const int array1[] = { 1, 2, 3};
+  B<const int, 3> b1 = g0(array1);
+  B<int, 3> b2 = g0b(array1);
+}
+
+template<typename T> B<T, 0> g1(const A<T>&);
+
+void test_g1(A<float> af) {
+  B<float, 0> b0 = g1(af);
+  B<int, 0> b1 = g1(A<int>());
+}
+
+//   - If the original P is a reference type, the deduced A (i.e., the type
+//     referred to by the reference) can be more cv-qualified than the 
+//     transformed A.
+template<typename T> A<T> f2(const T&);
+
+void test_f2(int i, const int ci, volatile int vi) {
+  A<int> a0 = f2(i);
+  A<int> a1 = f2(ci);
+  A<volatile int> a2 = f2(vi);
+}
+
+// PR5913
+template <typename T, int N>
+void Foo(const T (&a)[N]) {
+  T x;
+  x = 0;
+}
+
+const int a[1] = { 0 };
+
+void Test() {
+  Foo(a);
+}
+
+//   - The transformed A can be another pointer or pointer to member type that 
+//     can be converted to the deduced A via a qualification conversion (4.4).
+template<typename T> A<T> f3(T * * const * const);
+
+void test_f3(int ***ip, volatile int ***vip) {
+  A<int> a0 = f3(ip);
+  A<volatile int> a1 = f3(vip);
+}
+                             
+//   - If P is a class, and P has the form template-id, then A can be a 
+//     derived class of the deduced A. Likewise, if P is a pointer to a class
+//     of the form template-id, A can be a pointer to a derived class pointed 
+//     to by the deduced A.
+template<typename T, int I> struct C { };
+
+struct D : public C<int, 1> { };
+struct E : public D { };
+struct F : A<float> { };
+struct G : A<float>, C<int, 1> { };
+
+template<typename T, int I>
+  C<T, I> *f4a(const C<T, I>&);
+template<typename T, int I>
+  C<T, I> *f4b(C<T, I>);
+template<typename T, int I>
+  C<T, I> *f4c(C<T, I>*);
+int *f4c(...);
+
+void test_f4(D d, E e, F f, G g) {
+  C<int, 1> *ci1a = f4a(d);
+  C<int, 1> *ci2a = f4a(e);
+  C<int, 1> *ci1b = f4b(d);
+  C<int, 1> *ci2b = f4b(e);
+  C<int, 1> *ci1c = f4c(&d);
+  C<int, 1> *ci2c = f4c(&e);
+  C<int, 1> *ci3c = f4c(&g);
+  int       *ip1 = f4c(&f);
+}
diff --git a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p6.cpp b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p6.cpp
new file mode 100644
index 0000000..6edf079
--- /dev/null
+++ b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p6.cpp
@@ -0,0 +1,95 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace test0 {
+  template<class T> void apply(T x, void (*f)(T)) { f(x); } // expected-note 2 {{failed template argument deduction}}\
+  // expected-note {{no overload of 'temp2' matching 'void (*)(int)'}}
+
+  template<class A> void temp(A);
+  void test0() {
+    // okay: deduce T=int from first argument, A=int during overload
+    apply(0, &temp);
+    apply(0, &temp<>);
+
+    // okay: deduce T=int from first and second arguments
+    apply(0, &temp<int>);
+
+    // deduction failure: T=int from first, T=long from second
+    apply(0, &temp<long>); // expected-error {{no matching function for call to 'apply'}}
+  }
+
+  void over(int);
+  int over(long);
+
+  void test1() {
+    // okay: deductions match
+    apply(0, &over);
+
+    // deduction failure: deduced T=long from first argument, T=int from second
+    apply(0L, &over); // expected-error {{no matching function for call to 'apply'}}
+  }
+
+  void over(short);
+
+  void test2() {
+    // deduce T=int from first arg, second arg is undeduced context,
+    // pick correct overload of 'over' during overload resolution for 'apply'
+    apply(0, &over);
+  }
+
+  template<class A, class B> B temp2(A);
+  void test3() {
+    // deduce T=int from first arg, A=int B=void during overload resolution
+    apply(0, &temp2);
+    apply(0, &temp2<>);
+    apply(0, &temp2<int>);
+
+    // overload failure
+    apply(0, &temp2<long>); // expected-error {{no matching function for call to 'apply'}}
+  }
+}
+
+namespace test1 {
+  template<class T> void invoke(void (*f)(T)) { f(T()); } // expected-note 6 {{couldn't infer template argument}} \
+  // expected-note {{failed template argument deduction}}
+
+  template<class T> void temp(T);
+  void test0() {
+    // deduction failure: overload has template => undeduced context
+    invoke(&temp); // expected-error {{no matching function for call to 'invoke'}}
+    invoke(&temp<>); // expected-error {{no matching function for call to 'invoke'}}
+
+    // okay: full template-id
+    invoke(&temp<int>);
+  }
+
+  void over(int);
+  int over(long);
+
+  void test1() {
+    // okay: only one overload matches
+    invoke(&over);
+  }
+
+  void over(short);
+
+  void test2() {
+    // deduction failure: overload has multiple matches => undeduced context
+    invoke(&over); // expected-error {{no matching function for call to 'invoke'}}
+  }
+
+  template<class A, class B> B temp2(A);
+  void test3() {
+    // deduction failure: overload has template => undeduced context
+    // (even though partial application temp2<int> could in theory
+    // let us infer T=int)
+    invoke(&temp2); // expected-error {{no matching function for call to 'invoke'}}
+    invoke(&temp2<>); // expected-error {{no matching function for call to 'invoke'}}
+    invoke(&temp2<int>); // expected-error {{no matching function for call to 'invoke'}}
+
+    // okay: full template-id
+    invoke(&temp2<int, void>);
+
+    // overload failure
+    invoke(&temp2<int, int>); // expected-error {{no matching function for call to 'invoke'}}
+  }
+}
diff --git a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.conv/p2.cpp b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.conv/p2.cpp
new file mode 100644
index 0000000..5a9ea08
--- /dev/null
+++ b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.conv/p2.cpp
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// FIXME: [temp.deduct.conv]p2 bullets 1 and 2 can't actually happen without
+// references?
+// struct ConvertibleToArray {
+//   //  template<typename T, unsigned N>
+//   //  operator T(()[]) const;
+
+// private:
+//   typedef int array[17];
+
+//   operator array() const;
+// };
+
+// void test_array(ConvertibleToArray cta) {
+//   int *ip = cta;
+//   ip = cta;
+//   const float *cfp = cta;
+// }
+
+// bullet 2
+// struct ConvertibleToFunction {
+//   template<typename T, typename A1, typename A2>
+//   operator T(A1, A2) const ()  { };
+// };
+
+// bullet 3
+struct ConvertibleToCVQuals {
+  template<typename T>
+  operator T* const() const;
+};
+
+void test_cvqual_conv(ConvertibleToCVQuals ctcv) {
+  int *ip = ctcv;
+  const int *icp = ctcv;
+}
diff --git a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.conv/p3.cpp b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.conv/p3.cpp
new file mode 100644
index 0000000..e23e98a
--- /dev/null
+++ b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.conv/p3.cpp
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+struct AnyPtr {
+  template<typename T>
+  operator T*() const;
+};
+
+// If A is a cv-qualified type, the top level cv-qualifiers of A's type
+// are ignored for type deduction.
+void test_cvquals(AnyPtr ap) {
+  int* const ip = ap;
+  const float * const volatile fp = ap;
+}
+
+// If A is a reference type, the type referred to by A is used for
+// type deduction.
+void test_ref_arg(AnyPtr ap) {
+  const int* const &ip = ap;
+  double * const &dp = ap;
+}
+
+struct AnyRef {
+  template<typename T>
+  operator T&() const;
+};
+
+void test_ref_param(AnyRef ar) {
+  int &ir = ar;
+  const float &fr = ar;
+  int i = ar;
+}
diff --git a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.conv/p4.cpp b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.conv/p4.cpp
new file mode 100644
index 0000000..4dca820
--- /dev/null
+++ b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.conv/p4.cpp
@@ -0,0 +1,44 @@
+// RUN: %clang_cc1 -fsyntax-only %s
+
+struct AnyT {
+  template<typename T>
+  operator T();
+};
+
+void test_cvqual_ref(AnyT any) {
+  const int &cir = any;  
+}
+
+struct AnyThreeLevelPtr {
+  template<typename T>
+  operator T***() const
+  {
+    T x = 0;
+    // FIXME: looks like we get this wrong, too!
+    // x = 0; // will fail if T is deduced to a const type
+           // (EDG and GCC get this wrong)
+    return 0;
+  }
+};
+
+struct X { };
+
+void test_deduce_with_qual(AnyThreeLevelPtr a3) {
+  int * const * const * const ip = a3;
+}
+
+struct AnyPtrMem {
+  template<typename Class, typename T>
+  operator T Class::*() const
+  {
+    T x = 0;
+    // FIXME: looks like we get this wrong, too!
+    // x = 0; // will fail if T is deduced to a const type.
+           // (EDG and GCC get this wrong)
+    return 0;
+  }
+};
+
+void test_deduce_ptrmem_with_qual(AnyPtrMem apm) {
+  const float X::* pm = apm;
+}
diff --git a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.funcaddr/p1.cpp b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.funcaddr/p1.cpp
new file mode 100644
index 0000000..99a265a
--- /dev/null
+++ b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.funcaddr/p1.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -fsyntax-only %s
+
+template<typename T>
+  T f0(T, int);
+
+void test_f0() {
+  int (*f0a)(int, int) = f0;
+  int (*f0b)(int, int) = &f0;
+  float (*f0c)(float, int) = &f0;
+}
+
+template<typename T> T f1(T, int);
+template<typename T> T f1(T);
+
+void test_f1() {
+  float (*f1a)(float, int) = f1;
+  float (*f1b)(float, int) = &f1;
+  float (*f1c)(float) = f1;
+  float (*f1d)(float) = (f1);
+  float (*f1e)(float) = &f1;
+  float (*f1f)(float) = (&f1);
+}
diff --git a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p11.cpp b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p11.cpp
new file mode 100644
index 0000000..99ade4b
--- /dev/null
+++ b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p11.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template <class T> T* f(int);	// #1 
+template <class T, class U> T& f(U); // #2 
+
+void g() {
+  int *ip = f<int>(1);	// calls #1
+}
+
+template<typename T>
+struct identity {
+  typedef T type;
+};
+
+template <class T> 
+  T* f2(int, typename identity<T>::type = 0); // expected-note{{candidate}}
+template <class T, class U> 
+  T& f2(U, typename identity<T>::type = 0); // expected-note{{candidate}}
+
+void g2() {
+  f2<int>(1); // expected-error{{ambiguous}}
+}
diff --git a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p17.cpp b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p17.cpp
new file mode 100644
index 0000000..2a7f16d
--- /dev/null
+++ b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p17.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<int i> class A {  };
+template<short s> void f(A<s>); // expected-note{{failed template argument deduction}}
+
+void k1() { 
+  A<1> a;
+  f(a); // expected-error{{no matching function for call}}
+  f<1>(a);
+}
+template<const short cs> class B { }; 
+template<short s> void g(B<s>); 
+void k2() {
+  B<1> b; 
+  g(b); // OK: cv-qualifiers are ignored on template parameter types
+}
+
+template<short s> void h(int (&)[s]); // expected-note{{failed template argument deduction}}
+void k3() {
+  int array[5];
+  h(array);
+  h<5>(array);
+}
+
+template<short s> void h(int (&)[s], A<s>);  // expected-note{{failed template argument deduction}}
+void k4() {
+  A<5> a;
+  int array[5];
+  h(array, a); // expected-error{{no matching function for call}}
+  h<5>(array, a);
+}
diff --git a/test/CXX/temp/temp.names/p4.cpp b/test/CXX/temp/temp.names/p4.cpp
new file mode 100644
index 0000000..103a1bd
--- /dev/null
+++ b/test/CXX/temp/temp.names/p4.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct meta {
+  template<typename U>
+  struct apply {
+    typedef U* type;
+  };
+};
+
+template<typename T, typename U>
+void f(typename T::template apply<U>::type);
+
+void test_f(int *ip) {
+  f<meta, int>(ip);
+}
diff --git a/test/CXX/temp/temp.param/p1.cpp b/test/CXX/temp/temp.param/p1.cpp
new file mode 100644
index 0000000..676bffe
--- /dev/null
+++ b/test/CXX/temp/temp.param/p1.cpp
@@ -0,0 +1,4 @@
+// Suppress 'no run line' failure.
+// RUN: echo ok
+
+// Paragraph 1 is descriptive, and therefore requires no tests.
diff --git a/test/CXX/temp/temp.param/p10.cpp b/test/CXX/temp/temp.param/p10.cpp
new file mode 100644
index 0000000..b9dac75
--- /dev/null
+++ b/test/CXX/temp/temp.param/p10.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s 
+template<typename> struct Y1;
+template<typename, int> struct Y2;
+
+template<class T1, class T2 = int> class B2; 
+template<class T1 = int, class T2> class B2;
+
+template<template<class, int> class, template<class> class = Y1> class B2t;
+template<template<class, int> class = Y2, template<class> class> class B2t;
+
+template<int N, int M = 5> class B2n;
+template<int N = 5, int M> class B2n;
diff --git a/test/CXX/temp/temp.param/p11.cpp b/test/CXX/temp/temp.param/p11.cpp
new file mode 100644
index 0000000..5af0c4e
--- /dev/null
+++ b/test/CXX/temp/temp.param/p11.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s 
+template<typename> struct Y1;
+template<typename, int> struct Y2;
+
+template<class T1 = int, // expected-note{{previous default template argument defined here}}
+         class T2>  // expected-error{{template parameter missing a default argument}}
+  class B1;
+
+template<template<class> class = Y1, // expected-note{{previous default template argument defined here}}
+         template<class> class> // expected-error{{template parameter missing a default argument}}
+  class B1t;
+
+template<int N = 5,  // expected-note{{previous default template argument defined here}}
+         int M>  // expected-error{{template parameter missing a default argument}}
+  class B1n;
diff --git a/test/CXX/temp/temp.param/p12.cpp b/test/CXX/temp/temp.param/p12.cpp
new file mode 100644
index 0000000..7be3879
--- /dev/null
+++ b/test/CXX/temp/temp.param/p12.cpp
@@ -0,0 +1,39 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s 
+template<typename> struct Y1; // expected-note{{too few template parameters in template template argument}}
+template<typename, int> struct Y2;
+
+// C++ [temp.param]p12:
+template<class T1, 
+         class T2 = int> // expected-note{{previous default template argument defined here}}
+  class B3;
+template<class T1, typename T2> class B3;
+template<class T1, 
+         typename T2 = float> // expected-error{{template parameter redefines default argument}}
+  class B3;
+
+template<template<class, int> class, 
+         template<class> class = Y1> // expected-note{{previous default template argument defined here}}
+  class B3t;
+
+template<template<class, int> class, template<class> class> class B3t;
+
+template<template<class, int> class, 
+         template<class> class = Y1> // expected-error{{template parameter redefines default argument}}
+  class B3t;
+
+template<int N, 
+         int M = 5> // expected-note{{previous default template argument defined here}}
+  class B3n;
+
+template<int N, int M> class B3n;
+
+template<int N, 
+         int M = 7>  // expected-error{{template parameter redefines default argument}}
+  class B3n;
+
+// Check validity of default arguments
+template<template<class, int> class // expected-note{{previous template template parameter is here}}
+           = Y1> // expected-error{{template template argument has different template parameters than its corresponding template template parameter}}
+  class C1 {};
+
+C1<> c1; // expected-note{{while checking a default template argument}}
diff --git a/test/CXX/temp/temp.param/p13.cpp b/test/CXX/temp/temp.param/p13.cpp
new file mode 100644
index 0000000..7e7dbe5
--- /dev/null
+++ b/test/CXX/temp/temp.param/p13.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s 
+
+// The scope of atemplate-parameterextends from its point of
+// declaration until the end of its template. In particular, a
+// template-parameter can be used in the declaration of subsequent
+// template-parameters and their default arguments.
+
+template<class T, T* p, class U = T> class X { /* ... */ }; 
+// FIXME: template<class T> void f(T* p = new T); 
+
+// Check for bogus template parameter shadow warning.
+template<template<class T> class,
+         template<class T> class>
+  class B1noshadow;
diff --git a/test/CXX/temp/temp.param/p14.cpp b/test/CXX/temp/temp.param/p14.cpp
new file mode 100644
index 0000000..a6c53c1
--- /dev/null
+++ b/test/CXX/temp/temp.param/p14.cpp
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s 
+// XFAIL: *
+
+// A template-parameter shall not be used in its own default argument.
+template<typename T = typename T::type> struct X; // expected-error{{default}}
diff --git a/test/CXX/temp/temp.param/p15-cxx0x.cpp b/test/CXX/temp/temp.param/p15-cxx0x.cpp
new file mode 100644
index 0000000..0ce6699
--- /dev/null
+++ b/test/CXX/temp/temp.param/p15-cxx0x.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++0x -verify %s
+template<typename T> struct X;
+template<int I> struct Y;
+
+X<X<int>> *x1;
+
+Y<(1 >> 2)> *y1;
+Y<1 >> 2> *y2; // FIXME: expected-error{{expected unqualified-id}}
+
+X<X<X<X<X<int>>>>> *x2;
+
+template<> struct X<int> { };
+typedef X<int> X_int;
+struct Z : X_int { };
+
+void f(const X<int> x) {
+  (void)reinterpret_cast<X<int>>(x); // expected-error{{reinterpret_cast from}}
+  (void)reinterpret_cast<X<X<X<int>>>>(x); // expected-error{{reinterpret_cast from}}
+
+  X<X<int>> *x1;
+}
+
diff --git a/test/CXX/temp/temp.param/p15.cpp b/test/CXX/temp/temp.param/p15.cpp
new file mode 100644
index 0000000..1308779
--- /dev/null
+++ b/test/CXX/temp/temp.param/p15.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++98 -verify %s
+template<typename T> struct X;
+template<int I> struct Y;
+
+X<X<int> > *x1;
+X<X<int>> *x2; // expected-error{{a space is required between consecutive right angle brackets (use '> >')}}
+
+X<X<X<X<int>> // expected-error{{a space is required between consecutive right angle brackets (use '> >')}}
+    >> *x3;   // expected-error{{a space is required between consecutive right angle brackets (use '> >')}}
+
+Y<(1 >> 2)> *y1;
+Y<1 >> 2> *y2; // expected-warning{{use of right-shift operator ('>>') in template argument will require parentheses in C++0x}}
diff --git a/test/CXX/temp/temp.param/p2.cpp b/test/CXX/temp/temp.param/p2.cpp
new file mode 100644
index 0000000..41868c5
--- /dev/null
+++ b/test/CXX/temp/temp.param/p2.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// There is no semantic difference between class and typename in a
+// template-parameter. typename followed by an unqualified-id names a
+// template type parameter.
+template<class T> struct X;
+template<typename T> struct X;
+
+// typename followed by aqualified-id denotes the type in a non-type
+// parameter-declaration.
+template<typename T, typename T::type Value> struct Y0;
+template<typename T, typename X<T>::type Value> struct Y1;
+
+// A storage class shall not be specified in a template-parameter declaration.
+template<static int Value> struct Z; // FIXME: expect an error
+
+// FIXME: add the example from p2
diff --git a/test/CXX/temp/temp.param/p3.cpp b/test/CXX/temp/temp.param/p3.cpp
new file mode 100644
index 0000000..dc40c4b
--- /dev/null
+++ b/test/CXX/temp/temp.param/p3.cpp
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// A type-parameter defines its identifier to be a type-name (if
+// declared with class or typename) or template-name (if declared with
+// template) in the scope of the template declaration.
+template<typename T> struct X0 {
+  T* value;
+};
+
+template<template<class T> class Y> struct X1 {
+  Y<int> value;
+};
+
+// [Note: because of the name lookup rules, a template-parameter that
+// could be interpreted as either a non-type template-parameter or a
+// type-parameter (because its identifier is the name of an already
+// existing class) is taken as a type-parameter. For example, 
+class T { /* ... */ };  // expected-note{{candidate constructor (the implicit copy constructor) not viable}}
+int i; 
+
+template<class T, T i> struct X2 {
+  void f(T t) 
+  { 
+    T t1 = i; //template-parameters T and i 
+    ::T t2 = ::i; // global namespace members T and i  \
+    // expected-error{{no viable conversion}}
+  } 
+};
+
+namespace PR6831 {
+  namespace NA { struct S; }
+  namespace NB { struct S; }
+
+  using namespace NA;
+  using namespace NB;
+
+  template <typename S> void foo();
+  template <int S> void bar();
+  template <template<typename> class S> void baz();
+}
diff --git a/test/CXX/temp/temp.param/p4.cpp b/test/CXX/temp/temp.param/p4.cpp
new file mode 100644
index 0000000..5ec402a
--- /dev/null
+++ b/test/CXX/temp/temp.param/p4.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+class X;
+
+// C++ [temp.param]p4
+typedef int INT;
+enum E { enum1, enum2 };
+template<int N> struct A1;
+template<INT N, INT M> struct A2;
+template<enum E x, E y> struct A3;
+template<int &X> struct A4;
+template<int *Ptr> struct A5;
+template<int (&f)(int, int)> struct A6;
+template<int (*fp)(float, double)> struct A7;
+template<int X::*pm> struct A8;
+template<float (X::*pmf)(float, int)> struct A9;
+template<typename T, T x> struct A10;
+
+template<float f> struct A11; // expected-error{{a non-type template parameter cannot have type 'float'}}
+
+template<void *Ptr> struct A12; // expected-error{{a non-type template parameter cannot have type 'void *'}}
diff --git a/test/CXX/temp/temp.param/p7.cpp b/test/CXX/temp/temp.param/p7.cpp
new file mode 100644
index 0000000..13f0367
--- /dev/null
+++ b/test/CXX/temp/temp.param/p7.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// A non-type template-parameter shall not be declared to have
+// floating point, class, or void type.
+struct A;
+
+template<double d> class X; // expected-error{{cannot have type}}
+template<double* pd> class Y; //OK 
+template<double& rd> class Z; //OK 
+
+template<A a> class X0; // expected-error{{cannot have type}}
+
+typedef void VOID;
+template<VOID a> class X01; // expected-error{{cannot have type}}
+
diff --git a/test/CXX/temp/temp.param/p8.cpp b/test/CXX/temp/temp.param/p8.cpp
new file mode 100644
index 0000000..fed048c
--- /dev/null
+++ b/test/CXX/temp/temp.param/p8.cpp
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<int X[10]> struct A;
+template<int *X> struct A;
+template<int f(float, double)> struct B;
+typedef float FLOAT;
+template<int (*f)(FLOAT, double)> struct B;
diff --git a/test/CXX/temp/temp.param/p9.cpp b/test/CXX/temp/temp.param/p9.cpp
new file mode 100644
index 0000000..625477c
--- /dev/null
+++ b/test/CXX/temp/temp.param/p9.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++98 -verify %s
+
+// A default template-argument shall not be specified in a function
+// template declaration or a function template definition
+template<typename T = int> // expected-error{{cannot have a default argument}}
+  void foo0(T); 
+template<typename T = int> // expected-error{{cannot have a default argument}} 
+  void foo1(T) { } 
+
+// [...] nor in the template-parameter-list of the definition of a
+// member of a class template.
+template<int N>
+struct X0 {
+  void f();
+};
+
+template<int N = 0> // expected-error{{cannot add a default template argument}}
+void X0<N>::f() { } 
+
+class X1 {
+  template<template<int> class TT = X0> // expected-error{{not permitted on a friend template}}
+  friend void f2();
+};
diff --git a/test/CXX/temp/temp.res/temp.dep.res/temp.point/p1.cpp b/test/CXX/temp/temp.res/temp.dep.res/temp.point/p1.cpp
new file mode 100644
index 0000000..75580d2
--- /dev/null
+++ b/test/CXX/temp/temp.res/temp.dep.res/temp.point/p1.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// XFAIL: *
+
+// Note: we fail this test because we perform template instantiation
+// at the end of the translation unit, so argument-dependent lookup
+// finds functions that occur after the point of instantiation. Note
+// that GCC fails this test; EDG passes the test in strict mode, but
+// not in relaxed mode.
+namespace N {
+  struct A { };
+  struct B : public A { };
+
+  int& f0(A&);
+}
+
+template<typename T, typename Result>
+struct X0 {
+  void test_f0(T t) {
+    Result r = f0(t);
+  };
+};
+
+void test_f0() {
+  X0<N::A, int&> xA;
+  xA.test_f0(N::A());
+  X0<N::B, int&> xB;
+  xB.test_f0(N::B());
+}
+
+namespace N {
+  char& f0(B&);
+}
diff --git a/test/CXX/temp/temp.res/temp.dep/p3.cpp b/test/CXX/temp/temp.res/temp.dep/p3.cpp
new file mode 100644
index 0000000..c41a4c6
--- /dev/null
+++ b/test/CXX/temp/temp.res/temp.dep/p3.cpp
@@ -0,0 +1,43 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+struct A0 {
+  struct K { };
+};
+
+template <typename T> struct B0: A0 {
+  static void f() {
+    K k;
+  }
+};
+
+namespace E1 {
+  typedef double A; 
+
+  template<class T> class B {
+    typedef int A; 
+  };
+
+  template<class T> 
+  struct X : B<T> {
+    A* blarg(double *dp) {
+      return dp;
+    }
+  };
+}
+
+namespace E2 {
+  struct A { 
+    struct B;
+    int *a;
+    int Y;
+  };
+    
+  int a;
+  template<class T> struct Y : T { 
+    struct B { /* ... */ };
+    B b; 
+    void f(int i) { a = i; } 
+    Y* p;
+  }; 
+  
+  Y<A> ya;
+}
diff --git a/test/CXX/temp/temp.res/temp.local/p1.cpp b/test/CXX/temp/temp.res/temp.local/p1.cpp
new file mode 100644
index 0000000..1ad4464
--- /dev/null
+++ b/test/CXX/temp/temp.res/temp.local/p1.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// C++0x [temp.local]p1:
+//   Like normal (non-template) classes, class templates have an
+//   injected-class-name (Clause 9). The injected-class-name can be used with
+//   or without a template-argument-list. When it is used without
+//   a template-argument-list, it is equivalent to the injected-class-name
+//   followed by the template-parameters of the class template enclosed in <>.
+
+template <typename T> struct X0 {
+  X0();
+  ~X0();
+  X0 f(const X0&);
+};
+
+// Test non-type template parameters.
+template <int N1, const int& N2, const int* N3> struct X1 {
+  X1();
+  ~X1();
+  X1 f(const X1& x1a) { X1 x1b(x1a); return x1b; }
+};
+
+//   When it is used with a template-argument-list, it refers to the specified
+//   class template specialization, which could be the current specialization
+//   or another specialization.
+// FIXME: Test this clause.
+
+int i = 42;
+void test() {
+  X0<int> x0; (void)x0;
+  X1<42, i, &i> x1; (void)x1;
+}
diff --git a/test/CXX/temp/temp.res/temp.local/p3.cpp b/test/CXX/temp/temp.res/temp.local/p3.cpp
new file mode 100644
index 0000000..88f8963
--- /dev/null
+++ b/test/CXX/temp/temp.res/temp.local/p3.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -verify %s
+
+template <class T> struct Base { // expected-note 4 {{member found by ambiguous name lookup}}
+  static void f();
+}; 
+
+struct X0 { };
+
+template <class T> struct Derived: Base<int>, Base<char> {
+  typename Derived::Base b;	// expected-error{{member 'Base' found in multiple base classes of different types}}
+  typename Derived::Base<double> d;	// OK
+
+  void g(X0 *t) {
+    t->Derived::Base<T>::f();
+    t->Base<T>::f();
+    t->Base::f(); // expected-error{{member 'Base' found in multiple base classes of different types}} \
+    // expected-error{{no member named 'f' in 'X0'}} \
+    // expected-error{{expected a class or namespace}}
+  }
+};
+
+namespace PR6717 {
+  template <typename T>
+  class WebVector {
+  }
+
+    WebVector(const WebVector<T>& other) { } 
+
+  template <typename C>
+  WebVector<T>& operator=(const C& other) { } // expected-error{{unknown type name 'WebVector'}} \
+  // expected-error{{unqualified-id}}
+}
diff --git a/test/CXX/temp/temp.res/temp.local/p7.cpp b/test/CXX/temp/temp.res/temp.local/p7.cpp
new file mode 100644
index 0000000..bd05e75
--- /dev/null
+++ b/test/CXX/temp/temp.res/temp.local/p7.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<class T> struct A { 
+  int B;
+  int f();
+}; 
+
+template<class B> int A<B>::f() {
+  return B;
+}
diff --git a/test/CXX/temp/temp.res/temp.local/p8.cpp b/test/CXX/temp/temp.res/temp.local/p8.cpp
new file mode 100644
index 0000000..5d9d509
--- /dev/null
+++ b/test/CXX/temp/temp.res/temp.local/p8.cpp
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace N { 
+  enum { C };
+  template<class T> class B {
+    void f(T);
+  }; 
+}
+
+template<class C> void N::B<C>::f(C) {
+  C b;
+}
+
+namespace N {
+  enum { D };
+  namespace M {
+    enum { C , D };
+    template<typename C> class X {
+      template<typename U> void f(C, U);
+
+      template<typename D> void g(C, D) {
+        C c;
+        D d;
+      }
+    };
+
+    struct Y {
+      template<typename U> void f(U);      
+    };
+  }
+
+  struct Y {
+    template<typename D> void f(D);
+  };
+}
+
+template<typename C> 
+template<typename D>
+void N::M::X<C>::f(C, D) {
+  C c;
+  D d;
+}
+
+template<typename C>
+void N::M::Y::f(C) {
+  C c;
+}
+
+template<typename D> 
+void N::Y::f(D) {
+  D d;
+}
+
diff --git a/test/CXX/temp/temp.res/temp.local/p9.cpp b/test/CXX/temp/temp.res/temp.local/p9.cpp
new file mode 100644
index 0000000..9ca8d88
--- /dev/null
+++ b/test/CXX/temp/temp.res/temp.local/p9.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+struct A { 
+  struct B { void f(); }; 
+  int a; 
+  int Y;
+};
+
+template<class B, class a> struct X : A { 
+  B b;  // A's B 
+  a c;  // expected-error{{unknown type name 'a'}} 
+
+  void g() {
+    b.g(); // expected-error{{no member named 'g' in 'A::B'}}
+  }
+};
diff --git a/test/CXX/temp/temp.spec/p5.cpp b/test/CXX/temp/temp.spec/p5.cpp
new file mode 100644
index 0000000..ba99dd7
--- /dev/null
+++ b/test/CXX/temp/temp.spec/p5.cpp
@@ -0,0 +1,46 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T> inline void f(T) { }
+template void f(int); // expected-note{{previous explicit instantiation}}
+template void f(int); // expected-error{{duplicate explicit instantiation}}
+
+template<typename T>
+struct X0 {
+  union Inner { };
+  
+  void f(T) { }
+  
+  static T value;
+};
+
+template<typename T>
+T X0<T>::value = 3.14;
+
+template struct X0<int>; // expected-note{{previous explicit instantiation}}
+template struct X0<int>; // expected-error{{duplicate explicit instantiation}}
+
+template void X0<float>::f(float); // expected-note{{previous explicit instantiation}}
+template void X0<float>::f(float); // expected-error{{duplicate explicit instantiation}}
+
+template union X0<float>::Inner; // expected-note{{previous explicit instantiation}}
+template union X0<float>::Inner; // expected-error{{duplicate explicit instantiation}}
+
+template float X0<float>::value; // expected-note{{previous explicit instantiation}}
+template float X0<float>::value; // expected-error{{duplicate explicit instantiation}}
+
+// Make sure that we don't get tricked by redeclarations of nested classes.
+namespace NestedClassRedecls {
+  template<typename T>
+  struct X {
+    struct Nested;
+    friend struct Nested;
+
+    struct Nested { 
+      Nested() {}
+    } nested;
+  };
+
+  X<int> xi;
+
+  template struct X<int>;
+}
diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p1.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p1.cpp
new file mode 100644
index 0000000..3843c0d
--- /dev/null
+++ b/test/CXX/temp/temp.spec/temp.expl.spec/p1.cpp
@@ -0,0 +1,99 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// This test creates cases where implicit instantiations of various entities
+// would cause a diagnostic, but provides expliict specializations for those
+// entities that avoid the diagnostic. The intent is to verify that 
+// implicit instantiations do not occur (because the explicit specialization 
+// is used instead).
+struct NonDefaultConstructible {
+  NonDefaultConstructible(int);
+};
+
+
+// C++ [temp.expl.spec]p1:
+//   An explicit specialization of any of the following:
+
+//     -- function template
+template<typename T> void f0(T) {
+  T t;
+}
+
+template<> void f0(NonDefaultConstructible) { }
+
+void test_f0(NonDefaultConstructible NDC) {
+  f0(NDC);
+}
+
+//     -- class template
+template<typename T>
+struct X0 {
+  static T member;
+  
+  void f1(T t) {
+    t = 17;
+  }
+  
+  struct Inner : public T { };
+  
+  template<typename U>
+  struct InnerTemplate : public T { };
+  
+  template<typename U>
+  void ft1(T t, U u);
+};
+
+template<typename T> 
+template<typename U>
+void X0<T>::ft1(T t, U u) {
+  t = u;
+}
+
+template<typename T> T X0<T>::member;
+
+template<> struct X0<void> { };
+X0<void> test_X0;
+  
+
+//     -- member function of a class template
+template<> void X0<void*>::f1(void *) { }
+
+void test_spec(X0<void*> xvp, void *vp) {
+  xvp.f1(vp);
+}
+
+//     -- static data member of a class template
+template<> 
+NonDefaultConstructible X0<NonDefaultConstructible>::member = 17;
+
+NonDefaultConstructible &get_static_member() {
+  return X0<NonDefaultConstructible>::member;
+}
+
+//    -- member class of a class template
+template<>
+struct X0<void*>::Inner { };
+
+X0<void*>::Inner inner0;
+
+//    -- member class template of a class template
+template<>
+template<>
+struct X0<void*>::InnerTemplate<int> { };
+
+X0<void*>::InnerTemplate<int> inner_template0;
+
+//    -- member function template of a class template
+template<>
+template<>
+void X0<void*>::ft1(void*, const void*) { }
+
+void test_func_template(X0<void *> xvp, void *vp, const void *cvp) {
+  xvp.ft1(vp, cvp);
+}
+
+// example from the standard:
+template<class T> class stream;
+template<> class stream<char> { /* ... */ };
+template<class T> class Array { /* ... */ }; 
+template<class T> void sort(Array<T>& v) { /* ... */ }
+template<> void sort<char*>(Array<char*>&) ;
diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p10.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p10.cpp
new file mode 100644
index 0000000..b81c1e7
--- /dev/null
+++ b/test/CXX/temp/temp.spec/temp.expl.spec/p10.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<class T> class X; 
+template<> class X<int>; // expected-note{{forward}}
+X<int>* p; 
+
+X<int> x; // expected-error{{incomplete type}}
diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p11.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p11.cpp
new file mode 100644
index 0000000..5fa2f62
--- /dev/null
+++ b/test/CXX/temp/temp.spec/temp.expl.spec/p11.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<class T> class Array { /* ... */ }; 
+template<class T> void sort(Array<T>& v);
+
+// explicit specialization for sort(Array<int>&) 
+// with deduced template-argument of type int 
+template<> void sort(Array<int>&);
diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p13.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p13.cpp
new file mode 100644
index 0000000..fb6d1be
--- /dev/null
+++ b/test/CXX/temp/temp.spec/temp.expl.spec/p13.cpp
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -fsyntax-only %s
+
+template<typename T> void f(T);
+
+template<> void f(int) { }
+void f(int) { }
diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p14.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p14.cpp
new file mode 100644
index 0000000..121cb8e
--- /dev/null
+++ b/test/CXX/temp/temp.spec/temp.expl.spec/p14.cpp
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s 
+
+template<class T> void f(T) { /* ... */ }
+template<class T> inline void g(T) { /* ... */ }
+
+// CHECK: define void @_Z1gIiEvT_
+template<> void g<>(int) { /* ... */ }
+
+template<class T>
+struct X {
+  void f() { }
+  void g();
+  void h();
+};
+
+template<class T>
+void X<T>::g() {
+}
+
+template<class T>
+inline void X<T>::h() {
+}
+
+// CHECK: define void @_ZN1XIiE1fEv
+template<> void X<int>::f() { }
+
+// CHECK: define void @_ZN1XIiE1hEv
+template<> void X<int>::h() { }
+
+// CHECK: define linkonce_odr void @_Z1fIiEvT_
+template<> inline void f<>(int) { /* ... */ } 
+
+// CHECK: define linkonce_odr void @_ZN1XIiE1gEv
+template<> inline void X<int>::g() { }
+
+void test(X<int> xi) {
+  f(17);
+  g(17);
+  xi.f();
+  xi.g();
+  xi.h();
+}
diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p15.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p15.cpp
new file mode 100644
index 0000000..a5ecf5f
--- /dev/null
+++ b/test/CXX/temp/temp.spec/temp.expl.spec/p15.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct NonDefaultConstructible {
+  NonDefaultConstructible(const NonDefaultConstructible&); // expected-note{{candidate constructor}}
+};
+
+template<typename T, typename U>
+struct X {
+  static T member;
+};
+
+template<typename T, typename U>
+T X<T, U>::member; // expected-error{{no matching constructor}}
+
+// Okay; this is a declaration, not a definition.
+template<>
+NonDefaultConstructible X<NonDefaultConstructible, long>::member;
+
+NonDefaultConstructible &test(bool b) {
+  return b? X<NonDefaultConstructible, int>::member // expected-note{{instantiation}}
+          : X<NonDefaultConstructible, long>::member;
+}
diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p16.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p16.cpp
new file mode 100644
index 0000000..2f9a3cb
--- /dev/null
+++ b/test/CXX/temp/temp.spec/temp.expl.spec/p16.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -fsyntax-only %s
+template<class T> struct A { 
+  void f(T);
+  template<class X1> void g1(T, X1); 
+  template<class X2> void g2(T, X2); 
+  void h(T) { }
+};
+
+// specialization 
+template<> void A<int>::f(int);
+
+// out of class member template definition 
+template<class T> template<class X1> void A<T>::g1(T, X1) { }
+
+// member template specialization 
+template<> template<class X1> void A<int>::g1(int, X1);
+
+// member template specialization 
+template<> template<>
+  void A<int>::g1(int, char);	// X1 deduced as char 
+
+template<> template<>
+  void A<int>::g2<char>(int, char); // X2 specified as char 
+                                    // member specialization even if defined in class definition
+
+template<> void A<int>::h(int) { }
diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p17.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p17.cpp
new file mode 100644
index 0000000..88cfc5d
--- /dev/null
+++ b/test/CXX/temp/temp.spec/temp.expl.spec/p17.cpp
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<class T1> 
+class A {
+  template<class T2> class B {
+    void mf();
+  };
+};
+
+template<> template<> class A<int>::B<double>; 
+template<> template<> void A<char>::B<char>::mf();
+
+template<> void A<char>::B<int>::mf(); // expected-error{{requires 'template<>'}}
+
+namespace test1 {
+  template <class> class A {
+    static int foo;
+    static int bar;
+  };
+  typedef A<int> AA;
+  
+  template <> int AA::foo = 0; 
+  int AA::bar = 1; // expected-error {{template specialization requires 'template<>'}}
+  int A<float>::bar = 2; // expected-error {{template specialization requires 'template<>'}}
+
+  template <> class A<double> { 
+  public:
+    static int foo; // expected-note{{attempt to specialize}}
+    static int bar;    
+  };
+
+  typedef A<double> AB;
+  template <> int AB::foo = 0; // expected-error{{extraneous 'template<>'}} \
+                               // expected-error{{does not specialize}}
+  int AB::bar = 1;
+}
diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p18.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p18.cpp
new file mode 100644
index 0000000..4d175a8
--- /dev/null
+++ b/test/CXX/temp/temp.spec/temp.expl.spec/p18.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<class T1> class A { 
+  template<class T2> class B {
+    template<class T3> void mf1(T3); 
+    void mf2();
+  };
+}; 
+
+template<> template<class X>
+class A<long>::B { }; 
+
+template<> template<> template<class T>
+  void A<int>::B<double>::mf1(T t) { } 
+
+template<> template<> template<class T>
+void A<long>::B<double>::mf1(T t) { } // expected-error{{does not match}}
+
+// FIXME: This diagnostic could probably be better.
+template<class Y> template<>
+  void A<Y>::B<double>::mf2() { } // expected-error{{does not refer}}
diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p19.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p19.cpp
new file mode 100644
index 0000000..1c2ea7e
--- /dev/null
+++ b/test/CXX/temp/temp.spec/temp.expl.spec/p19.cpp
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T>
+struct X {
+  template<typename U> struct Inner { };
+  
+  template<typename U> void f(T, U) { }
+};
+
+template<> template<typename U>
+struct X<int>::Inner {
+  U member;
+};
+
+template<> template<typename U>
+void X<int>::f(int x, U y) { 
+  x = y; // expected-error{{incompatible type}}
+}
+
+void test(X<int> xi, X<long> xl, float *fp) {
+  X<int>::Inner<float*> xii;
+  xii.member = fp;
+  xi.f(17, 25);
+  xi.f(17, 3.14159);
+  xi.f(17, fp); // expected-note{{instantiation}}
+  X<long>::Inner<float*> xli;
+  
+  xli.member = fp; // expected-error{{no member}}
+  xl.f(17, fp); // okay
+}
diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p2.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p2.cpp
new file mode 100644
index 0000000..654f5ab
--- /dev/null
+++ b/test/CXX/temp/temp.spec/temp.expl.spec/p2.cpp
@@ -0,0 +1,239 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// This test creates cases where implicit instantiations of various entities
+// would cause a diagnostic, but provides expliict specializations for those
+// entities that avoid the diagnostic. The specializations are alternately
+// declarations and definitions, and the intent of this test is to verify
+// that we allow specializations only in the appropriate namespaces (and
+// nowhere else).
+struct NonDefaultConstructible {
+  NonDefaultConstructible(int);
+};
+
+
+// C++ [temp.expl.spec]p1:
+//   An explicit specialization of any of the following:
+
+//     -- function template
+namespace N0 {
+  template<typename T> void f0(T) { // expected-note{{here}}
+    T t;
+  }
+
+  template<> void f0(NonDefaultConstructible) { }
+
+  void test_f0(NonDefaultConstructible NDC) {
+    f0(NDC);
+  }
+  
+  template<> void f0(int);
+  template<> void f0(long);
+}
+
+template<> void N0::f0(int) { } // okay
+
+namespace N1 {
+  template<> void N0::f0(long) { } // expected-error{{not in a namespace enclosing}}
+}
+
+template<> void N0::f0(double) { } // expected-error{{originally be declared}}
+
+struct X1 {
+  template<typename T> void f(T);
+  
+  template<> void f(int); // expected-error{{in class scope}}
+};
+
+//     -- class template
+namespace N0 {
+  
+template<typename T>
+struct X0 { // expected-note 2{{here}}
+  static T member; // expected-note{{here}}
+  
+  void f1(T t) { // expected-note{{explicitly specialized declaration is here}}
+    t = 17;
+  }
+  
+  struct Inner : public T { }; // expected-note 3{{here}}
+  
+  template<typename U>
+  struct InnerTemplate : public T { }; // expected-note 2{{explicitly specialized}} \
+   // expected-error{{base specifier}}
+  
+  template<typename U>
+  void ft1(T t, U u); // expected-note{{explicitly specialized}}
+};
+
+}
+
+template<typename T> 
+template<typename U>
+void N0::X0<T>::ft1(T t, U u) {
+  t = u;
+}
+
+template<typename T> T N0::X0<T>::member;
+
+template<> struct N0::X0<void> { }; // expected-error{{originally}}
+N0::X0<void> test_X0;
+
+namespace N1 {
+  template<> struct N0::X0<const void> { }; // expected-error{{originally}}
+}
+
+namespace N0 {
+  template<> struct X0<volatile void>;
+}
+
+template<> struct N0::X0<volatile void> { 
+  void f1(void *);
+};
+
+//     -- member function of a class template
+template<> void N0::X0<void*>::f1(void *) { } // expected-error{{member function specialization}}
+
+void test_spec(N0::X0<void*> xvp, void *vp) {
+  xvp.f1(vp);
+}
+
+namespace N0 {
+  template<> void X0<volatile void>::f1(void *) { } // expected-error{{no function template matches}}
+
+  template<> void X0<const volatile void*>::f1(const volatile void*);
+}
+
+void test_x0_cvvoid(N0::X0<const volatile void*> x0, const volatile void *cvp) {
+  x0.f1(cvp); // okay: we've explicitly specialized
+}
+
+//     -- static data member of a class template
+namespace N0 {
+  // This actually tests p15; the following is a declaration, not a definition.
+  template<> 
+  NonDefaultConstructible X0<NonDefaultConstructible>::member;
+  
+  template<> long X0<long>::member = 17;
+
+  template<> float X0<float>::member;
+  
+  template<> double X0<double>::member;
+}
+
+NonDefaultConstructible &get_static_member() {
+  return N0::X0<NonDefaultConstructible>::member;
+}
+
+template<> int N0::X0<int>::member;  // expected-error{{originally}}
+
+template<> float N0::X0<float>::member = 3.14f;
+
+namespace N1 {
+  template<> double N0::X0<double>::member = 3.14; // expected-error{{not in a namespace enclosing}}
+}
+
+//    -- member class of a class template
+namespace N0 {
+  
+  template<>
+  struct X0<void*>::Inner { };
+
+  template<>
+  struct X0<int>::Inner { };
+
+  template<>
+  struct X0<unsigned>::Inner;
+
+  template<>
+  struct X0<float>::Inner;
+
+  template<>
+  struct X0<double>::Inner; // expected-note{{forward declaration}}
+}
+
+template<>
+struct N0::X0<long>::Inner { }; // expected-error{{originally}}
+
+template<>
+struct N0::X0<float>::Inner { };
+
+namespace N1 {
+  template<>
+  struct N0::X0<unsigned>::Inner { }; // expected-error{{member class specialization}}
+
+  template<>
+  struct N0::X0<unsigned long>::Inner { }; // expected-error{{member class specialization}}
+};
+
+N0::X0<void*>::Inner inner0;
+N0::X0<int>::Inner inner1;
+N0::X0<long>::Inner inner2;
+N0::X0<float>::Inner inner3;
+N0::X0<double>::Inner inner4; // expected-error{{incomplete}}
+
+//    -- member class template of a class template
+namespace N0 {
+  template<>
+  template<>
+  struct X0<void*>::InnerTemplate<int> { };
+  
+  template<> template<>
+  struct X0<int>::InnerTemplate<int>; // expected-note{{forward declaration}}
+
+  template<> template<>
+  struct X0<int>::InnerTemplate<long>;
+
+  template<> template<>
+  struct X0<int>::InnerTemplate<double>;
+}
+
+template<> template<>
+struct N0::X0<int>::InnerTemplate<long> { }; // okay
+
+template<> template<>
+struct N0::X0<int>::InnerTemplate<float> { }; // expected-error{{class template specialization}}
+
+namespace N1 {
+  template<> template<>
+  struct N0::X0<int>::InnerTemplate<double> { }; // expected-error{{enclosing}}
+}
+
+N0::X0<void*>::InnerTemplate<int> inner_template0;
+N0::X0<int>::InnerTemplate<int> inner_template1; // expected-error{{incomplete}}
+N0::X0<int>::InnerTemplate<long> inner_template2;
+N0::X0<int>::InnerTemplate<unsigned long> inner_template3; // expected-note{{instantiation}}
+
+//    -- member function template of a class template
+namespace N0 {
+  template<>
+  template<>
+  void X0<void*>::ft1(void*, const void*) { }
+  
+  template<> template<>
+  void X0<void*>::ft1(void *, int);
+
+  template<> template<>
+  void X0<void*>::ft1(void *, unsigned);
+
+  template<> template<>
+  void X0<void*>::ft1(void *, long);
+}
+
+template<> template<>
+void N0::X0<void*>::ft1(void *, unsigned) { } // okay
+
+template<> template<>
+void N0::X0<void*>::ft1(void *, float) { } // expected-error{{function template specialization}}
+
+namespace N1 {
+  template<> template<>
+  void N0::X0<void*>::ft1(void *, long) { } // expected-error{{enclosing}}
+}
+
+
+void test_func_template(N0::X0<void *> xvp, void *vp, const void *cvp,
+                        int i, unsigned u) {
+  xvp.ft1(vp, cvp);
+  xvp.ft1(vp, i);
+  xvp.ft1(vp, u);
+}
diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p20.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p20.cpp
new file mode 100644
index 0000000..86cdcf8
--- /dev/null
+++ b/test/CXX/temp/temp.spec/temp.expl.spec/p20.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename T>
+void f(T);
+
+template<typename T>
+struct A { };
+
+struct X {
+  template<> friend void f<int>(int); // expected-error{{in a friend}}
+  template<> friend class A<int>; // expected-error{{cannot be a friend}}
+  
+  friend void f<float>(float); // okay
+  friend class A<float>; // okay
+};
diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p21.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p21.cpp
new file mode 100644
index 0000000..ab26f40
--- /dev/null
+++ b/test/CXX/temp/temp.spec/temp.expl.spec/p21.cpp
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T>
+struct X {
+  void mf1(T);
+  template<typename U> void mf2(T, U); // expected-note{{previous}}
+};
+
+template<>
+void X<int>::mf1(int i = 17) // expected-error{{default}}
+{
+}
+
+template<> template<>
+void X<int>::mf2(int, int = 17) // expected-error{{default}}
+{ }
+
+template<> template<typename U> 
+void X<int>::mf2(int, U = U()) // expected-error{{default}}
+{
+}
+
+template<>
+struct X<float> {
+  void mf1(float);
+};
+
+void X<float>::mf1(float = 3.14f)  // okay
+{
+}
diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p3.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p3.cpp
new file mode 100644
index 0000000..84841cb
--- /dev/null
+++ b/test/CXX/temp/temp.spec/temp.expl.spec/p3.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace N {
+  template<class T> class X;
+}
+
+template<> class X<int> { /* ... */ };	// expected-error {{non-template class 'X'}}
+
+namespace N {
+  
+template<> class X<char*> { /* ... */ };	// OK: X is a template
+  
+}
diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p4.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p4.cpp
new file mode 100644
index 0000000..772aef6
--- /dev/null
+++ b/test/CXX/temp/temp.spec/temp.expl.spec/p4.cpp
@@ -0,0 +1,58 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct IntHolder { // expected-note{{here}} // expected-note 2{{candidate constructor (the implicit copy constructor)}}
+  IntHolder(int); // expected-note 2{{candidate constructor}}
+};
+
+template<typename T, typename U>
+struct X { // expected-note{{here}}
+  void f() { 
+    T t; // expected-error{{no matching}}
+  }
+
+  void g() { }
+  
+  struct Inner {  // expected-error{{implicit default}}
+    T value; 	// expected-note {{member is declared here}}
+  };
+  
+  static T value;
+};
+
+template<typename T, typename U>
+T X<T, U>::value; // expected-error{{no matching constructor}}
+
+IntHolder &test_X_IntHolderInt(X<IntHolder, int> xih) {
+  xih.g(); // okay
+  xih.f(); // expected-note{{instantiation}}
+  
+  X<IntHolder, int>::Inner inner; // expected-note {{first required here}}
+  
+  return X<IntHolder, int>::value; // expected-note{{instantiation}}
+}
+
+// Explicitly specialize the members of X<IntHolder, long> to not cause
+// problems with instantiation.
+template<>
+void X<IntHolder, long>::f() { }
+
+template<>
+struct X<IntHolder, long>::Inner {
+  Inner() : value(17) { }
+  IntHolder value;
+};
+
+template<>
+IntHolder X<IntHolder, long>::value = 17;
+
+IntHolder &test_X_IntHolderInt(X<IntHolder, long> xih) {
+  xih.g(); // okay
+  xih.f(); // okay, uses specialization
+  
+  X<IntHolder, long>::Inner inner; // okay, uses specialization
+  
+  return X<IntHolder, long>::value; // okay, uses specialization
+}
+
+template<>
+X<IntHolder, long>::X() { } // expected-error{{instantiated member}}
diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p5.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p5.cpp
new file mode 100644
index 0000000..512ea47
--- /dev/null
+++ b/test/CXX/temp/temp.spec/temp.expl.spec/p5.cpp
@@ -0,0 +1,61 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct IntHolder {
+  IntHolder(int);
+};
+
+template<typename T, typename U>
+struct X {
+  void f() { 
+    T t;
+  }
+  
+  void g() { }
+  
+  struct Inner { 
+    T value; 
+  };
+  
+  static T value;
+};
+
+template<typename T, typename U>
+T X<T, U>::value;
+
+// Explicitly specialize the members of X<IntHolder, long> to not cause
+// problems with instantiation, but only provide declarations (not definitions).
+template<>
+void X<IntHolder, long>::f();
+
+template<>
+struct X<IntHolder, long>::Inner; // expected-note{{forward declaration}}
+
+template<>
+IntHolder X<IntHolder, long>::value;
+
+IntHolder &test_X_IntHolderInt(X<IntHolder, long> xih) {
+  xih.g(); // okay
+  xih.f(); // okay, uses specialization
+  
+  X<IntHolder, long>::Inner inner; // expected-error {{incomplete}}
+  
+  return X<IntHolder, long>::value; // okay, uses specialization
+}
+
+
+template<class T> struct A {
+  void f(T) { /* ... */ }
+};
+
+template<> struct A<int> { 
+  void f(int);
+};
+
+void h() {
+  A<int> a; 
+  a.f(16); // A<int>::f must be defined somewhere
+}
+
+// explicit specialization syntax not used for a member of 
+// explicitly specialized class template specialization 
+void A<int>::f(int) { /* ... */ }
diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p6.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p6.cpp
new file mode 100644
index 0000000..f539471
--- /dev/null
+++ b/test/CXX/temp/temp.spec/temp.expl.spec/p6.cpp
@@ -0,0 +1,63 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T>
+struct X0 {
+  void f();
+  
+  template<typename U>
+  void g(U);
+  
+  struct Nested {
+  };
+  
+  static T member;
+};
+
+int &use_X0_int(X0<int> x0i,  // expected-note{{implicit instantiation first required here}}
+                int i) {
+  x0i.f(); // expected-note{{implicit instantiation first required here}}
+  x0i.g(i); // expected-note{{implicit instantiation first required here}}
+  X0<int>::Nested nested; // expected-note{{implicit instantiation first required here}}
+  return X0<int>::member; // expected-note{{implicit instantiation first required here}}
+}
+
+template<>
+void X0<int>::f() { // expected-error{{after instantiation}}
+}
+
+template<> template<>
+void X0<int>::g(int) { // expected-error{{after instantiation}}
+}
+
+template<>
+struct X0<int>::Nested { }; // expected-error{{after instantiation}}
+
+template<>
+int X0<int>::member = 17; // expected-error{{after instantiation}}
+
+template<>
+struct X0<int> { }; // expected-error{{after instantiation}}
+
+// Example from the standard
+template<class T> class Array { /* ... */ }; 
+
+template<class T> void sort(Array<T>& v) { /* ... */ }
+
+struct String {};
+
+void f(Array<String>& v) {
+  
+  sort(v); // expected-note{{required}}
+           // use primary template 
+           // sort(Array<T>&), T is String
+}
+
+template<> void sort<String>(Array<String>& v); // // expected-error{{after instantiation}}
+template<> void sort<>(Array<char*>& v);	// OK: sort<char*> not yet used
+
+namespace PR6160 {
+  template<typename T> void f(T);
+  template<> void f(int);
+  extern template void f(int);
+  template<> void f(int) { }
+}
diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p9.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p9.cpp
new file mode 100644
index 0000000..d4ce01f
--- /dev/null
+++ b/test/CXX/temp/temp.spec/temp.expl.spec/p9.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace N { 
+  template<class T> class X { /* ... */ }; 
+  template<class T> class Y { /* ... */ };
+  template<> class X<int> { /* ... */ }; 
+  template<> class Y<double>;
+  
+  const unsigned NumElements = 17;
+} 
+
+template<> class N::Y<double> { 
+  int array[NumElements];
+};
diff --git a/test/CXX/temp/temp.spec/temp.explicit/p1-0x.cpp b/test/CXX/temp/temp.spec/temp.explicit/p1-0x.cpp
new file mode 100644
index 0000000..a4cacea
--- /dev/null
+++ b/test/CXX/temp/temp.spec/temp.explicit/p1-0x.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++0x -verify %s
+
+template<typename T>
+struct X {
+  void f() {}
+};
+
+template inline void X<int>::f(); // expected-error{{'inline'}}
+
+// FIXME: test constexpr
diff --git a/test/CXX/temp/temp.spec/temp.explicit/p1-emit.cpp b/test/CXX/temp/temp.spec/temp.explicit/p1-emit.cpp
new file mode 100644
index 0000000..d8f7b52
--- /dev/null
+++ b/test/CXX/temp/temp.spec/temp.explicit/p1-emit.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -emit-llvm -triple x86_64-apple-darwin10 -o - %s | FileCheck %s
+template<typename T>
+struct X {
+  static T member1;
+  static T member2;
+  static T member3;
+};
+
+template<typename T>
+T X<T>::member1;
+
+template<typename T>
+T X<T>::member2 = 17;
+
+// CHECK: @_ZN1XIiE7member1E = weak global i32 0
+template int X<int>::member1;
+
+// CHECK: @_ZN1XIiE7member2E = weak global i32 17
+template int X<int>::member2;
+
+// For implicit instantiation of 
+long& get(bool Cond1, bool Cond2) {
+  // CHECK: @_ZN1XIlE7member1E = weak global i64 0
+  // CHECK: @_ZN1XIlE7member2E = weak global i64 17
+  // CHECK: @_ZN1XIlE7member3E = external global i64
+  return Cond1? X<long>::member1 
+       : Cond2? X<long>::member2
+              : X<long>::member3;
+}
diff --git a/test/CXX/temp/temp.spec/temp.explicit/p1.cpp b/test/CXX/temp/temp.spec/temp.explicit/p1.cpp
new file mode 100644
index 0000000..b426339
--- /dev/null
+++ b/test/CXX/temp/temp.spec/temp.explicit/p1.cpp
@@ -0,0 +1,89 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct C { };
+
+template<typename T>
+struct X0 {
+  T value; // expected-error{{incomplete}}
+};
+
+// Explicitly instantiate a class template specialization
+template struct X0<int>;
+template struct X0<void>; // expected-note{{instantiation}}
+
+// Explicitly instantiate a function template specialization
+template<typename T>
+void f0(T t) {
+  ++t; // expected-error{{cannot increment}}
+}
+
+template void f0(int);
+template void f0<long>(long);
+template void f0<>(unsigned);
+template void f0(int C::*); // expected-note{{instantiation}}
+
+// Explicitly instantiate a member template specialization
+template<typename T>
+struct X1 {
+  template<typename U>
+  struct Inner {
+    T member1;
+    U member2; // expected-error{{incomplete}}
+  };
+  
+  template<typename U>
+  void f(T& t, U u) {
+    t = u; // expected-error{{incompatible}}
+  }
+};
+
+template struct X1<int>::Inner<float>;
+template struct X1<int>::Inner<double>;
+template struct X1<int>::Inner<void>; // expected-note{{instantiation}}
+
+template void X1<int>::f(int&, float);
+template void X1<int>::f<long>(int&, long);
+template void X1<int>::f<>(int&, double);
+template void X1<int>::f<>(int&, int*); // expected-note{{instantiation}}
+
+// Explicitly instantiate members of a class template
+struct Incomplete; // expected-note{{forward declaration}}
+struct NonDefaultConstructible { // expected-note{{candidate constructor (the implicit copy constructor) not viable}}
+  NonDefaultConstructible(int); // expected-note{{candidate constructor}}
+};
+
+template<typename T, typename U>
+struct X2 {
+  void f(T &t, U u) { 
+    t = u; // expected-error{{incompatible}}
+  }
+  
+  struct Inner {
+    T member1;
+    U member2; // expected-error{{incomplete}}
+  };
+  
+  static T static_member1;
+  static U static_member2;
+};
+
+template<typename T, typename U>
+T X2<T, U>::static_member1 = 17; // expected-error{{cannot initialize}}
+
+template<typename T, typename U>
+U X2<T, U>::static_member2; // expected-error{{no matching}}
+
+template void X2<int, float>::f(int &, float);
+template void X2<int, float>::f(int &, double); // expected-error{{does not refer}}
+template void X2<int, int*>::f(int&, int*); // expected-note{{instantiation}}
+
+template struct X2<int, float>::Inner;
+template struct X2<int, Incomplete>::Inner; // expected-note{{instantiation}}
+
+template int X2<int, float>::static_member1;
+template int* X2<int*, float>::static_member1; // expected-note{{instantiation}}
+template 
+  NonDefaultConstructible X2<NonDefaultConstructible, int>::static_member1;
+
+template 
+  NonDefaultConstructible X2<int, NonDefaultConstructible>::static_member2; // expected-note{{instantiation}}
diff --git a/test/CXX/temp/temp.spec/temp.explicit/p10.cpp b/test/CXX/temp/temp.spec/temp.explicit/p10.cpp
new file mode 100644
index 0000000..290a874
--- /dev/null
+++ b/test/CXX/temp/temp.spec/temp.explicit/p10.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T>
+struct X0 {
+  void f(T&);
+  
+  struct Inner;
+  
+  static T static_var;
+};
+
+template<typename T>
+void X0<T>::f(T& t) { 
+  t = 1; // expected-error{{incompatible type}}
+}
+
+template<typename T>
+struct X0<T>::Inner {
+  T member;
+};
+
+template<typename T>
+T X0<T>::static_var = 1; // expected-error{{cannot initialize}}
+
+extern template struct X0<void*>;
+template struct X0<void*>; // expected-note 2{{instantiation}}
+
+template struct X0<int>; // expected-note 4{{explicit instantiation definition is here}}
+
+extern template void X0<int>::f(int&); // expected-error{{follows explicit instantiation definition}}
+extern template struct X0<int>::Inner; // expected-error{{follows explicit instantiation definition}}
+extern template int X0<int>::static_var; // expected-error{{follows explicit instantiation definition}}
+extern template struct X0<int>; // expected-error{{follows explicit instantiation definition}}
diff --git a/test/CXX/temp/temp.spec/temp.explicit/p12.cpp b/test/CXX/temp/temp.spec/temp.explicit/p12.cpp
new file mode 100644
index 0000000..912b8e1
--- /dev/null
+++ b/test/CXX/temp/temp.spec/temp.explicit/p12.cpp
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+char* p = 0; 
+template<class T> T g(T x = &p) { return x; }
+template int g<int>(int);	// OK even though &p isn’t an int.
+
diff --git a/test/CXX/temp/temp.spec/temp.explicit/p2.cpp b/test/CXX/temp/temp.spec/temp.explicit/p2.cpp
new file mode 100644
index 0000000..8538d27
--- /dev/null
+++ b/test/CXX/temp/temp.spec/temp.explicit/p2.cpp
@@ -0,0 +1,43 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// Example from the standard
+template<class T> class Array { void mf() { } }; 
+
+template class Array<char>; 
+template void Array<int>::mf();
+template<class T> void sort(Array<T>& v) { /* ... */ }
+template void sort(Array<char>&);
+namespace N { 
+  template<class T> void f(T&) { }
+} 
+template void N::f<int>(int&);
+
+
+template<typename T>
+struct X0 {
+  struct Inner {};
+  void f() { }
+  static T value;
+};
+
+template<typename T>
+T X0<T>::value = 17;
+
+typedef X0<int> XInt;
+
+template struct XInt::Inner; // expected-error{{template-id}}
+template void XInt::f(); // expected-error{{template-id}}
+template int XInt::value; // expected-error{{template-id}}
+
+namespace N {
+  template<typename T>
+  struct X1 { // expected-note{{explicit instantiation refers here}}
+  };
+  
+  template<typename T>
+  void f1(T) {}; // expected-note{{explicit instantiation refers here}}
+}
+using namespace N;
+
+template struct X1<int>; // expected-error{{must occur in}}
+template void f1(int); // expected-error{{must occur in}}
diff --git a/test/CXX/temp/temp.spec/temp.explicit/p3.cpp b/test/CXX/temp/temp.spec/temp.explicit/p3.cpp
new file mode 100644
index 0000000..e9758bc
--- /dev/null
+++ b/test/CXX/temp/temp.spec/temp.explicit/p3.cpp
@@ -0,0 +1,49 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// A declaration of a function template shall be in scope at the point of the 
+// explicit instantiation of the function template.
+template<typename T> void f0(T) { }
+template void f0(int); // okay
+
+// A definition of the class or class template containing a member function 
+// template shall be in scope at the point of the explicit instantiation of 
+// the member function template.
+struct X0; // expected-note {{forward declaration}}
+template<typename> struct X1; // expected-note 5{{declared here}}
+
+template void X0::f0<int>(int); // expected-error {{incomplete type}}
+template void X1<int>::f0<int>(int); // expected-error {{implicit instantiation of undefined template}}
+
+// A definition of a class template or class member template shall be in scope 
+// at the point of the explicit instantiation of the class template or class 
+// member template.
+template struct X1<float>; // expected-error{{explicit instantiation of undefined template}}
+
+template<typename T>
+struct X2 { // expected-note 4{{refers here}}
+  template<typename U>
+  struct Inner; // expected-note{{declared here}}
+  
+  struct InnerClass; // expected-note{{forward declaration}}
+};
+
+template struct X2<int>::Inner<float>; // expected-error{{explicit instantiation of undefined template}}
+
+// A definition of a class template shall be in scope at the point of an 
+// explicit instantiation of a member function or a static data member of the
+// class template.
+template void X1<int>::f1(int); // expected-error {{undefined template}}
+template void X1<int>::f1<int>(int); // expected-error {{undefined template}}
+
+template int X1<int>::member; // expected-error {{undefined template}}
+
+// A definition of a member class of a class template shall be in scope at the 
+// point of an explicit instantiation of the member class.
+template struct X2<float>::InnerClass; // expected-error{{undefined member}}
+
+// If the declaration of the explicit instantiation names an implicitly-declared 
+// special member function (Clause 12), the program is ill-formed.
+template X2<int>::X2(); // expected-error{{not an instantiation}}
+template X2<int>::X2(const X2&); // expected-error{{not an instantiation}}
+template X2<int>::~X2(); // expected-error{{not an instantiation}}
+template X2<int> &X2<int>::operator=(const X2<int>&); // expected-error{{not an instantiation}}
diff --git a/test/CXX/temp/temp.spec/temp.explicit/p4.cpp b/test/CXX/temp/temp.spec/temp.explicit/p4.cpp
new file mode 100644
index 0000000..d304374
--- /dev/null
+++ b/test/CXX/temp/temp.spec/temp.explicit/p4.cpp
@@ -0,0 +1,48 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s
+
+template<typename T> void f0(T); // expected-note{{here}}
+template void f0(int); // expected-error{{explicit instantiation of undefined function template}}
+
+template<typename T>
+struct X0 {
+  struct Inner;
+  
+  void f1(); // expected-note{{here}}
+  
+  static T value; // expected-note{{here}}
+};
+
+template void X0<int>::f1(); // expected-error{{explicit instantiation of undefined member function}}
+
+template int X0<int>::value; // expected-error{{explicit instantiation of undefined static data member}}
+
+template<> void f0(long); // expected-note{{previous template specialization is here}}
+template void f0(long); // expected-warning{{explicit instantiation of 'f0<long>' that occurs after an explicit specialization will be ignored}}
+
+template<> void X0<long>::f1(); // expected-note{{previous template specialization is here}}
+template void X0<long>::f1(); // expected-warning{{explicit instantiation of 'f1' that occurs after an explicit specialization will be ignored}}
+
+template<> struct X0<long>::Inner; // expected-note{{previous template specialization is here}}
+template struct X0<long>::Inner; // expected-warning{{explicit instantiation of 'Inner' that occurs after an explicit specialization will be ignored}}
+
+template<> long X0<long>::value; // expected-note{{previous template specialization is here}}
+template long X0<long>::value; // expected-warning{{explicit instantiation of 'value' that occurs after an explicit specialization will be ignored}}
+
+template<> struct X0<double>; // expected-note{{previous template specialization is here}}
+template struct X0<double>; // expected-warning{{explicit instantiation of 'X0<double>' that occurs after an explicit specialization will be ignored}}
+
+// PR 6458
+namespace test0 {
+  template <class T> class foo {
+    int compare(T x, T y);
+  };
+
+  template <> int foo<char>::compare(char x, char y);
+  template <class T> int foo<T>::compare(T x, T y) {
+    // invalid at T=char; if we get a diagnostic here, we're
+    // inappropriately instantiating this template.
+    void *ptr = x;
+  }
+  extern template class foo<char>;
+  template class foo<char>;
+}
diff --git a/test/CXX/temp/temp.spec/temp.explicit/p5.cpp b/test/CXX/temp/temp.spec/temp.explicit/p5.cpp
new file mode 100644
index 0000000..13fb049
--- /dev/null
+++ b/test/CXX/temp/temp.spec/temp.explicit/p5.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace N {
+  template<class T> class Y { // expected-note{{explicit instantiation refers here}}
+    void mf() { } 
+  };
+}
+
+template class Z<int>; // expected-error{{explicit instantiation of non-template class 'Z'}}
+
+// FIXME: This example from the standard is wrong; note posted to CWG reflector
+// on 10/27/2009
+using N::Y; 
+template class Y<int>; // expected-error{{must occur in}}
+
+template class N::Y<char*>; 
+template void N::Y<double>::mf();
diff --git a/test/CXX/temp/temp.spec/temp.explicit/p6.cpp b/test/CXX/temp/temp.spec/temp.explicit/p6.cpp
new file mode 100644
index 0000000..1382272
--- /dev/null
+++ b/test/CXX/temp/temp.spec/temp.explicit/p6.cpp
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<class T> class Array { /* ... */ }; 
+template<class T> void sort(Array<T>& v) { }
+
+// instantiate sort(Array<int>&) - template-argument deduced
+template void sort<>(Array<int>&);
+
+template void sort(Array<long>&);
+
+template<typename T, typename U> void f0(T, U*) { }
+
+template void f0<int>(int, float*);
+template void f0<>(double, float*);
+
+template<typename T> struct hash { };
+struct S {
+  bool operator==(const S&) const { return false; }
+};
+
+template<typename T> struct Hash_map {
+  void Method(const T& x) { h(x); }
+  hash<T> h;
+};
+
+Hash_map<S> *x;
+const Hash_map<S> *foo() {
+  return x;
+}
+
+template<> struct hash<S> {
+  int operator()(const S& k) const {
+    return 0;
+  }
+};
diff --git a/test/CXX/temp/temp.spec/temp.explicit/p7.cpp b/test/CXX/temp/temp.spec/temp.explicit/p7.cpp
new file mode 100644
index 0000000..b62e0cb
--- /dev/null
+++ b/test/CXX/temp/temp.spec/temp.explicit/p7.cpp
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T>
+struct X0 {
+  struct MemberClass {
+    T member; // expected-error{{with function type}}
+  };
+  
+  T* f0(T* ptr) { 
+    return ptr + 1; // expected-error{{pointer to function}}
+  } 
+  
+  static T* static_member;
+};
+
+template<typename T>
+T* X0<T>::static_member = ((T*)0) + 1; // expected-error{{pointer to function}}
+
+template class X0<int>; // okay
+
+template class X0<int(int)>; // expected-note 3{{requested here}}
+
+// Specialize everything, so that the explicit instantiation does not trigger
+// any diagnostics.
+template<>
+struct X0<int(long)>::MemberClass { };
+
+typedef int int_long_func(long);
+template<>
+int_long_func *X0<int_long_func>::f0(int_long_func *) { return 0; }
+
+template<>
+int_long_func *X0<int(long)>::static_member;
+
+template class X0<int(long)>;
+
diff --git a/test/CXX/temp/temp.spec/temp.explicit/p8.cpp b/test/CXX/temp/temp.spec/temp.explicit/p8.cpp
new file mode 100644
index 0000000..0c5aec3
--- /dev/null
+++ b/test/CXX/temp/temp.spec/temp.explicit/p8.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T>
+struct X0 {
+  struct MemberClass;
+  
+  T* f0(T* ptr);
+  
+  static T* static_member;
+};
+
+template class X0<int>; // okay
+template class X0<int(int)>; // okay; nothing gets instantiated.
+
+template<typename T>
+struct X0<T>::MemberClass {
+  T member;
+};
+
+template<typename T>
+T* X0<T>::f0(T* ptr) {
+  return ptr + 1;
+}
+
+template<typename T>
+T* X0<T>::static_member = 0;
+
diff --git a/test/CXX/temp/temp.spec/temp.explicit/p9-linkage.cpp b/test/CXX/temp/temp.spec/temp.explicit/p9-linkage.cpp
new file mode 100644
index 0000000..e67233c
--- /dev/null
+++ b/test/CXX/temp/temp.spec/temp.explicit/p9-linkage.cpp
@@ -0,0 +1,66 @@
+// RUN: %clang_cc1 -emit-llvm -std=c++0x -o - %s | FileCheck %s
+
+template<typename T>
+struct X0 {
+  void f(T &t) {
+    t = 0;
+  }
+  
+  void g(T &t);
+  
+  void h(T &t);
+  
+  static T static_var;
+};
+
+template<typename T>
+inline void X0<T>::g(T & t) {
+  t = 0;
+}
+
+template<typename T>
+void X0<T>::h(T & t) {
+  t = 0;
+}
+
+template<typename T>
+T X0<T>::static_var = 0;
+
+extern template struct X0<int*>;
+
+int *&test(X0<int*> xi, int *ip) {
+  // CHECK: define available_externally void @_ZN2X0IPiE1fERS0_
+  xi.f(ip);
+  // CHECK: define available_externally void @_ZN2X0IPiE1gERS0_
+  xi.g(ip);
+  // CHECK: declare void @_ZN2X0IPiE1hERS0_
+  xi.h(ip);
+  return X0<int*>::static_var;
+}
+
+template<typename T>
+void f0(T& t) {
+  t = 0;
+}
+
+template<typename T>
+inline void f1(T& t) {
+  t = 0;
+}
+
+extern template void f0<>(int *&);
+extern template void f1<>(int *&);
+
+void test_f0(int *ip, float *fp) {
+  // CHECK: declare void @_Z2f0IPiEvRT_
+  f0(ip);
+  // CHECK: define linkonce_odr void @_Z2f0IPfEvRT_
+  f0(fp);
+}
+
+void test_f1(int *ip, float *fp) {
+  // CHECK: define available_externally void @_Z2f1IPiEvRT_
+  f1(ip);
+  // CHECK: define linkonce_odr void @_Z2f1IPfEvRT_
+  f1(fp);
+}
diff --git a/test/CXX/temp/temp.spec/temp.explicit/p9.cpp b/test/CXX/temp/temp.spec/temp.explicit/p9.cpp
new file mode 100644
index 0000000..ad973bb
--- /dev/null
+++ b/test/CXX/temp/temp.spec/temp.explicit/p9.cpp
@@ -0,0 +1,59 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++0x -verify %s
+
+template<typename T>
+struct X0 {
+  void f(T &t) {
+    t = 1; // expected-error{{incompatible type}}
+  }
+  
+  void g(T &t);
+  
+  void h(T &t);
+  
+  static T static_var;
+};
+
+template<typename T>
+inline void X0<T>::g(T & t) {
+  t = 1; // expected-error{{incompatible type}}
+}
+
+template<typename T>
+void X0<T>::h(T & t) {
+  t = 1;
+}
+
+template<typename T>
+T X0<T>::static_var = 1;
+
+extern template struct X0<int*>;
+
+int *&test(X0<int*> xi, int *ip) {
+  xi.f(ip); // expected-note{{instantiation}}
+  xi.g(ip); // expected-note{{instantiation}}
+  xi.h(ip);
+  return X0<int*>::static_var;
+}
+
+template<typename T>
+void f0(T& t) {
+  t = 1; // expected-error{{incompatible type}}
+}
+
+template<typename T>
+inline void f1(T& t) {
+  t = 1; // expected-error 2{{incompatible type}}
+}
+
+extern template void f0<>(int *&);
+extern template void f1<>(int *&);
+
+void test_f0(int *ip, float *fp) {
+  f0(ip);
+  f0(fp); // expected-note{{instantiation}}
+}
+
+void test_f1(int *ip, float *fp) {
+  f1(ip); // expected-note{{instantiation}}
+  f1(fp); // expected-note{{instantiation}}
+}
diff --git a/test/CXX/temp/temp.spec/temp.inst/p11.cpp b/test/CXX/temp/temp.spec/temp.inst/p11.cpp
new file mode 100644
index 0000000..8184071
--- /dev/null
+++ b/test/CXX/temp/temp.spec/temp.inst/p11.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -verify -emit-llvm-only %s
+
+// rdar://problem/7838962
+namespace test0 {
+  template<typename T> unsigned f0() {
+    return T::MaxSize; // expected-error {{'int' cannot be used prior to '::'}}
+  };
+  template<typename T> struct A {
+    void Allocate(unsigned Alignment
+                    = f0<T>()) // expected-note {{in instantiation}}
+    {}
+  };
+  void f1(A<int> x) { x.Allocate(); }
+  
+}
diff --git a/test/CodeCompletion/Inputs/macros.h b/test/CodeCompletion/Inputs/macros.h
new file mode 100644
index 0000000..98b5ac6
--- /dev/null
+++ b/test/CodeCompletion/Inputs/macros.h
@@ -0,0 +1,4 @@
+#define FOO
+#define BAR(X, Y) X, Y
+#define IDENTITY(X) X
+#define WIBBLE(...)
diff --git a/test/CodeCompletion/call.c b/test/CodeCompletion/call.c
new file mode 100644
index 0000000..8210389
--- /dev/null
+++ b/test/CodeCompletion/call.c
@@ -0,0 +1,15 @@
+// Note: the run lines follow their respective tests, since line/column
+// matter in this test.
+void f0(float x, float y);
+void f1();
+void test() {
+  f0(0, 0);
+  g0(0, 0);
+  f1(0, 0);
+  // RUN: %clang_cc1 -std=c89 -fsyntax-only -code-completion-at=%s:6:6 %s -o - | FileCheck -check-prefix=CC1 %s
+  // CHECK-CC1: f0(<#float x#>, float y)
+  // RUN: %clang_cc1 -std=c89 -fsyntax-only -code-completion-at=%s:6:9 %s -o - | FileCheck -check-prefix=CC2 %s
+  // CHECK-CC2: f0(float x, <#float y#>)
+  // RUN: %clang_cc1 -std=c89 -fsyntax-only -code-completion-at=%s:8:6 %s -o - | FileCheck -check-prefix=CC3 %s
+  // CHECK-CC3: f1()
+}
diff --git a/test/CodeCompletion/call.cpp b/test/CodeCompletion/call.cpp
new file mode 100644
index 0000000..1df958e
--- /dev/null
+++ b/test/CodeCompletion/call.cpp
@@ -0,0 +1,28 @@
+// Note: the run lines follow their respective tests, since line/column
+// matter in this test.
+void f(float x, float y);
+void f(int i, int j, int k);
+struct X { };
+void f(X);
+namespace N {
+  struct Y { 
+    Y(int = 0); 
+    
+    operator int() const;
+  };
+  void f(Y y, int ZZ);
+}
+typedef N::Y Y;
+void f();
+
+void test() {
+  f(Y(), 0, 0);
+  // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:19:9 %s -o - | FileCheck -check-prefix=CC1 %s
+  // CHECK-CC1: COMPLETION: Pattern : dynamic_cast<<#type-id#>>(<#expression#>)
+  // CHECK-CC1: f(N::Y y, <#int ZZ#>)
+  // CHECK-CC1-NEXT: f(int i, <#int j#>, int k)
+  // CHECK-CC1-NEXT: f(float x, <#float y#>)
+  // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:19:13 %s -o - | FileCheck -check-prefix=CC2 %s
+  // CHECK-CC2-NOT: f(N::Y y, int ZZ)
+  // CHECK-CC2: f(int i, int j, <#int k#>)
+}
diff --git a/test/CodeCompletion/enum-switch-case-qualified.cpp b/test/CodeCompletion/enum-switch-case-qualified.cpp
new file mode 100644
index 0000000..e74ec9b
--- /dev/null
+++ b/test/CodeCompletion/enum-switch-case-qualified.cpp
@@ -0,0 +1,32 @@
+namespace M {
+  
+namespace N {
+  struct C {
+    enum Color {
+      Red,
+      Orange,
+      Yellow,
+      Green,
+      Blue,
+      Indigo,
+      Violet
+    };
+  };
+}
+  
+}
+
+namespace M {
+  
+void test(enum N::C::Color color) {
+  switch (color) {
+  case 
+    // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:23:8 %s -o - | FileCheck -check-prefix=CC1 %s
+    // CHECK-CC1: Blue : [#M::N::C::Color#]N::C::Blue
+    // CHECK-CC1-NEXT: Green : [#M::N::C::Color#]N::C::Green
+    // CHECK-CC1-NEXT: Indigo : [#M::N::C::Color#]N::C::Indigo
+    // CHECK-CC1-NEXT: Orange : [#M::N::C::Color#]N::C::Orange
+    // CHECK-CC1-NEXT: Red : [#M::N::C::Color#]N::C::Red
+    // CHECK-CC1-NEXT: Violet : [#M::N::C::Color#]N::C::Violet
+    // CHECK-CC1: Yellow : [#M::N::C::Color#]N::C::Yellow
+      
diff --git a/test/CodeCompletion/enum-switch-case.c b/test/CodeCompletion/enum-switch-case.c
new file mode 100644
index 0000000..0820726
--- /dev/null
+++ b/test/CodeCompletion/enum-switch-case.c
@@ -0,0 +1,28 @@
+enum Color {
+  Red,
+  Orange,
+  Yellow,
+  Green,
+  Blue,
+  Indigo,
+  Violet
+};
+
+void test(enum Color color) {
+  switch (color) {
+    case Red:
+      break;
+      
+    case Yellow:
+      break;
+
+    case Green:
+      break;
+      
+    // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:19:10 %s -o - | FileCheck -check-prefix=CC1 %s
+    // CHECK-CC1: Blue
+    // CHECK-CC1-NEXT: Green
+    // CHECK-CC1-NEXT: Indigo
+    // CHECK-CC1-NEXT: Orange
+    // CHECK-CC1-NEXT: Violet
+      
diff --git a/test/CodeCompletion/enum-switch-case.cpp b/test/CodeCompletion/enum-switch-case.cpp
new file mode 100644
index 0000000..2677f33
--- /dev/null
+++ b/test/CodeCompletion/enum-switch-case.cpp
@@ -0,0 +1,28 @@
+namespace N {
+  enum Color {
+    Red,
+    Orange,
+    Yellow,
+    Green,
+    Blue,
+    Indigo,
+    Violet
+  };
+}
+
+void test(enum N::Color color) {
+  switch (color) {
+  case N::Red:
+    break;
+    
+  case N::Yellow:
+    break;
+    
+  case 
+    // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:21:8 %s -o - | FileCheck -check-prefix=CC1 %s
+    // CHECK-CC1: Blue : [#N::Color#]N::Blue
+    // CHECK-CC1-NEXT: Green : [#N::Color#]N::Green
+    // CHECK-CC1-NEXT: Indigo : [#N::Color#]N::Indigo
+    // CHECK-CC1-NEXT: Orange : [#N::Color#]N::Orange
+    // CHECK-CC1-NEXT: Violet : [#N::Color#]N::Violet
+    
diff --git a/test/CodeCompletion/function-templates.cpp b/test/CodeCompletion/function-templates.cpp
new file mode 100644
index 0000000..cdbbf75
--- /dev/null
+++ b/test/CodeCompletion/function-templates.cpp
@@ -0,0 +1,23 @@
+namespace std {
+  template<typename RandomAccessIterator>
+  void sort(RandomAccessIterator first, RandomAccessIterator last);
+  
+  template<class X, class Y>
+  X* dyn_cast(Y *Val);
+}
+
+class Foo {
+public:
+  template<typename T> T &getAs();
+};
+
+void f() {
+  std::sort(1, 2);
+  Foo().getAs<int>();
+  // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:15:8 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s
+  // CHECK-CC1: dyn_cast<<#class X#>>(<#Y *Val#>)
+  // CHECK-CC1: sort(<#RandomAccessIterator first#>, <#RandomAccessIterator last#>
+  // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:16:9 %s -o - | FileCheck -check-prefix=CHECK-CC2 %s
+  // CHECK-CC2: getAs<<#typename T#>>()
+)
+  
diff --git a/test/CodeCompletion/functions.cpp b/test/CodeCompletion/functions.cpp
new file mode 100644
index 0000000..6838de3
--- /dev/null
+++ b/test/CodeCompletion/functions.cpp
@@ -0,0 +1,8 @@
+void f(int i, int j = 2, int k = 5);
+void f(float x, float y...);
+       
+void test() {
+  ::
+  // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:5:5 %s -o - | FileCheck -check-prefix=CC1 %s
+  // CHECK-CC1: f(<#int i#>{#, <#int j#>{#, <#int k#>#}#})
+  // CHECK-CC1: f(<#float x#>, <#float y#><#, ...#>)
diff --git a/test/CodeCompletion/macros.c b/test/CodeCompletion/macros.c
new file mode 100644
index 0000000..0758bbf
--- /dev/null
+++ b/test/CodeCompletion/macros.c
@@ -0,0 +1,34 @@
+enum Color {
+  Red, Green, Blue
+};
+
+struct Point {
+  float x, y, z;
+  enum Color color;
+};
+
+void test(struct Point *p) {
+  // RUN: %clang_cc1 -include %S/Inputs/macros.h -fsyntax-only -code-completion-macros -code-completion-at=%s:12:14 %s -o - | FileCheck -check-prefix=CC1 %s
+  switch (p->IDENTITY(color)) {
+  // RUN: %clang_cc1 -include %S/Inputs/macros.h -fsyntax-only -code-completion-macros -code-completion-at=%s:14:9 %s -o - | FileCheck -check-prefix=CC2 %s
+    case 
+  }
+
+  // Run the same tests, this time with macros loaded from the PCH file.
+  // RUN: %clang_cc1 -emit-pch -o %t %S/Inputs/macros.h
+  // RUN: %clang_cc1 -include-pch %t -fsyntax-only -code-completion-macros -code-completion-at=%s:12:14 %s -o - | FileCheck -check-prefix=CC1 %s
+  // RUN: %clang_cc1 -include-pch %t -fsyntax-only -code-completion-macros -code-completion-at=%s:14:9 %s -o - | FileCheck -check-prefix=CC2 %s
+
+  // CC1: color
+  // CC1: x
+  // CC1: y
+  // CC1: z
+
+  // CC2: BAR(<#X#>, <#Y#>)
+  // CC2: Blue
+  // CC2: FOO
+  // CC2: Green
+  // CC2: IDENTITY(<#X#>)
+  // CC2: Red
+  // CC2: WIBBLE
+}
diff --git a/test/CodeCompletion/member-access.c b/test/CodeCompletion/member-access.c
new file mode 100644
index 0000000..f41c509c
--- /dev/null
+++ b/test/CodeCompletion/member-access.c
@@ -0,0 +1,12 @@
+struct Point {
+  float x;
+  float y;
+  float z;
+};
+
+void test(struct Point *p) {
+  p->
+  // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:8:6 %s -o - | FileCheck -check-prefix=CC1 %s
+  // CHECK-CC1: x
+  // CHECK-CC1: y
+  // CHECK-CC1: z
diff --git a/test/CodeCompletion/member-access.cpp b/test/CodeCompletion/member-access.cpp
new file mode 100644
index 0000000..8f772c0
--- /dev/null
+++ b/test/CodeCompletion/member-access.cpp
@@ -0,0 +1,42 @@
+struct Base1 {
+  int member1;
+  float member2;
+};
+
+struct Base2 {
+  int member1;
+  double member3;
+  void memfun1(int);
+};
+
+struct Base3 : Base1, Base2 {
+  void memfun1(float);
+  void memfun1(double) const;
+  void memfun2(int);
+};
+
+struct Derived : Base3 {
+  int member4;
+  int memfun3(int);
+};
+
+class Proxy {
+public:
+  Derived *operator->() const;
+};
+
+void test(const Proxy &p) {
+  p->
+  // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:29:6 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s
+  // CHECK-CC1: Base1 : Base1::
+  // CHECK-CC1: member1 : [#int#][#Base1::#]member1
+  // CHECK-CC1: member1 : [#int#][#Base2::#]member1
+  // CHECK-CC1: member2 : [#float#][#Base1::#]member2
+  // CHECK-CC1: member3
+  // CHECK-CC1: member4
+  // CHECK-CC1: memfun1 : [#void#][#Base3::#]memfun1(<#float#>)
+  // CHECK-CC1: memfun1 : [#void#][#Base3::#]memfun1(<#double#>)[# const#]
+  // CHECK-CC1: memfun1 (Hidden) : [#void#]Base2::memfun1(<#int#>)
+  // CHECK-CC1: memfun2 : [#void#][#Base3::#]memfun2(<#int#>)
+  // CHECK-CC1: memfun3 : [#int#]memfun3(<#int#>)
+  
diff --git a/test/CodeCompletion/namespace-alias.cpp b/test/CodeCompletion/namespace-alias.cpp
new file mode 100644
index 0000000..efbf996
--- /dev/null
+++ b/test/CodeCompletion/namespace-alias.cpp
@@ -0,0 +1,20 @@
+namespace N4 {
+  namespace N3 { }
+}
+
+class N3;
+
+namespace N2 {
+  namespace I1 { }
+  namespace I4 = I1;
+  namespace I5 { }
+  namespace I1 { }
+  
+  namespace New =
+  // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:13:18 %s -o - | FileCheck -check-prefix=CC1 %s
+  // CHECK-CC1: I1
+  // CHECK-CC1: I4
+  // CHECK-CC1: I5
+  // CHECK-CC1: N2
+  // CHECK-CC1-NEXT: N4
+  
diff --git a/test/CodeCompletion/namespace.cpp b/test/CodeCompletion/namespace.cpp
new file mode 100644
index 0000000..ecd8480
--- /dev/null
+++ b/test/CodeCompletion/namespace.cpp
@@ -0,0 +1,14 @@
+namespace N3 {
+}
+
+namespace N2 {
+  namespace I1 { }
+  namespace I4 = I1;
+  namespace I5 { }
+  namespace I1 { }
+  
+  namespace
+  // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:10:12 %s -o - | FileCheck -check-prefix=CC1 %s
+  // CHECK-CC1: I1
+  // CHECK-CC1-NEXT: I5
+  
diff --git a/test/CodeCompletion/nested-name-specifier.cpp b/test/CodeCompletion/nested-name-specifier.cpp
new file mode 100644
index 0000000..e09a14b
--- /dev/null
+++ b/test/CodeCompletion/nested-name-specifier.cpp
@@ -0,0 +1,17 @@
+namespace N {
+  struct A { };
+  namespace M { 
+    struct C { };
+  };
+}
+
+namespace N {
+  struct B { };
+}
+
+N::
+// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:12:4 %s -o - | FileCheck -check-prefix=CC1 %s
+// CHECK-CC1: A
+// CHECK-CC1: B
+// CHECK-CC1: M
+
diff --git a/test/CodeCompletion/objc-message.m b/test/CodeCompletion/objc-message.m
new file mode 100644
index 0000000..a7b111f
--- /dev/null
+++ b/test/CodeCompletion/objc-message.m
@@ -0,0 +1,35 @@
+// Note: the run lines follow their respective tests, since line/column
+// matter in this test.
+
+@protocol FooTestProtocol
++ protocolClassMethod;
+- protocolInstanceMethod;
+@end
+@interface Foo <FooTestProtocol> {
+  void *isa;
+}
++ (int)classMethod1:a withKeyword:b;
++ (void)classMethod2;
++ new;
+- instanceMethod1;
+@end
+
+@interface Foo (FooTestCategory)
++ categoryClassMethod;
+- categoryInstanceMethod;
+@end
+
+void func() {
+  Foo *obj = [Foo new];
+  [obj xx];
+}
+// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:23:19 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s
+// CHECK-CC1: categoryClassMethod
+// CHECK-CC1: classMethod1:withKeyword:
+// CHECK-CC1: classMethod2
+// CHECK-CC1: new
+// CHECK-CC1: protocolClassMethod
+// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:24:8 %s -o - | FileCheck -check-prefix=CHECK-CC2 %s
+// CHECK-CC2: categoryInstanceMethod
+// CHECK-CC2: instanceMethod1
+// CHECK-CC2: protocolInstanceMethod
diff --git a/test/CodeCompletion/operator.cpp b/test/CodeCompletion/operator.cpp
new file mode 100644
index 0000000..05cd768
--- /dev/null
+++ b/test/CodeCompletion/operator.cpp
@@ -0,0 +1,17 @@
+class T { };
+
+typedef int Integer;
+
+namespace N { }
+
+void f() {
+  typedef float Float;
+  
+  operator
+  // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:10:11 %s -o - | FileCheck -check-prefix=CC1 %s
+  // CHECK-CC1: +
+  // CHECK-CC1: Float
+  // CHECK-CC1: Integer
+  // CHECK-CC1: N
+  // CHECK-CC1: short
+  // CHECK-CC1: T
diff --git a/test/CodeCompletion/ordinary-name.c b/test/CodeCompletion/ordinary-name.c
new file mode 100644
index 0000000..1580d01
--- /dev/null
+++ b/test/CodeCompletion/ordinary-name.c
@@ -0,0 +1,10 @@
+struct X { int x; };
+
+typedef struct t TYPEDEF;
+
+void foo() {
+  int y;
+  // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:6:9 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s
+  // CHECK-CC1: foo
+  // CHECK-CC1: y
+  // CHECK-CC1: TYPEDEF
diff --git a/test/CodeCompletion/ordinary-name.cpp b/test/CodeCompletion/ordinary-name.cpp
new file mode 100644
index 0000000..699b01d
--- /dev/null
+++ b/test/CodeCompletion/ordinary-name.cpp
@@ -0,0 +1,171 @@
+struct X { int x; };
+void z(int);
+typedef struct t TYPEDEF;
+
+void foo() {
+  int y = 17;
+  // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:6:14 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s
+  // CHECK-CC1: COMPLETION: bool
+  // CHECK-CC1-NEXT: COMPLETION: char
+  // CHECK-CC1-NEXT: COMPLETION: class
+  // CHECK-CC1-NEXT: COMPLETION: const
+  // CHECK-CC1-NEXT: COMPLETION: Pattern : const_cast<<#type-id#>>(<#expression#>)
+  // CHECK-CC1: COMPLETION: Pattern : delete <#expression#>
+  // CHECK-CC1-NEXT: COMPLETION: Pattern : delete[] <#expression#>
+  // CHECK-CC1-NEXT: COMPLETION: Pattern : do{<#statements#>
+  // CHECK-CC1: COMPLETION: double
+  // CHECK-CC1-NEXT: COMPLETION: Pattern : dynamic_cast<<#type-id#>>(<#expression#>)
+  // CHECK-CC1-NEXT: COMPLETION: enum
+  // CHECK-CC1-NEXT: COMPLETION: extern
+  // CHECK-CC1-NEXT: COMPLETION: false
+  // CHECK-CC1-NEXT: COMPLETION: float
+  // CHECK-CC1-NEXT: COMPLETION: foo : [#void#]foo()
+  // CHECK-CC1-NEXT: COMPLETION: Pattern : for(<#init-statement#>;<#condition#>;<#inc-expression#>){<#statements#>
+  // CHECK-CC1: COMPLETION: Pattern : goto <#identifier#>
+  // CHECK-CC1-NEXT: COMPLETION: Pattern : if(<#condition#>){<#statements#>
+  // CHECK-CC1: COMPLETION: int
+  // CHECK-CC1-NEXT: COMPLETION: long
+  // CHECK-CC1-NEXT: COMPLETION: Pattern : new <#type-id#>(<#expressions#>)
+  // CHECK-CC1-NEXT: COMPLETION: Pattern : new <#type-id#>[<#size#>](<#expressions#>)
+  // CHECK-CC1-NEXT: COMPLETION: operator
+  // CHECK-CC1-NEXT: COMPLETION: Pattern : reinterpret_cast<<#type-id#>>(<#expression#>)
+  // CHECK-CC1-NEXT: COMPLETION: Pattern : return
+  // CHECK-CC1-NEXT: COMPLETION: short
+  // CHECK-CC1-NEXT: COMPLETION: signed
+  // CHECK-CC1-NEXT: COMPLETION: Pattern : sizeof(<#expression-or-type#>)
+  // CHECK-CC1-NEXT: COMPLETION: static
+  // CHECK-CC1-NEXT: COMPLETION: Pattern : static_cast<<#type-id#>>(<#expression#>)
+  // CHECK-CC1-NEXT: COMPLETION: struct
+  // CHECK-CC1-NEXT: COMPLETION: Pattern : switch(<#condition#>){
+  // CHECK-CC1: COMPLETION: t : t
+  // CHECK-CC1-NEXT: COMPLETION: Pattern : throw <#expression#>
+  // CHECK-CC1-NEXT: COMPLETION: true
+  // CHECK-CC1-NEXT: COMPLETION: Pattern : try{<#statements#>
+  // CHECK-CC1: COMPLETION: TYPEDEF : TYPEDEF
+  // CHECK-CC1-NEXT: COMPLETION: typedef
+  // CHECK-CC1-NEXT: COMPLETION: Pattern : typeid(<#expression-or-type#>)
+  // CHECK-CC1-NEXT: COMPLETION: Pattern : typename <#qualified-id#>
+  // CHECK-CC1-NEXT: COMPLETION: Pattern : typeof(<#expression-or-type#>)
+  // CHECK-CC1-NEXT: COMPLETION: union
+  // CHECK-CC1-NEXT: COMPLETION: unsigned
+  // CHECK-CC1-NEXT: COMPLETION: Pattern : using namespace <#identifier#>
+  // CHECK-CC1-NEXT: COMPLETION: void
+  // CHECK-CC1-NEXT: COMPLETION: volatile
+  // CHECK-CC1-NEXT: COMPLETION: wchar_t
+  // CHECK-CC1-NEXT: COMPLETION: Pattern : while(<#condition#>){<#statements#>
+  // CHECK-CC1: COMPLETION: X : X
+  // CHECK-CC1-NEXT: COMPLETION: y : [#int#]y
+  // CHECK-CC1-NEXT: COMPLETION: z : [#void#]z(<#int#>)
+
+  // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:4:1 %s -o - | FileCheck -check-prefix=CHECK-CC2 %s
+  // CHECK-CC2: COMPLETION: Pattern : asm(<#string-literal#>)
+  // CHECK-CC2-NEXT: COMPLETION: bool
+  // CHECK-CC2-NEXT: COMPLETION: char
+  // CHECK-CC2-NEXT: COMPLETION: class
+  // CHECK-CC2-NEXT: COMPLETION: const
+  // CHECK-CC2-NEXT: COMPLETION: double
+  // CHECK-CC2-NEXT: COMPLETION: enum
+  // CHECK-CC2-NEXT: COMPLETION: extern
+  // CHECK-CC2-NEXT: COMPLETION: float
+  // CHECK-CC2-NEXT: COMPLETION: inline
+  // CHECK-CC2-NEXT: COMPLETION: int
+  // CHECK-CC2-NEXT: COMPLETION: long
+  // CHECK-CC2-NEXT: COMPLETION: Pattern : namespace <#identifier#>{<#declarations#>
+  // CHECK-CC2: COMPLETION: Pattern : namespace <#identifier#> = <#identifier#>
+  // CHECK-CC2-NEXT: COMPLETION: operator
+  // CHECK-CC2-NEXT: COMPLETION: short
+  // CHECK-CC2-NEXT: COMPLETION: signed
+  // CHECK-CC2-NEXT: COMPLETION: static
+  // CHECK-CC2-NEXT: COMPLETION: struct
+  // CHECK-CC2-NEXT: COMPLETION: t : t
+  // CHECK-CC2-NEXT: COMPLETION: Pattern : template <#declaration#>
+  // CHECK-CC2-NEXT: COMPLETION: Pattern : template<<#parameters#>>
+  // CHECK-CC2-NEXT: COMPLETION: TYPEDEF : TYPEDEF
+  // CHECK-CC2-NEXT: COMPLETION: typedef
+  // CHECK-CC2-NEXT: COMPLETION: Pattern : typename <#qualified-id#>
+  // CHECK-CC2-NEXT: COMPLETION: Pattern : typeof(<#expression-or-type#>)
+  // CHECK-CC2-NEXT: COMPLETION: union
+  // CHECK-CC2-NEXT: COMPLETION: unsigned
+  // CHECK-CC2-NEXT: COMPLETION: Pattern : using namespace <#identifier#>
+  // CHECK-CC2-NEXT: COMPLETION: Pattern : using <#qualified-id#>
+  // CHECK-CC2-NEXT: COMPLETION: void
+  // CHECK-CC2-NEXT: COMPLETION: volatile
+  // CHECK-CC2-NEXT: COMPLETION: wchar_t
+  // CHECK-CC2-NEXT: COMPLETION: X : X
+
+  // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:1:19 %s -o - | FileCheck -check-prefix=CHECK-CC3 %s
+  // CHECK-CC3: COMPLETION: bool
+  // CHECK-CC3-NEXT: COMPLETION: char
+  // CHECK-CC3-NEXT: COMPLETION: class
+  // CHECK-CC3-NEXT: COMPLETION: const
+  // CHECK-CC3-NEXT: COMPLETION: double
+  // CHECK-CC3-NEXT: COMPLETION: enum
+  // CHECK-CC3-NEXT: COMPLETION: explicit
+  // CHECK-CC3-NEXT: COMPLETION: extern
+  // CHECK-CC3-NEXT: COMPLETION: float
+  // CHECK-CC3-NEXT: COMPLETION: friend
+  // CHECK-CC3-NEXT: COMPLETION: inline
+  // CHECK-CC3-NEXT: COMPLETION: int
+  // CHECK-CC3-NEXT: COMPLETION: long
+  // CHECK-CC3-NEXT: COMPLETION: mutable
+  // CHECK-CC3-NEXT: COMPLETION: operator
+  // CHECK-CC3-NEXT: COMPLETION: Pattern : private: 
+  // CHECK-CC3-NEXT: COMPLETION: Pattern : protected: 
+  // CHECK-CC3-NEXT: COMPLETION: Pattern : public: 
+  // CHECK-CC3-NEXT: COMPLETION: short
+  // CHECK-CC3-NEXT: COMPLETION: signed
+  // CHECK-CC3-NEXT: COMPLETION: static
+  // CHECK-CC3-NEXT: COMPLETION: struct
+  // CHECK-CC3-NEXT: COMPLETION: Pattern : template<<#parameters#>>
+  // CHECK-CC3-NEXT: COMPLETION: typedef
+  // CHECK-CC3-NEXT: COMPLETION: Pattern : typename <#qualified-id#>
+  // CHECK-CC3-NEXT: COMPLETION: Pattern : typeof(<#expression-or-type#>)
+  // CHECK-CC3-NEXT: COMPLETION: union
+  // CHECK-CC3-NEXT: COMPLETION: unsigned
+  // CHECK-CC3-NEXT: COMPLETION: Pattern : using <#qualified-id#>
+  // CHECK-CC3-NEXT: COMPLETION: virtual
+  // CHECK-CC3-NEXT: COMPLETION: void
+  // CHECK-CC3-NEXT: COMPLETION: volatile
+  // CHECK-CC3-NEXT: COMPLETION: wchar_t
+  // CHECK-CC3-NEXT: COMPLETION: X : X
+
+  // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:6:11 %s -o - | FileCheck -check-prefix=CHECK-CC4 %s
+  // CHECK-CC4: COMPLETION: bool
+  // CHECK-CC4-NEXT: COMPLETION: char
+  // CHECK-CC4-NEXT: COMPLETION: class
+  // CHECK-CC4-NEXT: COMPLETION: const
+  // CHECK-CC4-NEXT: COMPLETION: Pattern : const_cast<<#type-id#>>(<#expression#>)
+  // CHECK-CC4-NEXT: COMPLETION: Pattern : delete <#expression#>
+  // CHECK-CC4-NEXT: COMPLETION: Pattern : delete[] <#expression#>
+  // CHECK-CC4-NEXT: COMPLETION: double
+  // CHECK-CC4-NEXT: COMPLETION: Pattern : dynamic_cast<<#type-id#>>(<#expression#>)
+  // CHECK-CC4-NEXT: COMPLETION: enum
+  // CHECK-CC4-NEXT: COMPLETION: false
+  // CHECK-CC4-NEXT: COMPLETION: float
+  // CHECK-CC4-NEXT: COMPLETION: foo : [#void#]foo()
+  // CHECK-CC4-NEXT: COMPLETION: int
+  // CHECK-CC4-NEXT: COMPLETION: long
+  // CHECK-CC4-NEXT: COMPLETION: Pattern : new <#type-id#>(<#expressions#>)
+  // CHECK-CC4-NEXT: COMPLETION: Pattern : new <#type-id#>[<#size#>](<#expressions#>)
+  // CHECK-CC4-NEXT: COMPLETION: operator
+  // CHECK-CC4-NEXT: COMPLETION: Pattern : reinterpret_cast<<#type-id#>>(<#expression#>)
+  // CHECK-CC4-NEXT: COMPLETION: short
+  // CHECK-CC4-NEXT: COMPLETION: signed
+  // CHECK-CC4-NEXT: COMPLETION: Pattern : sizeof(<#expression-or-type#>)
+  // CHECK-CC4-NEXT: COMPLETION: Pattern : static_cast<<#type-id#>>(<#expression#>)
+  // CHECK-CC4-NEXT: COMPLETION: struct
+  // CHECK-CC4-NEXT: COMPLETION: t : t
+  // CHECK-CC4-NEXT: COMPLETION: Pattern : throw <#expression#>
+  // CHECK-CC4-NEXT: COMPLETION: true
+  // CHECK-CC4-NEXT: COMPLETION: TYPEDEF : TYPEDEF
+  // CHECK-CC4-NEXT: COMPLETION: Pattern : typeid(<#expression-or-type#>)
+  // CHECK-CC4-NEXT: COMPLETION: Pattern : typename <#qualified-id#>
+  // CHECK-CC4-NEXT: COMPLETION: Pattern : typeof(<#expression-or-type#>)
+  // CHECK-CC4-NEXT: COMPLETION: union
+  // CHECK-CC4-NEXT: COMPLETION: unsigned
+  // CHECK-CC4-NEXT: COMPLETION: void
+  // CHECK-CC4-NEXT: COMPLETION: volatile
+  // CHECK-CC4-NEXT: COMPLETION: wchar_t
+  // CHECK-CC4-NEXT: COMPLETION: X : X
+  // CHECK-CC4-NEXT: COMPLETION: y : [#int#]y
+  // CHECK-CC4-NEXT: COMPLETION: z : [#void#]z(<#int#>)
diff --git a/test/CodeCompletion/tag.c b/test/CodeCompletion/tag.c
new file mode 100644
index 0000000..6ad2988
--- /dev/null
+++ b/test/CodeCompletion/tag.c
@@ -0,0 +1,12 @@
+enum X { x };
+enum Y { y };
+struct Z { };
+
+void X();
+
+void test() {
+  enum X { x };
+  enum
+  // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:9:7 %s -o - | FileCheck -check-prefix=CC1 %s
+  // CHECK-CC1: X
+  // CHECK-CC1: Y
diff --git a/test/CodeCompletion/tag.cpp b/test/CodeCompletion/tag.cpp
new file mode 100644
index 0000000..03fc0fd
--- /dev/null
+++ b/test/CodeCompletion/tag.cpp
@@ -0,0 +1,27 @@
+class X { };
+struct Y { };
+
+namespace N {
+  template<typename> class Z;
+}
+
+namespace M {
+  class A;
+}
+using M::A;
+
+namespace N {
+  class Y;
+  
+  void test() {
+    class
+    // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:17:10 %s -o - | FileCheck -check-prefix=CC1 %s
+    // FIXME: the redundant Y is really annoying... it needs qualification to 
+    // actually be useful. Here, it just looks redundant :(
+    // CHECK-CC1: A
+    // CHECK-CC1: M : M::
+    // CHECK-CC1: N : N::
+    // CHECK-CC1: X
+    // CHECK-CC1: Y
+    // CHECK-CC1: Y
+    // CHECK-CC1: Z
diff --git a/test/CodeCompletion/templates.cpp b/test/CodeCompletion/templates.cpp
new file mode 100644
index 0000000..32a7b21
--- /dev/null
+++ b/test/CodeCompletion/templates.cpp
@@ -0,0 +1,28 @@
+namespace std {
+  template<typename T>
+  class allocator { 
+  public:
+    void in_base();
+  };
+  
+  template<typename T, typename Alloc = std::allocator<T> >
+  class vector : Alloc {
+  public:
+    void foo();
+    void stop();
+  };
+  template<typename Alloc> class vector<bool, Alloc>;
+}
+
+void f() {
+  std::vector<int> v;
+  v.foo();
+  // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:18:8 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s
+  // CHECK-CC1: allocator<<#typename T#>>
+  // CHECK-CC1-NEXT: vector<<#typename T#>{#, <#typename Alloc#>#}>
+  // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:19:5 %s -o - | FileCheck -check-prefix=CHECK-CC2 %s
+  // CHECK-CC2: foo
+  // CHECK-CC2: in_base
+  // CHECK-CC2: stop
+  
+
diff --git a/test/CodeCompletion/truncation.c b/test/CodeCompletion/truncation.c
new file mode 100644
index 0000000..134139d
--- /dev/null
+++ b/test/CodeCompletion/truncation.c
@@ -0,0 +1,11 @@
+#include "truncation.c.h"
+
+struct 
+
+// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s.h:4:8 -o - %s | FileCheck -check-prefix=CC1 %s
+// CHECK-CC1: X
+// CHECK-CC1-NEXT: Y
+// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:3:8 -o - %s | FileCheck -check-prefix=CC2 %s
+// CHECK-CC2: X
+// CHECK-CC2: Xa
+// CHECK-CC2: Y
diff --git a/test/CodeCompletion/truncation.c.h b/test/CodeCompletion/truncation.c.h
new file mode 100644
index 0000000..a5ebbac
--- /dev/null
+++ b/test/CodeCompletion/truncation.c.h
@@ -0,0 +1,5 @@
+struct X { };
+struct Y { };
+
+struct Xa { };
+
diff --git a/test/CodeCompletion/using-namespace.cpp b/test/CodeCompletion/using-namespace.cpp
new file mode 100644
index 0000000..eb1c2bd
--- /dev/null
+++ b/test/CodeCompletion/using-namespace.cpp
@@ -0,0 +1,20 @@
+namespace N4 {
+  namespace N3 { }
+}
+
+class N3;
+
+namespace N2 {
+  namespace I1 { }
+  namespace I4 = I1;
+  namespace I5 { }
+  namespace I1 { }
+  
+  void foo() {
+    using namespace
+    // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:14:20 %s -o - | FileCheck -check-prefix=CC1 %s
+    // CHECK-CC1: I1
+    // CHECK-CC1: I4
+    // CHECK-CC1: I5
+    // CHECK-CC1: N2
+    // CHECK-CC1-NEXT: N4
diff --git a/test/CodeCompletion/using.cpp b/test/CodeCompletion/using.cpp
new file mode 100644
index 0000000..b84aa26
--- /dev/null
+++ b/test/CodeCompletion/using.cpp
@@ -0,0 +1,24 @@
+namespace N4 {
+  namespace N3 { }
+}
+
+class N3;
+
+namespace N2 {
+  namespace I1 { }
+  namespace I4 = I1;
+  namespace I5 { }
+  namespace I1 { }
+  
+  void foo() {
+    int N3;
+    
+    using
+    // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:16:10 %s -o - | FileCheck -check-prefix=CC1 %s
+    // CHECK-CC1: I1
+    // CHECK-CC1: I4
+    // CHECK-CC1: I5
+    // CHECK-CC1: N2
+    // CHECK-CC1: N3
+    // CHECK-CC1-NEXT: N4
+
diff --git a/test/CodeGen/2007-11-29-ArraySizeFromInitializer.c b/test/CodeGen/2007-11-29-ArraySizeFromInitializer.c
new file mode 100644
index 0000000..a1ec633
--- /dev/null
+++ b/test/CodeGen/2007-11-29-ArraySizeFromInitializer.c
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -emit-llvm %s -o %t
+
+int array[] = {1, 2, 3, 4, 5};
+
diff --git a/test/CodeGen/2008-02-07-bitfield-bug.c b/test/CodeGen/2008-02-07-bitfield-bug.c
new file mode 100644
index 0000000..73e31e7
--- /dev/null
+++ b/test/CodeGen/2008-02-07-bitfield-bug.c
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 %s -emit-llvm -o %t
+// PR1990
+
+struct test {
+  char a[3];
+  unsigned char b:1;
+};
+
+void f(struct test *t) {
+  t->b = 1;
+}
diff --git a/test/CodeGen/2008-02-08-bitfield-bug.c b/test/CodeGen/2008-02-08-bitfield-bug.c
new file mode 100644
index 0000000..1549b72
--- /dev/null
+++ b/test/CodeGen/2008-02-08-bitfield-bug.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 %s -emit-llvm -o %t
+
+struct test {
+  unsigned a:1;
+  unsigned b:1;
+};
+
+struct test *t;
+
diff --git a/test/CodeGen/2008-02-26-inline-asm-bug.c b/test/CodeGen/2008-02-26-inline-asm-bug.c
new file mode 100644
index 0000000..1103e9b
--- /dev/null
+++ b/test/CodeGen/2008-02-26-inline-asm-bug.c
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -emit-llvm < %s | grep "\$0,\$1"
+
+void f() {
+  int d1, d2;
+  asm("%0,%1": "=r" (d1) : "r" (d2));
+}
diff --git a/test/CodeGen/2008-07-17-no-emit-on-error.c b/test/CodeGen/2008-07-17-no-emit-on-error.c
new file mode 100644
index 0000000..0452325
--- /dev/null
+++ b/test/CodeGen/2008-07-17-no-emit-on-error.c
@@ -0,0 +1,14 @@
+// RUN: rm -f %t1.bc
+// RUN: %clang_cc1 -DPASS %s -emit-llvm-bc -o %t1.bc
+// RUN: test -f %t1.bc
+// RUN: not %clang_cc1 %s -emit-llvm-bc -o %t1.bc
+// RUN: not test -f %t1.bc
+
+void f() {
+}
+
+#ifndef PASS
+void g() {
+  *10;
+}
+#endif
diff --git a/test/CodeGen/2008-07-21-mixed-var-fn-decl.c b/test/CodeGen/2008-07-21-mixed-var-fn-decl.c
new file mode 100644
index 0000000..ac13260
--- /dev/null
+++ b/test/CodeGen/2008-07-21-mixed-var-fn-decl.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+
+int g0, f0();
+int f1(), g1;
+
+// CHECK: @g0 = common global i32 0, align 4
+// CHECK: @g1 = common global i32 0, align 4
+
diff --git a/test/CodeGen/2008-07-22-bitfield-init-after-zero-len-array.c b/test/CodeGen/2008-07-22-bitfield-init-after-zero-len-array.c
new file mode 100644
index 0000000..33bd800
--- /dev/null
+++ b/test/CodeGen/2008-07-22-bitfield-init-after-zero-len-array.c
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -triple=i686-apple-darwin9 -emit-llvm -o - %s | FileCheck %s
+
+struct et7 {
+  float lv7[0];
+  char mv7:6;
+} yv7 = {
+  {}, 
+  52, 
+};
+
+// CHECK: @yv7 = global 
+// CHECK: i8 52,
diff --git a/test/CodeGen/2008-07-22-packed-bitfield-access.c b/test/CodeGen/2008-07-22-packed-bitfield-access.c
new file mode 100644
index 0000000..76b942d
--- /dev/null
+++ b/test/CodeGen/2008-07-22-packed-bitfield-access.c
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 %s -emit-llvm -o -
+
+int main () {
+  struct foo {
+    unsigned a:16;
+    unsigned b:32 __attribute__ ((packed));
+  } x;
+  x.b = 0x56789abcL;
+  return 0;
+}
diff --git a/test/CodeGen/2008-07-29-override-alias-decl.c b/test/CodeGen/2008-07-29-override-alias-decl.c
new file mode 100644
index 0000000..a4bea0e
--- /dev/null
+++ b/test/CodeGen/2008-07-29-override-alias-decl.c
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+
+int x() { return 1; }
+
+// CHECK:  [[retval:%.*]] = alloca i32
+// CHECK:  store i32 1, i32* [[retval]]
+// CHECK:  [[load:%.*]] = load i32* [[retval]]
+// CHECK:  ret i32 [[load]]
+
+
+int f() __attribute__((weak, alias("x")));
+
+/* Test that we link to the alias correctly instead of making a new
+   forward definition. */
+int f();
+int h() {
+  return f();
+}
+
+// CHECK:  [[retval:%.*]] = alloca i32
+// CHECK:  [[call:%.*]] = call i32 (...)* @f()
+// CHECK:  store i32 [[call]], i32* [[retval]]
+// CHECK:  [[load:%.*]] = load i32* [[retval]]
+// CHECK:  ret i32 [[load]]
+
diff --git a/test/CodeGen/2008-07-30-implicit-initialization.c b/test/CodeGen/2008-07-30-implicit-initialization.c
new file mode 100644
index 0000000..8c719bb
--- /dev/null
+++ b/test/CodeGen/2008-07-30-implicit-initialization.c
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm-bc -o - %s | opt --std-compile-opts | llvm-dis > %t
+// RUN: grep "ret i32" %t | count 2
+// RUN: grep "ret i32 0" %t | count 2
+// <rdar://problem/6113085>
+
+struct s0 {
+  int x, y;
+};
+
+int f0() {
+  struct s0 x = {0};
+  return x.y;
+}
+
+#if 0
+/* Optimizer isn't smart enough to reduce this since we use
+   memset. Hrm. */
+int f1() {
+  struct s0 x[2] = { {0} };
+  return x[1].x;
+}
+#endif
+
+int f2() {
+  int x[2] = { 0 };
+  return x[1];
+}
+
diff --git a/test/CodeGen/2008-07-30-redef-of-bitcasted-decl.c b/test/CodeGen/2008-07-30-redef-of-bitcasted-decl.c
new file mode 100644
index 0000000..546590e
--- /dev/null
+++ b/test/CodeGen/2008-07-30-redef-of-bitcasted-decl.c
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s
+// <rdar://problem/6108358>
+
+/* For posterity, the issue here begins initial "char []" decl for
+ * s. This is a tentative definition and so a global was being
+ * emitted, however the mapping in GlobalDeclMap referred to a bitcast
+ * of this global.
+ *
+ * The problem was that later when the correct definition for s is
+ * emitted we were doing a RAUW on the old global which was destroying
+ * the bitcast in the GlobalDeclMap (since it cannot be replaced
+ * properly), leaving a dangling pointer.
+ *
+ * The purpose of bar is just to trigger a use of the old decl
+ * sometime after the dangling pointer has been introduced.
+ */
+
+char s[];
+
+static void bar(void *db) {
+  eek(s);
+}
+
+char s[5] = "hi";
+
+int foo() {
+  bar(0);
+}
diff --git a/test/CodeGen/2008-07-31-asm-labels.c b/test/CodeGen/2008-07-31-asm-labels.c
new file mode 100644
index 0000000..130ad6b
--- /dev/null
+++ b/test/CodeGen/2008-07-31-asm-labels.c
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -emit-llvm -o %t %s
+// RUN: grep "@pipe()" %t | count 0
+// RUN: grep '_thisIsNotAPipe' %t | count 3
+// RUN: grep 'g0' %t | count 0
+// RUN: grep '_renamed' %t | count 2
+// RUN: %clang_cc1 -DUSE_DEF -emit-llvm -o %t %s
+// RUN: grep "@pipe()" %t | count 0
+// RUN: grep '_thisIsNotAPipe' %t | count 3
+// <rdr://6116729>
+
+void pipe() asm("_thisIsNotAPipe");
+
+void f0() {
+  pipe();
+}
+
+void pipe(int);
+
+void f1() {
+  pipe(1);
+}
+
+#ifdef USE_DEF
+void pipe(int arg) {
+  int x = 10;
+}
+#endif
+
+// PR3698
+extern int g0 asm("_renamed");
+int f2() {
+  return g0;
+}
diff --git a/test/CodeGen/2008-07-31-promotion-of-compound-pointer-arithmetic.c b/test/CodeGen/2008-07-31-promotion-of-compound-pointer-arithmetic.c
new file mode 100644
index 0000000..de06263
--- /dev/null
+++ b/test/CodeGen/2008-07-31-promotion-of-compound-pointer-arithmetic.c
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm-bc -o - %s | opt -std-compile-opts | llvm-dis | grep "ret i32 1" | count 3
+// <rdr://6115726>
+
+int f0() {
+  int x;
+  unsigned short n = 1;
+  int *a = &x;
+  int *b = &x;
+  a = a - n;
+  b -= n;
+  return a == b;
+}
+
+int f1(int *a) {
+  long b = a - (int*) 1;
+  a -= (int*) 1;
+  return b == (long) a;
+}
+
+int f2(long n) {
+  int *b = n + (int*) 1;
+  n += (int*) 1;
+  return b == (int*) n;
+}
+
diff --git a/test/CodeGen/2008-08-04-void-pointer-arithmetic.c b/test/CodeGen/2008-08-04-void-pointer-arithmetic.c
new file mode 100644
index 0000000..dbfc107
--- /dev/null
+++ b/test/CodeGen/2008-08-04-void-pointer-arithmetic.c
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s
+// <rdar://problem/6122967>
+
+int f0(void *a, void *b) {
+  return a - b;
+}
diff --git a/test/CodeGen/2008-08-19-cast-of-typedef.c b/test/CodeGen/2008-08-19-cast-of-typedef.c
new file mode 100644
index 0000000..740f48a
--- /dev/null
+++ b/test/CodeGen/2008-08-19-cast-of-typedef.c
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -emit-llvm -o %t %s
+
+typedef short T[4];
+struct s {
+  T f0;
+};
+
+void foo(struct s *x) {
+  bar((long) x->f0);
+}
diff --git a/test/CodeGen/2008-08-25-incompatible-cond-expr.m b/test/CodeGen/2008-08-25-incompatible-cond-expr.m
new file mode 100644
index 0000000..f285cca
--- /dev/null
+++ b/test/CodeGen/2008-08-25-incompatible-cond-expr.m
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -emit-llvm -o %t %s
+
+@protocol P0
+@end
+@interface A <P0>
+@end
+
+id f0(int a, id<P0> x, A* p) {
+  return a ? x : p;
+}
diff --git a/test/CodeGen/2008-09-22-bad-switch-type.c b/test/CodeGen/2008-09-22-bad-switch-type.c
new file mode 100644
index 0000000..853e6bd
--- /dev/null
+++ b/test/CodeGen/2008-09-22-bad-switch-type.c
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -emit-llvm -o %t %s
+// PR2817
+
+void f0(void) {
+  switch (0) {
+  case (unsigned long long) 0 < 0: 
+    break;
+  }
+
+  switch (0) {
+  case (unsigned long long) 0 > 0: 
+    break;
+  }
+
+  switch (0) {
+  case (unsigned long long) 0 <= 0: 
+    break;
+  }
+
+  switch (0) {
+  case (unsigned long long) 0 >= 0: 
+    break;
+  }
+
+  switch (0) {
+  case (unsigned long long) 0 == 0: 
+    break;
+  }
+
+  switch (0) {
+  case (unsigned long long) 0 != 0: 
+    break;
+  }
+}
diff --git a/test/CodeGen/2008-12-02-logical-or-fold.c b/test/CodeGen/2008-12-02-logical-or-fold.c
new file mode 100644
index 0000000..167ad29
--- /dev/null
+++ b/test/CodeGen/2008-12-02-logical-or-fold.c
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s | grep "store i32 1"
+// PR3150
+
+int a() {return 1||1;}
diff --git a/test/CodeGen/2009-01-21-invalid-debug-info.m b/test/CodeGen/2009-01-21-invalid-debug-info.m
new file mode 100644
index 0000000..af912e2
--- /dev/null
+++ b/test/CodeGen/2009-01-21-invalid-debug-info.m
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -S -g -o %t.s %s
+
+// FIXME: This test case can be removed at some point (since it will
+// no longer effectively test anything). The reason it was causing
+// trouble was the synthesized self decl in im1 was causing the debug
+// info for I1* to be generated, but referring to an invalid compile
+// unit. This was later referred to by f1 and created ill formed debug
+// information.
+
+@interface I1 @end
+
+@implementation I1
+-im0 { return 0; }
+@end
+
+I1 *f1(void) { return 0; }
diff --git a/test/CodeGen/2009-03-22-increment-bitfield.c b/test/CodeGen/2009-03-22-increment-bitfield.c
new file mode 100644
index 0000000..407aea2
--- /dev/null
+++ b/test/CodeGen/2009-03-22-increment-bitfield.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -emit-llvm -O1 < %s | grep "ret i32 0"
+
+int a(void) {
+  return ++(struct x {unsigned x : 2;}){3}.x;
+}
+
+
diff --git a/test/CodeGen/2009-04-23-dbg.c b/test/CodeGen/2009-04-23-dbg.c
new file mode 100644
index 0000000..6a8bf01
--- /dev/null
+++ b/test/CodeGen/2009-04-23-dbg.c
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -g -o %t  %s -emit-llvm-bc && llc %t -o %t.s
+# 1 "a.c"
+# 1 "a.c" 1
+# 1 "<built-in>" 1
+# 103 "<built-in>"
+# 103 "<command line>" 1
+
+# 1 "/private/tmp/a.h" 1
+int bar;
+# 105 "<command line>" 2
+# 105 "<built-in>" 2
+# 1 "a.c" 2
+# 1 "/private/tmp/a.h" 1
+int bar;
+# 2 "a.c" 2
+
+int main() {
+ bar = 0;
+ return 0;
+}
diff --git a/test/CodeGen/2009-05-22-callingconv.c b/test/CodeGen/2009-05-22-callingconv.c
new file mode 100644
index 0000000..3e616d9
--- /dev/null
+++ b/test/CodeGen/2009-05-22-callingconv.c
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple i386-unknown-unknown | grep call | grep x86_stdcallcc
+void abort(void) __attribute__((__noreturn__));
+typedef void re_string_t;
+typedef void re_dfa_t;
+typedef int reg_errcode_t;
+static reg_errcode_t re_string_construct (re_string_t *pstr, const char *str,
+       int len, char * trans,
+       int icase, const re_dfa_t *dfa)
+     __attribute__ ((regparm (3), stdcall));
+static reg_errcode_t
+re_string_construct (pstr, str, len, trans, icase, dfa)
+     re_string_t *pstr;
+     const char *str;
+     int len, icase;
+     char * trans;
+     const re_dfa_t *dfa;
+{
+        if (dfa != (void*)0x282020c0)
+                abort();
+return 0;
+}
+int main()
+{
+  return re_string_construct(0, 0, 0, 0, 0, (void*)0x282020c0);
+}
diff --git a/test/CodeGen/2009-05-28-const-typedef.c b/test/CodeGen/2009-05-28-const-typedef.c
new file mode 100644
index 0000000..3464fde
--- /dev/null
+++ b/test/CodeGen/2009-05-28-const-typedef.c
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -emit-llvm %s -o -
+// PR4281
+
+typedef struct {
+        int i;
+} something;
+
+typedef const something const_something;
+
+something fail(void);
+
+int
+main(int argc, char *argv[])
+{
+        const_something R = fail();
+}
+
diff --git a/test/CodeGen/2009-06-01-addrofknr.c b/test/CodeGen/2009-06-01-addrofknr.c
new file mode 100644
index 0000000..17d6fdf
--- /dev/null
+++ b/test/CodeGen/2009-06-01-addrofknr.c
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 %s -o %t -emit-llvm -verify
+// PR4289
+
+struct funcptr {
+  int (*func)();
+};
+
+static int func(f)
+  void *f;
+{
+  return 0;
+}
+
+int
+main(int argc, char *argv[])
+{
+  struct funcptr fp;
+
+  fp.func = &func;
+  fp.func = func;
+}
diff --git a/test/CodeGen/2009-06-14-anonymous-union-init.c b/test/CodeGen/2009-06-14-anonymous-union-init.c
new file mode 100644
index 0000000..8ccd7bc
--- /dev/null
+++ b/test/CodeGen/2009-06-14-anonymous-union-init.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -emit-llvm < %s | grep "zeroinitializer, i16 16877"
+// PR4390
+struct sysfs_dirent {
+ union { struct sysfs_elem_dir {} s_dir; };
+ unsigned short s_mode;
+};
+struct sysfs_dirent sysfs_root = { {}, 16877 };
diff --git a/test/CodeGen/2009-07-31-DbgDeclare.c b/test/CodeGen/2009-07-31-DbgDeclare.c
new file mode 100644
index 0000000..3ccb263
--- /dev/null
+++ b/test/CodeGen/2009-07-31-DbgDeclare.c
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -S -g -o %t.s %s
+void foo() {
+     int i = 0;
+     i = 42;
+}
diff --git a/test/CodeGen/2009-08-14-vararray-crash.c b/test/CodeGen/2009-08-14-vararray-crash.c
new file mode 100644
index 0000000..7f489bc
--- /dev/null
+++ b/test/CodeGen/2009-08-14-vararray-crash.c
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -emit-llvm < %s
+
+void sum1(int rb) {
+  typedef unsigned char imgrow[rb];
+  typedef imgrow img[rb];
+
+  const img *br;
+  int y;
+
+  (*br)[y];
+}
diff --git a/test/CodeGen/2009-10-20-GlobalDebug.c b/test/CodeGen/2009-10-20-GlobalDebug.c
new file mode 100644
index 0000000..99be469
--- /dev/null
+++ b/test/CodeGen/2009-10-20-GlobalDebug.c
@@ -0,0 +1,4 @@
+// RUN: %clang -ccc-host-triple i386-apple-darwin10 -S -g -dA %s -o - | FileCheck %s
+int global;
+// CHECK: asciz "global" ## External Name
+int main() { return 0;}
diff --git a/test/CodeGen/2010-02-09-DbgSelf.m b/test/CodeGen/2010-02-09-DbgSelf.m
new file mode 100644
index 0000000..e09adac
--- /dev/null
+++ b/test/CodeGen/2010-02-09-DbgSelf.m
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -x objective-c -emit-llvm -g < %s | grep  "\"self\", metadata" 
+// Test to check that "self" argument is assigned a location.
+
+@interface Foo 
+-(void) Bar: (int)x ;
+@end
+
+
+@implementation Foo
+-(void) Bar: (int)x 
+{
+}
+@end
+
diff --git a/test/CodeGen/2010-02-15-Dbg-MethodStart.m b/test/CodeGen/2010-02-15-Dbg-MethodStart.m
new file mode 100644
index 0000000..5186b20
--- /dev/null
+++ b/test/CodeGen/2010-02-15-Dbg-MethodStart.m
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -x objective-c -emit-llvm -g < %s | grep  subprogram | grep "i32 9"
+// Test to check that subprogram start location.
+
+@interface Foo
+-(int) barMethod;
+@end
+
+@implementation Foo
+-(int) barMethod {
+  int i = 0;
+  int j = 1;
+  int k = 1;
+  return i + j + k;
+}
+@end
diff --git a/test/CodeGen/2010-02-16-DbgScopes.c b/test/CodeGen/2010-02-16-DbgScopes.c
new file mode 100644
index 0000000..b11f920
--- /dev/null
+++ b/test/CodeGen/2010-02-16-DbgScopes.c
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -emit-llvm -g < %s | grep  lexical | count 5
+// Test to check number of lexical scope identified in debug info.
+
+extern int bar();
+extern void foobar();
+void foo(int s) {
+  unsigned loc = 0;
+  if (s) {
+    if (bar()) {
+      foobar();
+    }
+  } else {
+    loc = 1;
+    if (bar()) {
+      loc = 2;
+    }
+  }
+}
diff --git a/test/CodeGen/2010-02-18-Dbg-VectorType.c b/test/CodeGen/2010-02-18-Dbg-VectorType.c
new file mode 100644
index 0000000..eb17d11
--- /dev/null
+++ b/test/CodeGen/2010-02-18-Dbg-VectorType.c
@@ -0,0 +1,9 @@
+// RUN: %clang -emit-llvm -S -O0 -g %s -o - | grep DW_TAG_typedef | grep float4
+typedef float float4 __attribute__((vector_size(16)));
+
+int main(){
+  volatile float4 x = (float4) { 0.0f, 1.0f, 2.0f, 3.0f };
+  x += x;
+  return 0;
+}
+
diff --git a/test/CodeGen/2010-03-09-DbgInfo.c b/test/CodeGen/2010-03-09-DbgInfo.c
new file mode 100644
index 0000000..04ee02e
--- /dev/null
+++ b/test/CodeGen/2010-03-09-DbgInfo.c
@@ -0,0 +1,2 @@
+// RUN: %clang -dA -S -O0 -g %s -o - | grep DW_TAG_variable
+unsigned char ctable1[1] = { 0001 };
diff --git a/test/CodeGen/OpaqueStruct.c b/test/CodeGen/OpaqueStruct.c
new file mode 100644
index 0000000..fe96126
--- /dev/null
+++ b/test/CodeGen/OpaqueStruct.c
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 %s -emit-llvm -o %t
+typedef struct a b;
+
+b* x;
+
+struct a {
+  b* p;
+};
+
+void f() {
+  b* z = x->p;
+}
diff --git a/test/CodeGen/PR2001-bitfield-reload.c b/test/CodeGen/PR2001-bitfield-reload.c
new file mode 100644
index 0000000..d05aef3
--- /dev/null
+++ b/test/CodeGen/PR2001-bitfield-reload.c
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown -O3 -emit-llvm -o - %s | FileCheck %s
+// PR2001
+
+/* Test that the result of the assignment properly uses the value *in
+   the bitfield* as opposed to the RHS. */
+static int foo(int i) {
+  struct {
+    int f0 : 2;
+  } x;
+  return (x.f0 = i);
+}
+
+int bar() {
+  // CHECK: ret i32 1
+  return foo(-5) == -1;
+}
diff --git a/test/CodeGen/PR2413-void-address-cast-error.c b/test/CodeGen/PR2413-void-address-cast-error.c
new file mode 100644
index 0000000..3920dfd
--- /dev/null
+++ b/test/CodeGen/PR2413-void-address-cast-error.c
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -emit-llvm %s -o -
+void f()
+{
+        void *addr;
+        addr = (void *)( ((long int)addr + 7L) );
+}
diff --git a/test/CodeGen/PR2643-null-store-to-bitfield.c b/test/CodeGen/PR2643-null-store-to-bitfield.c
new file mode 100644
index 0000000..d6c2f36
--- /dev/null
+++ b/test/CodeGen/PR2643-null-store-to-bitfield.c
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s
+// PR2643
+
+void foo() {
+  struct {
+    int a : 1;
+    int b : 1;
+  } entry = {0};
+}
+
diff --git a/test/CodeGen/PR2743-reference-missing-static.c b/test/CodeGen/PR2743-reference-missing-static.c
new file mode 100644
index 0000000..f32d6c5
--- /dev/null
+++ b/test/CodeGen/PR2743-reference-missing-static.c
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -emit-llvm -o %t %s
+// PR2743
+// <rdr://6094512>
+
+/* CodeGen should handle this even if it makes it past
+   sema. Unfortunately this test will become useless once sema starts
+   rejecting this. */
+
+static void e0();
+void f0() { e0(); }
+
+inline void e1();
+void f1() { e1(); }
+
+void e2() __attribute__((weak));
+void f2() { e2(); }
diff --git a/test/CodeGen/PR3130-cond-constant.c b/test/CodeGen/PR3130-cond-constant.c
new file mode 100644
index 0000000..dbec650
--- /dev/null
+++ b/test/CodeGen/PR3130-cond-constant.c
@@ -0,0 +1,3 @@
+// RUN: %clang_cc1 -emit-llvm %s -o -
+
+int a = 2.0 ? 1 : 2;
diff --git a/test/CodeGen/PR3589-freestanding-libcalls.c b/test/CodeGen/PR3589-freestanding-libcalls.c
new file mode 100644
index 0000000..8b8282f
--- /dev/null
+++ b/test/CodeGen/PR3589-freestanding-libcalls.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - | grep 'declare i32 @printf' | count 1
+// RUN: %clang_cc1 -O2 -emit-llvm %s -o - | grep 'declare i32 @puts' | count 1
+// RUN: %clang_cc1 -ffreestanding -O2 -emit-llvm %s -o - | grep 'declare i32 @puts' | count 0
+
+int printf(const char *, ...);
+
+void f0() {
+  printf("hello\n");
+}
diff --git a/test/CodeGen/PR3613-static-decl.c b/test/CodeGen/PR3613-static-decl.c
new file mode 100644
index 0000000..7f6d979
--- /dev/null
+++ b/test/CodeGen/PR3613-static-decl.c
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -o %t %s
+// RUN: grep '@g0 = internal global %.truct.s0 { i32 3 }' %t | count 1
+
+struct s0 {
+  int a;
+};
+
+static struct s0 g0;
+
+static int f0(void) {
+  return g0.a;
+}
+
+static struct s0 g0 = {3};
+
+void *g1 = f0;
diff --git a/test/CodeGen/PR3709-int-to-pointer-sign.c b/test/CodeGen/PR3709-int-to-pointer-sign.c
new file mode 100644
index 0000000..f77737e
--- /dev/null
+++ b/test/CodeGen/PR3709-int-to-pointer-sign.c
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -O1 -triple=x86_64-gnu-linux | grep "i64 -1"
+
+// PR3709
+long long a() { return (long long)(int*)-1;}
+
diff --git a/test/CodeGen/PR4611-bitfield-layout.c b/test/CodeGen/PR4611-bitfield-layout.c
new file mode 100644
index 0000000..3975ed0
--- /dev/null
+++ b/test/CodeGen/PR4611-bitfield-layout.c
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown %s -emit-llvm -o %t
+// RUN: grep "struct.object_entry = type { i8, \[2 x i8\], i8 }" %t
+
+struct object_entry {
+       unsigned int type:3, pack_id:16, depth:13;
+} entries;
diff --git a/test/CodeGen/PR5060-align.c b/test/CodeGen/PR5060-align.c
new file mode 100644
index 0000000..efd8520
--- /dev/null
+++ b/test/CodeGen/PR5060-align.c
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -verify | FileCheck %s
+
+// CHECK: @foo.p = internal global i8 0, align 32
+char *foo(void) {
+  static char p __attribute__((aligned(32)));
+  return &p;
+}
+
+void bar(long n) {
+  // CHECK: align 32
+  char p[n] __attribute__((aligned(32)));
+}
+
diff --git a/test/CodeGen/address-space-cast.c b/test/CodeGen/address-space-cast.c
new file mode 100644
index 0000000..076c2f1
--- /dev/null
+++ b/test/CodeGen/address-space-cast.c
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -emit-llvm < %s
+
+volatile unsigned char* const __attribute__((address_space(1))) serial_ctrl = 0x02;
+
diff --git a/test/CodeGen/address-space-compound-literal.c b/test/CodeGen/address-space-compound-literal.c
new file mode 100644
index 0000000..37d9c7b
--- /dev/null
+++ b/test/CodeGen/address-space-compound-literal.c
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -emit-llvm < %s | grep "internal addrspace(1) global i32 1"
+
+typedef int a __attribute__((address_space(1)));
+a* x = &(a){1};
+
diff --git a/test/CodeGen/address-space-field1.c b/test/CodeGen/address-space-field1.c
new file mode 100644
index 0000000..a81e08e
--- /dev/null
+++ b/test/CodeGen/address-space-field1.c
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -emit-llvm < %s -o - | FileCheck %s
+// CHECK:%struct.S = type { i32, i32 }
+// CHECK:define void @test_addrspace(%struct.S addrspace(1)* %p1, %struct.S addrspace(2)* %p2) nounwind
+// CHECK:  [[p1addr:%.*]] = alloca %struct.S addrspace(1)*
+// CHECK:  [[p2addr:%.*]] = alloca %struct.S addrspace(2)*
+// CHECK:  store %struct.S addrspace(1)* %p1, %struct.S addrspace(1)** [[p1addr]]
+// CHECK:  store %struct.S addrspace(2)* %p2, %struct.S addrspace(2)** [[p2addr]]
+// CHECK:  [[t0:%.*]] = load %struct.S addrspace(2)** [[p2addr]]   ; <%struct.S addrspace(2)*> [#uses=1]
+// CHECK:  [[t1:%.*]] = getelementptr inbounds %struct.S addrspace(2)* [[t0]], i32 0, i32 1 ; <i32 addrspace(2)*> [#uses=1]
+// CHECK:  [[t2:%.*]] = load i32 addrspace(2)* [[t1]]            ; <i32> [#uses=1]
+// CHECK:  [[t3:%.*]] = load %struct.S addrspace(1)** [[p1addr]]  ; <%struct.S addrspace(1)*> [#uses=1]
+// CHECK:  [[t4:%.*]] = getelementptr inbounds %struct.S addrspace(1)* [[t3]], i32 0, i32 0 ; <i32 addrspace(1)*> [#uses=1]
+// CHECK:  store i32 [[t2]], i32 addrspace(1)* [[t4]]
+// CHECK:  [[t5:%.*]] = load %struct.S addrspace(2)** [[p2addr]]  ; <%struct.S addrspace(2)*> [#uses=1]
+// CHECK:  [[t6:%.*]] = getelementptr inbounds %struct.S addrspace(2)* [[t5]], i32 0, i32 0 ; <i32 addrspace(2)*> [#uses=1]
+// CHECK:  [[t7:%.*]] = load i32 addrspace(2)* [[t6]]            ; <i32> [#uses=1]
+// CHECK:  [[t8:%.*]] = load %struct.S addrspace(1)** [[p1addr]]  ; <%struct.S addrspace(1)*> [#uses=1]
+// CHECK:  [[t9:%.*]] = getelementptr inbounds %struct.S addrspace(1)* [[t8]], i32 0, i32 1 ; <i32 addrspace(1)*> [#uses=1]
+// CHECK:  store i32 [[t7]], i32 addrspace(1)* [[t9]]
+// CHECK:  ret void
+// CHECK:}
+
+// Check that we don't lose the address space when accessing a member
+// of a structure.
+
+#define __addr1    __attribute__((address_space(1)))
+#define __addr2    __attribute__((address_space(2)))
+
+typedef struct S {
+  int a;
+  int b;
+} S;
+
+void test_addrspace(__addr1 S* p1, __addr2 S*p2) {
+  // swap
+  p1->a = p2->b;
+  p1->b = p2->a;
+}
diff --git a/test/CodeGen/address-space-field2.c b/test/CodeGen/address-space-field2.c
new file mode 100644
index 0000000..198fd22
--- /dev/null
+++ b/test/CodeGen/address-space-field2.c
@@ -0,0 +1,50 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s
+// CHECK: addrspace(1)
+// CHECK: addrspace(2)
+// CHECK: addrspace(1)
+// CHECK: addrspace(1)
+// CHECK: addrspace(2)
+// CHECK: addrspace(2)
+// CHECK: addrspace(1)
+// CHECK: addrspace(1)
+// CHECK: addrspace(2)
+// CHECK: addrspace(2)
+// CHECK: addrspace(1)
+// CHECK: addrspace(1)
+// CHECK: addrspace(1)
+// CHECK: addrspace(1)
+// CHECK: addrspace(1)
+// CHECK: addrspace(1)
+// CHECK: addrspace(1)
+// CHECK: addrspace(1)
+// CHECK: addrspace(1)
+// CHECK: addrspace(2)
+// CHECK: addrspace(2)
+// CHECK: addrspace(2)
+// CHECK: addrspace(2)
+// CHECK: addrspace(2)
+// CHECK: addrspace(2)
+// CHECK: addrspace(2)
+// CHECK: addrspace(2)
+// CHECK: addrspace(2)
+// CHECK: addrspace(2)
+// CHECK: addrspace(2)
+
+// Check that we don't lose the address space when accessing an array element
+// inside a structure.
+
+#define __addr1    __attribute__((address_space(1)))
+#define __addr2    __attribute__((address_space(2)))
+
+typedef struct S {
+  int arr[ 3 ];
+} S;
+
+void test_addrspace(__addr1 S* p1, __addr2 S*p2, int* val, int n) {
+  for (int i=0; i < 3; ++i) {
+    int t = val[i];
+    p1->arr[i] = t;
+    for (int j=0; j < n; ++j)
+      p2[j].arr[i] = t;
+  }
+}
diff --git a/test/CodeGen/address-space-field3.c b/test/CodeGen/address-space-field3.c
new file mode 100644
index 0000000..090f4a1
--- /dev/null
+++ b/test/CodeGen/address-space-field3.c
@@ -0,0 +1,46 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s
+// CHECK: addrspace(1)
+// CHECK: addrspace(2)
+// CHECK: addrspace(1)
+// CHECK: addrspace(1)
+// CHECK: addrspace(2)
+// CHECK: addrspace(2)
+// CHECK: addrspace(1)
+// CHECK: addrspace(1)
+// CHECK: addrspace(2)
+// CHECK: addrspace(2)
+// CHECK: addrspace(2)
+// CHECK: addrspace(2)
+// CHECK: addrspace(2)
+// CHECK: addrspace(2)
+// CHECK: addrspace(2)
+// CHECK: addrspace(2)
+// CHECK: addrspace(2)
+// CHECK: addrspace(2)
+// CHECK: addrspace(2)
+// CHECK: addrspace(1)
+// CHECK: addrspace(1)
+// CHECK: addrspace(1)
+// CHECK: addrspace(1)
+// CHECK: addrspace(1)
+// CHECK: addrspace(1)
+// CHECK: addrspace(1)
+// CHECK: addrspace(1)
+// CHECK: addrspace(1)
+
+// Check that we don't lose the address space when accessing an array element
+// inside a structure.
+
+#define __addr1    __attribute__((address_space(1)))
+#define __addr2    __attribute__((address_space(2)))
+
+typedef struct S {
+  int arr[ 3 ];
+} S;
+
+void test_addrspace(__addr1 S* p1, __addr2 S*p2, int* val, int n) {
+  for (int i=0; i < 3; ++i) {
+    int t = val[i];
+    p1->arr[i] = p2->arr[i];
+  }
+}
diff --git a/test/CodeGen/address-space-field4.c b/test/CodeGen/address-space-field4.c
new file mode 100644
index 0000000..a1906c0
--- /dev/null
+++ b/test/CodeGen/address-space-field4.c
@@ -0,0 +1,61 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s
+// CHECK: addrspace(2)
+// CHECK: addrspace(3)
+// CHECK: addrspace(1)
+// CHECK: addrspace(1)
+// CHECK: addrspace(1)
+// CHECK: addrspace(1)
+// CHECK: addrspace(1)
+// CHECK: addrspace(1)
+// CHECK: addrspace(1)
+// CHECK: addrspace(1)
+// CHECK: addrspace(1)
+// CHECK: addrspace(1)
+// CHECK: addrspace(1)
+// CHECK: addrspace(1)
+// CHECK: addrspace(1)
+// CHECK: addrspace(1)
+// CHECK: addrspace(1)
+// CHECK: addrspace(1)
+// CHECK: addrspace(1)
+// CHECK: addrspace(1)
+// CHECK: addrspace(1)
+// CHECK: addrspace(3)
+// CHECK: addrspace(3)
+// CHECK: addrspace(1)
+// CHECK: addrspace(3)
+// CHECK: addrspace(3)
+// CHECK: addrspace(1)
+// CHECK: addrspace(1)
+// CHECK: addrspace(1)
+// CHECK: addrspace(1)
+// CHECK: addrspace(1)
+// CHECK: addrspace(1)
+// CHECK: addrspace(1)
+// CHECK: addrspace(1)
+// CHECK: addrspace(1)
+// CHECK: addrspace(2)
+// CHECK: addrspace(1)
+// CHECK: addrspace(2)
+// CHECK: addrspace(2)
+// CHECK: addrspace(2)
+
+// Check the load and store are using the correct address space to access
+// the variables.
+
+#define __addr1    __attribute__((address_space(1)))
+#define __addr2    __attribute__((address_space(2)))
+#define __addr3    __attribute__((address_space(3)))
+
+typedef struct Pair {
+  __addr2 int* a;
+  __addr3 int* b;
+} Pair;
+
+typedef struct S {
+  Pair arr[ 3 ];
+} S;
+
+void test_addrspace(__addr1 S* p1, __addr1 S* p2) {
+  *p1->arr[0].a = *p2->arr[1].b;
+}
diff --git a/test/CodeGen/address-space.c b/test/CodeGen/address-space.c
new file mode 100644
index 0000000..5b58919
--- /dev/null
+++ b/test/CodeGen/address-space.c
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -emit-llvm < %s | grep '@foo.*global.*addrspace(1)'
+// RUN: %clang_cc1 -emit-llvm < %s | grep '@ban.*global.*addrspace(1)'
+// RUN: %clang_cc1 -emit-llvm < %s | grep 'load.*addrspace(1)' | count 2
+// RUN: %clang_cc1 -emit-llvm < %s | grep 'load.*addrspace(2).. @A'
+// RUN: %clang_cc1 -emit-llvm < %s | grep 'load.*addrspace(2).. @B'
+
+int foo __attribute__((address_space(1)));
+int ban[10] __attribute__((address_space(1)));
+
+int bar() { return foo; }
+
+int baz(int i) { return ban[i]; }
+
+// Both A and B point into addrspace(2).
+__attribute__((address_space(2))) int *A, *B;
+
+void test3() {
+  *A = *B;
+}
+
diff --git a/test/CodeGen/alias.c b/test/CodeGen/alias.c
new file mode 100644
index 0000000..f2e87a5
--- /dev/null
+++ b/test/CodeGen/alias.c
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -triple i386-pc-linux-gnu -emit-llvm -o %t %s
+// RUN: grep '@g0 = common global i32 0' %t
+// RUN: grep '@f1 = alias void ()\* @f0' %t
+// RUN: grep '@g1 = alias i32\* @g0' %t
+// RUN: grep 'define void @f0() nounwind {' %t
+
+void f0(void) { }
+extern void f1(void);
+extern void f1(void) __attribute((alias("f0")));
+
+int g0;
+extern int g1;
+extern int g1 __attribute((alias("g0")));
+
+// Make sure that aliases cause referenced values to be emitted.
+// PR3200
+// RUN: grep 'define internal i32 @foo1()' %t
+static inline int foo1() { return 0; }
+int foo() __attribute__((alias("foo1")));
+
+
+// RUN: grep '@bar1 = internal global i32 42' %t
+static int bar1 = 42;
+int bar() __attribute__((alias("bar1")));
+
+
+extern int test6();
+void test7() { test6(); }  // test6 is emitted as extern.
+
+// test6 changes to alias.
+int test6() __attribute__((alias("test7")));
+
diff --git a/test/CodeGen/align-local.c b/test/CodeGen/align-local.c
new file mode 100644
index 0000000..b839ee1
--- /dev/null
+++ b/test/CodeGen/align-local.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -emit-llvm < %s | grep "align 16" | count 2
+
+typedef struct __attribute((aligned(16))) {int x[4];} ff;
+
+int a() {
+  ff a;
+  struct {int x[4];} b __attribute((aligned(16)));
+}
diff --git a/test/CodeGen/alignof.c b/test/CodeGen/alignof.c
new file mode 100644
index 0000000..64d0c08
--- /dev/null
+++ b/test/CodeGen/alignof.c
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown -O1 -emit-llvm -o %t %s
+// RUN: grep 'ret i32 4' %t
+
+enum e0 { E0 };
+struct s0 {
+  enum e0         a:31;
+};
+
+struct s0 t1_tmp;
+int f0() {
+  return __alignof__(t1_tmp);
+}
diff --git a/test/CodeGen/always_inline.c b/test/CodeGen/always_inline.c
new file mode 100644
index 0000000..c91fd43
--- /dev/null
+++ b/test/CodeGen/always_inline.c
@@ -0,0 +1,20 @@
+// RUN: %clang -emit-llvm -S -o %t %s
+// RUN: not grep '@f0' %t
+// RUN: not grep 'call ' %t
+// RUN: %clang -mllvm -disable-llvm-optzns -emit-llvm -S -o %t %s
+// RUN: grep '@f0' %t | count 2
+
+//static int f0() { 
+static int __attribute__((always_inline)) f0() { 
+  return 1;
+}
+
+int f1() {
+  return f0();
+}
+
+// PR4372
+inline int f2() __attribute__((always_inline));
+int f2() { return 7; }
+int f3(void) { return f2(); }
+
diff --git a/test/CodeGen/annotate.c b/test/CodeGen/annotate.c
new file mode 100644
index 0000000..84d564a
--- /dev/null
+++ b/test/CodeGen/annotate.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+
+__attribute((annotate("foo"))) char foo;
+void a(char *a) { 
+  __attribute__((annotate("bar"))) static char bar;
+}
+
+// CHECK: @llvm.global.annotations = appending global [2 x %0]
diff --git a/test/CodeGen/arm-arguments.c b/test/CodeGen/arm-arguments.c
new file mode 100644
index 0000000..72fd7c3
--- /dev/null
+++ b/test/CodeGen/arm-arguments.c
@@ -0,0 +1,155 @@
+// RUN: %clang_cc1 -triple armv7-apple-darwin9 -target-abi apcs-gnu -emit-llvm -w -o - %s | FileCheck -check-prefix=APCS-GNU %s
+// RUN: %clang_cc1 -triple armv7-apple-darwin9 -target-abi aapcs -emit-llvm -w -o - %s | FileCheck -check-prefix=AAPCS %s
+
+// APCS-GNU: define arm_apcscc signext i8 @f0()
+// AAPCS: define arm_aapcscc signext i8 @f0()
+char f0(void) {
+  return 0;
+}
+
+// APCS-GNU: define arm_apcscc i8 @f1()
+// AAPCS: define arm_aapcscc i8 @f1()
+struct s1 { char f0; };
+struct s1 f1(void) {}
+
+// APCS-GNU: define arm_apcscc i16 @f2()
+// AAPCS: define arm_aapcscc i16 @f2()
+struct s2 { short f0; };
+struct s2 f2(void) {}
+
+// APCS-GNU: define arm_apcscc i32 @f3()
+// AAPCS: define arm_aapcscc i32 @f3()
+struct s3 { int f0; };
+struct s3 f3(void) {}
+
+// APCS-GNU: define arm_apcscc i32 @f4()
+// AAPCS: define arm_aapcscc i32 @f4()
+struct s4 { struct s4_0 { int f0; } f0; };
+struct s4 f4(void) {}
+
+// APCS-GNU: define arm_apcscc void @f5(
+// APCS-GNU: struct.s5* sret
+// AAPCS: define arm_aapcscc i32 @f5()
+struct s5 { struct { } f0; int f1; };
+struct s5 f5(void) {}
+
+// APCS-GNU: define arm_apcscc void @f6(
+// APCS-GNU: struct.s6* sret
+// AAPCS: define arm_aapcscc i32 @f6()
+struct s6 { int f0[1]; };
+struct s6 f6(void) {}
+
+// APCS-GNU: define arm_apcscc void @f7()
+// AAPCS: define arm_aapcscc void @f7()
+struct s7 { struct { int : 0; } f0; };
+struct s7 f7(void) {}
+
+// APCS-GNU: define arm_apcscc void @f8(
+// APCS-GNU: struct.s8* sret
+// AAPCS: define arm_aapcscc void @f8()
+struct s8 { struct { int : 0; } f0[1]; };
+struct s8 f8(void) {}
+
+// APCS-GNU: define arm_apcscc i32 @f9()
+// AAPCS: define arm_aapcscc i32 @f9()
+struct s9 { int f0; int : 0; };
+struct s9 f9(void) {}
+
+// APCS-GNU: define arm_apcscc i32 @f10()
+// AAPCS: define arm_aapcscc i32 @f10()
+struct s10 { int f0; int : 0; int : 0; };
+struct s10 f10(void) {}
+
+// APCS-GNU: define arm_apcscc void @f11(
+// APCS-GNU: struct.s10* sret
+// AAPCS: define arm_aapcscc i32 @f11()
+struct s11 { int : 0; int f0; };
+struct s11 f11(void) {}
+
+// APCS-GNU: define arm_apcscc i32 @f12()
+// AAPCS: define arm_aapcscc i32 @f12()
+union u12 { char f0; short f1; int f2; };
+union u12 f12(void) {}
+
+// APCS-GNU: define arm_apcscc void @f13(
+// APCS-GNU: struct.s13* sret
+
+// FIXME: This should return a float.
+// AAPCS-FIXME: define arm_aapcscc float @f13()
+struct s13 { float f0; };
+struct s13 f13(void) {}
+
+// APCS-GNU: define arm_apcscc void @f14(
+// APCS-GNU: struct.s13* sret
+// AAPCS: define arm_aapcscc i32 @f14()
+union u14 { float f0; };
+union u14 f14(void) {}
+
+// APCS-GNU: define arm_apcscc void @f15()
+// AAPCS: define arm_aapcscc void @f15()
+void f15(struct s7 a0) {}
+
+// APCS-GNU: define arm_apcscc void @f16()
+// AAPCS: define arm_aapcscc void @f16()
+void f16(struct s8 a0) {}
+
+// APCS-GNU: define arm_apcscc i32 @f17()
+// AAPCS: define arm_aapcscc i32 @f17()
+struct s17 { short f0 : 13; char f1 : 4; };
+struct s17 f17(void) {}
+
+// APCS-GNU: define arm_apcscc i32 @f18()
+// AAPCS: define arm_aapcscc i32 @f18()
+struct s18 { short f0; char f1 : 4; };
+struct s18 f18(void) {}
+
+// APCS-GNU: define arm_apcscc void @f19(
+// APCS-GNU: struct.s19* sret
+// AAPCS: define arm_aapcscc i32 @f19()
+struct s19 { int f0; struct s8 f1; };
+struct s19 f19(void) {}
+
+// APCS-GNU: define arm_apcscc void @f20(
+// APCS-GNU: struct.s20* sret
+// AAPCS: define arm_aapcscc i32 @f20()
+struct s20 { struct s8 f1; int f0; };
+struct s20 f20(void) {}
+
+// APCS-GNU: define arm_apcscc i8 @f21()
+// AAPCS: define arm_aapcscc i32 @f21()
+struct s21 { struct {} f1; int f0 : 4; };
+struct s21 f21(void) {}
+
+// APCS-GNU: define arm_apcscc i16 @f22()
+// APCS-GNU: define arm_apcscc i32 @f23()
+// APCS-GNU: define arm_apcscc i64 @f24()
+// APCS-GNU: define arm_apcscc i128 @f25()
+// APCS-GNU: define arm_apcscc i64 @f26()
+// APCS-GNU: define arm_apcscc i128 @f27()
+// AAPCS: define arm_aapcscc i16 @f22()
+// AAPCS: define arm_aapcscc i32 @f23()
+// AAPCS: define arm_aapcscc void @f24({{.*}} sret
+// AAPCS: define arm_aapcscc void @f25({{.*}} sret
+// AAPCS: define arm_aapcscc void @f26({{.*}} sret
+// AAPCS: define arm_aapcscc void @f27({{.*}} sret
+_Complex char       f22(void) {}
+_Complex short      f23(void) {}
+_Complex int        f24(void) {}
+_Complex long long  f25(void) {}
+_Complex float      f26(void) {}
+_Complex double     f27(void) {}
+
+// APCS-GNU: define arm_apcscc i16 @f28()
+// AAPCS: define arm_aapcscc i16 @f28()
+struct s28 { _Complex char f0; };
+struct s28 f28() {}
+
+// APCS-GNU: define arm_apcscc i32 @f29()
+// AAPCS: define arm_aapcscc i32 @f29()
+struct s29 { _Complex short f0; };
+struct s29 f29() {}
+
+// APCS-GNU: define arm_apcscc void @f30({{.*}} sret
+// AAPCS: define arm_aapcscc void @f30({{.*}} sret
+struct s30 { _Complex int f0; };
+struct s30 f30() {}
diff --git a/test/CodeGen/array.c b/test/CodeGen/array.c
new file mode 100644
index 0000000..0b401ea
--- /dev/null
+++ b/test/CodeGen/array.c
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -emit-llvm %s -o %t
+
+void f() {
+ int a[2];
+ a[0] = 0;
+}
+
+void f2() {
+  int x = 0;
+  int y = 1;
+  int a[10] = { y, x, 2, 3};
+  int b[10] = { 2,4,x,6,y,8};
+  int c[5] = { 0,1,2,3};
+}
diff --git a/test/CodeGen/asm-errors.c b/test/CodeGen/asm-errors.c
new file mode 100644
index 0000000..7323e61
--- /dev/null
+++ b/test/CodeGen/asm-errors.c
@@ -0,0 +1,8 @@
+// RUN: not %clang_cc1 -triple i386-apple-darwin10 -emit-obj %s  > %t 2>&1
+// RUN: FileCheck %s < %t
+
+int test1(int X) {
+// CHECK: error: unrecognized instruction
+  __asm__ ("abc incl    %0" : "+r" (X));
+  return X;
+}
diff --git a/test/CodeGen/asm.c b/test/CodeGen/asm.c
new file mode 100644
index 0000000..5077028
--- /dev/null
+++ b/test/CodeGen/asm.c
@@ -0,0 +1,170 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s
+void t1(int len) {
+  __asm__ volatile("" : "=&r"(len), "+&r"(len));
+}
+
+void t2(unsigned long long t)  {
+  __asm__ volatile("" : "+m"(t));
+}
+
+void t3(unsigned char *src, unsigned long long temp) {
+  __asm__ volatile("" : "+m"(temp), "+r"(src));
+}
+
+void t4() {
+  unsigned long long a;
+  struct reg { unsigned long long a, b; } b;
+
+  __asm__ volatile ("":: "m"(a), "m"(b));
+}
+
+// PR3417
+void t5(int i) {
+  asm("nop" : "=r"(i) : "0"(t5));
+}
+
+// PR3641
+void t6(void) {
+  __asm__ volatile("" : : "i" (t6));
+}
+
+void t7(int a) {
+  __asm__ volatile("T7 NAMED: %[input]" : "+r"(a): [input] "i" (4));
+  // CHECK: @t7(i32
+  // CHECK: T7 NAMED: $1
+}
+
+void t8() {
+  __asm__ volatile("T8 NAMED MODIFIER: %c[input]" :: [input] "i" (4));
+  // CHECK: @t8()
+  // CHECK: T8 NAMED MODIFIER: ${0:c}
+}
+
+// PR3682
+unsigned t9(unsigned int a) {
+  asm("bswap %0 %1" : "+r" (a));
+  return a;
+}
+
+// PR3908
+void t10(int r) {
+  __asm__("PR3908 %[lf] %[xx] %[li] %[r]" : [r] "+r" (r) : [lf] "mx" (0), [li] "mr" (0), [xx] "x" ((double)(0)));
+  
+// CHECK: @t10(
+// CHECK:PR3908 $1 $3 $2 $0
+}         
+
+
+// PR3373
+unsigned t11(signed char input) {
+  unsigned  output;
+  __asm__("xyz"
+          : "=a" (output)
+          : "0" (input));
+  return output;
+}
+
+// PR3373
+unsigned char t12(unsigned input) {
+  unsigned char output;
+  __asm__("xyz"
+          : "=a" (output)
+          : "0" (input));
+  return output;
+}
+
+unsigned char t13(unsigned input) {
+  unsigned char output;
+  __asm__("xyz %1"
+          : "=a" (output)
+          : "0" (input));
+  return output;
+}
+
+struct large {
+  int x[1000];
+};
+
+unsigned long t15(int x, struct large *P) {
+  __asm__("xyz "
+          : "=r" (x)
+          : "m" (*P), "0" (x));
+  return x;
+}
+
+
+
+
+// bitfield destination of an asm.
+struct S {
+  int a : 4;
+};
+
+void t14(struct S *P) {
+  __asm__("abc %0" : "=r"(P->a) );
+}
+
+
+// PR4938
+int t16() {
+  int a,b;
+  asm ( "nop;"
+       :"=%c" (a)
+       : "r" (b)
+       );
+  return 0;
+}
+
+// PR6475
+void t17() {
+  int i;
+  __asm__ ( "nop": "=m"(i));
+  
+// CHECK: @t17()
+// CHECK: call void asm "nop", "=*m,
+}
+
+// <rdar://problem/6841383>
+int t18(unsigned data) {
+  int a, b;
+  
+  asm("xyz" :"=a"(a), "=d"(b) : "a"(data));
+  return a + b;
+// CHECK: t18(i32
+// CHECK: = call {{.*}}asm "xyz"
+// CHECK-NEXT: extractvalue
+// CHECK-NEXT: extractvalue
+}
+
+
+// PR6780
+int t19(unsigned data) {
+  int a, b;
+  
+  asm("x{abc|def|ghi}z" :"=r"(a): "r"(data));
+  return a + b;
+  // CHECK: t19(i32
+  // CHECK: = call {{.*}}asm "x$(abc$|def$|ghi$)z"
+}
+
+
+// PR6845 - Mismatching source/dest fp types.
+double t20(double x) {
+  register long double result;
+  __asm __volatile ("frndint"  : "=t" (result) : "0" (x));
+  return result;
+  
+  // CHECK: @t20
+  // CHECK: fpext double {{.*}} to x86_fp80
+  // CHECK-NEXT: call x86_fp80 asm sideeffect "frndint"
+  // CHECK: fptrunc x86_fp80 {{.*}} to double
+}
+
+float t21(long double x) {
+  register float result;
+  __asm __volatile ("frndint"  : "=t" (result) : "0" (x));
+  return result;
+  // CHECK: @t21
+  // CHECK: call x86_fp80 asm sideeffect "frndint"
+  // CHECK-NEXT: fptrunc x86_fp80 {{.*}} to float
+}
diff --git a/test/CodeGen/asm_arm.c b/test/CodeGen/asm_arm.c
new file mode 100644
index 0000000..aac47d5
--- /dev/null
+++ b/test/CodeGen/asm_arm.c
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -triple armv6-unknown-unknown -emit-llvm -o - %s | FileCheck %s
+
+void test0(void) {
+	asm volatile("mov r0, r0" :: );
+}
+void test1(void) {
+	asm volatile("mov r0, r0" :::
+				 "cc", "memory" );
+}
+void test2(void) {
+	asm volatile("mov r0, r0" :::
+				 "r0", "r1", "r2", "r3");
+	asm volatile("mov r0, r0" :::
+				 "r4", "r5", "r6", "r8");
+}
+void test3(void) {
+	asm volatile("mov r0, r0" :::
+				 "a1", "a2", "a3", "a4");
+	asm volatile("mov r0, r0" :::
+				 "v1", "v2", "v3", "v5");
+}
+
+
+// {} should not be treated as asm variants.
+void test4(float *a, float *b) {
+  // CHECK: @test4
+  // CHECK: call void asm sideeffect "vld1.32 {d8[],d9[]}, 
+  __asm__ volatile (
+                    "vld1.32 {d8[],d9[]}, [%1,:32] \n\t"
+                    "vst1.32 {q4},        [%0,:128] \n\t"
+                    :: "r"(a), "r"(b));
+}
diff --git a/test/CodeGen/atomic.c b/test/CodeGen/atomic.c
new file mode 100644
index 0000000..aa5aa15
--- /dev/null
+++ b/test/CodeGen/atomic.c
@@ -0,0 +1,52 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple=i686-apple-darwin9 > %t1
+// RUN: grep @llvm.memory.barrier %t1 | count 38
+// RUN: grep @llvm.atomic.load.add.i32 %t1 | count 3
+// RUN: grep @llvm.atomic.load.sub.i8 %t1 | count 2
+// RUN: grep @llvm.atomic.load.min.i32 %t1
+// RUN: grep @llvm.atomic.load.max.i32 %t1
+// RUN: grep @llvm.atomic.load.umin.i32 %t1
+// RUN: grep @llvm.atomic.load.umax.i32 %t1
+// RUN: grep @llvm.atomic.swap.i32 %t1
+// RUN: grep @llvm.atomic.cmp.swap.i32 %t1 | count 4
+// RUN: grep @llvm.atomic.load.and.i32 %t1
+// RUN: grep @llvm.atomic.load.or.i8 %t1
+// RUN: grep @llvm.atomic.load.xor.i8 %t1
+
+
+int atomic(void)
+{
+  // non-sensical test for sync functions
+  int old;
+  int val = 1;
+  char valc = 1;
+  unsigned int uval = 1;
+  int cmp = 0;
+
+  old = __sync_fetch_and_add(&val, 1);
+  old = __sync_fetch_and_sub(&valc, 2);
+  old = __sync_fetch_and_min(&val, 3);
+  old = __sync_fetch_and_max(&val, 4);
+  old = __sync_fetch_and_umin(&uval, 5u);
+  old = __sync_fetch_and_umax(&uval, 6u);
+  old = __sync_lock_test_and_set(&val, 7);
+  old = __sync_val_compare_and_swap(&val, 4, 1976);
+  old = __sync_bool_compare_and_swap(&val, 4, 1976);
+  old = __sync_fetch_and_and(&val, 0x9);
+  old = __sync_fetch_and_or(&val, 0xa);
+  old = __sync_fetch_and_xor(&val, 0xb);
+
+  old = __sync_add_and_fetch(&val, 1);
+  old = __sync_sub_and_fetch(&val, 2);
+  old = __sync_and_and_fetch(&valc, 3);
+  old = __sync_or_and_fetch(&valc, 4);
+  old = __sync_xor_and_fetch(&valc, 5);
+
+  
+  __sync_val_compare_and_swap((void **)0, (void *)0, (void *)0);
+
+  
+  __sync_lock_release(&val);
+  __sync_synchronize ();
+
+  return old;
+}
diff --git a/test/CodeGen/attr-cleanup.c b/test/CodeGen/attr-cleanup.c
new file mode 100644
index 0000000..7c2053d
--- /dev/null
+++ b/test/CodeGen/attr-cleanup.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -emit-llvm %s -o %t
+
+// <rdar://problem/6827047>
+void f(void* arg);
+void g() {
+  __attribute__((cleanup(f))) void *g;
+}
+
diff --git a/test/CodeGen/attr-nodebug.c b/test/CodeGen/attr-nodebug.c
new file mode 100644
index 0000000..66caa2b
--- /dev/null
+++ b/test/CodeGen/attr-nodebug.c
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -g -emit-llvm -o %t %s
+// RUN: not grep 'call void @llvm.dbg.func.start' %t
+
+void t1() __attribute__((nodebug));
+
+void t1()
+{
+  int a = 10;
+  
+  a++;
+}
+
diff --git a/test/CodeGen/attr-noinline.c b/test/CodeGen/attr-noinline.c
new file mode 100644
index 0000000..dbca71f
--- /dev/null
+++ b/test/CodeGen/attr-noinline.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -g -emit-llvm -o %t %s
+// RUN: grep 'noinline' %t
+
+void t1() __attribute__((noinline));
+
+void t1()
+{
+}
+
diff --git a/test/CodeGen/attr-used.c b/test/CodeGen/attr-used.c
new file mode 100644
index 0000000..bc92b94
--- /dev/null
+++ b/test/CodeGen/attr-used.c
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -emit-llvm -o %t %s
+// RUN: grep '@llvm.used = .*@g0' %t
+// RUN: grep '@llvm.used = .*@f0' %t
+// RUN: grep '@llvm.used = .*@f1.l0' %t
+
+
+int g0 __attribute__((used));
+
+static void __attribute__((used)) f0(void) {
+}
+
+void f1() { 
+  static int l0 __attribute__((used)) = 5225; 
+}
diff --git a/test/CodeGen/attr-weakref.c b/test/CodeGen/attr-weakref.c
new file mode 100644
index 0000000..c1cc03b
--- /dev/null
+++ b/test/CodeGen/attr-weakref.c
@@ -0,0 +1,62 @@
+// RUN: %clang_cc1 -emit-llvm -triple i386-linux-gnu -o %t %s
+// RUN: FileCheck --input-file=%t %s
+
+// CHECK: declare extern_weak void @test1_f()
+void test1_f(void);
+static void test1_g(void) __attribute__((weakref("test1_f")));
+void test1_h(void) {
+  test1_g();
+}
+
+// CHECK: define void @test2_f()
+void test2_f(void) {}
+static void test2_g(void) __attribute__((weakref("test2_f")));
+void test2_h(void) {
+  test2_g();
+}
+
+// CHECK: declare void @test3_f()
+void test3_f(void);
+static void test3_g(void) __attribute__((weakref("test3_f")));
+void test3_foo(void) {
+  test3_f();
+}
+void test3_h(void) {
+  test3_g();
+}
+
+// CHECK: define void @test4_f()
+void test4_f(void);
+static void test4_g(void) __attribute__((weakref("test4_f")));
+void test4_h(void) {
+  test4_g();
+}
+void test4_f(void) {}
+
+// CHECK: declare void @test5_f()
+void test5_f(void);
+static void test5_g(void) __attribute__((weakref("test5_f")));
+void test5_h(void) {
+  test5_g();
+}
+void test5_foo(void) {
+  test5_f();
+}
+
+// CHECK: declare extern_weak void @test6_f()
+void test6_f(void) __attribute__((weak));
+static void test6_g(void) __attribute__((weakref("test6_f")));
+void test6_h(void) {
+  test6_g();
+}
+void test6_foo(void) {
+  test6_f();
+}
+
+// CHECK: declare extern_weak void @test7_f()
+void test7_f(void);
+static void test7_g(void) __attribute__((weakref("test7_f")));
+static void *const test7_zed = (void *) &test7_g;
+void* test7_h(void) {
+  return test7_zed;
+}
diff --git a/test/CodeGen/attr-weakref2.c b/test/CodeGen/attr-weakref2.c
new file mode 100644
index 0000000..9976063
--- /dev/null
+++ b/test/CodeGen/attr-weakref2.c
@@ -0,0 +1,54 @@
+// RUN: %clang_cc1 -emit-llvm -triple i386-linux-gnu -o %t %s
+// RUN: FileCheck --input-file=%t %s
+
+// CHECK: @test1_f = extern_weak global i32
+extern int test1_f;
+static int test1_g __attribute__((weakref("test1_f")));
+int test1_h(void) {
+  return test1_g;
+}
+
+// CHECK: @test2_f = common global i32 0, align 4
+int test2_f;
+static int test2_g __attribute__((weakref("test2_f")));
+int test2_h(void) {
+  return test2_g;
+}
+
+// CHECK: @test3_f = external global i32
+extern int test3_f;
+static int test3_g __attribute__((weakref("test3_f")));
+int test3_foo(void) {
+  return test3_f;
+}
+int test3_h(void) {
+  return test3_g;
+}
+
+// CHECK: @test4_f = common global i32 0, align 4
+extern int test4_f;
+static int test4_g __attribute__((weakref("test4_f")));
+int test4_h(void) {
+  return test4_g;
+}
+int test4_f;
+
+// CHECK: @test5_f = external global i32
+extern int test5_f;
+static int test5_g __attribute__((weakref("test5_f")));
+int test5_h(void) {
+  return test5_g;
+}
+int test5_foo(void) {
+  return test5_f;
+}
+
+// CHECK: @test6_f = extern_weak global i32
+extern int test6_f __attribute__((weak));
+static int test6_g __attribute__((weakref("test6_f")));
+int test6_h(void) {
+  return test6_g;
+}
+int test6_foo(void) {
+  return test6_f;
+}
diff --git a/test/CodeGen/attributes.c b/test/CodeGen/attributes.c
new file mode 100644
index 0000000..770ce76
--- /dev/null
+++ b/test/CodeGen/attributes.c
@@ -0,0 +1,83 @@
+// RUN: %clang_cc1 -emit-llvm -triple i386-linux-gnu -o %t %s
+// RUN: FileCheck --input-file=%t %s
+
+// CHECK: @t5 = weak global i32 2
+int t5 __attribute__((weak)) = 2;
+
+// CHECK: @t13 = global %0 zeroinitializer, section "SECT"
+struct s0 { int x; };
+struct s0 t13 __attribute__((section("SECT"))) = { 0 };
+
+// CHECK: @t14.x = internal global i32 0, section "SECT"
+void t14(void) {
+  static int x __attribute__((section("SECT"))) = 0;
+}
+
+// CHECK: @t18 = global i32 1, align 4
+extern int t18 __attribute__((weak_import));
+int t18 = 1;
+
+// CHECK: @t16 = extern_weak global i32
+extern int t16 __attribute__((weak_import));
+
+// CHECK: @t6 = common protected global i32 0
+int t6 __attribute__((visibility("protected")));
+
+// CHECK: @t12 = global i32 0, section "SECT"
+int t12 __attribute__((section("SECT")));
+
+// CHECK: @t9 = alias weak bitcast (void ()* @__t8 to void (...)*)
+void __t8() {}
+void t9() __attribute__((weak, alias("__t8")));
+
+// CHECK: declare extern_weak i32 @t15()
+int __attribute__((weak_import)) t15(void);
+int t17() {
+  return t15() + t16;
+}
+
+// CHECK: define void @t1() noreturn nounwind {
+void t1() __attribute__((noreturn));
+void t1() { while (1) {} }
+
+// CHECK: define void @t2() nounwind {
+void t2() __attribute__((nothrow));
+void t2() {}
+
+// CHECK: define weak void @t3() nounwind {
+void t3() __attribute__((weak));
+void t3() {}
+
+// CHECK: define hidden void @t4() nounwind {
+void t4() __attribute__((visibility("hidden")));
+void t4() {}
+
+// CHECK: define void @t7() noreturn nounwind {
+void t7() __attribute__((noreturn, nothrow));
+void t7() { while (1) {} }
+
+// CHECK: define void @t10() nounwind section "SECT" {
+void t10(void) __attribute__((section("SECT")));
+void t10(void) {}
+// CHECK: define void @t11() nounwind section "SECT" {
+void __attribute__((section("SECT"))) t11(void) {}
+
+// CHECK: define i32 @t19() nounwind {
+extern int t19(void) __attribute__((weak_import));
+int t19(void) {
+  return 10;
+}
+
+// CHECK:define void @t20() nounwind {
+// CHECK: call void @abort()
+// CHECK-NEXT: unreachable
+void t20(void) {
+  __builtin_abort();
+}
+
+void (__attribute__((fastcall)) *fptr)(int);
+void t21(void) {
+  fptr(10);
+}
+// CHECK: [[FPTRVAR:%[a-z0-9]+]] = load void (i32)** @fptr
+// CHECK-NEXT: call x86_fastcallcc void [[FPTRVAR]](i32 10)
diff --git a/test/CodeGen/bitfield-2.c b/test/CodeGen/bitfield-2.c
new file mode 100644
index 0000000..e91859f
--- /dev/null
+++ b/test/CodeGen/bitfield-2.c
@@ -0,0 +1,368 @@
+// RUN: %clang_cc1 -emit-llvm -triple x86_64 -O3 -o %t.opt.ll %s \
+// RUN:   -fdump-record-layouts 2> %t.dump.txt
+// RUN: FileCheck -check-prefix=CHECK-RECORD < %t.dump.txt %s
+// RUN: FileCheck -check-prefix=CHECK-OPT < %t.opt.ll %s
+
+/****/
+
+// Check that we don't read off the end a packed 24-bit structure.
+// PR6176
+
+// CHECK-RECORD: *** Dumping IRgen Record Layout
+// CHECK-RECORD: Record: struct s0
+// CHECK-RECORD: Layout: <CGRecordLayout
+// CHECK-RECORD:   LLVMType:<{ [3 x i8] }>
+// CHECK-RECORD:   ContainsPointerToDataMember:0
+// CHECK-RECORD:   BitFields:[
+// CHECK-RECORD:     <CGBitFieldInfo Size:24 IsSigned:1
+// CHECK-RECORD:                     NumComponents:2 Components: [
+// CHECK-RECORD:         <AccessInfo FieldIndex:0 FieldByteOffset:0 FieldBitStart:0 AccessWidth:16
+// CHECK-RECORD:                     AccessAlignment:1 TargetBitOffset:0 TargetBitWidth:16>
+// CHECK-RECORD:         <AccessInfo FieldIndex:0 FieldByteOffset:2 FieldBitStart:0 AccessWidth:8
+// CHECK-RECORD:                     AccessAlignment:1 TargetBitOffset:16 TargetBitWidth:8>
+struct __attribute((packed)) s0 {
+  int f0 : 24;
+};
+
+struct s0 g0 = { 0xdeadbeef };
+
+int f0_load(struct s0 *a0) {
+  int size_check[sizeof(struct s0) == 3 ? 1 : -1];
+  return a0->f0;
+}
+int f0_store(struct s0 *a0) {
+  return (a0->f0 = 1);
+}
+int f0_reload(struct s0 *a0) {
+  return (a0->f0 += 1);
+}
+
+// CHECK-OPT: define i64 @test_0()
+// CHECK-OPT:  ret i64 1
+// CHECK-OPT: }
+unsigned long long test_0() {
+  struct s0 g0 = { 0xdeadbeef };
+  unsigned long long res = 0;
+  res ^= g0.f0;
+  res ^= f0_load(&g0) ^ f0_store(&g0) ^ f0_reload(&g0);
+  res ^= g0.f0;
+  return res;
+}
+
+/****/
+
+// PR5591
+
+// CHECK-RECORD: *** Dumping IRgen Record Layout
+// CHECK-RECORD: Record: struct s1
+// CHECK-RECORD: Layout: <CGRecordLayout
+// CHECK-RECORD:   LLVMType:<{ [2 x i8], i8 }>
+// CHECK-RECORD:   ContainsPointerToDataMember:0
+// CHECK-RECORD:   BitFields:[
+// CHECK-RECORD:     <CGBitFieldInfo Size:10 IsSigned:1
+// CHECK-RECORD:                     NumComponents:1 Components: [
+// CHECK-RECORD:         <AccessInfo FieldIndex:0 FieldByteOffset:0 FieldBitStart:0 AccessWidth:16
+// CHECK-RECORD:                     AccessAlignment:1 TargetBitOffset:0 TargetBitWidth:10>
+// CHECK-RECORD:     ]>
+// CHECK-RECORD:     <CGBitFieldInfo Size:10 IsSigned:1
+// CHECK-RECORD:                     NumComponents:2 Components: [
+// CHECK-RECORD:         <AccessInfo FieldIndex:0 FieldByteOffset:0 FieldBitStart:10 AccessWidth:16
+// CHECK-RECORD:                     AccessAlignment:1 TargetBitOffset:0 TargetBitWidth:6>
+// CHECK-RECORD:         <AccessInfo FieldIndex:0 FieldByteOffset:2 FieldBitStart:0 AccessWidth:8
+// CHECK-RECORD:                     AccessAlignment:1 TargetBitOffset:6 TargetBitWidth:4>
+
+#pragma pack(push)
+#pragma pack(1)
+struct __attribute((packed)) s1 {
+  signed f0 : 10;
+  signed f1 : 10;
+};
+#pragma pack(pop)
+
+struct s1 g1 = { 0xdeadbeef, 0xdeadbeef };
+
+int f1_load(struct s1 *a0) {
+  int size_check[sizeof(struct s1) == 3 ? 1 : -1];
+  return a0->f1;
+}
+int f1_store(struct s1 *a0) {
+  return (a0->f1 = 1234);
+}
+int f1_reload(struct s1 *a0) {
+  return (a0->f1 += 1234);
+}
+
+// CHECK-OPT: define i64 @test_1()
+// CHECK-OPT:  ret i64 210
+// CHECK-OPT: }
+unsigned long long test_1() {
+  struct s1 g1 = { 0xdeadbeef, 0xdeadbeef };
+  unsigned long long res = 0;
+  res ^= g1.f0 ^ g1.f1;
+  res ^= f1_load(&g1) ^ f1_store(&g1) ^ f1_reload(&g1);
+  res ^= g1.f0 ^ g1.f1;
+  return res;
+}
+
+/****/
+
+// Check that we don't access beyond the bounds of a union.
+//
+// PR5567
+
+// CHECK-RECORD: *** Dumping IRgen Record Layout
+// CHECK-RECORD: Record: union u2
+// CHECK-RECORD: Layout: <CGRecordLayout
+// CHECK-RECORD:   LLVMType:<{ i8 }>
+// CHECK-RECORD:   ContainsPointerToDataMember:0
+// CHECK-RECORD:   BitFields:[
+// CHECK-RECORD:     <CGBitFieldInfo Size:3 IsSigned:0
+// CHECK-RECORD:                     NumComponents:1 Components: [
+// CHECK-RECORD:         <AccessInfo FieldIndex:0 FieldByteOffset:0 FieldBitStart:0 AccessWidth:8
+// CHECK-RECORD:                     AccessAlignment:1 TargetBitOffset:0 TargetBitWidth:3>
+
+union __attribute__((packed)) u2 {
+  unsigned long long f0 : 3;
+};
+
+union u2 g2 = { 0xdeadbeef };
+
+int f2_load(union u2 *a0) {
+  return a0->f0;
+}
+int f2_store(union u2 *a0) {
+  return (a0->f0 = 1234);
+}
+int f2_reload(union u2 *a0) {
+  return (a0->f0 += 1234);
+}
+
+// CHECK-OPT: define i64 @test_2()
+// CHECK-OPT:  ret i64 2
+// CHECK-OPT: }
+unsigned long long test_2() {
+  union u2 g2 = { 0xdeadbeef };
+  unsigned long long res = 0;
+  res ^= g2.f0;
+  res ^= f2_load(&g2) ^ f2_store(&g2) ^ f2_reload(&g2);
+  res ^= g2.f0;
+  return res;
+}
+
+/***/
+
+// PR5039
+
+struct s3 {
+  long long f0 : 32;
+  long long f1 : 32;
+};
+
+struct s3 g3 = { 0xdeadbeef, 0xdeadbeef };
+
+int f3_load(struct s3 *a0) {
+  a0->f0 = 1;
+  return a0->f0;
+}
+int f3_store(struct s3 *a0) {
+  a0->f0 = 1;
+  return (a0->f0 = 1234);
+}
+int f3_reload(struct s3 *a0) {
+  a0->f0 = 1;
+  return (a0->f0 += 1234);
+}
+
+// CHECK-OPT: define i64 @test_3()
+// CHECK-OPT:  ret i64 -559039940
+// CHECK-OPT: }
+unsigned long long test_3() {
+  struct s3 g3 = { 0xdeadbeef, 0xdeadbeef };
+  unsigned long long res = 0;
+  res ^= g3.f0 ^ g3.f1;
+  res ^= f3_load(&g3) ^ f3_store(&g3) ^ f3_reload(&g3);
+  res ^= g3.f0 ^ g3.f1;
+  return res;
+}
+
+/***/
+
+// This is a case where the bitfield access will straddle an alignment boundary
+// of its underlying type.
+
+struct s4 {
+  unsigned f0 : 16;
+  unsigned f1 : 28 __attribute__ ((packed));
+};
+
+struct s4 g4 = { 0xdeadbeef, 0xdeadbeef };
+
+int f4_load(struct s4 *a0) {
+  return a0->f0 ^ a0->f1;
+}
+int f4_store(struct s4 *a0) {
+  return (a0->f0 = 1234) ^ (a0->f1 = 5678);
+}
+int f4_reload(struct s4 *a0) {
+  return (a0->f0 += 1234) ^ (a0->f1 += 5678);
+}
+
+// CHECK-OPT: define i64 @test_4()
+// CHECK-OPT:  ret i64 4860
+// CHECK-OPT: }
+unsigned long long test_4() {
+  struct s4 g4 = { 0xdeadbeef, 0xdeadbeef };
+  unsigned long long res = 0;
+  res ^= g4.f0 ^ g4.f1;
+  res ^= f4_load(&g4) ^ f4_store(&g4) ^ f4_reload(&g4);
+  res ^= g4.f0 ^ g4.f1;
+  return res;
+}
+
+/***/
+
+struct s5 {
+  unsigned f0 : 2;
+  _Bool f1 : 1;
+  _Bool f2 : 1;
+};
+
+struct s5 g5 = { 0xdeadbeef, 0xdeadbeef };
+
+int f5_load(struct s5 *a0) {
+  return a0->f0 ^ a0->f1;
+}
+int f5_store(struct s5 *a0) {
+  return (a0->f0 = 0xF) ^ (a0->f1 = 0xF) ^ (a0->f2 = 0xF);
+}
+int f5_reload(struct s5 *a0) {
+  return (a0->f0 += 0xF) ^ (a0->f1 += 0xF) ^ (a0->f2 += 0xF);
+}
+
+// CHECK-OPT: define i64 @test_5()
+// CHECK-OPT:  ret i64 2
+// CHECK-OPT: }
+unsigned long long test_5() {
+  struct s5 g5 = { 0xdeadbeef, 0xdeadbeef, 0xdeadbeef };
+  unsigned long long res = 0;
+  res ^= g5.f0 ^ g5.f1 ^ g5.f2;
+  res ^= f5_load(&g5) ^ f5_store(&g5) ^ f5_reload(&g5);
+  res ^= g5.f0 ^ g5.f1 ^ g5.f2;
+  return res;
+}
+
+/***/
+
+struct s6 {
+  _Bool f0 : 2;
+};
+
+struct s6 g6 = { 0xF };
+
+int f6_load(struct s6 *a0) {
+  return a0->f0;
+}
+int f6_store(struct s6 *a0) {
+  return a0->f0 = 0x0;
+}
+int f6_reload(struct s6 *a0) {
+  return (a0->f0 += 0xF);
+}
+
+// CHECK-OPT: define zeroext i1 @test_6()
+// CHECK-OPT:  ret i1 true
+// CHECK-OPT: }
+_Bool test_6() {
+  struct s6 g6 = { 0xF };
+  unsigned long long res = 0;
+  res ^= g6.f0;
+  res ^= f6_load(&g6);
+  res ^= g6.f0;
+  return res;
+}
+
+/***/
+
+// Check that we compute the best alignment possible for each access.
+//
+// CHECK-RECORD: *** Dumping IRgen Record Layout
+// CHECK-RECORD: Record: struct s7
+// CHECK-RECORD: Layout: <CGRecordLayout
+// CHECK-RECORD:   LLVMType:{ i32, i32, i32, i8, [3 x i8], [4 x i8], [12 x i8] }
+// CHECK-RECORD:   ContainsPointerToDataMember:0
+// CHECK-RECORD:   BitFields:[
+// CHECK-RECORD:     <CGBitFieldInfo Size:5 IsSigned:1
+// CHECK-RECORD:                     NumComponents:1 Components: [
+// CHECK-RECORD:         <AccessInfo FieldIndex:0 FieldByteOffset:12 FieldBitStart:0 AccessWidth:32
+// CHECK-RECORD:                     AccessAlignment:4 TargetBitOffset:0 TargetBitWidth:5>
+// CHECK-RECORD:     ]>
+// CHECK-RECORD:     <CGBitFieldInfo Size:29 IsSigned:1
+// CHECK-RECORD:                     NumComponents:1 Components: [
+// CHECK-RECORD:         <AccessInfo FieldIndex:0 FieldByteOffset:16 FieldBitStart:0 AccessWidth:32
+// CHECK-RECORD:                     AccessAlignment:16 TargetBitOffset:0 TargetBitWidth:29>
+
+struct __attribute__((aligned(16))) s7 {
+  int a, b, c;
+  int f0 : 5;
+  int f1 : 29;
+};
+
+int f7_load(struct s7 *a0) {
+  return a0->f0;
+}
+
+/***/
+
+// This is a case where we narrow the access width immediately.
+
+struct __attribute__((packed)) s8 {
+  char f0 : 4;
+  char f1;
+  int  f2 : 4;
+  char f3 : 4;
+};
+
+struct s8 g8 = { 0xF };
+
+int f8_load(struct s8 *a0) {
+  return a0->f0 ^ a0 ->f2 ^ a0->f3;
+}
+int f8_store(struct s8 *a0) {
+  return (a0->f0 = 0xFD) ^ (a0->f2 = 0xFD) ^ (a0->f3 = 0xFD);
+}
+int f8_reload(struct s8 *a0) {
+  return (a0->f0 += 0xFD) ^ (a0->f2 += 0xFD) ^ (a0->f3 += 0xFD);
+}
+
+// CHECK-OPT: define i32 @test_8()
+// CHECK-OPT:  ret i32 -3
+// CHECK-OPT: }
+unsigned test_8() {
+  struct s8 g8 = { 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef };
+  unsigned long long res = 0;
+  res ^= g8.f0 ^ g8.f2 ^ g8.f3;
+  res ^= f8_load(&g8) ^ f8_store(&g8) ^ f8_reload(&g8);
+  res ^= g8.f0 ^ g8.f2 ^ g8.f3;
+  return res;
+}
+
+/***/
+
+// This is another case where we narrow the access width immediately.
+//
+// <rdar://problem/7893760>
+
+struct __attribute__((packed)) s9 {
+  unsigned f0 : 7;
+  unsigned f1 : 7;
+  unsigned f2 : 7;
+  unsigned f3 : 7;
+  unsigned f4 : 7;
+  unsigned f5 : 7;
+  unsigned f6 : 7;
+  unsigned f7 : 7;
+};
+
+int f9_load(struct s9 *a0) {
+  return a0->f7;
+}
diff --git a/test/CodeGen/bitfield-assign.c b/test/CodeGen/bitfield-assign.c
new file mode 100644
index 0000000..b8ab613
--- /dev/null
+++ b/test/CodeGen/bitfield-assign.c
@@ -0,0 +1,44 @@
+/* Check that the result of a bitfield assignment is properly
+   truncated and does not generate a redundant load. */
+
+/* Check that we get one load for each simple assign and two for the
+   compound assign (load the old value before the add then load again
+   to store back). Also check that our g0 pattern is good. */
+// RUN: %clang_cc1 -triple i386-unknown-unknown -O0 -emit-llvm -o %t %s
+// RUN: grep 'load ' %t | count 5
+// RUN: grep "@g0" %t | count 4
+
+// Check that we got the right value.
+// RUN: %clang_cc1 -triple i386-unknown-unknown -O3 -emit-llvm -o %t %s
+// RUN: grep 'load ' %t | count 0
+// RUN: grep "@g0" %t | count 0
+
+struct s0 {
+  int f0 : 2;
+  _Bool f1 : 1;
+  unsigned f2 : 2;
+};
+
+int g0();
+
+void f0(void) {
+  struct s0 s;  
+  if ((s.f0 = 3) != -1) g0();
+}
+
+void f1(void) {
+  struct s0 s;  
+  if ((s.f1 = 3) != 1) g0();
+}
+
+void f2(void) {
+  struct s0 s;  
+  if ((s.f2 = 3) != 3) g0();
+}
+
+void f3(void) {
+  struct s0 s;
+  // Just check this one for load counts.
+  s.f0 += 3;
+}
+
diff --git a/test/CodeGen/bitfield-init.c b/test/CodeGen/bitfield-init.c
new file mode 100644
index 0000000..bee4e7d
--- /dev/null
+++ b/test/CodeGen/bitfield-init.c
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 %s -emit-llvm -o %t
+typedef struct { unsigned int i: 1; } c;
+const c d = { 1 };
+
+// PR2310
+struct Token {
+  unsigned n : 31;
+};
+void sqlite3CodeSubselect(){
+  struct Token one = { 1 };
+}
+
+typedef union T0 { char field0 : 2; } T0;
+T0 T0_values = { 0 };
diff --git a/test/CodeGen/bitfield-promote.c b/test/CodeGen/bitfield-promote.c
new file mode 100644
index 0000000..4c3292c
--- /dev/null
+++ b/test/CodeGen/bitfield-promote.c
@@ -0,0 +1,18 @@
+// RUN: %clang -O3 -emit-llvm -S -o %t %s
+// RUN: grep 'ret i64 4294967292' %t | count 2
+// RUN: grep 'ret i64 -4' %t | count 1
+
+long long f0(void) {
+ struct { unsigned f0 : 32; } x = { 18 };
+ return (long long) (x.f0 - (int) 22);
+}
+
+long long f1(void) {
+ struct { unsigned f0 : 31; } x = { 18 };
+ return (long long) (x.f0 - (int) 22);
+}
+
+long long f2(void) {
+ struct { unsigned f0     ; } x = { 18 };
+ return (long long) (x.f0 - (int) 22);
+}
diff --git a/test/CodeGen/bitfield.c b/test/CodeGen/bitfield.c
new file mode 100644
index 0000000..dea5e43
--- /dev/null
+++ b/test/CodeGen/bitfield.c
@@ -0,0 +1,74 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown %s -emit-llvm -o %t -O3
+// RUN: grep "ret i32" %t | count 4
+// RUN: grep "ret i32 1" %t | count 4
+
+static int f0(int n) {
+  struct s0 {
+    int a : 30;
+    int b : 2;
+    long long c : 31;
+  } x = { 0xdeadbeef, 0xdeadbeef, 0xdeadbeef };
+  
+  x.a += n;
+  x.b += n;
+  x.c += n;
+
+  return x.a + x.b + x.c;
+}
+
+int g0(void) {
+  return f0(-1) + 44335655;
+}
+
+static int f1(void) {
+  struct s1 { 
+    int a:13; 
+    char b; 
+    unsigned short c:7;
+  } x;
+  
+  x.a = -40;
+  x.b = 10;
+  x.c = 15;
+
+  return x.a + x.b + x.c;
+}
+
+int g1(void) {
+  return f1() + 16;
+}
+
+static int f2(void) {
+  struct s2 {
+    short a[3];
+    int b : 15;
+  } x;
+  
+  x.a[0] = x.a[1] = x.a[2] = -40;
+  x.b = 10;
+
+  return x.b;
+}
+
+int g2(void) {
+  return f2() - 9;
+}
+
+static int f3(int n) {
+  struct s3 {
+    unsigned a:16;
+    unsigned b:28 __attribute__ ((packed));
+  } x = { 0xdeadbeef, 0xdeadbeef };
+  struct s4 {
+    signed a:16;
+    signed b:28 __attribute__ ((packed));
+  } y;
+  y.a = -0x56789abcL;
+  y.b = -0x56789abcL;
+  return ((y.a += x.a += n) + 
+          (y.b += x.b += n));
+}
+
+int g3(void) {
+  return f3(20) + 130725747;
+}
diff --git a/test/CodeGen/blocks-1.c b/test/CodeGen/blocks-1.c
new file mode 100644
index 0000000..71b4de8
--- /dev/null
+++ b/test/CodeGen/blocks-1.c
@@ -0,0 +1,78 @@
+// RUN: %clang_cc1 %s -emit-llvm -o %t -fblocks
+// RUN: grep "_Block_object_dispose" %t | count 17
+// RUN: grep "__copy_helper_block_" %t | count 16
+// RUN: grep "__destroy_helper_block_" %t | count 16
+// RUN: grep "__Block_byref_id_object_copy_" %t | count 2
+// RUN: grep "__Block_byref_id_object_dispose_" %t | count 2
+// RUN: grep "i32 135)" %t | count 2
+// RUN: grep "_Block_object_assign" %t | count 10
+
+int printf(const char *, ...);
+
+void test1() {
+  __block int a;
+  int b=2;
+  a=1;
+  printf("a is %d, b is %d\n", a, b);
+  ^{ a = 10; printf("a is %d, b is %d\n", a, b); }();
+  printf("a is %d, b is %d\n", a, b);
+  a = 1;
+  printf("a is %d, b is %d\n", a, b);
+}
+
+void test2() {
+  __block int a;
+  a=1;
+  printf("a is %d\n", a);
+  ^{
+    ^{
+      a = 10;
+    }();
+  }();
+  printf("a is %d\n", a);
+  a = 1;
+  printf("a is %d\n", a);
+}
+
+void test3() {
+  __block int k;
+  __block int (^j)(int);
+  ^{j=0; k=0;}();
+}
+
+int test4() {
+  extern int g;
+  static int i = 1;
+  ^(int j){ i = j; g = 0; }(0);
+  return i + g;
+}
+
+int g;
+
+void test5() {
+  __block struct { int i; } i;
+  ^{ (void)i; }();
+}
+
+void test6() {
+  __block int i;
+  ^{ i=1; }();
+  ^{}();
+}
+
+void test7() {
+  ^{
+    __block int i;
+    ^{ i = 1; }();
+  }();
+}
+
+int main() {
+  int rv = 0;
+  test1();
+  test2();
+  test3();
+  rv += test4();
+  test5();
+  return rv;
+}
diff --git a/test/CodeGen/blocks-2.c b/test/CodeGen/blocks-2.c
new file mode 100644
index 0000000..4e574da
--- /dev/null
+++ b/test/CodeGen/blocks-2.c
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -g %s -emit-llvm -o %t -fblocks
+// RUN: grep "func.start" %t | count 4
+// RUN: %clang_cc1 -g %s -triple i386-unknown-unknown -emit-llvm -o %t -fblocks -fblock-introspection
+// RUN: grep "v8@?0i4" %t | count 1
+// RUN: %clang_cc1 -g %s -triple i386-unknown-unknown -emit-llvm -o %t -fblocks
+// RUN: grep "v8@?0i4" %t | count 0
+// 1 declaration, 1 bar, 1 test_block_dbg and 1 for the block.
+// XFAIL: *
+
+static __inline__ __attribute__((always_inline)) int bar(int va, int vb) { return (va == vb); }
+
+int test_block_dbg() {
+  extern int g;
+  static int i = 1;
+  ^(int j){ i = bar(3,4); }(0);
+  return i + g;
+}
+
diff --git a/test/CodeGen/blocks-aligned-byref-variable.c b/test/CodeGen/blocks-aligned-byref-variable.c
new file mode 100644
index 0000000..79ac41d
--- /dev/null
+++ b/test/CodeGen/blocks-aligned-byref-variable.c
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -emit-llvm -o - -triple x86_64-apple-darwin10
+// RUN: %clang_cc1 -emit-llvm -o - -triple i386-apple-darwin10 
+typedef int __attribute__((aligned(32)))  ai;
+
+void f() {
+  __block ai a = 10;
+
+  ^{
+    a = 20;
+  }();
+}
+
+void g() {
+  __block double a = 10;
+
+  ^{
+    a = 20;
+  }();
+}
diff --git a/test/CodeGen/blocks-seq.c b/test/CodeGen/blocks-seq.c
new file mode 100644
index 0000000..3557b48
--- /dev/null
+++ b/test/CodeGen/blocks-seq.c
@@ -0,0 +1,18 @@
+// FIXME: We forcibly strip the names so that the test doesn't vary between
+// builds with and without asserts. We need a better solution for this.
+
+// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin10 -emit-llvm-bc -o - %s | opt -strip | llvm-dis > %t
+// RUN: grep '%6 = call i32 (...)\* @rhs()' %t | count 1
+// RUN: grep '%7 = getelementptr inbounds %0\* %1, i32 0, i32 1' %t | count 1
+// RUN: grep '%8 = load %0\*\* %7' %t | count 1
+// RUN: grep '%10 = call i32 (...)\* @rhs()' %t | count 1
+// RUN: grep '%11 = getelementptr inbounds %0\* %1, i32 0, i32 1' %t | count 1
+// RUN: grep '%12 = load %0\*\* %11' %t | count 1
+
+int rhs();
+
+void foo() {
+  __block int i;
+  i = rhs();
+  i += rhs();
+}
diff --git a/test/CodeGen/blocks.c b/test/CodeGen/blocks.c
new file mode 100644
index 0000000..e7625b1
--- /dev/null
+++ b/test/CodeGen/blocks.c
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown %s -emit-llvm -o %t -fblocks
+void (^f)(void) = ^{};
+
+// rdar://6768379
+int f0(int (^a0)()) {
+  return a0(1, 2, 3);
+}
+
+// Verify that attributes on blocks are set correctly.
+typedef struct s0 T;
+struct s0 {
+  int a[64];
+};
+
+// RUN: grep 'internal void @__f2_block_invoke_(.struct.s0\* sret .*, .*, .* byval .*)' %t
+struct s0 f2(struct s0 a0) {
+  return ^(struct s0 a1){ return a1; }(a0);
+}
+
+// This should not crash: rdar://6808051
+void *P = ^{
+  void *Q = __func__;
+};
+
+void (^test1)(void) = ^(void) {
+  __block int i;
+  ^ { i = 1; }();
+};
+
diff --git a/test/CodeGen/blocksignature.c b/test/CodeGen/blocksignature.c
new file mode 100644
index 0000000..6ed8750
--- /dev/null
+++ b/test/CodeGen/blocksignature.c
@@ -0,0 +1,94 @@
+// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin9 %s -emit-llvm -o - | FileCheck %s -check-prefix=X64
+// RUN: %clang_cc1 -fblocks -triple i686-apple-darwin9 %s -emit-llvm -o - | FileCheck %s -check-prefix=X32
+
+// X64: @.str = private constant [6 x i8] c"v8@?0\00" 
+// X64: @__block_literal_global = internal constant %1 { i8** @_NSConcreteGlobalBlock, i32 1342177280,
+// X64: @.str1 = private constant [12 x i8] c"i16@?0c8f12\00"
+// X64:   store i32 1073741824, i32*
+
+// X32: @.str = private constant [6 x i8] c"v4@?0\00" 
+// X32: @__block_literal_global = internal constant %1 { i8** @_NSConcreteGlobalBlock, i32 1342177280,
+// X32: @.str1 = private constant [11 x i8] c"i12@?0c4f8\00"
+// X32:   store i32 1073741824, i32*
+
+// rdar://7635294
+
+
+int globalInt;
+void (^global)(void) = ^{ ++globalInt; };
+
+    
+void foo(int param) {
+   extern int rand(void);
+   extern void rand_r(int (^b)(char x, float y));   // name a function present at runtime
+   while (param--)
+      rand_r(^(char x, float y){ return x + (int)y + param + rand(); });  // generate a local block binding param
+}
+
+#if 0
+#include <stdio.h>
+enum {
+    BLOCK_HAS_COPY_DISPOSE =  (1 << 25),
+    BLOCK_HAS_CXX_OBJ =       (1 << 26),
+    BLOCK_IS_GLOBAL =         (1 << 28),
+    BLOCK_HAS_DESCRIPTOR =    (1 << 29),
+    BLOCK_HAS_OBJC_TYPE  =    (1 << 30)
+};
+
+struct block_descriptor_big {
+    unsigned long int reserved;
+    unsigned long int size;
+    void (*copy)(void *dst, void *src); // conditional on BLOCK_HAS_COPY_DISPOSE
+    void (*dispose)(void *);            // conditional on BLOCK_HAS_COPY_DISPOSE
+    const char *signature;                  // conditional on BLOCK_HAS_OBJC
+    const char *layout;                 // conditional on BLOCK_HAS_OBJC
+};
+struct block_descriptor_small {
+    unsigned long int reserved;
+    unsigned long int size;
+    const char *signature;              // conditional on BLOCK_HAS_OBJC
+    const char *layout;                 // conditional on BLOCK_HAS_OBJC
+};
+
+struct block_layout_abi { // can't change
+  void *isa;
+  int flags;
+  int reserved; 
+  void (*invoke)(void *, ...);
+  struct block_descriptor_big *descriptor;
+};
+
+const char *getBlockSignature(void *block) {
+   struct block_layout_abi *layout = (struct block_layout_abi *)block;
+   if ((layout->flags & BLOCK_HAS_OBJC_TYPE) != BLOCK_HAS_OBJC_TYPE) return NULL;
+   if (layout->flags & BLOCK_HAS_COPY_DISPOSE) 
+      return layout->descriptor->signature;
+   else
+      return ((struct block_descriptor_small *)layout->descriptor)->signature;
+}
+  
+    
+   
+int main(int argc, char *argv[]) {
+   printf("desired global flags: %d\n", BLOCK_IS_GLOBAL  | BLOCK_HAS_OBJC_TYPE);
+   printf("desired stack flags: %d\n",  BLOCK_HAS_OBJC_TYPE);
+   
+   printf("types for global: %s\n", getBlockSignature(global));
+   printf("types for local: %s\n", getBlockSignature(^int(char x, float y) { return (int)(y + x); }));
+   return 0;
+}
+
+/*
+x86_64
+desired global flags: 1342177280
+desired stack flags: 1073741824
+types for global: v8@?0
+types for local: i16@?0c8f12
+
+i386
+desired global flags: 1342177280
+desired stack flags: 1073741824
+types for global: v4@?0
+types for local: i12@?0c4f8
+*/
+#endif
diff --git a/test/CodeGen/blockstret.c b/test/CodeGen/blockstret.c
new file mode 100644
index 0000000..09292b8
--- /dev/null
+++ b/test/CodeGen/blockstret.c
@@ -0,0 +1,106 @@
+// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin9 %s -emit-llvm -o - | FileCheck %s -check-prefix=X64
+// RUN: %clang_cc1 -fblocks -triple i686-apple-darwin9 %s -emit-llvm -o - | FileCheck %s -check-prefix=X32
+
+// X64:   internal constant %2 { i8** @_NSConcreteGlobalBlock, i32 1879048192
+// X64:     store i32 1610612736, i32* %want
+
+// X32:   @_NSConcreteGlobalBlock, i32 1879048192, i32 0,
+// X32:   store i32 1610612736, i32* %want
+
+// rdar://7677537
+int printf(const char *, ...);
+void *malloc(__SIZE_TYPE__ size);
+
+typedef struct bigbig {
+   int array[512];
+   char more[32];
+} BigStruct_t;
+
+BigStruct_t (^global)(void) = ^{ return *(BigStruct_t *)malloc(sizeof(struct bigbig)); };
+
+const char * getBlockSignature(void *);
+ 
+BigStruct_t foo(int param) {
+   BigStruct_t x;
+   BigStruct_t (^f)(int) = ^(int param) {
+     BigStruct_t *result = malloc(sizeof(BigStruct_t));
+     result->array[23] = param;
+     return *result;
+   };
+   getBlockSignature(f);
+   return x;
+}
+
+enum {
+    BLOCK_HAS_COPY_DISPOSE =  (1 << 25),
+    BLOCK_HAS_CXX_OBJ =       (1 << 26),
+    BLOCK_IS_GLOBAL =         (1 << 28),
+    BLOCK_USE_STRET =    (1 << 29),
+    BLOCK_HAS_OBJC_TYPE  =    (1 << 30)
+};
+
+struct block_descriptor_big {
+    unsigned long int reserved;
+    unsigned long int size;
+    void (*copy)(void *dst, void *src); // conditional on BLOCK_HAS_COPY_DISPOSE
+    void (*dispose)(void *);            // conditional on BLOCK_HAS_COPY_DISPOSE
+    const char *signature;                  // conditional on BLOCK_HAS_OBJC
+    const char *layout;                 // conditional on BLOCK_HAS_OBJC
+};
+struct block_descriptor_small {
+    unsigned long int reserved;
+    unsigned long int size;
+    const char *signature;              // conditional on BLOCK_HAS_OBJC
+    const char *layout;                 // conditional on BLOCK_HAS_OBJC
+};
+
+struct block_layout_abi { // can't change
+  void *isa;
+  int flags;
+  int reserved; 
+  void (*invoke)(void *, ...);
+  struct block_descriptor_big *descriptor;
+};
+
+const char *getBlockSignature(void *block) {
+   struct block_layout_abi *layout = (struct block_layout_abi *)block;
+   if ((layout->flags & BLOCK_HAS_OBJC_TYPE) != BLOCK_HAS_OBJC_TYPE) return 0;
+   if (layout->flags & BLOCK_HAS_COPY_DISPOSE) 
+      return layout->descriptor->signature;
+   else
+      return ((struct block_descriptor_small *)layout->descriptor)->signature;
+}
+
+int usesStruct(void *block) {
+   struct block_layout_abi *layout = (struct block_layout_abi *)block;
+   int want = BLOCK_HAS_OBJC_TYPE | BLOCK_USE_STRET;
+   return (layout->flags & want) == want;
+}
+    
+   
+int main(int argc, char *argv[]) {
+   printf("desired global flags: %d\n", BLOCK_USE_STRET | BLOCK_IS_GLOBAL  | BLOCK_HAS_OBJC_TYPE);
+   printf("desired stack flags: %d\n",  BLOCK_USE_STRET | BLOCK_HAS_OBJC_TYPE);
+   
+   printf("should be non-zero: %d\n", usesStruct(global));
+   BigStruct_t x;
+   BigStruct_t (^local)(int) = ^(int param) {
+     BigStruct_t *result = (BigStruct_t *)malloc(sizeof(BigStruct_t));
+     result->array[23] = argc;
+     return *result;
+   };
+   printf("should be non-zero: %d\n", usesStruct(global));
+   printf("should be non-zero: %d\n", usesStruct(local));
+   printf("should be zero: %d\n", usesStruct(^void(int x){ }));
+   return 0;
+}
+
+/*
+desired global flags: 1879048192
+desired stack flags: 1610612736
+should be non-zero: 0
+should be non-zero: 0
+should be non-zero: 1
+should be zero: 0
+
+*/
diff --git a/test/CodeGen/bool-bitfield.c b/test/CodeGen/bool-bitfield.c
new file mode 100644
index 0000000..cb2d1db
--- /dev/null
+++ b/test/CodeGen/bool-bitfield.c
@@ -0,0 +1,54 @@
+// RUN: %clang_cc1 -emit-llvm %s -o %t
+
+// From GCC PR19331
+struct SysParams
+{
+ unsigned short tag;
+ unsigned short version;
+ unsigned int seqnum;
+ int contrast;
+ int igain_1, igain_2;
+ int oattn_1, oattn_2;
+ int max_out_vltg_1, max_out_vltg_2;
+ int max_mains_current;
+ int meters_mode;
+ int input_select;
+ _Bool input_parallelch2:1;
+ _Bool cliplmt_ch1:1;
+ _Bool cliplmt_ch2:1;
+ _Bool gate_ch1:1;
+ _Bool gate_ch2:1;
+ _Bool mute_ch1:1;
+ _Bool mute_ch2:1;
+ _Bool brownout:1;
+ _Bool power_on:1;
+ _Bool pwrup_mute:1;
+ _Bool keylock:1;
+ _Bool dsp_ch1:1;
+ _Bool dsp_ch2:1;
+ int dsp_preset;
+ long unlock_code;
+};
+extern struct SysParams params;
+
+void foo(void *);
+void kcmd_setParams(void)
+{
+ struct {
+  unsigned char igain_1;
+  unsigned char igain_2;
+  unsigned char max_out_vltg_1;
+  unsigned char max_out_vltg_2;
+  unsigned char max_imains;
+  unsigned char cliplmt_ch1:1;
+  unsigned char cliplmt_ch2:1;
+  unsigned char gate_ch1:1;
+  unsigned char gate_ch2:1;
+ } msg;
+ foo(&msg);
+ params.cliplmt_ch1 = msg.cliplmt_ch1;
+ params.cliplmt_ch2 = msg.cliplmt_ch2;
+ params.gate_ch1 = msg.gate_ch1;
+ params.gate_ch2 = msg.gate_ch2;
+}
+
diff --git a/test/CodeGen/bool-convert.c b/test/CodeGen/bool-convert.c
new file mode 100644
index 0000000..8bde837
--- /dev/null
+++ b/test/CodeGen/bool-convert.c
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -emit-llvm < %s | grep i1 | count 1
+// All of these should uses the memory representation of _Bool
+struct teststruct1 {_Bool a, b;} test1;
+_Bool* test2;
+_Bool test3[10];
+_Bool (*test4)[];
+void f(int x) {
+  _Bool test5;
+  _Bool test6[x];
+}
diff --git a/test/CodeGen/bool-init.c b/test/CodeGen/bool-init.c
new file mode 100644
index 0000000..1a8f127
--- /dev/null
+++ b/test/CodeGen/bool-init.c
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -emit-llvm < %s | grep i1 | count 1
+
+// Check that the type of this global isn't i1
+_Bool test = &test;
diff --git a/test/CodeGen/boolassign.c b/test/CodeGen/boolassign.c
new file mode 100644
index 0000000..8c56319
--- /dev/null
+++ b/test/CodeGen/boolassign.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 %s -emit-llvm -o %t
+
+int testBoolAssign(void) {
+  int ss;
+  if ((ss = ss && ss)) {}
+  return 1;
+}
diff --git a/test/CodeGen/builtin-attributes.c b/test/CodeGen/builtin-attributes.c
new file mode 100644
index 0000000..944aac3
--- /dev/null
+++ b/test/CodeGen/builtin-attributes.c
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -triple arm-unknown-unknown -emit-llvm -o - %s | FileCheck %s
+
+// CHECK: declare arm_aapcscc i32 @printf(i8*, ...)
+void f0() {
+  printf("a\n");
+}
+
+// CHECK: call arm_aapcscc void @exit
+// CHECK: unreachable
+void f1() {
+  exit(1);
+}
diff --git a/test/CodeGen/builtin-count-zeros.c b/test/CodeGen/builtin-count-zeros.c
new file mode 100644
index 0000000..5a0be2f
--- /dev/null
+++ b/test/CodeGen/builtin-count-zeros.c
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - | grep 'cttz' | count 2
+// RUN: %clang_cc1 -emit-llvm %s -o - | grep 'ctlz' | count 2
+
+int a(int a) {return __builtin_ctz(a) + __builtin_clz(a);}
diff --git a/test/CodeGen/builtin-memfns.c b/test/CodeGen/builtin-memfns.c
new file mode 100644
index 0000000..e8c407f
--- /dev/null
+++ b/test/CodeGen/builtin-memfns.c
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -triple i386-pc-linux-gnu -emit-llvm < %s| FileCheck %s
+
+// CHECK: call void @llvm.memset.p0i8.i32
+// CHECK: call void @llvm.memset.p0i8.i32
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i32
+// CHECK: call void @llvm.memmove.p0i8.p0i8.i32
+// CHECK-NOT: __builtin
+// CHECK: ret
+int main(int argc, char **argv) {
+  unsigned char a = 0x11223344;
+  unsigned char b = 0x11223344;
+  __builtin_bzero(&a, sizeof(a));
+  __builtin_memset(&a, 0, sizeof(a));
+  __builtin_memcpy(&a, &b, sizeof(a));
+  __builtin_memmove(&a, &b, sizeof(a));
+  return 0;
+}
diff --git a/test/CodeGen/builtin-nanf.c b/test/CodeGen/builtin-nanf.c
new file mode 100644
index 0000000..ae37c9d
--- /dev/null
+++ b/test/CodeGen/builtin-nanf.c
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -emit-llvm -o %t %s
+// RUN: grep 'float 0x7FF8000000000000, float 0x7FF8000000000000, float 0x7FF8000020000000, float 0x7FF8000000000000, float 0x7FF80001E0000000, float 0x7FF8001E00000000, float 0x7FF801E000000000, float 0x7FF81E0000000000, float 0x7FF9E00000000000, float 0x7FFFFFFFE0000000' %t
+
+float n[] = {
+  __builtin_nanf("0"),
+  __builtin_nanf(""),
+  __builtin_nanf("1"),
+  __builtin_nanf("0x7fc00000"),
+  __builtin_nanf("0x7fc0000f"),
+  __builtin_nanf("0x7fc000f0"),
+  __builtin_nanf("0x7fc00f00"),
+  __builtin_nanf("0x7fc0f000"),
+  __builtin_nanf("0x7fcf0000"),
+  __builtin_nanf("0xffffffff"),
+};
diff --git a/test/CodeGen/builtin-rename.c b/test/CodeGen/builtin-rename.c
new file mode 100644
index 0000000..0b71d88
--- /dev/null
+++ b/test/CodeGen/builtin-rename.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - | grep 'declare.*printf' | count 1
+// PR3612
+
+int printf(const char *, ...);
+
+int foo(void) {
+  return printf(printf);
+}
diff --git a/test/CodeGen/builtin-stackaddress.c b/test/CodeGen/builtin-stackaddress.c
new file mode 100644
index 0000000..f13b90e
--- /dev/null
+++ b/test/CodeGen/builtin-stackaddress.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -emit-llvm < %s | grep "llvm.returnaddress"
+// RUN: %clang_cc1 -emit-llvm < %s | grep "llvm.frameaddress"
+void* a(unsigned x) {
+return __builtin_return_address(0);
+}
+
+void* c(unsigned x) {
+return __builtin_frame_address(0);
+}
diff --git a/test/CodeGen/builtin-unwind-init.c b/test/CodeGen/builtin-unwind-init.c
new file mode 100644
index 0000000..6fa7766
--- /dev/null
+++ b/test/CodeGen/builtin-unwind-init.c
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -emit-llvm < %s -o - | FileCheck %s
+
+void a() { __builtin_unwind_init(); }
+
+// CHECK:  call void @llvm.eh.unwind.init()
diff --git a/test/CodeGen/builtinmemcpy.c b/test/CodeGen/builtinmemcpy.c
new file mode 100644
index 0000000..93253c5
--- /dev/null
+++ b/test/CodeGen/builtinmemcpy.c
@@ -0,0 +1,3 @@
+// RUN: %clang_cc1 -emit-llvm < %s -o - | grep "llvm.memcpy"
+
+char* x(char* a, char* b) {return __builtin_memcpy(a, b, 4);}
diff --git a/test/CodeGen/builtins-arm.c b/test/CodeGen/builtins-arm.c
new file mode 100644
index 0000000..5553757
--- /dev/null
+++ b/test/CodeGen/builtins-arm.c
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -triple thumbv7-eabi -target-cpu cortex-a8 -O3 -emit-llvm -o %t %s
+
+void *f0()
+{
+  return __builtin_thread_pointer();
+}
diff --git a/test/CodeGen/builtins-ppc-altivec.c b/test/CodeGen/builtins-ppc-altivec.c
new file mode 100644
index 0000000..04249cc
--- /dev/null
+++ b/test/CodeGen/builtins-ppc-altivec.c
@@ -0,0 +1,332 @@
+// RUN: %clang_cc1 -faltivec -triple powerpc-unknown-unknown -emit-llvm %s -o - | FileCheck %s
+
+#include "altivec.h"
+
+int main ()
+{
+  vector signed char vsc = { 1, -2, 3, -4, 5, -6, 7, -8, 9, -10, 11, -12, 13, -14, 15, -16 };
+  vector unsigned char vuc = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
+  vector short vs = { -1, 2, -3, 4, -5, 6, -7, 8 };
+  vector unsigned short vus = { 1, 2, 3, 4, 5, 6, 7, 8 };
+  vector int vi = { -1, 2, -3, 4 };
+  vector unsigned int vui = { 1, 2, 3, 4 };
+  vector float vf = { -1.5, 2.5, -3.5, 4.5 };
+
+  vector signed char res_vsc;
+  vector unsigned char res_vuc;
+  vector short res_vs;
+  vector unsigned short res_vus;
+  vector int res_vi;
+  vector unsigned int res_vui;
+  vector float res_vf;
+
+  int param_i;
+  int res_i;
+
+  /* vec_abs */
+  vsc = vec_abs(vsc);              // CHECK: sub <16 x i8> zeroinitializer
+                                   // CHECK: @llvm.ppc.altivec.vmaxsb
+
+  vs = __builtin_vec_abs(vs);      // CHECK: sub <8 x i16> zeroinitializer
+                                   // CHECK: @llvm.ppc.altivec.vmaxsh
+
+  vi = vec_abs(vi);                // CHECK: sub <4 x i32> zeroinitializer
+                                   // CHECK: @llvm.ppc.altivec.vmaxsw
+
+  vf = vec_abs(vf);                // CHECK: store <4 x i32> <i32 2147483647, i32 2147483647, i32 2147483647, i32 2147483647>
+                                   // CHECK: and <4 x i32>
+
+  /* vec_abs */
+  vsc = vec_abss(vsc);             // CHECK: @llvm.ppc.altivec.vsubsbs
+                                   // CHECK: @llvm.ppc.altivec.vmaxsb
+
+  vs = __builtin_vec_abss(vs);     // CHECK: @llvm.ppc.altivec.vsubshs
+                                   // CHECK: @llvm.ppc.altivec.vmaxsh
+
+  vi = vec_abss(vi);               // CHECK: @llvm.ppc.altivec.vsubsws
+                                   // CHECK: @llvm.ppc.altivec.vmaxsw
+
+  /*  vec_add */
+  res_vsc  = vec_add(vsc, vsc);                 // CHECK: add nsw <16 x i8>
+  res_vuc = vec_vaddubm(vuc, vuc);              // CHECK: add <16 x i8>
+  res_vs  = __builtin_altivec_vadduhm(vs, vs);  // CHECK: add nsw <8 x i16>
+  res_vus = vec_vadduhm(vus, vus);              // CHECK: add <8 x i16>
+  res_vi  = __builtin_vec_vadduwm(vi, vi);      // CHECK: add nsw <4 x i32>
+  res_vui = vec_vadduwm(vui, vui);              // CHECK: add <4 x i32>
+  res_vf  = __builtin_vec_vaddfp(vf, vf);       // CHECK: fadd <4 x float>
+
+  /* vec_addc */
+  res_vui = vec_vaddcuw(vui, vui);              // HECK: @llvm.ppc.altivec.vaddcuw
+
+  /* vec_adds */
+  res_vsc  = vec_adds(vsc, vsc);                // CHECK: @llvm.ppc.altivec.vaddsbs
+  res_vuc = vec_vaddubs(vuc, vuc);              // CHECK: @llvm.ppc.altivec.vaddubs
+  res_vs  = __builtin_vec_vaddshs(vs, vs);      // CHECK: @llvm.ppc.altivec.vaddshs
+  res_vus = vec_vadduhs(vus, vus);              // CHECK: @llvm.ppc.altivec.vadduhs
+  res_vi  = __builtin_vec_vaddsws(vi, vi);      // CHECK: @llvm.ppc.altivec.vaddsws
+  res_vui = vec_vadduws(vui, vui);              // CHECK: @llvm.ppc.altivec.vadduws
+
+  /* vec_sub */
+  res_vsc  = vec_sub(vsc, vsc);                 // CHECK: sub nsw <16 x i8>
+  res_vuc = vec_vsububm(vuc, vuc);              // CHECK: sub <16 x i8>
+  res_vs  = __builtin_altivec_vsubuhm(vs, vs);  // CHECK: sub nsw <8 x i16>
+  res_vus = vec_vsubuhm(vus, vus);              // CHECK: sub <8 x i16>
+  res_vi  = __builtin_vec_vsubuwm(vi, vi);      // CHECK: sub nsw <4 x i32>
+  res_vui = vec_vsubuwm(vui, vui);              // CHECK: sub <4 x i32>
+  res_vf  = __builtin_vec_vsubfp(vf, vf);       // CHECK: fsub <4 x float>
+
+  /* vec_subs */
+  res_vsc  = vec_subs(vsc, vsc);                // CHECK: @llvm.ppc.altivec.vsubsbs
+  res_vuc = vec_vsububs(vuc, vuc);              // CHECK: @llvm.ppc.altivec.vsububs
+  res_vs  = __builtin_vec_vsubshs(vs, vs);      // CHECK: @llvm.ppc.altivec.vsubshs
+  res_vus = vec_vsubuhs(vus, vus);              // CHECK: @llvm.ppc.altivec.vsubuhs
+  res_vi  = __builtin_vec_vsubsws(vi, vi);      // CHECK: @llvm.ppc.altivec.vsubsws
+  res_vui = vec_vsubuws(vui, vui);              // CHECK: @llvm.ppc.altivec.vsubuws
+
+  /* vec_avg */
+  res_vsc  = vec_avg(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vavgsb
+  res_vuc = __builtin_vec_vavgub(vuc, vuc);     // CHECK: @llvm.ppc.altivec.vavgub
+  res_vs  = vec_vavgsh(vs, vs);                 // CHECK: @llvm.ppc.altivec.vavgsh
+  res_vus = __builtin_vec_vavguh(vus, vus);     // CHECK: @llvm.ppc.altivec.vavguh
+  res_vi  = vec_vavgsw(vi, vi);                 // CHECK: @llvm.ppc.altivec.vavgsw
+  res_vui = __builtin_vec_vavguw(vui, vui);     // CHECK: @llvm.ppc.altivec.vavguw
+
+  /* vec_st */
+  param_i = 5;
+  vec_st(vsc, 0, &res_vsc);                     // CHECK: @llvm.ppc.altivec.stvx
+  __builtin_vec_st(vuc, param_i, &res_vuc);     // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvx(vs, 1, &res_vs);                     // CHECK: @llvm.ppc.altivec.stvx
+  vec_st(vus, 1000, &res_vus);                  // CHECK: @llvm.ppc.altivec.stvx
+  vec_st(vi, 0, &res_vi);                       // CHECK: @llvm.ppc.altivec.stvx
+  vec_st(vui, 0, &res_vui);                     // CHECK: @llvm.ppc.altivec.stvx
+  vec_st(vf, 0, &res_vf);                       // CHECK: @llvm.ppc.altivec.stvx
+
+  /* vec_stl */
+  param_i = 10000;
+  vec_stl(vsc, param_i, &res_vsc);              // CHECK: @llvm.ppc.altivec.stvxl
+  __builtin_vec_stl(vuc, 1, &res_vuc);          // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvxl(vs, 0, &res_vs);                    // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stl(vus, 0, &res_vus);                    // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stl(vi, 0, &res_vi);                      // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stl(vui, 0, &res_vui);                    // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stl(vf, 0, &res_vf);                      // CHECK: @llvm.ppc.altivec.stvxl
+
+  /* vec_ste */
+  param_i = 10000;
+  vec_ste(vsc, param_i, &res_vsc);              // CHECK: @llvm.ppc.altivec.stvebx
+  vec_stvebx(vuc, 1, &res_vuc);                 // CHECK: @llvm.ppc.altivec.stvebx
+  __builtin_vec_stvehx(vs, 0, &res_vs);         // CHECK: @llvm.ppc.altivec.stvehx
+  vec_stvehx(vus, 0, &res_vus);                 // CHECK: @llvm.ppc.altivec.stvehx
+  vec_stvewx(vi, 0, &res_vi);                   // CHECK: @llvm.ppc.altivec.stvewx
+  __builtin_vec_stvewx(vui, 0, &res_vui);       // CHECK: @llvm.ppc.altivec.stvewx
+  vec_stvewx(vf, 0, &res_vf);                   // CHECK: @llvm.ppc.altivec.stvewx
+
+  /* vec_cmpb */
+  res_vi = vec_vcmpbfp(vf, vf);                 // CHECK: @llvm.ppc.altivec.vcmpbfp
+
+  /* vec_cmpeq */
+  res_vi = vec_cmpeq(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpequb
+  res_vi = __builtin_vec_cmpeq(vuc, vuc);       // CHECK: @llvm.ppc.altivec.vcmpequb
+  res_vi = vec_cmpeq(vs, vs);                   // CHECK: @llvm.ppc.altivec.vcmpequh
+  res_vi = vec_cmpeq(vus, vus);                 // CHECK: @llvm.ppc.altivec.vcmpequh
+  res_vi = vec_cmpeq(vi, vi);                   // CHECK: @llvm.ppc.altivec.vcmpequw
+  res_vi = vec_cmpeq(vui, vui);                 // CHECK: @llvm.ppc.altivec.vcmpequw
+  res_vi = vec_cmpeq(vf, vf);                   // CHECK: @llvm.ppc.altivec.vcmpeqfp
+
+  /* vec_cmpge */
+  res_vi = __builtin_vec_cmpge(vf, vf);         // CHECK: @llvm.ppc.altivec.vcmpgefp
+
+  /* vec_cmpgt */
+  res_vi = vec_cmpgt(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpgtsb
+  res_vi = vec_vcmpgtub(vuc, vuc);              // CHECK: @llvm.ppc.altivec.vcmpgtub
+  res_vi = __builtin_vec_vcmpgtsh(vs, vs);      // CHECK: @llvm.ppc.altivec.vcmpgtsh
+  res_vi = vec_cmpgt(vus, vus);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh
+  res_vi = vec_cmpgt(vi, vi);                   // CHECK: @llvm.ppc.altivec.vcmpgtsw
+  res_vi = vec_cmpgt(vui, vui);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw
+  res_vi = vec_cmpgt(vf, vf);                   // CHECK: @llvm.ppc.altivec.vcmpgtfp
+
+  /* vec_cmple */
+  res_vi = __builtin_vec_cmple(vf, vf);         // CHECK: @llvm.ppc.altivec.vcmpgefp
+
+  /* vec_cmplt */
+  res_vi = vec_cmplt(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpgtsb
+  res_vi = __builtin_vec_cmplt(vuc, vuc);       // CHECK: @llvm.ppc.altivec.vcmpgtub
+  res_vi = vec_cmplt(vs, vs);                   // CHECK: @llvm.ppc.altivec.vcmpgtsh
+  res_vi = vec_cmplt(vus, vus);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh
+  res_vi = vec_cmplt(vi, vi);                   // CHECK: @llvm.ppc.altivec.vcmpgtsw
+  res_vi = vec_cmplt(vui, vui);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw
+  res_vi = vec_cmplt(vf, vf);                   // CHECK: @llvm.ppc.altivec.vcmpgtfp
+
+  /* vec_max */
+  res_vsc  = vec_max(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vmaxsb
+  res_vuc = __builtin_vec_vmaxub(vuc, vuc);     // CHECK: @llvm.ppc.altivec.vmaxub
+  res_vs  = vec_vmaxsh(vs, vs);                 // CHECK: @llvm.ppc.altivec.vmaxsh
+  res_vus = vec_max(vus, vus);                  // CHECK: @llvm.ppc.altivec.vmaxuh
+  res_vi  = __builtin_vec_vmaxsw(vi, vi);       // CHECK: @llvm.ppc.altivec.vmaxsw
+  res_vui = vec_vmaxuw(vui, vui);               // CHECK: @llvm.ppc.altivec.vmaxuw
+  res_vf  = __builtin_vec_max(vf, vf);          // CHECK: @llvm.ppc.altivec.vmaxfp
+
+  /* vec_mfvscr */
+  vf = vec_mfvscr();                            // CHECK: @llvm.ppc.altivec.mfvscr
+
+  /* vec_min */
+  res_vsc  = vec_min(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vminsb
+  res_vuc = __builtin_vec_vminub(vuc, vuc);     // CHECK: @llvm.ppc.altivec.vminub
+  res_vs  = vec_vminsh(vs, vs);                 // CHECK: @llvm.ppc.altivec.vminsh
+  res_vus = vec_min(vus, vus);                  // CHECK: @llvm.ppc.altivec.vminuh
+  res_vi  = __builtin_vec_vminsw(vi, vi);       // CHECK: @llvm.ppc.altivec.vminsw
+  res_vui = vec_vminuw(vui, vui);               // CHECK: @llvm.ppc.altivec.vminuw
+  res_vf  = __builtin_vec_min(vf, vf);          // CHECK: @llvm.ppc.altivec.vminfp
+
+  /* vec_mtvscr */
+  vec_mtvscr(vsc);                              // CHECK: @llvm.ppc.altivec.mtvscr
+
+  /* ------------------------------ predicates -------------------------------------- */
+
+  res_i = __builtin_vec_vcmpeq_p(__CR6_EQ, vsc, vui); // CHECK: @llvm.ppc.altivec.vcmpeqfp.p
+  res_i = __builtin_vec_vcmpge_p(__CR6_EQ, vs, vi);   // CHECK: @llvm.ppc.altivec.vcmpgefp.p
+  res_i = __builtin_vec_vcmpgt_p(__CR6_EQ, vuc, vf);  // CHECK: @llvm.ppc.altivec.vcmpgtfp.p
+
+  /*  vec_all_eq */
+  res_i = vec_all_eq(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
+  res_i = vec_all_eq(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
+  res_i = vec_all_eq(vs, vs);                   // CHECK: @llvm.ppc.altivec.vcmpequh.p
+  res_i = vec_all_eq(vus, vus);                 // CHECK: @llvm.ppc.altivec.vcmpequh.p
+  res_i = vec_all_eq(vi, vi);                   // CHECK: @llvm.ppc.altivec.vcmpequw.p
+  res_i = vec_all_eq(vui, vui);                 // CHECK: @llvm.ppc.altivec.vcmpequw.p
+  res_i = vec_all_eq(vf, vf);                   // CHECK: @llvm.ppc.altivec.vcmpeqfp.p
+
+  /* vec_all_ge */
+  res_i = vec_all_ge(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpgtsb.p
+  res_i = vec_all_ge(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
+  res_i = vec_all_ge(vs, vs);                   // CHECK: @llvm.ppc.altivec.vcmpgtsh.p
+  res_i = vec_all_ge(vus, vus);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+  res_i = vec_all_ge(vi, vi);                   // CHECK: @llvm.ppc.altivec.vcmpgtsw.p
+  res_i = vec_all_ge(vui, vui);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+  res_i = vec_all_ge(vf, vf);                   // CHECK: @llvm.ppc.altivec.vcmpgtfp.p
+
+  /* vec_all_gt */
+  res_i = vec_all_gt(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpgtsb.p
+  res_i = vec_all_gt(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
+  res_i = vec_all_gt(vs, vs);                   // CHECK: @llvm.ppc.altivec.vcmpgtsh.p
+  res_i = vec_all_gt(vus, vus);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+  res_i = vec_all_gt(vi, vi);                   // CHECK: @llvm.ppc.altivec.vcmpgtsw.p
+  res_i = vec_all_gt(vui, vui);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+  res_i = vec_all_gt(vf, vf);                   // CHECK: @llvm.ppc.altivec.vcmpgtfp.p
+
+  /* vec_all_in */
+  res_i = vec_all_in(vf, vf);                   // CHECK: @llvm.ppc.altivec.vcmpbfp.p
+
+  /* vec_all_le */
+  res_i = vec_all_le(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpgtsb.p
+  res_i = vec_all_le(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
+  res_i = vec_all_le(vs, vs);                   // CHECK: @llvm.ppc.altivec.vcmpgtsh.p
+  res_i = vec_all_le(vus, vus);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+  res_i = vec_all_le(vi, vi);                   // CHECK: @llvm.ppc.altivec.vcmpgtsw.p
+  res_i = vec_all_le(vui, vui);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+  res_i = vec_all_le(vf, vf);                   // CHECK: @llvm.ppc.altivec.vcmpgtfp.p
+
+  /* vec_all_nan */
+  res_i = vec_all_nan(vf);                      // CHECK: @llvm.ppc.altivec.vcmpeqfp.p
+
+  /*  vec_all_ne */
+  res_i = vec_all_ne(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
+  res_i = vec_all_ne(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
+  res_i = vec_all_ne(vs, vs);                   // CHECK: @llvm.ppc.altivec.vcmpequh.p
+  res_i = vec_all_ne(vus, vus);                 // CHECK: @llvm.ppc.altivec.vcmpequh.p
+  res_i = vec_all_ne(vi, vi);                   // CHECK: @llvm.ppc.altivec.vcmpequw.p
+  res_i = vec_all_ne(vui, vui);                 // CHECK: @llvm.ppc.altivec.vcmpequw.p
+  res_i = vec_all_ne(vf, vf);                   // CHECK: @llvm.ppc.altivec.vcmpeqfp.p
+
+  /* vec_all_nge */
+  res_i = vec_all_nge(vf, vf);                  // CHECK: @llvm.ppc.altivec.vcmpgefp.p
+
+  /* vec_all_ngt */
+  res_i = vec_all_ngt(vf, vf);                  // CHECK: @llvm.ppc.altivec.vcmpgtfp.p
+
+  /* vec_all_nle */
+  res_i = vec_all_nle(vf, vf);                  // CHECK: @llvm.ppc.altivec.vcmpgefp.p
+
+  /* vec_all_nlt */
+  res_i = vec_all_nlt(vf, vf);                  // CHECK: @llvm.ppc.altivec.vcmpgtfp.p
+
+  /* vec_all_numeric */
+  res_i = vec_all_numeric(vf);                  // CHECK: @llvm.ppc.altivec.vcmpeqfp.p
+
+  /*  vec_any_eq */
+  res_i = vec_any_eq(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
+  res_i = vec_any_eq(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
+  res_i = vec_any_eq(vs, vs);                   // CHECK: @llvm.ppc.altivec.vcmpequh.p
+  res_i = vec_any_eq(vus, vus);                 // CHECK: @llvm.ppc.altivec.vcmpequh.p
+  res_i = vec_any_eq(vi, vi);                   // CHECK: @llvm.ppc.altivec.vcmpequw.p
+  res_i = vec_any_eq(vui, vui);                 // CHECK: @llvm.ppc.altivec.vcmpequw.p
+  res_i = vec_any_eq(vf, vf);                   // CHECK: @llvm.ppc.altivec.vcmpeqfp.p
+
+  /* vec_any_ge */
+  res_i = vec_any_ge(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpgtsb.p
+  res_i = vec_any_ge(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
+  res_i = vec_any_ge(vs, vs);                   // CHECK: @llvm.ppc.altivec.vcmpgtsh.p
+  res_i = vec_any_ge(vus, vus);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+  res_i = vec_any_ge(vi, vi);                   // CHECK: @llvm.ppc.altivec.vcmpgtsw.p
+  res_i = vec_any_ge(vui, vui);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+  res_i = vec_any_ge(vf, vf);                   // CHECK: @llvm.ppc.altivec.vcmpgtfp.p
+
+  /* vec_any_gt */
+  res_i = vec_any_gt(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpgtsb.p
+  res_i = vec_any_gt(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
+  res_i = vec_any_gt(vs, vs);                   // CHECK: @llvm.ppc.altivec.vcmpgtsh.p
+  res_i = vec_any_gt(vus, vus);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+  res_i = vec_any_gt(vi, vi);                   // CHECK: @llvm.ppc.altivec.vcmpgtsw.p
+  res_i = vec_any_gt(vui, vui);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+  res_i = vec_any_gt(vf, vf);                   // CHECK: @llvm.ppc.altivec.vcmpgtfp.p
+
+  /* vec_any_le */
+  res_i = vec_any_le(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpgtsb.p
+  res_i = vec_any_le(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
+  res_i = vec_any_le(vs, vs);                   // CHECK: @llvm.ppc.altivec.vcmpgtsh.p
+  res_i = vec_any_le(vus, vus);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+  res_i = vec_any_le(vi, vi);                   // CHECK: @llvm.ppc.altivec.vcmpgtsw.p
+  res_i = vec_any_le(vui, vui);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+  res_i = vec_any_le(vf, vf);                   // CHECK: @llvm.ppc.altivec.vcmpgtfp.p
+
+  /* vec_any_lt */
+  res_i = vec_any_lt(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpgtsb.p
+  res_i = vec_any_lt(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
+  res_i = vec_any_lt(vs, vs);                   // CHECK: @llvm.ppc.altivec.vcmpgtsh.p
+  res_i = vec_any_lt(vus, vus);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+  res_i = vec_any_lt(vi, vi);                   // CHECK: @llvm.ppc.altivec.vcmpgtsw.p
+  res_i = vec_any_lt(vui, vui);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+  res_i = vec_any_lt(vf, vf);                   // CHECK: @llvm.ppc.altivec.vcmpgtfp.p
+
+  /* vec_any_nan */
+  res_i = vec_any_nan(vf);                      // CHECK: @llvm.ppc.altivec.vcmpeqfp.p
+
+  /* vec_any_ne */
+  res_i = vec_any_ne(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
+  res_i = vec_any_ne(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
+  res_i = vec_any_ne(vs, vs);                   // CHECK: @llvm.ppc.altivec.vcmpequh.p
+  res_i = vec_any_ne(vus, vus);                 // CHECK: @llvm.ppc.altivec.vcmpequh.p
+  res_i = vec_any_ne(vi, vi);                   // CHECK: @llvm.ppc.altivec.vcmpequw.p
+  res_i = vec_any_ne(vui, vui);                 // CHECK: @llvm.ppc.altivec.vcmpequw.p
+  res_i = vec_any_ne(vf, vf);                   // CHECK: @llvm.ppc.altivec.vcmpeqfp.p
+
+  /* vec_any_nge */
+  res_i = vec_any_nge(vf, vf);                  // CHECK: @llvm.ppc.altivec.vcmpgefp.p
+
+  /* vec_any_ngt */
+  res_i = vec_any_ngt(vf, vf);                  // CHECK: @llvm.ppc.altivec.vcmpgtfp.p
+
+  /* vec_any_nle */
+  res_i = vec_any_nle(vf, vf);                  // CHECK: @llvm.ppc.altivec.vcmpgefp.p
+
+  /* vec_any_nlt */
+  res_i = vec_any_nlt(vf, vf);                  // CHECK: @llvm.ppc.altivec.vcmpgtfp.p
+
+  /* vec_any_numeric */
+  res_i = vec_any_numeric(vf);                  // CHECK: @llvm.ppc.altivec.vcmpeqfp.p
+
+  /* vec_any_out */
+  res_i = vec_any_out(vf, vf);                  // CHECK: @llvm.ppc.altivec.vcmpbfp.p
+
+  return 0;
+}
diff --git a/test/CodeGen/builtins-x86.c b/test/CodeGen/builtins-x86.c
new file mode 100644
index 0000000..b587814
--- /dev/null
+++ b/test/CodeGen/builtins-x86.c
@@ -0,0 +1,370 @@
+// RUN: %clang_cc1 -DUSE_64 -triple x86_64-unknown-unknown -emit-llvm -o %t %s
+// RUN: %clang_cc1 -DUSE_ALL -triple x86_64-unknown-unknown -fsyntax-only -o %t %s
+
+#ifdef USE_ALL
+#define USE_3DNOW
+#define USE_64
+#define USE_SSE4
+#endif
+
+// 64-bit
+typedef char V8c __attribute__((vector_size(8 * sizeof(char))));
+typedef signed short V4s __attribute__((vector_size(8)));
+typedef signed int V2i __attribute__((vector_size(8)));
+typedef signed long long V1LLi __attribute__((vector_size(8)));
+
+typedef float V2f __attribute__((vector_size(8)));
+
+// 128-bit
+typedef char V16c __attribute__((vector_size(16)));
+typedef signed short V8s __attribute__((vector_size(16)));
+typedef signed int V4i __attribute__((vector_size(16)));
+typedef signed long long V2LLi __attribute__((vector_size(16)));
+
+typedef float V4f __attribute__((vector_size(16)));
+typedef double V2d __attribute__((vector_size(16)));
+
+void f0() {
+  signed char         tmp_c;
+//  unsigned char       tmp_Uc;
+  signed short        tmp_s;
+#ifdef USE_ALL
+  unsigned short      tmp_Us;
+#endif
+  signed int          tmp_i;
+  unsigned int        tmp_Ui;
+  signed long long    tmp_LLi;
+//  unsigned long long  tmp_ULLi;
+  float               tmp_f;
+  double              tmp_d;
+
+  void*          tmp_vp;
+  const void*    tmp_vCp;
+  char*          tmp_cp; 
+  const char*    tmp_cCp; 
+  int*           tmp_ip;
+  float*         tmp_fp;
+  const float*   tmp_fCp;
+  double*        tmp_dp;
+  const double*  tmp_dCp;
+
+#define imm_i 32
+#define imm_i_0_2 0
+#define imm_i_0_4 3
+#define imm_i_0_8 7
+#define imm_i_0_16 15
+  // Check this.
+#define imm_i_0_256 0
+
+  V2i*   tmp_V2ip;
+  V1LLi* tmp_V1LLip;
+  V2LLi* tmp_V2LLip;
+
+  // 64-bit
+  V8c    tmp_V8c;
+  V4s    tmp_V4s;
+  V2i    tmp_V2i;
+  V1LLi  tmp_V1LLi;
+#ifdef USE_3DNOW
+  V2f    tmp_V2f;
+#endif
+
+  // 128-bit
+  V16c   tmp_V16c;
+  V8s    tmp_V8s;
+  V4i    tmp_V4i;
+  V2LLi  tmp_V2LLi;
+  V4f    tmp_V4f;
+  V2d    tmp_V2d;
+
+  tmp_i = __builtin_ia32_comieq(tmp_V4f, tmp_V4f);
+  tmp_i = __builtin_ia32_comilt(tmp_V4f, tmp_V4f);
+  tmp_i = __builtin_ia32_comile(tmp_V4f, tmp_V4f);
+  tmp_i = __builtin_ia32_comigt(tmp_V4f, tmp_V4f);
+  tmp_i = __builtin_ia32_comige(tmp_V4f, tmp_V4f);
+  tmp_i = __builtin_ia32_comineq(tmp_V4f, tmp_V4f);
+  tmp_i = __builtin_ia32_ucomieq(tmp_V4f, tmp_V4f);
+  tmp_i = __builtin_ia32_ucomilt(tmp_V4f, tmp_V4f);
+  tmp_i = __builtin_ia32_ucomile(tmp_V4f, tmp_V4f);
+  tmp_i = __builtin_ia32_ucomigt(tmp_V4f, tmp_V4f);
+  tmp_i = __builtin_ia32_ucomige(tmp_V4f, tmp_V4f);
+  tmp_i = __builtin_ia32_ucomineq(tmp_V4f, tmp_V4f);
+  tmp_i = __builtin_ia32_comisdeq(tmp_V2d, tmp_V2d);
+  tmp_i = __builtin_ia32_comisdlt(tmp_V2d, tmp_V2d);
+  tmp_i = __builtin_ia32_comisdle(tmp_V2d, tmp_V2d);
+  tmp_i = __builtin_ia32_comisdgt(tmp_V2d, tmp_V2d);
+  tmp_i = __builtin_ia32_comisdge(tmp_V2d, tmp_V2d);
+  tmp_i = __builtin_ia32_comisdneq(tmp_V2d, tmp_V2d);
+  tmp_i = __builtin_ia32_ucomisdeq(tmp_V2d, tmp_V2d);
+  tmp_i = __builtin_ia32_ucomisdlt(tmp_V2d, tmp_V2d);
+  tmp_i = __builtin_ia32_ucomisdle(tmp_V2d, tmp_V2d);
+  tmp_i = __builtin_ia32_ucomisdgt(tmp_V2d, tmp_V2d);
+  tmp_i = __builtin_ia32_ucomisdge(tmp_V2d, tmp_V2d);
+  tmp_i = __builtin_ia32_ucomisdneq(tmp_V2d, tmp_V2d);
+  tmp_V4f = __builtin_ia32_cmpps(tmp_V4f, tmp_V4f, 0);
+  tmp_V4f = __builtin_ia32_cmpps(tmp_V4f, tmp_V4f, 1);
+  tmp_V4f = __builtin_ia32_cmpps(tmp_V4f, tmp_V4f, 2);
+  tmp_V4f = __builtin_ia32_cmpps(tmp_V4f, tmp_V4f, 3);
+  tmp_V4f = __builtin_ia32_cmpps(tmp_V4f, tmp_V4f, 4);
+  tmp_V4f = __builtin_ia32_cmpps(tmp_V4f, tmp_V4f, 5);
+  tmp_V4f = __builtin_ia32_cmpps(tmp_V4f, tmp_V4f, 6);
+  tmp_V4f = __builtin_ia32_cmpps(tmp_V4f, tmp_V4f, 7);
+  tmp_V4f = __builtin_ia32_cmpss(tmp_V4f, tmp_V4f, 0);
+  tmp_V4f = __builtin_ia32_cmpss(tmp_V4f, tmp_V4f, 1);
+  tmp_V4f = __builtin_ia32_cmpss(tmp_V4f, tmp_V4f, 2);
+  tmp_V4f = __builtin_ia32_cmpss(tmp_V4f, tmp_V4f, 3);
+  tmp_V4f = __builtin_ia32_cmpss(tmp_V4f, tmp_V4f, 4);
+  tmp_V4f = __builtin_ia32_cmpss(tmp_V4f, tmp_V4f, 5);
+  tmp_V4f = __builtin_ia32_cmpss(tmp_V4f, tmp_V4f, 6);
+  tmp_V4f = __builtin_ia32_cmpss(tmp_V4f, tmp_V4f, 7);
+  tmp_V4f = __builtin_ia32_minps(tmp_V4f, tmp_V4f);
+  tmp_V4f = __builtin_ia32_maxps(tmp_V4f, tmp_V4f);
+  tmp_V4f = __builtin_ia32_minss(tmp_V4f, tmp_V4f);
+  tmp_V4f = __builtin_ia32_maxss(tmp_V4f, tmp_V4f);
+
+  tmp_V8c = __builtin_ia32_paddsb(tmp_V8c, tmp_V8c);
+  tmp_V4s = __builtin_ia32_paddsw(tmp_V4s, tmp_V4s);
+  tmp_V8c = __builtin_ia32_psubsb(tmp_V8c, tmp_V8c);
+  tmp_V4s = __builtin_ia32_psubsw(tmp_V4s, tmp_V4s);
+  tmp_V8c = __builtin_ia32_paddusb(tmp_V8c, tmp_V8c);
+  tmp_V4s = __builtin_ia32_paddusw(tmp_V4s, tmp_V4s);
+  tmp_V8c = __builtin_ia32_psubusb(tmp_V8c, tmp_V8c);
+  tmp_V4s = __builtin_ia32_psubusw(tmp_V4s, tmp_V4s);
+  tmp_V4s = __builtin_ia32_pmulhw(tmp_V4s, tmp_V4s);
+  tmp_V4s = __builtin_ia32_pmulhuw(tmp_V4s, tmp_V4s);
+  tmp_V8c = __builtin_ia32_pavgb(tmp_V8c, tmp_V8c);
+  tmp_V4s = __builtin_ia32_pavgw(tmp_V4s, tmp_V4s);
+  tmp_V8c = __builtin_ia32_pcmpeqb(tmp_V8c, tmp_V8c);
+  tmp_V4s = __builtin_ia32_pcmpeqw(tmp_V4s, tmp_V4s);
+  tmp_V2i = __builtin_ia32_pcmpeqd(tmp_V2i, tmp_V2i);
+  tmp_V8c = __builtin_ia32_pcmpgtb(tmp_V8c, tmp_V8c);
+  tmp_V4s = __builtin_ia32_pcmpgtw(tmp_V4s, tmp_V4s);
+  tmp_V2i = __builtin_ia32_pcmpgtd(tmp_V2i, tmp_V2i);
+  tmp_V8c = __builtin_ia32_pmaxub(tmp_V8c, tmp_V8c);
+  tmp_V4s = __builtin_ia32_pmaxsw(tmp_V4s, tmp_V4s);
+  tmp_V8c = __builtin_ia32_pminub(tmp_V8c, tmp_V8c);
+  tmp_V4s = __builtin_ia32_pminsw(tmp_V4s, tmp_V4s);
+  tmp_V2d = __builtin_ia32_cmppd(tmp_V2d, tmp_V2d, 0);
+  tmp_V2d = __builtin_ia32_cmppd(tmp_V2d, tmp_V2d, 1);
+  tmp_V2d = __builtin_ia32_cmppd(tmp_V2d, tmp_V2d, 2);
+  tmp_V2d = __builtin_ia32_cmppd(tmp_V2d, tmp_V2d, 3);
+  tmp_V2d = __builtin_ia32_cmppd(tmp_V2d, tmp_V2d, 4);
+  tmp_V2d = __builtin_ia32_cmppd(tmp_V2d, tmp_V2d, 5);
+  tmp_V2d = __builtin_ia32_cmppd(tmp_V2d, tmp_V2d, 6);
+  tmp_V2d = __builtin_ia32_cmppd(tmp_V2d, tmp_V2d, 7);
+  tmp_V2d = __builtin_ia32_cmpsd(tmp_V2d, tmp_V2d, 0);
+  tmp_V2d = __builtin_ia32_cmpsd(tmp_V2d, tmp_V2d, 1);
+  tmp_V2d = __builtin_ia32_cmpsd(tmp_V2d, tmp_V2d, 2);
+  tmp_V2d = __builtin_ia32_cmpsd(tmp_V2d, tmp_V2d, 3);
+  tmp_V2d = __builtin_ia32_cmpsd(tmp_V2d, tmp_V2d, 4);
+  tmp_V2d = __builtin_ia32_cmpsd(tmp_V2d, tmp_V2d, 5);
+  tmp_V2d = __builtin_ia32_cmpsd(tmp_V2d, tmp_V2d, 6);
+  tmp_V2d = __builtin_ia32_cmpsd(tmp_V2d, tmp_V2d, 7);
+  tmp_V2d = __builtin_ia32_minpd(tmp_V2d, tmp_V2d);
+  tmp_V2d = __builtin_ia32_maxpd(tmp_V2d, tmp_V2d);
+  tmp_V2d = __builtin_ia32_minsd(tmp_V2d, tmp_V2d);
+  tmp_V2d = __builtin_ia32_maxsd(tmp_V2d, tmp_V2d);
+  tmp_V16c = __builtin_ia32_paddsb128(tmp_V16c, tmp_V16c);
+  tmp_V8s = __builtin_ia32_paddsw128(tmp_V8s, tmp_V8s);
+  tmp_V16c = __builtin_ia32_psubsb128(tmp_V16c, tmp_V16c);
+  tmp_V8s = __builtin_ia32_psubsw128(tmp_V8s, tmp_V8s);
+  tmp_V16c = __builtin_ia32_paddusb128(tmp_V16c, tmp_V16c);
+  tmp_V8s = __builtin_ia32_paddusw128(tmp_V8s, tmp_V8s);
+  tmp_V16c = __builtin_ia32_psubusb128(tmp_V16c, tmp_V16c);
+  tmp_V8s = __builtin_ia32_psubusw128(tmp_V8s, tmp_V8s);
+  tmp_V8s = __builtin_ia32_pmulhw128(tmp_V8s, tmp_V8s);
+  tmp_V16c = __builtin_ia32_pavgb128(tmp_V16c, tmp_V16c);
+  tmp_V8s = __builtin_ia32_pavgw128(tmp_V8s, tmp_V8s);
+  tmp_V16c = __builtin_ia32_pcmpeqb128(tmp_V16c, tmp_V16c);
+  tmp_V8s = __builtin_ia32_pcmpeqw128(tmp_V8s, tmp_V8s);
+  tmp_V4i = __builtin_ia32_pcmpeqd128(tmp_V4i, tmp_V4i);
+  tmp_V16c = __builtin_ia32_pcmpgtb128(tmp_V16c, tmp_V16c);
+  tmp_V8s = __builtin_ia32_pcmpgtw128(tmp_V8s, tmp_V8s);
+  tmp_V4i = __builtin_ia32_pcmpgtd128(tmp_V4i, tmp_V4i);
+  tmp_V16c = __builtin_ia32_pmaxub128(tmp_V16c, tmp_V16c);
+  tmp_V8s = __builtin_ia32_pmaxsw128(tmp_V8s, tmp_V8s);
+  tmp_V16c = __builtin_ia32_pminub128(tmp_V16c, tmp_V16c);
+  tmp_V8s = __builtin_ia32_pminsw128(tmp_V8s, tmp_V8s);
+  tmp_V8s = __builtin_ia32_packsswb128(tmp_V8s, tmp_V8s);
+  tmp_V4i = __builtin_ia32_packssdw128(tmp_V4i, tmp_V4i);
+  tmp_V8s = __builtin_ia32_packuswb128(tmp_V8s, tmp_V8s);
+  tmp_V8s = __builtin_ia32_pmulhuw128(tmp_V8s, tmp_V8s);
+  tmp_V4f = __builtin_ia32_addsubps(tmp_V4f, tmp_V4f);
+  tmp_V2d = __builtin_ia32_addsubpd(tmp_V2d, tmp_V2d);
+  tmp_V4f = __builtin_ia32_haddps(tmp_V4f, tmp_V4f);
+  tmp_V2d = __builtin_ia32_haddpd(tmp_V2d, tmp_V2d);
+  tmp_V4f = __builtin_ia32_hsubps(tmp_V4f, tmp_V4f);
+  tmp_V2d = __builtin_ia32_hsubpd(tmp_V2d, tmp_V2d);
+  tmp_V8s = __builtin_ia32_phaddw128(tmp_V8s, tmp_V8s);
+  tmp_V4s = __builtin_ia32_phaddw(tmp_V4s, tmp_V4s);
+  tmp_V4i = __builtin_ia32_phaddd128(tmp_V4i, tmp_V4i);
+  tmp_V2i = __builtin_ia32_phaddd(tmp_V2i, tmp_V2i);
+  tmp_V8s = __builtin_ia32_phaddsw128(tmp_V8s, tmp_V8s);
+  tmp_V4s = __builtin_ia32_phaddsw(tmp_V4s, tmp_V4s);
+  tmp_V8s = __builtin_ia32_phsubw128(tmp_V8s, tmp_V8s);
+  tmp_V4s = __builtin_ia32_phsubw(tmp_V4s, tmp_V4s);
+  tmp_V4i = __builtin_ia32_phsubd128(tmp_V4i, tmp_V4i);
+  tmp_V2i = __builtin_ia32_phsubd(tmp_V2i, tmp_V2i);
+  tmp_V8s = __builtin_ia32_phsubsw128(tmp_V8s, tmp_V8s);
+  tmp_V4s = __builtin_ia32_phsubsw(tmp_V4s, tmp_V4s);
+  tmp_V16c = __builtin_ia32_pmaddubsw128(tmp_V16c, tmp_V16c);
+  tmp_V8c = __builtin_ia32_pmaddubsw(tmp_V8c, tmp_V8c);
+  tmp_V8s = __builtin_ia32_pmulhrsw128(tmp_V8s, tmp_V8s);
+  tmp_V4s = __builtin_ia32_pmulhrsw(tmp_V4s, tmp_V4s);
+  tmp_V16c = __builtin_ia32_pshufb128(tmp_V16c, tmp_V16c);
+  tmp_V8c = __builtin_ia32_pshufb(tmp_V8c, tmp_V8c);
+  tmp_V16c = __builtin_ia32_psignb128(tmp_V16c, tmp_V16c);
+  tmp_V8c = __builtin_ia32_psignb(tmp_V8c, tmp_V8c);
+  tmp_V8s = __builtin_ia32_psignw128(tmp_V8s, tmp_V8s);
+  tmp_V4s = __builtin_ia32_psignw(tmp_V4s, tmp_V4s);
+  tmp_V4i = __builtin_ia32_psignd128(tmp_V4i, tmp_V4i);
+  tmp_V2i = __builtin_ia32_psignd(tmp_V2i, tmp_V2i);
+  tmp_V16c = __builtin_ia32_pabsb128(tmp_V16c);
+  tmp_V8c = __builtin_ia32_pabsb(tmp_V8c);
+  tmp_V8s = __builtin_ia32_pabsw128(tmp_V8s);
+  tmp_V4s = __builtin_ia32_pabsw(tmp_V4s);
+  tmp_V4i = __builtin_ia32_pabsd128(tmp_V4i);
+  tmp_V2i = __builtin_ia32_pabsd(tmp_V2i);
+  tmp_V4s = __builtin_ia32_psllw(tmp_V4s, tmp_V1LLi);
+  tmp_V2i = __builtin_ia32_pslld(tmp_V2i, tmp_V1LLi);
+  tmp_V1LLi = __builtin_ia32_psllq(tmp_V1LLi, tmp_V1LLi);
+  tmp_V4s = __builtin_ia32_psrlw(tmp_V4s, tmp_V1LLi);
+  tmp_V2i = __builtin_ia32_psrld(tmp_V2i, tmp_V1LLi);
+  tmp_V1LLi = __builtin_ia32_psrlq(tmp_V1LLi, tmp_V1LLi);
+  tmp_V4s = __builtin_ia32_psraw(tmp_V4s, tmp_V1LLi);
+  tmp_V2i = __builtin_ia32_psrad(tmp_V2i, tmp_V1LLi);
+  tmp_V2i = __builtin_ia32_pmaddwd(tmp_V4s, tmp_V4s);
+  tmp_V8c = __builtin_ia32_packsswb(tmp_V4s, tmp_V4s);
+  tmp_V4s = __builtin_ia32_packssdw(tmp_V2i, tmp_V2i);
+  tmp_V8c = __builtin_ia32_packuswb(tmp_V4s, tmp_V4s);
+
+  (void) __builtin_ia32_ldmxcsr(tmp_Ui);
+  tmp_Ui = __builtin_ia32_stmxcsr();
+  tmp_V4f = __builtin_ia32_cvtpi2ps(tmp_V4f, tmp_V2i);
+  tmp_V2i = __builtin_ia32_cvtps2pi(tmp_V4f);
+  tmp_i = __builtin_ia32_cvtss2si(tmp_V4f);
+#ifdef USE_64
+  tmp_LLi = __builtin_ia32_cvtss2si64(tmp_V4f);
+#endif
+  tmp_V2i = __builtin_ia32_cvttps2pi(tmp_V4f);
+  (void) __builtin_ia32_maskmovq(tmp_V8c, tmp_V8c, tmp_cp);
+  tmp_V4f = __builtin_ia32_loadups(tmp_fCp);
+  (void) __builtin_ia32_storeups(tmp_fp, tmp_V4f);
+  (void) __builtin_ia32_storehps(tmp_V2ip, tmp_V4f);
+  (void) __builtin_ia32_storelps(tmp_V2ip, tmp_V4f);
+  tmp_i = __builtin_ia32_movmskps(tmp_V4f);
+  tmp_i = __builtin_ia32_pmovmskb(tmp_V8c);
+  (void) __builtin_ia32_movntps(tmp_fp, tmp_V4f);
+  (void) __builtin_ia32_movntq(tmp_V1LLip, tmp_V1LLi);
+  (void) __builtin_ia32_sfence();
+
+  tmp_V4s = __builtin_ia32_psadbw(tmp_V8c, tmp_V8c);
+  tmp_V4f = __builtin_ia32_rcpps(tmp_V4f);
+  tmp_V4f = __builtin_ia32_rcpss(tmp_V4f);
+  tmp_V4f = __builtin_ia32_rsqrtps(tmp_V4f);
+  tmp_V4f = __builtin_ia32_rsqrtss(tmp_V4f);
+  tmp_V4f = __builtin_ia32_sqrtps(tmp_V4f);
+  tmp_V4f = __builtin_ia32_sqrtss(tmp_V4f);
+  (void) __builtin_ia32_maskmovdqu(tmp_V16c, tmp_V16c, tmp_cp);
+  tmp_V2d = __builtin_ia32_loadupd(tmp_dCp);
+  (void) __builtin_ia32_storeupd(tmp_dp, tmp_V2d);
+  tmp_i = __builtin_ia32_movmskpd(tmp_V2d);
+  tmp_i = __builtin_ia32_pmovmskb128(tmp_V16c);
+  (void) __builtin_ia32_movnti(tmp_ip, tmp_i);
+  (void) __builtin_ia32_movntpd(tmp_dp, tmp_V2d);
+  (void) __builtin_ia32_movntdq(tmp_V2LLip, tmp_V2LLi);
+  tmp_V2LLi = __builtin_ia32_psadbw128(tmp_V16c, tmp_V16c);
+  tmp_V2d = __builtin_ia32_sqrtpd(tmp_V2d);
+  tmp_V2d = __builtin_ia32_sqrtsd(tmp_V2d);
+  tmp_V2d = __builtin_ia32_cvtdq2pd(tmp_V4i);
+  tmp_V4f = __builtin_ia32_cvtdq2ps(tmp_V4i);
+  tmp_V2LLi = __builtin_ia32_cvtpd2dq(tmp_V2d);
+  tmp_V2i = __builtin_ia32_cvtpd2pi(tmp_V2d);
+  tmp_V4f = __builtin_ia32_cvtpd2ps(tmp_V2d);
+  tmp_V4i = __builtin_ia32_cvttpd2dq(tmp_V2d);
+  tmp_V2i = __builtin_ia32_cvttpd2pi(tmp_V2d);
+  tmp_V2d = __builtin_ia32_cvtpi2pd(tmp_V2i);
+  tmp_i = __builtin_ia32_cvtsd2si(tmp_V2d);
+#ifdef USE_64
+  tmp_LLi = __builtin_ia32_cvtsd2si64(tmp_V2d);
+#endif
+  tmp_V4i = __builtin_ia32_cvtps2dq(tmp_V4f);
+  tmp_V2d = __builtin_ia32_cvtps2pd(tmp_V4f);
+  tmp_V4i = __builtin_ia32_cvttps2dq(tmp_V4f);
+  (void) __builtin_ia32_clflush(tmp_vCp);
+  (void) __builtin_ia32_lfence();
+  (void) __builtin_ia32_mfence();
+  tmp_V16c = __builtin_ia32_loaddqu(tmp_cCp);
+  (void) __builtin_ia32_storedqu(tmp_cp, tmp_V16c);
+  tmp_V4s = __builtin_ia32_psllwi(tmp_V4s, tmp_i);
+  tmp_V2i = __builtin_ia32_pslldi(tmp_V2i, tmp_i);
+  tmp_V1LLi = __builtin_ia32_psllqi(tmp_V1LLi, tmp_i);
+  tmp_V4s = __builtin_ia32_psrawi(tmp_V4s, tmp_i);
+  tmp_V2i = __builtin_ia32_psradi(tmp_V2i, tmp_i);
+  tmp_V4s = __builtin_ia32_psrlwi(tmp_V4s, tmp_i);
+  tmp_V2i = __builtin_ia32_psrldi(tmp_V2i, tmp_i);
+  tmp_V1LLi = __builtin_ia32_psrlqi(tmp_V1LLi, tmp_i);
+  tmp_V1LLi = __builtin_ia32_pmuludq(tmp_V2i, tmp_V2i);
+  tmp_V2LLi = __builtin_ia32_pmuludq128(tmp_V4i, tmp_V4i);
+  tmp_V8s = __builtin_ia32_psraw128(tmp_V8s, tmp_V8s);
+  tmp_V4i = __builtin_ia32_psrad128(tmp_V4i, tmp_V4i);
+  tmp_V8s = __builtin_ia32_psrlw128(tmp_V8s, tmp_V8s);
+  tmp_V4i = __builtin_ia32_psrld128(tmp_V4i, tmp_V4i);
+  tmp_V2LLi = __builtin_ia32_psrlq128(tmp_V2LLi, tmp_V2LLi);
+  tmp_V8s = __builtin_ia32_psllw128(tmp_V8s, tmp_V8s);
+  tmp_V4i = __builtin_ia32_pslld128(tmp_V4i, tmp_V4i);
+  tmp_V2LLi = __builtin_ia32_psllq128(tmp_V2LLi, tmp_V2LLi);
+  tmp_V8s = __builtin_ia32_psllwi128(tmp_V8s, tmp_i);
+  tmp_V4i = __builtin_ia32_pslldi128(tmp_V4i, tmp_i);
+  tmp_V2LLi = __builtin_ia32_psllqi128(tmp_V2LLi, tmp_i);
+  tmp_V8s = __builtin_ia32_psrlwi128(tmp_V8s, tmp_i);
+  tmp_V4i = __builtin_ia32_psrldi128(tmp_V4i, tmp_i);
+  tmp_V2LLi = __builtin_ia32_psrlqi128(tmp_V2LLi, tmp_i);
+  tmp_V8s = __builtin_ia32_psrawi128(tmp_V8s, tmp_i);
+  tmp_V4i = __builtin_ia32_psradi128(tmp_V4i, tmp_i);
+  tmp_V8s = __builtin_ia32_pmaddwd128(tmp_V8s, tmp_V8s);
+  (void) __builtin_ia32_monitor(tmp_vp, tmp_Ui, tmp_Ui);
+  (void) __builtin_ia32_mwait(tmp_Ui, tmp_Ui);
+  tmp_V16c = __builtin_ia32_lddqu(tmp_cCp);
+  tmp_V2LLi = __builtin_ia32_palignr128(tmp_V2LLi, tmp_V2LLi, imm_i);
+  tmp_V1LLi = __builtin_ia32_palignr(tmp_V1LLi, tmp_V1LLi, imm_i);
+  (void) __builtin_ia32_storelv4si(tmp_V2ip, tmp_V2LLi);
+#ifdef USE_SSE4
+  tmp_V16c = __builtin_ia32_pblendvb128(tmp_V16c, tmp_V16c, tmp_V16c);
+  tmp_V8s = __builtin_ia32_pblendw128(tmp_V8s, tmp_V8s, imm_i_0_256);
+  tmp_V2d = __builtin_ia32_blendpd(tmp_V2d, tmp_V2d, imm_i_0_256);
+  tmp_V4f = __builtin_ia32_blendps(tmp_V4f, tmp_V4f, imm_i_0_256);
+  tmp_V2d = __builtin_ia32_blendvpd(tmp_V2d, tmp_V2d, tmp_V2d);
+  tmp_V4f = __builtin_ia32_blendvps(tmp_V4f, tmp_V4f, tmp_V4f);
+  tmp_V8s = __builtin_ia32_packusdw128(tmp_V4i, tmp_V4i);
+  tmp_V16c = __builtin_ia32_pmaxsb128(tmp_V16c, tmp_V16c);
+  tmp_V4i = __builtin_ia32_pmaxsd128(tmp_V4i, tmp_V4i);
+  tmp_V4i = __builtin_ia32_pmaxud128(tmp_V4i, tmp_V4i);
+  tmp_V8s = __builtin_ia32_pmaxuw128(tmp_V8s, tmp_V8s);
+  tmp_V16c = __builtin_ia32_pminsb128(tmp_V16c, tmp_V16c);
+  tmp_V4i = __builtin_ia32_pminsd128(tmp_V4i, tmp_V4i);
+  tmp_V4i = __builtin_ia32_pminud128(tmp_V4i, tmp_V4i);
+  tmp_V8s = __builtin_ia32_pminuw128(tmp_V8s, tmp_V8s);
+  tmp_V4i = __builtin_ia32_pmovsxbd128(tmp_V16c);
+  tmp_V2LLi = __builtin_ia32_pmovsxbq128(tmp_V16c);
+  tmp_V8s = __builtin_ia32_pmovsxbw128(tmp_V16c);
+  tmp_V2LLi = __builtin_ia32_pmovsxdq128(tmp_V4i);
+  tmp_V4i = __builtin_ia32_pmovsxwd128(tmp_V8s);
+  tmp_V2LLi = __builtin_ia32_pmovsxwq128(tmp_V8s);
+  tmp_V4i = __builtin_ia32_pmovzxbd128(tmp_V16c);
+  tmp_V2LLi = __builtin_ia32_pmovzxbq128(tmp_V16c);
+  tmp_V8s = __builtin_ia32_pmovzxbw128(tmp_V16c);
+  tmp_V2LLi = __builtin_ia32_pmovzxdq128(tmp_V4i);
+  tmp_V4i = __builtin_ia32_pmovzxwd128(tmp_V8s);
+  tmp_V2LLi = __builtin_ia32_pmovzxwq128(tmp_V8s);
+  tmp_V2LLi = __builtin_ia32_pmuldq128(tmp_V4i, tmp_V4i);
+  tmp_V4i = __builtin_ia32_pmulld128(tmp_V4i, tmp_V4i);
+  tmp_V4f = __builtin_ia32_roundps(tmp_V4f, imm_i_0_16);
+  tmp_V4f = __builtin_ia32_roundss(tmp_V4f, tmp_V4f, imm_i_0_16);
+  tmp_V2d = __builtin_ia32_roundsd(tmp_V2d, tmp_V2d, imm_i_0_16);
+  tmp_V2d = __builtin_ia32_roundpd(tmp_V2d, imm_i_0_16);
+  tmp_V4f = __builtin_ia32_insertps128(tmp_V4f, tmp_V4f, tmp_i);
+#endif
+}
+
+
diff --git a/test/CodeGen/builtins.c b/test/CodeGen/builtins.c
new file mode 100644
index 0000000..a4424d7
--- /dev/null
+++ b/test/CodeGen/builtins.c
@@ -0,0 +1,165 @@
+// RUN: %clang_cc1 -emit-llvm -o %t %s
+// RUN: not grep __builtin %t
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple x86_64-darwin-apple | FileCheck %s
+
+int printf(const char *, ...);
+
+void p(char *str, int x) {
+  printf("%s: %d\n", str, x);
+}
+void q(char *str, double x) {
+  printf("%s: %f\n", str, x);
+}
+void r(char *str, void *ptr) {
+  printf("%s: %p\n", str, ptr);
+}
+
+int random(void);
+
+int main() {
+  int N = random();
+#define P(n,args) p(#n #args, __builtin_##n args)
+#define Q(n,args) q(#n #args, __builtin_##n args)
+#define R(n,args) r(#n #args, __builtin_##n args)
+#define V(n,args) p(#n #args, (__builtin_##n args, 0))
+  P(types_compatible_p, (int, float));
+  P(choose_expr, (0, 10, 20));
+  P(constant_p, (sizeof(10)));
+  P(expect, (N == 12, 0)); 
+  V(prefetch, (&N));
+  V(prefetch, (&N, 1));
+  V(prefetch, (&N, 1, 0));
+  
+  // Numeric Constants
+
+  Q(huge_val, ());
+  Q(huge_valf, ());
+  Q(huge_vall, ());
+  Q(inf, ());
+  Q(inff, ());
+  Q(infl, ());
+
+  // FIXME:
+  // XXX note funny semantics for the (last) argument
+  //  P(fpclassify, (FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, 1.0));
+  //  P(isinf_sign, (1.0));
+
+  Q(nan, (""));
+  Q(nanf, (""));
+  Q(nanl, (""));
+  Q(nans, (""));
+  Q(nan, ("10"));
+  Q(nanf, ("10"));
+  Q(nanl, ("10"));
+  Q(nans, ("10"));
+
+  P(isgreater, (1., 2.));
+  P(isgreaterequal, (1., 2.));
+  P(isless, (1., 2.));
+  P(islessequal, (1., 2.));
+  P(islessgreater, (1., 2.));
+  P(isunordered, (1., 2.));
+
+  P(isnan, (1.));
+
+  // Bitwise & Numeric Functions
+
+  P(abs, (N));
+
+  P(clz, (N));
+  P(clzl, (N));
+  P(clzll, (N));
+  P(ctz, (N));
+  P(ctzl, (N));
+  P(ctzll, (N));
+  P(ffs, (N));
+  P(ffsl, (N));
+  P(ffsll, (N));
+  P(parity, (N));
+  P(parityl, (N));
+  P(parityll, (N));
+  P(popcount, (N));
+  P(popcountl, (N));
+  P(popcountll, (N));
+  Q(powi, (1.2f, N));
+  Q(powif, (1.2f, N));
+  Q(powil, (1.2f, N));
+
+  // Lib functions
+  int a, b, n = random(); // Avoid optimizing out.
+  char s0[10], s1[] = "Hello";
+  V(strcat, (s0, s1));
+  V(strcmp, (s0, s1));
+  V(strncat, (s0, s1, n));
+  V(strchr, (s0, s1[0]));
+  V(strrchr, (s0, s1[0]));
+  V(strcpy, (s0, s1));
+  V(strncpy, (s0, s1, n));
+  
+  // Object size checking
+  V(__memset_chk, (s0, 0, sizeof s0, n));
+  V(__memcpy_chk, (s0, s1, sizeof s0, n));
+  V(__memmove_chk, (s0, s1, sizeof s0, n));
+  V(__mempcpy_chk, (s0, s1, sizeof s0, n));
+  V(__strncpy_chk, (s0, s1, sizeof s0, n));
+  V(__strcpy_chk, (s0, s1, n));
+  s0[0] = 0;
+  V(__strcat_chk, (s0, s1, n));
+  P(object_size, (s0, 0));
+  P(object_size, (s0, 1));
+  P(object_size, (s0, 2));
+  P(object_size, (s0, 3));
+
+  // Whatever
+
+  P(bswap32, (N));
+  P(bswap64, (N));
+  // FIXME
+  // V(clear_cache, (&N, &N+1));
+  V(trap, ());
+  R(extract_return_addr, (&N));
+  P(signbit, (1.0));
+
+  return 0;
+}
+
+
+
+void foo() {
+ __builtin_strcat(0, 0);
+}
+
+// CHECK: define void @bar(
+void bar() {
+  float f;
+  double d;
+  long double ld;
+
+  // LLVM's hex representation of float constants is really unfortunate;
+  // basically it does a float-to-double "conversion" and then prints the
+  // hex form of that.  That gives us wierd artifacts like exponents
+  // that aren't numerically similar to the original exponent and
+  // significand bit-patterns that are offset by three bits (because
+  // the exponent was expanded from 8 bits to 11).
+  //
+  // 0xAE98 == 1010111010011000
+  // 0x15D3 == 1010111010011
+
+  f = __builtin_huge_valf();     // CHECK: float    0x7FF0000000000000
+  d = __builtin_huge_val();      // CHECK: double   0x7FF0000000000000
+  ld = __builtin_huge_vall();    // CHECK: x86_fp80 0xK7FFF8000000000000000
+  f = __builtin_nanf("");        // CHECK: float    0x7FF8000000000000
+  d = __builtin_nan("");         // CHECK: double   0x7FF8000000000000
+  ld = __builtin_nanl("");       // CHECK: x86_fp80 0xK7FFFC000000000000000
+  f = __builtin_nanf("0xAE98");  // CHECK: float    0x7FF815D300000000
+  d = __builtin_nan("0xAE98");   // CHECK: double   0x7FF800000000AE98
+  ld = __builtin_nanl("0xAE98"); // CHECK: x86_fp80 0xK7FFFC00000000000AE98
+  f = __builtin_nansf("");       // CHECK: float    0x7FF4000000000000
+  d = __builtin_nans("");        // CHECK: double   0x7FF4000000000000
+  ld = __builtin_nansl("");      // CHECK: x86_fp80 0xK7FFFA000000000000000
+  f = __builtin_nansf("0xAE98"); // CHECK: float    0x7FF015D300000000
+  d = __builtin_nans("0xAE98");  // CHECK: double   0x7FF000000000AE98
+  ld = __builtin_nansl("0xAE98");// CHECK: x86_fp80 0xK7FFF800000000000AE98
+
+}
+// CHECK: }
diff --git a/test/CodeGen/builtinshufflevector.c b/test/CodeGen/builtinshufflevector.c
new file mode 100644
index 0000000..f365844
--- /dev/null
+++ b/test/CodeGen/builtinshufflevector.c
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -emit-llvm < %s | grep 'shufflevector' | count 1
+typedef int v4si __attribute__ ((vector_size (16)));
+
+v4si a(v4si x, v4si y) {return __builtin_shufflevector(x, y, 3, 2, 5, 7);}
+
diff --git a/test/CodeGen/c-strings.c b/test/CodeGen/c-strings.c
new file mode 100644
index 0000000..4fbeb7b
--- /dev/null
+++ b/test/CodeGen/c-strings.c
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -emit-llvm -o %t %s
+// RUN: grep "hello" %t | count 3
+// RUN: grep 'c"hello\\00"' %t | count 2
+// RUN: grep 'c"hello\\00\\00\\00"' %t | count 1
+// RUN: grep 'c"ola"' %t | count 1
+
+/* Should be 3 hello string, two global (of different sizes), the rest
+   are shared. */
+
+void f0() {
+  bar("hello");
+}
+
+void f1() {
+  static char *x = "hello";
+  bar(x);
+}
+
+void f2() {
+  static char x[] = "hello";
+  bar(x);
+}
+
+void f3() {
+  static char x[8] = "hello";
+  bar(x);
+}
+
+void f4() {
+  static struct s {
+    char *name;
+  } x = { "hello" };
+  gaz(&x);
+}
+
+char x[3] = "ola";
diff --git a/test/CodeGen/call-knr-indirect.c b/test/CodeGen/call-knr-indirect.c
new file mode 100644
index 0000000..2e923b3
--- /dev/null
+++ b/test/CodeGen/call-knr-indirect.c
@@ -0,0 +1,11 @@
+// RUN: %clang %s -O0 -emit-llvm -S -o - | grep 'call.*rb_define_global_function'
+// This should call rb_define_global_function, not rb_f_chop.
+
+void rb_define_global_function (const char*,void(*)(),int);
+static void rb_f_chop();
+void Init_String() {
+  rb_define_global_function("chop", rb_f_chop, 0);
+}
+static void rb_f_chop() {
+}
+
diff --git a/test/CodeGen/cast-emit.c b/test/CodeGen/cast-emit.c
new file mode 100644
index 0000000..4e33fa3
--- /dev/null
+++ b/test/CodeGen/cast-emit.c
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s
+
+typedef union {
+  int    i;
+  float  f;
+} MyUnion;
+void unionf(MyUnion a);
+void uniontest(float a) {
+  f((MyUnion)1.0f);
+// CHECK: store float 1.000000e+00
+}
+
diff --git a/test/CodeGen/cast.c b/test/CodeGen/cast.c
new file mode 100644
index 0000000..5f340c5
--- /dev/null
+++ b/test/CodeGen/cast.c
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 %s -emit-llvm -o %t
+
+extern void go(const void *p);
+float v[2] = { 0.0, 1.0 };
+void foo(void) { go(v); }
+
diff --git a/test/CodeGen/catch-undef-behavior.c b/test/CodeGen/catch-undef-behavior.c
new file mode 100644
index 0000000..fef1587
--- /dev/null
+++ b/test/CodeGen/catch-undef-behavior.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -fcatch-undefined-behavior -emit-llvm-only %s
+
+// PR6805
+void foo() {
+  union { int i; } u;
+  u.i=1;
+}
diff --git a/test/CodeGen/cfstring.c b/test/CodeGen/cfstring.c
new file mode 100644
index 0000000..1f0977f
--- /dev/null
+++ b/test/CodeGen/cfstring.c
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -emit-llvm %s -o %t
+#define CFSTR __builtin___CFStringMakeConstantString
+
+void f() {
+  CFSTR("Hello, World!");
+}
+
+// rdar://6248329
+void *G = CFSTR("yo joe");
+
+void h() {
+  static void* h = CFSTR("Goodbye, World!");
+}
diff --git a/test/CodeGen/cfstring2.c b/test/CodeGen/cfstring2.c
new file mode 100644
index 0000000..c760f5d
--- /dev/null
+++ b/test/CodeGen/cfstring2.c
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -emit-llvm %s -o %t
+
+typedef const struct __CFString * CFStringRef;
+
+#define CFSTR(x) (CFStringRef) __builtin___CFStringMakeConstantString (x)
+
+void f() {
+  CFSTR("Hello, World!");
+}
+
+// rdar://6151192
+void *G = CFSTR("yo joe");
+
diff --git a/test/CodeGen/cleanup-stack.c b/test/CodeGen/cleanup-stack.c
new file mode 100644
index 0000000..72a1a6c
--- /dev/null
+++ b/test/CodeGen/cleanup-stack.c
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown -O3 -emit-llvm %s -o %t
+// RUN: grep "ret i32 9" %t
+
+struct s0 {
+  int *var;
+  int addend;
+};
+
+static void f0(struct s0 *p) {
+  *p->var += p->addend;
+}
+
+int f1(void) {
+  int var = 0;
+  
+  {
+    struct s0 x __attribute__((cleanup(f0))) = { &var, 2 };  
+    struct s0 y __attribute__((cleanup(f0))) = { &var, 3 };
+    {
+      struct s0 y __attribute__((cleanup(f0))) = { &var, 4 };
+    }
+  }
+
+  return var;
+}
diff --git a/test/CodeGen/complex.c b/test/CodeGen/complex.c
new file mode 100644
index 0000000..ca60610
--- /dev/null
+++ b/test/CodeGen/complex.c
@@ -0,0 +1,91 @@
+// RUN: %clang_cc1 -emit-llvm-only %s
+
+int main(void)
+{
+  double _Complex a = 5;
+  double _Complex b = 42;
+
+  return a * b != b * a;
+}
+
+_Complex double bar(int);
+void test(_Complex double*);
+void takecomplex(_Complex double);
+
+void test2(int c) {
+  _Complex double X;
+  X = bar(1);
+  test(&X);
+  takecomplex(X);
+}
+
+_Complex double g1, g2;
+_Complex float cf;
+double D;
+
+void test3() {
+  g1 = g1 + g2;
+  g1 = g1 - g2;
+  g1 = g1 * g2;
+  g1 = +-~g1;
+
+  double Gr = __real g1;
+
+  cf += D;
+  // FIXME: Currently unsupported!
+  //D += cf;
+  cf /= g1;
+  g1 = g1 + D;
+  g1 = D + g1;
+}
+
+__complex__ int ci1, ci2;
+__complex__ short cs;
+int i;
+void test3int() {
+  ci1 = ci1 + ci2;
+  ci1 = ci1 - ci2;
+  ci1 = ci1 * ci2;
+  ci1 = +-~ci1;
+
+  i = __real ci1;
+
+  cs += i;
+  // FIXME: Currently unsupported!
+  //D += cf;
+  cs /= ci1;
+  ci1 = ci1 + i;
+  ci1 = i + ci1;
+}
+
+void t1() {
+  (__real__ cf) = 4.0;
+}
+
+void t2() {
+  (__imag__ cf) = 4.0;
+}
+
+// PR1960
+void t3() {
+  __complex__ long long v = 2;
+}
+
+// PR3131
+float _Complex t4();
+
+void t5() {
+  float _Complex x = t4();
+}
+
+void t6() {
+  g1++;
+  g1--;
+  ++g1;
+  --g1;
+  ci1++;
+  ci1--;
+  ++ci1;
+  --ci1;
+}
+
diff --git a/test/CodeGen/compound-literal.c b/test/CodeGen/compound-literal.c
new file mode 100644
index 0000000..4b995db
--- /dev/null
+++ b/test/CodeGen/compound-literal.c
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 < %s -emit-llvm
+
+int* a = &(int){1};
+struct s {int a, b, c;} * b = &(struct s) {1, 2, 3};
+// Not working; complex constants are broken
+// _Complex double * x = &(_Complex double){1.0f};
+
+int xxx() {
+int* a = &(int){1};
+struct s {int a, b, c;} * b = &(struct s) {1, 2, 3};
+_Complex double * x = &(_Complex double){1.0f};
+}
diff --git a/test/CodeGen/compound-type.c b/test/CodeGen/compound-type.c
new file mode 100644
index 0000000..63ba694
--- /dev/null
+++ b/test/CodeGen/compound-type.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 < %s -emit-llvm -triple i686-pc-linux-gnu > %t
+// RUN: grep "div i32" %t
+// RUN: grep "shl i32" %t
+
+unsigned char a,b;
+void c(void) {a <<= b;}
+void d(void) {a /= b;}
diff --git a/test/CodeGen/compound.c b/test/CodeGen/compound.c
new file mode 100644
index 0000000..960b2e8
--- /dev/null
+++ b/test/CodeGen/compound.c
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 < %s -emit-llvm
+int A;
+long long B;
+int C;
+int *P;
+void test1() {
+  C = (A /= B);
+
+  P -= 4;
+
+  C = P - (P+10);
+}
+
+short x; 
+void test2(char c) { x += c; }
+
+void foo(char *strbuf) {
+  int stufflen = 4;
+  strbuf += stufflen;
+}
+
+
+// Aggregate cast to void
+union uu { int a;}; void f(union uu p) { (void) p;}
+
diff --git a/test/CodeGen/conditional-gnu-ext.c b/test/CodeGen/conditional-gnu-ext.c
new file mode 100644
index 0000000..f4ac81b
--- /dev/null
+++ b/test/CodeGen/conditional-gnu-ext.c
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -emit-llvm %s -o %t
+// PR1824
+
+int foo(int x, short y) {
+  return x ?: y;
+}
+
+// rdar://6586493
+float test(float x, int Y) {
+  return Y != 0 ? : x;
+}
+
diff --git a/test/CodeGen/conditional.c b/test/CodeGen/conditional.c
new file mode 100644
index 0000000..d079aaf
--- /dev/null
+++ b/test/CodeGen/conditional.c
@@ -0,0 +1,49 @@
+// RUN: %clang_cc1 -emit-llvm %s -o %t
+
+float test1(int cond, float a, float b) {
+  return cond ? a : b;
+}
+
+double test2(int cond, float a, double b) {
+  return cond ? a : b;
+}
+
+void f();
+
+void test3(){
+   1 ? f() : (void)0;
+}
+
+void test4() {
+  int i; short j;
+  float* k = 1 ? &i : &j;
+}
+
+void test5() {
+  const int* cip;
+  void* vp;
+  cip = 0 ? vp : cip;
+}
+
+void test6();
+void test7(int);
+void* test8() {return 1 ? test6 : test7;}
+
+
+void _efree(void *ptr);
+
+void _php_stream_free3() {
+  (1 ? free(0) : _efree(0));
+}
+
+void _php_stream_free4() {
+  1 ? _efree(0) : free(0);
+}
+
+// PR5526
+struct test9 { int a; };
+void* test9spare();
+void test9(struct test9 *p) {
+  p ? p : test9spare();
+}
+
diff --git a/test/CodeGen/const-arithmetic.c b/test/CodeGen/const-arithmetic.c
new file mode 100644
index 0000000..e12b4f6
--- /dev/null
+++ b/test/CodeGen/const-arithmetic.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s
+
+// CHECK: @g1 = global [2 x i8*] [i8* getelementptr (i8* getelementptr inbounds ([0 x %struct.anon]* @g0, i32 0, i32 0, i32 0), i64 -2), i8* getelementptr (i8* getelementptr inbounds ([0 x %struct.anon]* @g0, i32 0, i32 0, i32 0), i64 -46)], align 8 ; <[2 x i8*]*> [#uses=0]
+// CHECK: @g2 = global [2 x i8*] [i8* getelementptr (i8* getelementptr inbounds ([0 x %struct.anon]* @g0, i32 0, i32 0, i32 0), i64 -2), i8* getelementptr (i8* getelementptr inbounds ([0 x %struct.anon]* @g0, i32 0, i32 0, i32 0), i64 -46)], align 8 ; <[2 x i8*]*> [#uses=0]
+
+extern struct { unsigned char a, b; } g0[];
+void *g1[] = {g0 + -1, g0 + -23 };
+void *g2[] = {g0 - 1, g0 - 23 };
diff --git a/test/CodeGen/const-init.c b/test/CodeGen/const-init.c
new file mode 100644
index 0000000..c7a53be
--- /dev/null
+++ b/test/CodeGen/const-init.c
@@ -0,0 +1,125 @@
+// RUN: %clang_cc1 -triple i386-pc-linux-gnu -ffreestanding -verify -emit-llvm -o - %s | FileCheck %s
+
+#include <stdint.h>
+
+// Brace-enclosed string array initializers
+char a[] = { "asdf" };
+
+// Double-implicit-conversions of array/functions (not legal C, but
+// clang accepts it for gcc compat).
+intptr_t b = a; // expected-warning {{incompatible pointer to integer conversion}}
+int c();
+void *d = c;
+intptr_t e = c; // expected-warning {{incompatible pointer to integer conversion}}
+
+int f, *g = __extension__ &f, *h = (1 != 1) ? &f : &f;
+
+union s2 {
+  struct {
+    struct { } *f0;
+  } f0;
+};
+
+int g0 = (int)(&(((union s2 *) 0)->f0.f0) - 0);
+
+// CHECK: @g1x = global {{%.}} { double 1.000000e+00{{[0]*}}, double 0.000000e+00{{[0]*}} }
+_Complex double g1x = 1.0f;
+// CHECK: @g1y = global {{%.}} { double 0.000000e+00{{[0]*}}, double 1.000000e+00{{[0]*}} }
+_Complex double g1y = 1.0fi;
+// CHECK: @g1 = global {{%.}} { i8 1, i8 10 }
+_Complex char g1 = (char) 1 + (char) 10 * 1i;
+// CHECK: @g2 = global %2 { i32 1, i32 10 }
+_Complex int g2 = 1 + 10i;
+// CHECK: @g3 = global {{%.}} { float 1.000000e+00{{[0]*}}, float 1.000000e+0{{[0]*}}1 }
+_Complex float g3 = 1.0 + 10.0i;
+// CHECK: @g4 = global {{%.}} { double 1.000000e+00{{[0]*}}, double 1.000000e+0{{[0]*}}1 }
+_Complex double g4 = 1.0 + 10.0i;
+// CHECK: @g5 = global %2 zeroinitializer
+_Complex int g5 = (2 + 3i) == (5 + 7i);
+// CHECK: @g6 = global {{%.}} { double -1.100000e+0{{[0]*}}1, double 2.900000e+0{{[0]*}}1 }
+_Complex double g6 = (2.0 + 3.0i) * (5.0 + 7.0i);
+// CHECK: @g7 = global i32 1
+int g7 = (2 + 3i) * (5 + 7i) == (-11 + 29i);
+// CHECK: @g8 = global i32 1
+int g8 = (2.0 + 3.0i) * (5.0 + 7.0i) == (-11.0 + 29.0i);
+// CHECK: @g9 = global i32 0
+int g9 = (2 + 3i) * (5 + 7i) != (-11 + 29i);
+// CHECK: @g10 = global i32 0
+int g10 = (2.0 + 3.0i) * (5.0 + 7.0i) != (-11.0 + 29.0i);
+
+// PR5108
+// CHECK: @gv1 = global %4 <{ i32 0, i8 7 }>, align 1
+struct {
+  unsigned long a;
+  unsigned long b:3;
+} __attribute__((__packed__)) gv1  = { .a = 0x0, .b = 7,  };
+
+// PR5118
+// CHECK: @gv2 = global %5 <{ i8 1, i8* null }>, align 1 
+struct {
+  unsigned char a;
+  char *b;
+} __attribute__((__packed__)) gv2 = { 1, (void*)0 };
+
+// Global references
+// CHECK: @g11.l0 = internal global i32 ptrtoint (i32 ()* @g11 to i32)
+long g11() { 
+  static long l0 = (long) g11;
+  return l0; 
+}
+
+// CHECK: @g12 = global i32 ptrtoint (i8* @g12_tmp to i32)
+static char g12_tmp;
+long g12 = (long) &g12_tmp;
+
+// CHECK: @g13 = global [1 x %struct.g13_s0] [%struct.g13_s0 { i32 ptrtoint (i8* @g12_tmp to i32) }]
+struct g13_s0 {
+   long a;
+};
+struct g13_s0 g13[] = {
+   { (long) &g12_tmp }
+};
+
+// CHECK: @g14 = global i8* inttoptr (i64 100 to i8*)
+void *g14 = (void*) 100;
+
+// CHECK: @g15 = global i32 -1
+int g15 = (int) (char) ((void*) 0 + 255);
+
+// CHECK: @g16 = global i64 4294967295
+long long g16 = (long long) ((void*) 0xFFFFFFFF);
+
+// CHECK: @g17 = global i32* @g15
+int *g17 = (int *) ((long) &g15);
+
+// CHECK: @g18.p = internal global [1 x i32*] [i32* @g19]
+void g18(void) {
+  extern int g19;
+  static int *p[] = { &g19 };
+}
+
+// CHECK: @g20.l0 = internal global %struct.g20_s1 { %struct.g20_s0* null, %struct.g20_s0** getelementptr inbounds (%struct.g20_s1* @g20.l0, i32 0, i32 0) }
+struct g20_s0;
+struct g20_s1 {
+  struct g20_s0 *f0, **f1;
+};
+void *g20(void) {
+  static struct g20_s1 l0 = { ((void*) 0), &l0.f0 };
+  return l0.f1;
+}
+
+// PR4108
+struct g21 {int g21;};
+const struct g21 g21 = (struct g21){1};
+
+// PR5474
+struct g22 {int x;} __attribute((packed));
+struct g23 {char a; short b; char c; struct g22 d;};
+struct g23 g24 = {1,2,3,4};
+
+// CHECK: @__func__.g25 = private constant [4 x i8] c"g25\00"
+// CHECK: @g25.g26 = internal global i8* getelementptr inbounds ([4 x i8]* @__func__.g25, i32 0, i32 0)
+int g25() {
+  static const char *g26 = __func__;
+  return *g26;
+}
diff --git a/test/CodeGen/const-label-addr.c b/test/CodeGen/const-label-addr.c
new file mode 100644
index 0000000..9d99f88
--- /dev/null
+++ b/test/CodeGen/const-label-addr.c
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 %s -emit-llvm -o %t
+int a() {
+A:;static void* a = &&A;
+}
diff --git a/test/CodeGen/constant-comparison.c b/test/CodeGen/constant-comparison.c
new file mode 100644
index 0000000..371cb17
--- /dev/null
+++ b/test/CodeGen/constant-comparison.c
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - 2>&1 | not grep warning
+// RUN: %clang_cc1 -emit-llvm %s -o - | grep @b | count 1
+
+int a, b;
+int *c1 = 1 < 2 ? &a : &b;
+int *c2 = 3 != 3LL ? &b : &a;
+int *c3 = !(3 <= 4.0) ? &b : &a;
+int *c4 = &a - (6 * 5 > 30);
+int *c5 = &a + (6 * 5 >= 30);
+int c6 = 44 < 33;
+
+
diff --git a/test/CodeGen/constructor-attribute.c b/test/CodeGen/constructor-attribute.c
new file mode 100644
index 0000000..a1f0e60
--- /dev/null
+++ b/test/CodeGen/constructor-attribute.c
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -emit-llvm -o %t %s
+// RUN: grep -e "global_ctors.*@A" %t
+// RUN: grep -e "global_dtors.*@B" %t
+// RUN: grep -e "global_ctors.*@C" %t
+// RUN: grep -e "global_dtors.*@D" %t
+
+int printf(const char *, ...);
+
+void A() __attribute__((constructor));
+void B() __attribute__((destructor));
+
+void A() {
+  printf("A\n");
+}
+
+void B() {
+  printf("B\n");
+}
+
+static void C() __attribute__((constructor));
+
+static void D() __attribute__((destructor));
+
+static int foo() {
+  return 10;
+}
+
+static void C() {
+  printf("A: %d\n", foo());
+}
+
+static void D() {
+  printf("B\n");
+}
+
+int main() {
+  return 0;
+}
diff --git a/test/CodeGen/cxx-condition.cpp b/test/CodeGen/cxx-condition.cpp
new file mode 100644
index 0000000..5aa0c5e
--- /dev/null
+++ b/test/CodeGen/cxx-condition.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -emit-llvm %s -o %t
+
+void f() {
+  int a;
+  if (int x=a) ++a; else a=x;
+  while (int x=a) ++a;
+  for (; int x=a; --a) ;
+  switch (int x=0) { }
+}
diff --git a/test/CodeGen/cxx-default-arg.cpp b/test/CodeGen/cxx-default-arg.cpp
new file mode 100644
index 0000000..25b7c10
--- /dev/null
+++ b/test/CodeGen/cxx-default-arg.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -emit-llvm %s -o %t
+
+// Note: define CLANG_GENERATE_KNOWN_GOOD and compile to generate code
+// that makes all of the defaulted arguments explicit. The resulting
+// byte code should be identical to the compilation without
+// CLANG_GENERATE_KNOWN_GOOD.
+#ifdef CLANG_GENERATE_KNOWN_GOOD
+#  define DEFARG(...) __VA_ARGS__
+#else
+#  define DEFARG(...)
+#endif
+
+extern int x;
+struct S { float x; float y; } s;
+double _Complex c;
+
+void f(int i = 0, int j = 1, int k = x, struct S t = s, double _Complex d = c);
+
+void g() {
+  f(0, 1, x, s DEFARG(, c));
+  f(0, 1, x DEFARG(, s, c));
+  f(0, 1 DEFARG(, x, s, c));
+  f(0 DEFARG(, 1, x, s, c));
+  f(DEFARG(0, 1, x, s, c));
+}
diff --git a/test/CodeGen/cxx-value-init.cpp b/test/CodeGen/cxx-value-init.cpp
new file mode 100644
index 0000000..6e4cc03
--- /dev/null
+++ b/test/CodeGen/cxx-value-init.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -emit-llvm %s -o %t
+
+enum E {};
+int v1 = E();
+float v2 = float();
+
+void f() {
+  int v3 = int();
+  _Complex int v4 = typeof(_Complex int)();
+  _Complex float v5 = typeof(_Complex float)();
+}
diff --git a/test/CodeGen/darwin-string-literals.c b/test/CodeGen/darwin-string-literals.c
new file mode 100644
index 0000000..8734295
--- /dev/null
+++ b/test/CodeGen/darwin-string-literals.c
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -emit-llvm %s -o - | FileCheck -check-prefix LSB %s
+
+// CHECK-LSB: @.str = private constant [8 x i8] c"string0\00"
+// CHECK-LSB: @.str1 = private constant [8 x i8] c"string1\00"
+// CHECK-LSB: @.str2 = internal constant [36 x i8] c"h\00e\00l\00l\00o\00 \00\92! \00\03& \00\90! \00w\00o\00r\00l\00d\00\00\00", align 2
+
+// RUN: %clang_cc1 -triple powerpc-apple-darwin9 -emit-llvm %s -o - | FileCheck -check-prefix MSB %s
+
+// CHECK-MSB: @.str = private constant [8 x i8] c"string0\00"
+// CHECK-MSB: @.str1 = private constant [8 x i8] c"string1\00"
+// CHECK-MSB: @.str2 = internal constant [36 x i8] c"\00h\00e\00l\00l\00o\00 !\92\00 &\03\00 !\90\00 \00w\00o\00r\00l\00d\00\00", align 2
+
+const char *g0 = "string0";
+const void *g1 = __builtin___CFStringMakeConstantString("string1");
+const void *g2 = __builtin___CFStringMakeConstantString("hello \u2192 \u2603 \u2190 world");
+const void *g3 = __builtin___CFStringMakeConstantString("test™");
diff --git a/test/CodeGen/debug-info-crash.c b/test/CodeGen/debug-info-crash.c
new file mode 100644
index 0000000..e0c9dd4
--- /dev/null
+++ b/test/CodeGen/debug-info-crash.c
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin10 -fblocks -g -S %s -o -
+
+// rdar://7590323
+typedef struct dispatch_queue_s *dispatch_queue_t;
+__attribute__((visibility("default")))
+extern struct dispatch_queue_s _dispatch_main_q;
+typedef struct dispatch_item_s *dispatch_item_t;
+typedef void (^dispatch_legacy_block_t)(dispatch_item_t);
+dispatch_item_t LEGACY_dispatch_call(dispatch_queue_t dq,
+                                     dispatch_legacy_block_t dispatch_block,
+                                     dispatch_legacy_block_t callback_block) {
+  dispatch_queue_t lq = _dispatch_queue_get_current() ?: (&_dispatch_main_q);
+  dispatch_async(dq, ^{
+      if (callback_block) {
+        dispatch_async(lq, ^{
+          }
+          );
+      }
+    }
+    );
+}
diff --git a/test/CodeGen/debug-info.c b/test/CodeGen/debug-info.c
new file mode 100644
index 0000000..a84d0b2
--- /dev/null
+++ b/test/CodeGen/debug-info.c
@@ -0,0 +1,49 @@
+// RUN: %clang_cc1 -o %t -emit-llvm -g %s
+// RUN: FileCheck --input-file=%t %s
+
+// PR3023
+void convert(void) {
+  struct { typeof(0) f0; } v0;
+}
+
+
+// PR2784
+struct OPAQUE;
+typedef struct OPAQUE *PTR;
+PTR p;
+
+
+// PR2950
+struct s0;
+struct s0 { struct s0 *p; } g0;
+
+struct s0 *f0(struct s0 *a0) {
+  return a0->p;
+}
+
+
+// PR3134
+char xpto[];
+
+
+// PR3427
+struct foo {
+  int a;
+  void *ptrs[];
+};
+struct foo bar;
+
+
+// PR4143
+struct foo2 {
+  enum bar *bar;
+};
+
+struct foo2 foo2;
+
+
+// Radar 7325611
+// CHECK: "barfoo"
+typedef int barfoo;
+barfoo foo() {
+}
diff --git a/test/CodeGen/decl.c b/test/CodeGen/decl.c
new file mode 100644
index 0000000..7ffb700
--- /dev/null
+++ b/test/CodeGen/decl.c
@@ -0,0 +1,91 @@
+// RUN: %clang_cc1 -w -emit-llvm < %s | FileCheck %s
+
+// CHECK: @test1.x = internal constant [12 x i32] [i32 1
+// CHECK: @test2.x = internal constant [13 x i32] [i32 1,
+// CHECK: @test5w = global %0 { i32 2, [4 x i8] undef }
+// CHECK: @test5y = global %union.test5u { double 7.300000e+0{{[0]*}}1 }
+
+// CHECK: @test6.x = internal constant %struct.SelectDest { i8 1, i8 2, i32 3, i32 0 }
+
+// CHECK: @test7 = global [2 x %struct.test7s] [%struct.test7s { i32 1, i32 2 }, %struct.test7s { i32 4, i32 0 }]
+
+void test1() {
+  // This should codegen as a "@test1.x" global.
+  const int x[] = { 1, 2, 3, 4, 6, 8, 9, 10, 123, 231, 123,23 };
+  foo(x);
+
+// CHECK: @test1()
+// CHECK: {{call.*@foo.*@test1.x}}
+}
+
+
+// rdar://7346691
+void test2() {
+  // This should codegen as a "@test2.x" global + memcpy.
+  int x[] = { 1, 2, 3, 4, 6, 8, 9, 10, 123, 231, 123,23, 24 };
+  foo(x);
+  
+  // CHECK: @test2()
+  // CHECK: %x = alloca [13 x i32]
+  // CHECK: call void @llvm.memcpy
+  // CHECK: call{{.*}}@foo{{.*}}i32* %
+}
+
+
+void test3() {
+  // This should codegen as a memset.
+  int x[100] = { 0 };
+  foo(x);
+  
+  // CHECK: @test3()
+  // CHECK: %x = alloca [100 x i32]
+  // CHECK: call void @llvm.memset
+}
+
+void test4(void) {
+  char a[10] = "asdf";
+  char b[10] = { "asdf" };
+  // CHECK: @test4()
+  // CHECK: %a = alloca [10 x i8]
+  // CHECK: %b = alloca [10 x i8]
+  // CHECK: call void @llvm.memcpy
+  // CHECK: call void @llvm.memcpy
+}
+
+
+union test5u { int i; double d; };
+
+void test5() {
+  union test5u ola = (union test5u) 351;
+  union test5u olb = (union test5u) 1.0;
+}
+
+union test5u test5w = (union test5u)2;
+union test5u test5y = (union test5u)73.0;
+
+
+
+// PR6660 - sqlite miscompile
+struct SelectDest {
+  unsigned char eDest;
+  unsigned char affinity;
+  int iParm;
+  int iMem;
+};
+
+void test6() {
+  struct SelectDest x = {1, 2, 3};
+  test6f(&x);
+}
+
+// rdar://7657600
+struct test7s { int a; int b; } test7[] = {
+  {1, 2},
+  {4},
+};
+
+// rdar://7872531
+#pragma pack(push, 2)
+struct test8s { int f0; char f1; } test8g = {};
+
+
diff --git a/test/CodeGen/designated-initializers.c b/test/CodeGen/designated-initializers.c
new file mode 100644
index 0000000..49f57ad
--- /dev/null
+++ b/test/CodeGen/designated-initializers.c
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown %s -emit-llvm -o - | FileCheck %s
+
+struct foo {
+    void *a;
+    int b;
+};
+
+// CHECK: @u = global %union.anon zeroinitializer
+union { int i; float f; } u = { };
+
+// CHECK: @u2 = global %0 { i32 0, [4 x i8] undef }
+union { int i; double f; } u2 = { };
+
+// CHECK: @u3 = global %1 zeroinitializer
+union { double f; int i; } u3 = { };
+
+// CHECK: @b = global [2 x i32] [i32 0, i32 22]
+int b[2] = {
+  [1] = 22
+};
+
+int main(int argc, char **argv)
+{
+  // CHECK: internal global %struct.foo { i8* null, i32 1024 }
+  static struct foo foo = {
+    .b = 1024,
+  };
+
+  // CHECK: bitcast %union.anon* %u2
+  // CHECK: call void @llvm.memset
+   union { int i; float f; } u2 = { };
+
+  // CHECK-NOT: call void @llvm.memset
+  union { int i; float f; } u3;
+
+  // CHECK: ret i32
+}
diff --git a/test/CodeGen/dllimport-dllexport.c b/test/CodeGen/dllimport-dllexport.c
new file mode 100644
index 0000000..c187503
--- /dev/null
+++ b/test/CodeGen/dllimport-dllexport.c
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -triple i386-mingw32 -emit-llvm < %s | FileCheck %s
+
+void __attribute__((dllimport)) foo1();
+void __attribute__((dllexport)) foo1(){}
+// CHECK: define dllexport void @foo1
+void __attribute__((dllexport)) foo2();
+
+// PR6269
+__declspec(dllimport) void foo3();
+__declspec(dllexport) void foo3(){}
+// CHECK: define dllexport void @foo3
+__declspec(dllexport) void foo4();
diff --git a/test/CodeGen/dostmt.c b/test/CodeGen/dostmt.c
new file mode 100644
index 0000000..1a2e02a
--- /dev/null
+++ b/test/CodeGen/dostmt.c
@@ -0,0 +1,70 @@
+// RUN: %clang_cc1 %s -emit-llvm -o -
+
+int bar();
+int test0() {
+  int i;
+  i = 1 + 2;
+  do {
+    i = bar();
+    i = bar();
+  } while(0);
+  return i;
+}
+
+
+int test1() {
+  int i;
+  i = 1 + 2;
+  do {
+    i = bar();
+    if (i == 42)
+      break;
+    i = bar();
+  } while(1);
+  return i;
+}
+
+
+int test2() {
+  int i;
+  i = 1 + 2;
+  do {
+    i = bar();
+    if (i == 42)
+      continue;
+    i = bar();
+  } while(1);
+  return i;
+}
+
+
+int test3() {
+  int i;
+  i = 1 + 2;
+  do {
+    i = bar();
+    if (i == 42)
+      break;
+  } while(0);
+  return i;
+}
+
+
+int test4() {
+  int i;
+  i = 1 + 2;
+  do {
+    i = bar();
+    if (i == 42)
+      continue;
+  } while(0);
+  return i;
+}
+
+// rdar://6103124
+void test5() {
+  do { break; } while(0);
+}
+
+ 
+
diff --git a/test/CodeGen/emit-all-decls.c b/test/CodeGen/emit-all-decls.c
new file mode 100644
index 0000000..deeb573a
--- /dev/null
+++ b/test/CodeGen/emit-all-decls.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -emit-llvm -o %t %s
+// RUN: not grep "@foo" %t
+// RUN: %clang_cc1 -femit-all-decls -emit-llvm -o %t %s
+// RUN: grep "@foo" %t
+
+static void foo() {
+  
+}
diff --git a/test/CodeGen/empty-union-init.c b/test/CodeGen/empty-union-init.c
new file mode 100644
index 0000000..a58354b
--- /dev/null
+++ b/test/CodeGen/empty-union-init.c
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -emit-llvm < %s -o -
+// PR2419
+
+struct Mem {
+        union {
+        } u;
+};
+
+struct Mem *columnMem(){
+        static const struct Mem nullMem = { {} };
+}
+
+
diff --git a/test/CodeGen/enum.c b/test/CodeGen/enum.c
new file mode 100644
index 0000000..87b0e1e
--- /dev/null
+++ b/test/CodeGen/enum.c
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown %s -O3 -emit-llvm -o - | grep 'ret i32 6'
+// RUN: %clang_cc1 -triple i386-unknown-unknown -x c++ %s -O3 -emit-llvm -o - | grep 'ret i32 7'
+
+static enum { foo, bar = 1U } z;
+
+int main (void)
+{
+  int r = 0;
+
+  if (bar - 2 < 0)
+    r += 4;
+  if (foo - 1 < 0)
+    r += 2;
+  if (z - 1 < 0)
+    r++;
+
+  return r;
+}
+
diff --git a/test/CodeGen/exprs.c b/test/CodeGen/exprs.c
new file mode 100644
index 0000000..d82cbf4
--- /dev/null
+++ b/test/CodeGen/exprs.c
@@ -0,0 +1,121 @@
+// RUN: %clang_cc1 %s -emit-llvm -o -
+
+// PR1895
+// sizeof function
+int zxcv(void);
+int x=sizeof(zxcv);
+int y=__alignof__(zxcv);
+
+
+void *test(int *i) {
+ short a = 1;
+ i += a;
+ i + a;
+ a + i;
+}
+
+_Bool test2b; 
+int test2() { if (test2b); return 0; }
+
+// PR1921
+int test3() {
+  const unsigned char *bp;
+  bp -= (short)1;
+}
+
+// PR2080 - sizeof void
+int t1 = sizeof(void);
+int t2 = __alignof__(void);
+void test4() {
+  t1 = sizeof(void);
+  t2 = __alignof__(void);
+  
+  t1 = sizeof(test4());
+  t2 = __alignof__(test4());
+}
+
+// 'const float' promotes to double in varargs.
+int test5(const float x, float float_number) {
+  return __builtin_isless(x, float_number);
+}
+
+// this one shouldn't fold
+int ola() {
+  int a=2;
+  if ((0, (int)a) & 2) { return 1; }
+  return 2;
+}
+
+// this one shouldn't fold as well
+void eMaisUma() {
+  double t[1];
+  if (*t)
+    return;
+}
+
+// rdar://6520707
+void f0(void (*fp)(void), void (*fp2)(void)) {
+  int x = fp - fp2;
+}
+
+// noop casts as lvalues.
+struct X {
+  int Y;
+};
+struct X foo();
+int bar() {
+  return ((struct X)foo()).Y + 1;
+}
+
+// PR3809: INC/DEC of function pointers.
+void f2(void);
+unsigned f1(void) {
+  void (*fp)(void) = f2;
+  
+  ++fp;
+  fp++;
+  --fp;
+  fp--;
+  return (unsigned) fp;
+}  
+
+union f3_x {int x; float y;};
+int f3() {return ((union f3_x)2).x;}
+
+union f4_y {int x; _Complex float y;};
+_Complex float f4() {return ((union f4_y)(_Complex float)2.0).y;}
+
+struct f5_a { int a; } f5_a;
+union f5_z {int x; struct f5_a y;};
+struct f5_a f5() {return ((union f5_z)f5_a).y;}
+
+// ?: in "lvalue"
+struct s6 { int f0; };
+int f6(int a0, struct s6 a1, struct s6 a2) {
+  return (a0 ? a1 : a2).f0;
+}
+
+// PR4026
+void f7() {
+  __func__;
+}
+
+// PR4067
+int f8() {
+  return ({ foo(); }).Y;
+}
+
+// rdar://6880558
+struct S;
+struct C {
+  int i;
+  struct S *tab[];
+};
+struct S { struct C c; };
+void f9(struct S *x) {
+  foo(((void)1, x->c).tab[0]);
+}
+
+void f10() {
+  __builtin_sin(0);
+}
diff --git a/test/CodeGen/ext-vector-shuffle.c b/test/CodeGen/ext-vector-shuffle.c
new file mode 100644
index 0000000..1d147a3
--- /dev/null
+++ b/test/CodeGen/ext-vector-shuffle.c
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 %s -x cl -emit-llvm -o - | not grep 'extractelement'
+// RUN: %clang_cc1 %s -x cl -emit-llvm -o - | not grep 'insertelement'
+// RUN: %clang_cc1 %s -x cl -emit-llvm -o - | grep 'shufflevector'
+
+typedef __attribute__(( ext_vector_type(2) )) float float2;
+typedef __attribute__(( ext_vector_type(4) )) float float4;
+
+float2 test1(float4 V) {
+  return V.xy + V.wz;
+}
+
+float4 test2(float4 V) {
+  float2 W = V.ww;
+  return W.xyxy + W.yxyx;
+}
+
+float4 test3(float4 V1, float4 V2) { return (float4)(V1.zw, V2.xy); }
diff --git a/test/CodeGen/ext-vector.c b/test/CodeGen/ext-vector.c
new file mode 100644
index 0000000..daa1826
--- /dev/null
+++ b/test/CodeGen/ext-vector.c
@@ -0,0 +1,162 @@
+// RUN: %clang_cc1 -emit-llvm-only %s
+
+typedef __attribute__(( ext_vector_type(4) )) float float4;
+typedef __attribute__(( ext_vector_type(2) )) float float2;
+typedef __attribute__(( ext_vector_type(4) )) int int4;
+
+float4 foo = (float4){ 1.0, 2.0, 3.0, 4.0 };
+
+const float4 bar = (float4){ 1.0, 2.0, 3.0, __builtin_inff() };
+
+float4 test1(float4 V) {
+  return V.wzyx+V;
+}
+
+float2 vec2, vec2_2;
+float4 vec4, vec4_2;
+float f;
+
+void test2() {
+    vec2 = vec4.xy;  // shorten
+    f = vec2.x;      // extract elt
+    vec4 = vec4.yyyy;  // splat
+    
+    vec2.x = f;      // insert one.
+    vec2.yx = vec2; // reverse
+}
+
+void test3(float4 *out) {
+  *out = ((float4) {1.0f, 2.0f, 3.0f, 4.0f });
+}
+
+void test4(float4 *out) {
+  float a = 1.0f;
+  float b = 2.0f;
+  float c = 3.0f;
+  float d = 4.0f;
+  *out = ((float4) {a,b,c,d});
+}
+
+void test5(float4 *out) {
+  float a;
+  float4 b;
+  
+  a = 1.0f;
+  b = a;
+  b = b * 5.0f;
+  b = 5.0f * b;
+  b *= a;
+  
+  *out = b;
+}
+
+void test6(float4 *ap, float4 *bp, float c) {
+  float4 a = *ap;
+  float4 b = *bp;
+  
+  a = a + b;
+  a = a - b;
+  a = a * b;
+  a = a / b;
+  
+  a = a + c;
+  a = a - c;
+  a = a * c;
+  a = a / c;
+
+  a += b;
+  a -= b;
+  a *= b;
+  a /= b;
+  
+  a += c;
+  a -= c;
+  a *= c;
+  a /= c;
+
+  // Vector comparisons can sometimes crash the x86 backend: rdar://6326239,
+  // reject them until the implementation is stable.
+#if 0
+  int4 cmp;
+  cmp = a < b;
+  cmp = a <= b;
+  cmp = a < b;
+  cmp = a >= b;
+  cmp = a == b;
+  cmp = a != b;
+#endif
+}
+
+void test7(int4 *ap, int4 *bp, int c) {
+  int4 a = *ap;
+  int4 b = *bp;
+  
+  a = a + b;
+  a = a - b;
+  a = a * b;
+  a = a / b;
+  a = a % b;
+  
+  a = a + c;
+  a = a - c;
+  a = a * c;
+  a = a / c;
+  a = a % c;
+
+  a += b;
+  a -= b;
+  a *= b;
+  a /= b;
+  a %= b;
+  
+  a += c;
+  a -= c;
+  a *= c;
+  a /= c;
+  a %= c;
+
+  // Vector comparisons.
+  int4 cmp;
+  cmp = a < b;
+  cmp = a <= b;
+  cmp = a < b;
+  cmp = a >= b;
+  cmp = a == b;
+  cmp = a != b;
+}
+
+void test8(float4 *ap, float4 *bp, int c) {
+  float4 a = *ap;
+  float4 b = *bp;
+
+  // Vector comparisons.
+  int4 cmp;
+  cmp = a < b;
+  cmp = a <= b;
+  cmp = a < b;
+  cmp = a >= b;
+  cmp = a == b;
+  cmp = a != b;
+}
+
+int test9(int4 V) {
+  return V.xy.x;
+}
+
+int test10(int4 V) {
+  return (V+V).x;
+}
+
+int4 test11a();
+int test11() {
+  return test11a().x;
+}
+
+int4 test12(int4 V) {
+  V.xyz = V.zyx;
+  return V;
+}
+
+int4 test13(int4 *V) {
+  return V->zyxw;
+}
diff --git a/test/CodeGen/extern-block-var.c b/test/CodeGen/extern-block-var.c
new file mode 100644
index 0000000..329f109
--- /dev/null
+++ b/test/CodeGen/extern-block-var.c
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 %s -emit-llvm -o %t
+
+int f() {
+  extern int a;
+  return a;
+}
diff --git a/test/CodeGen/extern-inline.c b/test/CodeGen/extern-inline.c
new file mode 100644
index 0000000..5dd9bfd
--- /dev/null
+++ b/test/CodeGen/extern-inline.c
@@ -0,0 +1,25 @@
+// RUN: %clang -S -emit-llvm -std=gnu89 -o - %s | FileCheck %s
+// PR5253
+
+// If an extern inline function is redefined, functions should call the
+// redefinition.
+extern inline int f(int a) {return a;}
+int g(void) {return f(0);}
+// CHECK: call i32 @f
+int f(int b) {return 1+b;}
+// CHECK: load i32* %{{.*}}
+// CHECK: add nsw i32 1, %{{.*}}
+int h(void) {return f(1);}
+// CHECK: call i32 @f
+
+// It shouldn't matter if the function was redefined static.
+extern inline int f2(int a, int b) {return a+b;}
+int g2(void) {return f2(0,1);}
+// CHECK: call i32 @f2
+static int f2(int a, int b) {return a*b;}
+// CHECK: load i32* %{{.*}}
+// CHECK: load i32* %{{.*}}
+// CHECK: mul i32 %{{.*}}, %{{.*}}
+int h2(void) {return f2(1,2);}
+// CHECK: call i32 @f2
+
diff --git a/test/CodeGen/flexible-array-init.c b/test/CodeGen/flexible-array-init.c
new file mode 100644
index 0000000..3632350
--- /dev/null
+++ b/test/CodeGen/flexible-array-init.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -o - %s | FileCheck %s
+
+struct { int x; int y[]; } a = { 1, 7, 11 };
+// CHECK: @a = global %0 { i32 1, [2 x i32] [i32 7, i32 11] }
+
+struct { int x; int y[]; } b = { 1, { 13, 15 } };
+// CHECK: @b = global %0 { i32 1, [2 x i32] [i32 13, i32 15] }
diff --git a/test/CodeGen/func-decl-cleanup.c b/test/CodeGen/func-decl-cleanup.c
new file mode 100644
index 0000000..0af8b69
--- /dev/null
+++ b/test/CodeGen/func-decl-cleanup.c
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 %s -emit-llvm -o -
+
+
+// PR2360
+typedef void fn_t();
+
+fn_t a,b;
+
+void b()
+{
+}
+
diff --git a/test/CodeGen/func-ptr-cast-decl.c b/test/CodeGen/func-ptr-cast-decl.c
new file mode 100644
index 0000000..e630796
--- /dev/null
+++ b/test/CodeGen/func-ptr-cast-decl.c
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -emit-llvm-only %s -verify
+// PR5882
+
+int q_sk_num(void *a);
+typedef int (*fptr)(double);
+void a() { ((fptr)q_sk_num)(0); }
diff --git a/test/CodeGen/func-return-member.c b/test/CodeGen/func-return-member.c
new file mode 100644
index 0000000..8c55a96
--- /dev/null
+++ b/test/CodeGen/func-return-member.c
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+
+struct frk { float _Complex c; int x; };
+struct faz { struct frk f; };
+struct fuz { struct faz f; };
+
+extern struct fuz foo(void);
+
+int X;
+struct frk F;
+float _Complex C;
+
+// CHECK: define void @bar
+void bar(void) {
+  X = foo().f.f.x;
+}
+
+// CHECK: define void @bun
+void bun(void) {
+  F = foo().f.f;
+}
+
+// CHECK: define void @ban
+void ban(void) {
+  C = foo().f.f.c;
+}
diff --git a/test/CodeGen/function-attributes.c b/test/CodeGen/function-attributes.c
new file mode 100644
index 0000000..3a1030a
--- /dev/null
+++ b/test/CodeGen/function-attributes.c
@@ -0,0 +1,91 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -Os -o - %s | FileCheck %s
+// CHECK: define signext i8 @f0(i32 %x) nounwind
+// CHECK: define zeroext i8 @f1(i32 %x) nounwind
+// CHECK: define void @f2(i8 signext %x) nounwind
+// CHECK: define void @f3(i8 zeroext %x) nounwind
+// CHECK: define signext i16 @f4(i32 %x) nounwind
+// CHECK: define zeroext i16 @f5(i32 %x) nounwind
+// CHECK: define void @f6(i16 signext %x) nounwind
+// CHECK: define void @f7(i16 zeroext %x) nounwind
+
+signed char f0(int x) { return x; }
+
+unsigned char f1(int x) { return x; }
+
+void f2(signed char x) { }
+
+void f3(unsigned char x) { }
+
+signed short f4(int x) { return x; }
+
+unsigned short f5(int x) { return x; }
+
+void f6(signed short x) { }
+
+void f7(unsigned short x) { }
+
+// CHECK: define void @f8()
+// CHECK: nounwind
+// CHECK: alwaysinline
+// CHECK: {
+void __attribute__((always_inline)) f8(void) { }
+
+// CHECK: call void @f9_t()
+// CHECK: noreturn
+// CHECK: {
+void __attribute__((noreturn)) f9_t(void);
+void f9(void) { f9_t(); }
+
+// FIXME: We should be setting nounwind on calls.
+// CHECK: call i32 @f10_t()
+// CHECK: readnone
+// CHECK: {
+int __attribute__((const)) f10_t(void);
+int f10(void) { return f10_t(); }
+int f11(void) {
+ exit:
+  return f10_t();
+}
+int f12(int arg) {
+  return arg ? 0 : f10_t();
+}
+
+// CHECK: define void @f13() nounwind readnone
+void f13(void) __attribute__((pure)) __attribute__((const));
+void f13(void){}
+
+
+// Ensure that these get inlined: rdar://6853279
+// CHECK: define void @f14
+// CHECK-NOT: @ai_
+// CHECK: call void @f14_end
+static __inline__ __attribute__((always_inline))
+int ai_1() {  return 4; }
+
+static __inline__ __attribute__((always_inline))
+struct {
+  int a, b, c, d, e;
+} ai_2() { while (1) {} }
+
+void f14(int a) {
+  extern void f14_end(void);
+  if (a)
+    ai_2();
+  ai_1();
+  f14_end();
+}
+
+// <rdar://problem/7102668> [irgen] clang isn't setting the optsize bit on functions
+// CHECK: define void @f15
+// CHECK: optsize
+// CHECK: {
+void f15(void) {
+}
+
+// PR5254
+// CHECK: define void @f16
+// CHECK: alignstack(16)
+// CHECK: {
+void __attribute__((force_align_arg_pointer)) f16(void) {
+}
+
diff --git a/test/CodeGen/function-decay.m b/test/CodeGen/function-decay.m
new file mode 100644
index 0000000..161f907
--- /dev/null
+++ b/test/CodeGen/function-decay.m
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 %s -emit-llvm -o -
+
+@interface I0 @end
+@implementation I0
+- (void) im0: (int (void)) a0 {
+}
+@end
+
+void func(int pf(void)) {
+}
diff --git a/test/CodeGen/functions.c b/test/CodeGen/functions.c
new file mode 100644
index 0000000..5629ef5
--- /dev/null
+++ b/test/CodeGen/functions.c
@@ -0,0 +1,49 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - -verify | FileCheck %s
+
+int g();
+
+int foo(int i) {
+  return g(i);
+}
+
+int g(int i) {
+  return g(i);
+}
+
+// rdar://6110827
+typedef void T(void);
+void test3(T f) {
+  f();
+}
+
+int a(int);
+int a() {return 1;}
+
+void f0() {}
+// CHECK: define void @f0()
+
+void f1();
+void f2(void) {
+// CHECK: call void @f1()
+  f1(1, 2, 3);
+}
+// CHECK: define void @f1()
+void f1() {}
+
+// CHECK: define {{.*}} @f3{{\(\)|\(.*sret.*\)}}
+struct foo { int X, Y, Z; } f3() {
+  while (1) {}
+}
+
+// PR4423 - This shouldn't crash in codegen
+void f4() {}
+void f5() { f4(42); } //expected-warning {{too many arguments}}
+
+// Qualifiers on parameter types shouldn't make a difference.
+static void f6(const float f, const float g) {
+}
+void f7(float f, float g) {
+  f6(f, g);
+// CHECK: define void @f7(float{{.*}}, float{{.*}})
+// CHECK: call void @f6(float{{.*}}, float{{.*}})
+}
diff --git a/test/CodeGen/global-decls.c b/test/CodeGen/global-decls.c
new file mode 100644
index 0000000..89e899f
--- /dev/null
+++ b/test/CodeGen/global-decls.c
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -triple i386-pc-linux-gnu -emit-llvm -o %t %s
+
+// RUN: grep '@g0_ext = extern_weak global i32' %t
+extern int g0_ext __attribute__((weak));
+// RUN: grep 'declare extern_weak i32 @g1_ext()' %t
+extern int __attribute__((weak)) g1_ext (void);
+
+// RUN: grep '@g0_common = weak global i32' %t
+int g0_common __attribute__((weak));
+
+// RUN: grep '@g0_def = weak global i32' %t
+int g0_def __attribute__((weak)) = 52;
+// RUN: grep 'define weak i32 @g1_def()' %t
+int __attribute__((weak)) g1_def (void) { return 0; }
+
+// Force _ext references
+void f0() {
+  int a = g0_ext;
+  int b = g1_ext();
+}
+
diff --git a/test/CodeGen/global-init.c b/test/CodeGen/global-init.c
new file mode 100644
index 0000000..351ca9e
--- /dev/null
+++ b/test/CodeGen/global-init.c
@@ -0,0 +1,52 @@
+// RUN: %clang_cc1 -emit-llvm -o - -triple i386-linux-gnu %s | FileCheck %s
+
+// This checks that the global won't be marked as common. 
+// (It shouldn't because it's being initialized).
+
+int a;
+int a = 242;
+// CHECK: @a = global i32 242
+
+// This should get normal weak linkage.
+int c __attribute__((weak))= 0;
+// CHECK: @c = weak global i32 0
+
+
+// Since this is marked const, it should get weak_odr linkage, since all
+// definitions have to be the same.
+// CHECK: @d = weak_odr constant i32 0
+const int d __attribute__((weak))= 0;
+
+// PR6168 "too many undefs"
+struct ManyFields {
+  int a;
+  int b;
+  int c;
+  char d;
+  int e;
+  int f;
+};
+
+// CHECK: global %0 { i32 1, i32 2, i32 0, i8 0, i32 0, i32 0 }
+struct ManyFields FewInits = {1, 2};
+
+
+// PR6766
+// CHECK: @l = global %1 { [24 x i8] c"f\00\00\00o\00\00\00o\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00", i32 1 }
+typedef __WCHAR_TYPE__ wchar_t;
+struct K {
+  wchar_t L[6];
+  int M;
+} l =  { { L"foo" }, 1 };
+
+
+// CHECK: @yuv_types = global [4 x [6 x i8]] {{\[}}[6 x i8] c"4:0:0\00", [6 x i8] c"4:2:0\00", [6 x i8] c"4:2:2\00", [6 x i8] c"4:4:4\00"]
+char yuv_types[4][6]= {"4:0:0","4:2:0","4:2:2","4:4:4"};
+
+
+// NOTE: tentative definitions are processed at the end of the translation unit.
+
+// This shouldn't be emitted as common because it has an explicit section.
+// rdar://7119244
+// CHECK: @b = global i32 0, section "foo"
+int b __attribute__((section("foo")));
diff --git a/test/CodeGen/global-with-initialiser.c b/test/CodeGen/global-with-initialiser.c
new file mode 100644
index 0000000..27d209e
--- /dev/null
+++ b/test/CodeGen/global-with-initialiser.c
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -emit-llvm %s -o %t
+
+const int globalInt = 1;
+int globalIntWithFloat = 1.5f;
+int globalIntArray[5] = { 1, 2 };
+int globalIntFromSizeOf = sizeof(globalIntArray);
+char globalChar = 'a';
+char globalCharArray[5] = { 'a', 'b' };
+float globalFloat = 1.0f;
+float globalFloatWithInt = 1;
+float globalFloatArray[5] = { 1.0f, 2.0f };
+double globalDouble = 1.0;
+double globalDoubleArray[5] = { 1.0, 2.0 };
+char *globalString = "abc";
+char *globalStringArray[5] = { "123", "abc" };
+long double globalLongDouble = 1;
+long double globalLongDoubleArray[5] = { 1.0, 2.0 };
+
+struct Struct {
+  int member1;
+  float member2;
+  char *member3; 
+};
+
+struct Struct globalStruct = { 1, 2.0f, "foobar"};
diff --git a/test/CodeGen/globalinit.c b/test/CodeGen/globalinit.c
new file mode 100644
index 0000000..e07a419
--- /dev/null
+++ b/test/CodeGen/globalinit.c
@@ -0,0 +1,51 @@
+// RUN: %clang_cc1 -emit-llvm %s -o %t
+
+int A[10] = { 1,2,3,4,5 };
+
+
+extern int x[];
+void foo() { x[0] = 1; }
+int x[10];
+void bar() { x[0] = 1; }
+
+
+extern int y[];
+void *g = y;
+
+int latin_ptr2len (char *p);
+int (*mb_ptr2len) (char *p) = latin_ptr2len;
+
+
+char string[8] = "string";   // extend init
+char string2[4] = "string";  // truncate init
+
+char *test(int c) {
+ static char buf[10];
+ static char *bufptr = buf;
+
+ return c ? buf : bufptr;
+}
+
+
+_Bool booltest = 0;
+void booltest2() {
+  static _Bool booltest3 = 4;
+}
+
+// Scalars in braces.
+static int a = { 1 };
+
+// References to enums.
+enum {
+  EnumA, EnumB
+};
+
+int c[] = { EnumA, EnumB };
+
+// Binary operators
+int d[] = { EnumA | EnumB };
+
+// PR1968
+static int array[];
+static int array[4];
+
diff --git a/test/CodeGen/illegal-UTF8.m b/test/CodeGen/illegal-UTF8.m
new file mode 100644
index 0000000..871e6e5
--- /dev/null
+++ b/test/CodeGen/illegal-UTF8.m
@@ -0,0 +1,8 @@
+// RUN: %clang %s -S -m64 -o -
+
+@class NSString;
+
+// FIXME: GCC emits the following warning:
+// CodeGen/illegal-UTF8.m:4: warning: input conversion stopped due to an input byte that does not belong to the input codeset UTF-8
+
+NSString *S = @"\xff\xff___WAIT___";
diff --git a/test/CodeGen/incomplete-function-type.c b/test/CodeGen/incomplete-function-type.c
new file mode 100644
index 0000000..0ba6633
--- /dev/null
+++ b/test/CodeGen/incomplete-function-type.c
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+// CHECK: ModuleID
+// CHECK-NOT: opaque
+// CHECK: define void @f0
+
+enum teste1 test1f(void), (*test1)(void) = test1f;
+struct tests2 test2f(), (*test2)() = test2f;
+struct tests3;
+void test3f(struct tests3), (*test3)(struct tests3) = test3f;
+enum teste1 { TEST1 };
+struct tests2 { int x,y,z,a,b,c,d,e,f,g; };
+struct tests3 { float x; };
+
+void f0() {}
diff --git a/test/CodeGen/indirect-goto.c b/test/CodeGen/indirect-goto.c
new file mode 100644
index 0000000..7a3d717
--- /dev/null
+++ b/test/CodeGen/indirect-goto.c
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown -O3 -emit-llvm -o - %s | grep "ret i32 2520"
+
+static int foo(unsigned i) {
+  void *addrs[] = { &&L1, &&L2, &&L3, &&L4, &&L5 };
+  int res = 1;
+
+  goto *addrs[i];
+ L5: res *= 11;
+ L4: res *= 7;
+ L3: res *= 5;
+ L2: res *= 3;
+ L1: res *= 2; 
+  return res;
+}
+
+static int foo2(unsigned i) {
+  static const void *addrs[] = { &&L1, &&L2, &&L3, &&L4, &&L5 };
+  int res = 1;
+  
+  goto *addrs[i];
+L5: res *= 11;
+L4: res *= 7;
+L3: res *= 5;
+L2: res *= 3;
+L1: res *= 2; 
+  return res;
+}
+
+int main() {
+  return foo(3)+foo2(4);
+}
diff --git a/test/CodeGen/init-with-member-expr.c b/test/CodeGen/init-with-member-expr.c
new file mode 100644
index 0000000..fdc8c14
--- /dev/null
+++ b/test/CodeGen/init-with-member-expr.c
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 < %s -emit-llvm
+struct test {
+  int a;
+};
+
+extern struct test t;
+
+int *b=&t.a;
+
+
+// PR2049
+typedef struct mark_header_tag {
+ unsigned char mark[7];
+} mark_header_t;
+int is_rar_archive(int fd) {
+        const mark_header_t rar_hdr[2] = {{0x52, 0x61, 0x72, 0x21, 0x1a, 0x07, 0x00}, {'U', 'n', 'i', 'q', 'u', 'E', '!'}};
+        foo(rar_hdr);
+
+        return 0;
+}
+
diff --git a/test/CodeGen/init.c b/test/CodeGen/init.c
new file mode 100644
index 0000000..d48e723
--- /dev/null
+++ b/test/CodeGen/init.c
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s
+
+void f1() {
+  // Scalars in braces.
+  int a = { 1 };
+}
+
+void f2() {
+  int a[2][2] = { { 1, 2 }, { 3, 4 } };
+  int b[3][3] = { { 1, 2 }, { 3, 4 } };
+  int *c[2] = { &a[1][1], &b[2][2] };
+  int *d[2][2] = { {&a[1][1], &b[2][2]}, {&a[0][0], &b[1][1]} };
+  int *e[3][3] = { {&a[1][1], &b[2][2]}, {&a[0][0], &b[1][1]} };
+  char ext[3][3] = {".Y",".U",".V"};
+}
+
+typedef void (* F)(void);
+extern void foo(void);
+struct S { F f; };
+void f3() {
+  struct S a[1] = { { foo } };
+}
+
+// Constants
+// CHECK: @g3 = constant i32 10
+// CHECK: @f4.g4 = internal constant i32 12
+const int g3 = 10;
+int f4() {
+  static const int g4 = 12;
+  return g4;
+}
+
+// PR6537
+typedef union vec3 {
+  struct { double x, y, z; };
+  double component[3];
+} vec3;
+vec3 f5(vec3 value) {
+  return (vec3) {{
+    .x = value.x
+  }};
+}
diff --git a/test/CodeGen/inline.c b/test/CodeGen/inline.c
new file mode 100644
index 0000000..a17b069
--- /dev/null
+++ b/test/CodeGen/inline.c
@@ -0,0 +1,86 @@
+// RUN: echo "GNU89 tests:"
+// RUN: %clang %s -emit-llvm -S -o %t -std=gnu89
+// RUN: grep "define available_externally i32 @ei()" %t
+// RUN: grep "define i32 @foo()" %t
+// RUN: grep "define i32 @bar()" %t
+// RUN: grep "define void @unreferenced1()" %t
+// RUN: not grep unreferenced2 %t
+// RUN: grep "define void @gnu_inline()" %t
+// RUN: grep "define available_externally void @gnu_ei_inline()" %t
+// RUN: grep "define i32 @test1" %t
+// RUN: grep "define i32 @test2" %t
+// RUN: grep "define void @test3()" %t
+// RUN: grep "define available_externally i32 @test4" %t
+// RUN: grep "define available_externally i32 @test5" %t
+
+// RUN: echo "\nC99 tests:"
+// RUN: %clang %s -emit-llvm -S -o %t -std=c99
+// RUN: grep "define i32 @ei()" %t
+// RUN: grep "define available_externally i32 @foo()" %t
+// RUN: grep "define i32 @bar()" %t
+// RUN: not grep unreferenced1 %t
+// RUN: grep "define void @unreferenced2()" %t
+// RUN: grep "define void @gnu_inline()" %t
+// RUN: grep "define available_externally void @gnu_ei_inline()" %t
+// RUN: grep "define i32 @test1" %t
+// RUN: grep "define i32 @test2" %t
+// RUN: grep "define void @test3" %t
+// RUN: grep "define available_externally i32 @test4" %t
+// RUN: grep "define available_externally i32 @test5" %t
+
+// RUN: echo "\nC++ tests:"
+// RUN: %clang %s -emit-llvm -S -o %t -std=c++98
+// RUN: grep "define linkonce_odr i32 @_Z2eiv()" %t
+// RUN: grep "define linkonce_odr i32 @_Z3foov()" %t
+// RUN: grep "define i32 @_Z3barv()" %t
+// RUN: not grep unreferenced %t
+// RUN: grep "define void @_Z10gnu_inlinev()" %t
+// RUN: grep "define available_externally void @_Z13gnu_ei_inlinev()" %t
+
+extern __inline int ei() { return 123; }
+
+__inline int foo() {
+  return ei();
+}
+
+int bar() { return foo(); }
+
+
+__inline void unreferenced1() {}
+extern __inline void unreferenced2() {}
+
+__inline __attribute((__gnu_inline__)) void gnu_inline() {}
+
+// PR3988
+extern __inline __attribute__((gnu_inline)) void gnu_ei_inline() {}
+void (*P)() = gnu_ei_inline;
+
+// <rdar://problem/6818429>
+int test1();
+__inline int test1() { return 4; }
+__inline int test2() { return 5; }
+__inline int test2();
+int test2();
+
+void test_test1() { test1(); }
+void test_test2() { test2(); }
+
+// PR3989
+extern __inline void test3() __attribute__((gnu_inline));
+__inline void __attribute__((gnu_inline)) test3() {}
+
+extern int test4(void);
+extern __inline __attribute__ ((__gnu_inline__)) int test4(void)
+{
+  return 0;
+}
+
+void test_test4() { test4(); }
+
+extern __inline int test5(void)  __attribute__ ((__gnu_inline__));
+extern __inline int __attribute__ ((__gnu_inline__)) test5(void)
+{
+  return 0;
+}
+
+void test_test5() { test5(); }
diff --git a/test/CodeGen/inline2.c b/test/CodeGen/inline2.c
new file mode 100644
index 0000000..737b58f
--- /dev/null
+++ b/test/CodeGen/inline2.c
@@ -0,0 +1,62 @@
+// RUN: %clang_cc1 -std=gnu89 -triple i386-apple-darwin9 -emit-llvm %s -o - | FileCheck -check-prefix GNU89 %s
+// RUN: %clang_cc1 -std=c99 -triple i386-apple-darwin9 -emit-llvm %s -o - | FileCheck -check-prefix C99 %s
+
+// CHECK-GNU89: define i32 @f0()
+// CHECK-C99: define i32 @f0()
+int f0(void);
+int f0(void) { return 0; }
+
+// CHECK-GNU89: define i32 @f1()
+// CHECK-C99: define i32 @f1()
+inline int f1(void);
+int f1(void) { return 0; }
+
+// CHECK-GNU89: define i32 @f2()
+// CHECK-C99: define i32 @f2()
+int f2(void);
+inline int f2(void) { return 0; }
+
+// CHECK-GNU89: define i32 @f3()
+// CHECK-C99: define i32 @f3()
+extern inline int f3(void);
+int f3(void) { return 0; }
+
+// CHECK-GNU89: define i32 @f5()
+// CHECK-C99: define i32 @f5()
+extern inline int f5(void);
+inline int f5(void) { return 0; }
+
+// CHECK-GNU89: define i32 @f6()
+// CHECK-C99: define i32 @f6()
+inline int f6(void);
+extern inline int f6(void) { return 0; }
+
+// CHECK-GNU89: define i32 @f7()
+// CHECK-C99: define i32 @f7()
+extern inline int f7(void);
+extern int f7(void) { return 0; }
+
+// CHECK-GNU89: define i32 @fA()
+inline int fA(void) { return 0; }
+
+// CHECK-GNU89: define available_externally i32 @f4()
+// CHECK-C99: define i32 @f4()
+int f4(void);
+extern inline int f4(void) { return 0; }
+
+// CHECK-GNU89: define available_externally i32 @f8()
+// CHECK-C99: define i32 @f8()
+extern int f8(void);
+extern inline int f8(void) { return 0; }
+
+// CHECK-GNU89: define available_externally i32 @f9()
+// CHECK-C99: define i32 @f9()
+extern inline int f9(void);
+extern inline int f9(void) { return 0; }
+
+// CHECK-C99: define available_externally i32 @fA()
+
+int test_all() { 
+  return f0() + f1() + f2() + f3() + f4() + f5() + f6() + f7() + f8() + f9() 
+    + fA();
+}
diff --git a/test/CodeGen/int-to-pointer.c b/test/CodeGen/int-to-pointer.c
new file mode 100644
index 0000000..242a8a6
--- /dev/null
+++ b/test/CodeGen/int-to-pointer.c
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -emit-llvm %s -o %t
+
+void *test(int i)
+{
+  return (void *)i;
+}
diff --git a/test/CodeGen/kr-func-promote.c b/test/CodeGen/kr-func-promote.c
new file mode 100644
index 0000000..fcdbac3
--- /dev/null
+++ b/test/CodeGen/kr-func-promote.c
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown %s -emit-llvm -o - | grep "i32 @a(i32)"
+
+int a();
+int a(x) short x; {return x;}
+
diff --git a/test/CodeGen/kr-style-block.c b/test/CodeGen/kr-style-block.c
new file mode 100644
index 0000000..09efb37
--- /dev/null
+++ b/test/CodeGen/kr-style-block.c
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -emit-llvm %s -o %t -fblocks
+
+void foo (void(^)());
+
+int main()
+{
+foo(
+  ^() { }
+);
+}
diff --git a/test/CodeGen/libcalls.c b/test/CodeGen/libcalls.c
new file mode 100644
index 0000000..828d7de
--- /dev/null
+++ b/test/CodeGen/libcalls.c
@@ -0,0 +1,52 @@
+// RUN: %clang_cc1 -fmath-errno -emit-llvm -o - %s -triple i386-unknown-unknown | FileCheck -check-prefix YES %s
+// RUN: %clang_cc1 -emit-llvm -o - %s -triple i386-unknown-unknown | FileCheck -check-prefix NO %s
+
+// CHECK-YES: define void @test_sqrt
+// CHECK-NO: define void @test_sqrt
+void test_sqrt(float a0, double a1, long double a2) {
+  // Following llvm-gcc's lead, we never emit these as intrinsics;
+  // no-math-errno isn't good enough.  We could probably use intrinsics
+  // with appropriate guards if it proves worthwhile.
+
+  // CHECK-YES: call float @sqrtf
+  // CHECK-NO: call float @sqrtf
+  float l0 = sqrtf(a0);
+
+  // CHECK-YES: call double @sqrt
+  // CHECK-NO: call double @sqrt
+  double l1 = sqrt(a1);
+
+  // CHECK-YES: call x86_fp80 @sqrtl
+  // CHECK-NO: call x86_fp80 @sqrtl
+  long double l2 = sqrtl(a2);
+}
+
+// CHECK-YES: declare float @sqrtf(float)
+// CHECK-YES: declare double @sqrt(double)
+// CHECK-YES: declare x86_fp80 @sqrtl(x86_fp80)
+// CHECK-NO: declare float @sqrtf(float) readnone
+// CHECK-NO: declare double @sqrt(double) readnone
+// CHECK-NO: declare x86_fp80 @sqrtl(x86_fp80) readnone
+
+// CHECK-YES: define void @test_pow
+// CHECK-NO: define void @test_pow
+void test_pow(float a0, double a1, long double a2) {
+  // CHECK-YES: call float @powf
+  // CHECK-NO: call float @llvm.pow.f32
+  float l0 = powf(a0, a0);
+
+  // CHECK-YES: call double @pow
+  // CHECK-NO: call double @llvm.pow.f64
+  double l1 = pow(a1, a1);
+
+  // CHECK-YES: call x86_fp80 @powl
+  // CHECK-NO: call x86_fp80 @llvm.pow.f80
+  long double l2 = powl(a2, a2);
+}
+
+// CHECK-YES: declare float @powf(float, float)
+// CHECK-YES: declare double @pow(double, double)
+// CHECK-YES: declare x86_fp80 @powl(x86_fp80, x86_fp80)
+// CHECK-NO: declare float @llvm.pow.f32(float, float) nounwind readonly
+// CHECK-NO: declare double @llvm.pow.f64(double, double) nounwind readonly
+// CHECK-NO: declare x86_fp80 @llvm.pow.f80(x86_fp80, x86_fp80) nounwind readonly
diff --git a/test/CodeGen/lineno-dbginfo.c b/test/CodeGen/lineno-dbginfo.c
new file mode 100644
index 0000000..c5c350f
--- /dev/null
+++ b/test/CodeGen/lineno-dbginfo.c
@@ -0,0 +1,6 @@
+// RUN: echo "#include <stdio.h>" > %t.h
+// RUN: %clang -S -save-temps -g -include %t.h %s -emit-llvm -o %t.ll
+// RUN: grep "i32 5" %t.ll
+// RUN: rm -f lineno-dbginfo.i
+// outer is at line number 5.
+int outer = 42;
diff --git a/test/CodeGen/linkage-redecl.c b/test/CodeGen/linkage-redecl.c
new file mode 100644
index 0000000..09b51f0
--- /dev/null
+++ b/test/CodeGen/linkage-redecl.c
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - |grep internal
+
+// C99 6.2.2p3
+// PR3425
+static void f(int x);
+
+void g0() {
+  f(5);
+}
+
+extern void f(int x) { } // still has internal linkage
diff --git a/test/CodeGen/long-double-x86.c b/test/CodeGen/long-double-x86.c
new file mode 100644
index 0000000..f040207
--- /dev/null
+++ b/test/CodeGen/long-double-x86.c
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple=i686-apple-darwin9 | grep x86_fp80
+
+long double x = 0;
+int checksize[sizeof(x) == 16 ? 1 : -1];
diff --git a/test/CodeGen/mandel.c b/test/CodeGen/mandel.c
new file mode 100644
index 0000000..8ecf8f2
--- /dev/null
+++ b/test/CodeGen/mandel.c
@@ -0,0 +1,65 @@
+// RUN: %clang_cc1 -emit-llvm %s -o %t
+
+/* Sparc is not C99-compliant */
+#if defined(sparc) || defined(__sparc__) || defined(__sparcv9)
+
+int main() { return 0; }
+
+#else /* sparc */
+
+#define ESCAPE 2
+#define IMAGE_WIDTH 150
+#define IMAGE_HEIGHT 50
+#if 1
+#define IMAGE_SIZE 60
+#else
+#define IMAGE_SIZE 5000
+#endif
+#define START_X -2.1
+#define END_X 1.0
+#define START_Y -1.25
+#define MAX_ITER 100
+
+#define step_X ((END_X - START_X)/IMAGE_WIDTH)
+#define step_Y ((-START_Y - START_Y)/IMAGE_HEIGHT)
+
+#define I 1.0iF
+
+int putchar(char c);
+
+volatile double __complex__ accum;
+
+void mandel() {
+  int x, y, n;
+  for (y = 0; y < IMAGE_HEIGHT; ++y) {
+    for (x = 0; x < IMAGE_WIDTH; ++x) {
+      double __complex__ c = (START_X+x*step_X) + (START_Y+y*step_Y) * I;
+      double __complex__ z = 0.0;
+
+      for (n = 0; n < MAX_ITER; ++n) {
+        z = z * z + c;
+        if (hypot(__real__ z, __imag__ z) >= ESCAPE)
+          break;
+      }
+
+      if (n == MAX_ITER)
+        putchar(' ');
+      else if (n > 6)
+        putchar('.');
+      else if (n > 3)
+        putchar('+');
+      else if (n > 2)
+        putchar('x');
+      else
+        putchar('*');
+    }
+    putchar('\n');
+  }
+}
+
+int main() {
+  mandel();
+  return 0;
+}
+
+#endif /* sparc */
diff --git a/test/CodeGen/mangle.c b/test/CodeGen/mangle.c
new file mode 100644
index 0000000..93d424a
--- /dev/null
+++ b/test/CodeGen/mangle.c
@@ -0,0 +1,65 @@
+// RUN: %clang_cc1 -triple i386-pc-linux-gnu -emit-llvm -o - %s | FileCheck %s
+
+// CHECK: @"\01foo"
+
+// Make sure we mangle overloadable, even in C system headers.
+# 1 "somesystemheader.h" 1 3 4
+// CHECK: @_Z2f0i
+void __attribute__((__overloadable__)) f0(int a) {}
+// CHECK: @_Z2f0l
+void __attribute__((__overloadable__)) f0(long b) {}
+
+// CHECK: @"\01bar"
+
+// These should get merged.
+void foo() __asm__("bar");
+void foo2() __asm__("bar");
+
+int nux __asm__("foo");
+extern float nux2 __asm__("foo");
+
+int test() { 
+  foo();
+  foo2();
+  
+  return nux + nux2;
+}
+
+
+// Function becomes a variable.
+void foo3() __asm__("var");
+
+void test2() {
+  foo3();
+}
+int foo4 __asm__("var") = 4;
+
+
+// Variable becomes a function
+extern int foo5 __asm__("var2");
+
+void test3() {
+  foo5 = 1;
+}
+
+void foo6() __asm__("var2");
+void foo6() {
+}
+
+
+
+int foo7 __asm__("foo7") __attribute__((used));
+float foo8 __asm__("foo7") = 42;
+
+// PR4412
+int func(void);
+extern int func (void) __asm__ ("FUNC");
+
+// CHECK: @"\01FUNC"
+int func(void) {
+  return 42;
+}
+
+// CHECK: @_Z4foo9Dv4_f
+typedef __attribute__(( vector_size(16) )) float float4;
+void __attribute__((__overloadable__)) foo9(float4 f) {}
diff --git a/test/CodeGen/merge-attrs.c b/test/CodeGen/merge-attrs.c
new file mode 100644
index 0000000..474b172
--- /dev/null
+++ b/test/CodeGen/merge-attrs.c
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 %s -emit-llvm -o %t
+
+void *malloc(__SIZE_TYPE__ size) __attribute__ ((__nothrow__));
+
+inline static void __zend_malloc() {
+    malloc(1);
+}
+
+void *malloc(__SIZE_TYPE__ size) __attribute__ ((__nothrow__));
+
+void fontFetch() {
+    __zend_malloc(1);
+}
diff --git a/test/CodeGen/merge-statics.c b/test/CodeGen/merge-statics.c
new file mode 100644
index 0000000..6716935
--- /dev/null
+++ b/test/CodeGen/merge-statics.c
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 < %s -emit-llvm | grep internal | count 1
+
+// The two decls for 'a' should merge into one llvm GlobalVariable.
+
+struct s { int x; };
+static struct s a;
+
+struct s *ap1 = &a;
+
+static struct s a =  {
+    10
+};
+
diff --git a/test/CodeGen/no-common.c b/test/CodeGen/no-common.c
new file mode 100644
index 0000000..03a5bb0
--- /dev/null
+++ b/test/CodeGen/no-common.c
@@ -0,0 +1,6 @@
+// RUN: %clang -emit-llvm -S -o %t %s
+// RUN: grep '@x = common global' %t
+// RUN: %clang -fno-common -emit-llvm -S -o %t %s
+// RUN: grep '@x = global' %t
+
+int x;
diff --git a/test/CodeGen/object-size.c b/test/CodeGen/object-size.c
new file mode 100644
index 0000000..3920ec5
--- /dev/null
+++ b/test/CodeGen/object-size.c
@@ -0,0 +1,121 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm %s -o - | FileCheck %s
+
+#define strcpy(dest, src) \
+  ((__builtin_object_size(dest, 0) != -1ULL) \
+   ? __builtin___strcpy_chk (dest, src, __builtin_object_size(dest, 1)) \
+   : __inline_strcpy_chk(dest, src))
+
+static char *__inline_strcpy_chk (char *dest, const char *src) {
+  return __builtin___strcpy_chk(dest, src, __builtin_object_size(dest, 1));
+}
+
+char gbuf[63];
+char *gp;
+int gi, gj;
+
+void test1() {
+  // CHECK:     = call i8* @__strcpy_chk(i8* getelementptr inbounds ([63 x i8]* @gbuf, i32 0, i64 4), i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0), i64 59)
+  strcpy(&gbuf[4], "Hi there");
+}
+
+void test2() {
+  // CHECK:     = call i8* @__strcpy_chk(i8* getelementptr inbounds ([63 x i8]* @gbuf, i32 0, i32 0), i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0), i64 63)
+  strcpy(gbuf, "Hi there");
+}
+
+void test3() {
+  // CHECK:     = call i8* @__strcpy_chk(i8* getelementptr inbounds ([63 x i8]* @gbuf, i64 1, i64 37), i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0), i64 0)
+  strcpy(&gbuf[100], "Hi there");
+}
+
+void test4() {
+  // CHECK:     = call i8* @__strcpy_chk(i8* getelementptr inbounds ([63 x i8]* @gbuf, i32 0, i64 -1), i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0), i64 0)
+  strcpy((char*)(void*)&gbuf[-1], "Hi there");
+}
+
+void test5() {
+  // CHECK:     = load i8** @gp
+  // CHECK-NEXT:= call i64 @llvm.objectsize.i64(i8* %{{.*}}, i1 false)
+  strcpy(gp, "Hi there");
+}
+
+void test6() {
+  char buf[57];
+
+  // CHECK:       = call i8* @__strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0), i64 53)
+  strcpy(&buf[4], "Hi there");
+}
+
+void test7() {
+  int i;
+  // CHECK-NOT:   __strcpy_chk
+  // CHECK:       = call i8* @__inline_strcpy_chk(i8* getelementptr inbounds ([63 x i8]* @gbuf, i32 0, i32 0), i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0))
+  strcpy((++i, gbuf), "Hi there");
+}
+
+void test8() {
+  char *buf[50];
+  // CHECK-NOT:   __strcpy_chk
+  // CHECK:       = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0))
+  strcpy(buf[++gi], "Hi there");
+}
+
+void test9() {
+  // CHECK-NOT:   __strcpy_chk
+  // CHECK:       = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0))
+  strcpy((char *)((++gi) + gj), "Hi there");
+}
+
+char **p;
+void test10() {
+  // CHECK-NOT:   __strcpy_chk
+  // CHECK:       = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0))
+  strcpy(*(++p), "Hi there");
+}
+
+void test11() {
+  // CHECK-NOT:   __strcpy_chk
+  // CHECK:       = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0))
+  strcpy(gp = gbuf, "Hi there");
+}
+
+void test12() {
+  // CHECK-NOT:   __strcpy_chk
+  // CHECK:       = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0))
+  strcpy(++gp, "Hi there");
+}
+
+void test13() {
+  // CHECK-NOT:   __strcpy_chk
+  // CHECK:       = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0))
+  strcpy(gp++, "Hi there");
+}
+
+void test14() {
+  // CHECK-NOT:   __strcpy_chk
+  // CHECK:       = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0))
+  strcpy(--gp, "Hi there");
+}
+
+void test15() {
+  // CHECK-NOT:   __strcpy_chk
+  // CHECK:       = call i8* @__inline_strcpy_chk(i8* %{{..*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0))
+  strcpy(gp--, "Hi there");
+}
+
+void test16() {
+  // CHECK-NOT:   __strcpy_chk
+  // CHECK:       = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0))
+  strcpy(gp += 1, "Hi there");
+}
+
+void test17() {
+  // CHECK: store i32 -1
+  gi = __builtin_object_size(gp++, 0);
+  // CHECK: store i32 -1
+  gi = __builtin_object_size(gp++, 1);
+  // CHECK: store i32 0
+  gi = __builtin_object_size(gp++, 2);
+  // CHECK: store i32 0
+  gi = __builtin_object_size(gp++, 3);
+}
diff --git a/test/CodeGen/offsetof.c b/test/CodeGen/offsetof.c
new file mode 100644
index 0000000..c279e22
--- /dev/null
+++ b/test/CodeGen/offsetof.c
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 %s -emit-llvm -o %t
+
+// PR2910
+struct sockaddr_un {
+ unsigned char sun_len;
+ char sun_path[104];
+};
+
+int test(int len) {
+  return __builtin_offsetof(struct sockaddr_un, sun_path[len+1]);
+}
+
diff --git a/test/CodeGen/opaque-pointer.c b/test/CodeGen/opaque-pointer.c
new file mode 100644
index 0000000..d658db1
--- /dev/null
+++ b/test/CodeGen/opaque-pointer.c
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 %s -emit-llvm -o -
+struct test;
+
+typedef void (*my_func) (struct test *);
+my_func handler;
+
+struct test {
+  char a;
+};
+
+char f(struct test *t) {
+  return t->a;
+}
diff --git a/test/CodeGen/overloadable.c b/test/CodeGen/overloadable.c
new file mode 100644
index 0000000..1ed72b1
--- /dev/null
+++ b/test/CodeGen/overloadable.c
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - | grep _Z1fPA10_1X
+int __attribute__((overloadable)) f(int x) { return x; }
+float __attribute__((overloadable)) f(float x) { return x; }
+double __attribute__((overloadable)) f(double x) { return x; }
+double _Complex __attribute__((overloadable)) f(double _Complex x) { return x; }
+typedef short v4hi __attribute__ ((__vector_size__ (8)));
+v4hi __attribute__((overloadable)) f(v4hi x) { return x; }
+
+struct X { };
+void  __attribute__((overloadable)) f(struct X (*ptr)[10]) { }
+
+void __attribute__((overloadable)) f(int x, int y, ...) { }
+
+int main() {
+  int iv = 17;
+  float fv = 3.0f;
+  double dv = 4.0;
+  double _Complex cdv;
+  v4hi vv;
+
+  iv = f(iv);
+  fv = f(fv);
+  dv = f(dv);
+  cdv = f(cdv);
+  vv = f(vv);
+}
diff --git a/test/CodeGen/packed-union.c b/test/CodeGen/packed-union.c
new file mode 100644
index 0000000..0aeed00
--- /dev/null
+++ b/test/CodeGen/packed-union.c
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm %s -o %t
+
+// RUN: grep "struct._attrs = type <{ i32, i8 }>" %t
+typedef struct _attrs {
+        unsigned file_attributes;
+        unsigned char filename_length;
+} __attribute__((__packed__)) attrs;
+
+// RUN: grep "union._attr_union = type <{ i32, i8 }>" %t
+typedef union _attr_union {
+  attrs file_attrs;
+  unsigned owner_id;
+} __attribute__((__packed__)) attr_union;
+
+attr_union u;
+
diff --git a/test/CodeGen/palignr.c b/test/CodeGen/palignr.c
new file mode 100644
index 0000000..6297b2e
--- /dev/null
+++ b/test/CodeGen/palignr.c
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 %s -triple=i686-apple-darwin -target-feature +ssse3 -O1 -S -o - | FileCheck %s
+
+#define _mm_alignr_epi8(a, b, n) (__builtin_ia32_palignr128((a), (b), (n)))
+typedef __attribute__((vector_size(16))) int int4;
+
+// CHECK: palignr
+int4 align1(int4 a, int4 b) { return _mm_alignr_epi8(a, b, 15); }
+// CHECK: ret
+// CHECK: ret
+// CHECK-NOT: palignr
+int4 align2(int4 a, int4 b) { return _mm_alignr_epi8(a, b, 16); }
+// CHECK: psrldq
+int4 align3(int4 a, int4 b) { return _mm_alignr_epi8(a, b, 17); }
+// CHECK: xor
+int4 align4(int4 a, int4 b) { return _mm_alignr_epi8(a, b, 32); }
+
+#define _mm_alignr_pi8(a, b, n) (__builtin_ia32_palignr((a), (b), (n)))
+typedef __attribute__((vector_size(8))) int int2;
+
+// CHECK-NOT: palignr
+int2 align5(int2 a, int2 b) { return _mm_alignr_pi8(a, b, 8); }
+
+// CHECK: psrlq
+int2 align6(int2 a, int2 b) { return _mm_alignr_pi8(a, b, 9); }
+
+// CHECK: xor
+int2 align7(int2 a, int2 b) { return _mm_alignr_pi8(a, b, 16); }
+
+// CHECK: palignr
+int2 align8(int2 a, int2 b) { return _mm_alignr_pi8(a, b, 7); }
\ No newline at end of file
diff --git a/test/CodeGen/parameter-passing.c b/test/CodeGen/parameter-passing.c
new file mode 100644
index 0000000..e48815b
--- /dev/null
+++ b/test/CodeGen/parameter-passing.c
@@ -0,0 +1,56 @@
+// Check the various ways in which the three classes of values
+// (scalar, complex, aggregate) interact with parameter passing
+// (function entry, function return, call argument, call result).
+//
+// We also check _Bool and empty structures, as these can have annoying
+// corner cases.
+
+// RUN: %clang_cc1 %s -triple i386-unknown-unknown -O3 -emit-llvm -o %t
+// RUN: not grep '@g0' %t
+
+// RUN: %clang_cc1 %s -triple x86_64-unknown-unknown -O3 -emit-llvm -o %t
+// RUN: not grep '@g0' %t
+
+// RUN: %clang_cc1 %s -triple powerpc-unknown-unknown -O3 -emit-llvm -o %t
+// RUN: not grep '@g0' %t
+
+typedef _Bool BoolTy;
+typedef int ScalarTy;
+typedef _Complex int ComplexTy;
+typedef struct { int a, b, c; } AggrTy;
+typedef struct { int a[0]; } EmptyTy;
+
+static int result;
+
+static BoolTy bool_id(BoolTy a) { return a; }
+static AggrTy aggr_id(AggrTy a) { return a; }
+static EmptyTy empty_id(EmptyTy a) { return a; }
+static ScalarTy scalar_id(ScalarTy a) { return a; }
+static ComplexTy complex_id(ComplexTy a) { return a; }
+
+static void bool_mul(BoolTy a) { result *= a; }
+
+static void aggr_mul(AggrTy a) { result *= a.a * a.b * a.c; }
+
+static void empty_mul(EmptyTy a) { result *= 53; }
+
+static void scalar_mul(ScalarTy a) { result *= a; }
+
+static void complex_mul(ComplexTy a) { result *= __real a * __imag a; }
+
+extern void g0(void);
+
+void f0(void) {
+  result = 1;
+  
+  bool_mul(bool_id(1));
+  aggr_mul(aggr_id((AggrTy) { 2, 3, 5}));
+  empty_mul(empty_id((EmptyTy) {}));
+  scalar_mul(scalar_id(7));
+  complex_mul(complex_id(11 + 13i));
+  
+  // This call should be eliminated.
+  if (result != 2 * 3 * 5 * 7 * 11 * 13 * 53)
+    g0();
+}
+
diff --git a/test/CodeGen/pascal-string.c b/test/CodeGen/pascal-string.c
new file mode 100644
index 0000000..0a9ee67
--- /dev/null
+++ b/test/CodeGen/pascal-string.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s -fpascal-strings | grep "05Hello"
+
+unsigned char * Foo( void )
+{
+  static unsigned char s[256] = "\pHello";
+  return s;
+}
+
diff --git a/test/CodeGen/pointer-arithmetic.c b/test/CodeGen/pointer-arithmetic.c
new file mode 100644
index 0000000..33465e0
--- /dev/null
+++ b/test/CodeGen/pointer-arithmetic.c
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -S %s -o -
+
+typedef int Int;
+
+int f0(int *a, Int *b) { return a - b; }
+
+int f1(const char *a, char *b) { return b - a; }
+
+// GNU extensions
+typedef void (*FP)(void);
+void *f2(void *a, int b) { return a + b; }
+void *f2_1(void *a, int b) { return (a += b); }
+void *f3(int a, void *b) { return a + b; }
+void *f3_1(int a, void *b) { return (a += b); }
+void *f4(void *a, int b) { return a - b; }
+void *f4_1(void *a, int b) { return (a -= b); }
+FP f5(FP a, int b) { return a + b; }
+FP f5_1(FP a, int b) { return (a += b); }
+FP f6(int a, FP b) { return a + b; }
+FP f6_1(int a, FP b) { return (a += b); }
+FP f7(FP a, int b) { return a - b; }
+FP f7_1(FP a, int b) { return (a -= b); }
diff --git a/test/CodeGen/pointer-cmp-type.c b/test/CodeGen/pointer-cmp-type.c
new file mode 100644
index 0000000..59b2712
--- /dev/null
+++ b/test/CodeGen/pointer-cmp-type.c
@@ -0,0 +1,3 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - | grep "icmp ult"
+
+int a(char* a, char* b) {return a<b;}
diff --git a/test/CodeGen/pointer-to-int.c b/test/CodeGen/pointer-to-int.c
new file mode 100644
index 0000000..30a6db2
--- /dev/null
+++ b/test/CodeGen/pointer-to-int.c
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -emit-llvm %s -o -
+
+int test(void* i)
+{
+  return (int)i;
+}
+
+// rdar://6093986
+int test2(void) {
+  float x[2];
+  return x;
+}
+
diff --git a/test/CodeGen/pragma-pack-1.c b/test/CodeGen/pragma-pack-1.c
new file mode 100644
index 0000000..f5d3016
--- /dev/null
+++ b/test/CodeGen/pragma-pack-1.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -emit-llvm -o - 
+
+// PR4610
+#pragma pack(4)
+struct ref {
+        struct ref *next;
+} refs;
diff --git a/test/CodeGen/pragma-pack-2.c b/test/CodeGen/pragma-pack-2.c
new file mode 100644
index 0000000..bfb34d7
--- /dev/null
+++ b/test/CodeGen/pragma-pack-2.c
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin9 %s -emit-llvm -o - | FileCheck -check-prefix X32 %s
+// CHECK-X32: %struct.s0 = type { i64, i64, i32, [12 x i32] }
+// CHECK-X32: %struct.s1 = type { [15 x i32], %struct.s0 }
+
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -emit-llvm -o - | FileCheck -check-prefix X64 %s
+// CHECK-X64: %struct.s0 = type <{ i64, i64, i32, [12 x i32] }>
+// CHECK-X64: %struct.s1 = type <{ [15 x i32], %struct.s0 }>
+
+// rdar://problem/7095436
+#pragma pack(4)
+
+struct s0 {
+  long long a __attribute__((aligned(8)));
+  long long b __attribute__((aligned(8)));
+  unsigned int c __attribute__((aligned(8)));
+  int d[12];
+} a;
+
+struct s1 {
+  int a[15];
+  struct s0 b;
+} b;
+
diff --git a/test/CodeGen/pragma-pack-3.c b/test/CodeGen/pragma-pack-3.c
new file mode 100644
index 0000000..676f0d7
--- /dev/null
+++ b/test/CodeGen/pragma-pack-3.c
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin9 %s -emit-llvm -o - | FileCheck -check-prefix X32 %s
+// CHECK-X32: %struct.menu = type <{ i8*, i8, i8 }>
+// CHECK-X32: %union.command = type <{ i8*, [2 x i8] }>
+
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -emit-llvm -o - | FileCheck -check-prefix X64 %s
+// CHECK-X64: %struct.menu = type <{ i8*, i8, i8 }>
+// CHECK-X64: %union.command = type <{ i8*, [2 x i8] }>
+
+// <rdar://problem/7184250>
+#pragma pack(push, 2)
+typedef union command {
+  void *windowRef;
+  struct menu {
+    void *menuRef;
+    unsigned char menuItemIndex;
+  } menu;
+} command;
+
+command c;
diff --git a/test/CodeGen/pragma-weak.c b/test/CodeGen/pragma-weak.c
new file mode 100644
index 0000000..5c2866e
--- /dev/null
+++ b/test/CodeGen/pragma-weak.c
@@ -0,0 +1,165 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -verify | FileCheck %s
+
+// CHECK: @weakvar = weak global
+// CHECK: @__weakvar_alias = common global
+// CHECK: @correct_linkage = weak global
+
+
+// CHECK: @both = alias void ()* @__both
+// CHECK: @both2 = alias void ()* @__both2
+// CHECK: @both3 = alias weak void ()* @__both3
+// CHECK: @a3 = alias weak void ()* @__a3
+// CHECK: @weakvar_alias = alias weak i32* @__weakvar_alias
+// CHECK: @foo = alias weak void ()* @__foo
+// CHECK: @foo2 = alias weak void ()* @__foo2
+// CHECK: @stutter = alias weak void ()* @__stutter
+// CHECK: @stutter2 = alias weak void ()* @__stutter2
+// CHECK: @declfirst = alias weak void ()* @__declfirst
+// CHECK: @declfirstattr = alias weak void ()* @__declfirstattr
+// CHECK: @mix2 = alias weak void ()* @__mix2
+// CHECK: @a1 = alias weak void ()* @__a1
+// CHECK: @xxx = alias weak void ()* @__xxx
+
+
+
+// CHECK: define weak void @weakdef()
+
+
+#pragma weak weakvar
+int weakvar;
+
+#pragma weak weakdef
+void weakdef(void) {}
+
+#pragma weak param // expected-warning {{weak identifier 'param' never declared}}
+#pragma weak correct_linkage
+void f(int param) {
+  int correct_linkage;
+}
+
+#pragma weak weakvar_alias = __weakvar_alias
+int __weakvar_alias;
+
+#pragma weak foo = __foo
+void __foo(void) {}
+// CHECK: define void @__foo()
+
+
+void __foo2(void) {}
+#pragma weak foo2 = __foo2
+// CHECK: define void @__foo2()
+
+
+///// test errors
+
+#pragma weak unused // expected-warning {{weak identifier 'unused' never declared}}
+#pragma weak unused_alias = __unused_alias  // expected-warning {{weak identifier '__unused_alias' never declared}}
+
+#pragma weak td // expected-warning {{weak identifier 'td' never declared}}
+typedef int td;
+
+#pragma weak td2 = __td2 // expected-warning {{weak identifier '__td2' never declared}}
+typedef int __td2;
+
+
+///// test weird cases
+
+// test repeats
+
+#pragma weak stutter = __stutter
+#pragma weak stutter = __stutter
+void __stutter(void) {}
+// CHECK: define void @__stutter()
+
+void __stutter2(void) {}
+#pragma weak stutter2 = __stutter2
+#pragma weak stutter2 = __stutter2
+// CHECK: define void @__stutter2()
+
+
+// test decl/pragma weak order
+
+void __declfirst(void);
+#pragma weak declfirst = __declfirst
+void __declfirst(void) {}
+// CHECK: define void @__declfirst()
+
+void __declfirstattr(void) __attribute((noinline));
+#pragma weak declfirstattr = __declfirstattr
+void __declfirstattr(void) {}
+// CHECK: define void @__declfirstattr()
+
+//// test that other attributes are preserved
+
+//// ensure that pragma weak/__attribute((weak)) play nice
+
+void mix(void);
+#pragma weak mix
+__attribute((weak)) void mix(void) { }
+// CHECK: define weak void @mix()
+
+// ensure following __attributes are preserved and that only a single
+// alias is generated
+#pragma weak mix2 = __mix2
+void __mix2(void) __attribute((noinline));
+void __mix2(void) __attribute((noinline));
+void __mix2(void) {}
+// CHECK: define void @__mix2()
+
+////////////// test #pragma weak/__attribute combinations
+
+// if the SAME ALIAS is already declared then it overrides #pragma weak
+// resulting in a non-weak alias in this case
+void both(void) __attribute((alias("__both")));
+#pragma weak both = __both
+void __both(void) {}
+// CHECK: define void @__both()
+
+// if the TARGET is previously declared then whichever aliasing method
+// comes first applies and subsequent aliases are discarded.
+// TODO: warn about this
+
+void __both2(void);
+void both2(void) __attribute((alias("__both2"))); // first, wins
+#pragma weak both2 = __both2
+void __both2(void) {}
+// CHECK: define void @__both2()
+
+void __both3(void);
+#pragma weak both3 = __both3 // first, wins
+void both3(void) __attribute((alias("__both3")));
+void __both3(void) {}
+// CHECK: define void @__both3()
+
+///////////// ensure that #pragma weak does not alter existing __attributes()
+
+void __a1(void) __attribute((noinline));
+#pragma weak a1 = __a1
+void __a1(void) {}
+// CHECK: define void @__a1()
+
+// attributes introduced BEFORE a combination of #pragma weak and alias()
+// hold...
+void __a3(void) __attribute((noinline));
+#pragma weak a3 = __a3
+void a3(void) __attribute((alias("__a3")));
+void __a3(void) {}
+// CHECK: define void @__a3()
+
+#pragma weak xxx = __xxx
+__attribute((pure,noinline,const,fastcall)) void __xxx(void) { }
+// CHECK: void @__xxx()
+
+/// TODO: stuff that still doesn't work
+
+// due to the fact that disparate TopLevelDecls cannot affect each other
+// (due to clang's Parser and ASTConsumer behavior, and quite reasonable)
+// #pragma weak must appear before or within the same TopLevelDecl as it
+// references.
+void yyy(void){}
+void zzz(void){}
+#pragma weak yyy
+// NOTE: weak doesn't apply, not before or in same TopLevelDec(!)
+// CHECK: define void @yyy()
+
+int correct_linkage;
diff --git a/test/CodeGen/predefined-expr.c b/test/CodeGen/predefined-expr.c
new file mode 100644
index 0000000..9be5754
--- /dev/null
+++ b/test/CodeGen/predefined-expr.c
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+
+// CHECK: @__func__.plainFunction = private constant [14 x i8] c"plainFunction\00"
+// CHECK: @__PRETTY_FUNCTION__.plainFunction = private constant [21 x i8] c"void plainFunction()\00"
+// CHECK: @__func__.externFunction = private constant [15 x i8] c"externFunction\00"
+// CHECK: @__PRETTY_FUNCTION__.externFunction = private constant [22 x i8] c"void externFunction()\00"
+// CHECK: @__func__.privateExternFunction = private constant [22 x i8] c"privateExternFunction\00"
+// CHECK: @__PRETTY_FUNCTION__.privateExternFunction = private constant [29 x i8] c"void privateExternFunction()\00"
+// CHECK: @__func__.staticFunction = private constant [15 x i8] c"staticFunction\00"
+// CHECK: @__PRETTY_FUNCTION__.staticFunction = private constant [22 x i8] c"void staticFunction()\00"
+
+int printf(const char *, ...);
+
+void plainFunction() {
+  printf("__func__ %s\n", __func__);
+  printf("__FUNCTION__ %s\n", __FUNCTION__);
+  printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+}
+
+extern void externFunction() {
+  printf("__func__ %s\n", __func__);
+  printf("__FUNCTION__ %s\n", __FUNCTION__);
+  printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+}
+
+__private_extern__ void privateExternFunction() {
+  printf("__func__ %s\n", __func__);
+  printf("__FUNCTION__ %s\n", __FUNCTION__);
+  printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+}
+
+static void staticFunction() {
+  printf("__func__ %s\n", __func__);
+  printf("__FUNCTION__ %s\n", __FUNCTION__);
+  printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+}
+
+int main() {
+  plainFunction();
+  externFunction();
+  privateExternFunction();
+  staticFunction();
+
+  return 0;
+}
diff --git a/test/CodeGen/private-extern.c b/test/CodeGen/private-extern.c
new file mode 100644
index 0000000..2d34d54
--- /dev/null
+++ b/test/CodeGen/private-extern.c
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -emit-llvm -o %t %s
+// RUN: grep '@g0 = external hidden constant i32' %t
+// RUN: grep '@g1 = hidden constant i32 1' %t
+
+__private_extern__ const int g0;
+__private_extern__ const int g1 = 1;
+
+int f0(void) {
+  return g0;
+}
diff --git a/test/CodeGen/rdr-6732143-dangling-block-reference.m b/test/CodeGen/rdr-6732143-dangling-block-reference.m
new file mode 100644
index 0000000..b4d21a3
--- /dev/null
+++ b/test/CodeGen/rdr-6732143-dangling-block-reference.m
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -emit-llvm %s -o -
+
+void f0(id x) {
+  @synchronized (x) {      
+    do { ; } while(0);
+    @try {
+    } @finally {
+    }
+  }
+}
diff --git a/test/CodeGen/regparm.c b/test/CodeGen/regparm.c
new file mode 100644
index 0000000..b60f8c7
--- /dev/null
+++ b/test/CodeGen/regparm.c
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown %s -emit-llvm -o - | FileCheck %s
+
+#define FASTCALL __attribute__((regparm(2)))
+
+typedef struct {
+  int aaa;
+  double bbbb;
+  int ccc[200];
+} foo;
+
+typedef void (*FType)(int, int)      __attribute ((regparm (3), stdcall));
+FType bar;
+
+static void FASTCALL
+reduced(char b, double c, foo* d, double e, int f);
+
+int
+main(void) {
+  // CHECK: call void @reduced(i8 signext inreg 0, {{.*}} %struct.anon* inreg null
+  reduced(0, 0.0, 0, 0.0, 0);
+  // CHECK: call x86_stdcallcc void {{.*}}(i32 inreg 1, i32 inreg 2)
+  bar(1,2);
+}
diff --git a/test/CodeGen/restrict.c b/test/CodeGen/restrict.c
new file mode 100644
index 0000000..8bbff24
--- /dev/null
+++ b/test/CodeGen/restrict.c
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -triple x86_64-darwin-apple -emit-llvm %s -o - | FileCheck %s
+
+// PR6695
+
+// CHECK: define void @test0(i32* %{{.*}}, i32 %{{.*}})
+void test0(int *x, int y) {
+}
+
+// CHECK: define void @test1(i32* noalias %{{.*}}, i32 %{{.*}})
+void test1(int * restrict x, int y) {
+}
+
+// CHECK: define void @test2(i32* %{{.*}}, i32* noalias %{{.*}})
+void test2(int *x, int * restrict y) {
+}
+
+typedef int * restrict rp;
+
+// CHECK: define void @test3(i32* noalias %{{.*}}, i32 %{{.*}})
+void test3(rp x, int y) {
+}
+
+// CHECK: define void @test4(i32* %{{.*}}, i32* noalias %{{.*}})
+void test4(int *x, rp y) {
+}
+
diff --git a/test/CodeGen/shared-string-literals.c b/test/CodeGen/shared-string-literals.c
new file mode 100644
index 0000000..00636b0
--- /dev/null
+++ b/test/CodeGen/shared-string-literals.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -emit-llvm %s -o %t
+
+char *globalString = "abc";
+char *globalStringArray[5] = { "123", "abc" };
+char *anotherGlobalString = "123";
+
+int main() {
+    printf("123");
+}
diff --git a/test/CodeGen/sizeof-vla.c b/test/CodeGen/sizeof-vla.c
new file mode 100644
index 0000000..b0c514f
--- /dev/null
+++ b/test/CodeGen/sizeof-vla.c
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o %t %s
+
+// PR3442
+
+static void *g(unsigned long len);
+
+void
+f(int n)
+{
+ unsigned begin_set[n];
+ 
+ g(sizeof(begin_set));
+}
diff --git a/test/CodeGen/stack-protector.c b/test/CodeGen/stack-protector.c
new file mode 100644
index 0000000..eb4cea2
--- /dev/null
+++ b/test/CodeGen/stack-protector.c
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s -stack-protector 0 | FileCheck -check-prefix=NOSSP %s
+// NOSSP: define void @test1(i8* %msg) nounwind {
+// RUN: %clang_cc1 -emit-llvm -o - %s -stack-protector 1 | FileCheck -check-prefix=WITHSSP %s
+// WITHSSP: define void @test1(i8* %msg) nounwind ssp {
+// RUN: %clang_cc1 -emit-llvm -o - %s -stack-protector 2 | FileCheck -check-prefix=SSPREQ %s
+// SSPREQ: define void @test1(i8* %msg) nounwind sspreq {
+
+int printf(const char * _Format, ...);
+
+void test1(const char *msg) {
+  char a[strlen(msg) + 1];
+  strcpy(a, msg);
+  printf("%s\n", a);
+}
diff --git a/test/CodeGen/statements.c b/test/CodeGen/statements.c
new file mode 100644
index 0000000..e3835f0
--- /dev/null
+++ b/test/CodeGen/statements.c
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 < %s -emit-llvm
+
+void test1(int x) {
+switch (x) {
+case 111111111111111111111111111111111111111:
+bar();
+}
+}
+
+// Mismatched type between return and function result.
+int test2() { return; }
+void test3() { return 4; }
+
+
+void test4() {
+bar:
+baz:
+blong:
+bing:
+ ;
+
+// PR5131
+static long x = &&bar - &&baz;
+static long y = &&baz;
+  &&bing;
+  &&blong;
+  if (y)
+    goto *y;
+
+  goto *x;
+}
+
+// PR3869
+int test5(long long b) { goto *b; }
+
diff --git a/test/CodeGen/static-forward-decl-fun.c b/test/CodeGen/static-forward-decl-fun.c
new file mode 100644
index 0000000..e33ee62
--- /dev/null
+++ b/test/CodeGen/static-forward-decl-fun.c
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 %s -emit-llvm -o %t
+
+static int staticfun(void);
+int (*staticuse1)(void) = staticfun;
+static int staticfun() {return 1;}
+int (*staticuse2)(void) = staticfun;
diff --git a/test/CodeGen/static-forward-decl.c b/test/CodeGen/static-forward-decl.c
new file mode 100644
index 0000000..0d35061
--- /dev/null
+++ b/test/CodeGen/static-forward-decl.c
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple=i686-apple-darwin9 | grep "global i32 10"
+
+static int i;
+int*j=&i;
+static int i = 10;
diff --git a/test/CodeGen/static-local-union.c b/test/CodeGen/static-local-union.c
new file mode 100644
index 0000000..bd32519
--- /dev/null
+++ b/test/CodeGen/static-local-union.c
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -emit-llvm < %s
+
+int a() {static union{int a;} r[2] = {1,2};return r[1].a;}
+
diff --git a/test/CodeGen/static-order.c b/test/CodeGen/static-order.c
new file mode 100644
index 0000000..e7f9814
--- /dev/null
+++ b/test/CodeGen/static-order.c
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+// CHECK: ModuleID
+// CHECK-NOT: zeroinitializer
+// CHECK: define i8* @f
+
+struct s {
+    int a;
+};
+
+static void *v;
+
+static struct s a;
+
+static struct s a = {
+    10
+};
+
+void *f()
+{
+  if (a.a)
+    return v;
+}
diff --git a/test/CodeGen/staticinit.c b/test/CodeGen/staticinit.c
new file mode 100644
index 0000000..cd1f059
--- /dev/null
+++ b/test/CodeGen/staticinit.c
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -triple i386-pc-linux-gnu -emit-llvm -o %t %s
+// RUN: grep "g.b = internal global i8. getelementptr" %t
+
+struct AStruct { 
+  int i;
+  char *s;
+  double d;
+};
+
+void f() {
+  static int i = 42;
+  static int is[] = { 1, 2, 3, 4 };
+  static char* str = "forty-two";
+  static char* strs[] = { "one", "two", "three", "four" };
+  static struct AStruct myStruct = { 1, "two", 3.0 };
+}
+
+void g() {
+  static char a[10];
+  static char *b = a;
+}
+
+struct s { void *p; };
+
+void foo(void) {
+  static struct s var = {((void*)&((char*)0)[0])};
+}
+
+// RUN: grep "f1.l0 = internal global i32 ptrtoint (i32 ()\* @f1 to i32)" %t
+int f1(void) { static int l0 = (unsigned) f1; }
+
diff --git a/test/CodeGen/stdcall-fastcall.c b/test/CodeGen/stdcall-fastcall.c
new file mode 100644
index 0000000..bea6df3
--- /dev/null
+++ b/test/CodeGen/stdcall-fastcall.c
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -emit-llvm < %s | FileCheck %s
+
+void __attribute__((fastcall)) f1(void);
+void __attribute__((stdcall)) f2(void);
+void __attribute__((fastcall)) f3(void) {
+// CHECK: define x86_fastcallcc void @f3()
+  f1();
+// CHECK: call x86_fastcallcc void @f1()
+}
+void __attribute__((stdcall)) f4(void) {
+// CHECK: define x86_stdcallcc void @f4()
+  f2();
+// CHECK: call x86_stdcallcc void @f2()
+}
+
+// PR5280
+void (__attribute__((fastcall)) *pf1)(void) = f1;
+void (__attribute__((stdcall)) *pf2)(void) = f2;
+void (__attribute__((fastcall)) *pf3)(void) = f3;
+void (__attribute__((stdcall)) *pf4)(void) = f4;
+
+int main(void) {
+    f3(); f4();
+    // CHECK: call x86_fastcallcc void @f3()
+    // CHECK: call x86_stdcallcc void @f4()
+    pf1(); pf2(); pf3(); pf4();
+    // CHECK: call x86_fastcallcc void %{{.*}}()
+    // CHECK: call x86_stdcallcc void %{{.*}}()
+    // CHECK: call x86_fastcallcc void %{{.*}}()
+    // CHECK: call x86_stdcallcc void %{{.*}}()
+    return 0;
+}
+
diff --git a/test/CodeGen/string-literal.c b/test/CodeGen/string-literal.c
new file mode 100644
index 0000000..22a81e7
--- /dev/null
+++ b/test/CodeGen/string-literal.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -emit-llvm %s -o -
+
+int main() {
+  char a[10] = "abc";
+
+  void *foo = L"AB";
+}
diff --git a/test/CodeGen/struct-comma.c b/test/CodeGen/struct-comma.c
new file mode 100644
index 0000000..e5b5151
--- /dev/null
+++ b/test/CodeGen/struct-comma.c
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 %s -emit-llvm -o -
+
+struct S {int a, b;} x;
+void a(struct S* b) {*b = (r(), x);}
diff --git a/test/CodeGen/struct-copy.c b/test/CodeGen/struct-copy.c
new file mode 100644
index 0000000..6f3b664
--- /dev/null
+++ b/test/CodeGen/struct-copy.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - | grep 'call.*llvm.memcpy'
+struct x { int a[100]; };
+
+
+void foo(struct x *P, struct x *Q) {
+  *P = *Q;
+}
diff --git a/test/CodeGen/struct-init.c b/test/CodeGen/struct-init.c
new file mode 100644
index 0000000..88b57a2
--- /dev/null
+++ b/test/CodeGen/struct-init.c
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 %s -emit-llvm -o -
+
+typedef struct _zend_ini_entry zend_ini_entry;
+struct _zend_ini_entry {
+  void *mh_arg1;
+};
+
+char a;
+
+const zend_ini_entry ini_entries[] = {
+  {  ((char*)&((zend_ini_entry*)0)->mh_arg1 - (char*)(void*)0)},
+};
diff --git a/test/CodeGen/struct-passing.c b/test/CodeGen/struct-passing.c
new file mode 100644
index 0000000..409d14e
--- /dev/null
+++ b/test/CodeGen/struct-passing.c
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -triple i386-pc-linux-gnu -emit-llvm -o %t %s
+// RUN: grep 'declare i32 @f0() readnone$' %t
+// RUN: grep 'declare i32 @f1() readonly$' %t
+// RUN: grep 'declare void @f2(.* sret)$' %t
+// RUN: grep 'declare void @f3(.* sret)$' %t
+// RUN: grep 'declare void @f4(.* byval)$' %t
+// RUN: grep 'declare void @f5(.* byval)$' %t
+// PR3835
+
+typedef int T0;
+typedef struct { int a[16]; } T1;
+
+T0 __attribute__((const)) f0(void);
+T0 __attribute__((pure)) f1(void);
+T1 __attribute__((const)) f2(void);
+T1 __attribute__((pure)) f3(void);
+void __attribute__((const)) f4(T1 a);
+void __attribute__((pure)) f5(T1 a);
+
+void *ps[] = { f0, f1, f2, f3, f4, f5 };
diff --git a/test/CodeGen/struct-x86-darwin.c b/test/CodeGen/struct-x86-darwin.c
new file mode 100644
index 0000000..afdcb8a
--- /dev/null
+++ b/test/CodeGen/struct-x86-darwin.c
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 < %s -emit-llvm > %t1 -triple=i686-apple-darwin9
+// RUN: grep "STest1 = type { i32, \[4 x i16\], double }" %t1
+// RUN: grep "STest2 = type { i16, i16, i32, i32 }" %t1
+// RUN: grep "STest3 = type { i8, i16, i32 }" %t1
+// RUN: grep "STestB1 = type { i8, i8 }" %t1
+// RUN: grep "STestB2 = type { i8, i8, i8 }" %t1
+// RUN: grep "STestB3 = type { i8, i8 }" %t1
+// RUN: grep "STestB4 = type { i8, i8, i8, i8 }" %t1
+// RUN: grep "STestB5 = type { i8, i8, \[2 x i8\], i8, i8 }" %t1
+// RUN: grep "STestB6 = type { i8, i8, \[2 x i8\] }" %t1
+// Test struct layout for x86-darwin target
+
+struct STest1 {int x; short y[4]; double z; } st1;
+struct STest2 {short a,b; int c,d; } st2;
+struct STest3 {char a; short b; int c; } st3;
+
+// Bitfields 
+struct STestB1 {char a; char b:2; } stb1;
+struct STestB2 {char a; char b:5; char c:4; } stb2;
+struct STestB3 {char a; char b:2; } stb3;
+struct STestB4 {char a; short b:2; char c; } stb4;
+struct STestB5 {char a; short b:10; char c; } stb5;
+struct STestB6 {int a:1; char b; int c:13 } stb6;
+
+// Packed struct STestP1 {char a; short b; int c; } __attribute__((__packed__)) stp1;
diff --git a/test/CodeGen/struct.c b/test/CodeGen/struct.c
new file mode 100644
index 0000000..25477a0
--- /dev/null
+++ b/test/CodeGen/struct.c
@@ -0,0 +1,183 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown %s -emit-llvm -o -
+
+struct  {
+  int x;
+  int y;
+} point;
+
+void fn1() {
+  point.x = 42;
+}
+
+/* Nested member */
+struct  {
+  struct {
+    int a;
+    int b;
+  } p1;
+} point2;
+
+void fn2() {
+  point2.p1.a = 42;
+}
+
+/* Indirect reference */
+typedef struct __sf {
+ unsigned char *c;
+ short flags;
+} F;
+
+typedef struct __sf2 {
+  F *ff;
+} F2;
+
+int fn3(F2 *c) {
+  if (c->ff->c >= 0)
+    return 1;
+  else
+    return 0;
+}
+
+/* Nested structs */
+typedef struct NA {
+  int data;
+  struct NA *next;
+} NA;
+void f1() {  NA a; }
+
+typedef struct NB {
+  int d1;
+  struct _B2 {
+    int d2;
+    struct NB *n2;
+  } B2;
+} NB;
+
+void f2() { NB b; }
+
+extern NB *f3();
+void f4() {
+  f3()->d1 = 42;
+}
+
+void f5() {
+  (f3())->d1 = 42;
+}
+
+/* Function calls */
+typedef struct {
+  int location;
+  int length;
+} range;
+extern range f6();
+void f7() {
+  range r = f6();
+}
+
+/* Member expressions */
+typedef struct {
+  range range1;
+  range range2;
+} rangepair;
+
+void f8() {
+  rangepair p;
+
+  range r = p.range1;
+}
+
+void f9(range *p) {
+  range r = *p;
+}
+
+void f10(range *p) {
+  range r = p[0];
+}
+
+/* _Bool types */
+
+struct _w {
+  short a,b;
+  short c,d;
+  short e,f;
+  short g;
+
+  unsigned int h,i;
+
+  _Bool j,k;
+} ws;
+
+/* Implicit casts (due to typedefs) */
+typedef struct _a {
+  int a;
+} a;
+
+void f11() {
+  struct _a a1;
+  a a2;
+    
+  a1 = a2;
+  a2 = a1;
+}
+
+/* Implicit casts (due to const) */
+void f12() {
+  struct _a a1;
+  const struct _a a2;
+
+  a1 = a2;
+}
+
+/* struct initialization */
+struct a13 {int b; int c;};
+struct a13 c13 = {5};
+typedef struct a13 a13;
+struct a14 { short a; int b; } x = {1, 1};
+
+/* flexible array members */
+struct a15 {char a; int b[];} c15;
+int a16(void) {c15.a = 1;}
+
+/* compound literals */
+void f13() {
+  a13 x; x = (a13){1,2};
+}
+
+/* va_arg */
+int f14(int i, ...) {
+  __builtin_va_list l;
+  __builtin_va_start(l,i);
+  a13 b = __builtin_va_arg(l, a13);
+  int c = __builtin_va_arg(l, a13).c;
+  return b.b;
+}
+
+/* Attribute packed */
+struct __attribute__((packed)) S2839 { double a[19];  signed char b; } s2839[5];
+
+struct __attribute__((packed)) SS { long double a; char b; } SS;
+
+
+/* As lvalue */
+
+int f15() {
+  extern range f15_ext();
+  return f15_ext().location;
+}
+
+range f16() {
+  extern rangepair f16_ext();
+  return f16_ext().range1;
+}
+
+int f17() {
+  extern range f17_ext();
+  range r;
+  return (r = f17_ext()).location;
+}
+
+range f18() {
+  extern rangepair f18_ext();
+  rangepair rp;
+  return (rp = f18_ext()).range1;
+}
diff --git a/test/CodeGen/switch.c b/test/CodeGen/switch.c
new file mode 100644
index 0000000..dc2d27b
--- /dev/null
+++ b/test/CodeGen/switch.c
@@ -0,0 +1,196 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown -O3 %s -emit-llvm -o - | FileCheck %s
+
+int foo(int i) {
+  int j = 0;
+  switch (i) {
+  case -1:
+    j = 1; break;
+  case 1 :
+    j = 2; break;
+  case 2:
+    j = 3; break;
+  default:
+    j = 42; break;
+  }
+  j = j + 1;
+  return j;
+}
+
+int foo2(int i) {
+  int j = 0;
+  switch (i) {
+  case 1 :
+    j = 2; break;
+  case 2 ... 10:
+    j = 3; break;
+  default:
+    j = 42; break;
+  }
+  j = j + 1;
+  return j;
+}
+
+int foo3(int i) {
+  int j = 0;
+  switch (i) {
+  default:
+    j = 42; break;
+  case 111:
+    j = 111; break;
+  case 0 ... 100:
+    j = 1; break;
+  case 222:
+    j = 222; break;
+  }
+  return j;
+}
+
+
+static int foo4(int i) {
+  int j = 0;
+  switch (i) {
+  case 111:
+    j = 111; break;
+  case 0 ... 100:
+    j = 1; break;
+  case 222:
+    j = 222; break;
+  default:
+    j = 42; break;
+  case 501 ... 600:
+    j = 5; break;
+  }
+  return j;
+}
+
+// CHECK: define i32 @foo4t()
+// CHECK: ret i32 376
+// CHECK: }
+int foo4t() {
+  // 111 + 1 + 222 + 42 = 376
+  return foo4(111) + foo4(99) + foo4(222) + foo4(601);
+}
+
+// CHECK: define void @foo5()
+// CHECK-NOT: switch
+// CHECK: }
+void foo5(){
+    switch(0){
+    default:
+        if (0) {
+
+        }
+    }
+}
+
+// CHECK: define void @foo6()
+// CHECK-NOT: switch
+// CHECK: }
+void foo6(){
+    switch(0){
+    }
+}
+
+// CHECK: define void @foo7()
+// CHECK-NOT: switch
+// CHECK: }
+void foo7(){
+    switch(0){
+      foo7();
+    }
+}
+
+
+// CHECK: define i32 @f8(
+// CHECK: ret i32 3
+// CHECK: }
+int f8(unsigned x) {
+  switch(x) {
+  default:
+    return 3;
+  case 0xFFFFFFFF ... 1: // This range should be empty because x is unsigned.
+    return 0;
+  }
+}
+
+// Ensure that default after a case range is not ignored.
+//
+// CHECK: define i32 @f9()
+// CHECK: ret i32 10
+// CHECK: }
+static int f9_0(unsigned x) {
+  switch(x) {
+  case 10 ... 0xFFFFFFFF:
+    return 0;
+  default:
+    return 10;
+  }
+}
+int f9() {
+  return f9_0(2);
+}
+
+// Ensure that this doesn't compile to infinite loop in g() due to
+// miscompilation of fallthrough from default to a (tested) case
+// range.
+//
+// CHECK: define i32 @f10()
+// CHECK: ret i32 10
+// CHECK: }
+static int f10_0(unsigned x) {
+  switch(x) {
+  default:
+    x += 1;
+  case 10 ... 0xFFFFFFFF:
+    return 0;
+  }
+}
+
+int f10() {
+  f10_0(1);
+  return 10;
+}
+
+// This generated incorrect code because of poor switch chaining.
+//
+// CHECK: define i32 @f11(
+// CHECK: ret i32 3
+// CHECK: }
+int f11(int x) {
+  switch(x) {
+  default:
+    return 3;
+  case 10 ... 0xFFFFFFFF:
+    return 0;
+  }
+}
+
+// This just asserted because of the way case ranges were calculated.
+//
+// CHECK: define i32 @f12(
+// CHECK: ret i32 3
+// CHECK: }
+int f12(int x) {
+  switch (x) {
+  default:
+    return 3;
+  case 10 ... -1: 
+    return 0;
+  }
+}
+
+// Make sure return is not constant (if empty range is skipped or miscompiled)
+//
+// CHECK: define i32 @f13(
+// CHECK: ret i32 %
+// CHECK: }
+int f13(unsigned x) {
+  switch(x) {
+  case 2:
+    // fallthrough empty range
+  case 10 ... 9:
+    return 10;
+  default:
+    return 0;
+  }
+}
diff --git a/test/CodeGen/target-data.c b/test/CodeGen/target-data.c
new file mode 100644
index 0000000..8139a4e
--- /dev/null
+++ b/test/CodeGen/target-data.c
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -triple i686-unknown-unknown -emit-llvm -o %t %s
+// RUN: grep 'target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32"' %t
+// RUN: %clang_cc1 -triple i686-apple-darwin9 -emit-llvm -o %t %s
+// RUN: grep 'target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128-n8:16:32"' %t
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o %t %s
+// RUN: grep 'target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"' %t
diff --git a/test/CodeGen/tentative-decls.c b/test/CodeGen/tentative-decls.c
new file mode 100644
index 0000000..d88c346
--- /dev/null
+++ b/test/CodeGen/tentative-decls.c
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -emit-llvm -o %t %s
+
+// RUN: grep '@r = common global \[1 x .*\] zeroinitializer' %t
+
+int r[];
+int (*a)[] = &r;
+
+struct s0;
+struct s0 x;
+// RUN: grep '@x = common global .struct.s0 zeroinitializer' %t
+
+struct s0 y;
+// RUN: grep '@y = common global .struct.s0 zeroinitializer' %t
+struct s0 *f0() {
+  return &y;
+}
+
+struct s0 {
+  int x;
+};
+
+// RUN: grep '@b = common global \[1 x .*\] zeroinitializer' %t
+int b[];
+int *f1() {
+  return b;
+}
+
+// Check that the most recent tentative definition wins.
+// RUN: grep '@c = common global \[4 x .*\] zeroinitializer' %t
+int c[];
+int c[4];
+
+// Check that we emit static tentative definitions
+// RUN: grep '@c5 = internal global \[1 x .*\] zeroinitializer' %t
+static int c5[];
+static int func() { return c5[0]; }
+int callfunc() { return func(); }
+
diff --git a/test/CodeGen/thread-specifier.c b/test/CodeGen/thread-specifier.c
new file mode 100644
index 0000000..b1e1ed8
--- /dev/null
+++ b/test/CodeGen/thread-specifier.c
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -triple i686-pc-linux-gnu -emit-llvm -o - %s | grep thread_local | count 4
+
+__thread int a;
+extern __thread int b;
+int c() { return &b; }
+int d() {
+  __thread static int e;
+  __thread static union {float a; int b;} f = {.b = 1};
+}
+
diff --git a/test/CodeGen/trapv.c b/test/CodeGen/trapv.c
new file mode 100644
index 0000000..d10d617
--- /dev/null
+++ b/test/CodeGen/trapv.c
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -ftrapv %s -emit-llvm -o %t
+// RUN: grep "__overflow_handler" %t | count 2
+
+unsigned int ui, uj, uk;
+int i, j, k;
+
+void foo() {
+  ui = uj + uk;
+  i = j + k;
+}
diff --git a/test/CodeGen/typedef-func.c b/test/CodeGen/typedef-func.c
new file mode 100644
index 0000000..bc08b35
--- /dev/null
+++ b/test/CodeGen/typedef-func.c
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -emit-llvm < %s
+
+// PR2414
+struct mad_frame{};
+enum mad_flow {};
+
+typedef enum mad_flow filter_func_t(void *, struct mad_frame *);
+
+filter_func_t mono_filter;
+
+void addfilter2(filter_func_t *func){}
+
+void setup_filters()
+{
+  addfilter2( mono_filter);
+}
diff --git a/test/CodeGen/typedef.c b/test/CodeGen/typedef.c
new file mode 100644
index 0000000..4af9d81
--- /dev/null
+++ b/test/CodeGen/typedef.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -emit-llvm %s -o -
+
+typedef struct { int i; } Value;
+typedef Value *PValue;
+
+int get_value(PValue v) {
+  return v->i;
+}
diff --git a/test/CodeGen/types.c b/test/CodeGen/types.c
new file mode 100644
index 0000000..55b806c
--- /dev/null
+++ b/test/CodeGen/types.c
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -emit-llvm <%s
+
+struct FileName {
+    struct FileName *next;
+} *fnhead;
+
+
+struct ieeeExternal {
+    struct ieeeExternal *next;
+} *exthead;
+
+
+void test1()
+{
+    struct ieeeExternal *exttmp = exthead;
+}
+
+struct MpegEncContext;
+typedef struct MpegEncContext {int pb;} MpegEncContext;
+static void test2(void) {MpegEncContext s; s.pb;}
+
+
+struct Village;
+
+struct List {
+  struct Village *v;
+};
+
+struct Village {
+  struct List returned;
+};
+
+void test3(struct List a) {
+}
diff --git a/test/CodeGen/uint128_t.c b/test/CodeGen/uint128_t.c
new file mode 100644
index 0000000..92cb5fa
--- /dev/null
+++ b/test/CodeGen/uint128_t.c
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple=x86_64-apple-darwin9
+
+typedef unsigned long long uint64_t;
+extern uint64_t numer;
+extern uint64_t denom;
+
+uint64_t
+f(uint64_t val)
+{
+    __uint128_t tmp;
+
+    tmp = val;
+    tmp *= numer;
+    tmp /= denom;
+
+    return tmp;
+}
+
diff --git a/test/CodeGen/union-init.c b/test/CodeGen/union-init.c
new file mode 100644
index 0000000..60906b5
--- /dev/null
+++ b/test/CodeGen/union-init.c
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -emit-llvm < %s -o -
+
+// A nice and complicated initialization example with unions from Python
+typedef int Py_ssize_t;
+
+typedef union _gc_head {
+  struct {
+    union _gc_head *gc_next;
+    union _gc_head *gc_prev;
+    Py_ssize_t gc_refs;
+  } gc;
+  long double dummy;  /* force worst-case alignment */
+} PyGC_Head;
+
+struct gc_generation {
+  PyGC_Head head;
+  int threshold; /* collection threshold */
+  int count;     /* count of allocations or collections of younger
+                    generations */
+};
+
+#define NUM_GENERATIONS 3
+#define GEN_HEAD(n) (&generations[n].head)
+
+/* linked lists of container objects */
+struct gc_generation generations[NUM_GENERATIONS] = {
+  /* PyGC_Head,                     threshold,      count */
+  {{{GEN_HEAD(0), GEN_HEAD(0), 0}}, 700,            0},
+  {{{GEN_HEAD(1), GEN_HEAD(1), 0}},  10,            0},
+  {{{GEN_HEAD(2), GEN_HEAD(2), 0}},  10,            0},
+};
diff --git a/test/CodeGen/union-init2.c b/test/CodeGen/union-init2.c
new file mode 100644
index 0000000..1386c27
--- /dev/null
+++ b/test/CodeGen/union-init2.c
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple i686-pc-linux-gnu | FileCheck %s
+
+// Make sure we generate something sane instead of a ptrtoint
+// CHECK: bitcast (%0* @r to %union.x*), [4 x i8] undef
+union x {long long b;union x* a;} r = {.a = &r};
+
+
+// CHECK: global %1 { [3 x i8] zeroinitializer, [5 x i8] undef }
+union z {
+  char a[3];
+  long long b;
+};
+union z y = {};
diff --git a/test/CodeGen/union.c b/test/CodeGen/union.c
new file mode 100644
index 0000000..1883ca6
--- /dev/null
+++ b/test/CodeGen/union.c
@@ -0,0 +1,44 @@
+// RUN: %clang_cc1 %s -emit-llvm -o -
+
+union u_tag {
+  int a;
+  float b;
+} u;
+
+void f() {
+  u.b = 11;
+}
+
+float get_b(union u_tag *my_u) {
+  return my_u->b;
+}
+
+int f2( float __x ) { 
+  union{ 
+    float __f; 
+    unsigned int __u; 
+  }__u;
+  return (int)(__u.__u >> 31); 
+}
+
+typedef union { int i; int *j; } value;
+
+int f3(value v) {
+  return *v.j;
+}
+
+enum E9 { one, two };
+union S65 { enum E9 a; } ; union S65 s65;
+void fS65() { enum E9 e = s65.a; } 
+
+typedef union{
+  unsigned char x[65536];
+} q;
+int qfunc() {q buf; unsigned char* x = buf.x;}
+
+union RR {_Bool a : 1;} RRU;
+int RRF(void) {return RRU.a;}
+
+// PR6164
+typedef union T0 { unsigned int : 0; } T0;
+T0 t0;
diff --git a/test/CodeGen/unreachable.c b/test/CodeGen/unreachable.c
new file mode 100644
index 0000000..5e9fa6a
--- /dev/null
+++ b/test/CodeGen/unreachable.c
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 -emit-llvm -o %t %s
+// RUN: grep '@unreachable' %t | count 0
+
+extern void abort() __attribute__((noreturn));
+extern int unreachable();
+
+int f0() {
+  return 0;
+  unreachable();
+}
+
+int f1(int i) {
+  goto L0;
+  int a = unreachable();
+ L0:
+  return 0;
+}
+
+int f2(int i) {
+  goto L0;
+  unreachable();
+  int a;
+  unreachable();
+ L0:
+  a = i + 1;
+  return a;
+}
+
+int f3(int i) {
+  if (i) {
+    return 0;
+  } else {
+    abort();
+  }
+  unreachable();
+  return 3;
+}
diff --git a/test/CodeGen/unwind-attr.c b/test/CodeGen/unwind-attr.c
new file mode 100644
index 0000000..ee3199d
--- /dev/null
+++ b/test/CodeGen/unwind-attr.c
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -fexceptions -emit-llvm -o - %s | grep "@foo()" | not grep nounwind
+// RUN: %clang_cc1 -emit-llvm -o - %s | grep "@foo()" | grep nounwind 
+
+int foo(void) {
+  return 0;
+}
diff --git a/test/CodeGen/var-align.c b/test/CodeGen/var-align.c
new file mode 100644
index 0000000..fefd35a
--- /dev/null
+++ b/test/CodeGen/var-align.c
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - | grep "align 16" | count 2
+
+__attribute((aligned(16))) float a[128];
+union {int a[4]; __attribute((aligned(16))) float b[4];} u;
diff --git a/test/CodeGen/varargs.c b/test/CodeGen/varargs.c
new file mode 100644
index 0000000..b3dba24
--- /dev/null
+++ b/test/CodeGen/varargs.c
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s
+
+
+// PR6433 - Don't crash on va_arg(typedef).
+typedef double gdouble;
+void focus_changed_cb () {
+    __builtin_va_list pa;
+    double mfloat;
+    mfloat = __builtin_va_arg((pa), gdouble);
+}
+
diff --git a/test/CodeGen/variable-array.c b/test/CodeGen/variable-array.c
new file mode 100644
index 0000000..80ca78d
--- /dev/null
+++ b/test/CodeGen/variable-array.c
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -emit-llvm < %s | grep puts | count 4
+
+// PR3248
+int a(int x)
+{
+  int (*y)[x];
+  return sizeof(*(puts("asdf"),y));
+}
+
+// PR3247
+int b() {
+  return sizeof(*(char(*)[puts("asdf")])0);
+}
+
+// PR3247
+int c() {
+  static int (*y)[puts("asdf")];
+  return sizeof(*y);
+}
diff --git a/test/CodeGen/vector.c b/test/CodeGen/vector.c
new file mode 100644
index 0000000..c16d65b
--- /dev/null
+++ b/test/CodeGen/vector.c
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -target-cpu pentium4 -g -emit-llvm %s -o -
+typedef short __v4hi __attribute__ ((__vector_size__ (8)));
+
+void test1() {
+  __v4hi A = (__v4hi)0LL;
+}
+
+__v4hi x = {1,2,3};
+__v4hi y = {1,2,3,4};
+
+typedef int vty __attribute((vector_size(16)));
+int test2() { vty b; return b[2LL]; }
+
+// PR4339
+typedef float vec4 __attribute__((vector_size(16)));
+
+void test3 ( vec4* a, char b, float c ) {
+  (*a)[b] = c;
+}
+
+
+
+
+#include <mmintrin.h>
+
+int test4(int argc, char *argv[]) {
+  int array[16] = { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 };
+  __m64 *p = (__m64 *)array;
+
+  __m64 accum = _mm_setzero_si64();
+
+  for (int i=0; i<8; ++i)
+     accum = _mm_add_pi32(p[i], accum);
+
+  __m64 accum2 = _mm_unpackhi_pi32(accum, accum);
+  accum = _mm_add_pi32(accum, accum2);
+
+  int result = _mm_cvtsi64_si32(accum);
+  _mm_empty();
+
+  return result;
+}
diff --git a/test/CodeGen/vfprintf.c b/test/CodeGen/vfprintf.c
new file mode 100644
index 0000000..7c583b5
--- /dev/null
+++ b/test/CodeGen/vfprintf.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -emit-llvm-only %s
+
+typedef struct _IO_FILE FILE;
+int vfprintf(FILE*restrict,const char*restrict, __builtin_va_list);
+void foo(__builtin_va_list ap) {
+  vfprintf(0, " ", ap);
+}
+
diff --git a/test/CodeGen/visibility.c b/test/CodeGen/visibility.c
new file mode 100644
index 0000000..8f81c8f
--- /dev/null
+++ b/test/CodeGen/visibility.c
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown -fvisibility default -emit-llvm -o %t %s
+// RUN: grep '@g_com = common global i32 0' %t
+// RUN: grep '@g_def = global i32 0' %t
+// RUN: grep '@g_ext = external global i32' %t
+// RUN: grep '@g_deferred = internal global' %t
+// RUN: grep 'declare void @f_ext()' %t
+// RUN: grep 'define internal void @f_deferred()' %t
+// RUN: grep 'define i32 @f_def()' %t
+// RUN: %clang_cc1 -triple i386-unknown-unknown -fvisibility protected -emit-llvm -o %t %s
+// RUN: grep '@g_com = common protected global i32 0' %t
+// RUN: grep '@g_def = protected global i32 0' %t
+// RUN: grep '@g_ext = external global i32' %t
+// RUN: grep '@g_deferred = internal global' %t
+// RUN: grep 'declare void @f_ext()' %t
+// RUN: grep 'define internal void @f_deferred()' %t
+// RUN: grep 'define protected i32 @f_def()' %t
+// RUN: %clang_cc1 -triple i386-unknown-unknown -fvisibility hidden -emit-llvm -o %t %s
+// RUN: grep '@g_com = common hidden global i32 0' %t
+// RUN: grep '@g_def = hidden global i32 0' %t
+// RUN: grep '@g_ext = external global i32' %t
+// RUN: grep '@g_deferred = internal global' %t
+// RUN: grep 'declare void @f_ext()' %t
+// RUN: grep 'define internal void @f_deferred()' %t
+// RUN: grep 'define hidden i32 @f_def()' %t
+
+int g_com;
+int g_def = 0;
+extern int g_ext;
+static char g_deferred[] = "hello";
+
+extern void f_ext(void);
+
+static void f_deferred(void) {
+}
+
+int f_def(void) {
+  f_ext();
+  f_deferred();
+  return g_com + g_def + g_ext + g_deferred[0];
+}
diff --git a/test/CodeGen/vla.c b/test/CodeGen/vla.c
new file mode 100644
index 0000000..0c53900
--- /dev/null
+++ b/test/CodeGen/vla.c
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 %s -emit-llvm -o %t
+
+int b(char* x);
+
+// Extremely basic VLA test
+void a(int x) {
+  char arry[x];
+  arry[0] = 10;
+  b(arry);
+}
+
+int c(int n)
+{
+  return sizeof(int[n]);
+}
+
+int f0(int x) {
+  int vla[x];
+  return vla[x-1];
+}
+
+void
+f(int count)
+{
+ int a[count];
+
+  do {  } while (0);
+
+  if (a[0] != 3) {
+  }
+}
+
+void g(int count) {
+  // Make sure we emit sizes correctly in some obscure cases
+  int (*a[5])[count];
+  int (*b)[][count];
+}
diff --git a/test/CodeGen/volatile-1.c b/test/CodeGen/volatile-1.c
new file mode 100644
index 0000000..e0c672b
--- /dev/null
+++ b/test/CodeGen/volatile-1.c
@@ -0,0 +1,143 @@
+// RUN: %clang_cc1 -Wno-unused-value -emit-llvm < %s -o %t
+// RUN: grep volatile %t | count 145
+// RUN: grep memcpy %t | count 4
+
+volatile int i, j, k;
+volatile int ar[5];
+volatile char c;
+volatile _Complex int ci;
+volatile struct S {
+#ifdef __cplusplus
+  void operator =(volatile struct S&o) volatile;
+#endif
+  int i;
+} a, b;
+
+//void operator =(volatile struct S&o1, volatile struct S&o2) volatile;
+int printf(const char *, ...);
+
+int main() {
+  // A use.
+  i;
+  // A use of the real part
+  (float)(ci);
+  // A use.
+  (void)ci;
+  // A use.
+  (void)a;
+  // Not a use.
+  (void)(ci=ci);
+  // Not a use.
+  (void)(i=j);
+  ci+=ci;
+  (ci += ci) + ci;
+  asm("nop");
+  (i += j) + k;
+  asm("nop");
+  // A use
+  (i += j) + 1;
+  asm("nop");
+  ci+ci;
+  // A use.
+  __real i;
+  // A use.
+  +ci;
+  asm("nop");
+  // Not a use.
+  (void)(i=i);
+  (float)(i=i);
+  // A use.
+  (void)i;
+  i=i;
+  i=i=i;
+#ifndef __cplusplus
+  // Not a use.
+  (void)__builtin_choose_expr(0, i=i, j=j);
+#endif
+  // A use.
+  k ? (i=i) : (j=j);
+  (void)(i,(i=i));
+  i=i,i;
+  (i=j,k=j);
+  (i=j,k);
+  (i,j);
+  i=c=k;
+  i+=k;
+  // A use of both.
+  ci;
+#ifndef __cplusplus
+  // A use of _real.
+  (int)ci;
+  // A use of both.
+  (_Bool)ci;
+#endif
+  ci=ci;
+  ci=ci=ci;
+  __imag ci = __imag ci = __imag ci;
+  // Not a use.
+  __real (i = j);
+  // Not a use.
+  __imag i;
+  
+  // ============================================================
+  // FIXME: Test cases we get wrong.
+
+  // A use.  We load all of a into a copy of a, then load i.  gcc forgets to do
+  // the assignment.
+  // (a = a).i;
+
+  // ============================================================
+  // Test cases where we intentionally differ from gcc, due to suspected bugs in
+  // gcc.
+
+  // Not a use.  gcc forgets to do the assignment.
+  ((a=a),a);
+
+  // Not a use.  gcc gets this wrong, it doesn't emit the copy!  
+  // (void)(a=a);
+
+  // Not a use.  gcc got this wrong in 4.2 and omitted the side effects
+  // entirely, but it is fixed in 4.4.0.
+  __imag (i = j);
+
+#ifndef __cplusplus
+  // A use of the real part
+  (float)(ci=ci);
+  // Not a use, bug?  gcc treats this as not a use, that's probably a bug due to
+  // tree folding ignoring volatile.
+  (int)(ci=ci);
+#endif
+
+  // A use.
+  (float)(i=i);
+  // A use.  gcc treats this as not a use, that's probably a bug due to tree
+  // folding ignoring volatile.
+  (int)(i=i);
+
+  // A use.
+  -(i=j);
+  // A use.  gcc treats this a not a use, that's probably a bug due to tree
+  // folding ignoring volatile.
+  +(i=k);
+
+  // A use. gcc treats this a not a use, that's probably a bug due to tree
+  // folding ignoring volatile.
+  __real (ci=ci);
+
+  // A use.
+  i + 0;
+  // A use.
+  (i=j) + i;
+  // A use.  gcc treats this as not a use, that's probably a bug due to tree
+  // folding ignoring volatile.
+  (i=j) + 0;
+
+#ifdef __cplusplus
+  (i,j)=k;
+  (j=k,i)=i;
+  struct { int x; } s, s1;
+  printf("s is at %p\n", &s);
+  printf("s is at %p\n", &(s = s1));
+  printf("s.x is at %p\n", &((s = s1).x));
+#endif
+}
diff --git a/test/CodeGen/volatile.c b/test/CodeGen/volatile.c
new file mode 100644
index 0000000..db87a37
--- /dev/null
+++ b/test/CodeGen/volatile.c
@@ -0,0 +1,100 @@
+// RUN: %clang_cc1 -emit-llvm < %s -o %t
+// RUN: grep volatile %t | count 29
+// RUN: grep memcpy %t | count 7
+
+// The number 29 comes from the current codegen for volatile loads;
+// if this number changes, it's not necessarily something wrong, but
+// something has changed to affect volatile load/store codegen
+
+int S;
+volatile int vS;
+
+int* pS;
+volatile int* pvS;
+
+int A[10];
+volatile int vA[10];
+
+struct { int x; } F;
+struct { volatile int x; } vF;
+
+struct { int x; } F2;
+volatile struct { int x; } vF2;
+volatile struct { int x; } *vpF2;
+
+struct { struct { int y; } x; } F3;
+volatile struct { struct { int y; } x; } vF3;
+
+struct { int x:3; } BF;
+struct { volatile int x:3; } vBF;
+
+typedef int v4si __attribute__ ((vector_size (16)));
+v4si V;
+volatile v4si vV;
+
+typedef __attribute__(( ext_vector_type(4) )) int extv4;
+extv4 VE;
+volatile extv4 vVE;
+
+volatile struct {int x;} aggFct(void);
+
+typedef volatile int volatile_int;
+volatile_int vtS;
+
+int main() {
+  int i;
+
+  // load
+  i=S;
+  i=vS;
+  i=*pS;
+  i=*pvS;
+  i=A[2];
+  i=vA[2];
+  i=F.x;
+  i=vF.x;
+  i=F2.x;
+  i=vF2.x;
+  i=vpF2->x;
+  i=F3.x.y;
+  i=vF3.x.y;
+  i=BF.x;
+  i=vBF.x;
+  i=V[3];
+  i=vV[3];
+  i=VE.yx[1];
+  i=vVE.zy[1];
+  i = aggFct().x;
+  i=vtS;
+
+
+  // store
+  S=i;
+  vS=i;
+  *pS=i;
+  *pvS=i;
+  A[2]=i;
+  vA[2]=i;
+  F.x=i;
+  vF.x=i;
+  F2.x=i;
+  vF2.x=i;
+  vpF2->x=i;
+  vF3.x.y=i;
+  BF.x=i;
+  vBF.x=i;
+  V[3]=i;
+  vV[3]=i;
+  vtS=i;
+
+  // other ops:
+  ++S;
+  ++vS;
+  i+=S;
+  i+=vS;
+  ++vtS;
+  (void)vF2;
+  vF2 = vF2;
+  vF2 = vF2 = vF2;
+  vF2 = (vF2, vF2);
+}
diff --git a/test/CodeGen/weak-global.c b/test/CodeGen/weak-global.c
new file mode 100644
index 0000000..f972cea
--- /dev/null
+++ b/test/CodeGen/weak-global.c
@@ -0,0 +1,3 @@
+// RUN: %clang_cc1 -emit-llvm < %s | grep common
+
+int i;
diff --git a/test/CodeGen/weak-incomplete.c b/test/CodeGen/weak-incomplete.c
new file mode 100644
index 0000000..af91ae7
--- /dev/null
+++ b/test/CodeGen/weak-incomplete.c
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -emit-llvm < %s | grep 'extern_weak' | count 1
+
+struct S;
+void __attribute__((weak)) foo1(struct S);
+void (*foo2)(struct S) = foo1;
diff --git a/test/CodeGen/whilestmt.c b/test/CodeGen/whilestmt.c
new file mode 100644
index 0000000..3973b28
--- /dev/null
+++ b/test/CodeGen/whilestmt.c
@@ -0,0 +1,62 @@
+// RUN: %clang_cc1 %s -emit-llvm -o -
+
+int bar();
+int foo() {
+  int i;
+  i = 1 + 2;
+  while(1) {
+    i = bar();
+    i = bar();
+  };
+  return i;
+}
+
+
+int foo1() {
+  int i;
+  i = 1 + 2;
+  while(1) {
+    i = bar();
+    if (i == 42)
+      break;
+    i = bar();
+  };
+  return i;
+}
+
+
+int foo2() {
+  int i;
+  i = 1 + 2;
+  while(1) {
+    i = bar();
+    if (i == 42)
+      continue;
+    i = bar();
+  };
+  return i;
+}
+
+
+int foo3() {
+  int i;
+  i = 1 + 2;
+  while(1) {
+    i = bar();
+    if (i == 42)
+      break;
+  };
+  return i;
+}
+
+
+int foo4() {
+  int i;
+  i = 1 + 2;
+  while(1) {
+    i = bar();
+    if (i == 42)
+      continue;
+  };
+  return i;
+}
diff --git a/test/CodeGen/writable-strings.c b/test/CodeGen/writable-strings.c
new file mode 100644
index 0000000..693fa5e
--- /dev/null
+++ b/test/CodeGen/writable-strings.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -emit-llvm -o - -fwritable-strings %s
+
+int main() {
+    char *str = "abc";
+    str[0] = '1';
+    printf("%s", str);
+}
+
diff --git a/test/CodeGen/x86.c b/test/CodeGen/x86.c
new file mode 100644
index 0000000..e97d537
--- /dev/null
+++ b/test/CodeGen/x86.c
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 %s -triple=i686-pc-linux-gnu -emit-llvm -o - > %t1
+// RUN: grep "ax" %t1
+// RUN: grep "bx" %t1
+// RUN: grep "cx" %t1
+// RUN: grep "dx" %t1
+// RUN: grep "di" %t1
+// RUN: grep "si" %t1
+// RUN: grep "st" %t1
+// RUN: grep "st(1)" %t1
+
+void test1() {
+  int d1, d2;
+  asm ("" : "=a" (d1), "=b" (d2) :
+       "c" (0), "d" (0), "S" (0), "D" (0), "t" (0), "u" (0));
+}
diff --git a/test/CodeGen/x86_32-arguments.c b/test/CodeGen/x86_32-arguments.c
new file mode 100644
index 0000000..01c3e23
--- /dev/null
+++ b/test/CodeGen/x86_32-arguments.c
@@ -0,0 +1,216 @@
+// RUN: %clang_cc1 -fblocks -triple i386-apple-darwin9 -emit-llvm -o %t %s
+// RUN: FileCheck < %t %s
+
+// CHECK: define signext i8 @f0()
+char f0(void) {
+  return 0;
+}
+
+// CHECK: define signext i16 @f1()
+short f1(void) {
+  return 0;
+}
+
+// CHECK: define i32 @f2()
+int f2(void) {
+  return 0;
+}
+
+// CHECK: define float @f3()
+float f3(void) {
+  return 0;
+}
+
+// CHECK: define double @f4()
+double f4(void) {
+  return 0;
+}
+
+// CHECK: define x86_fp80 @f5()
+long double f5(void) {
+  return 0;
+}
+
+// CHECK: define void @f6(i8 signext %a0, i16 signext %a1, i32 %a2, i64 %a3, i8* %a4)
+void f6(char a0, short a1, int a2, long long a3, void *a4) {}
+
+// CHECK: define void @f7(i32 %a0)
+typedef enum { A, B, C } e7;
+void f7(e7 a0) {}
+
+// CHECK: define i64 @f8_1()
+// CHECK: define void @f8_2(i32 %a0.0, i32 %a0.1)
+struct s8 {
+  int a;
+  int b;
+};
+struct s8 f8_1(void) { while (1) {} }
+void f8_2(struct s8 a0) {}
+
+// This should be passed just as s8.
+
+// CHECK: define i64 @f9_1()
+
+// FIXME: llvm-gcc expands this, this may have some value for the
+// backend in terms of optimization but doesn't change the ABI.
+// CHECK: define void @f9_2(%struct.s9* byval %a0)
+struct s9 {
+  int a : 17;
+  int b;
+};
+struct s9 f9_1(void) { while (1) {} }
+void f9_2(struct s9 a0) {}
+
+// Return of small structures and unions
+
+// CHECK: float @f10()
+struct s10 {
+  union { };
+  float f;
+} f10(void) { while (1) {} }
+
+// Small vectors and 1 x {i64,double} are returned in registers
+
+// CHECK: i32 @f11()
+// CHECK: void @f12(<2 x i32>* sret %agg.result)
+// CHECK: i64 @f13()
+// CHECK: i64 @f14()
+// CHECK: <2 x i64> @f15()
+// CHECK: <2 x i64> @f16()
+typedef short T11 __attribute__ ((vector_size (4)));
+T11 f11(void) { while (1) {} }
+typedef int T12 __attribute__ ((vector_size (8)));
+T12 f12(void) { while (1) {} }
+typedef long long T13 __attribute__ ((vector_size (8)));
+T13 f13(void) { while (1) {} }
+typedef double T14 __attribute__ ((vector_size (8)));
+T14 f14(void) { while (1) {} }
+typedef long long T15 __attribute__ ((vector_size (16)));
+T15 f15(void) { while (1) {} }
+typedef double T16 __attribute__ ((vector_size (16)));
+T16 f16(void) { while (1) {} }
+
+// And when the single element in a struct (but not for 64 and
+// 128-bits).
+
+// CHECK: i32 @f17()
+// CHECK: void @f18(%2* sret %agg.result)
+// CHECK: void @f19(%3* sret %agg.result)
+// CHECK: void @f20(%4* sret %agg.result)
+// CHECK: void @f21(%5* sret %agg.result)
+// CHECK: void @f22(%6* sret %agg.result)
+struct { T11 a; } f17(void) { while (1) {} }
+struct { T12 a; } f18(void) { while (1) {} }
+struct { T13 a; } f19(void) { while (1) {} }
+struct { T14 a; } f20(void) { while (1) {} }
+struct { T15 a; } f21(void) { while (1) {} }
+struct { T16 a; } f22(void) { while (1) {} }
+
+// Single element structures are handled specially
+
+// CHECK: float @f23()
+// CHECK: float @f24()
+// CHECK: float @f25()
+struct { float a; } f23(void) { while (1) {} }
+struct { float a[1]; } f24(void) { while (1) {} }
+struct { struct {} a; struct { float a[1]; } b; } f25(void) { while (1) {} }
+
+// Small structures are handled recursively
+// CHECK: i32 @f26()
+// CHECK: void @f27(%struct.s27* sret %agg.result)
+struct s26 { struct { char a, b; } a; struct { char a, b; } b; } f26(void) { while (1) {} }
+struct s27 { struct { char a, b, c; } a; struct { char a; } b; } f27(void) { while (1) {} }
+
+// CHECK: void @f28(%struct.s28* sret %agg.result)
+struct s28 { int a; int b[]; } f28(void) { while (1) {} }
+
+// CHECK: define i16 @f29()
+struct s29 { struct { } a[1]; char b; char c; } f29(void) { while (1) {} }
+
+// CHECK: define i16 @f30()
+struct s30 { char a; char b : 4; } f30(void) { while (1) {} }
+
+// CHECK: define float @f31()
+struct s31 { char : 0; float b; char : 0; } f31(void) { while (1) {} }
+
+// CHECK: define i32 @f32()
+struct s32 { char a; unsigned : 0; } f32(void) { while (1) {} }
+
+// CHECK: define float @f33()
+struct s33 { float a; long long : 0; } f33(void) { while (1) {} }
+
+// CHECK: define float @f34()
+struct s34 { struct { int : 0; } a; float b; } f34(void) { while (1) {} }
+
+// CHECK: define i16 @f35()
+struct s35 { struct { int : 0; } a; char b; char c; } f35(void) { while (1) {} }
+
+// CHECK: define i16 @f36()
+struct s36 { struct { int : 0; } a[2][10]; char b; char c; } f36(void) { while (1) {} }
+
+// CHECK: define float @f37()
+struct s37 { float c[1][1]; } f37(void) { while (1) {} }
+
+// CHECK: define void @f38(%struct.s38* sret %agg.result)
+struct s38 { char a[3]; short b; } f38(void) { while (1) {} }
+
+// CHECK: define void @f39(%struct.s39* byval align 16 %x)
+typedef int v39 __attribute((vector_size(16)));
+struct s39 { v39 x; };
+void f39(struct s39 x) {}
+
+// <rdar://problem/7247671>
+// CHECK: define i32 @f40()
+enum e40 { ec0 = 0 };
+enum e40 f40(void) { }
+
+// CHECK: define void ()* @f41()
+typedef void (^vvbp)(void);
+vvbp f41(void) { }
+
+// CHECK: define i32 @f42()
+struct s42 { enum e40 f0; } f42(void) {  }
+
+// CHECK: define i64 @f43()
+struct s43 { enum e40 f0; int f1; } f43(void) {  }
+
+// CHECK: define i32 @f44()
+struct s44 { vvbp f0; } f44(void) {  }
+
+// CHECK: define i64 @f45()
+struct s45 { vvbp f0; int f1; } f45(void) {  }
+
+// CHECK: define void @f46(i32 %a0)
+void f46(enum e40 a0) { }
+
+// CHECK: define void @f47(void ()* %a1)
+void f47(vvbp a1) { }
+
+// CHECK: define void @f48(i32 %a0.0)
+struct s48 { enum e40 f0; };
+void f48(struct s48 a0) { }
+
+// CHECK: define void @f49(i32 %a0.0, i32 %a0.1)
+struct s49 { enum e40 f0; int f1; };
+void f49(struct s49 a0) { }
+
+// CHECK: define void @f50(void ()* %a0.0)
+struct s50 { vvbp f0; };
+void f50(struct s50 a0) { }
+
+// CHECK: define void @f51(void ()* %a0.0, i32 %a0.1)
+struct s51 { vvbp f0; int f1; };
+void f51(struct s51 a0) { }
+
+// CHECK: define void @f52(%struct.s52* byval align 16 %x)
+struct s52 {
+  long double a;
+};
+void f52(struct s52 x) {}
+
+// CHECK: define void @f53(%struct.s53* byval align 32 %x)
+struct __attribute__((aligned(32))) s53 {
+  int x;
+  int y;
+};
+void f53(struct s53 x) {}
diff --git a/test/CodeGen/x86_64-arguments.c b/test/CodeGen/x86_64-arguments.c
new file mode 100644
index 0000000..47b2eb1
--- /dev/null
+++ b/test/CodeGen/x86_64-arguments.c
@@ -0,0 +1,115 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o %t %s
+// RUN: FileCheck < %t %s
+
+// CHECK: %0 = type { i64, double }
+
+// CHECK: define signext i8 @f0()
+char f0(void) {
+  return 0;
+}
+
+// CHECK: define signext i16 @f1()
+short f1(void) {
+  return 0;
+}
+
+// CHECK: define i32 @f2()
+int f2(void) {
+  return 0;
+}
+
+// CHECK: define float @f3()
+float f3(void) {
+  return 0;
+}
+
+// CHECK: define double @f4()
+double f4(void) {
+  return 0;
+}
+
+// CHECK: define x86_fp80 @f5()
+long double f5(void) {
+  return 0;
+}
+
+// CHECK: define void @f6(i8 signext %a0, i16 signext %a1, i32 %a2, i64 %a3, i8* %a4)
+void f6(char a0, short a1, int a2, long long a3, void *a4) {
+}
+
+// CHECK: define void @f7(i32 %a0)
+typedef enum { A, B, C } e7;
+void f7(e7 a0) {
+}
+
+// Test merging/passing of upper eightbyte with X87 class.
+//
+// CHECK: define %0 @f8_1()
+// CHECK: define void @f8_2(%0)
+union u8 {
+  long double a;
+  int b;
+};
+union u8 f8_1() { while (1) {} }
+void f8_2(union u8 a0) {}
+
+// CHECK: define i64 @f9()
+struct s9 { int a; int b; int : 0; } f9(void) { while (1) {} }
+
+// CHECK: define void @f10(i64)
+struct s10 { int a; int b; int : 0; };
+void f10(struct s10 a0) {}
+
+// CHECK: define void @f11(%struct.s19* sret %agg.result)
+union { long double a; float b; } f11() { while (1) {} }
+
+// CHECK: define i64 @f12_0()
+// CHECK: define void @f12_1(i64)
+struct s12 { int a __attribute__((aligned(16))); };
+struct s12 f12_0(void) { while (1) {} }
+void f12_1(struct s12 a0) {}
+
+// Check that sret parameter is accounted for when checking available integer
+// registers.
+// CHECK: define void @f13(%struct.s13_0* sret %agg.result, i32 %a, i32 %b, i32 %c, i32 %d, %struct.s13_1* byval %e, i32 %f)
+
+struct s13_0 { long long f0[3]; };
+struct s13_1 { long long f0[2]; };
+struct s13_0 f13(int a, int b, int c, int d,
+                 struct s13_1 e, int f) { while (1) {} }
+
+// CHECK: define void @f14({{.*}}, i8 signext %X)
+void f14(int a, int b, int c, int d, int e, int f, char X) {}
+
+// CHECK: define void @f15({{.*}}, i8* %X)
+void f15(int a, int b, int c, int d, int e, int f, void *X) {}
+
+// CHECK: define void @f16({{.*}}, float %X)
+void f16(float a, float b, float c, float d, float e, float f, float g, float h,
+         float X) {}
+
+// CHECK: define void @f17({{.*}}, x86_fp80 %X)
+void f17(float a, float b, float c, float d, float e, float f, float g, float h,
+         long double X) {}
+
+// Check for valid coercion.
+// CHECK: [[f18_t0:%.*]] = bitcast i64* {{.*}} to %struct.f18_s0*
+// CHECK: [[f18_t1:%.*]] = load %struct.f18_s0* [[f18_t0]], align 1
+// CHECK: store %struct.f18_s0 [[f18_t1]], %struct.f18_s0* %f18_arg1
+struct f18_s0 { int f0; };
+void f18(int a, struct f18_s0 f18_arg1) { while (1) {} }
+
+// Check byval alignment.
+
+// CHECK: define void @f19(%struct.s19* byval align 16 %x)
+struct s19 {
+  long double a;
+};
+void f19(struct s19 x) {}
+
+// CHECK: define void @f20(%struct.s20* byval align 32 %x)
+struct __attribute__((aligned(32))) s20 {
+  int x;
+  int y;
+};
+void f20(struct s20 x) {}
diff --git a/test/CodeGenCXX/2010-03-09-AnonAggregate.cpp b/test/CodeGenCXX/2010-03-09-AnonAggregate.cpp
new file mode 100644
index 0000000..99883d8
--- /dev/null
+++ b/test/CodeGenCXX/2010-03-09-AnonAggregate.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -g -S -o %t %s
+// PR: 6554
+// More then one anonymous aggregates on one line creates chaos when MDNode uniquness is 
+// combined with RAUW operation.
+// This test case causes crashes if malloc is configured to trip buffer overruns.
+class MO {
+
+  union {       struct {       union {    int BA;       } Val;       int Offset;     } OffsetedInfo;   } Contents; 
+
+};
+
+class MO m;
diff --git a/test/CodeGenCXX/PR4827-cast.cpp b/test/CodeGenCXX/PR4827-cast.cpp
new file mode 100644
index 0000000..34a840c
--- /dev/null
+++ b/test/CodeGenCXX/PR4827-cast.cpp
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s
+struct A;
+struct B;
+extern A *f();
+void a() { (B *) f(); }
diff --git a/test/CodeGenCXX/PR4983-constructor-conversion.cpp b/test/CodeGenCXX/PR4983-constructor-conversion.cpp
new file mode 100644
index 0000000..797a1ba
--- /dev/null
+++ b/test/CodeGenCXX/PR4983-constructor-conversion.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -emit-llvm-only %s
+
+struct A {
+  A(const char *s){}
+};
+
+struct B {
+  A a;
+  
+  B() : a("test") { }
+};
+
+void f() {
+    A a("test");
+}
+
diff --git a/test/CodeGenCXX/PR5050-constructor-conversion.cpp b/test/CodeGenCXX/PR5050-constructor-conversion.cpp
new file mode 100644
index 0000000..9103b83
--- /dev/null
+++ b/test/CodeGenCXX/PR5050-constructor-conversion.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++0x -S %s -o %t-64.s
+// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s
+// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++0x -S %s -o %t-32.s
+// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s
+
+struct A { A(const A&, int i1 = 1); };
+
+struct B : A { };
+
+A f(const B &b) {
+  return b;
+}
+
+// CHECK-LP64: callq    __ZN1AC1ERKS_i
+
+// CHECK-LP32: call     L__ZN1AC1ERKS_i
+
+
diff --git a/test/CodeGenCXX/PR5093-static-member-function.cpp b/test/CodeGenCXX/PR5093-static-member-function.cpp
new file mode 100644
index 0000000..ceab852
--- /dev/null
+++ b/test/CodeGenCXX/PR5093-static-member-function.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+struct a {
+  static void f();
+};
+
+void g(a *a) {
+  // CHECK: call void @_ZN1a1fEv()
+  a->f();
+}
diff --git a/test/CodeGenCXX/PR5834-constructor-conversion.cpp b/test/CodeGenCXX/PR5834-constructor-conversion.cpp
new file mode 100644
index 0000000..044d8e5
--- /dev/null
+++ b/test/CodeGenCXX/PR5834-constructor-conversion.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s
+
+// PR5834
+struct ASTMultiMover {};
+struct ASTMultiPtr {
+  ASTMultiPtr();
+  ASTMultiPtr(ASTMultiPtr&);
+  ASTMultiPtr(ASTMultiMover mover);
+  operator ASTMultiMover();
+};
+void f1() {
+  extern void f0(ASTMultiPtr);
+  f0(ASTMultiPtr());
+}
diff --git a/test/CodeGenCXX/PR6474.cpp b/test/CodeGenCXX/PR6474.cpp
new file mode 100644
index 0000000..0b155ce
--- /dev/null
+++ b/test/CodeGenCXX/PR6474.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 %s -emit-llvm-only
+
+namespace test0 {
+template <typename T> struct X {
+  virtual void foo();
+  virtual void bar();
+  virtual void baz();
+};
+
+template <typename T> void X<T>::foo() {}
+template <typename T> void X<T>::bar() {}
+template <typename T> void X<T>::baz() {}
+
+template <> void X<char>::foo() {}
+template <> void X<char>::bar() {}
+}
+
+namespace test1 {
+template <typename T> struct X {
+  virtual void foo();
+  virtual void bar();
+  virtual void baz();
+};
+
+template <typename T> void X<T>::foo() {}
+template <typename T> void X<T>::bar() {}
+template <typename T> void X<T>::baz() {}
+
+template <> void X<char>::bar() {}
+template <> void X<char>::foo() {}
+}
diff --git a/test/CodeGenCXX/PR6747.cpp b/test/CodeGenCXX/PR6747.cpp
new file mode 100644
index 0000000..5a07ce6
--- /dev/null
+++ b/test/CodeGenCXX/PR6747.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+
+struct foo {
+  virtual void bar();
+// CHECK: define available_externally void @_ZN3foo3bazEv
+  virtual void baz() {}
+};
+void zed() {
+  foo b;
+  b.baz();
+}
diff --git a/test/CodeGenCXX/__null.cpp b/test/CodeGenCXX/__null.cpp
new file mode 100644
index 0000000..8a17797
--- /dev/null
+++ b/test/CodeGenCXX/__null.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 %s -emit-llvm -o %t
+
+int* a = __null;
+int b = __null;
+
+void f() {
+  int* c = __null;
+  int d = __null;
+}
diff --git a/test/CodeGenCXX/address-of-fntemplate.cpp b/test/CodeGenCXX/address-of-fntemplate.cpp
new file mode 100644
index 0000000..c5fa89d
--- /dev/null
+++ b/test/CodeGenCXX/address-of-fntemplate.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+template <typename T> void f(T) {}
+template <typename T> void f() { }
+
+void test() {
+  // CHECK: @_Z1fIiEvT_
+  void (*p)(int) = &f;
+  
+  // CHECK: @_Z1fIiEvv
+  void (*p2)() = f<int>;
+}
+// CHECK: define linkonce_odr void @_Z1fIiEvT_
+// CHECK: define linkonce_odr void @_Z1fIiEvv
diff --git a/test/CodeGenCXX/alloca-align.cpp b/test/CodeGenCXX/alloca-align.cpp
new file mode 100644
index 0000000..b70e366
--- /dev/null
+++ b/test/CodeGenCXX/alloca-align.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s
+
+struct s0 {
+  int Start, End;
+  unsigned Alignment;
+  int TheStores __attribute__((aligned(16)));
+};
+
+// CHECK: define void @f0
+// CHECK: alloca %struct.s0, align 16
+extern "C" void f0() {
+  (void) s0();
+}
+
+// CHECK: define void @f1
+// CHECK: alloca %struct.s0, align 16
+extern "C" void f1() {
+  (void) (struct s0) { 0, 0, 0, 0 };
+}
+
+// CHECK: define i64 @f2
+// CHECK: alloca %struct.s1, align 2
+struct s1 { short x; short y; };
+extern "C" struct s1 f2(int a, struct s1 *x, struct s1 *y) {
+  if (a)
+    return *x;
+  return *y;
+}
diff --git a/test/CodeGenCXX/anonymous-namespaces.cpp b/test/CodeGenCXX/anonymous-namespaces.cpp
new file mode 100644
index 0000000..695f8f5
--- /dev/null
+++ b/test/CodeGenCXX/anonymous-namespaces.cpp
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s
+
+
+int f();
+
+namespace {
+  // CHECK: @_ZN12_GLOBAL__N_11bE = internal global i32 0
+  // CHECK: @_ZN12_GLOBAL__N_1L1cE = internal global i32 0
+  // CHECK: @_ZN12_GLOBAL__N_11D1dE = internal global i32 0
+  // CHECK: @_ZN12_GLOBAL__N_11aE = internal global i32 0
+  int a = 0;
+
+  int b = f();
+
+  static int c = f();
+
+  class D {
+    static int d;
+  };
+  
+  int D::d = f();
+
+  // CHECK: define internal i32 @_ZN12_GLOBAL__N_13fooEv()
+  int foo() {
+    return 32;
+  }
+
+  // CHECK: define internal i32 @_ZN12_GLOBAL__N_11A3fooEv()
+  namespace A {
+    int foo() {
+      return 45;
+    }
+  }
+}
+
+int concrete() {
+  return a + foo() + A::foo();
+}
diff --git a/test/CodeGenCXX/anonymous-union-member-initializer.cpp b/test/CodeGenCXX/anonymous-union-member-initializer.cpp
new file mode 100644
index 0000000..ea3eafc
--- /dev/null
+++ b/test/CodeGenCXX/anonymous-union-member-initializer.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s
+
+struct A {
+  union {
+    int a;
+    void* b;
+  };
+  
+  A() : a(0) { }
+};
+
+A a;
diff --git a/test/CodeGenCXX/arm.cpp b/test/CodeGenCXX/arm.cpp
new file mode 100644
index 0000000..5cca788
--- /dev/null
+++ b/test/CodeGenCXX/arm.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 %s -triple=thumbv7-apple-darwin3.0.0-iphoneos -fno-use-cxa-atexit -target-abi apcs-gnu -emit-llvm -o - | FileCheck %s
+
+class foo {
+public:
+    foo();
+    virtual ~foo();
+};
+
+class bar : public foo {
+public:
+	bar();
+};
+
+// The global dtor needs the right calling conv with -fno-use-cxa-atexit
+// rdar://7817590
+bar baz;
+
+// CHECK: @_GLOBAL__D_a()
+// CHECK: call arm_apcscc  void @_ZN3barD1Ev(%class.bar* @baz)
+
diff --git a/test/CodeGenCXX/array-construction.cpp b/test/CodeGenCXX/array-construction.cpp
new file mode 100644
index 0000000..ab46be7
--- /dev/null
+++ b/test/CodeGenCXX/array-construction.cpp
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++0x -S %s -o %t-64.s
+// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s
+// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++0x -S %s -o %t-32.s
+// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s
+
+extern "C" int printf(...);
+
+static int count;
+static float fcount;
+
+class xpto {
+public:
+  xpto() : i(count++), f(fcount++) {
+    printf("xpto::xpto()\n");
+  }
+  int i;
+  float f;
+
+  ~xpto() {
+    printf("xpto::~xpto()\n");
+  }
+};
+
+int main() {
+  xpto array[2][3][4];
+  for (int h = 0; h < 2; h++)
+   for (int i = 0; i < 3; i++)
+    for (int j = 0; j < 4; j++)
+       printf("array[%d][%d][%d] = {%d, %f}\n", 
+              h, i, j, array[h][i][j].i, array[h][i][j].f);
+}
+
+// CHECK-LP64: callq    __ZN4xptoC1Ev
+
+// CHECK-LP32: call     L__ZN4xptoC1Ev
+
diff --git a/test/CodeGenCXX/array-operator-delete-call.cpp b/test/CodeGenCXX/array-operator-delete-call.cpp
new file mode 100644
index 0000000..acb85d2
--- /dev/null
+++ b/test/CodeGenCXX/array-operator-delete-call.cpp
@@ -0,0 +1,63 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++0x -S %s -o %t-64.s
+// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s
+// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++0x -S %s -o %t-32.s
+// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s
+
+extern "C" int printf(...);
+
+int count;
+
+struct S {
+  S() : iS (++count) { printf("S::S(%d)\n", iS); }
+  ~S() { printf("S::~S(%d)\n", iS); }
+  int iS;
+};
+
+struct V {
+  V() : iV (++count) { printf("V::V(%d)\n", iV); }
+  virtual ~V() { printf("V::~V(%d)\n", iV); }
+  int iV;
+};
+
+struct COST
+{
+  S *cost;
+  V *vcost;
+  unsigned *cost_val;
+
+  ~COST();
+  COST();
+};
+
+
+COST::COST()
+{
+  cost = new S[3];
+  vcost = new V[4];
+  cost_val = new unsigned[10];
+}
+
+COST::~COST()
+{
+  if (cost) {
+   delete [] cost;
+  }
+  if (vcost) {
+   delete [] vcost;
+  }
+  if (cost_val)
+    delete [] cost_val;
+}
+
+COST c1;
+
+int main()
+{
+  COST c3;
+}
+COST c2;
+
+// CHECK-LP64: callq    __ZdaPv
+
+// CHECK-LP32: call     L__ZdaPv
+
diff --git a/test/CodeGenCXX/array-pointer-decay.cpp b/test/CodeGenCXX/array-pointer-decay.cpp
new file mode 100644
index 0000000..3fe6b72
--- /dev/null
+++ b/test/CodeGenCXX/array-pointer-decay.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 %s -emit-llvm -o -
+
+void f(const char*);
+
+void g() {
+  f("hello");
+}
diff --git a/test/CodeGenCXX/array-value-initialize.cpp b/test/CodeGenCXX/array-value-initialize.cpp
new file mode 100644
index 0000000..5fe6c20
--- /dev/null
+++ b/test/CodeGenCXX/array-value-initialize.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s
+
+// PR5463
+extern "C" int printf(...);
+
+struct S {
+  double filler;
+};
+
+struct Foo {
+        Foo(void) : bar_(), dbar_(), sbar_() { 
+	  for (int i = 0; i < 5; i++) {
+	    printf("bar_[%d] = %d\n", i, bar_[i]);
+	    printf("dbar_[%d] = %f\n", i, dbar_[i]);
+	    printf("sbar_[%d].filler = %f\n", i, sbar_[i].filler);
+	  }
+        } 
+
+        int bar_[5];
+        double dbar_[5];
+        S sbar_[5];
+};
+
+int main(void)
+{
+        Foo a;
+}
+
diff --git a/test/CodeGenCXX/assign-operator.cpp b/test/CodeGenCXX/assign-operator.cpp
new file mode 100644
index 0000000..c4b64e6
--- /dev/null
+++ b/test/CodeGenCXX/assign-operator.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -emit-llvm -verify -o - |FileCheck %s
+
+class x {
+public: int operator=(int);
+};
+void a() {
+  x a;
+  a = 1u;
+}
+
+void f(int i, int j) {
+  // CHECK: load i32
+  // CHECK: load i32
+  // CHECK: add nsw i32
+  // CHECK: store i32
+  // CHECK: store i32 17, i32
+  // CHECK: ret
+  (i += j) = 17;
+}
diff --git a/test/CodeGenCXX/attr.cpp b/test/CodeGenCXX/attr.cpp
new file mode 100644
index 0000000..d689a4f
--- /dev/null
+++ b/test/CodeGenCXX/attr.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -o - %s | FileCheck %s
+
+// CHECK: @test2 = alias i32 ()* @_Z5test1v
+
+// CHECK: define i32 @_Z3foov() nounwind align 1024
+int foo() __attribute__((aligned(1024)));
+int foo() { }
+
+class C {
+  virtual void bar1() __attribute__((aligned(1)));
+  virtual void bar2() __attribute__((aligned(2)));
+  virtual void bar3() __attribute__((aligned(1024)));
+} c;
+
+// CHECK: define void @_ZN1C4bar1Ev(%class.C* %this) nounwind align 2
+void C::bar1() { }
+
+// CHECK: define void @_ZN1C4bar2Ev(%class.C* %this) nounwind align 2
+void C::bar2() { }
+
+// CHECK: define void @_ZN1C4bar3Ev(%class.C* %this) nounwind align 1024
+void C::bar3() { }
+
+// PR6635
+// CHECK: define i32 @_Z5test1v()
+int test1() { return 10; }
+// CHECK at top of file
+extern "C" int test2() __attribute__((alias("_Z5test1v")));
diff --git a/test/CodeGenCXX/bitfield-layout.cpp b/test/CodeGenCXX/bitfield-layout.cpp
new file mode 100644
index 0000000..15f33d2
--- /dev/null
+++ b/test/CodeGenCXX/bitfield-layout.cpp
@@ -0,0 +1,43 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - -O3 | FileCheck -check-prefix LP64 %s
+// RUN: %clang_cc1 %s -triple=i386-apple-darwin10 -emit-llvm -o - -O3 | FileCheck -check-prefix LP32 %s
+
+// CHECK-LP64: %union.Test1 = type { i32, [4 x i8] }
+union Test1 {
+  int a;
+  int b: 39;
+} t1;
+
+// CHECK-LP64: %union.Test2 = type { i8 }
+union Test2 {
+  int : 6;
+} t2;
+
+// CHECK-LP64: %union.Test3 = type { [2 x i8] }
+union Test3 {
+  int : 9;
+} t3;
+
+
+#define CHECK(x) if (!(x)) return __LINE__
+
+int f() {
+  struct {
+    int a;
+
+    unsigned long long b : 65;
+
+    int c;
+  } c;
+  
+  c.a = 0;
+  c.b = (unsigned long long)-1;
+  c.c = 0;
+
+  CHECK(c.a == 0);
+  CHECK(c.b == (unsigned long long)-1);
+  CHECK(c.c == 0);
+
+// CHECK-LP64: ret i32 0
+// CHECK-LP32: ret i32 0
+  return 0;
+}
diff --git a/test/CodeGenCXX/c-linkage.cpp b/test/CodeGenCXX/c-linkage.cpp
new file mode 100644
index 0000000..b1f07b7
--- /dev/null
+++ b/test/CodeGenCXX/c-linkage.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+// pr6644
+
+extern "C" {
+  namespace N {
+    struct X { 
+      virtual void f();
+    };
+    void X::f() { }
+  }
+}
+
+// CHECK: define void @_ZN1N1X1fEv
diff --git a/test/CodeGenCXX/call-arg-zero-temp.cpp b/test/CodeGenCXX/call-arg-zero-temp.cpp
new file mode 100644
index 0000000..ed8118e
--- /dev/null
+++ b/test/CodeGenCXX/call-arg-zero-temp.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -S %s -o %t-64.s
+// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s
+// RUN: %clang_cc1 -triple i386-apple-darwin -S %s -o %t-32.s
+// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s
+
+
+extern "C" int printf(...);
+
+struct obj{ int a; float b; double d; };
+
+void foo(obj o) {
+  printf("%d  %f  %f\n", o.a, o.b, o.d);
+}
+
+int main() {
+  obj o = obj();
+  foo(obj());
+}
+
+// CHECK-LP64: callq    __Z3foo3obj
+
+// CHECK-LP32: call     __Z3foo3obj
diff --git a/test/CodeGenCXX/cast-conversion.cpp b/test/CodeGenCXX/cast-conversion.cpp
new file mode 100644
index 0000000..6dc6de6
--- /dev/null
+++ b/test/CodeGenCXX/cast-conversion.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++0x -S %s -o %t-64.s
+// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s
+// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++0x -S %s -o %t-32.s
+// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s
+
+struct A {
+  A(int);
+};
+
+struct B {
+  B(A);
+};
+
+int main () {
+  (B)10;
+  B(10);
+  static_cast<B>(10);
+}
+
+// CHECK-LP64: callq    __ZN1AC1Ei
+// CHECK-LP64: callq    __ZN1BC1E1A
+// CHECK-LP64: callq    __ZN1AC1Ei
+// CHECK-LP64: callq    __ZN1BC1E1A
+// CHECK-LP64: callq    __ZN1AC1Ei
+// CHECK-LP64: callq    __ZN1BC1E1A
+
+// CHECK-LP32: call     L__ZN1AC1Ei
+// CHECK-LP32: call     L__ZN1BC1E1A
+// CHECK-LP32: call     L__ZN1AC1Ei
+// CHECK-LP32: call     L__ZN1BC1E1A
+// CHECK-LP32: call     L__ZN1AC1Ei
+// CHECK-LP32: call     L__ZN1BC1E1A
diff --git a/test/CodeGenCXX/casts.cpp b/test/CodeGenCXX/casts.cpp
new file mode 100644
index 0000000..436b722
--- /dev/null
+++ b/test/CodeGenCXX/casts.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 %s -emit-llvm -o %t
+
+// PR5248
+namespace PR5248 {
+struct A {
+  void copyFrom(const A &src);
+  void addRef(void);
+
+  A& operator=(int);
+};
+
+void A::copyFrom(const A &src) {
+  ((A &)src).addRef();
+}
+}
+
+// reinterpret_cast to self
+void test(PR5248::A* a) {
+  reinterpret_cast<PR5248::A&>(*a) = 17;
+}
diff --git a/test/CodeGenCXX/class-layout.cpp b/test/CodeGenCXX/class-layout.cpp
new file mode 100644
index 0000000..31091c5
--- /dev/null
+++ b/test/CodeGenCXX/class-layout.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+
+// An extra byte shoudl be allocated for an empty class.
+// CHECK: %struct.A = type { i8 }
+struct A { } a;
+
+// No need to add tail padding here.
+// CHECK: %struct.B = type { i8*, i32 }
+struct B { void *a; int b; } b;
+
+// C should have a vtable pointer.
+// CHECK: %struct.C = type { i8**, i32 }
+struct C { virtual void f(); int a; } *c;
diff --git a/test/CodeGenCXX/condition.cpp b/test/CodeGenCXX/condition.cpp
new file mode 100644
index 0000000..e435408
--- /dev/null
+++ b/test/CodeGenCXX/condition.cpp
@@ -0,0 +1,110 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
+void *f();
+
+template <typename T> T* g() {
+ if (T* t = f())
+   return t;
+
+ return 0;
+}
+
+void h() {
+ void *a = g<void>();
+}
+
+struct X {
+  X();
+  ~X();
+  operator bool();
+};
+
+struct Y {
+  Y();
+  ~Y();
+};
+
+void if_destruct(int z) {
+  // Verify that the condition variable is destroyed at the end of the
+  // "if" statement.
+  // CHECK: call void @_ZN1XC1Ev
+  // CHECK: call zeroext i1 @_ZN1XcvbEv
+  if (X x = X()) {
+    // CHECK: store i32 18
+    z = 18;
+  }
+  // CHECK: call void @_ZN1XD1Ev
+  // CHECK: store i32 17
+  z = 17;
+
+  // CHECK: call void @_ZN1XC1Ev
+  if (X x = X())
+    Y y;
+  // CHECK: br
+  // CHECK: call  void @_ZN1YC1Ev
+  // CHECK: call  void @_ZN1YD1Ev
+  // CHECK: br
+  // CHECK: call  void @_ZN1XD1Ev
+}
+
+struct ConvertibleToInt {
+  ConvertibleToInt();
+  ~ConvertibleToInt();
+  operator int();
+};
+
+void switch_destruct(int z) {
+  // CHECK: call void @_ZN16ConvertibleToIntC1Ev
+  switch (ConvertibleToInt conv = ConvertibleToInt()) {
+  case 0:
+    break;
+
+  default:
+    // CHECK: {{sw.default:|:3}}
+    // CHECK: store i32 19
+    z = 19;
+    break;
+  }
+  // CHECK: {{sw.epilog:|:5}}
+  // CHECK: call void @_ZN16ConvertibleToIntD1Ev
+  // CHECK: store i32 20
+  z = 20;
+}
+
+int foo();
+
+void while_destruct(int z) {
+  // CHECK: define void @_Z14while_destructi
+  // CHECK: {{while.cond:|:2}}
+  while (X x = X()) {
+    // CHECK: call void @_ZN1XC1Ev
+
+    // CHECK: {{while.body:|:4}}
+    // CHECK: store i32 21
+    z = 21;
+
+    // CHECK: {{while.cleanup:|:5}}
+    // CHECK: call void @_ZN1XD1Ev
+  }
+  // CHECK: {{while.end|:7}}
+  // CHECK: store i32 22
+  z = 22;
+}
+
+void for_destruct(int z) {
+  // CHECK: define void @_Z12for_destruct
+  // CHECK: call void @_ZN1YC1Ev
+  for(Y y = Y(); X x = X(); ++z)
+    // CHECK: {{for.cond:|:2}}
+    // CHECK: call void @_ZN1XC1Ev
+    // CHECK: {{for.body:|:4}}
+    // CHECK: store i32 23
+    z = 23;
+    // CHECK: {{for.inc:|:5}}
+    // CHECK: br label %{{for.cond.cleanup|8}}
+    // CHECK: {{for.cond.cleanup:|:8}}
+    // CHECK: call void @_ZN1XD1Ev
+  // CHECK: {{for.end:|:10}}
+  // CHECK: call void @_ZN1YD1Ev
+  // CHECK: store i32 24
+  z = 24;
+}
diff --git a/test/CodeGenCXX/conditional-expr-lvalue.cpp b/test/CodeGenCXX/conditional-expr-lvalue.cpp
new file mode 100644
index 0000000..a0843c4
--- /dev/null
+++ b/test/CodeGenCXX/conditional-expr-lvalue.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -emit-llvm-only %s
+void f(bool flag) {
+  int a = 1;
+  int b = 2;
+  
+  (flag ? a : b) = 3;
+}
diff --git a/test/CodeGenCXX/conditional-temporaries.cpp b/test/CodeGenCXX/conditional-temporaries.cpp
new file mode 100644
index 0000000..d538287
--- /dev/null
+++ b/test/CodeGenCXX/conditional-temporaries.cpp
@@ -0,0 +1,55 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 -O3 | FileCheck %s
+
+namespace {
+
+static int ctorcalls;
+static int dtorcalls;
+  
+struct A {
+  A() : i(0) { ctorcalls++; }
+  ~A() { dtorcalls++; }
+  int i;
+  
+  friend const A& operator<<(const A& a, int n) {
+    return a;
+  }
+};
+
+void g(int) { }
+void g(const A&) { }
+
+void f1(bool b) {
+  g(b ? A().i : 0);
+  g(b || A().i);
+  g(b && A().i);
+  g(b ? A() << 1 : A() << 2);
+}
+
+struct Checker {
+  Checker() {
+    f1(true);
+    f1(false);
+  }
+};
+
+Checker c;
+
+}
+
+// CHECK: define i32 @_Z12getCtorCallsv()
+int getCtorCalls() {
+  // CHECK: ret i32 5
+  return ctorcalls;
+}
+
+// CHECK: define i32 @_Z12getDtorCallsv()
+int getDtorCalls() {
+  // CHECK: ret i32 5
+  return dtorcalls;
+}
+
+// CHECK: define zeroext i1 @_Z7successv()
+bool success() {
+  // CHECK: ret i1 true
+  return ctorcalls == dtorcalls;
+}
diff --git a/test/CodeGenCXX/const-base-cast.cpp b/test/CodeGenCXX/const-base-cast.cpp
new file mode 100644
index 0000000..ed47069
--- /dev/null
+++ b/test/CodeGenCXX/const-base-cast.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -O1 -emit-llvm %s -o - | FileCheck %s
+
+// Check that the following construct, which is similar to one which occurs
+// in Firefox, is not misfolded (folding it correctly would be a bonus, but
+// that doesn't work at the moment, hence the -O1 in the runline).
+struct A { char x; };
+struct B { char y; };
+struct C : A,B {};
+unsigned char x = ((char*)(B*)(C*)0x1000) - (char*)0x1000;
+
+// CHECK: @x = global i8 1
diff --git a/test/CodeGenCXX/const-global-linkage.cpp b/test/CodeGenCXX/const-global-linkage.cpp
new file mode 100644
index 0000000..d0a055b
--- /dev/null
+++ b/test/CodeGenCXX/const-global-linkage.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+
+const int x = 10;
+const int y = 20;
+// CHECK-NOT: @x
+// CHECK: @_ZL1y = internal constant i32 20
+const int& b() { return y; }
+
+const char z1[] = "asdf";
+const char z2[] = "zxcv";
+// CHECK-NOT: @z1
+// CHECK: @_ZL2z2 = internal constant
+const char* b2() { return z2; }
diff --git a/test/CodeGenCXX/const-init.cpp b/test/CodeGenCXX/const-init.cpp
new file mode 100644
index 0000000..9cfce7a
--- /dev/null
+++ b/test/CodeGenCXX/const-init.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin -emit-llvm -o - %s | FileCheck %s
+
+// CHECK: @a = global i32 10
+int a = 10;
+// CHECK: @ar = constant i32* @a
+int &ar = a;
+
+void f();
+// CHECK: @fr = constant void ()* @_Z1fv
+void (&fr)() = f;
+
+struct S { int& a; };
+// CHECK: @s = global %0 { i32* @a }
+S s = { a };
+
+// PR5581
+namespace PR5581 {
+class C {
+public:
+  enum { e0, e1 };
+  unsigned f;
+};
+
+// CHECK: @_ZN6PR55812g0E = global %1 { i32 1 }
+C g0 = { C::e1 };
+}
diff --git a/test/CodeGenCXX/constructor-conversion.cpp b/test/CodeGenCXX/constructor-conversion.cpp
new file mode 100644
index 0000000..f135da5
--- /dev/null
+++ b/test/CodeGenCXX/constructor-conversion.cpp
@@ -0,0 +1,54 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++0x -S %s -o %t-64.s
+// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s
+// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++0x -S %s -o %t-32.s
+// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s
+
+extern "C" int printf(...);
+
+class X { // ...
+public: 
+  X(int) : iX(2), fX(2.3) , name("HELLO\n") {  }
+
+  X(const char* arg, int ix=0) { iX = ix; fX = 6.0; name = arg+ix; }
+  X(): iX(100), fX(1.2) {}
+  int iX;
+  float fX;
+  const char *name;
+  void pr(void) {
+    printf("iX = %d  fX = %f name = %s\n", iX, fX, name);
+  }
+};
+
+void g(X arg) {
+  arg.pr();
+}
+
+void f(X arg) {
+  X a = 1;        // a = X(1)
+
+  a.pr();
+
+  X b = "Jessie"; //  b=X("Jessie",0)
+
+  b.pr();
+
+
+  a = 2;          // a = X(2)
+
+  a.pr();
+}
+
+
+int main() {
+  X x;
+  f(x);
+  g(3);           // g(X(3))
+}
+
+// CHECK-LP64: callq    __ZN1XC1Ei
+// CHECK-LP64: callq    __ZN1XC1EPKci
+// CHECK-LP64: callq    __ZN1XC1Ev
+
+// CHECK-LP32: call     L__ZN1XC1Ei
+// CHECK-LP32: call     L__ZN1XC1EPKci
+// CHECK-LP32: call     L__ZN1XC1Ev
diff --git a/test/CodeGenCXX/constructor-convert.cpp b/test/CodeGenCXX/constructor-convert.cpp
new file mode 100644
index 0000000..7de0772
--- /dev/null
+++ b/test/CodeGenCXX/constructor-convert.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang -emit-llvm -S -o - %s
+
+// PR5775
+class Twine {
+  Twine(const char *Str) { }
+};
+
+static void error(const Twine &Message);
+
+template<typename>
+struct opt_storage {
+  void f() {
+    error("cl::location(x) specified more than once!");
+  }
+};
+
+void f(opt_storage<int> o) {
+  o.f();
+}
diff --git a/test/CodeGenCXX/constructor-default-arg.cpp b/test/CodeGenCXX/constructor-default-arg.cpp
new file mode 100644
index 0000000..ec0b8da
--- /dev/null
+++ b/test/CodeGenCXX/constructor-default-arg.cpp
@@ -0,0 +1,39 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++0x -S %s -o %t-64.s
+// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s
+// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++0x -S %s -o %t-32.s
+// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s
+
+extern "C" int printf(...);
+
+
+struct C {
+  C() : iC(6) {}
+  int iC;
+};
+
+int foo() {
+  return 6;
+};
+
+class X { // ...
+public: 
+  X(int) {}
+  X(const X&, int i = 1, int j = 2, int k = foo()) {
+    printf("X(const X&, %d, %d, %d)\n", i, j, k);
+  }
+};
+
+int main() {
+  X a(1);
+  X b(a, 2);
+  X c = b;
+  X d(a, 5, 6);
+}
+
+// CHECK-LP64: callq __ZN1XC1ERKS_iii
+// CHECK-LP64: callq __ZN1XC1ERKS_iii
+// CHECK-LP64: callq __ZN1XC1ERKS_iii
+
+// CHECK-LP32: call L__ZN1XC1ERKS_iii
+// CHECK-LP32: call L__ZN1XC1ERKS_iii
+// CHECK-LP32: call L__ZN1XC1ERKS_iii
diff --git a/test/CodeGenCXX/constructor-for-array-members.cpp b/test/CodeGenCXX/constructor-for-array-members.cpp
new file mode 100644
index 0000000..b981da4
--- /dev/null
+++ b/test/CodeGenCXX/constructor-for-array-members.cpp
@@ -0,0 +1,43 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++0x -S %s -o %t-64.s
+// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s
+// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++0x -S %s -o %t-32.s
+// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s
+
+extern "C" int printf(...);
+
+int i = 1234;
+float vf = 1.00;
+
+struct S {
+  S() : iS(i++), f1(vf++) {printf("S::S()\n");}
+  ~S(){printf("S::~S(iS = %d  f1 = %f)\n", iS, f1); }
+  int iS;
+  float f1;
+};
+
+struct M {
+  double dM;
+  S ARR_S[3];
+  void pr() {
+    for (int i = 0; i < 3; i++)
+     printf("ARR_S[%d].iS = %d ARR_S[%d].f1 = %f\n", i, ARR_S[i].iS, i, ARR_S[i].f1);
+
+    for (int i = 0; i < 2; i++)
+      for (int j = 0; j < 3; j++)
+        for (int k = 0; k < 4; k++)
+           printf("MULTI_ARR[%d][%d][%d].iS = %d MULTI_ARR[%d][%d][%d].f1 = %f\n", 
+                  i,j,k, MULTI_ARR[i][j][k].iS, i,j,k, MULTI_ARR[i][j][k].f1);
+
+  }
+
+ S MULTI_ARR[2][3][4];
+};
+
+int main() {
+  M m1;
+  m1.pr();
+}
+
+// CHECK-LP64: callq __ZN1SC1Ev
+
+// CHECK-LP32: call L__ZN1SC1Ev
diff --git a/test/CodeGenCXX/constructor-init-reference.cpp b/test/CodeGenCXX/constructor-init-reference.cpp
new file mode 100644
index 0000000..5e75159
--- /dev/null
+++ b/test/CodeGenCXX/constructor-init-reference.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s | grep "store i32\* @x, i32\*\*"
+
+int x;
+struct A {
+  int& y;
+  A() : y(x) {}
+};
+A z;
+
diff --git a/test/CodeGenCXX/constructor-init.cpp b/test/CodeGenCXX/constructor-init.cpp
new file mode 100644
index 0000000..284b8b5
--- /dev/null
+++ b/test/CodeGenCXX/constructor-init.cpp
@@ -0,0 +1,103 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -emit-llvm -o - | FileCheck %s
+
+extern "C" int printf(...);
+
+struct M {
+  M() { printf("M()\n"); }
+  M(int i) { iM = i; printf("M(%d)\n", i); }
+  int iM;
+  void MPR() {printf("iM = %d\n", iM); };
+};
+
+struct P {
+  P() { printf("P()\n"); }
+  P(int i) { iP = i; printf("P(%d)\n", i); }
+  int iP;
+  void PPR() {printf("iP = %d\n", iP); };
+};
+
+struct Q {
+  Q() { printf("Q()\n"); }
+  Q(int i) { iQ = i; printf("Q(%d)\n", i); }
+  int iQ;
+  void QPR() {printf("iQ = %d\n", iQ); };
+};
+
+struct N : M , P, Q {
+  N() : f1(1.314), P(2000), ld(00.1234+f1), M(1000), Q(3000),
+        d1(3.4567), i1(1234), m1(100) { printf("N()\n"); }
+  M m1;
+  M m2;
+  float f1;
+  int i1;
+  float d1;
+  void PR() {
+    printf("f1 = %f d1 = %f i1 = %d ld = %f \n", f1,d1,i1, ld); 
+    MPR();
+    PPR();
+    QPR();
+    printf("iQ = %d\n", iQ);
+    printf("iP = %d\n", iP);
+    printf("iM = %d\n", iM);
+    // FIXME. We don't yet support this syntax.
+    // printf("iQ = %d\n", (*this).iQ);
+    printf("iQ = %d\n", this->iQ);
+    printf("iP = %d\n", this->iP);
+    printf("iM = %d\n", this->iM);
+  }
+  float ld;
+  float ff;
+  M arr_m[3];
+  P arr_p[1][3];
+  Q arr_q[2][3][4];
+};
+
+int main() {
+  M m1;
+
+  N n1;
+  n1.PR();
+}
+
+// PR5826
+template <class T> struct A {
+  A() {}
+  A(int) {}
+  A(const A&) {}
+  ~A() {}
+  operator int() {return 0;}
+};
+
+// CHECK: define void @_Z1fv()
+void f() {
+  // CHECK: call void @_ZN1AIsEC1Ei
+  A<short> a4 = 97;
+
+  // CHECK-NEXT: store i32 17
+  int i = 17;
+
+  // CHECK-NEXT: call void @_ZN1AIsED1Ev
+  // CHECK-NOT: call void @_ZN1AIsED1Ev
+  // CHECK: ret void
+}
+
+template<typename T>
+struct X {
+  X(const X &);
+
+  T *start;
+  T *end;
+};
+
+template<typename T> struct X;
+
+// Make sure that the instantiated constructor initializes start and
+// end properly.
+// CHECK: define linkonce_odr void @_ZN1XIiEC2ERKS0_
+// CHECK: {{store.*null}}
+// CHECK: {{store.*null}}
+// CHECK: ret
+template<typename T>
+X<T>::X(const X &other) : start(0), end(0) { }
+
+X<int> get_X(X<int> x) { return x; }
diff --git a/test/CodeGenCXX/constructor-template.cpp b/test/CodeGenCXX/constructor-template.cpp
new file mode 100644
index 0000000..a3f38a6
--- /dev/null
+++ b/test/CodeGenCXX/constructor-template.cpp
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++0x -S %s -o %t-64.s
+// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s
+// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++0x -S %s -o %t-32.s
+// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s
+
+// PR4826
+struct A {
+  A() {
+  }
+};
+
+template<typename T>
+struct B {
+  B(T) {}
+  
+  A nodes;
+};
+
+
+// PR4853
+template <typename T> class List {
+public:
+  List(){ }     // List<BinomialNode<int>*>::List() remains undefined.
+  ~List() {}
+};
+
+template <typename T> class Node {
+ int i;
+public:
+ Node(){ }      // Node<BinomialNode<int>*>::Node() remains undefined.
+ ~Node() {}
+};
+
+
+template<typename T> class BinomialNode : Node<BinomialNode<T>*> {
+public:
+  BinomialNode(T value) {}
+  List<BinomialNode<T>*> nodes;
+};
+
+int main() {
+  B<int> *n = new B<int>(4);
+  BinomialNode<int> *node = new BinomialNode<int>(1);
+  delete node;
+}
+
+// CHECK-LP64: __ZN4NodeIP12BinomialNodeIiEEC2Ev:
+// CHECK-LP64: __ZN4ListIP12BinomialNodeIiEEC1Ev:
+// CHECK-LP64: __ZN4ListIP12BinomialNodeIiEED1Ev:
+
+// CHECK-LP32: __ZN4NodeIP12BinomialNodeIiEEC2Ev:
+// CHECK-LP32: __ZN4ListIP12BinomialNodeIiEEC1Ev:
+// CHECK-LP32: __ZN4ListIP12BinomialNodeIiEED1Ev:
diff --git a/test/CodeGenCXX/constructors.cpp b/test/CodeGenCXX/constructors.cpp
new file mode 100644
index 0000000..e070905
--- /dev/null
+++ b/test/CodeGenCXX/constructors.cpp
@@ -0,0 +1,94 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -emit-llvm -o - | FileCheck %s
+
+struct Member { int x; Member(); Member(int); Member(const Member &); };
+struct VBase { int x; VBase(); VBase(int); VBase(const VBase &); };
+
+struct ValueClass {
+  ValueClass(int x, int y) : x(x), y(y) {}
+  int x;
+  int y;
+}; // subject to ABI trickery
+
+
+
+/* Test basic functionality. */
+struct A {
+  A(struct Undeclared &);
+  A(ValueClass);
+  Member mem;
+};
+
+A::A(struct Undeclared &ref) : mem(0) {}
+
+// Check that delegation works.
+// CHECK: define void @_ZN1AC1ER10Undeclared(
+// CHECK: call void @_ZN1AC2ER10Undeclared(
+
+// CHECK: define void @_ZN1AC2ER10Undeclared(
+// CHECK: call void @_ZN6MemberC1Ei(
+
+A::A(ValueClass v) : mem(v.y - v.x) {}
+
+// CHECK: define void @_ZN1AC1E10ValueClass(
+// CHECK: call void @_ZN1AC2E10ValueClass(
+
+// CHECK: define void @_ZN1AC2E10ValueClass(
+// CHECK: call void @_ZN6MemberC1Ei(
+
+
+/* Test that things work for inheritance. */
+struct B : A {
+  B(struct Undeclared &);
+  Member mem;
+};
+
+B::B(struct Undeclared &ref) : A(ref), mem(1) {}
+
+// CHECK: define void @_ZN1BC1ER10Undeclared(
+// CHECK: call void @_ZN1BC2ER10Undeclared(
+
+// CHECK: define void @_ZN1BC2ER10Undeclared(
+// CHECK: call void @_ZN1AC2ER10Undeclared(
+// CHECK: call void @_ZN6MemberC1Ei(
+
+
+
+/* Test that the delegation optimization is disabled for classes with
+   virtual bases (for now).  This is necessary because a vbase
+   initializer could access one of the parameter variables by
+   reference.  That's a solvable problem, but let's not solve it right
+   now. */
+struct C : virtual A {
+  C(int);
+  Member mem;
+};
+C::C(int x) : A(ValueClass(x, x+1)), mem(x * x) {}
+
+// CHECK: define void @_ZN1CC1Ei(
+// CHECK: call void @_ZN10ValueClassC1Eii(
+// CHECK: call void @_ZN1AC2E10ValueClass(
+// CHECK: call void @_ZN6MemberC1Ei(
+
+// CHECK: define void @_ZN1CC2Ei(
+// CHECK: call void @_ZN6MemberC1Ei(
+
+
+
+/* Test that the delegation optimization is disabled for varargs
+   constructors. */
+struct D : A {
+  D(int, ...);
+  Member mem;
+};
+
+D::D(int x, ...) : A(ValueClass(x, x+1)), mem(x*x) {}
+
+// CHECK: define void @_ZN1DC1Eiz(
+// CHECK: call void @_ZN10ValueClassC1Eii(
+// CHECK: call void @_ZN1AC2E10ValueClass(
+// CHECK: call void @_ZN6MemberC1Ei(
+
+// CHECK: define void @_ZN1DC2Eiz(
+// CHECK: call void @_ZN10ValueClassC1Eii(
+// CHECK: call void @_ZN1AC2E10ValueClass(
+// CHECK: call void @_ZN6MemberC1Ei(
diff --git a/test/CodeGenCXX/conversion-function.cpp b/test/CodeGenCXX/conversion-function.cpp
new file mode 100644
index 0000000..e2f8f7e
--- /dev/null
+++ b/test/CodeGenCXX/conversion-function.cpp
@@ -0,0 +1,120 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++0x -S %s -o %t-64.s
+// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s
+// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++0x -S %s -o %t-32.s
+// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s
+// XFAIL: *
+extern "C" int printf(...);
+struct S {
+  operator int();
+};
+
+S::operator int() {
+  return 10;
+}
+
+int f(S s) {
+  return s;
+}
+
+class X { // ...
+  public: operator int() { printf("operator int()\n"); return iX; }
+  public: operator float() { printf("operator float()\n"); return fX; }
+  X() : iX(100), fX(1.234)  {}
+  int iX;
+  float fX;
+};
+
+X x;
+
+struct Z {
+    operator X() { printf("perator X()\n"); x.iX += iZ; x.fX += fZ; return x; }
+    int iZ;
+    float fZ;
+    Z() : iZ(1), fZ(1.00) {}
+};
+
+Z z;
+
+class Y { // ...
+  public: operator Z(){printf("perator Z()\n"); return z; }
+};
+
+Y y;
+
+int count=0;
+class O { // ...
+public: 
+  operator int(){ return ++iO; }
+  O() : iO(count++) {}
+  int iO;
+};
+
+void g(O a, O b) {
+  int i = (a) ? 1+a : 0; 
+  int j = (a&&b) ? a+b : i; 
+  if (a) { }
+  printf("i = %d j = %d a.iO = %d b.iO = %d\n", i, j, a.iO, b.iO);
+}
+
+int main() {
+  int c = X(Z(y)); // OK: y.operator Z().operator X().operator int()
+  printf("c = %d\n", c);
+  float f = X(Z(y));
+  printf("f = %f\n", f);
+  int i = x;
+  printf("i = %d float = %f\n", i, float(x));
+  i = int(X(Z(y)));
+  f = float(X(Z(y)));
+  printf("i = %d float = %f\n", i,f);
+  f = (float)x;
+  i = (int)x;
+  printf("i = %d float = %f\n", i,f);
+
+  int d = (X)((Z)y);
+  printf("d = %d\n", d);
+
+  int e = (int)((X)((Z)y));
+  printf("e = %d\n", e);
+  O o1, o2;
+  g(o1, o2);
+}
+
+// Test. Conversion in base class is visible in derived class.
+class XB {
+  int a;
+public:
+  operator int();
+};
+
+class Yb : public XB {
+  double b;
+public:
+  operator char();
+};
+
+void f(Yb& a) {
+  int i = a; // OK. calls XB::operator int();
+  char ch = a;  // OK. calls Yb::operator char();
+}
+
+struct A {
+  operator int() const;
+};
+
+// CHECK-LP64: .globl __ZN1ScviEv
+// CHECK-LP64-NEXT: __ZN1ScviEv:
+// CHECK-LP64: callq __ZN1Ycv1ZEv
+// CHECK-LP64: callq __ZN1Zcv1XEv
+// CHECK-LP64: callq __ZN1XcviEv
+// CHECK-LP64: callq __ZN1XcvfEv
+// CHECK-LP64: callq __ZN2XBcviEv
+// CHECK-LP64: callq __ZN2YbcvcEv
+
+// CHECK-LP32: .globl  __ZN1ScviEv
+// CHECK-LP32-NEXT: __ZN1ScviEv:
+// CHECK-LP32: call L__ZN1Ycv1ZEv
+// CHECK-LP32: call L__ZN1Zcv1XEv
+// CHECK-LP32: call L__ZN1XcviEv
+// CHECK-LP32: call L__ZN1XcvfEv
+// CHECK-LP32: call L__ZN2XBcviEv
+// CHECK-LP32: call L__ZN2YbcvcEv
diff --git a/test/CodeGenCXX/conversion-operator-base.cpp b/test/CodeGenCXX/conversion-operator-base.cpp
new file mode 100644
index 0000000..8fbeadf
--- /dev/null
+++ b/test/CodeGenCXX/conversion-operator-base.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -emit-llvm-only %s -verify
+// PR5730
+
+struct A { operator int(); float y; };
+struct B : A { double z; };
+void a() { switch(B()) {} }
+
diff --git a/test/CodeGenCXX/convert-to-fptr.cpp b/test/CodeGenCXX/convert-to-fptr.cpp
new file mode 100644
index 0000000..dc49401
--- /dev/null
+++ b/test/CodeGenCXX/convert-to-fptr.cpp
@@ -0,0 +1,46 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++0x -S %s -o %t-64.s
+// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s
+// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++0x -S %s -o %t-32.s
+// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s
+
+extern "C" int printf(...);
+
+int f1(int arg)  { return arg; }; 
+
+int f2(float arg) { return int(arg); }; 
+
+typedef int (*fp1)(int); 
+
+typedef int (*fp2)(float); 
+
+struct A {
+  operator fp1() { return f1; }
+  operator fp2() { return f2; } 
+} a;
+
+
+// Test for function reference.
+typedef int (&fr1)(int); 
+typedef int (&fr2)(float); 
+
+struct B {
+  operator fr1() { return f1; }
+  operator fr2() { return f2; } 
+} b;
+
+int main()
+{
+ int i = a(10); // Calls f1 via pointer returned from conversion function
+ printf("i = %d\n", i);
+
+ int j = b(20); // Calls f1 via pointer returned from conversion function
+ printf("j = %d\n", j);
+ return 0;
+}
+
+// CHECK-LP64: callq __ZN1AcvPFiiEEv
+// CHECK-LP64: callq __ZN1BcvRFiiEEv
+
+// CHECK-LP32: call L__ZN1AcvPFiiEEv
+// CHECK-LP32: call L__ZN1BcvRFiiEEv
+
diff --git a/test/CodeGenCXX/copy-assign-synthesis-1.cpp b/test/CodeGenCXX/copy-assign-synthesis-1.cpp
new file mode 100644
index 0000000..eb761c2
--- /dev/null
+++ b/test/CodeGenCXX/copy-assign-synthesis-1.cpp
@@ -0,0 +1,108 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++0x -S %s -o %t-64.s
+// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s
+// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++0x -S %s -o %t-32.s
+// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s
+
+extern "C" int printf(...);
+
+struct B {
+  B() : B1(3.14), B2(3.15), auB2(3.16)  {} 
+  float B1;
+  float B2;
+  void pr() {
+    printf("B1 = %f B2 = %f auB1 = %f\n", B1, B2, auB1);
+  }
+
+  B& operator=(const B& arg) { B1 = arg.B1; B2 = arg.B2; 
+                               auB1 = arg.auB1; return *this; }
+  union {
+    float auB1;
+    float auB2;
+  };
+};
+
+struct M {
+  M() : M1(10), M2(11) , auM1(12) {} 
+  int M1;
+  int M2;
+  void pr() {
+    printf("M1 = %d M2 = %d auM1 = %d auM2 = %d\n", M1, M2, auM1, auM2);
+  }
+  union {
+    int auM1;
+    int auM2;
+  };
+};
+
+struct N  : B {
+  N() : N1(20), N2(21) {} 
+  int N1;
+  int N2;
+  void pr() {
+    printf("N1 = %d N2 = %d\n", N1, N2);
+    for (unsigned i = 0; i < 3; i++)
+      for (unsigned j = 0; j < 2; j++)
+        printf("arr_b[%d][%d] = %f\n", i,j,arr_b[i][j].B1);
+    B::pr();
+  }
+  N& operator=(const N& arg) {
+    N1 = arg.N1; N2 = arg.N2; 
+    for (unsigned i = 0; i < 3; i++)
+      for (unsigned j = 0; j < 2; j++)
+        arr_b[i][j] = arg.arr_b[i][j];
+    return *this;
+  }
+  B arr_b[3][2];
+};
+
+struct Q  : B {
+  Q() : Q1(30), Q2(31) {} 
+  int Q1;
+  int Q2;
+  void pr() {
+    printf("Q1 = %d Q2 = %d\n", Q1, Q2);
+  }
+};
+
+
+struct X : M , N { 
+  X() : d(0.0), d1(1.1), d2(1.2), d3(1.3) {}
+  double d;
+  double d1;
+  double d2;
+  double d3;
+  void pr() {
+    printf("d = %f d1 = %f d2 = %f d3 = %f\n", d, d1,d2,d3);
+    M::pr(); N::pr();
+    q1.pr(); q2.pr();
+  }
+
+ Q q1, q2;
+}; 
+
+
+X srcX; 
+X dstX; 
+X dstY; 
+
+int main() {
+  dstY = dstX = srcX;
+  srcX.pr();
+  dstX.pr();
+  dstY.pr();
+}
+
+// CHECK-LP64: .globl   __ZN1XaSERKS_
+// CHECK-LP64: .weak_definition  __ZN1XaSERKS_
+// CHECK-LP64: __ZN1XaSERKS_:
+// CHECK-LP64: .globl   __ZN1QaSERKS_
+// CHECK-LP64: .weak_definition  __ZN1QaSERKS_
+// CHECK-LP64: __ZN1QaSERKS_:
+
+// CHECK-LP32: .globl   __ZN1XaSERKS_
+// CHECK-LP32: .weak_definition  __ZN1XaSERKS_
+// CHECK-LP32: __ZN1XaSERKS_:
+// CHECK-LP32: .globl   __ZN1QaSERKS_
+// CHECK-LP32: .weak_definition  __ZN1QaSERKS_
+// CHECK-LP32: __ZN1QaSERKS_:
+
diff --git a/test/CodeGenCXX/copy-assign-synthesis-2.cpp b/test/CodeGenCXX/copy-assign-synthesis-2.cpp
new file mode 100644
index 0000000..c25e046
--- /dev/null
+++ b/test/CodeGenCXX/copy-assign-synthesis-2.cpp
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s
+struct A {};
+A& (A::*x)(const A&) = &A::operator=;
+// CHECK: define linkonce_odr %struct.A* @_ZN1AaSERKS_
diff --git a/test/CodeGenCXX/copy-assign-synthesis-3.cpp b/test/CodeGenCXX/copy-assign-synthesis-3.cpp
new file mode 100644
index 0000000..ce4640a
--- /dev/null
+++ b/test/CodeGenCXX/copy-assign-synthesis-3.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -emit-llvm-only -verify %s
+
+struct A {
+  A& operator=(A&);
+};
+
+struct B {
+  void operator=(B);
+};
+
+struct C {
+  A a;
+  B b;
+  float c;
+  int (A::*d)();
+  _Complex float e;
+  int f[10];
+  A g[2];
+  B h[2];
+};
+void a(C& x, C& y) {
+  x = y;
+}
+
diff --git a/test/CodeGenCXX/copy-assign-synthesis.cpp b/test/CodeGenCXX/copy-assign-synthesis.cpp
new file mode 100644
index 0000000..e9fc0c3
--- /dev/null
+++ b/test/CodeGenCXX/copy-assign-synthesis.cpp
@@ -0,0 +1,79 @@
+// RUN: %clang_cc1 -emit-llvm -o %t %s
+// RUN: grep "_ZN1XaSERK1X" %t | count 0
+
+extern "C" int printf(...);
+
+struct B {
+  B() : B1(3.14), B2(3.15), auB2(3.16)  {} 
+  float B1;
+  float B2;
+  void pr() {
+    printf("B1 = %f B2 = %f auB1 = %f\n", B1, B2, auB1);
+  }
+
+  union {
+    float auB1;
+    float auB2;
+  };
+};
+
+struct M {
+  M() : M1(10), M2(11) , auM1(12) {} 
+  int M1;
+  int M2;
+  void pr() {
+    printf("M1 = %d M2 = %d auM1 = %d auM2 = %d\n", M1, M2, auM1, auM2);
+  }
+  union {
+    int auM1;
+    int auM2;
+  };
+};
+
+struct N  : B {
+  N() : N1(20), N2(21) {} 
+  int N1;
+  int N2;
+  void pr() {
+    printf("N1 = %d N2 = %d\n", N1, N2);
+    B::pr();
+  }
+};
+
+struct Q {
+  Q() : Q1(30), Q2(31) {} 
+  int Q1;
+  int Q2;
+  void pr() {
+    printf("Q1 = %d Q2 = %d\n", Q1, Q2);
+  }
+};
+
+
+struct X : M , N { 
+  X() : d(0.0), d1(1.1), d2(1.2), d3(1.3) {}
+  double d;
+  double d1;
+  double d2;
+  double d3;
+  void pr() {
+    printf("d = %f d1 = %f d2 = %f d3 = %f\n", d, d1,d2,d3);
+    M::pr(); N::pr();
+    q1.pr(); q2.pr();
+  }
+
+ Q q1, q2;
+}; 
+
+
+X srcX; 
+X dstX; 
+X dstY; 
+
+int main() {
+  dstY = dstX = srcX;
+  srcX.pr();
+  dstX.pr();
+  dstY.pr();
+}
+
diff --git a/test/CodeGenCXX/copy-constructor-elim-2.cpp b/test/CodeGenCXX/copy-constructor-elim-2.cpp
new file mode 100644
index 0000000..3a06c10
--- /dev/null
+++ b/test/CodeGenCXX/copy-constructor-elim-2.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+
+struct A { int x; A(int); ~A(); };
+A f() { return A(0); }
+// CHECK: define void @_Z1fv
+// CHECK: call void @_ZN1AC1Ei
+// CHECK-NEXT: ret void
diff --git a/test/CodeGenCXX/copy-constructor-elim.cpp b/test/CodeGenCXX/copy-constructor-elim.cpp
new file mode 100644
index 0000000..c883584
--- /dev/null
+++ b/test/CodeGenCXX/copy-constructor-elim.cpp
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -emit-llvm -o %t %s
+// RUN: grep "_ZN1CC1ERK1C" %t | count 0
+// RUN: grep "_ZN1SC1ERK1S" %t | count 0
+
+extern "C" int printf(...);
+
+
+struct C {
+  C() : iC(6) {printf("C()\n"); }
+  C(const C& c) { printf("C(const C& c)\n"); }
+  int iC;
+};
+
+C foo() {
+  return C();
+};
+
+class X { // ...
+public: 
+  X(int) {}
+  X(const X&, int i = 1, int j = 2, C c = foo()) {
+    printf("X(const X&, %d, %d, %d)\n", i, j, c.iC);
+  }
+};
+
+
+struct S {
+  S();
+};
+
+S::S() { printf("S()\n"); }
+
+void Call(S) {};
+
+int main() {
+  X a(1);
+  X b(a, 2);
+  X c = b;
+  X d(a, 5, 6);
+  S s;
+  Call(s);
+}
diff --git a/test/CodeGenCXX/copy-constructor-synthesis-2.cpp b/test/CodeGenCXX/copy-constructor-synthesis-2.cpp
new file mode 100644
index 0000000..2f7c79b
--- /dev/null
+++ b/test/CodeGenCXX/copy-constructor-synthesis-2.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+
+struct A { virtual void a(); };
+A x(A& y) { return y; }
+
+// CHECK: define linkonce_odr void @_ZN1AC1ERKS_(
+// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTV1A, i64 0, i64 2)
diff --git a/test/CodeGenCXX/copy-constructor-synthesis.cpp b/test/CodeGenCXX/copy-constructor-synthesis.cpp
new file mode 100644
index 0000000..9cafd0a
--- /dev/null
+++ b/test/CodeGenCXX/copy-constructor-synthesis.cpp
@@ -0,0 +1,156 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -o - %s | FileCheck %s
+
+extern "C" int printf(...);
+
+int init = 100;
+
+struct M {
+  int iM;
+  M() : iM(init++) {}
+};
+
+struct N {
+  int iN;
+  N() : iN(200) {}
+  N(N const & arg){this->iN = arg.iN; }
+};
+
+struct P {
+  int iP;
+  P() : iP(init++) {}
+};
+
+
+// CHECK: define linkonce_odr void @_ZN1XC1ERKS_
+struct X  : M, N, P { // ...
+  X() : f1(1.0), d1(2.0), i1(3), name("HELLO"), bf1(0xff), bf2(0xabcd),
+        au_i1(1234), au1_4("MASKED") {}
+  P p0;
+  void pr() {
+    printf("iM = %d iN = %d, m1.iM = %d\n", iM, iN, m1.iM); 
+    printf("im = %d p0.iP = %d, p1.iP = %d\n", iP, p0.iP, p1.iP); 
+    printf("f1 = %f  d1 = %f  i1 = %d name(%s) \n", f1, d1, i1, name);
+    printf("bf1 = %x  bf2 = %x\n", bf1, bf2);
+    printf("au_i2 = %d\n", au_i2); 
+    printf("au1_1 = %s\n", au1_1); 
+  }
+  M m1;
+  P p1;
+  float f1;
+  double d1;
+  int i1;
+  const char *name;
+  unsigned bf1 : 8;
+  unsigned bf2 : 16;
+  int arr[2];
+  _Complex float complex;
+
+  union {
+    int au_i1;
+    int au_i2;
+  };
+  union {
+    const char * au1_1;
+    float au1_2;
+    int au1_3;
+    const char * au1_4;
+  };
+};
+
+static int ix = 1;
+// class with user-defined copy constructor.
+struct S {
+  S() : iS(ix++) {  }
+  S(const S& arg) { *this = arg; }
+  int iS;
+};
+
+// class with trivial copy constructor.
+struct I {
+  I() : iI(ix++) {  }
+  int iI;
+};
+
+struct XM {
+  XM() {  }
+  double dXM;
+  S ARR_S[3][4][2];
+  void pr() {
+   for (unsigned i = 0; i < 3; i++)
+     for (unsigned j = 0; j < 4; j++)
+      for (unsigned k = 0; k < 2; k++)
+        printf("ARR_S[%d][%d][%d] = %d\n", i,j,k, ARR_S[i][j][k].iS);
+   for (unsigned i = 0; i < 3; i++)
+      for (unsigned k = 0; k < 2; k++)
+        printf("ARR_I[%d][%d] = %d\n", i,k, ARR_I[i][k].iI);
+  }
+  I ARR_I[3][2];
+};
+
+int main() {
+  X a;
+  X b(a);
+  b.pr();
+  X x;
+  X c(x);
+  c.pr();
+
+  XM m0;
+  XM m1 = m0;
+  m1.pr();
+}
+
+struct A {
+};
+
+struct B : A {
+  A &a;
+};
+
+void f(const B &b1) {
+  B b2(b1);
+}
+
+// PR6628
+namespace PR6628 {
+
+struct T {
+  T();
+  ~T();
+
+  double d;
+};
+
+struct A {
+  A(const A &other, const T &t = T(), const T& t2 = T());
+};
+
+struct B : A {
+  A a1;
+  A a2;
+  A a[10];
+};
+
+// Force the copy constructor to be synthesized.
+void f(B b1) {
+  B b2 = b1;
+}
+
+// CHECK: define linkonce_odr void @_ZN6PR66281BC2ERKS0_
+// CHECK: call void @_ZN6PR66281TC1Ev
+// CHECK: call void @_ZN6PR66281TC1Ev
+// CHECK: call void @_ZN6PR66281AC2ERKS0_RKNS_1TES5_
+// CHECK: call void @_ZN6PR66281TD1Ev
+// CHECK: call void @_ZN6PR66281TD1Ev
+// CHECK: call void @_ZN6PR66281TC1Ev
+// CHECK: call void @_ZN6PR66281TC1Ev
+// CHECK: call void @_ZN6PR66281AC1ERKS0_RKNS_1TES5_
+// CHECK: call void @_ZN6PR66281TD1Ev
+// CHECK: call void @_ZN6PR66281TD1Ev
+// CHECK: call void @_ZN6PR66281TC1Ev
+// CHECK: call void @_ZN6PR66281TC1Ev
+// CHECK: call void @_ZN6PR66281AC1ERKS0_RKNS_1TES5_
+// CHECK: call void @_ZN6PR66281TD1Ev
+// CHECK: call void @_ZN6PR66281TD1Ev
+}
+
diff --git a/test/CodeGenCXX/copy-initialization.cpp b/test/CodeGenCXX/copy-initialization.cpp
new file mode 100644
index 0000000..62b9f26
--- /dev/null
+++ b/test/CodeGenCXX/copy-initialization.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
+
+struct Foo {
+  Foo();
+  Foo(const Foo&);
+};
+
+struct Bar {
+  Bar();
+  operator const Foo&() const;
+};
+
+void f(Foo);
+
+// CHECK: define void @_Z1g3Foo(%struct.Bar* %foo)
+void g(Foo foo) {
+  // CHECK: call void @_ZN3BarC1Ev
+  // CHECK: @_ZNK3BarcvRK3FooEv
+  // CHECK: call void @_Z1f3Foo
+  f(Bar());
+  // CHECK: call void @_ZN3FooC1Ev
+  // CHECK: call void @_Z1f3Foo
+  f(Foo());
+  // CHECK: call void @_ZN3FooC1ERKS_
+  // CHECK: call void @_Z1f3Foo
+  f(foo);
+  // CHECK: ret
+}
+
diff --git a/test/CodeGenCXX/cxx-apple-kext.cpp b/test/CodeGenCXX/cxx-apple-kext.cpp
new file mode 100644
index 0000000..8d67b53
--- /dev/null
+++ b/test/CodeGenCXX/cxx-apple-kext.cpp
@@ -0,0 +1,36 @@
+// RUN: %clang -ccc-host-triple x86_64-apple-darwin10 %s -flto -S -o - |\
+// RUN:   FileCheck --check-prefix=CHECK-NO-KEXT %s
+// RUN: %clang -ccc-host-triple x86_64-apple-darwin10 %s -fapple-kext -flto -S -o - |\
+// RUN:   FileCheck --check-prefix=CHECK-KEXT %s
+
+// CHECK-NO-KEXT: @_ZTI3foo = {{.*}} @_ZTVN10__cxxabiv117
+// CHECK-NO-KEXT-NOT: _GLOBAL__D_a
+// CHECK-NO-KEXT: @is_hosted = global
+// CHECK-NO-KEXT: call i32 @__cxa_atexit({{.*}} @_ZN3fooD1Ev
+// CHECK-NO-KEXT: declare i32 @__cxa_atexit
+
+// CHECK-KEXT: @_ZTV3foo = 
+// CHECK-KEXT-NOT: @_ZTVN10__cxxabiv117
+// CHECK-KEXT-NOT: call i32 @__cxa_atexit({{.*}} @_ZN3fooD1Ev
+// CHECK-KEXT-NOT: declare i32 @__cxa_atexit
+// CHECK-KEXT: @is_freestanding = global
+// CHECK-KEXT: _GLOBAL__D_a
+// CHECK-KEXT: call void @_ZN3fooD1Ev(%class.foo* @a)
+
+class foo {
+public:
+  foo();
+  virtual ~foo();
+};
+
+foo a;
+foo::~foo() {}
+
+#if !(__STDC_HOSTED__ == 1)
+int is_freestanding = 1;
+#else
+int is_hosted = 1;
+#endif
+
+extern "C" void f1() {
+}
diff --git a/test/CodeGenCXX/debug-info.cpp b/test/CodeGenCXX/debug-info.cpp
new file mode 100644
index 0000000..6bb9533
--- /dev/null
+++ b/test/CodeGenCXX/debug-info.cpp
@@ -0,0 +1,52 @@
+// RUN: %clang_cc1 -emit-llvm-only -g %s
+template<typename T> struct Identity {
+  typedef T Type;
+};
+
+void f(Identity<int>::Type a) {}
+void f(Identity<int> a) {}
+void f(int& a) { }
+
+template<typename T> struct A {
+  A<T> *next;
+};
+void f(A<int>) { }
+
+struct B { };
+
+void f() {
+  int B::*a = 0;
+  void (B::*b)() = 0;
+}
+
+namespace EmptyNameCrash {
+  struct A { A(); };
+  typedef struct { A x; } B;
+  B x;
+}
+
+// PR4890
+namespace PR4890 {
+  struct X {
+    ~X();
+  };
+
+  X::~X() { }
+}
+
+namespace VirtualDtor {
+  struct Y {
+    virtual ~Y();
+  };
+  
+  Y::~Y() { }
+}
+
+namespace VirtualBase {
+  struct A { };
+  struct B : virtual A { };
+
+  void f() {
+    B b;
+  }
+}
diff --git a/test/CodeGenCXX/decl-ref-init.cpp b/test/CodeGenCXX/decl-ref-init.cpp
new file mode 100644
index 0000000..c215b1b
--- /dev/null
+++ b/test/CodeGenCXX/decl-ref-init.cpp
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -S %s -o %t-64.s
+// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s
+// RUN: %clang_cc1 -triple i386-apple-darwin -S %s -o %t-32.s
+// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s
+
+struct A {};
+
+struct B 
+{ 
+  operator A&();
+}; 
+
+
+struct D : public B {
+  operator A();
+};
+
+extern B f(); 
+extern D d(); 
+
+int main() {
+	const A& rca = f();
+	const A& rca2 = d();
+}
+
+// CHECK-LP64: callq    __ZN1BcvR1AEv
+// CHECK-LP64: callq    __ZN1BcvR1AEv
+
+// CHECK-LP32: call     L__ZN1BcvR1AEv
+// CHECK-LP32: call     L__ZN1BcvR1AEv
diff --git a/test/CodeGenCXX/default-arg-temps.cpp b/test/CodeGenCXX/default-arg-temps.cpp
new file mode 100644
index 0000000..e523eb0
--- /dev/null
+++ b/test/CodeGenCXX/default-arg-temps.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -emit-llvm %s -o %t -triple=x86_64-apple-darwin9
+
+struct T {
+  T();
+  ~T();
+};
+
+void f(const T& t = T());
+
+class X { // ...
+public:
+        X();
+        X(const X&, const T& t = T());
+};
+
+void g() {
+  // RUN: grep "call void @_ZN1TC1Ev" %t | count 4
+  // RUN: grep "call void @_ZN1TD1Ev" %t | count 4
+  f();
+  f();
+
+  X a;
+  X b(a);
+  X c = a;
+}
+
+
+// RUN: grep memset %t
+class obj{ int a; float b; double d; };
+void h() {
+  obj o = obj();
+}
diff --git a/test/CodeGenCXX/default-arguments.cpp b/test/CodeGenCXX/default-arguments.cpp
new file mode 100644
index 0000000..2ed1567
--- /dev/null
+++ b/test/CodeGenCXX/default-arguments.cpp
@@ -0,0 +1,65 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+
+// PR5484
+namespace PR5484 {
+struct A { };
+extern A a;
+
+void f(const A & = a);
+
+void g() {
+  f();
+}
+}
+
+struct A1 {
+ A1();
+ ~A1();
+};
+
+struct A2 {
+ A2();
+ ~A2();
+};
+
+struct B {
+ B(const A1& = A1(), const A2& = A2());
+};
+
+// CHECK: define void @_Z2f1v()
+void f1() {
+
+ // CHECK: call void @_ZN2A1C1Ev(
+ // CHECK: call void @_ZN2A2C1Ev(
+ // CHECK: call void @_ZN1BC1ERK2A1RK2A2(
+ // CHECK: call void @_ZN2A2D1Ev
+ // CHECK: call void @_ZN2A1D1Ev
+ B bs[2];
+}
+
+struct C {
+ B bs[2];
+ C();
+};
+
+// CHECK: define void @_ZN1CC1Ev(
+// CHECK: call void @_ZN1CC2Ev(
+
+// CHECK: define void @_ZN1CC2Ev(
+// CHECK: call void @_ZN2A1C1Ev(
+// CHECK: call void @_ZN2A2C1Ev(
+// CHECK: call void @_ZN1BC1ERK2A1RK2A2(
+// CHECK: call void @_ZN2A2D1Ev
+// CHECK: call void @_ZN2A1D1Ev
+C::C() { }
+
+// CHECK: define void @_Z2f3v()
+void f3() {
+ // CHECK: call void @_ZN2A1C1Ev(
+ // CHECK: call void @_ZN2A2C1Ev(
+ // CHECK: call void @_ZN1BC1ERK2A1RK2A2(
+ // CHECK: call void @_ZN2A2D1Ev
+ // CHECK: call void @_ZN2A1D1Ev
+ B *bs = new B[2];
+ delete bs;
+}
diff --git a/test/CodeGenCXX/default-constructor-default-argument.cpp b/test/CodeGenCXX/default-constructor-default-argument.cpp
new file mode 100644
index 0000000..f2c7f6d
--- /dev/null
+++ b/test/CodeGenCXX/default-constructor-default-argument.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+
+// Check that call to constructor for struct A is generated correctly.
+struct A { A(int x = 2); };
+struct B : public A {};
+B x;
+
+// CHECK: call void @_ZN1AC2Ei
diff --git a/test/CodeGenCXX/default-constructor-for-members.cpp b/test/CodeGenCXX/default-constructor-for-members.cpp
new file mode 100644
index 0000000..1f17746
--- /dev/null
+++ b/test/CodeGenCXX/default-constructor-for-members.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -S %s -o %t-64.s
+// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s
+// RUN: %clang_cc1 -triple i386-apple-darwin -S %s -o %t-32.s
+// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s
+
+extern "C" int printf(...);
+
+struct S {
+  S() { printf("S::S()\n"); }
+  int iS;
+};
+
+struct M {
+  S ARR_S; 
+};
+
+int main() {
+  M m1;
+}
+
+// CHECK-LP64: callq __ZN1SC1Ev
+
+// CHECK-LP32: call L__ZN1SC1Ev
diff --git a/test/CodeGenCXX/default-constructor-template-member.cpp b/test/CodeGenCXX/default-constructor-template-member.cpp
new file mode 100644
index 0000000..e74fb6d
--- /dev/null
+++ b/test/CodeGenCXX/default-constructor-template-member.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s
+
+template <class T> struct A { A(); };
+struct B { A<int> x; };
+void a() {   
+  B b;
+}
+// CHECK: call void @_ZN1BC1Ev
+// CHECK: define linkonce_odr void @_ZN1BC1Ev
+// CHECK: call void @_ZN1AIiEC1Ev
diff --git a/test/CodeGenCXX/default-destructor-nested.cpp b/test/CodeGenCXX/default-destructor-nested.cpp
new file mode 100644
index 0000000..565a727
--- /dev/null
+++ b/test/CodeGenCXX/default-destructor-nested.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 %s -emit-llvm-only
+// PR6294
+
+class A {
+public: virtual ~A();
+};
+class B {
+  class C;
+};
+class B::C : public A {
+  C();
+};
+B::C::C() {}
diff --git a/test/CodeGenCXX/default-destructor-synthesis.cpp b/test/CodeGenCXX/default-destructor-synthesis.cpp
new file mode 100644
index 0000000..fac5cc0
--- /dev/null
+++ b/test/CodeGenCXX/default-destructor-synthesis.cpp
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -O2 -o - | FileCheck %s
+static int count = 0;
+
+struct S {
+  S() { count++; }
+  ~S() { count--; }
+};
+
+struct P {
+  P() { count++; }
+  ~P() { count--; }
+};
+
+struct Q {
+  Q() { count++; }
+  ~Q() { count--; }
+};
+
+struct M : Q, P {
+  S s;
+  Q q;
+  P p;
+  P p_arr[3];
+  Q q_arr[2][3];
+};
+  
+// CHECK: define i32 @_Z1fv() nounwind
+int f() {
+  {
+    count = 1;
+    M a;
+  }
+
+  // CHECK: ret i32 1
+  return count;
+}
diff --git a/test/CodeGenCXX/deferred-global-init.cpp b/test/CodeGenCXX/deferred-global-init.cpp
new file mode 100644
index 0000000..24c8c67
--- /dev/null
+++ b/test/CodeGenCXX/deferred-global-init.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+// PR5967
+
+extern void* foo;
+static void* const a = foo;
+void* bar() { return a; }
+
+// CHECK: @_ZL1a = internal global i8* null
+
+// CHECK: define internal void @__cxx_global_var_init
+// CHECK: load i8** @foo
+// CHECK: ret void
+
+// CHECK: define internal void @_GLOBAL__I_a
+// CHECK: call void @__cxx_global_var_init()
+// CHECK: ret void
diff --git a/test/CodeGenCXX/delete-two-arg.cpp b/test/CodeGenCXX/delete-two-arg.cpp
new file mode 100644
index 0000000..5358747
--- /dev/null
+++ b/test/CodeGenCXX/delete-two-arg.cpp
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -triple i686-pc-linux-gnu %s -o - -emit-llvm -verify | FileCheck %s
+
+struct A { void operator delete(void*,__typeof(sizeof(int))); int x; };
+void a(A* x) { delete x; }
+
+// CHECK: call void @_ZN1AdlEPvj(i8* %{{.*}}, i32 4)
diff --git a/test/CodeGenCXX/delete.cpp b/test/CodeGenCXX/delete.cpp
new file mode 100644
index 0000000..87f8698
--- /dev/null
+++ b/test/CodeGenCXX/delete.cpp
@@ -0,0 +1,59 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+
+void t1(int *a) {
+  delete a;
+}
+
+struct S {
+  int a;
+};
+
+// POD types.
+void t3(S *s) {
+  delete s;
+}
+
+// Non-POD
+struct T {
+  ~T();
+  int a;
+};
+
+// CHECK: define void @_Z2t4P1T
+void t4(T *t) {
+  // CHECK: call void @_ZN1TD1Ev
+  // CHECK-NEXT: bitcast
+  // CHECK-NEXT: call void @_ZdlPv
+  delete t;
+}
+
+// PR5102
+template <typename T>
+class A {
+  operator T *() const;
+};
+
+void f() {
+  A<char*> a;
+  
+  delete a;
+}
+
+namespace test0 {
+  struct A {
+    void *operator new(__SIZE_TYPE__ sz);
+    void operator delete(void *p) { ::operator delete(p); }
+    ~A() {}
+  };
+
+  // CHECK: define void @_ZN5test04testEPNS_1AE(
+  void test(A *a) {
+    // CHECK: call void @_ZN5test01AD1Ev
+    // CHECK-NEXT: bitcast
+    // CHECK-NEXT: call void @_ZN5test01AdlEPv
+    delete a;
+  }
+
+  // CHECK: define linkonce_odr void @_ZN5test01AD1Ev
+  // CHECK: define linkonce_odr void @_ZN5test01AdlEPv
+}
diff --git a/test/CodeGenCXX/derived-to-base-conv.cpp b/test/CodeGenCXX/derived-to-base-conv.cpp
new file mode 100644
index 0000000..f2835b7
--- /dev/null
+++ b/test/CodeGenCXX/derived-to-base-conv.cpp
@@ -0,0 +1,84 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++0x -S %s -o %t-64.s
+// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s
+// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++0x -S %s -o %t-32.s
+// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s
+
+extern "C" int printf(...);
+extern "C" void exit(int);
+
+struct A {
+  A (const A&) { printf("A::A(const A&)\n"); }
+  A() {};
+  ~A() { printf("A::~A()\n"); }
+}; 
+
+struct B : public A {
+  B() {};
+  B(const B& Other) : A(Other) { printf("B::B(const B&)\n"); }
+  ~B() { printf("B::~B()\n"); }
+};
+
+struct C : public B {
+  C() {};
+  C(const C& Other) : B(Other) { printf("C::C(const C&)\n"); }
+  ~C() { printf("C::~C()\n"); }
+}; 
+
+struct X {
+	operator B&() {printf("X::operator B&()\n"); return b; }
+	operator C&() {printf("X::operator C&()\n"); return c; }
+ 	X (const X&) { printf("X::X(const X&)\n"); }
+ 	X () { printf("X::X()\n"); }
+ 	~X () { printf("X::~X()\n"); }
+	B b;
+	C c;
+};
+
+void f(A) {
+  printf("f(A)\n");
+}
+
+
+void func(X x) 
+{
+  f (x);
+}
+
+int main()
+{
+    X x;
+    func(x);
+}
+
+struct Base;
+
+struct Root {
+  operator Base&() { exit(1); }
+};
+
+struct Derived;
+
+struct Base : Root {
+  Base(const Base&) { printf("Base::(const Base&)\n"); }
+  Base() { printf("Base::Base()\n"); }
+  operator Derived&() { exit(1); }
+};
+
+struct Derived : Base {
+};
+
+void foo(Base) {}
+
+void test(Derived bb)
+{
+	// CHECK-LP64-NOT: callq    __ZN4BasecvR7DerivedEv
+	// CHECK-LP32-NOT: callq    L__ZN4BasecvR7DerivedEv
+        foo(bb);
+}
+// CHECK-LP64: callq    __ZN1XcvR1BEv
+// CHECK-LP64: callq    __ZN1AC1ERKS_
+
+// CHECK-LP32: call     L__ZN1XcvR1BEv
+// CHECK-LP32: call     L__ZN1AC1ERKS_
+
+
diff --git a/test/CodeGenCXX/derived-to-base.cpp b/test/CodeGenCXX/derived-to-base.cpp
new file mode 100644
index 0000000..e44fdc5
--- /dev/null
+++ b/test/CodeGenCXX/derived-to-base.cpp
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+struct A { 
+  void f(); 
+  
+  int a;
+};
+
+struct B : A { 
+  double b;
+};
+
+void f() {
+  B b;
+  
+  b.f();
+}
+
+// CHECK: define %struct.B* @_Z1fP1A(%struct.A* %a) nounwind
+B *f(A *a) {
+  // CHECK-NOT: br label
+  // CHECK: ret %struct.B*
+  return static_cast<B*>(a);
+}
+
+// PR5965
+namespace PR5965 {
+
+// CHECK: define %struct.A* @_ZN6PR59651fEP1B(%struct.B* %b) nounwind
+A *f(B* b) {
+  // CHECK-NOT: br label
+  // CHECK: ret %struct.A*
+  return b;
+}
+
+}
+
diff --git a/test/CodeGenCXX/destructor-calls.cpp b/test/CodeGenCXX/destructor-calls.cpp
new file mode 100644
index 0000000..4da46a4
--- /dev/null
+++ b/test/CodeGenCXX/destructor-calls.cpp
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 %s -emit-llvm -o %t
+
+extern "C" int printf(...);
+
+static int val;
+
+struct B {
+  B() : iB(++val) { printf("B()\n"); }
+  int iB;
+  ~B() { printf("~B(%d)\n", iB); --val; }
+};
+
+struct M : B {
+  M() : iM(++val) { printf("M()\n"); }
+  int iM;
+  ~M() { printf("~M(%d)\n", iM); --val; }
+};
+
+struct P {
+  P() : iP(++val) { printf("P()\n"); }
+  int iP;
+  ~P() { printf("~P(%d)\n", iP); --val; }
+};
+
+struct N : M, P {
+  N() { printf("N()\n"); iN = ++val; }
+  ~N() { printf("~N(%d) val = %d\n", iN, --val);  }
+  int iN;
+  M m;
+  P p;
+};
+
+struct O : B { 
+  ~O() { return; } 
+};
+
+int main() {
+  N n1;
+  N n2;
+  O o;
+}
diff --git a/test/CodeGenCXX/destructor-debug-info.cpp b/test/CodeGenCXX/destructor-debug-info.cpp
new file mode 100644
index 0000000..9e32275
--- /dev/null
+++ b/test/CodeGenCXX/destructor-debug-info.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -g -S -emit-llvm -o %t %s
+// RUN: grep "i32 20, i32 3, metadata" %t | count 1
+// Check there is a line number entry for line 20 where b1 is destructed.
+class A { int a; };
+class B {
+public:
+  B() { a = new A; }
+  ~B() { delete a; }
+private:
+  A *a;
+};
+
+void fn(B b);
+
+int i;
+void foo() {
+  if (i) {
+    B b1;
+    fn (b1);
+  }
+}
diff --git a/test/CodeGenCXX/destructors.cpp b/test/CodeGenCXX/destructors.cpp
new file mode 100644
index 0000000..d40b174
--- /dev/null
+++ b/test/CodeGenCXX/destructors.cpp
@@ -0,0 +1,149 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - -mconstructor-aliases | FileCheck %s
+
+// CHECK: @_ZN5test01AD1Ev = alias {{.*}} @_ZN5test01AD2Ev
+// CHECK: @_ZN5test11MD2Ev = alias {{.*}} @_ZN5test11AD2Ev
+// CHECK: @_ZN5test11ND2Ev = alias {{.*}} @_ZN5test11AD2Ev
+// CHECK: @_ZN5test11OD2Ev = alias {{.*}} @_ZN5test11AD2Ev
+// CHECK: @_ZN5test11SD2Ev = alias bitcast {{.*}} @_ZN5test11AD2Ev
+
+struct A {
+  int a;
+  
+  ~A();
+};
+
+// Base with non-trivial destructor
+struct B : A {
+  ~B();
+};
+
+B::~B() { }
+
+// Field with non-trivial destructor
+struct C {
+  A a;
+  
+  ~C();
+};
+
+C::~C() { }
+
+// PR5084
+template<typename T>
+class A1 {
+  ~A1();
+};
+
+template<> A1<char>::~A1();
+
+// PR5529
+namespace PR5529 {
+  struct A {
+    ~A();
+  };
+  
+  A::~A() { }
+  struct B : A {
+    virtual ~B();
+  };
+  
+  B::~B()  {}
+}
+
+// FIXME: there's a known problem in the codegen here where, if one
+// destructor throws, the remaining destructors aren't run.  Fix it,
+// then make this code check for it.
+namespace test0 {
+  void foo();
+  struct VBase { ~VBase(); };
+  struct Base { ~Base(); };
+  struct Member { ~Member(); };
+
+  struct A : Base {
+    Member M;
+    ~A();
+  };
+
+  // The function-try-block won't suppress -mconstructor-aliases here.
+  A::~A() try { } catch (int i) {}
+
+// complete destructor alias tested above
+
+// CHECK: define void @_ZN5test01AD2Ev
+// CHECK: invoke void @_ZN5test06MemberD1Ev
+// CHECK:   unwind label [[MEM_UNWIND:%[a-zA-Z0-9.]+]]
+// CHECK: invoke void @_ZN5test04BaseD2Ev
+// CHECK:   unwind label [[BASE_UNWIND:%[a-zA-Z0-9.]+]]
+
+  struct B : Base, virtual VBase {
+    Member M;
+    ~B();
+  };
+  B::~B() try { } catch (int i) {}
+  // It will suppress the delegation optimization here, though.
+
+// CHECK: define void @_ZN5test01BD1Ev
+// CHECK: invoke void @_ZN5test06MemberD1Ev
+// CHECK:   unwind label [[MEM_UNWIND:%[a-zA-Z0-9.]+]]
+// CHECK: invoke void @_ZN5test04BaseD2Ev
+// CHECK:   unwind label [[BASE_UNWIND:%[a-zA-Z0-9.]+]]
+// CHECK: invoke void @_ZN5test05VBaseD2Ev
+// CHECK:   unwind label [[VBASE_UNWIND:%[a-zA-Z0-9.]+]]
+
+// CHECK: define void @_ZN5test01BD2Ev
+// CHECK: invoke void @_ZN5test06MemberD1Ev
+// CHECK:   unwind label [[MEM_UNWIND:%[a-zA-Z0-9.]+]]
+// CHECK: invoke void @_ZN5test04BaseD2Ev
+// CHECK:   unwind label [[BASE_UNWIND:%[a-zA-Z0-9.]+]]
+}
+
+// Test base-class aliasing.
+namespace test1 {
+  struct A { ~A(); char ***m; }; // non-trivial destructor
+  struct B { ~B(); }; // non-trivial destructor
+  struct Empty { }; // trivial destructor, empty
+  struct NonEmpty { int x; }; // trivial destructor, non-empty
+
+  // There must be a definition in this translation unit for the alias
+  // optimization to apply.
+  A::~A() { delete m; }
+
+  struct M : A { ~M(); };
+  M::~M() {} // alias tested above
+
+  struct N : A, Empty { ~N(); };
+  N::~N() {} // alias tested above
+
+  struct O : Empty, A { ~O(); };
+  O::~O() {} // alias tested above
+
+  struct P : NonEmpty, A { ~P(); };
+  P::~P() {} // CHECK: define void @_ZN5test11PD2Ev
+
+  struct Q : A, B { ~Q(); };
+  Q::~Q() {} // CHECK: define void @_ZN5test11QD2Ev
+
+  struct R : A { ~R(); };
+  R::~R() { A a; } // CHECK: define void @_ZN5test11RD2Ev
+
+  struct S : A { ~S(); int x; };
+  S::~S() {} // alias tested above
+
+  struct T : A { ~T(); B x; };
+  T::~T() {} // CHECK: define void @_ZN5test11TD2Ev
+
+  // The VTT parameter prevents this.  We could still make this work
+  // for calling conventions that are safe against extra parameters.
+  struct U : A, virtual B { ~U(); };
+  U::~U() {} // CHECK: define void @_ZN5test11UD2Ev
+}
+
+// PR6471
+namespace test2 {
+  struct A { ~A(); char ***m; };
+  struct B : A { ~B(); };
+
+  B::~B() {}
+  // CHECK: define void @_ZN5test21BD2Ev
+  // CHECK: call void @_ZN5test21AD2Ev
+}
diff --git a/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp b/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp
new file mode 100644
index 0000000..74795b5
--- /dev/null
+++ b/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+
+struct A {
+  virtual void f();
+  
+  A h();
+};
+
+A g();
+
+void f(A a, A *ap, A& ar) {
+  // This should not be a virtual function call.
+  
+  // CHECK: call void @_ZN1A1fEv(%struct.A* %a)
+  a.f();
+
+  // CHECK: call void %  
+  ap->f();
+
+  // CHECK: call void %  
+  ar.f();
+  
+  // CHECK: call void @_ZN1A1fEv
+  A().f();
+
+  // CHECK: call void @_ZN1A1fEv
+  g().f();
+  
+  // CHECK: call void @_ZN1A1fEv
+  a.h().f();
+}
+
+struct B {
+  virtual void f();
+  ~B();
+  
+  B h();
+};
+
+
+void f() {
+  // CHECK: call void @_ZN1B1fEv
+  B().f();
+  
+  // CHECK: call void @_ZN1B1fEv
+  B().h().f();
+}
diff --git a/test/CodeGenCXX/dynamic-cast.cpp b/test/CodeGenCXX/dynamic-cast.cpp
new file mode 100644
index 0000000..aeb2a64
--- /dev/null
+++ b/test/CodeGenCXX/dynamic-cast.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 %s -emit-llvm-only
+
+struct A { virtual void f(); };
+struct B : A { };
+
+const B& f(A *a) {
+  return dynamic_cast<const B&>(*a);
+}
diff --git a/test/CodeGenCXX/dyncast.cpp b/test/CodeGenCXX/dyncast.cpp
new file mode 100644
index 0000000..127cdd8
--- /dev/null
+++ b/test/CodeGenCXX/dyncast.cpp
@@ -0,0 +1,394 @@
+// RUN: %clang_cc1 -I%S -triple x86_64-apple-darwin -std=c++0x -emit-llvm %s -o %t.ll
+// RUN: FileCheck -check-prefix LL --input-file=%t.ll %s
+// XFAIL: win32
+
+#include <typeinfo>
+
+class test1_A { virtual void f() { } };
+class test1_B { virtual void g() { } };
+class test1_D : public virtual test1_A, private test1_B {};
+class test1_E : public test1_D, public test1_B {};
+class test1_F : public test1_E, public test1_D {};
+
+extern test1_D test1_d;
+extern test1_F test1_f;
+
+extern "C" int printf(const char *str...);
+
+#define S(V, N) if (V) printf("PASS: %d\n", N); else printf("FAIL: %d\n", N)
+
+void test1() {
+  test1_B* bp = (test1_B*)&test1_d;
+  test1_A* ap = &test1_d;
+  // This throws
+  //  test1_D&  dr = dynamic_cast<D&>(*bp);
+  test1_D* dp = dynamic_cast<test1_D*>(bp);
+  S(dp == 0, 1);
+  ap = dynamic_cast<test1_A*>(bp);
+  S(ap == 0, 2);
+  bp = dynamic_cast<test1_B*>(ap);
+  S(bp == 0, 3);
+  ap = dynamic_cast<test1_A*>(&test1_d);
+  S(ap != 0, 4);
+  // FIXME: Doesn't work yet, gcc fails this at compile time.  We'd need access
+  // control for this to work.
+  // bp = dynamic_cast<test1_B*>(&test1_d);
+  // S(bp == 0, 5);
+  {
+    test1_A*  ap  = &test1_f;
+    S(ap != 0, 6);
+    test1_D*  dp  = dynamic_cast<test1_D*>(ap);
+    S(dp == 0, 7);
+    // cast from virtual base
+    test1_E*  ep1 = dynamic_cast<test1_E*>(ap);
+    S(ep1 != 0, 8);
+  }
+  dp = dynamic_cast<test1_D*>(&test1_d);
+  S(dp == &test1_d, 9);
+  const test1_D *cdp = dynamic_cast<const test1_D*>(&test1_d);
+  S(cdp == &test1_d, 10);
+  dp = dynamic_cast<test1_D*>((test1_A*)0);
+  S(dp == 0, 11);
+  ap = dynamic_cast<test1_A*>(&test1_d);
+  S(ap == (test1_A*)&test1_d, 12);
+  test1_E* ep = dynamic_cast<test1_E*>(&test1_f);
+  S(ep == (test1_E*)&test1_f, 13);
+  void *vp = dynamic_cast<void*>(ap);
+  S(vp == &test1_d, 14);
+  const void *cvp = dynamic_cast<const void*>(ap);
+  S(cvp == &test1_d, 15);
+}
+
+// CHECK-LL:     define void @_Z5test1v() nounwind {
+// CHECK-LL:       [[bp:%.*]] = alloca %class.test1_A*, align 8
+// CHECK-LL-NEXT:  [[ap:%.*]] = alloca %class.test1_A*, align 8
+// CHECK-LL-NEXT:  [[dp:%.*]] = alloca %class.test1_D*, align 8
+// CHECK-LL-NEXT:  [[ap37:%.*]] = alloca %class.test1_A*, align 8
+// CHECK-LL-NEXT:  [[dp53:%.*]] = alloca %class.test1_D*, align 8
+// CHECK-LL-NEXT:  [[ep1:%.*]] = alloca %class.test1_E*, align 8
+// CHECK-LL-NEXT:  [[cdp:%.*]] = alloca %class.test1_D*, align 8
+// CHECK-LL-NEXT:  [[ep:%.*]] = alloca %class.test1_E*, align 8
+// CHECK-LL-NEXT:  [[vp:%.*]] = alloca i8*, align 8
+// CHECK-LL-NEXT:  [[cvp:%.*]] = alloca i8*, align 8
+// CHECK-LL-NEXT:  store %class.test1_A* bitcast (%class.test1_D* @test1_d to %class.test1_A*), %class.test1_A** [[bp]]
+// CHECK-LL-NEXT:  br i1 false, label %[[castnull2:.*]], label %[[castnotnull1:.*]]
+// CHECK-LL:       [[castnotnull1]]
+// CHECK-LL-NEXT:  [[vtable:%.*]] = load i8** bitcast (%class.test1_D* @test1_d to i8**)
+// CHECK-LL-NEXT:  [[vbaseoffsetptr:%.*]] = getelementptr i8* [[vtable]], i64 -24
+// CHECK-LL-NEXT:  [[v1:%.*]] = bitcast i8* [[vbaseoffsetptr]] to i64*
+// CHECK-LL-NEXT:  [[vbaseoffset:%.*]] = load i64* [[v1]]
+// CHECK-LL-NEXT:  [[addptr:%.*]] = getelementptr i8* getelementptr inbounds (%class.test1_D* @test1_d, i32 0, i32 0, i32 0), i64 [[vbaseoffset:.*]]
+// CHECK-LL-NEXT:  [[v2:%.*]] = bitcast i8* [[addptr]] to %class.test1_A*
+// CHECK-LL-NEXT:  br label %[[castend3:.*]]
+// CHECK-LL:       [[castnull2]]
+// CHECK-LL-NEXT:  br label %[[castend3]]
+// CHECK-LL:       [[castend3]]
+// CHECK-LL-NEXT:  [[v3:%.*]] = phi %class.test1_A* [ [[v2]], %[[castnotnull1]] ], [ null, %[[castnull2]] ]
+// CHECK-LL-NEXT:  store %class.test1_A* [[v3]], %class.test1_A** [[ap]]
+// CHECK-LL-NEXT:  [[tmp:%.*]] = load %class.test1_A** [[bp]]
+// CHECK-LL-NEXT:  [[v4:%.*]] = icmp ne %class.test1_A* [[tmp]], null
+// CHECK-LL-NEXT:  br i1 [[v4]], label %[[v5:.*]], label %[[v9:.*]]
+// CHECK-LL:       ; <label>:[[v5]]
+// CHECK-LL-NEXT:  [[v6:%.*]] = bitcast %class.test1_A* [[tmp]] to i8*
+// CHECK-LL-NEXT:  [[v7:%.*]] = call i8* @__dynamic_cast(i8* [[v6]], i8* bitcast (%0* @_ZTI7test1_B to i8*), i8* bitcast (%1* @_ZTI7test1_D to i8*), i64 -1) ; <i8*> [#uses=1]
+// CHECK-LL-NEXT:  [[v8:%.*]] = bitcast i8* [[v7]] to %class.test1_D*
+// CHECK-LL-NEXT:  br label %[[v10:.*]]
+// CHECK-LL:       ; <label>:[[v9]]
+// CHECK-LL-NEXT:  br label %[[v10]]
+// CHECK-LL:       ; <label>:[[v10]]
+// CHECK-LL-NEXT:  [[v11:%.*]] = phi %class.test1_D* [ [[v8]], %[[v5]] ], [ null, %[[v9]] ]
+// CHECK-LL-NEXT:  store %class.test1_D* [[v11]], %class.test1_D** [[dp]]
+// CHECK-LL-NEXT:  [[tmp4:%.*]] = load %class.test1_D** [[dp]]
+// CHECK-LL-NEXT:  [[cmp:%.*]] = icmp eq %class.test1_D* [[tmp4]], null
+// CHECK-LL-NEXT:  br i1 [[cmp]], label %[[ifthen:.*]], label %[[ifelse:.*]]
+// CHECK-LL:       [[ifthen]]
+// CHECK-LL-NEXT:  call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str, i32 0, i32 0), i32 1)
+// CHECK-LL-NEXT:  br label %[[ifend:.*]]
+// CHECK-LL:       [[ifelse]]
+// CHECK-LL-NEXT:  call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str1, i32 0, i32 0), i32 1)
+// CHECK-LL-NEXT:  br label %[[ifend]]
+// CHECK-LL:       [[ifend]]
+// CHECK-LL-NEXT:  [[tmp6:%.*]] = load %class.test1_A** [[bp]]
+// CHECK-LL-NEXT:  [[v12:%.*]] = icmp ne %class.test1_A* [[tmp6]], null
+// CHECK-LL-NEXT:  br i1 [[v12]], label %[[v13:.*]], label %[[v17:.*]]
+// CHECK-LL:       ; <label>:[[v13]]
+// CHECK-LL-NEXT:  [[v14:%.*]] = bitcast %class.test1_A* [[tmp6]] to i8*
+// CHECK-LL-NEXT:  [[v15:%.*]] = call i8* @__dynamic_cast(i8* [[v14]], i8* bitcast ({{.*}} @_ZTI7test1_B to i8*), i8* bitcast ({{.*}} @_ZTI7test1_A to i8*), i64 -1)
+// CHECK-LL-NEXT:  [[v16:%.*]] = bitcast i8* [[v15]] to %class.test1_A*
+// CHECK-LL-NEXT:  br label %[[v18:.*]]
+// CHECK-LL:       ; <label>:[[v17]]
+// CHECK-LL-NEXT:  br label %[[v18]]
+// CHECK-LL:       ; <label>:[[v18]]
+// CHECK-LL-NEXT:  [[v19:%.*]] = phi %class.test1_A* [ [[v16]], %[[v13]] ], [ null, %[[v17]] ]
+// CHECK-LL-NEXT:  store %class.test1_A* [[v19]], %class.test1_A** [[ap]]
+// CHECK-LL-NEXT:  [[tmp7:%.*]] = load %class.test1_A** [[ap]]
+// CHECK-LL-NEXT:  [[cmp8:%.*]] = icmp eq %class.test1_A* [[tmp7]], null
+// CHECK-LL-NEXT:  br i1 [[cmp8]], label %[[ifthen9:.*]], label %[[ifelse11:.*]]
+// CHECK-LL:       [[ifthen9]]
+// CHECK-LL-NEXT:  call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str, i32 0, i32 0), i32 2)
+// CHECK-LL-NEXT:  br label %[[ifend13:.*]]
+// CHECK-LL:       [[ifelse11]]
+// CHECK-LL-NEXT:  call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str1, i32 0, i32 0), i32 2)
+// CHECK-LL-NEXT:  br label %[[ifend13]]
+// CHECK-LL:       [[ifend13]]
+// CHECK-LL-NEXT:  [[tmp14:%.*]] = load %class.test1_A** [[ap]]
+// CHECK-LL-NEXT:  [[v20:%.*]] = icmp ne %class.test1_A* [[tmp14]], null
+// CHECK-LL-NEXT:  br i1 [[v20]], label %[[v21:.*]], label %[[v25:.*]]
+// CHECK-LL:       ; <label>:[[v21]]
+// CHECK-LL-NEXT:  [[v22:%.*]] = bitcast %class.test1_A* [[tmp14]] to i8*
+// CHECK-LL-NEXT:  [[v23:%.*]] = call i8* @__dynamic_cast({{.*}} [[v22]], i8* bitcast ({{.*}} @_ZTI7test1_A to i8*), i8* bitcast ({{.*}} @_ZTI7test1_B to i8*), i64 -1)
+// CHECK-LL-NEXT:  [[v24:%.*]] = bitcast i8* [[v23]] to %class.test1_A*
+// CHECK-LL-NEXT:  br label %[[v26:.*]]
+// CHECK-LL:       ; <label>:[[v25]]
+// CHECK-LL-NEXT:  br label %[[v26]]
+// CHECK-LL:       ; <label>:[[v26]]
+// CHECK-LL-NEXT:  [[v27:%.*]] = phi %class.test1_A* [ [[v24]], %[[v21]] ], [ null, %[[v25]] ]
+// CHECK-LL-NEXT:  store %class.test1_A* [[v27]], %class.test1_A** [[bp]]
+// CHECK-LL-NEXT:  [[tmp15:%.*]] = load %class.test1_A** [[bp]]
+// CHECK-LL-NEXT:  [[cmp16:%.*]] = icmp eq %class.test1_A* [[tmp15]], null
+// CHECK-LL-NEXT:  br i1 [[cmp16]], label %[[ifthen17:.*]], label %[[ifelse19:.*]]
+// CHECK-LL:       [[ifthen17]]
+// CHECK-LL-NEXT:  call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str, i32 0, i32 0), i32 3)
+// CHECK-LL-NEXT:  br label %[[ifend21:.*]]
+// CHECK-LL:       [[ifelse19]]
+// CHECK-LL-NEXT:  call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str1, i32 0, i32 0), i32 3)
+// CHECK-LL-NEXT:  br label %[[ifend21]]
+// CHECK-LL:       [[ifend21]]
+// CHECK-LL-NEXT:  br i1 false, label %[[castnull27:.*]], label %[[castnotnull22:.*]]
+// CHECK-LL:       [[castnotnull22]]
+// CHECK-LL-NEXT:  [[vtable23:%.*]] = load i8** bitcast (%class.test1_D* @test1_d to i8**)
+// CHECK-LL-NEXT:  [[vbaseoffsetptr24:%.*]] = getelementptr i8* [[vtable23]], i64 -24
+// CHECK-LL-NEXT:  [[v28:%.*]] = bitcast i8* [[vbaseoffsetptr24]] to i64*
+// CHECK-LL-NEXT:  [[vbaseoffset25:%.*]] = load i64* [[v28]]
+// CHECK-LL-NEXT:  [[addptr26:%.*]] = getelementptr i8* getelementptr inbounds (%class.test1_D* @test1_d, i32 0, i32 0, i32 0), i64 [[vbaseoffset25]]
+// CHECK-LL-NEXT:  [[v29:%.*]] = bitcast i8* [[addptr26]] to %class.test1_A*
+// CHECK-LL-NEXT:  br label %[[castend28:.*]]
+// CHECK-LL:       [[castnull27]]
+// CHECK-LL-NEXT:  br label %[[castend28]]
+// CHECK-LL:       [[castend28]]
+// CHECK-LL-NEXT:  [[v30:%.*]] = phi %class.test1_A* [ [[v29]], %[[castnotnull22]] ], [ null, %[[castnull27]] ]
+// CHECK-LL-NEXT:  store %class.test1_A* [[v30]], %class.test1_A** [[ap]]
+// CHECK-LL-NEXT:  [[tmp29:%.*]] = load %class.test1_A** [[ap]]
+// CHECK-LL-NEXT:  [[cmp30:%.*]] = icmp ne %class.test1_A* [[tmp29]], null
+// CHECK-LL-NEXT:  br i1 [[cmp30]], label %[[ifthen31:.*]], label %[[ifelse33:.*]]
+// CHECK-LL:       [[ifthen31]]
+// CHECK-LL-NEXT:  call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str, i32 0, i32 0), i32 4)
+// CHECK-LL-NEXT:  br label %[[ifend35:.*]]
+// CHECK-LL:       [[ifelse33]]
+// CHECK-LL-NEXT:  call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str1, i32 0, i32 0), i32 4)
+// CHECK-LL-NEXT:  br label %[[ifend35]]
+// CHECK-LL:       [[ifend35]]
+// CHECK-LL-NEXT:  br i1 false, label %[[castnull43:.*]], label %[[castnotnull38:.*]]
+// CHECK-LL:       [[castnotnull38]]
+// CHECK-LL-NEXT:  [[vtable39:%.*]] = load i8** bitcast (%class.test1_F* @test1_f to i8**)
+// CHECK-LL-NEXT:  [[vbaseoffsetptr40:%.*]] = getelementptr i8* [[vtable39]], i64 -24
+// CHECK-LL-NEXT:  [[v31:%.*]] = bitcast i8* [[vbaseoffsetptr40]] to i64*
+// CHECK-LL-NEXT:  [[vbaseoffset41:%.*]] = load i64* [[v31]]
+// CHECK-LL-NEXT:  [[addptr42:%.*]] = getelementptr i8* getelementptr inbounds (%class.test1_F* @test1_f, i32 0, i32 0, i32 0), i64 [[vbaseoffset41]]
+// CHECK-LL-NEXT:  [[v32:%.*]] = bitcast i8* [[addptr42]] to %class.test1_A*
+// CHECK-LL-NEXT:  br label %[[castend44:.*]]
+// CHECK-LL:       [[castnull43]]
+// CHECK-LL-NEXT:  br label %[[castend44]]
+// CHECK-LL:       [[castend44]]
+// CHECK-LL-NEXT:  [[v33:%.*]] = phi %class.test1_A* [ [[v32]], %[[castnotnull38]] ], [ null, %[[castnull43]] ]
+// CHECK-LL-NEXT:  store %class.test1_A* [[v33]], %class.test1_A** [[ap37]]
+// CHECK-LL-NEXT:  [[tmp45:%.*]] = load %class.test1_A** [[ap37]]
+// CHECK-LL-NEXT:  [[cmp46:%.*]] = icmp ne %class.test1_A* [[tmp45]], null
+// CHECK-LL-NEXT:  br i1 [[cmp46]], label %[[ifthen47:.*]], label %[[ifelse49:.*]]
+// CHECK-LL:       [[ifthen47]]
+// CHECK-LL-NEXT:  call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str, i32 0, i32 0), i32 6)
+// CHECK-LL-NEXT:  br label %[[ifend51:.*]]
+// CHECK-LL:       [[ifelse49]]
+// CHECK-LL-NEXT:  call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str1, i32 0, i32 0), i32 6)
+// CHECK-LL-NEXT:  br label %[[ifend51]]
+// CHECK-LL:       [[ifend51]]
+// CHECK-LL-NEXT:  [[tmp54:%.*]] = load %class.test1_A** [[ap37]]
+// CHECK-LL-NEXT:  [[v34:%.*]] = icmp ne %class.test1_A* [[tmp54]], null
+// CHECK-LL-NEXT:  br i1 [[v34]], label %[[v35:.*]], label %[[v39:.*]]
+// CHECK-LL:       ; <label>:[[v35]]
+// CHECK-LL-NEXT:  [[v36:%.*]] = bitcast %class.test1_A* [[tmp54]] to i8*
+// CHECK-LL-NEXT:  [[v37:%.*]] = call i8* @__dynamic_cast(i8* [[v36]], i8* bitcast ({{.*}} @_ZTI7test1_A to i8*), i8* bitcast ({{.*}} @_ZTI7test1_D to i8*), i64 -1)
+// CHECK-LL-NEXT:  [[v38:%.*]] = bitcast i8* [[v37]] to %class.test1_D*
+// CHECK-LL-NEXT:  br label %[[v40:.*]]
+// CHECK-LL:       ; <label>:[[v39]]
+// CHECK-LL-NEXT:  br label %[[v40]]
+// CHECK-LL:       ; <label>:[[v40]]
+// CHECK-LL-NEXT:  [[v41:%.*]] = phi %class.test1_D* [ [[v38]], %[[v35]] ], [ null, %[[v39]] ]
+// CHECK-LL-NEXT:  store %class.test1_D* [[v41]], %class.test1_D** [[dp53]]
+// CHECK-LL-NEXT:  [[tmp55:%.*]] = load %class.test1_D** [[dp53]]
+// CHECK-LL-NEXT:  [[cmp56:%.*]] = icmp eq %class.test1_D* [[tmp55]], null
+// CHECK-LL-NEXT:  br i1 [[cmp56]], label %[[ifthen57:.*]], label %[[ifelse59:.*]]
+// CHECK-LL:       [[ifthen57]]
+// CHECK-LL-NEXT:  call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str, i32 0, i32 0), i32 7)
+// CHECK-LL-NEXT:  br label %[[ifend61:.*]]
+// CHECK-LL:       [[ifelse59]]
+// CHECK-LL-NEXT:  call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str1, i32 0, i32 0), i32 7)
+// CHECK-LL-NEXT:  br label %[[ifend61]]
+// CHECK-LL:       [[ifend61]]
+// CHECK-LL-NEXT:  [[tmp63:%.*]] = load %class.test1_A** [[ap37]]
+// CHECK-LL-NEXT:  [[v42:%.*]] = icmp ne %class.test1_A* [[tmp63]], null
+// CHECK-LL-NEXT:  br i1 [[v42]], label %[[v43:.*]], label %[[v47:.*]]
+// CHECK-LL:       ; <label>:[[v43]]
+// CHECK-LL-NEXT:  [[v44:%.*]] = bitcast %class.test1_A* [[tmp63]] to i8*
+// CHECK-LL-NEXT:  [[v45:%.*]] = call i8* @__dynamic_cast(i8* [[v44]], i8* bitcast ({{.*}} @_ZTI7test1_A to i8*), i8* bitcast ({{.*}} @_ZTI7test1_E to i8*), i64 -1)
+// CHECK-LL-NEXT:  [[v46:%.*]] = bitcast i8* [[v45]] to %class.test1_E*
+// CHECK-LL-NEXT:  br label %[[v48:.*]]
+// CHECK-LL:       ; <label>:[[v47]]
+// CHECK-LL-NEXT:  br label %[[v48]]
+// CHECK-LL:       ; <label>:[[v48]]
+// CHECK-LL-NEXT:  [[v49:%.*]] = phi %class.test1_E* [ [[v46]], %[[v43]] ], [ null, %[[v47]] ]
+// CHECK-LL-NEXT:  store %class.test1_E* [[v49]], %class.test1_E** [[ep1]]
+// CHECK-LL-NEXT:  [[tmp64:%.*]] = load %class.test1_E** [[ep1]]
+// CHECK-LL-NEXT:  [[cmp65:%.*]] = icmp ne %class.test1_E* [[tmp64]], null
+// CHECK-LL-NEXT:  br i1 [[cmp65]], label %[[ifthen66:.*]], label %[[ifelse68:.*]]
+// CHECK-LL:       [[ifthen66]]
+// CHECK-LL-NEXT:  call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str, i32 0, i32 0), i32 8)
+// CHECK-LL-NEXT:  br label %[[ifend70:.*]]
+// CHECK-LL:       [[ifelse68]]
+// CHECK-LL-NEXT:  call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str1, i32 0, i32 0), i32 8)
+// CHECK-LL-NEXT:  br label %[[ifend70]]
+// CHECK-LL:       [[ifend70]]
+// CHECK-LL-NEXT:  store %class.test1_D* @test1_d, %class.test1_D** [[dp]]
+// CHECK-LL-NEXT:  [[tmp71:%.*]] = load %class.test1_D** [[dp]]
+// CHECK-LL-NEXT:  [[cmp72:%.*]] = icmp eq %class.test1_D* [[tmp71]], @test1_d
+// CHECK-LL-NEXT:  br i1 [[cmp72]], label %[[ifthen73:.*]], label %[[ifelse75:.*]]
+// CHECK-LL:       [[ifthen73]]
+// CHECK-LL-NEXT:  call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str, i32 0, i32 0), i32 9)
+// CHECK-LL-NEXT:  br label %[[ifend77:.*]]
+// CHECK-LL:       [[ifelse75]]
+// CHECK-LL-NEXT:  call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str1, i32 0, i32 0), i32 9)
+// CHECK-LL-NEXT:  br label %[[ifend77]]
+// CHECK-LL:       [[ifend77]]
+// CHECK-LL-NEXT:  store %class.test1_D* @test1_d, %class.test1_D** [[cdp]]
+// CHECK-LL-NEXT:  [[tmp79:%.*]] = load %class.test1_D** [[cdp]]
+// CHECK-LL-NEXT:  [[cmp80:%.*]] = icmp eq %class.test1_D* [[tmp79]], @test1_d
+// CHECK-LL-NEXT:  br i1 [[cmp80]], label %[[ifthen81:.*]], label %[[ifelse83:.*]]
+// CHECK-LL:       [[ifthen81]]
+// CHECK-LL-NEXT:  call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str, i32 0, i32 0), i32 10)
+// CHECK-LL-NEXT:  br label %[[ifend85:.*]]
+// CHECK-LL:       [[ifelse83]]
+// CHECK-LL-NEXT:  call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str1, i32 0, i32 0), i32 10)
+// CHECK-LL-NEXT:  br label %[[ifend85]]
+// CHECK-LL:       [[ifend85]]
+// CHECK-LL-NEXT:  br i1 false, label %[[v50:.*]], label %[[v53:.*]]
+// CHECK-LL:       ; <label>:[[v50]]
+// CHECK-LL-NEXT:  [[v51:%.*]] = call i8* @__dynamic_cast(i8* null, i8* bitcast ({{.*}}* @_ZTI7test1_A to i8*), i8* bitcast ({{.*}} @_ZTI7test1_D to i8*), i64 -1)
+// CHECK-LL-NEXT:  [[v52:%.*]] = bitcast i8* [[v51]] to %class.test1_D*
+// CHECK-LL-NEXT:  br label %[[v54:.*]]
+// CHECK-LL:       ; <label>:[[v53]]
+// CHECK-LL-NEXT:  br label %[[v54]]
+// CHECK-LL:       ; <label>:[[v54]]
+// CHECK-LL-NEXT:  [[v55:%.*]] = phi %class.test1_D* [ [[v52]], %[[v50]] ], [ null, %[[v53]] ]
+// CHECK-LL-NEXT:  store %class.test1_D* [[v55]], %class.test1_D** [[dp]]
+// CHECK-LL-NEXT:  [[tmp86:%.*]] = load %class.test1_D** [[dp]]
+// CHECK-LL-NEXT:  [[cmp87:%.*]] = icmp eq %class.test1_D* [[tmp86]], null
+// CHECK-LL-NEXT:  br i1 [[cmp87]], label %[[ifthen88:.*]], label %[[ifelse90:.*]]
+// CHECK-LL:       [[ifthen88]]
+// CHECK-LL-NEXT:  call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str, i32 0, i32 0), i32 11)
+// CHECK-LL-NEXT:  br label %[[ifend92:.*]]
+// CHECK-LL:       [[ifelse90]]
+// CHECK-LL-NEXT:  call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str1, i32 0, i32 0), i32 11)
+// CHECK-LL-NEXT:  br label %[[ifend92]]
+// CHECK-LL:       [[ifend92]]
+// CHECK-LL-NEXT:  br i1 false, label %[[castnull98:.*]], label %[[castnotnull93:.*]]
+// CHECK-LL:       [[castnotnull93]]
+// CHECK-LL-NEXT:  [[vtable94:%.*]] = load i8** bitcast (%class.test1_D* @test1_d to i8**)
+// CHECK-LL-NEXT:  [[vbaseoffsetptr95:%.*]] = getelementptr i8* [[vtable94]], i64 -24
+// CHECK-LL-NEXT:  [[v56:%.*]] = bitcast i8* [[vbaseoffsetptr95]] to i64*
+// CHECK-LL-NEXT:  [[vbaseoffset96:%.*]] = load i64* [[v56]]
+// CHECK-LL-NEXT:  [[addptr97:%.*]] = getelementptr i8* getelementptr inbounds (%class.test1_D* @test1_d, i32 0, i32 0, i32 0), i64 [[vbaseoffset96]]
+// CHECK-LL-NEXT:  [[v57:%.*]] = bitcast i8* [[addptr97]] to %class.test1_A*
+// CHECK-LL-NEXT:  br label %[[castend99:.*]]
+// CHECK-LL:       [[castnull98]]
+// CHECK-LL-NEXT:  br label %[[castend99]]
+// CHECK-LL:       [[castend99]]
+// CHECK-LL-NEXT:  [[v58:%.*]] = phi %class.test1_A* [ [[v57]], %[[castnotnull93]] ], [ null, %[[castnull98]] ]
+// CHECK-LL-NEXT:  store %class.test1_A* [[v58]], %class.test1_A** [[ap]]
+// CHECK-LL-NEXT:  [[tmp100:%.*]] = load %class.test1_A** [[ap]]
+// CHECK-LL-NEXT:  br i1 false, label %[[castnull106:.*]], label %[[castnotnull101:.*]]
+// CHECK-LL:       [[castnotnull101]]
+// CHECK-LL-NEXT:  [[vtable102:%.*]] = load i8** bitcast (%class.test1_D* @test1_d to i8**)
+// CHECK-LL-NEXT:  [[vbaseoffsetptr103:%.*]] = getelementptr i8* [[vtable102]], i64 -24
+// CHECK-LL-NEXT:  [[v59:%.*]] = bitcast i8* [[vbaseoffsetptr103]] to i64*
+// CHECK-LL-NEXT:  [[vbaseoffset104:%.*]] = load i64* [[v59]]
+// CHECK-LL-NEXT:  [[addptr105:%.*]] = getelementptr i8* getelementptr inbounds (%class.test1_D* @test1_d, i32 0, i32 0, i32 0), i64 [[vbaseoffset104]]
+// CHECK-LL-NEXT:  [[v60:%.*]] = bitcast i8* [[addptr105]] to %class.test1_A*
+// CHECK-LL-NEXT:  br label %[[castend107:.*]]
+// CHECK-LL:       [[castnull106]]
+// CHECK-LL-NEXT:  br label %[[castend107]]
+// CHECK-LL:       [[castend107]]
+// CHECK-LL-NEXT:  [[v61:%.*]] = phi %class.test1_A* [ [[v60]], %[[castnotnull101]] ], [ null, %[[castnull106]] ]
+// CHECK-LL-NEXT:  [[cmp108:%.*]] = icmp eq %class.test1_A* [[tmp100]], [[v61]]
+// CHECK-LL-NEXT:  br i1 [[cmp108]], label %[[ifthen109:.*]], label %[[ifelse111:.*]]
+// CHECK-LL:       [[ifthen109]]
+// CHECK-LL-NEXT:  call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str, i32 0, i32 0), i32 12)
+// CHECK-LL-NEXT:  br label %[[ifend113:.*]]
+// CHECK-LL:       [[ifelse111]]
+// CHECK-LL-NEXT:  call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str1, i32 0, i32 0), i32 12)
+// CHECK-LL-NEXT:  br label %[[ifend113]]
+// CHECK-LL:       [[ifend113]]
+// CHECK-LL-NEXT: store %class.test1_E* bitcast (%class.test1_F* @test1_f to %class.test1_E*), %class.test1_E** [[ep]]
+// CHECK-LL-NEXT:  [[tmp118:%.*]] = load %class.test1_E** [[ep]]
+// CHECK-LL-NEXT:  [[cmp122:%.*]] = icmp eq %class.test1_E* [[tmp118]], bitcast (%class.test1_F* @test1_f to %class.test1_E*) ; <i1> [#uses=1]
+
+// CHECK-LL-NEXT:  br i1 [[cmp122]], label %[[ifthen123:.*]], label %[[ifelse125:.*]]
+// CHECK-LL:       [[ifthen123]]
+// CHECK-LL-NEXT:  call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str, i32 0, i32 0), i32 13)
+// CHECK-LL-NEXT:  br label %[[ifend127:.*]]
+// CHECK-LL:       [[ifelse125]]
+// CHECK-LL-NEXT:  call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str1, i32 0, i32 0), i32 13)
+// CHECK-LL-NEXT:  br label %[[ifend127]]
+// CHECK-LL:       [[ifend127]]
+// CHECK-LL-NEXT:  [[tmp129:%.*]] = load %class.test1_A** [[ap]]
+// CHECK-LL-NEXT:  [[v64:%.*]] = icmp ne %class.test1_A* [[tmp129]], null
+// CHECK-LL-NEXT:  br i1 [[v64]], label %[[v65:.*]], label %[[v70:.*]]
+// CHECK-LL:       ; <label>:[[v65]]
+// CHECK-LL-NEXT:  [[v66:%.*]] = bitcast %class.test1_A* [[tmp129]] to i64**
+// CHECK-LL-NEXT:  [[vtable130:%.*]] = load i64** [[v66]]
+// CHECK-LL-NEXT:  [[v67:%.*]] = getelementptr inbounds i64* [[vtable130]], i64 -2
+// CHECK-LL-NEXT:  [[offsettotop:%.*]] = load i64* [[v67]]
+// CHECK-LL-NEXT:  [[v68:%.*]] = bitcast %class.test1_A* [[tmp129]] to i8*
+// CHECK-LL-NEXT:  [[v69:%.*]] = getelementptr inbounds i8* [[v68]], i64 [[offsettotop]]
+// CHECK-LL-NEXT:  br label %[[v71:.*]]
+// CHECK-LL:       ; <label>:[[v70]]
+// CHECK-LL-NEXT:  br label %[[v71]]
+// CHECK-LL:       ; <label>:[[v71]]
+// CHECK-LL-NEXT:  [[v72:%.*]] = phi i8* [ [[v69]], %[[v65]] ], [ null, %[[v70]] ]
+// CHECK-LL-NEXT:  store i8* [[v72]], i8** [[vp]]
+// CHECK-LL-NEXT:  [[tmp131:%.*]] = load i8** [[vp]]
+// CHECK-LL-NEXT:  [[cmp132:%.*]] = icmp eq i8* [[tmp131]], getelementptr inbounds (%class.test1_D* @test1_d, i32 0, i32 0, i32 0)
+// CHECK-LL-NEXT:  br i1 [[cmp132]], label %[[ifthen133:.*]], label %[[ifelse135:.*]]
+// CHECK-LL:       [[ifthen133]]
+// CHECK-LL-NEXT:  call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str, i32 0, i32 0), i32 14)
+// CHECK-LL-NEXT:  br label %[[ifend137:.*]]
+// CHECK-LL:       [[ifelse135]]
+// CHECK-LL-NEXT:  call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str1, i32 0, i32 0), i32 14)
+// CHECK-LL-NEXT:  br label %[[ifend137]]
+// CHECK-LL:       [[ifend137]]
+// CHECK-LL-NEXT:  [[tmp139:%.*]] = load %class.test1_A** [[ap]]
+// CHECK-LL-NEXT:  [[v73:%.*]] = icmp ne %class.test1_A* [[tmp139]], null
+// CHECK-LL-NEXT:  br i1 [[v73]], label %[[v74:.*]], label %[[v79:.*]]
+// CHECK-LL:       ; <label>:[[v74]]
+// CHECK-LL-NEXT:  [[v75:%.*]] = bitcast %class.test1_A* [[tmp139]] to i64**
+// CHECK-LL-NEXT:  [[vtable140:%.*]] = load i64** [[v75]]
+// CHECK-LL-NEXT:  [[v76:%.*]] = getelementptr inbounds i64* [[vtable140]], i64 -2
+// CHECK-LL-NEXT:  [[offsettotop141:%.*]] = load i64* [[v76]]
+// CHECK-LL-NEXT:  [[v77:%.*]] = bitcast %class.test1_A* [[tmp139]] to i8*
+// CHECK-LL-NEXT:  [[v78:%.*]] = getelementptr inbounds i8* [[v77]], i64 [[offsettotop141]]
+// CHECK-LL-NEXT:  br label %[[v80:.*]]
+// CHECK-LL:       ; <label>:[[v79]]
+// CHECK-LL-NEXT:  br label %[[v80]]
+// CHECK-LL:       ; <label>:[[v80]]
+// CHECK-LL-NEXT:  [[v81:%.*]] = phi i8* [ [[v78]], %[[v74]] ], [ null, %[[v79]] ]
+// CHECK-LL-NEXT:  store i8* [[v81]], i8** [[cvp]]
+// CHECK-LL-NEXT:  [[tmp142:%.*]] = load i8** [[cvp]]
+// CHECK-LL-NEXT:  [[cmp143:%.*]] = icmp eq i8* [[tmp142]], getelementptr inbounds (%class.test1_D* @test1_d, i32 0, i32 0, i32 0)
+// CHECK-LL-NEXT:  br i1 [[cmp143]], label %[[ifthen144:.*]], label %[[ifelse146:.*]]
+// CHECK-LL:       [[ifthen144]]
+// CHECK-LL-NEXT:  call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str, i32 0, i32 0), i32 15)
+// CHECK-LL-NEXT:  br label %[[ifend148:.*]]
+// CHECK-LL:       [[ifelse146]]
+// CHECK-LL-NEXT:  call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str1, i32 0, i32 0), i32 15)
+// CHECK-LL-NEXT:  br label %[[ifend148]]
+// CHECK-LL:       [[ifend148]]
+// CHECK-LL-NEXT:  ret void
diff --git a/test/CodeGenCXX/eh.cpp b/test/CodeGenCXX/eh.cpp
new file mode 100644
index 0000000..f2629d1
--- /dev/null
+++ b/test/CodeGenCXX/eh.cpp
@@ -0,0 +1,106 @@
+// RUN: %clang_cc1 -fexceptions -triple x86_64-apple-darwin -std=c++0x -emit-llvm %s -o %t.ll
+// RUN: FileCheck --input-file=%t.ll %s
+
+struct test1_D {
+  double d;
+} d1;
+
+void test1() {
+  throw d1;
+}
+
+// CHECK:     define void @_Z5test1v()
+// CHECK:       [[FREEVAR:%.*]] = alloca i1
+// CHECK-NEXT:  [[EXNOBJVAR:%.*]] = alloca i8*
+// CHECK-NEXT:  store i1 false, i1* [[FREEVAR]]
+// CHECK-NEXT:  [[EXNOBJ:%.*]] = call i8* @__cxa_allocate_exception(i64 8)
+// CHECK-NEXT:  store i8* [[EXNOBJ]], i8** [[EXNOBJVAR]]
+// CHECK-NEXT:  store i1 true, i1* [[FREEVAR]]
+// CHECK-NEXT:  [[EXN:%.*]] = bitcast i8* [[EXNOBJ]] to [[DSTAR:%[^*]*\*]]
+// CHECK-NEXT:  [[EXN2:%.*]] = bitcast [[DSTAR]] [[EXN]] to i8*
+// CHECK-NEXT:  call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[EXN2]], i8* bitcast ([[DSTAR]] @d1 to i8*), i64 8, i32 8, i1 false)
+// CHECK-NEXT:  store i1 false, i1* [[FREEVAR]]
+// CHECK-NEXT:  call void @__cxa_throw(i8* [[EXNOBJ]], i8* bitcast (%0* @_ZTI7test1_D to i8*), i8* null) noreturn
+// CHECK-NEXT:  unreachable
+
+
+struct test2_D {
+  test2_D(const test2_D&o);
+  test2_D();
+  virtual void bar() { }
+  int i; int j;
+} d2;
+
+void test2() {
+  throw d2;
+}
+
+// CHECK:     define void @_Z5test2v()
+// CHECK:       [[FREEVAR:%.*]] = alloca i1
+// CHECK-NEXT:  [[EXNOBJVAR:%.*]] = alloca i8*
+// CHECK-NEXT:  store i1 false, i1* [[FREEVAR]]
+// CHECK-NEXT:  [[EXNOBJ:%.*]] = call i8* @__cxa_allocate_exception(i64 16)
+// CHECK-NEXT:  store i8* [[EXNOBJ]], i8** [[EXNOBJVAR]]
+// CHECK-NEXT:  store i1 true, i1* [[FREEVAR]]
+// CHECK-NEXT:  [[EXN:%.*]] = bitcast i8* [[EXNOBJ]] to [[DSTAR:%[^*]*\*]]
+// CHECK-NEXT:  invoke void @_ZN7test2_DC1ERKS_([[DSTAR]] [[EXN]], [[DSTAR]] @d2)
+// CHECK-NEXT:     to label %[[CONT:.*]] unwind label %{{.*}}
+//      :     [[CONT]]:   (can't check this in Release-Asserts builds)
+// CHECK:       store i1 false, i1* [[FREEVAR]]
+// CHECK-NEXT:  call void @__cxa_throw(i8* [[EXNOBJ]], i8* bitcast (%{{.*}}* @_ZTI7test2_D to i8*), i8* null) noreturn
+// CHECK-NEXT:  unreachable
+
+
+struct test3_D {
+  test3_D() { }
+  test3_D(volatile test3_D&o);
+  virtual void bar();
+};
+
+void test3() {
+  throw (volatile test3_D *)0;
+}
+
+// CHECK:     define void @_Z5test3v()
+// CHECK:       [[FREEVAR:%.*]] = alloca i1
+// CHECK-NEXT:  [[EXNOBJVAR:%.*]] = alloca i8*
+// CHECK-NEXT:  store i1 false, i1* [[FREEVAR]]
+// CHECK-NEXT:  [[EXNOBJ:%.*]] = call i8* @__cxa_allocate_exception(i64 8)
+// CHECK-NEXT:  store i8* [[EXNOBJ]], i8** [[EXNOBJVAR]]
+// CHECK-NEXT:  store i1 true, i1* [[FREEVAR]]
+// CHECK-NEXT:  [[EXN:%.*]] = bitcast i8* [[EXNOBJ]] to [[DSS:%[^*]*\*]]*
+// CHECK-NEXT:  store [[DSS]] null, [[DSS]]* [[EXN]]
+// CHECK-NEXT:  store i1 false, i1* [[FREEVAR]]
+// CHECK-NEXT:  call void @__cxa_throw(i8* [[EXNOBJ]], i8* bitcast (%1* @_ZTIPV7test3_D to i8*), i8* null) noreturn
+// CHECK-NEXT:  unreachable
+
+
+void test4() {
+  throw;
+}
+
+// CHECK:     define void @_Z5test4v()
+// CHECK:        call void @__cxa_rethrow() noreturn
+// CHECK-NEXT:   unreachable
+
+
+// rdar://problem/7696549
+namespace test5 {
+  struct A {
+    A();
+    A(const A&);
+    ~A();
+  };
+
+  void test() {
+    try { throw A(); } catch (A &x) {}
+  }
+// CHECK:      define void @_ZN5test54testEv()
+// CHECK:      [[EXNOBJ:%.*]] = call i8* @__cxa_allocate_exception(i64 1)
+// CHECK:      [[EXNCAST:%.*]] = bitcast i8* [[EXNOBJ]] to [[A:%[^*]*]]*
+// CHECK-NEXT: invoke void @_ZN5test51AC1Ev([[A]]* [[EXNCAST]])
+// CHECK:      invoke void @__cxa_throw(i8* [[EXNOBJ]], i8* bitcast ({{%.*}}* @_ZTIN5test51AE to i8*), i8* bitcast (void ([[A]]*)* @_ZN5test51AD1Ev to i8*)) noreturn
+// CHECK-NEXT:   to label {{%.*}} unwind label %[[HANDLER:[^ ]*]]
+//      :    [[HANDLER]]:  (can't check this in Release-Asserts builds)
+// CHECK:      {{%.*}} = call i32 @llvm.eh.typeid.for(i8* bitcast ({{%.*}}* @_ZTIN5test51AE to i8*))
+}
diff --git a/test/CodeGenCXX/elide-call-reference.cpp b/test/CodeGenCXX/elide-call-reference.cpp
new file mode 100644
index 0000000..c82eee7
--- /dev/null
+++ b/test/CodeGenCXX/elide-call-reference.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+// PR5695
+
+struct A { A(const A&); ~A(); };
+A& a();
+void b() {
+  A x = a();
+}
+
+// CHECK: call void @_ZN1AC1ERKS_
+// CHECK: call void @_ZN1AD1Ev
diff --git a/test/CodeGenCXX/empty-union.cpp b/test/CodeGenCXX/empty-union.cpp
new file mode 100644
index 0000000..118a0d2
--- /dev/null
+++ b/test/CodeGenCXX/empty-union.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s
+
+union sigval { };
+
+union sigval sigev_value;
+
+int main()
+{
+  return sizeof(sigev_value);
+}
diff --git a/test/CodeGenCXX/enum.cpp b/test/CodeGenCXX/enum.cpp
new file mode 100644
index 0000000..cfcd264
--- /dev/null
+++ b/test/CodeGenCXX/enum.cpp
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -emit-llvm-only -verify %s
+
+enum A { a } __attribute((packed));
+int func(A x) { return x==a; }
diff --git a/test/CodeGenCXX/eval-recursive-constant.cpp b/test/CodeGenCXX/eval-recursive-constant.cpp
new file mode 100644
index 0000000..608c95d
--- /dev/null
+++ b/test/CodeGenCXX/eval-recursive-constant.cpp
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 %s -emit-llvm-only
+
+extern const int a,b;
+const int a=b,b=a;
+int c() { if (a) return 1; return 0; }
diff --git a/test/CodeGenCXX/exceptions.cpp b/test/CodeGenCXX/exceptions.cpp
new file mode 100644
index 0000000..4d8fb80
--- /dev/null
+++ b/test/CodeGenCXX/exceptions.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - -fexceptions
+
+struct allocator {
+  allocator();
+  allocator(const allocator&);
+  ~allocator();
+};
+
+void f();
+void g(bool b, bool c) {
+  if (b) {
+    if (!c)
+    throw allocator();
+
+    return;
+  }
+  f();
+}
diff --git a/test/CodeGenCXX/explicit-instantiation.cpp b/test/CodeGenCXX/explicit-instantiation.cpp
new file mode 100644
index 0000000..24d1a67
--- /dev/null
+++ b/test/CodeGenCXX/explicit-instantiation.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -emit-llvm -triple i686-pc-linux-gnu -o - %s | FileCheck %s
+
+template<typename T, typename U, typename Result>
+struct plus {
+  Result operator()(const T& t, const U& u) const;
+};
+
+template<typename T, typename U, typename Result>
+Result plus<T, U, Result>::operator()(const T& t, const U& u) const {
+  return t + u;
+}
+
+// CHECK: define weak_odr i32 @_ZNK4plusIillEclERKiRKl
+template struct plus<int, long, long>;
diff --git a/test/CodeGenCXX/expr.cpp b/test/CodeGenCXX/expr.cpp
new file mode 100644
index 0000000..d92cfb4
--- /dev/null
+++ b/test/CodeGenCXX/expr.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -emit-llvm -x c++ < %s
+
+void test0(int x) {
+          if (x != 0) return;
+}
+
+
+// PR5211
+void test1() {
+  char *xpto;
+  while ( true && xpto[0] );
+}
+
+// PR5514
+int a;
+void test2() { ++a+=10; }
diff --git a/test/CodeGenCXX/extern-c.cpp b/test/CodeGenCXX/extern-c.cpp
new file mode 100644
index 0000000..ca5cd73
--- /dev/null
+++ b/test/CodeGenCXX/extern-c.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -emit-llvm %s -o %t
+namespace foo {
+
+// RUN: not grep "@a = global i32" %t
+extern "C" int a;
+
+// RUN: not grep "@_ZN3foo1bE = global i32" %t
+extern int b;
+
+// RUN: grep "@_ZN3foo1cE = global i32" %t | count 1
+int c = 5;
+
+// RUN: not grep "@_ZN3foo1dE" %t
+extern "C" struct d;
+
+}
diff --git a/test/CodeGenCXX/field-access-debug-info.cpp b/test/CodeGenCXX/field-access-debug-info.cpp
new file mode 100644
index 0000000..907fe04
--- /dev/null
+++ b/test/CodeGenCXX/field-access-debug-info.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -g -S -masm-verbose -o %t %s
+// RUN: grep DW_AT_accessibility %t
+
+class A {
+public:
+  int p;
+private:
+  int pr;
+};
+
+A a;
diff --git a/test/CodeGenCXX/function-template-explicit-specialization.cpp b/test/CodeGenCXX/function-template-explicit-specialization.cpp
new file mode 100644
index 0000000..21f0127
--- /dev/null
+++ b/test/CodeGenCXX/function-template-explicit-specialization.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s
+
+template<typename T> void a(T);
+template<> void a(int) {}
+
+// CHECK: define void @_Z1aIiEvT_
+
+namespace X {
+template<typename T> void b(T);
+template<> void b(int) {}
+}
+
+// CHECK: define void @_ZN1X1bIiEEvT_
diff --git a/test/CodeGenCXX/function-template-specialization.cpp b/test/CodeGenCXX/function-template-specialization.cpp
new file mode 100644
index 0000000..4a79fb1
--- /dev/null
+++ b/test/CodeGenCXX/function-template-specialization.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s
+template<typename T, typename U>
+T* next(T* ptr, const U& diff);
+
+template<typename T, typename U>
+T* next(T* ptr, const U& diff) { 
+  return ptr + diff; 
+}
+
+void test(int *iptr, float *fptr, int diff) {
+  // CHECK: _Z4nextIiiEPT_S1_RKT0_
+  iptr = next(iptr, diff);
+
+  // CHECK: _Z4nextIfiEPT_S1_RKT0_
+  fptr = next(fptr, diff);
+}
+
+template<typename T, typename U>
+T* next(T* ptr, const U& diff);
+
+void test2(int *iptr, double *dptr, int diff) {
+  iptr = next(iptr, diff);
+
+  // CHECK: _Z4nextIdiEPT_S1_RKT0_
+  dptr = next(dptr, diff);
+}
diff --git a/test/CodeGenCXX/global-array-destruction.cpp b/test/CodeGenCXX/global-array-destruction.cpp
new file mode 100644
index 0000000..c77551c
--- /dev/null
+++ b/test/CodeGenCXX/global-array-destruction.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++0x -S %s -o %t-64.s
+// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s
+
+extern "C" int printf(...);
+
+int count;
+
+struct S {
+  S() : iS(++count) { printf("S::S(%d)\n", iS); }
+  ~S() { printf("S::~S(%d)\n", iS); }
+  int iS;
+};
+
+
+S arr[2][1];
+S s1;
+S arr1[3];
+static S sarr[4];
+
+int main () {}
+S arr2[2];
+static S sarr1[4];
+S s2;
+S arr3[3];
+
+// CHECK-LP64: callq    ___cxa_atexit
+// CHECK-LP64: callq    ___cxa_atexit
+// CHECK-LP64: callq    ___cxa_atexit
+// CHECK-LP64: callq    ___cxa_atexit
+// CHECK-LP64: callq    ___cxa_atexit
+// CHECK-LP64: callq    ___cxa_atexit
+// CHECK-LP64: callq    ___cxa_atexit
+// CHECK-LP64: callq    ___cxa_atexit
diff --git a/test/CodeGenCXX/global-dtor-no-atexit.cpp b/test/CodeGenCXX/global-dtor-no-atexit.cpp
new file mode 100644
index 0000000..81e2199
--- /dev/null
+++ b/test/CodeGenCXX/global-dtor-no-atexit.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -triple x86_64 %s -fno-use-cxa-atexit -emit-llvm -o - | FileCheck %s
+
+// CHECK: define internal void @_GLOBAL__D_a()
+// CHECK:   call void @_ZN1AD1Ev(%class.A* @b)
+// CHECK:   call void @_ZN1AD1Ev(%class.A* @a)
+// CHECK: }
+
+class A {
+public:
+  A();
+  ~A();
+};
+
+A a, b;
diff --git a/test/CodeGenCXX/global-init.cpp b/test/CodeGenCXX/global-init.cpp
new file mode 100644
index 0000000..7cbd559
--- /dev/null
+++ b/test/CodeGenCXX/global-init.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -triple=x86_64-apple-darwin10 -emit-llvm %s -o - |FileCheck %s
+
+struct A {
+  A();
+  ~A();
+};
+
+struct B { B(); ~B(); };
+
+struct C { void *field; };
+
+struct D { ~D(); };
+
+// CHECK: @c = global %struct.C zeroinitializer, align 8
+
+// CHECK: call void @_ZN1AC1Ev(%struct.A* @a)
+// CHECK: call i32 @__cxa_atexit(void (i8*)* bitcast (void (%struct.A*)* @_ZN1AD1Ev to void (i8*)*), i8* getelementptr inbounds (%struct.A* @a, i32 0, i32 0), i8* bitcast (i8** @__dso_handle to i8*))
+A a;
+
+// CHECK: call void @_ZN1BC1Ev(%struct.A* @b)
+// CHECK: call i32 @__cxa_atexit(void (i8*)* bitcast (void (%struct.A*)* @_ZN1BD1Ev to void (i8*)*), i8* getelementptr inbounds (%struct.A* @b, i32 0, i32 0), i8* bitcast (i8** @__dso_handle to i8*))
+B b;
+
+// PR6205: this should not require a global initializer
+// CHECK-NOT: call void @_ZN1CC1Ev(%struct.C* @c)
+C c;
+
+// CHECK: call i32 @__cxa_atexit(void (i8*)* bitcast (void (%struct.A*)* @_ZN1DD1Ev to void (i8*)*), i8* getelementptr inbounds (%struct.A* @d, i32 0, i32 0), i8* bitcast (i8** @__dso_handle to i8*))
+D d;
+
+// CHECK: define internal void @_GLOBAL__I_a() {
diff --git a/test/CodeGenCXX/global-llvm-constant.cpp b/test/CodeGenCXX/global-llvm-constant.cpp
new file mode 100644
index 0000000..ef1dcf0
--- /dev/null
+++ b/test/CodeGenCXX/global-llvm-constant.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+
+struct A {
+  A() { x = 10; }
+  int x;
+};
+
+const A x;
+
+// CHECK: @_ZL1x = internal global
diff --git a/test/CodeGenCXX/implicit-instantiation-1.cpp b/test/CodeGenCXX/implicit-instantiation-1.cpp
new file mode 100644
index 0000000..0c826e4
--- /dev/null
+++ b/test/CodeGenCXX/implicit-instantiation-1.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -emit-llvm %s -o %t
+
+template<typename T>
+struct X {
+  void f(T) { }
+  void f(char) { }
+  
+  void g(T) { }
+  
+  void h(T) { }
+};
+
+void foo(X<int> &xi, X<float> *xfp, int i, float f) {
+  // RUN: grep "linkonce_odr.*_ZN1XIiE1fEi" %t | count 1
+  xi.f(i);
+  
+  // RUN: grep "linkonce_odr.*_ZN1XIiE1gEi" %t | count 1
+  xi.g(f);
+  
+  // RUN: grep "linkonce_odr.*_ZN1XIfE1fEf" %t | count 1
+  xfp->f(f);
+  
+  // RUN: grep "linkonce_odr.*_ZN1XIfE1hEf" %t | count 0
+  
+}
+
+
+
diff --git a/test/CodeGenCXX/init-incomplete-type.cpp b/test/CodeGenCXX/init-incomplete-type.cpp
new file mode 100644
index 0000000..3312d3e
--- /dev/null
+++ b/test/CodeGenCXX/init-incomplete-type.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 %s -emit-llvm-only -verify
+// PR5489
+
+template<typename E>
+struct Bar {
+ int x_;
+};
+
+static struct Bar<int> bar[1] = {
+  { 0 }
+};
+
diff --git a/test/CodeGenCXX/inline-functions.cpp b/test/CodeGenCXX/inline-functions.cpp
new file mode 100644
index 0000000..8d046a2
--- /dev/null
+++ b/test/CodeGenCXX/inline-functions.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+// CHECK: ; ModuleID 
+
+struct A {
+    inline void f();
+};
+
+// CHECK-NOT: define void @_ZN1A1fEv
+void A::f() { }
+
+template<typename> struct B { };
+
+template<> struct B<char> {
+  inline void f();
+};
+
+// CHECK-NOT: _ZN1BIcE1fEv
+void B<char>::f() { }
+
+// We need a final CHECK line here.
+
+// CHECK: define void @_Z1fv
+void f() { }
diff --git a/test/CodeGenCXX/instantiate-init-list.cpp b/test/CodeGenCXX/instantiate-init-list.cpp
new file mode 100644
index 0000000..49c6f51
--- /dev/null
+++ b/test/CodeGenCXX/instantiate-init-list.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 %s -emit-llvm-only -verify
+
+struct F {
+  void (*x)();
+};
+void G();
+template<class T> class A {
+public: A();
+};
+template<class T> A<T>::A() {
+  static F f = { G };
+}
+A<int> a;
diff --git a/test/CodeGenCXX/internal-linkage.cpp b/test/CodeGenCXX/internal-linkage.cpp
new file mode 100644
index 0000000..4263891
--- /dev/null
+++ b/test/CodeGenCXX/internal-linkage.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+
+struct Global { Global(); };
+template<typename T> struct X { X(); };
+
+
+namespace {
+  struct Anon { Anon(); };
+
+  // CHECK: @_ZN12_GLOBAL__N_15anon0E = internal global
+  Global anon0;
+}
+
+// CHECK: @anon1 = internal global
+Anon anon1;
+
+// CHECK: @anon2 = internal global
+X<Anon> anon2;
+
diff --git a/test/CodeGenCXX/key-function-vtable.cpp b/test/CodeGenCXX/key-function-vtable.cpp
new file mode 100644
index 0000000..251a14e
--- /dev/null
+++ b/test/CodeGenCXX/key-function-vtable.cpp
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+
+// Simple key function test
+struct testa { virtual void a(); };
+void testa::a() {}
+
+// Simple key function test
+struct testb { virtual void a() {} };
+testb *testbvar = new testb;
+
+// Key function with out-of-line inline definition
+struct testc { virtual void a(); };
+inline void testc::a() {}
+
+// Key functions with inline specifier (PR5705)
+struct testd { inline virtual void a(); };
+void testd::a() {}
+
+// Key functions with inline specifier (PR5705)
+struct teste { inline virtual void a(); };
+teste *testevar = new teste;
+
+// Key functions with namespace (PR5711)
+namespace {
+  struct testf { virtual void a(); };
+}
+void testf::a() {}
+
+// Key functions with namespace (PR5711)
+namespace {
+  struct testg { virtual void a(); };
+}
+testg *testgvar = new testg;
+
+// FIXME: The checks are extremely difficult to get right when the globals
+// aren't alphabetized
+// CHECK: @_ZTV5testa = constant [3 x i8*] [i8* null
+// CHECK: @_ZTV5testc = weak_odr constant [3 x i8*] [i8* null
+// CHECK: @_ZTVN12_GLOBAL__N_15testgE = internal constant [3 x i8*] [i8* null
+// CHECK: @_ZTV5teste = weak_odr constant [3 x i8*] [i8* null
+// CHECK: @_ZTV5testb = weak_odr constant [3 x i8*] [i8* null
+
diff --git a/test/CodeGenCXX/mangle-exprs.cpp b/test/CodeGenCXX/mangle-exprs.cpp
new file mode 100644
index 0000000..6f1ca55
--- /dev/null
+++ b/test/CodeGenCXX/mangle-exprs.cpp
@@ -0,0 +1,44 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 | FileCheck %s
+
+template < bool condition, typename T = void >
+struct enable_if { typedef T type; };
+
+template< typename T >
+struct enable_if< false, T > {};
+
+// PR5876
+namespace Casts {
+  template< unsigned O >
+  void implicit(typename enable_if< O <= 4 >::type* = 0) {
+  }
+  
+  template< unsigned O >
+  void cstyle(typename enable_if< O <= (unsigned)4 >::type* = 0) {
+  }
+
+  template< unsigned O >
+  void functional(typename enable_if< O <= unsigned(4) >::type* = 0) {
+  }
+  
+  template< unsigned O >
+  void static_(typename enable_if< O <= static_cast<unsigned>(4) >::type* = 0) {
+  }
+
+  // FIXME: Test const_cast, reinterpret_cast, dynamic_cast, which are
+  // a bit harder to use in template arguments.
+  template <unsigned N> struct T {};
+
+  template <int N> T<N> f() { return T<N>(); }
+  
+  // CHECK: define weak_odr void @_ZN5Casts8implicitILj4EEEvPN9enable_ifIXleT_Li4EEvE4typeE
+  template void implicit<4>(void*);
+  // CHECK: define weak_odr void @_ZN5Casts6cstyleILj4EEEvPN9enable_ifIXleT_cvjLi4EEvE4typeE
+  template void cstyle<4>(void*);
+  // CHECK: define weak_odr void @_ZN5Casts10functionalILj4EEEvPN9enable_ifIXleT_cvjLi4EEvE4typeE
+  template void functional<4>(void*);
+  // CHECK: define weak_odr void @_ZN5Casts7static_ILj4EEEvPN9enable_ifIXleT_cvjLi4EEvE4typeE
+  template void static_<4>(void*);
+
+  // CHECK: define weak_odr i64 @_ZN5Casts1fILi6EEENS_1TIXT_EEEv
+  template T<6> f<6>();
+}
diff --git a/test/CodeGenCXX/mangle-extern-local.cpp b/test/CodeGenCXX/mangle-extern-local.cpp
new file mode 100644
index 0000000..ed91da4
--- /dev/null
+++ b/test/CodeGenCXX/mangle-extern-local.cpp
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+
+// CHECK: @var1 = external global i32
+// CHECK: @_ZN1N4var2E = external global i32
+// CHECK: @var5 = external global i32
+// CHECK: @_ZN1N4var3E = external global i32
+// CHECK: @_ZN1N4var4E = external global i32
+
+// CHECK: declare i32 @_Z5func1v()
+// CHECK: declare i32 @_ZN1N5func2Ev()
+// CHECK: declare i32 @func4()
+// CHECK: declare i32 @_ZN1N5func3Ev()
+
+int f1() {
+  extern int var1, func1();
+  return var1 + func1();
+}
+
+namespace N {
+
+int f2() {
+  extern int var2, func2();
+  return var2 + func2();
+}
+
+struct S {
+  static int f3() {
+    extern int var3, func3();
+    struct LC { int localfunc() { extern int var4; return var4; } };
+    LC localobj;
+    return var3 + func3() + localobj.localfunc();
+  }
+};
+
+int anchorf3() { return S::f3(); } 
+
+extern "C" {
+int f4() {
+  extern int var5, func4();
+  return var5 + func4();
+}
+}
+
+}
+
diff --git a/test/CodeGenCXX/mangle-extreme.cpp b/test/CodeGenCXX/mangle-extreme.cpp
new file mode 100644
index 0000000..ef2d466
--- /dev/null
+++ b/test/CodeGenCXX/mangle-extreme.cpp
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 | FileCheck %s
+
+struct X { };
+
+// CHECK: define void @_Z1fPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP1XS13_S12_S11_S10_SZ_SY_SX_SW_SV_SU_ST_SS_SR_SQ_SP_SO_SN_SM_SL_SK_SJ_SI_SH_SG_SF_SE_SD_SC_SB_SA_S9_S8_S7_S6_S5_S4_S3_S2_S1_S0_S_(
+void f(X****************************************,
+       X****************************************,
+       X***************************************,
+       X**************************************,
+       X*************************************,
+       X************************************,
+       X***********************************,
+       X**********************************,
+       X*********************************,
+       X********************************,
+       X*******************************,
+       X******************************,
+       X*****************************,
+       X****************************,
+       X***************************,
+       X**************************,
+       X*************************,
+       X************************,
+       X***********************,
+       X**********************,
+       X*********************,
+       X********************,
+       X*******************,
+       X******************,
+       X*****************,
+       X****************,
+       X***************,
+       X**************,
+       X*************,
+       X************,
+       X***********,
+       X**********,
+       X*********,
+       X********,
+       X*******,
+       X******,
+       X*****,
+       X****,
+       X***,
+       X**,
+       X*,
+       X) { }
diff --git a/test/CodeGenCXX/mangle-local-class-names.cpp b/test/CodeGenCXX/mangle-local-class-names.cpp
new file mode 100644
index 0000000..3321460
--- /dev/null
+++ b/test/CodeGenCXX/mangle-local-class-names.cpp
@@ -0,0 +1,57 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+
+// CHECK:  @_ZZ4FUNCvEN4SSSSC1ERKf
+// CHECK: @_ZZ4FUNCvEN4SSSSC2E_0RKf
+// CHECK:  @_ZZ4GORFfEN4SSSSC1ERKf
+// CHECK: @_ZZ4GORFfEN4SSSSC2E_0RKf
+
+void FUNC ()
+{
+  {
+    float IVAR1 ;
+
+    struct SSSS 
+    {
+      float bv;
+      SSSS( const float& from): bv(from) { }
+    };
+
+    SSSS VAR1(IVAR1);
+   }
+
+   {
+    float IVAR2 ;
+
+    struct SSSS
+    {
+     SSSS( const float& from) {}
+    };
+
+    SSSS VAR2(IVAR2);
+   }
+}
+
+void GORF (float IVAR1)
+{
+  {
+    struct SSSS 
+    {
+      float bv;
+      SSSS( const float& from): bv(from) { }
+    };
+
+    SSSS VAR1(IVAR1);
+   }
+
+   {
+    float IVAR2 ;
+
+    struct SSSS
+    {
+     SSSS( const float& from) {}
+    };
+
+    SSSS VAR2(IVAR2);
+   }
+}
+
diff --git a/test/CodeGenCXX/mangle-subst-std.cpp b/test/CodeGenCXX/mangle-subst-std.cpp
new file mode 100644
index 0000000..062610b
--- /dev/null
+++ b/test/CodeGenCXX/mangle-subst-std.cpp
@@ -0,0 +1,63 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 | FileCheck %s
+
+namespace std {
+  struct A { A(); };
+  
+  // CHECK: define void @_ZNSt1AC1Ev
+  // CHECK: define void @_ZNSt1AC2Ev
+  A::A() { }
+};
+
+namespace std {
+  template<typename> struct allocator { };
+}
+
+// CHECK: define void @_Z1fSaIcESaIiE
+void f(std::allocator<char>, std::allocator<int>) { }
+
+namespace std {
+  template<typename, typename, typename> struct basic_string { };
+}
+
+// CHECK: define void @_Z1fSbIcciE
+void f(std::basic_string<char, char, int>) { }
+
+namespace std {
+  template<typename> struct char_traits { };
+  
+  typedef std::basic_string<char, std::char_traits<char>, std::allocator<char> > string;
+}
+
+// CHECK: _Z1fSs
+void f(std::string) { }
+
+namespace std {
+  template<typename, typename> struct basic_istream { };
+  template<typename, typename> struct basic_ostream { };
+  template<typename, typename> struct basic_iostream { };
+}
+
+// CHECK: _Z1fSi
+void f(std::basic_istream<char, std::char_traits<char> >) { }
+
+// CHECK: _Z1fSo
+void f(std::basic_ostream<char, std::char_traits<char> >) { }
+
+// CHECK: _Z1fSd
+void f(std::basic_iostream<char, std::char_traits<char> >) { }
+
+extern "C++" {
+namespace std
+{
+  typedef void (*terminate_handler) ();
+  
+  // CHECK: _ZSt13set_terminatePFvvE
+  terminate_handler set_terminate(terminate_handler) { return 0; }
+}
+}
+
+// Make sure we don't treat the following like std::string
+// CHECK: define void @_Z1f12basic_stringIcSt11char_traitsIcESaIcEE
+template<typename, typename, typename> struct basic_string { };
+typedef basic_string<char, std::char_traits<char>, std::allocator<char> > not_string;
+void f(not_string) { }
diff --git a/test/CodeGenCXX/mangle-subst.cpp b/test/CodeGenCXX/mangle-subst.cpp
new file mode 100644
index 0000000..bd06869
--- /dev/null
+++ b/test/CodeGenCXX/mangle-subst.cpp
@@ -0,0 +1,69 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 | FileCheck %s
+
+struct X {};
+
+// CHECK: define void @_Z1f1XS_(
+void f(X, X) { }
+
+// CHECK: define void @_Z1fR1XS0_(
+void f(X&, X&) { }
+
+// CHECK: define void @_Z1fRK1XS1_(
+void f(const X&, const X&) { }
+
+typedef void T();
+struct S {};
+
+// CHECK: define void @_Z1fPFvvEM1SFvvE(
+void f(T*, T (S::*)) {}
+
+namespace A {
+  struct A { };
+  struct B { };
+};
+
+// CHECK: define void @_Z1fN1A1AENS_1BE(
+void f(A::A a, A::B b) { }
+
+struct C {
+  struct D { };
+};
+
+// CHECK: define void @_Z1fN1C1DERS_PS_S1_(
+void f(C::D, C&, C*, C&) { }
+
+template<typename T>
+struct V {
+  typedef int U;
+};
+
+template <typename T> void f1(typename V<T>::U, V<T>) { }
+
+// CHECK: @_Z2f1IiEvN1VIT_E1UES2_
+template void f1<int>(int, V<int>);
+
+template <typename T> void f2(V<T>, typename V<T>::U) { }
+
+// CHECK: @_Z2f2IiEv1VIT_ENS2_1UE
+template void f2<int>(V<int>, int);
+
+namespace NS {
+template <typename T> struct S1 {};
+template<typename T> void ft3(S1<T>, S1<char>) {  }
+
+// CHECK: @_ZN2NS3ft3IiEEvNS_2S1IT_EENS1_IcEE
+template void ft3<int>(S1<int>, S1<char>);
+}
+
+// PR5196
+// CHECK: @_Z1fPKcS0_
+void f(const char*, const char*) {}
+
+namespace NS {
+  class C;
+}
+
+namespace NS {
+  // CHECK: @_ZN2NS1fERNS_1CE
+  void f(C&) { } 
+}
diff --git a/test/CodeGenCXX/mangle-system-header.cpp b/test/CodeGenCXX/mangle-system-header.cpp
new file mode 100644
index 0000000..6716b58
--- /dev/null
+++ b/test/CodeGenCXX/mangle-system-header.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 | FileCheck %s
+
+// PR5420
+
+# 1 "fake_system_header.h" 1 3 4
+// CHECK: define void @_ZdlPvS_(
+void operator delete (void*, void*) {}
+
+// PR6217
+// CHECK: define void @_Z3barv() 
+void bar() { }
diff --git a/test/CodeGenCXX/mangle-template.cpp b/test/CodeGenCXX/mangle-template.cpp
new file mode 100644
index 0000000..8b097ff
--- /dev/null
+++ b/test/CodeGenCXX/mangle-template.cpp
@@ -0,0 +1,129 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+namespace test1 {
+int x;
+template <int& D> class T { };
+// CHECK: void @_ZN5test12f0ENS_1TILZNS_1xEEEE(
+void f0(T<x> a0) {}
+}
+
+namespace test1 {
+// CHECK: void @_ZN5test12f0Ef
+void f0(float) {}
+template<void (&)(float)> struct t1 {};
+// CHECK: void @_ZN5test12f1ENS_2t1ILZNS_2f0EfEEE(
+void f1(t1<f0> a0) {}
+}
+
+namespace test2 {
+// CHECK: void @_ZN5test22f0Ef
+void f0(float) {}
+template<void (*)(float)> struct t1 {};
+// FIXME: Fails because we don't treat as an expression.
+// CHECK-FIXME: void @_ZN5test22f1ENS_2t1IXadL_ZNS_2f0EfEEEE(
+void f1(t1<f0> a0) {}
+}
+
+namespace test3 {
+// CHECK: void @test3_f0
+extern "C" void test3_f0(float) {}
+template<void (&)(float)> struct t1 {};
+// FIXME: Fails because we tack on a namespace.
+// CHECK-FIXME: void @_ZN5test32f1ENS_2t1ILZ8test3_f0EEE(
+void f1(t1<test3_f0> a0) {}
+}
+
+namespace test4 {
+// CHECK: void @test4_f0
+extern "C" void test4_f0(float) {}
+template<void (*)(float)> struct t1 {};
+// FIXME: Fails because we don't treat as an expression.
+// CHECK-FIXME: void @_ZN5test42f1ENS_2t1IXadL_Z8test4_f0EEEE(
+void f1(t1<test4_f0> a0) {}
+}
+
+// CHECK: void @test5_f0
+extern "C" void test5_f0(float) {}
+int main(int) {}
+
+namespace test5 {
+template<void (&)(float)> struct t1 {};
+// CHECK: void @_ZN5test52f1ENS_2t1ILZ8test5_f0EEE(
+void f1(t1<test5_f0> a0) {}
+
+template<int (&)(int)> struct t2 {};
+// CHECK: void @_ZN5test52f2ENS_2t2ILZ4mainEEE
+void f2(t2<main> a0) {}
+}
+
+// FIXME: This fails.
+namespace test6 {
+struct A { void im0(float); };
+// CHECK: void @_ZN5test61A3im0Ef
+void A::im0(float) {}
+template <void(A::*)(float)> class T { };
+// FIXME: Fails because we don't treat as an expression.
+// CHECK-FAIL: void @_ZN5test62f0ENS_1TIXadL_ZNS_1A3im0EfEEEE(
+void f0(T<&A::im0> a0) {}
+}
+
+namespace test7 {
+  template<typename T>
+  struct meta {
+    static const unsigned value = sizeof(T);
+  };
+
+  template<unsigned> struct int_c { 
+    typedef float type;
+  };
+
+  template<typename T>
+  struct X {
+    template<typename U>
+    X(U*, typename int_c<(meta<T>::value + meta<U>::value)>::type *) { }
+  };
+
+  // CHECK: define weak_odr void @_ZN5test71XIiEC1IdEEPT_PNS_5int_cIXplL_ZNS_4metaIiE5valueEEsrNS6_IS3_EE5valueEE4typeE
+  template X<int>::X(double*, float*);
+}
+
+namespace test8 {
+  template<typename T>
+  struct meta {
+    struct type {
+      static const unsigned value = sizeof(T);
+    };
+  };
+
+  template<unsigned> struct int_c { 
+    typedef float type;
+  };
+
+  template<typename T>
+  void f(int_c<meta<T>::type::value>) { }
+
+  // CHECK: define weak_odr void @_ZN5test81fIiEEvNS_5int_cIXsrNS_4metaIT_E4typeE5valueEEE
+  template void f<int>(int_c<sizeof(int)>);
+}
+
+namespace test9 {
+  template<typename T>
+  struct supermeta {
+    template<typename U>
+    struct apply {
+      typedef T U::*type;
+    };
+  };
+
+  struct X { };
+
+  template<typename T, typename U>
+  typename supermeta<T>::template apply<U>::type f();
+
+  void test_f() {
+    // CHECK: @_ZN5test91fIiNS_1XEEENS_9supermetaIT_E5applyIT0_E4typeEv()
+    // Note: GCC incorrectly mangles this as
+    // _ZN5test91fIiNS_1XEEENS_9supermetaIT_E5apply4typeEv, while EDG
+    // gets it right.
+    f<int, X>();
+  }
+}
diff --git a/test/CodeGenCXX/mangle-unnamed.cpp b/test/CodeGenCXX/mangle-unnamed.cpp
new file mode 100644
index 0000000..4aec7db
--- /dev/null
+++ b/test/CodeGenCXX/mangle-unnamed.cpp
@@ -0,0 +1,39 @@
+// RUN: %clang_cc1 -emit-llvm-only -verify %s
+
+struct S {
+  virtual ~S() { }
+};
+
+// PR5706
+// Make sure this doesn't crash; the mangling doesn't matter because the name
+// doesn't have linkage.
+static struct : S { } obj8;
+
+void f() {
+  // Make sure this doesn't crash; the mangling doesn't matter because the
+  // generated vtable/etc. aren't modifiable (although it would be nice for
+  // codesize to make it consistent inside inline functions).
+  static struct : S { } obj8;
+}
+
+inline int f2() {
+  // FIXME: We don't mangle the names of a or x correctly!
+  static struct { int a() { static int x; return ++x; } } obj;
+  return obj.a();
+}
+
+int f3() { return f2(); }
+
+struct A {
+  typedef struct { int x; } *ptr;
+  ptr m;
+  int a() {
+    static struct x {
+      // FIXME: We don't mangle the names of a or x correctly!
+      int a(ptr A::*memp) { static int x; return ++x; }
+    } a;
+    return a.a(&A::m);
+  }
+};
+
+int f4() { return A().a(); }
diff --git a/test/CodeGenCXX/mangle.cpp b/test/CodeGenCXX/mangle.cpp
new file mode 100644
index 0000000..8f3d356
--- /dev/null
+++ b/test/CodeGenCXX/mangle.cpp
@@ -0,0 +1,479 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 -fblocks -std=c++0x | FileCheck %s
+struct X { };
+struct Y { };
+
+// CHECK: @unmangled_variable = global
+// CHECK: @_ZN1N1iE = global
+// CHECK: @_ZZN1N1fEiiE1b = internal global
+// CHECK: @_ZZN1N1gEvE1a = internal global
+// CHECK: @_ZGVZN1N1gEvE1a = internal global
+
+//CHECK: @pr5966_i = external global
+//CHECK: @_ZL8pr5966_i = internal global
+
+// CHECK: define zeroext i1 @_ZplRK1YRA100_P1X
+bool operator+(const Y&, X* (&xs)[100]) { return false; }
+
+// CHECK: define void @_Z1f1s
+typedef struct { int a; } s;
+void f(s) { }
+
+// CHECK: define void @_Z1f1e
+typedef enum { foo } e;
+void f(e) { }
+
+// CHECK: define void @_Z1f1u
+typedef union { int a; } u;
+void f(u) { }
+
+// CHECK: define void @_Z1f1x
+typedef struct { int a; } x,y;
+void f(y) { }
+
+// CHECK: define void @_Z1fv
+void f() { }
+
+// CHECK: define void @_ZN1N1fEv
+namespace N { void f() { } }
+
+// CHECK: define void @_ZN1N1N1fEv
+namespace N { namespace N { void f() { } } }
+
+// CHECK: define void @unmangled_function
+extern "C" { namespace N { void unmangled_function() { } } }
+
+extern "C" { namespace N { int unmangled_variable = 10; } }
+
+namespace N { int i; }
+
+namespace N { int f(int, int) { static int b; return b; } }
+
+namespace N { int h(); void g() { static int a = h(); } }
+
+// CHECK: define void @_Z1fno
+void f(__int128_t, __uint128_t) { } 
+
+template <typename T> struct S1 {};
+
+// CHECK: define void @_Z1f2S1IiE
+void f(S1<int>) {}
+
+// CHECK: define void @_Z1f2S1IdE
+void f(S1<double>) {}
+
+template <int N> struct S2 {};
+// CHECK: define void @_Z1f2S2ILi100EE
+void f(S2<100>) {}
+
+// CHECK: define void @_Z1f2S2ILin100EE
+void f(S2<-100>) {}
+
+template <bool B> struct S3 {};
+
+// CHECK: define void @_Z1f2S3ILb1EE
+void f(S3<true>) {}
+
+// CHECK: define void @_Z1f2S3ILb0EE
+void f(S3<false>) {}
+
+// CHECK: define void @_Z2f22S3ILb1EE
+void f2(S3<100>) {}
+
+struct S;
+
+// CHECK: define void @_Z1fM1SKFvvE
+void f(void (S::*)() const) {}
+
+// CHECK: define void @_Z1fM1SFvvE
+void f(void (S::*)()) {}
+
+// CHECK: define void @_Z1fi
+void f(const int) { }
+
+template<typename T, typename U> void ft1(U u, T t) { }
+
+template<typename T> void ft2(T t, void (*)(T), void (*)(T)) { }
+
+template<typename T, typename U = S1<T> > struct S4 { };
+template<typename T> void ft3(S4<T>*) {  }
+
+namespace NS {
+  template<typename T> void ft1(T) { }
+}
+
+void g1() {
+  // CHECK: @_Z3ft1IidEvT0_T_
+  ft1<int, double>(1, 0);
+  
+  // CHECK: @_Z3ft2IcEvT_PFvS0_ES2_
+  ft2<char>(1, 0, 0);
+  
+  // CHECK: @_Z3ft3IiEvP2S4IT_2S1IS1_EE
+  ft3<int>(0);
+  
+  // CHECK: @_ZN2NS3ft1IiEEvT_
+  NS::ft1<int>(1);
+}
+
+// Expressions
+template<int I> struct S5 { };
+
+template<int I> void ft4(S5<I>) { }
+void g2() {
+  // CHECK: @_Z3ft4ILi10EEv2S5IXT_EE
+  ft4(S5<10>());
+  
+  // CHECK: @_Z3ft4ILi20EEv2S5IXT_EE
+  ft4(S5<20>());
+}
+
+extern "C++" {
+  // CHECK: @_Z1hv
+ void h() { } 
+}
+
+// PR5019
+extern "C" { struct a { int b; }; }
+
+// CHECK: @_Z1fP1a
+int f(struct a *x) {
+    return x->b;
+}
+
+// PR5017
+extern "C" {
+struct Debug {
+  const Debug& operator<< (unsigned a) const { return *this; }
+};
+Debug dbg;
+// CHECK: @_ZNK5DebuglsEj
+int main(void) {  dbg << 32 ;}
+}
+
+template<typename T> struct S6 {
+  typedef int B;
+};
+
+template<typename T> void ft5(typename S6<T>::B) { }
+// CHECK: @_Z3ft5IiEvN2S6IT_E1BE
+template void ft5<int>(int);
+
+template<typename T> class A {};
+
+namespace NS {
+template<typename T> bool operator==(const A<T>&, const A<T>&) { return true; }
+}
+
+// CHECK: @_ZN2NSeqIcEEbRK1AIT_ES5_
+template bool NS::operator==(const ::A<char>&, const ::A<char>&);
+
+namespace std {
+template<typename T> bool operator==(const A<T>&, const A<T>&) { return true; }
+}
+
+// CHECK: @_ZSteqIcEbRK1AIT_ES4_
+template bool std::operator==(const ::A<char>&, const ::A<char>&);
+
+struct S {
+  typedef int U;
+};
+
+template <typename T> typename T::U ft6(const T&) { return 0; }
+
+// CHECK: @_Z3ft6I1SENT_1UERKS1_
+template int ft6<S>(const S&);
+
+template<typename> struct __is_scalar {
+  enum { __value = 1 };
+};
+
+template<bool, typename> struct __enable_if { };
+
+template<typename T> struct __enable_if<true, T> {
+  typedef T __type;
+};
+
+// PR5063
+template<typename T> typename __enable_if<__is_scalar<T>::__value, void>::__type ft7() { }
+
+// CHECK: @_Z3ft7IiEN11__enable_ifIXsr11__is_scalarIT_E7__valueEvE6__typeEv
+template void ft7<int>();
+// CHECK: @_Z3ft7IPvEN11__enable_ifIXsr11__is_scalarIT_E7__valueEvE6__typeEv
+template void ft7<void*>();
+
+// PR5144
+extern "C" {
+void extern_f(void);
+};
+
+// CHECK: @extern_f
+void extern_f(void) { }
+
+struct S7 {
+  S7();
+  
+  struct S { S(); };
+  struct {
+    S s;
+  } a;
+};
+
+// PR5139
+// CHECK: @_ZN2S7C1Ev
+// CHECK: @_ZN2S7C2Ev
+// CHECK: @"_ZN2S73$_0C1Ev"
+S7::S7() {}
+
+// PR5063
+template<typename T> typename __enable_if<(__is_scalar<T>::__value), void>::__type ft8() { }
+// CHECK: @_Z3ft8IiEN11__enable_ifIXsr11__is_scalarIT_E7__valueEvE6__typeEv
+template void ft8<int>();
+// CHECK: @_Z3ft8IPvEN11__enable_ifIXsr11__is_scalarIT_E7__valueEvE6__typeEv
+template void ft8<void*>();
+
+// PR5796
+namespace PR5796 {
+template<typename> struct __is_scalar {
+  enum { __value = 0 };
+};
+
+template<bool, typename> struct __enable_if {};
+template<typename T> struct __enable_if<true, T> { typedef T __type; };
+template<typename T>
+
+// CHECK: define linkonce_odr void @_ZN6PR57968__fill_aIiEENS_11__enable_ifIXntsrNS_11__is_scalarIT_EE7__valueEvE6__typeEv
+typename __enable_if<!__is_scalar<T>::__value, void>::__type __fill_a() { };
+
+void f() { __fill_a<int>(); }
+}
+
+namespace Expressions {
+// Unary operators.
+
+// CHECK: define weak_odr void @_ZN11Expressions2f1ILi1EEEvPAplngT_Li2E_i
+template <int i> void f1(int (*)[(-i) + 2]) { };
+template void f1<1>(int (*)[1]);
+
+// CHECK: define weak_odr void @_ZN11Expressions2f2ILi1EEEvPApsT__i
+template <int i> void f2(int (*)[+i]) { };
+template void f2<1>(int (*)[1]);
+
+// Binary operators.
+
+// CHECK: define weak_odr void @_ZN11Expressions2f3ILi1EEEvPAplT_T__i
+template <int i> void f3(int (*)[i+i]) { };
+template void f3<1>(int (*)[2]);
+
+// CHECK: define weak_odr void @_ZN11Expressions2f4ILi1EEEvPAplplLi2ET_T__i
+template <int i> void f4(int (*)[2 + i+i]) { };
+template void f4<1>(int (*)[4]);
+
+// The ternary operator.
+// CHECK: define weak_odr void @_ZN11Expressions2f4ILb1EEEvPAquT_Li1ELi2E_i
+template <bool b> void f4(int (*)[b ? 1 : 2]) { };
+template void f4<true>(int (*)[1]);
+}
+
+struct Ops {
+  Ops& operator+(const Ops&);
+  Ops& operator-(const Ops&);
+  Ops& operator&(const Ops&);
+  Ops& operator*(const Ops&);
+  
+  void *v;
+};
+
+// CHECK: define %struct.Ops* @_ZN3OpsplERKS_
+Ops& Ops::operator+(const Ops&) { return *this; }
+// CHECK: define %struct.Ops* @_ZN3OpsmiERKS_
+Ops& Ops::operator-(const Ops&) { return *this; }
+// CHECK: define %struct.Ops* @_ZN3OpsanERKS_
+Ops& Ops::operator&(const Ops&) { return *this; }
+// CHECK: define %struct.Ops* @_ZN3OpsmlERKS_
+Ops& Ops::operator*(const Ops&) { return *this; }
+
+// PR5861
+namespace PR5861 {
+template<bool> class P;
+template<> class P<true> {};
+
+template<template <bool> class, bool>
+struct Policy { };
+
+template<typename T, typename = Policy<P, true> > class Alloc
+{
+  T *allocate(int, const void*) { return 0; }
+};
+
+// CHECK: define weak_odr i8* @_ZN6PR58615AllocIcNS_6PolicyINS_1PELb1EEEE8allocateEiPKv
+template class Alloc<char>;
+}
+
+// CHECK: define void @_Z1fU13block_pointerFiiiE
+void f(int (^)(int, int)) { }
+
+void pr5966_foo() {
+  extern int pr5966_i;
+  pr5966_i = 0;
+}
+
+static int pr5966_i;
+
+void pr5966_bar() {
+  pr5966_i = 0;
+}
+
+namespace test0 {
+  int ovl(int x);
+  char ovl(double x);
+
+  template <class T> void f(T, char (&buffer)[sizeof(ovl(T()))]) {}
+
+  void test0() {
+    char buffer[1];
+    f(0.0, buffer);
+  }
+  // CHECK: define void @_ZN5test05test0Ev()
+  // CHECK: define linkonce_odr void @_ZN5test01fIdEEvT_RAszcl3ovlcvS1__EE_c(
+
+  void test1() {
+    char buffer[sizeof(int)];
+    f(1, buffer);
+  }
+  // CHECK: define void @_ZN5test05test1Ev()
+  // CHECK: define linkonce_odr void @_ZN5test01fIiEEvT_RAszcl3ovlcvS1__EE_c(
+
+  template <class T> void g(char (&buffer)[sizeof(T() + 5.0f)]) {}
+  void test2() {
+    char buffer[sizeof(float)];
+    g<float>(buffer);
+  }
+  // CHECK: define linkonce_odr void @_ZN5test01gIfEEvRAszplcvT__ELf40A00000E_c(
+
+  template <class T> void h(char (&buffer)[sizeof(T() + 5.0)]) {}
+  void test3() {
+    char buffer[sizeof(double)];
+    h<float>(buffer);
+  }
+  // CHECK: define linkonce_odr void @_ZN5test01hIfEEvRAszplcvT__ELd4014000000000000E_c(
+
+  template <class T> void j(char (&buffer)[sizeof(T().buffer)]) {}
+  struct A { double buffer[128]; };
+  void test4() {
+    char buffer[1024];
+    j<A>(buffer);
+  }
+  // CHECK: define linkonce_odr void @_ZN5test01jINS_1AEEEvRAszdtcvT__E6buffer_c(
+}
+
+namespace test1 {
+  template<typename T> struct X { };
+  template<template<class> class Y, typename T> void f(Y<T>) { }
+  // CHECK: define weak_odr void @_ZN5test11fINS_1XEiEEvT_IT0_E
+  template void f(X<int>);
+}
+
+// CHECK: define internal void @_Z27functionWithInternalLinkagev()
+static void functionWithInternalLinkage() {  }
+void g() { functionWithInternalLinkage(); }
+
+namespace test2 {
+  template <class T> decltype(((T*) 0)->member) read_member(T& obj) {
+    return obj.member;
+  }
+
+  struct A { int member; } obj;
+  int test() {
+    return read_member(obj);
+  }
+
+  // CHECK: define linkonce_odr i32 @_ZN5test211read_memberINS_1AEEEDtptcvPT_Li0E6memberERS2_(
+}
+
+namespace test3 {
+  struct AmbiguousBase { int ab; };
+  struct Path1 : AmbiguousBase { float p; };
+  struct Path2 : AmbiguousBase { double p; };
+  struct Derived : Path1, Path2 { };
+
+  //template <class T> decltype(((T*) 0)->Path1::ab) get_ab_1(T &ref) { return ref.Path1::ab; }
+  //template <class T> decltype(((T*) 0)->Path2::ab) get_ab_2(T &ref) { return ref.Path2::ab; }
+
+  // define weak_odr float @_ZN5test37get_p_1INS_7DerivedEEEDtptcvPT_Li0E5Path11pERS2_(
+  template <class T> decltype(((T*) 0)->Path1::p) get_p_1(T &ref) { return ref.Path1::p; }
+
+  // define weak_odr double @_ZN5test37get_p_1INS_7DerivedEEEDtptcvPT_Li0E5Path21pERS2_(
+  template <class T> decltype(((T*) 0)->Path2::p) get_p_2(T &ref) { return ref.Path2::p; }
+
+  Derived obj;
+  void test() {
+    // FIXME: uncomment these when we support diamonds competently
+    //get_ab_1(obj);
+    //get_ab_2(obj);
+    get_p_1(obj);
+    get_p_2(obj);
+  }
+}
+
+// CHECK: define void @_ZN5test41gEPNS_3zedIXadL_ZNS_3foo3barEEEEE
+namespace test4 {
+  struct foo { int bar; };
+  template <int (foo::*)>
+  struct zed {};
+  void g(zed<&foo::bar>*)
+  {}
+}
+// CHECK: define void @_ZN5test51gEPNS_3zedIXadL_ZNS_3foo3barEEEEE
+namespace test5 {
+  struct foo { static int bar; };
+  template <int *>
+  struct zed {};
+  void g(zed<&foo::bar>*)
+  {}
+}
+// CHECK: define void @_ZN5test61gEPNS_3zedIXadL_ZNS_3foo3barEvEEEE
+namespace test6 {
+  struct foo { int bar(); };
+  template <int (foo::*)()>
+  struct zed {};
+  void g(zed<&foo::bar>*)
+  {}
+}
+// CHECK: define void @_ZN5test71gEPNS_3zedIXadL_ZNS_3foo3barEvEEEE
+namespace test7 {
+  struct foo { static int bar(); };
+  template <int (*f)()>
+  struct zed {};
+  void g(zed<&foo::bar>*)
+  {}
+}
+// CHECK: define weak_odr void @_ZN5test81AILZNS_1B5valueEEE3incEv
+namespace test8 {
+  template <int &counter> class A { void inc() { counter++; } };
+  class B { public: static int value; };
+  template class A<B::value>;
+}
+// CHECK: declare void @_ZN5test91fIiNS_3barEEEvRKNT0_3baz1XE
+namespace test9 {
+  template<class T>
+  struct foo {
+    typedef T X;
+  };
+  struct bar {
+    typedef foo<int> baz;
+  };
+  template <class zaz, class zed>
+  void f(const typename zed::baz::X&);
+  void g() {
+    f<int, bar>( 0);
+  }
+}
+
+// <rdar://problem/7825453>
+namespace test10 {
+  template <char P1> struct S {};
+  template <char P2> void f(struct S<false ? 'a' : P2> ) {}
+
+  // CHECK: define weak_odr void @_ZN6test101fILc3EEEvNS_1SIXquLb0ELc97ET_EEE(
+  template void f<(char) 3>(struct S<3>);
+}
diff --git a/test/CodeGenCXX/member-call-parens.cpp b/test/CodeGenCXX/member-call-parens.cpp
new file mode 100644
index 0000000..2054137
--- /dev/null
+++ b/test/CodeGenCXX/member-call-parens.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -emit-llvm-only -verify %s
+
+struct A { int a(); };
+typedef int B;
+void a() {
+  A x;
+  ((x.a))();
+  ((x.*&A::a))();
+  B y;
+  // FIXME: Sema doesn't like this for some reason...
+  //(y.~B)();
+}
diff --git a/test/CodeGenCXX/member-expressions.cpp b/test/CodeGenCXX/member-expressions.cpp
new file mode 100644
index 0000000..d9fb394
--- /dev/null
+++ b/test/CodeGenCXX/member-expressions.cpp
@@ -0,0 +1,86 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin10 | FileCheck %s
+
+// PR5392
+namespace PR5392 {
+struct A
+{
+  static int a;
+};
+
+A a1;
+void f()
+{
+  // CHECK: store i32 10, i32* @_ZN6PR53921A1aE
+  a1.a = 10;
+  // CHECK: store i32 20, i32* @_ZN6PR53921A1aE
+  A().a = 20;
+}
+
+}
+
+struct A {
+  A();
+  ~A();
+  enum E { Foo };
+};
+
+A *g();
+
+void f(A *a) {
+  A::E e1 = a->Foo;
+  
+  // CHECK: call %struct.A* @_Z1gv()
+  A::E e2 = g()->Foo;
+  // CHECK: call void @_ZN1AC1Ev(
+  // CHECK: call void @_ZN1AD1Ev(
+  A::E e3 = A().Foo;
+}
+
+namespace test3 {
+struct A {
+  static int foo();
+};
+int f() {
+  return A().foo();
+}
+}
+
+namespace test4 {
+  struct A {
+    int x;
+  };
+  struct B {
+    int x;
+    void foo();
+  };
+  struct C : A, B {
+  };
+
+  extern C *c_ptr;
+
+  // CHECK: define i32 @_ZN5test44testEv()
+  int test() {
+    // CHECK: load {{.*}} @_ZN5test45c_ptrE
+    // CHECK-NEXT: bitcast
+    // CHECK-NEXT: getelementptr
+    // CHECK-NEXT: bitcast
+    // CHECK-NEXT: call void @_ZN5test41B3fooEv
+    c_ptr->B::foo();
+
+    // CHECK: load {{.*}} @_ZN5test45c_ptrE
+    // CHECK-NEXT: bitcast
+    // CHECK-NEXT: getelementptr
+    // CHECK-NEXT: bitcast
+    // CHECK-NEXT: getelementptr
+    // CHECK-NEXT: store i32 5
+    c_ptr->B::x = 5;
+
+    // CHECK: load {{.*}} @_ZN5test45c_ptrE
+    // CHECK-NEXT: bitcast
+    // CHECK-NEXT: getelementptr
+    // CHECK-NEXT: bitcast
+    // CHECK-NEXT: getelementptr
+    // CHECK-NEXT: load i32*
+    return c_ptr->B::x;
+  }
+}
diff --git a/test/CodeGenCXX/member-function-pointer-calls.cpp b/test/CodeGenCXX/member-function-pointer-calls.cpp
new file mode 100644
index 0000000..e1f2eb7
--- /dev/null
+++ b/test/CodeGenCXX/member-function-pointer-calls.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -O3 -o - | FileCheck %s
+struct A {
+  virtual int vf1() { return 1; }
+  virtual int vf2() { return 2; }
+};
+
+int f(A* a, int (A::*fp)()) {
+  return (a->*fp)();
+}
+
+// CHECK: define i32 @_Z2g1v()
+int g1() {
+  A a;
+  
+  // CHECK: call i32 @_ZN1A3vf1Ev
+  // CHECK-NEXT: ret i32
+  return f(&a, &A::vf1);
+}
+
+int g2() {
+  A a;
+  
+  // CHECK: call i32 @_ZN1A3vf2Ev
+  // CHECK-NEXT: ret i32
+  return f(&a, &A::vf2);
+}
diff --git a/test/CodeGenCXX/member-function-pointers.cpp b/test/CodeGenCXX/member-function-pointers.cpp
new file mode 100644
index 0000000..f7c445b
--- /dev/null
+++ b/test/CodeGenCXX/member-function-pointers.cpp
@@ -0,0 +1,175 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple=x86_64-apple-darwin9 | FileCheck %s
+
+struct A { int a; void f(); virtual void vf1(); virtual void vf2(); };
+struct B { int b; virtual void g(); };
+struct C : B, A { };
+
+void (A::*pa)();
+void (A::*volatile vpa)();
+void (B::*pb)();
+void (C::*pc)();
+
+// CHECK: @pa2 = global %0 { i64 ptrtoint (void (%struct.A*)* @_ZN1A1fEv to i64), i64 0 }, align 8
+void (A::*pa2)() = &A::f;
+
+// CHECK: @pa3 = global %0 { i64 1, i64 0 }, align 8
+void (A::*pa3)() = &A::vf1;
+
+// CHECK: @pa4 = global %0 { i64 9, i64 0 }, align 8
+void (A::*pa4)() = &A::vf2;
+
+// CHECK: @pc2 = global %0 { i64 ptrtoint (void (%struct.A*)* @_ZN1A1fEv to i64), i64 16 }, align 8
+void (C::*pc2)() = &C::f;
+
+// CHECK: @pc3 = global %0 { i64 1, i64 0 }, align 8
+void (A::*pc3)() = &A::vf1;
+
+void f() {
+  // CHECK: store i64 0, i64* getelementptr inbounds (%0* @pa, i32 0, i32 0)
+  // CHECK: store i64 0, i64* getelementptr inbounds (%0* @pa, i32 0, i32 1)
+  pa = 0;
+
+  // CHECK: volatile store i64 0, i64* getelementptr inbounds (%0* @vpa, i32 0, i32 0)
+  // CHECK: volatile store i64 0, i64* getelementptr inbounds (%0* @vpa, i32 0, i32 1)
+  vpa = 0;
+
+  // CHECK: store i64 {{.*}}, i64* getelementptr inbounds (%0* @pc, i32 0, i32 0)
+  // CHECK: [[ADJ:%[a-zA-Z0-9\.]+]] = add i64 {{.*}}, 16
+  // CHECK: store i64 [[ADJ]], i64* getelementptr inbounds (%0* @pc, i32 0, i32 1)
+  pc = pa;
+
+  // CHECK: store i64 {{.*}}, i64* getelementptr inbounds (%0* @pa, i32 0, i32 0)
+  // CHECK: [[ADJ:%[a-zA-Z0-9\.]+]] = sub i64 {{.*}}, 16
+  // CHECK: store i64 [[ADJ]], i64* getelementptr inbounds (%0* @pa, i32 0, i32 1)
+  pa = static_cast<void (A::*)()>(pc);
+}
+
+void f2() {
+  // CHECK: [[pa2ptr:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa2, i32 0, i32 0 
+  // CHECK: store i64 ptrtoint (void (%struct.A*)* @_ZN1A1fEv to i64), i64* [[pa2ptr]]
+  // CHECK: [[pa2adj:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa2, i32 0, i32 1
+  // CHECK: store i64 0, i64* [[pa2adj]]
+  void (A::*pa2)() = &A::f;
+  
+  // CHECK: [[pa3ptr:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa3, i32 0, i32 0 
+  // CHECK: store i64 1, i64* [[pa3ptr]]
+  // CHECK: [[pa3adj:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa3, i32 0, i32 1
+  // CHECK: store i64 0, i64* [[pa3adj]]
+  void (A::*pa3)() = &A::vf1;
+  
+  // CHECK: [[pa4ptr:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa4, i32 0, i32 0 
+  // CHECK: store i64 9, i64* [[pa4ptr]]
+  // CHECK: [[pa4adj:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa4, i32 0, i32 1
+  // CHECK: store i64 0, i64* [[pa4adj]]
+  void (A::*pa4)() = &A::vf2;
+}
+
+void f3(A *a, A &ar) {
+  (a->*pa)();
+  (ar.*pa)();
+}
+
+bool f4() {
+  return pa;
+}
+
+// PR5177
+namespace PR5177 {
+  struct A {
+   bool foo(int*) const;
+  } a;
+
+  struct B1 {
+   bool (A::*pmf)(int*) const;
+   const A* pa;
+
+   B1() : pmf(&A::foo), pa(&a) {}
+   bool operator()() const { return (pa->*pmf)(new int); }
+  };
+
+  void bar(B1 b2) { while (b2()) ; }
+}
+
+// PR5138
+namespace PR5138 {
+  struct foo {
+      virtual void bar(foo *);
+  };
+
+  extern "C" {
+    void baz(foo *);
+  }
+  
+  void (foo::*ptr1)(void *) = (void (foo::*)(void *))&foo::bar;
+  void (*ptr2)(void *) = (void (*)(void *))&baz;
+
+  void (foo::*ptr3)(void) = (void (foo::*)(void))&foo::bar;
+}
+
+// PR5593
+namespace PR5593 {
+  struct A { };
+  
+  bool f(void (A::*f)()) {
+    return f && f;
+  }
+}
+
+namespace PR5718 {
+  struct A { };
+  
+  bool f(void (A::*f)(), void (A::*g)()) {
+    return f == g;
+  }
+}
+
+namespace BoolMemberPointer {
+  struct A { };
+  
+  bool f(void (A::*f)()) {
+    return !f;
+  }
+
+  bool g(void (A::*f)()) {
+    if (!!f)
+      return true;
+    return false;
+  }
+}
+
+// PR5940
+namespace PR5940 {
+  class foo {
+  public:
+    virtual void baz(void);
+  };
+
+  void foo::baz(void) {
+       void (foo::*ptr)(void) = &foo::baz;
+  }
+}
+
+namespace MemberPointerImpCast {
+  struct A {
+    int x;
+  };
+  struct B : public A {
+  };
+  void f(B* obj, void (A::*method)()) {
+    (obj->*method)();
+  }
+}
+
+// PR6258
+namespace PR6258 {
+
+  struct A {
+    void f(bool);
+  };
+
+  void (A::*pf)(bool) = &A::f;
+
+  void f() {
+    void (A::*pf)(bool) = &A::f;
+  }
+}
diff --git a/test/CodeGenCXX/member-functions.cpp b/test/CodeGenCXX/member-functions.cpp
new file mode 100644
index 0000000..087e62c
--- /dev/null
+++ b/test/CodeGenCXX/member-functions.cpp
@@ -0,0 +1,63 @@
+// RUN: %clang_cc1 -emit-llvm %s -triple x86_64-apple-darwin9 -o %t
+struct C {
+  void f();
+  void g(int, ...);
+};
+
+// RUN: grep "define void @_ZN1C1fEv" %t | count 1
+void C::f() {
+}
+
+void test1() {
+  C c;
+  
+// RUN: grep "call void @_ZN1C1fEv" %t | count 1
+  c.f();
+  
+// RUN: grep "call void (.struct.C\*, i32, ...)\* @_ZN1C1gEiz" %t | count 1
+  c.g(1, 2, 3);
+}
+
+
+struct S {
+  // RUN: grep "define linkonce_odr void @_ZN1SC1Ev" %t
+  inline S() { }
+  // RUN: grep "define linkonce_odr void @_ZN1SC1Ev" %t
+  inline ~S() { }
+  
+  
+  // RUN: grep "define linkonce_odr void @_ZN1S9f_inline1Ev" %t
+  void f_inline1() { }
+  // RUN: grep "define linkonce_odr void @_ZN1S9f_inline2Ev" %t
+  inline void f_inline2() { }
+  
+  // RUN: grep "define linkonce_odr void @_ZN1S1gEv" %t
+  static void g() { }
+  
+  static void f();
+};
+
+// RUN: grep "define void @_ZN1S1fEv" %t
+void S::f() {
+}
+
+void test2() {
+  S s;
+  
+  s.f_inline1();
+  s.f_inline2();
+  
+  S::g();
+  
+}
+
+struct T {
+  T operator+(const T&);
+};
+
+void test3() {
+  T t1, t2;
+  
+  // RUN: grep "call i64 @_ZN1TplERKS_" %t
+  T result = t1 + t2;
+}
diff --git a/test/CodeGenCXX/member-init-struct.cpp b/test/CodeGenCXX/member-init-struct.cpp
new file mode 100644
index 0000000..688d92d
--- /dev/null
+++ b/test/CodeGenCXX/member-init-struct.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 %s -emit-llvm-only -verify
+
+struct A {int a;};
+struct B {float a;};
+struct C {
+  union {
+    A a;
+    B b[10];
+  };
+  _Complex float c;
+  int d[10];
+  void (C::*e)();
+  C() : a(), c(), d(), e() {}
+  C(A x) : a(x) {}
+  C(void (C::*x)(), int y) : b(), c(y), e(x) {}
+};
+A x;
+C a, b(x), c(0, 2);
diff --git a/test/CodeGenCXX/member-init-union.cpp b/test/CodeGenCXX/member-init-union.cpp
new file mode 100644
index 0000000..2c50e18
--- /dev/null
+++ b/test/CodeGenCXX/member-init-union.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 %s -emit-llvm-only -verify
+
+union x {
+  int a;
+  float b;
+  x(float y) : b(y) {}
+  x(int y) : a(y) {}
+};
+x a(1), b(1.0f);
+
diff --git a/test/CodeGenCXX/member-initializers.cpp b/test/CodeGenCXX/member-initializers.cpp
new file mode 100644
index 0000000..81dcee7
--- /dev/null
+++ b/test/CodeGenCXX/member-initializers.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin10 -O3 | FileCheck %s
+
+struct A {
+  virtual int f() { return 1; }
+};
+
+struct B : A {
+  B() : i(f()) { }
+  
+  virtual int f() { return 2; }
+  
+  int i;
+};
+
+// CHECK: define i32 @_Z1fv() nounwind
+int f() {
+  B b;
+  
+  // CHECK: call i32 @_ZN1B1fEv
+  return b.i;
+}
+
+// Test that we don't try to fold the default value of j when initializing i.
+// CHECK: define i32 @_Z9test_foldv() nounwind
+int test_fold() {
+  struct A {
+    A(const int j = 1) : i(j) { } 
+    int i;
+  };
+
+  // CHECK: ret i32 2
+  return A(2).i;
+}
+
diff --git a/test/CodeGenCXX/member-pointer-type-convert.cpp b/test/CodeGenCXX/member-pointer-type-convert.cpp
new file mode 100644
index 0000000..16c1469
--- /dev/null
+++ b/test/CodeGenCXX/member-pointer-type-convert.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s
+
+struct A;
+typedef int A::*param_t;
+struct {
+  const char *name;
+  param_t par;
+} *ptr;
+
+// CHECK: type { i8*, {{i..}} }
diff --git a/test/CodeGenCXX/member-templates.cpp b/test/CodeGenCXX/member-templates.cpp
new file mode 100644
index 0000000..bcf1187
--- /dev/null
+++ b/test/CodeGenCXX/member-templates.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+
+// CHECK: ; ModuleID
+struct A {
+  template<typename T>
+  A(T);
+};
+
+template<typename T> A::A(T) {}
+
+struct B {
+  template<typename T>
+  B(T);
+};
+
+template<typename T> B::B(T) {}
+
+// CHECK: define weak_odr void @_ZN1BC1IiEET_(%struct.B* %this, i32)
+// CHECK: define weak_odr void @_ZN1BC2IiEET_(%struct.B* %this, i32)
+template B::B(int);
+
+template<typename T>
+struct C {
+  void f() {
+    int a[] = { 1, 2, 3 };
+  }
+};
+
+void f(C<int>& c) {
+  c.f();
+}
diff --git a/test/CodeGenCXX/multi-dim-operator-new.cpp b/test/CodeGenCXX/multi-dim-operator-new.cpp
new file mode 100644
index 0000000..7a235e8
--- /dev/null
+++ b/test/CodeGenCXX/multi-dim-operator-new.cpp
@@ -0,0 +1,49 @@
+// RUN: %clang_cc1 %s -triple x86_64-unknown-unknown -emit-llvm -o - | FileCheck %s
+// PR6641
+
+extern "C" int printf(const char *, ...);
+
+struct Foo {
+ Foo() : iFoo (2) {
+  printf("%p\n", this);
+ }
+ int iFoo;
+};
+
+
+typedef Foo (*T)[3][4];
+
+T bar() {
+ return new Foo[2][3][4];
+}
+
+T bug(int i) {
+  return new Foo[i][3][4];
+}
+
+void pr(T a) {
+  for (int i = 0; i < 3; i++)
+   for (int j = 0; j < 4; j++)
+     printf("%p\n", a[i][j]);
+}
+
+Foo *test() {
+  return new Foo[5];
+}
+
+int main() {
+ T f =  bar();
+ pr(f);
+ f = bug(3);
+ pr(f);
+
+ Foo * g = test();
+ for (int i = 0; i < 5; i++)
+ printf("%d\n", g[i].iFoo);
+ return 0;
+}
+
+// CHECK: call noalias i8* @_Znam
+// CHECK: call noalias i8* @_Znam
+// CHECK: call noalias i8* @_Znam
+
diff --git a/test/CodeGenCXX/namespace-aliases.cpp b/test/CodeGenCXX/namespace-aliases.cpp
new file mode 100644
index 0000000..8624eb7
--- /dev/null
+++ b/test/CodeGenCXX/namespace-aliases.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -emit-llvm-only %s
+namespace A { }
+namespace B = A;
+
+namespace b {}
+
+void foo() {
+    namespace a = b;
+}
diff --git a/test/CodeGenCXX/nested-base-member-access.cpp b/test/CodeGenCXX/nested-base-member-access.cpp
new file mode 100644
index 0000000..f1c7dd9
--- /dev/null
+++ b/test/CodeGenCXX/nested-base-member-access.cpp
@@ -0,0 +1,52 @@
+// RUN: %clang_cc1 %s -emit-llvm -o %t
+
+extern "C" int printf(...);
+
+struct M {
+  M(int i){ iM = i; }
+  int iM;
+  void MPR() { printf("iM = %d\n", iM); }
+
+};
+
+struct Q {
+  Q(int i){ iQ = i; }
+  int iQ;
+  void QPR() { printf("iQ = %d\n", iQ); }
+};
+
+struct IQ {
+  IQ(int i) { iIQ = i; }
+  void IQPR() { printf("iIQ = %d\n", iIQ); }
+  int iIQ;
+};
+
+struct L : IQ {
+  L(int i) : IQ(i+100) { iL = i; }
+  int iL;
+};
+
+struct P : Q, L  {
+  P(int i) : Q(i+100), L(i+200) { iP = i; }
+  int iP;
+  void PPR() { printf("iP = %d\n", iP); }
+};
+
+
+struct N : M,P {
+  N() : M(100), P(200) {}
+  void PR() {
+    this->MPR(); this->PPR(); this->QPR(); 
+    IQPR();
+    printf("iM = %d\n", iM); 
+    printf("iP = %d\n", iP);
+    printf("iQ = %d\n", iQ);
+    printf("iL = %d\n", iL);
+    printf("iIQ = %d\n", iIQ);
+  }
+};
+
+int main() {
+  N n1;
+  n1.PR();
+}
diff --git a/test/CodeGenCXX/new-operator-phi.cpp b/test/CodeGenCXX/new-operator-phi.cpp
new file mode 100644
index 0000000..49859ac
--- /dev/null
+++ b/test/CodeGenCXX/new-operator-phi.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -emit-llvm-only -verify %s
+// PR5454
+#include <stddef.h>
+
+struct X {static void * operator new(size_t size) throw(); X(int); };
+int a(), b();
+void b(int x)
+{
+  new X(x ? a() : b());
+}
+
diff --git a/test/CodeGenCXX/new-with-default-arg.cpp b/test/CodeGenCXX/new-with-default-arg.cpp
new file mode 100644
index 0000000..248cc9e
--- /dev/null
+++ b/test/CodeGenCXX/new-with-default-arg.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s
+// pr5547
+
+struct A {
+  void* operator new(__typeof(sizeof(int)));
+  A();
+};
+
+A* x() {
+  return new A;
+}
+
+struct B {
+  void* operator new(__typeof(sizeof(int)), int = 1, int = 4);
+  B(float);
+};
+
+B* y() {
+  new (3,4) B(1);
+  return new(1) B(2);
+}
+
+struct C {
+  void* operator new(__typeof(sizeof(int)), int, int = 4);
+  C();
+};
+
+C* z() {
+  new (3,4) C;
+  return new(1) C;
+}
+
+
diff --git a/test/CodeGenCXX/new.cpp b/test/CodeGenCXX/new.cpp
new file mode 100644
index 0000000..ca7c52f
--- /dev/null
+++ b/test/CodeGenCXX/new.cpp
@@ -0,0 +1,98 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown %s -emit-llvm -o - | FileCheck %s
+#include <stddef.h>
+
+void t1() {
+  int* a = new int;
+}
+
+// Placement.
+void* operator new(size_t, void*) throw();
+
+void t2(int* a) {
+  int* b = new (a) int;
+}
+
+struct S {
+  int a;
+};
+
+// POD types.
+void t3() {
+  int *a = new int(10);
+  _Complex int* b = new _Complex int(10i);
+  
+  S s;
+  s.a = 10;
+  S *sp = new S(s);
+}
+
+// Non-POD
+struct T {
+  T();
+  int a;
+};
+
+void t4() {
+  // CHECK: call void @_ZN1TC1Ev
+  T *t = new T;
+}
+
+struct T2 {
+  int a;
+  T2(int, int);
+};
+
+void t5() { 
+  // CHECK: call void @_ZN2T2C1Eii
+  T2 *t2 = new T2(10, 10);
+}
+
+int *t6() {
+  // Null check.
+  return new (0) int(10);
+}
+
+void t7() {
+  new int();
+}
+
+struct U {
+  ~U();
+};
+  
+void t8(int n) {
+  new int[10];
+  new int[n];
+  
+  // Non-POD
+  new T[10];
+  new T[n];
+  
+  // Cookie required
+  new U[10];
+  new U[n];
+}
+
+void t9() {
+  bool b;
+
+  new bool(true);  
+  new (&b) bool(true);
+}
+
+struct A {
+  void* operator new(__typeof(sizeof(int)), int, float, ...);
+  A();
+};
+
+A* t10() {
+   // CHECK: @_ZN1AnwEmifz
+  return new(1, 2, 3.45, 100) A;
+}
+
+struct B { };
+void t11() {
+  // CHECK: call noalias i8* @_Znwm
+  // CHECK: call void @llvm.memset.p0i8.i64(
+  B* b = new B();
+}
diff --git a/test/CodeGenCXX/no-exceptions.cpp b/test/CodeGenCXX/no-exceptions.cpp
new file mode 100644
index 0000000..da672c4
--- /dev/null
+++ b/test/CodeGenCXX/no-exceptions.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+
+void g();
+
+// CHECK: define void @_Z1fv() nounwind
+void f() throw (int) { 
+
+  // CHECK-NOT: invoke void @_Z1gv
+  g();
+  // CHECK: call void @_Z1gv()
+  // CHECK: ret void
+}
diff --git a/test/CodeGenCXX/nullptr.cpp b/test/CodeGenCXX/nullptr.cpp
new file mode 100644
index 0000000..ab63b43
--- /dev/null
+++ b/test/CodeGenCXX/nullptr.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -std=c++0x -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
+
+int* a = nullptr;
+
+void f() {
+  int* a = nullptr;
+}
+
+typedef decltype(nullptr) nullptr_t;
+
+nullptr_t get_nullptr();
+
+struct X { };
+void g() {
+  // CHECK: call i8* @_Z11get_nullptrv()
+  int (X::*pmf)(int) = get_nullptr();
+}
diff --git a/test/CodeGenCXX/operator-new.cpp b/test/CodeGenCXX/operator-new.cpp
new file mode 100644
index 0000000..f718fae
--- /dev/null
+++ b/test/CodeGenCXX/operator-new.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -triple i686-pc-linux-gnu -emit-llvm -o %t-1.ll %s
+// RUN: FileCheck -check-prefix SANE --input-file=%t-1.ll %s
+// RUN: %clang_cc1 -triple i686-pc-linux-gnu -emit-llvm -fno-assume-sane-operator-new -o %t-2.ll %s
+// RUN: FileCheck -check-prefix SANENOT --input-file=%t-2.ll %s
+
+
+class teste {
+  int A;
+public:
+  teste() : A(2) {}
+};
+
+void f1() {
+  // CHECK-SANE: declare noalias i8* @_Znwj(
+  // CHECK-SANENOT: declare i8* @_Znwj(
+  new teste();
+}
diff --git a/test/CodeGenCXX/overload-binop-implicitconvert.cpp b/test/CodeGenCXX/overload-binop-implicitconvert.cpp
new file mode 100644
index 0000000..0eb7a06
--- /dev/null
+++ b/test/CodeGenCXX/overload-binop-implicitconvert.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 %s -emit-llvm-only
+class T
+{};
+
+void print(const char *t);
+
+T& operator<< (T& t,const char* c)
+{
+  print(c);
+  return t;
+}
+
+
+int main()
+{
+  T t;
+  print("foo");
+  t<<"foo";
+  
+  return 0;
+}
+  
diff --git a/test/CodeGenCXX/pointers-to-data-members.cpp b/test/CodeGenCXX/pointers-to-data-members.cpp
new file mode 100644
index 0000000..d96eb03
--- /dev/null
+++ b/test/CodeGenCXX/pointers-to-data-members.cpp
@@ -0,0 +1,87 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple=x86_64-apple-darwin10 | FileCheck %s
+
+struct A { int a; int b; };
+struct B { int b; };
+struct C : B, A { };
+
+// Zero init.
+namespace ZeroInit {
+  // CHECK: @_ZN8ZeroInit1aE = global i64 -1
+  int A::* a;
+  
+  // CHECK: @_ZN8ZeroInit2aaE = global [2 x i64] [i64 -1, i64 -1]
+  int A::* aa[2];
+  
+  // CHECK: @_ZN8ZeroInit3aaaE = global [2 x [2 x i64]] {{\[}}[2 x i64] [i64 -1, i64 -1], [2 x i64] [i64 -1, i64 -1]]
+  int A::* aaa[2][2];
+  
+  // CHECK: @_ZN8ZeroInit1bE = global i64 -1,
+  int A::* b = 0;
+
+  // CHECK: @_ZN8ZeroInit2saE = global %struct.anon { i64 -1 }
+  struct {
+    int A::*a;
+  } sa;
+  
+  // CHECK: @_ZN8ZeroInit3ssaE = 
+  // CHECK: [2 x i64] [i64 -1, i64 -1]
+  struct {
+    int A::*aa[2];
+  } ssa[2];
+  
+  // CHECK: @_ZN8ZeroInit2ssE = global %1 { %struct.anon { i64 -1 } }
+  struct {
+    struct {
+      int A::*pa;
+    } s;
+  } ss;
+}
+
+// PR5674
+namespace PR5674 {
+  // CHECK: @_ZN6PR56742pbE = global i64 4
+  int A::*pb = &A::b;
+}
+
+// Casts.
+namespace Casts {
+
+int A::*pa;
+int C::*pc;
+
+void f() {
+  // CHECK: store i64 -1, i64* @_ZN5Casts2paE
+  pa = 0;
+
+  // CHECK: [[ADJ:%[a-zA-Z0-9\.]+]] = add i64 {{.*}}, 4
+  // CHECK: store i64 [[ADJ]], i64* @_ZN5Casts2pcE
+  pc = pa;
+
+  // CHECK: [[ADJ:%[a-zA-Z0-9\.]+]] = sub i64 {{.*}}, 4
+  // CHECK: store i64 [[ADJ]], i64* @_ZN5Casts2paE
+  pa = static_cast<int A::*>(pc);
+}
+
+}
+
+// Comparisons
+namespace Comparisons {
+  void f() {
+    int A::*a;
+
+    // CHECK: icmp ne i64 {{.*}}, -1
+    if (a) { }
+
+    // CHECK: icmp ne i64 {{.*}}, -1
+    if (a != 0) { }
+    
+    // CHECK: icmp ne i64 -1, {{.*}}
+    if (0 != a) { }
+
+    // CHECK: icmp eq i64 {{.*}}, -1
+    if (a == 0) { }
+
+    // CHECK: icmp eq i64 -1, {{.*}}
+    if (0 == a) { }
+  }
+}
diff --git a/test/CodeGenCXX/predefined-expr-sizeof.cpp b/test/CodeGenCXX/predefined-expr-sizeof.cpp
new file mode 100644
index 0000000..f74cfb3
--- /dev/null
+++ b/test/CodeGenCXX/predefined-expr-sizeof.cpp
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+
+// CHECK: store i32 49, i32* %size
+// CHECK: store i32 52, i32* %size
+template<typename T>
+class TemplateClass {
+public:
+  void templateClassFunction() {
+    int size = sizeof(__PRETTY_FUNCTION__);
+  }
+};
+
+// CHECK: store i32 27, i32* %size
+// CHECK: store i32 30, i32* %size
+template<typename T>
+void functionTemplate(T t) {
+  int size = sizeof(__PRETTY_FUNCTION__);
+}
+
+int main() {
+  TemplateClass<int> t1;
+  t1.templateClassFunction();
+  TemplateClass<double> t2;
+  t2.templateClassFunction();
+
+  functionTemplate<int>(0);
+  functionTemplate(0.0);
+
+  return 0;
+}
diff --git a/test/CodeGenCXX/predefined-expr.cpp b/test/CodeGenCXX/predefined-expr.cpp
new file mode 100644
index 0000000..f5e5ca9
--- /dev/null
+++ b/test/CodeGenCXX/predefined-expr.cpp
@@ -0,0 +1,349 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+
+// CHECK: private constant [15 x i8] c"externFunction\00"
+// CHECK: private constant [26 x i8] c"void NS::externFunction()\00"
+
+// CHECK: private constant [22 x i8] c"classTemplateFunction\00"
+// CHECK: private constant [60 x i8] c"void NS::ClassTemplate<NS::Base *>::classTemplateFunction()\00"
+// CHECK: private constant [53 x i8] c"void NS::ClassTemplate<int>::classTemplateFunction()\00"
+
+// CHECK: private constant [18 x i8] c"functionTemplate1\00"
+// CHECK: private constant [45 x i8] c"void NS::Base::functionTemplate1(NS::Base *)\00"
+// CHECK: private constant [38 x i8] c"void NS::Base::functionTemplate1(int)\00"
+
+// CHECK: private constant [23 x i8] c"anonymousUnionFunction\00"
+// CHECK: private constant [83 x i8] c"void NS::ContainerForAnonymousRecords::<anonymous union>::anonymousUnionFunction()\00"
+
+// CHECK: private constant [24 x i8] c"anonymousStructFunction\00"
+// CHECK: private constant [85 x i8] c"void NS::ContainerForAnonymousRecords::<anonymous struct>::anonymousStructFunction()\00"
+
+// CHECK: private constant [23 x i8] c"anonymousClassFunction\00"
+// CHECK: private constant [83 x i8] c"void NS::ContainerForAnonymousRecords::<anonymous class>::anonymousClassFunction()\00"
+
+// CHECK: private constant [12 x i8] c"~Destructor\00"
+// CHECK: private constant [30 x i8] c"NS::Destructor::~Destructor()\00"
+
+// CHECK: private constant [12 x i8] c"Constructor\00"
+// CHECK: private constant [41 x i8] c"NS::Constructor::Constructor(NS::Base *)\00"
+// CHECK: private constant [34 x i8] c"NS::Constructor::Constructor(int)\00"
+// CHECK: private constant [31 x i8] c"NS::Constructor::Constructor()\00"
+
+// CHECK: private constant [16 x i8] c"virtualFunction\00"
+// CHECK: private constant [44 x i8] c"virtual void NS::Derived::virtualFunction()\00"
+
+// CHECK: private constant [22 x i8] c"constVolatileFunction\00"
+// CHECK: private constant [54 x i8] c"void NS::Base::constVolatileFunction() const volatile\00"
+
+// CHECK: private constant [17 x i8] c"volatileFunction\00"
+// CHECK: private constant [43 x i8] c"void NS::Base::volatileFunction() volatile\00"
+
+// CHECK: private constant [14 x i8] c"constFunction\00"
+// CHECK: private constant [37 x i8] c"void NS::Base::constFunction() const\00"
+
+// CHECK: private constant [26 x i8] c"functionReturingTemplate2\00"
+// CHECK: private constant [64 x i8] c"ClassTemplate<NS::Base *> NS::Base::functionReturingTemplate2()\00"
+
+// CHECK: private constant [26 x i8] c"functionReturingTemplate1\00"
+// CHECK: private constant [57 x i8] c"ClassTemplate<int> NS::Base::functionReturingTemplate1()\00"
+
+// CHECK: private constant [23 x i8] c"withTemplateParameter2\00"
+// CHECK: private constant [65 x i8] c"void NS::Base::withTemplateParameter2(ClassTemplate<NS::Base *>)\00"
+
+// CHECK: private constant [23 x i8] c"withTemplateParameter1\00"
+// CHECK: private constant [58 x i8] c"void NS::Base::withTemplateParameter1(ClassTemplate<int>)\00"
+
+// CHECK: private constant [23 x i8] c"functionReturningClass\00"
+// CHECK: private constant [45 x i8] c"NS::Base *NS::Base::functionReturningClass()\00"
+
+// CHECK: private constant [23 x i8] c"functionWithParameters\00"
+// CHECK: private constant [64 x i8] c"void NS::Base::functionWithParameters(int, float *, NS::Base *)\00"
+
+// CHECK: private constant [17 x i8] c"variadicFunction\00"
+// CHECK: private constant [42 x i8] c"void NS::Base::variadicFunction(int, ...)\00"
+
+// CHECK: private constant [41 x i8] c"virtual void NS::Base::virtualFunction()\00"
+
+// CHECK: private constant [15 x i8] c"inlineFunction\00"
+// CHECK: private constant [32 x i8] c"void NS::Base::inlineFunction()\00"
+
+// CHECK: private constant [15 x i8] c"staticFunction\00"
+// CHECK: private constant [39 x i8] c"static void NS::Base::staticFunction()\00"
+
+// CHECK: private constant [26 x i8] c"topLevelNamespaceFunction\00"
+// CHECK: private constant [59 x i8] c"void ClassInTopLevelNamespace::topLevelNamespaceFunction()\00"
+
+// CHECK: private constant [27 x i8] c"anonymousNamespaceFunction\00"
+// CHECK: private constant [84 x i8] c"void <anonymous namespace>::ClassInAnonymousNamespace::anonymousNamespaceFunction()\00"
+
+// CHECK: private constant [19 x i8] c"localClassFunction\00"
+// CHECK: private constant [59 x i8] c"void NS::localClass(int)::LocalClass::localClassFunction()\00"
+
+int printf(const char * _Format, ...);
+
+class ClassInTopLevelNamespace {
+public:
+  void topLevelNamespaceFunction() {
+    printf("__func__ %s\n", __func__);
+    printf("__FUNCTION__ %s\n", __FUNCTION__);
+    printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+  }
+};
+
+namespace {
+
+  class ClassInAnonymousNamespace {
+  public:
+    void anonymousNamespaceFunction() {
+      printf("__func__ %s\n", __func__);
+      printf("__FUNCTION__ %s\n", __FUNCTION__);
+      printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+    }
+  };
+
+} // end anonymous namespace
+
+namespace NS {
+
+template<typename T>
+class ClassTemplate {
+public:
+  void classTemplateFunction() {
+    printf("__func__ %s\n", __func__);
+    printf("__FUNCTION__ %s\n", __FUNCTION__);
+    printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+  }
+};
+
+class Base {
+public:
+  static void staticFunction() {
+    printf("__func__ %s\n", __func__);
+    printf("__FUNCTION__ %s\n", __FUNCTION__);
+    printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+  }
+
+  inline void inlineFunction() {
+    printf("__func__ %s\n", __func__);
+    printf("__FUNCTION__ %s\n", __FUNCTION__);
+    printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+  }
+
+  virtual void virtualFunction() {
+    printf("__func__ %s\n", __func__);
+    printf("__FUNCTION__ %s\n", __FUNCTION__);
+    printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+  }
+
+  void functionWithParameters(int, float*, Base* base) {
+    printf("__func__ %s\n", __func__);
+    printf("__FUNCTION__ %s\n", __FUNCTION__);
+    printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+  }
+
+  Base *functionReturningClass() {
+    printf("__func__ %s\n", __func__);
+    printf("__FUNCTION__ %s\n", __FUNCTION__);
+    printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+    return 0;
+  }
+
+  void variadicFunction(int, ...) {
+    printf("__func__ %s\n", __func__);
+    printf("__FUNCTION__ %s\n", __FUNCTION__);
+    printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+  }
+
+  void withTemplateParameter1(ClassTemplate<int>) {
+    printf("__func__ %s\n", __func__);
+    printf("__FUNCTION__ %s\n", __FUNCTION__);
+    printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+  }
+
+  void withTemplateParameter2(ClassTemplate<Base *>) {
+    printf("__func__ %s\n", __func__);
+    printf("__FUNCTION__ %s\n", __FUNCTION__);
+    printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+  }
+
+  ClassTemplate<int> functionReturingTemplate1() {
+    printf("__func__ %s\n", __func__);
+    printf("__FUNCTION__ %s\n", __FUNCTION__);
+    printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+    return ClassTemplate<int>();
+  }
+
+  ClassTemplate<Base *> functionReturingTemplate2() {
+    printf("__func__ %s\n", __func__);
+    printf("__FUNCTION__ %s\n", __FUNCTION__);
+    printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+    return ClassTemplate<Base *>();
+  }
+
+  template<typename T>
+  void functionTemplate1(T t) {
+    printf("__func__ %s\n", __func__);
+    printf("__FUNCTION__ %s\n", __FUNCTION__);
+    printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+  }
+
+  void constFunction() const {
+    printf("__func__ %s\n", __func__);
+    printf("__FUNCTION__ %s\n", __FUNCTION__);
+    printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+  }
+
+  void volatileFunction() volatile {
+    printf("__func__ %s\n", __func__);
+    printf("__FUNCTION__ %s\n", __FUNCTION__);
+    printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+  }
+  
+  void constVolatileFunction() const volatile {
+    printf("__func__ %s\n", __func__);
+    printf("__FUNCTION__ %s\n", __FUNCTION__);
+    printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+  }
+};
+
+class Derived : public Base {
+public:
+  // Virtual function without being explicitally written.
+  void virtualFunction() {
+    printf("__func__ %s\n", __func__);
+    printf("__FUNCTION__ %s\n", __FUNCTION__);
+    printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+  }
+};
+
+class Constructor {
+public:
+  Constructor() {
+    printf("__func__ %s\n", __func__);
+    printf("__FUNCTION__ %s\n", __FUNCTION__);
+    printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+  }
+
+  Constructor(int) {
+    printf("__func__ %s\n", __func__);
+    printf("__FUNCTION__ %s\n", __FUNCTION__);
+    printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+  }
+
+  Constructor(Base *) {
+    printf("__func__ %s\n", __func__);
+    printf("__FUNCTION__ %s\n", __FUNCTION__);
+    printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+  }
+};
+
+class Destructor {
+public:
+  ~Destructor() {
+    printf("__func__ %s\n", __func__);
+    printf("__FUNCTION__ %s\n", __FUNCTION__);
+    printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+  }
+};
+
+class ContainerForAnonymousRecords {
+public:
+  class {
+  public:
+    void anonymousClassFunction() {
+      printf("__func__ %s\n", __func__);
+      printf("__FUNCTION__ %s\n", __FUNCTION__);
+      printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+    }
+  } anonymousClass;
+
+  struct {
+    void anonymousStructFunction() {
+      printf("__func__ %s\n", __func__);
+      printf("__FUNCTION__ %s\n", __FUNCTION__);
+      printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+    }
+  } anonymousStruct;
+
+  union {
+    void anonymousUnionFunction() {
+      printf("__func__ %s\n", __func__);
+      printf("__FUNCTION__ %s\n", __FUNCTION__);
+      printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+    }
+  } anonymousUnion;
+};
+
+void localClass(int) {
+  class LocalClass {
+  public:
+    void localClassFunction() {
+      printf("__func__ %s\n", __func__);
+      printf("__FUNCTION__ %s\n", __FUNCTION__);
+      printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+    }
+  };
+  LocalClass lc;
+  lc.localClassFunction();
+}
+
+extern void externFunction() {
+  printf("__func__ %s\n", __func__);
+  printf("__FUNCTION__ %s\n", __FUNCTION__);
+  printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+}
+
+} // end NS namespace
+
+int main() {
+  ClassInAnonymousNamespace anonymousNamespace;
+  anonymousNamespace.anonymousNamespaceFunction();
+
+  ClassInTopLevelNamespace topLevelNamespace;
+  topLevelNamespace.topLevelNamespaceFunction();
+
+  NS::Base::staticFunction();
+  
+  NS::Base b;
+  b.inlineFunction();
+  b.virtualFunction();
+  b.variadicFunction(0);
+  b.functionWithParameters(0, 0, 0);
+  b.functionReturningClass();
+  
+  b.withTemplateParameter1(NS::ClassTemplate<int>());
+  b.withTemplateParameter2(NS::ClassTemplate<NS::Base *>());
+  b.functionReturingTemplate1();
+  b.functionReturingTemplate2();
+  b.functionTemplate1<int>(0);
+  b.functionTemplate1<NS::Base *>(0);
+  b.constFunction();
+  b.volatileFunction();
+  b.constVolatileFunction();
+
+  NS::Derived d;
+  d.virtualFunction();
+  
+  NS::ClassTemplate<int> t1;
+  t1.classTemplateFunction();
+  NS::ClassTemplate<NS::Base *> t2;
+  t2.classTemplateFunction();
+  
+  NS::Constructor c1;
+  NS::Constructor c2(0);
+  NS::Constructor c3((NS::Base *)0);
+  
+  {
+    NS::Destructor destructor;
+  }
+
+  NS::ContainerForAnonymousRecords anonymous; 
+  anonymous.anonymousClass.anonymousClassFunction();
+  anonymous.anonymousStruct.anonymousStructFunction();
+  anonymous.anonymousUnion.anonymousUnionFunction();
+
+  NS::localClass(0);
+
+  NS::externFunction();
+
+  return 0;
+}
diff --git a/test/CodeGenCXX/ptr-to-datamember.cpp b/test/CodeGenCXX/ptr-to-datamember.cpp
new file mode 100644
index 0000000..a6f523e
--- /dev/null
+++ b/test/CodeGenCXX/ptr-to-datamember.cpp
@@ -0,0 +1,99 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s
+
+extern "C" int printf(...);
+
+struct F {
+  F() : iF(1), fF(2.0) {}
+  int iF;
+  float fF;
+};
+
+struct V {
+  double d;
+  int iV;
+};
+
+struct B  : virtual V{
+  double d;
+  int iB;
+};
+
+struct B1  : virtual V{
+  double d;
+  int iB1;
+};
+
+class A  : public B, public B1 {
+public:
+  A() : f(1.0), d(2.0), Ai(3) {}
+  float f;
+  double d;
+  int Ai;
+  F Af;
+}; 
+
+template <typename T> struct TT {
+  int T::t::*pti;
+};
+
+struct I {
+  typedef I t;
+  int x;
+};
+
+void pr(const F& b) {
+  printf(" %d %f\n", b.iF, b.fF);
+}
+
+void test_aggr_pdata(A& a1) {
+  F A::* af = &A::Af;
+  pr(a1.*af);
+
+  (a1.*af).iF = 100;
+  (a1.*af).fF = 200.00;
+  printf(" %d %f\n", (a1.*af).iF, (a1.*af).fF);
+  pr(a1.*af);
+
+  (a1.*af).iF++;
+  (a1.*af).fF--;
+  --(a1.*af).fF;
+  pr(a1.*af);
+}
+
+void test_aggr_pdata_1(A* pa) {
+  F A::* af = &A::Af;
+  pr(pa->*af);
+
+  (pa->*af).iF = 100;
+  (pa->*af).fF = 200.00;
+  printf(" %d %f\n", (pa->*af).iF, (pa->*af).fF);
+  pr(pa->*af);
+
+  (pa->*af).iF++;
+  (pa->*af).fF--;
+  --(pa->*af).fF;
+  pr(pa->*af);
+}
+
+int main() 
+{
+  A a1;
+  TT<I> tt;
+  I i;
+  int A::* pa = &A::Ai;
+  float A::* pf = &A::f;
+  double A::* pd = &A::d;
+  tt.pti = &I::x;
+  printf("%d %d %d\n", &A::Ai, &A::f, &A::d);
+  printf("%d\n", &A::B::iB);
+  printf("%d\n", &A::B1::iB1);
+  printf("%d\n", &A::f);
+  printf("%d\n", &A::B::iV);
+  printf("%d\n", &A::B1::iV);
+  printf("%d\n", &A::B::V::iV);
+  printf("%d\n", &A::B1::V::iV);
+  printf("%d, %f, %f  \n", a1.*pa, a1.*pf, a1.*pd);
+  printf("%d\n", i.*tt.pti);
+  test_aggr_pdata(a1);
+  test_aggr_pdata_1(&a1);
+}
diff --git a/test/CodeGenCXX/ptr-to-member-function.cpp b/test/CodeGenCXX/ptr-to-member-function.cpp
new file mode 100644
index 0000000..e3912fe
--- /dev/null
+++ b/test/CodeGenCXX/ptr-to-member-function.cpp
@@ -0,0 +1,70 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++0x -S %s -o %t-64.s
+// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s
+// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++0x -S %s -o %t-32.s
+// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s
+// 13.3.3.2 Ranking implicit conversion sequences
+
+extern "C" int printf(...);
+
+struct A {
+int Ai;
+bool foo(int* arg) const;
+}; 
+
+bool A::foo(int* arg) const {
+    printf("A::foo(%d)\n", *arg);
+    return true;
+}
+
+struct B : public A {
+  void bf() { printf("B::bf called\n"); }
+}; 
+
+struct C : public B { }; 
+
+// conversion of B::* to C::* is better than conversion of A::* to C::*
+typedef void (A::*pmfa)();
+typedef void (B::*pmfb)();
+typedef void (C::*pmfc)();
+
+struct X {
+	operator pmfa();
+	operator pmfb() {
+	  return &B::bf;
+        }
+};
+
+
+void g(pmfc pm) {
+  C c;
+  (c.*pm)();
+}
+
+void test2(X x) 
+{
+    g(x);
+}
+
+struct B1 {
+  bool (A::*pmf)(int*) const;
+
+  B1(int i) : pmf(&A::foo), im(i) {
+    ((A*)this->*pmf)(&im);
+  }
+
+  int im;
+};
+
+int main()
+{
+	X x;
+	test2(x);
+        B1 b = B1(1);
+  	B1 c = B1(2);
+}
+
+// CHECK-LP64: callq	__ZN1XcvM1BFvvEEv
+// CHECK-LP64: callq	__Z1gM1CFvvE
+
+// CHECK-LP32: call	L__ZN1XcvM1BFvvEEv
+// CHECK-LP32: call	__Z1gM1CFvvE
diff --git a/test/CodeGenCXX/reference-bind-default-argument.cpp b/test/CodeGenCXX/reference-bind-default-argument.cpp
new file mode 100644
index 0000000..acce962
--- /dev/null
+++ b/test/CodeGenCXX/reference-bind-default-argument.cpp
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 %s -emit-llvm-only -verify
+
+struct A {};
+struct B : A {};
+void a(const A& x = B());
+void b() { a(); }
diff --git a/test/CodeGenCXX/reference-field.cpp b/test/CodeGenCXX/reference-field.cpp
new file mode 100644
index 0000000..0312029
--- /dev/null
+++ b/test/CodeGenCXX/reference-field.cpp
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s -O2 | grep "@_Z1bv"
+
+// Make sure the call to b() doesn't get optimized out.
+extern struct x {char& x,y;}y;
+int b();      
+int a() { if (!&y.x) b(); }
diff --git a/test/CodeGenCXX/reference-in-blocks.cpp b/test/CodeGenCXX/reference-in-blocks.cpp
new file mode 100644
index 0000000..c020bab
--- /dev/null
+++ b/test/CodeGenCXX/reference-in-blocks.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -fblocks %s -emit-llvm -o %t
+
+extern "C" int printf(const char*, ...);
+
+template<typename T> class range {
+public:
+T _i;
+        range(T i) {_i = i;};
+        T get() {return _i;};
+};
+
+int main() {
+
+        // works
+        void (^bl)(range<int> ) = ^(range<int> i){printf("Hello Blocks %d\n", i.get()); };
+
+        //crashes in godegen?
+        void (^bl2)(range<int>& ) = ^(range<int>& i){printf("Hello Blocks %d\n", i.get()); };
+        return 0;
+}
+
diff --git a/test/CodeGenCXX/reference-init.cpp b/test/CodeGenCXX/reference-init.cpp
new file mode 100644
index 0000000..9469c84
--- /dev/null
+++ b/test/CodeGenCXX/reference-init.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -emit-llvm-only -verify %s
+
+struct XPTParamDescriptor {};
+struct nsXPTParamInfo {
+  nsXPTParamInfo(const XPTParamDescriptor& desc);
+};
+void a(XPTParamDescriptor *params) {
+  const nsXPTParamInfo& paramInfo = params[0];
+}
+
+// CodeGen of reference initialized const arrays.
+namespace PR5911 {
+  template <typename T, int N> int f(const T (&a)[N]) { return N; }
+  int iarr[] = { 1 };
+  int test() { return f(iarr); }
+}
+
+// radar 7574896
+struct Foo { int foo; };
+Foo& ignoreSetMutex = *(new Foo);
+
+// Binding to a bit-field that requires a temporary. 
+struct { int bitfield : 3; } s = { 3 };
+const int &s2 = s.bitfield;
diff --git a/test/CodeGenCXX/references.cpp b/test/CodeGenCXX/references.cpp
new file mode 100644
index 0000000..5a5947d
--- /dev/null
+++ b/test/CodeGenCXX/references.cpp
@@ -0,0 +1,157 @@
+// RUN: %clang_cc1 -verify -emit-llvm -o - %s | FileCheck %s
+void t1() {
+  extern int& a;
+  int b = a; 
+}
+
+void t2(int& a) {
+  int b = a;
+}
+
+int g;
+int& gr = g;
+int& grr = gr;
+void t3() {
+  int b = gr;
+}
+
+// Test reference binding.
+
+struct C { int a; };
+void f(const bool&);
+void f(const int&);
+void f(const _Complex int&);
+void f(const C&);
+
+C aggregate_return();
+
+bool& bool_reference_return();
+int& int_reference_return();
+_Complex int& complex_int_reference_return();
+C& aggregate_reference_return();
+
+void test_bool() {
+  bool a = true;
+  f(a);
+
+  f(true);
+  
+  bool_reference_return() = true;
+  a = bool_reference_return();
+  
+  struct { const bool& b; } b = { true };
+}
+
+void test_scalar() {
+  int a = 10;
+  f(a);
+  
+  struct { int bitfield : 3; } s = { 3 };
+  f(s.bitfield);
+  
+  f(10);
+
+  __attribute((vector_size(16))) typedef int vec4;
+  f((vec4){1,2,3,4}[0]);
+  
+  int_reference_return() = 10;
+  a = int_reference_return();
+  
+  struct { const int& a; } agg = { 10 };
+}
+
+void test_complex() {
+  _Complex int a = 10i;
+  f(a);
+  
+  f(10i);
+  
+  complex_int_reference_return() = 10i;
+  a = complex_int_reference_return();
+  
+  struct { const _Complex int &a; } agg = { 10i };
+}
+
+void test_aggregate() {
+  C c;
+  f(c);
+
+  f(aggregate_return());
+  aggregate_reference_return().a = 10;
+
+  c = aggregate_reference_return();
+  
+  struct { const C& a; } agg = { C() };
+}
+
+int& reference_return() {
+  return g;
+}
+
+int reference_decl() {
+  int& a = g;
+  const int& b = 1;
+  return a+b;
+}
+
+struct A {
+  int& b();
+};
+
+void f(A* a) {
+  int b = a->b();
+}
+
+// PR5122
+void *foo = 0;
+void * const & kFoo = foo;
+
+struct D : C { D(); ~D(); };
+
+void h() {
+  // CHECK: call void @_ZN1DD1Ev
+  const C& c = D();
+}
+
+namespace T {
+  struct A {
+    A();
+    ~A();
+  };
+
+  struct B {
+    B();
+    ~B();
+    A f();
+  };
+
+  void f() {
+    // CHECK: call void @_ZN1T1BC1Ev
+    // CHECK: call void @_ZN1T1B1fEv
+    // CHECK: call void @_ZN1T1BD1Ev
+    const A& a = B().f();
+    // CHECK: call void @_ZN1T1fEv
+    f();
+    // CHECK: call void @_ZN1T1AD1Ev
+  }
+}
+
+// PR5227.
+namespace PR5227 {
+void f(int &a) {
+  (a = 10) = 20;
+}
+}
+
+// PR5590
+struct s0;
+struct s1 { struct s0 &s0; };
+void f0(s1 a) { s1 b = a; }
+
+// PR6024
+// CHECK: @_Z2f2v()
+// CHECK: alloca
+// CHECK: store
+// CHECK: load
+// CHECK: ret
+const int &f2() { return 0; }
diff --git a/test/CodeGenCXX/reinterpret-cast.cpp b/test/CodeGenCXX/reinterpret-cast.cpp
new file mode 100644
index 0000000..ff56792
--- /dev/null
+++ b/test/CodeGenCXX/reinterpret-cast.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s -std=c++0x
+void *f1(unsigned long l) {
+  return reinterpret_cast<void *>(l);
+}
+
+unsigned long f2() {
+  return reinterpret_cast<unsigned long>(nullptr);
+}
+
+unsigned long f3(void *p) {
+  return reinterpret_cast<unsigned long>(p);
+}
+
+void f4(int*&);
+void f5(void*& u) {
+  f4(reinterpret_cast<int*&>(u));
+}
diff --git a/test/CodeGenCXX/rtti-fundamental.cpp b/test/CodeGenCXX/rtti-fundamental.cpp
new file mode 100644
index 0000000..6826321
--- /dev/null
+++ b/test/CodeGenCXX/rtti-fundamental.cpp
@@ -0,0 +1,73 @@
+// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+
+#include <typeinfo>
+
+std::type_info foo() {
+  return typeid(void);
+}
+
+namespace __cxxabiv1 {
+  struct __fundamental_type_info {
+    virtual ~__fundamental_type_info();
+  };
+
+  __fundamental_type_info::~__fundamental_type_info() { }
+}
+
+// CHECK: @_ZTIv = weak_odr constant
+// CHECK: @_ZTIPv = weak_odr constant
+// CHECK: @_ZTIPKv = weak_odr constant
+// CHECK: @_ZTIDi = weak_odr constant
+// CHECK: @_ZTIPDi = weak_odr constant
+// CHECK: @_ZTIPKDi = weak_odr constant
+// CHECK: @_ZTIDs = weak_odr constant
+// CHECK: @_ZTIPDs = weak_odr constant
+// CHECK: @_ZTIPKDs = weak_odr constant
+// CHECK: @_ZTIy = weak_odr constant
+// CHECK: @_ZTIPy = weak_odr constant
+// CHECK: @_ZTIPKy = weak_odr constant
+// CHECK: @_ZTIx = weak_odr constant
+// CHECK: @_ZTIPx = weak_odr constant
+// CHECK: @_ZTIPKx = weak_odr constant
+// CHECK: @_ZTIw = weak_odr constant
+// CHECK: @_ZTIPw = weak_odr constant
+// CHECK: @_ZTIPKw = weak_odr constant
+// CHECK: @_ZTIt = weak_odr constant
+// CHECK: @_ZTIPt = weak_odr constant
+// CHECK: @_ZTIPKt = weak_odr constant
+// CHECK: @_ZTIs = weak_odr constant
+// CHECK: @_ZTIPs = weak_odr constant
+// CHECK: @_ZTIPKs = weak_odr constant
+// CHECK: @_ZTIm = weak_odr constant
+// CHECK: @_ZTIPm = weak_odr constant
+// CHECK: @_ZTIPKm = weak_odr constant
+// CHECK: @_ZTIl = weak_odr constant
+// CHECK: @_ZTIPl = weak_odr constant
+// CHECK: @_ZTIPKl = weak_odr constant
+// CHECK: @_ZTIj = weak_odr constant
+// CHECK: @_ZTIPj = weak_odr constant
+// CHECK: @_ZTIPKj = weak_odr constant
+// CHECK: @_ZTIi = weak_odr constant
+// CHECK: @_ZTIPi = weak_odr constant
+// CHECK: @_ZTIPKi = weak_odr constant
+// CHECK: @_ZTIh = weak_odr constant
+// CHECK: @_ZTIPh = weak_odr constant
+// CHECK: @_ZTIPKh = weak_odr constant
+// CHECK: @_ZTIf = weak_odr constant
+// CHECK: @_ZTIPf = weak_odr constant
+// CHECK: @_ZTIPKf = weak_odr constant
+// CHECK: @_ZTIe = weak_odr constant
+// CHECK: @_ZTIPe = weak_odr constant
+// CHECK: @_ZTIPKe = weak_odr constant
+// CHECK: @_ZTId = weak_odr constant
+// CHECK: @_ZTIPd = weak_odr constant
+// CHECK: @_ZTIPKd = weak_odr constant
+// CHECK: @_ZTIc = weak_odr constant
+// CHECK: @_ZTIPc = weak_odr constant
+// CHECK: @_ZTIPKc = weak_odr constant
+// CHECK: @_ZTIb = weak_odr constant
+// CHECK: @_ZTIPb = weak_odr constant
+// CHECK: @_ZTIPKb = weak_odr constant
+// CHECK: @_ZTIa = weak_odr constant
+// CHECK: @_ZTIPa = weak_odr constant
+// CHECK: @_ZTIPKa = weak_odr constant
diff --git a/test/CodeGenCXX/rtti-layout.cpp b/test/CodeGenCXX/rtti-layout.cpp
new file mode 100644
index 0000000..1ad87fb
--- /dev/null
+++ b/test/CodeGenCXX/rtti-layout.cpp
@@ -0,0 +1,191 @@
+// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -emit-llvm -O3 -o - | FileCheck %s
+#include <typeinfo>
+
+// vtables.
+extern "C" {
+  const void *_ZTVN10__cxxabiv123__fundamental_type_infoE;
+  const void *_ZTVN10__cxxabiv117__class_type_infoE;
+  const void *_ZTVN10__cxxabiv120__si_class_type_infoE;
+  const void *_ZTVN10__cxxabiv121__vmi_class_type_infoE;
+  const void *_ZTVN10__cxxabiv119__pointer_type_infoE;
+  const void *_ZTVN10__cxxabiv129__pointer_to_member_type_infoE;
+};
+#define fundamental_type_info_vtable _ZTVN10__cxxabiv123__fundamental_type_infoE
+#define class_type_info_vtable _ZTVN10__cxxabiv117__class_type_infoE
+#define si_class_type_info_vtable _ZTVN10__cxxabiv120__si_class_type_infoE
+#define vmi_class_type_info_vtable _ZTVN10__cxxabiv121__vmi_class_type_infoE
+#define pointer_type_info_vtable _ZTVN10__cxxabiv119__pointer_type_infoE
+#define pointer_to_member_type_info_vtable _ZTVN10__cxxabiv129__pointer_to_member_type_infoE
+
+class __pbase_type_info : public std::type_info {
+public:
+  unsigned int __flags;
+  const std::type_info *__pointee;
+
+  enum __masks {
+    __const_mask = 0x1,
+    __volatile_mask = 0x2,
+    __restrict_mask = 0x4,
+    __incomplete_mask = 0x8,
+    __incomplete_class_mask = 0x10
+  };
+};
+
+class __class_type_info : public std::type_info { };
+
+class __si_class_type_info : public __class_type_info {
+public:
+  const __class_type_info *__base_type;
+};
+
+struct __base_class_type_info {
+public:
+ const __class_type_info *__base_type;
+ long __offset_flags;
+
+ enum __offset_flags_masks {
+   __virtual_mask = 0x1,
+   __public_mask = 0x2,
+   __offset_shift = 8
+ };
+};
+
+class __vmi_class_type_info : public __class_type_info {
+public:
+  unsigned int __flags;
+  unsigned int __base_count;
+  __base_class_type_info __base_info[1];
+
+  enum __flags_masks {
+    __non_diamond_repeat_mask = 0x1,
+    __diamond_shaped_mask = 0x2
+  };
+};
+
+template<typename T> const T& to(const std::type_info &info) {
+return static_cast<const T&>(info);
+}
+struct Incomplete;
+
+struct A { int a; };
+struct Empty { };
+
+struct SI1 : A { };
+struct SI2 : Empty { };
+struct SI3 : Empty { virtual void f() { } };
+
+struct VMI1 : private A { };
+struct VMI2 : virtual A { };
+struct VMI3 : A { virtual void f() { } };
+struct VMI4 : A, Empty { };
+
+struct VMIBase1 { int a; };
+struct VMIBase2 : VMIBase1 { int a; };
+struct VMI5 : VMIBase1, VMIBase2 { int a; };
+
+struct VMIBase3 : virtual VMIBase1 { int a; };
+struct VMI6 : virtual VMIBase1, VMIBase3 { int a; };
+
+struct VMI7 : VMIBase1, VMI5, private VMI6 { };
+
+#define CHECK(x) if (!(x)) return __LINE__
+#define CHECK_VTABLE(type, vtable) CHECK(&vtable##_type_info_vtable + 2 == (((void **)&(typeid(type)))[0]))
+#define CHECK_BASE_INFO_TYPE(type, index, base) CHECK(to<__vmi_class_type_info>(typeid(type)).__base_info[(index)].__base_type == &typeid(base))
+#define CHECK_BASE_INFO_OFFSET_FLAGS(type, index, offset, flags) CHECK(to<__vmi_class_type_info>(typeid(type)).__base_info[(index)].__offset_flags == (((offset) << 8) | (flags)))
+
+// CHECK: define i32 @_Z1fv()
+int f() {
+  // Vectors should be treated as fundamental types.
+  typedef short __v4hi __attribute__ ((__vector_size__ (8)));
+  CHECK_VTABLE(__v4hi, fundamental);
+
+  // A does not have any bases.
+  CHECK_VTABLE(A, class);
+  
+  // SI1 has a single public base.
+  CHECK_VTABLE(SI1, si_class);
+  CHECK(to<__si_class_type_info>(typeid(SI1)).__base_type == &typeid(A));
+  
+  // SI2 has a single public empty base.
+  CHECK_VTABLE(SI2, si_class);
+  CHECK(to<__si_class_type_info>(typeid(SI2)).__base_type == &typeid(Empty));
+
+  // SI3 has a single public empty base. SI3 is dynamic whereas Empty is not, but since Empty is
+  // an empty class, it will still be at offset zero.
+  CHECK_VTABLE(SI3, si_class);
+  CHECK(to<__si_class_type_info>(typeid(SI3)).__base_type == &typeid(Empty));
+
+  // VMI1 has a single base, but it is private.
+  CHECK_VTABLE(VMI1, vmi_class);
+
+  // VMI2 has a single base, but it is virtual.
+  CHECK_VTABLE(VMI2, vmi_class);
+
+  // VMI3 has a single base, but VMI3 is dynamic whereas A is not, and A is not empty.
+  CHECK_VTABLE(VMI3, vmi_class);
+
+  // VMI4 has two bases.
+  CHECK_VTABLE(VMI4, vmi_class);
+
+  // VMI5 has non-diamond shaped inheritance.
+  CHECK_VTABLE(VMI5, vmi_class);
+  CHECK(to<__vmi_class_type_info>(typeid(VMI5)).__flags == __vmi_class_type_info::__non_diamond_repeat_mask);
+  CHECK(to<__vmi_class_type_info>(typeid(VMI5)).__base_count == 2);
+  CHECK_BASE_INFO_TYPE(VMI5, 0, VMIBase1);
+  CHECK_BASE_INFO_OFFSET_FLAGS(VMI5, 0, 0, __base_class_type_info::__public_mask);
+  CHECK_BASE_INFO_TYPE(VMI5, 1, VMIBase2);
+  CHECK_BASE_INFO_OFFSET_FLAGS(VMI5, 1, 4, __base_class_type_info::__public_mask);
+  
+  // VMI6 has diamond shaped inheritance.
+  CHECK_VTABLE(VMI6, vmi_class);
+  CHECK(to<__vmi_class_type_info>(typeid(VMI6)).__flags == __vmi_class_type_info::__diamond_shaped_mask);
+  CHECK(to<__vmi_class_type_info>(typeid(VMI6)).__base_count == 2);
+  CHECK_BASE_INFO_TYPE(VMI6, 0, VMIBase1);
+  CHECK_BASE_INFO_OFFSET_FLAGS(VMI6, 0, -24, __base_class_type_info::__public_mask | __base_class_type_info::__virtual_mask);
+  CHECK_BASE_INFO_TYPE(VMI6, 1, VMIBase3);
+  CHECK_BASE_INFO_OFFSET_FLAGS(VMI6, 1, 0, __base_class_type_info::__public_mask);
+  
+  // VMI7 has both non-diamond and diamond shaped inheritance.
+  CHECK_VTABLE(VMI7, vmi_class);
+  CHECK(to<__vmi_class_type_info>(typeid(VMI7)).__flags == (__vmi_class_type_info::__non_diamond_repeat_mask | __vmi_class_type_info::__diamond_shaped_mask));
+  CHECK(to<__vmi_class_type_info>(typeid(VMI7)).__base_count == 3);
+  CHECK_BASE_INFO_TYPE(VMI7, 0, VMIBase1);
+  CHECK_BASE_INFO_OFFSET_FLAGS(VMI7, 0, 16, __base_class_type_info::__public_mask);
+  CHECK_BASE_INFO_TYPE(VMI7, 1, VMI5);
+  CHECK_BASE_INFO_OFFSET_FLAGS(VMI7, 1, 20, __base_class_type_info::__public_mask);
+  CHECK_BASE_INFO_TYPE(VMI7, 2, VMI6);
+  CHECK_BASE_INFO_OFFSET_FLAGS(VMI7, 2, 0, 0);
+  
+  // Pointers to incomplete classes.
+  CHECK_VTABLE(Incomplete *, pointer);
+  CHECK(to<__pbase_type_info>(typeid(Incomplete *)).__flags == __pbase_type_info::__incomplete_mask);
+  CHECK(to<__pbase_type_info>(typeid(Incomplete **)).__flags == __pbase_type_info::__incomplete_mask);
+  CHECK(to<__pbase_type_info>(typeid(Incomplete ***)).__flags == __pbase_type_info::__incomplete_mask);
+
+  // Member pointers.
+  CHECK_VTABLE(int Incomplete::*, pointer_to_member);
+  CHECK(to<__pbase_type_info>(typeid(int Incomplete::*)).__flags == __pbase_type_info::__incomplete_class_mask);
+  CHECK(to<__pbase_type_info>(typeid(Incomplete Incomplete::*)).__flags == (__pbase_type_info::__incomplete_class_mask | __pbase_type_info::__incomplete_mask));
+  CHECK(to<__pbase_type_info>(typeid(Incomplete A::*)).__flags == (__pbase_type_info::__incomplete_mask));
+
+  // Success!
+  // CHECK: ret i32 0
+  return 0;
+}
+
+#ifdef HARNESS
+extern "C" void printf(const char *, ...);
+
+int main() {
+  int result = f();
+  
+  if (result == 0)
+    printf("success!\n");
+  else
+    printf("test on line %d failed!\n", result);
+
+  return result;
+}
+#endif
+
+
diff --git a/test/CodeGenCXX/rtti-linkage.cpp b/test/CodeGenCXX/rtti-linkage.cpp
new file mode 100644
index 0000000..b9eb5b4
--- /dev/null
+++ b/test/CodeGenCXX/rtti-linkage.cpp
@@ -0,0 +1,104 @@
+// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+#include <typeinfo>
+
+// CHECK: _ZTS1B = constant
+// CHECK: _ZTS1A = weak_odr constant
+// CHECK: _ZTI1A = weak_odr constant
+// CHECK: _ZTI1B = constant
+// CHECK: _ZTSP1C = internal constant
+// CHECK: _ZTS1C = internal constant
+// CHECK: _ZTI1C = internal constant
+// CHECK: _ZTIP1C = internal constant
+// CHECK: _ZTSPP1C = internal constant
+// CHECK: _ZTIPP1C = internal constant
+// CHECK: _ZTSM1Ci = internal constant
+// CHECK: _ZTIM1Ci = internal constant
+// CHECK: _ZTSPM1Ci = internal constant
+// CHECK: _ZTIPM1Ci = internal constant
+// CHECK: _ZTSM1CS_ = internal constant
+// CHECK: _ZTIM1CS_ = internal constant
+// CHECK: _ZTSM1CPS_ = internal constant
+// CHECK: _ZTIM1CPS_ = internal constant
+// CHECK: _ZTSM1A1C = internal constant
+// CHECK: _ZTIM1A1C = internal constant
+// CHECK: _ZTSM1AP1C = internal constant
+// CHECK: _ZTIM1AP1C = internal constant
+
+// CHECK: _ZTS1F = weak_odr constant
+
+// CHECK: _ZTSN12_GLOBAL__N_11DE = internal constant
+// CHECK: _ZTIN12_GLOBAL__N_11DE = internal constant
+// CHECK: _ZTSPN12_GLOBAL__N_11DE = internal constant
+// CHECK: _ZTIPN12_GLOBAL__N_11DE = internal constant
+// CHECK: _ZTSFN12_GLOBAL__N_11DEvE = internal constant
+// CHECK: _ZTIFN12_GLOBAL__N_11DEvE = internal constant
+// CHECK: _ZTSFvN12_GLOBAL__N_11DEE = internal constant
+// CHECK: _ZTIFvN12_GLOBAL__N_11DEE = internal constant
+
+// CHECK: _ZTSPFvvE = weak_odr constant
+// CHECK: _ZTSFvvE = weak_odr constant
+// CHECK: _ZTIFvvE = weak_odr
+// CHECK: _ZTIPFvvE = weak_odr constant
+
+// CHECK: _ZTSN12_GLOBAL__N_11EE = internal constant
+// CHECK: _ZTIN12_GLOBAL__N_11EE = internal constant
+
+// A has no key function, so its RTTI data should be weak_odr.
+struct A { };
+
+// B has a key function defined in the translation unit, so the RTTI data should
+// be emitted in this translation unit and have external linkage.
+struct B : A {
+  virtual void f();
+};
+void B::f() { }
+
+// C is an incomplete class type, so any direct or indirect pointer types should have 
+// internal linkage, as should the type info for C itself.
+struct C;
+
+void t1() {
+  (void)typeid(C*);
+  (void)typeid(C**);
+  (void)typeid(int C::*);
+  (void)typeid(int C::**);
+  (void)typeid(C C::*);
+  (void)typeid(C *C::*);
+  (void)typeid(C A::*);
+  (void)typeid(C* A::*);
+}
+
+namespace {
+  // D is inside an anonymous namespace, so all type information related to D should have
+  // internal linkage.
+  struct D { };
+  
+  // E is also inside an anonymous namespace.
+  enum E { };
+  
+};
+
+// F has a key function defined in the translation unit, but it is inline so the RTTI
+// data should be emitted with weak_odr linkage.
+struct F {
+  virtual void f();
+};
+
+inline void F::f() { }
+const D getD();
+
+const std::type_info &t2() {
+  (void)typeid(const D);
+  (void)typeid(D *);
+  (void)typeid(D (*)());
+  (void)typeid(void (*)(D));
+  (void)typeid(void (*)(D&));
+  // The exception specification is not part of the RTTI descriptor, so it should not have
+  // internal linkage.
+  (void)typeid(void (*)() throw (D));
+  
+  (void)typeid(E);
+  
+  // CHECK: _ZTIN12_GLOBAL__N_11DE to
+  return typeid(getD());  
+}
diff --git a/test/CodeGenCXX/static-assert.cpp b/test/CodeGenCXX/static-assert.cpp
new file mode 100644
index 0000000..dbb8f34
--- /dev/null
+++ b/test/CodeGenCXX/static-assert.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - -std=c++0x -verify
+
+static_assert(true, "");
+
+void f() {
+  static_assert(true, "");
+}
diff --git a/test/CodeGenCXX/static-data-member.cpp b/test/CodeGenCXX/static-data-member.cpp
new file mode 100644
index 0000000..b3a2af2
--- /dev/null
+++ b/test/CodeGenCXX/static-data-member.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s
+
+// CHECK: @_ZN1A1aE = constant i32 10
+
+// PR5564.
+struct A {
+  static const int a = 10;
+};
+
+const int A::a;
+
+struct S { 
+  static int i;
+};
+
+void f() { 
+  int a = S::i;
+}
diff --git a/test/CodeGenCXX/static-init-1.cpp b/test/CodeGenCXX/static-init-1.cpp
new file mode 100644
index 0000000..a926c0a
--- /dev/null
+++ b/test/CodeGenCXX/static-init-1.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -triple=x86_64-apple-darwin9 -emit-llvm %s -o %t
+// RUN: grep "call i32 @_Z5func1i" %t | count 3
+
+extern "C" int printf(...);
+
+static int count;
+
+int func2(int c) { return printf("loading the func2(%d)\n", c); };
+int func1(int c) { return printf("loading the func1(%d)\n", c); }
+
+static int loader_1 = func1(++count);
+
+int loader_2 = func2(++count);
+
+static int loader_3 = func1(++count);
+
+
+int main() {}
+
+int loader_4 = func2(++count);
+static int loader_5 = func1(++count);
+int loader_6 = func2(++count);
+
diff --git a/test/CodeGenCXX/static-init-2.cpp b/test/CodeGenCXX/static-init-2.cpp
new file mode 100644
index 0000000..65ab3bb
--- /dev/null
+++ b/test/CodeGenCXX/static-init-2.cpp
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -emit-llvm-only -verify %s
+
+// Make sure we don't crash generating y; its value is constant, but the
+// initializer has side effects, so EmitConstantExpr should fail.
+int x();
+int y = x() && 0;
diff --git a/test/CodeGenCXX/static-init.cpp b/test/CodeGenCXX/static-init.cpp
new file mode 100644
index 0000000..a67d137
--- /dev/null
+++ b/test/CodeGenCXX/static-init.cpp
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+
+// CHECK: @_ZZ1hvE1i = internal global i32 0, align 4
+
+// CHECK: @_ZZ2h2vE1i = weak global i32 0
+// CHECK: @_ZGVZ2h2vE1i = weak global i64 0
+
+struct A {
+  A();
+  ~A();
+};
+
+void f() {
+  // CHECK: call void @_ZN1AC1Ev(
+  // CHECK: call i32 @__cxa_atexit(void (i8*)* bitcast (void (%struct.A*)* @_ZN1AD1Ev to void (i8*)*), i8* getelementptr inbounds (%struct.A* @_ZZ1fvE1a, i32 0, i32 0), i8* bitcast (i8** @__dso_handle to i8*))
+  static A a;
+}
+
+void g() {
+  // CHECK: call noalias i8* @_Znwm(i64 1)
+  // CHECK: call void @_ZN1AC1Ev(
+  static A& a = *new A;
+}
+
+int a();
+void h() {
+  static const int i = a();
+}
+
+inline void h2() {
+  static int i = a();
+}
+
+void h3() {
+  h2();
+}
diff --git a/test/CodeGenCXX/static-local-in-local-class.cpp b/test/CodeGenCXX/static-local-in-local-class.cpp
new file mode 100644
index 0000000..d9e044c
--- /dev/null
+++ b/test/CodeGenCXX/static-local-in-local-class.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -emit-llvm -o %t %s
+// PR6769
+
+struct X {
+  static void f();
+};
+
+void X::f() {
+  static int *i;
+  {
+    struct Y {
+      static void g() {
+        i = new int();
+	*i = 100;
+	(*i) = (*i) +1;
+      }
+    };
+    (void)Y::g();
+  }
+  (void)i;
+}
diff --git a/test/CodeGenCXX/static-member-variable-explicit-specialization.cpp b/test/CodeGenCXX/static-member-variable-explicit-specialization.cpp
new file mode 100644
index 0000000..94fd9aa
--- /dev/null
+++ b/test/CodeGenCXX/static-member-variable-explicit-specialization.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+// CHECK: ; ModuleID
+template<typename> struct A { static int a; };
+
+// CHECK-NOT: @_ZN1AIcE1aE
+template<> int A<char>::a;
+
+// CHECK: @_ZN1AIbE1aE = global i32 10
+template<> int A<bool>::a = 10;
+
+
diff --git a/test/CodeGenCXX/temp-order.cpp b/test/CodeGenCXX/temp-order.cpp
new file mode 100644
index 0000000..341cd0c
--- /dev/null
+++ b/test/CodeGenCXX/temp-order.cpp
@@ -0,0 +1,226 @@
+// Output file should have no calls to error() with folding.
+// RUN: %clang_cc1 -triple i386-unknown-unknown -O3 -emit-llvm -o %t %s
+// RUN: FileCheck %s < %t
+
+static unsigned pow(unsigned Base, unsigned Power) {
+  unsigned Val = 1;
+  while (Power--)
+    Val *= Base;
+  return Val;
+}
+
+struct TempTracker {
+  unsigned Product, Index;
+
+  TempTracker() : Product(1), Index(0) {}
+
+};
+
+// FIXME: This can be used to check elision as well, if P = 0 hacks are removed.
+struct A {
+  TempTracker &TT;
+  mutable unsigned P;
+  bool Truth;
+
+  A(TempTracker &_TT, unsigned _P, bool _Truth = true)
+    : TT(_TT), P(_P), Truth(_Truth) {}
+  A(const A &RHS) : TT(RHS.TT), P(RHS.P), Truth(RHS.Truth) { RHS.P = 0; }
+  ~A() {
+    if (P)
+      TT.Product *= pow(P, ++TT.Index);
+  }
+
+  A &operator=(const A &RHS) {
+    TT = RHS.TT;
+    P = RHS.P;
+    Truth = RHS.Truth;
+    RHS.P = 0;
+    return *this;
+  }
+
+  operator bool () { return Truth; }
+};
+
+// 3, 7, 2
+static unsigned f0(bool val = false) {
+  TempTracker tt;
+  {
+    A a(tt, 2);
+    if ((A(tt, 3), val))
+      A b(tt, 5);
+    A c(tt, 7);
+  }
+  return tt.Product;
+}
+
+// 3, 5, 7, 2
+static unsigned f1(bool val = true) {
+  TempTracker tt;
+  {
+    A a(tt, 2);
+    if ((A(tt, 3), val))
+      A b(tt, 5);
+    A c(tt, 7);
+  }
+  return tt.Product;
+}
+
+// 5, 3, 7, 2
+static unsigned f2() {
+  TempTracker tt;
+  {
+    A a(tt, 2);
+    if (A b = A(tt, 3))
+      A c(tt, 5);
+    A d(tt, 7);
+  }
+  return tt.Product;
+}
+
+// 7, 3, 11, 2
+static unsigned f3() {
+  TempTracker tt;
+  {
+    A a(tt, 2);
+    if (A b = A(tt, 3, false))
+      A c(tt, 5);
+    else
+      A c(tt, 7);
+    A d(tt, 11);
+  }
+  return tt.Product;
+}
+
+// 3, 7, 2
+static unsigned f4() {
+  TempTracker tt;
+  {
+    A a(tt, 2);
+    while (A b = A(tt, 3, false))
+      A c(tt, 5);
+    A c(tt, 7);
+  }
+  return tt.Product;
+}
+
+// 5, 3, 7, 2
+static unsigned f5() {
+  TempTracker tt;
+  {
+    A a(tt, 2);
+    while (A b = A(tt, 3, true)) {
+      A c(tt, 5);
+      break;
+    }
+    A c(tt, 7);
+  }
+  return tt.Product;
+}
+
+// 3, 7, 11, 5, 13, 2
+static unsigned f6() {
+  TempTracker tt;
+  {
+    A a(tt, 2);
+    for (A b = (A(tt, 3), A(tt, 5)), c = (A(tt, 7), A(tt, 11));;)
+      break;
+    A c(tt, 13);
+  }
+  return tt.Product;
+}
+
+// 5, 2
+static unsigned f7() {
+  TempTracker tt;
+  {
+    (void)((A(tt, 2, false) && A(tt, 3, false)) || A(tt, 5, false));
+  }
+  return tt.Product;
+}
+
+// 5, 2
+static unsigned f8() {
+  TempTracker tt;
+  
+  {
+    (void)((A(tt, 2) || A(tt, 3)) && A(tt, 5));
+  }
+  return tt.Product;
+}
+
+extern "C" void error();
+extern "C" void print(const char *Name, unsigned N);
+
+#define ORDER2(a, b) (pow(a, 1) * pow(b, 2))
+#define ORDER3(a, b, c) (ORDER2(a, b) * pow(c, 3))
+#define ORDER4(a, b, c, d) (ORDER3(a, b, c) * pow(d, 4))
+#define ORDER5(a, b, c, d, e) (ORDER4(a, b, c, d) * pow(e, 5))
+#define ORDER6(a, b, c, d, e, f) (ORDER5(a, b, c, d, e) * pow(f, 6))
+void test() {
+// CHECK: call void @print(i8* {{.*}}, i32 1176)
+  print("f0", f0());
+  if (f0() != ORDER3(3, 7, 2))
+    error();
+
+// CHECK: call void @print(i8* {{.*}}, i32 411600)
+  print("f1", f1());
+  if (f1() != ORDER4(3, 5, 7, 2))
+    error();
+
+// CHECK: call void @print(i8* {{.*}}, i32 246960)
+  print("f2", f2());
+  if (f2() != ORDER4(5, 3, 7, 2))
+    error();
+
+// CHECK: call void @print(i8* {{.*}}, i32 1341648)
+  print("f3", f3());
+  if (f3() != ORDER4(7, 3, 11, 2))
+    error();
+
+// CHECK: call void @print(i8* {{.*}}, i32 1176)
+  print("f4", f4());
+  if (f4() != ORDER3(3, 7, 2))
+    error();
+
+// CHECK: call void @print(i8* {{.*}}, i32 246960)
+  print("f5", f5());
+  if (f5() != ORDER4(5, 3, 7, 2))
+    error();
+
+// CHECK: call void @print(i8* {{.*}}, i32 1251552576)
+  print("f6", f6());
+  if (f6() != ORDER6(3, 7, 11, 5, 13, 2))
+    error();
+
+//  CHECK: call void @print(i8* {{.*}}, i32 20)
+  print("f7", f7());
+  if (f7() != ORDER2(5, 2))
+    error();
+
+//  CHECK: call void @print(i8* {{.*}}, i32 20)
+  print("f8", f8());
+  if (f8() != ORDER2(5, 2))
+    error();
+}
+
+
+
+#ifdef HARNESS
+
+#include <cstdlib>
+#include <cstdio>
+
+extern "C" void error() {
+  abort();
+}
+
+extern "C" void print(const char *name, unsigned N) {
+  printf("%s: %d\n", name, N);
+}
+
+int main() {
+  test();
+  return 0;
+}
+
+#endif
diff --git a/test/CodeGenCXX/template-anonymous-union-member-initializer.cpp b/test/CodeGenCXX/template-anonymous-union-member-initializer.cpp
new file mode 100644
index 0000000..41ae084
--- /dev/null
+++ b/test/CodeGenCXX/template-anonymous-union-member-initializer.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -emit-llvm -o %t %s
+template <typename T>
+class A
+{
+    union { void *d; };
+
+public:
+    A() : d(0) { }
+};
+
+A<int> a0;
diff --git a/test/CodeGenCXX/template-instantiation.cpp b/test/CodeGenCXX/template-instantiation.cpp
new file mode 100644
index 0000000..4a38575
--- /dev/null
+++ b/test/CodeGenCXX/template-instantiation.cpp
@@ -0,0 +1,77 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+
+// CHECK-NOT: @_ZTVN5test118stdio_sync_filebufIwEE = constant
+// CHECK-NOT: _ZTVN5test315basic_fstreamXXIcEE
+// CHECK: @_ZTVN5test018stdio_sync_filebufIwEE = constant
+
+// CHECK: define linkonce_odr void @_ZN5test21CIiEC1Ev(
+// CHECK: define linkonce_odr void @_ZN5test21CIiE6foobarIdEEvT_(
+// CHECK: define available_externally void @_ZN5test21CIiE6zedbarEd(
+
+namespace test0 {
+  struct  basic_streambuf   {
+    virtual       ~basic_streambuf();
+  };
+  template<typename _CharT >
+  struct stdio_sync_filebuf : public basic_streambuf {
+    virtual void      xsgetn();
+  };
+
+  // This specialization should cause the vtable to be emitted, even with
+  // the following extern template declaration.
+  template<> void stdio_sync_filebuf<wchar_t>::xsgetn()  {
+  }
+  extern template class stdio_sync_filebuf<wchar_t>;
+}
+
+namespace test1 {
+  struct  basic_streambuf   {
+    virtual       ~basic_streambuf();
+  };
+  template<typename _CharT >
+  struct stdio_sync_filebuf : public basic_streambuf {
+    virtual void      xsgetn();
+  };
+
+  // Just a declaration should not force the vtable to be emitted.
+  template<> void stdio_sync_filebuf<wchar_t>::xsgetn();
+}
+
+namespace test2 {
+  template<typename T1>
+  class C {
+  public:
+    virtual ~C();
+    void zedbar(double) {
+    }
+    template<typename T2>
+    void foobar(T2 foo) {
+    }
+  };
+  extern template class C<int>;
+  void g() {
+    // The extern template declaration should not prevent us from producing
+    // the implicit constructor (test at the top).
+    C<int> a;
+
+    // or foobar(test at the top).
+    a.foobar(0.0);
+
+    // But it should prevent zebbar
+    // (test at the top).
+    a.zedbar(0.0);
+  }
+}
+
+namespace test3 {
+  template<typename T>
+  class basic_fstreamXX  {
+    virtual void foo(){}
+    virtual void is_open() const  { }
+  };
+
+  extern template class basic_fstreamXX<char>;
+  // This template instantiation should not cause us to produce a vtable.
+  // (test at the top).
+  template void basic_fstreamXX<char>::is_open() const;
+}
diff --git a/test/CodeGenCXX/template-linkage.cpp b/test/CodeGenCXX/template-linkage.cpp
new file mode 100644
index 0000000..ccd61a7
--- /dev/null
+++ b/test/CodeGenCXX/template-linkage.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+template<typename T> struct A {
+  virtual void f(T) { }
+  inline void g() { } 
+};
+
+// Explicit instantiations have external linkage.
+
+// CHECK: define weak_odr void @_ZN1AIiE1gEv(
+template void A<int>::g();
+
+// CHECK: define weak_odr void @_ZN1AIfE1fEf(
+// CHECK: define weak_odr void @_ZN1AIfE1gEv(
+// FIXME: This should also emit the vtable.
+template struct A<float>;
+
+// CHECK: define weak_odr void @_Z1fIiEvT_
+template <typename T> void f(T) { }
+template void f<int>(int);
+
+// CHECK: define weak_odr void @_Z1gIiEvT_
+template <typename T> inline void g(T) { }
+template void g<int>(int);
+
diff --git a/test/CodeGenCXX/temporaries.cpp b/test/CodeGenCXX/temporaries.cpp
new file mode 100644
index 0000000..eb543cb
--- /dev/null
+++ b/test/CodeGenCXX/temporaries.cpp
@@ -0,0 +1,322 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 | FileCheck %s
+struct A {
+  A();
+  ~A();
+  void f();
+};
+
+void f1() {
+  // CHECK: call void @_ZN1AC1Ev
+  // CHECK: call void @_ZN1AD1Ev
+  (void)A();
+
+  // CHECK: call void @_ZN1AC1Ev
+  // CHECK: call void @_ZN1AD1Ev
+  A().f();
+}
+
+// Function calls
+struct B {
+  B();
+  ~B();
+};
+
+B g();
+
+void f2() {
+  // CHECK-NOT: call void @_ZN1BC1Ev
+  // CHECK: call void @_ZN1BD1Ev
+  (void)g();
+}
+
+// Member function calls
+struct C {
+  C();
+  ~C();
+  
+  C f();
+};
+
+void f3() {
+  // CHECK: call void @_ZN1CC1Ev
+  // CHECK: call void @_ZN1CD1Ev
+  // CHECK: call void @_ZN1CD1Ev
+  C().f();
+}
+
+// Function call operator
+struct D {
+  D();
+  ~D();
+  
+  D operator()();
+};
+
+void f4() {
+  // CHECK: call void @_ZN1DC1Ev
+  // CHECK: call void @_ZN1DD1Ev
+  // CHECK: call void @_ZN1DD1Ev
+  D()();
+}
+
+// Overloaded operators
+struct E {
+  E();
+  ~E();
+  E operator+(const E&);
+  E operator!();
+};
+
+void f5() {
+  // CHECK: call void @_ZN1EC1Ev
+  // CHECK: call void @_ZN1EC1Ev
+  // CHECK: call void @_ZN1ED1Ev
+  // CHECK: call void @_ZN1ED1Ev
+  // CHECK: call void @_ZN1ED1Ev
+  E() + E();
+  
+  // CHECK: call void @_ZN1EC1Ev
+  // CHECK: call void @_ZN1ED1Ev
+  // CHECK: call void @_ZN1ED1Ev
+  !E();
+}
+
+struct F {
+  F();
+  ~F();
+  F& f();
+};
+
+void f6() {
+  // CHECK: call void @_ZN1FC1Ev
+  // CHECK: call void @_ZN1FD1Ev
+  F().f();
+}
+
+struct G {
+  G();
+  G(A);
+  ~G();
+  operator A();
+};
+
+void a(const A&);
+
+void f7() {
+  // CHECK: call void @_ZN1AC1Ev
+  // CHECK: call void @_Z1aRK1A
+  // CHECK: call void @_ZN1AD1Ev
+  a(A());
+  
+  // CHECK: call void @_ZN1GC1Ev
+  // CHECK: call void @_ZN1Gcv1AEv
+  // CHECK: call void @_Z1aRK1A
+  // CHECK: call void @_ZN1AD1Ev
+  // CHECK: call void @_ZN1GD1Ev
+  a(G());
+}
+
+namespace PR5077 {
+
+struct A {
+  A();
+  ~A();
+  int f();
+};
+
+void f();
+int g(const A&);
+
+struct B {
+  int a1;
+  int a2;
+  B();
+  ~B();
+};
+
+B::B()
+  // CHECK: call void @_ZN6PR50771AC1Ev
+  // CHECK: call i32 @_ZN6PR50771A1fEv
+  // CHECK: call void @_ZN6PR50771AD1Ev
+  : a1(A().f())
+  // CHECK: call void @_ZN6PR50771AC1Ev
+  // CHECK: call i32 @_ZN6PR50771gERKNS_1AE
+  // CHECK: call void @_ZN6PR50771AD1Ev
+  , a2(g(A()))
+{
+  // CHECK: call void @_ZN6PR50771fEv
+  f();
+}
+  
+struct C {
+  C();
+  
+  const B& b;
+};
+
+C::C() 
+  // CHECK: call void @_ZN6PR50771BC1Ev
+  : b(B()) {
+  // CHECK: call void @_ZN6PR50771fEv
+  f();
+  
+  // CHECK: call void @_ZN6PR50771BD1Ev
+}
+}
+
+A f8() {
+  // CHECK: call void @_ZN1AC1Ev
+  // CHECK-NOT: call void @_ZN1AD1Ev
+  return A();
+  // CHECK: ret void
+}
+
+struct H {
+  H();
+  ~H();
+  H(const H&);
+};
+
+void f9(H h) {
+  // CHECK: call void @_ZN1HC1Ev
+  // CHECK: call void @_Z2f91H
+  // CHECK: call void @_ZN1HD1Ev
+  f9(H());
+  
+  // CHECK: call void @_ZN1HC1ERKS_
+  // CHECK: call void @_Z2f91H
+  // CHECK: call void @_ZN1HD1Ev
+  f9(h);
+}
+
+void f10(const H&);
+
+void f11(H h) {
+  // CHECK: call void @_ZN1HC1Ev
+  // CHECK: call void @_Z3f10RK1H
+  // CHECK: call void @_ZN1HD1Ev
+  f10(H());
+  
+  // CHECK: call void @_Z3f10RK1H
+  // CHECK-NOT: call void @_ZN1HD1Ev
+  // CHECK: ret void
+  f10(h);
+}
+
+// PR5808
+struct I {
+  I(const char *);
+  ~I();
+};
+
+// CHECK: _Z3f12v
+I f12() {
+  // CHECK: call void @_ZN1IC1EPKc
+  // CHECK-NOT: call void @_ZN1ID1Ev
+  // CHECK: ret void
+  return "Hello";
+}
+
+// PR5867
+namespace PR5867 {
+  struct S {
+    S();
+    S(const S &);
+    ~S();
+  };
+
+  void f(S, int);
+  // CHECK: define void @_ZN6PR58671gEv
+  void g() {
+    // CHECK: call void @_ZN6PR58671SC1Ev
+    // CHECK-NEXT: call void @_ZN6PR58671fENS_1SEi
+    // CHECK-NEXT: call void @_ZN6PR58671SD1Ev
+    // CHECK-NEXT: ret void
+    (f)(S(), 0);
+  }
+
+  // CHECK: define linkonce_odr void @_ZN6PR58672g2IiEEvT_
+  template<typename T>
+  void g2(T) {
+    // CHECK: call void @_ZN6PR58671SC1Ev
+    // CHECK-NEXT: call void @_ZN6PR58671fENS_1SEi
+    // CHECK-NEXT: call void @_ZN6PR58671SD1Ev
+    // CHECK-NEXT: ret void
+    (f)(S(), 0);
+  }
+
+  void h() {
+    g2(17);
+  }
+}
+
+// PR6199
+namespace PR6199 {
+  struct A { ~A(); };
+
+  struct B { operator A(); };
+
+  // CHECK: define weak_odr void @_ZN6PR61992f2IiEENS_1AET_
+  template<typename T> A f2(T) {
+    B b;
+    // CHECK: call void @_ZN6PR61991BcvNS_1AEEv
+    // CHECK-NEXT: ret void
+    return b;
+  }
+
+  template A f2<int>(int);
+  
+}
+
+namespace T12 {
+
+struct A { 
+  A(); 
+  ~A();
+  int f();
+};
+
+int& f(int);
+
+// CHECK: define void @_ZN3T121gEv
+void g() {
+  // CHECK: call void @_ZN3T121AC1Ev
+  // CHECK-NEXT: call i32 @_ZN3T121A1fEv(
+  // CHECK-NEXT: call i32* @_ZN3T121fEi(
+  // CHECK-NEXT: call void @_ZN3T121AD1Ev(
+  int& i = f(A().f());
+}
+
+}
+
+namespace PR6648 {
+  struct B {
+    ~B();
+  };
+  B foo;
+  struct D;
+  D& zed(B);
+  void foobar() {
+    // CHECK: call %"struct.PR6648::D"* @_ZN6PR66483zedENS_1BE
+    zed(foo);
+  }
+}
+
+namespace UserConvertToValue {
+  struct X {
+    X(int);
+    X(const X&);
+    ~X();
+  };
+
+  void f(X);
+
+  // CHECK: void @_ZN18UserConvertToValue1gEv() 
+  void g() {
+    // CHECK: call void @_ZN18UserConvertToValue1XC1Ei
+    // CHECK: call void @_ZN18UserConvertToValue1fENS_1XE
+    // CHECK: call void @_ZN18UserConvertToValue1XD1Ev
+    // CHECK: ret void
+    f(1);
+  }
+}
diff --git a/test/CodeGenCXX/threadsafe-statics.cpp b/test/CodeGenCXX/threadsafe-statics.cpp
new file mode 100644
index 0000000..65ebc43
--- /dev/null
+++ b/test/CodeGenCXX/threadsafe-statics.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck -check-prefix=WITH-TSS %s
+// RUN: %clang_cc1 -emit-llvm -o - %s -fno-threadsafe-statics | FileCheck -check-prefix=NO-TSS %s
+
+int f();
+
+// WITH-TSS: define void @_Z1gv() nounwind
+// WITH-TSS: call i32 @__cxa_guard_acquire
+// WITH-TSS: call void @__cxa_guard_release
+// WITH-TSS: ret void
+void g() { 
+  static int a = f();
+}
+
+// NO-TSS: define void @_Z1gv() nounwind
+// NO-TSS-NOT: call i32 @__cxa_guard_acquire
+// NO-TSS-NOT: call void @__cxa_guard_release
+// NO-TSS: ret void
diff --git a/test/CodeGenCXX/throw-expressions.cpp b/test/CodeGenCXX/throw-expressions.cpp
new file mode 100644
index 0000000..1670e44
--- /dev/null
+++ b/test/CodeGenCXX/throw-expressions.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -emit-llvm-only -verify %s -Wno-unreachable-code
+
+int val = 42;
+int& test1() {
+  return throw val, val;
+}
+
+int test2() {
+  return val ? throw val : val;
+}
diff --git a/test/CodeGenCXX/thunks.cpp b/test/CodeGenCXX/thunks.cpp
new file mode 100644
index 0000000..b91ba32
--- /dev/null
+++ b/test/CodeGenCXX/thunks.cpp
@@ -0,0 +1,137 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+
+namespace Test1 {
+
+// Check that we emit a non-virtual thunk for C::f.
+
+struct A {
+  virtual void f();
+};
+
+struct B {
+  virtual void f();
+};
+
+struct C : A, B {
+  virtual void c();
+  
+  virtual void f();
+};
+
+// CHECK: define void @_ZThn8_N5Test11C1fEv(
+void C::f() { }
+
+}
+
+namespace Test2 {
+
+// Check that we emit a thunk for B::f since it's overriding a virtual base.
+
+struct A {
+  virtual void f();
+};
+
+struct B : virtual A {
+  virtual void b();
+  virtual void f();
+};
+
+// CHECK: define void @_ZTv0_n24_N5Test21B1fEv(
+void B::f() { }
+
+}
+
+namespace Test3 {
+
+// Check that we emit a covariant thunk for B::f.
+
+struct V1 { };
+struct V2 : virtual V1 { };
+
+struct A {
+  virtual V1 *f();
+};
+
+struct B : A {
+  virtual void b();
+  
+  virtual V2 *f();
+};
+
+// CHECK: define %{{.*}}* @_ZTch0_v0_n24_N5Test31B1fEv(
+V2 *B::f() { return 0; }
+
+}
+
+namespace Test4 {
+
+// Check that the thunk for 'C::f' has the same visibility as the function itself.
+
+struct A {
+  virtual void f();
+};
+
+struct B {
+  virtual void f();
+};
+
+struct __attribute__((visibility("protected"))) C : A, B {
+  virtual void c();
+  
+  virtual void f();
+};
+
+// CHECK: define protected void @_ZThn8_N5Test41C1fEv(
+void C::f() { }
+
+}
+
+// This is from Test5:
+// CHECK: define linkonce_odr void @_ZTv0_n24_N5Test51B1fEv
+
+// Check that the thunk gets internal linkage.
+namespace {
+
+struct A {
+  virtual void f();
+};
+
+struct B {
+  virtual void f();
+};
+
+struct C : A, B {
+  virtual void c();
+
+  virtual void f();
+};
+
+// CHECK: define internal void @_ZThn8_N12_GLOBAL__N_11C1fEv(
+void C::f() { }
+
+}
+
+// Force C::f to be used.
+void f() { 
+  C c; 
+  
+  c.f();
+}
+
+namespace Test5 {
+
+// Check that the thunk for 'B::f' gets the same linkage as the function itself.
+struct A {
+  virtual void f();
+};
+
+struct B : virtual A {
+  virtual void f() { }
+};
+
+void f(B b) {
+  b.f();
+}
+}
+
+
diff --git a/test/CodeGenCXX/trivial-constructor-init.cpp b/test/CodeGenCXX/trivial-constructor-init.cpp
new file mode 100644
index 0000000..343dc65
--- /dev/null
+++ b/test/CodeGenCXX/trivial-constructor-init.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1  -S %s -o %t-64.s
+// RUN: %clang_cc1  -S %s -o %t-32.s
+
+extern "C" int printf(...);
+
+struct S {
+  S() { printf("S::S\n"); }
+};
+
+struct A {
+  double x;
+  A() : x(), y(), s() { printf("x = %f y = %x \n", x, y); }
+  int *y;
+  S s;
+};
+
+A a;
+
+int main() {
+}
diff --git a/test/CodeGenCXX/try-catch.cpp b/test/CodeGenCXX/try-catch.cpp
new file mode 100644
index 0000000..2b5f323
--- /dev/null
+++ b/test/CodeGenCXX/try-catch.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - -fexceptions | FileCheck %s
+
+struct X { };
+
+const X g();
+
+void f() {
+  try {
+    throw g();
+    // CHECK: @_ZTI1X to i8
+  } catch (const X x) {
+  }
+}
diff --git a/test/CodeGenCXX/typeinfo b/test/CodeGenCXX/typeinfo
new file mode 100644
index 0000000..7af23cf
--- /dev/null
+++ b/test/CodeGenCXX/typeinfo
@@ -0,0 +1,16 @@
+namespace std {
+  class type_info {
+  public:
+    virtual ~type_info();
+    const char* name() const { return __name; }
+    bool operator==(const type_info& __arg) const {
+     return __name == __arg.__name;
+    }
+
+    bool operator!=(const type_info& __arg) const {
+      return !operator==(__arg);
+    }
+  protected:
+    const char *__name;
+  };
+}
diff --git a/test/CodeGenCXX/unary-type-trait.cpp b/test/CodeGenCXX/unary-type-trait.cpp
new file mode 100644
index 0000000..a11c67e
--- /dev/null
+++ b/test/CodeGenCXX/unary-type-trait.cpp
@@ -0,0 +1,3 @@
+// RUN: %clang_cc1 -emit-llvm-only -verify %s
+
+bool a() { return __is_pod(int); }
diff --git a/test/CodeGenCXX/value-init.cpp b/test/CodeGenCXX/value-init.cpp
new file mode 100644
index 0000000..37891bd
--- /dev/null
+++ b/test/CodeGenCXX/value-init.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+
+struct A {
+  virtual ~A();
+};
+
+struct B : A { };
+
+struct C {
+  int i;
+  B b;
+};
+
+// CHECK: _Z15test_value_initv
+void test_value_init() {
+  // This value initialization requires zero initialization of the 'B'
+  // subobject followed by a call to its constructor.
+  // PR5800
+
+  // CHECK: store i32 17
+  // CHECK: call void @llvm.memset.p0i8.i64
+  // CHECK: call void @_ZN1BC1Ev
+  C c = { 17 } ;
+  // CHECK: call void @_ZN1CD1Ev
+}
diff --git a/test/CodeGenCXX/vararg-conversion-ctor.cpp b/test/CodeGenCXX/vararg-conversion-ctor.cpp
new file mode 100644
index 0000000..7e42859
--- /dev/null
+++ b/test/CodeGenCXX/vararg-conversion-ctor.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++0x -emit-llvm %s -o %t-64.ll
+// RUN: FileCheck -check-prefix LPLL64 --input-file=%t-64.ll %s
+
+extern "C" int printf(...);
+
+struct A { 
+  A(...) {
+    printf("A::A(...)\n"); 
+  } 
+};
+
+A a(1.34);
+
+A b = 2.34;
+
+int main()
+{
+  A c[3];
+}
+
+// CHECK-LPLL64: call void (%struct.A*, ...)
+// CHECK-LPLL64: call void (%struct.A*, ...)
+// CHECK-LPLL64: call void (%struct.A*, ...)
diff --git a/test/CodeGenCXX/virt-call-offsets.cpp b/test/CodeGenCXX/virt-call-offsets.cpp
new file mode 100644
index 0000000..3eb6b5d
--- /dev/null
+++ b/test/CodeGenCXX/virt-call-offsets.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+
+struct A { virtual void a(); };
+struct B : A {};
+struct C : B { virtual void a(); };
+void (C::*x)() = &C::a;
+
+// CHECK: @x = global %0 { i{{[0-9]+}} 1, i{{[0-9]+}} 0 }
diff --git a/test/CodeGenCXX/virt-canonical-decl.cpp b/test/CodeGenCXX/virt-canonical-decl.cpp
new file mode 100644
index 0000000..dfc3619
--- /dev/null
+++ b/test/CodeGenCXX/virt-canonical-decl.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 %s -emit-llvm-only
+
+class Base {
+public:
+   virtual ~Base();
+};
+
+Base::~Base()
+{
+}
+
+class Foo : public Base {
+public:
+   virtual ~Foo();
+};
+
+Foo::~Foo()
+{
+}
diff --git a/test/CodeGenCXX/virt-dtor-gen.cpp b/test/CodeGenCXX/virt-dtor-gen.cpp
new file mode 100644
index 0000000..a4346ba
--- /dev/null
+++ b/test/CodeGenCXX/virt-dtor-gen.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -o - -emit-llvm %s | FileCheck %s
+// PR5483
+
+// Make sure we generate all three forms of the destructor when it is virtual.
+class Foo {
+  virtual ~Foo();
+};
+Foo::~Foo() {}
+
+// CHECK: define void @_ZN3FooD0Ev
diff --git a/test/CodeGenCXX/virt-dtor-key.cpp b/test/CodeGenCXX/virt-dtor-key.cpp
new file mode 100644
index 0000000..6a58c50
--- /dev/null
+++ b/test/CodeGenCXX/virt-dtor-key.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s
+// CHECK: @_ZTI3foo = constant
+class foo {
+   foo();
+   virtual ~foo();
+};
+
+foo::~foo() {
+}
diff --git a/test/CodeGenCXX/virt-template-vtable.cpp b/test/CodeGenCXX/virt-template-vtable.cpp
new file mode 100644
index 0000000..b968f38
--- /dev/null
+++ b/test/CodeGenCXX/virt-template-vtable.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+
+template<class T> class A {
+public:
+  A() {}
+  virtual void a() {}
+};
+class B : A<int> {
+  B();
+};
+B::B() {}
+
+// CHECK: @_ZTV1AIiE = weak_odr constant
diff --git a/test/CodeGenCXX/virt-thunk-reference.cpp b/test/CodeGenCXX/virt-thunk-reference.cpp
new file mode 100644
index 0000000..0cd958b
--- /dev/null
+++ b/test/CodeGenCXX/virt-thunk-reference.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -emit-llvm-only %s
+
+struct A { int a; virtual void aa(int&); };
+struct B { int b; virtual void bb(int&); };
+struct C : A,B { virtual void aa(int&), bb(int&); };
+void C::aa(int&) {}
+void C::bb(int&) {}
diff --git a/test/CodeGenCXX/virt.cpp b/test/CodeGenCXX/virt.cpp
new file mode 100644
index 0000000..1b0588f
--- /dev/null
+++ b/test/CodeGenCXX/virt.cpp
@@ -0,0 +1,696 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++0x -O0 -S %s -o %t-64.s
+// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s
+
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++0x -emit-llvm %s -o %t-64.ll
+// RUN: FileCheck -check-prefix LPLL64 --input-file=%t-64.ll %s
+
+
+// CHECK-LP64: main:
+// CHECK-LP64: movl $1, 12(%rax)
+// CHECK-LP64: movl $2, 8(%rax)
+
+struct B {
+  virtual void bar1();
+  virtual void bar2();
+  int b;
+};
+void B::bar1() { }
+void B::bar2() { }
+
+// CHECK-LPLL64:@_ZTV1B = constant [4 x i8*] [i8* null, i8* bitcast (%0* @_ZTI1B to i8*), i8* bitcast (void (%struct.B*)* @_ZN1B4bar1Ev to i8*), i8* bitcast (void (%struct.B*)* @_ZN1B4bar2Ev to i8*)]
+
+struct C {
+  virtual void bee1();
+  virtual void bee2();
+};
+void C::bee1() { }
+void C::bee2() { }
+
+struct D {
+  virtual void boo();
+};
+void D::boo() { }
+
+struct D1 {
+  virtual void bar();
+  virtual void bar2();
+  virtual void bar3();
+  virtual void bar4();
+  virtual void bar5();
+  void *d1;
+};
+void D1::bar() { }
+
+class F : virtual public D1, virtual public D {
+public:
+  virtual void foo();
+  void *f;
+};
+void F::foo() { }
+
+// CHECK-LPLL64:@_ZTV1F = constant [19 x i8*] [i8* null, i8* inttoptr (i64 16 to i8*), i8* null, i8* null, i8* bitcast (%1* @_ZTI1F to i8*), i8* bitcast (void (%class.test14*)* @_ZN1D3booEv to i8*), i8* bitcast (void (%class.F*)* @_ZN1F3fooEv to i8*), i8* null, i8* null, i8* null, i8* null, i8* null, i8* inttoptr (i64 -16 to i8*), i8* bitcast (%1* @_ZTI1F to i8*), i8* bitcast (void (%struct.D1*)* @_ZN2D13barEv to i8*), i8* bitcast (void (%struct.D1*)* @_ZN2D14bar2Ev to i8*), i8* bitcast (void (%struct.D1*)* @_ZN2D14bar3Ev to i8*), i8* bitcast (void (%struct.D1*)* @_ZN2D14bar4Ev to i8*), i8* bitcast (void (%struct.D1*)* @_ZN2D14bar5Ev to i8*)]
+
+
+struct E {
+  int e;
+};
+
+static_assert (sizeof (C) == (sizeof(void *)), "vtable pointer layout");
+
+class A : public E, public B, public C {
+public:
+  virtual void foo1();
+  virtual void foo2();
+  A() { }
+  int a;
+} *ap;
+void A::foo1() { }
+void A::foo2() { }
+
+// CHECK-LPLL64:@_ZTV1A = constant [10 x i8*] [i8* null, i8* bitcast (%2* @_ZTI1A to i8*), i8* bitcast (void (%struct.B*)* @_ZN1B4bar1Ev to i8*), i8* bitcast (void (%struct.B*)* @_ZN1B4bar2Ev to i8*), i8* bitcast (void (%class.A*)* @_ZN1A4foo1Ev to i8*), i8* bitcast (void (%class.A*)* @_ZN1A4foo2Ev to i8*), i8* inttoptr (i64 -16 to i8*), i8* bitcast (%2* @_ZTI1A to i8*), i8* bitcast (void (%class.test14*)* @_ZN1C4bee1Ev to i8*), i8* bitcast (void (%class.test14*)* @_ZN1C4bee2Ev to i8*)]
+
+int main() {
+  A a;
+  B b;
+  ap->e = 1;
+  ap->b = 2;
+}
+
+
+struct test12_A {
+  virtual void foo0() { }
+  virtual void foo();
+} *test12_pa;
+
+struct test12_B : public test12_A {
+  virtual void foo() { }
+} *test12_pb;
+
+struct test12_D : public test12_B {
+} *test12_pd;
+
+
+struct test6_B2 { virtual void funcB2(); char b[1000]; };
+struct test6_B1 : virtual test6_B2 { virtual void funcB1(); };
+
+struct test6_D : test6_B2, virtual test6_B1 {
+};
+
+// CHECK-LP64: .zerofill __DATA,__common,_d6,2024
+
+struct test7_B2 { virtual void funcB2(); };
+struct test7_B1 : virtual test7_B2 { virtual void funcB1(); };
+
+struct test7_D : test7_B2, virtual test7_B1 {
+};
+
+// FIXME: we were checking for an alignment of 3 (?)
+// CHECK-LP64: .zerofill __DATA,__common,_d7,16,
+
+
+struct test3_B3 { virtual void funcB3(); };
+struct test3_B2 : virtual test3_B3 { virtual void funcB2(); };
+struct test3_B1 : virtual test3_B2 { virtual void funcB1(); };
+
+struct test3_D : virtual test3_B1 {
+  virtual void funcD() { }
+};
+
+// CHECK-LPLL64:@_ZTV7test3_D = weak_odr constant [12 x i8*] [i8* null, i8* null, i8* null, i8* null, i8* null, i8* null, i8* null, i8* bitcast (%3* @_ZTI7test3_D to i8*), i8* bitcast (void (%class.test14*)* @_ZN8test3_B36funcB3Ev to i8*), i8* bitcast (void (%class.test17_B2*)* @_ZN8test3_B26funcB2Ev to i8*), i8* bitcast (void (%class.test17_B2*)* @_ZN8test3_B16funcB1Ev to i8*), i8* bitcast (void (%class.test17_B2*)* @_ZN7test3_D5funcDEv to i8*)]
+
+
+struct test4_D : virtual B, virtual C {
+};
+
+// CHECK-LPLL64:@_ZTV7test4_D = weak_odr constant [14 x i8*] [i8* null, i8* inttoptr (i64 8 to i8*), i8* null, i8* null, i8* null, i8* bitcast (%1* @_ZTI7test4_D to i8*), i8* bitcast (void (%class.test14*)* @_ZN1C4bee1Ev to i8*), i8* bitcast (void (%class.test14*)* @_ZN1C4bee2Ev to i8*), i8* null, i8* null, i8* inttoptr (i64 -8 to i8*), i8* bitcast (%1* @_ZTI7test4_D to i8*), i8* bitcast (void (%struct.B*)* @_ZN1B4bar1Ev to i8*), i8* bitcast (void (%struct.B*)* @_ZN1B4bar2Ev to i8*)]
+
+
+struct test5_B3 { virtual void funcB3(); };
+struct test5_B2 : virtual test5_B3 { virtual void funcB2(); };
+struct test5_B1 : virtual test5_B2 { virtual void funcB1(); };
+
+struct test5_B23 { virtual void funcB23(); };
+struct test5_B22 : virtual test5_B23 { virtual void funcB22(); };
+struct test5_B21 : virtual test5_B22 { virtual void funcB21(); };
+
+
+struct B232 { virtual void funcB232(); };
+struct B231 { virtual void funcB231(); };
+
+struct test5_B33 { virtual void funcB33(); };
+struct test5_B32 : virtual test5_B33, virtual B232 { virtual void funcB32(); };
+struct test5_B31 : virtual test5_B32, virtual B231 { virtual void funcB31(); };
+
+struct test5_D  : virtual test5_B1, virtual test5_B21, virtual test5_B31 {
+  virtual void funcD() { }
+};
+
+// CHECK-LPLL64:@_ZTV7test5_D = weak_odr constant [50 x i8*] [i8* inttoptr (i64 32 to i8*), i8* inttoptr (i64 24 to i8*), i8* inttoptr (i64 16 to i8*), i8* inttoptr (i64 16 to i8*), i8* inttoptr (i64 16 to i8*), i8* inttoptr (i64 8 to i8*), i8* inttoptr (i64 8 to i8*), i8* inttoptr (i64 8 to i8*), i8* null, i8* null, i8* null, i8* null, i8* null, i8* null, i8* null, i8* bitcast (%2* @_ZTI7test5_D to i8*), i8* bitcast (void (%class.test14*)* @_ZN8test5_B36funcB3Ev to i8*), i8* bitcast (void (%class.test17_B2*)* @_ZN8test5_B26funcB2Ev to i8*), i8* bitcast (void (%class.test17_B2*)* @_ZN8test5_B16funcB1Ev to i8*), i8* bitcast (void (%struct.test10_B2*)* @_ZN7test5_D5funcDEv to i8*), i8* null, i8* null, i8* null, i8* null, i8* null, i8* inttoptr (i64 -8 to i8*), i8* bitcast (%2* @_ZTI7test5_D to i8*), i8* bitcast (void (%class.test14*)* @_ZN9test5_B237funcB23Ev to i8*), i8* bitcast (void (%class.test17_B2*)* @_ZN9test5_B227funcB22Ev to i8*), i8* bitcast (void (%class.test17_B2*)* @_ZN9test5_B217funcB21Ev to i8*), i8* null, i8* inttoptr (i64 16 to i8*), i8* null, i8* null, i8* inttoptr (i64 8 to i8*), i8* null, i8* null, i8* inttoptr (i64 -16 to i8*), i8* bitcast (%2* @_ZTI7test5_D to i8*), i8* bitcast (void (%class.test14*)* @_ZN9test5_B337funcB33Ev to i8*), i8* bitcast (void (%class.test20_D*)* @_ZN9test5_B327funcB32Ev to i8*), i8* bitcast (void (%class.test23_D*)* @_ZN9test5_B317funcB31Ev to i8*), i8* null, i8* inttoptr (i64 -24 to i8*), i8* bitcast (%2* @_ZTI7test5_D to i8*), i8* bitcast (void (%class.test14*)* @_ZN4B2328funcB232Ev to i8*), i8* null, i8* inttoptr (i64 -32 to i8*), i8* bitcast (%2* @_ZTI7test5_D to i8*), i8* bitcast (void (%class.test14*)* @_ZN4B2318funcB231Ev to i8*)]
+
+struct test8_B1 {
+  virtual void ftest8_B1() { }
+};
+struct test8_B2aa {
+  virtual void ftest8_B2aa() { }
+  int i;
+};
+struct test8_B2ab {
+  virtual void ftest8_B2ab() { }
+  int i;
+};
+struct test8_B2a : virtual test8_B2aa, virtual test8_B2ab {
+  virtual void ftest8_B2a() { }
+};
+struct test8_B2b {
+  virtual void ftest8_B2b() { }
+};
+struct test8_B2 : test8_B2a, test8_B2b {
+  virtual void ftest8_B2() { }
+};
+struct test8_B3 {
+  virtual void ftest8_B3() { }
+};
+class test8_D : test8_B1, test8_B2, test8_B3 {
+};
+
+// CHECK-LPLL64:@_ZTV7test8_D = weak_odr constant [25 x i8*] [i8* inttoptr (i64 48 to i8*), i8* inttoptr (i64 32 to i8*), i8* null, i8* bitcast (%2* @_ZTI7test8_D to i8*), i8* bitcast (void (%class.test14*)* @_ZN8test8_B19ftest8_B1Ev to i8*), i8* inttoptr (i64 40 to i8*), i8* inttoptr (i64 24 to i8*), i8* inttoptr (i64 -8 to i8*), i8* bitcast (%2* @_ZTI7test8_D to i8*), i8* bitcast (void (%struct.test10_B2a*)* @_ZN9test8_B2a10ftest8_B2aEv to i8*), i8* bitcast (void (%struct.test15_D*)* @_ZN8test8_B29ftest8_B2Ev to i8*), i8* inttoptr (i64 -16 to i8*), i8* bitcast (%2* @_ZTI7test8_D to i8*), i8* bitcast (void (%class.test14*)* @_ZN9test8_B2b10ftest8_B2bEv to i8*), i8* inttoptr (i64 -24 to i8*), i8* bitcast (%2* @_ZTI7test8_D to i8*), i8* bitcast (void (%class.test14*)* @_ZN8test8_B39ftest8_B3Ev to i8*), i8* null, i8* inttoptr (i64 -32 to i8*), i8* bitcast (%2* @_ZTI7test8_D to i8*), i8* bitcast (void (%struct.B*)* @_ZN10test8_B2aa11ftest8_B2aaEv to i8*), i8* null, i8* inttoptr (i64 -48 to i8*), i8* bitcast (%2* @_ZTI7test8_D to i8*), i8* bitcast (void (%struct.B*)* @_ZN10test8_B2ab11ftest8_B2abEv to i8*)]
+
+// CHECK-LPLL64:@_ZTC7test8_D8_8test8_B2 = internal constant [14 x i8*] [i8* inttoptr (i64 40 to i8*), i8* inttoptr (i64 24 to i8*), i8* null, i8* bitcast (%1* @_ZTI8test8_B2 to i8*), i8* bitcast (void (%struct.test10_B2a*)* @_ZN9test8_B2a10ftest8_B2aEv to i8*), i8* bitcast (void (%struct.test15_D*)* @_ZN8test8_B29ftest8_B2Ev to i8*), i8* null, i8* inttoptr (i64 -24 to i8*), i8* bitcast (%1* @_ZTI8test8_B2 to i8*), i8* bitcast (void (%struct.B*)* @_ZN10test8_B2aa11ftest8_B2aaEv to i8*), i8* null, i8* inttoptr (i64 -40 to i8*), i8* bitcast (%1* @_ZTI8test8_B2 to i8*), i8* bitcast (void (%struct.B*)* @_ZN10test8_B2ab11ftest8_B2abEv to i8*)] ; <[14 x i8*]*> [#uses=3]
+
+// CHECK-LPLL64:@_ZTC7test8_D8_9test8_B2a = internal constant [13 x i8*] [i8* inttoptr (i64 40 to i8*), i8* inttoptr (i64 24 to i8*), i8* null, i8* bitcast (%1* @_ZTI9test8_B2a to i8*), i8* bitcast (void (%struct.test10_B2a*)* @_ZN9test8_B2a10ftest8_B2aEv to i8*), i8* null, i8* inttoptr (i64 -24 to i8*), i8* bitcast (%1* @_ZTI9test8_B2a to i8*), i8* bitcast (void (%struct.B*)* @_ZN10test8_B2aa11ftest8_B2aaEv to i8*), i8* null, i8* inttoptr (i64 -40 to i8*), i8* bitcast (%1* @_ZTI9test8_B2a to i8*), i8* bitcast (void (%struct.B*)* @_ZN10test8_B2ab11ftest8_B2abEv to i8*)] ; <[13 x i8*]*> [#uses=3]
+
+// CHECK-LPLL64:@_ZTT7test8_D = weak_odr constant [10 x i8*] [i8* bitcast (i8** getelementptr inbounds ([25 x i8*]* @_ZTV7test8_D, i64 0, i64 4) to i8*), i8* bitcast (i8** getelementptr inbounds ([14 x i8*]* @_ZTC7test8_D8_8test8_B2, i64 0, i64 4) to i8*), i8* bitcast (i8** getelementptr inbounds ([13 x i8*]* @_ZTC7test8_D8_9test8_B2a, i64 0, i64 4) to i8*), i8* bitcast (i8** getelementptr inbounds ([13 x i8*]* @_ZTC7test8_D8_9test8_B2a, i64 0, i64 8) to i8*), i8* bitcast (i8** getelementptr inbounds ([13 x i8*]* @_ZTC7test8_D8_9test8_B2a, i64 0, i64 12) to i8*), i8* bitcast (i8** getelementptr inbounds ([14 x i8*]* @_ZTC7test8_D8_8test8_B2, i64 0, i64 9) to i8*), i8* bitcast (i8** getelementptr inbounds ([14 x i8*]* @_ZTC7test8_D8_8test8_B2, i64 0, i64 13) to i8*), i8* bitcast (i8** getelementptr inbounds ([25 x i8*]* @_ZTV7test8_D, i64 0, i64 9) to i8*), i8* bitcast (i8** getelementptr inbounds ([25 x i8*]* @_ZTV7test8_D, i64 0, i64 20) to i8*), i8* bitcast (i8** getelementptr inbounds ([25 x i8*]* @_ZTV7test8_D, i64 0, i64 24) to i8*)]
+
+
+struct test9_B3 { virtual void funcB3(); int i; };
+struct test9_B2 : virtual test9_B3 { virtual void funcB2(); int i; };
+struct test9_B1 : virtual test9_B2 { virtual void funcB1(); int i; };
+
+struct test9_B23 { virtual void funcB23(); int i; };
+struct test9_B22 : virtual test9_B23 { virtual void funcB22(); int i; };
+struct test9_B21 : virtual test9_B22 { virtual void funcB21(); int i; };
+
+
+struct test9_B232 { virtual void funcB232(); int i; };
+struct test9_B231 { virtual void funcB231(); int i; };
+
+struct test9_B33 { virtual void funcB33(); int i; };
+struct test9_B32 : virtual test9_B33, virtual test9_B232 { virtual void funcB32(); int i; };
+struct test9_B31 : virtual test9_B32, virtual test9_B231 { virtual void funcB31(); int i; };
+
+struct test9_D  : virtual test9_B1, virtual test9_B21, virtual test9_B31 {
+  virtual void funcD() { }
+};
+
+// CHECK-LPLL64:@_ZTV7test9_D = weak_odr constant [70 x i8*] [i8* inttoptr (i64 168 to i8*), i8* inttoptr (i64 152 to i8*), i8* inttoptr (i64 136 to i8*), i8* inttoptr (i64 120 to i8*), i8* inttoptr (i64 104 to i8*), i8* inttoptr (i64 88 to i8*), i8* inttoptr (i64 72 to i8*), i8* inttoptr (i64 56 to i8*), i8* inttoptr (i64 40 to i8*), i8* inttoptr (i64 24 to i8*), i8* inttoptr (i64 8 to i8*), i8* null, i8* bitcast (%2* @_ZTI7test9_D to i8*), i8* bitcast (void (%struct.test9_D*)* @_ZN7test9_D5funcDEv to i8*), i8* null, i8* inttoptr (i64 32 to i8*), i8* inttoptr (i64 16 to i8*), i8* inttoptr (i64 -8 to i8*), i8* bitcast (%2* @_ZTI7test9_D to i8*), i8* bitcast (void (%struct.test9_B1*)* @_ZN8test9_B16funcB1Ev to i8*), i8* null, i8* inttoptr (i64 16 to i8*), i8* inttoptr (i64 -24 to i8*), i8* bitcast (%2* @_ZTI7test9_D to i8*), i8* bitcast (void (%struct.test13_B2*)* @_ZN8test9_B26funcB2Ev to i8*), i8* null, i8* inttoptr (i64 -40 to i8*), i8* bitcast (%2* @_ZTI7test9_D to i8*), i8* bitcast (void (%struct.B*)* @_ZN8test9_B36funcB3Ev to i8*), i8* null, i8* inttoptr (i64 32 to i8*), i8* inttoptr (i64 16 to i8*), i8* inttoptr (i64 -56 to i8*), i8* bitcast (%2* @_ZTI7test9_D to i8*), i8* bitcast (void (%struct.test9_B1*)* @_ZN9test9_B217funcB21Ev to i8*), i8* null, i8* inttoptr (i64 16 to i8*), i8* inttoptr (i64 -72 to i8*), i8* bitcast (%2* @_ZTI7test9_D to i8*), i8* bitcast (void (%struct.test13_B2*)* @_ZN9test9_B227funcB22Ev to i8*), i8* null, i8* inttoptr (i64 -88 to i8*), i8* bitcast (%2* @_ZTI7test9_D to i8*), i8* bitcast (void (%struct.B*)* @_ZN9test9_B237funcB23Ev to i8*), i8* null, i8* inttoptr (i64 64 to i8*), i8* inttoptr (i64 48 to i8*), i8* inttoptr (i64 32 to i8*), i8* inttoptr (i64 16 to i8*), i8* inttoptr (i64 -104 to i8*), i8* bitcast (%2* @_ZTI7test9_D to i8*), i8* bitcast (void (%struct.test9_B31*)* @_ZN9test9_B317funcB31Ev to i8*), i8* null, i8* inttoptr (i64 32 to i8*), i8* inttoptr (i64 16 to i8*), i8* inttoptr (i64 -120 to i8*), i8* bitcast (%2* @_ZTI7test9_D to i8*), i8* bitcast (void (%struct.test9_B1*)* @_ZN9test9_B327funcB32Ev to i8*), i8* null, i8* inttoptr (i64 -136 to i8*), i8* bitcast (%2* @_ZTI7test9_D to i8*), i8* bitcast (void (%struct.B*)* @_ZN9test9_B337funcB33Ev to i8*), i8* null, i8* inttoptr (i64 -152 to i8*), i8* bitcast (%2* @_ZTI7test9_D to i8*), i8* bitcast (void (%struct.B*)* @_ZN10test9_B2328funcB232Ev to i8*), i8* null, i8* inttoptr (i64 -168 to i8*), i8* bitcast (%2* @_ZTI7test9_D to i8*), i8* bitcast (void (%struct.B*)* @_ZN10test9_B2318funcB231Ev to i8*)] ; <[70 x i8*]*> [#uses=12]
+
+
+struct test10_O { int i; };
+
+struct test10_B1 : virtual test10_O {
+  virtual void ftest10_B1() { }
+};
+
+struct test10_B2aa : virtual test10_O {
+  int i;
+};
+struct test10_B2ab : virtual test10_O {
+  int i;
+};
+struct test10_B2a : virtual test10_B2aa, virtual test10_B2ab,virtual test10_O {
+  virtual void ftest10_B2a() { }
+};
+struct test10_B2b : virtual test10_O {
+  virtual void ftest10_B2b() { }
+};
+struct test10_B2 : test10_B2a {
+  virtual void ftest10_B2() { }
+};
+class test10_D : test10_B1, test10_B2 {
+  
+  void ftest10_B2aa() { }
+};
+
+// CHECK-LPLL64:@_ZTV8test10_D = weak_odr constant [19 x i8*] [i8* inttoptr (i64 40 to i8*), i8* inttoptr (i64 24 to i8*), i8* inttoptr (i64 16 to i8*), i8* null, i8* bitcast (%1* @_ZTI8test10_D to i8*), i8* bitcast (void (%struct.test10_B1*)* @_ZN9test10_B110ftest10_B1Ev to i8*), i8* inttoptr (i64 32 to i8*), i8* inttoptr (i64 8 to i8*), i8* inttoptr (i64 16 to i8*), i8* inttoptr (i64 -8 to i8*), i8* bitcast (%1* @_ZTI8test10_D to i8*), i8* bitcast (void (%struct.test10_B2a*)* @_ZN10test10_B2a11ftest10_B2aEv to i8*), i8* bitcast (void (%struct.test10_B2*)* @_ZN9test10_B210ftest10_B2Ev to i8*), i8* inttoptr (i64 -8 to i8*), i8* inttoptr (i64 -24 to i8*), i8* bitcast (%1* @_ZTI8test10_D to i8*), i8* inttoptr (i64 -24 to i8*), i8* inttoptr (i64 -40 to i8*), i8* bitcast (%1* @_ZTI8test10_D to i8*)] ; <[19 x i8*]*> [#uses=4]
+
+
+struct test11_B {
+  virtual void B1() { }
+  virtual void D() { }
+  virtual void B2() { }
+};
+
+struct test11_D : test11_B {
+  virtual void D1() { }
+  virtual void D() { }
+  virtual void D2() { }
+};
+
+// CHECK-LPLL64:@_ZTV8test11_D = weak_odr constant [7 x i8*] [i8* null, i8* bitcast (%4* @_ZTI8test11_D to i8*), i8* bitcast (void (%class.test14*)* @_ZN8test11_B2B1Ev to i8*), i8* bitcast (void (%class.test17_B2*)* @_ZN8test11_D1DEv to i8*), i8* bitcast (void (%class.test14*)* @_ZN8test11_B2B2Ev to i8*), i8* bitcast (void (%class.test17_B2*)* @_ZN8test11_D2D1Ev to i8*), i8* bitcast (void (%class.test17_B2*)* @_ZN8test11_D2D2Ev to i8*)]
+
+
+struct test13_B {
+  virtual void B1() { }
+  virtual void D() { }
+  virtual void Da();
+  virtual void Db() { }
+  virtual void Dc() { }
+  virtual void B2() { }
+  int i;
+};
+
+
+struct test13_NV1 {
+  virtual void fooNV1() { }
+  virtual void D() { }
+};
+
+
+struct test13_B2 : /* test13_NV1, */ virtual test13_B {
+  virtual void B2a() { }
+  virtual void B2() { }
+  virtual void D() { }
+  virtual void Da();
+  virtual void Dd() { }
+  virtual void B2b() { }
+  int i;
+};
+
+
+struct test13_D : test13_NV1, virtual test13_B2 {
+  virtual void D1() { }
+  virtual void D() { }
+  virtual void Db() { }
+  virtual void Dd() { }
+  virtual void D2() { }
+  virtual void fooNV1() { }
+};
+
+// CHECK-LPLL64:@_ZTV8test13_D = weak_odr constant [39 x i8*] [i8* inttoptr (i64 24 to i8*), i8* inttoptr (i64 8 to i8*), i8* null, i8* bitcast (%1* @_ZTI8test13_D to i8*), i8* bitcast (void (%struct.test10_B2*)* @_ZN8test13_D6fooNV1Ev to i8*), i8* bitcast (void (%struct.test10_B2*)* @_ZN8test13_D1DEv to i8*), i8* bitcast (void (%struct.test10_B2*)* @_ZN8test13_D2D1Ev to i8*), i8* bitcast (void (%struct.test10_B2*)* @_ZN8test13_D2DbEv to i8*), i8* bitcast (void (%struct.test10_B2*)* @_ZN8test13_D2DdEv to i8*), i8* bitcast (void (%struct.test10_B2*)* @_ZN8test13_D2D2Ev to i8*), i8* null, i8* inttoptr (i64 -8 to i8*), i8* null, i8* inttoptr (i64 -8 to i8*), i8* null, i8* null, i8* inttoptr (i64 16 to i8*), i8* inttoptr (i64 -8 to i8*), i8* bitcast (%1* @_ZTI8test13_D to i8*), i8* bitcast (void (%struct.test13_B2*)* @_ZN9test13_B23B2aEv to i8*), i8* bitcast (void (%struct.test13_B2*)* @_ZN9test13_B22B2Ev to i8*), i8* bitcast (void (%struct.test10_B2*)* @_ZTv0_n48_N8test13_D1DEv to i8*), i8* bitcast (void (%struct.test13_B2*)* @_ZN9test13_B22DaEv to i8*), i8* bitcast (void (%struct.test10_B2*)* @_ZTv0_n64_N8test13_D2DdEv to i8*), i8* bitcast (void (%struct.test13_B2*)* @_ZN9test13_B23B2bEv to i8*), i8* inttoptr (i64 -16 to i8*), i8* null, i8* inttoptr (i64 -24 to i8*), i8* inttoptr (i64 -16 to i8*), i8* inttoptr (i64 -24 to i8*), i8* null, i8* inttoptr (i64 -24 to i8*), i8* bitcast (%1* @_ZTI8test13_D to i8*), i8* bitcast (void (%struct.B*)* @_ZN8test13_B2B1Ev to i8*), i8* bitcast (void (%struct.test10_B2*)* @_ZTv0_n32_N8test13_D1DEv to i8*), i8* bitcast (void (%struct.test13_B2*)* @_ZTv0_n40_N9test13_B22DaEv to i8*), i8* bitcast (void (%struct.test10_B2*)* @_ZTv0_n48_N8test13_D2DbEv to i8*), i8* bitcast (void (%struct.B*)* @_ZN8test13_B2DcEv to i8*), i8* bitcast (void (%struct.test13_B2*)* @_ZTv0_n64_N9test13_B22B2Ev to i8*)]
+
+
+class test14 {
+public:
+    virtual void initWithInt(int a);
+    static test14 *withInt(int a);
+};
+
+void test14::initWithInt(int a) { }
+
+test14 *test14::withInt(int a) {
+  test14 *me = new test14;
+  me->initWithInt(a);
+  return me;
+}
+
+
+struct test15_B {
+  virtual test15_B *foo1() { return 0; }
+  virtual test15_B *foo2() { return 0; }
+  virtual test15_B *foo3() { return 0; }
+  int i;
+};
+
+struct test15_NV1 {
+  virtual void fooNV1() { }
+  int i;
+};
+
+struct test15_B2 : test15_NV1, virtual test15_B {
+  virtual test15_B2 *foo1() { return 0; }
+  virtual test15_B2 *foo2() { return 0; }
+  int i;
+};
+
+struct test15_D : test15_NV1, virtual test15_B2 {
+  virtual test15_D *foo1() { return 0; }
+};
+
+// CHECK-LPLL64:@_ZTV8test15_D = weak_odr constant [23 x i8*] [i8* inttoptr (i64 32 to i8*), i8* inttoptr (i64 16 to i8*), i8* null, i8* bitcast (%1* @_ZTI8test15_D to i8*), i8* bitcast (void (%struct.B*)* @_ZN10test15_NV16fooNV1Ev to i8*), i8* bitcast (%struct.test15_D* (%struct.test15_D*)* @_ZN8test15_D4foo1Ev to i8*), i8* null, i8* inttoptr (i64 -16 to i8*), i8* null, i8* inttoptr (i64 16 to i8*), i8* inttoptr (i64 -16 to i8*), i8* bitcast (%1* @_ZTI8test15_D to i8*), i8* bitcast (void (%struct.B*)* @_ZN10test15_NV16fooNV1Ev to i8*), i8* bitcast (%struct.test15_D* (%struct.test15_D*)* @_ZTcv0_n40_v0_n24_N8test15_D4foo1Ev to i8*), i8* bitcast (%struct.test15_B2* (%struct.test15_B2*)* @_ZN9test15_B24foo2Ev to i8*), i8* null, i8* inttoptr (i64 -16 to i8*), i8* inttoptr (i64 -32 to i8*), i8* inttoptr (i64 -32 to i8*), i8* bitcast (%1* @_ZTI8test15_D to i8*), i8* bitcast (%struct.test15_D* (%struct.test15_D*)* @_ZTcv0_n24_v0_n32_N8test15_D4foo1Ev to i8*), i8* bitcast (%struct.test15_B2* (%struct.test15_B2*)* @_ZTcv0_n32_v0_n24_N9test15_B24foo2Ev to i8*), i8* bitcast (%struct.B* (%struct.B*)* @_ZN8test15_B4foo3Ev to i8*)]
+
+
+struct test16_NV1 {
+  virtual void fooNV1() { }
+virtual void foo_NV1() { }
+  int i;
+};
+
+struct test16_NV2 {
+  virtual test16_NV2* foo1() { return 0; }
+virtual void foo_NV2() { }
+virtual void foo_NV2b() { }
+  int i;
+};
+
+struct test16_B : public test16_NV1, test16_NV2 {
+  virtual test16_B *foo1() { return 0; }
+  virtual test16_B *foo2() { return 0; }
+  virtual test16_B *foo3() { return 0; }
+virtual void foo_B() { }
+  int i;
+};
+
+struct test16_B2 : test16_NV1, virtual test16_B {
+  virtual test16_B2 *foo1() { return 0; }
+  virtual test16_B2 *foo2() { return 0; }
+virtual void foo_B2() { }
+  int i;
+};
+
+struct test16_D : test16_NV1, virtual test16_B2 {
+  virtual void bar() { }
+  virtual test16_D *foo1() { return 0; }
+};
+
+// FIXME:
+// CHECK-LP64: __ZTV8test16_D:
+// CHECK-LP64-NEXT: .quad 32
+// CHECK-LP64-NEXT: .quad 16
+// CHECK-LP64-NEXT: .quad 0
+// CHECK-LP64-NEXT: .quad __ZTI8test16_D
+// CHECK-LP64-NEXT: .quad __ZN10test16_NV16fooNV1Ev
+// CHECK-LP64-NEXT: .quad __ZN10test16_NV17foo_NV1Ev
+// CHECK-LP64-NEXT: .quad __ZN8test16_D3barEv
+// CHECK-LP64-NEXT: .quad __ZN8test16_D4foo1Ev
+// CHECK-LP64-NEXT: .quad 0
+// CHECK-LP64-NEXT: .quad 0
+// CHECK-LP64-NEXT: .quad -16
+// CHECK-LP64-NEXT: .quad 0
+// CHECK-LP64-NEXT: .quad 0
+// CHECK-LP64-NEXT: .quad 16
+// CHECK-LP64-NEXT: .quad -16
+// CHECK-LP64-NEXT: .quad __ZTI8test16_D
+// CHECK-LP64-NEXT: .quad __ZN10test16_NV16fooNV1Ev
+// CHECK-LP64-NEXT: .quad __ZN10test16_NV17foo_NV1Ev
+// CHECK-LP64-NEXT: .quad __ZTcv0_n48_v0_n24_N8test16_D4foo1Ev
+// CHECK-LP64-NEXT: .quad __ZN9test16_B24foo2Ev
+// CHECK-LP64-NEXT: .quad __ZN9test16_B26foo_B2Ev
+// CHECK-LP64-NEXT: .quad 16
+// CHECK-LP64-NEXT: .quad 16
+// CHECK-LP64-NEXT: .quad 0
+// CHECK-LP64-NEXT: .quad 0
+// CHECK-LP64-NEXT: .quad -16
+// CHECK-LP64-NEXT: .quad -32
+// CHECK-LP64-NEXT: .quad 0
+// CHECK-LP64-NEXT: .quad 0
+// CHECK-LP64-NEXT: .quad -32
+// CHECK-LP64-NEXT: .quad __ZTI8test16_D
+// CHECK-LP64-NEXT: .quad __ZN10test16_NV16fooNV1Ev
+// CHECK-LP64-NEXT: .quad __ZN10test16_NV17foo_NV1Ev
+// CHECK-LP64-NEXT: .quad __ZTcv0_n40_v0_n32_N8test16_D4foo1Ev
+// CHECK-LP64-NEXT: .quad __ZTcv0_n48_v0_n24_N9test16_B24foo2Ev
+// CHECK-LP64-NEXT: .quad __ZN8test16_B4foo3Ev
+// CHECK-LP64-NEXT: .quad __ZN8test16_B5foo_BEv
+// CHECK-LP64-NEXT: .quad -48
+// CHECK-LP64-NEXT: .quad __ZTI8test16_D
+// CHECK-LP64-NEXT: .quad __ZTcvn16_n40_v16_n32_N8test16_D4foo1Ev
+// CHECK-LP64-NEXT: .quad __ZN10test16_NV27foo_NV2Ev
+// CHECK-LP64-NEXT: .quad __ZN10test16_NV28foo_NV2bEv
+
+
+
+
+class test17_B1 {
+  virtual void foo() = 0;
+  virtual void bar() { }
+};
+
+class test17_B2 : public test17_B1 {
+  void foo() { }
+  virtual void bar() = 0;
+};
+
+class test17_D : public test17_B2 {
+  void bar() { }
+};
+
+
+// CHECK-LPLL64:@_ZTV8test17_D = weak_odr constant [4 x i8*] [i8* null, i8* bitcast (%4* @_ZTI8test17_D to i8*), i8* bitcast (void (%class.test17_B2*)* @_ZN9test17_B23fooEv to i8*), i8* bitcast (void (%class.test17_B2*)* @_ZN8test17_D3barEv to i8*)]
+
+// CHECK-LPLL64:@_ZTV9test17_B2 = weak_odr constant [4 x i8*] [i8* null, i8* bitcast (%4* @_ZTI9test17_B2 to i8*), i8* bitcast (void (%class.test17_B2*)* @_ZN9test17_B23fooEv to i8*), i8* bitcast (void ()* @__cxa_pure_virtual to i8*)]
+
+// CHECK-LPLL64:@_ZTV9test17_B1 = weak_odr constant [4 x i8*] [i8* null, i8* bitcast (%0* @_ZTI9test17_B1 to i8*), i8* bitcast (void ()* @__cxa_pure_virtual to i8*), i8* bitcast (void (%class.test14*)* @_ZN9test17_B13barEv to i8*)]
+
+
+struct test18_NV1 {
+  virtual void fooNV1() { }
+virtual void foo_NV1() { }
+  int i;
+};
+
+struct test18_NV2 {
+  virtual test18_NV2& foo1() { return *this; }
+virtual void foo_NV2() { }
+virtual void foo_NV2b() { }
+  int i;
+};
+
+struct test18_B : public test18_NV1, test18_NV2 {
+  virtual test18_B& foo1() { return *this; }
+  virtual test18_B *foo2() { return 0; }
+  virtual test18_B *foo3() { return 0; }
+virtual void foo_B() { }
+  int i;
+};
+
+struct test18_B2 : test18_NV1, virtual test18_B {
+  virtual test18_B2& foo1() { return *this; }
+  virtual test18_B2 *foo2() { return 0; }
+virtual void foo_B2() { }
+  int i;
+};
+
+struct test18_D : test18_NV1, virtual test18_B2 {
+  virtual test18_D& foo1() { return *this; }
+};
+
+
+struct test19_VB1 { };
+struct test19_B1 : public virtual test19_VB1 {
+  virtual void fB1() { }
+  virtual void foB1B2() { }
+  virtual void foB1B3() { }
+  virtual void foB1B4() { }
+};
+
+struct test19_VB2 { };
+struct test19_B2: public test19_B1, public virtual test19_VB2 {
+  virtual void foB1B2() { }
+  virtual void foB1B3() { }
+  virtual void foB1B4() { }
+
+  virtual void fB2() { }
+  virtual void foB2B3() { }
+  virtual void foB2B4() { }
+};
+
+struct test19_VB3 { };
+struct test19_B3: virtual public test19_B2, public virtual test19_VB3 {
+  virtual void foB1B3() { }
+  virtual void foB1B4() { }
+
+  virtual void foB2B3() { }
+  virtual void foB2B4() { }
+
+  virtual void fB3() { }
+  virtual void foB3B4() { }
+};
+
+struct test19_VB4 { };
+struct test19_B4: public test19_B3, public virtual test19_VB4 {
+  virtual void foB1B4() { }
+
+  virtual void foB2B4() { }
+
+  virtual void foB3B4() { }
+
+  virtual void fB4() { }
+};
+
+struct test19_D : virtual test19_B4 {
+};
+
+
+// CHECK-LPLL64:@_ZTV8test19_D = weak_odr constant [28 x i8*] [i8* null, i8* null, i8* null, i8* null, i8* null, i8* null, i8* null, i8* null, i8* null, i8* null, i8* null, i8* null, i8* null, i8* null, i8* null, i8* null, i8* null, i8* bitcast (%3* @_ZTI8test19_D to i8*), i8* bitcast (void (%class.test14*)* @_ZN9test19_B13fB1Ev to i8*), i8* bitcast (void (%class.test17_B2*)* @_ZN9test19_B26foB1B2Ev to i8*), i8* bitcast (void (%class.test17_B2*)* @_ZN9test19_B36foB1B3Ev to i8*), i8* bitcast (void (%class.test17_B2*)* @_ZN9test19_B46foB1B4Ev to i8*), i8* bitcast (void (%class.test17_B2*)* @_ZN9test19_B23fB2Ev to i8*), i8* bitcast (void (%class.test17_B2*)* @_ZN9test19_B36foB2B3Ev to i8*), i8* bitcast (void (%class.test17_B2*)* @_ZN9test19_B46foB2B4Ev to i8*), i8* bitcast (void (%class.test17_B2*)* @_ZN9test19_B33fB3Ev to i8*), i8* bitcast (void (%class.test17_B2*)* @_ZN9test19_B46foB3B4Ev to i8*), i8* bitcast (void (%class.test17_B2*)* @_ZN9test19_B43fB4Ev to i8*)]
+
+// FIXME:
+// CHECK-LP64:     __ZTT8test19_D:
+// CHECK-LP64-NEXT: .quad __ZTV8test19_D+144
+// CHECK-LP64-NEXT: .quad __ZTV8test19_D+144
+// CHECK-LP64-NEXT .quad __ZTV8test19_D+144
+// CHECK-LP64-NEXT .quad __ZTC8test19_D0_9test19_B4+136
+// CHECK-LP64-NEXT .quad __ZTC8test19_D0_9test19_B3+104
+// CHECK-LP64-NEXT .quad __ZTC8test19_D0_9test19_B3+104
+// CHECK-LP64-NEXT .quad __ZTC8test19_D0_9test19_B4+136
+// CHECK-LP64-NEXT .quad __ZTC8test19_D0_9test19_B2+88
+// CHECK-LP64-NEXT .quad __ZTC8test19_D0_9test19_B1+24
+
+class test20_V {
+  virtual void foo1();
+};
+class test20_V1 {
+  virtual void foo2();
+};
+class test20_B : virtual test20_V {
+} b;
+class test20_B1 : virtual test20_V1 {
+};
+class test20_D : public test20_B, public test20_B1 {
+};
+
+// CHECK-LPLL64:@_ZTV8test20_D = weak_odr constant [11 x i8*] [i8* inttoptr (i64 8 to i8*), i8* null, i8* null, i8* null, i8* bitcast (%1* @_ZTI8test20_D to i8*), i8* bitcast (void (%class.test14*)* @_ZN8test20_V4foo1Ev to i8*), i8* null, i8* null, i8* inttoptr (i64 -8 to i8*), i8* bitcast (%1* @_ZTI8test20_D to i8*), i8* bitcast (void (%class.test14*)* @_ZN9test20_V14foo2Ev to i8*)]
+
+// CHECK-LPLL64:@_ZTC8test20_D0_8test20_B = internal constant [5 x i8*] [i8* null, i8* null, i8* null, i8* bitcast (%3* @_ZTI8test20_B to i8*), i8* bitcast (void (%class.test14*)* @_ZN8test20_V4foo1Ev to i8*)]
+
+// CHECK-LPLL64:@_ZTC8test20_D8_9test20_B1 = internal constant [5 x i8*] [i8* null, i8* null, i8* null, i8* bitcast (%3* @_ZTI9test20_B1 to i8*), i8* bitcast (void (%class.test14*)* @_ZN9test20_V14foo2Ev to i8*)] ; <[5 x i8*]*> [#uses=1]
+
+// FIXME: 
+// CHECK-LP64:     __ZTT8test20_D:
+// CHECK-LP64-NEXT: .quad __ZTV8test20_D+40
+// CHECK-LP64-NEXT: .quad __ZTC8test20_D0_8test20_B+32
+// CHECK-LP64-NEXT: .quad __ZTC8test20_D0_8test20_B+32
+// CHECK-LP64-NEXT: .quad __ZTC8test20_D8_9test20_B1+32
+// CHECK-LP64-NEXT: .quad __ZTC8test20_D8_9test20_B1+32
+// CHECK-LP64-NEXT .quad __ZTV8test20_D+40
+// CHECK-LP64-NEXT .quad __ZTV8test20_D+80
+// CHECK-LP64-NEXT .quad __ZTV8test20_D+80
+
+
+class test21_V {
+  virtual void foo() { }
+};
+class test21_V1 {
+  virtual void foo() { }
+};
+class test21_B : virtual test21_V {
+};
+class test21_B1 : virtual test21_V1 {
+};
+class test21_D : public test21_B, public test21_B1 {
+  void foo() { }
+};
+
+// CHECK-LPLL64:@_ZTV8test21_D = weak_odr constant [11 x i8*] [i8* inttoptr (i64 8 to i8*), i8* null, i8* null, i8* null, i8* bitcast (%1* @_ZTI8test21_D to i8*), i8* bitcast (void (%class.test20_D*)* @_ZN8test21_D3fooEv to i8*), i8* null, i8* inttoptr (i64 -8 to i8*), i8* inttoptr (i64 -8 to i8*), i8* bitcast (%1* @_ZTI8test21_D to i8*), i8* bitcast (void (%class.test20_D*)* @_ZTv0_n24_N8test21_D3fooEv to i8*)]
+
+// CHECK-LPLL64:@_ZTC8test21_D0_8test21_B = internal constant [5 x i8*] [i8* null, i8* null, i8* null, i8* bitcast (%3* @_ZTI8test21_B to i8*), i8* bitcast (void (%class.test14*)* @_ZN8test21_V3fooEv to i8*)]
+
+// CHECK-LPLL64:@_ZTC8test21_D8_9test21_B1 = internal constant [5 x i8*] [i8* null, i8* null, i8* null, i8* bitcast (%3* @_ZTI9test21_B1 to i8*), i8* bitcast (void (%class.test14*)* @_ZN9test21_V13fooEv to i8*)] ; <[5 x i8*]*> [#uses=1]
+
+// FIXME:
+// CHECK-LP64:     __ZTT8test21_D:
+// CHECK-LP64-NEXT: .quad __ZTV8test21_D+40
+// CHECK-LP64-NEXT: .quad __ZTC8test21_D0_8test21_B+32
+// CHECK-LP64-NEXT: .quad __ZTC8test21_D0_8test21_B+32
+// CHECK-LP64-NEXT: .quad __ZTC8test21_D8_9test21_B1+32
+// CHECK-LP64-NEXT: .quad __ZTC8test21_D8_9test21_B1+32
+// CHECK-LP64-NEXT .quad __ZTV8test21_D+40
+// CHECK-LP64-NEXT .quad __ZTV8test21_D+80
+// CHECK-LP64-NEXT .quad __ZTV8test21_D+80
+
+
+struct test22_s1 { virtual void dtor() { } }; 
+struct test22_s2 { virtual void dtor() { } }; 
+struct test22_s3 : test22_s1, test22_s2 { virtual void dtor() { } }; 
+struct test22_D : test22_s3 { virtual void dtor() { } }; 
+
+// CHECK-LPLL64:@_ZTV8test22_D = weak_odr constant [6 x i8*] [i8* null, i8* bitcast (%4* @_ZTI8test22_D to i8*), i8* bitcast (void (%class.test20_D*)* @_ZN8test22_D4dtorEv to i8*), i8* inttoptr (i64 -8 to i8*), i8* bitcast (%4* @_ZTI8test22_D to i8*), i8* bitcast (void (%class.test20_D*)* @_ZThn8_N8test22_D4dtorEv to i8*)]
+
+
+class test23_s1 {
+  virtual void fun1(char *t) { }
+};
+class test23_s2 {
+  virtual void fun2(char *t) { }
+};
+class test23_s3 {
+  virtual void fun3(char *t) { }
+};
+class test23_s4: virtual test23_s1, test23_s2, test23_s3 {
+  virtual void fun4(char *t) { }
+};
+class test23_D: virtual test23_s4 {
+  virtual void fun5(char *t) { }
+};
+
+
+// FIXME:
+// CHECK-LP64:     __ZTV8test23_D:
+// CHECK-LP64-NEXT:	.quad	0
+// CHECK-LP64-NEXT:	.quad	8
+// CHECK-LP64-NEXT:	.quad	0
+// CHECK-LP64-NEXT:	.quad	0
+// CHECK-LP64-NEXT:	.quad	__ZTI8test23_D
+// CHECK-LP64-NEXT:	.quad	__ZN9test23_s14fun1EPc
+// CHECK-LP64-NEXT:	.quad	__ZN8test23_D4fun5EPc
+// CHECK-LP64-NEXT	.quad	8
+// CHECK-LP64:  	.quad	0
+// CHECK-LP64-NEXT:	.quad	0
+// CHECK-LP64:  	.quad	-8
+// CHECK-LP64-NEXT:	.quad	-8
+// CHECK-LP64-NEXT:	.quad	__ZTI8test23_D
+// CHECK-LP64-NEXT:	.quad	__ZN9test23_s24fun2EPc
+// CHECK-LP64-NEXT:	.quad	__ZN9test23_s44fun4EPc
+// CHECK-LP64-NEXT:	.quad	-16
+// CHECK-LP64-NEXT:	.quad	__ZTI8test23_D
+// CHECK-LP64-NEXT:	.quad	__ZN9test23_s34fun3EPc
+
+
+test23_D d23;
+test22_D d22;
+test21_D d21;
+test20_D d20;
+test19_D d19;
+test18_D d18;
+test17_D d17;
+test16_D d16;
+test15_D d15;
+test13_D d13;
+test11_D d11;
+test10_D d10;
+test9_D d9;
+test8_D d8;
+
+test5_D d5;
+test4_D d4;
+test3_D d3;
+
+test6_D d6;
+test7_D d7;
+
+
+int j;
+void *vp;
+void test2() {
+  F f;
+  static int sz = (char *)(&f.f) - (char *)(&f);
+  vp = &sz;
+  j = sz;
+  // FIXME: These should result in a frontend constant a la fold, no run time
+  // initializer
+  // CHECK-LPLL64: define void @_Z5test2v()
+  // CHECK-LPLL64: = getelementptr inbounds %class.F* %f, i32 0, i32 1
+}
+
+static_assert(sizeof(F) == sizeof(void*)*4, "invalid vbase size");
+
+
+void test12_foo() {
+  test12_pa->foo0();
+  test12_pb->foo0();
+  test12_pd->foo0();
+  test12_pa->foo();
+  test12_pb->foo();
+  test12_pd->foo();
+  test12_pa->test12_A::foo();
+}
+
+
+// CHECK-LPLL64:define void @_Z10test12_foov() nounwind {
+// CHECK-LPLL64:  call void %
+// CHECK-LPLL64:  call void %
+// CHECK-LPLL64:  call void %
+// CHECK-LPLL64:  call void %
+// CHECK-LPLL64:  call void %
+// CHECK-LPLL64:  call void %
+// CHECK-LPLL64:  call void @_ZN8test12_A3fooEv(%class.test14* %{{.*}})
+
diff --git a/test/CodeGenCXX/virtual-base-cast.cpp b/test/CodeGenCXX/virtual-base-cast.cpp
new file mode 100644
index 0000000..73b7c1c
--- /dev/null
+++ b/test/CodeGenCXX/virtual-base-cast.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple i686-pc-linux-gnu | FileCheck %s
+
+struct A { int a; virtual int aa(); };
+struct B { int b; virtual int bb(); };
+struct C : virtual A, virtual B { int c; virtual int aa(); virtual int bb(); };
+struct AA { int a; virtual int aa(); };
+struct BB { int b; virtual int bb(); };
+struct CC : AA, BB { virtual int aa(); virtual int bb(); virtual int cc(); };
+struct D : virtual C, virtual CC { int e; };
+
+D* x;
+
+A* a() { return x; }
+// CHECK: @_Z1av() nounwind
+// CHECK: [[VBASEOFFSETPTRA:%[a-zA-Z0-9\.]+]] = getelementptr i8* {{.*}}, i64 -16
+// CHECK: [[CASTVBASEOFFSETPTRA:%[a-zA-Z0-9\.]+]] = bitcast i8* [[VBASEOFFSETPTRA]] to i32*
+// CHECK: load i32* [[CASTVBASEOFFSETPTRA]]
+// CHECK: }
+
+B* b() { return x; }
+// CHECK: @_Z1bv() nounwind
+// CHECK: [[VBASEOFFSETPTRA:%[a-zA-Z0-9\.]+]] = getelementptr i8* {{.*}}, i64 -20
+// CHECK: [[CASTVBASEOFFSETPTRA:%[a-zA-Z0-9\.]+]] = bitcast i8* [[VBASEOFFSETPTRA]] to i32*
+// CHECK: load i32* [[CASTVBASEOFFSETPTRA]]
+// CHECK: }
+
+BB* c() { return x; }
+// CHECK: @_Z1cv() nounwind
+// CHECK: [[VBASEOFFSETPTRC:%[a-zA-Z0-9\.]+]] = getelementptr i8* {{.*}}, i64 -24
+// CHECK: [[CASTVBASEOFFSETPTRC:%[a-zA-Z0-9\.]+]] = bitcast i8* [[VBASEOFFSETPTRC]] to i32*
+// CHECK: [[VBASEOFFSETC:%[a-zA-Z0-9\.]+]] = load i32* [[CASTVBASEOFFSETPTRC]]
+// CHECK: add i32 [[VBASEOFFSETC]], 8
+// CHECK: }
diff --git a/test/CodeGenCXX/virtual-base-ctor.cpp b/test/CodeGenCXX/virtual-base-ctor.cpp
new file mode 100644
index 0000000..2d81ebd
--- /dev/null
+++ b/test/CodeGenCXX/virtual-base-ctor.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - -O2 | FileCheck %s
+
+struct B;
+extern B x;
+char y;
+typedef __typeof(sizeof(int)) size_t;
+struct A { int a; A() { y = ((size_t)this - (size_t)&x) / sizeof(void*); } };
+struct B : virtual A { void* x; };    
+B x;
+
+// CHECK: @y = global i8 2
diff --git a/test/CodeGenCXX/virtual-base-destructor-call.cpp b/test/CodeGenCXX/virtual-base-destructor-call.cpp
new file mode 100644
index 0000000..7de9dd2
--- /dev/null
+++ b/test/CodeGenCXX/virtual-base-destructor-call.cpp
@@ -0,0 +1,51 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+
+struct basic_ios{~basic_ios(); };
+
+template<typename _CharT> struct basic_istream : virtual public basic_ios {
+  virtual ~basic_istream(){}
+};
+
+template<typename _CharT> struct basic_iostream : public basic_istream<_CharT>
+{
+  virtual ~basic_iostream(){}
+};
+
+basic_iostream<char> res;
+
+int main() {
+}
+
+// basic_iostream's complete dtor calls its base dtor, then its
+// virtual base's dtor.
+//  CHECK: define linkonce_odr void @_ZN14basic_iostreamIcED1Ev
+//  CHECK: call void @_ZN14basic_iostreamIcED2Ev
+//  CHECK: call void @_ZN9basic_iosD2Ev
+
+// basic_iostream's base dtor calls its non-virtual base dtor.
+//  CHECK: define linkonce_odr void @_ZN14basic_iostreamIcED2Ev
+//  CHECK: call void @_ZN13basic_istreamIcED2Ev
+//  CHECK: }
+
+// basic_iostream's deleting dtor calls its complete dtor, then
+// operator delete().
+//  CHECK: define linkonce_odr void @_ZN14basic_iostreamIcED0Ev
+//  CHECK: call void @_ZN14basic_iostreamIcED1Ev
+//  CHECK: call void @_ZdlPv
+
+// basic_istream's complete dtor calls the base dtor,
+// then its virtual base's base dtor.
+//  CHECK: define linkonce_odr void @_ZN13basic_istreamIcED1Ev
+//  CHECK: call void @_ZN13basic_istreamIcED2Ev
+//  CHECK: call void @_ZN9basic_iosD2Ev
+
+// basic_istream's deleting dtor calls the complete dtor, then
+// operator delete().
+//  CHECK: define linkonce_odr void @_ZN13basic_istreamIcED0Ev
+//  CHECK: call void @_ZN13basic_istreamIcED1Ev
+//  CHECK: call void @_ZdlPv
+
+// basic_istream's base dtor is a no-op.
+//  CHECK: define linkonce_odr void @_ZN13basic_istreamIcED2Ev
+//  CHECK-NOT: call
+//  CHECK: }
diff --git a/test/CodeGenCXX/virtual-bases.cpp b/test/CodeGenCXX/virtual-bases.cpp
new file mode 100644
index 0000000..61de315
--- /dev/null
+++ b/test/CodeGenCXX/virtual-bases.cpp
@@ -0,0 +1,48 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin10 -mconstructor-aliases | FileCheck %s
+
+struct A { 
+  A();
+};
+
+// CHECK: @_ZN1AC1Ev = alias {{.*}} @_ZN1AC2Ev
+// CHECK: define void @_ZN1AC2Ev(%struct.A* %this)
+A::A() { }
+
+struct B : virtual A { 
+  B();
+};
+
+// CHECK: define void @_ZN1BC1Ev(%struct.B* %this)
+// CHECK: define void @_ZN1BC2Ev(%struct.B* %this, i8** %vtt)
+B::B() { }
+
+struct C : virtual A {
+  C(bool);
+};
+
+// CHECK: define void @_ZN1CC1Eb(%struct.B* %this, i1 zeroext)
+// CHECK: define void @_ZN1CC2Eb(%struct.B* %this, i8** %vtt, i1 zeroext)
+C::C(bool) { }
+
+// PR6251
+namespace PR6251 {
+
+// Test that we don't call the A<char> constructor twice.
+
+template<typename T>
+struct A { A(); };
+
+struct B : virtual A<char> { };
+struct C : virtual A<char> { };
+
+struct D : B, C  {
+  D();
+};
+
+// CHECK: define void @_ZN6PR62511DC1Ev
+// CHECK: call void @_ZN6PR62511AIcEC2Ev
+// CHECK-NOT: call void @_ZN6PR62511AIcEC2Ev
+// CHECK: ret void
+D::D() { }
+
+}
diff --git a/test/CodeGenCXX/virtual-destructor-calls.cpp b/test/CodeGenCXX/virtual-destructor-calls.cpp
new file mode 100644
index 0000000..c5b9262
--- /dev/null
+++ b/test/CodeGenCXX/virtual-destructor-calls.cpp
@@ -0,0 +1,48 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin10 -mconstructor-aliases | FileCheck %s
+
+struct Member {
+  ~Member();
+};
+
+struct A {
+  virtual ~A();
+};
+
+struct B : A {
+  Member m;
+  virtual ~B();
+};
+
+// Complete dtor: just an alias because there are no virtual bases.
+// CHECK: @_ZN1BD1Ev = alias {{.*}} @_ZN1BD2Ev
+
+// (aliases from C)
+// CHECK: @_ZN1CD1Ev = alias {{.*}} @_ZN1CD2Ev
+// CHECK: @_ZN1CD2Ev = alias bitcast {{.*}} @_ZN1BD2Ev
+
+// Deleting dtor: defers to the complete dtor.
+// CHECK: define void @_ZN1BD0Ev
+// CHECK: call void @_ZN1BD1Ev
+// CHECK: call void @_ZdlPv
+
+// Base dtor: actually calls A's base dtor.
+// CHECK: define void @_ZN1BD2Ev
+// CHECK: call void @_ZN6MemberD1Ev
+// CHECK: call void @_ZN1AD2Ev
+
+B::~B() { }
+
+struct C : B {
+  ~C();
+};
+
+C::~C() { }
+
+// Complete dtor: just an alias (checked above).
+
+// Deleting dtor: defers to the complete dtor.
+// CHECK: define void @_ZN1CD0Ev
+// CHECK: call void @_ZN1CD1Ev
+// CHECK: call void @_ZdlPv
+
+// Base dtor: just an alias to B's base dtor.
diff --git a/test/CodeGenCXX/virtual-destructor-synthesis.cpp b/test/CodeGenCXX/virtual-destructor-synthesis.cpp
new file mode 100644
index 0000000..90f66a8
--- /dev/null
+++ b/test/CodeGenCXX/virtual-destructor-synthesis.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+
+struct box {
+  virtual ~box();
+};
+
+struct pile_box : public box {
+  pile_box(box *);
+};
+
+pile_box::pile_box(box *pp)
+{
+}
+
+// CHECK: call void @_ZdlPv
+
diff --git a/test/CodeGenCXX/virtual-function-calls.cpp b/test/CodeGenCXX/virtual-function-calls.cpp
new file mode 100644
index 0000000..46e7b2d
--- /dev/null
+++ b/test/CodeGenCXX/virtual-function-calls.cpp
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+
+// PR5021
+namespace PR5021 {
+
+struct A {
+  virtual void f(char);
+};
+
+void f(A *a) {
+  // CHECK: call void %
+  a->f('c');
+}
+
+struct B : virtual A { 
+  virtual void f();
+};
+
+void f(B * b) {
+  b->f();
+}
+
+}
+
+namespace Test1 {
+  struct A { 
+    virtual ~A(); 
+  };
+
+  struct B : A {
+    virtual ~B();
+    virtual void f();
+  };
+
+  void f(B *b) {
+    b->f();
+  }
+}
diff --git a/test/CodeGenCXX/virtual-functions-incomplete-types.cpp b/test/CodeGenCXX/virtual-functions-incomplete-types.cpp
new file mode 100644
index 0000000..50e0435
--- /dev/null
+++ b/test/CodeGenCXX/virtual-functions-incomplete-types.cpp
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+
+struct A;
+
+struct B {
+  virtual void f();
+  virtual A g();
+};
+
+void B::f() { }
+
+// CHECK: declare void @_ZN1B1gEv()
+
+struct C;
+
+struct D {
+  virtual void f();
+  virtual C g();
+};
+
+void D::f() { }
+
+struct C {
+  int a;
+};
+
+// CHECK: define i64 @_ZN1D1gEv(%struct.B* %this)
+C D::g() {
+  return C();
+}
diff --git a/test/CodeGenCXX/virtual-implicit-copy-assignment.cpp b/test/CodeGenCXX/virtual-implicit-copy-assignment.cpp
new file mode 100644
index 0000000..70bc6fc
--- /dev/null
+++ b/test/CodeGenCXX/virtual-implicit-copy-assignment.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+
+struct D;
+struct B {
+ virtual D& operator = (const D&);
+};
+struct D : B { D(); virtual void a(); };
+void D::a() {}
+
+// CHECK: @_ZTV1D = {{.*}} @_ZN1DaSERKS_ 
+// CHECK: define linkonce_odr {{.*}} @_ZN1DaSERKS_
diff --git a/test/CodeGenCXX/virtual-inherited-destructor.cpp b/test/CodeGenCXX/virtual-inherited-destructor.cpp
new file mode 100644
index 0000000..509d40a
--- /dev/null
+++ b/test/CodeGenCXX/virtual-inherited-destructor.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 %s -emit-llvm-only
+
+struct A { virtual ~A(); };
+struct B : A {
+  ~B() { }
+};
+B x;
+
diff --git a/test/CodeGenCXX/virtual-operator-call.cpp b/test/CodeGenCXX/virtual-operator-call.cpp
new file mode 100644
index 0000000..42d38e5
--- /dev/null
+++ b/test/CodeGenCXX/virtual-operator-call.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+
+struct A {
+  virtual int operator-() = 0;
+};
+
+void f(A *a) {
+  // CHECK: call i32 %
+  -*a;
+}
diff --git a/test/CodeGenCXX/virtual-pseudo-destructor-call.cpp b/test/CodeGenCXX/virtual-pseudo-destructor-call.cpp
new file mode 100644
index 0000000..285e3da
--- /dev/null
+++ b/test/CodeGenCXX/virtual-pseudo-destructor-call.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+
+struct A {
+  virtual ~A();
+};
+
+void f(A *a) {
+  // CHECK: call void %
+  a->~A();
+}
diff --git a/test/CodeGenCXX/visibility.cpp b/test/CodeGenCXX/visibility.cpp
new file mode 100644
index 0000000..5edd27b
--- /dev/null
+++ b/test/CodeGenCXX/visibility.cpp
@@ -0,0 +1,66 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+
+#define HIDDEN __attribute__((visibility("hidden")))
+#define PROTECTED __attribute__((visibility("protected")))
+#define DEFAULT __attribute__((visibility("default")))
+
+// CHECK: @_ZN5Test425VariableInHiddenNamespaceE = hidden global i32 10
+
+namespace Test1 {
+  // CHECK: define hidden void @_ZN5Test11fEv
+  void HIDDEN f() { }
+  
+}
+
+namespace Test2 {
+  struct HIDDEN A {
+    void f();
+  };
+
+  // A::f is a member function of a hidden class.
+  // CHECK: define hidden void @_ZN5Test21A1fEv
+  void A::f() { }
+}
+ 
+namespace Test3 {
+  struct HIDDEN A {
+    struct B {
+      void f();
+    };
+  };
+
+  // B is a nested class where its parent class is hidden.
+  // CHECK: define hidden void @_ZN5Test31A1B1fEv
+  void A::B::f() { }  
+}
+
+namespace Test4 HIDDEN {
+  int VariableInHiddenNamespace = 10;
+
+  // Test4::g is in a hidden namespace.
+  // CHECK: define hidden void @_ZN5Test41gEv
+  void g() { } 
+  
+  struct DEFAULT A {
+    void f();
+  };
+  
+  // A has default visibility.
+  // CHECK: define void @_ZN5Test41A1fEv
+  void A::f() { } 
+}
+
+namespace Test5 {
+
+  namespace NS HIDDEN {
+    // f is in NS which is hidden.
+    // CHECK: define hidden void @_ZN5Test52NS1fEv()
+    void f() { }
+  }
+  
+  namespace NS {
+    // g is in NS, but this NS decl is not hidden.
+    // CHECK: define void @_ZN5Test52NS1gEv
+    void g() { }
+  }
+}
diff --git a/test/CodeGenCXX/vtable-cast-crash.cpp b/test/CodeGenCXX/vtable-cast-crash.cpp
new file mode 100644
index 0000000..cc419fd
--- /dev/null
+++ b/test/CodeGenCXX/vtable-cast-crash.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -emit-llvm-only %s
+struct A
+{
+A();    
+virtual ~A();
+};
+
+struct B: A
+{
+  B();
+  ~B();
+};
+
+B::B()
+{
+}
+
+B::~B()
+{
+}
+                         
diff --git a/test/CodeGenCXX/vtable-key-function.cpp b/test/CodeGenCXX/vtable-key-function.cpp
new file mode 100644
index 0000000..97a546f
--- /dev/null
+++ b/test/CodeGenCXX/vtable-key-function.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+// PR5697
+namespace PR5697 {
+struct A {
+  virtual void f() { } 
+  A();
+  A(int);
+};
+
+// A does not have a key function, so the first constructor we emit should
+// cause the vtable to be defined (without assertions.)
+// CHECK: @_ZTVN6PR56971AE = weak_odr constant
+A::A() { }
+A::A(int) { }
+}
+
+// Make sure that we don't assert when building the vtable for a class
+// template specialization or explicit instantiation with a key
+// function.
+template<typename T>
+struct Base {
+  virtual ~Base();
+};
+
+template<typename T>
+struct Derived : public Base<T> { };
+
+template<>
+struct Derived<char> : public Base<char> {
+  virtual void anchor();
+};
+
+void Derived<char>::anchor() { }
diff --git a/test/CodeGenCXX/vtable-layout-abi-examples.cpp b/test/CodeGenCXX/vtable-layout-abi-examples.cpp
new file mode 100644
index 0000000..c01c5ef
--- /dev/null
+++ b/test/CodeGenCXX/vtable-layout-abi-examples.cpp
@@ -0,0 +1,311 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm-only -fdump-vtable-layouts 2>&1 | FileCheck %s
+
+/// Examples from the Itanium C++ ABI specification.
+/// http://www.codesourcery.com/public/cxx-abi/
+
+namespace Test1 {
+  
+// This is from http://www.codesourcery.com/public/cxx-abi/cxx-vtable-ex.html
+
+// CHECK:      Vtable for 'Test1::A' (5 entries).
+// CHECK-NEXT:    0 | offset_to_top (0)
+// CHECK-NEXT:    1 | Test1::A RTTI
+// CHECK-NEXT:        -- (Test1::A, 0) vtable address --
+// CHECK-NEXT:    2 | void Test1::A::f()
+// CHECK-NEXT:    3 | void Test1::A::g()
+// CHECK-NEXT:    4 | void Test1::A::h()
+struct A {
+  virtual void f ();
+  virtual void g ();
+  virtual void h ();
+  int ia;
+};
+void A::f() {}
+
+// CHECK:      Vtable for 'Test1::B' (13 entries).
+// CHECK-NEXT:    0 | vbase_offset (16)
+// CHECK-NEXT:    1 | offset_to_top (0)
+// CHECK-NEXT:    2 | Test1::B RTTI
+// CHECK-NEXT:        -- (Test1::B, 0) vtable address --
+// CHECK-NEXT:    3 | void Test1::B::f()
+// CHECK-NEXT:    4 | void Test1::B::h()
+// CHECK-NEXT:    5 | vcall_offset (-16)
+// CHECK-NEXT:    6 | vcall_offset (0)
+// CHECK-NEXT:    7 | vcall_offset (-16)
+// CHECK-NEXT:    8 | offset_to_top (-16)
+// CHECK-NEXT:    9 | Test1::B RTTI
+// CHECK-NEXT:        -- (Test1::A, 16) vtable address --
+// CHECK-NEXT:   10 | void Test1::B::f()
+// CHECK-NEXT:        [this adjustment: 0 non-virtual, -24 vcall offset offset]
+// CHECK-NEXT:   11 | void Test1::A::g()
+// CHECK-NEXT:   12 | void Test1::B::h()
+// CHECK-NEXT:        [this adjustment: 0 non-virtual, -40 vcall offset offset]
+struct B: public virtual A {
+  void f ();
+  void h ();
+  int ib;
+};
+void B::f() {}
+
+// CHECK:      Vtable for 'Test1::C' (13 entries).
+// CHECK-NEXT:    0 | vbase_offset (16)
+// CHECK-NEXT:    1 | offset_to_top (0)
+// CHECK-NEXT:    2 | Test1::C RTTI
+// CHECK-NEXT:        -- (Test1::C, 0) vtable address --
+// CHECK-NEXT:    3 | void Test1::C::g()
+// CHECK-NEXT:    4 | void Test1::C::h()
+// CHECK-NEXT:    5 | vcall_offset (-16)
+// CHECK-NEXT:    6 | vcall_offset (-16)
+// CHECK-NEXT:    7 | vcall_offset (0)
+// CHECK-NEXT:    8 | offset_to_top (-16)
+// CHECK-NEXT:    9 | Test1::C RTTI
+// CHECK-NEXT:        -- (Test1::A, 16) vtable address --
+// CHECK-NEXT:   10 | void Test1::A::f()
+// CHECK-NEXT:   11 | void Test1::C::g()
+// CHECK-NEXT:        [this adjustment: 0 non-virtual, -32 vcall offset offset]
+// CHECK-NEXT:   12 | void Test1::C::h()
+// CHECK-NEXT:        [this adjustment: 0 non-virtual, -40 vcall offset offset]
+struct C: public virtual A {
+  void g ();
+  void h ();
+  int ic;
+};
+void C::g() {}
+
+// CHECK:      Vtable for 'Test1::D' (18 entries).
+// CHECK-NEXT:    0 | vbase_offset (32)
+// CHECK-NEXT:    1 | offset_to_top (0)
+// CHECK-NEXT:    2 | Test1::D RTTI
+// CHECK-NEXT:        -- (Test1::B, 0) vtable address --
+// CHECK-NEXT:        -- (Test1::D, 0) vtable address --
+// CHECK-NEXT:    3 | void Test1::B::f()
+// CHECK-NEXT:    4 | void Test1::D::h()
+// CHECK-NEXT:    5 | vbase_offset (16)
+// CHECK-NEXT:    6 | offset_to_top (-16)
+// CHECK-NEXT:    7 | Test1::D RTTI
+// CHECK-NEXT:        -- (Test1::C, 16) vtable address --
+// CHECK-NEXT:    8 | void Test1::C::g()
+// CHECK-NEXT:    9 | void Test1::D::h()
+// CHECK-NEXT:        [this adjustment: -16 non-virtual]
+// CHECK-NEXT:   10 | vcall_offset (-32)
+// CHECK-NEXT:   11 | vcall_offset (-16)
+// CHECK-NEXT:   12 | vcall_offset (-32)
+// CHECK-NEXT:   13 | offset_to_top (-32)
+// CHECK-NEXT:   14 | Test1::D RTTI
+// CHECK-NEXT:        -- (Test1::A, 32) vtable address --
+// CHECK-NEXT:   15 | void Test1::B::f()
+// CHECK-NEXT:        [this adjustment: 0 non-virtual, -24 vcall offset offset]
+// CHECK-NEXT:   16 | void Test1::C::g()
+// CHECK-NEXT:        [this adjustment: 0 non-virtual, -32 vcall offset offset]
+// CHECK-NEXT:   17 | void Test1::D::h()
+// CHECK-NEXT:        [this adjustment: 0 non-virtual, -40 vcall offset offset]
+struct D: public B, public C {
+  void h ();
+  int id;
+};
+void D::h() { }
+
+struct X {
+  int ix;
+  virtual void x();
+};
+
+// CHECK:      Vtable for 'Test1::E' (24 entries).
+// CHECK-NEXT:    0 | vbase_offset (56)
+// CHECK-NEXT:    1 | offset_to_top (0)
+// CHECK-NEXT:    2 | Test1::E RTTI
+// CHECK-NEXT:        -- (Test1::E, 0) vtable address --
+// CHECK-NEXT:        -- (Test1::X, 0) vtable address --
+// CHECK-NEXT:    3 | void Test1::X::x()
+// CHECK-NEXT:    4 | void Test1::E::f()
+// CHECK-NEXT:    5 | void Test1::E::h()
+// CHECK-NEXT:    6 | vbase_offset (40)
+// CHECK-NEXT:    7 | offset_to_top (-16)
+// CHECK-NEXT:    8 | Test1::E RTTI
+// CHECK-NEXT:        -- (Test1::B, 16) vtable address --
+// CHECK-NEXT:        -- (Test1::D, 16) vtable address --
+// CHECK-NEXT:    9 | void Test1::E::f()
+// CHECK-NEXT:        [this adjustment: -16 non-virtual]
+// CHECK-NEXT:   10 | void Test1::E::h()
+// CHECK-NEXT:        [this adjustment: -16 non-virtual]
+// CHECK-NEXT:   11 | vbase_offset (24)
+// CHECK-NEXT:   12 | offset_to_top (-32)
+// CHECK-NEXT:   13 | Test1::E RTTI
+// CHECK-NEXT:        -- (Test1::C, 32) vtable address --
+// CHECK-NEXT:   14 | void Test1::C::g()
+// CHECK-NEXT:   15 | void Test1::E::h()
+// CHECK-NEXT:        [this adjustment: -32 non-virtual]
+// CHECK-NEXT:   16 | vcall_offset (-56)
+// CHECK-NEXT:   17 | vcall_offset (-24)
+// CHECK-NEXT:   18 | vcall_offset (-56)
+// CHECK-NEXT:   19 | offset_to_top (-56)
+// CHECK-NEXT:   20 | Test1::E RTTI
+// CHECK-NEXT:        -- (Test1::A, 56) vtable address --
+// CHECK-NEXT:   21 | void Test1::E::f()
+// CHECK-NEXT:        [this adjustment: 0 non-virtual, -24 vcall offset offset]
+// CHECK-NEXT:   22 | void Test1::C::g()
+// CHECK-NEXT:        [this adjustment: 0 non-virtual, -32 vcall offset offset]
+// CHECK-NEXT:   23 | void Test1::E::h()
+// CHECK-NEXT:        [this adjustment: 0 non-virtual, -40 vcall offset offset]
+struct E : X, D {
+  int ie;
+  void f();
+  void h ();
+};
+void E::f() { } 
+
+}
+
+namespace Test2 {
+
+// From http://www.codesourcery.com/public/cxx-abi/abi.html#class-types.
+
+struct A { virtual void f(); };
+struct B : virtual public A { int i; };
+struct C : virtual public A { int j; };
+
+// CHECK:      Vtable for 'Test2::D' (11 entries).
+// CHECK-NEXT:    0 | vbase_offset (0)
+// CHECK-NEXT:    1 | vcall_offset (0)
+// CHECK-NEXT:    2 | offset_to_top (0)
+// CHECK-NEXT:    3 | Test2::D RTTI
+// CHECK-NEXT:        -- (Test2::A, 0) vtable address --
+// CHECK-NEXT:        -- (Test2::B, 0) vtable address --
+// CHECK-NEXT:        -- (Test2::D, 0) vtable address --
+// CHECK-NEXT:    4 | void Test2::A::f()
+// CHECK-NEXT:    5 | void Test2::D::d()
+// CHECK-NEXT:    6 | vbase_offset (-16)
+// CHECK-NEXT:    7 | vcall_offset (-16)
+// CHECK-NEXT:    8 | offset_to_top (-16)
+// CHECK-NEXT:    9 | Test2::D RTTI
+// CHECK-NEXT:        -- (Test2::C, 16) vtable address --
+// CHECK-NEXT:   10 | [unused] void Test2::A::f()
+struct D : public B, public C {
+  virtual void d();
+};
+void D::d() { } 
+
+}
+
+namespace Test3 {
+
+// From http://www.codesourcery.com/public/cxx-abi/abi-examples.html#vtable-ctor
+
+struct V1 {
+  int v1;
+  virtual void f();
+};
+
+struct V2 : virtual V1 {
+  int v2;
+  virtual void f();
+};
+
+// CHECK:      Vtable for 'Test3::C' (14 entries).
+// CHECK-NEXT:    0 | vbase_offset (32)
+// CHECK-NEXT:    1 | vbase_offset (16)
+// CHECK-NEXT:    2 | offset_to_top (0)
+// CHECK-NEXT:    3 | Test3::C RTTI
+// CHECK-NEXT:        -- (Test3::C, 0) vtable address --
+// CHECK-NEXT:    4 | void Test3::C::f()
+// CHECK-NEXT:    5 | vcall_offset (-16)
+// CHECK-NEXT:    6 | offset_to_top (-16)
+// CHECK-NEXT:    7 | Test3::C RTTI
+// CHECK-NEXT:        -- (Test3::V1, 16) vtable address --
+// CHECK-NEXT:    8 | void Test3::C::f()
+// CHECK-NEXT:        [this adjustment: 0 non-virtual, -24 vcall offset offset]
+// CHECK-NEXT:    9 | vcall_offset (-32)
+// CHECK-NEXT:   10 | vbase_offset (-16)
+// CHECK-NEXT:   11 | offset_to_top (-32)
+// CHECK-NEXT:   12 | Test3::C RTTI
+// CHECK-NEXT:        -- (Test3::V2, 32) vtable address --
+// CHECK-NEXT:   13 | void Test3::C::f()
+// CHECK-NEXT:        [this adjustment: 0 non-virtual, -32 vcall offset offset]
+
+// CHECK:      Construction vtable for ('Test3::V2', 32) in 'Test3::C' (9 entries).
+// CHECK-NEXT:    0 | vcall_offset (0)
+// CHECK-NEXT:    1 | vbase_offset (-16)
+// CHECK-NEXT:    2 | offset_to_top (0)
+// CHECK-NEXT:    3 | Test3::V2 RTTI
+// CHECK-NEXT:        -- (Test3::V2, 32) vtable address --
+// CHECK-NEXT:    4 | void Test3::V2::f()
+// CHECK-NEXT:    5 | vcall_offset (16)
+// CHECK-NEXT:    6 | offset_to_top (16)
+// CHECK-NEXT:    7 | Test3::V2 RTTI
+// CHECK-NEXT:        -- (Test3::V1, 16) vtable address --
+// CHECK-NEXT:    8 | void Test3::V2::f()
+// CHECK-NEXT:        [this adjustment: 0 non-virtual, -24 vcall offset offset]
+struct C : virtual V1, virtual V2 {
+  int c;
+  virtual void f();
+};
+void C::f() { }
+
+struct B {
+  int b;
+};
+
+// CHECK:      Vtable for 'Test3::D' (15 entries).
+// CHECK-NEXT:    0 | vbase_offset (40)
+// CHECK-NEXT:    1 | vbase_offset (24)
+// CHECK-NEXT:    2 | offset_to_top (0)
+// CHECK-NEXT:    3 | Test3::D RTTI
+// CHECK-NEXT:        -- (Test3::C, 0) vtable address --
+// CHECK-NEXT:        -- (Test3::D, 0) vtable address --
+// CHECK-NEXT:    4 | void Test3::C::f()
+// CHECK-NEXT:    5 | void Test3::D::g()
+// CHECK-NEXT:    6 | vcall_offset (-24)
+// CHECK-NEXT:    7 | offset_to_top (-24)
+// CHECK-NEXT:    8 | Test3::D RTTI
+// CHECK-NEXT:        -- (Test3::V1, 24) vtable address --
+// CHECK-NEXT:    9 | void Test3::C::f()
+// CHECK-NEXT:        [this adjustment: 0 non-virtual, -24 vcall offset offset]
+// CHECK-NEXT:   10 | vcall_offset (-40)
+// CHECK-NEXT:   11 | vbase_offset (-16)
+// CHECK-NEXT:   12 | offset_to_top (-40)
+// CHECK-NEXT:   13 | Test3::D RTTI
+// CHECK-NEXT:        -- (Test3::V2, 40) vtable address --
+// CHECK-NEXT:   14 | void Test3::C::f()
+// CHECK-NEXT:        [this adjustment: 0 non-virtual, -32 vcall offset offset]
+
+// CHECK:      Construction vtable for ('Test3::C', 0) in 'Test3::D' (14 entries).
+// CHECK-NEXT:    0 | vbase_offset (40)
+// CHECK-NEXT:    1 | vbase_offset (24)
+// CHECK-NEXT:    2 | offset_to_top (0)
+// CHECK-NEXT:    3 | Test3::C RTTI
+// CHECK-NEXT:        -- (Test3::C, 0) vtable address --
+// CHECK-NEXT:    4 | void Test3::C::f()
+// CHECK-NEXT:    5 | vcall_offset (-24)
+// CHECK-NEXT:    6 | offset_to_top (-24)
+// CHECK-NEXT:    7 | Test3::C RTTI
+// CHECK-NEXT:        -- (Test3::V1, 24) vtable address --
+// CHECK-NEXT:    8 | void Test3::C::f()
+// CHECK-NEXT:        [this adjustment: 0 non-virtual, -24 vcall offset offset]
+// CHECK-NEXT:    9 | vcall_offset (-40)
+// CHECK-NEXT:   10 | vbase_offset (-16)
+// CHECK-NEXT:   11 | offset_to_top (-40)
+// CHECK-NEXT:   12 | Test3::C RTTI
+// CHECK-NEXT:        -- (Test3::V2, 40) vtable address --
+// CHECK-NEXT:   13 | void Test3::C::f()
+// CHECK-NEXT:        [this adjustment: 0 non-virtual, -32 vcall offset offset]
+
+// CHECK:      Construction vtable for ('Test3::V2', 40) in 'Test3::D' (9 entries).
+// CHECK-NEXT:    0 | vcall_offset (0)
+// CHECK-NEXT:    1 | vbase_offset (-16)
+// CHECK-NEXT:    2 | offset_to_top (0)
+// CHECK-NEXT:    3 | Test3::V2 RTTI
+// CHECK-NEXT:        -- (Test3::V2, 40) vtable address --
+// CHECK-NEXT:    4 | void Test3::V2::f()
+// CHECK-NEXT:    5 | vcall_offset (16)
+// CHECK-NEXT:    6 | offset_to_top (16)
+// CHECK-NEXT:    7 | Test3::V2 RTTI
+// CHECK-NEXT:        -- (Test3::V1, 24) vtable address --
+// CHECK-NEXT:    8 | void Test3::V2::f()
+// CHECK-NEXT:        [this adjustment: 0 non-virtual, -24 vcall offset offset]
+struct D : B, C {
+  int d;
+  virtual void g();
+};
+void D::g() { }
+
+}
diff --git a/test/CodeGenCXX/vtable-layout-extreme.cpp b/test/CodeGenCXX/vtable-layout-extreme.cpp
new file mode 100644
index 0000000..14e7879
--- /dev/null
+++ b/test/CodeGenCXX/vtable-layout-extreme.cpp
@@ -0,0 +1,210 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm-only -fdump-vtable-layouts 2>&1 | FileCheck %s
+
+// A collection of big class hierarchies and their vtables.
+
+namespace Test1 {
+
+class C0
+{
+};
+class C1
+ :  virtual public C0
+{
+  int k0;
+};
+class C2
+ :  public C0
+ ,  virtual public C1
+{
+  int k0;
+};
+class C3
+ :  virtual public C0
+ ,  virtual public C1
+ ,  public C2
+{
+  int k0;
+  int k1;
+  int k2;
+  int k3;
+};
+class C4
+ :  public C2
+ ,  virtual public C3
+ ,  public C0
+{
+  int k0;
+};
+class C5
+ :  public C0
+ ,  virtual public C4
+ ,  public C2
+ ,  public C1
+ ,  virtual public C3
+{
+  int k0;
+};
+class C6
+ :  virtual public C3
+ ,  public C0
+ ,  public C5
+ ,  public C4
+ ,  public C1
+{
+  int k0;
+};
+class C7
+ :  virtual public C5
+ ,  virtual public C6
+ ,  virtual public C3
+ ,  public C4
+ ,  virtual public C2
+{
+  int k0;
+  int k1;
+};
+class C8
+ :  public C7
+ ,  public C5
+ ,  public C3
+ ,  virtual public C4
+ ,  public C1
+ ,  public C2
+{
+  int k0;
+  int k1;
+};
+
+// CHECK:     Vtable for 'Test1::C9' (87 entries).
+// CHECK-NEXT:   0 | vbase_offset (344)
+// CHECK-NEXT:   1 | vbase_offset (312)
+// CHECK-NEXT:   2 | vbase_offset (184)
+// CHECK-NEXT:   3 | vbase_offset (168)
+// CHECK-NEXT:   4 | vbase_offset (120)
+// CHECK-NEXT:   5 | vbase_offset (48)
+// CHECK-NEXT:   6 | vbase_offset (148)
+// CHECK-NEXT:   7 | vbase_offset (152)
+// CHECK-NEXT:   8 | offset_to_top (0)
+// CHECK-NEXT:   9 | Test1::C9 RTTI
+// CHECK-NEXT:       -- (Test1::C2, 0) vtable address --
+// CHECK-NEXT:       -- (Test1::C9, 0) vtable address --
+// CHECK-NEXT:  10 | void Test1::C9::f()
+// CHECK-NEXT:  11 | vbase_offset (104)
+// CHECK-NEXT:  12 | vbase_offset (132)
+// CHECK-NEXT:  13 | vbase_offset (136)
+// CHECK-NEXT:  14 | offset_to_top (-16)
+// CHECK-NEXT:  15 | Test1::C9 RTTI
+// CHECK-NEXT:       -- (Test1::C2, 16) vtable address --
+// CHECK-NEXT:       -- (Test1::C4, 16) vtable address --
+// CHECK-NEXT:  16 | vbase_offset (72)
+// CHECK-NEXT:  17 | vbase_offset (120)
+// CHECK-NEXT:  18 | vbase_offset (100)
+// CHECK-NEXT:  19 | vbase_offset (104)
+// CHECK-NEXT:  20 | offset_to_top (-48)
+// CHECK-NEXT:  21 | Test1::C9 RTTI
+// CHECK-NEXT:       -- (Test1::C2, 48) vtable address --
+// CHECK-NEXT:       -- (Test1::C5, 48) vtable address --
+// CHECK-NEXT:       -- (Test1::C6, 48) vtable address --
+// CHECK-NEXT:  22 | vbase_offset (84)
+// CHECK-NEXT:  23 | offset_to_top (-64)
+// CHECK-NEXT:  24 | Test1::C9 RTTI
+// CHECK-NEXT:       -- (Test1::C1, 64) vtable address --
+// CHECK-NEXT:  25 | vbase_offset (32)
+// CHECK-NEXT:  26 | vbase_offset (60)
+// CHECK-NEXT:  27 | vbase_offset (64)
+// CHECK-NEXT:  28 | offset_to_top (-88)
+// CHECK-NEXT:  29 | Test1::C9 RTTI
+// CHECK-NEXT:       -- (Test1::C2, 88) vtable address --
+// CHECK-NEXT:       -- (Test1::C4, 88) vtable address --
+// CHECK-NEXT:  30 | vbase_offset (44)
+// CHECK-NEXT:  31 | offset_to_top (-104)
+// CHECK-NEXT:  32 | Test1::C9 RTTI
+// CHECK-NEXT:       -- (Test1::C1, 104) vtable address --
+// CHECK-NEXT:  33 | vbase_offset (28)
+// CHECK-NEXT:  34 | vbase_offset (32)
+// CHECK-NEXT:  35 | offset_to_top (-120)
+// CHECK-NEXT:  36 | Test1::C9 RTTI
+// CHECK-NEXT:       -- (Test1::C2, 120) vtable address --
+// CHECK-NEXT:       -- (Test1::C3, 120) vtable address --
+// CHECK-NEXT:  37 | vbase_offset (-4)
+// CHECK-NEXT:  38 | offset_to_top (-152)
+// CHECK-NEXT:  39 | Test1::C9 RTTI
+// CHECK-NEXT:       -- (Test1::C1, 152) vtable address --
+// CHECK-NEXT:  40 | vbase_offset (-48)
+// CHECK-NEXT:  41 | vbase_offset (-20)
+// CHECK-NEXT:  42 | vbase_offset (-16)
+// CHECK-NEXT:  43 | offset_to_top (-168)
+// CHECK-NEXT:  44 | Test1::C9 RTTI
+// CHECK-NEXT:       -- (Test1::C2, 168) vtable address --
+// CHECK-NEXT:       -- (Test1::C4, 168) vtable address --
+// CHECK-NEXT:  45 | vbase_offset (160)
+// CHECK-NEXT:  46 | vbase_offset (-136)
+// CHECK-NEXT:  47 | vbase_offset (-16)
+// CHECK-NEXT:  48 | vbase_offset (128)
+// CHECK-NEXT:  49 | vbase_offset (-64)
+// CHECK-NEXT:  50 | vbase_offset (-36)
+// CHECK-NEXT:  51 | vbase_offset (-32)
+// CHECK-NEXT:  52 | offset_to_top (-184)
+// CHECK-NEXT:  53 | Test1::C9 RTTI
+// CHECK-NEXT:       -- (Test1::C2, 184) vtable address --
+// CHECK-NEXT:       -- (Test1::C4, 184) vtable address --
+// CHECK-NEXT:       -- (Test1::C7, 184) vtable address --
+// CHECK-NEXT:       -- (Test1::C8, 184) vtable address --
+// CHECK-NEXT:  54 | vbase_offset (-88)
+// CHECK-NEXT:  55 | vbase_offset (-40)
+// CHECK-NEXT:  56 | vbase_offset (-60)
+// CHECK-NEXT:  57 | vbase_offset (-56)
+// CHECK-NEXT:  58 | offset_to_top (-208)
+// CHECK-NEXT:  59 | Test1::C9 RTTI
+// CHECK-NEXT:       -- (Test1::C2, 208) vtable address --
+// CHECK-NEXT:       -- (Test1::C5, 208) vtable address --
+// CHECK-NEXT:  60 | vbase_offset (-76)
+// CHECK-NEXT:  61 | offset_to_top (-224)
+// CHECK-NEXT:  62 | Test1::C9 RTTI
+// CHECK-NEXT:       -- (Test1::C1, 224) vtable address --
+// CHECK-NEXT:  63 | vbase_offset (-92)
+// CHECK-NEXT:  64 | vbase_offset (-88)
+// CHECK-NEXT:  65 | offset_to_top (-240)
+// CHECK-NEXT:  66 | Test1::C9 RTTI
+// CHECK-NEXT:       -- (Test1::C2, 240) vtable address --
+// CHECK-NEXT:       -- (Test1::C3, 240) vtable address --
+// CHECK-NEXT:  67 | vbase_offset (-124)
+// CHECK-NEXT:  68 | offset_to_top (-272)
+// CHECK-NEXT:  69 | Test1::C9 RTTI
+// CHECK-NEXT:       -- (Test1::C1, 272) vtable address --
+// CHECK-NEXT:  70 | vbase_offset (-140)
+// CHECK-NEXT:  71 | vbase_offset (-136)
+// CHECK-NEXT:  72 | offset_to_top (-288)
+// CHECK-NEXT:  73 | Test1::C9 RTTI
+// CHECK-NEXT:       -- (Test1::C2, 288) vtable address --
+// CHECK-NEXT:  74 | vbase_offset (-192)
+// CHECK-NEXT:  75 | vbase_offset (-144)
+// CHECK-NEXT:  76 | vbase_offset (-164)
+// CHECK-NEXT:  77 | vbase_offset (-160)
+// CHECK-NEXT:  78 | offset_to_top (-312)
+// CHECK-NEXT:  79 | Test1::C9 RTTI
+// CHECK-NEXT:       -- (Test1::C2, 312) vtable address --
+// CHECK-NEXT:       -- (Test1::C5, 312) vtable address --
+// CHECK-NEXT:  80 | vbase_offset (-180)
+// CHECK-NEXT:  81 | offset_to_top (-328)
+// CHECK-NEXT:  82 | Test1::C9 RTTI
+// CHECK-NEXT:       -- (Test1::C1, 328) vtable address --
+// CHECK-NEXT:  83 | vbase_offset (-196)
+// CHECK-NEXT:  84 | vbase_offset (-192)
+// CHECK-NEXT:  85 | offset_to_top (-344)
+// CHECK-NEXT:  86 | Test1::C9 RTTI
+class C9
+ :  virtual public C6
+ ,  public C2
+ ,  public C4
+ ,  virtual public C8
+{
+  int k0;
+  int k1;
+  int k2;
+  int k3;
+  virtual void f();
+};
+void C9::f() { }
+
+}
diff --git a/test/CodeGenCXX/vtable-layout.cpp b/test/CodeGenCXX/vtable-layout.cpp
new file mode 100644
index 0000000..f2f5179
--- /dev/null
+++ b/test/CodeGenCXX/vtable-layout.cpp
@@ -0,0 +1,1639 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm-only -fdump-vtable-layouts 2>&1 | FileCheck %s
+
+// For now, just verify this doesn't crash.
+namespace test0 {
+  struct Obj {};
+
+  struct Base {           virtual const Obj *foo() = 0; };
+  struct Derived : Base { virtual       Obj *foo() { return new Obj(); } };
+
+  void test(Derived *D) { D->foo(); }
+}
+
+namespace Test1 {
+// CHECK:      Vtable for 'Test1::A' (3 entries).
+// CHECK-NEXT:   0 | offset_to_top (0)
+// CHECK-NEXT:   1 | Test1::A RTTI
+// CHECK-NEXT:       -- (Test1::A, 0) vtable address --
+// CHECK-NEXT:   2 | void Test1::A::f()
+struct A {
+  virtual void f();
+};
+void A::f() { }
+
+}
+
+namespace Test2 {
+
+// This is a smoke test of the vtable dumper.
+// CHECK:      Vtable for 'Test2::A' (9 entries).
+// CHECK-NEXT:   0 | offset_to_top (0)
+// CHECK-NEXT:   1 | Test2::A RTTI
+// CHECK-NEXT:       -- (Test2::A, 0) vtable address --
+// CHECK-NEXT:   2 | void Test2::A::f()
+// CHECK-NEXT:   3 | void Test2::A::f() const
+// CHECK-NEXT:   4 | Test2::A *Test2::A::g(int)
+// CHECK-NEXT:   5 | Test2::A::~A() [complete]
+// CHECK-NEXT:   6 | Test2::A::~A() [deleting]
+// CHECK-NEXT:   7 | void Test2::A::h()
+// CHECK-NEXT:   8 | Test2::A &Test2::A::operator=(Test2::A const &)
+struct A {
+  virtual void f();
+  virtual void f() const;
+  
+  virtual A* g(int a);
+  virtual ~A();
+  virtual void h();
+  virtual A& operator=(const A&);
+};
+void A::f() { }
+
+// Another simple vtable dumper test.
+
+// CHECK:     Vtable for 'Test2::B' (6 entries).
+// CHECK-NEXT:  0 | offset_to_top (0)
+// CHECK-NEXT:  1 | Test2::B RTTI
+// CHECK-NEXT:    -- (Test2::B, 0) vtable address --
+// CHECK-NEXT:  2 | void Test2::B::f()
+// CHECK-NEXT:  3 | void Test2::B::g() [pure]
+// CHECK-NEXT:  4 | Test2::B::~B() [complete] [pure]
+// CHECK-NEXT:  5 | Test2::B::~B() [deleting] [pure]
+struct B {
+  virtual void f();
+  virtual void g() = 0;
+  virtual ~B() = 0;
+};
+void B::f() { }
+
+}
+
+namespace Test3 {
+
+// If a function in a derived class overrides a function in a primary base,
+// then the function should not have an entry in the derived class (unless the return
+// value requires adjusting).
+
+// CHECK:      Vtable for 'Test3::A' (3 entries).
+// CHECK-NEXT:   0 | offset_to_top (0)
+// CHECK-NEXT:   1 | Test3::A RTTI
+// CHECK-NEXT:       -- (Test3::A, 0) vtable address --
+// CHECK-NEXT:   2 | void Test3::A::f()
+struct A {
+  virtual void f();
+};
+void A::f() { } 
+
+// CHECK:     Vtable for 'Test3::B' (4 entries).
+// CHECK-NEXT:  0 | offset_to_top (0)
+// CHECK-NEXT:  1 | Test3::B RTTI
+// CHECK-NEXT:      -- (Test3::A, 0) vtable address --
+// CHECK-NEXT:      -- (Test3::B, 0) vtable address --
+// CHECK-NEXT:  2 | void Test3::B::f()
+// CHECK-NEXT:  3 | void Test3::B::g()
+struct B : A {
+  virtual void f();
+  virtual void g();
+};
+void B::f() { }
+
+// CHECK:     Vtable for 'Test3::C' (5 entries).
+// CHECK-NEXT:  0 | offset_to_top (0)
+// CHECK-NEXT:  1 | Test3::C RTTI
+// CHECK-NEXT:     -- (Test3::A, 0) vtable address --
+// CHECK-NEXT:     -- (Test3::C, 0) vtable address --
+// CHECK-NEXT:  2 | void Test3::A::f()
+// CHECK-NEXT:  3 | void Test3::C::g()
+// CHECK-NEXT:  4 | void Test3::C::h()
+struct C : A {
+  virtual void g();
+  virtual void h();
+};
+void C::g() { }
+
+// CHECK:     Vtable for 'Test3::D' (5 entries).
+// CHECK-NEXT:  0 | offset_to_top (0)
+// CHECK-NEXT:  1 | Test3::D RTTI
+// CHECK-NEXT:     -- (Test3::A, 0) vtable address --
+// CHECK-NEXT:     -- (Test3::B, 0) vtable address --
+// CHECK-NEXT:     -- (Test3::D, 0) vtable address --
+// CHECK-NEXT:  2 | void Test3::D::f()
+// CHECK-NEXT:  3 | void Test3::D::g()
+// CHECK-NEXT:  4 | void Test3::D::h()
+struct D : B {
+  virtual void f();
+  virtual void g();
+  virtual void h();
+};
+
+void D::f() { } 
+}
+
+namespace Test4 {
+
+// Test non-virtual result adjustments.
+
+struct R1 { int r1; };
+struct R2 { int r2; };
+struct R3 : R1, R2 { int r3; };
+
+struct A {
+  virtual R2 *f();
+};
+
+// CHECK:     Vtable for 'Test4::B' (4 entries).
+// CHECK-NEXT:  0 | offset_to_top (0)
+// CHECK-NEXT:  1 | Test4::B RTTI
+// CHECK-NEXT:      -- (Test4::A, 0) vtable address --
+// CHECK-NEXT:      -- (Test4::B, 0) vtable address --
+// CHECK-NEXT:  2 | Test4::R3 *Test4::B::f()
+// CHECK-NEXT:      [return adjustment: 4 non-virtual]
+// CHECK-NEXT:  3 | Test4::R3 *Test4::B::f()
+
+struct B : A {
+  virtual R3 *f();
+};
+R3 *B::f() { return 0; }
+
+// Test virtual result adjustments.
+struct V1 { int v1; };
+struct V2 : virtual V1 { int v1; };
+
+struct C {
+  virtual V1 *f(); 
+};
+
+// CHECK:     Vtable for 'Test4::D' (4 entries).
+// CHECK-NEXT:   0 | offset_to_top (0)
+// CHECK-NEXT:   1 | Test4::D RTTI
+// CHECK-NEXT:       -- (Test4::C, 0) vtable address --
+// CHECK-NEXT:       -- (Test4::D, 0) vtable address --
+// CHECK-NEXT:   2 | Test4::V2 *Test4::D::f()
+// CHECK-NEXT:       [return adjustment: 0 non-virtual, -24 vbase offset offset]
+// CHECK-NEXT:   3 | Test4::V2 *Test4::D::f()
+struct D : C {
+  virtual V2 *f();
+};
+V2 *D::f() { return 0; };
+
+// Virtual result adjustments with an additional non-virtual adjustment.
+struct V3 : virtual R3 { int r3; };
+
+// CHECK:     Vtable for 'Test4::E' (4 entries).
+// CHECK-NEXT:   0 | offset_to_top (0)
+// CHECK-NEXT:   1 | Test4::E RTTI
+// CHECK-NEXT:       -- (Test4::A, 0) vtable address --
+// CHECK-NEXT:       -- (Test4::E, 0) vtable address --
+// CHECK-NEXT:   2 | Test4::V3 *Test4::E::f()
+// CHECK-NEXT:       [return adjustment: 4 non-virtual, -24 vbase offset offset]
+// CHECK-NEXT:   3 | Test4::V3 *Test4::E::f()
+
+struct E : A {
+  virtual V3 *f();
+};
+V3 *E::f() { return 0;}
+
+// Test that a pure virtual member doesn't get a thunk.
+
+// CHECK:     Vtable for 'Test4::F' (5 entries).
+// CHECK-NEXT:   0 | offset_to_top (0)
+// CHECK-NEXT:   1 | Test4::F RTTI
+// CHECK-NEXT:       -- (Test4::A, 0) vtable address --
+// CHECK-NEXT:       -- (Test4::F, 0) vtable address --
+// CHECK-NEXT:   2 | Test4::R3 *Test4::F::f() [pure]
+// CHECK-NEXT:   3 | void Test4::F::g()
+// CHECK-NEXT:   4 | Test4::R3 *Test4::F::f() [pure]
+struct F : A {
+  virtual void g();
+  virtual R3 *f() = 0;
+};
+void F::g() { }
+
+}
+
+namespace Test5 {
+
+// Simple secondary vtables without 'this' pointer adjustments.
+struct A {
+  virtual void f();
+  virtual void g();
+  int a;
+};
+
+struct B1 : A {
+  virtual void f();
+  int b1;
+};
+
+struct B2 : A {
+  virtual void g();
+  int b2;
+};
+
+// CHECK:     Vtable for 'Test5::C' (9 entries).
+// CHECK-NEXT:   0 | offset_to_top (0)
+// CHECK-NEXT:   1 | Test5::C RTTI
+// CHECK-NEXT:       -- (Test5::A, 0) vtable address --
+// CHECK-NEXT:       -- (Test5::B1, 0) vtable address --
+// CHECK-NEXT:       -- (Test5::C, 0) vtable address --
+// CHECK-NEXT:   2 | void Test5::B1::f()
+// CHECK-NEXT:   3 | void Test5::A::g()
+// CHECK-NEXT:   4 | void Test5::C::h()
+// CHECK-NEXT:   5 | offset_to_top (-16)
+// CHECK-NEXT:   6 | Test5::C RTTI
+// CHECK-NEXT:       -- (Test5::A, 16) vtable address --
+// CHECK-NEXT:       -- (Test5::B2, 16) vtable address --
+// CHECK-NEXT:   7 | void Test5::A::f()
+// CHECK-NEXT:   8 | void Test5::B2::g()
+struct C : B1, B2 {
+  virtual void h();
+};
+void C::h() { }  
+}
+
+namespace Test6 {
+
+// Simple non-virtual 'this' pointer adjustments.
+struct A1 {
+  virtual void f();
+  int a;
+};
+
+struct A2 {
+  virtual void f();
+  int a;
+};
+
+// CHECK:     Vtable for 'Test6::C' (6 entries).
+// CHECK-NEXT:   0 | offset_to_top (0)
+// CHECK-NEXT:   1 | Test6::C RTTI
+// CHECK-NEXT:       -- (Test6::A1, 0) vtable address --
+// CHECK-NEXT:       -- (Test6::C, 0) vtable address --
+// CHECK-NEXT:   2 | void Test6::C::f()
+// CHECK-NEXT:   3 | offset_to_top (-16)
+// CHECK-NEXT:   4 | Test6::C RTTI
+// CHECK-NEXT:       -- (Test6::A2, 16) vtable address --
+// CHECK-NEXT:   5 | void Test6::C::f()
+// CHECK-NEXT:       [this adjustment: -16 non-virtual]
+struct C : A1, A2 {
+  virtual void f();
+};
+void C::f() { }
+
+}
+
+namespace Test7 {
+
+// Test that the D::f overrider for A::f have different 'this' pointer
+// adjustments in the two A base subobjects.
+
+struct A {
+  virtual void f();
+  int a;
+};
+
+struct B1 : A { };
+struct B2 : A { };
+
+struct C { virtual void c(); };
+
+// CHECK:     Vtable for 'Test7::D' (10 entries).
+// CHECK-NEXT:   0 | offset_to_top (0)
+// CHECK-NEXT:   1 | Test7::D RTTI
+// CHECK-NEXT:       -- (Test7::C, 0) vtable address --
+// CHECK-NEXT:       -- (Test7::D, 0) vtable address --
+// CHECK-NEXT:   2 | void Test7::C::c()
+// CHECK-NEXT:   3 | void Test7::D::f()
+// CHECK-NEXT:   4 | offset_to_top (-8)
+// CHECK-NEXT:   5 | Test7::D RTTI
+// CHECK-NEXT:       -- (Test7::A, 8) vtable address --
+// CHECK-NEXT:       -- (Test7::B1, 8) vtable address --
+// CHECK-NEXT:   6 | void Test7::D::f()
+// CHECK-NEXT:       [this adjustment: -8 non-virtual]
+// CHECK-NEXT:   7 | offset_to_top (-24)
+// CHECK-NEXT:   8 | Test7::D RTTI
+// CHECK-NEXT:       -- (Test7::A, 24) vtable address --
+// CHECK-NEXT:       -- (Test7::B2, 24) vtable address --
+// CHECK-NEXT:   9 | void Test7::D::f()
+// CHECK-NEXT:       [this adjustment: -24 non-virtual]
+struct D : C, B1, B2 {
+  virtual void f();
+};
+void D::f() { }
+
+}
+
+namespace Test8 {
+
+// Test that we don't try to layout vtables for classes that don't have
+// virtual bases or virtual member functions.
+
+struct A { };
+
+// CHECK:     Vtable for 'Test8::B' (3 entries).
+// CHECK-NEXT:   0 | offset_to_top (0)
+// CHECK-NEXT:   1 | Test8::B RTTI
+// CHECK-NEXT:       -- (Test8::B, 0) vtable address --
+// CHECK-NEXT:   2 | void Test8::B::f()
+struct B : A { 
+  virtual void f();
+};
+void B::f() { }
+
+}
+
+namespace Test9 {
+
+// Simple test of vbase offsets.
+
+struct A1 { int a1; };
+struct A2 { int a2; };
+
+// CHECK:     Vtable for 'Test9::B' (5 entries).
+// CHECK-NEXT:   0 | vbase_offset (16)
+// CHECK-NEXT:   1 | vbase_offset (12)
+// CHECK-NEXT:   2 | offset_to_top (0)
+// CHECK-NEXT:   3 | Test9::B RTTI
+// CHECK-NEXT:       -- (Test9::B, 0) vtable address --
+// CHECK-NEXT:   4 | void Test9::B::f()
+struct B : virtual A1, virtual A2 {
+  int b;
+
+  virtual void f();
+};
+
+
+void B::f() { }
+
+}
+
+namespace Test10 {
+
+// Test for a bug where we would not emit secondary vtables for bases
+// of a primary base.
+struct A1 { virtual void a1(); };
+struct A2 { virtual void a2(); };
+
+// CHECK:     Vtable for 'Test10::C' (7 entries).
+// CHECK-NEXT:   0 | offset_to_top (0)
+// CHECK-NEXT:   1 | Test10::C RTTI
+// CHECK-NEXT:       -- (Test10::A1, 0) vtable address --
+// CHECK-NEXT:       -- (Test10::B, 0) vtable address --
+// CHECK-NEXT:       -- (Test10::C, 0) vtable address --
+// CHECK-NEXT:   2 | void Test10::A1::a1()
+// CHECK-NEXT:   3 | void Test10::C::f()
+// CHECK-NEXT:   4 | offset_to_top (-8)
+// CHECK-NEXT:   5 | Test10::C RTTI
+// CHECK-NEXT:       -- (Test10::A2, 8) vtable address --
+// CHECK-NEXT:   6 | void Test10::A2::a2()
+struct B : A1, A2 {
+  int b;
+};
+
+struct C : B {
+  virtual void f();
+};
+void C::f() { }
+
+}
+
+namespace Test11 {
+
+// Very simple test of vtables for virtual bases.
+struct A1 { int a; };
+struct A2 { int b; };
+
+struct B : A1, virtual A2 {
+  int b;
+};
+
+// CHECK:     Vtable for 'Test11::C' (8 entries).
+// CHECK-NEXT:   0 | vbase_offset (24)
+// CHECK-NEXT:   1 | vbase_offset (8)
+// CHECK-NEXT:   2 | offset_to_top (0)
+// CHECK-NEXT:   3 | Test11::C RTTI
+// CHECK-NEXT:       -- (Test11::C, 0) vtable address --
+// CHECK-NEXT:   4 | void Test11::C::f()
+// CHECK-NEXT:   5 | vbase_offset (16)
+// CHECK-NEXT:   6 | offset_to_top (-8)
+// CHECK-NEXT:   7 | Test11::C RTTI
+struct C : virtual B {
+  virtual void f();
+};
+void C::f() { }
+
+}
+
+namespace Test12 {
+
+// Test that the right vcall offsets are generated in the right order.
+
+// CHECK:      Vtable for 'Test12::B' (19 entries).
+// CHECK-NEXT:    0 | vbase_offset (8)
+// CHECK-NEXT:    1 | offset_to_top (0)
+// CHECK-NEXT:    2 | Test12::B RTTI
+// CHECK-NEXT:        -- (Test12::B, 0) vtable address --
+// CHECK-NEXT:    3 | void Test12::B::f()
+// CHECK-NEXT:    4 | void Test12::B::a()
+// CHECK-NEXT:    5 | vcall_offset (32)
+// CHECK-NEXT:    6 | vcall_offset (16)
+// CHECK-NEXT:    7 | vcall_offset (-8)
+// CHECK-NEXT:    8 | vcall_offset (0)
+// CHECK-NEXT:    9 | offset_to_top (-8)
+// CHECK-NEXT:   10 | Test12::B RTTI
+// CHECK-NEXT:        -- (Test12::A, 8) vtable address --
+// CHECK-NEXT:        -- (Test12::A1, 8) vtable address --
+// CHECK-NEXT:   11 | void Test12::A1::a1()
+// CHECK-NEXT:   12 | void Test12::B::a()
+// CHECK-NEXT:        [this adjustment: 0 non-virtual, -32 vcall offset offset]
+// CHECK-NEXT:   13 | offset_to_top (-24)
+// CHECK-NEXT:   14 | Test12::B RTTI
+// CHECK-NEXT:        -- (Test12::A2, 24) vtable address --
+// CHECK-NEXT:   15 | void Test12::A2::a2()
+// CHECK-NEXT:   16 | offset_to_top (-40)
+// CHECK-NEXT:   17 | Test12::B RTTI
+// CHECK-NEXT:        -- (Test12::A3, 40) vtable address --
+// CHECK-NEXT:   18 | void Test12::A3::a3()
+struct A1 {
+  virtual void a1();
+  int a;
+};
+
+struct A2 {
+  virtual void a2();
+  int a;
+};
+
+struct A3 {
+  virtual void a3();
+  int a;
+};
+
+struct A : A1, A2, A3 {
+  virtual void a();
+  int i;
+};
+
+struct B : virtual A {
+  virtual void f();
+
+  virtual void a();
+};
+void B::f() { } 
+
+}
+
+namespace Test13 {
+
+// Test that we don't try to emit a vtable for 'A' twice.
+struct A {
+  virtual void f();
+};
+
+struct B : virtual A {
+  virtual void f();
+};
+
+// CHECK:      Vtable for 'Test13::C' (6 entries).
+// CHECK-NEXT:    0 | vbase_offset (0)
+// CHECK-NEXT:    1 | vbase_offset (0)
+// CHECK-NEXT:    2 | vcall_offset (0)
+// CHECK-NEXT:    3 | offset_to_top (0)
+// CHECK-NEXT:    4 | Test13::C RTTI
+// CHECK-NEXT:        -- (Test13::A, 0) vtable address --
+// CHECK-NEXT:        -- (Test13::B, 0) vtable address --
+// CHECK-NEXT:        -- (Test13::C, 0) vtable address --
+// CHECK-NEXT:    5 | void Test13::C::f()
+struct C : virtual B, virtual A {
+  virtual void f();
+};
+void C::f() { }
+
+}
+
+namespace Test14 {
+
+// Verify that we handle A being a non-virtual base of B, which is a virtual base.
+
+struct A { 
+  virtual void f(); 
+};
+
+struct B : A { };
+
+struct C : virtual B { };
+
+// CHECK:      Vtable for 'Test14::D' (5 entries).
+// CHECK-NEXT:    0 | vbase_offset (0)
+// CHECK-NEXT:    1 | vcall_offset (0)
+// CHECK-NEXT:    2 | offset_to_top (0)
+// CHECK-NEXT:    3 | Test14::D RTTI
+// CHECK-NEXT:        -- (Test14::A, 0) vtable address --
+// CHECK-NEXT:        -- (Test14::B, 0) vtable address --
+// CHECK-NEXT:        -- (Test14::C, 0) vtable address --
+// CHECK-NEXT:        -- (Test14::D, 0) vtable address --
+// CHECK-NEXT:    4 | void Test14::D::f()
+struct D : C, virtual B {
+ virtual void f();
+};
+void D::f() { }
+
+}
+
+namespace Test15 {
+
+// Test that we don't emit an extra vtable for B since it's a primary base of C.
+struct A { virtual void a(); };
+struct B { virtual void b(); };
+
+struct C : virtual B { };
+
+// CHECK:      Vtable for 'Test15::D' (11 entries).
+// CHECK-NEXT:    0 | vbase_offset (8)
+// CHECK-NEXT:    1 | vbase_offset (8)
+// CHECK-NEXT:    2 | offset_to_top (0)
+// CHECK-NEXT:    3 | Test15::D RTTI
+// CHECK-NEXT:        -- (Test15::A, 0) vtable address --
+// CHECK-NEXT:        -- (Test15::D, 0) vtable address --
+// CHECK-NEXT:    4 | void Test15::A::a()
+// CHECK-NEXT:    5 | void Test15::D::f()
+// CHECK-NEXT:    6 | vbase_offset (0)
+// CHECK-NEXT:    7 | vcall_offset (0)
+// CHECK-NEXT:    8 | offset_to_top (-8)
+// CHECK-NEXT:    9 | Test15::D RTTI
+// CHECK-NEXT:        -- (Test15::B, 8) vtable address --
+// CHECK-NEXT:        -- (Test15::C, 8) vtable address --
+// CHECK-NEXT:   10 | void Test15::B::b()
+struct D : A, virtual B, virtual C { 
+  virtual void f();
+};
+void D::f() { } 
+
+}
+
+namespace Test16 {
+
+// Test that destructors share vcall offsets.
+
+struct A { virtual ~A(); };
+struct B { virtual ~B(); };
+
+struct C : A, B { virtual ~C(); };
+
+// CHECK:      Vtable for 'Test16::D' (15 entries).
+// CHECK-NEXT:    0 | vbase_offset (8)
+// CHECK-NEXT:    1 | offset_to_top (0)
+// CHECK-NEXT:    2 | Test16::D RTTI
+// CHECK-NEXT:        -- (Test16::D, 0) vtable address --
+// CHECK-NEXT:    3 | void Test16::D::f()
+// CHECK-NEXT:    4 | Test16::D::~D() [complete]
+// CHECK-NEXT:    5 | Test16::D::~D() [deleting]
+// CHECK-NEXT:    6 | vcall_offset (-8)
+// CHECK-NEXT:    7 | offset_to_top (-8)
+// CHECK-NEXT:    8 | Test16::D RTTI
+// CHECK-NEXT:        -- (Test16::A, 8) vtable address --
+// CHECK-NEXT:        -- (Test16::C, 8) vtable address --
+// CHECK-NEXT:    9 | Test16::D::~D() [complete]
+// CHECK-NEXT:        [this adjustment: 0 non-virtual, -24 vcall offset offset]
+// CHECK-NEXT:   10 | Test16::D::~D() [deleting]
+// CHECK-NEXT:        [this adjustment: 0 non-virtual, -24 vcall offset offset]
+// CHECK-NEXT:   11 | offset_to_top (-16)
+// CHECK-NEXT:   12 | Test16::D RTTI
+// CHECK-NEXT:        -- (Test16::B, 16) vtable address --
+// CHECK-NEXT:   13 | Test16::D::~D() [complete]
+// CHECK-NEXT:        [this adjustment: -8 non-virtual, -24 vcall offset offset]
+// CHECK-NEXT:   14 | Test16::D::~D() [deleting]
+// CHECK-NEXT:        [this adjustment: -8 non-virtual, -24 vcall offset offset]
+struct D : virtual C {
+  virtual void f();
+};
+void D::f() { } 
+
+}
+
+namespace Test17 {
+
+// Test that we don't mark E::f in the C-in-E vtable as unused.
+struct A { virtual void f(); };
+struct B : virtual A { virtual void f(); };
+struct C : virtual A { virtual void f(); };
+struct D : virtual B, virtual C { virtual void f(); };
+
+// CHECK:      Vtable for 'Test17::E' (13 entries).
+// CHECK-NEXT:    0 | vbase_offset (0)
+// CHECK-NEXT:    1 | vbase_offset (8)
+// CHECK-NEXT:    2 | vbase_offset (0)
+// CHECK-NEXT:    3 | vbase_offset (0)
+// CHECK-NEXT:    4 | vcall_offset (0)
+// CHECK-NEXT:    5 | offset_to_top (0)
+// CHECK-NEXT:    6 | Test17::E RTTI
+// CHECK-NEXT:        -- (Test17::A, 0) vtable address --
+// CHECK-NEXT:        -- (Test17::B, 0) vtable address --
+// CHECK-NEXT:        -- (Test17::D, 0) vtable address --
+// CHECK-NEXT:        -- (Test17::E, 0) vtable address --
+// CHECK-NEXT:    7 | void Test17::E::f()
+// CHECK-NEXT:    8 | vbase_offset (-8)
+// CHECK-NEXT:    9 | vcall_offset (-8)
+// CHECK-NEXT:   10 | offset_to_top (-8)
+// CHECK-NEXT:   11 | Test17::E RTTI
+// CHECK-NEXT:        -- (Test17::C, 8) vtable address --
+// CHECK-NEXT:   12 | void Test17::E::f()
+// CHECK-NEXT:        [this adjustment: 0 non-virtual, -24 vcall offset offset]
+class E : virtual D {
+  virtual void f();  
+};
+void E::f() {}
+
+}
+
+namespace Test18 {
+
+// Test that we compute the right 'this' adjustment offsets.
+
+struct A {
+  virtual void f();
+  virtual void g();
+};
+
+struct B : virtual A {
+  virtual void f();
+};
+
+struct C : A, B {
+  virtual void g();
+};
+
+// CHECK:      Vtable for 'Test18::D' (24 entries).
+// CHECK-NEXT:    0 | vbase_offset (8)
+// CHECK-NEXT:    1 | vbase_offset (0)
+// CHECK-NEXT:    2 | vbase_offset (0)
+// CHECK-NEXT:    3 | vcall_offset (8)
+// CHECK-NEXT:    4 | vcall_offset (0)
+// CHECK-NEXT:    5 | offset_to_top (0)
+// CHECK-NEXT:    6 | Test18::D RTTI
+// CHECK-NEXT:        -- (Test18::A, 0) vtable address --
+// CHECK-NEXT:        -- (Test18::B, 0) vtable address --
+// CHECK-NEXT:        -- (Test18::D, 0) vtable address --
+// CHECK-NEXT:    7 | void Test18::D::f()
+// CHECK-NEXT:    8 | void Test18::C::g()
+// CHECK-NEXT:        [this adjustment: 0 non-virtual, -32 vcall offset offset]
+// CHECK-NEXT:    9 | void Test18::D::h()
+// CHECK-NEXT:   10 | vcall_offset (0)
+// CHECK-NEXT:   11 | vcall_offset (-8)
+// CHECK-NEXT:   12 | vbase_offset (-8)
+// CHECK-NEXT:   13 | offset_to_top (-8)
+// CHECK-NEXT:   14 | Test18::D RTTI
+// CHECK-NEXT:        -- (Test18::A, 8) vtable address --
+// CHECK-NEXT:        -- (Test18::C, 8) vtable address --
+// CHECK-NEXT:   15 | void Test18::D::f()
+// CHECK-NEXT:        [this adjustment: 0 non-virtual, -32 vcall offset offset]
+// CHECK-NEXT:   16 | void Test18::C::g()
+// CHECK-NEXT:   17 | vbase_offset (-16)
+// CHECK-NEXT:   18 | vcall_offset (-8)
+// CHECK-NEXT:   19 | vcall_offset (-16)
+// CHECK-NEXT:   20 | offset_to_top (-16)
+// CHECK-NEXT:   21 | Test18::D RTTI
+// CHECK-NEXT:        -- (Test18::B, 16) vtable address --
+// CHECK-NEXT:   22 | void Test18::D::f()
+// CHECK-NEXT:        [this adjustment: -8 non-virtual, -32 vcall offset offset]
+// CHECK-NEXT:   23 | [unused] void Test18::C::g()
+
+// CHECK:      Construction vtable for ('Test18::B', 0) in 'Test18::D' (7 entries).
+// CHECK-NEXT:    0 | vbase_offset (0)
+// CHECK-NEXT:    1 | vcall_offset (0)
+// CHECK-NEXT:    2 | vcall_offset (0)
+// CHECK-NEXT:    3 | offset_to_top (0)
+// CHECK-NEXT:    4 | Test18::B RTTI
+// CHECK-NEXT:        -- (Test18::A, 0) vtable address --
+// CHECK-NEXT:        -- (Test18::B, 0) vtable address --
+// CHECK-NEXT:    5 | void Test18::B::f()
+// CHECK-NEXT:    6 | void Test18::A::g()
+
+// CHECK:      Construction vtable for ('Test18::C', 8) in 'Test18::D' (20 entries).
+// CHECK-NEXT:    0 | vcall_offset (0)
+// CHECK-NEXT:    1 | vcall_offset (0)
+// CHECK-NEXT:    2 | vbase_offset (-8)
+// CHECK-NEXT:    3 | offset_to_top (0)
+// CHECK-NEXT:    4 | Test18::C RTTI
+// CHECK-NEXT:        -- (Test18::A, 8) vtable address --
+// CHECK-NEXT:        -- (Test18::C, 8) vtable address --
+// CHECK-NEXT:    5 | void Test18::A::f()
+// CHECK-NEXT:    6 | void Test18::C::g()
+// CHECK-NEXT:    7 | vbase_offset (-16)
+// CHECK-NEXT:    8 | vcall_offset (-8)
+// CHECK-NEXT:    9 | vcall_offset (0)
+// CHECK-NEXT:   10 | offset_to_top (-8)
+// CHECK-NEXT:   11 | Test18::C RTTI
+// CHECK-NEXT:        -- (Test18::B, 16) vtable address --
+// CHECK-NEXT:   12 | void Test18::B::f()
+// CHECK-NEXT:   13 | [unused] void Test18::C::g()
+// CHECK-NEXT:   14 | vcall_offset (8)
+// CHECK-NEXT:   15 | vcall_offset (16)
+// CHECK-NEXT:   16 | offset_to_top (8)
+// CHECK-NEXT:   17 | Test18::C RTTI
+// CHECK-NEXT:        -- (Test18::A, 0) vtable address --
+// CHECK-NEXT:   18 | void Test18::B::f()
+// CHECK-NEXT:        [this adjustment: 0 non-virtual, -24 vcall offset offset]
+// CHECK-NEXT:   19 | void Test18::C::g()
+// CHECK-NEXT:        [this adjustment: 0 non-virtual, -32 vcall offset offset]
+
+// CHECK:      Construction vtable for ('Test18::B', 16) in 'Test18::D' (13 entries).
+// CHECK-NEXT:    0 | vbase_offset (-16)
+// CHECK-NEXT:    1 | vcall_offset (-16)
+// CHECK-NEXT:    2 | vcall_offset (0)
+// CHECK-NEXT:    3 | offset_to_top (0)
+// CHECK-NEXT:    4 | Test18::B RTTI
+// CHECK-NEXT:        -- (Test18::B, 16) vtable address --
+// CHECK-NEXT:    5 | void Test18::B::f()
+// CHECK-NEXT:    6 | [unused] void Test18::A::g()
+// CHECK-NEXT:    7 | vcall_offset (0)
+// CHECK-NEXT:    8 | vcall_offset (16)
+// CHECK-NEXT:    9 | offset_to_top (16)
+// CHECK-NEXT:   10 | Test18::B RTTI
+// CHECK-NEXT:        -- (Test18::A, 0) vtable address --
+// CHECK-NEXT:   11 | void Test18::B::f()
+// CHECK-NEXT:        [this adjustment: 0 non-virtual, -24 vcall offset offset]
+// CHECK-NEXT:   12 | void Test18::A::g()
+struct D : virtual B, virtual C, virtual A 
+{
+  virtual void f();
+  virtual void h();
+};
+void D::f() {}
+
+}
+
+namespace Test19 {
+
+// Another 'this' adjustment test.
+
+struct A {
+  int a;
+
+  virtual void f();
+};
+
+struct B : A {
+  int b;
+
+  virtual void g();
+};
+
+struct C {
+  virtual void c();
+};
+
+// CHECK:      Vtable for 'Test19::D' (13 entries).
+// CHECK-NEXT:    0 | vbase_offset (24)
+// CHECK-NEXT:    1 | offset_to_top (0)
+// CHECK-NEXT:    2 | Test19::D RTTI
+// CHECK-NEXT:        -- (Test19::C, 0) vtable address --
+// CHECK-NEXT:        -- (Test19::D, 0) vtable address --
+// CHECK-NEXT:    3 | void Test19::C::c()
+// CHECK-NEXT:    4 | void Test19::D::f()
+// CHECK-NEXT:    5 | offset_to_top (-8)
+// CHECK-NEXT:    6 | Test19::D RTTI
+// CHECK-NEXT:        -- (Test19::A, 8) vtable address --
+// CHECK-NEXT:        -- (Test19::B, 8) vtable address --
+// CHECK-NEXT:    7 | void Test19::D::f()
+// CHECK-NEXT:        [this adjustment: -8 non-virtual]
+// CHECK-NEXT:    8 | void Test19::B::g()
+// CHECK-NEXT:    9 | vcall_offset (-24)
+// CHECK-NEXT:   10 | offset_to_top (-24)
+// CHECK-NEXT:   11 | Test19::D RTTI
+// CHECK-NEXT:        -- (Test19::A, 24) vtable address --
+// CHECK-NEXT:   12 | void Test19::D::f()
+// CHECK-NEXT:        [this adjustment: 0 non-virtual, -24 vcall offset offset]
+struct D : C, B, virtual A {
+  virtual void f();
+};
+void D::f() { }
+
+}
+
+namespace Test20 {
+
+// pure virtual member functions should never have 'this' adjustments.
+
+struct A {
+  virtual void f() = 0;
+  virtual void g();
+};
+
+struct B : A { };
+
+// CHECK:      Vtable for 'Test20::C' (9 entries).
+// CHECK-NEXT:    0 | offset_to_top (0)
+// CHECK-NEXT:    1 | Test20::C RTTI
+// CHECK-NEXT:        -- (Test20::A, 0) vtable address --
+// CHECK-NEXT:        -- (Test20::C, 0) vtable address --
+// CHECK-NEXT:    2 | void Test20::C::f() [pure]
+// CHECK-NEXT:    3 | void Test20::A::g()
+// CHECK-NEXT:    4 | void Test20::C::h()
+// CHECK-NEXT:    5 | offset_to_top (-8)
+// CHECK-NEXT:    6 | Test20::C RTTI
+// CHECK-NEXT:        -- (Test20::A, 8) vtable address --
+// CHECK-NEXT:        -- (Test20::B, 8) vtable address --
+// CHECK-NEXT:    7 | void Test20::C::f() [pure]
+// CHECK-NEXT:    8 | void Test20::A::g()
+struct C : A, B { 
+  virtual void f() = 0;
+  virtual void h();
+};
+void C::h() { }
+
+}
+
+namespace Test21 {
+
+// Test that we get vbase offsets right in secondary vtables.
+struct A { 
+  virtual void f();
+};
+
+struct B : virtual A { };
+class C : virtual B { };
+class D : virtual C { };
+
+class E : virtual C { };
+
+// CHECK:      Vtable for 'Test21::F' (16 entries).
+// CHECK-NEXT:    0 | vbase_offset (8)
+// CHECK-NEXT:    1 | vbase_offset (0)
+// CHECK-NEXT:    2 | vbase_offset (0)
+// CHECK-NEXT:    3 | vbase_offset (0)
+// CHECK-NEXT:    4 | vbase_offset (0)
+// CHECK-NEXT:    5 | vcall_offset (0)
+// CHECK-NEXT:    6 | offset_to_top (0)
+// CHECK-NEXT:    7 | Test21::F RTTI
+// CHECK-NEXT:        -- (Test21::A, 0) vtable address --
+// CHECK-NEXT:        -- (Test21::B, 0) vtable address --
+// CHECK-NEXT:        -- (Test21::C, 0) vtable address --
+// CHECK-NEXT:        -- (Test21::D, 0) vtable address --
+// CHECK-NEXT:        -- (Test21::F, 0) vtable address --
+// CHECK-NEXT:    8 | void Test21::F::f()
+// CHECK-NEXT:    9 | vbase_offset (-8)
+// CHECK-NEXT:   10 | vbase_offset (-8)
+// CHECK-NEXT:   11 | vbase_offset (-8)
+// CHECK-NEXT:   12 | vcall_offset (-8)
+// CHECK-NEXT:   13 | offset_to_top (-8)
+// CHECK-NEXT:   14 | Test21::F RTTI
+// CHECK-NEXT:        -- (Test21::E, 8) vtable address --
+// CHECK-NEXT:   15 | [unused] void Test21::F::f()
+//
+// CHECK:      Virtual base offset offsets for 'Test21::F' (5 entries).
+// CHECK-NEXT:    Test21::A | -32
+// CHECK-NEXT:    Test21::B | -40
+// CHECK-NEXT:    Test21::C | -48
+// CHECK-NEXT:    Test21::D | -56
+// CHECK-NEXT:    Test21::E | -64
+class F : virtual D, virtual E {
+  virtual void f();
+};
+void F::f() { }
+
+}
+
+namespace Test22 {
+
+// Very simple construction vtable test.
+struct V1 {
+  int v1;
+}; 
+
+struct V2 : virtual V1 {
+  int v2; 
+};
+
+// CHECK:      Vtable for 'Test22::C' (8 entries).
+// CHECK-NEXT:    0 | vbase_offset (16)
+// CHECK-NEXT:    1 | vbase_offset (12)
+// CHECK-NEXT:    2 | offset_to_top (0)
+// CHECK-NEXT:    3 | Test22::C RTTI
+// CHECK-NEXT:        -- (Test22::C, 0) vtable address --
+// CHECK-NEXT:    4 | void Test22::C::f()
+// CHECK-NEXT:    5 | vbase_offset (-4)
+// CHECK-NEXT:    6 | offset_to_top (-16)
+// CHECK-NEXT:    7 | Test22::C RTTI
+// CHECK-NEXT:        -- (Test22::V2, 16) vtable address --
+
+// CHECK:      Construction vtable for ('Test22::V2', 16) in 'Test22::C' (3 entries).
+// CHECK-NEXT:    0 | vbase_offset (-4)
+// CHECK-NEXT:    1 | offset_to_top (0)
+// CHECK-NEXT:    2 | Test22::V2 RTTI
+
+struct C : virtual V1, virtual V2 {
+  int c; 
+  virtual void f(); 
+};
+void C::f() { } 
+
+}
+
+namespace Test23 {
+
+struct A {
+  int a;
+};
+
+struct B : virtual A {
+  int b;
+};
+
+struct C : A, virtual B {
+  int c;
+};
+
+// CHECK:      Vtable for 'Test23::D' (7 entries).
+// CHECK-NEXT:    0 | vbase_offset (20)
+// CHECK-NEXT:    1 | vbase_offset (24)
+// CHECK-NEXT:    2 | offset_to_top (0)
+// CHECK-NEXT:    3 | Test23::D RTTI
+// CHECK-NEXT:        -- (Test23::C, 0) vtable address --
+// CHECK-NEXT:        -- (Test23::D, 0) vtable address --
+// CHECK-NEXT:    4 | vbase_offset (-4)
+// CHECK-NEXT:    5 | offset_to_top (-24)
+// CHECK-NEXT:    6 | Test23::D RTTI
+// CHECK-NEXT:        -- (Test23::B, 24) vtable address --
+
+// CHECK:      Construction vtable for ('Test23::C', 0) in 'Test23::D' (7 entries).
+// CHECK-NEXT:    0 | vbase_offset (20)
+// CHECK-NEXT:    1 | vbase_offset (24)
+// CHECK-NEXT:    2 | offset_to_top (0)
+// CHECK-NEXT:    3 | Test23::C RTTI
+// CHECK-NEXT:        -- (Test23::C, 0) vtable address --
+// CHECK-NEXT:    4 | vbase_offset (-4)
+// CHECK-NEXT:    5 | offset_to_top (-24)
+// CHECK-NEXT:    6 | Test23::C RTTI
+// CHECK-NEXT:        -- (Test23::B, 24) vtable address --
+
+// CHECK:      Construction vtable for ('Test23::B', 24) in 'Test23::D' (3 entries).
+// CHECK-NEXT:    0 | vbase_offset (-4)
+// CHECK-NEXT:    1 | offset_to_top (0)
+// CHECK-NEXT:    2 | Test23::B RTTI
+// CHECK-NEXT:        -- (Test23::B, 24) vtable address --
+
+struct D : virtual A, virtual B, C {
+  int d;
+
+  void f();
+};
+void D::f() { } 
+
+}
+
+namespace Test24 {
+
+// Another construction vtable test.
+
+struct A {
+  virtual void f();
+};
+
+struct B : virtual A { };
+struct C : virtual A { };
+
+// CHECK:      Vtable for 'Test24::D' (10 entries).
+// CHECK-NEXT:    0 | vbase_offset (0)
+// CHECK-NEXT:    1 | vcall_offset (0)
+// CHECK-NEXT:    2 | offset_to_top (0)
+// CHECK-NEXT:    3 | Test24::D RTTI
+// CHECK-NEXT:        -- (Test24::A, 0) vtable address --
+// CHECK-NEXT:        -- (Test24::B, 0) vtable address --
+// CHECK-NEXT:        -- (Test24::D, 0) vtable address --
+// CHECK-NEXT:    4 | void Test24::D::f()
+// CHECK-NEXT:    5 | vbase_offset (-8)
+// CHECK-NEXT:    6 | vcall_offset (-8)
+// CHECK-NEXT:    7 | offset_to_top (-8)
+// CHECK-NEXT:    8 | Test24::D RTTI
+// CHECK-NEXT:        -- (Test24::C, 8) vtable address --
+// CHECK-NEXT:    9 | [unused] void Test24::D::f()
+
+// CHECK:      Construction vtable for ('Test24::B', 0) in 'Test24::D' (5 entries).
+// CHECK-NEXT:    0 | vbase_offset (0)
+// CHECK-NEXT:    1 | vcall_offset (0)
+// CHECK-NEXT:    2 | offset_to_top (0)
+// CHECK-NEXT:    3 | Test24::B RTTI
+// CHECK-NEXT:        -- (Test24::A, 0) vtable address --
+// CHECK-NEXT:        -- (Test24::B, 0) vtable address --
+// CHECK-NEXT:    4 | void Test24::A::f()
+
+// CHECK:      Construction vtable for ('Test24::C', 8) in 'Test24::D' (9 entries).
+// CHECK-NEXT:    0 | vbase_offset (-8)
+// CHECK-NEXT:    1 | vcall_offset (-8)
+// CHECK-NEXT:    2 | offset_to_top (0)
+// CHECK-NEXT:    3 | Test24::C RTTI
+// CHECK-NEXT:        -- (Test24::C, 8) vtable address --
+// CHECK-NEXT:    4 | [unused] void Test24::A::f()
+// CHECK-NEXT:    5 | vcall_offset (0)
+// CHECK-NEXT:    6 | offset_to_top (8)
+// CHECK-NEXT:    7 | Test24::C RTTI
+// CHECK-NEXT:        -- (Test24::A, 0) vtable address --
+// CHECK-NEXT:    8 | void Test24::A::f()
+struct D : B, C {
+  virtual void f();
+};
+void D::f() { }
+
+}
+
+namespace Test25 {
+  
+// This mainly tests that we don't assert on this class hierarchy.
+
+struct V {
+  virtual void f();
+};
+
+struct A : virtual V { };
+struct B : virtual V { };
+
+// CHECK:      Vtable for 'Test25::C' (11 entries).
+// CHECK-NEXT:    0 | vbase_offset (0)
+// CHECK-NEXT:    1 | vcall_offset (0)
+// CHECK-NEXT:    2 | offset_to_top (0)
+// CHECK-NEXT:    3 | Test25::C RTTI
+// CHECK-NEXT:        -- (Test25::A, 0) vtable address --
+// CHECK-NEXT:        -- (Test25::C, 0) vtable address --
+// CHECK-NEXT:        -- (Test25::V, 0) vtable address --
+// CHECK-NEXT:    4 | void Test25::V::f()
+// CHECK-NEXT:    5 | void Test25::C::g()
+// CHECK-NEXT:    6 | vbase_offset (-8)
+// CHECK-NEXT:    7 | vcall_offset (-8)
+// CHECK-NEXT:    8 | offset_to_top (-8)
+// CHECK-NEXT:    9 | Test25::C RTTI
+// CHECK-NEXT:        -- (Test25::B, 8) vtable address --
+// CHECK-NEXT:   10 | [unused] void Test25::V::f()
+
+// CHECK:      Construction vtable for ('Test25::A', 0) in 'Test25::C' (5 entries).
+// CHECK-NEXT:    0 | vbase_offset (0)
+// CHECK-NEXT:    1 | vcall_offset (0)
+// CHECK-NEXT:    2 | offset_to_top (0)
+// CHECK-NEXT:    3 | Test25::A RTTI
+// CHECK-NEXT:        -- (Test25::A, 0) vtable address --
+// CHECK-NEXT:        -- (Test25::V, 0) vtable address --
+// CHECK-NEXT:    4 | void Test25::V::f()
+
+// CHECK:      Construction vtable for ('Test25::B', 8) in 'Test25::C' (9 entries).
+// CHECK-NEXT:    0 | vbase_offset (-8)
+// CHECK-NEXT:    1 | vcall_offset (-8)
+// CHECK-NEXT:    2 | offset_to_top (0)
+// CHECK-NEXT:    3 | Test25::B RTTI
+// CHECK-NEXT:        -- (Test25::B, 8) vtable address --
+// CHECK-NEXT:    4 | [unused] void Test25::V::f()
+// CHECK-NEXT:    5 | vcall_offset (0)
+// CHECK-NEXT:    6 | offset_to_top (8)
+// CHECK-NEXT:    7 | Test25::B RTTI
+// CHECK-NEXT:        -- (Test25::V, 0) vtable address --
+// CHECK-NEXT:    8 | void Test25::V::f()
+struct C : A, virtual V, B {
+  virtual void g();
+};
+void C::g() { }
+
+}
+
+namespace Test26 {
+
+// Test that we generate the right number of entries in the C-in-D construction vtable, and that
+// we don't mark A::a as unused.
+
+struct A {
+  virtual void a();
+};
+
+struct B {
+  virtual void c();
+};
+
+struct C : virtual A {
+  virtual void b();
+};
+
+// CHECK:      Vtable for 'Test26::D' (15 entries).
+// CHECK-NEXT:    0 | vbase_offset (8)
+// CHECK-NEXT:    1 | vbase_offset (8)
+// CHECK-NEXT:    2 | vbase_offset (0)
+// CHECK-NEXT:    3 | vcall_offset (0)
+// CHECK-NEXT:    4 | offset_to_top (0)
+// CHECK-NEXT:    5 | Test26::D RTTI
+// CHECK-NEXT:        -- (Test26::B, 0) vtable address --
+// CHECK-NEXT:        -- (Test26::D, 0) vtable address --
+// CHECK-NEXT:    6 | void Test26::B::c()
+// CHECK-NEXT:    7 | void Test26::D::d()
+// CHECK-NEXT:    8 | vcall_offset (0)
+// CHECK-NEXT:    9 | vbase_offset (0)
+// CHECK-NEXT:   10 | vcall_offset (0)
+// CHECK-NEXT:   11 | offset_to_top (-8)
+// CHECK-NEXT:   12 | Test26::D RTTI
+// CHECK-NEXT:        -- (Test26::A, 8) vtable address --
+// CHECK-NEXT:        -- (Test26::C, 8) vtable address --
+// CHECK-NEXT:   13 | void Test26::A::a()
+// CHECK-NEXT:   14 | void Test26::C::b()
+
+// CHECK:      Construction vtable for ('Test26::C', 8) in 'Test26::D' (7 entries).
+// CHECK-NEXT:    0 | vcall_offset (0)
+// CHECK-NEXT:    1 | vbase_offset (0)
+// CHECK-NEXT:    2 | vcall_offset (0)
+// CHECK-NEXT:    3 | offset_to_top (0)
+// CHECK-NEXT:    4 | Test26::C RTTI
+// CHECK-NEXT:        -- (Test26::A, 8) vtable address --
+// CHECK-NEXT:        -- (Test26::C, 8) vtable address --
+// CHECK-NEXT:    5 | void Test26::A::a()
+// CHECK-NEXT:    6 | void Test26::C::b()
+class D : virtual B, virtual C {
+  virtual void d();
+};
+void D::d() { } 
+
+}
+
+namespace Test27 {
+
+// Test that we don't generate a secondary vtable for C in the D-in-E vtable, since
+// C doesn't have any virtual bases.
+
+struct A {
+  virtual void a();
+};
+
+struct B {
+  virtual void b();
+};
+
+struct C {
+  virtual void c();
+};
+
+struct D : A, virtual B, C {
+  virtual void d();
+};
+
+// CHECK:      Vtable for 'Test27::E' (13 entries).
+// CHECK-NEXT:    0 | vbase_offset (16)
+// CHECK-NEXT:    1 | offset_to_top (0)
+// CHECK-NEXT:    2 | Test27::E RTTI
+// CHECK-NEXT:        -- (Test27::A, 0) vtable address --
+// CHECK-NEXT:        -- (Test27::D, 0) vtable address --
+// CHECK-NEXT:        -- (Test27::E, 0) vtable address --
+// CHECK-NEXT:    3 | void Test27::A::a()
+// CHECK-NEXT:    4 | void Test27::D::d()
+// CHECK-NEXT:    5 | void Test27::E::e()
+// CHECK-NEXT:    6 | offset_to_top (-8)
+// CHECK-NEXT:    7 | Test27::E RTTI
+// CHECK-NEXT:        -- (Test27::C, 8) vtable address --
+// CHECK-NEXT:    8 | void Test27::C::c()
+// CHECK-NEXT:    9 | vcall_offset (0)
+// CHECK-NEXT:   10 | offset_to_top (-16)
+// CHECK-NEXT:   11 | Test27::E RTTI
+// CHECK-NEXT:        -- (Test27::B, 16) vtable address --
+// CHECK-NEXT:   12 | void Test27::B::b()
+
+// CHECK:      Construction vtable for ('Test27::D', 0) in 'Test27::E' (9 entries).
+// CHECK-NEXT:    0 | vbase_offset (16)
+// CHECK-NEXT:    1 | offset_to_top (0)
+// CHECK-NEXT:    2 | Test27::D RTTI
+// CHECK-NEXT:        -- (Test27::A, 0) vtable address --
+// CHECK-NEXT:        -- (Test27::D, 0) vtable address --
+// CHECK-NEXT:    3 | void Test27::A::a()
+// CHECK-NEXT:    4 | void Test27::D::d()
+// CHECK-NEXT:    5 | vcall_offset (0)
+// CHECK-NEXT:    6 | offset_to_top (-16)
+// CHECK-NEXT:    7 | Test27::D RTTI
+// CHECK-NEXT:        -- (Test27::B, 16) vtable address --
+// CHECK-NEXT:    8 | void Test27::B::b()
+struct E : D {
+  virtual void e();
+};
+void E::e() { }
+
+}
+
+namespace Test28 {
+
+// Check that we do include the vtable for B in the D-in-E construction vtable, since
+// B is a base class of a virtual base (C).
+
+struct A {
+  virtual void a();
+};
+
+struct B {
+  virtual void b();
+};
+
+struct C : A, B {
+  virtual void c();
+};
+
+struct D : virtual C {
+};
+
+// CHECK:      Vtable for 'Test28::E' (14 entries).
+// CHECK-NEXT:    0 | vbase_offset (8)
+// CHECK-NEXT:    1 | offset_to_top (0)
+// CHECK-NEXT:    2 | Test28::E RTTI
+// CHECK-NEXT:        -- (Test28::D, 0) vtable address --
+// CHECK-NEXT:        -- (Test28::E, 0) vtable address --
+// CHECK-NEXT:    3 | void Test28::E::e()
+// CHECK-NEXT:    4 | vcall_offset (8)
+// CHECK-NEXT:    5 | vcall_offset (0)
+// CHECK-NEXT:    6 | vcall_offset (0)
+// CHECK-NEXT:    7 | offset_to_top (-8)
+// CHECK-NEXT:    8 | Test28::E RTTI
+// CHECK-NEXT:        -- (Test28::A, 8) vtable address --
+// CHECK-NEXT:        -- (Test28::C, 8) vtable address --
+// CHECK-NEXT:    9 | void Test28::A::a()
+// CHECK-NEXT:   10 | void Test28::C::c()
+// CHECK-NEXT:   11 | offset_to_top (-16)
+// CHECK-NEXT:   12 | Test28::E RTTI
+// CHECK-NEXT:        -- (Test28::B, 16) vtable address --
+// CHECK-NEXT:   13 | void Test28::B::b()
+
+// CHECK:      Construction vtable for ('Test28::D', 0) in 'Test28::E' (13 entries).
+// CHECK-NEXT:    0 | vbase_offset (8)
+// CHECK-NEXT:    1 | offset_to_top (0)
+// CHECK-NEXT:    2 | Test28::D RTTI
+// CHECK-NEXT:        -- (Test28::D, 0) vtable address --
+// CHECK-NEXT:    3 | vcall_offset (8)
+// CHECK-NEXT:    4 | vcall_offset (0)
+// CHECK-NEXT:    5 | vcall_offset (0)
+// CHECK-NEXT:    6 | offset_to_top (-8)
+// CHECK-NEXT:    7 | Test28::D RTTI
+// CHECK-NEXT:        -- (Test28::A, 8) vtable address --
+// CHECK-NEXT:        -- (Test28::C, 8) vtable address --
+// CHECK-NEXT:    8 | void Test28::A::a()
+// CHECK-NEXT:    9 | void Test28::C::c()
+// CHECK-NEXT:   10 | offset_to_top (-16)
+// CHECK-NEXT:   11 | Test28::D RTTI
+// CHECK-NEXT:        -- (Test28::B, 16) vtable address --
+// CHECK-NEXT:   12 | void Test28::B::b()
+struct E : D {
+  virtual void e();
+};
+void E::e() { }
+
+}
+
+namespace Test29 {
+
+// Test that the covariant return thunk for B::f will have a virtual 'this' adjustment,
+// matching gcc.
+
+struct V1 { };
+struct V2 : virtual V1 { };
+
+struct A {
+  virtual V1 *f();
+};
+
+// CHECK:      Vtable for 'Test29::B' (6 entries).
+// CHECK-NEXT:    0 | vbase_offset (0)
+// CHECK-NEXT:    1 | vcall_offset (0)
+// CHECK-NEXT:    2 | offset_to_top (0)
+// CHECK-NEXT:    3 | Test29::B RTTI
+// CHECK-NEXT:        -- (Test29::A, 0) vtable address --
+// CHECK-NEXT:        -- (Test29::B, 0) vtable address --
+// CHECK-NEXT:    4 | Test29::V2 *Test29::B::f()
+// CHECK-NEXT:        [return adjustment: 0 non-virtual, -24 vbase offset offset]
+// CHECK-NEXT:        [this adjustment: 0 non-virtual, -24 vcall offset offset]
+// CHECK-NEXT:    5 | Test29::V2 *Test29::B::f()
+struct B : virtual A {
+  virtual V2 *f();
+};
+V2 *B::f() { return 0; }
+
+}
+
+namespace Test30 {
+
+// Test that we don't assert when generating a vtable for F.
+struct A { };
+
+struct B : virtual A {
+ int i;
+};
+
+struct C {
+ virtual void f();
+};
+
+struct D : virtual C, B { };
+struct E : virtual D { };
+
+struct F : E {
+ virtual void f();
+};
+void F::f() { }
+
+}
+
+namespace Test31 {
+
+// Test that we don't add D::f twice to the primary vtable.
+struct A {
+  int a;
+};
+
+struct B {
+  virtual void f();
+};
+
+struct C : A, virtual B {
+  virtual void f();
+};
+
+// CHECK:      Vtable for 'Test31::D' (11 entries).
+// CHECK-NEXT:    0 | vbase_offset (0)
+// CHECK-NEXT:    1 | vbase_offset (8)
+// CHECK-NEXT:    2 | vcall_offset (0)
+// CHECK-NEXT:    3 | offset_to_top (0)
+// CHECK-NEXT:    4 | Test31::D RTTI
+// CHECK-NEXT:        -- (Test31::B, 0) vtable address --
+// CHECK-NEXT:        -- (Test31::D, 0) vtable address --
+// CHECK-NEXT:    5 | void Test31::D::f()
+// CHECK-NEXT:    6 | vbase_offset (-8)
+// CHECK-NEXT:    7 | vcall_offset (-8)
+// CHECK-NEXT:    8 | offset_to_top (-8)
+// CHECK-NEXT:    9 | Test31::D RTTI
+// CHECK-NEXT:        -- (Test31::C, 8) vtable address --
+// CHECK-NEXT:   10 | void Test31::D::f()
+// CHECK-NEXT:        [this adjustment: 0 non-virtual, -24 vcall offset offset]
+struct D : virtual C {
+  virtual void f();
+};
+void D::f() { }
+
+}
+
+namespace Test32 {
+
+// Check that we correctly lay out the virtual bases of 'Test32::D'.
+
+struct A {
+  virtual void f();
+};
+
+struct B : virtual A { };
+struct C : A, virtual B { };
+struct D : virtual B { };
+
+// CHECK:      Virtual base offset offsets for 'Test32::E' (3 entries).
+// CHECK-NEXT:    Test32::A | -32
+// CHECK-NEXT:    Test32::B | -24
+// CHECK-NEXT:    Test32::D | -40
+struct E : C, virtual D {
+  virtual void f();
+};
+void E::f() { }
+
+}
+
+namespace Test33 {
+
+// Test that we don't emit too many vcall offsets in 'Test32::F'.
+
+struct A {
+  virtual void a();
+};
+
+struct B {
+  virtual void b();
+};
+
+struct C : virtual A, virtual B {
+  virtual void c();
+};
+
+struct D : virtual C { };
+
+struct E : A, D { 
+  virtual void e();
+};
+
+// CHECK:      Vtable for 'Test33::F' (30 entries).
+// CHECK-NEXT:    0 | vbase_offset (24)
+// CHECK-NEXT:    1 | vbase_offset (16)
+// CHECK-NEXT:    2 | vbase_offset (16)
+// CHECK-NEXT:    3 | vbase_offset (8)
+// CHECK-NEXT:    4 | offset_to_top (0)
+// CHECK-NEXT:    5 | Test33::F RTTI
+// CHECK-NEXT:        -- (Test33::A, 0) vtable address --
+// CHECK-NEXT:        -- (Test33::F, 0) vtable address --
+// CHECK-NEXT:    6 | void Test33::A::a()
+// CHECK-NEXT:    7 | void Test33::F::f()
+// CHECK-NEXT:    8 | vcall_offset (0)
+// CHECK-NEXT:    9 | vcall_offset (0)
+// CHECK-NEXT:   10 | vbase_offset (16)
+// CHECK-NEXT:   11 | vbase_offset (8)
+// CHECK-NEXT:   12 | vbase_offset (8)
+// CHECK-NEXT:   13 | offset_to_top (-8)
+// CHECK-NEXT:   14 | Test33::F RTTI
+// CHECK-NEXT:        -- (Test33::A, 8) vtable address --
+// CHECK-NEXT:        -- (Test33::E, 8) vtable address --
+// CHECK-NEXT:   15 | void Test33::A::a()
+// CHECK-NEXT:   16 | void Test33::E::e()
+// CHECK-NEXT:   17 | vbase_offset (0)
+// CHECK-NEXT:   18 | vcall_offset (0)
+// CHECK-NEXT:   19 | vbase_offset (8)
+// CHECK-NEXT:   20 | vbase_offset (0)
+// CHECK-NEXT:   21 | vcall_offset (0)
+// CHECK-NEXT:   22 | offset_to_top (-16)
+// CHECK-NEXT:   23 | Test33::F RTTI
+// CHECK-NEXT:        -- (Test33::A, 16) vtable address --
+// CHECK-NEXT:        -- (Test33::C, 16) vtable address --
+// CHECK-NEXT:        -- (Test33::D, 16) vtable address --
+// CHECK-NEXT:   24 | void Test33::A::a()
+// CHECK-NEXT:   25 | void Test33::C::c()
+// CHECK-NEXT:   26 | vcall_offset (0)
+// CHECK-NEXT:   27 | offset_to_top (-24)
+// CHECK-NEXT:   28 | Test33::F RTTI
+// CHECK-NEXT:        -- (Test33::B, 24) vtable address --
+// CHECK-NEXT:   29 | void Test33::B::b()
+struct F : virtual E, A {
+  virtual void f();
+};
+void F::f() { }
+
+}
+
+namespace Test34 {
+
+// Test that we lay out the construction vtable for 'Test34::E' in 'Test34::F' correctly.
+
+struct A {
+  virtual void a();
+};
+struct B : virtual A { };
+
+struct C : B, A {
+  virtual void c();
+};
+
+struct D : A, C { };
+
+struct E : virtual D {
+  virtual void e();
+};
+
+// CHECK:      Construction vtable for ('Test34::E', 0) in 'Test34::F' (22 entries).
+// CHECK-NEXT:    0 | vbase_offset (0)
+// CHECK-NEXT:    1 | vbase_offset (8)
+// CHECK-NEXT:    2 | vcall_offset (0)
+// CHECK-NEXT:    3 | offset_to_top (0)
+// CHECK-NEXT:    4 | Test34::E RTTI
+// CHECK-NEXT:        -- (Test34::A, 0) vtable address --
+// CHECK-NEXT:        -- (Test34::E, 0) vtable address --
+// CHECK-NEXT:    5 | void Test34::A::a()
+// CHECK-NEXT:    6 | void Test34::E::e()
+// CHECK-NEXT:    7 | vcall_offset (8)
+// CHECK-NEXT:    8 | vcall_offset (0)
+// CHECK-NEXT:    9 | vbase_offset (-8)
+// CHECK-NEXT:   10 | offset_to_top (-8)
+// CHECK-NEXT:   11 | Test34::E RTTI
+// CHECK-NEXT:        -- (Test34::A, 8) vtable address --
+// CHECK-NEXT:        -- (Test34::D, 8) vtable address --
+// CHECK-NEXT:   12 | void Test34::A::a()
+// CHECK-NEXT:   13 | vbase_offset (-16)
+// CHECK-NEXT:   14 | vcall_offset (-16)
+// CHECK-NEXT:   15 | offset_to_top (-16)
+// CHECK-NEXT:   16 | Test34::E RTTI
+// CHECK-NEXT:        -- (Test34::B, 16) vtable address --
+// CHECK-NEXT:        -- (Test34::C, 16) vtable address --
+// CHECK-NEXT:   17 | [unused] void Test34::A::a()
+// CHECK-NEXT:   18 | void Test34::C::c()
+// CHECK-NEXT:   19 | offset_to_top (-24)
+// CHECK-NEXT:   20 | Test34::E RTTI
+// CHECK-NEXT:        -- (Test34::A, 24) vtable address --
+// CHECK-NEXT:   21 | void Test34::A::a()
+struct F : E {
+  virtual void f();
+};
+void F::f() { }
+
+}
+
+namespace Test35 {
+
+// Test that we lay out the virtual bases of 'Test35::H' in the correct order.
+
+struct A {
+ virtual void a();
+
+ int i;
+};
+
+struct B : virtual A {
+ virtual void b();
+};
+
+struct C {
+ virtual void c();
+};
+
+struct D : C, virtual B {
+ virtual void d();
+};
+
+struct E : D {
+ virtual void e();
+
+ bool b;
+};
+
+struct F : virtual D { };
+struct G : virtual E { };
+
+// CHECK:      Vtable for 'Test35::H' (32 entries).
+// CHECK-NEXT:    0 | vbase_offset (32)
+// CHECK-NEXT:    1 | vbase_offset (0)
+// CHECK-NEXT:    2 | vcall_offset (0)
+// CHECK-NEXT:    3 | vcall_offset (0)
+// CHECK-NEXT:    4 | vbase_offset (16)
+// CHECK-NEXT:    5 | vbase_offset (8)
+// CHECK-NEXT:    6 | offset_to_top (0)
+// CHECK-NEXT:    7 | Test35::H RTTI
+// CHECK-NEXT:        -- (Test35::C, 0) vtable address --
+// CHECK-NEXT:        -- (Test35::D, 0) vtable address --
+// CHECK-NEXT:        -- (Test35::F, 0) vtable address --
+// CHECK-NEXT:        -- (Test35::H, 0) vtable address --
+// CHECK-NEXT:    8 | void Test35::C::c()
+// CHECK-NEXT:    9 | void Test35::D::d()
+// CHECK-NEXT:   10 | void Test35::H::h()
+// CHECK-NEXT:   11 | vbase_offset (0)
+// CHECK-NEXT:   12 | vbase_offset (24)
+// CHECK-NEXT:   13 | vcall_offset (0)
+// CHECK-NEXT:   14 | vbase_offset (8)
+// CHECK-NEXT:   15 | offset_to_top (-8)
+// CHECK-NEXT:   16 | Test35::H RTTI
+// CHECK-NEXT:        -- (Test35::B, 8) vtable address --
+// CHECK-NEXT:        -- (Test35::G, 8) vtable address --
+// CHECK-NEXT:   17 | void Test35::B::b()
+// CHECK-NEXT:   18 | vcall_offset (0)
+// CHECK-NEXT:   19 | offset_to_top (-16)
+// CHECK-NEXT:   20 | Test35::H RTTI
+// CHECK-NEXT:        -- (Test35::A, 16) vtable address --
+// CHECK-NEXT:   21 | void Test35::A::a()
+// CHECK-NEXT:   22 | vcall_offset (0)
+// CHECK-NEXT:   23 | vcall_offset (0)
+// CHECK-NEXT:   24 | vcall_offset (0)
+// CHECK-NEXT:   25 | vbase_offset (-16)
+// CHECK-NEXT:   26 | vbase_offset (-24)
+// CHECK-NEXT:   27 | offset_to_top (-32)
+// CHECK-NEXT:   28 | Test35::H RTTI
+// CHECK-NEXT:        -- (Test35::C, 32) vtable address --
+// CHECK-NEXT:        -- (Test35::D, 32) vtable address --
+// CHECK-NEXT:        -- (Test35::E, 32) vtable address --
+// CHECK-NEXT:   29 | void Test35::C::c()
+// CHECK-NEXT:   30 | void Test35::D::d()
+// CHECK-NEXT:   31 | void Test35::E::e()
+
+// CHECK:      Virtual base offset offsets for 'Test35::H' (4 entries).
+// CHECK-NEXT:    Test35::A | -32
+// CHECK-NEXT:    Test35::B | -24
+// CHECK-NEXT:    Test35::D | -56
+// CHECK-NEXT:    Test35::E | -64
+struct H : F, G {
+ virtual void h();
+};
+void H::h() { }
+
+}
+
+namespace Test36 {
+
+// Test that we don't mark B::f as unused in the vtable for D.
+
+struct A {
+ virtual void f();
+};
+
+struct B : virtual A { };
+
+struct C : virtual A {
+ virtual void f();
+};
+
+// CHECK:      Vtable for 'Test36::D' (12 entries).
+// CHECK-NEXT:    0 | vbase_offset (8)
+// CHECK-NEXT:    1 | vbase_offset (8)
+// CHECK-NEXT:    2 | vcall_offset (0)
+// CHECK-NEXT:    3 | offset_to_top (0)
+// CHECK-NEXT:    4 | Test36::D RTTI
+// CHECK-NEXT:        -- (Test36::C, 0) vtable address --
+// CHECK-NEXT:        -- (Test36::D, 0) vtable address --
+// CHECK-NEXT:    5 | void Test36::C::f()
+// CHECK-NEXT:    6 | void Test36::D::g()
+// CHECK-NEXT:    7 | vbase_offset (0)
+// CHECK-NEXT:    8 | vcall_offset (-8)
+// CHECK-NEXT:    9 | offset_to_top (-8)
+// CHECK-NEXT:   10 | Test36::D RTTI
+// CHECK-NEXT:        -- (Test36::A, 8) vtable address --
+// CHECK-NEXT:        -- (Test36::B, 8) vtable address --
+// CHECK-NEXT:   11 | void Test36::C::f()
+// CHECK-NEXT:        [this adjustment: 0 non-virtual, -24 vcall offset offset]
+struct D : virtual B, C {
+ virtual void g();
+};
+void D::g() { }
+
+}
diff --git a/test/CodeGenCXX/vtable-linkage.cpp b/test/CodeGenCXX/vtable-linkage.cpp
new file mode 100644
index 0000000..c75efe2
--- /dev/null
+++ b/test/CodeGenCXX/vtable-linkage.cpp
@@ -0,0 +1,151 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+
+namespace {
+  struct A {
+    virtual void f() { }
+  };
+}
+
+void f() { A b; }
+
+struct B {
+  B();
+  virtual void f();
+};
+
+B::B() { }
+
+struct C {
+  C();
+  virtual void f() { } 
+};
+
+C::C() { } 
+
+struct D {
+  virtual void f();
+};
+
+void D::f() { }
+
+static struct : D { } e;
+
+// The destructor is the key function.
+template<typename T>
+struct E {
+  virtual ~E();
+};
+
+template<typename T> E<T>::~E() { }
+
+// Anchor is the key function
+template<>
+struct E<char> {
+  virtual void anchor();
+};
+
+void E<char>::anchor() { }
+
+template struct E<short>;
+extern template struct E<int>;
+
+void use_E() {
+  E<int> ei;
+  (void)ei;
+  E<long> el;
+  (void)el;
+}
+
+// No key function
+template<typename T>
+struct F {
+  virtual void foo() { }
+};
+
+// No key function
+template<>
+struct F<char> {
+  virtual void foo() { }
+};
+
+template struct F<short>;
+extern template struct F<int>;
+
+void use_F(F<char> &fc) {
+  F<int> fi;
+  (void)fi;
+  F<long> fl;
+  (void)fl;
+  fc.foo();
+}
+
+// B has a key function that is not defined in this translation unit so its vtable
+// has external linkage.
+// CHECK: @_ZTV1B = external constant
+
+// C has no key function, so its vtable should have weak_odr linkage.
+// CHECK: @_ZTV1C = weak_odr constant
+// CHECK: @_ZTS1C = weak_odr constant
+// CHECK: @_ZTI1C = weak_odr constant
+
+// D has a key function that is defined in this translation unit so its vtable is
+// defined in the translation unit.
+// CHECK: @_ZTV1D = constant
+// CHECK: @_ZTS1D = constant
+// CHECK: @_ZTI1D = constant
+
+// E<char> is an explicit specialization with a key function defined
+// in this translation unit, so its vtable should have external
+// linkage.
+// CHECK: @_ZTV1EIcE = constant
+// CHECK: @_ZTS1EIcE = constant
+// CHECK: @_ZTI1EIcE = constant
+
+// E<short> is an explicit template instantiation with a key function
+// defined in this translation unit, so its vtable should have
+// weak_odr linkage.
+// CHECK: @_ZTV1EIsE = weak_odr constant
+// CHECK: @_ZTS1EIsE = weak_odr constant
+// CHECK: @_ZTI1EIsE = weak_odr constant
+
+// F<short> is an explicit template instantiation without a key
+// function, so its vtable should have weak_odr linkage
+// CHECK: @_ZTV1FIsE = weak_odr constant
+// CHECK: @_ZTS1FIsE = weak_odr constant
+// CHECK: @_ZTI1FIsE = weak_odr constant
+
+// E<long> is an implicit template instantiation with a key function
+// defined in this translation unit, so its vtable should have
+// weak_odr linkage.
+// CHECK: @_ZTV1EIlE = weak_odr constant
+// CHECK: @_ZTS1EIlE = weak_odr constant
+// CHECK: @_ZTI1EIlE = weak_odr constant
+
+// F<long> is an implicit template instantiation with no key function,
+// so its vtable should have weak_odr linkage.
+// CHECK: @_ZTV1FIlE = weak_odr constant
+// CHECK: @_ZTS1FIlE = weak_odr constant
+// CHECK: @_ZTI1FIlE = weak_odr constant
+
+// F<int> is an explicit template instantiation declaration without a
+// key function, so its vtable should have external linkage.
+// CHECK: @_ZTV1FIiE = external constant
+
+// E<int> is an explicit template instantiation declaration. It has a
+// key function that is not instantiated, so we should only reference
+// its vtable, not define it.
+// CHECK: @_ZTV1EIiE = external constant
+
+// The anonymous struct for e has no linkage, so the vtable should have
+// internal linkage.
+// CHECK: @"_ZTV3$_0" = internal constant
+// CHECK: @"_ZTS3$_0" = internal constant
+// CHECK: @"_ZTI3$_0" = internal constant
+
+// The A vtable should have internal linkage since it is inside an anonymous 
+// namespace.
+// CHECK: @_ZTVN12_GLOBAL__N_11AE = internal constant
+// CHECK: @_ZTSN12_GLOBAL__N_11AE = internal constant
+// CHECK: @_ZTIN12_GLOBAL__N_11AE = internal constant
+
+
diff --git a/test/CodeGenCXX/vtable-pointer-initialization.cpp b/test/CodeGenCXX/vtable-pointer-initialization.cpp
new file mode 100644
index 0000000..75620ab
--- /dev/null
+++ b/test/CodeGenCXX/vtable-pointer-initialization.cpp
@@ -0,0 +1,57 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+
+struct Field {
+  Field();
+  ~Field();
+};
+
+struct Base {
+  Base();
+  ~Base();
+};
+
+struct A : Base {
+  A();
+  ~A();
+
+  virtual void f();
+  
+  Field field;
+};
+
+// CHECK: define void @_ZN1AC2Ev(
+// CHECK: call void @_ZN4BaseC2Ev(
+// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTV1A, i64 0, i64 2)
+// CHECK: call void @_ZN5FieldC1Ev(
+// CHECK: ret void
+A::A() { }
+
+// CHECK: define void @_ZN1AD2Ev(
+// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTV1A, i64 0, i64 2)
+// CHECK: call void @_ZN5FieldD1Ev(
+// CHECK: call void @_ZN4BaseD2Ev(
+// CHECK: ret void
+A::~A() { } 
+
+struct B : Base {
+  virtual void f();
+  
+  Field field;
+};
+
+void f() { B b; }
+
+// CHECK: define linkonce_odr void @_ZN1BC1Ev(
+// CHECK: call void @_ZN1BC2Ev(
+
+// CHECK: define linkonce_odr void @_ZN1BD1Ev(
+// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTV1B, i64 0, i64 2)
+// CHECK: call void @_ZN5FieldD1Ev(
+// CHECK: call void @_ZN4BaseD2Ev(
+// CHECK: ret void
+
+// CHECK: define linkonce_odr void @_ZN1BC2Ev(
+// CHECK: call void @_ZN4BaseC2Ev(
+// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTV1B, i64 0, i64 2)
+// CHECK: call void @_ZN5FieldC1Ev
+// CHECK: ret void
diff --git a/test/CodeGenCXX/vtt-layout.cpp b/test/CodeGenCXX/vtt-layout.cpp
new file mode 100644
index 0000000..d7d4227
--- /dev/null
+++ b/test/CodeGenCXX/vtt-layout.cpp
@@ -0,0 +1,64 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+
+// Test1::B should just have a single entry in its VTT, which points to the vtable.
+namespace Test1 {
+struct A { };
+
+struct B : virtual A { 
+  virtual void f();
+};
+
+void B::f() { } 
+}
+
+// Check that we don't add a secondary virtual pointer for Test2::A, since Test2::A doesn't have any virtual member functions or bases.
+namespace Test2 {
+  struct A { };
+
+  struct B : A { virtual void f(); };
+  struct C : virtual B { };
+
+  C c;
+}
+
+// This is the sample from the C++ Itanium ABI, p2.6.2.
+namespace Test3 {
+  class A1 { int i; };
+  class A2 { int i; virtual void f(); };
+  class V1 : public A1, public A2 { int i; };
+  class B1 { int i; };
+  class B2 { int i; };
+  class V2 : public B1, public B2, public virtual V1 { int i; };
+  class V3 {virtual void g(); };
+  class C1 : public virtual V1 { int i; };
+  class C2 : public virtual V3, virtual V2 { int i; };
+  class X1 { int i; };
+  class C3 : public X1 { int i; };
+  class D : public C1, public C2, public C3 { int i;  };
+  
+  D d;
+}
+
+// This is the sample from the C++ Itanium ABI, p2.6.2, with the change suggested
+// (making A2 a virtual base of V1)
+namespace Test4 {
+  class A1 { int i; };
+  class A2 { int i; virtual void f(); };
+  class V1 : public A1, public virtual A2 { int i; };
+  class B1 { int i; };
+  class B2 { int i; };
+  class V2 : public B1, public B2, public virtual V1 { int i; };
+  class V3 {virtual void g(); };
+  class C1 : public virtual V1 { int i; };
+  class C2 : public virtual V3, virtual V2 { int i; };
+  class X1 { int i; };
+  class C3 : public X1 { int i; };
+  class D : public C1, public C2, public C3 { int i;  };
+  
+  D d;
+}
+
+// CHECK: @_ZTTN5Test11BE = constant [1 x i8*] [i8* bitcast (i8** getelementptr inbounds ([4 x i8*]* @_ZTVN5Test11BE, i64 0, i64 3) to i8*)]
+// CHECK: @_ZTTN5Test41DE = weak_odr constant [19 x i8*] [i8* bitcast (i8** getelementptr inbounds ([25 x i8*]* @_ZTVN5Test41DE, i64 0, i64 6) to i8*), i8* bitcast (i8** getelementptr inbounds ([11 x i8*]* @_ZTCN5Test41DE0_NS_2C1E, i64 0, i64 4) to i8*), i8* bitcast (i8** getelementptr inbounds ([11 x i8*]* @_ZTCN5Test41DE0_NS_2C1E, i64 0, i64 7) to i8*), i8* bitcast (i8** getelementptr inbounds ([11 x i8*]* @_ZTCN5Test41DE0_NS_2C1E, i64 0, i64 10) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*]* @_ZTCN5Test41DE16_NS_2C2E, i64 0, i64 7) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*]* @_ZTCN5Test41DE16_NS_2C2E, i64 0, i64 7) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*]* @_ZTCN5Test41DE16_NS_2C2E, i64 0, i64 12) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*]* @_ZTCN5Test41DE16_NS_2C2E, i64 0, i64 15) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*]* @_ZTCN5Test41DE16_NS_2C2E, i64 0, i64 18) to i8*), i8* bitcast (i8** getelementptr inbounds ([25 x i8*]* @_ZTVN5Test41DE, i64 0, i64 17) to i8*), i8* bitcast (i8** getelementptr inbounds ([25 x i8*]* @_ZTVN5Test41DE, i64 0, i64 20) to i8*), i8* bitcast (i8** getelementptr inbounds ([25 x i8*]* @_ZTVN5Test41DE, i64 0, i64 13) to i8*), i8* bitcast (i8** getelementptr inbounds ([25 x i8*]* @_ZTVN5Test41DE, i64 0, i64 13) to i8*), i8* bitcast (i8** getelementptr inbounds ([25 x i8*]* @_ZTVN5Test41DE, i64 1, i64 0) to i8*), i8* bitcast (i8** getelementptr inbounds ([7 x i8*]* @_ZTCN5Test41DE40_NS_2V1E, i64 0, i64 3) to i8*), i8* bitcast (i8** getelementptr inbounds ([7 x i8*]* @_ZTCN5Test41DE40_NS_2V1E, i64 0, i64 6) to i8*), i8* bitcast (i8** getelementptr inbounds ([11 x i8*]* @_ZTCN5Test41DE72_NS_2V2E, i64 0, i64 4) to i8*), i8* bitcast (i8** getelementptr inbounds ([11 x i8*]* @_ZTCN5Test41DE72_NS_2V2E, i64 0, i64 7) to i8*), i8* bitcast (i8** getelementptr inbounds ([11 x i8*]* @_ZTCN5Test41DE72_NS_2V2E, i64 0, i64 10) to i8*)] ; <[19 x i8*]*> [#uses=4]
+// CHECK: @_ZTTN5Test31DE = weak_odr constant [13 x i8*] [i8* bitcast (i8** getelementptr inbounds ([19 x i8*]* @_ZTVN5Test31DE, i64 0, i64 5) to i8*), i8* bitcast (i8** getelementptr inbounds ([7 x i8*]* @_ZTCN5Test31DE0_NS_2C1E, i64 0, i64 3) to i8*), i8* bitcast (i8** getelementptr inbounds ([7 x i8*]* @_ZTCN5Test31DE0_NS_2C1E, i64 0, i64 6) to i8*), i8* bitcast (i8** getelementptr inbounds ([14 x i8*]* @_ZTCN5Test31DE16_NS_2C2E, i64 0, i64 6) to i8*), i8* bitcast (i8** getelementptr inbounds ([14 x i8*]* @_ZTCN5Test31DE16_NS_2C2E, i64 0, i64 6) to i8*), i8* bitcast (i8** getelementptr inbounds ([14 x i8*]* @_ZTCN5Test31DE16_NS_2C2E, i64 0, i64 10) to i8*), i8* bitcast (i8** getelementptr inbounds ([14 x i8*]* @_ZTCN5Test31DE16_NS_2C2E, i64 0, i64 13) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*]* @_ZTVN5Test31DE, i64 0, i64 15) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*]* @_ZTVN5Test31DE, i64 0, i64 11) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*]* @_ZTVN5Test31DE, i64 0, i64 11) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*]* @_ZTVN5Test31DE, i64 1, i64 0) to i8*), i8* bitcast (i8** getelementptr inbounds ([7 x i8*]* @_ZTCN5Test31DE64_NS_2V2E, i64 0, i64 3) to i8*), i8* bitcast (i8** getelementptr inbounds ([7 x i8*]* @_ZTCN5Test31DE64_NS_2V2E, i64 0, i64 6) to i8*)] ; <[13 x i8*]*> [#uses=3]
+// CHECK: @_ZTTN5Test21CE = weak_odr constant [2 x i8*] [i8* bitcast (i8** getelementptr inbounds ([5 x i8*]* @_ZTVN5Test21CE, i64 0, i64 4) to i8*), i8* bitcast (i8** getelementptr inbounds ([5 x i8*]* @_ZTVN5Test21CE, i64 0, i64 4) to i8*)] ; <[2 x i8*]*> [#uses=0]
diff --git a/test/CodeGenCXX/x86_32-arguments.cpp b/test/CodeGenCXX/x86_32-arguments.cpp
new file mode 100644
index 0000000..f8d6551
--- /dev/null
+++ b/test/CodeGenCXX/x86_32-arguments.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -o - %s | FileCheck %s
+
+// Non-trivial dtors, should both be passed indirectly.
+struct S {
+  ~S();
+  int s;
+};
+
+// CHECK: define void @_Z1fv(%struct.S* sret %
+S f() { return S(); }
+// CHECK: define void @_Z1f1S(%struct.S*)
+void f(S) { }
+
+// Non-trivial dtors, should both be passed indirectly.
+class C {
+  ~C();
+  double c;
+};
+
+// CHECK: define void @_Z1gv(%class.C* sret %
+C g() { return C(); }
+
+// CHECK: define void @_Z1f1C(%class.C*) 
+void f(C) { }
diff --git a/test/CodeGenCXX/x86_64-arguments.cpp b/test/CodeGenCXX/x86_64-arguments.cpp
new file mode 100644
index 0000000..7ebbedc
--- /dev/null
+++ b/test/CodeGenCXX/x86_64-arguments.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s
+
+// CHECK: [[i64_i64_ty:%.*]] = type { i64, i64 }
+// CHECK: [[i64_double_ty:%.*]] = type { i64, double }
+
+// Basic base class test.
+struct f0_s0 { unsigned a; };
+struct f0_s1 : public f0_s0 { void *b; };
+// CHECK: define void @_Z2f05f0_s1([[i64_i64_ty]])
+void f0(f0_s1 a0) { }
+
+// Check with two eight-bytes in base class.
+struct f1_s0 { unsigned a; unsigned b; float c; };
+struct f1_s1 : public f1_s0 { float d;};
+// CHECK: define void @_Z2f15f1_s1([[i64_double_ty]])
+void f1(f1_s1 a0) { }
+
+// Check with two eight-bytes in base class and merge.
+struct f2_s0 { unsigned a; unsigned b; float c; };
+struct f2_s1 : public f2_s0 { char d;};
+// CHECK: define void @_Z2f25f2_s1([[i64_i64_ty]])
+void f2(f2_s1 a0) { }
+
+// PR5831
+struct s3_0 {};
+struct s3_1 { struct s3_0 a; long b; };
+void f3(struct s3_1 x) {}
diff --git a/test/CodeGenObjC/2008-10-23-invalid-icmp.m b/test/CodeGenObjC/2008-10-23-invalid-icmp.m
new file mode 100644
index 0000000..ce01bdb
--- /dev/null
+++ b/test/CodeGenObjC/2008-10-23-invalid-icmp.m
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -emit-llvm -o %t %s
+
+@protocol P @end
+
+int f0(id<P> d) {
+  return (d != ((void*) 0));
+}
diff --git a/test/CodeGenObjC/atomic-aggregate-property.m b/test/CodeGenObjC/atomic-aggregate-property.m
new file mode 100644
index 0000000..2896d37
--- /dev/null
+++ b/test/CodeGenObjC/atomic-aggregate-property.m
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10  -fobjc-nonfragile-abi -fobjc-gc -emit-llvm -o - %s | FileCheck -check-prefix LP64 %s
+// rdar: // 7849824
+
+struct s {
+  double a, b, c, d;  
+};
+
+struct s1 {
+    int i;
+    id j;
+    id k;
+};
+
+@interface A 
+@property (readwrite) double x;
+@property (readwrite) struct s y;
+@property (nonatomic, readwrite) struct s1 z;
+@end
+
+@implementation A
+@synthesize x;
+@synthesize y;
+@synthesize z;
+@end
+
+// CHECK-LP64: call void @objc_copyStruct
+// CHECK-LP64: call void @objc_copyStruct
+// CHECK-LP64: call void @objc_copyStruct
diff --git a/test/CodeGenObjC/attr-strong.c b/test/CodeGenObjC/attr-strong.c
new file mode 100644
index 0000000..f1474bc
--- /dev/null
+++ b/test/CodeGenObjC/attr-strong.c
@@ -0,0 +1,9 @@
+// RUN: %clang -emit-llvm -S -o %t %s
+
+struct s0 {
+  void *a;
+};
+struct s0 * __attribute__((objc_gc(strong))) g0;
+void f0(void) {
+  g0->a = 0;
+}
diff --git a/test/CodeGenObjC/bitfield-1.m b/test/CodeGenObjC/bitfield-1.m
new file mode 100644
index 0000000..978b3cc
--- /dev/null
+++ b/test/CodeGenObjC/bitfield-1.m
@@ -0,0 +1,81 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -emit-llvm -o %t %s
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -emit-llvm -o %t %s
+// RUN: %clang_cc1 -triple i386-pc-linux-gnu -emit-llvm -o %t %s
+
+@interface Object
+- (id) alloc;
+- (id) init;
+@end
+
+extern void abort(void);
+
+#define CHECK_IF(expr) if(!(expr)) abort();
+
+@interface Base: Object 
+{
+    int full;
+    int full2: 32;
+    int _refs: 8;
+    int field2: 3;
+    unsigned f3: 8;
+    short cc;
+    unsigned g: 16;
+    int r2: 8;
+    int r3: 8;
+    int r4: 2;
+    int r5: 8;
+    char c;
+}
+- (void)setValues;
+@end
+
+@interface Derived: Base
+{
+    char d;
+    int _field3: 6;
+}
+- (void)checkValues;
+@end
+
+@implementation Base
+-(void)setValues {
+  full = 1;
+  full2 = 2;
+  _refs = 3;
+  field2 = 1;
+  f3 = 6;
+  cc = 7;
+  g = 8;
+  r2 = 9;
+  r3 = 10;
+  r4 = 1;
+  r5 = 12;
+  c = 13;
+}
+@end
+
+@implementation Derived
+-(void)checkValues {
+  CHECK_IF(full == 1);
+  CHECK_IF(full2 == 2);
+  CHECK_IF(_refs == 3);
+  CHECK_IF(field2 == 1);
+  CHECK_IF(f3 == 6);
+  CHECK_IF(cc == 7);
+  CHECK_IF(g == 8);
+  CHECK_IF(r2 == 9);
+  CHECK_IF(r3 == 10);
+  CHECK_IF(r4 == 1);
+  CHECK_IF(r5 == 12);
+  CHECK_IF(c == 13);
+}
+@end
+
+int main(void) {
+  Derived *obj = [[Derived alloc] init];
+
+  [obj setValues];
+  [obj checkValues];
+
+  return 0;
+}
diff --git a/test/CodeGenObjC/bitfield-ivar-metadata.m b/test/CodeGenObjC/bitfield-ivar-metadata.m
new file mode 100644
index 0000000..9ab3fef
--- /dev/null
+++ b/test/CodeGenObjC/bitfield-ivar-metadata.m
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -emit-llvm -o %t %s
+
+@interface INTF
+{
+    unsigned ivar1;
+    unsigned ivar2;
+    unsigned char BDIVAR3:1;
+    unsigned char BDIVAR4:1;
+}
+@end
+
+@implementation INTF
+@end
+
+
diff --git a/test/CodeGenObjC/bitfield-ivar-offsets.m b/test/CodeGenObjC/bitfield-ivar-offsets.m
new file mode 100644
index 0000000..e0eebe1
--- /dev/null
+++ b/test/CodeGenObjC/bitfield-ivar-offsets.m
@@ -0,0 +1,25 @@
+// RUNX: llvm-gcc -m64  -emit-llvm -S -o %t %s &&
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -emit-llvm -o %t %s
+// RUN: grep -F '@"OBJC_IVAR_$_I0._b0" = global i64 0, section "__DATA, __objc_const", align 8' %t
+// RUN: grep -F '@"OBJC_IVAR_$_I0._b1" = global i64 0, section "__DATA, __objc_const", align 8' %t
+// RUN: grep -F '@"OBJC_IVAR_$_I0._b2" = global i64 1, section "__DATA, __objc_const", align 8' %t
+// RUN: grep -F '@"OBJC_IVAR_$_I0._x" = global i64 2, section "__DATA, __objc_const", align 8' %t
+// RUN: grep -F '@"OBJC_IVAR_$_I0._b3" = global i64 4, section "__DATA, __objc_const", align 8' %t
+// RUN: grep -F '@"OBJC_IVAR_$_I0._y" = global i64 6, section "__DATA, __objc_const", align 8' %t
+// RUN: grep -F '@"OBJC_IVAR_$_I0._b4" = global i64 7, section "__DATA, __objc_const", align 8' %t
+// RUN: grep -F '@"OBJC_IVAR_$_I0." = global' %t | count 0
+
+@interface I0 {
+  unsigned _b0:4;
+  unsigned _b1:5;
+  unsigned _b2:5;
+  char _x;
+  unsigned _b3:9;
+  char _y;
+  char _b4:3;
+  char : 0;
+}
+@end
+
+@implementation I0
+@end
diff --git a/test/CodeGenObjC/blocks-1.m b/test/CodeGenObjC/blocks-1.m
new file mode 100644
index 0000000..76bfd59
--- /dev/null
+++ b/test/CodeGenObjC/blocks-1.m
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 %s -emit-llvm -o %t -fobjc-gc -fblocks -triple i386-apple-darwin10
+// RUN: grep "_Block_object_dispose" %t | count 6
+// RUN: grep "__copy_helper_block_" %t | count 4
+// RUN: grep "__destroy_helper_block_" %t | count 4
+// RUN: grep "__Block_byref_id_object_copy_" %t | count 2
+// RUN: grep "__Block_byref_id_object_dispose_" %t | count 2
+// RUN: grep "i32 135)" %t | count 0
+// RUN: grep "_Block_object_assign" %t | count 4
+// RUN: grep "objc_read_weak" %t | count 2
+// RUN: grep "objc_assign_weak" %t | count 3
+
+@interface NSDictionary @end
+
+void test1(NSDictionary * dict) {
+  ^{ (void)dict; }();
+}
+
+@interface D
+@end
+
+void foo() {
+  __block __weak D *weakSelf;
+  D *l;
+  l = weakSelf;
+  weakSelf = l;
+}
+
+void (^__weak b)(void);
+
+void test2() {
+  __block int i = 0;
+  b = ^ {  ++i; };
+}
diff --git a/test/CodeGenObjC/blocks-2.m b/test/CodeGenObjC/blocks-2.m
new file mode 100644
index 0000000..15160cc
--- /dev/null
+++ b/test/CodeGenObjC/blocks-2.m
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 %s -emit-llvm -o %t -fobjc-gc -fblocks -triple i386-apple-darwin10
+// RUN: grep "objc_assign_strongCast" %t | count 2
+
+// This should generate a strong cast.
+
+id test3(id x) {
+  __block id result;
+  ^{ result = x; }();
+  return result;
+}
diff --git a/test/CodeGenObjC/blocks-3.m b/test/CodeGenObjC/blocks-3.m
new file mode 100644
index 0000000..d8379b9
--- /dev/null
+++ b/test/CodeGenObjC/blocks-3.m
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -emit-llvm -fblocks -o %t %s
+// RUN: grep 'object_assign' %t | count 11
+// RUN: grep 'object_dispose' %t | count 29
+
+int main() {
+  typedef id aid __attribute__((aligned(1)));
+  __block aid a1;
+  __block id a2 __attribute__((aligned(2)));
+  __block id a3 __attribute__((aligned(4)));
+  __block id a4 __attribute__((aligned(8)));
+  __block id a5, a6, a7;
+  __block void (^b)();
+  ^{ a1=a2=a3=a4=a5=a6=a7=0; b = 0; }();
+  return 0;
+}
diff --git a/test/CodeGenObjC/blocks-4.m b/test/CodeGenObjC/blocks-4.m
new file mode 100644
index 0000000..d945ed4
--- /dev/null
+++ b/test/CodeGenObjC/blocks-4.m
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -emit-llvm -fblocks -o %t %s
+// rdar://7590273
+
+void EXIT(id e);
+
+@interface NSBlockOperation {
+}
++(id)blockOperationWithBlock:(void (^)(void))block ;
+@end
+
+void FUNC() {
+        [NSBlockOperation blockOperationWithBlock:^{
+            @try {
+
+            }
+            @catch (id exception) {
+		EXIT(exception);
+            }
+        }];
+
+}
diff --git a/test/CodeGenObjC/blocks.m b/test/CodeGenObjC/blocks.m
new file mode 100644
index 0000000..8ba319e
--- /dev/null
+++ b/test/CodeGenObjC/blocks.m
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -emit-llvm -fblocks -o %t %s
+// rdar://6676764
+
+struct S {
+  void (^F)(struct S*);
+} P;
+
+
+@interface T
+
+  - (int)foo: (T (^)(T*)) x;
+@end
+
+void foo(T *P) {
+ [P foo: 0];
+}
+
+@interface A 
+-(void) im0;
+@end
+
+// RUN: grep 'define internal i32 @"__-\[A im0\]_block_invoke_"' %t
+@implementation A
+-(void) im0 {
+  (void) ^{ return 1; }();
+}
+@end
+
+@interface B : A @end
+@implementation B
+-(void) im1 {
+  ^(void) { [self im0]; }();
+}
+@end
+
diff --git a/test/CodeGenObjC/category-super-class-meth.m b/test/CodeGenObjC/category-super-class-meth.m
new file mode 100644
index 0000000..6f02aff
--- /dev/null
+++ b/test/CodeGenObjC/category-super-class-meth.m
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -emit-llvm -o %t %s
+
+@interface BASE
++ (int) BaseMeth;
+@end
+
+@interface Child: BASE
+@end
+
+@interface Child (Categ)
++ (int) flushCache2;
+@end
+
+@implementation Child  @end
+
+@implementation Child (Categ)
++ (int) flushCache2 { [super BaseMeth]; }
+@end
+
diff --git a/test/CodeGenObjC/class-getter-dotsyntax.m b/test/CodeGenObjC/class-getter-dotsyntax.m
new file mode 100644
index 0000000..bc142ce
--- /dev/null
+++ b/test/CodeGenObjC/class-getter-dotsyntax.m
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -emit-llvm -o %t %s
+
+@interface Test { }
++ (Test *)crash;
++ (void)setCrash: (int)value;
+@end
+
+@implementation Test
+static int _value;
+- (void)cachesPath
+{
+ static Test *cachesPath;
+
+ if (!cachesPath) {
+  Test *crash = Test.crash;
+ }
+}
++ (Test *)crash{ return 0; }
++ (void)setCrash: (int)value{ _value = value; }
+@end
+
diff --git a/test/CodeGenObjC/class-type.m b/test/CodeGenObjC/class-type.m
new file mode 100644
index 0000000..192a808
--- /dev/null
+++ b/test/CodeGenObjC/class-type.m
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -emit-llvm -o - %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -emit-llvm -o - %s
+
+
+@interface I0 {
+  struct { int a; } a;
+}
+@end 
+
+@class I2;
+
+@interface I1 {
+  I2 *_imageBrowser;
+}
+@end 
+
+@implementation I1 
+@end 
+
+@interface I2 : I0 
+@end 
+
+@implementation I2 
+@end 
+
+
+// Implementations without interface declarations.
+// rdar://6804402
+@class foo;
+@implementation foo 
+@end
+
+@implementation bar
+@end
+
diff --git a/test/CodeGenObjC/compatibility-alias.m b/test/CodeGenObjC/compatibility-alias.m
new file mode 100644
index 0000000..fcc53b8
--- /dev/null
+++ b/test/CodeGenObjC/compatibility-alias.m
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -emit-llvm -o %t %s
+
+@interface Int1 @end
+
+typedef Int1 Int1Typedef;
+@compatibility_alias Int1Alias Int1Typedef;
+
+@implementation Int1Alias @end
diff --git a/test/CodeGenObjC/complex-property.m b/test/CodeGenObjC/complex-property.m
new file mode 100644
index 0000000..5a2b78b
--- /dev/null
+++ b/test/CodeGenObjC/complex-property.m
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10  -fobjc-nonfragile-abi -emit-llvm -o - %s | FileCheck -check-prefix LP64 %s
+// rdar: // 7351147
+
+@interface A
+@property __complex int COMPLEX_PROP;
+- (__complex int)y;
+- (void) setY : (__complex int)rhs;
+@end
+
+void f0(A *a) {  
+  _Complex int a1 = 25 + 10i;
+  a.COMPLEX_PROP += a1;
+  a.y += a1;
+}
+
+// CHECK-LP64: internal global [13 x i8] c"COMPLEX_PROP
+// CHECK-LP64: internal global [17 x i8] c"setCOMPLEX_PROP
+
+// rdar: // 7351147
+@interface B
+@property (assign) _Complex float f_complex_ivar;
+@end
+
+@implementation B
+
+@synthesize f_complex_ivar = _f_complex_ivar;
+-(void) unary_f_complex: (_Complex float) a0 {
+  self.f_complex_ivar = a0;
+}
+
+@end
+
diff --git a/test/CodeGenObjC/constant-strings.m b/test/CodeGenObjC/constant-strings.m
new file mode 100644
index 0000000..2276949
--- /dev/null
+++ b/test/CodeGenObjC/constant-strings.m
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -emit-llvm -o %t %s
+// RUN: %clang_cc1 -fgnu-runtime -emit-llvm -o %t %s && grep NXConstantString %t | count 1
+// RUN: %clang_cc1 -fgnu-runtime -fconstant-string-class NSConstantString -emit-llvm -o %t %s && grep NSConstantString %t | count 1
+
+id a = @"Hello World!";
+
diff --git a/test/CodeGenObjC/continuation-class.m b/test/CodeGenObjC/continuation-class.m
new file mode 100644
index 0000000..6f903a0
--- /dev/null
+++ b/test/CodeGenObjC/continuation-class.m
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -emit-llvm -o %t %s
+
+@interface Object
+- (id)new;
+@end
+
+@interface ReadOnly : Object
+{
+  int _object;
+  int _Anotherobject;
+}
+@property(readonly) int object;
+@property(readonly) int Anotherobject;
+@end
+
+@interface ReadOnly ()
+@property(readwrite) int object;
+@property(readwrite, setter = myAnotherobjectSetter:) int Anotherobject;
+@end
+
+@implementation ReadOnly
+@synthesize object = _object;
+@synthesize  Anotherobject = _Anotherobject;
+- (void) myAnotherobjectSetter : (int)val {
+    _Anotherobject = val;
+}
+@end
+
+int main(int argc, char **argv) {
+    ReadOnly *test = [ReadOnly new];
+    test.object = 12345;
+    test.Anotherobject = 200;
+    return test.object - 12345 + test.Anotherobject - 200;
+}
+
diff --git a/test/CodeGenObjC/deadcode_strip_used_var.m b/test/CodeGenObjC/deadcode_strip_used_var.m
new file mode 100644
index 0000000..01e6bd4
--- /dev/null
+++ b/test/CodeGenObjC/deadcode_strip_used_var.m
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 %s -emit-llvm -o %t -triple i386-apple-darwin10
+// RUN: grep "llvm.used" %t | count 1
+// RUN: %clang_cc1 %s -emit-llvm -o %t -triple x86_64-apple-darwin10
+// RUN: grep "llvm.used" %t | count 1 
+
+
+__attribute__((used)) static int  XXXXXX  __attribute__ ((section ("__DATA,__Xinterpose"))) ;
+__attribute__((used)) static int  YYYY  __attribute__ ((section ("__DATA,__Xinterpose"))) ;
+
diff --git a/test/CodeGenObjC/debug-info-crash.m b/test/CodeGenObjC/debug-info-crash.m
new file mode 100644
index 0000000..92f9c0e
--- /dev/null
+++ b/test/CodeGenObjC/debug-info-crash.m
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin10 -fblocks -g -S %s -o -
+
+// rdar://7556129
+@implementation test
+- (void)wait {
+  ^{};
+}
+@end
+
+// PR4894
+@interface I0 {
+  I0 *_iv0;
+}
+@end
+@protocol P0 @end
+
+@interface I1 @end
+@implementation I1
+- (I0<P0> *) im0 {
+  // CHECK: @"\01-[I1 im0]"
+  // CHECK: llvm.dbg.func.start
+  return 0;
+}
+@end
+
+// PR4541
+@class NSString;
+@interface NSAttributedString 
+- (NSString *)string;
+@end 
+@interface NSMutableAttributedString : NSAttributedString 
+@end 
+@class NSImage;
+@implementation CYObjectsController 
++ (void)initialize {
+}
++ (NSAttributedString *)attributedStringWithString:(id)string image:(NSImage *)image  {
+  NSMutableAttributedString *attrStr;
+}
+@end
diff --git a/test/CodeGenObjC/debug-info-linkagename.m b/test/CodeGenObjC/debug-info-linkagename.m
new file mode 100644
index 0000000..2b10e2b
--- /dev/null
+++ b/test/CodeGenObjC/debug-info-linkagename.m
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1  -g -S -o %t %s
+// RUN: not grep 001 %t
+
+@interface F 
+-(int) bar;
+@end
+
+@implementation F
+-(int) bar {
+	return 42;
+}
+@end
+
+extern int f(F *fn) {
+	return [fn bar];
+}
+	
diff --git a/test/CodeGenObjC/dot-syntax-1.m b/test/CodeGenObjC/dot-syntax-1.m
new file mode 100644
index 0000000..417bcb4
--- /dev/null
+++ b/test/CodeGenObjC/dot-syntax-1.m
@@ -0,0 +1,264 @@
+// RUN: %clang_cc1 -emit-llvm -o %t %s
+
+int printf(const char *, ...);
+
+@interface Root
+-(id) alloc;
+-(id) init;
+@end
+
+// Property above methods...
+
+@interface Top0 : Root
+@property(getter=_getX,setter=_setX:) int x;
+@end
+
+@interface Bot0 : Top0
+-(int) x;
+-(void) setX: (int) arg;
+@end
+
+@implementation Top0
+-(int) _getX {
+  printf("-[ Top0 _getX ]\n");
+  return 0;
+}
+-(void) _setX: (int) arg {
+  printf("-[ Top0 _setX: %d ]\n", arg);
+}
+@end
+
+@implementation Bot0
+-(int) x {
+  printf("-[ Bot0 _getX ]\n");
+  return 0;
+}
+-(void) setX: (int) arg {
+  printf("-[ Bot0 _setX: %d ]\n", arg);
+}
+@end
+
+// Methods above property...
+
+@interface Top1 : Root
+-(int) x;
+-(void) setX: (int) arg;
+@end
+
+@interface Bot1 : Top1
+@property(getter=_getX,setter=_setX:) int x;
+@end
+
+@implementation Top1
+-(int) x {
+  printf("-[ Top1 x ]\n");
+  return 0;
+}
+-(void) setX: (int) arg {
+  printf("-[ Top1 setX: %d ]\n", arg);
+}
+@end
+
+@implementation Bot1
+-(int) _getX {
+  printf("-[ Bot1 _getX ]\n");
+  return 0;
+}
+-(void) _setX: (int) arg {
+  printf("-[ Bot1 _setX: %d ]\n", arg);
+}
+@end
+
+// Mixed setter & getter (variant 1)
+
+@interface Top2 : Root
+-(int) x;
+-(void) _setX: (int) arg;
+@end
+
+@interface Bot2 : Top2
+@property(getter=_getX,setter=_setX:) int x;
+@end
+
+@implementation Top2
+-(int) x {
+  printf("-[ Top2 x ]\n");
+  return 0;
+}
+-(void) _setX: (int) arg {
+  printf("-[ Top2 _setX: %d ]\n", arg);
+}
+@end
+
+@implementation Bot2
+-(int) _getX {
+  printf("-[ Bot2 _getX ]\n");
+  return 0;
+}
+-(void) setX: (int) arg {
+  printf("-[ Bot2 setX: %d ]\n", arg);
+}
+@end
+
+// Mixed setter & getter (variant 2)
+
+@interface Top3 : Root
+-(int) _getX;
+-(void) setX: (int) arg;
+@end
+
+@interface Bot3 : Top3
+@property(getter=_getX,setter=_setX:) int x;
+@end
+
+@implementation Top3
+-(int) _getX {
+  printf("-[ Top3 _getX ]\n");
+  return 0;
+}
+-(void) setX: (int) arg {
+  printf("-[ Top3 setX: %d ]\n", arg);
+}
+@end
+
+@implementation Bot3
+-(int) x {
+  printf("-[ Bot3 x ]\n");
+  return 0;
+}
+-(void) _setX: (int) arg {
+  printf("-[ Bot3 _setX: %d ]\n", arg);
+}
+@end
+
+// Mixed setter & getter (variant 3)
+
+@interface Top4 : Root
+@property(getter=_getX,setter=_setX:) int x;
+@end
+
+@interface Bot4 : Top4
+-(int) _getX;
+-(void) setX: (int) arg;
+@end
+
+@implementation Top4
+-(int) x {
+  printf("-[ Top4 x ]\n");
+  return 0;
+}
+-(void) _setX: (int) arg {
+  printf("-[ Top4 _setX: %d ]\n", arg);
+}
+@end
+
+@implementation Bot4
+-(int) _getX {
+  printf("-[ Bot4 _getX ]\n");
+  return 0;
+}
+-(void) setX: (int) arg {
+  printf("-[ Bot4 setX: %d ]\n", arg);
+}
+@end
+
+// Mixed setter & getter (variant 4)
+
+@interface Top5 : Root
+@property(getter=_getX,setter=_setX:) int x;
+@end
+
+@interface Bot5 : Top5
+-(int) x;
+-(void) _setX: (int) arg;
+@end
+
+@implementation Top5
+-(int) _getX {
+  printf("-[ Top5 _getX ]\n");
+  return 0;
+}
+-(void) setX: (int) arg {
+  printf("-[ Top5 setX: %d ]\n", arg);
+}
+@end
+
+@implementation Bot5
+-(int) x {
+  printf("-[ Bot5 x ]\n");
+  return 0;
+}
+-(void) _setX: (int) arg {
+  printf("-[ Bot5 _setX: %d ]\n", arg);
+}
+@end
+
+// Mixed level calls (variant 1)
+
+@interface Top6 : Root
+-(int) x;
+@end
+
+@interface Bot6 : Top6
+-(void) setX: (int) arg;
+@end
+
+@implementation Top6
+-(int) x {
+  printf("-[ Top6 x ]\n");
+  return 0;
+}
+@end
+
+@implementation Bot6
+-(void) setX: (int) arg {
+  printf("-[ Bot5 setX: %d ]\n", arg);
+}
+@end
+
+// Mixed level calls (variant 1)
+
+@interface Top7 : Root
+-(void) setX: (int) arg;
+@end
+
+@interface Bot7 : Top7
+-(int) x;
+@end
+
+@implementation Top7
+-(void) setX: (int) arg {
+  printf("-[ Top7 setX: %d ]\n", arg);
+}
+@end
+
+@implementation Bot7
+-(int) x {
+  printf("-[ Bot7 x ]\n");
+  return 0;
+}
+@end
+
+//
+
+// FIXME: Two more (thats it?) interesting cases. Method access on
+// getter w/o setter and method access on setter w/o getter.
+
+int main() {
+#define test(N) { \
+  Bot##N *ob = [[Bot##N alloc] init]; \
+  int x = ob.x; \
+  ob.x = 10; }
+
+  test(0);
+  test(1);
+  test(2);
+  test(3);
+  test(4);
+  test(5);
+  //  test(6);
+  //  test(7);
+
+  return 0;
+}
+
diff --git a/test/CodeGenObjC/dot-syntax.m b/test/CodeGenObjC/dot-syntax.m
new file mode 100644
index 0000000..6282ea4
--- /dev/null
+++ b/test/CodeGenObjC/dot-syntax.m
@@ -0,0 +1,98 @@
+// RUN: %clang_cc1 -emit-llvm -o %t %s
+
+int printf(const char *, ...);
+
+@interface Root
+-(id) alloc;
+-(id) init;
+@end
+
+typedef struct {
+  float x, y, z[2];
+} S;
+
+@interface A : Root {
+  int myX;
+  //  __complex myY;
+  S myZ;
+}
+
+@property int x;
+//@property __complex int y;
+@property S z;
+@end
+
+@implementation A
+-(int) x {
+  printf("-[A x] = %d\n", myX);
+  return myX;
+}
+-(void) setX: (int) arg {
+  myX = arg;
+  printf("-[A setX: %d]\n", myX);
+}
+
+// FIXME: Add back
+#if 0
+-(__complex int) y {
+  printf("-[A y] = (%d, %d)\n", __real myY, __imag myY);
+  return myY;
+}
+-(void) setY: (__complex int) arg {
+  myY = arg;
+  printf("-[A setY: (%d, %d)]\n", __real myY, __imag myY);
+}
+#endif
+
+-(S) z {
+  printf("-[A z] = { %f, %f, { %f, %f } }\n", 
+         myZ.x, myZ.y, myZ.z[0], myZ.z[1]);
+  return myZ;
+}
+-(void) setZ: (S) arg {
+  myZ = arg;
+  printf("-[A setZ: { %f, %f, { %f, %f } } ]\n", 
+         myZ.x, myZ.y, myZ.z[0], myZ.z[1]);
+}
+
+@end
+
+int main() {
+#define SWAP(T,a,b) { T a_tmp = a; a = b; b = a_tmp; }
+  A *a = [[A alloc] init];
+  A *b = [[A alloc] init];
+  int a0 = 23;
+  //  __complex a1 = 25 + 10i;
+  S a2 =  { 246, 458, {275, 12} };
+  int b0 = 42673;
+  //  __complex b1 = 15 + 13i;
+  S b2 =  { 26, 2, {367, 13} };
+
+  a.x = a0;
+  //  a.y = a1;
+  a.z = a2;
+
+  a.x += a0;
+  //  a.y += a1;
+  // Yay, no compound assign of structures. A GCC extension in the
+  // works, perhaps?
+
+  b.x = b0;
+  //  b.y = b1;
+  b.z = b2;
+
+  int x0 = (b.x = b0);
+  printf("(b.x = b0): %d\n", x0);
+
+  //  int x1 = __real (b.y = b1);
+  //  printf("__real (b.y = b1) = %d\n", x1);
+
+  float x2 = (b.z = b2).x;
+  printf("(b.z = b2).x: %f\n", x2);
+
+  SWAP(int, a.x, b.x);
+  //  SWAP(__complex int, a.y, b.y);
+  SWAP(S, a.z, b.z);
+
+  return 0;
+}
diff --git a/test/CodeGenObjC/encode-cstyle-method.m b/test/CodeGenObjC/encode-cstyle-method.m
new file mode 100644
index 0000000..187c9bf
--- /dev/null
+++ b/test/CodeGenObjC/encode-cstyle-method.m
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10  -emit-llvm -o - %s | FileCheck -check-prefix LP64 %s
+// rdar: // 7445205
+
+@interface Foo 
+- (id)test:(id)one, id two;
+@end
+
+@implementation Foo
+- (id)test:(id )one, id two {return two; } @end
+
+// CHECK-LP64: internal global [11 x i8] c"@24@0:8@16
diff --git a/test/CodeGenObjC/encode-test-1.m b/test/CodeGenObjC/encode-test-1.m
new file mode 100644
index 0000000..af7ad26
--- /dev/null
+++ b/test/CodeGenObjC/encode-test-1.m
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -triple=i686-apple-darwin9 -emit-llvm -o %t %s
+// RUN: grep -e "{Base=b2b3b4b5}" %t | count 1
+// RUN: grep -e "{Derived=b2b3b4b5b5b4b3}" %t | count 1
+
+enum Enum { one, two, three, four };
+
+@interface Base {
+  unsigned a: 2;
+  int b: 3;
+  enum Enum c: 4;
+  unsigned d: 5;
+} 
+@end
+
+@interface Derived: Base {
+  signed e: 5;
+  int f: 4;
+  enum Enum g: 3;
+} 
+@end
+
+@implementation Base @end
+
+@implementation Derived @end
+  
+int main(void)
+{
+
+  const char *en = @encode(Base);
+//  printf ("%s\n", en);
+
+  const char *ed = @encode(Derived);
+ // printf ("%s\n", ed);
+
+  return 0;
+}
diff --git a/test/CodeGenObjC/encode-test-2.m b/test/CodeGenObjC/encode-test-2.m
new file mode 100644
index 0000000..9e14237
--- /dev/null
+++ b/test/CodeGenObjC/encode-test-2.m
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -triple=i686-apple-darwin9 -emit-llvm -o %t %s
+// RUN: grep -e "@\\\22<X>\\\22" %t
+// RUN: grep -e "@\\\22<X><Y>\\\22" %t
+// RUN: grep -e "@\\\22<X><Y><Z>\\\22" %t
+// RUN: grep -e "@\\\22Foo<X><Y><Z>\\\22" %t
+// RUN: grep -e "{Intf=@@@@#}" %t  
+
+@protocol X, Y, Z;
+@class Foo;
+
+@protocol Proto
+@end
+
+@interface Intf <Proto>
+{
+id <X> IVAR_x;
+id <X, Y> IVAR_xy;
+id <X, Y, Z> IVAR_xyz;
+Foo <X, Y, Z> *IVAR_Fooxyz;
+Class <X> IVAR_Classx;
+}
+@end
+
+@implementation Intf 
+@end
+
+int main()
+{
+	const char * en = @encode(Intf);
+}
diff --git a/test/CodeGenObjC/encode-test-3.m b/test/CodeGenObjC/encode-test-3.m
new file mode 100644
index 0000000..4b39cd7
--- /dev/null
+++ b/test/CodeGenObjC/encode-test-3.m
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -triple=i686-apple-darwin9 -emit-llvm -o %t %s
+// RUN: grep -e "\^i" %t | count 1
+// RUN: grep -e "\[0i\]" %t | count 1
+
+int main() {
+  int n;
+  
+  const char * inc = @encode(int[]);
+  const char * vla = @encode(int[n]);
+}
+
+// PR3648
+int a[sizeof(@encode(int)) == 2 ? 1 : -1]; // Type is char[2]
+const char *B = @encode(int);
+char (*c)[2] = &@encode(int); // @encode is an lvalue
+
+char d[] = @encode(int);   // infer size.
+char e[1] = @encode(int);  // truncate
+char f[2] = @encode(int);  // fits
+char g[3] = @encode(int);  // zero fill
+
diff --git a/test/CodeGenObjC/encode-test-4.m b/test/CodeGenObjC/encode-test-4.m
new file mode 100644
index 0000000..117e173
--- /dev/null
+++ b/test/CodeGenObjC/encode-test-4.m
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s -O2 | grep "ret i32 1"
+
+int a() {
+  return @encode(int) == @encode(int);
+}
diff --git a/test/CodeGenObjC/encode-test-5.m b/test/CodeGenObjC/encode-test-5.m
new file mode 100644
index 0000000..a27ffb7
--- /dev/null
+++ b/test/CodeGenObjC/encode-test-5.m
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -triple=x86_64-apple-darwin9 -emit-llvm -o %t %s
+
+// RUN: grep ji.00 %t | count 1
+char *a = @encode(_Complex int);
+
+// RUN: grep jf.00 %t | count 1
+char *b = @encode(_Complex float);
+
+// RUN: grep jd.00 %t | count 1
+char *c = @encode(_Complex double);
+
+// RUN: grep "t.00" %t | count 1
+char *e = @encode(__int128_t);
+
+// RUN: grep "T.00" %t | count 1
+char *f = @encode(__uint128_t);
diff --git a/test/CodeGenObjC/encode-test.m b/test/CodeGenObjC/encode-test.m
new file mode 100644
index 0000000..9d1cf6c
--- /dev/null
+++ b/test/CodeGenObjC/encode-test.m
@@ -0,0 +1,97 @@
+// RUN: %clang_cc1 -triple=i686-apple-darwin9 -emit-llvm -o %t %s
+// RUN: grep -e "\^{Innermost=CC}" %t | count 1
+// RUN: grep -e "{Derived=#ib32b8b3b8sb16b8b8b2b8ccb6}" %t | count 1
+// RUN: grep -e "{B1=#@c}" %t | count 1
+// RUN: grep -e "v12@0:4\[3\[4@]]8" %t | count 1
+// RUN: grep -e "r\^{S=i}" %t | count 1
+// RUN: grep -e "\^{Object=#}" %t | count 1
+
+@class Int1;
+
+struct Innermost {
+  unsigned char a, b;
+};
+
+@interface Int1 {
+  signed char a, b;
+  struct Innermost *innermost;
+}
+@end
+
+@implementation Int1
+@end
+
+@interface Base
+{
+    struct objc_class *isa;
+    int full;
+    int full2: 32;
+    int _refs: 8;
+    int field2: 3;
+    unsigned f3: 8;
+    short cc;
+    unsigned g: 16;
+    int r2: 8;
+    int r3: 8;
+    int r4: 2;
+    int r5: 8;
+    char c;
+}
+@end
+
+@interface Derived: Base
+{
+    char d;
+    int _field3: 6;
+}
+@end
+
+@implementation Base
+@end
+
+@implementation Derived
+@end
+
+@interface B1 
+{
+    struct objc_class *isa;
+    Int1 *sBase;
+    char c;
+}
+@end
+
+@implementation B1
+@end
+
+@interface Test 
+{
+	int ivar;
+         __attribute__((objc_gc(weak))) SEL selector;
+}
+-(void) test3: (Test*  [3] [4])b ; 
+- (SEL**) meth : (SEL) arg : (SEL*****) arg1 : (SEL*)arg2 : (SEL**) arg3;
+@end
+
+@implementation Test
+-(void) test3: (Test* [3] [4])b {}
+- (SEL**) meth : (SEL) arg : (SEL*****) arg1 : (SEL*)arg2 : (SEL**) arg3 {}
+@end
+
+struct S { int iS; };
+
+@interface Object
+{
+ Class isa;
+}
+@end
+typedef Object MyObj;
+
+int main()
+{
+	const char *en = @encode(Derived);
+	const char *eb = @encode(B1);
+        const char *es = @encode(const struct S *);
+        const char *ec = @encode(const struct S);
+        const char *ee = @encode(MyObj *const);
+}
+
diff --git a/test/CodeGenObjC/exceptions.m b/test/CodeGenObjC/exceptions.m
new file mode 100644
index 0000000..a74dee9
--- /dev/null
+++ b/test/CodeGenObjC/exceptions.m
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o %t %s
+//
+// <rdar://problem/7471679> [irgen] [eh] Exception code built with clang (x86_64) crashes
+
+// Just check that we don't emit any dead blocks.
+//
+// RUN: grep 'No predecessors' %t | count 0
+
+@interface NSArray @end
+void f0() {
+  @try {
+    @try {
+      @throw @"a";
+    } @catch(NSArray *e) {
+    }
+  } @catch (id e) {
+  }
+}
diff --git a/test/CodeGenObjC/for-in.m b/test/CodeGenObjC/for-in.m
new file mode 100644
index 0000000..354ff32
--- /dev/null
+++ b/test/CodeGenObjC/for-in.m
@@ -0,0 +1,44 @@
+// RUN: %clang_cc1 -emit-llvm %s -o %t
+
+void p(const char*, ...);
+
+@interface NSArray
++(NSArray*) arrayWithObjects: (id) first, ...;
+-(unsigned) count;
+@end
+@interface NSString
+-(const char*) cString;
+@end
+
+#define S(n) @#n
+#define L1(n) S(n+0),S(n+1)
+#define L2(n) L1(n+0),L1(n+2)
+#define L3(n) L2(n+0),L2(n+4)
+#define L4(n) L3(n+0),L3(n+8)
+#define L5(n) L4(n+0),L4(n+16)
+#define L6(n) L5(n+0),L5(n+32)
+
+void t0() {
+  NSArray *array = [NSArray arrayWithObjects: L1(0), (void*)0];
+
+  p("array.length: %d\n", [array count]);
+  unsigned index = 0;
+  for (NSString *i in array) {
+    p("element %d: %s\n", index++, [i cString]);
+  }
+}
+
+void t1() {
+  NSArray *array = [NSArray arrayWithObjects: L6(0), (void*)0];
+
+  p("array.length: %d\n", [array count]);
+  unsigned index = 0;
+  for (NSString *i in array) {
+    index++;
+    if (index == 10)
+      continue;
+    p("element %d: %s\n", index, [i cString]);
+    if (index == 55)
+      break;
+  }
+}
diff --git a/test/CodeGenObjC/forward-class-impl-metadata.m b/test/CodeGenObjC/forward-class-impl-metadata.m
new file mode 100644
index 0000000..0ab7a81
--- /dev/null
+++ b/test/CodeGenObjC/forward-class-impl-metadata.m
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -fobjc-nonfragile-abi -emit-llvm -o %t %s
+
+@interface BASE  {
+@private
+    void* _reserved;
+}
+@end
+
+@class PVR;
+
+@interface PVRHandldler 
+{
+          PVR *_imageBrowser;
+}
+@end
+
+@implementation PVRHandldler @end
+
+
+@interface PVR   : BASE
+@end
+
+@implementation PVR
+@end
+
+// Reopen of an interface after use.
+
+@interface A { 
+@public 
+  int x; 
+} 
+@property int p0;
+@end
+
+int f0(A *a) { 
+  return a.p0; 
+}
+
+@implementation A
+@synthesize p0 = _p0;
+@end
diff --git a/test/CodeGenObjC/hidden-visibility.m b/test/CodeGenObjC/hidden-visibility.m
new file mode 100644
index 0000000..5e08ef9
--- /dev/null
+++ b/test/CodeGenObjC/hidden-visibility.m
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -fvisibility hidden -fobjc-nonfragile-abi -emit-llvm -o - %s | FileCheck %s
+// CHECK: @"OBJC_IVAR_$_I.P" = hidden
+// CHECK: @"OBJC_CLASS_$_I" = hidden
+// CHECK: @"OBJC_METACLASS_$_I" = hidden
+// CHECK: @"\01l_OBJC_PROTOCOL_$_Prot0" = weak hidden
+
+@interface I {
+  int P;
+}
+
+@property int P;
+@end
+
+@implementation I
+@synthesize P;
+@end
+
+
+@protocol Prot0;
+
+id f0() {
+  return @protocol(Prot0);
+}
+
+
diff --git a/test/CodeGenObjC/hidden.m b/test/CodeGenObjC/hidden.m
new file mode 100644
index 0000000..0b77e73
--- /dev/null
+++ b/test/CodeGenObjC/hidden.m
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -emit-llvm -o %t %s
+
+__attribute__((visibility("hidden")))
+@interface Hidden
++(void) bar;
+@end
+
+@implementation Hidden
++(void) bar {}
+@end
+
+__attribute__((visibility("default")))
+@interface Default
++(void) bar;
+@end
+
+@implementation Default
++(void) bar {}
+@end
diff --git a/test/CodeGenObjC/id-isa-codegen.m b/test/CodeGenObjC/id-isa-codegen.m
new file mode 100644
index 0000000..e4f5fd9
--- /dev/null
+++ b/test/CodeGenObjC/id-isa-codegen.m
@@ -0,0 +1,73 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10  -emit-llvm -o - %s | FileCheck -check-prefix LP64 %s
+// RUN: %clang_cc1 -triple i386-apple-darwin9  -emit-llvm -o - %s | FileCheck -check-prefix LP32 %s
+
+typedef struct objc_class *Class;
+
+typedef struct objc_object {
+    Class isa;
+} *id;
+
+@interface I
++ (Class) class;
+- (void)meth : (id)object : (id)src_object;
++ (unsigned char) isSubclassOfClass:(Class)aClass ;
+@end
+
+@implementation I
++ (Class) class {return 0;}
++ (unsigned char) isSubclassOfClass:(Class)aClass {return 0;}
+- (void)meth : (id)object  : (id)src_object {
+    [object->isa isSubclassOfClass:[I class]];
+
+    [(*object).isa isSubclassOfClass:[I class]];
+
+    object->isa = src_object->isa;
+    (*src_object).isa = (*object).isa;
+}
+@end
+
+
+// rdar 7470820
+static Class MyClass;
+
+Class Test(const void *inObject1) {
+  if(((id)inObject1)->isa == MyClass)
+   return ((id)inObject1)->isa;
+  return (id)0;
+}
+
+// rdar 7609722
+@interface Foo { 
+@public 
+  id isa; 
+} 
++(id)method;
+@end
+
+id Test2() {
+    if([Foo method]->isa)
+      return (*[Foo method]).isa;
+    return [Foo method]->isa;
+}
+
+// rdar 7709015
+@interface Cat   {}
+@end
+
+@interface SuperCat : Cat {}
++(void)geneticallyAlterCat:(Cat *)cat;
+@end
+
+@implementation SuperCat
++ (void)geneticallyAlterCat:(Cat *)cat {
+    Class dynamicSubclass;
+    ((id)cat)->isa = dynamicSubclass;
+}
+@end
+// CHECK-LP64: %{{.*}} = load i8** %
+// CHECK-NEXT: %{{.*}} = bitcast i8* %{{.*}} to i8**
+// CHECK-NEXT: store i8* %{{.*}}, i8** %{{.*}}
+
+// CHECK-LP32: %{{.*}} = load i8** %
+// CHECK-NEXT: %{{.*}} = bitcast i8* %{{.*}} to i8**
+// CHECK-NEXT: store i8* %{{.*}}, i8** %{{.*}}
diff --git a/test/CodeGenObjC/image-info.m b/test/CodeGenObjC/image-info.m
new file mode 100644
index 0000000..2777723
--- /dev/null
+++ b/test/CodeGenObjC/image-info.m
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -emit-llvm -o %t %s
+// RUN: FileCheck --check-prefix CHECK-FRAGILE < %t %s
+
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -emit-llvm -o %t %s
+// RUN: FileCheck --check-prefix CHECK-NONFRAGILE < %t %s
+
+// CHECK-FRAGILE: @"\01L_OBJC_IMAGE_INFO" = internal constant [2 x i32] [i32 0, i32 16], section "__OBJC, __image_info,regular"
+// CHECK-NONFRAGILE: @"\01L_OBJC_IMAGE_INFO" = internal constant [2 x i32] [i32 0, i32 16], section "__DATA, __objc_imageinfo, regular, no_dead_strip"
diff --git a/test/CodeGenObjC/implicit-objc_msgSend.m b/test/CodeGenObjC/implicit-objc_msgSend.m
new file mode 100644
index 0000000..a21e869
--- /dev/null
+++ b/test/CodeGenObjC/implicit-objc_msgSend.m
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -emit-llvm -o %t %s
+// RUN: grep -F 'declare i8* @objc_msgSend(...)' %t
+
+typedef struct objc_selector *SEL;
+id f0(id x, SEL s) {
+  return objc_msgSend(x, s);
+}
diff --git a/test/CodeGenObjC/implicit-property.m b/test/CodeGenObjC/implicit-property.m
new file mode 100644
index 0000000..db1da31
--- /dev/null
+++ b/test/CodeGenObjC/implicit-property.m
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -emit-llvm -triple=i686-apple-darwin8 -o %t %s
+// RUNX: %clang_cc1 -emit-llvm -o %t %s
+
+@interface A
+ -(void) setOk:(int)arg;
+ -(int) ok;
+
+ -(void) setX:(int)arg;
+ -(int) x;
+@end
+
+void f0(A *a) {
+   a.x = 1;   
+   a.ok = a.x;
+}
+
diff --git a/test/CodeGenObjC/interface-layout-64.m b/test/CodeGenObjC/interface-layout-64.m
new file mode 100644
index 0000000..2800b41
--- /dev/null
+++ b/test/CodeGenObjC/interface-layout-64.m
@@ -0,0 +1,123 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -emit-llvm -o %t %s
+// RUNX: llvm-gcc -m64 -emit-llvm -S -o %t %s &&
+
+// RUN: grep '@"OBJC_IVAR_$_I3._iv2" = global i64 8, section "__DATA, __objc_const", align 8' %t
+// RUN: grep '@"OBJC_IVAR_$_I3._iv3" = global i64 12, section "__DATA, __objc_const", align 8' %t
+// RUN: grep '@"OBJC_IVAR_$_I4._iv4" = global i64 13, section "__DATA, __objc_const", align 8' %t
+// RUN: grep '@"OBJC_IVAR_$_I5._iv5" = global i64 14, section "__DATA, __objc_const", align 8' %t
+// RUN: grep '@"OBJC_IVAR_$_I5._iv6_synth" = global i64 16, section "__DATA, __objc_const", align 8' %t
+// RUN: grep '@"OBJC_IVAR_$_I5._iv7_synth" = global i64 20, section "__DATA, __objc_const", align 8' %t
+// RUN: grep '@"OBJC_IVAR_$_I6.iv0" = global i64 0, section "__DATA, __objc_const", align 8' %t
+// RUN: grep '@"OBJC_IVAR_$_I8.b" = global i64 8, section "__DATA, __objc_const", align 8' %t
+// RUN: grep '@"OBJC_IVAR_$_I9.iv0" = global i64 0, section "__DATA, __objc_const", align 8' %t
+// RUN: grep '@"OBJC_IVAR_$_I10.iv1" = global i64 4, section "__DATA, __objc_const", align 8' %t
+// RUN: grep '@"OBJC_IVAR_$_I12.iv2" = global i64 8, section "__DATA, __objc_const", align 8' %t
+// RUN: grep '_OBJC_CLASS_RO_$_I3" = internal global .* { i32 0, i32 8, i32 13, .*' %t
+// RUN: grep '_OBJC_CLASS_RO_$_I4" = internal global .* { i32 0, i32 13, i32 14, .*' %t
+// RUN: grep '_OBJC_CLASS_RO_$_I5" = internal global .* { i32 0, i32 14, i32 24, .*' %t
+// RUN: grep '_OBJC_CLASS_RO_$_I6" = internal global .* { i32 2, i32 0, i32 1, .*' %t
+// RUN: grep '_OBJC_CLASS_RO_$_I8" = internal global .* { i32 0, i32 8, i32 16, .*' %t
+// RUN: grep '_OBJC_CLASS_RO_$_I9" = internal global .* { i32 2, i32 0, i32 4, .*' %t
+// RUN: grep '_OBJC_CLASS_RO_$_I10" = internal global .* { i32 0, i32 4, i32 5, .*' %t
+// RUN: grep '_OBJC_CLASS_RO_$_I11" = internal global .* { i32 0, i32 5, i32 5, .*' %t
+// RUN: grep '_OBJC_CLASS_RO_$_I12" = internal global .* { i32 0, i32 8, i32 12, .*' %t
+
+
+/*
+  Compare to:
+    gcc -m64 -S -o - interface-layout-64.m | grep '^_OBJC_IVAR_$_*.*' -A 1
+  and 
+    gcc -m64 -S -o - interface-layout-64.m | grep '^l.*_CLASS_RO_$_I[0-9]*' -A 3
+ */
+
+struct s0 {
+  double x;
+};
+
+@interface I2 {
+  struct s0 _iv1;
+}
+@end
+
+@interface I3 : I2 {
+  unsigned int _iv2 :1;
+  unsigned : 0;
+  unsigned int _iv3 : 3;
+}
+@end
+
+@interface I4 : I3 {
+ char _iv4;
+}
+@end
+
+@interface I5 : I4 {
+ char _iv5;
+}
+
+@property int prop0;
+@end
+
+@implementation I3
+@end
+
+@implementation I4 
+@end
+
+@interface I5 ()
+@property int prop1;
+@property char prop2;
+@end
+
+@implementation I5
+@synthesize prop0 = _iv6_synth;
+@synthesize prop1 = _iv7_synth;
+@synthesize prop2 = _iv5;
+@end
+
+// The size rounds up to the next available byte.
+@interface I6 {
+  unsigned iv0 : 2;
+}
+@end
+@implementation I6
+@end
+
+// The start of the subclass includes padding for its own alignment.
+@interface I7 {
+  char a;
+}
+@end
+@interface I8 : I7 {
+  double b;
+}
+@end
+@implementation I8
+@end
+
+// Padding bit-fields
+@interface I9 {
+  unsigned iv0 : 2;
+  unsigned : 0;
+}
+@end
+@implementation I9
+@end
+@interface I10 : I9 {
+  unsigned iv1 : 2;
+}
+@end
+@implementation I10
+@end
+
+// Empty structures
+@interface I11 : I10
+@end
+@implementation I11
+@end
+@interface I12 : I11 {
+  unsigned iv2;
+}
+@end
+@implementation I12
+@end
diff --git a/test/CodeGenObjC/interface.m b/test/CodeGenObjC/interface.m
new file mode 100644
index 0000000..17d56f7
--- /dev/null
+++ b/test/CodeGenObjC/interface.m
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -O3 -emit-llvm -o %t %s
+// RUN: grep 'ret i32 385' %t
+
+void *alloca();
+
+@interface I0 {
+@public
+  int iv0;
+  int iv1;
+  int iv2;
+}
+@end
+
+static int f0(I0 *a0) {
+  return (*(a0 + 2)).iv0;
+}
+
+static int f1(I0 *a0) {
+  return a0[2].iv1;
+}
+
+static int f2(I0 *a0) {
+  return (*(a0 - 1)).iv2;
+}
+
+int g0(void) {
+  I0 *a = alloca(sizeof(*a) * 4);
+  a[2].iv0 = 5;
+  a[2].iv1 = 7;
+  a[2].iv2 = 11;
+  return f0(a) * f1(a) * f2(&a[3]);
+}
+
+
diff --git a/test/CodeGenObjC/ivar-layout-64-bitfields.m b/test/CodeGenObjC/ivar-layout-64-bitfields.m
new file mode 100644
index 0000000..1b6a16b
--- /dev/null
+++ b/test/CodeGenObjC/ivar-layout-64-bitfields.m
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -fobjc-gc -emit-llvm -o %t %s
+@interface I
+{
+  struct {
+    unsigned int d : 1;
+  } bitfield;
+}
+@end
+
+@implementation I
+@end
+
+@interface J
+{
+    struct {
+        unsigned short _reserved : 16;
+
+        _Bool _draggedNodesAreDeletable: 1;
+        _Bool _draggedOutsideOutlineView : 1;
+        _Bool _adapterRespondsTo_addRootPaths : 1;
+        _Bool _adapterRespondsTo_moveDataNodes : 1;
+        _Bool _adapterRespondsTo_removeRootDataNode : 1;
+        _Bool _adapterRespondsTo_doubleClickDataNode : 1;
+        _Bool _adapterRespondsTo_selectDataNode : 1;
+        _Bool _adapterRespondsTo_textDidEndEditing : 1;
+
+        _Bool _adapterRespondsTo_updateAndSaveRoots : 1;
+        _Bool _adapterRespondsTo_askToDeleteRootNodes : 1;
+        _Bool _adapterRespondsTo_contextMenuForSelectedNodes : 1;
+        _Bool _adapterRespondsTo_pasteboardFilenamesForNodes : 1;
+        _Bool _adapterRespondsTo_writeItemsToPasteboard : 1;
+        _Bool _adapterRespondsTo_writeItemsToPasteboardXXXX : 1;
+    } _flags;
+}
+@end
+
+@implementation J
+@end
+
+
diff --git a/test/CodeGenObjC/ivar-layout-64.m b/test/CodeGenObjC/ivar-layout-64.m
new file mode 100644
index 0000000..60ce1df
--- /dev/null
+++ b/test/CodeGenObjC/ivar-layout-64.m
@@ -0,0 +1,88 @@
+// RUNX: llvm-gcc -m64 -fobjc-gc -emit-llvm -S -o %t %s &&
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fobjc-gc -emit-llvm -o %t %s
+// RUN: grep '@"\\01L_OBJC_CLASS_NAME_.*" = internal global .* c"A\\00"' %t
+// RUN: grep '@"\\01L_OBJC_CLASS_NAME_.*" = internal global .* c"\\11q\\10\\00"' %t
+// RUN: grep '@"\\01L_OBJC_CLASS_NAME_.*" = internal global .* c"!q\\00"' %t
+// RUN: grep '@"\\01L_OBJC_CLASS_NAME_.*" = internal global .* c"\\01\\14\\00"' %t
+
+/*
+
+Here is a handy command for looking at llvm-gcc's output:
+llvm-gcc -m64 -fobjc-gc -emit-llvm -S -o - ivar-layout-64.m | \
+  grep 'OBJC_CLASS_NAME.* =.*global' | \
+  sed -e 's#, section.*# ...#' | \
+  sed -e 's#_[0-9]*"#_NNN#' | \
+  sort
+
+*/
+
+@interface B @end
+
+@interface A {
+  struct s0 {
+    int f0;
+    int f1;
+  } f0;
+  id f1;
+__weak B *f2;
+  int f3 : 5;
+  struct s1 {
+    int *f0;
+    int *f1;
+  } f4[2][1];
+}
+@end
+
+@interface C : A
+@property int p3;
+@end
+
+@implementation C
+@synthesize p3 = _p3;
+@end
+
+@interface A()
+@property int p0;
+@property (assign) __strong id p1;
+@property (assign) __weak id p2;
+@end
+
+// FIXME: Check layout for this class, once it is clear what the right
+// answer is.
+@implementation A
+@synthesize p0 = _p0;
+@synthesize p1 = _p1;
+@synthesize p2 = _p2;
+@end
+
+@interface D : A
+@property int p3;
+@end
+
+// FIXME: Check layout for this class, once it is clear what the right
+// answer is.
+@implementation D
+@synthesize p3 = _p3;
+@end
+
+typedef unsigned short UInt16;
+
+
+typedef signed char BOOL;
+typedef unsigned int FSCatalogInfoBitmap;
+
+@interface NSFileLocationComponent {
+    @private
+
+    id _specifierOrStandardizedPath;
+    BOOL _carbonCatalogInfoAndNameAreValid;
+    FSCatalogInfoBitmap _carbonCatalogInfoMask;
+    id _name;
+    id _containerComponent;
+    id _presentableName;
+    id _iconAsAttributedString;
+}
+@end
+
+@implementation NSFileLocationComponent @end
+
diff --git a/test/CodeGenObjC/ivar-layout-no-optimize.m b/test/CodeGenObjC/ivar-layout-no-optimize.m
new file mode 100644
index 0000000..e7fd130
--- /dev/null
+++ b/test/CodeGenObjC/ivar-layout-no-optimize.m
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -fobjc-gc -triple x86_64-apple-darwin -O0 -S %s -o %t-64.s
+// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s
+
+@interface NSObject {
+  id isa;
+}
+@end
+
+@interface AllPointers : NSObject {
+    id foo;
+    void *__strong bar;    NSObject *bletch;}
+@end
+@implementation AllPointers
+@end
+
+// CHECK-LP64: L_OBJC_CLASS_NAME_6:
+// CHECK-LP64-NEXT: .asciz	"\004"
diff --git a/test/CodeGenObjC/ivars.m b/test/CodeGenObjC/ivars.m
new file mode 100644
index 0000000..fe178ab
--- /dev/null
+++ b/test/CodeGenObjC/ivars.m
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -emit-llvm -o - %s
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -emit-llvm -o - %s
+
+// rdar://6800926
+@interface ITF {
+@public
+  unsigned field :1 ;
+  _Bool boolfield :1 ;
+}
+@end
+
+void foo(ITF *P) {
+  P->boolfield = 1;
+}
diff --git a/test/CodeGenObjC/link-errors.m b/test/CodeGenObjC/link-errors.m
new file mode 100644
index 0000000..a82f0ce
--- /dev/null
+++ b/test/CodeGenObjC/link-errors.m
@@ -0,0 +1,39 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -emit-llvm -o %t %s
+// RUN: grep '.lazy_reference .objc_class_name_A' %t | count 1
+// RUN: grep '.lazy_reference .objc_class_name_Unknown' %t | count 1
+// RUN: grep '.lazy_reference .objc_class_name_Protocol' %t | count 1
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -DWITH_IMPL -emit-llvm -o %t %s
+// RUN: grep '.lazy_reference .objc_class_name_Root' %t | count 1
+
+@interface Root
+-(id) alloc;
+-(id) init;
+@end
+
+@protocol P;
+
+@interface A : Root
+@end
+
+@interface A (Category)
++(void) foo;
+@end
+
+#ifdef WITH_IMPL
+@implementation A
+@end
+#endif
+
+@interface Unknown
++test;
+@end
+
+
+int main() {
+  id x = @protocol(P);
+  [ A alloc ];
+  [ A foo ];
+  [ Unknown test ];
+  return 0;
+}
+
diff --git a/test/CodeGenObjC/message-arrays.m b/test/CodeGenObjC/message-arrays.m
new file mode 100644
index 0000000..3e8697f
--- /dev/null
+++ b/test/CodeGenObjC/message-arrays.m
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -emit-llvm -o %t %s
+
+void f0(id a) {
+  // This should have an implicit cast
+  [ a print: "hello" ];
+}
+
+@interface A
+-(void) m: (int) arg0, ...;
+@end
+
+int f1(A *a) {
+  // This should also get an implicit cast (for the vararg)
+  [a m: 1, "test"];
+}
diff --git a/test/CodeGenObjC/messages-2.m b/test/CodeGenObjC/messages-2.m
new file mode 100644
index 0000000..05e30ab
--- /dev/null
+++ b/test/CodeGenObjC/messages-2.m
@@ -0,0 +1,142 @@
+// RUN: %clang_cc1 -emit-llvm -o %t %s
+
+int printf(const char *, ...);
+
+@interface Root
+@end
+
+typedef struct {
+  int x, y, z[10];
+} MyPoint;
+typedef struct {
+  float width, height;
+} MySize;
+
+@interface A : Root
++(void) printThisInt: (int) arg0 andThatFloat: (float) arg1 andADouble: (double) arg2 andAPoint: (MyPoint) arg3;
++(float) returnAFloat;
++(double) returnADouble;
++(MyPoint) returnAPoint;
++(void) printThisSize: (MySize) arg0;
++(MySize) returnASize;
+
+-(void) printThisInt: (int) arg0 andThatFloat: (float) arg1 andADouble: (double) arg2 andAPoint: (MyPoint) arg3;
+-(float) returnAFloat;
+-(double) returnADouble;
+-(MyPoint) returnAPoint;
+-(void) printThisSize: (MySize) arg0;
+-(MySize) returnASize;
+@end
+@interface B : A
+@end
+
+@implementation A
++(void) printThisInt: (int) arg0 andThatFloat: (float) arg1 andADouble: (double) arg2 andAPoint: (MyPoint) arg3 {
+  printf("(CLASS) theInt: %d, theFloat: %f, theDouble: %f, thePoint: { %d, %d }\n",
+         arg0, arg1, arg2, arg3.x, arg3.y);
+}
++(float) returnAFloat {
+  return 15.;
+}
++(double) returnADouble {
+  return 25.;
+}
++(MyPoint) returnAPoint {
+  MyPoint x = { 35, 45 };
+  return x;
+}
++(void) printThisSize: (MySize) arg0 {
+  printf("(CLASS) theSize: { %f, %f }\n",
+         arg0.width, arg0.height);
+}
++(MySize) returnASize {
+  MySize x = { 32, 44 };
+  return x;
+}
+
+-(void) printThisInt: (int) arg0 andThatFloat: (float) arg1 andADouble: (double) arg2 andAPoint: (MyPoint) arg3 {
+  printf("theInt: %d, theFloat: %f, theDouble: %f, thePoint: { %d, %d }\n",
+         arg0, arg1, arg2, arg3.x, arg3.y);
+}
+-(float) returnAFloat {
+  return 10.;
+}
+-(double) returnADouble {
+  return 20.;
+}
+-(MyPoint) returnAPoint {
+  MyPoint x = { 30, 40 };
+  return x;
+}
+-(void) printThisSize: (MySize) arg0 {
+  printf("theSize: { %f, %f }\n",
+         arg0.width, arg0.height);
+}
+-(MySize) returnASize {
+  MySize x = { 22, 34 };
+  return x;
+}
+@end
+
+@implementation B
++(void) printThisInt: (int) arg0 andThatFloat: (float) arg1 andADouble: (double) arg2 andAPoint: (MyPoint) arg3 {
+  arg3.x *= 2;
+  arg3.y *= 2;
+  [ super printThisInt: arg0*2 andThatFloat: arg1*2 andADouble: arg2*2 andAPoint: arg3 ];
+}
++(void) printThisSize: (MySize) arg0 {
+  arg0.width *= 2;
+  arg0.height *= 2;
+  [ super printThisSize: arg0 ];
+}
++(float) returnAFloat {
+  return [ super returnAFloat ]*2;
+}
++(double) returnADouble {
+  return [ super returnADouble ]*2;
+}
++(MyPoint) returnAPoint {
+  MyPoint x = [ super returnAPoint ];
+  x.x *= 2;
+  x.y *= 2;
+  return x;
+}
++(MySize) returnASize {
+  MySize x = [ super returnASize ];
+  x.width *= 2;
+  x.height *= 2;
+  return x;
+}
+
+-(void) printThisInt: (int) arg0 andThatFloat: (float) arg1 andADouble: (double) arg2 andAPoint: (MyPoint) arg3 {
+  arg3.x *= 2;
+  arg3.y *= 2;
+  [ super printThisInt: arg0*2 andThatFloat: arg1*2 andADouble: arg2*2 andAPoint: arg3 ];
+}
+-(void) printThisSize: (MySize) arg0 {
+  arg0.width *= 2;
+  arg0.height *= 2;
+  [ super printThisSize: arg0 ];
+}
+-(float) returnAFloat {
+  return [ super returnAFloat ]*2;
+}
+-(double) returnADouble {
+  return [ super returnADouble ]*2;
+}
+-(MyPoint) returnAPoint {
+  MyPoint x = [ super returnAPoint ];
+  x.x *= 2;
+  x.y *= 2;
+  return x;
+}
+-(MySize) returnASize {
+  MySize x = [ super returnASize ];
+  x.width *= 2;
+  x.height *= 2;
+  return x;
+}
+-(const float) returnAConstFloat {
+  return 5;
+}
+@end
diff --git a/test/CodeGenObjC/messages.m b/test/CodeGenObjC/messages.m
new file mode 100644
index 0000000..5f77a8e
--- /dev/null
+++ b/test/CodeGenObjC/messages.m
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -emit-llvm -o %t %s
+// RUN: grep "objc_msgSend" %t | count 6
+// RUN: %clang_cc1 -fgnu-runtime -emit-llvm -o %t %s
+// RUN: grep "objc_msg_lookup" %t | count 6
+// RUN: %clang_cc1 -fgnu-runtime -fobjc-nonfragile-abi -emit-llvm -o %t %s
+// RUN: grep "objc_msg_lookup_sender" %t | count 6
+
+typedef struct {
+  int x;
+  int y;
+  int z[10];
+} MyPoint;
+
+void f0(id a) {
+  int i;
+  MyPoint pt = { 1, 2};
+
+  [a print0];
+  [a print1: 10];
+  [a print2: 10 and: "hello" and: 2.2];
+  [a takeStruct: pt ];
+  
+  void *s = @selector(print0);
+  for (i=0; i<2; ++i)
+    [a performSelector:s];
+}
diff --git a/test/CodeGenObjC/metadata-symbols-32.m b/test/CodeGenObjC/metadata-symbols-32.m
new file mode 100644
index 0000000..34cc83d
--- /dev/null
+++ b/test/CodeGenObjC/metadata-symbols-32.m
@@ -0,0 +1,87 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -emit-llvm -o %t %s
+// RUNX: llvm-gcc -m32 -emit-llvm -S -o %t %s &&
+
+// RUN: grep '@"\\01L_OBJC_CATEGORY_A_Cat" = internal global .*section "__OBJC,__category,regular,no_dead_strip", align 4' %t
+// RUN: grep '@"\\01L_OBJC_CATEGORY_CLASS_METHODS_A_Cat" = internal global .*section "__OBJC,__cat_cls_meth,regular,no_dead_strip", align 4' %t
+// RUN: grep '@"\\01L_OBJC_CATEGORY_INSTANCE_METHODS_A_Cat" = internal global .*section "__OBJC,__cat_inst_meth,regular,no_dead_strip", align 4' %t
+// RUN: grep '@"\\01L_OBJC_CLASSEXT_A" = internal global .*section "__OBJC,__class_ext,regular,no_dead_strip", align 4' %t
+// RUN: grep '@"\\01L_OBJC_CLASS_A" = internal global .*section "__OBJC,__class,regular,no_dead_strip", align 4' %t
+// RUN: grep '@"\\01L_OBJC_CLASS_METHODS_A" = internal global .*section "__OBJC,__cls_meth,regular,no_dead_strip", align 4' %t
+// RUN: grep '@"\\01L_OBJC_CLASS_NAME_[0-9]*" = internal global .*section "__TEXT,__cstring,cstring_literals", align 1' %t
+// RUN: grep '@"\\01L_OBJC_CLASS_PROTOCOLS_A" = internal global .*section "__OBJC,__cat_cls_meth,regular,no_dead_strip", align 4' %t
+// RUN: grep '@"\\01L_OBJC_CLASS_REFERENCES_[0-9]*" = internal global .*section "__OBJC,__cls_refs,literal_pointers,no_dead_strip", align 4' %t
+
+// Clang's Obj-C 32-bit doesn't emit ivars for the root class.
+// RUNX: grep '@"\\01L_OBJC_CLASS_VARIABLES_A" = internal global .*section "__OBJC,__class_vars,regular,no_dead_strip", align 4' %t && 
+
+// RUN: grep '@"\\01L_OBJC_INSTANCE_METHODS_A" = internal global .*section "__OBJC,__inst_meth,regular,no_dead_strip", align 4' %t
+// RUN: grep '@"\\01L_OBJC_INSTANCE_VARIABLES_A" = internal global .*section "__OBJC,__instance_vars,regular,no_dead_strip", align 4' %t
+// RUN: grep '@"\\01L_OBJC_METACLASS_A" = internal global .*section "__OBJC,__meta_class,regular,no_dead_strip", align 4' %t
+// RUN: grep '@"\\01L_OBJC_METH_VAR_NAME_[0-9]*" = internal global .*section "__TEXT,__cstring,cstring_literals", align 1' %t
+// RUN: grep '@"\\01L_OBJC_METH_VAR_TYPE_[0-9]*" = internal global .*section "__TEXT,__cstring,cstring_literals", align 1' %t
+// RUN: grep '@"\\01L_OBJC_MODULES" = internal global .*section "__OBJC,__module_info,regular,no_dead_strip", align 4' %t
+// RUN: grep '@"\\01L_OBJC_PROP_NAME_ATTR_[0-9]*" = internal global .*section "__TEXT,__cstring,cstring_literals", align 1' %t
+// RUN: grep '@"\\01L_OBJC_PROTOCOL_CLASS_METHODS_P" = internal global .*section "__OBJC,__cat_cls_meth,regular,no_dead_strip", align 4' %t
+// RUN: grep '@"\\01L_OBJC_PROTOCOL_INSTANCE_METHODS_P" = internal global .*section "__OBJC,__cat_inst_meth,regular,no_dead_strip", align 4' %t
+// RUN: grep '@"\\01L_OBJC_PROTOCOL_P" = internal global .*section "__OBJC,__protocol,regular,no_dead_strip", align 4' %t
+// RUN: grep '@"\\01L_OBJC_SELECTOR_REFERENCES_[0-9]*" = internal global .*section "__OBJC,__message_refs,literal_pointers,no_dead_strip", align 4' %t
+// RUN: grep '@"\\01L_OBJC_SYMBOLS" = internal global .*section "__OBJC,__symbols,regular,no_dead_strip", align 4' %t
+// RUN: grep '@"\\01l_OBJC_$_PROP_LIST_A" = internal global .*section "__OBJC,__property,regular,no_dead_strip", align 4' %t
+// RUN: grep "\.lazy_reference \.objc_class_name_J0" %t
+
+
+/*
+
+Here is a handy command for looking at llvm-gcc's output:
+llvm-gcc -m32 -emit-llvm -S -o - metadata-symbols-32.m | \
+  grep '=.*global' | \
+  sed -e 's#global.*, section#global ... section#' | \
+  sort
+
+*/
+
+@interface B
+@end
+@interface C
+@end
+
+@protocol P
++(void) fm0;
+-(void) im0;
+@end
+
+@interface A<P> {
+  int _ivar;
+}
+ 
+@property (assign) int ivar;
+
++(void) fm0;
+-(void) im0;
+@end
+
+@implementation A
+@synthesize ivar = _ivar;
++(void) fm0 {
+}
+-(void) im0 {
+}
+@end
+
+@implementation A (Cat)
++(void) fm1 {
+}
+-(void) im1 {
+}
+@end
+
+@interface J0
+@end
+
+@implementation J0(Category) @end
+
+void *f0() {
+   [B im0];
+   [C im1];
+}
+
diff --git a/test/CodeGenObjC/metadata-symbols-64.m b/test/CodeGenObjC/metadata-symbols-64.m
new file mode 100644
index 0000000..dbc06d7
--- /dev/null
+++ b/test/CodeGenObjC/metadata-symbols-64.m
@@ -0,0 +1,129 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fobjc-dispatch-method=mixed -emit-llvm -o %t %s
+// RUNX: llvm-gcc -m64 -emit-llvm -S -o %t %s &&
+
+// RUN: grep '@"OBJC_CLASS_$_A" = global' %t
+// RUN: grep '@"OBJC_CLASS_$_B" = external global' %t
+// RUN: grep '@"OBJC_IVAR_$_A._ivar" = global .* section "__DATA, __objc_const", align 8' %t
+// RUN: grep '@"OBJC_METACLASS_$_A" = global .* section "__DATA, __objc_data", align 8' %t
+// RUN: grep '@"\\01L_OBJC_CLASSLIST_REFERENCES_$_[0-9]*" = internal global .* section "__DATA, __objc_classrefs, regular, no_dead_strip", align 8' %t
+// RUN: grep '@"\\01L_OBJC_CLASSLIST_SUP_REFS_$_[0-9]*" = internal global .* section "__DATA, __objc_superrefs, regular, no_dead_strip", align 8' %t | count 2
+// RUN: grep '@"\\01L_OBJC_CLASS_NAME_[0-9]*" = internal global .* section "__TEXT,__cstring,cstring_literals", align 1' %t
+// RUN: grep '@"\\01L_OBJC_LABEL_CATEGORY_$" = internal global .* section "__DATA, __objc_catlist, regular, no_dead_strip", align 8' %t
+// RUN: grep '@"\\01L_OBJC_LABEL_CLASS_$" = internal global .* section "__DATA, __objc_classlist, regular, no_dead_strip", align 8' %t
+// RUN: grep '@"\\01L_OBJC_METH_VAR_NAME_[0-9]*" = internal global .* section "__TEXT,__cstring,cstring_literals", align 1' %t
+// RUN: grep '@"\\01L_OBJC_METH_VAR_TYPE_[0-9]*" = internal global .* section "__TEXT,__cstring,cstring_literals", align 1' %t
+// RUN: grep '@"\\01L_OBJC_PROP_NAME_ATTR_[0-9]*" = internal global .* section "__TEXT,__cstring,cstring_literals", align 1' %t
+// RUN: grep '@"\\01L_OBJC_SELECTOR_REFERENCES_*" = internal global .* section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"' %t
+// RUN: grep '@"\\01l_OBJC_$_CATEGORY_A_$_Cat" = internal global .* section "__DATA, __objc_const", align 8' %t
+// RUN: grep '@"\\01l_OBJC_$_CATEGORY_CLASS_METHODS_A_$_Cat" = internal global .* section "__DATA, __objc_const", align 8' %t
+// RUN: grep '@"\\01l_OBJC_$_CATEGORY_INSTANCE_METHODS_A_$_Cat" = internal global .* section "__DATA, __objc_const", align 8' %t
+// RUN: grep '@"\\01l_OBJC_$_CLASS_METHODS_A" = internal global .* section "__DATA, __objc_const", align 8' %t
+// RUN: grep '@"\\01l_OBJC_$_INSTANCE_METHODS_A" = internal global .* section "__DATA, __objc_const", align 8' %t
+// RUN: grep '@"\\01l_OBJC_$_INSTANCE_VARIABLES_A" = internal global .* section "__DATA, __objc_const", align 8' %t
+// RUN: grep '@"\\01l_OBJC_$_PROP_LIST_A" = internal global .* section "__DATA, __objc_const", align 8' %t
+// RUN: grep '@"\\01l_OBJC_$_PROTOCOL_CLASS_METHODS_P" = internal global .* section "__DATA, __objc_const", align 8' %t
+// RUN: grep '@"\\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_P" = internal global .* section "__DATA, __objc_const", align 8' %t
+// RUN: grep '@"\\01l_OBJC_CLASS_PROTOCOLS_$_A" = internal global .* section "__DATA, __objc_const", align 8' %t
+// RUN: grep '@"\\01l_OBJC_CLASS_RO_$_A" = internal global .* section "__DATA, __objc_const", align 8' %t
+// RUN: grep '@"\\01l_OBJC_LABEL_PROTOCOL_$_P" = weak hidden global .* section "__DATA, __objc_protolist, coalesced, no_dead_strip", align 8' %t
+// RUN: grep '@"\\01l_OBJC_METACLASS_RO_$_A" = internal global .* section "__DATA, __objc_const", align 8' %t
+// RUN: grep '@"\\01l_OBJC_PROTOCOL_$_P" = weak hidden global .* section "__DATA,__datacoal_nt,coalesced", align 8' %t
+// RUN: grep '@"\\01l_objc_msgSend_fixup_alloc" = weak hidden global .* section "__DATA, __objc_msgrefs, coalesced", align 16' %t
+// RUN: grep '@_objc_empty_cache = external global' %t
+// RUN: grep '@_objc_empty_vtable = external global' %t
+// RUN: grep '@objc_msgSend_fixup(' %t
+// RUN: grep '@objc_msgSend_fpret(' %t
+
+
+/*
+
+Here is a handy command for looking at llvm-gcc's output:
+llvm-gcc -m64 -emit-llvm -S -o - metadata-symbols-64.m | \
+  grep '=.*global' | \
+  sed -e 's#global.*, section#global ... section#' | \
+  sort
+
+*/
+
+@interface B
+@end
+@interface C
+@end
+
+@protocol P
++(void) fm0;
+-(void) im0;
+@end
+
+@interface A<P> {
+  int _ivar;
+}
+ 
+@property (assign) int ivar;
+
++(void) fm0;
+-(void) im0;
+@end
+
+@implementation A
+@synthesize ivar = _ivar;
++(void) fm0 {
+}
+-(void) im0 {
+}
+@end
+
+@implementation A (Cat)
++(void) fm1 {
+}
+-(void) im1 {
+}
+@end
+
+@interface D : A
+@end
+
+@implementation D
++(void) fm2 {
+  [super fm1];
+}
+-(void) im2 {
+  [super im1];
+}
+@end
+
+// Test for FP dispatch method APIs
+@interface Example 
+@end
+
+float FLOAT;
+double DOUBLE;
+long double LONGDOUBLE;
+id    ID;
+
+@implementation Example
+ - (double) RET_DOUBLE
+   {
+        return DOUBLE;
+   }
+ - (float) RET_FLOAT
+   {
+        return FLOAT;
+   }
+ - (long double) RET_LONGDOUBLE
+   {
+        return LONGDOUBLE;
+   }
+@end
+
+void *f0(id x) {
+   Example* pe;
+   double dd = [pe RET_DOUBLE];
+   dd = [pe RET_FLOAT];
+   dd = [pe RET_LONGDOUBLE];
+
+   [B im0];
+   [C im1];
+   [D alloc];
+}
+
diff --git a/test/CodeGenObjC/metadata_symbols.m b/test/CodeGenObjC/metadata_symbols.m
new file mode 100644
index 0000000..921168c
--- /dev/null
+++ b/test/CodeGenObjC/metadata_symbols.m
@@ -0,0 +1,75 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -emit-llvm -o %t %s
+// RUN: FileCheck -check-prefix=CHECK-X86_64 < %t %s
+// RUN: grep '@"OBJC_EHTYPE_$_EH3"' %t | count 3
+
+// CHECK-X86_64: @"OBJC_CLASS_$_A" = global {{.*}}, section "__DATA, __objc_data", align 8
+// CHECK-X86_64: @"OBJC_METACLASS_$_A" = global {{.*}}, section "__DATA, __objc_data", align 8
+// CHECK-X86_64: @"\01L_OBJC_CLASS_NAME_" = {{.*}}, section "__TEXT,__cstring,cstring_literals", align 1
+// CHECK-X86_64: @"OBJC_EHTYPE_$_EH1" = weak global {{.*}}, section "__DATA,__datacoal_nt,coalesced", align 8
+// CHECK-X86_64: @"OBJC_EHTYPE_$_EH2" = external global
+// CHECK-X86_64: @"OBJC_EHTYPE_$_EH3" = global {{.*}}, section "__DATA,__objc_const", align 8
+// CHECK-X86_64: @"\01L_OBJC_LABEL_CLASS_$" = internal global {{.*}}, section "__DATA, __objc_classlist, regular, no_dead_strip", align 8
+// CHECK-X86_64: define internal void @"\01-[A im0]"
+// CHECK-X86_64: define internal void @"\01-[A(Cat) im1]"
+
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fvisibility hidden -emit-llvm -o %t %s
+// RUN: FileCheck -check-prefix=CHECK-X86_64-HIDDEN < %t %s
+
+// CHECK-X86_64-HIDDEN: @"OBJC_CLASS_$_A" = hidden global {{.*}}, section "__DATA, __objc_data", align 8
+// CHECK-X86_64-HIDDEN: @"OBJC_METACLASS_$_A" = hidden global {{.*}}, section "__DATA, __objc_data", align 8
+// CHECK-X86_64-HIDDEN: @"OBJC_EHTYPE_$_EH1" = weak hidden global {{.*}}, section "__DATA,__datacoal_nt,coalesced"
+// CHECK-X86_64-HIDDEN: @"OBJC_EHTYPE_$_EH2" = external global
+// CHECK-X86_64-HIDDEN: @"OBJC_EHTYPE_$_EH3" = hidden global {{.*}}, section "__DATA,__objc_const", align 8
+// CHECK-X86_64-HIDDEN: define internal void @"\01-[A im0]"
+// CHECK-X86_64-HIDDEN: define internal void @"\01-[A(Cat) im1]"
+
+// RUN: %clang_cc1 -triple armv6-apple-darwin10 -target-abi apcs-gnu -fobjc-nonfragile-abi -emit-llvm -o %t %s
+// RUN: FileCheck -check-prefix=CHECK-ARMV6 < %t %s
+
+// CHECK-ARMV6: @"OBJC_CLASS_$_A" = global {{.*}}, section "__DATA, __objc_data", align 4
+// CHECK-ARMV6: @"OBJC_METACLASS_$_A" = global {{.*}}, section "__DATA, __objc_data", align 4
+// CHECK-ARMV6: @"\01L_OBJC_CLASS_NAME_" = {{.*}}, section "__TEXT,__cstring,cstring_literals", align 1
+// CHECK-ARMV6: @"OBJC_EHTYPE_$_EH1" = weak global {{.*}}, section "__DATA,__datacoal_nt,coalesced", align 4
+// CHECK-ARMV6: @"OBJC_EHTYPE_$_EH2" = external global
+// CHECK-ARMV6: @"OBJC_EHTYPE_$_EH3" = global {{.*}}, section "__DATA,__objc_const", align 4
+// CHECK-ARMV6: @"\01L_OBJC_LABEL_CLASS_$" = internal global {{.*}}, section "__DATA, __objc_classlist, regular, no_dead_strip", align 4
+// CHECK-ARMV6: define internal arm_apcscc void @"\01-[A im0]"
+// CHECK-ARMV6: define internal arm_apcscc void @"\01-[A(Cat) im1]"
+
+@interface A
+@end
+
+@implementation A
+-(void) im0 {
+}
+@end
+
+@implementation A (Cat)
+-(void) im1 {
+}
+@end
+
+@interface EH1
+@end
+
+__attribute__((__objc_exception__))
+@interface EH2
+@end
+
+__attribute__((__objc_exception__))
+@interface EH3
+@end
+
+void f1();
+
+void f0(id x) {
+  @try {
+    f1();
+  } @catch (EH1 *x) {
+  } @catch (EH2 *x) {
+  } @catch (EH3 *x) {
+  }
+}
+
+@implementation EH3
+@end
diff --git a/test/CodeGenObjC/missing-atend-metadata.m b/test/CodeGenObjC/missing-atend-metadata.m
new file mode 100644
index 0000000..50e597c
--- /dev/null
+++ b/test/CodeGenObjC/missing-atend-metadata.m
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -emit-llvm %s -o - | FileCheck %s
+
+@interface I0 
+@end
+
+@implementation I0 // expected-warning {{'@end' is missing in implementation context}}
+- meth { return 0; }
+
+@interface I1 : I0 
+@end
+
+@implementation I1 // expected-warning {{'@end' is missing in implementation context}}
+-(void) im0 { self = [super init]; }
+
+@interface I2 : I0
+- I2meth;
+@end
+
+@implementation I2 // expected-warning {{'@end' is missing in implementation context}}
+- I2meth { return 0; }
+
+@implementation  I2(CAT) // expected-warning {{'@end' is missing in implementation context}}
+
+// CHECK: @"\01L_OBJC_CLASS_I1" = internal global
diff --git a/test/CodeGenObjC/nested-rethrow.m b/test/CodeGenObjC/nested-rethrow.m
new file mode 100644
index 0000000..627b913
--- /dev/null
+++ b/test/CodeGenObjC/nested-rethrow.m
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -emit-llvm %s -o - | FileCheck %s
+
+
+extern int printf(const char*, ...);
+
+int main()
+{
+    @try {
+        @throw @"foo";
+    } @catch (id e) {
+        @try {
+// CHECK: call void @objc_exception_throw
+           @throw;
+        } @catch (id e) {
+            if (e) {
+                printf("caught \n");
+            } else {
+                printf("caught (WRONG)\n");
+            }
+        } @catch (...) {
+            printf("caught nothing (WRONG)\n");
+        }
+    }
+}
+
diff --git a/test/CodeGenObjC/newproperty-nested-synthesis-1.m b/test/CodeGenObjC/newproperty-nested-synthesis-1.m
new file mode 100644
index 0000000..4831c22
--- /dev/null
+++ b/test/CodeGenObjC/newproperty-nested-synthesis-1.m
@@ -0,0 +1,78 @@
+// RUN: %clang_cc1 -emit-llvm -o %t %s
+
+@interface Object
+- (id) new;
+@end
+
+@interface Tester : Object
+@property char PropertyAtomic_char;
+@property short PropertyAtomic_short;
+@property int PropertyAtomic_int;
+@property long PropertyAtomic_long;
+@property long long PropertyAtomic_longlong;
+@property float PropertyAtomic_float;
+@property double PropertyAtomic_double;
+@property(assign) id PropertyAtomic_id;
+@property(retain) id PropertyAtomicRetained_id;
+@property(copy) id PropertyAtomicRetainedCopied_id;
+@property(retain) id PropertyAtomicRetainedGCOnly_id;
+@property(copy) id PropertyAtomicRetainedCopiedGCOnly_id;
+@end
+
+@implementation Tester
+@dynamic PropertyAtomic_char;
+@dynamic PropertyAtomic_short;
+@dynamic PropertyAtomic_int;
+@dynamic PropertyAtomic_long;
+@dynamic PropertyAtomic_longlong;
+@dynamic PropertyAtomic_float;
+@dynamic PropertyAtomic_double;
+@dynamic PropertyAtomic_id;
+@dynamic PropertyAtomicRetained_id;
+@dynamic PropertyAtomicRetainedCopied_id;
+@dynamic PropertyAtomicRetainedGCOnly_id;
+@dynamic PropertyAtomicRetainedCopiedGCOnly_id;
+@end
+
+@interface SubClass : Tester
+{
+    char PropertyAtomic_char;
+    short PropertyAtomic_short;
+    int PropertyAtomic_int;
+    long PropertyAtomic_long;
+    long long PropertyAtomic_longlong;
+    float PropertyAtomic_float;
+    double PropertyAtomic_double;
+    id PropertyAtomic_id;
+    id PropertyAtomicRetained_id;
+    id PropertyAtomicRetainedCopied_id;
+    id PropertyAtomicRetainedGCOnly_id;
+    id PropertyAtomicRetainedCopiedGCOnly_id;
+}
+@end
+
+@implementation SubClass
+@synthesize PropertyAtomic_char;
+@synthesize PropertyAtomic_short;
+@synthesize PropertyAtomic_int;
+@synthesize PropertyAtomic_long;
+@synthesize PropertyAtomic_longlong;
+@synthesize PropertyAtomic_float;
+@synthesize PropertyAtomic_double;
+@synthesize PropertyAtomic_id;
+@synthesize PropertyAtomicRetained_id;
+@synthesize PropertyAtomicRetainedCopied_id;
+@synthesize PropertyAtomicRetainedGCOnly_id;
+@synthesize PropertyAtomicRetainedCopiedGCOnly_id;
+@end
+
+int main()
+{
+    SubClass *f = [SubClass new];
+    f.PropertyAtomic_int = 1;
+
+    f.PropertyAtomic_int += 3;
+
+    f.PropertyAtomic_int -= 4;
+    return f.PropertyAtomic_int;
+}
diff --git a/test/CodeGenObjC/next-objc-dispatch.m b/test/CodeGenObjC/next-objc-dispatch.m
new file mode 100644
index 0000000..a3e8e19
--- /dev/null
+++ b/test/CodeGenObjC/next-objc-dispatch.m
@@ -0,0 +1,73 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -emit-llvm -o - %s \
+// RUN:   -fobjc-dispatch-method=legacy | \
+// RUN:   FileCheck -check-prefix CHECK-FRAGILE_LEGACY %s
+//
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -emit-llvm -o - %s    \
+// RUN:   -fobjc-nonfragile-abi -fobjc-dispatch-method=legacy | \
+// RUN:   FileCheck -check-prefix CHECK-NONFRAGILE_LEGACY %s
+//
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -emit-llvm -o - %s    \
+// RUN:   -fobjc-nonfragile-abi -fobjc-dispatch-method=non-legacy | \
+// RUN:   FileCheck -check-prefix CHECK-NONFRAGILE_NONLEGACY %s
+//
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -emit-llvm -o - %s    \
+// RUN:   -fobjc-nonfragile-abi -fobjc-dispatch-method=mixed | \
+// RUN:   FileCheck -check-prefix CHECK-NONFRAGILE_MIXED %s
+//
+// <rdar://problem/7866951>
+
+// There are basically four ways that we end up doing message dispatch for the
+// NeXT runtime. They are:
+//  (1) fragile ABI, legacy dispatch
+//  (2) non-fragile ABI, legacy dispatch
+//  (2) non-fragile ABI, non-legacy dispatch
+//  (2) non-fragile ABI, mixed dispatch
+//
+// Note that fragile ABI and non-fragile ABI legacy dispatch are not the same,
+// they use some different API calls (objc_msgSendSuper vs objc_msgSendSuper2).
+
+// CHECK-FRAGILE_LEGACY: ModuleID
+// CHECK-FRAGILE_LEGACY-NOT: declare i8* @objc_msgSendSuper2_fixup(
+// CHECK-FRAGILE_LEGACY-NOT: declare i8* @objc_msgSend_fixup(
+// CHECK-FRAGILE_LEGACY: declare i8* @objc_msgSendSuper(
+// CHECK-FRAGILE_LEGACY: declare i8* @objc_msgSend(
+
+// CHECK-NONFRAGILE_LEGACY: ModuleID
+// CHECK-NONFRAGILE_LEGACY-NOT: declare i8* @objc_msgSendSuper2_fixup(
+// CHECK-NONFRAGILE_LEGACY-NOT: declare i8* @objc_msgSend_fixup(
+// CHECK-NONFRAGILE_LEGACY: declare i8* @objc_msgSendSuper2(
+// CHECK-NONFRAGILE_LEGACY: declare i8* @objc_msgSend(
+
+// CHECK-NONFRAGILE_NONLEGACY: ModuleID
+// CHECK-NONFRAGILE_NONLEGACY: declare i8* @objc_msgSendSuper2_fixup(
+// CHECK-NONFRAGILE_NONLEGACY: declare i8* @objc_msgSend_fixup(
+
+// CHECK-NONFRAGILE_MIXED: declare i8* @objc_msgSendSuper2_fixup(
+// CHECK-NONFRAGILE_MIXED: declare i8* @objc_msgSendSuper2(
+// CHECK-NONFRAGILE_MIXED: declare i8* @objc_msgSend_fixup(
+// CHECK-NONFRAGILE_MIXED: declare i8* @objc_msgSend(
+
+@interface NSObject
++ (id)alloc;
+- (id)init;
+@end
+
+@interface I0 : NSObject
+-(void) im0;
+@end
+
+@implementation I0
++(id) alloc {
+  return [super alloc];
+}
+-(id) init {
+ [super init];
+ return self;
+}
+-(void) im0 {}
+@end
+
+void f0(I0 *a) {
+  [I0 alloc];
+  [a im0];
+}
diff --git a/test/CodeGenObjC/no-category-class.m b/test/CodeGenObjC/no-category-class.m
new file mode 100644
index 0000000..0bd9996
--- /dev/null
+++ b/test/CodeGenObjC/no-category-class.m
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o %t %s
+
+@interface NSObject
+@end
+
+@implementation NSObject(IBXLIFFIntegration)
+@end
+
diff --git a/test/CodeGenObjC/non-lazy-classes.m b/test/CodeGenObjC/non-lazy-classes.m
new file mode 100644
index 0000000..512ad89
--- /dev/null
+++ b/test/CodeGenObjC/non-lazy-classes.m
@@ -0,0 +1,32 @@
+// RUNX: llvm-gcc -m64 -emit-llvm -S -o %t %s &&
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -emit-llvm -o %t %s
+// RUN: grep '@".01L_OBJC_LABEL_NONLAZY_CLASS_$" = internal global \[1 x .*\] .*@"OBJC_CLASS_$_A".*, section "__DATA, __objc_nlclslist, regular, no_dead_strip", align 8' %t
+// RUN: grep '@".01L_OBJC_LABEL_NONLAZY_CATEGORY_$" = internal global \[1 x .*\] .*@".01l_OBJC_$_CATEGORY_A_$_Cat".*, section "__DATA, __objc_nlcatlist, regular, no_dead_strip", align 8' %t
+
+@interface A @end
+@implementation A
++(void) load {
+}
+@end
+
+@interface A (Cat) @end
+@implementation A (Cat)
++(void) load {
+}
+@end
+
+@interface B @end
+@implementation B
+-(void) load {
+}
+@end
+
+@interface B (Cat) @end
+@implementation B (Cat)
+-(void) load {
+}
+@end
+
+@interface C : A @end
+@implementation C
+@end
diff --git a/test/CodeGenObjC/ns-constant-strings.m b/test/CodeGenObjC/ns-constant-strings.m
new file mode 100644
index 0000000..3ef5f55
--- /dev/null
+++ b/test/CodeGenObjC/ns-constant-strings.m
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -fno-constant-cfstrings -emit-llvm -o %t %s
+// RUN: FileCheck --check-prefix CHECK-FRAGILE < %t %s
+
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fno-constant-cfstrings -emit-llvm -o %t %s
+// RUN: FileCheck --check-prefix CHECK-NONFRAGILE < %t %s
+
+@interface NSString @end
+
+@interface NSSimpleCString : NSString {
+@protected
+    char *bytes;
+    unsigned int numBytes;
+}
+@end
+    
+@interface NSConstantString : NSSimpleCString
+@end
+
+#if OBJC_API_VERSION >= 2
+extern Class _NSConstantStringClassReference;
+#else
+extern struct objc_class _NSConstantStringClassReference;
+#endif
+
+const NSConstantString *appKey =  @"MyApp";
+
+int main() {
+  const NSConstantString *appKey =  @"MyApp";
+  const NSConstantString *appKey1 =  @"MyApp1";
+}
+
+// CHECK-FRAGILE: @_NSConstantStringClassReference = external global
+// CHECK-NONFRAGILE: @"OBJC_CLASS_$_NSConstantString" = external global
diff --git a/test/CodeGenObjC/objc-align.m b/test/CodeGenObjC/objc-align.m
new file mode 100644
index 0000000..ff3f2a0
--- /dev/null
+++ b/test/CodeGenObjC/objc-align.m
@@ -0,0 +1,46 @@
+// 32-bit
+
+// RUNX: llvm-gcc -m32 -emit-llvm -S -o %t %s &&
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -emit-llvm -o %t %s
+// RUN: grep '@"\\01L_OBJC_CATEGORY_A_Cat" = internal global .*, section "__OBJC,__category,regular,no_dead_strip", align 4' %t
+// RUN: grep '@"\\01L_OBJC_CLASS_A" = internal global .*, section "__OBJC,__class,regular,no_dead_strip", align 4' %t
+// RUN: grep '@"\\01L_OBJC_CLASS_C" = internal global .*, section "__OBJC,__class,regular,no_dead_strip", align 4' %t
+// RUN: grep '@"\\01L_OBJC_CLASS_PROTOCOLS_C" = internal global .*, section "__OBJC,__cat_cls_meth,regular,no_dead_strip", align 4' %t
+// RUN: grep '@"\\01L_OBJC_IMAGE_INFO" = internal constant .*, section "__OBJC, __image_info,regular"' %t
+// RUN: grep '@"\\01L_OBJC_METACLASS_A" = internal global .*, section "__OBJC,__meta_class,regular,no_dead_strip", align 4' %t
+// RUN: grep '@"\\01L_OBJC_METACLASS_C" = internal global .*, section "__OBJC,__meta_class,regular,no_dead_strip", align 4' %t
+// RUN: grep '@"\\01L_OBJC_MODULES" = internal global .*, section "__OBJC,__module_info,regular,no_dead_strip", align 4' %t
+// RUN: grep '@"\\01L_OBJC_PROTOCOL_P" = internal global .*, section "__OBJC,__protocol,regular,no_dead_strip", align 4' %t
+
+// 64-bit
+
+// RUNX: %clang_cc1 -triple i386-apple-darwin9 -emit-llvm -o %t %s &&
+// RUNX: grep '@"OBJC_CLASS_$_A" = global' %t &&
+// RUNX: grep '@"OBJC_CLASS_$_C" = global' %t &&
+// RUNX: grep '@"OBJC_METACLASS_$_A" = global' %t &&
+// RUNX: grep '@"OBJC_METACLASS_$_C" = global' %t &&
+// RUNX: grep '@"\\01L_OBJC_CLASSLIST_REFERENCES_$_0" = internal global .*, section "__DATA, __objc_classrefs, regular, no_dead_strip", align 8' %t &&
+// RUNX: grep '@"\\01L_OBJC_IMAGE_INFO" = internal constant .*, section "__DATA, __objc_imageinfo, regular, no_dead_strip"' %t &&
+// RUNX: grep '@"\\01L_OBJC_LABEL_CATEGORY_$" = internal global .*, section "__DATA, __objc_catlist, regular, no_dead_strip", align 8' %t &&
+// RUNX: grep '@"\\01L_OBJC_LABEL_CLASS_$" = internal global .*, section "__DATA, __objc_classlist, regular, no_dead_strip", align 8' %t &&
+// RUNX: grep '@"\\01l_OBJC_$_CATEGORY_A_$_Cat" = internal global .*, section "__DATA, __objc_const", align 8' %t &&
+// RUNX: grep '@"\\01l_OBJC_CLASS_PROTOCOLS_$_C" = internal global .*, section "__DATA, __objc_const", align 8' %t &&
+// RUNX: grep '@"\\01l_OBJC_CLASS_RO_$_A" = internal global .*, section "__DATA, __objc_const", align 8' %t &&
+// RUNX: grep '@"\\01l_OBJC_CLASS_RO_$_C" = internal global .*, section "__DATA, __objc_const", align 8' %t &&
+// RUNX: grep '@"\\01l_OBJC_LABEL_PROTOCOL_$_P" = weak hidden global .*, section "__DATA, __objc_protolist, coalesced, no_dead_strip", align 8' %t &&
+// RUNX: grep '@"\\01l_OBJC_METACLASS_RO_$_A" = internal global .*, section "__DATA, __objc_const", align 8' %t &&
+// RUNX: grep '@"\\01l_OBJC_METACLASS_RO_$_C" = internal global .*, section "__DATA, __objc_const", align 8' %t &&
+// RUNX: grep '@"\\01l_OBJC_PROTOCOL_$_P" = weak hidden global .*, section "__DATA,__datacoal_nt,coalesced", align 8' %t &&
+
+
+@interface A @end
+@implementation A
+@end
+@implementation A (Cat)
+@end
+@protocol P
+@end
+@interface C <P>
+@end
+@implementation C
+@end
diff --git a/test/CodeGenObjC/objc-assign-ivar.m b/test/CodeGenObjC/objc-assign-ivar.m
new file mode 100644
index 0000000..aefe97d
--- /dev/null
+++ b/test/CodeGenObjC/objc-assign-ivar.m
@@ -0,0 +1,52 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-gc -emit-llvm -o %t %s
+// RUN: grep -F '@objc_assign_ivar' %t  | count 14
+
+typedef struct {
+  id  element;
+  id elementArray[10];
+  __strong id cfElement;
+  __strong id cfElementArray[10];
+} struct_with_ids_t;
+
+
+@interface NSString @end
+
+@interface Foo  {
+@public
+// assignments to any/all of these fields should generate objc_assign_ivar
+  __strong id dict;
+  __strong id dictArray[3];
+  id ivar;
+  id array[10];
+  id nsobject;
+  NSString *stringArray[10];
+  struct_with_ids_t inner;
+
+  Foo *obj[20];
+  short idx[5];
+}
+@end
+
+// The test cases
+int IvarAssigns;
+void *rhs = 0;
+#define ASSIGNTEST(expr, global) expr = rhs
+
+void testIvars() {
+  Foo *foo;
+  ASSIGNTEST(foo->ivar, IvarAssigns);                                   // objc_assign_ivar
+  ASSIGNTEST(foo->dict, IvarAssigns);                                   // objc_assign_ivar
+  ASSIGNTEST(foo->dictArray[0], IvarAssigns);                           // objc_assign_ivar
+  ASSIGNTEST(foo->array[0], IvarAssigns);                               // objc_assign_ivar
+  ASSIGNTEST(foo->nsobject, IvarAssigns);                               // objc_assign_ivar
+  ASSIGNTEST(foo->stringArray[0], IvarAssigns);                         // objc_assign_ivar
+  ASSIGNTEST(foo->inner.element, IvarAssigns);                          // objc_assign_ivar
+  ASSIGNTEST(foo->inner.elementArray[0], IvarAssigns);                  // objc_assign_ivar
+  ASSIGNTEST(foo->inner.cfElement, IvarAssigns);                        // objc_assign_ivar
+  ASSIGNTEST(foo->inner.cfElementArray[0], IvarAssigns);                // objc_assign_ivar
+  int counter=1;
+  ASSIGNTEST(foo->obj[5], IvarAssigns);                 // objc_assign_ivar
+  ASSIGNTEST(foo->obj[++counter], IvarAssigns);         // objc_assign_ivar
+  foo->idx[++counter] = 15;
+  ASSIGNTEST(foo->obj[foo->idx[2]], IvarAssigns);       // objc_assign_ivar
+}
diff --git a/test/CodeGenObjC/objc-read-weak-byref.m b/test/CodeGenObjC/objc-read-weak-byref.m
new file mode 100644
index 0000000..1ddbcaf
--- /dev/null
+++ b/test/CodeGenObjC/objc-read-weak-byref.m
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -fblocks -fobjc-gc -triple x86_64-apple-darwin -S %s -o %t-64.s
+// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s
+// RUN: %clang_cc1 -fblocks -fobjc-gc -triple i386-apple-darwin -S %s -o %t-32.s
+// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s
+
+@interface NSObject 
+- copy;
+@end
+
+int main() {
+    NSObject *object = 0;
+    __weak __block NSObject* weak_object = object;
+    void (^callback) (void) = [^{
+        if (weak_object)
+                [weak_object copy];
+    } copy];
+    callback();
+    return 0;
+}
+
+// CHECK-LP64: callq    _objc_read_weak
+// CHECK-LP64: callq    _objc_read_weak
+
+// CHECK-LP32: call     L_objc_read_weak
+// CHECK-LP32: call     L_objc_read_weak
diff --git a/test/CodeGenObjC/objc2-assign-global.m b/test/CodeGenObjC/objc2-assign-global.m
new file mode 100644
index 0000000..ff3ecef
--- /dev/null
+++ b/test/CodeGenObjC/objc2-assign-global.m
@@ -0,0 +1,80 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-gc -emit-llvm -o %t %s
+// RUN: grep -F '@objc_assign_global' %t  | count 26
+
+@class NSObject;
+typedef const struct __CFDictionary * CFDictionaryRef;
+typedef struct {
+  id  element;
+  id elementArray[10];
+  __strong CFDictionaryRef cfElement;
+  __strong CFDictionaryRef cfElementArray[10];
+} struct_with_ids_t;
+
+
+// assignments to these should generate objc_assign_global
+@interface A
+@end
+
+typedef struct s0 {
+  A *a[4];
+} T;
+
+T g0;
+
+extern id FileExternID;
+static id FileStaticID;
+id GlobalId;
+id GlobalArray[20];
+NSObject *GlobalObject;
+NSObject *GlobalObjectArray[20];
+__strong CFDictionaryRef Gdict;
+__strong CFDictionaryRef Gdictarray[10];
+struct_with_ids_t GlobalStruct;
+struct_with_ids_t GlobalStructArray[10];
+
+#define ASSIGNTEST(expr, global) expr = rhs
+void *rhs = 0;
+
+int main() {
+  static id staticGlobalId;
+  static id staticGlobalArray[20];
+  static NSObject *staticGlobalObject;
+  static NSObject *staticGlobalObjectArray[20];
+  static __strong CFDictionaryRef staticGdict;
+  static __strong CFDictionaryRef staticGdictarray[10];
+  static struct_with_ids_t staticGlobalStruct;
+  static struct_with_ids_t staticGlobalStructArray[10];
+  extern id ExID;
+  id localID;
+
+  ASSIGNTEST(GlobalId, GlobalAssigns);                          // objc_assign_global
+  ASSIGNTEST(GlobalArray[0], GlobalAssigns);                    // objc_assign_global
+  ASSIGNTEST(GlobalObject, GlobalAssigns);                      // objc_assign_global
+  ASSIGNTEST(GlobalObjectArray[0], GlobalAssigns);              // objc_assign_global
+  ASSIGNTEST(Gdict, GlobalAssigns);                             // objc_assign_global
+  ASSIGNTEST(Gdictarray[1], GlobalAssigns);                     // objc_assign_global
+
+  ASSIGNTEST(GlobalStruct.element, GlobalAssigns);              // objc_assign_global
+  ASSIGNTEST(GlobalStruct.elementArray[0], GlobalAssigns);      // objc_assign_global
+  ASSIGNTEST(GlobalStruct.cfElement, GlobalAssigns);            // objc_assign_global
+  ASSIGNTEST(GlobalStruct.cfElementArray[0], GlobalAssigns);    // objc_assign_global
+
+  ASSIGNTEST(staticGlobalId, GlobalAssigns);                    // objc_assign_global
+  ASSIGNTEST(staticGlobalArray[0], GlobalAssigns);              // objc_assign_global
+  ASSIGNTEST(staticGlobalObject, GlobalAssigns);                // objc_assign_global
+  ASSIGNTEST(staticGlobalObjectArray[0], GlobalAssigns);        // objc_assign_global
+  ASSIGNTEST(staticGdict, GlobalAssigns);                       // objc_assign_global
+  ASSIGNTEST(staticGdictarray[1], GlobalAssigns);               // objc_assign_global
+
+  ASSIGNTEST(staticGlobalStruct.element, GlobalAssigns);                // objc_assign_global
+  ASSIGNTEST(staticGlobalStruct.elementArray[0], GlobalAssigns);        // objc_assign_global
+  ASSIGNTEST(staticGlobalStruct.cfElement, GlobalAssigns);              // objc_assign_global
+  ASSIGNTEST(staticGlobalStruct.cfElementArray[0], GlobalAssigns);      // objc_assign_global
+
+  ExID = 0;
+  localID = 0;
+  FileStaticID = 0;
+  FileExternID=0;
+  g0.a[0] = 0;
+  ((T*) &g0)->a[0] = 0;
+}
diff --git a/test/CodeGenObjC/objc2-ivar-assign.m b/test/CodeGenObjC/objc2-ivar-assign.m
new file mode 100644
index 0000000..e50cc5b
--- /dev/null
+++ b/test/CodeGenObjC/objc2-ivar-assign.m
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -fobjc-nonfragile-abi -fobjc-gc -emit-llvm -o %t %s
+// RUN: grep objc_assign_ivar %t | count 6
+
+@interface I @end
+
+typedef I TI;
+typedef I* TPI;
+
+typedef id ID;
+
+@interface MyClass {
+}
+
+@property id property;
+@property I* propertyI;
+
+@property TI* propertyTI;
+
+@property TPI propertyTPI;
+
+@property ID propertyID;
+@end
+
+@implementation MyClass
+	@synthesize property=_property;
+        @synthesize propertyI;
+        @synthesize propertyTI=_propertyTI;
+        @synthesize propertyTPI=_propertyTPI;
+         @synthesize propertyID = _propertyID;
+@end
+
+int main () {
+    MyClass *myObj;
+    myObj.property = 0;
+    myObj.propertyI = 0;
+    myObj.propertyTI = 0;
+    myObj.propertyTPI = 0;
+    myObj.propertyID = 0;
+    return 0;
+}
diff --git a/test/CodeGenObjC/objc2-legacy-dispatch.m b/test/CodeGenObjC/objc2-legacy-dispatch.m
new file mode 100644
index 0000000..7a99d15
--- /dev/null
+++ b/test/CodeGenObjC/objc2-legacy-dispatch.m
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -fobjc-nonfragile-abi -fobjc-dispatch-method=mixed -triple i386-apple-darwin10 -emit-llvm -o - %s | FileCheck -check-prefix=CHECK_NEW_DISPATCH %s
+//
+// CHECK_NEW_DISPATCH: define void @f0
+// CHECK_NEW_DISPATCH: bitcast {{.*}}objc_msgSend_fixup_alloc
+// CHECK_NEW_DISPATCH: define void @f1
+// CHECK_NEW_DISPATCH: load {{.*}}OBJC_SELECTOR_REFERENCES
+//
+// RUN: %clang_cc1 -fobjc-nonfragile-abi -fobjc-dispatch-method=legacy -emit-llvm -o - %s | FileCheck -check-prefix=CHECK_OLD_DISPATCH %s
+//
+// CHECK_OLD_DISPATCH: define void @f0
+// CHECK_OLD_DISPATCH: load {{.*}}OBJC_SELECTOR_REFERENCES
+// CHECK_OLD_DISPATCH: define void @f1
+// CHECK_OLD_DISPATCH: load {{.*}}OBJC_SELECTOR_REFERENCES
+
+@interface A
++(id) alloc;
+-(int) im0;
+@end
+
+void f0(void) {
+  [A alloc];
+}
+
+void f1(A *a) {
+  [a im0];
+}
diff --git a/test/CodeGenObjC/objc2-new-gc-api-strongcast.m b/test/CodeGenObjC/objc2-new-gc-api-strongcast.m
new file mode 100644
index 0000000..1ff2dd3
--- /dev/null
+++ b/test/CodeGenObjC/objc2-new-gc-api-strongcast.m
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fblocks -fobjc-gc -emit-llvm -o %t %s
+// RUN: grep -F '@objc_assign_strongCast' %t  | count 4
+
+@interface DSATextSearch @end
+
+DSATextSearch **_uniqueIdToIdentifierArray = ((void *)0);
+void foo (int _nextId)
+{
+	_uniqueIdToIdentifierArray[_nextId] = 0;  // objc_assign_strongCast
+}
+
+typedef struct {
+    unsigned long state;
+    id *itemsPtr;
+    void (^bp)();
+    unsigned long *mutationsPtr;
+    unsigned long extra[5];
+} NSFastEnumerationState;
+
+void foo1 (NSFastEnumerationState * state)
+{
+   state->itemsPtr = 0;
+   state->bp = ^{};
+}
+
diff --git a/test/CodeGenObjC/objc2-no-strong-cast.m b/test/CodeGenObjC/objc2-no-strong-cast.m
new file mode 100644
index 0000000..0824f40
--- /dev/null
+++ b/test/CodeGenObjC/objc2-no-strong-cast.m
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -emit-llvm -o %t %s
+
+@interface PDFViewPrivateVars 
+{
+@public
+	__attribute__((objc_gc(strong))) char *addedTooltips;
+}
+@end
+
+@interface PDFView 
+{
+    PDFViewPrivateVars *_pdfPriv;
+}
+@end
+
+@implementation PDFView
+- (void) addTooltipsForPage
+{
+ _pdfPriv->addedTooltips[4] = 1;
+}
+@end
+
diff --git a/test/CodeGenObjC/objc2-no-write-barrier.m b/test/CodeGenObjC/objc2-no-write-barrier.m
new file mode 100644
index 0000000..544c329
--- /dev/null
+++ b/test/CodeGenObjC/objc2-no-write-barrier.m
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -fobjc-gc -emit-llvm -o %t %s
+// RUN: grep 'objc_assign' %t | count 0
+
+typedef struct {
+    int ival;
+    id submenu;
+} XCBinderContextMenuItem;
+
+id actionMenuForDataNode(void) {
+    XCBinderContextMenuItem menusToCreate[]  = {
+        {1, 0}
+    };
+    return 0;
+}
+
+XCBinderContextMenuItem GmenusToCreate[]  = {
+        {1, 0}
+};
diff --git a/test/CodeGenObjC/objc2-nonfragile-abi-impl.m b/test/CodeGenObjC/objc2-nonfragile-abi-impl.m
new file mode 100644
index 0000000..ff94330
--- /dev/null
+++ b/test/CodeGenObjC/objc2-nonfragile-abi-impl.m
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi2 -emit-llvm -o %t %s
+// rdar://7547942.
+
+@interface Base @end
+
+@interface Sub1 : Base @end
+
+@implementation Sub1 @end
+
+@implementation Base { 
+@private 
+  id ivar; 
+} 
+@end
+
diff --git a/test/CodeGenObjC/objc2-property-encode.m b/test/CodeGenObjC/objc2-property-encode.m
new file mode 100644
index 0000000..0f18d6f
--- /dev/null
+++ b/test/CodeGenObjC/objc2-property-encode.m
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -triple=i686-apple-darwin9 -emit-llvm -o %t %s
+// RUN: grep -e "T@\\\\22NSString\\\\22" %t
+@interface NSString @end
+
+typedef NSString StoreVersionID ;
+
+@interface Parent 
+  @property(retain) StoreVersionID* foo;
+@end
+
+@implementation Parent
+@dynamic foo;
+@end
diff --git a/test/CodeGenObjC/objc2-protocol-enc.m b/test/CodeGenObjC/objc2-protocol-enc.m
new file mode 100644
index 0000000..0db0cb8
--- /dev/null
+++ b/test/CodeGenObjC/objc2-protocol-enc.m
@@ -0,0 +1,43 @@
+// RUN: %clang_cc1 -triple=i686-apple-darwin9 -emit-llvm -o %t %s
+// RUN: grep -e "T@\\\22<X>\\\22" %t
+// RUN: grep -e "T@\\\22<X><Y>\\\22" %t
+// RUN: grep -e "T@\\\22<X><Y><Z>\\\22" %t
+// RUN: grep -e "T@\\\22Foo<X><Y><Z>\\\22" %t
+
+@protocol X, Y, Z;
+@class Foo;
+
+@protocol Proto
+@property (copy) id <X> x;
+@property (copy) id <X, Y> xy;
+@property (copy) id <X, Y, Z> xyz;
+@property(copy)  Foo <X, Y, Z> *fooxyz;
+@end
+
+@interface Intf <Proto>
+{
+id <X> IVAR_x;
+id <X, Y> IVAR_xy;
+id <X, Y, Z> IVAR_xyz;
+Foo <X, Y, Z> *IVAR_Fooxyz;
+}
+@end
+
+@implementation Intf 
+@dynamic x, xy, xyz, fooxyz;
+@end
+
+/**
+This protocol should generate the following metadata:
+struct objc_property_list __Protocol_Test_metadata = {
+  sizeof(struct objc_property), 4,
+  {
+    { "x", "T@\"<X>\"" },
+    { "xy", "T@\"<X><Y>\"" },
+    { "xyz", "T@\"<X><Y><Z>\"" },
+    { "fooxyz", "T@\"Foo<X><Y><Z>\"" }
+  }
+};
+
+"T@\"<X><Y><Z>\",D
+*/
diff --git a/test/CodeGenObjC/objc2-retain-codegen.m b/test/CodeGenObjC/objc2-retain-codegen.m
new file mode 100644
index 0000000..2c3317a
--- /dev/null
+++ b/test/CodeGenObjC/objc2-retain-codegen.m
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fobjc-gc-only -emit-llvm -o %t %s
+
+@interface I0 {
+  I0 *_f0;
+}
+@property (retain) id p0;
+@end 
+
+@implementation I0 
+  @synthesize p0 = _f0;
+@end
+
diff --git a/test/CodeGenObjC/objc2-strong-cast-1.m b/test/CodeGenObjC/objc2-strong-cast-1.m
new file mode 100644
index 0000000..509f21a
--- /dev/null
+++ b/test/CodeGenObjC/objc2-strong-cast-1.m
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fobjc-gc -emit-llvm -o %t %s
+
+@interface I {
+  __attribute__((objc_gc(strong))) int *i_IdocumentIDs;
+  __attribute__((objc_gc(strong))) long *l_IdocumentIDs;
+  __attribute__((objc_gc(strong))) long long *ll_IdocumentIDs;
+  __attribute__((objc_gc(strong))) float *IdocumentIDs;
+  __attribute__((objc_gc(strong))) double *d_IdocumentIDs;
+}
+- (void) _getResultsOfMatches;
+@end
+
+@implementation I
+-(void) _getResultsOfMatches {
+    IdocumentIDs[2] = IdocumentIDs[3];
+    d_IdocumentIDs[2] = d_IdocumentIDs[3];
+    l_IdocumentIDs[2] = l_IdocumentIDs[3];
+    ll_IdocumentIDs[2] = ll_IdocumentIDs[3];
+    i_IdocumentIDs[2] = i_IdocumentIDs[3];
+}
+
+@end
+
diff --git a/test/CodeGenObjC/objc2-strong-cast.m b/test/CodeGenObjC/objc2-strong-cast.m
new file mode 100644
index 0000000..9ef463c
--- /dev/null
+++ b/test/CodeGenObjC/objc2-strong-cast.m
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -fobjc-gc -emit-llvm -o %t %s
+
+@interface I {
+  __attribute__((objc_gc(strong))) signed long *_documentIDs;
+  __attribute__((objc_gc(strong))) id *IdocumentIDs;
+}
+- (void) _getResultsOfMatches;
+@end
+
+@implementation I
+-(void) _getResultsOfMatches {
+    _documentIDs[2] = _documentIDs[3];
+    IdocumentIDs[2] = IdocumentIDs[3];
+}
+
+@end
+
diff --git a/test/CodeGenObjC/objc2-weak-assign.m b/test/CodeGenObjC/objc2-weak-assign.m
new file mode 100644
index 0000000..42fa773
--- /dev/null
+++ b/test/CodeGenObjC/objc2-weak-assign.m
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -fobjc-gc -emit-llvm -o %t %s
+// RUN: grep -e "objc_assign_weak" %t | grep -e "call" | count 6
+
+__weak id* x;
+id* __weak y;
+id* __weak* z;
+
+__weak id* a1[20];
+id* __weak a2[30];
+id** __weak a3[40];
+
+void foo (__weak id *param) {
+ *param = 0;
+}
+
+int main()
+{
+	*x = 0;
+	*y = 0;
+        **z = 0;
+
+        a1[3] = 0;
+        a2[3] = 0;
+        a3[3][4] = 0;
+}
+
diff --git a/test/CodeGenObjC/objc2-weak-block-call.m b/test/CodeGenObjC/objc2-weak-block-call.m
new file mode 100644
index 0000000..a3514b0
--- /dev/null
+++ b/test/CodeGenObjC/objc2-weak-block-call.m
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -fblocks -fobjc-gc -triple x86_64-apple-darwin -S %s -o %t-64.s
+// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s
+// RUN: %clang_cc1 -fblocks -fobjc-gc -triple i386-apple-darwin -S %s -o %t-32.s
+// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s
+
+@interface MyView
+- (void)MyView_sharedInit;
+@end
+
+void foo(MyView *(^obj)(void)) ;
+
+@implementation MyView
+- (void)MyView_sharedInit {
+    
+    __block __weak MyView *weakSelf = self;
+    foo(
+    ^{
+	return weakSelf;
+    });
+
+}
+@end
+
+// CHECK-LP64: callq    _objc_read_weak
+// CHECK-LP64: callq    _objc_read_weak
+
+// CHECK-LP32: call     L_objc_read_weak
+// CHECK-LP32: call     L_objc_read_weak
+
diff --git a/test/CodeGenObjC/objc2-weak-compare.m b/test/CodeGenObjC/objc2-weak-compare.m
new file mode 100644
index 0000000..cb8ca5f
--- /dev/null
+++ b/test/CodeGenObjC/objc2-weak-compare.m
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -fobjc-gc -emit-llvm -o %t %s
+
+@interface PBXTarget 
+{
+
+PBXTarget * __weak _lastKnownTarget;
+PBXTarget * __weak _KnownTarget;
+PBXTarget * result;
+}
+- Meth;
+@end
+
+@implementation PBXTarget
+- Meth {
+	if (_lastKnownTarget != result)
+	 foo();
+	if (result != _lastKnownTarget)
+	 foo();
+
+ 	if (_lastKnownTarget != _KnownTarget)
+	  foo();
+}
+
+@end
diff --git a/test/CodeGenObjC/objc2-weak-import-attribute.m b/test/CodeGenObjC/objc2-weak-import-attribute.m
new file mode 100644
index 0000000..946c79b
--- /dev/null
+++ b/test/CodeGenObjC/objc2-weak-import-attribute.m
@@ -0,0 +1,48 @@
+// RUN: %clang_cc1 -fobjc-nonfragile-abi -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-X86-64 %s
+
+__attribute__((weak_import)) @interface WeakRootClass @end
+
+__attribute__((weak_import)) @interface WeakClass : WeakRootClass
+@end
+
+@interface MySubclass : WeakClass @end
+
+@implementation MySubclass @end
+
+@implementation WeakClass(MyCategory) @end
+
+
+__attribute__((weak_import))
+@interface WeakClass1 @end
+
+@implementation WeakClass1(MyCategory) @end
+
+@implementation WeakClass1(YourCategory) @end
+
+ __attribute__((weak_import))
+@interface WeakClass3 
++ message;
+@end
+
+int main() {
+     [WeakClass3 message];
+}
+
+// CHECK-X86-64: OBJC_METACLASS_$_WeakRootClass" = extern_weak global
+// CHECK-X86-64: OBJC_METACLASS_$_WeakClass" = extern_weak global
+// CHECK-X86-64: OBJC_CLASS_$_WeakClass" = extern_weak global
+// CHECK-X86-64: OBJC_CLASS_$_WeakClass1" = extern_weak global
+// CHECK-X86-64: OBJC_CLASS_$_WeakClass3" = extern_weak global
+
+// Root is being implemented here. No extern_weak.
+__attribute__((weak_import)) @interface Root @end
+
+@interface Super : Root @end
+
+@interface Sub : Super @end
+
+@implementation Sub @end
+
+@implementation Root @end
+
+// CHECK-NOT-X86-64: OBJC_METACLASS_$_Root" = extern_weak global
diff --git a/test/CodeGenObjC/objc2-weak-ivar-debug.m b/test/CodeGenObjC/objc2-weak-ivar-debug.m
new file mode 100644
index 0000000..a6fb7fa
--- /dev/null
+++ b/test/CodeGenObjC/objc2-weak-ivar-debug.m
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -fobjc-gc -g -emit-llvm -o - %s
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -fobjc-gc -g -emit-llvm -o - %s
+
+// rdar://7252252
+@interface Loop {
+@public
+  __weak Loop *_loop;
+}
+@end
+
+@implementation Loop @end
+
+void loop(Loop *L) {
+  L->_loop = 0;
+}
diff --git a/test/CodeGenObjC/objc2-weak-ivar.m b/test/CodeGenObjC/objc2-weak-ivar.m
new file mode 100644
index 0000000..cfe1e95
--- /dev/null
+++ b/test/CodeGenObjC/objc2-weak-ivar.m
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -fobjc-gc -emit-llvm -o %t %s
+@class NSObject;
+
+@interface Foo  {
+@public
+  __weak NSObject *nsobject;
+}
+@end
+
+@implementation Foo @end
diff --git a/test/CodeGenObjC/objc2-write-barrier-2.m b/test/CodeGenObjC/objc2-write-barrier-2.m
new file mode 100644
index 0000000..9a76c6e
--- /dev/null
+++ b/test/CodeGenObjC/objc2-write-barrier-2.m
@@ -0,0 +1,79 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-gc -emit-llvm -o %t %s
+// RUN: grep -F '@objc_assign_global' %t  | count 7
+// RUN: grep -F '@objc_assign_ivar' %t  | count 5
+// RUN: grep -F '@objc_assign_strongCast' %t  | count 8
+
+extern id **somefunc(void);
+extern id *somefunc2(void);
+
+
+// Globals
+
+id W, *X, **Y;
+
+void func(id a, id *b, id **c) {
+   static id w, *x, **y;
+   W = a;  
+   w = a;
+   X = b;
+   x = b; 
+   Y = c;
+   y = c; 
+}
+
+// Instances
+
+@interface something {
+    id w, *x, **y;
+}
+@end
+
+@implementation something
+- (void)amethod {
+    id badIdea = *somefunc2();
+    w = badIdea;
+    x = &badIdea;
+    y = &x;
+}
+@end
+
+typedef struct {
+    int junk;
+    id  alfred;
+} AStruct;
+
+void funct2(AStruct *aptr) {
+    id **ppptr = somefunc();
+    aptr->alfred = 0;
+    **ppptr = aptr->alfred;
+    *ppptr = somefunc2(); 
+}
+
+typedef const struct __CFString * CFStringRef;
+@interface DSATextSearch {
+__strong CFStringRef *_documentNames;
+  struct {
+    id *innerNames;
+    struct {
+      id *nestedDeeperNames; 
+      struct I {
+         id *is1;
+         id is2[5];
+      } arrI [3];
+    } inner_most;
+  } inner;
+
+}
+- filter;
+@end
+@implementation DSATextSearch
+- filter {
+  int filteredPos = 0;
+  _documentNames[filteredPos] = 0; // storing into an element of array ivar. objc_assign_strongCast is needed.
+  inner.innerNames[filteredPos] = 0;
+  inner.inner_most.nestedDeeperNames[filteredPos] = 0;
+  inner.inner_most.arrI[3].is1[5] = 0;
+  inner.inner_most.arrI[3].is2[5] = 0;
+}
+@end
+
diff --git a/test/CodeGenObjC/objc2-write-barrier-3.m b/test/CodeGenObjC/objc2-write-barrier-3.m
new file mode 100644
index 0000000..626083b
--- /dev/null
+++ b/test/CodeGenObjC/objc2-write-barrier-3.m
@@ -0,0 +1,46 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fblocks -fobjc-gc -emit-llvm -o %t %s
+// RUN: grep objc_assign_ivar %t | count 3
+// RUN: grep objc_assign_strongCast %t | count 6
+
+struct Slice {
+    void *__strong * items;
+};
+
+typedef struct Slice Slice;
+
+@interface ISlice {
+@public
+    void *__strong * IvarItem;
+}
+@end
+
+typedef void (^observer_block_t)(id object);
+@interface Observer  {
+@public
+    observer_block_t block;
+}
+@end
+
+
+void foo (int i) {
+    // storing into an array of strong pointer types.
+    void *__strong* items;
+    items[i] = 0;
+
+    // storing indirectly into an array of strong pointer types.
+    void *__strong* *vitems;
+    *vitems[i] = 0;
+
+    Slice *slice;
+    slice->items = 0;
+    // storing into a struct element of an array of strong pointer types.
+    slice->items[i] = 0;
+
+    ISlice *islice;
+    islice->IvarItem = 0;
+    // Storing into an ivar of an array of strong pointer types.
+    islice->IvarItem[i] = (void*)0;
+
+    Observer *observer;
+    observer->block = 0;
+}
diff --git a/test/CodeGenObjC/objc2-write-barrier-4.m b/test/CodeGenObjC/objc2-write-barrier-4.m
new file mode 100644
index 0000000..11b4ab4
--- /dev/null
+++ b/test/CodeGenObjC/objc2-write-barrier-4.m
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-gc -emit-llvm -o %t %s
+// RUN: grep objc_assign_global %t | count 3
+// RUN: grep objc_assign_strongCast %t | count 2
+
+@interface A
+@end
+
+typedef struct s0 {
+  A *a[4];
+} T;
+
+T g0;
+
+void f0(id x) {
+  g0.a[0] = x;
+}
+
+void f1(id x) {
+  ((T*) &g0)->a[0] = x;
+}
+
+void f2(unsigned idx)
+{
+   id *keys;
+   keys[idx] = 0;
+}
+
diff --git a/test/CodeGenObjC/objc2-write-barrier-5.m b/test/CodeGenObjC/objc2-write-barrier-5.m
new file mode 100644
index 0000000..babe26d
--- /dev/null
+++ b/test/CodeGenObjC/objc2-write-barrier-5.m
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-gc -emit-llvm -o %t %s
+// RUN: grep objc_assign_ivar %t | count 0
+// RUN: grep objc_assign_strongCast %t | count 5
+
+@interface TestUnarchiver 
+{
+	void  *allUnarchivedObjects;
+}
+@end
+
+@implementation TestUnarchiver
+
+struct unarchive_list {
+    int ifield;
+    id *list;
+};
+
+- (id)init {
+    (*((struct unarchive_list *)allUnarchivedObjects)).list = 0;
+    ((struct unarchive_list *)allUnarchivedObjects)->list = 0;
+    (**((struct unarchive_list **)allUnarchivedObjects)).list = 0;
+    (*((struct unarchive_list **)allUnarchivedObjects))->list = 0;
+    return 0;
+}
+
+@end
diff --git a/test/CodeGenObjC/objc2-write-barrier.m b/test/CodeGenObjC/objc2-write-barrier.m
new file mode 100644
index 0000000..0934e0a
--- /dev/null
+++ b/test/CodeGenObjC/objc2-write-barrier.m
@@ -0,0 +1,113 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-gc -emit-llvm -o %t %s
+// RUN: grep -F '@objc_assign_global' %t  | count 21
+// RUN: grep -F '@objc_assign_ivar' %t  | count 11
+
+
+typedef const struct __CFDictionary * CFDictionaryRef;
+
+// callouts to these are generated with cc -fobjc-gc
+
+int GlobalAssigns;
+int IvarAssigns;
+int StrongCastAssigns;
+
+
+// The test case elements;
+@class NSObject;
+@class NSString;
+
+typedef struct {
+  id  element;
+  id elementArray[10];
+  __strong CFDictionaryRef cfElement;
+  __strong CFDictionaryRef cfElementArray[10];
+} struct_with_ids_t;
+
+@interface Foo  {
+@public
+// assignments to any/all of these fields should generate objc_assign_ivar
+  __strong CFDictionaryRef dict;
+  __strong CFDictionaryRef dictArray[3];
+  id ivar;
+  id array[10];
+  NSObject *nsobject;
+  NSString *stringArray[10];
+  struct_with_ids_t inner;
+}
+
+@end
+
+// assignments to these should generate objc_assign_global
+id GlobalId;
+id GlobalArray[20];
+NSObject *GlobalObject;
+NSObject *GlobalObjectArray[20];
+__strong CFDictionaryRef Gdict;
+__strong CFDictionaryRef Gdictarray[10];
+struct_with_ids_t GlobalStruct;
+struct_with_ids_t GlobalStructArray[10];
+
+
+// The test cases
+void *rhs = 0;
+
+#define ASSIGNTEST(expr, global) expr = rhs
+
+int testGlobals() {
+  // Everything in this function generates assign_global intercepts
+  int counter = 0;
+
+  static id staticGlobalId;
+  static id staticGlobalArray[20];
+  static NSObject *staticGlobalObject;
+  static NSObject *staticGlobalObjectArray[20];
+  static __strong CFDictionaryRef staticGdict;
+  static __strong CFDictionaryRef staticGdictarray[10];
+  static struct_with_ids_t staticGlobalStruct;
+  static struct_with_ids_t staticGlobalStructArray[10];
+
+  ASSIGNTEST(GlobalId, GlobalAssigns);				// objc_assign_global
+  ASSIGNTEST(GlobalArray[0], GlobalAssigns);			// objc_assign_global
+  ASSIGNTEST(GlobalObject, GlobalAssigns);			// objc_assign_global
+  ASSIGNTEST(GlobalObjectArray[0], GlobalAssigns);		// objc_assign_global
+  ASSIGNTEST(Gdict, GlobalAssigns);				// objc_assign_global
+  ASSIGNTEST(Gdictarray[1], GlobalAssigns);			// objc_assign_global
+
+  ASSIGNTEST(GlobalStruct.element, GlobalAssigns);		// objc_assign_global
+  ASSIGNTEST(GlobalStruct.elementArray[0], GlobalAssigns);	// objc_assign_global
+  ASSIGNTEST(GlobalStruct.cfElement, GlobalAssigns);		// objc_assign_global
+  ASSIGNTEST(GlobalStruct.cfElementArray[0], GlobalAssigns);	// objc_assign_global
+
+  ASSIGNTEST(staticGlobalId, GlobalAssigns);			// objc_assign_global
+  ASSIGNTEST(staticGlobalArray[0], GlobalAssigns);		// objc_assign_global
+  ASSIGNTEST(staticGlobalObject, GlobalAssigns);		// objc_assign_global
+  ASSIGNTEST(staticGlobalObjectArray[0], GlobalAssigns);	// objc_assign_global
+  ASSIGNTEST(staticGdict, GlobalAssigns);			// objc_assign_global
+  ASSIGNTEST(staticGdictarray[1], GlobalAssigns);		// objc_assign_global
+
+  ASSIGNTEST(staticGlobalStruct.element, GlobalAssigns);		// objc_assign_global
+  ASSIGNTEST(staticGlobalStruct.elementArray[0], GlobalAssigns);	// objc_assign_global
+  ASSIGNTEST(staticGlobalStruct.cfElement, GlobalAssigns);		// objc_assign_global
+  ASSIGNTEST(staticGlobalStruct.cfElementArray[0], GlobalAssigns);	// objc_assign_global
+
+  return counter;
+}
+
+
+int testIvars() {
+  Foo *foo;
+  int counter = 0;
+
+  ASSIGNTEST(foo->ivar, IvarAssigns);					// objc_assign_ivar
+  ASSIGNTEST(foo->dict, IvarAssigns);					// objc_assign_ivar
+  ASSIGNTEST(foo->dictArray[0], IvarAssigns);				// objc_assign_ivar
+  ASSIGNTEST(foo->array[0], IvarAssigns);				// objc_assign_ivar
+  ASSIGNTEST(foo->nsobject, IvarAssigns);				// objc_assign_ivar
+  ASSIGNTEST(foo->stringArray[0], IvarAssigns);				// objc_assign_ivar
+  ASSIGNTEST(foo->inner.element, IvarAssigns);				// objc_assign_ivar
+  ASSIGNTEST(foo->inner.elementArray[0], IvarAssigns);			// objc_assign_ivar
+  ASSIGNTEST(foo->inner.cfElement, IvarAssigns);			// objc_assign_ivar
+  ASSIGNTEST(foo->inner.cfElementArray[0], IvarAssigns);		// objc_assign_ivar
+
+  return counter;
+}
diff --git a/test/CodeGenObjC/object-incr-decr-1.m b/test/CodeGenObjC/object-incr-decr-1.m
new file mode 100644
index 0000000..6369076
--- /dev/null
+++ b/test/CodeGenObjC/object-incr-decr-1.m
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -emit-llvm %s -o %t
+
+@interface Foo 
+{
+	double d1,d3,d4;
+}
+@end
+
+Foo* foo()
+{
+  Foo *f;
+  
+  // Both of these crash clang nicely
+  ++f;
+  --f;
+ f--;
+ f++;
+ return f;
+}
diff --git a/test/CodeGenObjC/overloadable.m b/test/CodeGenObjC/overloadable.m
new file mode 100644
index 0000000..4fd1429
--- /dev/null
+++ b/test/CodeGenObjC/overloadable.m
@@ -0,0 +1,10 @@
+// rdar://6657613
+// RUN: %clang_cc1 -emit-llvm %s -o %t
+
+@class C;
+
+// RUN: grep _Z1fP11objc_object %t | count 1
+void __attribute__((overloadable)) f(id c) { }
+
+// RUN: grep _Z1fP1C %t | count 1
+void __attribute__((overloadable)) f(C *c) { }
diff --git a/test/CodeGenObjC/predefined-expr.m b/test/CodeGenObjC/predefined-expr.m
new file mode 100644
index 0000000..772093b
--- /dev/null
+++ b/test/CodeGenObjC/predefined-expr.m
@@ -0,0 +1,90 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin9 %s -emit-llvm -o - | FileCheck %s
+
+// CHECK: @"__func__.-[Foo instanceTest1]" = private constant [21 x i8] c"-[Foo instanceTest1]\00"
+// CHECK: @"__func__.-[Foo instanceTest2:]" = private constant [22 x i8] c"-[Foo instanceTest2:]\00"
+// CHECK: @"__func__.-[Foo instanceTest3:withB:]" = private constant [28 x i8] c"-[Foo instanceTest3:withB:]\00"
+// CHECK: @"__func__.-[Foo instanceTest4]" = private constant [21 x i8] c"-[Foo instanceTest4]\00"
+// CHECK: @"__func__.+[Foo classTest1]" = private constant [18 x i8] c"+[Foo classTest1]\00"
+// CHECK: @"__func__.+[Foo classTest2:]" = private constant [19 x i8] c"+[Foo classTest2:]\00"
+// CHECK: @"__func__.+[Foo classTest3:withB:]" = private constant [25 x i8] c"+[Foo classTest3:withB:]\00"
+// CHECK: @"__func__.+[Foo classTest4]" = private constant [18 x i8] c"+[Foo classTest4]\00"
+// CHECK: @"__func__.-[Foo(Category) instanceTestWithCategory]" = private constant [42 x i8] c"-[Foo(Category) instanceTestWithCategory]\00"
+// CHECK: @"__func__.+[Foo(Category) classTestWithCategory]" = private constant [39 x i8] c"+[Foo(Category) classTestWithCategory]\00"
+
+int printf(const char * _Format, ...);
+
+@interface Foo
+@end
+
+@implementation Foo
+
+- (void)instanceTest1 {
+  printf("__func__: %s\n", __func__);
+  printf("__FUNCTION__: %s\n", __FUNCTION__);
+  printf("__PRETTY_FUNCTION__: %s\n\n", __PRETTY_FUNCTION__);
+}
+
+- (void)instanceTest2:(int)i {
+  printf("__func__: %s\n", __func__);
+  printf("__FUNCTION__: %s\n", __FUNCTION__);
+  printf("__PRETTY_FUNCTION__: %s\n\n", __PRETTY_FUNCTION__);
+}
+
+- (void)instanceTest3:(int)a withB:(double)b {
+  printf("__func__: %s\n", __func__);
+  printf("__FUNCTION__: %s\n", __FUNCTION__);
+  printf("__PRETTY_FUNCTION__: %s\n\n", __PRETTY_FUNCTION__);
+}
+
+- (int)instanceTest4 {
+  printf("__func__: %s\n", __func__);
+  printf("__FUNCTION__: %s\n", __FUNCTION__);
+  printf("__PRETTY_FUNCTION__: %s\n\n", __PRETTY_FUNCTION__);
+  return 0;
+}
+
++ (void)classTest1 {
+  printf("__func__: %s\n", __func__);
+  printf("__FUNCTION__: %s\n", __FUNCTION__);
+  printf("__PRETTY_FUNCTION__: %s\n\n", __PRETTY_FUNCTION__);
+}
+
++ (void)classTest2:(int)i {
+  printf("__func__: %s\n", __func__);
+  printf("__FUNCTION__: %s\n", __FUNCTION__);
+  printf("__PRETTY_FUNCTION__: %s\n\n", __PRETTY_FUNCTION__);
+}
+
++ (void)classTest3:(int)a withB:(double)b {
+  printf("__func__: %s\n", __func__);
+  printf("__FUNCTION__: %s\n", __FUNCTION__);
+  printf("__PRETTY_FUNCTION__: %s\n\n", __PRETTY_FUNCTION__);
+}
+
++ (int)classTest4 {
+  printf("__func__: %s\n", __func__);
+  printf("__FUNCTION__: %s\n", __FUNCTION__);
+  printf("__PRETTY_FUNCTION__: %s\n\n", __PRETTY_FUNCTION__);
+  return 0;
+}
+
+@end
+
+@interface Foo (Category)
+@end
+
+@implementation Foo (Category)
+
+- (void)instanceTestWithCategory {
+  printf("__func__: %s\n", __func__);
+  printf("__FUNCTION__: %s\n", __FUNCTION__);
+  printf("__PRETTY_FUNCTION__: %s\n\n", __PRETTY_FUNCTION__);
+}
+
++ (void)classTestWithCategory {
+  printf("__func__: %s\n", __func__);
+  printf("__FUNCTION__: %s\n", __FUNCTION__);
+  printf("__PRETTY_FUNCTION__: %s\n\n", __PRETTY_FUNCTION__);
+}
+
+@end
diff --git a/test/CodeGenObjC/property-aggr-type.m b/test/CodeGenObjC/property-aggr-type.m
new file mode 100644
index 0000000..8ba87de
--- /dev/null
+++ b/test/CodeGenObjC/property-aggr-type.m
@@ -0,0 +1,50 @@
+// RUN: %clang_cc1 -emit-llvm -o %t %s
+
+@interface Object
+- (id) new;
+@end
+
+typedef struct {int x, y, w, h;} st1;
+typedef struct {int x, y, w, h;} st2;
+
+@interface bar : Object
+- (void)setFrame:(st1)frameRect;
+@end
+
+@interface bar1 : Object
+- (void)setFrame:(int)frameRect;
+@end
+
+@interface foo : Object
+{
+	st2 ivar;
+}
+@property (assign) st2 frame;
+@end
+
+@implementation foo
+@synthesize frame = ivar;
+@end
+
+extern void abort();
+
+static   st2 r = {1,2,3,4};
+st2 test (void)
+{
+    foo *obj = [foo new];
+    id objid = [foo new];;
+
+    obj.frame = r;
+
+    ((foo*)objid).frame = obj.frame;
+
+    return ((foo*)objid).frame;
+}
+
+int main ()
+{
+  st2 res = test ();
+  if (res.x != 1 || res.h != 4)
+    abort();
+  return 0;
+}
diff --git a/test/CodeGenObjC/property-agrr-getter.m b/test/CodeGenObjC/property-agrr-getter.m
new file mode 100644
index 0000000..2dd32bb
--- /dev/null
+++ b/test/CodeGenObjC/property-agrr-getter.m
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -emit-llvm -o %t %s
+
+typedef struct {
+  unsigned f0;
+} s0;
+
+@interface A
+- (s0) f0;
+@end
+
+@implementation A
+-(s0) f0{ while (1) {} }
+- (unsigned) bar {
+  return self.f0.f0;
+}
+@end
+
+
+typedef struct _NSSize {
+    float width;
+    float height;
+} NSSize;
+
+
+@interface AnObject
+{
+ NSSize size;
+}
+
+@property NSSize size;
+
+@end
+
+float f ()
+{
+  AnObject* obj;
+  return (obj.size).width;
+}
diff --git a/test/CodeGenObjC/property-complex.m b/test/CodeGenObjC/property-complex.m
new file mode 100644
index 0000000..59200eb
--- /dev/null
+++ b/test/CodeGenObjC/property-complex.m
@@ -0,0 +1,61 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -emit-llvm -S -o - %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -emit-llvm -S -o - %s
+
+@interface I0 {
+@public
+  _Complex float iv0;
+}
+
+@property(assign) _Complex float p0;
+
+-(_Complex float) im0;
+-(void) setIm0: (_Complex float) a0;
+@end
+
+@implementation I0 
+@dynamic p0;
+
+-(id) init {
+  self->iv0 = 5.0 + 2.0i;
+  return self;
+}
+
+-(_Complex float) im0 {
+  printf("im0: %.2f + %.2fi\n", __real iv0, __imag iv0);
+  return iv0 + (.1 + .2i);
+}
+-(void) setIm0: (_Complex float) a0 {
+  printf("setIm0: %.2f + %.2fi\n", __real a0, __imag a0);
+  iv0 = a0 + (.3 + .4i);
+}
+
+-(_Complex float) p0 {
+  printf("p0: %.2f + %.2fi\n", __real iv0, __imag iv0);
+  return iv0 + (.5 + .6i);
+}
+-(void) setP0: (_Complex float) a0 {
+  printf("setP0: %.2f + %.2fi\n", __real a0, __imag a0);
+  iv0 = a0 + (.7 + .8i);
+}
+@end
+
+void f0(I0 *a0) {
+    float l0 = __real a0.im0;
+    float l1 = __imag a0->iv0;
+    _Complex float l2 = (a0.im0 = a0.im0);
+    _Complex float l3 = a0->iv0;
+    _Complex float l4 = (a0->iv0 = a0->iv0);
+    _Complex float l5 = a0->iv0;
+    _Complex float l6 = (a0.p0 = a0.p0);
+    _Complex float l7 = a0->iv0;
+    _Complex float l8 = [a0 im0];
+    printf("l0: %.2f + %.2fi\n", __real l0, __imag l0);
+    printf("l1: %.2f + %.2fi\n", __real l1, __imag l1);
+    printf("l2: %.2f + %.2fi\n", __real l2, __imag l2);
+    printf("l3: %.2f + %.2fi\n", __real l3, __imag l3);
+    printf("l4: %.2f + %.2fi\n", __real l4, __imag l4);
+    printf("l5: %.2f + %.2fi\n", __real l5, __imag l5);
+    printf("l6: %.2f + %.2fi\n", __real l6, __imag l6);
+    printf("l7: %.2f + %.2fi\n", __real l7, __imag l7);
+    printf("l8: %.2f + %.2fi\n", __real l8, __imag l8);
+}
diff --git a/test/CodeGenObjC/property-dbg.m b/test/CodeGenObjC/property-dbg.m
new file mode 100644
index 0000000..5bbb046
--- /dev/null
+++ b/test/CodeGenObjC/property-dbg.m
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -S -g -masm-verbose -x objective-c < %s | grep setI | grep DW_AT_name
+@interface Foo {
+  int i;
+}
+@property int i;
+@end
+
+@implementation Foo
+@synthesize i;
+@end
+
+int bar(Foo *f) {
+  int i = 1;
+  f.i = 2;
+  i = f.i;
+  return i;
+}
diff --git a/test/CodeGenObjC/property-getter-dot-syntax.m b/test/CodeGenObjC/property-getter-dot-syntax.m
new file mode 100644
index 0000000..f22b051
--- /dev/null
+++ b/test/CodeGenObjC/property-getter-dot-syntax.m
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -emit-llvm -o %t %s
+
+@protocol NSObject
+- (void *)description;
+@end
+
+int main()
+{
+        id<NSObject> eggs;
+        void *eggsText= eggs.description;
+}
diff --git a/test/CodeGenObjC/property-incr-decr-1.m b/test/CodeGenObjC/property-incr-decr-1.m
new file mode 100644
index 0000000..d75c02e
--- /dev/null
+++ b/test/CodeGenObjC/property-incr-decr-1.m
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -emit-llvm -o %t %s
+
+@interface Object
+- (id) new;
+@end
+
+@interface SomeClass : Object
+{
+  int _myValue;
+}
+@property int myValue;
+@end
+
+@implementation SomeClass
+@synthesize myValue=_myValue;
+@end
+
+int main()
+{
+    int val;
+    SomeClass *o = [SomeClass new];
+    o.myValue = -1;
+    val = o.myValue++; /* val -1, o.myValue 0 */
+    val += o.myValue--; /* val -1. o.myValue -1 */
+    val += ++o.myValue; /* val -1, o.myValue 0 */
+    val += --o.myValue; /* val -2, o.myValue -1 */
+    return ++o.myValue + (val+2);
+}
+
diff --git a/test/CodeGenObjC/property-list-in-class.m b/test/CodeGenObjC/property-list-in-class.m
new file mode 100644
index 0000000..a5d0dc8
--- /dev/null
+++ b/test/CodeGenObjC/property-list-in-class.m
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -emit-llvm -o %t %s 
+// RUN: grep -F 'l_OBJC_$_PROP_LIST_C2" = internal global %8 { i32 16, i32 3' %t
+
+@protocol P 
+@property int i;
+@end
+
+@protocol P1 
+@property int i1;
+@end
+
+@protocol P2 < P1> 
+@property int i2;
+@end
+
+@interface C1 { id isa; } @end
+
+@interface C2 : C1 <P, P2> {
+    int i;
+}
+@property int i2;
+@end
+
+@implementation C1
++(void)initialize { }
+@end
+
+@implementation C2
+@synthesize i;
+@synthesize i1;
+@synthesize i2;
+@end
diff --git a/test/CodeGenObjC/property-setter-attr.m b/test/CodeGenObjC/property-setter-attr.m
new file mode 100644
index 0000000..d155ca8
--- /dev/null
+++ b/test/CodeGenObjC/property-setter-attr.m
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -emit-llvm -triple=i686-apple-darwin8 -o %t %s
+// RUN: grep -e "SiSetOtherThings:" %t
+
+@interface A 
+@property(setter=iSetOtherThings:) int otherThings;
+@end
+
+@implementation A
+@dynamic otherThings;
+@end
diff --git a/test/CodeGenObjC/property.m b/test/CodeGenObjC/property.m
new file mode 100644
index 0000000..7160b16
--- /dev/null
+++ b/test/CodeGenObjC/property.m
@@ -0,0 +1,52 @@
+// RUN: %clang_cc1 -emit-llvm -o %t %s
+
+int printf(const char *, ...);
+
+@interface Root
+-(id) alloc;
+-(id) init;
+@end
+
+@interface A : Root {
+  int x;
+  int y, ro, z;
+  id ob0, ob1, ob2, ob3, ob4;
+}
+@property int x;
+@property int y;
+@property int z;
+@property(readonly) int ro;
+@property(assign) id ob0;
+@property(retain) id ob1;
+@property(copy) id ob2;
+@property(retain, nonatomic) id ob3;
+@property(copy, nonatomic) id ob4;
+@end
+
+@implementation A
+@dynamic x;
+@synthesize y;
+@synthesize z = z;
+@synthesize ro;
+@synthesize ob0;
+@synthesize ob1;
+@synthesize ob2;
+@synthesize ob3;
+@synthesize ob4;
+-(int) y {
+  return x + 1;
+}
+-(void) setZ: (int) arg {
+  x = arg - 1;
+}
+@end
+
+@interface A (Cat)
+@property int dyn;
+@end
+
+@implementation A (Cat)
+-(int) dyn {
+  return 10;
+}
+@end
diff --git a/test/CodeGenObjC/protocol-in-extended-class.m b/test/CodeGenObjC/protocol-in-extended-class.m
new file mode 100644
index 0000000..d2955b1
--- /dev/null
+++ b/test/CodeGenObjC/protocol-in-extended-class.m
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -S %s -o %t-64.s
+// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s
+// RUN: %clang_cc1 -triple i386-apple-darwin -S %s -o %t-32.s
+// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s
+
+@protocol MyProtocol
+@end
+
+@protocol ExtendedProtocol
+@end
+
+@interface ItDoesntWork<MyProtocol> {
+}
+-(void) Meth;
+@end
+
+@interface ItDoesntWork() <MyProtocol, ExtendedProtocol>
+@end
+
+@implementation ItDoesntWork
+-(void) Meth {
+    ItDoesntWork <MyProtocol, ExtendedProtocol> *p = 0;
+ }
+@end
+
+// CHECK-LP64: l_OBJC_PROTOCOL_$_ExtendedProtocol:
+
+// CHECK-LP32: L_OBJC_PROTOCOL_ExtendedProtocol:
diff --git a/test/CodeGenObjC/protocol-property-synth.m b/test/CodeGenObjC/protocol-property-synth.m
new file mode 100644
index 0000000..8566949
--- /dev/null
+++ b/test/CodeGenObjC/protocol-property-synth.m
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -fobjc-nonfragile-abi -emit-llvm -o %t %s
+
+@interface BaseClass {
+    id _delegate;
+}
+@end
+
+@protocol MyProtocol
+@optional
+@property(assign) id delegate;
+@end
+
+@protocol AnotherProtocol
+@optional
+@property(assign) id myanother;
+@end
+
+@protocol SubProtocol <MyProtocol>
+@property(assign) id another;
+@end
+
+@interface SubClass : BaseClass <SubProtocol, AnotherProtocol> {
+}
+
+@end
+
+@implementation BaseClass @end 
+
+@implementation SubClass
+@synthesize delegate = _Subdelegate;
+@synthesize another;
+@synthesize myanother;
+@end
diff --git a/test/CodeGenObjC/protocols-lazy.m b/test/CodeGenObjC/protocols-lazy.m
new file mode 100644
index 0000000..2038e60
--- /dev/null
+++ b/test/CodeGenObjC/protocols-lazy.m
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -emit-llvm -triple=i686-apple-darwin8 -o %t %s
+// RUNX: llvm-gcc -S -emit-llvm -o %t %s &&
+
+// No object generated
+// RUN: grep OBJC_PROTOCOL_P0 %t | count 0
+@protocol P0;
+
+// No object generated
+// RUN: grep OBJC_PROTOCOL_P1 %t | count 0
+@protocol P1 -im1; @end
+
+// Definition triggered by protocol reference.
+// RUN: grep OBJC_PROTOCOL_P2 %t | count 3
+// RUN: grep OBJC_PROTOCOL_INSTANCE_METHODS_P2 %t | count 3
+@protocol P2 -im1; @end
+void f0() { id x = @protocol(P2); }
+
+// Forward definition triggered by protocol reference.
+// RUN: grep OBJC_PROTOCOL_P3 %t | count 3
+// RUN: grep OBJC_PROTOCOL_INSTANCE_METHODS_P3 %t | count 0
+@protocol P3;
+void f1() { id x = @protocol(P3); }
+
+// Definition triggered by class reference.
+// RUN: grep OBJC_PROTOCOL_P4 %t | count 3
+// RUN: grep OBJC_PROTOCOL_INSTANCE_METHODS_P4 %t | count 3
+@protocol P4 -im1; @end
+@interface I0<P4> @end
+@implementation I0 -im1 { return 0; }; @end
+
+// Definition following forward reference.
+// RUN: grep OBJC_PROTOCOL_P5 %t | count 3
+// RUN: grep OBJC_PROTOCOL_INSTANCE_METHODS_P5 %t | count 3
+@protocol P5;
+void f2() { id x = @protocol(P5); } // This generates a forward
+                                    // reference, which has to be
+                                    // updated on the next line.
+@protocol P5 -im1; @end               
+
+// Protocol reference following definition.
+// RUN: grep OBJC_PROTOCOL_P6 %t | count 4
+// RUN: grep OBJC_PROTOCOL_INSTANCE_METHODS_P6 %t | count 3
+@protocol P6 -im1; @end
+@interface I1<P6> @end
+@implementation I1 -im1 { return 0; }; @end
+void f3() { id x = @protocol(P6); }
+
diff --git a/test/CodeGenObjC/protocols.m b/test/CodeGenObjC/protocols.m
new file mode 100644
index 0000000..0f24a1c
--- /dev/null
+++ b/test/CodeGenObjC/protocols.m
@@ -0,0 +1,50 @@
+// RUN: %clang_cc1 -emit-llvm %s -o %t
+
+void p(const char*, ...);
+
+@interface Root
+-(int) conformsTo: (id) x;
+@end
+
+@protocol P0;
+
+@protocol P1
++(void) classMethodReq0;
+-(void) methodReq0;
+@optional
++(void) classMethodOpt1;
+-(void) methodOpt1;
+@required
++(void) classMethodReq2;
+-(void) methodReq2;
+@end
+
+@protocol P2
+//@property(readwrite) int x;
+@end
+
+@protocol P3<P1, P2>
+-(id <P1>) print0;
+-(void) print1;
+@end
+
+void foo(const id a) {
+  void *p = @protocol(P3);
+}
+
+int main() {
+  Protocol *P0 = @protocol(P0);
+  Protocol *P1 = @protocol(P1);
+  Protocol *P2 = @protocol(P2);
+  Protocol *P3 = @protocol(P3);
+
+#define Pbool(X) p(#X ": %s\n", X ? "yes" : "no");
+  Pbool([P0 conformsTo: P1]);
+  Pbool([P1 conformsTo: P0]);
+  Pbool([P1 conformsTo: P2]);
+  Pbool([P2 conformsTo: P1]);
+  Pbool([P3 conformsTo: P1]);
+  Pbool([P1 conformsTo: P3]);
+
+  return 0;
+}
diff --git a/test/CodeGenObjC/runtime-fns.m b/test/CodeGenObjC/runtime-fns.m
new file mode 100644
index 0000000..203d87f
--- /dev/null
+++ b/test/CodeGenObjC/runtime-fns.m
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -emit-llvm -o %t %s
+// RUN: grep -e "^de.*objc_msgSend[0-9]*(" %t | count 1
+// RUN: %clang_cc1 -DWITHDEF -emit-llvm -o %t %s
+// RUN: grep -e "^de.*objc_msgSend[0-9]*(" %t | count 1
+
+id objc_msgSend(int x);
+
+@interface A @end
+
+@implementation A
+-(void) f0 {
+  objc_msgSend(12);
+}
+
+-(void) hello {
+}
+@end
+
+void f0(id x) {
+  [x hello];
+}
+
+#ifdef WITHDEF
+// This isn't a very good send function.
+id objc_msgSend(int x) {
+  return 0;
+}
+
+// rdar://6800430
+void objc_assign_weak(id value, id *location) {
+}
+
+#endif
diff --git a/test/CodeGenObjC/sel-as-builtin-type.m b/test/CodeGenObjC/sel-as-builtin-type.m
new file mode 100644
index 0000000..72a8564
--- /dev/null
+++ b/test/CodeGenObjC/sel-as-builtin-type.m
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -emit-llvm -o %t %s
+// pr5025
+// radar 7405040
+
+typedef const struct objc_selector {
+  void *sel_id;
+  const char *sel_types;
+} *SEL;
+
+@interface I2
++(id) dictionary;
+@end
+
+@implementation I3; // expected-warning {{cannot find interface declaration for 'I3'}}
++(void) initialize {
+  I2 *a0 = [I2 dictionary];
+}
+@end
+
+int func(SEL s1, SEL s2)
+{
+        return s1->sel_id == s2->sel_id;
+}
diff --git a/test/CodeGenObjC/stand-alone-implementation.m b/test/CodeGenObjC/stand-alone-implementation.m
new file mode 100644
index 0000000..a519495
--- /dev/null
+++ b/test/CodeGenObjC/stand-alone-implementation.m
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -fobjc-nonfragile-abi -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-X86-64 %s
+
+// radar 7547942
+// Allow injection of ivars into implementation's implicit class.
+
+@implementation INTFSTANDALONE // expected-warning {{cannot find interface declaration for 'INTFSTANDALONE'}}
+{
+  id IVAR1;
+  id IVAR2;
+}
+- (id) Meth { return IVAR1; }
+@end
+
+// CHECK-X86-64: @"OBJC_IVAR_$_INTFSTANDALONE.IVAR1"
+// CHECK-X86-64: @"OBJC_IVAR_$_INTFSTANDALONE.IVAR2"
+
diff --git a/test/CodeGenObjC/super-classmethod-category.m b/test/CodeGenObjC/super-classmethod-category.m
new file mode 100644
index 0000000..c19663c
--- /dev/null
+++ b/test/CodeGenObjC/super-classmethod-category.m
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -emit-llvm -o %t %s
+
+@interface SUPER
++ (void)Meth;
+@end
+
+@interface CURRENT : SUPER
++ (void)Meth;
+@end
+
+@implementation CURRENT(CAT)
++ (void)Meth { [super Meth]; }
+@end
diff --git a/test/CodeGenObjC/super-dotsyntax-property.m b/test/CodeGenObjC/super-dotsyntax-property.m
new file mode 100644
index 0000000..9dfde2d
--- /dev/null
+++ b/test/CodeGenObjC/super-dotsyntax-property.m
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -emit-llvm -o %t %s
+
+@interface B
+{
+  int _parent;
+}
+@property int parent;
+  +(int) classGetter;
+  +(void) setClassGetter:(int) arg;
+
+  -(int) getter;
+  -(void) setGetter:(int)arg;
+@end
+
+@interface A : B
+@end
+
+@implementation A
++(int) classGetter {
+  return 0;
+}
+
++(int) classGetter2 {
+  super.classGetter = 100;
+  return super.classGetter;
+}
+
+-(void) method {
+  super.getter = 200;
+  int x = super.getter;
+}
+-(void) setParent : (int) arg {
+  super.parent = arg + super.parent;
+  
+}
+@end
+
+void f0() {
+  int l1 = A.classGetter;
+  int l2 = [A classGetter2];
+}
diff --git a/test/CodeGenObjC/super-message-fragileabi.m b/test/CodeGenObjC/super-message-fragileabi.m
new file mode 100644
index 0000000..5efc234
--- /dev/null
+++ b/test/CodeGenObjC/super-message-fragileabi.m
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -emit-llvm %s -o - | FileCheck %s
+
+@class  Some;
+
+@protocol Proto
+- (id)initSome:(Some *)anArg;
+@end
+
+
+@interface Table <Proto>
+@end
+
+@interface BetterTable: Table
+
+- (id)initSome:(Some *)arg;
+
+@end
+
+@implementation BetterTable
+
+- (id)initSome:(Some *)arg {
+
+ if(self=[super initSome:arg])
+ {
+	;
+ }
+// CHECK: load %struct._objc_class** getelementptr inbounds (%struct._objc_class* @"\01L_OBJC_CLASS_BetterTable", i32 0, i32 1)
+
+ return self;
+}
+@end
+
diff --git a/test/CodeGenObjC/synchronized.m b/test/CodeGenObjC/synchronized.m
new file mode 100644
index 0000000..1af8234
--- /dev/null
+++ b/test/CodeGenObjC/synchronized.m
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -emit-llvm -triple=i686-apple-darwin9 -o %t %s -O2
+// RUN: grep 'ret i32' %t | count 1
+// RUN: grep 'ret i32 1' %t | count 1
+
+@interface MyClass
+{
+}
+- (void)method;
+@end
+
+@implementation MyClass
+
+- (void)method
+{
+	@synchronized(self)
+	{
+	}
+}
+
+@end
+
+void foo(id a) {
+  @synchronized(a) {
+    return;
+  }
+}
+
+int f0(id a) {
+  int x = 0;
+  @synchronized((x++, a)) {    
+  }
+  return x; // ret i32 1
+}
+
+void f1(id a) {
+  // The trick here is that the return shouldn't go through clean up,
+  // but there isn't a simple way to check this property.
+  @synchronized(({ return; }), a) {
+    return;
+  }
+}
diff --git a/test/CodeGenObjC/synthesize_ivar-cont-class.m b/test/CodeGenObjC/synthesize_ivar-cont-class.m
new file mode 100644
index 0000000..f853202
--- /dev/null
+++ b/test/CodeGenObjC/synthesize_ivar-cont-class.m
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -fobjc-nonfragile-abi -emit-llvm -o %t %s
+// RUN: grep '@"OBJC_IVAR_$_XCOrganizerDeviceNodeInfo.viewController"' %t
+
+@interface XCOrganizerNodeInfo
+@property (readonly, retain) id viewController;
+@end
+
+@interface XCOrganizerDeviceNodeInfo : XCOrganizerNodeInfo
+@end
+
+@interface XCOrganizerDeviceNodeInfo()
+@property (retain) id viewController;
+@end
+
+@implementation XCOrganizerDeviceNodeInfo
+@synthesize viewController;
+@end
+
diff --git a/test/CodeGenObjC/synthesize_ivar.m b/test/CodeGenObjC/synthesize_ivar.m
new file mode 100644
index 0000000..5dd90ab
--- /dev/null
+++ b/test/CodeGenObjC/synthesize_ivar.m
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -fobjc-nonfragile-abi -emit-llvm -o %t %s
+
+@interface I
+@property int IP;
+@end
+
+@implementation I
+@synthesize IP;
+- (int) Meth {
+   return IP;
+}
+@end
+
+// Test for synthesis of ivar for a property
+// declared in continuation class.
+@interface OrganizerViolatorView
+@end
+
+@interface OrganizerViolatorView()
+@property (retain) id bindingInfo;
+@end
+
+@implementation OrganizerViolatorView
+@synthesize bindingInfo;
+@end
+
+// <rdar://problem/7336352> [irgen] crash in synthesized property construction
+
+@interface I0 @end
+@protocol P0 @end
+@interface I1 {
+  I0<P0> *iv0;
+}
+@property (assign, readwrite) id p0;
+@end
+@implementation I1
+@synthesize p0 = iv0;
+@end
diff --git a/test/CodeGenObjC/try.m b/test/CodeGenObjC/try.m
new file mode 100644
index 0000000..884e33a
--- /dev/null
+++ b/test/CodeGenObjC/try.m
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 %s -S -o - -triple=i686-apple-darwin9
+// RUN: %clang_cc1 %s -S -o - -triple=x86_64-apple-darwin9
+
+// rdar://6757213 - Don't crash if the internal proto for
+// __objc_personality_v0 mismatches with an actual one.
+void __objc_personality_v0() { }
+void test1(void) {
+  @try { } @catch (...) { }
+}
diff --git a/test/CodeGenObjC/undefined-protocol.m b/test/CodeGenObjC/undefined-protocol.m
new file mode 100644
index 0000000..d87a5c9
--- /dev/null
+++ b/test/CodeGenObjC/undefined-protocol.m
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -emit-llvm-only -fgnu-runtime %s
+
+@protocol MadeUpProtocol;
+
+@interface Object <MadeUpProtocol> @end
+@implementation Object @end
diff --git a/test/CodeGenObjC/unname-bf-metadata.m b/test/CodeGenObjC/unname-bf-metadata.m
new file mode 100644
index 0000000..c1208c1
--- /dev/null
+++ b/test/CodeGenObjC/unname-bf-metadata.m
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -emit-llvm -o %t %s
+// Test that meta-data for ivar lists with unnamed bitfield are generated.
+//
+@interface Foo {
+@private
+    int first;
+    int :1;
+    int third :1;
+    int :1;
+    int fifth :1;
+}
+@end
+@implementation Foo 
+@end
diff --git a/test/CodeGenObjC/unwind-fn.m b/test/CodeGenObjC/unwind-fn.m
new file mode 100644
index 0000000..0aa8cde
--- /dev/null
+++ b/test/CodeGenObjC/unwind-fn.m
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -fobjc-nonfragile-abi -emit-llvm -o - %s | FileCheck --check-prefix=DEFAULT_EH %s
+// RUN: %clang_cc1 -fsjlj-exceptions -fobjc-nonfragile-abi -emit-llvm -o - %s | FileCheck --check-prefix=SJLJ_EH %s
+
+// DEFAULT_EH: declare void @_Unwind_Resume_or_Rethrow(i8*)
+// SJLJ_EH: declare void @_Unwind_SjLj_Resume(i8*)
+
+void f1(), f2();
+void f0() {
+  @try {
+    f1();
+  } @catch (...) {
+    f2();
+  }
+}
diff --git a/test/CodeGenObjC/variadic-sends.m b/test/CodeGenObjC/variadic-sends.m
new file mode 100644
index 0000000..ea13823
--- /dev/null
+++ b/test/CodeGenObjC/variadic-sends.m
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-X86-32 %s
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-X86-64 %s
+
+@interface A
+-(void) im0;
+-(void) im1: (int) x;
+-(void) im2: (int) x, ...;
+@end
+
+void f0(A *a) {
+  // CHECK-X86-32: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*)*)
+  // CHECK-X86-64: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*)*)
+  [a im0];
+}
+
+void f1(A *a) {
+  // CHECK-X86-32: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, i32)*)
+  // CHECK-X86-64: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, i32)*)
+  [a im1: 1];
+}
+
+void f2(A *a) {
+  // CHECK-X86-32: call void (i8*, i8*, i32, i32, ...)* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, i32, i32, ...)*)
+  // CHECK-X86-64: call void (i8*, i8*, i32, i32, ...)* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, i32, i32, ...)*)
+  [a im2: 1, 2];
+}
+
+@interface B : A @end
+@implementation B : A
+-(void) foo {
+  // CHECK-X86-32: call void bitcast (i8* (%struct._objc_method_description*, i8*, ...)* @objc_msgSendSuper to void (%struct._objc_method_description*, i8*, i32)*)
+  // CHECK-X86-64: call void bitcast (i8* (%struct._objc_method_description*, i8*, ...)* @objc_msgSendSuper to void (%struct._objc_method_description*, i8*, i32)*)
+  [super im1: 1];
+}
+-(void) bar {
+  // CHECK-X86-32: call void (%struct._objc_method_description*, i8*, i32, i32, ...)* bitcast (i8* (%struct._objc_method_description*, i8*, ...)* @objc_msgSendSuper to void (%struct._objc_method_description*, i8*, i32, i32, ...)*)
+  // CHECK-X86-64: call void (%struct._objc_method_description*, i8*, i32, i32, ...)* bitcast (i8* (%struct._objc_method_description*, i8*, ...)* @objc_msgSendSuper to void (%struct._objc_method_description*, i8*, i32, i32, ...)*)
+  [super im2: 1, 2];
+}
+
+@end
diff --git a/test/CodeGenObjC/x86_64-struct-return-gc.m b/test/CodeGenObjC/x86_64-struct-return-gc.m
new file mode 100644
index 0000000..c62a33f
--- /dev/null
+++ b/test/CodeGenObjC/x86_64-struct-return-gc.m
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-gc -emit-llvm -o - %s | FileCheck %s
+struct Coerce {
+  id a;
+};
+
+struct Coerce coerce_func(void);
+
+// CHECK: define void @Coerce_test()
+void Coerce_test(void) {
+  struct Coerce c;
+  
+  // CHECK: call i64 @coerce_func
+  // CHECK: call i8* @objc_memmove_collectable(
+  c = coerce_func();
+}
+
+struct Indirect {
+  id a;
+  int b[10];
+};
+
+struct Indirect indirect_func(void);
+
+// CHECK: define void @Indirect_test()
+void Indirect_test(void) {
+  struct Indirect i;
+  
+  // CHECK: call void @indirect_func(%struct.Indirect* sret
+  // CHECK: call i8* @objc_memmove_collectable(
+  i = indirect_func();
+}
diff --git a/test/CodeGenObjCXX/mangle.mm b/test/CodeGenObjCXX/mangle.mm
new file mode 100644
index 0000000..7a75a5b
--- /dev/null
+++ b/test/CodeGenObjCXX/mangle.mm
@@ -0,0 +1,44 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+
+// CHECK: @"_ZZ11+[A shared]E1a" = internal global
+// CHECK: @"_ZZ11-[A(Foo) f]E1a" = internal global
+// CHECK: v56@0:8i16i20i24i28i32i36i40i44^i48
+
+@interface A
+@end
+
+@implementation A
+
++ (A *)shared {
+  static A* a;
+  
+  return a;
+}
+
+@end
+
+@interface A(Foo)
+@end
+
+@implementation A(Foo)
+- (int)f {
+  // FIXME: Add a member function to s and make sure that it's mangled correctly.
+  struct s {
+  };
+  
+  static s a;
+
+  return 0;
+}
+@end
+
+// PR6468
+@interface Test
+- (void) process: (int)r3 :(int)r4 :(int)r5 :(int)r6 :(int)r7 :(int)r8 :(int)r9 :(int)r10 :(int &)i;
+@end
+
+@implementation Test
+- (void) process: (int)r3 :(int)r4 :(int)r5 :(int)r6 :(int)r7 :(int)r8 :(int)r9 :(int)r10 :(int &)i {
+}
+@end
+
diff --git a/test/Coverage/ast-printing.c b/test/Coverage/ast-printing.c
new file mode 100644
index 0000000..bbbc366
--- /dev/null
+++ b/test/Coverage/ast-printing.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -fsyntax-only %s
+// RUN: %clang_cc1 -ast-print %s
+// RUN: %clang_cc1 -ast-dump %s
+// RUN: %clang_cc1 -ast-print-xml -o %t %s
+// RUN: %clang_cc1 -print-decl-contexts %s
+
+#include "c-language-features.inc"
diff --git a/test/Coverage/ast-printing.cpp b/test/Coverage/ast-printing.cpp
new file mode 100644
index 0000000..1a75fb4
--- /dev/null
+++ b/test/Coverage/ast-printing.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only %s
+// RUN: %clang_cc1 -ast-print %s
+// RUN: %clang_cc1 -ast-dump %s
+// FIXME: %clang_cc1 -ast-print-xml -o %t %s
+// RUN: %clang_cc1 -print-decl-contexts %s
+// RUN: %clang_cc1 -fdump-record-layouts %s
+
+#include "cxx-language-features.inc"
diff --git a/test/Coverage/ast-printing.m b/test/Coverage/ast-printing.m
new file mode 100644
index 0000000..d9c97d4
--- /dev/null
+++ b/test/Coverage/ast-printing.m
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -fsyntax-only %s
+// RUN: %clang_cc1 -ast-print %s
+// RUN: %clang_cc1 -ast-dump %s
+
+#include "objc-language-features.inc"
diff --git a/test/Coverage/c-language-features.inc b/test/Coverage/c-language-features.inc
new file mode 100644
index 0000000..3548132
--- /dev/null
+++ b/test/Coverage/c-language-features.inc
@@ -0,0 +1,190 @@
+//-*- C -*-
+
+/* This is a 
+   multiline comment */
+
+// Intended to exercise all syntactic parts of the C language.
+
+int g0;
+int g1, g2;
+
+struct s0;
+
+struct s0 {
+  int x;
+};
+
+int g3 = 10;
+
+__asm("");
+
+typedef int td0;
+
+td0 g4;
+
+enum e0 {
+  ec0
+};
+
+static void f0(int x) {
+}
+
+inline void f0_0(int x) {
+  ;
+}
+
+extern void f0_1(int x) {
+}
+
+void f1(int, ...);
+
+// Statements.
+void f2() {
+  for (;;) {
+    break;
+    continue;
+  }
+
+  while (0) {
+  }
+
+  do {
+  } while (0);
+
+  void *label = &&theif;
+  goto *label;
+
+  goto theif;
+theif:
+  if (0) {
+    ;
+  } else if (0) {
+  } else {
+  }
+
+  switch(0) {
+  case 0:
+  case 1 ... 2:
+    break;
+  default:
+    break;
+  }
+
+  asm ("nop");
+
+  return;
+}
+
+// Expressions.
+
+#include <stdarg.h>
+
+typedef struct ipair {
+  int first, second;
+} ipair;
+
+void f4(int a0, int a1, int a2, va_list ap) {
+  int t0 = a0 ? a1 : a2;
+  float t1 = (float) a0;
+  ipair t2 = {1, 2};
+  ipair t2a = { .second = 2 };
+  int t3 = sizeof(ipair);
+  ipair t4;
+  t4 = (ipair) {1, 2};
+  extern int g(int);
+  int t5 = g(a0);
+  int t6 = t4.first;
+  int t7[10];
+  int t8 = t7[a0];
+  t8++;
+  const char *t9 = __FUNCTION__;
+  char t10 = 'x';
+  int t11 = __builtin_offsetof(ipair, first);
+  int t12 = __builtin_types_compatible_p(ipair, int);  
+  int t12_0 = __builtin_classify_type(t0);
+  int t12_1 = __builtin_classify_type(t1);
+  int t12_2 = __builtin_classify_type(t2);
+  // FIXME: Add _Complex and aggregate cases.
+  int t13 = va_arg(ap, int);
+  va_list t13_0;
+  va_copy(t13_0, ap);
+  int t14 = __extension__(t13);
+  int t15 = +t13;
+  unsigned t16 = t14 ^ t15;
+  int t17 = t14 % t15;
+  int t17_0 = t16 % t16;
+  float t18;
+  int t19 = t18 ? 0 : 1;
+  char *t20; ++t20; --t20;
+  float t21; ++t21; --t21;
+  double t22; ++t22; --t22;
+  long double t23; ++t23; --t23;
+  int t24 = !t19;
+  int t25 = __real t24;
+  int t26 = __imag t24;
+  const char *t27 = t9;
+  t27 += (unsigned char) 0xFF;
+  t27 += (signed char) 0xFF;
+  
+  struct { char f0[10]; } *t28;
+  int t29 = t28 - t28;
+  char *t30 = &t28->f0[1];
+
+  struct s1 { int f0; };
+  struct s1 t31_a, t31_b;
+  int t31_cond;
+  int t31 = (t31_cond ? t31_a : t31_b).f0;
+
+  _Complex float t32_a, t32_b;
+  int t32_cond;
+  int t32 = __real (t32_cond ? t32_a : t32_b);
+
+  struct { int x, y; } t33, *t34, t35[12], t36(int, float);
+  float t37, *t38, t39[9], t40(double);
+}
+
+// Extended vectors
+
+typedef __attribute__((ext_vector_type(2))) float float2;
+typedef __attribute__((ext_vector_type(4))) float float4;
+
+void f5() {
+  float4 t0 = (float4) { 0, 1, 2, 3 };
+  float4 t1 = t0;
+  t0.lo.even = t1.hi.x;
+
+  // irgen doesn't support this yet.
+#if 0
+  int t2_cond;
+  float2 t2 = (t2_cond ? t0 : t1).lo;
+#endif
+}
+
+void f6() {
+  const char *s0 = __func__;
+  const char *s1 = __FUNCTION__;
+  const char *s2 = __PRETTY_FUNCTION__;
+}
+
+// Arg mismatch with passed type.
+void f7(x) 
+     float x;
+{
+}
+
+void f8(x) 
+     short x;
+{
+}
+
+// Function which inputs an array
+void f9(int x[]) { }
+
+// Object literals.
+void f10() {
+  struct f10_s0 {
+    char iv0[10];
+  } x;
+
+  x = (struct f10_s0) { .iv0 = "name" };
+}
diff --git a/test/Coverage/codegen-gnu.m b/test/Coverage/codegen-gnu.m
new file mode 100644
index 0000000..6e7790d
--- /dev/null
+++ b/test/Coverage/codegen-gnu.m
@@ -0,0 +1,3 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown -fgnu-runtime -emit-llvm -o %t %s
+
+#include "objc-language-features.inc"
diff --git a/test/Coverage/codegen-next.m b/test/Coverage/codegen-next.m
new file mode 100644
index 0000000..978b443
--- /dev/null
+++ b/test/Coverage/codegen-next.m
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -emit-llvm -o %t %s
+// RUN: %clang_cc1 -g -emit-llvm -o %t %s
+
+#include "objc-language-features.inc"
diff --git a/test/Coverage/codegen.c b/test/Coverage/codegen.c
new file mode 100644
index 0000000..8e5195c
--- /dev/null
+++ b/test/Coverage/codegen.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -o %t %s
+// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm-bc -o %t %s
+// RUN: %clang_cc1 -triple i386-unknown-unknown -g -emit-llvm-bc -o %t %s
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm-bc -o %t %s
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -g -emit-llvm-bc -o %t %s
+
+#include "c-language-features.inc"
diff --git a/test/Coverage/cxx-language-features.inc b/test/Coverage/cxx-language-features.inc
new file mode 100644
index 0000000..51c1104
--- /dev/null
+++ b/test/Coverage/cxx-language-features.inc
@@ -0,0 +1,21 @@
+//-*- C++ -*-
+
+// Intended to exercise all syntactic parts of the C++ language that
+// aren't part of C.
+
+namespace std {
+  namespace debug {
+  }
+}
+
+using namespace std::debug;
+using namespace std;
+
+namespace safestl = ::std::debug;
+
+class Base1 { 
+};
+
+class Base2 { };
+
+class Derived1 : Base1, virtual public Base2 { };
diff --git a/test/Coverage/html-diagnostics.c b/test/Coverage/html-diagnostics.c
new file mode 100644
index 0000000..81b2cfa
--- /dev/null
+++ b/test/Coverage/html-diagnostics.c
@@ -0,0 +1,19 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -analyze -analyzer-output=html -analyzer-check-objc-mem -o %t %s
+// RUN: cat %t/*.html | FileCheck %s
+
+// CHECK: <h3>Annotated Source Code</h3>
+// CHECK: Dereference of null pointer
+
+void f0(int x) {
+  int *p = &x;
+
+  if (x > 10) {
+    if (x == 22)
+      p = 0;
+  }
+
+  *p = 10;
+}
+
+
diff --git a/test/Coverage/html-print.c b/test/Coverage/html-print.c
new file mode 100644
index 0000000..a3f29c6
--- /dev/null
+++ b/test/Coverage/html-print.c
@@ -0,0 +1,3 @@
+// RUN: %clang_cc1 -emit-html -o %t %s
+
+#include "c-language-features.inc"
diff --git a/test/Coverage/objc-language-features.inc b/test/Coverage/objc-language-features.inc
new file mode 100644
index 0000000..dbbf205
--- /dev/null
+++ b/test/Coverage/objc-language-features.inc
@@ -0,0 +1,87 @@
+//-*- ObjC -*-
+
+@protocol P0;
+
+@protocol P1 
+-(void) fm0;
+@end
+
+@class B;
+
+@interface Root
+@end
+
+@interface A : Root <P1> {
+  int iv0;
+  B *iv1;
+  B<P1> *iv2;
+}
+
+@property(readonly) int p0;
+@property(assign,nonatomic,readwrite) int p1;
+@property(copy) id p2;
+@property(retain) id p3;
+@property(assign, getter=getme, setter=setme:) id p4;
+@property(assign, readwrite) id p5;
+@end
+
+@implementation A
+@dynamic p0;
+@synthesize p1 = iv0;
+
+// Property type can differ from ivar type.
+@synthesize p5 = iv2;
+
++(void) fm0 {
+  [super fm0];
+}
+-(void) im0 {
+  const char *s0 = __func__;
+  const char *s1 = __FUNCTION__;
+  const char *s2 = __PRETTY_FUNCTION__;
+  [super im0];
+  int x = super.p0;
+}
+-(void) im1: (int) x, ... {
+}
+@end
+
+@implementation C : A
+@end
+
+@interface A (Cat)
+@end
+
+@implementation A (Cat)
+@end
+
+@interface B
+@end
+
+int f0(id x) {
+  @synchronized(x) {
+  }
+
+  @try {
+    @throw x;
+
+  } @catch(A *e) {
+    @throw;
+
+    // @catch param doesn't require name.
+  } @catch(B *) {
+
+  } @finally {
+    ;
+  }
+
+  for (id y in x) {
+    break;
+  }
+}
+
+#ifndef __OBJC2__
+struct s0 {
+  @defs(A);
+};
+#endif
diff --git a/test/Coverage/parse-callbacks.c b/test/Coverage/parse-callbacks.c
new file mode 100644
index 0000000..02f3a83
--- /dev/null
+++ b/test/Coverage/parse-callbacks.c
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -parse-noop %s
+// RUN: %clang_cc1 -parse-print-callbacks %s
+
+#include "c-language-features.inc"
diff --git a/test/Coverage/parse-callbacks.m b/test/Coverage/parse-callbacks.m
new file mode 100644
index 0000000..f023d3d
--- /dev/null
+++ b/test/Coverage/parse-callbacks.m
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -parse-noop %s
+// RUN: %clang_cc1 -parse-print-callbacks %s
+
+#include "objc-language-features.inc"
diff --git a/test/Coverage/targets.c b/test/Coverage/targets.c
new file mode 100644
index 0000000..c9f6f8d
--- /dev/null
+++ b/test/Coverage/targets.c
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -g -triple armv6-apple-darwin9 -emit-llvm -o %t %s
+// RUN: %clang_cc1 -g -triple armv6-unknown-unknown -emit-llvm -o %t %s
+// RUN: %clang_cc1 -g -triple bfin-unknown-unknown -emit-llvm -o %t %s
+// RUN: %clang_cc1 -g -triple i686-apple-darwin9 -emit-llvm -o %t %s
+// RUN: %clang_cc1 -g -triple i686-pc-linux-gnu -emit-llvm -o %t %s
+// RUN: %clang_cc1 -g -triple i686-unknown-dragonfly -emit-llvm -o %t %s
+// RUN: %clang_cc1 -g -triple i686-unknown-unknown -emit-llvm -o %t %s
+// RUN: %clang_cc1 -g -triple i686-unknown-win32 -emit-llvm -o %t %s
+// RUN: %clang_cc1 -g -triple pic16-unknown-unknown -emit-llvm -o %t %s
+// RUN: %clang_cc1 -g -triple powerpc-apple-darwin9 -emit-llvm -o %t %s
+// RUN: %clang_cc1 -g -triple powerpc-unknown-unknown -emit-llvm -o %t %s
+// RUN: %clang_cc1 -g -triple powerpc64-apple-darwin9 -emit-llvm -o %t %s
+// RUN: %clang_cc1 -g -triple powerpc64-unknown-unknown -emit-llvm -o %t %s
+// RUN: %clang_cc1 -g -triple sparc-unknown-solaris -emit-llvm -o %t %s
+// RUN: %clang_cc1 -g -triple sparc-unknown-unknown -emit-llvm -o %t %s
+// RUN: %clang_cc1 -g -triple x86_64-apple-darwin9 -emit-llvm -o %t %s
+// RUN: %clang_cc1 -g -triple x86_64-pc-linux-gnu -emit-llvm -o %t %s
+// RUN: %clang_cc1 -g -triple x86_64-unknown-unknown -emit-llvm -o %t %s
+
+// <rdar://problem/7181838> clang 1.0 fails to compile Python 2.6
+// RUN: %clang -ccc-host-triple x86_64-apple-darwin9 -### -S %s -mmacosx-version-min=10.4
+
diff --git a/test/Coverage/verbose.c b/test/Coverage/verbose.c
new file mode 100644
index 0000000..72451d4
--- /dev/null
+++ b/test/Coverage/verbose.c
@@ -0,0 +1 @@
+// RUN: %clang_cc1 -fsyntax-only -v %s
diff --git a/test/Driver/Xarch.c b/test/Driver/Xarch.c
new file mode 100644
index 0000000..b35bf6c
--- /dev/null
+++ b/test/Driver/Xarch.c
@@ -0,0 +1,9 @@
+// RUN: %clang -ccc-host-triple i386-apple-darwin9 -m32 -Xarch_i386 -O2 %s -S -### 2> %t.log
+// RUN: grep ' "-O2" ' %t.log | count 1
+// RUN: %clang -ccc-host-triple i386-apple-darwin9 -m64 -Xarch_i386 -O2 %s -S -### 2> %t.log
+// RUN: grep ' "-O2" ' %t.log | count 0
+// RUN: grep "argument unused during compilation: '-Xarch_i386 -O2'" %t.log
+// RUN: not %clang -ccc-host-triple i386-apple-darwin9 -m32 -Xarch_i386 -o -Xarch_i386 -S %s -S -Xarch_i386 -o 2> %t.log
+// RUN: grep "error: invalid Xarch argument: '-Xarch_i386 -o'" %t.log | count 2
+// RUN: grep "error: invalid Xarch argument: '-Xarch_i386 -S'" %t.log
+
diff --git a/test/Driver/analyze.c b/test/Driver/analyze.c
new file mode 100644
index 0000000..359b0e0
--- /dev/null
+++ b/test/Driver/analyze.c
@@ -0,0 +1,8 @@
+// Verify that the analyzer gets the same flags as normal compilation
+// (at least for a few key ones).
+
+// RUN: env MACOSX_DEPLOYMENT_TARGET=10.5 %clang -ccc-host-triple i386-apple-darwin9  -### --analyze -o /dev/null %s -msse 2> %t.log
+// RUN: FileCheck --input-file=%t.log %s
+
+// CHECK: "-analyze"
+// CHECK: "-target-feature" "+sse"
diff --git a/test/Driver/arm-darwin-builtin.c b/test/Driver/arm-darwin-builtin.c
new file mode 100644
index 0000000..9d4cee0
--- /dev/null
+++ b/test/Driver/arm-darwin-builtin.c
@@ -0,0 +1,14 @@
+// FIXME: Disable pending PR4941.
+// RUX: clang -ccc-host-triple x86_64-apple-darwin9 -arch arm -### -fsyntax-only %s 2> %t &&
+// RUX: grep -- "-fno-builtin-strcat" %t &&
+// RUX: grep -- "-fno-builtin-strcpy" %t &&
+
+// FIXME: Disable pending PR4941.
+// RUX: clang -ccc-host-triple x86_64-apple-darwin9 -arch arm -### -fsyntax-only %s -fbuiltin-strcat -fbuiltin-strcpy 2> %t &&
+// RUX: not grep -- "-fno-builtin-strcat" %t &&
+// RUX: not grep -- "-fno-builtin-strcpy" %t &&
+
+// RUN: %clang -ccc-no-clang -ccc-host-triple x86_64-apple-darwin9 -arch arm -### -fsyntax-only %s -fbuiltin-strcat -fbuiltin-strcpy 2> %t
+// RUN: not grep -- "-fno-builtin-strcat" %t
+// RUN: not grep -- "-fno-builtin-strcpy" %t
+
diff --git a/test/Driver/ast.c b/test/Driver/ast.c
new file mode 100644
index 0000000..6e5857f
--- /dev/null
+++ b/test/Driver/ast.c
@@ -0,0 +1,26 @@
+// RUN: %clang -ccc-host-triple i386-unknown-unknown -ccc-print-phases -emit-ast %s 2> %t
+// RUN: echo 'END' >> %t
+// RUN: FileCheck -check-prefix EMIT-AST-PHASES -input-file %t %s
+
+// EMIT-AST-PHASES: 0: input,
+// EMIT-AST-PHASES: , c
+// EMIT-AST-PHASES: 1: preprocessor, {0}, cpp-output
+// EMIT-AST-PHASES: 2: compiler, {1}, ast
+// EMIT-AST-PHASES-NOT: 3:
+// EMIT-AST-PHASES: END
+
+// RUN: touch %t.ast
+// RUN: %clang -ccc-host-triple i386-unknown-unknown -ccc-print-phases -c %t.ast 2> %t
+// RUN: echo 'END' >> %t
+// RUN: FileCheck -check-prefix COMPILE-AST-PHASES -input-file %t %s
+
+// COMPILE-AST-PHASES: 0: input,
+// COMPILE-AST-PHASES: , ast
+// COMPILE-AST-PHASES: 1: compiler, {0}, assembler
+// COMPILE-AST-PHASES: 2: assembler, {1}, object
+// COMPILE-AST-PHASES-NOT: 3:
+// COMPILE-AST-PHASES: END
+
+// FIXME: There is a problem with compiling AST's in that the input language is
+// not availabe for use by other tools (for example, to automatically add
+// -lstdc++). We may need -x [objective-]c++-ast and all that goodness. :(
diff --git a/test/Driver/bindings.c b/test/Driver/bindings.c
new file mode 100644
index 0000000..2271ab5
--- /dev/null
+++ b/test/Driver/bindings.c
@@ -0,0 +1,55 @@
+// Basic binding.
+// RUN: %clang -ccc-host-triple i386-unknown-unknown -ccc-print-bindings %s 2> %t
+// RUN: grep '"clang", inputs: \[".*bindings.c"\], output: ".*\.s"' %t
+// RUN: grep '"gcc::Assemble", inputs: \[".*\.s"\], output: ".*\.o"' %t
+// RUN: grep '"gcc::Link", inputs: \[".*\.o"\], output: "a.out"' %t
+
+// RUN: %clang -ccc-host-triple i386-unknown-unknown -ccc-print-bindings -ccc-no-clang %s 2> %t
+// RUN: grep '"gcc::Compile", inputs: \[".*bindings.c"\], output: ".*\.s"' %t
+// RUN: grep '"gcc::Assemble", inputs: \[".*\.s"\], output: ".*\.o"' %t
+// RUN: grep '"gcc::Link", inputs: \[".*\.o"\], output: "a.out"' %t
+
+// RUN: %clang -ccc-host-triple i386-unknown-unknown -ccc-print-bindings -ccc-no-clang -no-integrated-cpp %s 2> %t
+// RUN: grep '"gcc::Preprocess", inputs: \[".*bindings.c"\], output: ".*\.i"' %t
+// RUN: grep '"gcc::Compile", inputs: \[".*\.i"\], output: ".*\.s"' %t
+// RUN: grep '"gcc::Assemble", inputs: \[".*\.s"\], output: ".*\.o"' %t
+// RUN: grep '"gcc::Link", inputs: \[".*\.o"\], output: "a.out"' %t
+
+// RUN: %clang -ccc-host-triple i386-unknown-unknown -ccc-print-bindings -ccc-no-clang -no-integrated-cpp -pipe %s 2> %t
+// RUN: grep '"gcc::Preprocess", inputs: \[".*bindings.c"\], output: (pipe)' %t
+// RUN: grep '"gcc::Compile", inputs: \[(pipe)\], output: (pipe)' %t
+// RUN: grep '"gcc::Assemble", inputs: \[(pipe)\], output: ".*\.o"' %t
+// RUN: grep '"gcc::Link", inputs: \[".*\.o"\], output: "a.out"' %t
+
+// RUN: %clang -ccc-host-triple i386-unknown-unknown -ccc-print-bindings -ccc-no-clang -x c-header %s 2> %t
+// RUN: grep '"gcc::Precompile", inputs: \[".*bindings.c"\], output: ".*bindings.c.gch' %t
+
+// Clang control options
+
+// RUN: %clang -ccc-host-triple i386-unknown-unknown -ccc-print-bindings -fsyntax-only %s 2> %t
+// RUN: grep '"clang", inputs: \[".*bindings.c"\], output: (nothing)' %t
+// RUN: %clang -ccc-host-triple i386-unknown-unknown -ccc-print-bindings -ccc-no-clang -fsyntax-only %s 2> %t
+// RUN: grep '"gcc::Compile", inputs: \[".*bindings.c"\], output: (nothing)' %t
+// RUN: %clang -ccc-host-triple i386-unknown-unknown -ccc-print-bindings -ccc-no-clang-cxx -fsyntax-only -x c++ %s 2> %t
+// RUN: grep '"gcc::Compile", inputs: \[".*bindings.c"\], output: (nothing)' %t
+// RUN: %clang -ccc-host-triple i386-unknown-unknown -ccc-print-bindings -ccc-clang-cxx -fsyntax-only -x c++ %s 2> %t
+// RUN: grep '"clang", inputs: \[".*bindings.c"\], output: (nothing)' %t
+// RUN: %clang -ccc-host-triple i386-unknown-unknown -ccc-print-bindings -ccc-no-clang-cpp -fsyntax-only -no-integrated-cpp %s 2> %t
+// RUN: grep '"gcc::Preprocess", inputs: \[".*bindings.c"\], output: ".*\.i"' %t
+// RUN: grep '"clang", inputs: \[".*\.i"\], output: (nothing)' %t
+// RUN: %clang -ccc-host-triple i386-apple-darwin9 -ccc-print-bindings -ccc-clang-archs i386 %s -S -arch ppc 2> %t
+// RUN: grep '"gcc::Compile", inputs: \[".*bindings.c"\], output: "bindings.s"' %t
+// RUN: %clang -ccc-host-triple i386-apple-darwin9 -ccc-print-bindings -ccc-clang-archs powerpc %s -S -arch ppc 2> %t
+// RUN: grep '"clang", inputs: \[".*bindings.c"\], output: "bindings.s"' %t
+
+// RUN: %clang -ccc-host-triple powerpc-unknown-unknown -ccc-print-bindings -ccc-clang-archs "" %s -S 2> %t
+// RUN: grep '"clang", inputs: \[".*bindings.c"\], output: "bindings.s"' %t
+// RUN: %clang -ccc-host-triple powerpc-unknown-unknown -ccc-print-bindings -ccc-clang-archs "i386" %s -S 2> %t
+// RUN: grep '"gcc::Compile", inputs: \[".*bindings.c"\], output: "bindings.s"' %t
+
+// Darwin bindings
+// RUN: %clang -ccc-host-triple i386-apple-darwin9 -ccc-print-bindings %s 2> %t
+// RUN: grep '"clang", inputs: \[".*bindings.c"\], output: ".*\.s"' %t
+// RUN: grep '"darwin::Assemble", inputs: \[".*\.s"\], output: ".*\.o"' %t
+// RUN: grep '"darwin::Link", inputs: \[".*\.o"\], output: "a.out"' %t
+
diff --git a/test/Driver/cc-print-options.c b/test/Driver/cc-print-options.c
new file mode 100644
index 0000000..7b798cb
--- /dev/null
+++ b/test/Driver/cc-print-options.c
@@ -0,0 +1,7 @@
+// RUN: env CC_PRINT_OPTIONS=1 \
+// RUN:     CC_PRINT_OPTIONS_FILE=%t.log \
+// RUN: %clang -S -o %t.s %s
+// RUN: FileCheck %s < %t.log
+
+// CHECK: [Logging clang options]{{.*}}clang{{.*}}"-S"
+
diff --git a/test/Driver/ccc-add-args.c b/test/Driver/ccc-add-args.c
new file mode 100644
index 0000000..d9a16cb
--- /dev/null
+++ b/test/Driver/ccc-add-args.c
@@ -0,0 +1,5 @@
+// RUN: env CCC_ADD_ARGS="-ccc-echo,-ccc-print-options,,-v" %clang -### 2>&1 | FileCheck %s
+// CHECK: Option 0 - Name: "-ccc-echo", Values: {}
+// CHECK: Option 1 - Name: "-ccc-print-options", Values: {}
+// CHECK: Option 2 - Name: "-v", Values: {}
+// CHECK: Option 3 - Name: "-###", Values: {}
diff --git a/test/Driver/clang-c-as-cxx.c b/test/Driver/clang-c-as-cxx.c
new file mode 100644
index 0000000..0e28178
--- /dev/null
+++ b/test/Driver/clang-c-as-cxx.c
@@ -0,0 +1,6 @@
+// RUN: %clangxx -### %s 2>&1 | FileCheck %s
+//
+// PR5803
+//
+// CHECK: warning: treating 'c' input as 'c++' when in C++ mode, this behavior is deprecated
+// CHECK: "-cc1" {{.*}} "-x" "c++"
diff --git a/test/Driver/clang-g-opts.c b/test/Driver/clang-g-opts.c
new file mode 100644
index 0000000..4dbdf61
--- /dev/null
+++ b/test/Driver/clang-g-opts.c
@@ -0,0 +1,5 @@
+// RUN: %clang -S -v -o %t %s        2>&1 | not grep -w -- -g
+// RUN: %clang -S -v -o %t %s -g     2>&1 | grep -w -- -g
+// RUN: %clang -S -v -o %t %s -g0    2>&1 | not grep -w -- -g
+// RUN: %clang -S -v -o %t %s -g -g0 2>&1 | not grep -w -- -g
+// RUN: %clang -S -v -o %t %s -g0 -g 2>&1 | grep -w -- -g
diff --git a/test/Driver/clang-translation.c b/test/Driver/clang-translation.c
new file mode 100644
index 0000000..2464f03
--- /dev/null
+++ b/test/Driver/clang-translation.c
@@ -0,0 +1,44 @@
+// RUN: %clang -ccc-host-triple i386-unknown-unknown -### -S -O0 -Os %s -o %t.s -fverbose-asm -funwind-tables -fvisibility=hidden 2> %t.log
+// RUN: grep '"-triple" "i386-unknown-unknown"' %t.log
+// RUN: grep '"-S"' %t.log
+// RUN: grep '"-disable-free"' %t.log
+// RUN: grep '"-mrelocation-model" "static"' %t.log
+// RUN: grep '"-mdisable-fp-elim"' %t.log
+// RUN: grep '"-munwind-tables"' %t.log
+// RUN: grep '"-Os"' %t.log
+// RUN: grep '"-o" .*clang-translation.*' %t.log
+// RUN: grep '"-masm-verbose"' %t.log
+// RUN: grep '"-fvisibility" "hidden"' %t.log
+// RUN: %clang -ccc-host-triple i386-apple-darwin9 -### -S %s -o %t.s 2> %t.log
+// RUN: grep '"-target-cpu" "yonah"' %t.log
+// RUN: %clang -ccc-host-triple x86_64-apple-darwin9 -### -S %s -o %t.s 2> %t.log
+// RUN: grep '"-target-cpu" "core2"' %t.log
+
+// RUN: %clang -ccc-host-triple x86_64-apple-darwin10 -### -S %s 2> %t.log \
+// RUN:   -arch armv7
+// RUN: FileCheck -check-prefix=ARMV7_DEFAULT %s < %t.log
+// ARMV7_DEFAULT: clang
+// ARMV7_DEFAULT: "-cc1"
+// ARMV7_DEFAULT-NOT: "-msoft-float"
+// ARMV7_DEFAULT: "-mfloat-abi" "soft"
+// ARMV7_DEFAULT-NOT: "-msoft-float"
+// ARMV7_DEFAULT: "-x" "c"
+
+// RUN: %clang -ccc-host-triple x86_64-apple-darwin10 -### -S %s 2> %t.log \
+// RUN:   -arch armv7 -msoft-float
+// RUN: FileCheck -check-prefix=ARMV7_SOFTFLOAT %s < %t.log
+// ARMV7_SOFTFLOAT: clang
+// ARMV7_SOFTFLOAT: "-cc1"
+// ARMV7_SOFTFLOAT: "-msoft-float"
+// ARMV7_SOFTFLOAT: "-mfloat-abi" "soft"
+// ARMV7_SOFTFLOAT: "-x" "c"
+
+// RUN: %clang -ccc-host-triple x86_64-apple-darwin10 -### -S %s 2> %t.log \
+// RUN:   -arch armv7 -mhard-float
+// RUN: FileCheck -check-prefix=ARMV7_HARDFLOAT %s < %t.log
+// ARMV7_HARDFLOAT: clang
+// ARMV7_HARDFLOAT: "-cc1"
+// ARMV7_HARDFLOAT-NOT: "-msoft-float"
+// ARMV7_HARDFLOAT: "-mfloat-abi" "hard"
+// ARMV7_HARDFLOAT-NOT: "-msoft-float"
+// ARMV7_HARDFLOAT: "-x" "c"
diff --git a/test/Driver/clang_cpp.c b/test/Driver/clang_cpp.c
new file mode 100644
index 0000000..79b2f55
--- /dev/null
+++ b/test/Driver/clang_cpp.c
@@ -0,0 +1,4 @@
+// Verify that -include isn't included twice with -save-temps.
+// RUN: %clang -S -o - %s -include %t.h -save-temps -### 2> %t.log
+// RUN: grep '"-include' %t.log | count 1
+
diff --git a/test/Driver/clang_f_opts.c b/test/Driver/clang_f_opts.c
new file mode 100644
index 0000000..f1d6759
--- /dev/null
+++ b/test/Driver/clang_f_opts.c
@@ -0,0 +1,14 @@
+// RUN: %clang -### -S -fblocks -fbuiltin -fno-math-errno -fcommon -fpascal-strings -fno-blocks -fno-builtin -fmath-errno -fno-common -fno-pascal-strings -fblocks -fbuiltin -fmath-errno -fcommon -fpascal-strings %s 2>&1 | FileCheck -check-prefix=CHECK-OPTIONS1 %s
+// RUN: %clang -### -S -fblocks -fbuiltin -fno-math-errno -fcommon -fpascal-strings -fno-blocks -fno-builtin -fmath-errno -fno-common -fno-pascal-strings -fno-show-source-location -fshort-wchar %s 2>&1 | FileCheck -check-prefix=CHECK-OPTIONS2 %s
+// RUN: %clang -### -fshort-enums %s 2>&1 | FileCheck -check-prefix=CHECK-SHORT-ENUMS %s
+
+// CHECK-OPTIONS1: -fblocks
+// CHECK-OPTIONS1: -fpascal-strings
+
+// CHECK-OPTIONS2: -fmath-errno
+// CHECK-OPTIONS2: -fno-builtin
+// CHECK-OPTIONS2: -fshort-wchar
+// CHECK-OPTIONS2: -fno-common
+// CHECK-OPTIONS2: -fno-show-source-location
+
+// CHECK-SHORT-ENUMS: compiler does not support '-fshort-enums'
diff --git a/test/Driver/cxx-pth.cpp b/test/Driver/cxx-pth.cpp
new file mode 100644
index 0000000..e349691
--- /dev/null
+++ b/test/Driver/cxx-pth.cpp
@@ -0,0 +1,12 @@
+// Test forced PTH for CXX support.
+
+// RUN: %clang -x c++-header %s -### 2> %t.log
+// RUN: FileCheck -check-prefix EMIT -input-file %t.log %s
+
+// EMIT: "{{.*}}/clang{{.*}}" {{.*}} "-emit-pth" "{{.*}}.cpp.gch" "-x" "c++-header" "{{.*}}.cpp"
+
+// RUN: touch %t.h.gch
+// RUN: %clang -E -include %t.h %s -### 2> %t.log
+// RUN: FileCheck -check-prefix USE -input-file %t.log %s
+
+// USE: "{{.*}}/clang{{.*}}" {{.*}}"-include-pth" "{{.*}}.h.gch" {{.*}}"-x" "c++" "{{.*}}.cpp"
diff --git a/test/Driver/darwin-as.c b/test/Driver/darwin-as.c
new file mode 100644
index 0000000..6410df0
--- /dev/null
+++ b/test/Driver/darwin-as.c
@@ -0,0 +1,10 @@
+// RUN: %clang -ccc-host-triple i386-apple-darwin10 -### -x assembler -c %s -static -dynamic 2>%t
+// RUN: FileCheck -check-prefix=STATIC_AND_DYNAMIC-32 --input-file %t %s
+
+// CHECK-STATIC_AND_DYNAMIC-32: as{{(.exe)?}}" "-arch" "i386" "-force_cpusubtype_ALL" "-static" "-o"
+
+// RUN: %clang -ccc-host-triple x86_64-apple-darwin10 -### -x assembler -c %s -static 2>%t
+// RUN: FileCheck -check-prefix=STATIC-64 --input-file %t %s
+
+// CHECK-STATIC-64: as{{(.exe)?}}" "-arch" "x86_64" "-force_cpusubtype_ALL" "-o"
+
diff --git a/test/Driver/darwin-cc.c b/test/Driver/darwin-cc.c
new file mode 100644
index 0000000..7a3a378
--- /dev/null
+++ b/test/Driver/darwin-cc.c
@@ -0,0 +1,5 @@
+// RUN: %clang -ccc-no-clang -ccc-host-triple i386-apple-darwin10 -m32 -### -MD -g -fast -Q -dA -mkernel -ansi -aFOO -S -o /tmp/OUTPUTNAME -g0 -gfull -O2 -Werror -pedantic -Wmost -w -std=c99 -trigraphs -v -pg -fFOO -undef -Qn --param a=b -fmudflap -coverage -save-temps -nostdinc -I ARG0 -F ARG1 -I ARG2 -P -MF ARG3 -MG -MP -remap -g3 -H -D ARG4 -U ARG5 -A ARG6 -D ARG7 -U ARG8 -A ARG9 -include ARG10 -pthread %s 2> %t.log
+// RUN: grep ' ".*cc1" "-E" "-nostdinc" "-v" "-I" "ARG0" "-F" "ARG1" "-I" "ARG2" "-P" "-MD" "/tmp/OUTPUTNAME.d" "-MF" "ARG3" "-MG" "-MP" "-MQ" "/tmp/OUTPUTNAME" "-remap" "-dD" "-H" "-D__STATIC__" "-D_REENTRANT" "-D" "ARG4" "-U" "ARG5" "-A" "ARG6" "-D" "ARG7" "-U" "ARG8" "-A" "ARG9" "-include" "ARG10" ".*darwin-cc.c" "-D_MUDFLAP" "-include" "mf-runtime.h" "-mmacosx-version-min=10.6.0" "-m32" "-mkernel" "-mtune=core2" "-ansi" "-std=c99" "-trigraphs" "-Werror" "-pedantic" "-Wmost" "-w" "-fast" "-fno-eliminate-unused-debug-symbols" "-fFOO" "-fmudflap" "-O2" "-undef" "-fpch-preprocess" "-o" ".*darwin-cc.i"' %t.log
+// RUN: grep ' ".*cc1" "-fpreprocessed" ".*darwin-cc.i" "-O3" "-dumpbase" ".*darwin-cc.c" "-dA" "-mmacosx-version-min=10.6.0" "-m32" "-mkernel" "-mtune=core2" "-ansi" "-aFOO" "-auxbase-strip" "/tmp/OUTPUTNAME" "-g" "-g0" "-g" "-g3" "-O2" "-Werror" "-pedantic" "-Wmost" "-w" "-ansi" "-std=c99" "-trigraphs" "-version" "-p" "-fast" "-fno-eliminate-unused-debug-symbols" "-fFOO" "-fmudflap" "-undef" "-fno-ident" "-o" "/tmp/OUTPUTNAME" "--param" "a=b" "-fno-builtin" "-fno-merge-constants" "-fprofile-arcs" "-ftest-coverage"' %t.log
+
+
diff --git a/test/Driver/darwin-debug-flags.c b/test/Driver/darwin-debug-flags.c
new file mode 100644
index 0000000..7ce6137
--- /dev/null
+++ b/test/Driver/darwin-debug-flags.c
@@ -0,0 +1,11 @@
+// RUN: env RC_DEBUG_OPTIONS=1 %clang -ccc-host-triple i386-apple-darwin9 -g -Os %s  -emit-llvm -S -o - | FileCheck %s
+// <rdar://problem/7256886>
+
+// CHECK: !1 = metadata !{
+// CHECK: -cc1
+// CHECK: -triple i386-apple-darwin9
+// CHECK: -g
+// CHECK: -Os
+// CHECK: [ DW_TAG_compile_unit ]
+
+int x;
diff --git a/test/Driver/darwin-iphone-defaults.m b/test/Driver/darwin-iphone-defaults.m
new file mode 100644
index 0000000..97ac4a4
--- /dev/null
+++ b/test/Driver/darwin-iphone-defaults.m
@@ -0,0 +1,30 @@
+// RUN: %clang -ccc-host-triple i386-apple-darwin9 -arch armv7 -flto -S -o - %s | FileCheck %s
+
+// CHECK: @f0
+// CHECK-NOT: ssp
+// CHECK: ) {
+// CHECK: @__f0_block_invoke
+// CHECK: void @f1
+// CHECK-NOT: msgSend_fixup_alloc
+// CHECK: OBJC_SELECTOR_REFERENCES
+
+int f0() {
+  return ^(){ return 0; }();
+}
+
+@interface I0
+@property (assign) int p0;
+@end
+
+@implementation I0
+@synthesize p0 = __sythesized_p0;
+@end
+
+@interface I1
++(id) alloc;
+@end
+
+void f1() {
+  [I1 alloc];
+}
+
diff --git a/test/Driver/darwin-ld.c b/test/Driver/darwin-ld.c
new file mode 100644
index 0000000..76ddaa8
--- /dev/null
+++ b/test/Driver/darwin-ld.c
@@ -0,0 +1,76 @@
+// Check that ld gets arch_multiple.
+
+// RUN: %clang -ccc-host-triple i386-apple-darwin9 -arch i386 -arch x86_64 %s -### -o foo 2> %t.log
+// RUN: grep '".*ld.*" .*"-arch_multiple" "-final_output" "foo"' %t.log
+
+// RUN: %clang -ccc-host-triple i386-apple-darwin9 -### -filelist FOO -static 2> %t.log
+// RUN: grep '"-lcrt0.o" .*"-lgcc_static"' %t.log
+// RUN: grep '"-lgcc"' %t.log | count 0
+// RUN: %clang -ccc-host-triple i386-apple-darwin7 -### -filelist FOO 2> %t.log
+// RUN: grep '"-lcrt1.o" .*"-lgcc" "-lSystem"' %t.log
+// RUN: grep '"-lgcc_s"' %t.log | count 0
+// RUN: %clang -ccc-host-triple i386-apple-darwin8 -### -filelist FOO 2> %t.log
+// RUN: grep '"-lcrt1.o" .*"-lgcc_s.10.4" "-lgcc" "-lSystem"' %t.log
+// RUN: %clang -ccc-host-triple i386-apple-darwin9 -### -filelist FOO 2> %t.log
+// RUN: grep '"-lcrt1.10.5.o" .*"-lgcc_s.10.5" "-lgcc" "-lSystem"' %t.log
+// RUN: %clang -ccc-host-triple i386-apple-darwin10 -### -filelist FOO 2> %t.log
+// RUN: grep '"-lcrt1.10.6.o" .*"-lSystem" "-lgcc"' %t.log
+// RUN: grep '"-lgcc_s"' %t.log | count 0
+
+// Make sure we run dsymutil on source input files.
+// RUN: %clang -ccc-host-triple i386-apple-darwin9 -### -g %s -o BAR 2> %t.log
+// RUN: grep '".*dsymutil" "BAR"' %t.log
+// RUN: %clang -ccc-host-triple i386-apple-darwin9 -### -g -filelist FOO %s -o BAR 2> %t.log
+// RUN: grep '".*dsymutil" "BAR"' %t.log
+
+// Splatter test case. This is gross, but it works for now. For the
+// driver, just getting coverage of the tool code and checking the
+// output options is nearly good enough. The main thing we are
+// protecting against here is unintended changes in the driver
+// output. Intended changes should add more reasonable test cases, and
+// just update this test to match the expected behavior.
+//
+// Note that at conception, this exactly matches gcc.
+
+// RUN: %clang -ccc-host-triple i386-apple-darwin9 -### -A ARG0 -F ARG1 -L ARG2 -Mach -T ARG4 -X -Z -all_load -allowable_client ARG8 -bind_at_load -compatibility_version ARG11 -current_version ARG12 -d -dead_strip -dylib_file ARG14 -dylinker -dylinker_install_name ARG16 -dynamic -dynamiclib -e ARG19 -exported_symbols_list ARG20 -fexceptions -flat_namespace -fnested-functions -fopenmp -force_cpusubtype_ALL -fpie -fprofile-arcs -headerpad_max_install_names -image_base ARG29 -init ARG30 -install_name ARG31 -m ARG33 -miphoneos-version-min=2.0 -mmacosx-version-min=10.3.2 -multi_module -multiply_defined ARG37 -multiply_defined_unused ARG38 -no_dead_strip_inits_and_terms -nodefaultlibs -nofixprebinding -nomultidefs -noprebind -noseglinkedit -nostartfiles -nostdlib -pagezero_size ARG54 -pg -prebind -prebind_all_twolevel_modules -preload -r -read_only_relocs ARG55 -s -sectalign ARG57_0 ARG57_1 ARG57_2 -sectcreate ARG58_0 ARG58_1 ARG58_2 -sectobjectsymbols ARG59_0 ARG59_1 -sectorder ARG60_0 ARG60_1 ARG60_2 -seg1addr ARG61 -seg_addr_table ARG62 -seg_addr_table_filename ARG63 -segaddr ARG64_0 ARG64_1 -segcreate ARG65_0 ARG65_1 ARG65_2 -seglinkedit -segprot ARG67_0 ARG67_1 ARG67_2 -segs_read_FOO -segs_read_only_addr ARG69 -segs_read_write_addr ARG70 -shared-libgcc -single_module -static -static-libgcc -sub_library ARG77 -sub_umbrella ARG78 -t -twolevel_namespace -twolevel_namespace_hints -u ARG82 -umbrella ARG83 -undefined ARG84 -unexported_symbols_list ARG85 -w -weak_reference_mismatches ARG87 -whatsloaded -whyload -y -filelist FOO -l FOO 2> %t.log
+// RUN: grep '".*ld.*" "-static" "-dylib" "-dylib_compatibility_version" "ARG11" "-dylib_current_version" "ARG12" "-arch" "i386" "-dylib_install_name" "ARG31" "-all_load" "-allowable_client" "ARG8" "-bind_at_load" "-dead_strip" "-no_dead_strip_inits_and_terms" "-dylib_file" "ARG14" "-dynamic" "-exported_symbols_list" "ARG20" "-flat_namespace" "-headerpad_max_install_names" "-image_base" "ARG29" "-init" "ARG30" "-macosx_version_min" "10.3.2" "-iphoneos_version_min" "2.0" "-nomultidefs" "-multi_module" "-single_module" "-multiply_defined" "ARG37" "-multiply_defined_unused" "ARG38" "-pie" "-prebind" "-noprebind" "-nofixprebinding" "-prebind_all_twolevel_modules" "-read_only_relocs" "ARG55" "-sectcreate" "ARG58_0" "ARG58_1" "ARG58_2" "-sectorder" "ARG60_0" "ARG60_1" "ARG60_2" "-seg1addr" "ARG61" "-segprot" "ARG67_0" "ARG67_1" "ARG67_2" "-segaddr" "ARG64_0" "ARG64_1" "-segs_read_only_addr" "ARG69" "-segs_read_write_addr" "ARG70" "-seg_addr_table" "ARG62" "-seg_addr_table_filename" "ARG63" "-sub_library" "ARG77" "-sub_umbrella" "ARG78" "-twolevel_namespace" "-twolevel_namespace_hints" "-umbrella" "ARG83" "-undefined" "ARG84" "-unexported_symbols_list" "ARG85" "-weak_reference_mismatches" "ARG87" "-X" "-y" "-w" "-pagezero_size" "ARG54" "-segs_read_FOO" "-seglinkedit" "-noseglinkedit" "-sectalign" "ARG57_0" "ARG57_1" "ARG57_2" "-sectobjectsymbols" "ARG59_0" "ARG59_1" "-segcreate" "ARG65_0" "ARG65_1" "ARG65_2" "-whyload" "-whatsloaded" "-dylinker_install_name" "ARG16" "-dylinker" "-Mach" "-d" "-s" "-t" "-Z" "-u" "ARG82" "-undefined" "ARG84" "-A" "ARG0" "-e" "ARG19" "-m" "ARG33" "-r" "-o" "a.out" "-L" "ARG2" "-lgomp".* "-filelist" "FOO" "-lFOO" "-lgcov" "-allow_stack_execute" "-T" "ARG4" "-F" "ARG1"' %t.log
+
+// Don't run dsymutil on a fat build of an executable.
+// RUN: %clang -ccc-host-triple i386-apple-darwin9 -### -arch i386 -arch x86_64 -g %s 2> %t.log
+// RUN: grep dsymutil %t.log | count 0
+
+// Check linker changes that came with new linkedit format.
+// RUN: touch %t.o
+// RUN: %clang -ccc-host-triple i386-apple-darwin9 -### -arch armv6 -miphoneos-version-min=3.0 %t.o 2> %t.log
+// RUN: %clang -ccc-host-triple i386-apple-darwin9 -### -arch armv6 -miphoneos-version-min=3.0 -dynamiclib %t.o 2>> %t.log
+// RUN: %clang -ccc-host-triple i386-apple-darwin9 -### -arch armv6 -miphoneos-version-min=3.0 -bundle %t.o 2>> %t.log
+// RUN: FileCheck -check-prefix=LINK_IPHONE_3_0 %s < %t.log
+
+// LINK_IPHONE_3_0: ld"
+// LINK_IPHONE_3_0-NOT: -lcrt1.3.1.o
+// LINK_IPHONE_3_0: -lcrt1.o
+// LINK_IPHONE_3_0: -lSystem
+// LINK_IPHONE_3_0: ld"
+// LINK_IPHONE_3_0: -dylib
+// LINK_IPHONE_3_0: -ldylib1.o
+// LINK_IPHONE_3_0: -lSystem
+// LINK_IPHONE_3_0: ld"
+// LINK_IPHONE_3_0: -lbundle1.o
+// LINK_IPHONE_3_0: -lSystem
+
+// RUN: %clang -ccc-host-triple i386-apple-darwin9 -### -arch armv7 -miphoneos-version-min=3.1 %t.o 2> %t.log
+// RUN: %clang -ccc-host-triple i386-apple-darwin9 -### -arch armv7 -miphoneos-version-min=3.1 -dynamiclib %t.o 2>> %t.log
+// RUN: %clang -ccc-host-triple i386-apple-darwin9 -### -arch armv7 -miphoneos-version-min=3.1 -bundle %t.o 2>> %t.log
+// RUN: FileCheck -check-prefix=LINK_IPHONE_3_1 %s < %t.log
+
+// LINK_IPHONE_3_1: ld"
+// LINK_IPHONE_3_1-NOT: -lcrt1.o
+// LINK_IPHONE_3_1: -lcrt1.3.1.o
+// LINK_IPHONE_3_1: -lSystem
+// LINK_IPHONE_3_1: ld"
+// LINK_IPHONE_3_1: -dylib
+// LINK_IPHONE_3_1-NOT: -ldylib1.o
+// LINK_IPHONE_3_1: -lSystem
+// LINK_IPHONE_3_1: ld"
+// LINK_IPHONE_3_1-NOT: -lbundle1.o
+// LINK_IPHONE_3_1: -lSystem
diff --git a/test/Driver/darwin-objc-defaults.m b/test/Driver/darwin-objc-defaults.m
new file mode 100644
index 0000000..4cf83a1
--- /dev/null
+++ b/test/Driver/darwin-objc-defaults.m
@@ -0,0 +1,88 @@
+// Check non-fragile ABI and dispatch method defaults.
+
+// i386
+
+// RUN: %clang -ccc-host-triple x86_64-apple-darwin10 -S -### %s \
+// RUN:   -arch i386 -mmacosx-version-min=10.5 2> %t
+// RUN: FileCheck --check-prefix CHECK-I386_OSX10_5 < %t %s
+
+// CHECK-CHECK-I386_OSX10_5: "-cc1"
+// CHECK-CHECK-I386_OSX10_5-NOT: -fobjc-nonfragile-abi
+// CHECK-CHECK-I386_OSX10_5-NOT: -fobjc-dispatch-method
+// CHECK-CHECK-I386_OSX10_5: darwin-objc-defaults
+
+// RUN: %clang -ccc-host-triple x86_64-apple-darwin10 -S -### %s \
+// RUN:   -arch i386 -mmacosx-version-min=10.6 2> %t
+// RUN: FileCheck --check-prefix CHECK-I386_OSX10_6 < %t %s
+
+// CHECK-CHECK-I386_OSX10_6: "-cc1"
+// CHECK-CHECK-I386_OSX10_6-NOT: -fobjc-nonfragile-abi
+// CHECK-CHECK-I386_OSX10_6-NOT: -fobjc-dispatch-method
+// CHECK-CHECK-I386_OSX10_6: darwin-objc-defaults
+
+// RUN: %clang -ccc-host-triple x86_64-apple-darwin10 -S -### %s \
+// RUN:   -arch i386 -miphoneos-version-min=3.0 2> %t
+// RUN: FileCheck --check-prefix CHECK-I386_IPHONE3_0 < %t %s
+
+// CHECK-CHECK-I386_IPHONE3_0: "-cc1"
+// CHECK-CHECK-I386_IPHONE3_0-NOT: -fobjc-nonfragile-abi
+// CHECK-CHECK-I386_IPHONE3_0-NOT: -fobjc-dispatch-method
+// CHECK-CHECK-I386_IPHONE3_0: darwin-objc-defaults
+
+// x86_64
+
+// RUN: %clang -ccc-host-triple x86_64-apple-darwin10 -S -### %s \
+// RUN:   -arch x86_64 -mmacosx-version-min=10.5 2> %t
+// RUN: FileCheck --check-prefix CHECK-X86_64_OSX10_5 < %t %s
+
+// CHECK-CHECK-X86_64_OSX10_5: "-cc1"
+// CHECK-CHECK-X86_64_OSX10_5: -fobjc-nonfragile-abi
+// CHECK-CHECK-X86_64_OSX10_5: -fobjc-dispatch-method=non-legacy
+// CHECK-CHECK-X86_64_OSX10_5: darwin-objc-defaults
+
+// RUN: %clang -ccc-host-triple x86_64-apple-darwin10 -S -### %s \
+// RUN:   -arch x86_64 -mmacosx-version-min=10.6 2> %t
+// RUN: FileCheck --check-prefix CHECK-X86_64_OSX10_6 < %t %s
+
+// CHECK-CHECK-X86_64_OSX10_6: "-cc1"
+// CHECK-CHECK-X86_64_OSX10_6: -fobjc-nonfragile-abi
+// CHECK-CHECK-X86_64_OSX10_6: -fobjc-dispatch-method=mixed
+// CHECK-CHECK-X86_64_OSX10_6: darwin-objc-defaults
+
+// RUN: %clang -ccc-host-triple x86_64-apple-darwin10 -S -### %s \
+// RUN:   -arch x86_64 -miphoneos-version-min=3.0 2> %t
+// RUN: FileCheck --check-prefix CHECK-X86_64_IPHONE3_0 < %t %s
+
+// CHECK-CHECK-X86_64_IPHONE3_0: "-cc1"
+// CHECK-CHECK-X86_64_IPHONE3_0: -fobjc-nonfragile-abi
+// CHECK-CHECK-X86_64_IPHONE3_0: -fobjc-dispatch-method=mixed
+// CHECK-CHECK-X86_64_IPHONE3_0: darwin-objc-defaults
+
+// armv7
+
+// RUN: %clang -ccc-host-triple x86_64-apple-darwin10 -S -### %s \
+// RUN:   -arch armv7 -mmacosx-version-min=10.5 2> %t
+// RUN: FileCheck --check-prefix CHECK-ARMV7_OSX10_5 < %t %s
+
+// CHECK-CHECK-ARMV7_OSX10_5: "-cc1"
+// CHECK-CHECK-ARMV7_OSX10_5: -fobjc-nonfragile-abi
+// CHECK-CHECK-ARMV7_OSX10_5-NOT: -fobjc-dispatch-method
+// CHECK-CHECK-ARMV7_OSX10_5: darwin-objc-defaults
+
+// RUN: %clang -ccc-host-triple x86_64-apple-darwin10 -S -### %s \
+// RUN:   -arch armv7 -mmacosx-version-min=10.6 2> %t
+// RUN: FileCheck --check-prefix CHECK-ARMV7_OSX10_6 < %t %s
+
+// CHECK-CHECK-ARMV7_OSX10_6: "-cc1"
+// CHECK-CHECK-ARMV7_OSX10_6: -fobjc-nonfragile-abi
+// CHECK-CHECK-ARMV7_OSX10_6-NOT: -fobjc-dispatch-method
+// CHECK-CHECK-ARMV7_OSX10_6: darwin-objc-defaults
+
+// RUN: %clang -ccc-host-triple x86_64-apple-darwin10 -S -### %s \
+// RUN:   -arch armv7 -miphoneos-version-min=3.0 2> %t
+// RUN: FileCheck --check-prefix CHECK-ARMV7_IPHONE3_0 < %t %s
+
+// CHECK-CHECK-ARMV7_IPHONE3_0: "-cc1"
+// CHECK-CHECK-ARMV7_IPHONE3_0: -fobjc-nonfragile-abi
+// CHECK-CHECK-ARMV7_IPHONE3_0-NOT: -fobjc-dispatch-method
+// CHECK-CHECK-ARMV7_IPHONE3_0: darwin-objc-defaults
diff --git a/test/Driver/darwin-objc-gc.m b/test/Driver/darwin-objc-gc.m
new file mode 100644
index 0000000..aecb9a6
--- /dev/null
+++ b/test/Driver/darwin-objc-gc.m
@@ -0,0 +1,19 @@
+// Check that we warn, but accept, -fobjc-gc for iPhone OS.
+
+// RUN: %clang -ccc-host-triple i386-apple-darwin9 -miphoneos-version-min=3.0 -fobjc-gc -flto -S -o %t %s 2> %t.err
+// RUN: FileCheck --check-prefix=IPHONE_OBJC_GC_LL %s < %t 
+// RUN: FileCheck --check-prefix=IPHONE_OBJC_GC_STDERR %s < %t.err
+
+// IPHONE_OBJC_GC_LL: define void @f0
+// IPHONE_OBJC_GC_LL-NOT: objc_assign_ivar
+// IPHONE_OBJC_GC_LL: }
+
+// IPHONE_OBJC_GC_STDERR: warning: Objective-C garbage collection is not supported on this platform, ignoring '-fobjc-gc'
+
+@interface A {
+@public
+ id x;
+}
+@end
+
+void f0(A *a, id x) { a->x = x; }
diff --git a/test/Driver/darwin-version.c b/test/Driver/darwin-version.c
new file mode 100644
index 0000000..84533a6
--- /dev/null
+++ b/test/Driver/darwin-version.c
@@ -0,0 +1,23 @@
+// RUN: env MACOSX_DEPLOYMENT_TARGET=10.1 \
+// RUN:   %clang -ccc-host-triple i386-apple-darwin9 -DTEST0 -E %s
+#ifdef TEST0
+#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ != 1010
+#error Invalid version
+#endif
+#endif
+
+// RUN: env IPHONEOS_DEPLOYMENT_TARGET=2.0 \
+// RUN:   %clang -ccc-host-triple i386-apple-darwin9 -DTEST1 -E %s
+#ifdef TEST1
+#if __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ != 20000
+#error Invalid version
+#endif
+#endif
+
+// RUN: env IPHONEOS_DEPLOYMENT_TARGET=2.3.1 \
+// RUN:   %clang -ccc-host-triple i386-apple-darwin9 -DTEST2 -E %s
+#ifdef TEST2
+#if __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ != 20301
+#error Invalid version
+#endif
+#endif
diff --git a/test/Driver/default-toolchain.c b/test/Driver/default-toolchain.c
new file mode 100644
index 0000000..eeff763
--- /dev/null
+++ b/test/Driver/default-toolchain.c
@@ -0,0 +1,8 @@
+// RUN: %clang -ccc-host-triple i386-unknown-unknown -m64 -v 2> %t
+// RUN: grep 'Target: x86_64-unknown-unknown' %t
+
+// RUN: %clang -ccc-host-triple i386-apple-darwin9 -arch ppc -m64 -v 2> %t
+// RUN: grep 'Target: powerpc64-apple-darwin9' %t
+
+// RUN: %clang -ccc-host-triple i386-apple-darwin9 -arch ppc64 -m32 -v 2> %t
+// RUN: grep 'Target: powerpc-apple-darwin9' %t
diff --git a/test/Driver/dragonfly.c b/test/Driver/dragonfly.c
new file mode 100644
index 0000000..d7b954d
--- /dev/null
+++ b/test/Driver/dragonfly.c
@@ -0,0 +1,8 @@
+// RUN: %clang -ccc-host-triple amd64-pc-dragonfly %s -### 2> %t.log
+// RUN: FileCheck -input-file %t.log %s
+
+// CHECK: clang{{.*}}" "-cc1" "-triple" "amd64-pc-dragonfly"
+// CHECK: as{{.*}}" "-o" "{{.*}}.o" "{{.*}}.s
+// CHECK: ld{{.*}}" "-dynamic-linker" "{{.*}}ld-elf.{{.*}}" "-o" "a.out" "{{.*}}crt1.o" "{{.*}}crti.o" "{{.*}}crtbegin.o" "{{.*}}.o" "-L{{.*}}/gcc{{.*}}" {{.*}} "-lc" "-lgcc" "{{.*}}crtend.o" "{{.*}}crtn.o"
+
+
diff --git a/test/Driver/emit-llvm.c b/test/Driver/emit-llvm.c
new file mode 100644
index 0000000..3439b58
--- /dev/null
+++ b/test/Driver/emit-llvm.c
@@ -0,0 +1,13 @@
+// RUN: not %clang -ccc-host-triple i386-pc-linux-gnu -emit-llvm -o %t %s 2> %t.log
+// RUN: grep 'unable to pass LLVM bit-code files to linker' %t.log
+
+// Check that -O4 is only honored as the effective -O option.
+// <rdar://problem/7046672> clang/loader problem
+
+// RUN: %clang -ccc-print-phases -c -O4 -O0 %s 2> %t
+// RUN: FileCheck --check-prefix=O4_AND_O0 %s < %t
+
+// O4_AND_O0: 0: input, "{{.*}}", c
+// O4_AND_O0: 1: preprocessor, {0}, cpp-output
+// O4_AND_O0: 2: compiler, {1}, assembler
+// O4_AND_O0: 3: assembler, {2}, object
diff --git a/test/Driver/flags.c b/test/Driver/flags.c
new file mode 100644
index 0000000..6d80892
--- /dev/null
+++ b/test/Driver/flags.c
@@ -0,0 +1,9 @@
+// RUN: %clang -ccc-host-triple i386-apple-darwin9 -### -S -msoft-float %s 2> %t.log
+// RUN: grep '"-no-implicit-float"' %t.log
+
+// RUN: %clang -ccc-host-triple i386-apple-darwin9 -### -S -msoft-float -mno-soft-float %s 2> %t.log
+// RUN: grep '"-no-implicit-float"' %t.log | count 0
+
+// RUN: %clang -ccc-host-triple i386-apple-darwin9 -### -S -mno-soft-float %s -msoft-float 2> %t.log
+// RUN: grep '"-no-implicit-float"' %t.log
+
diff --git a/test/Driver/freebsd.c b/test/Driver/freebsd.c
new file mode 100644
index 0000000..3deee46
--- /dev/null
+++ b/test/Driver/freebsd.c
@@ -0,0 +1,7 @@
+// RUN: %clang -ccc-clang-archs "" -ccc-host-triple powerpc64-pc-freebsd8 %s -### 2> %t.log
+// RUN: cat %t.log
+// RUN: FileCheck -input-file %t.log %s
+
+// CHECK: clang{{.*}}" "-cc1" "-triple" "powerpc64-pc-freebsd8"
+// CHECK: as{{.*}}" "-o" "{{.*}}.o" "{{.*}}.s
+// CHECK: ld{{.*}}" "--eh-frame-hdr" "-dynamic-linker" "{{.*}}ld-elf{{.*}}" "-o" "a.out" "{{.*}}crt1.o" "{{.*}}crti.o" "{{.*}}crtbegin.o" "{{.*}}.o" "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed" "-lc" "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed" "{{.*}}crtend.o" "{{.*}}crtn.o"
diff --git a/test/Driver/hello.c b/test/Driver/hello.c
new file mode 100644
index 0000000..da62872
--- /dev/null
+++ b/test/Driver/hello.c
@@ -0,0 +1,18 @@
+// RUN: %clang -ccc-echo -o %t %s 2> %t.log
+
+// Make sure we used clang.
+// RUN: grep 'clang" -cc1 .*hello.c' %t.log
+
+// RUN: %t > %t.out
+// RUN: grep "I'm a little driver, short and stout." %t.out
+
+// FIXME: We don't have a usable assembler on Windows, so we can't build real
+// apps yet.
+// XFAIL: win32
+
+#include <stdio.h>
+
+int main() {
+  printf("I'm a little driver, short and stout.");
+  return 0;
+}
diff --git a/test/Driver/immediate-options.c b/test/Driver/immediate-options.c
new file mode 100644
index 0000000..5a3ec87
--- /dev/null
+++ b/test/Driver/immediate-options.c
@@ -0,0 +1,4 @@
+// RUN: %clang --help
+// RUN: %clang --help-hidden
+// RUN: %clang -dumpversion
+// RUN: %clang -print-search-dirs
diff --git a/test/Driver/lto.c b/test/Driver/lto.c
new file mode 100644
index 0000000..4543ffc
--- /dev/null
+++ b/test/Driver/lto.c
@@ -0,0 +1,24 @@
+// -emit-llvm, -flto, and -O4 all cause a switch to llvm-bc object
+// files.
+// RUN: %clang -ccc-print-phases -c %s -flto 2> %t.log
+// RUN: grep '2: compiler, {1}, llvm-bc' %t.log
+// RUN: %clang -ccc-print-phases -c %s -O4 2> %t.log
+// RUN: grep '2: compiler, {1}, llvm-bc' %t.log
+
+// and -emit-llvm doesn't alter pipeline (unfortunately?).
+// RUN: %clang -ccc-print-phases %s -emit-llvm 2> %t.log
+// RUN: grep '0: input, ".*lto.c", c' %t.log
+// RUN: grep '1: preprocessor, {0}, cpp-output' %t.log
+// RUN: grep '2: compiler, {1}, llvm-bc' %t.log
+// RUN: grep '3: linker, {2}, image' %t.log
+
+// llvm-bc and llvm-ll outputs need to match regular suffixes
+// (unfortunately).
+// RUN: %clang %s -emit-llvm -save-temps -### 2> %t.log
+// RUN: grep '"-o" ".*lto\.i" "-x" "c" ".*lto\.c"' %t.log
+// RUN: grep '"-o" ".*lto\.o" .*".*lto\.i"' %t.log
+// RUN: grep '".*a.out" .*".*lto\.o"' %t.log
+
+// RUN: %clang %s -emit-llvm -S -### 2> %t.log
+// RUN: grep '"-o" ".*lto\.s" "-x" "c" ".*lto\.c"' %t.log
+
diff --git a/test/Driver/nostdincxx.cpp b/test/Driver/nostdincxx.cpp
new file mode 100644
index 0000000..7e00555
--- /dev/null
+++ b/test/Driver/nostdincxx.cpp
@@ -0,0 +1,4 @@
+// RUN: %clangxx -nostdinc++ %s 2>&1 | FileCheck %s
+// XFAIL: win32
+// CHECK: file not found
+#include <vector> 
diff --git a/test/Driver/openbsd.c b/test/Driver/openbsd.c
new file mode 100644
index 0000000..6024461
--- /dev/null
+++ b/test/Driver/openbsd.c
@@ -0,0 +1,6 @@
+// RUN: %clang -ccc-clang-archs "" -ccc-host-triple i686-pc-openbsd %s -### 2> %t.log
+// RUN: FileCheck -input-file %t.log %s
+
+// CHECK: clang{{.*}}" "-cc1" "-triple" "i686-pc-openbsd"
+// CHECK: as{{.*}}" "-o" "{{.*}}.o" "{{.*}}.s
+// CHECK: ld{{.*}}" "-e" "__start" "--eh-frame-hdr" "-Bdynamic" "-dynamic-linker" "{{.*}}ld.so" "-o" "a.out" "{{.*}}crt0.o" "{{.*}}crtbegin.o" "{{.*}}.o" "-lgcc" "-lc" "-lgcc" "{{.*}}crtend.o"
diff --git a/test/Driver/parsing.c b/test/Driver/parsing.c
new file mode 100644
index 0000000..ca3a7f4
--- /dev/null
+++ b/test/Driver/parsing.c
@@ -0,0 +1,25 @@
+// RUN: %clang -ccc-print-options input -Yunknown -m32 -arch ppc -djoined -A separate -Ajoined -Wp,one,two -Xarch_joined AndSeparate -sectalign 1 2 3 2> %t
+// RUN: grep 'Option 0 - Name: "-ccc-print-options", Values: {}' %t
+// RUN: grep 'Option 1 - Name: "<input>", Values: {"input"}' %t
+// RUN: grep 'Option 2 - Name: "<unknown>", Values: {"-Yunknown"}' %t
+// RUN: grep 'Option 3 - Name: "-m32", Values: {}' %t
+// RUN: grep 'Option 4 - Name: "-arch", Values: {"ppc"}' %t
+// RUN: grep 'Option 5 - Name: "-d", Values: {"joined"}' %t
+// RUN: grep 'Option 6 - Name: "-A", Values: {"separate"}' %t
+// RUN: grep 'Option 7 - Name: "-A", Values: {"joined"}' %t
+// RUN: grep 'Option 8 - Name: "-Wp,", Values: {"one", "two"}' %t
+// RUN: grep 'Option 9 - Name: "-Xarch_", Values: {"joined", "AndSeparate"}' %t
+// RUN: grep 'Option 10 - Name: "-sectalign", Values: {"1", "2", "3"}' %t
+
+// RUN: not %clang -V 2> %t
+// RUN: grep "error: argument to '-V' is missing (expected 1 value)" %t
+// RUN: not %clang -sectalign 1 2 2> %t
+// RUN: grep "error: argument to '-sectalign' is missing (expected 3 values)" %t
+
+// Verify that search continues after find the first option.
+// RUN: %clang -ccc-print-options -Wally 2> %t
+// RUN: grep 'Option 0 - Name: "-ccc-print-options", Values: {}' %t
+// RUN: grep 'Option 1 - Name: "-W", Values: {"ally"}' %t
+
+
+
diff --git a/test/Driver/phases.c b/test/Driver/phases.c
new file mode 100644
index 0000000..7fe529c
--- /dev/null
+++ b/test/Driver/phases.c
@@ -0,0 +1,78 @@
+// Basic compilation for various types of files.
+// RUN: %clang -ccc-host-triple i386-unknown-unknown -ccc-print-phases -x c %s -x objective-c %s -x c++ %s -x objective-c++ -x assembler %s -x assembler-with-cpp %s -x none %s 2>&1 | FileCheck -check-prefix=BASIC %s
+// BASIC: 0: input, "{{.*}}phases.c", c
+// BASIC: 1: preprocessor, {0}, cpp-output
+// BASIC: 2: compiler, {1}, assembler
+// BASIC: 3: assembler, {2}, object
+// BASIC: 4: input, "{{.*}}phases.c", objective-c
+// BASIC: 5: preprocessor, {4}, objective-c-cpp-output
+// BASIC: 6: compiler, {5}, assembler
+// BASIC: 7: assembler, {6}, object
+// BASIC: 8: input, "{{.*}}phases.c", c++
+// BASIC: 9: preprocessor, {8}, c++-cpp-output
+// BASIC: 10: compiler, {9}, assembler
+// BASIC: 11: assembler, {10}, object
+// BASIC: 12: input, "{{.*}}phases.c", assembler
+// BASIC: 13: assembler, {12}, object
+// BASIC: 14: input, "{{.*}}phases.c", assembler-with-cpp
+// BASIC: 15: preprocessor, {14}, assembler
+// BASIC: 16: assembler, {15}, object
+// BASIC: 17: input, "{{.*}}phases.c", c
+// BASIC: 18: preprocessor, {17}, cpp-output
+// BASIC: 19: compiler, {18}, assembler
+// BASIC: 20: assembler, {19}, object
+// BASIC: 21: linker, {3, 7, 11, 13, 16, 20}, image
+
+// Universal linked image.
+// RUN: %clang -ccc-host-triple i386-apple-darwin9 -ccc-print-phases -x c %s -arch ppc -arch i386 2>&1 | FileCheck -check-prefix=ULI %s
+// ULI: 0: input, "{{.*}}phases.c", c
+// ULI: 1: preprocessor, {0}, cpp-output
+// ULI: 2: compiler, {1}, assembler
+// ULI: 3: assembler, {2}, object
+// ULI: 4: linker, {3}, image
+// ULI: 5: bind-arch, "ppc", {4}, image
+// ULI: 6: bind-arch, "i386", {4}, image
+// ULI: 7: lipo, {5, 6}, image
+
+// Universal object file.
+// RUN: %clang -ccc-host-triple i386-apple-darwin9 -ccc-print-phases -c -x c %s -arch ppc -arch i386 2>&1 | FileCheck -check-prefix=UOF %s
+// UOF: 0: input, "{{.*}}phases.c", c
+// UOF: 1: preprocessor, {0}, cpp-output
+// UOF: 2: compiler, {1}, assembler
+// UOF: 3: assembler, {2}, object
+// UOF: 4: bind-arch, "ppc", {3}, object
+// UOF: 5: bind-arch, "i386", {3}, object
+// UOF: 6: lipo, {4, 5}, object
+
+// Arch defaulting
+// RUN: %clang -ccc-host-triple i386-apple-darwin9 -ccc-print-phases -c -x assembler %s 2>&1 | FileCheck -check-prefix=ARCH1 %s
+// ARCH1: 2: bind-arch, "i386", {1}, object
+// RUN: %clang -ccc-host-triple i386-apple-darwin9 -ccc-print-phases -c -x assembler %s -m32 -m64 2>&1 | FileCheck -check-prefix=ARCH2 %s
+// ARCH2: 2: bind-arch, "x86_64", {1}, object
+// RUN: %clang -ccc-host-triple x86_64-apple-darwin9 -ccc-print-phases -c -x assembler %s 2>&1 | FileCheck -check-prefix=ARCH3 %s
+// ARCH3: 2: bind-arch, "x86_64", {1}, object
+// RUN: %clang -ccc-host-triple x86_64-apple-darwin9 -ccc-print-phases -c -x assembler %s -m64 -m32 2>&1 | FileCheck -check-prefix=ARCH4 %s
+// ARCH4: 2: bind-arch, "i386", {1}, object
+
+// Analyzer
+// RUN: %clang -ccc-host-triple i386-unknown-unknown -ccc-print-phases --analyze %s 2>&1 | FileCheck -check-prefix=ANALYZE %s
+// ANALYZE: 0: input, "{{.*}}phases.c", c
+// ANALYZE: 1: preprocessor, {0}, cpp-output
+// ANALYZE: 2: analyzer, {1}, plist
+
+// Precompiler
+// RUN: %clang -ccc-host-triple i386-unknown-unknown -ccc-print-phases -x c-header %s 2>&1 | FileCheck -check-prefix=PCH %s
+// PCH: 0: input, "{{.*}}phases.c", c-header
+// PCH: 1: preprocessor, {0}, c-header-cpp-output
+// PCH: 2: precompiler, {1}, precompiled-header
+
+// Darwin overrides the handling for .s
+// RUN: touch %t.s
+// RUN: %clang -ccc-host-triple i386-unknown-unknown -ccc-print-phases -c %t.s 2>&1 | FileCheck -check-prefix=DARWIN1 %s
+// DARWIN1: 0: input, "{{.*}}.s", assembler
+// DARWIN1: 1: assembler, {0}, object
+// RUN: %clang -ccc-host-triple i386-apple-darwin9 -ccc-print-phases -c %t.s 2>&1 | FileCheck -check-prefix=DARWIN2 %s
+// DARWIN2: 0: input, "{{.*}}.s", assembler-with-cpp
+// DARWIN2: 1: preprocessor, {0}, assembler
+// DARWIN2: 2: assembler, {1}, object
+
diff --git a/test/Driver/preprocessor.c b/test/Driver/preprocessor.c
new file mode 100644
index 0000000..09c1f6c
--- /dev/null
+++ b/test/Driver/preprocessor.c
@@ -0,0 +1,6 @@
+// RUN: %clang -E -x c-header %s > %t
+// RUN: grep 'B B' %t
+
+#define A B
+A A
+
diff --git a/test/Driver/pth.c b/test/Driver/pth.c
new file mode 100644
index 0000000..9c47c55
--- /dev/null
+++ b/test/Driver/pth.c
@@ -0,0 +1,12 @@
+// Test transparent PTH support.
+
+// RUN: %clang -ccc-pch-is-pth -x c-header %s -o %t.h.pth -### 2> %t.log
+// RUN: FileCheck -check-prefix CHECK1 -input-file %t.log %s
+
+// CHECK1: "{{.*}}/clang{{.*}}" "-cc1" {{.*}} "-o" "{{.*}}.h.pth" "-x" "c-header" "{{.*}}pth.c"
+
+// RUN: touch %t.h.pth
+// RUN: %clang -ccc-pch-is-pth -E -include %t.h %s -### 2> %t.log
+// RUN: FileCheck -check-prefix CHECK2 -input-file %t.log %s
+
+// CHECK2: "{{.*}}/clang{{.*}}" "-cc1" {{.*}}"-include-pth" "{{.*}}.h.pth" {{.*}}"-x" "c" "{{.*}}pth.c"
diff --git a/test/Driver/qa_override.c b/test/Driver/qa_override.c
new file mode 100644
index 0000000..5f96976
--- /dev/null
+++ b/test/Driver/qa_override.c
@@ -0,0 +1,6 @@
+// RUN: env QA_OVERRIDE_GCC3_OPTIONS="#+-Os +-Oz +-O +-O3 +-Oignore +a +b +c xb Xa Omagic ^-ccc-print-options  " %clang x -O2 b -O3 2>&1 | FileCheck %s
+// CHECK-NOT: ###
+// CHECK: Option 0 - Name: "-ccc-print-options", Values: {}
+// CHECK-NEXT: Option 1 - Name: "<input>", Values: {"x"}
+// CHECK-NEXT: Option 2 - Name: "-O", Values: {"ignore"}
+// CHECK-NEXT: Option 3 - Name: "-O", Values: {"magic"}
diff --git a/test/Driver/redzone.c b/test/Driver/redzone.c
new file mode 100644
index 0000000..9f117d0
--- /dev/null
+++ b/test/Driver/redzone.c
@@ -0,0 +1,6 @@
+// RUN: %clang -ccc-host-triple i386-unknown-unknown -mno-red-zone %s -S -emit-llvm -o %t.log
+// RUN: grep 'noredzone' %t.log
+// RUN: %clang -ccc-host-triple i386-unknown-unknown -mred-zone %s -S -emit-llvm -o %t.log
+// RUN: grep -v 'noredzone' %t.log 
+
+int foo() { return 42; }
diff --git a/test/Driver/rewrite-objc.m b/test/Driver/rewrite-objc.m
new file mode 100644
index 0000000..38993fc
--- /dev/null
+++ b/test/Driver/rewrite-objc.m
@@ -0,0 +1,11 @@
+// RUN: %clang -ccc-host-triple unknown -rewrite-objc %s -o - -### 2>&1 | \
+// RUN:   FileCheck -check-prefix=TEST0 %s
+// TEST0: clang{{.*}}" "-rewrite-objc"
+
+// RUN: not %clang -ccc-no-clang -ccc-host-triple unknown -rewrite-objc %s -o - -### 2>&1 | \
+// RUN:   FileCheck -check-prefix=TEST1 %s
+// TEST1: invalid output type 'rewritten-objc' for use with gcc
+
+// RUN: not %clang -ccc-no-clang -ccc-host-triple i386-apple-darwin10 -rewrite-objc %s -o - -### 2>&1 | \
+// RUN:   FileCheck -check-prefix=TEST2 %s
+// TEST2: invalid output type 'rewritten-objc' for use with gcc
diff --git a/test/Driver/std.c b/test/Driver/std.c
new file mode 100644
index 0000000..c82e9f1
--- /dev/null
+++ b/test/Driver/std.c
@@ -0,0 +1,8 @@
+// RUN: %clang -std=c99 -trigraphs -std=gnu99 %s -E -o - | FileCheck -check-prefix=OVERRIDE %s
+// OVERRIDE: ??(??)
+// RUN: %clang -ansi %s -E -o - | FileCheck -check-prefix=ANSI %s
+// ANSI: []
+// RUN: %clang -std=gnu99 -trigraphs %s -E -o - | FileCheck -check-prefix=EXPLICIT %s
+// EXPLICIT: []
+
+??(??)
diff --git a/test/Driver/unknown-gcc-arch.c b/test/Driver/unknown-gcc-arch.c
new file mode 100644
index 0000000..7018bf8
--- /dev/null
+++ b/test/Driver/unknown-gcc-arch.c
@@ -0,0 +1,8 @@
+// RUN: %clang -ccc-host-triple x86_64-unknown-unknown -c -x assembler %s -### 2> %t.log
+// RUN: grep '.*gcc.*"-m64"' %t.log
+// RUN: %clang -ccc-host-triple x86_64-unknown-unknown -c -x assembler %s -### -m32 2> %t.log
+// RUN: grep '.*gcc.*"-m32"' %t.log
+// RUN: %clang -ccc-host-triple i386-unknown-unknown -c -x assembler %s -### 2> %t.log
+// RUN: grep '.*gcc.*"-m32"' %t.log
+// RUN: %clang -ccc-host-triple i386-unknown-unknown -c -x assembler %s -### -m64 2> %t.log
+// RUN: grep '.*gcc.*"-m64"' %t.log
diff --git a/test/Driver/x86_features.c b/test/Driver/x86_features.c
new file mode 100644
index 0000000..9dbdd0a
--- /dev/null
+++ b/test/Driver/x86_features.c
@@ -0,0 +1,3 @@
+// RUN: %clang -ccc-host-triple i386-unknown-unknown -### -S %s -msse -msse4 -mno-sse -mno-mmx -msse 2> %t
+// RUN: grep '"-target-feature" "+sse" "-target-feature" "+sse4" "-target-feature" "-sse" "-target-feature" "-mmx" "-target-feature" "+sse"' %t
+
diff --git a/test/FixIt/fixit-c90.c b/test/FixIt/fixit-c90.c
new file mode 100644
index 0000000..0bc1fad
--- /dev/null
+++ b/test/FixIt/fixit-c90.c
@@ -0,0 +1,17 @@
+/* RUN: cp %s %t
+   RUN: %clang_cc1 -std=c90 -pedantic -fixit %t
+   RUN: %clang_cc1 -pedantic -x c -std=c90 -Werror %t
+ */
+/* XPASS: *
+   This test passes because clang merely warns for this syntax error even with
+   -pedantic -Werror -std=c90.
+ */
+
+/* This is a test of the various code modification hints that are
+   provided as part of warning or extension diagnostics. All of the
+   warnings will be fixed by -fixit, and the resulting file should
+   compile cleanly with -Werror -pedantic. */
+
+enum e0 {
+  e1,
+};
diff --git a/test/FixIt/fixit-cxx0x.cpp b/test/FixIt/fixit-cxx0x.cpp
new file mode 100644
index 0000000..d8a858d
--- /dev/null
+++ b/test/FixIt/fixit-cxx0x.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -verify -std=c++0x %s
+// RUN: cp %s %t
+// RUN: %clang_cc1 -std=c++0x -fixit %t || true
+// RUN: %clang_cc1 -Wall -pedantic -x c++ -std=c++0x %t
+
+/* This is a test of the various code modification hints that only
+   apply in C++0x. */
+struct A {
+  explicit operator int(); // expected-note{{conversion to integral type}}
+};
+
+void x() {
+  switch(A()) { // expected-error{{explicit conversion to}}
+  }
+}
+
diff --git a/test/FixIt/fixit-errors-1.c b/test/FixIt/fixit-errors-1.c
new file mode 100644
index 0000000..96f27eb
--- /dev/null
+++ b/test/FixIt/fixit-errors-1.c
@@ -0,0 +1,16 @@
+// RUN: cp %s %t
+// RUN: %clang_cc1 -pedantic -fixit %t
+// RUN: echo %clang_cc1 -pedantic -Werror -x c %t
+/* XPASS: * */
+
+/* This is a test of the various code modification hints that are
+   provided as part of warning or extension diagnostics. All of the
+   warnings will be fixed by -fixit, and the resulting file should
+   compile cleanly with -Werror -pedantic. */
+
+// FIXME: If you put a space at the end of the line, it doesn't work yet!
+char *s = "hi\
+there";
+
+// The following line isn't terminated, don't fix it.
+int i; // expected-error{{no newline at end of file}}
diff --git a/test/FixIt/fixit-errors.c b/test/FixIt/fixit-errors.c
new file mode 100644
index 0000000..ff06363
--- /dev/null
+++ b/test/FixIt/fixit-errors.c
@@ -0,0 +1,23 @@
+// RUN: cp %s %t
+// RUN: %clang_cc1 -pedantic -verify -fixit -x c %t || true
+// RUN: %clang_cc1 -pedantic -Werror -x c %t
+// XFAIL: *
+
+/* This is a test of the various code modification hints that are
+   provided as part of warning or extension diagnostics. All of the
+   warnings will be fixed by -fixit, and the resulting file should
+   compile cleanly with -Werror -pedantic. */
+
+struct s; // expected-note{{previous use is here}}
+
+union s *s1; // expected-error{{use of 's' with tag type that does not match previous declaration}}
+
+struct Point {
+  float x, y, z;
+};
+
+struct Point *get_origin();
+
+void test_point() {
+  (void)get_origin->x;
+}
diff --git a/test/FixIt/fixit-objc.m b/test/FixIt/fixit-objc.m
new file mode 100644
index 0000000..03f28a1
--- /dev/null
+++ b/test/FixIt/fixit-objc.m
@@ -0,0 +1,37 @@
+// RUN: cp %s %t
+// RUN: %clang_cc1 -pedantic -fixit -x objective-c %t
+// RUN: %clang_cc1 -pedantic -verify -x objective-c %t
+
+/* This is a test of the various code modification hints that are
+   provided as part of warning or extension diagnostics. All of the
+   warnings will be fixed by -fixit, and the resulting file should
+   compile cleanly with -Werror -pedantic. */
+
+@protocol X;
+
+void foo() {
+  <X> *P;    // should be fixed to 'id<X>'.
+}
+
+@class A;
+@class NSString;
+
+@interface Test
+- (void)test:(NSString *)string;
+
+@property (copy) NSString *property;
+@end
+
+void g(NSString *a);
+void h(id a);
+
+void f(Test *t) {
+  NSString *a = "Foo";
+  id b = "Foo";
+  A* c = "Foo"; // expected-warning {{incompatible pointer types initializing 'A *' with an expression of type 'char [4]'}}
+  g("Foo");
+  h("Foo");
+  h(("Foo"));
+  [t test:"Foo"];
+  t.property = "Foo";
+}
diff --git a/test/FixIt/fixit-pmem.cpp b/test/FixIt/fixit-pmem.cpp
new file mode 100644
index 0000000..b69eadf
--- /dev/null
+++ b/test/FixIt/fixit-pmem.cpp
@@ -0,0 +1,26 @@
+// RUN: cp %s %t
+// RUN: %clang_cc1 -pedantic -fixit -x c++ %t
+// RUN: %clang_cc1 -fsyntax-only -pedantic -Werror -x c++ %t
+// XFAIL: *
+
+/* This is a test of the various code modification hints that are
+   provided as part of warning or extension diagnostics. All of the
+   warnings will be fixed by -fixit, and the resulting file should
+   compile cleanly with -Werror -pedantic. */
+
+struct  S {
+	int i;
+};
+
+int foo(int S::* ps, S s, S* p)
+{
+  p.*ps = 1;
+  return s->*ps;
+}
+
+void foo1(int (S::*ps)(), S s, S* p)
+{
+  (p.*ps)();
+  (s->*ps)();
+}
+
diff --git a/test/FixIt/fixit-suffix.c b/test/FixIt/fixit-suffix.c
new file mode 100644
index 0000000..a1a747a
--- /dev/null
+++ b/test/FixIt/fixit-suffix.c
@@ -0,0 +1,5 @@
+// RUN: cp %s %t.extrasuffix
+// RUN: %clang_cc1 -fixit=fixed -x c %t.extrasuffix
+// RUN: %clang_cc1 -Werror -pedantic -x c %t.fixed.extrasuffix
+
+_Complex cd;
diff --git a/test/FixIt/fixit-unrecoverable.c b/test/FixIt/fixit-unrecoverable.c
new file mode 100644
index 0000000..8052beb
--- /dev/null
+++ b/test/FixIt/fixit-unrecoverable.c
@@ -0,0 +1,10 @@
+/* FIXME: This is a file containing various typos for which we can
+   suggest corrections but are unable to actually recover from
+   them. Ideally, we would eliminate all such cases and move these
+   tests elsewhere. */
+
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// FIXME: Sadly, the following doesn't work within a function.
+
+unsinged x = 17; // expected-error{{unknown type name 'unsinged'; did you mean 'unsigned'?}}
diff --git a/test/FixIt/fixit-unrecoverable.cpp b/test/FixIt/fixit-unrecoverable.cpp
new file mode 100644
index 0000000..00ed897
--- /dev/null
+++ b/test/FixIt/fixit-unrecoverable.cpp
@@ -0,0 +1,11 @@
+/* FIXME: This is a file containing various typos for which we can
+   suggest corrections but are unable to actually recover from
+   them. Ideally, we would eliminate all such cases and move these
+   tests elsewhere. */
+
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+float f(int y) {
+  return static_cst<float>(y); // expected-error{{use of undeclared identifier 'static_cst'; did you mean 'static_cast'?}}
+}
+
diff --git a/test/FixIt/fixit.c b/test/FixIt/fixit.c
new file mode 100644
index 0000000..b799fa3
--- /dev/null
+++ b/test/FixIt/fixit.c
@@ -0,0 +1,40 @@
+// RUN: cp %s %t
+// RUN: %clang_cc1 -pedantic -fixit -x c %t || true
+// RUN: grep -v CHECK %t > %t2
+// RUN: %clang_cc1 -pedantic -Werror -x c %t
+// RUN: FileCheck -input-file=%t2 %t
+
+/* This is a test of the various code modification hints that are
+   provided as part of warning or extension diagnostics. All of the
+   warnings will be fixed by -fixit, and the resulting file should
+   compile cleanly with -Werror -pedantic. */
+
+// FIXME: FIX-IT should add #include <string.h>?
+int strcmp(const char *s1, const char *s2);
+
+void f0(void) { };
+
+struct s {
+  int x, y;;
+};
+
+// CHECK: _Complex double cd;
+_Complex cd;
+
+// CHECK: struct s s0 = { .y = 5 };
+struct s s0 = { y: 5 };
+
+// CHECK: int array0[5] = { [3] = 3 };
+int array0[5] = { [3] 3 };
+
+void f1(x, y)
+{
+}
+
+int i0 = { 17 };
+
+int test_cond(int y, int fooBar) {
+// CHECK: int x = y ? 1 : 4+fooBar;
+  int x = y ? 1 4+foobar;
+  return x;
+}
diff --git a/test/FixIt/fixit.cpp b/test/FixIt/fixit.cpp
new file mode 100644
index 0000000..b9282c4
--- /dev/null
+++ b/test/FixIt/fixit.cpp
@@ -0,0 +1,53 @@
+// RUN: cp %s %t
+// RUN: %clang_cc1 -pedantic -Wall -fixit -x c++ %t || true
+// RUN: %clang_cc1 -fsyntax-only -pedantic -Wall -Werror -x c++ %t
+
+/* This is a test of the various code modification hints that are
+   provided as part of warning or extension diagnostics. All of the
+   warnings will be fixed by -fixit, and the resulting file should
+   compile cleanly with -Werror -pedantic. */
+
+struct C1 {
+  virtual void f();
+  static void g();
+};
+struct C2 : virtual public virtual C1 { }; // expected-error{{duplicate}}
+
+virtual void C1::f() { } // expected-error{{'virtual' can only be specified inside the class definition}}
+
+static void C1::g() { } // expected-error{{'static' can only be specified inside the class definition}}
+
+template<int Value> struct CT { }; // expected-note{{previous use is here}}
+
+CT<10 >> 2> ct; // expected-warning{{require parentheses}}
+
+class C3 {
+public:
+  C3(C3, int i = 0); // expected-error{{copy constructor must pass its first argument by reference}}
+};
+
+struct CT<0> { }; // expected-error{{'template<>'}}
+
+template<> class CT<1> { }; // expected-error{{tag type}}
+
+// Access declarations
+class A {
+protected:
+  int foo();
+};
+
+class B : public A {
+  A::foo; // expected-warning{{access declarations are deprecated}}
+};
+
+void f() throw();
+void f(); // expected-warning{{missing exception specification}}
+
+namespace rdar7853795 {
+  struct A {
+    bool getNumComponents() const; // expected-note{{declared here}}
+    void dump() const {
+      getNumComponenets(); // expected-error{{use of undeclared identifier 'getNumComponenets'; did you mean 'getNumComponents'?}}
+    }
+  };
+}
diff --git a/test/FixIt/typo-crash.m b/test/FixIt/typo-crash.m
new file mode 100644
index 0000000..f10fe61
--- /dev/null
+++ b/test/FixIt/typo-crash.m
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// <rdar://problem/7605289>
+@implementation Unknown (Blarg) // expected-error{{cannot find interface declaration for 'Unknown'}}
+- (int)method { return ivar; } // expected-error{{use of undeclared identifier 'ivar'}}
+@end
diff --git a/test/FixIt/typo.c b/test/FixIt/typo.c
new file mode 100644
index 0000000..01ff3a0
--- /dev/null
+++ b/test/FixIt/typo.c
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: cp %s %t
+// RUN: %clang_cc1 -fsyntax-only -fixit -x c %t || true
+// RUN: %clang_cc1 -fsyntax-only -pedantic -Werror -x c %t
+struct Point {
+  float x, y;
+};
+
+struct Rectangle {
+  struct Point top_left, // expected-note{{'top_left' declared here}}
+               bottom_right;
+};
+
+enum Color { Red, Green, Blue };
+
+struct Window {
+  struct Rectangle bounds; // expected-note{{'bounds' declared here}}
+  enum Color color;
+};
+
+struct Window window = {
+  .bunds. // expected-error{{field designator 'bunds' does not refer to any field in type 'struct Window'; did you mean 'bounds'?}}
+  topleft.x = 3.14, // expected-error{{field designator 'topleft' does not refer to any field in type 'struct Rectangle'; did you mean 'top_left'?}}
+  2.71818, 5.0, 6.0, Red
+};
diff --git a/test/FixIt/typo.cpp b/test/FixIt/typo.cpp
new file mode 100644
index 0000000..5b9e68b
--- /dev/null
+++ b/test/FixIt/typo.cpp
@@ -0,0 +1,57 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: cp %s %t
+// RUN: %clang_cc1 -fsyntax-only -fixit -x c++ %t || true
+// RUN: %clang_cc1 -fsyntax-only -pedantic -Werror -x c++ %t
+namespace std {
+  template<typename T> class basic_string { // expected-note 2{{'basic_string' declared here}}
+  public:
+    int find(const char *substr); // expected-note{{'find' declared here}}
+    static const int npos = -1; // expected-note{{'npos' declared here}}
+  };
+
+  typedef basic_string<char> string; // expected-note 2{{'string' declared here}}
+}
+
+namespace otherstd { // expected-note 2{{'otherstd' declared here}}
+  using namespace std;
+}
+
+using namespace std;
+
+other_std::strng str1; // expected-error{{use of undeclared identifier 'other_std'; did you mean 'otherstd'?}} \
+// expected-error{{no type named 'strng' in namespace 'otherstd'; did you mean 'string'?}}
+tring str2; // expected-error{{unknown type name 'tring'; did you mean 'string'?}}
+
+::other_std::string str3; // expected-error{{no member named 'other_std' in the global namespace; did you mean 'otherstd'?}}
+
+float area(float radius, // expected-note{{'radius' declared here}}
+           float pi) {
+  return radious * pi; // expected-error{{did you mean 'radius'?}}
+}
+
+bool test_string(std::string s) {
+  basc_string<char> b1; // expected-error{{no template named 'basc_string'; did you mean 'basic_string'?}}
+  std::basic_sting<char> b2; // expected-error{{no template named 'basic_sting' in namespace 'std'; did you mean 'basic_string'?}}
+  (void)b1;
+  (void)b2;
+  return s.fnd("hello") // expected-error{{no member named 'fnd' in 'std::basic_string<char>'; did you mean 'find'?}}
+    == std::string::pos; // expected-error{{no member named 'pos' in 'std::basic_string<char>'; did you mean 'npos'?}}
+}
+
+struct Base { };
+struct Derived : public Base { // expected-note{{base class 'Base' specified here}}
+  int member; // expected-note 3{{'member' declared here}}
+
+  Derived() : base(), // expected-error{{initializer 'base' does not name a non-static data member or base class; did you mean the base class 'Base'?}}
+              ember() { } // expected-error{{initializer 'ember' does not name a non-static data member or base class; did you mean the member 'member'?}}
+
+  int getMember() const {
+    return ember; // expected-error{{use of undeclared identifier 'ember'; did you mean 'member'?}}
+  }
+
+  int &getMember();
+};
+
+int &Derived::getMember() {
+  return ember; // expected-error{{use of undeclared identifier 'ember'; did you mean 'member'?}}
+}
diff --git a/test/FixIt/typo.m b/test/FixIt/typo.m
new file mode 100644
index 0000000..f161bb8
--- /dev/null
+++ b/test/FixIt/typo.m
@@ -0,0 +1,140 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: cp %s %t
+// RUN: %clang_cc1 -fsyntax-only -fixit %t || true
+// RUN: %clang_cc1 -fsyntax-only -pedantic -Werror -x objective-c %t
+// XFAIL: *
+
+@interface NSString // expected-note{{'NSString' declared here}}
++ (int)method:(int)x;
+@end
+
+void test() {
+  // FIXME: not providing fix-its
+  NSstring *str = @"A string"; // expected-error{{use of undeclared identifier 'NSstring'; did you mean 'NSString'?}}
+}
+
+@protocol P1
+@optional
+@property int *sprop; // expected-note{{'sprop' declared here}}
+@end
+
+@interface A
+{
+  int his_ivar; // expected-note 2{{'his_ivar' declared here}}
+  float wibble;
+}
+
+@property int his_prop; // expected-note{{'his_prop' declared here}}
+@end
+
+@interface B : A <P1>
+{
+  int her_ivar; // expected-note 2{{'her_ivar' declared here}}
+}
+
+@property int her_prop; // expected-note{{'her_prop' declared here}}
+- (void)inst_method1:(int)a;
++ (void)class_method1;
+@end
+
+@implementation A
+@synthesize his_prop = his_ivar;
+@end
+
+@implementation B
+@synthesize her_prop = her_ivar;
+
+-(void)inst_method1:(int)a {
+  herivar = a; // expected-error{{use of undeclared identifier 'herivar'; did you mean 'her_ivar'?}}
+  hisivar = a; // expected-error{{use of undeclared identifier 'hisivar'; did you mean 'his_ivar'?}}
+  self->herivar = a; // expected-error{{'B' does not have a member named 'herivar'; did you mean 'her_ivar'?}}
+  self->hisivar = a; // expected-error{{'B' does not have a member named 'hisivar'; did you mean 'his_ivar'?}}
+  self.hisprop = 0; // expected-error{{property 'hisprop' not found on object of type 'B *'; did you mean 'his_prop'?}}
+  self.herprop = 0; // expected-error{{property 'herprop' not found on object of type 'B *'; did you mean 'her_prop'?}}
+  self.s_prop = 0; // expected-error{{property 's_prop' not found on object of type 'B *'; did you mean 'sprop'?}}
+}
+
++(void)class_method1 {
+}
+@end
+
+void test_message_send(B* b) {
+  [NSstring method:17]; // expected-error{{unknown receiver 'NSstring'; did you mean 'NSString'?}}
+}
+
+@interface Collide // expected-note{{'Collide' declared here}}
+{
+@public
+  int value; // expected-note{{'value' declared here}}
+}
+
+@property int value; // expected-note{{'value' declared here}}
+@end
+
+@implementation Collide
+@synthesize value = value;
+@end
+
+void test2(Collide *a) {
+  a.valu = 17; // expected-error{{property 'valu' not found on object of type 'Collide *'; did you mean 'value'?}}
+  a->vale = 17; // expected-error{{'Collide' does not have a member named 'vale'; did you mean 'value'?}}
+}
+
+@interface Derived : Collid // expected-error{{cannot find interface declaration for 'Collid', superclass of 'Derived'; did you mean 'Collide'?}}
+@end
+
+@protocol NetworkSocket // expected-note{{'NetworkSocket' declared here}}
+- (int)send:(void*)buffer bytes:(int)bytes;
+@end
+
+@interface IPv6 <Network_Socket> // expected-error{{cannot find protocol declaration for 'Network_Socket'; did you mean 'NetworkSocket'?}}
+@end
+
+@interface Super
+- (int)method;
+@end
+
+@interface Sub : Super
+- (int)method;
+@end
+
+@implementation Sub
+- (int)method {
+  return [supper method]; // expected-error{{unknown receiver 'supper'; did you mean 'super'?}}
+}
+  
+@end
+
+@interface Ivar
+@end
+
+@protocol Proto
+@property (retain) id ivar;
+@end
+
+@interface User <Proto>
+- (void)method;
+@end
+
+@implementation User
+@synthesize ivar;
+
+- (void)method {
+    [ivar method]; // Test that we don't correct 'ivar' to 'Ivar'
+}
+@end
+
+@interface User2
+@end
+
+@interface User2 (Cat) < Proto>
+- (void)method;
+@end
+
+@implementation User2 (Cat)
+@synthesize ivar;
+
+- (void)method {
+    [ivar method]; // Test that we don't correct 'ivar' to 'Ivar'
+}
+@end
diff --git a/test/Frontend/ast-codegen.c b/test/Frontend/ast-codegen.c
new file mode 100644
index 0000000..b5b2157
--- /dev/null
+++ b/test/Frontend/ast-codegen.c
@@ -0,0 +1,12 @@
+// RUN: %clang -emit-ast -o %t.ast %s
+// RUN: %clang -emit-llvm -S -o - %t.ast | FileCheck %s
+
+// CHECK: module asm "foo"
+__asm__("foo");
+
+// CHECK: @g0 = common global i32 0, align 4
+int g0;
+
+// CHECK: define i32 @f0()
+int f0() {
+}
diff --git a/test/Frontend/ast-main.c b/test/Frontend/ast-main.c
new file mode 100644
index 0000000..43237a1
--- /dev/null
+++ b/test/Frontend/ast-main.c
@@ -0,0 +1,8 @@
+// RUN: %clang -emit-llvm -S -o %t1.ll -x c - < %s
+// RUN: %clang -emit-ast -o %t.ast %s
+// RUN: %clang -emit-llvm -S -o %t2.ll -x ast - < %t.ast
+// RUN: diff %t1.ll %t2.ll
+
+int main() {
+  return 0;
+}
diff --git a/test/Frontend/cpp-output.c b/test/Frontend/cpp-output.c
new file mode 100644
index 0000000..e44095b
--- /dev/null
+++ b/test/Frontend/cpp-output.c
@@ -0,0 +1,14 @@
+// RUN: %clang -E -o %t -C %s
+// RUN: grep '^int x; // comment' %t
+// RUN: grep '^x x' %t
+// RUN: %clang -E -o %t -CC %s
+// RUN: grep '^int x; // comment' %t
+// RUN: grep '^x /\* comment \*/ x /\* comment \*/' %t
+
+int x; // comment
+
+#define A(foo, bar) foo bar
+#define B x // comment 
+
+A(B, B)
+
diff --git a/test/Frontend/darwin-version.c b/test/Frontend/darwin-version.c
new file mode 100644
index 0000000..1c866ee
--- /dev/null
+++ b/test/Frontend/darwin-version.c
@@ -0,0 +1,22 @@
+// RUN: %clang -ccc-host-triple armv6-apple-darwin9 -dM -E -o %t %s
+// RUN: grep '__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__' %t | grep '30000' | count 1
+// RUN: grep '__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__' %t | count 0
+// RUN: %clang -ccc-host-triple armv6-apple-darwin9 -miphoneos-version-min=2.0 -dM -E -o %t %s
+// RUN: grep '__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__' %t | grep '20000' | count 1
+// RUN: grep '__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__' %t | count 0
+// RUN: %clang -ccc-host-triple armv6-apple-darwin9 -miphoneos-version-min=2.2 -dM -E -o %t %s
+// RUN: grep '__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__' %t | grep '20200' | count 1
+// RUN: %clang -ccc-host-triple i686-apple-darwin8 -dM -E -o %t %s
+// RUN: grep '__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__' %t | count 0
+// RUN: grep '__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__' %t | grep '1040' | count 1
+// RUN: %clang -ccc-host-triple i686-apple-darwin9 -dM -E -o %t %s
+// RUN: grep '__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__' %t | grep '1050' | count 1
+// RUN: %clang -ccc-host-triple i686-apple-darwin10 -dM -E -o %t %s
+// RUN: grep '__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__' %t | grep '1060' | count 1
+// RUN: %clang -ccc-host-triple i686-apple-darwin9 -mmacosx-version-min=10.4 -dM -E -o %t %s
+// RUN: grep '__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__' %t | count 0
+// RUN: grep '__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__' %t | grep '1040' | count 1
+// RUN: %clang -ccc-host-triple i686-apple-darwin9 -mmacosx-version-min=10.5 -dM -E -o %t %s
+// RUN: grep '__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__' %t | grep '1050' | count 1
+// RUN: %clang -ccc-host-triple i686-apple-darwin9 -mmacosx-version-min=10.6 -dM -E -o %t %s
+// RUN: grep '__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__' %t | grep '1060' | count 1
diff --git a/test/Frontend/dependency-gen.c b/test/Frontend/dependency-gen.c
new file mode 100644
index 0000000..c85d60b
--- /dev/null
+++ b/test/Frontend/dependency-gen.c
@@ -0,0 +1,8 @@
+// rdar://6533411
+// RUN: %clang -MD -MF %t.d -S -x c -o %t.o %s
+// RUN: grep '.*dependency-gen.*:' %t.d
+// RUN: grep 'dependency-gen.c' %t.d
+
+// RUN: %clang -S -M -x c %s -o %t.d
+// RUN: grep '.*dependency-gen.*:' %t.d
+// RUN: grep 'dependency-gen.c' %t.d
diff --git a/test/Frontend/macros.c b/test/Frontend/macros.c
new file mode 100644
index 0000000..3170797
--- /dev/null
+++ b/test/Frontend/macros.c
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -DA= -DB=1 -verify -fsyntax-only %s
+
+int a[(B A) == 1 ? 1 : -1];
+
diff --git a/test/Frontend/output-failures.c b/test/Frontend/output-failures.c
new file mode 100644
index 0000000..e2af7c7
--- /dev/null
+++ b/test/Frontend/output-failures.c
@@ -0,0 +1,4 @@
+// RUN: not %clang_cc1 -emit-llvm -o %S/doesnotexist/somename %s 2> %t
+// RUN: FileCheck -check-prefix=OUTPUTFAIL -input-file=%t %s
+
+// OUTPUTFAIL: Error opening output file '{{.*}}doesnotexist{{.*}}'
diff --git a/test/Frontend/rewrite-macros.c b/test/Frontend/rewrite-macros.c
new file mode 100644
index 0000000..f44e545
--- /dev/null
+++ b/test/Frontend/rewrite-macros.c
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -verify -rewrite-macros -o %t %s
+
+#define A(a,b) a ## b
+
+// RUN: grep '12 */\*A\*/ /\*(1,2)\*/' %t
+A(1,2)
+
+// RUN: grep '/\*_Pragma("mark")\*/' %t
+_Pragma("mark")
+
+// RUN: grep "//#warning eek" %t
+/* expected-warning {{#warning eek}} */ #warning eek
+
+// RUN: grep "//#pragma mark mark" %t
+#pragma mark mark
+
+
diff --git a/test/Frontend/stdin.c b/test/Frontend/stdin.c
new file mode 100644
index 0000000..2d0a237
--- /dev/null
+++ b/test/Frontend/stdin.c
@@ -0,0 +1,3 @@
+// RUN: %clang_cc1 -E - < /dev/null > %t
+// RUN: grep '<built-in>' %t
+ 
diff --git a/test/Headers/c89.c b/test/Headers/c89.c
new file mode 100644
index 0000000..9e01ff9
--- /dev/null
+++ b/test/Headers/c89.c
@@ -0,0 +1,10 @@
+// RUN: %clang -ccc-host-triple i386-apple-darwin10 -fsyntax-only -Xclang -verify -std=c89 %s
+
+// FIXME: Disable inclusion of mm_malloc.h, our current implementation is broken
+// on win32 since we don't generally know how to find errno.h.
+
+#define __MM_MALLOC_H
+
+// PR6658
+#include <xmmintrin.h>
+
diff --git a/test/Headers/typedef_guards.c b/test/Headers/typedef_guards.c
new file mode 100644
index 0000000..1aa667b
--- /dev/null
+++ b/test/Headers/typedef_guards.c
@@ -0,0 +1,28 @@
+// RUN: %clang -fsyntax-only -verify %s
+
+// NULL is rdefined in stddef.h
+#define NULL ((void*) 0)
+
+// These are headers bundled with Clang.
+#include <stdarg.h>
+#include <stddef.h>
+
+#ifndef _VA_LIST
+typedef __builtin_va_list va_list;
+#endif
+
+#ifndef _SIZE_T
+typedef __typeof__(sizeof(int)) size_t;
+#endif
+
+#ifndef _WCHAR_T
+typedef __typeof__(*L"") wchar_t;
+#endif
+
+extern void foo(wchar_t x);
+extern void bar(size_t x);
+void *baz() { return NULL; }
+void quz() {
+  va_list y;
+}
+
diff --git a/test/Headers/x86-intrinsics-headers.c b/test/Headers/x86-intrinsics-headers.c
new file mode 100644
index 0000000..24c2d92
--- /dev/null
+++ b/test/Headers/x86-intrinsics-headers.c
@@ -0,0 +1,32 @@
+// RUN: %clang -fsyntax-only %s
+// RUN: %clang -fsyntax-only -fno-lax-vector-conversions %s
+// RUN: %clang -fsyntax-only -x c++ %s
+
+#if defined(i386) || defined(__x86_64__)
+
+#  if defined(__MMX__)
+#include <emmintrin.h>
+#include <mm_malloc.h>
+#  endif
+
+#  if defined(__SSE__)
+#include <xmmintrin.h>
+#  endif
+
+#  if defined(__SSE3__)
+#include <pmmintrin.h>
+#  endif
+
+#  if defined(__SSSE3__)
+#include <tmmintrin.h>
+#  endif
+
+#  if defined(__SSE4_1__)
+#include <smmintrin.h>
+#  endif
+
+#  if defined(__SSE4_2__)
+#include <nmmintrin.h>
+#  endif
+
+#endif
diff --git a/test/Index/Inputs/c-index-pch.h b/test/Index/Inputs/c-index-pch.h
new file mode 100644
index 0000000..6dda180
--- /dev/null
+++ b/test/Index/Inputs/c-index-pch.h
@@ -0,0 +1,7 @@
+#ifndef C_INDEX_PCH_H
+#define C_INDEX_PCH_H
+
+void foo(int i, float f);
+extern int bar;
+
+#endif // C_INDEX_PCH_H
diff --git a/test/Index/Inputs/cindex-from-source.h b/test/Index/Inputs/cindex-from-source.h
new file mode 100644
index 0000000..d13d397
--- /dev/null
+++ b/test/Index/Inputs/cindex-from-source.h
@@ -0,0 +1 @@
+typedef int t0;
diff --git a/test/Index/Inputs/complete-pch.h b/test/Index/Inputs/complete-pch.h
new file mode 100644
index 0000000..ddf5253
--- /dev/null
+++ b/test/Index/Inputs/complete-pch.h
@@ -0,0 +1,10 @@
+@interface A
+- (int)instanceMethod1:(int)x;
++ (int)classMethod1:(double)d;
+@end
+
+@interface B
+- (int)instanceMethod2:(int)x;
++ (int)classMethod2:(float)f;
+@end
+
diff --git a/test/Index/Inputs/foo.h b/test/Index/Inputs/foo.h
new file mode 100644
index 0000000..7670c00
--- /dev/null
+++ b/test/Index/Inputs/foo.h
@@ -0,0 +1,8 @@
+extern int global_var;
+
+void foo_func(int param1);
+void bar_func(void);
+
+struct MyStruct {
+  int field_var;
+};
diff --git a/test/Index/Inputs/lit.local.cfg b/test/Index/Inputs/lit.local.cfg
new file mode 100644
index 0000000..e6f55ee
--- /dev/null
+++ b/test/Index/Inputs/lit.local.cfg
@@ -0,0 +1 @@
+config.suffixes = []
diff --git a/test/Index/Inputs/objc.h b/test/Index/Inputs/objc.h
new file mode 100644
index 0000000..c671add
--- /dev/null
+++ b/test/Index/Inputs/objc.h
@@ -0,0 +1,11 @@
+@interface Base {
+    int my_var;
+}
+-(int) my_var;
+-(void) my_method: (int)param;
++(void) my_method: (int)param;
+@end
+
+@interface Sub : Base
+-(void) my_method: (int)param;
+@end
diff --git a/test/Index/Inputs/remap-complete-to.c b/test/Index/Inputs/remap-complete-to.c
new file mode 100644
index 0000000..30199db
--- /dev/null
+++ b/test/Index/Inputs/remap-complete-to.c
@@ -0,0 +1,6 @@
+int f0(int *pointer1, float *pointer2) {
+  return pointer2 - pointer1;
+}
+
+void g() {
+  
diff --git a/test/Index/Inputs/remap-load-to.c b/test/Index/Inputs/remap-load-to.c
new file mode 100644
index 0000000..8f9e1eb
--- /dev/null
+++ b/test/Index/Inputs/remap-load-to.c
@@ -0,0 +1,3 @@
+int foo(int parm1, float parm2) {
+  return parm1 + parm2;
+}
diff --git a/test/Index/Inputs/t1.c b/test/Index/Inputs/t1.c
new file mode 100644
index 0000000..ceaad4c
--- /dev/null
+++ b/test/Index/Inputs/t1.c
@@ -0,0 +1,28 @@
+#include "foo.h"
+
+void foo_func(int param1) {
+  int local_var = global_var;
+  for (int for_var = 100; for_var < 500; ++for_var) {
+    local_var = param1 + for_var;
+  }
+  bar_func();
+}
+
+struct S1 {
+  int x;
+};
+
+struct S2 {
+  int x;
+};
+
+void field_test(void) {
+  struct S1 s1;
+  s1.x = 0;
+  ((struct S2 *)0)->x = 0;
+  
+  struct MyStruct ms;
+  ms.field_var = 10;
+}
+
+int (^CP)(int) = ^(int x) { return x * global_var; };
diff --git a/test/Index/Inputs/t1.m b/test/Index/Inputs/t1.m
new file mode 100644
index 0000000..b7c86cd
--- /dev/null
+++ b/test/Index/Inputs/t1.m
@@ -0,0 +1,20 @@
+#include "objc.h"
+
+static void foo() {
+  Base *base;
+  int x = [base my_var];
+  [base my_method:x];
+  [Base my_method:x];
+}
+
+@implementation Base
+-(int) my_var {
+  return my_var;
+}
+
+-(void) my_method: (int)param {
+}
+
++(void) my_method: (int)param {
+}
+@end
diff --git a/test/Index/Inputs/t2.c b/test/Index/Inputs/t2.c
new file mode 100644
index 0000000..76d5d6c
--- /dev/null
+++ b/test/Index/Inputs/t2.c
@@ -0,0 +1,11 @@
+#include "foo.h"
+
+int global_var = 10;
+
+void bar_func(void) {
+  global_var += 100;
+  foo_func(global_var);
+
+  struct MyStruct *ms;
+  ms->field_var = 10;
+}
diff --git a/test/Index/Inputs/t2.m b/test/Index/Inputs/t2.m
new file mode 100644
index 0000000..3f103ee
--- /dev/null
+++ b/test/Index/Inputs/t2.m
@@ -0,0 +1,13 @@
+#include "objc.h"
+
+static void foo() {
+  Sub *sub;
+  int x = [sub my_var];
+  [sub my_method:x];
+  [Sub my_method:x];
+}
+
+@implementation Sub
+-(void) my_method: (int)param {
+}
+@end
diff --git a/test/Index/TestClassDecl.m b/test/Index/TestClassDecl.m
new file mode 100644
index 0000000..b55c862
--- /dev/null
+++ b/test/Index/TestClassDecl.m
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fblocks -emit-pch -x objective-c %s -o %t.ast
+// RUN: c-index-test -test-file-scan %t.ast %s | FileCheck -check-prefix=scan %s
+// RUN: c-index-test -test-load-tu %t.ast local | FileCheck -check-prefix=load %s
+
+// This test checks how the @class resolves as a cursor when there is a real definition
+// that follows. <rdar://problem/7383421>
+
+@class Foo;
+
+@interface Foo
+@end
+
+void function(Foo * arg)
+{
+    // nothing here.
+}
+
+// CHECK-scan: [1:1 - 8:1] Invalid Cursor => NoDeclFound
+// CHECK-scan: [8:1 - 8:8] UnexposedDecl=:8:1
+// CHECK-scan: [8:8 - 8:11] ObjCClassRef=Foo:10:12
+// CHECK-scan: [8:11 - 10:1] Invalid Cursor => NoDeclFound
+// CHECK-scan: [10:1 - 11:5] ObjCInterfaceDecl=Foo:10:12
+// CHECK-scan: [11:5 - 13:6] Invalid Cursor => NoDeclFound
+// CHECK-scan: [13:6 - 13:15] FunctionDecl=function:13:6 (Definition)
+// CHECK-scan: [13:15 - 13:18] ObjCClassRef=Foo:10:12
+// CHECK-scan: [13:18 - 13:24] ParmDecl=arg:13:21 (Definition)
+// CHECK-scan: [13:24 - 14:1] FunctionDecl=function:13:6 (Definition)
+// CHECK-scan: [14:1 - 16:2] UnexposedStmt=
+
+// CHECK-load: TestClassDecl.m:10:12: ObjCInterfaceDecl=Foo:10:12 Extent=[10:1 - 11:5]
+// CHECK-load: TestClassDecl.m:13:6: FunctionDecl=function:13:6 (Definition) Extent=[13:6 - 16:2]
+// CHECK-load: TestClassDecl.m:13:21: ParmDecl=arg:13:21 (Definition) Extent=[13:15 - 13:24]
+
diff --git a/test/Index/TestClassForwardDecl.m b/test/Index/TestClassForwardDecl.m
new file mode 100644
index 0000000..325a423
--- /dev/null
+++ b/test/Index/TestClassForwardDecl.m
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fblocks -emit-pch -x objective-c %s -o %t.ast
+// RUN: c-index-test -test-file-scan %t.ast %s | FileCheck -check-prefix=scan %s
+// RUN: c-index-test -test-load-tu %t.ast local | FileCheck -check-prefix=load %s
+
+// This test checks how the @class resolves as a cursor when the @interface is implicitly defined.
+// See TestClassDecl.m for the corresponding test case. (<rdar://problem/7383421>)
+
+@class Foo;
+
+void function(Foo * arg)
+{
+    // nothing here.
+}
+
+// CHECK-scan: [1:1 - 8:1] Invalid Cursor => NoDeclFound
+// CHECK-scan: [8:1 - 8:8] UnexposedDecl=:8:1
+// CHECK-scan: [8:8 - 8:11] ObjCClassRef=Foo:8:8
+// CHECK-scan: [8:11 - 10:6] Invalid Cursor => NoDeclFound
+// CHECK-scan: [10:6 - 10:15] FunctionDecl=function:10:6 (Definition)
+// CHECK-scan: [10:15 - 10:18] ObjCClassRef=Foo:8:8
+// CHECK-scan: [10:18 - 10:24] ParmDecl=arg:10:21 (Definition)
+// CHECK-scan: [10:24 - 11:1] FunctionDecl=function:10:6 (Definition)
+// CHECK-scan: [11:1 - 13:2] UnexposedStmt=
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// CHECK-load: TestClassForwardDecl.m:10:6: FunctionDecl=function:10:6 (Definition)
+// CHECK-load: TestClassForwardDecl.m:10:21: ParmDecl=arg:10:21
+
diff --git a/test/Index/annotate-tokens-pp.c b/test/Index/annotate-tokens-pp.c
new file mode 100644
index 0000000..485786e
--- /dev/null
+++ b/test/Index/annotate-tokens-pp.c
@@ -0,0 +1,58 @@
+#define NOTHING(X,Y)
+#define STILL_NOTHING NOTHING(honk,warble)
+#define BAR baz
+#define WIBBLE(X, Y) X##Y
+NOTHING(more,junk) float WIBBLE(int, float);
+int BAR STILL_NOTHING;
+#include "foo.h"
+#undef BAR
+
+// RUN: c-index-test -test-annotate-tokens=%s:2:1:9:1 -I%S/Inputs %s | FileCheck %s
+// CHECK: Punctuation: "#" [2:1 - 2:2] preprocessing directive=
+// CHECK: Identifier: "define" [2:2 - 2:8] preprocessing directive=
+// CHECK: Identifier: "STILL_NOTHING" [2:9 - 2:22] macro definition=STILL_NOTHING
+// CHECK: Identifier: "NOTHING" [2:23 - 2:30] preprocessing directive=
+// CHECK: Punctuation: "(" [2:30 - 2:31] preprocessing directive=
+// CHECK: Identifier: "honk" [2:31 - 2:35] preprocessing directive=
+// CHECK: Punctuation: "," [2:35 - 2:36] preprocessing directive=
+// CHECK: Identifier: "warble" [2:36 - 2:42] preprocessing directive=
+// CHECK: Punctuation: ")" [2:42 - 2:43] preprocessing directive=
+// CHECK: Punctuation: "#" [3:1 - 3:2] preprocessing directive=
+// CHECK: Identifier: "define" [3:2 - 3:8] preprocessing directive=
+// CHECK: Identifier: "BAR" [3:9 - 3:12] macro definition=BAR
+// CHECK: Identifier: "baz" [3:13 - 3:16] preprocessing directive=
+// CHECK: Punctuation: "#" [4:1 - 4:2] preprocessing directive=
+// CHECK: Identifier: "define" [4:2 - 4:8] preprocessing directive=
+// CHECK: Identifier: "WIBBLE" [4:9 - 4:15] macro definition=WIBBLE
+// CHECK: Punctuation: "(" [4:15 - 4:16] preprocessing directive=
+// CHECK: Identifier: "X" [4:16 - 4:17] preprocessing directive=
+// CHECK: Punctuation: "," [4:17 - 4:18] preprocessing directive=
+// CHECK: Identifier: "Y" [4:19 - 4:20] preprocessing directive=
+// CHECK: Punctuation: ")" [4:20 - 4:21] preprocessing directive=
+// CHECK: Identifier: "X" [4:22 - 4:23] preprocessing directive=
+// CHECK: Punctuation: "##" [4:23 - 4:25] preprocessing directive=
+// CHECK: Identifier: "Y" [4:25 - 4:26] preprocessing directive=
+// CHECK: Identifier: "NOTHING" [5:1 - 5:8] macro instantiation=NOTHING:1:9
+// CHECK: Punctuation: "(" [5:8 - 5:9]
+// CHECK: Identifier: "more" [5:9 - 5:13]
+// CHECK: Punctuation: "," [5:13 - 5:14]
+// CHECK: Identifier: "junk" [5:14 - 5:18]
+// CHECK: Punctuation: ")" [5:18 - 5:19]
+// CHECK: Keyword: "float" [5:20 - 5:25]
+// CHECK: Identifier: "WIBBLE" [5:26 - 5:32] macro instantiation=WIBBLE:4:9
+// CHECK: Punctuation: "(" [5:32 - 5:33]
+// CHECK: Keyword: "int" [5:33 - 5:36]
+// CHECK: Punctuation: "," [5:36 - 5:37]
+// CHECK: Keyword: "float" [5:38 - 5:43]
+// CHECK: Punctuation: ")" [5:43 - 5:44]
+// CHECK: Punctuation: ";" [5:44 - 5:45]
+// CHECK: Keyword: "int" [6:1 - 6:4]
+// CHECK: Identifier: "BAR" [6:5 - 6:8] macro instantiation=BAR:3:9
+// CHECK: Identifier: "STILL_NOTHING" [6:9 - 6:22] macro instantiation=STILL_NOTHING:2:9
+// CHECK: Punctuation: ";" [6:22 - 6:23]
+// CHECK: Punctuation: "#" [7:1 - 7:2] preprocessing directive=
+// CHECK: Identifier: "include" [7:2 - 7:9] preprocessing directive=
+// CHECK: Literal: ""foo.h"" [7:10 - 7:17] preprocessing directive=
+// CHECK: Punctuation: "#" [8:1 - 8:2] preprocessing directive=
+// CHECK: Identifier: "undef" [8:2 - 8:7] preprocessing directive=
+// CHECK: Identifier: "BAR" [8:8 - 8:11] preprocessing directive=
diff --git a/test/Index/annotate-tokens.c b/test/Index/annotate-tokens.c
new file mode 100644
index 0000000..7fbf9cc
--- /dev/null
+++ b/test/Index/annotate-tokens.c
@@ -0,0 +1,65 @@
+typedef int T;
+struct X { int a, b; };
+void f(void *ptr) {
+  T* t_ptr = (T *)ptr;
+  (void)sizeof(T);
+  /* A comment */
+  struct X x = (struct X){1, 2};
+  void *xx = ptr ? : &x;
+  const char * hello = "Hello";
+}
+
+// RUN: c-index-test -test-annotate-tokens=%s:4:1:9:32 %s | FileCheck %s
+// CHECK: Identifier: "T" [4:3 - 4:4] TypeRef=T:1:13
+// CHECK: Punctuation: "*" [4:4 - 4:5]
+// CHECK: Identifier: "t_ptr" [4:6 - 4:11] VarDecl=t_ptr:4:6 (Definition)
+// CHECK: Punctuation: "=" [4:12 - 4:13]
+// CHECK: Punctuation: "(" [4:14 - 4:15]
+// CHECK: Identifier: "T" [4:15 - 4:16] TypeRef=T:1:13
+// CHECK: Punctuation: "*" [4:17 - 4:18]
+// CHECK: Punctuation: ")" [4:18 - 4:19]
+// CHECK: Identifier: "ptr" [4:19 - 4:22] DeclRefExpr=ptr:3:14
+// CHECK: Punctuation: ";" [4:22 - 4:23]
+// CHECK: Punctuation: "(" [5:3 - 5:4]
+// CHECK: Keyword: "void" [5:4 - 5:8]
+// CHECK: Punctuation: ")" [5:8 - 5:9]
+// CHECK: Keyword: "sizeof" [5:9 - 5:15]
+// CHECK: Punctuation: "(" [5:15 - 5:16]
+// CHECK: Identifier: "T" [5:16 - 5:17] TypeRef=T:1:13
+// CHECK: Punctuation: ")" [5:17 - 5:18]
+// CHECK: Punctuation: ";" [5:18 - 5:19]
+// CHECK: Comment: "/* A comment */" [6:3 - 6:18]
+// CHECK: Keyword: "struct" [7:3 - 7:9]
+// CHECK: Identifier: "X" [7:10 - 7:11] TypeRef=struct X:2:8
+// CHECK: Identifier: "x" [7:12 - 7:13] VarDecl=x:7:12 (Definition)
+// CHECK: Punctuation: "=" [7:14 - 7:15]
+// CHECK: Punctuation: "(" [7:16 - 7:17]
+// CHECK: Keyword: "struct" [7:17 - 7:23]
+// CHECK: Identifier: "X" [7:24 - 7:25] TypeRef=struct X:2:8
+// CHECK: Punctuation: ")" [7:25 - 7:26]
+// CHECK: Punctuation: "{" [7:26 - 7:27]
+// CHECK: Literal: "1" [7:27 - 7:28]
+// CHECK: Punctuation: "," [7:28 - 7:29]
+// CHECK: Literal: "2" [7:30 - 7:31]
+// CHECK: Punctuation: "}" [7:31 - 7:32]
+// CHECK: Punctuation: ";" [7:32 - 7:33]
+// CHECK: Keyword: "void" [8:3 - 8:7]
+// CHECK: Punctuation: "*" [8:8 - 8:9]
+// CHECK: Identifier: "xx" [8:9 - 8:11] VarDecl=xx:8:9 (Definition)
+// CHECK: Punctuation: "=" [8:12 - 8:13]
+// CHECK: Identifier: "ptr" [8:14 - 8:17] DeclRefExpr=ptr:3:14
+// CHECK: Punctuation: "?" [8:18 - 8:19]
+// CHECK: Punctuation: ":" [8:20 - 8:21]
+// CHECK: Punctuation: "&" [8:22 - 8:23]
+// CHECK: Identifier: "x" [8:23 - 8:24] DeclRefExpr=x:7:12
+// CHECK: Punctuation: ";" [8:24 - 8:25]
+// CHECK: Keyword: "const" [9:3 - 9:8]
+// CHECK: Keyword: "char" [9:9 - 9:13]
+// CHECK: Punctuation: "*" [9:14 - 9:15]
+// CHECK: Identifier: "hello" [9:16 - 9:21] VarDecl=hello:9:16 (Definition)
+// CHECK: Punctuation: "=" [9:22 - 9:23]
+// CHECK: Literal: ""Hello"" [9:24 - 9:31]
+// CHECK: Punctuation: ";" [9:31 - 9:32]
+// CHECK: Punctuation: "}" [10:1 - 10:2]
+// RUN: c-index-test -test-annotate-tokens=%s:4:1:165:32 %s | FileCheck %s
+// RUN: c-index-test -test-annotate-tokens=%s:4:1:165:38 %s | FileCheck %s
diff --git a/test/Index/annotate-tokens.m b/test/Index/annotate-tokens.m
new file mode 100644
index 0000000..ce399d3
--- /dev/null
+++ b/test/Index/annotate-tokens.m
@@ -0,0 +1,59 @@
+@interface Foo
+- (int)compare:(Foo*)other;
+@end
+
+@implementation Foo
+- (int)compare:(Foo*)other {
+  return 0;
+  (void)@encode(Foo);
+}
+@end
+
+// RUN: c-index-test -test-annotate-tokens=%s:1:1:10:5 %s | FileCheck %s
+// CHECK: Punctuation: "@" [1:1 - 1:2]
+// CHECK: Identifier: "interface" [1:2 - 1:11]
+// CHECK: Identifier: "Foo" [1:12 - 1:15] ObjCInterfaceDecl=Foo:1:12
+// CHECK: Punctuation: "-" [2:1 - 2:2] ObjCInstanceMethodDecl=compare::2:1
+// CHECK: Punctuation: "(" [2:3 - 2:4]
+// CHECK: Keyword: "int" [2:4 - 2:7]
+// CHECK: Punctuation: ")" [2:7 - 2:8]
+// CHECK: Identifier: "compare" [2:8 - 2:15]
+// CHECK: Punctuation: ":" [2:15 - 2:16]
+// CHECK: Punctuation: "(" [2:16 - 2:17]
+// CHECK: Identifier: "Foo" [2:17 - 2:20] ObjCClassRef=Foo:1:12
+// CHECK: Punctuation: "*" [2:20 - 2:21]
+// CHECK: Punctuation: ")" [2:21 - 2:22]
+// CHECK: Identifier: "other" [2:22 - 2:27] ParmDecl=other:2:22 (Definition)
+// CHECK: Punctuation: ";" [2:27 - 2:28]
+// CHECK: Punctuation: "@" [3:1 - 3:2]
+// CHECK: Identifier: "end" [3:2 - 3:5]
+// CHECK: Punctuation: "@" [5:1 - 5:2] ObjCImplementationDecl=Foo:5:1 (Definition)
+// CHECK: Identifier: "implementation" [5:2 - 5:16]
+// CHECK: Identifier: "Foo" [5:17 - 5:20]
+// CHECK: Punctuation: "-" [6:1 - 6:2] ObjCInstanceMethodDecl=compare::6:1 (Definition)
+// CHECK: Punctuation: "(" [6:3 - 6:4]
+// CHECK: Keyword: "int" [6:4 - 6:7]
+// CHECK: Punctuation: ")" [6:7 - 6:8]
+// CHECK: Identifier: "compare" [6:8 - 6:15]
+// CHECK: Punctuation: ":" [6:15 - 6:16]
+// CHECK: Punctuation: "(" [6:16 - 6:17]
+// CHECK: Identifier: "Foo" [6:17 - 6:20] ObjCClassRef=Foo:1:12
+// CHECK: Punctuation: "*" [6:20 - 6:21]
+// CHECK: Punctuation: ")" [6:21 - 6:22]
+// CHECK: Identifier: "other" [6:22 - 6:27] ParmDecl=other:6:22 (Definition)
+// CHECK: Punctuation: "{" [6:28 - 6:29]
+// CHECK: Keyword: "return" [7:3 - 7:9]
+// CHECK: Literal: "0" [7:10 - 7:11]
+// CHECK: Punctuation: ";" [7:11 - 7:12]
+// CHECK: Punctuation: "(" [8:3 - 8:4]
+// CHECK: Keyword: "void" [8:4 - 8:8]
+// CHECK: Punctuation: ")" [8:8 - 8:9]
+// CHECK: Punctuation: "@" [8:9 - 8:10]
+// CHECK: Identifier: "encode" [8:10 - 8:16]
+// CHECK: Punctuation: "(" [8:16 - 8:17]
+// CHECK: Identifier: "Foo" [8:17 - 8:20] ObjCClassRef=Foo:1:12
+// CHECK: Punctuation: ")" [8:20 - 8:21]
+// CHECK: Punctuation: ";" [8:21 - 8:22]
+// CHECK: Punctuation: "}" [9:1 - 9:2]
+// CHECK: Punctuation: "@" [10:1 - 10:2]
+// CHECK: Identifier: "end" [10:2 - 10:5]
diff --git a/test/Index/c-index-api-loadTU-test.m b/test/Index/c-index-api-loadTU-test.m
new file mode 100644
index 0000000..5b2f86e
--- /dev/null
+++ b/test/Index/c-index-api-loadTU-test.m
@@ -0,0 +1,124 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fblocks -emit-pch -x objective-c %s -o %t.ast
+// RUN: c-index-test -test-load-tu %t.ast all | FileCheck %s
+
+@interface Foo 
+{
+  __attribute__((iboutlet)) id myoutlet;
+}
+- (void) __attribute__((ibaction)) myMessage:(id)msg;
+- foo;
++ fooC;
+
+@end
+
+@interface Bar : Foo 
+{
+}
+
+@end
+
+@interface Foo (FooCat)
+- (int) catMethodWithFloat:(float) fArg;
+- (float) floatMethod;
+@end
+
+@protocol Proto
+- pMethod;
+@end
+
+@protocol SubP <Proto>
+- spMethod;
+@end
+
+@interface Baz : Bar <SubP>
+{
+    int _anIVar;
+}
+
+- (Foo *) bazMethod;
+
+@end
+
+enum {
+  someEnum
+};
+
+int main (int argc, const char * argv[]) {
+	Baz * bee;
+	id a = [bee foo];
+	id <SubP> c = [Foo fooC];
+	id <Proto> d;
+	d = c;
+	[d pMethod];
+	[bee catMethodWithFloat:[bee floatMethod]];
+  main(someEnum, (const char **)bee);
+}
+
+// CHECK: c-index-api-loadTU-test.m:4:12: ObjCInterfaceDecl=Foo:4:12 Extent=[4:1 - 12:5]
+// CHECK: c-index-api-loadTU-test.m:6:32: ObjCIvarDecl=myoutlet:6:32 (Definition) Extent=[6:32 - 6:40]
+// CHECK: c-index-api-loadTU-test.m:6:32: attribute(iboutlet)= Extent=[6:32 - 6:40]
+// CHECK: c-index-api-loadTU-test.m:6:29: TypeRef=id:0:0 Extent=[6:29 - 6:31]
+// CHECK: c-index-api-loadTU-test.m:8:1: ObjCInstanceMethodDecl=myMessage::8:1 Extent=[8:1 - 8:54]
+// CHECK: c-index-api-loadTU-test.m:8:1: attribute(ibaction)= Extent=[8:1 - 8:54]
+// CHECK: c-index-api-loadTU-test.m:8:50: ParmDecl=msg:8:50 (Definition) Extent=[8:47 - 8:53]
+// CHECK: c-index-api-loadTU-test.m:8:47: TypeRef=id:0:0 Extent=[8:47 - 8:49]
+// CHECK: c-index-api-loadTU-test.m:9:1: ObjCInstanceMethodDecl=foo:9:1 Extent=[9:1 - 9:7]
+// CHECK: c-index-api-loadTU-test.m:10:1: ObjCClassMethodDecl=fooC:10:1 Extent=[10:1 - 10:8]
+// CHECK: c-index-api-loadTU-test.m:14:12: ObjCInterfaceDecl=Bar:14:12 Extent=[14:1 - 18:5]
+// CHECK: c-index-api-loadTU-test.m:14:18: ObjCSuperClassRef=Foo:4:12 Extent=[14:18 - 14:21]
+// CHECK: c-index-api-loadTU-test.m:20:12: ObjCCategoryDecl=FooCat:20:12 Extent=[20:1 - 23:5]
+// CHECK: c-index-api-loadTU-test.m:20:12: ObjCClassRef=Foo:4:12 Extent=[20:12 - 20:15]
+// CHECK: c-index-api-loadTU-test.m:21:1: ObjCInstanceMethodDecl=catMethodWithFloat::21:1 Extent=[21:1 - 21:41]
+// CHECK: c-index-api-loadTU-test.m:21:36: ParmDecl=fArg:21:36 (Definition) Extent=[21:29 - 21:40]
+// CHECK: c-index-api-loadTU-test.m:22:1: ObjCInstanceMethodDecl=floatMethod:22:1 Extent=[22:1 - 22:23]
+// CHECK: c-index-api-loadTU-test.m:25:1: ObjCProtocolDecl=Proto:25:1 (Definition) Extent=[25:1 - 27:5]
+// CHECK: c-index-api-loadTU-test.m:26:1: ObjCInstanceMethodDecl=pMethod:26:1 Extent=[26:1 - 26:11]
+// CHECK: c-index-api-loadTU-test.m:29:1: ObjCProtocolDecl=SubP:29:1 (Definition) Extent=[29:1 - 31:5]
+// CHECK: c-index-api-loadTU-test.m:29:17: ObjCProtocolRef=Proto:25:1 Extent=[29:17 - 29:22]
+// CHECK: c-index-api-loadTU-test.m:30:1: ObjCInstanceMethodDecl=spMethod:30:1 Extent=[30:1 - 30:12]
+// CHECK: c-index-api-loadTU-test.m:33:12: ObjCInterfaceDecl=Baz:33:12 Extent=[33:1 - 40:5]
+// CHECK: c-index-api-loadTU-test.m:33:18: ObjCSuperClassRef=Bar:14:12 Extent=[33:18 - 33:21]
+// CHECK: c-index-api-loadTU-test.m:33:23: ObjCProtocolRef=SubP:29:1 Extent=[33:23 - 33:27]
+// CHECK: c-index-api-loadTU-test.m:35:9: ObjCIvarDecl=_anIVar:35:9 (Definition) Extent=[35:9 - 35:16]
+// CHECK: c-index-api-loadTU-test.m:38:1: ObjCInstanceMethodDecl=bazMethod:38:1 Extent=[38:1 - 38:21]
+// CHECK: c-index-api-loadTU-test.m:42:1: EnumDecl=:42:1 (Definition) Extent=[42:1 - 44:2]
+// CHECK: c-index-api-loadTU-test.m:43:3: EnumConstantDecl=someEnum:43:3 (Definition) Extent=[43:3 - 43:11]
+// CHECK: c-index-api-loadTU-test.m:46:5: FunctionDecl=main:46:5 (Definition) Extent=[46:5 - 55:2]
+// CHECK: c-index-api-loadTU-test.m:46:15: ParmDecl=argc:46:15 (Definition) Extent=[46:11 - 46:19]
+// CHECK: c-index-api-loadTU-test.m:46:34: ParmDecl=argv:46:34 (Definition) Extent=[46:27 - 46:38]
+// CHECK: c-index-api-loadTU-test.m:46:5: UnexposedStmt= Extent=[46:42 - 55:2]
+// CHECK: c-index-api-loadTU-test.m:46:5: UnexposedStmt= Extent=[47:2 - 47:12]
+// CHECK: c-index-api-loadTU-test.m:47:8: VarDecl=bee:47:8 (Definition) Extent=[47:2 - 47:11]
+// CHECK: c-index-api-loadTU-test.m:47:2: ObjCClassRef=Baz:33:12 Extent=[47:2 - 47:5]
+// CHECK: c-index-api-loadTU-test.m:47:8: UnexposedStmt= Extent=[48:2 - 48:19]
+// CHECK: c-index-api-loadTU-test.m:48:5: VarDecl=a:48:5 (Definition) Extent=[48:2 - 48:18]
+// CHECK: c-index-api-loadTU-test.m:48:2: TypeRef=id:0:0 Extent=[48:2 - 48:4]
+// CHECK: c-index-api-loadTU-test.m:48:9: ObjCMessageExpr=foo:9:1 Extent=[48:9 - 48:18]
+// CHECK: c-index-api-loadTU-test.m:48:10: DeclRefExpr=bee:47:8 Extent=[48:10 - 48:13]
+// CHECK: c-index-api-loadTU-test.m:48:5: UnexposedStmt= Extent=[49:2 - 49:27]
+// CHECK: c-index-api-loadTU-test.m:49:12: VarDecl=c:49:12 (Definition) Extent=[49:2 - 49:26]
+// CHECK: c-index-api-loadTU-test.m:49:2: TypeRef=id:0:0 Extent=[49:2 - 49:4]
+// CHECK: c-index-api-loadTU-test.m:49:6: ObjCProtocolRef=SubP:29:1 Extent=[49:6 - 49:10]
+// CHECK: c-index-api-loadTU-test.m:49:16: UnexposedExpr=fooC:10:1 Extent=[49:16 - 49:26]
+// CHECK: c-index-api-loadTU-test.m:49:16: ObjCMessageExpr=fooC:10:1 Extent=[49:16 - 49:26]
+// CHECK: c-index-api-loadTU-test.m:49:12: UnexposedStmt= Extent=[50:2 - 50:15]
+// CHECK: c-index-api-loadTU-test.m:50:13: VarDecl=d:50:13 (Definition) Extent=[50:2 - 50:14]
+// CHECK: c-index-api-loadTU-test.m:50:2: TypeRef=id:0:0 Extent=[50:2 - 50:4]
+// CHECK: c-index-api-loadTU-test.m:50:6: ObjCProtocolRef=Proto:25:1 Extent=[50:6 - 50:11]
+// CHECK: c-index-api-loadTU-test.m:51:2: UnexposedExpr= Extent=[51:2 - 51:7]
+// CHECK: c-index-api-loadTU-test.m:51:2: DeclRefExpr=d:50:13 Extent=[51:2 - 51:3]
+// CHECK: c-index-api-loadTU-test.m:51:6: UnexposedExpr=c:49:12 Extent=[51:6 - 51:7]
+// CHECK: c-index-api-loadTU-test.m:51:6: DeclRefExpr=c:49:12 Extent=[51:6 - 51:7]
+// CHECK: c-index-api-loadTU-test.m:52:2: ObjCMessageExpr=pMethod:26:1 Extent=[52:2 - 52:13]
+// CHECK: c-index-api-loadTU-test.m:52:3: DeclRefExpr=d:50:13 Extent=[52:3 - 52:4]
+// CHECK: c-index-api-loadTU-test.m:53:2: ObjCMessageExpr=catMethodWithFloat::21:1 Extent=[53:2 - 53:44]
+// CHECK: c-index-api-loadTU-test.m:53:3: DeclRefExpr=bee:47:8 Extent=[53:3 - 53:6]
+// CHECK: c-index-api-loadTU-test.m:53:26: ObjCMessageExpr=floatMethod:22:1 Extent=[53:26 - 53:43]
+// CHECK: c-index-api-loadTU-test.m:53:27: DeclRefExpr=bee:47:8 Extent=[53:27 - 53:30]
+// CHECK: c-index-api-loadTU-test.m:54:3: CallExpr=main:46:5 Extent=[54:3 - 54:37]
+// CHECK: c-index-api-loadTU-test.m:54:3: UnexposedExpr=main:46:5 Extent=[54:3 - 54:7]
+// CHECK: c-index-api-loadTU-test.m:54:3: DeclRefExpr=main:46:5 Extent=[54:3 - 54:7]
+// CHECK: c-index-api-loadTU-test.m:54:8: DeclRefExpr=someEnum:43:3 Extent=[54:8 - 54:16]
+// CHECK: c-index-api-loadTU-test.m:54:18: UnexposedExpr=bee:47:8 Extent=[54:18 - 54:36]
+// CHECK: c-index-api-loadTU-test.m:54:33: DeclRefExpr=bee:47:8 Extent=[54:33 - 54:36]
+
diff --git a/test/Index/c-index-getCursor-pp.c b/test/Index/c-index-getCursor-pp.c
new file mode 100644
index 0000000..67fcfef
--- /dev/null
+++ b/test/Index/c-index-getCursor-pp.c
@@ -0,0 +1,18 @@
+#define OBSCURE(X) X
+#define DECORATION
+
+typedef int T;
+void OBSCURE(func)(int x) {
+  OBSCURE(T) DECORATION value;
+}
+
+// RUN: c-index-test -cursor-at=%s:1:11 %s | FileCheck -check-prefix=CHECK-1 %s
+// CHECK-1: macro definition=OBSCURE
+// RUN: c-index-test -cursor-at=%s:2:14 %s | FileCheck -check-prefix=CHECK-2 %s
+// CHECK-2: macro definition=DECORATION
+// RUN: c-index-test -cursor-at=%s:5:7 %s | FileCheck -check-prefix=CHECK-3 %s
+// CHECK-3: macro instantiation=OBSCURE:1:9
+// RUN: c-index-test -cursor-at=%s:6:6 %s | FileCheck -check-prefix=CHECK-4 %s
+// CHECK-4: macro instantiation=OBSCURE:1:9
+// RUN: c-index-test -cursor-at=%s:6:19 %s | FileCheck -check-prefix=CHECK-5 %s
+// CHECK-5: macro instantiation=DECORATION:2:9
diff --git a/test/Index/c-index-getCursor-test.m b/test/Index/c-index-getCursor-test.m
new file mode 100644
index 0000000..3cf1b6d
--- /dev/null
+++ b/test/Index/c-index-getCursor-test.m
@@ -0,0 +1,168 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fblocks -emit-pch -x objective-c %s -detailed-preprocessing-record -o %t.ast
+// RUN: c-index-test -test-file-scan %t.ast %s | FileCheck %s
+@interface Foo 
+{
+}
+
+- foo;
++ fooC;
+
+@end
+
+@interface Bar : Foo 
+{
+}
+
+@end
+
+@interface Foo (FooCat)
+- (int) catMethodWithFloat:(float) fArg;
+- (float) floatMethod;
+@end
+
+@protocol Proto
+- pMethod;
+@end
+
+@protocol SubP <Proto>
+- spMethod;
+@end
+
+@interface Baz : Bar <SubP>
+{
+    int _anIVar;
+}
+
+- (Foo *) bazMethod;
+
+@end
+
+enum {
+  someEnum
+};
+
+int main (int argc, const char * argv[]) {
+	Baz * bee;
+	id a = [bee foo];
+	id <SubP> c = [Foo fooC];
+	id <Proto> d;
+	d = c;
+	[d pMethod];
+	[bee catMethodWithFloat:[bee floatMethod]];
+  main(someEnum, (const char **)bee);
+}
+
+#define CONCAT(X, Y) X##Y
+
+void f() {
+   int CONCAT(my,_var);
+}
+#undef CONCAT
+
+// CHECK: [1:1 - 3:1] Invalid Cursor => NoDeclFound
+// CHECK: [3:1 - 7:1] ObjCInterfaceDecl=Foo:3:12
+// CHECK: [7:1 - 7:7] ObjCInstanceMethodDecl=foo:7:1
+// CHECK: [7:7 - 8:1] ObjCInterfaceDecl=Foo:3:12
+// CHECK: [8:1 - 8:8] ObjCClassMethodDecl=fooC:8:1
+// CHECK: [8:8 - 10:5] ObjCInterfaceDecl=Foo:3:12
+// CHECK: [10:5 - 12:1] Invalid Cursor => NoDeclFound
+// CHECK: [12:1 - 12:18] ObjCInterfaceDecl=Bar:12:12
+// CHECK: [12:18 - 12:21] ObjCSuperClassRef=Foo:3:12
+// CHECK: [12:21 - 16:5] ObjCInterfaceDecl=Bar:12:12
+// CHECK: [16:5 - 18:1] Invalid Cursor => NoDeclFound
+// CHECK: [18:1 - 18:12] ObjCCategoryDecl=FooCat:18:12
+// CHECK: [18:12 - 18:15] ObjCClassRef=Foo:3:12
+// CHECK: [18:15 - 19:1] ObjCCategoryDecl=FooCat:18:12
+// CHECK: [19:1 - 19:29] ObjCInstanceMethodDecl=catMethodWithFloat::19:1
+// CHECK: [19:29 - 19:40] ParmDecl=fArg:19:36 (Definition)
+// CHECK: [19:40 - 19:41] ObjCInstanceMethodDecl=catMethodWithFloat::19:1
+// CHECK: [19:41 - 20:1] ObjCCategoryDecl=FooCat:18:12
+// CHECK: [20:1 - 20:23] ObjCInstanceMethodDecl=floatMethod:20:1
+// CHECK: [20:23 - 21:5] ObjCCategoryDecl=FooCat:18:12
+// CHECK: [21:5 - 23:1] Invalid Cursor => NoDeclFound
+// CHECK: [23:1 - 24:1] ObjCProtocolDecl=Proto:23:1 (Definition)
+// CHECK: [24:1 - 24:11] ObjCInstanceMethodDecl=pMethod:24:1
+// CHECK: [24:11 - 25:5] ObjCProtocolDecl=Proto:23:1 (Definition)
+// CHECK: [25:5 - 27:1] Invalid Cursor => NoDeclFound
+// CHECK: [27:1 - 27:17] ObjCProtocolDecl=SubP:27:1 (Definition)
+// CHECK: [27:17 - 27:22] ObjCProtocolRef=Proto:23:1
+// CHECK: [27:22 - 28:1] ObjCProtocolDecl=SubP:27:1 (Definition)
+// CHECK: [28:1 - 28:12] ObjCInstanceMethodDecl=spMethod:28:1
+// CHECK: [28:12 - 29:5] ObjCProtocolDecl=SubP:27:1 (Definition)
+// CHECK: [29:5 - 31:1] Invalid Cursor => NoDeclFound
+// CHECK: [31:1 - 31:18] ObjCInterfaceDecl=Baz:31:12
+// CHECK: [31:18 - 31:21] ObjCSuperClassRef=Bar:12:12
+// CHECK: [31:21 - 31:23] ObjCInterfaceDecl=Baz:31:12
+// CHECK: [31:23 - 31:27] ObjCProtocolRef=SubP:27:1
+// CHECK: [31:27 - 33:9] ObjCInterfaceDecl=Baz:31:12
+// CHECK: [33:9 - 33:16] ObjCIvarDecl=_anIVar:33:9 (Definition)
+// CHECK: [33:16 - 36:1] ObjCInterfaceDecl=Baz:31:12
+// CHECK: [36:1 - 36:4] ObjCInstanceMethodDecl=bazMethod:36:1
+// CHECK: [36:4 - 36:7] ObjCClassRef=Foo:3:12
+// CHECK: [36:7 - 36:21] ObjCInstanceMethodDecl=bazMethod:36:1
+// CHECK: [36:21 - 38:5] ObjCInterfaceDecl=Baz:31:12
+// CHECK: [38:5 - 40:1] Invalid Cursor => NoDeclFound
+// CHECK: [40:1 - 41:3] EnumDecl=:40:1 (Definition)
+// CHECK: [41:3 - 41:11] EnumConstantDecl=someEnum:41:3 (Definition)
+// CHECK: [41:11 - 42:2] EnumDecl=:40:1 (Definition)
+// CHECK: [42:2 - 44:5] Invalid Cursor => NoDeclFound
+// CHECK: [44:5 - 44:11] FunctionDecl=main:44:5 (Definition)
+// CHECK: [44:11 - 44:19] ParmDecl=argc:44:15 (Definition)
+// CHECK: [44:19 - 44:27] FunctionDecl=main:44:5 (Definition)
+// CHECK: [44:27 - 44:38] ParmDecl=argv:44:34 (Definition)
+// CHECK: [44:38 - 44:42] FunctionDecl=main:44:5 (Definition)
+// CHECK: [44:42 - 45:2] UnexposedStmt=
+// CHECK: [45:2 - 45:5] ObjCClassRef=Baz:31:12
+// CHECK: [45:5 - 45:11] VarDecl=bee:45:8 (Definition)
+// CHECK: [45:11 - 45:12] UnexposedStmt=
+// CHECK: [45:12 - 46:2] UnexposedStmt=
+// CHECK: [46:2 - 46:4] TypeRef=id:0:0
+// CHECK: [46:4 - 46:9] VarDecl=a:46:5 (Definition)
+// CHECK: [46:9 - 46:10] ObjCMessageExpr=foo:7:1
+// CHECK: [46:10 - 46:13] DeclRefExpr=bee:45:8
+// CHECK: [46:13 - 46:18] ObjCMessageExpr=foo:7:1
+// CHECK: [46:18 - 46:19] UnexposedStmt=
+// CHECK: [46:19 - 47:2] UnexposedStmt=
+// CHECK: [47:2 - 47:4] TypeRef=id:0:0
+// CHECK: [47:4 - 47:6] VarDecl=c:47:12 (Definition)
+// CHECK: [47:6 - 47:10] ObjCProtocolRef=SubP:27:1
+// CHECK: [47:10 - 47:16] VarDecl=c:47:12 (Definition)
+// CHECK: [47:16 - 47:17] ObjCMessageExpr=fooC:8:1
+// CHECK: [47:17 - 47:20] ObjCClassRef=Foo:3:12
+// CHECK: [47:20 - 47:26] ObjCMessageExpr=fooC:8:1
+// CHECK: [47:26 - 47:27] UnexposedStmt=
+// CHECK: [47:27 - 48:2] UnexposedStmt=
+// CHECK: [48:2 - 48:4] TypeRef=id:0:0
+// CHECK: [48:4 - 48:6] VarDecl=d:48:13 (Definition)
+// CHECK: [48:6 - 48:11] ObjCProtocolRef=Proto:23:1
+// CHECK: [48:11 - 48:14] VarDecl=d:48:13 (Definition)
+// CHECK: [48:14 - 48:15] UnexposedStmt=
+// CHECK: [48:15 - 49:2] UnexposedStmt=
+// CHECK: [49:2 - 49:3] DeclRefExpr=d:48:13
+// CHECK: [49:3 - 49:6] UnexposedExpr=
+// CHECK: [49:6 - 49:7] DeclRefExpr=c:47:12
+// CHECK: [49:7 - 50:2] UnexposedStmt=
+// CHECK: [50:2 - 50:3] ObjCMessageExpr=pMethod:24:1
+// CHECK: [50:3 - 50:4] DeclRefExpr=d:48:13
+// CHECK: [50:4 - 50:13] ObjCMessageExpr=pMethod:24:1
+// CHECK: [50:13 - 51:2] UnexposedStmt=
+// CHECK: [51:2 - 51:3] ObjCMessageExpr=catMethodWithFloat::19:1
+// CHECK: [51:3 - 51:6] DeclRefExpr=bee:45:8
+// CHECK: [51:6 - 51:26] ObjCMessageExpr=catMethodWithFloat::19:1
+// CHECK: [51:26 - 51:27] ObjCMessageExpr=floatMethod:20:1
+// CHECK: [51:27 - 51:30] DeclRefExpr=bee:45:8
+// CHECK: [51:30 - 51:43] ObjCMessageExpr=floatMethod:20:1
+// CHECK: [51:43 - 51:44] ObjCMessageExpr=catMethodWithFloat::19:1
+// CHECK: [51:44 - 52:3] UnexposedStmt=
+// CHECK: [52:3 - 52:7] DeclRefExpr=main:44:5
+// CHECK: [52:7 - 52:8] CallExpr=main:44:5
+// CHECK: [52:8 - 52:16] DeclRefExpr=someEnum:41:3
+// CHECK: [52:16 - 52:18] CallExpr=main:44:5
+// CHECK: [52:18 - 52:33] UnexposedExpr=bee:45:8
+// CHECK: [52:33 - 52:36] DeclRefExpr=bee:45:8
+// CHECK: [52:36 - 52:37] CallExpr=main:44:5
+// CHECK: [52:37 - 53:2] UnexposedStmt=
+// CHECK: [55:9 - 55:26] macro definition=CONCAT
+// CHECK: [57:6 - 57:10] FunctionDecl=f:57:6 (Definition)
+// CHECK: [58:4 - 58:8] VarDecl=my_var:58:8 (Definition)
+// CHECK: [58:8 - 58:14] macro instantiation=CONCAT:55:9
diff --git a/test/Index/c-index-pch.c b/test/Index/c-index-pch.c
new file mode 100644
index 0000000..2037fc5
--- /dev/null
+++ b/test/Index/c-index-pch.c
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -emit-pch -x c -o %t.pch %S/Inputs/c-index-pch.h
+// RUN: %clang_cc1 -include-pch %t.pch -x c -emit-pch -o %t.ast %s
+// RUN: c-index-test -test-load-tu %t.ast all | FileCheck -check-prefix=ALL %s
+// RUN: c-index-test -test-load-tu %t.ast local | FileCheck -check-prefix=LOCAL %s
+// ALL: FunctionDecl=foo
+// ALL: VarDecl=bar
+// ALL: FunctionDecl=wibble
+// ALL: FunctionDecl=wonka
+// LOCAL-NOT: FunctionDecl=foo
+// LOCAL-NOT: VarDecl=bar
+// LOCAL: FunctionDecl=wibble
+// LOCAL: FunctionDecl=wonka
+void wibble(int i);
+void wonka(float);
diff --git a/test/Index/cindex-from-source.m b/test/Index/cindex-from-source.m
new file mode 100644
index 0000000..86e794d
--- /dev/null
+++ b/test/Index/cindex-from-source.m
@@ -0,0 +1,9 @@
+
+// RUN: %clang -x objective-c-header %S/Inputs/cindex-from-source.h -o %t.pfx.h.gch
+// RUN: c-index-test -test-load-source local %s -include %t.pfx.h > %t
+// RUN: FileCheck %s < %t
+// CHECK: cindex-from-source.m:{{.*}}:{{.*}}: StructDecl=s0:{{.*}}:{{.*}}
+// CHECK: cindex-from-source.m:{{.*}}:{{.*}}: VarDecl=g0:{{.*}}:{{.*}}
+// CHECK: cindex-from-source.m:9:1: TypeRef=t0:1:13 Extent=[9:1 - 9:3]
+struct s0 {};
+t0 g0;
diff --git a/test/Index/cindex-on-invalid.m b/test/Index/cindex-on-invalid.m
new file mode 100644
index 0000000..d2d952d
--- /dev/null
+++ b/test/Index/cindex-on-invalid.m
@@ -0,0 +1,6 @@
+// RUN: c-index-test -test-load-source local %s 2>&1 | FileCheck %s
+
+int foo;
+int
+
+// CHECK: cindex-on-invalid.m:6:70: error: expected identifier or '('
\ No newline at end of file
diff --git a/test/Index/cindex-test-inclusions.c b/test/Index/cindex-test-inclusions.c
new file mode 100644
index 0000000..9c7de2e
--- /dev/null
+++ b/test/Index/cindex-test-inclusions.c
@@ -0,0 +1,13 @@
+// RUN: c-index-test -test-inclusion-stack-source %s 2>&1 | FileCheck %s
+
+#include "include_test.h"
+
+// CHECK: cindex-test-inclusions.c
+// CHECK: included by:
+// CHECK: include_test.h
+// CHECK: included by:
+// CHECK: cindex-test-inclusions.c:3:10
+// CHECK: include_test_2.h
+// CHECK: included by:
+// CHECK: include_test.h:1:10
+// CHECK: cindex-test-inclusions.c:3:10
diff --git a/test/Index/code-complete-errors.c b/test/Index/code-complete-errors.c
new file mode 100644
index 0000000..29c2a86
--- /dev/null
+++ b/test/Index/code-complete-errors.c
@@ -0,0 +1,16 @@
+_Complex cd; // CHECK: code-complete-errors.c:1:1: warning: plain '_Complex' requires a type specifier; assuming '_Complex double'
+// CHECK: FIX-IT: Insert " double" at 1:9
+struct s {
+  int x, y;; // CHECK: code-complete-errors.c:4:12: warning: extra ';' inside a struct or union
+}; // CHECK: FIX-IT: Remove [4:12 - 4:13]
+
+struct s s0 = { y: 5 }; // CHECK: code-complete-errors.c:7:20: warning: use of GNU old-style field designator extension
+// CHECK: FIX-IT: Replace [7:17 - 7:19] with ".y = "
+int f(int *ptr1, float *ptr2) {
+  return ptr1 != ptr2; // CHECK: code-complete-errors.c:10:15:{10:10-10:14}{10:18-10:22}: warning: comparison of distinct pointer types ('int *' and 'float *')
+}
+
+void g() {  }
+
+// RUN: c-index-test -code-completion-at=%s:13:12 -pedantic %s 2> %t
+// RUN: FileCheck -check-prefix=CHECK %s < %t
diff --git a/test/Index/code-completion.cpp b/test/Index/code-completion.cpp
new file mode 100644
index 0000000..670b13f
--- /dev/null
+++ b/test/Index/code-completion.cpp
@@ -0,0 +1,54 @@
+// Code-completion through the C interface
+#include "nonexistent_header.h"
+struct X {
+  int member;
+  
+  enum E { Val1 };
+};
+
+struct Y {
+  float member;
+  void memfunc(int i = 17);
+};
+
+struct Z : X, Y {
+  double member;
+  operator int() const;
+};
+
+struct Z get_Z();
+
+void test_Z() {
+  // RUN: c-index-test -code-completion-at=%s:23:11 %s | FileCheck -check-prefix=CHECK-MEMBER %s
+  get_Z().member = 17;
+}
+
+
+float& overloaded(int i, long second);
+double& overloaded(float f, int second);
+int& overloaded(Z z, int second);
+                
+void test_overloaded() {
+  // RUN: c-index-test -code-completion-at=%s:33:18 %s | FileCheck -check-prefix=CHECK-OVERLOAD %s
+  overloaded(Z(), 0);
+}
+
+// CHECK-MEMBER: FieldDecl:{ResultType double}{TypedText member}
+// CHECK-MEMBER: FieldDecl:{ResultType int}{Text X::}{TypedText member}
+// CHECK-MEMBER: FieldDecl:{ResultType float}{Text Y::}{TypedText member}
+// CHECK-MEMBER: FunctionDecl:{ResultType void}{Informative Y::}{TypedText memfunc}{LeftParen (}{Optional {Placeholder int i}}{RightParen )}
+// CHECK-MEMBER: FunctionDecl:{ResultType int}{TypedText operator int}{LeftParen (}{RightParen )}{Informative  const}
+// CHECK-MEMBER: FunctionDecl:{ResultType Z &}{TypedText operator=}{LeftParen (}{Placeholder Z const &}{RightParen )}
+// CHECK-MEMBER: FunctionDecl:{ResultType X &}{Text X::}{TypedText operator=}{LeftParen (}{Placeholder X const &}{RightParen )}
+// CHECK-MEMBER: FunctionDecl:{ResultType Y &}{Text Y::}{TypedText operator=}{LeftParen (}{Placeholder Y const &}{RightParen )}
+// CHECK-MEMBER: EnumConstantDecl:{ResultType X::E}{Informative E::}{TypedText Val1}
+// CHECK-MEMBER: StructDecl:{TypedText X}{Text ::}
+// CHECK-MEMBER: StructDecl:{TypedText Y}{Text ::}
+// CHECK-MEMBER: StructDecl:{TypedText Z}{Text ::}
+// CHECK-MEMBER: FunctionDecl:{ResultType void}{Informative X::}{TypedText ~X}{LeftParen (}{RightParen )}
+// CHECK-MEMBER: FunctionDecl:{ResultType void}{Informative Y::}{TypedText ~Y}{LeftParen (}{RightParen )}
+// CHECK-MEMBER: FunctionDecl:{ResultType void}{TypedText ~Z}{LeftParen (}{RightParen )}
+
+// CHECK-OVERLOAD: NotImplemented:{ResultType int &}{Text overloaded}{LeftParen (}{Text Z z}{Comma , }{CurrentParameter int second}{RightParen )}
+// CHECK-OVERLOAD: NotImplemented:{ResultType float &}{Text overloaded}{LeftParen (}{Text int i}{Comma , }{CurrentParameter long second}{RightParen )}
+// CHECK-OVERLOAD: NotImplemented:{ResultType double &}{Text overloaded}{LeftParen (}{Text float f}{Comma , }{CurrentParameter int second}{RightParen )}
diff --git a/test/Index/complete-at-directives.m b/test/Index/complete-at-directives.m
new file mode 100644
index 0000000..811bca0
--- /dev/null
+++ b/test/Index/complete-at-directives.m
@@ -0,0 +1,59 @@
+/* Run lines are at the end, since line/column matter in this test. */
+@interface MyClass { @public }
+@end
+
+@implementation MyClass
+@end
+
+// RUN: c-index-test -code-completion-at=%s:2:2 %s | FileCheck -check-prefix=CHECK-CC1 %s
+// CHECK-CC1: {TypedText class}{HorizontalSpace  }{Placeholder identifier}
+// CHECK-CC1: {TypedText compatibility_alias}{HorizontalSpace  }{Placeholder alias}{HorizontalSpace  }{Placeholder class}
+// CHECK-CC1: {TypedText implementation}{HorizontalSpace  }{Placeholder class}
+// CHECK-CC1: {TypedText interface}{HorizontalSpace  }{Placeholder class}
+// CHECK-CC1: {TypedText protocol}{HorizontalSpace  }{Placeholder protocol}
+
+// RUN: c-index-test -code-completion-at=%s:3:2 %s | FileCheck -check-prefix=CHECK-CC2 %s
+// CHECK-CC2: {TypedText end}
+// CHECK-CC2: {TypedText optional}
+// CHECK-CC2: {TypedText property}
+// CHECK-CC2: {TypedText required}
+
+// RUN: c-index-test -code-completion-at=%s:6:2 %s | FileCheck -check-prefix=CHECK-CC3 %s
+// CHECK-CC3: {TypedText dynamic}{HorizontalSpace  }{Placeholder property}
+// CHECK-CC3: {TypedText end}
+// CHECK-CC3: {TypedText synthesize}{HorizontalSpace  }{Placeholder property}
+
+// RUN: c-index-test -code-completion-at=%s:2:1 %s | FileCheck -check-prefix=CHECK-CC4 %s
+// CHECK-CC4: NotImplemented:{TypedText @class}{HorizontalSpace  }{Placeholder identifier}
+// CHECK-CC4: NotImplemented:{TypedText @compatibility_alias}{HorizontalSpace  }{Placeholder alias}{HorizontalSpace  }{Placeholder class}
+// CHECK-CC4: NotImplemented:{TypedText @implementation}{HorizontalSpace  }{Placeholder class}
+// CHECK-CC4: NotImplemented:{TypedText @interface}{HorizontalSpace  }{Placeholder class}
+// CHECK-CC4: NotImplemented:{TypedText @protocol}{HorizontalSpace  }{Placeholder protocol}
+// CHECK-CC4: NotImplemented:{TypedText _Bool}
+// CHECK-CC4: TypedefDecl:{TypedText Class}
+// CHECK-CC4: TypedefDecl:{TypedText id}
+// CHECK-CC4: TypedefDecl:{TypedText SEL}
+
+// RUN: c-index-test -code-completion-at=%s:3:1 %s | FileCheck -check-prefix=CHECK-CC5 %s
+// CHECK-CC5: {TypedText @end}
+// CHECK-CC5: {TypedText @optional}
+// CHECK-CC5: {TypedText @property}
+// CHECK-CC5: {TypedText @required}
+// CHECK-CC5: NotImplemented:{TypedText _Bool}
+// CHECK-CC5: TypedefDecl:{TypedText Class}
+// CHECK-CC5: TypedefDecl:{TypedText id}
+// CHECK-CC5: ObjCInterfaceDecl:{TypedText MyClass}
+// CHECK-CC5: TypedefDecl:{TypedText SEL}
+
+// RUN: c-index-test -code-completion-at=%s:2:23 %s | FileCheck -check-prefix=CHECK-CC6 %s
+// CHECK-CC6: NotImplemented:{TypedText package}
+// CHECK-CC6: NotImplemented:{TypedText private}
+// CHECK-CC6: NotImplemented:{TypedText protected}
+// CHECK-CC6: NotImplemented:{TypedText public}
+
+// RUN: c-index-test -code-completion-at=%s:2:22 %s | FileCheck -check-prefix=CHECK-CC7 %s
+// CHECK-CC7: NotImplemented:{TypedText @package}
+// CHECK-CC7: NotImplemented:{TypedText @private}
+// CHECK-CC7: NotImplemented:{TypedText @protected}
+// CHECK-CC7: NotImplemented:{TypedText @public}
+// CHECK-CC7: NotImplemented:{TypedText _Bool}
diff --git a/test/Index/complete-at-exprstmt.m b/test/Index/complete-at-exprstmt.m
new file mode 100644
index 0000000..87e554f
--- /dev/null
+++ b/test/Index/complete-at-exprstmt.m
@@ -0,0 +1,37 @@
+/* The run lines are below, because this test is line- and
+   column-number sensitive. */
+@interface MyClass { int ivar; }
+- (int)myMethod:(int)arg;
+@end
+
+@implementation MyClass 
+- (int)myMethod:(int)arg {
+  @synchronized (@encode(MyClass)) { }
+}
+@end
+// RUN: c-index-test -code-completion-at=%s:9:4 %s | FileCheck -check-prefix=CHECK-CC1 %s
+// CHECK-CC1: {TypedText encode}{LeftParen (}{Placeholder type-name}{RightParen )}
+// CHECK-CC1: {TypedText protocol}{LeftParen (}{Placeholder protocol-name}{RightParen )}
+// CHECK-CC1: {TypedText selector}{LeftParen (}{Placeholder selector}{RightParen )}
+// CHECK-CC1: {TypedText synchronized}{HorizontalSpace  }{LeftParen (}{Placeholder expression}{RightParen )}{LeftBrace {}{Placeholder statements}{RightBrace }}
+// CHECK-CC1: {TypedText throw}{HorizontalSpace  }{Placeholder expression}
+// CHECK-CC1: {TypedText try}{LeftBrace {}{Placeholder statements}{RightBrace }}{Text @catch}{LeftParen (}{Placeholder parameter}{RightParen )}{LeftBrace {}{Placeholder statements}{RightBrace }}{Text @finally}{LeftBrace {}{Placeholder statements}{RightBrace }}
+// RUN: c-index-test -code-completion-at=%s:9:19 %s | FileCheck -check-prefix=CHECK-CC2 %s
+// CHECK-CC2: {TypedText encode}{LeftParen (}{Placeholder type-name}{RightParen )}
+// CHECK-CC2: {TypedText protocol}{LeftParen (}{Placeholder protocol-name}{RightParen )}
+// CHECK-CC2: {TypedText selector}{LeftParen (}{Placeholder selector}{RightParen )}
+// RUN: c-index-test -code-completion-at=%s:9:3 %s | FileCheck -check-prefix=CHECK-CC3 %s
+// CHECK-CC3: NotImplemented:{TypedText @encode}{LeftParen (}{Placeholder type-name}{RightParen )}
+// CHECK-CC3: NotImplemented:{TypedText @protocol}{LeftParen (}{Placeholder protocol-name}{RightParen )}
+// CHECK-CC3: NotImplemented:{TypedText @selector}{LeftParen (}{Placeholder selector}{RightParen )}
+// CHECK-CC3: NotImplemented:{TypedText @synchronized}{HorizontalSpace  }{LeftParen (}{Placeholder expression}{RightParen )}{LeftBrace {}{Placeholder statements}{RightBrace }}
+// CHECK-CC3: NotImplemented:{TypedText @throw}{HorizontalSpace  }{Placeholder expression}
+// CHECK-CC3: NotImplemented:{TypedText @try}{LeftBrace {}{Placeholder statements}{RightBrace }}{Text @catch}{LeftParen (}{Placeholder parameter}{RightParen )}{LeftBrace {}{Placeholder statements}{RightBrace }}{Text @finally}{LeftBrace {}{Placeholder statements}{RightBrace }}
+// CHECK-CC3: NotImplemented:{ResultType SEL}{TypedText _cmd}
+// CHECK-CC3: ParmDecl:{ResultType int}{TypedText arg}
+// CHECK-CC3: TypedefDecl:{TypedText Class}
+// CHECK-CC3: TypedefDecl:{TypedText id}
+// CHECK-CC3: ObjCIvarDecl:{ResultType int}{TypedText ivar}
+// CHECK-CC3: ObjCInterfaceDecl:{TypedText MyClass}
+// CHECK-CC3: TypedefDecl:{TypedText SEL}
+// CHECK-CC3: NotImplemented:{ResultType MyClass *}{TypedText self}
diff --git a/test/Index/complete-categories.m b/test/Index/complete-categories.m
new file mode 100644
index 0000000..92b14db
--- /dev/null
+++ b/test/Index/complete-categories.m
@@ -0,0 +1,39 @@
+/* Note: the RUN lines are near the end of the file, since line/column
+   matter for this test. */
+
+@interface I1 @end
+@interface I2 @end
+@interface I3 : I2 @end
+
+@interface I1(Cat1) @end
+@interface I1(Cat2) @end
+@interface I1(Cat3) @end
+
+@interface I2 (Cat2) @end
+@interface I2 (Cat3) @end
+@interface I2 (Cat2) @end
+@interface I3 (Cat1) @end
+@interface I3 (Cat2) @end
+
+@implementation I1(Cat2) @end
+@implementation I1(Cat3) @end
+@implementation I3(Cat2) @end
+
+// RUN: c-index-test -code-completion-at=%s:12:16 %s | FileCheck -check-prefix=CHECK-CC1 %s
+// CHECK-CC1: ObjCCategoryDecl:{TypedText Cat1}
+// CHECK-CC1: ObjCCategoryDecl:{TypedText Cat2}
+// CHECK-CC1: ObjCCategoryDecl:{TypedText Cat3}
+// RUN: c-index-test -code-completion-at=%s:13:16 %s | FileCheck -check-prefix=CHECK-CC2 %s
+// CHECK-CC2: ObjCCategoryDecl:{TypedText Cat1}
+// CHECK-CC2-NEXT: ObjCCategoryDecl:{TypedText Cat3}
+// RUN: c-index-test -code-completion-at=%s:18:20 %s | FileCheck -check-prefix=CHECK-CC3 %s
+// CHECK-CC3: ObjCCategoryDecl:{TypedText Cat1}
+// CHECK-CC3: ObjCCategoryDecl:{TypedText Cat2}
+// CHECK-CC3: ObjCCategoryDecl:{TypedText Cat3}
+// RUN: c-index-test -code-completion-at=%s:19:20 %s | FileCheck -check-prefix=CHECK-CC4 %s
+// CHECK-CC4: ObjCCategoryDecl:{TypedText Cat1}
+// CHECK-CC4-NEXT: ObjCCategoryDecl:{TypedText Cat3}
+// RUN: c-index-test -code-completion-at=%s:20:20 %s | FileCheck -check-prefix=CHECK-CC5 %s
+// CHECK-CC5: ObjCCategoryDecl:{TypedText Cat1}
+// CHECK-CC5-NEXT: ObjCCategoryDecl:{TypedText Cat2}
+// CHECK-CC5-NEXT: ObjCCategoryDecl:{TypedText Cat3}
diff --git a/test/Index/complete-enums.c b/test/Index/complete-enums.c
new file mode 100644
index 0000000..5e712a1
--- /dev/null
+++ b/test/Index/complete-enums.c
@@ -0,0 +1,15 @@
+// Note: the run lines follow their respective tests, since line/column
+// matter in this test.
+
+enum {
+  Red = 17,
+  Green,
+  Blue
+};
+
+void f() {
+  
+}
+
+// RUN: c-index-test -code-completion-at=%s:11:1 %s | FileCheck -check-prefix=CHECK-CC1 %s
+// CHECK-CC1: EnumConstantDecl:{ResultType enum <anonymous>}{TypedText Red}
diff --git a/test/Index/complete-exprs.c b/test/Index/complete-exprs.c
new file mode 100644
index 0000000..efc82f9
--- /dev/null
+++ b/test/Index/complete-exprs.c
@@ -0,0 +1,15 @@
+// Note: the run lines follow their respective tests, since line/column
+// matter in this test.
+
+int f(int);
+
+int test(int i, int j, int k, int l) {
+  return i | j | k & l;
+}
+
+// RUN: c-index-test -code-completion-at=%s:7:9 %s | FileCheck -check-prefix=CHECK-CC1 %s
+// CHECK-CC1: FunctionDecl:{ResultType int}{TypedText f}{LeftParen (}{Placeholder int}{RightParen )}
+// CHECK-CC1: NotImplemented:{TypedText sizeof}{LeftParen (}{Placeholder expression-or-type}{RightParen )}
+// RUN: c-index-test -code-completion-at=%s:7:14 %s | FileCheck -check-prefix=CHECK-CC1 %s
+// RUN: c-index-test -code-completion-at=%s:7:18 %s | FileCheck -check-prefix=CHECK-CC1 %s
+// RUN: c-index-test -code-completion-at=%s:7:22 %s | FileCheck -check-prefix=CHECK-CC1 %s
diff --git a/test/Index/complete-interfaces.m b/test/Index/complete-interfaces.m
new file mode 100644
index 0000000..229ec2d
--- /dev/null
+++ b/test/Index/complete-interfaces.m
@@ -0,0 +1,43 @@
+/* Note: the RUN lines are near the end of the file, since line/column
+   matter for this test. */
+
+@class Int1, Int2, Int3, Int4;
+
+@interface Int3 
+{
+}
+@end
+
+@interface Int2 : Int3
+{
+}
+@end
+
+@implementation Int2
+@end
+
+@implementation Int3
+@end
+
+// RUN: c-index-test -code-completion-at=%s:6:12 %s | FileCheck -check-prefix=CHECK-CC1 %s
+// CHECK-CC1: ObjCInterfaceDecl:{TypedText Int1}
+// CHECK-CC1: ObjCInterfaceDecl:{TypedText Int2}
+// CHECK-CC1: ObjCInterfaceDecl:{TypedText Int3}
+// CHECK-CC1: ObjCInterfaceDecl:{TypedText Int4}
+// RUN: c-index-test -code-completion-at=%s:11:12 %s | FileCheck -check-prefix=CHECK-CC2 %s
+// CHECK-CC2: ObjCInterfaceDecl:{TypedText Int1}
+// CHECK-CC2-NEXT: ObjCInterfaceDecl:{TypedText Int2}
+// CHECK-CC2-NEXT: ObjCInterfaceDecl:{TypedText Int4}
+// RUN: c-index-test -code-completion-at=%s:11:19 %s | FileCheck -check-prefix=CHECK-CC3 %s
+// CHECK-CC3: ObjCInterfaceDecl:{TypedText Int1}
+// CHECK-CC3-NEXT: ObjCInterfaceDecl:{TypedText Int3}
+// CHECK-CC3-NEXT: ObjCInterfaceDecl:{TypedText Int4}
+// RUN: c-index-test -code-completion-at=%s:16:17 %s | FileCheck -check-prefix=CHECK-CC4 %s
+// CHECK-CC4: ObjCInterfaceDecl:{TypedText Int1}
+// CHECK-CC4-NEXT: ObjCInterfaceDecl:{TypedText Int2}
+// CHECK-CC4-NEXT: ObjCInterfaceDecl:{TypedText Int3}
+// CHECK-CC4-NEXT: ObjCInterfaceDecl:{TypedText Int4}
+// RUN: c-index-test -code-completion-at=%s:19:17 %s | FileCheck -check-prefix=CHECK-CC5 %s
+// CHECK-CC5: ObjCInterfaceDecl:{TypedText Int1}
+// CHECK-CC5-NEXT: ObjCInterfaceDecl:{TypedText Int3}
+// CHECK-CC5-NEXT: ObjCInterfaceDecl:{TypedText Int4}
diff --git a/test/Index/complete-macros.c b/test/Index/complete-macros.c
new file mode 100644
index 0000000..c33d8c0
--- /dev/null
+++ b/test/Index/complete-macros.c
@@ -0,0 +1,11 @@
+// Note: the run lines follow their respective tests, since line/column
+// matter in this test.
+
+#define FOO(Arg1,Arg2) foobar
+
+void f() {
+
+}
+
+// RUN: c-index-test -code-completion-at=%s:7:1 %s | FileCheck -check-prefix=CHECK-CC1 %s
+// CHECK-CC1: macro definition:{TypedText FOO}{LeftParen (}{Placeholder Arg1}{Comma , }{Placeholder Arg2}{RightParen )}
diff --git a/test/Index/complete-member-access.m b/test/Index/complete-member-access.m
new file mode 100644
index 0000000..2502d77
--- /dev/null
+++ b/test/Index/complete-member-access.m
@@ -0,0 +1,30 @@
+/* Note: the RUN lines are near the end of the file, since line/column
+   matter for this test. */
+
+@protocol MyProtocol
+@property float ProtoProp;
+@end
+
+@interface Super {
+  int SuperIVar;
+}
+@end
+@interface Int : Super<MyProtocol>
+{
+  int IVar;
+}
+
+@property int prop1;
+@end
+
+void test_props(Int* ptr) {
+  ptr.prop1 = 0;
+  ptr->IVar = 0;
+}
+
+// RUN: c-index-test -code-completion-at=%s:21:7 %s | FileCheck -check-prefix=CHECK-CC1 %s
+// CHECK-CC1: ObjCPropertyDecl:{ResultType int}{TypedText prop1}
+// CHECK-CC1: ObjCPropertyDecl:{ResultType float}{TypedText ProtoProp}
+// RUN: c-index-test -code-completion-at=%s:22:8 %s | FileCheck -check-prefix=CHECK-CC2 %s
+// CHECK-CC2: ObjCIvarDecl:{ResultType int}{TypedText IVar}
+// CHECK-CC2: ObjCIvarDecl:{ResultType int}{TypedText SuperIVar}
diff --git a/test/Index/complete-method-decls.m b/test/Index/complete-method-decls.m
new file mode 100644
index 0000000..c18994e
--- /dev/null
+++ b/test/Index/complete-method-decls.m
@@ -0,0 +1,82 @@
+/* Note: the RUN lines are near the end of the file, since line/column
+   matter for this test. */
+
+@protocol P1
+- (id)abc;
+- (id)initWithInt:(int)x;
+- (id)initWithTwoInts:(int)x second:(int)y;
+- (int)getInt;
+- (id)getSelf;
+@end
+
+@protocol P2<P1>
++ (id)alloc;
+@end
+
+@interface A <P1>
+- (id)init;
+- (int)getValue;
+@end
+
+@interface B : A<P2>
+- (id)initWithInt:(int)x;
+- (int)getSecondValue;
+- (id)getSelf;
+- (int)setValue:(int)x;
+@end
+
+@interface B (FooBar)
+- (id)categoryFunction:(int)x;
+@end
+
+@implementation B
+- (int)getSecondValue { return 0; }
+- (id)init { return self; }
+- (id)getSelf { return self; }
+- (void)setValue:(int)x { }
+- (id)initWithTwoInts:(int)x second:(int)y { return self; }
++ (id)alloc { return 0; }
+@end
+
+@implementation B (FooBar)
+- (id)categoryFunction:(int)x { return self; }
+@end
+
+// RUN: c-index-test -code-completion-at=%s:17:3 %s | FileCheck -check-prefix=CHECK-CC1 %s
+// CHECK-CC1: NotImplemented:{LeftParen (}{Text id}{RightParen )}{TypedText abc}
+// CHECK-CC1: NotImplemented:{LeftParen (}{Text int}{RightParen )}{TypedText getInt}
+// CHECK-CC1: NotImplemented:{LeftParen (}{Text id}{RightParen )}{TypedText getSelf}
+// CHECK-CC1: NotImplemented:{LeftParen (}{Text id}{RightParen )}{TypedText initWithInt}{Colon :}{LeftParen (}{Text int}{RightParen )}{Text x}
+// CHECK-CC1: NotImplemented:{LeftParen (}{Text id}{RightParen )}{TypedText initWithTwoInts}{Colon :}{LeftParen (}{Text int}{RightParen )}{Text x}{HorizontalSpace  }{Text second}{Colon :}{LeftParen (}{Text int}{RightParen )}{Text y}
+// RUN: c-index-test -code-completion-at=%s:17:7 %s | FileCheck -check-prefix=CHECK-CC2 %s
+// CHECK-CC2: NotImplemented:{TypedText abc}
+// CHECK-CC2-NEXT: NotImplemented:{TypedText getSelf}
+// CHECK-CC2: NotImplemented:{TypedText initWithInt}{Colon :}{LeftParen (}{Text int}{RightParen )}{Text x}
+// CHECK-CC2: NotImplemented:{TypedText initWithTwoInts}{Colon :}{LeftParen (}{Text int}{RightParen )}{Text x}{HorizontalSpace  }{Text second}{Colon :}{LeftParen (}{Text int}{RightParen )}{Text y}
+// RUN: c-index-test -code-completion-at=%s:24:7 %s | FileCheck -check-prefix=CHECK-CC3 %s
+// CHECK-CC3: NotImplemented:{TypedText abc}
+// CHECK-CC3-NEXT: NotImplemented:{TypedText getSelf}
+// CHECK-CC3: NotImplemented:{TypedText init}
+// CHECK-CC3: NotImplemented:{TypedText initWithInt}{Colon :}{LeftParen (}{Text int}{RightParen )}{Text x}
+// CHECK-CC3: NotImplemented:{TypedText initWithTwoInts}{Colon :}{LeftParen (}{Text int}{RightParen )}{Text x}{HorizontalSpace  }{Text second}{Colon :}{LeftParen (}{Text int}{RightParen )}{Text y}
+// RUN: c-index-test -code-completion-at=%s:33:3 %s | FileCheck -check-prefix=CHECK-CC4 %s
+// CHECK-CC4: NotImplemented:{LeftParen (}{Text id}{RightParen )}{TypedText abc}{HorizontalSpace  }{LeftBrace {}{VerticalSpace
+// CHECK-CC4: NotImplemented:{LeftParen (}{Text int}{RightParen )}{TypedText getInt}{HorizontalSpace  }{LeftBrace {}{VerticalSpace
+// CHECK-CC4: NotImplemented:{LeftParen (}{Text int}{RightParen )}{TypedText getSecondValue}{HorizontalSpace  }{LeftBrace {}{VerticalSpace
+// CHECK-CC4: NotImplemented:{LeftParen (}{Text id}{RightParen )}{TypedText getSelf}{HorizontalSpace  }{LeftBrace {}{VerticalSpace
+// CHECK-CC4: NotImplemented:{LeftParen (}{Text id}{RightParen )}{TypedText initWithInt}{Colon :}{LeftParen (}{Text int}{RightParen )}{Text x}{HorizontalSpace  }{LeftBrace {}{VerticalSpace
+// CHECK-CC4: NotImplemented:{LeftParen (}{Text id}{RightParen )}{TypedText initWithTwoInts}{Colon :}{LeftParen (}{Text int}{RightParen )}{Text x}{HorizontalSpace  }{Text second}{Colon :}{LeftParen (}{Text int}{RightParen )}{Text y}{HorizontalSpace  }{LeftBrace {}{VerticalSpace
+// CHECK-CC4: NotImplemented:{LeftParen (}{Text int}{RightParen )}{TypedText setValue}{Colon :}{LeftParen (}{Text int}{RightParen )}{Text x}{HorizontalSpace  }{LeftBrace {}{VerticalSpace
+// RUN: c-index-test -code-completion-at=%s:33:8 %s | FileCheck -check-prefix=CHECK-CC5 %s
+// CHECK-CC5: NotImplemented:{TypedText getInt}{HorizontalSpace  }{LeftBrace {}{VerticalSpace
+// CHECK-CC5: NotImplemented:{TypedText getSecondValue}{HorizontalSpace  }{LeftBrace {}{VerticalSpace
+// CHECK-CC5-NOT: {TypedText getSelf}{HorizontalSpace  }{LeftBrace {}{VerticalSpace
+// CHECK-CC5: NotImplemented:{TypedText setValue}{Colon :}{LeftParen (}{Text int}{RightParen )}{Text x}{HorizontalSpace  }{LeftBrace {}{VerticalSpace
+// RUN: c-index-test -code-completion-at=%s:37:7 %s | FileCheck -check-prefix=CHECK-CC6 %s
+// CHECK-CC6: NotImplemented:{TypedText abc}{HorizontalSpace  }{LeftBrace {}{VerticalSpace 
+// CHECK-CC6-NOT: getSelf
+// CHECK-CC6: NotImplemented:{TypedText initWithInt}{Colon :}{LeftParen (}{Text int}{RightParen )}{Text x}{HorizontalSpace  }{LeftBrace {}{VerticalSpace 
+// CHECK-CC6: NotImplemented:{TypedText initWithTwoInts}{Colon :}{LeftParen (}{Text int}{RightParen )}{Text x}{HorizontalSpace  }{Text second}{Colon :}{LeftParen (}{Text int}{RightParen )}{Text y}{HorizontalSpace  }{LeftBrace {}{VerticalSpace 
+// RUN: c-index-test -code-completion-at=%s:42:3 %s | FileCheck -check-prefix=CHECK-CC7 %s
+// CHECK-CC7: NotImplemented:{LeftParen (}{Text id}{RightParen )}{TypedText categoryFunction}{Colon :}{LeftParen (}{Text int}{RightParen )}{Text x}{HorizontalSpace  }{LeftBrace {}{VerticalSpace 
+
diff --git a/test/Index/complete-objc-message-id.m b/test/Index/complete-objc-message-id.m
new file mode 100644
index 0000000..a75ee4a
--- /dev/null
+++ b/test/Index/complete-objc-message-id.m
@@ -0,0 +1,42 @@
+// Note: the run lines follow their respective tests, since line/column
+// matter in this test.
+
+@interface A
++ (id)alloc;
++ (id)init;
++ (id)new;
++ (Class)class;
++ (Class)superclass;
+- (id)retain;
+- (id)autorelease;
+- (id)superclass;
+@end
+
+@interface B : A
+- (int)B_method;
+@end
+
+@interface Unrelated
++ (id)icky;
+@end
+
+void message_id(B *b) {
+  [[A alloc] init];
+  [[b retain] B_method];
+  [[b superclass] B_method];
+}
+
+// RUN: c-index-test -code-completion-at=%s:24:14 %s | FileCheck -check-prefix=CHECK-CC1 %s
+// CHECK-CC1: ObjCInstanceMethodDecl:{ResultType id}{TypedText autorelease}
+// CHECK-CC1-NOT: B_method
+// CHECK-CC1: ObjCInstanceMethodDecl:{ResultType id}{TypedText retain}
+// RUN: c-index-test -code-completion-at=%s:25:15 %s | FileCheck -check-prefix=CHECK-CC2 %s
+// CHECK-CC2: ObjCInstanceMethodDecl:{ResultType id}{TypedText autorelease}
+// CHECK-CC2: ObjCInstanceMethodDecl:{ResultType int}{TypedText B_method}
+// CHECK-CC2: ObjCInstanceMethodDecl:{ResultType id}{TypedText retain}
+// RUN: c-index-test -code-completion-at=%s:26:19 %s | FileCheck -check-prefix=CHECK-CC3 %s
+// CHECK-CC3: ObjCInstanceMethodDecl:{ResultType id}{TypedText autorelease}
+// CHECK-CC3-NOT: B_method
+// CHECK-CC3: ObjCInstanceMethodDecl:{ResultType id}{TypedText retain}
+
+
diff --git a/test/Index/complete-objc-message.m b/test/Index/complete-objc-message.m
new file mode 100644
index 0000000..e65a056
--- /dev/null
+++ b/test/Index/complete-objc-message.m
@@ -0,0 +1,233 @@
+// Note: the run lines follow their respective tests, since line/column
+// matter in this test.
+
+@protocol FooTestProtocol
++ protocolClassMethod;
+- protocolInstanceMethod : (int)value;
+@end
+@interface Foo <FooTestProtocol> {
+  void *isa;
+}
++ (int)classMethod1:a withKeyword:(int)b;
++ (void)classMethod2;
++ new;
+- instanceMethod1;
+@end
+
+@interface Foo (FooTestCategory)
++ categoryClassMethod;
+- categoryInstanceMethod;
+@end
+
+void func() {
+  Foo *obj = [Foo new];
+  [obj xx];
+}
+
+@interface MyClass { }
++ (int)MyClassMethod:(id)obj;
+- (int)MyInstMethod:(id)x second:(id)y;
+@end
+
+@interface MySubClass : MyClass { }
++ (int)MySubClassMethod;
+- (int)MySubInstMethod;
+@end
+
+@implementation MyClass 
++ (int)MyClassMethod:(id)obj {
+  return 0;
+}
+
++ (int)MyPrivateMethod {
+  return 1;
+}
+
+- (int)MyInstMethod:(id)x second:(id)y {
+  return 2;
+}
+
+- (int)MyPrivateInstMethod {
+  return 3;
+}
+@end
+
+@implementation MySubClass
++ (int)MySubClassMethod {
+  return 2;
+}
+
++ (int)MySubPrivateMethod {
+  return [super MyPrivateMethod];
+}
+
+- (int)MySubInstMethod:(id)obj {
+  return [super MyInstMethod: obj second:obj];
+}
+
+- (int)MyInstMethod:(id)x second:(id)y {
+  return 3;
+}
+@end
+
+void test_super_var(MySubClass *super) {
+  [super MyInstMethod: super second:super];
+}
+
+@protocol FooTestProtocol2
+- (int)secondProtocolInstanceMethod;
+@end
+
+void test_qual_id(id<FooTestProtocol,FooTestProtocol2> ptr) {
+  [ptr protocolInstanceMethod:1];
+}
+
+@interface Overload
+- (int)Method:(int)i;
+- (int)Method;
+- (int)Method:(float)f Arg1:(int)i1 Arg2:(int)i2;
+- (int)Method:(float)f Arg1:(int)i1 OtherArg:(id)obj;
+- (int)Method:(float)f SomeArg:(int)i1 OtherArg:(id)obj;
+- (int)OtherMethod:(float)f Arg1:(int)i1 Arg2:(int)i2;
+@end
+
+void test_overload(Overload *ovl) {
+  [ovl Method:1 Arg1:1 OtherArg:ovl];
+}
+
+@interface Ellipsis
+- (int)Method:(int)i, ...;
+@end
+
+void f(Ellipsis *e) {
+  [e Method:1, 2, 3];
+}
+
+@interface Overload2
++ (int)Method:(int)i;
++ (int)Method;
++ (int)Method:(float)f Arg1:(int)i1 Arg2:(int)i2;
++ (int)Method:(float)f Arg1:(int)i1 OtherArg:(id)obj;
++ (int)Method:(float)f SomeArg:(int)i1 OtherArg:(id)obj;
++ (int)OtherMethod:(float)f Arg1:(int)i1 Arg2:(int)i2;
+@end
+
+void test_overload2(void) {
+  [Overload2 Method:1 Arg1:1 OtherArg:ovl];
+}
+
+void msg_id(id x) {
+  [x Method:1 Arg1:1 OtherArg:ovl];
+  [[x blarg] Method:1 Arg1:1 OtherArg:ovl];
+  [id Method:1 Arg1:1 OtherArg:ovl];
+}
+
+// RUN: c-index-test -code-completion-at=%s:23:19 %s | FileCheck -check-prefix=CHECK-CC1 %s
+// CHECK-CC1: {TypedText categoryClassMethod}
+// CHECK-CC1: {TypedText classMethod1:}{Placeholder (id)a}{HorizontalSpace  }{Text withKeyword:}{Placeholder (int)b}
+// CHECK-CC1: {TypedText classMethod2}
+// CHECK-CC1: {TypedText new}
+// CHECK-CC1: {TypedText protocolClassMethod}
+// RUN: c-index-test -code-completion-at=%s:24:8 %s | FileCheck -check-prefix=CHECK-CC2 %s
+// CHECK-CC2: {TypedText categoryInstanceMethod}
+// CHECK-CC2: {TypedText instanceMethod1}
+// CHECK-CC2: {TypedText protocolInstanceMethod:}{Placeholder (int)value}
+// RUN: c-index-test -code-completion-at=%s:61:16 %s | FileCheck -check-prefix=CHECK-CC3 %s
+// CHECK-CC3: ObjCClassMethodDecl:{ResultType int}{TypedText MyClassMethod:}{Placeholder (id)obj}
+// CHECK-CC3: ObjCClassMethodDecl:{ResultType int}{TypedText MyPrivateMethod}
+// RUN: c-index-test -code-completion-at=%s:65:16 %s | FileCheck -check-prefix=CHECK-CC4 %s
+// CHECK-CC4: ObjCInstanceMethodDecl:{ResultType int}{TypedText MyInstMethod:}{Placeholder (id)x}{HorizontalSpace  }{Text second:}{Placeholder (id)y}
+// CHECK-CC4: ObjCInstanceMethodDecl:{ResultType int}{TypedText MyPrivateInstMethod}
+// RUN: c-index-test -code-completion-at=%s:74:9 %s | FileCheck -check-prefix=CHECK-CC5 %s
+// CHECK-CC5: ObjCInstanceMethodDecl:{ResultType int}{TypedText MyInstMethod:}{Placeholder (id)x}{HorizontalSpace  }{Text second:}{Placeholder (id)y}
+// CHECK-CC5: ObjCInstanceMethodDecl:{ResultType int}{TypedText MySubInstMethod}
+// RUN: c-index-test -code-completion-at=%s:82:8 %s | FileCheck -check-prefix=CHECK-CC6 %s
+// CHECK-CC6: ObjCInstanceMethodDecl:{ResultType id}{TypedText protocolInstanceMethod:}{Placeholder (int)value}
+// CHECK-CC6: ObjCInstanceMethodDecl:{ResultType int}{TypedText secondProtocolInstanceMethod}
+// RUN: c-index-test -code-completion-at=%s:95:8 %s | FileCheck -check-prefix=CHECK-CC7 %s
+// CHECK-CC7: ObjCInstanceMethodDecl:{ResultType int}{TypedText Method}
+// CHECK-CC7: ObjCInstanceMethodDecl:{ResultType int}{TypedText Method:}{Placeholder (int)i}
+// CHECK-CC7: ObjCInstanceMethodDecl:{ResultType int}{TypedText Method:}{Placeholder (float)f}{HorizontalSpace  }{Text Arg1:}{Placeholder (int)i1}{HorizontalSpace  }{Text Arg2:}{Placeholder (int)i2}
+// CHECK-CC7: ObjCInstanceMethodDecl:{ResultType int}{TypedText Method:}{Placeholder (float)f}{HorizontalSpace  }{Text Arg1:}{Placeholder (int)i1}{HorizontalSpace  }{Text OtherArg:}{Placeholder (id)obj}
+// CHECK-CC7: ObjCInstanceMethodDecl:{ResultType int}{TypedText Method:}{Placeholder (float)f}{HorizontalSpace  }{Text SomeArg:}{Placeholder (int)i1}{HorizontalSpace  }{Text OtherArg:}{Placeholder (id)obj}
+// CHECK-CC7: ObjCInstanceMethodDecl:{ResultType int}{TypedText OtherMethod:}{Placeholder (float)f}{HorizontalSpace  }{Text Arg1:}{Placeholder (int)i1}{HorizontalSpace  }{Text Arg2:}{Placeholder (int)i2}
+// RUN: c-index-test -code-completion-at=%s:95:17 %s | FileCheck -check-prefix=CHECK-CC8 %s
+// CHECK-CC8: ObjCInstanceMethodDecl:{ResultType int}{Informative Method:}{TypedText }
+// CHECK-CC8: ObjCInstanceMethodDecl:{ResultType int}{Informative Method:}{TypedText Arg1:}{Placeholder (int)i1}{HorizontalSpace  }{Text Arg2:}{Placeholder (int)i2}
+// CHECK-CC8: ObjCInstanceMethodDecl:{ResultType int}{Informative Method:}{TypedText Arg1:}{Placeholder (int)i1}{HorizontalSpace  }{Text OtherArg:}{Placeholder (id)obj}
+// CHECK-CC8: ObjCInstanceMethodDecl:{ResultType int}{Informative Method:}{TypedText SomeArg:}{Placeholder (int)i1}{HorizontalSpace  }{Text OtherArg:}{Placeholder (id)obj}
+// RUN: c-index-test -code-completion-at=%s:95:24 %s | FileCheck -check-prefix=CHECK-CC9 %s
+// CHECK-CC9: ObjCInstanceMethodDecl:{ResultType int}{Informative Method:}{Informative Arg1:}{TypedText Arg2:}{Placeholder (int)i2}
+// CHECK-CC9: ObjCInstanceMethodDecl:{ResultType int}{Informative Method:}{Informative Arg1:}{TypedText OtherArg:}{Placeholder (id)obj}
+// RUN: c-index-test -code-completion-at=%s:61:11 %s | FileCheck -check-prefix=CHECK-CCA %s
+// CHECK-CCA: {ResultType SEL}{TypedText _cmd}
+// CHECK-CCA: TypedefDecl:{TypedText Class}
+// CHECK-CCA: ObjCInterfaceDecl:{TypedText Foo}
+// CHECK-CCA: FunctionDecl:{ResultType void}{TypedText func}{LeftParen (}{RightParen )}
+// CHECK-CCA: TypedefDecl:{TypedText id}
+// CHECK-CCA: ObjCInterfaceDecl:{TypedText MyClass}
+// CHECK-CCA: ObjCInterfaceDecl:{TypedText MySubClass}
+// CHECK-CCA: TypedefDecl:{TypedText SEL}
+// CHECK-CCA: {ResultType Class}{TypedText self}
+// CHECK-CCA: {TypedText super}
+// RUN: c-index-test -code-completion-at=%s:103:6 %s | FileCheck -check-prefix=CHECK-CCB %s
+// CHECK-CCB: ObjCInstanceMethodDecl:{ResultType int}{TypedText Method:}{Placeholder (int)i}{Placeholder , ...}
+// RUN: c-index-test -code-completion-at=%s:116:14 %s | FileCheck -check-prefix=CHECK-CCC %s
+// CHECK-CCC: ObjCClassMethodDecl:{ResultType int}{TypedText Method}
+// CHECK-CCC: ObjCClassMethodDecl:{ResultType int}{TypedText Method:}{Placeholder (int)i}
+// CHECK-CCC: ObjCClassMethodDecl:{ResultType int}{TypedText Method:}{Placeholder (float)f}{HorizontalSpace  }{Text Arg1:}{Placeholder (int)i1}{HorizontalSpace  }{Text Arg2:}{Placeholder (int)i2}
+// CHECK-CCC: ObjCClassMethodDecl:{ResultType int}{TypedText Method:}{Placeholder (float)f}{HorizontalSpace  }{Text Arg1:}{Placeholder (int)i1}{HorizontalSpace  }{Text OtherArg:}{Placeholder (id)obj}
+// CHECK-CCC: ObjCClassMethodDecl:{ResultType int}{TypedText Method:}{Placeholder (float)f}{HorizontalSpace  }{Text SomeArg:}{Placeholder (int)i1}{HorizontalSpace  }{Text OtherArg:}{Placeholder (id)obj}
+// CHECK-CCC: ObjCClassMethodDecl:{ResultType int}{TypedText OtherMethod:}{Placeholder (float)f}{HorizontalSpace  }{Text Arg1:}{Placeholder (int)i1}{HorizontalSpace  }{Text Arg2:}{Placeholder (int)i2}
+// RUN: c-index-test -code-completion-at=%s:116:23 %s | FileCheck -check-prefix=CHECK-CCD %s
+// CHECK-CCD: ObjCClassMethodDecl:{ResultType int}{Informative Method:}{TypedText }
+// CHECK-CCD: ObjCClassMethodDecl:{ResultType int}{Informative Method:}{TypedText Arg1:}{Placeholder (int)i1}{HorizontalSpace  }{Text Arg2:}{Placeholder (int)i2}
+// CHECK-CCD: ObjCClassMethodDecl:{ResultType int}{Informative Method:}{TypedText Arg1:}{Placeholder (int)i1}{HorizontalSpace  }{Text OtherArg:}{Placeholder (id)obj}
+// CHECK-CCD: ObjCClassMethodDecl:{ResultType int}{Informative Method:}{TypedText SomeArg:}{Placeholder (int)i1}{HorizontalSpace  }{Text OtherArg:}{Placeholder (id)obj}
+// RUN: c-index-test -code-completion-at=%s:116:30 %s | FileCheck -check-prefix=CHECK-CCE %s
+// CHECK-CCE: ObjCClassMethodDecl:{ResultType int}{Informative Method:}{Informative Arg1:}{TypedText Arg2:}{Placeholder (int)i2}
+// CHECK-CCE: ObjCClassMethodDecl:{ResultType int}{Informative Method:}{Informative Arg1:}{TypedText OtherArg:}{Placeholder (id)obj}
+// RUN: c-index-test -code-completion-at=%s:61:11 %s | FileCheck -check-prefix=CHECK-CCF %s
+// CHECK-CCF: {ResultType SEL}{TypedText _cmd}
+// CHECK-CCF: TypedefDecl:{TypedText Class}
+// CHECK-CCF: ObjCInterfaceDecl:{TypedText Foo}
+// CHECK-CCF: FunctionDecl:{ResultType void}{TypedText func}{LeftParen (}{RightParen )}
+// CHECK-CCF: TypedefDecl:{TypedText id}
+// CHECK-CCF: ObjCInterfaceDecl:{TypedText MyClass}
+// CHECK-CCF: ObjCInterfaceDecl:{TypedText MySubClass}
+// CHECK-CCF: TypedefDecl:{TypedText SEL}
+// CHECK-CCF: {ResultType Class}{TypedText self}
+// CHECK-CCF: {TypedText super}
+// RUN: c-index-test -code-completion-at=%s:120:6 %s | FileCheck -check-prefix=CHECK-CCG %s
+// CHECK-CCG: ObjCInstanceMethodDecl:{ResultType id}{TypedText categoryInstanceMethod}
+// CHECK-CCG: ObjCInstanceMethodDecl:{ResultType id}{TypedText instanceMethod1}
+// CHECK-CCG: ObjCInstanceMethodDecl:{ResultType int}{TypedText Method}
+// CHECK-CCG: ObjCInstanceMethodDecl:{ResultType int}{TypedText Method:}{Placeholder (int)i}
+// CHECK-CCG: ObjCInstanceMethodDecl:{ResultType int}{TypedText Method:}{Placeholder (float)f}{HorizontalSpace  }{Text Arg1:}{Placeholder (int)i1}{HorizontalSpace  }{Text Arg2:}{Placeholder (int)i2}
+// CHECK-CCG: ObjCInstanceMethodDecl:{ResultType int}{TypedText Method:}{Placeholder (float)f}{HorizontalSpace  }{Text Arg1:}{Placeholder (int)i1}{HorizontalSpace  }{Text OtherArg:}{Placeholder (id)obj}
+// CHECK-CCG: ObjCInstanceMethodDecl:{ResultType int}{TypedText Method:}{Placeholder (float)f}{HorizontalSpace  }{Text SomeArg:}{Placeholder (int)i1}{HorizontalSpace  }{Text OtherArg:}{Placeholder (id)obj}
+// CHECK-CCG: ObjCInstanceMethodDecl:{ResultType int}{TypedText MyInstMethod:}{Placeholder (id)x}{HorizontalSpace  }{Text second:}{Placeholder (id)y}
+// CHECK-CCG: ObjCInstanceMethodDecl:{ResultType int}{TypedText MyPrivateInstMethod}
+// CHECK-CCG: ObjCInstanceMethodDecl:{ResultType int}{TypedText MySubInstMethod}
+// CHECK-CCG: ObjCInstanceMethodDecl:{ResultType int}{TypedText MySubInstMethod:}{Placeholder (id)obj}
+// CHECK-CCG: ObjCInstanceMethodDecl:{ResultType int}{TypedText OtherMethod:}{Placeholder (float)f}{HorizontalSpace  }{Text Arg1:}{Placeholder (int)i1}{HorizontalSpace  }{Text Arg2:}{Placeholder (int)i2}
+// CHECK-CCG: ObjCInstanceMethodDecl:{ResultType id}{TypedText protocolInstanceMethod:}{Placeholder (int)value}
+// CHECK-CCG: ObjCInstanceMethodDecl:{ResultType int}{TypedText secondProtocolInstanceMethod}
+// RUN: c-index-test -code-completion-at=%s:121:14 %s | FileCheck -check-prefix=CHECK-CCG %s
+// RUN: c-index-test -code-completion-at=%s:122:7 %s | FileCheck -check-prefix=CHECK-CCH %s
+// CHECK-CCH: ObjCClassMethodDecl:{ResultType id}{TypedText categoryClassMethod}
+// CHECK-CCH: ObjCClassMethodDecl:{ResultType int}{TypedText classMethod1:}{Placeholder (id)a}{HorizontalSpace  }{Text withKeyword:}{Placeholder (int)b}
+// CHECK-CCH: ObjCClassMethodDecl:{ResultType void}{TypedText classMethod2}
+// CHECK-CCH: ObjCClassMethodDecl:{ResultType int}{TypedText Method}
+// CHECK-CCH: ObjCClassMethodDecl:{ResultType int}{TypedText Method:}{Placeholder (int)i}
+// CHECK-CCH: ObjCClassMethodDecl:{ResultType int}{TypedText Method:}{Placeholder (float)f}{HorizontalSpace  }{Text Arg1:}{Placeholder (int)i1}{HorizontalSpace  }{Text Arg2:}{Placeholder (int)i2}
+// CHECK-CCH: ObjCClassMethodDecl:{ResultType int}{TypedText Method:}{Placeholder (float)f}{HorizontalSpace  }{Text Arg1:}{Placeholder (int)i1}{HorizontalSpace  }{Text OtherArg:}{Placeholder (id)obj}
+// CHECK-CCH: ObjCClassMethodDecl:{ResultType int}{TypedText Method:}{Placeholder (float)f}{HorizontalSpace  }{Text SomeArg:}{Placeholder (int)i1}{HorizontalSpace  }{Text OtherArg:}{Placeholder (id)obj}
+// CHECK-CCH: ObjCClassMethodDecl:{ResultType int}{TypedText MyClassMethod:}{Placeholder (id)obj}
+// CHECK-CCH: ObjCClassMethodDecl:{ResultType int}{TypedText MyPrivateMethod}
+// CHECK-CCH: ObjCClassMethodDecl:{ResultType int}{TypedText MySubClassMethod}
+// CHECK-CCH: ObjCClassMethodDecl:{ResultType int}{TypedText MySubPrivateMethod}
+// CHECK-CCH: ObjCClassMethodDecl:{ResultType id}{TypedText new}
+// CHECK-CCH: ObjCClassMethodDecl:{ResultType int}{TypedText OtherMethod:}{Placeholder (float)f}{HorizontalSpace  }{Text Arg1:}{Placeholder (int)i1}{HorizontalSpace  }{Text Arg2:}{Placeholder (int)i2}
+// CHECK-CCH: ObjCClassMethodDecl:{ResultType id}{TypedText protocolClassMethod}
+
diff --git a/test/Index/complete-pch.m b/test/Index/complete-pch.m
new file mode 100644
index 0000000..09192ae
--- /dev/null
+++ b/test/Index/complete-pch.m
@@ -0,0 +1,26 @@
+// Note: the run lines follow their respective tests, since line/column
+// matter in this test.
+
+@interface C
+- (int)instanceMethod3:(int)x;
++ (int)classMethod3:(float)f;
+@end
+
+void msg_id(id x) {
+  [id classMethod1:1.0];
+  [x instanceMethod1:5];
+}
+
+// Build the precompiled header
+// RUN: %clang -x objective-c-header -o %t.h.pch %S/Inputs/complete-pch.h
+
+// Run the actual tests
+// RUN: c-index-test -code-completion-at=%s:10:7 -include %t.h %s | FileCheck -check-prefix=CHECK-CC1 %s
+// CHECK-CC1: ObjCClassMethodDecl:{ResultType int}{TypedText classMethod1:}{Placeholder (double)d}
+// CHECK-CC1: ObjCClassMethodDecl:{ResultType int}{TypedText classMethod2:}{Placeholder (float)f}
+// CHECK-CC1: ObjCClassMethodDecl:{ResultType int}{TypedText classMethod3:}{Placeholder (float)f}
+
+// RUN: c-index-test -code-completion-at=%s:11:6 -include %t.h %s | FileCheck -check-prefix=CHECK-CC2 %s
+// CHECK-CC2: ObjCInstanceMethodDecl:{ResultType int}{TypedText instanceMethod1:}{Placeholder (int)x}
+// CHECK-CC2: ObjCInstanceMethodDecl:{ResultType int}{TypedText instanceMethod2:}{Placeholder (int)x}
+// CHECK-CC2: ObjCInstanceMethodDecl:{ResultType int}{TypedText instanceMethod3:}{Placeholder (int)x}
diff --git a/test/Index/complete-properties.m b/test/Index/complete-properties.m
new file mode 100644
index 0000000..80e10e7
--- /dev/null
+++ b/test/Index/complete-properties.m
@@ -0,0 +1,40 @@
+/* Note: the RUN lines are near the end of the file, since line/column
+ matter for this test. */
+
+@interface I1 
+{
+  id StoredProp3;
+  int RandomIVar;
+}
+@property int Prop0;
+@property int Prop1;
+@property float Prop2;
+@end
+
+@interface I2 : I1
+@property id Prop3;
+@property id Prop4;
+@end
+
+@implementation I2
+@synthesize Prop2, Prop1, Prop3 = StoredProp3;
+@dynamic Prop4;
+@end
+
+// RUN: c-index-test -code-completion-at=%s:20:13 %s | FileCheck -check-prefix=CHECK-CC1 %s
+// CHECK-CC1: ObjCPropertyDecl:{ResultType int}{TypedText Prop0}
+// CHECK-CC1: ObjCPropertyDecl:{ResultType int}{TypedText Prop1}
+// CHECK-CC1: ObjCPropertyDecl:{ResultType float}{TypedText Prop2}
+// CHECK-CC1: ObjCPropertyDecl:{ResultType id}{TypedText Prop3}
+// CHECK-CC1: ObjCPropertyDecl:{ResultType id}{TypedText Prop4}
+// RUN: c-index-test -code-completion-at=%s:20:20 %s | FileCheck -check-prefix=CHECK-CC2 %s
+// CHECK-CC2: ObjCPropertyDecl:{ResultType int}{TypedText Prop0}
+// CHECK-CC2: ObjCPropertyDecl:{ResultType int}{TypedText Prop1}
+// CHECK-CC2-NEXT: ObjCPropertyDecl:{ResultType id}{TypedText Prop3}
+// CHECK-CC2: ObjCPropertyDecl:{ResultType id}{TypedText Prop4}
+// RUN: c-index-test -code-completion-at=%s:20:35 %s | FileCheck -check-prefix=CHECK-CC3 %s
+// CHECK-CC3: ObjCIvarDecl:{ResultType int}{TypedText RandomIVar}
+// CHECK-CC3: ObjCIvarDecl:{ResultType id}{TypedText StoredProp3}
+// RUN: c-index-test -code-completion-at=%s:21:10 %s | FileCheck -check-prefix=CHECK-CC4 %s
+// CHECK-CC4: ObjCPropertyDecl:{ResultType int}{TypedText Prop0}
+// CHECK-CC4-NEXT: ObjCPropertyDecl:{ResultType id}{TypedText Prop4}
diff --git a/test/Index/complete-property-flags.m b/test/Index/complete-property-flags.m
new file mode 100644
index 0000000..cd3696f
--- /dev/null
+++ b/test/Index/complete-property-flags.m
@@ -0,0 +1,23 @@
+// Note: the run lines follow their respective tests, since line/column
+// matter in this test.
+
+@interface Foo  {
+  void *isa;
+}
+@property(copy) Foo *myprop;
+@property(retain, nonatomic) id xx;
+// RUN: c-index-test -code-completion-at=%s:7:11 %s | FileCheck -check-prefix=CHECK-CC1 %s
+// CHECK-CC1: {TypedText assign}
+// CHECK-CC1-NEXT: {TypedText copy}
+// CHECK-CC1-NEXT: {TypedText getter}{Text  = }{Placeholder method}
+// CHECK-CC1-NEXT: {TypedText nonatomic}
+// CHECK-CC1-NEXT: {TypedText readonly}
+// CHECK-CC1-NEXT: {TypedText readwrite}
+// CHECK-CC1-NEXT: {TypedText retain}
+// CHECK-CC1-NEXT: {TypedText setter}{Text  = }{Placeholder method}
+// RUN: c-index-test -code-completion-at=%s:8:18 %s | FileCheck -check-prefix=CHECK-CC2 %s
+// CHECK-CC2: {TypedText getter}{Text  = }{Placeholder method}
+// CHECK-CC2-NEXT: {TypedText nonatomic}
+// CHECK-CC2-NEXT: {TypedText readwrite}
+// CHECK-CC2-NEXT: {TypedText setter}{Text  = }{Placeholder method}
+@end
diff --git a/test/Index/complete-property-getset.m b/test/Index/complete-property-getset.m
new file mode 100644
index 0000000..f4424ce
--- /dev/null
+++ b/test/Index/complete-property-getset.m
@@ -0,0 +1,41 @@
+// Note: the run lines follow their respective tests, since line/column
+// matter in this test.
+
+@interface Super { }
+- (int)getter1;
++ (int)getter2_not_instance;
+- (int)getter2_not:(int)x;
+- (int)getter3;
+- (void)setter1:(int)x;
++ (void)setter2_not_inst:(int)x;
++ (void)setter2_many_args:(int)x second:(int)y;
+- (void)setter3:(int)y;
+@property (getter = getter1, setter = setter1:) int blah;
+@end
+
+@interface Sub : Super { }
+- (int)getter4;
+- (void)setter4:(int)x;
+@property (getter = getter4, setter = setter1:) int blarg;
+@end
+
+// RUN: c-index-test -code-completion-at=%s:13:21 %s | FileCheck -check-prefix=CHECK-CC1 %s
+// CHECK-CC1: ObjCInstanceMethodDecl:{ResultType int}{TypedText getter1}
+// CHECK-CC1-NOT: getter2
+// CHECK-CC1: ObjCInstanceMethodDecl:{ResultType int}{TypedText getter3}
+// RUN: c-index-test -code-completion-at=%s:13:39 %s | FileCheck -check-prefix=CHECK-CC2 %s
+// CHECK-CC2: ObjCInstanceMethodDecl:{ResultType int}{TypedText getter2_not:}
+// CHECK-CC2: ObjCInstanceMethodDecl:{ResultType void}{TypedText setter1:}
+// CHECK-CC2-NOT: setter2
+// CHECK-CC2: ObjCInstanceMethodDecl:{ResultType void}{TypedText setter3:}
+// RUN: c-index-test -code-completion-at=%s:19:21 %s | FileCheck -check-prefix=CHECK-CC3 %s
+// CHECK-CC3: ObjCInstanceMethodDecl:{ResultType int}{TypedText getter1}
+// CHECK-CC3-NOT: getter2
+// CHECK-CC3: ObjCInstanceMethodDecl:{ResultType int}{TypedText getter3}
+// CHECK-CC3: ObjCInstanceMethodDecl:{ResultType int}{TypedText getter4}
+// RUN: c-index-test -code-completion-at=%s:19:39 %s | FileCheck -check-prefix=CHECK-CC4 %s
+// CHECK-CC4: ObjCInstanceMethodDecl:{ResultType int}{TypedText getter2_not:}{Informative (int)x}
+// CHECK-CC4: ObjCInstanceMethodDecl:{ResultType void}{TypedText setter1:}{Informative (int)x}
+// CHECK-CC4-NOT: setter2
+// CHECK-CC4: ObjCInstanceMethodDecl:{ResultType void}{TypedText setter3:}{Informative (int)y}
+// CHECK-CC4: ObjCInstanceMethodDecl:{ResultType void}{TypedText setter4:}{Informative (int)x}
diff --git a/test/Index/complete-protocols.m b/test/Index/complete-protocols.m
new file mode 100644
index 0000000..89f61bc
--- /dev/null
+++ b/test/Index/complete-protocols.m
@@ -0,0 +1,25 @@
+/* Note: the RUN lines are near the end of the file, since line/column
+   matter for this test. */
+
+@protocol Protocol1
+@end
+
+@protocol Protocol2;
+
+void f(id<Protocol1,Protocol2>);
+
+@protocol Protocol0;
+@protocol NewProtocol 
+{
+}
+@end
+
+// RUN: c-index-test -code-completion-at=%s:9:11 %s | FileCheck -check-prefix=CHECK-CC1 %s
+// CHECK-CC1: ObjCProtocolDecl:{TypedText Protocol1}
+// CHECK-CC1: ObjCProtocolDecl:{TypedText Protocol2}
+// RUN: c-index-test -code-completion-at=%s:9:21 %s | FileCheck -check-prefix=CHECK-CC2 %s
+// CHECK-CC2-NOT: ObjCProtocolDecl:{TypedText Protocol1}
+// CHECK-CC2: ObjCProtocolDecl:{TypedText Protocol2}
+// RUN: c-index-test -code-completion-at=%s:12:11 %s | FileCheck -check-prefix=CHECK-CC3 %s
+// CHECK-CC3: ObjCProtocolDecl:{TypedText Protocol0}
+// CHECK-CC3-NEXT: ObjCProtocolDecl:{TypedText Protocol2}
diff --git a/test/Index/complete-tabs.c b/test/Index/complete-tabs.c
new file mode 100644
index 0000000..f3313bf
--- /dev/null
+++ b/test/Index/complete-tabs.c
@@ -0,0 +1,9 @@
+// Test code-completion in the presence of tabs
+struct Point { int x, y; };
+
+void f(struct Point *p) {
+	p->
+
+// RUN: c-index-test -code-completion-at=%s:5:5 %s | FileCheck -check-prefix=CHECK-CC1 %s
+// CHECK-CC1: {TypedText x}
+// CHECK-CC1: {TypedText y}
diff --git a/test/Index/cxx-operator-overload.cpp b/test/Index/cxx-operator-overload.cpp
new file mode 100644
index 0000000..8647448
--- /dev/null
+++ b/test/Index/cxx-operator-overload.cpp
@@ -0,0 +1,28 @@
+// Run lines are sensitive to line numbers and come below the code.
+// FIXME: re-enable this when we can serialize more C++ ASTs
+class Cls {
+public:
+    Cls operator +(const Cls &RHS);
+};
+
+static void bar() {
+    Cls x1, x2, x3;
+    Cls x4 = x1 + x2 + x3;
+}
+
+Cls Cls::operator +(const Cls &RHS) { while (1) {} }
+
+// RUN: %clang_cc1 -emit-pch %s -o %t.ast
+
+// RUNx: index-test %t.ast -point-at %s:10:17 -print-decls > %t &&
+// RUNx: cat %t | count 2 &&
+// RUNx: grep ':5:9,' %t &&
+// RUNx: grep ':13:10,' %t &&
+
+// Yep, we can show references of '+' plus signs that are overloaded, w00t!
+// RUNx: index-test %t.ast -point-at %s:5:15 -print-refs > %t &&
+// RUNx: cat %t | count 2 &&
+// RUNx: grep ':10:17,' %t &&
+// RUNx: grep ':10:22,' %t &&
+
+// RUNx: index-test %t.ast -point-at %s:10:14 | grep 'DeclRefExpr x1'
diff --git a/test/Index/include_test.h b/test/Index/include_test.h
new file mode 100644
index 0000000..3c40c8d
--- /dev/null
+++ b/test/Index/include_test.h
@@ -0,0 +1 @@
+#include "include_test_2.h"
diff --git a/test/Index/include_test_2.h b/test/Index/include_test_2.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Index/include_test_2.h
diff --git a/test/Index/invalid-code-rdar_7833619.m b/test/Index/invalid-code-rdar_7833619.m
new file mode 100644
index 0000000..0034539
--- /dev/null
+++ b/test/Index/invalid-code-rdar_7833619.m
@@ -0,0 +1,4 @@
+// RUN: c-index-test -test-load-source all %s
+// All we care about in this test is that it doesn't crash.
+typedef r7833619_a (*r7833619_b)(r7833619_c *r7833619_d, r7833619_c *r7833619_e);
+
diff --git a/test/Index/linkage.c b/test/Index/linkage.c
new file mode 100644
index 0000000..d1f1c5b
--- /dev/null
+++ b/test/Index/linkage.c
@@ -0,0 +1,26 @@
+// RUN: c-index-test -test-print-linkage-source %s | FileCheck %s
+
+enum Baz { Qux = 0 };
+int x;
+void foo();
+static int w;
+void bar(int y) {
+  static int z;
+  int k;
+}
+extern int n;
+static int wibble(int);
+
+// CHECK: EnumDecl=Baz:3:6 (Definition)linkage=External
+// CHECK: EnumConstantDecl=Qux:3:12 (Definition)linkage=External
+// CHECK: VarDecl=x:4:5linkage=External
+// CHECK: FunctionDecl=foo:5:6linkage=External
+// CHECK: VarDecl=w:6:12linkage=Internal
+// CHECK: FunctionDecl=bar:7:6 (Definition)linkage=External
+// CHECK: ParmDecl=y:7:14 (Definition)linkage=NoLinkage
+// CHECK: VarDecl=z:8:14 (Definition)linkage=NoLinkage
+// CHECK: VarDecl=k:9:7 (Definition)linkage=NoLinkage
+// CHECK: VarDecl=n:11:12linkage=External
+// CHECK: FunctionDecl=wibble:12:12linkage=Internal
+// CHECL: ParmDecl=:12:22 (Definition)linkage=NoLinkage
+
diff --git a/test/Index/load-exprs.c b/test/Index/load-exprs.c
new file mode 100644
index 0000000..248bc6e
--- /dev/null
+++ b/test/Index/load-exprs.c
@@ -0,0 +1,55 @@
+typedef int T;
+struct X { int a, b; };
+void f(void *ptr) {
+  T* t_ptr = (T *)ptr;
+  (void)sizeof(T);
+  struct X x = (struct X){1, 2};
+  void *xx = ptr ? : &x;
+}
+
+int test_blocks(int x) {
+  __block int y = x;
+  ^{
+     static int z = 0;
+     y = (++z) + x;
+     ^{
+       ++z;
+       ++y;
+     }();
+   }();
+  return y;
+}
+
+// RUN: c-index-test -test-load-source all %s -fblocks | FileCheck %s
+
+// CHECK: load-exprs.c:1:13: TypedefDecl=T:1:13 (Definition) Extent=[1:13 - 1:14]
+// CHECK: load-exprs.c:2:8: StructDecl=X:2:8 (Definition) Extent=[2:1 - 2:23]
+// CHECK: load-exprs.c:2:16: FieldDecl=a:2:16 (Definition) Extent=[2:16 - 2:17]
+// CHECK: load-exprs.c:2:19: FieldDecl=b:2:19 (Definition) Extent=[2:19 - 2:20]
+// CHECK: load-exprs.c:3:6: FunctionDecl=f:3:6 (Definition) Extent=[3:6 - 8:2]
+// CHECK: load-exprs.c:3:14: ParmDecl=ptr:3:14 (Definition) Extent=[3:8 - 3:17]
+// CHECK: load-exprs.c:4:6: VarDecl=t_ptr:4:6 (Definition) Extent=[4:3 - 4:22]
+// CHECK: load-exprs.c:4:3: TypeRef=T:1:13 Extent=[4:3 - 4:4]
+// CHECK: load-exprs.c:4:15: TypeRef=T:1:13 Extent=[4:15 - 4:16]
+// CHECK: load-exprs.c:4:19: DeclRefExpr=ptr:3:14 Extent=[4:19 - 4:22]
+// CHECK: load-exprs.c:5:16: TypeRef=T:1:13 Extent=[5:16 - 5:17]
+// CHECK: load-exprs.c:6:12: VarDecl=x:6:12 (Definition) Extent=[6:10 - 6:32]
+// CHECK: load-exprs.c:6:10: TypeRef=struct X:2:8 Extent=[6:10 - 6:11]
+// CHECK: load-exprs.c:6:24: TypeRef=struct X:2:8 Extent=[6:24 - 6:25]
+// CHECK: load-exprs.c:7:9: VarDecl=xx:7:9 (Definition) Extent=[7:3 - 7:24]
+// CHECK: load-exprs.c:7:14: DeclRefExpr=ptr:3:14 Extent=[7:14 - 7:17]
+// CHECK: load-exprs.c:7:23: DeclRefExpr=x:6:12 Extent=[7:23 - 7:24]
+// CHECK: load-exprs.c:10:5: FunctionDecl=test_blocks:10:5 (Definition) Extent=[10:5 - 21:2]
+// CHECK: load-exprs.c:10:21: ParmDecl=x:10:21 (Definition) Extent=[10:17 - 10:22]
+// CHECK: load-exprs.c:11:15: VarDecl=y:11:15 (Definition) Extent=[11:11 - 11:20]
+// CHECK: load-exprs.c:11:19: DeclRefExpr=x:10:21 Extent=[11:19 - 11:20]
+// CHECK: load-exprs.c:12:3: CallExpr= Extent=[12:3 - 19:7]
+// CHECK: load-exprs.c:13:17: VarDecl=z:13:17 (Definition) Extent=[13:13 - 13:22]
+// CHECK: load-exprs.c:14:6: DeclRefExpr= Extent=[14:6 - 14:7]
+// CHECK: load-exprs.c:14:13: DeclRefExpr=z:13:17 Extent=[14:13 - 14:14]
+// CHECK: load-exprs.c:14:18: DeclRefExpr= Extent=[14:18 - 14:19]
+// CHECK: load-exprs.c:15:6: CallExpr= Extent=[15:6 - 18:9]
+// CHECK: load-exprs.c:16:10: DeclRefExpr=z:13:17 Extent=[16:10 - 16:11]
+// CHECK: load-exprs.c:17:10: DeclRefExpr= Extent=[17:10 - 17:11]
+// CHECK: load-exprs.c:20:10: DeclRefExpr=y:11:15 Extent=[20:10 - 20:11]
+
diff --git a/test/Index/load-stmts.cpp b/test/Index/load-stmts.cpp
new file mode 100644
index 0000000..fdfedfb
--- /dev/null
+++ b/test/Index/load-stmts.cpp
@@ -0,0 +1,51 @@
+typedef int T;
+struct X { int a, b; };
+void f(int x) {
+  for (T y = x; T z = x; ++x) {
+  }
+  if (T *z2 = &x) { }
+  while (T *z3 = &x) { }
+  switch (T z4 = x) {
+  case 17: break;
+  }
+}
+
+// RUN: c-index-test -test-load-source all %s | FileCheck %s
+// CHECK: load-stmts.cpp:3:6: UnexposedStmt= Extent=[4:3 - 5:4]
+// CHECK: load-stmts.cpp:3:6: UnexposedStmt= Extent=[4:8 - 4:16]
+// CHECK: load-stmts.cpp:4:10: VarDecl=y:4:10 (Definition) Extent=[4:8 - 4:15]
+// CHECK: load-stmts.cpp:4:8: TypeRef=T:1:13 Extent=[4:8 - 4:9]
+// CHECK: load-stmts.cpp:4:14: DeclRefExpr=x:3:12 Extent=[4:14 - 4:15]
+// CHECK: load-stmts.cpp:4:19: VarDecl=z:4:19 (Definition) Extent=[4:17 - 4:24]
+// CHECK: load-stmts.cpp:4:17: TypeRef=T:1:13 Extent=[4:17 - 4:18]
+// CHECK: load-stmts.cpp:4:23: DeclRefExpr=x:3:12 Extent=[4:23 - 4:24]
+// CHECK: load-stmts.cpp:4:19: UnexposedExpr=z:4:19 Extent=[4:19 - 4:20]
+// CHECK: load-stmts.cpp:4:19: DeclRefExpr=z:4:19 Extent=[4:19 - 4:20]
+// CHECK: load-stmts.cpp:4:26: UnexposedExpr= Extent=[4:26 - 4:29]
+// CHECK: load-stmts.cpp:4:28: DeclRefExpr=x:3:12 Extent=[4:28 - 4:29]
+// CHECK: load-stmts.cpp:4:19: UnexposedStmt= Extent=[4:31 - 5:4]
+// CHECK: load-stmts.cpp:4:19: UnexposedStmt= Extent=[6:3 - 6:22]
+// CHECK: load-stmts.cpp:6:10: VarDecl=z2:6:10 (Definition) Extent=[6:7 - 6:17]
+// CHECK: load-stmts.cpp:6:7: TypeRef=T:1:13 Extent=[6:7 - 6:8]
+// CHECK: load-stmts.cpp:6:15: UnexposedExpr= Extent=[6:15 - 6:17]
+// CHECK: load-stmts.cpp:6:16: DeclRefExpr=x:3:12 Extent=[6:16 - 6:17]
+// CHECK: load-stmts.cpp:6:10: UnexposedExpr=z2:6:10 Extent=[6:10 - 6:12]
+// CHECK: load-stmts.cpp:6:10: DeclRefExpr=z2:6:10 Extent=[6:10 - 6:12]
+// CHECK: load-stmts.cpp:6:10: UnexposedStmt= Extent=[6:19 - 6:22]
+// CHECK: load-stmts.cpp:6:10: UnexposedStmt= Extent=[7:3 - 7:25]
+// CHECK: load-stmts.cpp:7:13: VarDecl=z3:7:13 (Definition) Extent=[7:10 - 7:20]
+// CHECK: load-stmts.cpp:7:10: TypeRef=T:1:13 Extent=[7:10 - 7:11]
+// CHECK: load-stmts.cpp:7:18: UnexposedExpr= Extent=[7:18 - 7:20]
+// CHECK: load-stmts.cpp:7:19: DeclRefExpr=x:3:12 Extent=[7:19 - 7:20]
+// CHECK: load-stmts.cpp:7:13: UnexposedExpr=z3:7:13 Extent=[7:13 - 7:15]
+// CHECK: load-stmts.cpp:7:13: DeclRefExpr=z3:7:13 Extent=[7:13 - 7:15]
+// CHECK: load-stmts.cpp:7:13: UnexposedStmt= Extent=[7:22 - 7:25]
+// CHECK: load-stmts.cpp:7:13: UnexposedStmt= Extent=[8:3 - 10:4]
+// CHECK: load-stmts.cpp:8:13: VarDecl=z4:8:13 (Definition) Extent=[8:11 - 8:19]
+// CHECK: load-stmts.cpp:8:11: TypeRef=T:1:13 Extent=[8:11 - 8:12]
+// CHECK: load-stmts.cpp:8:18: DeclRefExpr=x:3:12 Extent=[8:18 - 8:19]
+// CHECK: load-stmts.cpp:8:13: DeclRefExpr=z4:8:13 Extent=[8:13 - 8:15]
+// CHECK: load-stmts.cpp:8:13: UnexposedStmt= Extent=[8:21 - 10:4]
+// CHECK: load-stmts.cpp:8:13: UnexposedStmt= Extent=[9:3 - 9:17]
+// CHECK: load-stmts.cpp:8:13: UnexposedStmt= Extent=[9:12 - 9:17]
+// CHECK: load-stmts.cpp:9:8: UnexposedExpr= Extent=[9:8 - 9:10]
diff --git a/test/Index/print-usrs.c b/test/Index/print-usrs.c
new file mode 100644
index 0000000..898778b
--- /dev/null
+++ b/test/Index/print-usrs.c
@@ -0,0 +1,17 @@
+// RUN: c-index-test -print-usr-file %s | FileCheck %s
+// This isn't really C code; it has a .c extension to get picked up by lit.
+ObjCClass NSObject
+ObjCCategory NSObject foo
+ObjCIvar x c:objc(cs)NSObject
+ObjCMethod foo: 0 c:objc(cs)NSObject
+ObjCMethod baz:with 1 c:objc(cs)NSObject
+ObjCProperty gimme c:objc(cs)NSObject
+ObjCProtocol blah
+// CHECK: c:objc(cs)NSObject
+// CHECK: c:objc(cy)NSObject@foo
+// CHECK: c:objc(cs)NSObject@x
+// CHECK: c:objc(cs)NSObject(cm)foo:
+// CHECK: c:objc(cs)NSObject(im)baz:with
+// CHECK: c:objc(cs)NSObject(py)gimme
+// CHECK: c:objc(pl)blah
+
diff --git a/test/Index/recover-bad-code-rdar_7487294.c b/test/Index/recover-bad-code-rdar_7487294.c
new file mode 100644
index 0000000..e060672
--- /dev/null
+++ b/test/Index/recover-bad-code-rdar_7487294.c
@@ -0,0 +1,13 @@
+// RUN: %clang-cc1 -fsyntax-only %s 2>&1 | FileCheck %s
+
+// IMPORTANT: This test case intentionally DOES NOT use --disable-free.  It
+// tests that we are properly reclaiming the ASTs and we do not have a double free.
+// Previously we tried to free the size expression of the VLA twice.
+
+int foo(int x) {
+  int y[x * 3];
+  help
+};
+
+// CHECK: 9:3: error: use of undeclared identifier 'help'
+// CHECK:  help
diff --git a/test/Index/remap-complete.c b/test/Index/remap-complete.c
new file mode 100644
index 0000000..813d1df
--- /dev/null
+++ b/test/Index/remap-complete.c
@@ -0,0 +1,8 @@
+// RUN: c-index-test -code-completion-at=%s:6:2 -remap-file="%s;%S/Inputs/remap-complete-to.c" %s 2> %t.err | FileCheck %s
+// RUN: FileCheck -check-prefix=CHECK-DIAGS %s < %t.err
+// XFAIL: win32
+
+// CHECK: FunctionDecl:{ResultType int}{TypedText f0}{LeftParen (}
+void f() { }
+
+// CHECK-DIAGS: remap-complete.c:2:19
diff --git a/test/Index/remap-cursor-at.c b/test/Index/remap-cursor-at.c
new file mode 100644
index 0000000..fb97d5d
--- /dev/null
+++ b/test/Index/remap-cursor-at.c
@@ -0,0 +1,5 @@
+// RUN: c-index-test -cursor-at=%s:1:15 -cursor-at=%s:2:21 -remap-file="%s;%S/Inputs/remap-load-to.c" %s | FileCheck %s
+// RUN: env CINDEXTEST_USE_EXTERNAL_AST_GENERATION=1 c-index-test -cursor-at=%s:1:15 -cursor-at=%s:2:21 -remap-file="%s;%S/Inputs/remap-load-to.c" %s | FileCheck %s
+
+// CHECK: ParmDecl=parm1:1:13 (Definition)
+// CHECK: DeclRefExpr=parm2:1:26
diff --git a/test/Index/remap-load.c b/test/Index/remap-load.c
new file mode 100644
index 0000000..b8415e6
--- /dev/null
+++ b/test/Index/remap-load.c
@@ -0,0 +1,14 @@
+// RUN: c-index-test -test-load-source all -remap-file="%s;%S/Inputs/remap-load-to.c" %s | FileCheck -check-prefix=CHECK %s
+// RUN: env CINDEXTEST_USE_EXTERNAL_AST_GENERATION=1 c-index-test -test-load-source all -remap-file="%s;%S/Inputs/remap-load-to.c" %s | FileCheck -check-prefix=CHECK %s
+// XFAIL: win32
+
+// CHECK: remap-load.c:1:5: FunctionDecl=foo:1:5 (Definition) Extent=[1:5 - 3:2]
+// CHECK: remap-load.c:1:13: ParmDecl=parm1:1:13 (Definition) Extent=[1:9 - 1:18]
+// CHECK: remap-load.c:1:26: ParmDecl=parm2:1:26 (Definition) Extent=[1:20 - 1:31]
+// CHECK: remap-load.c:1:5: UnexposedStmt= Extent=[1:33 - 3:2]
+// CHECK: remap-load.c:1:5: UnexposedStmt= Extent=[2:3 - 2:23]
+// CHECK: remap-load.c:2:10: UnexposedExpr= Extent=[2:10 - 2:23]
+// CHECK: remap-load.c:2:10: UnexposedExpr= Extent=[2:10 - 2:23]
+// CHECK: remap-load.c:2:10: UnexposedExpr=parm1:1:13 Extent=[2:10 - 2:15]
+// CHECK: remap-load.c:2:10: DeclRefExpr=parm1:1:13 Extent=[2:10 - 2:15]
+// CHECK: remap-load.c:2:18: DeclRefExpr=parm2:1:26 Extent=[2:18 - 2:23]
diff --git a/test/Index/usrs.m b/test/Index/usrs.m
new file mode 100644
index 0000000..28771ae
--- /dev/null
+++ b/test/Index/usrs.m
@@ -0,0 +1,74 @@
+// RUN: c-index-test -test-load-source-usrs all %s | FileCheck %s
+
+enum {
+  ABA,
+  CADABA
+};
+
+enum {
+  FOO,
+  BAR
+};
+
+typedef struct {
+  int wa;
+  int moo;
+} MyStruct;
+
+enum Pizza {
+  CHEESE,
+  MUSHROOMS
+};
+
+@interface Foo {
+  id x;
+  id y;
+}
+- (id) godzilla;
++ (id) kingkong;
+@property int d1;
+@end
+
+@implementation Foo
+- (id) godzilla {
+  static int a = 0;
+  extern int z;
+  return 0;
+}
++ (id) kingkong {
+  return 0;
+}
+@synthesize d1;
+@end
+
+int z;
+
+// CHECK: usrs.m c:@Ea@usrs.m@3:1 Extent=[3:1 - 6:2]
+// CHECK: usrs.m c:@Ea@usrs.m@3:1@ABA Extent=[4:3 - 4:6]
+// CHECK: usrs.m c:@Ea@usrs.m@3:1@CADABA Extent=[5:3 - 5:9]
+// CHECK: usrs.m c:@Ea@usrs.m@8:1 Extent=[8:1 - 11:2]
+// CHECK: usrs.m c:@Ea@usrs.m@8:1@FOO Extent=[9:3 - 9:6]
+// CHECK: usrs.m c:@Ea@usrs.m@8:1@BAR Extent=[10:3 - 10:6]
+// CHECK: usrs.m c:@SA@MyStruct Extent=[13:9 - 16:2]
+// CHECK: usrs.m c:@SA@MyStruct@FI@wa Extent=[14:7 - 14:9]
+// CHECK: usrs.m c:@SA@MyStruct@FI@moo Extent=[15:7 - 15:10]
+// CHECK: usrs.m c:@T@usrs.m@16:3@MyStruct Extent=[16:3 - 16:11]
+// CHECK: usrs.m c:@E@Pizza Extent=[18:1 - 21:2]
+// CHECK: usrs.m c:@E@Pizza@CHEESE Extent=[19:3 - 19:9]
+// CHECK: usrs.m c:@E@Pizza@MUSHROOMS Extent=[20:3 - 20:12]
+// CHECK: usrs.m c:objc(cs)Foo Extent=[23:1 - 30:5]
+// CHECK: usrs.m c:objc(cs)Foo@x Extent=[24:6 - 24:7]
+// CHECK: usrs.m c:objc(cs)Foo@y Extent=[25:6 - 25:7]
+// CHECK: usrs.m c:objc(cs)Foo(py)d1 Extent=[29:15 - 29:17]
+// CHECK: usrs.m c:objc(cs)Foo(im)godzilla Extent=[27:1 - 27:17]
+// CHECK: usrs.m c:objc(cs)Foo(cm)kingkong Extent=[28:1 - 28:17]
+// CHECK: usrs.m c:objc(cs)Foo(im)d1 Extent=[29:15 - 29:17]
+// CHECK: usrs.m c:objc(cs)Foo(im)setD1: Extent=[29:15 - 29:17]
+// CHECK: usrs.m c:objc(cs)Foo Extent=[32:1 - 42:2]
+// CHECK: usrs.m c:objc(cs)Foo(im)godzilla Extent=[33:1 - 37:2]
+// CHECK: usrs.m c:@z Extent=[35:10 - 35:15]
+// CHECK: usrs.m c:objc(cs)Foo(cm)kingkong Extent=[38:1 - 40:2]
+// CHECK: usrs.m c:objc(cs)Foo@d1 Extent=[41:13 - 41:15]
+// CHECK: usrs.m c:objc(cs)Foo(py)d1 Extent=[41:1 - 41:15]
+// CHECK: usrs.m c:@z Extent=[44:1 - 44:6]
+
diff --git a/test/Lexer/11-27-2007-FloatLiterals.c b/test/Lexer/11-27-2007-FloatLiterals.c
new file mode 100644
index 0000000..ccd9e2e
--- /dev/null
+++ b/test/Lexer/11-27-2007-FloatLiterals.c
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+
+// CHECK: 0x3BFD83C940000000
+// CHECK: 2.000000e+{{[0]*}}32
+// CHECK: 0x3BFD83C940000000
+// CHECK: 2.000000e+{{[0]*}}32
+
+float  F  = 1e-19f;
+double D  = 2e32;
+float  F2 = 01e-19f;
+double D2 = 02e32;
diff --git a/test/Lexer/badstring_in_if0.c b/test/Lexer/badstring_in_if0.c
new file mode 100644
index 0000000..486dcf2
--- /dev/null
+++ b/test/Lexer/badstring_in_if0.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -E %s 2>&1 | not grep error
+#if 0
+
+  "
+
+  '
+
+#endif
diff --git a/test/Lexer/block_cmt_end.c b/test/Lexer/block_cmt_end.c
new file mode 100644
index 0000000..72bc836
--- /dev/null
+++ b/test/Lexer/block_cmt_end.c
@@ -0,0 +1,38 @@
+/*
+  RUN: %clang_cc1 -E -trigraphs %s | grep bar
+  RUN: %clang_cc1 -E -trigraphs %s | grep foo
+  RUN: %clang_cc1 -E -trigraphs %s | not grep abc
+  RUN: %clang_cc1 -E -trigraphs %s | not grep xyz
+  RUN: %clang_cc1 -fsyntax-only -trigraphs -verify %s  
+*/
+
+// This is a simple comment, /*/ does not end a comment, the trailing */ does.
+int i = /*/ */ 1;
+
+/* abc
+
+next comment ends with normal escaped newline:
+*/
+
+/* expected-warning {{escaped newline}} expected-warning {{backslash and newline}}  *\  
+/
+
+int bar /* expected-error {{invalid token after top level declarator}} */
+
+/* xyz
+
+next comment ends with a trigraph escaped newline: */
+
+/* expected-warning {{escaped newline between}}   expected-warning {{backslash and newline separated by space}}    expected-warning {{trigraph ends block comment}}   *??/    
+/
+
+foo
+
+
+// rdar://6060752 - We should not get warnings about trigraphs in comments:
+// '????'
+/* ???? */
+
+
+
+
diff --git a/test/Lexer/c90.c b/test/Lexer/c90.c
new file mode 100644
index 0000000..6293d42
--- /dev/null
+++ b/test/Lexer/c90.c
@@ -0,0 +1,13 @@
+/* RUN: %clang_cc1 -std=c90 -fsyntax-only %s -verify -pedantic-errors
+ */
+
+enum { cast_hex = (long) (
+      0x0p-1   /* expected-error {{hexadecimal floating constants are a C99 feature}} */
+     ) };
+
+/* PR2477 */
+int test1(int a,int b) {return a//* This is a divide followed by block comment in c89 mode */
+b;}
+
+// comment accepted as extension    /* expected-error {{// comments are not allowed in this language}}
+
diff --git a/test/Lexer/char-escapes.c b/test/Lexer/char-escapes.c
new file mode 100644
index 0000000..d918bf4
--- /dev/null
+++ b/test/Lexer/char-escapes.c
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -fsyntax-only -pedantic -verify %s
+
+int test['\\' == 92 ? 1 : -1];
+int test['\"' == 34 ? 1 : -1];
+int test['\'' == 39 ? 1 : -1];
+int test['\?' == 63 ? 1 : -1];
+int test['\a' == 7 ? 1 : -1];
+int test['\b' == 8 ? 1 : -1];
+int test['\e' == 27 ? 1 : -1]; // expected-warning {{non-standard escape}}
+int test['\E' == 27 ? 1 : -1]; // expected-warning {{non-standard escape}}
+int test['\f' == 12 ? 1 : -1];
+int test['\n' == 10 ? 1 : -1];
+int test['\r' == 13 ? 1 : -1];
+int test['\t' == 9 ? 1 : -1];
+int test['\v' == 11 ? 1 : -1];
+int test['\xa' == 10 ? 1 : -1];
+int test['\1' == 1 ? 1 : -1];
+int test['\(' == 40 ? 1 : -1]; // expected-warning {{non-standard escape}}
+int test['\{' == 123 ? 1 : -1]; // expected-warning {{non-standard escape}}
+int test['\[' == 91 ? 1 : -1]; // expected-warning {{non-standard escape}}
+int test['\%' == 37 ? 1 : -1]; // expected-warning {{non-standard escape}}
diff --git a/test/Lexer/comment-escape.c b/test/Lexer/comment-escape.c
new file mode 100644
index 0000000..191e654
--- /dev/null
+++ b/test/Lexer/comment-escape.c
@@ -0,0 +1,6 @@
+// RUN: %clang -fsyntax-only %s 
+// rdar://6757323
+// foo \
+
+#define blork 32
+
diff --git a/test/Lexer/conflict-marker.c b/test/Lexer/conflict-marker.c
new file mode 100644
index 0000000..f86111c
--- /dev/null
+++ b/test/Lexer/conflict-marker.c
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only
+
+// Test that we recover gracefully from conflict markers left in input files.
+// PR5238
+
+// diff3 style
+<<<<<<< .mine             // expected-error {{version control conflict marker in file}}
+int x = 4;
+|||||||
+int x = 123;
+=======
+float x = 17;
+>>>>>>> .r91107
+
+// normal style.
+<<<<<<< .mine             // expected-error {{version control conflict marker in file}}
+typedef int y;
+=======
+typedef struct foo *y;
+>>>>>>> .r91107
+
+;
+y b;
+
+int foo() {
+  y a = x;
+  return x + a;
+}
+
diff --git a/test/Lexer/constants-ms.c b/test/Lexer/constants-ms.c
new file mode 100644
index 0000000..97e6600
--- /dev/null
+++ b/test/Lexer/constants-ms.c
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -fms-extensions %s
+
+__int8 x1  = 3i8;
+__int16 x2 = 4i16;
+__int32 x3 = 5i32;
+__int64 x5 = 0x42i64;
+__int64 x4 = 70000000i128;
+
+__int64 y = 0x42i64u;  // expected-error {{invalid suffix}}
+__int64 w = 0x43ui64; 
+__int64 z = 9Li64;  // expected-error {{invalid suffix}}
+__int64 q = 10lli64;  // expected-error {{invalid suffix}}
+
+// radar 7562363
+#define ULLONG_MAX 0xffffffffffffffffui64
+#define UINT 0xffffffffui32
+#define USHORT 0xffffui16
+#define UCHAR 0xffui8
+
+void a() {
+	unsigned long long m = ULLONG_MAX;
+	unsigned int n = UINT;
+        unsigned short s = USHORT;
+        unsigned char c = UCHAR;
+}
diff --git a/test/Lexer/constants.c b/test/Lexer/constants.c
new file mode 100644
index 0000000..b833e7b
--- /dev/null
+++ b/test/Lexer/constants.c
@@ -0,0 +1,57 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -pedantic -trigraphs %s
+
+int x = 000000080;  // expected-error {{invalid digit}}
+
+int y = 0000\
+00080;             // expected-error {{invalid digit}}
+
+
+
+float X = 1.17549435e-38F;
+float Y = 08.123456;
+
+// PR2252
+#if -0x8000000000000000  // should not warn.
+#endif
+
+
+char c[] = {
+  'df',   // expected-warning {{multi-character character constant}}
+  '\t',
+  '\\
+t',
+  '??!',  // expected-warning {{trigraph converted to '|' character}}
+  'abcd'  // expected-warning {{multi-character character constant}}
+};
+
+
+#pragma clang diagnostic ignored "-Wmultichar"
+
+char d = 'df'; // no warning.
+char e = 'abcd';  // still warn: expected-warning {{multi-character character constant}}
+
+#pragma clang diagnostic ignored "-Wfour-char-constants"
+
+char f = 'abcd';  // ignored.
+
+// rdar://problem/6974641
+float t0[] = {
+  1.9e20f,
+  1.9e-20f,
+  1.9e50f,   // expected-warning {{too large}}
+  1.9e-50f,  // expected-warning {{too small}}
+  -1.9e20f,
+  -1.9e-20f,
+  -1.9e50f,  // expected-warning {{too large}}
+  -1.9e-50f  // expected-warning {{too small}}
+};
+double t1[] = {
+  1.9e50,
+  1.9e-50,
+  1.9e500,   // expected-warning {{too large}}
+  1.9e-500,  // expected-warning {{too small}}
+  -1.9e50,
+  -1.9e-50,
+  -1.9e500,  // expected-warning {{too large}}
+  -1.9e-500  // expected-warning {{too small}}
+};
diff --git a/test/Lexer/counter.c b/test/Lexer/counter.c
new file mode 100644
index 0000000..2173730
--- /dev/null
+++ b/test/Lexer/counter.c
@@ -0,0 +1,16 @@
+// __COUNTER__ support: rdar://4329310
+// RUN: %clang -E %s > %t
+
+#define PASTE2(x,y) x##y
+#define PASTE1(x,y) PASTE2(x,y)
+#define UNIQUE(x) PASTE1(x,__COUNTER__)
+
+// RUN: grep "A: 0" %t
+A: __COUNTER__
+
+// RUN: grep "B: foo1" %t
+B: UNIQUE(foo);
+// RUN: grep "C: foo2" %t
+C: UNIQUE(foo);
+// RUN: grep "D: 3" %t
+D: __COUNTER__
diff --git a/test/Lexer/cxx0x_keyword.cpp b/test/Lexer/cxx0x_keyword.cpp
new file mode 100644
index 0000000..c27925b
--- /dev/null
+++ b/test/Lexer/cxx0x_keyword.cpp
@@ -0,0 +1,2 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s 2>&1
+int static_assert; /* expected-error {{expected unqualified-id}} */
diff --git a/test/Lexer/cxx0x_keyword_as_cxx98.cpp b/test/Lexer/cxx0x_keyword_as_cxx98.cpp
new file mode 100644
index 0000000..2bfb8b0
--- /dev/null
+++ b/test/Lexer/cxx0x_keyword_as_cxx98.cpp
@@ -0,0 +1,2 @@
+// RUN: %clang_cc1 %s -fsyntax-only
+int static_assert;
diff --git a/test/Lexer/digraph.c b/test/Lexer/digraph.c
new file mode 100644
index 0000000..b8a99bb
--- /dev/null
+++ b/test/Lexer/digraph.c
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only -verify < %s
+
+%:include <stdint.h>
+
+    %:ifndef BUFSIZE
+     %:define BUFSIZE  512
+    %:endif
+
+    void copy(char d<::>, const char s<::>, int len)
+    <%
+        while (len-- >= 0)
+        <%
+            d<:len:> = s<:len:>;
+        %>
+    %>
diff --git a/test/Lexer/dollar-idents.c b/test/Lexer/dollar-idents.c
new file mode 100644
index 0000000..cbf25b0
--- /dev/null
+++ b/test/Lexer/dollar-idents.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -dump-tokens %s 2> %t
+// RUN: grep "identifier '\$A'" %t
+// RUN: %clang_cc1 -dump-tokens -x assembler-with-cpp %s 2> %t
+// RUN: grep "identifier 'A'" %t
+// PR3808
+
+$A
diff --git a/test/Lexer/escape_newline.c b/test/Lexer/escape_newline.c
new file mode 100644
index 0000000..43ba417
--- /dev/null
+++ b/test/Lexer/escape_newline.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -E -trigraphs %s | grep -- ' ->'
+// RUN: %clang_cc1 -E -trigraphs %s 2>&1 | grep 'backslash and newline separated by space'
+// RUN: %clang_cc1 -E -trigraphs %s 2>&1 | grep 'trigraph converted'
+
+// This is an ugly way to spell a -> token.
+ -??/      
+>
diff --git a/test/Lexer/gnu_keywords.c b/test/Lexer/gnu_keywords.c
new file mode 100644
index 0000000..3234f58
--- /dev/null
+++ b/test/Lexer/gnu_keywords.c
@@ -0,0 +1,12 @@
+// RUN: %clang -DGNU_KEYWORDS -std=gnu89 -fsyntax-only -verify %s
+// RUN: %clang -DGNU_KEYWORDS -std=c99 -fgnu-keywords -fsyntax-only -verify %s
+// RUN: %clang -std=c99 -fsyntax-only -verify %s
+// RUN: %clang -std=gnu89 -fno-gnu-keywords -fsyntax-only -verify %s
+
+void f() {
+#ifdef GNU_KEYWORDS
+  asm ("ret" : :);
+#else
+  int asm;
+#endif
+}
diff --git a/test/Lexer/has_feature_cxx0x.cpp b/test/Lexer/has_feature_cxx0x.cpp
new file mode 100644
index 0000000..7ea4c2c
--- /dev/null
+++ b/test/Lexer/has_feature_cxx0x.cpp
@@ -0,0 +1,101 @@
+// RUN: %clang -E -std=c++0x %s -o - | FileCheck --check-prefix=CHECK-0X %s
+// RUN: %clang -E %s -o - | FileCheck --check-prefix=CHECK-NO-0X %s
+
+#if __has_feature(cxx_lambdas)
+int lambdas();
+#else
+int no_lambdas();
+#endif
+
+// CHECK-0X: no_lambdas
+// CHECK-NO-0X: no_lambdas
+
+
+#if __has_feature(cxx_nullptr)
+int has_nullptr();
+#else
+int no_nullptr();
+#endif
+
+// CHECK-0X: no_nullptr
+// CHECK-NO-0X: no_nullptr
+
+
+#if __has_feature(cxx_concepts)
+int concepts();
+#else
+int no_concepts();
+#endif
+
+// CHECK-0X: no_concepts
+// CHECK-NO-0X: no_concepts
+
+
+#if __has_feature(cxx_decltype)
+int has_decltype();
+#else
+int no_decltype();
+#endif
+
+// CHECK-0X: has_decltype
+// CHECK-NO-0X: no_decltype
+
+
+#if __has_feature(cxx_auto_type)
+int auto_type();
+#else
+int no_auto_type();
+#endif
+
+// CHECK-0X: auto_type
+// CHECK-NO-0X: no_auto_type
+
+
+#if __has_feature(cxx_attributes)
+int attributes();
+#else
+int no_attributes();
+#endif
+
+// CHECK-0X: attributes
+// CHECK-NO-0X: no_attributes
+
+
+#if __has_feature(cxx_static_assert)
+int has_static_assert();
+#else
+int no_static_assert();
+#endif
+
+// CHECK-0X: has_static_assert
+// CHECK-NO-0X: no_static_assert
+
+
+#if __has_feature(cxx_deleted_functions)
+int deleted_functions();
+#else
+int no_deleted_functions();
+#endif
+
+// CHECK-0X: deleted_functions
+// CHECK-NO-0X: no_deleted_functions
+
+
+#if __has_feature(cxx_rvalue_references)
+int rvalue_references();
+#else
+int no_rvalue_references();
+#endif
+
+// CHECK-0X: no_rvalue_references
+// CHECK-NO-0X: no_rvalue_references
+
+
+#if __has_feature(cxx_variadic_templates)
+int variadic_templates();
+#else
+int no_variadic_templates();
+#endif
+
+// CHECK-0X: no_variadic_templates
+// CHECK-NO-0X: no_variadic_templates
diff --git a/test/Lexer/has_feature_exceptions.cpp b/test/Lexer/has_feature_exceptions.cpp
new file mode 100644
index 0000000..cfd1efb
--- /dev/null
+++ b/test/Lexer/has_feature_exceptions.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang -E -fexceptions %s -o - | FileCheck --check-prefix=CHECK-EXCEPTIONS %s
+// RUN: %clang -E -fno-exceptions %s -o - | FileCheck --check-prefix=CHECK-NO-EXCEPTIONS %s
+
+#if __has_feature(cxx_exceptions)
+int foo();
+#else
+int bar();
+#endif
+
+// CHECK-EXCEPTIONS: foo
+// CHECK-NO-EXCEPTIONS: bar
diff --git a/test/Lexer/has_feature_rtti.cpp b/test/Lexer/has_feature_rtti.cpp
new file mode 100644
index 0000000..690906c
--- /dev/null
+++ b/test/Lexer/has_feature_rtti.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang -E -frtti %s -o - | FileCheck --check-prefix=CHECK-RTTI %s
+// RUN: %clang -E -fno-rtti %s -o - | FileCheck --check-prefix=CHECK-NO-RTTI %s
+
+#if __has_feature(cxx_rtti)
+int foo();
+#else
+int bar();
+#endif
+
+// CHECK-RTTI: foo
+// CHECK-NO-RTTI: bar
diff --git a/test/Lexer/hexfloat.cpp b/test/Lexer/hexfloat.cpp
new file mode 100644
index 0000000..5a62556
--- /dev/null
+++ b/test/Lexer/hexfloat.cpp
@@ -0,0 +1,8 @@
+//RUN: %clang_cc1 -fsyntax-only -verify
+//RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify
+
+#ifndef __GXX_EXPERIMENTAL_CXX0X__
+float f = 0x1p+1; // expected-warning {{incompatible with C++0x}}
+#else
+float f = 0x1p+1; // expected-warning {{invalid suffix}}
+#endif
diff --git a/test/Lexer/msdos-cpm-eof.c b/test/Lexer/msdos-cpm-eof.c
new file mode 100644
index 0000000..9ef6e32
--- /dev/null
+++ b/test/Lexer/msdos-cpm-eof.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -fms-extensions %s
+
+int x; 
+
+
+
+I am random garbage after ^Z
diff --git a/test/Lexer/multiple-include.c b/test/Lexer/multiple-include.c
new file mode 100644
index 0000000..d737f95
--- /dev/null
+++ b/test/Lexer/multiple-include.c
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 %s -fsyntax-only
+
+#ifndef XVID_AUTO_INCLUDE
+
+#define XVID_AUTO_INCLUDE
+#define FUNC_H      H_Pass_16_C
+#include "multiple-include.c"
+
+#define FUNC_H      H_Pass_8_C
+
+#include "multiple-include.c"
+#undef XVID_AUTO_INCLUDE
+
+typedef void ff();
+typedef struct { ff *a;} S;
+
+S s = { H_Pass_8_C };
+
+#endif 
+
+#if defined(XVID_AUTO_INCLUDE) && defined(REFERENCE_CODE)
+#elif defined(XVID_AUTO_INCLUDE) && !defined(REFERENCE_CODE)
+
+static void FUNC_H(){};
+#undef FUNC_H
+
+#endif
diff --git a/test/Lexer/numeric-literal-trash.c b/test/Lexer/numeric-literal-trash.c
new file mode 100644
index 0000000..5407ba9
--- /dev/null
+++ b/test/Lexer/numeric-literal-trash.c
@@ -0,0 +1,13 @@
+/* RUN: %clang_cc1 -fsyntax-only -verify %s
+ */
+# define XRECORD(x, c_name) e##c (x, __LINE__)
+
+
+
+int ec(int, int);
+
+
+ void x() {
+
+XRECORD (XRECORD (1, 1), 1);
+    }
diff --git a/test/Lexer/pragma-mark.c b/test/Lexer/pragma-mark.c
new file mode 100644
index 0000000..96e8485
--- /dev/null
+++ b/test/Lexer/pragma-mark.c
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify
+
+// Lexer diagnostics shouldn't be included in #pragma mark.
+#pragma mark Mike's world
+_Pragma("mark foo ' bar")
+
+#define X(S) _Pragma(S)
+X("mark foo ' bar")
+
+int i;
+
diff --git a/test/Lexer/rdr-6096838-2.c b/test/Lexer/rdr-6096838-2.c
new file mode 100644
index 0000000..f7f5906
--- /dev/null
+++ b/test/Lexer/rdr-6096838-2.c
@@ -0,0 +1,5 @@
+/* RUN: %clang_cc1 -pedantic -std=gnu89 -fsyntax-only -verify %s
+ rdar://6096838
+ */
+
+long double d = 0x0.0000003ffffffff00000p-16357L; /* expected-warning {{ hexadecimal floating constants are a C99 feature }} */
diff --git a/test/Lexer/rdr-6096838.c b/test/Lexer/rdr-6096838.c
new file mode 100644
index 0000000..2f00f47
--- /dev/null
+++ b/test/Lexer/rdr-6096838.c
@@ -0,0 +1,6 @@
+/* RUN: %clang_cc1 -fsyntax-only -verify %s
+ * RUN: %clang_cc1 -std=gnu89 -fsyntax-only -verify %s
+ rdar://6096838
+ */
+
+long double d = 0x0.0000003ffffffff00000p-16357L;
diff --git a/test/Lexer/token-concat-2.c b/test/Lexer/token-concat-2.c
new file mode 100644
index 0000000..7d3cd64
--- /dev/null
+++ b/test/Lexer/token-concat-2.c
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -E -x c -o - %s | grep '[.][*]'
+// PR4395
+#define X .*
+X
diff --git a/test/Lexer/token-concat.c b/test/Lexer/token-concat.c
new file mode 100644
index 0000000..551af95
--- /dev/null
+++ b/test/Lexer/token-concat.c
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -E -x c -o %t %s
+// RUN: grep 'IDENT.2' %t
+
+IDENT.2
diff --git a/test/Lexer/unknown-char.c b/test/Lexer/unknown-char.c
new file mode 100644
index 0000000..334df37
--- /dev/null
+++ b/test/Lexer/unknown-char.c
@@ -0,0 +1,2 @@
+// RUN: %clang_cc1 -E %s 2>&1 | not grep error
+ ` ` ` `
diff --git a/test/Lexer/utf-16.c b/test/Lexer/utf-16.c
new file mode 100644
index 0000000..2b313e4
--- /dev/null
+++ b/test/Lexer/utf-16.c
@@ -0,0 +1,6 @@
+// RUN: not %clang %s -fsyntax-only -verify
+// rdar://7876588
+
+// This test verifies that clang gives a decent error for UTF-16 source files.
+
+#include "utf-16.c.txt" // expected-error {{UTF-16 (LE) byte order mark detected}}
diff --git a/test/Lexer/utf-16.c.txt b/test/Lexer/utf-16.c.txt
new file mode 100644
index 0000000..4f3d169
--- /dev/null
+++ b/test/Lexer/utf-16.c.txt
Binary files differ
diff --git a/test/Makefile b/test/Makefile
new file mode 100644
index 0000000..e9d8945
--- /dev/null
+++ b/test/Makefile
@@ -0,0 +1,53 @@
+LEVEL = ../../..
+include $(LEVEL)/Makefile.common
+
+# Test in all immediate subdirectories if unset.
+ifdef TESTSUITE
+TESTDIRS := $(TESTSUITE:%=$(PROJ_SRC_DIR)/%)
+else
+TESTDIRS ?= $(PROJ_SRC_DIR)
+endif
+
+# 'lit' wants objdir paths, so it will pick up the lit.site.cfg.
+TESTDIRS := $(TESTDIRS:$(PROJ_SRC_DIR)%=$(PROJ_OBJ_DIR)%)
+
+# Allow EXTRA_TESTDIRS to provide additional test directories.
+TESTDIRS += $(EXTRA_TESTDIRS)
+
+ifndef TESTARGS
+ifdef VERBOSE
+TESTARGS = -v
+else
+TESTARGS = -s -v
+endif
+endif
+
+# Make sure any extra test suites can find the main site config.
+LIT_ARGS := --param clang_site_config=$(PROJ_OBJ_DIR)/lit.site.cfg
+
+ifdef VG
+  LIT_ARGS += "--vg"
+endif
+
+all:: lit.site.cfg
+	@ echo '--- Running clang tests for $(TARGET_TRIPLE) ---'
+	@ $(PYTHON) $(LLVM_SRC_ROOT)/utils/lit/lit.py \
+	  $(LIT_ARGS) $(TESTARGS) $(TESTDIRS)
+
+FORCE:
+
+lit.site.cfg: FORCE
+	@echo "Making Clang 'lit.site.cfg' file..."
+	@sed -e "s#@LLVM_SOURCE_DIR@#$(LLVM_SRC_ROOT)#g" \
+	     -e "s#@LLVM_BINARY_DIR@#$(LLVM_OBJ_ROOT)#g" \
+	     -e "s#@LLVM_TOOLS_DIR@#$(ToolDir)#g" \
+	     -e "s#@LLVM_LIBS_DIR@#$(LibDir)#g" \
+	     -e "s#@CLANG_SOURCE_DIR@#$(PROJ_SRC_DIR)/..#g" \
+	     -e "s#@CLANG_BINARY_DIR@#$(PROJ_OBJ_DIR)/..#g" \
+	     -e "s#@TARGET_TRIPLE@#$(TARGET_TRIPLE)#g" \
+	     $(PROJ_SRC_DIR)/lit.site.cfg.in > $@
+
+clean::
+	@ find . -name Output | xargs rm -fr
+
+.PHONY: all report clean
diff --git a/test/Misc/Inputs/remapped-file b/test/Misc/Inputs/remapped-file
new file mode 100644
index 0000000..657613e
--- /dev/null
+++ b/test/Misc/Inputs/remapped-file
@@ -0,0 +1 @@
+int *f(float *fp) { return fp; }
diff --git a/test/Misc/Inputs/remapped-file-2 b/test/Misc/Inputs/remapped-file-2
new file mode 100644
index 0000000..9ac034a
--- /dev/null
+++ b/test/Misc/Inputs/remapped-file-2
@@ -0,0 +1,3 @@
+#include "nonexistent.h"
+
+int *f() { return fp; }
diff --git a/test/Misc/Inputs/remapped-file-3 b/test/Misc/Inputs/remapped-file-3
new file mode 100644
index 0000000..b7ab613
--- /dev/null
+++ b/test/Misc/Inputs/remapped-file-3
@@ -0,0 +1,2 @@
+extern float *fp;
+
diff --git a/test/Misc/caret-diags-macros.c b/test/Misc/caret-diags-macros.c
new file mode 100644
index 0000000..e138f59
--- /dev/null
+++ b/test/Misc/caret-diags-macros.c
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -fsyntax-only %s > %t 2>&1
+
+#define M1(x) x
+
+// RUN: grep ":6:12: note: instantiated from:" %t
+#define M2 1;
+
+void foo() {
+ // RUN: grep ":10:2: warning: expression result unused" %t
+ M1(
+ // RUN: grep ":12:5: note: instantiated from:" %t
+    M2)
+}
+
+// RUN: grep ":16:11: note: instantiated from:" %t
+#define A 1
+// RUN: grep ":18:11: note: instantiated from:" %t
+#define B A
+// RUN: grep ":20:11: note: instantiated from:" %t
+#define C B
+
+void bar() {
+  // RUN: grep  ":24:3: warning: expression result unused" %t
+  C;
+}
+
+
+// rdar://7597492
+#define sprintf(str, A, B) \
+__builtin___sprintf_chk (str, 0, 42, A, B)
+
+void baz(char *Msg) {
+  sprintf(Msg,  "  sizeof FoooLib            : =%3u\n",   12LL);
+}
+
diff --git a/test/Misc/caret-diags-scratch-buffer.c b/test/Misc/caret-diags-scratch-buffer.c
new file mode 100644
index 0000000..883c68e
--- /dev/null
+++ b/test/Misc/caret-diags-scratch-buffer.c
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fsyntax-only %s 2>&1 | not grep keyXXXX
+// This should not show keyXXXX in the caret diag output.  This once
+// happened because the two tokens ended up in the scratch buffer and
+// the caret diag from the scratch buffer included the previous token.
+#define M(name) \
+    if (name ## XXXX != name ## _sb);
+
+void foo() {
+  int keyXXXX;
+  M(key);
+}
+
diff --git a/test/Misc/diag-mapping.c b/test/Misc/diag-mapping.c
new file mode 100644
index 0000000..75b49ef
--- /dev/null
+++ b/test/Misc/diag-mapping.c
@@ -0,0 +1,30 @@
+// This should warn by default.
+// RUN: %clang_cc1 %s 2>&1 | grep "warning:"
+// This should not emit anything.
+// RUN: %clang_cc1 %s -Wno-extra-tokens 2>&1 | not grep diagnostic
+
+// -Werror can map all warnings to error.
+// RUN: %clang_cc1 %s -Werror 2>&1 | grep "error:"
+
+// -Werror can map this one warning to error.
+// RUN: %clang_cc1 %s -Werror=extra-tokens 2>&1 | grep "error:"
+
+// Mapping unrelated diags to errors doesn't affect this one.
+// RUN: %clang_cc1 %s -Werror=trigraphs 2>&1 | grep "warning:"
+
+// This should stay a warning with -pedantic.
+// RUN: %clang_cc1 %s -pedantic 2>&1 | grep "warning:"
+
+// This should emit an error with -pedantic-errors.
+// RUN: %clang_cc1 %s -pedantic-errors 2>&1 | grep "error:"
+
+// This should emit a warning, because -Wfoo overrides -pedantic*.
+// RUN: %clang_cc1 %s -pedantic-errors -Wextra-tokens 2>&1 | grep "warning:"
+
+// This should emit nothing, because -Wno-extra-tokens overrides -pedantic*
+// RUN: %clang_cc1 %s -pedantic-errors -Wno-extra-tokens 2>&1 | not grep diagnostic
+
+#ifdef foo
+#endif bad // extension!
+
+int x;
diff --git a/test/Misc/diag-mapping2.c b/test/Misc/diag-mapping2.c
new file mode 100644
index 0000000..bc5a087
--- /dev/null
+++ b/test/Misc/diag-mapping2.c
@@ -0,0 +1,22 @@
+// This should warn by default.
+// RUN: %clang_cc1 %s 2>&1 | grep "warning:"
+
+// This should not emit anything.
+// RUN: %clang_cc1 %s -w 2>&1 | not grep diagnostic
+// RUN: %clang_cc1 %s -Wno-#warnings 2>&1 | not grep diagnostic
+
+// -Werror can map all warnings to error.
+// RUN: %clang_cc1 %s -Werror 2>&1 | grep "error:"
+
+// -Werror can map this one warning to error.
+// RUN: %clang_cc1 %s -Werror=#warnings 2>&1 | grep "error:"
+
+// -Wno-error= overrides -Werror.  rdar://3158301
+// RUN: %clang_cc1 %s -Werror -Wno-error=#warnings 2>&1 | grep "warning:"
+
+// -Wno-error overrides -Werror.  PR4715
+// RUN: %clang_cc1 %s -Werror -Wno-error 2>&1 | grep "warning:"
+
+#warning foo
+
+
diff --git a/test/Misc/emit-html-insert.c b/test/Misc/emit-html-insert.c
new file mode 100644
index 0000000..289c28a
--- /dev/null
+++ b/test/Misc/emit-html-insert.c
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 %s -emit-html -o - | grep ">&lt; 10; }"
+
+int a(int x) { return x
+< 10; }
diff --git a/test/Misc/emit-html.c b/test/Misc/emit-html.c
new file mode 100644
index 0000000..48c8b61
--- /dev/null
+++ b/test/Misc/emit-html.c
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 %s -emit-html -o -
+
+// rdar://6562329
+#line 42 "foo.c"
+
+// PR3635
+#define F(fmt, ...) fmt, ## __VA_ARGS__
+int main(int argc, char **argv) {
+  return F(argc, 1);
+}
+
+// PR3798
+#define FOR_ALL_FILES(f,i) i
+
+#if 0
+  FOR_ALL_FILES(f) { }
+#endif
+
diff --git a/test/Misc/message-length.c b/test/Misc/message-length.c
new file mode 100644
index 0000000..3e69b6a
--- /dev/null
+++ b/test/Misc/message-length.c
@@ -0,0 +1,42 @@
+// RUN: not %clang_cc1 -fmessage-length 72 %s 2>&1 | FileCheck -strict-whitespace %s
+// RUN: not %clang_cc1 -fmessage-length 1 %s
+// RUN: not %clang_cc1 -fmessage-length 8 %s 2>&1 | FileCheck -check-prefix=CHECK-DOT %s
+// Hack so we can check things better, force the file name and line.
+# 1 "FILE" 1
+
+/* It's tough to verify the results of this test mechanically, since
+   the length of the filename (and, therefore, how the word-wrapping
+   behaves) changes depending on where the test-suite resides in the
+   file system. */
+void f(int, float, char, float);
+
+void g() {
+      int (*fp1)(int, float, short, float) = f;
+
+  int (*fp2)(int, float, short, float) = f;
+}
+
+void a_func_to_call(int, int, int);
+
+void a_very_long_line(int *ip, float *FloatPointer) {
+  for (int ALongIndexName = 0; ALongIndexName < 100; ALongIndexName++) if (ip[ALongIndexName] == 17) a_func_to_call(ip == FloatPointer, ip[ALongIndexName], FloatPointer[ALongIndexName]);
+
+
+  int array0[] = { [3] 3, 5, 7, 4, 2, 7, 6, 3, 4, 5, 6, 7, 8, 9, 12, 345, 14, 345, 789, 234, 678, 345, 123, 765, 234 };
+}
+
+#pragma STDC CX_LIMITED_RANGE    // some long comment text and a brace, eh {}
+
+
+// CHECK: FILE:23:78
+// CHECK: {{^  ...// some long comment text and a brace, eh {} }}
+
+struct A { int x; };
+void h(struct A *a) {
+  // CHECK-DOT: member
+  // CHECK-DOT: reference
+  // CHECK-DOT: type
+  (void)a
+          .
+          x;
+}
diff --git a/test/Misc/predefines.c b/test/Misc/predefines.c
new file mode 100644
index 0000000..8e57c80
--- /dev/null
+++ b/test/Misc/predefines.c
@@ -0,0 +1,5 @@
+/* RUN: %clang_cc1 -fsyntax-only -verify -std=c89 -pedantic-errors %s
+ * rdar://6814950
+ */
+#include <stdint.h>
+
diff --git a/test/Misc/remap-file.c b/test/Misc/remap-file.c
new file mode 100644
index 0000000..003cd2e
--- /dev/null
+++ b/test/Misc/remap-file.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -remap-file "%s;%S/Inputs/remapped-file" -fsyntax-only %s 2>&1 | FileCheck -check-prefix=CHECK-EXIST %s
+// RUN: %clang_cc1 -remap-file "%S/nonexistent.c;%S/Inputs/remapped-file" -fsyntax-only %S/nonexistent.c 2>&1 | FileCheck -check-prefix=CHECK-NONEXIST %s
+// RUN: %clang_cc1 -remap-file "%S/nonexistent.c;%S/Inputs/remapped-file-2" -remap-file "%S/nonexistent.h;%S/Inputs/remapped-file-3" -fsyntax-only %S/nonexistent.c 2>&1 | FileCheck -check-prefix=CHECK-HEADER %s
+
+// CHECK-EXIST: remap-file.c:1:28: warning: incompatible pointer types
+// CHECK-NONEXIST: nonexistent.c:1:28: warning: incompatible pointer types
+// CHECK-HEADER: nonexistent.c:3:19: warning: incompatible pointer types
+int
diff --git a/test/Misc/tabstop.c b/test/Misc/tabstop.c
new file mode 100644
index 0000000..49c4d7b
--- /dev/null
+++ b/test/Misc/tabstop.c
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -ftabstop 3 -fsyntax-only %s 2>&1 | FileCheck -check-prefix=3 -strict-whitespace %s
+// RUN: %clang_cc1 -ftabstop 4 -fsyntax-only %s 2>&1 | FileCheck -check-prefix=4 -strict-whitespace %s
+// RUN: %clang_cc1 -ftabstop 5 -fsyntax-only %s 2>&1 | FileCheck -check-prefix=5 -strict-whitespace %s
+
+// tab
+	void* a = 1;
+
+// tab tab
+		void* b = 1;
+
+// 3x space tab
+   	void* c = 1;
+
+// tab at column 10
+void* d =	1;
+
+//CHECK-3: {{^   void\* a = 1;}}
+//CHECK-3: {{^      void\* b = 1;}}
+//CHECK-3: {{^      void\* c = 1;}}
+//CHECK-3: {{^void\* d =   1;}}
+
+//CHECK-4: {{^    void\* a = 1;}}
+//CHECK-4: {{^        void\* b = 1;}}
+//CHECK-4: {{^    void\* c = 1;}}
+//CHECK-4: {{^void\* d =   1;}}
+
+//CHECK-5: {{^     void\* a = 1;}}
+//CHECK-5: {{^          void\* b = 1;}}
+//CHECK-5: {{^     void\* c = 1;}}
+//CHECK-5: {{^void\* d = 1;}}
+
+// Test code modification hints
+
+void f(void)
+{
+	if (0	& 1	== 1)
+	{}
+}
+
+// CHECK-3: {{^   }}if (0 & 1   == 1)
+// CHECK-3: {{^   }}        (       )
+
+// CHECK-4: {{^    }}if (0   & 1 == 1)
+// CHECK-4: {{^    }}          (     )
+
+// CHECK-5: {{^     }}if (0     & 1  == 1)
+// CHECK-5: {{^     }}            (      )
diff --git a/test/PCH/Inputs/namespaces.h b/test/PCH/Inputs/namespaces.h
new file mode 100644
index 0000000..1bab746
--- /dev/null
+++ b/test/PCH/Inputs/namespaces.h
@@ -0,0 +1,13 @@
+// Header for PCH test namespaces.cpp
+
+namespace N1 {
+  typedef int t1;
+}
+
+namespace N1 {
+  typedef int t2;
+}
+
+namespace N2 {
+  typedef float t1;
+}
diff --git a/test/PCH/asm.c b/test/PCH/asm.c
new file mode 100644
index 0000000..99bc14d
--- /dev/null
+++ b/test/PCH/asm.c
@@ -0,0 +1,11 @@
+// Test this without pch.
+// RUN: %clang_cc1 -triple i386-unknown-unknown -include %S/asm.h -fsyntax-only -verify %s
+
+// Test with pch.
+// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-pch -o %t %S/asm.h
+// RUN: %clang_cc1 -triple i386-unknown-unknown -include-pch %t -fsyntax-only -verify %s 
+
+
+void call_f(void) { f(); }
+
+void call_clobbers(void) { clobbers(); }
diff --git a/test/PCH/asm.h b/test/PCH/asm.h
new file mode 100644
index 0000000..a568058
--- /dev/null
+++ b/test/PCH/asm.h
@@ -0,0 +1,14 @@
+// Header for the PCH test asm.c
+
+void f() {
+  int i;
+
+  asm ("foo\n" : : "a" (i + 2));
+  asm ("foo\n" : [symbolic_name] "=a" (i) : "[symbolic_name]" (i));
+}
+
+void clobbers() {
+  asm ("nop" : : : "ax", "#ax", "%ax");
+  asm ("nop" : : : "eax", "rax", "ah", "al");
+  asm ("nop" : : : "0", "%0", "#0");
+}
diff --git a/test/PCH/attrs.c b/test/PCH/attrs.c
new file mode 100644
index 0000000..c971193
--- /dev/null
+++ b/test/PCH/attrs.c
@@ -0,0 +1,8 @@
+// Test this without pch.
+// RUN: %clang_cc1 -include %S/attrs.h -fsyntax-only -verify %s
+
+// Test with pch.
+// RUN: %clang_cc1 -emit-pch -o %t %S/attrs.h
+// RUN: %clang_cc1 -include-pch %t -fsyntax-only -verify %s 
+// expected-note{{previous overload}}
+double f(double); // expected-error{{overloadable}}
diff --git a/test/PCH/attrs.h b/test/PCH/attrs.h
new file mode 100644
index 0000000..0d01565
--- /dev/null
+++ b/test/PCH/attrs.h
@@ -0,0 +1,7 @@
+// Header for PCH test exprs.c
+
+
+
+
+
+int f(int) __attribute__((overloadable));
diff --git a/test/PCH/blocks.c b/test/PCH/blocks.c
new file mode 100644
index 0000000..e749886
--- /dev/null
+++ b/test/PCH/blocks.c
@@ -0,0 +1,12 @@
+// Test this without pch.
+// RUN: %clang_cc1 -fblocks -include %S/blocks.h -fsyntax-only -emit-llvm -o - %s
+
+// Test with pch.
+// RUN: %clang_cc1 -emit-pch -fblocks -o %t %S/blocks.h
+// RUN: %clang_cc1 -fblocks -include-pch %t -fsyntax-only -emit-llvm -o - %s 
+
+int do_add(int x, int y) { return add(x, y); }
+
+int do_scaled_add(int a, int b, int s) {
+  return scaled_add(a, b, s);
+}
diff --git a/test/PCH/blocks.h b/test/PCH/blocks.h
new file mode 100644
index 0000000..af7bb6f
--- /dev/null
+++ b/test/PCH/blocks.h
@@ -0,0 +1,14 @@
+// Header for PCH test blocks.c
+
+int call_block(int (^bl)(int x, int y), int a, int b) {
+  return bl(a, b);
+}
+
+int add(int a, int b) {
+  return call_block(^(int x, int y) { return x + y; }, a, b);
+}
+
+int scaled_add(int a, int b, int s) {
+  __block int scale = s;
+  return call_block(^(int x, int y) { return x*scale + y; }, a, b);
+}
diff --git a/test/PCH/builtins.c b/test/PCH/builtins.c
new file mode 100644
index 0000000..eed2224
--- /dev/null
+++ b/test/PCH/builtins.c
@@ -0,0 +1,10 @@
+// Test this without pch.
+// RUN: %clang_cc1 -include %S/builtins.h -fsyntax-only -verify %s
+
+// Test with pch.
+// RUN: %clang_cc1 -emit-pch -o %t %S/builtins.h
+// RUN: %clang_cc1 -include-pch %t -fsyntax-only -verify %s 
+
+void hello() {
+  printf("Hello, World!");
+}
diff --git a/test/PCH/builtins.h b/test/PCH/builtins.h
new file mode 100644
index 0000000..56e4a53
--- /dev/null
+++ b/test/PCH/builtins.h
@@ -0,0 +1,2 @@
+// Header for PCH test builtins.c
+int printf(char const *, ...);
diff --git a/test/PCH/changed-files.c b/test/PCH/changed-files.c
new file mode 100644
index 0000000..d1b603b
--- /dev/null
+++ b/test/PCH/changed-files.c
@@ -0,0 +1,28 @@
+const char *s0 = m0;
+int s1 = m1;
+const char *s2 = m0;
+
+// FIXME: This test fails inexplicably on Windows in a manner that makes it 
+// look like standard error isn't getting flushed properly.
+
+// RUN: false
+// XFAIL: *
+
+// RUN: echo '#define m0 ""' > %t.h
+// RUN: %clang_cc1 -emit-pch -o %t.h.pch %t.h
+// RUN: echo '' > %t.h
+// RUN: not %clang_cc1 -include-pch %t.h.pch %s 2> %t.stderr
+// RUN: grep "modified" %t.stderr
+
+// RUN: echo '#define m0 000' > %t.h
+// RUN: %clang_cc1 -emit-pch -o %t.h.pch %t.h
+// RUN: echo '' > %t.h
+// RUN: not %clang_cc1 -include-pch %t.h.pch %s 2> %t.stderr
+// RUN: grep "modified" %t.stderr
+
+// RUN: echo '#define m0 000' > %t.h
+// RUN: echo "#define m1 'abcd'" >> %t.h
+// RUN: %clang_cc1 -emit-pch -o %t.h.pch %t.h
+// RUN: echo '' > %t.h
+// RUN: not %clang_cc1 -include-pch %t.h.pch %s 2> %t.stderr
+// RUN: grep "modified" %t.stderr
diff --git a/test/PCH/cxx-method.cpp b/test/PCH/cxx-method.cpp
new file mode 100644
index 0000000..37dabcc
--- /dev/null
+++ b/test/PCH/cxx-method.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -emit-pch %s -o %t
+
+struct S {
+  void m(int x);
+};
+
+void S::m(int x) { }
diff --git a/test/PCH/cxx_exprs.cpp b/test/PCH/cxx_exprs.cpp
new file mode 100644
index 0000000..0f0fe88
--- /dev/null
+++ b/test/PCH/cxx_exprs.cpp
@@ -0,0 +1,35 @@
+// Test this without pch.
+// RUN: %clang_cc1 -include %S/cxx_exprs.h -std=c++0x -fsyntax-only -verify %s
+
+// Test with pch.
+// RUN: %clang_cc1 -x c++-header -std=c++0x -emit-pch -o %t %S/cxx_exprs.h
+// RUN: %clang_cc1 -std=c++0x -include-pch %t -fsyntax-only -verify %s 
+
+int integer;
+double floating;
+char character;
+bool boolean;
+
+// CXXStaticCastExpr
+static_cast_result void_ptr = &integer;
+
+// CXXDynamicCastExpr
+Derived *d;
+dynamic_cast_result derived_ptr = d;
+
+// CXXReinterpretCastExpr
+reinterpret_cast_result void_ptr2 = &integer;
+
+// CXXConstCastExpr
+const_cast_result char_ptr = &character;
+
+// CXXFunctionalCastExpr
+functional_cast_result *double_ptr = &floating;
+
+// CXXBoolLiteralExpr
+bool_literal_result *bool_ptr = &boolean;
+static_assert(true_value, "true_value is true");
+static_assert(!false_value, "false_value is false");
+
+// CXXNullPtrLiteralExpr
+cxx_null_ptr_result null_ptr = nullptr;
diff --git a/test/PCH/cxx_exprs.h b/test/PCH/cxx_exprs.h
new file mode 100644
index 0000000..a871aa2
--- /dev/null
+++ b/test/PCH/cxx_exprs.h
@@ -0,0 +1,29 @@
+// Header for PCH test cxx_exprs.cpp
+
+// CXXStaticCastExpr
+typedef __typeof__(static_cast<void *>(0)) static_cast_result;
+
+// CXXDynamicCastExpr
+struct Base { virtual void f(); };
+struct Derived : Base { };
+Base *base_ptr;
+typedef __typeof__(dynamic_cast<Derived *>(base_ptr)) dynamic_cast_result;
+
+// CXXReinterpretCastExpr
+typedef __typeof__(reinterpret_cast<void *>(0)) reinterpret_cast_result;
+
+// CXXConstCastExpr
+const char *const_char_ptr_value;
+typedef __typeof__(const_cast<char *>(const_char_ptr_value)) const_cast_result;
+
+// CXXFunctionalCastExpr
+int int_value;
+typedef __typeof__(double(int_value)) functional_cast_result;
+
+// CXXBoolLiteralExpr
+typedef __typeof__(true) bool_literal_result;
+const bool true_value = true;
+const bool false_value = false;
+
+// CXXNullPtrLiteralExpr
+typedef __typeof__(nullptr) cxx_null_ptr_result;
diff --git a/test/PCH/enum.c b/test/PCH/enum.c
new file mode 100644
index 0000000..10ceb7c
--- /dev/null
+++ b/test/PCH/enum.c
@@ -0,0 +1,15 @@
+// Test this without pch.
+// RUN: %clang_cc1 -include %S/enum.h -fsyntax-only -verify %s
+
+// Test with pch.
+// RUN: %clang_cc1 -emit-pch -o %t %S/enum.h
+// RUN: %clang_cc1 -include-pch %t -fsyntax-only -verify %s 
+
+int i = Red;
+
+int return_enum_constant() {
+  int result = aRoundShape;
+  return result;
+}
+
+enum Shape s = Triangle;
diff --git a/test/PCH/enum.h b/test/PCH/enum.h
new file mode 100644
index 0000000..7dc4e63
--- /dev/null
+++ b/test/PCH/enum.h
@@ -0,0 +1,16 @@
+/* Used in enum.c test */
+
+enum Color {
+  Red,
+  Green,
+  Blue
+};
+
+enum Shape {
+  Square,
+  Triangle = 17,
+  Rhombus,
+  Circle
+};
+
+enum Shape aRoundShape = Circle;
diff --git a/test/PCH/exprs.c b/test/PCH/exprs.c
new file mode 100644
index 0000000..2b588a2
--- /dev/null
+++ b/test/PCH/exprs.c
@@ -0,0 +1,89 @@
+// Test this without pch.
+// RUN: %clang_cc1 -fblocks -include %S/exprs.h -fsyntax-only -verify %s
+
+// Test with pch.
+// RUN: %clang_cc1 -emit-pch -fblocks -o %t %S/exprs.h
+// RUN: %clang_cc1 -fblocks -include-pch %t -fsyntax-only -verify %s 
+
+int integer;
+long long_integer;
+double floating;
+_Complex double floating_complex;
+
+// DeclRefExpr
+int_decl_ref *int_ptr1 = &integer;
+enum_decl_ref *enum_ptr1 = &integer;
+
+// IntegerLiteral
+integer_literal *int_ptr2 = &integer;
+long_literal *long_ptr1 = &long_integer;
+
+// FloatingLiteral + ParenExpr
+floating_literal *double_ptr = &floating;
+
+// ImaginaryLiteral
+imaginary_literal *cdouble_ptr = &floating_complex;
+
+// StringLiteral
+const char* printHello() {
+  return hello;
+}
+
+// CharacterLiteral
+char_literal *int_ptr3 = &integer;
+
+// UnaryOperator
+negate_enum *int_ptr4 = &integer;
+
+// SizeOfAlignOfExpr
+typeof(sizeof(float)) size_t_value;
+typeof_sizeof *size_t_ptr = &size_t_value;
+typeof_sizeof2 *size_t_ptr2 = &size_t_value;
+
+// ArraySubscriptExpr
+array_subscript *double_ptr1_5 = &floating;
+
+// CallExpr
+call_returning_double *double_ptr2 = &floating;
+
+// MemberExpr
+member_ref_double *double_ptr3 = &floating;
+
+// BinaryOperator
+add_result *int_ptr5 = &integer;
+
+// CompoundAssignOperator
+addeq_result *int_ptr6 = &integer;
+
+// ConditionalOperator
+conditional_operator *double_ptr4 = &floating;
+
+// CStyleCastExpr
+void_ptr vp1 = &integer;
+
+// CompoundLiteral
+struct S s;
+compound_literal *sptr = &s;
+
+// ExtVectorElementExpr
+ext_vector_element *double_ptr5 = &floating;
+
+// InitListExpr
+double get_from_double_array(unsigned Idx) { return double_array[Idx]; }
+
+/// DesignatedInitExpr
+float get_from_designated(unsigned Idx) {
+  return designated_inits[2].y;
+}
+
+// TypesCompatibleExpr
+types_compatible *int_ptr7 = &integer;
+
+// ChooseExpr
+choose_expr *int_ptr8 = &integer;
+
+// GNUNullExpr FIXME: needs C++
+//null_type null = __null;
+
+// ShuffleVectorExpr
+shuffle_expr *vec_ptr = &vec2;
diff --git a/test/PCH/exprs.h b/test/PCH/exprs.h
new file mode 100644
index 0000000..7012422
--- /dev/null
+++ b/test/PCH/exprs.h
@@ -0,0 +1,86 @@
+// Header for PCH test exprs.c
+
+// DeclRefExpr
+int i = 17;
+enum Enum { Enumerator = 18 };
+typedef typeof(i) int_decl_ref;
+typedef typeof(Enumerator) enum_decl_ref;
+
+// IntegerLiteral
+typedef typeof(17) integer_literal;
+typedef typeof(17l) long_literal;
+
+// FloatingLiteral and ParenExpr
+typedef typeof((42.5)) floating_literal;
+
+// ImaginaryLiteral
+typedef typeof(17.0i) imaginary_literal;
+
+// StringLiteral
+const char *hello = "Hello" "PCH" "World";
+
+// CharacterLiteral
+typedef typeof('a') char_literal;
+
+// UnaryOperator
+typedef typeof(-Enumerator) negate_enum;
+
+// SizeOfAlignOfExpr
+typedef typeof(sizeof(int)) typeof_sizeof;
+typedef typeof(sizeof(Enumerator)) typeof_sizeof2;
+
+// ArraySubscriptExpr
+extern double values[];
+typedef typeof(values[2]) array_subscript;
+
+// CallExpr
+double dplus(double x, double y);
+double d0, d1;
+typedef typeof((&dplus)(d0, d1)) call_returning_double;
+
+// MemberExpr
+struct S {
+  double x;
+};
+typedef typeof(((struct S*)0)->x) member_ref_double;
+
+// BinaryOperator
+typedef typeof(i + Enumerator) add_result;
+
+// CompoundAssignOperator
+typedef typeof(i += Enumerator) addeq_result;
+
+// ConditionalOperator
+typedef typeof(i? : d0) conditional_operator;
+
+// CStyleCastExpr
+typedef typeof((void *)0) void_ptr;
+
+// CompoundLiteral
+typedef typeof((struct S){.x = 3.5}) compound_literal;
+
+// ExtVectorElementExpr
+typedef __attribute__(( ext_vector_type(2) )) double double2;
+extern double2 vec2, vec2b;
+typedef typeof(vec2.x) ext_vector_element;
+
+// InitListExpr
+double double_array[3] = { 1.0, 2.0 };
+
+// DesignatedInitExpr
+struct {
+  int x;
+  float y;
+} designated_inits[3] = { [0].y = 17, [2].x = 12.3, 3.5 };
+
+// TypesCompatibleExpr
+typedef typeof(__builtin_types_compatible_p(float, double)) types_compatible;
+
+// ChooseExpr
+typedef typeof(__builtin_choose_expr(17 > 19, d0, 1)) choose_expr;
+
+// GNUNullExpr FIXME: needs C++
+// typedef typeof(__null) null_type;
+
+// ShuffleVectorExpr
+typedef typeof(__builtin_shufflevector(vec2, vec2b, 2, 1)) shuffle_expr;
diff --git a/test/PCH/ext_vector.c b/test/PCH/ext_vector.c
new file mode 100644
index 0000000..bd129ea
--- /dev/null
+++ b/test/PCH/ext_vector.c
@@ -0,0 +1,10 @@
+// Test this without pch.
+// RUN: %clang_cc1 -include %S/ext_vector.h -fsyntax-only -verify %s
+
+// Test with pch.
+// RUN: %clang_cc1 -emit-pch -o %t %S/ext_vector.h
+// RUN: %clang_cc1 -include-pch %t -fsyntax-only -verify %s 
+
+int test(float4 f4) {
+  return f4.xy; // expected-error{{float2}}
+}
diff --git a/test/PCH/ext_vector.h b/test/PCH/ext_vector.h
new file mode 100644
index 0000000..39ab923
--- /dev/null
+++ b/test/PCH/ext_vector.h
@@ -0,0 +1,4 @@
+// Header file for ext_vector.c PCH test
+
+typedef __attribute__((ext_vector_type(2))) float float2;
+typedef __attribute__((ext_vector_type(4))) float float4;
diff --git a/test/PCH/external-defs.c b/test/PCH/external-defs.c
new file mode 100644
index 0000000..5097859
--- /dev/null
+++ b/test/PCH/external-defs.c
@@ -0,0 +1,19 @@
+// Test with pch.
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -emit-pch -o %t.pch %S/external-defs.h
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -include-pch %t.pch -emit-llvm -o %t %s
+
+// RUN: grep "@x = common global i32 0" %t | count 1
+// RUN: grep "@z" %t | count 0
+
+// RUN: grep "@x2 = global i32 19" %t | count 1
+int x2 = 19;
+
+// RUN: grep "@incomplete_array = common global .*1 x i32" %t | count 1
+// RUN: grep "@incomplete_array2 = common global .*17 x i32" %t | count 1
+int incomplete_array2[17];
+// RUN: grep "@incomplete_array3 = common global .*1 x i32" %t | count 1
+int incomplete_array3[];
+
+struct S {
+  int x, y;
+};
diff --git a/test/PCH/external-defs.h b/test/PCH/external-defs.h
new file mode 100644
index 0000000..657b47b
--- /dev/null
+++ b/test/PCH/external-defs.h
@@ -0,0 +1,13 @@
+// Helper for external-defs.c test
+
+// Tentative definitions
+int x;
+int x2;
+
+// Should not show up
+static int z;
+
+int incomplete_array[];
+int incomplete_array2[];
+
+struct S s;
diff --git a/test/PCH/functions.c b/test/PCH/functions.c
new file mode 100644
index 0000000..23becb6
--- /dev/null
+++ b/test/PCH/functions.c
@@ -0,0 +1,25 @@
+// Test this without pch.
+// RUN: %clang_cc1 -include %S/functions.h -fsyntax-only -verify %s
+
+// Test with pch.
+// RUN: %clang_cc1 -emit-pch -o %t %S/functions.h
+// RUN: %clang_cc1 -include-pch %t -fsyntax-only -verify %s 
+
+int f0(int x0, int y0, ...) { return x0 + y0; }
+// expected-note{{passing argument to parameter here}}
+float *test_f1(int val, double x, double y) {
+  if (val > 5)
+    return f1(x, y);
+  else
+    return f1(x); // expected-error{{too few arguments to function call}}
+}
+
+void test_g0(int *x, float * y) {
+  g0(y); // expected-warning{{incompatible pointer types passing 'float *' to parameter of type 'int *'}}
+  g0(x); 
+}
+
+void __attribute__((noreturn)) test_abort(int code) {
+  do_abort(code);
+}
+  
diff --git a/test/PCH/functions.h b/test/PCH/functions.h
new file mode 100644
index 0000000..f57400f
--- /dev/null
+++ b/test/PCH/functions.h
@@ -0,0 +1,11 @@
+/* For use with the functions.c test */
+
+
+
+
+int f0(int x, int y, ...); 
+float *f1(float x, float y);
+
+void g0(int *);
+
+void do_abort(int) __attribute__((noreturn));
diff --git a/test/PCH/fuzzy-pch.c b/test/PCH/fuzzy-pch.c
new file mode 100644
index 0000000..5675753
--- /dev/null
+++ b/test/PCH/fuzzy-pch.c
@@ -0,0 +1,19 @@
+// Test with pch.
+// RUN: %clang_cc1 -emit-pch -DFOO -o %t %S/variables.h
+// RUN: %clang_cc1 -DBAR=int -include-pch %t -fsyntax-only -pedantic %s
+// RUN: %clang_cc1 -DFOO -DBAR=int -include-pch %t -Werror %s
+// RUN: not %clang_cc1 -DFOO -DBAR=int -DX=5 -include-pch %t -Werror %s 
+
+BAR bar = 17;
+
+#ifndef FOO
+#  error FOO was not defined
+#endif
+
+#if FOO != 1
+#  error FOO has the wrong definition
+#endif
+
+#ifndef BAR
+#  error BAR was not defined
+#endif
diff --git a/test/PCH/fuzzy-pch.h b/test/PCH/fuzzy-pch.h
new file mode 100644
index 0000000..9eb1005
--- /dev/null
+++ b/test/PCH/fuzzy-pch.h
@@ -0,0 +1,2 @@
+// Header for PCH test fuzzy-pch.c
+void f(int X);
diff --git a/test/PCH/headermap.h b/test/PCH/headermap.h
new file mode 100644
index 0000000..efab2d8
--- /dev/null
+++ b/test/PCH/headermap.h
@@ -0,0 +1,3 @@
+/* Helper for the headermap.m test */
+int x = 17;
+
diff --git a/test/PCH/headermap.m b/test/PCH/headermap.m
new file mode 100644
index 0000000..6ba83d7
--- /dev/null
+++ b/test/PCH/headermap.m
@@ -0,0 +1,15 @@
+// RUN: touch %t.hmap
+
+// RUN: %clang_cc1 -x objective-c -emit-pch -o %t.h.pch %S/headermap.h
+// RUN: %clang_cc1 -include-pch %t.h.pch %s
+
+// RUN: %clang_cc1 -x objective-c -emit-pch -o %t.h.pch %S/headermap.h
+// RUN: %clang_cc1 -include-pch %t.h.pch -I%t.hmap %s
+
+// RUN: %clang_cc1 -x objective-c -I%t.hmap -emit-pch -o %t.h.pch %S/headermap.h
+// RUN: %clang_cc1 -include-pch %t.h.pch %s
+
+// RUN: %clang_cc1 -x objective-c -I%t.hmap -emit-pch -o %t.h.pch %S/headermap.h
+// RUN: %clang_cc1 -include-pch %t.h.pch -I%t.hmap %s
+#import "headermap.h"
+
diff --git a/test/PCH/libroot/usr/include/reloc.h b/test/PCH/libroot/usr/include/reloc.h
new file mode 100644
index 0000000..04eeacb
--- /dev/null
+++ b/test/PCH/libroot/usr/include/reloc.h
@@ -0,0 +1,15 @@
+#ifndef RELOC_H
+#define RELOC_H
+
+#include <reloc2.h>
+
+
+
+
+
+
+
+// Line number 13 below is important
+int x = 2;
+
+#endif // RELOC_H
diff --git a/test/PCH/libroot/usr/include/reloc2.h b/test/PCH/libroot/usr/include/reloc2.h
new file mode 100644
index 0000000..995415c
--- /dev/null
+++ b/test/PCH/libroot/usr/include/reloc2.h
@@ -0,0 +1,15 @@
+#ifndef RELOC2_H
+#define RELOC2_H
+#include <stddef.h>
+
+
+
+
+
+
+
+
+
+// Line number below is important!
+int y = 2;
+#endif // RELOC2_H
diff --git a/test/PCH/line-directive.c b/test/PCH/line-directive.c
new file mode 100644
index 0000000..4710c40
--- /dev/null
+++ b/test/PCH/line-directive.c
@@ -0,0 +1,25 @@
+// Test this without pch.
+// RUN: %clang_cc1 -include %S/line-directive.h -fsyntax-only %s 2>&1|grep "25:5"
+
+// Test with pch.
+// RUN: %clang_cc1 -emit-pch -o %t %S/line-directive.h
+// RUN: %clang_cc1 -include-pch %t -fsyntax-only %s 2>&1|grep "25:5"  
+
+double x; // expected-error{{redefinition of 'x' with a different type}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// expected-note{{previous definition is here}}
diff --git a/test/PCH/line-directive.h b/test/PCH/line-directive.h
new file mode 100644
index 0000000..c5594b4
--- /dev/null
+++ b/test/PCH/line-directive.h
@@ -0,0 +1,2 @@
+#line 25 "line-directive.c"
+int x;
diff --git a/test/PCH/method_pool.h b/test/PCH/method_pool.h
new file mode 100644
index 0000000..8085836
--- /dev/null
+++ b/test/PCH/method_pool.h
@@ -0,0 +1,36 @@
+/* For use with the method_pool.m test */
+
+/* Whitespace below is significant */
+
+
+
+
+
+
+
+
+
+
+
+@interface TestMethodPool1
++ alloc;
+- (double)instMethod:(int)foo;
+@end
+
+@interface TestMethodPool2
+- (char)instMethod:(int)foo;
+@end
+
+@implementation TestMethodPool1
++ alloc { return 0; }
+
+- (double)instMethod:(int)foo {
+  return foo;
+}
+@end
+
+@implementation TestMethodPool2
+- (char)instMethod:(int)foo {
+  return foo;
+}
+@end
diff --git a/test/PCH/method_pool.m b/test/PCH/method_pool.m
new file mode 100644
index 0000000..ee53784
--- /dev/null
+++ b/test/PCH/method_pool.m
@@ -0,0 +1,21 @@
+// Test this without pch.
+// RUN: %clang_cc1 -include %S/method_pool.h -fsyntax-only -verify %s
+
+// Test with pch.
+// RUN: %clang_cc1 -x objective-c -emit-pch -o %t %S/method_pool.h
+// RUN: %clang_cc1 -include-pch %t -fsyntax-only -verify %s 
+
+int message_id(id x) {
+   return [x instMethod:17]; // expected-warning{{multiple methods}}
+}
+
+
+
+
+
+/* Whitespace below is significant */
+/* expected-note{{using}} */
+
+
+
+/* expected-note{{also}} */
diff --git a/test/PCH/multiple_decls.c b/test/PCH/multiple_decls.c
new file mode 100644
index 0000000..e2cc552
--- /dev/null
+++ b/test/PCH/multiple_decls.c
@@ -0,0 +1,17 @@
+// Test this without pch.
+// RUN: %clang_cc1 -include %S/multiple_decls.h -fsyntax-only -ast-print -o - %s
+
+// Test with pch.
+// RUN: %clang_cc1 -emit-pch -o %t %S/multiple_decls.h
+// RUN: %clang_cc1 -include-pch %t -fsyntax-only -ast-print -o - %s 
+
+void f0(char c) {
+  wide(c);
+}
+
+struct wide w;
+struct narrow n;
+
+void f1(int i) {
+  narrow(i);
+}
diff --git a/test/PCH/multiple_decls.h b/test/PCH/multiple_decls.h
new file mode 100644
index 0000000..23696b0
--- /dev/null
+++ b/test/PCH/multiple_decls.h
@@ -0,0 +1,7 @@
+// Header for PCH test multiple_decls.c
+
+struct wide { int value; };
+int wide(char);
+
+struct narrow { char narrow; };
+char narrow(int);
diff --git a/test/PCH/namespaces.cpp b/test/PCH/namespaces.cpp
new file mode 100644
index 0000000..eef9e06
--- /dev/null
+++ b/test/PCH/namespaces.cpp
@@ -0,0 +1,14 @@
+// Test this without pch.
+// RUN: %clang_cc1 -x c++ -include %S/Inputs/namespaces.h -fsyntax-only %s
+
+// Test with pch.
+// RUN: %clang_cc1 -x c++ -emit-pch -o %t %S/Inputs/namespaces.h
+// RUN: %clang_cc1 -x c++ -include-pch %t -fsyntax-only %s 
+
+int int_val;
+N1::t1 *ip1 = &int_val;
+N1::t2 *ip2 = &int_val;
+
+float float_val;
+namespace N2 { }
+N2::t1 *fp1 = &float_val;
diff --git a/test/PCH/nonvisible-external-defs.c b/test/PCH/nonvisible-external-defs.c
new file mode 100644
index 0000000..49392ca
--- /dev/null
+++ b/test/PCH/nonvisible-external-defs.c
@@ -0,0 +1,10 @@
+// Test this without pch.
+// RUN: %clang_cc1 -include %S/nonvisible-external-defs.h -fsyntax-only -verify %s
+
+// Test with pch.
+// RUN: %clang_cc1 -emit-pch -o %t %S/nonvisible-external-defs.h
+// RUN: %clang_cc1 -include-pch %t -fsyntax-only -verify %s 
+
+int g(int, float); // expected-error{{conflicting types}}
+
+// expected-note{{previous declaration}}
diff --git a/test/PCH/nonvisible-external-defs.h b/test/PCH/nonvisible-external-defs.h
new file mode 100644
index 0000000..a36fc2e
--- /dev/null
+++ b/test/PCH/nonvisible-external-defs.h
@@ -0,0 +1,11 @@
+// Helper for PCH test nonvisible-external-defs.h
+
+
+
+
+
+
+
+void f() {
+  extern int g(int, int);
+}
diff --git a/test/PCH/objc_exprs.h b/test/PCH/objc_exprs.h
new file mode 100644
index 0000000..b811430
--- /dev/null
+++ b/test/PCH/objc_exprs.h
@@ -0,0 +1,18 @@
+
+@protocol foo;
+@class itf;
+
+// Expressions
+typedef typeof(@"foo" "bar") objc_string;
+typedef typeof(@encode(int)) objc_encode;
+typedef typeof(@protocol(foo)) objc_protocol;
+typedef typeof(@selector(noArgs)) objc_selector_noArgs;
+typedef typeof(@selector(oneArg:)) objc_selector_oneArg;
+typedef typeof(@selector(foo:bar:)) objc_selector_twoArg;
+
+
+// Types.
+typedef typeof(id<foo>) objc_id_protocol_ty;
+
+typedef typeof(itf*) objc_interface_ty;
+typedef typeof(itf<foo>*) objc_qual_interface_ty;
diff --git a/test/PCH/objc_exprs.m b/test/PCH/objc_exprs.m
new file mode 100644
index 0000000..c37968b
--- /dev/null
+++ b/test/PCH/objc_exprs.m
@@ -0,0 +1,27 @@
+// Test this without pch.
+// RUN: %clang_cc1 -fblocks -include %S/objc_exprs.h -fsyntax-only -verify %s
+
+// Test with pch.
+// RUN: %clang_cc1 -x objective-c-header -emit-pch -fblocks -o %t %S/objc_exprs.h
+// RUN: %clang_cc1 -fblocks -include-pch %t -fsyntax-only -verify %s 
+
+// Expressions
+int *A1 = (objc_string)0;   // expected-warning {{aka 'id'}}
+
+char A2 = (objc_encode){};  // expected-error {{not a compile-time constant}} \
+                               expected-warning {{char [2]}}
+
+int *A3 = (objc_protocol)0; // expected-warning {{aka 'Protocol *'}}
+
+
+// Types.
+int *T0 = (objc_id_protocol_ty)0; // expected-warning {{aka 'id<foo>'}}
+
+int *T1 = (objc_interface_ty)0; // expected-warning {{aka 'itf *'}}
+int *T2 = (objc_qual_interface_ty)0; // expected-warning {{aka 'itf<foo> *'}}
+
+objc_selector_noArgs s1;
+objc_selector_oneArg s2;
+objc_selector_twoArg s3;
+
+
diff --git a/test/PCH/objc_import.h b/test/PCH/objc_import.h
new file mode 100644
index 0000000..8af87ab
--- /dev/null
+++ b/test/PCH/objc_import.h
@@ -0,0 +1,7 @@
+/* For use with the objc_import.m test */
+
+@interface TestPCH
++ alloc;
+- (void)instMethod;
+@end
+
diff --git a/test/PCH/objc_import.m b/test/PCH/objc_import.m
new file mode 100644
index 0000000..277c6dd
--- /dev/null
+++ b/test/PCH/objc_import.m
@@ -0,0 +1,15 @@
+// Test this without pch.
+// RUN: %clang_cc1 -include %S/objc_import.h -fsyntax-only -verify %s
+
+// Test with pch.
+// RUN: %clang_cc1 -x objective-c -emit-pch -o %t %S/objc_import.h
+// RUN: %clang_cc1 -include-pch %t -fsyntax-only -verify %s 
+
+#import "objc_import.h"
+
+void func() {
+ TestPCH *xx;
+
+ xx = [TestPCH alloc];
+ [xx instMethod];
+}
diff --git a/test/PCH/objc_methods.h b/test/PCH/objc_methods.h
new file mode 100644
index 0000000..4c6b1e1
--- /dev/null
+++ b/test/PCH/objc_methods.h
@@ -0,0 +1,11 @@
+/* For use with the methods.m test */
+
+@interface TestPCH
++ alloc;
+- (void)instMethod;
+@end
+
+@class TestForwardClassDecl;
+
+// FIXME: @compatibility_alias  AliasForTestPCH TestPCH;
+
diff --git a/test/PCH/objc_methods.m b/test/PCH/objc_methods.m
new file mode 100644
index 0000000..e90a463
--- /dev/null
+++ b/test/PCH/objc_methods.m
@@ -0,0 +1,16 @@
+// Test this without pch.
+// RUN: %clang_cc1 -include %S/objc_methods.h -fsyntax-only -verify %s
+
+// Test with pch.
+// RUN: %clang_cc1 -x objective-c -emit-pch -o %t %S/objc_methods.h
+// RUN: %clang_cc1 -include-pch %t -fsyntax-only -verify %s 
+
+void func() {
+ TestPCH *xx;
+ TestForwardClassDecl *yy;
+// FIXME:
+// AliasForTestPCH *zz;
+ 
+ xx = [TestPCH alloc];
+ [xx instMethod];
+}
diff --git a/test/PCH/objc_property.h b/test/PCH/objc_property.h
new file mode 100644
index 0000000..2432370
--- /dev/null
+++ b/test/PCH/objc_property.h
@@ -0,0 +1,12 @@
+/* For use with the objc_property.m PCH test */
+@interface TestProperties
+{
+  int value;
+  float percentage;
+}
+
++ alloc;
+
+@property int value;
+@property float percentage;
+@end
diff --git a/test/PCH/objc_property.m b/test/PCH/objc_property.m
new file mode 100644
index 0000000..b51cd90
--- /dev/null
+++ b/test/PCH/objc_property.m
@@ -0,0 +1,11 @@
+// Test this without pch.
+// RUN: %clang_cc1 -include %S/objc_property.h -fsyntax-only -verify %s
+
+// Test with pch.
+// RUN: %clang_cc1 -x objective-c -emit-pch -o %t %S/objc_property.h
+// RUN: %clang_cc1 -include-pch %t -fsyntax-only -verify %s 
+
+void func() {
+ TestProperties *xx = [TestProperties alloc];
+ xx.value = 5;
+}
diff --git a/test/PCH/objc_stmts.h b/test/PCH/objc_stmts.h
new file mode 100644
index 0000000..5f705df
--- /dev/null
+++ b/test/PCH/objc_stmts.h
@@ -0,0 +1,22 @@
+/* For use with the methods.m test */
+
+@interface A
+@end
+
+@interface B
+@end
+
+@interface TestPCH
+- (void)instMethod;
+@end
+
+@implementation TestPCH
+- (void)instMethod {
+  @try {
+  } @catch(A *a) {
+  } @catch(B *b) {
+  } @catch(...) {
+  } @finally {
+  }
+}
+@end
diff --git a/test/PCH/objc_stmts.m b/test/PCH/objc_stmts.m
new file mode 100644
index 0000000..ed7466a
--- /dev/null
+++ b/test/PCH/objc_stmts.m
@@ -0,0 +1,12 @@
+// Test this without pch.
+// RUN: %clang_cc1 -include %S/objc_stmts.h -emit-llvm -o - %s
+// RUN: %clang_cc1 -include %S/objc_stmts.h -ast-dump -o - %s 2>&1 | FileCheck %s
+
+// Test with pch.
+// RUN: %clang_cc1 -x objective-c -emit-pch -o %t %S/objc_stmts.h
+// RUN: %clang_cc1 -include-pch %t -emit-llvm -o - %s 
+// RUN: %clang_cc1 -include-pch %t -ast-dump -o - %s 2>&1 | FileCheck %s
+
+// CHECK: catch parm = "A *a"
+// CHECK: catch parm = "B *b"
+// CHECK: catch all
diff --git a/test/PCH/pr4489.c b/test/PCH/pr4489.c
new file mode 100644
index 0000000..033e55b
--- /dev/null
+++ b/test/PCH/pr4489.c
@@ -0,0 +1,48 @@
+// RUN: %clang -x c-header -o %t.pch %s
+// RUN: echo > %t.empty.c
+// RUN: %clang -include %t -x c %t.empty.c -emit-llvm -S -o -
+
+// FIXME: This test is forcibly disabled, it is flaky on the clang-i686-xp-msvc9
+// buildbot.
+//
+// RUN: false
+// XFAIL: *
+
+// PR 4489: Crash with PCH
+// PR 4492: Crash with PCH (round two)
+// PR 4509: Crash with PCH (round three)
+typedef struct _IO_FILE FILE;
+extern int fprintf (struct _IO_FILE *__restrict __stream,
+                    __const char *__restrict __format, ...);
+
+int x(void)
+{
+  switch (1) {
+    case 2: ;
+      int y = 0;
+  }
+}
+
+void y(void) {
+  extern char z;
+  fprintf (0, "a");
+}
+
+struct y0 { int i; } y0[1] = {};
+
+void x0(void)
+{
+  extern char z0;
+  fprintf (0, "a");
+}
+
+void x1(void)
+{
+  fprintf (0, "asdf");
+}
+
+void y1(void)
+{
+  extern char e;
+  fprintf (0, "asdf");
+}
diff --git a/test/PCH/preprocess.c b/test/PCH/preprocess.c
new file mode 100644
index 0000000..8bf841f
--- /dev/null
+++ b/test/PCH/preprocess.c
@@ -0,0 +1,8 @@
+// Check that -E mode is invariant when using an implicit PCH.
+
+// RUN: %clang_cc1 -include %S/preprocess.h -E -o %t.orig %s
+// RUN: %clang_cc1 -emit-pch -o %t %S/preprocess.h
+// RUN: %clang_cc1 -include-pch %t -E -o %t.from_pch %s
+// RUN: diff %t.orig %t.from_pch
+
+a_typedef a_value;
diff --git a/test/PCH/preprocess.h b/test/PCH/preprocess.h
new file mode 100644
index 0000000..39fa006
--- /dev/null
+++ b/test/PCH/preprocess.h
@@ -0,0 +1,7 @@
+// Helper header for preprocess.c PCH test
+#ifndef PREPROCESS_H
+#define PREPROCESS_H
+
+typedef int a_typedef;
+
+#endif // PREPROCESS_H
diff --git a/test/PCH/reloc.c b/test/PCH/reloc.c
new file mode 100644
index 0000000..fd78feb
--- /dev/null
+++ b/test/PCH/reloc.c
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -emit-pch -o %t -relocatable-pch -isysroot %S/libroot %S/libroot/usr/include/reloc.h
+// RUN: %clang_cc1 -include-pch %t -isysroot %S/libroot %s -verify
+// RUN: not %clang_cc1 -include-pch %t %s
+
+#include <reloc.h>
+
+int x = 2; // expected-error{{redefinition}}
+int y = 5; // expected-error{{redefinition}}
+
+
+
+
+// expected-note{{previous definition}}
+// expected-note{{previous definition}}
diff --git a/test/PCH/source-manager-stack.c b/test/PCH/source-manager-stack.c
new file mode 100644
index 0000000..cc85556
--- /dev/null
+++ b/test/PCH/source-manager-stack.c
@@ -0,0 +1,12 @@
+// Test that the source manager has the "proper" idea about the include stack
+// when using PCH.
+
+// RUN: echo 'int x;' > %t.prefix.h
+// RUN: not %clang_cc1 -fsyntax-only -include %t.prefix.h %s 2> %t.diags.no_pch.txt
+// RUN: %clang_cc1 -emit-pch -o %t.prefix.pch %t.prefix.h
+// RUN: not %clang_cc1 -fsyntax-only -include-pch %t.prefix.pch %s 2> %t.diags.pch.txt
+// RUN: diff %t.diags.no_pch.txt %t.diags.pch.txt
+// XFAIL: *
+// PR5662
+
+float x;
diff --git a/test/PCH/stmts.c b/test/PCH/stmts.c
new file mode 100644
index 0000000..6def453
--- /dev/null
+++ b/test/PCH/stmts.c
@@ -0,0 +1,14 @@
+// Test this without pch.
+// RUN: %clang_cc1 -include %S/stmts.h -fsyntax-only -emit-llvm -o - %s
+
+// Test with pch.
+// RUN: %clang_cc1 -emit-pch -o %t %S/stmts.h
+// RUN: %clang_cc1 -include-pch %t -fsyntax-only -emit-llvm -o - %s 
+
+void g0(void) { f0(5); }
+int g1(int x) { return f1(x); }
+const char* query_name(void) { return what_is_my_name(); }
+
+int use_computed_goto(int x) { return computed_goto(x); }
+
+int get_weird_max(int x, int y) { return weird_max(x, y); }
diff --git a/test/PCH/stmts.h b/test/PCH/stmts.h
new file mode 100644
index 0000000..4267e2c
--- /dev/null
+++ b/test/PCH/stmts.h
@@ -0,0 +1,96 @@
+// Header for PCH test stmts.c
+
+void f0(int x) { 
+  // NullStmt
+  ;
+  // IfStmt
+  if (x) {
+  } else if (x + 1) {
+  }
+
+  switch (x) {
+  case 0:
+    x = 17;
+    break;
+
+  case 1:
+    break;
+
+  default:
+    switch (x >> 1) {
+    case 7:
+      // fall through
+    case 9:
+      break;
+    }
+    x += 2;
+    break;
+  }
+
+  while (x > 20) {
+    if (x > 30) {
+      --x;
+      continue;
+    } else if (x < 5)
+      break;
+    else
+      goto done;
+  }
+
+  do {
+    x++;
+  } while (x < 10);
+
+ almost_done:
+  for (int y = x; y < 20; ++y) {
+    if (x + y == 12)
+      return;
+    else if (x - y == 7)
+      goto almost_done;
+  }
+
+ done:
+  x = x + 2;
+
+  int z = x, *y, j = 5;
+}
+
+int f1(int x) {
+  switch (x) {
+  case 17:
+    return 12;
+
+  default:
+    break;
+  }
+
+  // variable-length array
+  int array[x * 17 + 3];
+
+  return x*2;
+}
+
+const char* what_is_my_name(void) { return __func__; }
+
+int computed_goto(int x) {
+ start:
+  x = x << 1;
+  void *location = &&start;
+
+  if (x > 17)
+    location = &&done;
+
+  while (x > 12) {
+    --x;
+    if (x == 15)
+      goto *location;
+  }
+
+  done:
+  return 5;
+}
+
+#define maxint(a,b) ({int _a = (a), _b = (b); _a > _b ? _a : _b; })
+int weird_max(int x, int y) {
+  return maxint(++x, --y);
+}
diff --git a/test/PCH/struct.c b/test/PCH/struct.c
new file mode 100644
index 0000000..3e9d188
--- /dev/null
+++ b/test/PCH/struct.c
@@ -0,0 +1,28 @@
+// Test this without pch.
+// RUN: %clang_cc1 -include %S/struct.h -fsyntax-only -verify %s
+
+// Test with pch.
+// RUN: %clang_cc1 -emit-pch -o %t %S/struct.h
+// RUN: %clang_cc1 -include-pch %t -fsyntax-only -verify %s 
+
+struct Point *p1;
+
+float getX(struct Point *p1) {
+  return p1->x;
+}
+
+void *get_fun_ptr() {
+  return fun->is_ptr? fun->ptr : 0;
+}
+
+struct Fun2 {
+  int very_fun;
+};
+
+int get_very_fun() {
+  return fun2->very_fun;
+}
+
+int *int_ptr_fail = &fun->is_ptr; // expected-error{{address of bit-field requested}}
+
+struct Nested nested = { 1, 2 };
diff --git a/test/PCH/struct.h b/test/PCH/struct.h
new file mode 100644
index 0000000..2ffdd4a
--- /dev/null
+++ b/test/PCH/struct.h
@@ -0,0 +1,29 @@
+// Used with the struct.c test
+
+struct Point {
+  float x, y, z;
+};
+
+struct Point2 {
+  float xValue, yValue, zValue;
+};
+
+struct Fun;
+
+struct Fun *fun;
+
+struct Fun {
+  int is_ptr : 1;
+
+  union {
+    void *ptr;
+    int  *integer;
+  };
+};
+
+struct Fun2;
+struct Fun2 *fun2;
+
+struct S {
+  struct Nested { int x, y; } nest;
+};
diff --git a/test/PCH/tentative-defs.c b/test/PCH/tentative-defs.c
new file mode 100644
index 0000000..0072818
--- /dev/null
+++ b/test/PCH/tentative-defs.c
@@ -0,0 +1,9 @@
+// Test with pch.
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -emit-pch -o %t.pch %S/tentative-defs.h
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -include-pch %t.pch -verify -emit-llvm -o %t %s
+
+// RUN: grep "@variable = common global i32 0" %t | count 1
+// RUN: grep "@incomplete_array = common global .*1 x i32" %t | count 1
+
+
+// FIXME: tentative-defs.h expected-warning{{tentative}}
diff --git a/test/PCH/tentative-defs.h b/test/PCH/tentative-defs.h
new file mode 100644
index 0000000..4675d9a
--- /dev/null
+++ b/test/PCH/tentative-defs.h
@@ -0,0 +1,9 @@
+// Header for PCH test tentative-defs.c
+int variable;
+
+
+
+
+
+
+int incomplete_array[];
diff --git a/test/PCH/types.c b/test/PCH/types.c
new file mode 100644
index 0000000..c21b33a
--- /dev/null
+++ b/test/PCH/types.c
@@ -0,0 +1,72 @@
+// Test this without pch.
+// RUN: %clang_cc1 -fblocks -include %S/types.h -fsyntax-only -verify %s
+
+// Test with pch.
+// RUN: %clang_cc1 -emit-pch -fblocks -o %t %S/types.h
+// RUN: %clang_cc1 -fblocks -include-pch %t -fsyntax-only -verify %s 
+
+typedef int INT;
+INT int_value;
+
+__attribute__((address_space(1))) int int_as_one;
+
+// TYPE_EXT_QUAL
+ASInt *as_int_ptr1 = &int_value;  // expected-error{{different address spaces}} \
+                             // FIXME: expected-warning{{discards qualifiers}}
+ASInt *as_int_ptr2 = &int_as_one;
+
+// FIXME: TYPE_FIXED_WIDTH_INT
+
+// TYPE_COMPLEX
+_Complex float Cfloat_val;
+Cfloat *Cfloat_ptr = &Cfloat_val;
+
+// TYPE_POINTER
+int_ptr int_value_ptr = &int_value;
+
+// TYPE_BLOCK_POINTER
+void test_block_ptr(Block *bl) {
+  *bl = ^(int x, float f) { return x; };
+}
+
+// TYPE_CONSTANT_ARRAY
+five_ints fvi = { 1, 2, 3, 4, 5 };
+
+// TYPE_INCOMPLETE_ARRAY
+float_array fa1 = { 1, 2, 3 };
+float_array fa2 = { 1, 2, 3, 4, 5, 6, 7, 8 };
+
+// TYPE_VARIABLE_ARRAY in stmts.[ch]
+
+// TYPE_VECTOR
+float4 f4 = { 1.0, 2.0, 3.0, 4.0 };
+
+// TYPE_EXT_VECTOR
+ext_float4 ef4 = { 1.0, 2.0, 3.0, 4.0 };
+
+// TYPE_FUNCTION_NO_PROTO
+noproto np1;
+int np1(x, y)
+     int x;
+     float y;
+{
+  return x;
+}
+
+// TYPE_FUNCTION_PROTO
+proto p1;
+float p1(float x, float y, ...) {
+  return x + y;
+}
+proto *p2 = p1;
+
+// TYPE_TYPEDEF
+int_ptr_ptr ipp = &int_value_ptr;
+
+// TYPE_TYPEOF_EXPR
+typeof_17 *t17 = &int_value;
+struct S { int x, y; };
+typeof_17 t17_2 = (struct S){1, 2}; // expected-error{{initializing 'typeof_17' (aka 'int') with an expression of incompatible type 'struct S'}}
+
+// TYPE_TYPEOF
+int_ptr_ptr2 ipp2 = &int_value_ptr;
diff --git a/test/PCH/types.h b/test/PCH/types.h
new file mode 100644
index 0000000..df9f5c8
--- /dev/null
+++ b/test/PCH/types.h
@@ -0,0 +1,44 @@
+/* Used with the types.c test */
+
+// TYPE_EXT_QUAL
+typedef __attribute__((address_space(1))) int ASInt;
+
+// FIXME: TYPE_FIXED_WIDTH_INT
+
+// TYPE_COMPLEX
+typedef _Complex float Cfloat;
+
+// TYPE_POINTER
+typedef int * int_ptr;
+
+// TYPE_BLOCK_POINTER
+typedef int (^Block)(int, float);
+
+// TYPE_CONSTANT_ARRAY
+typedef int five_ints[5];
+
+// TYPE_INCOMPLETE_ARRAY
+typedef float float_array[];
+
+// TYPE_VARIABLE_ARRAY in stmts.[ch]
+
+// TYPE_VECTOR
+typedef float float4 __attribute__((vector_size(16)));
+
+// TYPE_EXT_VECTOR
+typedef float ext_float4 __attribute__((ext_vector_type(4)));
+
+// TYPE_FUNCTION_NO_PROTO
+typedef int noproto();
+
+// TYPE_FUNCTION_PROTO
+typedef float proto(float, float, ...);
+
+// TYPE_TYPEDEF
+typedef int_ptr * int_ptr_ptr;
+
+// TYPE_TYPEOF_EXPR
+typedef typeof(17) typeof_17;
+
+// TYPE_TYPEOF
+typedef typeof(int_ptr *) int_ptr_ptr2;
diff --git a/test/PCH/va_arg.c b/test/PCH/va_arg.c
new file mode 100644
index 0000000..1fb2a83
--- /dev/null
+++ b/test/PCH/va_arg.c
@@ -0,0 +1,12 @@
+// Test this without pch.
+// RUN: %clang_cc1 -triple=x86_64-unknown-freebsd7.0 -include %S/va_arg.h %s -emit-llvm -o -
+
+// Test with pch.
+// RUN: %clang_cc1 -triple=x86_64-unknown-freebsd7.0 -emit-pch -o %t %S/va_arg.h
+// RUN: %clang_cc1 -triple=x86_64-unknown-freebsd7.0 -include-pch %t %s -emit-llvm -o -
+
+char *g0(char** argv, int argc) { return argv[argc]; }
+
+char *g(char **argv) {
+  f(g0, argv, 1, 2, 3);
+}
diff --git a/test/PCH/va_arg.h b/test/PCH/va_arg.h
new file mode 100644
index 0000000..4a8e510
--- /dev/null
+++ b/test/PCH/va_arg.h
@@ -0,0 +1,8 @@
+// Header for PCH test va_arg.c
+
+typedef __builtin_va_list va_list;
+char *f (char * (*g) (char **, int), char **p, ...) {
+    char *s;
+    va_list v;
+    s = g (p, __builtin_va_arg(v, int));
+}
diff --git a/test/PCH/variables.c b/test/PCH/variables.c
new file mode 100644
index 0000000..58fd8ae
--- /dev/null
+++ b/test/PCH/variables.c
@@ -0,0 +1,23 @@
+// Test this without pch.
+// RUN: %clang_cc1 -include %S/variables.h -fsyntax-only -verify %s
+
+// Test with pch.
+// RUN: %clang_cc1 -emit-pch -o %t %S/variables.h
+// RUN: %clang_cc1 -include-pch %t -fsyntax-only -verify %s 
+
+int *ip2 = &x;
+float *fp = &ip; // expected-warning{{incompatible pointer types}}
+// FIXME:variables.h expected-note{{previous}}
+double z; // expected-error{{redefinition}}
+// FIXME:variables.h expected-note{{previous}}
+int z2 = 18; // expected-error{{redefinition}}
+double VeryHappy; // expected-error{{redefinition}}
+// FIXME:variables.h expected-note{{previous definition is here}}
+
+int Q = A_MACRO_IN_THE_PCH;
+
+int R = FUNCLIKE_MACRO(A_MACRO_, IN_THE_PCH);
+
+
+int UNIQUE(a);  // a2
+int *Arr[] = { &a0, &a1, &a2 };
diff --git a/test/PCH/variables.h b/test/PCH/variables.h
new file mode 100644
index 0000000..c937429
--- /dev/null
+++ b/test/PCH/variables.h
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -emit-pch -o variables.h.pch variables.h
+// Do not mess with the whitespace in this file. It's important.
+
+
+
+
+extern float y;
+extern int *ip, x;
+
+float z;
+
+int z2 = 17;
+
+#define MAKE_HAPPY(X) X##Happy
+int MAKE_HAPPY(Very);
+
+#define A_MACRO_IN_THE_PCH 492
+#define FUNCLIKE_MACRO(X, Y) X ## Y
+
+#define PASTE2(x,y) x##y
+#define PASTE1(x,y) PASTE2(x,y)
+#define UNIQUE(x) PASTE1(x,__COUNTER__)
+
+int UNIQUE(a);  // a0
+int UNIQUE(a);  // a1
+
diff --git a/test/Parser/2008-10-31-parse-noop-failure.c b/test/Parser/2008-10-31-parse-noop-failure.c
new file mode 100755
index 0000000..6df508e
--- /dev/null
+++ b/test/Parser/2008-10-31-parse-noop-failure.c
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -verify -parse-noop %s
+
+void add_attribute(id) int id; {}
+
diff --git a/test/Parser/CompoundStmtScope.c b/test/Parser/CompoundStmtScope.c
new file mode 100644
index 0000000..4f99103
--- /dev/null
+++ b/test/Parser/CompoundStmtScope.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+void foo() {
+  {
+    typedef float X;
+  }
+  X Y;  // expected-error {{use of undeclared identifier}}
+}
diff --git a/test/Parser/MicrosoftExtensions.c b/test/Parser/MicrosoftExtensions.c
new file mode 100644
index 0000000..0b2733e
--- /dev/null
+++ b/test/Parser/MicrosoftExtensions.c
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -triple i386-mingw32 -fsyntax-only -verify -fms-extensions -x objective-c++ %s
+__stdcall int func0();
+int __stdcall func();
+typedef int (__cdecl *tptr)();
+void (*__fastcall fastpfunc)();
+extern __declspec(dllimport) void __stdcall VarR4FromDec();
+__declspec(deprecated) __declspec(deprecated) char * __cdecl ltoa( long _Val, char * _DstBuf, int _Radix);
+__declspec(noalias) __declspec(restrict) void * __cdecl xxx( void * _Memory );
+typedef __w64 unsigned long ULONG_PTR, *PULONG_PTR;
+void * __ptr64 PtrToPtr64(const void *p)
+{
+  return((void * __ptr64) (unsigned __int64) (ULONG_PTR)p );
+}
+void __forceinline InterlockedBitTestAndSet (long *Base, long Bit)
+{
+  __asm {
+    mov eax, Bit
+    mov ecx, Base
+    lock bts [ecx], eax
+    setc al
+  };
+}
+
+void *_alloca(int);
+
+void foo() {
+  __declspec(align(16)) int *buffer = (int *)_alloca(9);
+}
+
+typedef bool (__stdcall __stdcall *blarg)(int);
+
+
+// Charify extension.
+#define FOO(x) #@x
+char x = FOO(a);
+
diff --git a/test/Parser/altivec.c b/test/Parser/altivec.c
new file mode 100644
index 0000000..ed14457
--- /dev/null
+++ b/test/Parser/altivec.c
@@ -0,0 +1,93 @@
+// RUN: %clang_cc1 -triple=powerpc-apple-darwin8 -faltivec -fsyntax-only -verify %s
+
+__vector char vv_c;
+__vector signed char vv_sc;
+__vector unsigned char vv_uc;
+__vector short vv_s;
+__vector signed  short vv_ss;
+__vector unsigned  short vv_us;
+__vector short int vv_si;
+__vector signed short int vv_ssi;
+__vector unsigned short int vv_usi;
+__vector int vv_i;
+__vector signed int vv_sint;
+__vector unsigned int vv_ui;
+__vector float vv_f;
+__vector bool vv_b;
+__vector __pixel vv_p;
+__vector pixel vv__p;
+__vector int vf__r();
+void vf__a(__vector int a);
+void vf__a2(int b, __vector int a);
+
+vector char v_c;
+vector signed char v_sc;
+vector unsigned char v_uc;
+vector short v_s;
+vector signed  short v_ss;
+vector unsigned  short v_us;
+vector short int v_si;
+vector signed short int v_ssi;
+vector unsigned short int v_usi;
+vector int v_i;
+vector signed int v_sint;
+vector unsigned int v_ui;
+vector float v_f;
+vector bool v_b;
+vector __pixel v_p;
+vector pixel v__p;
+vector int f__r();
+void f_a(vector int a);
+void f_a2(int b, vector int a);
+
+vector int v = (vector int)(-1);
+
+// These should have warnings.
+__vector long vv_l;                 // expected-warning {{Use of 'long' with '__vector' is deprecated}}
+__vector signed long vv_sl;         // expected-warning {{Use of 'long' with '__vector' is deprecated}}
+__vector unsigned long vv_ul;       // expected-warning {{Use of 'long' with '__vector' is deprecated}}
+__vector long int vv_li;            // expected-warning {{Use of 'long' with '__vector' is deprecated}}
+__vector signed long int vv_sli;    // expected-warning {{Use of 'long' with '__vector' is deprecated}}
+__vector unsigned long int vv_uli;  // expected-warning {{Use of 'long' with '__vector' is deprecated}}
+vector long v_l;                    // expected-warning {{Use of 'long' with '__vector' is deprecated}}
+vector signed long v_sl;            // expected-warning {{Use of 'long' with '__vector' is deprecated}}
+vector unsigned long v_ul;          // expected-warning {{Use of 'long' with '__vector' is deprecated}}
+vector long int v_li;               // expected-warning {{Use of 'long' with '__vector' is deprecated}}
+vector signed long int v_sli;       // expected-warning {{Use of 'long' with '__vector' is deprecated}}
+vector unsigned long int v_uli;     // expected-warning {{Use of 'long' with '__vector' is deprecated}}
+__vector long double  vv_ld;        // expected-warning {{Use of 'long' with '__vector' is deprecated}} expected-error {{cannot use 'double' with '__vector'}}
+vector long double  v_ld;           // expected-warning {{Use of 'long' with '__vector' is deprecated}} expected-error {{cannot use 'double' with '__vector'}}
+
+// These should have errors.
+__vector double vv_d;               // expected-error {{cannot use 'double' with '__vector'}}
+__vector double vv_d;               // expected-error {{cannot use 'double' with '__vector'}}
+vector double v_d;                  // expected-error {{cannot use 'double' with '__vector'}}
+vector double v_d;                  // expected-error {{cannot use 'double' with '__vector'}}
+__vector long double  vv_ld;        // expected-warning {{Use of 'long' with '__vector' is deprecated}} expected-error {{cannot use 'double' with '__vector'}}
+vector long double  v_ld;           // expected-warning {{Use of 'long' with '__vector' is deprecated}} expected-error {{cannot use 'double' with '__vector'}}
+
+void f() {
+  __vector unsigned int v = {0,0,0,0};
+  __vector int v__cast = (__vector int)v;
+  __vector int v_cast = (vector int)v;
+  __vector char vb_cast = (vector char)v;
+
+  // Check some casting between gcc and altivec vectors.
+  #define gccvector __attribute__((vector_size(16)))
+  gccvector unsigned int gccv = {0,0,0,0};
+  gccvector unsigned int gccv1 = gccv;
+  gccvector int gccv2 = (gccvector int)gccv;
+  gccvector unsigned int gccv3 = v;
+  __vector unsigned int av = gccv;
+  __vector int avi = (__vector int)gccv;
+  gccvector unsigned int gv = v;
+  gccvector int gvi = (gccvector int)v;
+  __attribute__((vector_size(8))) unsigned int gv8;
+  gv8 = gccv;     // expected-error {{assigning to '__attribute__((__vector_size__(2 * sizeof(unsigned int)))) unsigned int' from incompatible type '__attribute__((__vector_size__(4 * sizeof(unsigned int)))) unsigned int'}}
+  av = gv8;       // expected-error {{assigning to '__vector unsigned int' from incompatible type '__attribute__((__vector_size__(2 * sizeof(unsigned int)))) unsigned int'}}
+
+  v = gccv;
+  __vector unsigned int tv = gccv;
+  gccv = v;
+  gccvector unsigned int tgv = v;
+}
diff --git a/test/Parser/argument_qualified.c b/test/Parser/argument_qualified.c
new file mode 100644
index 0000000..7d1b9fd
--- /dev/null
+++ b/test/Parser/argument_qualified.c
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 %s
+int abc (const float x) {
+  return 1;
+}
+
diff --git a/test/Parser/argument_redef.c b/test/Parser/argument_redef.c
new file mode 100644
index 0000000..519e8fd
--- /dev/null
+++ b/test/Parser/argument_redef.c
@@ -0,0 +1,6 @@
+/* RUN: %clang_cc1 -fsyntax-only -verify %s
+*/
+
+void foo(int A) { /* expected-note {{previous definition is here}} */
+  int A; /* expected-error {{redefinition of 'A'}} */
+}
diff --git a/test/Parser/argument_scope.c b/test/Parser/argument_scope.c
new file mode 100644
index 0000000..d2d10c2
--- /dev/null
+++ b/test/Parser/argument_scope.c
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -fsyntax-only %s
+typedef struct foo foo;
+
+void blah(int foo) {
+  foo = 1;
+}
diff --git a/test/Parser/asm.c b/test/Parser/asm.c
new file mode 100644
index 0000000..df2e16f
--- /dev/null
+++ b/test/Parser/asm.c
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+void f1() {
+  asm ("ret" : : :); // expected-error {{expected string literal}}
+}
+
+void f2() {
+  asm("foo" : "=r" (a)); // expected-error {{use of undeclared identifier 'a'}}
+  asm("foo" : : "r" (b)); // expected-error {{use of undeclared identifier 'b'}} 
+}
+
+
+// rdar://5952468
+__asm ; // expected-error {{expected '(' after 'asm'}}
+
diff --git a/test/Parser/attributes.c b/test/Parser/attributes.c
new file mode 100644
index 0000000..b287363
--- /dev/null
+++ b/test/Parser/attributes.c
@@ -0,0 +1,58 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -pedantic -std=c99
+
+int __attribute__(()) x;
+
+__inline void __attribute__((__always_inline__, __nodebug__))
+foo(void) {
+}
+
+
+__attribute__(()) y;   // expected-warning {{defaults to 'int'}}
+
+// PR2796
+int (__attribute__(()) *z)(long y);
+
+
+void f1(__attribute__(()) int x);
+
+int f2(y, __attribute__(()) x);     // expected-error {{expected identifier}}
+
+// This is parsed as a normal argument list (with two args that are implicit
+// int) because the __attribute__ is a declspec.
+void f3(__attribute__(()) x,  // expected-warning {{defaults to 'int'}}
+        y);               // expected-warning {{defaults to 'int'}}
+
+void f4(__attribute__(()));   // expected-error {{expected parameter declarator}}
+
+
+// This is ok, the __attribute__ applies to the pointer.
+int baz(int (__attribute__(()) *x)(long y));
+
+void g1(void (*f1)(__attribute__(()) int x));
+void g2(int (*f2)(y, __attribute__(()) x));    // expected-error {{expected identifier}}
+void g3(void (*f3)(__attribute__(()) x, int y));  // expected-warning {{defaults to 'int'}}
+void g4(void (*f4)(__attribute__(())));  // expected-error {{expected parameter declarator}}
+
+
+void (*h1)(void (*f1)(__attribute__(()) int x));
+void (*h2)(int (*f2)(y, __attribute__(()) x));    // expected-error {{expected identifier}}
+
+void (*h3)(void (*f3)(__attribute__(()) x));   // expected-warning {{defaults to 'int'}}
+void (*h4)(void (*f4)(__attribute__(())));  // expected-error {{expected parameter declarator}}
+
+
+
+// rdar://6131260
+int foo42(void) {
+  int x, __attribute__((unused)) y, z;
+  return 0;
+}
+
+// rdar://6096491
+void __attribute__((noreturn)) d0(void), __attribute__((noreturn)) d1(void);
+
+void d2(void) __attribute__((noreturn)), d3(void) __attribute__((noreturn));
+
+
+// PR6287
+void __attribute__((returns_twice)) returns_twice_test();
diff --git a/test/Parser/bad-control.c b/test/Parser/bad-control.c
new file mode 100644
index 0000000..480d81b
--- /dev/null
+++ b/test/Parser/bad-control.c
@@ -0,0 +1,9 @@
+/* RUN: %clang_cc1 -fsyntax-only -verify %s
+*/
+void foo() { 
+  break; /* expected-error {{'break' statement not in loop or switch statement}} */
+}
+
+void foo2() { 
+  continue; /* expected-error {{'continue' statement not in loop statement}} */
+}
diff --git a/test/Parser/block-block-storageclass.c b/test/Parser/block-block-storageclass.c
new file mode 100644
index 0000000..a4efc44
--- /dev/null
+++ b/test/Parser/block-block-storageclass.c
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -parse-noop %s
+#if 0
+int printf(const char *, ...);
+void _Block_byref_release(void*src){}
+
+int main() {
+   __block  int X = 1234;
+   __block  const char * message = "HELLO";
+
+   X = X - 1234;
+
+   X += 1;
+
+   printf ("%s(%d)\n", message, X);
+   X -= 1;
+
+   return X;
+}
+#endif
diff --git a/test/Parser/block-pointer-decl.c b/test/Parser/block-pointer-decl.c
new file mode 100644
index 0000000..2979b01
--- /dev/null
+++ b/test/Parser/block-pointer-decl.c
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -parse-noop -fblocks %s
+
+struct blockStruct {
+  int (^a)(float, int);
+  int b;
+};
+
+int blockTaker (int (^myBlock)(int), int other_input)
+{
+  return 5 * myBlock (other_input);
+}
+
+int main (int argc, char **argv)
+{
+  int (^blockptr) (int) = ^(int inval) {
+    printf ("Inputs: %d, %d.\n", argc, inval);
+    return argc * inval;
+  };
+
+
+  argc = 10;
+  printf ("I got: %d.\n",
+          blockTaker (blockptr, 6));
+  return 0;
+}
+
diff --git a/test/Parser/builtin_classify_type.c b/test/Parser/builtin_classify_type.c
new file mode 100644
index 0000000..a7c0855
--- /dev/null
+++ b/test/Parser/builtin_classify_type.c
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct foo { int a; };
+
+int main() {
+  int a;
+  float b;
+  double d;
+  struct foo s;
+
+  static int ary[__builtin_classify_type(a)];
+  static int ary2[(__builtin_classify_type)(a)]; // expected-error{{variable length array declaration can not have 'static' storage duration}}
+  static int ary3[(*__builtin_classify_type)(a)]; // expected-error{{variable length array declaration can not have 'static' storage duration}}
+
+  int result;
+
+  result =  __builtin_classify_type(a);
+  result =  __builtin_classify_type(b);
+  result =  __builtin_classify_type(d);
+  result =  __builtin_classify_type(s);
+}
diff --git a/test/Parser/builtin_types_compatible.c b/test/Parser/builtin_types_compatible.c
new file mode 100644
index 0000000..ac81e7b
--- /dev/null
+++ b/test/Parser/builtin_types_compatible.c
@@ -0,0 +1,43 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+extern int funcInt(int);
+extern float funcFloat(float);
+extern double funcDouble(double);
+// figure out why "char *" doesn't work (with gcc, nothing to do with clang)
+//extern void funcCharPtr(char *);
+
+#define func(expr) \
+  do { \
+    typeof(expr) tmp; \
+    if (__builtin_types_compatible_p(typeof(expr), int)) funcInt(tmp); \
+    else if (__builtin_types_compatible_p(typeof(expr), float)) funcFloat(tmp); \
+    else if (__builtin_types_compatible_p(typeof(expr), double)) funcDouble(tmp); \
+  } while (0)
+#define func_choose(expr) \
+  __builtin_choose_expr(__builtin_types_compatible_p(typeof(expr), int), funcInt(expr), \
+    __builtin_choose_expr(__builtin_types_compatible_p(typeof(expr), float), funcFloat(expr), \
+      __builtin_choose_expr(__builtin_types_compatible_p(typeof(expr), double), funcDouble(expr), (void)0)))
+
+static void test()
+{
+  int a;
+  float b;
+  double d;
+
+  func(a);
+  func(b);
+  func(d);
+  a = func_choose(a);
+  b = func_choose(b);
+  d = func_choose(d);
+
+  int c; 
+  struct xx { int a; } x, y;
+  
+  c = __builtin_choose_expr(a+3-7, b, x); // expected-error{{'__builtin_choose_expr' requires a constant expression}}
+  c = __builtin_choose_expr(0, b, x); // expected-error{{assigning to 'int' from incompatible type 'struct xx'}}
+  c = __builtin_choose_expr(5+3-7, b, x);
+  y = __builtin_choose_expr(4+3-7, b, x);
+
+}
+
diff --git a/test/Parser/c-namespace.c b/test/Parser/c-namespace.c
new file mode 100644
index 0000000..fbef09e
--- /dev/null
+++ b/test/Parser/c-namespace.c
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -fsyntax-only %s 
+void bla1() {
+  struct XXX;
+  int XXX;
+}
+
diff --git a/test/Parser/char-literal-printing.c b/test/Parser/char-literal-printing.c
new file mode 100644
index 0000000..5843e5f
--- /dev/null
+++ b/test/Parser/char-literal-printing.c
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -ast-print %s
+
+#include <stddef.h>
+
+char    test1(void) { return '\\'; }
+wchar_t test2(void) { return L'\\'; }
+char    test3(void) { return '\''; }
+wchar_t test4(void) { return L'\''; }
+char    test5(void) { return '\a'; }
+wchar_t test6(void) { return L'\a'; }
+char    test7(void) { return '\b'; }
+wchar_t test8(void) { return L'\b'; }
+char    test9(void) { return '\e'; }
+wchar_t test10(void) { return L'\e'; }
+char    test11(void) { return '\f'; }
+wchar_t test12(void) { return L'\f'; }
+char    test13(void) { return '\n'; }
+wchar_t test14(void) { return L'\n'; }
+char    test15(void) { return '\r'; }
+wchar_t test16(void) { return L'\r'; }
+char    test17(void) { return '\t'; }
+wchar_t test18(void) { return L'\t'; }
+char    test19(void) { return '\v'; }
+wchar_t test20(void) { return L'\v'; }
+
+char    test21(void) { return 'c'; }
+wchar_t test22(void) { return L'c'; }
+char    test23(void) { return '\x3'; }
+wchar_t test24(void) { return L'\x3'; }
+
+wchar_t test25(void) { return L'\x333'; }
diff --git a/test/Parser/check-objc2-syntax-1.m b/test/Parser/check-objc2-syntax-1.m
new file mode 100644
index 0000000..3cdf2b0
--- /dev/null
+++ b/test/Parser/check-objc2-syntax-1.m
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@interface Subclass 
++ (int)magicNumber;
+@end
+
+int main (void) {
+  return Subclass.magicNumber;
+}
+
diff --git a/test/Parser/check-syntax-1.m b/test/Parser/check-syntax-1.m
new file mode 100644
index 0000000..db37793
--- /dev/null
+++ b/test/Parser/check-syntax-1.m
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+int @interface bla  ; // expected-error {{cannot combine with previous 'int' declaration specifier}}
+@end
+
+typedef float CGFloat;
+@interface XNSNumber 
++ (XNSNumber *) numberWithCGFloat  : (CGFloat) float; // expected-error {{expected identifier}}  \
+                                                      // expected-error {{ expected ';' after method prototype}}
+@end
+
+// rdar: // 7822196
+@interface A
+(void) x;	// expected-error {{method type specifier must start with '-' or '+'}} 
+(int)im; // expected-error {{method type specifier must start with '-' or '+'}} \
+- ok;
+@end
+
+
diff --git a/test/Parser/check_cast.c b/test/Parser/check_cast.c
new file mode 100644
index 0000000..790ee40
--- /dev/null
+++ b/test/Parser/check_cast.c
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+struct foo {
+  int a;
+};
+
+int main() {
+  struct foo xxx;
+  int i;
+
+  xxx = (struct foo)1;  // expected-error {{used type 'struct foo' where arithmetic or pointer type is required}}
+  i = (int)xxx; // expected-error {{operand of type 'struct foo' where arithmetic or pointer type is required}}
+}
diff --git a/test/Parser/compound_literal.c b/test/Parser/compound_literal.c
new file mode 100644
index 0000000..4f3609d
--- /dev/null
+++ b/test/Parser/compound_literal.c
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+int main() {
+  char *s;
+  s = (char []){"whatever"}; 
+}
diff --git a/test/Parser/control-scope.c b/test/Parser/control-scope.c
new file mode 100644
index 0000000..5314980
--- /dev/null
+++ b/test/Parser/control-scope.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 %s -std=c90 -verify
+// RUN: %clang_cc1 %s -std=c99
+
+int f (int z) { 
+  if (z + sizeof (enum {a}))        // expected-note {{previous definition is here}}
+    return 1 + sizeof (enum {a});   // expected-error {{redefinition of enumerator 'a'}}
+  return 0; 
+}
diff --git a/test/Parser/cxx-altivec.cpp b/test/Parser/cxx-altivec.cpp
new file mode 100644
index 0000000..66d4f32
--- /dev/null
+++ b/test/Parser/cxx-altivec.cpp
@@ -0,0 +1,109 @@
+// RUN: %clang_cc1 -triple=powerpc-apple-darwin8 -faltivec -fsyntax-only -verify %s
+// This is the same as the C version:
+
+__vector char vv_c;
+__vector signed char vv_sc;
+__vector unsigned char vv_uc;
+__vector short vv_s;
+__vector signed  short vv_ss;
+__vector unsigned  short vv_us;
+__vector short int vv_si;
+__vector signed short int vv_ssi;
+__vector unsigned short int vv_usi;
+__vector int vv_i;
+__vector signed int vv_sint;
+__vector unsigned int vv_ui;
+__vector float vv_f;
+__vector bool vv_b;
+__vector __pixel vv_p;
+__vector pixel vv__p;
+__vector int vf__r();
+void vf__a(__vector int a);
+void vf__a2(int b, __vector int a);
+
+vector char v_c;
+vector signed char v_sc;
+vector unsigned char v_uc;
+vector short v_s;
+vector signed  short v_ss;
+vector unsigned  short v_us;
+vector short int v_si;
+vector signed short int v_ssi;
+vector unsigned short int v_usi;
+vector int v_i;
+vector signed int v_sint;
+vector unsigned int v_ui;
+vector float v_f;
+vector bool v_b;
+vector __pixel v_p;
+vector pixel v__p;
+vector int f__r();
+void f_a(vector int a);
+void f_a2(int b, vector int a);
+
+vector int v = (vector int)(-1);
+
+// These should have warnings.
+__vector long vv_l;                 // expected-warning {{Use of 'long' with '__vector' is deprecated}}
+__vector signed long vv_sl;         // expected-warning {{Use of 'long' with '__vector' is deprecated}}
+__vector unsigned long vv_ul;       // expected-warning {{Use of 'long' with '__vector' is deprecated}}
+__vector long int vv_li;            // expected-warning {{Use of 'long' with '__vector' is deprecated}}
+__vector signed long int vv_sli;    // expected-warning {{Use of 'long' with '__vector' is deprecated}}
+__vector unsigned long int vv_uli;  // expected-warning {{Use of 'long' with '__vector' is deprecated}}
+vector long v_l;                    // expected-warning {{Use of 'long' with '__vector' is deprecated}}
+vector signed long v_sl;            // expected-warning {{Use of 'long' with '__vector' is deprecated}}
+vector unsigned long v_ul;          // expected-warning {{Use of 'long' with '__vector' is deprecated}}
+vector long int v_li;               // expected-warning {{Use of 'long' with '__vector' is deprecated}}
+vector signed long int v_sli;       // expected-warning {{Use of 'long' with '__vector' is deprecated}}
+vector unsigned long int v_uli;     // expected-warning {{Use of 'long' with '__vector' is deprecated}}
+__vector long double  vv_ld;        // expected-warning {{Use of 'long' with '__vector' is deprecated}} expected-error {{cannot use 'double' with '__vector'}}
+vector long double  v_ld;           // expected-warning {{Use of 'long' with '__vector' is deprecated}} expected-error {{cannot use 'double' with '__vector'}}
+
+// These should have errors.
+__vector double vv_d1;               // expected-error {{cannot use 'double' with '__vector'}}
+vector double v_d2;                  // expected-error {{cannot use 'double' with '__vector'}}
+__vector long double  vv_ld3;        // expected-warning {{Use of 'long' with '__vector' is deprecated}} expected-error {{cannot use 'double' with '__vector'}}
+vector long double  v_ld4;           // expected-warning {{Use of 'long' with '__vector' is deprecated}} expected-error {{cannot use 'double' with '__vector'}}
+
+void f() {
+  __vector unsigned int v = {0,0,0,0};
+  __vector int v__cast = (__vector int)v;
+  __vector int v_cast = (vector int)v;
+  __vector char vb_cast = (vector char)v;
+
+  // Check some casting between gcc and altivec vectors.
+  #define gccvector __attribute__((vector_size(16)))
+  gccvector unsigned int gccv = {0,0,0,0};
+  gccvector unsigned int gccv1 = gccv;
+  gccvector int gccv2 = (gccvector int)gccv;
+  gccvector unsigned int gccv3 = v;
+  __vector unsigned int av = gccv;
+  __vector int avi = (__vector int)gccv;
+  gccvector unsigned int gv = v;
+  gccvector int gvi = (gccvector int)v;
+  __attribute__((vector_size(8))) unsigned int gv8;
+  gv8 = gccv;     // expected-error {{assigning to '__attribute__((__vector_size__(2 * sizeof(unsigned int)))) unsigned int' from incompatible type '__attribute__((__vector_size__(4 * sizeof(unsigned int)))) unsigned int'}}
+  av = gv8;       // expected-error {{assigning to '__vector unsigned int' from incompatible type '__attribute__((__vector_size__(2 * sizeof(unsigned int)))) unsigned int'}}
+
+  v = gccv;
+  __vector unsigned int tv = gccv;
+  gccv = v;
+  gccvector unsigned int tgv = v;
+}
+
+// Now for the C++ version:
+
+class vc__v {
+  __vector int v;
+  __vector int f__r();
+  void f__a(__vector int a);
+  void f__a2(int b, __vector int a);
+};
+
+class c_v {
+  vector int v;
+  vector int f__r();
+  void f__a(vector int a);
+  void f__a2(int b, vector int a);
+};
+
diff --git a/test/Parser/cxx-ambig-paren-expr.cpp b/test/Parser/cxx-ambig-paren-expr.cpp
new file mode 100644
index 0000000..3988205
--- /dev/null
+++ b/test/Parser/cxx-ambig-paren-expr.cpp
@@ -0,0 +1,66 @@
+// RUN: %clang_cc1 -fsyntax-only -pedantic -verify %s
+
+void f() {
+  typedef int T;
+  int x, *px;
+  
+  // Type id.
+  (T())x;    // expected-error {{cast from 'int' to 'T ()'}}
+  (T())+x;   // expected-error {{cast from 'int' to 'T ()'}}
+  (T())*px;  // expected-error {{cast from 'int' to 'T ()'}}
+  
+  // Expression.
+  x = (T());
+  x = (T())/x;
+
+  typedef int *PT;
+  // Make sure stuff inside the parens are parsed only once (only one warning).
+  x = (PT()[(int){1}]); // expected-warning {{compound literals}}
+
+  // Special case: empty parens is a call, not an expression
+  struct S{int operator()();};
+  (S())();
+
+  // FIXME: Special case: "++" is postfix here, not prefix
+  // (S())++;
+}
+
+// Make sure we do tentative parsing correctly in conditions.
+typedef int type;
+struct rec { rec(int); };
+
+namespace ns {
+  typedef int type;
+  struct rec { rec(int); };
+}
+
+struct cls {
+  typedef int type;
+  struct rec { rec(int); };
+};
+
+struct result {
+  template <class T> result(T);
+  bool check();
+};
+
+void test(int i) {
+  if (result((cls::type) i).check())
+    return;
+
+  if (result((ns::type) i).check())
+    return;
+
+  if (result((::type) i).check())
+    return;
+
+  if (result((cls::rec) i).check())
+    return;
+
+  if (result((ns::rec) i).check())
+    return;
+
+  if (result((::rec) i).check())
+    return;
+}
+
diff --git a/test/Parser/cxx-attributes.cpp b/test/Parser/cxx-attributes.cpp
new file mode 100644
index 0000000..192193a
--- /dev/null
+++ b/test/Parser/cxx-attributes.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s

+

+class c {

+  virtual void f1(const char* a, ...)

+    __attribute__ (( __format__(__printf__,2,3) )) = 0;

+  virtual void f2(const char* a, ...)

+    __attribute__ (( __format__(__printf__,2,3) )) {}

+};

+

diff --git a/test/Parser/cxx-bool.cpp b/test/Parser/cxx-bool.cpp
new file mode 100644
index 0000000..a8a161e
--- /dev/null
+++ b/test/Parser/cxx-bool.cpp
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -fsyntax-only %s
+
+bool a = true;
+bool b = false;
diff --git a/test/Parser/cxx-casting.cpp b/test/Parser/cxx-casting.cpp
new file mode 100644
index 0000000..c8b4716
--- /dev/null
+++ b/test/Parser/cxx-casting.cpp
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -fsyntax-only %s
+
+char *const_cast_test(const char *var)
+{
+  return const_cast<char*>(var);
+}
+
+#if 0
+// FIXME: Uncomment when C++ is supported more.
+struct A {
+  virtual ~A() {}
+};
+
+struct B : public A {
+};
+
+struct B *dynamic_cast_test(struct A *a)
+{
+  return dynamic_cast<struct B*>(a);
+}
+#endif
+
+char *reinterpret_cast_test()
+{
+  return reinterpret_cast<char*>(0xdeadbeef);
+}
+
+double static_cast_test(int i)
+{
+  return static_cast<double>(i);
+}
+
+char postfix_expr_test()
+{
+  return reinterpret_cast<char*>(0xdeadbeef)[0];
+}
diff --git a/test/Parser/cxx-class.cpp b/test/Parser/cxx-class.cpp
new file mode 100644
index 0000000..4abbbc5
--- /dev/null
+++ b/test/Parser/cxx-class.cpp
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+class C;
+class C {
+public:
+protected:
+  typedef int A,B;
+  static int sf(), u;
+
+  struct S {};
+  enum {};
+  int; // expected-warning {{declaration does not declare anything}}
+  int : 1, : 2;
+
+public:
+  void m() {
+    int l = 2;
+  }
+  virtual int vf() const volatile = 0;
+  
+private:
+  int x,f(),y,g();
+  inline int h();
+  static const int sci = 10;
+  mutable int mi;
+};
+void glo()
+{
+  struct local {};
+}
+
+// PR3177
+typedef union {
+  __extension__ union {
+    int a;
+    float b;
+  } y;
+} bug3177;
+
diff --git a/test/Parser/cxx-condition.cpp b/test/Parser/cxx-condition.cpp
new file mode 100644
index 0000000..a3991c4
--- /dev/null
+++ b/test/Parser/cxx-condition.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -parse-noop -verify %s
+
+void f() {
+  int a;
+  while (a) ;
+  while (int x) ; // expected-error {{expected '=' after declarator}}
+  while (float x = 0) ;
+  if (const int x = a) ;
+  switch (int x = a+10) {}
+  for (; int x = ++a; ) ;
+}
diff --git a/test/Parser/cxx-decl.cpp b/test/Parser/cxx-decl.cpp
new file mode 100644
index 0000000..ae004ce
--- /dev/null
+++ b/test/Parser/cxx-decl.cpp
@@ -0,0 +1,74 @@
+// RUN: %clang_cc1 -verify -fsyntax-only %s
+
+int x(*g); // expected-error {{use of undeclared identifier 'g'}}
+
+struct Type {
+  int Type;
+};
+
+
+// PR4451 - We should recover well from the typo of '::' as ':' in a2.
+namespace y {
+  struct a { };
+  typedef int b;
+}
+
+y::a a1;
+y:a a2;  // expected-error {{unexpected ':' in nested name specifier}}
+y::a a3 = a2;
+
+// Some valid colons:
+void foo() {
+y:  // label
+  y::a s;
+  
+  int a = 4;
+  a = a ? a : a+1;
+}
+
+struct b : y::a {};
+
+template <typename T>
+class someclass {
+  
+  int bar() {
+    T *P;
+    return 1 ? P->x : P->y;
+  }
+};
+
+enum { fooenum = 1 };
+
+struct a {
+  int Type : fooenum;
+};
+
+void test(struct Type *P) {
+  int Type;
+  Type = 1 ? P->Type : Type;
+  
+  Type = (y:b) 4;   // expected-error {{unexpected ':' in nested name specifier}}
+  Type = 1 ? (
+              (y:b)  // expected-error {{unexpected ':' in nested name specifier}}
+              4) : 5;
+}
+
+struct test4 {
+  int x  // expected-error {{expected ';' at end of declaration list}}
+  int y;
+  int z  // expected-error {{expected ';' at end of declaration list}}
+};
+
+// PR5825
+struct test5 {};
+::new(static_cast<void*>(0)) test5; // expected-error {{expected unqualified-id}}
+
+
+// PR6782
+template<class T>
+class Class1;
+
+class Class2 {
+}  // no ;
+
+typedef Class1<Class2> Type1; // expected-error {{cannot combine with previous 'class' declaration specifier}}
diff --git a/test/Parser/cxx-default-args.cpp b/test/Parser/cxx-default-args.cpp
new file mode 100644
index 0000000..a084fb0
--- /dev/null
+++ b/test/Parser/cxx-default-args.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// PR6647
+class C {
+  // After the error, the rest of the tokens inside the default arg should be
+  // skipped, avoiding a "expected ';' after class" after 'undecl'.
+  void m(int x = undecl + 0); // expected-error {{use of undeclared identifier 'undecl'}}
+};
+
diff --git a/test/Parser/cxx-exception-spec.cpp b/test/Parser/cxx-exception-spec.cpp
new file mode 100644
index 0000000..e6c3c75
--- /dev/null
+++ b/test/Parser/cxx-exception-spec.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -fsyntax-only  %s
+
+struct X { };
+
+struct Y { };
+
+void f() throw() { }
+
+void g(int) throw(X) { }
+
+void h() throw(X, Y) { }
+
+class Class {
+  void foo() throw (X, Y) { }
+};
+
+void (*fptr)() throw();
diff --git a/test/Parser/cxx-extern-c-array.cpp b/test/Parser/cxx-extern-c-array.cpp
new file mode 100644
index 0000000..14912fd
--- /dev/null
+++ b/test/Parser/cxx-extern-c-array.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+extern "C" int myarray[];
+int myarray[12] = {0};
+
+extern "C" int anotherarray[][3];
+int anotherarray[2][3] = {1,2,3,4,5,6};
diff --git a/test/Parser/cxx-friend.cpp b/test/Parser/cxx-friend.cpp
new file mode 100644
index 0000000..59350b5
--- /dev/null
+++ b/test/Parser/cxx-friend.cpp
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+class C {
+  friend class D;
+};
+
+class A {
+public:
+  void f();
+};
+
+friend int x; // expected-error {{'friend' used outside of class}}
+
+friend class D {}; // expected-error {{'friend' used outside of class}}
+
+union U {
+  int u1;
+};
+
+class B {
+  // 'A' here should refer to the declaration above.  
+  friend class A;
+
+  friend C; // expected-warning {{must specify 'class' to befriend}}
+  friend U; // expected-warning {{must specify 'union' to befriend}}
+  friend int; // expected-warning {{non-class type 'int' cannot be a friend}}
+
+  friend void myfunc();
+
+  void f(A *a) { a->f(); }
+};
+
+
+
+
+
+template <typename t1, typename t2> class some_template;
+friend   // expected-error {{'friend' used outside of class}}
+some_template<foo, bar>&  // expected-error {{use of undeclared identifier 'foo'}}
+  ;  // expected-error {{expected unqualified-id}}
diff --git a/test/Parser/cxx-member-initializers.cpp b/test/Parser/cxx-member-initializers.cpp
new file mode 100644
index 0000000..34a725f
--- /dev/null
+++ b/test/Parser/cxx-member-initializers.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct x {
+  x() : a(4) ; // expected-error {{expected '{'}}
+};
+
+struct y {
+  int a;
+  y() : a(4) ; // expected-error {{expected '{'}}
+};
diff --git a/test/Parser/cxx-namespace-alias.cpp b/test/Parser/cxx-namespace-alias.cpp
new file mode 100644
index 0000000..2e4d7af
--- /dev/null
+++ b/test/Parser/cxx-namespace-alias.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -parse-noop -verify %s
+
+namespace A = B;
+
+namespace A = !; // expected-error {{expected namespace name}}
+namespace A = A::!; // expected-error {{expected namespace name}}
+
+
diff --git a/test/Parser/cxx-reference.cpp b/test/Parser/cxx-reference.cpp
new file mode 100644
index 0000000..46f9fb0
--- /dev/null
+++ b/test/Parser/cxx-reference.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+extern char *bork;
+char *& bar = bork;
+
+int val;
+
+void foo(int &a) {
+}
+
+typedef int & A;
+
+void g(const A aref) {
+}
+
+int & const X = val; // expected-error {{'const' qualifier may not be applied to a reference}}
+int & volatile Y = val; // expected-error {{'volatile' qualifier may not be applied to a reference}}
+int & const volatile Z = val; /* expected-error {{'const' qualifier may not be applied}} \
+                           expected-error {{'volatile' qualifier may not be applied}} */
+
+typedef int && RV; // expected-error {{rvalue references are only allowed in C++0x}}
diff --git a/test/Parser/cxx-stmt.cpp b/test/Parser/cxx-stmt.cpp
new file mode 100644
index 0000000..fdd573e
--- /dev/null
+++ b/test/Parser/cxx-stmt.cpp
@@ -0,0 +1,60 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+void f1()
+{
+  try {
+    ;
+  } catch(int i) {
+    ;
+  } catch(...) {
+  }
+}
+
+void f2()
+{
+  try; // expected-error {{expected '{'}}
+
+  try {}
+  catch; // expected-error {{expected '('}}
+
+  try {}
+  catch (...); // expected-error {{expected '{'}}
+
+  try {}
+  catch {} // expected-error {{expected '('}}
+}
+
+void f3() try {
+} catch(...) {
+}
+
+struct A {
+  int i;
+  A(int);
+  A(char);
+  A() try : i(0) {} catch(...) {}
+  void f() try {} catch(...) {}
+  A(float) : i(0) try {} // expected-error {{expected '{' or ','}}
+};
+
+A::A(char) : i(0) try {} // expected-error {{expected '{' or ','}}
+A::A(int j) try : i(j) {} catch(...) {}
+
+
+
+// PR5740
+struct Type { };
+
+enum { Type } Kind;
+void f4() {
+  int i = 0;
+  switch (Kind) {
+    case Type: i = 7; break;  // no error.
+  }
+}
+
+// PR5500
+void f5() {
+  asm volatile ("":: :"memory");
+  asm volatile ("": ::"memory");
+}
diff --git a/test/Parser/cxx-template-argument.cpp b/test/Parser/cxx-template-argument.cpp
new file mode 100644
index 0000000..532b4c9
--- /dev/null
+++ b/test/Parser/cxx-template-argument.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T> struct A {};
+
+// Check for template argument lists followed by junk
+// FIXME: The diagnostics here aren't great...
+A<int+> int x; // expected-error {{expected '>'}} expected-error {{expected unqualified-id}}
+A<int x; // expected-error {{expected '>'}}
+
diff --git a/test/Parser/cxx-template-decl.cpp b/test/Parser/cxx-template-decl.cpp
new file mode 100644
index 0000000..3a97efa
--- /dev/null
+++ b/test/Parser/cxx-template-decl.cpp
@@ -0,0 +1,108 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// Errors
+export class foo { };   // expected-error {{expected template}}
+template  x;            // expected-error {{C++ requires a type specifier for all declarations}} \
+                        // expected-error {{does not refer}}
+export template x;      // expected-error {{expected '<' after 'template'}}
+export template<class T> class x0; // expected-warning {{exported templates are unsupported}}
+template < ;            // expected-error {{parse error}} expected-warning {{declaration does not declare anything}}
+template <template X> struct Err1; // expected-error {{expected '<' after 'template'}} \
+// expected-error{{extraneous}}
+template <template <typename> > struct Err2;       // expected-error {{expected 'class' before '>'}} \
+// expected-error{{extraneous}}
+template <template <typename> Foo> struct Err3;    // expected-error {{expected 'class' before 'Foo'}} \
+// expected-error{{extraneous}}
+
+// Template function declarations
+template <typename T> void foo();
+template <typename T, typename U> void foo();
+
+// Template function definitions.
+template <typename T> void foo() { }
+
+// Template class (forward) declarations
+template <typename T> struct A;
+template <typename T, typename U> struct b;
+template <typename> struct C;
+template <typename, typename> struct D;
+
+// Forward declarations with default parameters?
+template <typename T = int> class X1;
+template <typename = int> class X2;
+
+// Forward declarations w/template template parameters
+template <template <typename> class T> class TTP1;
+template <template <typename> class> class TTP2;
+template <template <typename> class T = foo> class TTP3; // expected-error{{must be a class template}}
+template <template <typename> class = foo> class TTP3; // expected-error{{must be a class template}}
+template <template <typename X, typename Y> class T> class TTP5;
+
+// Forward declarations with non-type params
+template <int> class NTP0;
+template <int N> class NTP1;
+template <int N = 5> class NTP2;
+template <int = 10> class NTP3;
+template <unsigned int N = 12u> class NTP4; 
+template <unsigned int = 12u> class NTP5;
+template <unsigned = 15u> class NTP6;
+template <typename T, T Obj> class NTP7;
+
+// Template class declarations
+template <typename T> struct A { };
+template <typename T, typename U> struct B { };
+
+// Template parameter shadowing
+template<typename T, // expected-note{{template parameter is declared here}}
+         typename T> // expected-error{{declaration of 'T' shadows template parameter}}
+  void shadow1();
+
+template<typename T> // expected-note{{template parameter is declared here}}
+void shadow2(int T); // expected-error{{declaration of 'T' shadows template parameter}}
+
+template<typename T> // expected-note{{template parameter is declared here}}
+class T { // expected-error{{declaration of 'T' shadows template parameter}}
+};
+
+template<int Size> // expected-note{{template parameter is declared here}}
+void shadow3(int Size); // expected-error{{declaration of 'Size' shadows template parameter}}
+
+// <rdar://problem/6952203>
+template<typename T> // expected-note{{here}}
+struct shadow4 {
+  int T; // expected-error{{shadows}}
+};
+
+template<typename T> // expected-note{{here}}
+struct shadow5 {
+  int T(int, float); // expected-error{{shadows}}
+};
+
+// Non-type template parameters in scope
+template<int Size> 
+void f(int& i) {
+  i = Size;
+  Size = i; // expected-error{{expression is not assignable}}
+}
+
+template<typename T>
+const T& min(const T&, const T&);
+
+void f2() {
+  int x;
+  A< typeof(x>1) > a;
+}
+
+
+// PR3844
+template <> struct S<int> { }; // expected-error{{explicit specialization of non-template struct 'S'}}
+
+namespace PR6184 {
+  namespace N {
+    template <typename T>
+    void bar(typename T::x);
+  }
+  
+  template <typename T>
+  void N::bar(typename T::x) { }
+}
diff --git a/test/Parser/cxx-throw.cpp b/test/Parser/cxx-throw.cpp
new file mode 100644
index 0000000..a878816
--- /dev/null
+++ b/test/Parser/cxx-throw.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+int i;
+
+void foo() {
+  (throw,throw);
+  (1 ? throw 1 : throw 2);
+  throw int(1);
+  throw;
+  throw 1;
+  throw;
+  1 ? throw : (void)42;
+  __extension__ throw 1;    // expected-error {{expected expression}}
+  (void)throw;              // expected-error {{expected expression}}
+}
diff --git a/test/Parser/cxx-typeid.cpp b/test/Parser/cxx-typeid.cpp
new file mode 100644
index 0000000..a825dc3
--- /dev/null
+++ b/test/Parser/cxx-typeid.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// FIXME: This should really include <typeinfo>, but we don't have that yet.
+namespace std {
+  class type_info;
+}
+
+void f()
+{
+  (void)typeid(int);
+  (void)typeid(0);
+  (void)typeid 1; // expected-error {{error: expected '(' after 'typeid'}}
+}
diff --git a/test/Parser/cxx-typeof.cpp b/test/Parser/cxx-typeof.cpp
new file mode 100644
index 0000000..7e89101
--- /dev/null
+++ b/test/Parser/cxx-typeof.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+static void test() {
+  int *pi;
+  int x;
+  typeof pi[x] y; 
+}
diff --git a/test/Parser/cxx-using-declaration.cpp b/test/Parser/cxx-using-declaration.cpp
new file mode 100644
index 0000000..2b2a69d
--- /dev/null
+++ b/test/Parser/cxx-using-declaration.cpp
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace A {
+    int VA;
+    void FA() {}
+    struct SA { int V; };
+}
+
+using A::VA;
+using A::FA;
+using typename A::SA;
+
+int main()
+{
+    VA = 1;
+    FA();
+    SA x;   //Still needs handling.
+}
+
+struct B {
+    void f(char){};
+    void g(char){};
+};
+struct D : B {
+    using B::f;
+    void f(int);
+    void g(int);
+};
+void D::f(int) { f('c'); } // calls B::f(char)
+void D::g(int) { g('c'); } // recursively calls D::g(int)
+
+namespace E {
+    template <typename TYPE> int funcE(TYPE arg) { return(arg); }
+}
+
+using E::funcE<int>; // expected-error{{using declaration can not refer to a template specialization}}
+
+namespace F {
+    struct X;
+}
+
+using F::X;
+// Should have some errors here.  Waiting for implementation.
+void X(int);
+struct X *x;
diff --git a/test/Parser/cxx-using-directive.cpp b/test/Parser/cxx-using-directive.cpp
new file mode 100644
index 0000000..1e91899
--- /dev/null
+++ b/test/Parser/cxx-using-directive.cpp
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+class A {};
+
+namespace B {
+  namespace A {}
+  using namespace A ;
+}
+
+namespace C {}
+
+namespace D {
+  
+  class C {
+    
+    using namespace B ; // expected-error{{not allowed}}
+  };
+  
+  namespace B {}
+  
+  using namespace C ;
+  using namespace B::A ; // expected-error{{expected namespace name}}
+  //FIXME: would be nice to note, that A is not member of D::B
+  using namespace ::B::A ;
+  using namespace ::D::C ; // expected-error{{expected namespace name}}
+}
+
+using namespace ! ; // expected-error{{expected namespace name}}
+using namespace A ; // expected-error{{expected namespace name}}
+using namespace ::A // expected-error{{expected namespace name}} \
+                    // expected-error{{expected ';' after namespace name}}
+                    B ; 
+
+void test_nslookup() {
+  int B;
+  class C;
+  using namespace B;
+  using namespace C;
+}
+
diff --git a/test/Parser/cxx-variadic-func.cpp b/test/Parser/cxx-variadic-func.cpp
new file mode 100644
index 0000000..b9360d6
--- /dev/null
+++ b/test/Parser/cxx-variadic-func.cpp
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -fsyntax-only  %s
+
+void f(...) {
+  int g(int(...));
+}
diff --git a/test/Parser/cxx0x-attributes.cpp b/test/Parser/cxx0x-attributes.cpp
new file mode 100644
index 0000000..67b2ea6
--- /dev/null
+++ b/test/Parser/cxx0x-attributes.cpp
@@ -0,0 +1,61 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s
+
+// Declaration syntax checks
+[[]] int before_attr;
+int after_attr [[]];
+int * [[]] ptr_attr;
+int array_attr [1] [[]];
+[[align(8)]] int aligned_attr;
+[[test::valid(for 42 [very] **** '+' symbols went on a trip; the end.)]]
+  int garbage_attr;
+void fn_attr () [[]];
+class [[]] class_attr {};
+extern "C++" [[]] int extern_attr;
+template <typename T> [[]] void template_attr ();
+
+int comma_attr [[,]]; // expected-error {{expected identifier}}
+int scope_attr [[foo::]]; // expected-error {{expected identifier}}
+int & [[]] ref_attr = after_attr; // expected-error {{an attribute list cannot appear here}}
+class foo {
+  void after_const_attr () const [[]]; // expected-error {{expected expression}}
+};
+extern "C++" [[]] { } // expected-error {{an attribute list cannot appear here}}
+[[]] template <typename T> void before_template_attr (); // expected-error {{an attribute list cannot appear here}}
+[[]] namespace ns { int i; } // expected-error {{an attribute list cannot appear here}}
+[[]] static_assert(true, ""); //expected-error {{an attribute list cannot appear here}}
+[[]] asm(""); // expected-error {{an attribute list cannot appear here}}
+
+[[]] using ns::i; // expected-error {{an attribute list cannot appear here}}
+[[]] using namespace ns;
+
+// Argument tests
+[[final()]] int final_params; // expected-error {{C++0x attribute 'final' cannot have an argument list}}
+[[align]] int aligned_no_params; // expected-error {{C++0x attribute 'align' must have an argument list}}
+[[align(i)]] int aligned_nonconst; // expected-error {{'aligned' attribute requires integer constant}}
+
+// Statement tests
+void foo () {
+  [[]] ;
+  [[]] { }
+  [[]] if (0) { }
+  [[]] for (;;);
+  [[]] do {
+    [[]] continue;
+  } while (0);
+  [[]] while (0);
+  
+  [[]] switch (i) {
+    [[]] case 0:
+    [[]] default:
+      [[]] break;
+  }
+  
+  [[]] goto there;
+  [[]] there:
+  
+  [[]] try {
+  } [[]] catch (...) { // expected-error {{an attribute list cannot appear here}}
+  }
+  
+  [[]] return;
+}
diff --git a/test/Parser/cxx0x-literal-operators.cpp b/test/Parser/cxx0x-literal-operators.cpp
new file mode 100644
index 0000000..30b2903
--- /dev/null
+++ b/test/Parser/cxx0x-literal-operators.cpp
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s
+
+void operator "" (const char *); // expected-error {{expected identifier}}
+void operator "k" foo(const char *); // expected-error {{string literal after 'operator' must be '""'}}
+void operator "" tester (const char *);
diff --git a/test/Parser/cxx0x-rvalue-reference.cpp b/test/Parser/cxx0x-rvalue-reference.cpp
new file mode 100644
index 0000000..ae568e8
--- /dev/null
+++ b/test/Parser/cxx0x-rvalue-reference.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s
+
+int && r1(int &&a);
+
+typedef int && R;
+void r2(const R a) {
+  int & &&ar = a; // expected-error{{'ar' declared as a reference to a reference}}
+}
+
diff --git a/test/Parser/declarators.c b/test/Parser/declarators.c
new file mode 100644
index 0000000..31712af
--- /dev/null
+++ b/test/Parser/declarators.c
@@ -0,0 +1,85 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify -pedantic
+
+extern int a1[];
+
+void f0();
+void f1(int [*]);
+void f2(int [const *]);
+void f3(int [volatile const*]);
+int f4(*XX)(void); /* expected-error {{cannot return}} expected-warning {{type specifier missing, defaults to 'int'}} */
+
+char ((((*X))));
+
+void (*signal(int, void (*)(int)))(int);
+
+int aaaa, ***C, * const D, B(int);
+
+int *A;
+
+struct str;
+
+void test2(int *P, int A) {
+  struct str;
+
+  // Hard case for array decl, not Array[*].
+  int Array[*(int*)P+A];
+}
+
+typedef int atype;
+void test3(x, 
+           atype         /* expected-error {{unexpected type name 'atype': expected identifier}} */
+          ) int x, atype; {}
+
+void test4(x, x) int x; {} /* expected-error {{redefinition of parameter 'x'}} */
+
+
+// PR3031
+int (test5), ;  // expected-error {{expected identifier or '('}}
+
+
+
+// PR3963 & rdar://6759604 - test error recovery for mistyped "typenames".
+
+foo_t *d;      // expected-error {{unknown type name 'foo_t'}}
+foo_t a;   // expected-error {{unknown type name 'foo_t'}}
+int test6() { return a; }  // a should be declared.
+
+// Use of tagged type without tag. rdar://6783347
+struct xyz { int y; };
+enum myenum { ASDFAS };
+xyz b;         // expected-error {{must use 'struct' tag to refer to type 'xyz'}}
+myenum c;      // expected-error {{must use 'enum' tag to refer to type 'myenum'}}
+
+float *test7() {
+  // We should recover 'b' by parsing it with a valid type of "struct xyz", which
+  // allows us to diagnose other bad things done with y, such as this.
+  return &b.y;   // expected-warning {{incompatible pointer types returning 'int *' from a function with result type 'float *'}}
+}
+
+struct xyz test8() { return a; }  // a should be be marked invalid, no diag.
+
+
+// Verify that implicit int still works.
+static f;      // expected-warning {{type specifier missing, defaults to 'int'}}
+static g = 4;  // expected-warning {{type specifier missing, defaults to 'int'}}
+static h        // expected-warning {{type specifier missing, defaults to 'int'}} 
+      __asm__("foo");
+
+
+struct test9 {
+  int x  // expected-error {{expected ';' at end of declaration list}}
+  int y;
+  int z  // expected-warning {{expected ';' at end of declaration list}}
+};
+
+// PR6208
+struct test10 { int a; } static test10x;
+struct test11 { int a; } const test11x;
+
+// PR6216
+void test12() {
+  (void)__builtin_offsetof(struct { char c; int i; }, i);
+}
+
+// rdar://7608537
+struct test13 { int a; } (test13x);
diff --git a/test/Parser/designator.c b/test/Parser/designator.c
new file mode 100644
index 0000000..6badab7
--- /dev/null
+++ b/test/Parser/designator.c
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -fsyntax-only %s -verify -pedantic
+
+int X[] = {
+  [4]4,       // expected-warning {{use of GNU 'missing =' extension in designator}}
+  [5] = 7
+};
+
+struct foo {
+  int arr[10];
+};
+
+struct foo Y[10] = {
+  [4] .arr [2] = 4,
+
+  // This is not the GNU array init designator extension.
+  [4] .arr [2] 4  // expected-error {{expected '=' or another designator}}
+};
diff --git a/test/Parser/encode.m b/test/Parser/encode.m
new file mode 100644
index 0000000..e0e7535
--- /dev/null
+++ b/test/Parser/encode.m
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+int main(void) {
+  const char ch = @encode(char *)[2];
+  char c = @encode(char *)[2] + 4;
+  return c;
+}
+
diff --git a/test/Parser/enhanced-proto-1.m b/test/Parser/enhanced-proto-1.m
new file mode 100644
index 0000000..a3819f3
--- /dev/null
+++ b/test/Parser/enhanced-proto-1.m
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@protocol MyProto1 
+@optional
+- (void) FOO;
+@optional
+- (void) FOO;
+@required 
+- (void) REQ;
+@optional
+@end
+
+@protocol  MyProto2 <MyProto1>
+- (void) FOO2;
+@optional
+- (void) FOO3;
+@end
diff --git a/test/Parser/expressions.c b/test/Parser/expressions.c
new file mode 100644
index 0000000..44ebe66
--- /dev/null
+++ b/test/Parser/expressions.c
@@ -0,0 +1,50 @@
+// RUN: %clang_cc1 -parse-noop -verify %s
+
+void test1() {
+  if (sizeof (int){ 1});   // sizeof compound literal
+  if (sizeof (int));       // sizeof type
+
+  (int)4;   // cast.
+  (int){4}; // compound literal.
+
+  // FIXME: change this to the struct version when we can.
+  //int A = (struct{ int a;}){ 1}.a;
+  int A = (int){ 1}.a;
+}
+
+int test2(int a, int b) {
+  return a ? a,b : a;
+}
+
+int test3(int a, int b, int c) {
+  return a = b = c;
+}
+
+int test4() {
+  test4();
+}
+
+int test_offsetof() {
+  // FIXME: change into something that is semantically correct.
+  __builtin_offsetof(int, a.b.c[4][5]);
+}
+
+void test_sizeof(){
+        int arr[10];
+        sizeof arr[0];
+        sizeof(arr[0]);
+        sizeof(arr)[0];
+}
+
+// PR3418
+int test_leading_extension() {
+  __extension__ (*(char*)0) = 1;
+}
+
+// PR3972
+int test5(int);
+int test6(void) { 
+  return test5(      // expected-note {{to match}}
+               test5(1)
+                 ; // expected-error {{expected ')'}}
+}
diff --git a/test/Parser/expressions.m b/test/Parser/expressions.m
new file mode 100644
index 0000000..e27f405
--- /dev/null
+++ b/test/Parser/expressions.m
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -parse-noop %s
+
+void test1() {
+  @"s";            // expected-warning {{expression result unused}}
+}
+
diff --git a/test/Parser/extension.c b/test/Parser/extension.c
new file mode 100644
index 0000000..fd4cf80
--- /dev/null
+++ b/test/Parser/extension.c
@@ -0,0 +1,20 @@
+/* RUN: %clang_cc1 %s -fsyntax-only -pedantic -verify -std=c89
+ */
+
+/* Top level extension marker. */
+
+__extension__ typedef struct
+{
+    long long int quot; 
+    long long int rem; 
+} lldiv_t;
+
+
+/* Decl/expr __extension__ marker. */
+void bar() {
+  __extension__ int i;
+  int j;
+  __extension__ (j = 10LL);
+  __extension__ j = 10LL; /* expected-warning {{'long long' is an extension}} */
+}
+
diff --git a/test/Parser/function-decls.c b/test/Parser/function-decls.c
new file mode 100644
index 0000000..db9a98b
--- /dev/null
+++ b/test/Parser/function-decls.c
@@ -0,0 +1,10 @@
+/* RUN: %clang_cc1 %s -ast-print
+ */
+
+void foo() {
+  int X;
+  X = sizeof(void (*(*)())());
+  X = sizeof(int(*)(int, float, ...));
+  X = sizeof(void (*(int arga, void (*argb)(double Y)))(void* Z));
+}
+
diff --git a/test/Parser/goto-ident.c b/test/Parser/goto-ident.c
new file mode 100644
index 0000000..32051dc
--- /dev/null
+++ b/test/Parser/goto-ident.c
@@ -0,0 +1,6 @@
+/* RUN: %clang_cc1 -fsyntax-only -verify %s
+*/
+
+void foo() { 
+  goto ; /* expected-error {{expected identifier}} */
+}
diff --git a/test/Parser/if-scope-c90.c b/test/Parser/if-scope-c90.c
new file mode 100644
index 0000000..c368fab
--- /dev/null
+++ b/test/Parser/if-scope-c90.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c90 %s
+
+int f (int z)
+{ 
+  if (z > (int) sizeof (enum {a, b}))
+      return a;
+   return b;
+} 
diff --git a/test/Parser/if-scope-c99.c b/test/Parser/if-scope-c99.c
new file mode 100644
index 0000000..63f82e0
--- /dev/null
+++ b/test/Parser/if-scope-c99.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c99 %s
+
+int f (int z)
+{ 
+   if (z > (int) sizeof (enum {a, b}))
+      return a;
+   return b; // expected-error{{use of undeclared identifier}}
+}
diff --git a/test/Parser/implicit-casts.c b/test/Parser/implicit-casts.c
new file mode 100644
index 0000000..a2b31f9
--- /dev/null
+++ b/test/Parser/implicit-casts.c
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s
+_Complex double X;
+void test1(int c) {
+  X = 5;
+}
+void test2() {
+  int i;
+  double d = i;
+  double _Complex a = 5;
+
+  test1(a);
+  a = 5;
+  d = i;
+}
+int test3() {
+  int a[2];
+  a[0] = test3; // expected-warning{{incompatible pointer to integer conversion assigning to 'int' from 'int ()'}}
+  return 0;
+}
+short x; void test4(char c) { x += c; }
+int y; void test5(char c) { y += c; }
diff --git a/test/Parser/knr_parameter_attributes.c b/test/Parser/knr_parameter_attributes.c
new file mode 100644
index 0000000..fb975cb
--- /dev/null
+++ b/test/Parser/knr_parameter_attributes.c
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -fsyntax-only -W -Wall -Werror -verify %s
+
+int f(int i __attribute__((__unused__)))
+{
+    return 0;
+}
+int g(i)
+    int i __attribute__((__unused__));
+{
+    return 0;
+}
diff --git a/test/Parser/method-prototype-1.m b/test/Parser/method-prototype-1.m
new file mode 100644
index 0000000..d2d9563
--- /dev/null
+++ b/test/Parser/method-prototype-1.m
@@ -0,0 +1,43 @@
+// RUN: %clang_cc1 %s -parse-noop
+@interface MyObject 
+- (void) bycopy  : (int) woodo, ... ;
+- (void) break  : (int) woodo, ... ;
+- (void) enum  : (int) woodo, ... ;
+- (void) struct  : (int) woodo, ... ;
+- (void) union  : (int) woodo, ... ;
+- (void) if  : (int) woodo, int i, char chh, ... ;
+- (void) else  : (int) woodo, ... ;
+- (void) while  : (int) woodo, ... ;
+- (void) do  : (int) woodo, ... ;
+- (void) for  : (int) woodo, ... ;
+- (void) switch  : (int) woodo, ... ;
+- (void) case  : (int) woodo, ... ;
+- (void) default  : (int) woodo, ... ;
+- (void) break  : (int) woodo, ... ;
+- (void) continue  : (int) woodo, ... ;
+- (void) return  : (int) woodo, ... ;
+- (void) goto  : (int) woodo, ... ;
+- (void) sizeof  : (int) woodo, ... ;
+- (void) typeof  : (int) woodo, ... ;
+- (void) __alignof  : (int) woodo, ... ;
+- (void) unsigned  : (int) woodo, ... ;
+- (void) long  : (int) woodo, ... ;
+- (void) const  : (int) woodo, ... ;
+- (void) short  : (int) woodo, ... ;
+- (void) volatile  : (int) woodo, ... ;
+- (void) signed  : (int) woodo, ... ;
+- (void) restrict  : (int) woodo, ... ;
+- (void) _Complex  : (int) woodo, ... ;
+- (void) in  : (int) woodo, ... ;
+- (void) out  : (int) woodo, ... ;
+- (void) inout  : (int) woodo, ... ;
+- (void) bycopy  : (int) woodo, ... ;
+- (void) byref  : (int) woodo, ... ;
+- (void) oneway  : (int) woodo, ... ;
+- (void) int  : (int) woodo, ... ;
+- (void) char  : (int) woodo, ... ;
+- (void) float  : (int) woodo, ... ;
+- (void) double  : (int) woodo, ... ;
+- (void) void  : (int) woodo, ... ;
+- (void) _Bool  : (int) woodo, ... ;
+@end
diff --git a/test/Parser/missing-end.m b/test/Parser/missing-end.m
new file mode 100644
index 0000000..fb26461
--- /dev/null
+++ b/test/Parser/missing-end.m
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@interface AAA
+{
+}
+@ x// expected-error{{expected an Objective-C directive after '@'}}
+// expected-error{{missing @end}}
diff --git a/test/Parser/namelookup-bug-1.c b/test/Parser/namelookup-bug-1.c
new file mode 100644
index 0000000..8667a71
--- /dev/null
+++ b/test/Parser/namelookup-bug-1.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -verify %s
+
+typedef int Object;
+
+struct Object *pp;
+
+Object staticObject1;
diff --git a/test/Parser/namelookup-bug-2.c b/test/Parser/namelookup-bug-2.c
new file mode 100644
index 0000000..84850ff
--- /dev/null
+++ b/test/Parser/namelookup-bug-2.c
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -verify %s
+
+typedef int Object;
+
+struct Object {int i1; } *P;
+
+void foo() {
+ struct Object { int i2; } *X;
+  Object:
+ {
+    Object a;
+ }
+}
+
diff --git a/test/Parser/namespace-alias-attr.cpp b/test/Parser/namespace-alias-attr.cpp
new file mode 100644
index 0000000..ba80922
--- /dev/null
+++ b/test/Parser/namespace-alias-attr.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -verify %s
+
+namespace A
+{
+}
+
+namespace B __attribute__ (( static )) = A; // expected-error{{attributes can not be specified on namespace alias}}
+
diff --git a/test/Parser/objc-alias-printing.m b/test/Parser/objc-alias-printing.m
new file mode 100644
index 0000000..8b9cc6e
--- /dev/null
+++ b/test/Parser/objc-alias-printing.m
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -ast-print %s
+
+@protocol P1 @end
+@protocol P2 @end
+
+@interface INTF @end
+
+@compatibility_alias alias INTF;
+
+
+int foo ()
+{
+	INTF *pi;
+	INTF<P2,P1> *pi2;
+	alias *p;
+	alias<P1,P2> *p2;
+	return pi2 == p2;
+}
diff --git a/test/Parser/objc-category-neg-1.m b/test/Parser/objc-category-neg-1.m
new file mode 100644
index 0000000..5799db0
--- /dev/null
+++ b/test/Parser/objc-category-neg-1.m
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+void __assert_rtn(const char *, const char *, int, const char *) __attribute__((__noreturn__));
+static __inline__ int __inline_isfinitef (float ) __attribute__ ((always_inline));
+
+@interface NSATSTypesetter (NSPantherCompatibility) // expected-error {{ "cannot find interface declaration for 'NSATSTypesetter'" }}
+- (id)lineFragmentRectForProposedRect:(id)proposedRect remainingRect:(id)remainingRect __attribute__((deprecated));
+@end
diff --git a/test/Parser/objc-forcollection-1.m b/test/Parser/objc-forcollection-1.m
new file mode 100644
index 0000000..4850deb
--- /dev/null
+++ b/test/Parser/objc-forcollection-1.m
@@ -0,0 +1,43 @@
+// RUN: %clang_cc1 -fsyntax-only %s
+
+typedef struct objc_class *Class;
+typedef struct objc_object {
+ Class isa;
+} *id;
+    
+            
+@protocol P @end
+
+@interface MyList
+@end
+    
+@implementation MyList
+- (unsigned int)countByEnumeratingWithState:  (struct __objcFastEnumerationState *)state objects:  (id *)items count:(unsigned int)stackcount
+{
+        return 0;
+}
+@end
+
+@interface MyList (BasicTest)
+- (void)compilerTestAgainst;
+@end
+
+@implementation MyList (BasicTest)
+- (void)compilerTestAgainst {
+	int i;
+        for (id elem in self) 
+           ++i;
+        for (MyList *elem in self) 
+           ++i;
+        for (id<P> se in self) 
+           ++i;
+
+	MyList<P> *p;
+        for (p in self) 
+           ++i;
+
+	for (p in p)
+	  ++i;
+}
+@end
+
diff --git a/test/Parser/objc-forcollection-neg-2.m b/test/Parser/objc-forcollection-neg-2.m
new file mode 100644
index 0000000..e02c51c
--- /dev/null
+++ b/test/Parser/objc-forcollection-neg-2.m
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+typedef struct objc_class *Class;
+typedef struct objc_object {
+ Class isa;
+} *id;
+    
+            
+@protocol P @end
+
+@interface MyList
+@end
+    
+@implementation MyList
+- (unsigned int)countByEnumeratingWithState:  (struct __objcFastEnumerationState *)state objects:  (id *)items count:(unsigned int)stackcount
+{
+        return 0;
+}
+@end
+
+@interface MyList (BasicTest)
+- (void)compilerTestAgainst;
+@end
+
+@implementation MyList (BasicTest)
+- (void)compilerTestAgainst {
+    static i;// expected-warning {{type specifier missing, defaults to 'int'}}
+        for (id el, elem in self)  // expected-error {{only one element declaration is allowed}}
+           ++i;
+        for (id el in self) 
+           ++i;
+	MyList<P> ***p;
+        for (p in self)  // expected-error {{selector element type 'MyList<P> ***' is not a valid object type}}
+           ++i;
+
+}
+@end
+
diff --git a/test/Parser/objc-forcollection-neg.m b/test/Parser/objc-forcollection-neg.m
new file mode 100644
index 0000000..0ba093e
--- /dev/null
+++ b/test/Parser/objc-forcollection-neg.m
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+typedef struct objc_class *Class;
+typedef struct objc_object {
+ Class isa;
+} *id;
+    
+            
+@interface MyList
+@end
+    
+@implementation MyList
+- (unsigned int)countByEnumeratingWithState:  (struct __objcFastEnumerationState *)state objects:  (id *)items count:(unsigned int)stackcount
+{
+        return 0;
+}
+@end
+
+@interface MyList (BasicTest)
+- (void)compilerTestAgainst;
+@end
+
+@implementation MyList (BasicTest)
+- (void)compilerTestAgainst {
+
+        int i=0;
+        for (int * elem in elem) // expected-error {{selector element type 'int *' is not a valid object}} \
+				    expected-error {{collection expression type 'int *' is not a valid object}}
+           ++i;
+        for (i in elem)  // expected-error {{use of undeclared identifier 'elem'}} \
+			    expected-error {{selector element type 'int' is not a valid object}}
+           ++i;
+        for (id se in i) // expected-error {{collection expression type 'int' is not a valid object}} 
+           ++i;
+}
+@end
+
diff --git a/test/Parser/objc-foreach-syntax.m b/test/Parser/objc-foreach-syntax.m
new file mode 100644
index 0000000..943540e
--- /dev/null
+++ b/test/Parser/objc-foreach-syntax.m
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+
+
+@implementation MyList // expected-warning {{cannot find interface declaration for 'MyList'}}
+- (unsigned int)countByEnumeratingWithState:  (struct __objcFastEnumerationState *)state objects:  (id *)items count:(unsigned int)stackcount
+{
+     return 0;
+}
+@end
+
+
+int LOOP();
+
+@implementation MyList (BasicTest) 
+- (void)compilerTestAgainst {
+MyList * el; 
+     for (el in @"foo") 
+	  { LOOP(); }
+}
+@end
+
+
+static int test7(id keys) {
+  for (id key; in keys) ;  // expected-error {{use of undeclared identifier 'in'}}
+}
diff --git a/test/Parser/objc-init.m b/test/Parser/objc-init.m
new file mode 100644
index 0000000..32ba948
--- /dev/null
+++ b/test/Parser/objc-init.m
@@ -0,0 +1,60 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -pedantic
+// RUN: %clang_cc1 -fsyntax-only -verify -x objective-c++ %s 
+// rdar://5707001
+
+@interface NSNumber;
+- () METH;
+- (unsigned) METH2;
+@end
+
+struct SomeStruct {
+  int x, y, z, q;
+};
+
+void test1() {
+	id objects[] = {[NSNumber METH]};
+}
+
+void test2(NSNumber x) { // expected-error {{Objective-C interface type 'NSNumber' cannot be passed by value; did you forget * in 'NSNumber'}}
+	id objects[] = {[x METH]};
+}
+
+void test3(NSNumber *x) {
+	id objects[] = {[x METH]};
+}
+
+
+// rdar://5977581
+void test4() {
+  unsigned x[] = {[NSNumber METH2]+2};
+}
+
+void test5(NSNumber *x) {
+  unsigned y[] = {
+    [4][NSNumber METH2]+2,   // expected-warning {{use of GNU 'missing =' extension in designator}}
+    [4][x METH2]+2   // expected-warning {{use of GNU 'missing =' extension in designator}}
+  };
+  
+  struct SomeStruct z = {
+    .x = [x METH2], // ok.
+    .x [x METH2]    // expected-error {{expected '=' or another designator}}
+  };
+}
+
+// rdar://7370882
+@interface SemicolonsAppDelegate 
+{
+  id i;
+}
+@property (assign) id window;
+@end
+
+@implementation SemicolonsAppDelegate
+{
+  id i;
+}
+  @synthesize window=i;
+@end
+
+
+
diff --git a/test/Parser/objc-interfaces.m b/test/Parser/objc-interfaces.m
new file mode 100644
index 0000000..aac3faa
--- /dev/null
+++ b/test/Parser/objc-interfaces.m
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify
+
+// Test features and error recovery for objc interfaces.
+
+@interface INTF
+- (int*) foo2  __attribute__((deprecated)) : (int) x1 __attribute__((deprecated)); // expected-error {{expected ';' after method prototype}}
+@end
+
diff --git a/test/Parser/objc-messaging-1.m b/test/Parser/objc-messaging-1.m
new file mode 100644
index 0000000..511290e
--- /dev/null
+++ b/test/Parser/objc-messaging-1.m
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 %s -parse-noop
+int main ()
+{
+	int i,j;
+	struct S *p;
+        id a, b, c;
+	[p ii];
+	[p if: 1 :2];
+	[p inout: 1 :2 another:(2,3,4)];
+	[p inout: 1 :2 another:(2,3,4), 6,6,8];
+	[p inout: 1 :2 another:(2,3,4), (6,4,5),6,8];
+	[p inout: 1 :2 another:(i+10), (i,j-1,5),6,8];
+	[p long: 1 :2 another:(i+10), (i,j-1,5),6,8];
+	[p : "Hello\n" :2 another:(i+10), (i,j-1,5),6,8];
+
+	// Comma expression as receiver (rdar://6222856)
+	[a, b, c foo];
+
+}
diff --git a/test/Parser/objc-messaging-neg-1.m b/test/Parser/objc-messaging-neg-1.m
new file mode 100644
index 0000000..4ddadb8
--- /dev/null
+++ b/test/Parser/objc-messaging-neg-1.m
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@interface A
++(void) foo:(int) a;
+@end
+
+int main() {
+  id a;
+  [a bla:0 6:7]; // expected-error {{expected ']'}}
+  [A foo bar]; // expected-error {{expected ':'}}
+  [A foo bar bar1]; // expected-error {{expected ':'}}
+}
diff --git a/test/Parser/objc-missing-impl.m b/test/Parser/objc-missing-impl.m
new file mode 100644
index 0000000..05d9d6c
--- /dev/null
+++ b/test/Parser/objc-missing-impl.m
@@ -0,0 +1,2 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+@end // expected-warning {{@end must appear in an @implementation context}}
diff --git a/test/Parser/objc-property-syntax.m b/test/Parser/objc-property-syntax.m
new file mode 100644
index 0000000..064a209
--- /dev/null
+++ b/test/Parser/objc-property-syntax.m
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@interface MyClass {
+
+};
+@property unsigned char bufferedUTF8Bytes[4];  // expected-error {{property cannot have array or function type}}
+@property unsigned char bufferedUTFBytes:1;    // expected-error {{property name cannot be a bitfield}}
+@property(nonatomic, retain, setter=ab_setDefaultToolbarItems) MyClass *ab_defaultToolbarItems; // expected-error {{method name referenced in property setter attribute must end with ':'}}
+@end
+
+@implementation MyClass
+@dynamic ab_defaultToolbarItems;
+@end
+
diff --git a/test/Parser/objc-quirks.m b/test/Parser/objc-quirks.m
new file mode 100644
index 0000000..b6671d1
--- /dev/null
+++ b/test/Parser/objc-quirks.m
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// FIXME: This is a horrible error message here. Fix.
+int @"s" = 5;  // expected-error {{prefix attribute must be}}
+
+
+// rdar://6480479
+@interface A
+}; // expected-error {{missing @end}} expected-error {{expected external declaration}}
+
+
+
+
+// PR6811
+// 'super' isn't an expression, it is a magic context-sensitive keyword.
+@interface A2 {
+  id isa;
+}
+- (void)a;
+@end
+
+@interface B2 : A2 @end
+@implementation B2
+- (void)a
+{
+  [(super) a];  // expected-error {{use of undeclared identifier 'super'}}
+}
+@end
diff --git a/test/Parser/objc-synthesized-recover.m b/test/Parser/objc-synthesized-recover.m
new file mode 100644
index 0000000..3f04a8c
--- /dev/null
+++ b/test/Parser/objc-synthesized-recover.m
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@interface I1 
+{
+  int value;
+  int value2;
+}
+@property int value;
+@property int value2;
+@end
+
+@implementation I1
+@synthesize value, - value2; // expected-error{{expected a property name}}
+@synthesize value2;
+@end
diff --git a/test/Parser/objc-try-catch-1.m b/test/Parser/objc-try-catch-1.m
new file mode 100644
index 0000000..1934cbd
--- /dev/null
+++ b/test/Parser/objc-try-catch-1.m
@@ -0,0 +1,68 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -x objective-c++ %s
+void * proc();
+
+@interface NSConstantString
+@end
+
+@interface Frob
+@end
+
+@interface Frob1
+@end
+
+void * foo()
+{
+  @try {
+    return proc();
+  }
+  @catch (Frob* ex) {
+    @throw;
+  }
+  @catch (Frob1* ex) {
+    @throw proc();
+  }
+  @finally {
+    @try {
+      return proc();
+    }
+    @catch (Frob* ex) {
+      @throw 1,2; // expected-error {{@throw requires an Objective-C object type ('int' invalid)}}
+    }
+    @catch (float x) {  // expected-error {{@catch parameter is not a pointer to an interface type}}
+      
+    }
+    @catch(...) {
+      @throw (4,3,proc());
+    }
+  }
+
+  @try {  // expected-error {{@try statement without a @catch and @finally clause}}
+    return proc();
+  }
+}
+
+
+void bar()
+{
+  @try {}// expected-error {{@try statement without a @catch and @finally clause}}
+  @"s"; //  expected-warning {{result unused}}
+}
+
+void baz()
+{
+  @try {}// expected-error {{@try statement without a @catch and @finally clause}}
+  @try {}
+  @finally {}
+}
+
+void noTwoTokenLookAheadRequiresABitOfFancyFootworkInTheParser() {
+    @try {
+        // Do something
+    } @catch (...) {}
+    @try {
+        // Do something
+    } @catch (...) {}
+    return;
+}
+
diff --git a/test/Parser/objc-type-printing.m b/test/Parser/objc-type-printing.m
new file mode 100644
index 0000000..9bbdac9
--- /dev/null
+++ b/test/Parser/objc-type-printing.m
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -ast-print %s
+
+@protocol P1 @end
+@protocol P2 @end
+@protocol P3 @end
+
+@interface INTF 
+- (INTF<P1>*) METH;
+@end
+
+void foo()
+{
+        INTF *pintf;
+	INTF<P1>* p1;
+	INTF<P1, P1>* p2;
+	INTF<P1, P3>* p3;
+	INTF<P1, P3, P2>* p4;
+	INTF<P2,P2, P3, P1>* p5;
+}
diff --git a/test/Parser/offsetof.c b/test/Parser/offsetof.c
new file mode 100644
index 0000000..3a5b9f3
--- /dev/null
+++ b/test/Parser/offsetof.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct a { struct { int b; } x[2]; };
+
+int a = __builtin_offsetof(struct a, x; // expected-error{{expected ')'}} expected-note{{to match this '('}}
+// FIXME: This actually shouldn't give an error
+int b = __builtin_offsetof(struct a, x->b); // expected-error{{expected ')'}} expected-note{{to match this '('}}
diff --git a/test/Parser/parmvardecl_conversion.c b/test/Parser/parmvardecl_conversion.c
new file mode 100644
index 0000000..9fa8a68
--- /dev/null
+++ b/test/Parser/parmvardecl_conversion.c
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+void f (int p[]) { p++; }
+
diff --git a/test/Parser/pointer-arithmetic.c b/test/Parser/pointer-arithmetic.c
new file mode 100644
index 0000000..87eb1a2
--- /dev/null
+++ b/test/Parser/pointer-arithmetic.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+int *test1(int *a)         { return a + 1; }
+int *test2(int *a)         { return 1 + a; }
+int *test3(int *a)         { return a - 1; }
+int  test4(int *a, int *b) { return a - b; }
+
+int  test5(int *a, int *b) { return a + b; } /* expected-error {{invalid operands}} */
+int *test6(int *a)         { return 1 - a; } /* expected-error {{invalid operands}} */
diff --git a/test/Parser/pointer_promotion.c b/test/Parser/pointer_promotion.c
new file mode 100644
index 0000000..30589d0
--- /dev/null
+++ b/test/Parser/pointer_promotion.c
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+void test() {
+  void *vp;
+  int *ip;
+  char *cp;
+  struct foo *fp;
+  struct bar *bp;
+  short sint = 7;
+
+  if (ip < cp) {} // expected-warning {{comparison of distinct pointer types ('int *' and 'char *')}}
+  if (cp < fp) {} // expected-warning {{comparison of distinct pointer types ('char *' and 'struct foo *')}}
+  if (fp < bp) {} // expected-warning {{comparison of distinct pointer types ('struct foo *' and 'struct bar *')}}
+  if (ip < 7) {} // expected-warning {{comparison between pointer and integer ('int *' and 'int')}}
+  if (sint < ip) {} // expected-warning {{comparison between pointer and integer ('int' and 'int *')}}
+  if (ip == cp) {} // expected-warning {{comparison of distinct pointer types ('int *' and 'char *')}}
+}
diff --git a/test/Parser/pragma-pack.c b/test/Parser/pragma-pack.c
new file mode 100644
index 0000000..84778cd
--- /dev/null
+++ b/test/Parser/pragma-pack.c
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// Note that this puts the expected lines before the directives to work around
+// limitations in the -verify mode.
+
+/* expected-warning {{missing '(' after '#pragma pack'}}*/ #pragma pack 10
+#pragma pack()
+#pragma pack(8)
+
+/*expected-warning {{unknown action for '#pragma pack'}}*/ #pragma pack(hello) 
+#pragma pack(push)
+#pragma pack(pop)
+
+/* expected-warning {{expected integer or identifier in '#pragma pack'}}*/ #pragma pack(push,)
+/* expected-warning {{expected integer or identifier in '#pragma pack'}}*/ #pragma pack(push,)
+/* expected-warning {{expected integer or identifier in '#pragma pack'}}*/  #pragma pack(pop,) 
+
+#pragma pack(push,i)
+/* expected-warning {{expected integer or identifier in '#pragma pack'}}*/ #pragma pack(push,i, 
+/* expected-warning {{expected integer or identifier in '#pragma pack'}}*/ #pragma pack(push,i,) 
+/* expected-warning {{expected integer or identifier in '#pragma pack'}}*/ #pragma pack(push,i,help) 
+
+#pragma pack(push,8)
+/* expected-warning {{missing ')' after '#pragma pack'}}*/ #pragma pack(push,8, 
+/* expected-warning {{missing ')' after '#pragma pack'}}*/ #pragma pack(push,8,) 
+/* expected-warning {{missing ')' after '#pragma pack'}}*/ #pragma pack(push,i,8 
+#pragma pack(push,i,8)
+
+/* expected-warning {{missing ')' after '#pragma pack'}}*/ #pragma pack(push 
+
+_Pragma("pack(push)")
+/* expected-warning {{expected integer or identifier in '#pragma pack'}}*/ _Pragma("pack(push,)") 
diff --git a/test/Parser/pragma-weak.c b/test/Parser/pragma-weak.c
new file mode 100644
index 0000000..7e5740b
--- /dev/null
+++ b/test/Parser/pragma-weak.c
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// Note that this puts the expected lines before the directives to work around
+// limitations in the -verify mode.
+
+int x;
+/* expected-warning {{expected identifier in '#pragma weak'}}*/ #pragma weak
+#pragma weak x
+
+extern int z;
+/* expected-warning {{expected identifier in '#pragma weak'}}*/ #pragma weak z = =
+/* expected-warning {{expected identifier in '#pragma weak'}}*/ #pragma weak z =
+/* expected-warning {{weak identifier 'y' never declared}} */ #pragma weak z = y
+
+extern int a;
+/* expected-warning {{extra tokens at end of '#pragma weak'}}*/ #pragma weak a b
+/* expected-warning {{extra tokens at end of '#pragma weak'}}*/ #pragma weak a = x c
diff --git a/test/Parser/prefix-attributes.m b/test/Parser/prefix-attributes.m
new file mode 100644
index 0000000..399421f
--- /dev/null
+++ b/test/Parser/prefix-attributes.m
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -verify -fsyntax-only %s
+
+__attribute__((deprecated)) @class B; // expected-error {{prefix attribute must be followed by an interface or protocol}}
+
+__attribute__((deprecated)) @interface A @end
+__attribute__((deprecated)) @protocol P0;
+__attribute__((deprecated)) @protocol P1
+@end
diff --git a/test/Parser/promote_types_in_proto.c b/test/Parser/promote_types_in_proto.c
new file mode 100644
index 0000000..969ba28
--- /dev/null
+++ b/test/Parser/promote_types_in_proto.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 %s
+void functionPromotion(void f(char *const []));
+void arrayPromotion(char * const argv[]);
+
+int whatever(int argc, char *argv[])
+{
+        arrayPromotion(argv);
+        functionPromotion(arrayPromotion);
+}
diff --git a/test/Parser/recovery.c b/test/Parser/recovery.c
new file mode 100644
index 0000000..8e7181e
--- /dev/null
+++ b/test/Parser/recovery.c
@@ -0,0 +1,75 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -pedantic -fblocks %s
+
+// PR2241
+float test2241[2] = { 
+  1e,            // expected-error {{exponent}}
+  1ee0           // expected-error {{exponent}}
+};
+
+
+// Testcase derived from PR2692
+static void f (char * (*g) (char **, int), char **p, ...) {
+  char *s;
+  va_list v;                              // expected-error {{identifier}}
+  s = g (p, __builtin_va_arg(v, int));    // expected-error {{identifier}}
+}
+
+
+// PR3172
+} // expected-error {{expected external declaration}}
+
+
+// rdar://6094870
+void test(int a) {
+  struct { int i; } x;
+  
+  if (x.hello)   // expected-error {{no member named 'hello'}}
+    test(0);
+  else
+    ;
+  
+  if (x.hello == 0)   // expected-error {{no member named 'hello'}}
+    test(0);
+  else
+    ;
+  
+  if ((x.hello == 0))   // expected-error {{no member named 'hello'}}
+    test(0);
+  else
+    ;
+  
+  if (x.i == 0))   // expected-error {{expected expression}}
+    test(0);
+  else
+    ;
+}
+
+
+
+char ((((                       /* expected-note {{to match this '('}} */
+         *X x ] ))));                    /* expected-error {{expected ')'}} */
+
+;   // expected-warning {{ISO C does not allow an extra ';' outside of a function}}
+
+
+
+
+struct S { void *X, *Y; };
+
+struct S A = {
+&BADIDENT, 0     /* expected-error {{use of undeclared identifier}} */
+};
+
+// rdar://6248081
+void test6248081() { 
+  [10]  // expected-error {{expected expression}}
+}
+
+struct forward; // expected-note{{forward declaration of 'struct forward'}}
+void x(struct forward* x) {switch(x->a) {}} // expected-error {{incomplete definition of type}}
+
+// PR3410
+void foo() {
+  int X;
+  X = 4 // expected-error{{expected ';' after expression}}
+}
diff --git a/test/Parser/selector-1.m b/test/Parser/selector-1.m
new file mode 100644
index 0000000..1f9cad6
--- /dev/null
+++ b/test/Parser/selector-1.m
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -parse-noop %s 
+
+int main() {
+ SEL s = @selector(retain);
+ SEL s1 = @selector(meth1:);
+ SEL s2 = @selector(retainArgument::);
+ SEL s3 = @selector(retainArgument:::::);
+ SEL s4 = @selector(retainArgument:with:);
+ SEL s5 = @selector(meth1:with:with:);
+ SEL s6 = @selector(getEnum:enum:bool:);
+ SEL s7 = @selector(char:float:double:unsigned:short:long:);
+
+ SEL s9 = @selector(:enum:bool:);
+}
diff --git a/test/Parser/statements.c b/test/Parser/statements.c
new file mode 100644
index 0000000..bc7192a
--- /dev/null
+++ b/test/Parser/statements.c
@@ -0,0 +1,64 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -Wno-unreachable-code
+
+void test1() {
+  { ; {  ;;}} ;;
+}
+
+void test2() {
+  if (0) { if (1) {} } else { }
+
+  do { } while (0); 
+  
+  while (0) while(0) do ; while(0);
+
+  for ((void)0;0;(void)0)
+    for (;;)
+      for ((void)9;0;(void)2)
+        ;
+  for (int X = 0; 0; (void)0);
+}
+
+void test3() {
+    switch (0) {
+    
+    case 4:
+      if (0) {
+    case 6: ;
+      }
+    default:
+      ;     
+  }
+}
+
+void test4() {
+  if (0);  // expected-warning {{if statement has empty body}}
+  
+  int X;  // declaration in a block.
+  
+foo:  if (0); // expected-warning {{if statement has empty body}}
+}
+
+typedef int t;
+void test5() {
+  if (0);   // expected-warning {{if statement has empty body}}
+
+  t x = 0;
+
+  if (0);  // expected-warning {{if statement has empty body}}
+}
+
+
+void test6(void) { 
+  do 
+    .           // expected-error {{expected expression}}
+   while (0);
+}
+
+int test7() {
+  return 4     // expected-error {{expected ';' after return statement}}
+}
+
+void test8() {
+  // Should not skip '}' and produce a "expected '}'" error.
+  undecl // expected-error {{use of undeclared identifier 'undecl'}}
+}
diff --git a/test/Parser/struct-recursion.c b/test/Parser/struct-recursion.c
new file mode 100644
index 0000000..834c5d0
--- /dev/null
+++ b/test/Parser/struct-recursion.c
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 %s -fsyntax-only
+
+// C99 6.7.2.3p11
+
+// mutually recursive structs
+struct s1 { struct s2 *A; };
+struct s2 { struct s1 *B; };
+
+// both types are complete now.
+struct s1 a;
+struct s2 b;
diff --git a/test/Parser/top-level-semi-cxx0x.cpp b/test/Parser/top-level-semi-cxx0x.cpp
new file mode 100644
index 0000000..592483c
--- /dev/null
+++ b/test/Parser/top-level-semi-cxx0x.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only -pedantic -std=c++0x -verify %s
+
+void foo();
+
+void bar() { };
+
+void wibble();
+
+;
+
+namespace Blah {
+  void f() { };
+  
+  void g();
+}
diff --git a/test/Parser/traditional_arg_scope.c b/test/Parser/traditional_arg_scope.c
new file mode 100644
index 0000000..3811d0d
--- /dev/null
+++ b/test/Parser/traditional_arg_scope.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -fsyntax-only %s -verify
+
+int x(a) int a; {return a;}
+int y(b) int b; {return a;} // expected-error {{use of undeclared identifier}}
+
+// PR2332
+int a(a)int a;{a=10;return a;}
diff --git a/test/Parser/typeof.c b/test/Parser/typeof.c
new file mode 100644
index 0000000..cf0e47a
--- /dev/null
+++ b/test/Parser/typeof.c
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+typedef int TInt;
+
+static void test() {
+  int *pi;
+
+  int typeof (int) aIntInt; // expected-error{{cannot combine with previous 'int' declaration specifier}}
+  short typeof (int) aShortInt; // expected-error{{'short typeof' is invalid}} 
+  int int ttt; // expected-error{{cannot combine with previous 'int' declaration specifier}}
+  typeof(TInt) anInt; 
+  short TInt eee; // expected-error{{expected ';' at end of declaration}}
+  void ary[7] fff; // expected-error{{array has incomplete element type 'void'}} expected-error{{expected ';' at end of declaration}}
+  typeof(void ary[7]) anIntError; // expected-error{{expected ')'}} expected-note {{to match this '('}}  expected-error {{variable has incomplete type 'typeof(void)' (aka 'void')}}
+  typeof(const int) aci; 
+  const typeof (*pi) aConstInt; 
+  int xx;
+  int *i;
+}
diff --git a/test/Parser/types.c b/test/Parser/types.c
new file mode 100644
index 0000000..0e8a63d
--- /dev/null
+++ b/test/Parser/types.c
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 %s -parse-noop
+
+// Test the X can be overloaded inside the struct.
+typedef int X; 
+struct Y { short X; };
+
+// Variable shadows type, PR3872
+
+typedef struct foo { int x; } foo;
+void test() {
+   foo *foo;
+   foo->x = 0;
+}
+
diff --git a/test/Preprocessor/_Pragma-dependency.c b/test/Preprocessor/_Pragma-dependency.c
new file mode 100644
index 0000000..a2861c9
--- /dev/null
+++ b/test/Preprocessor/_Pragma-dependency.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 %s -E 2>&1 | grep 'DO_PRAGMA (STR'
+// RUN: %clang_cc1 %s -E 2>&1 | grep '7:3'
+
+#define DO_PRAGMA _Pragma 
+#define STR "GCC dependency \"parse.y\"")
+  // Test that this line is printed by caret diagnostics.
+  DO_PRAGMA (STR
diff --git a/test/Preprocessor/_Pragma-dependency2.c b/test/Preprocessor/_Pragma-dependency2.c
new file mode 100644
index 0000000..c178764
--- /dev/null
+++ b/test/Preprocessor/_Pragma-dependency2.c
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -E %s -verify
+
+#define DO_PRAGMA _Pragma 
+DO_PRAGMA ("GCC dependency \"blahblabh\"")  // expected-error {{file not found}}
+
diff --git a/test/Preprocessor/_Pragma-location.c b/test/Preprocessor/_Pragma-location.c
new file mode 100644
index 0000000..8b68d6c
--- /dev/null
+++ b/test/Preprocessor/_Pragma-location.c
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 %s -E | not grep 'scratch space'
+
+#define push _Pragma ("pack(push)")
+push
diff --git a/test/Preprocessor/_Pragma-physloc.c b/test/Preprocessor/_Pragma-physloc.c
new file mode 100644
index 0000000..a093af2
--- /dev/null
+++ b/test/Preprocessor/_Pragma-physloc.c
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 %s -E | grep '#pragma x y z'
+// RUN: %clang_cc1 %s -E | grep '#pragma a b c'
+
+_Pragma("x y z")
+_Pragma("a b c")
+
diff --git a/test/Preprocessor/_Pragma.c b/test/Preprocessor/_Pragma.c
new file mode 100644
index 0000000..0a83b14
--- /dev/null
+++ b/test/Preprocessor/_Pragma.c
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 %s -verify -Wall
+
+_Pragma ("GCC system_header")  // expected-warning {{system_header ignored in main file}}
+
+// rdar://6880630
+_Pragma("#define macro")    // expected-warning {{unknown pragma ignored}}
+
+#ifdef macro
+#error #define invalid
+#endif
diff --git a/test/Preprocessor/assembler-with-cpp.c b/test/Preprocessor/assembler-with-cpp.c
new file mode 100644
index 0000000..0543077
--- /dev/null
+++ b/test/Preprocessor/assembler-with-cpp.c
@@ -0,0 +1,74 @@
+// RUN: %clang_cc1 -x assembler-with-cpp -E %s -o - | FileCheck -strict-whitespace -check-prefix=CHECK-Identifiers-False %s
+
+#ifndef __ASSEMBLER__
+#error "__ASSEMBLER__ not defined"
+#endif
+
+
+// Invalid token pasting is ok. 
+#define A X ## .
+1: A
+// CHECK-Identifiers-False: 1: X .
+
+// Line markers are not linemarkers in .S files, they are passed through.
+# 321
+// CHECK-Identifiers-False: # 321
+
+// Unknown directives are passed through.
+# B C
+// CHECK-Identifiers-False: # B C
+
+// Unknown directives are expanded.
+#define D(x) BAR ## x
+# D(42)
+// CHECK-Identifiers-False: # BAR42
+
+// Unmatched quotes are permitted.
+2: '
+3: "
+// CHECK-Identifiers-False: 2: '
+// CHECK-Identifiers-False: 3: "
+
+// (balance quotes to keep editors happy): "'
+
+// Empty char literals are ok.
+4: ''
+// CHECK-Identifiers-False: 4: ''
+
+
+// Portions of invalid pasting should still expand as macros.
+// rdar://6709206
+#define M4 expanded
+#define M5() M4 ## (
+
+5: M5()
+// CHECK-Identifiers-False: 5: expanded (
+
+// rdar://6804322
+#define FOO(name)  name ## $foo
+6: FOO(blarg)
+// CHECK-Identifiers-False: 6: blarg $foo
+
+// RUN: %clang_cc1 -x assembler-with-cpp -fdollars-in-identifiers -E %s -o - | FileCheck -check-prefix=CHECK-Identifiers-True -strict-whitespace %s
+#define FOO(name)  name ## $foo
+7: FOO(blarg)
+// CHECK-Identifiers-True: 7: blarg$foo
+
+// 
+#define T6() T6 #nostring
+#define T7(x) T7 #x
+8: T6()
+9: T7(foo)
+// CHECK-Identifiers-True: 8: T6 #nostring
+// CHECK-Identifiers-True: 9: T7 "foo"
+
+// Concatenation with period doesn't leave a space
+#define T8(A,B) A ## B
+10: T8(.,T8)
+// CHECK-Identifiers-True: 10: .T8
+
+// This should not crash.
+#define T11(a) #0
+11: T11(b)
+// CHECK-Identifiers-True: 11: #0
+
diff --git a/test/Preprocessor/builtin_line.c b/test/Preprocessor/builtin_line.c
new file mode 100644
index 0000000..52228b5
--- /dev/null
+++ b/test/Preprocessor/builtin_line.c
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 %s -E | grep "^  4"
+#define FOO __LINE__
+
+  FOO
+
+// PR3579 - This should expand to the __LINE__ of the ')' not of the X.
+// RUN: %clang_cc1 %s -E | grep "^A 13"
+
+#define X() __LINE__
+
+A X(
+
+)
diff --git a/test/Preprocessor/c90.c b/test/Preprocessor/c90.c
new file mode 100644
index 0000000..1d5010d
--- /dev/null
+++ b/test/Preprocessor/c90.c
@@ -0,0 +1,10 @@
+/* RUN: %clang_cc1 %s -std=c89 -Eonly -verify -pedantic-errors 
+ */
+
+/* PR3919 */
+
+#define foo`bar   /* expected-error {{whitespace required after macro name}} */
+#define foo2!bar  /* expected-warning {{whitespace recommended after macro name}} */
+
+#define foo3$bar  /* expected-error {{'$' in identifier}} */
+
diff --git a/test/Preprocessor/c99-6_10_3_3_p4.c b/test/Preprocessor/c99-6_10_3_3_p4.c
new file mode 100644
index 0000000..320e6cf
--- /dev/null
+++ b/test/Preprocessor/c99-6_10_3_3_p4.c
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -E %s | FileCheck -strict-whitespace %s
+
+#define hash_hash # ## # 
+#define mkstr(a) # a 
+#define in_between(a) mkstr(a) 
+#define join(c, d) in_between(c hash_hash d) 
+char p[] = join(x, y);
+
+// CHECK: char p[] = "x ## y";
+
diff --git a/test/Preprocessor/c99-6_10_3_4_p5.c b/test/Preprocessor/c99-6_10_3_4_p5.c
new file mode 100644
index 0000000..6dea09d
--- /dev/null
+++ b/test/Preprocessor/c99-6_10_3_4_p5.c
@@ -0,0 +1,28 @@
+// Example from C99 6.10.3.4p5
+// RUN: %clang_cc1 -E %s | FileCheck -strict-whitespace %s
+
+#define x 3 
+#define f(a) f(x * (a)) 
+#undef x 
+#define x 2 
+#define g f 
+#define z z[0] 
+#define h g(~ 
+#define m(a) a(w) 
+#define w 0,1 
+#define t(a) a 
+#define p() int 
+#define q(x) x 
+#define r(x,y) x ## y 
+#define str(x) # x 
+            f(y+1) + f(f(z)) % t(t(g)(0) + t)(1); 
+            g(x+(3,4)-w) | h 5) & m 
+(f)^m(m); 
+p() i[q()] = { q(1), r(2,3), r(4,), r(,5), r(,) }; 
+char c[2][6] = { str(hello), str() }; 
+
+// CHECK: f(2 * (y+1)) + f(2 * (f(2 * (z[0])))) % f(2 * (0)) + t(1);
+// CHECK: f(2 * (2 +(3,4)-0,1)) | f(2 * (~ 5)) & f(2 * (0,1))^m(0,1);
+// CHECK: int i[] = { 1, 23, 4, 5, };
+// CHECK: char c[2][6] = { "hello", "" };
+
diff --git a/test/Preprocessor/c99-6_10_3_4_p6.c b/test/Preprocessor/c99-6_10_3_4_p6.c
new file mode 100644
index 0000000..98bacb2
--- /dev/null
+++ b/test/Preprocessor/c99-6_10_3_4_p6.c
@@ -0,0 +1,27 @@
+// Example from C99 6.10.3.4p6
+
+// RUN: %clang_cc1 -E %s | FileCheck -strict-whitespace %s
+
+#define str(s) # s 
+#define xstr(s) str(s) 
+#define debug(s, t) printf("x" # s "= %d, x" # t "= s" \ 
+                           x ## s, x ## t) 
+#define INCFILE(n) vers ## n 
+#define glue(a, b) a ## b 
+#define xglue(a, b) glue(a, b) 
+#define HIGHLOW "hello" 
+#define LOW LOW ", world" 
+debug(1, 2); 
+fputs(str(strncmp("abc\0d" "abc", '\4') // this goes away 
+          == 0) str(: @\n), s); 
+include xstr(INCFILE(2).h) 
+glue(HIGH, LOW); 
+xglue(HIGH, LOW) 
+
+
+// CHECK: printf("x" "1" "= %d, x" "2" "= s" x1, x2);
+// CHECK: fputs("strncmp(\"abc\\0d\" \"abc\", '\\4') == 0" ": @\n", s);
+// CHECK: include "vers2.h"
+// CHECK: "hello";
+// CHECK: "hello" ", world"
+
diff --git a/test/Preprocessor/c99-6_10_3_4_p7.c b/test/Preprocessor/c99-6_10_3_4_p7.c
new file mode 100644
index 0000000..b63209b
--- /dev/null
+++ b/test/Preprocessor/c99-6_10_3_4_p7.c
@@ -0,0 +1,10 @@
+// Example from C99 6.10.3.4p7
+
+// RUN: %clang_cc1 -E %s | FileCheck -strict-whitespace %s
+
+#define t(x,y,z) x ## y ## z 
+int j[] = { t(1,2,3), t(,4,5), t(6,,7), t(8,9,), 
+t(10,,), t(,11,), t(,,12), t(,,) }; 
+
+// CHECK: int j[] = { 123, 45, 67, 89,
+// CHECK: 10, 11, 12, };
diff --git a/test/Preprocessor/c99-6_10_3_4_p9.c b/test/Preprocessor/c99-6_10_3_4_p9.c
new file mode 100644
index 0000000..04c4b79
--- /dev/null
+++ b/test/Preprocessor/c99-6_10_3_4_p9.c
@@ -0,0 +1,20 @@
+// Example from C99 6.10.3.4p9
+
+// RUN: %clang_cc1 -E %s | FileCheck -strict-whitespace %s
+
+#define debug(...) fprintf(stderr, __VA_ARGS__) 
+#define showlist(...) puts(#__VA_ARGS__) 
+#define report(test, ...) ((test)?puts(#test):\
+                           printf(__VA_ARGS__)) 
+debug("Flag");
+// CHECK: fprintf(stderr, "Flag");
+
+debug("X = %d\n", x);
+// CHECK: fprintf(stderr, "X = %d\n", x);
+
+showlist(The first, second, and third items.);
+// CHECK: puts("The first, second, and third items.");
+
+report(x>y, "x is %d but y is %d", x, y);
+// CHECK: ((x>y)?puts("x>y"): printf("x is %d but y is %d", x, y));
+
diff --git a/test/Preprocessor/clang_headers.c b/test/Preprocessor/clang_headers.c
new file mode 100644
index 0000000..f2dec4f
--- /dev/null
+++ b/test/Preprocessor/clang_headers.c
@@ -0,0 +1,3 @@
+// RUN: %clang_cc1 -E %s
+
+#include <limits.h>
diff --git a/test/Preprocessor/comment_save.c b/test/Preprocessor/comment_save.c
new file mode 100644
index 0000000..b860042
--- /dev/null
+++ b/test/Preprocessor/comment_save.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -E -C %s | FileCheck -strict-whitespace %s
+
+// foo
+// CHECK: // foo
+
+/* bar */
+// CHECK: /* bar */
+
diff --git a/test/Preprocessor/comment_save_if.c b/test/Preprocessor/comment_save_if.c
new file mode 100644
index 0000000..2f35bcb
--- /dev/null
+++ b/test/Preprocessor/comment_save_if.c
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 %s -E -CC -pedantic 2>&1 | grep -v '^/' | not grep warning
+
+#if 1 /*bar */
+
+#endif /*foo*/
+
diff --git a/test/Preprocessor/comment_save_macro.c b/test/Preprocessor/comment_save_macro.c
new file mode 100644
index 0000000..6ad759f
--- /dev/null
+++ b/test/Preprocessor/comment_save_macro.c
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -E -C %s | FileCheck -check-prefix=CHECK-C -strict-whitespace %s
+// CHECK-C: boo bork bar // zot
+
+// RUN: %clang_cc1 -E -CC %s | FileCheck -check-prefix=CHECK-CC -strict-whitespace %s
+// CHECK-CC: boo bork /* blah*/ bar // zot
+
+// RUN: %clang_cc1 -E %s | FileCheck -check-prefix=CHECK -strict-whitespace %s
+// CHECK: boo bork bar
+
+
+#define FOO bork // blah
+boo FOO bar // zot
+
diff --git a/test/Preprocessor/cxx_and.cpp b/test/Preprocessor/cxx_and.cpp
new file mode 100644
index 0000000..a84ffe7
--- /dev/null
+++ b/test/Preprocessor/cxx_and.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -DA -DB -E %s | grep 'int a = 37 == 37'
+// RUN: %clang_cc1 -DA -E %s | grep 'int a = 927 == 927'
+// RUN: %clang_cc1 -DB -E %s | grep 'int a = 927 == 927'
+// RUN: %clang_cc1 -E %s | grep 'int a = 927 == 927'
+#if defined(A) and defined(B)
+#define X 37
+#else
+#define X 927
+#endif
+
+#if defined(A) && defined(B)
+#define Y 37
+#else
+#define Y 927
+#endif
+
+int a = X == Y;
diff --git a/test/Preprocessor/cxx_bitand.cpp b/test/Preprocessor/cxx_bitand.cpp
new file mode 100644
index 0000000..01b4ff1
--- /dev/null
+++ b/test/Preprocessor/cxx_bitand.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -DA=1 -DB=2 -E %s | grep 'int a = 927 == 927'
+// RUN: %clang_cc1 -DA=1 -DB=1 -E %s | grep 'int a = 37 == 37'
+// RUN: %clang_cc1 -E %s | grep 'int a = 927 == 927'
+#if A bitand B
+#define X 37
+#else
+#define X 927
+#endif
+
+#if A & B
+#define Y 37
+#else
+#define Y 927
+#endif
+
+int a = X == Y;
diff --git a/test/Preprocessor/cxx_bitor.cpp b/test/Preprocessor/cxx_bitor.cpp
new file mode 100644
index 0000000..c92596e
--- /dev/null
+++ b/test/Preprocessor/cxx_bitor.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -DA=1 -DB=1 -E %s | grep 'int a = 37 == 37'
+// RUN: %clang_cc1 -DA=0 -DB=1 -E %s | grep 'int a = 37 == 37'
+// RUN: %clang_cc1 -DA=1 -DB=0 -E %s | grep 'int a = 37 == 37'
+// RUN: %clang_cc1 -DA=0 -DB=0 -E %s | grep 'int a = 927 == 927'
+// RUN: %clang_cc1 -E %s | grep 'int a = 927 == 927'
+#if A bitor B
+#define X 37
+#else
+#define X 927
+#endif
+
+#if A | B
+#define Y 37
+#else
+#define Y 927
+#endif
+
+int a = X == Y;
diff --git a/test/Preprocessor/cxx_compl.cpp b/test/Preprocessor/cxx_compl.cpp
new file mode 100644
index 0000000..824092c
--- /dev/null
+++ b/test/Preprocessor/cxx_compl.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -DA=1 -E %s | grep 'int a = 37 == 37'
+// RUN: %clang_cc1 -DA=0 -E %s | grep 'int a = 927 == 927'
+// RUN: %clang_cc1 -E %s | grep 'int a = 927 == 927'
+#if compl 0 bitand A
+#define X 37
+#else
+#define X 927
+#endif
+
+#if ~0 & A
+#define Y 37
+#else
+#define Y 927
+#endif
+
+int a = X == Y;
diff --git a/test/Preprocessor/cxx_not.cpp b/test/Preprocessor/cxx_not.cpp
new file mode 100644
index 0000000..67e8775
--- /dev/null
+++ b/test/Preprocessor/cxx_not.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -DA=1 -E %s | grep 'int a = 927 == 927'
+// RUN: %clang_cc1 -E %s | grep 'int a = 37 == 37'
+#if not defined(A)
+#define X 37
+#else
+#define X 927
+#endif
+
+#if ! defined(A)
+#define Y 37
+#else
+#define Y 927
+#endif
+
+int a = X == Y;
diff --git a/test/Preprocessor/cxx_not_eq.cpp b/test/Preprocessor/cxx_not_eq.cpp
new file mode 100644
index 0000000..f7670fa
--- /dev/null
+++ b/test/Preprocessor/cxx_not_eq.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -DA=1 -DB=1 -E %s | grep 'int a = 927 == 927'
+// RUN: %clang_cc1 -E %s | grep 'int a = 927 == 927'
+// RUN: %clang_cc1 -DA=1 -DB=2 -E %s | grep 'int a = 37 == 37'
+#if A not_eq B
+#define X 37
+#else
+#define X 927
+#endif
+
+#if A != B
+#define Y 37
+#else
+#define Y 927
+#endif
+
+int a = X == Y;
diff --git a/test/Preprocessor/cxx_oper_keyword.cpp b/test/Preprocessor/cxx_oper_keyword.cpp
new file mode 100644
index 0000000..3fc246d
--- /dev/null
+++ b/test/Preprocessor/cxx_oper_keyword.cpp
@@ -0,0 +1,7 @@
+// RUN: not %clang_cc1 %s -E
+// RUN: %clang_cc1 %s -E -fno-operator-names
+
+// Not valid in C++ unless -fno-operator-names is passed.
+#define and foo
+
+
diff --git a/test/Preprocessor/cxx_oper_spelling.cpp b/test/Preprocessor/cxx_oper_spelling.cpp
new file mode 100644
index 0000000..0ae9afd
--- /dev/null
+++ b/test/Preprocessor/cxx_oper_spelling.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -E %s | grep 'a: "and"'
+
+#define X(A) #A
+
+// C++'03 2.5p2: "In all respects of the language, each alternative 
+// token behaves the same, respectively, as its primary token, 
+// except for its spelling"
+//
+// This should be spelled as 'and', not '&&'
+a: X(and)
+
diff --git a/test/Preprocessor/cxx_or.cpp b/test/Preprocessor/cxx_or.cpp
new file mode 100644
index 0000000..e8ed92f
--- /dev/null
+++ b/test/Preprocessor/cxx_or.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -DA -DB -E %s | grep 'int a = 37 == 37'
+// RUN: %clang_cc1 -DA -E %s | grep 'int a = 37 == 37'
+// RUN: %clang_cc1 -DB -E %s | grep 'int a = 37 == 37'
+// RUN: %clang_cc1 -E %s | grep 'int a = 927 == 927'
+#if defined(A) or defined(B)
+#define X 37
+#else
+#define X 927
+#endif
+
+#if defined(A) || defined(B)
+#define Y 37
+#else
+#define Y 927
+#endif
+
+int a = X == Y;
diff --git a/test/Preprocessor/cxx_true.cpp b/test/Preprocessor/cxx_true.cpp
new file mode 100644
index 0000000..b123e0c
--- /dev/null
+++ b/test/Preprocessor/cxx_true.cpp
@@ -0,0 +1,13 @@
+/* RUN: %clang_cc1 -E %s -x c++ | grep block_1
+   RUN: %clang_cc1 -E %s -x c++ | not grep block_2
+   RUN: %clang_cc1 -E %s -x c | not grep block
+*/
+
+#if true
+block_1
+#endif
+
+#if false
+block_2
+#endif
+
diff --git a/test/Preprocessor/cxx_xor.cpp b/test/Preprocessor/cxx_xor.cpp
new file mode 100644
index 0000000..24a6ce4
--- /dev/null
+++ b/test/Preprocessor/cxx_xor.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -DA=1 -DB=1 -E %s | grep 'int a = 927 == 927'
+// RUN: %clang_cc1 -DA=0 -DB=1 -E %s | grep 'int a = 37 == 37'
+// RUN: %clang_cc1 -DA=1 -DB=0 -E %s | grep 'int a = 37 == 37'
+// RUN: %clang_cc1 -DA=0 -DB=0 -E %s | grep 'int a = 927 == 927'
+// RUN: %clang_cc1 -E %s | grep 'int a = 927 == 927'
+#if A xor B
+#define X 37
+#else
+#define X 927
+#endif
+
+#if A ^ B
+#define Y 37
+#else
+#define Y 927
+#endif
+
+int a = X == Y;
diff --git a/test/Preprocessor/dependencies-and-pp.c b/test/Preprocessor/dependencies-and-pp.c
new file mode 100644
index 0000000..7877df3
--- /dev/null
+++ b/test/Preprocessor/dependencies-and-pp.c
@@ -0,0 +1,31 @@
+// Test -MT and -E flags, PR4063
+
+// RUN: %clang -E -o %t.1 %s
+// RUN: %clang -E -MD -MF %t.d -MT foo -o %t.2 %s
+// RUN: diff %t.1 %t.2
+// RUN: grep "foo:" %t.d
+// RUN: grep "dependencies-and-pp.c" %t.d
+
+// Test -MQ flag without quoting
+
+// RUN: %clang -E -MD -MF %t.d -MQ foo -o %t %s
+// RUN: grep "foo:" %t.d
+
+// Test -MQ flag with quoting
+
+// RUN: %clang -E -MD -MF %t.d -MQ '$fo\ooo ooo\ ooo\\ ooo#oo' -o %t %s
+// RUN: fgrep '$$fo\ooo\ ooo\\\ ooo\\\\\ ooo\#oo:' %t.d
+
+// Test consecutive -MT flags
+
+// RUN: %clang -E -MD -MF %t.d -MT foo -MT bar -MT baz -o %t %s
+// RUN: diff %t.1 %t
+// RUN: fgrep "foo bar baz:" %t.d
+
+// Test consecutive -MT and -MQ flags
+
+// RUN: %clang -E -MD -MF %t.d -MT foo -MQ '$(bar)' -MT 'b az' -MQ 'qu ux' -MQ ' space' -o %t %s
+// RUN: fgrep 'foo $$(bar) b az qu\ ux \ space:' %t.d
+
+// TODO: Test default target without quoting
+// TODO: Test default target with quoting
diff --git a/test/Preprocessor/directive-invalid.c b/test/Preprocessor/directive-invalid.c
new file mode 100644
index 0000000..86cd253
--- /dev/null
+++ b/test/Preprocessor/directive-invalid.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -E -verify %s
+// rdar://7683173
+
+#define r_paren )
+#if defined( x r_paren  // expected-error {{missing ')' after 'defined'}} \
+                        // expected-note {{to match this '('}}
+#endif
diff --git a/test/Preprocessor/disabled-cond-diags.c b/test/Preprocessor/disabled-cond-diags.c
new file mode 100644
index 0000000..531842a
--- /dev/null
+++ b/test/Preprocessor/disabled-cond-diags.c
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -E %s 2>&1 | not grep "warning\|error"
+
+#if 0
+
+// Shouldn't get warnings here.
+??( ??)
+
+// Should not get an error here.
+` ` ` `
+#endif
diff --git a/test/Preprocessor/dump-macros-spacing.c b/test/Preprocessor/dump-macros-spacing.c
new file mode 100644
index 0000000..1392442
--- /dev/null
+++ b/test/Preprocessor/dump-macros-spacing.c
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -E -dD < %s | grep stdin | grep -v define
+#define A A
+/* 1
+ * 2
+ * 3
+ * 4
+ * 5
+ * 6
+ * 7
+ * 8
+ */
+#define B B
+
diff --git a/test/Preprocessor/dump-options.c b/test/Preprocessor/dump-options.c
new file mode 100644
index 0000000..a329bd4
--- /dev/null
+++ b/test/Preprocessor/dump-options.c
@@ -0,0 +1,3 @@
+// RUN: %clang %s -E -dD | grep __INTMAX_MAX__
+// RUN: %clang %s -E -dM | grep __INTMAX_MAX__
+
diff --git a/test/Preprocessor/dump_macros.c b/test/Preprocessor/dump_macros.c
new file mode 100644
index 0000000..d420eb4
--- /dev/null
+++ b/test/Preprocessor/dump_macros.c
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -E -dM %s -o - | FileCheck %s -strict-whitespace
+
+// Space at end even without expansion tokens
+// CHECK: #define A(x) 
+#define A(x)
+
+// Space before expansion list.
+// CHECK: #define B(x,y) x y
+#define B(x,y)x y
+
+// No space in argument list.
+// CHECK: #define C(x,y) x y
+#define C(x, y) x y
+
+// No paste avoidance.
+// CHECK: #define D() ..
+#define D() ..
+
+// Simple test.
+// CHECK: #define E .
+// CHECK: #define F X()Y
+#define E .
+#define F X()Y
+
+// gcc prints macros at end of translation unit, so last one wins.
+// CHECK: #define G 2
+#define G 1
+#undef G
+#define G 2
+
+// Variadic macros of various sorts. PR5699
+
+// CHECK: H(x,...) __VA_ARGS__
+#define H(x, ...) __VA_ARGS__
+// CHECK: I(...) __VA_ARGS__
+#define I(...) __VA_ARGS__
+// CHECK: J(x...) __VA_ARGS__
+#define J(x ...) __VA_ARGS__
diff --git a/test/Preprocessor/dumptokens_phyloc.c b/test/Preprocessor/dumptokens_phyloc.c
new file mode 100644
index 0000000..7321c0e
--- /dev/null
+++ b/test/Preprocessor/dumptokens_phyloc.c
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -dump-tokens %s 2>&1 | grep "Spelling=.*dumptokens_phyloc.c:3:20"
+
+#define TESTPHYLOC 10
+
+TESTPHYLOC
diff --git a/test/Preprocessor/expr_comma.c b/test/Preprocessor/expr_comma.c
new file mode 100644
index 0000000..538727d
--- /dev/null
+++ b/test/Preprocessor/expr_comma.c
@@ -0,0 +1,10 @@
+// Comma is not allowed in C89
+// RUN: not %clang_cc1 -E %s -std=c89 -pedantic-errors
+
+// Comma is allowed if unevaluated in C99
+// RUN: %clang_cc1 -E %s -std=c99 -pedantic-errors 
+
+// PR2279
+
+#if 0? 1,2:3
+#endif
diff --git a/test/Preprocessor/expr_invalid_tok.c b/test/Preprocessor/expr_invalid_tok.c
new file mode 100644
index 0000000..5defcc5
--- /dev/null
+++ b/test/Preprocessor/expr_invalid_tok.c
@@ -0,0 +1,15 @@
+// RUN: not %clang_cc1 -E %s 2>&1 | grep 'invalid token at start of a preprocessor expression'
+// RUN: not %clang_cc1 -E %s 2>&1 | grep 'token is not a valid binary operator in a preprocessor subexpression'
+// RUN: not %clang_cc1 -E %s 2>&1 | grep ':14: error: expected end of line in preprocessor expression'
+// PR2220
+
+#if 1 * * 2
+#endif
+
+#if 4 [ 2
+#endif
+
+
+// PR2284 - The constant-expr production does not including comma.
+#if 1 ? 2 : 0, 1
+#endif
diff --git a/test/Preprocessor/expr_liveness.c b/test/Preprocessor/expr_liveness.c
new file mode 100644
index 0000000..c3b6421
--- /dev/null
+++ b/test/Preprocessor/expr_liveness.c
@@ -0,0 +1,52 @@
+/* RUN: %clang_cc1 -E %s -DNO_ERRORS -Werror -Wundef
+   RUN: not %clang_cc1 -E %s
+ */
+
+#ifdef NO_ERRORS
+/* None of these divisions by zero are in live parts of the expression, do not
+   emit any diagnostics. */
+
+#define MACRO_0 0
+#define MACRO_1 1
+
+#if MACRO_0 && 10 / MACRO_0
+foo
+#endif
+
+#if MACRO_1 || 10 / MACRO_0
+bar
+#endif
+
+#if 0 ? 124/0 : 42
+#endif
+
+// PR2279
+#if 0 ? 1/0: 2
+#else
+#error
+#endif
+
+// PR2279
+#if 1 ? 2 ? 3 : 4 : 5
+#endif
+
+// PR2284
+#if 1 ? 0: 1 ? 1/0: 1/0
+#endif
+
+#else
+
+
+/* The 1/0 is live, it should error out. */
+#if 0 && 1 ? 4 : 1 / 0
+baz
+#endif
+
+
+#endif
+
+// rdar://6505352
+// -Wundef should not warn about use of undefined identifier if not live.
+#if (!defined(XXX) || XXX > 42)
+#endif
+
diff --git a/test/Preprocessor/expr_multichar.c b/test/Preprocessor/expr_multichar.c
new file mode 100644
index 0000000..8ab12d9
--- /dev/null
+++ b/test/Preprocessor/expr_multichar.c
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 < %s -E -verify -triple i686-pc-linux-gnu
+
+#if (('1234' >> 24) != '1')
+#error Bad multichar constant calculation!
+#endif
diff --git a/test/Preprocessor/expr_usual_conversions.c b/test/Preprocessor/expr_usual_conversions.c
new file mode 100644
index 0000000..5ca2cb8
--- /dev/null
+++ b/test/Preprocessor/expr_usual_conversions.c
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 %s -E -verify
+
+#define INTMAX_MIN (-9223372036854775807LL -1)
+
+#if (-42 + 0U) /* expected-warning {{left side of operator converted from negative value to unsigned: -42 to 18446744073709551574}} */  \
+  / -2         /* expected-warning {{right side of operator converted from negative value to unsigned: -2 to 18446744073709551614}} */
+foo
+#endif
+
+// Shifts don't want the usual conversions: PR2279
+#if (2 << 1U) - 30 >= 0
+#error
+#endif
+
diff --git a/test/Preprocessor/extension-warning.c b/test/Preprocessor/extension-warning.c
new file mode 100644
index 0000000..4ba57f7
--- /dev/null
+++ b/test/Preprocessor/extension-warning.c
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s
+
+// The preprocessor shouldn't warn about extensions within macro bodies that
+// aren't expanded.
+#define TY typeof
+#define TY1 typeof(1)
+
+// But we should warn here
+TY1 x; // expected-warning {{extension}}
+TY(1) x; // FIXME: And we should warn here
+
+// Note: this warning intentionally doesn't trigger on keywords like
+// __attribute; the standard allows implementation-defined extensions
+// prefixed with "__".
+// Current list of keywords this can trigger on:
+// inline, restrict, asm, typeof, _asm
+
+void whatever() {}
diff --git a/test/Preprocessor/feature_tests.c b/test/Preprocessor/feature_tests.c
new file mode 100644
index 0000000..35592bd
--- /dev/null
+++ b/test/Preprocessor/feature_tests.c
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 %s -triple=i686-apple-darwin9
+// RUN: %clang_cc1 %s -E -triple=i686-apple-darwin9
+#ifndef __has_feature
+#error Should have __has_feature
+#endif
+
+
+#if __has_feature(something_we_dont_have)
+#error Bad
+#endif
+
+#if  !__has_builtin(__builtin_huge_val) || \
+     !__has_builtin(__builtin_shufflevector) || \
+     !__has_builtin(__builtin_trap) || \
+     !__has_feature(attribute_analyzer_noreturn) || \
+     !__has_feature(attribute_overloadable)
+#error Clang should have these
+#endif
+
+#if __has_builtin(__builtin_insanity)
+#error Clang should not have this
+#endif
+
+
+
+// Make sure we have x86 builtins only (forced with target triple).
+
+#if !__has_builtin(__builtin_ia32_emms) || \
+    __has_builtin(__builtin_altivec_abs_v4sf)
+#error Broken handling of target-specific builtins
+#endif
diff --git a/test/Preprocessor/file_to_include.h b/test/Preprocessor/file_to_include.h
new file mode 100644
index 0000000..97728ab
--- /dev/null
+++ b/test/Preprocessor/file_to_include.h
@@ -0,0 +1,3 @@
+
+#warning file successfully included
+
diff --git a/test/Preprocessor/function_macro_file.c b/test/Preprocessor/function_macro_file.c
new file mode 100644
index 0000000..c97bb75
--- /dev/null
+++ b/test/Preprocessor/function_macro_file.c
@@ -0,0 +1,5 @@
+/* RUN: %clang_cc1 -E -P %s | grep f
+ */
+
+#include "function_macro_file.h"
+()
diff --git a/test/Preprocessor/function_macro_file.h b/test/Preprocessor/function_macro_file.h
new file mode 100644
index 0000000..43d1199
--- /dev/null
+++ b/test/Preprocessor/function_macro_file.h
@@ -0,0 +1,3 @@
+
+#define f() x
+f
diff --git a/test/Preprocessor/has_include.c b/test/Preprocessor/has_include.c
new file mode 100644
index 0000000..c34c348
--- /dev/null
+++ b/test/Preprocessor/has_include.c
@@ -0,0 +1,83 @@
+// RUN: %clang_cc1 -Eonly -verify %s
+
+// Try different path permutations of __has_include with existing file.
+#if __has_include("stdio.h")
+#else
+  #error "__has_include failed (1)."
+#endif
+
+#if __has_include(<stdio.h>)
+#else
+  #error "__has_include failed (2)."
+#endif
+
+// Try unary expression.
+#if !__has_include("stdio.h")
+  #error "__has_include failed (5)."
+#endif
+
+// Try binary expression.
+#if __has_include("stdio.h") && __has_include("stddef.h")
+#else
+  #error "__has_include failed (6)."
+#endif
+
+// Try non-existing file.
+#if __has_include("blahblah.h")
+  #error "__has_include failed (7)."
+#endif
+
+// Try defined.
+#if !defined(__has_include)
+  #error "defined(__has_include) failed (8)."
+#endif
+
+// Try different path permutations of __has_include_next with existing file.
+#if __has_include_next("stddef.h") // expected-warning {{#include_next in primary source file}}
+#else
+  #error "__has_include failed (1)."
+#endif
+
+#if __has_include_next(<stddef.h>) // expected-warning {{#include_next in primary source file}}
+#else
+  #error "__has_include failed (2)."
+#endif
+
+// Try unary expression.
+#if !__has_include_next("stdio.h") // expected-warning {{#include_next in primary source file}}
+  #error "__has_include_next failed (5)."
+#endif
+
+// Try binary expression.
+#if __has_include_next("stdio.h") && __has_include("stddef.h") // expected-warning {{#include_next in primary source file}}
+#else
+  #error "__has_include_next failed (6)."
+#endif
+
+// Try non-existing file.
+#if __has_include_next("blahblah.h") // expected-warning {{#include_next in primary source file}}
+  #error "__has_include_next failed (7)."
+#endif
+
+// Try defined.
+#if !defined(__has_include_next)
+  #error "defined(__has_include_next) failed (8)."
+#endif
+
+// Try badly formed expressions.
+// FIXME: I don't quite know how to avoid preprocessor side effects.
+// Use FileCheck?
+// It also assert due to unterminated #if's.
+//#if __has_include("stdio.h"
+//#if __has_include "stdio.h")
+//#if __has_include(stdio.h)
+//#if __has_include()
+//#if __has_include(
+//#if __has_include)
+//#if __has_include
+//#if __has_include(<stdio.h>
+//#if __has_include<stdio.h>)
+//#if __has_include("stdio.h)
+//#if __has_include(stdio.h")
+//#if __has_include(<stdio.h)
+//#if __has_include(stdio.h>)
diff --git a/test/Preprocessor/hash_line.c b/test/Preprocessor/hash_line.c
new file mode 100644
index 0000000..4f724df
--- /dev/null
+++ b/test/Preprocessor/hash_line.c
@@ -0,0 +1,8 @@
+// The 1 and # should not go on the same line.
+// RUN: %clang_cc1 %s -E | not grep "1 #"
+// RUN: %clang_cc1 %s -E | grep '^1$'
+// RUN: %clang_cc1 %s -E | grep '^      #$'
+1
+#define EMPTY
+EMPTY #
+
diff --git a/test/Preprocessor/hash_space.c b/test/Preprocessor/hash_space.c
new file mode 100644
index 0000000..ac97556
--- /dev/null
+++ b/test/Preprocessor/hash_space.c
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 %s -E | grep " #"
+
+// Should put a space before the # so that -fpreprocessed mode doesn't
+// macro expand this again.
+#define HASH #
+HASH define foo bar
diff --git a/test/Preprocessor/header_lookup1.c b/test/Preprocessor/header_lookup1.c
new file mode 100644
index 0000000..f93d0af
--- /dev/null
+++ b/test/Preprocessor/header_lookup1.c
@@ -0,0 +1,2 @@
+// RUN: %clang -fno-ms-extensions -I /usr/include %s -E | grep 'stdio.h.*3.*4'
+#include <stdio.h>
diff --git a/test/Preprocessor/if_warning.c b/test/Preprocessor/if_warning.c
new file mode 100644
index 0000000..345ac95
--- /dev/null
+++ b/test/Preprocessor/if_warning.c
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 %s -Eonly -Werror=undef -verify
+// RUN: %clang_cc1 %s -Eonly -Werror-undef -verify
+
+extern int x;
+
+#if foo   // expected-error {{'foo' is not defined, evaluates to 0}}
+#endif
+
+#ifdef foo
+#endif
+
+#if defined(foo)
+#endif
+
+
+// PR3938
+#if 0
+#ifdef D
+#else 1       // Should not warn due to C99 6.10p4
+#endif
+#endif
+
+
+// PR6852
+#if 'somesillylongthing'  // expected-warning {{character constant too long for its type}} \
+                          // expected-warning {{multi-character character constant}}
+#endif
diff --git a/test/Preprocessor/ifdef-recover.c b/test/Preprocessor/ifdef-recover.c
new file mode 100644
index 0000000..51d06d1
--- /dev/null
+++ b/test/Preprocessor/ifdef-recover.c
@@ -0,0 +1,15 @@
+/* RUN: %clang_cc1 -E %s 2>&1 >/dev/null | grep error: | count 3
+ */
+
+#ifdef
+
+#endif
+
+/* End of function-like macro invocation in #ifdef */
+/* PR1936 */
+#define f(x) x
+#if f(2
+#endif
+
+int x;
+
diff --git a/test/Preprocessor/import_self.c b/test/Preprocessor/import_self.c
new file mode 100644
index 0000000..8ba0b19
--- /dev/null
+++ b/test/Preprocessor/import_self.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -E -I. %s | grep BODY_OF_FILE | wc -l | grep 1
+
+// This #import should have no effect, as we're importing the current file.
+#import <import_self.c>
+
+BODY_OF_FILE
+
diff --git a/test/Preprocessor/include-directive1.c b/test/Preprocessor/include-directive1.c
new file mode 100644
index 0000000..20f4582
--- /dev/null
+++ b/test/Preprocessor/include-directive1.c
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -E %s -fno-caret-diagnostics 2>&1 >/dev/null | grep 'file successfully included' | count 3
+
+// XX expands to nothing.
+#define XX
+
+// expand macros to get to file to include
+#define FILE "file_to_include.h"
+#include XX FILE
+
+#include FILE
+
+// normal include
+#include "file_to_include.h"
+
diff --git a/test/Preprocessor/include-directive2.c b/test/Preprocessor/include-directive2.c
new file mode 100644
index 0000000..b205325
--- /dev/null
+++ b/test/Preprocessor/include-directive2.c
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -Eonly -verify %s 
+#  define HEADER <float.h>
+
+#  include HEADER
+
+#include <limits.h> NON_EMPTY // expected-warning {{extra tokens at end of #include directive}}
+
+// PR3916: these are ok.
+#define EMPTY
+#include <limits.h> EMPTY
+#include HEADER  EMPTY
+
+// PR3916
+#define FN limits.h>
+#include <FN
+
+#include <>    // expected-error {{empty filename}}
diff --git a/test/Preprocessor/include-directive3.c b/test/Preprocessor/include-directive3.c
new file mode 100644
index 0000000..c0e2ae1
--- /dev/null
+++ b/test/Preprocessor/include-directive3.c
@@ -0,0 +1,3 @@
+// RUN: %clang_cc1 -include %S/file_to_include.h -E %s -fno-caret-diagnostics 2>&1 >/dev/null | grep 'file successfully included' | count 1
+// PR3464
+
diff --git a/test/Preprocessor/include-macros.c b/test/Preprocessor/include-macros.c
new file mode 100644
index 0000000..b86cd0d
--- /dev/null
+++ b/test/Preprocessor/include-macros.c
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -E -Dtest=FOO -imacros %S/pr2086.h %s | grep 'HERE: test'
+
+// This should not be expanded into FOO because pr2086.h undefs 'test'.
+HERE: test
diff --git a/test/Preprocessor/include-pth.c b/test/Preprocessor/include-pth.c
new file mode 100644
index 0000000..e1d6685
--- /dev/null
+++ b/test/Preprocessor/include-pth.c
@@ -0,0 +1,3 @@
+// RUN: %clang_cc1 -emit-pth %s -o %t
+// RUN: %clang_cc1 -include-pth %t %s -E | grep 'file_to_include' | count 2
+#include "file_to_include.h"
diff --git a/test/Preprocessor/indent_macro.c b/test/Preprocessor/indent_macro.c
new file mode 100644
index 0000000..e695007
--- /dev/null
+++ b/test/Preprocessor/indent_macro.c
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -E %s | grep '^   zzap$'
+
+// zzap is on a new line, should be indented.
+#define BLAH  zzap
+   BLAH
+
diff --git a/test/Preprocessor/init.c b/test/Preprocessor/init.c
new file mode 100644
index 0000000..4ef460b
--- /dev/null
+++ b/test/Preprocessor/init.c
@@ -0,0 +1,1030 @@
+// RUN: %clang_cc1 -E -dM -x assembler-with-cpp < /dev/null | FileCheck -check-prefix ASM %s
+//
+// ASM:#define __ASSEMBLER__ 1
+//
+// 
+// RUN: %clang_cc1 -fblocks -E -dM < /dev/null | FileCheck -check-prefix BLOCKS %s
+//
+// BLOCKS:#define __BLOCKS__ 1
+// BLOCKS:#define __block __attribute__((__blocks__(byref)))
+//
+// 
+// RUN: %clang_cc1 -x c++ -std=c++0x -E -dM < /dev/null | FileCheck -check-prefix CXX0X %s
+//
+// CXX0X:#define __DEPRECATED 1
+// CXX0X:#define __GNUG__
+// CXX0X:#define __GXX_EXPERIMENTAL_CXX0X__ 1
+// CXX0X:#define __GXX_WEAK__ 1
+// CXX0X:#define __cplusplus 199711L
+// CXX0X:#define __private_extern__ extern
+//
+// 
+// RUN: %clang_cc1 -x c++ -std=c++98 -E -dM < /dev/null | FileCheck -check-prefix CXX98 %s
+// 
+// CXX98:#define __DEPRECATED 1
+// CXX98:#define __GNUG__
+// CXX98:#define __GXX_WEAK__ 1
+// CXX98:#define __cplusplus 199711L
+// CXX98:#define __private_extern__ extern
+//
+// 
+// RUN: %clang_cc1 -std=c99 -E -dM < /dev/null | FileCheck -check-prefix C99 %s
+//
+// C99:#define __STDC_VERSION__ 199901L
+// C99:#define __STRICT_ANSI__ 1
+//
+// 
+// RUN: %clang_cc1 -E -dM < /dev/null | FileCheck -check-prefix COMMON %s
+//
+// COMMON:#define __CONSTANT_CFSTRINGS__ 1
+// COMMON:#define __FINITE_MATH_ONLY__ 0
+// COMMON:#define __GNUC_MINOR__
+// COMMON:#define __GNUC_PATCHLEVEL__
+// COMMON:#define __GNUC_STDC_INLINE__ 1
+// COMMON:#define __GNUC__
+// COMMON:#define __GXX_ABI_VERSION
+// COMMON:#define __STDC_HOSTED__ 1
+// COMMON:#define __STDC_VERSION__
+// COMMON:#define __STDC__ 1
+// COMMON:#define __VERSION__
+// COMMON:#define __clang__ 1
+// COMMON:#define __llvm__ 1
+//
+// 
+// RUN: %clang_cc1 -ffreestanding -E -dM < /dev/null | FileCheck -check-prefix FREESTANDING %s
+// FREESTANDING:#define __STDC_HOSTED__ 0
+// 
+// RUN: %clang_cc1 -x c++ -std=gnu++98 -E -dM < /dev/null | FileCheck -check-prefix GXX98 %s
+//
+// GXX98:#define __DEPRECATED 1
+// GXX98:#define __GNUG__
+// GXX98:#define __GXX_WEAK__ 1
+// GXX98:#define __cplusplus 1
+// GXX98:#define __private_extern__ extern
+//
+// 
+// RUN: %clang_cc1 -std=iso9899:199409 -E -dM < /dev/null | FileCheck -check-prefix C94 %s
+//
+// C94:#define __STDC_VERSION__ 199409L
+//
+// 
+// RUN: %clang_cc1 -fms-extensions -E -dM < /dev/null | FileCheck -check-prefix MSEXT %s
+//
+// MSEXT-NOT:#define __STDC__
+// MSEXT:#define __int16 __INT16_TYPE__
+// MSEXT:#define __int32 __INT32_TYPE__
+// MSEXT:#define __int64 __INT64_TYPE__
+// MSEXT:#define __int8 __INT8_TYPE__
+//
+// 
+// RUN: %clang_cc1 -x objective-c -E -dM < /dev/null | FileCheck -check-prefix OBJC %s
+//
+// OBJC:#define OBJC_NEW_PROPERTIES 1
+// OBJC:#define __NEXT_RUNTIME__ 1
+// OBJC:#define __OBJC__ 1
+//
+//
+// RUN: %clang_cc1 -x objective-c -fobjc-gc -E -dM < /dev/null | FileCheck -check-prefix OBJCGC %s
+//
+// OBJCGC:#define __OBJC_GC__ 1
+//
+// 
+// RUN: %clang_cc1 -x objective-c -fobjc-nonfragile-abi -E -dM < /dev/null | FileCheck -check-prefix NONFRAGILE %s
+//
+// NONFRAGILE:#define OBJC_ZEROCOST_EXCEPTIONS 1
+// NONFRAGILE:#define __OBJC2__ 1
+//
+// 
+// RUN: %clang_cc1 -O1 -E -dM < /dev/null | FileCheck -check-prefix O1 %s
+//
+// O1:#define __OPTIMIZE__ 1
+//
+// 
+// RUN: %clang_cc1 -fpascal-strings -E -dM < /dev/null | FileCheck -check-prefix PASCAL %s
+//
+// PASCAL:#define __PASCAL_STRINGS__ 1
+//
+// 
+// RUN: %clang_cc1 -E -dM < /dev/null | FileCheck -check-prefix SCHAR %s
+// 
+// SCHAR:#define __STDC__ 1
+// SCHAR-NOT:#define __UNSIGNED_CHAR__
+// SCHAR:#define __clang__ 1
+//
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=arm-none-none < /dev/null | FileCheck -check-prefix ARM %s
+//
+// ARM:#define __APCS_32__ 1
+// ARM:#define __ARMEL__ 1
+// ARM:#define __ARM_ARCH_6J__ 1
+// ARM:#define __CHAR_BIT__ 8
+// ARM:#define __DBL_DENORM_MIN__ 4.9406564584124654e-324
+// ARM:#define __DBL_DIG__ 15
+// ARM:#define __DBL_EPSILON__ 2.2204460492503131e-16
+// ARM:#define __DBL_HAS_DENORM__ 1
+// ARM:#define __DBL_HAS_INFINITY__ 1
+// ARM:#define __DBL_HAS_QUIET_NAN__ 1
+// ARM:#define __DBL_MANT_DIG__ 53
+// ARM:#define __DBL_MAX_10_EXP__ 308
+// ARM:#define __DBL_MAX_EXP__ 1024
+// ARM:#define __DBL_MAX__ 1.7976931348623157e+308
+// ARM:#define __DBL_MIN_10_EXP__ (-307)
+// ARM:#define __DBL_MIN_EXP__ (-1021)
+// ARM:#define __DBL_MIN__ 2.2250738585072014e-308
+// ARM:#define __DECIMAL_DIG__ 17
+// ARM:#define __FLT_DENORM_MIN__ 1.40129846e-45F
+// ARM:#define __FLT_DIG__ 6
+// ARM:#define __FLT_EPSILON__ 1.19209290e-7F
+// ARM:#define __FLT_EVAL_METHOD__ 0
+// ARM:#define __FLT_HAS_DENORM__ 1
+// ARM:#define __FLT_HAS_INFINITY__ 1
+// ARM:#define __FLT_HAS_QUIET_NAN__ 1
+// ARM:#define __FLT_MANT_DIG__ 24
+// ARM:#define __FLT_MAX_10_EXP__ 38
+// ARM:#define __FLT_MAX_EXP__ 128
+// ARM:#define __FLT_MAX__ 3.40282347e+38F
+// ARM:#define __FLT_MIN_10_EXP__ (-37)
+// ARM:#define __FLT_MIN_EXP__ (-125)
+// ARM:#define __FLT_MIN__ 1.17549435e-38F
+// ARM:#define __FLT_RADIX__ 2
+// ARM:#define __INT16_TYPE__ short
+// ARM:#define __INT32_TYPE__ int
+// ARM:#define __INT64_C_SUFFIX__ LL
+// ARM:#define __INT64_TYPE__ long long int
+// ARM:#define __INT8_TYPE__ char
+// ARM:#define __INTMAX_MAX__ 9223372036854775807LL
+// ARM:#define __INTMAX_TYPE__ long long int
+// ARM:#define __INTMAX_WIDTH__ 64
+// ARM:#define __INTPTR_TYPE__ long int
+// ARM:#define __INTPTR_WIDTH__ 32
+// ARM:#define __INT_MAX__ 2147483647
+// ARM:#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324
+// ARM:#define __LDBL_DIG__ 15
+// ARM:#define __LDBL_EPSILON__ 2.2204460492503131e-16
+// ARM:#define __LDBL_HAS_DENORM__ 1
+// ARM:#define __LDBL_HAS_INFINITY__ 1
+// ARM:#define __LDBL_HAS_QUIET_NAN__ 1
+// ARM:#define __LDBL_MANT_DIG__ 53
+// ARM:#define __LDBL_MAX_10_EXP__ 308
+// ARM:#define __LDBL_MAX_EXP__ 1024
+// ARM:#define __LDBL_MAX__ 1.7976931348623157e+308
+// ARM:#define __LDBL_MIN_10_EXP__ (-307)
+// ARM:#define __LDBL_MIN_EXP__ (-1021)
+// ARM:#define __LDBL_MIN__ 2.2250738585072014e-308
+// ARM:#define __LITTLE_ENDIAN__ 1
+// ARM:#define __LONG_LONG_MAX__ 9223372036854775807LL
+// ARM:#define __LONG_MAX__ 2147483647L
+// ARM:#define __NO_INLINE__ 1
+// ARM:#define __POINTER_WIDTH__ 32
+// ARM:#define __PTRDIFF_TYPE__ int
+// ARM:#define __PTRDIFF_WIDTH__ 32
+// ARM:#define __REGISTER_PREFIX__
+// ARM:#define __SCHAR_MAX__ 127
+// ARM:#define __SHRT_MAX__ 32767
+// ARM:#define __SIG_ATOMIC_WIDTH__ 32
+// ARM:#define __SIZE_TYPE__ unsigned int
+// ARM:#define __SIZE_WIDTH__ 32
+// ARM:#define __THUMB_INTERWORK__ 1
+// ARM:#define __UINTMAX_TYPE__ long long unsigned int
+// ARM:#define __USER_LABEL_PREFIX__ _
+// ARM:#define __WCHAR_MAX__ 2147483647
+// ARM:#define __WCHAR_TYPE__ int
+// ARM:#define __WCHAR_WIDTH__ 32
+// ARM:#define __WINT_TYPE__ int
+// ARM:#define __WINT_WIDTH__ 32
+// ARM:#define __arm 1
+// ARM:#define __arm__ 1
+//
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=bfin-none-none < /dev/null | FileCheck -check-prefix BFIN %s
+//
+// BFIN:#define BFIN 1
+// BFIN:#define __ADSPBLACKFIN__ 1
+// BFIN:#define __ADSPLPBLACKFIN__ 1
+// BFIN:#define __BFIN 1
+// BFIN:#define __BFIN__ 1
+// BFIN:#define __CHAR_BIT__ 8
+// BFIN:#define __DBL_DENORM_MIN__ 4.9406564584124654e-324
+// BFIN:#define __DBL_DIG__ 15
+// BFIN:#define __DBL_EPSILON__ 2.2204460492503131e-16
+// BFIN:#define __DBL_HAS_DENORM__ 1
+// BFIN:#define __DBL_HAS_INFINITY__ 1
+// BFIN:#define __DBL_HAS_QUIET_NAN__ 1
+// BFIN:#define __DBL_MANT_DIG__ 53
+// BFIN:#define __DBL_MAX_10_EXP__ 308
+// BFIN:#define __DBL_MAX_EXP__ 1024
+// BFIN:#define __DBL_MAX__ 1.7976931348623157e+308
+// BFIN:#define __DBL_MIN_10_EXP__ (-307)
+// BFIN:#define __DBL_MIN_EXP__ (-1021)
+// BFIN:#define __DBL_MIN__ 2.2250738585072014e-308
+// BFIN:#define __DECIMAL_DIG__ 17
+// BFIN:#define __FLT_DENORM_MIN__ 1.40129846e-45F
+// BFIN:#define __FLT_DIG__ 6
+// BFIN:#define __FLT_EPSILON__ 1.19209290e-7F
+// BFIN:#define __FLT_EVAL_METHOD__ 0
+// BFIN:#define __FLT_HAS_DENORM__ 1
+// BFIN:#define __FLT_HAS_INFINITY__ 1
+// BFIN:#define __FLT_HAS_QUIET_NAN__ 1
+// BFIN:#define __FLT_MANT_DIG__ 24
+// BFIN:#define __FLT_MAX_10_EXP__ 38
+// BFIN:#define __FLT_MAX_EXP__ 128
+// BFIN:#define __FLT_MAX__ 3.40282347e+38F
+// BFIN:#define __FLT_MIN_10_EXP__ (-37)
+// BFIN:#define __FLT_MIN_EXP__ (-125)
+// BFIN:#define __FLT_MIN__ 1.17549435e-38F
+// BFIN:#define __FLT_RADIX__ 2
+// BFIN:#define __INT16_TYPE__ short
+// BFIN:#define __INT32_TYPE__ int
+// BFIN:#define __INT64_C_SUFFIX__ LL
+// BFIN:#define __INT64_TYPE__ long long int
+// BFIN:#define __INT8_TYPE__ char
+// BFIN:#define __INTMAX_MAX__ 9223372036854775807LL
+// BFIN:#define __INTMAX_TYPE__ long long int
+// BFIN:#define __INTMAX_WIDTH__ 64
+// BFIN:#define __INTPTR_TYPE__ long int
+// BFIN:#define __INTPTR_WIDTH__ 32
+// BFIN:#define __INT_MAX__ 2147483647
+// BFIN:#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324
+// BFIN:#define __LDBL_DIG__ 15
+// BFIN:#define __LDBL_EPSILON__ 2.2204460492503131e-16
+// BFIN:#define __LDBL_HAS_DENORM__ 1
+// BFIN:#define __LDBL_HAS_INFINITY__ 1
+// BFIN:#define __LDBL_HAS_QUIET_NAN__ 1
+// BFIN:#define __LDBL_MANT_DIG__ 53
+// BFIN:#define __LDBL_MAX_10_EXP__ 308
+// BFIN:#define __LDBL_MAX_EXP__ 1024
+// BFIN:#define __LDBL_MAX__ 1.7976931348623157e+308
+// BFIN:#define __LDBL_MIN_10_EXP__ (-307)
+// BFIN:#define __LDBL_MIN_EXP__ (-1021)
+// BFIN:#define __LDBL_MIN__ 2.2250738585072014e-308
+// BFIN:#define __LONG_LONG_MAX__ 9223372036854775807LL
+// BFIN:#define __LONG_MAX__ 2147483647L
+// BFIN:#define __NO_INLINE__ 1
+// BFIN:#define __POINTER_WIDTH__ 32
+// BFIN:#define __PTRDIFF_TYPE__ long int
+// BFIN:#define __PTRDIFF_WIDTH__ 32
+// BFIN:#define __SCHAR_MAX__ 127
+// BFIN:#define __SHRT_MAX__ 32767
+// BFIN:#define __SIG_ATOMIC_WIDTH__ 32
+// BFIN:#define __SIZE_TYPE__ long unsigned int
+// BFIN:#define __SIZE_WIDTH__ 32
+// BFIN:#define __UINTMAX_TYPE__ long long unsigned int
+// BFIN:#define __USER_LABEL_PREFIX__ _
+// BFIN:#define __WCHAR_MAX__ 2147483647
+// BFIN:#define __WCHAR_TYPE__ int
+// BFIN:#define __WCHAR_WIDTH__ 32
+// BFIN:#define __WINT_TYPE__ int
+// BFIN:#define __WINT_WIDTH__ 32
+// BFIN:#define __bfin 1
+// BFIN:#define __bfin__ 1
+// BFIN:#define bfin 1
+//
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=i386-none-none < /dev/null | FileCheck -check-prefix I386 %s
+//
+// I386:#define __CHAR_BIT__ 8
+// I386:#define __DBL_DENORM_MIN__ 4.9406564584124654e-324
+// I386:#define __DBL_DIG__ 15
+// I386:#define __DBL_EPSILON__ 2.2204460492503131e-16
+// I386:#define __DBL_HAS_DENORM__ 1
+// I386:#define __DBL_HAS_INFINITY__ 1
+// I386:#define __DBL_HAS_QUIET_NAN__ 1
+// I386:#define __DBL_MANT_DIG__ 53
+// I386:#define __DBL_MAX_10_EXP__ 308
+// I386:#define __DBL_MAX_EXP__ 1024
+// I386:#define __DBL_MAX__ 1.7976931348623157e+308
+// I386:#define __DBL_MIN_10_EXP__ (-307)
+// I386:#define __DBL_MIN_EXP__ (-1021)
+// I386:#define __DBL_MIN__ 2.2250738585072014e-308
+// I386:#define __DECIMAL_DIG__ 21
+// I386:#define __FLT_DENORM_MIN__ 1.40129846e-45F
+// I386:#define __FLT_DIG__ 6
+// I386:#define __FLT_EPSILON__ 1.19209290e-7F
+// I386:#define __FLT_EVAL_METHOD__ 0
+// I386:#define __FLT_HAS_DENORM__ 1
+// I386:#define __FLT_HAS_INFINITY__ 1
+// I386:#define __FLT_HAS_QUIET_NAN__ 1
+// I386:#define __FLT_MANT_DIG__ 24
+// I386:#define __FLT_MAX_10_EXP__ 38
+// I386:#define __FLT_MAX_EXP__ 128
+// I386:#define __FLT_MAX__ 3.40282347e+38F
+// I386:#define __FLT_MIN_10_EXP__ (-37)
+// I386:#define __FLT_MIN_EXP__ (-125)
+// I386:#define __FLT_MIN__ 1.17549435e-38F
+// I386:#define __FLT_RADIX__ 2
+// I386:#define __INT16_TYPE__ short
+// I386:#define __INT32_TYPE__ int
+// I386:#define __INT64_C_SUFFIX__ LL
+// I386:#define __INT64_TYPE__ long long int
+// I386:#define __INT8_TYPE__ char
+// I386:#define __INTMAX_MAX__ 9223372036854775807LL
+// I386:#define __INTMAX_TYPE__ long long int
+// I386:#define __INTMAX_WIDTH__ 64
+// I386:#define __INTPTR_TYPE__ int
+// I386:#define __INTPTR_WIDTH__ 32
+// I386:#define __INT_MAX__ 2147483647
+// I386:#define __LDBL_DENORM_MIN__ 3.64519953188247460253e-4951L
+// I386:#define __LDBL_DIG__ 18
+// I386:#define __LDBL_EPSILON__ 1.08420217248550443401e-19L
+// I386:#define __LDBL_HAS_DENORM__ 1
+// I386:#define __LDBL_HAS_INFINITY__ 1
+// I386:#define __LDBL_HAS_QUIET_NAN__ 1
+// I386:#define __LDBL_MANT_DIG__ 64
+// I386:#define __LDBL_MAX_10_EXP__ 4932
+// I386:#define __LDBL_MAX_EXP__ 16384
+// I386:#define __LDBL_MAX__ 1.18973149535723176502e+4932L
+// I386:#define __LDBL_MIN_10_EXP__ (-4931)
+// I386:#define __LDBL_MIN_EXP__ (-16381)
+// I386:#define __LDBL_MIN__ 3.36210314311209350626e-4932L
+// I386:#define __LITTLE_ENDIAN__ 1
+// I386:#define __LONG_LONG_MAX__ 9223372036854775807LL
+// I386:#define __LONG_MAX__ 2147483647L
+// I386:#define __NO_INLINE__ 1
+// I386:#define __NO_MATH_INLINES 1
+// I386:#define __POINTER_WIDTH__ 32
+// I386:#define __PTRDIFF_TYPE__ int
+// I386:#define __PTRDIFF_WIDTH__ 32
+// I386:#define __REGISTER_PREFIX__ 
+// I386:#define __SCHAR_MAX__ 127
+// I386:#define __SHRT_MAX__ 32767
+// I386:#define __SIG_ATOMIC_WIDTH__ 32
+// I386:#define __SIZE_TYPE__ unsigned int
+// I386:#define __SIZE_WIDTH__ 32
+// I386:#define __UINTMAX_TYPE__ long long unsigned int
+// I386:#define __USER_LABEL_PREFIX__ _
+// I386:#define __WCHAR_MAX__ 2147483647
+// I386:#define __WCHAR_TYPE__ int
+// I386:#define __WCHAR_WIDTH__ 32
+// I386:#define __WINT_TYPE__ int
+// I386:#define __WINT_WIDTH__ 32
+// I386:#define __i386 1
+// I386:#define __i386__ 1
+// I386:#define __nocona 1
+// I386:#define __nocona__ 1
+// I386:#define __tune_nocona__ 1
+// I386:#define i386 1
+//
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=msp430-none-none < /dev/null | FileCheck -check-prefix MSP430 %s
+//
+// MSP430:#define MSP430 1
+// MSP430:#define __CHAR_BIT__ 8
+// MSP430:#define __DBL_DENORM_MIN__ 4.9406564584124654e-324
+// MSP430:#define __DBL_DIG__ 15
+// MSP430:#define __DBL_EPSILON__ 2.2204460492503131e-16
+// MSP430:#define __DBL_HAS_DENORM__ 1
+// MSP430:#define __DBL_HAS_INFINITY__ 1
+// MSP430:#define __DBL_HAS_QUIET_NAN__ 1
+// MSP430:#define __DBL_MANT_DIG__ 53
+// MSP430:#define __DBL_MAX_10_EXP__ 308
+// MSP430:#define __DBL_MAX_EXP__ 1024
+// MSP430:#define __DBL_MAX__ 1.7976931348623157e+308
+// MSP430:#define __DBL_MIN_10_EXP__ (-307)
+// MSP430:#define __DBL_MIN_EXP__ (-1021)
+// MSP430:#define __DBL_MIN__ 2.2250738585072014e-308
+// MSP430:#define __DECIMAL_DIG__ 17
+// MSP430:#define __FLT_DENORM_MIN__ 1.40129846e-45F
+// MSP430:#define __FLT_DIG__ 6
+// MSP430:#define __FLT_EPSILON__ 1.19209290e-7F
+// MSP430:#define __FLT_EVAL_METHOD__ 0
+// MSP430:#define __FLT_HAS_DENORM__ 1
+// MSP430:#define __FLT_HAS_INFINITY__ 1
+// MSP430:#define __FLT_HAS_QUIET_NAN__ 1
+// MSP430:#define __FLT_MANT_DIG__ 24
+// MSP430:#define __FLT_MAX_10_EXP__ 38
+// MSP430:#define __FLT_MAX_EXP__ 128
+// MSP430:#define __FLT_MAX__ 3.40282347e+38F
+// MSP430:#define __FLT_MIN_10_EXP__ (-37)
+// MSP430:#define __FLT_MIN_EXP__ (-125)
+// MSP430:#define __FLT_MIN__ 1.17549435e-38F
+// MSP430:#define __FLT_RADIX__ 2
+// MSP430:#define __INT16_TYPE__ short
+// MSP430:#define __INT32_C_SUFFIX__ L
+// MSP430:#define __INT32_TYPE__ long int
+// MSP430:#define __INT8_TYPE__ char
+// MSP430:#define __INTMAX_MAX__ 2147483647L
+// MSP430:#define __INTMAX_TYPE__ long int
+// MSP430:#define __INTMAX_WIDTH__ 32
+// MSP430:#define __INTPTR_TYPE__ short
+// MSP430:#define __INTPTR_WIDTH__ 16
+// MSP430:#define __INT_MAX__ 32767
+// MSP430:#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324
+// MSP430:#define __LDBL_DIG__ 15
+// MSP430:#define __LDBL_EPSILON__ 2.2204460492503131e-16
+// MSP430:#define __LDBL_HAS_DENORM__ 1
+// MSP430:#define __LDBL_HAS_INFINITY__ 1
+// MSP430:#define __LDBL_HAS_QUIET_NAN__ 1
+// MSP430:#define __LDBL_MANT_DIG__ 53
+// MSP430:#define __LDBL_MAX_10_EXP__ 308
+// MSP430:#define __LDBL_MAX_EXP__ 1024
+// MSP430:#define __LDBL_MAX__ 1.7976931348623157e+308
+// MSP430:#define __LDBL_MIN_10_EXP__ (-307)
+// MSP430:#define __LDBL_MIN_EXP__ (-1021)
+// MSP430:#define __LDBL_MIN__ 2.2250738585072014e-308
+// MSP430:#define __LONG_LONG_MAX__ 9223372036854775807LL
+// MSP430:#define __LONG_MAX__ 2147483647L
+// MSP430:#define __MSP430__ 1
+// MSP430:#define __NO_INLINE__ 1
+// MSP430:#define __POINTER_WIDTH__ 16
+// MSP430:#define __PTRDIFF_TYPE__ int
+// MSP430:#define __PTRDIFF_WIDTH__ 16 
+// MSP430:#define __SCHAR_MAX__ 127
+// MSP430:#define __SHRT_MAX__ 32767
+// MSP430:#define __SIG_ATOMIC_WIDTH__ 32
+// MSP430:#define __SIZE_TYPE__ unsigned int
+// MSP430:#define __SIZE_WIDTH__ 16
+// MSP430:#define __UINTMAX_TYPE__ long unsigned int
+// MSP430:#define __USER_LABEL_PREFIX__ _
+// MSP430:#define __WCHAR_MAX__ 32767
+// MSP430:#define __WCHAR_TYPE__ int
+// MSP430:#define __WCHAR_WIDTH__ 16
+// MSP430:#define __WINT_TYPE__ int
+// MSP430:#define __WINT_WIDTH__ 16
+// MSP430:#define __clang__ 1
+//
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=pic16-none-none < /dev/null | FileCheck -check-prefix PIC16 %s
+//
+// PIC16:#define __CHAR_BIT__ 8
+// PIC16:#define __DBL_DENORM_MIN__ 1.40129846e-45F
+// PIC16:#define __DBL_DIG__ 6
+// PIC16:#define __DBL_EPSILON__ 1.19209290e-7F
+// PIC16:#define __DBL_HAS_DENORM__ 1
+// PIC16:#define __DBL_HAS_INFINITY__ 1
+// PIC16:#define __DBL_HAS_QUIET_NAN__ 1
+// PIC16:#define __DBL_MANT_DIG__ 24
+// PIC16:#define __DBL_MAX_10_EXP__ 38
+// PIC16:#define __DBL_MAX_EXP__ 128
+// PIC16:#define __DBL_MAX__ 3.40282347e+38F
+// PIC16:#define __DBL_MIN_10_EXP__ (-37)
+// PIC16:#define __DBL_MIN_EXP__ (-125)
+// PIC16:#define __DBL_MIN__ 1.17549435e-38F
+// PIC16:#define __DECIMAL_DIG__ -1
+// PIC16:#define __FLT_DENORM_MIN__ 1.40129846e-45F
+// PIC16:#define __FLT_DIG__ 6
+// PIC16:#define __FLT_EPSILON__ 1.19209290e-7F
+// PIC16:#define __FLT_EVAL_METHOD__ 0
+// PIC16:#define __FLT_HAS_DENORM__ 1
+// PIC16:#define __FLT_HAS_INFINITY__ 1
+// PIC16:#define __FLT_HAS_QUIET_NAN__ 1
+// PIC16:#define __FLT_MANT_DIG__ 24
+// PIC16:#define __FLT_MAX_10_EXP__ 38
+// PIC16:#define __FLT_MAX_EXP__ 128
+// PIC16:#define __FLT_MAX__ 3.40282347e+38F
+// PIC16:#define __FLT_MIN_10_EXP__ (-37)
+// PIC16:#define __FLT_MIN_EXP__ (-125)
+// PIC16:#define __FLT_MIN__ 1.17549435e-38F
+// PIC16:#define __FLT_RADIX__ 2
+// PIC16:#define __INT16_TYPE__ short
+// PIC16:#define __INT32_C_SUFFIX__ L
+// PIC16:#define __INT32_TYPE__ long int
+// PIC16:#define __INT8_TYPE__ char
+// PIC16:#define __INTMAX_MAX__ 2147483647L
+// PIC16:#define __INTMAX_TYPE__ long int
+// PIC16:#define __INTMAX_WIDTH__ 32
+// PIC16:#define __INTPTR_TYPE__ short
+// PIC16:#define __INTPTR_WIDTH__ 16
+// PIC16:#define __INT_MAX__ 32767
+// PIC16:#define __LDBL_DENORM_MIN__ 1.40129846e-45F
+// PIC16:#define __LDBL_DIG__ 6
+// PIC16:#define __LDBL_EPSILON__ 1.19209290e-7F
+// PIC16:#define __LDBL_HAS_DENORM__ 1
+// PIC16:#define __LDBL_HAS_INFINITY__ 1
+// PIC16:#define __LDBL_HAS_QUIET_NAN__ 1
+// PIC16:#define __LDBL_MANT_DIG__ 24
+// PIC16:#define __LDBL_MAX_10_EXP__ 38
+// PIC16:#define __LDBL_MAX_EXP__ 128
+// PIC16:#define __LDBL_MAX__ 3.40282347e+38F
+// PIC16:#define __LDBL_MIN_10_EXP__ (-37)
+// PIC16:#define __LDBL_MIN_EXP__ (-125)
+// PIC16:#define __LDBL_MIN__ 1.17549435e-38F
+// PIC16:#define __LONG_LONG_MAX__ 2147483647LL
+// PIC16:#define __LONG_MAX__ 2147483647L
+// PIC16:#define __NO_INLINE__ 1
+// PIC16:#define __PIC16 1
+// PIC16:#define __POINTER_WIDTH__ 16
+// PIC16:#define __PTRDIFF_TYPE__ int
+// PIC16:#define __PTRDIFF_WIDTH__ 16
+// PIC16:#define __SCHAR_MAX__ 127
+// PIC16:#define __SHRT_MAX__ 32767
+// PIC16:#define __SIG_ATOMIC_WIDTH__ 32
+// PIC16:#define __SIZE_TYPE__ unsigned int
+// PIC16:#define __SIZE_WIDTH__ 16
+// PIC16:#define __UINTMAX_TYPE__ long unsigned int
+// PIC16:#define __USER_LABEL_PREFIX__ _
+// PIC16:#define __WCHAR_MAX__ 32767
+// PIC16:#define __WCHAR_TYPE__ int
+// PIC16:#define __WCHAR_WIDTH__ 16
+// PIC16:#define __WINT_TYPE__ int
+// PIC16:#define __WINT_WIDTH__ 16
+// PIC16:#define __address(Addr) __attribute__((section("Address="#Addr)))
+// PIC16:#define __clang__ 1
+// PIC16:#define __config(conf) asm("CONFIG "#conf)
+// PIC16:#define __idlocs(value) asm("__IDLOCS "#value)
+// PIC16:#define __llvm__ 1
+// PIC16:#define __pic16 1
+// PIC16:#define __section(SectName) __attribute__((section(SectName)))
+// PIC16:#define interrupt __attribute__((section("interrupt=0x4"))) __attribute__((used))
+// PIC16:#define near __attribute__((section("Address=NEAR")))
+// PIC16:#define ram __attribute__((address_space(0)))
+// PIC16:#define rom __attribute__((address_space(1)))
+//
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-none-none -fno-signed-char < /dev/null | FileCheck -check-prefix PPC64 %s
+//
+// PPC64:#define _ARCH_PPC 1
+// PPC64:#define _ARCH_PPC64 1
+// PPC64:#define _BIG_ENDIAN 1
+// PPC64:#define _LP64 1
+// PPC64:#define __BIG_ENDIAN__ 1
+// PPC64:#define __CHAR_BIT__ 8
+// PPC64:#define __CHAR_UNSIGNED__ 1
+// PPC64:#define __DBL_DENORM_MIN__ 4.9406564584124654e-324
+// PPC64:#define __DBL_DIG__ 15
+// PPC64:#define __DBL_EPSILON__ 2.2204460492503131e-16
+// PPC64:#define __DBL_HAS_DENORM__ 1
+// PPC64:#define __DBL_HAS_INFINITY__ 1
+// PPC64:#define __DBL_HAS_QUIET_NAN__ 1
+// PPC64:#define __DBL_MANT_DIG__ 53
+// PPC64:#define __DBL_MAX_10_EXP__ 308
+// PPC64:#define __DBL_MAX_EXP__ 1024
+// PPC64:#define __DBL_MAX__ 1.7976931348623157e+308
+// PPC64:#define __DBL_MIN_10_EXP__ (-307)
+// PPC64:#define __DBL_MIN_EXP__ (-1021)
+// PPC64:#define __DBL_MIN__ 2.2250738585072014e-308
+// PPC64:#define __DECIMAL_DIG__ 17
+// PPC64:#define __FLT_DENORM_MIN__ 1.40129846e-45F
+// PPC64:#define __FLT_DIG__ 6
+// PPC64:#define __FLT_EPSILON__ 1.19209290e-7F
+// PPC64:#define __FLT_EVAL_METHOD__ 0
+// PPC64:#define __FLT_HAS_DENORM__ 1
+// PPC64:#define __FLT_HAS_INFINITY__ 1
+// PPC64:#define __FLT_HAS_QUIET_NAN__ 1
+// PPC64:#define __FLT_MANT_DIG__ 24
+// PPC64:#define __FLT_MAX_10_EXP__ 38
+// PPC64:#define __FLT_MAX_EXP__ 128
+// PPC64:#define __FLT_MAX__ 3.40282347e+38F
+// PPC64:#define __FLT_MIN_10_EXP__ (-37)
+// PPC64:#define __FLT_MIN_EXP__ (-125)
+// PPC64:#define __FLT_MIN__ 1.17549435e-38F
+// PPC64:#define __FLT_RADIX__ 2
+// PPC64:#define __INT16_TYPE__ short
+// PPC64:#define __INT32_TYPE__ int
+// PPC64:#define __INT64_C_SUFFIX__ L
+// PPC64:#define __INT64_TYPE__ long int
+// PPC64:#define __INT8_TYPE__ char
+// PPC64:#define __INTMAX_MAX__ 9223372036854775807L
+// PPC64:#define __INTMAX_TYPE__ long int
+// PPC64:#define __INTMAX_WIDTH__ 64
+// PPC64:#define __INTPTR_TYPE__ long int
+// PPC64:#define __INTPTR_WIDTH__ 64
+// PPC64:#define __INT_MAX__ 2147483647
+// PPC64:#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324
+// PPC64:#define __LDBL_DIG__ 15
+// PPC64:#define __LDBL_EPSILON__ 2.2204460492503131e-16
+// PPC64:#define __LDBL_HAS_DENORM__ 1
+// PPC64:#define __LDBL_HAS_INFINITY__ 1
+// PPC64:#define __LDBL_HAS_QUIET_NAN__ 1
+// PPC64:#define __LDBL_MANT_DIG__ 53
+// PPC64:#define __LDBL_MAX_10_EXP__ 308
+// PPC64:#define __LDBL_MAX_EXP__ 1024
+// PPC64:#define __LDBL_MAX__ 1.7976931348623157e+308
+// PPC64:#define __LDBL_MIN_10_EXP__ (-307)
+// PPC64:#define __LDBL_MIN_EXP__ (-1021)
+// PPC64:#define __LDBL_MIN__ 2.2250738585072014e-308
+// PPC64:#define __LONG_DOUBLE_128__ 1
+// PPC64:#define __LONG_LONG_MAX__ 9223372036854775807LL
+// PPC64:#define __LONG_MAX__ 9223372036854775807L
+// PPC64:#define __LP64__ 1
+// PPC64:#define __NATURAL_ALIGNMENT__ 1
+// PPC64:#define __NO_INLINE__ 1
+// PPC64:#define __POINTER_WIDTH__ 64
+// PPC64:#define __POWERPC__ 1
+// PPC64:#define __PTRDIFF_TYPE__ long int
+// PPC64:#define __PTRDIFF_WIDTH__ 64
+// PPC64:#define __REGISTER_PREFIX__ 
+// PPC64:#define __SCHAR_MAX__ 127
+// PPC64:#define __SHRT_MAX__ 32767
+// PPC64:#define __SIG_ATOMIC_WIDTH__ 32
+// PPC64:#define __SIZE_TYPE__ long unsigned int
+// PPC64:#define __SIZE_WIDTH__ 64
+// PPC64:#define __UINTMAX_TYPE__ long unsigned int
+// PPC64:#define __USER_LABEL_PREFIX__ _
+// PPC64:#define __WCHAR_MAX__ 2147483647
+// PPC64:#define __WCHAR_TYPE__ int
+// PPC64:#define __WCHAR_WIDTH__ 32
+// PPC64:#define __WINT_TYPE__ int
+// PPC64:#define __WINT_WIDTH__ 32
+// PPC64:#define __ppc64__ 1
+// PPC64:#define __ppc__ 1
+//
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc-none-none -fno-signed-char < /dev/null | FileCheck -check-prefix PPC %s
+//
+// PPC:#define _ARCH_PPC 1
+// PPC:#define _BIG_ENDIAN 1
+// PPC:#define __BIG_ENDIAN__ 1
+// PPC:#define __CHAR_BIT__ 8
+// PPC:#define __CHAR_UNSIGNED__ 1
+// PPC:#define __DBL_DENORM_MIN__ 4.9406564584124654e-324
+// PPC:#define __DBL_DIG__ 15
+// PPC:#define __DBL_EPSILON__ 2.2204460492503131e-16
+// PPC:#define __DBL_HAS_DENORM__ 1
+// PPC:#define __DBL_HAS_INFINITY__ 1
+// PPC:#define __DBL_HAS_QUIET_NAN__ 1
+// PPC:#define __DBL_MANT_DIG__ 53
+// PPC:#define __DBL_MAX_10_EXP__ 308
+// PPC:#define __DBL_MAX_EXP__ 1024
+// PPC:#define __DBL_MAX__ 1.7976931348623157e+308
+// PPC:#define __DBL_MIN_10_EXP__ (-307)
+// PPC:#define __DBL_MIN_EXP__ (-1021)
+// PPC:#define __DBL_MIN__ 2.2250738585072014e-308
+// PPC:#define __DECIMAL_DIG__ 17
+// PPC:#define __FLT_DENORM_MIN__ 1.40129846e-45F
+// PPC:#define __FLT_DIG__ 6
+// PPC:#define __FLT_EPSILON__ 1.19209290e-7F
+// PPC:#define __FLT_EVAL_METHOD__ 0
+// PPC:#define __FLT_HAS_DENORM__ 1
+// PPC:#define __FLT_HAS_INFINITY__ 1
+// PPC:#define __FLT_HAS_QUIET_NAN__ 1
+// PPC:#define __FLT_MANT_DIG__ 24
+// PPC:#define __FLT_MAX_10_EXP__ 38
+// PPC:#define __FLT_MAX_EXP__ 128
+// PPC:#define __FLT_MAX__ 3.40282347e+38F
+// PPC:#define __FLT_MIN_10_EXP__ (-37)
+// PPC:#define __FLT_MIN_EXP__ (-125)
+// PPC:#define __FLT_MIN__ 1.17549435e-38F
+// PPC:#define __FLT_RADIX__ 2
+// PPC:#define __INT16_TYPE__ short
+// PPC:#define __INT32_TYPE__ int
+// PPC:#define __INT64_C_SUFFIX__ LL
+// PPC:#define __INT64_TYPE__ long long int
+// PPC:#define __INT8_TYPE__ char
+// PPC:#define __INTMAX_MAX__ 9223372036854775807LL
+// PPC:#define __INTMAX_TYPE__ long long int
+// PPC:#define __INTMAX_WIDTH__ 64
+// PPC:#define __INTPTR_TYPE__ long int
+// PPC:#define __INTPTR_WIDTH__ 32
+// PPC:#define __INT_MAX__ 2147483647
+// PPC:#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324
+// PPC:#define __LDBL_DIG__ 15
+// PPC:#define __LDBL_EPSILON__ 2.2204460492503131e-16
+// PPC:#define __LDBL_HAS_DENORM__ 1
+// PPC:#define __LDBL_HAS_INFINITY__ 1
+// PPC:#define __LDBL_HAS_QUIET_NAN__ 1
+// PPC:#define __LDBL_MANT_DIG__ 53
+// PPC:#define __LDBL_MAX_10_EXP__ 308
+// PPC:#define __LDBL_MAX_EXP__ 1024
+// PPC:#define __LDBL_MAX__ 1.7976931348623157e+308
+// PPC:#define __LDBL_MIN_10_EXP__ (-307)
+// PPC:#define __LDBL_MIN_EXP__ (-1021)
+// PPC:#define __LDBL_MIN__ 2.2250738585072014e-308
+// PPC:#define __LONG_DOUBLE_128__ 1
+// PPC:#define __LONG_LONG_MAX__ 9223372036854775807LL
+// PPC:#define __LONG_MAX__ 2147483647L
+// PPC:#define __NATURAL_ALIGNMENT__ 1
+// PPC:#define __NO_INLINE__ 1
+// PPC:#define __POINTER_WIDTH__ 32
+// PPC:#define __POWERPC__ 1
+// PPC:#define __PTRDIFF_TYPE__ long int
+// PPC:#define __PTRDIFF_WIDTH__ 32
+// PPC:#define __REGISTER_PREFIX__ 
+// PPC:#define __SCHAR_MAX__ 127
+// PPC:#define __SHRT_MAX__ 32767
+// PPC:#define __SIG_ATOMIC_WIDTH__ 32
+// PPC:#define __SIZE_TYPE__ long unsigned int
+// PPC:#define __SIZE_WIDTH__ 32
+// PPC:#define __UINTMAX_TYPE__ long long unsigned int
+// PPC:#define __USER_LABEL_PREFIX__ _
+// PPC:#define __WCHAR_MAX__ 2147483647
+// PPC:#define __WCHAR_TYPE__ int
+// PPC:#define __WCHAR_WIDTH__ 32
+// PPC:#define __WINT_TYPE__ int
+// PPC:#define __WINT_WIDTH__ 32
+// PPC:#define __ppc__ 1
+//
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=s390x-none-none -fno-signed-char < /dev/null | FileCheck -check-prefix S390X %s
+//
+// S390X:#define __CHAR_BIT__ 8
+// S390X:#define __CHAR_UNSIGNED__ 1
+// S390X:#define __DBL_DENORM_MIN__ 4.9406564584124654e-324
+// S390X:#define __DBL_DIG__ 15
+// S390X:#define __DBL_EPSILON__ 2.2204460492503131e-16
+// S390X:#define __DBL_HAS_DENORM__ 1
+// S390X:#define __DBL_HAS_INFINITY__ 1
+// S390X:#define __DBL_HAS_QUIET_NAN__ 1
+// S390X:#define __DBL_MANT_DIG__ 53
+// S390X:#define __DBL_MAX_10_EXP__ 308
+// S390X:#define __DBL_MAX_EXP__ 1024
+// S390X:#define __DBL_MAX__ 1.7976931348623157e+308
+// S390X:#define __DBL_MIN_10_EXP__ (-307)
+// S390X:#define __DBL_MIN_EXP__ (-1021)
+// S390X:#define __DBL_MIN__ 2.2250738585072014e-308
+// S390X:#define __DECIMAL_DIG__ 17
+// S390X:#define __FLT_DENORM_MIN__ 1.40129846e-45F
+// S390X:#define __FLT_DIG__ 6
+// S390X:#define __FLT_EPSILON__ 1.19209290e-7F
+// S390X:#define __FLT_EVAL_METHOD__ 0
+// S390X:#define __FLT_HAS_DENORM__ 1
+// S390X:#define __FLT_HAS_INFINITY__ 1
+// S390X:#define __FLT_HAS_QUIET_NAN__ 1
+// S390X:#define __FLT_MANT_DIG__ 24
+// S390X:#define __FLT_MAX_10_EXP__ 38
+// S390X:#define __FLT_MAX_EXP__ 128
+// S390X:#define __FLT_MAX__ 3.40282347e+38F
+// S390X:#define __FLT_MIN_10_EXP__ (-37)
+// S390X:#define __FLT_MIN_EXP__ (-125)
+// S390X:#define __FLT_MIN__ 1.17549435e-38F
+// S390X:#define __FLT_RADIX__ 2
+// S390X:#define __INT16_TYPE__ short
+// S390X:#define __INT32_TYPE__ int
+// S390X:#define __INT64_C_SUFFIX__ L
+// S390X:#define __INT64_TYPE__ long int
+// S390X:#define __INT8_TYPE__ char
+// S390X:#define __INTMAX_MAX__ 9223372036854775807LL
+// S390X:#define __INTMAX_TYPE__ long long int
+// S390X:#define __INTMAX_WIDTH__ 64
+// S390X:#define __INTPTR_TYPE__ long int
+// S390X:#define __INTPTR_WIDTH__ 64
+// S390X:#define __INT_MAX__ 2147483647
+// S390X:#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324
+// S390X:#define __LDBL_DIG__ 15
+// S390X:#define __LDBL_EPSILON__ 2.2204460492503131e-16
+// S390X:#define __LDBL_HAS_DENORM__ 1
+// S390X:#define __LDBL_HAS_INFINITY__ 1
+// S390X:#define __LDBL_HAS_QUIET_NAN__ 1
+// S390X:#define __LDBL_MANT_DIG__ 53
+// S390X:#define __LDBL_MAX_10_EXP__ 308
+// S390X:#define __LDBL_MAX_EXP__ 1024
+// S390X:#define __LDBL_MAX__ 1.7976931348623157e+308
+// S390X:#define __LDBL_MIN_10_EXP__ (-307)
+// S390X:#define __LDBL_MIN_EXP__ (-1021)
+// S390X:#define __LDBL_MIN__ 2.2250738585072014e-308
+// S390X:#define __LONG_LONG_MAX__ 9223372036854775807LL
+// S390X:#define __LONG_MAX__ 9223372036854775807L
+// S390X:#define __NO_INLINE__ 1
+// S390X:#define __POINTER_WIDTH__ 64
+// S390X:#define __PTRDIFF_TYPE__ long int
+// S390X:#define __PTRDIFF_WIDTH__ 64
+// S390X:#define __SCHAR_MAX__ 127
+// S390X:#define __SHRT_MAX__ 32767
+// S390X:#define __SIG_ATOMIC_WIDTH__ 32
+// S390X:#define __SIZE_TYPE__ long unsigned int
+// S390X:#define __SIZE_WIDTH__ 64
+// S390X:#define __UINTMAX_TYPE__ long long unsigned int
+// S390X:#define __USER_LABEL_PREFIX__ _
+// S390X:#define __WCHAR_MAX__ 2147483647
+// S390X:#define __WCHAR_TYPE__ int
+// S390X:#define __WCHAR_WIDTH__ 32
+// S390X:#define __WINT_TYPE__ int
+// S390X:#define __WINT_WIDTH__ 32
+// S390X:#define __s390__ 1
+// S390X:#define __s390x__ 1
+//
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=sparc-none-none < /dev/null | FileCheck -check-prefix SPARC %s
+//
+// SPARC:#define __CHAR_BIT__ 8
+// SPARC:#define __DBL_DENORM_MIN__ 4.9406564584124654e-324
+// SPARC:#define __DBL_DIG__ 15
+// SPARC:#define __DBL_EPSILON__ 2.2204460492503131e-16
+// SPARC:#define __DBL_HAS_DENORM__ 1
+// SPARC:#define __DBL_HAS_INFINITY__ 1
+// SPARC:#define __DBL_HAS_QUIET_NAN__ 1
+// SPARC:#define __DBL_MANT_DIG__ 53
+// SPARC:#define __DBL_MAX_10_EXP__ 308
+// SPARC:#define __DBL_MAX_EXP__ 1024
+// SPARC:#define __DBL_MAX__ 1.7976931348623157e+308
+// SPARC:#define __DBL_MIN_10_EXP__ (-307)
+// SPARC:#define __DBL_MIN_EXP__ (-1021)
+// SPARC:#define __DBL_MIN__ 2.2250738585072014e-308
+// SPARC:#define __DECIMAL_DIG__ 17
+// SPARC:#define __FLT_DENORM_MIN__ 1.40129846e-45F
+// SPARC:#define __FLT_DIG__ 6
+// SPARC:#define __FLT_EPSILON__ 1.19209290e-7F
+// SPARC:#define __FLT_EVAL_METHOD__ 0
+// SPARC:#define __FLT_HAS_DENORM__ 1
+// SPARC:#define __FLT_HAS_INFINITY__ 1
+// SPARC:#define __FLT_HAS_QUIET_NAN__ 1
+// SPARC:#define __FLT_MANT_DIG__ 24
+// SPARC:#define __FLT_MAX_10_EXP__ 38
+// SPARC:#define __FLT_MAX_EXP__ 128
+// SPARC:#define __FLT_MAX__ 3.40282347e+38F
+// SPARC:#define __FLT_MIN_10_EXP__ (-37)
+// SPARC:#define __FLT_MIN_EXP__ (-125)
+// SPARC:#define __FLT_MIN__ 1.17549435e-38F
+// SPARC:#define __FLT_RADIX__ 2
+// SPARC:#define __INT16_TYPE__ short
+// SPARC:#define __INT32_TYPE__ int
+// SPARC:#define __INT64_C_SUFFIX__ LL
+// SPARC:#define __INT64_TYPE__ long long int
+// SPARC:#define __INT8_TYPE__ char
+// SPARC:#define __INTMAX_MAX__ 9223372036854775807LL
+// SPARC:#define __INTMAX_TYPE__ long long int
+// SPARC:#define __INTMAX_WIDTH__ 64
+// SPARC:#define __INTPTR_TYPE__ long int
+// SPARC:#define __INTPTR_WIDTH__ 32
+// SPARC:#define __INT_MAX__ 2147483647
+// SPARC:#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324
+// SPARC:#define __LDBL_DIG__ 15
+// SPARC:#define __LDBL_EPSILON__ 2.2204460492503131e-16
+// SPARC:#define __LDBL_HAS_DENORM__ 1
+// SPARC:#define __LDBL_HAS_INFINITY__ 1
+// SPARC:#define __LDBL_HAS_QUIET_NAN__ 1
+// SPARC:#define __LDBL_MANT_DIG__ 53
+// SPARC:#define __LDBL_MAX_10_EXP__ 308
+// SPARC:#define __LDBL_MAX_EXP__ 1024
+// SPARC:#define __LDBL_MAX__ 1.7976931348623157e+308
+// SPARC:#define __LDBL_MIN_10_EXP__ (-307)
+// SPARC:#define __LDBL_MIN_EXP__ (-1021)
+// SPARC:#define __LDBL_MIN__ 2.2250738585072014e-308
+// SPARC:#define __LONG_LONG_MAX__ 9223372036854775807LL
+// SPARC:#define __LONG_MAX__ 2147483647L
+// SPARC:#define __NO_INLINE__ 1
+// SPARC:#define __POINTER_WIDTH__ 32
+// SPARC:#define __PTRDIFF_TYPE__ long int
+// SPARC:#define __PTRDIFF_WIDTH__ 32
+// SPARC:#define __REGISTER_PREFIX__
+// SPARC:#define __SCHAR_MAX__ 127
+// SPARC:#define __SHRT_MAX__ 32767
+// SPARC:#define __SIG_ATOMIC_WIDTH__ 32
+// SPARC:#define __SIZE_TYPE__ long unsigned int
+// SPARC:#define __SIZE_WIDTH__ 32
+// SPARC:#define __UINTMAX_TYPE__ long long unsigned int
+// SPARC:#define __USER_LABEL_PREFIX__ _
+// SPARC:#define __VERSION__ "4.2.1 Compatible Clang Compiler"
+// SPARC:#define __WCHAR_MAX__ 2147483647
+// SPARC:#define __WCHAR_TYPE__ int
+// SPARC:#define __WCHAR_WIDTH__ 32
+// SPARC:#define __WINT_TYPE__ int
+// SPARC:#define __WINT_WIDTH__ 32
+// SPARC:#define __sparc 1
+// SPARC:#define __sparc__ 1
+// SPARC:#define __sparcv8 1
+// SPARC:#define sparc 1
+// 
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=tce-none-none < /dev/null | FileCheck -check-prefix TCE %s
+//
+// TCE:#define __CHAR_BIT__ 8
+// TCE:#define __DBL_DENORM_MIN__ 1.40129846e-45F
+// TCE:#define __DBL_DIG__ 6
+// TCE:#define __DBL_EPSILON__ 1.19209290e-7F
+// TCE:#define __DBL_HAS_DENORM__ 1
+// TCE:#define __DBL_HAS_INFINITY__ 1
+// TCE:#define __DBL_HAS_QUIET_NAN__ 1
+// TCE:#define __DBL_MANT_DIG__ 24
+// TCE:#define __DBL_MAX_10_EXP__ 38
+// TCE:#define __DBL_MAX_EXP__ 128
+// TCE:#define __DBL_MAX__ 3.40282347e+38F
+// TCE:#define __DBL_MIN_10_EXP__ (-37)
+// TCE:#define __DBL_MIN_EXP__ (-125)
+// TCE:#define __DBL_MIN__ 1.17549435e-38F
+// TCE:#define __DECIMAL_DIG__ -1
+// TCE:#define __FLT_DENORM_MIN__ 1.40129846e-45F
+// TCE:#define __FLT_DIG__ 6
+// TCE:#define __FLT_EPSILON__ 1.19209290e-7F
+// TCE:#define __FLT_EVAL_METHOD__ 0
+// TCE:#define __FLT_HAS_DENORM__ 1
+// TCE:#define __FLT_HAS_INFINITY__ 1
+// TCE:#define __FLT_HAS_QUIET_NAN__ 1
+// TCE:#define __FLT_MANT_DIG__ 24
+// TCE:#define __FLT_MAX_10_EXP__ 38
+// TCE:#define __FLT_MAX_EXP__ 128
+// TCE:#define __FLT_MAX__ 3.40282347e+38F
+// TCE:#define __FLT_MIN_10_EXP__ (-37)
+// TCE:#define __FLT_MIN_EXP__ (-125)
+// TCE:#define __FLT_MIN__ 1.17549435e-38F
+// TCE:#define __FLT_RADIX__ 2
+// TCE:#define __INT16_TYPE__ short
+// TCE:#define __INT32_TYPE__ int
+// TCE:#define __INT8_TYPE__ char
+// TCE:#define __INTMAX_MAX__ 2147483647L
+// TCE:#define __INTMAX_TYPE__ long int
+// TCE:#define __INTMAX_WIDTH__ 32
+// TCE:#define __INTPTR_TYPE__ int
+// TCE:#define __INTPTR_WIDTH__ 32
+// TCE:#define __INT_MAX__ 2147483647
+// TCE:#define __LDBL_DENORM_MIN__ 1.40129846e-45F
+// TCE:#define __LDBL_DIG__ 6
+// TCE:#define __LDBL_EPSILON__ 1.19209290e-7F
+// TCE:#define __LDBL_HAS_DENORM__ 1
+// TCE:#define __LDBL_HAS_INFINITY__ 1
+// TCE:#define __LDBL_HAS_QUIET_NAN__ 1
+// TCE:#define __LDBL_MANT_DIG__ 24
+// TCE:#define __LDBL_MAX_10_EXP__ 38
+// TCE:#define __LDBL_MAX_EXP__ 128
+// TCE:#define __LDBL_MAX__ 3.40282347e+38F
+// TCE:#define __LDBL_MIN_10_EXP__ (-37)
+// TCE:#define __LDBL_MIN_EXP__ (-125)
+// TCE:#define __LDBL_MIN__ 1.17549435e-38F
+// TCE:#define __LONG_LONG_MAX__ 2147483647LL
+// TCE:#define __LONG_MAX__ 2147483647L
+// TCE:#define __NO_INLINE__ 1
+// TCE:#define __POINTER_WIDTH__ 32
+// TCE:#define __PTRDIFF_TYPE__ int
+// TCE:#define __PTRDIFF_WIDTH__ 32
+// TCE:#define __SCHAR_MAX__ 127
+// TCE:#define __SHRT_MAX__ 32767
+// TCE:#define __SIG_ATOMIC_WIDTH__ 32
+// TCE:#define __SIZE_TYPE__ unsigned int
+// TCE:#define __SIZE_WIDTH__ 32
+// TCE:#define __TCE_V1__ 1
+// TCE:#define __TCE__ 1
+// TCE:#define __UINTMAX_TYPE__ long unsigned int
+// TCE:#define __USER_LABEL_PREFIX__ _
+// TCE:#define __WCHAR_MAX__ 2147483647
+// TCE:#define __WCHAR_TYPE__ int
+// TCE:#define __WCHAR_WIDTH__ 32
+// TCE:#define __WINT_TYPE__ int
+// TCE:#define __WINT_WIDTH__ 32
+// TCE:#define __tce 1
+// TCE:#define __tce__ 1
+// TCE:#define tce 1
+//
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=x86_64-none-none < /dev/null | FileCheck -check-prefix X86_64 %s
+//
+// X86_64:#define _LP64 1
+// X86_64:#define __CHAR_BIT__ 8
+// X86_64:#define __DBL_DENORM_MIN__ 4.9406564584124654e-324
+// X86_64:#define __DBL_DIG__ 15
+// X86_64:#define __DBL_EPSILON__ 2.2204460492503131e-16
+// X86_64:#define __DBL_HAS_DENORM__ 1
+// X86_64:#define __DBL_HAS_INFINITY__ 1
+// X86_64:#define __DBL_HAS_QUIET_NAN__ 1
+// X86_64:#define __DBL_MANT_DIG__ 53
+// X86_64:#define __DBL_MAX_10_EXP__ 308
+// X86_64:#define __DBL_MAX_EXP__ 1024
+// X86_64:#define __DBL_MAX__ 1.7976931348623157e+308
+// X86_64:#define __DBL_MIN_10_EXP__ (-307)
+// X86_64:#define __DBL_MIN_EXP__ (-1021)
+// X86_64:#define __DBL_MIN__ 2.2250738585072014e-308
+// X86_64:#define __DECIMAL_DIG__ 21
+// X86_64:#define __FLT_DENORM_MIN__ 1.40129846e-45F
+// X86_64:#define __FLT_DIG__ 6
+// X86_64:#define __FLT_EPSILON__ 1.19209290e-7F
+// X86_64:#define __FLT_EVAL_METHOD__ 0
+// X86_64:#define __FLT_HAS_DENORM__ 1
+// X86_64:#define __FLT_HAS_INFINITY__ 1
+// X86_64:#define __FLT_HAS_QUIET_NAN__ 1
+// X86_64:#define __FLT_MANT_DIG__ 24
+// X86_64:#define __FLT_MAX_10_EXP__ 38
+// X86_64:#define __FLT_MAX_EXP__ 128
+// X86_64:#define __FLT_MAX__ 3.40282347e+38F
+// X86_64:#define __FLT_MIN_10_EXP__ (-37)
+// X86_64:#define __FLT_MIN_EXP__ (-125)
+// X86_64:#define __FLT_MIN__ 1.17549435e-38F
+// X86_64:#define __FLT_RADIX__ 2
+// X86_64:#define __INT16_TYPE__ short
+// X86_64:#define __INT32_TYPE__ int
+// X86_64:#define __INT64_C_SUFFIX__ L
+// X86_64:#define __INT64_TYPE__ long int
+// X86_64:#define __INT8_TYPE__ char
+// X86_64:#define __INTMAX_MAX__ 9223372036854775807L
+// X86_64:#define __INTMAX_TYPE__ long int
+// X86_64:#define __INTMAX_WIDTH__ 64
+// X86_64:#define __INTPTR_TYPE__ long int
+// X86_64:#define __INTPTR_WIDTH__ 64
+// X86_64:#define __INT_MAX__ 2147483647
+// X86_64:#define __LDBL_DENORM_MIN__ 3.64519953188247460253e-4951L
+// X86_64:#define __LDBL_DIG__ 18
+// X86_64:#define __LDBL_EPSILON__ 1.08420217248550443401e-19L
+// X86_64:#define __LDBL_HAS_DENORM__ 1
+// X86_64:#define __LDBL_HAS_INFINITY__ 1
+// X86_64:#define __LDBL_HAS_QUIET_NAN__ 1
+// X86_64:#define __LDBL_MANT_DIG__ 64
+// X86_64:#define __LDBL_MAX_10_EXP__ 4932
+// X86_64:#define __LDBL_MAX_EXP__ 16384
+// X86_64:#define __LDBL_MAX__ 1.18973149535723176502e+4932L
+// X86_64:#define __LDBL_MIN_10_EXP__ (-4931)
+// X86_64:#define __LDBL_MIN_EXP__ (-16381)
+// X86_64:#define __LDBL_MIN__ 3.36210314311209350626e-4932L
+// X86_64:#define __LITTLE_ENDIAN__ 1
+// X86_64:#define __LONG_LONG_MAX__ 9223372036854775807LL
+// X86_64:#define __LONG_MAX__ 9223372036854775807L
+// X86_64:#define __LP64__ 1
+// X86_64:#define __MMX__ 1
+// X86_64:#define __NO_INLINE__ 1
+// X86_64:#define __NO_MATH_INLINES 1
+// X86_64:#define __POINTER_WIDTH__ 64
+// X86_64:#define __PTRDIFF_TYPE__ long int
+// X86_64:#define __PTRDIFF_WIDTH__ 64
+// X86_64:#define __REGISTER_PREFIX__ 
+// X86_64:#define __SCHAR_MAX__ 127
+// X86_64:#define __SHRT_MAX__ 32767
+// X86_64:#define __SIG_ATOMIC_WIDTH__ 32
+// X86_64:#define __SIZE_TYPE__ long unsigned int
+// X86_64:#define __SIZE_WIDTH__ 64
+// X86_64:#define __SSE2_MATH__ 1
+// X86_64:#define __SSE2__ 1
+// X86_64:#define __SSE_MATH__ 1
+// X86_64:#define __SSE__ 1
+// X86_64:#define __UINTMAX_TYPE__ long unsigned int
+// X86_64:#define __USER_LABEL_PREFIX__ _
+// X86_64:#define __WCHAR_MAX__ 2147483647
+// X86_64:#define __WCHAR_TYPE__ int
+// X86_64:#define __WCHAR_WIDTH__ 32
+// X86_64:#define __WINT_TYPE__ int
+// X86_64:#define __WINT_WIDTH__ 32
+// X86_64:#define __amd64 1
+// X86_64:#define __amd64__ 1
+// X86_64:#define __nocona 1
+// X86_64:#define __nocona__ 1
+// X86_64:#define __tune_nocona__ 1
+// X86_64:#define __x86_64 1
+// X86_64:#define __x86_64__ 1
+//
+// RUN: %clang_cc1 -x c++ -triple i686-pc-linux-gnu -E -dM < /dev/null | FileCheck -check-prefix GNUSOURCE %s
+// GNUSOURCE:#define _GNU_SOURCE 1
+// 
diff --git a/test/Preprocessor/line-directive-output.c b/test/Preprocessor/line-directive-output.c
new file mode 100644
index 0000000..290703a
--- /dev/null
+++ b/test/Preprocessor/line-directive-output.c
@@ -0,0 +1,71 @@
+// RUN: %clang_cc1 -E %s 2>&1 | FileCheck %s -strict-whitespace
+// PR6101
+int a;
+// CHECK: # 1 "{{.*}}line-directive-output.c"
+// CHECK: int a;
+
+// CHECK-NEXT: # 50 "{{.*}}line-directive-output.c"
+// CHECK-NEXT: int b;
+#line 50
+int b;
+
+// CHECK: # 13 "{{.*}}line-directive-output.c"
+// CHECK-NEXT: int c;
+# 13
+int c;
+
+
+// CHECK-NEXT: # 1 "A.c"
+#line 1 "A.c"
+// CHECK-NEXT: # 2 "A.c"
+#line 2
+
+// CHECK-NEXT: # 1 "B.c"
+#line 1 "B.c"
+
+// CHECK-NEXT: # 1000 "A.c"
+#line 1000 "A.c"
+
+int y;
+
+
+
+
+
+
+
+// CHECK: # 1010 "A.c"
+int z;
+
+extern int x;
+
+# 3 "temp2.h" 1
+extern int y;
+
+# 7 "A.c" 2
+extern int z;
+
+
+
+
+
+
+
+
+
+
+
+
+
+// CHECK: # 25 "A.c"
+
+
+// CHECK: # 50 "C.c" 1
+# 50 "C.c" 1
+
+
+// CHECK-NEXT: # 2000 "A.c" 2
+# 2000 "A.c" 2
+# 42 "A.c"
+# 44 "A.c"
+# 49 "A.c"
diff --git a/test/Preprocessor/line-directive.c b/test/Preprocessor/line-directive.c
new file mode 100644
index 0000000..878d067
--- /dev/null
+++ b/test/Preprocessor/line-directive.c
@@ -0,0 +1,92 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s
+// RUN: %clang_cc1 -E %s 2>&1 | grep 'blonk.c:92:2: error: #error ABC'
+// RUN: %clang_cc1 -E %s 2>&1 | grep 'blonk.c:93:2: error: #error DEF'
+
+#line 'a'            // expected-error {{#line directive requires a positive integer argument}}
+#line 0              // expected-error {{#line directive requires a positive integer argument}}
+#line 00             // expected-error {{#line directive requires a positive integer argument}}
+#line 2147483648     // expected-warning {{C requires #line number to be less than 2147483648, allowed as extension}}
+#line 42             // ok
+#line 42 'a'         // expected-error {{invalid filename for #line directive}}
+#line 42 "foo/bar/baz.h"  // ok
+
+
+// #line directives expand macros.
+#define A 42 "foo"
+#line A
+
+# 42
+# 42 "foo"
+# 42 "foo" 2 // expected-error {{invalid line marker flag '2': cannot pop empty include stack}}
+# 42 "foo" 1 3  // enter
+# 42 "foo" 2 3  // exit
+# 42 "foo" 2 3 4 // expected-error {{invalid line marker flag '2': cannot pop empty include stack}}
+# 42 "foo" 3 4
+
+# 'a'            // expected-error {{invalid preprocessing directive}}
+# 42 'f'         // expected-error {{invalid filename for line marker directive}}
+# 42 1 3         // expected-error {{invalid filename for line marker directive}}
+# 42 "foo" 3 1   // expected-error {{invalid flag line marker directive}}
+# 42 "foo" 42    // expected-error {{invalid flag line marker directive}}
+# 42 "foo" 1 2   // expected-error {{invalid flag line marker directive}}
+
+
+// These are checked by the RUN line.
+#line 92 "blonk.c"
+#error ABC  // expected-error {{#error ABC}}
+#error DEF  // expected-error {{#error DEF}}
+
+
+// Verify that linemarker diddling of the system header flag works.
+
+# 192 "glomp.h" // not a system header.
+typedef int x;  // expected-note {{previous definition is here}}
+typedef int x;  // expected-error {{redefinition of typedef 'x' is invalid in C}}
+
+# 192 "glomp.h" 3 // System header.
+typedef int y;  // ok
+typedef int y;  // ok
+
+typedef int q;  // q is in system header.
+
+#line 42 "blonk.h"  // doesn't change system headerness.
+
+typedef int z;  // ok
+typedef int z;  // ok
+
+# 97     // doesn't change system headerness.
+
+typedef int z1;  // ok
+typedef int z1;  // ok
+
+# 42 "blonk.h"  // DOES change system headerness.
+
+typedef int w;  // expected-note {{previous definition is here}}
+typedef int w;  // expected-error {{redefinition of typedef 'w' is invalid in C}}
+
+typedef int q;  // original definition in system header, should not diagnose.
+
+// This should not produce an "extra tokens at end of #line directive" warning,
+// because #line is allowed to contain expanded tokens.
+#define EMPTY()
+#line 2 "foo.c" EMPTY( )
+#line 2 "foo.c" NONEMPTY( )  // expected-warning{{extra tokens at end of #line directive}}
+
+// PR3940
+#line 0xf  // expected-error {{#line directive requires a simple digit sequence}}
+#line 42U  // expected-error {{#line directive requires a simple digit sequence}}
+
+
+// Line markers are digit strings interpreted as decimal numbers, this is
+// 10, not 8.
+#line 010  // expected-warning {{#line directive interprets number as decimal, not octal}}
+extern int array[__LINE__ == 10 ? 1:-1];
+
+/* PR3917 */
+#line 41
+extern char array2[\
+_\
+_LINE__ == 42 ? 1: -1];  /* line marker is location of first _ */
+
+
+
diff --git a/test/Preprocessor/macro-multiline.c b/test/Preprocessor/macro-multiline.c
new file mode 100644
index 0000000..df7c40a
--- /dev/null
+++ b/test/Preprocessor/macro-multiline.c
@@ -0,0 +1,8 @@
+// RUN: %clang -E %s "-DX=A
+// RUN: THIS_SHOULD_NOT_EXIST_IN_THE_OUTPUT" > %t
+// RUN: grep "GOOD: A" %t
+// RUN: not grep THIS_SHOULD_NOT_EXIST_IN_THE_OUTPUT %t
+// rdar://6762183
+
+GOOD: X
+
diff --git a/test/Preprocessor/macro_arg_keyword.c b/test/Preprocessor/macro_arg_keyword.c
new file mode 100644
index 0000000..b9bbbf3
--- /dev/null
+++ b/test/Preprocessor/macro_arg_keyword.c
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -E %s | grep xxx-xxx
+
+#define foo(return) return-return
+
+foo(xxx)
+
diff --git a/test/Preprocessor/macro_disable.c b/test/Preprocessor/macro_disable.c
new file mode 100644
index 0000000..d7859dc
--- /dev/null
+++ b/test/Preprocessor/macro_disable.c
@@ -0,0 +1,43 @@
+// RUN: %clang_cc1 %s -E | FileCheck -strict-whitespace %s
+// Check for C99 6.10.3.4p2.
+
+#define f(a) f(x * (a)) 
+#define x 2 
+#define z z[0] 
+f(f(z)); 
+// CHECK: f(2 * (f(2 * (z[0]))));
+
+
+
+#define A A B C 
+#define B B C A 
+#define C C A B 
+A 
+// CHECK: A B C A B A C A B C A
+
+
+// PR1820
+#define i(x) h(x
+#define h(x) x(void) 
+extern int i(i));
+// CHECK: int i(void)
+
+
+#define M_0(x) M_ ## x 
+#define M_1(x) x + M_0(0) 
+#define M_2(x) x + M_1(1) 
+#define M_3(x) x + M_2(2) 
+#define M_4(x) x + M_3(3) 
+#define M_5(x) x + M_4(4) 
+
+a: M_0(1)(2)(3)(4)(5);
+b: M_0(5)(4)(3)(2)(1);
+
+// CHECK: a: 2 + M_0(3)(4)(5);
+// CHECK: b: 4 + 4 + 3 + 2 + 1 + M_0(3)(2)(1);
+
+#define n(v) v
+#define l m
+#define m l a
+c: n(m) X
+// CHECK: c: m a X
diff --git a/test/Preprocessor/macro_expand.c b/test/Preprocessor/macro_expand.c
new file mode 100644
index 0000000..4dc0357
--- /dev/null
+++ b/test/Preprocessor/macro_expand.c
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -E %s | grep '^A: Y$'
+// RUN: %clang_cc1 -E %s | grep '^B: f()$'
+// RUN: %clang_cc1 -E %s | grep '^C: for()$'
+
+#define X() Y
+#define Y() X
+
+A: X()()()
+
+// PR3927
+#define f(x) h(x
+#define for(x) h(x
+#define h(x) x()
+B: f(f))
+C: for(for))
+
+// rdar://6880648
+#define f(x,y...) y
+f()
diff --git a/test/Preprocessor/macro_expandloc.c b/test/Preprocessor/macro_expandloc.c
new file mode 100644
index 0000000..f466013
--- /dev/null
+++ b/test/Preprocessor/macro_expandloc.c
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 %s -E 2>&1 | grep '#include'
+#define FOO 1
+
+// The error message should be on the #include line, not the 1.
+#include FOO
+
diff --git a/test/Preprocessor/macro_expandloc2.c b/test/Preprocessor/macro_expandloc2.c
new file mode 100644
index 0000000..4aa7dfe
--- /dev/null
+++ b/test/Preprocessor/macro_expandloc2.c
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 %s -E 2>&1 | grep '#include'
+#define FOO BAR
+
+// The error message should be on the #include line, not the 1.
+#include FOO
+
diff --git a/test/Preprocessor/macro_fn.c b/test/Preprocessor/macro_fn.c
new file mode 100644
index 0000000..85733b4
--- /dev/null
+++ b/test/Preprocessor/macro_fn.c
@@ -0,0 +1,46 @@
+/* RUN: %clang_cc1 %s -Eonly -std=c89 -pedantic -verify
+*/
+/* PR3937 */
+#define zero() 0
+#define one(x) 0
+#define two(x, y) 0
+#define zero_dot(...) 0   /* expected-warning {{variadic macros were introduced in C99}} */
+#define one_dot(x, ...) 0 /* expected-warning {{variadic macros were introduced in C99}} */
+
+zero()
+zero(1);          /* expected-error {{too many arguments provided to function-like macro invocation}} */
+zero(1, 2, 3);    /* expected-error {{too many arguments provided to function-like macro invocation}} */
+
+one()   /* ok */
+one(a)
+one(a,)           /* expected-error {{too many arguments provided to function-like macro invocation}} */
+one(a, b)         /* expected-error {{too many arguments provided to function-like macro invocation}} */
+
+two()       /* expected-error {{too few arguments provided to function-like macro invocation}} */
+two(a)      /* expected-error {{too few arguments provided to function-like macro invocation}} */
+two(a,b)
+two(a, )    /* expected-warning {{empty macro arguments were standardized in C99}} */
+two(a,b,c)  /* expected-error {{too many arguments provided to function-like macro invocation}} */
+two(
+    ,     /* expected-warning {{empty macro arguments were standardized in C99}} */
+    ,     /* expected-warning {{empty macro arguments were standardized in C99}}  \
+             expected-error {{too many arguments provided to function-like macro invocation}} */
+    )     
+two(,)      /* expected-warning 2 {{empty macro arguments were standardized in C99}} */
+
+
+
+/* PR4006 & rdar://6807000 */
+#define e(...) __VA_ARGS__  /* expected-warning {{variadic macros were introduced in C99}} */
+e(x)
+e()
+
+zero_dot()
+one_dot(x)  /* empty ... argument: expected-warning {{varargs argument missing, but tolerated as an extension}}  */
+one_dot()   /* empty first argument, elided ...: expected-warning {{varargs argument missing, but tolerated as an extension}} */
+
+
+/* rdar://6816766 - Crash with function-like macro test at end of directive. */
+#define E() (i == 0)
+#if E
+#endif
diff --git a/test/Preprocessor/macro_fn_comma_swallow.c b/test/Preprocessor/macro_fn_comma_swallow.c
new file mode 100644
index 0000000..5742591
--- /dev/null
+++ b/test/Preprocessor/macro_fn_comma_swallow.c
@@ -0,0 +1,21 @@
+// Test the GNU comma swallowing extension.
+// RUN: %clang_cc1 %s -E | grep 'foo{A, }'
+// RUN: %clang_cc1 %s -E | grep 'fo2{A,}'
+// RUN: %clang_cc1 %s -E | grep '{foo}'
+
+#define X(Y) foo{A, Y}
+X()
+
+#define X2(Y) fo2{A,##Y}
+X2()
+
+// should eat the comma.
+#define X3(b, ...) {b, ## __VA_ARGS__}
+X3(foo)
+
+
+
+// RUN: %clang_cc1 %s -E | grep 'AA BB'
+// PR3880
+#define X4(...)  AA , ## __VA_ARGS__ BB
+X4()
diff --git a/test/Preprocessor/macro_fn_disable_expand.c b/test/Preprocessor/macro_fn_disable_expand.c
new file mode 100644
index 0000000..16948dc
--- /dev/null
+++ b/test/Preprocessor/macro_fn_disable_expand.c
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 %s -E | FileCheck %s
+
+#define foo(x) bar x
+foo(foo) (2)
+// CHECK: bar foo (2)
+
+#define m(a) a(w)
+#define w ABCD
+m(m)
+// CHECK: m(ABCD)
+
+
+
+// rdar://7466570 PR4438, PR5163
+
+// We should get '42' in the argument list for gcc compatibility.
+#define A 1
+#define B 2
+#define C(x) (x + 1)
+
+X: C(
+#ifdef A
+#if A == 1
+#if B
+    42
+#endif
+#endif
+#endif
+    )
+// CHECK: X: (42 + 1)
diff --git a/test/Preprocessor/macro_fn_lparen_scan.c b/test/Preprocessor/macro_fn_lparen_scan.c
new file mode 100644
index 0000000..0218469
--- /dev/null
+++ b/test/Preprocessor/macro_fn_lparen_scan.c
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -E %s | grep 'noexp: foo y'
+// RUN: %clang_cc1 -E %s | grep 'expand: abc'
+// RUN: %clang_cc1 -E %s | grep 'noexp2: foo nonexp'
+// RUN: %clang_cc1 -E %s | grep 'expand2: abc'
+
+#define A foo
+#define foo() abc
+#define X A y
+
+// This should not expand to abc, because the foo macro isn't followed by (.
+noexp: X
+
+
+// This should expand to abc.
+#undef X
+#define X A ()
+expand: X
+
+
+// This should be 'foo nonexp'
+noexp2: A nonexp
+
+// This should expand
+expand2: A (
+)
+
+
diff --git a/test/Preprocessor/macro_fn_lparen_scan2.c b/test/Preprocessor/macro_fn_lparen_scan2.c
new file mode 100644
index 0000000..c23e741
--- /dev/null
+++ b/test/Preprocessor/macro_fn_lparen_scan2.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -E %s | grep 'FUNC (3 +1);'
+
+#define F(a) a 
+#define FUNC(a) (a+1) 
+
+F(FUNC) FUNC (3); /* final token sequence is FUNC(3+1) */ 
+
diff --git a/test/Preprocessor/macro_fn_placemarker.c b/test/Preprocessor/macro_fn_placemarker.c
new file mode 100644
index 0000000..1791054
--- /dev/null
+++ b/test/Preprocessor/macro_fn_placemarker.c
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 %s -E | grep 'foo(A, )'
+
+#define X(Y) foo(A, Y)
+X()
+
diff --git a/test/Preprocessor/macro_fn_preexpand.c b/test/Preprocessor/macro_fn_preexpand.c
new file mode 100644
index 0000000..1b94c82
--- /dev/null
+++ b/test/Preprocessor/macro_fn_preexpand.c
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 %s -E | grep 'pre: 1 1 X'
+// RUN: %clang_cc1 %s -E | grep 'nopre: 1A(X)'
+
+/* Preexpansion of argument. */
+#define A(X) 1 X
+pre: A(A(X))
+
+/* The ## operator disables preexpansion. */
+#undef A
+#define A(X) 1 ## X
+nopre: A(A(X))
+
diff --git a/test/Preprocessor/macro_fn_varargs_iso.c b/test/Preprocessor/macro_fn_varargs_iso.c
new file mode 100644
index 0000000..a1aab26
--- /dev/null
+++ b/test/Preprocessor/macro_fn_varargs_iso.c
@@ -0,0 +1,11 @@
+
+// RUN: %clang_cc1 -E %s | grep 'foo{a, b, c, d, e}'
+// RUN: %clang_cc1 -E %s | grep 'foo2{d, C, B}'
+// RUN: %clang_cc1 -E %s | grep 'foo2{d,e, C, B}'
+
+#define va1(...) foo{a, __VA_ARGS__, e}
+va1(b, c, d)
+#define va2(a, b, ...) foo2{__VA_ARGS__, b, a}
+va2(B, C, d)
+va2(B, C, d,e)
+
diff --git a/test/Preprocessor/macro_fn_varargs_named.c b/test/Preprocessor/macro_fn_varargs_named.c
new file mode 100644
index 0000000..b50d53d
--- /dev/null
+++ b/test/Preprocessor/macro_fn_varargs_named.c
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -E %s | grep '^a: x$'
+// RUN: %clang_cc1 -E %s | grep '^b: x y, z,h$'
+// RUN: %clang_cc1 -E %s | grep '^c: foo(x)$'
+
+#define A(b, c...) b c
+a: A(x)
+b: A(x, y, z,h)
+
+#define B(b, c...) foo(b, ## c)
+c: B(x)
diff --git a/test/Preprocessor/macro_misc.c b/test/Preprocessor/macro_misc.c
new file mode 100644
index 0000000..53d9982
--- /dev/null
+++ b/test/Preprocessor/macro_misc.c
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 %s -Eonly -verify
+
+// This should not be rejected.
+#ifdef defined
+#endif
+
+
+
+// PR3764
+
+// This should not produce a redefinition warning.
+#define FUNC_LIKE(a) (a)
+#define FUNC_LIKE(a)(a)
+
+// This either.
+#define FUNC_LIKE2(a)\
+(a)
+#define FUNC_LIKE2(a) (a)
+
+// This should.
+#define FUNC_LIKE3(a) ( a)  // expected-note {{previous definition is here}}
+#define FUNC_LIKE3(a) (a) // expected-warning {{'FUNC_LIKE3' macro redefined}}
+
diff --git a/test/Preprocessor/macro_not_define.c b/test/Preprocessor/macro_not_define.c
new file mode 100644
index 0000000..82648d4
--- /dev/null
+++ b/test/Preprocessor/macro_not_define.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -E %s | grep '^ # define X 3$'
+
+#define H # 
+ #define D define 
+ 
+ #define DEFINE(a, b) H D a b 
+ 
+ DEFINE(X, 3) 
+
diff --git a/test/Preprocessor/macro_paste_bad.c b/test/Preprocessor/macro_paste_bad.c
new file mode 100644
index 0000000..2af0173
--- /dev/null
+++ b/test/Preprocessor/macro_paste_bad.c
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -Eonly -verify -pedantic %s
+// pasting ""x"" and ""+"" does not give a valid preprocessing token
+#define XYZ  x ## + 
+XYZ   // expected-error {{pasting formed 'x+', an invalid preprocessing token}}
+#define XXYZ  . ## test
+XXYZ   // expected-error {{pasting formed '.test', an invalid preprocessing token}}
+
+// GCC PR 20077
+
+#define a   a ## ## // expected-error {{'##' cannot appear at end of macro expansion}}
+#define b() b ## ## // expected-error {{'##' cannot appear at end of macro expansion}}
+#define c   c ##    // expected-error {{'##' cannot appear at end of macro expansion}}
+#define d() d ##    // expected-error {{'##' cannot appear at end of macro expansion}}
+
+
+#define e   ## ## e // expected-error {{'##' cannot appear at start of macro expansion}}
+#define f() ## ## f // expected-error {{'##' cannot appear at start of macro expansion}}
+#define g   ## g    // expected-error {{'##' cannot appear at start of macro expansion}}
+#define h() ## h    // expected-error {{'##' cannot appear at start of macro expansion}}
+#define i   ##      // expected-error {{'##' cannot appear at start of macro expansion}}
+#define j() ##      // expected-error {{'##' cannot appear at start of macro expansion}}
+
+// Invalid token pasting.
+// PR3918
+
+// When pasting creates poisoned identifiers, we error.
+#pragma GCC poison BLARG
+BLARG  // expected-error {{attempt to use a poisoned identifier}}
+#define XX BL ## ARG
+XX     // expected-error {{attempt to use a poisoned identifier}}
+
+#define VA __VA_ ## ARGS__
+int VA;   // expected-warning {{__VA_ARGS__ can only appear in the expansion of a C99 variadic macro}}
+
+
diff --git a/test/Preprocessor/macro_paste_bcpl_comment.c b/test/Preprocessor/macro_paste_bcpl_comment.c
new file mode 100644
index 0000000..fd07b1f
--- /dev/null
+++ b/test/Preprocessor/macro_paste_bcpl_comment.c
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 %s -Eonly 2>&1 | grep error
+
+#define COMM1 / ## /
+COMM1
+
diff --git a/test/Preprocessor/macro_paste_c_block_comment.c b/test/Preprocessor/macro_paste_c_block_comment.c
new file mode 100644
index 0000000..3441f27
--- /dev/null
+++ b/test/Preprocessor/macro_paste_c_block_comment.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 %s -Eonly 2>&1 | grep error
+// RUN: %clang_cc1 %s -Eonly 2>&1 | not grep unterminated
+// RUN: %clang_cc1 %s -Eonly 2>&1 | not grep scratch
+
+#define COMM / ## *
+COMM
+
diff --git a/test/Preprocessor/macro_paste_commaext.c b/test/Preprocessor/macro_paste_commaext.c
new file mode 100644
index 0000000..7cfe43d
--- /dev/null
+++ b/test/Preprocessor/macro_paste_commaext.c
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 %s -E | grep 'V);'
+// RUN: %clang_cc1 %s -E | grep 'W, 1, 2);'
+// RUN: %clang_cc1 %s -E | grep 'X, 1, 2);'
+// RUN: %clang_cc1 %s -E | grep 'Y, );'
+// RUN: %clang_cc1 %s -E | grep 'Z, );'
+
+#define debug(format, ...) format, ## __VA_ARGS__)
+debug(V);
+debug(W, 1, 2);
+debug(X, 1, 2 );
+debug(Y, );
+debug(Z,);
+
diff --git a/test/Preprocessor/macro_paste_empty.c b/test/Preprocessor/macro_paste_empty.c
new file mode 100644
index 0000000..2e26f14
--- /dev/null
+++ b/test/Preprocessor/macro_paste_empty.c
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -E %s | grep 'a:Y'
+// RUN: %clang_cc1 -E %s | grep 'b:Y'
+// RUN: %clang_cc1 -E %s | grep 'c:YY'
+
+#define FOO(X) X ## Y
+a:FOO()
+
+#define FOO2(X) Y ## X
+b:FOO2()
+
+#define FOO3(X) X ## Y ## X ## Y ## X ## X
+c:FOO3()
+
diff --git a/test/Preprocessor/macro_paste_hard.c b/test/Preprocessor/macro_paste_hard.c
new file mode 100644
index 0000000..fad8426
--- /dev/null
+++ b/test/Preprocessor/macro_paste_hard.c
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -E %s | grep '1: aaab 2'
+// RUN: %clang_cc1 -E %s | grep '2: 2 baaa'
+// RUN: %clang_cc1 -E %s | grep '3: 2 xx'
+
+#define a(n) aaa ## n
+#define b 2
+1: a(b b)   // aaab 2    2 gets expanded, not b.
+
+#undef a
+#undef b
+#define a(n) n ## aaa
+#define b 2
+2: a(b b)   // 2 baaa    2 gets expanded, not b.
+
+#define baaa xx
+3: a(b b)   // 2 xx
+
diff --git a/test/Preprocessor/macro_paste_hashhash.c b/test/Preprocessor/macro_paste_hashhash.c
new file mode 100644
index 0000000..e7993cc
--- /dev/null
+++ b/test/Preprocessor/macro_paste_hashhash.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -E %s | grep '^"x ## y";$'
+#define hash_hash # ## # 
+#define mkstr(a) # a 
+#define in_between(a) mkstr(a) 
+#define join(c, d) in_between(c hash_hash d) 
+join(x, y);
+
diff --git a/test/Preprocessor/macro_paste_mscomment.c b/test/Preprocessor/macro_paste_mscomment.c
new file mode 100644
index 0000000..7132406
--- /dev/null
+++ b/test/Preprocessor/macro_paste_mscomment.c
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -P -E -fms-extensions %s | FileCheck -strict-whitespace %s
+// This horrible stuff should preprocess into (other than whitespace):
+//   int foo;
+//   int bar;
+//   int baz;
+
+int foo;
+
+// CHECK: int foo;
+
+#define comment /##/  dead tokens live here
+comment This is stupidity
+
+int bar;
+
+// CHECK: int bar;
+
+#define nested(x) int x comment cute little dead tokens...
+
+nested(baz)  rise of the dead tokens
+
+;
+
+// CHECK: int baz
+// CHECK: ;
+
diff --git a/test/Preprocessor/macro_paste_none.c b/test/Preprocessor/macro_paste_none.c
new file mode 100644
index 0000000..97ccd7c
--- /dev/null
+++ b/test/Preprocessor/macro_paste_none.c
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -E %s | grep '!!'
+
+#define A(B,C) B ## C
+
+!A(,)!
+
diff --git a/test/Preprocessor/macro_paste_simple.c b/test/Preprocessor/macro_paste_simple.c
new file mode 100644
index 0000000..563d7f4
--- /dev/null
+++ b/test/Preprocessor/macro_paste_simple.c
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 %s -E | grep "barbaz123"
+
+#define FOO bar ## baz ## 123
+
+FOO
diff --git a/test/Preprocessor/macro_paste_spacing.c b/test/Preprocessor/macro_paste_spacing.c
new file mode 100644
index 0000000..6498ffc
--- /dev/null
+++ b/test/Preprocessor/macro_paste_spacing.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 %s -E | grep "^xy$"
+
+#define A  x ## y
+blah
+
+A
+
diff --git a/test/Preprocessor/macro_paste_spacing2.c b/test/Preprocessor/macro_paste_spacing2.c
new file mode 100644
index 0000000..02cc12f
--- /dev/null
+++ b/test/Preprocessor/macro_paste_spacing2.c
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 %s -E | grep "movl %eax"
+// PR4132
+#define R1E %eax
+#define epilogue(r1) movl r1 ## E;
+epilogue(R1)
+
diff --git a/test/Preprocessor/macro_rescan.c b/test/Preprocessor/macro_rescan.c
new file mode 100644
index 0000000..3a38548
--- /dev/null
+++ b/test/Preprocessor/macro_rescan.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -E %s | grep 'ei_1 = (17 +1);'
+// RUN: %clang_cc1 -E %s | grep 'ei_2 = (M1)(17);'
+
+#define M1(a) (a+1) 
+#define M2(b) b 
+
+int ei_1 = M2(M1)(17); /* becomes int ei_1 = (17+1); */ 
+int ei_2 = (M2(M1))(17); /* becomes int ei_2 = (M1)(17); */ 
+
diff --git a/test/Preprocessor/macro_rescan2.c b/test/Preprocessor/macro_rescan2.c
new file mode 100644
index 0000000..826f4ee
--- /dev/null
+++ b/test/Preprocessor/macro_rescan2.c
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 %s -E | grep 'a: 2\*f(9)'
+// RUN: %clang_cc1 %s -E | grep 'b: 2\*9\*g'
+
+#define f(a) a*g 
+#define g f 
+a: f(2)(9) 
+
+#undef f
+#undef g
+
+#define f(a) a*g 
+#define g(a) f(a) 
+
+b: f(2)(9)
+
diff --git a/test/Preprocessor/macro_rescan_varargs.c b/test/Preprocessor/macro_rescan_varargs.c
new file mode 100644
index 0000000..6c6415a
--- /dev/null
+++ b/test/Preprocessor/macro_rescan_varargs.c
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -E %s | FileCheck -strict-whitespace %s
+
+#define LPAREN ( 
+#define RPAREN ) 
+#define F(x, y) x + y 
+#define ELLIP_FUNC(...) __VA_ARGS__ 
+
+1: ELLIP_FUNC(F, LPAREN, 'a', 'b', RPAREN); /* 1st invocation */ 
+2: ELLIP_FUNC(F LPAREN 'a', 'b' RPAREN); /* 2nd invocation */ 
+
+// CHECK: 1: F, (, 'a', 'b', );
+// CHECK: 2: 'a' + 'b';
+
diff --git a/test/Preprocessor/macro_rparen_scan.c b/test/Preprocessor/macro_rparen_scan.c
new file mode 100644
index 0000000..e4de5db
--- /dev/null
+++ b/test/Preprocessor/macro_rparen_scan.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -E %s | grep '^3 ;$'
+
+/* Right paren scanning, hard case.  Should expand to 3. */
+#define i(x) 3 
+#define a i(yz 
+#define b ) 
+a b ) ; 
+
diff --git a/test/Preprocessor/macro_rparen_scan2.c b/test/Preprocessor/macro_rparen_scan2.c
new file mode 100644
index 0000000..42aa544
--- /dev/null
+++ b/test/Preprocessor/macro_rparen_scan2.c
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -E %s | FileCheck -strict-whitespace %s
+
+#define R_PAREN ) 
+
+#define FUNC(a) a 
+
+static int glob = (1 + FUNC(1 R_PAREN ); 
+
+// CHECK: static int glob = (1 + 1 );
+
diff --git a/test/Preprocessor/macro_space.c b/test/Preprocessor/macro_space.c
new file mode 100644
index 0000000..49a9a0f
--- /dev/null
+++ b/test/Preprocessor/macro_space.c
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 %s -E | grep '! ,'
+
+#define XX
+! XX,
+
diff --git a/test/Preprocessor/macro_undef.c b/test/Preprocessor/macro_undef.c
new file mode 100644
index 0000000..c842c85
--- /dev/null
+++ b/test/Preprocessor/macro_undef.c
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -dM -undef -Dfoo=1 -E %s | FileCheck %s
+
+// CHECK-NOT: #define __clang__
+// CHECK: #define foo 1
diff --git a/test/Preprocessor/mi_opt.c b/test/Preprocessor/mi_opt.c
new file mode 100644
index 0000000..597ac07
--- /dev/null
+++ b/test/Preprocessor/mi_opt.c
@@ -0,0 +1,11 @@
+// RUN: not %clang_cc1 -fsyntax-only %s
+// PR1900
+// This test should get a redefinition error from m_iopt.h: the MI opt 
+// shouldn't apply.
+
+#define MACRO
+#include "mi_opt.h"
+#undef MACRO
+#define MACRO || 1
+#include "mi_opt.h"
+
diff --git a/test/Preprocessor/mi_opt.h b/test/Preprocessor/mi_opt.h
new file mode 100644
index 0000000..a82aa6a
--- /dev/null
+++ b/test/Preprocessor/mi_opt.h
@@ -0,0 +1,4 @@
+#if !defined foo MACRO
+#define foo
+int x = 2;
+#endif
diff --git a/test/Preprocessor/mi_opt2.c b/test/Preprocessor/mi_opt2.c
new file mode 100644
index 0000000..198d19f
--- /dev/null
+++ b/test/Preprocessor/mi_opt2.c
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -E %s | FileCheck %s
+// PR6282
+// This test should not trigger the include guard optimization since
+// the guard macro is defined on the first include.
+
+#define ITERATING 1
+#define X 1
+#include "mi_opt2.h"
+#undef X
+#define X 2
+#include "mi_opt2.h"
+
+// CHECK: b: 1
+// CHECK: b: 2
+
diff --git a/test/Preprocessor/mi_opt2.h b/test/Preprocessor/mi_opt2.h
new file mode 100644
index 0000000..df37eba
--- /dev/null
+++ b/test/Preprocessor/mi_opt2.h
@@ -0,0 +1,5 @@
+#ifndef ITERATING
+a: X
+#else
+b: X
+#endif
diff --git a/test/Preprocessor/non_fragile_feature.m b/test/Preprocessor/non_fragile_feature.m
new file mode 100644
index 0000000..552209d
--- /dev/null
+++ b/test/Preprocessor/non_fragile_feature.m
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fobjc-nonfragile-abi %s
+#ifndef __has_feature
+#error Should have __has_feature
+#endif
+
+#if !__has_feature(objc_nonfragile_abi)
+#error Non-fragile ABI used for compilation but feature macro not set.
+#endif
diff --git a/test/Preprocessor/non_fragile_feature1.m b/test/Preprocessor/non_fragile_feature1.m
new file mode 100644
index 0000000..89b52ed
--- /dev/null
+++ b/test/Preprocessor/non_fragile_feature1.m
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown %s
+#ifndef __has_feature
+#error Should have __has_feature
+#endif
+
+#if __has_feature(objc_nonfragile_abi)
+#error Non-fragile ABI not used for compilation but feature macro set.
+#endif
diff --git a/test/Preprocessor/objc-pp.m b/test/Preprocessor/objc-pp.m
new file mode 100644
index 0000000..3e09325
--- /dev/null
+++ b/test/Preprocessor/objc-pp.m
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify -pedantic
+
+#import <stdint.h>  // no warning on #import in objc mode.
+
diff --git a/test/Preprocessor/optimize.c b/test/Preprocessor/optimize.c
new file mode 100644
index 0000000..c820ded
--- /dev/null
+++ b/test/Preprocessor/optimize.c
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -Eonly %s -DOPT_O2 -O2 -verify
+#ifdef OPT_O2
+  #ifndef __OPTIMIZE__
+    #error "__OPTIMIZE__ not defined"
+  #endif
+  #ifdef __OPTIMIZE_SIZE__
+    #error "__OPTIMIZE_SIZE__ defined"
+  #endif
+#endif
+
+// RUN: %clang_cc1 -Eonly %s -DOPT_O0 -O0 -verify
+#ifdef OPT_O0
+  #ifdef __OPTIMIZE__
+    #error "__OPTIMIZE__ defined"
+  #endif
+  #ifdef __OPTIMIZE_SIZE__
+    #error "__OPTIMIZE_SIZE__ defined"
+  #endif
+#endif
+
+// RUN: %clang_cc1 -Eonly %s -DOPT_OS -Os -verify
+#ifdef OPT_OS
+  #ifndef __OPTIMIZE__
+    #error "__OPTIMIZE__ not defined"
+  #endif
+  #ifdef __OPTIMIZE_SIZE__
+    #error "__OPTIMIZE_SIZE__ not defined"
+  #endif
+#endif
diff --git a/test/Preprocessor/output_paste_avoid.c b/test/Preprocessor/output_paste_avoid.c
new file mode 100644
index 0000000..8e4f3a4
--- /dev/null
+++ b/test/Preprocessor/output_paste_avoid.c
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -E %s -o - | FileCheck -strict-whitespace %s
+
+
+#define y(a) ..a
+A: y(.)
+// This should print as ".. ." to avoid turning into ...
+// CHECK: A: .. .
+
+#define X 0 .. 1
+B: X
+// CHECK: B: 0 .. 1
+
+#define DOT .
+C: ..DOT
+// CHECK: C: .. .
+
+
+#define PLUS +
+#define EMPTY
+#define f(x) =x=
+D: +PLUS -EMPTY- PLUS+ f(=)
+// CHECK: D: + + - - + + = = =
+
+
+#define test(x) L#x
+E: test(str)
+// Should expand to L "str" not L"str"
+// CHECK: E: L "str"
+
+// Should avoid producing >>=.
+#define equal =
+F: >>equal
+// CHECK: F: >> =
diff --git a/test/Preprocessor/overflow.c b/test/Preprocessor/overflow.c
new file mode 100644
index 0000000..a921441
--- /dev/null
+++ b/test/Preprocessor/overflow.c
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -Eonly %s -verify -triple i686-pc-linux-gnu
+
+// Multiply signed overflow
+#if 0x7FFFFFFFFFFFFFFF*2 // expected-warning {{overflow}}
+#endif
+
+// Multiply unsigned overflow
+#if 0xFFFFFFFFFFFFFFFF*2
+#endif
+
+// Add signed overflow
+#if 0x7FFFFFFFFFFFFFFF+1 // expected-warning {{overflow}}
+#endif
+
+// Add unsigned overflow
+#if 0xFFFFFFFFFFFFFFFF+1
+#endif
+
+// Subtract signed overflow
+#if 0x7FFFFFFFFFFFFFFF- -1 // expected-warning {{overflow}}
+#endif
+
+// Subtract unsigned overflow
+#if 0xFFFFFFFFFFFFFFFF- -1 // expected-warning {{converted from negative value}}
+#endif
diff --git a/test/Preprocessor/pic.c b/test/Preprocessor/pic.c
new file mode 100644
index 0000000..886beb7
--- /dev/null
+++ b/test/Preprocessor/pic.c
@@ -0,0 +1,9 @@
+// RUN: %clang -ccc-host-triple i386-unknown-unknown -static -dM -E -o %t %s
+// RUN: grep '#define __PIC__' %t | count 0
+// RUN: grep '#define __pic__' %t | count 0
+// RUN: %clang -ccc-host-triple i386-unknown-unknown -fpic -dM -E -o %t %s
+// RUN: grep '#define __PIC__ 1' %t | count 1
+// RUN: grep '#define __pic__ 1' %t | count 1
+// RUN: %clang -ccc-host-triple i386-unknown-unknown -fPIC -dM -E -o %t %s
+// RUN: grep '#define __PIC__ 2' %t | count 1
+// RUN: grep '#define __pic__ 2' %t | count 1
diff --git a/test/Preprocessor/pr2086.c b/test/Preprocessor/pr2086.c
new file mode 100644
index 0000000..d438e87
--- /dev/null
+++ b/test/Preprocessor/pr2086.c
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -E %s
+
+#define test
+#include "pr2086.h"
+#define test
+#include "pr2086.h"
+
+#ifdef test
+#error
+#endif
+
diff --git a/test/Preprocessor/pr2086.h b/test/Preprocessor/pr2086.h
new file mode 100644
index 0000000..b98b996
--- /dev/null
+++ b/test/Preprocessor/pr2086.h
@@ -0,0 +1,6 @@
+#ifndef test
+#endif
+
+#ifdef test
+#undef test
+#endif
diff --git a/test/Preprocessor/pragma_diagnostic.c b/test/Preprocessor/pragma_diagnostic.c
new file mode 100644
index 0000000..d157406
--- /dev/null
+++ b/test/Preprocessor/pragma_diagnostic.c
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-undef %s
+// rdar://2362963
+
+#if FOO    // ok.
+#endif
+
+#pragma GCC diagnostic warning "-Wundef"
+
+#if FOO    // expected-warning {{'FOO' is not defined}}
+#endif
+
+#pragma GCC diagnostic ignored "-Wun" "def"
+
+#if FOO    // ok.
+#endif
+
+#pragma GCC diagnostic error "-Wundef"
+
+#if FOO    // expected-error {{'FOO' is not defined}}
+#endif
+
+
+
+#define foo error
+#pragma GCC diagnostic foo "-Wundef"  // expected-warning {{pragma diagnostic expected 'error', 'warning', 'ignored', or 'fatal'}}
+
+#pragma GCC diagnostic error 42  // expected-warning {{unexpected token in pragma diagnostic}}
+
+#pragma GCC diagnostic error "-Wundef" 42  // expected-warning {{unexpected token in pragma diagnostic}}
+#pragma GCC diagnostic error "invalid-name"  // expected-warning {{pragma diagnostic expected option name (e.g. "-Wundef")}}
+
+#pragma GCC diagnostic error "-Winvalid-name"  // expected-warning {{unknown warning group '-Winvalid-name', ignored}}
+
diff --git a/test/Preprocessor/pragma_microsoft.c b/test/Preprocessor/pragma_microsoft.c
new file mode 100644
index 0000000..0201c45
--- /dev/null
+++ b/test/Preprocessor/pragma_microsoft.c
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify -fms-extensions
+
+// rdar://6495941
+
+#define FOO 1
+#define BAR "2"
+
+#pragma comment(linker,"foo=" FOO) // expected-error {{pragma comment requires parenthesized identifier and optional string}}
+#pragma comment(linker," bar=" BAR)
+
+#pragma comment( user, "Compiled on " __DATE__ " at " __TIME__ ) 
+
+#pragma comment(foo)    // expected-error {{unknown kind of pragma comment}}
+#pragma comment(compiler,)     // expected-error {{pragma comment requires}}
+#define foo compiler
+#pragma comment(foo)   // macro expand kind.
+#pragma comment(foo) x // expected-error {{pragma comment requires}}
+
+#pragma comment(user, "foo\abar\nbaz\tsome	thing")
+
diff --git a/test/Preprocessor/pragma_poison.c b/test/Preprocessor/pragma_poison.c
new file mode 100644
index 0000000..5b39183
--- /dev/null
+++ b/test/Preprocessor/pragma_poison.c
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 %s -Eonly -verify
+
+#pragma GCC poison rindex
+rindex(some_string, 'h');   // expected-error {{attempt to use a poisoned identifier}}
+
+#define BAR _Pragma ("GCC poison XYZW")  XYZW /*NO ERROR*/
+  XYZW      // ok
+BAR
+  XYZW      // expected-error {{attempt to use a poisoned identifier}}
+
+// Pragma poison shouldn't warn from macro expansions defined before the token
+// is poisoned.
+
+#define strrchr rindex2
+#pragma GCC poison rindex2
+
+// Can poison multiple times.
+#pragma GCC poison rindex2
+
+strrchr(some_string, 'h');   // ok.
diff --git a/test/Preprocessor/pragma_sysheader.c b/test/Preprocessor/pragma_sysheader.c
new file mode 100644
index 0000000..cf2843b
--- /dev/null
+++ b/test/Preprocessor/pragma_sysheader.c
@@ -0,0 +1,3 @@
+// RUN: %clang -verify -pedantic %s -fsyntax-only
+// rdar://6899937
+#include "pragma_sysheader.h"
diff --git a/test/Preprocessor/pragma_sysheader.h b/test/Preprocessor/pragma_sysheader.h
new file mode 100644
index 0000000..b79bde5
--- /dev/null
+++ b/test/Preprocessor/pragma_sysheader.h
@@ -0,0 +1,4 @@
+#pragma GCC system_header
+typedef int x;
+typedef int x;
+
diff --git a/test/Preprocessor/pragma_unknown.c b/test/Preprocessor/pragma_unknown.c
new file mode 100644
index 0000000..c185153
--- /dev/null
+++ b/test/Preprocessor/pragma_unknown.c
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -E %s | grep '#pragma foo bar'
+// RUN: %clang_cc1 -fsyntax-only -Wunknown-pragmas -verify %s
+
+// GCC doesn't expand macro args for unrecognized pragmas.
+#define bar xX
+#pragma foo bar   // expected-warning {{unknown pragma ignored}}
+
+#pragma STDC FP_CONTRACT ON
+#pragma STDC FP_CONTRACT OFF
+#pragma STDC FP_CONTRACT DEFAULT
+#pragma STDC FP_CONTRACT IN_BETWEEN  // expected-warning {{expected 'ON' or 'OFF' or 'DEFAULT' in pragma}}
+
+#pragma STDC FENV_ACCESS ON          // expected-warning {{pragma STDC FENV_ACCESS ON is not supported, ignoring pragma}}
+#pragma STDC FENV_ACCESS OFF
+#pragma STDC FENV_ACCESS DEFAULT
+#pragma STDC FENV_ACCESS IN_BETWEEN   // expected-warning {{expected 'ON' or 'OFF' or 'DEFAULT' in pragma}}
+
+#pragma STDC CX_LIMITED_RANGE ON
+#pragma STDC CX_LIMITED_RANGE OFF
+#pragma STDC CX_LIMITED_RANGE DEFAULT 
+#pragma STDC CX_LIMITED_RANGE IN_BETWEEN   // expected-warning {{expected 'ON' or 'OFF' or 'DEFAULT' in pragma}}
+
+#pragma STDC CX_LIMITED_RANGE    // expected-warning {{expected 'ON' or 'OFF' or 'DEFAULT' in pragma}}
+#pragma STDC CX_LIMITED_RANGE ON FULL POWER  // expected-warning {{expected end of macro in STDC pragma}}
+
+#pragma STDC SO_GREAT  // expected-warning {{unknown pragma in STDC namespace}}
+#pragma STDC   // expected-warning {{unknown pragma in STDC namespace}}
+
diff --git a/test/Preprocessor/print_line_count.c b/test/Preprocessor/print_line_count.c
new file mode 100644
index 0000000..6a02b0e
--- /dev/null
+++ b/test/Preprocessor/print_line_count.c
@@ -0,0 +1,4 @@
+/* RUN: %clang -E -C -P %s | wc -l | grep 4
+   PR2741
+   comment */ 
+y
diff --git a/test/Preprocessor/print_line_track.c b/test/Preprocessor/print_line_track.c
new file mode 100644
index 0000000..c87fe00
--- /dev/null
+++ b/test/Preprocessor/print_line_track.c
@@ -0,0 +1,17 @@
+/* RUN: %clang_cc1 -E %s | grep 'a 3'
+ * RUN: %clang_cc1 -E %s | grep 'b 16'
+ * RUN: %clang_cc1 -E -P %s | grep 'a 3'
+ * RUN: %clang_cc1 -E -P %s | grep 'b 16'
+ * RUN: %clang_cc1 -E %s | not grep '# 0 '
+ * PR1848
+ * PR3437
+*/
+
+#define t(x) x
+
+t(a
+3)
+
+t(b
+__LINE__)
+
diff --git a/test/Preprocessor/pushable-diagnostics.c b/test/Preprocessor/pushable-diagnostics.c
new file mode 100644
index 0000000..6c861a1
--- /dev/null
+++ b/test/Preprocessor/pushable-diagnostics.c
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s
+
+#pragma clang diagnostic pop // expected-warning{{pragma diagnostic pop could not pop, no matching push}}
+
+#pragma clang diagnostic puhs // expected-warning{{pragma diagnostic expected 'error', 'warning', 'ignored', 'fatal' 'push', or 'pop'}}
+
+char a = 'df'; // expected-warning{{multi-character character constant}}
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wmultichar"
+
+char b = 'df'; // no warning.
+#pragma clang diagnostic pop
+
+char c = 'df';  // expected-warning{{multi-character character constant}}
+
+#pragma clang diagnostic pop // expected-warning{{pragma diagnostic pop could not pop, no matching push}}
diff --git a/test/Preprocessor/skipping_unclean.c b/test/Preprocessor/skipping_unclean.c
new file mode 100644
index 0000000..52d1785
--- /dev/null
+++ b/test/Preprocessor/skipping_unclean.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -E %s | grep bark
+
+#if 0
+blah
+#\
+else
+bark
+#endif
+
diff --git a/test/Preprocessor/stdint.c b/test/Preprocessor/stdint.c
new file mode 100644
index 0000000..e701494
--- /dev/null
+++ b/test/Preprocessor/stdint.c
@@ -0,0 +1,1262 @@
+// RUN: %clang_cc1 -E -ffreestanding -triple=arm-none-none %s | FileCheck -check-prefix ARM %s
+//
+// ARM:typedef signed long long int int64_t;
+// ARM:typedef unsigned long long int uint64_t;
+// ARM:typedef int64_t int_least64_t;
+// ARM:typedef uint64_t uint_least64_t;
+// ARM:typedef int64_t int_fast64_t;
+// ARM:typedef uint64_t uint_fast64_t;
+//
+// ARM:typedef signed int int32_t;
+// ARM:typedef unsigned int uint32_t;
+// ARM:typedef int32_t int_least32_t;
+// ARM:typedef uint32_t uint_least32_t;
+// ARM:typedef int32_t int_fast32_t;
+// ARM:typedef uint32_t uint_fast32_t;
+// 
+// ARM:typedef signed short int16_t;
+// ARM:typedef unsigned short uint16_t;
+// ARM:typedef int16_t int_least16_t;
+// ARM:typedef uint16_t uint_least16_t;
+// ARM:typedef int16_t int_fast16_t;
+// ARM:typedef uint16_t uint_fast16_t;
+//
+// ARM:typedef signed char int8_t;
+// ARM:typedef unsigned char uint8_t;
+// ARM:typedef int8_t int_least8_t;
+// ARM:typedef uint8_t uint_least8_t;
+// ARM:typedef int8_t int_fast8_t;
+// ARM:typedef uint8_t uint_fast8_t;
+//
+// ARM:typedef int32_t intptr_t;
+// ARM:typedef uint32_t uintptr_t;
+// 
+// ARM:typedef int64_t intmax_t;
+// ARM:typedef uint64_t uintmax_t;
+//
+// ARM:INT8_MAX_ 127
+// ARM:INT8_MIN_ (-127 -1)
+// ARM:UINT8_MAX_ 255
+// ARM:INT_LEAST8_MIN_ (-127 -1)
+// ARM:INT_LEAST8_MAX_ 127
+// ARM:UINT_LEAST8_MAX_ 255
+// ARM:INT_FAST8_MIN_ (-127 -1)
+// ARM:INT_FAST8_MAX_ 127
+// ARM:UINT_FAST8_MAX_ 255
+//
+// ARM:INT16_MAX_ 32767
+// ARM:INT16_MIN_ (-32767 -1)
+// ARM:UINT16_MAX_ 65535
+// ARM:INT_LEAST16_MIN_ (-32767 -1)
+// ARM:INT_LEAST16_MAX_ 32767
+// ARM:UINT_LEAST16_MAX_ 65535
+// ARM:INT_FAST16_MIN_ (-32767 -1)
+// ARM:INT_FAST16_MAX_ 32767
+// ARM:UINT_FAST16_MAX_ 65535
+//
+// ARM:INT32_MAX_ 2147483647
+// ARM:INT32_MIN_ (-2147483647 -1)
+// ARM:UINT32_MAX_ 4294967295U
+// ARM:INT_LEAST32_MIN_ (-2147483647 -1)
+// ARM:INT_LEAST32_MAX_ 2147483647
+// ARM:UINT_LEAST32_MAX_ 4294967295U
+// ARM:INT_FAST32_MIN_ (-2147483647 -1)
+// ARM:INT_FAST32_MAX_ 2147483647
+// ARM:UINT_FAST32_MAX_ 4294967295U
+//
+// ARM:INT64_MAX_ 9223372036854775807LL
+// ARM:INT64_MIN_ (-9223372036854775807LL -1)
+// ARM:UINT64_MAX_ 18446744073709551615ULL
+// ARM:INT_LEAST64_MIN_ (-9223372036854775807LL -1)
+// ARM:INT_LEAST64_MAX_ 9223372036854775807LL
+// ARM:UINT_LEAST64_MAX_ 18446744073709551615ULL
+// ARM:INT_FAST64_MIN_ (-9223372036854775807LL -1)
+// ARM:INT_FAST64_MAX_ 9223372036854775807LL
+// ARM:UINT_FAST64_MAX_ 18446744073709551615ULL
+//
+// ARM:INTPTR_MIN_ (-2147483647 -1)
+// ARM:INTPTR_MAX_ 2147483647
+// ARM:UINTPTR_MAX_ 4294967295U
+// ARM:PTRDIFF_MIN_ (-2147483647 -1)
+// ARM:PTRDIFF_MAX_ 2147483647
+// ARM:SIZE_MAX_ 4294967295U
+//
+// ARM:INTMAX_MIN_ (-9223372036854775807LL -1)
+// ARM:INTMAX_MAX_ 9223372036854775807LL
+// ARM:UINTMAX_MAX_ 18446744073709551615ULL
+//
+// ARM:SIG_ATOMIC_MIN_ (-2147483647 -1)
+// ARM:SIG_ATOMIC_MAX_ 2147483647
+// ARM:WINT_MIN_ (-2147483647 -1)
+// ARM:WINT_MAX_ 2147483647
+//
+// ARM:WCHAR_MAX_ 2147483647
+// ARM:WCHAR_MIN_ (-2147483647 -1)
+//
+// ARM:INT8_C_(0) 0
+// ARM:UINT8_C_(0) 0U
+// ARM:INT16_C_(0) 0
+// ARM:UINT16_C_(0) 0U
+// ARM:INT32_C_(0) 0
+// ARM:UINT32_C_(0) 0U
+// ARM:INT64_C_(0) 0LL
+// ARM:UINT64_C_(0) 0ULL
+//
+// ARM:INTMAX_C_(0) 0LL
+// ARM:UINTMAX_C_(0) 0ULL
+//
+//
+// RUN: %clang_cc1 -E -ffreestanding -triple=bfin-none-none %s | FileCheck -check-prefix BFIN %s
+//
+// BFIN:typedef signed long long int int64_t;
+// BFIN:typedef unsigned long long int uint64_t;
+// BFIN:typedef int64_t int_least64_t;
+// BFIN:typedef uint64_t uint_least64_t;
+// BFIN:typedef int64_t int_fast64_t;
+// BFIN:typedef uint64_t uint_fast64_t;
+//
+// BFIN:typedef signed int int32_t;
+// BFIN:typedef unsigned int uint32_t;
+// BFIN:typedef int32_t int_least32_t;
+// BFIN:typedef uint32_t uint_least32_t;
+// BFIN:typedef int32_t int_fast32_t;
+// BFIN:typedef uint32_t uint_fast32_t;
+//
+// BFIN:typedef signed short int16_t;
+// BFIN:typedef unsigned short uint16_t;
+// BFIN:typedef int16_t int_least16_t;
+// BFIN:typedef uint16_t uint_least16_t;
+// BFIN:typedef int16_t int_fast16_t;
+// BFIN:typedef uint16_t uint_fast16_t;
+//
+// BFIN:typedef signed char int8_t;
+// BFIN:typedef unsigned char uint8_t;
+// BFIN:typedef int8_t int_least8_t;
+// BFIN:typedef uint8_t uint_least8_t;
+// BFIN:typedef int8_t int_fast8_t;
+// BFIN:typedef uint8_t uint_fast8_t;
+//
+// BFIN:typedef int32_t intptr_t;
+// BFIN:typedef uint32_t uintptr_t;
+//
+// BFIN:typedef int64_t intmax_t;
+// BFIN:typedef uint64_t uintmax_t;
+//
+// BFIN:INT8_MAX_ 127
+// BFIN:INT8_MIN_ (-127 -1)
+// BFIN:UINT8_MAX_ 255
+// BFIN:INT_LEAST8_MIN_ (-127 -1)
+// BFIN:INT_LEAST8_MAX_ 127
+// BFIN:UINT_LEAST8_MAX_ 255
+// BFIN:INT_FAST8_MIN_ (-127 -1)
+// BFIN:INT_FAST8_MAX_ 127
+// BFIN:UINT_FAST8_MAX_ 255
+//
+// BFIN:INT16_MAX_ 32767
+// BFIN:INT16_MIN_ (-32767 -1)
+// BFIN:UINT16_MAX_ 65535
+// BFIN:INT_LEAST16_MIN_ (-32767 -1)
+// BFIN:INT_LEAST16_MAX_ 32767
+// BFIN:UINT_LEAST16_MAX_ 65535
+// BFIN:INT_FAST16_MIN_ (-32767 -1)
+// BFIN:INT_FAST16_MAX_ 32767
+// BFIN:UINT_FAST16_MAX_ 65535
+//
+// BFIN:INT32_MAX_ 2147483647
+// BFIN:INT32_MIN_ (-2147483647 -1)
+// BFIN:UINT32_MAX_ 4294967295U
+// BFIN:INT_LEAST32_MIN_ (-2147483647 -1)
+// BFIN:INT_LEAST32_MAX_ 2147483647
+// BFIN:UINT_LEAST32_MAX_ 4294967295U
+// BFIN:INT_FAST32_MIN_ (-2147483647 -1)
+// BFIN:INT_FAST32_MAX_ 2147483647
+// BFIN:UINT_FAST32_MAX_ 4294967295U
+//
+// BFIN:INT64_MAX_ 9223372036854775807LL
+// BFIN:INT64_MIN_ (-9223372036854775807LL -1)
+// BFIN:UINT64_MAX_ 18446744073709551615ULL
+// BFIN:INT_LEAST64_MIN_ (-9223372036854775807LL -1)
+// BFIN:INT_LEAST64_MAX_ 9223372036854775807LL
+// BFIN:UINT_LEAST64_MAX_ 18446744073709551615ULL
+// BFIN:INT_FAST64_MIN_ (-9223372036854775807LL -1)
+// BFIN:INT_FAST64_MAX_ 9223372036854775807LL
+// BFIN:UINT_FAST64_MAX_ 18446744073709551615ULL
+//
+// BFIN:INTPTR_MIN_ (-2147483647 -1)
+// BFIN:INTPTR_MAX_ 2147483647
+// BFIN:UINTPTR_MAX_ 4294967295U
+// BFIN:PTRDIFF_MIN_ (-2147483647 -1)
+// BFIN:PTRDIFF_MAX_ 2147483647
+// BFIN:SIZE_MAX_ 4294967295U
+//
+// BFIN:INTMAX_MIN_ (-9223372036854775807LL -1)
+// BFIN:INTMAX_MAX_ 9223372036854775807LL
+// BFIN:UINTMAX_MAX_ 18446744073709551615ULL
+//
+// BFIN:SIG_ATOMIC_MIN_ (-2147483647 -1)
+// BFIN:SIG_ATOMIC_MAX_ 2147483647
+// BFIN:WINT_MIN_ (-2147483647 -1)
+// BFIN:WINT_MAX_ 2147483647
+//
+// BFIN:WCHAR_MAX_ 2147483647
+// BFIN:WCHAR_MIN_ (-2147483647 -1)
+//
+// BFIN:INT8_C_(0) 0
+// BFIN:UINT8_C_(0) 0U
+// BFIN:INT16_C_(0) 0
+// BFIN:UINT16_C_(0) 0U
+// BFIN:INT32_C_(0) 0
+// BFIN:UINT32_C_(0) 0U
+// BFIN:INT64_C_(0) 0LL
+// BFIN:UINT64_C_(0) 0ULL
+// 
+// BFIN:INTMAX_C_(0) 0LL
+// BFIN:UINTMAX_C_(0) 0ULL
+//
+//
+// RUN: %clang_cc1 -E -ffreestanding -triple=i386-none-none %s | FileCheck -check-prefix I386 %s
+//
+// I386:typedef signed long long int int64_t;
+// I386:typedef unsigned long long int uint64_t;
+// I386:typedef int64_t int_least64_t;
+// I386:typedef uint64_t uint_least64_t;
+// I386:typedef int64_t int_fast64_t;
+// I386:typedef uint64_t uint_fast64_t;
+//
+// I386:typedef signed int int32_t;
+// I386:typedef unsigned int uint32_t;
+// I386:typedef int32_t int_least32_t;
+// I386:typedef uint32_t uint_least32_t;
+// I386:typedef int32_t int_fast32_t;
+// I386:typedef uint32_t uint_fast32_t;
+//
+// I386:typedef signed short int16_t;
+// I386:typedef unsigned short uint16_t;
+// I386:typedef int16_t int_least16_t;
+// I386:typedef uint16_t uint_least16_t;
+// I386:typedef int16_t int_fast16_t;
+// I386:typedef uint16_t uint_fast16_t;
+//
+// I386:typedef signed char int8_t;
+// I386:typedef unsigned char uint8_t;
+// I386:typedef int8_t int_least8_t;
+// I386:typedef uint8_t uint_least8_t;
+// I386:typedef int8_t int_fast8_t;
+// I386:typedef uint8_t uint_fast8_t;
+//
+// I386:typedef int32_t intptr_t;
+// I386:typedef uint32_t uintptr_t;
+//
+// I386:typedef int64_t intmax_t;
+// I386:typedef uint64_t uintmax_t;
+//
+// I386:INT8_MAX_ 127
+// I386:INT8_MIN_ (-127 -1)
+// I386:UINT8_MAX_ 255
+// I386:INT_LEAST8_MIN_ (-127 -1)
+// I386:INT_LEAST8_MAX_ 127
+// I386:UINT_LEAST8_MAX_ 255
+// I386:INT_FAST8_MIN_ (-127 -1)
+// I386:INT_FAST8_MAX_ 127
+// I386:UINT_FAST8_MAX_ 255
+//
+// I386:INT16_MAX_ 32767
+// I386:INT16_MIN_ (-32767 -1)
+// I386:UINT16_MAX_ 65535
+// I386:INT_LEAST16_MIN_ (-32767 -1)
+// I386:INT_LEAST16_MAX_ 32767
+// I386:UINT_LEAST16_MAX_ 65535
+// I386:INT_FAST16_MIN_ (-32767 -1)
+// I386:INT_FAST16_MAX_ 32767
+// I386:UINT_FAST16_MAX_ 65535
+//
+// I386:INT32_MAX_ 2147483647
+// I386:INT32_MIN_ (-2147483647 -1)
+// I386:UINT32_MAX_ 4294967295U
+// I386:INT_LEAST32_MIN_ (-2147483647 -1)
+// I386:INT_LEAST32_MAX_ 2147483647
+// I386:UINT_LEAST32_MAX_ 4294967295U
+// I386:INT_FAST32_MIN_ (-2147483647 -1)
+// I386:INT_FAST32_MAX_ 2147483647
+// I386:UINT_FAST32_MAX_ 4294967295U
+//
+// I386:INT64_MAX_ 9223372036854775807LL
+// I386:INT64_MIN_ (-9223372036854775807LL -1)
+// I386:UINT64_MAX_ 18446744073709551615ULL
+// I386:INT_LEAST64_MIN_ (-9223372036854775807LL -1)
+// I386:INT_LEAST64_MAX_ 9223372036854775807LL
+// I386:UINT_LEAST64_MAX_ 18446744073709551615ULL
+// I386:INT_FAST64_MIN_ (-9223372036854775807LL -1)
+// I386:INT_FAST64_MAX_ 9223372036854775807LL
+// I386:UINT_FAST64_MAX_ 18446744073709551615ULL
+//
+// I386:INTPTR_MIN_ (-2147483647 -1)
+// I386:INTPTR_MAX_ 2147483647
+// I386:UINTPTR_MAX_ 4294967295U
+// I386:PTRDIFF_MIN_ (-2147483647 -1)
+// I386:PTRDIFF_MAX_ 2147483647
+// I386:SIZE_MAX_ 4294967295U
+//
+// I386:INTMAX_MIN_ (-9223372036854775807LL -1)
+// I386:INTMAX_MAX_ 9223372036854775807LL
+// I386:UINTMAX_MAX_ 18446744073709551615ULL
+//
+// I386:SIG_ATOMIC_MIN_ (-2147483647 -1)
+// I386:SIG_ATOMIC_MAX_ 2147483647
+// I386:WINT_MIN_ (-2147483647 -1)
+// I386:WINT_MAX_ 2147483647
+//
+// I386:WCHAR_MAX_ 2147483647
+// I386:WCHAR_MIN_ (-2147483647 -1)
+//
+// I386:INT8_C_(0) 0
+// I386:UINT8_C_(0) 0U
+// I386:INT16_C_(0) 0
+// I386:UINT16_C_(0) 0U
+// I386:INT32_C_(0) 0
+// I386:UINT32_C_(0) 0U
+// I386:INT64_C_(0) 0LL
+// I386:UINT64_C_(0) 0ULL
+//
+// I386:INTMAX_C_(0) 0LL
+// I386:UINTMAX_C_(0) 0ULL
+//
+// RUN: %clang_cc1 -E -ffreestanding -triple=msp430-none-none %s | FileCheck -check-prefix MSP430 %s
+//
+// MSP430:typedef signed long int int32_t;
+// MSP430:typedef unsigned long int uint32_t;
+// MSP430:typedef int32_t int_least32_t;
+// MSP430:typedef uint32_t uint_least32_t;
+// MSP430:typedef int32_t int_fast32_t;
+// MSP430:typedef uint32_t uint_fast32_t;
+//
+// MSP430:typedef signed short int16_t;
+// MSP430:typedef unsigned short uint16_t;
+// MSP430:typedef int16_t int_least16_t;
+// MSP430:typedef uint16_t uint_least16_t;
+// MSP430:typedef int16_t int_fast16_t;
+// MSP430:typedef uint16_t uint_fast16_t;
+//
+// MSP430:typedef signed char int8_t;
+// MSP430:typedef unsigned char uint8_t;
+// MSP430:typedef int8_t int_least8_t;
+// MSP430:typedef uint8_t uint_least8_t;
+// MSP430:typedef int8_t int_fast8_t;
+// MSP430:typedef uint8_t uint_fast8_t;
+//
+// MSP430:typedef int16_t intptr_t;
+// MSP430:typedef uint16_t uintptr_t;
+//
+// MSP430:typedef int32_t intmax_t;
+// MSP430:typedef uint32_t uintmax_t;
+//
+// MSP430:INT8_MAX_ 127
+// MSP430:INT8_MIN_ (-127 -1)
+// MSP430:UINT8_MAX_ 255
+// MSP430:INT_LEAST8_MIN_ (-127 -1)
+// MSP430:INT_LEAST8_MAX_ 127
+// MSP430:UINT_LEAST8_MAX_ 255
+// MSP430:INT_FAST8_MIN_ (-127 -1)
+// MSP430:INT_FAST8_MAX_ 127
+// MSP430:UINT_FAST8_MAX_ 255
+//
+// MSP430:INT16_MAX_ 32767
+// MSP430:INT16_MIN_ (-32767 -1)
+// MSP430:UINT16_MAX_ 65535
+// MSP430:INT_LEAST16_MIN_ (-32767 -1)
+// MSP430:INT_LEAST16_MAX_ 32767
+// MSP430:UINT_LEAST16_MAX_ 65535
+// MSP430:INT_FAST16_MIN_ (-32767 -1)
+// MSP430:INT_FAST16_MAX_ 32767
+// MSP430:UINT_FAST16_MAX_ 65535
+//
+// MSP430:INT32_MAX_ 2147483647L
+// MSP430:INT32_MIN_ (-2147483647L -1)
+// MSP430:UINT32_MAX_ 4294967295UL
+// MSP430:INT_LEAST32_MIN_ (-2147483647L -1)
+// MSP430:INT_LEAST32_MAX_ 2147483647L
+// MSP430:UINT_LEAST32_MAX_ 4294967295UL
+// MSP430:INT_FAST32_MIN_ (-2147483647L -1)
+// MSP430:INT_FAST32_MAX_ 2147483647L
+// MSP430:UINT_FAST32_MAX_ 4294967295UL
+//
+// MSP430:INT64_MAX_ 9223372036854775807LL
+// MSP430:INT64_MIN_ (-9223372036854775807LL -1)
+// MSP430:UINT64_MAX_ 18446744073709551615ULL
+// MSP430:INT_LEAST64_MIN_ (-9223372036854775807LL -1)
+// MSP430:INT_LEAST64_MAX_ 9223372036854775807LL
+// MSP430:UINT_LEAST64_MAX_ 18446744073709551615ULL
+// MSP430:INT_FAST64_MIN_ (-9223372036854775807LL -1)
+// MSP430:INT_FAST64_MAX_ 9223372036854775807LL
+// MSP430:UINT_FAST64_MAX_ 18446744073709551615ULL
+//
+// MSP430:INTPTR_MIN_ (-32767 -1)
+// MSP430:INTPTR_MAX_ 32767
+// MSP430:UINTPTR_MAX_ 65535
+// MSP430:PTRDIFF_MIN_ (-32767 -1)
+// MSP430:PTRDIFF_MAX_ 32767
+// MSP430:SIZE_MAX_ 65535
+//
+// MSP430:INTMAX_MIN_ (-2147483647L -1)
+// MSP430:INTMAX_MAX_ 2147483647L
+// MSP430:UINTMAX_MAX_ 4294967295UL
+//
+// MSP430:SIG_ATOMIC_MIN_ (-2147483647L -1)
+// MSP430:SIG_ATOMIC_MAX_ 2147483647L
+// MSP430:WINT_MIN_ (-32767 -1)
+// MSP430:WINT_MAX_ 32767
+//
+// MSP430:WCHAR_MAX_ 32767
+// MSP430:WCHAR_MIN_ (-32767 -1)
+//
+// MSP430:INT8_C_(0) 0
+// MSP430:UINT8_C_(0) 0U
+// MSP430:INT16_C_(0) 0
+// MSP430:UINT16_C_(0) 0U
+// MSP430:INT32_C_(0) 0L
+// MSP430:UINT32_C_(0) 0UL
+// MSP430:INT64_C_(0) 0LL
+// MSP430:UINT64_C_(0) 0ULL
+//
+// MSP430:INTMAX_C_(0) 0L
+// MSP430:UINTMAX_C_(0) 0UL
+//
+// RUN: %clang_cc1 -E -ffreestanding -triple=pic16-none-none %s | FileCheck -check-prefix PIC16 %s
+// 
+// PIC16:typedef signed long int int32_t;
+// PIC16:typedef unsigned long int uint32_t;
+// PIC16:typedef int32_t int_least32_t;
+// PIC16:typedef uint32_t uint_least32_t;
+// PIC16:typedef int32_t int_fast32_t;
+// PIC16:typedef uint32_t uint_fast32_t;
+//
+// PIC16:typedef signed short int16_t;
+// PIC16:typedef unsigned short uint16_t;
+// PIC16:typedef int16_t int_least16_t;
+// PIC16:typedef uint16_t uint_least16_t;
+// PIC16:typedef int16_t int_fast16_t;
+// PIC16:typedef uint16_t uint_fast16_t;
+//
+// PIC16:typedef signed char int8_t;
+// PIC16:typedef unsigned char uint8_t;
+// PIC16:typedef int8_t int_least8_t;
+// PIC16:typedef uint8_t uint_least8_t;
+// PIC16:typedef int8_t int_fast8_t;
+// PIC16:typedef uint8_t uint_fast8_t;
+//
+// PIC16:typedef int16_t intptr_t;
+// PIC16:typedef uint16_t uintptr_t;
+//
+// PIC16:typedef int32_t intmax_t;
+// PIC16:typedef uint32_t uintmax_t;
+//
+// PIC16:INT8_MAX_ 127
+// PIC16:INT8_MIN_ (-127 -1)
+// PIC16:UINT8_MAX_ 255
+// PIC16:INT_LEAST8_MIN_ (-127 -1)
+// PIC16:INT_LEAST8_MAX_ 127
+// PIC16:UINT_LEAST8_MAX_ 255
+// PIC16:INT_FAST8_MIN_ (-127 -1)
+// PIC16:INT_FAST8_MAX_ 127
+// PIC16:UINT_FAST8_MAX_ 255
+//
+// PIC16:INT16_MAX_ 32767
+// PIC16:INT16_MIN_ (-32767 -1)
+// PIC16:UINT16_MAX_ 65535
+// PIC16:INT_LEAST16_MIN_ (-32767 -1)
+// PIC16:INT_LEAST16_MAX_ 32767
+// PIC16:UINT_LEAST16_MAX_ 65535
+// PIC16:INT_FAST16_MIN_ (-32767 -1)
+// PIC16:INT_FAST16_MAX_ 32767
+// PIC16:UINT_FAST16_MAX_ 65535
+//
+// PIC16:INT32_MAX_ 2147483647L
+// PIC16:INT32_MIN_ (-2147483647L -1)
+// PIC16:UINT32_MAX_ 4294967295UL
+// PIC16:INT_LEAST32_MIN_ (-2147483647L -1)
+// PIC16:INT_LEAST32_MAX_ 2147483647L
+// PIC16:UINT_LEAST32_MAX_ 4294967295UL
+// PIC16:INT_FAST32_MIN_ (-2147483647L -1)
+// PIC16:INT_FAST32_MAX_ 2147483647L
+// PIC16:UINT_FAST32_MAX_ 4294967295UL
+//
+// PIC16:INT64_MAX_ INT64_MAX
+// PIC16:INT64_MIN_ INT64_MIN
+// PIC16:UINT64_MAX_ UINT64_MAX
+// PIC16:INT_LEAST64_MIN_ INT_LEAST64_MIN
+// PIC16:INT_LEAST64_MAX_ INT_LEAST64_MAX
+// PIC16:UINT_LEAST64_MAX_ UINT_LEAST64_MAX
+// PIC16:INT_FAST64_MIN_ INT_FAST64_MIN
+// PIC16:INT_FAST64_MAX_ INT_FAST64_MAX
+// PIC16:UINT_FAST64_MAX_ UINT_FAST64_MAX
+//
+// PIC16:INTPTR_MIN_ (-32767 -1)
+// PIC16:INTPTR_MAX_ 32767
+// PIC16:UINTPTR_MAX_ 65535
+// PIC16:PTRDIFF_MIN_ (-32767 -1)
+// PIC16:PTRDIFF_MAX_ 32767
+// PIC16:SIZE_MAX_ 65535
+//
+// PIC16:INTMAX_MIN_ (-2147483647L -1)
+// PIC16:INTMAX_MAX_ 2147483647L
+// PIC16:UINTMAX_MAX_ 4294967295UL
+//
+// PIC16:SIG_ATOMIC_MIN_ (-2147483647L -1)
+// PIC16:SIG_ATOMIC_MAX_ 2147483647L
+// PIC16:WINT_MIN_ (-32767 -1)
+// PIC16:WINT_MAX_ 32767
+//
+// PIC16:WCHAR_MAX_ 32767
+// PIC16:WCHAR_MIN_ (-32767 -1)
+//
+// PIC16:INT8_C_(0) 0
+// PIC16:UINT8_C_(0) 0U
+// PIC16:INT16_C_(0) 0
+// PIC16:UINT16_C_(0) 0U
+// PIC16:INT32_C_(0) 0L
+// PIC16:UINT32_C_(0) 0UL
+// PIC16:INT64_C_(0) INT64_C(0)
+// PIC16:UINT64_C_(0) UINT64_C(0)
+//
+// PIC16:INTMAX_C_(0) 0L
+// PIC16:UINTMAX_C_(0) 0UL
+//
+// RUN: %clang_cc1 -E -ffreestanding -triple=powerpc64-none-none %s | FileCheck -check-prefix PPC64 %s
+//
+// PPC64:typedef signed long int int64_t;
+// PPC64:typedef unsigned long int uint64_t;
+// PPC64:typedef int64_t int_least64_t;
+// PPC64:typedef uint64_t uint_least64_t;
+// PPC64:typedef int64_t int_fast64_t;
+// PPC64:typedef uint64_t uint_fast64_t;
+//
+// PPC64:typedef signed int int32_t;
+// PPC64:typedef unsigned int uint32_t;
+// PPC64:typedef int32_t int_least32_t;
+// PPC64:typedef uint32_t uint_least32_t;
+// PPC64:typedef int32_t int_fast32_t;
+// PPC64:typedef uint32_t uint_fast32_t;
+//
+// PPC64:typedef signed short int16_t;
+// PPC64:typedef unsigned short uint16_t;
+// PPC64:typedef int16_t int_least16_t;
+// PPC64:typedef uint16_t uint_least16_t;
+// PPC64:typedef int16_t int_fast16_t;
+// PPC64:typedef uint16_t uint_fast16_t;
+//
+// PPC64:typedef signed char int8_t;
+// PPC64:typedef unsigned char uint8_t;
+// PPC64:typedef int8_t int_least8_t;
+// PPC64:typedef uint8_t uint_least8_t;
+// PPC64:typedef int8_t int_fast8_t;
+// PPC64:typedef uint8_t uint_fast8_t;
+//
+// PPC64:typedef int64_t intptr_t;
+// PPC64:typedef uint64_t uintptr_t;
+//
+// PPC64:typedef int64_t intmax_t;
+// PPC64:typedef uint64_t uintmax_t;
+//
+// PPC64:INT8_MAX_ 127
+// PPC64:INT8_MIN_ (-127 -1)
+// PPC64:UINT8_MAX_ 255
+// PPC64:INT_LEAST8_MIN_ (-127 -1)
+// PPC64:INT_LEAST8_MAX_ 127
+// PPC64:UINT_LEAST8_MAX_ 255
+// PPC64:INT_FAST8_MIN_ (-127 -1)
+// PPC64:INT_FAST8_MAX_ 127
+// PPC64:UINT_FAST8_MAX_ 255
+//
+// PPC64:INT16_MAX_ 32767
+// PPC64:INT16_MIN_ (-32767 -1)
+// PPC64:UINT16_MAX_ 65535
+// PPC64:INT_LEAST16_MIN_ (-32767 -1)
+// PPC64:INT_LEAST16_MAX_ 32767
+// PPC64:UINT_LEAST16_MAX_ 65535
+// PPC64:INT_FAST16_MIN_ (-32767 -1)
+// PPC64:INT_FAST16_MAX_ 32767
+// PPC64:UINT_FAST16_MAX_ 65535
+//
+// PPC64:INT32_MAX_ 2147483647
+// PPC64:INT32_MIN_ (-2147483647 -1)
+// PPC64:UINT32_MAX_ 4294967295U
+// PPC64:INT_LEAST32_MIN_ (-2147483647 -1)
+// PPC64:INT_LEAST32_MAX_ 2147483647
+// PPC64:UINT_LEAST32_MAX_ 4294967295U
+// PPC64:INT_FAST32_MIN_ (-2147483647 -1)
+// PPC64:INT_FAST32_MAX_ 2147483647
+// PPC64:UINT_FAST32_MAX_ 4294967295U
+//
+// PPC64:INT64_MAX_ 9223372036854775807L
+// PPC64:INT64_MIN_ (-9223372036854775807L -1)
+// PPC64:UINT64_MAX_ 18446744073709551615UL
+// PPC64:INT_LEAST64_MIN_ (-9223372036854775807L -1)
+// PPC64:INT_LEAST64_MAX_ 9223372036854775807L
+// PPC64:UINT_LEAST64_MAX_ 18446744073709551615UL
+// PPC64:INT_FAST64_MIN_ (-9223372036854775807L -1)
+// PPC64:INT_FAST64_MAX_ 9223372036854775807L
+// PPC64:UINT_FAST64_MAX_ 18446744073709551615UL
+//
+// PPC64:INTPTR_MIN_ (-9223372036854775807L -1)
+// PPC64:INTPTR_MAX_ 9223372036854775807L
+// PPC64:UINTPTR_MAX_ 18446744073709551615UL
+// PPC64:PTRDIFF_MIN_ (-9223372036854775807L -1)
+// PPC64:PTRDIFF_MAX_ 9223372036854775807L
+// PPC64:SIZE_MAX_ 18446744073709551615UL
+//
+// PPC64:INTMAX_MIN_ (-9223372036854775807L -1)
+// PPC64:INTMAX_MAX_ 9223372036854775807L
+// PPC64:UINTMAX_MAX_ 18446744073709551615UL
+//
+// PPC64:SIG_ATOMIC_MIN_ (-2147483647 -1)
+// PPC64:SIG_ATOMIC_MAX_ 2147483647
+// PPC64:WINT_MIN_ (-2147483647 -1)
+// PPC64:WINT_MAX_ 2147483647
+//
+// PPC64:WCHAR_MAX_ 2147483647
+// PPC64:WCHAR_MIN_ (-2147483647 -1)
+//
+// PPC64:INT8_C_(0) 0
+// PPC64:UINT8_C_(0) 0U
+// PPC64:INT16_C_(0) 0
+// PPC64:UINT16_C_(0) 0U
+// PPC64:INT32_C_(0) 0
+// PPC64:UINT32_C_(0) 0U
+// PPC64:INT64_C_(0) 0L
+// PPC64:UINT64_C_(0) 0UL
+//
+// PPC64:INTMAX_C_(0) 0L
+// PPC64:UINTMAX_C_(0) 0UL
+//
+// RUN: %clang_cc1 -E -ffreestanding -triple=powerpc-none-none %s | FileCheck -check-prefix PPC %s
+//
+//
+// PPC:typedef signed long long int int64_t;
+// PPC:typedef unsigned long long int uint64_t;
+// PPC:typedef int64_t int_least64_t;
+// PPC:typedef uint64_t uint_least64_t;
+// PPC:typedef int64_t int_fast64_t;
+// PPC:typedef uint64_t uint_fast64_t;
+//
+// PPC:typedef signed int int32_t;
+// PPC:typedef unsigned int uint32_t;
+// PPC:typedef int32_t int_least32_t;
+// PPC:typedef uint32_t uint_least32_t;
+// PPC:typedef int32_t int_fast32_t;
+// PPC:typedef uint32_t uint_fast32_t;
+//
+// PPC:typedef signed short int16_t;
+// PPC:typedef unsigned short uint16_t;
+// PPC:typedef int16_t int_least16_t;
+// PPC:typedef uint16_t uint_least16_t;
+// PPC:typedef int16_t int_fast16_t;
+// PPC:typedef uint16_t uint_fast16_t;
+//
+// PPC:typedef signed char int8_t;
+// PPC:typedef unsigned char uint8_t;
+// PPC:typedef int8_t int_least8_t;
+// PPC:typedef uint8_t uint_least8_t;
+// PPC:typedef int8_t int_fast8_t;
+// PPC:typedef uint8_t uint_fast8_t;
+//
+// PPC:typedef int32_t intptr_t;
+// PPC:typedef uint32_t uintptr_t;
+//
+// PPC:typedef int64_t intmax_t;
+// PPC:typedef uint64_t uintmax_t;
+//
+// PPC:INT8_MAX_ 127
+// PPC:INT8_MIN_ (-127 -1)
+// PPC:UINT8_MAX_ 255
+// PPC:INT_LEAST8_MIN_ (-127 -1)
+// PPC:INT_LEAST8_MAX_ 127
+// PPC:UINT_LEAST8_MAX_ 255
+// PPC:INT_FAST8_MIN_ (-127 -1)
+// PPC:INT_FAST8_MAX_ 127
+// PPC:UINT_FAST8_MAX_ 255
+//
+// PPC:INT16_MAX_ 32767
+// PPC:INT16_MIN_ (-32767 -1)
+// PPC:UINT16_MAX_ 65535
+// PPC:INT_LEAST16_MIN_ (-32767 -1)
+// PPC:INT_LEAST16_MAX_ 32767
+// PPC:UINT_LEAST16_MAX_ 65535
+// PPC:INT_FAST16_MIN_ (-32767 -1)
+// PPC:INT_FAST16_MAX_ 32767
+// PPC:UINT_FAST16_MAX_ 65535
+//
+// PPC:INT32_MAX_ 2147483647
+// PPC:INT32_MIN_ (-2147483647 -1)
+// PPC:UINT32_MAX_ 4294967295U
+// PPC:INT_LEAST32_MIN_ (-2147483647 -1)
+// PPC:INT_LEAST32_MAX_ 2147483647
+// PPC:UINT_LEAST32_MAX_ 4294967295U
+// PPC:INT_FAST32_MIN_ (-2147483647 -1)
+// PPC:INT_FAST32_MAX_ 2147483647
+// PPC:UINT_FAST32_MAX_ 4294967295U
+//
+// PPC:INT64_MAX_ 9223372036854775807LL
+// PPC:INT64_MIN_ (-9223372036854775807LL -1)
+// PPC:UINT64_MAX_ 18446744073709551615ULL
+// PPC:INT_LEAST64_MIN_ (-9223372036854775807LL -1)
+// PPC:INT_LEAST64_MAX_ 9223372036854775807LL
+// PPC:UINT_LEAST64_MAX_ 18446744073709551615ULL
+// PPC:INT_FAST64_MIN_ (-9223372036854775807LL -1)
+// PPC:INT_FAST64_MAX_ 9223372036854775807LL
+// PPC:UINT_FAST64_MAX_ 18446744073709551615ULL
+//
+// PPC:INTPTR_MIN_ (-2147483647 -1)
+// PPC:INTPTR_MAX_ 2147483647
+// PPC:UINTPTR_MAX_ 4294967295U
+// PPC:PTRDIFF_MIN_ (-2147483647 -1)
+// PPC:PTRDIFF_MAX_ 2147483647
+// PPC:SIZE_MAX_ 4294967295U
+//
+// PPC:INTMAX_MIN_ (-9223372036854775807LL -1)
+// PPC:INTMAX_MAX_ 9223372036854775807LL
+// PPC:UINTMAX_MAX_ 18446744073709551615ULL
+//
+// PPC:SIG_ATOMIC_MIN_ (-2147483647 -1)
+// PPC:SIG_ATOMIC_MAX_ 2147483647
+// PPC:WINT_MIN_ (-2147483647 -1)
+// PPC:WINT_MAX_ 2147483647
+//
+// PPC:WCHAR_MAX_ 2147483647
+// PPC:WCHAR_MIN_ (-2147483647 -1)
+//
+// PPC:INT8_C_(0) 0
+// PPC:UINT8_C_(0) 0U
+// PPC:INT16_C_(0) 0
+// PPC:UINT16_C_(0) 0U
+// PPC:INT32_C_(0) 0
+// PPC:UINT32_C_(0) 0U
+// PPC:INT64_C_(0) 0LL
+// PPC:UINT64_C_(0) 0ULL
+//
+// PPC:INTMAX_C_(0) 0LL
+// PPC:UINTMAX_C_(0) 0ULL
+//
+// RUN: %clang_cc1 -E -ffreestanding -triple=s390x-none-none %s | FileCheck -check-prefix S390X %s
+//
+// S390X:typedef signed long int int64_t;
+// S390X:typedef unsigned long int uint64_t;
+// S390X:typedef int64_t int_least64_t;
+// S390X:typedef uint64_t uint_least64_t;
+// S390X:typedef int64_t int_fast64_t;
+// S390X:typedef uint64_t uint_fast64_t;
+//
+// S390X:typedef signed int int32_t;
+// S390X:typedef unsigned int uint32_t;
+// S390X:typedef int32_t int_least32_t;
+// S390X:typedef uint32_t uint_least32_t;
+// S390X:typedef int32_t int_fast32_t;
+// S390X:typedef uint32_t uint_fast32_t;
+//
+// S390X:typedef signed short int16_t;
+// S390X:typedef unsigned short uint16_t;
+// S390X:typedef int16_t int_least16_t;
+// S390X:typedef uint16_t uint_least16_t;
+// S390X:typedef int16_t int_fast16_t;
+// S390X:typedef uint16_t uint_fast16_t;
+//
+// S390X:typedef signed char int8_t;
+// S390X:typedef unsigned char uint8_t;
+// S390X:typedef int8_t int_least8_t;
+// S390X:typedef uint8_t uint_least8_t;
+// S390X:typedef int8_t int_fast8_t;
+// S390X:typedef uint8_t uint_fast8_t;
+//
+// S390X:typedef int64_t intptr_t;
+// S390X:typedef uint64_t uintptr_t;
+//
+// S390X:typedef int64_t intmax_t;
+// S390X:typedef uint64_t uintmax_t;
+//
+// S390X:INT8_MAX_ 127
+// S390X:INT8_MIN_ (-127 -1)
+// S390X:UINT8_MAX_ 255
+// S390X:INT_LEAST8_MIN_ (-127 -1)
+// S390X:INT_LEAST8_MAX_ 127
+// S390X:UINT_LEAST8_MAX_ 255
+// S390X:INT_FAST8_MIN_ (-127 -1)
+// S390X:INT_FAST8_MAX_ 127
+// S390X:UINT_FAST8_MAX_ 255
+//
+// S390X:INT16_MAX_ 32767
+// S390X:INT16_MIN_ (-32767 -1)
+// S390X:UINT16_MAX_ 65535
+// S390X:INT_LEAST16_MIN_ (-32767 -1)
+// S390X:INT_LEAST16_MAX_ 32767
+// S390X:UINT_LEAST16_MAX_ 65535
+// S390X:INT_FAST16_MIN_ (-32767 -1)
+// S390X:INT_FAST16_MAX_ 32767
+// S390X:UINT_FAST16_MAX_ 65535
+//
+// S390X:INT32_MAX_ 2147483647
+// S390X:INT32_MIN_ (-2147483647 -1)
+// S390X:UINT32_MAX_ 4294967295U
+// S390X:INT_LEAST32_MIN_ (-2147483647 -1)
+// S390X:INT_LEAST32_MAX_ 2147483647
+// S390X:UINT_LEAST32_MAX_ 4294967295U
+// S390X:INT_FAST32_MIN_ (-2147483647 -1)
+// S390X:INT_FAST32_MAX_ 2147483647
+// S390X:UINT_FAST32_MAX_ 4294967295U
+//
+// S390X:INT64_MAX_ 9223372036854775807L
+// S390X:INT64_MIN_ (-9223372036854775807L -1)
+// S390X:UINT64_MAX_ 18446744073709551615UL
+// S390X:INT_LEAST64_MIN_ (-9223372036854775807L -1)
+// S390X:INT_LEAST64_MAX_ 9223372036854775807L
+// S390X:UINT_LEAST64_MAX_ 18446744073709551615UL
+// S390X:INT_FAST64_MIN_ (-9223372036854775807L -1)
+// S390X:INT_FAST64_MAX_ 9223372036854775807L
+// S390X:UINT_FAST64_MAX_ 18446744073709551615UL
+//
+// S390X:INTPTR_MIN_ (-9223372036854775807L -1)
+// S390X:INTPTR_MAX_ 9223372036854775807L
+// S390X:UINTPTR_MAX_ 18446744073709551615UL
+// S390X:PTRDIFF_MIN_ (-9223372036854775807L -1)
+// S390X:PTRDIFF_MAX_ 9223372036854775807L
+// S390X:SIZE_MAX_ 18446744073709551615UL
+//
+// S390X:INTMAX_MIN_ (-9223372036854775807L -1)
+// S390X:INTMAX_MAX_ 9223372036854775807L
+// S390X:UINTMAX_MAX_ 18446744073709551615UL
+//
+// S390X:SIG_ATOMIC_MIN_ (-2147483647 -1)
+// S390X:SIG_ATOMIC_MAX_ 2147483647
+// S390X:WINT_MIN_ (-2147483647 -1)
+// S390X:WINT_MAX_ 2147483647
+//
+// S390X:WCHAR_MAX_ 2147483647
+// S390X:WCHAR_MIN_ (-2147483647 -1)
+//
+// S390X:INT8_C_(0) 0
+// S390X:UINT8_C_(0) 0U
+// S390X:INT16_C_(0) 0
+// S390X:UINT16_C_(0) 0U
+// S390X:INT32_C_(0) 0
+// S390X:UINT32_C_(0) 0U
+// S390X:INT64_C_(0) 0L
+// S390X:UINT64_C_(0) 0UL
+//
+// S390X:INTMAX_C_(0) 0L
+// S390X:UINTMAX_C_(0) 0UL
+//
+// RUN: %clang_cc1 -E -ffreestanding -triple=sparc-none-none %s | FileCheck -check-prefix SPARC %s
+//
+// SPARC:typedef signed long long int int64_t;
+// SPARC:typedef unsigned long long int uint64_t;
+// SPARC:typedef int64_t int_least64_t;
+// SPARC:typedef uint64_t uint_least64_t;
+// SPARC:typedef int64_t int_fast64_t;
+// SPARC:typedef uint64_t uint_fast64_t;
+//
+// SPARC:typedef signed int int32_t;
+// SPARC:typedef unsigned int uint32_t;
+// SPARC:typedef int32_t int_least32_t;
+// SPARC:typedef uint32_t uint_least32_t;
+// SPARC:typedef int32_t int_fast32_t;
+// SPARC:typedef uint32_t uint_fast32_t;
+//
+// SPARC:typedef signed short int16_t;
+// SPARC:typedef unsigned short uint16_t;
+// SPARC:typedef int16_t int_least16_t;
+// SPARC:typedef uint16_t uint_least16_t;
+// SPARC:typedef int16_t int_fast16_t;
+// SPARC:typedef uint16_t uint_fast16_t;
+//
+// SPARC:typedef signed char int8_t;
+// SPARC:typedef unsigned char uint8_t;
+// SPARC:typedef int8_t int_least8_t;
+// SPARC:typedef uint8_t uint_least8_t;
+// SPARC:typedef int8_t int_fast8_t;
+// SPARC:typedef uint8_t uint_fast8_t;
+//
+// SPARC:typedef int32_t intptr_t;
+// SPARC:typedef uint32_t uintptr_t;
+//
+// SPARC:typedef int64_t intmax_t;
+// SPARC:typedef uint64_t uintmax_t;
+//
+// SPARC:INT8_MAX_ 127
+// SPARC:INT8_MIN_ (-127 -1)
+// SPARC:UINT8_MAX_ 255
+// SPARC:INT_LEAST8_MIN_ (-127 -1)
+// SPARC:INT_LEAST8_MAX_ 127
+// SPARC:UINT_LEAST8_MAX_ 255
+// SPARC:INT_FAST8_MIN_ (-127 -1)
+// SPARC:INT_FAST8_MAX_ 127
+// SPARC:UINT_FAST8_MAX_ 255
+//
+// SPARC:INT16_MAX_ 32767
+// SPARC:INT16_MIN_ (-32767 -1)
+// SPARC:UINT16_MAX_ 65535
+// SPARC:INT_LEAST16_MIN_ (-32767 -1)
+// SPARC:INT_LEAST16_MAX_ 32767
+// SPARC:UINT_LEAST16_MAX_ 65535
+// SPARC:INT_FAST16_MIN_ (-32767 -1)
+// SPARC:INT_FAST16_MAX_ 32767
+// SPARC:UINT_FAST16_MAX_ 65535
+//
+// SPARC:INT32_MAX_ 2147483647
+// SPARC:INT32_MIN_ (-2147483647 -1)
+// SPARC:UINT32_MAX_ 4294967295U
+// SPARC:INT_LEAST32_MIN_ (-2147483647 -1)
+// SPARC:INT_LEAST32_MAX_ 2147483647
+// SPARC:UINT_LEAST32_MAX_ 4294967295U
+// SPARC:INT_FAST32_MIN_ (-2147483647 -1)
+// SPARC:INT_FAST32_MAX_ 2147483647
+// SPARC:UINT_FAST32_MAX_ 4294967295U
+//
+// SPARC:INT64_MAX_ 9223372036854775807LL
+// SPARC:INT64_MIN_ (-9223372036854775807LL -1)
+// SPARC:UINT64_MAX_ 18446744073709551615ULL
+// SPARC:INT_LEAST64_MIN_ (-9223372036854775807LL -1)
+// SPARC:INT_LEAST64_MAX_ 9223372036854775807LL
+// SPARC:UINT_LEAST64_MAX_ 18446744073709551615ULL
+// SPARC:INT_FAST64_MIN_ (-9223372036854775807LL -1)
+// SPARC:INT_FAST64_MAX_ 9223372036854775807LL
+// SPARC:UINT_FAST64_MAX_ 18446744073709551615ULL
+//
+// SPARC:INTPTR_MIN_ (-2147483647 -1)
+// SPARC:INTPTR_MAX_ 2147483647
+// SPARC:UINTPTR_MAX_ 4294967295U
+// SPARC:PTRDIFF_MIN_ (-2147483647 -1)
+// SPARC:PTRDIFF_MAX_ 2147483647
+// SPARC:SIZE_MAX_ 4294967295U
+//
+// SPARC:INTMAX_MIN_ (-9223372036854775807LL -1)
+// SPARC:INTMAX_MAX_ 9223372036854775807LL
+// SPARC:UINTMAX_MAX_ 18446744073709551615ULL
+//
+// SPARC:SIG_ATOMIC_MIN_ (-2147483647 -1)
+// SPARC:SIG_ATOMIC_MAX_ 2147483647
+// SPARC:WINT_MIN_ (-2147483647 -1)
+// SPARC:WINT_MAX_ 2147483647
+//
+// SPARC:WCHAR_MAX_ 2147483647
+// SPARC:WCHAR_MIN_ (-2147483647 -1)
+//
+// SPARC:INT8_C_(0) 0
+// SPARC:UINT8_C_(0) 0U
+// SPARC:INT16_C_(0) 0
+// SPARC:UINT16_C_(0) 0U
+// SPARC:INT32_C_(0) 0
+// SPARC:UINT32_C_(0) 0U
+// SPARC:INT64_C_(0) 0LL
+// SPARC:UINT64_C_(0) 0ULL
+//
+// SPARC:INTMAX_C_(0) 0LL
+// SPARC:UINTMAX_C_(0) 0ULL
+//
+// RUN: %clang_cc1 -E -ffreestanding -triple=tce-none-none %s | FileCheck -check-prefix TCE %s
+//
+// TCE:typedef signed int int32_t;
+// TCE:typedef unsigned int uint32_t;
+// TCE:typedef int32_t int_least32_t;
+// TCE:typedef uint32_t uint_least32_t;
+// TCE:typedef int32_t int_fast32_t;
+// TCE:typedef uint32_t uint_fast32_t;
+//
+// TCE:typedef signed short int16_t;
+// TCE:typedef unsigned short uint16_t;
+// TCE:typedef int16_t int_least16_t;
+// TCE:typedef uint16_t uint_least16_t;
+// TCE:typedef int16_t int_fast16_t;
+// TCE:typedef uint16_t uint_fast16_t;
+//
+// TCE:typedef signed char int8_t;
+// TCE:typedef unsigned char uint8_t;
+// TCE:typedef int8_t int_least8_t;
+// TCE:typedef uint8_t uint_least8_t;
+// TCE:typedef int8_t int_fast8_t;
+// TCE:typedef uint8_t uint_fast8_t;
+//
+// TCE:typedef int32_t intptr_t;
+// TCE:typedef uint32_t uintptr_t;
+//
+// TCE:typedef int32_t intmax_t;
+// TCE:typedef uint32_t uintmax_t;
+//
+// TCE:INT8_MAX_ 127
+// TCE:INT8_MIN_ (-127 -1)
+// TCE:UINT8_MAX_ 255
+// TCE:INT_LEAST8_MIN_ (-127 -1)
+// TCE:INT_LEAST8_MAX_ 127
+// TCE:UINT_LEAST8_MAX_ 255
+// TCE:INT_FAST8_MIN_ (-127 -1)
+// TCE:INT_FAST8_MAX_ 127
+// TCE:UINT_FAST8_MAX_ 255
+//
+// TCE:INT16_MAX_ 32767
+// TCE:INT16_MIN_ (-32767 -1)
+// TCE:UINT16_MAX_ 65535
+// TCE:INT_LEAST16_MIN_ (-32767 -1)
+// TCE:INT_LEAST16_MAX_ 32767
+// TCE:UINT_LEAST16_MAX_ 65535
+// TCE:INT_FAST16_MIN_ (-32767 -1)
+// TCE:INT_FAST16_MAX_ 32767
+// TCE:UINT_FAST16_MAX_ 65535
+//
+// TCE:INT32_MAX_ 2147483647
+// TCE:INT32_MIN_ (-2147483647 -1)
+// TCE:UINT32_MAX_ 4294967295U
+// TCE:INT_LEAST32_MIN_ (-2147483647 -1)
+// TCE:INT_LEAST32_MAX_ 2147483647
+// TCE:UINT_LEAST32_MAX_ 4294967295U
+// TCE:INT_FAST32_MIN_ (-2147483647 -1)
+// TCE:INT_FAST32_MAX_ 2147483647
+// TCE:UINT_FAST32_MAX_ 4294967295U
+//
+// TCE:INT64_MAX_ INT64_MAX
+// TCE:INT64_MIN_ INT64_MIN
+// TCE:UINT64_MAX_ UINT64_MAX
+// TCE:INT_LEAST64_MIN_ INT_LEAST64_MIN
+// TCE:INT_LEAST64_MAX_ INT_LEAST64_MAX
+// TCE:UINT_LEAST64_MAX_ UINT_LEAST64_MAX
+// TCE:INT_FAST64_MIN_ INT_FAST64_MIN
+// TCE:INT_FAST64_MAX_ INT_FAST64_MAX
+// TCE:UINT_FAST64_MAX_ UINT_FAST64_MAX
+//
+// TCE:INTPTR_MIN_ (-2147483647 -1)
+// TCE:INTPTR_MAX_ 2147483647
+// TCE:UINTPTR_MAX_ 4294967295U
+// TCE:PTRDIFF_MIN_ (-2147483647 -1)
+// TCE:PTRDIFF_MAX_ 2147483647
+// TCE:SIZE_MAX_ 4294967295U
+//
+// TCE:INTMAX_MIN_ (-2147483647 -1)
+// TCE:INTMAX_MAX_ 2147483647
+// TCE:UINTMAX_MAX_ 4294967295U
+//
+// TCE:SIG_ATOMIC_MIN_ (-2147483647 -1)
+// TCE:SIG_ATOMIC_MAX_ 2147483647
+// TCE:WINT_MIN_ (-2147483647 -1)
+// TCE:WINT_MAX_ 2147483647
+//
+// TCE:WCHAR_MAX_ 2147483647
+// TCE:WCHAR_MIN_ (-2147483647 -1)
+//
+// TCE:INT8_C_(0) 0
+// TCE:UINT8_C_(0) 0U
+// TCE:INT16_C_(0) 0
+// TCE:UINT16_C_(0) 0U
+// TCE:INT32_C_(0) 0
+// TCE:UINT32_C_(0) 0U
+// TCE:INT64_C_(0) INT64_C(0)
+// TCE:UINT64_C_(0) UINT64_C(0)
+//
+// TCE:INTMAX_C_(0) 0
+// TCE:UINTMAX_C_(0) 0U
+//
+// RUN: %clang_cc1 -E -ffreestanding -triple=x86_64-none-none %s | FileCheck -check-prefix X86_64 %s
+//
+//
+// X86_64:typedef signed long int int64_t;
+// X86_64:typedef unsigned long int uint64_t;
+// X86_64:typedef int64_t int_least64_t;
+// X86_64:typedef uint64_t uint_least64_t;
+// X86_64:typedef int64_t int_fast64_t;
+// X86_64:typedef uint64_t uint_fast64_t;
+//
+// X86_64:typedef signed int int32_t;
+// X86_64:typedef unsigned int uint32_t;
+// X86_64:typedef int32_t int_least32_t;
+// X86_64:typedef uint32_t uint_least32_t;
+// X86_64:typedef int32_t int_fast32_t;
+// X86_64:typedef uint32_t uint_fast32_t;
+//
+// X86_64:typedef signed short int16_t;
+// X86_64:typedef unsigned short uint16_t;
+// X86_64:typedef int16_t int_least16_t;
+// X86_64:typedef uint16_t uint_least16_t;
+// X86_64:typedef int16_t int_fast16_t;
+// X86_64:typedef uint16_t uint_fast16_t;
+//
+// X86_64:typedef signed char int8_t;
+// X86_64:typedef unsigned char uint8_t;
+// X86_64:typedef int8_t int_least8_t;
+// X86_64:typedef uint8_t uint_least8_t;
+// X86_64:typedef int8_t int_fast8_t;
+// X86_64:typedef uint8_t uint_fast8_t;
+//
+// X86_64:typedef int64_t intptr_t;
+// X86_64:typedef uint64_t uintptr_t;
+//
+// X86_64:typedef int64_t intmax_t;
+// X86_64:typedef uint64_t uintmax_t;
+//
+// X86_64:INT8_MAX_ 127
+// X86_64:INT8_MIN_ (-127 -1)
+// X86_64:UINT8_MAX_ 255
+// X86_64:INT_LEAST8_MIN_ (-127 -1)
+// X86_64:INT_LEAST8_MAX_ 127
+// X86_64:UINT_LEAST8_MAX_ 255
+// X86_64:INT_FAST8_MIN_ (-127 -1)
+// X86_64:INT_FAST8_MAX_ 127
+// X86_64:UINT_FAST8_MAX_ 255
+//
+// X86_64:INT16_MAX_ 32767
+// X86_64:INT16_MIN_ (-32767 -1)
+// X86_64:UINT16_MAX_ 65535
+// X86_64:INT_LEAST16_MIN_ (-32767 -1)
+// X86_64:INT_LEAST16_MAX_ 32767
+// X86_64:UINT_LEAST16_MAX_ 65535
+// X86_64:INT_FAST16_MIN_ (-32767 -1)
+// X86_64:INT_FAST16_MAX_ 32767
+// X86_64:UINT_FAST16_MAX_ 65535
+//
+// X86_64:INT32_MAX_ 2147483647
+// X86_64:INT32_MIN_ (-2147483647 -1)
+// X86_64:UINT32_MAX_ 4294967295U
+// X86_64:INT_LEAST32_MIN_ (-2147483647 -1)
+// X86_64:INT_LEAST32_MAX_ 2147483647
+// X86_64:UINT_LEAST32_MAX_ 4294967295U
+// X86_64:INT_FAST32_MIN_ (-2147483647 -1)
+// X86_64:INT_FAST32_MAX_ 2147483647
+// X86_64:UINT_FAST32_MAX_ 4294967295U
+//
+// X86_64:INT64_MAX_ 9223372036854775807L
+// X86_64:INT64_MIN_ (-9223372036854775807L -1)
+// X86_64:UINT64_MAX_ 18446744073709551615UL
+// X86_64:INT_LEAST64_MIN_ (-9223372036854775807L -1)
+// X86_64:INT_LEAST64_MAX_ 9223372036854775807L
+// X86_64:UINT_LEAST64_MAX_ 18446744073709551615UL
+// X86_64:INT_FAST64_MIN_ (-9223372036854775807L -1)
+// X86_64:INT_FAST64_MAX_ 9223372036854775807L
+// X86_64:UINT_FAST64_MAX_ 18446744073709551615UL
+//
+// X86_64:INTPTR_MIN_ (-9223372036854775807L -1)
+// X86_64:INTPTR_MAX_ 9223372036854775807L
+// X86_64:UINTPTR_MAX_ 18446744073709551615UL
+// X86_64:PTRDIFF_MIN_ (-9223372036854775807L -1)
+// X86_64:PTRDIFF_MAX_ 9223372036854775807L
+// X86_64:SIZE_MAX_ 18446744073709551615UL
+//
+// X86_64:INTMAX_MIN_ (-9223372036854775807L -1)
+// X86_64:INTMAX_MAX_ 9223372036854775807L
+// X86_64:UINTMAX_MAX_ 18446744073709551615UL
+//
+// X86_64:SIG_ATOMIC_MIN_ (-2147483647 -1)
+// X86_64:SIG_ATOMIC_MAX_ 2147483647
+// X86_64:WINT_MIN_ (-2147483647 -1)
+// X86_64:WINT_MAX_ 2147483647
+//
+// X86_64:WCHAR_MAX_ 2147483647
+// X86_64:WCHAR_MIN_ (-2147483647 -1)
+//
+// X86_64:INT8_C_(0) 0
+// X86_64:UINT8_C_(0) 0U
+// X86_64:INT16_C_(0) 0
+// X86_64:UINT16_C_(0) 0U
+// X86_64:INT32_C_(0) 0
+// X86_64:UINT32_C_(0) 0U
+// X86_64:INT64_C_(0) 0L
+// X86_64:UINT64_C_(0) 0UL
+//
+// X86_64:INTMAX_C_(0) 0L
+// X86_64:UINTMAX_C_(0) 0UL
+//
+//
+// stdint.h forms several macro definitions by pasting together identifiers
+// to form names (eg. int32_t is formed from int ## 32 ## _t). The following 
+// case tests that these joining operations are performed correctly even if
+// the identifiers used in the operations (int, uint, _t, INT, UINT, _MIN,
+// _MAX, and _C(v)) are themselves macros.
+//
+// RUN: %clang_cc1 -E -ffreestanding -Dint=a -Duint=b -D_t=c -DINT=d -DUINT=e -D_MIN=f -D_MAX=g '-D_C(v)=h' -triple=i386-none-none %s | FileCheck -check-prefix JOIN %s
+// JOIN:typedef int32_t intptr_t;
+// JOIN:typedef uint32_t uintptr_t;
+// JOIN:typedef int64_t intmax_t;
+// JOIN:typedef uint64_t uintmax_t;
+// JOIN:INTPTR_MIN_ (-2147483647 -1)
+// JOIN:INTPTR_MAX_ 2147483647
+// JOIN:UINTPTR_MAX_ 4294967295U
+// JOIN:PTRDIFF_MIN_ (-2147483647 -1)
+// JOIN:PTRDIFF_MAX_ 2147483647
+// JOIN:SIZE_MAX_ 4294967295U
+// JOIN:INTMAX_MIN_ (-9223372036854775807LL -1)
+// JOIN:INTMAX_MAX_ 9223372036854775807LL
+// JOIN:UINTMAX_MAX_ 18446744073709551615ULL
+// JOIN:SIG_ATOMIC_MIN_ (-2147483647 -1)
+// JOIN:SIG_ATOMIC_MAX_ 2147483647
+// JOIN:WINT_MIN_ (-2147483647 -1)
+// JOIN:WINT_MAX_ 2147483647
+// JOIN:WCHAR_MAX_ 2147483647
+// JOIN:WCHAR_MIN_ (-2147483647 -1)
+// JOIN:INTMAX_C_(0) 0LL
+// JOIN:UINTMAX_C_(0) 0ULL
+
+#include <stdint.h>
+
+INT8_MAX_ INT8_MAX
+INT8_MIN_ INT8_MIN
+UINT8_MAX_ UINT8_MAX
+INT_LEAST8_MIN_ INT_LEAST8_MIN
+INT_LEAST8_MAX_ INT_LEAST8_MAX
+UINT_LEAST8_MAX_ UINT_LEAST8_MAX
+INT_FAST8_MIN_ INT_FAST8_MIN
+INT_FAST8_MAX_ INT_FAST8_MAX
+UINT_FAST8_MAX_ UINT_FAST8_MAX
+
+INT16_MAX_ INT16_MAX
+INT16_MIN_ INT16_MIN
+UINT16_MAX_ UINT16_MAX
+INT_LEAST16_MIN_ INT_LEAST16_MIN
+INT_LEAST16_MAX_ INT_LEAST16_MAX
+UINT_LEAST16_MAX_ UINT_LEAST16_MAX
+INT_FAST16_MIN_ INT_FAST16_MIN
+INT_FAST16_MAX_ INT_FAST16_MAX
+UINT_FAST16_MAX_ UINT_FAST16_MAX
+
+INT32_MAX_ INT32_MAX
+INT32_MIN_ INT32_MIN
+UINT32_MAX_ UINT32_MAX
+INT_LEAST32_MIN_ INT_LEAST32_MIN
+INT_LEAST32_MAX_ INT_LEAST32_MAX
+UINT_LEAST32_MAX_ UINT_LEAST32_MAX
+INT_FAST32_MIN_ INT_FAST32_MIN
+INT_FAST32_MAX_ INT_FAST32_MAX
+UINT_FAST32_MAX_ UINT_FAST32_MAX
+
+INT64_MAX_ INT64_MAX
+INT64_MIN_ INT64_MIN
+UINT64_MAX_ UINT64_MAX
+INT_LEAST64_MIN_ INT_LEAST64_MIN
+INT_LEAST64_MAX_ INT_LEAST64_MAX
+UINT_LEAST64_MAX_ UINT_LEAST64_MAX
+INT_FAST64_MIN_ INT_FAST64_MIN
+INT_FAST64_MAX_ INT_FAST64_MAX
+UINT_FAST64_MAX_ UINT_FAST64_MAX
+
+INTPTR_MIN_ INTPTR_MIN
+INTPTR_MAX_ INTPTR_MAX
+UINTPTR_MAX_ UINTPTR_MAX
+PTRDIFF_MIN_ PTRDIFF_MIN
+PTRDIFF_MAX_ PTRDIFF_MAX
+SIZE_MAX_ SIZE_MAX
+
+INTMAX_MIN_ INTMAX_MIN
+INTMAX_MAX_ INTMAX_MAX
+UINTMAX_MAX_ UINTMAX_MAX
+
+SIG_ATOMIC_MIN_ SIG_ATOMIC_MIN
+SIG_ATOMIC_MAX_ SIG_ATOMIC_MAX
+WINT_MIN_ WINT_MIN
+WINT_MAX_ WINT_MAX
+
+WCHAR_MAX_ WCHAR_MAX
+WCHAR_MIN_ WCHAR_MIN
+
+INT8_C_(0) INT8_C(0)
+UINT8_C_(0) UINT8_C(0)
+INT16_C_(0) INT16_C(0)
+UINT16_C_(0) UINT16_C(0)
+INT32_C_(0) INT32_C(0)
+UINT32_C_(0) UINT32_C(0)
+INT64_C_(0) INT64_C(0)
+UINT64_C_(0) UINT64_C(0)
+
+INTMAX_C_(0) INTMAX_C(0)
+UINTMAX_C_(0) UINTMAX_C(0)
diff --git a/test/Preprocessor/stringize_misc.c b/test/Preprocessor/stringize_misc.c
new file mode 100644
index 0000000..6c2c78d
--- /dev/null
+++ b/test/Preprocessor/stringize_misc.c
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -E %s | FileCheck -strict-whitespace %s
+
+#define M(x, y) #x #y
+
+M( f(1, 2), g((x=y++, y))) 
+// CHECK: "f(1, 2)" "g((x=y++, y))"
+
+M( {a=1 , b=2;} ) /* A semicolon is not a comma */ 
+// CHECK: "{a=1" "b=2;}"
+
+M( <, [ ) /* Passes the arguments < and [ */ 
+// CHECK: "<" "["
+
+M( (,), (...) ) /* Passes the arguments (,) and (...) */ 
+// CHECK: "(,)" "(...)"
+
+#define START_END(start, end) start c=3; end 
+
+START_END( {a=1 , b=2;} ) /* braces are not parentheses */ 
+// CHECK: {a=1 c=3; b=2;}
+
+/* 
+ * To pass a comma token as an argument it is 
+ * necessary to write: 
+ */ 
+#define COMMA , 
+ 
+M(a COMMA b, (a, b)) 
+// CHECK: "a COMMA b" "(a, b)"
+
diff --git a/test/Preprocessor/stringize_space.c b/test/Preprocessor/stringize_space.c
new file mode 100644
index 0000000..263cff8
--- /dev/null
+++ b/test/Preprocessor/stringize_space.c
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -E %s | grep -- '-"" , - "" , -"" , - ""'
+
+#define A(b) -#b  ,  - #b  ,  -# b  ,  - # b
+A()
diff --git a/test/Preprocessor/stringize_space2.c b/test/Preprocessor/stringize_space2.c
new file mode 100644
index 0000000..a87d78e
--- /dev/null
+++ b/test/Preprocessor/stringize_space2.c
@@ -0,0 +1,6 @@
+/* RUN: %clang_cc1 -E %s | grep 'a c'
+ */
+#define t(x) #x
+t(a
+c)
+
diff --git a/test/Preprocessor/undef-error.c b/test/Preprocessor/undef-error.c
new file mode 100644
index 0000000..ad611de
--- /dev/null
+++ b/test/Preprocessor/undef-error.c
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 %s -pedantic-errors -verify 
+// PR2045
+
+#define b
+/* expected-error {{extra tokens at end of #undef directive}} */ #undef a b
diff --git a/test/Preprocessor/unterminated.c b/test/Preprocessor/unterminated.c
new file mode 100644
index 0000000..9180653
--- /dev/null
+++ b/test/Preprocessor/unterminated.c
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -E -verify %s
+// PR3096
+#ifdef FOO // expected-error {{unterminated conditional directive}}
+/* /* */
+
diff --git a/test/Preprocessor/x86_target_features.c b/test/Preprocessor/x86_target_features.c
new file mode 100644
index 0000000..f39c220
--- /dev/null
+++ b/test/Preprocessor/x86_target_features.c
@@ -0,0 +1,34 @@
+// FIXME: Use -triple, not -ccc-host-triple.
+
+// RUN: %clang -ccc-host-triple i386-unknown-unknown -march=core2 -msse4 -x c -E -dM -o %t %s
+// RUN: grep '#define __SSE2_MATH__ 1' %t
+// RUN: grep '#define __SSE2__ 1' %t
+// RUN: grep '#define __SSE3__ 1' %t
+// RUN: grep '#define __SSE4_1__ 1' %t
+// RUN: grep '#define __SSE4_2__ 1' %t
+// RUN: grep '#define __SSE_MATH__ 1' %t
+// RUN: grep '#define __SSE__ 1' %t
+// RUN: grep '#define __SSSE3__ 1' %t
+
+// RUN: %clang -ccc-host-triple i386-unknown-unknown -march=core2 -msse4 -mno-sse2 -x c -E -dM -o %t %s
+// RUN: grep '#define __SSE2_MATH__ 1' %t | count 0
+// RUN: grep '#define __SSE2__ 1' %t | count 0
+// RUN: grep '#define __SSE3__ 1' %t | count 0
+// RUN: grep '#define __SSE4_1__ 1' %t | count 0
+// RUN: grep '#define __SSE4_2__ 1' %t | count 0
+// RUN: grep '#define __SSE_MATH__ 1' %t
+// RUN: grep '#define __SSE__ 1' %t
+// RUN: grep '#define __SSSE3__ 1' %t | count 0
+
+// RUN: %clang -ccc-host-triple i386-unknown-unknown -march=pentium-m -x c -E -dM -o %t %s
+// RUN: grep '#define __SSE2_MATH__ 1' %t
+// RUN: grep '#define __SSE2__ 1' %t
+// RUN: grep '#define __SSE3__ 1' %t | count 0
+// RUN: grep '#define __SSE4_1__ 1' %t | count 0
+// RUN: grep '#define __SSE4_2__ 1' %t | count 0
+// RUN: grep '#define __SSE_MATH__ 1' %t
+// RUN: grep '#define __SSE__ 1' %t
+// RUN: grep '#define __SSSE3__ 1' %t | count 0
+
+
+
diff --git a/test/Rewriter/blockcast3.mm b/test/Rewriter/blockcast3.mm
new file mode 100644
index 0000000..97f417c
--- /dev/null
+++ b/test/Rewriter/blockcast3.mm
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -x objective-c++ -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp
+// RUN: FileCheck -check-prefix LP --input-file=%t-rw.cpp %s
+// radar 7607781
+
+typedef struct {
+	int a;
+	int b;
+} mystruct;
+	
+void g(int (^block)(mystruct s)) {
+	mystruct x;
+	int v = block(x);
+}
+
+void f(const void **arg) {
+	__block const void **q = arg;
+	g(^(mystruct s){
+		*q++ = (void*)s.a;
+		return 314;
+		});
+}
+
+// CHECK-LP: (struct __Block_byref_q_0 *)&q
diff --git a/test/Rewriter/crash.m b/test/Rewriter/crash.m
new file mode 100644
index 0000000..107b7a5
--- /dev/null
+++ b/test/Rewriter/crash.m
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -rewrite-objc -o - %s
+// rdar://5950938
+@interface NSArray {}
++ (id)arrayWithObjects:(id)firstObj, ...;
+@end
+
+@interface NSConstantString {}
+@end
+
+int main() {
+    id foo = [NSArray arrayWithObjects:@"1", @"2", @"3", @"4", @"5", @"6", @"7", @"8", @"9", @"10", @"11", @"12", 0];
+    return 0;
+}
+
+// rdar://6291588
+@protocol A
+@end
+
+@interface Foo
+@end
+
+void func() {
+  id <A> obj = (id <A>)[Foo bar];
+}
+
diff --git a/test/Rewriter/dllimport-typedef.c b/test/Rewriter/dllimport-typedef.c
new file mode 100644
index 0000000..b86fa4a
--- /dev/null
+++ b/test/Rewriter/dllimport-typedef.c
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -triple i686-pc-win32 -fms-extensions -fsyntax-only %s 2>&1 | FileCheck -check-prefix=CHECK-NEG %s
+// RUN: %clang_cc1 -triple i686-pc-win32 -fsyntax-only %s 2>&1 | FileCheck -check-prefix=CHECK-POS %s
+
+// Do not report an error with including dllimport in the typedef when -fms-extensions is specified.
+// Addresses <rdar://problem/7653870>.
+typedef __declspec(dllimport) int CB(void);
+
+// This function is added just to trigger a diagnostic.  This way we can test how many
+// diagnostics we expect.
+void bar() { return 1; }
+
+// CHECK-NEG: warning: void function 'bar' should not return a value
+// CHECK-NEG: 1 warning generated
+// CHECK-POS: warning: 'dllimport' attribute only applies to variable and function type
+// CHECK-POS: warning: void function 'bar' should not return a value
+// CHECK-POS: 2 warnings generated
+
diff --git a/test/Rewriter/finally.m b/test/Rewriter/finally.m
new file mode 100644
index 0000000..67774b5
--- /dev/null
+++ b/test/Rewriter/finally.m
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -rewrite-objc -verify %s -o -
+
+int main() {
+  @try {
+    printf("executing try"); // expected-warning{{implicitly declaring C library function 'printf' with type 'int (char const *, ...)'}} \
+        // expected-note{{please include the header <stdio.h> or explicitly provide a declaration for 'printf'}}
+    return(0); // expected-warning{{rewriter doesn't support user-specified control flow semantics for @try/@finally (code may not execute properly)}}
+  } @finally {
+    printf("executing finally");
+  }
+  while (1) {
+    @try {
+      printf("executing try");
+      break;
+    } @finally {
+      printf("executing finally");
+    }
+    printf("executing after finally block");
+  }
+  @try {
+    printf("executing try");
+  } @finally {
+    printf("executing finally");
+  }
+  return 0;
+}
+
+void test_sync_with_implicit_finally() {
+    id foo;
+    @synchronized (foo) {
+        return; // The rewriter knows how to generate code for implicit finally
+    }
+}
+
+void test2_try_with_implicit_finally() {
+    @try {
+        return; // The rewriter knows how to generate code for implicit finally
+    } @catch (id e) {
+        
+    }
+}
+
diff --git a/test/Rewriter/id-test-3.m b/test/Rewriter/id-test-3.m
new file mode 100644
index 0000000..8557f2b
--- /dev/null
+++ b/test/Rewriter/id-test-3.m
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -rewrite-objc %s -o -
+
+@protocol P
+- (id<P>) Meth: (id<P>) Arg;
+@end
+
+@interface INTF<P>
+- (id<P>)IMeth;
+@end
+
+@implementation INTF
+- (id<P>)IMeth { return [(id<P>)self Meth: (id<P>)0]; }
+- (id<P>) Meth : (id<P>) Arg { return 0; }
+@end
diff --git a/test/Rewriter/ivar-encoding-1.m b/test/Rewriter/ivar-encoding-1.m
new file mode 100644
index 0000000..af11ce2
--- /dev/null
+++ b/test/Rewriter/ivar-encoding-1.m
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -rewrite-objc %s -o -
+
+@interface Intf
+{
+  id ivar;
+  id ivar1[12];
+
+  id **ivar3;
+
+  id (*ivar4) (id, id);
+}
+@end
+
+@implementation Intf
+@end
diff --git a/test/Rewriter/ivar-encoding-2.m b/test/Rewriter/ivar-encoding-2.m
new file mode 100644
index 0000000..4650bde
--- /dev/null
+++ b/test/Rewriter/ivar-encoding-2.m
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -rewrite-objc %s -o -
+
+@implementation Intf
+{
+  id ivar;
+  id ivar1[12];
+
+  id **ivar3;
+
+  id (*ivar4) (id, id);
+}
+@end
diff --git a/test/Rewriter/metadata-test-1.m b/test/Rewriter/metadata-test-1.m
new file mode 100644
index 0000000..5dc1a33
--- /dev/null
+++ b/test/Rewriter/metadata-test-1.m
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -rewrite-objc %s -o -
+
+@interface Intf 
+@end
+
+@implementation Intf(Category)
+- (void) CatMeth {}
+@end
+
+@implementation Another
+- (void) CatMeth {}
+@end
diff --git a/test/Rewriter/metadata-test-2.m b/test/Rewriter/metadata-test-2.m
new file mode 100644
index 0000000..0fd0429
--- /dev/null
+++ b/test/Rewriter/metadata-test-2.m
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -rewrite-objc %s -o -
+
+typedef struct _NSPoint {
+    float x;
+    float y;
+} NSPoint;
+
+@interface Intf
+- (void) MyMeth : (NSPoint) Arg1;
+@end
+
+@implementation Intf
+- (void) MyMeth : (NSPoint) Arg1{}
+@end
+
diff --git a/test/Rewriter/method-encoding-1.m b/test/Rewriter/method-encoding-1.m
new file mode 100644
index 0000000..08ee24b
--- /dev/null
+++ b/test/Rewriter/method-encoding-1.m
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -rewrite-objc %s -o -
+
+@protocol P1
+- (void) MyProtoMeth : (int **) arg1 : (void*) arg2;
++ (void) MyProtoMeth : (int **) arg1 : (void*) arg2;
+@end
+
+@interface Intf <P1>
+- (char *) MyMeth : (double) arg1 : (char *[12]) arg2;
+- (id) address:(void *)location with:(unsigned **)arg2;
+@end
+
+@implementation Intf
+- (char *) MyMeth : (double) arg1 : (char *[12]) arg2{ return 0; }
+- (void) MyProtoMeth : (int **) arg1 : (void*) arg2 {}
++ (void) MyProtoMeth : (int **) arg1 : (void*) arg2 {}
+- (id) address:(void *)location with:(unsigned **)arg2{ return 0; }
+@end
diff --git a/test/Rewriter/missing-dllimport.c b/test/Rewriter/missing-dllimport.c
new file mode 100644
index 0000000..c060379
--- /dev/null
+++ b/test/Rewriter/missing-dllimport.c
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -triple i686-pc-win32 -fms-extensions -fsyntax-only %s 2>&1 | FileCheck -check-prefix=CHECK-NEG %s
+// RUN: %clang_cc1 -triple i686-pc-win32 -fsyntax-only %s 2>&1 | FileCheck -check-prefix=CHECK-POS %s
+
+// Do not report that 'foo()' is redeclared without dllimport attribute with -fms-extensions
+// specified.  Addresses <rdar://problem/7653912>.
+
+__declspec(dllimport) int __cdecl foo(void);
+inline int __cdecl foo() { return 0; }
+
+// This function is added just to trigger a diagnostic.  This way we can test how many
+// diagnostics we expect.
+void bar() { return 1; }
+
+// CHECK-NEG: warning: void function 'bar' should not return a value
+// CHECK-NEG: 1 warning generated
+// CHECK-POS: warning: 'foo' redeclared without dllimport attribute: previous dllimport ignored
+// CHECK-POS: warning: void function 'bar' should not return a value
+// CHECK-POS: 2 warnings generated
+
diff --git a/test/Rewriter/objc-encoding-bug-1.m b/test/Rewriter/objc-encoding-bug-1.m
new file mode 100644
index 0000000..5605b66
--- /dev/null
+++ b/test/Rewriter/objc-encoding-bug-1.m
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -rewrite-objc %s -o -
+
+typedef struct NSMethodFrameArgInfo {
+    struct NSMethodFrameArgInfo *subInfo;
+    struct NSMethodFrameArgInfo *an;
+} NSMethodFrameArgInfo;
+
+@interface NSMethodSignature 
+- (NSMethodFrameArgInfo *)_argInfo;
+@end
+
+@implementation NSMethodSignature
+
+- (NSMethodFrameArgInfo *)_argInfo{
+    return 0;
+}
+
+@end
+
diff --git a/test/Rewriter/objc-ivar-receiver-1.m b/test/Rewriter/objc-ivar-receiver-1.m
new file mode 100644
index 0000000..5fb028e
--- /dev/null
+++ b/test/Rewriter/objc-ivar-receiver-1.m
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -rewrite-objc %s -o -
+// RUN: %clang_cc1 -rewrite-objc %s -o - | grep 'newInv->_container'
+
+@interface NSMutableArray 
+- (void)addObject:(id)addObject;
+@end
+
+@interface NSInvocation {
+@private
+    id _container;
+}
++ (NSInvocation *)invocationWithMethodSignature;
+
+@end
+
+@implementation NSInvocation
+
++ (NSInvocation *)invocationWithMethodSignature {
+    NSInvocation *newInv;
+    id obj = newInv->_container;
+    [newInv->_container addObject:0];
+   return 0;
+}
+@end
diff --git a/test/Rewriter/objc-string-concat-1.m b/test/Rewriter/objc-string-concat-1.m
new file mode 100644
index 0000000..32b2526
--- /dev/null
+++ b/test/Rewriter/objc-string-concat-1.m
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -rewrite-objc %s -o -
+
+@class NSString;
+
+@interface NSConstantString;
+@end
+
+
+
+NSConstantString *t0 = @"123";
+NSConstantString *t = @"123"     @"4567"; // concat
+NSConstantString *t1 = @"123"     @"4567" /* COMMENT */ @"89"; // concat
+NSConstantString *t2 = @"123"     @/* COMMENT */ "4567"; // concat
+
diff --git a/test/Rewriter/objc-super-test.m b/test/Rewriter/objc-super-test.m
new file mode 100644
index 0000000..38f68b9
--- /dev/null
+++ b/test/Rewriter/objc-super-test.m
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -rewrite-objc %s -o - | grep objc_msgSendSuper | grep MainMethod
+
+typedef struct objc_selector    *SEL;
+typedef struct objc_object *id;
+
+@interface SUPER
+- (int) MainMethod;
+@end
+
+@interface MyDerived : SUPER
+- (int) instanceMethod;
+@end
+
+@implementation MyDerived 
+- (int) instanceMethod {
+  return [super MainMethod];
+}
+@end
diff --git a/test/Rewriter/objc-synchronized-1.m b/test/Rewriter/objc-synchronized-1.m
new file mode 100644
index 0000000..27f2a0a
--- /dev/null
+++ b/test/Rewriter/objc-synchronized-1.m
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -rewrite-objc %s -o -
+
+id SYNCH_EXPR();
+void SYNCH_BODY();
+void  SYNCH_BEFORE();
+void  SYNC_AFTER();
+
+void foo(id sem)
+{
+  SYNCH_BEFORE();
+  @synchronized (SYNCH_EXPR()) { 
+    SYNCH_BODY();
+    return;
+  }
+ SYNC_AFTER();
+ @synchronized ([sem self]) {
+    SYNCH_BODY();
+    return;
+ }
+}
diff --git a/test/Rewriter/properties.m b/test/Rewriter/properties.m
new file mode 100644
index 0000000..44c55b1
--- /dev/null
+++ b/test/Rewriter/properties.m
@@ -0,0 +1,54 @@
+// RUN: %clang_cc1 -rewrite-objc %s -o -
+
+@interface Foo {
+    int i;
+    int rrrr;
+    Foo *o;
+}
+@property int i;
+@property(readonly) int rrrr;
+@property int d;
+@property(retain) Foo *o;
+
+- (void)foo;
+@end
+
+@implementation Foo
+@synthesize i;
+@synthesize rrrr;
+@synthesize o;
+
+@dynamic d;
+
+- (void)foo {
+    i = 99;
+}
+
+- (int)bar {
+  return i;
+}
+@end
+
+@interface Bar {
+}
+@end
+
+@implementation Bar
+
+static int func(int i);
+
+- (void)baz {
+    Foo *obj1, *obj2;
+    int i;
+    if (obj1.i == obj2.rrrr)
+      obj1.i = 33;
+    obj1.i = func(obj2.rrrr);
+    obj1.i = obj2.rrrr;
+    obj1.i = (obj2.rrrr);
+    [obj1 setI:[obj2 rrrr]];
+    obj1.i = [obj2 rrrr];
+    obj1.i = 3 + [obj2 rrrr];
+    i = obj1.o.i;
+    obj1.o.i = 77;
+}
+@end
diff --git a/test/Rewriter/protocol-rewrite-1.m b/test/Rewriter/protocol-rewrite-1.m
new file mode 100644
index 0000000..440527b
--- /dev/null
+++ b/test/Rewriter/protocol-rewrite-1.m
@@ -0,0 +1,48 @@
+// RUN: %clang_cc1 -rewrite-objc %s -o -
+
+typedef struct MyWidget {
+  int a;
+} MyWidget;
+
+MyWidget gWidget = { 17 };
+
+@protocol MyProto
+- (MyWidget *)widget;
+@end
+
+@interface Foo 
+@end
+
+@interface Bar: Foo <MyProto>
+@end
+
+@interface Container 
++ (MyWidget *)elementForView:(Foo *)view;
+@end
+
+@implementation Foo
+@end
+
+@implementation Bar
+- (MyWidget *)widget {
+  return &gWidget;
+}
+@end
+
+@implementation Container
++ (MyWidget *)elementForView:(Foo *)view
+{
+  MyWidget *widget = (void*)0;
+  if (@protocol(MyProto)) {
+    widget = [(id <MyProto>)view widget];
+  }
+  return widget;
+}
+@end
+
+int main(void) {
+  id view;
+  MyWidget *w = [Container elementForView: view];
+
+  return 0;
+}
diff --git a/test/Rewriter/rewrite-anonymous-union.m b/test/Rewriter/rewrite-anonymous-union.m
new file mode 100644
index 0000000..579a068
--- /dev/null
+++ b/test/Rewriter/rewrite-anonymous-union.m
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -rewrite-objc -o - %s
+// rdar://6948022
+
+typedef unsigned int uint32_t;
+
+typedef struct {
+    union {
+        uint32_t daysOfWeek;
+        uint32_t dayOfMonth;
+    };
+    uint32_t nthOccurrence;
+} OSPatternSpecificData;
+
+@interface NSNumber
++ (NSNumber *)numberWithLong:(long)value;
+@end
+
+@interface OSRecurrence  {
+    OSPatternSpecificData _pts;
+}
+- (void)_setTypeSpecificInfoOnRecord;
+@end
+
+@implementation OSRecurrence
+- (void)_setTypeSpecificInfoOnRecord
+{
+    [NSNumber numberWithLong:(_pts.dayOfMonth >= 31 ? -1 : _pts.dayOfMonth)];
+}
+@end
+
diff --git a/test/Rewriter/rewrite-api-bug.m b/test/Rewriter/rewrite-api-bug.m
new file mode 100644
index 0000000..03fc89f
--- /dev/null
+++ b/test/Rewriter/rewrite-api-bug.m
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -rewrite-objc %s -o -
+
+@interface MyDerived
+- (void) instanceMethod;
+@end
+
+@implementation MyDerived
+- (void) instanceMethod {
+}
+@end
+
diff --git a/test/Rewriter/rewrite-block-ivar-call.mm b/test/Rewriter/rewrite-block-ivar-call.mm
new file mode 100644
index 0000000..80e8caa
--- /dev/null
+++ b/test/Rewriter/rewrite-block-ivar-call.mm
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -x objective-c++ -fblocks -rewrite-objc -o - %s
+
+@interface Foo {
+    void (^_block)(void);
+}
+@end
+
+@implementation Foo
+- (void)bar {
+    _block();
+}
+@end
diff --git a/test/Rewriter/rewrite-block-literal.c b/test/Rewriter/rewrite-block-literal.c
new file mode 100644
index 0000000..be9c06f
--- /dev/null
+++ b/test/Rewriter/rewrite-block-literal.c
@@ -0,0 +1,80 @@
+// RUN: %clang_cc1 -rewrite-objc %s -fblocks -o -
+
+void I( void (^)(void));
+void (^noop)(void);
+
+void nothing();
+int printf(const char*, ...);
+
+typedef void (^T) (void);
+
+void takeblock(T);
+int takeintint(int (^C)(int)) { return C(4); }
+
+T somefunction() {
+  if (^{ })
+    nothing();
+
+  noop = ^{};
+
+  noop = ^{printf("\nClosure\n"); };
+
+  I(^{ });
+
+  return ^{printf("\nClosure\n"); };
+}
+void test2() {
+  int x = 4;
+
+  takeblock(^{ printf("%d\n", x); });
+
+  while (1) {
+    takeblock(^{ 
+        while(1) break;  // ok
+      });
+    break;
+  }
+}
+
+
+void (^test3())(void) { 
+  return ^{};
+}
+
+void test4() {
+  void (^noop)(void) = ^{};
+  void (*noop2)() = 0;
+}
+
+void myfunc(int (^block)(int)) {}
+
+void myfunc3(const int *x);
+
+void test5() {
+  int a;
+
+  myfunc(^(int abcd) {
+      myfunc3(&a);
+      return 1;
+    });
+}
+
+void *X;
+
+void test_arguments() {
+  int y;
+  int (^c)(char);
+  (1 ? c : 0)('x');
+  (1 ? 0 : c)('x');
+
+  (1 ? c : c)('x');
+}
+
+static int global_x = 10;
+void (^global_block)(void) = ^{ printf("global x is %d\n", global_x); };
+
+typedef void (^void_block_t)(void);
+
+static const void_block_t myBlock = ^{ };
+
+static const void_block_t myBlock2 = ^ void(void) { }; 
diff --git a/test/Rewriter/rewrite-block-pointer.mm b/test/Rewriter/rewrite-block-pointer.mm
new file mode 100644
index 0000000..212b236
--- /dev/null
+++ b/test/Rewriter/rewrite-block-pointer.mm
@@ -0,0 +1,60 @@
+// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp
+// RUN: %clang_cc1 -fsyntax-only -Wno-address-of-temporary -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp
+// radar 7638400
+
+typedef void * id;
+void *sel_registerName(const char *);
+
+@interface X
+@end
+
+void foo(void (^block)(int));
+
+@implementation X
+static void enumerateIt(void (^block)(id, id, char *)) {
+      foo(^(int idx) { });
+}
+@end
+
+// radar 7651312
+void apply(void (^block)(int));
+
+static void x(int (^cmp)(int, int)) {
+	x(cmp);
+}
+
+static void y(int (^cmp)(int, int)) {
+	apply(^(int sect) {
+		x(cmp);
+    });
+}
+
+// radar 7659483
+void *_Block_copy(const void *aBlock);
+void x(void (^block)(void)) {
+        block = ((__typeof(block))_Block_copy((const void *)(block)));
+}
+
+// radar 7682763
+@interface Y {
+@private
+    id _private;
+}
+- (void (^)(void))f;
+@end
+
+typedef void (^void_block_t)(void);
+
+@interface YY {
+    void_block_t __completion;
+}
+@property (copy) void_block_t f;
+@end
+
+@implementation Y
+- (void (^)(void))f {
+    return [_private f];
+}
+
+@end
+
diff --git a/test/Rewriter/rewrite-byref-in-nested-blocks.mm b/test/Rewriter/rewrite-byref-in-nested-blocks.mm
new file mode 100644
index 0000000..a8f5b14
--- /dev/null
+++ b/test/Rewriter/rewrite-byref-in-nested-blocks.mm
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp
+// RUN: %clang_cc1 -fsyntax-only -fblocks -Wno-address-of-temporary -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp
+// radar 7692350
+
+void f(void (^block)(void));
+
+@interface X {
+        int y;
+}
+- (void)foo;
+@end
+
+@implementation X
+- (void)foo {
+        __block int kerfluffle;
+        // radar 7692183
+        __block x; 
+        f(^{
+                f(^{
+                                y = 42;
+                            kerfluffle = 1;
+			    x = 2;
+                });
+        });
+}
+@end
diff --git a/test/Rewriter/rewrite-byref-vars.mm b/test/Rewriter/rewrite-byref-vars.mm
new file mode 100644
index 0000000..007ab43
--- /dev/null
+++ b/test/Rewriter/rewrite-byref-vars.mm
@@ -0,0 +1,57 @@
+// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp
+// RUN: %clang_cc1 -fsyntax-only -fblocks -Wno-address-of-temporary -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp
+// radar 7540194
+
+extern "C" __declspec(dllexport) void BreakTheRewriter(int i) {
+        __block int aBlockVariable = 0;
+        void (^aBlock)(void) = ^ {
+                aBlockVariable = 42;
+        };
+        aBlockVariable++;
+	if (i) {
+	  __block int bbBlockVariable = 0;
+	  void (^aBlock)(void) = ^ {
+                bbBlockVariable = 42;
+          };
+        }
+}
+
+__declspec(dllexport) extern "C" __declspec(dllexport) void XXXXBreakTheRewriter(void) {
+
+        __block int aBlockVariable = 0;
+        void (^aBlock)(void) = ^ {
+                aBlockVariable = 42;
+        };
+        aBlockVariable++;
+        void (^bBlocks)(void) = ^ {
+                aBlockVariable = 43;
+        };
+        void (^c)(void) = ^ {
+                aBlockVariable = 44;
+        };
+
+}
+
+@interface I
+{
+   id list;
+}
+- (void) Meth;
+// radar 7589385 use before definition
+- (void) allObjects;
+@end
+
+@implementation I
+// radar 7589385 use before definition
+- (void) allObjects {
+    __attribute__((__blocks__(byref))) id *listp;
+
+    ^(void) {
+      *listp++ = 0;
+    };
+}
+- (void) Meth { __attribute__((__blocks__(byref))) void ** listp = (void **)list; }
+@end
+
+// $CLANG -cc1 -fms-extensions -rewrite-objc -x objective-c++ -fblocks bug.mm
+// g++ -c -D"__declspec(X)=" bug.cpp
diff --git a/test/Rewriter/rewrite-cast-ivar-access.mm b/test/Rewriter/rewrite-cast-ivar-access.mm
new file mode 100644
index 0000000..c04cbab
--- /dev/null
+++ b/test/Rewriter/rewrite-cast-ivar-access.mm
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 -x objective-c++ -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp
+// RUN: FileCheck -check-prefix LP --input-file=%t-rw.cpp %s
+// radar 7575882
+
+@interface F {
+  int supervar;
+}
+@end
+
+@interface G : F {
+@public
+  int ivar;
+}
+@end
+
+@implementation G
+- (void)foo:(F *)arg {
+        int q = arg->supervar;
+        int v = ((G *)arg)->ivar;
+}
+@end
+
+void objc_assign_strongCast(id);
+void __CFAssignWithWriteBarrier(void **location, void *value) {
+        objc_assign_strongCast((id)value);
+}
+
+// radar 7607605
+@interface RealClass {
+        @public
+        int f;
+}
+@end
+
+@implementation RealClass
+@end
+
+@interface Foo {
+        id reserved;
+}
+@end
+
+@implementation Foo
+- (void)bar {
+        ((RealClass*)reserved)->f = 99;
+}
+@end
+
+// CHECK-LP: ((struct G_IMPL *)arg)->ivar
+
+// CHECK-LP: objc_assign_strongCast((id)value)
+
+// CHECK-LP: ((struct RealClass_IMPL *)((RealClass *)((struct Foo_IMPL *)self)->reserved))->f
diff --git a/test/Rewriter/rewrite-category-property.mm b/test/Rewriter/rewrite-category-property.mm
new file mode 100644
index 0000000..6b8f076
--- /dev/null
+++ b/test/Rewriter/rewrite-category-property.mm
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -x objective-c++ -fms-extensions -rewrite-objc %s -o %t-rw.cpp
+// RUN: FileCheck -check-prefix LP --input-file=%t-rw.cpp %s
+// radar 7630636
+
+@class Y, Z;
+
+@interface A
+@property (readonly) Y *y;
+@end
+
+@interface A (cat)
+@property (readonly) Z *z;
+@end
+
+// CHECK-LP: // @property (readonly) Z *z;
diff --git a/test/Rewriter/rewrite-eh.m b/test/Rewriter/rewrite-eh.m
new file mode 100644
index 0000000..5bc80b5
--- /dev/null
+++ b/test/Rewriter/rewrite-eh.m
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -rewrite-objc -o - %s
+// rdar://7522880
+
+@interface NSException
+@end
+
+@interface Foo
+@end
+
+@implementation Foo
+- (void)bar {
+    @try {
+    } @catch (NSException *e) {
+    }
+    @catch (Foo *f) {
+    }
+    @catch (...) {
+    }
+}
+@end
diff --git a/test/Rewriter/rewrite-extern-c.mm b/test/Rewriter/rewrite-extern-c.mm
new file mode 100644
index 0000000..1c8e90f
--- /dev/null
+++ b/test/Rewriter/rewrite-extern-c.mm
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -x objective-c++ -fblocks -rewrite-objc -o - %s
+// radar 7546096
+
+extern "C" {
+        short foo() { } 
+}
+typedef unsigned char Boolean;
+
diff --git a/test/Rewriter/rewrite-foreach-1.m b/test/Rewriter/rewrite-foreach-1.m
new file mode 100644
index 0000000..e68b45d
--- /dev/null
+++ b/test/Rewriter/rewrite-foreach-1.m
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 -rewrite-objc %s -o -
+            
+@protocol P @end
+
+@interface MyList
+@end
+    
+@implementation MyList
+- (unsigned int)countByEnumeratingWithState:  (struct __objcFastEnumerationState *)state objects:  (id *)items count:(unsigned int)stackcount
+{
+        return 0;
+}
+@end
+
+@interface MyList (BasicTest)
+- (void)compilerTestAgainst;
+@end
+
+int LOOP();
+@implementation MyList (BasicTest)
+- (void)compilerTestAgainst {
+  id el;
+        for (el in self) 
+	  { LOOP(); }
+        for (id el1 in self) 
+	  LOOP();
+
+	for (el in (self)) 
+          if (el)
+            LOOP(); 
+
+	for (el in ((self))) 
+          if (el)
+            LOOP(); 
+}
+@end
+
diff --git a/test/Rewriter/rewrite-foreach-2.m b/test/Rewriter/rewrite-foreach-2.m
new file mode 100644
index 0000000..5ed15a3
--- /dev/null
+++ b/test/Rewriter/rewrite-foreach-2.m
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -rewrite-objc %s -o -
+
+@protocol P @end
+
+@interface MyList
+@end
+    
+@implementation MyList
+- (unsigned int)countByEnumeratingWithState:  (struct __objcFastEnumerationState *)state objects:  (id *)items count:(unsigned int)stackcount
+{
+        return 0;
+}
+@end
+
+@interface MyList (BasicTest)
+- (void)compilerTestAgainst;
+@end
+
+int LOOP();
+int INNERLOOP();
+void END_LOOP();
+@implementation MyList (BasicTest)
+- (void)compilerTestAgainst {
+  id el;
+        for (el in self) 
+	  { LOOP(); 
+            for (id el1 in self) 
+	       INNER_LOOP();
+
+	    END_LOOP();
+	  }
+}
+@end
+
diff --git a/test/Rewriter/rewrite-foreach-3.m b/test/Rewriter/rewrite-foreach-3.m
new file mode 100644
index 0000000..ffe8295
--- /dev/null
+++ b/test/Rewriter/rewrite-foreach-3.m
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -rewrite-objc %s -o -
+
+@protocol P @end
+
+@interface MyList
+@end
+    
+@implementation MyList
+- (unsigned int)countByEnumeratingWithState:  (struct __objcFastEnumerationState *)state objects:  (id *)items count:(unsigned int)stackcount
+{
+        return 0;
+}
+@end
+
+@interface MyList (BasicTest)
+- (void)compilerTestAgainst;
+@end
+
+int LOOP();
+@implementation MyList (BasicTest)
+- (void)compilerTestAgainst {
+  MyList * el;
+        for (el in self) 
+	  { LOOP(); }
+        for (MyList *  el1 in self) 
+	  LOOP();
+}
+@end
+
diff --git a/test/Rewriter/rewrite-foreach-4.m b/test/Rewriter/rewrite-foreach-4.m
new file mode 100644
index 0000000..5b66e97
--- /dev/null
+++ b/test/Rewriter/rewrite-foreach-4.m
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -rewrite-objc %s -o -
+
+@interface MyList
+- (id) allKeys;
+@end
+    
+@implementation MyList
+- (unsigned int)countByEnumeratingWithState:  (struct __objcFastEnumerationState *)state objects:  (id *)items count:(unsigned int)stackcount
+{
+        return 0;
+}
+- (id) allKeys { return 0; }
+@end
+
+@interface MyList (BasicTest)
+- (void)compilerTestAgainst;
+@end
+
+int LOOP();
+@implementation MyList (BasicTest)
+- (void)compilerTestAgainst {
+  MyList * el;
+        for (el in [el allKeys]) { LOOP(); 
+	  }
+
+        for (id el1 in[el allKeys]) { LOOP(); 
+	  }
+        for (el in([el allKeys])) { LOOP(); 
+	  }
+}
+@end
+
diff --git a/test/Rewriter/rewrite-foreach-5.m b/test/Rewriter/rewrite-foreach-5.m
new file mode 100644
index 0000000..adfd7f8
--- /dev/null
+++ b/test/Rewriter/rewrite-foreach-5.m
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -rewrite-objc %s -o -
+
+@interface MyList
+- (id) allKeys;
+@end
+    
+@implementation MyList
+- (unsigned int)countByEnumeratingWithState:  (struct __objcFastEnumerationState *)state objects:  (id *)items count:(unsigned int)stackcount
+{
+        return 0;
+}
+- (id) allKeys { return 0; }
+@end
+
+@interface MyList (BasicTest)
+- (void)compilerTestAgainst;
+@end
+
+int LOOP();
+@implementation MyList (BasicTest)
+- (void)compilerTestAgainst {
+  MyList * el;
+  int i;
+        for (el in [el allKeys]) { 
+		for (i = 0; i < 10; i++)
+		  if (i == 5)
+		   break;
+
+		if (el == 0)
+		 break;
+		if (el != self)
+		  continue;
+		LOOP(); 
+	  }
+
+        for (id el1 in[el allKeys]) { 
+	    LOOP(); 
+	    for (el in self) {
+	      if (el)
+		continue;
+	    }
+	    if (el1)
+	      break;
+	  }
+}
+@end
+
diff --git a/test/Rewriter/rewrite-foreach-6.m b/test/Rewriter/rewrite-foreach-6.m
new file mode 100644
index 0000000..2aa19ae
--- /dev/null
+++ b/test/Rewriter/rewrite-foreach-6.m
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 %s -rewrite-objc -o -
+// rdar://5716356
+// FIXME: Should be able to pipe into clang, but code is not
+// yet correct for other reasons: rdar://5716940
+
+@class NSNotification;
+@class NSMutableArray;
+
+void foo(NSMutableArray *notificationArray, id X) {
+  for (NSNotification *notification in notificationArray)
+    [X postNotification:notification];
+}
+
diff --git a/test/Rewriter/rewrite-foreach-7.m b/test/Rewriter/rewrite-foreach-7.m
new file mode 100644
index 0000000..9fa6a1a
--- /dev/null
+++ b/test/Rewriter/rewrite-foreach-7.m
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -rewrite-objc %s -o -
+
+@class NSArray;
+int main() {
+	NSArray *foo;
+	for (Class c in foo) { }
+}
diff --git a/test/Rewriter/rewrite-forward-class.m b/test/Rewriter/rewrite-forward-class.m
new file mode 100644
index 0000000..5a50f53
--- /dev/null
+++ b/test/Rewriter/rewrite-forward-class.m
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -rewrite-objc -o - %s
+// rdar://6969189
+
+@class XX;
+@class YY, ZZ, QQ;
+@class ISyncClient, SMSession, ISyncManager, ISyncSession, SMDataclassInfo, SMClientInfo,
+    DMCConfiguration, DMCStatusEntry;
+
diff --git a/test/Rewriter/rewrite-function-decl.mm b/test/Rewriter/rewrite-function-decl.mm
new file mode 100644
index 0000000..023e55d
--- /dev/null
+++ b/test/Rewriter/rewrite-function-decl.mm
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -fms-extensions -rewrite-objc -x objective-c++ -fblocks -o - %s
+
+extern "C" __declspec(dllexport) void BreakTheRewriter(void) {
+        __block int aBlockVariable = 0;
+        void (^aBlock)(void) = ^ {
+                aBlockVariable = 42;
+        };
+        aBlockVariable++;
+        void (^bBlocks)(void) = ^ {
+                aBlockVariable = 43;
+        };
+        void (^c)(void) = ^ {
+                aBlockVariable = 44;
+        };
+
+}
+__declspec(dllexport) extern "C" void AnotherBreakTheRewriter(int *p1, double d) {
+
+        __block int bBlockVariable = 0;
+        void (^aBlock)(void) = ^ {
+                bBlockVariable = 42;
+        };
+        bBlockVariable++;
+        void (^bBlocks)(void) = ^ {
+                bBlockVariable = 43;
+        };
+        void (^c)(void) = ^ {
+                bBlockVariable = 44;
+        };
+
+}
diff --git a/test/Rewriter/rewrite-implementation.mm b/test/Rewriter/rewrite-implementation.mm
new file mode 100644
index 0000000..c1d89a3
--- /dev/null
+++ b/test/Rewriter/rewrite-implementation.mm
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -x objective-c++ -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp
+// RUN: %clang_cc1 -fsyntax-only -Wno-address-of-temporary -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp
+// radar 7649577
+
+@interface a
+@end
+
+@interface b : a
+@end
+
+@implementation b
+@end
+
diff --git a/test/Rewriter/rewrite-ivar-use.m b/test/Rewriter/rewrite-ivar-use.m
new file mode 100644
index 0000000..82cff5b
--- /dev/null
+++ b/test/Rewriter/rewrite-ivar-use.m
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -rewrite-objc -fms-extensions %s -o -
+// radar 7490331
+
+@interface Foo {
+        int a;
+        id b;
+}
+- (void)bar;
+- (void)baz:(id)q;
+@end
+
+@implementation Foo
+// radar 7522803
+static void foo(id bar) {
+        int i = ((Foo *)bar)->a;
+}
+
+- (void)bar {
+        a = 42;
+        [self baz:b];
+}
+- (void)baz:(id)q {
+}
+@end
+
diff --git a/test/Rewriter/rewrite-local-externs-in-block.mm b/test/Rewriter/rewrite-local-externs-in-block.mm
new file mode 100644
index 0000000..d1a56a8
--- /dev/null
+++ b/test/Rewriter/rewrite-local-externs-in-block.mm
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp
+// RUN: %clang_cc1 -fsyntax-only -Wno-address-of-temporary -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp
+// radar 7735987
+
+extern "C" int printf(const char*, ...);
+
+void bar(void (^block)()) {
+	block();
+}
+
+int main() {
+	static int myArr[3] = {1, 2, 3};
+	printf ("%d %d %d\n", myArr[0], myArr[1], myArr[2]);
+	
+	bar(^{
+		printf ("%d %d %d\n", myArr[0], myArr[1], myArr[2]);
+		myArr[0] = 42;
+		myArr[2] = 100;
+		printf ("%d %d %d\n", myArr[0], myArr[1], myArr[2]);
+	});
+
+	printf ("%d %d %d\n", myArr[0], myArr[1], myArr[2]);
+}
diff --git a/test/Rewriter/rewrite-message-expr.mm b/test/Rewriter/rewrite-message-expr.mm
new file mode 100644
index 0000000..d909f3e
--- /dev/null
+++ b/test/Rewriter/rewrite-message-expr.mm
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -x objective-c++ -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp
+// RUN: FileCheck -check-prefix LP --input-file=%t-rw.cpp %s
+// radar 7617047
+
+@interface Baz
+- (id)y;
++ (id)z;
+@end
+
+@interface Foo {
+@public
+	int bar;
+}
+@end
+
+extern Foo* x(id a);
+
+int f(Baz *baz) {
+	int i = x([Baz z])->bar;
+        int j = ((Foo*)[Baz z])->bar;
+        int k = x([baz y])->bar;
+        return i+j+k;
+}
+
+// CHECK-LP: ((struct Foo_IMPL *)x(((id (*)(id, SEL))(void *)objc_msgSend)(objc_getClass("Baz"), sel_registerName("z"))))->bar
diff --git a/test/Rewriter/rewrite-nest.m b/test/Rewriter/rewrite-nest.m
new file mode 100644
index 0000000..ebbcded
--- /dev/null
+++ b/test/Rewriter/rewrite-nest.m
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -rewrite-objc %s -o -
+
+@interface NSMapTable @end
+@interface NSEnumerator @end
+
+typedef unsigned int NSUInteger;
+
+@interface NSConcreteMapTable : NSMapTable {
+@public
+    NSUInteger capacity;
+}
+@end
+
+@interface NSConcreteMapTableValueEnumerator : NSEnumerator {
+    NSConcreteMapTable *mapTable;
+}
+@end
+
+@implementation NSConcreteMapTableValueEnumerator
+
+- nextObject {
+    while (mapTable->capacity) {
+    }
+    return 0;
+}
+@end
+
diff --git a/test/Rewriter/rewrite-nested-blocks-1.mm b/test/Rewriter/rewrite-nested-blocks-1.mm
new file mode 100644
index 0000000..582f5f4
--- /dev/null
+++ b/test/Rewriter/rewrite-nested-blocks-1.mm
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp
+// RUN: %clang_cc1 -fsyntax-only -fblocks -Wno-address-of-temporary -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp
+// radar 7696893
+
+void *sel_registerName(const char *);
+
+void f(void (^block)(void));
+void f2(id);
+void f3(int);
+char f4(id, id);
+
+@interface Baz
+- (void)b:(void (^)(void))block;
+@end
+
+@interface Bar
+@end
+
+@interface Foo {
+	int _x;
+}
+@end
+
+@implementation Foo
+- (void)method:(Bar *)up {
+    Baz *down;
+	int at;
+    id cq;
+    __block char didit = 'a';
+    __block char upIsFinished = 'b';
+    f(^{
+            id old_cq;
+			f2(cq);
+            [down b:^{
+                    [down b:^{
+                            f(^{
+                                    didit = f4(up, down);
+									upIsFinished = 'c';
+                                    self->_x++;
+                                });
+                        }];
+                }];
+				f2(old_cq);
+			f3(at);
+    });
+}
+@end
diff --git a/test/Rewriter/rewrite-nested-blocks.mm b/test/Rewriter/rewrite-nested-blocks.mm
new file mode 100644
index 0000000..1a6bcdd
--- /dev/null
+++ b/test/Rewriter/rewrite-nested-blocks.mm
@@ -0,0 +1,56 @@
+// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp
+// RUN: %clang_cc1 -fsyntax-only -Wno-address-of-temporary -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp
+// radar 7682149
+
+
+void f(void (^block)(void));
+
+@interface X {
+	int y;
+}
+- (void)foo;
+@end
+
+@implementation X
+- (void)foo {
+    f(^{
+  f(^{
+    f(^{
+      y=42;
+    });
+  });
+});
+
+}
+@end
+
+struct S {
+  int y;
+};
+
+void foo () {
+	struct S *SELF;
+	f(^{
+		f(^{
+			SELF->y = 42;
+		});
+	});
+}
+
+// radar 7692419
+@interface Bar
+@end
+
+void f(Bar *);
+void q(void (^block)(void));
+
+void x() {
+        void (^myblock)(Bar *b) = ^(Bar *b) {
+                q(^{
+                        f(b);   
+                });
+        };
+        
+        Bar *b = (Bar *)42;
+        myblock(b);
+}
diff --git a/test/Rewriter/rewrite-nested-ivar.mm b/test/Rewriter/rewrite-nested-ivar.mm
new file mode 100644
index 0000000..1787cc7
--- /dev/null
+++ b/test/Rewriter/rewrite-nested-ivar.mm
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp
+// RUN: %clang_cc1 -fsyntax-only -fblocks -Wno-address-of-temporary -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp
+// radar 7583971
+
+
+@interface NSURLResponse {
+@public
+  NSURLResponse *InnerResponse;
+}
+@end
+
+@interface NSCachedURLResponseInternal 
+{
+    @public
+    NSURLResponse *response;
+}
+@end
+
+@interface NSCachedURLResponse
+{
+    @private
+    NSCachedURLResponseInternal *_internal;
+}
+- (void) Meth;
+@end
+
+@implementation NSCachedURLResponse
+- (void) Meth {
+    _internal->response->InnerResponse = 0;
+  }
+@end
diff --git a/test/Rewriter/rewrite-property-attributes.mm b/test/Rewriter/rewrite-property-attributes.mm
new file mode 100644
index 0000000..41f457c
--- /dev/null
+++ b/test/Rewriter/rewrite-property-attributes.mm
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp
+// RUN: %clang_cc1 -fsyntax-only -Wno-address-of-temporary  -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp
+// radar 7214439
+
+typedef void (^void_block_t)(void);
+
+@interface Y {
+    void_block_t __completion;
+    Y* YVAR;
+    id ID;
+}
+@property (copy) void_block_t completionBlock;
+@property (retain) Y* Yblock;
+@property (copy) id ID;
+@end
+
+@implementation Y
+@synthesize completionBlock=__completion;
+@synthesize Yblock = YVAR;
+@synthesize  ID;
+@end
+
diff --git a/test/Rewriter/rewrite-protocol-qualified.mm b/test/Rewriter/rewrite-protocol-qualified.mm
new file mode 100644
index 0000000..5f12010
--- /dev/null
+++ b/test/Rewriter/rewrite-protocol-qualified.mm
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp
+// RUN: %clang_cc1 -fsyntax-only -Wno-address-of-temporary -D"SEL=void*" -D"id=void*" -D"__declspec(X)=" %t-rw.cpp
+// radar 7589414
+
+@protocol NSPortDelegate;
+@interface NSConnection @end
+
+@interface NSMessagePort
+- (void) clone;
+@end
+
+@implementation NSMessagePort
+- (void) clone {
+     NSConnection <NSPortDelegate> *conn = 0;
+     id <NSPortDelegate> *idc = 0;
+}
+@end
+
+// radar 7607413
+@protocol Proto1, Proto2;
+
+@protocol Proto
+@end
+
+unsigned char func(id<Proto1, Proto2> inProxy);
+
+id bar(id);
+
+void f() {
+        id a;
+        id b = bar((id <Proto>)a);
+}
diff --git a/test/Rewriter/rewrite-protocol-type-1.m b/test/Rewriter/rewrite-protocol-type-1.m
new file mode 100644
index 0000000..2bdf8e4
--- /dev/null
+++ b/test/Rewriter/rewrite-protocol-type-1.m
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -rewrite-objc %s -o -
+
+@protocol MyProto1 
+@end
+
+@protocol MyProto2
+@end
+
+@interface INTF @end
+
+INTF <MyProto1> *g1;
+
+INTF <MyProto1, MyProto2> *g2, *g3;
+
+INTF <MyProto1> * Func(INTF <MyProto1> *p2, INTF<MyProto1> *p3, INTF *p4, INTF<MyProto1> *p5)
+{
+	return p2;
+}
+
+INTF <MyProto1, MyProto2> * Func1(INTF *p2, INTF<MyProto1, MyProto2> *p3, INTF *p4, INTF<MyProto1> *p5)
+{
+	return p3;
+}
+
+@interface Foo
+@property int (*hashFunction)(const void *item, int (*size)(const void *item));
+@end
diff --git a/test/Rewriter/rewrite-qualified-id.mm b/test/Rewriter/rewrite-qualified-id.mm
new file mode 100644
index 0000000..fe3607d
--- /dev/null
+++ b/test/Rewriter/rewrite-qualified-id.mm
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp
+// RUN: %clang_cc1 -fsyntax-only -Wno-address-of-temporary -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp
+// radar 7680953
+
+typedef void * id;
+
+@protocol foo
+@end
+
+@interface CL
+{
+  id <foo> changeSource;
+  CL <foo>* changeSource1;
+}
+@end
+
+typedef struct x
+{
+   id <foo> changeSource;
+} x;
+
diff --git a/test/Rewriter/rewrite-rewritten-initializer.mm b/test/Rewriter/rewrite-rewritten-initializer.mm
new file mode 100644
index 0000000..80ad7fc
--- /dev/null
+++ b/test/Rewriter/rewrite-rewritten-initializer.mm
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp
+// RUN: %clang_cc1 -fsyntax-only -Wno-address-of-temporary -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp
+// radar 7669784
+
+typedef void * id;
+void *sel_registerName(const char *);
+
+@interface NSMutableString
+- (NSMutableString *)string;
+@end
+
+@interface Z
+@end
+
+@implementation Z
+
+- (void)x {
+        id numbers;
+    int i, numbersCount = 42;
+    __attribute__((__blocks__(byref))) int blockSum = 0;
+    void (^add)(id n, int idx, char *stop) = ^(id n, int idx, char *stop) { };
+    [numbers enumerateObjectsUsingBlock:add];
+    NSMutableString *forwardAppend = [NSMutableString string];
+    __attribute__((__blocks__(byref))) NSMutableString *blockAppend = [NSMutableString string];
+}
+
+@end
+
diff --git a/test/Rewriter/rewrite-static-block.mm b/test/Rewriter/rewrite-static-block.mm
new file mode 100644
index 0000000..c99557f
--- /dev/null
+++ b/test/Rewriter/rewrite-static-block.mm
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp
+// RUN: %clang_cc1 -Wno-address-of-temporary -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp -emit-llvm -o %t-rw.ll
+// RUN: FileCheck --input-file=%t-rw.ll %s
+
+typedef void (^void_block_t)(void);
+
+static const void_block_t myblock = ^{
+        
+};
+
+// CHECK: myblock = internal global
diff --git a/test/Rewriter/rewrite-super-message.mm b/test/Rewriter/rewrite-super-message.mm
new file mode 100644
index 0000000..be0a963
--- /dev/null
+++ b/test/Rewriter/rewrite-super-message.mm
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp
+// RUN: %clang_cc1 -fsyntax-only -Wno-address-of-temporary -DKEEP_ATTRIBUTES -D"id=struct objc_object *" -D"Class=struct objc_class *" -D"SEL=void*" -D"__declspec(X)=" -emit-llvm -o - %t-rw.cpp | FileCheck %t-rw.cpp
+// radar 7738453
+
+void *sel_registerName(const char *);
+
+@interface __NSCFType
+@end
+
+@interface __NSCFString : __NSCFType
+- (const char *)UTF8String;
+@end
+
+@implementation __NSCFString
+- (const char *)UTF8String {
+    return (const char *)[super UTF8String];
+}
+@end
+
+// CHECK: call %struct.objc_class* @class_getSuperclass
diff --git a/test/Rewriter/rewrite-trivial-constructor.mm b/test/Rewriter/rewrite-trivial-constructor.mm
new file mode 100644
index 0000000..81c7d9b
--- /dev/null
+++ b/test/Rewriter/rewrite-trivial-constructor.mm
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -fms-extensions -rewrite-objc -x objective-c++ -fblocks -o - %s
+// radar 7537770
+
+typedef struct {
+        int a;
+        int b;
+} s;
+
+extern void CFBasicHashApply(int (^block)(s)) {
+        int used, cnt;
+    for (int idx = 0; 0 < used && idx < cnt; idx++) {
+                s bkt;
+        if (0 < bkt.a) {
+            if (!block(bkt)) {
+                return;
+            }
+            used--;
+        }
+    }
+}
+
diff --git a/test/Rewriter/rewrite-try-catch.m b/test/Rewriter/rewrite-try-catch.m
new file mode 100644
index 0000000..d0c6d2a
--- /dev/null
+++ b/test/Rewriter/rewrite-try-catch.m
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -rewrite-objc %s -o -
+
+@interface Foo @end
+@interface GARF @end
+
+void foo() {
+  @try  { TRY(); } 
+  @catch (...) { SPLATCH(); @throw; }
+}
+
+int main()
+{
+
+  @try  {
+     MYTRY();
+  }
+
+  @catch (Foo* localException) {
+     MYCATCH();
+     @throw;
+  }
+  
+  // no catch clause
+  @try { } 
+  @finally { }
+}
+
diff --git a/test/Rewriter/rewrite-typeof.mm b/test/Rewriter/rewrite-typeof.mm
new file mode 100644
index 0000000..b859ac3
--- /dev/null
+++ b/test/Rewriter/rewrite-typeof.mm
@@ -0,0 +1,39 @@
+// RUN: %clang_cc1 -x objective-c++ -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp
+// RUN: FileCheck -check-prefix LP --input-file=%t-rw.cpp %s
+
+extern "C" {
+extern "C" void *_Block_copy(const void *aBlock);
+extern "C" void _Block_release(const void *aBlock);
+}
+
+int main() {
+    __attribute__((__blocks__(byref))) int a = 42;
+    int save_a = a;
+
+    void (^b)(void) = ^{
+        ((__typeof(^{ a = 2; }))_Block_copy((const void *)(^{ a = 2; })));
+    };
+
+    ((__typeof(b))_Block_copy((const void *)(b)));
+
+    return 0;
+}
+
+// CHECK-LP: ((void (^)(void))_Block_copy((const void *)(b)))
+
+// radar 7628153
+void f() {
+	int a;	
+	__typeof__(a) aVal = a;
+	char *a1t = (char *)@encode(__typeof__(a));
+        __typeof__(aVal) bVal;
+	char *a2t = (char *)@encode(__typeof__(bVal));
+        __typeof__(bVal) cVal = bVal;
+	char *a3t = (char *)@encode(__typeof__(cVal));
+
+}
+
+
+// CHECK-LP: int aVal =  a;
+
+// CHECK-LP: int bVal;
diff --git a/test/Rewriter/rewrite-unique-block-api.mm b/test/Rewriter/rewrite-unique-block-api.mm
new file mode 100644
index 0000000..130f514
--- /dev/null
+++ b/test/Rewriter/rewrite-unique-block-api.mm
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -x objective-c++ -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp
+// RUN: %clang_cc1 -fsyntax-only -Wno-address-of-temporary -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp
+// radar 7630551
+
+void f(void (^b)(char c));
+
+@interface a
+- (void)processStuff;
+@end
+
+@implementation a
+- (void)processStuff {
+    f(^(char x) { });
+}
+@end
+
+@interface b
+- (void)processStuff;
+@end
+
+@implementation b
+- (void)processStuff {
+    f(^(char x) { });
+}
+@end
diff --git a/test/Rewriter/rewrite-weak-attr.m b/test/Rewriter/rewrite-weak-attr.m
new file mode 100644
index 0000000..2e559ee
--- /dev/null
+++ b/test/Rewriter/rewrite-weak-attr.m
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -triple i686-pc-win32 -fms-extensions -fblocks -Dnil=0 -rewrite-objc  -o - %s
+int main() {
+        __weak __block id foo = nil;
+        __block id foo2 = nil;
+        id foo3 = nil;
+        
+        void (^myblock)() = ^{
+                foo = nil;
+                foo2 = nil;
+                [foo3 bar];
+                id foo4 = foo3;
+        };
+}
diff --git a/test/Rewriter/static-type-protocol-1.m b/test/Rewriter/static-type-protocol-1.m
new file mode 100644
index 0000000..a072c9f
--- /dev/null
+++ b/test/Rewriter/static-type-protocol-1.m
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -rewrite-objc %s -o -
+
+@protocol Proto
+- (void) ProtoDidget;
+@end
+
+@protocol MyProto <Proto>
+- (void) widget;
+@end
+
+@interface Foo 
+- (void)StillMode;
+@end
+
+@interface Container
++ (void)MyMeth;
+@end
+
+@implementation Container
++ (void)MyMeth
+{
+  Foo *view;
+  [(Foo <MyProto> *)view StillMode];
+  [(Foo <MyProto> *)view widget];
+  [(Foo <MyProto> *)view ProtoDidget];
+}
+@end
diff --git a/test/Rewriter/undecl-objc-h.m b/test/Rewriter/undecl-objc-h.m
new file mode 100644
index 0000000..a60d810
--- /dev/null
+++ b/test/Rewriter/undecl-objc-h.m
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -rewrite-objc %s -o -
+
+typedef struct S {
+	int * pint;
+	int size;
+}NSRec;
+
+@interface SUPER
+- (NSRec) MainMethod : (NSRec) Arg1 : (NSRec) Arg2;
+@end
+
+@interface MyDerived : SUPER
+{
+	NSRec d;
+}
+- (int) instanceMethod;
+- (int) another : (int) arg;
+- (NSRec) MainMethod : (NSRec) Arg1 : (NSRec) Arg2;
+@end
+
+@implementation MyDerived 
+- (int) instanceMethod {
+  return [self another : [self MainMethod : d : d].size];
+}
+
+- (int) another : (int) arg { return arg; }
+- (NSRec) MainMethod : (NSRec) Arg1 : (NSRec) Arg2 { return Arg2; }
+@end
+
diff --git a/test/Rewriter/undeclared-method-1.m b/test/Rewriter/undeclared-method-1.m
new file mode 100644
index 0000000..89d33ce
--- /dev/null
+++ b/test/Rewriter/undeclared-method-1.m
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -rewrite-objc %s -o -
+
+@interface Derived @end
+
+int main(void) {
+  Derived *v ;
+  [v free];
+  return 0;
+}
diff --git a/test/Rewriter/undef-field-reference-1.m b/test/Rewriter/undef-field-reference-1.m
new file mode 100644
index 0000000..039c500
--- /dev/null
+++ b/test/Rewriter/undef-field-reference-1.m
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -rewrite-objc %s -o -
+
+@interface MyDerived 
+{
+@public
+	int IVAR;
+}
+@end
+
+MyDerived *pd;
+int main() {
+	return pd->IVAR;
+}
+
+
diff --git a/test/Rewriter/va-method.m b/test/Rewriter/va-method.m
new file mode 100644
index 0000000..366552f
--- /dev/null
+++ b/test/Rewriter/va-method.m
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -rewrite-objc %s -o -
+
+#include <stdarg.h>
+
+@interface NSObject @end
+@interface XX : NSObject @end
+
+@implementation XX
+- (void)encodeValuesOfObjCTypes:(const char *)types, ... {
+   va_list ap;
+   va_start(ap, types); 
+   while (*types) ;
+   va_end(ap);
+}
+
+@end
+
diff --git a/test/Rewriter/weak_byref_objects.m b/test/Rewriter/weak_byref_objects.m
new file mode 100644
index 0000000..a0ebe88
--- /dev/null
+++ b/test/Rewriter/weak_byref_objects.m
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fblocks -triple i386-apple-darwin9 -fobjc-gc -rewrite-objc %s -o -
+
+#define nil 0
+int main() {
+        __weak __block id foo = nil;
+        __block id foo2 = nil;
+        id foo3 = nil;
+
+        void (^myblock)() = ^{
+                foo = nil;
+                foo2 = nil;
+                [foo3 bar];
+                id foo4 = foo3;
+        };
+}
diff --git a/test/Sema/128bitint.c b/test/Sema/128bitint.c
new file mode 100644
index 0000000..fe83d97
--- /dev/null
+++ b/test/Sema/128bitint.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -triple x86_64-apple-darwin9 %s
+typedef int i128 __attribute__((__mode__(TI)));
+typedef unsigned u128 __attribute__((__mode__(TI)));
+
+int a[((i128)-1 ^ (i128)-2) == 1 ? 1 : -1];
+int a[(u128)-1 > 1LL ? 1 : -1];
+
+// PR5435
+__uint128_t b = (__uint128_t)-1;
diff --git a/test/Sema/Inputs/conversion.h b/test/Sema/Inputs/conversion.h
new file mode 100644
index 0000000..9f6ed2e
--- /dev/null
+++ b/test/Sema/Inputs/conversion.h
@@ -0,0 +1,3 @@
+/* Fake system header for Sema/conversion.c */
+
+#define LONG_MAX __LONG_MAX__
diff --git a/test/Sema/PR2727.c b/test/Sema/PR2727.c
new file mode 100644
index 0000000..332b0df
--- /dev/null
+++ b/test/Sema/PR2727.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -verify -fsyntax-only -std=c90 %s
+// RUN: %clang_cc1 -verify -fsyntax-only -std=c99 %s
+
+int f (int x)
+{
+  // sizeof applied to a type should not delete the type.
+  return sizeof (int[x]);
+}
diff --git a/test/Sema/PR2728.c b/test/Sema/PR2728.c
new file mode 100644
index 0000000..e9f1dea
--- /dev/null
+++ b/test/Sema/PR2728.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -verify -fsyntax-only -std=c90 %s
+// RUN: %clang_cc1 -verify -fsyntax-only -std=c99 %s
+
+struct s
+{
+  int a;
+};
+
+int a[__builtin_offsetof(struct s, a) == 0];
diff --git a/test/Sema/PR2919-builtin-types-compat-strips-crv.c b/test/Sema/PR2919-builtin-types-compat-strips-crv.c
new file mode 100644
index 0000000..9c13357
--- /dev/null
+++ b/test/Sema/PR2919-builtin-types-compat-strips-crv.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -fsyntax-only %s
+
+typedef struct foo T0;
+typedef const struct foo T1;
+
+int a0[__builtin_types_compatible_p(T0,
+                                    const T1) ? 1 : -1];
diff --git a/test/Sema/PR2923.c b/test/Sema/PR2923.c
new file mode 100644
index 0000000..f22e70d
--- /dev/null
+++ b/test/Sema/PR2923.c
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// Test for absence of crash reported in PR 2923:
+//
+//  http://llvm.org/bugs/show_bug.cgi?id=2923
+//
+// Previously we had a crash when deallocating the FunctionDecl for 'bar'
+// because FunctionDecl::getNumParams() just used the type of foo to determine
+// the number of parameters it has.  In the case of 'bar' there are no
+// ParmVarDecls.
+int foo(int x, int y) { return x + y; }
+extern typeof(foo) bar;
diff --git a/test/Sema/PR2963-enum-constant.c b/test/Sema/PR2963-enum-constant.c
new file mode 100644
index 0000000..1900eef
--- /dev/null
+++ b/test/Sema/PR2963-enum-constant.c
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only
+
+typedef short short_fixed;
+
+enum
+{
+        // 8.8 short_fixed
+        SHORT_FIXED_FRACTIONAL_BITS= 8,
+        SHORT_FIXED_ONE= 1<<SHORT_FIXED_FRACTIONAL_BITS
+};
+
+#define FLOAT_TO_SHORT_FIXED(f) ((short_fixed)((f)*SHORT_FIXED_ONE))
+
+enum
+{
+        SOME_VALUE= FLOAT_TO_SHORT_FIXED(0.1) // expected-warning{{expression is not integer constant expression}}
+};
diff --git a/test/Sema/address-constant.c b/test/Sema/address-constant.c
new file mode 100644
index 0000000..e842a73
--- /dev/null
+++ b/test/Sema/address-constant.c
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+int i;
+int a[] = {0};
+struct { int i; } s;
+
+int *array[] = {&i, a, &s.i};
+
+extern void f(void);
+void (*f_addr)(void) = &f;
diff --git a/test/Sema/address_spaces.c b/test/Sema/address_spaces.c
new file mode 100644
index 0000000..6258114
--- /dev/null
+++ b/test/Sema/address_spaces.c
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify
+
+#define _AS1 __attribute__((address_space(1)))
+#define _AS2 __attribute__((address_space(2)))
+#define _AS3 __attribute__((address_space(3)))
+
+void bar(_AS2 int a); // expected-error {{parameter may not be qualified with an address space}}
+
+void foo(_AS3 float *a, 
+         _AS1 float b) // expected-error {{parameter may not be qualified with an address space}}
+{
+  _AS2 *x;// expected-warning {{type specifier missing, defaults to 'int'}}
+  _AS1 float * _AS2 *B;
+
+  int _AS1 _AS2 *Y;   // expected-error {{multiple address spaces specified for type}}
+  int *_AS1 _AS2 *Z;  // expected-error {{multiple address spaces specified for type}}
+
+  _AS1 int local;     // expected-error {{automatic variable qualified with an address space}}
+  _AS1 int array[5];  // expected-error {{automatic variable qualified with an address space}}
+  _AS1 int arrarr[5][5]; // expected-error {{automatic variable qualified with an address space}}
+
+  __attribute__((address_space(-1))) int *_boundsA; // expected-error {{address space is negative}}
+  __attribute__((address_space(0xFFFFFF))) int *_boundsB;
+  __attribute__((address_space(0x1000000))) int *_boundsC; // expected-error {{address space is larger than the maximum supported}}
+  // chosen specifically to overflow 32 bits and come out reasonable
+  __attribute__((address_space(4294967500))) int *_boundsD; // expected-error {{address space is larger than the maximum supported}}
+
+  *a = 5.0f + b;
+}
+
+struct _st {
+ int x, y;
+} s __attribute ((address_space(1))) = {1, 1};
+
+
+// rdar://6774906
+__attribute__((address_space(256))) void * * const base = 0;
+void * get_0(void) {
+  return base[0];  // expected-error {{illegal implicit cast between two pointers with different address spaces}} \
+                      expected-warning {{returning 'void __attribute__((address_space(256))) *' from a function with result type 'void *' discards qualifiers}}
+}
+
diff --git a/test/Sema/align-arm-apcs.c b/test/Sema/align-arm-apcs.c
new file mode 100644
index 0000000..0a5d3fe
--- /dev/null
+++ b/test/Sema/align-arm-apcs.c
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -triple arm-unknown-unknown -target-abi apcs-gnu -fsyntax-only -verify %s
+
+struct s0 { double f0; int f1; };
+char chk0[__alignof__(struct s0) == 4 ? 1 : -1]; 
diff --git a/test/Sema/align-x86.c b/test/Sema/align-x86.c
new file mode 100644
index 0000000..c9a6398
--- /dev/null
+++ b/test/Sema/align-x86.c
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -fsyntax-only -verify %s
+
+// PR3433
+double g1;
+short chk1[__alignof__(g1) == 8 ? 1 : -1]; 
+short chk2[__alignof__(double) == 8 ? 1 : -1];
+
+long long g2;
+short chk1[__alignof__(g2) == 8 ? 1 : -1]; 
+short chk2[__alignof__(long long) == 8 ? 1 : -1];
+
+_Complex double g3;
+short chk1[__alignof__(g3) == 8 ? 1 : -1]; 
+short chk2[__alignof__(_Complex double) == 8 ? 1 : -1];
+
+// PR6362
+struct __attribute__((packed)) {unsigned int a} g4;
+short chk1[__alignof__(g4) == 1 ? 1 : -1];
+short chk2[__alignof__(g4.a) == 1 ? 1 : -1];
+
diff --git a/test/Sema/altivec-init.c b/test/Sema/altivec-init.c
new file mode 100644
index 0000000..57abc93
--- /dev/null
+++ b/test/Sema/altivec-init.c
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 %s -triple=powerpc-apple-darwin8 -faltivec -verify -pedantic -fsyntax-only
+
+typedef int v4 __attribute((vector_size(16)));
+typedef short v8 __attribute((vector_size(16)));
+
+v8 foo(void) { 
+  v8 a;
+  v4 b;
+  a = (v8){4, 2};
+  b = (v4)(5, 6, 7, 8, 9); // expected-warning {{excess elements in vector initializer}}
+  b = (v4)(5, 6, 8, 8.0f);
+  return (v8){0, 1, 2, 3, 1, 2, 3, 4};
+
+  // FIXME: test that (type)(fn)(args) still works with -faltivec
+  // FIXME: test that c++ overloaded commas still work -faltivec
+}
diff --git a/test/Sema/annotate.c b/test/Sema/annotate.c
new file mode 100644
index 0000000..4d55075
--- /dev/null
+++ b/test/Sema/annotate.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify
+
+void __attribute__((annotate("foo"))) foo(float *a) { 
+  __attribute__((annotate("bar"))) int x;
+  __attribute__((annotate(1))) int y; // expected-error {{argument to annotate attribute was not a string literal}}
+  __attribute__((annotate("bar", 1))) int z; // expected-error {{attribute requires 1 argument(s)}}
+}
diff --git a/test/Sema/anonymous-struct-union.c b/test/Sema/anonymous-struct-union.c
new file mode 100644
index 0000000..d9e0839
--- /dev/null
+++ b/test/Sema/anonymous-struct-union.c
@@ -0,0 +1,104 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+struct X {
+  union {
+    float f3;
+    double d2;
+  } named;
+
+  union {
+    int i;
+    float f;
+    
+    union {
+      float f2;
+      double d;
+    };
+  };
+
+  struct {
+    int a;
+    float b;
+  };
+};
+
+void test_unqual_references(struct X x, const struct X xc) {
+  x.i = 0;
+  x.f = 0.0;
+  x.f2 = x.f;
+  x.d = x.f;
+  x.f3 = 0; // expected-error{{no member named 'f3'}}
+  x.a = 0;
+
+  xc.d = 0.0; // expected-error{{read-only variable is not assignable}}
+  xc.f = 0; // expected-error{{read-only variable is not assignable}}
+  xc.a = 0; // expected-error{{read-only variable is not assignable}}
+}
+
+
+struct Redecl {
+  int x; // expected-note{{previous declaration is here}}
+  struct y { };
+
+  union {
+    int x; // expected-error{{member of anonymous union redeclares 'x'}}
+    float y;
+    double z; // expected-note{{previous declaration is here}}
+    double zz; // expected-note{{previous declaration is here}}
+  };
+
+  int z; // expected-error{{duplicate member 'z'}}
+  void zz(); // expected-error{{duplicate member 'zz'}} 
+};
+
+union { // expected-warning{{declaration does not declare anything}}
+  int int_val;
+  float float_val;
+};
+
+static union { // expected-warning{{declaration does not declare anything}}
+  int int_val2;
+  float float_val2;
+};
+
+void f() {
+  int_val2 = 0; // expected-error{{use of undeclared identifier}}
+  float_val2 = 0.0; // expected-error{{use of undeclared identifier}}
+}
+
+void g() {
+  union { // expected-warning{{declaration does not declare anything}}
+    int i;
+    float f2;
+  };
+  i = 0; // expected-error{{use of undeclared identifier}}
+  f2 = 0.0; // expected-error{{use of undeclared identifier}}
+}
+
+// <rdar://problem/6483159>
+struct s0 { union { int f0; }; };
+
+// <rdar://problem/6481130>
+typedef struct { }; // expected-warning{{declaration does not declare anything}}
+
+// PR3675
+struct s1 {
+  int f0; // expected-note{{previous declaration is here}}
+  union {
+    int f0; // expected-error{{member of anonymous union redeclares 'f0'}}
+  };
+};
+
+// PR3680
+struct {}; // expected-warning{{declaration does not declare anything}}
+
+struct s2 {
+  union {
+    int a;
+  }
+}; // expected-error{{expected member name or ';' after declaration specifiers}}
+
+// Make sure we don't a.k.a. anonymous structs.
+typedef struct {
+  int x;
+} a_struct;
+int tmp = (a_struct) { .x = 0 }; // expected-error {{initializing 'int' with an expression of incompatible type 'a_struct'}}
diff --git a/test/Sema/arg-duplicate.c b/test/Sema/arg-duplicate.c
new file mode 100644
index 0000000..feeb458
--- /dev/null
+++ b/test/Sema/arg-duplicate.c
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+int f3(y, x, 
+       x)          // expected-error {{redefinition of parameter}}
+  int y, 
+      x,           // expected-note {{previous declaration is here}}
+      x;           // expected-error {{redefinition of parameter}}
+{
+  return x + y; 
+} 
+
+void f4(void) { 
+  f3 (1, 1, 2, 3, 4); // expected-warning{{too many arguments}}
+}
+
diff --git a/test/Sema/arg-scope-c99.c b/test/Sema/arg-scope-c99.c
new file mode 100644
index 0000000..912776a
--- /dev/null
+++ b/test/Sema/arg-scope-c99.c
@@ -0,0 +1,2 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c99 -verify %s
+void bb(int sz, int ar[sz][sz]) { }
diff --git a/test/Sema/arg-scope.c b/test/Sema/arg-scope.c
new file mode 100644
index 0000000..ed92619
--- /dev/null
+++ b/test/Sema/arg-scope.c
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+void aa(int b, int x[sizeof b]) {}
+
+void foo(int i, int A[i]) {}
+
diff --git a/test/Sema/arm-layout.c b/test/Sema/arm-layout.c
new file mode 100644
index 0000000..4248685
--- /dev/null
+++ b/test/Sema/arm-layout.c
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 -triple armv7-unknown-unknown -target-abi apcs-gnu %s -verify
+// RUN: %clang_cc1 -triple armv7-unknown-unknown -target-abi aapcs %s -verify
+
+#define check(name, cond) int _##name##_check[(cond) ? 1 : -1]
+
+struct s0 { char field0; double field1; };
+#ifdef __ARM_EABI__
+check(s0_size, sizeof(struct s0) == 16);
+#else
+check(s0_size, sizeof(struct s0) == 12);
+#endif
+
+struct s1 { char field0; long double field1; };
+#ifdef __ARM_EABI__
+check(s1_size, sizeof(struct s1) == 16);
+#else
+check(s1_size, sizeof(struct s1) == 12);
+#endif
+
+struct s2 {
+  short field0;
+  int field1 : 24;
+  char field2;
+};
+#ifdef __ARM_EABI__
+check(s2_size, sizeof(struct s2) == 8);
+check(s2_offset_0, __builtin_offsetof(struct s2, field0) == 0);
+check(s2_offset_1, __builtin_offsetof(struct s2, field2) == 7);
+#else
+check(s2_size, sizeof(struct s2) == 6);
+check(s2_offset_0, __builtin_offsetof(struct s2, field0) == 0);
+check(s2_offset_1, __builtin_offsetof(struct s2, field2) == 5);
+#endif
+
+struct s3 {
+  short field0;
+  int field1 : 24 __attribute__((aligned(4)));
+  char field2;
+};
+check(s3_size, sizeof(struct s3) == 8);
+check(s3_offset_0, __builtin_offsetof(struct s3, field0) == 0);
+check(s3_offset_1, __builtin_offsetof(struct s3, field2) == 7);
+
+struct s4 {
+  int field0 : 4
+};
+#ifdef __ARM_EABI__
+check(s4_size, sizeof(struct s4) == 4);
+check(s4_align, __alignof(struct s4) == 4);
+#else
+check(s4_size, sizeof(struct s4) == 1);
+check(s4_align, __alignof(struct s4) == 1);
+#endif
diff --git a/test/Sema/array-constraint.c b/test/Sema/array-constraint.c
new file mode 100644
index 0000000..9fcac25
--- /dev/null
+++ b/test/Sema/array-constraint.c
@@ -0,0 +1,52 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s
+
+struct s;  // expected-note 2 {{forward declaration of 'struct s'}}
+struct s* t (struct s z[]) {   // expected-error {{array has incomplete element type}}
+  return z;
+}
+
+void ff() { 
+  struct s v, *p; // expected-error {{variable has incomplete type 'struct s'}}
+
+  p = &v;
+}
+
+void *k (void l[2]) {          // expected-error {{array has incomplete element type}}
+  return l; 
+}
+
+struct vari {
+  int a;
+  int b[];
+};
+
+struct vari *func(struct vari a[]) { // expected-warning {{'struct vari' may not be used as an array element due to flexible array member}}
+  return a;
+}
+
+int foo[](void);  // expected-error {{'foo' declared as array of functions}}
+int foo2[1](void);  // expected-error {{'foo2' declared as array of functions}}
+
+typedef int (*pfunc)(void);
+
+pfunc xx(int f[](void)) { // expected-error {{'f' declared as array of functions}}
+  return f;
+}
+
+void check_size() {
+  float f;
+  int size_not_int[f]; // expected-error {{size of array has non-integer type 'float'}}
+  int negative_size[1-2]; // expected-error{{array size is negative}}
+  int zero_size[0]; // expected-warning{{zero size arrays are an extension}}
+}
+
+static int I;
+typedef int TA[I]; // expected-error {{variable length array declaration not allowed at file scope}}
+
+void strFunc(char *); // expected-note{{passing argument to parameter here}}
+const char staticAry[] = "test";
+void checkStaticAry() { 
+  strFunc(staticAry); // expected-warning{{passing 'char const [5]' to parameter of type 'char *' discards qualifiers}}
+}
+
+
diff --git a/test/Sema/array-declared-as-incorrect-type.c b/test/Sema/array-declared-as-incorrect-type.c
new file mode 100644
index 0000000..b93fa9a
--- /dev/null
+++ b/test/Sema/array-declared-as-incorrect-type.c
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s
+
+extern int a1[];
+int a1[1];
+
+extern int a2[]; // expected-note {{previous definition is here}}
+float a2[1]; // expected-error {{redefinition of 'a2'}}
+
+extern int a3[][2];
+int a3[1][2];
+
+extern int a4[][2]; // expected-note {{previous definition is here}}
+int a4[2]; // expected-error {{redefinition of 'a4'}}
+
+extern int a5[1][2][3]; // expected-note {{previous definition is here}}
+int a5[3][2][1]; // expected-error {{redefinition of 'a5'}}
diff --git a/test/Sema/array-init.c b/test/Sema/array-init.c
new file mode 100644
index 0000000..f93b087
--- /dev/null
+++ b/test/Sema/array-init.c
@@ -0,0 +1,264 @@
+// RUN: %clang_cc1 -fsyntax-only -pedantic -verify %s
+
+extern int foof() = 1; // expected-error{{illegal initializer (only variables can be initialized)}}
+
+static int x, y, z;
+
+static int ary[] = { x, y, z }; // expected-error{{initializer element is not a compile-time constant}}
+int ary2[] = { x, y, z }; // expected-error{{initializer element is not a compile-time constant}}
+
+extern int fileScopeExtern[3] = { 1, 3, 5 }; // expected-warning{{'extern' variable has an initializer}}
+
+static long ary3[] = { 1, "abc", 3, 4 }; // expected-warning{{incompatible pointer to integer conversion initializing 'long' with an expression of type 'char [4]'}}
+
+void func() {
+  int x = 1;
+
+  typedef int TInt = 1; // expected-error{{illegal initializer (only variables can be initialized)}}
+
+  int xComputeSize[] = { 1, 3, 5 };
+
+  int x3[x] = { 1, 2 }; // expected-error{{variable-sized object may not be initialized}}
+
+  int x4 = { 1, 2 }; // expected-warning{{excess elements in scalar initializer}}
+
+  int y[4][3] = { 
+    { 1, 3, 5 },
+    { 2, 4, 6 },
+    { 3, 5, 7 },
+  };
+
+  int y2[4][3] = {
+    1, 3, 5, 2, 4, 6, 3, 5, 7
+  };
+
+  int y3[4][3] = {  
+    { 1, 3, 5 },
+    { 2, 4, 6 },
+    { 3, 5, 7 },
+    { 4, 6, 8 },
+    { 5 }, // expected-warning{{excess elements in array initializer}}
+  };
+
+  struct threeElements {
+    int a,b,c;
+  } z = { 1 };
+
+  struct threeElements *p = 7; // expected-warning{{incompatible integer to pointer conversion initializing 'struct threeElements *' with an expression of type 'int'}}
+  
+  extern int blockScopeExtern[3] = { 1, 3, 5 }; // expected-error{{'extern' variable cannot have an initializer}}
+  
+  static long x2[3] = { 1.0, "abc" , 5.8 }; // expected-warning{{incompatible pointer to integer conversion initializing 'long' with an expression of type 'char [4]'}}
+}
+
+void test() {
+  int y1[3] = { 
+    { 1, 2, 3 } // expected-warning{{braces around scalar initializer}} expected-warning{{excess elements in scalar initializer}}
+  };
+  int y3[4][3] = {  
+    { 1, 3, 5 },
+    { 2, 4, 6 },
+    { 3, 5, 7 },
+    { 4, 6, 8 },
+    {  }, // expected-warning{{use of GNU empty initializer extension}} expected-warning{{excess elements in array initializer}}
+  };
+  int y4[4][3] = {  
+    { 1, 3, 5, 2 }, // expected-warning{{excess elements in array initializer}}
+    { 4, 6 },
+    { 3, 5, 7 },
+    { 4, 6, 8 },
+  };
+}
+
+void allLegalAndSynonymous() {
+  short q[4][3][2] = {
+    { 1 },
+    { 2, 3 },
+    { 4, 5, 6 }
+  };
+  short q2[4][3][2] = {
+    { 1, 0, 0, 0, 0, 0 },
+    { 2, 3, 0, 0, 0, 0 },
+    { 4, 5, 6 }
+  };
+  short q3[4][3][2] = {
+    { 
+      { 1 },
+    },
+    { 
+      { 2, 3 },
+    },
+    { 
+      { 4, 5 },
+      { 6 },
+    },
+  };
+}
+
+void legal() {
+  short q[][3][2] = {
+    { 1 },
+    { 2, 3 },
+    { 4, 5, 6 }
+  };
+  int q_sizecheck[(sizeof(q) / sizeof(short [3][2])) == 3? 1 : -1];
+}
+
+unsigned char asso_values[] = { 34 };
+int legal2() { 
+  return asso_values[0]; 
+}
+
+void illegal() {
+  short q2[4][][2] = { // expected-error{{array has incomplete element type 'short [][2]'}}
+    { 1, 0, 0, 0, 0, 0 },
+    { 2, 3, 0, 0, 0, 0 },
+    { 4, 5, 6 }
+  };
+  short q3[4][3][] = { // expected-error{{array has incomplete element type 'short []'}}
+    { 
+      { 1 },
+    },
+    { 
+      { 2, 3 },
+    },
+    { 
+      { 4, 5 },
+      { 6 },
+    },
+  };
+  int a[][] = { 1, 2 }; // expected-error{{array has incomplete element type 'int []'}}
+}
+
+typedef int AryT[];
+
+void testTypedef()
+{
+  AryT a = { 1, 2 }, b = { 3, 4, 5 };
+  int a_sizecheck[(sizeof(a) / sizeof(int)) == 2? 1 : -1];
+  int b_sizecheck[(sizeof(b) / sizeof(int)) == 3? 1 : -1];
+}
+
+static char const xx[] = "test";
+int xx_sizecheck[(sizeof(xx) / sizeof(char)) == 5? 1 : -1];
+static char const yy[5] = "test";
+static char const zz[3] = "test"; // expected-warning{{initializer-string for char array is too long}}
+
+void charArrays() {
+  static char const test[] = "test";
+  int test_sizecheck[(sizeof(test) / sizeof(char)) == 5? 1 : -1];
+  static char const test2[] = { "weird stuff" };
+  static char const test3[] = { "test", "excess stuff" }; // expected-warning{{excess elements in char array initializer}}
+
+  char* cp[] = { "Hello" };
+
+  char c[] = { "Hello" };
+  int l[sizeof(c) == 6 ? 1 : -1];
+  
+  int i[] = { "Hello "}; // expected-warning{{incompatible pointer to integer conversion initializing 'int' with an expression of type 'char [7]'}}
+  char c2[] = { "Hello", "Good bye" }; //expected-warning{{excess elements in char array initializer}}
+
+  int i2[1] = { "Hello" }; //expected-warning{{incompatible pointer to integer conversion initializing 'int' with an expression of type 'char [6]'}}
+  char c3[5] = { "Hello" };
+  char c4[4] = { "Hello" }; //expected-warning{{initializer-string for char array is too long}}
+
+  int i3[] = {}; //expected-warning{{zero size arrays are an extension}} expected-warning{{use of GNU empty initializer extension}}
+}
+
+void variableArrayInit() {
+  int a = 4;
+  char strlit[a] = "foo"; //expected-error{{array initializer must be an initializer list or string literal}}
+  int b[a] = { 1, 2, 4 }; //expected-error{{variable-sized object may not be initialized}}
+}
+
+// Pure array tests
+float r1[10] = {{7}}; //expected-warning{{braces around scalar initializer}}
+float r2[] = {{8}}; //expected-warning{{braces around scalar initializer}}
+char r3[][5] = {1,2,3,4,5,6};
+int r3_sizecheck[(sizeof(r3) / sizeof(char[5])) == 2? 1 : -1];
+char r3_2[sizeof r3 == 10 ? 1 : -1];
+float r4[1][2] = {1,{2},3,4}; //expected-warning{{braces around scalar initializer}} expected-warning{{excess elements in array initializer}}
+char r5[][5] = {"aa", "bbb", "ccccc"};
+char r6[sizeof r5 == 15 ? 1 : -1];
+const char r7[] = "zxcv";
+char r8[5] = "5char";
+char r9[5] = "6chars"; //expected-warning{{initializer-string for char array is too long}}
+
+int r11[0] = {}; //expected-warning{{zero size arrays are an extension}} expected-warning{{use of GNU empty initializer extension}}
+
+// Some struct tests
+void autoStructTest() {
+struct s1 {char a; char b;} t1;
+struct s2 {struct s1 c;} t2 = { t1 };
+// The following is a less than great diagnostic (though it's on par with EDG).
+struct s1 t3[] = {t1, t1, "abc", 0}; //expected-warning{{incompatible pointer to integer conversion initializing 'char' with an expression of type 'char [4]'}}
+int t4[sizeof t3 == 6 ? 1 : -1];
+}
+struct foo { int z; } w;
+int bar (void) { 
+  struct foo z = { w }; //expected-error{{initializing 'int' with an expression of incompatible type 'struct foo'}}
+  return z.z; 
+} 
+struct s3 {void (*a)(void);} t5 = {autoStructTest};
+struct {int a; int b[];} t6 = {1, {1, 2, 3}}; // expected-warning{{flexible array initialization is a GNU extension}} \
+// expected-note{{initialized flexible array member 'b' is here}}
+union {char a; int b;} t7[] = {1, 2, 3};
+int t8[sizeof t7 == (3*sizeof(int)) ? 1 : -1];
+
+struct bittest{int : 31, a, :21, :12, b;};
+struct bittest bittestvar = {1, 2, 3, 4}; //expected-warning{{excess elements in struct initializer}}
+
+// Not completely sure what should happen here...
+int u1 = {}; //expected-warning{{use of GNU empty initializer extension}} expected-error{{scalar initializer cannot be empty}}
+int u2 = {{3}}; //expected-error{{too many braces around scalar initializer}}
+
+// PR2362
+void varArray() {
+  int c[][x] = { 0 }; //expected-error{{variable-sized object may not be initialized}}
+}
+
+// PR2151
+void emptyInit() {struct {} x[] = {6};} //expected-warning{{empty struct extension}} expected-error{{initializer for aggregate with no elements}}
+
+void noNamedInit() {
+  struct {int:5;} x[] = {6}; //expected-error{{initializer for aggregate with no elements}}
+}
+struct {int a; int:5;} noNamedImplicit[] = {1,2,3};
+int noNamedImplicitCheck[sizeof(noNamedImplicit) == 3 * sizeof(*noNamedImplicit) ? 1 : -1];
+
+
+// ptrs are constant
+struct soft_segment_descriptor {
+  long ssd_base;
+};
+static int dblfault_tss;
+
+union uniao { int ola; } xpto[1];
+
+struct soft_segment_descriptor gdt_segs[] = {
+  {(long) &dblfault_tss},
+  { (long)xpto},
+};
+
+static void sppp_ipv6cp_up();
+const struct {} ipcp = { sppp_ipv6cp_up }; //expected-warning{{empty struct extension}} expected-warning{{excess elements in struct initializer}}
+
+struct _Matrix { union { float m[4][4]; }; }; //expected-warning{{anonymous unions are a GNU extension in C}}
+typedef struct _Matrix Matrix;
+void test_matrix() {
+  const Matrix mat1 = {
+    { { 1.0f, 2.0f, 3.0f, 4.0f,
+        5.0f, 6.0f, 7.0f, 8.0f,
+        9.0f, 10.0f, 11.0f, 12.0f,
+        13.0f, 14.0f, 15.0f, 16.0f } }
+  };
+
+  const Matrix mat2 = {
+    1.0f, 2.0f, 3.0f, 4.0f,
+    5.0f, 6.0f, 7.0f, 8.0f,
+    9.0f, 10.0f, 11.0f, 12.0f,
+    13.0f, 14.0f, 15.0f, 16.0f 
+  };
+}
+
+char badchararray[1] = { badchararray[0], "asdf" }; // expected-warning {{excess elements in array initializer}} expected-error {{initializer element is not a compile-time constant}}
diff --git a/test/Sema/asm.c b/test/Sema/asm.c
new file mode 100644
index 0000000..6f2272d
--- /dev/null
+++ b/test/Sema/asm.c
@@ -0,0 +1,81 @@
+// RUN: %clang_cc1 %s -triple i386-pc-linux-gnu -verify -fsyntax-only
+
+void f() {
+  int i;
+
+  asm ("foo\n" : : "a" (i + 2));
+  asm ("foo\n" : : "a" (f())); // expected-error {{invalid type 'void' in asm input}}
+  
+  asm ("foo\n" : "=a" (f())); // expected-error {{invalid lvalue in asm output}}
+  asm ("foo\n" : "=a" (i + 2)); // expected-error {{invalid lvalue in asm output}}
+
+  asm ("foo\n" : [symbolic_name] "=a" (i) : "[symbolic_name]" (i));
+  asm ("foo\n" : "=a" (i) : "[" (i)); // expected-error {{invalid input constraint '[' in asm}}
+  asm ("foo\n" : "=a" (i) : "[foo" (i)); // expected-error {{invalid input constraint '[foo' in asm}}
+  asm ("foo\n" : "=a" (i) : "[symbolic_name]" (i)); // expected-error {{invalid input constraint '[symbolic_name]' in asm}}
+}
+
+void clobbers() {
+  asm ("nop" : : : "ax", "#ax", "%ax");
+  asm ("nop" : : : "eax", "rax", "ah", "al");
+  asm ("nop" : : : "0", "%0", "#0");
+  asm ("nop" : : : "foo"); // expected-error {{unknown register name 'foo' in asm}}
+  asm ("nop" : : : "52");
+  asm ("nop" : : : "53"); // expected-error {{unknown register name '53' in asm}}
+  asm ("nop" : : : "-1"); // expected-error {{unknown register name '-1' in asm}}
+  asm ("nop" : : : "+1"); // expected-error {{unknown register name '+1' in asm}}
+}
+
+// rdar://6094010
+void test3() {
+  int x;
+  asm(L"foo" : "=r"(x)); // expected-error {{wide string}}
+  asm("foo" : L"=r"(x)); // expected-error {{wide string}}
+}
+
+// <rdar://problem/6156893>
+void test4(const volatile void *addr)
+{
+    asm ("nop" : : "r"(*addr)); // expected-error {{invalid type 'void const volatile' in asm input for constraint 'r'}}
+    asm ("nop" : : "m"(*addr));
+
+    asm ("nop" : : "r"(test4(addr))); // expected-error {{invalid type 'void' in asm input for constraint 'r'}}
+    asm ("nop" : : "m"(test4(addr))); // expected-error {{invalid lvalue in asm input for constraint 'm'}}
+
+    asm ("nop" : : "m"(f())); // expected-error {{invalid lvalue in asm input for constraint 'm'}}
+}
+
+// <rdar://problem/6512595>
+void test5() {
+  asm("nop" : : "X" (8)); 
+}
+
+// PR3385
+void test6(long i) {
+  asm("nop" : : "er"(i));
+}
+
+void asm_string_tests(int i) {
+  asm("%!");   // simple asm string, %! is not an error.   
+  asm("%!" : );   // expected-error {{invalid % escape in inline assembly string}}
+  asm("xyz %" : );   // expected-error {{invalid % escape in inline assembly string}}
+
+  asm ("%[somename]" :: [somename] "i"(4)); // ok
+  asm ("%[somename]" :: "i"(4)); // expected-error {{unknown symbolic operand name in inline assembly string}}
+  asm ("%[somename" :: "i"(4)); // expected-error {{unterminated symbolic operand name in inline assembly string}}
+  asm ("%[]" :: "i"(4)); // expected-error {{empty symbolic operand name in inline assembly string}}
+  
+  // PR3258
+  asm("%9" :: "i"(4)); // expected-error {{invalid operand number in inline asm string}}
+  asm("%1" : "+r"(i)); // ok, referring to input.
+}
+
+// PR4077
+int test7(unsigned long long b) {
+  int a;
+  asm volatile("foo %0 %1" : "=a" (a) :"0" (b)); // expected-error {{input with type 'unsigned long long' matching output with type 'int'}}
+  return a;
+}
+
+// <rdar://problem/7574870>
+asm volatile (""); // expected-warning {{meaningless 'volatile' on asm outside function}}
diff --git a/test/Sema/assign-null.c b/test/Sema/assign-null.c
new file mode 100644
index 0000000..7f172b1
--- /dev/null
+++ b/test/Sema/assign-null.c
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+#include <stddef.h>
+
+typedef void (*hookfunc)(void *arg);
+hookfunc hook;
+
+void clear_hook() {
+  hook = NULL;
+}
diff --git a/test/Sema/assign.c b/test/Sema/assign.c
new file mode 100644
index 0000000..2d57029
--- /dev/null
+++ b/test/Sema/assign.c
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+void *test1(void) { return 0; }
+
+void test2 (const struct {int a;} *x) {
+  x->a = 10; // expected-error {{read-only variable is not assignable}}
+}
+
+typedef int arr[10];
+void test3() {
+  const arr b;
+  const int b2[10]; 
+  b[4] = 1; // expected-error {{read-only variable is not assignable}}
+  b2[4] = 1; // expected-error {{read-only variable is not assignable}}
+}
diff --git a/test/Sema/ast-print.c b/test/Sema/ast-print.c
new file mode 100644
index 0000000..ff66d35
--- /dev/null
+++ b/test/Sema/ast-print.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 %s -ast-print
+
+typedef void func_typedef();
+func_typedef xxx;
+
+typedef void func_t(int x);
+func_t a;
+
diff --git a/test/Sema/attr-aligned.c b/test/Sema/attr-aligned.c
new file mode 100644
index 0000000..bcb12ee
--- /dev/null
+++ b/test/Sema/attr-aligned.c
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -fsyntax-only -verify %s
+
+int x __attribute__((aligned(3))); // expected-error {{requested alignment is not a power of 2}}
+
+// PR3254
+short g0[3] __attribute__((aligned));
+short g0_chk[__alignof__(g0) == 16 ? 1 : -1]; 
+
+// <rdar://problem/6840045>
+typedef char ueber_aligned_char __attribute__((aligned(8)));
+
+struct struct_with_ueber_char {
+  ueber_aligned_char c;
+};
+
+char c = 0;
+
+char a0[__alignof__(ueber_aligned_char) == 8? 1 : -1] = { 0 };
+char a1[__alignof__(struct struct_with_ueber_char) == 8? 1 : -1] = { 0 };
+char a2[__alignof__(c) == 1? : -1] = { 0 };
+char a3[sizeof(c) == 1? : -1] = { 0 };
diff --git a/test/Sema/attr-cleanup.c b/test/Sema/attr-cleanup.c
new file mode 100644
index 0000000..9057c27
--- /dev/null
+++ b/test/Sema/attr-cleanup.c
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only
+
+void c1(int *a);
+
+extern int g1 __attribute((cleanup(c1))); // expected-warning {{cleanup attribute ignored}}
+int g2 __attribute((cleanup(c1))); // expected-warning {{cleanup attribute ignored}}
+static int g3 __attribute((cleanup(c1))); // expected-warning {{cleanup attribute ignored}}
+
+void t1()
+{
+    int v1 __attribute((cleanup)); // expected-error {{attribute requires 1 argument(s)}}
+    int v2 __attribute((cleanup(1, 2))); // expected-error {{attribute requires 1 argument(s)}}
+    
+    static int v3 __attribute((cleanup(c1))); // expected-warning {{cleanup attribute ignored}}
+    
+    int v4 __attribute((cleanup(h))); // expected-error {{'cleanup' argument 'h' not found}}
+
+    int v5 __attribute((cleanup(c1)));
+    int v6 __attribute((cleanup(v3))); // expected-error {{'cleanup' argument 'v3' is not a function}}
+}
+
+struct s {
+    int a, b;
+};
+
+void c2();
+void c3(struct s a);
+
+void t2()
+{
+    int v1 __attribute__((cleanup(c2))); // expected-error {{'cleanup' function 'c2' must take 1 parameter}}
+    int v2 __attribute__((cleanup(c3))); // expected-error {{'cleanup' function 'c3' parameter has type 'struct s' which is incompatible with type 'int *'}}
+}
+
+// This is a manufactured testcase, but gcc accepts it...
+void c4(_Bool a);
+void t4() {
+  __attribute((cleanup(c4))) void* g;
+}
+
diff --git a/test/Sema/attr-decl-after-definition.c b/test/Sema/attr-decl-after-definition.c
new file mode 100644
index 0000000..4d32e00
--- /dev/null
+++ b/test/Sema/attr-decl-after-definition.c
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+void foo();
+void foo() __attribute__((unused));
+void foo() __attribute__((unused));
+void foo(){} // expected-note {{previous definition is here}}
+void foo() __attribute__((constructor)); // expected-warning {{must precede definition}}
+void foo();
+
+int bar;
+extern int bar;
+int bar;
+int bar __attribute__((weak));
+int bar __attribute__((used));
+extern int bar __attribute__((weak));
+int bar = 0; // expected-note {{previous definition is here}}
+int bar __attribute__((weak)); // expected-warning {{must precede definition}}
+int bar;
+
diff --git a/test/Sema/attr-deprecated.c b/test/Sema/attr-deprecated.c
new file mode 100644
index 0000000..e723255
--- /dev/null
+++ b/test/Sema/attr-deprecated.c
@@ -0,0 +1,102 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only
+
+int f() __attribute__((deprecated));
+void g() __attribute__((deprecated));
+void g();
+
+void z() __attribute__((bogusattr)); // expected-warning {{'bogusattr' attribute ignored}}
+
+extern int var __attribute__((deprecated));
+
+int a() {
+  int (*ptr)() = f; // expected-warning {{'f' is deprecated}}
+  f(); // expected-warning {{'f' is deprecated}}
+
+  // test if attributes propagate to functions
+  g(); // expected-warning {{'g' is deprecated}}
+
+  return var; // expected-warning {{'var' is deprecated}}
+}
+
+// test if attributes propagate to variables
+extern int var;
+int w() {
+  return var; // expected-warning {{'var' is deprecated}}
+}
+
+int old_fn() __attribute__ ((deprecated));
+int old_fn();
+int (*fn_ptr)() = old_fn; // expected-warning {{'old_fn' is deprecated}}
+
+int old_fn() {
+  return old_fn()+1;  // no warning, deprecated functions can use deprecated symbols.
+}
+
+
+struct foo {
+  int x __attribute__((deprecated));
+};
+
+void test1(struct foo *F) {
+  ++F->x;  // expected-warning {{'x' is deprecated}}
+}
+
+typedef struct foo foo_dep __attribute__((deprecated));
+foo_dep *test2;    // expected-warning {{'foo_dep' is deprecated}}
+
+struct bar_dep __attribute__((deprecated, 
+                              invalid_attribute));  // expected-warning {{'invalid_attribute' attribute ignored}}
+
+struct bar_dep *test3;   // expected-warning {{'bar_dep' is deprecated}}
+
+
+// These should not warn because the actually declaration itself is deprecated.
+// rdar://6756623
+foo_dep *test4 __attribute__((deprecated));
+struct bar_dep *test5 __attribute__((deprecated));
+
+typedef foo_dep test6(struct bar_dep*); // expected-warning {{'foo_dep' is deprecated}} \
+                                        // expected-warning {{'bar_dep' is deprecated}}
+typedef foo_dep test7(struct bar_dep*) __attribute__((deprecated));
+
+int test8(char *p) {
+  p += sizeof(foo_dep); // expected-warning {{'foo_dep' is deprecated}}
+
+  foo_dep *ptr;         // expected-warning {{'foo_dep' is deprecated}}
+  ptr = (foo_dep*) p;   // expected-warning {{'foo_dep' is deprecated}}
+
+  int func(foo_dep *foo); // expected-warning {{'foo_dep' is deprecated}}
+  return func(ptr);
+}
+
+foo_dep *test9(void) __attribute__((deprecated));
+foo_dep *test9(void) {
+  void* myalloc(unsigned long);
+
+  foo_dep *ptr
+    = (foo_dep*)
+        myalloc(sizeof(foo_dep));
+  return ptr;
+}
+
+void test10(void) __attribute__((deprecated));
+void test10(void) {
+  if (sizeof(foo_dep) == sizeof(void*)) {
+  }
+  foo_dep *localfunc(void);
+  foo_dep localvar;
+}
+
+char test11[sizeof(foo_dep)] __attribute__((deprecated));
+char test12[sizeof(foo_dep)]; // expected-warning {{'foo_dep' is deprecated}}
+
+int test13(foo_dep *foo) __attribute__((deprecated));
+int test14(foo_dep *foo); // expected-warning {{'foo_dep' is deprecated}}
+
+unsigned long test15 = sizeof(foo_dep); // expected-warning {{'foo_dep' is deprecated}}
+unsigned long test16 __attribute__((deprecated))
+  = sizeof(foo_dep);
+
+foo_dep test17, // expected-warning {{'foo_dep' is deprecated}}
+        test18 __attribute__((deprecated)),
+        test19;
diff --git a/test/Sema/attr-format.c b/test/Sema/attr-format.c
new file mode 100644
index 0000000..a223e08
--- /dev/null
+++ b/test/Sema/attr-format.c
@@ -0,0 +1,80 @@
+//RUN: %clang_cc1 -fsyntax-only -verify %s
+
+#include <stdarg.h>
+
+void a(const char *a, ...) __attribute__((format(printf, 1,2))); // no-error
+void b(const char *a, ...) __attribute__((format(printf, 1,1))); // expected-error {{'format' attribute parameter 3 is out of bounds}}
+void c(const char *a, ...) __attribute__((format(printf, 0,2))); // expected-error {{'format' attribute parameter 2 is out of bounds}}
+void d(const char *a, int c) __attribute__((format(printf, 1,2))); // expected-error {{format attribute requires variadic function}}
+void e(char *str, int c, ...) __attribute__((format(printf, 2,3))); // expected-error {{format argument not a string type}}
+
+typedef const char* xpto;
+void f(xpto c, va_list list) __attribute__((format(printf, 1, 0))); // no-error
+void g(xpto c) __attribute__((format(printf, 1, 0))); // no-error
+
+void y(char *str) __attribute__((format(strftime, 1,0))); // no-error
+void z(char *str, int c, ...) __attribute__((format(strftime, 1,2))); // expected-error {{strftime format attribute requires 3rd parameter to be 0}}
+
+int (*f_ptr)(char*,...) __attribute__((format(printf, 1,2))); // no-error
+int (*f2_ptr)(double,...) __attribute__((format(printf, 1, 2))); // expected-error {{format argument not a string type}}
+
+struct _mystruct {
+  int (*printf)(const char *format, ...) __attribute__((__format__(printf, 1, 2))); // no-error
+  int (*printf2)(double format, ...) __attribute__((__format__(printf, 1, 2))); // expected-error {{format argument not a string type}}
+};
+
+typedef int (*f3_ptr)(char*,...) __attribute__((format(printf,1,0))); // no-error
+
+// <rdar://problem/6623513>
+int rdar6623513(void *, const char*, const char*, ...)
+  __attribute__ ((format (printf, 3, 0)));
+
+int rdar6623513_aux(int len, const char* s) {
+  rdar6623513(0, "hello", "%.*s", len, s);
+}
+
+
+
+// same as format(printf(...))...
+void a2(const char *a, ...)    __attribute__((format(printf0, 1,2))); // no-error
+void b2(const char *a, ...)    __attribute__((format(printf0, 1,1))); // expected-error {{'format' attribute parameter 3 is out of bounds}}
+void c2(const char *a, ...)    __attribute__((format(printf0, 0,2))); // expected-error {{'format' attribute parameter 2 is out of bounds}}
+void d2(const char *a, int c)  __attribute__((format(printf0, 1,2))); // expected-error {{format attribute requires variadic function}}
+void e2(char *str, int c, ...) __attribute__((format(printf0, 2,3))); // expected-error {{format argument not a string type}}
+
+// FreeBSD usage
+#define __printf0like(fmt,va) __attribute__((__format__(__printf0__,fmt,va)))
+void null(int i, const char *a, ...) __printf0like(2,0); // no-error
+void null(int i, const char *a, ...) { // expected-note{{passing argument to parameter 'a' here}}
+  if (a)
+    (void)0/* vprintf(...) would go here */;
+}
+
+void callnull(void){
+  null(0,        0); // no error
+  null(0, (char*)0); // no error
+  null(0, (void*)0); // no error
+  null(0,  (int*)0); // expected-warning {{incompatible pointer types}}
+}
+
+
+
+// PR4470
+int xx_vprintf(const char *, va_list);
+
+const char *foo(const char *format) __attribute__((format_arg(1)));
+
+void __attribute__((format(printf, 1, 0)))
+foo2(const char *fmt, va_list va) {
+  xx_vprintf(foo(fmt), va);
+}
+
+// PR6542
+extern void gcc_format (const char *, ...)
+  __attribute__ ((__format__(__gcc_diag__, 1, 2)));
+extern void gcc_cformat (const char *, ...)
+  __attribute__ ((__format__(__gcc_cdiag__, 1, 2)));
+extern void gcc_cxxformat (const char *, ...)
+  __attribute__ ((__format__(__gcc_cxxdiag__, 1, 2)));
+extern void gcc_tformat (const char *, ...)
+  __attribute__ ((__format__(__gcc_tdiag__, 1, 2)));
diff --git a/test/Sema/attr-format_arg.c b/test/Sema/attr-format_arg.c
new file mode 100644
index 0000000..64a2387
--- /dev/null
+++ b/test/Sema/attr-format_arg.c
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+int printf(const char *, ...);
+
+const char* f(const char *s) __attribute__((format_arg(1)));
+
+void g(const char *s) {
+  printf("%d", 123);
+  printf("%d %d", 123); // expected-warning{{more '%' conversions than data arguments}}
+
+  printf(f("%d"), 123);
+  printf(f("%d %d"), 123); // expected-warning{{more '%' conversions than data arguments}}
+}
diff --git a/test/Sema/attr-malloc.c b/test/Sema/attr-malloc.c
new file mode 100644
index 0000000..9970b9d
--- /dev/null
+++ b/test/Sema/attr-malloc.c
@@ -0,0 +1,25 @@
+// RUN: %clang -Xclang -verify -fsyntax-only %s
+// RUN: %clang -emit-llvm -S -o %t %s
+
+#include <stdlib.h>
+
+int no_vars __attribute((malloc)); // expected-warning {{functions returning a pointer type}}
+
+void  returns_void  (void) __attribute((malloc)); // expected-warning {{functions returning a pointer type}}
+int   returns_int   (void) __attribute((malloc)); // expected-warning {{functions returning a pointer type}}
+int * returns_intptr(void) __attribute((malloc)); // no-warning
+typedef int * iptr;
+iptr  returns_iptr  (void) __attribute((malloc)); // no-warning
+
+__attribute((malloc)) void *(*f)(); //  expected-warning{{'malloc' attribute only applies to functions returning a pointer type}}
+__attribute((malloc)) int (*g)(); // expected-warning{{'malloc' attribute only applies to functions returning a pointer type}}
+
+__attribute((malloc))
+void * xalloc(unsigned n) { return malloc(n); } // no-warning
+// RUN: grep 'define noalias .* @xalloc(' %t
+
+#define malloc_like __attribute((__malloc__))
+void * xalloc2(unsigned) malloc_like;
+void * xalloc2(unsigned n) { return malloc(n); }
+// RUN: grep 'define noalias .* @xalloc2(' %t
+
diff --git a/test/Sema/attr-mode.c b/test/Sema/attr-mode.c
new file mode 100644
index 0000000..0c53362
--- /dev/null
+++ b/test/Sema/attr-mode.c
@@ -0,0 +1,59 @@
+// RUN: %clang_cc1 -triple i686-pc-linux-gnu -DTEST_32BIT_X86 -fsyntax-only \
+// RUN:   -verify %s
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -DTEST_64BIT_X86 -fsyntax-only \
+// RUN:   -verify %s
+
+typedef int i16_1 __attribute((mode(HI)));
+int i16_1_test[sizeof(i16_1) == 2 ? 1 : -1];
+typedef int i16_2 __attribute((__mode__(__HI__)));
+int i16_2_test[sizeof(i16_1) == 2 ? 1 : -1];
+
+typedef float f64 __attribute((mode(DF)));
+int f64_test[sizeof(f64) == 8 ? 1 : -1];
+
+typedef int invalid_1 __attribute((mode)); // expected-error{{attribute requires unquoted parameter}}
+typedef int invalid_2 __attribute((mode())); // expected-error{{attribute requires unquoted parameter}}
+typedef int invalid_3 __attribute((mode(II))); // expected-error{{unknown machine mode}}
+typedef struct {int i,j,k;} invalid_4 __attribute((mode(SI))); // expected-error{{mode attribute only supported for integer and floating-point types}}
+typedef float invalid_5 __attribute((mode(SI))); // expected-error{{type of machine mode does not match type of base type}}
+
+int **__attribute((mode(QI)))* i32;  // expected-error{{mode attribute}}
+
+typedef _Complex double c32 __attribute((mode(SC)));
+int c32_test[sizeof(c32) == 8 ? 1 : -1];
+typedef _Complex float c64 __attribute((mode(DC)));
+typedef _Complex float c80 __attribute((mode(XC)));
+
+// PR6108: Correctly select 'long' built in type on 64-bit platforms for 64 bit
+// modes. Also test other mode-based conversions.
+typedef int i8_mode_t __attribute__ ((__mode__ (__QI__)));
+typedef unsigned int ui8_mode_t __attribute__ ((__mode__ (__QI__)));
+typedef int i16_mode_t __attribute__ ((__mode__ (__HI__)));
+typedef unsigned int ui16_mode_t __attribute__ ((__mode__ (__HI__)));
+typedef int i32_mode_t __attribute__ ((__mode__ (__SI__)));
+typedef unsigned int ui32_mode_t __attribute__ ((__mode__ (__SI__)));
+typedef int i64_mode_t __attribute__ ((__mode__ (__DI__)));
+typedef unsigned int ui64_mode_t __attribute__ ((__mode__ (__DI__)));
+void f_i8_arg(i8_mode_t* x) { (void)x; }
+void f_ui8_arg(ui8_mode_t* x) { (void)x; }
+void f_i16_arg(i16_mode_t* x) { (void)x; }
+void f_ui16_arg(ui16_mode_t* x) { (void)x; }
+void f_i32_arg(i32_mode_t* x) { (void)x; }
+void f_ui32_arg(ui32_mode_t* x) { (void)x; }
+void f_i64_arg(i64_mode_t* x) { (void)x; }
+void f_ui64_arg(ui64_mode_t* x) { (void)x; }
+void test_char_to_i8(signed char* y) { f_i8_arg(y); }
+void test_char_to_ui8(unsigned char* y) { f_ui8_arg(y); }
+void test_short_to_i16(short* y) { f_i16_arg(y); }
+void test_short_to_ui16(unsigned short* y) { f_ui16_arg(y); }
+void test_int_to_i32(int* y) { f_i32_arg(y); }
+void test_int_to_ui32(unsigned int* y) { f_ui32_arg(y); }
+#if TEST_32BIT_X86
+void test_long_to_i64(long long* y) { f_i64_arg(y); }
+void test_long_to_ui64(unsigned long long* y) { f_ui64_arg(y); }
+#elif TEST_64BIT_X86
+void test_long_to_i64(long* y) { f_i64_arg(y); }
+void test_long_to_ui64(unsigned long* y) { f_ui64_arg(y); }
+#else
+#error Unknown test architecture.
+#endif
diff --git a/test/Sema/attr-nodebug.c b/test/Sema/attr-nodebug.c
new file mode 100644
index 0000000..203c2a7
--- /dev/null
+++ b/test/Sema/attr-nodebug.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only
+
+int a __attribute__((nodebug)); // expected-warning {{'nodebug' attribute only applies to function types}}
+
+void t1() __attribute__((nodebug));
+
+void t2() __attribute__((nodebug(2))); // expected-error {{attribute requires 0 argument(s)}}
+
diff --git a/test/Sema/attr-noinline.c b/test/Sema/attr-noinline.c
new file mode 100644
index 0000000..92dc900
--- /dev/null
+++ b/test/Sema/attr-noinline.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only
+
+int a __attribute__((noinline)); // expected-warning {{'noinline' attribute only applies to function types}}
+
+void t1() __attribute__((noinline));
+
+void t2() __attribute__((noinline(2))); // expected-error {{attribute requires 0 argument(s)}}
+
diff --git a/test/Sema/attr-noreturn.c b/test/Sema/attr-noreturn.c
new file mode 100644
index 0000000..b17f9fd
--- /dev/null
+++ b/test/Sema/attr-noreturn.c
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -verify -fsyntax-only %s
+
+static void (*fp0)(void) __attribute__((noreturn));
+
+void fatal();
+
+static void __attribute__((noreturn)) f0(void) {
+  fatal();
+} // expected-warning {{function declared 'noreturn' should not return}}
+
+// On K&R
+int f1() __attribute__((noreturn));
+
+int g0 __attribute__((noreturn)); // expected-warning {{'noreturn' only applies to function types; type here is 'int'}}
+
+int f2() __attribute__((noreturn(1, 2))); // expected-error {{attribute requires 0 argument(s)}}
+
+void f3() __attribute__((noreturn));
+void f3() {
+  return;  // expected-warning {{function 'f3' declared 'noreturn' should not return}}
+}
+
+#pragma clang diagnostic error "-Winvalid-noreturn"
+
+void f4() __attribute__((noreturn));
+void f4() {
+  return;  // expected-error {{function 'f4' declared 'noreturn' should not return}}
+}
+
+// PR4685
+extern void f5 (unsigned long) __attribute__ ((__noreturn__));
+
+void
+f5 (unsigned long size)
+{
+  
+}
+
+// PR2461
+__attribute__((noreturn)) void f(__attribute__((noreturn)) void (*x)(void)) {
+  x();
+}
diff --git a/test/Sema/attr-regparm.c b/test/Sema/attr-regparm.c
new file mode 100644
index 0000000..045a413
--- /dev/null
+++ b/test/Sema/attr-regparm.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -fsyntax-only -verify %s
+
+__attribute((regparm(2))) int x(void);
+__attribute((regparm(1.0))) int x(void); // expected-error{{'regparm' attribute requires integer constant}}
+__attribute((regparm(-1))) int x(void); // expected-error{{'regparm' parameter must be between 0 and 3 inclusive}}
+__attribute((regparm(5))) int x(void); // expected-error{{'regparm' parameter must be between 0 and 3 inclusive}}
+__attribute((regparm(5,3))) int x(void); // expected-error{{attribute requires 1 argument(s)}}
diff --git a/test/Sema/attr-section.c b/test/Sema/attr-section.c
new file mode 100644
index 0000000..a932525
--- /dev/null
+++ b/test/Sema/attr-section.c
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -verify -fsyntax-only -triple x86_64-apple-darwin9 %s
+
+int x __attribute__((section(
+   42)));  // expected-error {{argument to section attribute was not a string literal}}
+
+
+// rdar://4341926
+int y __attribute__((section(
+   "sadf"))); // expected-error {{mach-o section specifier requires a segment and section separated by a comma}}
+
+// PR6007
+void test() {
+  __attribute__((section("NEAR,x"))) int n1; // expected-error {{'section' attribute is not valid on local variables}}
+  __attribute__((section("NEAR,x"))) static int n2; // ok.
+}
diff --git a/test/Sema/attr-sentinel.c b/test/Sema/attr-sentinel.c
new file mode 100644
index 0000000..db90d07
--- /dev/null
+++ b/test/Sema/attr-sentinel.c
@@ -0,0 +1,48 @@
+// RUN: %clang_cc1  -fsyntax-only -verify %s
+
+#define NULL (void*)0
+
+#define ATTR __attribute__ ((__sentinel__)) 
+
+void foo1 (int x, ...) ATTR; // expected-note {{function has been explicitly marked sentinel here}}
+void foo5 (int x, ...) __attribute__ ((__sentinel__(1))); // expected-note {{function has been explicitly marked sentinel here}}
+void foo6 (int x, ...) __attribute__ ((__sentinel__(5))); // expected-note {{function has been explicitly marked sentinel here}}
+void foo7 (int x, ...) __attribute__ ((__sentinel__(0))); // expected-note {{function has been explicitly marked sentinel here}}
+void foo10 (int x, ...) __attribute__ ((__sentinel__(1,1)));
+void foo12 (int x, ... ) ATTR; // expected-note {{function has been explicitly marked sentinel here}}
+
+void test1() {
+  foo1(1, NULL); // OK
+  foo1(1, 0) ; // expected-warning {{missing sentinel in function call}}
+  foo5(1, NULL, 2);  // OK
+  foo5(1,2,NULL, 1); // OK
+  foo5(1, NULL, 2, 1); // expected-warning {{missing sentinel in function call}}
+
+  foo6(1,2,3,4,5,6,7); // expected-warning {{missing sentinel in function call}}
+  foo6(1,NULL,3,4,5,6,7); // OK
+  foo7(1); // expected-warning {{not enough variable arguments in 'foo7' declaration to fit a sentinel}}
+  foo7(1, NULL); // OK
+
+  foo12(1); // expected-warning {{not enough variable arguments in 'foo12' declaration to fit a sentinel}}
+}
+ 
+
+
+void (*e) (int arg, const char * format, ...) __attribute__ ((__sentinel__ (1,1)));
+
+void test2() {
+  void (*b) (int arg, const char * format, ...) __attribute__ ((__sentinel__));  // expected-note {{function has been explicitly marked sentinel here}}
+  void (*z) (int arg, const char * format, ...) __attribute__ ((__sentinel__ (2))); // expected-note {{function has been explicitly marked sentinel here}}
+  
+  
+  void (*y) (int arg, const char * format, ...) __attribute__ ((__sentinel__ (5))); // expected-note {{function has been explicitly marked sentinel here}}
+  
+  b(1, "%s", (void*)0); // OK
+  b(1, "%s", 0);  // expected-warning {{missing sentinel in function call}}
+  z(1, "%s",4 ,1,0);  // expected-warning {{missing sentinel in function call}}
+  z(1, "%s", (void*)0, 1, 0); // OK
+  
+  y(1, "%s", 1,2,3,4,5,6,7);  // expected-warning {{missing sentinel in function call}}
+  
+  y(1, "%s", (void*)0,3,4,5,6,7); // OK
+}
diff --git a/test/Sema/attr-unused.c b/test/Sema/attr-unused.c
new file mode 100644
index 0000000..2871514
--- /dev/null
+++ b/test/Sema/attr-unused.c
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -verify -Wunused-variable -fsyntax-only %s
+
+static void (*fp0)(void) __attribute__((unused));
+
+static void __attribute__((unused)) f0(void);
+
+// On K&R
+int f1() __attribute__((unused));
+
+int g0 __attribute__((unused));
+
+int f2() __attribute__((unused(1, 2))); // expected-error {{attribute requires 0 argument(s)}}
+
+struct Test0_unused {} __attribute__((unused));
+struct Test0_not_unused {};
+typedef int Int_unused __attribute__((unused));
+typedef int Int_not_unused;
+
+void test0() {
+  int x; // expected-warning {{unused variable}}
+
+  Int_not_unused i0; // expected-warning {{unused variable}}
+  Int_unused i1;
+
+  struct Test0_not_unused s0; // expected-warning {{unused variable}}
+  struct Test0_unused s1;
+}
diff --git a/test/Sema/attr-used.c b/test/Sema/attr-used.c
new file mode 100644
index 0000000..d50f4c0
--- /dev/null
+++ b/test/Sema/attr-used.c
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -verify -fsyntax-only %s
+
+extern int l0 __attribute__((used)); // expected-warning {{used attribute ignored}}
+__private_extern__ int l1 __attribute__((used)); // expected-warning {{used attribute ignored}}
+
+struct __attribute__((used)) s { // expected-warning {{'used' attribute only applies to variable and function types}}
+  int x;
+};
+
+int a __attribute__((used));
+
+static void __attribute__((used)) f0(void) {
+}
+
+void f1() {
+  static int a __attribute__((used)); 
+  int b __attribute__((used)); // expected-warning {{used attribute ignored}}
+}
+
+
diff --git a/test/Sema/attr-weak.c b/test/Sema/attr-weak.c
new file mode 100644
index 0000000..8e3e626
--- /dev/null
+++ b/test/Sema/attr-weak.c
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -verify -fsyntax-only %s
+
+extern int g0 __attribute__((weak));
+extern int g1 __attribute__((weak_import));
+int g2 __attribute__((weak));
+int g3 __attribute__((weak_import)); // expected-warning {{'weak_import' attribute cannot be specified on a definition}}
+int __attribute__((weak_import)) g4(void);
+void __attribute__((weak_import)) g5(void) { 
+}
+
+struct __attribute__((weak)) s0 {}; // expected-warning {{'weak' attribute only applies to variable and function types}}
+struct __attribute__((weak_import)) s1 {}; // expected-warning {{'weak_import' attribute only applies to variable and function types}}
+
+static int x __attribute__((weak)); // expected-error {{weak declaration of 'x' must be public}}
+
diff --git a/test/Sema/bitfield-layout.c b/test/Sema/bitfield-layout.c
new file mode 100644
index 0000000..edc44bd
--- /dev/null
+++ b/test/Sema/bitfield-layout.c
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify -triple=i686-apple-darwin9
+
+#define CHECK_SIZE(kind, name, size) extern int name##1[sizeof(kind name) == size ? 1 : -1];
+#define CHECK_ALIGN(kind, name, size) extern int name##2[__alignof(kind name) == size ? 1 : -1];
+
+// Zero-width bit-fields
+struct a {char x; int : 0; char y;};
+CHECK_SIZE(struct, a, 5)
+CHECK_ALIGN(struct, a, 1)
+
+union b {char x; int : 0; char y;};
+CHECK_SIZE(union, b, 1)
+CHECK_ALIGN(union, b, 1)
+
+// Unnamed bit-field align
+struct c {char x; int : 20;};
+CHECK_SIZE(struct, c, 4)
+CHECK_ALIGN(struct, c, 1)
+
+union d {char x; int : 20;};
+CHECK_SIZE(union, d, 3)
+CHECK_ALIGN(union, d, 1)
+
+// Bit-field packing
+struct __attribute__((packed)) e {int x : 4, y : 30, z : 30;};
+CHECK_SIZE(struct, e, 8)
+CHECK_ALIGN(struct, e, 1)
+
+// Alignment on bit-fields
+struct f {__attribute((aligned(8))) int x : 30, y : 30, z : 30;};
+CHECK_SIZE(struct, f, 24)
+CHECK_ALIGN(struct, f, 8)
diff --git a/test/Sema/bitfield-promote-int-16bit.c b/test/Sema/bitfield-promote-int-16bit.c
new file mode 100644
index 0000000..cd9adcf
--- /dev/null
+++ b/test/Sema/bitfield-promote-int-16bit.c
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -triple pic16-unknown-unknown
+
+// Check that int-sized unsigned bit-fields promote to unsigned int
+// on targets where sizeof(unsigned short) == sizeof(unsigned int)
+
+enum E { ec1, ec2, ec3 };
+struct S {
+  enum E          e : 16;
+  unsigned short us : 16;
+  unsigned long ul1 :  8;
+  unsigned long ul2 : 16;
+} s;
+
+__typeof(s.e + s.e) x_e;
+unsigned x_e;
+
+__typeof(s.us + s.us) x_us;
+unsigned x_us;
+
+__typeof(s.ul1 + s.ul1) x_ul1;
+signed x_ul1;
+
+__typeof(s.ul2 + s.ul2) x_ul2;
+unsigned x_ul2;
+
diff --git a/test/Sema/bitfield-promote.c b/test/Sema/bitfield-promote.c
new file mode 100644
index 0000000..4d14ad1
--- /dev/null
+++ b/test/Sema/bitfield-promote.c
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+struct {unsigned x : 2;} x;
+__typeof__((x.x+=1)+1) y;
+__typeof__(x.x<<1) y;
+int y;
+
+
+struct { int x : 8; } x1;
+long long y1;
+__typeof__(((long long)x1.x + 1)) y1;
+
+
+// Check for extensions: variously sized unsigned bit-fields fitting
+// into a signed int promote to signed int.
+enum E { ec1, ec2, ec3 };
+struct S {
+  enum E          e : 2;
+  unsigned short us : 4;
+  unsigned long long ul1 : 8;
+  unsigned long long ul2 : 50;
+} s;
+
+__typeof(s.e + s.e) x_e;
+int x_e;
+
+__typeof(s.us + s.us) x_us;
+int x_us;
+
+__typeof(s.ul1 + s.ul1) x_ul1;
+int x_ul1;
+
+__typeof(s.ul2 + s.ul2) x_ul2;
+unsigned long long x_ul2;
+
diff --git a/test/Sema/bitfield.c b/test/Sema/bitfield.c
new file mode 100644
index 0000000..5bb194b
--- /dev/null
+++ b/test/Sema/bitfield.c
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify 
+enum e0; // expected-note{{forward declaration of 'enum e0'}}
+
+struct a {
+  int a : -1; // expected-error{{bit-field 'a' has negative width}}
+
+  // rdar://6081627
+  int b : 33; // expected-error{{size of bit-field 'b' (33 bits) exceeds size of its type (32 bits)}}
+
+  int c : (1 + 0.25); // expected-error{{expression is not an integer constant expression}}
+  int d : (int)(1 + 0.25); 
+
+  // rdar://6138816
+  int e : 0;  // expected-error {{bit-field 'e' has zero width}}
+
+  float xx : 4;  // expected-error {{bit-field 'xx' has non-integral type}}
+
+  // PR3607
+  enum e0 f : 1; // expected-error {{field has incomplete type 'enum e0'}}
+  
+  int g : (_Bool)1;
+  
+  // PR4017  
+  char : 10;      // expected-error {{size of anonymous bit-field (10 bits) exceeds size of its type (8 bits)}}
+  unsigned : -2;  // expected-error {{anonymous bit-field has negative width (-2)}}
+  float : 12;     // expected-error {{anonymous bit-field has non-integral type 'float'}}
+};
+
+struct b {unsigned x : 2;} x;
+__typeof__(x.x+1) y;
+int y;
+
+struct {unsigned x : 2;} x2;
+__typeof__((x.x+=1)+1) y;
+__typeof__(x.x<<1) y;
+int y;
diff --git a/test/Sema/block-args.c b/test/Sema/block-args.c
new file mode 100644
index 0000000..970c60d
--- /dev/null
+++ b/test/Sema/block-args.c
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify -fblocks
+
+void take(void*);
+
+void test() {
+  take(^(int x){});
+  take(^(int x, int y){});
+  take(^(int x, int y){});
+  take(^(int x,      // expected-note {{previous declaration is here}}
+         int x){});  // expected-error {{redefinition of parameter 'x'}}
+
+
+  take(^(int x) { return x+1; });
+
+  int (^CP)(int) = ^(int x) { return x*x; };
+  take(CP);
+
+  int arg;
+  ^{return 1;}();
+  ^{return 2;}(arg); // expected-error {{too many arguments to block call}}
+  ^(void){return 3;}(1); // expected-error {{too many arguments to block call}}
+  ^(){return 4;}(arg); // expected-error {{too many arguments to block call}}
+  ^(int x, ...){return 5;}(arg, arg);   // Explicit varargs, ok.
+}
+
+int main(int argc, char** argv) {
+  ^(int argCount) {
+    argCount = 3;
+  }(argc);
+}
+
+// radar 7528255
+void f0() {
+  ^(int, double d, char) {}(1, 1.34, 'a'); // expected-error {{parameter name omitted}} \
+				 	   // expected-error {{parameter name omitted}}
+}
diff --git a/test/Sema/block-as-object.m b/test/Sema/block-as-object.m
new file mode 100644
index 0000000..a85b606
--- /dev/null
+++ b/test/Sema/block-as-object.m
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify -fblocks
+
+@interface Whatever
+- copy;
+@end
+
+typedef long (^MyBlock)(id obj1, id obj2);
+
+void foo(MyBlock b) {
+    id bar = [b copy];
+}
+
+void foo2(id b) {
+}
+
+void foo3(void (^block)(void)) {
+    foo2(block);
+    id x;
+    foo(x);
+}
diff --git a/test/Sema/block-call.c b/test/Sema/block-call.c
new file mode 100644
index 0000000..318bc6b
--- /dev/null
+++ b/test/Sema/block-call.c
@@ -0,0 +1,51 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -fblocks
+
+int (*FP)();
+int (^IFP) ();
+int (^II) (int);
+int main() {
+  int (*FPL) (int) = FP; // C doesn't consider this an error.
+
+  // For Blocks, the ASTContext::typesAreBlockCompatible() makes sure this is an error.
+  int (^PFR) (int) = IFP; // OK
+  PFR = II;       // OK
+
+  int (^IFP) () = PFR; // OK
+
+
+  const int (^CIC) () = IFP; // expected-error {{incompatible block pointer types initializing 'int const (^)()' with an expression of type 'int (^)()'}}
+
+  const int (^CICC) () = CIC;
+
+  int * const (^IPCC) () = 0;
+
+  int * const (^IPCC1) () = IPCC;
+
+  int * (^IPCC2) () = IPCC;       // expected-error {{incompatible block pointer types initializing 'int *(^)()' with an expression of type 'int *const (^)()'}}
+
+  int (^IPCC3) (const int) = PFR;
+
+  int (^IPCC4) (int, char (^CArg) (double));
+
+  int (^IPCC5) (int, char (^CArg) (double)) = IPCC4;
+
+  int (^IPCC6) (int, char (^CArg) (float))  = IPCC4; // expected-error {{incompatible block pointer types initializing 'int (^)(int, char (^)(float))' with an expression of type 'int (^)(int, char (^)(double))'}}
+
+  IPCC2 = 0;
+  IPCC2 = 1; // expected-error {{invalid block pointer conversion assigning to 'int *(^)()' from 'int'}}
+  int (^x)() = 0;
+  int (^y)() = 3;   // expected-error {{invalid block pointer conversion initializing 'int (^)()' with an expression of type 'int'}}
+  int a = 1;
+  int (^z)() = a+4;   // expected-error {{invalid block pointer conversion initializing 'int (^)()' with an expression of type 'int'}}
+}
+
+int blah() {
+  int (^IFP) (float);
+  char (^PCP)(double, double, char);
+
+  IFP(1.0);
+  IFP (1.0, 2.0); // expected-error {{too many arguments to block call}}
+
+  char ch = PCP(1.0, 2.0, 'a');
+  return PCP(1.0, 2.0);   // expected-error {{too few arguments to block}}
+}
diff --git a/test/Sema/block-labels.c b/test/Sema/block-labels.c
new file mode 100644
index 0000000..353a570
--- /dev/null
+++ b/test/Sema/block-labels.c
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 %s -verify -fblocks -fsyntax-only
+
+void xx();
+
+int a() { 
+  A:if (1) xx();
+  return ^{A:return 1;}();
+}
+int b() { 
+  A: return ^{int a; A:return 1;}();
+}
+
+int d() { 
+  A: return ^{int a; A: a = ^{int a; A:return 1;}() + ^{int b; A:return 2;}(); return a; }();
+}
+
+int c() { 
+  goto A; return ^{ A:return 1;}(); // expected-error {{use of undeclared label 'A'}}
+}
diff --git a/test/Sema/block-literal.c b/test/Sema/block-literal.c
new file mode 100644
index 0000000..c303b84
--- /dev/null
+++ b/test/Sema/block-literal.c
@@ -0,0 +1,89 @@
+// RUN: %clang_cc1 -fsyntax-only %s -verify -fblocks
+
+void I( void (^)(void));
+void (^noop)(void);
+
+void nothing();
+int printf(const char*, ...);
+
+typedef void (^T) (void);
+
+void takeblock(T);
+int takeintint(int (^C)(int)) { return C(4); }
+
+T somefunction() {
+  if (^{ })
+    nothing();
+
+  noop = ^{};
+
+  noop = ^{printf("\nClosure\n"); };
+
+  I(^{ });
+
+  return ^{printf("\nClosure\n"); };
+}
+void test2() {
+  int x = 4;
+
+  takeblock(^{ printf("%d\n", x); });
+
+  while (1) {
+    takeblock(^{ 
+        break;  // expected-error {{'break' statement not in loop or switch statement}}
+        continue; // expected-error {{'continue' statement not in loop statement}}
+        while(1) break;  // ok
+        goto foo; // expected-error {{use of undeclared label 'foo'}}
+        a: goto a;       // ok
+      });
+    break;
+  }
+
+  foo:
+  takeblock(^{ x = 4; });  // expected-error {{variable is not assignable (missing __block type specifier)}}
+  __block y = 7;    // expected-warning {{type specifier missing, defaults to 'int'}}
+  takeblock(^{ y = 8; });
+}
+
+
+void (^test3())(void) { 
+  return ^{};
+}
+
+void test4() {
+  void (^noop)(void) = ^{};
+  void (*noop2)() = 0;
+}
+
+void myfunc(int (^block)(int)) {}
+
+void myfunc3(const int *x);
+
+void test5() {
+  int a;
+
+  myfunc(^(int abcd) {
+      myfunc3(&a);
+      return 1;
+    });
+}
+
+void *X;
+
+void test_arguments() {
+  int y;
+  int (^c)(char);
+  (1 ? c : 0)('x');
+  (1 ? 0 : c)('x');
+
+  (1 ? c : c)('x');
+}
+
+static int global_x = 10;
+void (^global_block)(void) = ^{ printf("global x is %d\n", global_x); };
+
+typedef void (^void_block_t)(void);
+
+static const void_block_t myBlock = ^{ };
+
+static const void_block_t myBlock2 = ^ void(void) { }; 
diff --git a/test/Sema/block-misc.c b/test/Sema/block-misc.c
new file mode 100644
index 0000000..92be5b1
--- /dev/null
+++ b/test/Sema/block-misc.c
@@ -0,0 +1,223 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -fblocks
+void donotwarn();
+
+int (^IFP) ();
+int (^II) (int);
+int test1() {
+  int (^PFR) (int) = 0; // OK
+  PFR = II;             // OK
+
+  if (PFR == II)        // OK
+    donotwarn();
+
+  if (PFR == IFP)       // OK
+    donotwarn();
+
+  if (PFR == (int (^) (int))IFP) // OK
+    donotwarn();
+
+  if (PFR == 0)         // OK
+    donotwarn();
+
+  if (PFR)              // OK
+    donotwarn();
+
+  if (!PFR)             // OK
+    donotwarn();
+
+  return PFR != IFP;    // OK
+}
+
+int test2(double (^S)()) {
+  double (^I)(int)  = (void*) S;
+  (void*)I = (void *)S; // expected-error {{assignment to cast is illegal, lvalue casts are not supported}}
+
+  void *pv = I;
+
+  pv = S;
+
+  I(1);
+
+  return (void*)I == (void *)S;
+}
+
+int^ x; // expected-error {{block pointer to non-function type is invalid}}
+int^^ x1; // expected-error {{block pointer to non-function type is invalid}} expected-error {{block pointer to non-function type is invalid}}
+
+void test3() {
+  char *^ y; // expected-error {{block pointer to non-function type is invalid}}
+}
+
+
+
+enum {NSBIRLazilyAllocated = 0};
+
+int test4(int argc) {  // rdar://6251437
+  ^{
+    switch (argc) {
+      case NSBIRLazilyAllocated:  // is an integer constant expression.
+      default:
+        break;
+    }
+  }();
+  return 0;
+}
+
+
+void bar(void*);
+// rdar://6257721 - reference to static/global is byref by default.
+static int test5g;
+void test5() {
+  bar(^{ test5g = 1; });
+}
+
+// rdar://6405429 - __func__ in a block refers to the containing function name.
+const char*test6() {
+  return ^{
+    return __func__;
+  } ();
+}
+
+// radr://6732116 - block comparisons
+void (^test7a)();
+int test7(void (^p)()) {
+  return test7a == p;
+}
+
+
+void test8() {
+somelabel:
+  ^{ goto somelabel; }();   // expected-error {{use of undeclared label 'somelabel'}}
+}
+
+void test9() {
+  goto somelabel;       // expected-error {{use of undeclared label 'somelabel'}}
+  ^{ somelabel: ; }();
+}
+
+void test10(int i) {
+  switch (i) {
+  case 41: ;
+  ^{ case 42: ; }();     // expected-error {{'case' statement not in switch statement}}
+  }
+}
+
+void test11(int i) {
+  switch (i) {
+  case 41: ;
+    ^{ break; }();     // expected-error {{'break' statement not in loop or switch statement}}
+  }
+  
+  for (; i < 100; ++i)
+    ^{ break; }();     // expected-error {{'break' statement not in loop or switch statement}}
+}
+
+void (^test12f)(void);
+void test12() {
+  test12f = ^test12f;  // expected-error {{type name requires a specifier or qualifier}} expected-error {{expected expression}}
+}
+
+// rdar://6808730
+void *test13 = ^{
+  int X = 32;
+
+  void *P = ^{
+    return X+4;  // References outer block's "X", so outer block is constant.
+  };
+};
+
+void test14() {
+  int X = 32;
+  static void *P = ^{  // expected-error {{initializer element is not a compile-time constant}}
+
+    void *Q = ^{
+      // References test14's "X": outer block is non constant.
+      return X+4;
+    };
+  };
+}
+
+enum { LESS };
+
+void foo(long (^comp)()) { // expected-note{{passing argument to parameter 'comp' here}}
+}
+
+void (^test15f)(void);
+void test15() {
+  foo(^{ return LESS; }); // expected-error {{incompatible block pointer types passing 'int (^)(void)' to parameter of type 'long (^)()'}}
+}
+
+__block int test16i;  // expected-error {{__block attribute not allowed, only allowed on local variables}}
+
+void test16(__block int i) { // expected-error {{__block attribute not allowed, only allowed on local variables}}
+  int size = 5;
+  extern __block double extern_var; // expected-error {{__block attribute not allowed, only allowed on local variables}}
+  static __block char * pch; // expected-error {{__block attribute not allowed, only allowed on local variables}}
+  __block int a[size]; // expected-error {{__block attribute not allowed on declaration with a variably modified type}}
+  __block int (*ap)[size]; // expected-error {{__block attribute not allowed on declaration with a variably modified type}}
+}
+
+void f();
+
+void test17() {
+  void (^bp)(int);
+  void (*rp)(int);
+  void (^bp1)();
+  void *vp = bp;
+
+  f(1 ? bp : vp);
+  f(1 ? vp : bp);
+  f(1 ? bp : bp1);
+  (void)(bp > rp); // expected-error {{invalid operands}}
+  (void)(bp > 0); // expected-error {{invalid operands}}
+  (void)(bp > bp); // expected-error {{invalid operands}}
+  (void)(bp > vp); // expected-error {{invalid operands}}
+  f(1 ? bp : rp); // expected-error {{incompatible operand types ('void (^)(int)' and 'void (*)(int)')}}
+  (void)(bp == 1); // expected-error {{invalid operands to binary expression}}
+  (void)(bp == 0);
+  (void)(1 == bp); // expected-error {{invalid operands to binary expression}}
+  (void)(0 == bp);
+  (void)(bp < 1); // expected-error {{invalid operands to binary expression}}
+  (void)(bp < 0); // expected-error {{invalid operands to binary expression}}
+  (void)(1 < bp); // expected-error {{invalid operands to binary expression}}
+  (void)(0 < bp); // expected-error {{invalid operands to binary expression}}
+}
+
+void test18() {
+  void (^const  blockA)(void) = ^{ };
+  blockA = ^{ }; // expected-error {{read-only variable is not assignable}}
+}
+
+// rdar://7072507
+int test19() {
+  goto L0;       // expected-error {{illegal goto into protected scope}}
+  
+  __block int x; // expected-note {{jump bypasses setup of __block variable}}
+L0:
+  x = 0;
+  ^(){ ++x; }();
+  return x;
+}
+
+// radr://7438948
+void test20() {
+  int n = 7;
+  int vla[n]; // expected-note {{declared here}}
+  int (*vm)[n] = 0; // expected-note {{declared here}}
+  vla[1] = 4341;
+  ^{
+    (void)vla[1];  // expected-error {{cannot refer to declaration with a variably modified type inside block}}
+    (void)(vm+1);  // expected-error {{cannot refer to declaration with a variably modified type inside block}}
+  }();
+}
+
+// radr://7438948
+void test21() {
+  int a[7]; // expected-note {{declared here}}
+  __block int b[10]; // expected-note {{declared here}}
+  a[1] = 1;
+  ^{
+    (void)a[1]; // expected-error {{cannot refer to declaration with an array type inside block}}
+    (void)b[1]; // expected-error {{cannot refer to declaration with an array type inside block}}
+  }();
+}
diff --git a/test/Sema/block-printf-attribute-1.c b/test/Sema/block-printf-attribute-1.c
new file mode 100644
index 0000000..c19b378
--- /dev/null
+++ b/test/Sema/block-printf-attribute-1.c
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify -fblocks
+
+int main() {
+  void (^b) (int arg, const char * format, ...) __attribute__ ((__format__ (__printf__, 1, 3))) =   // expected-error {{format argument not a string type}}
+    ^ __attribute__ ((__format__ (__printf__, 1, 3))) (int arg, const char * format, ...) {}; // expected-error {{format argument not a string type}}
+ 
+  void (^z) (int arg, const char * format, ...) __attribute__ ((__format__ (__printf__, 2, 3))) = ^ __attribute__ ((__format__ (__printf__, 2, 3))) (int arg, const char * format, ...) {};
+
+  z(1, "%s", 1); // expected-warning{{conversion specifies type 'char *' but the argument has type 'int'}}
+  z(1, "%s", "HELLO"); // no-warning
+}
diff --git a/test/Sema/block-return-1.c b/test/Sema/block-return-1.c
new file mode 100644
index 0000000..631a2d4
--- /dev/null
+++ b/test/Sema/block-return-1.c
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -fsyntax-only %s -verify -fblocks
+
+int j;
+void foo() {
+  ^ (void) { if (j) return 1; }(); // expected-error {{control may reach end of non-void block}}
+}
diff --git a/test/Sema/block-return-2.c b/test/Sema/block-return-2.c
new file mode 100644
index 0000000..d5fbc6f
--- /dev/null
+++ b/test/Sema/block-return-2.c
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -fsyntax-only %s -verify -fblocks
+
+void foo() {
+  ^ (void) __attribute__((noreturn)) { }(); // expected-error {{block declared 'noreturn' should not return}}
+}
diff --git a/test/Sema/block-return-3.c b/test/Sema/block-return-3.c
new file mode 100644
index 0000000..cd942a7
--- /dev/null
+++ b/test/Sema/block-return-3.c
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -fsyntax-only %s -verify -fblocks
+
+void foo() {
+  ^ int (void) { }(); // expected-error {{control reaches end of non-void block}}
+}
diff --git a/test/Sema/block-return.c b/test/Sema/block-return.c
new file mode 100644
index 0000000..10b3b84
--- /dev/null
+++ b/test/Sema/block-return.c
@@ -0,0 +1,130 @@
+// RUN: %clang_cc1 -fsyntax-only %s -verify -fblocks
+
+typedef void (^CL)(void);
+
+CL foo() {
+  short y;
+  short (^add1)(void) = ^{ return y+1; }; // expected-error {{incompatible block pointer types initializing 'short (^)(void)' with an expression of type 'int (^)(void)'}}
+
+  CL X = ^{
+    if (2)
+      return;
+    return 1;  // expected-error {{void block should not return a value}}
+  };
+
+  int (^Y) (void)  = ^{
+    if (3)
+      return 1;
+    else
+      return; // expected-error {{non-void block should return a value}}
+  };
+
+  char *(^Z)(void) = ^{
+    if (3)
+      return "";
+    else
+      return (char*)0;
+  };
+
+  double (^A)(void) = ^ { // expected-error {{incompatible block pointer types initializing 'double (^)(void)' with an expression of type 'float (^)(void)'}}
+    if (1)
+      return (float)1.0;
+    else
+      if (2)
+        return (double)2.0;
+    return 1;
+  };
+  char *(^B)(void) = ^{
+    if (3)
+      return "";
+    else
+      return 2; // expected-warning {{incompatible integer to pointer conversion returning 'int' from a function with result type 'char *'}}
+  };
+
+  return ^{ return 1; }; // expected-error {{incompatible block pointer types returning 'int (^)(void)' from a function with result type 'CL' (aka 'void (^)(void)')}}
+}
+
+typedef int (^CL2)(void);
+
+CL2 foo2() {
+  return ^{ return 1; };
+}
+
+typedef unsigned int * uintptr_t;
+typedef char Boolean;
+typedef int CFBasicHash;
+
+#define INVOKE_CALLBACK2(P, A, B) (P)(A, B)
+
+typedef struct {
+    Boolean (^isEqual)(const CFBasicHash *, uintptr_t stack_value_or_key1, uintptr_t stack_value_or_key2, Boolean is_key);
+} CFBasicHashCallbacks;
+
+int foo3() {
+    CFBasicHashCallbacks cb;
+    
+    Boolean (*value_equal)(uintptr_t, uintptr_t) = 0;
+            
+    cb.isEqual = ^(const CFBasicHash *table, uintptr_t stack_value_or_key1, uintptr_t stack_value_or_key2, Boolean is_key) {
+      return (Boolean)(uintptr_t)INVOKE_CALLBACK2(value_equal, (uintptr_t)stack_value_or_key1, (uintptr_t)stack_value_or_key2);
+    };
+}
+
+static int funk(char *s) {
+  if (^{} == ((void*)0))
+    return 1;
+  else 
+    return 0;
+}
+void next();
+void foo4() {
+  int (^xx)(const char *s) = ^(char *s) { return 1; }; // expected-error {{incompatible block pointer types initializing 'int (^)(char const *)' with an expression of type 'int (^)(char *)'}}
+  int (*yy)(const char *s) = funk; // expected-warning {{incompatible pointer types initializing 'int (*)(char const *)' with an expression of type 'int (char *)'}}
+  
+  int (^nested)(char *s) = ^(char *str) { void (^nest)(void) = ^(void) { printf("%s\n", str); }; next(); return 1; }; // expected-warning{{implicitly declaring C library function 'printf' with type 'int (char const *, ...)'}} \
+  // expected-note{{please include the header <stdio.h> or explicitly provide a declaration for 'printf'}}
+}
+
+typedef void (^bptr)(void);
+
+bptr foo5(int j) {
+  __block int i;
+  if (j)
+    return ^{ ^{ i=0; }(); };  // expected-error {{returning block that lives on the local stack}}
+  return ^{ i=0; };  // expected-error {{returning block that lives on the local stack}}
+  return (^{ i=0; });  // expected-error {{returning block that lives on the local stack}}
+  return (void*)(^{ i=0; });  // expected-error {{returning block that lives on the local stack}}
+}
+
+int (*funcptr3[5])(long);
+int sz8 = sizeof(^int (*[5])(long) {return funcptr3;}); // expected-error {{block declared as returning an array}}
+
+void foo6() {
+  int (^b)(int) __attribute__((noreturn));
+  b = ^ (int i) __attribute__((noreturn)) { return 1; };  // expected-error {{block declared 'noreturn' should not return}}
+  b(1);
+  int (^c)(void) __attribute__((noreturn)) = ^ __attribute__((noreturn)) { return 100; }; // expected-error {{block declared 'noreturn' should not return}}
+}
+
+
+void foo7()
+{
+ const int (^BB) (void) = ^{ const int i = 1; return i; }; // expected-error{{incompatible block pointer types initializing 'int const (^)(void)' with an expression of type 'int (^)(void)'}}
+ const int (^CC) (void)  = ^const int{ const int i = 1; return i; }; // OK
+
+  int i;
+  int (^FF) (void)  = ^{ return i; }; // OK
+  int (^EE) (void)  = ^{ return i+1; }; // OK
+
+  __block int j;
+  int (^JJ) (void)  = ^{ return j; }; // OK
+  int (^KK) (void)  = ^{ return j+1; }; // OK
+
+  __block const int k;
+  const int cint = 100;
+
+  int (^MM) (void)  = ^{ return k; };
+  int (^NN) (void)  = ^{ return cint; };
+}
+
+
diff --git a/test/Sema/block-sentinel-attribute.c b/test/Sema/block-sentinel-attribute.c
new file mode 100644
index 0000000..b5ce0da
--- /dev/null
+++ b/test/Sema/block-sentinel-attribute.c
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -fblocks -fsyntax-only -verify %s
+
+void (^e) (int arg, const char * format, ...) __attribute__ ((__sentinel__ (1,1)));
+
+int main() {
+  void (^bbad) (int arg, const char * format) __attribute__ ((__sentinel__)) ; // expected-warning {{sentinel' attribute only supported for variadic blocks}}
+  void (^b) (int arg, const char * format, ...) __attribute__ ((__sentinel__)) =  // expected-note {{block has been explicitly marked sentinel here}}
+    ^ __attribute__ ((__sentinel__)) (int arg, const char * format, ...) {};
+  void (^z) (int arg, const char * format, ...) __attribute__ ((__sentinel__ (2))) = ^ __attribute__ ((__sentinel__ (2))) (int arg, const char * format, ...) {}; // expected-note {{block has been explicitly marked sentinel here}}
+
+
+  void (^y) (int arg, const char * format, ...) __attribute__ ((__sentinel__ (5))) = ^ __attribute__ ((__sentinel__ (5))) (int arg, const char * format, ...) {}; // expected-note {{block has been explicitly marked sentinel here}}
+
+  b(1, "%s", (void*)0); // OK
+  b(1, "%s", 0);  // expected-warning {{missing sentinel in block call}}
+  z(1, "%s",4 ,1,0);  // expected-warning {{missing sentinel in block call}}
+  z(1, "%s", (void*)0, 1, 0); // OK
+
+  y(1, "%s", 1,2,3,4,5,6,7);  // expected-warning {{missing sentinel in block call}}
+
+  y(1, "%s", (void*)0,3,4,5,6,7); // OK
+
+}
+
diff --git a/test/Sema/block-storageclass.c b/test/Sema/block-storageclass.c
new file mode 100644
index 0000000..9bfbfbd
--- /dev/null
+++ b/test/Sema/block-storageclass.c
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify -fblocks
+
+int printf(const char *, ...);
+void _Block_byref_release(void*src){}
+
+int main() {
+   __block  int X = 1234;
+   __block  const char * message = "HELLO";
+
+   X = X - 1234;
+
+   X += 1;
+
+   printf ("%s(%d)\n", message, X);
+   X -= 1;
+
+   return X;
+}
diff --git a/test/Sema/builtin-object-size.c b/test/Sema/builtin-object-size.c
new file mode 100644
index 0000000..0abc27b
--- /dev/null
+++ b/test/Sema/builtin-object-size.c
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -triple x86_64-apple-darwin9 -verify %s
+
+int a[10];
+
+int f0() {
+  return __builtin_object_size(&a); // expected-error {{too few arguments to function}}
+}
+int f1() {
+  return (__builtin_object_size(&a, 0) + 
+          __builtin_object_size(&a, 1) + 
+          __builtin_object_size(&a, 2) + 
+          __builtin_object_size(&a, 3));
+}
+int f2() {
+  return __builtin_object_size(&a, -1); // expected-error {{argument should be a value from 0 to 3}}
+}
+int f3() {
+  return __builtin_object_size(&a, 4); // expected-error {{argument should be a value from 0 to 3}}
+}
+
+
+// rdar://6252231 - cannot call vsnprintf with va_list on x86_64
+void f4(const char *fmt, ...) {
+ __builtin_va_list args;
+ __builtin___vsnprintf_chk (0, 42, 0, 11, fmt, args);
+}
+
diff --git a/test/Sema/builtin-prefetch.c b/test/Sema/builtin-prefetch.c
new file mode 100644
index 0000000..c5fa792
--- /dev/null
+++ b/test/Sema/builtin-prefetch.c
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+void foo() {
+  int a;
+  __builtin_prefetch(&a);
+  __builtin_prefetch(&a, 1);
+  __builtin_prefetch(&a, 1, 2);
+  __builtin_prefetch(&a, 1, 9, 3); // expected-error{{too many arguments to function}}
+  __builtin_prefetch(&a, "hello", 2); // expected-error{{argument to '__builtin_prefetch' must be a constant integer}}
+  __builtin_prefetch(&a, a, 2); // expected-error{{argument to '__builtin_prefetch' must be a constant integer}}
+  __builtin_prefetch(&a, 2); // expected-error{{argument should be a value from 0 to 1}}
+  __builtin_prefetch(&a, 0, 4); // expected-error{{argument should be a value from 0 to 3}}
+  __builtin_prefetch(&a, -1, 4); // expected-error{{argument should be a value from 0 to 1}}
+}
diff --git a/test/Sema/builtin-stackaddress.c b/test/Sema/builtin-stackaddress.c
new file mode 100644
index 0000000..5f63bb1
--- /dev/null
+++ b/test/Sema/builtin-stackaddress.c
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+void* a(unsigned x) {
+return __builtin_return_address(0);
+}
+
+void b(unsigned x) {
+return __builtin_return_address(x); // expected-error{{argument to '__builtin_return_address' must be a constant integer}}
+}
+
+void* c(unsigned x) {
+return __builtin_frame_address(0);
+}
+
+void d(unsigned x) {
+return __builtin_frame_address(x); // expected-error{{argument to '__builtin_frame_address' must be a constant integer}}
+}
diff --git a/test/Sema/builtin-unary-fp.c b/test/Sema/builtin-unary-fp.c
new file mode 100644
index 0000000..57568db
--- /dev/null
+++ b/test/Sema/builtin-unary-fp.c
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify -pedantic
+void check(int);
+void a() {
+  check(__builtin_isfinite(1.0f));
+  check(__builtin_isinf(1.0));
+  check(__builtin_isinf_sign(1.0L));
+  check(__builtin_isnan(1.0f));
+  check(__builtin_isnormal(1.0f));
+  check(__builtin_isfinite(1)); // expected-error{{requires argument of floating point type}}
+  check(__builtin_isinf()); // expected-error{{too few arguments}}
+  check(__builtin_isnan(1,2)); // expected-error{{too many arguments}}
+  check(__builtin_fpclassify(0, 0, 0, 0, 0, 1.0));
+  check(__builtin_fpclassify(0, 0, 0, 0, 0, 1)); // expected-error{{requires argument of floating point type}}
+  check(__builtin_fpclassify(0, 0, 0, 0, 1)); // expected-error{{too few arguments}}
+  check(__builtin_fpclassify(0, 0, 0, 0, 0, 1, 0)); // expected-error{{too many arguments}}
+}
diff --git a/test/Sema/builtins.c b/test/Sema/builtins.c
new file mode 100644
index 0000000..6fa563b
--- /dev/null
+++ b/test/Sema/builtins.c
@@ -0,0 +1,74 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify -pedantic -triple=i686-apple-darwin9
+// This test needs to set the target because it uses __builtin_ia32_vec_ext_v4si
+
+int test1(float a, int b) {
+  return __builtin_isless(a, b);
+}
+int test2(int a, int b) {
+  return __builtin_islessequal(a, b);  // expected-error {{floating point type}}
+}
+
+int test3(double a, float b) {
+  return __builtin_isless(a, b);
+}
+int test4(int* a, double b) {
+  return __builtin_islessequal(a, b);  // expected-error {{floating point type}}
+}
+
+int test5(float a, long double b) {
+  return __builtin_isless(a, b, b);  // expected-error {{too many arguments}}
+}
+int test6(float a, long double b) {
+  return __builtin_islessequal(a);  // expected-error {{too few arguments}}
+}
+
+
+#define CFSTR __builtin___CFStringMakeConstantString
+void test7() {
+  const void *X;
+  X = CFSTR("\242");
+  X = CFSTR("\0"); // expected-warning {{ CFString literal contains NUL character }}
+  X = CFSTR(242); // expected-error {{ CFString literal is not a string constant }} expected-warning {{incompatible integer to pointer conversion}}
+  X = CFSTR("foo", "bar"); // expected-error {{too many arguments to function call}}
+}
+
+
+// atomics.
+
+void test9(short v) {
+  unsigned i, old;
+  
+  old = __sync_fetch_and_add();  // expected-error {{too few arguments to function call}}
+  old = __sync_fetch_and_add(&old);  // expected-error {{too few arguments to function call}}
+  old = __sync_fetch_and_add((int**)0, 42i); // expected-warning {{imaginary constants are an extension}}
+}
+
+
+// rdar://7236819
+void test10(void) __attribute__((noreturn));
+
+void test10(void) {
+  __asm__("int3");  
+  __builtin_unreachable();
+ 
+  // No warning about falling off the end of a noreturn function.
+}
+
+void test11(int X) {
+  switch (X) {  
+  case __builtin_eh_return_data_regno(0):  // constant foldable.
+    break;
+  }
+
+  __builtin_eh_return_data_regno(X);  // expected-error {{argument to '__builtin_eh_return_data_regno' must be a constant integer}}
+}
+
+// PR5062
+void test12(void) __attribute__((__noreturn__));
+void test12(void) {
+  __builtin_trap();  // no warning because trap is noreturn.
+}
+
+void test_unknown_builtin(int a, int b) {
+  __builtin_foo(a, b); // expected-error{{use of unknown builtin}}
+}
diff --git a/test/Sema/c89-2.c b/test/Sema/c89-2.c
new file mode 100644
index 0000000..f6f6bd9
--- /dev/null
+++ b/test/Sema/c89-2.c
@@ -0,0 +1,5 @@
+/* RUN: %clang_cc1 %s -std=c89 -pedantic-errors -verify
+ */
+
+#if 1LL        /* expected-error {{long long}} */
+#endif
diff --git a/test/Sema/c89.c b/test/Sema/c89.c
new file mode 100644
index 0000000..8a9e622
--- /dev/null
+++ b/test/Sema/c89.c
@@ -0,0 +1,82 @@
+/* RUN: %clang_cc1 %s -std=c89 -pedantic -fsyntax-only -verify
+ */
+void test1() {
+  {
+    int i;
+    i = i + 1;
+    int j;          /* expected-warning {{mixing declarations and code}} */
+  }
+  {
+    __extension__ int i;
+    i = i + 1;
+    int j;          /* expected-warning {{mixing declarations and code}} */
+  }
+  {
+    int i;
+    i = i + 1;
+    __extension__ int j; /* expected-warning {{mixing declarations and code}} */
+  }
+}
+
+long long test2;   /* expected-warning {{extension}} */
+
+
+void test3(int i) {
+  int A[i];        /* expected-warning {{variable length array}} */
+}
+
+int test4 = 0LL;   /* expected-warning {{long long}} */
+
+/* PR1999 */
+void test5(register);
+
+/* PR2041 */
+int *restrict;
+int *__restrict;  /* expected-error {{expected identifier}} */
+
+
+/* Implicit int, always ok */
+test6() { return 0; }
+
+/* PR2012 */
+test7;  /* expected-warning {{declaration specifier missing, defaulting to 'int'}} */
+
+void test8(int, x);  /* expected-warning {{declaration specifier missing, defaulting to 'int'}} */
+
+typedef int sometype;
+int a(sometype, y) {return 0;}  /* expected-warning {{declaration specifier missing, defaulting to 'int'}} \
+                                   expected-error {{parameter name omitted}}*/
+
+
+
+
+void bar (void *); 
+void f11 (z)       /* expected-error {{may not have 'void' type}} */
+void z; 
+{ bar (&z); }
+
+typedef void T;
+void foo(T); /* typedef for void is allowed */
+
+void foo(void) {}
+
+/* PR2759 */
+void test10 (int x[*]); /* expected-warning {{use of C99-specific array features}} */
+void test11 (int x[static 4]); /* expected-warning {{use of C99-specific array features}} */
+
+void test12 (int x[const 4]) { /* expected-warning {{use of C99-specific array features}} */
+  int Y[x[1]]; /* expected-warning {{variable length arrays are a C99 feature, accepted as an extension}} */
+}
+
+/* PR4074 */
+struct test13 {
+  int X[23];
+} test13a();
+
+void test13b() {
+  int a = test13a().X[1]; /* expected-warning {{ISO C90 does not allow subscripting non-lvalue array}} */
+  int b = 1[test13a().X]; /* expected-warning {{ISO C90 does not allow subscripting non-lvalue array}} */
+}
+
+/* Make sure we allow *test14 as a "function designator" */
+int test14() { return (&*test14)(); }
diff --git a/test/Sema/callingconv.c b/test/Sema/callingconv.c
new file mode 100644
index 0000000..92a2057
--- /dev/null
+++ b/test/Sema/callingconv.c
@@ -0,0 +1,46 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify
+
+void __attribute__((fastcall)) foo(float *a) { 
+}
+
+void __attribute__((stdcall)) bar(float *a) { 
+}
+
+void __attribute__((fastcall(1))) baz(float *a) { // expected-error {{attribute requires 0 argument(s)}}
+}
+
+void __attribute__((fastcall)) test0() { // expected-error {{function with no prototype cannot use fastcall calling convention}}
+}
+
+void __attribute__((fastcall)) test1(void) {
+}
+
+void __attribute__((fastcall)) test2(int a, ...) { // expected-error {{variadic function cannot use fastcall calling convention}}
+}
+
+void __attribute__((cdecl)) ctest0() {}
+
+void __attribute__((cdecl(1))) ctest1(float x) {} // expected-error {{attribute requires 0 argument(s)}}
+
+void (__attribute__((fastcall)) *pfoo)(float*) = foo;
+
+void (__attribute__((stdcall)) *pbar)(float*) = bar;
+
+void (__attribute__((cdecl)) *ptest1)(void) = test1; // expected-warning {{incompatible pointer types}}
+
+void (*pctest0)() = ctest0;
+
+void ctest2() {}
+void (__attribute__((cdecl)) *pctest2)() = ctest2;
+
+typedef void (__attribute__((fastcall)) *Handler) (float *);
+Handler H = foo;
+
+// PR6361
+void ctest3();
+void __attribute__((cdecl)) ctest3() {}
+
+// PR6408
+typedef __attribute__((stdcall)) void (*PROC)();
+PROC __attribute__((cdecl)) ctest4(const char *x) {}
+
diff --git a/test/Sema/carbon.c b/test/Sema/carbon.c
new file mode 100644
index 0000000..f0affd2
--- /dev/null
+++ b/test/Sema/carbon.c
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -target-cpu pentium4 %s -print-stats
+#ifdef __APPLE__
+#include <Carbon/Carbon.h>
+#endif
+
diff --git a/test/Sema/cast-to-union.c b/test/Sema/cast-to-union.c
new file mode 100644
index 0000000..6f275e8
--- /dev/null
+++ b/test/Sema/cast-to-union.c
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s
+
+union u { int i; };
+void f(union u);
+
+void test(int x) {
+  f((union u)x); // expected-warning {{C99 forbids casts to union type}}
+  f((union u)&x); // expected-error {{cast to union type from type 'int *' not present in union}}
+}
+
+union u w = (union u)2; // expected-warning {{C99 forbids casts to union type}}
+union u ww = (union u)1.0; // expected-error{{cast to union type from type 'double' not present in union}}
+union u x = 7; // expected-error{{initializing 'union u' with an expression of incompatible type 'int'}}
+int i;
+union u zz = (union u)i; // expected-error{{initializer element is not a compile-time constant}}  expected-warning {{C99 forbids casts to union type}}
+
+struct s {int a, b;};
+struct s y = { 1, 5 };
+struct s z = (struct s){ 1, 5 };
diff --git a/test/Sema/cast.c b/test/Sema/cast.c
new file mode 100644
index 0000000..e52dcae
--- /dev/null
+++ b/test/Sema/cast.c
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -fsyntax-only %s -verify
+
+typedef struct { unsigned long bits[(((1) + (64) - 1) / (64))]; } cpumask_t;
+cpumask_t x;
+void foo() {
+  (void)x;
+}
+void bar() {
+  char* a;
+  double b;
+  b = (double)a; // expected-error {{pointer cannot be cast to type}}
+  a = (char*)b; // expected-error {{cannot be cast to a pointer type}}
+}
+
+long bar1(long *next) {
+        return (long)(*next)++;  
+}
+
diff --git a/test/Sema/check-increment.c b/test/Sema/check-increment.c
new file mode 100644
index 0000000..070ea74
--- /dev/null
+++ b/test/Sema/check-increment.c
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+int printf(const char *, ...);
+typedef int *pint;
+int main() {
+   int a[5] = {0};
+   pint p = a;
+   p++;
+   printf("%d\n", *p);
+}
diff --git a/test/Sema/compare.c b/test/Sema/compare.c
new file mode 100644
index 0000000..631b694
--- /dev/null
+++ b/test/Sema/compare.c
@@ -0,0 +1,289 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -fsyntax-only -pedantic -verify -Wsign-compare %s -Wno-unreachable-code
+
+int test(char *C) { // nothing here should warn.
+  return C != ((void*)0);
+  return C != (void*)0;
+  return C != 0;  
+  return C != 1;  // expected-warning {{comparison between pointer and integer ('char *' and 'int')}}
+}
+
+int ints(long a, unsigned long b) {
+  enum EnumA {A};
+  enum EnumB {B};
+  enum EnumC {C = 0x10000};
+  return
+         // (a,b)
+         (a == (unsigned long) b) +  // expected-warning {{comparison of integers of different signs}}
+         (a == (unsigned int) b) +
+         (a == (unsigned short) b) +
+         (a == (unsigned char) b) +
+         ((long) a == b) +  // expected-warning {{comparison of integers of different signs}}
+         ((int) a == b) +  // expected-warning {{comparison of integers of different signs}}
+         ((short) a == b) +  // expected-warning {{comparison of integers of different signs}}
+         ((signed char) a == b) +  // expected-warning {{comparison of integers of different signs}}
+         ((long) a == (unsigned long) b) +  // expected-warning {{comparison of integers of different signs}}
+         ((int) a == (unsigned int) b) +  // expected-warning {{comparison of integers of different signs}}
+         ((short) a == (unsigned short) b) +  // expected-warning {{comparison of integers of different signs}}
+         ((signed char) a == (unsigned char) b) +  // expected-warning {{comparison of integers of different signs}}
+         (a < (unsigned long) b) +  // expected-warning {{comparison of integers of different signs}}
+         (a < (unsigned int) b) +
+         (a < (unsigned short) b) +
+         (a < (unsigned char) b) +
+         ((long) a < b) +  // expected-warning {{comparison of integers of different signs}}
+         ((int) a < b) +  // expected-warning {{comparison of integers of different signs}}
+         ((short) a < b) +  // expected-warning {{comparison of integers of different signs}}
+         ((signed char) a < b) +  // expected-warning {{comparison of integers of different signs}}
+         ((long) a < (unsigned long) b) +  // expected-warning {{comparison of integers of different signs}}
+         ((int) a < (unsigned int) b) +  // expected-warning {{comparison of integers of different signs}}
+         ((short) a < (unsigned short) b) +  // expected-warning {{comparison of integers of different signs}}
+         ((signed char) a < (unsigned char) b) +  // expected-warning {{comparison of integers of different signs}}
+
+         // (A,b)
+         (A == (unsigned long) b) +
+         (A == (unsigned int) b) +
+         (A == (unsigned short) b) +
+         (A == (unsigned char) b) +
+         ((long) A == b) +
+         ((int) A == b) +
+         ((short) A == b) +
+         ((signed char) A == b) +
+         ((long) A == (unsigned long) b) +
+         ((int) A == (unsigned int) b) +
+         ((short) A == (unsigned short) b) +
+         ((signed char) A == (unsigned char) b) +
+         (A < (unsigned long) b) +
+         (A < (unsigned int) b) +
+         (A < (unsigned short) b) +
+         (A < (unsigned char) b) +
+         ((long) A < b) +
+         ((int) A < b) +
+         ((short) A < b) +
+         ((signed char) A < b) +
+         ((long) A < (unsigned long) b) +
+         ((int) A < (unsigned int) b) +
+         ((short) A < (unsigned short) b) +
+         ((signed char) A < (unsigned char) b) +
+
+         // (a,B)
+         (a == (unsigned long) B) +
+         (a == (unsigned int) B) +
+         (a == (unsigned short) B) +
+         (a == (unsigned char) B) +
+         ((long) a == B) +
+         ((int) a == B) +
+         ((short) a == B) +
+         ((signed char) a == B) +
+         ((long) a == (unsigned long) B) +
+         ((int) a == (unsigned int) B) +
+         ((short) a == (unsigned short) B) +
+         ((signed char) a == (unsigned char) B) +
+         (a < (unsigned long) B) +  // expected-warning {{comparison of integers of different signs}}
+         (a < (unsigned int) B) +
+         (a < (unsigned short) B) +
+         (a < (unsigned char) B) +
+         ((long) a < B) +
+         ((int) a < B) +
+         ((short) a < B) +
+         ((signed char) a < B) +
+         ((long) a < (unsigned long) B) +  // expected-warning {{comparison of integers of different signs}}
+         ((int) a < (unsigned int) B) +  // expected-warning {{comparison of integers of different signs}}
+         ((short) a < (unsigned short) B) +  // expected-warning {{comparison of integers of different signs}}
+         ((signed char) a < (unsigned char) B) +  // expected-warning {{comparison of integers of different signs}}
+
+         // (C,b)
+         (C == (unsigned long) b) +
+         (C == (unsigned int) b) +
+         (C == (unsigned short) b) +
+         (C == (unsigned char) b) +
+         ((long) C == b) +
+         ((int) C == b) +
+         ((short) C == b) +
+         ((signed char) C == b) +
+         ((long) C == (unsigned long) b) +
+         ((int) C == (unsigned int) b) +
+         ((short) C == (unsigned short) b) +
+         ((signed char) C == (unsigned char) b) +
+         (C < (unsigned long) b) +
+         (C < (unsigned int) b) +
+         (C < (unsigned short) b) +
+         (C < (unsigned char) b) +
+         ((long) C < b) +
+         ((int) C < b) +
+         ((short) C < b) +
+         ((signed char) C < b) +
+         ((long) C < (unsigned long) b) +
+         ((int) C < (unsigned int) b) +
+         ((short) C < (unsigned short) b) +
+         ((signed char) C < (unsigned char) b) +
+
+         // (a,C)
+         (a == (unsigned long) C) +
+         (a == (unsigned int) C) +
+         (a == (unsigned short) C) +
+         (a == (unsigned char) C) +
+         ((long) a == C) +
+         ((int) a == C) +
+         ((short) a == C) +
+         ((signed char) a == C) +
+         ((long) a == (unsigned long) C) +
+         ((int) a == (unsigned int) C) +
+         ((short) a == (unsigned short) C) +
+         ((signed char) a == (unsigned char) C) +
+         (a < (unsigned long) C) +  // expected-warning {{comparison of integers of different signs}}
+         (a < (unsigned int) C) +
+         (a < (unsigned short) C) +
+         (a < (unsigned char) C) +
+         ((long) a < C) +
+         ((int) a < C) +
+         ((short) a < C) +
+         ((signed char) a < C) +
+         ((long) a < (unsigned long) C) +  // expected-warning {{comparison of integers of different signs}}
+         ((int) a < (unsigned int) C) +  // expected-warning {{comparison of integers of different signs}}
+         ((short) a < (unsigned short) C) +  // expected-warning {{comparison of integers of different signs}}
+         ((signed char) a < (unsigned char) C) +  // expected-warning {{comparison of integers of different signs}}
+
+         // (0x80000,b)
+         (0x80000 == (unsigned long) b) +
+         (0x80000 == (unsigned int) b) +
+         (0x80000 == (unsigned short) b) +
+         (0x80000 == (unsigned char) b) +
+         ((long) 0x80000 == b) +
+         ((int) 0x80000 == b) +
+         ((short) 0x80000 == b) +
+         ((signed char) 0x80000 == b) +
+         ((long) 0x80000 == (unsigned long) b) +
+         ((int) 0x80000 == (unsigned int) b) +
+         ((short) 0x80000 == (unsigned short) b) +
+         ((signed char) 0x80000 == (unsigned char) b) +
+         (0x80000 < (unsigned long) b) +
+         (0x80000 < (unsigned int) b) +
+         (0x80000 < (unsigned short) b) +
+         (0x80000 < (unsigned char) b) +
+         ((long) 0x80000 < b) +
+         ((int) 0x80000 < b) +
+         ((short) 0x80000 < b) +
+         ((signed char) 0x80000 < b) +
+         ((long) 0x80000 < (unsigned long) b) +
+         ((int) 0x80000 < (unsigned int) b) +
+         ((short) 0x80000 < (unsigned short) b) +
+         ((signed char) 0x80000 < (unsigned char) b) +
+
+         // (a,0x80000)
+         (a == (unsigned long) 0x80000) +
+         (a == (unsigned int) 0x80000) +
+         (a == (unsigned short) 0x80000) +
+         (a == (unsigned char) 0x80000) +
+         ((long) a == 0x80000) +
+         ((int) a == 0x80000) +
+         ((short) a == 0x80000) +
+         ((signed char) a == 0x80000) +
+         ((long) a == (unsigned long) 0x80000) +
+         ((int) a == (unsigned int) 0x80000) +
+         ((short) a == (unsigned short) 0x80000) +
+         ((signed char) a == (unsigned char) 0x80000) +
+         (a < (unsigned long) 0x80000) +  // expected-warning {{comparison of integers of different signs}}
+         (a < (unsigned int) 0x80000) +
+         (a < (unsigned short) 0x80000) +
+         (a < (unsigned char) 0x80000) +
+         ((long) a < 0x80000) +
+         ((int) a < 0x80000) +
+         ((short) a < 0x80000) +
+         ((signed char) a < 0x80000) +
+         ((long) a < (unsigned long) 0x80000) +  // expected-warning {{comparison of integers of different signs}}
+         ((int) a < (unsigned int) 0x80000) +  // expected-warning {{comparison of integers of different signs}}
+         ((short) a < (unsigned short) 0x80000) +  // expected-warning {{comparison of integers of different signs}}
+         ((signed char) a < (unsigned char) 0x80000) +  // expected-warning {{comparison of integers of different signs}}
+
+         // We should be able to avoid warning about this.
+         (b != (a < 4 ? 1 : 2)) +
+
+         10
+    ;
+}
+
+int equal(char *a, const char *b) {
+    return a == b;
+}
+
+int arrays(char (*a)[5], char(*b)[10], char(*c)[5]) {
+  int d = (a == c);
+  return a == b; // expected-warning {{comparison of distinct pointer types}}
+}
+
+int pointers(int *a) {
+  return a > 0; // expected-warning {{ordered comparison between pointer and zero ('int *' and 'int') is an extension}}
+  return a > 42; // expected-warning {{ordered comparison between pointer and integer ('int *' and 'int')}}
+  return a > (void *)0; // expected-warning {{comparison of distinct pointer types}}
+}
+
+int function_pointers(int (*a)(int), int (*b)(int), void (*c)(int)) {
+  return a > b; // expected-warning {{ordered comparison of function pointers}}
+  return function_pointers > function_pointers; // expected-warning {{ordered comparison of function pointers}}
+  return a > c; // expected-warning {{comparison of distinct pointer types}}
+  return a == (void *) 0;
+  return a == (void *) 1; // expected-warning {{equality comparison between function pointer and void pointer}}
+}
+
+int void_pointers(void* foo) {
+  return foo == (void*) 0;
+  return foo == (void*) 1;
+}
+
+int test1(int i) {
+  enum en { zero };
+  return i > zero;
+}
+
+// PR5937
+int test2(int i32) {
+  struct foo {
+    unsigned int u8 : 8;
+    unsigned long long u31 : 31;
+    unsigned long long u32 : 32;
+    unsigned long long u63 : 63;
+    unsigned long long u64 : 64;
+  } *x;
+  
+  if (x->u8 == i32) { // comparison in int32, exact
+    return 0;
+  } else if (x->u31 == i32) { // comparison in int32, exact
+    return 1;
+  } else if (x->u32 == i32) { // expected-warning {{comparison of integers of different signs}}
+    return 2;
+  } else if (x->u63 == i32) { // comparison in uint64, exact because ==
+    return 3;
+  } else if (x->u64 == i32) { // expected-warning {{comparison of integers of different signs}}
+    return 4;
+  } else {
+    return 5;
+  }
+}
+
+// PR5887
+void test3() {
+  unsigned short x, y;
+  unsigned int z;
+  if ((x > y ? x : y) > z)
+    (void) 0;
+}
+
+// PR5961
+extern char *ptr4;
+void test4() {
+  long value;
+  if (value < (unsigned long) &ptr4) // expected-warning {{comparison of integers of different signs}}
+    return;
+}
+
+// PR4807
+int test5(unsigned int x) {
+  return (x < 0) // expected-warning {{comparison of unsigned expression < 0 is always false}}
+    && (0 > x)   // expected-warning {{comparison of 0 > unsigned expression is always false}}
+    && (x >= 0)  // expected-warning {{comparison of unsigned expression >= 0 is always true}}
+    && (0 <= x); // expected-warning {{comparison of 0 <= unsigned expression is always true}}
+}
+
+int test6(unsigned i, unsigned power) {
+  unsigned x = (i < (1 << power) ? i : 0);
+  return x != 3 ? 1 << power : i;
+}
diff --git a/test/Sema/complex-int.c b/test/Sema/complex-int.c
new file mode 100644
index 0000000..cb76a34
--- /dev/null
+++ b/test/Sema/complex-int.c
@@ -0,0 +1,55 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only
+
+void a() {
+__complex__ int arr;
+__complex__ short brr;
+__complex__ unsigned xx;
+__complex__ signed yy;
+__complex__ int result;
+int ii;
+int aa = 1 + 1.0iF;
+
+result = arr*ii;
+result = ii*brr;
+
+result = arr*brr;
+result = xx*yy;
+
+switch (arr) { // expected-error{{statement requires expression of integer type ('_Complex int' invalid)}}
+  case brr: ; // expected-error{{expression is not an integer constant expression}}
+  case xx: ; // expected-error{{expression is not an integer constant expression}}
+}
+}
+
+void Tester() {
+__complex short a1;
+__complex int a2;
+__complex float a3;
+__complex double a4;
+short a5;
+int a6;
+float a7;
+double a8;
+#define TestPair(m,n) int x##m##n = a##m+a##n;
+#define TestPairs(m) TestPair(m,1) TestPair(m,2) \
+                    TestPair(m,3) TestPair(m,4) \
+                    TestPair(m,5) TestPair(m,6) \
+                    TestPair(m,7) TestPair(m,8)
+TestPairs(1); TestPairs(2);
+TestPairs(3); TestPairs(4);
+TestPairs(5); TestPairs(6);
+TestPairs(7); TestPairs(8);
+}
+
+// rdar://6097730
+void test3(_Complex int *x) {
+  *x = ~*x;
+}
+
+void test4(_Complex float *x) {
+  *x = ~*x;
+}
+
+void test5(_Complex int *x) {
+  (*x)++;
+}
diff --git a/test/Sema/complex-promotion.c b/test/Sema/complex-promotion.c
new file mode 100644
index 0000000..23c3b68
--- /dev/null
+++ b/test/Sema/complex-promotion.c
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only
+
+float a;
+
+int b[__builtin_classify_type(a + 1i) == 9 ? 1 : -1];
+int c[__builtin_classify_type(1i + a) == 9 ? 1 : -1];
+
+double d;
+__typeof__ (d + 1i) e;
+
+int f[sizeof(e) == 2 * sizeof(double) ? 1 : -1];
+
+int g;
+int h[__builtin_classify_type(g + 1.0i) == 9 ? 1 : -1];
+int i[__builtin_classify_type(1.0i + a) == 9 ? 1 : -1];
diff --git a/test/Sema/compound-literal.c b/test/Sema/compound-literal.c
new file mode 100644
index 0000000..08c30b3
--- /dev/null
+++ b/test/Sema/compound-literal.c
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s
+
+struct foo { int a, b; };
+
+static struct foo t = (struct foo){0,0};
+static struct foo t2 = {0,0}; 
+static struct foo t3 = t2; // -expected-error {{initializer element is not a compile-time constant}}
+static int *p = (int []){2,4}; 
+static int x = (int){1};
+
+static int *p2 = (int []){2,x}; // -expected-error {{initializer element is not a compile-time constant}}
+static long *p3 = (long []){2,"x"}; // -expected-warning {{incompatible pointer to integer conversion initializing 'long' with an expression of type 'char [2]'}}
+
+typedef struct { } cache_t; // -expected-warning{{use of empty struct extension}}
+static cache_t clo_I1_cache = ((cache_t) { } ); // -expected-warning{{use of GNU empty initializer extension}}
+
+typedef struct Test {int a;int b;} Test;
+static Test* ll = &(Test) {0,0};
+
+extern void fooFunc(struct foo *pfoo);
+
+int main(int argc, char **argv) {
+ int *l = (int []){x, *p, *p2};
+ fooFunc(&(struct foo){ 1, 2 });
+}
+
+struct Incomplete; // expected-note{{forward declaration of 'struct Incomplete'}}
+struct Incomplete* I1 = &(struct Incomplete){1, 2, 3}; // -expected-error {{variable has incomplete type}}
+void IncompleteFunc(unsigned x) {
+  struct Incomplete* I2 = (struct foo[x]){1, 2, 3}; // -expected-error {{variable-sized object may not be initialized}}
+  (void){1,2,3}; // -expected-error {{variable has incomplete type}}
+  (void(void)) { 0 }; // -expected-error{{illegal initializer type 'void (void)'}}
+}
+
+// PR6080
+int array[(sizeof(int[3]) == sizeof( (int[]) {0,1,2} )) ? 1 : -1];
diff --git a/test/Sema/conditional-expr.c b/test/Sema/conditional-expr.c
new file mode 100644
index 0000000..5e2c1a4
--- /dev/null
+++ b/test/Sema/conditional-expr.c
@@ -0,0 +1,70 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -pedantic -Wsign-compare %s
+void foo() {
+  *(0 ? (double *)0 : (void *)0) = 0;
+  // FIXME: GCC doesn't consider the the following two statements to be errors.
+  *(0 ? (double *)0 : (void *)(int *)0) = 0; // expected-error {{incomplete type 'void' is not assignable}}
+  *(0 ? (double *)0 : (void *)(double *)0) = 0; // expected-error {{incomplete type 'void' is not assignable}}
+  *(0 ? (double *)0 : (int *)(void *)0) = 0; // expected-error {{incomplete type 'void' is not assignable}} expected-warning {{pointer type mismatch ('double *' and 'int *')}}
+  *(0 ? (double *)0 : (double *)(void *)0) = 0;
+  *((void *) 0) = 0; // expected-error {{incomplete type 'void' is not assignable}}
+  double *dp;
+  int *ip;
+  void *vp;
+
+  dp = vp;
+  vp = dp;
+  ip = dp; // expected-warning {{incompatible pointer types assigning to 'int *' from 'double *'}}
+  dp = ip; // expected-warning {{incompatible pointer types assigning to 'double *' from 'int *'}}
+  dp = 0 ? (double *)0 : (void *)0;
+  vp = 0 ? (double *)0 : (void *)0;
+  ip = 0 ? (double *)0 : (void *)0; // expected-warning {{incompatible pointer types assigning to 'int *' from 'double *'}}
+
+  const int *cip;
+  vp = (0 ? vp : cip); // expected-warning {{discards qualifiers}}
+  vp = (0 ? cip : vp); // expected-warning {{discards qualifiers}}
+
+  int i = 2;
+  int (*pf)[2];
+  int (*pv)[i];
+  pf = (i ? pf : pv);
+
+  enum {xxx,yyy,zzz} e, *ee;
+  short x;
+  ee = ee ? &x : ee ? &i : &e; // expected-warning {{pointer type mismatch}}
+
+  typedef void *asdf;
+  *(0 ? (asdf) 0 : &x) = 10;
+
+  unsigned long test0 = 5;
+  test0 = test0 ? (long) test0 : test0; // expected-warning {{operands of ? are integers of different signs}}
+  test0 = test0 ? (int) test0 : test0; // expected-warning {{operands of ? are integers of different signs}}
+  test0 = test0 ? (short) test0 : test0; // expected-warning {{operands of ? are integers of different signs}}
+  test0 = test0 ? test0 : (long) test0; // expected-warning {{operands of ? are integers of different signs}}
+  test0 = test0 ? test0 : (int) test0; // expected-warning {{operands of ? are integers of different signs}}
+  test0 = test0 ? test0 : (short) test0; // expected-warning {{operands of ? are integers of different signs}}
+  test0 = test0 ? test0 : (long) 10;
+  test0 = test0 ? test0 : (int) 10;
+  test0 = test0 ? test0 : (short) 10;
+  test0 = test0 ? (long) 10 : test0;
+  test0 = test0 ? (int) 10 : test0;
+  test0 = test0 ? (short) 10 : test0;
+
+  enum Enum { EVal };
+  test0 = test0 ? EVal : test0;
+  test0 = test0 ? EVal : (int) test0; // okay: EVal is an int
+  test0 = test0 ? (unsigned) EVal : (int) test0; // expected-warning {{operands of ? are integers of different signs}}
+}
+
+int Postgresql() {
+  char x;
+  return ((((&x) != ((void *) 0)) ? (*(&x) = ((char) 1)) : (void) ((void *) 0)), (unsigned long) ((void *) 0)); // expected-warning {{C99 forbids conditional expressions with only one void side}}
+}
+
+#define nil ((void*) 0)
+
+extern int f1(void);
+
+int f0(int a) {
+  // GCC considers this a warning.
+  return a ? f1() : nil; // expected-warning {{pointer/integer type mismatch in conditional expression ('int' and 'void *')}} expected-warning {{incompatible pointer to integer conversion returning 'void *' from a function with result type 'int'}}
+}
diff --git a/test/Sema/conditional.c b/test/Sema/conditional.c
new file mode 100644
index 0000000..3d7bcca
--- /dev/null
+++ b/test/Sema/conditional.c
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify
+
+const char* test1 = 1 ? "i" : 1 == 1 ? "v" : "r";
+
+void _efree(void *ptr);
+void free(void *ptr);
+
+int _php_stream_free1() {
+  return (1 ? free(0) : _efree(0)); // expected-error {{returning 'void' from a function with incompatible result type 'int'}}
+}
+
+int _php_stream_free2() {
+  return (1 ? _efree(0) : free(0));  // expected-error {{returning 'void' from a function with incompatible result type 'int'}}
+}
diff --git a/test/Sema/const-eval.c b/test/Sema/const-eval.c
new file mode 100644
index 0000000..9c53725
--- /dev/null
+++ b/test/Sema/const-eval.c
@@ -0,0 +1,78 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+#define EVAL_EXPR(testno, expr) int test##testno = sizeof(struct{char qq[expr];});
+int x;
+EVAL_EXPR(1, (_Bool)&x)
+EVAL_EXPR(2, (int)(1.0+(double)4))
+EVAL_EXPR(3, (int)(1.0+(float)4.0))
+EVAL_EXPR(4, (_Bool)(1 ? (void*)&x : 0))
+EVAL_EXPR(5, (_Bool)(int[]){0})
+struct y {int x,y;};
+EVAL_EXPR(6, (int)(1+(struct y*)0))
+EVAL_EXPR(7, (int)&((struct y*)0)->y)
+EVAL_EXPR(8, (_Bool)"asdf")
+EVAL_EXPR(9, !!&x)
+EVAL_EXPR(10, ((void)1, 12))
+void g0(void);
+EVAL_EXPR(11, (g0(), 12)) // FIXME: This should give an error
+EVAL_EXPR(12, 1.0&&2.0)
+EVAL_EXPR(13, x || 3.0)
+
+unsigned int l_19 = 1;
+EVAL_EXPR(14, (1 ^ l_19) && 1); // expected-error {{fields must have a constant size}}
+
+void f()
+{
+  int a;
+  EVAL_EXPR(15, (_Bool)&a); // expected-error {{fields must have a constant size}}
+}
+
+// FIXME: Turn into EVAL_EXPR test once we have more folding.
+_Complex float g16 = (1.0f + 1.0fi);
+
+// ?: in constant expressions.
+int g17[(3?:1) - 2]; 
+
+EVAL_EXPR(18, ((int)((void*)10 + 10)) == 20 ? 1 : -1);
+
+struct s {
+  int a[(int)-1.0f]; // expected-error {{array size is negative}}
+};
+
+EVAL_EXPR(19, ((int)&*(char*)10 == 10 ? 1 : -1));
+
+EVAL_EXPR(20, __builtin_constant_p(*((int*) 10), -1, 1));
+
+EVAL_EXPR(21, (__imag__ 2i) == 2 ? 1 : -1);
+
+EVAL_EXPR(22, (__real__ (2i+3)) == 3 ? 1 : -1);
+
+int g23[(int)(1.0 / 1.0)] = { 1 };
+int g24[(int)(1.0 / 1.0)] = { 1 , 2 }; // expected-warning {{excess elements in array initializer}}
+int g25[(int)(1.0 + 1.0)], g26 = sizeof(g25);
+
+EVAL_EXPR(26, (_Complex double)0 ? -1 : 1)
+EVAL_EXPR(27, (_Complex int)0 ? -1 : 1)
+EVAL_EXPR(28, (_Complex double)1 ? 1 : -1)
+EVAL_EXPR(29, (_Complex int)1 ? 1 : -1)
+
+
+// PR4027 + rdar://6808859
+struct a { int x, y };
+static struct a V2 = (struct a)(struct a){ 1, 2};
+static const struct a V1 = (struct a){ 1, 2};
+
+EVAL_EXPR(30, (int)(_Complex float)((1<<30)-1) == (1<<30) ? 1 : -1)
+EVAL_EXPR(31, (int*)0 == (int*)0 ? 1 : -1)
+EVAL_EXPR(32, (int*)0 != (int*)0 ? -1 : 1)
+EVAL_EXPR(33, (void*)0 - (void*)0 == 0 ? 1 : -1)
+void foo(void) {}
+EVAL_EXPR(34, (foo == (void *)0) ? -1 : 1)
+
+// No PR. Mismatched bitwidths lead to a crash on second evaluation.
+const _Bool constbool = 0;
+EVAL_EXPR(35, constbool)
+EVAL_EXPR(36, constbool)
+
+EVAL_EXPR(37, (1,2.0) == 2.0)
+EVAL_EXPR(38, __builtin_expect(1,1) == 1)
diff --git a/test/Sema/const-ptr-int-ptr-cast.c b/test/Sema/const-ptr-int-ptr-cast.c
new file mode 100644
index 0000000..c6e70b8
--- /dev/null
+++ b/test/Sema/const-ptr-int-ptr-cast.c
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+#include <stdint.h>
+
+char *a = (void*)(uintptr_t)(void*)&a;
diff --git a/test/Sema/constant-builtins-2.c b/test/Sema/constant-builtins-2.c
new file mode 100644
index 0000000..23aa314
--- /dev/null
+++ b/test/Sema/constant-builtins-2.c
@@ -0,0 +1,52 @@
+// RUN: %clang_cc1 -fsyntax-only %s
+
+// Math stuff
+
+double       g0  = __builtin_huge_val();
+float        g1  = __builtin_huge_valf();
+long double  g2  = __builtin_huge_vall();
+
+double       g3  = __builtin_inf();
+float        g4  = __builtin_inff();
+long double  g5  = __builtin_infl();
+
+double       g6  = __builtin_nan("");
+float        g7  = __builtin_nanf("");
+long double  g8  = __builtin_nanl("");
+
+// GCC constant folds these too (via native strtol):
+//double       g6_1  = __builtin_nan("1");
+//float        g7_1  = __builtin_nanf("1");
+//long double  g8_1  = __builtin_nanl("1");
+
+// APFloat doesn't have signalling NaN functions.
+//double       g9  = __builtin_nans("");
+//float        g10 = __builtin_nansf("");
+//long double  g11 = __builtin_nansl("");
+
+//int          g12 = __builtin_abs(-12);
+
+double       g13 = __builtin_fabs(-12.);
+double       g13_0 = __builtin_fabs(-0.);
+double       g13_1 = __builtin_fabs(-__builtin_inf());
+float        g14 = __builtin_fabsf(-12.f);
+// GCC doesn't eat this one.
+//long double  g15 = __builtin_fabsfl(-12.0L);
+
+float        g16 = __builtin_copysign(1.0, -1.0);
+double       g17 = __builtin_copysignf(1.0f, -1.0f);
+long double  g18 = __builtin_copysignl(1.0L, -1.0L);
+
+//double       g19 = __builtin_powi(2.0, 4);
+//float        g20 = __builtin_powif(2.0f, 4);
+//long double  g21 = __builtin_powil(2.0L, 4);
+
+// GCC misc stuff
+
+extern int f();
+
+int h0 = __builtin_types_compatible_p(int, float);
+//int h1 = __builtin_choose_expr(1, 10, f());
+//int h2 = __builtin_expect(0, 0);
+extern long int bi0;
+extern __typeof__(__builtin_expect(0, 0)) bi0;
diff --git a/test/Sema/constant-builtins.c b/test/Sema/constant-builtins.c
new file mode 100644
index 0000000..5d67fc7
--- /dev/null
+++ b/test/Sema/constant-builtins.c
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -fsyntax-only %s -verify -pedantic
+
+// Math stuff
+
+float        g0 = __builtin_huge_val();
+double       g1 = __builtin_huge_valf();
+long double  g2 = __builtin_huge_vall();
+float        g3 = __builtin_inf();
+double       g4 = __builtin_inff();
+long double  g5 = __builtin_infl();
+
+// GCC misc stuff
+
+extern int f();
+
+int h0 = __builtin_types_compatible_p(int,float);
+//int h1 = __builtin_choose_expr(1, 10, f());
+//int h2 = __builtin_expect(0, 0);
+
+short somefunc();
+
+short t = __builtin_constant_p(5353) ? 42 : somefunc();
+
+
diff --git a/test/Sema/constructor-attribute.c b/test/Sema/constructor-attribute.c
new file mode 100644
index 0000000..3dfbbcb
--- /dev/null
+++ b/test/Sema/constructor-attribute.c
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+int x __attribute__((constructor)); // expected-warning {{'constructor' attribute only applies to function types}}
+int f() __attribute__((constructor));
+int f() __attribute__((constructor(1)));
+int f() __attribute__((constructor(1,2))); // expected-error {{attribute requires 0 or 1 argument(s)}}
+int f() __attribute__((constructor(1.0))); // expected-error {{'constructor' attribute requires parameter 1 to be an integer constant}}
+
+int x __attribute__((destructor)); // expected-warning {{'destructor' attribute only applies to function types}}
+int f() __attribute__((destructor));
+int f() __attribute__((destructor(1)));
+int f() __attribute__((destructor(1,2))); // expected-error {{attribute requires 0 or 1 argument(s)}}
+int f() __attribute__((destructor(1.0))); // expected-error {{'destructor' attribute requires parameter 1 to be an integer constant}}
+
+
diff --git a/test/Sema/conversion-64-32.c b/test/Sema/conversion-64-32.c
new file mode 100644
index 0000000..1043996
--- /dev/null
+++ b/test/Sema/conversion-64-32.c
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wshorten-64-to-32 -triple x86_64-apple-darwin %s
+
+int test0(long v) {
+  return v; // expected-warning {{implicit cast loses integer precision}}
+}
diff --git a/test/Sema/conversion.c b/test/Sema/conversion.c
new file mode 100644
index 0000000..addedd9
--- /dev/null
+++ b/test/Sema/conversion.c
@@ -0,0 +1,289 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wconversion -nostdinc -isystem %S/Inputs -triple x86_64-apple-darwin %s -Wno-unreachable-code
+
+#include <conversion.h>
+
+#define BIG 0x7f7f7f7f7f7f7f7fL
+
+void test0(char c, short s, int i, long l, long long ll) {
+  c = c;
+  c = s; // expected-warning {{implicit cast loses integer precision}}
+  c = i; // expected-warning {{implicit cast loses integer precision}}
+  c = l; // expected-warning {{implicit cast loses integer precision}}
+  s = c;
+  s = s;
+  s = i; // expected-warning {{implicit cast loses integer precision}}
+  s = l; // expected-warning {{implicit cast loses integer precision}}
+  i = c;
+  i = s;
+  i = i;
+  i = l; // expected-warning {{implicit cast loses integer precision}}
+  l = c;
+  l = s;
+  l = i;
+  l = l;
+
+  c = (char) 0;
+  c = (short) 0;
+  c = (int) 0;
+  c = (long) 0;
+  s = (char) 0;
+  s = (short) 0;
+  s = (int) 0;
+  s = (long) 0;
+  i = (char) 0;
+  i = (short) 0;
+  i = (int) 0;
+  i = (long) 0;
+  l = (char) 0;
+  l = (short) 0;
+  l = (int) 0;
+  l = (long) 0;
+
+  c = (char) BIG;
+  c = (short) BIG; // expected-warning {{implicit cast loses integer precision}}
+  c = (int) BIG; // expected-warning {{implicit cast loses integer precision}}
+  c = (long) BIG; // expected-warning {{implicit cast loses integer precision}}
+  s = (char) BIG;
+  s = (short) BIG;
+  s = (int) BIG; // expected-warning {{implicit cast loses integer precision}}
+  s = (long) BIG; // expected-warning {{implicit cast loses integer precision}}
+  i = (char) BIG;
+  i = (short) BIG;
+  i = (int) BIG;
+  i = (long) BIG; // expected-warning {{implicit cast loses integer precision}}
+  l = (char) BIG;
+  l = (short) BIG;
+  l = (int) BIG;
+  l = (long) BIG;
+}
+
+char test1(long long ll) {
+  return (long long) ll; // expected-warning {{implicit cast loses integer precision}}
+  return (long) ll; // expected-warning {{implicit cast loses integer precision}}
+  return (int) ll; // expected-warning {{implicit cast loses integer precision}}
+  return (short) ll; // expected-warning {{implicit cast loses integer precision}}
+  return (char) ll;
+  return (long long) BIG; // expected-warning {{implicit cast loses integer precision}}
+  return (long) BIG; // expected-warning {{implicit cast loses integer precision}}
+  return (int) BIG; // expected-warning {{implicit cast loses integer precision}}
+  return (short) BIG; // expected-warning {{implicit cast loses integer precision}}
+  return (char) BIG;
+}
+
+short test2(long long ll) {
+  return (long long) ll; // expected-warning {{implicit cast loses integer precision}}
+  return (long) ll; // expected-warning {{implicit cast loses integer precision}}
+  return (int) ll; // expected-warning {{implicit cast loses integer precision}}
+  return (short) ll;
+  return (char) ll;
+  return (long long) BIG;  // expected-warning {{implicit cast loses integer precision}}
+  return (long) BIG;  // expected-warning {{implicit cast loses integer precision}}
+  return (int) BIG;  // expected-warning {{implicit cast loses integer precision}}
+  return (short) BIG;
+  return (char) BIG;
+}
+
+int test3(long long ll) {
+  return (long long) ll;  // expected-warning {{implicit cast loses integer precision}}
+  return (long) ll;  // expected-warning {{implicit cast loses integer precision}}
+  return (int) ll;
+  return (short) ll;
+  return (char) ll;
+  return (long long) BIG;  // expected-warning {{implicit cast loses integer precision}}
+  return (long) BIG; // expected-warning {{implicit cast loses integer precision}}
+  return (int) BIG;
+  return (short) BIG;
+  return (char) BIG;
+}
+
+long test4(long long ll) {
+  return (long long) ll;
+  return (long) ll;
+  return (int) ll;
+  return (short) ll;
+  return (char) ll;
+  return (long long) BIG;
+  return (long) BIG;
+  return (int) BIG;
+  return (short) BIG;
+  return (char) BIG;
+}
+
+long long test5(long long ll) {
+  return (long long) ll;
+  return (long) ll;
+  return (int) ll;
+  return (short) ll;
+  return (char) ll;
+  return (long long) BIG;
+  return (long) BIG;
+  return (int) BIG;
+  return (short) BIG;
+  return (char) BIG;
+}
+
+void takes_char(char);
+void takes_short(short);
+void takes_int(int);
+void takes_long(long);
+void takes_longlong(long long);
+void takes_float(float);
+void takes_double(double);
+void takes_longdouble(long double);
+
+void test6(char v) {
+  takes_char(v);
+  takes_short(v);
+  takes_int(v);
+  takes_long(v);
+  takes_longlong(v);
+  takes_float(v);
+  takes_double(v);
+  takes_longdouble(v);
+}
+
+void test7(short v) {
+  takes_char(v); // expected-warning {{implicit cast loses integer precision}}
+  takes_short(v);
+  takes_int(v);
+  takes_long(v);
+  takes_longlong(v);
+  takes_float(v);
+  takes_double(v);
+  takes_longdouble(v);
+}
+
+void test8(int v) {
+  takes_char(v); // expected-warning {{implicit cast loses integer precision}}
+  takes_short(v); // expected-warning {{implicit cast loses integer precision}}
+  takes_int(v);
+  takes_long(v);
+  takes_longlong(v);
+  takes_float(v);
+  takes_double(v);
+  takes_longdouble(v);
+}
+
+void test9(long v) {
+  takes_char(v); // expected-warning {{implicit cast loses integer precision}}
+  takes_short(v); // expected-warning {{implicit cast loses integer precision}}
+  takes_int(v); // expected-warning {{implicit cast loses integer precision}}
+  takes_long(v);
+  takes_longlong(v);
+  takes_float(v);
+  takes_double(v);
+  takes_longdouble(v);
+}
+
+void test10(long long v) {
+  takes_char(v); // expected-warning {{implicit cast loses integer precision}}
+  takes_short(v); // expected-warning {{implicit cast loses integer precision}}
+  takes_int(v); // expected-warning {{implicit cast loses integer precision}}
+  takes_long(v);
+  takes_longlong(v);
+  takes_float(v);
+  takes_double(v);
+  takes_longdouble(v);
+}
+
+void test11(float v) {
+  takes_char(v); // expected-warning {{implicit cast turns floating-point number into integer}}
+  takes_short(v); // expected-warning {{implicit cast turns floating-point number into integer}}
+  takes_int(v); // expected-warning {{implicit cast turns floating-point number into integer}}
+  takes_long(v); // expected-warning {{implicit cast turns floating-point number into integer}}
+  takes_longlong(v); // expected-warning {{implicit cast turns floating-point number into integer}}
+  takes_float(v);
+  takes_double(v);
+  takes_longdouble(v);
+}
+
+void test12(double v) {
+  takes_char(v); // expected-warning {{implicit cast turns floating-point number into integer}}
+  takes_short(v); // expected-warning {{implicit cast turns floating-point number into integer}}
+  takes_int(v); // expected-warning {{implicit cast turns floating-point number into integer}}
+  takes_long(v); // expected-warning {{implicit cast turns floating-point number into integer}}
+  takes_longlong(v); // expected-warning {{implicit cast turns floating-point number into integer}}
+  takes_float(v); // expected-warning {{implicit cast loses floating-point precision}}
+  takes_double(v);
+  takes_longdouble(v);
+}
+
+void test13(long double v) {
+  takes_char(v); // expected-warning {{implicit cast turns floating-point number into integer}}
+  takes_short(v); // expected-warning {{implicit cast turns floating-point number into integer}}
+  takes_int(v); // expected-warning {{implicit cast turns floating-point number into integer}}
+  takes_long(v); // expected-warning {{implicit cast turns floating-point number into integer}}
+  takes_longlong(v); // expected-warning {{implicit cast turns floating-point number into integer}}
+  takes_float(v); // expected-warning {{implicit cast loses floating-point precision}}
+  takes_double(v); // expected-warning {{implicit cast loses floating-point precision}}
+  takes_longdouble(v);
+}
+
+void test14(long l) {
+  // Fine because of the boolean whitelist.
+  char c;
+  c = (l == 4);
+  c = ((l <= 4) && (l >= 0));
+  c = ((l <= 4) && (l >= 0)) || (l > 20);
+}
+
+void test15(char c) {
+  c = c + 1 + c * 2;
+  c = (short) c + 1 + c * 2; // expected-warning {{implicit cast loses integer precision}}
+}
+
+// PR 5422
+extern void *test16_external;
+void test16(void) {
+  int a = (unsigned long) &test16_external; // expected-warning {{implicit cast loses integer precision}}
+}
+
+// PR 5938
+void test17() {
+  union {
+    unsigned long long a : 8;
+    unsigned long long b : 32;
+    unsigned long long c;
+  } U;
+
+  unsigned int x;
+  x = U.a;
+  x = U.b;
+  x = U.c; // expected-warning {{implicit cast loses integer precision}} 
+}
+
+// PR 5939
+void test18() {
+  union {
+    unsigned long long a : 1;
+    unsigned long long b;
+  } U;
+
+  int x;
+  x = (U.a ? 0 : 1);
+  x = (U.b ? 0 : 1);
+}
+
+// None of these should warn.
+unsigned char test19(unsigned long u64) {
+  unsigned char x1 = u64 & 0xff;
+  unsigned char x2 = u64 >> 56;
+
+  unsigned char mask = 0xee;
+  unsigned char x3 = u64 & mask;
+  return x1 + x2 + x3;
+}
+
+// <rdar://problem/7631400>
+void test_7631400(void) {
+  // This should show up despite the caret being inside a macro substitution
+  char s = LONG_MAX; // expected-warning {{implicit cast loses integer precision: 'long' to 'char'}}
+}
+
+// <rdar://problem/7676608>: assertion for compound operators with non-integral RHS
+void f7676608(int);
+void test_7676608(void) {
+  float q = 0.7f;
+  char c = 5;
+  f7676608(c *= q);
+}
diff --git a/test/Sema/darwin-align-cast.c b/test/Sema/darwin-align-cast.c
new file mode 100644
index 0000000..2080974
--- /dev/null
+++ b/test/Sema/darwin-align-cast.c
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+typedef long unsigned int __darwin_size_t;
+typedef long __darwin_ssize_t;
+typedef __darwin_size_t size_t;
+typedef __darwin_ssize_t ssize_t;
+
+struct cmsghdr {};
+
+#if 0
+This code below comes from the following system headers:
+sys/socket.h:#define CMSG_SPACE(l) (__DARWIN_ALIGN(sizeof(struct  
+cmsghdr)) + __DARWIN_ALIGN(l))
+
+i386/_param.h:#define __DARWIN_ALIGN(p) ((__darwin_size_t)((char *)(p)  
++ __DARWIN_ALIGNBYTES) &~ __DARWIN_ALIGNBYTES)
+#endif
+
+ssize_t sendFileDescriptor(int fd, void *data, size_t nbytes, int sendfd) {
+  union {
+    char control[(((__darwin_size_t)((char *)(sizeof(struct cmsghdr)) + (sizeof(__darwin_size_t) - 1)) &~ (sizeof(__darwin_size_t) - 1)) + ((__darwin_size_t)((char *)(sizeof(int)) + (sizeof(__darwin_size_t) - 1)) &~ (sizeof(__darwin_size_t) - 1)))];
+  } control_un;
+  return 0;
+}
+
diff --git a/test/Sema/decl-invalid.c b/test/Sema/decl-invalid.c
new file mode 100644
index 0000000..f6fed3c
--- /dev/null
+++ b/test/Sema/decl-invalid.c
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify
+
+// See Sema::ParsedFreeStandingDeclSpec about the double diagnostic
+typedef union <anonymous> __mbstate_t;  // expected-error {{declaration of anonymous union must be a definition}} expected-warning {{declaration does not declare anything}}
+
+
+// PR2017
+void x(); 
+int a() {
+  int r[x()];  // expected-error {{size of array has non-integer type 'void'}}
+
+  static y ?; // expected-error{{unknown type name 'y'}} \
+                 expected-error{{expected identifier or '('}}
+}
+
+int; // expected-warning {{declaration does not declare anything}}
+typedef int; // expected-warning {{declaration does not declare anything}}
+const int; // expected-warning {{declaration does not declare anything}}
+struct; // expected-error {{declaration of anonymous struct must be a definition}} // expected-warning {{declaration does not declare anything}}
+typedef int I;
+I; // expected-warning {{declaration does not declare anything}}
+
+
+
+// rdar://6880449
+register int test1;     // expected-error {{illegal storage class on file-scoped variable}}
+register int test2 __asm__("edi");  // expected-error {{global register variables are not supported}}
+
diff --git a/test/Sema/decl-type-merging.c b/test/Sema/decl-type-merging.c
new file mode 100644
index 0000000..259b0dd
--- /dev/null
+++ b/test/Sema/decl-type-merging.c
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c99 -verify -pedantic %s
+
+int x[10];
+int x[] = {1,2,3};
+int testx[(sizeof(x) == sizeof(int) * 10) ? 1 : -1];
+
+int (*a)(int (*x)[10], int (*y)[]);
+int (*a)(int (*x)[], int (*y)[5]);
+void b() {
+  int x[10], y[5];
+  a(&x, &y);
+  a(&y, &y); // expected-warning {{incompatible pointer}}
+  a(&x, &x); // expected-warning {{incompatible pointer}}
+}
+
+
diff --git a/test/Sema/declspec.c b/test/Sema/declspec.c
new file mode 100644
index 0000000..7354028
--- /dev/null
+++ b/test/Sema/declspec.c
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only
+typedef char T[4];
+
+T foo(int n, int m) {  }  // expected-error {{cannot return array type}}
+
+void foof(const char *, ...) __attribute__((__format__(__printf__, 1, 2))), barf (void);
+
+int typedef validTypeDecl() { } // expected-error {{function definition declared 'typedef'}}
+
+struct _zend_module_entry { }    // expected-error {{expected ';' after struct}}
+int gv1;
+typedef struct _zend_function_entry { } // expected-error {{expected ';' after struct}} \
+                                        // expected-warning {{declaration does not declare anything}}
+int gv2;
+
+static void buggy(int *x) { }
+
+// Type qualifiers.
+typedef int f(void); 
+typedef f* fptr;
+const f* v1;         // expected-warning {{qualifier on function type 'f' (aka 'int (void)') has unspecified behavior}}
+__restrict__ f* v2;  // expected-error {{restrict requires a pointer or reference ('f' (aka 'int (void)') is invalid)}}
+__restrict__ fptr v3; // expected-error {{pointer to function type 'f' (aka 'int (void)') may not be 'restrict' qualified}}
+f *__restrict__ v4;   // expected-error {{pointer to function type 'f' (aka 'int (void)') may not be 'restrict' qualified}}
+
+restrict struct hallo; // expected-error {{restrict requires a pointer or reference}}
+
+// PR6180
+struct test1 {
+} // expected-error {{expected ';' after struct}}
+
+void test2() {}
+
+
+// PR6423
+struct test3s {
+} // expected-error {{expected ';' after struct}}
+typedef int test3g;
diff --git a/test/Sema/default.c b/test/Sema/default.c
new file mode 100644
index 0000000..1318601
--- /dev/null
+++ b/test/Sema/default.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+void f5 (int z) { 
+  if (z) 
+    default:  // expected-error {{not in switch statement}}
+      ; // expected-warning {{if statement has empty body}}
+} 
+
diff --git a/test/Sema/default1.c b/test/Sema/default1.c
new file mode 100644
index 0000000..631e848
--- /dev/null
+++ b/test/Sema/default1.c
@@ -0,0 +1,2 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+void f(int i = 0); // expected-error {{C does not support default arguments}}
diff --git a/test/Sema/deref.c b/test/Sema/deref.c
new file mode 100644
index 0000000..845b286
--- /dev/null
+++ b/test/Sema/deref.c
@@ -0,0 +1,44 @@
+/* RUN: %clang_cc1 -fsyntax-only -verify -std=c90 -pedantic %s
+ */
+void
+foo (void)
+{
+ struct b;
+ struct b* x = 0;
+ struct b* y = &*x;
+}
+
+void foo2 (void)
+{
+ typedef int (*arrayptr)[];
+ arrayptr x = 0;
+ arrayptr y = &*x;
+}
+
+void foo3 (void)
+{
+ void* x = 0;
+ void* y = &*x; /* expected-warning{{address of an expression of type 'void'}} */
+}
+
+extern const void cv1;
+
+const void *foo4 (void)
+{
+  return &cv1;
+}
+
+extern void cv2;
+void *foo5 (void)
+{
+  return &cv2; /* expected-warning{{address of an expression of type 'void'}} */
+}
+
+typedef const void CVT;
+extern CVT cv3;
+
+const void *foo6 (void)
+{
+  return &cv3;
+}
+
diff --git a/test/Sema/designated-initializers.c b/test/Sema/designated-initializers.c
new file mode 100644
index 0000000..7e4ed68
--- /dev/null
+++ b/test/Sema/designated-initializers.c
@@ -0,0 +1,251 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -triple x86_64-unknown-unknown %s
+
+int complete_array_from_init[] = { 1, 2, [10] = 5, 1, 2, [5] = 2, 6 };
+
+int complete_array_from_init_check[((sizeof(complete_array_from_init) / sizeof(int)) == 13)? 1 : -1];
+
+int iarray[10] = {
+  [0] = 1,
+  [1 ... 5] = 2,
+  [ 6 ... 6 ] = 3,
+  [ 8 ... 7 ] = 4, // expected-error{{array designator range [8, 7] is empty}}
+  [10] = 5,
+  [-1] = 6 // expected-error{{array designator value '-1' is negative}}
+};
+
+int iarray2[10] = {
+  [10] = 1, // expected-error{{array designator index (10) exceeds array bounds (10)}}
+};
+
+int iarray3[10] = {
+  [3] 2, // expected-warning{{use of GNU 'missing =' extension in designator}}
+  [5 ... 12] = 2 // expected-error{{array designator index (12) exceeds array bounds (10)}}
+};
+
+struct point {
+  double x;
+  double y;
+};
+
+struct point p1 = { 
+  .y = 1.0, 
+  x: 2.0, // expected-warning{{}}
+  .a = 4.0, // expected-error{{field designator 'a' does not refer to any field in type 'struct point'}}
+};
+
+struct point p2 = {
+  [1] = 1.0 // expected-error{{array designator cannot initialize non-array type}}
+};
+
+struct point array[10] = { 
+  [0].x = 1.0,
+  [1].y = 2.0,
+  [2].z = 3.0, // expected-error{{field designator 'z' does not refer to any field in type 'struct point'}}
+};
+
+struct point array2[10] = {
+  [10].x = 2.0, // expected-error{{array designator index (10) exceeds array bounds (10)}}
+  [4 ... 5].y = 2.0,
+  [4 ... 6] = { .x = 3, .y = 4.0 }
+};
+
+struct point array3[10] = {
+  .x = 5 // expected-error{{field designator cannot initialize a non-struct, non-union type}}
+};
+
+struct rect {
+  struct point top_left;
+  struct point bottom_right;
+};
+
+struct rect window = { .top_left.x = 1.0 };
+
+struct rect windows[] = {
+  [2].top_left = { 1.0, 2.0 },
+  [4].bottom_right = { .y = 1.0 },
+  { { .y = 7.0, .x = 8.0 }, { .x = 5.0 } },
+  [3] = { .top_left = { 1.1, 2.2 }, .bottom_right = { .y = 1.1 } }
+};
+
+int windows_size[((sizeof(windows) / sizeof(struct rect)) == 6)? 1 : -1];
+
+struct rect windows_bad[3] = {
+  [2].top_left = { { .x = 1.1 } }, // expected-error{{designator in initializer for scalar type}}
+  [1].top_left = { .x = 1.1 }
+};
+
+struct gui {
+  struct rect windows[10];
+};
+
+struct gui gui[] = {
+  [5].windows[3].top_left.x = { 7.0 } // expected-warning{{braces around scalar initializer}}
+};
+
+struct translator {
+  struct wonky { int * ptr; } wonky ;
+  struct rect window;
+  struct point offset;
+} tran = {
+  .window = { .top_left = { 1.0, 2.0 } },
+  { .x = 5.0, .y = 6.0 },
+  .wonky = { 0 }
+};
+
+int anint;
+struct {int x,*y;} z[] = {[0].x = 2, &z[0].x};
+
+struct outer { struct inner { int x, *y; } in, *inp; } zz[] = {
+  [0].in.x = 2, &zz[0].in.x, &zz[0].in,
+  0, &anint, &zz[1].in,
+  [3].in = { .y = &anint, .x = 17 },
+  [7].in.y = &anint, &zz[0].in,
+  [4].in.y = &anint, [5].in.x = 12
+};
+
+int zz_sizecheck[sizeof(zz) / sizeof(struct outer) == 8? 1 : -1 ];
+
+struct disklabel_ops {
+  struct {} type;
+  int labelsize;
+};
+
+struct disklabel_ops disklabel64_ops = {
+  .labelsize = sizeof(struct disklabel_ops)
+};
+
+// PR clang/3378
+int bitwidth[] = { [(long long int)1] = 5, [(short int)2] = 2 };
+int a[]= { [sizeof(int)] = 0 };
+int a2[]= { [0 ... sizeof(int)] = 0 };
+
+// Test warnings about initializers overriding previous initializers
+struct X {
+  int a, b, c;
+};
+
+int counter = 0;
+int get8() { ++counter; return 8; }
+
+void test() {
+  struct X xs[] = { 
+    [0] = (struct X){1, 2}, // expected-note{{previous initialization is here}}
+    [0].c = 3,  // expected-warning{{subobject initialization overrides initialization of other fields within its enclosing subobject}}
+    (struct X) {4, 5, 6}, // expected-note{{previous initialization is here}}
+    [1].b = get8(), // expected-warning{{subobject initialization overrides initialization of other fields within its enclosing subobject}}
+    [0].b = 8
+  };
+}
+
+// FIXME: How do we test that this initializes the long properly?
+union { char c; long l; } u1 = { .l = 0xFFFF };
+
+extern float global_float;
+
+struct XX { int a, *b; };
+struct XY { int before; struct XX xx, *xp; float* after; } xy[] = {
+  0, 0, &xy[0].xx.a, &xy[0].xx, &global_float,
+  [1].xx = 0, &xy[1].xx.a, &xy[1].xx, &global_float,
+  0, // expected-note{{previous initialization is here}}
+  0, // expected-note{{previous initialization is here}}
+  [2].before = 0, // expected-warning{{initializer overrides prior initialization of this subobject}}
+  0, // expected-warning{{initializer overrides prior initialization of this subobject}}
+  &xy[2].xx.a, &xy[2].xx, &global_float
+};
+
+// PR3519
+struct foo {
+  int arr[10];
+};
+
+struct foo Y[10] = {
+  [1] .arr [1] = 2,
+  [4] .arr [2] = 4
+};
+
+struct bar {
+  struct foo f;
+  float *arr[10];
+};
+
+extern float f;
+struct bar saloon = {
+  .f.arr[3] = 1,
+  .arr = { &f }
+};
+
+typedef unsigned char u_char;
+typedef unsigned short u_short;
+
+union wibble {
+        u_char  arr1[6];
+        u_short arr2[3];
+};
+
+const union wibble wobble = { .arr2[0] = 0xffff,
+                              .arr2[1] = 0xffff,
+                              .arr2[2] = 0xffff };
+
+const union wibble wobble2 = { .arr2 = {4, 5, 6}, 7 }; // expected-warning{{excess elements in union initializer}}
+
+// PR3778
+struct s {
+    union { int i; };
+};
+struct s si = {
+    { .i = 1 }
+};
+
+double d0;
+char c0;
+float f0;
+int i0;
+
+struct Enigma {
+  union {
+    struct {
+      struct {
+        double *double_ptr;
+        char *string;
+      };
+      float *float_ptr;
+    };
+    int *int_ptr;
+  };
+  char *string2;
+};
+
+struct Enigma enigma = { 
+  .double_ptr = &d0, &c0, 
+  &f0, // expected-note{{previous}}
+  &c0,
+  .float_ptr = &f0 // expected-warning{{overrides}}
+};
+
+
+/// PR4073
+/// Should use evaluate to fold aggressively and emit a warning if not an ice.
+extern int crazy_x;
+
+int crazy_Y[] = {
+  [ 0 ? crazy_x : 4] = 1
+};
+
+// PR5843
+struct expr {
+  int nargs;
+  union {
+    unsigned long int num;
+    struct expr *args[3];
+  } val;
+};
+
+struct expr expr0 = { 
+  .nargs = 2,
+  .val = {
+    .args = { 
+      [0] = (struct expr *)0, 
+      [1] = (struct expr *)0 
+    }
+  }
+};
diff --git a/test/Sema/dllimport-dllexport.c b/test/Sema/dllimport-dllexport.c
new file mode 100644
index 0000000..eea2f6f
--- /dev/null
+++ b/test/Sema/dllimport-dllexport.c
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -triple i386-mingw32 -fsyntax-only -verify %s
+
+inline void __attribute__((dllexport)) foo1(){} // expected-warning{{dllexport attribute ignored}}
+inline void __attribute__((dllimport)) foo2(){} // expected-warning{{dllimport attribute ignored}}
+
+void __attribute__((dllimport)) foo3(){} // expected-error{{dllimport attribute can be applied only to symbol declaration}}
+
+void __attribute__((dllimport, dllexport)) foo4(); // expected-warning{{dllimport attribute ignored}}
+
+void __attribute__((dllexport)) foo5();
+void __attribute__((dllimport)) foo5(); // expected-warning{{dllimport attribute ignored}}
+
+typedef int __attribute__((dllexport)) type6; // expected-warning{{'dllexport' attribute only applies to variable and function types}}
+
+typedef int __attribute__((dllimport)) type7; // expected-warning{{'dllimport' attribute only applies to variable and function}}
+
+void __attribute__((dllimport)) foo6();
+void foo6(){} // expected-warning {{'foo6' redeclared without dllimport attribute: previous dllimport ignored}}
+
+// PR6269
+inline void __declspec(dllexport) foo7(){} // expected-warning{{dllexport attribute ignored}}
+inline void __declspec(dllimport) foo8(){} // expected-warning{{dllimport attribute ignored}}
+
+void __declspec(dllimport) foo9(){} // expected-error{{dllimport attribute can be applied only to symbol declaration}}
+
+void __declspec(dllimport) __declspec(dllexport) foo10(); // expected-warning{{dllimport attribute ignored}}
+
+void __declspec(dllexport) foo11();
+void __declspec(dllimport) foo11(); // expected-warning{{dllimport attribute ignored}}
+
+typedef int __declspec(dllexport) type1; // expected-warning{{'dllexport' attribute only applies to variable and function types}}
+
+typedef int __declspec(dllimport) type2; // expected-warning{{'dllimport' attribute only applies to variable and function}}
+
+void __declspec(dllimport) foo12();
+void foo12(){} // expected-warning {{'foo12' redeclared without dllimport attribute: previous dllimport ignored}}
diff --git a/test/Sema/enum.c b/test/Sema/enum.c
new file mode 100644
index 0000000..ba4e56b
--- /dev/null
+++ b/test/Sema/enum.c
@@ -0,0 +1,98 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify -pedantic
+enum e {A, 
+        B = 42LL << 32,        // expected-warning {{ISO C restricts enumerator values to range of 'int'}}
+      C = -4, D = 12456 };
+
+enum f { a = -2147483648, b = 2147483647 }; // ok.
+
+enum g {  // too negative
+   c = -2147483649,         // expected-warning {{ISO C restricts enumerator values to range of 'int'}}
+   d = 2147483647 };
+enum h { e = -2147483648, // too pos
+   f = 2147483648,           // expected-warning {{ISO C restricts enumerator values to range of 'int'}}
+  i = 0xFFFF0000 // expected-warning {{too large}}
+}; 
+
+// minll maxull
+enum x                      // expected-warning {{enumeration values exceed range of largest integer}}
+{ y = -9223372036854775807LL-1,  // expected-warning {{ISO C restricts enumerator values to range of 'int'}}
+z = 9223372036854775808ULL };    // expected-warning {{ISO C restricts enumerator values to range of 'int'}}
+
+int test() {
+  return sizeof(enum e) ;
+}
+
+enum gccForwardEnumExtension ve; // expected-warning{{ISO C forbids forward references to 'enum' types}} \
+// expected-error{{tentative definition has type 'enum gccForwardEnumExtension' that is never completed}} \
+// expected-note{{forward declaration of 'enum gccForwardEnumExtension'}}
+
+int test2(int i)
+{
+  ve + i; // expected-error{{invalid operands to binary expression}}
+}
+
+// PR2020
+union u0;    // expected-note {{previous use is here}}
+enum u0 { U0A }; // expected-error {{use of 'u0' with tag type that does not match previous declaration}}
+
+
+// rdar://6095136
+extern enum some_undefined_enum ve2; // expected-warning {{ISO C forbids forward references to 'enum' types}}
+
+void test4() {
+  for (; ve2;) // expected-error {{statement requires expression of scalar type}}
+    ;
+  (_Bool)ve2;  // expected-error {{arithmetic or pointer type is required}}
+
+  for (; ;ve2) // expected-warning {{expression result unused}}
+    ;
+  (void)ve2;
+  ve2;         // expected-warning {{expression result unused}}
+}
+
+// PR2416
+enum someenum {};  // expected-warning {{use of empty enum extension}}
+
+// <rdar://problem/6093889>
+enum e0 { // expected-note {{previous definition is here}}
+  E0 = sizeof(enum e0 { E1 }), // expected-error {{nested redefinition}}
+};
+
+// PR3173
+enum { PR3173A, PR3173B = PR3173A+50 };
+
+// PR2753
+void foo() {
+  enum xpto; // expected-warning{{ISO C forbids forward references to 'enum' types}}
+  enum xpto; // expected-warning{{ISO C forbids forward references to 'enum' types}}
+}
+
+// <rdar://problem/6503878>
+typedef enum { X = 0 }; // expected-warning{{typedef requires a name}}
+
+
+enum NotYetComplete { // expected-note{{definition of 'enum NotYetComplete' is not complete until the closing '}'}}
+  NYC1 = sizeof(enum NotYetComplete) // expected-error{{invalid application of 'sizeof' to an incomplete type 'enum NotYetComplete'}}
+};
+
+/// PR3688
+struct s1 {
+  enum e1 (*bar)(void); // expected-warning{{ISO C forbids forward references to 'enum' types}}
+};
+
+enum e1 { YES, NO };
+
+static enum e1 badfunc(struct s1 *q) {
+  return q->bar();
+}
+
+
+// Make sure we don't a.k.a. anonymous enums.
+typedef enum {
+  an_enumerator = 20
+} an_enum;
+char * s = (an_enum) an_enumerator; // expected-warning {{incompatible integer to pointer conversion initializing 'char *' with an expression of type 'an_enum'}}
+
+// PR4515
+enum PR4515 {PR4515a=1u,PR4515b=(PR4515a-2)/2};
+int CheckPR4515[PR4515b==0?1:-1];
diff --git a/test/Sema/expr-address-of.c b/test/Sema/expr-address-of.c
new file mode 100644
index 0000000..8f9f795
--- /dev/null
+++ b/test/Sema/expr-address-of.c
@@ -0,0 +1,109 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only
+struct xx { int bitf:1; };
+
+struct entry { struct xx *whatever; 
+               int value; 
+               int bitf:1; };
+void add_one(int *p) { (*p)++; }
+
+void test() {
+ register struct entry *p;
+ add_one(&p->value);
+ struct entry pvalue;
+ add_one(&p->bitf);  // expected-error {{address of bit-field requested}}
+ add_one(&pvalue.bitf); // expected-error {{address of bit-field requested}}
+ add_one(&p->whatever->bitf); // expected-error {{address of bit-field requested}}
+}
+
+void foo() {
+  register int x[10];
+  &x[10];              // expected-error {{address of register variable requested}}
+    
+  register int *y;
+  
+  int *x2 = &y; // expected-error {{address of register variable requested}}
+  int *x3 = &y[10];
+}
+
+void testVectorComponentAccess() {
+  typedef float v4sf __attribute__ ((vector_size (16)));
+  static v4sf q;
+  float* r = &q[0]; // expected-error {{address of vector element requested}}
+}
+
+typedef __attribute__(( ext_vector_type(4) ))  float float4;
+
+float *testExtVectorComponentAccess(float4 x) { 
+  return &x.w; // expected-error {{address of vector element requested}}
+}
+
+void f0() {
+  register int *x0;
+  int *_dummy0 = &(*x0);
+
+  register int *x1;
+  int *_dummy1 = &(*(x1 + 1));
+}
+
+// FIXME: The checks for this function are broken; we should error
+// on promoting a register array to a pointer! (C99 6.3.2.1p3)
+void f1() {
+  register int x0[10];
+  int *_dummy00 = x0; // fixme-error {{address of register variable requested}}
+  int *_dummy01 = &(*x0); // fixme-error {{address of register variable requested}}
+
+  register int x1[10];
+  int *_dummy1 = &(*(x1 + 1)); // fixme-error {{address of register variable requested}}
+
+  register int *x2;
+  int *_dummy2 = &(*(x2 + 1));
+
+  register int x3[10][10][10];
+  int (*_dummy3)[10] = &x3[0][0]; // expected-error {{address of register variable requested}}
+
+  register struct { int f0[10]; } x4;
+  int *_dummy4 = &x4.f0[2]; // expected-error {{address of register variable requested}}
+}
+
+void f2() {
+  register int *y;
+  
+  int *_dummy0 = &y; // expected-error {{address of register variable requested}}
+  int *_dummy1 = &y[10];
+}
+
+void f3() {
+  extern void f4();
+  void (*_dummy0)() = &****f4;
+}
+
+void f4() {
+  register _Complex int x;
+  
+  int *_dummy0 = &__real__ x; // expected-error {{address of register variable requested}}
+}
+
+void f5() {
+  register int arr[2];
+
+  /* This is just here because if we happened to support this as an
+     lvalue we would need to give a warning. Note that gcc warns about
+     this as a register before it warns about it as an invalid
+     lvalue. */
+  int *_dummy0 = &(int*) arr; // expected-error {{address expression must be an lvalue or a function designator}}
+  int *_dummy1 = &(arr + 1); // expected-error {{address expression must be an lvalue or a function designator}}
+}
+
+void f6(register int x) {
+  int * dummy0 = &x; // expected-error {{address of register variable requested}}
+}
+
+char* f7() {
+  register struct {char* x;} t1 = {"Hello"};
+  char* dummy1 = &(t1.x[0]);
+
+  struct {int a : 10;} t2;
+  int* dummy2 = &(t2.a); // expected-error {{address of bit-field requested}}
+
+  void* t3 = &(*(void*)0);
+}
diff --git a/test/Sema/expr-comma-c89.c b/test/Sema/expr-comma-c89.c
new file mode 100644
index 0000000..d0883ba
--- /dev/null
+++ b/test/Sema/expr-comma-c89.c
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify -std=c99
+// rdar://6095180
+
+struct s { char c[17]; };
+extern struct s foo(void);
+
+struct s a, b, c;
+
+int A[sizeof((foo().c)) == 17 ? 1 : -1];
+int B[sizeof((a.c)) == 17 ? 1 : -1];
+
+
+// comma does array/function promotion in c99.
+int X[sizeof(0, (foo().c)) == sizeof(char*) ? 1 : -1];
+int Y[sizeof(0, (a,b).c) == sizeof(char*) ? 1 : -1];
+int Z[sizeof(0, (a=b).c) == sizeof(char*) ? 1 : -1];
+
diff --git a/test/Sema/expr-comma.c b/test/Sema/expr-comma.c
new file mode 100644
index 0000000..d3e4020
--- /dev/null
+++ b/test/Sema/expr-comma.c
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify -std=c89
+// rdar://6095180
+
+struct s { char c[17]; };
+extern struct s foo(void);
+
+struct s a, b, c;
+
+int A[sizeof((foo().c)) == 17 ? 1 : -1];
+int B[sizeof((a.c)) == 17 ? 1 : -1];
+
+
+// comma does not promote array/function in c90 unless they are lvalues.
+int W[sizeof(0, a.c) == sizeof(char*) ? 1 : -1];
+int X[sizeof(0, (foo().c)) == 17 ? 1 : -1];
+int Y[sizeof(0, (a,b).c) == 17 ? 1 : -1];
+int Z[sizeof(0, (a=b).c) == 17 ? 1 : -1];
diff --git a/test/Sema/exprs.c b/test/Sema/exprs.c
new file mode 100644
index 0000000..dbb6e80
--- /dev/null
+++ b/test/Sema/exprs.c
@@ -0,0 +1,136 @@
+// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only
+
+// PR1966
+_Complex double test1() {
+  return __extension__ 1.0if;
+}
+
+_Complex double test2() {
+  return 1.0if;    // expected-warning {{imaginary constants are an extension}}
+}
+
+// rdar://6097308
+void test3() {
+  int x;
+  (__extension__ x) = 10;
+}
+
+// rdar://6162726
+void test4() {
+      static int var;
+      var =+ 5;  // expected-warning {{use of unary operator that may be intended as compound assignment (+=)}}
+      var =- 5;  // expected-warning {{use of unary operator that may be intended as compound assignment (-=)}}
+      var = +5;  // no warning when space between the = and +.
+      var = -5;
+
+      var =+5;  // no warning when the subexpr of the unary op has no space before it.
+      var =-5;
+  
+#define FIVE 5
+      var=-FIVE;  // no warning with macros.
+      var=-FIVE;
+}
+
+// rdar://6319320
+void test5(int *X, float *P) {
+  (float*)X = P;   // expected-error {{assignment to cast is illegal, lvalue casts are not supported}}
+#define FOO ((float*) X)
+  FOO = P;   // expected-error {{assignment to cast is illegal, lvalue casts are not supported}}
+}
+
+void test6() {
+  int X;
+  X();  // expected-error {{called object type 'int' is not a function or function pointer}}
+}
+
+void test7(int *P, _Complex float Gamma) {
+   P = (P-42) + Gamma*4;  // expected-error {{invalid operands to binary expression ('int *' and '_Complex float')}}
+}
+
+
+// rdar://6095061
+int test8(void) {
+  int i;
+  __builtin_choose_expr (0, 42, i) = 10;
+  return i;
+}
+
+
+// PR3386
+struct f { int x : 4;  float y[]; };
+int test9(struct f *P) {
+  int R;
+  R = __alignof(P->x);  // expected-error {{invalid application of '__alignof' to bit-field}}
+  R = __alignof(P->y);   // ok.
+  R = sizeof(P->x); // expected-error {{invalid application of 'sizeof' to bit-field}}
+  return R;
+}
+
+// PR3562
+void test10(int n,...) {
+  struct S {
+    double          a[n];  // expected-error {{fields must have a constant size}}
+  }               s;
+  double x = s.a[0];  // should not get another error here.
+}
+
+
+#define MYMAX(A,B)    __extension__ ({ __typeof__(A) __a = (A); __typeof__(B) __b = (B); __a < __b ? __b : __a; })
+
+struct mystruct {int A; };
+void test11(struct mystruct P, float F) {
+  MYMAX(P, F);  // expected-error {{invalid operands to binary expression ('typeof (P)' (aka 'struct mystruct') and 'typeof (F)' (aka 'float'))}}
+}
+
+// PR3753
+int test12(const char *X) {
+  return X == "foo";  // expected-warning {{comparison against a string literal is unspecified (use strncmp instead)}}
+}
+
+int test12b(const char *X) {
+  return sizeof(X == "foo"); // no-warning
+}
+
+// rdar://6719156
+void test13(
+            void (^P)()) { // expected-error {{blocks support disabled - compile with -fblocks}}
+  P();
+  P = ^(){}; // expected-error {{blocks support disabled - compile with -fblocks}}
+}
+
+void test14() {
+  typedef long long __m64 __attribute__((__vector_size__(8)));
+  typedef short __v4hi __attribute__((__vector_size__(8)));
+
+  // Ok.
+  __v4hi a;
+  __m64 mask = (__m64)((__v4hi)a > (__v4hi)a);
+}
+
+
+// PR5242
+typedef unsigned long *test15_t;
+
+test15_t test15(void) {
+  return (test15_t)0 + (test15_t)0;  // expected-error {{invalid operands to binary expression ('test15_t' (aka 'unsigned long *') and 'test15_t')}}
+}
+
+// rdar://7446395
+void test16(float x) { x == ((void*) 0); }  // expected-error {{invalid operands to binary expression}}
+
+// PR6004
+void test17(int x) {
+  x = x / 0;  // expected-warning {{division by zero is undefined}}
+  x = x % 0;  // expected-warning {{remainder by zero is undefined}}
+  x /= 0;  // expected-warning {{division by zero is undefined}}
+  x %= 0;  // expected-warning {{remainder by zero is undefined}}
+  
+  x = sizeof(x/0);  // no warning.
+}
+
+// PR6501
+void test18_a(int a);
+void test18(int b) {
+  test18_a(b, b); // expected-error {{too many arguments to function call, expected 1, have 2}}
+  test18_a(); // expected-error {{too few arguments to function call, expected 1, have 0}}
+}
diff --git a/test/Sema/ext_vector_casts.c b/test/Sema/ext_vector_casts.c
new file mode 100644
index 0000000..d297623
--- /dev/null
+++ b/test/Sema/ext_vector_casts.c
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+typedef __attribute__(( ext_vector_type(2) )) float float2;
+typedef __attribute__(( ext_vector_type(4) )) int int4;
+typedef __attribute__(( ext_vector_type(8) )) short short8;
+typedef __attribute__(( ext_vector_type(4) )) float float4;
+typedef float t3 __attribute__ ((vector_size (16)));
+
+static void test() {
+    float2 vec2;
+    float4 vec4, vec4_2;
+    int4 ivec4;
+    short8 ish8;
+    t3 vec4_3;
+    int *ptr;
+    int i;
+    
+    vec4 = 5.0f;
+    vec4 = (float4)5.0f;
+    vec4 = (float4)5;
+    vec4 = (float4)vec4_3;
+    
+    ivec4 = (int4)5.0f;
+    ivec4 = (int4)5;
+    ivec4 = (int4)vec4_3;
+    
+    i = (int)ivec4; // expected-error {{invalid conversion between vector type 'int4' and integer type 'int' of different size}}
+    i = ivec4; // expected-error {{assigning to 'int' from incompatible type 'int4'}}
+    
+    ivec4 = (int4)ptr; // expected-error {{invalid conversion between vector type 'int4' and scalar type 'int *'}}
+    
+    vec4 = (float4)vec2; // expected-error {{invalid conversion between ext-vector type 'float4' and 'float2'}}
+    
+    ish8 += 5; // expected-error {{can't convert between vector values of different size ('short8' and 'int')}}
+    ish8 += (short)5;
+    ivec4 *= 5;
+     vec4 /= 5.2f;
+     vec4 %= 4; // expected-error {{invalid operands to binary expression ('float4' and 'int')}}
+    ivec4 %= 4;
+    ivec4 += vec4; // expected-error {{can't convert between vector values of different size ('float4' and 'int4')}}
+    ivec4 += (int4)vec4;
+    ivec4 -= ivec4;
+    ivec4 |= ivec4;
+    ivec4 += ptr; // expected-error {{can't convert between vector values of different size ('int4' and 'int *')}}
+}
diff --git a/test/Sema/ext_vector_components.c b/test/Sema/ext_vector_components.c
new file mode 100644
index 0000000..7d3d52a
--- /dev/null
+++ b/test/Sema/ext_vector_components.c
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+typedef __attribute__(( ext_vector_type(2) )) float float2;
+typedef __attribute__(( ext_vector_type(3) )) float float3;
+typedef __attribute__(( ext_vector_type(4) )) float float4;
+typedef __attribute__(( ext_vector_type(16) )) float float16;
+
+static float4 vec4_0 = (float4)0.5f;
+
+static void test() {
+    float2 vec2, vec2_2;
+    float3 vec3;
+    float4 vec4, vec4_2, *vec4p;
+    float16 vec16;
+    float f;
+
+    vec2.z; // expected-error {{vector component access exceeds type 'float2'}}
+    vec2.xyzw; // expected-error {{vector component access exceeds type 'float2'}}
+    vec4.xyzw; // expected-warning {{expression result unused}}
+    vec4.xyzc; // expected-error {{illegal vector component name 'c'}}
+    vec4.s01z; // expected-error {{illegal vector component name 'z'}}
+    vec2 = vec4.s01; // legal, shorten
+    vec2 = vec4.S01; // legal, shorten
+    
+    vec3 = vec4.xyz; // legal, shorten
+    f = vec2.x; // legal, shorten
+    f = vec4.xy.x; // legal, shorten
+
+    vec4_2.xyzx = vec4.xyzw; // expected-error {{vector is not assignable (contains duplicate components)}}
+    vec4_2.xyzz = vec4.xyzw; // expected-error {{vector is not assignable (contains duplicate components)}}
+    vec4_2.xyyw = vec4.xyzw; // expected-error {{vector is not assignable (contains duplicate components)}}
+    vec2.x = f;
+    vec2.xx = vec2_2.xy; // expected-error {{vector is not assignable (contains duplicate components)}}
+    vec2.yx = vec2_2.xy;
+    vec4 = (float4){ 1,2,3,4 };
+    vec4.xy.w; // expected-error {{vector component access exceeds type 'float2'}}
+    vec4.s06; // expected-error {{vector component access exceeds type 'float4'}}
+    vec4.x = vec16.sf;
+    vec4.x = vec16.sF;
+  
+    vec4p->yz = vec4p->xy;
+}
+
+float2 lo(float3 x) { return x.lo; }
+float2 hi(float3 x) { return x.hi; }
+float2 ev(float3 x) { return x.even; }
+float2 od(float3 x) { return x.odd; }
diff --git a/test/Sema/flexible-array-init.c b/test/Sema/flexible-array-init.c
new file mode 100644
index 0000000..e03881c
--- /dev/null
+++ b/test/Sema/flexible-array-init.c
@@ -0,0 +1,58 @@
+// RUN: %clang_cc1 -fsyntax-only -pedantic -verify %s
+struct one {
+  int a;
+  int values[]; // expected-note 3{{initialized flexible array member 'values' is here}}
+} x = {5, {1, 2, 3}}; // expected-warning{{flexible array initialization is a GNU extension}}
+
+struct one x2 = { 5, 1, 2, 3 }; // expected-warning{{flexible array initialization is a GNU extension}}
+
+void test() {
+  struct one x3 = {5, {1, 2, 3}}; // expected-warning{{flexible array initialization is a GNU extension}}
+}
+
+struct foo { 
+  int x; 
+  int y[]; // expected-note 6 {{initialized flexible array member 'y' is here}}
+}; 
+struct bar { struct foo z; }; // expected-warning {{'z' may not be nested in a struct due to flexible array member}}
+     
+struct foo a = { 1, { 2, 3, 4 } };        // expected-warning{{flexible array initialization is a GNU extension}}
+struct bar b = { { 1, { 2, 3, 4 } } };    // expected-error{{non-empty initialization of flexible array member inside subobject}}
+struct bar c = { { 1, { } } };            // // expected-warning{{flexible array initialization is a GNU extension}} \
+              // expected-warning{{use of GNU empty initializer extension}} \
+              // expected-warning{{zero size arrays are an extension}}
+struct foo d[1] = { { 1, { 2, 3, 4 } } };  // expected-warning{{'struct foo' may not be used as an array element due to flexible array member}} \
+              // expected-error{{non-empty initialization of flexible array member inside subobject}}
+
+struct foo desig_foo = { .y = {2, 3, 4} };
+struct bar desig_bar = { .z.y = { } }; // expected-warning{{use of GNU empty initializer extension}} \
+  // expected-warning{{zero size arrays are an extension}}
+struct bar desig_bar2 = { .z.y = { 2, 3, 4} }; // expected-error{{non-empty initialization of flexible array member inside subobject}}
+struct foo design_foo2 = { .y = 2 }; // expected-error{{flexible array requires brace-enclosed initializer}}
+
+struct point {
+  int x, y;
+};
+
+struct polygon {
+  int numpoints;
+  struct point points[]; // expected-note{{initialized flexible array member 'points' is here}}
+};
+struct polygon poly = { 
+  .points[2] = { 1, 2} }; // expected-error{{designator into flexible array member subobject}}
+
+// PR3540
+struct X {
+  int a;
+  int b;
+  char data[];
+};
+
+struct Y {
+  int a:4;
+  int b:4;
+  int c;
+  int d;
+  int e;
+  struct X xs[]; // expected-warning{{'struct X' may not be used as an array element due to flexible array member}}
+};
diff --git a/test/Sema/floating-point-compare.c b/test/Sema/floating-point-compare.c
new file mode 100644
index 0000000..60f971c
--- /dev/null
+++ b/test/Sema/floating-point-compare.c
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -fsyntax-only -Wfloat-equal -verify %s
+
+int f1(float x, float y) {
+  return x == y; // expected-warning {{comparing floating point with ==}}
+} 
+
+int f2(float x, float y) {
+  return x != y; // expected-warning {{comparing floating point with ==}}
+}
+
+int f3(float x) {
+  return x == x; // no-warning
+}
+
+int f4(float x) {
+  return x == 0.0; // no-warning {{comparing}}
+}
+
+int f5(float x) {
+  return x == __builtin_inf(); // no-warning
+}
+
+int f7(float x) {
+  return x == 3.14159; // expected-warning {{comparing}}
+}
diff --git a/test/Sema/for.c b/test/Sema/for.c
new file mode 100644
index 0000000..b998f4b
--- /dev/null
+++ b/test/Sema/for.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// Check C99 6.8.5p3
+void b1 (void) { for (void (*f) (void);;); }
+void b2 (void) { for (void f (void);;); }   // expected-error {{declaration of non-local variable}}
+void b3 (void) { for (static int f;;); }    // expected-error {{declaration of non-local variable}}
+void b4 (void) { for (typedef int f;;); }   // expected-error {{declaration of non-local variable}}
diff --git a/test/Sema/format-string-percentm.c b/test/Sema/format-string-percentm.c
new file mode 100644
index 0000000..1ffc439
--- /dev/null
+++ b/test/Sema/format-string-percentm.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -triple i686-pc-linux-gnu
+
+// PR 4142 - support glibc extension to printf: '%m' (which prints strerror(errno)).
+int printf(char const*,...);
+void percentm(void) {
+  printf("%m");
+}
diff --git a/test/Sema/format-strings.c b/test/Sema/format-strings.c
new file mode 100644
index 0000000..bdc2bb0
--- /dev/null
+++ b/test/Sema/format-strings.c
@@ -0,0 +1,253 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wformat-nonliteral %s
+
+#include <stdarg.h>
+typedef __typeof(sizeof(int)) size_t;
+typedef struct _FILE FILE;
+int fprintf(FILE *, const char *restrict, ...);
+int printf(const char *restrict, ...); // expected-note{{passing argument to parameter here}}
+int snprintf(char *restrict, size_t, const char *restrict, ...);
+int sprintf(char *restrict, const char *restrict, ...);
+int vasprintf(char **, const char *, va_list);
+int asprintf(char **, const char *, ...);
+int vfprintf(FILE *, const char *restrict, va_list);
+int vprintf(const char *restrict, va_list);
+int vsnprintf(char *, size_t, const char *, va_list);
+int vsprintf(char *restrict, const char *restrict, va_list); // expected-note{{passing argument to parameter here}}
+
+char * global_fmt;
+
+void check_string_literal( FILE* fp, const char* s, char *buf, ... ) {
+
+  char * b;
+  va_list ap;
+  va_start(ap,buf);
+
+  printf(s); // expected-warning {{format string is not a string literal}}
+  vprintf(s,ap); // // no-warning
+  fprintf(fp,s); // expected-warning {{format string is not a string literal}}
+  vfprintf(fp,s,ap); // no-warning
+  asprintf(&b,s); // expected-warning {{format string is not a string lit}}
+  vasprintf(&b,s,ap); // no-warning
+  sprintf(buf,s); // expected-warning {{format string is not a string literal}}
+  snprintf(buf,2,s); // expected-warning {{format string is not a string lit}}
+  __builtin___sprintf_chk(buf,0,-1,s); // expected-warning {{format string is not a string literal}}
+  __builtin___snprintf_chk(buf,2,0,-1,s); // expected-warning {{format string is not a string lit}}
+  vsprintf(buf,s,ap); // no-warning
+  vsnprintf(buf,2,s,ap); // no-warning
+  vsnprintf(buf,2,global_fmt,ap); // expected-warning {{format string is not a string literal}}
+  __builtin___vsnprintf_chk(buf,2,0,-1,s,ap); // no-warning
+  __builtin___vsnprintf_chk(buf,2,0,-1,global_fmt,ap); // expected-warning {{format string is not a string literal}}
+
+  // rdar://6079877
+  printf("abc"
+         "%*d", 1, 1); // no-warning
+  printf("abc\
+def"
+         "%*d", 1, 1); // no-warning
+         
+  // <rdar://problem/6079850>, allow 'unsigned' (instead of 'int') to be used for both
+  // the field width and precision.  This deviates from C99, but is reasonably safe
+  // and is also accepted by GCC.
+  printf("%*d", (unsigned) 1, 1); // no-warning  
+}
+
+void check_conditional_literal(const char* s, int i) {
+  printf(i == 1 ? "yes" : "no"); // no-warning
+  printf(i == 0 ? (i == 1 ? "yes" : "no") : "dont know"); // no-warning
+  printf(i == 0 ? (i == 1 ? s : "no") : "dont know"); // expected-warning{{format string is not a string literal}}
+  printf("yes" ?: "no %d", 1); // expected-warning{{data argument not used by format string}}
+}
+
+void check_writeback_specifier()
+{
+  int x;
+  char *b;
+
+  printf("%n",&x); // expected-warning {{'%n' in format string discouraged}}
+  sprintf(b,"%d%%%n",1, &x); // expected-warning {{'%n' in format string dis}}
+}
+
+void check_invalid_specifier(FILE* fp, char *buf)
+{
+  printf("%s%lb%d","unix",10,20); // expected-warning {{invalid conversion specifier 'b'}}
+  fprintf(fp,"%%%l"); // expected-warning {{incomplete format specifier}}
+  sprintf(buf,"%%%%%ld%d%d", 1, 2, 3); // expected-warning{{conversion specifies type 'long' but the argument has type 'int'}}
+  snprintf(buf, 2, "%%%%%ld%;%d", 1, 2, 3); // expected-warning{{conversion specifies type 'long' but the argument has type 'int'}} expected-warning {{invalid conversion specifier ';'}}
+}
+
+void check_null_char_string(char* b)
+{
+  printf("\0this is bogus%d",1); // expected-warning {{string contains '\0'}}
+  snprintf(b,10,"%%%%%d\0%d",1,2); // expected-warning {{string contains '\0'}}
+  printf("%\0d",1); // expected-warning {{string contains '\0'}}
+}
+
+void check_empty_format_string(char* buf, ...)
+{
+  va_list ap;
+  va_start(ap,buf);
+  vprintf("",ap); // expected-warning {{format string is empty}}
+  sprintf(buf,""); // expected-warning {{format string is empty}}
+}
+
+void check_wide_string(char* b, ...)
+{
+  va_list ap;
+  va_start(ap,b);
+
+  printf(L"foo %d",2); // expected-warning {{incompatible pointer types}}, expected-warning {{should not be a wide string}}
+  vsprintf(b,L"bar %d",ap); // expected-warning {{incompatible pointer types}}, expected-warning {{should not be a wide string}}
+}
+
+void check_asterisk_precision_width(int x) {
+  printf("%*d"); // expected-warning {{'*' specified field width is missing a matching 'int' argument}}
+  printf("%.*d"); // expected-warning {{'.*' specified field precision is missing a matching 'int' argument}}
+  printf("%*d",12,x); // no-warning
+  printf("%*d","foo",x); // expected-warning {{field width should have type 'int', but argument has type 'char *'}}
+  printf("%.*d","foo",x); // expected-warning {{field precision should have type 'int', but argument has type 'char *'}}
+}
+
+void __attribute__((format(printf,1,3))) myprintf(const char*, int blah, ...);
+
+void test_myprintf() {
+  myprintf("%d", 17, 18); // okay
+}
+
+void test_constant_bindings(void) {
+  const char * const s1 = "hello";
+  const char s2[] = "hello";
+  const char *s3 = "hello";
+  char * const s4 = "hello";
+  extern const char s5[];
+  
+  printf(s1); // no-warning
+  printf(s2); // no-warning
+  printf(s3); // expected-warning{{not a string literal}}
+  printf(s4); // expected-warning{{not a string literal}}
+  printf(s5); // expected-warning{{not a string literal}}
+}
+
+
+// Test what happens when -Wformat-security only.
+#pragma GCC diagnostic ignored "-Wformat-nonliteral"
+#pragma GCC diagnostic warning "-Wformat-security"
+
+void test9(char *P) {
+  int x;
+  printf(P);   // expected-warning {{format string is not a string literal (potentially insecure)}}
+  printf(P, 42);
+  printf("%n", &x); // expected-warning {{use of '%n' in format string discouraged }}
+}
+
+void torture(va_list v8) {
+  vprintf ("%*.*d", v8);  // no-warning
+  
+}
+
+void test10(int x, float f, int i, long long lli) {
+  printf("%s"); // expected-warning{{more '%' conversions than data arguments}}
+  printf("%@", 12); // expected-warning{{invalid conversion specifier '@'}}
+  printf("\0"); // expected-warning{{format string contains '\0' within the string body}}
+  printf("xs\0"); // expected-warning{{format string contains '\0' within the string body}}
+  printf("%*d\n"); // expected-warning{{'*' specified field width is missing a matching 'int' argument}}
+  printf("%*.*d\n", x); // expected-warning{{'.*' specified field precision is missing a matching 'int' argument}}
+  printf("%*d\n", f, x); // expected-warning{{field width should have type 'int', but argument has type 'double'}}
+  printf("%*.*d\n", x, f, x); // expected-warning{{field precision should have type 'int', but argument has type 'double'}}
+  printf("%**\n"); // expected-warning{{invalid conversion specifier '*'}}
+  printf("%n", &i); // expected-warning{{use of '%n' in format string discouraged (potentially insecure)}}
+  printf("%d%d\n", x); // expected-warning{{more '%' conversions than data arguments}}
+  printf("%d\n", x, x); // expected-warning{{data argument not used by format string}}
+  printf("%W%d%Z\n", x, x, x); // expected-warning{{invalid conversion specifier 'W'}} expected-warning{{invalid conversion specifier 'Z'}}
+  printf("%"); // expected-warning{{incomplete format specifier}}
+  printf("%.d", x); // no-warning
+  printf("%.", x);  // expected-warning{{incomplete format specifier}}
+  printf("%f", 4); // expected-warning{{conversion specifies type 'double' but the argument has type 'int'}}
+  printf("%qd", lli);
+  printf("hhX %hhX", (unsigned char)10); // no-warning
+  printf("llX %llX", (long long) 10); // no-warning
+  // This is fine, because there is an implicit conversion to an int.
+  printf("%d", (unsigned char) 10); // no-warning
+  printf("%d", (long long) 10); // expected-warning{{conversion specifies type 'int' but the argument has type 'long long'}}
+  printf("%Lf\n", (long double) 1.0); // no-warning
+  printf("%f\n", (long double) 1.0); // expected-warning{{conversion specifies type 'double' but the argument has type 'long double'}}
+  // The man page says that a zero precision is okay.
+  printf("%.0Lf", (long double) 1.0); // no-warning
+} 
+
+void test11(void *p, char *s) {
+  printf("%p", p); // no-warning
+  printf("%.4p", p); // expected-warning{{precision used in 'p' conversion specifier (where it has no meaning)}}
+  printf("%+p", p); // expected-warning{{flag '+' results in undefined behavior in 'p' conversion specifier}}
+  printf("% p", p); // expected-warning{{flag ' ' results in undefined behavior in 'p' conversion specifier}}
+  printf("%0p", p); // expected-warning{{flag '0' results in undefined behavior in 'p' conversion specifier}}
+  printf("%s", s); // no-warning
+  printf("%+s", p); // expected-warning{{flag '+' results in undefined behavior in 's' conversion specifier}}
+  printf("% s", p); // expected-warning{{flag ' ' results in undefined behavior in 's' conversion specifier}}
+  printf("%0s", p); // expected-warning{{flag '0' results in undefined behavior in 's' conversion specifier}}
+}
+
+void test12(char *b) {
+  unsigned char buf[4];
+  printf ("%.4s\n", buf); // no-warning
+  printf ("%.4s\n", &buf); // expected-warning{{conversion specifies type 'char *' but the argument has type 'unsigned char (*)[4]'}}
+  
+  // Verify that we are checking asprintf
+  asprintf(&b, "%d", "asprintf"); // expected-warning{{conversion specifies type 'int' but the argument has type 'char *'}}
+}
+
+typedef struct __aslclient *aslclient;
+typedef struct __aslmsg *aslmsg;
+int asl_log(aslclient asl, aslmsg msg, int level, const char *format, ...) __attribute__((__format__ (__printf__, 4, 5)));
+void test_asl(aslclient asl) {
+  // Test case from <rdar://problem/7341605>.
+  asl_log(asl, 0, 3, "Error: %m"); // no-warning
+  asl_log(asl, 0, 3, "Error: %W"); // expected-warning{{invalid conversion specifier 'W'}}
+}
+
+// <rdar://problem/7595366>
+typedef enum { A } int_t;
+void f0(int_t x) { printf("%d\n", x); }
+
+// Unicode test cases.  These are possibly specific to Mac OS X.  If so, they should
+// eventually be moved into a separate test.
+typedef __WCHAR_TYPE__ wchar_t;
+
+void test_unicode_conversions(wchar_t *s) {
+  printf("%S", s); // no-warning
+  printf("%s", s); // expected-warning{{conversion specifies type 'char *' but the argument has type 'wchar_t *'}}
+  printf("%C", s[0]); // no-warning
+  printf("%c", s[0]);
+  // FIXME: This test reports inconsistent results. On Windows, '%C' expects
+  // 'unsigned short'.
+  // printf("%C", 10);
+  // FIXME: we report the expected type as 'int*' instead of 'wchar_t*'
+  printf("%S", "hello"); // expected-warning{{but the argument has type 'char *'}}
+}
+
+// Mac OS X supports positional arguments in format strings.
+// This is an IEEE extension (IEEE Std 1003.1).
+// FIXME: This is probably not portable everywhere.
+void test_positional_arguments() {
+  printf("%0$", (int)2); // expected-warning{{position arguments in format strings start counting at 1 (not 0)}}
+  printf("%1$*0$d", (int) 2); // expected-warning{{position arguments in format strings start counting at 1 (not 0)}}
+  printf("%1$d", (int) 2); // no-warning
+  printf("%1$d", (int) 2, 2); // expected-warning{{data argument not used by format string}}
+  printf("%1$d%1$f", (int) 2); // expected-warning{{conversion specifies type 'double' but the argument has type 'int'}}
+  printf("%1$2.2d", (int) 2); // no-warning
+  printf("%2$*1$.2d", (int) 2, (int) 3); // no-warning
+  printf("%2$*8$d", (int) 2, (int) 3); // expected-warning{{specified field width is missing a matching 'int' argument}}
+}
+
+// PR 6697 - Handle format strings where the data argument is not adjacent to the format string
+void myprintf_PR_6697(const char *format, int x, ...) __attribute__((__format__(printf,1, 3)));
+void test_pr_6697() {
+  myprintf_PR_6697("%s\n", 1, "foo"); // no-warning
+  myprintf_PR_6697("%s\n", 1, (int)0); // expected-warning{{conversion specifies type 'char *' but the argument has type 'int'}}
+  // FIXME: Not everything should clearly support positional arguments,
+  // but we need a way to identify those cases.
+  myprintf_PR_6697("%1$s\n", 1, "foo"); // no-warning
+  myprintf_PR_6697("%2$s\n", 1, "foo"); // expected-warning{{data argument position '2' exceeds the number of data arguments (1)}}
+  myprintf_PR_6697("%18$s\n", 1, "foo"); // expected-warning{{data argument position '18' exceeds the number of data arguments (1)}}
+  myprintf_PR_6697("%1$s\n", 1, (int) 0); // expected-warning{{conversion specifies type 'char *' but the argument has type 'int'}}
+}
+
diff --git a/test/Sema/freemain.c b/test/Sema/freemain.c
new file mode 100644
index 0000000..eed644d
--- /dev/null
+++ b/test/Sema/freemain.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -ffreestanding %s
+
+// Tests that -ffreestanding disables all special treatment of main().
+
+void* allocate(long size);
+
+void* main(void* context, long size) {
+  if (context) return allocate(size);
+} // expected-warning {{control may reach end of non-void function}}
diff --git a/test/Sema/function-ptr.c b/test/Sema/function-ptr.c
new file mode 100644
index 0000000..ff85272
--- /dev/null
+++ b/test/Sema/function-ptr.c
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 %s -verify -pedantic
+typedef int unary_int_func(int arg);
+unary_int_func *func;
+
+unary_int_func *set_func(void *p) {
+ func = p; // expected-warning {{converts between void pointer and function pointer}}
+ p = func; // expected-warning {{converts between void pointer and function pointer}}
+
+ return p; // expected-warning {{converts between void pointer and function pointer}}
+}
+
diff --git a/test/Sema/function-redecl.c b/test/Sema/function-redecl.c
new file mode 100644
index 0000000..b8a64af
--- /dev/null
+++ b/test/Sema/function-redecl.c
@@ -0,0 +1,131 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// PR3588
+void g0(int, int);
+void g0(); // expected-note{{previous declaration is here}}
+
+void f0() {
+  g0(1, 2, 3); // expected-error{{too many arguments to function call}}
+}
+
+void g0(int); // expected-error{{conflicting types for 'g0'}}
+
+int g1(int, int);
+
+typedef int INT;
+
+INT g1(x, y)
+     int x;
+     int y;
+{
+  return x + y;
+}
+
+int g2(int, int); // expected-note{{previous declaration is here}}
+
+INT g2(x) // expected-error{{conflicting types for 'g2'}}
+     int x;
+{
+  return x;
+}
+
+void test() {
+  int f1;
+  {
+    void f1(double);
+    {
+      void f1(double); // expected-note{{previous declaration is here}}
+      {
+        int f1(int); // expected-error{{conflicting types for 'f1'}}
+      }
+    }
+  }
+}
+
+extern void g3(int); // expected-note{{previous declaration is here}}
+static void g3(int x) { } // expected-error{{static declaration of 'g3' follows non-static declaration}}
+
+void test2() {
+  extern int f2; // expected-note 2 {{previous definition is here}}
+  {
+    void f2(int); // expected-error{{redefinition of 'f2' as different kind of symbol}}
+  }
+
+  {
+    int f2;
+    {
+      void f2(int); // expected-error{{redefinition of 'f2' as different kind of symbol}}
+    }
+  }
+}
+
+// <rdar://problem/6127293>
+int outer1(int); // expected-note{{previous declaration is here}}
+struct outer3 { };
+int outer4(int);
+int outer5; // expected-note{{previous definition is here}}
+int *outer7(int);
+
+void outer_test() {
+  int outer1(float); // expected-error{{conflicting types for 'outer1'}}
+  int outer2(int); // expected-note{{previous declaration is here}}
+  int outer3(int); // expected-note{{previous declaration is here}}
+  int outer4(int); // expected-note{{previous declaration is here}}
+  int outer5(int); // expected-error{{redefinition of 'outer5' as different kind of symbol}}
+  int* outer6(int); // expected-note{{previous declaration is here}}
+  int *outer7(int);
+  int outer8(int);
+
+  int *ip7 = outer7(6);
+}
+
+int outer2(float); // expected-error{{conflicting types for 'outer2'}}
+int outer3(float); // expected-error{{conflicting types for 'outer3'}}
+int outer4(float); // expected-error{{conflicting types for 'outer4'}}
+
+void outer_test2(int x) {
+  int* ip = outer6(x); // expected-warning{{use of out-of-scope declaration of 'outer6'}}
+  int *ip2 = outer7(x);
+}
+
+void outer_test3() {
+  int *(*fp)(int) = outer8; // expected-error{{use of undeclared identifier 'outer8'}}
+}
+
+static float outer8(float); // okay
+
+enum e { e1, e2 };
+
+// GNU extension: prototypes and K&R function definitions
+int isroot(short x, // expected-note{{previous declaration is here}}
+           enum e); 
+
+int isroot(x, y)
+     short x; // expected-warning{{promoted type 'int' of K&R function parameter is not compatible with the parameter type 'short' declared in a previous prototype}}
+     unsigned int y;
+{
+  return x == 1;
+}
+
+// PR3817
+void *h0(unsigned a0,     ...);
+extern __typeof (h0) h1 __attribute__((__sentinel__));
+extern __typeof (h1) h1 __attribute__((__sentinel__));
+
+// PR3840
+void i0 (unsigned short a0);
+extern __typeof (i0) i1;
+extern __typeof (i1) i1;
+
+typedef int a();
+typedef int a2(int*);
+a x;
+a2 x2;
+void test_x() {
+  x(5);
+  x2(5); // expected-warning{{incompatible integer to pointer conversion passing 'int' to parameter of type 'int *'}}
+}
+
+enum e0 {}; 
+void f3(); 
+void f3(enum e0 x) {}
diff --git a/test/Sema/function.c b/test/Sema/function.c
new file mode 100644
index 0000000..9a83519
--- /dev/null
+++ b/test/Sema/function.c
@@ -0,0 +1,91 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify -pedantic
+// PR1892
+void f(double a[restrict][5]);  // should promote to restrict ptr.
+void f(double (* restrict a)[5]);
+
+int foo (__const char *__path);
+int foo(__const char *__restrict __file);
+
+void func(const char*); // expected-note {{previous declaration is here}}
+void func(char*); // expected-error{{conflicting types for 'func'}}
+
+void g(int (*)(const void **, const void **));
+void g(int (*compar)()) {
+}
+
+void h();  // expected-note {{previous declaration is here}}
+void h (const char *fmt, ...) {} // expected-error{{conflicting types for 'h'}}
+
+// PR1965
+int t5(b);          // expected-error {{parameter list without types}}
+int t6(int x, g);   // expected-warning {{type specifier missing, defaults to 'int'}}
+
+int t7(, );       // expected-error {{expected parameter declarator}} expected-error {{expected parameter declarator}}
+int t8(, int a);  // expected-error {{expected parameter declarator}}
+int t9(int a, );  // expected-error {{expected parameter declarator}}
+
+
+// PR2042
+void t10(){}
+void t11(){t10(1);} // expected-warning{{too many arguments}}
+
+// PR3208
+void t12(int) {}  // expected-error{{parameter name omitted}}
+
+// PR2790
+void t13() {
+  return 0; // expected-warning {{void function 't13' should not return a value}}
+}
+int t14() {
+  return; // expected-warning {{non-void function 't14' should return a value}}
+}
+
+// <rdar://problem/6097326>
+y(y) { return y; } // expected-warning{{parameter 'y' was not declared, defaulting to type 'int'}} \
+                   // expected-warning{{type specifier missing, defaults to 'int'}}
+
+
+// PR3137, <rdar://problem/6127293>
+extern int g0_3137(void);
+void f0_3137() {
+  int g0_3137(void);
+}
+void f1_3137() {
+  int (*fp)(void) = g0_3137;
+}
+
+void f1static() {
+  static void f2static(int); // expected-error{{function declared in block scope cannot have 'static' storage class}}
+  register void f2register(int); // expected-error{{illegal storage class on function}}
+}
+
+struct incomplete_test a(void) {} // expected-error{{incomplete result type 'struct incomplete_test' in function definition}} \
+    // expected-note{{forward declaration of 'struct incomplete_test'}}
+
+
+extern __inline
+__attribute__((__gnu_inline__))
+void gnu_inline1() {}
+
+void
+__attribute__((__gnu_inline__)) // expected-warning {{'gnu_inline' attribute requires function to be marked 'inline', attribute ignored}}
+gnu_inline2() {}
+
+
+// rdar://6802350
+inline foo_t invalid_type() {  // expected-error {{unknown type name 'foo_t'}}
+}
+
+typedef void fn_t(void);
+fn_t t17;
+
+// PR4049
+unknown_type t18(void*) {   // expected-error {{unknown type name 'unknown_type'}} expected-error{{parameter name omitted}}
+}
+
+unknown_type t19(int* P) {   // expected-error {{unknown type name 'unknown_type'}}
+  P = P+1;  // no warning.
+}
+
+// missing ',' before '...'
+void t20(int i...) { } // expected-error {{requires a comma}}
diff --git a/test/Sema/gnu89.c b/test/Sema/gnu89.c
new file mode 100644
index 0000000..fc21dcd
--- /dev/null
+++ b/test/Sema/gnu89.c
@@ -0,0 +1,3 @@
+// RUN: %clang_cc1 %s -std=gnu89 -pedantic -fsyntax-only -verify
+
+int f(int restrict);
diff --git a/test/Sema/heinous-extensions-off.c b/test/Sema/heinous-extensions-off.c
new file mode 100644
index 0000000..9b80d34
--- /dev/null
+++ b/test/Sema/heinous-extensions-off.c
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 %s -verify
+
+int foo() {
+        int a;
+        // PR3788
+        asm("nop" : : "m"((int)(a))); // expected-error {{cast in a inline asm context requiring an l-value}}
+        // PR3794
+        asm("nop" : "=r"((unsigned)a)); // expected-error {{cast in a inline asm context requiring an l-value}}
+}
+
diff --git a/test/Sema/heinous-extensions-on.c b/test/Sema/heinous-extensions-on.c
new file mode 100644
index 0000000..176f472
--- /dev/null
+++ b/test/Sema/heinous-extensions-on.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 %s -verify -fheinous-gnu-extensions
+
+void foo() {
+  int a;
+  // PR3788
+  asm("nop" : : "m"((int)(a))); // expected-warning {{cast in a inline asm context requiring an l-value}}
+  // PR3794
+  asm("nop" : "=r"((unsigned)a)); // expected-warning {{cast in a inline asm context requiring an l-value}}
+}
diff --git a/test/Sema/i-c-e.c b/test/Sema/i-c-e.c
new file mode 100644
index 0000000..97d9f43
--- /dev/null
+++ b/test/Sema/i-c-e.c
@@ -0,0 +1,67 @@
+// RUN: %clang %s -fsyntax-only -Xclang -verify -pedantic -fpascal-strings
+
+#include <stdint.h>
+#include <limits.h>
+
+int a() {int p; *(1 ? &p : (void*)(0 && (a(),1))) = 10;} // expected-error {{incomplete type 'void' is not assignable}}
+
+// rdar://6091492 - ?: with __builtin_constant_p as the operand is an i-c-e.
+int expr;
+char w[__builtin_constant_p(expr) ? expr : 1];
+
+
+// __builtin_constant_p as the condition of ?: allows arbitrary foldable
+// constants to be transmogrified into i-c-e's.
+char b[__builtin_constant_p((int)(1.0+2.0)) ? (int)(1.0+2.0) : -1];
+
+struct c {
+  int a : (  // expected-error {{expression is not an integer constant expression}}
+           __builtin_constant_p((int)(1.0+2.0)) ? (int)(1.0+
+     expr  // expected-note {{subexpression not valid in an integer constant expression}}
+           ) : -1);
+};
+
+
+
+
+void test1(int n, int* p) { *(n ? p : (void *)(7-7)) = 1; }
+void test2(int n, int* p) { *(n ? p : (void *)0) = 1; }
+
+
+
+char array[1024/(sizeof (long))];
+
+int x['\xBb' == (char) 187 ? 1: -1];
+
+// PR1992
+void func(int x)
+{
+  switch (x) {
+    case sizeof("abc"): break;
+    case sizeof("loooong"): func(4);
+    case sizeof("\ploooong"): func(4);
+  }
+}
+
+
+// rdar://4213768
+int expr;
+char y[__builtin_constant_p(expr) ? -1 : 1];
+char z[__builtin_constant_p(4) ? 1 : -1];
+
+// Comma tests
+int comma1[0?1,2:3];
+int comma2[1||(1,2)];
+int comma3[(1,2)]; // expected-warning {{size of static array must be an integer constant expression}}
+
+// Pointer + __builtin_constant_p
+char pbcp[__builtin_constant_p(4) ? (intptr_t)&expr : 0]; // expected-error {{variable length array declaration not allowed at file scope}}
+
+int illegaldiv1[1 || 1/0];  // expected-warning {{division by zero is undefined}}
+int illegaldiv2[1/0]; // expected-error {{variable length array declaration not allowed at file scope}} \
+                      // expected-warning {{division by zero is undefined}}
+int illegaldiv3[INT_MIN / -1]; // expected-error {{variable length array declaration not allowed at file scope}}
+
+int chooseexpr[__builtin_choose_expr(1, 1, expr)];
+int realop[(__real__ 4) == 4 ? 1 : -1];
+int imagop[(__imag__ 4) == 0 ? 1 : -1];
diff --git a/test/Sema/if-empty-body.c b/test/Sema/if-empty-body.c
new file mode 100644
index 0000000..af1e62f
--- /dev/null
+++ b/test/Sema/if-empty-body.c
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+void f1(int a) {
+    if (a); // expected-warning {{if statement has empty body}}
+}
+
+void f2(int a) {
+    if (a) {}
+}
+
+void f3() {
+  if (1)
+    xx;      // expected-error {{use of undeclared identifier}}
+  return;    // no empty body warning.
+}
+
diff --git a/test/Sema/illegal-types.c b/test/Sema/illegal-types.c
new file mode 100644
index 0000000..3c59df8
--- /dev/null
+++ b/test/Sema/illegal-types.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
+
+void a (void []()); // expected-error{{'type name' declared as array of functions}}
+void b (void p[]()); // expected-error{{'p' declared as array of functions}}
+void c (int &[]); // expected-error{{'type name' declared as array of references}}
+void d (int &p[]); // expected-error{{'p' declared as array of references}}
+
diff --git a/test/Sema/implicit-builtin-decl.c b/test/Sema/implicit-builtin-decl.c
new file mode 100644
index 0000000..3d92038
--- /dev/null
+++ b/test/Sema/implicit-builtin-decl.c
@@ -0,0 +1,54 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+void f() {
+  int *ptr = malloc(sizeof(int) * 10); // expected-warning{{implicitly declaring C library function 'malloc' with type}} \
+  // expected-note{{please include the header <stdlib.h> or explicitly provide a declaration for 'malloc'}} \
+  // expected-note{{'malloc' is a builtin with type 'void *}}
+}
+
+void *alloca(__SIZE_TYPE__); // redeclaration okay
+
+int *calloc(__SIZE_TYPE__, __SIZE_TYPE__); // expected-warning{{incompatible redeclaration of library function 'calloc'}} \
+                    // expected-note{{'calloc' is a builtin with type 'void *}}
+
+
+void g(int malloc) { // okay: these aren't functions
+  int calloc = 1;
+}
+
+void h() {
+  int malloc(int); // expected-warning{{incompatible redeclaration of library function 'malloc'}}
+  int strcpy(int); // expected-warning{{incompatible redeclaration of library function 'strcpy'}} \
+  // expected-note{{'strcpy' is a builtin with type 'char *(char *, char const *)'}}
+}
+
+void f2() {
+  fprintf(0, "foo"); // expected-error{{implicit declaration of 'fprintf' requires inclusion of the header <stdio.h>}} \
+   expected-warning {{implicit declaration of function 'fprintf' is invalid in C99}}
+}
+
+// PR2892
+void __builtin_object_size(); // expected-error{{conflicting types}} \
+// expected-note{{'__builtin_object_size' is a builtin with type}}
+
+int a[10];
+
+int f0() {
+  return __builtin_object_size(&a); // expected-error {{too few arguments to function}}
+}
+
+void * realloc(void *p, int size) { // expected-warning{{incompatible redeclaration of library function 'realloc'}} \
+// expected-note{{'realloc' is a builtin with type 'void *(void *,}}
+  return p;
+}
+
+// PR3855
+void snprintf(); // expected-warning{{incompatible redeclaration of library function 'snprintf'}} \
+    // expected-note{{'snprintf' is a builtin}}
+
+int
+main(int argc, char *argv[])
+{
+  snprintf();
+}
+
+void snprintf() { }
diff --git a/test/Sema/implicit-builtin-freestanding.c b/test/Sema/implicit-builtin-freestanding.c
new file mode 100644
index 0000000..505e522
--- /dev/null
+++ b/test/Sema/implicit-builtin-freestanding.c
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -ffreestanding %s
+
+int malloc(int a) { return a; }
+
diff --git a/test/Sema/implicit-builtin-redecl.c b/test/Sema/implicit-builtin-redecl.c
new file mode 100644
index 0000000..1e520d2
--- /dev/null
+++ b/test/Sema/implicit-builtin-redecl.c
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// PR3592
+static void* malloc(int);
+static void* malloc(int size) {
+  return ((void*)0); /*do not use heap in this file*/
+}
+
+void *calloc(int, int, int); // expected-warning{{incompatible redeclaration of library function 'calloc' will be ignored}} \
+// expected-note{{'calloc' is a builtin with type 'void *}}
+
+void f1(void) { 
+  calloc(0, 0, 0);
+}
+
+void f2() {
+  int index = 1;
+}
+
+static int index;
+
+int f3() {
+  return index << 2;
+}
+
+typedef int rindex;
diff --git a/test/Sema/implicit-cast.c b/test/Sema/implicit-cast.c
new file mode 100644
index 0000000..088b195
--- /dev/null
+++ b/test/Sema/implicit-cast.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only %s
+
+static char *test1(int cf) {
+  return cf ? "abc" : 0;
+}
+static char *test2(int cf) {
+  return cf ? 0 : "abc";
+}
diff --git a/test/Sema/implicit-decl.c b/test/Sema/implicit-decl.c
new file mode 100644
index 0000000..830cde9
--- /dev/null
+++ b/test/Sema/implicit-decl.c
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only
+
+typedef int int32_t;
+typedef unsigned char Boolean;
+
+void func() {
+   int32_t *vector[16];
+   const char compDesc[16 + 1];
+   int32_t compCount = 0;
+   if (_CFCalendarDecomposeAbsoluteTimeV(compDesc, vector, compCount)) { // expected-note {{previous implicit declaration is here}} \
+         expected-warning {{implicit declaration of function '_CFCalendarDecomposeAbsoluteTimeV' is invalid in C99}}
+   }
+   return ((void *)0); // expected-warning {{void function 'func' should not return a value}}
+}
+Boolean _CFCalendarDecomposeAbsoluteTimeV(const char *componentDesc, int32_t **vector, int32_t count) { // expected-error{{conflicting types for '_CFCalendarDecomposeAbsoluteTimeV'}}
+ return 0;
+}
+
diff --git a/test/Sema/implicit-def.c b/test/Sema/implicit-def.c
new file mode 100644
index 0000000..6caa090
--- /dev/null
+++ b/test/Sema/implicit-def.c
@@ -0,0 +1,8 @@
+/* RUN: %clang_cc1 -fsyntax-only %s -std=c89
+ * RUN: not %clang_cc1 -fsyntax-only %s -std=c99 -pedantic-errors
+ */
+
+int A() {
+  return X();
+}
+
diff --git a/test/Sema/implicit-int.c b/test/Sema/implicit-int.c
new file mode 100644
index 0000000..1bb9a83
--- /dev/null
+++ b/test/Sema/implicit-int.c
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -fsyntax-only %s -verify -pedantic
+
+foo() { // expected-warning {{type specifier missing, defaults to 'int'}}
+  return 0;
+}
+
+y;  // expected-warning {{type specifier missing, defaults to 'int'}}
+
+// rdar://6131634
+void f((x));  // expected-warning {{type specifier missing, defaults to 'int'}}
+
+
+// PR3702
+#define PAD(ms10) { \
+    register i;     \
+}
+
+#define ILPAD() PAD((NROW - tt.tt_row) * 10) /* 1 ms per char */
+
+void
+h19_insline(n)  // expected-warning {{parameter 'n' was not declared, defaulting to type 'int'}}
+{
+  ILPAD();  // expected-warning {{type specifier missing, defaults to 'int'}}
+}
+
+struct foo {
+ __extension__ __attribute__((packed)) x : 4;
+};
+
+
+
+
diff --git a/test/Sema/incompatible-sign.c b/test/Sema/incompatible-sign.c
new file mode 100644
index 0000000..6249feb
--- /dev/null
+++ b/test/Sema/incompatible-sign.c
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only
+
+int a(int* x); // expected-note{{passing argument to parameter 'x' here}}
+int b(unsigned* y) { return a(y); } // expected-warning {{passing 'unsigned int *' to parameter of type 'int *' converts between pointers to integer types with different sign}}
+
diff --git a/test/Sema/incomplete-call.c b/test/Sema/incomplete-call.c
new file mode 100644
index 0000000..3ef578d
--- /dev/null
+++ b/test/Sema/incomplete-call.c
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct foo; // expected-note 3 {{forward declaration of 'struct foo'}}
+
+struct foo a(); // expected-note {{'a' declared here}}
+void b(struct foo);
+void c();
+
+void func() {
+  a(); // expected-error{{calling 'a' with incomplete return type 'struct foo'}}
+  b(*(struct foo*)0); // expected-error{{argument type 'struct foo' is incomplete}}
+  c(*(struct foo*)0); // expected-error{{argument type 'struct foo' is incomplete}}
+}
diff --git a/test/Sema/incomplete-decl.c b/test/Sema/incomplete-decl.c
new file mode 100644
index 0000000..e5b6d5f
--- /dev/null
+++ b/test/Sema/incomplete-decl.c
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct foo; // expected-note 5 {{forward declaration of 'struct foo'}}
+
+void b;  // expected-error {{variable has incomplete type 'void'}}
+struct foo f; // expected-error{{tentative definition has type 'struct foo' that is never completed}}
+
+static void c; // expected-error {{variable has incomplete type 'void'}}
+static struct foo g;  // expected-warning {{tentative definition of variable with internal linkage has incomplete non-array type 'struct foo'}} \
+    expected-error{{tentative definition has type 'struct foo' that is never completed}}
+
+extern void d;
+extern struct foo e;
+
+int ary[]; // expected-warning {{tentative array definition assumed to have one element}}
+struct foo bary[]; // expected-error {{array has incomplete element type 'struct foo'}}
+
+void func() {
+  int ary[]; // expected-error{{definition of variable with array type needs an explicit size or an initializer}}
+  void b; // expected-error {{variable has incomplete type 'void'}}
+  struct foo f; // expected-error {{variable has incomplete type 'struct foo'}}
+}
+
+int h[]; // expected-warning {{tentative array definition assumed to have one element}}
+int (*i)[] = &h+1; // expected-error {{arithmetic on pointer to incomplete type 'int (*)[]'}}
+
+struct bar j = {1}; // expected-error {{variable has incomplete type 'struct bar'}} \
+    expected-note {{forward declaration of 'struct bar'}}
+struct bar k;
+struct bar { int a; };
+
diff --git a/test/Sema/indirect-goto.c b/test/Sema/indirect-goto.c
new file mode 100644
index 0000000..4c1c6c3
--- /dev/null
+++ b/test/Sema/indirect-goto.c
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct c {int x;};
+int a(struct c x, long long y) {
+  void const* l1_ptr = &&l1;
+  goto *l1_ptr;
+l1:
+  goto *x; // expected-error{{incompatible type}}
+  goto *y; // expected-warning{{incompatible integer to pointer conversion}}
+}
+
diff --git a/test/Sema/init-struct-qualified.c b/test/Sema/init-struct-qualified.c
new file mode 100644
index 0000000..49ec7cc
--- /dev/null
+++ b/test/Sema/init-struct-qualified.c
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fsyntax-only -verify < %s
+typedef float CGFloat;
+typedef struct _NSPoint { CGFloat x; CGFloat y; } NSPoint;
+typedef struct _NSSize { CGFloat width; CGFloat height; } NSSize;
+typedef struct _NSRect { NSPoint origin; NSSize size; } NSRect;
+
+extern const NSPoint NSZeroPoint;
+
+extern NSSize canvasSize();
+void func() {
+   const NSRect canvasRect = { NSZeroPoint, canvasSize() };
+}
diff --git a/test/Sema/init-vector.c b/test/Sema/init-vector.c
new file mode 100644
index 0000000..f0cf32b
--- /dev/null
+++ b/test/Sema/init-vector.c
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+typedef float __attribute__((vector_size (16))) v4f_t;
+
+typedef union {
+    struct {
+        float x, y, z, w;
+    }s;
+    v4f_t v;
+} vector_t;
+
+
+vector_t foo(v4f_t p)
+{
+  vector_t v = {.v = p};
+  return v;
+}
diff --git a/test/Sema/init.c b/test/Sema/init.c
new file mode 100644
index 0000000..b9867cf
--- /dev/null
+++ b/test/Sema/init.c
@@ -0,0 +1,133 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only
+
+#include <stddef.h>
+#include <stdint.h>
+
+typedef void (* fp)(void);
+void foo(void);
+
+// PR clang/3377
+fp a[(short int)1] = { foo };
+
+int myArray[5] = {1, 2, 3, 4, 5};
+int *myPointer2 = myArray;
+int *myPointer = &(myArray[2]);
+
+
+extern int x;
+void *g = &x;
+int *h = &x;
+
+int test() {
+int a[10];
+int b[10] = a; // expected-error {{array initializer must be an initializer list}}
+int +; // expected-error {{expected identifier or '('}}
+}
+
+
+// PR2050
+struct cdiff_cmd {
+          const char *name;
+          unsigned short argc;
+          int (*handler)();
+};
+int cdiff_cmd_open();
+struct cdiff_cmd commands[] = {
+        {"OPEN", 1, &cdiff_cmd_open }
+};
+
+// PR2348
+static struct { int z; } s[2];
+int *t = &(*s).z;
+
+// PR2349
+short *a2(void)
+{
+  short int b;
+  static short *bp = &b; // expected-error {{initializer element is not a compile-time constant}}
+
+  return bp;
+}
+
+int pbool(void) {
+  typedef const _Bool cbool;
+  _Bool pbool1 = (void *) 0;
+  cbool pbool2 = &pbool;
+  return pbool2;
+}
+
+
+// rdar://5870981
+union { float f; unsigned u; } u = { 1.0f };
+
+// rdar://6156694
+int f3(int x) { return x; }
+typedef void (*vfunc)(void);
+void *bar = (vfunc) f3;
+
+// PR2747
+struct sym_reg {
+        char nc_gpreg;
+};
+int sym_fw1a_scr[] = {
+           ((int)(&((struct sym_reg *)0)->nc_gpreg)) & 0,
+           8 * ((int)(&((struct sym_reg *)0)->nc_gpreg))
+};
+
+// PR3001
+struct s1 s2 = { // expected-error {{variable has incomplete type 'struct s1'}}  \
+                 // expected-note {{forward declaration of 'struct s1'}}
+    .a = sizeof(struct s3), // expected-error {{invalid application of 'sizeof'}} \
+                            // expected-note{{forward declaration of 'struct s3'}}
+    .b = bogus // expected-error {{use of undeclared identifier 'bogus'}}
+}
+
+// PR3382
+char t[] = ("Hello");
+
+// <rdar://problem/6094855>
+typedef struct { } empty;
+
+typedef struct {
+  empty e;
+  int i2;
+} st;
+
+st st1 = { .i2 = 1 };
+
+// <rdar://problem/6096826>
+struct {
+  int a;
+  int z[2];
+} y = { .z = {} };
+
+int bbb[10];
+
+struct foo2 {
+   uintptr_t a;
+};
+
+struct foo2 bar2[] = {
+   { (intptr_t)bbb }
+};
+
+struct foo2 bar3 = { 1, 2 }; // expected-warning{{excess elements in struct initializer}}
+
+int* ptest1 = __builtin_choose_expr(1, (int*)0, (int*)0);
+
+typedef int32_t ivector4 __attribute((vector_size(16)));
+ivector4 vtest1 = 1 ? (ivector4){1} : (ivector4){1};
+ivector4 vtest2 = __builtin_choose_expr(1, (ivector4){1}, (ivector4){1});
+ivector4 vtest3 = __real__ (ivector4){1};
+ivector4 vtest4 = __imag__ (ivector4){1};
+
+uintptr_t ptrasintadd1 = (uintptr_t)&a - 4;
+uintptr_t ptrasintadd2 = (uintptr_t)&a + 4;
+uintptr_t ptrasintadd3 = 4 + (uintptr_t)&a;
+
+// PR4285
+const wchar_t widestr[] = L"asdf";
+
+// PR5447
+const double pr5447 = (0.05 < -1.0) ? -1.0 : 0.0499878;
+
diff --git a/test/Sema/inline.c b/test/Sema/inline.c
new file mode 100644
index 0000000..b4795d3
--- /dev/null
+++ b/test/Sema/inline.c
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -std=gnu89 -fsyntax-only -verify %s
+
+// Check that we don't allow illegal uses of inline
+inline int a; // expected-error{{'inline' can only appear on functions}}
+typedef inline int b; // expected-error{{'inline' can only appear on functions}}
+int d(inline int a); // expected-error{{'inline' can only appear on functions}}
+
+// PR5253
+// GNU Extension: check that we can redefine an extern inline function
+extern inline int f(int a) {return a;}
+int f(int b) {return b;} // expected-note{{previous definition is here}}
+// And now check that we can't redefine a normal function
+int f(int c) {return c;} // expected-error{{redefinition of 'f'}}
+
+// Check that we can redefine an extern inline function as a static function
+extern inline int g(int a) {return a;}
+static int g(int b) {return b;}
+
+// Check that we ensure the types of the two definitions are the same
+extern inline int h(int a) {return a;} // expected-note{{previous definition is here}}
+int h(short b) {return b;}  // expected-error{{conflicting types for 'h'}}
+
diff --git a/test/Sema/int-arith-convert.c b/test/Sema/int-arith-convert.c
new file mode 100644
index 0000000..c56ab3b
--- /dev/null
+++ b/test/Sema/int-arith-convert.c
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -triple=i686-linux-gnu -fsyntax-only -verify %s
+
+// Check types are the same through redeclaration
+unsigned long x;
+__typeof(1u+1l) x;
+
+unsigned y;
+__typeof(1+1u) y;
+__typeof(1u+1) y;
+
+long long z;
+__typeof(1ll+1u) z;
diff --git a/test/Sema/invalid-decl.c b/test/Sema/invalid-decl.c
new file mode 100644
index 0000000..a5e7ad3
--- /dev/null
+++ b/test/Sema/invalid-decl.c
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify
+
+void test() {
+    char = 4;  // expected-error {{expected identifier}}
+}
+
+
+// PR2400
+typedef xtype (*x)(void* handle); // expected-error {{function cannot return function type}} expected-warning {{type specifier missing, defaults to 'int'}} expected-warning {{type specifier missing, defaults to 'int'}}
+
+typedef void ytype();
+
+
+typedef struct _zend_module_entry zend_module_entry;
+struct _zend_module_entry {
+    ytype globals_size; // expected-error {{field 'globals_size' declared as a function}}
+};
+
+zend_module_entry openssl_module_entry = {
+    sizeof(zend_module_entry)
+};
+
diff --git a/test/Sema/invalid-init-diag.c b/test/Sema/invalid-init-diag.c
new file mode 100644
index 0000000..3e4870e
--- /dev/null
+++ b/test/Sema/invalid-init-diag.c
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only
+
+int a;
+struct {int x;} x = a; // expected-error {{with an expression of incompatible type 'int'}}
diff --git a/test/Sema/invalid-struct-init.c b/test/Sema/invalid-struct-init.c
new file mode 100644
index 0000000..a598d57
--- /dev/null
+++ b/test/Sema/invalid-struct-init.c
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only
+
+typedef struct _zend_module_entry zend_module_entry;
+struct _zend_module_entry {
+  _efree((p)); // expected-error{{type name requires a specifier or qualifier}} \
+                  expected-error{{field '_efree' declared as a function}} \
+                  expected-warning {{type specifier missing, defaults to 'int'}} \
+                  expected-warning {{type specifier missing, defaults to 'int'}}
+  
+};
+typedef struct _zend_function_entry { } zend_function_entry;
+typedef struct _zend_pcre_globals { } zend_pcre_globals;
+zend_pcre_globals pcre_globals;
+
+static void zm_globals_ctor_pcre(zend_pcre_globals *pcre_globals ) { }
+static void zm_globals_dtor_pcre(zend_pcre_globals *pcre_globals ) { }
+static void zm_info_pcre(zend_module_entry *zend_module ) { }
+static int zm_startup_pcre(int type, int module_number ) { }
+
+static int zm_shutdown_pcre(int type, int module_number ) {
+  zend_function_entry pcre_functions[] = {{ }; // expected-error{{expected '}'}} expected-note {{to match this '{'}}
+  zend_module_entry pcre_module_entry = {
+    sizeof(zend_module_entry), 20071006, 0, 0, ((void *)0), ((void *)0),    
+    "pcre",  pcre_functions,  zm_startup_pcre,  zm_shutdown_pcre,  ((void *)0),  
+    ((void *)0),  zm_info_pcre,  ((void *)0),  sizeof(zend_pcre_globals), &pcre_globals,  
+    ((void (*)(void* ))(zm_globals_ctor_pcre)),  ((void (*)(void* ))(zm_globals_dtor_pcre)),  
+    ((void *)0),  0, 0, ((void *)0), 0 
+  };
+}
diff --git a/test/Sema/knr-def-call.c b/test/Sema/knr-def-call.c
new file mode 100644
index 0000000..8ae0550
--- /dev/null
+++ b/test/Sema/knr-def-call.c
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// C DR #316, PR 3626.
+void f0(a, b, c, d) int a,b,c,d; {}
+void t0(void) { 
+  f0(1);  // expected-warning{{too few arguments}}
+}
+
+void f1(a, b) int a, b; {}
+void t1(void) { 
+  f1(1, 2, 3); // expected-warning{{too many arguments}}
+}
+
+void f2(float); // expected-note{{previous declaration is here}}
+void f2(x) float x; { } // expected-warning{{promoted type 'double' of K&R function parameter is not compatible with the parameter type 'float' declared in a previous prototype}}
+
+typedef void (*f3)(void);
+f3 t3(int b) { return b? f0 : f1; } // okay
diff --git a/test/Sema/knr-variadic-def.c b/test/Sema/knr-variadic-def.c
new file mode 100644
index 0000000..6d5d632
--- /dev/null
+++ b/test/Sema/knr-variadic-def.c
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s
+// PR4287
+
+#include <stdarg.h>
+char *foo = "test";
+int test(char*,...);
+
+int test(fmt)
+        char*fmt;
+{
+        va_list ap;
+        char*a;
+        int x;
+
+        va_start(ap,fmt);
+        a=va_arg(ap,char*);
+        x=(a!=foo);
+        va_end(ap);
+        return x;
+}
+
+void exit();
+
+int main(argc,argv)
+        int argc;char**argv;
+{
+        exit(test("",foo));
+}
+
diff --git a/test/Sema/member-reference.c b/test/Sema/member-reference.c
new file mode 100644
index 0000000..7bda143
--- /dev/null
+++ b/test/Sema/member-reference.c
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only
+
+struct simple { int i; };
+
+void f(void) {
+   struct simple s[1];
+   s->i = 1;
+}
+
+typedef int x;
+struct S {
+  int x;
+  x z;
+};
+
+void g(void) {
+  struct S s[1];
+  s->x = 1;
+  s->z = 2;
+}
diff --git a/test/Sema/merge-decls.c b/test/Sema/merge-decls.c
new file mode 100644
index 0000000..1a84d33
--- /dev/null
+++ b/test/Sema/merge-decls.c
@@ -0,0 +1,39 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only
+
+void foo(void);
+void foo(void) {} 
+void foo(void);
+void foo(void); // expected-note {{previous declaration is here}}
+
+void foo(int); // expected-error {{conflicting types for 'foo'}}
+
+int funcdef()
+{
+ return 0;
+}
+
+int funcdef();
+
+int funcdef2() { return 0; } // expected-note {{previous definition is here}}
+int funcdef2() { return 0; } // expected-error {{redefinition of 'funcdef2'}}
+
+// PR2502
+void (*f)(void);
+void (*f)() = 0;
+
+typedef __attribute__(( ext_vector_type(2) )) int Vi2;
+typedef __attribute__(( ext_vector_type(2) )) float Vf2;
+
+Vf2 g0; // expected-note {{previous definition is here}}
+Vi2 g0; // expected-error {{redefinition of 'g0'}}
+
+_Complex int g1; // expected-note {{previous definition is here}}
+_Complex float g1; // expected-error {{redefinition of 'g1'}}
+
+// rdar://6096412
+extern char i6096412[10];
+extern char i6096412[];
+void foo6096412(void) {
+  int x = sizeof(i6096412);
+}
+
diff --git a/test/Sema/missing-field-initializers.c b/test/Sema/missing-field-initializers.c
new file mode 100644
index 0000000..8281914
--- /dev/null
+++ b/test/Sema/missing-field-initializers.c
@@ -0,0 +1,50 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wmissing-field-initializers %s
+
+// This was PR4808.
+
+struct Foo { int a, b; };
+
+struct Foo foo0 = { 1 }; // expected-warning {{missing field 'b' initializer}}
+struct Foo foo1 = { .a = 1 }; // designator avoids MFI warning
+struct Foo foo2 = { .b = 1 }; // designator avoids MFI warning
+
+struct Foo bar0[] = {
+  { 1,2 },
+  { 1 },   // expected-warning {{missing field 'b' initializer}}
+  { 1,2 }
+};
+
+struct Foo bar1[] = {
+  1, 2,
+  1, 2,
+  1
+}; // expected-warning {{missing field 'b' initializer}}
+
+struct One { int a; int b; };
+struct Two { float c; float d; float e; };
+
+struct Three {
+    union {
+        struct One one;
+        struct Two two;
+    } both;
+};
+
+struct Three t0 = {
+    { .one = { 1, 2 } }
+};
+struct Three t1 = {
+    { .two = { 1.0f, 2.0f, 3.0f } }
+};
+
+struct Three data[] = {
+  { { .one = { 1, 2 } } },
+  { { .one = { 1 } } }, // expected-warning {{missing field 'b' initializer}}
+  { { .two = { 1.0f, 2.0f, 3.0f } } },
+  { { .two = { 1.0f, 2.0f } } } // expected-warning {{missing field 'e' initializer}}
+};
+
+struct { int:5; int a; int:5; int b; int:5 } noNamedImplicit[] = {
+  { 1, 2 },
+  { 1 } // expected-warning {{missing field 'b' initializer}}
+};
diff --git a/test/Sema/ms-fuzzy-asm.c b/test/Sema/ms-fuzzy-asm.c
new file mode 100644
index 0000000..250e322
--- /dev/null
+++ b/test/Sema/ms-fuzzy-asm.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 %s -verify -fms-extensions
+
+#define M __asm int 0x2c
+#define M2 int
+
+void t1(void) { M }
+void t2(void) { __asm int 0x2c }
+void t3(void) { __asm M2 0x2c } 
+void* t4(void) { __asm mov eax, fs:[0x10] }
diff --git a/test/Sema/nested-redef.c b/test/Sema/nested-redef.c
new file mode 100644
index 0000000..bbc4859
--- /dev/null
+++ b/test/Sema/nested-redef.c
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+struct X { // expected-note{{previous definition is here}}
+  struct X { } x; // expected-error{{nested redefinition of 'X'}}
+}; 
+
+struct Y { };
+void f(void) {
+  struct Y { }; // okay: this is a different Y
+}
+
+struct T;
+struct Z {
+  struct T { int x; } t;
+  struct U { int x; } u;
+};
+
+void f2(void) {
+  struct T t;
+  struct U u;
+}
+
+
diff --git a/test/Sema/offsetof.c b/test/Sema/offsetof.c
new file mode 100644
index 0000000..49d4eb4
--- /dev/null
+++ b/test/Sema/offsetof.c
@@ -0,0 +1,56 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+#define offsetof(TYPE, MEMBER) __builtin_offsetof (TYPE, MEMBER)
+
+typedef struct P { int i; float f; } PT;
+struct external_sun3_core
+{
+ unsigned c_regs; 
+
+  PT  X[100];
+  
+};
+
+void swap()
+{
+  int x;
+  x = offsetof(struct external_sun3_core, c_regs);
+  x = __builtin_offsetof(struct external_sun3_core, X[42].f);
+  
+  x = __builtin_offsetof(struct external_sun3_core, X[42].f2);  // expected-error {{no member named 'f2'}}
+  x = __builtin_offsetof(int, X[42].f2);  // expected-error {{offsetof requires struct}}
+  
+  int a[__builtin_offsetof(struct external_sun3_core, X) == 4 ? 1 : -1];
+  int b[__builtin_offsetof(struct external_sun3_core, X[42]) == 340 ? 1 : -1];
+  int c[__builtin_offsetof(struct external_sun3_core, X[42].f2) == 344 ? 1 : -1];  // expected-error {{no member named 'f2'}}
+}    
+
+extern int f();
+
+struct s1 { int a; }; 
+int v1 = offsetof (struct s1, a) == 0 ? 0 : f();
+
+struct s2 { int a; }; 
+int v2 = (int)(&((struct s2 *) 0)->a) == 0 ? 0 : f();
+
+struct s3 { int a; }; 
+int v3 = __builtin_offsetof(struct s3, a) == 0 ? 0 : f();
+
+// PR3396
+struct sockaddr_un {
+ unsigned char sun_len;
+ char sun_path[104];
+};
+int a(int len) {
+int a[__builtin_offsetof(struct sockaddr_un, sun_path[len+1])];
+}
+
+// PR4079
+union x {struct {int x;};};
+int x[__builtin_offsetof(union x, x)];
+
+// rdar://problem/7222956
+struct incomplete; // expected-note 2 {{forward declaration of 'struct incomplete'}}
+int test1[__builtin_offsetof(struct incomplete, foo)]; // expected-error {{offsetof of incomplete type 'struct incomplete'}}
+
+int test1[__builtin_offsetof(struct incomplete[10], [4].foo)]; // expected-error {{array has incomplete element type 'struct incomplete'}}
diff --git a/test/Sema/overloadable-complex.c b/test/Sema/overloadable-complex.c
new file mode 100644
index 0000000..770a972
--- /dev/null
+++ b/test/Sema/overloadable-complex.c
@@ -0,0 +1,50 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+char *foo(float) __attribute__((__overloadable__));
+
+void test_foo_1(float fv, double dv, float _Complex fc, double _Complex dc) {
+  char *cp1 = foo(fv);
+  char *cp2 = foo(dv);
+  // Note: GCC and EDG reject these two, but they are valid C99 conversions
+  char *cp3 = foo(fc);
+  char *cp4 = foo(dc);
+}
+
+int *foo(float _Complex) __attribute__((__overloadable__));
+
+void test_foo_2(float fv, double dv, float _Complex fc, double _Complex dc) {
+  char *cp1 = foo(fv);
+  char *cp2 = foo(dv);
+  int *ip = foo(fc);
+  int *lp = foo(dc);
+}
+
+long *foo(double _Complex) __attribute__((__overloadable__));
+
+void test_foo_3(float fv, double dv, float _Complex fc, double _Complex dc) {
+  char *cp1 = foo(fv);
+  char *cp2 = foo(dv);
+  int *ip = foo(fc);
+  long *lp = foo(dc);
+}
+
+char *promote_or_convert(double _Complex) __attribute__((__overloadable__));  // expected-note 2 {{candidate function}}
+int *promote_or_convert(long double _Complex) __attribute__((__overloadable__)); // expected-note 2 {{candidate function}} 
+
+void test_promote_or_convert(float f, float _Complex fc) {
+  char *cp = promote_or_convert(fc); // expected-error{{call to 'promote_or_convert' is ambiguous; candidates are:}}
+  int *ip2 = promote_or_convert(f); // expected-error{{call to 'promote_or_convert' is ambiguous; candidates are:}}
+}
+
+char *promote_or_convert2(float) __attribute__((__overloadable__));
+int *promote_or_convert2(double _Complex) __attribute__((__overloadable__));
+
+void test_promote_or_convert2(float _Complex fc) {
+  int *cp = promote_or_convert2(fc);
+}
+
+char *promote_or_convert3(int _Complex) __attribute__((__overloadable__));
+int *promote_or_convert3(long _Complex) __attribute__((__overloadable__));
+
+void test_promote_or_convert3(short _Complex sc) {
+  char *cp = promote_or_convert3(sc);
+}
diff --git a/test/Sema/overloadable.c b/test/Sema/overloadable.c
new file mode 100644
index 0000000..28c3e4c
--- /dev/null
+++ b/test/Sema/overloadable.c
@@ -0,0 +1,62 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+int var __attribute__((overloadable)); // expected-error{{'overloadable' attribute can only be applied to a function}}
+
+int *f(int) __attribute__((overloadable)); // expected-note 2{{previous overload of function is here}}
+float *f(float); // expected-error{{overloaded function 'f' must have the 'overloadable' attribute}}
+int *f(int); // expected-error{{redeclaration of 'f' must have the 'overloadable' attribute}} \
+             // expected-note{{previous declaration is here}}
+double *f(double) __attribute__((overloadable)); // okay, new
+
+void test_f(int iv, float fv, double dv) {
+  int *ip = f(iv);
+  float *fp = f(fv);
+  double *dp = f(dv);
+}
+
+int *accept_funcptr(int (*)()) __attribute__((overloadable)); //         \
+  // expected-note{{candidate function}}
+float *accept_funcptr(int (*)(int, double)) __attribute__((overloadable)); //  \
+  // expected-note{{candidate function}}
+
+void test_funcptr(int (*f1)(int, double),
+                  int (*f2)(int, float)) {
+  float *fp = accept_funcptr(f1);
+  accept_funcptr(f2); // expected-error{{no matching function for call to 'accept_funcptr'; candidates are:}}
+}
+
+struct X { int x; float y; };
+struct Y { int x; float y; };
+int* accept_struct(struct X x) __attribute__((__overloadable__));
+float* accept_struct(struct Y y) __attribute__((overloadable));
+
+void test_struct(struct X x, struct Y y) {
+  int *ip = accept_struct(x);
+  float *fp = accept_struct(y);
+}
+
+double *f(int) __attribute__((overloadable)); // expected-error{{conflicting types for 'f'}}
+
+double promote(float) __attribute__((__overloadable__)); // expected-note {{candidate}}
+double promote(double) __attribute__((__overloadable__)); // expected-note {{candidate}}
+long double promote(long double) __attribute__((__overloadable__)); // expected-note {{candidate}}
+
+void promote() __attribute__((__overloadable__)); // expected-error{{'overloadable' function 'promote' must have a prototype}}
+void promote(...) __attribute__((__overloadable__, __unavailable__)); // \
+    // expected-note{{candidate function}}
+
+void test_promote(short* sp) {
+  promote(1.0);
+  promote(sp); // expected-error{{call to unavailable function 'promote'}}
+}
+
+// PR6600
+typedef double Double;
+typedef Double DoubleVec __attribute__((vector_size(16)));
+typedef int Int;
+typedef Int IntVec __attribute__((vector_size(16)));
+double magnitude(DoubleVec) __attribute__((__overloadable__));
+double magnitude(IntVec) __attribute__((__overloadable__));
+double test_p6600(DoubleVec d) {
+  return magnitude(d) * magnitude(d);
+}
diff --git a/test/Sema/parentheses.c b/test/Sema/parentheses.c
new file mode 100644
index 0000000..e53f0eb
--- /dev/null
+++ b/test/Sema/parentheses.c
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -Wparentheses -fsyntax-only -verify %s
+// RUN: %clang_cc1 -Wparentheses -fixit %s -o - | %clang_cc1 -Wparentheses -Werror -
+
+// Test the various warnings under -Wparentheses
+void if_assign(void) {
+  int i;
+  if (i = 4) {} // expected-warning {{assignment as a condition}} \
+                // expected-note{{use '==' to turn this assignment into an equality comparison}} \
+  // expected-note{{place parentheses around the assignment to silence this warning}}
+  if ((i = 4)) {}
+}
+
+void bitwise_rel(unsigned i) {
+  (void)(i & 0x2 == 0); // expected-warning {{& has lower precedence than ==}} \
+                        // expected-note{{place parentheses around the & expression to evaluate it first}} \
+  // expected-note{{place parentheses around the == expression to silence this warning}}
+  (void)(0 == i & 0x2); // expected-warning {{& has lower precedence than ==}} \
+                        // expected-note{{place parentheses around the & expression to evaluate it first}} \
+  // expected-note{{place parentheses around the == expression to silence this warning}}
+  (void)(i & 0xff < 30); // expected-warning {{& has lower precedence than <}} \
+                        // expected-note{{place parentheses around the & expression to evaluate it first}} \
+  // expected-note{{place parentheses around the < expression to silence this warning}}
+  (void)((i & 0x2) == 0);
+  (void)(i & (0x2 == 0));
+  // Eager logical op
+  (void)(i == 1 | i == 2 | i == 3);
+  (void)(i != 1 & i != 2 & i != 3);
+}
diff --git a/test/Sema/pointer-addition.c b/test/Sema/pointer-addition.c
new file mode 100644
index 0000000..34f8bbb
--- /dev/null
+++ b/test/Sema/pointer-addition.c
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify -pedantic
+
+typedef struct S S; // expected-note 3 {{forward declaration of 'struct S'}}
+void a(S* b, void* c) {
+  void (*fp)(int) = 0;
+  b++;       // expected-error {{arithmetic on pointer to incomplete type}}
+  b += 1;    // expected-error {{arithmetic on pointer to incomplete type}}
+  c++;       // expected-warning {{use of GNU void* extension}}
+  c += 1;    // expected-warning {{use of GNU void* extension}}
+  c--;       // expected-warning {{use of GNU void* extension}}
+  c -= 1;    // expected-warning {{use of GNU void* extension}}
+  b = 1+b;   // expected-error {{arithmetic on pointer to incomplete type}}
+  /* The next couple tests are only pedantic warnings in gcc */
+  void (*d)(S*,void*) = a;
+  d += 1;    // expected-warning {{arithmetic on pointer to function type 'void (*)(S *, void *)' is a GNU extension}}
+  d++;       // expected-warning {{arithmetic on pointer to function type 'void (*)(S *, void *)' is a GNU extension}}}
+  d--;       // expected-warning {{arithmetic on pointer to function type 'void (*)(S *, void *)' is a GNU extension}}
+  d -= 1;    // expected-warning {{arithmetic on pointer to function type 'void (*)(S *, void *)' is a GNU extension}}
+}
diff --git a/test/Sema/pointer-conversion.c b/test/Sema/pointer-conversion.c
new file mode 100644
index 0000000..2d755ae
--- /dev/null
+++ b/test/Sema/pointer-conversion.c
@@ -0,0 +1,10 @@
+//RUN: %clang_cc1 -fsyntax-only -verify %s
+
+char * c;
+char const ** c2 = &c; // expected-warning {{discards qualifiers in nested pointer types}}
+
+typedef char dchar;
+dchar *** c3 = &c2; // expected-warning {{discards qualifiers in nested pointer types}}
+
+volatile char * c4;
+char ** c5 = &c4; // expected-warning {{discards qualifiers in nested pointer types}}
diff --git a/test/Sema/pointer-subtract-compat.c b/test/Sema/pointer-subtract-compat.c
new file mode 100644
index 0000000..70340c6
--- /dev/null
+++ b/test/Sema/pointer-subtract-compat.c
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify -pedantic
+
+typedef const char rchar;
+int a(char* a, rchar* b) {
+  return a-b;
+}
+
+// <rdar://problem/6520707> 
+void f0(void (*fp)(void)) {
+  int x = fp - fp; // expected-warning{{arithmetic on pointer to function type 'void (*)(void)' is a GNU extension}}
+}
diff --git a/test/Sema/pragma-pack-2.c b/test/Sema/pragma-pack-2.c
new file mode 100644
index 0000000..3e6234c
--- /dev/null
+++ b/test/Sema/pragma-pack-2.c
@@ -0,0 +1,93 @@
+// RUN: %clang_cc1 -triple i686-apple-darwin9 %s -fsyntax-only -verify
+
+#include <stddef.h>
+
+#pragma pack(4)
+
+// Baseline
+struct s0 {
+  char f0;
+  int  f1;
+};
+extern int a0[offsetof(struct s0, f1) == 4 ? 1 : -1];
+
+#pragma pack(push, 2)
+struct s1 {
+  char f0;
+  int  f1;
+};
+extern int a1[offsetof(struct s1, f1) == 2 ? 1 : -1];
+#pragma pack(pop)
+
+// Test scope of definition
+
+#pragma pack(push, 2)
+struct s2_0 {
+#pragma pack(pop)
+  char f0;
+  int  f1;
+};
+extern int a2_0[offsetof(struct s2_0, f1) == 2 ? 1 : -1];
+
+struct s2_1 {
+  char f0;
+#pragma pack(push, 2)
+  int  f1;
+#pragma pack(pop)
+};
+extern int a2_1[offsetof(struct s2_1, f1) == 4 ? 1 : -1];
+
+struct s2_2 {
+  char f0;
+  int  f1;
+#pragma pack(push, 2)
+};
+#pragma pack(pop)
+extern int a2_2[offsetof(struct s2_2, f1) == 4 ? 1 : -1];
+
+struct s2_3 {
+  char f0;
+#pragma pack(push, 2)
+  struct s2_3_0 { 
+#pragma pack(pop)
+    int f0; 
+  } f1;
+};
+extern int a2_3[offsetof(struct s2_3, f1) == 2 ? 1 : -1];
+
+struct s2_4 {
+  char f0;
+  struct s2_4_0 { 
+    int f0; 
+#pragma pack(push, 2)
+  } f1;
+#pragma pack(pop)
+};
+extern int a2_4[offsetof(struct s2_4, f1) == 4 ? 1 : -1];
+
+#pragma pack(1)
+struct s3_0 {
+  char f0;
+  int f1;
+};
+#pragma pack()
+struct s3_1 {
+  char f0;
+  int f1;
+};
+extern int a3_0[offsetof(struct s3_0, f1) == 1 ? 1 : -1];
+extern int a3_1[offsetof(struct s3_1, f1) == 4 ? 1 : -1];
+
+// pack(0) is like pack()
+#pragma pack(1)
+struct s4_0 {
+  char f0;
+  int f1;
+};
+#pragma pack(0)
+struct s4_1 {
+  char f0;
+  int f1;
+};
+extern int a4_0[offsetof(struct s4_0, f1) == 1 ? 1 : -1];
+extern int a4_1[offsetof(struct s4_1, f1) == 4 ? 1 : -1];
diff --git a/test/Sema/pragma-pack-3.c b/test/Sema/pragma-pack-3.c
new file mode 100644
index 0000000..d97359e
--- /dev/null
+++ b/test/Sema/pragma-pack-3.c
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -triple i686-apple-darwin9 %s -fsyntax-only -verify
+
+// Stack: [], Alignment: 8
+
+#pragma pack(push, 1)
+// Stack: [8], Alignment: 1
+
+#pragma pack(push, 4)
+// Stack: [8, 1], Alignment: 4
+
+// Note that this differs from gcc; pack() in gcc appears to pop the
+// top stack entry and resets the current alignment. This is both
+// inconsistent with MSVC, and the gcc documentation. In other cases,
+// for example changing this to pack(8), I don't even understand what gcc
+// is doing.
+
+#pragma pack()
+// Stack: [8, 1], Alignment: 8
+
+#pragma pack(pop)
+// Stack: [8], Alignment: 1
+struct s0 {
+  char f0;
+  short f1;
+};
+int a[sizeof(struct s0) == 3 ? 1 : -1];
+
+#pragma pack(pop)
+// Stack: [], Alignment: 8
+struct s1 {
+  char f0;
+  short f1;
+};
+int b[sizeof(struct s1) == 4 ? 1 : -1];
diff --git a/test/Sema/pragma-pack-4.c b/test/Sema/pragma-pack-4.c
new file mode 100644
index 0000000..b06fc0e
--- /dev/null
+++ b/test/Sema/pragma-pack-4.c
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -triple i686-apple-darwin9 %s -fsyntax-only -verify
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -fsyntax-only -verify
+
+// rdar://problem/7095436
+#pragma pack(4)
+
+struct s0 {
+  long long a __attribute__((aligned(8)));
+  long long b __attribute__((aligned(8)));
+  unsigned int c __attribute__((aligned(8)));
+  int d[12];
+};
+
+struct s1 {
+  int a[15];
+  struct s0 b;
+};
+
+int arr0[((sizeof(struct s1) % 64) == 0) ? 1 : -1];
diff --git a/test/Sema/pragma-pack.c b/test/Sema/pragma-pack.c
new file mode 100644
index 0000000..e93ce42
--- /dev/null
+++ b/test/Sema/pragma-pack.c
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -triple i686-apple-darwin9 -fsyntax-only -verify %s
+
+/* expected-warning {{value of #pragma pack(show) == 8}} */ #pragma pack(show)
+/* expected-warning {{expected #pragma pack parameter to be}} */ #pragma pack(3)
+/* expected-warning {{value of #pragma pack(show) == 8}} */ #pragma pack(show)
+#pragma pack(4)
+/* expected-warning {{value of #pragma pack(show) == 4}} */ #pragma pack(show)
+#pragma pack() // resets to default
+/* expected-warning {{value of #pragma pack(show) == 8}} */ #pragma pack(show)
+#pragma pack(2)
+#pragma pack(push, eek, 16) // -> (eek, 2), 16
+/* expected-warning {{value of #pragma pack(show) == 16}} */ #pragma pack(show)
+#pragma pack(push) // -> (eek, 2), (, 2), 16
+/* expected-warning {{value of #pragma pack(show) == 16}} */ #pragma pack(show)
+#pragma pack(1) 
+#pragma pack(push, 8) // -> (eek, 2), (, 2), (, 1), 8
+/* expected-warning {{value of #pragma pack(show) == 8}} */ #pragma pack(show)
+#pragma pack(pop) // -> (eek, 2), (,2), 1
+/* expected-warning {{value of #pragma pack(show) == 1}} */ #pragma pack(show)
+#pragma pack(pop, eek)
+/* expected-warning {{value of #pragma pack(show) == 2}} */ #pragma pack(show)
+/* expected-warning {{pack(pop, ...) failed: stack empty}} */ #pragma pack(pop)
+
+#pragma pack(push)
+#pragma pack(pop, 16)
+/* expected-warning {{value of #pragma pack(show) == 16}} */ #pragma pack(show)
+
diff --git a/test/Sema/pragma-unused.c b/test/Sema/pragma-unused.c
new file mode 100644
index 0000000..8a051a3
--- /dev/null
+++ b/test/Sema/pragma-unused.c
@@ -0,0 +1,43 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+void f1(void) {
+  int x, y, z;
+  #pragma unused(x)
+  #pragma unused(y, z)
+  
+  int w; // FIXME: We should emit a warning that 'w' is unused.  
+  #pragma unused w // expected-warning{{missing '(' after '#pragma unused' - ignoring}}
+}
+
+void f2(void) {
+  int x, y;
+  #pragma unused(x,) // expected-warning{{expected '#pragma unused' argument to be a variable name}}
+  #pragma unused() // expected-warning{{expected '#pragma unused' argument to be a variable name}}
+}
+
+void f3(void) {
+  #pragma unused(x) // expected-warning{{undeclared variable 'x' used as an argument for '#pragma unused'}}
+}
+
+void f4(void) {
+  int w; // FIXME: We should emit a warning that 'w' is unused.
+  #pragma unused((w)) // expected-warning{{expected '#pragma unused' argument to be a variable name}}
+}
+
+int k;
+void f5(void) {
+  #pragma unused(k) // expected-warning{{only local variables can be arguments to '#pragma unused'}}
+}
+
+void f6(void) {
+  int z; // no-warning
+  {
+    #pragma unused(z) // no-warning
+  }
+}
+
+void f7() {
+  int y;
+  #pragma unused(undeclared, undefined, y) // expected-warning{{undeclared variable 'undeclared' used as an argument for '#pragma unused'}} expected-warning{{undeclared variable 'undefined' used as an argument for '#pragma unused'}}
+}
+
diff --git a/test/Sema/predef.c b/test/Sema/predef.c
new file mode 100644
index 0000000..08a4a2b
--- /dev/null
+++ b/test/Sema/predef.c
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+void abcdefghi12(void) {
+ const char (*ss)[12] = &__func__;
+ static int arr[sizeof(__func__)==12 ? 1 : -1];
+}
+
+char *X = __func__; // expected-warning {{predefined identifier is only valid}} \
+                       expected-warning {{initializing 'char *' with an expression of type 'char const [1]' discards qualifiers}}
+
+void a() {
+  __func__[0] = 'a';  // expected-error {{variable is not assignable}}
+}
+
+// rdar://6097892 - GCC permits this insanity.
+const char *b = __func__;  // expected-warning {{predefined identifier is only valid}}
+const char *c = __FUNCTION__; // expected-warning {{predefined identifier is only valid}}
+const char *d = __PRETTY_FUNCTION__; // expected-warning {{predefined identifier is only valid}}
+
diff --git a/test/Sema/predefined-function.c b/test/Sema/predefined-function.c
new file mode 100644
index 0000000..1c40b6e
--- /dev/null
+++ b/test/Sema/predefined-function.c
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s
+
+char *funk(int format);
+enum Test {A=-1};
+char *funk(enum Test x);
+
+int eli(float b); // expected-note {{previous declaration is here}} \
+// expected-note{{passing argument to parameter 'b' here}}
+int b(int c) {return 1;}
+
+int foo();
+int foo() {
+  int eli(int (int)); // expected-error {{conflicting types for 'eli'}}
+  eli(b); // expected-error{{passing 'int (int)' to parameter of incompatible type 'float'}}
+  return 0;
+}
+
+int bar();
+int bar(int i) // expected-note {{previous definition is here}}
+{
+  return 0;
+}
+int bar() // expected-error {{redefinition of 'bar'}} 
+{
+  return 0;
+}
+
+int foobar(int); // note {{previous declaration is here}}
+int foobar() // error {{conflicting types for 'foobar'}}
+{
+  return 0;
+}
+
+int wibble(); // expected-note {{previous declaration is here}}
+float wibble() // expected-error {{conflicting types for 'wibble'}}
+{
+  return 0.0f;
+}
diff --git a/test/Sema/private-extern.c b/test/Sema/private-extern.c
new file mode 100644
index 0000000..d3c1265
--- /dev/null
+++ b/test/Sema/private-extern.c
@@ -0,0 +1,88 @@
+// RUN: %clang_cc1 -verify -fsyntax-only %s
+
+static int g0; // expected-note{{previous definition}}
+int g0; // expected-error{{non-static declaration of 'g0' follows static declaration}}
+
+static int g1;
+extern int g1;
+
+static int g2; 
+__private_extern__ int g2;
+
+int g3; // expected-note{{previous definition}}
+static int g3; // expected-error{{static declaration of 'g3' follows non-static declaration}}
+
+extern int g4; // expected-note{{previous definition}}
+static int g4; // expected-error{{static declaration of 'g4' follows non-static declaration}}
+
+__private_extern__ int g5; // expected-note{{previous definition}}
+static int g5; // expected-error{{static declaration of 'g5' follows non-static declaration}}
+
+void f0() {
+  // FIXME: Diagnose this?
+  int g6;
+  extern int g6;
+}
+
+void f1() {
+  // FIXME: Diagnose this?
+  int g7;
+  __private_extern__ int g7;
+}
+
+void f2() {
+  extern int g8; // expected-note{{previous definition}}
+  // FIXME: Improve this diagnostic.
+  int g8; // expected-error{{redefinition of 'g8'}}
+}
+
+void f3() {
+  __private_extern__ int g9; // expected-note{{previous definition}}
+  // FIXME: Improve this diagnostic.
+  int g9; // expected-error{{redefinition of 'g9'}}
+}
+
+void f4() {
+  extern int g10;
+  extern int g10;
+}
+
+void f5() {
+  __private_extern__ int g11;
+  __private_extern__ int g11;
+}
+
+void f6() {
+  // FIXME: Diagnose
+  extern int g12;
+  __private_extern__ int g12;
+}
+
+void f7() {
+  // FIXME: Diagnose
+  __private_extern__ int g13;
+  extern int g13;
+}
+
+struct s0;
+void f8() {
+  extern struct s0 g14;
+  __private_extern__ struct s0 g14;
+}
+struct s0 { int x; };
+
+void f9() {
+  extern int g15 = 0; // expected-error{{'extern' variable cannot have an initializer}}
+  // FIXME: linkage specifier in warning.
+  __private_extern__ int g16 = 0; // expected-error{{'extern' variable cannot have an initializer}}
+}
+
+extern int g17;
+int g17 = 0;
+
+extern int g18 = 0; // expected-warning{{'extern' variable has an initializer}}
+
+__private_extern__ int g19;
+int g19 = 0;
+
+__private_extern__ int g20 = 0;
diff --git a/test/Sema/promote-int-16bit.c b/test/Sema/promote-int-16bit.c
new file mode 100644
index 0000000..6446720
--- /dev/null
+++ b/test/Sema/promote-int-16bit.c
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -triple pic16-unknown-unknown
+
+// Check that unsigned short promotes to unsigned int on targets where
+// sizeof(unsigned short) == sizeof(unsigned int)
+__typeof(1+(unsigned short)1) x;
+unsigned x;
diff --git a/test/Sema/rdar6248119.m b/test/Sema/rdar6248119.m
new file mode 100644
index 0000000..6b120b2
--- /dev/null
+++ b/test/Sema/rdar6248119.m
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -fsyntax-only %s -verify
+// Test case for: 
+//   <rdar://problem/6248119> @finally doesn't introduce a new scope
+
+void f0() {
+  int i;
+  @try { 
+  } @finally {
+    int i = 0;
+  }
+}
+
+void f1() {
+  int i;
+  @try { 
+    int i =0;
+  } @finally {
+  }
+}
+
+void f2() {
+  int i;
+  @try { 
+  } @catch(id e) {
+    int i = 0;
+  }
+}
diff --git a/test/Sema/rdr6094103-unordered-compare-promote.c b/test/Sema/rdr6094103-unordered-compare-promote.c
new file mode 100644
index 0000000..9991982
--- /dev/null
+++ b/test/Sema/rdr6094103-unordered-compare-promote.c
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -ast-dump %s 2>&1 | grep ImplicitCastExpr | count 2
+
+int foo (double x, long double y) {
+  // There needs to be an implicit cast on x here.
+  return __builtin_isgreater(x, y);
+}
diff --git a/test/Sema/recover-goto.c b/test/Sema/recover-goto.c
new file mode 100644
index 0000000..0d665f9
--- /dev/null
+++ b/test/Sema/recover-goto.c
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -fsyntax-only %s -verify
+
+void a() {goto A; // expected-error {{use of undeclared label}}
+// expected-error {{expected '}'}}
diff --git a/test/Sema/redefinition.c b/test/Sema/redefinition.c
new file mode 100644
index 0000000..1092b33
--- /dev/null
+++ b/test/Sema/redefinition.c
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify
+int f(int a) { return 0; } // expected-note {{previous definition is here}}
+int f(int);
+int f(int a) { return 0; } // expected-error {{redefinition of 'f'}}
+
+// <rdar://problem/6097326>
+int foo(x) {
+  return 0;
+}
+int x = 1;
diff --git a/test/Sema/return-noreturn.c b/test/Sema/return-noreturn.c
new file mode 100644
index 0000000..ff43754
--- /dev/null
+++ b/test/Sema/return-noreturn.c
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify -fblocks -Wmissing-noreturn -Wno-unreachable-code
+
+int j;
+void test1() { // expected-warning {{function could be attribute 'noreturn'}}
+  ^ (void) { while (1) { } }(); // expected-warning {{block could be attribute 'noreturn'}}
+  ^ (void) { if (j) while (1) { } }();
+  while (1) { }
+}
+
+void test2() {
+  if (j) while (1) { }
+}
+
+__attribute__((__noreturn__))
+void test2_positive() {
+  if (j) while (1) { }
+} // expected-warning{{function declared 'noreturn' should not return}}
+
+
+// This test case illustrates that we don't warn about the missing return
+// because the function is marked noreturn and there is an infinite loop.
+extern int foo_test_3();
+__attribute__((__noreturn__)) void* test3(int arg) {
+  while (1) foo_test_3();
+}
+
+__attribute__((__noreturn__)) void* test3_positive(int arg) {
+  while (0) foo_test_3();
+} // expected-warning{{function declared 'noreturn' should not return}}
+
+
+// PR5298 - -Wmissing-noreturn shouldn't warn if the function is already
+// declared noreturn.
+void __attribute__((noreturn))
+test4() {
+  test2_positive();
+}
diff --git a/test/Sema/return-silent.c b/test/Sema/return-silent.c
new file mode 100644
index 0000000..eb9641b
--- /dev/null
+++ b/test/Sema/return-silent.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 %s -Wno-return-type -fsyntax-only -verify
+
+int t14() {
+  return;
+}
+
+void t15() {
+  return 1;
+}
diff --git a/test/Sema/return.c b/test/Sema/return.c
new file mode 100644
index 0000000..0d46d98
--- /dev/null
+++ b/test/Sema/return.c
@@ -0,0 +1,241 @@
+// RUN: %clang %s -fsyntax-only -Xclang -verify -fblocks -Wno-unreachable-code -Wno-unused-value
+
+// clang emits the following warning by default.
+// With GCC, -pedantic, -Wreturn-type or -Wall are required to produce the 
+// following warning.
+int t14() {
+  return; // expected-warning {{non-void function 't14' should return a value}}
+}
+
+void t15() {
+  return 1; // expected-warning {{void function 't15' should not return a value}}
+}
+
+int unknown();
+
+void test0() {
+}
+
+int test1() {
+} // expected-warning {{control reaches end of non-void function}}
+
+int test2() {
+  a: goto a;
+}
+
+int test3() {
+  goto a;
+  a: ;
+} // expected-warning {{control reaches end of non-void function}}
+
+
+void halt() {
+  a: goto a;
+}
+
+void halt2() __attribute__((noreturn));
+
+int test4() {
+  halt2();
+}
+
+int test5() {
+  halt2(), (void)1;
+}
+
+int test6() {
+  1, halt2();
+}
+
+int j;
+int unknown_nohalt() {
+  return j;
+}
+
+int test7() {
+  unknown();
+} // expected-warning {{control reaches end of non-void function}}
+
+int test8() {
+  (void)(1 + unknown());
+} // expected-warning {{control reaches end of non-void function}}
+
+int halt3() __attribute__((noreturn));
+
+int test9() {
+  (void)(halt3() + unknown());
+}
+
+int test10() {
+  (void)(unknown() || halt3());
+} // expected-warning {{control may reach end of non-void function}}
+
+int test11() {
+  (void)(unknown() && halt3());
+} // expected-warning {{control may reach end of non-void function}}
+
+int test12() {
+  (void)(halt3() || unknown());
+}
+
+int test13() {
+  (void)(halt3() && unknown());
+}
+
+int test14() {
+  (void)(1 || unknown());
+} // expected-warning {{control reaches end of non-void function}}
+
+int test15() {
+  (void)(0 || unknown());
+} // expected-warning {{control reaches end of non-void function}}
+
+int test16() {
+  (void)(0 && unknown());
+} // expected-warning {{control reaches end of non-void function}}
+
+int test17() {
+  (void)(1 && unknown());
+} // expected-warning {{control reaches end of non-void function}}
+
+int test18() {
+  (void)(unknown_nohalt() && halt3());
+} // expected-warning {{control may reach end of non-void function}}
+
+int test19() {
+  (void)(unknown_nohalt() && unknown());
+} // expected-warning {{control reaches end of non-void function}}
+
+int test20() {
+  int i;
+  if (i)
+    return 0;
+  else if (0)
+    return 2;
+} // expected-warning {{control may reach end of non-void function}}
+
+int test21() {
+  int i;
+  if (i)
+    return 0;
+  else if (1)
+    return 2;
+}
+
+int test22() {
+  int i;
+  switch (i) default: ;
+} // expected-warning {{control reaches end of non-void function}}
+
+int test23() {
+  int i;
+  switch (i) {
+  case 0:
+    return 0;
+  case 2:
+    return 2;
+  }
+} // expected-warning {{control may reach end of non-void function}}
+
+int test24() {
+  int i;
+  switch (i) {
+    case 0:
+    return 0;
+  case 2:
+    return 2;
+  default:
+    return -1;
+  }
+}
+
+int test25() {
+  1 ? halt3() : unknown();
+}
+
+int test26() {
+  0 ? halt3() : unknown();
+} // expected-warning {{control reaches end of non-void function}}
+
+int j;
+void (*fptr)() __attribute__((noreturn));
+int test27() {
+  switch (j) {
+  case 1:
+    do { } while (1);
+    break;
+  case 2:
+    for (;;) ;
+    break;
+  case 3:
+    for (;1;) ;
+    for (;0;) {
+      goto done;
+    }
+    return 1;
+  case 4:    
+    while (0) { goto done; }
+    return 1;
+  case 5:
+    while (1) { return 1; }
+    break;
+  case 6:
+    fptr();
+    break;
+  default:
+    return 1;
+  }
+  done: ;
+}
+
+// PR4624
+void test28() __attribute__((noreturn));
+void test28(x) { while (1) { } }
+
+void exit(int);
+int test29() {
+  exit(1);
+}
+
+#include <setjmp.h>
+jmp_buf test30_j;
+int test30() {
+  if (j)
+    longjmp(test30_j, 1);
+  else
+#if defined(_WIN32) || defined(_WIN64)
+    longjmp(test30_j, 2);
+#else
+    _longjmp(test30_j, 1);
+#endif
+}
+
+typedef void test31_t(int status);
+void test31(test31_t *callback __attribute__((noreturn)));
+
+void test32() {
+  ^ (void) { while (1) { } }();
+  ^ (void) { if (j) while (1) { } }();
+  while (1) { }
+}
+
+void test33() {
+  if (j) while (1) { }
+}
+
+// Test that 'static inline' functions are only analyzed for CFG-based warnings
+// when they are used.
+static inline int si_has_missing_return() {} // expected-warning{{control reaches end of non-void function}}
+static inline int si_has_missing_return_2() {}; // expected-warning{{control reaches end of non-void function}}
+static inline int si_forward();
+static inline int si_has_missing_return_3(int x) {
+  if (x)
+   return si_has_missing_return_3(x+1);
+} // expected-warning{{control may reach end of non-void function}}
+
+int test_static_inline(int x) {
+  si_forward();
+  return x ? si_has_missing_return_2() : si_has_missing_return_3(x);
+}
+static inline int si_forward() {} // expected-warning{{control reaches end of non-void function}}
+
diff --git a/test/Sema/scope-check.c b/test/Sema/scope-check.c
new file mode 100644
index 0000000..6f86402
--- /dev/null
+++ b/test/Sema/scope-check.c
@@ -0,0 +1,195 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -std=gnu99 %s -Wno-unreachable-code
+
+int test1(int x) {
+  goto L;    // expected-error{{illegal goto into protected scope}}
+  int a[x];  // expected-note {{jump bypasses initialization of variable length array}}
+  int b[x];  // expected-note {{jump bypasses initialization of variable length array}}
+  L:
+  return sizeof a;
+}
+
+int test2(int x) {
+  goto L;            // expected-error{{illegal goto into protected scope}}
+  typedef int a[x];  // expected-note {{jump bypasses initialization of VLA typedef}}
+  L:
+  return sizeof(a);
+}
+
+void test3clean(int*);
+
+int test3() {
+  goto L;            // expected-error{{illegal goto into protected scope}}
+int a __attribute((cleanup(test3clean))); // expected-note {{jump bypasses initialization of declaration with __attribute__((cleanup))}}
+L:
+  return a;
+}
+
+int test4(int x) {
+  goto L;       // expected-error{{illegal goto into protected scope}}
+int a[x];       // expected-note {{jump bypasses initialization of variable length array}}
+  test4(x);
+L:
+  return sizeof a;
+}
+
+int test5(int x) {
+  int a[x];
+  test5(x);
+  goto L;  // Ok.
+L:
+  goto L;  // Ok.
+  return sizeof a;
+}
+
+int test6() { 
+  // just plain invalid.
+  goto x;  // expected-error {{use of undeclared label 'x'}}
+}
+
+void test7(int x) {
+  switch (x) {
+  case 1: ;
+    int a[x];       // expected-note {{jump bypasses initialization of variable length array}}
+  case 2:           // expected-error {{illegal switch case into protected scope}}
+    a[1] = 2;
+    break;
+  }
+}
+
+int test8(int x) {
+  // For statement.
+  goto L2;     // expected-error {{illegal goto into protected scope}}
+  for (int arr[x];   // expected-note {{jump bypasses initialization of variable length array}}  
+       ; ++x)
+    L2:;
+
+  // Statement expressions.
+  goto L3;   // expected-error {{illegal goto into protected scope}}
+  int Y = ({  int a[x];   // expected-note {{jump bypasses initialization of variable length array}}  
+           L3: 4; });
+  
+  goto L4; // expected-error {{illegal goto into protected scope}}
+  {
+    int A[x],  // expected-note {{jump bypasses initialization of variable length array}}
+        B[x];  // expected-note {{jump bypasses initialization of variable length array}}
+  L4: ;
+  }
+  
+  {
+  L5: ;// ok
+    int A[x], B = ({ if (x)
+                       goto L5;
+                     else 
+                       goto L6;
+                   4; }); 
+  L6:; // ok.
+    if (x) goto L6; // ok
+  }
+  
+  {
+  L7: ;// ok
+    int A[x], B = ({ if (x)
+                       goto L7;
+                     else 
+                       goto L8;  // expected-error {{illegal goto into protected scope}}
+                     4; }),
+        C[x];   // expected-note {{jump bypasses initialization of variable length array}}
+  L8:; // bad
+  }
+ 
+  {
+  L9: ;// ok
+    int A[({ if (x)
+               goto L9;
+             else
+               // FIXME:
+               goto L10;  // fixme-error {{illegal goto into protected scope}}
+           4; })];
+  L10:; // bad
+  }
+  
+  {
+    // FIXME: Crashes goto checker.
+    //goto L11;// ok
+    //int A[({   L11: 4; })];
+  }
+  
+  {
+    goto L12;
+    
+    int y = 4;   // fixme-warn: skips initializer.
+  L12:
+    ;
+  }
+  
+  // Statement expressions 2.
+  goto L1;     // expected-error {{illegal goto into protected scope}}
+  return x == ({
+                 int a[x];   // expected-note {{jump bypasses initialization of variable length array}}  
+               L1:
+                 42; });
+}
+
+void test9(int n, void *P) {
+  int Y;
+  int Z = 4;
+  goto *P;  // ok.
+
+L2: ;
+  int a[n]; // expected-note 2 {{jump bypasses initialization of variable length array}}
+
+L3:
+L4:  
+  goto *P;  // expected-warning {{illegal indirect goto in protected scope, unknown effect on scopes}}
+  goto L3;  // ok
+  goto L4;  // ok
+  
+  void *Ptrs[] = {
+    &&L2,   // Ok.
+    &&L3   // expected-warning {{address taken of label in protected scope, jump to it would have unknown effect on scope}}
+  };
+}
+
+void test10(int n, void *P) {
+  goto L0;     // expected-error {{illegal goto into protected scope}}
+  typedef int A[n];  // expected-note {{jump bypasses initialization of VLA typedef}}
+L0:
+  
+  goto L1;      // expected-error {{illegal goto into protected scope}}
+  A b, c[10];        // expected-note 2 {{jump bypasses initialization of variable length array}}
+L1:
+  goto L2;     // expected-error {{illegal goto into protected scope}}
+  A d[n];      // expected-note {{jump bypasses initialization of variable length array}}
+L2:
+  return;
+}
+
+void test11(int n) {
+  void *P = ^{
+    switch (n) {
+    case 1:;
+    case 2: 
+    case 3:;
+      int Arr[n]; // expected-note {{jump bypasses initialization of variable length array}}
+    case 4:       // expected-error {{illegal switch case into protected scope}}
+      return;
+    }
+  };
+}
+
+
+// TODO: When and if gotos are allowed in blocks, this should work.
+void test12(int n) {
+  void *P = ^{
+    goto L1;
+  L1:
+    goto L2;
+  L2:
+    goto L3;    // expected-error {{illegal goto into protected scope}}
+    int Arr[n]; // expected-note {{jump bypasses initialization of variable length array}}
+  L3:
+    goto L4;
+  L4: return;
+  };
+}
+
diff --git a/test/Sema/self-comparison.c b/test/Sema/self-comparison.c
new file mode 100644
index 0000000..1baba27
--- /dev/null
+++ b/test/Sema/self-comparison.c
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+int foo(int x) {
+  return x == x; // expected-warning {{self-comparison always results}}
+}
+
+int foo2(int x) {
+  return (x) != (((x))); // expected-warning {{self-comparison always results}}
+}
+
+int qux(int x) {
+   return x < x; // expected-warning {{self-comparison}}
+}
+
+int qux2(int x) {
+   return x > x; // expected-warning {{self-comparison}}
+}
+
+int bar(float x) {
+  return x == x; // no-warning
+}
+
+int bar2(float x) {
+  return x != x; // no-warning
+}
+
+// Motivated by <rdar://problem/6703892>, self-comparisons of enum constants
+// should not be warned about.  These can be expanded from macros, and thus
+// are usually deliberate.
+int compare_enum() {
+  enum { A };
+  return A == A; // no-warning
+}
+
+// Don't complain in unevaluated contexts.
+int compare_sizeof(int x) {
+  return sizeof(x == x); // no-warning
+}
diff --git a/test/Sema/sentinel-attribute.c b/test/Sema/sentinel-attribute.c
new file mode 100644
index 0000000..4c09273
--- /dev/null
+++ b/test/Sema/sentinel-attribute.c
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+int x __attribute__((sentinel)); //expected-warning{{'sentinel' attribute only applies to function, method or block types}}
+
+void f1(int a, ...) __attribute__ ((sentinel));
+void f2(int a, ...) __attribute__ ((sentinel(1)));
+
+void f3(int a, ...) __attribute__ ((sentinel("hello"))); //expected-error{{'sentinel' attribute requires parameter 1 to be an integer constant}}
+void f4(int a, ...) __attribute__ ((sentinel(1, 2, 3))); //expected-error{{attribute requires 0, 1 or 2 argument(s)}}
+void f4(int a, ...) __attribute__ ((sentinel(-1))); //expected-error{{parameter 1 less than zero}}
+void f4(int a, ...) __attribute__ ((sentinel(0, 2))); // expected-error{{parameter 2 not 0 or 1}}
+
+void f5(int a) __attribute__ ((sentinel)); //expected-warning{{'sentinel' attribute only supported for variadic functions}}
+
+
+void f6() __attribute__((__sentinel__));  // expected-warning {{'sentinel' attribute requires named arguments}}
diff --git a/test/Sema/shift.c b/test/Sema/shift.c
new file mode 100644
index 0000000..558a7d2
--- /dev/null
+++ b/test/Sema/shift.c
@@ -0,0 +1,40 @@
+// RUN: %clang -Wall -fsyntax-only -Xclang -verify %s
+
+#include <limits.h>
+
+enum {
+  X = 1 << 0,
+  Y = 1 << 1,
+  Z = 1 << 2
+};
+
+void test() {
+  char c;
+
+  c = 0 << 0;
+  c = 0 << 1;
+  c = 1 << 0;
+  c = 1 << -0;
+  c = 1 >> -0;
+  c = 1 << -1; // expected-warning {{shift count is negative}}
+  c = 1 >> -1; // expected-warning {{shift count is negative}}
+  c = 1 << c;
+  c <<= 0;
+  c >>= 0;
+  c <<= 1;
+  c >>= 1;
+  c <<= -1; // expected-warning {{shift count is negative}}
+  c >>= -1; // expected-warning {{shift count is negative}}
+  c <<= 999999; // expected-warning {{shift count >= width of type}}
+  c >>= 999999; // expected-warning {{shift count >= width of type}}
+  c <<= CHAR_BIT; // expected-warning {{shift count >= width of type}}
+  c >>= CHAR_BIT; // expected-warning {{shift count >= width of type}}
+  c <<= CHAR_BIT+1; // expected-warning {{shift count >= width of type}}
+  c >>= CHAR_BIT+1; // expected-warning {{shift count >= width of type}}
+  (void)((long)c << CHAR_BIT);
+}
+
+#define a 0
+#define ashift 8
+enum { b = (a << ashift) };
+
diff --git a/test/Sema/statements.c b/test/Sema/statements.c
new file mode 100644
index 0000000..e3c41f3
--- /dev/null
+++ b/test/Sema/statements.c
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify
+
+typedef unsigned __uint32_t;
+
+#define __byte_swap_int_var(x) \
+__extension__ ({ register __uint32_t __X = (x); \
+   __asm ("bswap %0" : "+r" (__X)); \
+   __X; })
+
+int test(int _x) {
+ return (__byte_swap_int_var(_x));
+}
+
+// PR2374
+int test2() { return ({L:5;}); }
+int test3() { return ({ {5;} }); }         // expected-error {{returning 'void' from a function with incompatible result type 'int'}}\
+                                           // expected-warning {{expression result unused}}
+int test4() { return ({ ({5;}); }); }
+int test5() { return ({L1: L2: L3: 5;}); }
+int test6() { return ({5;}); }
+void test7() { ({5;}); }                   // expected-warning {{expression result unused}}
+
+// PR3062
+int test8[({10;})]; // expected-error {{statement expression not allowed at file scope}}
+
+// PR3912
+void test9(const void *P) {
+  __builtin_prefetch(P);
+}
+
+
+void *test10() { 
+bar:
+  return &&bar;  // expected-warning {{returning address of label, which is local}}
+}
+
+// PR6034
+void test11(int bit) {
+  switch (bit)
+  switch (env->fpscr)  // expected-error {{use of undeclared identifier 'env'}}
+  {
+  }
+}
+
+// rdar://3271964
+enum Numbers { kOne,  kTwo,  kThree,  kFour};
+int test12(enum Numbers num) {
+  switch (num == kOne) {// expected-warning {{switch condition has boolean value}}
+  default: 
+  case kThree:
+    break;
+  }
+}
\ No newline at end of file
diff --git a/test/Sema/static-init.c b/test/Sema/static-init.c
new file mode 100644
index 0000000..b4de927
--- /dev/null
+++ b/test/Sema/static-init.c
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+typedef __typeof((int*) 0 - (int*) 0) intptr_t;
+
+static int f = 10;
+static int b = f; // expected-error {{initializer element is not a compile-time constant}}
+
+float r  = (float) (intptr_t) &r; // expected-error {{initializer element is not a compile-time constant}}
+intptr_t s = (intptr_t) &s;
+_Bool t = &t;
+
+
+union bar {
+  int i;
+};
+
+struct foo {
+  unsigned ptr;
+};
+
+union bar u[1];
+struct foo x = {(intptr_t) u}; // no-error
+struct foo y = {(char) u}; // expected-error {{initializer element is not a compile-time constant}}
diff --git a/test/Sema/stdcall-fastcall.c b/test/Sema/stdcall-fastcall.c
new file mode 100644
index 0000000..a069526
--- /dev/null
+++ b/test/Sema/stdcall-fastcall.c
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// CC qualifier can be applied only to functions
+int __attribute__((stdcall)) var1; // expected-warning{{'stdcall' only applies to function types; type here is 'int'}}
+int __attribute__((fastcall)) var2; // expected-warning{{'fastcall' only applies to function types; type here is 'int'}}
+
+// Different CC qualifiers are not compatible
+void __attribute__((stdcall, fastcall)) foo3(void); // expected-error{{stdcall and fastcall attributes are not compatible}}
+void __attribute__((stdcall)) foo4(); // expected-note{{previous declaration is here}}
+void __attribute__((fastcall)) foo4(void); // expected-error{{function declared 'fastcall' here was previously declared 'stdcall'}}
diff --git a/test/Sema/struct-cast.c b/test/Sema/struct-cast.c
new file mode 100644
index 0000000..dc7db13
--- /dev/null
+++ b/test/Sema/struct-cast.c
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -fsyntax-only %s -verify
+
+struct S {
+ int one;
+ int two;
+};
+
+struct S const foo(void);
+
+struct S tmp;
+
+void priv_sock_init() {
+  tmp = (struct S)foo();
+}
diff --git a/test/Sema/struct-compat.c b/test/Sema/struct-compat.c
new file mode 100644
index 0000000..65bef9f
--- /dev/null
+++ b/test/Sema/struct-compat.c
@@ -0,0 +1,17 @@
+/* RUN: %clang_cc1 %s -fsyntax-only -pedantic -verify
+ */
+
+extern struct {int a;} x; // expected-note {{previous definition is here}}
+extern struct {int a;} x; // expected-error {{redefinition of 'x'}}
+
+struct x;
+int a(struct x* b) {
+// Per C99 6.7.2.3, since the outer and inner "struct x"es have different
+// scopes, they don't refer to the same type, and are therefore incompatible
+struct x {int a;} *c = b; // expected-warning {{incompatible pointer types}}
+}
+
+struct x {int a;} r;
+int b() {
+struct x {char x;} s = r; // expected-error {{initializing 'struct x' with an expression of incompatible type 'struct x'}}
+}
diff --git a/test/Sema/struct-decl.c b/test/Sema/struct-decl.c
new file mode 100644
index 0000000..f888053
--- /dev/null
+++ b/test/Sema/struct-decl.c
@@ -0,0 +1,43 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// PR3459
+struct bar {
+  char n[1];
+};
+
+struct foo {
+  char name[(int)&((struct bar *)0)->n];
+  char name2[(int)&((struct bar *)0)->n - 1]; //expected-error{{array size is negative}}
+};
+
+// PR3430
+struct s {
+  struct st {
+    int v;
+  } *ts;
+};
+
+struct st;
+
+int foo() {
+  struct st *f;
+  return f->v + f[0].v;
+}
+
+// PR3642, PR3671
+struct pppoe_tag {
+ short tag_type;
+ char tag_data[];
+};
+struct datatag {
+  struct pppoe_tag hdr; //expected-warning{{field 'hdr' with variable sized type 'struct pppoe_tag' not at the end of a struct or class is a GNU extension}}
+  char data;
+};
+
+
+// PR4092
+struct s0 {
+  char a;  // expected-note {{previous declaration is here}}
+  char a;  // expected-error {{duplicate member 'a'}}
+};
+
+struct s0 f0(void) {}
diff --git a/test/Sema/struct-packed-align.c b/test/Sema/struct-packed-align.c
new file mode 100644
index 0000000..2b94567
--- /dev/null
+++ b/test/Sema/struct-packed-align.c
@@ -0,0 +1,119 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify
+
+// Packed structs.
+struct s {
+    char a;
+    int b  __attribute__((packed));
+    char c;
+    int d;
+};
+
+extern int a1[sizeof(struct s) == 12 ? 1 : -1];
+extern int a2[__alignof(struct s) == 4 ? 1 : -1];
+
+struct __attribute__((packed)) packed_s {
+    char a;
+    int b  __attribute__((packed));
+    char c;
+    int d;
+};
+
+extern int b1[sizeof(struct packed_s) == 10 ? 1 : -1];
+extern int b2[__alignof(struct packed_s) == 1 ? 1 : -1];
+
+struct fas {
+    char a;
+    int b[];
+};
+
+extern int c1[sizeof(struct fas) == 4 ? 1 : -1];
+extern int c2[__alignof(struct fas) == 4 ? 1 : -1];
+
+struct __attribute__((packed)) packed_fas {
+    char a;
+    int b[];
+};
+
+extern int d1[sizeof(struct packed_fas) == 1 ? 1 : -1];
+extern int d2[__alignof(struct packed_fas) == 1 ? 1 : -1];
+
+struct packed_after_fas {
+    char a;
+    int b[];
+} __attribute__((packed));
+
+extern int d1_2[sizeof(struct packed_after_fas) == 1 ? 1 : -1];
+extern int d2_2[__alignof(struct packed_after_fas) == 1 ? 1 : -1];
+
+// Alignment
+
+struct __attribute__((aligned(8))) as1 {
+    char c;
+};
+
+extern int e1[sizeof(struct as1) == 8 ? 1 : -1];
+extern int e2[__alignof(struct as1) == 8 ? 1 : -1];
+
+// FIXME: Will need to force arch once max usable alignment isn't hard
+// coded.
+struct __attribute__((aligned)) as1_2 {
+    char c;
+};
+extern int e1_2[sizeof(struct as1_2) == 16 ? 1 : -1];
+extern int e2_2[__alignof(struct as1_2) == 16 ? 1 : -1];
+
+struct as2 {
+    char c;
+    int __attribute__((aligned(8))) a;
+};
+
+extern int f1[sizeof(struct as2) == 16 ? 1 : -1];
+extern int f2[__alignof(struct as2) == 8 ? 1 : -1];
+
+struct __attribute__((packed)) as3 {
+    char c;
+    int a;
+    int __attribute__((aligned(8))) b;
+};
+
+extern int g1[sizeof(struct as3) == 16 ? 1 : -1];
+extern int g2[__alignof(struct as3) == 8 ? 1 : -1];
+
+
+// rdar://5921025
+struct packedtest {
+  int ted_likes_cheese;
+  void *args[] __attribute__((packed));
+};
+
+// Packed union
+union __attribute__((packed)) au4 {char c; int x;};
+extern int h1[sizeof(union au4) == 4 ? 1 : -1];
+extern int h2[__alignof(union au4) == 1 ? 1 : -1];
+
+// Aligned union
+union au5 {__attribute__((aligned(4))) char c;};
+extern int h1[sizeof(union au5) == 4 ? 1 : -1];
+extern int h2[__alignof(union au5) == 4 ? 1 : -1];
+
+// Alignment+packed
+struct as6 {char c; __attribute__((packed, aligned(2))) int x;};
+extern int i1[sizeof(struct as6) == 6 ? 1 : -1];
+extern int i2[__alignof(struct as6) == 2 ? 1 : -1];
+
+union au6 {char c; __attribute__((packed, aligned(2))) int x;};
+extern int k1[sizeof(union au6) == 4 ? 1 : -1];
+extern int k2[__alignof(union au6) == 2 ? 1 : -1];
+
+// Check postfix attributes
+union au7 {char c; int x;} __attribute__((packed));
+extern int l1[sizeof(union au7) == 4 ? 1 : -1];
+extern int l2[__alignof(union au7) == 1 ? 1 : -1];
+
+struct packed_fas2 {
+    char a;
+    int b[];
+} __attribute__((packed));
+
+extern int m1[sizeof(struct packed_fas2) == 1 ? 1 : -1];
+extern int m2[__alignof(struct packed_fas2) == 1 ? 1 : -1];
diff --git a/test/Sema/surpress-deprecated.c b/test/Sema/surpress-deprecated.c
new file mode 100644
index 0000000..78faf22
--- /dev/null
+++ b/test/Sema/surpress-deprecated.c
@@ -0,0 +1,7 @@
+// RUN: %clang -fsyntax-only -Wno-deprecated-declarations -verify %s
+extern void OldFunction() __attribute__((deprecated));
+
+int main (int argc, const char * argv[]) {
+  OldFunction();
+}
+
diff --git a/test/Sema/switch.c b/test/Sema/switch.c
new file mode 100644
index 0000000..e63a194
--- /dev/null
+++ b/test/Sema/switch.c
@@ -0,0 +1,263 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+void f (int z) { 
+  while (z) { 
+    default: z--;            // expected-error {{statement not in switch}}
+  } 
+}
+
+void foo(int X) {
+  switch (X) {
+  case 42: ;                 // expected-note {{previous case}}
+  case 5000000000LL:         // expected-warning {{overflow}}
+  case 42:                   // expected-error {{duplicate case value}}
+   ;
+
+  case 100 ... 99: ;         // expected-warning {{empty case range}}
+
+  case 43: ;                 // expected-note {{previous case}}
+  case 43 ... 45:  ;         // expected-error {{duplicate case value}}
+
+  case 100 ... 20000:;       // expected-note {{previous case}}
+  case 15000 ... 40000000:;  // expected-error {{duplicate case value}}
+  }
+}
+
+void test3(void) { 
+  // empty switch;
+  switch (0); 
+}
+
+extern int g();
+
+void test4()
+{
+  switch (1) {
+  case 0 && g():
+  case 1 || g():
+    break;
+  }
+
+  switch(1)  {
+  case g(): // expected-error {{expression is not an integer constant expression}}
+  case 0 ... g(): // expected-error {{expression is not an integer constant expression}}
+    break;
+  }
+  
+  switch (1) {
+  case 0 && g() ... 1 || g():
+    break;
+  }
+  
+  switch (1) {
+  case g() && 0: // expected-error {{expression is not an integer constant expression}} // expected-note {{subexpression not valid in an integer constant expression}}
+    break;
+  }
+  
+  switch (1) {
+  case 0 ... g() || 1: // expected-error {{expression is not an integer constant expression}} // expected-note {{subexpression not valid in an integer constant expression}}
+    break;
+  }
+}
+
+void test5(int z) { 
+  switch(z) {
+    default:  // expected-note {{previous case defined here}}
+    default:  // expected-error {{multiple default labels in one switch}}
+      break;
+  }
+} 
+
+void test6() {
+  const char ch = 'a';
+  switch(ch) {
+    case 1234:  // expected-warning {{overflow converting case value}}
+      break;
+  }
+}
+
+// PR5606
+int f0(int var) { // expected-note{{'var' declared here}}
+  switch (va) { // expected-error{{use of undeclared identifier 'va'}}
+  case 1:
+    break;
+  case 2:
+    return 1;
+  }
+  return 2;
+}
+
+void test7() {
+  enum {
+    A = 1,
+    B
+  } a;
+  switch(a) { //expected-warning{{enumeration value 'B' not handled in switch}}
+    case A:
+      break;
+  }
+  switch(a) {
+    case B:
+    case A:
+      break;
+  }
+  switch(a) {
+    case A:
+    case B:
+    case 3: // expected-warning{{case value not in enumerated type ''}}
+      break;
+  }
+  switch(a) {
+    case A:
+    case B:
+    case 3 ... //expected-warning{{case value not in enumerated type ''}}
+        4: //expected-warning{{case value not in enumerated type ''}}
+      break;
+  }
+  switch(a) {
+    case 1 ... 2:
+      break;
+  }
+  switch(a) {
+    case 0 ... 2: //expected-warning{{case value not in enumerated type ''}}
+      break;
+  }
+  switch(a) {
+    case 1 ... 3: //expected-warning{{case value not in enumerated type ''}}
+      break;
+  }
+  switch(a) {
+    case 0 ...  //expected-warning{{case value not in enumerated type ''}}
+      3:  //expected-warning{{case value not in enumerated type ''}}
+      break;
+  }
+
+}
+
+void test8() {
+  enum {
+    A,
+    B,
+    C = 1
+  } a;
+  switch(a) {
+    case A:
+    case B:
+     break;
+  }
+  switch(a) {
+    case A:
+    case C:
+      break;
+  }
+  switch(a) { //expected-warning{{enumeration value 'B' not handled in switch}}
+    case A:
+      break;
+  }
+}
+
+void test9() {
+  enum {
+    A = 3,
+    C = 1
+  } a;
+  switch(a) {
+    case 0: //expected-warning{{case value not in enumerated type ''}}
+    case 1:
+    case 2: //expected-warning{{case value not in enumerated type ''}}
+    case 3:
+    case 4: //expected-warning{{case value not in enumerated type ''}}
+      break;
+  }
+}
+
+void test10() {
+  enum {
+    A = 10,
+    C = 2,
+    B = 4,
+    D = 12
+  } a;
+  switch(a) {
+    case 0 ...  //expected-warning{{case value not in enumerated type ''}}
+	    1:  //expected-warning{{case value not in enumerated type ''}}
+    case 2 ... 4:
+    case 5 ...  //expected-warning{{case value not in enumerated type ''}}	
+	      9:  //expected-warning{{case value not in enumerated type ''}}
+    case 10 ... 12:
+    case 13 ...  //expected-warning{{case value not in enumerated type ''}}
+              16: //expected-warning{{case value not in enumerated type ''}}
+      break;
+  }
+}
+
+void test11() {
+  enum {
+    A = -1,
+    B,
+    C
+  } a;
+  switch(a) { //expected-warning{{enumeration value 'A' not handled in switch}}
+    case B:
+    case C:
+      break;
+  }
+
+  switch(a) {
+    case B:
+    case C:
+      break;
+      
+    default:
+      break;
+  }
+}
+
+void test12() {
+  enum {
+    A = -1,
+    B = 4294967286
+  } a;
+  switch(a) {
+    case A:
+    case B:
+      break;
+  }
+}
+
+// <rdar://problem/7643909>
+typedef enum {
+    val1,
+    val2,
+    val3
+} my_type_t;
+
+int test13(my_type_t t) {
+  switch(t) { // expected-warning{{enumeration value 'val3' not handled in switch}}
+  case val1:
+    return 1;
+  case val2:
+    return 2;
+  }
+  return -1;
+}
+
+// <rdar://problem/7658121>
+enum {
+  EC0 = 0xFFFF0000,
+  EC1 = 0xFFFF0001,
+};
+
+int test14(int a) {
+  switch(a) {
+  case EC0: return 0;
+  case EC1: return 1;
+  }
+  return 0;
+}
+
+void f1(unsigned x) {
+  switch (x) {
+  case -1: break;
+  default: break;
+  }
+}
diff --git a/test/Sema/tentative-decls.c b/test/Sema/tentative-decls.c
new file mode 100644
index 0000000..b15537b
--- /dev/null
+++ b/test/Sema/tentative-decls.c
@@ -0,0 +1,65 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify
+
+// PR3310
+struct a x1; // expected-note 2{{forward declaration of 'struct a'}}
+static struct a x2; // expected-warning{{tentative definition of variable with internal linkage has incomplete non-array type 'struct a'}}
+struct a x3[10]; // expected-error{{array has incomplete element type 'struct a'}}
+struct a {int x;};
+static struct a x2_okay;
+struct a x3_okay[10];
+struct b x4; // expected-error{{tentative definition has type 'struct b' that is never completed}} \
+            // expected-note{{forward declaration of 'struct b'}}
+
+const int a [1] = {1};
+extern const int a[];
+
+extern const int b[];
+const int b [1] = {1};
+
+extern const int c[] = {1}; // expected-warning{{'extern' variable has an initializer}}
+const int c[];
+
+int i1 = 1; // expected-note {{previous definition is here}}
+int i1 = 2; // expected-error {{redefinition of 'i1'}}
+int i1;
+int i1;
+extern int i5; // expected-note {{previous definition is here}}
+static int i5; // expected-error{{static declaration of 'i5' follows non-static declaration}}
+
+static int i2 = 5; // expected-note 1 {{previous definition is here}}
+int i2 = 3; // expected-error{{non-static declaration of 'i2' follows static declaration}}
+
+static int i3 = 5;
+extern int i3;
+
+__private_extern__ int pExtern;
+int pExtern = 0;
+
+int i4;
+int i4;
+extern int i4;
+
+int (*pToArray)[];
+int (*pToArray)[8];
+
+int redef[10];
+int redef[];  // expected-note {{previous definition is here}}
+int redef[11]; // expected-error{{redefinition of 'redef'}}
+
+void func() {
+  extern int i6; // expected-note {{previous definition is here}}
+  static int i6; // expected-error{{static declaration of 'i6' follows non-static declaration}}
+}
+
+void func2(void)
+{
+  extern double *p;
+  extern double *p;
+}
+
+// <rdar://problem/6808352>
+static int a0[];
+static int b0;
+
+static int a0[] = { 4 };
+static int b0 = 5;
diff --git a/test/Sema/text-diag.c b/test/Sema/text-diag.c
new file mode 100644
index 0000000..6dcaaa8
--- /dev/null
+++ b/test/Sema/text-diag.c
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -fsyntax-only %s
+unsigned char *foo = "texto\
+que continua\
+e continua";
diff --git a/test/Sema/thread-specifier.c b/test/Sema/thread-specifier.c
new file mode 100644
index 0000000..ed27c70
--- /dev/null
+++ b/test/Sema/thread-specifier.c
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -triple i686-pc-linux-gnu -fsyntax-only -verify %s
+
+__thread int t1;
+__thread extern int t2;
+__thread static int t3;
+__thread __private_extern__ int t4;
+struct t5 { __thread int x; }; // expected-error {{type name does not allow storage class to be specified}}
+__thread int t6(); // expected-error {{'__thread' is only allowed on variable declarations}}
+int f(__thread int t7) { // expected-error {{'__thread' is only allowed on variable declarations}}
+  __thread int t8; // expected-error {{'__thread' variables must have global storage}}
+  __thread extern int t9;
+  __thread static int t10;
+  __thread __private_extern__ int t11;
+  __thread auto int t12; // expected-error {{'__thread' variables must have global storage}}
+  __thread register int t13; // expected-error {{'__thread' variables must have global storage}}
+}
+__thread typedef int t14; // expected-error {{'__thread' is only allowed on variable declarations}}
+__thread int t15; // expected-note {{[previous definition is here}}
+int t15; // expected-error {{non-thread-local declaration of 't15' follows thread-local declaration}}
+int t16; // expected-note {{[previous definition is here}}
+__thread int t16; // expected-error {{thread-local declaration of 't16' follows non-thread-local declaration}}
diff --git a/test/Sema/transparent-union-pointer.c b/test/Sema/transparent-union-pointer.c
new file mode 100644
index 0000000..31c9391
--- /dev/null
+++ b/test/Sema/transparent-union-pointer.c
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify
+
+typedef union   {
+  union wait *__uptr;
+  int *__iptr;
+} __WAIT_STATUS __attribute__ ((__transparent_union__));
+
+extern int wait (__WAIT_STATUS __stat_loc);
+
+void fastcgi_cleanup() {
+  int status = 0;
+  wait(&status);
+}
+
diff --git a/test/Sema/transparent-union.c b/test/Sema/transparent-union.c
new file mode 100644
index 0000000..cdfc850
--- /dev/null
+++ b/test/Sema/transparent-union.c
@@ -0,0 +1,40 @@
+// RUN: %clang -fsyntax-only -Xclang -verify %s
+typedef union {
+  int *ip;
+  float *fp;
+} TU __attribute__((transparent_union));
+
+void f(TU); // expected-note{{passing argument to parameter here}}
+
+void g(int *ip, float *fp, char *cp) {
+  f(ip);
+  f(fp);
+  f(cp); // expected-error{{incompatible type}}
+  f(0);
+
+  TU tu_ip = ip; // expected-error{{incompatible type}}
+  TU tu;
+  tu.ip = ip;
+}
+
+/* FIXME: we'd like to just use an "int" here and align it differently
+   from the normal "int", but if we do so we lose the alignment
+   information from the typedef within the compiler. */
+typedef struct { int x, y; } __attribute__((aligned(8))) aligned_struct8;
+
+typedef struct { int x, y; } __attribute__((aligned(4))) aligned_struct4;
+typedef union {
+  aligned_struct4 s4; // expected-note{{alignment of first field}}
+  aligned_struct8 s8; // expected-warning{{alignment of field}}
+} TU1 __attribute__((transparent_union));
+
+typedef union {
+  char c; // expected-note{{size of first field is 8 bits}}
+  int i; // expected-warning{{size of field}}
+} TU2 __attribute__((transparent_union));
+
+typedef union {
+  float f; // expected-warning{{floating}}
+} TU3 __attribute__((transparent_union));
+
+typedef union { } TU4 __attribute__((transparent_union)); // expected-warning{{field}} 
diff --git a/test/Sema/type-spec-struct-union.c b/test/Sema/type-spec-struct-union.c
new file mode 100644
index 0000000..ce65095
--- /dev/null
+++ b/test/Sema/type-spec-struct-union.c
@@ -0,0 +1,65 @@
+// RUN: %clang_cc1 -fsyntax-only -pedantic -verify %s
+
+/* This test checks the introduction of struct and union types based
+   on a type specifier of the form "struct-or-union identifier" when they
+   type has not yet been declared. See C99 6.7.2.3p8. */
+
+typedef struct S1 {
+  union {
+    struct S2 *x;
+    struct S3 *y;
+  } u1;
+} S1;
+
+int test_struct_scope(S1 *s1, struct S2 *s2, struct S3 *s3) {
+  if (s1->u1.x == s2) return 1;
+  if (s1->u1.y == s3) return 1;
+  return 0;
+}
+
+int test_struct_scope_2(S1 *s1) {
+  struct S2 { int x; } *s2 = 0;
+  if (s1->u1.x == s2) return 1; /* expected-warning {{comparison of distinct pointer types ('struct S2 *' and 'struct S2 *')}} */
+  return 0;
+}
+
+// FIXME: We do not properly implement C99 6.2.1p4, which says that
+// the type "struct S4" declared in the function parameter list has
+// block scope within the function definition. The problem, in this
+// case, is that the code is ill-formed but we warn about the two S4's
+// being incompatible (we think they are two different types).
+int test_struct_scope_3(struct S4 * s4) { // expected-warning{{declaration of 'struct S4' will not be visible outside of this function}}
+  struct S4 { int y; } *s4_2 = 0;
+  /*  if (s4 == s4_2) return 1; */
+  return 0;
+}
+
+void f(struct S5 { int y; } s5); // expected-warning{{declaration of 'struct S5' will not be visible outside of this function}}
+
+// PR clang/3312
+struct S6 {
+        enum { BAR } e;
+};
+
+void test_S6() {
+        struct S6 a;
+        a.e = BAR;
+}
+
+// <rdar://problem/6487669>
+typedef struct z_foo_s {
+  struct bar_baz *baz;
+} z_foo;
+typedef z_foo *z_foop;
+struct bar_baz {
+  enum {
+    SQUAT, FLAG, DICT4, DICT3, DICT2, DICT1, DICT0, HOP, CHECK4, CHECK3, CHECK2, CHECK1, DONE, BAD
+  } mode;
+  int             nowrap;
+};
+void
+wizbiz_quxPoof(z)
+  z_foop       z;
+{
+  z->baz->mode = z->baz->nowrap ? HOP : SQUAT;
+}
diff --git a/test/Sema/typecheck-binop.c b/test/Sema/typecheck-binop.c
new file mode 100644
index 0000000..712dad2
--- /dev/null
+++ b/test/Sema/typecheck-binop.c
@@ -0,0 +1,27 @@
+/* RUN: %clang_cc1 %s -fsyntax-only -pedantic -verify
+ */
+struct incomplete; // expected-note{{forward declaration of 'struct incomplete'}}
+
+int sub1(int *a, double *b) { 
+  return a - b;    /* expected-error{{not pointers to compatible types}} */
+}
+
+void *sub2(struct incomplete *P) {
+  return P-4;      /* expected-error{{subtraction of pointer 'struct incomplete *' requires pointee to be a complete object type}} */
+}
+
+void *sub3(void *P) {
+  return P-4;      /* expected-warning{{GNU void* extension}} */
+}
+
+int sub4(void *P, void *Q) {
+  return P-Q;      /* expected-warning{{GNU void* extension}} */
+}
+
+int sub5(void *P, int *Q) {
+  return P-Q;      /* expected-error{{not pointers to compatible types}} */
+}
+
+int logicaland1(int a) {
+  return a && (void)a; /* expected-error{{invalid operands}} */
+}
diff --git a/test/Sema/typedef-prototype.c b/test/Sema/typedef-prototype.c
new file mode 100644
index 0000000..8372154
--- /dev/null
+++ b/test/Sema/typedef-prototype.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+typedef int unary_int_func(int arg);
+unary_int_func add_one;
+
+int add_one(int arg) {
+  return arg + 1;
+}
diff --git a/test/Sema/typedef-redef.c b/test/Sema/typedef-redef.c
new file mode 100644
index 0000000..025f65c
--- /dev/null
+++ b/test/Sema/typedef-redef.c
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+typedef const int x; // expected-note {{previous definition is here}}
+extern x a;
+typedef int x;  // expected-error {{typedef redefinition with different types}}
+extern x a;
+
+// <rdar://problem/6097585>
+int y; // expected-note 2 {{previous definition is here}}
+float y; // expected-error{{redefinition of 'y' with a different type}}
+double y; // expected-error{{redefinition of 'y' with a different type}}
diff --git a/test/Sema/typedef-retain.c b/test/Sema/typedef-retain.c
new file mode 100644
index 0000000..5b963c4
--- /dev/null
+++ b/test/Sema/typedef-retain.c
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -fno-lax-vector-conversions
+
+typedef float float4 __attribute__((vector_size(16)));
+typedef int int4 __attribute__((vector_size(16)));
+typedef int4* int4p;
+
+void test1(float4 a, int4 *result, int i) {
+    result[i] = a; // expected-error {{assigning to 'int4' from incompatible type 'float4'}}
+}
+
+void test2(float4 a, int4p result, int i) {
+    result[i] = a; // expected-error {{assigning to 'int4' from incompatible type 'float4'}}
+}
+
+// PR2039
+typedef int a[5];
+void test3() {
+  typedef const a b;
+  b r;
+  r[0]=10;  // expected-error {{read-only variable is not assignable}}
+}
+
+int test4(const a y) {
+  y[0] = 10; // expected-error {{read-only variable is not assignable}}
+}
+
+// PR2189
+int test5() {
+  const int s[5]; int t[5]; 
+  return &s == &t;   // expected-warning {{comparison of distinct pointer types}}
+}
+
+int test6() {
+  const a s; 
+  a t; 
+  return &s == &t;   // expected-warning {{comparison of distinct pointer types}}
+}
+
diff --git a/test/Sema/typedef-variable-type.c b/test/Sema/typedef-variable-type.c
new file mode 100644
index 0000000..f298968
--- /dev/null
+++ b/test/Sema/typedef-variable-type.c
@@ -0,0 +1,3 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only -pedantic
+
+typedef int (*a)[!.0]; // expected-warning{{size of static array must be an integer constant expression}}
diff --git a/test/Sema/types.c b/test/Sema/types.c
new file mode 100644
index 0000000..1770bf5
--- /dev/null
+++ b/test/Sema/types.c
@@ -0,0 +1,39 @@
+// RUN: %clang_cc1 %s -pedantic -verify -triple=x86_64-apple-darwin9
+
+// rdar://6097662
+typedef int (*T)[2];
+restrict T x;
+
+typedef int *S[2];
+restrict S y; // expected-error {{restrict requires a pointer or reference ('S' (aka 'int *[2]') is invalid)}}
+
+
+
+// int128_t is available.
+int a() {
+  __int128_t s;
+  __uint128_t t;
+}
+// but not a keyword
+int b() {
+  int __int128_t;
+  int __uint128_t;
+}
+
+
+// Array type merging should convert array size to whatever matches the target
+// pointer size.
+// rdar://6880874
+extern int i[1LL];
+int i[(short)1];
+
+enum e { e_1 };
+extern int j[sizeof(enum e)];  // expected-note {{previous definition}}
+int j[42];   // expected-error {{redefinition of 'j' with a different type}}
+
+// rdar://6880104
+_Decimal32 x;  // expected-error {{GNU decimal type extension not supported}}
+
+
+// rdar://6880951
+int __attribute__ ((vector_size (8), vector_size (8))) v;  // expected-error {{invalid vector type}}
diff --git a/test/Sema/ucn-cstring.c b/test/Sema/ucn-cstring.c
new file mode 100644
index 0000000..ac1d37f
--- /dev/null
+++ b/test/Sema/ucn-cstring.c
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only -pedantic
+
+int printf(const char *, ...);
+
+int main(void) {
+  int a[sizeof("hello \u2192 \u2603 \u2190 world") == 24 ? 1 : -1];
+  
+  printf("%s (%zd)\n", "hello \u2192 \u2603 \u2190 world", sizeof("hello \u2192 \u2603 \u2190 world"));
+  printf("%s (%zd)\n", "\U00010400\U0001D12B", sizeof("\U00010400\U0001D12B"));
+  // Some error conditions...
+  printf("%s\n", "\U"); // expected-error{{\u used with no following hex digits}}
+  printf("%s\n", "\U00"); // expected-error{{incomplete universal character name}}
+  printf("%s\n", "\U0001"); // expected-error{{incomplete universal character name}}
+  printf("%s\n", "\u0001"); // expected-error{{invalid universal character}}
+  return 0;
+}
+
diff --git a/test/Sema/unnamed-bitfield-init.c b/test/Sema/unnamed-bitfield-init.c
new file mode 100644
index 0000000..f3cc49c
--- /dev/null
+++ b/test/Sema/unnamed-bitfield-init.c
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+typedef struct {
+        int a; int : 24; char b;
+} S;
+
+S a = { 1, 2 };
diff --git a/test/Sema/unused-expr.c b/test/Sema/unused-expr.c
new file mode 100644
index 0000000..4ae0d4b
--- /dev/null
+++ b/test/Sema/unused-expr.c
@@ -0,0 +1,112 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -Wno-unreachable-code
+
+int foo(int X, int Y);
+
+double sqrt(double X);  // implicitly const because of no -fmath-errno!
+
+void bar(volatile int *VP, int *P, int A,
+         _Complex double C, volatile _Complex double VC) {
+  
+  VP == P;             // expected-warning {{expression result unused}}
+  (void)A;
+  (void)foo(1,2);      // no warning.
+  
+  A == foo(1, 2);      // expected-warning {{expression result unused}}
+
+  foo(1,2)+foo(4,3);   // expected-warning {{expression result unused}}
+
+
+  *P;                  // expected-warning {{expression result unused}}
+  *VP;                 // no warning.
+  P[4];                // expected-warning {{expression result unused}}
+  VP[4];               // no warning.
+
+  __real__ C;          // expected-warning {{expression result unused}}
+  __real__ VC;
+  
+  // We know this can't change errno because of no -fmath-errno.
+  sqrt(A);  // expected-warning {{ignoring return value of function declared with const attribute}}
+}
+
+extern void t1();
+extern void t2();
+void t3(int c) {
+  c ? t1() : t2();
+}
+
+// This shouldn't warn: the expr at the end of the stmtexpr really is used.
+int stmt_expr(int x, int y) {
+  return ({int _a = x, _b = y; _a > _b ? _a : _b; });
+}
+
+void nowarn(unsigned char* a, unsigned char* b)
+{
+  unsigned char c = 1;
+  *a |= c, *b += c;
+
+
+  // PR4633
+  int y, x;
+  ((void)0), y = x;
+}
+
+void t4(int a) {
+  int b = 0;
+
+  if (a)
+    b == 1; // expected-warning{{expression result unused}}
+  else
+    b == 2; // expected-warning{{expression result unused}}
+    
+  while (1)
+    b == 3; // expected-warning{{expression result unused}}
+
+  do
+    b == 4; // expected-warning{{expression result unused}}
+  while (1);
+  
+  for (;;)
+    b == 5; // expected-warning{{expression result unused}}
+    
+  for (b == 1;;) {} // expected-warning{{expression result unused}}
+  for (;b == 1;) {}
+  for (;;b == 1) {} // expected-warning{{expression result unused}}
+}
+
+// rdar://7186119
+int t5f(void) __attribute__((warn_unused_result));
+void t5() {
+  t5f();   // expected-warning {{ignoring return value of function declared with warn_unused_result}}
+}
+
+
+int fn1() __attribute__ ((warn_unused_result));
+int fn2() __attribute__ ((pure));
+int fn3() __attribute__ ((const));
+// rdar://6587766
+int t6() {
+  if (fn1() < 0 || fn2(2,1) < 0 || fn3(2) < 0)  // no warnings
+    return -1;
+
+  fn1();  // expected-warning {{ignoring return value of function declared with warn_unused_result attribute}}
+  fn2(92, 21);  // expected-warning {{ignoring return value of function declared with pure attribute}}
+  fn3(42);  // expected-warning {{ignoring return value of function declared with const attribute}}
+  __builtin_fabsf(0); // expected-warning {{ignoring return value of function declared with const attribute}}
+  return 0;
+}
+
+int t7 __attribute__ ((warn_unused_result)); // expected-warning {{'warn_unused_result' attribute only applies to function types}}
+
+// PR4010
+int (*fn4)(void) __attribute__ ((warn_unused_result));
+void t8() {
+  fn4(); // expected-warning {{ignoring return value of function declared with warn_unused_result attribute}}
+}
+
+void t9() __attribute__((warn_unused_result)); // expected-warning {{attribute 'warn_unused_result' cannot be applied to functions without return value}}
+
+// rdar://7410924
+void *some_function(void);
+void t10() {
+  (void*) some_function(); //expected-warning {{expression result unused; should this cast be to 'void'?}}
+}
diff --git a/test/Sema/usual-float.c b/test/Sema/usual-float.c
new file mode 100644
index 0000000..5a9ab34
--- /dev/null
+++ b/test/Sema/usual-float.c
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 %s -fsyntax-only
+
+typedef float CGFloat;
+
+extern void func(CGFloat);
+void foo(int dir, int n, int tindex) {
+  const float PI = 3.142;
+  CGFloat cgf = 3.4;
+
+  float ang = (float) tindex * (-dir*2.0f*PI/n);
+  func((CGFloat)cgf/65535.0f);
+}
diff --git a/test/Sema/va_arg_x86_32.c b/test/Sema/va_arg_x86_32.c
new file mode 100644
index 0000000..e49f0a4
--- /dev/null
+++ b/test/Sema/va_arg_x86_32.c
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -triple=i686-pc-linux-gnu %s
+
+int a() {
+  __builtin_va_arg((char*)0, int); // expected-error {{expression is not assignable}}
+  __builtin_va_arg((void*){0}, int); // expected-error {{first argument to 'va_arg' is of type 'void *'}}
+}
diff --git a/test/Sema/va_arg_x86_64.c b/test/Sema/va_arg_x86_64.c
new file mode 100644
index 0000000..9f514c1
--- /dev/null
+++ b/test/Sema/va_arg_x86_64.c
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -triple=x86_64-unknown-freebsd7.0 %s
+
+// PR2631
+char* foo(char *fmt, __builtin_va_list ap)
+{
+  return __builtin_va_arg((ap), char *);
+}
+
+// PR2692
+typedef __builtin_va_list va_list;
+static void f (char * (*g) (char **, int), char **p, ...) {
+  char *s;
+  va_list v;
+  s = g (p, __builtin_va_arg(v, int));
+}
diff --git a/test/Sema/var-redecl.c b/test/Sema/var-redecl.c
new file mode 100644
index 0000000..71d7ea1
--- /dev/null
+++ b/test/Sema/var-redecl.c
@@ -0,0 +1,62 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+int outer1; // expected-note{{previous definition is here}}
+extern int outer2; // expected-note{{previous definition is here}}
+int outer4;
+int outer4; // expected-note{{previous definition is here}}
+int outer5;
+int outer6(float); // expected-note{{previous definition is here}}
+int outer7(float);
+
+void outer_test() {
+  extern float outer1; // expected-error{{redefinition of 'outer1' with a different type}}
+  extern float outer2; // expected-error{{redefinition of 'outer2' with a different type}}
+  extern float outer3; // expected-note{{previous definition is here}}
+  double outer4;
+  extern int outer5; // expected-note{{previous definition is here}}
+  extern int outer6; // expected-error{{redefinition of 'outer6' as different kind of symbol}}
+  int outer7;
+  extern int outer8; // expected-note{{previous definition is here}}
+  extern int outer9;
+  {
+    extern int outer9; // expected-note{{previous definition is here}}
+  }
+}
+
+int outer3; // expected-error{{redefinition of 'outer3' with a different type}}
+float outer4; // expected-error{{redefinition of 'outer4' with a different type}}
+float outer5;  // expected-error{{redefinition of 'outer5' with a different type}}
+int outer8(int); // expected-error{{redefinition of 'outer8' as different kind of symbol}}
+float outer9; // expected-error{{redefinition of 'outer9' with a different type}}
+
+extern int outer13; // expected-note{{previous definition is here}}
+void outer_shadowing_test() {
+  extern int outer10;
+  extern int outer11; // expected-note{{previous definition is here}}
+  extern int outer12; // expected-note{{previous definition is here}}
+  {
+    float outer10;
+    float outer11;
+    float outer12;
+    {
+      extern int outer10; // okay
+      extern float outer11; // expected-error{{redefinition of 'outer11' with a different type}}
+      static double outer12;
+      {
+        extern float outer12; // expected-error{{redefinition of 'outer12' with a different type}}
+        extern float outer13; // expected-error{{redefinition of 'outer13' with a different type}}
+      }
+    }
+  }
+}
+
+void g18(void) { // expected-note{{'g18' declared here}}
+  extern int g19;
+}
+int *p=&g19; // expected-error{{use of undeclared identifier 'g19'}} \
+             // expected-warning{{incompatible pointer types}}
+
+// PR3645
+static int a;
+extern int a;
+int a;
diff --git a/test/Sema/varargs-x86-64.c b/test/Sema/varargs-x86-64.c
new file mode 100644
index 0000000..2cfedc1
--- /dev/null
+++ b/test/Sema/varargs-x86-64.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -triple x86_64-apple-darwin9
+
+// rdar://6726818
+void f1() {
+  const __builtin_va_list args2;
+  (void)__builtin_va_arg(args2, int); // expected-error {{first argument to 'va_arg' is of type '__builtin_va_list const' and not 'va_list'}}
+}
+
diff --git a/test/Sema/varargs.c b/test/Sema/varargs.c
new file mode 100644
index 0000000..e399f89
--- /dev/null
+++ b/test/Sema/varargs.c
@@ -0,0 +1,63 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify %s -triple x86_64-apple-darwin9
+
+void f1(int a)
+{
+    __builtin_va_list ap;
+    
+    __builtin_va_start(ap, a, a); // expected-error {{too many arguments to function}}
+    __builtin_va_start(ap, a); // expected-error {{'va_start' used in function with fixed args}}
+}
+
+void f2(int a, int b, ...)
+{
+    __builtin_va_list ap;
+    
+    __builtin_va_start(ap, 10); // expected-warning {{second parameter of 'va_start' not last named argument}}
+    __builtin_va_start(ap, a); // expected-warning {{second parameter of 'va_start' not last named argument}}
+    __builtin_va_start(ap, b);
+}
+
+void f3(float a, ...)
+{
+    __builtin_va_list ap;
+    
+    __builtin_va_start(ap, a);
+    __builtin_va_start(ap, (a));
+}
+
+
+// stdarg: PR3075
+void f4(const char *msg, ...) {
+ __builtin_va_list ap;
+ __builtin_stdarg_start((ap), (msg));
+ __builtin_va_end (ap);
+}
+
+void f5() {
+  __builtin_va_list ap;
+  __builtin_va_start(ap,ap); // expected-error {{'va_start' used in function with fixed args}}
+}
+
+void f6(int a, ...) {
+  __builtin_va_list ap;
+  __builtin_va_start(ap); // expected-error {{too few arguments to function}}
+}
+
+// PR3350
+void
+foo(__builtin_va_list authors, ...) {
+  __builtin_va_start (authors, authors);
+  (void)__builtin_va_arg(authors, int);
+  __builtin_va_end (authors);
+}
+
+void f7(int a, ...) {
+  __builtin_va_list ap;
+  __builtin_va_start(ap, a);
+  // FIXME: This error message is sub-par.
+  __builtin_va_arg(ap, int) = 1; // expected-error {{expression is not assignable}}
+  int *x = &__builtin_va_arg(ap, int); // expected-error {{address expression must be an lvalue or a function designator}}
+  __builtin_va_end(ap);
+}
+
diff --git a/test/Sema/variadic-block.c b/test/Sema/variadic-block.c
new file mode 100644
index 0000000..ba4bb71
--- /dev/null
+++ b/test/Sema/variadic-block.c
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only -fblocks
+
+#include <stdarg.h>
+
+int main(int argc, char *argv[]) {
+    
+    long (^addthem)(const char *, ...) = ^long (const char *format, ...){
+        va_list argp;
+        const char *p;
+        int i;
+        char c;
+        double d;
+        long result = 0;
+        va_start(argp, format);
+        for (p = format; *p; p++) switch (*p) {
+            case 'i':
+                i = va_arg(argp, int);
+                result += i;
+                break;
+            case 'd':
+                d = va_arg(argp, double);
+                result += (int)d;
+                break;
+            case 'c':
+                c = va_arg(argp, int);
+                result += c;
+                break;
+        }
+        return result;
+    };
+    long testresult = addthem("ii", 10, 20);
+    if (testresult != 30) {
+        return 1;
+    }
+    testresult = addthem("idc", 30, 40.0, 'a');
+    if (testresult != (70+'a')) {
+        return 1;
+    }
+    return 0;
+}
+
diff --git a/test/Sema/vector-assign.c b/test/Sema/vector-assign.c
new file mode 100644
index 0000000..05fc3b1
--- /dev/null
+++ b/test/Sema/vector-assign.c
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only -Wvector-conversions
+typedef unsigned int v2u __attribute__ ((vector_size (8)));
+typedef signed int v2s __attribute__ ((vector_size (8)));
+typedef signed int v1s __attribute__ ((vector_size (4)));
+typedef float v2f __attribute__ ((vector_size(8)));
+typedef signed short v4ss __attribute__ ((vector_size (8)));
+
+void test1() {
+  v2s v1;
+  v2u v2;
+  v1s v3;
+  v2f v4;
+  v4ss v5;
+  
+  v1 = v2; // expected-warning {{incompatible vector types assigning to 'v2s' from 'v2u'}}
+  v1 = v3; // expected-error {{assigning to 'v2s' from incompatible type 'v1s'}}
+  v1 = v4; // expected-warning {{incompatible vector types assigning to 'v2s' from 'v2f'}}
+  v1 = v5; // expected-warning {{incompatible vector types assigning to 'v2s' from 'v4ss'}}
+  
+  v2 = v1; // expected-warning {{incompatible vector types assigning to 'v2u' from 'v2s'}}
+  v2 = v3; // expected-error {{assigning to 'v2u' from incompatible type 'v1s'}}
+  v2 = v4; // expected-warning {{incompatible vector types assigning to 'v2u' from 'v2f'}}
+  v2 = v5; // expected-warning {{incompatible vector types assigning to 'v2u' from 'v4ss'}}
+  
+  v3 = v1; // expected-error {{assigning to 'v1s' from incompatible type 'v2s'}}
+  v3 = v2; // expected-error {{assigning to 'v1s' from incompatible type 'v2u'}}
+  v3 = v4; // expected-error {{assigning to 'v1s' from incompatible type 'v2f'}}
+  v3 = v5; // expected-error {{assigning to 'v1s' from incompatible type 'v4ss'}}
+  
+  v4 = v1; // expected-warning {{incompatible vector types assigning to 'v2f' from 'v2s'}}
+  v4 = v2; // expected-warning {{incompatible vector types assigning to 'v2f' from 'v2u'}}
+  v4 = v3; // expected-error {{assigning to 'v2f' from incompatible type 'v1s'}}
+  v4 = v5; // expected-warning {{incompatible vector types assigning to 'v2f' from 'v4ss'}}
+  
+  v5 = v1; // expected-warning {{incompatible vector types assigning to 'v4ss' from 'v2s'}}
+  v5 = v2; // expected-warning {{incompatible vector types assigning to 'v4ss' from 'v2u'}}
+  v5 = v3; // expected-error {{assigning to 'v4ss' from incompatible type 'v1s'}}
+  v5 = v4; // expected-warning {{incompatible vector types assigning to 'v4ss' from 'v2f'}}
+}
+
+// PR2263
+float test2(__attribute__((vector_size(16))) float a, int b) {
+   return a[b];
+}
+
+// PR4838
+typedef long long __attribute__((__vector_size__(2 * sizeof(long long))))
+longlongvec;
+
+void test3a(longlongvec *); // expected-note{{passing argument to parameter here}}
+void test3(const unsigned *src) {
+  test3a(src);  // expected-warning {{incompatible pointer types passing 'unsigned int const *' to parameter of type 'longlongvec *'}}
+}
diff --git a/test/Sema/vector-cast.c b/test/Sema/vector-cast.c
new file mode 100644
index 0000000..a717e86
--- /dev/null
+++ b/test/Sema/vector-cast.c
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -fsyntax-only %s -verify -Wvector-conversions
+
+typedef long long t1 __attribute__ ((vector_size (8)));
+typedef char t2 __attribute__ ((vector_size (16)));
+typedef float t3 __attribute__ ((vector_size (16)));
+
+void f()
+{  
+  t1 v1;
+  t2 v2;
+  t3 v3;
+  
+  v2 = (t2)v1; // -expected-error {{invalid conversion between vector type \
+'t2' and 't1' of different size}}
+  v1 = (t1)v2; // -expected-error {{invalid conversion between vector type \
+'t1' and 't2' of different size}}
+  v3 = (t3)v2;
+  
+  v1 = (t1)(char *)10; // -expected-error {{invalid conversion between vector \
+type 't1' and scalar type 'char *'}}
+  v1 = (t1)(long long)10;
+  v1 = (t1)(short)10; // -expected-error {{invalid conversion between vector \
+type 't1' and integer type 'short' of different size}}
+  
+  long long r1 = (long long)v1;
+  short r2 = (short)v1; // -expected-error {{invalid conversion between vector \
+type 't1' and integer type 'short' of different size}}
+  char *r3 = (char *)v1; // -expected-error {{invalid conversion between vector\
+ type 't1' and scalar type 'char *'}}
+}
+
+
+void f2(t2 X); // expected-note{{passing argument to parameter 'X' here}}
+
+void f3(t3 Y) {
+  f2(Y);  // expected-warning {{incompatible vector types passing 't3' to parameter of type 't2'}}
+}
+
diff --git a/test/Sema/vector-init.c b/test/Sema/vector-init.c
new file mode 100644
index 0000000..8f81adc
--- /dev/null
+++ b/test/Sema/vector-init.c
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify
+
+//typedef __attribute__(( ext_vector_type(4) ))  float float4;
+typedef float float4 __attribute__((vector_size(16)));
+
+float4 foo = (float4){ 1.0, 2.0, 3.0, 4.0 };
+
+float4 foo2 = (float4){ 1.0, 2.0, 3.0, 4.0 , 5.0 }; // expected-warning{{excess elements in vector initializer}}
+
+float4 array[] = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0};
+int array_sizecheck[(sizeof(array) / sizeof(float4)) == 3 ? 1 : -1];
+
+float4 array2[2] = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 
+                     9.0 }; // expected-warning {{excess elements in array initializer}}
+
+float4 array3[2] = { {1.0, 2.0, 3.0}, 5.0, 6.0, 7.0, 8.0,
+                     9.0 }; // expected-warning {{excess elements in array initializer}}
+
+// PR5650
+__attribute__((vector_size(16))) float f1(void) {
+  __attribute__((vector_size(16))) float vec = {0.0f, 0.0f, 0.0f};
+  return(vec);
+}
+
+__attribute__((vector_size(16))) float f2(
+    __attribute__((vector_size(16))) float a1) {
+  return(a1);
+}
+
+
+
+// PR5265
+typedef float __attribute__((ext_vector_type (3))) float3;
+int test2[sizeof(float3) == sizeof(float4) ? 1 : -1];
+
diff --git a/test/Sema/vfprintf-invalid-redecl.c b/test/Sema/vfprintf-invalid-redecl.c
new file mode 100644
index 0000000..cbf47a6
--- /dev/null
+++ b/test/Sema/vfprintf-invalid-redecl.c
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify
+// PR4290
+
+// The following declaration is not compatible with vfprintf(), but make
+// sure this isn't an error: autoconf expects this to build.
+char vfprintf(); // expected-warning {{incompatible redeclaration of library function 'vfprintf'}} expected-note {{'vfprintf' is a builtin}}
diff --git a/test/Sema/vfprintf-valid-redecl.c b/test/Sema/vfprintf-valid-redecl.c
new file mode 100644
index 0000000..14fbbc4
--- /dev/null
+++ b/test/Sema/vfprintf-valid-redecl.c
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 %s -fsyntax-only -pedantic -verify
+// PR4290
+
+// The following declaration is compatible with vfprintf, so we shouldn't
+// warn.
+int vfprintf();
diff --git a/test/Sema/vla.c b/test/Sema/vla.c
new file mode 100644
index 0000000..ebf9b88
--- /dev/null
+++ b/test/Sema/vla.c
@@ -0,0 +1,62 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only -pedantic
+
+int test1() {
+  typedef int x[test1()];  // vla
+  static int y = sizeof(x);  // expected-error {{not a compile-time constant}}
+}
+
+// PR2347
+void f (unsigned int m)
+{
+  int e[2][m];
+
+  e[0][0] = 0;
+}
+
+// PR3048
+int x = sizeof(struct{char qq[x];}); // expected-error {{fields must have a constant size}}
+
+// PR2352
+void f2(unsigned int m)
+{
+  extern int e1[2][m]; // expected-error {{variable length array declaration can not have 'extern' linkage}}
+
+  e1[0][0] = 0;
+  
+}
+
+// PR2361
+int i; 
+int c[][i]; // expected-error {{variably modified type declaration not allowed at file scope}}
+int d[i]; // expected-error {{variable length array declaration not allowed at file scope}}
+
+int (*e)[i]; // expected-error {{variably modified type declaration not allowed at file scope}}
+
+void f3()
+{
+  static int a[i]; // expected-error {{variable length array declaration can not have 'static' storage duration}}
+  extern int b[i]; // expected-error {{variable length array declaration can not have 'extern' linkage}}
+
+  extern int (*c1)[i]; // expected-error {{variably modified type declaration can not have 'extern' linkage}}
+  static int (*d)[i];
+}
+
+// PR3663
+static const unsigned array[((2 * (int)((((4) / 2) + 1.0/3.0) * (4) - 1e-8)) + 1)]; // expected-warning {{size of static array must be an integer constant expression}}
+
+int a[*]; // expected-error {{star modifier used outside of function prototype}}
+int f4(int a[*][*]);
+
+// PR2044
+int pr2044(int b) {int (*c(void))[b];**c() = 2;} // expected-error {{variably modified type}}
+int pr2044b;
+int (*pr2044c(void))[pr2044b]; // expected-error {{variably modified type}}
+
+const int f5_ci = 1;
+void f5() { char a[][f5_ci] = {""}; } // expected-error {{variable-sized object may not be initialized}}
+
+// PR5185
+void pr5185(int a[*]);
+void pr5185(int a[*]) // expected-error {{variable length array must be bound in function definition}}
+{
+}
diff --git a/test/Sema/void_arg.c b/test/Sema/void_arg.c
new file mode 100644
index 0000000..337972f
--- /dev/null
+++ b/test/Sema/void_arg.c
@@ -0,0 +1,26 @@
+/* RUN: %clang_cc1 -fsyntax-only %s -verify
+ */
+
+typedef void Void;
+
+void foo() {
+  int X;
+  
+  X = sizeof(int (void a));    // expected-error {{argument may not have 'void' type}}
+  X = sizeof(int (int, void)); // expected-error {{must be the first and only parameter}}
+  X = sizeof(int (void, ...)); // expected-error {{must be the first and only parameter}}
+
+  X = sizeof(int (Void a));    // expected-error {{argument may not have 'void' type}}
+  X = sizeof(int (int, Void)); // expected-error {{must be the first and only parameter}}
+  X = sizeof(int (Void, ...)); // expected-error {{must be the first and only parameter}}
+
+  // Accept these.
+  X = sizeof(int (void));
+  X = sizeof(int (Void));
+}
+
+// this is ok.
+void bar(Void) {
+}
+
+void f(const void);            // expected-error {{parameter must not have type qualifiers}}
diff --git a/test/Sema/warn-char-subscripts.c b/test/Sema/warn-char-subscripts.c
new file mode 100644
index 0000000..374a609
--- /dev/null
+++ b/test/Sema/warn-char-subscripts.c
@@ -0,0 +1,64 @@
+// RUN: %clang_cc1 -Wchar-subscripts -fsyntax-only -verify %s
+
+void t1() {
+  int array[1] = { 0 };
+  char subscript = 0;
+  int val = array[subscript]; // expected-warning{{array subscript is of type 'char'}}
+}
+
+void t2() {
+  int array[1] = { 0 };
+  char subscript = 0;
+  int val = subscript[array]; // expected-warning{{array subscript is of type 'char'}}
+}
+
+void t3() {
+  int *array = 0;
+  char subscript = 0;
+  int val = array[subscript]; // expected-warning{{array subscript is of type 'char'}}
+}
+
+void t4() {
+  int *array = 0;
+  char subscript = 0;
+  int val = subscript[array]; // expected-warning{{array subscript is of type 'char'}}
+}
+
+char returnsChar();
+void t5() {
+  int *array = 0;
+  int val = array[returnsChar()]; // expected-warning{{array subscript is of type 'char'}}
+}
+
+void t6() {
+  int array[1] = { 0 };
+  signed char subscript = 0;
+  int val = array[subscript]; // no warning for explicit signed char
+}
+
+void t7() {
+  int array[1] = { 0 };
+  unsigned char subscript = 0;
+  int val = array[subscript]; // no warning for unsigned char
+}
+
+typedef char CharTy;
+void t8() {
+  int array[1] = { 0 };
+  CharTy subscript = 0;
+  int val = array[subscript]; // expected-warning{{array subscript is of type 'char'}}
+}
+
+typedef signed char SignedCharTy;
+void t9() {
+  int array[1] = { 0 };
+  SignedCharTy subscript = 0;
+  int val = array[subscript]; // no warning for explicit signed char
+}
+
+typedef unsigned char UnsignedCharTy;
+void t10() {
+  int array[1] = { 0 };
+  UnsignedCharTy subscript = 0;
+  int val = array[subscript]; // no warning for unsigned char
+}
diff --git a/test/Sema/warn-freestanding-complex.c b/test/Sema/warn-freestanding-complex.c
new file mode 100644
index 0000000..14e063f
--- /dev/null
+++ b/test/Sema/warn-freestanding-complex.c
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -fsyntax-only -ffreestanding -pedantic -verify %s
+
+void foo(float _Complex c) { // expected-warning{{complex numbers are an extension in a freestanding C99 implementation}}
+}
diff --git a/test/Sema/warn-gnu-designators.c b/test/Sema/warn-gnu-designators.c
new file mode 100644
index 0000000..d5ac8cf
--- /dev/null
+++ b/test/Sema/warn-gnu-designators.c
@@ -0,0 +1,2 @@
+// RUN: %clang_cc1 -Wno-gnu-designator -verify %s
+struct { int x, y, z[12] } value = { x:17, .z [3 ... 5] = 7 };
diff --git a/test/Sema/warn-missing-braces.c b/test/Sema/warn-missing-braces.c
new file mode 100644
index 0000000..ebfe984
--- /dev/null
+++ b/test/Sema/warn-missing-braces.c
@@ -0,0 +1,3 @@
+// RUN: %clang_cc1 -fsyntax-only -Wmissing-braces -verify %s
+
+int a[2][2] = { 0, 1, 2, 3 }; // expected-warning{{suggest braces}} expected-warning{{suggest braces}}
diff --git a/test/Sema/warn-missing-prototypes.c b/test/Sema/warn-missing-prototypes.c
new file mode 100644
index 0000000..bfd1459
--- /dev/null
+++ b/test/Sema/warn-missing-prototypes.c
@@ -0,0 +1,37 @@
+// RUN: %clang -Wmissing-prototypes -fsyntax-only -Xclang -verify %s
+
+int f();
+
+int f(int x) { return x; } // expected-warning{{no previous prototype for function 'f'}}
+
+static int g(int x) { return x; }
+
+int h(int x) { return x; } // expected-warning{{no previous prototype for function 'h'}}
+
+static int g2();
+
+int g2(int x) { return x; }
+
+void test(void);
+
+int h3();
+int h4(int);
+int h4();
+
+void test(void) {
+  int h2(int x);
+  int h3(int x);
+  int h4();
+}
+
+int h2(int x) { return x; } // expected-warning{{no previous prototype for function 'h2'}}
+int h3(int x) { return x; } // expected-warning{{no previous prototype for function 'h3'}}
+int h4(int x) { return x; }
+
+int f2(int);
+int f2();
+
+int f2(int x) { return x; }
+
+// rdar://6759522
+int main(void) { return 0; }
diff --git a/test/Sema/warn-shadow.c b/test/Sema/warn-shadow.c
new file mode 100644
index 0000000..a112210
--- /dev/null
+++ b/test/Sema/warn-shadow.c
@@ -0,0 +1,50 @@
+// RUN: %clang_cc1 -verify -fsyntax-only -fblocks -Wshadow %s
+
+int i;          // expected-note 3 {{previous declaration is here}}
+
+void foo() {
+  int pass1;
+  int i;        // expected-warning {{declaration shadows a variable in the global scope}} \
+                // expected-note {{previous declaration is here}}
+  {
+    int pass2;
+    int i;      // expected-warning {{declaration shadows a local variable}} \
+                // expected-note {{previous declaration is here}}
+    {
+      int pass3;
+      int i;    // expected-warning {{declaration shadows a local variable}}
+    }
+  }
+
+  int sin; // okay; 'sin' has not been declared, even though it's a builtin.
+}
+
+// <rdar://problem/7677531>
+void (^test1)(int) = ^(int i) { // expected-warning {{declaration shadows a variable in the global scope}} \
+                                 // expected-note{{previous declaration is here}}
+  {
+    int i; // expected-warning {{declaration shadows a local variable}} \
+           // expected-note{{previous declaration is here}}
+    
+    (^(int i) { return i; })(i); //expected-warning {{declaration shadows a local variable}}
+  }
+};
+
+
+struct test2 {
+  int i;
+};
+
+void test3(void) {
+  struct test4 {
+    int i;
+  };
+}
+
+void test4(int i) { // expected-warning {{declaration shadows a variable in the global scope}}
+}
+
+// Don't warn about shadowing for function declarations.
+void test5(int i);
+void test6(void (*f)(int i)) {}
+void test7(void *context, void (*callback)(void *context)) {}
diff --git a/test/Sema/warn-unreachable.c b/test/Sema/warn-unreachable.c
new file mode 100644
index 0000000..10ed696
--- /dev/null
+++ b/test/Sema/warn-unreachable.c
@@ -0,0 +1,100 @@
+// RUN: %clang %s -fsyntax-only -Xclang -verify -fblocks -Wunreachable-code -Wno-unused-value
+
+int halt() __attribute__((noreturn));
+int live();
+int dead();
+
+void test1() {
+  goto c;
+  d:
+  goto e;       // expected-warning {{will never be executed}}
+  c: ;
+  int i;
+  return;
+  goto b;        // expected-warning {{will never be executed}}
+  goto a;        // expected-warning {{will never be executed}}
+  b:
+  i = 1;
+  a:
+  i = 2;
+  goto f;
+  e:
+  goto d;
+  f: ;
+}
+
+void test2() {
+  int i;
+  switch (live()) {
+  case 1:
+    halt(),
+      dead();   // expected-warning {{will never be executed}}
+
+  case 2:
+    live(), halt(),
+      dead();   // expected-warning {{will never be executed}}
+
+  case 3:
+  live()        // expected-warning {{will never be executed}}
+    +           
+    halt();
+  dead();
+
+  case 4:
+  a4:
+    live(),
+      halt();
+    goto a4;    // expected-warning {{will never be executed}}
+
+  case 5:
+    goto a5;
+  c5:
+    dead();     // expected-warning {{will never be executed}}
+    goto b5;
+  a5:
+    live(),
+      halt();
+  b5:
+    goto c5;
+
+  case 6:
+    if (live())
+      goto e6;
+    live(),
+      halt();
+  d6:
+    dead();     // expected-warning {{will never be executed}}
+    goto b6;
+  c6:
+    dead();
+    goto b6;
+  e6:
+    live(),
+      halt();
+  b6:
+    goto c6;
+  case 7:
+    halt()
+      +         // expected-warning {{will never be executed}}
+      dead();
+    -           // expected-warning {{will never be executed}}
+      halt();
+  case 8:
+    i
+      +=        // expected-warning {{will never be executed}}
+      halt();
+  case 9:
+    halt()
+      ?         // expected-warning {{will never be executed}}
+      dead() : dead();
+  case 10:
+    (           // expected-warning {{will never be executed}}
+      float)halt();
+  case 11: {
+    int a[5];
+    live(),
+      a[halt()
+        ];      // expected-warning {{will never be executed}}
+  }
+  }
+}
diff --git a/test/Sema/warn-unused-function.c b/test/Sema/warn-unused-function.c
new file mode 100644
index 0000000..d5e676b
--- /dev/null
+++ b/test/Sema/warn-unused-function.c
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 -fsyntax-only -Wunused-function -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -Wunused %s
+// RUN: %clang_cc1 -fsyntax-only -verify -Wall %s
+
+void foo() {}
+static void f2() {} 
+static void f1() {f2();} // expected-warning{{unused}}
+
+static int f0() { return 17; } // expected-warning{{unused}}
+int x = sizeof(f0());
+
+static void f3();
+extern void f3() { } // expected-warning{{unused}}
+
+// FIXME: This will trigger a warning when it should not.
+// Update once PR6281 is fixed.
+//inline static void f4();
+//void f4() { }
+
+static void __attribute__((used)) f5() {}
+static void f6();
+static void __attribute__((used)) f6();
+static void f6() {};
+
+static void f7(void);
+void f8(void(*a0)(void));
+void f9(void) { f8(f7); }
+static void f7(void) {}
+
+__attribute__((unused)) static void bar(void);
+void bar(void) { }
+
+__attribute__((constructor)) static void bar2(void);
+void bar2(void) { }
+
+__attribute__((destructor)) static void bar3(void);
+void bar3(void) { }
diff --git a/test/Sema/warn-unused-parameters.c b/test/Sema/warn-unused-parameters.c
new file mode 100644
index 0000000..e47ddd5
--- /dev/null
+++ b/test/Sema/warn-unused-parameters.c
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -fblocks -fsyntax-only -Wunused-parameter %s 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -fblocks -fsyntax-only -Wunused %s 2>&1 | FileCheck -check-prefix=CHECK-unused %s
+
+int f0(int x,
+       int y,
+       int z __attribute__((unused))) {
+  return x;
+}
+
+void f1() {
+  (void)^(int x,
+          int y,
+          int z __attribute__((unused))) { return x; };
+}
+
+// Used when testing '-Wunused' to see that we only emit one diagnostic, and no
+// warnings for the above cases.
+static void achor() {};
+
+// CHECK: 5:12: warning: unused parameter 'y'
+// CHECK: 12:15: warning: unused parameter 'y'
+// CHECK-unused: 1 warning generated
\ No newline at end of file
diff --git a/test/Sema/warn-unused-value.c b/test/Sema/warn-unused-value.c
new file mode 100644
index 0000000..16b787f
--- /dev/null
+++ b/test/Sema/warn-unused-value.c
@@ -0,0 +1,68 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wunused-value %s
+// RUN: %clang_cc1 -fsyntax-only -verify -Wunused %s
+// RUN: %clang_cc1 -fsyntax-only -verify -Wall %s
+
+int i = 0;
+int j = 0;
+
+void foo();
+
+// PR4806
+void pr4806() {
+  1,foo();          // expected-warning {{expression result unused}}
+
+  // other
+  foo();
+  i;                // expected-warning {{expression result unused}}
+
+  i,foo();          // expected-warning {{expression result unused}}
+  foo(),i;          // expected-warning {{expression result unused}}
+
+  i,j,foo();        // expected-warning {{expression result unused}}
+  i,foo(),j;        // expected-warning {{expression result unused}}
+  foo(),i,j;        // expected-warning {{expression result unused}}
+
+  i++;
+
+  i++,foo();
+  foo(),i++;
+
+  i++,j,foo();      // expected-warning {{expression result unused}}
+  i++,foo(),j;      // expected-warning {{expression result unused}}
+  foo(),i++,j;      // expected-warning {{expression result unused}}
+
+  i,j++,foo();      // expected-warning {{expression result unused}}
+  i,foo(),j++;      // expected-warning {{expression result unused}}
+  foo(),i,j++;      // expected-warning {{expression result unused}}
+
+  i++,j++,foo();
+  i++,foo(),j++;
+  foo(),i++,j++;
+
+  {};
+  ({});
+  ({}),foo();
+  foo(),({});
+
+  (int)1U;          // expected-warning {{expression result unused}}
+  (void)1U;
+
+  // pointer to volatile has side effect (thus no warning)
+  int* pi = &i;
+  volatile int* pj = &j;
+  *pi;              // expected-warning {{expression result unused}}
+  *pj;
+}
+
+// Don't warn about unused '||', '&&' expressions that contain assignments.
+int test_logical_foo1();
+int test_logical_foo2();
+int test_logical_foo3();
+int test_logical_bar() {
+  int x = 0;
+  (x = test_logical_foo1()) ||  // no-warning
+  (x = test_logical_foo2()) ||  // no-warning
+  (x = test_logical_foo3());    // no-warning
+  return x;
+}
+
diff --git a/test/Sema/warn-unused-variables.c b/test/Sema/warn-unused-variables.c
new file mode 100644
index 0000000..58e52b1
--- /dev/null
+++ b/test/Sema/warn-unused-variables.c
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -fsyntax-only -Wunused-variable -fblocks -verify %s
+
+struct s0 {
+	unsigned int	i;
+};
+
+int proto(int a, int b);
+
+void f0(void) {
+	int	a __attribute__((unused)),
+		b; // expected-warning{{unused}}
+	return;
+}
+
+void f1(void) {
+	int	i;
+	(void)sizeof(i);
+	return;
+}
+
+// PR5933
+int f2() {
+  int X = 4;  // Shouldn't have a bogus 'unused variable X' warning.
+  return Y + X; // expected-error {{use of undeclared identifier 'Y'}}
+}
+
+int f3() {
+  int X1 = 4; 
+  (void)(Y1 + X1); // expected-error {{use of undeclared identifier 'Y1'}}
+  (void)(^() { int X = 4; }); // expected-warning{{unused}}
+  (void)(^() { int X = 4; return Y + X; }); // expected-error {{use of undeclared identifier 'Y'}}
+}
diff --git a/test/Sema/warn-write-strings.c b/test/Sema/warn-write-strings.c
new file mode 100644
index 0000000..04af00c
--- /dev/null
+++ b/test/Sema/warn-write-strings.c
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -verify -fsyntax-only -Wwrite-strings %s
+
+// PR4804
+char* x = "foo"; // expected-warning {{initializing 'char *' with an expression of type 'char const [4]' discards qualifiers}}
diff --git a/test/Sema/wchar.c b/test/Sema/wchar.c
new file mode 100644
index 0000000..28ec2f1
--- /dev/null
+++ b/test/Sema/wchar.c
@@ -0,0 +1,22 @@
+// RUN: %clang %s -fsyntax-only -Xclang -verify
+// RUN: %clang %s -fsyntax-only -fshort-wchar -Xclang -verify -DSHORT_WCHAR
+
+typedef __WCHAR_TYPE__ wchar_t;
+
+#if defined(_WIN32) || defined(_M_IX86) || defined(__CYGWIN__) \
+ || defined(_M_X64) || defined(SHORT_WCHAR)
+  #define WCHAR_T_TYPE unsigned short
+#elif defined(__sun) || defined(__AuroraUX__)
+  #define WCHAR_T_TYPE long
+#else /* Solaris or AuroraUX. */
+  #define WCHAR_T_TYPE int
+#endif
+ 
+int check_wchar_size[sizeof(*L"") == sizeof(wchar_t) ? 1 : -1];
+ 
+void foo() {
+  WCHAR_T_TYPE t1[] = L"x";
+  wchar_t tab[] = L"x";
+  WCHAR_T_TYPE t2[] = "x";     // expected-error {{initializer}}
+  char t3[] = L"x";   // expected-error {{initializer}}
+}
diff --git a/test/Sema/x86-attr-force-align-arg-pointer.c b/test/Sema/x86-attr-force-align-arg-pointer.c
new file mode 100644
index 0000000..b406a77
--- /dev/null
+++ b/test/Sema/x86-attr-force-align-arg-pointer.c
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin10 -fsyntax-only -verify %s
+
+int a __attribute__((force_align_arg_pointer)); // expected-warning{{attribute only applies to function types}}
+
+// It doesn't matter where the attribute is located.
+void b(void) __attribute__((force_align_arg_pointer));
+void __attribute__((force_align_arg_pointer)) c(void);
+
+// Functions only have to be declared force_align_arg_pointer once.
+void b(void) {}
+
+// It doesn't matter which declaration has the attribute.
+void d(void);
+void __attribute__((force_align_arg_pointer)) d(void) {}
+
+// Attribute is ignored on function pointer types.
+void (__attribute__((force_align_arg_pointer)) *p)();
+typedef void (__attribute__((__force_align_arg_pointer__)) *p2)();
+// Attribute is also ignored on function typedefs.
+typedef void __attribute__((force_align_arg_pointer)) e(void);
+
diff --git a/test/Sema/x86-builtin-palignr.c b/test/Sema/x86-builtin-palignr.c
new file mode 100644
index 0000000..eedf99b
--- /dev/null
+++ b/test/Sema/x86-builtin-palignr.c
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -target-feature +ssse3 -verify %s
+// Temporarily xfail this on windows.
+// XFAIL: win32
+
+#include <tmmintrin.h>
+
+__m64 foo(__m64 a, __m64 b, int c)
+{
+   return _mm_alignr_pi8(a, b, c); // expected-error {{argument to '__builtin_ia32_palignr' must be a constant integer}}
+}
diff --git a/test/SemaCXX/Inputs/lit.local.cfg b/test/SemaCXX/Inputs/lit.local.cfg
new file mode 100644
index 0000000..e6f55ee
--- /dev/null
+++ b/test/SemaCXX/Inputs/lit.local.cfg
@@ -0,0 +1 @@
+config.suffixes = []
diff --git a/test/SemaCXX/Inputs/malloc.h b/test/SemaCXX/Inputs/malloc.h
new file mode 100644
index 0000000..c54d621
--- /dev/null
+++ b/test/SemaCXX/Inputs/malloc.h
@@ -0,0 +1,3 @@
+extern "C" {
+extern void *malloc (__SIZE_TYPE__ __size) throw () __attribute__ ((__malloc__)) ;
+}
diff --git a/test/SemaCXX/PR5086-ambig-resolution-enum.cpp b/test/SemaCXX/PR5086-ambig-resolution-enum.cpp
new file mode 100644
index 0000000..720566a
--- /dev/null
+++ b/test/SemaCXX/PR5086-ambig-resolution-enum.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
+
+class C {
+public:
+        enum E { e1=0 };
+        const char * fun1(int , enum E) const;
+        int fun1(unsigned, const char *) const;
+};
+
+void foo(const C& rc) {
+        enum {BUFLEN = 128 };
+        const char *p = rc.fun1(BUFLEN - 2, C::e1);
+}
diff --git a/test/SemaCXX/PR6562.cpp b/test/SemaCXX/PR6562.cpp
new file mode 100644
index 0000000..854d9b0
--- /dev/null
+++ b/test/SemaCXX/PR6562.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct X { ~X(); };
+template <typename T>
+struct A {
+  struct B { X x; };
+  struct C : public B {
+    C() : B() { }
+  };
+};
diff --git a/test/SemaCXX/PR6618.cpp b/test/SemaCXX/PR6618.cpp
new file mode 100644
index 0000000..10d4dc8
--- /dev/null
+++ b/test/SemaCXX/PR6618.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+class bar; // expected-note {{forward declaration of 'bar'}}
+struct zed {
+  bar g; // expected-error {{field has incomplete type}}
+};
+class baz {
+  zed h;
+};
+void f() {
+  enum {
+    e = sizeof(baz)
+  };
+}
diff --git a/test/SemaCXX/__null.cpp b/test/SemaCXX/__null.cpp
new file mode 100644
index 0000000..3583655
--- /dev/null
+++ b/test/SemaCXX/__null.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown %s -fsyntax-only -verify
+// RUN: %clang_cc1 -triple i686-unknown-unknown %s -fsyntax-only -verify
+
+void f() {
+  int* i = __null;
+  i = __null;
+  int i2 = __null;
+
+  // Verify statically that __null is the right size
+  int a[sizeof(typeof(__null)) == sizeof(void*)? 1 : -1];
+  
+  // Verify that null is evaluated as 0.
+  int b[__null ? -1 : 1];
+}
diff --git a/test/SemaCXX/abstract.cpp b/test/SemaCXX/abstract.cpp
new file mode 100644
index 0000000..0ae6c44
--- /dev/null
+++ b/test/SemaCXX/abstract.cpp
@@ -0,0 +1,171 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
+
+#ifndef __GXX_EXPERIMENTAL_CXX0X__
+#define __CONCAT(__X, __Y) __CONCAT1(__X, __Y)
+#define __CONCAT1(__X, __Y) __X ## __Y
+
+#define static_assert(__b, __m) \
+  typedef int __CONCAT(__sa, __LINE__)[__b ? 1 : -1]
+#endif
+
+class C {
+  virtual void f() = 0; // expected-note {{pure virtual function 'f'}}
+};
+
+static_assert(__is_abstract(C), "C has a pure virtual function");
+
+class D : C {
+};
+
+static_assert(__is_abstract(D), "D inherits from an abstract class");
+
+class E : D {
+  virtual void f();
+};
+
+static_assert(!__is_abstract(E), "E inherits from an abstract class but implements f");
+
+C *d = new C; // expected-error {{allocation of an object of abstract type 'C'}}
+
+C c; // expected-error {{variable type 'C' is an abstract class}}
+void t1(C c); // expected-error {{parameter type 'C' is an abstract class}}
+void t2(C); // expected-error {{parameter type 'C' is an abstract class}}
+
+struct S {
+  C c; // expected-error {{field type 'C' is an abstract class}}
+};
+
+void t3(const C&);
+
+void f() {
+  C(); // expected-error {{allocation of an object of abstract type 'C'}}
+  t3(C()); // expected-error {{allocation of an object of abstract type 'C'}}
+}
+
+C e1[2]; // expected-error {{variable type 'C' is an abstract class}}
+C (*e2)[2]; // expected-error {{variable type 'C' is an abstract class}}
+C (**e3)[2]; // expected-error {{variable type 'C' is an abstract class}}
+
+void t4(C c[2]); // expected-error {{parameter type 'C' is an abstract class}}
+
+void t5(void (*)(C)); // expected-error {{parameter type 'C' is an abstract class}}
+
+typedef void (*Func)(C); // expected-error {{parameter type 'C' is an abstract class}}
+void t6(Func);
+
+class F {
+  F a() { while (1) {} } // expected-error {{return type 'F' is an abstract class}}
+    
+  class D {
+    void f(F c); // expected-error {{parameter type 'F' is an abstract class}}
+  };
+
+  union U {
+    void u(F c); // expected-error {{parameter type 'F' is an abstract class}}
+  };
+    
+  virtual void f() = 0; // expected-note {{pure virtual function 'f'}}
+};
+
+class Abstract;
+
+void t7(Abstract a); // expected-error {{parameter type 'Abstract' is an abstract class}}
+
+void t8() {
+  void h(Abstract a); // expected-error {{parameter type 'Abstract' is an abstract class}}
+}
+
+namespace N {
+void h(Abstract a); // expected-error {{parameter type 'Abstract' is an abstract class}}
+}
+
+class Abstract {
+  virtual void f() = 0; // expected-note {{pure virtual function 'f'}}
+};
+
+// <rdar://problem/6854087>
+class foo {
+public:
+  virtual foo *getFoo() = 0;
+};
+
+class bar : public foo {
+public:
+  virtual bar *getFoo();
+};
+
+bar x;
+
+// <rdar://problem/6902298>
+class A {
+public:
+  virtual void release() = 0;
+  virtual void release(int count) = 0;
+  virtual void retain() = 0;
+};
+
+class B : public A {
+public:
+  virtual void release();
+  virtual void release(int count);
+  virtual void retain();
+};
+
+void foo(void) {
+  B b;
+}
+
+struct K {
+ int f;
+ virtual ~K();
+};
+
+struct L : public K {
+ void f();
+};
+
+// PR5222
+namespace PR5222 {
+  struct A {
+    virtual A *clone() = 0;
+  };
+  struct B : public A {
+    virtual B *clone() = 0;
+  };
+  struct C : public B {
+    virtual C *clone();
+  };
+
+  C c;  
+}
+
+// PR5550 - instantiating template didn't track overridden methods
+namespace PR5550 {
+  struct A {
+    virtual void a() = 0;
+    virtual void b() = 0;
+  };
+  template<typename T> struct B : public A {
+    virtual void b();
+    virtual void c() = 0;
+  };
+  struct C : public B<int> {
+    virtual void a();
+    virtual void c();
+  }; 
+  C x;
+}
+
+namespace PureImplicit {
+  // A pure virtual destructor should be implicitly overridden.
+  struct A { virtual ~A() = 0; };
+  struct B : A {};
+  B x;
+
+  // A pure virtual assignment operator should be implicitly overridden.
+  struct D;
+  struct C { virtual D& operator=(const D&) = 0; };
+  struct D : C {};
+  D y;
+}
+
diff --git a/test/SemaCXX/access-base-class.cpp b/test/SemaCXX/access-base-class.cpp
new file mode 100644
index 0000000..8551690
--- /dev/null
+++ b/test/SemaCXX/access-base-class.cpp
@@ -0,0 +1,91 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+namespace T1 {
+  
+class A { };
+class B : private A { }; // expected-note {{declared private here}}
+
+void f(B* b) {
+  A *a = b; // expected-error{{cannot cast 'T1::B' to its private base class 'T1::A'}}
+}
+
+}
+
+namespace T2 { 
+
+class A { };
+class B : A { }; // expected-note {{implicitly declared private here}}
+
+void f(B* b) {
+  A *a = b; // expected-error {{cannot cast 'T2::B' to its private base class 'T2::A'}}
+}
+
+}
+
+namespace T3 {
+
+class A { };
+class B : public A { }; 
+
+void f(B* b) {
+  A *a = b;
+}
+
+}
+
+namespace T4 {
+
+class A {};
+
+class B : private virtual A {};
+class C : public virtual A {};
+
+class D : public B, public C {};
+
+void f(D *d) {
+  // This takes the D->C->B->A path.
+  A *a = d;
+}
+
+}
+
+namespace T5 {
+  class A {};
+    
+  class B : private A {
+    void f(B *b) {
+      A *a = b;
+    }
+  };    
+}
+
+namespace T6 {
+  class C;
+  
+  class A {};
+  
+  class B : private A { // expected-note {{declared private here}} expected-note {{constrained by private inheritance here}}
+    void f(C* c);
+  };
+  
+  class C : public B { 
+    void f(C *c) {
+      A* a = c; // expected-error {{cannot cast 'T6::C' to its private base class 'T6::A'}} \
+                // expected-error {{'A' is a private member of 'T6::A'}}
+    }
+  };
+  
+  void B::f(C *c) {
+    A *a = c;
+  }
+}
+
+namespace T7 {
+  class A {};
+  class B : public A {};
+  class C : private B { 
+    void f(C *c) {
+      A* a = c; // okay
+    }
+  };
+}
+
diff --git a/test/SemaCXX/access-control-check.cpp b/test/SemaCXX/access-control-check.cpp
new file mode 100644
index 0000000..4540e99
--- /dev/null
+++ b/test/SemaCXX/access-control-check.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+class M {
+  int iM;
+};
+
+class P {
+  int iP; // expected-note {{declared private here}}
+  int PPR(); // expected-note {{declared private here}}
+};
+
+class N : M,P {
+  N() {}
+  int PR() { return iP + PPR(); } // expected-error 2 {{private member of 'P'}}
+};
diff --git a/test/SemaCXX/access.cpp b/test/SemaCXX/access.cpp
new file mode 100644
index 0000000..6115ff6
--- /dev/null
+++ b/test/SemaCXX/access.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+class C {
+    struct S; // expected-note {{previously declared 'private' here}}
+public:
+    
+    struct S {}; // expected-error {{'S' redeclared with 'public' access}}
+};
+
+struct S {
+    class C; // expected-note {{previously declared 'public' here}}
+    
+private:
+    class C { }; // expected-error {{'C' redeclared with 'private' access}}
+};
+
+class T {
+protected:
+    template<typename T> struct A; // expected-note {{previously declared 'protected' here}}
+    
+private:
+    template<typename T> struct A {}; // expected-error {{'A' redeclared with 'private' access}}
+};
+
+// PR5573
+namespace test1 {
+  class A {
+  private:
+    class X; // expected-note {{previously declared 'private' here}}
+  public:
+    class X; // expected-error {{ 'X' redeclared with 'public' access}}
+    class X {};
+  };
+}
diff --git a/test/SemaCXX/addr-of-overloaded-function.cpp b/test/SemaCXX/addr-of-overloaded-function.cpp
new file mode 100644
index 0000000..f8b00df
--- /dev/null
+++ b/test/SemaCXX/addr-of-overloaded-function.cpp
@@ -0,0 +1,88 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s 
+int f(double);
+int f(int);
+
+int (*pfd)(double) = f; // selects f(double)
+int (*pfd2)(double) = &f; // selects f(double)
+int (*pfd3)(double) = ((&((f)))); // selects f(double)
+int (*pfi)(int) = &f;    // selects f(int)
+// FIXME: This error message is not very good. We need to keep better
+// track of what went wrong when the implicit conversion failed to
+// give a better error message here.
+int (*pfe)(...) = &f;    // expected-error{{cannot initialize a variable of type 'int (*)(...)' with an rvalue of type '<overloaded function type>'}}
+int (&rfi)(int) = f;     // selects f(int)
+int (&rfd)(double) = f;  // selects f(double)
+
+void g(int (*fp)(int));   // expected-note{{note: candidate function}}
+void g(int (*fp)(float));
+void g(int (*fp)(double)); // expected-note{{note: candidate function}}
+
+int g1(int);
+int g1(char);
+
+int g2(int);
+int g2(double);
+
+template<typename T> T g3(T);
+int g3(int);
+int g3(char);
+
+void g_test() {
+  g(g1);
+  g(g2); // expected-error{{call to 'g' is ambiguous; candidates are:}}
+  g(g3);
+}
+
+template<typename T> T h1(T);
+template<typename R, typename A1> R h1(A1);
+int h1(char);
+
+void ha(int (*fp)(int));
+void hb(int (*fp)(double));
+
+void h_test() {
+  ha(h1);
+  hb(h1);
+}
+
+struct A { };
+void f(void (*)(A *));
+
+struct B
+{
+  void g() { f(d); }
+  void d(void *);
+  static void d(A *);
+};
+
+struct C {
+  C &getC() {
+    return makeAC; // expected-error{{address of overloaded function 'makeAC' cannot be converted to type 'C'}}
+  }
+
+  C &makeAC();
+  const C &makeAC() const;
+
+  static void f(); // expected-note{{candidate function}}
+  static void f(int); // expected-note{{candidate function}}
+
+  void g() {
+    int (&fp)() = f; // expected-error{{address of overloaded function 'f' does not match required type 'int ()'}}
+  }
+};
+
+// PR6886
+namespace test0 {
+  void myFunction(void (*)(void *));
+
+  class Foo {
+    void foo();
+
+    static void bar(void*);
+    static void bar();
+  };
+
+  void Foo::foo() {
+    myFunction(bar);
+  }
+}
diff --git a/test/SemaCXX/address-of-temporary.cpp b/test/SemaCXX/address-of-temporary.cpp
new file mode 100644
index 0000000..decdc95
--- /dev/null
+++ b/test/SemaCXX/address-of-temporary.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fsyntax-only -Wno-error=address-of-temporary -verify %s
+struct X { 
+  X();
+  X(int);
+  X(int, int);
+};
+
+void *f0() { return &X(); } // expected-warning{{taking the address of a temporary object}}
+void *f1() { return &X(1); } // expected-warning{{taking the address of a temporary object}}
+void *f2() { return &X(1, 2); } // expected-warning{{taking the address of a temporary object}}
+void *f3() { return &(X)1; } // expected-warning{{taking the address of a temporary object}}
+
diff --git a/test/SemaCXX/address-of.cpp b/test/SemaCXX/address-of.cpp
new file mode 100644
index 0000000..a7e712b
--- /dev/null
+++ b/test/SemaCXX/address-of.cpp
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// PR clang/3175
+
+void bar(int*);
+
+class c {
+  int var;
+  static int svar;
+  void foo() { 
+    bar(&var); 
+    bar(&svar);  
+  }
+
+  static void wibble() {
+    bar(&var); // expected-error{{invalid use of member 'var' in static member function}}
+    bar(&svar); 
+  }
+};
+
+enum E {
+  Enumerator
+};
+
+void test() {
+  (void)&Enumerator; // expected-error{{address expression must be an lvalue or a function designator}}
+}
+
+template<int N>
+void test2() {
+  (void)&N; // expected-error{{address expression must be an lvalue or a function designator}}
+}
+
+// PR clang/3222
+void xpto();
+void (*xyz)(void) = &xpto;
diff --git a/test/SemaCXX/aggregate-initialization.cpp b/test/SemaCXX/aggregate-initialization.cpp
new file mode 100644
index 0000000..4c34447
--- /dev/null
+++ b/test/SemaCXX/aggregate-initialization.cpp
@@ -0,0 +1,82 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s 
+
+// Verify that we can't initialize non-aggregates with an initializer
+// list.
+struct NonAggr1 {
+  NonAggr1(int) { }
+
+  int m;
+};
+
+struct Base { };
+struct NonAggr2 : public Base {
+  int m;
+};
+
+class NonAggr3 {
+  int m;
+};
+
+struct NonAggr4 {
+  int m;
+  virtual void f();
+};
+
+NonAggr1 na1 = { 17 }; // expected-error{{non-aggregate type 'NonAggr1' cannot be initialized with an initializer list}}
+NonAggr2 na2 = { 17 }; // expected-error{{non-aggregate type 'NonAggr2' cannot be initialized with an initializer list}}
+NonAggr3 na3 = { 17 }; // expected-error{{non-aggregate type 'NonAggr3' cannot be initialized with an initializer list}}
+NonAggr4 na4 = { 17 }; // expected-error{{non-aggregate type 'NonAggr4' cannot be initialized with an initializer list}}
+
+// PR5817
+typedef int type[][2];
+const type foo = {0};
+
+// Vector initialization.
+typedef short __v4hi __attribute__ ((__vector_size__ (8)));
+__v4hi v1 = { (void *)1, 2, 3 }; // expected-error {{cannot initialize a vector element of type 'short' with an rvalue of type 'void *'}}
+
+// Array initialization.
+int a[] = { (void *)1 }; // expected-error {{cannot initialize an array element of type 'int' with an rvalue of type 'void *'}}
+
+// Struct initialization.
+struct S { int a; } s = { (void *)1 }; // expected-error {{cannot initialize a member subobject of type 'int' with an rvalue of type 'void *'}}
+
+// Check that we're copy-initializing the structs.
+struct A {
+  A();
+  A(int);
+  ~A();
+  
+  A(const A&) = delete; // expected-note 2 {{function has been explicitly marked deleted here}}
+};
+
+struct B {
+  A a;
+};
+
+struct C {
+  const A& a;
+};
+
+void f() {
+  A as1[1] = { };
+  A as2[1] = { 1 }; // expected-error {{copying array element of type 'A' invokes deleted constructor}}
+
+  B b1 = { };
+  B b2 = { 1 }; // expected-error {{copying member subobject of type 'A' invokes deleted constructor}}
+  
+  C c1 = { 1 };
+}
+
+class Agg {
+public:
+  int i, j;
+};
+
+class AggAgg {
+public:
+  Agg agg1;
+  Agg agg2;
+};
+
+AggAgg aggagg = { 1, 2, 3, 4 };
diff --git a/test/SemaCXX/alignof-sizeof-reference.cpp b/test/SemaCXX/alignof-sizeof-reference.cpp
new file mode 100644
index 0000000..f02282d
--- /dev/null
+++ b/test/SemaCXX/alignof-sizeof-reference.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+struct s0; // expected-note {{forward declaration}}
+char ar[sizeof(s0&)]; // expected-error {{invalid application of 'sizeof' to an incomplete type}}
+void test() {
+  char &r = ar[0];
+  static_assert(alignof(r) == 1, "bad alignment");
+  static_assert(sizeof(r) == 1, "bad size");
+}
diff --git a/test/SemaCXX/ambig-user-defined-conversions.cpp b/test/SemaCXX/ambig-user-defined-conversions.cpp
new file mode 100644
index 0000000..7f67674
--- /dev/null
+++ b/test/SemaCXX/ambig-user-defined-conversions.cpp
@@ -0,0 +1,58 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace test0 {
+  struct BASE { 
+    operator int &(); // expected-note {{candidate function}}
+  }; 
+  struct BASE1 { 
+    operator int &(); // expected-note {{candidate function}}
+  }; 
+
+  struct B : public BASE, BASE1 {};
+
+  extern B f(); 
+  B b1;
+
+  void func(const int ci, const char cc); // expected-note {{candidate function}}
+  void func(const char ci, const B b); // expected-note {{candidate function}}
+  void func(const B b, const int ci); // expected-note {{candidate function}}
+
+  const int Test1() {
+    func(b1, f()); // expected-error {{call to 'func' is ambiguous}}
+    return f(); // expected-error {{conversion from 'test0::B' to 'int const' is ambiguous}}
+  }
+
+  // This used to crash when comparing the two operands.
+  void func2(const char cc); // expected-note {{candidate function}}
+  void func2(const int ci); // expected-note {{candidate function}}
+  void Test2() {
+    func2(b1); // expected-error {{call to 'func2' is ambiguous}}
+  }
+}
+
+namespace test1 {
+  struct E;
+  struct A { 
+    A (E&); 
+  };
+
+  struct E { 
+    operator A (); 
+  };
+
+  struct C { 
+    C (E&);  
+  };
+
+  void f1(A);	// expected-note {{candidate function}}
+  void f1(C);	// expected-note {{candidate function}}
+
+  void Test2()
+  {
+    E b;
+    f1(b);  // expected-error {{call to 'f1' is ambiguous}}	
+            // ambiguous because b -> C via constructor and
+            // b → A via constructor or conversion function.
+  }
+}
+
diff --git a/test/SemaCXX/ambiguous-builtin-unary-operator.cpp b/test/SemaCXX/ambiguous-builtin-unary-operator.cpp
new file mode 100644
index 0000000..1aa09a6
--- /dev/null
+++ b/test/SemaCXX/ambiguous-builtin-unary-operator.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
+
+struct A {
+  operator int&();
+  operator long*& ();
+};
+
+struct B {
+  operator long&();
+  operator int*& ();
+};
+
+struct C : B, A { };
+
+void test(C c) {
+  ++c; // expected-error {{use of overloaded operator '++' is ambiguous}}\
+       // expected-note {{built-in candidate operator++(int &)}} \
+       // expected-note {{built-in candidate operator++(long &)}} \
+       // expected-note {{built-in candidate operator++(long *&)}} \
+       // expected-note {{built-in candidate operator++(int *&)}}
+}
+
+struct A1 { operator volatile int&(); };
+
+struct B1 { operator volatile long&(); };
+
+struct C1 : B1, A1 { };
+
+void test(C1 c) {
+  ++c;	// expected-error {{use of overloaded operator '++' is ambiguous}} \
+	// expected-note {{built-in candidate operator++(int volatile &)}} \
+	// expected-note {{built-in candidate operator++(long volatile &)}}
+}
+
diff --git a/test/SemaCXX/anonymous-union.cpp b/test/SemaCXX/anonymous-union.cpp
new file mode 100644
index 0000000..5c34e01
--- /dev/null
+++ b/test/SemaCXX/anonymous-union.cpp
@@ -0,0 +1,123 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+struct X {
+  union {
+    float f3;
+    double d2;
+  } named;
+
+  union {
+    int i;
+    float f;
+    
+    union {
+      float f2;
+      mutable double d;
+    };
+  };
+
+  void test_unqual_references();
+
+  struct {
+    int a;
+    float b;
+  };
+
+  void test_unqual_references_const() const;
+
+  mutable union { // expected-error{{anonymous union at class scope must not have a storage specifier}}
+    float c1;
+    double c2;
+  };
+};
+
+void X::test_unqual_references() {
+  i = 0;
+  f = 0.0;
+  f2 = f;
+  d = f;
+  f3 = 0; // expected-error{{use of undeclared identifier 'f3'}}
+  a = 0;
+}
+
+void X::test_unqual_references_const() const {
+  d = 0.0;
+  f2 = 0; // expected-error{{read-only variable is not assignable}}
+  a = 0; // expected-error{{read-only variable is not assignable}}
+}
+
+void test_unqual_references(X x, const X xc) {
+  x.i = 0;
+  x.f = 0.0;
+  x.f2 = x.f;
+  x.d = x.f;
+  x.f3 = 0; // expected-error{{no member named 'f3'}}
+  x.a = 0;
+
+  xc.d = 0.0;
+  xc.f = 0; // expected-error{{read-only variable is not assignable}}
+  xc.a = 0; // expected-error{{read-only variable is not assignable}}
+}
+
+
+struct Redecl {
+  int x; // expected-note{{previous declaration is here}}
+  class y { };
+
+  union {
+    int x; // expected-error{{member of anonymous union redeclares 'x'}}
+    float y;
+    double z; // expected-note{{previous declaration is here}}
+    double zz; // expected-note{{previous definition is here}}
+  };
+
+  int z; // expected-error{{duplicate member 'z'}}
+  void zz(); // expected-error{{redefinition of 'zz' as different kind of symbol}}
+};
+
+union { // expected-error{{anonymous unions at namespace or global scope must be declared 'static'}}
+  int int_val;
+  float float_val;
+};
+
+static union {
+  int int_val2;
+  float float_val2;
+};
+
+void f() {
+  int_val2 = 0;
+  float_val2 = 0.0;
+}
+
+void g() {
+  union {
+    int i;
+    float f2;
+  };
+  i = 0;
+  f2 = 0.0;
+}
+
+struct BadMembers {
+  union {
+    struct X { }; // expected-error {{types cannot be declared in an anonymous union}}
+    struct { int x; int y; } y;
+    
+    void f(); // expected-error{{functions cannot be declared in an anonymous union}}
+  private: int x1; // expected-error{{anonymous union cannot contain a private data member}}
+  protected: float x2; // expected-error{{anonymous union cannot contain a protected data member}}
+  };
+};
+
+// <rdar://problem/6481130>
+typedef union { }; // expected-warning{{declaration does not declare anything}}
+
+// <rdar://problem/7562438>
+typedef struct objc_module *Foo ;
+
+typedef struct _s {
+    union {
+        int a;
+        int Foo;
+    };
+} s, *ps;
diff --git a/test/SemaCXX/array-bound-merge.cpp b/test/SemaCXX/array-bound-merge.cpp
new file mode 100644
index 0000000..74f58fa
--- /dev/null
+++ b/test/SemaCXX/array-bound-merge.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// PR5515
+
+extern int a[];
+int a[10];
+extern int b[10];
+int b[];
+extern int c[1];
+int c[] = {1,2}; // expected-error {{excess elements in array initializer}}
diff --git a/test/SemaCXX/arrow-operator.cpp b/test/SemaCXX/arrow-operator.cpp
new file mode 100644
index 0000000..29b23ed
--- /dev/null
+++ b/test/SemaCXX/arrow-operator.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+struct T { 
+  void f();
+};
+
+struct A {
+  T* operator->(); // expected-note{{candidate function}}
+};
+
+struct B {
+  T* operator->(); // expected-note{{candidate function}}
+};
+
+struct C : A, B {
+};
+
+struct D : A { };
+
+struct E; // expected-note {{forward declaration of 'E'}}
+
+void f(C &c, D& d, E& e) {
+  c->f(); // expected-error{{use of overloaded operator '->' is ambiguous}}
+  d->f();
+  e->f(); // expected-error{{incomplete definition of type}}
+}
diff --git a/test/SemaCXX/attr-after-definition.cpp b/test/SemaCXX/attr-after-definition.cpp
new file mode 100644
index 0000000..148a63e
--- /dev/null
+++ b/test/SemaCXX/attr-after-definition.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+struct X { };
+struct Y { };
+
+bool f0(X) { return true; } // expected-note{{definition}}
+bool f1(X) { return true; }
+
+__attribute__ ((__visibility__("hidden"))) bool f0(X); // expected-warning{{attribute}}
+__attribute__ ((__visibility__("hidden"))) bool f1(Y);
diff --git a/test/SemaCXX/attr-cxx0x.cpp b/test/SemaCXX/attr-cxx0x.cpp
new file mode 100644
index 0000000..8fbf50c
--- /dev/null
+++ b/test/SemaCXX/attr-cxx0x.cpp
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s
+
+int final_fail [[final]]; //expected-error {{'final' attribute only applies to virtual method or class types}}
+
+struct [[final]] final_base { }; // expected-note {{'final_base' declared here}}
+struct final_child : final_base { }; // expected-error {{derivation from 'final' struct final_base}}
+
+struct final_member { virtual void quux [[final]] (); }; // expected-note {{overridden virtual function is here}}
+struct final_override : final_member { virtual void quux (); }; // expected-error {{declaration of 'quux' overrides a 'final' function}}
+
+int align_illegal [[align(3)]]; //expected-error {{requested alignment is not a power of 2}}
+char align_big [[align(int)]];
+int align_small [[align(1)]];
+int align_multiple [[align(1), align(8), align(1)]];
+
+struct align_member {
+  int member [[align(8)]];
+};
+
+static_assert(alignof(align_big) == alignof(int), "k's alignment is wrong");
+static_assert(alignof(align_small) == alignof(int), "j's alignment is wrong");
+static_assert(alignof(align_multiple) == 8, "l's alignment is wrong");
+static_assert(alignof(align_member) == 8, "quuux's alignment is wrong");
+static_assert(sizeof(align_member) == 8, "quuux's size is wrong");
+
+int bc_fail [[base_check]]; // expected-error {{'base_check' attribute only applies to class types}}
+int hiding_fail [[hiding]]; // expected-error {{'hiding' attribute only applies to member types}}
+int override_fail [[override]]; // expected-error {{'override' attribute only applies to virtual method types}}
+
+struct base {
+  virtual void function();
+  virtual void other_function();
+};
+
+struct [[base_check, base_check]] bc : base { // expected-error {{'base_check' attribute cannot be repeated}}
+};
diff --git a/test/SemaCXX/attr-deprecated.cpp b/test/SemaCXX/attr-deprecated.cpp
new file mode 100644
index 0000000..d5662d3
--- /dev/null
+++ b/test/SemaCXX/attr-deprecated.cpp
@@ -0,0 +1,66 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only
+class A {
+  void f() __attribute__((deprecated));
+  void g(A* a);
+  void h(A* a) __attribute__((deprecated));
+
+  int b __attribute__((deprecated));
+};
+
+void A::g(A* a)
+{
+  f(); // expected-warning{{'f' is deprecated}}
+  a->f(); // expected-warning{{'f' is deprecated}}
+  
+  (void)b; // expected-warning{{'b' is deprecated}}
+  (void)a->b; // expected-warning{{'b' is deprecated}}
+}
+
+void A::h(A* a)
+{
+  f();
+  a->f();
+  
+  (void)b;
+  (void)a->b;
+}
+
+struct B {
+  virtual void f() __attribute__((deprecated));
+  void g();
+};
+
+void B::g() {
+  f();
+  B::f(); // expected-warning{{'f' is deprecated}}
+}
+
+struct C : B {
+  virtual void f();
+  void g();
+};
+
+void C::g() {
+  f();
+  C::f();
+  B::f(); // expected-warning{{'f' is deprecated}}
+}
+
+void f(B* b, C *c) {
+  b->f();
+  b->B::f(); // expected-warning{{'f' is deprecated}}
+  
+  c->f();
+  c->C::f();
+  c->B::f(); // expected-warning{{'f' is deprecated}}
+}
+
+struct D {
+  virtual void f() __attribute__((deprecated));
+};
+
+void D::f() { }
+
+void f(D* d) {
+  d->f();
+}
diff --git a/test/SemaCXX/attr-format.cpp b/test/SemaCXX/attr-format.cpp
new file mode 100644
index 0000000..0c1eb53
--- /dev/null
+++ b/test/SemaCXX/attr-format.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+struct S {
+  static void f(const char*, ...) __attribute__((format(printf, 1, 2)));
+
+  // GCC has a hidden 'this' argument in member functions which is why
+  // the format argument is argument 2 here.
+  void g(const char*, ...) __attribute__((format(printf, 2, 3)));
+};
diff --git a/test/SemaCXX/attr-noreturn.cpp b/test/SemaCXX/attr-noreturn.cpp
new file mode 100644
index 0000000..b7d3999
--- /dev/null
+++ b/test/SemaCXX/attr-noreturn.cpp
@@ -0,0 +1,39 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// PR5620
+void f0() __attribute__((__noreturn__));
+void f1(void (*)()); 
+void f2() { f1(f0); }
+
+// Taking the address of a noreturn function
+void test_f0a() {
+  void (*fp)() = f0;
+  void (*fp1)() __attribute__((noreturn)) = f0;
+}
+
+// Taking the address of an overloaded noreturn function 
+void f0(int) __attribute__((__noreturn__));
+
+void test_f0b() {
+  void (*fp)() = f0;
+  void (*fp1)() __attribute__((noreturn)) = f0;
+}
+
+// No-returned function pointers
+typedef void (* noreturn_fp)() __attribute__((noreturn));
+
+void f3(noreturn_fp); // expected-note{{candidate function}}
+
+void test_f3() {
+  f3(f0); // okay
+  f3(f2); // expected-error{{no matching function for call}}
+}
+
+
+class xpto {
+  int blah() __attribute__((noreturn));
+};
+
+int xpto::blah() {
+  return 3; // expected-warning {{function 'blah' declared 'noreturn' should not return}}
+}
diff --git a/test/SemaCXX/attr-sentinel.cpp b/test/SemaCXX/attr-sentinel.cpp
new file mode 100644
index 0000000..56c8f88
--- /dev/null
+++ b/test/SemaCXX/attr-sentinel.cpp
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+void f(int, ...) __attribute__((sentinel));
+
+void g() {
+  f(1, 2, __null);
+}
diff --git a/test/SemaCXX/attr-unavailable.cpp b/test/SemaCXX/attr-unavailable.cpp
new file mode 100644
index 0000000..8b381df
--- /dev/null
+++ b/test/SemaCXX/attr-unavailable.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+int &foo(int); // expected-note {{candidate}}
+double &foo(double); // expected-note {{candidate}}
+void foo(...) __attribute__((__unavailable__)); // expected-note {{candidate function}} \
+// expected-note{{function has been explicitly marked unavailable here}}
+
+void bar(...) __attribute__((__unavailable__)); // expected-note 2{{explicitly marked unavailable}}
+
+void test_foo(short* sp) {
+  int &ir = foo(1);
+  double &dr = foo(1.0);
+  foo(sp); // expected-error{{call to unavailable function 'foo'}}
+
+  void (*fp)(...) = &bar; // expected-warning{{'bar' is unavailable}}
+  void (*fp2)(...) = bar; // expected-warning{{'bar' is unavailable}}
+
+  int &(*fp3)(int) = foo;
+  void (*fp4)(...) = foo; // expected-warning{{'foo' is unavailable}}
+}
diff --git a/test/SemaCXX/attr-weakref.cpp b/test/SemaCXX/attr-weakref.cpp
new file mode 100644
index 0000000..5773acc
--- /dev/null
+++ b/test/SemaCXX/attr-weakref.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// GCC will accept anything as the argument of weakref. Should we
+// check for an existing decl?
+static int a1() __attribute__((weakref ("foo")));
+static int a2() __attribute__((weakref, alias ("foo")));
+
+static int a3 __attribute__((weakref ("foo")));
+static int a4 __attribute__((weakref, alias ("foo")));
+
+// gcc rejects, clang accepts
+static int a5 __attribute__((alias ("foo"), weakref));
+
+// this is pointless, but accepted by gcc. We reject it.
+static int a6 __attribute__((weakref)); //expected-error {{weakref declaration of 'a6' must also have an alias attribute}}
+
+// gcc warns, clang rejects
+void f(void) {
+  static int a __attribute__((weakref ("v2"))); // expected-error {{declaration of 'a' must be in a global context}}
+}
+
+// both gcc and clang reject
+class c {
+  static int a __attribute__((weakref ("v2"))); // expected-error {{declaration of 'a' must be in a global context}}
+  static int b() __attribute__((weakref ("f3"))); // expected-error {{declaration of 'b' must be in a global context}}
+};
+int a7() __attribute__((weakref ("f1"))); // expected-error {{declaration of 'a7' must be static}}
+int a8 __attribute__((weakref ("v1"))); // expected-error {{declaration of 'a8' must be static}}
+
+// gcc accepts this
+int a9 __attribute__((weakref)); // expected-error {{declaration of 'a9' must be static}}
diff --git a/test/SemaCXX/auto-cxx0x.cpp b/test/SemaCXX/auto-cxx0x.cpp
new file mode 100644
index 0000000..654acb5
--- /dev/null
+++ b/test/SemaCXX/auto-cxx0x.cpp
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
+void f() {
+  auto int a; // expected-error{{cannot combine with previous 'auto' declaration specifier}} // expected-error{{declaration of variable 'a' with type 'auto' requires an initializer}}
+  int auto b; // expected-error{{cannot combine with previous 'int' declaration specifier}}
+}
diff --git a/test/SemaCXX/auto-cxx98.cpp b/test/SemaCXX/auto-cxx98.cpp
new file mode 100644
index 0000000..fe02811
--- /dev/null
+++ b/test/SemaCXX/auto-cxx98.cpp
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++98
+void f() {
+  auto int a;
+  int auto b;
+}
diff --git a/test/SemaCXX/bitfield-layout.cpp b/test/SemaCXX/bitfield-layout.cpp
new file mode 100644
index 0000000..adecf55
--- /dev/null
+++ b/test/SemaCXX/bitfield-layout.cpp
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify -triple=x86_64-apple-darwin10
+
+#define CHECK_SIZE(name, size) extern int name##1[sizeof(name) == size ? 1 : -1];
+#define CHECK_ALIGN(name, size) extern int name##2[__alignof(name) == size ? 1 : -1];
+
+// Simple tests.
+struct Test1 {
+  char c : 9; // expected-warning {{size of bit-field 'c' (9 bits) exceeds the size of its type; value will be truncated to 8 bits}}
+};
+CHECK_SIZE(Test1, 2);
+CHECK_ALIGN(Test1, 1);
+
+struct Test2 {
+  char c : 16; // expected-warning {{size of bit-field 'c' (16 bits) exceeds the size of its type; value will be truncated to 8 bits}}
+};
+CHECK_SIZE(Test2, 2);
+CHECK_ALIGN(Test2, 2);
+
+struct Test3 {
+  char c : 32; // expected-warning {{size of bit-field 'c' (32 bits) exceeds the size of its type; value will be truncated to 8 bits}}
+};
+CHECK_SIZE(Test3, 4);
+CHECK_ALIGN(Test3, 4);
+
+struct Test4 {
+  char c : 64; // expected-warning {{size of bit-field 'c' (64 bits) exceeds the size of its type; value will be truncated to 8 bits}}
+};
+CHECK_SIZE(Test4, 8);
+CHECK_ALIGN(Test4, 8);
+
diff --git a/test/SemaCXX/blocks-1.cpp b/test/SemaCXX/blocks-1.cpp
new file mode 100644
index 0000000..d93997a
--- /dev/null
+++ b/test/SemaCXX/blocks-1.cpp
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -fblocks
+
+extern "C" int exit(int);
+
+typedef struct {
+    unsigned long ps[30];
+    int qs[30];
+} BobTheStruct;
+
+int main (int argc, const char * argv[]) {
+    BobTheStruct inny;
+    BobTheStruct outty;
+    BobTheStruct (^copyStruct)(BobTheStruct);
+    int i;
+    
+    for(i=0; i<30; i++) {
+        inny.ps[i] = i * i * i;
+        inny.qs[i] = -i * i * i;
+    }
+    
+    copyStruct = ^(BobTheStruct aBigStruct){ return aBigStruct; };  // pass-by-value intrinsically copies the argument
+    
+    outty = copyStruct(inny);
+
+    if ( &inny == &outty ) {
+        exit(1);
+    }
+    for(i=0; i<30; i++) {
+        if ( (inny.ps[i] != outty.ps[i]) || (inny.qs[i] != outty.qs[i]) ) {
+            exit(1);
+        }
+    }
+    
+    return 0;
+}
diff --git a/test/SemaCXX/blocks.cpp b/test/SemaCXX/blocks.cpp
new file mode 100644
index 0000000..9429543
--- /dev/null
+++ b/test/SemaCXX/blocks.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -fblocks
+
+void tovoid(void*);
+
+void tovoid_test(int (^f)(int, int)) {
+  tovoid(f);
+}
+
+void reference_lvalue_test(int& (^f)()) {
+  f() = 10;
+}
diff --git a/test/SemaCXX/bool.cpp b/test/SemaCXX/bool.cpp
new file mode 100644
index 0000000..44e17ce
--- /dev/null
+++ b/test/SemaCXX/bool.cpp
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s 
+
+// Bool literals can be enum values.
+enum {
+  ReadWrite = false,
+  ReadOnly = true
+};
+
+// bool cannot be decremented, and gives a warning on increment
+void test(bool b)
+{
+  ++b; // expected-warning {{incrementing expression of type bool is deprecated}}
+  b++; // expected-warning {{incrementing expression of type bool is deprecated}}
+  --b; // expected-error {{cannot decrement expression of type bool}}
+  b--; // expected-error {{cannot decrement expression of type bool}}
+
+  bool *b1 = (int *)0; // expected-error{{cannot initialize}}
+}
+
+// static_assert_arg_is_bool(x) compiles only if x is a bool.
+template <typename T>
+void static_assert_arg_is_bool(T x) {
+  bool* p = &x;
+}
+
+void test2() {
+  int n = 2;
+  static_assert_arg_is_bool(n && 4);
+  static_assert_arg_is_bool(n || 5);
+}
diff --git a/test/SemaCXX/builtin-exception-spec.cpp b/test/SemaCXX/builtin-exception-spec.cpp
new file mode 100644
index 0000000..324d20e
--- /dev/null
+++ b/test/SemaCXX/builtin-exception-spec.cpp
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -isystem %S/Inputs -fsyntax-only -verify %s
+#include <malloc.h>
+
+extern "C" {
+void *malloc(__SIZE_TYPE__);
+}
diff --git a/test/SemaCXX/builtin-ptrtomember-ambig.cpp b/test/SemaCXX/builtin-ptrtomember-ambig.cpp
new file mode 100644
index 0000000..3e0dfbb
--- /dev/null
+++ b/test/SemaCXX/builtin-ptrtomember-ambig.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
+
+struct A {};
+
+struct R {
+    operator const A*();
+};
+
+
+struct B  : R {
+    operator A*();
+};
+
+struct C : B {
+
+};
+
+
+void foo(C c, int A::* pmf) {
+       				// FIXME. Why so many built-in candidates?
+	int i = c->*pmf; 	// expected-error {{use of overloaded operator '->*' is ambiguous}} \
+				// expected-note {{built-in candidate operator->*(struct A const *, int const struct A::*)}} \
+				// expected-note {{built-in candidate operator->*(struct A const *, int struct A::*)}} \
+				// expected-note {{built-in candidate operator->*(struct A *, int const struct A::*)}} \
+				// expected-note {{built-in candidate operator->*(struct A *, int struct A::*)}}
+}
+
diff --git a/test/SemaCXX/builtin-ptrtomember-overload-1.cpp b/test/SemaCXX/builtin-ptrtomember-overload-1.cpp
new file mode 100644
index 0000000..f736394
--- /dev/null
+++ b/test/SemaCXX/builtin-ptrtomember-overload-1.cpp
@@ -0,0 +1,46 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
+
+struct A {};
+struct E {};
+
+struct R {
+    operator A*();
+    operator E*();	// expected-note{{candidate function}}
+};
+
+
+struct S {
+    operator A*();
+    operator E*();	// expected-note{{candidate function}}
+};
+
+struct B  : R {
+    operator A*();
+};
+
+struct C : B {
+
+};
+
+void foo(C c, int A::* pmf) {
+	int i = c->*pmf; 
+}
+
+struct B1  : R, S {
+    operator A*();
+};
+
+struct C1 : B1 {
+
+};
+
+void foo1(C1 c1, int A::* pmf) {
+        int i = c1->*pmf;
+        c1->*pmf = 10;
+}
+
+void foo1(C1 c1, int E::* pmf) {
+        int i = c1->*pmf;	// expected-error {{use of overloaded operator '->*' is ambiguous}} \
+                                // expected-note {{because of ambiguity in conversion of 'C1' to 'E *'}} \
+                                // expected-note 4 {{built-in candidate operator}}
+}
diff --git a/test/SemaCXX/builtin-ptrtomember-overload.cpp b/test/SemaCXX/builtin-ptrtomember-overload.cpp
new file mode 100644
index 0000000..6c13236
--- /dev/null
+++ b/test/SemaCXX/builtin-ptrtomember-overload.cpp
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
+
+struct A {};
+
+struct B {
+	operator A*();
+};
+
+struct C : B {
+
+};
+
+
+void foo(C c, B b, int A::* pmf) {
+	int j = c->*pmf; 
+	int i = b->*pmf;
+}
+
+struct D {
+ operator const D *();
+};
+
+struct DPtr {
+ operator volatile int D::*();
+};
+
+int test(D d, DPtr dptr) {
+ return d->*dptr;
+}
+
diff --git a/test/SemaCXX/builtins.cpp b/test/SemaCXX/builtins.cpp
new file mode 100644
index 0000000..568ba5d
--- /dev/null
+++ b/test/SemaCXX/builtins.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify
+typedef const struct __CFString * CFStringRef;
+#define CFSTR __builtin___CFStringMakeConstantString
+
+void f() {
+  (void)CFStringRef(CFSTR("Hello"));
+}
+
+void a() { __builtin_va_list x, y; ::__builtin_va_copy(x, y); }
diff --git a/test/SemaCXX/c99.cpp b/test/SemaCXX/c99.cpp
new file mode 100644
index 0000000..f4c3639
--- /dev/null
+++ b/test/SemaCXX/c99.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+void f0(int i) {
+  char array[i]; // expected-error{{variable length arrays}}
+}
+
+void f1(int i[static 5]) { // expected-error{{C99}}
+}
diff --git a/test/SemaCXX/cast-conversion.cpp b/test/SemaCXX/cast-conversion.cpp
new file mode 100644
index 0000000..d68e789
--- /dev/null
+++ b/test/SemaCXX/cast-conversion.cpp
@@ -0,0 +1,46 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
+
+struct R {
+  R(int);
+};
+
+struct A {
+  A(R);
+};
+
+struct B {
+  B(A);
+};
+
+int main () {
+  B(10);	// expected-error {{functional-style cast from 'int' to 'B' is not allowed}}
+  (B)10;	// expected-error {{C-style cast from 'int' to 'B' is not allowed}}
+  static_cast<B>(10);	// expected-error {{static_cast from 'int' to 'B' is not allowed}} \\
+			// expected-warning {{expression result unused}}
+}
+
+template<class T>
+struct X0 {
+  X0(const T &);
+};
+
+template<class T>
+X0<T> make_X0(const T &Val) {
+  return X0<T>(Val);
+}
+
+void test_X0() {
+  const char array[2] = { 'a', 'b' };
+  make_X0(array);
+}
+
+// PR5210 recovery
+class C {
+protected:
+  template <int> float* &f0(); // expected-note{{candidate}}
+  template <unsigned> float* &f0(); // expected-note{{candidate}}
+
+  void f1() {
+    static_cast<float*>(f0<0>()); // expected-error{{ambiguous}}
+  }
+};
diff --git a/test/SemaCXX/cast-explicit-ctor.cpp b/test/SemaCXX/cast-explicit-ctor.cpp
new file mode 100644
index 0000000..0052856
--- /dev/null
+++ b/test/SemaCXX/cast-explicit-ctor.cpp
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+struct B { explicit B(bool); };
+void f() { 
+  (void)(B)true;
+  (void)B(true); 
+}
diff --git a/test/SemaCXX/class-base-member-init.cpp b/test/SemaCXX/class-base-member-init.cpp
new file mode 100644
index 0000000..ca9f045
--- /dev/null
+++ b/test/SemaCXX/class-base-member-init.cpp
@@ -0,0 +1,76 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+class S {
+public:
+  S (); 
+};
+
+struct D : S {
+  D() : 
+    b1(0), // expected-note {{previous initialization is here}}
+    b2(1),
+    b1(0), // expected-error {{multiple initializations given for non-static member 'b1'}}
+    S(),   // expected-note {{previous initialization is here}}
+    S()    // expected-error {{multiple initializations given for base 'S'}}
+    {}
+  int b1;
+  int b2;
+};
+
+struct A {
+  struct {
+    int a;
+    int b; 
+  };
+  A();
+};
+
+A::A() : a(10), b(20) { }
+
+namespace Test1 {
+  template<typename T> struct A {};
+  template<typename T> struct B : A<T> {
+
+    B() : A<T>(), // expected-note {{previous initialization is here}} 
+      A<T>() { } // expected-error {{multiple initializations given for base 'A<T>'}}
+  };
+}
+
+namespace Test2 {
+  template<typename T> struct A : T {
+    A() : T(), // expected-note {{previous initialization is here}}
+      T() { } // expected-error {{multiple initializations given for base 'T'}}
+  };
+}
+
+namespace Test3 {
+  template<typename T> struct A {
+    T t;
+    
+    A() : t(1), // expected-note {{previous initialization is here}}
+      t(2) { } // expected-error {{multiple initializations given for non-static member 't'}}
+  };
+}
+
+namespace test4 {
+  class A {
+    union {
+      struct {
+        int a;
+        int b;
+      };
+
+      int c;
+
+      union {
+        int d;
+        int e;
+      };
+    };
+
+    A(char _) : a(0), b(0) {}
+    A(short _) : a(0), c(0) {} // expected-error {{initializing multiple members of anonymous union}} expected-note {{previous initialization is here}}
+    A(int _) : d(0), e(0) {} // expected-error {{initializing multiple members of anonymous union}} expected-note {{previous initialization is here}}
+    A(long _) : a(0), d(0) {} // expected-error {{initializing multiple members of anonymous union}} expected-note {{previous initialization is here}}
+  };
+}
diff --git a/test/SemaCXX/class-layout.cpp b/test/SemaCXX/class-layout.cpp
new file mode 100644
index 0000000..f3c75f4
--- /dev/null
+++ b/test/SemaCXX/class-layout.cpp
@@ -0,0 +1,73 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown %s -fsyntax-only -verify 
+
+#define SA(n, p) int a##n[(p) ? 1 : -1]
+
+struct A {
+  int a;
+  char b;
+};
+
+SA(0, sizeof(A) == 8);
+
+struct B : A {
+  char c;
+};
+
+SA(1, sizeof(B) == 12);
+
+struct C {
+// Make fields private so C won't be a POD type.
+private:
+  int a;
+  char b;
+};
+
+SA(2, sizeof(C) == 8);
+
+struct D : C {
+  char c;
+};
+
+SA(3, sizeof(D) == 8);
+
+struct __attribute__((packed)) E {
+  char b;
+  int a;
+};
+
+SA(4, sizeof(E) == 5);
+
+struct __attribute__((packed)) F : E {
+  char d;
+};
+
+SA(5, sizeof(F) == 6);
+
+struct G { G(); };
+struct H : G { };
+
+SA(6, sizeof(H) == 1);
+
+struct I {
+  char b;
+  int a;
+} __attribute__((packed));
+
+SA(6_1, sizeof(I) == 5);
+
+// PR5580
+namespace PR5580 {
+
+class A { bool iv0 : 1; };
+SA(7, sizeof(A) == 1);  
+
+class B : A { bool iv0 : 1; };
+SA(8, sizeof(B) == 2);
+
+struct C { bool iv0 : 1; };
+SA(9, sizeof(C) == 1);  
+
+struct D : C { bool iv0 : 1; };
+SA(10, sizeof(D) == 2);
+
+}
diff --git a/test/SemaCXX/class-names.cpp b/test/SemaCXX/class-names.cpp
new file mode 100644
index 0000000..2962988
--- /dev/null
+++ b/test/SemaCXX/class-names.cpp
@@ -0,0 +1,52 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+class C { };
+
+C c;
+
+void D(int);
+
+class D {};
+
+void foo()
+{
+  D(5);
+  class D d;
+}
+
+class D; // expected-note {{previous use is here}}
+
+enum D; // expected-error {{use of 'D' with tag type that does not match previous declaration}}
+
+class A * A;
+
+class A * a2;
+
+void bar()
+{
+  A = 0;
+}
+
+void C(int);
+
+void bar2()
+{
+  C(17);
+}
+
+extern int B;
+class B;
+class B {};
+int B;
+
+enum E { e1_val };
+E e1;
+
+void E(int);
+
+void bar3() {
+  E(17);
+}
+
+enum E e2;
+
+enum E2 { E2 };
diff --git a/test/SemaCXX/class.cpp b/test/SemaCXX/class.cpp
new file mode 100644
index 0000000..7eea67a
--- /dev/null
+++ b/test/SemaCXX/class.cpp
@@ -0,0 +1,138 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s 
+class C {
+public:
+  auto int errx; // expected-error {{error: storage class specified for a member declaration}}
+  register int erry; // expected-error {{error: storage class specified for a member declaration}}
+  extern int errz; // expected-error {{error: storage class specified for a member declaration}}
+
+  static void sm() {
+    sx = 0;
+    this->x = 0; // expected-error {{error: invalid use of 'this' outside of a nonstatic member function}}
+    x = 0; // expected-error {{error: invalid use of member 'x' in static member function}}
+  }
+
+  class NestedC {
+    void m() {
+      sx = 0;
+      x = 0; // expected-error {{error: invalid use of nonstatic data member 'x'}}
+    }
+  };
+
+  int b : 1, w : 2;
+  int : 1, : 2;
+  typedef int E : 1; // expected-error {{typedef member 'E' cannot be a bit-field}}
+  static int sb : 1; // expected-error {{error: static member 'sb' cannot be a bit-field}}
+  static int vs;
+
+  typedef int func();
+  func tm;
+  func *ptm;
+  func btm : 1; // expected-error {{bit-field 'btm' has non-integral type}}
+  NestedC bc : 1; // expected-error {{bit-field 'bc' has non-integral type}}
+
+  enum E1 { en1, en2 };
+
+  int i = 0; // expected-error {{error: 'i' can only be initialized if it is a static const integral data member}}
+  static int si = 0; // expected-error {{error: 'si' can only be initialized if it is a static const integral data member}}
+  static const NestedC ci = 0; // expected-error {{error: 'ci' can only be initialized if it is a static const integral data member}}
+  static const int nci = vs; // expected-error {{in-class initializer is not an integral constant expression}}
+  static const int vi = 0;
+  static const E evi = 0;
+
+  void m() {
+    sx = 0;
+    this->x = 0;
+    y = 0;
+    this = 0; // expected-error {{error: expression is not assignable}}
+  }
+
+  int f1(int p) {
+    A z = 6;
+    return p + x + this->y + z;
+  }
+
+  typedef int A;
+
+  virtual int viv; // expected-error {{'virtual' can only appear on non-static member functions}}
+  virtual static int vsif(); // expected-error {{error: 'virtual' can only appear on non-static member functions}}
+  virtual int vif();
+
+private:
+  int x,y;
+  static int sx;
+
+  mutable int mi;
+  mutable int &mir; // expected-error {{error: 'mutable' cannot be applied to references}}
+  mutable void mfn(); // expected-error {{error: 'mutable' cannot be applied to functions}}
+  mutable const int mci; // expected-error {{error: 'mutable' and 'const' cannot be mixed}}
+
+  static const int number = 50;
+  static int arr[number];
+};
+
+class C2 {
+  void f() {
+    static int lx;
+    class LC1 {
+      int m() { return lx; }
+    };
+    class LC2 {
+      int m() { return lx; }
+    };
+  }
+};
+
+struct C3 {
+  int i;
+  mutable int j;
+};
+void f()
+{
+  const C3 c3 = { 1, 2 };
+  (void)static_cast<int*>(&c3.i); // expected-error {{static_cast from 'int const *' to 'int *' is not allowed}}
+  // but no error here
+  (void)static_cast<int*>(&c3.j);
+}
+
+// Play with mutable a bit more, to make sure it doesn't crash anything.
+mutable int gi; // expected-error {{error: 'mutable' can only be applied to member variables}}
+mutable void gfn(); // expected-error {{illegal storage class on function}}
+void ogfn()
+{
+  mutable int ml; // expected-error {{error: 'mutable' can only be applied to member variables}}
+
+  // PR3020: This used to crash due to double ownership of C4.
+  struct C4;
+  C4; // expected-warning {{declaration does not declare anything}}
+}
+
+struct C4 {
+  void f(); // expected-note{{previous declaration is here}}
+  int f; // expected-error{{duplicate member 'f'}}
+};
+
+// PR5415 - don't hang!
+struct S
+{
+  void f(); // expected-note 1 {{previous declaration}}
+  void S::f() {} // expected-error {{class member cannot be redeclared}} expected-note {{previous declaration}} expected-note {{previous definition}}
+  void f() {} // expected-error {{class member cannot be redeclared}} expected-error {{redefinition}}
+};
+
+// Don't crash on this bogus code.
+namespace pr6629 {
+  // TODO: most of these errors are spurious
+  template<class T1, class T2> struct foo :
+    bogus<foo<T1,T2> > // expected-error {{unknown template name 'bogus'}} \
+                       // BOGUS expected-error {{expected '{' after base class list}} \
+                       // BOGUS expected-error {{expected ';' after struct}} \
+                       // BOGUS expected-error {{expected unqualified-id}} \
+  { };
+
+  template<> struct foo<unknown,unknown> { // why isn't there an error here?
+    template <typename U1, typename U2> struct bar {
+      typedef bar type;
+      static const int value = 0;
+    };
+  };
+}
diff --git a/test/SemaCXX/comma.cpp b/test/SemaCXX/comma.cpp
new file mode 100644
index 0000000..79ff7d1
--- /dev/null
+++ b/test/SemaCXX/comma.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// PR6076
+void f();
+void (&g)() = (void(), f);
+
+int a[1];
+int (&b)[1] = (void(), a);
diff --git a/test/SemaCXX/compare.cpp b/test/SemaCXX/compare.cpp
new file mode 100644
index 0000000..cd243e3
--- /dev/null
+++ b/test/SemaCXX/compare.cpp
@@ -0,0 +1,200 @@
+// Force x86-64 because some of our heuristics are actually based
+// on integer sizes.
+
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -fsyntax-only -pedantic -verify -Wsign-compare %s
+
+int test0(long a, unsigned long b) {
+  enum EnumA {A};
+  enum EnumB {B};
+  enum EnumC {C = 0x10000};
+  return
+         // (a,b)
+         (a == (unsigned long) b) +  // expected-warning {{comparison of integers of different signs}}
+         (a == (unsigned int) b) +
+         (a == (unsigned short) b) +
+         (a == (unsigned char) b) +
+         ((long) a == b) +  // expected-warning {{comparison of integers of different signs}}
+         ((int) a == b) +  // expected-warning {{comparison of integers of different signs}}
+         ((short) a == b) +  // expected-warning {{comparison of integers of different signs}}
+         ((signed char) a == b) +  // expected-warning {{comparison of integers of different signs}}
+         ((long) a == (unsigned long) b) +  // expected-warning {{comparison of integers of different signs}}
+         ((int) a == (unsigned int) b) +  // expected-warning {{comparison of integers of different signs}}
+         ((short) a == (unsigned short) b) +  // expected-warning {{comparison of integers of different signs}}
+         ((signed char) a == (unsigned char) b) +  // expected-warning {{comparison of integers of different signs}}
+         (a < (unsigned long) b) +  // expected-warning {{comparison of integers of different signs}}
+         (a < (unsigned int) b) +
+         (a < (unsigned short) b) +
+         (a < (unsigned char) b) +
+         ((long) a < b) +  // expected-warning {{comparison of integers of different signs}}
+         ((int) a < b) +  // expected-warning {{comparison of integers of different signs}}
+         ((short) a < b) +  // expected-warning {{comparison of integers of different signs}}
+         ((signed char) a < b) +  // expected-warning {{comparison of integers of different signs}}
+         ((long) a < (unsigned long) b) +  // expected-warning {{comparison of integers of different signs}}
+         ((int) a < (unsigned int) b) +  // expected-warning {{comparison of integers of different signs}}
+         ((short) a < (unsigned short) b) +  // expected-warning {{comparison of integers of different signs}}
+         ((signed char) a < (unsigned char) b) +  // expected-warning {{comparison of integers of different signs}}
+
+         // (A,b)
+         (A == (unsigned long) b) +
+         (A == (unsigned int) b) +
+         (A == (unsigned short) b) +
+         (A == (unsigned char) b) +
+         ((long) A == b) +
+         ((int) A == b) +
+         ((short) A == b) +
+         ((signed char) A == b) +
+         ((long) A == (unsigned long) b) +
+         ((int) A == (unsigned int) b) +
+         ((short) A == (unsigned short) b) +
+         ((signed char) A == (unsigned char) b) +
+         (A < (unsigned long) b) +
+         (A < (unsigned int) b) +
+         (A < (unsigned short) b) +
+         (A < (unsigned char) b) +
+         ((long) A < b) +
+         ((int) A < b) +
+         ((short) A < b) +
+         ((signed char) A < b) +
+         ((long) A < (unsigned long) b) +
+         ((int) A < (unsigned int) b) +
+         ((short) A < (unsigned short) b) +
+         ((signed char) A < (unsigned char) b) +
+
+         // (a,B)
+         (a == (unsigned long) B) +
+         (a == (unsigned int) B) +
+         (a == (unsigned short) B) +
+         (a == (unsigned char) B) +
+         ((long) a == B) +
+         ((int) a == B) +
+         ((short) a == B) +
+         ((signed char) a == B) +
+         ((long) a == (unsigned long) B) +
+         ((int) a == (unsigned int) B) +
+         ((short) a == (unsigned short) B) +
+         ((signed char) a == (unsigned char) B) +
+         (a < (unsigned long) B) +  // expected-warning {{comparison of integers of different signs}}
+         (a < (unsigned int) B) +
+         (a < (unsigned short) B) +
+         (a < (unsigned char) B) +
+         ((long) a < B) +
+         ((int) a < B) +
+         ((short) a < B) +
+         ((signed char) a < B) +
+         ((long) a < (unsigned long) B) +  // expected-warning {{comparison of integers of different signs}}
+         ((int) a < (unsigned int) B) +  // expected-warning {{comparison of integers of different signs}}
+         ((short) a < (unsigned short) B) +  // expected-warning {{comparison of integers of different signs}}
+         ((signed char) a < (unsigned char) B) +  // expected-warning {{comparison of integers of different signs}}
+
+         // (C,b)
+         (C == (unsigned long) b) +
+         (C == (unsigned int) b) +
+         (C == (unsigned short) b) +
+         (C == (unsigned char) b) +
+         ((long) C == b) +
+         ((int) C == b) +
+         ((short) C == b) +
+         ((signed char) C == b) +
+         ((long) C == (unsigned long) b) +
+         ((int) C == (unsigned int) b) +
+         ((short) C == (unsigned short) b) +
+         ((signed char) C == (unsigned char) b) +
+         (C < (unsigned long) b) +
+         (C < (unsigned int) b) +
+         (C < (unsigned short) b) +
+         (C < (unsigned char) b) +
+         ((long) C < b) +
+         ((int) C < b) +
+         ((short) C < b) +
+         ((signed char) C < b) +
+         ((long) C < (unsigned long) b) +
+         ((int) C < (unsigned int) b) +
+         ((short) C < (unsigned short) b) +
+         ((signed char) C < (unsigned char) b) +
+
+         // (a,C)
+         (a == (unsigned long) C) +
+         (a == (unsigned int) C) +
+         (a == (unsigned short) C) +
+         (a == (unsigned char) C) +
+         ((long) a == C) +
+         ((int) a == C) +
+         ((short) a == C) +
+         ((signed char) a == C) +
+         ((long) a == (unsigned long) C) +
+         ((int) a == (unsigned int) C) +
+         ((short) a == (unsigned short) C) +
+         ((signed char) a == (unsigned char) C) +
+         (a < (unsigned long) C) +  // expected-warning {{comparison of integers of different signs}}
+         (a < (unsigned int) C) +
+         (a < (unsigned short) C) +
+         (a < (unsigned char) C) +
+         ((long) a < C) +
+         ((int) a < C) +
+         ((short) a < C) +
+         ((signed char) a < C) +
+         ((long) a < (unsigned long) C) +  // expected-warning {{comparison of integers of different signs}}
+         ((int) a < (unsigned int) C) +  // expected-warning {{comparison of integers of different signs}}
+         ((short) a < (unsigned short) C) +  // expected-warning {{comparison of integers of different signs}}
+         ((signed char) a < (unsigned char) C) +  // expected-warning {{comparison of integers of different signs}}
+
+         // (0x80000,b)
+         (0x80000 == (unsigned long) b) +
+         (0x80000 == (unsigned int) b) +
+         (0x80000 == (unsigned short) b) +
+         (0x80000 == (unsigned char) b) +
+         ((long) 0x80000 == b) +
+         ((int) 0x80000 == b) +
+         ((short) 0x80000 == b) +
+         ((signed char) 0x80000 == b) +
+         ((long) 0x80000 == (unsigned long) b) +
+         ((int) 0x80000 == (unsigned int) b) +
+         ((short) 0x80000 == (unsigned short) b) +
+         ((signed char) 0x80000 == (unsigned char) b) +
+         (0x80000 < (unsigned long) b) +
+         (0x80000 < (unsigned int) b) +
+         (0x80000 < (unsigned short) b) +
+         (0x80000 < (unsigned char) b) +
+         ((long) 0x80000 < b) +
+         ((int) 0x80000 < b) +
+         ((short) 0x80000 < b) +
+         ((signed char) 0x80000 < b) +
+         ((long) 0x80000 < (unsigned long) b) +
+         ((int) 0x80000 < (unsigned int) b) +
+         ((short) 0x80000 < (unsigned short) b) +
+         ((signed char) 0x80000 < (unsigned char) b) +
+
+         // (a,0x80000)
+         (a == (unsigned long) 0x80000) +
+         (a == (unsigned int) 0x80000) +
+         (a == (unsigned short) 0x80000) +
+         (a == (unsigned char) 0x80000) +
+         ((long) a == 0x80000) +
+         ((int) a == 0x80000) +
+         ((short) a == 0x80000) +
+         ((signed char) a == 0x80000) +
+         ((long) a == (unsigned long) 0x80000) +
+         ((int) a == (unsigned int) 0x80000) +
+         ((short) a == (unsigned short) 0x80000) +
+         ((signed char) a == (unsigned char) 0x80000) +
+         (a < (unsigned long) 0x80000) +  // expected-warning {{comparison of integers of different signs}}
+         (a < (unsigned int) 0x80000) +
+         (a < (unsigned short) 0x80000) +
+         (a < (unsigned char) 0x80000) +
+         ((long) a < 0x80000) +
+         ((int) a < 0x80000) +
+         ((short) a < 0x80000) +
+         ((signed char) a < 0x80000) +
+         ((long) a < (unsigned long) 0x80000) +  // expected-warning {{comparison of integers of different signs}}
+         ((int) a < (unsigned int) 0x80000) +  // expected-warning {{comparison of integers of different signs}}
+         ((short) a < (unsigned short) 0x80000) +  // expected-warning {{comparison of integers of different signs}}
+         ((signed char) a < (unsigned char) 0x80000) +  // expected-warning {{comparison of integers of different signs}}
+
+         10
+    ;
+}
+
+int test1(int i) {
+  enum en { zero };
+  return i > zero;
+}
diff --git a/test/SemaCXX/complex-overload.cpp b/test/SemaCXX/complex-overload.cpp
new file mode 100644
index 0000000..2c057ac
--- /dev/null
+++ b/test/SemaCXX/complex-overload.cpp
@@ -0,0 +1,50 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+char *foo(float);
+
+void test_foo_1(float fv, double dv, float _Complex fc, double _Complex dc) {
+  char *cp1 = foo(fv);
+  char *cp2 = foo(dv);
+  // Note: GCC and EDG reject these two, but they are valid C99 conversions
+  char *cp3 = foo(fc);
+  char *cp4 = foo(dc);
+}
+
+int *foo(float _Complex);
+
+void test_foo_2(float fv, double dv, float _Complex fc, double _Complex dc) {
+  char *cp1 = foo(fv);
+  char *cp2 = foo(dv);
+  int *ip = foo(fc);
+  int *lp = foo(dc);
+}
+
+long *foo(double _Complex);
+
+void test_foo_3(float fv, double dv, float _Complex fc, double _Complex dc) {
+  char *cp1 = foo(fv);
+  char *cp2 = foo(dv);
+  int *ip = foo(fc);
+  long *lp = foo(dc);
+}
+
+char *promote_or_convert(double _Complex);  // expected-note{{candidate function}}
+int *promote_or_convert(long double _Complex); // expected-note{{candidate function}} 
+
+void test_promote_or_convert(float f, float _Complex fc) {
+  char *cp = promote_or_convert(fc);
+  int *ip2 = promote_or_convert(f); // expected-error{{call to 'promote_or_convert' is ambiguous; candidates are:}}
+}
+
+char *promote_or_convert2(float);
+int *promote_or_convert2(double _Complex);
+
+void test_promote_or_convert2(float _Complex fc) {
+  int *cp = promote_or_convert2(fc);
+}
+
+char *promote_or_convert3(int _Complex);
+int *promote_or_convert3(long _Complex);
+
+void test_promote_or_convert3(short _Complex sc) {
+  char *cp = promote_or_convert3(sc);
+}
diff --git a/test/SemaCXX/composite-pointer-type.cpp b/test/SemaCXX/composite-pointer-type.cpp
new file mode 100644
index 0000000..e8b0920
--- /dev/null
+++ b/test/SemaCXX/composite-pointer-type.cpp
@@ -0,0 +1,60 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+class Base { };
+class Derived1 : public Base { };
+class Derived2 : public Base { };
+
+void f0(volatile Base *b, Derived1 *d1, const Derived2 *d2) {
+  if (b > d1)
+    return;
+  if (d1 <= b)
+    return;
+  if (b > d2)
+    return;
+  if (d1 >= d2) // expected-error{{comparison of distinct}}
+    return;
+}
+
+void f1(volatile Base *b, Derived1 *d1, const Derived2 *d2) {
+  if (b == d1)
+    return;
+  if (d1 == b)
+    return;
+  if (b != d2)
+    return;
+  if (d1 == d2) // expected-error{{comparison of distinct}}
+    return;
+}
+
+// PR4691
+int ptrcmp1(void *a, int *b) {
+  return a < b;
+}
+int ptrcmp2(long *a, int *b) {
+  return a < b; // expected-error{{distinct}}
+}
+
+// PR5509 - Multi-level pointers
+int f2() {
+  typedef int *IntPtr;
+  typedef IntPtr *IntPtrPtr;
+  typedef IntPtr const *IntPtrConstPtr;
+  IntPtrConstPtr i = 0;
+  IntPtrPtr j = 0;
+  return i != j;
+}
+
+// PR5763
+typedef double Matrix4[4][4];
+
+bool f(Matrix4 m1, const Matrix4 m2) {
+  return m1 != m2;
+}
+
+// PR6346
+bool f1(bool b, void **p, const void **q) {
+  if (p == q) // expected-warning{{comparison of distinct pointer types ('void **' and 'void const **') uses non-standard composite pointer type 'void const *const *'}}
+    return false;
+
+  return b? p : q; // expected-warning{{incompatible operand types ('void **' and 'void const **') use non-standard composite pointer type 'void const *const *'}}
+}
diff --git a/test/SemaCXX/condition.cpp b/test/SemaCXX/condition.cpp
new file mode 100644
index 0000000..daa86f6
--- /dev/null
+++ b/test/SemaCXX/condition.cpp
@@ -0,0 +1,44 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s 
+
+void test() {
+  int x;
+  if (x) ++x;
+  if (int x=0) ++x;
+
+  typedef int arr[10];
+  while (arr x=0) ; // expected-error {{an array type is not allowed here}} expected-error {{array initializer must be an initializer list}}
+  while (int f()=0) ; // expected-error {{a function type is not allowed here}}
+
+  struct S {} s;
+  if (s) ++x; // expected-error {{value of type 'struct S' is not contextually convertible to 'bool'}}
+  while (struct S x=s) ; // expected-error {{value of type 'struct S' is not contextually convertible to 'bool'}}
+  do ; while (s); // expected-error {{value of type 'struct S' is not contextually convertible to 'bool'}}
+  for (;s;) ; // expected-error {{value of type 'struct S' is not contextually convertible to 'bool'}}
+  switch (s) {} // expected-error {{statement requires expression of integer type ('struct S' invalid)}}
+
+  while (struct S {} x=0) ; // expected-error {{types may not be defined in conditions}} expected-error {{no viable conversion}} expected-error {{value of type 'struct S' is not contextually convertible to 'bool'}} expected-note{{candidate constructor (the implicit copy constructor)}}
+  while (struct {} x=0) ; // expected-error {{types may not be defined in conditions}} expected-error {{no viable conversion}} expected-error {{not contextually convertible to 'bool'}} expected-note{{candidate constructor (the implicit copy constructor)}}
+  switch (enum {E} x=0) ; // expected-error {{types may not be defined in conditions}} expected-error {{cannot initialize}} \
+  // expected-warning{{enumeration value 'E' not handled in switch}}
+
+  if (int x=0) { // expected-note 2 {{previous definition is here}}
+    int x;  // expected-error {{redefinition of 'x'}}
+  }
+  else
+    int x;  // expected-error {{redefinition of 'x'}}
+  while (int x=0) int x; // expected-error {{redefinition of 'x'}} expected-note {{previous definition is here}}
+  while (int x=0) { int x; } // expected-error {{redefinition of 'x'}} expected-note {{previous definition is here}}
+  for (int x; int x=0; ) ; // expected-error {{redefinition of 'x'}} expected-note {{previous definition is here}}
+  for (int x; ; ) int x; // expected-error {{redefinition of 'x'}} expected-note {{previous definition is here}}
+  for (; int x=0; ) int x; // expected-error {{redefinition of 'x'}} expected-note {{previous definition is here}}
+  for (; int x=0; ) { int x; } // expected-error {{redefinition of 'x'}} expected-note {{previous definition is here}}
+  switch (int x=0) { default: int x; } // expected-error {{redefinition of 'x'}} expected-note {{previous definition is here}}
+}
+
+int* get_int_ptr();
+
+void test2() {
+  float *ip;
+  if (int *ip = ip) {
+  }
+}
diff --git a/test/SemaCXX/conditional-expr.cpp b/test/SemaCXX/conditional-expr.cpp
new file mode 100644
index 0000000..a812a59
--- /dev/null
+++ b/test/SemaCXX/conditional-expr.cpp
@@ -0,0 +1,240 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x -Wsign-compare %s
+
+// C++ rules for ?: are a lot stricter than C rules, and have to take into
+// account more conversion options.
+// This test runs in C++0x mode for the contextual conversion of the condition.
+
+struct ToBool { explicit operator bool(); };
+
+struct B;
+struct A { A(); A(const B&); }; // expected-note 2 {{candidate constructor}}
+struct B { operator A() const; }; // expected-note 2 {{candidate function}}
+struct I { operator int(); };
+struct J { operator I(); };
+struct K { operator double(); };
+typedef void (*vfn)();
+struct F { operator vfn(); };
+struct G { operator vfn(); };
+
+struct Base {
+  int trick();
+  A trick() const;
+  void fn1();
+};
+struct Derived : Base {
+  void fn2();
+};
+struct Convertible { operator Base&(); };
+struct Priv : private Base {}; // expected-note 4 {{declared private here}}
+struct Mid : Base {};
+struct Fin : Mid, Derived {};
+typedef void (Derived::*DFnPtr)();
+struct ToMemPtr { operator DFnPtr(); };
+
+struct BadDerived;
+struct BadBase { operator BadDerived&(); };
+struct BadDerived : BadBase {};
+
+struct Fields {
+  int i1, i2, b1 : 3, b2 : 3;
+};
+struct MixedFields {
+  int i;
+  volatile int vi;
+  const int ci;
+  const volatile int cvi;
+};
+struct MixedFieldsDerived : MixedFields {
+};
+
+enum Enum { EVal };
+
+struct Ambig {
+  operator short(); // expected-note 2 {{candidate function}}
+  operator signed char(); // expected-note 2 {{candidate function}}
+};
+
+void test()
+{
+  // This function tests C++0x 5.16
+
+  // p1 (contextually convert to bool)
+  int i1 = ToBool() ? 0 : 1;
+
+  // p2 (one or both void, and throwing)
+  i1 ? throw 0 : throw 1;
+  i1 ? test() : throw 1;
+  i1 ? throw 0 : test();
+  i1 ? test() : test();
+  i1 = i1 ? throw 0 : 0;
+  i1 = i1 ? 0 : throw 0;
+  i1 ? 0 : test(); // expected-error {{right operand to ? is void, but left operand is of type 'int'}}
+  i1 ? test() : 0; // expected-error {{left operand to ? is void, but right operand is of type 'int'}}
+  (i1 ? throw 0 : i1) = 0; // expected-error {{expression is not assignable}}
+  (i1 ? i1 : throw 0) = 0; // expected-error {{expression is not assignable}}
+
+  // p3 (one or both class type, convert to each other)
+  // b1 (lvalues)
+  Base base;
+  Derived derived;
+  Convertible conv;
+  Base &bar1 = i1 ? base : derived;
+  Base &bar2 = i1 ? derived : base;
+  Base &bar3 = i1 ? base : conv;
+  Base &bar4 = i1 ? conv : base;
+  // these are ambiguous
+  BadBase bb;
+  BadDerived bd;
+  (void)(i1 ? bb : bd); // expected-error {{conditional expression is ambiguous; 'BadBase' can be converted to 'BadDerived' and vice versa}}
+  (void)(i1 ? bd : bb); // expected-error {{conditional expression is ambiguous}}
+  // curiously enough (and a defect?), these are not
+  // for rvalues, hierarchy takes precedence over other conversions
+  (void)(i1 ? BadBase() : BadDerived());
+  (void)(i1 ? BadDerived() : BadBase());
+
+  // b2.1 (hierarchy stuff)
+  const Base constret();
+  const Derived constder();
+  // should use const overload
+  A a1((i1 ? constret() : Base()).trick());
+  A a2((i1 ? Base() : constret()).trick());
+  A a3((i1 ? constret() : Derived()).trick());
+  A a4((i1 ? Derived() : constret()).trick());
+  // should use non-const overload
+  i1 = (i1 ? Base() : Base()).trick();
+  i1 = (i1 ? Base() : Base()).trick();
+  i1 = (i1 ? Base() : Derived()).trick();
+  i1 = (i1 ? Derived() : Base()).trick();
+  // should fail: const lost
+  (void)(i1 ? Base() : constder()); // expected-error {{incompatible operand types ('Base' and 'Derived const')}}
+  (void)(i1 ? constder() : Base()); // expected-error {{incompatible operand types ('Derived const' and 'Base')}}
+
+  Priv priv;
+  Fin fin;
+  (void)(i1 ? Base() : Priv()); // expected-error{{private base class}}
+  (void)(i1 ? Priv() : Base()); // expected-error{{private base class}}
+  (void)(i1 ? Base() : Fin()); // expected-error{{ambiguous conversion from derived class 'Fin' to base class 'Base':}}
+  (void)(i1 ? Fin() : Base()); // expected-error{{ambiguous conversion from derived class 'Fin' to base class 'Base':}}
+  (void)(i1 ? base : priv); // expected-error {{private base class}}
+  (void)(i1 ? priv : base); // expected-error {{private base class}}
+  (void)(i1 ? base : fin); // expected-error {{ambiguous conversion from derived class 'Fin' to base class 'Base':}}
+  (void)(i1 ? fin : base); // expected-error {{ambiguous conversion from derived class 'Fin' to base class 'Base':}}
+
+  // b2.2 (non-hierarchy)
+  i1 = i1 ? I() : i1;
+  i1 = i1 ? i1 : I();
+  I i2(i1 ? I() : J());
+  I i3(i1 ? J() : I());
+  // "the type [it] woud have if E2 were converted to an rvalue"
+  vfn pfn = i1 ? F() : test;
+  pfn = i1 ? test : F();
+  (void)(i1 ? A() : B()); // expected-error {{conversion from 'B' to 'A' is ambiguous}}
+  (void)(i1 ? B() : A()); // expected-error {{conversion from 'B' to 'A' is ambiguous}}
+  (void)(i1 ? 1 : Ambig()); // expected-error {{conversion from 'Ambig' to 'int' is ambiguous}}
+  (void)(i1 ? Ambig() : 1); // expected-error {{conversion from 'Ambig' to 'int' is ambiguous}}
+  // By the way, this isn't an lvalue:
+  &(i1 ? i1 : i2); // expected-error {{address expression must be an lvalue or a function designator}}
+
+  // p4 (lvalue, same type)
+  Fields flds;
+  int &ir1 = i1 ? flds.i1 : flds.i2;
+  (i1 ? flds.b1 : flds.i2) = 0;
+  (i1 ? flds.i1 : flds.b2) = 0;
+  (i1 ? flds.b1 : flds.b2) = 0;
+
+  // p5 (conversion to built-in types)
+  // GCC 4.3 fails these
+  double d1 = i1 ? I() : K();
+  pfn = i1 ? F() : G();
+  DFnPtr pfm;
+  pfm = i1 ? DFnPtr() : &Base::fn1;
+  pfm = i1 ? &Base::fn1 : DFnPtr();
+
+  // p6 (final conversions)
+  i1 = i1 ? i1 : ir1;
+  int *pi1 = i1 ? &i1 : 0;
+  pi1 = i1 ? 0 : &i1;
+  i1 = i1 ? i1 : EVal;
+  i1 = i1 ? EVal : i1;
+  d1 = i1 ? 'c' : 4.0;
+  d1 = i1 ? 4.0 : 'c';
+  Base *pb = i1 ? (Base*)0 : (Derived*)0;
+  pb = i1 ? (Derived*)0 : (Base*)0;
+  pfm = i1 ? &Base::fn1 : &Derived::fn2;
+  pfm = i1 ? &Derived::fn2 : &Base::fn1;
+  pfm = i1 ? &Derived::fn2 : 0;
+  pfm = i1 ? 0 : &Derived::fn2;
+  const int (MixedFieldsDerived::*mp1) =
+    i1 ? &MixedFields::ci : &MixedFieldsDerived::i;
+  const volatile int (MixedFields::*mp2) =
+    i1 ? &MixedFields::ci : &MixedFields::cvi;
+  (void)(i1 ? &MixedFields::ci : &MixedFields::vi);
+  // Conversion of primitives does not result in an lvalue.
+  &(i1 ? i1 : d1); // expected-error {{address expression must be an lvalue or a function designator}}
+
+  (void)&(i1 ? flds.b1 : flds.i1); // expected-error {{address of bit-field requested}}
+  (void)&(i1 ? flds.i1 : flds.b1); // expected-error {{address of bit-field requested}}
+  
+
+  unsigned long test0 = 5;
+  test0 = test0 ? (long) test0 : test0; // expected-warning {{operands of ? are integers of different signs}}
+  test0 = test0 ? (int) test0 : test0; // expected-warning {{operands of ? are integers of different signs}}
+  test0 = test0 ? (short) test0 : test0; // expected-warning {{operands of ? are integers of different signs}}
+  test0 = test0 ? test0 : (long) test0; // expected-warning {{operands of ? are integers of different signs}}
+  test0 = test0 ? test0 : (int) test0; // expected-warning {{operands of ? are integers of different signs}}
+  test0 = test0 ? test0 : (short) test0; // expected-warning {{operands of ? are integers of different signs}}
+  test0 = test0 ? test0 : (long) 10;
+  test0 = test0 ? test0 : (int) 10;
+  test0 = test0 ? test0 : (short) 10;
+  test0 = test0 ? (long) 10 : test0;
+  test0 = test0 ? (int) 10 : test0;
+  test0 = test0 ? (short) 10 : test0;
+
+  test0 = test0 ? EVal : test0;
+  test0 = test0 ? EVal : (int) test0;
+
+  // Note the thing that this does not test: since DR446, various situations
+  // *must* create a separate temporary copy of class objects. This can only
+  // be properly tested at runtime, though.
+}
+
+namespace PR6595 {
+  struct String {
+    String(const char *);
+    operator const char*() const;
+  };
+
+  void f(bool Cond, String S) {
+    (void)(Cond? S : "");
+    (void)(Cond? "" : S);
+    const char a[1] = {'a'};
+    (void)(Cond? S : a);
+    (void)(Cond? a : S);
+  }
+}
+
+namespace PR6757 {
+  struct Foo1 {
+    Foo1();
+    Foo1(const Foo1&);
+  };
+
+  struct Foo2 { };
+
+  struct Foo3 {
+    Foo3();
+    Foo3(Foo3&); // expected-note{{would lose const qualifier}}
+  };
+
+  struct Bar {
+    operator const Foo1&() const;
+    operator const Foo2&() const;
+    operator const Foo3&() const;
+  };
+
+  void f() {
+    (void)(true ? Bar() : Foo1()); // okay
+    (void)(true ? Bar() : Foo2()); // okay
+    (void)(true ? Bar() : Foo3()); // expected-error{{no viable constructor copying temporary}}
+  }
+}
diff --git a/test/SemaCXX/const-cast.cpp b/test/SemaCXX/const-cast.cpp
new file mode 100644
index 0000000..50bd316
--- /dev/null
+++ b/test/SemaCXX/const-cast.cpp
@@ -0,0 +1,64 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct A {};
+
+// See if aliasing can confuse this baby.
+typedef char c;
+typedef c *cp;
+typedef cp *cpp;
+typedef cpp *cppp;
+typedef cppp &cpppr;
+typedef const cppp &cpppcr;
+typedef const char cc;
+typedef cc *ccp;
+typedef volatile ccp ccvp;
+typedef ccvp *ccvpp;
+typedef const volatile ccvpp ccvpcvp;
+typedef ccvpcvp *ccvpcvpp;
+typedef int iar[100];
+typedef iar &iarr;
+typedef int (*f)(int);
+
+char ***good_const_cast_test(ccvpcvpp var)
+{
+  // Cast away deep consts and volatiles.
+  char ***var2 = const_cast<cppp>(var);
+  char ***const &var3 = var2;
+  // Const reference to reference.
+  char ***&var4 = const_cast<cpppr>(var3);
+  // Drop reference. Intentionally without qualifier change.
+  char *** var5 = const_cast<cppp>(var4);
+  // Const array to array reference.
+  const int ar[100] = {0};
+  int (&rar)[100] = const_cast<iarr>(ar);
+  // Array decay. Intentionally without qualifier change.
+  int *pi = const_cast<int*>(ar);
+  f fp = 0;
+  // Don't misidentify fn** as a function pointer.
+  f *fpp = const_cast<f*>(&fp);
+  int const A::* const A::*icapcap = 0;
+  int A::* A::* iapap = const_cast<int A::* A::*>(icapcap);
+
+  return var4;
+}
+
+short *bad_const_cast_test(char const *volatile *const volatile *var)
+{
+  // Different pointer levels.
+  char **var2 = const_cast<char**>(var); // expected-error {{const_cast from 'char const *volatile *const volatile *' to 'char **' is not allowed}}
+  // Different final type.
+  short ***var3 = const_cast<short***>(var); // expected-error {{const_cast from 'char const *volatile *const volatile *' to 'short ***' is not allowed}}
+  // Rvalue to reference.
+  char ***&var4 = const_cast<cpppr>(&var2); // expected-error {{const_cast from rvalue to reference type 'cpppr'}}
+  // Non-pointer.
+  char v = const_cast<char>(**var2); // expected-error {{const_cast to 'char', which is not a reference, pointer-to-object, or pointer-to-data-member}}
+  const int *ar[100] = {0};
+  // Not even lenient g++ accepts this.
+  int *(*rar)[100] = const_cast<int *(*)[100]>(&ar); // expected-error {{const_cast from 'int const *(*)[100]' to 'int *(*)[100]' is not allowed}}
+  f fp1 = 0;
+  // Function pointers.
+  f fp2 = const_cast<f>(fp1); // expected-error {{const_cast to 'f' (aka 'int (*)(int)'), which is not a reference, pointer-to-object, or pointer-to-data-member}}
+  void (A::*mfn)() = 0;
+  (void)const_cast<void (A::*)()>(mfn); // expected-error {{const_cast to 'void (A::*)()', which is not a reference, pointer-to-object, or pointer-to-data-member}}
+  return **var3;
+}
diff --git a/test/SemaCXX/constant-expression.cpp b/test/SemaCXX/constant-expression.cpp
new file mode 100644
index 0000000..a17dd58
--- /dev/null
+++ b/test/SemaCXX/constant-expression.cpp
@@ -0,0 +1,87 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
+// C++ [expr.const]p1:
+//   In several places, C++ requires expressions that evaluate to an integral
+//   or enumeration constant: as array bounds, as case expressions, as
+//   bit-field lengths, as enumerator initializers, as static member
+//   initializers, and as integral or enumeration non-type template arguments.
+//   An integral constant-expression can involve only literals, enumerators,
+//   const variables or static data members of integral or enumeration types
+//   initialized with constant expressions, and sizeof expressions. Floating
+//   literals can appear only if they are cast to integral or enumeration types.
+
+enum Enum { eval = 1 };
+const int cval = 2;
+const Enum ceval = eval;
+struct Struct {
+  static const int sval = 3;
+  static const Enum seval = eval;
+};
+
+template <int itval, Enum etval> struct C {
+  enum E {
+    v1 = 1,
+    v2 = eval,
+    v3 = cval,
+    v4 = ceval,
+    v5 = Struct::sval,
+    v6 = Struct::seval,
+    v7 = itval,
+    v8 = etval,
+    v9 = (int)1.5,
+    v10 = sizeof(Struct),
+    v11 = true? 1 + cval * Struct::sval ^ itval / (int)1.5 - sizeof(Struct) : 0
+  };
+  unsigned
+    b1 : 1,
+    b2 : eval,
+    b3 : cval,
+    b4 : ceval,
+    b5 : Struct::sval,
+    b6 : Struct::seval,
+    b7 : itval,
+    b8 : etval,
+    b9 : (int)1.5,
+    b10 : sizeof(Struct),
+    b11 : true? 1 + cval * Struct::sval ^ itval / (int)1.5 - sizeof(Struct) : 0
+    ;
+  static const int
+    i1 = 1,
+    i2 = eval,
+    i3 = cval,
+    i4 = ceval,
+    i5 = Struct::sval,
+    i6 = Struct::seval,
+    i7 = itval,
+    i8 = etval,
+    i9 = (int)1.5,
+    i10 = sizeof(Struct),
+    i11 = true? 1 + cval * Struct::sval ^ itval / (int)1.5 - sizeof(Struct) : 0
+    ;
+  void f() {
+    switch(0) {
+    case    0 + 1:
+    case  100 + eval:
+    case  200 + cval:
+    case  300 + ceval:
+    case  400 + Struct::sval:
+    case  500 + Struct::seval:
+    case  600 + itval:
+    case  700 + etval:
+    case  800 + (int)1.5:
+    case  900 + sizeof(Struct):
+    case 1000 + (true? 1 + cval * Struct::sval ^
+                 itval / (int)1.5 - sizeof(Struct) : 0):
+      ;
+    }
+  }
+  typedef C<itval, etval> T0;
+};
+
+template struct C<1, eval>;
+template struct C<cval, ceval>;
+template struct C<Struct::sval, Struct::seval>;
+
+enum {
+  a = sizeof(int) == 8,
+  b = a? 8 : 4
+};
diff --git a/test/SemaCXX/constructor-initializer.cpp b/test/SemaCXX/constructor-initializer.cpp
new file mode 100644
index 0000000..8e9e133
--- /dev/null
+++ b/test/SemaCXX/constructor-initializer.cpp
@@ -0,0 +1,206 @@
+// RUN: %clang_cc1 -Wreorder -fsyntax-only -verify %s
+class A { 
+  int m;
+public:
+   A() : A::m(17) { } // expected-error {{member initializer 'm' does not name a non-static data member or base class}}
+   A(int);
+};
+
+class B : public A { 
+public:
+  B() : A(), m(1), n(3.14) { }
+
+private:
+  int m;
+  float n;  
+};
+
+
+class C : public virtual B { 
+public:
+  C() : B() { }
+};
+
+class D : public C { 
+public:
+  D() : B(), C() { }
+};
+
+class E : public D, public B { 
+public:
+  E() : B(), D() { } // expected-error{{base class initializer 'B' names both a direct base class and an inherited virtual base class}}
+};
+
+
+typedef int INT;
+
+class F : public B { 
+public:
+  int B;
+
+  F() : B(17),
+        m(17), // expected-error{{member initializer 'm' does not name a non-static data member or base class}}
+        INT(17) // expected-error{{constructor initializer 'INT' (aka 'int') does not name a class}}
+  { 
+  }
+};
+
+class G : A {
+  G() : A(10); // expected-error{{expected '{'}}
+};
+
+void f() : a(242) { } // expected-error{{only constructors take base initializers}}
+
+class H : A {
+  H();
+};
+
+H::H() : A(10) { }
+
+
+class  X {};
+class Y {};
+
+struct S : Y, virtual X {
+  S (); 
+};
+
+struct Z : S { 
+  Z() : X(), S(), E()  {} // expected-error {{type 'E' is not a direct or virtual base of 'Z'}}
+};
+
+class U { 
+  union { int a; char* p; };
+  union { int b; double d; };
+
+  U() :  a(1), // expected-note {{previous initialization is here}}
+         p(0), // expected-error {{initializing multiple members of anonymous union}}
+         d(1.0)  {}
+};
+
+struct V {};
+struct Base {};
+struct Base1 {};
+
+struct Derived : Base, Base1, virtual V {
+  Derived ();
+};
+
+struct Current : Derived {
+  int Derived;
+  Current() : Derived(1), ::Derived(), // expected-warning {{field 'Derived' will be initialized after base '::Derived'}} \
+                                       // expected-warning {{base class '::Derived' will be initialized after base 'Derived::V'}}
+                          ::Derived::Base(), // expected-error {{type '::Derived::Base' is not a direct or virtual base of 'Current'}}
+                           Derived::Base1(), // expected-error {{type 'Derived::Base1' is not a direct or virtual base of 'Current'}}
+                           Derived::V(),
+                           ::NonExisting(), // expected-error {{member initializer 'NonExisting' does not name a non-static data member or}}
+                           INT::NonExisting()  {} // expected-error {{expected a class or namespace}} \
+                                                  // expected-error {{member initializer 'NonExisting' does not name a non-static data member or}}
+};
+
+struct M {              // expected-note 2 {{candidate constructor (the implicit copy constructor)}} \
+                        // expected-note {{declared here}} \
+                        // expected-note {{declared here}}
+  M(int i, int j);      // expected-note 2 {{candidate constructor}}
+};
+
+struct N : M  {
+  N() : M(1),        // expected-error {{no matching constructor for initialization of 'M'}}
+        m1(100) {  } // expected-error {{no matching constructor for initialization of 'M'}}
+  M m1;
+};
+
+struct P : M  {
+  P()  {  } // expected-error {{constructor for 'P' must explicitly initialize the base class 'M' which does not have a default constructor}} \
+            // expected-error {{member 'm'}}
+  M m; // expected-note {{member is declared here}}
+};
+
+struct Q {
+  Q() : f1(1,2),       // expected-error {{excess elements in scalar initializer}}
+        pf(0.0)  { }   // expected-error {{cannot initialize a member subobject of type 'float *' with an rvalue of type 'double'}}
+  float f1;
+
+  float *pf;
+};
+
+// A silly class used to demonstrate field-is-uninitialized in constructors with
+// multiple params.
+class TwoInOne { public: TwoInOne(TwoInOne a, TwoInOne b) {} };
+class InitializeUsingSelfTest {
+  bool A;
+  char* B;
+  int C;
+  TwoInOne D;
+  InitializeUsingSelfTest(int E)
+      : A(A),  // expected-warning {{field is uninitialized when used here}}
+        B((((B)))),  // expected-warning {{field is uninitialized when used here}}
+        C(A && InitializeUsingSelfTest::C),  // expected-warning {{field is uninitialized when used here}}
+        D(D,  // expected-warning {{field is uninitialized when used here}}
+          D) {}  // expected-warning {{field is uninitialized when used here}}
+};
+
+int IntWrapper(int i) { return 0; };
+class InitializeUsingSelfExceptions {
+  int A;
+  int B;
+  InitializeUsingSelfExceptions(int B)
+      : A(IntWrapper(A)),  // Due to a conservative implementation, we do not report warnings inside function/ctor calls even though it is possible to do so.
+        B(B) {}  // Not a warning; B is a local variable.
+};
+
+class CopyConstructorTest {
+  bool A, B, C;
+  CopyConstructorTest(const CopyConstructorTest& rhs)
+      : A(rhs.A),
+        B(B),  // expected-warning {{field is uninitialized when used here}}
+        C(rhs.C || C) { }  // expected-warning {{field is uninitialized when used here}}
+};
+
+// Make sure we aren't marking default constructors when we shouldn't be.
+template<typename T>
+struct NDC {
+  T &ref;
+  
+  NDC() { }
+  NDC(T &ref) : ref(ref) { }
+};
+  
+struct X0 : NDC<int> {
+  X0(int &ref) : NDC<int>(ref), ndc(ref) { }
+  
+  NDC<int> ndc;
+};
+
+namespace Test0 {
+
+struct A { A(); };
+
+struct B {
+  B() { } 
+  const A a;
+};
+
+}
+
+namespace Test1 {
+  struct A {
+    enum Kind { Foo } Kind;
+    A() : Kind(Foo) {}
+  };
+}
+
+namespace Test2 {
+
+struct A { 
+  A(const A&);
+};
+
+struct B : virtual A { };
+struct C : A, B { };
+
+C f(C c) {
+  return c;
+}
+
+}
diff --git a/test/SemaCXX/constructor-recovery.cpp b/test/SemaCXX/constructor-recovery.cpp
new file mode 100644
index 0000000..c1bb436
--- /dev/null
+++ b/test/SemaCXX/constructor-recovery.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct C {
+  virtual C() = 0; // expected-error{{constructor cannot be declared 'virtual'}}
+};
+
+void f() {
+ C c;
+}
diff --git a/test/SemaCXX/constructor.cpp b/test/SemaCXX/constructor.cpp
new file mode 100644
index 0000000..9ef5c98
--- /dev/null
+++ b/test/SemaCXX/constructor.cpp
@@ -0,0 +1,86 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s 
+typedef int INT;
+
+class Foo {
+  Foo();
+  (Foo)(float) { }
+  explicit Foo(int); // expected-note {{previous declaration is here}}
+  Foo(const Foo&);
+
+  ((Foo))(INT); // expected-error{{cannot be redeclared}}
+
+  Foo(Foo foo, int i = 17, int j = 42); // expected-error{{copy constructor must pass its first argument by reference}}
+
+  static Foo(short, short); // expected-error{{constructor cannot be declared 'static'}}
+  virtual Foo(double); // expected-error{{constructor cannot be declared 'virtual'}}
+  Foo(long) const; // expected-error{{'const' qualifier is not allowed on a constructor}}
+  
+  int Foo(int, int); // expected-error{{constructor cannot have a return type}}
+};
+
+Foo::Foo(const Foo&) { }
+
+typedef struct {
+  int version;
+} Anon;
+extern const Anon anon;
+extern "C" const Anon anon2;
+
+// PR3188: The extern declaration complained about not having an appropriate
+// constructor.
+struct x;
+extern x a;
+
+// A similar case.
+struct y {
+  y(int);
+};
+extern y b;
+
+struct Length {
+  Length l() const { return *this; }
+};
+
+// <rdar://problem/6815988>
+struct mmst_reg{
+ char mmst_reg[10];
+};
+
+// PR3948
+namespace PR3948 {
+// PR3948
+class a {
+  public:
+  int b(int a());
+};
+int x();
+void y() {
+  a z; z.b(x);
+}
+}
+
+namespace A {
+  struct S {
+    S();
+    S(int);
+    void f1();
+    void f2();
+    operator int ();
+    ~S();
+  };
+}
+
+A::S::S() {}
+
+void A::S::f1() {}
+
+struct S {};
+
+A::S::S(int) {}
+
+void A::S::f2() {}
+
+A::S::operator int() { return 1; }
+
+A::S::~S() {}
+
diff --git a/test/SemaCXX/conversion-delete-expr.cpp b/test/SemaCXX/conversion-delete-expr.cpp
new file mode 100644
index 0000000..862ae5a
--- /dev/null
+++ b/test/SemaCXX/conversion-delete-expr.cpp
@@ -0,0 +1,109 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s
+
+// Test1
+struct B {
+  operator char *(); // expected-note {{candidate function}}
+};
+
+struct D : B {
+  operator int *(); // expected-note {{candidate function}}
+};
+
+void f (D d)
+{
+   delete d; // expected-error {{ambiguous conversion of delete expression of type 'D' to a pointer}}
+}
+
+// Test2
+struct B1 {
+  operator int *();
+};
+
+struct D1 : B1 {
+  operator int *();
+};
+
+void f1 (D1 d)
+{
+   delete d;
+}
+
+// Test3
+struct B2 {
+  operator const int *();	// expected-note {{candidate function}}
+};
+
+struct D2 : B2 {
+  operator int *();	// expected-note {{candidate function}}
+};
+
+void f2 (D2 d)
+{
+   delete d; // expected-error {{ambiguous conversion of delete expression of type 'D2' to a pointer}}
+}
+
+// Test4
+struct B3 {
+  operator const int *();	// expected-note {{candidate function}}
+};
+
+struct A3 {
+  operator const int *();	// expected-note {{candidate function}}
+};
+
+struct D3 : A3, B3 {
+};
+
+void f3 (D3 d)
+{
+   delete d; // expected-error {{ambiguous conversion of delete expression of type 'D3' to a pointer}}
+}
+
+// Test5
+struct X {
+   operator int();
+   operator int*();
+};
+
+void f4(X x) { delete x; delete x; }
+
+// Test6
+struct X1 {
+   operator int();
+   operator int*();
+   template<typename T> operator T*() const; // converts to any pointer!
+};
+
+void f5(X1 x) { delete x; }  // OK. In selecting a conversion to pointer function, template convesions are skipped.
+
+// Test7
+struct Base {
+   operator int*();	
+};
+
+struct Derived : Base {
+   // not the same function as Base's non-const operator int()
+   operator int*() const;
+};
+
+void foo6(const Derived cd, Derived d) {
+	// overload resolution selects Derived::operator int*() const;
+	delete cd;
+	delete d;	
+}
+
+// Test8
+struct BB {
+   template<typename T> operator T*() const;
+};
+
+struct DD : BB {
+   template<typename T> operator T*() const; // hides base conversion
+   operator int *() const;
+};
+
+void foo7 (DD d)
+{
+        // OK. In selecting a conversion to pointer function, template convesions are skipped.
+	delete d;
+}
diff --git a/test/SemaCXX/conversion-function.cpp b/test/SemaCXX/conversion-function.cpp
new file mode 100644
index 0000000..3e96d02
--- /dev/null
+++ b/test/SemaCXX/conversion-function.cpp
@@ -0,0 +1,217 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+class X { 
+public:
+  operator bool();
+  operator int() const;
+
+  bool f() {
+    return operator bool();
+  }
+
+  float g() {
+    return operator float(); // expected-error{{use of undeclared 'operator float'}}
+  }
+};
+
+operator int(); // expected-error{{conversion function must be a non-static member function}}
+
+operator int; // expected-error{{'operator int' cannot be the name of a variable or data member}}
+
+typedef int func_type(int);
+typedef int array_type[10];
+
+class Y {
+public:
+  void operator bool(int, ...) const; // expected-error{{conversion function cannot have a return type}} \
+  // expected-error{{conversion function cannot have any parameters}}
+  
+  operator float(...) const;  // expected-error{{conversion function cannot be variadic}}
+  
+  
+  operator func_type(); // expected-error{{conversion function cannot convert to a function type}}
+  operator array_type(); // expected-error{{conversion function cannot convert to an array type}}
+};
+
+
+typedef int INT;
+typedef INT* INT_PTR;
+
+class Z { 
+  operator int(); // expected-note {{previous declaration is here}}
+  operator int**(); // expected-note {{previous declaration is here}}
+  
+  operator INT();  // expected-error{{conversion function cannot be redeclared}}
+  operator INT_PTR*(); // expected-error{{conversion function cannot be redeclared}}
+};
+
+
+class A { };
+
+class B : public A {
+public:
+  operator A&() const; // expected-warning{{conversion function converting 'B' to its base class 'A' will never be used}}
+  operator const void() const; // expected-warning{{conversion function converting 'B' to 'void const' will never be used}}
+  operator const B(); // expected-warning{{conversion function converting 'B' to itself will never be used}}
+};
+
+// This used to crash Clang.
+struct Flip;
+struct Flop {
+  Flop();
+  Flop(const Flip&); // expected-note{{candidate constructor}}
+};
+struct Flip {
+  operator Flop() const; // expected-note{{candidate function}}
+};
+Flop flop = Flip(); // expected-error {{conversion from 'Flip' to 'Flop' is ambiguous}}
+
+// This tests that we don't add the second conversion declaration to the list of user conversions
+struct C {
+  operator const char *() const;
+};
+
+C::operator const char*() const { return 0; }
+
+void f(const C& c) {
+  const char* v = c;
+}
+
+// Test. Conversion in base class is visible in derived class.
+class XB { 
+public:
+  operator int(); // expected-note {{candidate function}}
+};
+
+class Yb : public XB { 
+public:
+  operator char(); // expected-note {{candidate function}}
+};
+
+void f(Yb& a) {
+  if (a) { } // expected-error {{conversion from 'Yb' to 'bool' is ambiguous}}
+  int i = a; // OK. calls XB::operator int();
+  char ch = a;  // OK. calls Yb::operator char();
+}
+
+// Test conversion + copy construction.
+class AutoPtrRef { };
+
+class AutoPtr {
+  // FIXME: Using 'unavailable' since we do not have access control yet.
+  // FIXME: The error message isn't so good.
+  AutoPtr(AutoPtr &) __attribute__((unavailable)); // expected-note{{explicitly marked}}
+  
+public:
+  AutoPtr();
+  AutoPtr(AutoPtrRef);
+  
+  operator AutoPtrRef();
+};
+
+AutoPtr make_auto_ptr();
+
+AutoPtr test_auto_ptr(bool Cond) {
+  AutoPtr p1( make_auto_ptr() );
+  
+  AutoPtr p;
+  if (Cond)
+    return p; // expected-error{{call to deleted constructor}}
+  
+  return AutoPtr();
+}
+
+struct A1 {
+  A1(const char *);
+  ~A1();
+
+private:
+  A1(const A1&) __attribute__((unavailable)); // expected-note{{here}}
+};
+
+A1 f() {
+  return "Hello"; // expected-error{{invokes deleted constructor}}
+}
+
+namespace source_locations {
+  template<typename T>
+  struct sneaky_int {
+    typedef int type;
+  };
+
+  template<typename T, typename U>
+  struct A { };
+
+  template<typename T>
+  struct A<T, T> : A<T, int> { };
+
+  struct E {
+    template<typename T>
+    operator A<T, typename sneaky_int<T>::type>&() const; // expected-note{{candidate function}}
+  };
+
+  void f() {
+    A<float, float> &af = E(); // expected-error{{no viable conversion}}
+    A<float, int> &af2 = E();
+    const A<float, int> &caf2 = E();
+  }
+
+  // Check 
+  template<typename T>
+  struct E2 {
+    operator T
+    * // expected-error{{pointer to a reference}}
+    () const;
+  };
+
+  E2<int&> e2i; // expected-note{{in instantiation}}
+}
+
+namespace crazy_declarators {
+  struct A {
+    (&operator bool())(); // expected-error {{must use a typedef to declare a conversion to 'bool (&)()'}}
+
+    // FIXME: This diagnostic is misleading (the correct spelling
+    // would be 'operator int*'), but it's a corner case of a
+    // rarely-used syntax extension.
+    *operator int();  // expected-error {{must use a typedef to declare a conversion to 'int *'}}
+  };
+}
+
+namespace smart_ptr {
+  class Y { 
+    class YRef { };
+
+    Y(Y&);
+
+  public:
+    Y();
+    Y(YRef);
+
+    operator YRef(); // expected-note{{candidate function}}
+  };
+
+  struct X { // expected-note{{candidate constructor (the implicit copy constructor) not}}
+    explicit X(Y);
+  };
+
+  Y make_Y();
+
+  X f() {
+    X x = make_Y(); // expected-error{{no viable conversion from 'smart_ptr::Y' to 'smart_ptr::X'}}
+    X x2(make_Y());
+    return X(Y());
+  }
+}
+
+struct Any {
+  Any(...);
+};
+
+struct Other {
+  Other(const Other &); 
+  Other();
+};
+
+void test_any() {
+  Any any = Other(); // expected-error{{cannot pass object of non-POD type 'Other' through variadic constructor; call will abort at runtime}}
+}
diff --git a/test/SemaCXX/convert-to-bool.cpp b/test/SemaCXX/convert-to-bool.cpp
new file mode 100644
index 0000000..4cd22e9
--- /dev/null
+++ b/test/SemaCXX/convert-to-bool.cpp
@@ -0,0 +1,67 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s 
+struct ConvToBool {
+  operator bool() const;
+};
+
+struct ConvToInt {
+  operator int();
+};
+
+struct ExplicitConvToBool {
+  explicit operator bool(); // expected-warning{{explicit conversion functions are a C++0x extension}}
+};
+
+void test_conv_to_bool(ConvToBool ctb, ConvToInt cti, ExplicitConvToBool ecb) {
+  if (ctb) { }
+  if (cti) { }
+  if (ecb) { }
+  for (; ctb; ) { }
+  for (; cti; ) { }
+  for (; ecb; ) { }
+  while (ctb) { };
+  while (cti) { }
+  while (ecb) { }
+  do { } while (ctb);
+  do { } while (cti);
+  do { } while (ecb);
+
+  if (!ctb) { }
+  if (!cti) { }
+  if (!ecb) { }
+
+  bool b1 = !ecb;
+  if (ctb && ecb) { }
+  bool b2 = ctb && ecb;
+  if (ctb || ecb) { }
+  bool b3 = ctb || ecb;
+}
+
+void accepts_bool(bool) { } // expected-note{{candidate function}}
+
+struct ExplicitConvToRef {
+  explicit operator int&(); // expected-warning{{explicit conversion functions are a C++0x extension}}
+};
+
+void test_explicit_bool(ExplicitConvToBool ecb) {
+  bool b1(ecb); // okay
+  bool b2 = ecb; // expected-error{{no viable conversion from 'ExplicitConvToBool' to 'bool'}}
+  accepts_bool(ecb); // expected-error{{no matching function for call to}}
+}
+
+void test_explicit_conv_to_ref(ExplicitConvToRef ecr) {
+  int& i1 = ecr; // expected-error{{non-const lvalue reference to type 'int' cannot bind to a value of unrelated type 'ExplicitConvToRef'}}
+  int& i2(ecr); // okay
+}
+
+struct A { };
+struct B { };
+struct C {
+  explicit operator A&(); // expected-warning{{explicit conversion functions are a C++0x extension}}
+  operator B&(); // expected-note{{candidate}}
+};
+
+void test_copy_init_conversions(C c) {
+  A &a = c; // expected-error{{no viable conversion from 'C' to 'A'}}
+  B &b = b; // okay
+}
+
diff --git a/test/SemaCXX/converting-constructor.cpp b/test/SemaCXX/converting-constructor.cpp
new file mode 100644
index 0000000..1688e51
--- /dev/null
+++ b/test/SemaCXX/converting-constructor.cpp
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s 
+class Z { };
+
+class Y { 
+public:
+  Y(const Z&);
+};
+
+class X {
+public:
+  X(int);
+  X(const Y&);
+};
+
+void f(X); // expected-note{{candidate function}}
+
+void g(short s, Y y, Z z) {
+  f(s);
+  f(1.0f);
+  f(y);
+  f(z); // expected-error{{no matching function}}
+}
+
+
+class FromShort {
+public:
+  FromShort(short s);
+};
+
+class FromShortExplicitly { // expected-note{{candidate constructor (the implicit copy constructor)}}
+public:
+  explicit FromShortExplicitly(short s);
+};
+
+void explicit_constructor(short s) {
+  FromShort fs1(s);
+  FromShort fs2 = s;
+  FromShortExplicitly fse1(s);
+  FromShortExplicitly fse2 = s; // expected-error{{no viable conversion}}
+}
+
+// PR5519
+struct X1 { X1(const char&); };
+void x1(X1);
+void y1() {
+  x1(1);
+}
diff --git a/test/SemaCXX/copy-assignment.cpp b/test/SemaCXX/copy-assignment.cpp
new file mode 100644
index 0000000..bfe1501
--- /dev/null
+++ b/test/SemaCXX/copy-assignment.cpp
@@ -0,0 +1,99 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s 
+struct A {
+};
+
+struct ConvertibleToA {
+  operator A();
+};
+
+struct ConvertibleToConstA {
+  operator const A();
+};
+
+struct B {
+  B& operator=(B&);  // expected-note 4 {{candidate function}}
+};
+
+struct ConvertibleToB {
+  operator B();
+};
+
+struct ConvertibleToBref {
+  operator B&();
+};
+
+struct ConvertibleToConstB {
+  operator const B();
+};
+
+struct ConvertibleToConstBref {
+  operator const B&();
+};
+
+struct C {
+  int operator=(int); // expected-note{{candidate function}}
+  long operator=(long); // expected-note{{candidate function}}
+  int operator+=(int); // expected-note{{candidate function}}
+  int operator+=(long); // expected-note{{candidate function}}
+};
+
+struct D {
+  D& operator+=(const D &);
+};
+
+struct ConvertibleToInt {
+  operator int();
+};
+
+void test() {
+  A a, na;
+  const A constA = A();
+  ConvertibleToA convertibleToA;
+  ConvertibleToConstA convertibleToConstA;
+
+  B b, nb;
+  const B constB = B();
+  ConvertibleToB convertibleToB;
+  ConvertibleToBref convertibleToBref;
+  ConvertibleToConstB convertibleToConstB;
+  ConvertibleToConstBref convertibleToConstBref;
+
+  C c, nc;
+  const C constC = C();
+
+  D d, nd;
+  const D constD = D();
+
+  ConvertibleToInt convertibleToInt;
+
+  na = a;
+  na = constA;
+  na = convertibleToA;
+  na = convertibleToConstA;
+  na += a; // expected-error{{no viable overloaded '+='}}
+
+  nb = b;
+  nb = constB;  // expected-error{{no viable overloaded '='}}
+  nb = convertibleToB; // expected-error{{no viable overloaded '='}}
+  nb = convertibleToBref;
+  nb = convertibleToConstB; // expected-error{{no viable overloaded '='}}
+  nb = convertibleToConstBref; // expected-error{{no viable overloaded '='}}
+
+  nc = c;
+  nc = constC;
+  nc = 1;
+  nc = 1L;
+  nc = 1.0; // expected-error{{use of overloaded operator '=' is ambiguous}}
+  nc += 1;
+  nc += 1L;
+  nc += 1.0; // expected-error{{use of overloaded operator '+=' is ambiguous}}
+
+  nd = d;
+  nd += d;
+  nd += constD;
+
+  int i;
+  i = convertibleToInt;
+  i = a; // expected-error{{assigning to 'int' from incompatible type 'A'}}
+}
+
diff --git a/test/SemaCXX/copy-constructor-error.cpp b/test/SemaCXX/copy-constructor-error.cpp
new file mode 100644
index 0000000..9809bfc
--- /dev/null
+++ b/test/SemaCXX/copy-constructor-error.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s 
+
+struct S {
+   S (S);  // expected-error {{copy constructor must pass its first argument by reference}}
+};
+
+S f();
+
+void g() { 
+  S a( f() );
+}
+
+namespace PR6064 {
+  struct A {
+    A() { }
+    inline A(A&, int);
+  };
+
+  A::A(A&, int = 0) { }
+
+  void f() {
+    A const a;
+    A b(a);
+  }
+}
diff --git a/test/SemaCXX/copy-initialization.cpp b/test/SemaCXX/copy-initialization.cpp
new file mode 100644
index 0000000..0c4aa96
--- /dev/null
+++ b/test/SemaCXX/copy-initialization.cpp
@@ -0,0 +1,44 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s 
+class X {
+public:
+  explicit X(const X&); // expected-note {{candidate constructor}}
+  X(int*); // expected-note 3{{candidate constructor}}
+  explicit X(float*); // expected-note {{candidate constructor}}
+};
+
+class Y : public X { };
+
+void f(Y y, int *ip, float *fp) {
+  X x1 = y; // expected-error{{no matching constructor for initialization of 'X'}}
+  X x2 = 0; // expected-error{{no viable constructor copying variable}}
+  X x3 = ip; // expected-error{{no viable constructor copying variable}}
+  X x4 = fp; // expected-error{{no viable conversion}}
+  X x2a(0); // expected-error{{call to constructor of 'X' is ambiguous}}
+  X x3a(ip);
+  X x4a(fp);
+}
+
+struct foo {
+ void bar();
+};
+
+// PR3600
+void test(const foo *P) { P->bar(); } // expected-error{{cannot initialize object parameter of type 'foo' with an expression of type 'foo const'}}
+
+namespace PR6757 {
+  struct Foo {
+    Foo();
+    Foo(Foo&); // expected-note{{candidate constructor not viable}}
+  };
+
+  struct Bar {
+    operator const Foo&() const;
+  };
+
+  void f(Foo);
+
+  void g(Foo foo) {
+    f(Bar()); // expected-error{{no viable constructor copying parameter of type 'PR6757::Foo const'}}
+    f(foo);
+  }
+}
diff --git a/test/SemaCXX/cstyle-cast.cpp b/test/SemaCXX/cstyle-cast.cpp
new file mode 100644
index 0000000..ccb25f0
--- /dev/null
+++ b/test/SemaCXX/cstyle-cast.cpp
@@ -0,0 +1,231 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct A {};
+
+// ----------- const_cast --------------
+
+typedef char c;
+typedef c *cp;
+typedef cp *cpp;
+typedef cpp *cppp;
+typedef cppp &cpppr;
+typedef const cppp &cpppcr;
+typedef const char cc;
+typedef cc *ccp;
+typedef volatile ccp ccvp;
+typedef ccvp *ccvpp;
+typedef const volatile ccvpp ccvpcvp;
+typedef ccvpcvp *ccvpcvpp;
+typedef int iar[100];
+typedef iar &iarr;
+typedef int (*f)(int);
+
+void t_cc()
+{
+  ccvpcvpp var = 0;
+  // Cast away deep consts and volatiles.
+  char ***var2 = (cppp)(var);
+  char ***const &var3 = var2;
+  // Const reference to reference.
+  char ***&var4 = (cpppr)(var3);
+  // Drop reference. Intentionally without qualifier change.
+  char *** var5 = (cppp)(var4);
+  const int ar[100] = {0};
+  // Array decay. Intentionally without qualifier change.
+  int *pi = (int*)(ar);
+  f fp = 0;
+  // Don't misidentify fn** as a function pointer.
+  f *fpp = (f*)(&fp);
+  int const A::* const A::*icapcap = 0;
+  int A::* A::* iapap = (int A::* A::*)(icapcap);
+}
+
+// ----------- static_cast -------------
+
+struct B : public A {};             // Single public base.
+struct C1 : public virtual B {};    // Single virtual base.
+struct C2 : public virtual B {};
+struct D : public C1, public C2 {}; // Diamond
+struct E : private A {};            // Single private base.
+struct F : public C1 {};            // Single path to B with virtual.
+struct G1 : public B {};
+struct G2 : public B {};
+struct H : public G1, public G2 {}; // Ambiguous path to B.
+
+enum Enum { En1, En2 };
+enum Onom { On1, On2 };
+
+struct Co1 { operator int(); };
+struct Co2 { Co2(int); };
+struct Co3 { };
+struct Co4 { Co4(Co3); operator Co3(); };
+
+// Explicit implicits
+void t_529_2()
+{
+  int i = 1;
+  (void)(float)(i);
+  double d = 1.0;
+  (void)(float)(d);
+  (void)(int)(d);
+  (void)(char)(i);
+  (void)(unsigned long)(i);
+  (void)(int)(En1);
+  (void)(double)(En1);
+  (void)(int&)(i);
+  (void)(const int&)(i);
+
+  int ar[1];
+  (void)(const int*)(ar);
+  (void)(void (*)())(t_529_2);
+
+  (void)(void*)(0);
+  (void)(void*)((int*)0);
+  (void)(volatile const void*)((const int*)0);
+  (void)(A*)((B*)0);
+  (void)(A&)(*((B*)0));
+  (void)(const B*)((C1*)0);
+  (void)(B&)(*((C1*)0));
+  (void)(A*)((D*)0);
+  (void)(const A&)(*((D*)0));
+  (void)(int B::*)((int A::*)0);
+  (void)(void (B::*)())((void (A::*)())0);
+  (void)(A*)((E*)0); // C-style cast ignores access control
+  (void)(void*)((const int*)0); // const_cast appended
+
+  (void)(int)(Co1());
+  (void)(Co2)(1);
+  (void)(Co3)((Co4)(Co3()));
+
+  // Bad code below
+  //(void)(A*)((H*)0); // {{static_cast from 'struct H *' to 'struct A *' is not allowed}}
+}
+
+// Anything to void
+void t_529_4()
+{
+  (void)(1);
+  (void)(t_529_4);
+}
+
+// Static downcasts
+void t_529_5_8()
+{
+  (void)(B*)((A*)0);
+  (void)(B&)(*((A*)0));
+  (void)(const G1*)((A*)0);
+  (void)(const G1&)(*((A*)0));
+  (void)(B*)((const A*)0); // const_cast appended
+  (void)(B&)(*((const A*)0)); // const_cast appended
+  (void)(E*)((A*)0); // access control ignored
+  (void)(E&)(*((A*)0)); // access control ignored
+
+  // Bad code below
+
+  (void)(C1*)((A*)0); // expected-error {{cannot cast 'A *' to 'C1 *' via virtual base 'B'}}
+  (void)(C1&)(*((A*)0)); // expected-error {{cannot cast 'A' to 'C1 &' via virtual base 'B'}}
+  (void)(D*)((A*)0); // expected-error {{cannot cast 'A *' to 'D *' via virtual base 'B'}}
+  (void)(D&)(*((A*)0)); // expected-error {{cannot cast 'A' to 'D &' via virtual base 'B'}}
+  (void)(H*)((A*)0); // expected-error {{ambiguous cast from base 'A' to derived 'H':\n    struct A -> struct B -> struct G1 -> struct H\n    struct A -> struct B -> struct G2 -> struct H}}
+  (void)(H&)(*((A*)0)); // expected-error {{ambiguous cast from base 'A' to derived 'H':\n    struct A -> struct B -> struct G1 -> struct H\n    struct A -> struct B -> struct G2 -> struct H}}
+
+  // TODO: Test DR427. This requires user-defined conversions, though.
+}
+
+// Enum conversions
+void t_529_7()
+{
+  (void)(Enum)(1);
+  (void)(Enum)(1.0);
+  (void)(Onom)(En1);
+
+  // Bad code below
+
+  (void)(Enum)((int*)0); // expected-error {{C-style cast from 'int *' to 'Enum' is not allowed}}
+}
+
+// Void pointer to object pointer
+void t_529_10()
+{
+  (void)(int*)((void*)0);
+  (void)(const A*)((void*)0);
+  (void)(int*)((const void*)0); // const_cast appended
+}
+
+// Member pointer upcast.
+void t_529_9()
+{
+  (void)(int A::*)((int B::*)0);
+
+  // Bad code below
+  (void)(int A::*)((int H::*)0); // expected-error {{ambiguous conversion from pointer to member of derived class 'H' to pointer to member of base class 'A':}}
+  (void)(int A::*)((int F::*)0); // expected-error {{conversion from pointer to member of class 'F' to pointer to member of class 'A' via virtual base 'B' is not allowed}}
+}
+
+// -------- reinterpret_cast -----------
+
+enum test { testval = 1 };
+struct structure { int m; };
+typedef void (*fnptr)();
+
+// Test conversion between pointer and integral types, as in p3 and p4.
+void integral_conversion()
+{
+  void *vp = (void*)(testval);
+  long l = (long)(vp);
+  (void)(float*)(l);
+  fnptr fnp = (fnptr)(l);
+  (void)(char)(fnp); // expected-error {{cast from pointer to smaller type 'char' loses information}}
+  (void)(long)(fnp);
+}
+
+void pointer_conversion()
+{
+  int *p1 = 0;
+  float *p2 = (float*)(p1);
+  structure *p3 = (structure*)(p2);
+  typedef int **ppint;
+  ppint *deep = (ppint*)(p3);
+  (void)(fnptr*)(deep);
+}
+
+void constness()
+{
+  int ***const ipppc = 0;
+  int const *icp = (int const*)(ipppc);
+  (void)(int*)(icp); // const_cast appended
+  int const *const **icpcpp = (int const* const**)(ipppc); // const_cast appended
+  int *ip = (int*)(icpcpp);
+  (void)(int const*)(ip);
+  (void)(int const* const* const*)(ipppc);
+}
+
+void fnptrs()
+{
+  typedef int (*fnptr2)(int);
+  fnptr fp = 0;
+  (void)(fnptr2)(fp);
+  void *vp = (void*)(fp);
+  (void)(fnptr)(vp);
+}
+
+void refs()
+{
+  long l = 0;
+  char &c = (char&)(l);
+  // Bad: from rvalue
+  (void)(int&)(&c); // expected-error {{C-style cast from rvalue to reference type 'int &'}}
+}
+
+void memptrs()
+{
+  const int structure::*psi = 0;
+  (void)(const float structure::*)(psi);
+  (void)(int structure::*)(psi); // const_cast appended
+
+  void (structure::*psf)() = 0;
+  (void)(int (structure::*)())(psf);
+
+  (void)(void (structure::*)())(psi); // expected-error {{C-style cast from 'int const structure::*' to 'void (structure::*)()' is not allowed}}
+  (void)(int structure::*)(psf); // expected-error {{C-style cast from 'void (structure::*)()' to 'int structure::*' is not allowed}}
+}
diff --git a/test/SemaCXX/cxx-member-pointer-op.cpp b/test/SemaCXX/cxx-member-pointer-op.cpp
new file mode 100644
index 0000000..f43d438
--- /dev/null
+++ b/test/SemaCXX/cxx-member-pointer-op.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -fsyntax-only -pedantic -verify %s
+
+struct C {
+  static int (C::* a);
+};
+
+typedef void (C::*pmfc)();
+
+void g(pmfc) {
+  C *c;
+  c->*pmfc(); // expected-error {{invalid use of pointer to member type after ->*}}
+  C c1;
+  c1.*pmfc(); // expected-error {{invalid use of pointer to member type after .*}}
+  c->*(pmfc()); // expected-error {{invalid use of pointer to member type after ->*}}
+  c1.*((pmfc())); // expected-error {{invalid use of pointer to member type after .*}}
+}
+
+int a(C* x) { 
+  return x->*C::a; 
+}
+
diff --git a/test/SemaCXX/dcl_ambig_res.cpp b/test/SemaCXX/dcl_ambig_res.cpp
new file mode 100644
index 0000000..f0ba297
--- /dev/null
+++ b/test/SemaCXX/dcl_ambig_res.cpp
@@ -0,0 +1,73 @@
+// RUN: %clang_cc1 -fsyntax-only -pedantic -verify %s
+
+// [dcl.ambig.res]p1:
+struct S { 
+  S(int); 
+  void bar();
+}; 
+
+int returns_an_int();
+
+void foo(double a) 
+{ 
+  S w(int(a)); // expected-warning{{disambiguated}}
+  w(17);
+  S x1(int()); // expected-warning{{disambiguated}}
+  x1(&returns_an_int);
+  S y((int)a); 
+  y.bar();
+  S z = int(a);
+  z.bar();
+} 
+
+// [dcl.ambig.res]p3:
+char *p; 
+void *operator new(__SIZE_TYPE__, int); 
+void foo3() { 
+  const int x = 63; 
+  new (int(*p)) int; //new-placement expression 
+  new (int(*[x])); //new type-id 
+} 
+
+// [dcl.ambig.res]p4:
+template <class T>  // expected-note{{here}}
+struct S4 { 
+  T *p; 
+}; 
+S4<int()> x; //type-id 
+S4<int(1)> y; // expected-error{{must be a type}}
+
+// [dcl.ambig.res]p5:
+void foo5() 
+{ 
+  (void)sizeof(int(1)); //expression 
+  // FIXME: should we make this an error rather than a warning? 
+  // (It affects SFINAE)
+  (void)sizeof(int()); // expected-warning{{function type}}
+}
+
+// [dcl.ambig.res]p6:
+void foo6() 
+{ 
+  (void)(int(1)); //expression 
+  (void)(int())1; // expected-error{{to 'int ()'}}
+} 
+
+// [dcl.ambig.res]p7:
+class C7 { }; 
+void f7(int(C7)) { } // expected-note{{candidate}}
+int g7(C7); 
+void foo7() { 
+  f7(1); // expected-error{{no matching function}}
+  f7(g7); //OK 
+} 
+
+void h7(int *(C7[10])) { } // expected-note{{previous}}
+void h7(int *(*_fp)(C7 _parm[10])) { } // expected-error{{redefinition}}
+
+struct S5 {
+  static bool const value = false;
+};
+int foo8() {
+  int v(int(S5::value)); // expected-warning{{disambiguated}} expected-error{{parameter declarator cannot be qualified}}
+}
diff --git a/test/SemaCXX/dcl_init_aggr.cpp b/test/SemaCXX/dcl_init_aggr.cpp
new file mode 100644
index 0000000..8b28663
--- /dev/null
+++ b/test/SemaCXX/dcl_init_aggr.cpp
@@ -0,0 +1,123 @@
+// RUN: %clang_cc1 -fsyntax-only -pedantic -verify %s
+// C++ [dcl.init.aggr]p2
+struct A { 
+  int x;
+  struct B { 
+    int i;
+    int j;
+  } b; 
+} a1 = { 1, { 2, 3 } };
+
+struct NonAggregate {
+  NonAggregate();
+
+  int a, b;
+};
+NonAggregate non_aggregate_test = { 1, 2 }; // expected-error{{non-aggregate type 'NonAggregate' cannot be initialized with an initializer list}}
+
+NonAggregate non_aggregate_test2[2] = { { 1, 2 }, { 3, 4 } }; // expected-error 2 {{initialization of non-aggregate type 'NonAggregate' with an initializer list}}
+
+
+// C++ [dcl.init.aggr]p3
+A a_init = A(); 
+
+// C++ [dcl.init.aggr]p4
+int x[] = { 1, 3, 5 };
+int x_sizecheck[(sizeof(x) / sizeof(int)) == 3? 1 : -1];
+int x2[] = { }; // expected-warning{{zero size arrays are an extension}}
+
+// C++ [dcl.init.aggr]p5
+struct StaticMemberTest {
+  int i;
+  static int s;
+  int *j;
+} smt = { 1, &smt.i };
+
+// C++ [dcl.init.aggr]p6
+char cv[4] = { 'a', 's', 'd', 'f', 0 }; // expected-error{{excess elements in array initializer}}
+
+// C++ [dcl.init.aggr]p7
+struct TooFew { int a; char* b; int c; }; 
+TooFew too_few = { 1, "asdf" }; // expected-warning{{conversion from string literal to 'char *' is deprecated}}
+
+struct NoDefaultConstructor { // expected-note 3 {{candidate constructor (the implicit copy constructor)}} \
+                              // expected-note{{declared here}}
+  NoDefaultConstructor(int); // expected-note 3 {{candidate constructor}}
+};
+struct TooFewError { // expected-error{{implicit default constructor for}}
+  int a;
+  NoDefaultConstructor nodef; // expected-note{{member is declared here}}
+};
+TooFewError too_few_okay = { 1, 1 };
+TooFewError too_few_error = { 1 }; // expected-error{{no matching constructor}}
+
+TooFewError too_few_okay2[2] = { 1, 1 }; // expected-note{{implicit default constructor for 'TooFewError' first required here}}
+TooFewError too_few_error2[2] = { 1 }; // expected-error{{no matching constructor}}
+
+NoDefaultConstructor too_few_error3[3] = { }; // expected-error {{no matching constructor}}
+
+// C++ [dcl.init.aggr]p8
+struct Empty { };
+struct EmptyTest {
+  Empty s;
+  int i;
+} empty_test = { { }, 3 };
+
+EmptyTest empty_test2 = { 3 }; // expected-error{{initializer for aggregate with no elements requires explicit braces}}
+
+struct NonEmpty { 
+  int a;
+  Empty empty;
+};
+struct NonEmptyTest {
+  NonEmpty a, b;
+} non_empty_test = { { }, { } };
+
+// C++ [dcl.init.aggr]p9
+struct HasReference {
+  int i;
+  int &j; // expected-note{{uninitialized reference member is here}}
+};
+int global_int;
+HasReference r1 = { 1, global_int };
+HasReference r2 = { 1 } ; // expected-error{{initialization leaves reference member of type 'int &' uninitialized}}
+
+// C++ [dcl.init.aggr]p10
+// Note: the behavior here is identical to C
+int xs[2][2] = { 3, 1, 4, 2 };
+float y[4][3] = { { 1 }, { 2 }, { 3 }, { 4 } };
+
+// C++ [dcl.init.aggr]p11
+// Note: the behavior here is identical to C
+float y2[4][3] = { { 1, 3, 5 }, { 2, 4, 6 }, { 3, 5, 7 } };
+float same_as_y2[4][3] = { 1, 3, 5, 2, 4, 6, 3, 5, 7 };
+
+// C++ [dcl.init.aggr]p12
+struct A2 { 
+  int i;
+  operator int *();
+}; 
+struct B2 {
+  A2 a1, a2; 
+  int *z;
+}; 
+struct C2 {
+  operator A2();
+};
+struct D2 {
+  operator int();
+};
+A2 a2;
+C2 c2; 
+D2 d2;
+B2 b2 = { 4, a2, a2 };
+B2 b2_2 = { 4, d2, 0 };
+B2 b2_3 = { c2, a2, a2 };
+
+// C++ [dcl.init.aggr]p15:
+union u { int a; char* b; }; // expected-note{{candidate constructor (the implicit copy constructor)}}
+u u1 = { 1 }; 
+u u2 = u1; 
+u u3 = 1; // expected-error{{no viable conversion}}
+u u4 = { 0, "asdf" };  // expected-error{{excess elements in union initializer}}
+u u5 = { "asdf" }; // expected-error{{cannot initialize a member subobject of type 'int' with an lvalue of type 'char const [5]'}}
diff --git a/test/SemaCXX/decl-expr-ambiguity.cpp b/test/SemaCXX/decl-expr-ambiguity.cpp
new file mode 100644
index 0000000..4243c1c
--- /dev/null
+++ b/test/SemaCXX/decl-expr-ambiguity.cpp
@@ -0,0 +1,43 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -pedantic-errors %s 
+
+void f() {
+  int a;
+  struct S { int m; };
+  typedef S *T;
+
+  // Expressions.
+  T(a)->m = 7;
+  int(a)++; // expected-error {{expression is not assignable}}
+  __extension__ int(a)++; // expected-error {{expression is not assignable}}
+  __typeof(int)(a,5)<<a; // expected-error {{function-style cast to a builtin type can only take one argument}}
+  void(a), ++a;
+  if (int(a)+1) {}
+  for (int(a)+1;;) {} // expected-warning {{expression result unused}}
+  a = sizeof(int()+1);
+  a = sizeof(int(1));
+  typeof(int()+1) a2; // expected-error {{extension used}}
+  (int(1)); // expected-warning {{expression result unused}}
+
+  // type-id
+  (int())1; // expected-error {{C-style cast from 'int' to 'int ()' is not allowed}}
+
+  // Declarations.
+  int fd(T(a)); // expected-warning {{parentheses were disambiguated as a function declarator}}
+  T(*d)(int(p)); // expected-warning {{parentheses were disambiguated as a function declarator}} expected-note {{previous definition is here}}
+  T(d)[5]; // expected-error {{redefinition of 'd'}}
+  typeof(int[])(f) = { 1, 2 }; // expected-error {{extension used}}
+  void(b)(int);
+  int(d2) __attribute__(()); 
+  if (int(a)=1) {}
+  int(d3(int()));
+}
+
+class C { };
+void fn(int(C)) { } // void fn(int(*fp)(C c)) { } expected-note{{candidate function}}
+                    // not: void fn(int C);
+int g(C);
+
+void foo() {
+  fn(1); // expected-error {{no matching function}}
+  fn(g); // OK
+}
diff --git a/test/SemaCXX/decl-init-ref.cpp b/test/SemaCXX/decl-init-ref.cpp
new file mode 100644
index 0000000..7ae0439
--- /dev/null
+++ b/test/SemaCXX/decl-init-ref.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s
+
+struct A {}; // expected-note {{candidate is the implicit copy constructor}}
+
+struct BASE {
+  operator A(); // expected-note {{candidate function}}
+};
+
+struct BASE1 {
+ operator A();  // expected-note {{candidate function}}
+};
+
+class B : public BASE , public BASE1
+{
+  public:
+  B();
+} b;
+
+extern B f();
+
+const int& ri = (void)0; // expected-error {{reference to type 'int const' could not bind to an rvalue of type 'void'}}
+
+int main() {
+        const A& rca = f(); // expected-error {{reference initialization of type 'A const &' with initializer of type 'B' is ambiguous}}
+        A& ra = f(); // expected-error {{non-const lvalue reference to type 'A' cannot bind to a temporary of type 'B'}}
+}
+
+struct PR6139 { A (&x)[1]; };
+PR6139 x = {{A()}}; // expected-error{{non-const lvalue reference to type 'A [1]' cannot bind to a temporary of type 'A'}}
diff --git a/test/SemaCXX/decltype-crash.cpp b/test/SemaCXX/decltype-crash.cpp
new file mode 100644
index 0000000..f94ba45
--- /dev/null
+++ b/test/SemaCXX/decltype-crash.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+int& a();
+
+void f() {
+  decltype(a()) c; // expected-error {{use of undeclared identifier 'decltype'}}
+}
diff --git a/test/SemaCXX/decltype-overloaded-functions.cpp b/test/SemaCXX/decltype-overloaded-functions.cpp
new file mode 100644
index 0000000..0aa49b0
--- /dev/null
+++ b/test/SemaCXX/decltype-overloaded-functions.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
+
+void f();
+void f(int);
+decltype(f) a; // expected-error{{cannot determine the declared type of an overloaded function}}
+
+template<typename T> struct S {
+  decltype(T::f) * f; // expected-error{{cannot determine the declared type of an overloaded function}}
+};
+
+struct K { void f(); void f(int); };
+S<K> b; // expected-note{{in instantiation of template class 'S<K>' requested here}}
diff --git a/test/SemaCXX/decltype-pr4444.cpp b/test/SemaCXX/decltype-pr4444.cpp
new file mode 100644
index 0000000..456b22c
--- /dev/null
+++ b/test/SemaCXX/decltype-pr4444.cpp
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
+
+template<typename T, T t>
+struct TestStruct {
+   typedef decltype(t+2) sum_type;
+};
diff --git a/test/SemaCXX/decltype-pr4448.cpp b/test/SemaCXX/decltype-pr4448.cpp
new file mode 100644
index 0000000..ead24ce
--- /dev/null
+++ b/test/SemaCXX/decltype-pr4448.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
+
+template< typename T, T t, decltype(t+2) v >
+struct Convoluted {};
+
+int test_array[5];
+
+Convoluted< int *, test_array, nullptr > tarray;
diff --git a/test/SemaCXX/decltype-this.cpp b/test/SemaCXX/decltype-this.cpp
new file mode 100644
index 0000000..f9bf499
--- /dev/null
+++ b/test/SemaCXX/decltype-this.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s
+
+template<typename T, typename U> struct is_same {
+  static const bool value = false;
+};
+
+template<typename T> struct is_same<T, T> {
+  static const bool value = true;
+};
+
+struct S {
+  void f() { static_assert(is_same<decltype(this), S*>::value, ""); }
+  void g() const { static_assert(is_same<decltype(this), const S*>::value, ""); }
+  void h() volatile { static_assert(is_same<decltype(this), volatile S*>::value, ""); }
+  void i() const volatile { static_assert(is_same<decltype(this), const volatile S*>::value, ""); }
+};
diff --git a/test/SemaCXX/default-argument-temporaries.cpp b/test/SemaCXX/default-argument-temporaries.cpp
new file mode 100644
index 0000000..3ab7bf4
--- /dev/null
+++ b/test/SemaCXX/default-argument-temporaries.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+struct B { B(void* = 0); };
+
+struct A {
+  A(B b = B()) { }
+};
+
+void f() {
+  (void)B();
+  (void)A();
+}
diff --git a/test/SemaCXX/default-assignment-operator.cpp b/test/SemaCXX/default-assignment-operator.cpp
new file mode 100644
index 0000000..81e7059
--- /dev/null
+++ b/test/SemaCXX/default-assignment-operator.cpp
@@ -0,0 +1,87 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+class Base { // expected-error {{cannot define the implicit default assignment operator for 'Base', because non-static reference member 'ref' can't use default assignment operator}} \
+  // expected-warning{{class 'Base' does not declare any constructor to initialize its non-modifiable members}}
+  int &ref;  // expected-note {{declared here}} \
+  // expected-note{{reference member 'ref' will never be initialized}}
+};
+
+class X  : Base {  // // expected-error {{cannot define the implicit default assignment operator for 'X', because non-static const member 'cint' can't use default assignment operator}}
+public:
+  X();
+  const int cint;  // expected-note {{declared here}}
+}; 
+
+struct Y  : X { 
+  Y();
+  Y& operator=(const Y&);
+  Y& operator=(volatile Y&);
+  Y& operator=(const volatile Y&);
+  Y& operator=(Y&);
+}; 
+
+class Z : Y {};
+
+Z z1;
+Z z2;
+
+// Test1
+void f(X x, const X cx) {
+  x = cx;  // expected-note 2 {{synthesized method is first required here}}
+  x = cx;
+  z1 = z2;
+}
+
+// Test2
+class T {};
+T t1;
+T t2;
+
+void g() {
+  t1 = t2;
+}
+
+// Test3
+class V {
+public:
+  V();
+  V &operator = (V &b);
+};
+
+class W : V {};
+W w1, w2;
+
+void h() {
+  w1 = w2;
+}
+
+// Test4
+
+class B1 {
+public:
+  B1();
+  B1 &operator = (B1 b);
+};
+
+class D1 : B1 {};
+D1 d1, d2;
+
+void i() {
+  d1 = d2;
+}
+
+// Test5
+
+class E1 { // expected-error{{cannot define the implicit default assignment operator for 'E1', because non-static const member 'a' can't use default assignment operator}}
+public:
+  const int a; // expected-note{{declared here}}
+  E1() : a(0) {}  
+
+};
+
+E1 e1, e2;
+
+void j() {
+  e1 = e2; // expected-note{{synthesized method is first required here}}
+}
+
diff --git a/test/SemaCXX/default-constructor-initializers.cpp b/test/SemaCXX/default-constructor-initializers.cpp
new file mode 100644
index 0000000..757332d
--- /dev/null
+++ b/test/SemaCXX/default-constructor-initializers.cpp
@@ -0,0 +1,55 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct X1 { // has no implicit default constructor
+   X1(int);
+};
+
+struct X2  : X1 {  // expected-note 2 {{'X2' declared here}}
+   X2(int);
+};
+
+struct X3 : public X2 { // expected-error {{implicit default constructor for 'X3' must explicitly initialize the base class 'X2' which does not have a default constructor}}
+};
+X3 x3; // expected-note {{first required here}}
+
+
+struct X4 { // expected-error {{must explicitly initialize the member 'x2'}} \
+            // expected-error {{must explicitly initialize the reference member 'rx2'}}
+  X2 x2; 	// expected-note {{member is declared here}}
+  X2 & rx2; // expected-note {{declared here}}
+};
+
+X4 x4; // expected-note {{first required here}}
+
+
+struct Y1 { // has no implicit default constructor
+   Y1(int);
+};
+
+struct Y2  : Y1 { 
+   Y2(int);
+   Y2();
+};
+
+struct Y3 : public Y2 {
+};
+Y3 y3; 
+
+struct Y4 {
+  Y2 y2; 
+};
+
+Y4 y4;
+
+// More tests
+
+
+struct Z1 { // expected-error {{must explicitly initialize the reference member 'z'}} \
+            // expected-error {{must explicitly initialize the const member 'c1'}}
+  int& z;       // expected-note {{declared here}}
+  const int c1; // expected-note {{declared here}}
+  volatile int v1;
+};
+
+Z1 z1; // expected-note {{first required here}}
+
diff --git a/test/SemaCXX/default1.cpp b/test/SemaCXX/default1.cpp
new file mode 100644
index 0000000..e9d8a2f
--- /dev/null
+++ b/test/SemaCXX/default1.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+void f(int i);
+void f(int i = 0); // expected-note {{previous definition is here}}
+void f(int i = 17); // expected-error {{redefinition of default argument}}
+
+
+void g(int i, int j, int k = 3);
+void g(int i, int j = 2, int k);
+void g(int i = 1, int j, int k);
+
+void h(int i, int j = 2, int k = 3, 
+       int l, // expected-error {{missing default argument on parameter 'l'}}
+       int,   // expected-error {{missing default argument on parameter}}
+       int n);// expected-error {{missing default argument on parameter 'n'}}
+
+struct S { } s;
+void i(int = s) { } // expected-error {{no viable conversion}} \
+// expected-note{{passing argument to parameter here}}
+
+struct X { 
+  X(int);
+};
+
+void j(X x = 17);
+
+struct Y { // expected-note 2{{candidate}}
+  explicit Y(int);
+};
+
+void k(Y y = 17); // expected-error{{no viable conversion}} \
+// expected-note{{passing argument to parameter 'y' here}}
+
+void kk(Y = 17); // expected-error{{no viable conversion}} \
+// expected-note{{passing argument to parameter here}}
diff --git a/test/SemaCXX/default2.cpp b/test/SemaCXX/default2.cpp
new file mode 100644
index 0000000..d9f1edf
--- /dev/null
+++ b/test/SemaCXX/default2.cpp
@@ -0,0 +1,121 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+void f(int i, int j, int k = 3);
+void f(int i, int j, int k);
+void f(int i, int j = 2, int k);
+void f(int i, int j, int k);
+void f(int i = 1, int j, int k);
+void f(int i, int j, int k);
+
+void i()
+{
+  f();
+  f(0);
+  f(0, 1);
+  f(0, 1, 2);
+}
+
+
+int f1(int i,          // expected-note {{previous declaration is here}}
+       int i, int j) { // expected-error {{redefinition of parameter 'i'}}
+  i = 17;
+  return j;
+} 
+
+int x;
+void g(int x, int y = x); // expected-error {{default argument references parameter 'x'}}
+
+void g2(int x, int y, int z = x + y); // expected-error {{default argument references parameter 'x'}} expected-error {{default argument references parameter 'y'}}
+
+class X {
+  void f(X* x = this); // expected-error{{invalid use of 'this' outside of a nonstatic member function}}
+
+  void g() { 
+    int f(X* x = this); // expected-error{{default argument references 'this'}}
+  }
+};
+
+// C++ [dcl.fct.default]p6
+class C { 
+  static int x;
+  void f(int i = 3); // expected-note{{previous definition is here}}
+  void g(int i, int j = x); 
+
+  void h();
+}; 
+void C::f(int i = 3) // expected-error{{redefinition of default argument}}
+{ } 
+
+void C::g(int i = 88, int j) {}
+
+void C::h() {
+  g(); // okay
+}
+
+// C++ [dcl.fct.default]p9
+struct Y { 
+  int a; 
+  int mem1(int i = a); // expected-error{{invalid use of nonstatic data member 'a'}}
+  int mem2(int i = b); // OK; use Y::b 
+  int mem3(int i);
+  int mem4(int i);
+
+  struct Nested {
+    int mem5(int i = b, // OK; use Y::b
+             int j = c, // OK; use Y::Nested::c
+             int k = j, // expected-error{{default argument references parameter 'j'}}
+             int l = a,  // expected-error{{invalid use of nonstatic data member 'a'}}
+             Nested* self = this, // expected-error{{invalid use of 'this' outside of a nonstatic member function}}
+             int m); // expected-error{{missing default argument on parameter 'm'}}
+    static int c;
+  };
+
+  static int b; 
+}; 
+
+int Y::mem3(int i = b) { return i; } // OK; use X::b
+
+int Y::mem4(int i = a) // expected-error{{invalid use of nonstatic data member 'a'}}
+{ return i; }
+
+
+// Try to verify that default arguments interact properly with copy
+// constructors.
+class Z {
+public:
+  Z(Z&, int i = 17); // expected-note 3 {{candidate constructor}}
+
+  void f(Z& z) { 
+    Z z2;    // expected-error{{no matching constructor for initialization}}
+    Z z3(z);
+  }
+
+  void test_Z(const Z& z) {
+    Z z2(z); // expected-error{{no matching constructor for initialization of 'Z'}}
+  }
+};
+
+void test_Z(const Z& z) {
+  Z z2(z); // expected-error{{no matching constructor for initialization of 'Z'}}
+}
+
+struct ZZ {
+  static ZZ g(int = 17);
+
+  void f(ZZ z = g()); // expected-error{{no matching constructor for initialization}} \
+  // expected-note{{passing argument to parameter 'z' here}}
+
+  ZZ(ZZ&, int = 17); // expected-note{{candidate constructor}}
+};
+
+// http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#325
+class C2 {
+  static void g(int = f()); // expected-error{{use of default argument to function 'f' that is declared later in class 'C2'}}
+  static int f(int = 10); // expected-note{{default argument declared here}}
+};
+
+// Make sure we actually parse the default argument for an inline definition
+class XX {
+  void A(int length = -1 ) {  } 
+  void B() { A(); }
+};
diff --git a/test/SemaCXX/deleted-function.cpp b/test/SemaCXX/deleted-function.cpp
new file mode 100644
index 0000000..b3e1296
--- /dev/null
+++ b/test/SemaCXX/deleted-function.cpp
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s
+
+int i = delete; // expected-error {{only functions can have deleted definitions}}
+
+void fn() = delete; // expected-note {{candidate function has been explicitly deleted}}
+
+void fn2(); // expected-note {{previous declaration is here}}
+void fn2() = delete; // expected-error {{deleted definition must be first declaration}}
+
+void fn3() = delete;
+void fn3() {
+  // FIXME: This definition should be invalid.
+}
+
+void ov(int) {} // expected-note {{candidate function}}
+void ov(double) = delete; // expected-note {{candidate function has been explicitly deleted}}
+
+struct WithDel {
+  WithDel() = delete; // expected-note {{function has been explicitly marked deleted here}}
+  void fn() = delete; // expected-note {{function has been explicitly marked deleted here}}
+  operator int() = delete; // expected-note {{function has been explicitly marked deleted here}}
+  void operator +(int) = delete;
+
+  int i = delete; // expected-error {{only functions can have deleted definitions}}
+};
+
+void test() {
+  fn(); // expected-error {{call to deleted function 'fn'}}
+  ov(1);
+  ov(1.0); // expected-error {{call to deleted function 'ov'}}
+
+  WithDel dd; // expected-error {{call to deleted constructor of 'WithDel'}}
+  WithDel *d = 0;
+  d->fn(); // expected-error {{attempt to use a deleted function}}
+  int i = *d; // expected-error {{invokes a deleted function}}
+}
diff --git a/test/SemaCXX/dependent-types.cpp b/test/SemaCXX/dependent-types.cpp
new file mode 100644
index 0000000..d9b5323
--- /dev/null
+++ b/test/SemaCXX/dependent-types.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -pedantic -verify %s
+
+template<typename T, int Size> void f() {
+  T x1;
+  T* x2;
+  T& x3; // expected-error{{declaration of reference variable 'x3' requires an initializer}}
+  T x4[]; // expected-error{{needs an explicit size or an initializer}}
+  T x5[Size];
+  int x6[Size];
+}
diff --git a/test/SemaCXX/derived-to-base-ambig.cpp b/test/SemaCXX/derived-to-base-ambig.cpp
new file mode 100644
index 0000000..129ec79
--- /dev/null
+++ b/test/SemaCXX/derived-to-base-ambig.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+class A { };
+class B : public A { };
+class C : public A { };
+class D : public B, public C { };
+
+void f(D* d) {
+  A* a;
+  a = d; // expected-error{{ambiguous conversion from derived class 'D' to base class 'A':}} expected-error{{assigning to 'A *' from incompatible type 'D *'}}
+}
+
+class Object2 { };
+class A2 : public Object2 { };
+class B2 : public virtual A2 { };
+class C2 : virtual public A2 { };
+class D2 : public B2, public C2 { };
+class E2 : public D2, public C2, public virtual A2 { };
+class F2 : public E2, public A2 { };
+
+void g(E2* e2, F2* f2) {
+  Object2* o2;
+  o2 = e2;
+  o2 = f2; // expected-error{{ambiguous conversion from derived class 'F2' to base class 'Object2':}} expected-error{{assigning to 'Object2 *' from incompatible type 'F2 *'}}
+}
+
+// Test that ambiguous/inaccessibility checking does not trigger too
+// early, because it should not apply during overload resolution.
+void overload_okay(Object2*);
+void overload_okay(E2*);
+
+void overload_call(F2* f2) {
+  overload_okay(f2);
+}
diff --git a/test/SemaCXX/destructor.cpp b/test/SemaCXX/destructor.cpp
new file mode 100644
index 0000000..ae3dc86
--- /dev/null
+++ b/test/SemaCXX/destructor.cpp
@@ -0,0 +1,85 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s 
+class A {
+public:
+  ~A();
+};
+
+class B {
+public:
+  ~B() { }
+};
+
+class C {
+public:
+  (~C)() { }
+};
+
+struct D {
+  static void ~D(int, ...) const { } //                          \
+    // expected-error{{type qualifier is not allowed on this function}} \
+    // expected-error{{destructor cannot be declared 'static'}}  \
+    // expected-error{{destructor cannot have any parameters}}   \
+    // expected-error{{destructor cannot be variadic}}
+};
+
+struct D2 {
+  void ~D2() { } //                          \
+  // expected-error{{destructor cannot have a return type}}  
+};
+
+
+struct E;
+
+typedef E E_typedef;
+struct E {
+  ~E_typedef(); // expected-error{{destructor cannot be declared using a typedef 'E_typedef' (aka 'E') of the class name}}
+};
+
+struct F {
+  (~F)(); // expected-note {{previous declaration is here}}
+  ~F(); // expected-error {{destructor cannot be redeclared}}
+};
+
+~; // expected-error {{expected a class name after '~' to name a destructor}}
+~undef(); // expected-error {{expected the class name after '~' to name a destructor}}
+~operator+(int, int);  // expected-error {{expected a class name after '~' to name a destructor}}
+~F(){} // expected-error {{destructor must be a non-static member function}}
+
+struct G {
+  ~G();
+};
+
+G::~G() { }
+
+// <rdar://problem/6841210>
+struct H {
+  ~H(void) { } 
+};
+
+struct X {};
+
+struct Y {
+  ~X(); // expected-error {{expected the class name after '~' to name the enclosing class}}
+};
+
+namespace PR6421 {
+  class T; // expected-note{{forward declaration}}
+
+  class QGenericArgument
+  {
+    template<typename U>
+    void foo(T t) // expected-error{{variable has incomplete type}}
+    { }
+    
+    void disconnect()
+    {
+      T* t;
+      bob<QGenericArgument>(t); // expected-error{{undeclared identifier 'bob'}}
+    }
+  };
+}
+
+namespace PR6709 {
+  template<class T> class X { T v; ~X() { ++*v; } };
+  void a(X<int> x) {}
+}
diff --git a/test/SemaCXX/direct-initializer.cpp b/test/SemaCXX/direct-initializer.cpp
new file mode 100644
index 0000000..54cd6ca
--- /dev/null
+++ b/test/SemaCXX/direct-initializer.cpp
@@ -0,0 +1,50 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s 
+
+int x(1);
+int (x2)(1);
+
+void f() {
+  int x(1);
+  int (x2)(1);
+  for (int x(1);;) {}
+}
+
+class Y { 
+public: explicit Y(float);
+};
+
+class X { // expected-note{{candidate constructor (the implicit copy constructor)}}
+public:
+  explicit X(int); // expected-note{{candidate constructor}}
+  X(float, float, float); // expected-note{{candidate constructor}}
+  X(float, Y); // expected-note{{candidate constructor}}
+};
+
+class Z { // expected-note{{candidate constructor (the implicit copy constructor)}}
+public:
+  Z(int); // expected-note{{candidate constructor}}
+};
+
+void g() {
+  X x1(5);
+  X x2(1.0, 3, 4.2);
+  X x3(1.0, 1.0); // expected-error{{no matching constructor for initialization of 'X'}}
+  Y y(1.0);
+  X x4(3.14, y);
+
+  Z z; // expected-error{{no matching constructor for initialization of 'Z'}}
+}
+
+struct Base {
+   operator int*() const; 
+};
+
+struct Derived : Base {
+   operator int*(); // expected-note {{candidate function}}
+};
+
+void foo(const Derived cd, Derived d) {
+        int *pi = cd;	// expected-error {{no viable conversion from 'Derived const' to 'int *'}}
+        int *ppi = d; 
+
+}
diff --git a/test/SemaCXX/do-while-scope.cpp b/test/SemaCXX/do-while-scope.cpp
new file mode 100644
index 0000000..2602ae1
--- /dev/null
+++ b/test/SemaCXX/do-while-scope.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s 
+
+void test() {
+  int x;
+  do
+    int x;
+  while (1);
+}
diff --git a/test/SemaCXX/dynamic-cast.cpp b/test/SemaCXX/dynamic-cast.cpp
new file mode 100644
index 0000000..b73e8c5
--- /dev/null
+++ b/test/SemaCXX/dynamic-cast.cpp
@@ -0,0 +1,74 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct A {};
+struct B : A {};
+struct C : B {};
+
+struct D : private A {};
+struct E : A {};
+struct F : B, E {};
+
+struct Incomplete; // expected-note 2 {{forward declaration of 'Incomplete'}}
+
+struct Poly
+{
+  virtual void f();
+};
+
+struct PolyDerived : Poly
+{
+};
+
+void basic_bad()
+{
+  // ptr -> nonptr
+  (void)dynamic_cast<A>((A*)0); // expected-error {{'A' is not a reference or pointer}}
+  // nonptr -> ptr
+  (void)dynamic_cast<A*>(0); // expected-error {{'int' is not a pointer}}
+  // ptr -> noncls
+  (void)dynamic_cast<int*>((A*)0); // expected-error {{'int' is not a class}}
+  // noncls -> ptr
+  (void)dynamic_cast<A*>((int*)0); // expected-error {{'int' is not a class}}
+  // ref -> noncls
+  (void)dynamic_cast<int&>(*((A*)0)); // expected-error {{'int' is not a class}}
+  // noncls -> ref
+  (void)dynamic_cast<A&>(*((int*)0)); // expected-error {{'int' is not a class}}
+  // ptr -> incomplete
+  (void)dynamic_cast<Incomplete*>((A*)0); // expected-error {{'Incomplete' is an incomplete type}}
+  // incomplete -> ptr
+  (void)dynamic_cast<A*>((Incomplete*)0); // expected-error {{'Incomplete' is an incomplete type}}
+}
+
+void same()
+{
+  (void)dynamic_cast<A*>((A*)0);
+  (void)dynamic_cast<A&>(*((A*)0));
+}
+
+void up()
+{
+  (void)dynamic_cast<A*>((B*)0);
+  (void)dynamic_cast<A&>(*((B*)0));
+  (void)dynamic_cast<A*>((C*)0);
+  (void)dynamic_cast<A&>(*((C*)0));
+
+  // Inaccessible
+  //(void)dynamic_cast<A*>((D*)0);
+  //(void)dynamic_cast<A&>(*((D*)0));
+
+  // Ambiguous
+  (void)dynamic_cast<A*>((F*)0); // expected-error {{ambiguous conversion from derived class 'F' to base class 'A':\n    struct F -> struct B -> struct A\n    struct F -> struct E -> struct A}}
+  (void)dynamic_cast<A&>(*((F*)0)); // expected-error {{ambiguous conversion from derived class 'F' to base class 'A':\n    struct F -> struct B -> struct A\n    struct F -> struct E -> struct A}}
+}
+
+void poly()
+{
+  (void)dynamic_cast<A*>((Poly*)0);
+  (void)dynamic_cast<A&>(*((Poly*)0));
+  (void)dynamic_cast<A*>((PolyDerived*)0);
+  (void)dynamic_cast<A&>(*((PolyDerived*)0));
+
+  // Not polymorphic source
+  (void)dynamic_cast<Poly*>((A*)0); // expected-error {{'A' is not polymorphic}}
+  (void)dynamic_cast<PolyDerived&>(*((A*)0)); // expected-error {{'A' is not polymorphic}}
+}
diff --git a/test/SemaCXX/elaborated-type-specifier.cpp b/test/SemaCXX/elaborated-type-specifier.cpp
new file mode 100644
index 0000000..2d0b571
--- /dev/null
+++ b/test/SemaCXX/elaborated-type-specifier.cpp
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// Test the use of elaborated-type-specifiers to inject the names of
+// structs (or classes or unions) into an outer scope as described in
+// C++ [basic.scope.pdecl]p5.
+typedef struct S1 {
+  union {
+    struct S2 *x;
+    struct S3 *y;
+  };
+} S1;
+
+bool test_elab(S1 *s1, struct S2 *s2, struct S3 *s3) {
+  if (s1->x == s2) return true;
+  if (s1->y == s3) return true;
+  return false;
+}
+
+namespace NS {
+  class X {
+  public:
+    void test_elab2(struct S4 *s4);
+  };
+
+  void X::test_elab2(S4 *s4) { } // expected-note{{passing argument to parameter 's4' here}}
+}
+
+void test_X_elab(NS::X x) {
+  struct S4 *s4 = 0;
+  x.test_elab2(s4); // expected-error{{cannot initialize a parameter of type 'NS::S4 *' with an lvalue of type 'struct S4 *'}}
+}
+
+namespace NS {
+  S4 *get_S4();
+}
+
+void test_S5_scope() {
+  S4 *s4; // expected-error{{use of undeclared identifier 'S4'}}
+}
+
+int test_funcparam_scope(struct S5 * s5) {
+  struct S5 { int y; } *s5_2 = 0;
+  if (s5 == s5_2) return 1; // expected-error {{comparison of distinct pointer types ('struct S5 *' and 'struct S5 *')}}
+  return 0;
+}
+
+
diff --git a/test/SemaCXX/empty-class-layout.cpp b/test/SemaCXX/empty-class-layout.cpp
new file mode 100644
index 0000000..c3dc733
--- /dev/null
+++ b/test/SemaCXX/empty-class-layout.cpp
@@ -0,0 +1,68 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown %s -fsyntax-only -verify 
+
+#define SA(n, p) int a##n[(p) ? 1 : -1]
+
+struct A { int a; };
+SA(0, sizeof(A) == 4);
+
+struct B { };
+SA(1, sizeof(B) == 1);
+
+struct C : A, B { };
+SA(2, sizeof(C) == 4);
+
+struct D { };
+struct E : D { };
+struct F : E { };
+
+struct G : E, F { };
+SA(3, sizeof(G) == 2);
+
+struct Empty { Empty(); };
+
+struct I : Empty { 
+  Empty e;
+};
+SA(4, sizeof(I) == 2);
+
+struct J : Empty { 
+  Empty e[2];
+};
+SA(5, sizeof(J) == 3);
+
+template<int N> struct Derived : Empty, Derived<N - 1> { 
+};
+template<> struct Derived<0> : Empty { };
+
+struct S1 : virtual Derived<10> { 
+  Empty e;
+};
+SA(6, sizeof(S1) == 24);
+
+struct S2 : virtual Derived<10> { 
+  Empty e[2];
+};
+SA(7, sizeof(S2) == 24);
+
+struct S3 {
+  Empty e;
+};
+
+struct S4 : Empty, S3 { 
+};
+SA(8, sizeof(S4) == 2);
+
+struct S5 : S3, Empty {};
+SA(9, sizeof(S5) == 2);
+
+struct S6 : S5 { };
+SA(10, sizeof(S6) == 2);
+
+struct S7 : Empty {
+  void *v;
+};
+SA(11, sizeof(S7) == 8);
+
+struct S8 : Empty, A {
+};
+SA(12, sizeof(S8) == 4);
diff --git a/test/SemaCXX/enum.cpp b/test/SemaCXX/enum.cpp
new file mode 100644
index 0000000..dc4a506
--- /dev/null
+++ b/test/SemaCXX/enum.cpp
@@ -0,0 +1,73 @@
+// RUN: %clang_cc1 -fsyntax-only -pedantic -std=c++98 -verify -triple x86_64-apple-darwin %s
+
+enum E {
+  Val1,
+  Val2
+};
+
+int& enumerator_type(int);
+float& enumerator_type(E);
+
+void f() {
+  E e = Val1;
+  float& fr = enumerator_type(Val2);
+}
+
+// <rdar://problem/6502934>
+typedef enum Foo {
+  A = 0,
+  B = 1
+} Foo;
+
+void bar() {
+  Foo myvar = A;
+  myvar = B;
+}
+
+/// PR3688
+struct s1 {
+  enum e1 (*bar)(void); // expected-error{{ISO C++ forbids forward references to 'enum' types}}
+};
+
+enum e1 { YES, NO };
+
+static enum e1 badfunc(struct s1 *q) {
+  return q->bar();
+}
+
+enum e2; // expected-error{{ISO C++ forbids forward references to 'enum' types}}
+
+namespace test1 {
+  template <class A, class B> struct is_same { static const int value = -1; };
+  template <class A> struct is_same<A,A> { static const int value = 1; };
+
+  enum enum0 { v0 };
+  int test0[is_same<__typeof(+v0), int>::value];
+
+  enum enum1 { v1 = __INT_MAX__ };
+  int test1[is_same<__typeof(+v1), int>::value];
+
+  enum enum2 { v2 = __INT_MAX__ * 2U };
+  int test2[is_same<__typeof(+v2), unsigned int>::value];
+
+  enum enum3 { v3 = __LONG_MAX__ };
+  int test3[is_same<__typeof(+v3), long>::value];
+
+  enum enum4 { v4 = __LONG_MAX__ * 2UL };
+  int test4[is_same<__typeof(+v4), unsigned long>::value];
+}
+
+// PR6061
+namespace PR6061 {
+  struct A { enum { id }; };
+  struct B { enum { id }; };
+  
+  struct C : public A, public B
+  { 
+    enum { id }; 
+  };
+}
+
+namespace Conditional {
+  enum a { A }; a x(const enum a x) { return 1?x:A; }
+}
diff --git a/test/SemaCXX/exception-spec.cpp b/test/SemaCXX/exception-spec.cpp
new file mode 100644
index 0000000..498611e
--- /dev/null
+++ b/test/SemaCXX/exception-spec.cpp
@@ -0,0 +1,203 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -fexceptions -fms-extensions %s
+
+// Straight from the standard:
+// Plain function with spec
+void f() throw(int);
+// Pointer to function with spec
+void (*fp)() throw (int);
+// Function taking reference to function with spec
+void g(void pfa() throw(int));
+// Typedef for pointer to function with spec
+typedef int (*pf)() throw(int); // expected-error {{specifications are not allowed in typedefs}}
+
+// Some more:
+// Function returning function with spec
+void (*h())() throw(int);
+// Ultimate parser thrill: function with spec returning function with spec and
+// taking pointer to function with spec.
+// The actual function throws int, the return type double, the argument float.
+void (*i() throw(int))(void (*)() throw(float)) throw(double);
+// Pointer to pointer to function taking function with spec
+void (**k)(void pfa() throw(int)); // no-error
+// Pointer to pointer to function with spec
+void (**j)() throw(int); // expected-error {{not allowed beyond a single}}
+// Pointer to function returning pointer to pointer to function with spec
+void (**(*h())())() throw(int); // expected-error {{not allowed beyond a single}}
+
+struct Incomplete; // expected-note 3 {{forward declaration}}
+
+// Exception spec must not have incomplete types, or pointers to them, except
+// void.
+void ic1() throw(void); // expected-error {{incomplete type 'void' is not allowed in exception specification}}
+void ic2() throw(Incomplete); // expected-error {{incomplete type 'Incomplete' is not allowed in exception specification}}
+void ic3() throw(void*);
+void ic4() throw(Incomplete*); // expected-error {{pointer to incomplete type 'Incomplete' is not allowed in exception specification}}
+void ic5() throw(Incomplete&); // expected-error {{reference to incomplete type 'Incomplete' is not allowed in exception specification}}
+
+// Redeclarations
+typedef int INT;
+void r1() throw(int);
+void r1() throw(int);
+
+void r2() throw(int);
+void r2() throw(INT);
+
+// throw-any spec and no spec at all are semantically equivalent
+void r3();
+void r3() throw(...);
+
+void r4() throw(int, float);
+void r4() throw(float, int);
+
+void r5() throw(int); // expected-note {{previous declaration}}
+void r5(); // expected-warning {{missing exception specification}}
+
+void r6() throw(...); // expected-note {{previous declaration}}
+void r6() throw(int); // expected-error {{exception specification in declaration does not match}}
+
+void r7() throw(int); // expected-note {{previous declaration}}
+void r7() throw(float); // expected-error {{exception specification in declaration does not match}}
+
+// Top-level const doesn't matter.
+void r8() throw(int);
+void r8() throw(const int);
+
+// Multiple appearances don't matter.
+void r9() throw(int, int);
+void r9() throw(int, int);
+
+struct A
+{
+};
+
+struct B1 : A
+{
+};
+
+struct B2 : A
+{
+};
+
+struct D : B1, B2
+{
+};
+
+struct P : private A
+{
+};
+
+struct Base
+{
+  virtual void f1() throw();
+  virtual void f2();
+  virtual void f3() throw(...);
+  virtual void f4() throw(int, float);
+
+  virtual void f5() throw(int, float);
+  virtual void f6() throw(A);
+  virtual void f7() throw(A, int, float);
+  virtual void f8();
+
+  virtual void g1() throw(); // expected-note {{overridden virtual function is here}}
+  virtual void g2() throw(int); // expected-note {{overridden virtual function is here}}
+  virtual void g3() throw(A); // expected-note {{overridden virtual function is here}}
+  virtual void g4() throw(B1); // expected-note {{overridden virtual function is here}}
+  virtual void g5() throw(A); // expected-note {{overridden virtual function is here}}
+};
+struct Derived : Base
+{
+  virtual void f1() throw();
+  virtual void f2() throw(...);
+  virtual void f3();
+  virtual void f4() throw(float, int);
+
+  virtual void f5() throw(float);
+  virtual void f6() throw(B1);
+  virtual void f7() throw(B1, B2, int);
+  virtual void f8() throw(B2, B2, int, float, char, double, bool);
+
+  virtual void g1() throw(int); // expected-error {{exception specification of overriding function is more lax}}
+  virtual void g2(); // expected-error {{exception specification of overriding function is more lax}}
+  virtual void g3() throw(D); // expected-error {{exception specification of overriding function is more lax}}
+  virtual void g4() throw(A); // expected-error {{exception specification of overriding function is more lax}}
+  virtual void g5() throw(P); // expected-error {{exception specification of overriding function is more lax}}
+};
+
+// Some functions to play with below.
+void s1() throw();
+void s2() throw(int);
+void s3() throw(A);
+void s4() throw(B1);
+void s5() throw(D);
+void s6();
+void s7() throw(int, float);
+void (*s8())() throw(B1); // s8 returns a pointer to function with spec
+void s9(void (*)() throw(B1)); // s9 takes pointer to function with spec
+
+void fnptrs()
+{
+  // Assignment and initialization of function pointers.
+  void (*t1)() throw() = &s1;    // valid
+  t1 = &s2;                      // expected-error {{not superset}} expected-error {{incompatible type}}
+  t1 = &s3;                      // expected-error {{not superset}} expected-error {{incompatible type}}
+  void (&t2)() throw() = s2;     // expected-error {{not superset}}
+  void (*t3)() throw(int) = &s2; // valid
+  void (*t4)() throw(A) = &s1;   // valid
+  t4 = &s3;                      // valid
+  t4 = &s4;                      // valid
+  t4 = &s5;                      // expected-error {{not superset}} expected-error {{incompatible type}}
+  void (*t5)() = &s1;            // valid
+  t5 = &s2;                      // valid
+  t5 = &s6;                      // valid
+  t5 = &s7;                      // valid
+  t1 = t3;                       // expected-error {{not superset}} expected-error {{incompatible type}}
+  t3 = t1;                       // valid
+  void (*t6)() throw(B1);
+  t6 = t4;                       // expected-error {{not superset}} expected-error {{incompatible type}}
+  t4 = t6;                       // valid
+  t5 = t1;                       // valid
+  t1 = t5;                       // expected-error {{not superset}} expected-error {{incompatible type}}
+
+  // return types and arguments must match exactly, no inheritance allowed
+  void (*(*t7)())() throw(B1) = &s8;       // valid
+  void (*(*t8)())() throw(A) = &s8;        // expected-error {{return types differ}}
+  void (*(*t9)())() throw(D) = &s8;        // expected-error {{return types differ}}
+  void (*t10)(void (*)() throw(B1)) = &s9; // valid   expected-warning{{disambiguated}}
+  void (*t11)(void (*)() throw(A)) = &s9;  // expected-error {{argument types differ}} expected-warning{{disambiguated}}
+  void (*t12)(void (*)() throw(D)) = &s9;  // expected-error {{argument types differ}} expected-warning{{disambiguated}}
+}
+
+// Member function stuff
+
+struct Str1 { void f() throw(int); }; // expected-note {{previous declaration}}
+void Str1::f() // expected-warning {{missing exception specification}}
+{
+}
+
+void mfnptr()
+{
+  void (Str1::*pfn1)() throw(int) = &Str1::f; // valid
+  void (Str1::*pfn2)() = &Str1::f; // valid
+  void (Str1::*pfn3)() throw() = &Str1::f; // expected-error {{not superset}}
+}
+
+// Don't suppress errors in template instantiation.
+template <typename T> struct TEx; // expected-note {{template is declared here}}
+
+void tf() throw(TEx<int>); // expected-error {{implicit instantiation of undefined template}}
+
+// DR 437, class throws itself.
+struct DR437 {
+   void f() throw(DR437);
+   void g() throw(DR437*);
+   void h() throw(DR437&);
+};
+
+// DR 437 within a nested class
+struct DR437_out {
+   struct DR437_in {
+      void f() throw(DR437_out);
+      void g() throw(DR437_out*);
+      void h() throw(DR437_out&);
+   }; 
+};
diff --git a/test/SemaCXX/exceptions.cpp b/test/SemaCXX/exceptions.cpp
new file mode 100644
index 0000000..18349d1
--- /dev/null
+++ b/test/SemaCXX/exceptions.cpp
@@ -0,0 +1,122 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct A; // expected-note 4 {{forward declaration of 'A'}}
+
+struct Abstract { virtual void f() = 0; }; // expected-note {{pure virtual function 'f'}}
+
+void trys() {
+  try {
+  } catch(int i) { // expected-note {{previous definition}}
+    int j = i;
+    int i; // expected-error {{redefinition of 'i'}}
+  } catch(float i) {
+  } catch(void v) { // expected-error {{cannot catch incomplete type 'void'}}
+  } catch(A a) { // expected-error {{cannot catch incomplete type 'A'}}
+  } catch(A *a) { // expected-warning {{ISO C++ forbids catching a pointer to incomplete type 'A'}}
+  } catch(A &a) { // expected-warning {{ISO C++ forbids catching a reference to incomplete type 'A'}}
+  } catch(Abstract) { // expected-error {{variable type 'Abstract' is an abstract class}}
+  } catch(...) {
+    int j = i; // expected-error {{use of undeclared identifier 'i'}}
+  }
+
+  try {
+  } catch(...) { // expected-error {{catch-all handler must come last}}
+  } catch(int) {
+  }
+}
+
+void throws() {
+  throw;
+  throw 0;
+  throw throw; // expected-error {{cannot throw object of incomplete type 'void'}}
+  throw (A*)0; // expected-error {{cannot throw pointer to object of incomplete type 'A'}}
+}
+
+void jumps() {
+l1:
+  goto l5;
+  goto l4; // expected-error {{illegal goto into protected scope}}
+  goto l3; // expected-error {{illegal goto into protected scope}}
+  goto l2; // expected-error {{illegal goto into protected scope}}
+  goto l1;
+  try { // expected-note 4 {{jump bypasses initialization of try block}}
+  l2:
+    goto l5;
+    goto l4; // expected-error {{illegal goto into protected scope}}
+    goto l3; // expected-error {{illegal goto into protected scope}}
+    goto l2;
+    goto l1;
+  } catch(int) { // expected-note 4 {{jump bypasses initialization of catch block}}
+  l3:
+    goto l5;
+    goto l4; // expected-error {{illegal goto into protected scope}}
+    goto l3;
+    goto l2; // expected-error {{illegal goto into protected scope}}
+    goto l1;
+  } catch(...) { // expected-note 4 {{jump bypasses initialization of catch block}}
+  l4:
+    goto l5;
+    goto l4;
+    goto l3; // expected-error {{illegal goto into protected scope}}
+    goto l2; // expected-error {{illegal goto into protected scope}}
+    goto l1;
+  }
+l5:
+  goto l5;
+  goto l4; // expected-error {{illegal goto into protected scope}}
+  goto l3; // expected-error {{illegal goto into protected scope}}
+  goto l2; // expected-error {{illegal goto into protected scope}}
+  goto l1;
+}
+
+struct BadReturn {
+  BadReturn() try {
+  } catch(...) {
+    // Try to hide
+    try {
+    } catch(...) {
+      {
+        if (0)
+          return; // expected-error {{return in the catch of a function try block of a constructor is illegal}}
+      }
+    }
+  }
+  BadReturn(int);
+};
+
+BadReturn::BadReturn(int) try {
+} catch(...) {
+  // Try to hide
+  try {
+  } catch(int) {
+    return; // expected-error {{return in the catch of a function try block of a constructor is illegal}}
+  } catch(...) {
+    {
+      if (0)
+        return; // expected-error {{return in the catch of a function try block of a constructor is illegal}}
+    }
+  }
+}
+
+// Cannot throw an abstract type.
+class foo {
+public:
+  foo() {}
+  void bar () {
+    throw *this; // expected-error{{cannot throw an object of abstract type 'foo'}}
+  }
+  virtual void test () = 0; // expected-note{{pure virtual function 'test'}}
+};
+
+namespace PR6831 {
+  namespace NA { struct S; }
+  namespace NB { struct S; }
+  
+  void f() {
+    using namespace NA;
+    using namespace NB;
+    try {
+    } catch (int S) { 
+    }
+  }
+}
diff --git a/test/SemaCXX/explicit.cpp b/test/SemaCXX/explicit.cpp
new file mode 100644
index 0000000..717ed1e
--- /dev/null
+++ b/test/SemaCXX/explicit.cpp
@@ -0,0 +1,39 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s
+namespace Constructor {
+struct A {
+  A(int);
+};
+
+struct B {
+  explicit B(int);
+};
+
+B::B(int) { }
+
+struct C {
+  void f(const A&);
+  void f(const B&);
+};
+
+void f(C c) {
+  c.f(10);
+}
+}
+
+namespace Conversion {
+  struct A {
+    operator int();
+    explicit operator bool();
+  };
+
+  A::operator bool() { return false; } 
+
+  struct B {
+    void f(int);
+    void f(bool);
+  };
+
+  void f(A a, B b) {
+    b.f(a);
+  }
+}
diff --git a/test/SemaCXX/expressions.cpp b/test/SemaCXX/expressions.cpp
new file mode 100644
index 0000000..f3a05c1
--- /dev/null
+++ b/test/SemaCXX/expressions.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s 
+
+void choice(int);
+int choice(bool);
+
+void test() {
+  // Result of ! must be type bool.
+  int i = choice(!1);
+}
diff --git a/test/SemaCXX/fntype-decl.cpp b/test/SemaCXX/fntype-decl.cpp
new file mode 100644
index 0000000..b8ae625
--- /dev/null
+++ b/test/SemaCXX/fntype-decl.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// PR2942
+typedef void fn(int);
+fn f; // expected-note {{previous declaration is here}}
+
+int g(int x, int y);
+int g(int x, int y = 2);
+
+typedef int g_type(int, int);
+g_type g;
+
+int h(int x) { // expected-note {{previous definition is here}}
+  return g(x);
+}
+
+float f(int) { } // expected-error{{functions that differ only in their return type cannot be overloaded}}
+
+int h(int) { } // expected-error{{redefinition of 'h'}}
+
diff --git a/test/SemaCXX/format-attribute.cpp b/test/SemaCXX/format-attribute.cpp
new file mode 100644
index 0000000..92b7cf5
--- /dev/null
+++ b/test/SemaCXX/format-attribute.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s 
+
+// PR5521
+struct A { void a(const char*,...) __attribute((format(printf,2,3))); };
+void b(A x) {
+  x.a("%d", 3);
+}
+struct X { void a(const char*,...) __attribute((format(printf,1,3))); }; // expected-error {{format argument not a string type}}
diff --git a/test/SemaCXX/friend-class-nodecl.cpp b/test/SemaCXX/friend-class-nodecl.cpp
new file mode 100644
index 0000000..41e2da6
--- /dev/null
+++ b/test/SemaCXX/friend-class-nodecl.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -ast-print %s -o %t
+// RUN: not grep '^ *class B' %t
+
+// Tests that the tag decls in friend declarations aren't added to the
+// declaring class's decl chain.
+
+class A {
+  friend class B;
+};
+
diff --git a/test/SemaCXX/friend.cpp b/test/SemaCXX/friend.cpp
new file mode 100644
index 0000000..ffad0e2
--- /dev/null
+++ b/test/SemaCXX/friend.cpp
@@ -0,0 +1,49 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+friend class A; // expected-error {{'friend' used outside of class}}
+void f() { friend class A; } // expected-error {{'friend' used outside of class}}
+class C { friend class A; };
+class D { void f() { friend class A; } }; // expected-error {{'friend' used outside of class}}
+
+// PR5760
+namespace test0 {
+  namespace ns {
+    void f(int);
+  }
+
+  struct A {
+    friend void ns::f(int a);
+  };
+}
+
+// Test derived from LLVM's Registry.h
+namespace test1 {
+  template <class T> struct Outer {
+    void foo(T);
+    struct Inner {
+      friend void Outer::foo(T);
+    };
+  };
+
+  void test() {
+    (void) Outer<int>::Inner();
+  }
+}
+
+// PR5476
+namespace test2 {
+  namespace foo {
+    void Func(int x);
+  }
+
+  class Bar {
+    friend void ::test2::foo::Func(int x);
+  };
+}
+
+// PR5134
+namespace test3 {
+  class Foo {
+    friend const int getInt(int inInt = 0);
+  };
+}
diff --git a/test/SemaCXX/function-overloaded-redecl.cpp b/test/SemaCXX/function-overloaded-redecl.cpp
new file mode 100644
index 0000000..0077881
--- /dev/null
+++ b/test/SemaCXX/function-overloaded-redecl.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s 
+
+typedef const int cInt;
+
+void f (int); 
+void f (const int);  // redecl
+
+void f (int) {  }    // expected-note {{previous definition is here}}
+void f (cInt) { }    // expected-error {{redefinition of 'f'}}
+
diff --git a/test/SemaCXX/function-redecl.cpp b/test/SemaCXX/function-redecl.cpp
new file mode 100644
index 0000000..b15d866
--- /dev/null
+++ b/test/SemaCXX/function-redecl.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+int foo(int);
+
+namespace N {
+  void f1() {
+    void foo(int); // okay
+  }
+
+  // FIXME: we shouldn't even need this declaration to detect errors
+  // below.
+  void foo(int); // expected-note{{previous declaration is here}}
+
+  void f2() {
+    int foo(int); // expected-error{{functions that differ only in their return type cannot be overloaded}}
+
+    {
+      int foo;
+      {
+        // FIXME: should diagnose this because it's incompatible with
+        // N::foo. However, name lookup isn't properly "skipping" the
+        // "int foo" above.
+        float foo(int); 
+      }
+    }
+  }
+}
diff --git a/test/SemaCXX/function-type-qual.cpp b/test/SemaCXX/function-type-qual.cpp
new file mode 100644
index 0000000..be61f2b
--- /dev/null
+++ b/test/SemaCXX/function-type-qual.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+void f() const; // expected-error {{type qualifier is not allowed on this function}}
+
+typedef void cfn() const; 
+cfn f2; // expected-error {{a qualified function type cannot be used to declare a nonmember function or a static member function}}
+
+class C {
+  void f() const;
+  cfn f2;
+  static void f3() const; // expected-error {{type qualifier is not allowed on this function}}
+  static cfn f4; // expected-error {{a qualified function type cannot be used to declare a nonmember function or a static member function}}
+
+  void m1() {
+    x = 0;
+  }
+
+  void m2() const {
+    x = 0; // expected-error {{read-only variable is not assignable}}
+  }
+
+  int x;
+};
diff --git a/test/SemaCXX/functional-cast.cpp b/test/SemaCXX/functional-cast.cpp
new file mode 100644
index 0000000..3b08864
--- /dev/null
+++ b/test/SemaCXX/functional-cast.cpp
@@ -0,0 +1,317 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// ------------ not interpreted as C-style cast ------------
+
+struct SimpleValueInit {
+  int i;
+};
+
+struct InitViaConstructor {
+  InitViaConstructor(int i = 7);
+};
+
+struct NoValueInit { // expected-note 2 {{candidate constructor (the implicit copy constructor)}} 
+  NoValueInit(int i, int j); // expected-note 2 {{candidate constructor}}
+};
+
+void test_cxx_functional_value_init() {
+  (void)SimpleValueInit();
+  (void)InitViaConstructor();
+  (void)NoValueInit(); // expected-error{{no matching constructor for initialization}}
+}
+
+void test_cxx_function_cast_multi() { 
+  (void)NoValueInit(0, 0);
+  (void)NoValueInit(0, 0, 0); // expected-error{{no matching constructor for initialization}}
+  (void)int(1, 2); // expected-error{{function-style cast to a builtin type can only take one argument}}
+}
+
+
+// ------------------ everything else --------------------
+
+struct A {};
+
+// ----------- const_cast --------------
+
+typedef char c;
+typedef c *cp;
+typedef cp *cpp;
+typedef cpp *cppp;
+typedef cppp &cpppr;
+typedef const cppp &cpppcr;
+typedef const char cc;
+typedef cc *ccp;
+typedef volatile ccp ccvp;
+typedef ccvp *ccvpp;
+typedef const volatile ccvpp ccvpcvp;
+typedef ccvpcvp *ccvpcvpp;
+typedef int iar[100];
+typedef iar &iarr;
+typedef int (*f)(int);
+
+void t_cc()
+{
+  ccvpcvpp var = 0;
+  // Cast away deep consts and volatiles.
+  char ***var2 = cppp(var);
+  char ***const &var3 = var2;
+  // Const reference to reference.
+  char ***&var4 = cpppr(var3);
+  // Drop reference. Intentionally without qualifier change.
+  char *** var5 = cppp(var4);
+  const int ar[100] = {0};
+  // Array decay. Intentionally without qualifier change.
+  typedef int *intp;
+  int *pi = intp(ar);
+  f fp = 0;
+  // Don't misidentify fn** as a function pointer.
+  typedef f *fp_t;
+  f *fpp = fp_t(&fp);
+  int const A::* const A::*icapcap = 0;
+  typedef int A::* A::*iapap_t;
+  iapap_t iapap = iapap_t(icapcap);
+}
+
+// ----------- static_cast -------------
+
+struct B : public A {};             // Single public base.
+struct C1 : public virtual B {};    // Single virtual base.
+struct C2 : public virtual B {};
+struct D : public C1, public C2 {}; // Diamond
+struct E : private A {};            // Single private base.
+struct F : public C1 {};            // Single path to B with virtual.
+struct G1 : public B {};
+struct G2 : public B {};
+struct H : public G1, public G2 {}; // Ambiguous path to B.
+
+enum Enum { En1, En2 };
+enum Onom { On1, On2 };
+
+struct Co1 { operator int(); };
+struct Co2 { Co2(int); };
+struct Co3 { };
+struct Co4 { Co4(Co3); operator Co3(); };
+
+// Explicit implicits
+void t_529_2()
+{
+  int i = 1;
+  (void)float(i);
+  double d = 1.0;
+  (void)float(d);
+  (void)int(d);
+  (void)char(i);
+  typedef unsigned long ulong;
+  (void)ulong(i);
+  (void)int(En1);
+  (void)double(En1);
+  typedef int &intr;
+  (void)intr(i);
+  typedef const int &cintr;
+  (void)cintr(i);
+
+  int ar[1];
+  typedef const int *cintp;
+  (void)cintp(ar);
+  typedef void (*pfvv)();
+  (void)pfvv(t_529_2);
+
+  typedef void *voidp;
+  (void)voidp(0);
+  (void)voidp((int*)0);
+  typedef volatile const void *vcvoidp;
+  (void)vcvoidp((const int*)0);
+  typedef A *Ap;
+  (void)Ap((B*)0);
+  typedef A &Ar;
+  (void)Ar(*((B*)0));
+  typedef const B *cBp;
+  (void)cBp((C1*)0);
+  typedef B &Br;
+  (void)Br(*((C1*)0));
+  (void)Ap((D*)0);
+  typedef const A &cAr;
+  (void)cAr(*((D*)0));
+  typedef int B::*Bmp;
+  (void)Bmp((int A::*)0);
+  typedef void (B::*Bmfp)();
+  (void)Bmfp((void (A::*)())0);
+  (void)Ap((E*)0); // functional-style cast ignores access control
+  (void)voidp((const int*)0); // const_cast appended
+
+  (void)int(Co1());
+  (void)Co2(1);
+  (void)Co3((Co4)(Co3()));
+
+  // Bad code below
+  //(void)(A*)((H*)0); // {{static_cast from 'struct H *' to 'struct A *' is not allowed}}
+}
+
+// Anything to void
+void t_529_4()
+{
+  void(1);
+  (void(t_529_4));
+}
+
+// Static downcasts
+void t_529_5_8()
+{
+  typedef B *Bp;
+  (void)Bp((A*)0);
+  typedef B &Br;
+  (void)Br(*((A*)0));
+  typedef const G1 *cG1p;
+  (void)cG1p((A*)0);
+  typedef const G1 &cG1r;
+  (void)cG1r(*((A*)0));
+  (void)Bp((const A*)0); // const_cast appended
+  (void)Br(*((const A*)0)); // const_cast appended
+  typedef E *Ep;
+  (void)Ep((A*)0); // access control ignored
+  typedef E &Er;
+  (void)Er(*((A*)0)); // access control ignored
+
+  // Bad code below
+
+  typedef C1 *C1p;
+  (void)C1p((A*)0); // expected-error {{cannot cast 'A *' to 'C1p' (aka 'C1 *') via virtual base 'B'}}
+  typedef C1 &C1r;
+  (void)C1r(*((A*)0)); // expected-error {{cannot cast 'A' to 'C1r' (aka 'C1 &') via virtual base 'B'}}
+  typedef D *Dp;
+  (void)Dp((A*)0); // expected-error {{cannot cast 'A *' to 'Dp' (aka 'D *') via virtual base 'B'}}
+  typedef D &Dr;
+  (void)Dr(*((A*)0)); // expected-error {{cannot cast 'A' to 'Dr' (aka 'D &') via virtual base 'B'}}
+  typedef H *Hp;
+  (void)Hp((A*)0); // expected-error {{ambiguous cast from base 'A' to derived 'H':\n    struct A -> struct B -> struct G1 -> struct H\n    struct A -> struct B -> struct G2 -> struct H}}
+  typedef H &Hr;
+  (void)Hr(*((A*)0)); // expected-error {{ambiguous cast from base 'A' to derived 'H':\n    struct A -> struct B -> struct G1 -> struct H\n    struct A -> struct B -> struct G2 -> struct H}}
+
+  // TODO: Test DR427. This requires user-defined conversions, though.
+}
+
+// Enum conversions
+void t_529_7()
+{
+  (void)Enum(1);
+  (void)Enum(1.0);
+  (void)Onom(En1);
+
+  // Bad code below
+
+  (void)Enum((int*)0); // expected-error {{functional-style cast from 'int *' to 'Enum' is not allowed}}
+}
+
+// Void pointer to object pointer
+void t_529_10()
+{
+  typedef int *intp;
+  (void)intp((void*)0);
+  typedef const A *cAp;
+  (void)cAp((void*)0);
+  (void)intp((const void*)0); // const_cast appended
+}
+
+// Member pointer upcast.
+void t_529_9()
+{
+  typedef int A::*Amp;
+  (void)Amp((int B::*)0);
+
+  // Bad code below
+  (void)Amp((int H::*)0); // expected-error {{ambiguous conversion from pointer to member of derived class 'H' to pointer to member of base class 'A':}}
+  (void)Amp((int F::*)0); // expected-error {{conversion from pointer to member of class 'F' to pointer to member of class 'A' via virtual base 'B' is not allowed}}
+}
+
+// -------- reinterpret_cast -----------
+
+enum test { testval = 1 };
+struct structure { int m; };
+typedef void (*fnptr)();
+
+// Test conversion between pointer and integral types, as in p3 and p4.
+void integral_conversion()
+{
+  typedef void *voidp;
+  void *vp = voidp(testval);
+  long l = long(vp);
+  typedef float *floatp;
+  (void)floatp(l);
+  fnptr fnp = fnptr(l);
+  (void)char(fnp); // expected-error {{cast from pointer to smaller type 'char' loses information}}
+  (void)long(fnp);
+}
+
+void pointer_conversion()
+{
+  int *p1 = 0;
+  typedef float *floatp;
+  float *p2 = floatp(p1);
+  typedef structure *structurep;
+  structure *p3 = structurep(p2);
+  typedef int **ppint;
+  typedef ppint *pppint;
+  ppint *deep = pppint(p3);
+  typedef fnptr fnptrp;
+  (void)fnptrp(deep);
+}
+
+void constness()
+{
+  int ***const ipppc = 0;
+  typedef int const *icp_t;
+  int const *icp = icp_t(ipppc);
+  typedef int *intp;
+  (void)intp(icp); // const_cast appended
+  typedef int const *const ** intcpcpp;
+  intcpcpp icpcpp = intcpcpp(ipppc); // const_cast appended
+  int *ip = intp(icpcpp);
+  (void)icp_t(ip);
+  typedef int const *const *const *intcpcpcp;
+  (void)intcpcpcp(ipppc);
+}
+
+void fnptrs()
+{
+  typedef int (*fnptr2)(int);
+  fnptr fp = 0;
+  (void)fnptr2(fp);
+  typedef void *voidp;
+  void *vp = voidp(fp);
+  (void)fnptr(vp);
+}
+
+void refs()
+{
+  long l = 0;
+  typedef char &charr;
+  char &c = charr(l);
+  // Bad: from rvalue
+  typedef int &intr;
+  (void)intr(&c); // expected-error {{functional-style cast from rvalue to reference type 'intr' (aka 'int &')}}
+}
+
+void memptrs()
+{
+  const int structure::*psi = 0;
+  typedef const float structure::*structurecfmp;
+  (void)structurecfmp(psi);
+  typedef int structure::*structureimp;
+  (void)structureimp(psi); // const_cast appended
+
+  void (structure::*psf)() = 0;
+  typedef int (structure::*structureimfp)();
+  (void)structureimfp(psf);
+
+  typedef void (structure::*structurevmfp)();
+  (void)structurevmfp(psi); // expected-error {{functional-style cast from 'int const structure::*' to 'structurevmfp' (aka 'void (structure::*)()') is not allowed}}
+  (void)structureimp(psf); // expected-error {{functional-style cast from 'void (structure::*)()' to 'structureimp' (aka 'int structure::*') is not allowed}}
+}
+
+// ---------------- misc ------------------
+
+void crash_on_invalid_1()
+{
+  typedef itn Typo; // expected-error {{unknown type name 'itn'}}
+  (void)Typo(1); // used to crash
+}
diff --git a/test/SemaCXX/i-c-e-cxx.cpp b/test/SemaCXX/i-c-e-cxx.cpp
new file mode 100644
index 0000000..e8275d4
--- /dev/null
+++ b/test/SemaCXX/i-c-e-cxx.cpp
@@ -0,0 +1,44 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// C++-specific tests for integral constant expressions.
+
+const int c = 10;
+int ar[c];
+
+struct X0 {
+  static const int value = static_cast<int>(4.0);
+};
+
+void f() {
+  if (const int value = 17) {
+    int array[value];
+  }
+}
+
+int a() {
+  const int t=t; // expected-note {{subexpression not valid}}
+  switch(1) {
+    case t:; // expected-error {{not an integer constant expression}}
+  }
+}
+
+// PR6206:  out-of-line definitions are legit
+namespace pr6206 {
+  class Foo {
+  public:
+    static const int kBar;
+  };
+
+  const int Foo::kBar = 20;
+  
+  char Test() {
+    char str[Foo::kBar];
+    str[0] = '0';
+    return str[0];
+  }
+}
+
+// PR6373:  default arguments don't count.
+void pr6373(const unsigned x = 0) {
+  unsigned max = 80 / x;
+}
diff --git a/test/SemaCXX/illegal-member-initialization.cpp b/test/SemaCXX/illegal-member-initialization.cpp
new file mode 100644
index 0000000..87069ef
--- /dev/null
+++ b/test/SemaCXX/illegal-member-initialization.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s 
+
+struct A {
+   A() : value(), cvalue() { } // expected-error {{reference to type 'int' requires an initializer}}
+   int &value;
+   const int cvalue;
+};
+
+struct B {
+};
+
+struct X {
+   X() { }      // expected-error {{constructor for 'X' must explicitly initialize the reference member 'value'}} \
+                // expected-error {{constructor for 'X' must explicitly initialize the const member 'cvalue'}} \
+                // expected-error {{constructor for 'X' must explicitly initialize the reference member 'b'}} \
+                // expected-error {{constructor for 'X' must explicitly initialize the const member 'cb'}}
+   int &value; // expected-note{{declared here}}
+   const int cvalue; // expected-note{{declared here}}
+   B& b; // expected-note{{declared here}}
+   const B cb; // expected-note{{declared here}}
+};
+
+
+// PR5924
+struct bar {};
+bar xxx();
+
+struct foo {
+  foo_t a;  // expected-error {{unknown type name 'foo_t'}}
+  foo() : a(xxx()) {}  // no error here.
+};
diff --git a/test/SemaCXX/implicit-int.cpp b/test/SemaCXX/implicit-int.cpp
new file mode 100644
index 0000000..9711adf
--- /dev/null
+++ b/test/SemaCXX/implicit-int.cpp
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+x; // expected-error{{C++ requires a type specifier for all declarations}}
+
+f(int y) { return y; } // expected-error{{C++ requires a type specifier for all declarations}}
diff --git a/test/SemaCXX/implicit-member-functions.cpp b/test/SemaCXX/implicit-member-functions.cpp
new file mode 100644
index 0000000..79cc367
--- /dev/null
+++ b/test/SemaCXX/implicit-member-functions.cpp
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct A { };
+A::A() { } // expected-error {{definition of implicitly declared constructor}}
+
+struct B { };
+B::B(const B&) { } // expected-error {{definition of implicitly declared copy constructor}}
+
+struct C { };
+C& C::operator=(const C&) { return *this; } // expected-error {{definition of implicitly declared copy assignment operator}}
+
+struct D { };
+D::~D() { } // expected-error {{definition of implicitly declared destructor}}
+
+// Make sure that the special member functions are introduced for
+// name-lookup purposes and overload with user-declared
+// constructors and assignment operators.
+namespace PR6570 {
+  class A { };
+
+  class B {
+  public:
+    B() {}
+
+    B(const A& a) {
+      operator = (CONST);
+      operator = (a);
+    }
+
+    B& operator = (const A& a) {
+      return *this;
+    }
+
+    void f(const A &a) {
+      B b(a);
+    };
+
+    static const B CONST;
+  };
+
+}
diff --git a/test/SemaCXX/implicit-virtual-member-functions.cpp b/test/SemaCXX/implicit-virtual-member-functions.cpp
new file mode 100644
index 0000000..cb24501
--- /dev/null
+++ b/test/SemaCXX/implicit-virtual-member-functions.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+struct A {
+  virtual ~A();
+};
+
+struct B : A { // expected-error {{no suitable member 'operator delete' in 'B'}}
+  virtual void f();
+
+  void operator delete (void *, int); // expected-note {{'operator delete' declared here}}
+};
+
+void B::f() { // expected-note {{implicit default destructor for 'B' first required here}}
+}
+
+struct C : A { // expected-error {{no suitable member 'operator delete' in 'C'}}
+  C();
+  void operator delete(void *, int); // expected-note {{'operator delete' declared here}}
+};
+
+C::C() { }  // expected-note {{implicit default destructor for 'C' first required here}}
+
+struct D : A { // expected-error {{no suitable member 'operator delete' in 'D'}}
+  void operator delete(void *, int); // expected-note {{'operator delete' declared here}}
+}; // expected-note {{implicit default destructor for 'D' first required here}}
+
+void f() {
+  new D; 
+}
+
diff --git a/test/SemaCXX/incomplete-call.cpp b/test/SemaCXX/incomplete-call.cpp
new file mode 100644
index 0000000..d627c33
--- /dev/null
+++ b/test/SemaCXX/incomplete-call.cpp
@@ -0,0 +1,49 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+struct A; // expected-note 14 {{forward declaration of 'A'}}
+
+A f(); // expected-note {{note: 'f' declared here}}
+
+struct B {
+  A f(); // expected-note {{'f' declared here}}
+  A operator()(); // expected-note 2 {{'operator()' declared here}}
+  operator A(); // expected-note {{'operator A' declared here}}
+  A operator!(); // expected-note 2 {{'operator!' declared here}}
+  A operator++(int); // expected-note {{'operator++' declared here}}
+  A operator[](int); // expected-note {{'operator[]' declared here}}
+  A operator+(int); // expected-note {{'operator+' declared here}}
+  A operator->(); // expected-note {{'operator->' declared here}}
+};
+
+void g() {
+  f(); // expected-error {{calling 'f' with incomplete return type 'A'}}
+
+  typedef A (*Func)();
+  Func fp;
+  fp(); // expected-error {{calling function with incomplete return type 'A'}}
+  ((Func)0)();  // expected-error {{calling function with incomplete return type 'A'}}  
+  
+  B b;
+  b.f(); // expected-error {{calling 'f' with incomplete return type 'A'}}
+  
+  b.operator()(); // expected-error {{calling 'operator()' with incomplete return type 'A'}}
+  b.operator A(); // expected-error {{calling 'operator A' with incomplete return type 'A'}}
+  b.operator!(); // expected-error {{calling 'operator!' with incomplete return type 'A'}}
+  
+  !b; // expected-error {{calling 'operator!' with incomplete return type 'A'}}
+  b(); // expected-error {{calling 'operator()' with incomplete return type 'A'}}
+  b++; // expected-error {{calling 'operator++' with incomplete return type 'A'}}
+  b[0]; // expected-error {{calling 'operator[]' with incomplete return type 'A'}}
+  b + 1; // expected-error {{calling 'operator+' with incomplete return type 'A'}}
+  b->f(); // expected-error {{calling 'operator->' with incomplete return type 'A'}}
+  
+  A (B::*mfp)() = 0;
+  (b.*mfp)(); // expected-error {{calling function with incomplete return type 'A'}}
+  
+}
+
+
+struct C; // expected-note{{forward declaration}}
+
+void test_incomplete_object_call(C& c) {
+  c(); // expected-error{{incomplete type in call to object of type}}
+}
diff --git a/test/SemaCXX/inherit.cpp b/test/SemaCXX/inherit.cpp
new file mode 100644
index 0000000..a926c81
--- /dev/null
+++ b/test/SemaCXX/inherit.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+class A { };
+
+class B1 : A { };
+
+class B2 : virtual A { };
+
+class B3 : virtual virtual A { }; // expected-error{{duplicate 'virtual' in base specifier}}
+
+class C : public B1, private B2 { };
+
+
+class D;                // expected-note {{forward declaration of 'D'}}
+
+class E : public D { }; // expected-error{{base class has incomplete type}}
+
+typedef int I;
+
+class F : public I { }; // expected-error{{base specifier must name a class}}
+
+union U1 : public A { }; // expected-error{{unions cannot have base classes}}
+
+union U2 {};
+
+class G : public U2 { }; // expected-error{{unions cannot be base classes}}
+
+typedef G G_copy;
+typedef G G_copy_2;
+typedef G_copy G_copy_3;
+
+class H : G_copy, A, G_copy_2, // expected-error{{base class 'G_copy' (aka 'G') specified more than once as a direct base class}}
+          public G_copy_3 { }; // expected-error{{base class 'G_copy' (aka 'G') specified more than once as a direct base class}}
diff --git a/test/SemaCXX/inline.cpp b/test/SemaCXX/inline.cpp
new file mode 100644
index 0000000..e569300
--- /dev/null
+++ b/test/SemaCXX/inline.cpp
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// Check that we don't allow illegal uses of inline
+// (checking C++-only constructs here)
+struct c {inline int a;}; // expected-error{{'inline' can only appear on functions}}
diff --git a/test/SemaCXX/invalid-member-expr.cpp b/test/SemaCXX/invalid-member-expr.cpp
new file mode 100644
index 0000000..7307a47
--- /dev/null
+++ b/test/SemaCXX/invalid-member-expr.cpp
@@ -0,0 +1,39 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+class X {};
+
+void test() {
+  X x;
+
+  x.int; // expected-error{{expected unqualified-id}}
+  x.~int(); // expected-error{{expected a class name}}
+  x.operator; // expected-error{{missing type specifier after 'operator'}}
+  x.operator typedef; // expected-error{{missing type specifier after 'operator'}}
+}
+
+void test2() {
+  X *x;
+
+  x->int; // expected-error{{expected unqualified-id}}
+  x->~int(); // expected-error{{expected a class name}}
+  x->operator; // expected-error{{missing type specifier after 'operator'}}
+  x->operator typedef; // expected-error{{missing type specifier after 'operator'}}
+}
+
+// PR6327
+namespace test3 {
+  template <class A, class B> struct pair {};
+
+  void test0() {
+    pair<int, int> z = minmax({}); // expected-error {{expected expression}}
+  }
+
+  struct string {
+    class iterator {};
+  };
+
+  void test1() {
+    string s;
+    string::iterator i = s.foo(); // expected-error {{no member named 'foo'}}
+  }
+}
diff --git a/test/SemaCXX/invalid-template-specifier.cpp b/test/SemaCXX/invalid-template-specifier.cpp
new file mode 100644
index 0000000..bcd6da7
--- /dev/null
+++ b/test/SemaCXX/invalid-template-specifier.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only
+// PR4809
+// This test is primarily checking that this doesn't crash, not the particular
+// diagnostics.
+
+const template basic_istream<char>; // expected-error {{expected unqualified-id}}
+
+namespace S {}
+template <class X> class Y {
+  void x() { S::template y<char>(1); } // expected-error {{does not refer to a template}} \
+                                       // expected-error {{unqualified-id}}
+};
diff --git a/test/SemaCXX/libstdcxx_is_pod_hack.cpp b/test/SemaCXX/libstdcxx_is_pod_hack.cpp
new file mode 100644
index 0000000..2e92032
--- /dev/null
+++ b/test/SemaCXX/libstdcxx_is_pod_hack.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fsyntax-only %s
+
+// This is a test for an egregious hack in Clang that works around
+// issues with GCC's evolution. libstdc++ 4.2.x uses __is_pod as an
+// identifier (to declare a struct template like the one below), while
+// GCC 4.3 and newer make __is_pod a keyword. Clang treats __is_pod as
+// a keyword *unless* it is introduced following the struct keyword.
+
+template<typename T>
+struct __is_pod {
+};
+
+__is_pod<int> ipi;
diff --git a/test/SemaCXX/libstdcxx_map_base_hack.cpp b/test/SemaCXX/libstdcxx_map_base_hack.cpp
new file mode 100644
index 0000000..a556281
--- /dev/null
+++ b/test/SemaCXX/libstdcxx_map_base_hack.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -fsyntax-only %s
+
+// libstdc++ 4.2.x contains a bug where a friend struct template
+// declaration for std::tr1::__detail::_Map base has different
+// template arguments than the real declaration. Clang has an
+// egregious hack to work around this problem, since we can't modify
+// all of the world's libstdc++'s.
+
+namespace std { namespace tr1 { namespace __detail {
+  template<typename _Key, typename _Value, typename _Ex, bool __unique,
+	   typename _Hashtable>
+    struct _Map_base { };
+
+} } } 
+
+namespace std { namespace tr1 {
+  template<typename T>
+  struct X1 {
+    template<typename _Key2, typename _Pair, typename _Hashtable>
+    friend struct __detail::_Map_base;
+  };
+
+} }
+
+std::tr1::X1<int> x1i;
diff --git a/test/SemaCXX/linkage-spec.cpp b/test/SemaCXX/linkage-spec.cpp
new file mode 100644
index 0000000..57730a6
--- /dev/null
+++ b/test/SemaCXX/linkage-spec.cpp
@@ -0,0 +1,56 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+extern "C" {
+  extern "C" void f(int);
+}
+
+extern "C++" {
+  extern "C++" int& g(int);
+  float& g();
+}
+double& g(double);
+
+void test(int x, double d) {
+  f(x);
+  float &f1 = g();
+  int& i1 = g(x);
+  double& d1 = g(d);
+}
+
+extern "C" int foo;
+extern "C" int foo;
+
+extern "C" const int bar;
+extern "C" int const bar;
+
+// <rdar://problem/6895431>
+extern "C" struct bar d;
+extern struct bar e;
+
+extern "C++" {
+  namespace N0 {
+    struct X0 {
+      int foo(int x) { return x; }
+    };
+  }
+}
+
+// PR5430
+namespace pr5430 {
+  extern "C" void func(void);
+}
+using namespace pr5430;
+extern "C" void pr5430::func(void) { }
+
+// PR5404
+int f2(char *)
+{
+        return 0;
+}
+
+extern "C"
+{
+    int f2(int)
+    {
+        return f2((char *)0);
+    }
+}
diff --git a/test/SemaCXX/literal-operators.cpp b/test/SemaCXX/literal-operators.cpp
new file mode 100644
index 0000000..ec585a6
--- /dev/null
+++ b/test/SemaCXX/literal-operators.cpp
@@ -0,0 +1,43 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s
+
+#include <stddef.h>
+
+struct tag {
+  void operator "" tag_bad (const char *); // expected-error {{literal operator 'operator "" tag_bad' must be in a namespace or global scope}}
+  friend void operator "" tag_good (const char *);
+};
+
+namespace ns { void operator "" ns_good (const char *); }
+
+// Check extern "C++" declarations
+extern "C++" void operator "" extern_good (const char *);
+extern "C++" { void operator "" extern_good (const char *); }
+
+void fn () { void operator "" fn_bad (const char *); } // expected-error {{literal operator 'operator "" fn_bad' must be in a namespace or global scope}}
+
+// One-param declarations (const char * was already checked)
+void operator "" good (char);
+void operator "" good (wchar_t);
+void operator "" good (char16_t);
+void operator "" good (char32_t);
+void operator "" good (unsigned long long);
+void operator "" good (long double);
+
+// Two-param declarations
+void operator "" good (const char *, size_t);
+void operator "" good (const wchar_t *, size_t);
+void operator "" good (const char16_t *, size_t);
+void operator "" good (const char32_t *, size_t);
+
+// Check typedef and array equivalences
+void operator "" good (const char[]);
+typedef const char c;
+void operator "" good (c*);
+
+// Check extra cv-qualifiers
+void operator "" cv_good (volatile const char *, const size_t);
+
+// Template delcaration (not implemented yet)
+// template <char...> void operator "" good ();
+
+// FIXME: Test some invalid decls that might crop up.
diff --git a/test/SemaCXX/literal-type.cpp b/test/SemaCXX/literal-type.cpp
new file mode 100644
index 0000000..142dd75
--- /dev/null
+++ b/test/SemaCXX/literal-type.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s
+
+static_assert(__is_literal(int), "fail");
+static_assert(__is_literal(void*), "fail");
+enum E { E1 };
+static_assert(__is_literal(E), "fail");
+static_assert(__is_literal(decltype(E1)), "fail");
+typedef int IAR[10];
+static_assert(__is_literal(IAR), "fail");
+// FIXME: Records
diff --git a/test/SemaCXX/local-classes.cpp b/test/SemaCXX/local-classes.cpp
new file mode 100644
index 0000000..6799e58
--- /dev/null
+++ b/test/SemaCXX/local-classes.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace PR6382 {
+  int foo()
+  {
+    goto error;
+    {
+      struct BitPacker {
+        BitPacker() {}
+      };
+      BitPacker packer;
+    }
+
+  error:
+    return -1;
+  }
+}
+
+namespace PR6383 {
+  void test (bool gross)
+  {
+    struct compare_and_set
+    {
+      void operator() (const bool inner, const bool gross = false)
+      {
+        // the code
+      }
+    } compare_and_set2;
+
+    compare_and_set2 (false, gross);
+  }
+}
diff --git a/test/SemaCXX/member-expr-anonymous-union.cpp b/test/SemaCXX/member-expr-anonymous-union.cpp
new file mode 100644
index 0000000..0f03596
--- /dev/null
+++ b/test/SemaCXX/member-expr-anonymous-union.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify
+// PR5543
+
+struct A { int x; union { int* y; float& z; }; }; struct B : A {int a;};
+int* a(B* x) { return x->y; }
+
+struct x { union { int y; }; }; x y; template <int X> int f() { return X+y.y; }
+int g() { return f<2>(); }
+
diff --git a/test/SemaCXX/member-expr-static.cpp b/test/SemaCXX/member-expr-static.cpp
new file mode 100644
index 0000000..7ed60f7
--- /dev/null
+++ b/test/SemaCXX/member-expr-static.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+typedef void (*thread_continue_t)();
+
+extern "C" {
+  extern void kernel_thread_start(thread_continue_t continuation);
+  extern void pure_c(void);
+}
+
+class _IOConfigThread {
+public:
+  static void main( void );
+};
+
+
+void foo( void ) {
+  kernel_thread_start(&_IOConfigThread::main);
+  kernel_thread_start((thread_continue_t)&_IOConfigThread::main);
+  kernel_thread_start(&pure_c);
+}
diff --git a/test/SemaCXX/member-expr.cpp b/test/SemaCXX/member-expr.cpp
new file mode 100644
index 0000000..54a9593
--- /dev/null
+++ b/test/SemaCXX/member-expr.cpp
@@ -0,0 +1,74 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+class X{
+public:
+  enum E {Enumerator}; // expected-note 2{{declared here}}
+  int f();
+  static int mem;
+  static float g();
+};
+
+void test(X* xp, X x) {
+  int i1 = x.f();
+  int i2 = xp->f();
+  x.E; // expected-error{{cannot refer to type member 'E' in 'X' with '.'}}
+  xp->E; // expected-error{{cannot refer to type member 'E' in 'X' with '->'}}
+  int i3 = x.Enumerator;
+  int i4 = xp->Enumerator;
+  x.mem = 1;
+  xp->mem = 2;
+  float f1 = x.g();
+  float f2 = xp->g();
+}
+
+struct A {
+ int f0;
+};
+struct B {
+ A *f0();
+};
+int f0(B *b) {
+  return b->f0->f0; // expected-error{{perhaps you meant to call this function}}
+}
+
+int i;
+
+namespace C {
+  int i;
+}
+
+void test2(X *xp) {
+  xp->::i = 7; // expected-error{{qualified member access refers to a member in the global namespace}}
+  xp->C::i = 7; // expected-error{{qualified member access refers to a member in namespace 'C'}}
+}
+
+
+namespace test3 {
+  struct NamespaceDecl;
+
+  struct NamedDecl {
+    void *getIdentifier() const;
+  };
+
+  struct NamespaceDecl : NamedDecl {
+    bool isAnonymousNamespace() const {
+      return !getIdentifier();
+    }
+  };
+}
+
+namespace test4 {
+  class X {
+  protected:
+    template<typename T> void f(T);
+  };
+
+  class Y : public X {
+  public:
+    using X::f;
+  };
+
+  void test_f(Y y) {
+    y.f(17);
+  }
+}
diff --git a/test/SemaCXX/member-location.cpp b/test/SemaCXX/member-location.cpp
new file mode 100644
index 0000000..6f7e1f5
--- /dev/null
+++ b/test/SemaCXX/member-location.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// PR4103: Make sure we have a location for the error
+class A { 
+  float a(int *); // expected-note{{passing argument to parameter here}}
+  int b(); 
+};
+int A::b() { return a(a((int*)0)); } // expected-error {{cannot initialize a parameter of type 'int *' with an rvalue of type 'float'}}
+
diff --git a/test/SemaCXX/member-name-lookup.cpp b/test/SemaCXX/member-name-lookup.cpp
new file mode 100644
index 0000000..0149169
--- /dev/null
+++ b/test/SemaCXX/member-name-lookup.cpp
@@ -0,0 +1,158 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+struct A { 
+  int a;  // expected-note 4{{member found by ambiguous name lookup}}
+  static int b;
+  static int c; // expected-note 2{{member found by ambiguous name lookup}}
+
+  enum E { enumerator };
+
+  typedef int type;
+
+  static void f(int);
+  void f(float); // expected-note 2{{member found by ambiguous name lookup}}
+
+  static void static_f(int);
+  static void static_f(double);
+};
+
+struct B : A {
+  int d; // expected-note 2{{member found by ambiguous name lookup}}
+
+  enum E2 { enumerator2 };
+
+  enum E3 { enumerator3 }; // expected-note 2{{member found by ambiguous name lookup}}
+};
+
+struct C : A {
+  int c; // expected-note 2{{member found by ambiguous name lookup}}
+  int d; // expected-note 2{{member found by ambiguous name lookup}}
+
+  enum E3 { enumerator3_2 }; // expected-note 2{{member found by ambiguous name lookup}}
+};
+
+struct D : B, C {
+  void test_lookup();
+};
+
+void test_lookup(D d) {
+  d.a; // expected-error{{non-static member 'a' found in multiple base-class subobjects of type 'A':}}
+  (void)d.b; // okay
+  d.c; // expected-error{{member 'c' found in multiple base classes of different types}}
+  d.d; // expected-error{{member 'd' found in multiple base classes of different types}}
+  d.f(0); // expected-error{{non-static member 'f' found in multiple base-class subobjects of type 'A':}}
+  d.static_f(0); // okay
+
+  D::E e = D::enumerator; // okay
+  D::type t = 0; // okay
+
+  D::E2 e2 = D::enumerator2; // okay
+
+  D::E3 e3; // expected-error{{multiple base classes}}
+}
+
+void D::test_lookup() {
+  a; // expected-error{{non-static member 'a' found in multiple base-class subobjects of type 'A':}}
+  (void)b; // okay
+  c; // expected-error{{member 'c' found in multiple base classes of different types}}
+  d; // expected-error{{member 'd' found in multiple base classes of different types}}
+  f(0); // expected-error{{non-static member 'f' found in multiple base-class subobjects of type 'A':}}
+  static_f(0); // okay
+
+  E e = enumerator; // okay
+  type t = 0; // okay
+
+  E2 e2 = enumerator2; // okay
+
+  E3 e3; // expected-error{{member 'E3' found in multiple base classes of different types}}
+}
+
+struct B2 : virtual A {
+  int d; // expected-note 2{{member found by ambiguous name lookup}}
+
+  enum E2 { enumerator2 };
+
+  enum E3 { enumerator3 }; // expected-note 2 {{member found by ambiguous name lookup}}
+};
+
+struct C2 : virtual A {
+  int c;
+  int d; // expected-note 2{{member found by ambiguous name lookup}}
+
+  enum E3 { enumerator3_2 }; // expected-note 2{{member found by ambiguous name lookup}}
+};
+
+struct D2 : B2, C2 { 
+  void test_virtual_lookup();
+};
+
+struct F : A { };
+struct G : F, D2 { 
+  void test_virtual_lookup();
+};
+
+void test_virtual_lookup(D2 d2, G g) {
+  (void)d2.a;
+  (void)d2.b;
+  (void)d2.c; // okay
+  d2.d; // expected-error{{member 'd' found in multiple base classes of different types}}
+  d2.f(0); // okay
+  d2.static_f(0); // okay
+
+  D2::E e = D2::enumerator; // okay
+  D2::type t = 0; // okay
+
+  D2::E2 e2 = D2::enumerator2; // okay
+
+  D2::E3 e3; // expected-error{{member 'E3' found in multiple base classes of different types}}
+
+  g.a; // expected-error{{non-static member 'a' found in multiple base-class subobjects of type 'A':}}
+  g.static_f(0); // okay
+}
+
+void D2::test_virtual_lookup() {
+  (void)a;
+  (void)b;
+  (void)c; // okay
+  d; // expected-error{{member 'd' found in multiple base classes of different types}}
+  f(0); // okay
+  static_f(0); // okay
+
+  E e = enumerator; // okay
+  type t = 0; // okay
+
+  E2 e2 = enumerator2; // okay
+
+  E3 e3; // expected-error{{member 'E3' found in multiple base classes of different types}}
+}
+
+void G::test_virtual_lookup() {
+  a; // expected-error{{non-static member 'a' found in multiple base-class subobjects of type 'A':}}
+  static_f(0); // okay
+}
+
+
+struct HasMemberType1 {
+  struct type { }; // expected-note{{member found by ambiguous name lookup}}
+};
+
+struct HasMemberType2 {
+  struct type { }; // expected-note{{member found by ambiguous name lookup}}
+};
+
+struct HasAnotherMemberType : HasMemberType1, HasMemberType2 { 
+  struct type { };
+};
+
+struct UsesAmbigMemberType : HasMemberType1, HasMemberType2 {
+  type t; // expected-error{{member 'type' found in multiple base classes of different types}}
+};
+
+struct X0 {
+  struct Inner {
+    static const int m;
+  };
+  
+  static const int n = 17;
+};
+
+const int X0::Inner::m = n;
diff --git a/test/SemaCXX/member-operator-expr.cpp b/test/SemaCXX/member-operator-expr.cpp
new file mode 100644
index 0000000..5e3d0c0
--- /dev/null
+++ b/test/SemaCXX/member-operator-expr.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+class X {
+public:
+  int operator++();
+  operator int();
+};
+
+void test() {
+  X x;
+  int i;
+
+  i = x.operator++();
+  i = x.operator int();
+  x.operator--(); // expected-error{{no member named 'operator--'}}
+  x.operator float(); // expected-error{{no member named 'operator float'}}
+  x.operator; // expected-error{{missing type specifier after 'operator'}}
+}
+
+void test2() {
+  X *x;
+  int i;
+
+  i = x->operator++();
+  i = x->operator int();
+  x->operator--(); // expected-error{{no member named 'operator--'}}
+  x->operator float(); // expected-error{{no member named 'operator float'}}
+  x->operator; // expected-error{{missing type specifier after 'operator'}}
+}
diff --git a/test/SemaCXX/member-pointer-size.cpp b/test/SemaCXX/member-pointer-size.cpp
new file mode 100644
index 0000000..3aa1eaf
--- /dev/null
+++ b/test/SemaCXX/member-pointer-size.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown %s -fsyntax-only -verify
+// RUN: %clang_cc1 -triple i686-unknown-unknown %s -fsyntax-only -verify
+#include <stddef.h>
+
+struct A;
+
+void f() {
+  int A::*dataMember;
+  
+  int (A::*memberFunction)();
+  
+  typedef int assert1[sizeof(dataMember) == sizeof(ptrdiff_t) ? 1 : -1];
+  typedef int assert2[sizeof(memberFunction) == sizeof(ptrdiff_t) * 2 ? 1 : -1];
+}
+
diff --git a/test/SemaCXX/member-pointer.cpp b/test/SemaCXX/member-pointer.cpp
new file mode 100644
index 0000000..be25cbd
--- /dev/null
+++ b/test/SemaCXX/member-pointer.cpp
@@ -0,0 +1,159 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct A {};
+enum B { Dummy };
+namespace C {}
+struct D : A {};
+struct E : A {};
+struct F : D, E {};
+struct G : virtual D {};
+
+int A::*pdi1;
+int (::A::*pdi2);
+int (A::*pfi)(int);
+
+int B::*pbi; // expected-error {{expected a class or namespace}}
+int C::*pci; // expected-error {{'pci' does not point into a class}}
+void A::*pdv; // expected-error {{'pdv' declared as a member pointer to void}}
+int& A::*pdr; // expected-error {{'pdr' declared as a member pointer to a reference}}
+
+void f() {
+  // This requires tentative parsing.
+  int (A::*pf)(int, int);
+
+  // Implicit conversion to bool.
+  bool b = pdi1;
+  b = pfi;
+
+  // Conversion from null pointer constant.
+  pf = 0;
+  pf = __null;
+
+  // Conversion to member of derived.
+  int D::*pdid = pdi1;
+  pdid = pdi2;
+
+  // Fail conversion due to ambiguity and virtuality.
+  int F::*pdif = pdi1; // expected-error {{ambiguous conversion from pointer to member of base class 'A' to pointer to member of derived class 'F':}}
+  int G::*pdig = pdi1; // expected-error {{conversion from pointer to member of class 'A' to pointer to member of class 'G' via virtual base 'D' is not allowed}}
+
+  // Conversion to member of base.
+  pdi1 = pdid; // expected-error {{assigning to 'int A::*' from incompatible type 'int D::*'}}
+  
+  // Comparisons
+  int (A::*pf2)(int, int);
+  int (D::*pf3)(int, int) = 0;
+  bool b1 = (pf == pf2); (void)b1;
+  bool b2 = (pf != pf2); (void)b2;
+  bool b3 = (pf == pf3); (void)b3;
+  bool b4 = (pf != 0); (void)b4;
+}
+
+struct TheBase
+{
+  void d();
+};
+
+struct HasMembers : TheBase
+{
+  int i;
+  void f();
+
+  void g();
+  void g(int);
+  static void g(double);
+};
+
+namespace Fake
+{
+  int i;
+  void f();
+}
+
+void g() {
+  HasMembers hm;
+
+  int HasMembers::*pmi = &HasMembers::i;
+  int *pni = &Fake::i;
+  int *pmii = &hm.i;
+
+  void (HasMembers::*pmf)() = &HasMembers::f;
+  void (*pnf)() = &Fake::f;
+  &hm.f; // expected-error {{must explicitly qualify}} expected-warning{{result unused}}
+
+  void (HasMembers::*pmgv)() = &HasMembers::g;
+  void (HasMembers::*pmgi)(int) = &HasMembers::g;
+  void (*pmgd)(double) = &HasMembers::g;
+
+  void (HasMembers::*pmd)() = &HasMembers::d;
+}
+
+struct Incomplete; // expected-note {{forward declaration}}
+
+void h() {
+  HasMembers hm, *phm = &hm;
+
+  int HasMembers::*pi = &HasMembers::i;
+  hm.*pi = 0;
+  int i = phm->*pi;
+  (void)&(hm.*pi);
+  (void)&(phm->*pi);
+  (void)&((&hm)->*pi); 
+
+  void (HasMembers::*pf)() = &HasMembers::f;
+  (hm.*pf)();
+  (phm->*pf)();
+
+  (void)(hm->*pi); // expected-error {{left hand operand to ->* must be a pointer to class compatible with the right hand operand, but is 'HasMembers'}}
+  (void)(phm.*pi); // expected-error {{left hand operand to .* must be a class compatible with the right hand operand, but is 'HasMembers *'}}
+  (void)(i.*pi); // expected-error {{left hand operand to .* must be a class compatible with the right hand operand, but is 'int'}}
+  int *ptr;
+  (void)(ptr->*pi); // expected-error {{left hand operand to ->* must be a pointer to class compatible with the right hand operand, but is 'int *'}}
+
+  int A::*pai = 0;
+  D d, *pd = &d;
+  (void)(d.*pai);
+  (void)(pd->*pai);
+  F f, *ptrf = &f;
+  (void)(f.*pai); // expected-error {{left hand operand to .* must be a class compatible with the right hand operand, but is 'F'}}
+  (void)(ptrf->*pai); // expected-error {{left hand operand to ->* must be a pointer to class compatible with the right hand operand, but is 'F *'}}
+
+  (void)(hm.*i); // expected-error {{pointer-to-member}}
+  (void)(phm->*i); // expected-error {{pointer-to-member}}
+
+  Incomplete *inc;
+  int Incomplete::*pii = 0;
+  (void)(inc->*pii); // expected-error {{pointer into incomplete}}
+}
+
+struct OverloadsPtrMem
+{
+  int operator ->*(const char *);
+};
+
+void i() {
+  OverloadsPtrMem m;
+  int foo = m->*"Awesome!";
+}
+
+namespace pr5985 {
+  struct c {
+    void h();
+    void f() {
+      void (c::*p)();
+      p = &h; // expected-error {{must explicitly qualify}}
+      p = &this->h; // expected-error {{must explicitly qualify}}
+      p = &(*this).h; // expected-error {{must explicitly qualify}}
+    }
+  };
+}
+
+namespace pr6783 {
+  struct Base {};
+  struct X; // expected-note {{forward declaration}}
+
+  int test1(int Base::* p2m, X* object)
+  {
+    return object->*p2m; // expected-error {{left hand operand to ->*}}
+  }
+}
diff --git a/test/SemaCXX/member-pointers-2.cpp b/test/SemaCXX/member-pointers-2.cpp
new file mode 100644
index 0000000..4b3b82c
--- /dev/null
+++ b/test/SemaCXX/member-pointers-2.cpp
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -emit-llvm-only %s
+
+// Tests that Sema properly creates member-access expressions for
+// these instead of bare FieldDecls.
+
+struct Foo {
+  int myvalue;
+
+  // We have to override these to get something with an lvalue result.
+  int &operator++(int);
+  int &operator--(int);
+};
+
+struct Test0 {
+  Foo memfoo;
+  int memint;
+  int memarr[10];
+  Test0 *memptr;
+  struct MemClass { int a; } memstruct;
+  int &memfun();
+  
+  void test() {
+    int *p;
+    p = &Test0::memfoo++;
+    p = &Test0::memfoo--;
+    p = &Test0::memarr[1];
+    p = &Test0::memptr->memint;
+    p = &Test0::memstruct.a;
+    p = &Test0::memfun();
+  }
+};
+
+void test0() {
+  Test0 mytest;
+  mytest.test();
+}
diff --git a/test/SemaCXX/missing-header.cpp b/test/SemaCXX/missing-header.cpp
new file mode 100644
index 0000000..f436579
--- /dev/null
+++ b/test/SemaCXX/missing-header.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+#include "not exist" // expected-error{{'not exist' file not found}}
+
+class AnalysisContext {};
+static ControlFlowKind CheckFallThrough(AnalysisContext &AC) {
+  if (const AsmStmt *AS = dyn_cast<AsmStmt>(S)) {}
+  bool NoReturnEdge = false;
+}
diff --git a/test/SemaCXX/missing-members.cpp b/test/SemaCXX/missing-members.cpp
new file mode 100644
index 0000000..529ba10
--- /dev/null
+++ b/test/SemaCXX/missing-members.cpp
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+namespace A {
+  namespace B {
+    class C { };
+    struct S { };
+    union U { };
+  }
+}
+
+void f() {
+  A::B::i; // expected-error {{no member named 'i' in namespace 'A::B'}}
+  A::B::C::i; // expected-error {{no member named 'i' in 'A::B::C'}}
+  ::i; // expected-error {{no member named 'i' in the global namespace}}
+}
+
+namespace B {
+  class B { };
+}
+
+void g() {
+  A::B::D::E; // expected-error {{no member named 'D' in namespace 'A::B'}}
+  B::B::C::D; // expected-error {{no member named 'C' in 'B::B'}}
+  ::C::D; // expected-error {{no member named 'C' in the global namespace}}
+}
+
+int A::B::i = 10; // expected-error {{no member named 'i' in namespace 'A::B'}}
+int A::B::C::i = 10; // expected-error {{no member named 'i' in 'A::B::C'}}
+int A::B::S::i = 10; // expected-error {{no member named 'i' in 'A::B::S'}}
+int A::B::U::i = 10; // expected-error {{no member named 'i' in 'A::B::U'}}
+
+using A::B::D; // expected-error {{no member named 'D' in namespace 'A::B'}}
+
+struct S : A::B::C { 
+  using A::B::C::f; // expected-error {{no member named 'f' in 'A::B::C'}}
+  
+};
diff --git a/test/SemaCXX/ms-exception-spec.cpp b/test/SemaCXX/ms-exception-spec.cpp
new file mode 100644
index 0000000..bda56f5
--- /dev/null
+++ b/test/SemaCXX/ms-exception-spec.cpp
@@ -0,0 +1,3 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify -fms-extensions
+
+void f() throw(...) { }
diff --git a/test/SemaCXX/namespace-alias.cpp b/test/SemaCXX/namespace-alias.cpp
new file mode 100644
index 0000000..3ea1ccf
--- /dev/null
+++ b/test/SemaCXX/namespace-alias.cpp
@@ -0,0 +1,93 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace N { struct X { }; };
+
+namespace A = N;
+
+int B; // expected-note {{previous definition is here}}
+namespace B = N; // expected-error {{redefinition of 'B' as different kind of symbol}}
+
+namespace C { } // expected-note {{previous definition is here}}
+namespace C = N; // expected-error {{redefinition of 'C'}}
+
+int i;
+namespace D = i; // expected-error {{expected namespace name}}
+
+namespace E = N::Foo; // expected-error {{expected namespace name}}
+
+namespace F {
+  namespace A { namespace B { } } // expected-note {{candidate found by name lookup is 'F::A::B'}}
+  namespace B { } // expected-note {{candidate found by name lookup is 'F::B'}}
+  using namespace A;
+  namespace D = B; // expected-error {{reference to 'B' is ambiguous}}
+}
+
+namespace G { 
+  namespace B = N;
+}
+
+namespace H {
+  namespace A1 { }
+  namespace A2 { }
+
+  // These all point to A1.
+  namespace B = A1; // expected-note {{previous definition is here}}
+  namespace B = A1;
+  namespace C = B;
+  namespace B = C;
+
+  namespace B = A2; // expected-error {{redefinition of 'B' as different kind of symbol}}
+}
+
+namespace I { 
+  namespace A1 { int i; }
+  
+  namespace A2 = A1;
+}
+
+int f() {
+  return I::A2::i;
+}
+
+namespace J {
+  namespace A { 
+    namespace B { void func (); }
+  }
+
+  namespace C = A;
+
+  using namespace C::B;
+
+  void g() {
+    func();
+  }
+}
+
+namespace K {
+  namespace KA { void func(); }
+
+  void f() {
+    namespace KB = KA;
+    KB::func();
+  }
+
+  template <class T> void g() {
+    namespace KC = KA;
+    KC::func();
+  }
+  template void g<int>();
+  template void g<long>();
+
+  void h() {
+    KB::func(); // expected-error {{undeclared identifier 'KB'}}
+    KC::func(); // expected-error {{undeclared identifier 'KC'}}
+  }
+}
+
+// PR6341
+namespace A = N;
+namespace N { }
+namespace A = N;
+
+A::X nx;
+
diff --git a/test/SemaCXX/namespace.cpp b/test/SemaCXX/namespace.cpp
new file mode 100644
index 0000000..d47b707
--- /dev/null
+++ b/test/SemaCXX/namespace.cpp
@@ -0,0 +1,92 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s 
+namespace A { // expected-note 2 {{previous definition is here}}
+  int A;
+  void f() { A = 0; }
+}
+
+void f() { A = 0; } // expected-error {{unexpected namespace name 'A': expected expression}}
+int A; // expected-error {{redefinition of 'A' as different kind of symbol}}
+class A; // expected-error {{redefinition of 'A' as different kind of symbol}}
+
+class B {}; // expected-note {{previous definition is here}} \
+            // expected-note{{candidate function (the implicit copy assignment operator)}}
+
+void C(); // expected-note {{previous definition is here}}
+namespace C {} // expected-error {{redefinition of 'C' as different kind of symbol}}
+
+namespace D {
+  class D {};
+}
+
+namespace S1 {
+  int x;
+
+  namespace S2 {
+
+    namespace S3 {
+      B x;
+    }
+  }
+}
+
+namespace S1 {
+  void f() {
+    x = 0;
+  }
+
+  namespace S2 {
+    
+    namespace S3 {
+      void f() {
+        x = 0; // expected-error {{no viable overloaded '='}}
+      }
+    }
+
+    int y;
+  }
+}
+
+namespace S1 {
+  namespace S2 {
+    namespace S3 {
+      void f3() {
+        y = 0;
+      }
+    }
+  }
+}
+
+namespace B {} // expected-error {{redefinition of 'B' as different kind of symbol}}
+
+
+namespace foo {
+  enum x {
+    Y
+  };
+}
+
+static foo::x  test1;  // ok
+
+static foo::X  test2;  // typo: expected-error {{no type named 'X' in}}
+
+namespace PR6620 {
+  namespace numeric {
+    namespace op {
+      struct greater {};
+    }
+    namespace {
+      extern op::greater const greater;
+    }
+  }
+
+  namespace numeric {
+    namespace {
+      op::greater const greater = op::greater();
+    }
+
+    template<typename T, typename U>
+    int f(T& l, U& r)
+    { numeric::greater(l, r); }
+
+  }
+}
diff --git a/test/SemaCXX/nested-name-spec.cpp b/test/SemaCXX/nested-name-spec.cpp
new file mode 100644
index 0000000..59a8e8c
--- /dev/null
+++ b/test/SemaCXX/nested-name-spec.cpp
@@ -0,0 +1,230 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++98 -verify %s 
+namespace A {
+  struct C {
+    static int cx;
+
+    static int cx2;
+
+    static int Ag1();
+    static int Ag2();
+  };
+  int ax;
+  void Af();
+}
+
+A:: ; // expected-error {{expected unqualified-id}}
+// FIXME: there is a member 'ax'; it's just not a class.
+::A::ax::undef ex3; // expected-error {{no member named 'ax'}}
+A::undef1::undef2 ex4; // expected-error {{no member named 'undef1'}}
+
+int A::C::Ag1() { return 0; }
+
+static int A::C::Ag2() { return 0; } // expected-error{{'static' can}}
+
+int A::C::cx = 17;
+
+
+static int A::C::cx2 = 17; // expected-error{{'static' can}}
+
+class C2 {
+  void m(); // expected-note{{member declaration nearly matches}}
+
+  void f(const int& parm); // expected-note{{member declaration nearly matches}}
+  void f(int) const; // expected-note{{member declaration nearly matches}}
+  void f(float);
+
+  int x;
+};
+
+void C2::m() const { } // expected-error{{out-of-line definition of 'm' does not match any declaration in 'C2'}}
+
+void C2::f(int) { } // expected-error{{out-of-line definition of 'f' does not match any declaration in 'C2'}}
+
+void C2::m() {
+  x = 0;
+}
+
+namespace B {
+  void ::A::Af() {} // expected-error {{definition or redeclaration of 'Af' not in a namespace enclosing 'A'}}
+}
+
+void f1() {
+  void A::Af(); // expected-error {{definition or redeclaration of 'Af' not allowed inside a function}}
+}
+
+void f2() {
+  A:: ; // expected-error {{expected unqualified-id}}
+  A::C::undef = 0; // expected-error {{no member named 'undef'}}
+  ::A::C::cx = 0;
+  int x = ::A::ax = A::C::cx;
+  x = sizeof(A::C);
+  x = sizeof(::A::C::cx);
+}
+
+A::C c1;
+struct A::C c2;
+struct S : public A::C {};
+struct A::undef; // expected-error {{no struct named 'undef' in namespace 'A'}}
+
+namespace A2 {
+  typedef int INT;
+  struct RC;
+  struct CC {
+    struct NC;
+  };
+}
+
+struct A2::RC {
+  INT x;
+};
+
+struct A2::CC::NC {
+  void m() {}
+};
+
+void f3() {
+  N::x = 0; // expected-error {{use of undeclared identifier 'N'}}
+  int N;
+  N::x = 0; // expected-error {{expected a class or namespace}}
+  { int A;           A::ax = 0; }
+  { typedef int A;   A::ax = 0; } // expected-error{{expected a class or namespace}}
+  { typedef A::C A;  A::ax = 0; } // expected-error {{no member named 'ax'}}
+  { typedef A::C A;  A::cx = 0; }
+}
+
+// make sure the following doesn't hit any asserts
+void f4(undef::C); // expected-error {{use of undeclared identifier 'undef'}} \
+                      expected-error {{variable has incomplete type 'void'}}
+
+typedef void C2::f5(int); // expected-error{{typedef declarator cannot be qualified}}
+
+void f6(int A2::RC::x); // expected-error{{parameter declarator cannot be qualified}}
+
+int A2::RC::x; // expected-error{{non-static data member defined out-of-line}}
+
+void A2::CC::NC::m(); // expected-error{{out-of-line declaration of a member must be a definition}}
+
+
+namespace E {
+  int X = 5;
+  
+  namespace Nested {
+    enum E {
+      X = 0
+    };
+
+    void f() {
+      return E::X; // expected-error{{expected a class or namespace}}
+    }
+  }
+}
+
+
+class Operators {
+  Operators operator+(const Operators&) const; // expected-note{{member declaration nearly matches}}
+  operator bool();
+};
+
+Operators Operators::operator+(const Operators&) { // expected-error{{out-of-line definition of 'operator+' does not match any declaration in 'Operators'}}
+  Operators ops;
+  return ops;
+}
+
+Operators Operators::operator+(const Operators&) const {
+  Operators ops;
+  return ops;
+}
+
+Operators::operator bool() {
+  return true;
+}
+
+namespace A {
+  void g(int&); // expected-note{{member declaration nearly matches}}
+} 
+
+void A::f() {} // expected-error{{out-of-line definition of 'f' does not match any declaration in namespace 'A'}}
+
+void A::g(const int&) { } // expected-error{{out-of-line definition of 'g' does not match any declaration in namespace 'A'}}
+
+struct Struct { };
+
+void Struct::f() { } // expected-error{{out-of-line definition of 'f' does not match any declaration in 'Struct'}}
+
+void global_func(int);
+void global_func2(int);
+
+namespace N {
+  void ::global_func(int) { } // expected-error{{definition or redeclaration of 'global_func' cannot name the global scope}}
+
+  void f();
+  // FIXME: if we move this to a separate definition of N, things break!
+}
+void ::global_func2(int) { } // expected-error{{definition or redeclaration of 'global_func2' cannot name the global scope}}
+
+void N::f() { } // okay
+
+struct Y;  // expected-note{{forward declaration of 'Y'}}
+Y::foo y; // expected-error{{incomplete type 'Y' named in nested name specifier}}
+
+X::X() : a(5) { } // expected-error{{use of undeclared identifier 'X'}} \
+      // expected-error{{C++ requires a type specifier for all declarations}} \
+      // expected-error{{only constructors take base initializers}}
+
+struct foo_S {
+  static bool value;
+};
+bool (foo_S::value);
+
+
+namespace somens {
+  struct a { }; // expected-note{{candidate constructor (the implicit copy constructor)}}
+}
+
+template <typename T>
+class foo {
+};
+
+
+// PR4452 / PR4451
+foo<somens:a> a2;  // expected-error {{unexpected ':' in nested name specifier}}
+
+somens::a a3 = a2; // expected-error {{no viable conversion}}
+
+// typedefs and using declarations.
+namespace test1 {
+  namespace ns {
+    class Counter { public: static int count; };
+    typedef Counter counter;
+  }
+  using ns::counter;
+
+  class Test {
+    void test1() {
+      counter c;
+      c.count++;
+      counter::count++;
+    }
+  };
+}
+
+// We still need to do lookup in the lexical scope, even if we push a
+// non-lexical scope.
+namespace test2 {
+  namespace ns {
+    extern int *count_ptr;
+  }
+  namespace {
+    int count = 0;
+  }
+
+  int *ns::count_ptr = &count;
+}
+
+// PR6259, invalid case
+namespace test3 {
+  class A; // expected-note {{forward declaration}}
+  void foo(const char *path) {
+    A::execute(path); // expected-error {{incomplete type 'test3::A' named in nested name specifier}}
+  }
+}
diff --git a/test/SemaCXX/new-delete-predefined-decl-2.cpp b/test/SemaCXX/new-delete-predefined-decl-2.cpp
new file mode 100644
index 0000000..981476d
--- /dev/null
+++ b/test/SemaCXX/new-delete-predefined-decl-2.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -DQUALIFIED -fsyntax-only -verify %s
+
+// PR5904
+void f0(int *ptr) {
+#ifndef QUALIFIED
+  operator delete(ptr);
+#endif
+}
+
+void f1(int *ptr) {
+  ::operator delete[](ptr);
+}
diff --git a/test/SemaCXX/new-delete-predefined-decl.cpp b/test/SemaCXX/new-delete-predefined-decl.cpp
new file mode 100644
index 0000000..20b15b7
--- /dev/null
+++ b/test/SemaCXX/new-delete-predefined-decl.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -DTEMPLATE_OVERLOAD -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+#include <stddef.h>
+
+// Note that each test must be run separately so it can be the first operator
+// new declaration in the file.
+
+#if defined(TEMPLATE_OVERLOAD)
+// Don't crash on global template operator new overloads.
+template<typename T> void* operator new(size_t, T);
+void test_template_overload() {
+  (void)new(0) double;
+}
+#endif
+
+void test_predefined() {
+  (void)new double;
+}
diff --git a/test/SemaCXX/new-delete.cpp b/test/SemaCXX/new-delete.cpp
new file mode 100644
index 0000000..50aba47
--- /dev/null
+++ b/test/SemaCXX/new-delete.cpp
@@ -0,0 +1,233 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+#include <stddef.h>
+
+struct S // expected-note {{candidate}}
+{
+  S(int, int, double); // expected-note {{candidate}}
+  S(double, int); // expected-note 2 {{candidate}}
+  S(float, int); // expected-note 2 {{candidate}}
+};
+struct T; // expected-note{{forward declaration of 'T'}}
+struct U
+{
+  // A special new, to verify that the global version isn't used.
+  void* operator new(size_t, S*); // expected-note {{candidate}}
+};
+struct V : U
+{
+};
+
+// PR5823
+void* operator new(const size_t); // expected-note 2 {{candidate}}
+void* operator new(size_t, int*); // expected-note 3 {{candidate}}
+void* operator new(size_t, float*); // expected-note 3 {{candidate}}
+void* operator new(size_t, S); // expected-note 2 {{candidate}}
+
+void good_news()
+{
+  int *pi = new int;
+  float *pf = new (pi) float();
+  pi = new int(1);
+  pi = new int('c');
+  const int *pci = new const int();
+  S *ps = new S(1, 2, 3.4);
+  ps = new (pf) (S)(1, 2, 3.4);
+  S *(*paps)[2] = new S*[*pi][2];
+  ps = new (S[3])(1, 2, 3.4);
+  typedef int ia4[4];
+  ia4 *pai = new (int[3][4]);
+  pi = ::new int;
+  U *pu = new (ps) U;
+  V *pv = new (ps) V;
+  
+  pi = new (S(1.0f, 2)) int;
+  
+  (void)new int[true];
+}
+
+struct abstract {
+  virtual ~abstract() = 0;
+};
+
+void bad_news(int *ip)
+{
+  int i = 1;
+  (void)new; // expected-error {{missing type specifier}}
+  (void)new 4; // expected-error {{missing type specifier}}
+  (void)new () int; // expected-error {{expected expression}}
+  (void)new int[1.1]; // expected-error {{array size expression must have integral or enumerated type, not 'double'}}
+  (void)new int[1][i]; // expected-error {{only the first dimension}}
+  (void)new (int[1][i]); // expected-error {{only the first dimension}}
+  (void)new (int[i]); // expected-error {{when type is in parentheses}}
+  (void)new int(*(S*)0); // expected-error {{no viable conversion from 'S' to 'int'}}
+  (void)new int(1, 2); // expected-error {{excess elements in scalar initializer}}
+  (void)new S(1); // expected-error {{no matching constructor}}
+  (void)new S(1, 1); // expected-error {{call to constructor of 'S' is ambiguous}}
+  (void)new const int; // expected-error {{default initialization of an object of const type 'int const'}}
+  (void)new float*(ip); // expected-error {{cannot initialize a new value of type 'float *' with an lvalue of type 'int *'}}
+  // Undefined, but clang should reject it directly.
+  (void)new int[-1]; // expected-error {{array size is negative}}
+  (void)new int[*(S*)0]; // expected-error {{array size expression must have integral or enumerated type, not 'S'}}
+  (void)::S::new int; // expected-error {{expected unqualified-id}}
+  (void)new (0, 0) int; // expected-error {{no matching function for call to 'operator new'}}
+  (void)new (0L) int; // expected-error {{call to 'operator new' is ambiguous}}
+  // This must fail, because the member version shouldn't be found.
+  (void)::new ((S*)0) U; // expected-error {{no matching function for call to 'operator new'}}
+  // This must fail, because any member version hides all global versions.
+  (void)new U; // expected-error {{no matching function for call to 'operator new'}}
+  (void)new (int[]); // expected-error {{array size must be specified in new expressions}}
+  (void)new int&; // expected-error {{cannot allocate reference type 'int &' with new}}
+  // Some lacking cases due to lack of sema support.
+}
+
+void good_deletes()
+{
+  delete (int*)0;
+  delete [](int*)0;
+  delete (S*)0;
+  ::delete (int*)0;
+}
+
+void bad_deletes()
+{
+  delete 0; // expected-error {{cannot delete expression of type 'int'}}
+  delete [0] (int*)0; // expected-error {{expected ']'}} \
+                      // expected-note {{to match this '['}}
+  delete (void*)0; // expected-error {{cannot delete expression}}
+  delete (T*)0; // expected-warning {{deleting pointer to incomplete type}}
+  ::S::delete (int*)0; // expected-error {{expected unqualified-id}}
+}
+
+struct X0 { };
+
+struct X1 {
+  operator int*();
+  operator float();
+};
+
+struct X2 {
+  operator int*(); // expected-note {{candidate function}}
+  operator float*(); // expected-note {{candidate function}}
+};
+
+void test_delete_conv(X0 x0, X1 x1, X2 x2) {
+  delete x0; // expected-error{{cannot delete}}
+  delete x1;
+  delete x2; // expected-error{{ambiguous conversion of delete expression of type 'X2' to a pointer}}
+}
+
+// PR4782
+class X3 {
+public:
+  static void operator delete(void * mem, size_t size);
+};
+
+class X4 {
+public:
+  static void release(X3 *x);
+  static void operator delete(void * mem, size_t size);
+};
+
+
+void X4::release(X3 *x) {
+  delete x;
+}
+
+class X5 {
+public:
+  void Destroy() const { delete this; }
+};
+
+class Base {
+public:
+  static void *operator new(signed char) throw(); // expected-error {{'operator new' takes type size_t}}
+  static int operator new[] (size_t) throw(); // expected-error {{operator new[]' must return type 'void *'}}
+};
+
+class Tier {};
+class Comp : public Tier {};
+
+class Thai : public Base {
+public:
+  Thai(const Tier *adoptDictionary);
+};
+
+void loadEngineFor() {
+  const Comp *dict;
+  new Thai(dict);
+}
+
+template <class T> struct TBase {
+  void* operator new(T size, int); // expected-error {{'operator new' cannot take a dependent type as first parameter; use size_t}}
+};
+
+TBase<int> t1;
+
+class X6 {
+public:
+  static void operator delete(void*, int); // expected-note {{member found by ambiguous name lookup}}
+};
+
+class X7 {
+public:
+  static void operator delete(void*, int); // expected-note {{member found by ambiguous name lookup}}
+};
+
+class X8 : public X6, public X7 {
+};
+
+void f(X8 *x8) {
+  delete x8; // expected-error {{member 'operator delete' found in multiple base classes of different types}}
+}
+
+class X9 {
+public:
+  static void operator delete(void*, int); // expected-note {{'operator delete' declared here}}
+  static void operator delete(void*, float); // expected-note {{'operator delete' declared here}}
+};
+
+void f(X9 *x9) {
+  delete x9; // expected-error {{no suitable member 'operator delete' in 'X9'}}
+}
+
+struct X10 {
+  virtual ~X10();
+};
+
+struct X11 : X10 { // expected-error {{no suitable member 'operator delete' in 'X11'}}
+  void operator delete(void*, int); // expected-note {{'operator delete' declared here}}
+};
+
+void f() {
+  X11 x11; // expected-note {{implicit default destructor for 'X11' first required here}}
+}
+
+struct X12 {
+  void* operator new(size_t, void*);
+};
+
+struct X13 : X12 {
+  using X12::operator new;
+};
+
+static void* f(void* g)
+{
+    return new (g) X13();
+}
+
+class X14 {
+public:
+  static void operator delete(void*, const size_t);
+};
+
+void f(X14 *x14a, X14 *x14b) {
+  delete x14a;
+}
+
+namespace PR5918 { // Look for template operator new overloads.
+  struct S { template<typename T> static void* operator new(size_t, T); };
+  void test() {
+    (void)new(0) S;
+  }
+}
diff --git a/test/SemaCXX/no-exceptions.cpp b/test/SemaCXX/no-exceptions.cpp
new file mode 100644
index 0000000..019e25c
--- /dev/null
+++ b/test/SemaCXX/no-exceptions.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// Various tests for -fno-exceptions
+
+typedef __SIZE_TYPE__ size_t;
+
+namespace test0 {
+  // rdar://problem/7878149
+  class Foo {
+  public:
+    void* operator new(size_t x);
+  private:
+    void operator delete(void *x);
+  };
+
+  void test() {
+    // Under -fexceptions, this does access control for the associated
+    // 'operator delete'.
+    (void) new Foo();
+  }
+}
diff --git a/test/SemaCXX/no-implicit-builtin-decls.cpp b/test/SemaCXX/no-implicit-builtin-decls.cpp
new file mode 100644
index 0000000..d82f7f1
--- /dev/null
+++ b/test/SemaCXX/no-implicit-builtin-decls.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+void f() {
+  void *p = malloc(sizeof(int) * 10); // expected-error{{use of undeclared identifier 'malloc'}}
+}
+
+int malloc(double);
diff --git a/test/SemaCXX/nullptr.cpp b/test/SemaCXX/nullptr.cpp
new file mode 100644
index 0000000..a3aab7f
--- /dev/null
+++ b/test/SemaCXX/nullptr.cpp
@@ -0,0 +1,67 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s
+#include <stdint.h>
+
+// Don't have decltype yet.
+typedef __typeof__(nullptr) nullptr_t;
+
+struct A {};
+
+int o1(char*);
+void o1(uintptr_t);
+void o2(char*); // expected-note {{candidate}}
+void o2(int A::*); // expected-note {{candidate}}
+
+nullptr_t f(nullptr_t null)
+{
+  // Implicit conversions.
+  null = nullptr;
+  void *p = nullptr;
+  p = null;
+  int *pi = nullptr;
+  pi = null;
+  null = 0;
+  int A::*pm = nullptr;
+  pm = null;
+  void (*pf)() = nullptr;
+  pf = null;
+  void (A::*pmf)() = nullptr;
+  pmf = null;
+  bool b = nullptr;
+
+  // Can't convert nullptr to integral implicitly.
+  uintptr_t i = nullptr; // expected-error {{cannot initialize}}
+
+  // Operators
+  (void)(null == nullptr);
+  (void)(null <= nullptr);
+  (void)(null == (void*)0);
+  (void)((void*)0 == nullptr);
+  (void)(null <= (void*)0);
+  (void)((void*)0 <= nullptr);
+  (void)(1 > nullptr); // expected-error {{invalid operands to binary expression}}
+  (void)(1 != nullptr); // expected-error {{invalid operands to binary expression}}
+  (void)(1 + nullptr); // expected-error {{invalid operands to binary expression}}
+  (void)(0 ? nullptr : 0); // expected-error {{incompatible operand types}}
+  (void)(0 ? nullptr : (void*)0);
+
+  // Overloading
+  int t = o1(nullptr);
+  t = o1(null);
+  o2(nullptr); // expected-error {{ambiguous}}
+
+  // nullptr is an rvalue, null is an lvalue
+  (void)&nullptr; // expected-error {{address expression must be an lvalue}}
+  nullptr_t *pn = &null;
+
+  // You can reinterpret_cast nullptr to an integer.
+  (void)reinterpret_cast<uintptr_t>(nullptr);
+
+  // You can throw nullptr.
+  throw nullptr;
+}
+
+// Template arguments can be nullptr.
+template <int *PI, void (*PF)(), int A::*PM, void (A::*PMF)()>
+struct T {};
+
+typedef T<nullptr, nullptr, nullptr, nullptr> NT;
diff --git a/test/SemaCXX/offsetof.cpp b/test/SemaCXX/offsetof.cpp
new file mode 100644
index 0000000..3283270
--- /dev/null
+++ b/test/SemaCXX/offsetof.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -Winvalid-offsetof
+
+struct NonPOD {
+  virtual void f();
+  int m;
+};
+
+struct P {
+  NonPOD fieldThatPointsToANonPODType;
+};
+
+void f() {
+  int i = __builtin_offsetof(P, fieldThatPointsToANonPODType.m); // expected-warning{{offset of on non-POD type 'P'}}
+}
+
+struct Base { int x; };
+struct Derived : Base { int y; };
+int o = __builtin_offsetof(Derived, x); // expected-warning{{offset of on non-POD type}}
+
+const int o2 = sizeof(__builtin_offsetof(Derived, x));
diff --git a/test/SemaCXX/overload-call-copycon.cpp b/test/SemaCXX/overload-call-copycon.cpp
new file mode 100644
index 0000000..f57484e
--- /dev/null
+++ b/test/SemaCXX/overload-call-copycon.cpp
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -Wnon-pod-varargs
+class X { };
+
+int& copycon(X x);
+float& copycon(...);
+
+void test_copycon(X x, X const xc, X volatile xv) {
+  int& i1 = copycon(x);
+  int& i2 = copycon(xc);
+  float& f1 = copycon(xv);
+}
+
+class A {
+public:
+  A(A&);
+};
+
+class B : public A { };
+
+short& copycon2(A a);
+int& copycon2(B b);
+float& copycon2(...);
+
+void test_copycon2(A a, const A ac, B b, B const bc, B volatile bv) {
+  int& i1 = copycon2(b);
+  float& f1 = copycon2(bc); // expected-warning {{cannot pass object of non-POD type}}
+  float& f2 = copycon2(bv); // expected-warning {{cannot pass object of non-POD type}}
+  short& s1 = copycon2(a);
+  float& f3 = copycon2(ac); // expected-warning {{cannot pass object of non-POD type}}
+}
+
+int& copycon3(A a);
+float& copycon3(...);
+
+void test_copycon3(B b, const B bc) {
+  int& i1 = copycon3(b);
+  float& f1 = copycon3(bc); // expected-warning {{cannot pass object of non-POD type}}
+}
+
+class C : public B { };
+
+float& copycon4(A a);
+int& copycon4(B b);
+
+void test_copycon4(C c) {
+  int& i = copycon4(c);
+};
diff --git a/test/SemaCXX/overload-call.cpp b/test/SemaCXX/overload-call.cpp
new file mode 100644
index 0000000..79c74ce
--- /dev/null
+++ b/test/SemaCXX/overload-call.cpp
@@ -0,0 +1,432 @@
+// RUN: %clang_cc1 -fsyntax-only -pedantic -verify %s
+int* f(int) { return 0; }
+float* f(float) { return 0; }
+void f();
+
+void test_f(int iv, float fv) {
+  float* fp = f(fv);
+  int* ip = f(iv);
+}
+
+int* g(int, float, int); // expected-note {{ candidate function }}
+float* g(int, int, int); // expected-note {{ candidate function }}
+double* g(int, float, float); // expected-note {{ candidate function }}
+char* g(int, float, ...); // expected-note {{ candidate function }}
+void g();
+
+void test_g(int iv, float fv) {
+  int* ip1 = g(iv, fv, 0);
+  float* fp1 = g(iv, iv, 0);
+  double* dp1 = g(iv, fv, fv);
+  char* cp1 = g(0, 0);
+  char* cp2 = g(0, 0, 0, iv, fv);
+
+  double* dp2 = g(0, fv, 1.5); // expected-error {{ call to 'g' is ambiguous; candidates are: }}
+}
+
+double* h(double f);
+int* h(int);
+
+void test_h(float fv, unsigned char cv) {
+  double* dp = h(fv);
+  int* ip = h(cv);
+}
+
+int* i(int);
+double* i(long);
+
+void test_i(short sv, int iv, long lv, unsigned char ucv) {
+  int* ip1 = i(sv);
+  int* ip2 = i(iv);
+  int* ip3 = i(ucv);
+  double* dp1 = i(lv);
+}
+
+int* j(void*);
+double* j(bool);
+
+void test_j(int* ip) {
+  int* ip1 = j(ip);
+}
+
+int* k(char*);
+double* k(bool);
+
+void test_k() {
+  int* ip1 = k("foo"); // expected-warning{{conversion from string literal to 'char *' is deprecated}}
+  double* dp1 = k(L"foo");
+}
+
+int* l(wchar_t*);
+double* l(bool);
+
+void test_l() {
+  int* ip1 = l(L"foo"); // expected-warning{{conversion from string literal to 'wchar_t *' is deprecated}}
+  double* dp1 = l("foo");
+}
+
+int* m(const char*);
+double* m(char*);
+
+void test_m() {
+  int* ip = m("foo");
+}
+
+int* n(char*);
+double* n(void*);
+class E;
+
+void test_n(E* e) {
+  char ca[7];
+  int* ip1 = n(ca);
+  int* ip2 = n("foo"); // expected-warning{{conversion from string literal to 'char *' is deprecated}}
+
+  float fa[7];
+  double* dp1 = n(fa);
+
+  double* dp2 = n(e);
+}
+
+enum PromotesToInt {
+  PromotesToIntValue = -1
+};
+
+enum PromotesToUnsignedInt {
+  PromotesToUnsignedIntValue = __INT_MAX__ * 2U
+};
+
+int* o(int);
+double* o(unsigned int);
+float* o(long);
+
+void test_o() {
+  int* ip1 = o(PromotesToIntValue);
+  double* dp1 = o(PromotesToUnsignedIntValue);
+}
+
+int* p(int);
+double* p(double);
+
+void test_p() {
+  int* ip = p((short)1);
+  double* dp = p(1.0f);
+}
+
+struct Bits {
+  signed short int_bitfield : 5;
+  unsigned int uint_bitfield : 8;
+};
+
+int* bitfields(int, int);
+float* bitfields(unsigned int, int);
+
+void test_bitfield(Bits bits, int x) {
+  int* ip = bitfields(bits.int_bitfield, 0);
+  float* fp = bitfields(bits.uint_bitfield, 0u);
+}
+
+int* multiparm(long, int, long); // expected-note {{ candidate function }}
+float* multiparm(int, int, int); // expected-note {{ candidate function }}
+double* multiparm(int, int, short); // expected-note {{ candidate function }}
+
+void test_multiparm(long lv, short sv, int iv) {
+  int* ip1 = multiparm(lv, iv, lv);
+  int* ip2 = multiparm(lv, sv, lv);
+  float* fp1 = multiparm(iv, iv, iv);
+  float* fp2 = multiparm(sv, iv, iv);
+  double* dp1 = multiparm(sv, sv, sv);
+  double* dp2 = multiparm(iv, sv, sv);
+  multiparm(sv, sv, lv); // expected-error {{ call to 'multiparm' is ambiguous; candidates are: }}
+}
+
+// Test overloading based on qualification vs. no qualification
+// conversion.
+int* quals1(int const * p);
+char* quals1(int * p);
+
+int* quals2(int const * const * pp);
+char* quals2(int * * pp);
+
+int* quals3(int const * * const * ppp);
+char* quals3(int *** ppp);
+
+void test_quals(int * p, int * * pp, int * * * ppp) {
+  char* q1 = quals1(p);
+  char* q2 = quals2(pp);
+  char* q3 = quals3(ppp);
+}
+
+// Test overloading based on qualification ranking (C++ 13.3.2)p3.
+int* quals_rank1(int const * p);
+float* quals_rank1(int const volatile *p);
+char* quals_rank1(char*);
+double* quals_rank1(const char*);
+
+int* quals_rank2(int const * const * pp);
+float* quals_rank2(int * const * pp);
+
+void quals_rank3(int const * const * const volatile * p); // expected-note{{candidate function}}
+void quals_rank3(int const * const volatile * const * p); // expected-note{{candidate function}}
+
+void quals_rank3(int const *); // expected-note{{candidate function}}
+void quals_rank3(int volatile *); // expected-note{{candidate function}}
+
+void test_quals_ranking(int * p, int volatile *pq, int * * pp, int * * * ppp) {
+  int* q1 = quals_rank1(p);
+  float* q2 = quals_rank1(pq); 
+  double* q3 = quals_rank1("string literal");
+  char a[17];
+  const char* ap = a;
+  char* q4 = quals_rank1(a);
+  double* q5 = quals_rank1(ap);
+
+  float* q6 = quals_rank2(pp);
+
+  quals_rank3(ppp); // expected-error {{call to 'quals_rank3' is ambiguous; candidates are:}}
+
+  quals_rank3(p); // expected-error {{call to 'quals_rank3' is ambiguous; candidates are:}}
+  quals_rank3(pq);
+}
+
+// Test overloading based on derived-to-base conversions
+class A { };
+class B : public A { };
+class C : public B { };
+class D : public C { };
+
+int* derived1(A*);
+char* derived1(const A*);
+float* derived1(void*);
+
+int* derived2(A*);
+float* derived2(B*);
+
+int* derived3(A*);
+float* derived3(const B*);
+char* derived3(C*);
+
+void test_derived(B* b, B const* bc, C* c, const C* cc, void* v, D* d) {
+  int* d1 = derived1(b);
+  char* d2 = derived1(bc);
+  int* d3 = derived1(c);
+  char* d4 = derived1(cc);
+  float* d5 = derived1(v);
+
+  float* d6 = derived2(b);
+  float* d7 = derived2(c);
+
+  char* d8 = derived3(d);
+}
+
+// Test overloading of references. 
+// (FIXME: tests binding to determine candidate sets, not overload 
+//  resolution per se).
+int* intref(int&);
+float* intref(const int&);
+
+void intref_test() {
+  float* ir1 = intref(5);
+  float* ir2 = intref(5.5);
+}
+
+// Test reference binding vs. standard conversions.
+int& bind_vs_conv(const double&);
+float& bind_vs_conv(int);
+
+void bind_vs_conv_test()
+{
+  int& i1 = bind_vs_conv(1.0f);
+  float& f1 = bind_vs_conv((short)1);
+}
+
+// Test that cv-qualifiers get subsumed in the reference binding.
+struct X { };
+struct Y { };
+struct Z : X, Y { };
+
+int& cvqual_subsume(X&); // expected-note{{candidate function}}
+float& cvqual_subsume(const Y&); // expected-note{{candidate function}}
+
+int& cvqual_subsume2(const X&); // expected-note{{candidate function}}
+float& cvqual_subsume2(const volatile Y&); // expected-note{{candidate function}}
+
+Z get_Z();
+
+void cvqual_subsume_test(Z z) {
+  cvqual_subsume(z); // expected-error{{call to 'cvqual_subsume' is ambiguous; candidates are:}}
+  int& x = cvqual_subsume2(get_Z()); // expected-error{{call to 'cvqual_subsume2' is ambiguous; candidates are:}}
+}
+
+// Test overloading with cv-qualification differences in reference
+// binding.
+int& cvqual_diff(X&);
+float& cvqual_diff(const X&);
+
+void cvqual_diff_test(X x, Z z) {
+  int& i1 = cvqual_diff(x);
+  int& i2 = cvqual_diff(z);
+}
+
+// Test overloading with derived-to-base differences in reference
+// binding.
+struct Z2 : Z { };
+
+int& db_rebind(X&);
+long& db_rebind(Y&);
+float& db_rebind(Z&);
+
+void db_rebind_test(Z2 z2) {
+  float& f1 = db_rebind(z2);
+}
+
+class string { };
+class opt : public string { };
+
+struct SR {
+  SR(const string&);
+};
+
+void f(SR) { }
+
+void g(opt o) {
+  f(o);
+}
+
+
+namespace PR5756 {
+  int &a(void*, int);
+  float &a(void*, float);
+  void b() { 
+    int &ir = a(0,0);
+    (void)ir;
+  }
+}
+
+// Tests the exact text used to note the candidates
+namespace test1 {
+  template <class T> void foo(T t, unsigned N); // expected-note {{candidate function [with T = int] not viable: no known conversion from 'char const [6]' to 'unsigned int' for 2nd argument}}
+  void foo(int n, char N); // expected-note {{candidate function not viable: no known conversion from 'char const [6]' to 'char' for 2nd argument}} 
+  void foo(int n); // expected-note {{candidate function not viable: requires 1 argument, but 2 were provided}}
+  void foo(unsigned n = 10); // expected-note {{candidate function not viable: requires at most 1 argument, but 2 were provided}}
+  void foo(int n, const char *s, int t); // expected-note {{candidate function not viable: requires 3 arguments, but 2 were provided}}
+  void foo(int n, const char *s, int t, ...); // expected-note {{candidate function not viable: requires at least 3 arguments, but 2 were provided}}
+  void foo(int n, const char *s, int t, int u = 0); // expected-note {{candidate function not viable: requires at least 3 arguments, but 2 were provided}}
+
+  void test() {
+    foo(4, "hello"); //expected-error {{no matching function for call to 'foo'}}
+  }
+}
+
+// PR 6014
+namespace test2 {
+  struct QFixed {
+    QFixed(int i);
+    QFixed(long i);
+  };
+
+  bool operator==(const QFixed &f, int i);
+
+  class qrgb666 {
+    inline operator unsigned int () const;
+
+    inline bool operator==(const qrgb666 &v) const;
+    inline bool operator!=(const qrgb666 &v) const { return !(*this == v); }
+  };
+}
+
+// PR 6117
+namespace test3 {
+  struct Base {};
+  struct Incomplete;
+
+  void foo(Base *); // expected-note 2 {{cannot convert argument of incomplete type}}
+  void foo(Base &); // expected-note 2 {{cannot convert argument of incomplete type}}
+
+  void test(Incomplete *P) {
+    foo(P); // expected-error {{no matching function for call to 'foo'}}
+    foo(*P); // expected-error {{no matching function for call to 'foo'}}
+  }
+}
+
+namespace DerivedToBaseVsVoid {
+  struct A { };
+  struct B : A { };
+  
+  float &f(void *);
+  int &f(const A*);
+  
+  void g(B *b) {
+    int &ir = f(b);
+  }
+}
+
+// PR 6398 + PR 6421
+namespace test4 {
+  class A;
+  class B {
+    static void foo(); // expected-note {{not viable}}
+    static void foo(int*); // expected-note {{not viable}}
+    static void foo(long*); // expected-note {{not viable}}
+
+    void bar(A *a) { 
+      foo(a); // expected-error {{no matching function for call}}
+    }
+  };
+}
+
+namespace DerivedToBase {
+  struct A { };
+  struct B : A { };
+  struct C : B { };
+  
+  int &f0(const A&);
+  float &f0(B);
+  
+  void g() {
+    float &fr = f0(C());
+  }
+}
+
+namespace PR6483 {
+  struct X0 {
+    operator const unsigned int & () const;
+  };
+
+  struct X1 {
+    operator unsigned int & () const;
+  };
+
+  void f0(const bool &);
+  void f1(bool &); // expected-note 2{{not viable}}
+
+  void g(X0 x0, X1 x1) {
+    f0(x0);
+    f1(x0); // expected-error{{no matching function for call}}
+    f0(x1);
+    f1(x1); // expected-error{{no matching function for call}}
+  }  
+}
+
+namespace PR6078 {
+  struct A {
+    A(short); // expected-note{{candidate constructor}}
+    A(long); // expected-note{{candidate constructor}}
+  };
+  struct S {
+    typedef void ft(A);
+    operator ft*();
+  };
+
+  void f() {
+    S()(0); // expected-error{{conversion from 'int' to 'PR6078::A' is ambiguous}}
+  }
+}
+
+namespace PR6177 {
+  struct String { String(char const*); };
+
+  void f(bool const volatile&); // expected-note{{passing argument to parameter here}}
+  void f(String);
+
+  void g() { f(""); } // expected-error{{volatile lvalue reference to type 'bool const volatile' cannot bind to a value of unrelated type 'char const [1]'}}
+}
diff --git a/test/SemaCXX/overload-decl.cpp b/test/SemaCXX/overload-decl.cpp
new file mode 100644
index 0000000..c610ff7
--- /dev/null
+++ b/test/SemaCXX/overload-decl.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s 
+void f();
+void f(int);
+void f(int, float); 
+void f(int, int);
+void f(int, ...);
+
+typedef float Float;
+void f(int, Float); // expected-note {{previous declaration is here}}
+
+int f(int, Float); // expected-error {{functions that differ only in their return type cannot be overloaded}}
+
+void g(void); // expected-note {{previous declaration is here}}
+int g(); // expected-error {{functions that differ only in their return type cannot be overloaded}}
+
+typedef int INT;
+
+class X {
+  void f();
+  void f(int); // expected-note {{previous declaration is here}}
+  void f() const;
+
+  void f(INT); // expected-error{{cannot be redeclared}}
+
+  void g(int); // expected-note {{previous declaration is here}}
+  void g(int, float); // expected-note {{previous declaration is here}}
+  int g(int, Float); // expected-error {{functions that differ only in their return type cannot be overloaded}}
+
+  static void g(float);
+  static void g(int); // expected-error {{static and non-static member functions with the same parameter types cannot be overloaded}}
+};
diff --git a/test/SemaCXX/overload-member-call.cpp b/test/SemaCXX/overload-member-call.cpp
new file mode 100644
index 0000000..8016b11
--- /dev/null
+++ b/test/SemaCXX/overload-member-call.cpp
@@ -0,0 +1,98 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct X {
+  int& f(int) const; // expected-note 2 {{candidate function}}
+  float& f(int); // expected-note 2 {{candidate function}}
+
+  void test_f(int x) const {
+    int& i = f(x);
+  }
+
+  void test_f2(int x) {
+    float& f2 = f(x);
+  }
+
+  int& g(int) const; // expected-note 2 {{candidate function}}
+  float& g(int); // expected-note 2 {{candidate function}}
+  static double& g(double); // expected-note 2 {{candidate function}}
+
+  void h(int);
+
+  void test_member() {
+    float& f1 = f(0);
+    float& f2 = g(0);
+    double& d1 = g(0.0);
+  }
+
+  void test_member_const() const {
+    int &i1 = f(0);
+    int &i2 = g(0);
+    double& d1 = g(0.0);
+  }
+
+  static void test_member_static() {
+    double& d1 = g(0.0);
+    g(0); // expected-error{{call to 'g' is ambiguous; candidates are:}}
+  }
+};
+
+void test(X x, const X xc, X* xp, const X* xcp, volatile X xv, volatile X* xvp) {
+  int& i1 = xc.f(0);
+  int& i2 = xcp->f(0);
+  float& f1 = x.f(0);
+  float& f2 = xp->f(0);
+  xv.f(0); // expected-error{{no matching member function for call to 'f'; candidates are:}}
+  xvp->f(0); // expected-error{{no matching member function for call to 'f'; candidates are:}}
+
+  int& i3 = xc.g(0);
+  int& i4 = xcp->g(0);
+  float& f3 = x.g(0);
+  float& f4 = xp->g(0);
+  double& d1 = xp->g(0.0);
+  double& d2 = X::g(0.0);
+  X::g(0); // expected-error{{call to 'g' is ambiguous; candidates are:}}
+  
+  X::h(0); // expected-error{{call to non-static member function without an object argument}}
+}
+
+struct X1 {
+  int& member();
+  float& member() const;
+};
+
+struct X2 : X1 { };
+
+void test_X2(X2 *x2p, const X2 *cx2p) {
+  int &ir = x2p->member();
+  float &fr = cx2p->member();
+}
+
+// Tests the exact text used to note the candidates
+namespace test1 {
+  class A {
+    template <class T> void foo(T t, unsigned N); // expected-note {{candidate function [with T = int] not viable: no known conversion from 'char const [6]' to 'unsigned int' for 2nd argument}}
+    void foo(int n, char N); // expected-note {{candidate function not viable: no known conversion from 'char const [6]' to 'char' for 2nd argument}} 
+    void foo(int n); // expected-note {{candidate function not viable: requires 1 argument, but 2 were provided}}
+    void foo(unsigned n = 10); // expected-note {{candidate function not viable: requires at most 1 argument, but 2 were provided}}
+    void foo(int n, const char *s, int t); // expected-note {{candidate function not viable: requires 3 arguments, but 2 were provided}}
+    void foo(int n, const char *s, int t, ...); // expected-note {{candidate function not viable: requires at least 3 arguments, but 2 were provided}}
+    void foo(int n, const char *s, int t, int u = 0); // expected-note {{candidate function not viable: requires at least 3 arguments, but 2 were provided}}
+
+    void bar(double d); //expected-note {{candidate function not viable: 'this' argument has type 'test1::A const', but method is not marked const}}
+    void bar(int i); //expected-note {{candidate function not viable: 'this' argument has type 'test1::A const', but method is not marked const}}
+
+    void baz(A &d); // expected-note {{candidate function not viable: 1st argument ('test1::A const') would lose const qualifier}}
+    void baz(int i); // expected-note {{candidate function not viable: no known conversion from 'test1::A const' to 'int' for 1st argument}} 
+  };
+
+  void test() {
+    A a;
+    a.foo(4, "hello"); //expected-error {{no matching member function for call to 'foo'}}
+
+    const A b = A();
+    b.bar(0); //expected-error {{no matching member function for call to 'bar'}}
+
+    a.baz(b); //expected-error {{no matching member function for call to 'baz'}}
+  }
+}
+
diff --git a/test/SemaCXX/overload-value-dep-arg.cpp b/test/SemaCXX/overload-value-dep-arg.cpp
new file mode 100644
index 0000000..c1834a7
--- /dev/null
+++ b/test/SemaCXX/overload-value-dep-arg.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+class C {
+  C(void*);
+};
+
+int f(const C&);
+int f(unsigned long);
+
+template<typename T> int f(const T* t) {
+  return f(reinterpret_cast<unsigned long>(t));
+}
+
diff --git a/test/SemaCXX/overloaded-builtin-operators.cpp b/test/SemaCXX/overloaded-builtin-operators.cpp
new file mode 100644
index 0000000..61c2e21
--- /dev/null
+++ b/test/SemaCXX/overloaded-builtin-operators.cpp
@@ -0,0 +1,190 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s 
+struct yes;
+struct no;
+
+struct Short {
+  operator short();
+};
+
+struct Long {
+  operator long();
+};
+
+enum E1 { };
+struct Enum1 {
+  operator E1();
+};
+
+enum E2 { };
+struct Enum2 {
+  operator E2();
+};
+
+
+struct X { 
+  void f();
+};
+
+typedef void (X::*pmf)();
+struct Xpmf {
+  operator pmf();
+};
+
+yes& islong(long);
+yes& islong(unsigned long); // FIXME: shouldn't be needed
+no& islong(int);
+
+void f(Short s, Long l, Enum1 e1, Enum2 e2, Xpmf pmf) {
+  // C++ [over.built]p8
+  int i1 = +e1;
+  int i2 = -e2;
+
+  // C++  [over.built]p10:
+  int i3 = ~s;
+  bool b1 = !s;
+
+  // C++ [over.built]p12
+  (void)static_cast<yes&>(islong(s + l));
+  (void)static_cast<no&>(islong(s + s));
+
+  // C++ [over.built]p16
+  (void)(pmf == &X::f);
+  (void)(pmf == 0);
+  
+  // C++ [over.built]p17
+  (void)static_cast<yes&>(islong(s % l));
+  (void)static_cast<yes&>(islong(l << s));
+  (void)static_cast<no&>(islong(s << l));
+  (void)static_cast<yes&>(islong(e1 % l));
+  // FIXME: should pass (void)static_cast<no&>(islong(e1 % e2));
+}
+
+struct ShortRef { // expected-note{{candidate function (the implicit copy assignment operator)}}
+  operator short&();
+};
+
+struct LongRef {
+  operator volatile long&();
+};
+
+struct XpmfRef { // expected-note{{candidate function (the implicit copy assignment operator)}}
+  operator pmf&();
+};
+
+struct E2Ref {
+  operator E2&();
+};
+
+void g(ShortRef sr, LongRef lr, E2Ref e2_ref, XpmfRef pmf_ref) {
+  // C++ [over.built]p3
+  short s1 = sr++;
+
+  // C++ [over.built]p3
+  long l1 = lr--;
+
+  // C++ [over.built]p18
+  short& sr1 = (sr *= lr);
+  volatile long& lr1 = (lr *= sr);
+
+  // C++ [over.built]p20:
+  E2 e2r2;
+  e2r2 = e2_ref;
+  
+  pmf &pmr = (pmf_ref = &X::f); // expected-error{{no viable overloaded '='}}
+  pmf pmr2;
+  pmr2 = pmf_ref;
+               
+  // C++ [over.built]p22
+  short& sr2 = (sr %= lr);
+  volatile long& lr2 = (lr <<= sr);
+
+  bool b1 = (sr && lr) || (sr || lr);
+}
+
+struct VolatileIntPtr {
+  operator int volatile *();
+};
+
+struct ConstIntPtr {
+  operator int const *();
+};
+
+struct VolatileIntPtrRef {
+  operator int volatile *&();
+};
+
+struct ConstIntPtrRef {
+  operator int const *&();
+};
+
+void test_with_ptrs(VolatileIntPtr vip, ConstIntPtr cip, ShortRef sr,
+                    VolatileIntPtrRef vipr, ConstIntPtrRef cipr) {
+  const int& cir1 = cip[sr];
+  const int& cir2 = sr[cip];
+  volatile int& vir1 = vip[sr];
+  volatile int& vir2 = sr[vip];
+  bool b1 = (vip == cip);
+  long p1 = vip - cip;
+
+  // C++ [over.built]p5:
+  int volatile *vip1 = vipr++;
+  int const *cip1 = cipr++;
+  int volatile *&vipr1 = ++vipr;
+  int const *&cipr1 = --cipr;
+
+  // C++ [over.built]p6:
+  int volatile &ivr = *vip;
+
+  // C++ [over.built]p8:
+  int volatile *vip2 = +vip;
+  int i1 = +sr;
+  int i2 = -sr;
+
+  // C++ [over.built]p13:
+  int volatile &ivr2 = vip[17];
+  int const &icr2 = 17[cip];
+}
+
+// C++ [over.match.open]p4
+
+void test_assign_restrictions(ShortRef& sr) {
+  sr = (short)0; // expected-error{{no viable overloaded '='}}
+}
+
+struct Base { };
+struct Derived1 : Base { };
+struct Derived2 : Base { };
+
+template<typename T>
+struct ConvertibleToPtrOf {
+  operator T*();
+};
+
+bool test_with_base_ptrs(ConvertibleToPtrOf<Derived1> d1, 
+                         ConvertibleToPtrOf<Derived2> d2) {
+  return d1 == d2; // expected-error{{invalid operands}}
+}
+
+// DR425
+struct A {
+  template< typename T > operator T() const;
+};
+
+void test_dr425(A a) {
+  // FIXME: lots of candidates here!
+  (void)(1.0f * a); // expected-error{{ambiguous}} \
+                    // expected-note 81{{candidate}}
+}
+
+// pr5432
+enum e {X};
+
+const int a[][2] = {{1}};
+
+int test_pr5432() {
+  return a[X][X];
+}
+
+void f() {
+  (void)__extension__(A());
+}
diff --git a/test/SemaCXX/overloaded-operator-decl.cpp b/test/SemaCXX/overloaded-operator-decl.cpp
new file mode 100644
index 0000000..5f8655c
--- /dev/null
+++ b/test/SemaCXX/overloaded-operator-decl.cpp
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s 
+struct X { 
+  X();
+  X(int); 
+};
+
+X operator+(X, X);
+X operator-(X, X) { X x; return x; }
+
+struct Y {
+  Y operator-() const;
+  void operator()(int x = 17) const;
+  int operator[](int);
+
+  static int operator+(Y, Y); // expected-error{{overloaded 'operator+' cannot be a static member function}}
+};
+
+
+void f(X x) {
+  x = operator+(x, x);
+}
+
+X operator+(int, float); // expected-error{{overloaded 'operator+' must have at least one parameter of class or enumeration type}}
+
+X operator*(X, X = 5); // expected-error{{parameter of overloaded 'operator*' cannot have a default argument}}
+
+X operator/(X, X, ...); // expected-error{{overloaded 'operator/' cannot be variadic}}
+
+X operator%(Y); // expected-error{{overloaded 'operator%' must be a binary operator (has 1 parameter)}}
+
+void operator()(Y&, int, int); // expected-error{{overloaded 'operator()' must be a non-static member function}}
+
+typedef int INT;
+typedef float FLOAT;
+Y& operator++(Y&);
+Y operator++(Y&, INT);
+X operator++(X&, FLOAT); // expected-error{{parameter of overloaded post-increment operator must have type 'int' (not 'FLOAT' (aka 'float'))}}
+
+int operator+; // expected-error{{'operator+' cannot be the name of a variable or data member}}
+
+namespace PR6238 {
+  static struct {
+    void operator()();
+  } plus;
+}
diff --git a/test/SemaCXX/overloaded-operator.cpp b/test/SemaCXX/overloaded-operator.cpp
new file mode 100644
index 0000000..3d737f4
--- /dev/null
+++ b/test/SemaCXX/overloaded-operator.cpp
@@ -0,0 +1,379 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s 
+class X { };
+
+X operator+(X, X);
+
+void f(X x) {
+  x = x + x;
+}
+
+struct Y;
+struct Z;
+
+struct Y {
+  Y(const Z&);
+};
+
+struct Z {
+  Z(const Y&);
+};
+
+Y operator+(Y, Y);
+bool operator-(Y, Y); // expected-note{{candidate function}}
+bool operator-(Z, Z); // expected-note{{candidate function}}
+
+void g(Y y, Z z) {
+  y = y + z;
+  bool b = y - z; // expected-error{{use of overloaded operator '-' is ambiguous; candidates are:}}
+}
+
+struct A {
+  bool operator==(Z&); // expected-note 2{{candidate function}}
+};
+
+A make_A();
+
+bool operator==(A&, Z&); // expected-note 2{{candidate function}}
+
+void h(A a, const A ac, Z z) {
+  make_A() == z;
+  a == z; // expected-error{{use of overloaded operator '==' is ambiguous; candidates are:}}
+  ac == z; // expected-error{{invalid operands to binary expression ('A const' and 'Z')}}
+}
+
+struct B {
+  bool operator==(const B&) const;
+
+  void test(Z z) {
+    make_A() == z;
+  }
+};
+
+enum Enum1 { };
+enum Enum2 { };
+
+struct E1 {
+  E1(Enum1) { }
+};
+
+struct E2 {
+  E2(Enum2);
+};
+
+// C++ [over.match.oper]p3 - enum restriction.
+float& operator==(E1, E2); 
+
+void enum_test(Enum1 enum1, Enum2 enum2, E1 e1, E2 e2) {
+  float &f1 = (e1 == e2);
+  float &f2 = (enum1 == e2); 
+  float &f3 = (e1 == enum2); 
+  float &f4 = (enum1 == enum2);  // expected-error{{non-const lvalue reference to type 'float' cannot bind to a temporary of type 'bool'}}
+}
+
+// PR5244 - Argument-dependent lookup would include the two operators below,
+// which would break later assumptions and lead to a crash.
+class pr5244_foo
+{
+  pr5244_foo(int);
+  pr5244_foo(char);
+};
+
+bool operator==(const pr5244_foo& s1, const pr5244_foo& s2);
+bool operator==(char c, const pr5244_foo& s);
+
+enum pr5244_bar
+{
+    pr5244_BAR
+};
+
+class pr5244_baz
+{
+public:
+    pr5244_bar quux;
+};
+
+void pr5244_barbaz()
+{
+  pr5244_baz quuux;
+  (void)(pr5244_BAR == quuux.quux);
+}
+
+
+
+struct PostInc {
+  PostInc operator++(int);
+  PostInc& operator++();
+};
+
+struct PostDec {
+  PostDec operator--(int);
+  PostDec& operator--();
+};
+
+void incdec_test(PostInc pi, PostDec pd) {
+  const PostInc& pi1 = pi++;
+  const PostDec& pd1 = pd--;
+  PostInc &pi2 = ++pi;
+  PostDec &pd2 = --pd;
+}
+
+struct SmartPtr {
+  int& operator*();
+  long& operator*() const volatile;
+};
+
+void test_smartptr(SmartPtr ptr, const SmartPtr cptr, 
+                   const volatile SmartPtr cvptr) {
+  int &ir = *ptr;
+  long &lr = *cptr;
+  long &lr2 = *cvptr;
+}
+
+
+struct ArrayLike {
+  int& operator[](int);
+};
+
+void test_arraylike(ArrayLike a) {
+  int& ir = a[17];
+}
+
+struct SmartRef {
+  int* operator&();
+};
+
+void test_smartref(SmartRef r) {
+  int* ip = &r;
+}
+
+bool& operator,(X, Y);
+
+void test_comma(X x, Y y) {
+  bool& b1 = (x, y);
+  X& xr = (x, x);
+}
+
+struct Callable {
+  int& operator()(int, double = 2.71828); // expected-note{{candidate function}}
+  float& operator()(int, double, long, ...); // expected-note{{candidate function}}
+
+  double& operator()(float); // expected-note{{candidate function}}
+};
+
+struct Callable2 {
+  int& operator()(int i = 0);
+  double& operator()(...) const;
+};
+
+struct DerivesCallable : public Callable {
+};
+
+void test_callable(Callable c, Callable2 c2, const Callable2& c2c,
+                   DerivesCallable dc) {
+  int &ir = c(1);
+  float &fr = c(1, 3.14159, 17, 42);
+
+  c(); // expected-error{{no matching function for call to object of type 'Callable'}}
+
+  double &dr = c(1.0f);
+
+  int &ir2 = c2();
+  int &ir3 = c2(1);
+  double &fr2 = c2c();
+  
+  int &ir4 = dc(17);
+  double &fr3 = dc(3.14159f);
+}
+
+typedef float FLOAT;
+typedef int& INTREF;
+typedef INTREF Func1(FLOAT, double);
+typedef float& Func2(int, double);
+
+struct ConvertToFunc {
+  operator Func1*(); // expected-note 2{{conversion candidate of type 'INTREF (*)(FLOAT, double)'}}
+  operator Func2&(); // expected-note 2{{conversion candidate of type 'float &(&)(int, double)'}}
+  void operator()();
+};
+
+struct ConvertToFuncDerived : ConvertToFunc { };
+
+void test_funcptr_call(ConvertToFunc ctf, ConvertToFuncDerived ctfd) {
+  int &i1 = ctf(1.0f, 2.0);
+  float &f1 = ctf((short int)1, 1.0f);
+  ctf((long int)17, 2.0); // expected-error{{call to object of type 'ConvertToFunc' is ambiguous}}
+  ctf();
+
+  int &i2 = ctfd(1.0f, 2.0);
+  float &f2 = ctfd((short int)1, 1.0f);
+  ctfd((long int)17, 2.0); // expected-error{{call to object of type 'ConvertToFuncDerived' is ambiguous}}
+  ctfd();
+}
+
+struct HasMember {
+  int m;
+};
+
+struct Arrow1 {
+  HasMember* operator->();
+};
+
+struct Arrow2 {
+  Arrow1 operator->(); // expected-note{{candidate function}}
+};
+
+void test_arrow(Arrow1 a1, Arrow2 a2, const Arrow2 a3) {
+  int &i1 = a1->m;
+  int &i2 = a2->m;
+  a3->m; // expected-error{{no viable overloaded 'operator->'; candidate is}}
+}
+
+struct CopyConBase {
+};
+
+struct CopyCon : public CopyConBase {
+  CopyCon(const CopyConBase &Base);
+
+  CopyCon(const CopyConBase *Base) {
+    *this = *Base;
+  }
+};
+
+namespace N {
+  struct X { };
+}
+
+namespace M {
+  N::X operator+(N::X, N::X);
+}
+
+namespace M {
+  void test_X(N::X x) {
+    (void)(x + x);
+  }
+}
+
+struct AA { bool operator!=(AA&); };
+struct BB : AA {};
+bool x(BB y, BB z) { return y != z; }
+
+
+struct AX { 
+  AX& operator ->();	 // expected-note {{declared here}}
+  int b;
+}; 
+
+void m() {
+  AX a; 
+  a->b = 0; // expected-error {{circular pointer delegation detected}}
+}
+
+struct CircA {
+  struct CircB& operator->(); // expected-note {{declared here}}
+  int val;
+};
+struct CircB {
+  struct CircC& operator->(); // expected-note {{declared here}}
+};
+struct CircC {
+  struct CircA& operator->(); // expected-note {{declared here}}
+};
+
+void circ() {
+  CircA a;
+  a->val = 0; // expected-error {{circular pointer delegation detected}}
+}
+
+// PR5360: Arrays should lead to built-in candidates for subscript.
+typedef enum {
+  LastReg = 23,
+} Register;
+class RegAlloc {
+  int getPriority(Register r) {
+    return usepri[r];
+  }
+  int usepri[LastReg + 1];
+};
+
+// PR5546: Don't generate incorrect and ambiguous overloads for multi-level
+// arrays.
+namespace pr5546
+{
+  enum { X };
+  extern const char *const sMoveCommands[][2][2];
+  const char* a() { return sMoveCommands[X][0][0]; }
+  const char* b() { return (*(sMoveCommands+X))[0][0]; }
+}
+
+// PR5512 and its discussion
+namespace pr5512 {
+  struct Y {
+    operator short();
+    operator float();
+  };
+  void g_test(Y y) {
+    short s = 0;
+    // DR507, this should be ambiguous, but we special-case assignment
+    s = y;
+    // Note: DR507, this is ambiguous as specified
+    //s += y;
+  }
+
+  struct S {};
+  void operator +=(int&, S);
+  void f(S s) {
+    int i = 0;
+    i += s;
+  }
+
+  struct A {operator int();};
+  int a;
+  void b(A x) {
+    a += x;
+  }
+}
+
+// PR5900
+namespace pr5900 {
+  struct NotAnArray {};
+  void test0() {
+    NotAnArray x;
+    x[0] = 0; // expected-error {{does not provide a subscript operator}}
+  }
+
+  struct NonConstArray {
+    int operator[](unsigned); // expected-note {{candidate}}
+  };
+  int test1() {
+    const NonConstArray x = NonConstArray();
+    return x[0]; // expected-error {{no viable overloaded operator[] for type}}
+  }
+
+  // Not really part of this PR, but implemented at the same time.
+  struct NotAFunction {};
+  void test2() {
+    NotAFunction x;
+    x(); // expected-error {{does not provide a call operator}}
+  }
+}
+
+// Operator lookup through using declarations.
+namespace N {
+  struct X2 { };
+}
+
+namespace N2 {
+  namespace M {
+    namespace Inner {
+      template<typename T>
+      N::X2 &operator<<(N::X2&, const T&);
+    }
+    using Inner::operator<<;
+  }
+}
+
+void test_lookup_through_using() {
+  using namespace N2::M;
+  N::X2 x;
+  x << 17;
+}
diff --git a/test/SemaCXX/prefetch-enum.cpp b/test/SemaCXX/prefetch-enum.cpp
new file mode 100644
index 0000000..3c77dae
--- /dev/null
+++ b/test/SemaCXX/prefetch-enum.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -fsyntax-only %s -verify
+// PR5679
+
+enum X { A = 3 };
+
+void Test() {
+  char ch;
+  __builtin_prefetch(&ch, 0, A);
+}
diff --git a/test/SemaCXX/primary-base.cpp b/test/SemaCXX/primary-base.cpp
new file mode 100644
index 0000000..a6cbbad
--- /dev/null
+++ b/test/SemaCXX/primary-base.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+class A { virtual void f(); };
+class B : virtual A { };
+
+class C : B { };
+
+// Since A is already a primary base class, C should be the primary base class
+// of F.
+class F : virtual A, virtual C { };
+
+int sa[sizeof(F) == sizeof(A) ? 1 : -1];
diff --git a/test/SemaCXX/pseudo-destructors.cpp b/test/SemaCXX/pseudo-destructors.cpp
new file mode 100644
index 0000000..472e5b4
--- /dev/null
+++ b/test/SemaCXX/pseudo-destructors.cpp
@@ -0,0 +1,59 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+struct A {};
+
+enum Foo { F };
+typedef Foo Bar;
+
+typedef int Integer;
+typedef double Double;
+
+void g();
+
+namespace N {
+  typedef Foo Wibble;
+  typedef int OtherInteger;
+}
+
+void f(A* a, Foo *f, int *i, double *d) {
+  a->~A();
+  a->A::~A();
+  
+  a->~foo(); // expected-error{{identifier 'foo' in pseudo-destructor expression does not name a type}}
+  
+  // FIXME: the diagnostic below isn't wonderful
+  a->~Bar(); // expected-error{{does not name a type}}
+  
+  f->~Bar();
+  f->~Foo();
+  i->~Bar(); // expected-error{{does not match}}
+  
+  g().~Bar(); // expected-error{{non-scalar}}
+  
+  f->::~Bar();
+  f->N::~Wibble(); // FIXME: technically, Wibble isn't a class-name
+  
+  f->::~Bar(17, 42); // expected-error{{cannot have any arguments}}
+
+  i->~Integer();
+  i->Integer::~Integer();
+  i->N::~OtherInteger();
+  i->N::OtherInteger::~OtherInteger();
+  i->N::OtherInteger::~Integer(); // expected-error{{'Integer' does not refer to a type name in pseudo-destructor expression; expected the name of type 'int'}}
+  i->N::~Integer(); // expected-error{{'Integer' does not refer to a type name in pseudo-destructor expression; expected the name of type 'int'}}
+  i->Integer::~Double(); // expected-error{{the type of object expression ('int') does not match the type being destroyed ('Double' (aka 'double')) in pseudo-destructor expression}}
+}
+
+typedef int Integer;
+
+void destroy_without_call(int *ip) {
+  ip->~Integer; // expected-error{{called immediately}}
+}
+
+// PR5530
+namespace N1 {
+  class X0 { };
+}
+
+void test_X0(N1::X0 &x0) {
+  x0.~X0();
+}
diff --git a/test/SemaCXX/ptrtomember-badcall.cpp b/test/SemaCXX/ptrtomember-badcall.cpp
new file mode 100644
index 0000000..fb774d8
--- /dev/null
+++ b/test/SemaCXX/ptrtomember-badcall.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
+
+struct  S {
+	int i;
+
+	int mem(int);
+};
+
+int foo(int S::* ps, S *s)
+{
+    return (s->*ps)(1); // expected-error {{called object type 'int' is not a function or function pointer}}
+}
+
diff --git a/test/SemaCXX/ptrtomember-overload-resolution.cpp b/test/SemaCXX/ptrtomember-overload-resolution.cpp
new file mode 100644
index 0000000..4c7908e
--- /dev/null
+++ b/test/SemaCXX/ptrtomember-overload-resolution.cpp
@@ -0,0 +1,44 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
+
+// 13.3.3.2 Ranking implicit conversion sequences
+// conversion of A::* to B::* is better than conversion of A::* to C::*,
+struct A {
+int Ai;
+}; 
+
+struct B : public A {}; 
+struct C : public B {}; 
+
+const char * f(int C::*){ return ""; } 
+int f(int B::*) { return 1; } 
+
+struct D : public C {}; 
+
+const char * g(int B::*){ return ""; } 
+int g(int D::*) { return 1; } 
+
+void test() 
+{
+  int i = f(&A::Ai);
+
+  const char * str = g(&A::Ai);
+}
+
+// conversion of B::* to C::* is better than conversion of A::* to C::*
+typedef void (A::*pmfa)();
+typedef void (B::*pmfb)();
+typedef void (C::*pmfc)();
+
+struct X {
+	operator pmfa();
+	operator pmfb();
+};
+
+
+void g(pmfc);
+
+void test2(X x) 
+{
+    g(x);
+}
+
diff --git a/test/SemaCXX/qual-id-test.cpp b/test/SemaCXX/qual-id-test.cpp
new file mode 100644
index 0000000..e5c7306
--- /dev/null
+++ b/test/SemaCXX/qual-id-test.cpp
@@ -0,0 +1,149 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s 
+namespace A
+{
+    namespace B
+    {
+        struct base // expected-note{{object type}}
+        {
+            void x() {}
+            void y() {}
+        };
+    }
+
+    struct member
+    {
+        void foo();
+    };
+
+    struct middleman
+    {
+        member * operator->() { return 0; }
+    };
+
+    struct sub : B::base
+    {
+        void x() {}
+        middleman operator->() { return middleman(); }
+    };
+}
+
+struct bad
+{
+  int x();
+};
+
+namespace C
+{
+    void fun()
+    {
+        A::sub a;
+
+        a.x();
+    
+        a.sub::x();
+        a.base::x();
+
+        a.B::base::x(); // expected-error{{use of undeclared identifier 'B'}}
+
+        a.A::sub::x();
+        a.A::B::base::x();
+
+        a.bad::x(); // expected-error{{'bad::x' is not a member of class 'A::sub'}}
+
+        a->foo();
+        a->member::foo();
+        a->A::member::foo();
+    }
+
+    void fun2()
+    {
+        A::sub *a;
+
+        a->x();
+
+        a->sub::x();
+        a->base::x();
+
+        a->B::base::x(); // expected-error{{use of undeclared identifier 'B'}}
+
+        a->A::sub::x();
+        a->A::B::base::x();
+
+        a->bad::x(); // expected-error{{'bad::x' is not a member of class 'A::sub'}}
+
+        (*a)->foo();
+        (*a)->member::foo();
+        (*a)->A::member::foo();
+    }
+
+    void fun3()
+    {
+        int i;
+        i.foo(); // expected-error{{member reference base type 'int' is not a structure or union}}
+    }
+
+    void fun4a() {
+      A::sub *a;
+      
+      typedef A::member base; // expected-note{{current scope}}
+      a->base::x(); // expected-error{{ambiguous}}      
+    }
+
+    void fun4b() {
+      A::sub *a;
+      
+      typedef A::B::base base;
+      a->base::x();
+    }
+  
+    template<typename T>
+    void fun5()
+    {
+        T a;
+        a.x();
+        a->foo();
+
+        a.A::sub::x();
+        a.A::B::base::x();
+        a->A::member::foo();
+
+        a.bad::x(); // expected-error{{'bad::x' is not a member of class 'A::sub'}}
+    }
+
+  void test_fun5() {
+    fun5<A::sub>(); // expected-note{{instantiation}}
+  }
+  
+  template<typename T>
+  void fun6() {
+    T a;
+    a.sub::x();
+    a.base::x();
+    a->member::foo();
+    a.B::base::x(); // expected-error{{use of undeclared identifier 'B'}}
+   }
+  
+  void test_fun6() {
+    fun6<A::sub>(); // expected-note{{instantiation}}
+  }
+  
+}
+
+// PR4703
+struct a {
+  int a;
+  static int sa;
+};
+
+a a;
+
+int a::sa = a.a; // expected-error {{invalid use of nonstatic data member 'a'}}
+
+
+namespace PR6645 {
+  typedef int foo;
+  namespace Inner {
+    typedef int PR6645::foo; // expected-error{{typedef declarator cannot be qualified}} \
+    // expected-error{{definition or redeclaration of 'foo' not in a namespace enclosing 'PR6645'}}
+  }
+}
diff --git a/test/SemaCXX/qualification-conversion.cpp b/test/SemaCXX/qualification-conversion.cpp
new file mode 100644
index 0000000..f1af5bf
--- /dev/null
+++ b/test/SemaCXX/qualification-conversion.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -fsyntax-only -pedantic -verify %s 
+int* quals1(int const * p);
+int* quals2(int const * const * pp);
+int* quals3(int const * * const * ppp); // expected-note{{candidate function}}
+
+void test_quals(int * p, int * * pp, int * * * ppp) {
+  int const * const * pp2 = pp; 
+  quals1(p);
+  quals2(pp);
+  quals3(ppp); // expected-error {{no matching}}
+}
+
+struct A {};
+void mquals1(int const A::*p);
+void mquals2(int const A::* const A::*pp);
+void mquals3(int const A::* A::* const A::*ppp);  // expected-note{{candidate function}}
+
+void test_mquals(int A::*p, int A::* A::*pp, int A::* A::* A::*ppp) {
+  int const A::* const A::* pp2 = pp;
+  mquals1(p);
+  mquals2(pp);
+  mquals3(ppp); // expected-error {{no matching}}
+}
+
+void aquals1(int const (*p)[1]);
+void aquals2(int * const (*pp)[1]);
+void aquals2a(int const * (*pp2)[1]); // expected-note{{candidate function}}
+
+void test_aquals(int (*p)[1], int * (*pp)[1], int * (*pp2)[1]) {
+  int const (*p2)[1] = p;
+  aquals1(p);
+  aquals2(pp);
+  aquals2a(pp2); // expected-error {{no matching}}
+}
diff --git a/test/SemaCXX/qualified-id-lookup.cpp b/test/SemaCXX/qualified-id-lookup.cpp
new file mode 100644
index 0000000..dfb059a
--- /dev/null
+++ b/test/SemaCXX/qualified-id-lookup.cpp
@@ -0,0 +1,148 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s 
+namespace Ns {
+  int f(); // expected-note{{previous declaration is here}}
+
+  enum E {
+    Enumerator
+  };
+}
+namespace Ns {
+  double f(); // expected-error{{functions that differ only in their return type cannot be overloaded}}
+
+  int x = Enumerator;
+}
+
+namespace Ns2 {
+  float f();
+}
+
+int y = Ns::Enumerator;
+
+namespace Ns2 {
+  float f(int); // expected-note{{previous declaration is here}}
+}
+
+namespace Ns2 {
+  double f(int); // expected-error{{functions that differ only in their return type cannot be overloaded}}
+}
+
+namespace N {
+  int& f1();
+}
+
+namespace N {
+  struct f1 {
+    static int member;
+
+    typedef int type;
+
+    void foo(type);
+  };
+
+  void test_f1() {
+    int &i1 = f1();
+  }
+}
+
+void N::f1::foo(int i) { 
+  f1::member = i; 
+  f1::type &ir = i;
+}
+
+namespace N {
+  float& f1(int x) {
+    N::f1::type& i1 = x;
+    f1::type& i2 = x;
+  }
+
+  struct f2 {
+    static int member;
+  };
+  void f2();
+}
+
+int i1 = N::f1::member;
+typedef struct N::f1 type1;
+int i2 = N::f2::member;
+typedef struct N::f2 type2;
+
+void test_f1(int i) {
+  int &v1 = N::f1();
+  float &v2 = N::f1(i);
+  int v3 = ::i1;
+  int v4 = N::f1::member;
+}
+
+typedef int f2_type;
+namespace a {
+  typedef int f2_type(int, int);
+
+  void test_f2() {
+    ::f2_type(1, 2); // expected-error {{function-style cast to a builtin type can only take one argument}}
+  }
+}
+
+// PR clang/3291
+namespace a {  
+  namespace a {   // A1
+    namespace a { // A2
+      int i;
+    }
+  }
+}
+
+void test_a() {
+  a::a::i = 3; // expected-error{{no member named 'i'}}
+  a::a::a::i = 4;
+}
+  
+struct Undef { // expected-note{{definition of 'Undef' is not complete until the closing '}'}}
+  typedef int type;
+
+  Undef::type member;
+
+  static int size = sizeof(Undef); // expected-error{{invalid application of 'sizeof' to an incomplete type 'Undef'}}
+
+  int f();
+};
+
+int Undef::f() {
+  return sizeof(Undef);
+}
+
+// PR clang/5667
+namespace test1 {
+  template <typename T> struct is_class {
+    enum { value = 0 };
+  };
+
+  template <typename T> class ClassChecker {
+    bool isClass() {
+      return is_class<T>::value;
+    }
+  };
+
+  template class ClassChecker<int>;  
+}
+
+namespace PR6830 {
+  namespace foo {
+
+    class X {
+    public:
+      X() {}
+    };
+
+  }  // namespace foo
+
+  class Z {
+  public:
+    explicit Z(const foo::X& x) {}
+
+    void Work() {}
+  };
+
+  void Test() {
+    Z(foo::X()).Work();
+  }
+}
diff --git a/test/SemaCXX/qualified-names-diag.cpp b/test/SemaCXX/qualified-names-diag.cpp
new file mode 100644
index 0000000..c8b5746
--- /dev/null
+++ b/test/SemaCXX/qualified-names-diag.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+namespace foo {
+  namespace wibble {
+    struct x { int y; };
+
+    namespace bar {
+      namespace wonka {
+        struct x {
+          struct y { };
+        };
+      }
+    }
+  }
+}
+
+namespace bar {
+  typedef int y;
+
+  struct incomplete; // expected-note{{forward declaration of 'bar::incomplete'}}
+}
+void test() {
+  foo::wibble::x a;
+  ::bar::y b;
+  a + b; // expected-error{{invalid operands to binary expression ('foo::wibble::x' and '::bar::y' (aka 'int'))}}
+
+  ::foo::wibble::bar::wonka::x::y c;
+  c + b; // expected-error{{invalid operands to binary expression ('::foo::wibble::bar::wonka::x::y' and '::bar::y' (aka 'int'))}}
+
+  (void)sizeof(bar::incomplete); // expected-error{{invalid application of 'sizeof' to an incomplete type 'bar::incomplete'}}
+}
+
+int ::foo::wibble::bar::wonka::x::y::* ptrmem;
+
diff --git a/test/SemaCXX/qualified-names-print.cpp b/test/SemaCXX/qualified-names-print.cpp
new file mode 100644
index 0000000..2099268
--- /dev/null
+++ b/test/SemaCXX/qualified-names-print.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -ast-print %s 2>&1 | grep "N::M::X<INT>::value"
+namespace N {
+  namespace M {
+    template<typename T>
+    struct X {
+      enum { value };
+    };
+  }
+}
+
+typedef int INT;
+
+int test() {
+  return N::M::X<INT>::value;
+}
diff --git a/test/SemaCXX/ref-init-ambiguous.cpp b/test/SemaCXX/ref-init-ambiguous.cpp
new file mode 100644
index 0000000..a8e95a3
--- /dev/null
+++ b/test/SemaCXX/ref-init-ambiguous.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
+
+enum E2 { };
+
+struct A { 
+  operator E2&(); // expected-note 3 {{candidate function}}
+};
+
+struct B { 
+  operator E2&(); // expected-note 3 {{candidate function}}
+};
+
+struct C : B, A { 
+};
+
+void test(C c) {
+  const E2 &e2 = c; // expected-error {{reference initialization of type 'E2 const &' with initializer of type 'C' is ambiguous}}
+}
+
+void foo(const E2 &);// expected-note{{passing argument to parameter here}}
+
+const E2 & re(C c) {
+    foo(c); // expected-error {{reference initialization of type 'E2 const &' with initializer of type 'C' is ambiguous}}
+
+    return c; // expected-error {{reference initialization of type 'E2 const &' with initializer of type 'C' is ambiguous}}
+}
+
+
diff --git a/test/SemaCXX/references.cpp b/test/SemaCXX/references.cpp
new file mode 100644
index 0000000..e40ea01
--- /dev/null
+++ b/test/SemaCXX/references.cpp
@@ -0,0 +1,117 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+int g(int);
+
+void f() {
+  int i;
+  int &r = i;
+  r = 1;
+  int *p = &r;
+  int &rr = r;
+  int (&rg)(int) = g;
+  rg(i);
+  int a[3];
+  int (&ra)[3] = a;
+  ra[1] = i;
+  int *Q;
+  int *& P = Q;
+  P[1] = 1;
+}
+
+typedef int t[1];
+void test2() {
+    t a;
+    t& b = a;
+
+
+    int c[3];
+    int (&rc)[3] = c;
+}
+
+// C++ [dcl.init.ref]p5b1
+struct A { };
+struct B : A { } b;
+
+void test3() {
+  double d = 2.0;
+  double& rd = d; // rd refers to d
+  const double& rcd = d; // rcd refers to d
+
+  A& ra = b; // ra refers to A subobject in b
+  const A& rca = b; // rca refers to A subobject in b
+}
+
+B fB();
+
+// C++ [dcl.init.ref]p5b2
+void test4() {
+  double& rd2 = 2.0; // expected-error{{non-const lvalue reference to type 'double' cannot bind to a temporary of type 'double'}}
+  int i = 2;
+  double& rd3 = i; // expected-error{{non-const lvalue reference to type 'double' cannot bind to a value of unrelated type 'int'}}
+
+  const A& rca = fB();
+}
+
+void test5() {
+  //  const double& rcd2 = 2; // rcd2 refers to temporary with value 2.0
+  const volatile int cvi = 1;
+  const int& r = cvi; // expected-error{{binding of reference to type 'int const' to a value of type 'int const volatile' drops qualifiers}}
+}
+
+// C++ [dcl.init.ref]p3
+int& test6(int& x) {
+  int& yo; // expected-error{{declaration of reference variable 'yo' requires an initializer}}
+
+  return x;
+}
+int& not_initialized_error; // expected-error{{declaration of reference variable 'not_initialized_error' requires an initializer}}
+extern int& not_initialized_okay;
+
+class Test6 { // expected-warning{{class 'Test6' does not declare any constructor to initialize its non-modifiable members}}
+  int& okay; // expected-note{{reference member 'okay' will never be initialized}}
+};
+
+struct C : B, A { };
+
+void test7(C& c) {
+  A& a1 = c; // expected-error {{ambiguous conversion from derived class 'C' to base class 'A':}}
+}
+
+// C++ [dcl.ref]p1, C++ [dcl.ref]p4
+void test8(int& const,// expected-error{{'const' qualifier may not be applied to a reference}}
+           
+           void&,     // expected-error{{cannot form a reference to 'void'}}
+           int& &)    // expected-error{{type name declared as a reference to a reference}}
+{
+  typedef int& intref;
+  typedef intref& intrefref; // C++ DR 106: reference collapsing
+
+  typedef intref const intref_c; // okay. FIXME: how do we verify that this is the same type as intref?
+}
+
+
+class string {
+  char *Data;
+  unsigned Length;
+public:
+  string(); 
+  ~string();
+};
+
+string getInput();
+
+void test9() {
+  string &s = getInput(); // expected-error{{lvalue reference}}
+}
+
+void test10() {
+  __attribute((vector_size(16))) typedef int vec4;
+  typedef __attribute__(( ext_vector_type(4) )) int ext_vec4;
+  
+  vec4 v;
+  int &a = v[0]; // expected-error{{non-const reference cannot bind to vector element}}
+  const int &b = v[0];
+  
+  ext_vec4 ev;
+  int &c = ev.x; // expected-error{{non-const reference cannot bind to vector element}}
+  const int &d = ev.x;
+}
diff --git a/test/SemaCXX/reinterpret-cast.cpp b/test/SemaCXX/reinterpret-cast.cpp
new file mode 100644
index 0000000..45d41e8
--- /dev/null
+++ b/test/SemaCXX/reinterpret-cast.cpp
@@ -0,0 +1,98 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+#include <stdint.h>
+
+enum test { testval = 1 };
+struct structure { int m; };
+typedef void (*fnptr)();
+
+// Test the conversion to self.
+void self_conversion()
+{
+  // T*->T* is allowed, T->T in general not.
+  int i = 0;
+  (void)reinterpret_cast<int>(i); // expected-error {{reinterpret_cast from 'int' to 'int' is not allowed}}
+  structure s;
+  (void)reinterpret_cast<structure>(s); // expected-error {{reinterpret_cast from 'structure' to 'structure' is not allowed}}
+  int *pi = 0;
+  (void)reinterpret_cast<int*>(pi);
+}
+
+// Test conversion between pointer and integral types, as in /3 and /4.
+void integral_conversion()
+{
+  void *vp = reinterpret_cast<void*>(testval);
+  intptr_t i = reinterpret_cast<intptr_t>(vp);
+  (void)reinterpret_cast<float*>(i);
+  fnptr fnp = reinterpret_cast<fnptr>(i);
+  (void)reinterpret_cast<char>(fnp); // expected-error {{cast from pointer to smaller type 'char' loses information}}
+  (void)reinterpret_cast<intptr_t>(fnp);
+}
+
+void pointer_conversion()
+{
+  int *p1 = 0;
+  float *p2 = reinterpret_cast<float*>(p1);
+  structure *p3 = reinterpret_cast<structure*>(p2);
+  typedef int **ppint;
+  ppint *deep = reinterpret_cast<ppint*>(p3);
+  (void)reinterpret_cast<fnptr*>(deep);
+}
+
+void constness()
+{
+  int ***const ipppc = 0;
+  // Valid: T1* -> T2 const*
+  int const *icp = reinterpret_cast<int const*>(ipppc);
+  // Invalid: T1 const* -> T2*
+  (void)reinterpret_cast<int*>(icp); // expected-error {{reinterpret_cast from 'int const *' to 'int *' casts away constness}}
+  // Invalid: T1*** -> T2 const* const**
+  int const *const **icpcpp = reinterpret_cast<int const* const**>(ipppc); // expected-error {{reinterpret_cast from 'int ***' to 'int const *const **' casts away constness}}
+  // Valid: T1* -> T2*
+  int *ip = reinterpret_cast<int*>(icpcpp);
+  // Valid: T* -> T const*
+  (void)reinterpret_cast<int const*>(ip);
+  // Valid: T*** -> T2 const* const* const*
+  (void)reinterpret_cast<int const* const* const*>(ipppc);
+}
+
+void fnptrs()
+{
+  typedef int (*fnptr2)(int);
+  fnptr fp = 0;
+  (void)reinterpret_cast<fnptr2>(fp);
+  void *vp = reinterpret_cast<void*>(fp);
+  (void)reinterpret_cast<fnptr>(vp);
+}
+
+void refs()
+{
+  long l = 0;
+  char &c = reinterpret_cast<char&>(l);
+  // Bad: from rvalue
+  (void)reinterpret_cast<int&>(&c); // expected-error {{reinterpret_cast from rvalue to reference type 'int &'}}
+}
+
+void memptrs()
+{
+  const int structure::*psi = 0;
+  (void)reinterpret_cast<const float structure::*>(psi);
+  (void)reinterpret_cast<int structure::*>(psi); // expected-error {{reinterpret_cast from 'int const structure::*' to 'int structure::*' casts away constness}}
+
+  void (structure::*psf)() = 0;
+  (void)reinterpret_cast<int (structure::*)()>(psf);
+
+  (void)reinterpret_cast<void (structure::*)()>(psi); // expected-error {{reinterpret_cast from 'int const structure::*' to 'void (structure::*)()' is not allowed}}
+  (void)reinterpret_cast<int structure::*>(psf); // expected-error {{reinterpret_cast from 'void (structure::*)()' to 'int structure::*' is not allowed}}
+
+  // Cannot cast from integers to member pointers, not even the null pointer
+  // literal.
+  (void)reinterpret_cast<void (structure::*)()>(0); // expected-error {{reinterpret_cast from 'int' to 'void (structure::*)()' is not allowed}}
+  (void)reinterpret_cast<int structure::*>(0); // expected-error {{reinterpret_cast from 'int' to 'int structure::*' is not allowed}}
+}
+
+// PR5545
+class A;
+class B;
+void (A::*a)();
+void (B::*b)() = reinterpret_cast<void (B::*)()>(a);
diff --git a/test/SemaCXX/reinterpret-fn-obj-pedantic.cpp b/test/SemaCXX/reinterpret-fn-obj-pedantic.cpp
new file mode 100644
index 0000000..09d08f9
--- /dev/null
+++ b/test/SemaCXX/reinterpret-fn-obj-pedantic.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 -pedantic %s
+
+void fnptrs()
+{
+  typedef void (*fnptr)();
+  fnptr fp = 0;
+  void *vp = reinterpret_cast<void*>(fp); // expected-warning {{reinterpret_cast between pointer-to-function and pointer-to-object is an extension}}
+  (void)reinterpret_cast<fnptr>(vp); // expected-warning {{reinterpret_cast between pointer-to-function and pointer-to-object is an extension}}
+}
diff --git a/test/SemaCXX/return-stack-addr.cpp b/test/SemaCXX/return-stack-addr.cpp
new file mode 100644
index 0000000..ba64765
--- /dev/null
+++ b/test/SemaCXX/return-stack-addr.cpp
@@ -0,0 +1,112 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+int* ret_local() {
+  int x = 1;
+  return &x; // expected-warning {{address of stack memory}}
+}
+
+int* ret_local_array() {
+  int x[10];
+  return x; // expected-warning {{address of stack memory}}
+}
+
+int* ret_local_array_element(int i) {
+  int x[10];
+  return &x[i]; // expected-warning {{address of stack memory}}
+}
+
+int *ret_local_array_element_reversed(int i) {
+  int x[10];
+  return &i[x]; // expected-warning {{address of stack memory}}
+}
+
+int* ret_local_array_element_const_index() {
+  int x[10];
+  return &x[2];  // expected-warning {{address of stack memory}}
+}
+
+int& ret_local_ref() {
+  int x = 1;
+  return x;  // expected-warning {{reference to stack memory}}
+}
+
+int* ret_local_addrOf() {
+  int x = 1;
+  return &*&x; // expected-warning {{address of stack memory}}
+}
+
+int* ret_local_addrOf_paren() {
+  int x = 1;
+  return (&(*(&x))); // expected-warning {{address of stack memory}}
+}
+
+int* ret_local_addrOf_ptr_arith() {
+  int x = 1;
+  return &*(&x+1); // expected-warning {{address of stack memory}}
+}
+
+int* ret_local_addrOf_ptr_arith2() {
+  int x = 1;
+  return &*(&x+1); // expected-warning {{address of stack memory}}
+}
+
+int* ret_local_field() {
+  struct { int x; } a;
+  return &a.x; // expected-warning {{address of stack memory}}
+}
+
+int& ret_local_field_ref() {
+  struct { int x; } a;
+  return a.x; // expected-warning {{reference to stack memory}}
+}
+
+int* ret_conditional(bool cond) {
+  int x = 1;
+  int y = 2;
+  return cond ? &x : &y; // expected-warning {{address of stack memory}}
+}
+
+int* ret_conditional_rhs(int *x, bool cond) {
+  int y = 1;
+  return cond ? x : &y;  // expected-warning {{address of stack memory}}
+}
+
+void* ret_c_cast() {
+  int x = 1;
+  return (void*) &x;  // expected-warning {{address of stack memory}}
+}
+
+int* ret_static_var() {
+  static int x = 1;
+  return &x;  // no warning.
+}
+
+int z = 1;
+
+int* ret_global() {
+  return &z;  // no warning.
+}
+
+int* ret_parameter(int x) {
+  return &x;  // expected-warning {{address of stack memory}}
+}
+
+
+void* ret_cpp_static_cast(short x) {
+  return static_cast<void*>(&x); // expected-warning {{address of stack memory}}
+}
+
+int* ret_cpp_reinterpret_cast(double x) {
+  return reinterpret_cast<int*>(&x); // expected-warning {{address of stack me}}
+}
+
+int* ret_cpp_reinterpret_cast_no_warning(long x) {
+  return reinterpret_cast<int*>(x); // no-warning
+}
+
+int* ret_cpp_const_cast(const int x) {
+  return const_cast<int*>(&x);  // expected-warning {{address of stack memory}}
+}
+
+// TODO: test case for dynamic_cast.  clang does not yet have
+// support for C++ classes to write such a test case.
diff --git a/test/SemaCXX/return.cpp b/test/SemaCXX/return.cpp
new file mode 100644
index 0000000..e682fdf
--- /dev/null
+++ b/test/SemaCXX/return.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify
+
+int test1() {
+  throw;
+}
+
+// PR5071
+template<typename T> T f() { }
+
+template<typename T>
+void g(T t) {
+  return t * 2; // okay
+}
+
+template<typename T>
+T h() {
+  return 17;
+}
diff --git a/test/SemaCXX/rval-references-xfail.cpp b/test/SemaCXX/rval-references-xfail.cpp
new file mode 100644
index 0000000..d41f8f1
--- /dev/null
+++ b/test/SemaCXX/rval-references-xfail.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s
+// XFAIL: *
+struct MoveOnly {
+  MoveOnly();
+  MoveOnly(const MoveOnly&) = delete;	// expected-note {{candidate function}} \
+  // expected-note 3{{explicitly marked deleted here}}
+  MoveOnly(MoveOnly&&);	// expected-note {{candidate function}}
+  MoveOnly(int&&);	// expected-note {{candidate function}}
+};
+
+MoveOnly returning() {
+  MoveOnly mo;
+  return mo;
+}
diff --git a/test/SemaCXX/rval-references.cpp b/test/SemaCXX/rval-references.cpp
new file mode 100644
index 0000000..d5b465f
--- /dev/null
+++ b/test/SemaCXX/rval-references.cpp
@@ -0,0 +1,87 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s
+
+typedef int&& irr;
+typedef irr& ilr_c1; // Collapses to int&
+typedef int& ilr;
+typedef ilr&& ilr_c2; // Collapses to int&
+
+irr ret_irr() {
+  return 0;
+}
+
+struct not_int {};
+
+int over(int&);
+not_int over(int&&);
+
+int over2(const int&);
+not_int over2(int&&);
+
+struct conv_to_not_int_rvalue {
+  operator not_int &&();
+};
+
+void f() {
+  int &&virr1; // expected-error {{declaration of reference variable 'virr1' requires an initializer}}
+  int &&virr2 = 0;
+  int &&virr3 = virr2; // expected-error {{rvalue reference cannot bind to lvalue}}
+  int i1 = 0;
+  int &&virr4 = i1; // expected-error {{rvalue reference cannot bind to lvalue}}
+  int &&virr5 = ret_irr();
+  int &&virr6 = static_cast<int&&>(i1);
+  (void)static_cast<not_int&&>(i1); // expected-error {{types are not compatible}}
+
+  int i2 = over(i1);
+  not_int ni1 = over(0);
+  int i3 = over(virr2);
+  not_int ni2 = over(ret_irr());
+
+  int i4 = over2(i1);
+  not_int ni3 = over2(0);
+
+  ilr_c1 vilr1 = i1;
+  ilr_c2 vilr2 = i1;
+
+  conv_to_not_int_rvalue cnir;
+  not_int &&ni4 = cnir; // expected-error {{rvalue reference cannot bind to lvalue}}
+  not_int &ni5 = cnir; // expected-error{{non-const lvalue reference to type 'not_int' cannot bind to a value of unrelated type 'conv_to_not_int_rvalue'}}
+  not_int &&ni6 = conv_to_not_int_rvalue();
+
+
+  try {
+  } catch(int&&) { // expected-error {{cannot catch exceptions by rvalue reference}}
+  }
+}
+
+int&& should_warn(int i) {
+  // FIXME: The stack address return test doesn't reason about casts.
+  return static_cast<int&&>(i); // xpected-warning {{returning reference to temporary}}
+}
+int&& should_not_warn(int&& i) { // But GCC 4.4 does
+  return static_cast<int&&>(i);
+}
+
+
+// Test the return dance. This also tests IsReturnCopyElidable.
+struct MoveOnly {
+  MoveOnly();
+  MoveOnly(const MoveOnly&) = delete;	// expected-note {{candidate constructor}} \
+  // expected-note 3{{explicitly marked deleted here}}
+  MoveOnly(MoveOnly&&);	// expected-note {{candidate constructor}}
+  MoveOnly(int&&);	// expected-note {{candidate constructor}}
+};
+
+MoveOnly gmo;
+MoveOnly returningNonEligible() {
+  int i;
+  static MoveOnly mo;
+  MoveOnly &r = mo;
+  if (0) // Copy from global can't be elided
+    return gmo; // expected-error {{call to deleted constructor}}
+  else if (0) // Copy from local static can't be elided
+    return mo; // expected-error {{call to deleted constructor}}
+  else if (0) // Copy from reference can't be elided
+    return r; // expected-error {{call to deleted constructor}}
+  else // Construction from different type can't be elided
+    return i; // expected-error {{no viable conversion from 'int' to 'MoveOnly'}}
+}
diff --git a/test/SemaCXX/statements.cpp b/test/SemaCXX/statements.cpp
new file mode 100644
index 0000000..0e27f46
--- /dev/null
+++ b/test/SemaCXX/statements.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 %s -fsyntax-only -pedantic -verify
+
+void foo() { 
+  return foo();
+}
+
+// PR6451 - C++ Jump checking
+struct X {
+  X();
+};
+
+void test2() {
+  goto later;  // expected-error {{illegal goto into protected scope}}
+  X x;         // expected-note {{jump bypasses variable initialization}} 
+later:
+  ;
+}
+
+namespace PR6536 {
+  struct A {};
+  void a() { goto out; A x; out: return; }
+}
diff --git a/test/SemaCXX/static-array-member.cpp b/test/SemaCXX/static-array-member.cpp
new file mode 100644
index 0000000..8f57549
--- /dev/null
+++ b/test/SemaCXX/static-array-member.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -fsyntax-only %s
+
+struct X0 {
+  static int array[];
+  
+  int x;
+  int y;
+};
+
+int X0::array[sizeof(X0) * 2];
+
+template<typename T, int N>
+struct X1 {
+  static T array[];
+};
+
+template<typename T, int N>
+T X1<T, N>::array[N];
diff --git a/test/SemaCXX/static-assert.cpp b/test/SemaCXX/static-assert.cpp
new file mode 100644
index 0000000..516243e
--- /dev/null
+++ b/test/SemaCXX/static-assert.cpp
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
+
+int f();
+
+static_assert(f(), "f"); // expected-error {{static_assert expression is not an integral constant expression}}
+static_assert(true, "true is not false");
+static_assert(false, "false is false"); // expected-error {{static_assert failed "false is false"}}
+
+void g() {
+    static_assert(false, "false is false"); // expected-error {{static_assert failed "false is false"}}
+}
+
+class C {
+    static_assert(false, "false is false"); // expected-error {{static_assert failed "false is false"}}
+};
+
+template<int N> struct T {
+    static_assert(N == 2, "N is not 2!"); // expected-error {{static_assert failed "N is not 2!"}}
+};
+
+T<1> t1; // expected-note {{in instantiation of template class 'T<1>' requested here}}
+T<2> t2;
+
+template<typename T> struct S {
+    static_assert(sizeof(T) > sizeof(char), "Type not big enough!"); // expected-error {{static_assert failed "Type not big enough!"}}
+};
+
+S<char> s1; // expected-note {{in instantiation of template class 'S<char>' requested here}}
+S<int> s2;
+
diff --git a/test/SemaCXX/static-cast-complete-type.cpp b/test/SemaCXX/static-cast-complete-type.cpp
new file mode 100644
index 0000000..6d76f81
--- /dev/null
+++ b/test/SemaCXX/static-cast-complete-type.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename T> struct S {
+  S(int);
+};
+
+struct T; // expected-note{{forward declaration of 'T'}}
+
+void f() {
+  S<int> s0 = static_cast<S<int> >(0);
+  S<void*> s1 = static_cast<S<void*> >(00);
+
+  (void)static_cast<T>(10); // expected-error{{'T' is an incomplete type}}
+}
diff --git a/test/SemaCXX/static-cast.cpp b/test/SemaCXX/static-cast.cpp
new file mode 100644
index 0000000..48f641a
--- /dev/null
+++ b/test/SemaCXX/static-cast.cpp
@@ -0,0 +1,197 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+struct A {};
+struct B : public A {};             // Single public base.
+struct C1 : public virtual B {};    // Single virtual base.
+struct C2 : public virtual B {};
+struct D : public C1, public C2 {}; // Diamond
+struct E : private A {};            // Single private base. expected-note 3 {{declared private here}}
+struct F : public C1 {};            // Single path to B with virtual.
+struct G1 : public B {};
+struct G2 : public B {};
+struct H : public G1, public G2 {}; // Ambiguous path to B.
+
+enum Enum { En1, En2 };
+enum Onom { On1, On2 };
+
+struct Co1 { operator int(); };
+struct Co2 { Co2(int); };
+struct Co3 { };
+struct Co4 { Co4(Co3); operator Co3(); };
+
+// Explicit implicits
+void t_529_2()
+{
+  int i = 1;
+  (void)static_cast<float>(i);
+  double d = 1.0;
+  (void)static_cast<float>(d);
+  (void)static_cast<int>(d);
+  (void)static_cast<char>(i);
+  (void)static_cast<unsigned long>(i);
+  (void)static_cast<int>(En1);
+  (void)static_cast<double>(En1);
+  (void)static_cast<int&>(i);
+  (void)static_cast<const int&>(i);
+
+  int ar[1];
+  (void)static_cast<const int*>(ar);
+  (void)static_cast<void (*)()>(t_529_2);
+
+  (void)static_cast<void*>(0);
+  (void)static_cast<void*>((int*)0);
+  (void)static_cast<volatile const void*>((const int*)0);
+  (void)static_cast<A*>((B*)0);
+  (void)static_cast<A&>(*((B*)0));
+  (void)static_cast<const B*>((C1*)0);
+  (void)static_cast<B&>(*((C1*)0));
+  (void)static_cast<A*>((D*)0);
+  (void)static_cast<const A&>(*((D*)0));
+  (void)static_cast<int B::*>((int A::*)0);
+  (void)static_cast<void (B::*)()>((void (A::*)())0);
+
+  (void)static_cast<int>(Co1());
+  (void)static_cast<Co2>(1);
+  (void)static_cast<Co3>(static_cast<Co4>(Co3()));
+
+  // Bad code below
+
+  (void)static_cast<void*>((const int*)0); // expected-error {{static_cast from 'int const *' to 'void *' is not allowed}}
+  (void)static_cast<A*>((E*)0); // expected-error {{cannot cast 'E' to its private base class 'A'}}
+  (void)static_cast<A*>((H*)0); // expected-error {{ambiguous conversion}}
+  (void)static_cast<int>((int*)0); // expected-error {{static_cast from 'int *' to 'int' is not allowed}}
+  (void)static_cast<A**>((B**)0); // expected-error {{static_cast from 'B **' to 'A **' is not allowed}}
+  (void)static_cast<char&>(i); // expected-error {{non-const lvalue reference to type 'char' cannot bind to a value of unrelated type 'int'}}
+}
+
+// Anything to void
+void t_529_4()
+{
+  static_cast<void>(1);
+  static_cast<void>(t_529_4);
+}
+
+// Static downcasts
+void t_529_5_8()
+{
+  (void)static_cast<B*>((A*)0);
+  (void)static_cast<B&>(*((A*)0));
+  (void)static_cast<const G1*>((A*)0);
+  (void)static_cast<const G1&>(*((A*)0));
+
+  // Bad code below
+
+  (void)static_cast<C1*>((A*)0); // expected-error {{cannot cast 'A *' to 'C1 *' via virtual base 'B'}}
+  (void)static_cast<C1&>(*((A*)0)); // expected-error {{cannot cast 'A' to 'C1 &' via virtual base 'B'}}
+  (void)static_cast<D*>((A*)0); // expected-error {{cannot cast 'A *' to 'D *' via virtual base 'B'}}
+  (void)static_cast<D&>(*((A*)0)); // expected-error {{cannot cast 'A' to 'D &' via virtual base 'B'}}
+  (void)static_cast<B*>((const A*)0); // expected-error {{static_cast from 'A const *' to 'B *' casts away constness}}
+  (void)static_cast<B&>(*((const A*)0)); // expected-error {{static_cast from 'A const' to 'B &' casts away constness}}
+  (void)static_cast<E*>((A*)0); // expected-error {{cannot cast private base class 'A' to 'E'}}
+  (void)static_cast<E&>(*((A*)0)); // expected-error {{cannot cast private base class 'A' to 'E'}}
+  (void)static_cast<H*>((A*)0); // expected-error {{ambiguous cast from base 'A' to derived 'H':\n    struct A -> struct B -> struct G1 -> struct H\n    struct A -> struct B -> struct G2 -> struct H}}
+  (void)static_cast<H&>(*((A*)0)); // expected-error {{ambiguous cast from base 'A' to derived 'H':\n    struct A -> struct B -> struct G1 -> struct H\n    struct A -> struct B -> struct G2 -> struct H}}
+  (void)static_cast<E*>((B*)0); // expected-error {{static_cast from 'B *' to 'E *' is not allowed}}
+  (void)static_cast<E&>(*((B*)0)); // expected-error {{non-const lvalue reference to type 'E' cannot bind to a value of unrelated type 'B'}}
+
+  // TODO: Test inaccessible base in context where it's accessible, i.e.
+  // member function and friend.
+
+  // TODO: Test DR427. This requires user-defined conversions, though.
+}
+
+// Enum conversions
+void t_529_7()
+{
+  (void)static_cast<Enum>(1);
+  (void)static_cast<Enum>(1.0);
+  (void)static_cast<Onom>(En1);
+
+  // Bad code below
+
+  (void)static_cast<Enum>((int*)0); // expected-error {{static_cast from 'int *' to 'Enum' is not allowed}}
+}
+
+// Void pointer to object pointer
+void t_529_10()
+{
+  (void)static_cast<int*>((void*)0);
+  (void)static_cast<const A*>((void*)0);
+
+  // Bad code below
+
+  (void)static_cast<int*>((const void*)0); // expected-error {{static_cast from 'void const *' to 'int *' casts away constness}}
+  (void)static_cast<void (*)()>((void*)0); // expected-error {{static_cast from 'void *' to 'void (*)()' is not allowed}}
+}
+
+// Member pointer upcast.
+void t_529_9()
+{
+  (void)static_cast<int A::*>((int B::*)0);
+
+  // Bad code below
+  (void)static_cast<int A::*>((int H::*)0); // expected-error {{ambiguous conversion from pointer to member of derived class 'H' to pointer to member of base class 'A':}}
+  (void)static_cast<int A::*>((int F::*)0); // expected-error {{conversion from pointer to member of class 'F' to pointer to member of class 'A' via virtual base 'B' is not allowed}}
+}
+
+// PR 5261 - static_cast should instantiate template if possible
+namespace pr5261 {
+  struct base {};
+  template<typename E> struct derived : public base {};
+  template<typename E> struct outer {
+    base *pb;
+    ~outer() { (void)static_cast<derived<E>*>(pb); }
+  };
+  outer<int> EntryList;
+}
+
+
+// Initialization by constructor
+struct X0;
+
+struct X1 {
+  X1();
+  X1(X1&);
+  X1(const X0&);
+  
+  operator X0() const;
+};
+
+struct X0 { };
+
+void test_ctor_init() {
+  (void)static_cast<X1>(X1());
+}
+
+// Casting away constness
+struct X2 {
+};
+
+struct X3 : X2 {
+};
+
+struct X4 {
+  typedef const X3 X3_typedef;
+  
+  void f() const {
+    (void)static_cast<X3_typedef*>(x2);
+  }
+  
+  const X2 *x2;
+};
+
+// PR5897 - accept static_cast from const void* to const int (*)[1].
+void PR5897() { (void)static_cast<const int(*)[1]>((const void*)0); }
+
+namespace PR6072 {
+  struct A { }; 
+  struct B : A { void f(int); void f(); }; 
+  struct C : B { };
+  struct D { };
+
+  void f() {
+    (void)static_cast<void (A::*)()>(&B::f);
+    (void)static_cast<void (B::*)()>(&B::f);
+    (void)static_cast<void (C::*)()>(&B::f);
+    (void)static_cast<void (D::*)()>(&B::f); // expected-error{{static_cast from '<overloaded function type>' to 'void (PR6072::D::*)()' is not allowed}}
+  }
+}
diff --git a/test/SemaCXX/static-initializers.cpp b/test/SemaCXX/static-initializers.cpp
new file mode 100644
index 0000000..ca49fce
--- /dev/null
+++ b/test/SemaCXX/static-initializers.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s 
+int f() {
+  return 10;
+}
+
+void g() {
+  static int a = f();
+}
+
+static int b = f();
diff --git a/test/SemaCXX/storage-class.cpp b/test/SemaCXX/storage-class.cpp
new file mode 100644
index 0000000..a2e2063
--- /dev/null
+++ b/test/SemaCXX/storage-class.cpp
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+extern const int PR6495a = 42;
+extern int PR6495b = 42; // expected-warning{{'extern' variable has an initializer}}
+extern const int PR6495c[] = {42,43,44};
diff --git a/test/SemaCXX/struct-class-redecl.cpp b/test/SemaCXX/struct-class-redecl.cpp
new file mode 100644
index 0000000..d3d6d79
--- /dev/null
+++ b/test/SemaCXX/struct-class-redecl.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only -Wmismatched-tags -verify %s
+class X; // expected-note 2{{here}}
+typedef struct X * X_t; // expected-warning{{previously declared}}
+
+template<typename T> struct Y; // expected-note{{previous}}
+template<class U> class Y { }; // expected-warning{{previously declared}}
+
+union X { int x; float y; }; // expected-error{{use of 'X' with tag type that does not match previous declaration}}
diff --git a/test/SemaCXX/switch-0x.cpp b/test/SemaCXX/switch-0x.cpp
new file mode 100644
index 0000000..adaeb85
--- /dev/null
+++ b/test/SemaCXX/switch-0x.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s
+
+// PR5518
+struct A { 
+  explicit operator int(); // expected-note{{conversion to integral type}}
+};
+
+void x() { 
+  switch(A()) { // expected-error{{explicit conversion to}}
+  }
+}
diff --git a/test/SemaCXX/switch.cpp b/test/SemaCXX/switch.cpp
new file mode 100644
index 0000000..c256960
--- /dev/null
+++ b/test/SemaCXX/switch.cpp
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+void test() {
+  bool x = true;
+  switch (x) { // expected-warning {{bool}}
+    case 0:
+      break;
+  }
+
+  int n = 3;
+  switch (n && 1) { // expected-warning {{bool}}
+    case 1:
+      break;
+  }
+}
+
+// PR5518
+struct A { 
+  operator int(); // expected-note{{conversion to integral type}}
+};
+
+void x() { 
+  switch(A()) {
+  }
+}
+
+enum E { e1, e2 };
+struct B : A {
+  operator E() const; // expected-note{{conversion to enumeration type}}
+};
+
+void x2() {
+  switch (B()) { // expected-error{{multiple conversions}}
+  }
+}
+
+struct C; // expected-note{{forward declaration}}
+
+void x3(C &c) {
+  switch (c) { // expected-error{{incomplete class type}}
+  }
+}
diff --git a/test/SemaCXX/templated-friend-decl.cpp b/test/SemaCXX/templated-friend-decl.cpp
new file mode 100644
index 0000000..c0034cd
--- /dev/null
+++ b/test/SemaCXX/templated-friend-decl.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 %s
+
+template <typename T>
+struct Foo {
+  template <typename U>
+  struct Bar {};
+
+  // The templated declaration for class Bar should not be instantiated when
+  // Foo<int> is. This is to protect against PR5848; for now, this "parses" but
+  // requires a rewrite of the templated friend code to be properly fixed.
+  template <typename U>
+  friend struct Bar;
+};
+
+Foo<int> x;
diff --git a/test/SemaCXX/this.cpp b/test/SemaCXX/this.cpp
new file mode 100644
index 0000000..167755f
--- /dev/null
+++ b/test/SemaCXX/this.cpp
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s 
+int x = this; // expected-error {{error: invalid use of 'this' outside of a nonstatic member function}}
+
+void f() {
+  int x = this; // expected-error {{error: invalid use of 'this' outside of a nonstatic member function}}
+}
diff --git a/test/SemaCXX/trivial-constructor.cpp b/test/SemaCXX/trivial-constructor.cpp
new file mode 100644
index 0000000..494d1ec
--- /dev/null
+++ b/test/SemaCXX/trivial-constructor.cpp
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
+struct T1 {
+};
+static_assert(__has_trivial_constructor(T1), "T1 has trivial constructor!");
+
+struct T2 {
+  T2();
+};
+static_assert(!__has_trivial_constructor(T2), "T2 has a user-declared constructor!");
+
+struct T3 {
+  virtual void f();
+};
+static_assert(!__has_trivial_constructor(T3), "T3 has a virtual function!");
+
+struct T4 : virtual T3 {
+};
+static_assert(!__has_trivial_constructor(T4), "T4 has a virtual base class!");
+
+struct T5 : T1 {
+};
+static_assert(__has_trivial_constructor(T5), "All the direct base classes of T5 have trivial constructors!");
+
+struct T6 {
+  T5 t5;
+  T1 t1[2][2];
+  static T2 t2;
+};
+static_assert(__has_trivial_constructor(T6), "All nonstatic data members of T6 have trivial constructors!");
+
+struct T7 {
+  T4 t4;
+};
+static_assert(!__has_trivial_constructor(T7), "t4 does not have a trivial constructor!");
+
+struct T8 : T2 {
+};
+static_assert(!__has_trivial_constructor(T8), "The base class T2 does not have a trivial constructor!");
diff --git a/test/SemaCXX/trivial-destructor.cpp b/test/SemaCXX/trivial-destructor.cpp
new file mode 100644
index 0000000..29358d8
--- /dev/null
+++ b/test/SemaCXX/trivial-destructor.cpp
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
+struct T1 {
+};
+static_assert(__has_trivial_destructor(T1), "T1 has trivial destructor!");
+
+struct T2 {
+  ~T2();
+};
+static_assert(!__has_trivial_destructor(T2), "T2 has a user-declared destructor!");
+
+struct T3 {
+  virtual void f();
+};
+static_assert(__has_trivial_destructor(T3), "T3 has a virtual function (but still a trivial destructor)!");
+
+struct T4 : virtual T3 {
+};
+static_assert(__has_trivial_destructor(T4), "T4 has a virtual base class! (but still a trivial destructor)!");
+
+struct T5 : T1 {
+};
+static_assert(__has_trivial_destructor(T5), "All the direct base classes of T5 have trivial destructors!");
+
+struct T6 {
+  T5 t5;
+  T1 t1[2][2];
+  static T2 t2;
+};
+static_assert(__has_trivial_destructor(T6), "All nonstatic data members of T6 have trivial destructors!");
+
+struct T7 {
+  T2 t2;
+};
+static_assert(!__has_trivial_destructor(T7), "t2 does not have a trivial destructor!");
+
+struct T8 : T2 {
+};
+static_assert(!__has_trivial_destructor(T8), "The base class T2 does not have a trivial destructor!");
diff --git a/test/SemaCXX/type-convert-construct.cpp b/test/SemaCXX/type-convert-construct.cpp
new file mode 100644
index 0000000..8f92a03
--- /dev/null
+++ b/test/SemaCXX/type-convert-construct.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s 
+
+void f() {
+  float v1 = float(1);
+  int v2 = typeof(int)(1,2); // expected-error {{function-style cast to a builtin type can only take one argument}}
+  typedef int arr[];
+  int v3 = arr(); // expected-error {{array types cannot be value-initialized}}
+  int v4 = int();
+  int v5 = int; // expected-error {{expected '(' for function-style cast or type construction}}
+  typedef int T;
+  int *p;
+  bool v6 = T(0) == p;
+  char *str;
+  str = "a string"; // expected-warning{{conversion from string literal to 'char *' is deprecated}}
+  wchar_t *wstr;
+  wstr = L"a wide string"; // expected-warning{{conversion from string literal to 'wchar_t *' is deprecated}}
+}
diff --git a/test/SemaCXX/type-definition-in-specifier.cpp b/test/SemaCXX/type-definition-in-specifier.cpp
new file mode 100644
index 0000000..a614e6c
--- /dev/null
+++ b/test/SemaCXX/type-definition-in-specifier.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct S0;
+struct S1;
+struct S2;
+struct S3;
+struct S4;
+struct S5;
+struct S6;
+
+struct S0 { int x; };
+
+void f0() {
+  typedef struct S1 { int x; } S1_typedef;
+
+  (void)((struct S2 { int x; }*)0); // expected-error{{can not be defined}}
+
+  struct S3 { int x; } s3;
+
+  (void)static_cast<struct S4 { int x; } *>(0); // expected-error{{can not be defined}}
+}
+
+struct S5 { int x; } f1() { return S5(); } // expected-error{{result type}}
+
+void f2(struct S6 { int x; } p); // expected-error{{parameter type}}
diff --git a/test/SemaCXX/type-dependent-exprs.cpp b/test/SemaCXX/type-dependent-exprs.cpp
new file mode 100644
index 0000000..abe1b4d
--- /dev/null
+++ b/test/SemaCXX/type-dependent-exprs.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+class X { 
+public:
+  virtual int f();
+};
+
+void g(int); // expected-note{{candidate function}}
+
+template<typename T>
+T f(T x) {
+  (void)(x + 0);
+  (void)T(0);
+  (void)(x += 0);
+  (void)(x? x : x);
+  (void)static_cast<int>(x);
+  (void)reinterpret_cast<int>(x);
+  (void)dynamic_cast<X*>(&x);
+  (void)const_cast<int>(x);
+  return g(x);
+  h(x); // h is a dependent name
+  g(1, 1); // expected-error{{no matching function for call}}
+  h(1); // expected-error{{use of undeclared identifier 'h'}}
+  return 0;
+}
diff --git a/test/SemaCXX/type-traits-incomplete.cpp b/test/SemaCXX/type-traits-incomplete.cpp
new file mode 100644
index 0000000..f959821
--- /dev/null
+++ b/test/SemaCXX/type-traits-incomplete.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s 
+
+struct S; // expected-note{{forward declaration of 'S'}}
+
+void f() {
+  __is_pod(S); // expected-error{{incomplete type 'S' used in type trait expression}}
+}
diff --git a/test/SemaCXX/type-traits.cpp b/test/SemaCXX/type-traits.cpp
new file mode 100644
index 0000000..85bd596
--- /dev/null
+++ b/test/SemaCXX/type-traits.cpp
@@ -0,0 +1,260 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s 
+#define T(b) (b) ? 1 : -1
+#define F(b) (b) ? -1 : 1
+
+struct NonPOD { NonPOD(int); };
+
+// PODs
+enum Enum { EV };
+struct POD { Enum e; int i; float f; NonPOD* p; };
+struct Empty {};
+typedef Empty EmptyAr[10];
+typedef int Int;
+typedef Int IntAr[10];
+class Statics { static int priv; static NonPOD np; };
+union EmptyUnion {};
+union Union { int i; float f; };
+struct HasFunc { void f (); };
+struct HasOp { void operator *(); };
+struct HasConv { operator int(); };
+struct HasAssign { void operator =(int); };
+
+// Not PODs
+struct Derives : POD {};
+struct DerivesEmpty : Empty {};
+struct HasCons { HasCons(int); };
+struct HasCopyAssign { HasCopyAssign operator =(const HasCopyAssign&); };
+struct HasDest { ~HasDest(); };
+class  HasPriv { int priv; };
+class  HasProt { protected: int prot; };
+struct HasRef { int i; int& ref; HasRef() : i(0), ref(i) {} };
+struct HasNonPOD { NonPOD np; };
+struct HasVirt { virtual void Virt() {}; };
+typedef Derives NonPODAr[10];
+typedef HasVirt VirtAr[10];
+union NonPODUnion { int i; Derives n; };
+
+void is_pod()
+{
+  int t01[T(__is_pod(int))];
+  int t02[T(__is_pod(Enum))];
+  int t03[T(__is_pod(POD))];
+  int t04[T(__is_pod(Int))];
+  int t05[T(__is_pod(IntAr))];
+  int t06[T(__is_pod(Statics))];
+  int t07[T(__is_pod(Empty))];
+  int t08[T(__is_pod(EmptyUnion))];
+  int t09[T(__is_pod(Union))];
+  int t10[T(__is_pod(HasFunc))];
+  int t11[T(__is_pod(HasOp))];
+  int t12[T(__is_pod(HasConv))];
+  int t13[T(__is_pod(HasAssign))];
+
+  int t21[F(__is_pod(Derives))];
+  int t22[F(__is_pod(HasCons))];
+  int t23[F(__is_pod(HasCopyAssign))];
+  int t24[F(__is_pod(HasDest))];
+  int t25[F(__is_pod(HasPriv))];
+  int t26[F(__is_pod(HasProt))];
+  int t27[F(__is_pod(HasRef))];
+  int t28[F(__is_pod(HasNonPOD))];
+  int t29[F(__is_pod(HasVirt))];
+  int t30[F(__is_pod(NonPODAr))];
+  int t31[F(__is_pod(DerivesEmpty))];
+ // int t32[F(__is_pod(NonPODUnion))];
+}
+
+typedef Empty EmptyAr[10];
+struct Bit0 { int : 0; };
+struct Bit0Cons { int : 0; Bit0Cons(); };
+struct BitOnly { int x : 3; };
+//struct DerivesVirt : virtual POD {};
+
+void is_empty()
+{
+  int t01[T(__is_empty(Empty))];
+  int t02[T(__is_empty(DerivesEmpty))];
+  int t03[T(__is_empty(HasCons))];
+  int t04[T(__is_empty(HasCopyAssign))];
+  int t05[T(__is_empty(HasDest))];
+  int t06[T(__is_empty(HasFunc))];
+  int t07[T(__is_empty(HasOp))];
+  int t08[T(__is_empty(HasConv))];
+  int t09[T(__is_empty(HasAssign))];
+  int t10[T(__is_empty(Bit0))];
+  int t11[T(__is_empty(Bit0Cons))];
+
+  int t21[F(__is_empty(Int))];
+  int t22[F(__is_empty(POD))];
+  int t23[F(__is_empty(EmptyUnion))];
+  int t24[F(__is_empty(EmptyAr))];
+  int t25[F(__is_empty(HasRef))];
+  int t26[F(__is_empty(HasVirt))];
+  int t27[F(__is_empty(BitOnly))];
+//  int t27[F(__is_empty(DerivesVirt))];
+}
+
+typedef Derives ClassType;
+
+void is_class()
+{
+  int t01[T(__is_class(Derives))];
+  int t02[T(__is_class(HasPriv))];
+  int t03[T(__is_class(ClassType))];
+
+  int t11[F(__is_class(int))];
+  int t12[F(__is_class(Enum))];
+  int t13[F(__is_class(Int))];
+  int t14[F(__is_class(IntAr))];
+  int t15[F(__is_class(NonPODAr))];
+  int t16[F(__is_class(Union))];
+}
+
+typedef Union UnionAr[10];
+typedef Union UnionType;
+
+void is_union()
+{
+  int t01[T(__is_union(Union))];
+  int t02[T(__is_union(UnionType))];
+
+  int t11[F(__is_union(int))];
+  int t12[F(__is_union(Enum))];
+  int t13[F(__is_union(Int))];
+  int t14[F(__is_union(IntAr))];
+  int t15[F(__is_union(UnionAr))];
+}
+
+typedef Enum EnumType;
+
+void is_enum()
+{
+  int t01[T(__is_enum(Enum))];
+  int t02[T(__is_enum(EnumType))];
+
+  int t11[F(__is_enum(int))];
+  int t12[F(__is_enum(Union))];
+  int t13[F(__is_enum(Int))];
+  int t14[F(__is_enum(IntAr))];
+  int t15[F(__is_enum(UnionAr))];
+  int t16[F(__is_enum(Derives))];
+  int t17[F(__is_enum(ClassType))];
+}
+
+typedef HasVirt Polymorph;
+struct InheritPolymorph : Polymorph {};
+
+void is_polymorphic()
+{
+  int t01[T(__is_polymorphic(Polymorph))];
+  int t02[T(__is_polymorphic(InheritPolymorph))];
+
+  int t11[F(__is_polymorphic(int))];
+  int t12[F(__is_polymorphic(Union))];
+  int t13[F(__is_polymorphic(Int))];
+  int t14[F(__is_polymorphic(IntAr))];
+  int t15[F(__is_polymorphic(UnionAr))];
+  int t16[F(__is_polymorphic(Derives))];
+  int t17[F(__is_polymorphic(ClassType))];
+  int t18[F(__is_polymorphic(Enum))];
+}
+
+typedef Int& IntRef;
+typedef const IntAr ConstIntAr;
+typedef ConstIntAr ConstIntArAr[4];
+
+struct HasCopy {
+  HasCopy(HasCopy& cp);
+};
+
+void has_trivial_default_constructor() {
+  int t01[T(__has_trivial_constructor(Int))];
+  int t02[T(__has_trivial_constructor(IntAr))];
+  int t03[T(__has_trivial_constructor(Union))];
+  int t04[T(__has_trivial_constructor(UnionAr))];
+  int t05[T(__has_trivial_constructor(POD))];
+  int t06[T(__has_trivial_constructor(Derives))];
+  int t07[T(__has_trivial_constructor(ConstIntAr))];
+  int t08[T(__has_trivial_constructor(ConstIntArAr))];
+  int t09[T(__has_trivial_constructor(HasDest))];
+  int t10[T(__has_trivial_constructor(HasPriv))];
+  int t11[F(__has_trivial_constructor(HasCons))];
+  int t12[F(__has_trivial_constructor(HasRef))];
+  int t13[F(__has_trivial_constructor(HasCopy))];
+  int t14[F(__has_trivial_constructor(IntRef))];
+  int t15[T(__has_trivial_constructor(HasCopyAssign))];
+  int t16[T(__has_trivial_constructor(const Int))];
+  int t17[T(__has_trivial_constructor(NonPODAr))];
+  int t18[F(__has_trivial_constructor(VirtAr))];
+}
+
+void has_trivial_copy_constructor() {
+  int t01[T(__has_trivial_copy(Int))];
+  int t02[T(__has_trivial_copy(IntAr))];
+  int t03[T(__has_trivial_copy(Union))];
+  int t04[T(__has_trivial_copy(UnionAr))];
+  int t05[T(__has_trivial_copy(POD))];
+  int t06[T(__has_trivial_copy(Derives))];
+  int t07[T(__has_trivial_copy(ConstIntAr))];
+  int t08[T(__has_trivial_copy(ConstIntArAr))];
+  int t09[T(__has_trivial_copy(HasDest))];
+  int t10[T(__has_trivial_copy(HasPriv))];
+  int t11[T(__has_trivial_copy(HasCons))];
+  int t12[T(__has_trivial_copy(HasRef))];
+  int t13[F(__has_trivial_copy(HasCopy))];
+  int t14[T(__has_trivial_copy(IntRef))];
+  int t15[T(__has_trivial_copy(HasCopyAssign))];
+  int t16[T(__has_trivial_copy(const Int))];
+  int t17[F(__has_trivial_copy(NonPODAr))];
+  int t18[F(__has_trivial_copy(VirtAr))];
+}
+
+void has_trivial_copy_assignment() {
+  int t01[T(__has_trivial_assign(Int))];
+  int t02[T(__has_trivial_assign(IntAr))];
+  int t03[T(__has_trivial_assign(Union))];
+  int t04[T(__has_trivial_assign(UnionAr))];
+  int t05[T(__has_trivial_assign(POD))];
+  int t06[T(__has_trivial_assign(Derives))];
+  int t07[F(__has_trivial_assign(ConstIntAr))];
+  int t08[F(__has_trivial_assign(ConstIntArAr))];
+  int t09[T(__has_trivial_assign(HasDest))];
+  int t10[T(__has_trivial_assign(HasPriv))];
+  int t11[T(__has_trivial_assign(HasCons))];
+  int t12[T(__has_trivial_assign(HasRef))];
+  int t13[T(__has_trivial_assign(HasCopy))];
+  int t14[F(__has_trivial_assign(IntRef))];
+  int t15[F(__has_trivial_assign(HasCopyAssign))];
+  int t16[F(__has_trivial_assign(const Int))];
+  int t17[F(__has_trivial_assign(NonPODAr))];
+  int t18[F(__has_trivial_assign(VirtAr))];
+}
+
+void has_trivial_destructor() {
+  int t01[T(__has_trivial_destructor(Int))];
+  int t02[T(__has_trivial_destructor(IntAr))];
+  int t03[T(__has_trivial_destructor(Union))];
+  int t04[T(__has_trivial_destructor(UnionAr))];
+  int t05[T(__has_trivial_destructor(POD))];
+  int t06[T(__has_trivial_destructor(Derives))];
+  int t07[T(__has_trivial_destructor(ConstIntAr))];
+  int t08[T(__has_trivial_destructor(ConstIntArAr))];
+  int t09[F(__has_trivial_destructor(HasDest))];
+  int t10[T(__has_trivial_destructor(HasPriv))];
+  int t11[T(__has_trivial_destructor(HasCons))];
+  int t12[T(__has_trivial_destructor(HasRef))];
+  int t13[T(__has_trivial_destructor(HasCopy))];
+  int t14[T(__has_trivial_destructor(IntRef))];
+  int t15[T(__has_trivial_destructor(HasCopyAssign))];
+  int t16[T(__has_trivial_destructor(const Int))];
+  int t17[T(__has_trivial_destructor(NonPODAr))];
+  int t18[T(__has_trivial_destructor(VirtAr))];
+}
+
+struct A { ~A() {} };
+template<typename> struct B : A { };
+
+void f() {
+  int t01[T(!__has_trivial_destructor(A))];
+  int t02[T(!__has_trivial_destructor(B<int>))];
+}
diff --git a/test/SemaCXX/typedef-redecl.cpp b/test/SemaCXX/typedef-redecl.cpp
new file mode 100644
index 0000000..2acf675
--- /dev/null
+++ b/test/SemaCXX/typedef-redecl.cpp
@@ -0,0 +1,39 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s 
+typedef int INT;
+typedef INT REALLY_INT; // expected-note {{previous definition is here}}
+typedef REALLY_INT REALLY_REALLY_INT;
+typedef REALLY_INT BOB;
+typedef float REALLY_INT; // expected-error{{typedef redefinition with different types ('float' vs 'INT' (aka 'int'))}}
+
+struct X {
+  typedef int result_type; // expected-note {{previous definition is here}}
+  typedef INT result_type; // expected-error {{redefinition of 'result_type'}}
+};
+
+struct Y; // expected-note{{previous definition is here}}
+typedef int Y;  // expected-error{{typedef redefinition with different types ('int' vs 'Y')}}
+
+typedef int Y2; // expected-note{{declared here}}
+struct Y2; // expected-error{{definition of type 'Y2' conflicts with typedef of the same name}}
+
+void f(); // expected-note{{previous definition is here}}
+typedef int f; // expected-error{{redefinition of 'f' as different kind of symbol}}
+
+typedef int f2; // expected-note{{previous definition is here}}
+void f2(); // expected-error{{redefinition of 'f2' as different kind of symbol}}
+
+typedef struct s s; 
+typedef int I; 
+typedef int I; 
+typedef I I; 
+
+struct s { };
+
+// PR5874
+namespace test1 {
+  typedef int foo;
+  namespace a { using test1::foo; };
+  typedef int foo;
+  using namespace a; 
+  foo x;
+}
diff --git a/test/SemaCXX/typeid-ref.cpp b/test/SemaCXX/typeid-ref.cpp
new file mode 100644
index 0000000..da00169
--- /dev/null
+++ b/test/SemaCXX/typeid-ref.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+namespace std {
+  class type_info;
+}
+
+struct X { };
+
+void f() {
+  // CHECK: @_ZTS1X = weak_odr constant
+  // CHECK: @_ZTI1X = weak_odr constant 
+  (void)typeid(X&);
+}
diff --git a/test/SemaCXX/typeid.cpp b/test/SemaCXX/typeid.cpp
new file mode 100644
index 0000000..8db7db5
--- /dev/null
+++ b/test/SemaCXX/typeid.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+void f()
+{
+  (void)typeid(int); // expected-error {{error: you need to include <typeinfo> before using the 'typeid' operator}}
+}
+
+namespace std {
+  class type_info;
+}
+
+void g()
+{
+  (void)typeid(int);
+}
+
+struct X; // expected-note 3{{forward declaration}}
+
+void g1(X &x) {
+  (void)typeid(X); // expected-error{{'typeid' of incomplete type 'X'}}
+  (void)typeid(X&); // expected-error{{'typeid' of incomplete type 'X'}}
+  (void)typeid(x); // expected-error{{'typeid' of incomplete type 'X'}}
+}
diff --git a/test/SemaCXX/types_compatible_p.cpp b/test/SemaCXX/types_compatible_p.cpp
new file mode 100644
index 0000000..4aa9a1c
--- /dev/null
+++ b/test/SemaCXX/types_compatible_p.cpp
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+bool f() {
+  return __builtin_types_compatible_p(int, const int); // expected-error{{C++}}
+}
diff --git a/test/SemaCXX/unknown-type-name.cpp b/test/SemaCXX/unknown-type-name.cpp
new file mode 100644
index 0000000..5f8d8ca
--- /dev/null
+++ b/test/SemaCXX/unknown-type-name.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// PR3990
+namespace N {
+  struct Wibble {
+  };
+
+  typedef Wibble foo;
+}
+using namespace N;
+
+foo::bar x; // expected-error{{no type named 'bar' in 'N::Wibble'}}
+
+void f() {
+  foo::bar  = 4; // expected-error{{no member named 'bar' in 'N::Wibble'}}
+}
+
+template<typename T>
+struct A {
+  typedef T type;
+  
+  type f();
+};
+
+template<typename T>
+A<T>::type g(T t) { return t; } // expected-error{{missing 'typename'}}
+
+template<typename T>
+A<T>::type A<T>::f() { return type(); } // expected-error{{missing 'typename'}}
diff --git a/test/SemaCXX/unreachable-catch-clauses.cpp b/test/SemaCXX/unreachable-catch-clauses.cpp
new file mode 100644
index 0000000..9fc4aef
--- /dev/null
+++ b/test/SemaCXX/unreachable-catch-clauses.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+class BaseEx {};
+class Ex1: public BaseEx {};
+typedef Ex1 Ex2;
+
+void f();
+
+void test()
+try {}
+catch (BaseEx &e) { f(); }
+catch (Ex1 &e) { f(); } // expected-note {{for type class Ex1 &}}
+catch (Ex2 &e) { f(); } // expected-warning {{exception of type Ex2 & will be caught by earlier handler}}
+
diff --git a/test/SemaCXX/unreachable-code.cpp b/test/SemaCXX/unreachable-code.cpp
new file mode 100644
index 0000000..528bba7
--- /dev/null
+++ b/test/SemaCXX/unreachable-code.cpp
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -fsyntax-only -Wunreachable-code -fblocks -verify %s
+
+int j;
+void bar() { }
+int test1() {
+  for (int i = 0;
+       i != 10;
+       ++i) {  // expected-warning {{will never be executed}}
+    if (j == 23) // missing {}'s
+      bar();
+      return 1;
+  }
+  return 0;
+  return 1;    // expected-warning {{will never be executed}}
+}
+
+void test2(int i) {
+  switch (i) {
+  case 0:
+    break;
+    bar();     // expected-warning {{will never be executed}}
+  case 2:
+    switch (i) {
+    default:
+    a: goto a;
+    }
+    bar();     // expected-warning {{will never be executed}}
+  }
+  b: goto b;
+  bar();       // expected-warning {{will never be executed}}
+}
+
+void test3() {
+  ^{ return;
+     bar();    // expected-warning {{will never be executed}}
+  }();
+  while (++j) {
+    continue;
+    bar();     // expected-warning {{will never be executed}}
+  }
+}
diff --git a/test/SemaCXX/unused-functions.cpp b/test/SemaCXX/unused-functions.cpp
new file mode 100644
index 0000000..cefa9e1
--- /dev/null
+++ b/test/SemaCXX/unused-functions.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only -Wunused -verify %s
+
+static int foo(int x) { return x; }
+
+template<typename T>
+T get_from_foo(T y) { return foo(y); }
+
+int g(int z) { return get_from_foo(z); }
diff --git a/test/SemaCXX/unused.cpp b/test/SemaCXX/unused.cpp
new file mode 100644
index 0000000..88783ce
--- /dev/null
+++ b/test/SemaCXX/unused.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// PR4103 : Make sure we don't get a bogus unused expression warning
+class APInt {
+  char foo;
+};
+class APSInt : public APInt {
+  char bar;
+public:
+  APSInt &operator=(const APSInt &RHS);
+};
+
+APSInt& APSInt::operator=(const APSInt &RHS) {
+  APInt::operator=(RHS);
+  return *this;
+}
+
+template<typename T>
+struct X {
+  X();
+};
+
+void test() {
+  X<int>();
+}
diff --git a/test/SemaCXX/user-defined-conversions.cpp b/test/SemaCXX/user-defined-conversions.cpp
new file mode 100644
index 0000000..5de7f44
--- /dev/null
+++ b/test/SemaCXX/user-defined-conversions.cpp
@@ -0,0 +1,84 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s 
+struct X {
+  operator bool();
+};
+
+int& f(bool);
+float& f(int);
+
+void f_test(X x) {
+  int& i1 = f(x);
+}
+
+struct Y {
+  operator short();
+  operator float();
+};
+
+void g(int);
+
+void g_test(Y y) {
+  g(y);
+  short s;
+  s = y;
+}
+
+struct A { };
+struct B : A { };
+
+struct C {
+  operator B&();
+};
+
+// Test reference binding via an lvalue conversion function.
+void h(volatile A&);
+void h_test(C c) {
+  h(c);
+}
+
+// Test conversion followed by copy-construction
+struct FunkyDerived;
+
+struct Base { 
+  Base(const FunkyDerived&);
+};
+
+struct Derived : Base { };
+
+struct FunkyDerived : Base { };
+
+struct ConvertibleToBase {
+  operator Base();
+};
+
+struct ConvertibleToDerived {
+  operator Derived();
+};
+
+struct ConvertibleToFunkyDerived {
+  operator FunkyDerived();
+};
+
+void test_conversion(ConvertibleToBase ctb, ConvertibleToDerived ctd,
+                     ConvertibleToFunkyDerived ctfd) {
+  Base b1 = ctb;
+  Base b2(ctb);
+  Base b3 = ctd;
+  Base b4(ctd);
+  Base b5 = ctfd;
+}
+
+struct X1 {
+  X1(X1&); // expected-note{{candidate constructor not viable: no known conversion from 'X1' to 'X1 &' for 1st argument}}
+};
+
+struct X2 {
+  operator X1();
+};
+
+int &f(X1);
+float &f(...);
+
+void g(X2 b) {
+  int &ir = f(b); // expected-error{{no viable constructor copying parameter of type 'X1'}}
+}
diff --git a/test/SemaCXX/using-decl-1.cpp b/test/SemaCXX/using-decl-1.cpp
new file mode 100644
index 0000000..30c4cfd
--- /dev/null
+++ b/test/SemaCXX/using-decl-1.cpp
@@ -0,0 +1,97 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+extern "C" { void f(bool); }
+
+namespace std {
+  using ::f;
+  inline void f() { return f(true); }
+}
+
+namespace M {
+  void f(float);
+}
+
+namespace N {
+  using M::f;
+  void f(int) { } // expected-note{{previous}}
+  
+  void f(int) { } // expected-error{{redefinition}}
+}
+
+namespace N {
+  void f(double);
+  void f(long);
+}
+
+struct X0 {
+  void operator()(int);
+  void operator()(long);
+};
+
+struct X1 : X0 {
+  // FIXME: give this operator() a 'float' parameter to test overloading
+  // behavior. It currently fails.
+  void operator()();
+  using X0::operator();
+  
+  void test() {
+    (*this)(1);
+  }
+};
+
+struct A { void f(); };
+struct B : A { };
+class C : B { using B::f; };
+
+// PR5751: Resolve overloaded functions through using decls.
+namespace O {
+  void f(int i);
+  void f(double d);
+}
+namespace P {
+  void f();
+  void g(void (*ptr)(int));
+  using O::f;
+  void test() {
+    f();
+    f(1);
+    void (*f_ptr1)(double) = f;
+    void (*f_ptr2)() = f;
+    g(f);
+  }
+}
+
+// Make sure that ADL can find names brought in by using decls.
+namespace test0 {
+  namespace ns {
+    class Foo {};
+    
+    namespace inner {
+      void foo(char *); // expected-note {{no known conversion}} 
+    }
+
+    using inner::foo;
+  }
+
+  void test(ns::Foo *p) {
+    foo(*p); // expected-error {{no matching function for call to 'foo'}}
+  }
+}
+
+// Redeclarations!
+namespace test1 {
+  namespace ns0 { struct Foo {}; }
+  namespace A { void foo(ns0::Foo *p, int y, int z); }
+  namespace ns2 { using A::foo; }
+  namespace ns1 { struct Bar : ns0::Foo {}; }
+  namespace A { void foo(ns0::Foo *p, int y, int z = 0); } // expected-note {{candidate}}
+  namespace ns1 { using A::foo; }
+  namespace ns2 { struct Baz : ns1::Bar {}; }
+  namespace A { void foo(ns0::Foo *p, int y = 0, int z); }
+
+  void test(ns2::Baz *p) {
+    foo(p, 0, 0); // okay!
+    foo(p, 0); // should be fine!
+    foo(p); // expected-error {{no matching function}}
+  }
+}
diff --git a/test/SemaCXX/using-decl-pr4441.cpp b/test/SemaCXX/using-decl-pr4441.cpp
new file mode 100644
index 0000000..39a446f
--- /dev/null
+++ b/test/SemaCXX/using-decl-pr4441.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace A {
+    struct B { };
+    void operator+(B,B);
+}
+
+using A::operator+;
diff --git a/test/SemaCXX/using-decl-pr4450.cpp b/test/SemaCXX/using-decl-pr4450.cpp
new file mode 100644
index 0000000..4f929ad
--- /dev/null
+++ b/test/SemaCXX/using-decl-pr4450.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace A {
+  void g();
+}
+
+namespace X {
+  using A::g; 
+}
+
+void h()
+{
+  A::g();
+  X::g();
+}
diff --git a/test/SemaCXX/using-decl-templates.cpp b/test/SemaCXX/using-decl-templates.cpp
new file mode 100644
index 0000000..5148ed5
--- /dev/null
+++ b/test/SemaCXX/using-decl-templates.cpp
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T> struct A {
+  void f() { }
+  struct N { }; // expected-note{{target of using declaration}}
+};
+
+template<typename T> struct B : A<T> {
+  using A<T>::f;
+  using A<T>::N; // expected-error{{dependent using declaration resolved to type without 'typename'}}
+  
+  using A<T>::foo; // expected-error{{no member named 'foo'}}
+  using A<double>::f; // expected-error{{using declaration refers into 'A<double>::', which is not a base class of 'B<int>'}}
+};
+
+B<int> a; // expected-note{{in instantiation of template class 'B<int>' requested here}}
+
+template<typename T> struct C : A<T> {
+  using A<T>::f;
+  
+  void f() { };
+};
+
+template <typename T> struct D : A<T> {
+  using A<T>::f;
+  
+  void f();
+};
+
+template<typename T> void D<T>::f() { }
+
+template<typename T> struct E : A<T> {
+  using A<T>::f;
+
+  void g() { f(); }
+};
+
+namespace test0 {
+  struct Base {
+    int foo;
+  };
+  template<typename T> struct E : Base {
+    using Base::foo;
+  };
+
+  template struct E<int>;
+}
diff --git a/test/SemaCXX/using-directive.cpp b/test/SemaCXX/using-directive.cpp
new file mode 100644
index 0000000..0d5c840
--- /dev/null
+++ b/test/SemaCXX/using-directive.cpp
@@ -0,0 +1,123 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace A {
+  short i; // expected-note 2{{candidate found by name lookup is 'A::i'}}
+  namespace B {
+    long i; // expected-note{{candidate found by name lookup is 'A::B::i'}}
+    void f() {} // expected-note{{candidate function}}
+    int k;
+    namespace E {} // \
+      expected-note{{candidate found by name lookup is 'A::B::E'}}
+  }
+
+  namespace E {} // expected-note{{candidate found by name lookup is 'A::E'}}
+
+  namespace C {
+    using namespace B;
+    namespace E {} // \
+      expected-note{{candidate found by name lookup is 'A::C::E'}}
+  }
+
+  void f() {} // expected-note{{candidate function}}
+
+  class K1 {
+    void foo();
+  };
+
+  void local_i() {
+    char i;
+    using namespace A;
+    using namespace B;
+    int a[sizeof(i) == sizeof(char)? 1 : -1]; // okay
+  }
+  namespace B {
+    int j;
+  }
+
+  void ambig_i() {
+    using namespace A;
+    using namespace A::B;
+    (void) i; // expected-error{{reference to 'i' is ambiguous}}
+    f(); // expected-error{{call to 'f' is ambiguous}}
+    (void) j; // okay
+    using namespace C;
+    (void) k; // okay
+    using namespace E; // expected-error{{reference to 'E' is ambiguous}}
+  }
+
+  struct K2 {}; // expected-note 2{{candidate found by name lookup is 'A::K2'}}
+}
+
+struct K2 {}; // expected-note 2{{candidate found by name lookup is 'K2'}}
+
+using namespace A;
+
+void K1::foo() {} // okay
+
+struct K2 *k2; // expected-error{{reference to 'K2' is ambiguous}}
+
+K2 *k3; // expected-error{{reference to 'K2' is ambiguous}}
+
+class X { // expected-note{{candidate found by name lookup is 'X'}}
+  // FIXME: produce a suitable error message for this
+  using namespace A; // expected-error{{not allowed}}
+};
+
+namespace N {
+  struct K2;
+  struct K2 { };
+}
+
+namespace Ni {
+ int i(); // expected-note{{candidate found by name lookup is 'Ni::i'}}
+}
+
+namespace NiTest {
+ using namespace A;
+ using namespace Ni;
+
+ int test() {
+   return i; // expected-error{{reference to 'i' is ambiguous}}
+ }
+}
+
+namespace OneTag {
+  struct X; // expected-note{{candidate found by name lookup is 'OneTag::X'}}
+}
+
+namespace OneFunction {
+  void X(); // expected-note{{candidate found by name lookup is 'OneFunction::X'}}
+}
+
+namespace TwoTag {
+  struct X; // expected-note{{candidate found by name lookup is 'TwoTag::X'}}
+}
+
+namespace FuncHidesTagAmbiguity {
+  using namespace OneTag;
+  using namespace OneFunction;
+  using namespace TwoTag;
+
+  void test() {
+    (void)X(); // expected-error{{reference to 'X' is ambiguous}}
+  }
+}
+
+// PR5479
+namespace Aliased {
+  void inAliased();
+}
+namespace Alias = Aliased;
+using namespace Alias;
+void testAlias() {
+  inAliased();
+}
+
+namespace N { void f2(int); }
+
+extern "C++" {
+  using namespace N;
+  void f3() { f2(1); }
+}
+
+void f4() { f2(1); }
diff --git a/test/SemaCXX/value-dependent-exprs.cpp b/test/SemaCXX/value-dependent-exprs.cpp
new file mode 100644
index 0000000..2017ffa
--- /dev/null
+++ b/test/SemaCXX/value-dependent-exprs.cpp
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -verify %s
+
+template <unsigned I>
+class C0 {
+  static const int iv0 = 1 << I;
+
+  enum {
+    A = I,
+    B = I + 1
+  };
+
+  struct s0 {
+    int a : I;
+    int b[I];
+  };
+
+  // FIXME: I'm unclear where the right place to handle this is.
+#if 0
+  void f0(int *p) {
+    if (p == I) {
+    }
+  }
+#endif
+
+#if 0
+  // FIXME: Not sure whether we care about these.
+  void f1(int *a)
+    __attribute__((nonnull(1 + I)))
+    __attribute__((constructor(1 + I)))
+    __attribute__((destructor(1 + I)))
+    __attribute__((sentinel(1 + I, 2 + I))),
+    __attribute__((reqd_work_group_size(1 + I, 2 + I, 3 + I))),
+    __attribute__((format_arg(1 + I))),
+    __attribute__((aligned(1 + I))),
+    __attribute__((regparm(1 + I)));
+
+  typedef int int_a0 __attribute__((address_space(1 + B)));
+#endif
+
+#if 0
+  // FIXME: This doesn't work. PR4996.
+  int f2() {
+    return __builtin_choose_expr(I, 1, 2);
+  }
+#endif
+
+};
diff --git a/test/SemaCXX/value-initialization.cpp b/test/SemaCXX/value-initialization.cpp
new file mode 100644
index 0000000..10520fb
--- /dev/null
+++ b/test/SemaCXX/value-initialization.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
+
+struct A { // expected-error {{implicit default constructor for 'A' must explicitly initialize the const member 'i'}} \
+  // expected-warning{{struct 'A' does not declare any constructor to initialize its non-modifiable members}}
+     const int i;	// expected-note {{declared here}} \
+  // expected-note{{const member 'i' will never be initialized}}
+     virtual void f() { } 
+};
+
+int main () {
+      (void)A(); // expected-note {{first required here}}
+}
diff --git a/test/SemaCXX/vararg-default-arg.cpp b/test/SemaCXX/vararg-default-arg.cpp
new file mode 100644
index 0000000..3c8e41c
--- /dev/null
+++ b/test/SemaCXX/vararg-default-arg.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only
+// PR5462
+
+void f1(void);
+void f2(const char * = __null, ...);
+
+void f1(void)
+{
+        f2();
+}
diff --git a/test/SemaCXX/vararg-non-pod.cpp b/test/SemaCXX/vararg-non-pod.cpp
new file mode 100644
index 0000000..d31f1f7
--- /dev/null
+++ b/test/SemaCXX/vararg-non-pod.cpp
@@ -0,0 +1,90 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -fblocks %s -Wnon-pod-varargs
+
+extern char version[];
+
+class C {
+public:
+  C(int);
+  void g(int a, ...);
+  static void h(int a, ...);
+};
+
+void g(int a, ...);
+
+void t1()
+{
+  C c(10);
+  
+  g(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic function; call will abort at runtime}}
+  g(10, version);
+}
+
+void t2()
+{
+  C c(10);
+
+  c.g(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic method; call will abort at runtime}}
+  c.g(10, version);
+  
+  C::h(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic function; call will abort at runtime}}
+  C::h(10, version);
+}
+
+int (^block)(int, ...);
+
+void t3()
+{
+  C c(10);
+  
+  block(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic block; call will abort at runtime}}
+  block(10, version);
+}
+
+class D {
+public:
+  void operator() (int a, ...);
+};
+
+void t4()
+{
+  C c(10);
+
+  D d;
+  
+  d(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic method; call will abort at runtime}}
+  d(10, version);
+}
+
+class E {
+  E(int, ...);
+};
+
+void t5()
+{
+  C c(10);
+  
+  E e(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic constructor; call will abort at runtime}}
+  (void)E(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic constructor; call will abort at runtime}}
+}
+
+// PR5761: unevaluated operands and the non-POD warning
+class Foo {
+ public:
+  Foo() {}
+};
+
+int Helper(...);
+const int size = sizeof(Helper(Foo()));
+
+namespace std {
+  class type_info { };
+}
+
+struct Base { virtual ~Base(); };
+Base &get_base(...);
+int eat_base(...);
+
+void test_typeid(Base &base) {
+  (void)typeid(get_base(base)); // expected-warning{{cannot pass object of non-POD type 'Base' through variadic function; call will abort at runtime}}
+  (void)typeid(eat_base(base)); // okay
+}
diff --git a/test/SemaCXX/vector-casts.cpp b/test/SemaCXX/vector-casts.cpp
new file mode 100644
index 0000000..4bb5808
--- /dev/null
+++ b/test/SemaCXX/vector-casts.cpp
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+typedef int __v2si __attribute__((__vector_size__(8)));
+typedef short __v4hi __attribute__((__vector_size__(8)));
+typedef short __v8hi __attribute__((__vector_size__(16)));
+
+struct S { };
+
+void f() {
+  __v2si v2si;
+  __v4hi v4hi;
+  __v8hi v8hi;
+  unsigned long long ll;
+  unsigned char c;
+  S s;
+  
+  (void)reinterpret_cast<__v2si>(v4hi);
+  (void)(__v2si)v4hi;
+  (void)reinterpret_cast<__v4hi>(v2si);
+  (void)(__v4hi)v2si;
+  (void)reinterpret_cast<unsigned long long>(v2si);
+  (void)(unsigned long long)v2si;
+  (void)reinterpret_cast<__v2si>(ll);
+  (void)(__v2si)(ll);
+
+  (void)reinterpret_cast<S>(v2si); // expected-error {{reinterpret_cast from '__v2si' to 'S' is not allowed}}
+  (void)(S)v2si; // expected-error {{C-style cast from '__v2si' to 'S' is not allowed}}
+  (void)reinterpret_cast<__v2si>(s); // expected-error {{reinterpret_cast from 'S' to '__v2si' is not allowed}}
+  (void)(__v2si)s; // expected-error {{C-style cast from 'S' to '__v2si' is not allowed}}
+  
+  (void)reinterpret_cast<unsigned char>(v2si); // expected-error {{reinterpret_cast from vector '__v2si' to scalar 'unsigned char' of different size}}
+  (void)(unsigned char)v2si; // expected-error {{C-style cast from vector '__v2si' to scalar 'unsigned char' of different size}}
+  (void)reinterpret_cast<__v2si>(c); // expected-error {{reinterpret_cast from scalar 'unsigned char' to vector '__v2si' of different size}}
+
+  (void)reinterpret_cast<__v8hi>(v4hi); // expected-error {{reinterpret_cast from vector '__v4hi' to vector '__v8hi' of different size}}
+  (void)(__v8hi)v4hi; // expected-error {{C-style cast from vector '__v4hi' to vector '__v8hi' of different size}}
+  (void)reinterpret_cast<__v4hi>(v8hi); // expected-error {{reinterpret_cast from vector '__v8hi' to vector '__v4hi' of different size}}
+  (void)(__v4hi)v8hi; // expected-error {{C-style cast from vector '__v8hi' to vector '__v4hi' of different size}}
+}
+
+
diff --git a/test/SemaCXX/virtual-member-functions-key-function.cpp b/test/SemaCXX/virtual-member-functions-key-function.cpp
new file mode 100644
index 0000000..97164d9
--- /dev/null
+++ b/test/SemaCXX/virtual-member-functions-key-function.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+struct A {
+  virtual ~A();
+};
+
+struct B : A {  // expected-error {{no suitable member 'operator delete' in 'B'}}
+  B() { }
+  void operator delete(void *, int); // expected-note {{'operator delete' declared here}}
+}; // expected-note {{implicit default destructor for 'B' first required here}}
+
+struct C : A {  // expected-error {{no suitable member 'operator delete' in 'C'}}
+  void operator delete(void *, int); // expected-note {{'operator delete' declared here}}
+}; // expected-note {{implicit default destructor for 'C' first required here}}
+
+void f() {
+  (void)new B;
+  (void)new C;
+}
+
+// Make sure that the key-function computation is consistent when the
+// first virtual member function of a nested class has an inline body.
+struct Outer {
+  struct Inner {
+    virtual void f() { }
+    void g();
+  };
+};
+
+void Outer::Inner::g() { }
diff --git a/test/SemaCXX/virtual-override.cpp b/test/SemaCXX/virtual-override.cpp
new file mode 100644
index 0000000..e07531f
--- /dev/null
+++ b/test/SemaCXX/virtual-override.cpp
@@ -0,0 +1,278 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
+namespace T1 {
+
+class A {
+  virtual int f(); // expected-note{{overridden virtual function is here}}
+};
+
+class B : A {
+  virtual void f(); // expected-error{{virtual function 'f' has a different return type ('void') than the function it overrides (which has return type 'int')}}
+};
+
+}
+
+namespace T2 {
+
+struct a { };
+struct b { };
+  
+class A {
+  virtual a* f(); // expected-note{{overridden virtual function is here}}
+};
+
+class B : A {
+  virtual b* f(); // expected-error{{return type of virtual function 'f' is not covariant with the return type of the function it overrides ('T2::b *' is not derived from 'T2::a *')}}
+};
+
+}
+
+namespace T3 {
+
+struct a { };
+struct b : private a { }; // expected-note{{declared private here}}
+  
+class A {
+  virtual a* f(); // expected-note{{overridden virtual function is here}}
+};
+
+class B : A {
+  virtual b* f(); // expected-error{{invalid covariant return for virtual function: 'T3::a' is a private base class of 'T3::b'}}
+};
+
+}
+
+namespace T4 {
+
+struct a { };
+struct a1 : a { };
+struct b : a, a1 { };
+  
+class A {
+  virtual a* f(); // expected-note{{overridden virtual function is here}}
+};
+
+class B : A {
+  virtual b* f(); // expected-error{{return type of virtual function 'f' is not covariant with the return type of the function it overrides (ambiguous conversion from derived class 'T4::b' to base class 'T4::a':\n\
+    struct T4::b -> struct T4::a\n\
+    struct T4::b -> struct T4::a1 -> struct T4::a)}}
+};
+
+}
+
+namespace T5 {
+  
+struct a { };
+
+class A {
+  virtual a* const f(); 
+  virtual a* const g(); // expected-note{{overridden virtual function is here}}
+};
+
+class B : A {
+  virtual a* const f(); 
+  virtual a* g(); // expected-error{{return type of virtual function 'g' is not covariant with the return type of the function it overrides ('T5::a *' has different qualifiers than 'T5::a *const')}}
+};
+
+}
+
+namespace T6 {
+  
+struct a { };
+
+class A {
+  virtual const a* f(); 
+  virtual a* g(); // expected-note{{overridden virtual function is here}}
+};
+
+class B : A {
+  virtual a* f(); 
+  virtual const a* g(); // expected-error{{return type of virtual function 'g' is not covariant with the return type of the function it overrides (class type 'T6::a const *' is more qualified than class type 'T6::a *'}}
+};
+
+}
+
+namespace T7 {
+  struct a { };
+  struct b { };
+
+  class A {
+    a* f();
+  };
+
+  class B : A {
+    virtual b* f();
+  };
+}
+
+namespace T8 {
+  struct a { };
+  struct b; // expected-note {{forward declaration of 'T8::b'}}
+  
+  class A {
+    virtual a *f();
+  };
+  
+  class B : A {
+    b* f(); // expected-error {{return type of virtual function 'f' is not covariant with the return type of the function it overrides ('T8::b' is incomplete)}}
+  };
+}
+
+namespace T9 {
+  struct a { };
+  
+  template<typename T> struct b : a {
+    int a[sizeof(T) ? -1 : -1]; // expected-error {{array size is negative}}
+  };
+  
+  class A {
+    virtual a *f();
+  };
+  
+  class B : A {
+    virtual b<int> *f(); // expected-note {{in instantiation of template class 'T9::b<int>' requested here}}
+  };
+}
+
+// PR5656
+class X0 {
+  virtual void f0();
+};
+class X1 : public X0 {
+  void f0() = 0;
+};
+
+template <typename Base>
+struct Foo : Base { 
+  void f(int) = 0; // expected-error{{not virtual and cannot be declared pure}}
+};
+
+struct Base1 { virtual void f(int); };
+struct Base2 { };
+
+void test() {
+  (void)sizeof(Foo<Base1>);
+  (void)sizeof(Foo<Base2>); // expected-note{{instantiation}}
+}
+
+template<typename Base>
+struct Foo2 : Base {
+  template<typename T> int f(T);
+};
+
+void test2() {
+  Foo2<Base1> f1;
+  Foo2<Base2> f2;
+  f1.f(17);
+  f2.f(17);
+};
+
+struct Foo3 {
+  virtual void f(int) = 0; // expected-note{{pure virtual function}}
+};
+
+template<typename T>
+struct Bar3 : Foo3 {
+  void f(T);
+};
+
+void test3() {
+  Bar3<int> b3i; // okay
+  Bar3<float> b3f; // expected-error{{is an abstract class}}
+}
+
+// 5920
+namespace PR5920 {
+  class Base {};
+
+  template <typename T>
+  class Derived : public Base {};
+
+  class Foo {
+   public:
+    virtual Base* Method();
+  };
+
+  class Bar : public Foo {
+   public:
+    virtual Derived<int>* Method();
+  };
+}
+
+// Look through template types and typedefs to see whether return types are
+// pointers or references.
+namespace PR6110 {
+  class Base {};
+  class Derived : public Base {};
+
+  typedef Base* BaseP;
+  typedef Derived* DerivedP;
+
+  class X { virtual BaseP f(); };
+  class X1 : public X { virtual DerivedP f(); };
+
+  template <typename T> class Y { virtual T f(); };
+  template <typename T1, typename T> class Y1 : public Y<T> { virtual T1 f(); };
+  Y1<Derived*, Base*> y;
+}
+
+// Defer checking for covariance if either return type is dependent.
+namespace type_dependent_covariance {
+  struct B {};
+  template <int N> struct TD : public B {};
+  template <> struct TD<1> {};
+
+  template <int N> struct TB {};
+  struct D : public TB<0> {};
+
+  template <int N> struct X {
+    virtual B* f1(); // expected-note{{overridden virtual function is here}}
+    virtual TB<N>* f2(); // expected-note{{overridden virtual function is here}}
+  };
+  template <int N, int M> struct X1 : X<N> {
+    virtual TD<M>* f1(); // expected-error{{return type of virtual function 'f1' is not covariant with the return type of the function it overrides ('TD<1> *'}}
+    virtual D* f2(); // expected-error{{return type of virtual function 'f2' is not covariant with the return type of the function it overrides ('type_dependent_covariance::D *' is not derived from 'TB<1> *')}}
+  };
+
+  X1<0, 0> good;
+  X1<0, 1> bad_derived; // expected-note{{instantiation}}
+  X1<1, 0> bad_base; // expected-note{{instantiation}}
+}
+
+namespace T10 {
+  struct A { };
+  struct B : A { };
+
+  struct C { 
+    virtual A&& f();
+  };
+
+  struct D : C {
+    virtual B&& f();
+  };
+};
+
+namespace T11 {
+  struct A { };
+  struct B : A { };
+
+  struct C { 
+    virtual A& f(); // expected-note {{overridden virtual function is here}}
+  };
+
+  struct D : C {
+    virtual B&& f(); // expected-error {{virtual function 'f' has a different return type ('T11::B &&') than the function it overrides (which has return type 'T11::A &')}}
+  };
+};
+
+namespace T12 {
+  struct A { };
+  struct B : A { };
+
+  struct C { 
+    virtual A&& f(); // expected-note {{overridden virtual function is here}}
+  };
+
+  struct D : C {
+    virtual B& f(); // expected-error {{virtual function 'f' has a different return type ('T12::B &') than the function it overrides (which has return type 'T12::A &&')}}
+  };
+};
diff --git a/test/SemaCXX/virtuals.cpp b/test/SemaCXX/virtuals.cpp
new file mode 100644
index 0000000..792467e
--- /dev/null
+++ b/test/SemaCXX/virtuals.cpp
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+class A {
+  virtual void f();
+  virtual void g() = 0;
+
+  void h() = 0; // expected-error {{'h' is not virtual and cannot be declared pure}}
+  void i() = 1; // expected-error {{initializer on function does not look like a pure-specifier}}
+  void j() = 0u; // expected-error {{initializer on function does not look like a pure-specifier}}
+
+
+  void k();
+
+public:
+  A(int);
+};
+
+virtual void A::k() { } // expected-error{{'virtual' can only be specified inside the class definition}}
+
+class B : public A {
+  // Needs to recognize that overridden function is virtual.
+  //void g() = 0;
+
+  // Needs to recognize that function does not override.
+  //void g(int) = 0;
+};
+
+// Needs to recognize invalid uses of abstract classes.
+/*
+A fn(A)
+{
+  A a;
+  static_cast<A>(0);
+  try {
+  } catch(A) {
+  }
+}
+*/
diff --git a/test/SemaCXX/warn-assignment-condition.cpp b/test/SemaCXX/warn-assignment-condition.cpp
new file mode 100644
index 0000000..e5a3425
--- /dev/null
+++ b/test/SemaCXX/warn-assignment-condition.cpp
@@ -0,0 +1,98 @@
+// RUN: %clang_cc1 -fsyntax-only -Wparentheses -verify %s
+
+struct A {
+  int foo();
+  friend A operator+(const A&, const A&);
+  operator bool();
+};
+
+void test() {
+  int x, *p;
+  A a, b;
+
+  // With scalars.
+  if (x = 7) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
+                // expected-note{{use '==' to turn this assignment into an equality comparison}} \
+  // expected-note{{place parentheses around the assignment to silence this warning}}
+  if ((x = 7)) {}
+  do {
+  } while (x = 7); // expected-warning {{using the result of an assignment as a condition without parentheses}} \
+                // expected-note{{use '==' to turn this assignment into an equality comparison}} \
+  // expected-note{{place parentheses around the assignment to silence this warning}}
+  do {
+  } while ((x = 7));
+  while (x = 7) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
+                // expected-note{{use '==' to turn this assignment into an equality comparison}} \
+  // expected-note{{place parentheses around the assignment to silence this warning}}
+
+  while ((x = 7)) {}
+  for (; x = 7; ) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
+                // expected-note{{use '==' to turn this assignment into an equality comparison}} \
+  // expected-note{{place parentheses around the assignment to silence this warning}}
+  for (; (x = 7); ) {}
+
+  if (p = p) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
+                // expected-note{{use '==' to turn this assignment into an equality comparison}} \
+  // expected-note{{place parentheses around the assignment to silence this warning}}
+  if ((p = p)) {}
+  do {
+  } while (p = p); // expected-warning {{using the result of an assignment as a condition without parentheses}} \
+                // expected-note{{use '==' to turn this assignment into an equality comparison}} \
+  // expected-note{{place parentheses around the assignment to silence this warning}}
+  do {
+  } while ((p = p));
+  while (p = p) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
+                // expected-note{{use '==' to turn this assignment into an equality comparison}} \
+  // expected-note{{place parentheses around the assignment to silence this warning}}
+  while ((p = p)) {}
+  for (; p = p; ) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
+                // expected-note{{use '==' to turn this assignment into an equality comparison}} \
+  // expected-note{{place parentheses around the assignment to silence this warning}}
+  for (; (p = p); ) {}
+
+  // Initializing variables (shouldn't warn).
+  if (int y = x) {}
+  while (int y = x) {}
+  if (A y = a) {}
+  while (A y = a) {}
+
+  // With temporaries.
+  if (x = (b+b).foo()) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
+                // expected-note{{use '==' to turn this assignment into an equality comparison}} \
+  // expected-note{{place parentheses around the assignment to silence this warning}}
+  if ((x = (b+b).foo())) {}
+  do {
+  } while (x = (b+b).foo()); // expected-warning {{using the result of an assignment as a condition without parentheses}} \
+                // expected-note{{use '==' to turn this assignment into an equality comparison}} \
+  // expected-note{{place parentheses around the assignment to silence this warning}}
+  do {
+  } while ((x = (b+b).foo()));
+  while (x = (b+b).foo()) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
+                // expected-note{{use '==' to turn this assignment into an equality comparison}} \
+  // expected-note{{place parentheses around the assignment to silence this warning}}
+  while ((x = (b+b).foo())) {}
+  for (; x = (b+b).foo(); ) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
+                // expected-note{{use '==' to turn this assignment into an equality comparison}} \
+  // expected-note{{place parentheses around the assignment to silence this warning}}
+  for (; (x = (b+b).foo()); ) {}
+
+  // With a user-defined operator.
+  if (a = b + b) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
+                // expected-note{{use '==' to turn this assignment into an equality comparison}} \
+  // expected-note{{place parentheses around the assignment to silence this warning}}
+  if ((a = b + b)) {}
+  do {
+  } while (a = b + b); // expected-warning {{using the result of an assignment as a condition without parentheses}} \
+                // expected-note{{use '==' to turn this assignment into an equality comparison}} \
+  // expected-note{{place parentheses around the assignment to silence this warning}}
+  do {
+  } while ((a = b + b));
+  while (a = b + b) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
+                // expected-note{{use '==' to turn this assignment into an equality comparison}} \
+  // expected-note{{place parentheses around the assignment to silence this warning}}
+  while ((a = b + b)) {}
+  for (; a = b + b; ) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
+                // expected-note{{use '==' to turn this assignment into an equality comparison}} \
+  // expected-note{{place parentheses around the assignment to silence this warning}}
+  for (; (a = b + b); ) {}
+}
diff --git a/test/SemaCXX/warn-char-subscripts.cpp b/test/SemaCXX/warn-char-subscripts.cpp
new file mode 100644
index 0000000..84ea536
--- /dev/null
+++ b/test/SemaCXX/warn-char-subscripts.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -Wchar-subscripts -fsyntax-only -verify %s
+
+template<typename T>
+void t1() {
+  int array[1] = { 0 };
+  T subscript = 0;
+  int val = array[subscript]; // expected-warning{{array subscript is of type 'char'}}
+}
+
+template<typename T>
+void t2() {
+  int array[1] = { 0 };
+  T subscript = 0;
+  int val = subscript[array]; // expected-warning{{array subscript is of type 'char'}}
+}
+
+void test() {
+  t1<char>(); // expected-note {{in instantiation of function template specialization 't1<char>' requested here}}
+  t2<char>(); // expected-note {{in instantiation of function template specialization 't2<char>' requested here}}
+}
+
diff --git a/test/SemaCXX/warn-for-var-in-else.cpp b/test/SemaCXX/warn-for-var-in-else.cpp
new file mode 100644
index 0000000..1307c43
--- /dev/null
+++ b/test/SemaCXX/warn-for-var-in-else.cpp
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// rdar://6425550
+int bar();
+void do_something(int);
+int *get_ptr();
+
+int foo() {
+  if (int X = bar()) {
+    return X;
+  } else {
+    do_something(X); // expected-warning{{'X' is always zero in this context}}
+    return 0;
+  }
+}
+
+bool foo2() {
+  if (bool B = bar()) {
+    if (int Y = bar()) {
+      return B;
+    } else {
+      do_something(Y); // expected-warning{{'Y' is always zero in this context}}
+      return B;
+    }
+  } else {
+    if (bool B2 = B) { // expected-warning{{'B' is always false in this context}}
+      do_something(B); // expected-warning{{'B' is always false in this context}}
+    } else if (B2) {  // expected-warning{{'B2' is always false in this context}}
+      do_something(B); // expected-warning{{'B' is always false in this context}}
+      do_something(B2); // expected-warning{{'B2' is always false in this context}}
+    }
+    return B; // expected-warning{{'B' is always false in this context}}
+  }
+}
+
+void foo3() {  
+  if (int *P1 = get_ptr())
+    do_something(*P1);
+  else if (int *P2 = get_ptr()) {
+    do_something(*P1); // expected-warning{{'P1' is always NULL in this context}}
+    do_something(*P2);
+  } else {
+    do_something(*P1); // expected-warning{{'P1' is always NULL in this context}}
+    do_something(*P2); // expected-warning{{'P2' is always NULL in this context}}
+  }
+}
diff --git a/test/SemaCXX/warn-missing-noreturn.cpp b/test/SemaCXX/warn-missing-noreturn.cpp
new file mode 100644
index 0000000..5ca2eca
--- /dev/null
+++ b/test/SemaCXX/warn-missing-noreturn.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -Wmissing-noreturn
+void f() __attribute__((noreturn));
+
+template<typename T> void g(T) { // expected-warning {{function could be attribute 'noreturn'}}
+  f();
+}
+
+template void g<int>(int); // expected-note {{in instantiation of function template specialization 'g<int>' requested here}}
+
+template<typename T> struct A {
+  void g() { // expected-warning {{function could be attribute 'noreturn'}}
+    f();
+  }
+};
+
+template struct A<int>; // expected-note {{in instantiation of member function 'A<int>::g' requested here}}
+
+struct B {
+  template<typename T> void g(T) { // expected-warning {{function could be attribute 'noreturn'}}
+    f();
+  }
+};
+
+template void B::g<int>(int); // expected-note {{in instantiation of function template specialization 'B::g<int>' requested here}}
+
+// We don't want a warning here.
+struct X {
+  virtual void g() { f(); }
+};
diff --git a/test/SemaCXX/warn-missing-prototypes.cpp b/test/SemaCXX/warn-missing-prototypes.cpp
new file mode 100644
index 0000000..b6ebe82
--- /dev/null
+++ b/test/SemaCXX/warn-missing-prototypes.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wmissing-prototypes %s
+
+void f() { } // expected-warning {{no previous prototype for function 'f'}}
+
+namespace NS {
+  void f() { } // expected-warning {{no previous prototype for function 'f'}}
+}
+
+namespace {
+  // Don't warn about functions in anonymous namespaces.
+  void f() { }
+}
+
+struct A {
+  // Don't warn about member functions.
+  void f() { }
+};
+
+// Don't warn about inline functions.
+inline void g() { }
+
+// Don't warn about function templates.
+template<typename> void h() { }
+
+// Don't warn when instantiating function templates.
+template void h<int>();
diff --git a/test/SemaCXX/warn-reorder-ctor-initialization.cpp b/test/SemaCXX/warn-reorder-ctor-initialization.cpp
new file mode 100644
index 0000000..3ff01af
--- /dev/null
+++ b/test/SemaCXX/warn-reorder-ctor-initialization.cpp
@@ -0,0 +1,122 @@
+// RUN: %clang_cc1  -fsyntax-only -Wreorder -verify %s
+
+struct BB {};
+
+struct BB1 {};
+
+class complex : public BB, BB1 { 
+public: 
+  complex()
+    : s2(1), // expected-warning {{field 's2' will be initialized after field 's1'}}
+      s1(1),
+      s3(3), // expected-warning {{field 's3' will be initialized after base 'BB1'}} 
+      BB1(), // expected-warning {{base class 'BB1' will be initialized after base 'BB'}}
+      BB()
+  {}
+  int s1;
+  int s2;
+  int s3;
+}; 
+
+
+// testing virtual bases.
+
+
+struct V { 
+  V();
+};
+
+struct A : public virtual V { 
+  A(); 
+};
+
+struct B : public virtual V {
+  B(); 
+};
+
+struct Diamond : public A, public B {
+  Diamond() : A(), B() {}
+};
+
+
+struct C : public A, public B, private virtual V { 
+  C() { }
+};
+
+
+struct D : public A, public B { 
+  D()  : A(), V() {   } // expected-warning {{base class 'A' will be initialized after base 'V'}}
+};
+
+
+struct E : public A, public B, private virtual V { 
+  E()  : A(), V() {  } // expected-warning {{base class 'A' will be initialized after base 'V'}}
+};
+
+
+struct A1  { 
+  A1(); 
+};
+
+struct B1 {
+  B1();
+};
+
+struct F : public A1, public B1, private virtual V { 
+  F()  : A1(), V() {  } // expected-warning {{base class 'A1' will be initialized after base 'V'}}
+};
+
+struct X : public virtual A, virtual V, public virtual B {
+  X(): A(), V(), B() {} // expected-warning {{base class 'A' will be initialized after base 'V'}}
+};
+
+class Anon {
+  int c; union {int a,b;}; int d;
+  Anon() : c(10), b(1), d(2) {}
+};
+class Anon2 {
+  int c; union {int a,b;}; int d;
+  Anon2() : c(2),
+            d(10), // expected-warning {{field 'd' will be initialized after field 'b'}}
+            b(1) {}
+};
+class Anon3 {
+  union {int a,b;};
+  Anon3() : b(1) {}
+};
+
+namespace T1 {
+
+struct S1 { };
+struct S2: virtual S1 { };
+struct S3 { };
+
+struct S4: virtual S3, S2 {
+  S4() : S2(), // expected-warning {{base class 'T1::S2' will be initialized after base 'T1::S3'}}
+    S3() { };
+};
+}
+
+namespace test2 {
+  struct Foo { Foo(); };
+  class A {
+    template <class T> A(T *t) :
+      y(),  // expected-warning {{field 'y' will be initialized after field 'x'}}
+      x()
+    {}
+    Foo x;
+    Foo y;
+  };
+}
+
+// PR6575: this should not crash
+namespace test3 {
+  struct MyClass {
+    MyClass() : m_int(0) {}
+    union {
+      struct {
+        int m_int;
+      };
+    };
+  };
+}
diff --git a/test/SemaCXX/warn-shadow.cpp b/test/SemaCXX/warn-shadow.cpp
new file mode 100644
index 0000000..509c344
--- /dev/null
+++ b/test/SemaCXX/warn-shadow.cpp
@@ -0,0 +1,44 @@
+// RUN: %clang_cc1 -verify -fsyntax-only -Wshadow %s
+
+namespace {
+  int i; // expected-note {{previous declaration is here}}
+}
+
+namespace one {
+namespace two {
+  int j; // expected-note {{previous declaration is here}}
+}
+}
+
+namespace xx {
+  int m;
+}
+namespace yy {
+  int m;
+}
+
+using namespace one::two;
+using namespace xx;
+using namespace yy;
+
+void foo() {
+  int i; // expected-warning {{declaration shadows a variable in namespace '<anonymous>'}}
+  int j; // expected-warning {{declaration shadows a variable in namespace 'one::two'}}
+  int m;
+}
+
+class A {
+  static int data; // expected-note {{previous declaration}}
+  int field; // expected-note {{previous declaration}}
+
+  void test() {
+    char *field; // expected-warning {{declaration shadows a field of 'A'}}
+    char *data; // expected-warning {{declaration shadows a static data member of 'A'}}
+  }
+};
+
+// TODO: this should warn, <rdar://problem/5018057>
+class B : A {
+  int data;
+  static int field;
+};
diff --git a/test/SemaCXX/warn-sign-compare.cpp b/test/SemaCXX/warn-sign-compare.cpp
new file mode 100644
index 0000000..3042bfd
--- /dev/null
+++ b/test/SemaCXX/warn-sign-compare.cpp
@@ -0,0 +1,72 @@
+// RUN: %clang_cc1 -verify -fsyntax-only -Wsign-compare %s
+
+// NOTE: When a 'enumeral mismatch' warning is implemented then expect several
+// of the following cases to be impacted.
+
+// namespace for anonymous enums tests
+namespace test1 {
+  enum { A };
+  enum { B = -1 };
+
+  template <typename T> struct Foo {
+    enum { C };
+    enum { D = ~0U };
+  };
+
+  enum { E = ~0U };
+
+  void doit_anonymous( int i ) {
+    int a1 = 1 ? i : A;
+    int a2 = 1 ? A : i;
+
+    int b1 = 1 ? i : B;
+    int b2 = 1 ? B : i;
+
+    int c1 = 1 ? i : Foo<bool>::C;
+    int c2 = 1 ? Foo<bool>::C : i;
+
+    int d1 = 1 ? i : Foo<bool>::D; // expected-warning {{operands of ? are integers of different signs}}
+    int d2 = 1 ? Foo<bool>::D : i; // expected-warning {{operands of ? are integers of different signs}}
+    int d3 = 1 ? B : Foo<bool>::D; // expected-warning {{operands of ? are integers of different signs}}
+    int d4 = 1 ? Foo<bool>::D : B; // expected-warning {{operands of ? are integers of different signs}}
+
+    int e1 = 1 ? i : E; // expected-warning {{operands of ? are integers of different signs}}
+    int e2 = 1 ? E : i; // expected-warning {{operands of ? are integers of different signs}}
+    int e3 = 1 ? E : B; // expected-warning {{operands of ? are integers of different signs}}
+    int e4 = 1 ? B : E; // expected-warning {{operands of ? are integers of different signs}}
+  }
+}
+
+// namespace for named enums tests
+namespace test2 {
+  enum Named1 { A };
+  enum Named2 { B = -1 };
+
+  template <typename T> struct Foo {
+    enum Named3 { C };
+    enum Named4 { D = ~0U };
+  };
+
+  enum Named5 { E = ~0U };
+
+  void doit_anonymous( int i ) {
+    int a1 = 1 ? i : A;
+    int a2 = 1 ? A : i;
+
+    int b1 = 1 ? i : B;
+    int b2 = 1 ? B : i;
+
+    int c1 = 1 ? i : Foo<bool>::C;
+    int c2 = 1 ? Foo<bool>::C : i;
+
+    int d1 = 1 ? i : Foo<bool>::D; // expected-warning {{operands of ? are integers of different signs}}
+    int d2 = 1 ? Foo<bool>::D : i; // expected-warning {{operands of ? are integers of different signs}}
+    int d3 = 1 ? B : Foo<bool>::D; // expected-warning {{operands of ? are integers of different signs}}
+    int d4 = 1 ? Foo<bool>::D : B; // expected-warning {{operands of ? are integers of different signs}}
+
+    int e1 = 1 ? i : E; // expected-warning {{operands of ? are integers of different signs}}
+    int e2 = 1 ? E : i; // expected-warning {{operands of ? are integers of different signs}}
+    int e3 = 1 ? E : B; // expected-warning {{operands of ? are integers of different signs}}
+    int e4 = 1 ? B : E; // expected-warning {{operands of ? are integers of different signs}}
+  }
+}
diff --git a/test/SemaCXX/warn-unreachable.cpp b/test/SemaCXX/warn-unreachable.cpp
new file mode 100644
index 0000000..01b36de
--- /dev/null
+++ b/test/SemaCXX/warn-unreachable.cpp
@@ -0,0 +1,76 @@
+// RUN: %clang %s -fsyntax-only -Xclang -verify -fblocks -Wunreachable-code -Wno-unused-value
+
+int &halt() __attribute__((noreturn));
+int &live();
+int dead();
+int liveti() throw(int);
+int (*livetip)() throw(int);
+
+int test1() {
+  try {
+    live();
+  } catch (int i) {
+    live();
+  }
+  return 1;
+}
+
+void test2() {
+  try {
+    live();
+  } catch (int i) {
+    live();
+  }
+  try {
+    liveti();
+  } catch (int i) {
+    live();
+  }
+  try {
+    livetip();
+  } catch (int i) {
+    live();
+  }
+  throw 1;
+  dead();       // expected-warning {{will never be executed}}
+}
+
+
+void test3() {
+  halt()
+    --;         // expected-warning {{will never be executed}}
+  halt()
+    ?           // expected-warning {{will never be executed}}
+    dead() : dead();
+  live(),
+    float       // expected-warning {{will never be executed}}
+      (halt());
+}
+
+void test4() {
+  struct S {
+    int mem;
+  } s;
+  S &foor();
+  halt(), foor()// expected-warning {{will never be executed}}
+    .mem;       
+}
+
+void test5() {
+  struct S {
+    int mem;
+  } s;
+  S &foor() __attribute__((noreturn));
+  foor()
+    .mem;       // expected-warning {{will never be executed}}
+}
+
+void test6() {
+  struct S {
+    ~S() { }
+    S(int i) { }
+  };
+  live(),
+    S            // expected-warning {{will never be executed}}
+      (halt());
+}
diff --git a/test/SemaCXX/warn-unused-parameters.cpp b/test/SemaCXX/warn-unused-parameters.cpp
new file mode 100644
index 0000000..75d8dcc
--- /dev/null
+++ b/test/SemaCXX/warn-unused-parameters.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -fsyntax-only -Wunused-parameter -verify %s
+template<typename T>
+struct X {
+  T f0(T x);
+  T f1(T x);
+  T f2(T);
+  template<typename U> U f3(U x);
+  template<typename U> U f4(U x);
+  template<typename U> U f5(U);
+};
+
+template<typename T> T X<T>::f0(T x) { return x; }
+template<typename T> T X<T>::f1(T) { return T(); }
+template<typename T> T X<T>::f2(T x) { return T(); } // expected-warning{{unused parameter 'x'}}
+template<typename T> template<typename U> U X<T>::f3(U x) { return x; }
+template<typename T> template<typename U> U X<T>::f4(U) { return U(); }
+template<typename T> template<typename U> U X<T>::f5(U x) { return U(); } // expected-warning{{unused parameter 'x'}}
+
+void test_X(X<int> &x, int i) {
+  x.f0(i);
+  x.f1(i);
+  x.f2(i);
+  x.f3(i);
+  x.f4(i);
+  x.f5(i);
+}
diff --git a/test/SemaCXX/warn-unused-value.cpp b/test/SemaCXX/warn-unused-value.cpp
new file mode 100644
index 0000000..775c3cf
--- /dev/null
+++ b/test/SemaCXX/warn-unused-value.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wunused-value %s
+
+// PR4806
+namespace test0 {
+  class Box {
+  public:
+    int i;
+    volatile int j;
+  };
+
+  void doit() {
+    // pointer to volatile has side effect (thus no warning)
+    Box* box = new Box;
+    box->i; // expected-warning {{expression result unused}}
+    box->j;
+  }
+}
diff --git a/test/SemaCXX/warn-unused-variables.cpp b/test/SemaCXX/warn-unused-variables.cpp
new file mode 100644
index 0000000..3b5349a
--- /dev/null
+++ b/test/SemaCXX/warn-unused-variables.cpp
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 -fsyntax-only -Wunused-variable -verify %s
+template<typename T> void f() {
+  T t;
+  t = 17;
+}
+
+// PR5407
+struct A { A(); };
+struct B { ~B(); };
+void f() {
+  A a;
+  B b;
+}
+
+// PR5531
+namespace PR5531 {
+  struct A {
+  };
+
+  struct B {
+    B(int);
+  };
+
+  struct C {
+    ~C();
+  };
+
+  void test() {
+    A(); // expected-warning{{expression result unused}}
+    B(17);
+    C();
+  }
+}
+
+
+struct X {
+ int foo() __attribute__((warn_unused_result));
+};
+
+void bah() {
+  X x, *x2;
+  x.foo(); // expected-warning {{ignoring return value of function declared with warn_unused_result attribute}}
+  x2->foo(); // expected-warning {{ignoring return value of function declared with warn_unused_result attribute}}
+}
+
+template<typename T>
+struct X0 { };
+
+template<typename T>
+void test_dependent_init(T *p) {
+  X0<int> i(p);
+  (void)i;
+}
diff --git a/test/SemaCXX/warn-weak-vtables.cpp b/test/SemaCXX/warn-weak-vtables.cpp
new file mode 100644
index 0000000..39333c1
--- /dev/null
+++ b/test/SemaCXX/warn-weak-vtables.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify -Wweak-vtables
+
+struct A { // expected-warning {{'A' has no out-of-line virtual method definitions; its vtable will be emitted in every translation unit}}
+  virtual void f() { } 
+};
+
+template<typename T> struct B {
+  virtual void f() { } 
+};
+
+namespace {
+  struct C { 
+    virtual void f() { }
+  };
+}
+
+void f() {
+  struct A {
+    virtual void f() { }
+  };
+}
diff --git a/test/SemaCXX/wchar_t.cpp b/test/SemaCXX/wchar_t.cpp
new file mode 100644
index 0000000..789dbf6
--- /dev/null
+++ b/test/SemaCXX/wchar_t.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -fsyntax-only -pedantic -verify %s 
+wchar_t x;
+
+void f(wchar_t p) {
+  wchar_t x;
+  unsigned wchar_t y; // expected-warning {{'wchar_t' cannot be signed or unsigned}}
+  signed wchar_t z; // expected-warning {{'wchar_t' cannot be signed or unsigned}}
+  ++x;
+}
+
+// PR4502
+wchar_t const c = L'c';
+int a[c == L'c' ? 1 : -1];
+
+
+// PR5917
+template<typename _CharT>
+struct basic_string {
+};
+
+template<typename _CharT>
+basic_string<_CharT> operator+ (const basic_string<_CharT>&, _CharT);
+
+int t(void) {
+  basic_string<wchar_t>() + L'-';
+  return (0);
+}
diff --git a/test/SemaObjC/ContClassPropertyLookup.m b/test/SemaObjC/ContClassPropertyLookup.m
new file mode 100644
index 0000000..b3459c1
--- /dev/null
+++ b/test/SemaObjC/ContClassPropertyLookup.m
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1  -fsyntax-only -verify %s
+
+@interface MyObject {
+    int _foo;
+}
+@end
+
+@interface MyObject(whatever)
+@property (assign) int foo;
+@end
+
+@interface MyObject()
+@property (assign) int foo;
+@end
+
+@implementation MyObject
+@synthesize foo = _foo;
+@end
diff --git a/test/SemaObjC/DoubleMethod.m b/test/SemaObjC/DoubleMethod.m
new file mode 100644
index 0000000..98aa699
--- /dev/null
+++ b/test/SemaObjC/DoubleMethod.m
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@interface Subclass
+{
+    int ivar;
+}
+
+- (void) method;
+- (void) method;
+@end
+
+@implementation Subclass
+- (void) method {;} // expected-note {{previous declaration is here}}
+- (void) method {;} // expected-error {{duplicate declaration of method 'method'}}
+@end
+
+int main (void) {
+    return 0;
+}
diff --git a/test/SemaObjC/access-property-getter.m b/test/SemaObjC/access-property-getter.m
new file mode 100644
index 0000000..331bb30
--- /dev/null
+++ b/test/SemaObjC/access-property-getter.m
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -verify %s
+
+@protocol NSObject
+- (oneway void)release;
+@end
+
+@protocol XCOutputStreams <NSObject>
+@end
+
+
+@interface XCWorkQueueCommandInvocation 
+{
+    id <XCOutputStreams> _outputStream;
+}
+@end
+
+@interface XCWorkQueueCommandSubprocessInvocation : XCWorkQueueCommandInvocation
+@end
+
+@interface XCWorkQueueCommandLocalSubprocessInvocation : XCWorkQueueCommandSubprocessInvocation
+@end
+
+@interface XCWorkQueueCommandDistributedSubprocessInvocation : XCWorkQueueCommandSubprocessInvocation
+@end
+
+@interface XCWorkQueueCommandCacheFetchInvocation : XCWorkQueueCommandSubprocessInvocation
+
+@end
+
+@implementation XCWorkQueueCommandCacheFetchInvocation
+- (id)harvestPredictivelyProcessedOutputFiles
+{
+     _outputStream.release;
+     return 0;
+}
+@end
diff --git a/test/SemaObjC/alias-test-1.m b/test/SemaObjC/alias-test-1.m
new file mode 100644
index 0000000..2cea115
--- /dev/null
+++ b/test/SemaObjC/alias-test-1.m
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@compatibility_alias alias4 foo; // expected-warning {{cannot find interface declaration for 'foo'}}
+
+@class class2; // expected-note {{previous declaration is here}}
+@class class3;
+
+typedef int I;  // expected-note {{previous declaration is here}}
+
+@compatibility_alias alias1 I;  // expected-warning {{cannot find interface declaration for 'I'}}
+
+@compatibility_alias alias class2;     
+@compatibility_alias alias class3;   // expected-error {{conflicting types for alias 'alias'}}
+
+
+typedef int alias2;	// expected-note {{previous declaration is here}}
+@compatibility_alias alias2 class3;  // expected-error {{conflicting types for alias 'alias2'}}
+
+alias *p;
+class2 *p2;
+
+int foo ()
+{
+
+	if (p == p2) {
+	  int alias = 1;
+	}
+
+	alias *p3;
+	return p3 == p2;
+}
diff --git a/test/SemaObjC/alias-test-2.m b/test/SemaObjC/alias-test-2.m
new file mode 100644
index 0000000..1f12b76
--- /dev/null
+++ b/test/SemaObjC/alias-test-2.m
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// Note: GCC doesn't produce any of the following errors.
+@interface Super @end // expected-note {{previous definition is here}}
+
+@interface MyWpModule @end  // expected-note {{previous definition is here}}
+
+@compatibility_alias  MyAlias MyWpModule;
+
+@compatibility_alias  AliasForSuper Super;
+
+@interface MyAlias : AliasForSuper // expected-error {{duplicate interface definition for class 'MyWpModule'}}
+@end
+
+@implementation MyAlias : AliasForSuper // expected-error {{conflicting super class name 'Super'}}
+@end
+
diff --git a/test/SemaObjC/argument-checking.m b/test/SemaObjC/argument-checking.m
new file mode 100644
index 0000000..9019a0f
--- /dev/null
+++ b/test/SemaObjC/argument-checking.m
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s
+
+struct S { int a; };
+
+extern int charStarFunc(char *); // expected-note{{passing argument to parameter here}}
+extern int charFunc(char); // expected-note{{passing argument to parameter here}}
+
+@interface Test
++alloc;
+-(int)charStarMeth:(char *)s; // expected-note{{passing argument to parameter 's' here}}
+-structMeth:(struct S)s; // expected-note{{passing argument to parameter 's' here}}
+-structMeth:(struct S)s 
+   :(struct S)s2; // expected-note{{passing argument to parameter 's2' here}}
+@end
+
+void test() {
+  id obj = [Test alloc];
+  struct S sInst;
+
+  charStarFunc(1); // expected-warning {{incompatible integer to pointer conversion passing 'int' to parameter of type 'char *'}}
+  charFunc("abc"); // expected-warning {{incompatible pointer to integer conversion passing 'char [4]' to parameter of type 'char'}}
+
+  [obj charStarMeth:1]; // expected-warning {{incompatible integer to pointer conversion sending 'int'}}
+  [obj structMeth:1]; // expected-error {{sending 'int'}}
+  [obj structMeth:sInst :1]; // expected-error {{sending 'int'}}
+}
diff --git a/test/SemaObjC/at-defs.m b/test/SemaObjC/at-defs.m
new file mode 100644
index 0000000..bfa2123
--- /dev/null
+++ b/test/SemaObjC/at-defs.m
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown %s -fsyntax-only
+
+@interface Test {
+	double a;
+}
+@end
+@implementation Test
+@end
+@interface TestObject : Test {
+@public
+  float bar;
+  int foo;
+}
+@end
+@implementation TestObject
+@end
+struct wibble {
+  @defs(TestObject)
+};
+
+
+int main(void)
+{
+	TestObject * a = (id)malloc(100);
+	a->foo = 12;
+	printf("12: %d\n", ((struct wibble*)a)->foo);
+	printf("%d: %d\n", ((char*)&(((struct wibble*)a)->foo)) - (char*)a, ((char*)&(a->foo)) - (char*)a);
+	return 0;
+}
diff --git a/test/SemaObjC/atomoic-property-synnthesis-rules.m b/test/SemaObjC/atomoic-property-synnthesis-rules.m
new file mode 100644
index 0000000..af790e3
--- /dev/null
+++ b/test/SemaObjC/atomoic-property-synnthesis-rules.m
@@ -0,0 +1,369 @@
+// RUN: %clang_cc1  -fsyntax-only -verify %s
+
+/*
+  Conditions for warning:
+  1. the property is atomic
+  2. the current @implementation contains an @synthesize for the property
+  3. the current @implementation contains a hand-written setter XOR getter
+  4. the property is read-write
+  
+  Cases marked WARN should warn one the following:
+  warning: Atomic property 'x' has a synthesized setter and a 
+  manually-implemented getter, which may break atomicity.
+  warning: Atomic property 'x' has a synthesized getter and a 
+  manually-implemented setter, which may break atomicity.
+  
+  Cases not marked WARN only satisfy the indicated subset 
+  of the conditions required to warn.
+
+  There should be 8 warnings.
+*/
+
+@interface Foo 
+{
+    /* 12 4 */    int GetSet;
+    /* WARN */    int Get;
+    /* WARN */    int Set;
+    /* 12 4 */    int None;
+    /*  2 4 */    int GetSet_Nonatomic;
+    /*  234 */    int Get_Nonatomic;
+    /*  234 */    int Set_Nonatomic;
+    /*  2 4 */    int None_Nonatomic;
+
+    /* 12   */    int GetSet_ReadOnly;
+    /* 123  */    int Get_ReadOnly;
+    /* 123  */    int Set_ReadOnly;
+    /* 12   */    int None_ReadOnly;
+    /*  2   */    int GetSet_Nonatomic_ReadOnly;
+    /*  23  */    int Get_Nonatomic_ReadOnly;
+    /*  23  */    int Set_Nonatomic_ReadOnly;
+    /*  2   */    int None_Nonatomic_ReadOnly;
+
+    /* 12 4 */    int GetSet_ReadWriteInExt;
+    /* WARN */    int Get_ReadWriteInExt;
+    /* WARN */    int Set_ReadWriteInExt;
+    /* 12 4 */    int None_ReadWriteInExt;
+    /*  2 4 */    int GetSet_Nonatomic_ReadWriteInExt;
+    /*  234 */    int Get_Nonatomic_ReadWriteInExt;
+    /*  234 */    int Set_Nonatomic_ReadWriteInExt;
+    /*  2 4 */    int None_Nonatomic_ReadWriteInExt;
+
+
+    /* 12 4 */    int GetSet_LateSynthesize;
+    /* WARN */    int Get_LateSynthesize;
+    /* WARN */    int Set_LateSynthesize;
+    /* 12 4 */    int None_LateSynthesize;
+    /*  2 4 */    int GetSet_Nonatomic_LateSynthesize;
+    /*  234 */    int Get_Nonatomic_LateSynthesize;
+    /*  234 */    int Set_Nonatomic_LateSynthesize;
+    /*  2 4 */    int None_Nonatomic_LateSynthesize;
+
+    /* 12   */    int GetSet_ReadOnly_LateSynthesize;
+    /* 123  */    int Get_ReadOnly_LateSynthesize;
+    /* 123  */    int Set_ReadOnly_LateSynthesize;
+    /* 12   */    int None_ReadOnly_LateSynthesize;
+    /*  2   */    int GetSet_Nonatomic_ReadOnly_LateSynthesize;
+    /*  23  */    int Get_Nonatomic_ReadOnly_LateSynthesize;
+    /*  23  */    int Set_Nonatomic_ReadOnly_LateSynthesize;
+    /*  2   */    int None_Nonatomic_ReadOnly_LateSynthesize;
+
+    /* 12 4 */    int GetSet_ReadWriteInExt_LateSynthesize;
+    /* WARN */    int Get_ReadWriteInExt_LateSynthesize;
+    /* WARN */    int Set_ReadWriteInExt_LateSynthesize;
+    /* 12 4 */    int None_ReadWriteInExt_LateSynthesize;
+    /*  2 4 */    int GetSet_Nonatomic_ReadWriteInExt_LateSynthesize;
+    /*  234 */    int Get_Nonatomic_ReadWriteInExt_LateSynthesize;
+    /*  234 */    int Set_Nonatomic_ReadWriteInExt_LateSynthesize;
+    /*  2 4 */    int None_Nonatomic_ReadWriteInExt_LateSynthesize;
+
+
+    /* 1  4 */    int GetSet_NoSynthesize;
+    /* 1 34 */    int Get_NoSynthesize;
+    /* 1 34 */    int Set_NoSynthesize;
+    /* 1  4 */    int None_NoSynthesize;
+    /*    4 */    int GetSet_Nonatomic_NoSynthesize;
+    /*   34 */    int Get_Nonatomic_NoSynthesize;
+    /*   34 */    int Set_Nonatomic_NoSynthesize;
+    /*    4 */    int None_Nonatomic_NoSynthesize;
+
+    /* 1    */    int GetSet_ReadOnly_NoSynthesize;
+    /* 1 3  */    int Get_ReadOnly_NoSynthesize;
+    /* 1 3  */    int Set_ReadOnly_NoSynthesize;
+    /* 1    */    int None_ReadOnly_NoSynthesize;
+    /*      */    int GetSet_Nonatomic_ReadOnly_NoSynthesize;
+    /*   3  */    int Get_Nonatomic_ReadOnly_NoSynthesize;
+    /*   3  */    int Set_Nonatomic_ReadOnly_NoSynthesize;
+    /*      */    int None_Nonatomic_ReadOnly_NoSynthesize;
+
+    /* 1  4 */    int GetSet_ReadWriteInExt_NoSynthesize;
+    /* 1 34 */    int Get_ReadWriteInExt_NoSynthesize;
+    /* 1 34 */    int Set_ReadWriteInExt_NoSynthesize;
+    /* 1  4 */    int None_ReadWriteInExt_NoSynthesize;
+    /*    4 */    int GetSet_Nonatomic_ReadWriteInExt_NoSynthesize;
+    /*   34 */    int Get_Nonatomic_ReadWriteInExt_NoSynthesize;
+    /*   34 */    int Set_Nonatomic_ReadWriteInExt_NoSynthesize;
+    /*    4 */    int None_Nonatomic_ReadWriteInExt_NoSynthesize;
+}
+
+// read-write - might warn
+@property int GetSet;
+@property int Get;	// expected-note {{property declared here}}
+@property int Set;	// expected-note {{property declared here}}
+@property int None;
+@property(nonatomic) int GetSet_Nonatomic;
+@property(nonatomic) int Get_Nonatomic;
+@property(nonatomic) int Set_Nonatomic;
+@property(nonatomic) int None_Nonatomic;
+
+// read-only - must not warn
+@property(readonly) int GetSet_ReadOnly;
+@property(readonly) int Get_ReadOnly;
+@property(readonly) int Set_ReadOnly;
+@property(readonly) int None_ReadOnly;
+@property(nonatomic,readonly) int GetSet_Nonatomic_ReadOnly;
+@property(nonatomic,readonly) int Get_Nonatomic_ReadOnly;
+@property(nonatomic,readonly) int Set_Nonatomic_ReadOnly;
+@property(nonatomic,readonly) int None_Nonatomic_ReadOnly;
+
+// read-only in class, read-write in class extension - might warn
+@property(readonly) int GetSet_ReadWriteInExt;
+@property(readonly) int Get_ReadWriteInExt;	// expected-note {{property declared here}}
+@property(readonly) int Set_ReadWriteInExt;	// expected-note {{property declared here}}
+@property(readonly) int None_ReadWriteInExt;
+@property(nonatomic,readonly) int GetSet_Nonatomic_ReadWriteInExt;
+@property(nonatomic,readonly) int Get_Nonatomic_ReadWriteInExt;
+@property(nonatomic,readonly) int Set_Nonatomic_ReadWriteInExt;
+@property(nonatomic,readonly) int None_Nonatomic_ReadWriteInExt;
+
+
+// same as above, but @synthesize follows the hand-written methods - might warn
+@property int GetSet_LateSynthesize;
+@property int Get_LateSynthesize;	// expected-note {{property declared here}}
+@property int Set_LateSynthesize;	// expected-note {{property declared here}}
+@property int None_LateSynthesize;
+@property(nonatomic) int GetSet_Nonatomic_LateSynthesize;
+@property(nonatomic) int Get_Nonatomic_LateSynthesize;
+@property(nonatomic) int Set_Nonatomic_LateSynthesize;
+@property(nonatomic) int None_Nonatomic_LateSynthesize;
+
+@property(readonly) int GetSet_ReadOnly_LateSynthesize;
+@property(readonly) int Get_ReadOnly_LateSynthesize;
+@property(readonly) int Set_ReadOnly_LateSynthesize;
+@property(readonly) int None_ReadOnly_LateSynthesize;
+@property(nonatomic,readonly) int GetSet_Nonatomic_ReadOnly_LateSynthesize;
+@property(nonatomic,readonly) int Get_Nonatomic_ReadOnly_LateSynthesize;
+@property(nonatomic,readonly) int Set_Nonatomic_ReadOnly_LateSynthesize;
+@property(nonatomic,readonly) int None_Nonatomic_ReadOnly_LateSynthesize;
+
+@property(readonly) int GetSet_ReadWriteInExt_LateSynthesize;
+@property(readonly) int Get_ReadWriteInExt_LateSynthesize;	// expected-note {{property declared here}}
+@property(readonly) int Set_ReadWriteInExt_LateSynthesize;	// expected-note {{property declared here}}
+@property(readonly) int None_ReadWriteInExt_LateSynthesize;
+@property(nonatomic,readonly) int GetSet_Nonatomic_ReadWriteInExt_LateSynthesize;
+@property(nonatomic,readonly) int Get_Nonatomic_ReadWriteInExt_LateSynthesize;
+@property(nonatomic,readonly) int Set_Nonatomic_ReadWriteInExt_LateSynthesize;
+@property(nonatomic,readonly) int None_Nonatomic_ReadWriteInExt_LateSynthesize;
+
+
+// same as above, but with no @synthesize - must not warn
+@property int GetSet_NoSynthesize;
+@property int Get_NoSynthesize;
+@property int Set_NoSynthesize;
+@property int None_NoSynthesize;
+@property(nonatomic) int GetSet_Nonatomic_NoSynthesize;
+@property(nonatomic) int Get_Nonatomic_NoSynthesize;
+@property(nonatomic) int Set_Nonatomic_NoSynthesize;
+@property(nonatomic) int None_Nonatomic_NoSynthesize;
+
+@property(readonly) int GetSet_ReadOnly_NoSynthesize;
+@property(readonly) int Get_ReadOnly_NoSynthesize;
+@property(readonly) int Set_ReadOnly_NoSynthesize;
+@property(readonly) int None_ReadOnly_NoSynthesize;
+@property(nonatomic,readonly) int GetSet_Nonatomic_ReadOnly_NoSynthesize;
+@property(nonatomic,readonly) int Get_Nonatomic_ReadOnly_NoSynthesize;
+@property(nonatomic,readonly) int Set_Nonatomic_ReadOnly_NoSynthesize;
+@property(nonatomic,readonly) int None_Nonatomic_ReadOnly_NoSynthesize;
+
+@property(readonly) int GetSet_ReadWriteInExt_NoSynthesize;
+@property(readonly) int Get_ReadWriteInExt_NoSynthesize;
+@property(readonly) int Set_ReadWriteInExt_NoSynthesize;
+@property(readonly) int None_ReadWriteInExt_NoSynthesize;
+@property(nonatomic,readonly) int GetSet_Nonatomic_ReadWriteInExt_NoSynthesize;
+@property(nonatomic,readonly) int Get_Nonatomic_ReadWriteInExt_NoSynthesize;
+@property(nonatomic,readonly) int Set_Nonatomic_ReadWriteInExt_NoSynthesize;
+@property(nonatomic,readonly) int None_Nonatomic_ReadWriteInExt_NoSynthesize;
+
+@end
+
+
+@interface Foo ()
+
+@property(readwrite) int GetSet_ReadWriteInExt;
+@property(readwrite) int Get_ReadWriteInExt;
+@property(readwrite) int Set_ReadWriteInExt;
+@property(readwrite) int None_ReadWriteInExt;
+@property(nonatomic,readwrite) int GetSet_Nonatomic_ReadWriteInExt;
+@property(nonatomic,readwrite) int Get_Nonatomic_ReadWriteInExt;
+@property(nonatomic,readwrite) int Set_Nonatomic_ReadWriteInExt;
+@property(nonatomic,readwrite) int None_Nonatomic_ReadWriteInExt;
+
+@property(readwrite) int GetSet_ReadWriteInExt_LateSynthesize;
+@property(readwrite) int Get_ReadWriteInExt_LateSynthesize;
+@property(readwrite) int Set_ReadWriteInExt_LateSynthesize;
+@property(readwrite) int None_ReadWriteInExt_LateSynthesize;
+@property(nonatomic,readwrite) int GetSet_Nonatomic_ReadWriteInExt_LateSynthesize;
+@property(nonatomic,readwrite) int Get_Nonatomic_ReadWriteInExt_LateSynthesize;
+@property(nonatomic,readwrite) int Set_Nonatomic_ReadWriteInExt_LateSynthesize;
+@property(nonatomic,readwrite) int None_Nonatomic_ReadWriteInExt_LateSynthesize;
+
+@property(readwrite) int GetSet_ReadWriteInExt_NoSynthesize;
+@property(readwrite) int Get_ReadWriteInExt_NoSynthesize;
+@property(readwrite) int Set_ReadWriteInExt_NoSynthesize;
+@property(readwrite) int None_ReadWriteInExt_NoSynthesize;
+@property(nonatomic,readwrite) int GetSet_Nonatomic_ReadWriteInExt_NoSynthesize;
+@property(nonatomic,readwrite) int Get_Nonatomic_ReadWriteInExt_NoSynthesize;
+@property(nonatomic,readwrite) int Set_Nonatomic_ReadWriteInExt_NoSynthesize;
+@property(nonatomic,readwrite) int None_Nonatomic_ReadWriteInExt_NoSynthesize;
+
+@end
+
+@implementation Foo
+
+@synthesize GetSet, Get, Set, None, GetSet_Nonatomic, Get_Nonatomic, Set_Nonatomic, None_Nonatomic;
+@synthesize GetSet_ReadOnly, Get_ReadOnly, Set_ReadOnly, None_ReadOnly, GetSet_Nonatomic_ReadOnly, Get_Nonatomic_ReadOnly, Set_Nonatomic_ReadOnly, None_Nonatomic_ReadOnly;
+@synthesize GetSet_ReadWriteInExt, Get_ReadWriteInExt, Set_ReadWriteInExt, None_ReadWriteInExt, GetSet_Nonatomic_ReadWriteInExt, Get_Nonatomic_ReadWriteInExt, Set_Nonatomic_ReadWriteInExt, None_Nonatomic_ReadWriteInExt;
+
+#define GET(x) \
+    -(int) x { return self->x; }  
+#define SET(x) \
+    -(void) set##x:(int)value { self->x = value; }  
+
+GET(GetSet)
+SET(GetSet)
+GET(Get) // expected-warning {{writable atomic property 'Get' cannot pair a synthesized setter/getter with a user defined setter/getter}}
+SET(Set) // expected-warning {{writable atomic property 'Set' cannot pair a synthesized setter/getter with a user defined setter/getter}}
+GET(GetSet_Nonatomic)
+SET(GetSet_Nonatomic)
+GET(Get_Nonatomic)
+SET(Set_Nonatomic)
+
+GET(GetSet_ReadOnly)
+SET(GetSet_ReadOnly)
+GET(Get_ReadOnly)
+SET(Set_ReadOnly)
+GET(GetSet_Nonatomic_ReadOnly)
+SET(GetSet_Nonatomic_ReadOnly)
+GET(Get_Nonatomic_ReadOnly)
+SET(Set_Nonatomic_ReadOnly)
+
+GET(GetSet_ReadWriteInExt)
+SET(GetSet_ReadWriteInExt)
+GET(Get_ReadWriteInExt) // expected-warning {{writable atomic property 'Get_ReadWriteInExt' cannot pair a synthesized setter/getter with a user defined setter/getter}}
+SET(Set_ReadWriteInExt) // expected-warning {{writable atomic property 'Set_ReadWriteInExt' cannot pair a synthesized setter/getter with a user defined setter/getter}}
+GET(GetSet_Nonatomic_ReadWriteInExt)
+SET(GetSet_Nonatomic_ReadWriteInExt)
+GET(Get_Nonatomic_ReadWriteInExt)
+SET(Set_Nonatomic_ReadWriteInExt)
+
+
+GET(GetSet_LateSynthesize)
+SET(GetSet_LateSynthesize)
+GET(Get_LateSynthesize) // expected-warning {{writable atomic property 'Get_LateSynthesize' cannot pair a synthesized setter/getter with a user defined setter/getter}}
+SET(Set_LateSynthesize) // expected-warning {{writable atomic property 'Set_LateSynthesize' cannot pair a synthesized setter/getter with a user defined setter/getter}}
+GET(GetSet_Nonatomic_LateSynthesize)
+SET(GetSet_Nonatomic_LateSynthesize)
+GET(Get_Nonatomic_LateSynthesize)
+SET(Set_Nonatomic_LateSynthesize)
+
+GET(GetSet_ReadOnly_LateSynthesize)
+SET(GetSet_ReadOnly_LateSynthesize)
+GET(Get_ReadOnly_LateSynthesize)
+SET(Set_ReadOnly_LateSynthesize)
+GET(GetSet_Nonatomic_ReadOnly_LateSynthesize)
+SET(GetSet_Nonatomic_ReadOnly_LateSynthesize)
+GET(Get_Nonatomic_ReadOnly_LateSynthesize)
+SET(Set_Nonatomic_ReadOnly_LateSynthesize)
+
+GET(GetSet_ReadWriteInExt_LateSynthesize)
+SET(GetSet_ReadWriteInExt_LateSynthesize)
+GET(Get_ReadWriteInExt_LateSynthesize) // expected-warning {{writable atomic property 'Get_ReadWriteInExt_LateSynthesize' cannot pair a synthesized setter/getter with a user defined setter/getter}}
+SET(Set_ReadWriteInExt_LateSynthesize) // expected-warning {{writable atomic property 'Set_ReadWriteInExt_LateSynthesize' cannot pair a synthesized setter/getter with a user defined setter/getter}}
+GET(GetSet_Nonatomic_ReadWriteInExt_LateSynthesize)
+SET(GetSet_Nonatomic_ReadWriteInExt_LateSynthesize)
+GET(Get_Nonatomic_ReadWriteInExt_LateSynthesize)
+SET(Set_Nonatomic_ReadWriteInExt_LateSynthesize)
+
+
+GET(GetSet_NoSynthesize)
+SET(GetSet_NoSynthesize)
+GET(Get_NoSynthesize)
+SET(Set_NoSynthesize)
+GET(GetSet_Nonatomic_NoSynthesize)
+SET(GetSet_Nonatomic_NoSynthesize)
+GET(Get_Nonatomic_NoSynthesize)
+SET(Set_Nonatomic_NoSynthesize)
+
+GET(GetSet_ReadOnly_NoSynthesize)
+SET(GetSet_ReadOnly_NoSynthesize)
+GET(Get_ReadOnly_NoSynthesize)
+SET(Set_ReadOnly_NoSynthesize)
+GET(GetSet_Nonatomic_ReadOnly_NoSynthesize)
+SET(GetSet_Nonatomic_ReadOnly_NoSynthesize)
+GET(Get_Nonatomic_ReadOnly_NoSynthesize)
+SET(Set_Nonatomic_ReadOnly_NoSynthesize)
+
+GET(GetSet_ReadWriteInExt_NoSynthesize)
+SET(GetSet_ReadWriteInExt_NoSynthesize)
+GET(Get_ReadWriteInExt_NoSynthesize)
+SET(Set_ReadWriteInExt_NoSynthesize)
+GET(GetSet_Nonatomic_ReadWriteInExt_NoSynthesize)
+SET(GetSet_Nonatomic_ReadWriteInExt_NoSynthesize)
+GET(Get_Nonatomic_ReadWriteInExt_NoSynthesize)
+SET(Set_Nonatomic_ReadWriteInExt_NoSynthesize)
+
+
+// late synthesize - follows getter/setter implementations
+
+@synthesize GetSet_LateSynthesize, Get_LateSynthesize, Set_LateSynthesize, None_LateSynthesize, GetSet_Nonatomic_LateSynthesize, Get_Nonatomic_LateSynthesize, Set_Nonatomic_LateSynthesize, None_Nonatomic_LateSynthesize;
+@synthesize GetSet_ReadOnly_LateSynthesize, Get_ReadOnly_LateSynthesize, Set_ReadOnly_LateSynthesize, None_ReadOnly_LateSynthesize, GetSet_Nonatomic_ReadOnly_LateSynthesize, Get_Nonatomic_ReadOnly_LateSynthesize, Set_Nonatomic_ReadOnly_LateSynthesize, None_Nonatomic_ReadOnly_LateSynthesize;
+@synthesize GetSet_ReadWriteInExt_LateSynthesize, Get_ReadWriteInExt_LateSynthesize, Set_ReadWriteInExt_LateSynthesize, None_ReadWriteInExt_LateSynthesize, GetSet_Nonatomic_ReadWriteInExt_LateSynthesize, Get_Nonatomic_ReadWriteInExt_LateSynthesize, Set_Nonatomic_ReadWriteInExt_LateSynthesize, None_Nonatomic_ReadWriteInExt_LateSynthesize;
+
+// no synthesize - use dynamic instead
+
+@dynamic GetSet_NoSynthesize, Get_NoSynthesize, Set_NoSynthesize, None_NoSynthesize, GetSet_Nonatomic_NoSynthesize, Get_Nonatomic_NoSynthesize, Set_Nonatomic_NoSynthesize, None_Nonatomic_NoSynthesize;
+@dynamic GetSet_ReadOnly_NoSynthesize, Get_ReadOnly_NoSynthesize, Set_ReadOnly_NoSynthesize, None_ReadOnly_NoSynthesize, GetSet_Nonatomic_ReadOnly_NoSynthesize, Get_Nonatomic_ReadOnly_NoSynthesize, Set_Nonatomic_ReadOnly_NoSynthesize, None_Nonatomic_ReadOnly_NoSynthesize;
+@dynamic GetSet_ReadWriteInExt_NoSynthesize, Get_ReadWriteInExt_NoSynthesize, Set_ReadWriteInExt_NoSynthesize, None_ReadWriteInExt_NoSynthesize, GetSet_Nonatomic_ReadWriteInExt_NoSynthesize, Get_Nonatomic_ReadWriteInExt_NoSynthesize, Set_Nonatomic_ReadWriteInExt_NoSynthesize, None_Nonatomic_ReadWriteInExt_NoSynthesize;
+
+@end
+
+/*
+// the following method should cause a warning along the lines of
+// :warning: Atomic property 'x' cannot pair a synthesized setter/getter with a manually implemented setter/getter
+- (void) setX: (int) aValue
+{
+    x = aValue;
+}
+
+// no warning 'cause this is nonatomic
+- (void) setY: (int) aValue
+{
+    y = aValue;
+}
+
+// the following method should cause a warning along the lines of
+// :warning: Atomic property 'x' cannot pair a synthesized setter/getter with a manually implemented setter/getter
+- (int) j
+{
+    return j;
+}
+
+// no warning 'cause this is nonatomic
+- (int) k
+{
+    return k;
+}
+@end
+*/
+int main (int argc, const char * argv[]) {
+    return 0;
+}
diff --git a/test/SemaObjC/attr-cleanup.m b/test/SemaObjC/attr-cleanup.m
new file mode 100644
index 0000000..8415c69
--- /dev/null
+++ b/test/SemaObjC/attr-cleanup.m
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only
+
+@class NSString;
+
+void c1(id *a);
+
+void t1()
+{
+  NSString *s __attribute((cleanup(c1)));
+}
diff --git a/test/SemaObjC/attr-deprecated.m b/test/SemaObjC/attr-deprecated.m
new file mode 100644
index 0000000..a58068b
--- /dev/null
+++ b/test/SemaObjC/attr-deprecated.m
@@ -0,0 +1,99 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify
+
+@interface A {
+  int X __attribute__((deprecated));
+}
++ (void)F __attribute__((deprecated));
+- (void)f __attribute__((deprecated));
+@end
+
+@implementation A
++ (void)F __attribute__((deprecated))
+{	// expected-warning {{method attribute can only be specified on method declarations}}
+  [self F]; // no warning, since the caller is also deprecated.
+}
+
+- (void)g
+{
+  X++;        // expected-warning{{'X' is deprecated}}
+  self->X++;  // expected-warning{{'X' is deprecated}}
+  [self f]; // expected-warning{{'f' is deprecated}}
+}
+
+- (void)f
+{
+  [self f]; // no warning, the caller is deprecated in its interface.
+}
+@end
+
+@interface B: A
+@end
+  
+@implementation B
++ (void)G
+{
+  [super F]; // expected-warning{{'F' is deprecated}}
+}
+
+- (void)g
+{
+  [super f]; // // expected-warning{{'f' is deprecated}}
+}
+@end
+
+@protocol P
+- (void)p __attribute__((deprecated));
+@end
+
+void t1(A *a)
+{
+  [A F]; // expected-warning{{'F' is deprecated}}
+  [a f]; // expected-warning{{'f' is deprecated}}
+}
+
+void t2(id a)
+{
+  [a f];
+}
+
+void t3(A<P>* a)
+{
+  [a f]; // expected-warning{{'f' is deprecated}}
+  [a p]; // expected-warning{{'p' is deprecated}}
+} 
+
+void t4(Class c)
+{
+  [c F];
+}
+
+
+
+@interface Bar 
+
+@property (assign, setter = MySetter:) int FooBar __attribute__ ((deprecated));
+- (void) MySetter : (int) value;
+@end
+
+int t5() {
+  Bar *f;
+  f.FooBar = 1;	   // expected-warning {{warning: 'FooBar' is deprecated}}
+  return f.FooBar; // expected-warning {{warning: 'FooBar' is deprecated}}
+}
+
+
+__attribute ((deprecated))  
+@interface DEPRECATED {
+  @public int ivar; 
+} 
+- (int) instancemethod;
+@property  int prop; 
+@end
+
+@interface DEPRECATED (Category) // expected-warning {{warning: 'DEPRECATED' is deprecated}}
+@end
+
+@interface NS : DEPRECATED  // expected-warning {{warning: 'DEPRECATED' is deprecated}}
+@end
+
+
diff --git a/test/SemaObjC/attr-malloc.m b/test/SemaObjC/attr-malloc.m
new file mode 100644
index 0000000..a504b33
--- /dev/null
+++ b/test/SemaObjC/attr-malloc.m
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -verify -fsyntax-only -fblocks %s
+
+@interface TestAttrMallocOnMethods {}
+- (id) test1 __attribute((malloc)); //  expected-warning {{functions returning a pointer type}}
+- (int) test2 __attribute((malloc)); //  expected-warning {{functions returning a pointer type}}
+@end
+
+id bar(void) __attribute((malloc)); // no-warning
+
+typedef void (^bptr)(void);
+bptr baz(void) __attribute((malloc)); // no-warning
+
+__attribute((malloc)) id (*f)(); //  expected-warning {{functions returning a pointer type}}
+__attribute((malloc)) bptr (*g)(); //  expected-warning {{functions returning a pointer type}}
+__attribute((malloc)) void *(^h)(); //  expected-warning {{functions returning a pointer type}}
+
diff --git a/test/SemaObjC/attr-objc-exception.m b/test/SemaObjC/attr-objc-exception.m
new file mode 100644
index 0000000..b497271
--- /dev/null
+++ b/test/SemaObjC/attr-objc-exception.m
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify
+
+__attribute__((__objc_exception__))
+@interface NSException {
+  int x;
+}
+
+@end
+
+
+__attribute__((__objc_exception__)) // expected-error {{attribute may only be applied to an Objective-C interface}}
+int X;
+
+__attribute__((__objc_exception__)) // expected-error {{attribute may only be applied to an Objective-C interface}}
+void foo();
+
diff --git a/test/SemaObjC/attr-objc-gc.m b/test/SemaObjC/attr-objc-gc.m
new file mode 100644
index 0000000..47da653
--- /dev/null
+++ b/test/SemaObjC/attr-objc-gc.m
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+static id __attribute((objc_gc(weak))) a;
+static id __attribute((objc_gc(strong))) b;
+
+static id __attribute((objc_gc())) c; // expected-error{{'objc_gc' attribute requires parameter 1 to be a string}}
+static id __attribute((objc_gc(123))) d; // expected-error{{'objc_gc' attribute requires parameter 1 to be a string}}
+static id __attribute((objc_gc(foo, 456))) e; // expected-error{{attribute requires 1 argument(s)}}
+static id __attribute((objc_gc(hello))) f; // expected-warning{{'objc_gc' attribute argument not supported: 'hello'}}
diff --git a/test/SemaObjC/bad-receiver-1.m b/test/SemaObjC/bad-receiver-1.m
new file mode 100644
index 0000000..33e1630
--- /dev/null
+++ b/test/SemaObjC/bad-receiver-1.m
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@interface I
+- (id) retain;
+@end
+
+int objc_lookUpClass(const char*);
+
+void __raiseExc1() {
+ [objc_lookUpClass("NSString") retain]; // expected-warning {{receiver type 'int' is not 'id'}} \
+    expected-warning {{method '-retain' not found}}
+}
+
+typedef const struct __CFString * CFStringRef;
+
+void func() {
+  CFStringRef obj;
+
+  [obj self]; // expected-warning {{receiver type 'CFStringRef' (aka 'struct __CFString const *') is not 'id'}} \\
+                 expected-warning {{method '-self' not found}}
+}
diff --git a/test/SemaObjC/block-attr.m b/test/SemaObjC/block-attr.m
new file mode 100644
index 0000000..c89aed4
--- /dev/null
+++ b/test/SemaObjC/block-attr.m
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -fblocks -fobjc-gc-only %s
+
+@interface Thing  {}
+
+@property void(^someBlock)(void); // expected-warning {{'copy' attribute must be specified for the block property}}
+@property(copy)  void(^OK)(void);
+
+
+@end
diff --git a/test/SemaObjC/block-explicit-return-type.m b/test/SemaObjC/block-explicit-return-type.m
new file mode 100644
index 0000000..22e5b6f
--- /dev/null
+++ b/test/SemaObjC/block-explicit-return-type.m
@@ -0,0 +1,77 @@
+// RUN: %clang_cc1 -fsyntax-only %s -verify -fblocks
+// FIXME: should compile
+// Test for blocks with explicit return type specified.
+
+typedef float * PF;
+float gf;
+
+@interface NSView
+  - (id) some_method_that_returns_id;
+@end
+
+NSView *some_object;
+
+void some_func (NSView * (^) (id));
+
+typedef struct dispatch_item_s *dispatch_item_t;
+typedef void (^completion_block_t)(void);
+
+typedef double (^myblock)(int);
+double test(myblock I);
+
+int main() {
+  __block int x = 1;
+  __block int y = 2;
+
+  (void)^void *{ return 0; };
+
+  (void)^float(float y){ return y; };
+
+  (void)^double (float y, double d) {
+    if (y)
+      return d;
+    else
+      return y;
+  };
+
+  const char * (^chb) (int flag, const char *arg, char *arg1) = ^ const char * (int flag, const char *arg, char *arg1) {
+    if (flag)
+      return 0;
+    if (flag == 1)
+      return arg;
+    else if (flag == 2)
+      return "";
+    return arg1; 
+  };
+
+  (void)^PF { return &gf; };
+
+  some_func(^ NSView * (id whatever) { return [some_object some_method_that_returns_id]; });
+
+  double res = test(^(int z){x = y+z; return (double)z; });
+}
+
+void func() {
+  completion_block_t X;
+
+  completion_block_t (^blockx)(dispatch_item_t) = ^completion_block_t (dispatch_item_t item) {
+    return X;
+  };
+
+  completion_block_t (^blocky)(dispatch_item_t) = ^(dispatch_item_t item) {
+    return X;
+  };
+
+  blockx = blocky;
+}
+
+
+// intent: block taking int returning block that takes char,int and returns int
+int (^(^block)(double x))(char, short);
+
+void foo() {
+   int one = 1;
+   block = ^(double x){ return ^(char c, short y) { return one + c + y; };};  // expected-error {{returning block that lives on the local stack}}
+   // or:
+   block = ^(double x){ return ^(char c, short y) { return one + (int)c + y; };};  // expected-error {{returning block that lives on the local stack}}
+}
diff --git a/test/SemaObjC/block-ivar.m b/test/SemaObjC/block-ivar.m
new file mode 100644
index 0000000..c7ea1d9
--- /dev/null
+++ b/test/SemaObjC/block-ivar.m
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -fblocks
+
+@interface NSObject {
+  struct objc_object *isa;
+}
+@end
+@interface Foo : NSObject {
+  int _prop;
+}
+@end
+
+@implementation Foo
+- (int)doSomething {
+  int (^blk)(void) = ^{ return _prop; };
+  return blk();
+}
+
+@end
+
diff --git a/test/SemaObjC/block-type-safety.m b/test/SemaObjC/block-type-safety.m
new file mode 100644
index 0000000..402a658
--- /dev/null
+++ b/test/SemaObjC/block-type-safety.m
@@ -0,0 +1,106 @@
+// RUN: %clang_cc1 -fsyntax-only %s -verify -fblocks
+// test for block type safety.
+
+@interface Super  @end
+@interface Sub : Super @end
+
+void f2(void(^f)(Super *)) { // expected-note{{passing argument to parameter 'f' here}}
+    Super *o;
+    f(o);
+}
+
+void f3(void(^f)(Sub *)) {
+    Sub *o;
+    f(o);
+}
+
+void r0(Super* (^f)()) {
+     Super *o = f();
+}
+
+void r1(Sub* (^f)()) { // expected-note{{passing argument to parameter 'f' here}}
+    Sub *o = f();
+}
+
+@protocol NSObject;
+
+void r2 (id<NSObject> (^f) (void)) {
+  id o = f();
+}
+
+void test1() {
+    f2(^(Sub *o) { });    // expected-error {{incompatible block pointer types passing}}
+    f3(^(Super *o) { });  // OK, block taking Super* may be called with a Sub*
+
+    r0(^Super* () { return 0; });  // OK
+    r0(^Sub* () { return 0; });    // OK, variable of type Super* gets return value of type Sub*
+    r0(^id () { return 0; });
+
+    r1(^Super* () { return 0; });  // expected-error {{incompatible block pointer types passing}}
+    r1(^Sub* () { return 0; });    // OK
+    r1(^id () { return 0; }); 
+     
+    r2(^id<NSObject>() { return 0; });
+}
+
+
+@interface A @end
+@interface B @end
+
+void f0(void (^f)(A* x)) {
+  A* a;
+  f(a);
+}
+
+void f1(void (^f)(id x)) {
+  B *b;
+  f(b);
+}
+
+void test2(void) 
+{ 
+  f0(^(id a) { }); // OK
+  f1(^(A* a) { });
+   f1(^(id<NSObject> a) { });	// OK
+}
+
+@interface NSArray
+   // Calls block() with every object in the array
+   -enumerateObjectsWithBlock:(void (^)(id obj))block;
+@end
+
+@interface MyThing
+-(void) printThing;
+@end
+
+@implementation MyThing
+    static NSArray* myThings;  // array of MyThing*
+
+   -(void) printThing {  }
+
+// programmer wants to write this:
+   -printMyThings1 {
+       [myThings enumerateObjectsWithBlock: ^(MyThing *obj) {
+           [obj printThing];
+       }];
+   }
+
+// strict type safety requires this:
+   -printMyThings {
+       [myThings enumerateObjectsWithBlock: ^(id obj) {
+           MyThing *obj2 = (MyThing *)obj;
+           [obj2 printThing];
+       }];
+   }
+@end
+
+@protocol P, P2;
+void f4(void (^f)(id<P> x)) { // expected-note{{passing argument to parameter 'f' here}}
+    NSArray<P2> *b;
+    f(b);	// expected-warning {{passing 'NSArray<P2> *' to parameter of incompatible type 'id<P>'}}
+}
+
+void test3() {
+  f4(^(NSArray<P2>* a) { });  // expected-error {{incompatible block pointer types passing 'void (^)(NSArray<P2> *)' to parameter of type 'void (^)(id<P>)'}}
+}
+
diff --git a/test/SemaObjC/blocks.m b/test/SemaObjC/blocks.m
new file mode 100644
index 0000000..15aa581
--- /dev/null
+++ b/test/SemaObjC/blocks.m
@@ -0,0 +1,69 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -fblocks %s
+@protocol NSObject;
+
+void bar(id(^)(void));
+void foo(id <NSObject>(^objectCreationBlock)(void)) {
+    return bar(objectCreationBlock);
+}
+
+void bar2(id(*)(void));
+void foo2(id <NSObject>(*objectCreationBlock)(void)) {
+    return bar2(objectCreationBlock);
+}
+
+void bar3(id(*)());
+void foo3(id (*objectCreationBlock)(int)) {
+    return bar3(objectCreationBlock);
+}
+
+void bar4(id(^)());
+void foo4(id (^objectCreationBlock)(int)) {
+    return bar4(objectCreationBlock);
+}
+
+void bar5(id(^)(void)); // expected-note{{passing argument to parameter here}}
+void foo5(id (^objectCreationBlock)(int)) {
+    return bar5(objectCreationBlock); // expected-error {{incompatible block pointer types passing 'id (^)(int)' to parameter of type 'id (^)(void)'}}
+}
+
+void bar6(id(^)(int));
+void foo6(id (^objectCreationBlock)()) {
+    return bar6(objectCreationBlock);
+}
+
+void foo7(id (^x)(int)) {
+  if (x) { }
+}
+
+@interface itf
+@end
+
+void foo8() {
+  void *P = ^(itf x) {};  // expected-error {{Objective-C interface type 'itf' cannot be passed by value; did you forget * in 'itf'}}
+  P = ^itf(int x) {};     // expected-error {{Objective-C interface type 'itf' cannot be returned by value; did you forget * in 'itf'}}
+  P = ^itf() {};          // expected-error {{Objective-C interface type 'itf' cannot be returned by value; did you forget * in 'itf'}}
+  P = ^itf{};             // expected-error {{Objective-C interface type 'itf' cannot be returned by value; did you forget * in 'itf'}}
+}
+
+
+int foo9() {
+  typedef void (^DVTOperationGroupScheduler)();
+  id _suboperationSchedulers;
+
+  for (DVTOperationGroupScheduler scheduler in _suboperationSchedulers) {
+            ;
+        }
+
+}
+
+// rdar 7725203
+@class NSString;
+
+extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, 2)));
+
+void foo10() {
+    void(^myBlock)(void) = ^{
+    };
+    NSLog(@"%@", myBlock);
+}
+
diff --git a/test/SemaObjC/call-super-2.m b/test/SemaObjC/call-super-2.m
new file mode 100644
index 0000000..043314d
--- /dev/null
+++ b/test/SemaObjC/call-super-2.m
@@ -0,0 +1,108 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+#include <stddef.h>
+
+typedef struct objc_object *id;
+id objc_getClass(const char *s);
+
+@interface Object 
+- (id) initWithInt: (int) i;
+@end
+
+@protocol Func
++ (int) class_func0;
+- (int) instance_func0;
+@end
+
+@interface Derived: Object
++ (int) class_func1;
++ (int) class_func2;
++ (int) class_func3;
++ (int) class_func4;
++ (int) class_func5;
++ (int) class_func6;
++ (int) class_func7;
+- (int) instance_func1;
+- (int) instance_func2;
+- (int) instance_func3;
+- (int) instance_func4;
+- (int) instance_func5;
+- (int) instance_func6;
+- (int) instance_func7;
+- (id) initWithInt: (int) i;
+@end
+
+@implementation Derived
++ (int) class_func1
+{
+   int i = (size_t)[self class_func0];       // expected-warning {{method '-class_func0' not found (return type defaults to 'id')}}
+   return i + (size_t)[super class_func0];   // expected-warning {{method '+class_func0' not found (return type defaults to 'id')}}
+}
++ (int) class_func2
+{
+   int i = [(id <Func>)self class_func0];
+   i += [(id <Func>)super class_func0];    // expected-error {{cannot cast 'super' (it isn't an expression)}}
+   i += [(Class <Func>)self class_func0];  // 
+   return i + [(Class <Func>)super class_func0]; // // expected-error {{cannot cast 'super' (it isn't an expression)}}
+}
++ (int) class_func3
+{
+   return [(Object <Func> *)super class_func0];  // expected-error {{cannot cast 'super' (it isn't an expression)}}
+}
++ (int) class_func4
+{
+   return [(Derived <Func> *)super class_func0]; // expected-error {{cannot cast 'super' (it isn't an expression)}}
+}   
++ (int) class_func5
+{
+   int i = (size_t)[Derived class_func0];    // expected-warning {{method '+class_func0' not found (return type defaults to 'id')}}
+   return i + (size_t)[Object class_func0];  // expected-warning {{method '+class_func0' not found (return type defaults to 'id')}}
+}
++ (int) class_func6
+{
+   return (size_t)[objc_getClass("Object") class_func1]; // GCC warns about this
+}
++ (int) class_func7
+{
+   return [objc_getClass("Derived") class_func1];
+}
+- (int) instance_func1
+{
+   int i = (size_t)[self instance_func0];     // expected-warning {{method '-instance_func0' not found (return type defaults to 'id'))}}
+   return i + (size_t)[super instance_func0]; // expected-warning {{'Object' may not respond to 'instance_func0')}}
+}
+- (int) instance_func2
+{
+   return [(id <Func>)super instance_func0]; // expected-error {{cannot cast 'super' (it isn't an expression)}}
+}
+- (int) instance_func3
+{
+   return [(Object <Func> *)super instance_func0]; // expected-error {{cannot cast 'super' (it isn't an expression)}}
+}
+- (int) instance_func4
+{
+   return [(Derived <Func> *)super instance_func0]; // expected-error {{cannot cast 'super' (it isn't an expression)}}
+}   
+- (int) instance_func5
+{
+   int i = (size_t)[Derived instance_func1]; // expected-warning {{method '+instance_func1' not found (return type defaults to 'id')}} 
+   return i + (size_t)[Object instance_func1]; // expected-warning {{method '+instance_func1' not found (return type defaults to 'id')}}
+}
+- (int) instance_func6
+{
+   return (size_t)[objc_getClass("Object") class_func1];
+}
+- (int) instance_func7
+{
+   return [objc_getClass("Derived") class_func1];
+}
+- (id) initWithInt: (int) i
+{
+   // Don't warn about parentheses here.
+   if (self = [super initWithInt: i]) {
+     [self instance_func1];
+   }
+   return self;
+}
+@end
+
diff --git a/test/SemaObjC/catch-stmt.m b/test/SemaObjC/catch-stmt.m
new file mode 100644
index 0000000..80c986f
--- /dev/null
+++ b/test/SemaObjC/catch-stmt.m
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -verify %s
+
+@protocol P;
+
+void f() {
+  @try {
+  } @catch (void a) { // expected-error{{@catch parameter is not a pointer to an interface type}}
+  } @catch (int) { // expected-error{{@catch parameter is not a pointer to an interface type}}
+  } @catch (int *b) { // expected-error{{@catch parameter is not a pointer to an interface type}}
+  } @catch (id <P> c) { // expected-error{{illegal qualifiers on @catch parameter}}
+  }
+}
+
diff --git a/test/SemaObjC/category-1.m b/test/SemaObjC/category-1.m
new file mode 100644
index 0000000..18cbb83
--- /dev/null
+++ b/test/SemaObjC/category-1.m
@@ -0,0 +1,79 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@interface MyClass1 @end
+
+@protocol p1,p2,p3;
+
+@interface MyClass1 (Category1)  <p1> // expected-warning {{cannot find protocol definition for 'p1'}} expected-note {{previous definition is here}}
+@end
+
+@interface MyClass1 (Category1)  // expected-warning {{duplicate definition of category 'Category1' on interface 'MyClass1'}}
+@end
+
+@interface MyClass1 (Category3) 
+@end
+
+@interface MyClass1 (Category4) @end // expected-note {{previous definition is here}}
+@interface MyClass1 (Category5) @end
+@interface MyClass1 (Category6) @end
+@interface MyClass1 (Category7) @end // expected-note {{previous definition is here}}
+@interface MyClass1 (Category8) @end // expected-note {{previous definition is here}}
+
+
+@interface MyClass1 (Category4) @end // expected-warning {{duplicate definition of category 'Category4' on interface 'MyClass1'}}
+@interface MyClass1 (Category7) @end // expected-warning {{duplicate definition of category 'Category7' on interface 'MyClass1'}}
+@interface MyClass1 (Category8) @end // expected-warning {{duplicate definition of category 'Category8' on interface 'MyClass1'}}
+
+
+@protocol p3 @end
+
+@interface MyClass1 (Category) <p2, p3> @end  // expected-warning {{cannot find protocol definition for 'p2'}}
+
+@interface UnknownClass  (Category) @end // expected-error {{cannot find interface declaration for 'UnknownClass'}}
+
+@class MyClass2;
+
+@interface MyClass2  (Category) @end  // expected-error {{cannot find interface declaration for 'MyClass2'}}
+
+@interface XCRemoteComputerManager
+@end
+
+@interface XCRemoteComputerManager() 
+@end 
+
+@interface XCRemoteComputerManager()
+@end
+
+@interface XCRemoteComputerManager(x) // expected-note {{previous definition is here}}
+@end 
+
+@interface XCRemoteComputerManager(x) // expected-warning {{duplicate definition of category 'x' on interface 'XCRemoteComputerManager'}}
+@end
+
+@implementation XCRemoteComputerManager
+@end
+
+@implementation XCRemoteComputerManager(x) // expected-note {{previous definition is here}}
+@end
+
+@implementation XCRemoteComputerManager(x) // expected-error {{reimplementation of category 'x' for class 'XCRemoteComputerManager'}}
+@end
+
+// <rdar://problem/7249233>
+
+@protocol MultipleCat_P
+-(void) im0; // expected-warning {{method in protocol not implemented [-Wprotocol]}}
+@end
+
+@interface MultipleCat_I @end // expected-note {{required for direct or indirect protocol 'MultipleCat_P'}}
+
+@interface MultipleCat_I()  @end
+
+@interface MultipleCat_I() <MultipleCat_P>  @end
+
+@implementation MultipleCat_I // expected-warning {{incomplete implementation}}
+@end
+
+// <rdar://problem/7680391> - Handle nameless categories with no name that refer
+// to an undefined class
+@interface RDar7680391 () @end // expected-error{{cannot find interface declaration}}
diff --git a/test/SemaObjC/category-method-lookup-2.m b/test/SemaObjC/category-method-lookup-2.m
new file mode 100644
index 0000000..a31d824
--- /dev/null
+++ b/test/SemaObjC/category-method-lookup-2.m
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+typedef struct objc_class *Class;
+@interface NSObject
+- (Class)class;
+@end
+@interface Bar : NSObject
+@end
+@interface Bar (Cat)
+@end
+
+// NOTE: No class implementation for Bar precedes this category definition.
+@implementation Bar (Cat)
+
+// private method.
++ classMethod { return self; }
+
+- instanceMethod {
+  [[self class] classMethod];
+  return 0;
+}
+
+@end
diff --git a/test/SemaObjC/category-method-lookup.m b/test/SemaObjC/category-method-lookup.m
new file mode 100644
index 0000000..27a10e5
--- /dev/null
+++ b/test/SemaObjC/category-method-lookup.m
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@interface Foo
+@end
+@implementation Foo
+@end
+
+@implementation Foo(Whatever)
++(float)returnsFloat { return 7.0; }
+@end
+
+@interface Foo (MoreStuff)
++(int)returnsInt;
+@end
+
+@implementation Foo (MoreStuff)
++(int)returnsInt {
+  return 0;
+}
+
++(void)returnsNothing {
+}
+-(int)callsReturnsInt {
+  float f = [Foo returnsFloat]; // GCC doesn't find this method (which is a bug IMHO).
+  [Foo returnsNothing];
+  return [Foo returnsInt];
+}
+@end
+
+int main() {return 0;}
+
diff --git a/test/SemaObjC/check-dup-decl-methods-1.m b/test/SemaObjC/check-dup-decl-methods-1.m
new file mode 100644
index 0000000..1dd6446
--- /dev/null
+++ b/test/SemaObjC/check-dup-decl-methods-1.m
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@interface SUPER
+- (int) meth;
++ (int) foobar;
+@end
+
+@interface T @end
+
+@interface class1 : SUPER
+- (int) meth;	// expected-note {{previous declaration is here}}
+- (int*) meth;	// expected-error {{duplicate declaration of method 'meth'}}
+- (T*) meth1;  
+- (T*) meth1;
++ (T*) meth1;
+@end
+
+@interface class1(cat)
+- (int) catm : (char)ch1; // expected-note {{previous declaration is here}}
+- (int) catm1 : (char)ch : (int)i;
+- (int) catm : (char*)ch1; // expected-error {{duplicate declaration of method 'catm:'}}
++ (int) catm1 : (char)ch : (int)i;
++ (T*) meth1;
+@end
+
+@interface class1(cat1)
++ (int) catm1 : (char)ch : (int)i; // expected-note {{previous declaration is here}}
++ (T*) meth1; // expected-note {{previous declaration is here}}
++ (int) catm1 : (char)ch : (int*)i; // expected-error {{duplicate declaration of method 'catm1::'}}
++ (T**) meth1; // expected-error {{duplicate declaration of method 'meth1'}}
++ (int) foobar;
+@end
+
+@protocol P
+- (int) meth; // expected-note {{previous declaration is here}}
+- (int*) meth; // expected-error {{duplicate declaration of method 'meth'}}
+@end
+
diff --git a/test/SemaObjC/check-dup-objc-decls-1.m b/test/SemaObjC/check-dup-objc-decls-1.m
new file mode 100644
index 0000000..8dde777
--- /dev/null
+++ b/test/SemaObjC/check-dup-objc-decls-1.m
@@ -0,0 +1,44 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@interface Foo // expected-note {{previous definition is here}}
+@end
+
+float Foo;	// expected-error {{redefinition of 'Foo' as different kind of symbol}}
+
+@class Bar;  // expected-note {{previous definition is here}}
+
+typedef int Bar;  // expected-error {{redefinition of 'Bar' as different kind of symbol}}
+
+@implementation FooBar // expected-warning {{cannot find interface declaration for 'FooBar'}} 
+@end
+
+
+typedef int OBJECT; // expected-note {{previous definition is here}}
+
+@class OBJECT ;	// expected-error {{redefinition of 'OBJECT' as different kind of symbol}}
+
+
+typedef int Gorf;  // expected-note {{previous definition is here}}
+
+@interface Gorf @end // expected-error {{redefinition of 'Gorf' as different kind of symbol}} expected-note {{previous definition is here}}
+
+void Gorf() // expected-error {{redefinition of 'Gorf' as different kind of symbol}}
+{
+  int Bar, Foo, FooBar;
+}
+
+@protocol P -im1; @end
+@protocol Q -im2; @end
+@interface A<P> @end  // expected-note {{previous definition is here}}
+@interface A<Q> @end  // expected-error {{duplicate interface definition for class 'A'}}
+
+@protocol PP<P> @end  // expected-note {{previous definition is here}}
+@protocol PP<Q> @end  // expected-warning {{duplicate protocol definition of 'PP'}}
+
+@interface A(Cat)<P> @end // expected-note {{previous definition is here}}
+@interface A(Cat)<Q> @end // expected-warning {{duplicate definition of category 'Cat' on interface 'A'}}
+
+// rdar 7626768
+@class NSString;
+NSString * TestBaz;  // expected-note {{previous definition is here}}
+NSString * const TestBaz;  // expected-error {{redefinition of 'TestBaz' with a different type}}
diff --git a/test/SemaObjC/class-bitfield.m b/test/SemaObjC/class-bitfield.m
new file mode 100644
index 0000000..c0393c2
--- /dev/null
+++ b/test/SemaObjC/class-bitfield.m
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify 
+
+@interface X 
+{
+  int a : -1; // expected-error{{bit-field 'a' has negative width}}
+
+  // rdar://6081627
+  int b : 33; // expected-error{{size of bit-field 'b' (33 bits) exceeds size of its type (32 bits)}}
+
+  int c : (1 + 0.25); // expected-error{{expression is not an integer constant expression}}
+  int d : (int)(1 + 0.25); 
+
+  // rdar://6138816
+  int e : 0;  // expected-error {{bit-field 'e' has zero width}}
+}
+@end
+
+@interface Base {
+  int i;
+}
+@end
+
+@interface WithBitFields: Base {
+  void *isa; // expected-note {{previous definition is here}}
+  unsigned a: 5;
+  signed b: 4;
+  int c: 5; // expected-note {{previous definition is here}}
+}
+@end
+
+@implementation WithBitFields {
+  char *isa;  // expected-error {{instance variable 'isa' has conflicting type: 'char *' vs 'void *'}}
+  unsigned a: 5;  
+  signed b: 4; 
+  int c: 3;  // expected-error {{instance variable 'c' has conflicting bit-field width}}
+}
+@end
diff --git a/test/SemaObjC/class-conforming-protocol-1.m b/test/SemaObjC/class-conforming-protocol-1.m
new file mode 100644
index 0000000..43ea6d3
--- /dev/null
+++ b/test/SemaObjC/class-conforming-protocol-1.m
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@protocol P1 @end
+@protocol P2 @end
+@protocol P3 @end
+
+@interface INTF 
+- (INTF*) METH1;	// expected-note {{previous declaration is here}}
+- (INTF<P1>*) METH1;	// expected-error {{duplicate declaration of method 'METH1'}}
+
+- (INTF<P1,P2>*) METH2;
+- (INTF<P2,P1>*) METH2;  // expected-note {{previous declaration is here}}
+- (INTF<P2,P1,P3>*) METH2;  // expected-error {{duplicate declaration of method 'METH2'}}
+
+- (INTF<P2,P1,P3>*) METH3;
+- (INTF<P3,P1,P2, P3>*) METH3;
+
+@end
+
+INTF<P2,P1,P3>* p1;
+
diff --git a/test/SemaObjC/class-conforming-protocol-2.m b/test/SemaObjC/class-conforming-protocol-2.m
new file mode 100644
index 0000000..fcf9146
--- /dev/null
+++ b/test/SemaObjC/class-conforming-protocol-2.m
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1  -fsyntax-only -verify %s
+
+@protocol NSWindowDelegate @end
+
+@interface NSWindow
+- (void)setDelegate:(id <NSWindowDelegate>)anObject;
+- (id <NSWindowDelegate>) delegate;
+@end
+
+@protocol IBStringsTableWindowDelegate <NSWindowDelegate>
+@end
+
+@interface IBStringsTableWindow : NSWindow {}
+@end
+
+@implementation IBStringsTableWindow
+- (void)setDelegate:(id <IBStringsTableWindowDelegate>)delegate {
+}
+- (id <IBStringsTableWindowDelegate>)delegate {
+        return 0;
+}
+@end
diff --git a/test/SemaObjC/class-def-test-1.m b/test/SemaObjC/class-def-test-1.m
new file mode 100644
index 0000000..95a259b
--- /dev/null
+++ b/test/SemaObjC/class-def-test-1.m
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@protocol SUPER;
+
+@interface SUPER <SUPER> @end // expected-warning {{cannot find protocol definition for 'SUPER'}}
+
+typedef int INTF; //  expected-note {{previous definition is here}}
+
+@interface INTF @end // expected-error {{redefinition of 'INTF' as different kind of symbol}}
+
+@interface OBJECT @end	// expected-note {{previous definition is here}}
+
+@interface INTF1 : OBJECT @end // expected-note {{previous definition is here}}
+
+@interface INTF1 : OBJECT @end // expected-error {{duplicate interface definition for class 'INTF1'}}
+
+typedef int OBJECT; // expected-error {{redefinition of 'OBJECT' as different kind of symbol}}
+
+typedef int OBJECT2; // expected-note {{previous definition is here}}
+@interface INTF2 : OBJECT2 @end // expected-error {{redefinition of 'OBJECT2' as different kind of symbol}}
+
+
+@protocol PROTO;
+
+@interface INTF3 : PROTO @end // expected-error {{cannot find interface declaration for 'PROTO', superclass of 'INTF3'}}
+
+// Make sure we allow the following (for GCC compatibility).
+@interface NSObject @end
+typedef NSObject TD_NSObject;
+@interface XCElementUnit : TD_NSObject {}
+@end
+
+
diff --git a/test/SemaObjC/class-extension-after-implementation.m b/test/SemaObjC/class-extension-after-implementation.m
new file mode 100644
index 0000000..2d8a5b1
--- /dev/null
+++ b/test/SemaObjC/class-extension-after-implementation.m
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1  -fsyntax-only -verify %s
+// rdar://7822210
+
+@interface A @end
+
+@implementation A @end // expected-note {{class implementation is declared here}}
+
+@interface A () // expected-error {{cannot declare class extension for 'A' after class implementation}}
+-(void) im0;
+@end
+
diff --git a/test/SemaObjC/class-extension-dup-methods.m b/test/SemaObjC/class-extension-dup-methods.m
new file mode 100644
index 0000000..452d242
--- /dev/null
+++ b/test/SemaObjC/class-extension-dup-methods.m
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@interface Foo
+- (int)  garf; // expected-note {{ previous declaration is here}}
+- (int) OK;
++ (int)  cgarf; // expected-note {{ previous declaration is here}}
+- (int)  InstMeth;
+@end
+
+@interface Foo()
+- (void)  garf; // expected-error {{duplicate declaration of method 'garf'}}
++ (void)  cgarf; // expected-error {{duplicate declaration of method 'cgarf'}}
++ (int)  InstMeth;
+- (int) OK;
+@end
diff --git a/test/SemaObjC/class-getter-using-dotsyntax.m b/test/SemaObjC/class-getter-using-dotsyntax.m
new file mode 100644
index 0000000..6454bc0
--- /dev/null
+++ b/test/SemaObjC/class-getter-using-dotsyntax.m
@@ -0,0 +1,39 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+typedef struct objc_class *Class;
+
+struct objc_class {
+    Class isa;
+};
+
+typedef struct objc_object {
+    Class isa;
+} *id;
+
+@interface XCActivityLogSection 
++ (unsigned)serializationFormatVersion;
++ (unsigned)sectionByDeserializingData;
++ (Class)retursClass;
+@end
+
+@implementation XCActivityLogSection
+
++ (unsigned)serializationFormatVersion
+{
+
+    return 0;
+}
++ (unsigned)sectionByDeserializingData {
+    unsigned version;
+    return self.serializationFormatVersion;
+}
+
++ (Class)retursClass {
+    Class version;
+    // FIXIT. (*version).isa does not work. Results in compiler error.
+    return version->isa;
+}
+
+@end
+
+
diff --git a/test/SemaObjC/class-impl-1.m b/test/SemaObjC/class-impl-1.m
new file mode 100644
index 0000000..90a4112
--- /dev/null
+++ b/test/SemaObjC/class-impl-1.m
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+typedef int INTF3; // expected-note {{previous definition is here}}
+
+@interface SUPER @end // expected-note {{previous definition is here}}
+
+@interface OBJECT @end
+
+@interface INTF  : OBJECT
+@end
+
+@implementation INTF @end // expected-note {{previous definition is here}}
+
+@implementation INTF //  expected-error {{reimplementation of class 'INTF'}}
+@end
+
+
+@interface INTF1 : OBJECT
+@end
+
+@implementation INTF1 : SUPER // expected-error {{conflicting super class name 'SUPER'}}
+@end
+
+@interface INTF2 
+@end
+
+@implementation INTF2 : SUPR //  expected-error {{cannot find interface declaration for 'SUPR', superclass of 'INTF2'}}
+@end
+
+@implementation INTF3 @end // expected-error {{redefinition of 'INTF3' as different kind of symbol}}
+
+@implementation INTF4 @end // expected-warning {{cannot find interface declaration for 'INTF4'}}
+
+@class INTF5;
+
+@implementation INTF5 {  // expected-warning {{cannot find interface declaration for 'INTF5'}}
+  int x;
+}
+@end
+
diff --git a/test/SemaObjC/class-method-lookup.m b/test/SemaObjC/class-method-lookup.m
new file mode 100644
index 0000000..f26d692
--- /dev/null
+++ b/test/SemaObjC/class-method-lookup.m
@@ -0,0 +1,46 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@interface MyBase 
+- (void) rootInstanceMethod;
+@end
+
+@interface MyIntermediate: MyBase
+@end
+
+@interface MyDerived: MyIntermediate
+- (void) instanceMethod;
++ (void) classMethod;
+@end
+
+@implementation MyDerived
+- (void) instanceMethod {
+}
+
++ (void) classMethod {                    /* If a class method is not found, the root  */
+    [self rootInstanceMethod];            /* class is searched for an instance method  */
+    [MyIntermediate rootInstanceMethod];  /* with the same name.                       */
+
+    [self instanceMethod];// expected-warning {{'-instanceMethod' not found (return type defaults to 'id')}}
+    [MyDerived instanceMethod];// expected-warning {{'+instanceMethod' not found (return type defaults to 'id')}}
+}
+@end
+
+@interface Object @end
+
+@interface Class1
+- (void)setWindow:(Object *)wdw;
+@end
+
+@interface Class2
+- (void)setWindow:(Class1 *)window;
+@end
+
+#define nil (void*)0
+
+id foo(void) {
+  Object *obj;
+  id obj2 = obj;
+  [obj setWindow:nil]; // expected-warning {{'Object' may not respond to 'setWindow:'}}
+
+  return obj;
+}
diff --git a/test/SemaObjC/class-method-self.m b/test/SemaObjC/class-method-self.m
new file mode 100644
index 0000000..ba70644
--- /dev/null
+++ b/test/SemaObjC/class-method-self.m
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -verify %s 
+
+typedef struct objc_class *Class;
+@interface XX
+
+- (void)addObserver:(XX*)o; // expected-note 2{{passing argument to parameter 'o' here}}
+
+@end
+
+@interface YY
+
++ (void)classMethod;
+
+@end
+
+@implementation YY
+
+static XX *obj;
+
++ (void)classMethod {
+  [obj addObserver:self];     // expected-warning {{incompatible pointer types sending 'Class' to parameter of type 'XX *'}}
+  Class whatever;
+  [obj addObserver:whatever]; // expected-warning {{incompatible pointer types sending 'Class' to parameter of type 'XX *'}}
+}
+@end
+
diff --git a/test/SemaObjC/class-property-access.m b/test/SemaObjC/class-property-access.m
new file mode 100644
index 0000000..c46d3fb
--- /dev/null
+++ b/test/SemaObjC/class-property-access.m
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@interface Test {}
++ (Test*)one;
+- (int)two;
+@end
+
+int main ()
+{
+  return Test.one.two;
+}
+
diff --git a/test/SemaObjC/class-proto-1.m b/test/SemaObjC/class-proto-1.m
new file mode 100644
index 0000000..246b500
--- /dev/null
+++ b/test/SemaObjC/class-proto-1.m
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@interface INTF1 @end
+
+@protocol p1,p2,p3;
+
+@protocol p1;
+
+@protocol PROTO1
+- (INTF1<p1>*) meth;
+@end
+
+@protocol p1 @end
+
+@interface I1 <p1> @end
+
+@interface E1 <p2> @end	// expected-warning {{cannot find protocol definition for 'p2'}}
+
+@protocol p2 @end
+
+
+@interface I2 <p1,p2> @end
+
+@interface E2 <p1,p2,p3> @end  // expected-warning {{cannot find protocol definition for 'p3'}}
+
+@class U1, U2;
+
+@interface E3 : U1 @end // expected-error {{cannot find interface declaration for 'U1', superclass of 'E3'}}
+
+
+@interface I3 : E3  @end
+
+@interface U2 @end
+
+@interface I4 : U2 <p1,p2>
+@end
diff --git a/test/SemaObjC/class-protocol.m b/test/SemaObjC/class-protocol.m
new file mode 100644
index 0000000..91cd138
--- /dev/null
+++ b/test/SemaObjC/class-protocol.m
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1  -fsyntax-only -verify %s
+// pr5552
+
+@interface Protocol 
+@end
+
diff --git a/test/SemaObjC/cocoa.m b/test/SemaObjC/cocoa.m
new file mode 100644
index 0000000..a8cfb72
--- /dev/null
+++ b/test/SemaObjC/cocoa.m
@@ -0,0 +1,5 @@
+// RUN: %clang -arch x86_64 %s -fsyntax-only -Xclang -print-stats 
+#ifdef __APPLE__
+#include <Cocoa/Cocoa.h>
+#endif
+
diff --git a/test/SemaObjC/compare-qualified-id.m b/test/SemaObjC/compare-qualified-id.m
new file mode 100644
index 0000000..08fb366
--- /dev/null
+++ b/test/SemaObjC/compare-qualified-id.m
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+typedef signed char BOOL;
+typedef unsigned int NSUInteger;
+typedef struct _NSZone NSZone;
+@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+@protocol NSObject  - (BOOL)isEqual:(id)object; @end
+@protocol NSCopying  - (id)copyWithZone:(NSZone *)zone; @end // expected-warning {{method in protocol not implemented [-Wprotocol]}}
+@protocol NSMutableCopying  - (id)mutableCopyWithZone:(NSZone *)zone; @end
+@protocol NSCoding  - (void)encodeWithCoder:(NSCoder *)aCoder; @end
+@interface NSObject <NSObject> {} @end
+typedef struct {} NSFastEnumerationState;
+@protocol NSFastEnumeration  - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len; @end
+@interface NSDictionary : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration>  - (NSUInteger)count; @end
+@interface NSMutableDictionary : NSDictionary  - (void)removeObjectForKey:(id)aKey; @end
+extern NSString * const NSTaskDidTerminateNotification;
+
+@interface XCPropertyExpansionContext : NSObject <NSCopying> { // expected-note {{required for direct or indirect protocol 'NSCopying'}}
+  NSMutableDictionary * _propNamesToPropValuesCache;
+} @end
+
+@protocol XCPropertyValues <NSObject, NSCopying>
+- (NSString *)evaluateAsStringInContext:(XCPropertyExpansionContext *)context withNestingState:(const void *)state;
+@end
+
+@implementation XCPropertyExpansionContext // expected-warning {{incomplete implementation}}
+- (NSString *)expandedValueForProperty:(NSString *)property {
+  id <XCPropertyValues> cachedValueNode = [_propNamesToPropValuesCache objectForKey:property]; // expected-warning {{method '-objectForKey:' not found (return type defaults to 'id')}}
+  if (cachedValueNode == ((void *)0)) { }
+  NSString * expandedValue = [cachedValueNode evaluateAsStringInContext:self withNestingState:((void *)0)];
+  return expandedValue;
+}
+@end
diff --git a/test/SemaObjC/compatible-protocol-qualified-types.m b/test/SemaObjC/compatible-protocol-qualified-types.m
new file mode 100644
index 0000000..0342622
--- /dev/null
+++ b/test/SemaObjC/compatible-protocol-qualified-types.m
@@ -0,0 +1,76 @@
+// RUN: %clang_cc1 -pedantic -fsyntax-only -verify %s
+typedef signed char BOOL;
+
+@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+
+@protocol NSObject
+- (BOOL)isEqual:(id)object;
+@end
+
+@protocol NSCoding
+- (void)encodeWithCoder:(NSCoder *)aCoder;
+@end
+
+@interface NSObject <NSObject> {}
+@end
+
+typedef float CGFloat;
+
+@interface NSResponder : NSObject <NSCoding> {}
+@end
+
+@protocol XCSelectionSource;
+
+@interface XCSelection : NSResponder {}
+- (NSObject <XCSelectionSource> *) source;
+@end
+
+extern NSString * const XCActiveSelectionLevel;
+
+@interface XCActionManager : NSResponder {}
++defaultActionManager;
+-selectionAtLevel:(NSString *const)s;
+@end
+
+@implementation XDMenuItemsManager // expected-warning {{cannot find interface declaration for 'XDMenuItemsManager'}}
++ (void)initialize {
+  id<XCSelectionSource, NSObject> source = 
+    [[[XCActionManager defaultActionManager] selectionAtLevel:XCActiveSelectionLevel] source];
+}
+@end
+
+@protocol NSTextStorageDelegate;
+@class NSNotification;
+
+@interface NSTextStorage : NSObject
+
+- (void)setDelegate:(id <NSTextStorageDelegate>)delegate; // expected-note{{passing argument to parameter 'delegate' here}}
+- (id <NSTextStorageDelegate>)delegate;
+
+@end
+
+@protocol NSTextStorageDelegate <NSObject>
+@optional
+
+- (void)textStorageWillProcessEditing:(NSNotification *)notification;
+- (void)textStorageDidProcessEditing:(NSNotification *)notification;
+
+@end
+
+@interface SKTText : NSObject {
+    @private
+
+
+    NSTextStorage *_contents;
+}
+@end
+
+@implementation SKTText
+
+
+- (NSTextStorage *)contents {
+ [_contents setDelegate:self]; // expected-warning {{sending 'SKTText *' to parameter of incompatible type 'id<NSTextStorageDelegate>'}}
+ return 0;
+}
+
+@end
diff --git a/test/SemaObjC/comptypes-1.m b/test/SemaObjC/comptypes-1.m
new file mode 100644
index 0000000..98107ee
--- /dev/null
+++ b/test/SemaObjC/comptypes-1.m
@@ -0,0 +1,89 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s
+
+#define nil (void *)0;
+#define Nil (void *)0;
+
+extern void foo();
+
+@protocol MyProtocol
+- (void) foo;
+@end
+
+@interface MyClass
+@end
+
+@interface MyOtherClass <MyProtocol>
+- (void) foo;
+@end
+
+int main()
+{
+  id obj = nil;
+  id<MyProtocol> obj_p = nil;
+  MyClass *obj_c = nil;
+  MyOtherClass *obj_cp = nil;
+  Class obj_C = Nil;
+
+  /* Assigning to an 'id' variable should never
+     generate a warning.  */
+  obj = obj_p;  /* Ok  */
+  obj = obj_c;  /* Ok  */
+  obj = obj_cp; /* Ok  */
+  obj = obj_C;  /* Ok  */
+  
+  /* Assigning to a 'MyClass *' variable should always generate a
+     warning, unless done from an 'id'.  */
+  obj_c = obj;    /* Ok */
+  obj_c = obj_cp; // // expected-warning {{incompatible pointer types assigning to 'MyClass *' from 'MyOtherClass *'}}
+  obj_c = obj_C;  // expected-warning {{incompatible pointer types assigning to 'MyClass *' from 'Class'}}
+
+  /* Assigning to an 'id<MyProtocol>' variable should generate a
+     warning if done from a 'MyClass *' (which doesn't implement
+     MyProtocol), but not from an 'id' or from a 'MyOtherClass *'
+     (which implements MyProtocol).  */
+  obj_p = obj;    /* Ok */
+  obj_p = obj_c;  // expected-warning {{ assigning to 'id<MyProtocol>' from incompatible type 'MyClass *'}}
+  obj_p = obj_cp; /* Ok  */
+  obj_p = obj_C;  // expected-warning {{incompatible pointer types assigning to 'id<MyProtocol>' from 'Class'}}
+
+  /* Assigning to a 'MyOtherClass *' variable should always generate
+     a warning, unless done from an 'id' or an 'id<MyProtocol>' (since
+     MyOtherClass implements MyProtocol).  */
+  obj_cp = obj;    /* Ok */
+  obj_cp = obj_c;  // expected-warning {{incompatible pointer types assigning to 'MyOtherClass *' from 'MyClass *'}}
+  obj_cp = obj_p;  /* Ok */
+  obj_cp = obj_C;  // expected-warning {{incompatible pointer types assigning to 'MyOtherClass *' from 'Class'}}
+
+  /* Any comparison involving an 'id' must be without warnings.  */
+  if (obj == obj_p) foo() ;  /* Ok  */ /*Bogus warning here in 2.95.4*/
+  if (obj_p == obj) foo() ;  /* Ok  */
+  if (obj == obj_c) foo() ;  /* Ok  */
+  if (obj_c == obj) foo() ;  /* Ok  */
+  if (obj == obj_cp) foo() ; /* Ok  */
+  if (obj_cp == obj) foo() ; /* Ok  */
+  if (obj == obj_C) foo() ;  /* Ok  */
+  if (obj_C == obj) foo() ;  /* Ok  */
+
+  /* Any comparison between 'MyClass *' and anything which is not an 'id'
+     must generate a warning.  */
+  if (obj_p == obj_c) foo() ; // expected-warning {{comparison of distinct pointer types ('id<MyProtocol>' and 'MyClass *')}}
+
+  if (obj_c == obj_cp) foo() ; // expected-warning {{comparison of distinct pointer types ('MyClass *' and 'MyOtherClass *')}} 
+  if (obj_cp == obj_c) foo() ; // expected-warning {{comparison of distinct pointer types ('MyOtherClass *' and 'MyClass *')}}
+
+  if (obj_c == obj_C) foo() ;
+  if (obj_C == obj_c) foo() ;
+
+  /* Any comparison between 'MyOtherClass *' (which implements
+     MyProtocol) and an 'id' implementing MyProtocol are Ok.  */
+  if (obj_cp == obj_p) foo() ; /* Ok */
+  if (obj_p == obj_cp) foo() ; /* Ok */
+
+
+  if (obj_p == obj_C) foo() ;  
+  if (obj_C == obj_p) foo() ;
+  if (obj_cp == obj_C) foo() ;  
+  if (obj_C == obj_cp) foo() ;
+
+  return 0;
+}
diff --git a/test/SemaObjC/comptypes-2.m b/test/SemaObjC/comptypes-2.m
new file mode 100644
index 0000000..74e42c9
--- /dev/null
+++ b/test/SemaObjC/comptypes-2.m
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+#define nil (void *)0;
+#define Nil (void *)0;
+
+@protocol MyProtocol
+- (void) foo;
+@end
+
+@interface MyClass
+@end
+
+int main()
+{
+  id obj = nil;
+  id<MyProtocol> obj_p = nil;
+  MyClass *obj_c = nil;
+  Class obj_C = Nil;
+
+  /* All these casts should generate no warnings.  */
+
+  obj = (id)obj_p;
+  obj = (id)obj_c;
+  obj = (id)obj_C;
+  obj_c = (MyClass *)obj;
+  obj_c = (MyClass *)obj_p;
+  obj_c = (MyClass *)obj_C;
+  obj_p = (id<MyProtocol>)obj;
+  obj_p = (id<MyProtocol>)obj_c;
+  obj_p = (id<MyProtocol>)obj_C;
+  obj_C = (Class)obj;
+  obj_C = (Class)obj_p;
+  obj_C = (Class)obj_c;
+  
+
+  return 0;
+}
diff --git a/test/SemaObjC/comptypes-3.m b/test/SemaObjC/comptypes-3.m
new file mode 100644
index 0000000..6c1ce41
--- /dev/null
+++ b/test/SemaObjC/comptypes-3.m
@@ -0,0 +1,64 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+#define nil (void *)0;
+
+extern void foo();
+
+@protocol MyProtocolA
+- (void) methodA;
+@end
+
+@protocol MyProtocolB
+- (void) methodB;
+@end
+
+@protocol MyProtocolAB <MyProtocolA, MyProtocolB>
+@end
+
+@protocol MyProtocolAC <MyProtocolA>
+- (void) methodC;
+@end
+
+int main()
+{
+  id<MyProtocolA> obj_a = nil;
+  id<MyProtocolB> obj_b = nil;
+  id<MyProtocolAB> obj_ab = nil;
+  id<MyProtocolAC> obj_ac = nil;
+
+  obj_a = obj_b;  // expected-warning {{assigning to 'id<MyProtocolA>' from incompatible type 'id<MyProtocolB>'}}
+  obj_a = obj_ab; /* Ok */
+  obj_a = obj_ac; /* Ok */
+  
+  obj_b = obj_a;  // expected-warning {{assigning to 'id<MyProtocolB>' from incompatible type 'id<MyProtocolA>'}}
+  obj_b = obj_ab; /* Ok */
+  obj_b = obj_ac; // expected-warning {{assigning to 'id<MyProtocolB>' from incompatible type 'id<MyProtocolAC>'}}
+  
+  obj_ab = obj_a;  // expected-warning {{assigning to 'id<MyProtocolAB>' from incompatible type 'id<MyProtocolA>'}}
+  obj_ab = obj_b;  // expected-warning {{assigning to 'id<MyProtocolAB>' from incompatible type 'id<MyProtocolB>'}}
+  obj_ab = obj_ac; // expected-warning {{assigning to 'id<MyProtocolAB>' from incompatible type 'id<MyProtocolAC>'}}
+  
+  obj_ac = obj_a;  // expected-warning {{assigning to 'id<MyProtocolAC>' from incompatible type 'id<MyProtocolA>'}}
+  obj_ac = obj_b;  // expected-warning {{assigning to 'id<MyProtocolAC>' from incompatible type 'id<MyProtocolB>'}}
+  obj_ac = obj_ab; // expected-warning {{assigning to 'id<MyProtocolAC>' from incompatible type 'id<MyProtocolAB>'}}
+
+  if (obj_a == obj_b) foo (); // expected-warning {{comparison of distinct pointer types ('id<MyProtocolA>' and 'id<MyProtocolB>')}}
+  if (obj_b == obj_a) foo (); // expected-warning {{comparison of distinct pointer types ('id<MyProtocolB>' and 'id<MyProtocolA>')}}
+
+  if (obj_a == obj_ab) foo (); /* Ok */
+  if (obj_ab == obj_a) foo (); /* Ok */ 
+
+  if (obj_a == obj_ac) foo (); /* Ok */ 
+  if (obj_ac == obj_a) foo (); /* Ok */ 
+
+  if (obj_b == obj_ab) foo (); /* Ok */ 
+  if (obj_ab == obj_b) foo (); /* Ok */ 
+
+  if (obj_b == obj_ac) foo (); // expected-warning {{comparison of distinct pointer types ('id<MyProtocolB>' and 'id<MyProtocolAC>')}} 
+  if (obj_ac == obj_b) foo (); // expected-warning {{comparison of distinct pointer types ('id<MyProtocolAC>' and 'id<MyProtocolB>')}} 
+
+  if (obj_ab == obj_ac) foo (); // expected-warning {{comparison of distinct pointer types ('id<MyProtocolAB>' and 'id<MyProtocolAC>')}} 
+  if (obj_ac == obj_ab) foo (); // expected-warning {{comparison of distinct pointer types ('id<MyProtocolAC>' and 'id<MyProtocolAB>')}} 
+
+  return 0;
+}
diff --git a/test/SemaObjC/comptypes-4.m b/test/SemaObjC/comptypes-4.m
new file mode 100644
index 0000000..56b23b2
--- /dev/null
+++ b/test/SemaObjC/comptypes-4.m
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+extern void foo();
+
+@protocol MyProtocol @end
+
+@interface MyClass @end
+
+int main()
+{
+  MyClass <MyProtocol> *obj_p;
+  MyClass *obj_cp;
+
+  obj_cp = obj_p;  
+  obj_p = obj_cp;
+
+  if (obj_cp == obj_p)
+    foo();
+
+  if (obj_p == obj_cp)
+    foo();
+
+}
+
+
diff --git a/test/SemaObjC/comptypes-5.m b/test/SemaObjC/comptypes-5.m
new file mode 100644
index 0000000..aaf6446
--- /dev/null
+++ b/test/SemaObjC/comptypes-5.m
@@ -0,0 +1,44 @@
+// RUN: %clang_cc1 -fsyntax-only -pedantic -verify %s
+
+#define nil (void *)0;
+
+extern void foo();
+
+@protocol MyProtocol
+- (void) method;
+@end
+
+@interface MyClass
+@end
+
+@interface MyClass (Addition) <MyProtocol>
+- (void) method;
+@end
+
+@interface MyOtherClass : MyClass
+@end
+
+int main()
+{
+  id <MyProtocol> obj_id_p = nil;
+  MyClass *obj_c_cat_p = nil;
+  MyOtherClass *obj_c_super_p = nil;
+  MyOtherClass<MyProtocol> *obj_c_super_p_q = nil;
+  MyClass<MyProtocol> *obj_c_cat_p_q = nil;
+
+  obj_c_cat_p = obj_id_p;   
+  obj_c_super_p = obj_id_p;  
+  obj_id_p = obj_c_cat_p;  /* Ok */
+  obj_id_p = obj_c_super_p; /* Ok */
+
+  if (obj_c_cat_p == obj_id_p) foo(); /* Ok */
+  if (obj_c_super_p == obj_id_p) foo() ; /* Ok */
+  if (obj_id_p == obj_c_cat_p)  foo(); /* Ok */
+  if (obj_id_p == obj_c_super_p)  foo(); /* Ok */
+
+  obj_c_cat_p = obj_c_super_p; // ok.
+  obj_c_cat_p = obj_c_super_p_q; // ok.
+  obj_c_super_p = obj_c_cat_p_q; // expected-warning {{incompatible pointer types}}
+  obj_c_cat_p_q = obj_c_super_p;
+  return 0;
+}
diff --git a/test/SemaObjC/comptypes-6.m b/test/SemaObjC/comptypes-6.m
new file mode 100644
index 0000000..98cf488
--- /dev/null
+++ b/test/SemaObjC/comptypes-6.m
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s
+
+@interface Derived
+@end
+
+@interface Object @end
+
+extern Object* foo(void);
+
+static Derived *test(void)
+{
+   Derived *m = foo();   // expected-warning {{incompatible pointer types initializing 'Derived *' with an expression of type 'Object *'}}
+
+   return m;
+}
+
diff --git a/test/SemaObjC/comptypes-7.m b/test/SemaObjC/comptypes-7.m
new file mode 100644
index 0000000..df627e5
--- /dev/null
+++ b/test/SemaObjC/comptypes-7.m
@@ -0,0 +1,75 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s
+
+#define nil (void *)0;
+#define Nil (void *)0;
+
+extern void foo();
+
+@protocol MyProtocol
+- (void) method;
+@end
+
+@interface MyClass
+@end
+
+int main()
+{
+  id obj = nil;
+  id <MyProtocol> obj_p = nil;
+  MyClass *obj_c = nil;
+  Class obj_C = Nil;
+  
+  int i = 0;
+  int *j = nil;
+
+  /* These should all generate warnings.  */
+  
+  obj = i; // expected-warning {{incompatible integer to pointer conversion assigning to 'id' from 'int'}}
+  obj = j; // expected-warning {{incompatible pointer types assigning to 'id' from 'int *'}}
+
+  obj_p = i; // expected-warning {{incompatible integer to pointer conversion assigning to 'id<MyProtocol>' from 'int'}}
+  obj_p = j; // expected-warning {{ incompatible pointer types assigning to 'id<MyProtocol>' from 'int *'}}
+  
+  obj_c = i; // expected-warning {{ incompatible integer to pointer conversion assigning to 'MyClass *' from 'int'}}
+  obj_c = j; // expected-warning {{incompatible pointer types assigning to 'MyClass *' from 'int *'}}
+
+  obj_C = i; // expected-warning {{incompatible integer to pointer conversion assigning to 'Class' from 'int'}}
+  obj_C = j; // expected-warning {{incompatible pointer types assigning to 'Class' from 'int *'}}
+  
+  i = obj;   // expected-warning {{incompatible pointer to integer conversion assigning to 'int' from 'id'}}
+  i = obj_p; // expected-warning {{incompatible pointer to integer conversion assigning to 'int' from 'id<MyProtocol>'}}
+  i = obj_c; // expected-warning {{incompatible pointer to integer conversion assigning to 'int' from 'MyClass *'}}
+  i = obj_C; // expected-warning {{incompatible pointer to integer conversion assigning to 'int' from 'Class'}}
+  
+  j = obj;   // expected-warning {{incompatible pointer types assigning to 'int *' from 'id'}}
+  j = obj_p; // expected-warning {{ incompatible pointer types assigning to 'int *' from 'id<MyProtocol>'}}
+  j = obj_c; // expected-warning {{incompatible pointer types assigning to 'int *' from 'MyClass *'}}
+  j = obj_C; // expected-warning {{incompatible pointer types assigning to 'int *' from 'Class'}}
+  
+  if (obj == i) foo() ; // expected-warning {{comparison between pointer and integer ('id' and 'int')}}
+  if (i == obj) foo() ; // expected-warning {{comparison between pointer and integer ('int' and 'id')}}
+  if (obj == j) foo() ; // expected-warning {{comparison of distinct pointer types ('id' and 'int *')}}
+  if (j == obj) foo() ; // expected-warning {{comparison of distinct pointer types ('int *' and 'id')}}
+
+  if (obj_c == i) foo() ; // expected-warning {{comparison between pointer and integer ('MyClass *' and 'int')}}
+  if (i == obj_c) foo() ; // expected-warning {{comparison between pointer and integer ('int' and 'MyClass *')}}
+  if (obj_c == j) foo() ; // expected-warning {{comparison of distinct pointer types ('MyClass *' and 'int *')}}
+  if (j == obj_c) foo() ; // expected-warning {{comparison of distinct pointer types ('int *' and 'MyClass *')}}
+
+  if (obj_p == i) foo() ; // expected-warning {{comparison between pointer and integer ('id<MyProtocol>' and 'int')}}
+  if (i == obj_p) foo() ; // expected-warning {{comparison between pointer and integer ('int' and 'id<MyProtocol>')}}
+  if (obj_p == j) foo() ; // expected-warning {{comparison of distinct pointer types ('id<MyProtocol>' and 'int *')}}
+  if (j == obj_p) foo() ; // expected-warning {{comparison of distinct pointer types ('int *' and 'id<MyProtocol>')}}
+
+  if (obj_C == i) foo() ; // expected-warning {{comparison between pointer and integer ('Class' and 'int')}}
+  if (i == obj_C) foo() ; // expected-warning {{comparison between pointer and integer ('int' and 'Class')}}
+  if (obj_C == j) foo() ; // expected-warning {{comparison of distinct pointer types ('Class' and 'int *')}}
+  if (j == obj_C) foo() ; // expected-warning {{comparison of distinct pointer types ('int *' and 'Class')}}
+
+  Class bar1 = Nil;
+  Class <MyProtocol> bar = Nil;
+  bar = bar1;
+  bar1 = bar;
+
+  return 0;
+}
diff --git a/test/SemaObjC/comptypes-8.m b/test/SemaObjC/comptypes-8.m
new file mode 100644
index 0000000..750b0a6
--- /dev/null
+++ b/test/SemaObjC/comptypes-8.m
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@protocol MyProtocol
+@end
+
+id<MyProtocol> obj_p = 0;
+
+int main()
+{
+  obj_p = 0;
+}
+
diff --git a/test/SemaObjC/comptypes-9.m b/test/SemaObjC/comptypes-9.m
new file mode 100644
index 0000000..cc6932d
--- /dev/null
+++ b/test/SemaObjC/comptypes-9.m
@@ -0,0 +1,86 @@
+// RUN: %clang_cc1 -fsyntax-only %s
+// FIXME: This test case tests the patch applied in: http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20080602/006017.html
+//   Eventually that logic should be treated as an extension.
+
+typedef signed char BOOL;
+typedef int NSInteger;
+typedef unsigned int NSUInteger;
+typedef struct _NSZone NSZone;
+@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+
+@protocol NSObject
+- (BOOL)isEqual:(id)object;
+@end
+
+@protocol NSCopying
+- (id)copyWithZone:(NSZone *)zone;
+@end
+
+@protocol NSMutableCopying
+- (id)mutableCopyWithZone:(NSZone *)zone;
+@end
+
+@protocol NSCoding
+- (void)encodeWithCoder:(NSCoder *)aCoder;
+@end
+
+@interface NSObject <NSObject> {}
+@end
+
+@class NSArray;
+
+typedef struct {} NSFastEnumerationState;
+
+@protocol NSFastEnumeration
+- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len;
+@end
+
+@class NSString;
+
+@interface NSArray : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration>
+- (NSUInteger)count;
+- (id)objectAtIndex:(NSUInteger)index;
+@end
+
+typedef unsigned short unichar;
+
+@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding>
+- (NSUInteger)length;
+@end
+
+@interface NSSimpleCString : NSString
+{}
+
+@end
+
+@interface NSConstantString : NSSimpleCString @end
+
+extern void *_NSConstantStringClassReference;
+
+@interface NSResponder : NSObject <NSCoding> {}
+@end
+
+@class NSDate, NSDictionary, NSError, NSException, NSNotification;
+
+@interface NSWindowController : NSResponder <NSCoding> {}
+@end
+
+@class PBXBuildLog, PBXBuildLogItem, PBXBuildLogContainerItem, XCWorkQueueCommand, XCBuildLogContainerItemMutationState;
+
+@protocol PBXBuildLogContainerItems <NSObject>
+- (PBXBuildLog *)buildLog;
+@end
+
+@interface PBXBuildLogItem : NSObject {}
+- (id <PBXBuildLogContainerItems>)superitem;
+@end
+@interface PBXBuildResultsModule
+@end
+
+@implementation PBXBuildResultsModule
+- (void) revealItems
+{
+        PBXBuildLogItem *objItem;
+        PBXBuildLogItem *superitem = [objItem superitem];
+}
+@end
diff --git a/test/SemaObjC/comptypes-a.m b/test/SemaObjC/comptypes-a.m
new file mode 100644
index 0000000..d48dfe4
--- /dev/null
+++ b/test/SemaObjC/comptypes-a.m
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s
+typedef signed char BOOL;
+typedef int NSInteger;
+
+@class NSString;
+
+@protocol PBXCompletionItem
+- (NSString *) name;
+- (NSInteger)priority;
+@end
+
+extern NSInteger codeAssistantCaseCompareItems(id a, id b, void *context);
+
+NSInteger codeAssistantCaseCompareItems(id<PBXCompletionItem> a, id<PBXCompletionItem> b, void *context)
+{
+  return 0;
+}
+
+@interface TedWantsToVerifyObjCDoesTheRightThing
+
+- compareThis:(int)a withThat:(id)b;  // expected-note {{previous definition is here}}
+
+@end
+
+@implementation TedWantsToVerifyObjCDoesTheRightThing
+
+- compareThis:(id<PBXCompletionItem>)
+    a // expected-warning {{conflicting parameter types in implementation of 'compareThis:withThat:': 'int' vs 'id<PBXCompletionItem>'}}
+     withThat:(id<PBXCompletionItem>)b {
+  return self;
+}
+
+@end
diff --git a/test/SemaObjC/comptypes-legal.m b/test/SemaObjC/comptypes-legal.m
new file mode 100644
index 0000000..d83d559
--- /dev/null
+++ b/test/SemaObjC/comptypes-legal.m
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s
+
+@protocol NSObject
+@end
+@interface NSObject <NSObject> {
+}
+@end
+@interface NSString : NSObject
+@end
+void __setRetained(id *ivar, id value, NSObject **o) {
+    *ivar = value;
+}
+static NSString *_logProcessPrefix = 0;
+void func() {
+  __setRetained(&_logProcessPrefix, _logProcessPrefix, &_logProcessPrefix);
+}
+@implementation NSObject (ScopeAdditions)
++ (void)setObjectLogProcessPrefix:(NSString *)processPrefix {
+    __setRetained(&_logProcessPrefix, processPrefix, &_logProcessPrefix);
+}
+@end
+
+@class Derived;
+
+NSObject *ExternFunc (NSObject *filePath, NSObject *key);
+typedef id FuncSignature (NSObject *arg1, Derived *arg2);
+
+@interface Derived: NSObject
++ (void)registerFunc:(FuncSignature *)function; // expected-note{{passing argument to parameter 'function' here}}
+@end
+
+void foo(void)
+{
+  // GCC currently allows this (it has some fiarly new support for covariant return types and contravariant argument types).
+  // Since registerFunc: expects a Derived object as it's second argument, I don't know why this would be legal.
+  [Derived registerFunc: ExternFunc];  // expected-warning{{incompatible pointer types sending 'NSObject *(NSObject *, NSObject *)' to parameter of type 'FuncSignature *'}}
+}
diff --git a/test/SemaObjC/conditional-expr-2.m b/test/SemaObjC/conditional-expr-2.m
new file mode 100644
index 0000000..fdf3d13
--- /dev/null
+++ b/test/SemaObjC/conditional-expr-2.m
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@interface A
+@end
+@interface B
+@end
+
+void f0(int cond, A *a, B *b) {
+  // Ensure that we can still send a message to result of incompatible
+  // conditional expression.
+  [ (cond ? a : b) test ]; // expected-warning{{incompatible operand types ('A *' and 'B *')}} expected-warning {{method '-test' not found}}
+}
+
+@interface NSKey @end
+@interface KeySub : NSKey @end
+
+@interface UpdatesList @end
+
+void foo (int i, NSKey *NSKeyValueCoding_NullValue, UpdatesList *nukedUpdatesList)
+{
+  id obj;
+  NSKey *key;
+  KeySub *keysub;
+
+  obj = i ? NSKeyValueCoding_NullValue : nukedUpdatesList; // expected-warning{{incompatible operand types ('NSKey *' and 'UpdatesList *')}}
+  key = i ? NSKeyValueCoding_NullValue : nukedUpdatesList; // expected-warning{{incompatible operand types ('NSKey *' and 'UpdatesList *')}}
+  key = i ? NSKeyValueCoding_NullValue : keysub;
+  keysub = i ? NSKeyValueCoding_NullValue : keysub; // expected-warning{{incompatible pointer types assigning to 'KeySub *' from 'NSKey *'}}
+}
diff --git a/test/SemaObjC/conditional-expr-3.m b/test/SemaObjC/conditional-expr-3.m
new file mode 100644
index 0000000..3b5f609
--- /dev/null
+++ b/test/SemaObjC/conditional-expr-3.m
@@ -0,0 +1,67 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@protocol P0
+@end
+@protocol P1
+@end
+@protocol P2
+@end
+
+@interface A <P0>
+@end
+
+@interface B : A
+@end
+
+void bar(id x);
+void barP0(id<P0> x);
+void barP1(id<P1> x);
+void barP2(id<P2> x);
+
+void f0(A *a) {
+  id l = a;
+}
+
+void f1(id x, A *a) {
+  id<P0> l = a;
+}
+
+void f2(id<P1> x) {
+  id<P0> l = x; // expected-warning {{initializing 'id<P0>' with an expression of incompatible type 'id<P1>'}}
+}
+
+void f3(A *a) {
+  id<P1> l = a; // expected-warning {{ initializing 'id<P1>' with an expression of incompatible type 'A *'}}
+}
+
+void f4(int cond, id x, A *a) {
+  bar(cond ? x : a);
+}
+
+void f5(int cond, A *a, B *b) {
+  bar(cond ? a : b);
+}
+
+void f6(int cond, id x, A *a) {
+  bar(cond ? (id<P0, P1>) x : a);
+}
+
+void f7(int cond, id x, A *a) {
+  bar(cond ? a : (id<P0, P1>) x);
+}
+
+void f8(int cond, id<P0,P1> x0, id<P0,P2> x1) {
+  barP0(cond ? x0 : x1); // expected-warning {{incompatible operand types ('id<P0,P1>' and 'id<P0,P2>')}}
+}
+
+void f9(int cond, id<P0,P1> x0, id<P0,P2> x1) {
+  barP1(cond ? x0 : x1); // expected-warning {{incompatible operand types ('id<P0,P1>' and 'id<P0,P2>')}}
+}
+
+void f10(int cond, id<P0,P1> x0, id<P0,P2> x1) {
+  barP2(cond ? x0 : x1); // expected-warning {{incompatible operand types ('id<P0,P1>' and 'id<P0,P2>')}}
+}
+
+int f11(int cond, A* a, B* b) {
+  return (cond? b : a)->x; // expected-error{{'A' does not have a member named 'x'}}
+}
diff --git a/test/SemaObjC/conditional-expr-4.m b/test/SemaObjC/conditional-expr-4.m
new file mode 100644
index 0000000..b3317f5
--- /dev/null
+++ b/test/SemaObjC/conditional-expr-4.m
@@ -0,0 +1,80 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// <rdar://problem/6212771>
+
+#define nil ((void*) 0)
+
+@interface A 
+@property int x;
+@end
+
+@interface B : A
+@end
+
+// Basic checks...
+id f0(int cond, id a, void *b) {
+  return cond ? a : b;
+}
+A *f0_a(int cond, A *a, void *b) {
+  return cond ? a : b;
+}
+
+id f1(int cond, id a) {
+  return cond ? a : nil;
+}
+A *f1_a(int cond, A *a) {
+  return cond ? a : nil;
+}
+
+void *f1_const_a(int x, void *p, const A * q) {
+  void *r = x ? p : q; // expected-warning{{initializing 'void *' with an expression of type 'void const *' discards qualifiers}}
+  return r;
+}
+
+// Check interaction with qualified id
+
+@protocol P0 @end
+
+id f2(int cond, id<P0> a, void *b) {
+  return cond ? a : b;
+}
+
+id f3(int cond, id<P0> a) {
+  return cond ? a : nil;
+}
+
+// Check that result actually has correct type.
+
+// Using properties is one way to find the compiler internal type of a
+// conditional expression. Simple assignment doesn't work because if
+// the type is id then it can be implicitly promoted.
+@protocol P1
+@property int x;
+@end
+
+int f5(int cond, id<P1> a, id<P1> b) {
+  return (cond ? a : b).x;
+}
+int f5_a(int cond, A *a, A *b) {
+  return (cond ? a : b).x;
+}
+int f5_b(int cond, A *a, B *b) {
+  return (cond ? a : b).x;
+}
+
+int f6(int cond, id<P1> a, void *b) {
+  // This should result in something with id type, currently.
+  return (cond ? a : b).x; // expected-error {{member reference base type 'void *' is not a structure or union}}
+}
+
+int f7(int cond, id<P1> a) {
+  return (cond ? a : nil).x;
+}
+
+int f8(int cond, id<P1> a, A *b) {
+  return a == b; // expected-warning {{comparison of distinct pointer types ('id<P1>' and 'A *')}}
+}
+
+int f9(int cond, id<P1> a, A *b) {
+  return (cond ? a : b).x; // expected-warning {{incompatible operand types ('id<P1>' and 'A *')}} \
+                              expected-error {{property 'x' not found on object of type 'id'}}
+}
diff --git a/test/SemaObjC/conditional-expr-5.m b/test/SemaObjC/conditional-expr-5.m
new file mode 100644
index 0000000..63afca1
--- /dev/null
+++ b/test/SemaObjC/conditional-expr-5.m
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1  -fsyntax-only -verify %s
+
+@interface PBXBuildSettingsDictionary
+{
+  int i;
+}
+@end
+
+@interface XCConditionalBuildSettingsDictionary : PBXBuildSettingsDictionary
+{
+}
+@end
+
+@implementation PBXBuildSettingsDictionary
+
+- (XCConditionalBuildSettingsDictionary *)conditionalDictionaryForConditionSet
+{
+  return i ? self : (id)0;
+}
+
+- (XCConditionalBuildSettingsDictionary *)conditionalDictionaryForConditionSet2
+{
+  return i ? (id)0 : self;
+}
+@end
+
+
diff --git a/test/SemaObjC/conditional-expr-6.m b/test/SemaObjC/conditional-expr-6.m
new file mode 100644
index 0000000..098688a
--- /dev/null
+++ b/test/SemaObjC/conditional-expr-6.m
@@ -0,0 +1,51 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@protocol MyProtocol @end
+
+@interface NSObject @end
+
+@interface NSInterm : NSObject <MyProtocol>
+@end
+
+@interface NSArray : NSInterm 
+@end
+
+@interface NSSet : NSObject <MyProtocol>
+@end
+
+
+@interface N1 : NSObject
+@end
+
+@interface N1() <MyProtocol>
+@end
+
+NSObject* test (int argc) {
+    NSArray *array = ((void*)0);
+    NSSet *set = ((void*)0);
+    return (argc) ? set : array ;
+}
+
+
+NSObject* test1 (int argc) {
+    NSArray *array = ((void*)0);
+    NSSet *set = ((void*)0);
+    id <MyProtocol> instance = (argc) ? array : set;
+    id <MyProtocol> instance1 = (argc) ? set : array;
+
+    N1 *n1 = ((void*)0);
+    id <MyProtocol> instance2 = (argc) ? set : n1;
+    id <MyProtocol> instance3 = (argc) ? n1 : array;
+
+    NSArray<MyProtocol> *qual_array = ((void*)0);
+    id <MyProtocol> instance4 = (argc) ? array : qual_array;
+    id <MyProtocol> instance5 = (argc) ? qual_array : array;
+    NSSet<MyProtocol> *qual_set = ((void*)0);
+    id <MyProtocol> instance6 = (argc) ? qual_set : qual_array;
+    id <MyProtocol> instance7 = (argc) ? qual_set : array;
+    id <MyProtocol> instance8 = (argc) ? qual_array : set;
+    id <MyProtocol> instance9 = (argc) ? qual_array : qual_set;
+
+
+    return (argc) ? array : set;
+}
diff --git a/test/SemaObjC/conditional-expr-7.m b/test/SemaObjC/conditional-expr-7.m
new file mode 100644
index 0000000..3ddf3d7
--- /dev/null
+++ b/test/SemaObjC/conditional-expr-7.m
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// radar 7682116
+
+@interface Super @end
+
+@interface NSArray : Super @end
+@interface NSSet : Super @end
+
+@protocol MyProtocol
+- (void)myMethod;
+@end
+
+@protocol MyProtocol2 <MyProtocol>
+- (void)myMethod2;
+@end
+
+@interface NSArray() <MyProtocol2>
+@end
+
+@interface NSSet() <MyProtocol>
+@end
+
+int main (int argc, const char * argv[]) {
+    NSArray *array = (void*)0;
+    NSSet *set = (void*)0;
+    id <MyProtocol> instance = (argc) ? array : set;
+    instance = (void*)0;
+    return 0;
+}
+
diff --git a/test/SemaObjC/conditional-expr.m b/test/SemaObjC/conditional-expr.m
new file mode 100644
index 0000000..74ab59b
--- /dev/null
+++ b/test/SemaObjC/conditional-expr.m
@@ -0,0 +1,119 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s
+@protocol NSObject
+@end
+
+@protocol DTOutputStreams <NSObject>
+@end
+
+@interface DTFilterOutputStream <DTOutputStreams>
+- nextOutputStream;
+@end
+
+@implementation DTFilterOutputStream
+- (id)initWithNextOutputStream:(id <DTOutputStreams>) outputStream {
+  id <DTOutputStreams> nextOutputStream = [self nextOutputStream];
+  self = nextOutputStream;
+  return nextOutputStream ? nextOutputStream : self;
+}
+- nextOutputStream {
+  return self;
+}
+@end
+
+@interface DTFilterOutputStream2
+- nextOutputStream; // expected-note {{{{method definition for 'nextOutputStream' not found}}
+@end
+
+@implementation DTFilterOutputStream2 // expected-warning {{incomplete implementation}}
+- (id)initWithNextOutputStream:(id <DTOutputStreams>) outputStream {
+  id <DTOutputStreams> nextOutputStream = [self nextOutputStream];
+  self = nextOutputStream; // expected-warning {{assigning to 'DTFilterOutputStream2 *' from incompatible type 'id<DTOutputStreams>'}}
+  return nextOutputStream ? nextOutputStream : self; // expected-warning {{incompatible operand types ('id<DTOutputStreams>' and 'DTFilterOutputStream2 *')}}
+}
+@end
+
+// No @interface declaration for DTFilterOutputStream3
+@implementation DTFilterOutputStream3 // expected-warning {{cannot find interface declaration for 'DTFilterOutputStream3'}}
+- (id)initWithNextOutputStream:(id <DTOutputStreams>) outputStream {
+  id <DTOutputStreams> nextOutputStream = [self nextOutputStream]; // expected-warning {{method '-nextOutputStream' not found (return type defaults to 'id')}}
+  self = nextOutputStream; // expected-warning {{assigning to 'DTFilterOutputStream3 *' from incompatible type 'id<DTOutputStreams>'}}
+  return nextOutputStream ? nextOutputStream : self; // expected-warning {{incompatible operand types ('id<DTOutputStreams>' and 'DTFilterOutputStream3 *')}}
+}
+@end
+
+//
+
+@protocol P0
+@property int intProp;
+@end
+@protocol P1
+@end
+@protocol P2
+@end
+
+@interface A <P0>
+@end
+
+@interface B : A
+@end
+
+@interface C
+@end
+
+@interface D
+@end
+
+void f0(id<P0> x) {
+  x.intProp = 1;
+}
+
+void f1(int cond, id<P0> x, id<P0> y) {
+  (cond ? x : y).intProp = 1;
+}
+
+void f2(int cond, id<P0> x, A *y) {
+  (cond ? x : y).intProp = 1;
+}
+
+void f3(int cond, id<P0> x, B *y) {
+  (cond ? x : y).intProp = 1;
+}
+
+void f4(int cond, id x, B *y) {
+  (cond ? x : y).intProp = 1; // expected-error {{property 'intProp' not found on object of type 'id'}}
+}
+
+void f5(int cond, id<P0> x, C *y) {
+  (cond ? x : y).intProp = 1; // expected-warning {{incompatible operand types ('id<P0>' and 'C *')}} expected-error {{property 'intProp' not found on object of type 'id'}}
+}
+
+void f6(int cond, C *x, D *y) {
+  (cond ? x : y).intProp = 1; // expected-warning {{incompatible operand types}}, expected-error {{property 'intProp' not found on object of type 'id'}}
+}
+
+id f7(int a, id<P0> x, A* p) {
+  return a ? x : p;
+}
+
+void f8(int a, A<P0> *x, A *y) {
+  [ (a ? x : y ) intProp ];
+}
+
+void f9(int a, A<P0> *x, A<P1> *y) {
+  id l0 = (a ? x : y ); // expected-warning {{incompatible operand types ('A<P0> *' and 'A<P1> *')'}}
+  A<P0> *l1 = (a ? x : y ); // expected-warning {{incompatible operand types ('A<P0> *' and 'A<P1> *')}}
+  A<P1> *l2 = (a ? x : y ); // expected-warning {{incompatible operand types ('A<P0> *' and 'A<P1> *')}}
+  [ (a ? x : y ) intProp ]; // expected-warning {{incompatible operand types ('A<P0> *' and 'A<P1> *')}}
+}
+
+void f10(int a, id<P0> x, id y) {
+  [ (a ? x : y ) intProp ];
+}
+
+void f11(int a, id<P0> x, id<P1> y) {
+  [ (a ? x : y ) intProp ]; // expected-warning {{incompatible operand types ('id<P0>' and 'id<P1>')}}
+}
+
+void f12(int a, A<P0> *x, A<P1> *y) {
+  A<P1>* l0 = (a ? x : y ); // expected-warning {{incompatible operand types ('A<P0> *' and 'A<P1> *')}}
+}
diff --git a/test/SemaObjC/conflicting-ivar-test-1.m b/test/SemaObjC/conflicting-ivar-test-1.m
new file mode 100644
index 0000000..1c68a23
--- /dev/null
+++ b/test/SemaObjC/conflicting-ivar-test-1.m
@@ -0,0 +1,86 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@interface INTF 
+{
+@public
+	int IVAR; // expected-note {{previous definition is here}}
+}
+@end
+
+@implementation INTF
+{
+@private
+
+        int XIVAR; // expected-error {{conflicting instance variable names: 'XIVAR' vs 'IVAR'}}
+}
+@end
+
+
+
+@interface INTF1 
+{
+@public
+	int IVAR;
+	int IVAR1; // expected-error {{inconsistent number of instance variables specified}}
+}
+@end
+
+@implementation INTF1
+{
+@private
+
+        int IVAR;
+}
+@end
+
+
+@interface INTF2 
+{
+@public
+	int IVAR;
+}
+@end
+
+@implementation INTF2
+{
+@private
+
+        int IVAR;
+	int IVAR1; // expected-error {{inconsistent number of instance variables specified}}
+}
+@end
+
+
+@interface INTF3
+{
+@public
+	int IVAR; // expected-note {{previous definition is here}}
+}
+@end
+
+@implementation INTF3
+{
+@private
+
+        short IVAR; // expected-error {{instance variable 'IVAR' has conflicting type: 'short' vs 'int'}}
+}
+@end
+
+@implementation  INTF4 // expected-warning {{cannot find interface declaration for 'INTF4'}}
+{
+@private
+
+        short IVAR;
+}
+@end
+
+@interface INTF5
+{
+  char * ch;
+}
+@end
+
+@implementation  INTF5
+{
+}
+@end
diff --git a/test/SemaObjC/continuation-class-err.m b/test/SemaObjC/continuation-class-err.m
new file mode 100644
index 0000000..2525182
--- /dev/null
+++ b/test/SemaObjC/continuation-class-err.m
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@interface ReadOnly 
+{
+  id _object;
+  id _object1;
+}
+@property(readonly) id object;	// expected-note {{property declared here}}
+@property(readwrite, assign) id object1; // expected-note {{property declared here}}
+@property (readonly) int indentLevel;
+@end
+
+@interface ReadOnly ()
+@property(readwrite, copy) id object;	// expected-warning {{property attribute in continuation class does not match the primary class}}
+@property(readonly) id object1; // expected-error {{illegal declaration of property in continuation class 'ReadOnly': attribute must be}}
+@property (readwrite, assign) int indentLevel; // OK. assign the the default in any case.
+@end
+
+@protocol Proto
+  @property (copy) id fee; // expected-note {{property declared here}}
+@end
+
+@protocol Foo<Proto>
+  @property (copy) id foo; // expected-note {{property declared here}}
+@end
+
+@interface Bar  <Foo> {
+        id _foo;
+        id _fee;
+}
+@end
+
+@interface Bar ()
+@property (copy) id foo;	// expected-error {{illegal declaration of property in continuation class 'Bar': attribute must be}}
+@property (copy) id fee;	// expected-error {{illegal declaration of property in continuation class 'Bar': attribute must be}}
+@end
+
+@implementation Bar
+@synthesize foo = _foo;
+@synthesize fee = _fee;
+@end
+
diff --git a/test/SemaObjC/continuation-class-property.m b/test/SemaObjC/continuation-class-property.m
new file mode 100644
index 0000000..c48a23d
--- /dev/null
+++ b/test/SemaObjC/continuation-class-property.m
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1  -fsyntax-only -verify %s
+// radar 7509234
+
+@protocol Foo
+@property (readonly, copy) id foos;
+@end
+
+@interface Bar <Foo> {
+}
+
+@end
+
+@interface Baz  <Foo> {
+}
+@end
+
+@interface Bar ()
+@property (readwrite, copy) id foos;
+@end
+
+@interface Baz ()
+@property (readwrite, copy) id foos;
+@end
+
diff --git a/test/SemaObjC/crash-label.m b/test/SemaObjC/crash-label.m
new file mode 100644
index 0000000..d0a5ae4
--- /dev/null
+++ b/test/SemaObjC/crash-label.m
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1  -fsyntax-only -verify %s
+
+  - (NSDictionary*) _executeScript:(NSString *)source { // expected-error 2 {{expected a type}} \
+							// expected-error {{missing context for method declaration}} 
+                          Exit:  [nilArgs release]; // expected-error {{use of undeclared identifier}}
+                          }
+                                     - (NSDictionary *) _setupKernelStandardMode:(NSString *)source { // expected-error 2 {{expected a type}} \
+expected-error {{missing context for method declaration}}
+                           Exit:   if(_ciKernel && !success ) { // expected-error {{use of undeclared identifier}} // expected-error 2 {{expected}}
diff --git a/test/SemaObjC/default-synthesize.m b/test/SemaObjC/default-synthesize.m
new file mode 100644
index 0000000..b892dfa
--- /dev/null
+++ b/test/SemaObjC/default-synthesize.m
@@ -0,0 +1,95 @@
+// RUN: %clang_cc1 -fsyntax-only -fobjc-nonfragile-abi2 -verify %s
+
+@interface NSString @end
+
+@interface NSObject @end
+
+@interface SynthItAll
+@property int howMany;
+@property (retain) NSString* what;
+@end
+
+@implementation SynthItAll
+//@synthesize howMany, what;
+@end
+
+
+@interface SynthSetter : NSObject
+@property (nonatomic) int howMany;  // REM: nonatomic to avoid warnings about only implementing one of the pair
+@property (nonatomic, retain) NSString* what;
+@end
+
+@implementation SynthSetter
+//@synthesize howMany, what;
+
+- (int) howMany {
+    return self.howMany;
+}
+// - (void) setHowMany: (int) value
+
+- (NSString*) what {
+    return self.what;
+}
+// - (void) setWhat: (NSString*) value    
+@end
+
+
+@interface SynthGetter : NSObject
+@property (nonatomic) int howMany;  // REM: nonatomic to avoid warnings about only implementing one of the pair
+@property (nonatomic, retain) NSString* what;
+@end
+
+@implementation SynthGetter
+//@synthesize howMany, what;
+
+// - (int) howMany
+- (void) setHowMany: (int) value {
+    self.howMany = value;
+}
+
+// - (NSString*) what
+- (void) setWhat: (NSString*) value {
+    if (self.what != value) {
+    }
+}
+@end
+
+
+@interface SynthNone : NSObject
+@property int howMany;
+@property (retain) NSString* what;
+@end
+
+@implementation SynthNone
+//@synthesize howMany, what;  // REM: Redundant anyway
+
+- (int) howMany {
+    return self.howMany;
+}
+- (void) setHowMany: (int) value {
+    self.howMany = value;
+}
+
+- (NSString*) what {
+    return self.what;
+}
+- (void) setWhat: (NSString*) value {
+    if (self.what != value) {
+    }
+}
+@end
+
+@protocol TopProtocol
+  @property (readonly) id myString;
+@end
+
+@interface TopClass <TopProtocol> 
+{
+  id myString; // expected-note {{previously declared 'myString' here}}
+}
+@end
+
+@interface SubClass : TopClass <TopProtocol> 
+@end
+
+@implementation SubClass @end // expected-error {{property 'myString' attempting to use ivar 'myString' declared in super class 'TopClass'}}
diff --git a/test/SemaObjC/deref-interface.m b/test/SemaObjC/deref-interface.m
new file mode 100644
index 0000000..c7096bd
--- /dev/null
+++ b/test/SemaObjC/deref-interface.m
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fobjc-nonfragile-abi -verify -fsyntax-only %s
+
+@interface NSView 
+  - (id)initWithView:(id)realView;
+@end
+
+@implementation NSView
+ - (id)initWithView:(id)realView {
+     *(NSView *)self = *(NSView *)realView;	// expected-error {{indirection cannot be to an interface in non-fragile ABI}}
+ }
+@end
+
diff --git a/test/SemaObjC/duplicate-ivar-check.m b/test/SemaObjC/duplicate-ivar-check.m
new file mode 100644
index 0000000..260c215
--- /dev/null
+++ b/test/SemaObjC/duplicate-ivar-check.m
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@interface B1 {
+@public
+  double fill_B;	// expected-note {{previous declaration is here}}
+  unsigned : 0;
+}
+@end
+
+@interface B : B1 {
+@public
+  int one;	// expected-note {{previous declaration is here}}
+  int one;	// expected-error {{duplicate member 'one'}}
+  unsigned : 0;
+}
+@end
+
+@interface A : B {
+@public
+  int fill_B;	// expected-error {{duplicate member 'fill_B'}}
+}
+@end
diff --git a/test/SemaObjC/duplicate-ivar-in-class-extension.m b/test/SemaObjC/duplicate-ivar-in-class-extension.m
new file mode 100644
index 0000000..b66736f
--- /dev/null
+++ b/test/SemaObjC/duplicate-ivar-in-class-extension.m
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -fsyntax-only -fobjc-nonfragile-abi2 -verify %s
+
+@interface Root @end
+
+@interface SuperClass  : Root 
+{
+  int iSuper;	// expected-note {{previous declaration is here}}
+}
+@end
+
+@interface SubClass : SuperClass {
+    int ivar;	// expected-error {{duplicate member 'ivar'}}
+    int another_ivar;	// expected-error {{duplicate member 'another_ivar'}}
+    int iSuper;	// expected-error {{duplicate member 'iSuper'}}
+}
+@end
+
+@interface SuperClass () {
+   int ivar;	// expected-note {{previous declaration is here}}
+}
+@end
+
+@interface Root () {
+  int another_ivar;	// expected-note {{previous declaration is here}}
+}
+@end
+
+@implementation SubClass
+-(int) method {
+        return self->ivar;  // would be ambiguous if the duplicate ivar were allowed
+}
+@end
diff --git a/test/SemaObjC/duplicate-property-class-extension.m b/test/SemaObjC/duplicate-property-class-extension.m
new file mode 100644
index 0000000..bdf4786
--- /dev/null
+++ b/test/SemaObjC/duplicate-property-class-extension.m
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1  -fsyntax-only -verify %s
+
+@interface Foo 
+@property (readonly) char foo;
+@end
+
+@interface Foo ()
+@property (readwrite) char foo; // expected-note {{property declared here}}
+@end
+
+@interface Foo ()
+@property (readwrite) char foo;	// expected-error {{property has a previous declaration}}
+@end
diff --git a/test/SemaObjC/duplicate-property.m b/test/SemaObjC/duplicate-property.m
new file mode 100644
index 0000000..bc1fe71
--- /dev/null
+++ b/test/SemaObjC/duplicate-property.m
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@interface Foo {
+  id x;
+}
+@property (nonatomic, retain) id x; // expected-note{{property declared here}}
+@property (nonatomic, retain) id x; // expected-error{{property has a previous declaration}}
+@end
diff --git a/test/SemaObjC/enhanced-proto-2.m b/test/SemaObjC/enhanced-proto-2.m
new file mode 100644
index 0000000..da7875c
--- /dev/null
+++ b/test/SemaObjC/enhanced-proto-2.m
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -verify %s
+
+@protocol MyProto1 
+@optional
+- (void) FOO;
+@optional
+- (void) FOO;
+@optional 
+- (void) REQ;
+@optional
+@end
+
+@interface  MyProto2 <MyProto1>
+- (void) FOO2;
+- (void) FOO3;
+@end
+
+@implementation MyProto2
+- (void) FOO2{}
+- (void) FOO3{}
+@end
diff --git a/test/SemaObjC/error-property-gc-attr.m b/test/SemaObjC/error-property-gc-attr.m
new file mode 100644
index 0000000..a361704
--- /dev/null
+++ b/test/SemaObjC/error-property-gc-attr.m
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -fobjc-gc -fsyntax-only -verify %s
+
+@interface INTF
+{
+  id IVAR;
+  __weak id II;
+  __weak id WID;
+  id ID;
+  __weak INTF* AWEAK;
+  __weak INTF* WI;
+}
+@property (assign) __weak id pweak;
+@property (assign) __weak id WID;
+@property (assign) __strong id not;
+@property (assign)  id ID;
+@property (assign) INTF* AWEAK;
+@property (assign) __weak INTF* WI;
+@end	
+
+@implementation INTF
+@synthesize pweak=IVAR;  // expected-error {{existing ivar 'IVAR' for __weak property 'pweak' must be __weak}}
+@synthesize not=II; // expected-error {{existing ivar 'II' for a __strong property 'not' must be garbage collectable}}
+@synthesize WID;
+@synthesize ID;
+@synthesize AWEAK; // expected-error {{existing ivar 'AWEAK' for a __strong property 'AWEAK' must be garbage collectable}}
+@synthesize WI;
+@end
diff --git a/test/SemaObjC/exprs.m b/test/SemaObjC/exprs.m
new file mode 100644
index 0000000..3370bda
--- /dev/null
+++ b/test/SemaObjC/exprs.m
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 %s -fsyntax-only -fblocks -verify -Wno-unreachable-code
+
+// rdar://6597252
+Class test1(Class X) {
+  return 1 ? X : X;
+}
+
+
+// rdar://6079877
+void test2() {
+  id str = @"foo" 
+          "bar\0"    // expected-warning {{literal contains NUL character}}
+          @"baz"  " blarg";
+  id str2 = @"foo" 
+            "bar"
+           @"baz"
+           " b\0larg";  // expected-warning {{literal contains NUL character}}
+
+  
+  if (@encode(int) == "foo") { }  // expected-warning {{result of comparison against @encode is unspecified}}
+}
+
+#define MAX(A,B) ({ __typeof__(A) __a = (A); __typeof__(B) __b = (B); __a < __b ? __b : __a; })
+void (^foo)(int, int) = ^(int x, int y) { int z = MAX(x, y); };
diff --git a/test/SemaObjC/foreach.m b/test/SemaObjC/foreach.m
new file mode 100644
index 0000000..0f7fd9e
--- /dev/null
+++ b/test/SemaObjC/foreach.m
@@ -0,0 +1,18 @@
+/* RUN: %clang_cc1 -Wall -fsyntax-only -verify -std=c89 -pedantic %s
+ */
+
+@class NSArray;
+
+void f(NSArray *a) {
+    id keys;
+    for (int i in a); /* expected-error{{selector element type 'int' is not a valid object}} */
+    for ((id)2 in a); /* expected-error{{selector element is not a valid lvalue}} */
+    for (2 in a); /* expected-error{{selector element is not a valid lvalue}} */
+  
+  /* This should be ok, 'thisKey' should be scoped to the loop in question,
+   * and no diagnostics even in pedantic mode should happen.
+   * rdar://6814674
+   */
+  for (id thisKey in keys);
+  for (id thisKey in keys);
+}
diff --git a/test/SemaObjC/format-arg-attribute.m b/test/SemaObjC/format-arg-attribute.m
new file mode 100644
index 0000000..264e7a8
--- /dev/null
+++ b/test/SemaObjC/format-arg-attribute.m
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -verify -fsyntax-only %s
+
+@class NSString;
+
+extern NSString *fa2 (const NSString *) __attribute__((format_arg(1)));
+extern NSString *fa3 (NSString *) __attribute__((format_arg(1)));
+
+extern void fc1 (const NSString *) __attribute__((format_arg));  // expected-error {{attribute requires 1 argument(s)}}
+extern void fc2 (const NSString *) __attribute__((format_arg())); // expected-error {{attribute requires 1 argument(s)}}
+extern void fc3 (const NSString *) __attribute__((format_arg(1, 2))); // expected-error {{attribute requires 1 argument(s)}}
+
+struct s1 { int i; } __attribute__((format_arg(1)));  // expected-warning {{'format_arg' attribute only applies to function types}}
+union u1 { int i; } __attribute__((format_arg(1)));  // expected-warning {{'format_arg' attribute only applies to function types}}
+enum e1 { E1V0 } __attribute__((format_arg(1))); // expected-warning {{'format_arg' attribute only applies to function types}}
+
+extern NSString *ff3 (const NSString *) __attribute__((format_arg(3-2)));
+extern NSString *ff4 (const NSString *) __attribute__((format_arg(foo))); // expected-error {{attribute requires 1 argument(s)}}
+
+/* format_arg formats must take and return a string.  */
+extern NSString *fi0 (int) __attribute__((format_arg(1)));  // expected-error {{format argument not a string type}}
+extern NSString *fi1 (NSString *) __attribute__((format_arg(1))); 
+
+extern NSString *fi2 (NSString *) __attribute__((format_arg(1))); 
+
+extern int fi3 (const NSString *) __attribute__((format_arg(1)));  // expected-error {{function does not return NSString}}
+extern NSString *fi4 (const NSString *) __attribute__((format_arg(1))); 
+extern NSString *fi5 (const NSString *) __attribute__((format_arg(1))); 
diff --git a/test/SemaObjC/format-strings-objc.m b/test/SemaObjC/format-strings-objc.m
new file mode 100644
index 0000000..1fcc34f
--- /dev/null
+++ b/test/SemaObjC/format-strings-objc.m
@@ -0,0 +1,57 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+//===----------------------------------------------------------------------===//
+// The following code is reduced using delta-debugging from
+// Foundation.h (Mac OS X).
+//
+// It includes the basic definitions for the test cases below.
+// Not including Foundation.h directly makes this test case both svelt and
+// portable to non-Mac platforms.
+//===----------------------------------------------------------------------===//
+
+typedef signed char BOOL;
+typedef unsigned int NSUInteger;
+@class NSString, Protocol;
+extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, 2)));
+typedef struct _NSZone NSZone;
+@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+@protocol NSObject  - (BOOL)isEqual:(id)object; @end
+@protocol NSCopying  - (id)copyWithZone:(NSZone *)zone; @end
+@protocol NSMutableCopying  - (id)mutableCopyWithZone:(NSZone *)zone; @end
+@protocol NSCoding  - (void)encodeWithCoder:(NSCoder *)aCoder; @end
+@interface NSObject <NSObject> {} @end
+typedef float CGFloat;
+@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding>    - (NSUInteger)length; @end
+@interface NSSimpleCString : NSString {} @end
+@interface NSConstantString : NSSimpleCString @end
+extern void *_NSConstantStringClassReference;
+
+typedef const struct __CFString * CFStringRef;
+extern void CFStringCreateWithFormat(CFStringRef format, ...) __attribute__((format(CFString, 1, 2)));
+
+int printf(const char * restrict, ...) ;
+
+//===----------------------------------------------------------------------===//
+// Test cases.
+//===----------------------------------------------------------------------===//
+
+void check_nslog(unsigned k) {
+  NSLog(@"%d%%", k); // no-warning
+  NSLog(@"%s%lb%d", "unix", 10,20); // expected-warning {{invalid conversion specifier 'b'}}
+}
+
+// Check type validation
+extern void NSLog2(int format, ...) __attribute__((format(__NSString__, 1, 2))); // expected-error {{format argument not an NSString}}
+extern void CFStringCreateWithFormat2(int *format, ...) __attribute__((format(CFString, 1, 2))); // expected-error {{format argument not a CFString}}
+
+// <rdar://problem/7068334> - Catch use of long long with int arguments.
+void rdar_7068334() {
+  long long test = 500;  
+  printf("%i ",test); // expected-warning{{conversion specifies type 'int' but the argument has type 'long long'}}
+  NSLog(@"%i ",test); // expected-warning{{conversion specifies type 'int' but the argument has type 'long long'}}
+}
+
+// <rdar://problem/7697748>
+void rdar_7697748() {
+  NSLog(@"%@!"); // expected-warning{{more '%' conversions than data arguments}}
+}
diff --git a/test/SemaObjC/forward-class-1.m b/test/SemaObjC/forward-class-1.m
new file mode 100644
index 0000000..ab213fb
--- /dev/null
+++ b/test/SemaObjC/forward-class-1.m
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@class FOO, BAR;
+@class FOO, BAR;
+
+@interface INTF : FOO	// expected-error {{cannot find interface declaration for 'FOO', superclass of 'INTF'}}
+@end
+
+@interface FOO 
+- (BAR*) Meth1;
+- (FOO*) Meth2;
+@end
+
+@interface INTF1 : FOO	
+@end
+
+@interface INTF2 : INTF1 // expected-note {{previous definition is here}}
+@end
+
+
+@class INTF1, INTF2;
+
+@interface INTF2 : INTF1 // expected-error {{duplicate interface definition for class 'INTF2'}}
+@end
+
+// 2nd test of a forward class declaration matching a typedef name
+// referring to class object.
+// FIXME. This may become a negative test should we decide to make this an error.
+//
+@interface NSObject @end
+
+@protocol XCElementP @end
+
+typedef NSObject <XCElementP> XCElement;
+
+@interface XCElementMainImp  {
+  XCElement * _editingElement;
+}
+@end
+
+@class XCElement;
+
+@implementation XCElementMainImp
+- (XCElement *)editingElement  { return _editingElement;  }
+@end
+
+
diff --git a/test/SemaObjC/forward-class-receiver.m b/test/SemaObjC/forward-class-receiver.m
new file mode 100644
index 0000000..55b29c1
--- /dev/null
+++ b/test/SemaObjC/forward-class-receiver.m
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1  -fsyntax-only -verify %s
+
+@interface I
++ new; // expected-note {{method 'new' is used for the forward class}}
+@end
+Class isa;
+
+@class NotKnown;
+
+void foo(NotKnown *n) {
+  [isa new];
+  [NotKnown new];	   /* expected-warning {{receiver 'NotKnown' is a forward class and corresponding}} */
+}
diff --git a/test/SemaObjC/gcc-cast-ext.m b/test/SemaObjC/gcc-cast-ext.m
new file mode 100644
index 0000000..599e37d
--- /dev/null
+++ b/test/SemaObjC/gcc-cast-ext.m
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 %s -verify -fms-extensions
+@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+typedef struct _NSRange { } NSRange;
+
+@class PBXFileReference;
+
+@interface PBXDocBookmark
++ alloc;	// expected-note {{{{method definition for 'alloc' not found}}
+- autorelease;	// expected-note {{{{method definition for 'autorelease' not found}}
+@end
+
+// GCC allows pointer expressions in integer constant expressions.
+struct {
+  char control[((int)(char *)2)];
+} xx;
+
+@implementation PBXDocBookmark  // expected-warning {{incomplete implementation}}
+
++ (id)bookmarkWithFileReference:(PBXFileReference *)fileRef gylphRange:(NSRange)range anchor:(NSString *)htmlAnchor
+{
+    NSRange r = (NSRange)range;
+    return [[[self alloc] initWithFileReference:fileRef gylphRange:(NSRange)range anchor:(NSString *)htmlAnchor] autorelease];  // expected-warning {{method '-initWithFileReference:gylphRange:anchor:' not found (return type defaults to 'id')}}
+}
+@end
diff --git a/test/SemaObjC/ibaction.m b/test/SemaObjC/ibaction.m
new file mode 100644
index 0000000..b97e002
--- /dev/null
+++ b/test/SemaObjC/ibaction.m
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 %s -verify
+
+@interface Foo 
+{
+  __attribute__((iboutlet)) id myoutlet;
+}
+- (void) __attribute__((ibaction)) myMessage:(id)msg;
+@end
+
+@implementation Foo
+// Normally attributes should not be attached to method definitions, but
+// we allow 'ibaction' to be attached because it can be expanded from
+// the IBAction macro.
+- (void) __attribute__((ibaction)) myMessage:(id)msg {} // no-warning
+@end
diff --git a/test/SemaObjC/id-isa-ref.m b/test/SemaObjC/id-isa-ref.m
new file mode 100644
index 0000000..a75f2f3
--- /dev/null
+++ b/test/SemaObjC/id-isa-ref.m
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+typedef struct objc_object {
+  struct objc_class *isa;
+} *id;
+
+@interface NSObject {
+  struct objc_class *isa;
+}
+@end
+@interface Whatever : NSObject
++self;
+@end
+
+static void func() {
+ 
+  id x;
+
+  [(*x).isa self];
+  [x->isa self];
+  
+  Whatever *y;
+
+  // GCC allows this, with the following warning: 
+  //   instance variable ‘isa’ is @protected; this will be a hard error in the future
+  //
+  // FIXME: see if we can avoid the 2 warnings that follow the error.
+  [(*y).isa self]; // expected-error {{instance variable 'isa' is protected}} \
+                      expected-warning{{receiver type 'struct objc_class *' is not 'id' or interface pointer, consider casting it to 'id'}} \
+                      expected-warning{{method '-self' not found (return type defaults to 'id')}}
+  [y->isa self]; // expected-error {{instance variable 'isa' is protected}} \
+                    expected-warning{{receiver type 'struct objc_class *' is not 'id' or interface pointer, consider casting it to 'id'}} \
+                    expected-warning{{method '-self' not found (return type defaults to 'id')}}
+}
diff --git a/test/SemaObjC/id.m b/test/SemaObjC/id.m
new file mode 100644
index 0000000..27b84de
--- /dev/null
+++ b/test/SemaObjC/id.m
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@protocol Foo;
+
+Class T;
+id<Foo> S;
+id R;
+void foo() {
+  // Test assignment compatibility of Class and id.  No warning should be
+  // produced.
+  // rdar://6770142 - Class and id<foo> are compatible.
+  S = T; // expected-warning {{incompatible pointer types assigning to 'id<Foo>' from 'Class'}}
+  T = S; // expected-warning {{incompatible pointer types assigning to 'Class' from 'id<Foo>'}}
+  R = T; T = R;
+  R = S; S = R;
+}
+
+// Test attempt to redefine 'id' in an incompatible fashion.
+typedef int id;  // FIXME: Decide how we want to deal with this (now that 'id' is more of a built-in type).
+id b;
+
diff --git a/test/SemaObjC/id_builtin.m b/test/SemaObjC/id_builtin.m
new file mode 100644
index 0000000..a1431d6
--- /dev/null
+++ b/test/SemaObjC/id_builtin.m
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify
+
+// id is now builtin. There should be no errors. 
+id obj; 
+
+@interface Foo
+
+- defaultToId; 
+
+@end
diff --git a/test/SemaObjC/idiomatic-parentheses.m b/test/SemaObjC/idiomatic-parentheses.m
new file mode 100644
index 0000000..011efbc
--- /dev/null
+++ b/test/SemaObjC/idiomatic-parentheses.m
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// Don't warn about some common ObjC idioms unless we have -Wparentheses on.
+// <rdar://problem/7382435>
+
+@interface Object 
+- (id) init;
+- (id) initWithInt: (int) i;
+- (void) iterate: (id) coll;
+- (id) nextObject;
+@end
+
+@implementation Object
+- (id) init {
+  if (self = [self init]) {
+  }
+  return self;
+}
+
+- (id) initWithInt: (int) i {
+  if (self = [self initWithInt: i]) {
+  }
+  return self;
+}
+
+- (void) iterate: (id) coll {
+  id cur;
+  while (cur = [coll nextObject]) {
+  }
+}
+
+- (id) nextObject {
+  return self;
+}
+@end
diff --git a/test/SemaObjC/ignore-weakimport-method.m b/test/SemaObjC/ignore-weakimport-method.m
new file mode 100644
index 0000000..f80312a
--- /dev/null
+++ b/test/SemaObjC/ignore-weakimport-method.m
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1  -fsyntax-only -verify %s
+
+@interface foo 
++ (void) cx __attribute__((weak_import));
+- (void) x __attribute__((weak_import));
+@end
+
diff --git a/test/SemaObjC/incompatible-protocol-qualified-types.m b/test/SemaObjC/incompatible-protocol-qualified-types.m
new file mode 100644
index 0000000..494d23e
--- /dev/null
+++ b/test/SemaObjC/incompatible-protocol-qualified-types.m
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -pedantic -fsyntax-only -verify %s
+
+@protocol MyProto1 
+@end
+
+@protocol MyProto2 
+@end
+
+@interface INTF @end
+
+INTF <MyProto1> * Func(INTF <MyProto1, MyProto2> *p2) // expected-note{{passing argument to parameter 'p2' here}}
+{
+	return p2;
+}
+
+
+INTF <MyProto1> * Func1(INTF <MyProto1, MyProto2> *p2)
+{
+	return p2;
+}
+
+INTF <MyProto1, MyProto2> * Func2(INTF <MyProto1> *p2)
+{
+	Func(p2);	// expected-warning {{incompatible pointer types passing 'INTF<MyProto1> *' to parameter of type 'INTF<MyProto1,MyProto2> *'}}
+	return p2;	// expected-warning {{incompatible pointer types returning 'INTF<MyProto1> *' from a function with result type 'INTF<MyProto1,MyProto2> *'}}
+}
+
+
+
+INTF <MyProto1> * Func3(INTF <MyProto2> *p2)
+{
+	return p2;	// expected-warning {{incompatible pointer types returning 'INTF<MyProto2> *' from a function with result type 'INTF<MyProto1> *'}}
+}
+
+
+INTF <MyProto1, MyProto2> * Func4(INTF <MyProto2, MyProto1> *p2)
+{
+	return p2;
+}
+
diff --git a/test/SemaObjC/inst-method-lookup-in-root.m b/test/SemaObjC/inst-method-lookup-in-root.m
new file mode 100644
index 0000000..babd2a0
--- /dev/null
+++ b/test/SemaObjC/inst-method-lookup-in-root.m
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1  -fsyntax-only -verify %s
+
+@protocol P
+- (id) inst_in_proto;
+@end
+
+@interface Object <P>
+- (id) inst_in_root;
+@end
+
+@interface Base
+@end
+
+@interface Derived: Base
+- (id)starboard;
+@end
+
+void foo(void) {
+  Class receiver;
+
+  [Derived starboard]; // expected-warning {{method '+starboard' not found}}
+
+  [receiver starboard]; // expected-warning {{instance method 'starboard' is being used on 'Class'}}
+  [receiver inst_in_root]; // Ok!
+  [receiver inst_in_proto]; // Ok!
+}
+
diff --git a/test/SemaObjC/interface-1.m b/test/SemaObjC/interface-1.m
new file mode 100644
index 0000000..91586c9
--- /dev/null
+++ b/test/SemaObjC/interface-1.m
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin9 %s -fsyntax-only -verify
+// rdar://5957506
+
+@interface NSWhatever :
+NSObject     // expected-error {{cannot find interface declaration for 'NSObject'}}
+<NSCopying>  // expected-error {{cannot find protocol declaration for 'NSCopying'}}
+@end
+
+
+// rdar://6095245
+@interface A
+{
+  int x
+}  // expected-error {{expected ';' at end of declaration list}}
+@end
+
+
+// rdar://4304469
+@interface INT1
+@end
+
+void test2() {
+    // rdar://6827200
+    INT1 b[3];          // expected-error {{array of interface 'INT1' is invalid (probably should be an array of pointers)}}
+    INT1 *c = &b[0];
+    ++c;
+}
+
+
+// rdar://6611778
+@interface FOO  // expected-note {{previous definition is here}}
+- (void)method;
+@end
+
+@interface FOO  // expected-error {{duplicate interface definition for class 'FOO'}}
+- (void)method2;
+@end
+
diff --git a/test/SemaObjC/interface-layout-2.m b/test/SemaObjC/interface-layout-2.m
new file mode 100644
index 0000000..02b1403
--- /dev/null
+++ b/test/SemaObjC/interface-layout-2.m
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify
+@interface A
+{
+  int ivar;
+}
+@end
+
+@interface B : A
+- (int)ivar;
+@end
+
+@implementation B
+- (int)ivar {
+  return ivar;
+} 
+@end
diff --git a/test/SemaObjC/interface-layout.m b/test/SemaObjC/interface-layout.m
new file mode 100644
index 0000000..72a7155
--- /dev/null
+++ b/test/SemaObjC/interface-layout.m
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify  -triple i386-apple-darwin9
+typedef struct objc_object {} *id;
+typedef signed char BOOL;
+typedef unsigned int NSUInteger;
+typedef struct _NSZone NSZone;
+
+@protocol NSObject
+- (BOOL) isEqual:(id) object;
+@end
+
+@protocol NSCopying
+- (id) copyWithZone:(NSZone *) zone;
+@end
+
+@interface NSObject < NSObject > {}
+@end
+
+extern id NSAllocateObject (Class aClass, NSUInteger extraBytes, NSZone * zone);
+
+@interface MyClassBase : NSObject < NSCopying > {}
+@end
+
+@interface MyClassDirectNode : MyClassBase < NSCopying >
+{
+  @public NSUInteger attributeRuns[((1024 - 16 - sizeof (MyClassBase)) / (sizeof (NSUInteger) + sizeof (void *)))];
+}
+@end
diff --git a/test/SemaObjC/interface-scope-2.m b/test/SemaObjC/interface-scope-2.m
new file mode 100644
index 0000000..d8046c9
--- /dev/null
+++ b/test/SemaObjC/interface-scope-2.m
@@ -0,0 +1,128 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -triple i686-apple-darwin9  %s
+// FIXME: must also compile as Objective-C++ 
+
+// <rdar://problem/6487662>
+typedef struct objc_selector *SEL;
+typedef signed char BOOL;
+typedef unsigned int NSUInteger;
+typedef struct _NSZone NSZone;
+@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+@protocol NSObject
+- (BOOL)isEqual:(id)object;
+- (BOOL)respondsToSelector:(SEL)aSelector;
+@end
+@protocol NSCopying
+- (id)copyWithZone:(NSZone *)zone;
+@end
+@protocol NSMutableCopying
+- (id)mutableCopyWithZone:(NSZone *)zone;
+@end
+@protocol NSCoding
+- (void)encodeWithCoder:(NSCoder *)aCoder;
+@end
+@interface NSObject <NSObject> {}
+@end
+@class NSString, NSData;
+typedef struct _NSPoint {}
+NSRange;
+@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding>
+- (NSUInteger)length;
+@end
+@interface NSMutableString : NSString
+- (void)replaceCharactersInRange:(NSRange)range withString:(NSString *)aString;
+@end
+@class NSArray, NSDictionary, NSMapTable;
+@interface NSResponder : NSObject <NSCoding> {}
+@end
+@protocol NSAnimatablePropertyContainer
+- (id)animator;
+@end
+extern NSString *NSAnimationTriggerOrderIn ;
+@interface NSView : NSResponder  <NSAnimatablePropertyContainer>  {
+  struct __VFlags2 {} _vFlags2;
+}
+@end
+@class NSAttributedString, NSEvent, NSFont, NSFormatter, NSImage, NSMenu, NSText, NSView;
+@interface FooiagramView : NSView {
+id _delegate;
+}
+@end
+@class FooiagramView;
+@interface _FooiagramViewReserved : NSObject {
+@public
+  NSMutableString *_typeToSelectString;
+  struct _FooiagramViewFlags {
+      unsigned int delegateRespondsToPrintInfoForBarView : 1;
+  } _dvFlags;
+}
+@end
+extern _FooiagramViewReserved *_FooiagramViewBarViewReserved(FooiagramView *BarView);
+@interface FooiagramView (FooiagramViewPrivate)
++ (Class)_defaultBarToolManagerClass;
+@end
+@implementation FooiagramView
+static NSMapTable *_defaultMenuForClass = 0;
+- (void)setDelegate:(id)delegate {
+  if (_delegate != delegate) {
+    struct _FooiagramViewFlags *dvFlags =
+      &_FooiagramViewBarViewReserved(self)->_dvFlags;
+    if (_delegate != ((void *)0)) {
+      dvFlags->delegateRespondsToPrintInfoForBarView = [_delegate respondsToSelector:@selector(printInfoForBarView:)];
+    }
+  }
+}
+@end
+
+// <rdar://problem/6487684>
+@interface WizKing_MIKeep {
+struct __LoreStuffNode *_historyStuff;
+}
+@end
+typedef struct __LoreStuffNode {} LoreStuffNode;
+@implementation WizKing_MIKeep
+- init {
+  LoreStuffNode *node;
+  node = &(_historyStuff[1]);
+  return 0;
+}
+@end
+
+// <rdar://problem/6487702>
+typedef long unsigned int __darwin_size_t;
+typedef __darwin_size_t size_t;
+void *memset(void *, int, size_t);
+@class NSString, NSURL, NSError;
+@interface OingoWerdnaPeon : NSObject {}
+@end        typedef enum {
+OingoPT_SmashOK,     OingoPT_NoSuchFile, }
+OingoWerdnaPeonIOMethod;
+@interface OingoWerdnaPeonSmashDrivel : NSObject <NSCopying> {}
+@end
+@interface OingoBoingoContraptionPeon : OingoWerdnaPeon {
+struct _OingoBoingoContraptionPeonFlags {}
+_nfttFlags;
+}
+@end
+@implementation OingoBoingoContraptionPeon
++ (void)initialize {}
+- (id)initWithSmashDrivel:(OingoWerdnaPeonSmashDrivel *)info {
+  if (self != ((void *)0)) {
+    (void)memset(&_nfttFlags, 0, sizeof(struct _OingoBoingoContraptionPeonFlags));
+  }
+  return 0;
+}
+@end
+
+@interface Blah {
+  struct X {
+    int x;
+  } value;
+}
+@end
+
+@implementation Blah
+- (int)getValue {
+  struct X *xp = &value;
+  return xp->x;
+}
+@end
diff --git a/test/SemaObjC/interface-scope.m b/test/SemaObjC/interface-scope.m
new file mode 100644
index 0000000..0671dae
--- /dev/null
+++ b/test/SemaObjC/interface-scope.m
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@interface I1 {
+@private
+  int x;
+  struct {
+    unsigned int x : 3;
+    unsigned int y : 3;
+  } flags;
+  int y;
+}
+@end
diff --git a/test/SemaObjC/interface-tu-variable.m b/test/SemaObjC/interface-tu-variable.m
new file mode 100644
index 0000000..b8779cc
--- /dev/null
+++ b/test/SemaObjC/interface-tu-variable.m
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@interface XX
+int x;  // expected-error {{cannot declare variable inside @interface or @protocol}}
+int one=1;  // expected-error {{cannot declare variable inside @interface or @protocol}}
+@end
+
+@protocol PPP
+int ddd; // expected-error {{cannot declare variable inside @interface or @protocol}}
+@end
+
+@interface XX(CAT)
+  char * III; // expected-error {{cannot declare variable inside @interface or @protocol}}
+  extern int OK;
+@end
+
+@interface XX()
+  char * III2; // expected-error {{cannot declare variable inside @interface or @protocol}}
+  extern int OK2;
+@end
+
+
+int main( int argc, const char *argv[] ) {
+    return x+one;
+}
+
diff --git a/test/SemaObjC/invalid-code.m b/test/SemaObjC/invalid-code.m
new file mode 100644
index 0000000..7a642fb
--- /dev/null
+++ b/test/SemaObjC/invalid-code.m
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify
+
+// rdar://6124613
+void test1() {
+  void *p = @1; // expected-error {{unexpected '@' in program}}
+}
+
+// <rdar://problem/7495713>
+// This previously triggered a crash because the class has not been defined.
+@implementation RDar7495713 (rdar_7495713_cat)  // expected-error{{cannot find interface declaration for 'RDar7495713'}}
+- (id) rdar_7495713 {
+  __PRETTY_FUNCTION__; // expected-warning{{expression result unused}}
+}
+@end
+
+// <rdar://problem/7881045>
+// This previously triggered a crash because a ';' was expected after the @throw statement.
+void foo() {
+  @throw (id)0 // expected-error{{expected ';' after @throw}}
+}
+
diff --git a/test/SemaObjC/invalid-objc-decls-1.m b/test/SemaObjC/invalid-objc-decls-1.m
new file mode 100644
index 0000000..91bd8a8
--- /dev/null
+++ b/test/SemaObjC/invalid-objc-decls-1.m
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@interface Super @end
+Super s1; // expected-error{{interface type cannot be statically allocated}}
+
+extern Super e1; // expected-error{{interface type cannot be statically allocated}}
+
+struct S {
+  Super s1; // expected-error{{interface type cannot be statically allocated}}
+};
+
+@protocol P1 @end
+
+@interface INTF
+{
+  Super ivar1; // expected-error{{interface type cannot be statically allocated}}
+}
+@end
+
+struct whatever {
+  Super objField; // expected-error{{interface type cannot be statically allocated}}
+};
+
+@interface MyIntf
+{
+  Super<P1> ivar1; // expected-error{{interface type cannot be statically allocated}}
+}
+@end
+
+Super foo( // expected-error{{interface interface type 'Super' cannot be returned by value; did you forget * in 'Super'}}
+          Super parm1) { // expected-error{{interface interface type 'Super' cannot be passed by value; did you forget * in 'Super'}}
+	Super p1; // expected-error{{interface type cannot be statically allocated}}
+	return p1;
+}
+
+@interface NSMutableSet @end
+
+@interface DVTDummyAnnotationProvider  
+  @property(readonly) NSMutableSet annotations;	// expected-error{{interface type cannot be statically allocated}}
+
+@end
+
diff --git a/test/SemaObjC/invalid-receiver.m b/test/SemaObjC/invalid-receiver.m
new file mode 100644
index 0000000..1174dd2
--- /dev/null
+++ b/test/SemaObjC/invalid-receiver.m
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+typedef struct NotAClass {
+  int a, b;
+} NotAClass;
+
+void foo() {
+  [NotAClass nonexistent_method]; // expected-error {{receiver type 'NotAClass' (aka 'struct NotAClass') is not an Objective-C class}}
+}
diff --git a/test/SemaObjC/invalid-typename.m b/test/SemaObjC/invalid-typename.m
new file mode 100644
index 0000000..50dd188
--- /dev/null
+++ b/test/SemaObjC/invalid-typename.m
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@class NSString, NSArray;
+
+@protocol ISyncSessionCallback 
+- (oneway void)clientWithId:(bycopy NSString *)clientId
+                   canBeginSyncingPlanWithId:(bycopy NSString *)planId
+                   syncModes:(bycopy NSArray /* ISDSyncState */ *)syncModes
+                   entities:(bycopy NSArray /* ISDEntity */ *)entities
+                   truthPullers:(bycopy NSDictionary /* NSString -> [NSString] */ *)truthPullers; // expected-error{{expected ')'}} expected-note {{to match this '('}}
+@end
+
diff --git a/test/SemaObjC/ivar-access-package.m b/test/SemaObjC/ivar-access-package.m
new file mode 100644
index 0000000..abc3420
--- /dev/null
+++ b/test/SemaObjC/ivar-access-package.m
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+typedef unsigned char BOOL;
+
+@interface NSObject {
+  id isa;
+}
++new;
++alloc;
+-init;
+-autorelease;
+@end
+
+@interface NSAutoreleasePool : NSObject
+- drain;
+@end
+ 
+@interface A : NSObject {
+@package
+    id object;
+}
+@end
+
+@interface B : NSObject
+- (BOOL)containsSelf:(A*)a;
+@end
+
+@implementation A
+@end
+
+@implementation B
+- (BOOL)containsSelf:(A*)a {
+    return a->object == self;
+}
+@end
+
+void NSLog(id, ...);
+
+int main (int argc, const char * argv[]) {
+    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+    A *a = [[A new] autorelease];
+    B *b = [[B new] autorelease];
+    NSLog(@"%s", [b containsSelf:a] ? "YES" : "NO");
+    [pool drain];
+    return 0;
+}
+
diff --git a/test/SemaObjC/ivar-access-tests.m b/test/SemaObjC/ivar-access-tests.m
new file mode 100644
index 0000000..8561220
--- /dev/null
+++ b/test/SemaObjC/ivar-access-tests.m
@@ -0,0 +1,122 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@interface MySuperClass
+{
+@private
+  int private;
+
+@protected
+  int protected;
+
+@public
+  int public;
+}
+@end
+
+@implementation MySuperClass
+- (void) test {
+    int access;
+    MySuperClass *s = 0;
+    access = s->private;   
+    access = s->protected;
+}
+@end
+
+
+@interface MyClass : MySuperClass 
+@end
+
+@implementation MyClass
+- (void) test {
+    int access;
+    MySuperClass *s = 0;
+    access = s->private; // expected-error {{instance variable 'private' is private}}
+    access = s->protected;
+    MyClass *m=0;
+    access = m->private; // expected-error {{instance variable 'private' is private}}
+    access = m->protected;
+}
+@end
+
+
+@interface Deeper : MyClass
+@end
+
+@implementation Deeper 
+- (void) test {
+    int access;
+    MySuperClass *s = 0;
+    access = s->private; // expected-error {{instance variable 'private' is private}}
+    access = s->protected;
+    MyClass *m=0;
+    access = m->private; // expected-error {{instance variable 'private' is private}}
+    access = m->protected;
+}
+@end
+
+@interface Unrelated
+@end
+
+@implementation Unrelated 
+- (void) test {
+    int access;
+    MySuperClass *s = 0;
+    access = s->private; // expected-error {{instance variable 'private' is private}}
+    access = s->protected; // expected-error {{instance variable 'protected' is protected}}
+    MyClass *m=0;
+    access = m->private; // expected-error {{instance variable 'private' is private}}
+    access = m->protected; // expected-error {{instance variable 'protected' is protected}}
+}
+@end
+
+int main (void)
+{
+  MySuperClass *s = 0;
+  int access;
+  access = s->private;   // expected-error {{instance variable 'private' is private}}
+  access = s->protected; // expected-error {{instance variable 'protected' is protected}}
+  return 0;
+}
+
+typedef signed char BOOL;
+typedef unsigned int NSUInteger;
+typedef struct _NSZone NSZone;
+@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+@protocol NSObject  - (BOOL)isEqual:(id)object;
+@end
+@protocol NSCoding  - (void)encodeWithCoder:(NSCoder *)aCoder;
+@end 
+@interface NSObject <NSObject> {}
+@end
+extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone);
+@interface NSResponder : NSObject <NSCoding> {}
+@end 
+@protocol NSAnimatablePropertyContainer
+- (id)animator;
+@end
+extern NSString *NSAnimationTriggerOrderIn ;
+@interface NSView : NSResponder  <NSAnimatablePropertyContainer>  {
+  struct __VFlags2 {
+  }
+  _vFlags2;
+}
+@end
+@class NSFontDescriptor, NSAffineTransform, NSGraphicsContext;
+@interface NSScrollView : NSView {}
+@end
+
+@class CasperMixerView;
+@interface CasperDiffScrollView : NSScrollView {
+@private
+  CasperMixerView *_comparatorView;
+  NSView *someField;
+}
+@end
+
+@implementation CasperDiffScrollView
++ (void)initialize {}
+static void _CasperDiffScrollViewInstallMixerView(CasperDiffScrollView *scrollView) {
+  if (scrollView->someField != ((void *)0)) {
+  }
+}
+@end
diff --git a/test/SemaObjC/ivar-in-class-extension-error.m b/test/SemaObjC/ivar-in-class-extension-error.m
new file mode 100644
index 0000000..6e0b577
--- /dev/null
+++ b/test/SemaObjC/ivar-in-class-extension-error.m
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1  -fsyntax-only -verify %s
+// rdar:// 6812436
+
+@interface A @end
+
+@interface A () { 
+  int _p0; // expected-error {{ivars may not be placed in class extension}}
+}
+@property int p0;
+@end
+
+@interface A(CAT) { 
+  int _p1; // expected-error {{ivars may not be placed in categories}}
+}
+@end
diff --git a/test/SemaObjC/ivar-in-class-extension.m b/test/SemaObjC/ivar-in-class-extension.m
new file mode 100644
index 0000000..4130d8f
--- /dev/null
+++ b/test/SemaObjC/ivar-in-class-extension.m
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -fsyntax-only -fobjc-nonfragile-abi2 -verify %s
+
+@interface SomeClass  @end
+
+int fn1(SomeClass *obj) {
+        obj->privateIvar = 1; // expected-error {{'SomeClass' does not have a member named 'privateIvar}}
+        return obj->publicIvar;     // expected-error {{'SomeClass' does not have a member named 'publicIvar'}}
+}
+
+@interface SomeClass () {
+// @private by default
+        int privateIvar;
+@public
+        int publicIvar;
+}
+@end
+
+int fn2(SomeClass *obj) {
+	obj->publicIvar = 1;
+        return obj->publicIvar    // ok
+             + obj->privateIvar;  // expected-error {{instance variable 'privateIvar' is private}}
+}
+
+@implementation SomeClass
+
+int fn3(SomeClass *obj) {
+	obj->privateIvar = 2;
+        return obj->publicIvar    // ok
+             + obj->privateIvar;  // ok
+    }
+@end
+
+@interface SomeClass (Category)
+    {	
+        int categoryIvar; // expected-error {{ivars may not be placed in categories}}
+    }
+@end
+
+@interface SomeClass (Category1)
+    {	
+    }
+@end
diff --git a/test/SemaObjC/ivar-in-implementations.m b/test/SemaObjC/ivar-in-implementations.m
new file mode 100644
index 0000000..4060526
--- /dev/null
+++ b/test/SemaObjC/ivar-in-implementations.m
@@ -0,0 +1,39 @@
+// RUN: %clang_cc1 -fsyntax-only -fobjc-nonfragile-abi2 -verify %s
+
+@interface Super @end
+
+@interface INTFSTANDALONE : Super
+{
+  id IVAR;	// expected-note {{previous definition is here}}
+}
+
+@end
+
+@implementation INTFSTANDALONE : Super // expected-warning {{class implementation may not have super class}}
+{
+  id PRIV_IVAR;
+@protected
+  id PRTCTD;	
+@private
+  id IVAR3;
+  int IVAR;	// expected-error {{instance variable is already declared}}
+@public
+  id IVAR4;
+}
+@end
+
+@interface Base @end
+
+@implementation Base { 
+    int ivar1; 
+@public
+    int ivar2; 
+} 
+@end
+
+id fn1(INTFSTANDALONE *b) { return b->PRIV_IVAR; } // expected-error {{instance variable 'PRIV_IVAR' is private}}
+
+id fn2(INTFSTANDALONE *b) { return b->PRTCTD; }  // expected-error {{instance variable 'PRTCTD' is protected}}
+
+id fn4(INTFSTANDALONE *b) { return b->IVAR4; }
+
diff --git a/test/SemaObjC/ivar-lookup-resolution-builtin.m b/test/SemaObjC/ivar-lookup-resolution-builtin.m
new file mode 100644
index 0000000..2e90e8e
--- /dev/null
+++ b/test/SemaObjC/ivar-lookup-resolution-builtin.m
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1  -fsyntax-only -verify %s
+// pr5986
+
+@interface Test {
+  int index;
+}
+- (int) index;
++ (int) ClassMethod;
+@end
+
+@implementation Test
+- (int) index
+{
+  return index;
+}
++ (int) ClassMethod
+{
+  return index;	// expected-error {{instance variable 'index' accessed in class method}}
+}
+@end
+
+@interface Test1 {
+}
+- (int) InstMethod;
++ (int) ClassMethod;
+@end
+
+@implementation Test1
+- (int) InstMethod
+{
+  return index;	// expected-warning {{implicitly declaring C library function 'index'}}	\
+                // expected-note {{please include the header <strings.h> or explicitly provide a declaration for 'index'}} \
+                // expected-warning {{incompatible pointer to integer conversion returning}}
+}
++ (int) ClassMethod
+{
+  return index; // expected-warning {{incompatible pointer to integer conversion returning}}
+}
+@end
+
diff --git a/test/SemaObjC/ivar-lookup.m b/test/SemaObjC/ivar-lookup.m
new file mode 100644
index 0000000..06e4711
--- /dev/null
+++ b/test/SemaObjC/ivar-lookup.m
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify
+
+@interface Test {
+   int x;
+}
+
+-(void) setX: (int) d;
+@end
+
+extern struct foo x;
+
+@implementation Test
+
+-(void) setX: (int) n {
+   x = n;
+}
+
+@end
+
+@interface Ivar
+- (float*)method;
+@end
+
+@interface A {
+  A *Ivar;
+}
+- (int*)method;
+@end
+
+@implementation A
+- (int*)method {
+  int *ip = [Ivar method]; // expected-warning{{warning: incompatible pointer types initializing 'int *' with an expression of type 'float *'}}
+                           // Note that there is no warning in Objective-C++
+  return 0;
+}
+@end
+
diff --git a/test/SemaObjC/ivar-ref-misuse.m b/test/SemaObjC/ivar-ref-misuse.m
new file mode 100644
index 0000000..ba2f115
--- /dev/null
+++ b/test/SemaObjC/ivar-ref-misuse.m
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@interface Sprite {
+  int sprite, spree;
+  int UseGlobalBar;
+}
++ (void)setFoo:(int)foo;
++ (void)setSprite:(int)sprite;
+- (void)setFoo:(int)foo;
+- (void)setSprite:(int)sprite;
+@end
+
+int spree = 23;
+int UseGlobalBar;
+
+@implementation Sprite
++ (void)setFoo:(int)foo {
+  sprite = foo;   // expected-error {{instance variable 'sprite' accessed in class method}}
+  spree = foo;
+  Xsprite = foo; // expected-error {{use of undeclared identifier 'Xsprite'}} 
+  UseGlobalBar = 10;
+}
++ (void)setSprite:(int)sprite {
+  int spree;
+  sprite = 15;
+  spree = 17;
+  ((Sprite *)self)->sprite = 16;   /* NB: This is how one _should_ access */
+  ((Sprite *)self)->spree = 18;    /* ivars from within class methods!    */
+}
+- (void)setFoo:(int)foo {
+  sprite = foo;
+  spree = foo;
+}
+- (void)setSprite:(int)sprite {
+  int spree;
+  sprite = 15;  // expected-warning {{local declaration of 'sprite' hides instance variable}}
+  self->sprite = 16;
+  spree = 17;  // expected-warning {{local declaration of 'spree' hides instance variable}}
+  self->spree = 18;
+}   
+@end
diff --git a/test/SemaObjC/ivar-sem-check-1.m b/test/SemaObjC/ivar-sem-check-1.m
new file mode 100644
index 0000000..de038f5
--- /dev/null
+++ b/test/SemaObjC/ivar-sem-check-1.m
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct S; // expected-note{{forward declaration of 'struct S'}}
+typedef int FOO();
+
+@interface INTF
+{
+	struct F {} JJ;
+	int arr[];  // expected-error {{field has incomplete type}}
+	struct S IC;  // expected-error {{field has incomplete type}}
+	struct T { // expected-note {{previous definition is here}}
+	  struct T {} X;  // expected-error {{nested redefinition of 'T'}}
+	}YYY; 
+	FOO    BADFUNC;  // expected-error {{field 'BADFUNC' declared as a function}}
+	int kaka;	// expected-note {{previous declaration is here}}
+	int kaka;	// expected-error {{duplicate member 'kaka'}}
+	char ch[];	// expected-error {{field has incomplete type}}
+}
+@end
diff --git a/test/SemaObjC/ivar-sem-check-2.m b/test/SemaObjC/ivar-sem-check-2.m
new file mode 100644
index 0000000..28c795e
--- /dev/null
+++ b/test/SemaObjC/ivar-sem-check-2.m
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1  -fsyntax-only -fobjc-nonfragile-abi -verify %s
+
+@interface Super  {
+  id value2; // expected-note {{previously declared 'value2' here}}
+} 
+@property(retain) id value;
+@property(retain) id value1;
+@property(retain) id prop;
+@end
+
+@interface Sub : Super 
+{
+  id value; 
+}
+@end
+
+@implementation Sub
+@synthesize value; // expected-note {{previous use is here}}
+@synthesize value1=value; // expected-error {{synthesized properties 'value1' and 'value' both claim ivar 'value'}} 
+@synthesize prop=value2;  // expected-error {{property 'prop' attempting to use ivar 'value2' declared in super class 'Super'}}
+@end
+
+
diff --git a/test/SemaObjC/legacy-implementation-1.m b/test/SemaObjC/legacy-implementation-1.m
new file mode 100644
index 0000000..e9abb87
--- /dev/null
+++ b/test/SemaObjC/legacy-implementation-1.m
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@implementation INTF // expected-warning {{cannot find interface declaration for 'INTF'}}
+@end
+
+INTF* pi;
+
+INTF* FUNC()
+{
+	return pi;
+}
diff --git a/test/SemaObjC/message.m b/test/SemaObjC/message.m
new file mode 100644
index 0000000..fed3961
--- /dev/null
+++ b/test/SemaObjC/message.m
@@ -0,0 +1,100 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+typedef struct objc_object {
+  Class isa;
+} *id;
+
+
+@interface foo
+- (void)meth;
+@end
+
+@implementation foo
+- (void) contents {}			// No declaration in @interface!
+- (void) meth { [self contents]; } 
+@end
+
+typedef struct _NSPoint {
+    float x;
+    float y;
+} NSPoint;
+
+typedef struct _NSSize {
+    float width; 
+    float height;
+} NSSize;
+
+typedef struct _NSRect {
+    NSPoint origin;
+    NSSize size;
+} NSRect;
+
+@interface AnyClass
+- (NSRect)rect;
+@end
+
+@class Helicopter;
+
+static void func(Helicopter *obj) {
+  // Note that the proto for "rect" is found in the global pool even when
+  // a statically typed object's class interface isn't in scope! This 
+  // behavior isn't very desirable, however wee need it for GCC compatibility.
+  NSRect r = [obj rect];
+}
+
+@interface NSObject @end
+
+extern Class NSClassFromObject(id object);
+
+@interface XX : NSObject 
+@end
+
+@implementation XX
+
++ _privateMethod {
+  return self;
+}
+
+- (void) xx {
+  [NSClassFromObject(self) _privateMethod];
+}
+@end
+
+@implementation XX (Private)
+- (void) yy {
+  [NSClassFromObject(self) _privateMethod];
+}
+@end
+
+@interface I0
+-(void) nonVararg: (int) x;
+@end
+
+int f0(I0 *ob) {
+  [ ob nonVararg: 0, 1, 2]; // expected-error {{too many arguments to method call}}
+}
+
+int f2() {
+    const id foo;
+    [foo bar];  // expected-warning {{method '-bar' not found (return type defaults to 'id')}}
+    return 0;
+}
+
+
+// PR3766
+struct S { int X; } S;
+
+int test5(int X) {
+  int a = [X somemsg];  // expected-warning {{receiver type 'int' is not 'id'}} \
+                           expected-warning {{method '-somemsg' not found}} \
+                           expected-warning {{incompatible pointer to integer conversion initializing 'int' with an expression of type 'id'}}
+  int b = [S somemsg];  // expected-error {{bad receiver type 'struct S'}}
+}
+
+// PR4021
+void foo4() {
+  struct objc_object X[10];
+  
+  [X rect]; // expected-warning {{receiver type 'struct objc_object *' is not 'id' or interface pointer, consider casting it to 'id'}} expected-warning {{method '-rect' not found (return type defaults to 'id')}}
+}
+
diff --git a/test/SemaObjC/method-arg-decay.m b/test/SemaObjC/method-arg-decay.m
new file mode 100644
index 0000000..012a3ee
--- /dev/null
+++ b/test/SemaObjC/method-arg-decay.m
@@ -0,0 +1,97 @@
+// RUN: %clang_cc1 -analyzer-check-objc-mem -verify %s
+typedef signed char BOOL;
+typedef int NSInteger;
+typedef unsigned int NSUInteger;
+typedef struct _NSZone NSZone;
+@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+@protocol NSObject  - (BOOL)isEqual:(id)object;
+@end  @protocol NSCopying  - (id)copyWithZone:(NSZone *)zone;
+@end  @protocol NSMutableCopying  - (id)mutableCopyWithZone:(NSZone *)zone;
+@end  @protocol NSCoding  - (void)encodeWithCoder:(NSCoder *)aCoder;
+@end    @interface NSObject <NSObject> {
+}
+@end    extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone);
+@interface NSValue : NSObject <NSCopying, NSCoding>  - (void)getValue:(void *)value;
+@end       @class NSString, NSData, NSMutableData, NSMutableDictionary, NSMutableArray;
+typedef struct {
+}
+  NSFastEnumerationState;
+@protocol NSFastEnumeration  - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len;
+@end        @class NSString;
+typedef struct _NSRange {
+}
+  NSRange;
+@interface NSValue (NSValueRangeExtensions)  + (NSValue *)valueWithRange:(NSRange)range;
+- (id)objectAtIndex:(NSUInteger)index;
+@end         typedef unsigned short unichar;
+@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding>    - (NSUInteger)length;
+@end       @class NSArray, NSDictionary, NSString, NSError;
+@interface NSSet : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration>  - (NSUInteger)count;
+@end    extern NSString *NSAccessibilityRoleDescription(NSString *role, NSString *subrole)     ;
+@interface NSResponder : NSObject <NSCoding> {
+}
+@end    @protocol NSAnimatablePropertyContainer      - (id)animator;
+@end  extern NSString *NSAnimationTriggerOrderIn ;
+@interface NSView : NSResponder  <NSAnimatablePropertyContainer>  {
+}
+@end  @class NSAttributedString, NSEvent, NSFont, NSFormatter, NSImage, NSMenu, NSText, NSView;
+@interface NSWindowController : NSResponder <NSCoding> {
+}
+@end @class NSArray, NSFont, NSTabViewItem;
+@interface NSTabView : NSView {
+}
+- (NSArray *)tabViewItems;
+- (NSString *)label;
+@end typedef enum {
+PBXNoItemChanged = 0x00,     PBXProjectItemChanged = 0x01,     PBXReferenceChanged = 0x02,     PBXGroupChanged = 0x04,     PBXTargetChanged = 0x08,     PBXBuildPhaseChanged = 0x10,     PBXBuildFileChanged = 0x20,     PBXBreakpointChanged = 0x40, }
+  PBXArchiveMask;
+@interface PBXModule : NSWindowController {
+}
+@end       typedef enum {
+PBXFindMatchContains,     PBXFindMatchStartsWith,     PBXFindMatchWholeWords,     PBXFindMatchEndsWith }
+  PBXFindMatchStyle;
+@protocol PBXSelectableText  - (NSString *)selectedString;
+@end  @protocol PBXFindableText <PBXSelectableText>    - (BOOL)findText:(NSString *)string ignoreCase:(BOOL)ignoreCase matchStyle:(PBXFindMatchStyle)matchStyle backwards:(BOOL)backwards wrap:(BOOL)wrap;
+@end  @class PBXProjectDocument, PBXProject, PBXAttributedStatusView;
+@interface PBXProjectModule : PBXModule <PBXFindableText> {
+}
+@end @class PBXBookmark;
+@protocol PBXSelectionTarget - (NSObject <PBXSelectionTarget> *) performAction:(id)action withSelection:(NSArray *)selection; // expected-warning {{method in protocol not implemented [-Wprotocol]}}
+@end @class XCPropertyDictionary, XCPropertyCondition, XCPropertyConditionSet, XCMutablePropertyConditionSet;
+extern NSMutableArray *XCFindPossibleKeyModules(PBXModule *module, BOOL useExposedModulesOnly);
+@interface NSString (StringUtilities) - (NSString *) trimToLength:(NSInteger)length preserveRange:(NSRange)range;
+- (id) objectOfType:(Class)type matchingFunction:(BOOL (void *, void *))comparator usingData:(void *)data;
+@end  @class XCControlView;
+@protocol XCDockViewHeader - (NSImage *) headerImage;
+@end  @class XCDockableTabModule;
+@interface XCExtendedTabView : NSTabView <XCDockViewHeader> {
+}
+@end     @class PBXProjectDocument, PBXFileReference, PBXModule, XCWindowTool;
+@interface XCPerspectiveModule : PBXProjectModule <PBXSelectionTarget> { // expected-note {{required for direct or indirect protocol 'PBXSelectionTarget'}}
+  XCExtendedTabView *_perspectivesTabView;
+}
+- (PBXModule *) moduleForTab:(NSTabViewItem *)item; // expected-note {{method definition for 'moduleForTab:' not found}}
+@end  
+@implementation XCPerspectiveModule // expected-warning {{incomplete implementation}}
++ (void) openForProjectDocument:(PBXProjectDocument *)projectDocument {
+}
+- (PBXModule *) type:(Class)type inPerspective:(id)perspectiveIdentifer  matchingFunction:(BOOL (void *, void *))comparator usingData:(void *)data {
+  NSArray *allItems = [_perspectivesTabView tabViewItems];
+  NSInteger i, c = [allItems count];
+  for (i = 0;
+       i < c;
+       i++) {
+    NSTabViewItem *item = [allItems objectAtIndex:i];
+    if ([[item label] isEqual:perspectiveIdentifer]) {
+      PBXProjectModule *pModule = (PBXProjectModule *)[self moduleForTab:item];
+      PBXModule *obj = [XCFindPossibleKeyModules(pModule, (BOOL)0) objectOfType:type     matchingFunction:comparator usingData:data];
+    }
+  }
+  return 0;
+}
+- (BOOL)buffer:(char *)buf containsAnyPrompts:(char *[])prompts
+{
+ prompts++;
+ return (BOOL)0;
+}
+@end
diff --git a/test/SemaObjC/method-arg-qualifier-warning.m b/test/SemaObjC/method-arg-qualifier-warning.m
new file mode 100644
index 0000000..463fb7f
--- /dev/null
+++ b/test/SemaObjC/method-arg-qualifier-warning.m
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1  -fsyntax-only -verify %s
+
+typedef signed char BOOL;
+
+@interface NSString
+- (BOOL)isEqualToString:(NSString *)aString; // expected-note 2{{passing argument to parameter 'aString' here}}
+@end
+
+static const NSString * Identifier1 =   @"Identifier1";
+static NSString const * Identifier2 =   @"Identifier2";
+static NSString * const Identifier3 =   @"Identifier3";
+
+int main () {
+        
+    [@"Identifier1" isEqualToString:Identifier1]; // expected-warning {{sending 'NSString const *' to parameter of type 'NSString *' discards qualifiers}}
+    [@"Identifier2" isEqualToString:Identifier2]; // expected-warning {{sending 'NSString const *' to parameter of type 'NSString *' discards qualifiers}}
+    [@"Identifier3" isEqualToString:Identifier3];
+    return 0;
+}
+
diff --git a/test/SemaObjC/method-attributes.m b/test/SemaObjC/method-attributes.m
new file mode 100644
index 0000000..9157fcf
--- /dev/null
+++ b/test/SemaObjC/method-attributes.m
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -verify -fsyntax-only %s
+
+@class NSString;
+
+@interface A
+-t1 __attribute__((noreturn));
+- (NSString *)stringByAppendingFormat:(NSString *)format, ... __attribute__((format(__NSString__, 1, 2)));
+-(void) m0 __attribute__((noreturn));
+-(void) m1 __attribute__((unused));
+@end
+
+
+@interface INTF
+- (int) foo1: (int)arg1 __attribute__((deprecated));
+
+- (int) foo: (int)arg1; 
+
+- (int) foo2: (int)arg1 __attribute__((deprecated)) __attribute__((unavailable));
+@end
+
+@implementation INTF
+- (int) foo: (int)arg1  __attribute__((deprecated)){ // expected-warning {{method attribute can only be specified}}
+        return 10;
+}
+- (int) foo1: (int)arg1 {
+        return 10;
+}
+- (int) foo2: (int)arg1 __attribute__((deprecated)) {  // expected-warning {{method attribute can only be specified}}
+        return 10;
+}
+@end
+
diff --git a/test/SemaObjC/method-bad-param.m b/test/SemaObjC/method-bad-param.m
new file mode 100644
index 0000000..324ed34
--- /dev/null
+++ b/test/SemaObjC/method-bad-param.m
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@interface foo
+@end
+
+@implementation foo
+@end
+
+@interface bar
+-(void) my_method:(foo) my_param; // expected-error {{Objective-C interface type 'foo' cannot be passed by value; did you forget * in 'foo'}}
+- (foo)cccccc:(long)ddddd;  // expected-error {{Objective-C interface type 'foo' cannot be returned by value; did you forget * in 'foo'}}
+@end
+
+@implementation bar
+-(void) my_method:(foo) my_param  // expected-error {{Objective-C interface type 'foo' cannot be passed by value; did you forget * in 'foo'}}
+{
+}
+- (foo)cccccc:(long)ddddd // expected-error {{Objective-C interface type 'foo' cannot be returned by value; did you forget * in 'foo'}}
+{
+}
+@end
+
+void somefunc(foo x) {} // expected-error {{Objective-C interface type 'foo' cannot be passed by value; did you forget * in 'foo'}}
+foo somefunc2() {} // expected-error {{Objective-C interface type 'foo' cannot be returned by value; did you forget * in 'foo'}}
+
+// rdar://6780761
+void f0(foo *a0) {
+  extern void g0(int x, ...);
+  g0(1, *(foo*)0);  // expected-error {{cannot pass object with interface type 'foo' by-value through variadic function}}
+}
diff --git a/test/SemaObjC/method-conflict.m b/test/SemaObjC/method-conflict.m
new file mode 100644
index 0000000..08fdfc0
--- /dev/null
+++ b/test/SemaObjC/method-conflict.m
@@ -0,0 +1,55 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+typedef signed char BOOL;
+typedef unsigned int NSUInteger;
+typedef struct _NSZone NSZone;
+@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+@protocol NSObject  - (BOOL)isEqual:(id)object;
+@end  @protocol NSCopying  - (id)copyWithZone:(NSZone *)zone;
+@end  @protocol NSMutableCopying  - (id)mutableCopyWithZone:(NSZone *)zone;
+@end  @protocol NSCoding  - (void)encodeWithCoder:(NSCoder *)aCoder;
+@end    @interface NSObject <NSObject> {
+}
+@end    extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone);
+@interface NSValue : NSObject <NSCopying, NSCoding>  - (void)getValue:(void *)value;
+@end        @class NSString;
+typedef struct _NSRange {
+}
+  NSRange;
+@interface NSValue (NSValueRangeExtensions)  + (NSValue *)valueWithRange:(NSRange)range;
+@end  @interface NSAttributedString : NSObject <NSCopying, NSMutableCopying, NSCoding>  - (NSString *)string;
+@end  @interface NSMutableAttributedString : NSAttributedString  - (void)replaceCharactersInRange:(NSRange)range withString:(NSString *)str;
+@end       @class NSArray, NSDictionary, NSString, NSError;
+@interface NSScanner : NSObject <NSCopying>  - (NSString *)string;
+@end        typedef struct {
+}
+  CSSM_FIELDGROUP, *CSSM_FIELDGROUP_PTR;
+@protocol XDUMLClassifier;
+@protocol XDUMLClassInterfaceCommons <XDUMLClassifier> 
+@end  @protocol XDUMLImplementation;
+@protocol XDUMLElement <NSObject> - (NSArray *) ownedElements;
+@end @protocol XDUMLDataType;
+@protocol XDUMLNamedElement <XDUMLElement>     - (NSString *) name;
+@end enum _XDSourceLanguage {
+XDSourceUnknown=0,     XDSourceJava,     XDSourceC,     XDSourceCPP,     XDSourceObjectiveC };
+typedef NSUInteger XDSourceLanguage;
+@protocol XDSCClassifier <XDUMLClassInterfaceCommons> - (XDSourceLanguage)language;
+@end  @class XDSCDocController;
+@interface XDSCDisplaySpecification : NSObject <NSCoding>{
+}
+@end  @class XDSCOperation;
+@interface XDSCClassFormatter : NSObject {
+}
++ (NSUInteger) compartmentsForClassifier: (id <XDUMLClassifier>) classifier withSpecification: (XDSCDisplaySpecification *) displaySpec; 
+@end  
+@class NSString;
+@implementation XDSCClassFormatter       
+
++ appendVisibility: (id <XDUMLNamedElement>) element withSpecification: (XDSCDisplaySpecification *) displaySpec to: (NSMutableAttributedString *) attributedString
+{
+  return 0;
+}
++ (NSUInteger) compartmentsForClassifier: (id <XDSCClassifier>) classifier withSpecification: (XDSCDisplaySpecification *) displaySpec {
+  return 0;
+}
+@end 
diff --git a/test/SemaObjC/method-def-1.m b/test/SemaObjC/method-def-1.m
new file mode 100644
index 0000000..7630ad0
--- /dev/null
+++ b/test/SemaObjC/method-def-1.m
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@interface foo
+- (int)meth;
+@end
+
+@implementation foo
+- (int) meth { return [self meth]; }
+@end
+
+// PR2708
+@interface MyClass
++- (void)myMethod;   // expected-error {{expected selector for Objective-C method}}
+- (vid)myMethod2;    // expected-error {{expected a type}}
+@end
+
+@implementation MyClass
+- (void)myMethod { }
+- (vid)myMethod2 { }	// expected-error {{expected a type}}
+
+@end
+
+
+@protocol proto;
+@protocol NSObject;
+
+//@protocol GrowlPluginHandler <NSObject> @end
+
+
+@interface SomeClass2
+- (int)myMethod1: (id<proto>)
+arg; // expected-note {{previous definition is here}}
+@end
+
+@implementation SomeClass2
+- (int)myMethod1: (id<NSObject>)
+  arg { // expected-warning {{conflicting parameter types in implementation of 'myMethod1:': 'id<proto>' vs 'id<NSObject>'}}
+  
+}
+@end
diff --git a/test/SemaObjC/method-def-2.m b/test/SemaObjC/method-def-2.m
new file mode 100644
index 0000000..915f231
--- /dev/null
+++ b/test/SemaObjC/method-def-2.m
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -ast-print %s
+extern void abort(void);
+#define CHECK_IF(expr) if(!(expr)) abort()
+
+static double d = 4.5920234e2;
+
+@interface Foo 
+-(void) brokenType: (int)x floatingPoint: (double)y;
+@end
+
+
+@implementation Foo
+-(void) brokenType: (int)x floatingPoint: (double)y
+{
+        CHECK_IF(x == 459);
+        CHECK_IF(y == d);
+}
+@end
+
diff --git a/test/SemaObjC/method-encoding-2.m b/test/SemaObjC/method-encoding-2.m
new file mode 100644
index 0000000..619a886
--- /dev/null
+++ b/test/SemaObjC/method-encoding-2.m
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 %s
+// TODO: We don't support rewrite of method definitions
+
+@interface Intf 
+- (in out bycopy id) address:(byref inout void *)location with:(out oneway unsigned **)arg2;
+- (id) another:(void *)location with:(unsigned **)arg2;
+@end
+
+@implementation Intf
+- (in out bycopy id) address:(byref inout void *)location with:(out oneway unsigned **)arg2{ return 0; }
+- (id) another:(void *)location with:(unsigned **)arg2 { return 0; }
+@end
diff --git a/test/SemaObjC/method-lookup-2.m b/test/SemaObjC/method-lookup-2.m
new file mode 100644
index 0000000..53cae83
--- /dev/null
+++ b/test/SemaObjC/method-lookup-2.m
@@ -0,0 +1,63 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+typedef signed char BOOL;
+
+@protocol NSObject
++ alloc;
+- init;
+- (BOOL) isEqual:(id) object;
+- (Class)class;
+@end
+
+@interface NSObject < NSObject > {} @end
+
+@class NSString, NSPort;
+
+@interface NSPortNameServer:NSObject
++ (NSPortNameServer *) systemDefaultPortNameServer;
+@end
+
+@interface NSMachBootstrapServer:NSPortNameServer + (id) sharedInstance; @end
+
+enum {
+  NSWindowsNTOperatingSystem = 1, NSWindows95OperatingSystem, NSSolarisOperatingSystem, NSHPUXOperatingSystem, NSMACHOperatingSystem, NSSunOSOperatingSystem, NSOSF1OperatingSystem
+};
+
+@interface NSRunLoop:NSObject {} @end
+
+@interface NSRunLoop(NSRunLoopConveniences)
+- (void) run;
+@end
+
+extern NSString *const NSWillBecomeMultiThreadedNotification;
+
+@interface SenTestTool:NSObject {}
+@end
+
+@implementation SenTestTool
++ (void) initialize {}
++(SenTestTool *) sharedInstance { return 0; }
+-(int) run { return 0; }
++(int) run {
+  return[[self sharedInstance] run];
+}
+@end
+
+@interface XX : NSObject
+
++ classMethod;
+
+@end
+
+@interface YY : NSObject
+- whatever;
+@end
+
+@implementation YY 
+
+- whatever {
+  id obj = [[XX alloc] init];
+  [[obj class] classMethod];
+  return 0;
+}
+
+@end
diff --git a/test/SemaObjC/method-lookup-3.m b/test/SemaObjC/method-lookup-3.m
new file mode 100644
index 0000000..18a9982
--- /dev/null
+++ b/test/SemaObjC/method-lookup-3.m
@@ -0,0 +1,52 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+typedef struct { int y; } Abstract;
+
+typedef struct { int x; } Alternate;
+
+#define INTERFERE_TYPE Alternate*
+
+@protocol A
+@property Abstract *x; // expected-note {{using}}
+@end
+
+@interface B
+@property Abstract *y; // expected-note {{using}}
+@end
+
+@interface B (Category)
+@property Abstract *z; // expected-note {{using}}
+@end
+
+@interface InterferencePre
+-(void) x; // expected-note {{also found}}
+-(void) y; // expected-note {{also found}}
+-(void) z; // expected-note {{also found}}
+-(void) setX: (INTERFERE_TYPE) arg; 
+-(void) setY: (INTERFERE_TYPE) arg;
+-(void) setZ: (INTERFERE_TYPE) arg;
+@end
+
+void f0(id a0) {
+  Abstract *l = [a0 x]; // expected-warning {{multiple methods named 'x' found}} 
+}
+
+void f1(id a0) {
+  Abstract *l = [a0 y]; // expected-warning {{multiple methods named 'y' found}}
+}
+
+void f2(id a0) {
+  Abstract *l = [a0 z]; // expected-warning {{multiple methods named 'z' found}}
+}
+
+void f3(id a0, Abstract *a1) { 
+  [ a0 setX: a1];
+}
+
+void f4(id a0, Abstract *a1) { 
+  [ a0 setY: a1];
+}
+
+void f5(id a0, Abstract *a1) { 
+  [ a0 setZ: a1];
+}
diff --git a/test/SemaObjC/method-lookup-4.m b/test/SemaObjC/method-lookup-4.m
new file mode 100644
index 0000000..700565e
--- /dev/null
+++ b/test/SemaObjC/method-lookup-4.m
@@ -0,0 +1,62 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@interface NSObject {}
+
+@end
+
+@interface MyClass : NSObject {}
+
+@end
+
+@interface MyClass (MyCategorie)
+
+@end
+
+@interface MySubClass : MyClass {}
+
+@end
+
+@interface MySubSubClass : MySubClass {}
+
+@end
+
+@implementation NSObject (NSObjectCategory)
+- (void)rootMethod {}
+@end
+
+@implementation MyClass
+
++ (void)myClassMethod { }
+- (void)myMethod { }
+
+@end
+
+@implementation MyClass (MyCategorie)
++ (void)myClassCategoryMethod { }
+- (void)categoryMethod {}
+@end
+
+@implementation MySubClass
+
+- (void)mySubMethod {}
+
+- (void)myTest {
+  [self mySubMethod];
+  // should lookup method in superclass implementation if available
+  [self myMethod];
+  [super myMethod];
+  
+  [self categoryMethod];
+  [super categoryMethod];
+  
+  // instance method of root class
+  [MyClass rootMethod];
+  
+  [MyClass myClassMethod];
+  [MySubClass myClassMethod];
+  
+  [MyClass myClassCategoryMethod];
+  [MySubClass myClassCategoryMethod];
+}
+
+@end
diff --git a/test/SemaObjC/method-lookup.m b/test/SemaObjC/method-lookup.m
new file mode 100644
index 0000000..e378958
--- /dev/null
+++ b/test/SemaObjC/method-lookup.m
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+typedef signed char BOOL;
+typedef int NSInteger;
+
+@protocol NSObject
+- (BOOL)isEqual:(id)object;
+- (BOOL)respondsToSelector:(SEL)s;
+@end
+
+@interface NSObject <NSObject> {}
+@end
+
+@class NSString, NSData, NSMutableData, NSMutableDictionary, NSMutableArray;
+
+@protocol PBXCompletionItem
+- (NSString *) name;
+- (NSInteger)priority;
+- setPriority:(NSInteger)p;
+@end
+
+@implementation PBXCodeAssistant // expected-warning{{cannot find interface declaration for 'PBXCodeAssistant'}}
+static NSMutableArray * recentCompletions = ((void *)0);
++ (float) factorForRecentCompletion:(NSString *) completion
+{
+    for (NSObject<PBXCompletionItem> * item in [self completionItems]) // expected-warning{{method '-completionItems' not found (return type defaults to 'id')}}
+    {
+        if ([item respondsToSelector:@selector(setPriority:)])
+        {
+            [(id)item setPriority:[item priority] / [PBXCodeAssistant factorForRecentCompletion:[item name]]];
+        }
+    }
+    return 0;
+}
+@end
+
diff --git a/test/SemaObjC/method-no-context.m b/test/SemaObjC/method-no-context.m
new file mode 100644
index 0000000..c88205d
--- /dev/null
+++ b/test/SemaObjC/method-no-context.m
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+- im0 { int a; return 0; // expected-error{{missing context for method declaration}}
+// expected-error{{expected '}'}}
diff --git a/test/SemaObjC/method-not-defined.m b/test/SemaObjC/method-not-defined.m
new file mode 100644
index 0000000..78bf650
--- /dev/null
+++ b/test/SemaObjC/method-not-defined.m
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@interface Foo
+@end
+
+void test() {
+  Foo *fooObj;
+  id obj;
+
+  [[Foo alloc] init]; // expected-warning {{method '+alloc' not found (return type defaults to 'id')}} expected-warning {{method '-init' not found (return type defaults to 'id')}}
+  [fooObj notdefined]; // expected-warning {{method '-notdefined' not found (return type defaults to 'id')}}
+  [obj whatever:1 :2 :3]; // expected-warning {{method '-whatever:::' not found (return type defaults to 'id'))}}
+}
diff --git a/test/SemaObjC/method-sentinel-attr.m b/test/SemaObjC/method-sentinel-attr.m
new file mode 100644
index 0000000..08358cc
--- /dev/null
+++ b/test/SemaObjC/method-sentinel-attr.m
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1  -fsyntax-only -verify %s
+
+#define NULL (void*)0
+
+#define ATTR __attribute__ ((__sentinel__)) 
+
+@interface INTF
+- (void) foo1 : (int)x, ... ATTR; // expected-note {{method has been explicitly marked sentinel here}}
+- (void) foo3 : (int)x __attribute__ ((__sentinel__)) ; // expected-warning {{'sentinel' attribute only supported for variadic functions}}
+- (void) foo5 : (int)x, ... __attribute__ ((__sentinel__(1))); // expected-note {{method has been explicitly marked sentinel here}}
+- (void) foo6 : (int)x, ... __attribute__ ((__sentinel__(5))); // expected-note {{method has been explicitly marked sentinel here}}
+- (void) foo7 : (int)x, ... __attribute__ ((__sentinel__(0))); // expected-note {{method has been explicitly marked sentinel here}}
+- (void) foo8 : (int)x, ... __attribute__ ((__sentinel__("a")));  // expected-error {{'sentinel' attribute requires parameter 1 to be an integer constant}}
+- (void) foo9 : (int)x, ... __attribute__ ((__sentinel__(-1)));  // expected-error {{'sentinel' parameter 1 less than zero}}
+- (void) foo10 : (int)x, ... __attribute__ ((__sentinel__(1,1)));
+- (void) foo11 : (int)x, ... __attribute__ ((__sentinel__(1,1,3)));  // expected-error {{attribute requires 0, 1 or 2 argument(s)}}
+- (void) foo12 : (int)x, ... ATTR; // expected-note {{method has been explicitly marked sentinel here}}
+@end
+
+int main ()
+{
+  INTF *p;
+
+  [p foo1:1, NULL]; // OK
+  [p foo1:1, 0];  // expected-warning {{missing sentinel in method dispatch}}
+  [p foo5:1, NULL, 2]; // OK
+  [p foo5:1, 2, NULL, 1]; // OK
+  [p foo5:1, NULL, 2, 1];  // expected-warning {{missing sentinel in method dispatch}}
+
+  [p foo6:1,2,3,4,5,6,7];  // expected-warning {{missing sentinel in method dispatch}}
+  [p foo6:1,NULL,3,4,5,6,7]; // OK
+  [p foo7:1];	 // expected-warning {{not enough variable arguments in 'foo7:' declaration to fit a sentinel}}
+  [p foo7:1, NULL]; // ok
+
+  [p foo12:1]; // expected-warning {{not enough variable arguments in 'foo12:' declaration to fit a sentinel}}
+}
+ 
diff --git a/test/SemaObjC/method-typecheck-1.m b/test/SemaObjC/method-typecheck-1.m
new file mode 100644
index 0000000..6c382d8
--- /dev/null
+++ b/test/SemaObjC/method-typecheck-1.m
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@interface A
+- (void) setMoo: (int) x;	//  expected-note {{previous definition is here}}
+- (int) setMoo1: (int) x;	//  expected-note {{previous definition is here}}
+- (int) setOk : (int) x : (double) d;
+@end
+
+@implementation A 
+-(void) setMoo: (float) x {}	//  expected-warning {{conflicting parameter types in implementation of 'setMoo:': 'int' vs 'float'}}
+- (char) setMoo1: (int) x { return 0; }	//  expected-warning {{conflicting return type in implementation of 'setMoo1:': 'int' vs 'char'}}
+- (int) setOk : (int) x : (double) d { return 0; }
+@end
+
+
+
+@interface C
++ (void) cMoo: (int) x;	//  expected-note 2 {{previous definition is here}}
+@end
+
+@implementation C 
++(float) cMoo:   // expected-warning {{conflicting return type in implementation of 'cMoo:': 'void' vs 'float'}}
+   (float) x { return 0; }	//  expected-warning {{conflicting parameter types in implementation of 'cMoo:': 'int' vs 'float'}}
+@end
+
+
+@interface A(CAT)
+- (void) setCat: (int) x;	// expected-note 2 {{previous definition is here}}
++ (void) cCat: (int) x;	//  expected-note {{previous definition is here}}
+@end
+
+@implementation A(CAT) 
+-(float) setCat:  // expected-warning {{conflicting return type in implementation of 'setCat:': 'void' vs 'float'}}
+(float) x { return 0; }	//  expected-warning {{conflicting parameter types in implementation of 'setCat:': 'int' vs 'float'}}
++ (int) cCat: (int) x { return 0; }	//  expected-warning {{conflicting return type in implementation of 'cCat:': 'void' vs 'int'}}
+@end
diff --git a/test/SemaObjC/method-typecheck-2.m b/test/SemaObjC/method-typecheck-2.m
new file mode 100644
index 0000000..84efa0b
--- /dev/null
+++ b/test/SemaObjC/method-typecheck-2.m
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@protocol P
+- (void) doSomethingInProtocol: (float) x; // expected-note {{previous definition is here}}
++ (void) doSomethingClassyInProtocol: (float) x; // expected-note {{previous definition is here}}
+- (void) doNothingInProtocol : (float) x;
++ (void) doNothingClassyInProtocol : (float) x;
+@end
+
+@interface I <P>
+- (void) doSomething: (float) x; // expected-note {{previous definition is here}}
++ (void) doSomethingClassy: (int) x; // expected-note {{previous definition is here}}
+@end
+
+@interface Bar : I
+@end
+
+@implementation Bar
+- (void) doSomething: (int) x {} // expected-warning {{conflicting parameter types}}
++ (void) doSomethingClassy: (float) x{}  // expected-warning {{conflicting parameter types}}
+- (void) doSomethingInProtocol: (id) x {}  // expected-warning {{conflicting parameter types}}
++ (void) doSomethingClassyInProtocol: (id) x {}  // expected-warning {{conflicting parameter types}}
+@end
+
+
diff --git a/test/SemaObjC/method-undef-category-warn-1.m b/test/SemaObjC/method-undef-category-warn-1.m
new file mode 100644
index 0000000..b367801
--- /dev/null
+++ b/test/SemaObjC/method-undef-category-warn-1.m
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@interface MyClass1
+@end
+
+@protocol P
+- (void) Pmeth;	 // expected-warning {{method in protocol not implemented [-Wprotocol]}}
+- (void) Pmeth1;   // expected-warning {{method in protocol not implemented [-Wprotocol]}}
+@end
+
+@interface MyClass1(CAT) <P> // expected-note {{required for direct or indirect protocol 'P'}}
+- (void) meth2;	 // expected-note {{method definition for 'meth2' not found}}
+@end
+
+@implementation MyClass1(CAT) // expected-warning {{incomplete implementation}} 
+- (void) Pmeth1{}
+@end
+
+@interface MyClass1(DOG) <P> // expected-note {{required for direct or indirect protocol 'P'}}
+- (void)ppp;    // expected-note {{method definition for 'ppp' not found}}
+@end
+
+@implementation MyClass1(DOG) // expected-warning {{incomplete implementation}}
+- (void) Pmeth {}
+@end
+
+@implementation MyClass1(CAT1)
+@end
diff --git a/test/SemaObjC/method-undef-extension-warn-1.m b/test/SemaObjC/method-undef-extension-warn-1.m
new file mode 100644
index 0000000..1addcf7
--- /dev/null
+++ b/test/SemaObjC/method-undef-extension-warn-1.m
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@interface MyClass // expected-note {{required for direct or indirect protocol 'P'}}
+@end
+
+@protocol P
+- (void)Pmeth;
+- (void)Pmeth1; // expected-warning {{method in protocol not implemented [-Wprotocol]}}
+@end
+
+// Class extension
+@interface MyClass () <P>
+- (void)meth2; // expected-note {{method definition for 'meth2' not found}}
+@end
+
+// Add a category to test that clang does not emit warning for this method.
+@interface MyClass (Category) 
+- (void)categoryMethod;
+@end
+
+@implementation MyClass // expected-warning {{incomplete implementation}} 
+- (void)Pmeth {}
+@end
diff --git a/test/SemaObjC/method-undefined-warn-1.m b/test/SemaObjC/method-undefined-warn-1.m
new file mode 100644
index 0000000..1ebc59e
--- /dev/null
+++ b/test/SemaObjC/method-undefined-warn-1.m
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@interface INTF
+- (void) meth;
+- (void) meth : (int) arg1;
+- (int)  int_meth;  // expected-note {{method definition for 'int_meth' not found}}
++ (int) cls_meth;  // expected-note {{method definition for 'cls_meth' not found}}
++ (void) cls_meth1 : (int) arg1;  // expected-note {{method definition for 'cls_meth1:' not found}}
+@end
+
+@implementation INTF 	// expected-warning {{incomplete implementation}}
+- (void) meth {}
+- (void) meth : (int) arg2{}
+- (void) cls_meth1 : (int) arg2{}
+@end
+
+@interface INTF1
+- (void) meth;
+- (void) meth : (int) arg1;
+- (int)  int_meth;       // expected-note {{method definition for 'int_meth' not found}}
++ (int) cls_meth;        // expected-note {{method definition for 'cls_meth' not found}}
++ (void) cls_meth1 : (int) arg1;  // expected-note {{method definition for 'cls_meth1:' not found}}
+@end
+
+@implementation INTF1 // expected-warning {{incomplete implementation}}
+- (void) meth {}
+- (void) meth : (int) arg2{}
+- (void) cls_meth1 : (int) arg2{}
+@end
+
+@interface INTF2
+- (void) meth;
+- (void) meth : (int) arg1;
+- (void) cls_meth1 : (int) arg1; 
+@end
+
+@implementation INTF2
+- (void) meth {}
+- (void) meth : (int) arg2{}
+- (void) cls_meth1 : (int) arg2{}
+@end
+
diff --git a/test/SemaObjC/method-unused-attribute.m b/test/SemaObjC/method-unused-attribute.m
new file mode 100644
index 0000000..a4e5321
--- /dev/null
+++ b/test/SemaObjC/method-unused-attribute.m
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1  -fsyntax-only -Wunused-parameter -verify %s
+
+@interface INTF
+- (void) correct_use_of_unused: (void *) notice : (id)another_arg;
+- (void) will_warn_unused_arg: (void *) notice : (id)warn_unused;
+- (void) unused_attr_on_decl_ignored: (void *)  __attribute__((unused)) will_warn;
+@end
+
+@implementation INTF
+- (void) correct_use_of_unused: (void *)  __attribute__((unused)) notice : (id) __attribute__((unused)) newarg{
+}
+- (void) will_warn_unused_arg: (void *) __attribute__((unused))  notice : (id)warn_unused {}  // expected-warning {{unused parameter 'warn_unused'}}
+- (void) unused_attr_on_decl_ignored: (void *)  will_warn{}  // expected-warning {{unused parameter 'will_warn'}}
+@end
+
diff --git a/test/SemaObjC/method-warn-unused-attribute.m b/test/SemaObjC/method-warn-unused-attribute.m
new file mode 100644
index 0000000..042f442
--- /dev/null
+++ b/test/SemaObjC/method-warn-unused-attribute.m
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1  -fsyntax-only -Wunused-value -verify %s
+
+@interface INTF
+- (id) foo __attribute__((warn_unused_result)); 
+- (void) garf __attribute__((warn_unused_result)); // expected-warning {{attribute 'warn_unused_result' cannot be applied to Objective-C method without return value}}
+- (int) fee __attribute__((warn_unused_result));
++ (int) c __attribute__((warn_unused_result));
+@end
+
+void foo(INTF *a) {
+  [a garf];
+  [a fee]; // expected-warning {{ignoring return value of function declared with warn_unused_result attribute}}
+  [INTF c]; // expected-warning {{ignoring return value of function declared with warn_unused_result attribute}}
+}
+
+
diff --git a/test/SemaObjC/missing-method-context.m b/test/SemaObjC/missing-method-context.m
new file mode 100644
index 0000000..1378b36
--- /dev/null
+++ b/test/SemaObjC/missing-method-context.m
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only
+- (void)compilerTestAgainst;  // expected-error {{missing context for method declaration}}
+
+void xx();  // expected-error {{expected method body}}
diff --git a/test/SemaObjC/newproperty-class-method-1.m b/test/SemaObjC/newproperty-class-method-1.m
new file mode 100644
index 0000000..d4ea5e5
--- /dev/null
+++ b/test/SemaObjC/newproperty-class-method-1.m
@@ -0,0 +1,62 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only
+
+void abort(void);
+
+@interface Subclass
++ (int)magicNumber;
++ (void)setMagicNumber:(int)value;
++ (void)setFakeSetterNumber:(int)value;
+@end
+
+@implementation Subclass
+int _magicNumber = 0;
++ (int)magicNumber {
+  return _magicNumber;
+}
+
++ (void)setMagicNumber:(int)value {
+  _magicNumber = value;
+}
+
++ (void)setFakeSetterNumber:(int)value {
+  _magicNumber = value;
+}
+
++ (void) classMeth
+{
+	self.magicNumber = 10;
+	if (self.magicNumber != 10)
+	  abort ();
+}
+@end
+
+int main (void) {
+  
+  int a;
+  Subclass.magicNumber = 2 /*[Subclass setMagicNumber:2]*/;
+  if (Subclass.magicNumber != 0)
+    abort ();
+  if (Subclass.magicNumber != 2)
+    abort ();
+  Subclass.magicNumber += 3;
+  if (Subclass.magicNumber != 5)
+    abort ();
+  Subclass.magicNumber -= 5;
+  if (Subclass.magicNumber != 0)
+    abort ();
+  /* We only have a setter in the following case. */
+  Subclass.fakeSetterNumber = 123;
+
+  /* We read it using the other getter. */
+  if (Subclass.magicNumber != 123)
+   abort ();
+  Subclass.fakeSetterNumber = Subclass.magicNumber;
+  if (Subclass.magicNumber != 123)
+   abort ();
+
+  Subclass.fakeSetterNumberX = 123; // expected-error{{property 'fakeSetterNumberX' not found on object of type 'Subclass'}}
+
+  /* Test class methods using the new syntax. */
+  [Subclass classMeth];
+  return 0;
+}
diff --git a/test/SemaObjC/no-gc-weak-test.m b/test/SemaObjC/no-gc-weak-test.m
new file mode 100644
index 0000000..ca8318d
--- /dev/null
+++ b/test/SemaObjC/no-gc-weak-test.m
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -fsyntax-only -verify %s
+
+@interface Subtask
+{
+  id _delegate;
+}
+@property(nonatomic,readwrite,assign)   id __weak       delegate;
+@end
+
+@implementation Subtask
+@synthesize delegate = _delegate;
+@end
+
+ 
+@interface PVSelectionOverlayView2 
+{
+ id __weak _selectionRect;
+}
+
+@property(assign) id selectionRect;
+
+@end
+
+@implementation PVSelectionOverlayView2
+
+@synthesize selectionRect = _selectionRect;
+@end
+
diff --git a/test/SemaObjC/no-protocol-option-tests.m b/test/SemaObjC/no-protocol-option-tests.m
new file mode 100644
index 0000000..5d2da0a
--- /dev/null
+++ b/test/SemaObjC/no-protocol-option-tests.m
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -fsyntax-only -Wno-protocol -verify %s
+// rdar: // 7056600
+
+@protocol P
+- PMeth;
+@end
+
+// Test1
+@interface I  <P> @end
+@implementation I @end //  no warning with -Wno-protocol
+
+// Test2
+@interface C -PMeth; @end
+@interface C (Category) <P> @end
+@implementation C (Category) @end //  no warning with -Wno-protocol
+
+// Test2
+@interface super - PMeth; @end
+@interface J : super <P>
+- PMeth;	// expected-note {{ method definition for 'PMeth' not found}}
+@end
+@implementation J @end	// expected-warning {{incomplete implementation}}
+
+// Test3
+@interface K : super <P>
+@end
+@implementation K @end // no warning with -Wno-protocol
+
+// Test4
+@interface Root @end
+@interface L : Root<P> @end
+@implementation L @end // no warning with -Wno-protocol
diff --git a/test/SemaObjC/no-warn-qual-mismatch.m b/test/SemaObjC/no-warn-qual-mismatch.m
new file mode 100644
index 0000000..1b5f184
--- /dev/null
+++ b/test/SemaObjC/no-warn-qual-mismatch.m
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1  -fsyntax-only -verify %s
+// radar 7211563
+
+@interface X
+
++ (void)prototypeWithScalar:(int)aParameter;
++ (void)prototypeWithPointer:(void *)aParameter;
+
+@end
+
+@implementation X
+
++ (void)prototypeWithScalar:(const int)aParameter {}
++ (void)prototypeWithPointer:(void * const)aParameter {}
+
+@end
diff --git a/test/SemaObjC/no-warn-synth-protocol-meth.m b/test/SemaObjC/no-warn-synth-protocol-meth.m
new file mode 100644
index 0000000..fed6b27
--- /dev/null
+++ b/test/SemaObjC/no-warn-synth-protocol-meth.m
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1  -fsyntax-only -verify %s
+
+@protocol CYCdef
+- (int)name;
+@end
+
+@interface JSCdef <CYCdef> {
+    int name;
+}
+
+@property (assign) int name;
+@end
+
+@implementation JSCdef
+@synthesize name;
+@end
+
diff --git a/test/SemaObjC/no-warn-unimpl-method.m b/test/SemaObjC/no-warn-unimpl-method.m
new file mode 100644
index 0000000..dd6e3ad
--- /dev/null
+++ b/test/SemaObjC/no-warn-unimpl-method.m
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify %s
+// This program tests that if class implements the forwardInvocation method, then
+// every method possible is implemented in the class and should not issue
+// warning of the "Method definition not found" kind. */
+
+@interface NSObject
+@end
+
+@interface NSInvocation
+@end
+
+@interface NSProxy
+@end
+
+@protocol MyProtocol
+        -(void) doSomething;
+@end
+
+@interface DestinationClass : NSObject<MyProtocol>
+        -(void) doSomething;
+@end
+
+@implementation DestinationClass
+        -(void) doSomething
+        {
+        }
+@end
+
+@interface MyProxy : NSProxy<MyProtocol>
+{
+        DestinationClass        *mTarget;
+}
+        - (id) init;
+        - (void)forwardInvocation:(NSInvocation *)anInvocation;
+@end
+
+@implementation MyProxy
+        - (void)forwardInvocation:(NSInvocation *)anInvocation
+        {
+        }
+	- (id) init { return 0; }
+@end
diff --git a/test/SemaObjC/nonnull.m b/test/SemaObjC/nonnull.m
new file mode 100644
index 0000000..642f50f
--- /dev/null
+++ b/test/SemaObjC/nonnull.m
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 -fblocks -fsyntax-only -verify %s
+
+@class NSObject;
+
+int f1(int x) __attribute__((nonnull)); // expected-warning{{'nonnull' attribute applied to function with no pointer arguments}}
+int f2(int *x) __attribute__ ((nonnull (1)));
+int f3(int *x) __attribute__ ((nonnull (0))); // expected-error {{'nonnull' attribute parameter 1 is out of bounds}}
+int f4(int *x, int *y) __attribute__ ((nonnull (1,2)));
+int f5(int *x, int *y) __attribute__ ((nonnull (2,1)));
+int f6(NSObject *x) __attribute__ ((nonnull (1))); // no-warning
+int f7(NSObject *x) __attribute__ ((nonnull)); // no-warning
+
+
+extern void func1 (void (^block1)(), void (^block2)(), int) __attribute__((nonnull));
+
+extern void func3 (void (^block1)(), int, void (^block2)(), int)
+__attribute__((nonnull(1,3)));
+
+extern void func4 (void (^block1)(), void (^block2)()) __attribute__((nonnull(1)))
+__attribute__((nonnull(2)));
+
+void func6();
+void func7();
+
+void
+foo (int i1, int i2, int i3, void (^cp1)(), void (^cp2)(), void (^cp3)())
+{
+  func1(cp1, cp2, i1);
+  
+  func1(0, cp2, i1);  // expected-warning {{null passed to a callee which requires a non-null argument}}
+  func1(cp1, 0, i1);  // expected-warning {{null passed to a callee which requires a non-null argument}}
+  func1(cp1, cp2, 0);
+  
+  
+  func3(0, i2, cp3, i3); // expected-warning {{null passed to a callee which requires a non-null argument}}
+  func3(cp3, i2, 0, i3);  // expected-warning {{null passed to a callee which requires a non-null argument}}
+  
+  func4(0, cp1); // expected-warning {{null passed to a callee which requires a non-null argument}}
+  func4(cp1, 0); // expected-warning {{null passed to a callee which requires a non-null argument}}
+  
+  // Shouldn't these emit warnings?  Clang doesn't, and neither does GCC.  It
+  // seems that the checking should handle Objective-C pointers.
+  func6((NSObject*) 0); // no-warning
+  func7((NSObject*) 0); // no-warning
+}
diff --git a/test/SemaObjC/nsobject-attribute-1.m b/test/SemaObjC/nsobject-attribute-1.m
new file mode 100644
index 0000000..991246c
--- /dev/null
+++ b/test/SemaObjC/nsobject-attribute-1.m
@@ -0,0 +1,48 @@
+// RUN: %clang_cc1 -fblocks -fsyntax-only -verify %s
+
+@interface NSObject
+- (id)self;
+- (id)copy;
+@end
+
+typedef struct _foo  *__attribute__((NSObject)) Foo_ref;
+
+@interface TestObject {
+    Foo_ref dict;
+}
+@property(retain) Foo_ref dict;
+@end
+
+@implementation TestObject
+@synthesize dict;
+@end
+
+@interface NSDictionary
+- (int)retainCount;
+@end
+
+int main(int argc, char *argv[]) {
+    NSDictionary *dictRef;
+    Foo_ref foo = (Foo_ref)dictRef;
+
+    // do Properties retain?
+    int before = [dictRef retainCount];
+    int after = [dictRef retainCount];
+
+    if ([foo retainCount] != [dictRef retainCount]) {
+    }
+
+    // do Blocks retain?
+    {
+        void (^block)(void) = ^{
+            [foo self];
+        };
+        before = [foo retainCount];
+        id save = [block copy];
+        after = [foo retainCount];
+        if (after <= before) {
+            ;
+        }
+    }
+    return 0;
+}
diff --git a/test/SemaObjC/nsobject-attribute.m b/test/SemaObjC/nsobject-attribute.m
new file mode 100644
index 0000000..13a4929
--- /dev/null
+++ b/test/SemaObjC/nsobject-attribute.m
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+typedef struct CGColor * __attribute__ ((NSObject)) CGColorRef;
+static int count;
+static CGColorRef tmp = 0;
+
+typedef struct S1  __attribute__ ((NSObject)) CGColorRef1; // expected-error {{__attribute ((NSObject)) is for pointer types only}}
+typedef void *  __attribute__ ((NSObject)) CGColorRef2; // expected-error {{__attribute ((NSObject)) is for pointer types only}}
+
+
+@interface HandTested {
+@public
+    CGColorRef x;
+}
+
+@property(copy) CGColorRef x;
+// rdar: // 7809460
+typedef struct CGColor *CGColorRefNoNSObject;
+@property (nonatomic, retain) __attribute__((NSObject)) CGColorRefNoNSObject color;
+@end
+
+void setProperty(id self, id value)  {
+  ((HandTested *)self)->x = value;
+}
+
+id getProperty(id self) {
+     return (id)((HandTested *)self)->x;
+}
+
+@implementation HandTested
+@synthesize x=x;
+@dynamic color;
+@end
+
+int main(int argc, char *argv[]) {
+    HandTested *to;
+    to.x = tmp;  // setter
+    if (tmp != to.x)
+      to.x = tmp;
+    return 0;
+}
+
diff --git a/test/SemaObjC/objc-cstyle-args-in-methods.m b/test/SemaObjC/objc-cstyle-args-in-methods.m
new file mode 100644
index 0000000..9f75295
--- /dev/null
+++ b/test/SemaObjC/objc-cstyle-args-in-methods.m
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1  -fsyntax-only -verify %s
+
+@interface Foo 
+- (id)test:(id)one, id two;
+- (id)bad:(id)one, id two, double three;
+@end
+
+@implementation Foo
+- (id)test:(id )one, id two {return two; } 
+- (id)bad:(id)one, id two, double three { return two; }
+@end
+
+
+int main() {
+	Foo *foo;
+	[foo test:@"One", @"Two"];
+	[foo bad:@"One", @"Two"]; // expected-error {{too few arguments to method call}}
+	[foo bad:@"One", @"Two", 3.14];
+	[foo bad:@"One", @"Two", 3.14, @"Two"]; // expected-error {{too many arguments to method call}}
+}
diff --git a/test/SemaObjC/objc-string-constant.m b/test/SemaObjC/objc-string-constant.m
new file mode 100644
index 0000000..cc6d60c
--- /dev/null
+++ b/test/SemaObjC/objc-string-constant.m
@@ -0,0 +1,39 @@
+// RUN: %clang_cc1 -Wsemicolon-before-method-body %s -verify -fsyntax-only
+
+#define nil 0       /* id of Nil instance */
+
+@interface NSObject 
+@end
+
+@interface NSString : NSObject
+
+@end
+
+@interface NSMutableString : NSString
+
+@end
+
+@interface NSSimpleCString : NSString {
+@protected
+    char *bytes;
+    int numBytes;
+}
+@end
+
+@interface NSConstantString : NSSimpleCString
+@end
+
+
+@interface Subclass : NSObject 
+- (NSString *)token;
+@end
+
+@implementation Subclass
+- (NSString *)token;	// expected-warning {{semicolon before method body is ignored}}
+{
+  NSMutableString *result = nil;
+
+  return (result != nil) ? result : @"";
+}
+@end
+
diff --git a/test/SemaObjC/objc2-merge-gc-attribue-decl.m b/test/SemaObjC/objc2-merge-gc-attribue-decl.m
new file mode 100644
index 0000000..673a741
--- /dev/null
+++ b/test/SemaObjC/objc2-merge-gc-attribue-decl.m
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -fobjc-gc -fsyntax-only -verify %s
+@interface INTF @end
+
+extern INTF* p2;
+extern __strong INTF* p2;
+
+extern __strong id p1;
+extern id p1;
+
+extern id CFRunLoopGetMain();
+extern __strong id CFRunLoopGetMain();
+
+extern __weak id WLoopGetMain(); // expected-note {{previous declaration is here}}
+extern id WLoopGetMain();	// expected-error {{conflicting types for 'WLoopGetMain'}}
+
+extern id p3;	// expected-note {{previous definition is here}}
+extern __weak id p3;	// expected-error {{redefinition of 'p3' with a different type}}
+
+extern void *p4; // expected-note {{previous definition is here}}
+extern void * __strong p4; // expected-error {{redefinition of 'p4' with a different type}}
+
+extern id p5;
+extern __strong id p5;
+
+extern char* __strong p6; // expected-note {{previous definition is here}}
+extern char* p6; // expected-error {{redefinition of 'p6' with a different type}}
+
+extern __strong char* p7; // expected-note {{previous definition is here}}
+extern char* p7; // expected-error {{redefinition of 'p7' with a different type}}
diff --git a/test/SemaObjC/objc2-warn-weak-decl.m b/test/SemaObjC/objc2-warn-weak-decl.m
new file mode 100644
index 0000000..76b542d
--- /dev/null
+++ b/test/SemaObjC/objc2-warn-weak-decl.m
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -fsyntax-only -fobjc-gc -verify %s
+struct S {
+	__weak id  p;  // expected-warning {{__weak attribute cannot be specified on a field declaration}}
+};
+
+int main ()
+{
+  __weak id  local;  // expected-warning {{__weak attribute cannot be specified on an automatic variable}}
+}
+
diff --git a/test/SemaObjC/pedantic-dynamic-test.m b/test/SemaObjC/pedantic-dynamic-test.m
new file mode 100644
index 0000000..9b14c1d
--- /dev/null
+++ b/test/SemaObjC/pedantic-dynamic-test.m
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s
+// rdar: // 7860960
+
+@interface I
+{
+  int window;
+}
+@property int window, noWarningNeeded;
+@end
+
+@implementation I
+
+@synthesize window;
+
+@dynamic noWarningNeeded;
+@end
diff --git a/test/SemaObjC/property-10.m b/test/SemaObjC/property-10.m
new file mode 100644
index 0000000..bd07df6
--- /dev/null
+++ b/test/SemaObjC/property-10.m
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -fsyntax-only -Wreadonly-setter-attrs -verify %s  -fblocks
+
+// Check property attribute consistency.
+
+@interface I0
+@property(readonly, readwrite) int p0; // expected-error {{property attributes 'readonly' and 'readwrite' are mutually exclusive}}
+
+@property(retain) int p1; // expected-error {{property with 'retain' attribute must be of object type}}
+
+@property(copy) int p2; // expected-error {{property with 'copy' attribute must be of object type}}
+
+@property(assign, copy) id p3_0; // expected-error {{property attributes 'assign' and 'copy' are mutually exclusive}} 
+@property(assign, retain) id p3_1; // expected-error {{property attributes 'assign' and 'retain' are mutually exclusive}} 
+@property(copy, retain) id p3_2; // expected-error {{property attributes 'copy' and 'retain' are mutually exclusive}} 
+@property(assign, copy, retain) id p3_3; // expected-error {{property attributes 'assign' and 'copy' are mutually exclusive}}, expected-error {{property attributes 'assign' and 'retain' are mutually exclusive}} 
+
+@property id p4; // expected-warning {{no 'assign', 'retain', or 'copy' attribute is specified - 'assign' is assumed}}, expected-warning {{default property attribute 'assign' not appropriate for non-gc object}}
+
+@property(nonatomic,copy) int (^includeMailboxCondition)(); 
+@property(nonatomic,copy) int (*includeMailboxCondition2)(); // expected-error {{property with 'copy' attribute must be of object type}}
+
+@end
diff --git a/test/SemaObjC/property-11.m b/test/SemaObjC/property-11.m
new file mode 100644
index 0000000..2976115
--- /dev/null
+++ b/test/SemaObjC/property-11.m
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@interface NSSound
+@end
+@interface NSFont
+@end
+
+@interface NSSound (Adds)
+@end
+
+@implementation NSSound (Adds)
+- foo {
+  return self;
+}
+- (void)setFoo:obj {
+}
+@end
+
+@implementation NSFont (Adds)
+
+- xx {
+  NSSound *x;
+  id o;
+
+  // GCC does *not* warn about the following. Since foo/setFoo: are not in the
+  // class or category interface for NSSound, the compiler shouldn't find them.
+  // For now, we will support GCC's behavior (sigh).
+  o = [x foo];
+  o = x.foo;
+  [x setFoo:o];
+  x.foo = o;
+  return 0;
+}
+
+@end
+
diff --git a/test/SemaObjC/property-12.m b/test/SemaObjC/property-12.m
new file mode 100644
index 0000000..cd0fccf
--- /dev/null
+++ b/test/SemaObjC/property-12.m
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -fsyntax-only -Wreadonly-setter-attrs -verify %s
+
+@protocol P0
+@property(readonly,assign) id X; // expected-warning {{property attributes 'readonly' and 'assign' are mutually exclusive}}
+@end
+
+@protocol P1
+@property(readonly,retain) id X; // expected-warning {{property attributes 'readonly' and 'retain' are mutually exclusive}}
+@end
+
+@protocol P2
+@property(readonly,copy) id X; // expected-warning {{property attributes 'readonly' and 'copy' are mutually exclusive}}
+@end
+
+@protocol P3
+@property(readonly,readwrite) id X; // expected-error {{property attributes 'readonly' and 'readwrite' are mutually exclusive}}
+@end
+
+@protocol P4
+@property(assign,copy) id X; // expected-error {{property attributes 'assign' and 'copy' are mutually exclusive}}
+@end
+
+@protocol P5
+@property(assign,retain) id X; // expected-error {{property attributes 'assign' and 'retain' are mutually exclusive}}
+@end
+
+@protocol P6
+@property(copy,retain) id X; // expected-error {{property attributes 'copy' and 'retain' are mutually exclusive}}
+@end
+
+
+
diff --git a/test/SemaObjC/property-13.m b/test/SemaObjC/property-13.m
new file mode 100644
index 0000000..6d56dab
--- /dev/null
+++ b/test/SemaObjC/property-13.m
@@ -0,0 +1,78 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -Wno-unreachable-code
+
+@interface NSObject 
++ alloc;
+- init;
+@end
+
+@protocol Test
+  @property int required;
+
+@optional
+  @property int optional;
+  @property int optional1;
+  @property int optional_preexisting_setter_getter;
+  @property (setter = setOptional_preexisting_setter_getter: ,
+	     getter = optional_preexisting_setter_getter) int optional_with_setter_getter_attr;
+@required
+  @property int required1;
+@optional
+  @property int optional_to_be_defined;
+  @property (readonly, getter = optional_preexisting_setter_getter) int optional_getter_attr;
+@end
+
+@interface Test : NSObject <Test> {
+  int ivar;
+  int ivar1;
+  int ivar2;
+}
+@property int required;
+@property int optional_to_be_defined;
+- (int) optional_preexisting_setter_getter;
+- (void) setOptional_preexisting_setter_getter:(int)value;
+@end
+
+@implementation Test
+@synthesize required = ivar;
+@synthesize required1 = ivar1;
+@synthesize optional_to_be_defined = ivar2;
+- (int) optional_preexisting_setter_getter { return ivar; }
+- (void) setOptional_preexisting_setter_getter:(int)value
+	   {
+		ivar = value;
+	   }
+- (void) setOptional_getter_attr:(int)value { ivar = value; }
+@end
+
+void abort(void);
+int main ()
+{
+	Test *x = [[Test alloc] init];
+	/* 1. Test of a requred property */
+	x.required1 = 100;
+  	if (x.required1 != 100)
+	  abort ();
+
+	/* 2. Test of a synthesize optional property */
+  	x.optional_to_be_defined = 123;
+	if (x.optional_to_be_defined != 123)
+	  abort ();
+
+	/* 3. Test of optional property with pre-sxisting defined setter/getter */
+	x.optional_preexisting_setter_getter = 200;
+	if (x.optional_preexisting_setter_getter != 200)
+	  abort ();
+
+	/* 4. Test of optional property with setter/getter attribute */
+	if (x.optional_with_setter_getter_attr != 200)
+	  abort ();
+	return 0;
+
+	/* 5. Test of optional property with getter attribute and default setter method. */
+	x.optional_getter_attr = 1000;
+        if (x.optional_getter_attr != 1000)
+	  abort ();
+
+	return 0;
+}
+
diff --git a/test/SemaObjC/property-2.m b/test/SemaObjC/property-2.m
new file mode 100644
index 0000000..069b0cb
--- /dev/null
+++ b/test/SemaObjC/property-2.m
@@ -0,0 +1,63 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@interface Tester 
+@property char PropertyAtomic_char;
+@property short PropertyAtomic_short;
+@property int PropertyAtomic_int;
+@property long PropertyAtomic_long;
+@property long long PropertyAtomic_longlong;
+@property float PropertyAtomic_float;
+@property double PropertyAtomic_double;
+@property(assign) id PropertyAtomic_id;
+@property(retain) id PropertyAtomicRetained_id;
+@property(copy) id PropertyAtomicRetainedCopied_id;
+@property(retain) id PropertyAtomicRetainedGCOnly_id;
+@property(copy) id PropertyAtomicRetainedCopiedGCOnly_id;
+@end
+
+@implementation Tester
+@dynamic PropertyAtomic_char;
+@dynamic PropertyAtomic_short;
+@dynamic PropertyAtomic_int;
+@dynamic PropertyAtomic_long;
+@dynamic PropertyAtomic_longlong;
+@dynamic PropertyAtomic_float;
+@dynamic PropertyAtomic_double;
+@dynamic PropertyAtomic_id;
+@dynamic PropertyAtomicRetained_id;
+@dynamic PropertyAtomicRetainedCopied_id;
+@dynamic PropertyAtomicRetainedGCOnly_id;
+@dynamic PropertyAtomicRetainedCopiedGCOnly_id;
+@end
+
+@interface SubClass : Tester
+{
+    char PropertyAtomic_char;
+    short PropertyAtomic_short;
+    int PropertyAtomic_int;
+    long PropertyAtomic_long;
+    long long PropertyAtomic_longlong;
+    float PropertyAtomic_float;
+    double PropertyAtomic_double;
+    id PropertyAtomic_id;
+    id PropertyAtomicRetained_id;
+    id PropertyAtomicRetainedCopied_id;
+    id PropertyAtomicRetainedGCOnly_id;
+    id PropertyAtomicRetainedCopiedGCOnly_id;
+}
+@end
+
+@implementation SubClass
+@synthesize PropertyAtomic_char;
+@synthesize PropertyAtomic_short;
+@synthesize PropertyAtomic_int;
+@synthesize PropertyAtomic_long;
+@synthesize PropertyAtomic_longlong;
+@synthesize PropertyAtomic_float;
+@synthesize PropertyAtomic_double;
+@synthesize PropertyAtomic_id;
+@synthesize PropertyAtomicRetained_id;
+@synthesize PropertyAtomicRetainedCopied_id;
+@synthesize PropertyAtomicRetainedGCOnly_id;
+@synthesize PropertyAtomicRetainedCopiedGCOnly_id;
+@end
diff --git a/test/SemaObjC/property-3.m b/test/SemaObjC/property-3.m
new file mode 100644
index 0000000..439dc28
--- /dev/null
+++ b/test/SemaObjC/property-3.m
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -verify %s
+
+@interface I 
+{
+	id d1;
+}
+@property (readwrite, copy) id d1;
+@property (readwrite, copy) id d2;
+@end
+
+@interface NOW : I
+@property (readonly) id d1; // expected-warning {{attribute 'readonly' of property 'd1' restricts attribute 'readwrite' of property inherited from 'I'}} expected-warning {{property 'd1' 'copy' attribute does not match the property inherited from 'I'}}
+@property (readwrite, copy) I* d2;
+@end
diff --git a/test/SemaObjC/property-4.m b/test/SemaObjC/property-4.m
new file mode 100644
index 0000000..2168048
--- /dev/null
+++ b/test/SemaObjC/property-4.m
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -verify %s
+
+@interface Object 
+@end
+
+@protocol ProtocolObject
+@property int class;
+@property (copy) id MayCauseError;
+@end
+
+@protocol ProtocolDerivedGCObject <ProtocolObject>
+@property int Dclass;
+@end
+
+@interface GCObject  : Object <ProtocolDerivedGCObject> {
+    int ifield;
+    int iOwnClass;
+    int iDclass;
+}
+@property int OwnClass;
+@end
+
+@interface ReleaseObject : GCObject <ProtocolObject> {
+   int newO;
+   int oldO;
+}
+@property (retain) id MayCauseError;  // expected-warning {{property 'MayCauseError' 'copy' attribute does not match the property inherited from 'ProtocolObject'}}
+@end
+
diff --git a/test/SemaObjC/property-5.m b/test/SemaObjC/property-5.m
new file mode 100644
index 0000000..cd7cc24
--- /dev/null
+++ b/test/SemaObjC/property-5.m
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -verify %s
+
+@protocol P1 @end
+@protocol P2 @end
+@protocol P3 @end
+
+@interface NSData @end
+
+@interface MutableNSData : NSData @end
+
+@interface Base : NSData <P1>
+@property(readonly) id ref;
+@property(readonly) Base *p_base;
+@property(readonly) NSData *nsdata;
+@property(readonly) NSData * m_nsdata;
+@end
+
+@interface Data : Base <P1, P2>
+@property(readonly) NSData *ref;	
+@property(readonly) Data *p_base;	
+@property(readonly) MutableNSData * m_nsdata;  
+@end
+
+@interface  MutedData: Data
+@property(readonly) id p_base; 
+@end
+
+@interface ConstData : Data <P1, P2, P3>
+@property(readonly) ConstData *p_base;
+@end
+
+void foo(Base *b, id x) {
+  [ b setRef: x ]; // expected-warning {{method '-setRef:' not found}}
+}
diff --git a/test/SemaObjC/property-6.m b/test/SemaObjC/property-6.m
new file mode 100644
index 0000000..72beb67
--- /dev/null
+++ b/test/SemaObjC/property-6.m
@@ -0,0 +1,69 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+# 1 "<command line>"
+# 1 "/System/Library/Frameworks/Foundation.framework/Headers/Foundation.h" 1 3
+typedef signed char BOOL;
+typedef unsigned int NSUInteger;
+typedef struct _NSZone NSZone;
+
+@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+
+@protocol NSObject
+- (BOOL)isEqual:(id)object;
++ class;
+@end
+
+@protocol NSCopying 
+- (id)copyWithZone:(NSZone *)zone;
+@end
+
+@protocol NSMutableCopying
+- (id)mutableCopyWithZone:(NSZone *)zone;
+@end
+
+@protocol NSCoding
+- (void)encodeWithCoder:(NSCoder *)aCoder;
+@end
+
+@interface NSObject <NSObject> {}
+@end
+
+typedef struct {} NSFastEnumerationState;
+
+@protocol NSFastEnumeration 
+- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len;
+@end
+
+@interface NSArray : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration>
+- (NSUInteger)count;
+@end
+
+@interface NSMutableArray : NSArray
+- (void)addObject:(id)anObject;
++ (id)arrayWithCapacity:(int)numItems;
+@end
+
+@interface NSBundle : NSObject {}
++ (NSBundle *)bundleForClass:(Class)aClass;
+- (NSString *)bundlePath;
+- (void)setBundlePath:(NSString *)x;
+@end
+
+@interface NSException : NSObject <NSCopying, NSCoding> {}
+@end
+
+@class NSArray, NSDictionary, NSError, NSString, NSURL;
+
+@interface DTPlugInManager : NSObject
+@end
+
+@implementation DTPlugInManager
++ (DTPlugInManager *)defaultPlugInManager {
+  @try {
+    NSMutableArray *plugInPaths = [NSMutableArray arrayWithCapacity:100];
+    NSBundle *frameworkBundle = [NSBundle bundleForClass:[DTPlugInManager class]];
+    frameworkBundle.bundlePath = 0;
+    [plugInPaths addObject:frameworkBundle.bundlePath];
+  }
+  @catch (NSException *exception) {}
+}
+@end
diff --git a/test/SemaObjC/property-7.m b/test/SemaObjC/property-7.m
new file mode 100644
index 0000000..e6cba50
--- /dev/null
+++ b/test/SemaObjC/property-7.m
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+typedef signed char BOOL;
+typedef struct _NSZone NSZone;
+
+@protocol NSObject
+- (BOOL)isEqual:(id)object;
+@end
+
+@protocol NSCopying
+- (id)copyWithZone:(NSZone *)zone;
+@end
+
+@interface NSObject <NSObject> {}
+@end
+
+@class NSString, NSData, NSMutableData, NSMutableDictionary, NSMutableArray;
+
+@interface SCMObject : NSObject <NSCopying> {}
+  @property(assign) SCMObject *__attribute__((objc_gc(weak))) parent;
+@end
+
+@interface SCMNode : SCMObject
+{
+  NSString *_name;
+}
+@property(copy) NSString *name;
+@end
+
+@implementation SCMNode
+  @synthesize name = _name;
+  - (void) setParent:(SCMObject *__attribute__((objc_gc(weak)))) inParent {
+    super.parent = inParent;
+  }
+@end
diff --git a/test/SemaObjC/property-8.m b/test/SemaObjC/property-8.m
new file mode 100644
index 0000000..8647aba
--- /dev/null
+++ b/test/SemaObjC/property-8.m
@@ -0,0 +1,74 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+typedef signed char BOOL;
+typedef unsigned int NSUInteger;
+typedef struct _NSZone NSZone;
+
+@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+
+@protocol NSObject  - (BOOL)isEqual:(id)object; @end
+@protocol NSCopying  - (id)copyWithZone:(NSZone *)zone; @end
+@protocol NSMutableCopying  - (id)mutableCopyWithZone:(NSZone *)zone; @end
+@protocol NSCoding  - (void)encodeWithCoder:(NSCoder *)aCoder; @end
+
+@interface NSObject <NSObject> {} @end
+
+typedef float CGFloat;
+
+typedef enum { NSMinXEdge = 0, NSMinYEdge = 1, NSMaxXEdge = 2, NSMaxYEdge = 3 } NSFastEnumerationState;
+
+@protocol NSFastEnumeration
+- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len;
+@end
+
+@class NSString;
+
+@interface NSDictionary : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration>
+- (NSUInteger)count;
+@end
+
+extern NSString * const NSBundleDidLoadNotification;
+
+@interface NSObject(NSKeyValueObserving)
+- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context;
+- (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath;
+@end
+
+enum { NSCaseInsensitivePredicateOption = 0x01,     NSDiacriticInsensitivePredicateOption = 0x02 };
+
+@interface NSResponder : NSObject <NSCoding> {}
+@end
+
+extern NSString * const NSFullScreenModeAllScreens;
+@interface NSWindowController : NSResponder <NSCoding> {}
+@end
+
+extern NSString *NSAlignmentBinding ;
+
+@interface _XCOQQuery : NSObject {}
+@end
+
+extern NSString *PBXWindowDidChangeFirstResponderNotification;
+
+@interface PBXModule : NSWindowController {}
+@end
+
+@class _XCOQHelpTextBackgroundView;
+@interface PBXOpenQuicklyModule : PBXModule
+{
+@private
+  _XCOQQuery *_query;
+}
+@end
+
+@interface PBXOpenQuicklyModule ()
+@property(readwrite, retain) _XCOQQuery *query;
+@end
+
+@implementation PBXOpenQuicklyModule  
+@synthesize query = _query;
+- (void) _clearQuery
+{
+  [self.query removeObserver: self forKeyPath: @"matches"];
+}
+@end
+
diff --git a/test/SemaObjC/property-9-impl-method.m b/test/SemaObjC/property-9-impl-method.m
new file mode 100644
index 0000000..84eb363
--- /dev/null
+++ b/test/SemaObjC/property-9-impl-method.m
@@ -0,0 +1,95 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify
+// rdar://5967199
+
+typedef signed char BOOL;
+@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+
+@protocol NSObject
+- (BOOL) isEqual:(id) object;
+@end
+
+@protocol NSCoding
+- (void) encodeWithCoder:(NSCoder *) aCoder;
+@end
+
+@interface NSObject < NSObject > {}
+@end
+
+typedef float CGFloat;
+typedef struct _NSPoint {} NSSize;
+typedef struct _NSRect {} NSRect;
+typedef enum { NSMinXEdge = 0, NSMinYEdge = 1, NSMaxXEdge = 2, NSMaxYEdge = 3} NSRectEdge;
+extern void NSDivideRect(NSRect inRect, NSRect * slice, NSRect * rem, CGFloat amount, NSRectEdge edge);
+
+@interface NSResponder:NSObject < NSCoding > {}
+@end
+
+@protocol NSAnimatablePropertyContainer
+- (id) animator;
+@end
+
+extern NSString *NSAnimationTriggerOrderIn;
+
+@interface NSView:NSResponder < NSAnimatablePropertyContainer > {}
+-(NSRect) bounds;
+@end
+
+enum {
+  NSBackgroundStyleLight = 0, NSBackgroundStyleDark, NSBackgroundStyleRaised, NSBackgroundStyleLowered
+};
+
+@interface NSTabView:NSView {}
+@end
+
+@ class OrganizerTabHeader;
+
+@interface OrganizerTabView:NSTabView {}
+@property(assign)
+NSSize minimumSize;
+@end
+
+@interface OrganizerTabView()
+@property(readonly) OrganizerTabHeader *tabHeaderView;
+@property(readonly) NSRect headerRect;
+@end
+
+@implementation OrganizerTabView
+@dynamic tabHeaderView, headerRect, minimumSize;
+-(CGFloat) tabAreaThickness { return 0; }
+-(NSRectEdge) rectEdgeForTabs { 
+  NSRect dummy, result = {};
+  NSDivideRect(self.bounds, &result, &dummy, self.tabAreaThickness, self.rectEdgeForTabs);
+  return 0;
+}
+@end
+
+@class NSImage;
+
+@interface XCImageArchiveEntry : NSObject
+{
+  NSImage *_cachedImage;
+}
+
+@end
+
+@implementation XCImageArchiveEntry
+
+- (NSImage *)image
+{
+  return _cachedImage;
+}
+
+@end
+
+@interface XCImageArchive : NSObject
+@end
+
+@implementation XCImageArchive
+
+- (NSImage *)imageNamed:(NSString *)name
+{
+    XCImageArchiveEntry * entry;
+    return entry ? entry.image : ((void *)0);
+}
+
+@end
diff --git a/test/SemaObjC/property-9.m b/test/SemaObjC/property-9.m
new file mode 100644
index 0000000..669f9c0
--- /dev/null
+++ b/test/SemaObjC/property-9.m
@@ -0,0 +1,98 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+typedef signed char BOOL;
+@protocol NSObject  - (BOOL)isEqual:(id)object; @end
+
+@interface NSObject <NSObject> {} @end
+
+@interface _NSServicesInContextMenu : NSObject {
+    id _requestor;
+    NSObject *_appleEventDescriptor;
+}
+
+@property (retain, nonatomic) id requestor;
+@property (retain, nonatomic) id appleEventDescriptor;
+
+@end
+
+@implementation _NSServicesInContextMenu
+
+@synthesize requestor = _requestor, appleEventDescriptor = _appleEventDescriptor;
+
+@end
+
+@class NSString;
+
+@protocol MyProtocol
+- (NSString *)stringValue;
+@end
+
+@interface MyClass : NSObject {
+  id  _myIvar;
+}
+@property (readwrite, retain) id<MyProtocol> myIvar;
+@end
+
+@implementation MyClass
+@synthesize myIvar = _myIvar;
+@end
+
+
+@interface BadPropClass
+{
+ int _awesome;
+}
+
+@property (readonly) int; // expected-warning {{declaration does not declare anything}}
+@property (readonly) ; // expected-error {{type name requires a specifier or qualifier}} \
+                          expected-warning {{declaration does not declare anything}}
+@property (readonly) int : 4; // expected-error {{property requires fields to be named}}
+
+
+// test parser recovery: rdar://6254579
+@property (                           // expected-note {{to match this '('}}
+           readonly getter=isAwesome) // expected-error {{error: expected ')'}}
+           
+  int _awesome;
+@property (readonlyx) // expected-error {{unknown property attribute 'readonlyx'}}
+  int _awesome2;
+
+@property (    // expected-note {{to match this '('}}
+           +)  // expected-error {{error: expected ')'}}
+           
+  int _awesome3;
+
+@end
+
+@protocol PVImageViewProtocol
+@property int inEyeDropperMode;
+@end
+
+@interface Cls
+@property int inEyeDropperMode;
+@end
+
+@interface PVAdjustColor @end
+
+@implementation PVAdjustColor
+
+- xx {
+  id <PVImageViewProtocol> view;
+  Cls *c;
+
+  c.inEyeDropperMode = 1;
+  view.inEyeDropperMode = 1;
+}
+@end
+
+// radar 7427072
+@interface MyStyleIntf 
+{
+    int _myStyle;
+}
+
+@property(readonly) int myStyle;
+
+- (float)setMyStyle:(int)style;
+@end
+
diff --git a/test/SemaObjC/property-and-class-extension.m b/test/SemaObjC/property-and-class-extension.m
new file mode 100644
index 0000000..51bf8de
--- /dev/null
+++ b/test/SemaObjC/property-and-class-extension.m
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -fsyntax-only -fobjc-nonfragile-abi2 -verify %s
+
+/**
+When processing @synthesize, treat ivars in a class extension the same as ivars in the class @interface, 
+and treat ivars in a superclass extension the same as ivars in the superclass @interface.
+In particular, when searching for an ivar to back an @synthesize, do look at ivars in the class's own class 
+extension but ignore any ivars in superclass class extensions.
+*/
+
+@interface Super {
+  	int ISA;
+}
+@end
+
+@interface Super() {
+  int Property;		// expected-note {{previously declared 'Property' here}}
+}
+@end
+
+@interface SomeClass : Super {
+        int interfaceIvar1;
+        int interfaceIvar2;
+}
+@property int Property;
+@property int Property1;
+@end
+
+@interface SomeClass () {
+  int Property1;
+}
+@end
+
+@implementation SomeClass 
+@synthesize Property;	// expected-error {{property 'Property' attempting to use ivar 'Property' declared in super class 'Super'}}
+@synthesize Property1;	// OK
+@end
diff --git a/test/SemaObjC/property-category-1.m b/test/SemaObjC/property-category-1.m
new file mode 100644
index 0000000..26e7313
--- /dev/null
+++ b/test/SemaObjC/property-category-1.m
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@interface Object
++ (id)new;
+@end
+
+@interface ReadOnly : Object
+{
+  int _object;
+  int _Anotherobject;
+}
+@property(readonly) int object;
+@property(readonly) int Anotherobject;
+@end
+
+@interface ReadOnly ()
+@property(readwrite) int object;
+@property(readwrite, setter = myAnotherobjectSetter:) int Anotherobject;
+@end
+
+@implementation ReadOnly
+@synthesize object = _object;
+@synthesize  Anotherobject = _Anotherobject;
+- (void) myAnotherobjectSetter : (int)val {
+    _Anotherobject = val;
+}
+- (int) Anotherobject { return _Anotherobject; }
+@end
+
+int main(int argc, char **argv) {
+    ReadOnly *test = [ReadOnly new];
+    test.object = 12345;
+    test.Anotherobject = 200;
+    return test.object - 12345 + test.Anotherobject - 200;
+}
+
+///
+
+@interface I0
+@property(readonly) int p0;	// expected-warning {{property 'p0' requires method 'p0' to be defined}}
+@end 
+
+@interface I0 (Cat0)
+@end 
+
+@interface I0 (Cat1)
+@end 
+  
+@implementation I0	// expected-note {{implementation is here}}
+- (void) foo {
+  self.p0 = 0; // expected-error {{assigning to property with 'readonly' attribute not allowed}}
+}
+@end
diff --git a/test/SemaObjC/property-category-2.m b/test/SemaObjC/property-category-2.m
new file mode 100644
index 0000000..e63672b
--- /dev/null
+++ b/test/SemaObjC/property-category-2.m
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// Test that a property can be synthesize in a category
+// implementation with no error.
+
+@protocol MyProtocol
+@property float  myFloat;
+@property float  anotherFloat; // expected-warning {{property 'anotherFloat' requires method 'anotherFloat' to be defined - use @dynamic}} \
+                               // expected-warning {{property 'anotherFloat' requires method 'setAnotherFloat:' to be defined }}
+@end
+
+@interface MyObject { float anotherFloat; }
+@end
+
+@interface MyObject (CAT) <MyProtocol>
+@end
+
+@implementation MyObject (CAT)	// expected-note 2 {{implementation is here}}
+@dynamic myFloat;	// OK
+@synthesize anotherFloat; // expected-error {{@synthesize not allowed in a category's implementation}}
+@end
diff --git a/test/SemaObjC/property-category-3.m b/test/SemaObjC/property-category-3.m
new file mode 100644
index 0000000..237de0f
--- /dev/null
+++ b/test/SemaObjC/property-category-3.m
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@protocol P
+  @property(readonly) int X;
+@end
+
+@protocol P1<P>
+  @property (copy) id ID;
+@end
+
+@interface I
+@end
+
+@interface I (Cat) <P>
+@property float X; // expected-warning {{property type 'float' is incompatible with type 'int' inherited from 'P'}}
+@end
+
+@interface I (Cat2) <P1>
+@property (retain) id ID; // expected-warning {{property 'ID' 'copy' attribute does not match the property inherited from 'P1'}}
+@end
+
+
+@interface A 
+@property(assign) int categoryProperty;
+@end
+
+// Don't issue warning on unimplemented setter/getter
+// because property is @dynamic.
+@implementation A 
+@dynamic categoryProperty;
+@end
diff --git a/test/SemaObjC/property-category-4.m b/test/SemaObjC/property-category-4.m
new file mode 100644
index 0000000..aa49a3f
--- /dev/null
+++ b/test/SemaObjC/property-category-4.m
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@interface IDELogNavigator
+{
+  id selectedObjects;
+}
+@end
+
+@interface IDELogNavigator (CAT)
+  @property (readwrite, retain) id selectedObjects; // expected-note {{property declared here}}
+  @property (readwrite, retain) id d_selectedObjects; // expected-note {{property declared here}}
+@end
+
+@implementation IDELogNavigator 
+@synthesize selectedObjects = _selectedObjects; // expected-error {{property declared in category 'CAT' cannot be implemented in class implementation}}
+@dynamic d_selectedObjects; // expected-error {{property declared in category 'CAT' cannot be implemented in class implementation}}
+@end
+
diff --git a/test/SemaObjC/property-category-impl.m b/test/SemaObjC/property-category-impl.m
new file mode 100644
index 0000000..9979497
--- /dev/null
+++ b/test/SemaObjC/property-category-impl.m
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+/* This test is for categories which don't implement the accessors but some accessors are
+   implemented in their base class implementation. In this case,no warning must be issued.
+*/
+
+@interface MyClass 
+{
+    int        _foo;
+}
+@property(readonly)    int        foo;
+@end
+
+@implementation MyClass
+- (int) foo        { return _foo; }
+@end
+
+@interface MyClass (private)
+@property(readwrite)    int        foo;
+@end
+
+@implementation MyClass (private)
+- (void) setFoo:(int)foo    { _foo = foo; }
+@end
+
+@interface MyClass (public)
+@property(readwrite)    int        foo;	// expected-warning {{property 'foo' requires method 'setFoo:' to be defined }}
+@end
+
+@implementation MyClass (public)// expected-note {{implementation is here}}
+@end 
diff --git a/test/SemaObjC/property-error-readonly-assign.m b/test/SemaObjC/property-error-readonly-assign.m
new file mode 100644
index 0000000..fc8c48c
--- /dev/null
+++ b/test/SemaObjC/property-error-readonly-assign.m
@@ -0,0 +1,44 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@interface A
+ -(int) x;
+@property (readonly) int x;
+@property int ok;
+@end
+
+@interface B
+ -(void) setOk:(int)arg;
+ -(int) x;
+ -(int) ok;
+@end
+
+void f0(A *a, B* b) {
+  a.x = 10;  // expected-error {{assigning to property with 'readonly' attribute not allowed}}
+  a.ok = 20;
+  b.x = 10;  // expected-error {{setter method is needed to assign to object using property assignment syntax}}
+  b.ok = 20;
+}
+
+typedef struct {
+  int i1, i2;
+} NSRect;
+
+NSRect NSMakeRect();
+
+@interface NSWindow 
+{
+    NSRect _frame;
+}
+- (NSRect)frame;
+@end
+
+@interface NSWindow (Category)
+-(void)methodToMakeClangCrash;
+@end
+
+@implementation NSWindow (Category)
+-(void)methodToMakeClangCrash
+{
+ self.frame =  NSMakeRect(); // expected-error {{setter method is needed to assign to object using property assignment syntax}}
+}
+@end
diff --git a/test/SemaObjC/property-expression-error.m b/test/SemaObjC/property-expression-error.m
new file mode 100644
index 0000000..6b5cf04
--- /dev/null
+++ b/test/SemaObjC/property-expression-error.m
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1  -fsyntax-only -verify %s
+
+@interface AddressMyProperties 
+{
+  unsigned index;
+}
+@property unsigned index;
+@end
+
+@implementation AddressMyProperties
+@synthesize index;
+@end
+
+int main() {
+	AddressMyProperties *object;
+	&object.index; // expected-error {{address of property expression requested}}
+	return 0;
+}
+
+typedef int Foo;
+void test() {
+  Foo.x;	// expected-error {{expected identifier or '('}}
+}
diff --git a/test/SemaObjC/property-impl-misuse.m b/test/SemaObjC/property-impl-misuse.m
new file mode 100644
index 0000000..58c91c5
--- /dev/null
+++ b/test/SemaObjC/property-impl-misuse.m
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@interface I {
+  int Y;
+}
+@property int X;
+@property int Y;
+@property int Z;
+@end
+
+@implementation I
+@dynamic X; // expected-note {{previous declaration is here}}
+@dynamic X; // expected-error {{property 'X' is already implemented}}
+@synthesize Y; // expected-note {{previous use is here}}
+@synthesize Z=Y; // expected-error {{synthesized properties 'Z' and 'Y' both claim ivar 'Y'}}
+@end
diff --git a/test/SemaObjC/property-in-class-extension.m b/test/SemaObjC/property-in-class-extension.m
new file mode 100644
index 0000000..3f252d0
--- /dev/null
+++ b/test/SemaObjC/property-in-class-extension.m
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1  -fsyntax-only -verify %s
+// rdar: // 7766184
+
+@interface Foo @end
+
+@interface Foo ()
+  @property (readonly) int bar;
+@end
+
+void FUNC () {
+    Foo *foo;
+    foo.bar = 0; // expected-error {{assigning to property with 'readonly' attribute not allowed}}
+}
+
+
diff --git a/test/SemaObjC/property-inherited.m b/test/SemaObjC/property-inherited.m
new file mode 100644
index 0000000..5c5631e
--- /dev/null
+++ b/test/SemaObjC/property-inherited.m
@@ -0,0 +1,44 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify 
+
+// <rdar://problem/6497242> Inherited overridden protocol declared objects don't work
+
+@protocol NSObject @end
+@interface NSObject @end
+
+@protocol FooDelegate<NSObject>
+@optional
+- (void)fooTask;
+@end
+
+@protocol BarDelegate<NSObject, FooDelegate>
+@optional
+- (void)barTask;
+@end
+
+@interface Foo : NSObject {
+  id _delegate;
+}
+@property(nonatomic, assign) id<FooDelegate> delegate;
+@property(nonatomic, assign) id<BarDelegate> delegate2;
+@end
+@interface Bar : Foo {
+}
+@property(nonatomic, assign) id<BarDelegate> delegate;
+@property(nonatomic, assign) id<FooDelegate> delegate2; // expected-warning{{property type 'id<FooDelegate>' is incompatible with type 'id<BarDelegate>' inherited from 'Foo'}}
+@end
+
+@interface NSData @end
+
+@interface NSMutableData : NSData @end
+
+@interface Base : NSData 
+@property(assign) id ref;
+@property(assign) Base *p_base;
+@property(assign) NSMutableData *p_data;	
+@end
+
+@interface Data : Base 
+@property(assign) NSData *ref;	
+@property(assign) Data *p_base;	
+@property(assign) NSData *p_data;	// expected-warning{{property type 'NSData *' is incompatible with type 'NSMutableData *' inherited from 'Base'}}
+@end
diff --git a/test/SemaObjC/property-ivar-mismatch.m b/test/SemaObjC/property-ivar-mismatch.m
new file mode 100644
index 0000000..16ff338
--- /dev/null
+++ b/test/SemaObjC/property-ivar-mismatch.m
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// Test that arithmatic types on property and its ivar have exact match.
+
+@interface Test4 
+{
+   char ivar; // expected-note{{ivar is declared here}}
+}
+@property int prop;
+@end
+
+@implementation Test4
+@synthesize prop = ivar;  // expected-error {{type of property 'prop' ('int') does not match type of ivar 'ivar' ('char')}}
+@end
+
diff --git a/test/SemaObjC/property-method-lookup-impl.m b/test/SemaObjC/property-method-lookup-impl.m
new file mode 100644
index 0000000..0a018b0
--- /dev/null
+++ b/test/SemaObjC/property-method-lookup-impl.m
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1  -fsyntax-only -verify %s
+
+@interface SSyncCEList
+{
+	id _list;
+}
+@end
+
+@implementation SSyncCEList
+
+- (id) list { return 0; }
+@end
+
+@interface SSyncConflictList : SSyncCEList
+@end
+
+@implementation SSyncConflictList
+
+- (id)Meth : (SSyncConflictList*)other
+  {
+    return other.list;
+  }
+@end
+
diff --git a/test/SemaObjC/property-missing.m b/test/SemaObjC/property-missing.m
new file mode 100644
index 0000000..6ce0bea
--- /dev/null
+++ b/test/SemaObjC/property-missing.m
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// PR3234
+
+@protocol NSCopying @end
+@interface NSObject @end
+
+void f1(NSObject *o)
+{
+  o.foo; // expected-error{{property 'foo' not found on object of type 'NSObject *'}}
+}
+
+void f2(id<NSCopying> o)
+{
+  o.foo; // expected-error{{property 'foo' not found on object of type 'id<NSCopying>'}}
+}
+
+void f3(id o)
+{
+  o.foo; // expected-error{{property 'foo' not found on object of type 'id'}}
+}
+
diff --git a/test/SemaObjC/property-nonfragile-abi.m b/test/SemaObjC/property-nonfragile-abi.m
new file mode 100644
index 0000000..ae82cb7
--- /dev/null
+++ b/test/SemaObjC/property-nonfragile-abi.m
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -fsyntax-only -fobjc-nonfragile-abi -verify %s
+
+typedef signed char BOOL;
+
+@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+
+@protocol NSObject
+- (BOOL)isEqual:(id)object;
+@end
+
+@interface NSObject <NSObject> {}
+@end
+
+@interface XCDeviceWillExecuteInfoBaton : NSObject {}
+  @property (retain) __attribute__((objc_gc(strong))) NSString *sdkPath;
+@end
+
+@implementation XCDeviceWillExecuteInfoBaton
+  @synthesize sdkPath; 
+@end
+
diff --git a/test/SemaObjC/property-noprotocol-warning.m b/test/SemaObjC/property-noprotocol-warning.m
new file mode 100644
index 0000000..71bb86a
--- /dev/null
+++ b/test/SemaObjC/property-noprotocol-warning.m
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+
+@interface Object
++ (id) new;
+@end
+
+@protocol GCObject
+@property int class;
+@end
+
+@protocol DerivedGCObject <GCObject>
+@property int Dclass;
+@end
+
+@interface GCObject  : Object <DerivedGCObject> {
+    int ifield;
+    int iOwnClass;
+    int iDclass;
+}
+@property int OwnClass;
+@end
+
+@implementation GCObject : Object
+@synthesize class=ifield;
+@synthesize Dclass=iDclass;
+@synthesize OwnClass=iOwnClass;
+@end
+
+int main(int argc, char **argv) {
+    GCObject *f = [GCObject new];
+    f.class = 5;
+    f.Dclass = 1;
+    f.OwnClass = 3;
+    return f.class + f.Dclass  + f.OwnClass - 9;
+}
diff --git a/test/SemaObjC/property-not-lvalue.m b/test/SemaObjC/property-not-lvalue.m
new file mode 100644
index 0000000..55eec3e
--- /dev/null
+++ b/test/SemaObjC/property-not-lvalue.m
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+typedef struct NSSize {
+     		int width;
+		struct {
+		  int dim;
+		} inner;
+} NSSize;
+
+@interface Foo  {
+        NSSize _size;
+}
+@property NSSize size;
+@end
+
+void foo() { 
+        Foo *f;
+        f.size.width = 2.2; // expected-error {{expression is not assignable using property assignment syntax}}
+	f.size.inner.dim = 200; // expected-error {{expression is not assignable using property assignment syntax}}
+}
+
+// radar 7628953
+
+@interface Gorf  {
+}
+- (NSSize)size;
+@end
+
+@implementation Gorf
+- (void)MyView_sharedInit {
+    self.size.width = 2.2; // expected-error {{expression is not assignable using property assignment syntax}}
+}
+- (NSSize)size {}
+@end
diff --git a/test/SemaObjC/property-redundant-decl-accessor.m b/test/SemaObjC/property-redundant-decl-accessor.m
new file mode 100644
index 0000000..2a24e7e
--- /dev/null
+++ b/test/SemaObjC/property-redundant-decl-accessor.m
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -fsyntax-only -Werror -verify %s
+
+@interface MyClass {
+    const char	*_myName;
+}
+
+@property const char *myName;
+
+- (const char *)myName;
+- (void)setMyName:(const char *)name;
+
+@end
+
+@implementation MyClass
+
+@synthesize myName = _myName;
+
+@end
diff --git a/test/SemaObjC/property-typecheck-1.m b/test/SemaObjC/property-typecheck-1.m
new file mode 100644
index 0000000..f86e047
--- /dev/null
+++ b/test/SemaObjC/property-typecheck-1.m
@@ -0,0 +1,101 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@interface A
+-(float) x;	// expected-note {{declared here}}
+@property int x; // expected-warning {{type of property 'x' does not match type of accessor 'x'}}
+@end
+
+@interface A (Cat)
+@property int moo;	// expected-note {{previous definition is here}}
+@end
+
+@implementation A (Cat)
+-(int) moo {
+  return 0;
+}
+-(void) setMoo: (float) x { // expected-warning {{conflicting parameter types in implementation of 'setMoo:': 'int' vs 'float'}}
+}
+@end
+
+
+typedef int T[2];
+typedef void (F)(void);
+
+@interface C
+@property(assign) T p2;  // expected-error {{property cannot have array or function type 'T'}}
+
+@property(assign) F f2; // expected-error {{property cannot have array or function type 'F'}}
+
+@end
+
+
+@class SSyncSet;
+
+@interface SPeer
+  @property(nonatomic,readonly,retain) SSyncSet* syncSet;
+@end
+
+@class SSyncSet_iDisk;
+
+@interface SPeer_iDisk_remote1 : SPeer
+- (SSyncSet_iDisk*) syncSet; // expected-note {{declared here}}
+@end
+
+@interface SPeer_iDisk_local
+- (SSyncSet_iDisk*) syncSet;
+@end
+
+@interface SSyncSet
+@end
+
+@interface SSyncSet_iDisk
+@property(nonatomic,readonly,retain) SPeer_iDisk_local* localPeer;
+@end
+
+@interface SPeer_iDisk_remote1 (protected)
+@end
+
+@implementation SPeer_iDisk_remote1 (protected)
+- (id) preferredSource1
+{
+  return self.syncSet.localPeer; // expected-warning {{type of property 'syncSet' does not match type of accessor 'syncSet'}}
+}
+@end
+
+@interface NSArray @end
+
+@interface NSMutableArray : NSArray
+@end
+
+@interface Class1 
+{
+ NSMutableArray* pieces;
+ NSArray* first;
+}
+
+@property (readonly) NSArray* pieces;  // expected-warning {{type of property 'pieces' does not match type of accessor 'pieces'}}
+@property (readonly) NSMutableArray* first; 
+
+- (NSMutableArray*) pieces; // expected-note {{declared here}} // expected-note {{declared here}}
+- (NSArray*) first;
+@end
+
+@interface Class2  {
+ Class1* container;
+}
+
+@end
+
+@implementation Class2
+
+- (id) lastPiece
+{
+ return container.pieces; // expected-warning {{type of property 'pieces' does not match type of accessor 'pieces'}}
+}
+
+- (id)firstPeice
+{
+  return container.first; 
+}
+@end
+
diff --git a/test/SemaObjC/property-user-setter.m b/test/SemaObjC/property-user-setter.m
new file mode 100644
index 0000000..9479bc6
--- /dev/null
+++ b/test/SemaObjC/property-user-setter.m
@@ -0,0 +1,104 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@interface I0 
+@property(readonly) int x;
+@property(readonly) int y;
+@property(readonly) int z;
+-(void) setY: (int) y0;
+@end
+
+@interface I0 (Cat0)
+-(void) setX: (int) a0;
+@end
+
+@implementation I0
+@dynamic x;
+@dynamic y;
+@dynamic z;
+-(void) setY: (int) y0{}
+
+-(void) im0 {
+  self.x = 0;
+  self.y = 2;
+  self.z = 2; // expected-error {{assigning to property with 'readonly' attribute not allowed}}
+}
+@end
+
+// Test when property is 'readonly' but it has a setter in
+// its implementation only.
+@interface I1  {
+}
+@property(readonly) int identifier;
+@end
+
+
+@implementation I1
+@dynamic identifier;
+- (void)setIdentifier:(int)ident {}
+
+- (id)initWithIdentifier:(int)Arg {
+    self.identifier = 0;
+}
+
+@end
+
+
+// Also in a category implementation
+@interface I1(CAT)  
+@property(readonly) int rprop;
+@end
+
+
+@implementation I1(CAT)
+@dynamic rprop;
+- (void)setRprop:(int)ident {}
+
+- (id)initWithIdentifier:(int)Arg {
+    self.rprop = 0;
+}
+
+@end
+
+static int g_val;
+
+@interface Root 
++ alloc;
+- init;
+@end
+
+@interface Subclass : Root
+{
+    int setterOnly;
+}
+- (void) setSetterOnly:(int)value;	// expected-note {{or because setter is declared here, but no getter method 'setterOnly' is found}}
+@end
+
+@implementation Subclass
+- (void) setSetterOnly:(int)value {
+    setterOnly = value;
+    g_val = setterOnly;
+}
+@end
+
+@interface C {}
+// - (int)Foo;
+- (void)setFoo:(int)value;	// expected-note 2 {{or because setter is declared here, but no getter method 'Foo' is found}}
+@end
+
+void g(int);
+
+void f(C *c) {
+    c.Foo = 17; // expected-error {{property 'Foo' not found on object of type 'C *'}}
+    g(c.Foo); // expected-error {{property 'Foo' not found on object of type 'C *'}}
+}
+
+
+void abort(void);
+int main (void) {
+    Subclass *x = [[Subclass alloc] init];
+
+    x.setterOnly = 4;  // expected-error {{property 'setterOnly' not found on object of type 'Subclass *'}}
+    if (g_val != 4)
+      abort ();
+    return 0;
+}
diff --git a/test/SemaObjC/property-weak.m b/test/SemaObjC/property-weak.m
new file mode 100644
index 0000000..a4397a6
--- /dev/null
+++ b/test/SemaObjC/property-weak.m
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -fsyntax-only -verify %s
+
+@interface foo
+@property(nonatomic) int foo __attribute__((weak_import));
+@end
diff --git a/test/SemaObjC/property.m b/test/SemaObjC/property.m
new file mode 100644
index 0000000..4d00bd2
--- /dev/null
+++ b/test/SemaObjC/property.m
@@ -0,0 +1,65 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -fsyntax-only -verify %s
+
+@interface I 
+{
+	int IVAR; // expected-note{{ivar is declared here}}
+	int name;
+}
+@property int d1;
+@property id  prop_id; // expected-warning {{no 'assign', 'retain', or 'copy' attribute is specified - 'assign' is assumed}}, expected-warning {{default property attribute 'assign' not appropriate for non-gc object}}
+@property int name;
+@end
+
+@interface I(CAT)
+@property int d1;	// expected-warning {{property 'd1' requires method 'd1' to be defined }} \
+			// expected-warning {{property 'd1' requires method 'setD1:' to be defined }}
+@end
+
+@implementation I
+@synthesize d1;		// expected-error {{synthesized property 'd1' must either be named the same as}}
+@dynamic    bad;	// expected-error {{property implementation must have its declaration in interface 'I'}}
+@synthesize prop_id;	// expected-error {{synthesized property 'prop_id' must either be named the same}}  // expected-note {{previous declaration is here}}
+@synthesize prop_id = IVAR;	// expected-error {{type of property 'prop_id' ('id') does not match type of ivar 'IVAR' ('int')}} // expected-error {{property 'prop_id' is already implemented}}
+@synthesize name;	// OK! property with same name as an accessible ivar of same name
+@end
+
+@implementation I(CAT)  // expected-note 2 {{implementation is here}}
+@synthesize d1;		// expected-error {{@synthesize not allowed in a category's implementation}}
+@dynamic bad;		// expected-error {{property implementation must have its declaration in the category 'CAT'}}
+@end
+
+@implementation E	// expected-warning {{cannot find interface declaration for 'E'}}
+@dynamic d;		// expected-error {{property implementation must have its declaration in interface 'E'}}
+@end
+
+@implementation Q(MYCAT)  // expected-error {{cannot find interface declaration for 'Q'}}
+@dynamic d;		// expected-error {{property implementation in a category with no category declaration}}
+@end
+
+@interface Foo
+@property double bar;
+@end
+
+int func1() {
+   id foo;
+   double bar = [foo bar];
+   return 0;
+}
+
+// PR3932
+typedef id BYObjectIdentifier;
+@interface Foo1  {
+  void *isa;
+}
+@property(copy) BYObjectIdentifier identifier;
+@end
+
+@interface Foo2 
+{
+  int ivar;
+}
+@property int treeController;  // expected-note {{property declared here}}
+@property int ivar;	// OK
+@property int treeController;  // expected-error {{property has a previous declaration}}
+@end
+
diff --git a/test/SemaObjC/props-on-prots.m b/test/SemaObjC/props-on-prots.m
new file mode 100644
index 0000000..c01e833
--- /dev/null
+++ b/test/SemaObjC/props-on-prots.m
@@ -0,0 +1,65 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+typedef signed char BOOL;
+@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+
+@protocol NSObject
+- (BOOL) isEqual:(id) object;
+@end
+
+@protocol NSCoding
+- (void) encodeWithCoder:(NSCoder *) aCoder;
+@end
+
+@interface NSObject < NSObject > {} @end
+
+typedef float CGFloat;
+
+@interface NSResponder:NSObject < NSCoding > {} @end
+
+@class XCElementView;
+
+typedef struct _XCElementInset {} XCElementInset;
+
+@protocol XCElementP < NSObject >
+-(id) vertical;
+@end
+
+@protocol XCElementDisplayDelegateP;
+@protocol XCElementTabMarkerP;
+
+typedef NSObject < XCElementTabMarkerP > XCElementTabMarker;
+
+@protocol XCElementTabberP < XCElementP >
+-(void) setMarker:(XCElementTabMarker *) marker;
+@end
+
+typedef NSObject < XCElementTabberP > XCElementTabber;
+
+@protocol XCElementTabMarkerP < NSObject >
+@property(nonatomic)
+BOOL variableSized;
+@end
+
+@protocol XCElementJustifierP < XCElementP >
+-(void) setHJustification:(CGFloat) hJust;
+@end
+
+typedef NSObject < XCElementJustifierP > XCElementJustifier;
+@interface XCElementImp:NSObject < XCElementP > {}
+@end
+
+@class XCElementImp;
+
+@interface XCElementTabberImp:XCElementImp < XCElementTabberP > {
+	XCElementTabMarker *_marker;
+}
+@end
+
+@implementation XCElementTabberImp 
+- (void) setMarker:(XCElementTabMarker *) marker {
+  if (_marker && _marker.variableSized) {
+  }
+}
+- (id)vertical { return self; }
+- (BOOL)isEqual:x { return 1; }
+@end
diff --git a/test/SemaObjC/protocol-archane.m b/test/SemaObjC/protocol-archane.m
new file mode 100644
index 0000000..138c43d
--- /dev/null
+++ b/test/SemaObjC/protocol-archane.m
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// rdar://5986251
+
+@protocol SomeProtocol
+- (void) bar;
+@end
+
+void bar();
+void foo(id x) {
+  bar((short<SomeProtocol>)x); // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  bar((<SomeProtocol>)x);      // expected-warning {{protocol qualifiers without 'id' is archaic}}
+
+  [(<SomeProtocol>)x bar];      // expected-warning {{protocol qualifiers without 'id' is archaic}}
+}
+
+@protocol MyProtocol
+- (void)doSomething;
+@end
+
+@interface MyClass
+- (void)m1:(id <MyProtocol> const)arg1;
+
+// FIXME: provide a better diagnostic (no typedef).
+- (void)m2:(id <MyProtocol> short)arg1; // expected-error {{'short type-name' is invalid}}
+@end
+
+typedef int NotAnObjCObjectType;
+
+// GCC doesn't diagnose this.
+NotAnObjCObjectType <SomeProtocol> *obj; // expected-error {{invalid protocol qualifiers on non-ObjC type}}
+
+typedef struct objc_class *Class;
+
+Class <SomeProtocol> UnfortunateGCCExtension;
+
diff --git a/test/SemaObjC/protocol-attribute.m b/test/SemaObjC/protocol-attribute.m
new file mode 100644
index 0000000..e04a39b
--- /dev/null
+++ b/test/SemaObjC/protocol-attribute.m
@@ -0,0 +1,49 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+__attribute ((unavailable))
+@protocol FwProto; // expected-note{{marked unavailable}}
+
+Class <FwProto> cFw = 0;  // expected-warning {{'FwProto' is unavailable}}
+
+
+__attribute ((deprecated)) @protocol MyProto1
+@end
+
+@protocol Proto2  <MyProto1>  // expected-warning {{'MyProto1' is deprecated}}
++method2;
+@end
+
+
+@interface MyClass1 <MyProto1>  // expected-warning {{'MyProto1' is deprecated}}
+{
+  Class isa;
+}
+@end
+
+@interface Derived : MyClass1 <MyProto1>  // expected-warning {{'MyProto1' is deprecated}}
+{
+	id <MyProto1> ivar;  // expected-warning {{'MyProto1' is deprecated}}
+}
+@end
+
+@interface MyClass1 (Category) <MyProto1, Proto2>  // expected-warning {{'MyProto1' is deprecated}}
+@end
+
+
+
+Class <MyProto1> clsP1 = 0;  // expected-warning {{'MyProto1' is deprecated}}
+
+@protocol FwProto @end // expected-note{{marked unavailable}}
+
+@interface MyClass2 <FwProto> // expected-warning {{'FwProto' is unavailable}}
+@end
+
+__attribute ((unavailable)) __attribute ((deprecated)) @protocol XProto; // expected-note{{marked unavailable}}
+
+id <XProto> idX = 0; // expected-warning {{'XProto' is unavailable}} expected-warning {{'XProto' is deprecated}}
+
+int main ()
+{
+	MyClass1 <MyProto1> *p1;  // expected-warning {{'MyProto1' is deprecated}}
+}
+
diff --git a/test/SemaObjC/protocol-expr-1.m b/test/SemaObjC/protocol-expr-1.m
new file mode 100644
index 0000000..fe01d1d
--- /dev/null
+++ b/test/SemaObjC/protocol-expr-1.m
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@protocol fproto;
+
+@protocol p1 
+@end
+
+@class cl;
+
+int main()
+{
+	Protocol *proto = @protocol(p1);
+        Protocol *fproto = @protocol(fproto);
+}
+
diff --git a/test/SemaObjC/protocol-expr-neg-1.m b/test/SemaObjC/protocol-expr-neg-1.m
new file mode 100644
index 0000000..58ac8c0
--- /dev/null
+++ b/test/SemaObjC/protocol-expr-neg-1.m
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@class Protocol;
+
+@protocol fproto;
+
+@protocol p1 
+@end
+
+@class cl;
+
+int main()
+{
+	Protocol *proto = @protocol(p1);
+        Protocol *fproto = @protocol(fproto);
+	Protocol *pp = @protocol(i); // expected-error {{cannot find protocol declaration for 'i'}}
+	Protocol *p1p = @protocol(cl); // expected-error {{cannot find protocol declaration for 'cl'}}
+}
+
diff --git a/test/SemaObjC/protocol-id-test-1.m b/test/SemaObjC/protocol-id-test-1.m
new file mode 100644
index 0000000..6b2b682
--- /dev/null
+++ b/test/SemaObjC/protocol-id-test-1.m
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -verify %s
+
+@interface FF
+- (void) Meth;
+@end
+
+@protocol P
+@end
+
+@interface INTF<P>
+- (void)IMeth;
+@end
+
+@implementation INTF
+- (void)IMeth {INTF<P> *pi;  [pi Meth]; } // expected-warning {{method '-Meth' not found (return type defaults to 'id')}}
+@end
diff --git a/test/SemaObjC/protocol-id-test-2.m b/test/SemaObjC/protocol-id-test-2.m
new file mode 100644
index 0000000..a9365e9
--- /dev/null
+++ b/test/SemaObjC/protocol-id-test-2.m
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -verify %s
+
+@protocol P
+@end
+
+@interface INTF<P>
+- (void)IMeth;
+@end
+
+@implementation INTF
+- (void)IMeth { [(id<P>)self Meth]; }  // expected-warning {{method '-Meth' not found (return type defaults to 'id')}}
+@end
diff --git a/test/SemaObjC/protocol-id-test-3.m b/test/SemaObjC/protocol-id-test-3.m
new file mode 100644
index 0000000..624bab0
--- /dev/null
+++ b/test/SemaObjC/protocol-id-test-3.m
@@ -0,0 +1,94 @@
+// RUN: %clang_cc1 -pedantic -fsyntax-only -verify %s
+
+@protocol MyProto1 
+@end
+
+@protocol MyProto2 
+@end
+
+@interface INTF @end
+
+id<MyProto1> Func(INTF <MyProto1, MyProto2> *p2) // expected-note 2{{passing argument to parameter 'p2' here}}
+{
+	return p2;
+}
+
+
+
+
+ id<MyProto1> Gunc(id <MyProto1, MyProto2>p2)
+{
+	return p2;
+}
+
+
+ id<MyProto1> Gunc1(id <MyProto1, MyProto2>p2)
+{
+	return p2;
+}
+
+id<MyProto1, MyProto2> Gunc2(id <MyProto1>p2)
+{
+	Func(p2);	// expected-warning {{passing 'id<MyProto1>' to parameter of incompatible type 'INTF<MyProto1,MyProto2> *'}}
+	return p2;	// expected-warning {{returning 'id<MyProto1>' from a function with incompatible result type 'id<MyProto1,MyProto2>'}}
+}
+
+
+
+id<MyProto1> Gunc3(id <MyProto2>p2)
+{
+	return p2;	 // expected-warning {{returning 'id<MyProto2>' from a function with incompatible result type 'id<MyProto1>'}}
+}
+
+
+id<MyProto1, MyProto2> Gunc4(id <MyProto2, MyProto1>p2)
+{
+	return p2;
+}
+
+
+
+INTF<MyProto1> * Hunc(id <MyProto1, MyProto2>p2)
+{
+	return p2;
+}
+
+
+INTF<MyProto1> * Hunc1(id <MyProto1, MyProto2>p2)
+{
+	return p2;
+}
+
+INTF<MyProto1, MyProto2> * Hunc2(id <MyProto1>p2)
+{
+	Func(p2);	// expected-warning {{passing 'id<MyProto1>' to parameter of incompatible type 'INTF<MyProto1,MyProto2> *'}}
+	return p2;	// expected-warning {{returning 'id<MyProto1>' from a function with incompatible result type 'INTF<MyProto1,MyProto2> *'}}
+}
+
+INTF<MyProto1> * Hunc3(id <MyProto2>p2)
+{
+	return p2;	 // expected-warning {{returning 'id<MyProto2>' from a function with incompatible result type 'INTF<MyProto1> *'}}
+}
+
+
+INTF<MyProto1, MyProto2> * Hunc4(id <MyProto2, MyProto1>p2)
+{
+	return p2;
+}
+
+id Iunc(id <MyProto1, MyProto2>p2)
+{
+	return p2;
+}
+
+
+id<MyProto1> Iunc1(id p2)
+{
+	return p2;
+}
+
+id<MyProto1, MyProto2> Iunc2(id p2)
+{
+	Iunc(p2);	
+	return p2;
+}
diff --git a/test/SemaObjC/protocol-implementation-inherited.m b/test/SemaObjC/protocol-implementation-inherited.m
new file mode 100644
index 0000000..c333bb5
--- /dev/null
+++ b/test/SemaObjC/protocol-implementation-inherited.m
@@ -0,0 +1,56 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@protocol P0
+-bar;
+@end
+
+@interface A <P0>
+@end
+
+// Interface conforms to inherited protocol
+
+@interface B0 : A <P0>
+@end
+
+@implementation B0
+@end
+
+// Interface conforms to a protocol which extends another. The other
+// protocol is inherited, and extended methods are implemented.
+
+@protocol P1 <P0>
+-foo;
+@end
+
+@interface B1 : A <P1>
+@end
+
+@implementation B1
+-foo { return 0; };
+@end
+
+// Interface conforms to a protocol whose methods are provided by an
+// alternate inherited protocol.
+
+@protocol P2
+-bar;
+@end
+
+@interface B2 : A <P2>
+@end
+
+@implementation B2
+@end
+
+// Interface conforms to a protocol whose methods are provided by a base class.
+
+@interface A1 
+-bar;
+@end
+
+@interface B3 : A1 <P2>
+@end
+
+@implementation B3
+@end
+
diff --git a/test/SemaObjC/protocol-lookup-2.m b/test/SemaObjC/protocol-lookup-2.m
new file mode 100644
index 0000000..bf07523
--- /dev/null
+++ b/test/SemaObjC/protocol-lookup-2.m
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+@interface NSObject @end
+
+@protocol ProtocolA
+
++ (id)classMethod;
+- (id)instanceMethod;
+
+@end
+
+@protocol ProtocolB <ProtocolA>
+
+@end
+
+@interface Foo : NSObject <ProtocolB>
+
+@end
+
+@interface SubFoo : Foo
+
+@end
+
+@implementation SubFoo
+
++ (id)method {
+  return [super classMethod];
+}
+
+- (id)method {
+  return [super instanceMethod];
+}
+
+@end
diff --git a/test/SemaObjC/protocol-lookup.m b/test/SemaObjC/protocol-lookup.m
new file mode 100644
index 0000000..ed3fbe0
--- /dev/null
+++ b/test/SemaObjC/protocol-lookup.m
@@ -0,0 +1,51 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+@protocol NSObject
+- retain;
+- release;
+@end
+
+@interface NSObject
+- init;
+- dealloc;
+@end
+
+@protocol Foo <NSObject>
+@end
+
+@protocol Bar <Foo>
+@end
+
+@interface Baz : NSObject {
+	id <Foo> _foo;
+	id <Bar> _bar;
+}
+- (id)initWithFoo:(id <Foo>)foo bar:(id <Bar>)bar;
+@end
+
+@implementation Baz
+
+- (id)init
+{
+	return [self initWithFoo:0 bar:0];
+}
+
+- (id)initWithFoo:(id <Foo>)foo bar:(id <Bar>)bar
+{
+	self = [super init];
+	if (self != 0) {
+		_foo = [foo retain];
+		_bar = [bar retain];
+	}
+	return self;
+}
+
+- dealloc
+{
+	[_foo release];
+	[_bar release];
+	[super dealloc];
+	return 0;
+}
+
+@end
+
diff --git a/test/SemaObjC/protocol-qualified-class-unsupported.m b/test/SemaObjC/protocol-qualified-class-unsupported.m
new file mode 100644
index 0000000..4bf6b28
--- /dev/null
+++ b/test/SemaObjC/protocol-qualified-class-unsupported.m
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+#include <stddef.h>
+
+typedef struct objc_class *Class;
+typedef struct objc_object {
+    Class isa;
+} *id;
+id objc_getClass(const char *s);
+
+@interface Object
++ self;
+@end
+
+@protocol Func
++ (void) class_func0;
+- (void) instance_func0;
+@end
+
+@interface Derived: Object <Func>
+@end
+
+@interface Derived2: Object <Func>
+@end
+
+static void doSomething(Class <Func> unsupportedObjectType) {
+  [unsupportedObjectType class_func0];
+}
+
+static void doSomethingElse(id <Func> pleaseConvertToThisType) {
+  [pleaseConvertToThisType class_func0];
+}
+
+int main(int argv, char *argc[]) {
+  doSomething([Derived self]);
+  doSomething([Derived2 self]);
+  doSomethingElse([Derived self]);
+  doSomethingElse([Derived2 self]);
+}
+
diff --git a/test/SemaObjC/protocol-typecheck.m b/test/SemaObjC/protocol-typecheck.m
new file mode 100644
index 0000000..4eb1b26
--- /dev/null
+++ b/test/SemaObjC/protocol-typecheck.m
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@interface NSObject @end
+@protocol XCElementP @end
+@protocol XCElementSpacerP <XCElementP>  @end
+
+@protocol PWhatever @end
+
+@interface XX
+
+- (void)setFlexElement:(NSObject <PWhatever, XCElementP> *)flexer;
+- (void)setFlexElement2:(NSObject <PWhatever, XCElementSpacerP> *)flexer; // expected-note{{passing argument to parameter 'flexer' here}}
+
+@end
+
+void func() {
+  NSObject <PWhatever, XCElementSpacerP> * flexer;
+  NSObject <PWhatever, XCElementP> * flexer2;
+  XX *obj;
+  [obj setFlexElement:flexer];
+  // FIXME: GCC provides the following diagnostic (which is much better):
+  // protocol-typecheck.m:21: warning: class 'NSObject <PWhatever, XCElementP>' does not implement the 'XCElementSpacerP' protocol
+  [obj setFlexElement2:flexer2]; // expected-warning{{incompatible pointer types sending 'NSObject<PWhatever,XCElementP> *' to parameter of type 'NSObject<PWhatever,XCElementSpacerP> *'}}
+}
+
diff --git a/test/SemaObjC/protocol-warn.m b/test/SemaObjC/protocol-warn.m
new file mode 100644
index 0000000..2d04238
--- /dev/null
+++ b/test/SemaObjC/protocol-warn.m
@@ -0,0 +1,55 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// radar 7638810
+
+@protocol NSObject @end
+
+@interface NSObject <NSObject> @end
+
+@interface UIResponder : NSObject
+@end
+
+@implementation UIResponder
+@end
+
+@interface UIView : UIResponder
+@end
+
+@implementation UIView
+@end
+
+@interface UIWebTiledView : UIView
+@end
+
+@implementation UIWebTiledView
+@end
+
+@interface UIWebDocumentView : UIWebTiledView
+@end
+
+@implementation UIWebDocumentView
+@end
+
+@interface UIWebBrowserView : UIWebDocumentView
+@end
+
+@implementation UIWebBrowserView
+@end
+
+@interface UIPDFView : UIView
+@end
+
+@implementation UIPDFView
+@end
+
+@interface UIWebPDFView : UIPDFView
+@end
+
+@implementation UIWebPDFView
+@end
+
+UIWebPDFView *getView()
+{
+    UIWebBrowserView *browserView;
+    UIWebPDFView *pdfView;
+    return pdfView ? pdfView : browserView; // expected-warning {{incompatible pointer types returning 'UIView<NSObject> *' from a function with result type 'UIWebPDFView *'}}
+}
diff --git a/test/SemaObjC/protocols.m b/test/SemaObjC/protocols.m
new file mode 100644
index 0000000..8447fe2
--- /dev/null
+++ b/test/SemaObjC/protocols.m
@@ -0,0 +1,63 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@interface INTF1
+@required  // expected-error {{directive may only be specified in protocols only}}
+- (int) FooBar;
+- (int) FooBar1;
+- (int) FooBar2;
+@optional  // expected-error {{directive may only be specified in protocols only}}
++ (int) C;
+
+- (int)I;
+@end
+
+@protocol p1,p2,p3;
+
+@protocol p1;
+
+@protocol PROTO1
+@required 
+- (int) FooBar;
+@optional
+- (void) MyMethod1;
++ (int) S;
+@end
+
+
+@protocol PROTO2<p1>
+@end
+
+@protocol p1 @end
+
+@protocol PROTO<p1>     // expected-note {{previous definition is here}}
+@end
+
+@protocol PROTO<p1>	// expected-warning {{duplicate protocol definition of 'PROTO'}}
+@end
+
+@protocol PROTO3<p1, p1>
+@end
+
+@protocol p2 <p1>
+@end
+
+@protocol PROTO4 <p1, p2, PROTO, PROTO3, p3> 
+@end
+
+
+// rdar://6771034
+@protocol XX;
+@protocol YY <XX>  // Use of declaration of XX here should not cause a warning.
+- zz;
+@end
+
+
+// Detect circular dependencies.
+@protocol B;
+@protocol C < B > // expected-note{{previous definition is here}}
+@end
+@protocol A < C > 
+@end
+@protocol B < A > // expected-error{{protocol has circular dependency}}
+@end
+
diff --git a/test/SemaObjC/rdr-6211479-array-property.m b/test/SemaObjC/rdr-6211479-array-property.m
new file mode 100644
index 0000000..39c056c
--- /dev/null
+++ b/test/SemaObjC/rdr-6211479-array-property.m
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// <rdar://problem/6211479>
+
+typedef int T[2];
+
+@interface A
+@property(assign) T p2; // expected-error {{property cannot have array or function type 'T' (aka 'int [2]')}}
+@end
diff --git a/test/SemaObjC/restrict-id-type.m b/test/SemaObjC/restrict-id-type.m
new file mode 100644
index 0000000..b24fcb0
--- /dev/null
+++ b/test/SemaObjC/restrict-id-type.m
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1  -std=gnu99 -fsyntax-only -verify %s
+
+void f0(restrict id a0) {}
+
+void f1(restrict id *a0) {}
+
+void f2(restrict Class a0) {}
+
+void f3(restrict Class *a0) {}
diff --git a/test/SemaObjC/return.m b/test/SemaObjC/return.m
new file mode 100644
index 0000000..c578bf3
--- /dev/null
+++ b/test/SemaObjC/return.m
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify -Wmissing-noreturn
+
+int test1() {
+  id a;
+  @throw a;
+}
+
+// PR5286
+void test2(int a) {
+  while (1) {
+    if (a)
+      return;
+  }
+}
+
+// PR5286
+void test3(int a) {  // expected-warning {{function could be attribute 'noreturn'}}
+  while (1) {
+    if (a)
+      @throw (id)0;
+  }
+}
diff --git a/test/SemaObjC/scope-check.m b/test/SemaObjC/scope-check.m
new file mode 100644
index 0000000..bba321e
--- /dev/null
+++ b/test/SemaObjC/scope-check.m
@@ -0,0 +1,103 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@class A, B, C;
+
+void test1() {
+  goto L; // expected-error{{illegal goto into protected scope}}
+  goto L2; // expected-error{{illegal goto into protected scope}}
+  goto L3; // expected-error{{illegal goto into protected scope}}
+  @try {   // expected-note {{jump bypasses initialization of @try block}}
+L: ;
+  } @catch (A *x) { // expected-note {{jump bypasses initialization of @catch block}}
+L2: ;
+  } @catch (B *x) {
+  } @catch (C *c) {
+  } @finally {// expected-note {{jump bypasses initialization of @finally block}}
+L3: ;
+  }
+  
+  @try {
+    goto L4; // expected-error{{illegal goto into protected scope}}
+    goto L5; // expected-error{{illegal goto into protected scope}}
+  } @catch (C *c) { // expected-note {{jump bypasses initialization of @catch block}}
+  L5: ;
+    goto L6; // expected-error{{illegal goto into protected scope}}
+  } @catch (B *c) { // expected-note {{jump bypasses initialization of @catch block}}
+  L6: ;
+  } @finally { // expected-note {{jump bypasses initialization of @finally block}}
+  L4: ;
+  }
+ 
+  
+  @try { // expected-note 2 {{jump bypasses initialization of @try block}}
+  L7: ;
+  } @catch (C *c) {
+    goto L7; // expected-error{{illegal goto into protected scope}}
+  } @finally {
+    goto L7; // expected-error{{illegal goto into protected scope}}
+  }
+  
+  goto L8;  // expected-error{{illegal goto into protected scope}}
+  @try { 
+  } @catch (A *c) {
+  } @catch (B *c) {
+  } @catch (C *c) { // expected-note {{jump bypasses initialization of @catch block}}
+  L8: ;
+  }
+  
+  // rdar://6810106
+  id X;
+  goto L9;    // expected-error{{illegal goto into protected scope}}
+  goto L10;   // ok
+  @synchronized    // expected-note {{jump bypasses initialization of @synchronized block}}
+  ( ({ L10: ; X; })) {
+  L9:
+    ;
+  }
+}
+
+void test2(int a) {
+  if (a) goto L0;
+  @try {} @finally {}
+ L0:
+  return;
+}
+
+// rdar://6803963
+void test3() {
+  @try {
+    goto blargh;
+  blargh: ;
+  } @catch (...) {}
+}
+
+@interface Greeter
++ (void) hello;
+@end
+
+@implementation Greeter
++ (void) hello {
+
+  @try {
+    goto blargh;     // expected-error {{illegal goto into protected scope}}
+  } @catch (...) {   // expected-note {{jump bypasses initialization of @catch block}}
+  blargh: ;
+  }
+}
+
++ (void)meth2 {
+    int n; void *P;
+    goto L0;     // expected-error {{illegal goto into protected scope}}
+    typedef int A[n];  // expected-note {{jump bypasses initialization of VLA typedef}}
+  L0:
+    
+    goto L1;      // expected-error {{illegal goto into protected scope}}
+    A b, c[10];        // expected-note 2 {{jump bypasses initialization of variable length array}}
+  L1:
+    goto L2;     // expected-error {{illegal goto into protected scope}}
+    A d[n];      // expected-note {{jump bypasses initialization of variable length array}}
+  L2:
+    return;
+}
+
+@end
diff --git a/test/SemaObjC/selector-1.m b/test/SemaObjC/selector-1.m
new file mode 100644
index 0000000..9a7375b
--- /dev/null
+++ b/test/SemaObjC/selector-1.m
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -verify %s 
+
+@interface Lancelot @end
+@implementation Lancelot
+
+- (void):(int)x {}
+- (void)xx:(int)x :(int)y { }
+
+@end
+
+@interface I
+- (id) compare: (char) arg1;
+@end
+
+@interface J
+- (id) compare: (id) arg1;
+@end
+
+SEL foo()
+{
+	return @selector(compare:);	// Non warning on multiple selector found.
+}
+
+int main() {
+ SEL s = @selector(retain);
+ SEL s1 = @selector(meth1:);
+ SEL s2 = @selector(retainArgument::);
+ SEL s3 = @selector(retainArgument:::::);
+ SEL s4 = @selector(retainArgument:with:);
+ SEL s5 = @selector(meth1:with:with:);
+ SEL s6 = @selector(getEnum:enum:bool:);
+ SEL s7 = @selector(char:float:double:unsigned:short:long:);
+
+ SEL s9 = @selector(:enum:bool:);
+}
diff --git a/test/SemaObjC/selector-error.m b/test/SemaObjC/selector-error.m
new file mode 100644
index 0000000..dfd6bd0
--- /dev/null
+++ b/test/SemaObjC/selector-error.m
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1  -fsyntax-only -verify %s
+
+@interface Foo
+- (char*) foo;
+- (void) bar;
+@end
+
+@implementation Foo
+- (void) bar
+{
+}
+
+- (char*) foo
+{
+  char* a,b,c;
+  a = (char*)@selector(bar);  // expected-error {{cannot type cast @selector expression}}
+  return (char*)@selector(bar);  // expected-error {{cannot type cast @selector expression}}
+}
+@end
+
diff --git a/test/SemaObjC/selector-overload.m b/test/SemaObjC/selector-overload.m
new file mode 100644
index 0000000..53ba6f7
--- /dev/null
+++ b/test/SemaObjC/selector-overload.m
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 %s -fsyntax-only
+
+@interface NSObject
++ alloc;
+- init;
+@end
+
+struct D {
+  double d;
+};
+
+@interface Foo : NSObject 
+
+- method:(int)a;
+- method:(int)a;
+
+@end
+
+@interface Bar : NSObject 
+
+- method:(void *)a;
+
+@end
+
+@interface Car : NSObject 
+
+- method:(struct D)a;
+
+@end
+
+@interface Zar : NSObject 
+
+- method:(float)a;
+
+@end
+
+@interface Rar : NSObject 
+
+- method:(float)a;
+
+@end
+
+int main() {
+  id xx = [[Car alloc] init]; // expected-warning {{incompatible types assigning 'int' to 'id'}}
+
+  [xx method:4];
+}
diff --git a/test/SemaObjC/sizeof-interface.m b/test/SemaObjC/sizeof-interface.m
new file mode 100644
index 0000000..9d85f1f
--- /dev/null
+++ b/test/SemaObjC/sizeof-interface.m
@@ -0,0 +1,90 @@
+// RUN: %clang_cc1 -fobjc-nonfragile-abi -verify -fsyntax-only %s
+
+@class I0;
+
+// rdar://6811884
+int g0 = sizeof(I0); // expected-error{{invalid application of 'sizeof' to an incomplete type 'I0'}}
+
+// rdar://6821047
+void *g3(I0 *P) {
+  P = P+5;        // expected-error {{arithmetic on pointer to incomplete type 'I0 *'}}
+
+  return &P[4];   // expected-error{{subscript of pointer to incomplete type 'I0'}}
+}
+
+
+
+@interface I0 {
+@public
+  char x[4];
+}
+
+@property int p0;
+@end
+
+// size == 4
+int g1[ sizeof(I0)     // expected-error {{invalid application of 'sizeof' to interface 'I0' in non-fragile ABI}}
+       == 4 ? 1 : -1];
+
+@implementation I0
+@synthesize p0 = _p0;
+@end
+
+// size == 4 (we do not include extended properties in the
+// sizeof).
+int g2[ sizeof(I0)   // expected-error {{invalid application of 'sizeof' to interface 'I0' in non-fragile ABI}}
+       == 4 ? 1 : -1];
+
+@interface I1
+@property int p0;
+@end
+
+@implementation I1
+@synthesize p0 = _p0;
+@end
+
+typedef struct { @defs(I1) } I1_defs; // expected-error {{invalid application of @defs in non-fragile ABI}}
+
+// FIXME: This is currently broken due to the way the record layout we
+// create is tied to whether we have seen synthesized properties. Ugh.
+// int g3[ sizeof(I1) == 0 ? 1 : -1];
+
+// rdar://6821047
+int bar(I0 *P) {
+  P = P+5;  // expected-error {{arithmetic on pointer to interface 'I0', which is not a constant size in non-fragile ABI}}
+  P = 5+P;  // expected-error {{arithmetic on pointer to interface 'I0', which is not a constant size in non-fragile ABI}}
+  P = P-5;  // expected-error {{arithmetic on pointer to interface 'I0', which is not a constant size in non-fragile ABI}}
+  
+  return P[4].x[2];  // expected-error {{subscript requires size of interface 'I0', which is not constant in non-fragile ABI}}
+}
+
+
+@interface I @end
+
+@interface XCAttributeRunDirectNode
+{
+    @public
+    unsigned long attributeRuns[1024 + sizeof(I)]; // expected-error {{invalid application of 'sizeof' to interface 'I' in non-fragile ABI}}
+    int i;
+}
+@end
+
+@implementation XCAttributeRunDirectNode
+
+- (unsigned long)gatherStats:(id )stats
+{
+        return attributeRuns[i];
+}
+@end
+
+
+@interface Foo @end
+
+int foo()
+{
+  Foo *f;
+  
+  // Both of these crash clang nicely
+  ++f; 	// expected-error {{arithmetic on pointer to interface 'Foo', which is not a constant size in non-fragile ABI}}
+  --f; 	// expected-error {{arithmetic on pointer to interface 'Foo', which is not a constant size in non-fragile ABI}}
+}
diff --git a/test/SemaObjC/stand-alone-implementation.m b/test/SemaObjC/stand-alone-implementation.m
new file mode 100644
index 0000000..c33b66a
--- /dev/null
+++ b/test/SemaObjC/stand-alone-implementation.m
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// radar 7547942
+// Allow injection of ivars into implementation's implicit class.
+
+@implementation INTFSTANDALONE // expected-warning {{cannot find interface declaration for 'INTFSTANDALONE'}}
+{
+  id IVAR1;
+  id IVAR2;
+}
+- (id) Meth { return IVAR1; }
+@end
+
diff --git a/test/SemaObjC/static-ivar-ref-1.m b/test/SemaObjC/static-ivar-ref-1.m
new file mode 100644
index 0000000..cd5e055
--- /dev/null
+++ b/test/SemaObjC/static-ivar-ref-1.m
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown -ast-print %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10  -ast-print %s
+
+@interface current 
+{
+@public
+  int ivar;
+  int ivar1;
+  int ivar2;
+}
+@end
+
+current *pc;
+
+int foo()
+{
+	return pc->ivar2 + (*pc).ivar + pc->ivar1;
+}
diff --git a/test/SemaObjC/stmts.m b/test/SemaObjC/stmts.m
new file mode 100644
index 0000000..d1e2ad3
--- /dev/null
+++ b/test/SemaObjC/stmts.m
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only
+
+struct some_struct;
+
+@interface NSObject
+@end
+
+// Note: NSException is not declared.
+void f0(id x) {
+  @try {
+  } @catch (NSException *x) { // expected-error {{unknown type name 'NSException'}}
+  } @catch (struct some_struct x) { // expected-error {{@catch parameter is not a pointer to an interface type}}
+  } @catch (int x) { // expected-error {{@catch parameter is not a pointer to an interface type}}
+  } @catch (static NSObject *y) { // expected-error {{@catch parameter cannot have storage specifier 'static'}}
+  } @catch (...) {
+  }
+}
+
diff --git a/test/SemaObjC/string.m b/test/SemaObjC/string.m
new file mode 100644
index 0000000..04f20ab
--- /dev/null
+++ b/test/SemaObjC/string.m
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only
+// RUN: %clang_cc1 %s -verify -fsyntax-only -DDECLAREIT
+
+// a declaration of NSConstantString is not required.
+#ifdef DECLAREIT
+@interface NSConstantString;
+@end
+#endif
+
+
+
+id s = @"123"; // simple
+id t = @"123" @"456"; // concat
+id u = @"123" @ blah; // expected-error {{unexpected token}}
+
diff --git a/test/SemaObjC/super-cat-prot.m b/test/SemaObjC/super-cat-prot.m
new file mode 100644
index 0000000..3e28986
--- /dev/null
+++ b/test/SemaObjC/super-cat-prot.m
@@ -0,0 +1,50 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+typedef signed char BOOL;
+typedef unsigned int NSUInteger;
+@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+@protocol NSObject  - (BOOL)isEqual:(id)object; @end
+@protocol NSCoding  - (void)encodeWithCoder:(NSCoder *)aCoder; @end
+@interface NSObject <NSObject> {} @end
+typedef float CGFloat;
+typedef struct _NSSize {} NSSize;
+typedef struct _NSRect {} NSRect;
+@interface NSResponder : NSObject <NSCoding> {} @end
+@protocol NSAnimatablePropertyContainer - (id)animator; @end
+extern NSString *NSAnimationTriggerOrderIn ;
+@interface NSView : NSResponder  <NSAnimatablePropertyContainer>  {} @end
+@class NSAttributedString, NSEvent, NSFont, NSFormatter, NSImage, NSMenu, NSText, NSView;
+enum { NSBoxPrimary = 0, NSBoxSecondary = 1, NSBoxSeparator = 2, NSBoxOldStyle = 3, NSBoxCustom = 4};
+typedef NSUInteger NSBoxType;
+@interface NSBox : NSView {} - (NSBoxType)boxType; @end
+@class NSArray, NSError, NSImage, NSView, NSNotificationCenter, NSURL;
+@interface NSProBox:NSBox {} @end
+enum IBKnobPosition { IBNoKnobPosition = -1, IBBottomLeftKnobPosition = 0, 
+                      IBMiddleLeftKnobPosition, IBTopLeftKnobPosition,
+                      IBTopMiddleKnobPosition, IBTopRightKnobPosition,
+                      IBMiddleRightKnobPosition, IBBottomRightKnobPosition, 
+                      IBBottomMiddleKnobPosition };
+typedef enum IBKnobPosition IBKnobPosition;
+typedef struct _IBInset {} IBInset;
+@protocol IBObjectProtocol -(NSString *)inspectorClassName; @end
+@protocol IBViewProtocol
+  -(NSSize)minimumFrameSizeFromKnobPosition:(IBKnobPosition)position;
+  -(IBInset)ibShadowInset;
+@end
+@class NSPasteboard;
+@interface NSObject (NSObject_IBObjectProtocol) <IBObjectProtocol> @end
+@interface NSView (NSView_IBViewProtocol) <IBViewProtocol>  - (NSRect)layoutRect; @end
+typedef enum { NSProTextFieldSquareBezel = 0, NSProTextFieldRoundedBezel = 1, NSProTextFieldDisplayBezel = 2 } MKModuleReusePolicy;
+@implementation NSProBox(IBAdditions)
+-(NSString *)inspectorClassName { return 0; }
+-(IBInset)ibShadowInset {
+  if ([self boxType] == NSBoxSeparator) {
+    return [super ibShadowInset];
+  }
+  while (1) {}
+}
+-(NSSize)minimumFrameSizeFromKnobPosition:(IBKnobPosition)knobPosition {
+  if ([self boxType] != NSBoxSeparator)
+    return [super minimumFrameSizeFromKnobPosition:knobPosition];
+  while (1) {}
+}
+@end
diff --git a/test/SemaObjC/super-property-message-expr.m b/test/SemaObjC/super-property-message-expr.m
new file mode 100644
index 0000000..c25164e
--- /dev/null
+++ b/test/SemaObjC/super-property-message-expr.m
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1  -fsyntax-only -verify %s
+
+@interface SStoreNodeInfo 
+
+@property(nonatomic,readonly,retain) id descriptionShort;
+
+- (id)stringByAppendingFormat:(int)format, ... ;
+
+@end
+
+@interface SStoreNodeInfo_iDisk : SStoreNodeInfo
+{
+@private
+ id _etag;
+}
+@end
+
+@implementation SStoreNodeInfo_iDisk
+- (id) X { return [super.descriptionShort stringByAppendingFormat:1, _etag]; }
+
+@end
diff --git a/test/SemaObjC/super-property-notation.m b/test/SemaObjC/super-property-notation.m
new file mode 100644
index 0000000..7d3f7c7
--- /dev/null
+++ b/test/SemaObjC/super-property-notation.m
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@interface B
++(int) classGetter;
+-(int) getter;
+@end
+
+@interface A : B
+@end
+
+@implementation A
++(int) classGetter {
+  return 0;
+}
+
++(int) classGetter2 {
+  return super.classGetter;
+}
+
+-(void) method {
+  int x = super.getter;
+}
+@end
+
+void f0() {
+  // FIXME: not implemented yet.
+  //int l1 = A.classGetter;
+  int l2 = [A classGetter2];
+}
+
diff --git a/test/SemaObjC/super.m b/test/SemaObjC/super.m
new file mode 100644
index 0000000..31d8db1
--- /dev/null
+++ b/test/SemaObjC/super.m
@@ -0,0 +1,87 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -fblocks %s
+
+void takevoidptr(void*);
+
+
+@interface Foo
+- iMethod;
++ cMethod;
+@end
+
+@interface A
++ superClassMethod;
+- (void)instanceMethod;
+@end
+
+@interface B : A
+- (void)instanceMethod;
++ classMethod;
+@end
+
+@implementation B
+
+- (void)instanceMethod {
+  [super iMethod]; // expected-warning{{'A' may not respond to 'iMethod')}}
+  
+  // Use of super in a block is ok and does codegen to the right thing.
+  // rdar://7852959
+  takevoidptr(^{
+    [super instanceMethod];
+  });
+}
+
++ classMethod {
+  [super cMethod]; // expected-warning{{method '+cMethod' not found (return type defaults to 'id')}}
+  
+  id X[] = { [ super superClassMethod] };
+  id Y[] = {
+    [ super.superClassMethod iMethod],
+    super.superClassMethod,
+    (id)super.superClassMethod  // not a cast of super: rdar://7853261
+  };
+  return 0;
+}
+@end
+
+@interface XX
+- m;
+@end
+
+void f(id super) {
+  [super m];
+}
+void f0(int super) {
+  [super m]; // expected-warning{{receiver type 'int' is not 'id'}} \
+                expected-warning {{method '-m' not found (return type defaults to 'id')}}
+}
+void f1(id puper) {  // expected-note {{'puper' declared here}}
+  [super m]; // expected-error{{use of undeclared identifier 'super'; did you mean 'puper'?}}
+}
+
+// radar 7400691
+typedef Foo super;
+
+typedef Foo FooTD;
+
+void test() {
+  [FooTD cMethod];
+  [super cMethod];
+}
+
+struct SomeStruct {
+  int X;
+};
+
+int test2() {
+  struct SomeStruct super = { 0 };
+  return super.X;
+}
+
+int test3() {
+  id super = 0;
+  [(B*)super instanceMethod];
+  int *s1 = (int*)super;
+  
+  id X[] = { [ super superClassMethod] };
+  return 0;
+}
diff --git a/test/SemaObjC/synchronized.m b/test/SemaObjC/synchronized.m
new file mode 100644
index 0000000..dac620a
--- /dev/null
+++ b/test/SemaObjC/synchronized.m
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@interface PBXTrackableTaskManager @end
+
+@implementation PBXTrackableTaskManager
+- (id) init { return 0; }
+- (void) unregisterTask:(id) task {
+  @synchronized (self) {
+  id taskID = [task taskIdentifier];  // expected-warning {{method '-taskIdentifier' not found (return type defaults to 'id')}}
+  }
+}
+@end
+
+
+struct x { int a; } b;
+
+void test1() {
+  @synchronized (b) {  // expected-error {{@synchronized requires an Objective-C object type ('struct x' invalid)}}
+  }
+
+  @synchronized (42) {  // expected-error {{@synchronized requires an Objective-C object type ('int' invalid)}}
+  }
+}
diff --git a/test/SemaObjC/synthesize-setter-contclass.m b/test/SemaObjC/synthesize-setter-contclass.m
new file mode 100644
index 0000000..36967d4
--- /dev/null
+++ b/test/SemaObjC/synthesize-setter-contclass.m
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1  -fsyntax-only -verify %s
+
+@interface TestClass 
+{
+ int _isItIsOrIsItAint;
+}
+@property (readonly) int itIsOrItAint;
+-(void) doSomething;
+@end
+
+@interface TestClass()
+@property (readwrite) int itIsOrItAint;
+@end
+
+@implementation TestClass
+@synthesize itIsOrItAint = _isItIsOrIsItAint;
+
+-(void) doSomething
+{
+  int i = [self itIsOrItAint];
+
+ [self setItIsOrItAint:(int)1];
+}
+@end
diff --git a/test/SemaObjC/synthesized-ivar.m b/test/SemaObjC/synthesized-ivar.m
new file mode 100644
index 0000000..58bcf40
--- /dev/null
+++ b/test/SemaObjC/synthesized-ivar.m
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -fsyntax-only -fobjc-nonfragile-abi -verify %s
+@interface I
+{
+}
+@property int IP;
+@end
+
+@implementation I
+@synthesize IP;
+- (int) Meth {
+   return IP;
+}
+@end
+
+// rdar: // 7823675
+int f0(I *a) { return a->IP; } // expected-error {{instance variable 'IP' is protected}}
diff --git a/test/SemaObjC/transparent-union.m b/test/SemaObjC/transparent-union.m
new file mode 100644
index 0000000..cb03dfe
--- /dev/null
+++ b/test/SemaObjC/transparent-union.m
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1  -fsyntax-only -verify %s
+
+typedef union {
+ struct xx_object_s *_do;
+ struct xx_continuation_s *_dc;
+ struct xx_queue_s *_dq;
+ struct xx_queue_attr_s *_dqa;
+ struct xx_group_s *_dg;
+ struct xx_source_s *_ds;
+ struct xx_source_attr_s *_dsa;
+ struct xx_semaphore_s *_dsema;
+} xx_object_t __attribute__((transparent_union));
+
+@interface INTF
+- (void) doSomething : (xx_object_t) xxObject;
+- (void)testMeth;
+@end
+
+@implementation INTF
+- (void) doSomething : (xx_object_t) xxObject {}
+- (void)testMeth { struct xx_queue_s *sq; [self doSomething:sq ]; }
+@end
diff --git a/test/SemaObjC/try-catch.m b/test/SemaObjC/try-catch.m
new file mode 100644
index 0000000..01fc4f4
--- /dev/null
+++ b/test/SemaObjC/try-catch.m
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+typedef signed char BOOL;
+typedef struct _NSZone NSZone;
+
+@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+
+@protocol NSObject
+- (BOOL)isEqual:(id)object;
+@end
+
+@protocol NSCopying
+- (id)copyWithZone:(NSZone *)zone;
+@end
+
+@protocol NSCoding
+- (void)encodeWithCoder:(NSCoder *)aCoder;
+@end
+
+@interface NSObject <NSObject> {}
+@end
+
+@class NSData, NSArray, NSDictionary, NSCharacterSet, NSData, NSURL, NSError, NSLocale;
+
+@interface NSException : NSObject <NSCopying, NSCoding> {}
+@end
+
+@class ASTNode, XCRefactoringParser, Transform, TransformInstance, XCRefactoringSelectionInfo;
+
+@interface XCRefactoringTransformation : NSObject {}
+@end
+
+@implementation XCRefactoringTransformation
+- (NSDictionary *)setUpInfoForTransformKey:(NSString *)transformKey outError:(NSError **)outError {
+    @try {}
+    // the exception name is optional (weird)
+    @catch (NSException *) {}
+}
+@end
+
+int foo() {
+  struct s { int a, b; } agg, *pagg;
+
+  @throw 42; // expected-error {{@throw requires an Objective-C object type ('int' invalid))}}
+  @throw agg; // expected-error {{@throw requires an Objective-C object type ('struct s' invalid)}}
+  @throw pagg; // expected-error {{@throw requires an Objective-C object type ('struct s *' invalid)}}
+  @throw; // expected-error {{@throw (rethrow) used outside of a @catch block}}
+}
diff --git a/test/SemaObjC/typedef-class.m b/test/SemaObjC/typedef-class.m
new file mode 100644
index 0000000..0f7e682
--- /dev/null
+++ b/test/SemaObjC/typedef-class.m
@@ -0,0 +1,78 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+typedef signed char BOOL;
+typedef unsigned int NSUInteger;
+typedef struct _NSZone NSZone;
+
+@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+
+@protocol NSObject - (BOOL) isEqual:(id) object; @end
+@protocol NSCopying - (id) copyWithZone:(NSZone *) zone; @end
+@protocol NSCoding - (void) encodeWithCoder:(NSCoder *) aCoder; @end
+
+@interface NSObject < NSObject > {}
++(id) alloc;
+@end
+
+typedef float CGFloat;
+
+@interface NSTask:NSObject
+- (id) init;
+@end
+
+typedef NSUInteger NSControlSize;
+typedef struct __CFlags {} _CFlags;
+
+@interface NSCell:NSObject < NSCopying, NSCoding > {}
+@end
+
+@interface NSActionCell:NSCell {} @end
+
+@class NSAttributedString, NSFont, NSImage, NSSound;
+
+typedef struct _XCElementInset {} XCElementInset;
+
+@protocol XCElementP < NSObject >
+-(BOOL) vertical;
+@end
+
+@protocol XCElementDisplayDelegateP;
+@protocol XCElementDisplayDelegateP < NSObject >
+-(void) configureForControlSize:(NSControlSize)size font:(NSFont *)font addDefaultSpace:(XCElementInset) additionalSpace;
+@end
+
+@protocol XCElementSpacerP < XCElementP >
+@end
+
+typedef NSObject < XCElementSpacerP > XCElementSpacer;
+
+@protocol XCElementTogglerP < XCElementP > -(void) setDisplayed:(BOOL) displayed;
+@end
+
+typedef NSObject < XCElementTogglerP > XCElementToggler;
+
+@interface XCElementRootFace:NSObject {} @end
+
+@interface XCElementFace:XCElementRootFace {} @end
+
+@class XCElementToggler; 
+
+@interface XCRASlice:XCElementFace {} @end
+
+@class XCElementSpacings;
+
+@interface XCElementDisplay:NSObject < XCElementDisplayDelegateP > {} @end
+@interface XCElementDisplayRect:XCElementDisplay {} @end
+
+typedef XCElementDisplayRect XCElementGraphicsRect;
+
+@interface XCElementDisplayFillerImage:XCElementDisplay {} @end
+
+@implementation XCRASlice
+- (void) addSliceWithLabel:(NSString *)label statusKey:(NSString *)statusKey disclosed:(BOOL)disclosed
+{
+  static XCElementGraphicsRect *_sGraphicsDelegate = ((void *) 0);
+  if (!_sGraphicsDelegate) {
+    _sGraphicsDelegate =[[XCElementGraphicsRect alloc] init]; 
+  }
+}
+@end
diff --git a/test/SemaObjC/ucn-objc-string.m b/test/SemaObjC/ucn-objc-string.m
new file mode 100644
index 0000000..6070278
--- /dev/null
+++ b/test/SemaObjC/ucn-objc-string.m
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only
+@class NSString;
+extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, 2)));
+
+int main() {
+  NSLog(@"Hi…");
+  NSLog(@"Exposé");
+  NSLog(@"\U00010400\U0001D12B");
+  NSLog(@"hello \u2192 \u2603 \u2190 world");
+  NSLog(@"hello → ☃ ← world");
+  return 0;
+}
+
diff --git a/test/SemaObjC/undeclared-selector.m b/test/SemaObjC/undeclared-selector.m
new file mode 100644
index 0000000..758e1d7
--- /dev/null
+++ b/test/SemaObjC/undeclared-selector.m
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1  -fsyntax-only -Wundeclared-selector -verify %s
+
+typedef struct objc_selector *SEL;
+
+@interface MyClass
+
++ (void) methodA;
+- (void) methodB;
++ (void) methodD;
+- (void) methodF;
+
+@end
+
+@implementation MyClass
+
++ (void) methodA {}
+- (void) methodB {}
++ (void) methodD
+{
+  SEL d = @selector(methodD); /* Ok */
+  SEL e = @selector(methodE);  // expected-warning {{undeclared selector 'methodE'}}
+}
+
+- (void) methodE
+{
+  SEL e = @selector(methodE); /* Ok */
+}
+
+- (void) methodF
+{
+  SEL e = @selector(methodE); /* Ok */
+}
+
+@end
+
+int main (void)
+{
+  SEL a = @selector(methodA); /* Ok */
+  SEL b = @selector(methodB); /* Ok */
+  SEL c = @selector(methodC);  // expected-warning {{undeclared selector 'methodC'}}
+  SEL d = @selector(methodD); /* Ok */
+  SEL e = @selector(methodE); /* Ok */
+  return 0;
+  
+}
diff --git a/test/SemaObjC/undef-class-messagin-error.m b/test/SemaObjC/undef-class-messagin-error.m
new file mode 100644
index 0000000..63e0b9d
--- /dev/null
+++ b/test/SemaObjC/undef-class-messagin-error.m
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@interface _Child // expected-note{{'_Child' declared here}}
++ (int) flashCache;
+@end
+
+@interface Child (Categ) // expected-error {{cannot find interface declaration for 'Child'; did you mean '_Child'?}}
++ (int) flushCache2;
+@end
+
+@implementation OtherChild (Categ) // expected-error {{cannot find interface declaration for 'OtherChild'}}
++ (int) flushCache2 { [super flashCache]; } // expected-error {{no @interface declaration found in class messaging of 'flushCache2'}}
+@end
diff --git a/test/SemaObjC/undef-protocol-methods-1.m b/test/SemaObjC/undef-protocol-methods-1.m
new file mode 100644
index 0000000..cbef3e5
--- /dev/null
+++ b/test/SemaObjC/undef-protocol-methods-1.m
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@protocol P1
+- (void) P1proto; // expected-warning {{method in protocol not implemented [-Wprotocol]}}
++ (void) ClsP1Proto;   // expected-warning {{method in protocol not implemented [-Wprotocol]}}
+- (void) DefP1proto;
+@end
+@protocol P2
+- (void) P2proto;   // expected-warning {{method in protocol not implemented [-Wprotocol]}}
++ (void) ClsP2Proto;  // expected-warning {{method in protocol not implemented [-Wprotocol]}}
+@end
+
+@protocol P3<P2>
+- (void) P3proto;  // expected-warning {{method in protocol not implemented [-Wprotocol]}}
++ (void) ClsP3Proto;  // expected-warning {{method in protocol not implemented [-Wprotocol]}}
++ (void) DefClsP3Proto;
+@end
+
+@protocol PROTO<P1, P3>
+- (void) meth;		 // expected-warning {{method in protocol not implemented [-Wprotocol]}}
+- (void) meth : (int) arg1;  // expected-warning {{method in protocol not implemented [-Wprotocol]}}
++ (void) cls_meth : (int) arg1;  // expected-warning {{method in protocol not implemented [-Wprotocol]}}
+@end
+
+@interface INTF <PROTO> // expected-note 3 {{required for direct or indirect protocol 'PROTO'}} \
+			// expected-note 2 {{required for direct or indirect protocol 'P1'}} \
+			// expected-note 2 {{required for direct or indirect protocol 'P3'}} \
+			// expected-note 2 {{required for direct or indirect protocol 'P2'}}
+@end
+
+@implementation INTF   // expected-warning {{incomplete implementation}} 
+- (void) DefP1proto{}
+
++ (void) DefClsP3Proto{}
+
+@end
diff --git a/test/SemaObjC/undef-superclass-1.m b/test/SemaObjC/undef-superclass-1.m
new file mode 100644
index 0000000..0c2594c
--- /dev/null
+++ b/test/SemaObjC/undef-superclass-1.m
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@class SUPER, Y;
+
+@interface INTF :SUPER  // expected-error {{cannot find interface declaration for 'SUPER', superclass of 'INTF'}}
+@end
+
+@interface SUPER @end
+
+@interface INTF1 : SUPER  // expected-note {{previous definition is here}}
+@end
+
+@interface INTF2 : INTF1
+@end
+
+@interface INTF3 : Y // expected-error {{cannot find interface declaration for 'Y', superclass of 'INTF3'}} \
+                     // expected-note{{'INTF3' declared here}}
+@end
+
+@interface INTF1  // expected-error {{duplicate interface definition for class 'INTF1'}}
+@end
+
+@implementation SUPER
+- (void)dealloc {
+    [super dealloc]; // expected-error {{no super class declared in @interface for 'SUPER'}}
+}
+@end
+
+@interface RecursiveClass : RecursiveClass // expected-error {{trying to recursively use 'RecursiveClass' as superclass of 'RecursiveClass'}}
+@end
+
+@implementation RecursiveClass
+@end
+
+@implementation iNTF3 // expected-warning{{cannot find interface declaration for 'iNTF3'; did you mean 'INTF3'?}}
+@end
diff --git a/test/SemaObjC/undefined-protocol-type-1.m b/test/SemaObjC/undefined-protocol-type-1.m
new file mode 100644
index 0000000..3be4425
--- /dev/null
+++ b/test/SemaObjC/undefined-protocol-type-1.m
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@protocol p1, p4;
+@protocol p2 @end
+
+@interface T
+- (T<p2, p3, p1, p4>*) meth;  // expected-error {{cannot find protocol declaration for 'p3'}}
+- (T<p2, p3, p1, p4>*) meth;  // expected-error {{cannot find protocol declaration for 'p3'}}
+@end
diff --git a/test/SemaObjC/unimplemented-protocol-prop.m b/test/SemaObjC/unimplemented-protocol-prop.m
new file mode 100644
index 0000000..d3de50e
--- /dev/null
+++ b/test/SemaObjC/unimplemented-protocol-prop.m
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1  -fsyntax-only -verify %s
+
+@protocol PROTOCOL0
+@required
+@property float MyProperty0; // expected-warning {{property 'MyProperty0' requires method 'MyProperty0' to be defined }} \
+			     // expected-warning {{property 'MyProperty0' requires method 'setMyProperty0:' to be defined}}
+@end
+
+@protocol PROTOCOL<PROTOCOL0>
+@required
+@property float MyProperty; // expected-warning {{property 'MyProperty' requires method 'MyProperty' to be defined}} \
+			// expected-warning {{property 'MyProperty' requires method 'setMyProperty:' to be defined}}
+@optional
+@property float OptMyProperty;
+@end
+
+@interface I <PROTOCOL>
+@end
+
+@implementation I @end // expected-note 4 {{implementation is here}}
diff --git a/test/SemaObjC/unused.m b/test/SemaObjC/unused.m
new file mode 100644
index 0000000..1ecf322
--- /dev/null
+++ b/test/SemaObjC/unused.m
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 %s -verify -Wunused -Wunused-parameter -fsyntax-only
+
+int printf(const char *, ...);
+
+@interface Greeter
++ (void) hello;
+@end
+
+@implementation Greeter
++ (void) hello { printf("Hello, World!\n"); }
+@end
+
+int test1(void) {
+  [Greeter hello];
+  return 0;
+}
+
+@interface NSObject @end
+@interface NSString : NSObject 
+- (int)length;
+@end
+
+void test2() {
+  @"pointless example call for test purposes".length; // expected-warning {{property access result unused - getters should not be used for side effects}}
+}
+
+@interface foo
+- (int)meth: (int)x: (int)y: (int)z ;
+@end
+
+@implementation foo
+- (int) meth: (int)x: 
+(int)y: // expected-warning{{unused}} 
+(int) __attribute__((unused))z { return x; }
+@end
+
+//===------------------------------------------------------------------------===
+// The next test shows how clang accepted attribute((unused)) on ObjC
+// instance variables, which GCC does not.
+//===------------------------------------------------------------------------===
+
+#if __has_feature(attribute_objc_ivar_unused)
+#define UNUSED_IVAR __attribute__((unused))
+#else
+#error __attribute__((unused)) not supported on ivars
+#endif
+
+@interface TestUnusedIvar {
+  id y __attribute__((unused)); // no-warning
+  id x UNUSED_IVAR; // no-warning
+}
+@end
+
diff --git a/test/SemaObjC/va-method-1.m b/test/SemaObjC/va-method-1.m
new file mode 100644
index 0000000..fe7ccd7
--- /dev/null
+++ b/test/SemaObjC/va-method-1.m
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+#include <stdarg.h>
+
+@interface NSObject @end
+@interface XX : NSObject @end
+
+@implementation XX
+- (void)encodeValuesOfObjCTypes:(const char *)types, ... {
+   va_list ap;
+   va_start(ap, types); 
+   while (*types) ;
+   va_end(ap);
+}
+
+@end
+
diff --git a/test/SemaObjC/warn-assign-property-nscopying.m b/test/SemaObjC/warn-assign-property-nscopying.m
new file mode 100644
index 0000000..953814c
--- /dev/null
+++ b/test/SemaObjC/warn-assign-property-nscopying.m
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1  -fobjc-gc -fsyntax-only -verify %s
+
+@protocol NSCopying @end
+
+@interface NSObject <NSCopying>
+@end
+
+@interface NSDictionary : NSObject
+@end
+
+@interface INTF
+  @property NSDictionary* undoAction;  // expected-warning {{no 'assign', 'retain', or 'copy' attribute is specified - 'assign' is assumed}} // expected-warning {{default assign attribute on property 'undoAction' which implements NSCopying protocol is not appropriate with}}
+  @property id okAction;  // expected-warning {{no 'assign', 'retain', or 'copy' attribute is specified - 'assign' is assumed}}
+@end
+
diff --git a/test/SemaObjC/warn-incompatible-builtin-types.m b/test/SemaObjC/warn-incompatible-builtin-types.m
new file mode 100644
index 0000000..79c8cea
--- /dev/null
+++ b/test/SemaObjC/warn-incompatible-builtin-types.m
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// rdar 7634850
+
+@interface Foo
+- (void)foo:(Class)class; // expected-note{{passing argument to parameter 'class' here}}
+@end
+
+void FUNC() {
+    Class c, c1;
+    SEL s1, s2;
+    id i, i1;
+    Foo *f;
+    [f foo:f];	// expected-warning {{incompatible pointer types sending 'Foo *' to parameter of type 'Class'}}
+    c = f;	// expected-warning {{incompatible pointer types assigning to 'Class' from 'Foo *'}}
+
+    c = i;
+
+    i = c;
+
+    c = c1;
+
+    i = i1;
+
+    s1 = i;	// expected-warning {{incompatible pointer types assigning to 'SEL' from 'id'}}
+    i = s1;	// expected-warning {{incompatible pointer types assigning to 'id' from 'SEL'}}
+
+    s1 = s2;
+
+    s1 = c;	// expected-warning {{incompatible pointer types assigning to 'SEL' from 'Class'}}
+
+    c = s1;	// expected-warning {{incompatible pointer types assigning to 'Class' from 'SEL'}}
+
+    f = i;
+
+    f = c;	// expected-warning {{incompatible pointer types assigning to 'Foo *' from 'Class'}}
+
+    f = s1;	// expected-warning {{incompatible pointer types assigning to 'Foo *' from 'SEL'}}
+
+    i = f;
+
+    s1 = f; 	// expected-warning {{incompatible pointer types assigning to 'SEL' from 'Foo *'}}
+}
diff --git a/test/SemaObjC/warn-selector-selection.m b/test/SemaObjC/warn-selector-selection.m
new file mode 100644
index 0000000..e395f43
--- /dev/null
+++ b/test/SemaObjC/warn-selector-selection.m
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@interface Object 
+- (void)foo;
+@end
+
+@interface Class1
+- (void)setWindow:(Object *)wdw;
+@end
+
+void foo(void) {
+  Object *obj;
+  [obj setWindow:0]; // expected-warning{{'Object' may not respond to 'setWindow:'}}
+}
diff --git a/test/SemaObjC/warn-superclass-method-mismatch.m b/test/SemaObjC/warn-superclass-method-mismatch.m
new file mode 100644
index 0000000..5205473
--- /dev/null
+++ b/test/SemaObjC/warn-superclass-method-mismatch.m
@@ -0,0 +1,50 @@
+// RUN: %clang_cc1  -fsyntax-only -Wsuper-class-method-mismatch -verify %s
+
+@interface Root
+-(void) method_r: (char)ch : (float*)f1 : (int*) x; // expected-note {{previous declaration is here}}
+@end
+
+@class Sub;
+
+@interface Base : Root
+-(void) method: (int*) x; // expected-note {{previous declaration is here}}
+-(void) method1: (Base*) x; // expected-note {{previous declaration is here}}
+-(void) method2: (Sub*) x; // expected-note{{passing argument to parameter 'x' here}}
++ method3: (int)x1 : (Base *)x2 : (float)x3; // expected-note {{previous declaration is here}}
++ mathod4: (id)x1;
+- method5: (int) x : (double) d; // expected-note {{previous declaration is here}}
+- method6: (int) x : (float) d; // expected-note {{previous declaration is here}}
+@end
+
+struct A {
+  int x,y,z;
+};
+
+@interface Sub : Base
+-(void) method: (struct A*) a;	// expected-warning {{method parameter type 'struct A *' does not match super class method parameter type 'int *'}}
+-(void) method1: (Sub*) x;	// expected-warning {{method parameter type 'Sub *' does not match super class method parameter type 'Base *'}}
+-(void) method2: (Base*) x;	// no need to warn. At call point we warn if need be.
++ method3: (int)x1 : (Sub *)x2 : (float)x3;	// expected-warning {{method parameter type 'Sub *' does not match super class method parameter type 'Base *'}}
++ mathod4: (Base*)x1;
+-(void) method_r: (char)ch : (float*)f1 : (Sub*) x; // expected-warning {{method parameter type 'Sub *' does not match super class method parameter type 'int *'}}
+- method5: (int) x : (float) d; // expected-warning {{method parameter type 'float' does not match super class method parameter type 'double'}}
+- method6: (int) x : (double) d; // expected-warning {{method parameter type 'double' does not match super class method parameter type 'float'}}
+@end
+
+void f(Base *base, Sub *sub) {
+  int x;
+  [base method:&x];  // warn. if base is actually 'Sub' it will use -[Sub method] with wrong arguments
+  
+  Base *b;
+  [base method1:b]; // if base is actuall 'Sub'  it will use [Sub method1] with wrong argument.
+
+  [base method2:b];  // expected-warning {{}}
+
+  Sub *s;
+  [base method2:s]; // if base is actually 'Sub' OK. Either way OK.
+  
+}
+
+
+
+
diff --git a/test/SemaObjC/warn-weak-field.m b/test/SemaObjC/warn-weak-field.m
new file mode 100644
index 0000000..f20691c
--- /dev/null
+++ b/test/SemaObjC/warn-weak-field.m
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -fsyntax-only -fobjc-gc -verify %s
+
+struct S {
+	__weak id w; // expected-warning {{__weak attribute cannot be specified on a field declaration}}
+	__strong id p1;
+};
+
+@interface I
+{
+   __weak id w;	// OK
+   __strong id LHS;
+}
+- (void) foo;
+@end
+@implementation I
+- (void) foo { w = 0; LHS = w; }
+@end
+
+int main ()
+{
+	struct I {
+        __weak id w1;  // expected-warning {{__weak attribute cannot be specified on a field declaration}}
+	};
+}
diff --git a/test/SemaObjC/warn-write-strings.m b/test/SemaObjC/warn-write-strings.m
new file mode 100644
index 0000000..04af00c
--- /dev/null
+++ b/test/SemaObjC/warn-write-strings.m
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -verify -fsyntax-only -Wwrite-strings %s
+
+// PR4804
+char* x = "foo"; // expected-warning {{initializing 'char *' with an expression of type 'char const [4]' discards qualifiers}}
diff --git a/test/SemaObjC/weak-attr-ivar.m b/test/SemaObjC/weak-attr-ivar.m
new file mode 100644
index 0000000..d5bbb01
--- /dev/null
+++ b/test/SemaObjC/weak-attr-ivar.m
@@ -0,0 +1,74 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+typedef signed char BOOL;
+typedef unsigned int NSUInteger;
+typedef struct _NSZone NSZone;
+@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+@protocol NSObject
+- (BOOL)isEqual:(id)object;
+@end
+@protocol NSCopying  - (id)copyWithZone:(NSZone *)zone;
+@end
+@protocol NSMutableCopying  - (id)mutableCopyWithZone:(NSZone *)zone;
+@end
+@protocol NSCoding  - (void)encodeWithCoder:(NSCoder *)aCoder;
+@end
+@interface NSObject <NSObject> {}
+@end
+extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone);
+typedef struct {
+  id *itemsPtr;
+  unsigned long *mutationsPtr;
+} NSFastEnumerationState;
+@protocol NSFastEnumeration
+- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len;
+@end
+@class NSString;
+@interface NSArray : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration>  - (NSUInteger)count;
+@end
+@interface NSMutableArray : NSArray  - (void)addObject:(id)anObject;
+@end
+extern NSString * const NSUndoManagerCheckpointNotification;
+@interface NSValueTransformer : NSObject {} @end
+@class FooModel;
+@interface FooObject : NSObject <NSCopying> {}
+@end
+@interface FooNode : FooObject {}
+- (NSArray *) children;
+@end
+typedef enum { Foo_HUH_NONE } FooHUHCode;
+@interface FooPlaypenEntry : FooNode {
+  NSMutableArray *_interestingChildren;
+  FooHUHCode _HUH;
+  __attribute__((objc_gc(weak))) FooPlaypenEntry *_mostInterestingChild;
+  id _author;
+}
+@property(copy) NSString *author;
+- (BOOL) isInteresting;
+@end  NSString *FooHUHCodeToString(FooHUHCode HUH) { return 0; }
+@interface FooHUHCodeToStringTransformer: NSValueTransformer {
+}
+@end  @implementation FooPlaypenEntry  @synthesize author = _author;
+- (BOOL) isInteresting { return 1; }
+- (NSArray *) interestingChildren {
+  if (!_interestingChildren) {
+    for (FooPlaypenEntry *child in [self children]) {
+      if ([child isInteresting]) {
+        if (!_mostInterestingChild)
+          _mostInterestingChild = child;
+        else if (child->_HUH > _mostInterestingChild->_HUH) 
+          _mostInterestingChild = child;
+      }
+    }
+  }
+  return 0;
+}
+- (FooHUHCode) HUH {
+  if (_HUH == Foo_HUH_NONE) {
+    if (_mostInterestingChild)
+      return [_mostInterestingChild HUH];
+  }
+  return 0;
+}
+@end
+
diff --git a/test/SemaObjC/writable-property-in-superclass.m b/test/SemaObjC/writable-property-in-superclass.m
new file mode 100644
index 0000000..bbd1f16
--- /dev/null
+++ b/test/SemaObjC/writable-property-in-superclass.m
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1  -fsyntax-only -verify %s
+
+@interface MessageStore
+@property (assign, readonly) int P;
+@end
+
+@interface MessageStore (CAT)
+@property (assign) int P;
+@end
+
+@interface  NeXTMbox : MessageStore
+@end
+
+@implementation NeXTMbox
+- (void) Meth { self.P = 1; }
+@end
+
diff --git a/test/SemaObjCXX/blocks.mm b/test/SemaObjCXX/blocks.mm
new file mode 100644
index 0000000..fd0df4e
--- /dev/null
+++ b/test/SemaObjCXX/blocks.mm
@@ -0,0 +1,52 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -fblocks %s
+@protocol NSObject;
+
+void bar(id(^)(void));
+void foo(id <NSObject>(^objectCreationBlock)(void)) {
+    return bar(objectCreationBlock); // expected-warning{{incompatible pointer types converting 'id<NSObject> (^)()' to type 'id (^)()'}}
+}
+
+void bar2(id(*)(void));
+void foo2(id <NSObject>(*objectCreationBlock)(void)) {
+    return bar2(objectCreationBlock); // expected-warning{{incompatible pointer types converting 'id<NSObject> (*)()' to type 'id (*)()'}}
+}
+
+void bar3(id(*)()); // expected-note{{candidate function}}
+void foo3(id (*objectCreationBlock)(int)) {
+    return bar3(objectCreationBlock); // expected-error{{no matching}}
+}
+
+void bar4(id(^)()); // expected-note{{candidate function}}
+void foo4(id (^objectCreationBlock)(int)) {
+    return bar4(objectCreationBlock); // expected-error{{no matching}}
+}
+
+void foo5(id (^x)(int)) {
+  if (x) { }
+}
+
+// <rdar://problem/6590445>
+@interface Foo {
+    @private
+    void (^_block)(void);
+}
+- (void)bar;
+@end
+
+namespace N {
+  class X { };      
+  void foo(X);
+}
+
+@implementation Foo
+- (void)bar {
+    _block();
+    foo(N::X()); // okay
+}
+@end
+
+typedef signed char BOOL;
+void foo6(void *block) {  
+	void (^vb)(id obj, int idx, BOOL *stop) = (void (^)(id, int, BOOL *))block;
+    BOOL (^bb)(id obj, int idx, BOOL *stop) = (BOOL (^)(id, int, BOOL *))block;
+}
diff --git a/test/SemaObjCXX/category-lookup.mm b/test/SemaObjCXX/category-lookup.mm
new file mode 100644
index 0000000..0e87025
--- /dev/null
+++ b/test/SemaObjCXX/category-lookup.mm
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@interface NSObject @end
+
+@interface NSObject (NSScriptClassDescription)
+@end
+
+void f() {
+  NSScriptClassDescription *f; // expected-error {{use of undeclared identifier 'NSScriptClassDescription'}}
+}
diff --git a/test/SemaObjCXX/composite-objc-pointertype.mm b/test/SemaObjCXX/composite-objc-pointertype.mm
new file mode 100644
index 0000000..0d9a938
--- /dev/null
+++ b/test/SemaObjCXX/composite-objc-pointertype.mm
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@interface Foo
+@end
+
+@implementation Foo
+- (id)test {
+        id bar;
+    Class cl;
+    Foo *f;
+
+    (void)((bar!= 0) ? bar : 0);
+    (void)((cl != 0) ? cl : 0);
+    (void)((f != 0) ? 0 : f);
+    return (0 == 1) ? 0 : bar;
+}
+@end
+
diff --git a/test/SemaObjCXX/conditional-expr.mm b/test/SemaObjCXX/conditional-expr.mm
new file mode 100644
index 0000000..a6b7c08
--- /dev/null
+++ b/test/SemaObjCXX/conditional-expr.mm
@@ -0,0 +1,67 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@protocol P0
+@end
+@protocol P1
+@end
+@protocol P2
+@end
+
+@interface A <P0>
+@end
+
+@interface B : A
+@end
+
+void bar(id x);
+void barP0(id<P0> x);
+void barP1(id<P1> x);
+void barP2(id<P2> x);
+
+void f0(A *a) {
+  id l = a;
+}
+
+void f1(id x, A *a) {
+  id<P0> l = a;
+}
+
+void f2(id<P1> x) {
+  id<P0> l = x; // expected-error {{cannot initialize a variable of type 'id<P0>' with an lvalue of type 'id<P1>'}}
+}
+
+void f3(A *a) {
+  id<P1> l = a; // expected-error {{cannot initialize a variable of type 'id<P1>' with an lvalue of type 'A *'}}
+}
+
+void f4(int cond, id x, A *a) {
+  bar(cond ? x : a);
+}
+
+void f5(int cond, A *a, B *b) {
+  bar(cond ? a : b);
+}
+
+void f6(int cond, id x, A *a) {
+  bar(cond ? (id<P0, P1>) x : a);
+}
+
+void f7(int cond, id x, A *a) {
+  bar(cond ? a : (id<P0, P1>) x);
+}
+
+void f8(int cond, id<P0,P1> x0, id<P0,P2> x1) {
+  barP0(cond ? x0 : x1); // expected-warning {{incompatible operand types ('id<P0,P1>' and 'id<P0,P2>')}}
+}
+
+void f9(int cond, id<P0,P1> x0, id<P0,P2> x1) {
+  barP1(cond ? x0 : x1); // expected-warning {{incompatible operand types ('id<P0,P1>' and 'id<P0,P2>')}}
+}
+
+void f10(int cond, id<P0,P1> x0, id<P0,P2> x1) {
+  barP2(cond ? x0 : x1); // expected-warning {{incompatible operand types ('id<P0,P1>' and 'id<P0,P2>')}}
+}
+
+int f11(int cond, A* a, B* b) {
+  return (cond? b : a)->x; // expected-error{{'A' does not have a member named 'x'}}
+}
diff --git a/test/SemaObjCXX/cstyle-block-pointer-cast.mm b/test/SemaObjCXX/cstyle-block-pointer-cast.mm
new file mode 100644
index 0000000..72f5283
--- /dev/null
+++ b/test/SemaObjCXX/cstyle-block-pointer-cast.mm
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -fblocks %s
+// radar 7562285
+
+typedef int (^blocktype)(int a, int b);
+
+@interface A {
+    A* a;
+    id b;
+    Class c;
+}
+- (blocktype)Meth;
+@end
+
+@implementation A
+- (blocktype)Meth {
+        if (b)
+	  return (blocktype)b;
+        else if (a)
+          return (blocktype)a; // expected-error {{C-style cast from 'A *' to 'blocktype' (aka 'int (^)(int, int)') is not allowed}}
+        else
+          return (blocktype)c;
+}
+@end
+
+@interface B {
+    blocktype a;
+    blocktype b;
+    blocktype c;
+}
+- (id)Meth;
+@end
+
+@implementation B
+- (id)Meth {
+        if (a)
+          return (A*)a; // expected-error {{C-style cast from 'blocktype' (aka 'int (^)(int, int)') to 'A *' is not allowed}}
+        if (b)
+	  return (id)b;
+        if (c)
+	  return (Class)b;
+}
+@end
diff --git a/test/SemaObjCXX/cstyle-cast.mm b/test/SemaObjCXX/cstyle-cast.mm
new file mode 100644
index 0000000..c4b176c
--- /dev/null
+++ b/test/SemaObjCXX/cstyle-cast.mm
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@protocol P @end
+@interface I @end
+
+struct X { X(); };
+
+void test1(X x) {
+  void *cft;
+  id oct = (id)cft;
+
+  Class ccct;
+  ccct = (Class)cft;
+
+  I* iict = (I*)cft;
+
+  id<P> qid = (id<P>)cft;
+
+  I<P> *ip = (I<P>*)cft;
+
+  (id)x; // expected-error {{C-style cast from 'X' to 'id' is not allowed}}
+
+  id *pid = (id*)ccct;
+
+  id<P> *qpid = (id<P>*)ccct;
+
+  int **pii;
+
+  ccct = (Class)pii;
+
+  qpid = (id<P>*)pii;
+
+  iict = (I*)pii;
+
+  pii = (int **)ccct;
+
+  pii = (int **)qpid;
+  
+}
+
diff --git a/test/SemaObjCXX/function-pointer-void-star.mm b/test/SemaObjCXX/function-pointer-void-star.mm
new file mode 100644
index 0000000..8d3d625
--- /dev/null
+++ b/test/SemaObjCXX/function-pointer-void-star.mm
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+extern "C" id (*_dealloc)(id) ;
+
+void foo() {
+        extern void *_original_dealloc;
+        if (_dealloc == _original_dealloc) { }
+        if (_dealloc != _original_dealloc) { }
+}
diff --git a/test/SemaObjCXX/instantiate-expr.mm b/test/SemaObjCXX/instantiate-expr.mm
new file mode 100644
index 0000000..08be5f7
--- /dev/null
+++ b/test/SemaObjCXX/instantiate-expr.mm
@@ -0,0 +1,73 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@interface A {
+@public
+  int ivar;
+}
+@property int prop;
+@end
+
+typedef struct objc_object {
+    Class isa;
+} *id;
+
+// Test instantiation of value-dependent ObjCIvarRefExpr,
+// ObjCIsaRefExpr, and ObjCPropertyRefExpr nodes.
+A *get_an_A(unsigned);
+id get_an_id(unsigned);
+
+template<unsigned N, typename T, typename U, typename V>
+void f(U value, V value2) {
+  get_an_A(N)->ivar = value; // expected-error{{assigning to 'int' from incompatible type 'int *'}}
+  get_an_A(N).prop = value2; // expected-error{{assigning to 'int' from incompatible type 'double *'}}
+  T c = get_an_id(N)->isa; // expected-error{{cannot initialize a variable of type 'int' with an lvalue of type 'Class'}}
+}
+
+template void f<6, Class>(int, int);
+template void f<7, Class>(int*, int); // expected-note{{in instantiation of}}
+template void f<8, Class>(int, double*); // expected-note{{in instantiation of}}
+template void f<9, int>(int, int); // expected-note{{in instantiation of}}
+
+// Test instantiation of unresolved member reference expressions to an
+// ivar reference.
+template<typename T, typename U, typename V>
+void f2(T ptr, U value, V value2) {
+  ptr->ivar = value; // expected-error{{assigning to 'int' from incompatible type 'int *'}}
+  ptr.prop = value2; // expected-error{{assigning to 'int' from incompatible type 'double *'}}
+}
+
+template void f2(A*, int, int);
+template void f2(A*, int*, int); // expected-note{{instantiation of}}
+template void f2(A*, int, double*); // expected-note{{instantiation of}}
+
+// Test instantiation of unresolved member referfence expressions to
+// an isa.
+template<typename T, typename U>
+void f3(U ptr) {
+  T c = ptr->isa; // expected-error{{cannot initialize a variable of type 'int' with an lvalue of type 'Class'}}
+}
+
+template void f3<Class>(id);
+template void f3<int>(id); // expected-note{{instantiation of}}
+
+// Implicit setter/getter
+@interface B
+- (int)foo;
+- (void)setFoo:(int)value;
+@end
+
+template<typename T>
+void f4(B *b, T value) {
+  b.foo = value; // expected-error{{assigning to 'int' from incompatible type 'int *'}}
+}
+
+template void f4(B*, int);
+template void f4(B*, int*); // expected-note{{in instantiation of function template specialization 'f4<int *>' requested here}}
+
+template<typename T, typename U>
+void f5(T ptr, U value) {
+  ptr.foo = value; // expected-error{{assigning to 'int' from incompatible type 'int *'}}
+}
+
+template void f5(B*, int);
+template void f5(B*, int*); // expected-note{{in instantiation of function template specialization 'f5<B *, int *>' requested here}}
diff --git a/test/SemaObjCXX/instantiate-message.mm b/test/SemaObjCXX/instantiate-message.mm
new file mode 100644
index 0000000..46c8ede
--- /dev/null
+++ b/test/SemaObjCXX/instantiate-message.mm
@@ -0,0 +1,50 @@
+// RUN: %clang -cc1 -fsyntax-only -verify %s
+
+// Test template instantiation of Objective-C message sends.
+
+@interface ClassMethods
++ (ClassMethods *)method1:(void*)ptr;
+@end
+
+template<typename T>
+struct identity {
+  typedef T type;
+};
+
+template<typename R, typename T, typename Arg1>
+void test_class_method(Arg1 arg1) {
+  R *result1 = [T method1:arg1];
+  R *result2 = [typename identity<T>::type method1:arg1];
+  R *result3 = [ClassMethods method1:arg1]; // expected-error{{cannot initialize a variable of type 'ClassMethods2 *' with an rvalue of type 'ClassMethods *'}}
+}
+
+template void test_class_method<ClassMethods, ClassMethods>(void*);
+template void test_class_method<ClassMethods, ClassMethods>(int*);
+
+@interface ClassMethods2
++ (ClassMethods2 *)method1:(int*)ptr;
+@end
+
+template void test_class_method<ClassMethods2, ClassMethods2>(int*); // expected-note{{in instantiation of}}
+
+
+@interface InstanceMethods
+- (InstanceMethods *)method1:(void*)ptr;
+@end
+
+template<typename R, typename T, typename Arg1>
+void test_instance_method(Arg1 arg1) {
+  T *receiver = 0;
+  InstanceMethods *im = 0;
+  R *result1 = [receiver method1:arg1];
+  R *result2 = [im method1:arg1]; // expected-error{{cannot initialize a variable of type 'InstanceMethods2 *' with an rvalue of type 'InstanceMethods *'}}
+}
+
+template void test_instance_method<InstanceMethods, InstanceMethods>(void*);
+template void test_instance_method<InstanceMethods, InstanceMethods>(int*);
+
+@interface InstanceMethods2
+- (InstanceMethods2 *)method1:(void*)ptr;
+@end
+
+template void test_instance_method<InstanceMethods2, InstanceMethods2>(int*); // expected-note{{in instantiation of}}
diff --git a/test/SemaObjCXX/instantiate-stmt.mm b/test/SemaObjCXX/instantiate-stmt.mm
new file mode 100644
index 0000000..e92f8e8
--- /dev/null
+++ b/test/SemaObjCXX/instantiate-stmt.mm
@@ -0,0 +1,77 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@interface NSException
+@end
+
+// @throw
+template<typename T>
+void throw_test(T value) {
+  @throw value; // expected-error{{@throw requires an Objective-C object type ('int' invalid)}}
+}
+
+template void throw_test(NSException *);
+template void throw_test(int); // expected-note{{in instantiation of}}
+
+// @synchronized
+template<typename T>
+void synchronized_test(T value) {
+  @synchronized (value) { // expected-error{{@synchronized requires an Objective-C object type ('int' invalid)}}
+    value = 0;
+  }
+}
+
+template void synchronized_test(NSException *);
+template void synchronized_test(int); // expected-note{{in instantiation of}}
+
+// fast enumeration
+@interface NSArray
+@end
+
+@interface NSString
+@end
+
+struct vector {};
+
+template<typename T> void eat(T);
+
+template<typename E, typename T>
+void fast_enumeration_test(T collection) {
+  for (E element in collection) { // expected-error{{selector element type 'int' is not a valid object}} \
+    // expected-error{{collection expression type 'vector' is not a valid object}}
+    eat(element);
+  }
+
+  E element;
+  for (element in collection) // expected-error{{selector element type 'int' is not a valid object}} \
+    // expected-error{{collection expression type 'vector' is not a valid object}}
+    eat(element);
+
+  for (NSString *str in collection) // expected-error{{collection expression type 'vector' is not a valid object}}
+    eat(str);
+
+  NSString *str;
+  for (str in collection) // expected-error{{collection expression type 'vector' is not a valid object}}
+    eat(str);
+}
+
+template void fast_enumeration_test<NSString *>(NSArray*);
+template void fast_enumeration_test<int>(NSArray*); // expected-note{{in instantiation of}}
+template void fast_enumeration_test<NSString *>(vector); // expected-note{{in instantiation of}}
+
+// @try/@catch/@finally
+
+template<typename T, typename U>
+void try_catch_finally_test(U value) {
+  @try {
+    value = 1; // expected-error{{assigning to 'int *' from incompatible type 'int'}}
+  }
+  @catch (T obj) { // expected-error{{@catch parameter is not a pointer to an interface type}}
+    id x = obj;
+  } @finally {
+    value = 0;
+  }
+}
+
+template void try_catch_finally_test<NSString *>(int);
+template void try_catch_finally_test<NSString *>(int*); // expected-note{{in instantiation of}}
+template void try_catch_finally_test<NSString>(int); // expected-note{{in instantiation of function template specialization 'try_catch_finally_test<NSString, int>' requested here}}
diff --git a/test/SemaObjCXX/ivar-lookup.mm b/test/SemaObjCXX/ivar-lookup.mm
new file mode 100644
index 0000000..bb26f48
--- /dev/null
+++ b/test/SemaObjCXX/ivar-lookup.mm
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+@interface Ivar
+- (float*)method;
+@end
+
+@interface A {
+  A *Ivar;
+}
+- (int*)method;
+@end
+
+@implementation A
+- (int*)method {
+  int *ip = [Ivar method]; // Okay; calls A's method on the instance variable Ivar.
+                           // Note that Objective-C calls Ivar's method.
+  return 0;
+}
+@end
diff --git a/test/SemaObjCXX/ivar-reference-type.mm b/test/SemaObjCXX/ivar-reference-type.mm
new file mode 100644
index 0000000..2b5df45
--- /dev/null
+++ b/test/SemaObjCXX/ivar-reference-type.mm
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+@interface A {
+  int &r; // expected-error {{instance variables cannot be of reference type}}
+}
+@end
diff --git a/test/SemaObjCXX/linkage-spec.mm b/test/SemaObjCXX/linkage-spec.mm
new file mode 100644
index 0000000..1454e6a
--- /dev/null
+++ b/test/SemaObjCXX/linkage-spec.mm
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+extern "C" {
+@class Protocol;
+}
+
+// <rdar://problem/7827709>
+extern "C" {
+@class I;
+}
+
+@interface I
+@end
diff --git a/test/SemaObjCXX/message.mm b/test/SemaObjCXX/message.mm
new file mode 100644
index 0000000..b75608e
--- /dev/null
+++ b/test/SemaObjCXX/message.mm
@@ -0,0 +1,94 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+@interface I1
+- (int*)method;
+@end
+
+@implementation I1
+- (int*)method {
+  struct x { };
+  [x method]; // expected-error{{receiver type 'x' is not an Objective-C class}}
+  return 0;
+}
+@end
+
+typedef struct { int x; } ivar;
+
+@interface I2 {
+  id ivar;
+}
+- (int*)method;
++ (void)method;
+@end
+
+struct I2_holder {
+  I2_holder();
+
+  I2 *get();
+};
+
+I2 *operator+(I2_holder, int);
+
+@implementation I2
+- (int*)method {
+  [ivar method];
+
+  // Test instance messages that start with a simple-type-specifier.
+  [I2_holder().get() method];
+  [I2_holder().get() + 17 method];
+  return 0;
+}
++ (void)method {
+  [ivar method]; // expected-error{{receiver type 'ivar' (aka 'ivar') is not an Objective-C class}}
+}
+@end
+
+// Class message sends
+@interface I3
++ (int*)method;
+@end
+
+@interface I4 : I3
++ (int*)otherMethod;
+@end
+
+template<typename T>
+struct identity {
+  typedef T type;
+};
+
+@implementation I4
++ (int *)otherMethod {
+  // Test class messages that use non-trivial simple-type-specifiers
+  // or typename-specifiers.
+  if (false) {
+    if (true)
+      return [typename identity<I3>::type method];
+
+    return [::I3 method];
+  }
+
+  int* ip1 = {[super method]};
+  int* ip2 = {[::I3 method]};
+  int* ip3 = {[typename identity<I3>::type method]};
+  int* ip4 = {[typename identity<I2_holder>::type().get() method]};
+  int array[5] = {[3] = 2};
+  return [super method];
+}
+@end
+
+struct String {
+  String(const char *);
+};
+
+struct MutableString : public String { };
+
+// C++-specific parameter types
+@interface I5
+- method:(const String&)str1 
+   other:(String&)str2; // expected-note{{passing argument to parameter 'str2' here}}
+@end
+
+void test_I5(I5 *i5, String s) {
+  [i5 method:"hello" other:s];
+  [i5 method:s other:"world"]; // expected-error{{non-const lvalue reference to type 'String' cannot bind to a value of unrelated type 'char const [6]'}}
+}
diff --git a/test/SemaObjCXX/objc-decls-inside-namespace.mm b/test/SemaObjCXX/objc-decls-inside-namespace.mm
new file mode 100644
index 0000000..9953ec3
--- /dev/null
+++ b/test/SemaObjCXX/objc-decls-inside-namespace.mm
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace C {
+
+@protocol P; //expected-error{{Objective-C declarations may only appear in global scope}}
+
+@class Bar; //expected-error{{Objective-C declarations may only appear in global scope}}
+
+@compatibility_alias Foo Bar; //expected-error{{Objective-C declarations may only appear in global scope}}
+
+@interface A //expected-error{{Objective-C declarations may only appear in global scope}}
+@end
+
+@implementation A //expected-error{{Objective-C declarations may only appear in global scope}}
+@end
+
+@protocol P //expected-error{{Objective-C declarations may only appear in global scope}}
+@end
+
+@interface A(C) //expected-error{{Objective-C declarations may only appear in global scope}}
+@end
+
+@implementation A(C) //expected-error{{Objective-C declarations may only appear in global scope}}
+@end
+
+}
+
diff --git a/test/SemaObjCXX/objc-pointer-conv.mm b/test/SemaObjCXX/objc-pointer-conv.mm
new file mode 100644
index 0000000..cc3264f
--- /dev/null
+++ b/test/SemaObjCXX/objc-pointer-conv.mm
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+typedef const void * VoidStar;
+
+typedef struct __CFDictionary * CFMDRef;
+
+void RandomFunc(CFMDRef theDict, const void *key, const void *value);
+
+@interface Foo
+- (void)_apply:(void (*)(const void *, const void *, void *))func context:(void *)context;
+- (void)a:(id *)objects b:(id *)keys;
+@end
+
+@implementation Foo
+- (void)_apply:(void (*)(const void *, const void *, void *))func context:(void *)context {
+	id item;
+	id obj;
+    func(item, obj, context);
+}
+
+- (void)a:(id *)objects b:(id *)keys {
+    VoidStar dict;
+	id key;
+    RandomFunc((CFMDRef)dict, key, objects[3]);
+}
+@end
+
+@interface I
+- (void) Meth : (I*) Arg; // expected-note{{passing argument to parameter 'Arg' here}}
+@end
+
+void Func (I* arg);  // expected-note {{candidate function not viable: no known conversion from 'I const *' to 'I *' for 1st argument}}
+
+void foo(const I *p, I* sel) {
+  [sel Meth : p];	// expected-error {{cannot initialize a parameter of type 'I *' with an lvalue of type 'I const *'}}
+  Func(p);		// expected-error {{no matching function for call to 'Func'}}
+}
+
diff --git a/test/SemaObjCXX/overload.mm b/test/SemaObjCXX/overload.mm
new file mode 100644
index 0000000..18da69f
--- /dev/null
+++ b/test/SemaObjCXX/overload.mm
@@ -0,0 +1,95 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// XFAIL: *
+@interface Foo
+@end
+
+@implementation Foo
+
+void func(id);
+
++ zone {
+ func(self);
+ return self;
+}
+@end
+
+@protocol P0
+@end
+
+@protocol P1
+@end
+
+@interface A <P0>
+@end
+
+@interface B : A
+@end
+
+@interface C <P1>
+@end
+
+int& f(A*);
+float& f(B*);
+void g(A*);
+
+int& h(A*);
+float& h(id);
+
+void test(A* a, B* b, id val) {
+  int& i1 = f(a);
+  float& f1 = f(b);
+  float& f2 = f(val);
+  g(a);
+  g(b);
+  g(val);
+  int& i2 = h(a);
+  float& f3 = h(val);
+  //  int& i3 = h(b); FIXME: we match GCC here, but shouldn't this work?
+}
+
+void downcast_test(A* a, A** ap) {
+  B* b = a; // expected-warning{{incompatible pointer types initializing 'B *', expected 'A *'}}
+  b = a;  // expected-warning{{incompatible pointer types assigning 'B *', expected 'A *'}}
+
+  B** bp = ap; // expected-warning{{incompatible pointer types initializing 'B **', expected 'A **'}}
+  bp = ap; // expected-warning{{incompatible pointer types assigning 'B **', expected 'A **'}}
+}
+
+int& cv(A*);
+float& cv(const A*);
+int& cv2(void*);
+float& cv2(const void*);
+
+void cv_test(A* a, B* b, const A* ac, const B* bc) {
+  int &i1 = cv(a);
+  int &i2 = cv(b);
+  float &f1 = cv(ac);
+  float &f2 = cv(bc);
+  int& i3 = cv2(a);
+  float& f3 = cv2(ac);
+}
+
+
+int& qualid(id<P0>);
+float& qualid(id<P1>); // FIXME: GCC complains that this isn't an overload. Is it?
+
+void qualid_test(A *a, B *b, C *c) {
+  int& i1 = qualid(a);
+  int& i2 = qualid(b);
+  float& f1 = qualid(c);
+
+  id<P0> p1 = 0;
+  p1 = 0;
+}
+
+
+@class NSException;
+typedef struct {
+    void (*throw_exc)(id);
+}
+objc_exception_functions_t;
+
+void (*_NSExceptionRaiser(void))(NSException *) {
+    objc_exception_functions_t exc_funcs;
+    return exc_funcs.throw_exc; // expected-warning{{incompatible pointer types returning 'void (*)(NSException *)', expected 'void (*)(id)'}}
+}
diff --git a/test/SemaObjCXX/parameters.mm b/test/SemaObjCXX/parameters.mm
new file mode 100644
index 0000000..aab1fbd
--- /dev/null
+++ b/test/SemaObjCXX/parameters.mm
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -verify %s
+
+@interface A
+@end
+
+template<typename T>
+struct X0 {
+  void f(T); // expected-error{{interface type 'A' cannot be passed by value}}
+};
+
+X0<A> x0a; // expected-note{{instantiation}}
+
diff --git a/test/SemaObjCXX/pointer-to-objc-pointer-conv.mm b/test/SemaObjCXX/pointer-to-objc-pointer-conv.mm
new file mode 100644
index 0000000..80383eb
--- /dev/null
+++ b/test/SemaObjCXX/pointer-to-objc-pointer-conv.mm
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@interface G
+@end
+
+@interface F
+- (void)bar:(id *)objects;
+- (void)foo:(G**)objects;
+@end
+
+
+void a() {
+	F *b;
+	G **keys;
+	[b bar:keys];
+
+	id *PID;
+	[b foo:PID];
+
+}
+
diff --git a/test/SemaObjCXX/protocol-lookup.mm b/test/SemaObjCXX/protocol-lookup.mm
new file mode 100644
index 0000000..ed3fbe0
--- /dev/null
+++ b/test/SemaObjCXX/protocol-lookup.mm
@@ -0,0 +1,51 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+@protocol NSObject
+- retain;
+- release;
+@end
+
+@interface NSObject
+- init;
+- dealloc;
+@end
+
+@protocol Foo <NSObject>
+@end
+
+@protocol Bar <Foo>
+@end
+
+@interface Baz : NSObject {
+	id <Foo> _foo;
+	id <Bar> _bar;
+}
+- (id)initWithFoo:(id <Foo>)foo bar:(id <Bar>)bar;
+@end
+
+@implementation Baz
+
+- (id)init
+{
+	return [self initWithFoo:0 bar:0];
+}
+
+- (id)initWithFoo:(id <Foo>)foo bar:(id <Bar>)bar
+{
+	self = [super init];
+	if (self != 0) {
+		_foo = [foo retain];
+		_bar = [bar retain];
+	}
+	return self;
+}
+
+- dealloc
+{
+	[_foo release];
+	[_bar release];
+	[super dealloc];
+	return 0;
+}
+
+@end
+
diff --git a/test/SemaObjCXX/references.mm b/test/SemaObjCXX/references.mm
new file mode 100644
index 0000000..70ce827
--- /dev/null
+++ b/test/SemaObjCXX/references.mm
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -verify -emit-llvm -o - %s
+
+// Test reference binding.
+
+typedef struct {
+  int f0;
+  int f1;
+} T;
+
+@interface A
+@property (assign) T p0;
+@property (assign) T& p1; // expected-error {{property of reference type is not supported}}
+@end
+
+int f0(const T& t) {
+  return t.f0;
+}
+
+int f1(A *a) {
+  return f0(a.p0);
+}
+
+int f2(A *a) {
+  return f0(a.p1);	// expected-error {{property 'p1' not found on object of type 'A *'}}
+}
+
diff --git a/test/SemaObjCXX/reinterpret-cast-objc-pointertype.mm b/test/SemaObjCXX/reinterpret-cast-objc-pointertype.mm
new file mode 100644
index 0000000..fcabade
--- /dev/null
+++ b/test/SemaObjCXX/reinterpret-cast-objc-pointertype.mm
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@interface NSString @end
+
+typedef const struct __CFString * CFStringRef;
+const NSString* fRef;
+
+CFStringRef func() {
+  return reinterpret_cast<CFStringRef>(fRef);
+}
+
+CFStringRef fRef1;
+
+const NSString* func1() {
+  return reinterpret_cast<const NSString*>(fRef1);
+}
+
+@interface I @end
+const I *fRef2;
+
+const NSString* func2() {
+  return reinterpret_cast<const NSString*>(fRef2);
+}
diff --git a/test/SemaObjCXX/reserved-keyword-selectors.mm b/test/SemaObjCXX/reserved-keyword-selectors.mm
new file mode 100644
index 0000000..3c4bef5
--- /dev/null
+++ b/test/SemaObjCXX/reserved-keyword-selectors.mm
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@interface A 
+- (void)asm;
+- (void)bool;
+- (void)catch;
+- (void)class;
+- (void)const_cast;
+- (void)delete;
+- (void)dynamic_cast;
+- (void)explicit;
+- (void)export;
+- (void)false;      
+- (void)friend;
+- (void)mutable;
+- (void)namespace;
+- (void)new;
+- (void)operator;
+- (void)private;
+- (void)protected;
+- (void)public;
+- (void)reinterpret_cast;
+- (void)static_cast;
+- (void)template;
+- (void)this;
+- (void)throw;
+- (void)true;
+- (void)try;
+- (void)typename;
+- (void)typeid;
+- (void)using;
+- (void)virtual;
+- (void)wchar_t;
+@end
+
diff --git a/test/SemaObjCXX/standard-conversion-to-bool.mm b/test/SemaObjCXX/standard-conversion-to-bool.mm
new file mode 100644
index 0000000..2e69848
--- /dev/null
+++ b/test/SemaObjCXX/standard-conversion-to-bool.mm
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@class NSString;
+id a;
+NSString *b;
+
+void f() {
+  bool b1 = a;
+  bool b2 = b;
+}
+
+
diff --git a/test/SemaObjCXX/vararg-non-pod.mm b/test/SemaObjCXX/vararg-non-pod.mm
new file mode 100644
index 0000000..7e5c4c6
--- /dev/null
+++ b/test/SemaObjCXX/vararg-non-pod.mm
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -Wnon-pod-varargs
+
+extern char version[];
+
+@protocol P;
+
+class C {
+public:
+  C(int);
+};
+
+@interface D 
+- (void)g:(int)a, ...;
+@end
+
+void t1(D *d)
+{
+  C c(10);
+
+  [d g:10, c]; // expected-warning{{cannot pass object of non-POD type 'C' through variadic method; call will abort at runtime}}
+  [d g:10, version];
+}
+
+void t2(D *d, id p)
+{
+  [d g:10, p];
+}
+
+void t3(D *d, id<P> p)
+{
+  [d g:10, p];
+}
diff --git a/test/SemaObjCXX/vla.mm b/test/SemaObjCXX/vla.mm
new file mode 100644
index 0000000..9c6fc54
--- /dev/null
+++ b/test/SemaObjCXX/vla.mm
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@interface Data
+- (unsigned)length;
+- (void)getData:(void*)buffer;
+@end
+
+void test(Data *d) {
+  char buffer[[d length]]; // expected-error{{variable length arrays are not permitted in C++}}
+  [d getData:buffer];
+}
+
diff --git a/test/SemaObjCXX/void_to_obj.mm b/test/SemaObjCXX/void_to_obj.mm
new file mode 100644
index 0000000..52510c8
--- /dev/null
+++ b/test/SemaObjCXX/void_to_obj.mm
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// <rdar://problem/6463729>
+@class XX;
+
+void func() {
+  XX *obj;
+  void *vv;
+
+  obj = vv; // expected-error{{assigning to 'XX *' from incompatible type 'void *'}}
+}
diff --git a/test/SemaTemplate/ackermann.cpp b/test/SemaTemplate/ackermann.cpp
new file mode 100644
index 0000000..9525bfc
--- /dev/null
+++ b/test/SemaTemplate/ackermann.cpp
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// template<unsigned M, unsigned N>
+// struct Ackermann {
+//   enum {
+//     value = M ? (N ? Ackermann<M-1, Ackermann<M, N-1> >::value
+//                    : Ackermann<M-1, 1>::value)
+//               : N + 1
+//   };
+// };
+
+template<unsigned M, unsigned N>
+struct Ackermann {
+ enum {
+   value = Ackermann<M-1, Ackermann<M, N-1>::value >::value
+ };
+};
+
+template<unsigned M> struct Ackermann<M, 0> {
+ enum {
+   value = Ackermann<M-1, 1>::value
+ };
+};
+
+template<unsigned N> struct Ackermann<0, N> {
+ enum {
+   value = N + 1
+ };
+};
+
+template<> struct Ackermann<0, 0> {
+ enum {
+   value = 1
+ };
+};
+
+int g0[Ackermann<3, 4>::value == 125 ? 1 : -1];
+
diff --git a/test/SemaTemplate/ambiguous-ovl-print.cpp b/test/SemaTemplate/ambiguous-ovl-print.cpp
new file mode 100644
index 0000000..7e3fa24
--- /dev/null
+++ b/test/SemaTemplate/ambiguous-ovl-print.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+void f(void*, int); // expected-note{{candidate function}}
+template<typename T>
+  void f(T*, long); // expected-note{{candidate function}}
+
+void test_f(int *ip, int i) {
+  f(ip, i); // expected-error{{ambiguous}}
+}
diff --git a/test/SemaTemplate/anonymous-union.cpp b/test/SemaTemplate/anonymous-union.cpp
new file mode 100644
index 0000000..59d1f25
--- /dev/null
+++ b/test/SemaTemplate/anonymous-union.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// PR5868
+struct T0 {
+  int x;
+  union {
+    void *m0;
+  };
+};
+template <typename T>
+struct T1 : public T0, public T { 
+  void f0() { 
+    m0 = 0; // expected-error{{ambiguous conversion}}
+  } 
+};
+
+struct A : public T0 { };
+
+void f1(T1<A> *S) { S->f0(); } // expected-note{{instantiation of member function}}
diff --git a/test/SemaTemplate/canonical-expr-type-0x.cpp b/test/SemaTemplate/canonical-expr-type-0x.cpp
new file mode 100644
index 0000000..73cf3c2
--- /dev/null
+++ b/test/SemaTemplate/canonical-expr-type-0x.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s
+
+void f();
+
+// FIXME: would like to refer to the first function parameter in these test,
+// but that won't work (yet).
+
+// Test typeof(expr) canonicalization
+template<typename T, T N>
+void f0(T x, decltype(f(N)) y) { } // expected-note{{previous}}
+
+template<typename T, T N>
+void f0(T x, decltype((f)(N)) y) { }
+
+template<typename U, U M>
+void f0(U u, decltype(f(M))) { } // expected-error{{redefinition}}
diff --git a/test/SemaTemplate/canonical-expr-type.cpp b/test/SemaTemplate/canonical-expr-type.cpp
new file mode 100644
index 0000000..7582df5
--- /dev/null
+++ b/test/SemaTemplate/canonical-expr-type.cpp
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+void f();
+
+// Test typeof(expr) canonicalization
+template<typename T>
+void f0(T x, __typeof__(f(x)) y) { } // expected-note{{previous}}
+
+template<typename T>
+void f0(T x, __typeof__((f)(x)) y) { }
+
+template<typename U>
+void f0(U u, __typeof__(f(u))) { } // expected-error{{redefinition}}
+
+// Test insane typeof(expr) overload set canonicalization
+void f(int);
+void f(double);
+
+template<typename T, T N>
+void f0a(T x, __typeof__(f(N)) y) { } // expected-note{{previous}}
+
+void f(int);
+
+template<typename T, T N>
+void f0a(T x, __typeof__(f(N)) y) { } // expected-error{{redefinition}} \
+                                      // expected-note{{previous}}
+
+void f(float);
+
+template<typename T, T N>
+void f0a(T x, __typeof__(f(N)) y) { } // expected-error{{redefinition}}
+
+// Test dependently-sized array canonicalization
+template<typename T, int N, int M>
+void f1(T (&array)[N + M]) { } // expected-note{{previous}}
+
+template<typename T, int N, int M>
+void f1(T (&array)[M + N]) { }
+
+template<typename T, int M, int N>
+void f1(T (&array)[M + N]) { } // expected-error{{redefinition}}
+
+// Test dependently-sized extended vector type canonicalization
+template<typename T, int N, int M>
+struct X2 {
+  typedef T __attribute__((ext_vector_type(N))) type1;
+  typedef T __attribute__((ext_vector_type(M))) type2;
+  typedef T __attribute__((ext_vector_type(N))) type3;
+  
+  void f0(type1); // expected-note{{previous}}
+  void f0(type2);
+  void f0(type3); // expected-error{{redeclared}}
+};
diff --git a/test/SemaTemplate/class-template-ctor-initializer.cpp b/test/SemaTemplate/class-template-ctor-initializer.cpp
new file mode 100644
index 0000000..fd9417c
--- /dev/null
+++ b/test/SemaTemplate/class-template-ctor-initializer.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<class X> struct A {};
+
+template<class X> struct B : A<X> { 
+  B() : A<X>() {} 
+};
+B<int> x;
+
+template<class X> struct B1 : A<X> {
+  typedef A<X> Base;
+  B1() : Base() {}
+};
+B1<int> x1;
+
+
+template<typename T> struct Tmpl { };
+
+template<typename T> struct TmplB { };
+
+struct TmplC : Tmpl<int> {
+   TmplC() :
+             Tmpl<int>(),
+             TmplB<int>() { } // expected-error {{type 'TmplB<int>' is not a direct or virtual base of 'TmplC'}}
+};
+
+
+struct TmplD : Tmpl<char>, TmplB<char> {
+    TmplD():
+            Tmpl<int>(), // expected-error {{type 'Tmpl<int>' is not a direct or virtual base of 'TmplD'}}
+            TmplB<char>() {}
+};
+
diff --git a/test/SemaTemplate/class-template-decl.cpp b/test/SemaTemplate/class-template-decl.cpp
new file mode 100644
index 0000000..1be1bc0
--- /dev/null
+++ b/test/SemaTemplate/class-template-decl.cpp
@@ -0,0 +1,58 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T> class A;
+
+extern "C++" {
+  template<typename T> class B;
+}
+
+namespace N {
+  template<typename T> class C;
+}
+
+extern "C" {
+  template<typename T> class D; // expected-error{{templates must have C++ linkage}}
+}
+
+template<class U> class A; // expected-note{{previous template declaration is here}}
+
+template<int N> class A; // expected-error{{template parameter has a different kind in template redeclaration}}
+
+template<int N> class NonTypeTemplateParm;
+
+typedef int INT;
+
+template<INT M> class NonTypeTemplateParm; // expected-note{{previous non-type template parameter with type 'INT' (aka 'int') is here}}
+
+template<long> class NonTypeTemplateParm; // expected-error{{template non-type parameter has a different type 'long' in template redeclaration}}
+
+template<template<typename T> class X> class TemplateTemplateParm;
+
+template<template<class> class Y> class TemplateTemplateParm; // expected-note{{previous template declaration is here}} \
+      // expected-note{{previous template template parameter is here}}
+
+template<typename> class TemplateTemplateParm; // expected-error{{template parameter has a different kind in template redeclaration}}
+
+template<template<typename T, int> class X> class TemplateTemplateParm; // expected-error{{too many template parameters in template template parameter redeclaration}}
+
+template<typename T>
+struct test {}; // expected-note{{previous definition}}
+
+template<typename T>
+struct test : T {}; // expected-error{{redefinition}}
+
+class X {
+public:
+  template<typename T> class C;
+};
+
+void f() {
+  template<typename T> class X; // expected-error{{expression}}
+}
+
+template<typename T> class X1 { } var; // expected-error{{declared as a template}}
+
+namespace M {
+}
+
+template<typename T> class M::C3 { }; // expected-error{{out-of-line definition of 'C3' does not match any declaration in namespace 'M'}}
diff --git a/test/SemaTemplate/class-template-id-2.cpp b/test/SemaTemplate/class-template-id-2.cpp
new file mode 100644
index 0000000..d09f524
--- /dev/null
+++ b/test/SemaTemplate/class-template-id-2.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+namespace N {
+  template<typename T> class A { };
+
+  template<> class A<int> { };
+
+  template<> class A<float>; // expected-note{{forward declaration of 'N::A<float>'}}
+
+  class B : public A<int> { };
+}
+
+class C1 : public N::A<int> { };
+
+class C2 : public N::A<float> { }; // expected-error{{base class has incomplete type}}
+
+struct D1 {
+  operator N::A<int>();
+};
+
+namespace N {
+  struct D2 {
+    operator A<int>();
+  };
+}
diff --git a/test/SemaTemplate/class-template-id.cpp b/test/SemaTemplate/class-template-id.cpp
new file mode 100644
index 0000000..df5ef55
--- /dev/null
+++ b/test/SemaTemplate/class-template-id.cpp
@@ -0,0 +1,43 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename T, typename U = float> struct A { };
+
+typedef A<int> A_int;
+
+typedef float FLOAT;
+
+A<int, FLOAT> *foo(A<int> *ptr, A<int> const *ptr2, A<int, double> *ptr3) {
+  if (ptr)
+    return ptr; // okay
+  else if (ptr2)
+    return ptr2; // expected-error{{cannot initialize return object of type 'A<int, FLOAT> *' with an lvalue of type 'A<int> const *'}}
+  else {
+    return ptr3; // expected-error{{cannot initialize return object of type 'A<int, FLOAT> *' with an lvalue of type 'A<int, double> *'}}
+  }
+}
+
+template<int I> struct B;
+
+const int value = 12;
+B<17 + 2> *bar(B<(19)> *ptr1, B< (::value + 7) > *ptr2, B<19 - 3> *ptr3) {
+  if (ptr1)
+    return ptr1;
+  else if (ptr2)
+    return ptr2;
+  else
+    return ptr3; // expected-error{{cannot initialize return object of type 'B<17 + 2> *' with an lvalue of type 'B<19 - 3>}}
+}
+
+typedef B<5> B5;
+
+
+namespace N {
+  template<typename T> struct C {};
+}
+
+N::C<int> c1;
+typedef N::C<float> c2;
+
+// PR5655
+template<typename T> struct Foo { }; // expected-note{{template is declared here}}
+
+void f(void) { Foo bar; } // expected-error{{without a template argument list}}
diff --git a/test/SemaTemplate/class-template-spec.cpp b/test/SemaTemplate/class-template-spec.cpp
new file mode 100644
index 0000000..c65802e
--- /dev/null
+++ b/test/SemaTemplate/class-template-spec.cpp
@@ -0,0 +1,111 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename T, typename U = int> struct A; // expected-note {{template is declared here}} \
+                                                 // expected-note{{explicitly specialized}}
+
+template<> struct A<double, double>; // expected-note{{forward declaration}}
+
+template<> struct A<float, float> {  // expected-note{{previous definition}}
+  int x;
+};
+
+template<> struct A<float> { // expected-note{{previous definition}}
+  int y;
+};
+
+int test_specs(A<float, float> *a1, A<float, int> *a2) {
+  return a1->x + a2->y;
+}
+
+int test_incomplete_specs(A<double, double> *a1, 
+                          A<double> *a2)
+{
+  (void)a1->x; // expected-error{{member access into incomplete type}}
+  (void)a2->x; // expected-error{{implicit instantiation of undefined template 'A<double, int>'}}
+}
+
+typedef float FLOAT;
+
+template<> struct A<float, FLOAT>;
+
+template<> struct A<FLOAT, float> { }; // expected-error{{redefinition}}
+
+template<> struct A<float, int> { }; // expected-error{{redefinition}}
+
+template<typename T, typename U = int> struct X;
+
+template <> struct X<int, int> { int foo(); }; // #1
+template <> struct X<float> { int bar(); };  // #2
+
+typedef int int_type;
+void testme(X<int_type> *x1, X<float, int> *x2) { 
+  (void)x1->foo(); // okay: refers to #1
+  (void)x2->bar(); // okay: refers to #2
+}
+
+// Make sure specializations are proper classes.
+template<>
+struct A<char> {
+  A();
+};
+
+A<char>::A() { }
+
+// Make sure we can see specializations defined before the primary template.
+namespace N{ 
+  template<typename T> struct A0;
+}
+
+namespace N {
+  template<>
+  struct A0<void> {
+    typedef void* pointer;
+  };
+}
+
+namespace N {
+  template<typename T>
+  struct A0 {
+    void foo(A0<void>::pointer p = 0);
+  };
+}
+
+// Diagnose specialization errors
+struct A<double> { }; // expected-error{{template specialization requires 'template<>'}}
+
+template<> struct ::A<double>;
+
+namespace N {
+  template<typename T> struct B; // expected-note 2{{explicitly specialized}}
+
+  template<> struct ::N::B<char>; // okay
+  template<> struct ::N::B<short>; // okay
+  template<> struct ::N::B<int>; // okay
+
+  int f(int);
+}
+
+template<> struct N::B<int> { }; // okay
+
+template<> struct N::B<float> { }; // expected-error{{originally}}
+
+namespace M {
+  template<> struct ::N::B<short> { }; // expected-error{{class template specialization of 'B' not in a namespace enclosing 'N'}}
+
+  template<> struct ::A<long double>; // expected-error{{originally}}
+}
+
+template<> struct N::B<char> { 
+  int testf(int x) { return f(x); }
+};
+
+// PR5264
+template <typename T> class Foo;
+Foo<int>* v;
+Foo<int>& F() { return *v; }
+template <typename T> class Foo {};
+Foo<int> x;
+
+
+// Template template parameters
+template<template<class T> class Wibble>
+class Wibble<int> { }; // expected-error{{cannot specialize a template template parameter}}
diff --git a/test/SemaTemplate/constructor-template.cpp b/test/SemaTemplate/constructor-template.cpp
new file mode 100644
index 0000000..b6ca72e
--- /dev/null
+++ b/test/SemaTemplate/constructor-template.cpp
@@ -0,0 +1,111 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+struct X0 { // expected-note{{candidate}}
+  X0(int); // expected-note{{candidate}}
+  template<typename T> X0(T); // expected-note {{candidate}}
+  template<typename T, typename U> X0(T*, U*); // expected-note {{candidate}}
+  
+  // PR4761
+  template<typename T> X0() : f0(T::foo) {} // expected-note {{candidate}}
+  int f0;
+};
+
+void accept_X0(X0);
+
+void test_X0(int i, float f) {
+  X0 x0a(i);
+  X0 x0b(f);
+  X0 x0c = i;
+  X0 x0d = f;
+  accept_X0(i);
+  accept_X0(&i);
+  accept_X0(f);
+  accept_X0(&f);
+  X0 x0e(&i, &f);
+  X0 x0f(&f, &i);
+  
+  X0 x0g(f, &i); // expected-error{{no matching constructor}}
+}
+
+template<typename T>
+struct X1 {
+  X1(const X1&);
+  template<typename U> X1(const X1<U>&);
+};
+
+template<typename T>
+struct Outer {
+  typedef X1<T> A;
+  
+  A alloc;
+  
+  explicit Outer(const A& a) : alloc(a) { }
+};
+
+void test_X1(X1<int> xi) {
+  Outer<int> oi(xi);
+  Outer<float> of(xi);
+}
+
+// PR4655
+template<class C> struct A {};
+template <> struct A<int>{A(const A<int>&);};
+struct B { A<int> x; B(B& a) : x(a.x) {} };
+
+struct X2 {
+  X2(); // expected-note{{candidate constructor}}
+  X2(X2&);	// expected-note {{candidate constructor}}
+  template<typename T> X2(T);
+};
+
+X2 test(bool Cond, X2 x2) {
+  if (Cond)
+    return x2; // okay, uses copy constructor
+  
+  return X2(); // expected-error{{no matching constructor}}
+}
+
+struct X3 {
+  template<typename T> X3(T);
+};
+
+template<> X3::X3(X3); // expected-error{{must pass its first argument by reference}}
+
+struct X4 {
+  X4(); // expected-note{{candidate constructor}}
+  ~X4();
+  X4(X4&);	// expected-note {{candidate constructor}}
+  template<typename T> X4(const T&, int = 17);
+};
+
+X4 test_X4(bool Cond, X4 x4) {
+  X4 a(x4, 17); // okay, constructor template
+  X4 b(x4); // okay, copy constructor
+  return X4(); // expected-error{{no matching constructor}}
+}
+
+// Instantiation of a non-dependent use of a constructor
+struct DefaultCtorHasDefaultArg {
+  explicit DefaultCtorHasDefaultArg(int i = 17);
+};
+
+template<typename T>
+void default_ctor_inst() {
+  DefaultCtorHasDefaultArg def;
+}
+
+template void default_ctor_inst<int>();
+
+template<typename T>
+struct X5 {
+  X5();
+  X5(const T &);
+};
+
+struct X6 {
+  template<typename T> X6(T);
+};
+
+void test_X5_X6() {
+  X5<X6> tf;
+  X5<X6> tf2(tf);
+}
diff --git a/test/SemaTemplate/copy-ctor-assign.cpp b/test/SemaTemplate/copy-ctor-assign.cpp
new file mode 100644
index 0000000..ae6dc9c
--- /dev/null
+++ b/test/SemaTemplate/copy-ctor-assign.cpp
@@ -0,0 +1,52 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// Make sure that copy constructors and assignment operators are properly 
+// generated when there is a matching 
+
+// PR5072
+template<typename T>
+struct X {
+  template<typename U> 
+  X(const X<U>& other) 
+    : value(other.value + 1) { } // expected-error{{binary expression}}
+
+  template<typename U> 
+  X& operator=(const X<U>& other)  {
+    value = other.value + 1; // expected-error{{binary expression}}
+    return *this;
+  }
+  
+  T value;
+};
+
+struct Y {};
+
+X<int Y::*> test0(X<int Y::*> x) { return x; }
+X<int> test1(X<long> x) { return x; }
+
+
+X<int> test2(X<int Y::*> x) { 
+  return x; // expected-note{{instantiation}}
+}
+
+void test3(X<int> &x, X<int> xi, X<long> xl, X<int Y::*> xmptr) {
+  x = xi;
+  x = xl;
+  x = xmptr; // expected-note{{instantiation}}
+}
+
+struct X1 {
+  X1 &operator=(const X1&);
+};
+
+template<typename T>
+struct X2 : X1 {
+  template<typename U> X2 &operator=(const U&);
+};
+
+struct X3 : X2<int> {
+};
+
+void test_X2(X3 &to, X3 from) {
+  to = from;
+}
diff --git a/test/SemaTemplate/current-instantiation.cpp b/test/SemaTemplate/current-instantiation.cpp
new file mode 100644
index 0000000..4563748
--- /dev/null
+++ b/test/SemaTemplate/current-instantiation.cpp
@@ -0,0 +1,153 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// This test concerns the identity of dependent types within the
+// canonical type system, specifically focusing on the difference
+// between members of the current instantiation and membmers of an
+// unknown specialization. This considers C++ [temp.type], which
+// specifies type equivalence within a template, and C++0x
+// [temp.dep.type], which defines what it means to be a member of the
+// current instantiation.
+
+template<typename T, typename U>
+struct X0 {
+  typedef T T_type;
+  typedef U U_type;
+
+  void f0(T&); // expected-note{{previous}}
+  void f0(typename X0::U_type&);
+  void f0(typename X0::T_type&); // expected-error{{redecl}}
+
+  void f1(T&); // expected-note{{previous}}
+  void f1(typename X0::U_type&);
+  void f1(typename X0<T, U>::T_type&); // expected-error{{redecl}}
+
+  void f2(T&); // expected-note{{previous}}
+  void f2(typename X0::U_type&);
+  void f2(typename X0<T_type, U_type>::T_type&); // expected-error{{redecl}}
+
+  void f3(T&); // expected-note{{previous}}
+  void f3(typename X0::U_type&);
+  void f3(typename ::X0<T_type, U_type>::T_type&); // expected-error{{redecl}}
+
+  struct X1 {
+    typedef T my_T_type;
+
+    void g0(T&); // expected-note{{previous}}
+    void g0(typename X0::U_type&);
+    void g0(typename X0::T_type&); // expected-error{{redecl}}
+
+    void g1(T&); // expected-note{{previous}}
+    void g1(typename X0::U_type&);
+    void g1(typename X0<T, U>::T_type&); // expected-error{{redecl}}
+    
+    void g2(T&); // expected-note{{previous}}
+    void g2(typename X0::U_type&);
+    void g2(typename X0<T_type, U_type>::T_type&); // expected-error{{redecl}}
+    
+    void g3(T&); // expected-note{{previous}}
+    void g3(typename X0::U_type&);
+    void g3(typename ::X0<T_type, U_type>::T_type&); // expected-error{{redecl}}
+
+    void g4(T&); // expected-note{{previous}}
+    void g4(typename X0::U_type&);
+    void g4(typename X1::my_T_type&); // expected-error{{redecl}}
+
+    void g5(T&); // expected-note{{previous}}
+    void g5(typename X0::U_type&);
+    void g5(typename X0::X1::my_T_type&); // expected-error{{redecl}}
+
+    void g6(T&); // expected-note{{previous}}
+    void g6(typename X0::U_type&);
+    void g6(typename X0<T, U>::X1::my_T_type&); // expected-error{{redecl}}
+
+    void g7(T&); // expected-note{{previous}}
+    void g7(typename X0::U_type&);
+    void g7(typename ::X0<typename X1::my_T_type, U_type>::X1::my_T_type&); // expected-error{{redecl}}
+
+    void g8(T&); // expected-note{{previous}}
+    void g8(typename X0<U, T_type>::T_type&);
+    void g8(typename ::X0<typename X0<T_type, U>::X1::my_T_type, U_type>::X1::my_T_type&); // expected-error{{redecl}}
+  };
+};
+
+
+template<typename T, typename U>
+struct X0<T*, U*> {
+  typedef T T_type;
+  typedef U U_type;
+  typedef T* Tptr;
+  typedef U* Uptr;
+  
+  void f0(T&); // expected-note{{previous}}
+  void f0(typename X0::U_type&);
+  void f0(typename X0::T_type&); // expected-error{{redecl}}
+  
+  void f1(T&); // expected-note{{previous}}
+  void f1(typename X0::U_type&);
+  void f1(typename X0<T*, U*>::T_type&); // expected-error{{redecl}}
+  
+  void f2(T&); // expected-note{{previous}}
+  void f2(typename X0::U_type&);
+  void f2(typename X0<T_type*, U_type*>::T_type&); // expected-error{{redecl}}
+  
+  void f3(T&); // expected-note{{previous}}
+  void f3(typename X0::U_type&);
+  void f3(typename ::X0<T_type*, U_type*>::T_type&); // expected-error{{redecl}}
+
+  void f4(T&); // expected-note{{previous}}
+  void f4(typename X0::U_type&);
+  void f4(typename ::X0<Tptr, Uptr>::T_type&); // expected-error{{redecl}}
+  
+  void f5(X0*); // expected-note{{previous}}
+  void f5(::X0<T, U>*);
+  void f5(::X0<T*, U*>*); // expected-error{{redecl}}
+  
+  struct X2 {
+    typedef T my_T_type;
+    
+    void g0(T&); // expected-note{{previous}}
+    void g0(typename X0::U_type&);
+    void g0(typename X0::T_type&); // expected-error{{redecl}}
+    
+    void g1(T&); // expected-note{{previous}}
+    void g1(typename X0::U_type&);
+    void g1(typename X0<T*, U*>::T_type&); // expected-error{{redecl}}
+    
+    void g2(T&); // expected-note{{previous}}
+    void g2(typename X0::U_type&);
+    void g2(typename X0<T_type*, U_type*>::T_type&); // expected-error{{redecl}}
+    
+    void g3(T&); // expected-note{{previous}}
+    void g3(typename X0::U_type&);
+    void g3(typename ::X0<T_type*, U_type*>::T_type&); // expected-error{{redecl}}
+    
+    void g4(T&); // expected-note{{previous}}
+    void g4(typename X0::U_type&);
+    void g4(typename X2::my_T_type&); // expected-error{{redecl}}
+    
+    void g5(T&); // expected-note{{previous}}
+    void g5(typename X0::U_type&);
+    void g5(typename X0::X2::my_T_type&); // expected-error{{redecl}}
+    
+    void g6(T&); // expected-note{{previous}}
+    void g6(typename X0::U_type&);
+    void g6(typename X0<T*, U*>::X2::my_T_type&); // expected-error{{redecl}}
+    
+    void g7(T&); // expected-note{{previous}}
+    void g7(typename X0::U_type&);
+    void g7(typename ::X0<typename X2::my_T_type*, U_type*>::X2::my_T_type&); // expected-error{{redecl}}
+    
+    void g8(T&); // expected-note{{previous}}
+    void g8(typename X0<U, T_type>::T_type&);
+    void g8(typename ::X0<typename X0<T_type*, U*>::X2::my_T_type*, U_type*>::X2::my_T_type&); // expected-error{{redecl}}
+  };
+};
+
+template<typename T>
+struct X1 {
+  static int *a;
+  void f(float *b) {
+    X1<T>::a = b; // expected-error{{incompatible}}
+    X1<T*>::a = b;
+  }
+};
diff --git a/test/SemaTemplate/deduction.cpp b/test/SemaTemplate/deduction.cpp
new file mode 100644
index 0000000..8d00bb7
--- /dev/null
+++ b/test/SemaTemplate/deduction.cpp
@@ -0,0 +1,100 @@
+// RUN: %clang_cc1 -fsyntax-only %s
+
+// Template argument deduction with template template parameters.
+template<typename T, template<T> class A> 
+struct X0 {
+  static const unsigned value = 0;
+};
+
+template<template<int> class A>
+struct X0<int, A> {
+  static const unsigned value = 1;
+};
+
+template<int> struct X0i;
+template<long> struct X0l;
+int array_x0a[X0<long, X0l>::value == 0? 1 : -1];
+int array_x0b[X0<int, X0i>::value == 1? 1 : -1];
+
+template<typename T, typename U>
+struct is_same {
+  static const bool value = false;
+};
+
+template<typename T>
+struct is_same<T, T> {
+  static const bool value = true;
+};
+
+template<typename T> struct allocator { };
+template<typename T, typename Alloc = allocator<T> > struct vector {};
+
+// Fun with meta-lambdas!
+struct _1 {};
+struct _2 {};
+
+// Replaces all occurrences of _1 with Arg1 and _2 with Arg2 in T.
+template<typename T, typename Arg1, typename Arg2>
+struct Replace {
+  typedef T type;
+};
+
+// Replacement of the whole type.
+template<typename Arg1, typename Arg2>
+struct Replace<_1, Arg1, Arg2> {
+  typedef Arg1 type;
+};
+
+template<typename Arg1, typename Arg2>
+struct Replace<_2, Arg1, Arg2> {
+  typedef Arg2 type;
+};
+
+// Replacement through cv-qualifiers
+template<typename T, typename Arg1, typename Arg2>
+struct Replace<const T, Arg1, Arg2> {
+  typedef typename Replace<T, Arg1, Arg2>::type const type;
+};
+
+// Replacement of templates
+template<template<typename> class TT, typename T1, typename Arg1, typename Arg2>
+struct Replace<TT<T1>, Arg1, Arg2> {
+  typedef TT<typename Replace<T1, Arg1, Arg2>::type> type;
+};
+
+template<template<typename, typename> class TT, typename T1, typename T2,
+         typename Arg1, typename Arg2>
+struct Replace<TT<T1, T2>, Arg1, Arg2> {
+  typedef TT<typename Replace<T1, Arg1, Arg2>::type,
+             typename Replace<T2, Arg1, Arg2>::type> type;
+};
+
+// Just for kicks...
+template<template<typename, typename> class TT, typename T1,
+         typename Arg1, typename Arg2>
+struct Replace<TT<T1, _2>, Arg1, Arg2> {
+  typedef TT<typename Replace<T1, Arg1, Arg2>::type, Arg2> type;
+};
+
+int array0[is_same<Replace<_1, int, float>::type, int>::value? 1 : -1];
+int array1[is_same<Replace<const _1, int, float>::type, const int>::value? 1 : -1];
+int array2[is_same<Replace<vector<_1>, int, float>::type, vector<int> >::value? 1 : -1];
+int array3[is_same<Replace<vector<const _1>, int, float>::type, vector<const int> >::value? 1 : -1];
+int array4[is_same<Replace<vector<int, _2>, double, float>::type, vector<int, float> >::value? 1 : -1];
+
+// PR5911
+template <typename T, int N> void f(const T (&a)[N]);
+int iarr[] = { 1 };
+void test_PR5911() { f(iarr); }
+
+// Must not examine base classes of incomplete type during template argument
+// deduction.
+namespace PR6257 {
+  template <typename T> struct X {
+    template <typename U> X(const X<U>& u);
+  };
+  struct A;
+  void f(A& a);
+  void f(const X<A>& a);
+  void test(A& a) { (void)f(a); }
+}
diff --git a/test/SemaTemplate/default-arguments-cxx0x.cpp b/test/SemaTemplate/default-arguments-cxx0x.cpp
new file mode 100644
index 0000000..0f7ba46
--- /dev/null
+++ b/test/SemaTemplate/default-arguments-cxx0x.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++0x -verify %s
+
+// Test default template arguments for function templates.
+template<typename T = int>
+void f0();
+
+template<typename T>
+void f0();
+
+void g0() {
+  f0(); // okay!
+} 
+
+template<typename T, int N = T::value>
+int &f1(T);
+
+float &f1(...);
+
+struct HasValue {
+  static const int value = 17;
+};
+
+void g1() {
+  float &fr = f1(15);
+  int &ir = f1(HasValue());
+}
diff --git a/test/SemaTemplate/default-arguments.cpp b/test/SemaTemplate/default-arguments.cpp
new file mode 100644
index 0000000..9ea0fc2
--- /dev/null
+++ b/test/SemaTemplate/default-arguments.cpp
@@ -0,0 +1,123 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename T, int N = 2> struct X; // expected-note{{template is declared here}}
+
+X<int, 1> *x1;
+X<int> *x2;
+
+X<> *x3; // expected-error{{too few template arguments for class template 'X'}}
+
+template<typename U = float, int M> struct X;
+
+X<> *x4;
+
+template<typename T = int> struct Z { };
+template struct Z<>;
+
+// PR4362
+template<class T> struct a { };
+template<> struct a<int> { static const bool v = true; };
+
+template<class T, bool = a<T>::v> struct p { }; // expected-error {{no member named 'v'}}
+
+template struct p<bool>; // expected-note {{in instantiation of default argument for 'p<bool>' required here}}
+template struct p<int>;
+
+// PR5187
+template<typename T, typename U>
+struct A;
+
+template<typename T, typename U = T>
+struct A;
+
+template<typename T, typename U>
+struct A {
+  void f(A<T>);
+};
+
+template<typename T>
+struct B { };
+
+template<>
+struct B<void> {
+  typedef B<void*> type;
+};
+
+// Nested default arguments for template parameters.
+template<typename T> struct X1 { };
+
+template<typename T>
+struct X2 {
+  template<typename U = typename X1<T>::type> // expected-error{{no type named}}
+  struct Inner1 { };
+  
+  template<T Value = X1<T>::value> // expected-error{{no member named 'value'}}
+  struct NonType1 { };
+  
+  template<T Value>
+  struct Inner2 { };
+  
+  template<typename U>
+  struct Inner3 {
+    template<typename X = T, typename V = U>
+    struct VeryInner { };
+    
+    template<T Value1 = sizeof(T), T Value2 = sizeof(U), 
+             T Value3 = Value1 + Value2>
+    struct NonType2 { };
+  };
+};
+
+X2<int> x2i;
+X2<int>::Inner1<float> x2iif;
+
+X2<int>::Inner1<> x2bad; // expected-note{{instantiation of default argument}}
+
+X2<int>::NonType1<'a'> x2_nontype1;
+X2<int>::NonType1<> x2_nontype1_bad; // expected-note{{instantiation of default argument}}
+
+// Check multi-level substitution into template type arguments
+X2<int>::Inner3<float>::VeryInner<> vi;
+X2<char>::Inner3<int>::NonType2<> x2_deep_nontype;
+
+template<typename T, typename U>
+struct is_same { static const bool value = false; };
+
+template<typename T>
+struct is_same<T, T> { static const bool value = true; };
+
+int array1[is_same<__typeof__(vi), 
+               X2<int>::Inner3<float>::VeryInner<int, float> >::value? 1 : -1];
+
+int array2[is_same<__typeof(x2_deep_nontype),
+                   X2<char>::Inner3<int>::NonType2<sizeof(char), sizeof(int), 
+                                    sizeof(char)+sizeof(int)> >::value? 1 : -1];
+
+// Template template parameter defaults
+template<template<typename T> class X = X2> struct X3 { };
+int array3[is_same<X3<>, X3<X2> >::value? 1 : -1];
+
+struct add_pointer {
+  template<typename T>
+  struct apply {
+    typedef T* type;
+  };
+};
+
+template<typename T, template<typename> class X = T::template apply>
+  struct X4;
+int array4[is_same<X4<add_pointer>, 
+                   X4<add_pointer, add_pointer::apply> >::value? 1 : -1];
+
+template<int> struct X5 {}; // expected-note{{has a different type 'int'}}
+template<long> struct X5b {};
+template<typename T, 
+         template<T> class B = X5> // expected-error{{template template argument has different}} \
+                                   // expected-note{{previous non-type template parameter}}
+  struct X6 {};
+
+X6<int> x6a;
+X6<long> x6b; // expected-note{{while checking a default template argument}}
+X6<long, X5b> x6c;
+
+
+template<template<class> class X = B<int> > struct X7; // expected-error{{must be a class template}}
diff --git a/test/SemaTemplate/default-expr-arguments-2.cpp b/test/SemaTemplate/default-expr-arguments-2.cpp
new file mode 100644
index 0000000..88cc43d
--- /dev/null
+++ b/test/SemaTemplate/default-expr-arguments-2.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -ast-dump %s 2>&1 | FileCheck %s
+
+// This is a wacky test to ensure that we're actually instantiating
+// the default rguments of the constructor when the function type is
+// otherwise non-dependent.
+namespace PR6733 {
+  template <class T>
+  class bar {
+  public: enum { kSomeConst = 128 };
+    bar(int x = kSomeConst) {}
+  };
+  
+  // CHECK: void f()
+  void f() {
+    // CHECK: bar<int> tmp =
+    // CHECK: CXXDefaultArgExpr{{.*}}'int'
+    bar<int> tmp;
+  }
+}
diff --git a/test/SemaTemplate/default-expr-arguments.cpp b/test/SemaTemplate/default-expr-arguments.cpp
new file mode 100644
index 0000000..7c3525a
--- /dev/null
+++ b/test/SemaTemplate/default-expr-arguments.cpp
@@ -0,0 +1,208 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename T>
+class C { C(int a0 = 0); };
+
+template<>
+C<char>::C(int a0);
+
+struct S { }; // expected-note 3 {{candidate constructor (the implicit copy constructor)}}
+
+template<typename T> void f1(T a, T b = 10) { } // expected-error{{no viable conversion}} \
+// expected-note{{passing argument to parameter 'b' here}}
+
+template<typename T> void f2(T a, T b = T()) { }
+
+template<typename T> void f3(T a, T b = T() + T()); // expected-error{{invalid operands to binary expression ('S' and 'S')}}
+
+void g() {
+  f1(10);
+  f1(S()); // expected-note{{in instantiation of default function argument expression for 'f1<S>' required here}}
+  
+  f2(10);
+  f2(S());
+  
+  f3(10);
+  f3(S()); // expected-note{{in instantiation of default function argument expression for 'f3<S>' required here}}
+}
+
+template<typename T> struct F {
+  F(T t = 10); // expected-error{{no viable conversion}} \
+  // expected-note{{passing argument to parameter 't' here}}
+  void f(T t = 10); // expected-error{{no viable conversion}} \
+  // expected-note{{passing argument to parameter 't' here}}
+};
+
+struct FD : F<int> { };
+
+void g2() {
+  F<int> f;
+  FD fd;
+}
+
+void g3(F<int> f, F<struct S> s) {
+  f.f();
+  s.f(); // expected-note{{in instantiation of default function argument expression for 'f<S>' required here}}
+  
+  F<int> f2;
+  F<S> s2; // expected-note{{in instantiation of default function argument expression for 'F<S>' required here}}
+}
+
+template<typename T> struct G {
+  G(T) {}
+};
+
+void s(G<int> flags = 10) { }
+
+// Test default arguments
+template<typename T>
+struct X0 {
+  void f(T = T()); // expected-error{{no matching}}
+};
+
+template<typename U>
+void X0<U>::f(U) { }
+
+void test_x0(X0<int> xi) {
+  xi.f();
+  xi.f(17);
+}
+
+struct NotDefaultConstructible { // expected-note 2{{candidate}}
+  NotDefaultConstructible(int); // expected-note 2{{candidate}}
+};
+
+void test_x0_not_default_constructible(X0<NotDefaultConstructible> xn) {
+  xn.f(NotDefaultConstructible(17));
+  xn.f(42);
+  xn.f(); // expected-note{{in instantiation of default function argument}}
+}
+
+template<typename T>
+struct X1 {
+  typedef T value_type;
+  X1(const value_type& value = value_type());
+};
+
+void test_X1() {
+  X1<int> x1;
+}
+
+template<typename T>
+struct X2 {
+  void operator()(T = T()); // expected-error{{no matching}}
+};
+
+void test_x2(X2<int> x2i, X2<NotDefaultConstructible> x2n) {
+  x2i();
+  x2i(17);
+  x2n(NotDefaultConstructible(17));
+  x2n(); // expected-note{{in instantiation of default function argument}}
+}
+
+// PR5283
+namespace PR5283 {
+template<typename T> struct A {
+  A(T = 1); // expected-error 3 {{cannot initialize a parameter of type 'int *' with an rvalue of type 'int'}} \
+  // expected-note 3{{passing argument to parameter here}}
+};
+
+struct B : A<int*> { 
+  B();
+};
+B::B() { } // expected-note {{in instantiation of default function argument expression for 'A<int *>' required he}}
+
+struct C : virtual A<int*> {
+  C();
+};
+C::C() { } // expected-note {{in instantiation of default function argument expression for 'A<int *>' required he}}
+
+struct D {
+  D();
+  
+  A<int*> a;
+};
+D::D() { } // expected-note {{in instantiation of default function argument expression for 'A<int *>' required he}}
+}
+
+// PR5301
+namespace pr5301 {
+  void f(int, int = 0);
+
+  template <typename T>
+  void g(T, T = 0);
+
+  template <int I>
+  void i(int a = I);
+
+  template <typename T>
+  void h(T t) {
+    f(0);
+    g(1);
+    g(t);
+    i<2>();
+  }
+
+  void test() {
+    h(0);
+  }
+}
+
+// PR5810
+namespace PR5810 {
+  template<typename T>
+  struct allocator {
+    allocator() { int a[sizeof(T) ? -1 : -1]; } // expected-error2 {{array size is negative}}
+  };
+  
+  template<typename T>
+  struct vector {
+    vector(const allocator<T>& = allocator<T>()) {} // expected-note2 {{instantiation of}}
+  };
+  
+  struct A { };
+  struct B { };
+
+  template<typename>
+  void FilterVTs() {
+    vector<A> Result;
+  }
+  
+  void f() {
+    vector<A> Result;
+  }
+
+  template<typename T>
+  struct X {
+    vector<B> bs;
+    X() { }
+  };
+
+  void f2() {
+    X<float> x; // expected-note{{member function}}
+  }
+}
+
+template<typename T> void f4(T, int = 17);
+template<> void f4<int>(int, int);
+
+void f4_test(int i) {
+  f4(i);
+}
+
+// Instantiate for initialization
+namespace InstForInit {
+  template<typename T>
+  struct Ptr {
+    typedef T* type;
+    Ptr(type);
+  };
+
+  template<typename T>
+  struct Holder {
+    Holder(int i, Ptr<T> ptr = 0);
+  };
+
+  void test_holder(int i) {
+    Holder<int> h(i);
+  }
+};
diff --git a/test/SemaTemplate/dependent-base-classes.cpp b/test/SemaTemplate/dependent-base-classes.cpp
new file mode 100644
index 0000000..d0dd9c9
--- /dev/null
+++ b/test/SemaTemplate/dependent-base-classes.cpp
@@ -0,0 +1,135 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T, typename U>
+struct X0 : T::template apply<U> { 
+  X0(U u) : T::template apply<U>(u) { }
+};
+
+template<typename T, typename U>
+struct X1 : T::apply<U> { }; // expected-error{{missing 'template' keyword prior to dependent template name 'T::apply'}}
+
+template<typename T>
+struct X2 : vector<T> { }; // expected-error{{unknown template name 'vector'}}
+
+namespace PR6031 {
+  template<typename T>
+  struct A;
+
+  template <class X>
+  struct C { };
+
+  template <class TT>
+  struct II {
+    typedef typename A<TT>::type type;
+  };
+
+  template <class TT>
+  struct FI : II<TT>
+  {
+    C<typename FI::type> a;
+  };
+
+  template <class TT>
+  struct FI2
+  {
+    C<typename FI2::type> a; // expected-error{{no type named 'type' in 'FI2<TT>'}} \
+        // expected-error{{C++ requires a type specifier for all declarations}}
+  };
+
+  template<typename T>
+  struct Base {
+    class Nested { };
+    template<typename U> struct MemberTemplate { };
+    int a;
+  };
+
+  template<typename T>
+  struct HasDepBase : Base<T> {
+    int foo() {
+      class HasDepBase::Nested nested;
+      typedef typename HasDepBase::template MemberTemplate<T>::type type;
+      return HasDepBase::a;
+    }
+  };
+
+  template<typename T>
+  struct NoDepBase {
+    int foo() {
+      class NoDepBase::Nested nested; // expected-error{{no class named 'Nested' in 'NoDepBase<T>'}}
+      typedef typename NoDepBase::template MemberTemplate<T>::type type; // expected-error{{'MemberTemplate' following the 'template' keyword does not refer to a template}} \
+      // FIXME: expected-error{{unqualified-id}}
+      return NoDepBase::a; // expected-error{{no member named 'a' in 'NoDepBase<T>'}}
+    }
+  };
+}
+
+namespace Ambig {
+  template<typename T>
+  struct Base1 {
+    typedef int type; // expected-note{{member found by ambiguous name lookup}}
+  };
+
+  struct Base2 {
+    typedef float type; // expected-note{{member found by ambiguous name lookup}}
+  };
+
+  template<typename T>
+  struct Derived : Base1<T>, Base2 {
+    typedef typename Derived::type type; // expected-error{{member 'type' found in multiple base classes of different types}}
+    type *foo(float *fp) { return fp; }
+  };
+
+  Derived<int> di; // expected-note{{instantiation of}}
+}
+
+namespace PR6081 {
+  template<typename T>
+  struct A { };
+
+  template<typename T>
+  class B : public A<T> 
+  {
+  public:
+    template< class X >
+    void f0(const X & k)
+    {
+      this->template f1<int>()(k);
+    }
+  };
+
+  template<typename T>
+  class C
+  {
+  public:
+    template< class X >
+    void f0(const X & k)
+    {
+      this->template f1<int>()(k); // expected-error{{'f1' following the 'template' keyword does not refer to a template}} \
+      // FIXME: expected-error{{unqualified-id}}
+    }
+  };
+}
+
+namespace PR6413 {
+  template <typename T> class Base_A { };
+  
+  class Base_B { };
+  
+  template <typename T>
+  class Derived
+    : public virtual Base_A<T>
+    , public virtual Base_B
+  { };
+}
+
+namespace PR5812 {
+  template <class T> struct Base { 
+    Base* p; 
+  }; 
+
+  template <class T> struct Derived: public Base<T> { 
+    typename Derived::Base* p; // meaning Derived::Base<T> 
+  };
+
+  Derived<int> di;
+}
diff --git a/test/SemaTemplate/dependent-base-member-init.cpp b/test/SemaTemplate/dependent-base-member-init.cpp
new file mode 100644
index 0000000..1f13149
--- /dev/null
+++ b/test/SemaTemplate/dependent-base-member-init.cpp
@@ -0,0 +1,59 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// PR4381
+template<class T> struct X {};
+template<typename T> struct Y : public X<T>::X { };
+
+// PR4621
+class A1 {
+  A1(int x) {}
+};
+template<class C> class B1 : public A1 {
+  B1(C x) : A1(x.x) {}
+};
+class A2 { A2(int x, int y); };
+template <class C> class B2 {
+  A2 x;
+  B2(C x) : x(x.x, x.y) {}
+};
+template <class C> class B3 {
+  C x;
+  B3() : x(1,2) {}
+};
+
+// PR4627
+template<typename _Container> class insert_iterator {
+    _Container* container;
+    insert_iterator(_Container& __x) : container(&__x) {}
+};
+
+// PR4763
+template<typename T> struct s0 {};
+template<typename T> struct s0_traits {};
+template<typename T> struct s1 : s0<typename s0_traits<T>::t0> {
+  s1() {}
+};
+
+// PR6062
+namespace PR6062 {
+  template <typename T>
+  class A : public T::type
+  {
+    A() : T::type()
+    {  
+    }
+    
+    template <typename U>
+    A(U const& init)
+      : T::type(init)
+    { }
+
+    template<typename U>
+    A(U& init) : U::other_type(init) { }
+  };
+}
+
+template<typename T, typename U>
+struct X0 : T::template apply<U> {
+  X0(int i) : T::template apply<U>(i) { }
+};
diff --git a/test/SemaTemplate/dependent-expr.cpp b/test/SemaTemplate/dependent-expr.cpp
new file mode 100644
index 0000000..3f481b5
--- /dev/null
+++ b/test/SemaTemplate/dependent-expr.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// PR5908
+template <typename Iterator>
+void Test(Iterator it) {
+  *(it += 1);
+}
+
+namespace PR6045 {
+  template<unsigned int r>
+  class A
+  {
+    static const unsigned int member = r;
+    void f();
+  };
+  
+  template<unsigned int r>
+  const unsigned int A<r>::member;
+  
+  template<unsigned int r>
+  void A<r>::f() 
+  {
+    unsigned k;
+    (void)(k % member);
+  }
+}
diff --git a/test/SemaTemplate/dependent-names.cpp b/test/SemaTemplate/dependent-names.cpp
new file mode 100644
index 0000000..7796106
--- /dev/null
+++ b/test/SemaTemplate/dependent-names.cpp
@@ -0,0 +1,104 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s 
+
+typedef double A;
+template<typename T> class B {
+  typedef int A;
+};
+
+template<typename T> struct X : B<T> {
+  static A a;
+};
+
+int a0[sizeof(X<int>::a) == sizeof(double) ? 1 : -1];
+
+// PR4365.
+template<class T> class Q;
+template<class T> class R : Q<T> {T current;};
+
+
+namespace test0 {
+  template <class T> class Base {
+  public:
+    void instance_foo();
+    static void static_foo();
+    class Inner {
+    public:
+      void instance_foo();
+      static void static_foo();
+    };
+  };
+
+  template <class T> class Derived1 : Base<T> {
+  public:
+    void test0() {
+      Base<T>::static_foo();
+      Base<T>::instance_foo();
+    }
+
+    void test1() {
+      Base<T>::Inner::static_foo();
+      Base<T>::Inner::instance_foo(); // expected-error {{call to non-static member function without an object argument}}
+    }
+
+    static void test2() {
+      Base<T>::static_foo();
+      Base<T>::instance_foo(); // expected-error {{call to non-static member function without an object argument}}
+    }
+
+    static void test3() {
+      Base<T>::Inner::static_foo();
+      Base<T>::Inner::instance_foo(); // expected-error {{call to non-static member function without an object argument}}
+    }
+  };
+
+  template <class T> class Derived2 : Base<T>::Inner {
+  public:
+    void test0() {
+      Base<T>::static_foo();
+      Base<T>::instance_foo(); // expected-error {{call to non-static member function without an object argument}}
+    }
+
+    void test1() {
+      Base<T>::Inner::static_foo();
+      Base<T>::Inner::instance_foo();
+    }
+
+    static void test2() {
+      Base<T>::static_foo();
+      Base<T>::instance_foo(); // expected-error {{call to non-static member function without an object argument}}
+    }
+
+    static void test3() {
+      Base<T>::Inner::static_foo();
+      Base<T>::Inner::instance_foo(); // expected-error {{call to non-static member function without an object argument}}
+    }
+  };
+
+  void test0() {
+    Derived1<int> d1;
+    d1.test0();
+    d1.test1(); // expected-note {{in instantiation of member function}}
+    d1.test2(); // expected-note {{in instantiation of member function}}
+    d1.test3(); // expected-note {{in instantiation of member function}}
+
+    Derived2<int> d2;
+    d2.test0(); // expected-note {{in instantiation of member function}}
+    d2.test1();
+    d2.test2(); // expected-note {{in instantiation of member function}}
+    d2.test3(); // expected-note {{in instantiation of member function}}
+  }
+}
+
+namespace test1 {
+  template <class T> struct Base {
+    void foo(T); // expected-note {{must qualify identifier to find this declaration in dependent base class}}
+  };
+
+  template <class T> struct Derived : Base<T> {
+    void doFoo(T v) {
+      foo(v); // expected-error {{use of undeclared identifier}}
+    }
+  };
+
+  template struct Derived<int>; // expected-note {{requested here}}
+}
diff --git a/test/SemaTemplate/dependent-sized_array.cpp b/test/SemaTemplate/dependent-sized_array.cpp
new file mode 100644
index 0000000..cf0e0f3
--- /dev/null
+++ b/test/SemaTemplate/dependent-sized_array.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -fsyntax-only -pedantic -verify %s
+
+template<int N>
+void f() {
+  int a[] = { 1, 2, 3, N };
+  unsigned numAs = sizeof(a) / sizeof(int);
+}
+
+template void f<17>();
+
+
+template<int N>
+void f1() {
+  int a0[] = {}; // expected-warning{{zero}}
+  int a1[] = { 1, 2, 3, N };
+  int a3[sizeof(a1)/sizeof(int) != 4? 1 : -1]; // expected-error{{negative}}
+}
diff --git a/test/SemaTemplate/dependent-type-identity.cpp b/test/SemaTemplate/dependent-type-identity.cpp
new file mode 100644
index 0000000..e095812
--- /dev/null
+++ b/test/SemaTemplate/dependent-type-identity.cpp
@@ -0,0 +1,72 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// This test concerns the identity of dependent types within the
+// canonical type system. This corresponds to C++ [temp.type], which
+// specifies type equivalence within a template.
+//
+// FIXME: template template parameters
+
+namespace N {
+  template<typename T>
+  struct X2 {
+    template<typename U>
+    struct apply {
+      typedef U* type;
+    };
+  };
+}
+
+namespace Nalias = N;
+
+template<typename T>
+struct X0 { };
+
+using namespace N;
+
+template<typename T, typename U>
+struct X1 {
+  typedef T type;
+  typedef U U_type;
+
+  void f0(T); // expected-note{{previous}}
+  void f0(U);
+  void f0(type); // expected-error{{redeclar}}
+
+  void f1(T*); // expected-note{{previous}}
+  void f1(U*);
+  void f1(type*); // expected-error{{redeclar}}
+
+  void f2(X0<T>*); // expected-note{{previous}}
+  void f2(X0<U>*);
+  void f2(X0<type>*); // expected-error{{redeclar}}
+
+  void f3(X0<T>*); // expected-note{{previous}}
+  void f3(X0<U>*);
+  void f3(::X0<type>*); // expected-error{{redeclar}}  
+
+  void f4(typename T::template apply<U>*); // expected-note{{previous}}
+  void f4(typename U::template apply<U>*);
+  void f4(typename type::template apply<T>*);
+  void f4(typename type::template apply<U_type>*); // expected-error{{redeclar}}
+
+  void f5(typename T::template apply<U>::type*); // expected-note{{previous}}
+  void f5(typename U::template apply<U>::type*);
+  void f5(typename U::template apply<T>::type*);
+  void f5(typename type::template apply<T>::type*);
+  void f5(typename type::template apply<U_type>::type*); // expected-error{{redeclar}}
+
+  void f6(typename N::X2<T>::template apply<U> *); // expected-note{{previous}}
+  void f6(typename N::X2<U>::template apply<U> *);
+  void f6(typename N::X2<U>::template apply<T> *);
+  void f6(typename ::N::X2<type>::template apply<U_type> *); // expected-error{{redeclar}}
+  
+  void f7(typename N::X2<T>::template apply<U> *); // expected-note{{previous}}
+  void f7(typename N::X2<U>::template apply<U> *);
+  void f7(typename N::X2<U>::template apply<T> *);
+  void f7(typename X2<type>::template apply<U_type> *); // expected-error{{redeclar}}
+
+  void f8(typename N::X2<T>::template apply<U> *); // expected-note{{previous}}
+  void f8(typename N::X2<U>::template apply<U> *);
+  void f8(typename N::X2<U>::template apply<T> *);
+  void f8(typename ::Nalias::X2<type>::template apply<U_type> *); // expected-error{{redeclar}}
+};
diff --git a/test/SemaTemplate/destructor-template.cpp b/test/SemaTemplate/destructor-template.cpp
new file mode 100644
index 0000000..fa1b3e0
--- /dev/null
+++ b/test/SemaTemplate/destructor-template.cpp
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename A> class s0 {
+
+  template<typename B> class s1 : public s0<A> {
+    ~s1() {}
+    s0<A> ms0;
+  };
+
+};
+
+struct Incomplete;
+
+template<typename T>
+void destroy_me(T me) {
+  me.~T();
+}
+
+template void destroy_me(Incomplete*);
+
+namespace PR6152 {
+  template<typename T> struct X { void f(); };
+  template<typename T> struct Y { };
+  template<typename T>
+  void X<T>::f() {
+    Y<T> *y;
+    y->template Y<T>::~Y();
+    y->template Y<T>::~Y<T>();
+    y->~Y();
+  }
+  
+  template struct X<int>;
+}
+
+namespace cvquals {
+  template<typename T>
+  void f(int *ptr) {
+    ptr->~T();
+  }
+
+  template void f<const volatile int>(int *);
+}
diff --git a/test/SemaTemplate/elaborated-type-specifier.cpp b/test/SemaTemplate/elaborated-type-specifier.cpp
new file mode 100644
index 0000000..b34660a
--- /dev/null
+++ b/test/SemaTemplate/elaborated-type-specifier.cpp
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace PR6915 {
+  template <typename T>
+  class D {
+    enum T::X v; // expected-error{{use of 'X' with tag type that does not match previous declaration}} \
+    // expected-error{{no enum named 'X' in 'PR6915::D3'}}
+  };
+
+  struct D1 {
+    enum X { value };
+  };
+  struct D2 { 
+    class X { }; // expected-note{{previous use is here}}
+  };
+  struct D3 { };
+
+  template class D<D1>;
+  template class D<D2>; // expected-note{{in instantiation of}}
+  template class D<D3>; // expected-note{{in instantiation of}}
+}
+
+template<typename T>
+struct DeclOrDef {
+  enum T::foo; // expected-error{{nested name specifier for a declaration cannot depend on a template parameter}}
+  enum T::bar { // expected-error{{nested name specifier for a declaration cannot depend on a template parameter}}
+    value 
+  };
+};
+
+namespace PR6649 {
+  template <typename T> struct foo { 
+    class T::bar;  // expected-error{{nested name specifier for a declaration cannot depend on a template parameter}}
+    class T::bar { int x; }; // expected-error{{nested name specifier for a declaration cannot depend on a template parameter}}
+  };
+}
diff --git a/test/SemaTemplate/enum-argument.cpp b/test/SemaTemplate/enum-argument.cpp
new file mode 100644
index 0000000..de89487
--- /dev/null
+++ b/test/SemaTemplate/enum-argument.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+enum Enum { val = 1 };
+template <Enum v> struct C {
+  typedef C<v> Self;
+};
+template struct C<val>;
+
+template<typename T>
+struct get_size {
+  static const unsigned value = sizeof(T);
+};
+
+template<typename T>
+struct X0 {
+  enum {
+    Val1 = get_size<T>::value,
+    Val2,
+    SumOfValues = Val1 + Val2
+  };
+};
+
+X0<int> x0i;
diff --git a/test/SemaTemplate/example-dynarray.cpp b/test/SemaTemplate/example-dynarray.cpp
new file mode 100644
index 0000000..1f6ede6
--- /dev/null
+++ b/test/SemaTemplate/example-dynarray.cpp
@@ -0,0 +1,177 @@
+// RUN: %clang -emit-llvm -S -o %t %s
+#include <stddef.h>
+#include <stdlib.h>
+#include <assert.h>
+
+// Placement new requires <new> to be included, but we don't support that yet.
+void* operator new(size_t, void* ptr) throw() {
+  return ptr;
+}
+void operator delete(void*, void*) throw() {
+}
+
+template<typename T>
+class dynarray {
+public:
+  dynarray() { Start = Last = End = 0; }
+
+  dynarray(const dynarray &other) {
+    Start = (T*)malloc(sizeof(T) * other.size());
+    Last = End = Start + other.size();
+
+    for (unsigned I = 0, N = other.size(); I != N; ++I)
+      new (Start + I) T(other[I]);
+  }
+  
+  ~dynarray() {
+    for (unsigned I = 0, N = size(); I != N; ++I)
+      Start[I].~T();
+    
+    free(Start);
+  }
+
+  dynarray &operator=(const dynarray &other) {
+    T* NewStart = (T*)malloc(sizeof(T) * other.size());
+
+    for (unsigned I = 0, N = other.size(); I != N; ++I)
+      new (NewStart + I) T(other[I]);
+
+    for (unsigned I = 0, N = size(); I != N; ++I)
+      Start[I].~T();
+    
+    free(Start);
+    Start = NewStart;
+    Last = End = NewStart + other.size();
+    return *this;
+  }
+
+  unsigned size() const { return Last - Start; }
+  unsigned capacity() const { return End - Start; }
+
+  void push_back(const T& value);
+  
+  void pop_back() {
+    --Last;
+    Last->~T();
+  }
+
+  T& operator[](unsigned Idx) {
+    return Start[Idx];
+  }
+
+  const T& operator[](unsigned Idx) const {
+    return Start[Idx];
+  }
+
+  typedef T* iterator;
+  typedef const T* const_iterator;
+
+  iterator begin() { return Start; }
+  const_iterator begin() const { return Start; }
+  
+  iterator end() { return Last; }
+  const_iterator end() const { return Last; }
+  
+  bool operator==(const dynarray &other) const {
+    if (size() != other.size())
+      return false;
+    
+    for (unsigned I = 0, N = size(); I != N; ++I)
+      if ((*this)[I] != other[I])
+        return false;
+    
+    return true;
+  }
+  
+  bool operator!=(const dynarray &other) const {
+    return !(*this == other);
+  }
+  
+public:
+  T* Start, *Last, *End;
+};
+
+template<typename T>
+void dynarray<T>::push_back(const T& value) {
+  if (Last == End) {
+    unsigned NewCapacity = capacity() * 2;
+    if (NewCapacity == 0)
+      NewCapacity = 4;
+    
+    T* NewStart = (T*)malloc(sizeof(T) * NewCapacity);
+    
+    unsigned Size = size();
+    for (unsigned I = 0; I != Size; ++I)
+      new (NewStart + I) T(Start[I]);
+    
+    for (unsigned I = 0, N = size(); I != N; ++I)
+      Start[I].~T();
+    free(Start);
+    
+    Start = NewStart;
+    Last = Start + Size;
+    End = Start + NewCapacity;
+  }
+  
+  new (Last) T(value);
+  ++Last;
+}
+
+struct Point { 
+  Point() { x = y = z = 0.0; }
+  Point(const Point& other) : x(other.x), y(other.y), z(other.z) { }
+
+  float x, y, z;
+};
+
+int main() {
+  dynarray<int> di;
+  di.push_back(0);
+  di.push_back(1);
+  di.push_back(2);
+  di.push_back(3);
+  di.push_back(4);
+  assert(di.size() == 5);
+  for (dynarray<int>::iterator I = di.begin(), IEnd = di.end(); I != IEnd; ++I)
+    assert(*I == I - di.begin());
+
+  for (int I = 0, N = di.size(); I != N; ++I)
+    assert(di[I] == I);
+
+  di.pop_back();
+  assert(di.size() == 4);
+  di.push_back(4);
+
+  dynarray<int> di2 = di;
+  assert(di2.size() == 5);
+  assert(di.begin() != di2.begin());
+  for (dynarray<int>::iterator I = di2.begin(), IEnd = di2.end(); 
+       I != IEnd; ++I)
+    assert(*I == I - di2.begin());
+
+  dynarray<int> di3(di);
+  assert(di3.size() == 5);
+  assert(di.begin() != di3.begin());
+  for (dynarray<int>::iterator I = di3.begin(), IEnd = di3.end(); 
+       I != IEnd; ++I)
+    assert(*I == I - di3.begin());
+
+  dynarray<int> di4;
+  assert(di4.size() == 0);
+  di4 = di;
+  assert(di4.size() == 5);
+  assert(di.begin() != di4.begin());
+  for (dynarray<int>::iterator I = di4.begin(), IEnd = di4.end(); 
+       I != IEnd; ++I)
+    assert(*I == I - di4.begin());
+
+  assert(di4 == di);
+  di4[3] = 17;
+  assert(di4 != di);
+  
+  dynarray<Point> dp;
+  dp.push_back(Point());
+  assert(dp.size() == 1);
+  
+  return 0;
+}
diff --git a/test/SemaTemplate/example-typelist.cpp b/test/SemaTemplate/example-typelist.cpp
new file mode 100644
index 0000000..082aeb8
--- /dev/null
+++ b/test/SemaTemplate/example-typelist.cpp
@@ -0,0 +1,98 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// A simple cons-style typelist
+struct nil { };
+
+template<typename Head, typename Tail = nil>
+struct cons { 
+  typedef Head head;
+  typedef Tail tail;
+};
+
+// is_same trait, for testing
+template<typename T, typename U>
+struct is_same {
+  static const bool value = false;
+};
+
+template<typename T>
+struct is_same<T, T> {
+  static const bool value = true;
+};
+
+// metaprogram that computes the length of a list
+template<typename T> struct length;
+
+template<typename Head, typename Tail>
+struct length<cons<Head, Tail> > {
+  static const unsigned value = length<Tail>::value + 1;
+};
+
+template<>
+struct length<nil> {
+  static const unsigned value = 0;
+};
+
+typedef cons<unsigned char, 
+             cons<unsigned short, 
+                  cons<unsigned int,
+                       cons<unsigned long> > > > unsigned_inttypes;
+int length0[length<unsigned_inttypes>::value == 4? 1 : -1];
+
+// metaprogram that reverses a list
+
+// FIXME: I would prefer that this be a partial specialization, but
+// that requires partial ordering of class template partial
+// specializations.
+template<typename T> 
+class reverse {
+  typedef typename reverse<typename T::tail>::type reversed_tail;
+
+  typedef typename reverse<typename reversed_tail::tail>::type most_of_tail;
+
+public:
+  typedef cons<typename reversed_tail::head,
+               typename reverse<cons<typename T::head, most_of_tail> >::type> type;
+};
+
+template<typename Head>
+class reverse<cons<Head> > {
+public:
+  typedef cons<Head> type;
+};
+
+template<>
+class reverse<nil> {
+public:
+  typedef nil type;
+};
+
+int reverse0[is_same<reverse<unsigned_inttypes>::type,
+                     cons<unsigned long, 
+                          cons<unsigned int, 
+                               cons<unsigned short,
+                                    cons<unsigned char> > > > >::value? 1 : -1];
+
+// metaprogram that finds a type within a list
+
+// FIXME: I would prefer that this be a partial specialization, but
+// that requires partial ordering of class template partial
+// specializations.
+template<typename List, typename T>
+struct find : find<typename List::tail, T> { };
+
+template<typename Tail, typename T>
+struct find<cons<T, Tail>, T> {
+  typedef cons<T, Tail> type;
+};
+
+template<typename T>
+struct find<nil, T> {
+  typedef nil type;
+};
+
+int find0[is_same<find<unsigned_inttypes, unsigned int>::type,
+                       cons<unsigned int, cons<unsigned long> > >::value?
+             1 : -1];
+int find1[is_same<find<unsigned_inttypes, int>::type, nil>::value? 1 : -1];
+
diff --git a/test/SemaTemplate/explicit-instantiation.cpp b/test/SemaTemplate/explicit-instantiation.cpp
new file mode 100644
index 0000000..de51f09
--- /dev/null
+++ b/test/SemaTemplate/explicit-instantiation.cpp
@@ -0,0 +1,85 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template void *; // expected-error{{expected unqualified-id}}
+
+template typedef void f0; // expected-error{{explicit instantiation of typedef}}
+
+int v0; // expected-note{{refers here}}
+template int v0; // expected-error{{does not refer}}
+
+template<typename T>
+struct X0 {
+  static T value;
+  
+  T f0(T x) {
+    return x + 1;  // expected-error{{invalid operands}}
+  } 
+  T* f0(T*, T*) { return T(); }
+  
+  template<typename U>
+  T f0(T, U) { return T(); }
+};
+
+template<typename T>
+T X0<T>::value; // expected-error{{no matching constructor}}
+
+template int X0<int>::value;
+
+struct NotDefaultConstructible { // expected-note{{candidate constructor (the implicit copy constructor)}}
+  NotDefaultConstructible(int); // expected-note{{candidate constructor}}
+};
+
+template NotDefaultConstructible X0<NotDefaultConstructible>::value; // expected-note{{instantiation}}
+
+template int X0<int>::f0(int);
+template int* X0<int>::f0(int*, int*);
+template int X0<int>::f0(int, float);
+
+template int X0<int>::f0(int) const; // expected-error{{does not refer}}
+template int* X0<int>::f0(int*, float*); // expected-error{{does not refer}}
+
+struct X1 { };
+typedef int X1::*MemPtr;
+
+template MemPtr X0<MemPtr>::f0(MemPtr); // expected-note{{requested here}}
+
+struct X2 {
+  int f0(int); // expected-note{{refers here}}
+  
+  template<typename T> T f1(T) { return T(); }
+  template<typename T> T* f1(T*) { return 0; }
+
+  template<typename T, typename U> void f2(T, U*) { } // expected-note{{candidate}}
+  template<typename T, typename U> void f2(T*, U) { } // expected-note{{candidate}}
+};
+
+template int X2::f0(int); // expected-error{{not an instantiation}}
+
+template int *X2::f1(int *); // okay
+
+template void X2::f2(int *, int *); // expected-error{{ambiguous}}
+
+
+template<typename T> void print_type() { }
+
+template void print_type<int>();
+template void print_type<float>();
+
+template<typename T> void print_type(T*) { }
+
+template void print_type(int*);
+template void print_type<int>(float*); // expected-error{{does not refer}}
+
+void print_type(double*);
+template void print_type<double>(double*);
+
+// PR5069
+template<int I> void foo0 (int (&)[I + 1]) { }
+template void foo0<2> (int (&)[3]);
+
+namespace explicit_instantiation_after_implicit_instantiation {
+  template <int I> struct X0 { static int x; };
+  template <int I> int X0<I>::x;
+  void test1() { (void)&X0<1>::x; }
+  template struct X0<1>;
+}
diff --git a/test/SemaTemplate/explicit-specialization-member.cpp b/test/SemaTemplate/explicit-specialization-member.cpp
new file mode 100644
index 0000000..417cdc1
--- /dev/null
+++ b/test/SemaTemplate/explicit-specialization-member.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename T>
+struct X0 {
+  typedef T* type;
+  
+  void f0(T);
+  void f1(type);
+};
+
+template<> void X0<char>::f0(char);
+template<> void X0<char>::f1(type);
+
+namespace PR6161 {
+  template<typename _CharT>
+  class numpunct : public locale::facet // expected-error{{use of undeclared identifier 'locale'}} \
+              // expected-error{{expected class name}} \
+  // expected-note{{attempt to specialize declaration here}}
+  {
+    static locale::id id; // expected-error{{use of undeclared identifier}}
+  };
+  numpunct<char>::~numpunct(); // expected-error{{template specialization requires 'template<>'}} \
+  // expected-error{{specialization of member 'PR6161::numpunct<char>::~numpunct' does not specialize an instantiated member}}
+}
diff --git a/test/SemaTemplate/ext-vector-type.cpp b/test/SemaTemplate/ext-vector-type.cpp
new file mode 100644
index 0000000..3973102
--- /dev/null
+++ b/test/SemaTemplate/ext-vector-type.cpp
@@ -0,0 +1,60 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename T, unsigned Length> 
+struct make1 { 
+  typedef T __attribute__((ext_vector_type(Length))) type; 
+};
+
+void test_make1() {
+  make1<int, 5>::type x;
+  x.x = 4;
+}
+
+template<typename T, unsigned Length> 
+struct make2 { 
+  typedef T __attribute__((ext_vector_type(Length))) type; // expected-error{{zero vector size}}
+};
+
+int test_make2() {
+  make2<int, 0> x; // expected-note{{in instantiation of}} 
+}
+
+template<typename T, unsigned Length> 
+struct make3 { 
+  typedef T __attribute__((ext_vector_type(Length))) type; // expected-error{{invalid vector type 's'}}
+};
+
+struct s {};
+
+int test_make3() {
+  make3<s, 3>x; // expected-note{{in instantiation of}} 
+}
+
+template<typename T, T Length> 
+struct make4 { 
+  typedef T __attribute__((ext_vector_type(Length))) type; 
+};
+
+int test_make4() {
+  make4<int, 4>::type x;
+  x.w = 7;
+}
+
+typedef int* int_ptr;
+template<unsigned Length>
+struct make5 {
+  typedef int_ptr __attribute__((ext_vector_type(Length))) type; // expected-error{{invalid vector type}}             
+};
+
+template<int Length>
+struct make6 {
+  typedef int __attribute__((ext_vector_type(Length))) type;
+};
+
+int test_make6() {
+  make6<4>::type x;
+  x.w = 7;
+
+  make6<2>::type y;
+  y.x = -1;
+  y.w = -1; // expected-error{{vector component access exceeds type}}
+}
diff --git a/test/SemaTemplate/extern-templates.cpp b/test/SemaTemplate/extern-templates.cpp
new file mode 100644
index 0000000..eca64ed
--- /dev/null
+++ b/test/SemaTemplate/extern-templates.cpp
@@ -0,0 +1,64 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T>
+class X0 {
+public:
+  void f(T t);
+  
+  struct Inner {
+    void g(T t);
+  };
+};
+
+template<typename T>
+void X0<T>::f(T t) {
+  t = 17; // expected-error{{incompatible}}
+}
+
+extern template class X0<int>;
+
+extern template class X0<int*>;
+
+template<typename T>
+void X0<T>::Inner::g(T t) {
+  t = 17; // expected-error{{incompatible}}
+}
+
+void test_intptr(X0<int*> xi, X0<int*>::Inner xii) {
+  xi.f(0);
+  xii.g(0);
+}
+
+extern template class X0<long*>; 
+
+void test_longptr(X0<long*> xl, X0<long*>::Inner xli) {
+  xl.f(0);
+  xli.g(0);
+}
+
+template class X0<long*>; // expected-note 2{{instantiation}}
+
+template<typename T>
+class X1 {
+public:
+  void f(T t) { t += 2; }
+  
+  void g(T t);
+};
+
+template<typename T>
+void X1<T>::g(T t) { 
+  t += 2; 
+}
+
+extern template class X1<void*>;
+
+void g_X1(X1<void*> x1, void *ptr) {
+  x1.g(ptr);
+}
+
+extern template void X1<const void*>::g(const void*);
+
+void g_X1_2(X1<const void *> x1, const void *ptr) {
+  x1.g(ptr);
+}
diff --git a/test/SemaTemplate/fibonacci.cpp b/test/SemaTemplate/fibonacci.cpp
new file mode 100644
index 0000000..ff1711f
--- /dev/null
+++ b/test/SemaTemplate/fibonacci.cpp
@@ -0,0 +1,66 @@
+// RUN: %clang_cc1 -fsyntax-only %s
+
+template<unsigned I>
+struct FibonacciEval;
+
+template<unsigned I>
+struct Fibonacci {
+  enum { value = FibonacciEval<I-1>::value + FibonacciEval<I-2>::value };
+};
+
+template<unsigned I>
+struct FibonacciEval {
+  enum { value = Fibonacci<I>::value };
+};
+
+template<> struct Fibonacci<0> {
+  enum { value = 0 };
+};
+
+template<> struct Fibonacci<1> {
+  enum { value = 1 };
+};
+
+int array5[Fibonacci<5>::value == 5? 1 : -1];
+int array10[Fibonacci<10>::value == 55? 1 : -1];
+
+template<unsigned I>
+struct FibonacciEval2;
+
+template<unsigned I>
+struct Fibonacci2 {
+  static const unsigned value 
+    = FibonacciEval2<I-1>::value + FibonacciEval2<I-2>::value;
+};
+
+template<unsigned I>
+struct FibonacciEval2 {
+  static const unsigned value = Fibonacci2<I>::value;
+};
+
+template<> struct Fibonacci2<0> {
+  static const unsigned value = 0;
+};
+
+template<> struct Fibonacci2<1> {
+  static const unsigned value = 1;
+};
+
+int array5_2[Fibonacci2<5>::value == 5? 1 : -1];
+int array10_2[Fibonacci2<10>::value == 55? 1 : -1];
+
+template<unsigned I>
+struct Fibonacci3 {
+  static const unsigned value = Fibonacci3<I-1>::value + Fibonacci3<I-2>::value;
+};
+
+template<> struct Fibonacci3<0> {
+  static const unsigned value = 0;
+};
+
+template<> struct Fibonacci3<1> {
+  static const unsigned value = 1;
+};
+
+int array5_3[Fibonacci3<5>::value == 5? 1 : -1];
+int array10_3[Fibonacci3<10>::value == 55? 1 : -1];
diff --git a/test/SemaTemplate/friend-template.cpp b/test/SemaTemplate/friend-template.cpp
new file mode 100644
index 0000000..6ee30aa
--- /dev/null
+++ b/test/SemaTemplate/friend-template.cpp
@@ -0,0 +1,129 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// PR5057
+namespace test0 {
+  namespace std {
+    class X {
+    public:
+      template<typename T> friend struct Y;
+    };
+  }
+
+  namespace std {
+    template<typename T> struct Y {};
+  }
+}
+
+namespace test1 {
+  template<typename T> void f1(T) { } // expected-note{{here}}
+
+  class X {
+    template<typename T> friend void f0(T);
+    template<typename T> friend void f1(T);
+  };
+
+  template<typename T> void f0(T) { }
+  template<typename T> void f1(T) { } // expected-error{{redefinition}}
+}
+
+// PR4768
+namespace test2 {
+  template<typename T> struct X0 {
+    template<typename U> friend struct X0;
+  };
+  
+  template<typename T> struct X0<T*> {
+    template<typename U> friend struct X0;
+  };
+
+  template<> struct X0<int> {
+    template<typename U> friend struct X0;
+  };
+
+  template<typename T> struct X1 {
+    template<typename U> friend void f2(U);
+    template<typename U> friend void f3(U);
+  };
+
+  template<typename U> void f2(U);
+
+  X1<int> x1i;
+  X0<int*> x0ip;
+
+  template<> void f2(int);
+
+  // FIXME: Should this declaration of f3 be required for the specialization of
+  // f3<int> (further below) to work? GCC and EDG don't require it, we do...
+  template<typename U> void f3(U);
+
+  template<> void f3(int);
+}
+
+// PR5332
+namespace test3 {
+  template <typename T> class Foo {
+    template <typename U>
+    friend class Foo;
+  };
+
+  Foo<int> foo;
+
+  template<typename T, T Value> struct X2a;
+
+  template<typename T, int Size> struct X2b;
+
+  template<typename T>
+  class X3 {
+    template<typename U, U Value> friend struct X2a;
+
+    // FIXME: the redeclaration note ends up here because redeclaration
+    // lookup ends up finding the friend target from X3<int>.
+    template<typename U, T Value> friend struct X2b; // expected-error {{template non-type parameter has a different type 'long' in template redeclaration}} \
+      // expected-note {{previous non-type template parameter with type 'int' is here}}
+  };
+
+  X3<int> x3i; // okay
+
+  X3<long> x3l; // expected-note {{in instantiation}}
+}
+
+// PR5716
+namespace test4 {
+  template<typename> struct A {
+    template<typename T> friend void f(const A<T>&);
+  };
+
+  template<typename T> void f(const A<T>&) {
+    int a[sizeof(T) ? -1 : -1]; // expected-error {{array size is negative}}
+  }
+
+  void f() {
+    f(A<int>()); // expected-note {{in instantiation of function template specialization}}
+  }
+}
+
+namespace test5 {
+  class outer {
+    class foo;
+    template <typename T> friend struct cache;
+  };
+  class outer::foo {
+    template <typename T> friend struct cache;
+  };
+}
+
+// PR6022
+namespace PR6022 {
+  template <class T1, class T2 , class T3  > class A;
+
+  namespace inner {
+    template<class T1, class T2, class T3, class T> 
+    A<T1, T2, T3>& f0(A<T1, T2, T3>&, T);
+  } 
+
+  template<class T1, class T2, class T3>
+  class A {
+    template<class U1, class U2, class U3, class T>  
+    friend A<U1, U2, U3>& inner::f0(A<U1, U2, U3>&, T);
+  };
+}
+
diff --git a/test/SemaTemplate/friend.cpp b/test/SemaTemplate/friend.cpp
new file mode 100644
index 0000000..99685f2
--- /dev/null
+++ b/test/SemaTemplate/friend.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename T> struct A {
+  struct B { };
+  
+  friend struct B;
+};
+
+void f() {
+  A<int>::B b;
+}
+
+struct C0 {
+  friend struct A<int>;
+};
+
+namespace PR6770 {
+  namespace N {
+    int f1(int);
+  }
+  using namespace N;
+
+  namespace M { 
+    float f1(float);
+  }
+  using M::f1;
+
+  template<typename T> void f1(T, T);
+  template <class T>
+  void f() {
+    friend class f; // expected-error{{'friend' used outside of class}}
+    friend class f1; // expected-error{{ 'friend' used outside of class}}
+  }
+}
diff --git a/test/SemaTemplate/fun-template-def.cpp b/test/SemaTemplate/fun-template-def.cpp
new file mode 100644
index 0000000..309921c
--- /dev/null
+++ b/test/SemaTemplate/fun-template-def.cpp
@@ -0,0 +1,48 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// Tests that dependent expressions are always allowed, whereas non-dependent
+// are checked as usual.
+
+#include <stddef.h>
+
+// Fake typeid, lacking a typeinfo header.
+namespace std { class type_info {}; }
+
+struct dummy {}; // expected-note 3 {{candidate constructor (the implicit copy constructor)}}
+
+template<typename T>
+int f0(T x) {
+  return (sizeof(x) == sizeof(int))? 0 : (sizeof(x) == sizeof(double))? 1 : 2;
+}
+
+template <typename T, typename U>
+T f1(T t1, U u1, int i1)
+{
+  T t2 = i1;
+  t2 = i1 + u1;
+  ++u1;
+  u1++;
+  int i2 = u1;
+
+  i1 = t1[u1];
+  i1 *= t1;
+
+  i1(u1, t1); // error
+  u1(i1, t1);
+
+  U u2 = (T)i1;
+  static_cast<void>(static_cast<U>(reinterpret_cast<T>(
+    dynamic_cast<U>(const_cast<T>(i1)))));
+
+  new U(i1, t1);
+  new int(t1, u1);
+  new (t1, u1) int;
+  delete t1;
+
+  dummy d1 = sizeof(t1); // expected-error {{no viable conversion}}
+  dummy d2 = offsetof(T, foo); // expected-error {{no viable conversion}}
+  dummy d3 = __alignof(u1); // expected-error {{no viable conversion}}
+  i1 = typeid(t1); // expected-error {{assigning to 'int' from incompatible type 'std::type_info const'}}
+
+  return u1;
+}
diff --git a/test/SemaTemplate/function-template-specialization.cpp b/test/SemaTemplate/function-template-specialization.cpp
new file mode 100644
index 0000000..9afc99f
--- /dev/null
+++ b/test/SemaTemplate/function-template-specialization.cpp
@@ -0,0 +1,43 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<int N> void f0(int (&array)[N]);
+
+// Simple function template specialization (using overloading)
+template<> void f0(int (&array)[1]);
+
+void test_f0() {
+  int iarr1[1];
+  f0(iarr1);
+}
+
+// Function template specialization where there are no matches
+template<> void f0(char (&array)[1]); // expected-error{{no function template matches}}
+template<> void f0<2>(int (&array)[2]) { }
+
+// Function template specialization that requires partial ordering
+template<typename T, int N> void f1(T (&array)[N]); // expected-note{{matches}}
+template<int N> void f1(int (&array)[N]); // expected-note{{matches}}
+
+template<> void f1(float (&array)[1]);
+template<> void f1(int (&array)[1]);
+
+// Function template specialization that results in an ambiguity
+template<typename T> void f1(T (&array)[17]); // expected-note{{matches}}
+template<> void f1(int (&array)[17]); // expected-error{{ambiguous}}
+
+// Resolving that ambiguity with explicitly-specified template arguments.
+template<int N> void f2(double (&array)[N]);
+template<typename T> void f2(T (&array)[42]);
+
+template<> void f2<double>(double (&array)[42]);
+template<> void f2<42>(double (&array)[42]);
+
+void f2<25>(double (&array)[25]); // expected-error{{specialization}} 
+
+// PR5833
+namespace PR5833 {
+  template <typename T> bool f0(T &t1);
+  template <> bool f0<float>(float &t1);
+}
+template <> bool PR5833::f0<float>(float &t1) {}
+
diff --git a/test/SemaTemplate/implicit-instantiation-1.cpp b/test/SemaTemplate/implicit-instantiation-1.cpp
new file mode 100644
index 0000000..d1bc5a8
--- /dev/null
+++ b/test/SemaTemplate/implicit-instantiation-1.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename T, typename U>
+struct X {
+  T f(T x, U y) { return x + y; }
+
+  unsigned g(T x, U y) { return sizeof(f(x, y)); }
+};
+
+void test(X<int, int> *xii, X<int*, int> *xpi, X<int, int*> *xip) {
+  (void)xii->f(1, 2);
+  (void)xpi->f(0, 2);
+  (void)sizeof(xip->f(2, 0)); // okay: does not instantiate
+  (void)xip->g(2, 0); // okay: does not instantiate
+}
+
+template<typename T, typename U>
+T add(T t, U u) {
+  return t + u; // expected-error{{invalid operands}}
+}
+
+void test_add(char *cp, int i, int *ip) {
+  char* cp2 = add(cp, i);
+  add(cp, cp); // expected-note{{instantiation of}}
+  (void)sizeof(add(ip, ip));
+}
diff --git a/test/SemaTemplate/injected-class-name.cpp b/test/SemaTemplate/injected-class-name.cpp
new file mode 100644
index 0000000..586be18
--- /dev/null
+++ b/test/SemaTemplate/injected-class-name.cpp
@@ -0,0 +1,50 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename T>
+struct X {
+  X<T*> *ptr;
+};
+
+X<int> x;
+
+template<>
+struct X<int***> {
+  typedef X<int***> *ptr;
+};
+
+X<float>::X<int> xi = x; // expected-error{{qualified reference to 'X' is a constructor name rather than a template name wherever a constructor can be declared}}
+
+// [temp.local]p1:
+
+// FIXME: test template template parameters
+template<typename T, typename U>
+struct X0 {
+  typedef T type;
+  typedef U U_type;
+  typedef U_type U_type2;
+
+  void f0(const X0&); // expected-note{{here}}
+  void f0(X0&);
+  void f0(const X0<T, U>&); // expected-error{{redecl}}
+
+  void f1(const X0&); // expected-note{{here}}
+  void f1(X0&);
+  void f1(const X0<type, U_type2>&); // expected-error{{redecl}}
+
+  void f2(const X0&); // expected-note{{here}}
+  void f2(X0&);
+  void f2(const ::X0<type, U_type2>&); // expected-error{{redecl}}
+};
+
+template<typename T, T N>
+struct X1 {
+  void f0(const X1&); // expected-note{{here}}
+  void f0(X1&);
+  void f0(const X1<T, N>&); // expected-error{{redecl}}
+};
+
+namespace pr6326 {
+  template <class T> class A {
+    friend class A;
+  };
+  template class A<int>;
+}
diff --git a/test/SemaTemplate/instantiate-anonymous-union.cpp b/test/SemaTemplate/instantiate-anonymous-union.cpp
new file mode 100644
index 0000000..7c75885
--- /dev/null
+++ b/test/SemaTemplate/instantiate-anonymous-union.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -fsyntax-only %s -Wall
+
+template <typename T> class A { struct { }; };
+
+A<int> a0;
+
+template <typename T> struct B {
+  union {
+    int a;
+    void* b;
+  };
+    
+  void f() {
+    a = 10;
+    b = 0;
+  }
+};
+
+B<int> b0;
+
+template <typename T> struct C {
+  union {
+    int a;
+    void* b;
+  };
+
+  C(int a) : a(a) { }
+  C(void* b) : b(b) { }
+};
+
+C<int> c0(0);
diff --git a/test/SemaTemplate/instantiate-array.cpp b/test/SemaTemplate/instantiate-array.cpp
new file mode 100644
index 0000000..97ea6cb
--- /dev/null
+++ b/test/SemaTemplate/instantiate-array.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
+
+#ifndef __GXX_EXPERIMENTAL_CXX0X__
+#define __CONCAT(__X, __Y) __CONCAT1(__X, __Y)
+#define __CONCAT1(__X, __Y) __X ## __Y
+
+#define static_assert(__b, __m) \
+  typedef int __CONCAT(__sa, __LINE__)[__b ? 1 : -1]
+#endif
+
+template <int N> class IntArray {
+  int elems[N];
+};
+
+static_assert(sizeof(IntArray<10>) == sizeof(int) * 10, "Array size mismatch");
+static_assert(sizeof(IntArray<1>) == sizeof(int) * 1, "Array size mismatch");
+
+template <typename T> class TenElementArray {
+  int elems[10];
+};
+
+static_assert(sizeof(TenElementArray<int>) == sizeof(int) * 10, "Array size mismatch");
+
+template<typename T, int N> class Array {
+  T elems[N];
+};
+
+static_assert(sizeof(Array<int, 10>) == sizeof(int) * 10, "Array size mismatch");
diff --git a/test/SemaTemplate/instantiate-attr.cpp b/test/SemaTemplate/instantiate-attr.cpp
new file mode 100644
index 0000000..7fb1736
--- /dev/null
+++ b/test/SemaTemplate/instantiate-attr.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template <typename T>
+struct A {
+  char a __attribute__((aligned(16)));
+};
+int a[sizeof(A<int>) == 16 ? 1 : -1];
+
diff --git a/test/SemaTemplate/instantiate-c99.cpp b/test/SemaTemplate/instantiate-c99.cpp
new file mode 100644
index 0000000..ae15528
--- /dev/null
+++ b/test/SemaTemplate/instantiate-c99.cpp
@@ -0,0 +1,81 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// Test template instantiation for C99-specific features.
+
+// ---------------------------------------------------------------------
+// Designated initializers
+// ---------------------------------------------------------------------
+template<typename T, typename XType, typename YType>
+struct DesigInit0 {
+  void f(XType x, YType y) {
+    T agg = { 
+      .y = y, // expected-error{{does not refer}}
+      .x = x  // expected-error{{does not refer}}
+    };
+  }
+};
+
+struct Point2D {
+  float x, y;
+};
+
+template struct DesigInit0<Point2D, int, double>;
+
+struct Point3D {
+  float x, y, z;
+};
+
+template struct DesigInit0<Point3D, int, double>;
+
+struct Color { 
+  unsigned char red, green, blue;
+};
+
+struct ColorPoint3D {
+  Color color;
+  float x, y, z;
+};
+
+template struct DesigInit0<ColorPoint3D, int, double>;
+template struct DesigInit0<Color, int, double>; // expected-note{{instantiation}}
+
+template<typename T, int Subscript1, int Subscript2,
+         typename Val1, typename Val2>
+struct DesigArrayInit0 {
+  void f(Val1 val1, Val2 val2) {
+    T array = {
+      [Subscript1] = val1,
+      [Subscript2] = val2 // expected-error{{exceeds array bounds}}
+    };
+
+    int array2[10] = { [5] = 3 };
+  }
+};
+
+template struct DesigArrayInit0<int[8], 5, 3, float, int>;
+template struct DesigArrayInit0<int[8], 5, 13, float, int>; // expected-note{{instantiation}}
+
+template<typename T, int Subscript1, int Subscript2,
+         typename Val1>
+struct DesigArrayRangeInit0 {
+  void f(Val1 val1) {
+    T array = {
+      [Subscript1...Subscript2] = val1 // expected-error{{exceeds}}
+    };
+  }
+};
+
+template struct DesigArrayRangeInit0<int[8], 3, 5, float>;
+template struct DesigArrayRangeInit0<int[8], 5, 13, float>; // expected-note{{instantiation}}
+
+// ---------------------------------------------------------------------
+// Compound literals
+// ---------------------------------------------------------------------
+template<typename T, typename Arg1, typename Arg2>
+struct CompoundLiteral0 {
+  T f(Arg1 a1, Arg2 a2) {
+    return (T){a1, a2};
+  }
+};
+
+template struct CompoundLiteral0<Point2D, int, float>;
diff --git a/test/SemaTemplate/instantiate-call.cpp b/test/SemaTemplate/instantiate-call.cpp
new file mode 100644
index 0000000..ad06be3
--- /dev/null
+++ b/test/SemaTemplate/instantiate-call.cpp
@@ -0,0 +1,50 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace N1 {
+  struct X0 { };
+
+  int& f0(X0);
+}
+
+namespace N2 {
+  char& f0(char);
+
+  template<typename T, typename Result>
+  struct call_f0 {
+    void test_f0(T t) {
+      Result result = f0(t);
+    }
+  };
+}
+
+template struct N2::call_f0<int, char&>;
+template struct N2::call_f0<N1::X0, int&>;
+
+namespace N3 {
+  template<typename T, typename Result>
+  struct call_f0 {
+    void test_f0(T t) {
+      Result &result = f0(t); // expected-error 2{{undeclared identifier}}
+    }
+  };
+}
+
+template struct N3::call_f0<int, char&>; // expected-note{{instantiation}}
+template struct N3::call_f0<N1::X0, int&>;
+
+short& f0(char);
+namespace N4 {
+  template<typename T, typename Result>
+  struct call_f0 {
+    void test_f0(T t) {
+      Result &result = f0(t);
+    }
+  };
+}
+
+template struct N4::call_f0<int, short&>;
+template struct N4::call_f0<N1::X0, int&>;
+template struct N3::call_f0<int, short&>; // expected-note{{instantiation}}
+
+// FIXME: test overloaded function call operators, calls to member
+// functions, etc.
diff --git a/test/SemaTemplate/instantiate-case.cpp b/test/SemaTemplate/instantiate-case.cpp
new file mode 100644
index 0000000..1cc2d5d
--- /dev/null
+++ b/test/SemaTemplate/instantiate-case.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<class T>
+static int alpha(T c)
+{
+    return *c; // expected-error{{indirection requires pointer operand}}
+}
+
+template<class T>
+static void
+_shexp_match()
+{
+  switch(1) {
+  case 1:
+    alpha(1); // expected-note{{instantiation of function template}}
+  }
+}
+int main() {
+  _shexp_match<char>(); // expected-note{{instantiation of function template}}
+  return 0;
+}
diff --git a/test/SemaTemplate/instantiate-cast.cpp b/test/SemaTemplate/instantiate-cast.cpp
new file mode 100644
index 0000000..9669b20
--- /dev/null
+++ b/test/SemaTemplate/instantiate-cast.cpp
@@ -0,0 +1,117 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct A { int x; }; 
+
+class Base { 
+public:
+  virtual void f();
+};
+
+class Derived : public Base { };
+
+struct ConvertibleToInt {
+  operator int() const;
+};
+
+struct Constructible {
+  Constructible(int, float);
+};
+
+// ---------------------------------------------------------------------
+// C-style casts
+// ---------------------------------------------------------------------
+template<typename T, typename U>
+struct CStyleCast0 {
+  void f(T t) {
+    (void)((U)t); // expected-error{{C-style cast from 'A' to 'int' is not allowed}}
+  }
+};
+
+template struct CStyleCast0<int, float>;
+template struct CStyleCast0<A, int>; // expected-note{{instantiation}}
+
+// ---------------------------------------------------------------------
+// static_cast
+// ---------------------------------------------------------------------
+template<typename T, typename U>
+struct StaticCast0 {
+  void f(T t) {
+    (void)static_cast<U>(t); // expected-error{{static_cast from 'int' to 'A' is not allowed}}
+  }
+};
+
+template struct StaticCast0<ConvertibleToInt, bool>;
+template struct StaticCast0<int, float>;
+template struct StaticCast0<int, A>; // expected-note{{instantiation}}
+
+// ---------------------------------------------------------------------
+// dynamic_cast
+// ---------------------------------------------------------------------
+template<typename T, typename U>
+struct DynamicCast0 {
+  void f(T t) {
+    (void)dynamic_cast<U>(t); // expected-error{{not a reference or pointer}}
+  }
+};
+
+template struct DynamicCast0<Base*, Derived*>;
+template struct DynamicCast0<Base*, A>; // expected-note{{instantiation}}
+
+// ---------------------------------------------------------------------
+// reinterpret_cast
+// ---------------------------------------------------------------------
+template<typename T, typename U>
+struct ReinterpretCast0 {
+  void f(T t) {
+    (void)reinterpret_cast<U>(t); // expected-error{{constness}}
+  }
+};
+
+template struct ReinterpretCast0<void (*)(int), void (*)(float)>;
+template struct ReinterpretCast0<int const *, float *>; // expected-note{{instantiation}}
+
+// ---------------------------------------------------------------------
+// const_cast
+// ---------------------------------------------------------------------
+template<typename T, typename U>
+struct ConstCast0 {
+  void f(T t) {
+    (void)const_cast<U>(t); // expected-error{{not allowed}}
+  }
+};
+
+template struct ConstCast0<int const * *, int * *>;
+template struct ConstCast0<int const *, float *>; // expected-note{{instantiation}}
+
+// ---------------------------------------------------------------------
+// C++ functional cast
+// ---------------------------------------------------------------------
+template<typename T, typename U>
+struct FunctionalCast1 {
+  void f(T t) {
+    (void)U(t); // expected-error{{functional-style cast from 'A' to 'int' is not allowed}}
+  }
+};
+
+template struct FunctionalCast1<int, float>;
+template struct FunctionalCast1<A, int>; // expected-note{{instantiation}}
+
+// Generates temporaries, which we cannot handle yet.
+template<int N, long M>
+struct FunctionalCast2 {
+  void f() {
+    (void)Constructible(N, M);
+  }
+};
+
+template struct FunctionalCast2<1, 3>;
+
+// ---------------------------------------------------------------------
+// implicit casting
+// ---------------------------------------------------------------------
+template<typename T>
+struct Derived2 : public Base { };
+
+void test_derived_to_base(Base *&bp, Derived2<int> *dp) {
+  bp = dp;
+}
diff --git a/test/SemaTemplate/instantiate-clang.cpp b/test/SemaTemplate/instantiate-clang.cpp
new file mode 100644
index 0000000..cef2b70
--- /dev/null
+++ b/test/SemaTemplate/instantiate-clang.cpp
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// Test template instantiation for Clang-specific features.
+
+// ---------------------------------------------------------------------
+// Vector types
+// ---------------------------------------------------------------------
+typedef __attribute__(( ext_vector_type(2) )) double double2;
+typedef __attribute__(( ext_vector_type(4) )) double double4;
+
+template<typename T>
+struct ExtVectorAccess0 {
+  void f(T v1, double4 v2) {
+    v1.xy = v2.yx;
+  }
+};
+
+template struct ExtVectorAccess0<double2>;
+template struct ExtVectorAccess0<double4>;
+
+typedef __attribute__(( ext_vector_type(2) )) double double2;
+
+template<typename T, typename U, int N, int M>
+struct ShuffleVector0 {
+  void f(T t, U u, double2 a, double2 b) {
+    (void)__builtin_shufflevector(t, u, N, M); // expected-error{{index}}
+    (void)__builtin_shufflevector(a, b, N, M);
+    (void)__builtin_shufflevector(a, b, 2, 1);
+  }
+};
+
+template struct ShuffleVector0<double2, double2, 2, 1>;
+template struct ShuffleVector0<double2, double2, 4, 3>; // expected-note{{instantiation}}
+
+
diff --git a/test/SemaTemplate/instantiate-complete.cpp b/test/SemaTemplate/instantiate-complete.cpp
new file mode 100644
index 0000000..d854c9e
--- /dev/null
+++ b/test/SemaTemplate/instantiate-complete.cpp
@@ -0,0 +1,101 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// Tests various places where requiring a complete type involves
+// instantiation of that type.
+
+template<typename T>
+struct X {
+  X(T);
+
+  T f; // expected-error{{data member instantiated with function type 'float (int)'}} \
+       // expected-error{{data member instantiated with function type 'int (int)'}} \
+       // expected-error{{data member instantiated with function type 'char (char)'}} \
+       // expected-error{{data member instantiated with function type 'short (short)'}} \
+       // expected-error{{data member instantiated with function type 'float (float)'}} \
+       // expected-error{{data member instantiated with function type 'long (long)'}}
+};
+
+X<int> f() { return 0; }
+
+struct XField {
+  X<float(int)> xf; // expected-note{{in instantiation of template class 'X<float (int)>' requested here}}
+};
+
+void test_subscript(X<double> *ptr1, X<int(int)> *ptr2, int i) {
+  (void)ptr1[i];
+  (void)ptr2[i]; // expected-note{{in instantiation of template class 'X<int (int)>' requested here}}
+}
+
+void test_arith(X<signed char> *ptr1, X<unsigned char> *ptr2,
+                X<char(char)> *ptr3, X<short(short)> *ptr4) {
+  (void)(ptr1 + 5);
+  // FIXME: if I drop the ')' after void, below, it still parses (!)
+  (void)(5 + ptr2);
+  (void)(ptr3 + 5); // expected-note{{in instantiation of template class 'X<char (char)>' requested here}}
+  (void)(5 + ptr4); // expected-note{{in instantiation of template class 'X<short (short)>' requested here}}
+}
+
+void test_new() {
+  (void)new X<float>(0);
+  (void)new X<float(float)>; // expected-note{{in instantiation of template class 'X<float (float)>' requested here}}
+}
+
+void test_memptr(X<long> *p1, long X<long>::*pm1,
+                 X<long(long)> *p2, 
+                 long (X<long(long)>::*pm2)(long)) {
+  (void)(p1->*pm1);
+  (void)((p2->*pm2)(0)); // expected-note{{in instantiation of template class 'X<long (long)>' requested here}}
+}
+
+// Reference binding to a base
+template<typename T>
+struct X1 { };
+
+template<typename T>
+struct X2 : public T { };
+
+void refbind_base(X2<X1<int> > &x2) {
+  X1<int> &x1 = x2;
+}
+
+// Enumerate constructors for user-defined conversion.
+template<typename T>
+struct X3 {
+  X3(T);
+};
+
+void enum_constructors(X1<float> &x1) {
+  X3<X1<float> > x3 = x1;
+}
+
+namespace PR6376 {
+  template<typename T, typename U> struct W { };
+
+  template<typename T>
+  struct X {
+    template<typename U>
+    struct apply {
+      typedef W<T, U> type;
+    };
+  };
+  
+  template<typename T, typename U>
+  struct Y : public X<T>::template apply<U>::type { };
+
+  template struct Y<int, float>;
+}
+
+namespace TemporaryObjectCopy {
+  // Make sure we instantiate classes when we create a temporary copy.
+  template<typename T>
+  struct X {
+    X(T); 
+  };
+
+  template<typename T>
+  void f(T t) {
+    const X<int> &x = X<int>(t);
+  }
+
+  template void f(int);
+}
diff --git a/test/SemaTemplate/instantiate-decl-dtor.cpp b/test/SemaTemplate/instantiate-decl-dtor.cpp
new file mode 100644
index 0000000..193d976
--- /dev/null
+++ b/test/SemaTemplate/instantiate-decl-dtor.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify
+
+template <typename T> struct A {
+  T x;
+  A(int y) { x = y; }
+  ~A() { *x = 10; } // expected-error {{indirection requires pointer operand}}
+};
+
+void a() {
+  A<int> b = 10; // expected-note {{requested here}}
+}
diff --git a/test/SemaTemplate/instantiate-decl-init.cpp b/test/SemaTemplate/instantiate-decl-init.cpp
new file mode 100644
index 0000000..6b76d72
--- /dev/null
+++ b/test/SemaTemplate/instantiate-decl-init.cpp
@@ -0,0 +1,46 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// PR5426 - the non-dependent obj would be fully processed and wrapped in a
+// CXXConstructExpr at definition time, which would lead to a failure at
+// instantiation time.
+struct arg {
+  arg();
+};
+
+struct oldstylemove {
+  oldstylemove(oldstylemove&);
+  oldstylemove(const arg&);
+};
+
+template <typename T>
+void fn(T t, const arg& arg) {
+  oldstylemove obj(arg);
+}
+
+void test() {
+  fn(1, arg());
+}
+
+struct X0 { };
+
+struct X1 {
+  explicit X1(const X0 &x0 = X0());
+};
+
+template<typename T>
+void f0() {
+  X1 x1;
+}
+
+template void f0<int>();
+template void f0<float>();
+
+struct NonTrivial {
+  NonTrivial();
+  ~NonTrivial();
+};
+
+template<int N> void f1() {
+  NonTrivial array[N];
+}
+template<> void f1<2>();
diff --git a/test/SemaTemplate/instantiate-declref-ice.cpp b/test/SemaTemplate/instantiate-declref-ice.cpp
new file mode 100644
index 0000000..e88b494
--- /dev/null
+++ b/test/SemaTemplate/instantiate-declref-ice.cpp
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<int i> struct x {
+  static const int j = i;
+  x<j>* y;
+};
+
+template<int i>
+const int x<i>::j;
+
+int array0[x<2>::j];
+
+template<typename T>
+struct X0 {
+  static const unsigned value = sizeof(T);
+};
+
+template<typename T>
+const unsigned X0<T>::value;
+
+int array1[X0<int>::value == sizeof(int)? 1 : -1];
+
+const unsigned& testX0() { return X0<int>::value; }
+
+int array2[X0<int>::value == sizeof(int)? 1 : -1];
+
+template<typename T>
+struct X1 {
+  static const unsigned value;
+};
+
+template<typename T>
+const unsigned X1<T>::value = sizeof(T);
+
+int array3[X1<int>::value == sizeof(int)? 1 : -1]; // expected-error{{variable length arrays are not permitted in C++}} \
+// expected-error{{variable length array declaration not allowed at file scope}}
diff --git a/test/SemaTemplate/instantiate-declref.cpp b/test/SemaTemplate/instantiate-declref.cpp
new file mode 100644
index 0000000..2d27075
--- /dev/null
+++ b/test/SemaTemplate/instantiate-declref.cpp
@@ -0,0 +1,97 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+namespace N {
+  struct Outer {
+    struct Inner {
+      template<typename T>
+      struct InnerTemplate {
+        struct VeryInner {
+          typedef T type;
+
+          static enum K1 { K1Val = sizeof(T) } Kind1;
+          static enum { K2Val = sizeof(T)*2 } Kind2;
+          enum { K3Val = sizeof(T)*2 } Kind3;
+
+          void foo() {
+            K1 k1 = K1Val;
+            Kind1 = K1Val;
+            Outer::Inner::InnerTemplate<type>::VeryInner::Kind2 = K2Val;
+            Kind3 = K3Val;
+          }
+
+          struct UeberInner {
+            void bar() {
+              K1 k1 = K1Val;
+              Kind1 = K1Val;
+              Outer::Inner::InnerTemplate<type>::VeryInner::Kind2 = K2Val;
+
+              InnerTemplate t;
+              InnerTemplate<type> t2;
+            }
+          };
+        };
+      };
+    };
+  };
+}
+
+typedef int INT;
+template struct N::Outer::Inner::InnerTemplate<INT>::VeryInner;
+template struct N::Outer::Inner::InnerTemplate<INT>::UeberInner; // expected-error{{no struct named 'UeberInner' in 'N::Outer::Inner::InnerTemplate<int>'}}
+
+namespace N2 {
+  struct Outer2 {
+    template<typename T, typename U = T>
+    struct Inner {
+      void foo() {
+        enum { K1Val = sizeof(T) } k1;
+        enum K2 { K2Val = sizeof(T)*2 } k2a;
+
+        K2 k2b = K2Val;
+
+        struct S { T x, y; } s1;
+        struct { U x, y; } s2;
+        s1.x = s2.x; // expected-error{{incompatible}}
+
+        typedef T type;
+        type t2 = s1.x;
+
+        typedef struct { T z; } type2;
+        type2 t3 = { s1.x };
+
+        Inner i1;
+        i1.foo();
+        Inner<T> i2;
+        i2.foo();
+      }
+    };
+  };
+}
+
+template struct N2::Outer2::Inner<float>;
+template struct N2::Outer2::Inner<int*, float*>; // expected-note{{instantiation}}
+
+// Test dependent pointer-to-member expressions.
+template<typename T>
+struct smart_ptr {
+  struct safe_bool {
+    int member;
+  };
+  
+  operator int safe_bool::*() const { 
+    return ptr? &safe_bool::member : 0;
+  }
+  
+  T* ptr;
+};
+
+void test_smart_ptr(smart_ptr<int> p) {
+  if (p) { }
+}
+
+// PR5517
+namespace test0 {
+  template <int K> struct X {
+    X() { extern void x(); }
+  };
+  void g() { X<2>(); }
+}
diff --git a/test/SemaTemplate/instantiate-deeply.cpp b/test/SemaTemplate/instantiate-deeply.cpp
new file mode 100644
index 0000000..c5f6594
--- /dev/null
+++ b/test/SemaTemplate/instantiate-deeply.cpp
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -fsyntax-only -Wall -verify %s
+template<typename a> struct A {
+  template <typename b> struct B {
+    template <typename c> struct C {
+      template <typename d> struct D {
+        template <typename e> struct E {
+          e field;
+          E() : field(0) {
+            d v1 = 4;
+            c v2 = v1 * v1;
+            b v3 = 8;
+            a v4 = v3 * v3;
+            field += v2 + v4;
+          }
+        };
+      };
+    };
+  };
+};
+
+A<int>::B<int>::C<int>::D<int>::E<int> global;
+
+// PR5352
+template <typename T>
+class Foo {
+public:
+  Foo() {}
+  
+  struct Bar {
+    T value;
+  };
+  
+  Bar u;
+};
+
+template class Foo<int>;
diff --git a/test/SemaTemplate/instantiate-default-assignment-operator.cpp b/test/SemaTemplate/instantiate-default-assignment-operator.cpp
new file mode 100644
index 0000000..5594d6c
--- /dev/null
+++ b/test/SemaTemplate/instantiate-default-assignment-operator.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename> struct PassRefPtr { };
+template<typename T> struct RefPtr {
+  RefPtr& operator=(const RefPtr&) { int a[sizeof(T) ? -1 : -1];} // expected-error 2 {{array size is negative}}
+  RefPtr& operator=(const PassRefPtr<T>&);
+};
+
+struct A { RefPtr<int> a; };
+struct B : RefPtr<float> { };
+
+void f() {
+  A a1, a2;
+  a1 = a2; // expected-note {{instantiation of member function 'RefPtr<int>::operator=' requested here}}
+
+  B b1, b2;
+  b1 = b2; // expected-note {{in instantiation of member function 'RefPtr<float>::operator=' requested here}}
+}
diff --git a/test/SemaTemplate/instantiate-dependent-nested-name.cpp b/test/SemaTemplate/instantiate-dependent-nested-name.cpp
new file mode 100644
index 0000000..eb1d3fb
--- /dev/null
+++ b/test/SemaTemplate/instantiate-dependent-nested-name.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// PR4382
+template<typename T> struct X { static const T A = 1; };
+template<typename T, bool = X<T>::A> struct Y { typedef T A; };
+template<typename T> struct Z { typedef typename Y<T>::A A; };
+extern int x;
+extern Z<int>::A x;
diff --git a/test/SemaTemplate/instantiate-elab-type-specifier.cpp b/test/SemaTemplate/instantiate-elab-type-specifier.cpp
new file mode 100644
index 0000000..e5e10a8
--- /dev/null
+++ b/test/SemaTemplate/instantiate-elab-type-specifier.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// PR5681
+template <class T> struct Base {
+  struct foo {};
+  int foo;
+};
+
+template <class T> struct Derived : Base<T> {
+  typedef struct Base<T>::foo type;
+};
+
+template struct Derived<int>;
diff --git a/test/SemaTemplate/instantiate-enum-2.cpp b/test/SemaTemplate/instantiate-enum-2.cpp
new file mode 100644
index 0000000..aa3b590
--- /dev/null
+++ b/test/SemaTemplate/instantiate-enum-2.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify
+
+template<int IntBits> struct X {
+  enum {
+    IntShift = (unsigned long long)IntBits,
+    ShiftedIntMask = (1 << IntShift)
+  };
+};
+X<1> x;
diff --git a/test/SemaTemplate/instantiate-enum.cpp b/test/SemaTemplate/instantiate-enum.cpp
new file mode 100644
index 0000000..5353a92
--- /dev/null
+++ b/test/SemaTemplate/instantiate-enum.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -fsyntax-only %s
+
+template<typename T, T I, int J>
+struct adder {
+  enum {
+    value = I + J,
+    value2
+  };
+};
+
+int array1[adder<long, 3, 4>::value == 7? 1 : -1];
+
+namespace PR6375 {
+  template<typename T> 
+  void f() {
+    enum Enum
+    {
+      enumerator1 = 0xFFFFFFF,
+      enumerator2 = enumerator1 - 1
+    };
+  
+    int xb1 = enumerator1;
+    int xe1 = enumerator2;
+  }
+
+  template void f<int>();
+}
diff --git a/test/SemaTemplate/instantiate-exception-spec.cpp b/test/SemaTemplate/instantiate-exception-spec.cpp
new file mode 100644
index 0000000..d4f12df
--- /dev/null
+++ b/test/SemaTemplate/instantiate-exception-spec.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// FIXME: the "note" should be down at the call site!
+template<typename T> void f1(T*) throw(T); // expected-error{{incomplete type 'Incomplete' is not allowed in exception specification}} \
+                         // expected-note{{instantiation of}}
+struct Incomplete; // expected-note{{forward}}
+
+void test_f1(Incomplete *incomplete_p, int *int_p) {
+  f1(int_p);
+  f1(incomplete_p); 
+}
diff --git a/test/SemaTemplate/instantiate-expr-1.cpp b/test/SemaTemplate/instantiate-expr-1.cpp
new file mode 100644
index 0000000..7af59fd
--- /dev/null
+++ b/test/SemaTemplate/instantiate-expr-1.cpp
@@ -0,0 +1,172 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<int I, int J>
+struct Bitfields {
+  int simple : I; // expected-error{{bit-field 'simple' has zero width}}
+  int parens : (J);
+};
+
+void test_Bitfields(Bitfields<0, 5> *b) {
+  (void)sizeof(Bitfields<10, 5>);
+  (void)sizeof(Bitfields<0, 1>); // expected-note{{in instantiation of template class 'Bitfields<0, 1>' requested here}}
+}
+
+template<int I, int J>
+struct BitfieldPlus {
+  int bitfield : I + J; // expected-error{{bit-field 'bitfield' has zero width}}
+};
+
+void test_BitfieldPlus() {
+  (void)sizeof(BitfieldPlus<0, 1>);
+  (void)sizeof(BitfieldPlus<-5, 5>); // expected-note{{in instantiation of template class 'BitfieldPlus<-5, 5>' requested here}}
+}
+
+template<int I, int J>
+struct BitfieldMinus {
+  int bitfield : I - J; // expected-error{{bit-field 'bitfield' has negative width (-1)}} \
+  // expected-error{{bit-field 'bitfield' has zero width}}
+};
+
+void test_BitfieldMinus() {
+  (void)sizeof(BitfieldMinus<5, 1>);
+  (void)sizeof(BitfieldMinus<0, 1>); // expected-note{{in instantiation of template class 'BitfieldMinus<0, 1>' requested here}}
+  (void)sizeof(BitfieldMinus<5, 5>); // expected-note{{in instantiation of template class 'BitfieldMinus<5, 5>' requested here}}
+}
+
+template<int I, int J>
+struct BitfieldDivide {
+  int bitfield : I / J; // expected-error{{expression is not an integer constant expression}} \
+                        // expected-note{{division by zero}}
+};
+
+void test_BitfieldDivide() {
+  (void)sizeof(BitfieldDivide<5, 1>);
+  (void)sizeof(BitfieldDivide<5, 0>); // expected-note{{in instantiation of template class 'BitfieldDivide<5, 0>' requested here}}
+}
+
+template<typename T, T I, int J>
+struct BitfieldDep {
+  int bitfield : I + J;
+};
+
+void test_BitfieldDep() {
+  (void)sizeof(BitfieldDep<int, 1, 5>);
+}
+
+template<int I>
+struct BitfieldNeg {
+  int bitfield : (-I); // expected-error{{bit-field 'bitfield' has negative width (-5)}}
+};
+
+template<typename T, T I>
+struct BitfieldNeg2 {
+  int bitfield : (-I); // expected-error{{bit-field 'bitfield' has negative width (-5)}}
+};
+
+void test_BitfieldNeg() {
+  (void)sizeof(BitfieldNeg<-5>); // okay
+  (void)sizeof(BitfieldNeg<5>); // expected-note{{in instantiation of template class 'BitfieldNeg<5>' requested here}}
+  (void)sizeof(BitfieldNeg2<int, -5>); // okay
+  (void)sizeof(BitfieldNeg2<int, 5>); // expected-note{{in instantiation of template class 'BitfieldNeg2<int, 5>' requested here}}
+}
+
+template<typename T>
+void increment(T &x) {
+  (void)++x;
+}
+
+struct Incrementable {
+  Incrementable &operator++();
+};
+
+void test_increment(Incrementable inc) {
+  increment(inc);
+}
+
+template<typename T>
+void add(const T &x) {
+  (void)(x + x);
+}
+
+namespace PR6237 {
+  template <typename T>
+  void f(T t) {
+    t++;
+  }
+
+  struct B { };
+  B operator++(B &, int);
+
+  template void f(B);
+}
+
+struct Addable {
+  Addable operator+(const Addable&) const;
+};
+
+void test_add(Addable &a) {
+  add(a);
+}
+
+struct CallOperator {
+  int &operator()(int);
+  double &operator()(double);
+};
+
+template<typename Result, typename F, typename Arg1>
+Result test_call_operator(F f, Arg1 arg1) {
+  // PR5266: non-dependent invocations of a function call operator.
+  CallOperator call_op;
+  int &ir = call_op(17);
+  return f(arg1);
+}
+
+void test_call_operator(CallOperator call_op, int i, double d) {
+  int &ir = test_call_operator<int&>(call_op, i);
+  double &dr = test_call_operator<double&>(call_op, d);
+}
+
+template<typename T>
+void test_asm(T t) {
+  asm ("nop" : "=a"(*t) : "r"(*t)); // expected-error {{indirection requires pointer operand ('int' invalid)}}
+}
+
+void test_asm() {
+  int* a;
+  test_asm(a);
+  
+  int b;
+  test_asm(b); // expected-note {{in instantiation of function template specialization 'test_asm<int>' requested here}}
+}
+
+namespace PR6424 {
+  template<int I> struct X { 
+    X() { 
+      int *ip = I; // expected-error{{cannot initialize a variable of type 'int *' with an rvalue of type 'int'}}
+    }
+  };
+  
+  template<int> struct Y {
+    typedef X<7> X7;
+    
+    void f() { X7(); } // expected-note{{instantiation}}
+  };
+  
+  template void Y<3>::f(); 
+
+  template<int I> 
+  struct X2 {
+    void *operator new(__SIZE_TYPE__) { 
+      int *ip = I; // expected-error{{cannot initialize a variable of type 'int *' with an rvalue of type 'int'}}
+      return ip;
+    }
+  };
+
+  template<int> struct Y2 {
+    typedef X2<7> X;
+    void f() { 
+      new X(); // expected-note{{instantiation of}}
+    }
+  };
+
+  template void Y2<3>::f();
+}
diff --git a/test/SemaTemplate/instantiate-expr-2.cpp b/test/SemaTemplate/instantiate-expr-2.cpp
new file mode 100644
index 0000000..b91b398
--- /dev/null
+++ b/test/SemaTemplate/instantiate-expr-2.cpp
@@ -0,0 +1,214 @@
+// RUN: %clang_cc1 -fsyntax-only %s
+typedef char one_byte;
+typedef char (&two_bytes)[2];
+typedef char (&four_bytes)[4];
+typedef char (&eight_bytes)[8];
+
+template<int N> struct A { };
+
+namespace N1 {
+  struct X { };
+}
+
+namespace N2 {
+  struct Y { };
+
+  two_bytes operator+(Y, Y);
+}
+
+namespace N3 {
+  struct Z { };
+
+  eight_bytes operator+(Z, Z);
+}
+
+namespace N4 {
+  one_byte operator+(N1::X, N2::Y);
+
+  template<typename T, typename U>
+  struct BinOpOverload {
+    typedef A<sizeof(T() + U())> type;
+  };
+}
+
+namespace N1 {
+  four_bytes operator+(X, X);
+}
+
+namespace N3 {
+  eight_bytes operator+(Z, Z); // redeclaration
+}
+
+void test_bin_op_overload(A<1> *a1, A<2> *a2, A<4> *a4, A<8> *a8) {
+  typedef N4::BinOpOverload<N1::X, N2::Y>::type XY;
+  XY *xy = a1;
+  typedef N4::BinOpOverload<N1::X, N1::X>::type XX;
+  XX *xx = a4;
+  typedef N4::BinOpOverload<N2::Y, N2::Y>::type YY;
+  YY *yy = a2;
+  typedef N4::BinOpOverload<N3::Z, N3::Z>::type ZZ;
+  ZZ *zz = a8;
+}
+
+namespace N3 {
+  eight_bytes operator-(::N3::Z);
+}
+
+namespace N4 {
+  template<typename T>
+  struct UnaryOpOverload {
+    typedef A<sizeof(-T())> type;
+  };
+}
+
+void test_unary_op_overload(A<8> *a8) {
+  typedef N4::UnaryOpOverload<N3::Z>::type UZ;
+  UZ *uz = a8;
+}
+
+/*
+namespace N5 {
+  template<int I>
+  struct Lookup {
+    enum { val = I, more = val + 1 };
+  };
+
+  template<bool B>
+  struct Cond {
+    enum Junk { is = B ? Lookup<B>::more : Lookup<Lookup<B+1>::more>::val };
+  };
+
+  enum { resultT = Cond<true>::is,
+         resultF = Cond<false>::is };
+}
+*/
+
+namespace N6 {
+  // non-typedependent
+  template<int I>
+  struct Lookup {};
+
+  template<bool B, typename T, typename E>
+  struct Cond {
+    typedef Lookup<B ? sizeof(T) : sizeof(E)> True;
+    typedef Lookup<!B ? sizeof(T) : sizeof(E)> False;
+  };
+
+  typedef Cond<true, int, char>::True True;
+  typedef Cond<true, int, char>::False False;
+
+  // check that we have the right types
+  Lookup<1> const &L1(False());
+  Lookup<sizeof(int)> const &L2(True());
+}
+
+
+namespace N7 {
+  // type dependent
+  template<int I>
+  struct Lookup {};
+
+  template<bool B, typename T, typename E>
+  struct Cond {
+    T foo() { return B ? T() : E(); }
+    typedef Lookup<sizeof(B ? T() : E())> Type;
+  };
+
+  //Cond<true, int*, double> C; // Errors
+  //int V(C.foo()); // Errors
+  //typedef Cond<true, int*, double>::Type Type; // Errors
+  typedef Cond<true, int, double>::Type Type;
+}
+
+template<typename T, unsigned long N> struct IntegralConstant { };
+
+template<typename T>
+struct X0 {
+  void f(T x, IntegralConstant<T, sizeof(x)>);
+};
+
+void test_X0(X0<int> x, IntegralConstant<int, sizeof(int)> ic) {
+  x.f(5,ic);
+}
+
+namespace N8 {
+  struct X {
+    X operator+(const X&) const;
+  };
+  
+  template<typename T>
+  T test_plus(const T* xp, const T& x, const T& y) {
+    x.operator+(y);
+    return xp->operator+(y);
+  }
+  
+  void test_test_plus(X x) {
+    test_plus(&x, x, x);
+  }
+}
+
+namespace N9 {
+  struct A {
+    bool operator==(int value);
+  };
+  
+  template<typename T> struct B {
+    bool f(A a) {
+      return a == 1;
+    }
+  };
+  
+  template struct B<int>;  
+}
+
+namespace N10 {
+  template <typename T>
+  class A {
+    struct X { };
+    
+  public:
+    ~A() {
+      f(reinterpret_cast<X *>(0), reinterpret_cast<X *>(0));
+    }
+    
+  private:
+    void f(X *);
+    void f(X *, X *);
+  };
+  
+  template class A<int>;
+}
+
+namespace N12 {
+  // PR5224
+  template<typename T>
+  struct A { typedef int t0; };
+  
+  struct C  {
+    C(int);
+    
+    template<typename T>
+    static C *f0(T a0) {return new C((typename A<T>::t0) 1);   }
+  };
+
+  void f0(int **a) { C::f0(a); }
+}
+
+namespace N13 {
+  class A{
+    A(const A&);
+
+  public:
+    ~A();
+    A(int);
+    template<typename T> A &operator<<(const T&);
+  };
+
+  template<typename T>
+  void f(T t) {
+    A(17) << t;
+  }
+
+  template void f(int);
+
+}
diff --git a/test/SemaTemplate/instantiate-expr-3.cpp b/test/SemaTemplate/instantiate-expr-3.cpp
new file mode 100644
index 0000000..41a96a3
--- /dev/null
+++ b/test/SemaTemplate/instantiate-expr-3.cpp
@@ -0,0 +1,115 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// ---------------------------------------------------------------------
+// Imaginary literals
+// ---------------------------------------------------------------------
+template<typename T>
+struct ImaginaryLiteral0 {
+  void f(T &x) {
+    x = 3.0I; // expected-error{{incompatible type}}
+  }
+};
+
+template struct ImaginaryLiteral0<_Complex float>;
+template struct ImaginaryLiteral0<int*>; // expected-note{{instantiation}}
+
+// ---------------------------------------------------------------------
+// Compound assignment operator
+// ---------------------------------------------------------------------
+namespace N1 {
+  struct X { };
+
+  int& operator+=(X&, int); // expected-note{{candidate}}
+}
+
+namespace N2 {
+  long& operator+=(N1::X&, long); // expected-note{{candidate}}
+
+  template<typename T, typename U, typename Result>
+  struct PlusEquals0 {
+    void f(T t, U u) {
+      Result r = t += u; // expected-error{{ambiguous}}
+    }
+  };
+}
+
+namespace N3 {
+  struct Y : public N1::X {
+    short& operator+=(long); // expected-note{{candidate}}
+  };
+}
+
+template struct N2::PlusEquals0<N1::X, int, int&>;
+template struct N2::PlusEquals0<N1::X, long, long&>;
+template struct N2::PlusEquals0<N3::Y, long, short&>;
+template struct N2::PlusEquals0<int, int, int&>;
+template struct N2::PlusEquals0<N3::Y, int, short&>; // expected-note{{instantiation}}
+
+// ---------------------------------------------------------------------
+// Conditional operator
+// ---------------------------------------------------------------------
+template<typename T, typename U, typename Result>
+struct Conditional0 {
+  void f(T t, U u) {
+    Result result = t? : u;
+  }
+};
+
+template struct Conditional0<int, int, int>;
+
+// ---------------------------------------------------------------------
+// Statement expressions
+// ---------------------------------------------------------------------
+template<typename T>
+struct StatementExpr0 {
+  void f(T t) {
+    (void)({ if (t) t = t + 17; t + 12;}); // expected-error{{invalid}}
+  }
+};
+
+template struct StatementExpr0<int>;
+template struct StatementExpr0<N1::X>; // expected-note{{instantiation}}
+
+// ---------------------------------------------------------------------
+// __builtin_choose_expr
+// ---------------------------------------------------------------------
+template<bool Cond, typename T, typename U, typename Result>
+struct Choose0 {
+  void f(T t, U u) {
+    Result r = __builtin_choose_expr(Cond, t, u); // expected-error{{lvalue}}
+  }
+};
+
+template struct Choose0<true, int, float, int&>;
+template struct Choose0<false, int, float, float&>;
+template struct Choose0<true, int, float, float&>; // expected-note{{instantiation}}
+
+// ---------------------------------------------------------------------
+// __builtin_va_arg
+// ---------------------------------------------------------------------
+template<typename ArgType>
+struct VaArg0 {
+  void f(int n, ...) {
+    __builtin_va_list va;
+    __builtin_va_start(va, n);
+    for (int i = 0; i != n; ++i)
+      (void)__builtin_va_arg(va, ArgType);
+    __builtin_va_end(va);
+  }
+};
+
+template struct VaArg0<int>;
+
+template<typename VaList, typename ArgType>
+struct VaArg1 {
+  void f(int n, ...) {
+    VaList va;
+    __builtin_va_start(va, n); // expected-error{{int}}
+    for (int i = 0; i != n; ++i)
+      (void)__builtin_va_arg(va, ArgType);
+    __builtin_va_end(va);
+  }
+};
+
+template struct VaArg1<__builtin_va_list, int>;
+template struct VaArg1<int, int>; // expected-note{{instantiation}}
diff --git a/test/SemaTemplate/instantiate-expr-4.cpp b/test/SemaTemplate/instantiate-expr-4.cpp
new file mode 100644
index 0000000..8cd7342
--- /dev/null
+++ b/test/SemaTemplate/instantiate-expr-4.cpp
@@ -0,0 +1,327 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// ---------------------------------------------------------------------
+// C++ Functional Casts
+// ---------------------------------------------------------------------
+template<int N>
+struct ValueInit0 {
+  int f() {
+    return int();
+  }
+};
+
+template struct ValueInit0<5>;
+
+template<int N>
+struct FunctionalCast0 {
+  int f() {
+    return int(N);
+  }
+};
+
+template struct FunctionalCast0<5>;
+
+struct X { // expected-note 3 {{candidate constructor (the implicit copy constructor)}}
+  X(int, int); // expected-note 3 {{candidate constructor}}
+};
+
+template<int N, int M>
+struct BuildTemporary0 {
+  X f() {
+    return X(N, M);
+  }
+};
+
+template struct BuildTemporary0<5, 7>;
+
+template<int N, int M>
+struct Temporaries0 {
+  void f() {
+    (void)X(N, M);
+  }
+};
+
+template struct Temporaries0<5, 7>;
+
+// Ensure that both the constructor and the destructor are instantiated by
+// checking for parse errors from each.
+template<int N> struct BadX {
+  BadX() { int a[-N]; } // expected-error {{array size is negative}}
+  ~BadX() { int a[-N]; } // expected-error {{array size is negative}}
+};
+
+template<int N>
+struct PR6671 {
+  void f() { (void)BadX<1>(); } // expected-note 2 {{instantiation}}
+};
+template struct PR6671<1>;
+
+// ---------------------------------------------------------------------
+// new/delete expressions
+// ---------------------------------------------------------------------
+struct Y { };
+
+template<typename T>
+struct New0 {
+  T* f(bool x) {
+    if (x)
+      return new T; // expected-error{{no matching}}
+    else
+      return new T();
+  }
+};
+
+template struct New0<int>;
+template struct New0<Y>;
+template struct New0<X>; // expected-note{{instantiation}}
+
+template<typename T, typename Arg1>
+struct New1 {
+  T* f(bool x, Arg1 a1) {
+    return new T(a1); // expected-error{{no matching}}
+  }
+};
+
+template struct New1<int, float>;
+template struct New1<Y, Y>;
+template struct New1<X, Y>; // expected-note{{instantiation}}
+
+template<typename T, typename Arg1, typename Arg2>
+struct New2 {
+  T* f(bool x, Arg1 a1, Arg2 a2) {
+    return new T(a1, a2); // expected-error{{no matching}}
+  }
+};
+
+template struct New2<X, int, float>;
+template struct New2<X, int, int*>; // expected-note{{instantiation}}
+// FIXME: template struct New2<int, int, float>;
+
+// PR5833
+struct New3 {
+  New3();
+
+  void *operator new[](__SIZE_TYPE__) __attribute__((unavailable)); // expected-note{{explicitly made unavailable}}
+};
+
+template<class C>
+void* object_creator() {
+  return new C(); // expected-error{{call to unavailable function 'operator new[]'}}
+}
+
+template void *object_creator<New3[4]>(); // expected-note{{instantiation}}
+
+template<typename T>
+struct Delete0 {
+  void f(T t) {
+    delete t; // expected-error{{cannot delete}}
+    ::delete [] t;
+  }
+};
+
+template struct Delete0<int*>;
+template struct Delete0<X*>;
+template struct Delete0<int>; // expected-note{{instantiation}}
+
+namespace PR5755 {
+  template <class T>
+  void Foo() {
+    char* p = 0;
+    delete[] p;
+  }
+  
+  void Test() {
+    Foo<int>();
+  }
+}
+
+// ---------------------------------------------------------------------
+// throw expressions
+// ---------------------------------------------------------------------
+template<typename T>
+struct Throw1 {
+  void f(T t) {
+    throw;
+    throw t; // expected-error{{incomplete type}}
+  }
+};
+
+struct Incomplete; // expected-note 2{{forward}}
+
+template struct Throw1<int>;
+template struct Throw1<int*>;
+template struct Throw1<Incomplete*>; // expected-note{{instantiation}}
+
+// ---------------------------------------------------------------------
+// typeid expressions
+// ---------------------------------------------------------------------
+
+namespace std {
+  class type_info;
+}
+
+template<typename T>
+struct TypeId0 {
+  const std::type_info &f(T* ptr) {
+    if (ptr)
+      return typeid(ptr);
+    else
+      return typeid(T); // expected-error{{'typeid' of incomplete type 'Incomplete'}}
+  }
+};
+
+struct Abstract {
+  virtual void f() = 0;
+};
+
+template struct TypeId0<int>;
+template struct TypeId0<Incomplete>; // expected-note{{instantiation of member function}}
+template struct TypeId0<Abstract>;
+
+// ---------------------------------------------------------------------
+// type traits
+// ---------------------------------------------------------------------
+template<typename T>
+struct is_pod {
+  static const bool value = __is_pod(T);
+};
+
+static int is_pod0[is_pod<X>::value? -1 : 1];
+static int is_pod1[is_pod<Y>::value? 1 : -1];
+
+// ---------------------------------------------------------------------
+// initializer lists
+// ---------------------------------------------------------------------
+template<typename T, typename Val1>
+struct InitList1 {
+  void f(Val1 val1) { 
+    T x = { val1 };
+  }
+};
+
+struct APair {
+  int *x;
+  const float *y;
+};
+
+template struct InitList1<int[1], float>;
+template struct InitList1<APair, int*>;
+
+template<typename T, typename Val1, typename Val2>
+struct InitList2 {
+  void f(Val1 val1, Val2 val2) { 
+    T x = { val1, val2 }; // expected-error{{cannot initialize}}
+  }
+};
+
+template struct InitList2<APair, int*, float*>;
+template struct InitList2<APair, int*, double*>; // expected-note{{instantiation}}
+
+// ---------------------------------------------------------------------
+// member references
+// ---------------------------------------------------------------------
+template<typename T, typename Result>
+struct DotMemRef0 {
+  void f(T t) {
+    Result result = t.m; // expected-error{{non-const lvalue reference to type}}
+  }
+};
+
+struct MemInt {
+  int m;
+};
+
+struct InheritsMemInt : MemInt { };
+
+struct MemIntFunc {
+  static int m(int);
+};
+
+template struct DotMemRef0<MemInt, int&>;
+template struct DotMemRef0<InheritsMemInt, int&>;
+template struct DotMemRef0<MemIntFunc, int (*)(int)>;
+template struct DotMemRef0<MemInt, float&>; // expected-note{{instantiation}}
+
+template<typename T, typename Result>
+struct ArrowMemRef0 {
+  void f(T t) {
+    Result result = t->m; // expected-error 2{{non-const lvalue reference}}
+  }
+};
+
+template<typename T>
+struct ArrowWrapper {
+  T operator->();
+};
+
+template struct ArrowMemRef0<MemInt*, int&>;
+template struct ArrowMemRef0<InheritsMemInt*, int&>;
+template struct ArrowMemRef0<MemIntFunc*, int (*)(int)>;
+template struct ArrowMemRef0<MemInt*, float&>; // expected-note{{instantiation}}
+
+template struct ArrowMemRef0<ArrowWrapper<MemInt*>, int&>;
+template struct ArrowMemRef0<ArrowWrapper<InheritsMemInt*>, int&>;
+template struct ArrowMemRef0<ArrowWrapper<MemIntFunc*>, int (*)(int)>;
+template struct ArrowMemRef0<ArrowWrapper<MemInt*>, float&>; // expected-note{{instantiation}}
+template struct ArrowMemRef0<ArrowWrapper<ArrowWrapper<MemInt*> >, int&>;
+
+// FIXME: we should be able to return a MemInt without the reference!
+MemInt &createMemInt(int);
+
+template<int N>
+struct NonDepMemberExpr0 {
+  void f() {
+    createMemInt(N).m = N;
+  }
+};
+
+template struct NonDepMemberExpr0<0>; 
+
+template<typename T, typename Result>
+struct MemberFuncCall0 {
+  void f(T t) {
+    Result result = t.f();
+  }
+};
+
+template<typename T>
+struct HasMemFunc0 {
+  T f();
+};
+
+
+template struct MemberFuncCall0<HasMemFunc0<int&>, const int&>;
+
+template<typename Result>
+struct ThisMemberFuncCall0 {
+  Result g();
+
+  void f() {
+    Result r1 = g();
+    Result r2 = this->g();
+  }
+};
+
+template struct ThisMemberFuncCall0<int&>;
+
+template<typename T>
+struct NonDepMemberCall0 {
+  void foo(HasMemFunc0<int&> x) {
+    T result = x.f(); // expected-error{{non-const lvalue reference}}
+  }
+};
+
+template struct NonDepMemberCall0<int&>;
+template struct NonDepMemberCall0<const int&>;
+template struct NonDepMemberCall0<float&>; // expected-note{{instantiation}}
+
+
+template<typename T>
+struct QualifiedDeclRef0 {
+  T f() {
+    return is_pod<X>::value; // expected-error{{non-const lvalue reference to type 'int' cannot bind to a value of unrelated type 'bool const'}}
+  }
+};
+
+template struct QualifiedDeclRef0<bool>;
+template struct QualifiedDeclRef0<int&>; // expected-note{{instantiation}}
diff --git a/test/SemaTemplate/instantiate-expr-5.cpp b/test/SemaTemplate/instantiate-expr-5.cpp
new file mode 100644
index 0000000..941dae4
--- /dev/null
+++ b/test/SemaTemplate/instantiate-expr-5.cpp
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -fsyntax-only %s
+
+template <class A> int x(A x) { return x++; }
+int y() { return x<int>(1); }
diff --git a/test/SemaTemplate/instantiate-expr-basic.cpp b/test/SemaTemplate/instantiate-expr-basic.cpp
new file mode 100644
index 0000000..074fe69
--- /dev/null
+++ b/test/SemaTemplate/instantiate-expr-basic.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value -std=c++0x %s
+
+template <typename T>
+struct S {
+  void f() {
+    __func__; // PredefinedExpr
+    10;       // IntegerLiteral
+    10.5;     // FloatingLiteral
+    'c';      // CharacterLiteral
+    "hello";  // StringLiteral
+    true;     // CXXBooleanLiteralExpr
+    nullptr;  // CXXNullPtrLiteralExpr
+    __null;   // GNUNullExpr
+  }
+};
+
+template struct S<int>;
diff --git a/test/SemaTemplate/instantiate-field.cpp b/test/SemaTemplate/instantiate-field.cpp
new file mode 100644
index 0000000..60d4b21
--- /dev/null
+++ b/test/SemaTemplate/instantiate-field.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T>
+struct X {
+  int x;
+  T y; // expected-error{{data member instantiated with function type}}
+  T* z;
+  T bitfield : 12; // expected-error{{bit-field 'bitfield' has non-integral type 'float'}} \
+                  // expected-error{{data member instantiated with function type}}
+
+  mutable T x2; // expected-error{{data member instantiated with function type}}
+};
+
+void test1(const X<int> *xi) {
+  int i1 = xi->x;
+  const int &i2 = xi->y;
+  int* ip1 = xi->z;
+  int i3 = xi->bitfield;
+  xi->x2 = 17;
+}
+
+void test2(const X<float> *xf) {
+  (void)xf->x; // expected-note{{in instantiation of template class 'X<float>' requested here}}
+}
+
+void test3(const X<int(int)> *xf) {
+  (void)xf->x; // expected-note{{in instantiation of template class 'X<int (int)>' requested here}}
+}
diff --git a/test/SemaTemplate/instantiate-friend-class.cpp b/test/SemaTemplate/instantiate-friend-class.cpp
new file mode 100644
index 0000000..c87b8d0
--- /dev/null
+++ b/test/SemaTemplate/instantiate-friend-class.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// PR4794
+
+template <class T> class X
+{
+  friend class Y;
+};
+X<int> y;
+
diff --git a/test/SemaTemplate/instantiate-function-1.cpp b/test/SemaTemplate/instantiate-function-1.cpp
new file mode 100644
index 0000000..6e0d711
--- /dev/null
+++ b/test/SemaTemplate/instantiate-function-1.cpp
@@ -0,0 +1,222 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename T, typename U>
+struct X0 {
+  void f(T x, U y) { 
+    (void)(x + y); // expected-error{{invalid operands}}
+  }
+};
+
+struct X1 { };
+
+template struct X0<int, float>;
+template struct X0<int*, int>;
+template struct X0<int X1::*, int>; // expected-note{{instantiation of}}
+
+template<typename T>
+struct X2 {
+  void f(T);
+
+  T g(T x, T y) {
+    /* DeclStmt */;
+    T *xp = &x, &yr = y; // expected-error{{pointer to a reference}}
+    /* NullStmt */;
+  }
+};
+
+template struct X2<int>;
+template struct X2<int&>; // expected-note{{instantiation of}}
+
+template<typename T>
+struct X3 {
+  void f(T) {
+    Label:
+    T x;
+    goto Label;
+  }
+};
+
+template struct X3<int>;
+
+template <typename T> struct X4 {
+  T f() const {
+    return; // expected-warning{{non-void function 'f' should return a value}}
+  }
+  
+  T g() const {
+    return 1; // expected-warning{{void function 'g' should not return a value}}
+  }
+};
+
+template struct X4<void>; // expected-note{{in instantiation of}}
+template struct X4<int>; // expected-note{{in instantiation of}}
+
+struct Incomplete; // expected-note 2{{forward declaration}}
+
+template<typename T> struct X5 {
+  T f() { } // expected-error{{incomplete result type}}
+};
+void test_X5(X5<Incomplete> x5); // okay!
+
+template struct X5<Incomplete>; // expected-note{{instantiation}}
+
+template<typename T, typename U, typename V> struct X6 {
+  U f(T t, U u, V v) {
+    // IfStmt
+    if (t > 0)
+      return u;
+    else { 
+      if (t < 0)
+        return v; // expected-error{{cannot initialize return object of type}}
+    }
+
+    if (T x = t) {
+      t = x;
+    }
+    return v;
+  }
+};
+
+struct ConvertibleToInt {
+  operator int() const;
+};
+
+template struct X6<ConvertibleToInt, float, char>;
+template struct X6<bool, int, int*>; // expected-note{{instantiation}}
+
+template <typename T> struct X7 {
+  void f() {
+    void *v = this;
+  }
+};
+
+template struct X7<int>;
+
+template<typename T> struct While0 {
+  void f(T t) {
+    while (t) {
+    }
+
+    while (T t2 = T()) ;
+  }
+};
+
+template struct While0<float>;
+
+template<typename T> struct Do0 {
+  void f(T t) {
+    do {
+    } while (t); // expected-error{{not contextually}}
+  }
+};
+
+struct NotConvertibleToBool { };
+template struct Do0<ConvertibleToInt>;
+template struct Do0<NotConvertibleToBool>; // expected-note{{instantiation}}
+
+template<typename T> struct For0 {
+  void f(T f, T l) {
+    for (; f != l; ++f) {
+      if (*f)
+        continue;
+      else if (*f == 17)
+        break;
+    }
+  }
+};
+
+template struct For0<int*>;
+
+template<typename T> struct Member0 {
+  void f(T t) {
+    t;
+    t.f;
+    t->f;
+    
+    T* tp;
+    tp.f; // expected-error{{member reference base type 'T *' is not a structure or union}}
+    tp->f;
+
+    this->f;
+    this.f; // expected-error{{member reference base type 'Member0<T> *' is not a structure or union}}
+  }
+};
+
+template<typename T, typename U> struct Switch0 {
+  U f(T value, U v0, U v1, U v2) {
+    switch (value) {
+    case 0: return v0;
+
+    case 1: return v1;
+
+    case 2: // fall through
+
+    default:
+      return  v2;
+    }
+  }
+};
+
+template struct Switch0<int, float>;
+
+template<typename T, int I1, int I2> struct Switch1 {
+  T f(T x, T y, T z) {
+    switch (x) {
+    case I1: return y; // expected-note{{previous}}
+    case I2: return z; // expected-error{{duplicate}}
+    default: return x;
+    }
+  }
+};
+
+template struct Switch1<int, 1, 2>;
+template struct Switch1<int, 2, 2>; // expected-note{{instantiation}}
+
+template<typename T> struct IndirectGoto0 {
+  void f(T x) {
+    // FIXME: crummy error message below
+    goto *x; // expected-error{{incompatible}}
+
+  prior:
+    T prior_label;
+    prior_label = &&prior;
+
+    T later_label;
+    later_label = &&later;
+
+  later:
+    (void)(1+1);
+  }
+};
+
+template struct IndirectGoto0<void*>;
+template struct IndirectGoto0<int>; // expected-note{{instantiation}}
+
+template<typename T> struct TryCatch0 {
+  void f() {
+    try {
+    } catch (T t) { // expected-warning{{incomplete type}} \
+                    // expected-error{{abstract class}}
+    } catch (...) {
+    }
+  }
+};
+
+struct Abstract {
+  virtual void foo() = 0; // expected-note{{pure virtual}}
+};
+
+template struct TryCatch0<int>; // okay
+template struct TryCatch0<Incomplete*>; // expected-note{{instantiation}}
+template struct TryCatch0<Abstract>; // expected-note{{instantiation}}
+
+// PR4383
+template<typename T> struct X;
+template<typename T> struct Y : public X<T> {
+  Y& x() { return *this; }
+};
+
+// Make sure our assertions don't get too uppity.
+namespace test0 {
+  template <class T> class A { void foo(T array[10]); };
+  template class A<int>;
+}
diff --git a/test/SemaTemplate/instantiate-function-1.mm b/test/SemaTemplate/instantiate-function-1.mm
new file mode 100644
index 0000000..c67b598
--- /dev/null
+++ b/test/SemaTemplate/instantiate-function-1.mm
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// XFAIL: *
+
+template<typename T> struct Member0 {
+  void f(T t) {
+    t;
+    t.f;
+    t->f;
+    
+    T* tp;
+    tp.f;
+    tp->f;
+
+    this->f;
+    this.f; // expected-error{{member reference base type 'struct Member0 *const' is not a structure or union}}
+  }
+};
diff --git a/test/SemaTemplate/instantiate-function-2.cpp b/test/SemaTemplate/instantiate-function-2.cpp
new file mode 100644
index 0000000..6318fac
--- /dev/null
+++ b/test/SemaTemplate/instantiate-function-2.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template <typename T> struct S {
+  S() { }
+  S(T t);
+};
+
+template struct S<int>;
+
+void f() {
+  S<int> s1;
+  S<int> s2(10);
+}
diff --git a/test/SemaTemplate/instantiate-function-params.cpp b/test/SemaTemplate/instantiate-function-params.cpp
new file mode 100644
index 0000000..cfca020
--- /dev/null
+++ b/test/SemaTemplate/instantiate-function-params.cpp
@@ -0,0 +1,56 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// PR6619
+template<bool C> struct if_c { };
+template<typename T1> struct if_ {
+  typedef if_c< static_cast<bool>(T1::value)> almost_type_; // expected-note 7{{in instantiation}}
+};
+template <class Model, void (Model::*)()> struct wrap_constraints { };
+template <class Model> 
+inline char has_constraints_(Model* ,  // expected-note 4{{while substituting deduced template arguments into function template 'has_constraints_' [with }} \
+                             // expected-note 3{{candidate template ignored}}
+                               wrap_constraints<Model,&Model::constraints>* = 0); // expected-note 4{{in instantiation}}
+
+template <class Model> struct not_satisfied {
+  static const bool value = sizeof( has_constraints_((Model*)0)  == 1); // expected-error 3{{no matching function}}
+};
+template <class ModelFn> struct requirement_;
+template <void(*)()> struct instantiate {
+};
+template <class Model> struct requirement_<void(*)(Model)>                           : if_<       not_satisfied<Model>         >::type { // expected-error 3{{no type named}} \
+  // expected-note 7{{in instantiation}}
+};
+template <class Model> struct usage_requirements {
+};
+template < typename TT > struct InputIterator                            {
+    typedef  instantiate< & requirement_<void(*)(usage_requirements<InputIterator> x)>::failed> boost_concept_check1; // expected-note 2{{in instantiation}}
+};
+template < typename TT > struct ForwardIterator                              : InputIterator<TT>                              { // expected-note 2{{in instantiation}}
+  typedef instantiate< & requirement_<void(*)(usage_requirements<ForwardIterator> x)>::failed> boost_concept_check2; // expected-note 2 {{in instantiation}}
+
+};
+typedef instantiate< &requirement_<void(*)(ForwardIterator<char*> x)>::failed> boost_concept_checkX;// expected-note 6{{in instantiation}}
+
+template<typename T> struct X0 { };
+template<typename R, typename A1> struct X0<R(A1 param)> { };
+
+template<typename T, typename A1, typename A2>
+void instF0(X0<T(A1)> x0a, X0<T(A2)> x0b) {
+  X0<T(A1)> x0c;
+  X0<T(A2)> x0d;
+}
+
+template void instF0<int, int, float>(X0<int(int)>, X0<int(float)>);
+
+template<typename R, typename A1, R (*ptr)(A1)> struct FuncPtr { };
+template<typename A1, int (*ptr)(A1)> struct FuncPtr<int, A1, ptr> { };
+
+template<typename R, typename A1> R unary_func(A1);
+
+template<typename R, typename A1, typename A2>
+void use_func_ptr() {
+  FuncPtr<R, A1, &unary_func<R, A1> > fp1;
+  FuncPtr<R, A2, &unary_func<R, A2> > fp2;
+};
+
+template void use_func_ptr<int, float, double>();
diff --git a/test/SemaTemplate/instantiate-init.cpp b/test/SemaTemplate/instantiate-init.cpp
new file mode 100644
index 0000000..e292aa3
--- /dev/null
+++ b/test/SemaTemplate/instantiate-init.cpp
@@ -0,0 +1,57 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct X0 { // expected-note 4{{candidate}}
+  X0(int*, float*); // expected-note 4{{candidate}}
+};
+
+template<typename T, typename U>
+X0 f0(T t, U u) {
+  X0 x0(t, u); // expected-error{{no matching}}
+  return X0(t, u); // expected-error{{no matching}}
+}
+
+void test_f0(int *ip, float *fp, double *dp) {
+  f0(ip, fp);
+  f0(ip, dp); // expected-note{{instantiation}}
+}
+
+template<typename Ret, typename T, typename U>
+Ret f1(Ret *retty, T t, U u) {
+  Ret r0(t, u); // expected-error{{no matching}}
+  return Ret(t, u); // expected-error{{no matching}}
+}
+
+void test_f1(X0 *x0, int *ip, float *fp, double *dp) {
+  f1(x0, ip, fp);
+  f1(x0, ip, dp); // expected-note{{instantiation}}
+}
+
+namespace PR6457 {
+  template <typename T> struct X { explicit X(T* p = 0) { }; };
+  template <typename T> struct Y { Y(int, const T& x); };
+  struct A { };
+  template <typename T>
+  struct B {
+    B() : y(0, X<A>()) { }
+    Y<X<A> > y;
+  };
+  B<int> b;
+}
+
+namespace PR6657 {
+  struct X
+  {
+    X (int, int) { }
+  };
+
+  template <typename>
+  void f0()
+  {
+    X x = X(0, 0);
+  }
+
+  void f1()
+  {
+    f0<int>();
+  }
+}
diff --git a/test/SemaTemplate/instantiate-invalid.cpp b/test/SemaTemplate/instantiate-invalid.cpp
new file mode 100644
index 0000000..b8a5901
--- /dev/null
+++ b/test/SemaTemplate/instantiate-invalid.cpp
@@ -0,0 +1,52 @@
+// RUN: not %clang_cc1 -fsyntax-only %s
+namespace PR6375 {
+  template<class Conv> class rasterizer_sl_clip Conv::xi(x2), Conv::yi(y2));
+namespace agg
+{
+	template<class Clip=rasterizer_sl_clip_int> class rasterizer_scanline_aa
+	{
+		template<class Scanline> bool sweep_scanline(Scanline& sl)
+		{
+			unsigned num_cells = m_outline.scanline_num_cells(m_scan_y);
+			while(num_cells) { }
+		}
+	}
+    class scanline_u8 {}
+    template<class PixelFormat> class renderer_base { }
+}
+    template<class Rasterizer, class Scanline, class BaseRenderer, class ColorT>
+    void render_scanlines_aa_solid(Rasterizer& ras, Scanline& sl, BaseRenderer& ren, const ColorT& color)
+    {
+            while(ras.sweep_scanline(sl))
+            {
+        }
+    };
+namespace agg
+{
+    struct rgba8
+    {
+    };
+    template<class Rasterizer, class Scanline, class Renderer, class Ctrl>
+    void render_ctrl(Rasterizer& ras, Scanline& sl, Renderer& r, Ctrl& c)
+    {
+        unsigned i;
+            render_scanlines_aa_solid(ras, sl, r, c.color(i));
+        }
+    template<class ColorT> class rbox_ctrl : public rbox_ctrl_impl
+    {
+        const ColorT& color(unsigned i) const { return *m_colors[i]; }
+    }
+class the_application : public agg::platform_support
+{
+    agg::rbox_ctrl<agg::rgba8> m_polygons;
+    virtual void on_init()
+    {
+        typedef agg::renderer_base<pixfmt_type> base_ren_type;
+        base_ren_type ren_base(pf);
+        agg::scanline_u8 sl;
+        agg::rasterizer_scanline_aa<> ras;
+        agg::render_ctrl(ras, sl, ren_base, m_polygons);
+    }
+};
+}
+}
diff --git a/test/SemaTemplate/instantiate-local-class.cpp b/test/SemaTemplate/instantiate-local-class.cpp
new file mode 100644
index 0000000..d57ba8a
--- /dev/null
+++ b/test/SemaTemplate/instantiate-local-class.cpp
@@ -0,0 +1,52 @@
+// RUN: %clang_cc1 -verify %s
+template<typename T>
+void f0() {
+  struct X;
+  typedef struct Y {
+    T (X::* f1())(int) { return 0; }
+  } Y2;
+
+  Y2 y = Y();
+}
+
+template void f0<int>();
+
+// PR5764
+namespace PR5764 {
+  struct X {
+    template <typename T>
+    void Bar() {
+      typedef T ValueType;
+      struct Y {
+        Y() { V = ValueType(); }
+
+        ValueType V;
+      };
+
+      Y y;
+    }
+  };
+
+  void test(X x) {
+    x.Bar<int>();
+  }
+}
+
+// Instantiation of local classes with virtual functions.
+namespace local_class_with_virtual_functions {
+  template <typename T> struct X { };
+  template <typename T> struct Y { };
+
+  template <typename T>
+  void f() {
+    struct Z : public X<Y<T>*> {
+      virtual void g(Y<T>* y) { }
+      void g2(int x) {(void)x;}
+    };
+    Z z;
+    (void)z;
+  }
+
+  struct S { };
+  void test() { f<S>(); }
+}
diff --git a/test/SemaTemplate/instantiate-member-class.cpp b/test/SemaTemplate/instantiate-member-class.cpp
new file mode 100644
index 0000000..f1bdf3e
--- /dev/null
+++ b/test/SemaTemplate/instantiate-member-class.cpp
@@ -0,0 +1,83 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T>
+class X {
+public:
+  struct C { T &foo(); };
+
+  struct D {
+    struct E { T &bar(); }; // expected-error{{cannot form a reference to 'void'}}
+    struct F; // expected-note{{member is declared here}}
+  };
+};
+
+X<int>::C *c1;
+X<float>::C *c2;
+
+X<int>::X *xi; // expected-error{{qualified reference to 'X' is a constructor name rather than a type wherever a constructor can be declared}}
+X<float>::X *xf; // expected-error{{qualified reference to 'X' is a constructor name rather than a type wherever a constructor can be declared}}
+
+void test_naming() {
+  c1 = c2; // expected-error{{assigning to 'X<int>::C *' from incompatible type 'X<float>::C *'}}
+  xi = xf;  // expected-error{{assigning to 'X<int>::X<int> *' from incompatible type 'X<float>::X<float> *'}}
+    // FIXME: error above doesn't print the type X<int>::X cleanly!
+}
+
+void test_instantiation(X<double>::C *x,
+                        X<float>::D::E *e,
+                        X<float>::D::F *f) {
+  double &dr = x->foo();
+  float &fr = e->bar();
+  f->foo(); // expected-error{{implicit instantiation of undefined member 'X<float>::D::F'}}
+  
+}
+
+
+X<void>::C *c3; // okay
+X<void>::D::E *e1; // okay
+X<void>::D::E e2; // expected-note{{in instantiation of member class 'X<void>::D::E' requested here}}
+
+// Redeclarations.
+namespace test1 {
+  template <typename T> struct Registry {
+    struct node;
+    static node *Head;
+    struct node {
+      node(int v) { Head = this; }
+    };
+  };
+  void test() {
+    Registry<int>::node node(0);
+  }
+}
+
+// Redeclarations during explicit instantiations.
+namespace test2 {
+  template <typename T> class A {
+    class Foo;
+    class Foo {
+      int foo();
+    };
+  };
+  template class A<int>;
+
+  template <typename T> class B {
+    class Foo;
+    class Foo {
+    public:
+      typedef int X;
+    };
+    typename Foo::X x;
+    class Foo;
+  };
+  template class B<int>;
+
+  template <typename T> class C {
+    class Foo;
+    class Foo;
+  };
+  template <typename T> class C<T>::Foo {
+    int x;
+  };
+  template class C<int>;
+}
diff --git a/test/SemaTemplate/instantiate-member-expr.cpp b/test/SemaTemplate/instantiate-member-expr.cpp
new file mode 100644
index 0000000..188705c
--- /dev/null
+++ b/test/SemaTemplate/instantiate-member-expr.cpp
@@ -0,0 +1,51 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename T>
+struct S {
+ S() { }
+};
+
+template<typename T>
+struct vector {
+  void push_back(const T&) { int a[sizeof(T) ? -1: -1]; } // expected-error {{array size is negative}}
+};
+
+class GRExprEngine {
+public:
+ typedef vector<S<void *> >CheckersOrdered;
+ CheckersOrdered Checkers;
+
+ template <typename CHECKER>
+ void registerCheck(CHECKER *check) {
+   Checkers.push_back(S<void *>()); // expected-note {{in instantiation of member function 'vector<S<void *> >::push_back' requested here}}
+ }
+};
+
+class RetainReleaseChecker { };
+
+void f(GRExprEngine& Eng) {
+   Eng.registerCheck(new RetainReleaseChecker); // expected-note {{in instantiation of function template specialization 'GRExprEngine::registerCheck<RetainReleaseChecker>' requested here}}
+}
+
+// PR 5838
+namespace test1 {
+  template<typename T> struct A {
+    int a;
+  };
+
+  template<typename T> struct B : A<float>, A<T> {
+    void f() {
+      a = 0; // should not be ambiguous
+    }
+  };
+  template struct B<int>;
+
+  struct O {
+    int a;
+    template<typename T> struct B : A<T> {
+      void f() {
+        a = 0; // expected-error {{'test1::O::a' is not a member of class 'test1::O::B<int>'}}
+      }
+    };
+  };
+  template struct O::B<int>; // expected-note {{in instantiation}}
+}
diff --git a/test/SemaTemplate/instantiate-member-initializers.cpp b/test/SemaTemplate/instantiate-member-initializers.cpp
new file mode 100644
index 0000000..45503b3
--- /dev/null
+++ b/test/SemaTemplate/instantiate-member-initializers.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -fsyntax-only -Wall -verify %s
+
+template<typename T> struct A {
+  A() : a(1) { } // expected-error{{cannot initialize a member subobject of type 'void *' with an rvalue of type 'int'}}
+
+  T a;
+};
+
+A<int> a0;
+A<void*> a1; // expected-note{{in instantiation of member function 'A<void *>::A' requested here}}
+
+template<typename T> struct B {
+  B() : b(1), // expected-warning {{field 'b' will be initialized after field 'a'}}
+    a(2) { }
+  
+  int a;
+  int b;
+};
+
+B<int> b0; // expected-note {{in instantiation of member function 'B<int>::B' requested here}}
+
+template <class T> struct AA { AA(int); };
+template <class T> class BB : public AA<T> {
+public:
+  BB() : AA<T>(1) {}
+};
+BB<int> x;
diff --git a/test/SemaTemplate/instantiate-member-pointers.cpp b/test/SemaTemplate/instantiate-member-pointers.cpp
new file mode 100644
index 0000000..2308ac5
--- /dev/null
+++ b/test/SemaTemplate/instantiate-member-pointers.cpp
@@ -0,0 +1,55 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+struct Y {
+  int x;
+};
+
+template<typename T>
+struct X1 {
+  int f(T* ptr, int T::*pm) { // expected-error{{member pointer}}
+    return ptr->*pm;
+  }
+};
+
+template struct X1<Y>;
+template struct X1<int>; // expected-note{{instantiation}}
+
+template<typename T, typename Class>
+struct X2 {
+  T f(Class &obj, T Class::*pm) { // expected-error{{to a reference}} \
+                      // expected-error{{member pointer to void}}
+    return obj.*pm; 
+  }
+};
+
+template struct X2<int, Y>;
+template struct X2<int&, Y>; // expected-note{{instantiation}}
+template struct X2<const void, Y>; // expected-note{{instantiation}}
+
+template<typename T, typename Class, T Class::*Ptr>
+struct X3 {
+  X3<T, Class, Ptr> &operator=(const T& value) {
+    return *this;
+  }
+};
+
+X3<int, Y, &Y::x> x3;
+
+typedef int Y::*IntMember;
+
+template<IntMember Member>
+struct X4 {
+  X3<int, Y, Member> member;
+  
+  int &getMember(Y& y) { return y.*Member; }
+};
+
+int &get_X4(X4<&Y::x> x4, Y& y) { 
+  return x4.getMember(y); 
+}
+
+template<IntMember Member>
+void accept_X4(X4<Member>);
+
+void test_accept_X4(X4<&Y::x> x4) {
+  accept_X4(x4);
+}
diff --git a/test/SemaTemplate/instantiate-member-template.cpp b/test/SemaTemplate/instantiate-member-template.cpp
new file mode 100644
index 0000000..ae8425e
--- /dev/null
+++ b/test/SemaTemplate/instantiate-member-template.cpp
@@ -0,0 +1,158 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T>
+struct X0 {
+  template<typename U> T f0(U);
+  template<typename U> U& f1(T*, U); // expected-error{{pointer to a reference}} \
+                                     // expected-note{{candidate}}
+};
+
+X0<int> x0i;
+X0<void> x0v;
+X0<int&> x0ir; // expected-note{{instantiation}}
+
+void test_X0(int *ip, double *dp) {
+  X0<int> xi;
+  int i1 = xi.f0(ip);
+  double *&dpr = xi.f1(ip, dp);
+  xi.f1(dp, dp); // expected-error{{no matching}}
+
+  X0<void> xv;
+  double *&dpr2 = xv.f1(ip, dp);
+}
+
+template<typename T>
+struct X1 {
+  template<typename U>
+  struct Inner0 {
+    U x; 
+    T y; // expected-error{{void}}
+  };
+
+  template<typename U>
+  struct Inner1 {
+    U x; // expected-error{{void}}
+    T y;
+  };
+  
+  template<typename U>
+  struct Inner2 {
+    struct SuperInner {
+      U z; // expected-error{{void}}
+    };
+  };
+  
+  template<typename U>
+  struct Inner3 {
+    void f0(T t, U u) { // expected-note{{passing argument to parameter 't' here}}
+      (void)(t + u); // expected-error{{invalid operands}}
+    }
+    
+    template<typename V>
+    V f1(T t, U u, V) {
+      return t + u; // expected-error{{cannot initialize return object}}
+    }
+  };
+  
+  template<typename U>
+  struct Inner4;
+};
+
+template<typename T>
+template<typename U>
+struct X1<T>::Inner4 {
+  template<typename V>
+  V f2(T t, U u, V);
+  
+  static U value;
+};
+
+template<typename T>
+template<typename U>
+U X1<T>::Inner4<U>::value; // expected-error{{reference variable}}
+
+template<typename T>
+template<typename U>
+template<typename V>
+V X1<T>::Inner4<U>::f2(T t, U u, V) {
+  return t + u; // expected-error{{cannot initialize return object}}
+}
+
+void test_X1(int *ip, int i, double *dp) {
+  X1<void>::Inner0<int> *xvip; // okay
+  X1<void>::Inner0<int> xvi; // expected-note{{instantiation}}
+  
+  X1<int>::Inner1<void> *xivp; // okay
+  X1<int>::Inner1<void> xiv; // expected-note{{instantiation}}
+  
+  X1<int>::Inner2<void>::SuperInner *xisivp; // okay
+  X1<int>::Inner2<void>::SuperInner xisiv; // expected-note{{instantiation}}
+  
+  X1<int*>::Inner3<int> id3;
+  id3.f0(ip, i);
+  id3.f0(dp, i); // expected-error{{cannot initialize a parameter of type 'int *' with an lvalue of type 'double *'}}
+  id3.f1(ip, i, ip);
+  id3.f1(ip, i, dp); // expected-note{{instantiation}}
+  
+  X1<int*>::Inner3<double*> id3b;
+  id3b.f0(ip, dp); // expected-note{{instantiation}}
+  
+  X1<int*>::Inner4<int> id4;
+  id4.f2(ip, i, dp); // expected-note{{instantiation}}
+  
+  X1<int*>::Inner4<int>::value = 17;
+  i = X1<int*>::Inner4<int&>::value; // expected-note{{instantiation}}
+}
+
+
+template<typename T>
+struct X2 {
+  template<T *Ptr> // expected-error{{pointer to a reference}}
+  struct Inner;
+  
+  template<T Value> // expected-error{{cannot have type 'float'}}
+  struct Inner2;
+};
+
+X2<int&> x2a; // expected-note{{instantiation}}
+X2<float> x2b; // expected-note{{instantiation}}
+
+namespace N0 {
+  template<typename T>
+  struct X0 { };
+  
+  struct X1 {
+    template<typename T> void f(X0<T>& vals) { g(vals); }
+    template<typename T> void g(X0<T>& vals) { }
+  };
+  
+  void test(X1 x1, X0<int> x0i, X0<long> x0l) {
+    x1.f(x0i);
+    x1.f(x0l);
+  }  
+}
+
+namespace PR6239 {
+  template <typename T>  
+  struct X0 {  
+    class type {
+      typedef T E;    
+      template <E e>  // subsitute T for E and bug goes away
+      struct sfinae {  };  
+      
+      template <class U>  
+      typename sfinae<&U::operator=>::type test(int);  
+    };
+  };
+
+  template <typename T>  
+  struct X1 {  
+    typedef T E;    
+    template <E e>  // subsitute T for E and bug goes away
+    struct sfinae {  };  
+    
+    template <class U>  
+    typename sfinae<&U::operator=>::type test(int);  
+  };
+
+}
diff --git a/test/SemaTemplate/instantiate-method.cpp b/test/SemaTemplate/instantiate-method.cpp
new file mode 100644
index 0000000..3ef07d3
--- /dev/null
+++ b/test/SemaTemplate/instantiate-method.cpp
@@ -0,0 +1,129 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename T>
+class X {
+public:
+  void f(T x); // expected-error{{argument may not have 'void' type}}
+  void g(T*);
+
+  static int h(T, T); // expected-error {{argument may not have 'void' type}}
+};
+
+int identity(int x) { return x; }
+
+void test(X<int> *xi, int *ip, X<int(int)> *xf) {
+  xi->f(17);
+  xi->g(ip);
+  xf->f(&identity);
+  xf->g(identity);
+  X<int>::h(17, 25);
+  X<int(int)>::h(identity, &identity);
+}
+
+void test_bad() {
+  X<void> xv; // expected-note{{in instantiation of template class 'X<void>' requested here}}
+}
+
+template<typename T, typename U>
+class Overloading {
+public:
+  int& f(T, T); // expected-note{{previous declaration is here}}
+  float& f(T, U); // expected-error{{functions that differ only in their return type cannot be overloaded}}
+};
+
+void test_ovl(Overloading<int, long> *oil, int i, long l) {
+  int &ir = oil->f(i, i);
+  float &fr = oil->f(i, l);
+}
+
+void test_ovl_bad() {
+  Overloading<float, float> off; // expected-note{{in instantiation of template class 'Overloading<float, float>' requested here}}
+}
+
+template<typename T>
+class HasDestructor {
+public:
+  virtual ~HasDestructor() = 0;
+};
+
+int i = sizeof(HasDestructor<int>); // FIXME: forces instantiation, but 
+                // the code below should probably instantiate by itself.
+int abstract_destructor[__is_abstract(HasDestructor<int>)? 1 : -1];
+
+
+template<typename T>
+class Constructors {
+public:
+  Constructors(const T&);
+  Constructors(const Constructors &other);
+};
+
+void test_constructors() {
+  Constructors<int> ci1(17);
+  Constructors<int> ci2 = ci1;
+}
+
+
+template<typename T>
+struct ConvertsTo {
+  operator T();
+};
+
+void test_converts_to(ConvertsTo<int> ci, ConvertsTo<int *> cip) {
+  int i = ci;
+  int *ip = cip;
+}
+
+// PR4660
+template<class T> struct A0 { operator T*(); };
+template<class T> struct A1;
+
+int *a(A0<int> &x0, A1<int> &x1) {
+  int *y0 = x0;
+  int *y1 = x1; // expected-error{{no viable conversion}}
+}
+
+struct X0Base {
+  int &f();
+  int& g(int);
+  static double &g(double);
+};
+
+template<typename T>
+struct X0 : X0Base {
+};
+
+template<typename U>
+struct X1 : X0<U> {
+  int &f2() { 
+    return X0Base::f();
+  }
+};
+
+void test_X1(X1<int> x1i) {
+  int &ir = x1i.f2();
+}
+
+template<typename U>
+struct X2 : X0Base, U {
+  int &f2() { return X0Base::f(); }
+};
+
+template<typename T>
+struct X3 {
+  void test(T x) {
+    double& d1 = X0Base::g(x);
+  }
+};
+
+
+template struct X3<double>;
+
+// Don't try to instantiate this, it's invalid.
+namespace test1 {
+  template <class T> class A {};
+  template <class T> class B {
+    void foo(A<test1::Undeclared> &a) // expected-error {{no member named 'Undeclared' in namespace 'test1'}}
+    {}
+  };
+  template class B<int>;
+}
diff --git a/test/SemaTemplate/instantiate-non-type-template-parameter.cpp b/test/SemaTemplate/instantiate-non-type-template-parameter.cpp
new file mode 100644
index 0000000..414e62b
--- /dev/null
+++ b/test/SemaTemplate/instantiate-non-type-template-parameter.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// PR5311
+template<typename T>
+class StringSwitch {
+public:
+  template<unsigned N>
+  void Case(const char (&S)[N], const int & Value) {
+  }
+};
+
+int main(int argc, char *argv[]) {
+  (void)StringSwitch<int>();
+}
diff --git a/test/SemaTemplate/instantiate-objc-1.mm b/test/SemaTemplate/instantiate-objc-1.mm
new file mode 100644
index 0000000..92d0d6c
--- /dev/null
+++ b/test/SemaTemplate/instantiate-objc-1.mm
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// Obj-C string literal expressions
+template <typename T> struct StringTest {
+  void f() {
+    (void)@"Hello";
+  }
+};
+
+template struct StringTest<int>;
+template struct StringTest<double>;
+
+// @selector expressions
+template <typename T> struct SelectorTest {
+  SEL f() {
+    return @selector(multiple:arguments:);
+  }
+  SEL f2() {
+    return @selector(multiple:arguments:);
+  }
+};
+
+template struct SelectorTest<int>;
+template struct SelectorTest<double>;
+
+// @protocol expressions
+@protocol P
+@end
+
+template <typename T> struct ProtocolTest {
+  void f() {
+    (void)@protocol(P);
+  }
+};
+
+template struct ProtocolTest<int>;
+template struct ProtocolTest<double>;
+
+// @encode expressions
+template <typename T> struct EncodeTest {
+  static const char *encode(T t) { 
+    return @encode(T);
+  }
+};
+
+template struct EncodeTest<int>;
+template struct EncodeTest<double>;
diff --git a/test/SemaTemplate/instantiate-overloaded-arrow.cpp b/test/SemaTemplate/instantiate-overloaded-arrow.cpp
new file mode 100644
index 0000000..ee36427
--- /dev/null
+++ b/test/SemaTemplate/instantiate-overloaded-arrow.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// PR5488
+
+struct X {
+  int x;
+};
+
+struct Iter {
+  X* operator->();
+};
+
+template <typename T>
+void Foo() {
+  (void)Iter()->x;
+}
+
+void Func() {
+  Foo<int>();
+}
+
diff --git a/test/SemaTemplate/instantiate-static-var.cpp b/test/SemaTemplate/instantiate-static-var.cpp
new file mode 100644
index 0000000..e90ac52
--- /dev/null
+++ b/test/SemaTemplate/instantiate-static-var.cpp
@@ -0,0 +1,117 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename T, T Divisor>
+class X {
+public:
+  static const T value = 10 / Divisor; // expected-error{{in-class initializer is not an integral constant expression}}
+};
+
+int array1[X<int, 2>::value == 5? 1 : -1];
+X<int, 0> xi0; // expected-note{{in instantiation of template class 'X<int, 0>' requested here}}
+
+
+template<typename T>
+class Y {
+  static const T value = 0; // expected-error{{'value' can only be initialized if it is a static const integral data member}}
+};
+
+Y<float> fy; // expected-note{{in instantiation of template class 'Y<float>' requested here}}
+
+
+// out-of-line static member variables
+
+template<typename T>
+struct Z {
+  static T value;
+};
+
+template<typename T>
+T Z<T>::value; // expected-error{{no matching constructor}}
+
+struct DefCon {};
+
+struct NoDefCon { 
+  NoDefCon(const NoDefCon&); // expected-note{{candidate constructor}}
+};
+
+void test() {
+  DefCon &DC = Z<DefCon>::value;
+  NoDefCon &NDC = Z<NoDefCon>::value; // expected-note{{instantiation}}
+}
+
+// PR5609
+struct X1 {
+  ~X1();  // The errors won't be triggered without this dtor.
+};
+
+template <typename T>
+struct Y1 {
+  static char Helper(T);
+  static const int value = sizeof(Helper(T()));
+};
+
+struct X2 {
+  virtual ~X2();
+};
+
+namespace std {
+  class type_info { };
+}
+
+template <typename T>
+struct Y2 {
+  static T &Helper();
+  static const int value = sizeof(typeid(Helper()));
+};
+
+template <int>
+struct Z1 {};
+
+void Test() {
+  Z1<Y1<X1>::value> x;
+  int y[Y1<X1>::value];
+  Z1<Y2<X2>::value> x2;
+  int y2[Y2<X2>::value];
+}
+
+// PR5672
+template <int n>
+struct X3 {};
+
+class Y3 {
+ public:
+  ~Y3();  // The error isn't triggered without this dtor.
+
+  void Foo(X3<1>);
+};
+
+template <typename T>
+struct SizeOf {
+  static const int value = sizeof(T);
+};
+
+void MyTest3() {
+   Y3().Foo(X3<SizeOf<char>::value>());
+}
+
+namespace PR6449 {
+  template<typename T>    
+  struct X0  {
+    static const bool var = false;
+  };
+
+  template<typename T>
+  const bool X0<T>::var;
+
+  template<typename T>
+  struct X1 : public X0<T> {
+    static const bool var = false;
+  };
+
+  template<typename T>      
+  const bool X1<T>::var;
+
+  template class X0<char>;
+  template class X1<char>;
+
+}
+
diff --git a/test/SemaTemplate/instantiate-subscript.cpp b/test/SemaTemplate/instantiate-subscript.cpp
new file mode 100644
index 0000000..8c119ec
--- /dev/null
+++ b/test/SemaTemplate/instantiate-subscript.cpp
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+
+struct Sub0 {
+  int &operator[](int);
+};
+
+struct Sub1 {
+  long &operator[](long); // expected-note{{candidate function}}
+};
+
+struct ConvertibleToInt {
+  operator int();
+};
+
+template<typename T, typename U, typename Result>
+struct Subscript0 {
+  void test(T t, U u) {
+    Result &result = t[u]; // expected-error{{no viable overloaded operator[] for type}}
+  }
+};
+
+template struct Subscript0<int*, int, int&>;
+template struct Subscript0<Sub0, int, int&>;
+template struct Subscript0<Sub1, ConvertibleToInt, long&>;
+template struct Subscript0<Sub1, Sub0, long&>; // expected-note{{instantiation}}
+
+// PR5345
+template <typename T>
+struct S {
+  bool operator[](int n) const { return true; }
+};
+
+template <typename T>
+void Foo(const S<int>& s, T x) {
+  if (s[0]) {}
+}
+
+void Bar() {
+  Foo(S<int>(), 0);
+}
diff --git a/test/SemaTemplate/instantiate-template-template-parm.cpp b/test/SemaTemplate/instantiate-template-template-parm.cpp
new file mode 100644
index 0000000..f48a0c7
--- /dev/null
+++ b/test/SemaTemplate/instantiate-template-template-parm.cpp
@@ -0,0 +1,46 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<template<typename T> class MetaFun, typename Value>
+struct apply {
+  typedef typename MetaFun<Value>::type type;
+};
+
+template<class T>
+struct add_pointer {
+  typedef T* type;
+};
+
+template<class T>
+struct add_reference {
+  typedef T& type;
+};
+
+int i;
+apply<add_pointer, int>::type ip = &i;
+apply<add_reference, int>::type ir = i;
+apply<add_reference, float>::type fr = i; // expected-error{{non-const lvalue reference to type 'float' cannot bind to a value of unrelated type 'int'}}
+
+// Template template parameters
+template<int> struct B; // expected-note{{has a different type 'int'}}
+
+template<typename T, 
+         template<T Value> class X> // expected-error{{cannot have type 'float'}} \
+                                    // expected-note{{with type 'long'}}
+struct X0 { };
+
+X0<int, B> x0b1;
+X0<float, B> x0b2; // expected-note{{while substituting}}
+X0<long, B> x0b3; // expected-error{{template template argument has different template parameters}}
+
+template<template<int V> class TT> // expected-note{{parameter with type 'int'}}
+struct X1 { };
+
+template<typename T, template<T V> class TT>
+struct X2 {
+  X1<TT> x1; // expected-error{{has different template parameters}}
+};
+
+template<int V> struct X3i { };
+template<long V> struct X3l { }; // expected-note{{different type 'long'}}
+
+X2<int, X3i> x2okay;
+X2<long, X3l> x2bad; // expected-note{{instantiation}}
diff --git a/test/SemaTemplate/instantiate-try-catch.cpp b/test/SemaTemplate/instantiate-try-catch.cpp
new file mode 100644
index 0000000..aa809e4
--- /dev/null
+++ b/test/SemaTemplate/instantiate-try-catch.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++0x -verify %s
+
+template<typename T> struct TryCatch0 {
+  void f() {
+    try {
+    } catch (T&&) { // expected-error 2{{cannot catch exceptions by rvalue reference}}
+    }
+  }
+};
+
+template struct TryCatch0<int&>; // okay
+template struct TryCatch0<int&&>; // expected-note{{instantiation}}
+template struct TryCatch0<int>; // expected-note{{instantiation}}
+
diff --git a/test/SemaTemplate/instantiate-type.cpp b/test/SemaTemplate/instantiate-type.cpp
new file mode 100644
index 0000000..f5d0270
--- /dev/null
+++ b/test/SemaTemplate/instantiate-type.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -fsyntax-only %s
+
+int* f(int);
+float *f(...);
+
+template<typename T>
+struct X {
+  typedef typeof(T*) typeof_type;
+  typedef typeof(f(T())) typeof_expr;
+};
+
+int *iptr0;
+float *fptr0;
+X<int>::typeof_type &iptr1 = iptr0;
+
+X<int>::typeof_expr &iptr2 = iptr0;
+X<float*>::typeof_expr &fptr1 = fptr0;
diff --git a/test/SemaTemplate/instantiate-typedef.cpp b/test/SemaTemplate/instantiate-typedef.cpp
new file mode 100644
index 0000000..4e6cd24
--- /dev/null
+++ b/test/SemaTemplate/instantiate-typedef.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T>
+struct add_pointer {
+  typedef T* type; // expected-error{{'type' declared as a pointer to a reference}}
+};
+
+add_pointer<int>::type test1(int * ptr) { return ptr; }
+
+add_pointer<float>::type test2(int * ptr) { 
+  return ptr; // expected-error{{cannot initialize return object of type 'add_pointer<float>::type' (aka 'float *') with an lvalue of type 'int *'}}
+}
+
+add_pointer<int&>::type // expected-note{{in instantiation of template class 'add_pointer<int &>' requested here}}
+test3(); 
diff --git a/test/SemaTemplate/instantiate-using-decl.cpp b/test/SemaTemplate/instantiate-using-decl.cpp
new file mode 100644
index 0000000..2579044
--- /dev/null
+++ b/test/SemaTemplate/instantiate-using-decl.cpp
@@ -0,0 +1,63 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace test0 {
+  namespace N { }
+
+  template<typename T>
+  struct A {
+    void f();
+  };
+
+  template<typename T>
+  struct B : A<T> {
+    using A<T>::f;
+
+    void g() {
+      using namespace N;
+      f();
+    }
+  };
+
+  template struct B<int>;
+}
+
+namespace test1 {
+  template <class Derived> struct Visitor1 {
+    void Visit(struct Object1*);
+  };
+  template <class Derived> struct Visitor2 {
+    void Visit(struct Object2*); // expected-note {{candidate function}}
+  };
+
+  template <class Derived> struct JoinVisitor
+      : Visitor1<Derived>, Visitor2<Derived> {
+    typedef Visitor1<Derived> Base1;
+    typedef Visitor2<Derived> Base2;
+
+    void Visit(struct Object1*);  // expected-note {{candidate function}}
+    using Base2::Visit;
+  };
+
+  class Knot : public JoinVisitor<Knot> {
+  };
+
+  void test() {
+    Knot().Visit((struct Object1*) 0);
+    Knot().Visit((struct Object2*) 0);
+    Knot().Visit((struct Object3*) 0); // expected-error {{no matching member function for call}}
+  }
+}
+
+// PR5847
+namespace test2 {
+  namespace ns {
+    void foo();
+  }
+
+  template <class T> void bar(T* ptr) {
+    using ns::foo;
+    foo();
+  }
+
+  template void bar(char *);
+}
diff --git a/test/SemaTemplate/instantiation-backtrace.cpp b/test/SemaTemplate/instantiation-backtrace.cpp
new file mode 100644
index 0000000..21456e9
--- /dev/null
+++ b/test/SemaTemplate/instantiation-backtrace.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename T> struct A; // expected-note 4{{template is declared here}}
+
+template<typename T> struct B : A<T*> { }; // expected-error{{implicit instantiation of undefined template}} \
+// expected-error{{implicit instantiation of undefined template 'A<X *>'}}
+
+template<typename T> struct C : B<T> { } ; // expected-note{{instantiation of template class}}
+
+template<typename T> struct D : C<T> { }; // expected-note{{instantiation of template class}}
+
+template<typename T> struct E : D<T> { }; // expected-note{{instantiation of template class}}
+
+template<typename T> struct F : E<T(T)> { }; // expected-note{{instantiation of template class}}
+
+void f() {
+ (void)sizeof(F<int>); // expected-note{{instantiation of template class}}
+}
+
+typedef struct { } X;
+
+void g() {
+  (void)sizeof(B<X>); // expected-note{{in instantiation of template class 'B<X>' requested here}}
+}
+
+template<typename T> 
+struct G : A<T>, // expected-error{{implicit instantiation of undefined template 'A<int>'}}
+  A<T*> // expected-error{{implicit instantiation of undefined template 'A<int *>'}}
+  { };
+
+void h() {
+  (void)sizeof(G<int>); // expected-note{{in instantiation of template class 'G<int>' requested here}}
+}
diff --git a/test/SemaTemplate/instantiation-default-1.cpp b/test/SemaTemplate/instantiation-default-1.cpp
new file mode 100644
index 0000000..6f5a660
--- /dev/null
+++ b/test/SemaTemplate/instantiation-default-1.cpp
@@ -0,0 +1,102 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename T, typename U = const T> struct Def1;
+
+template<> struct Def1<int> { 
+  void foo();
+};
+
+template<> struct Def1<const int> { // expected-note{{previous definition is here}}
+  void bar();
+};
+
+template<> struct Def1<int&> {
+  void wibble();
+};
+
+void test_Def1(Def1<int, const int> *d1, Def1<const int, const int> *d2,
+               Def1<int&, int&> *d3) {
+  d1->foo();
+  d2->bar();
+  d3->wibble();
+}
+
+template<typename T,  // FIXME: bad error message below, needs better location info
+         typename T2 = const T*>  // expected-error{{'T2' declared as a pointer to a reference}}
+  struct Def2;
+
+template<> struct Def2<int> { 
+  void foo();
+};
+
+void test_Def2(Def2<int, int const*> *d2) {
+  d2->foo();
+}
+
+typedef int& int_ref_t;
+Def2<int_ref_t> *d2; // expected-note{{in instantiation of default argument for 'Def2<int &>' required here}}
+
+
+template<> struct Def1<const int, const int> { }; // expected-error{{redefinition of 'Def1<int const>'}}
+
+template<typename T, typename T2 = T&> struct Def3;
+
+template<> struct Def3<int> { 
+  void foo();
+};
+
+template<> struct Def3<int&> { 
+  void bar();
+};
+
+void test_Def3(Def3<int, int&> *d3a, Def3<int&, int&> *d3b) {
+  d3a->foo();
+  d3b->bar();
+}
+
+
+template<typename T, typename T2 = T[]> struct Def4;
+
+template<> struct Def4<int> {
+  void foo();
+};
+
+void test_Def4(Def4<int, int[]> *d4a) {
+  d4a->foo();
+}
+
+template<typename T, typename T2 = T const[12]> struct Def5;
+
+template<> struct Def5<int> {
+  void foo();
+};
+
+template<> struct Def5<int, int const[13]> {
+  void bar();
+};
+
+void test_Def5(Def5<int, const int[12]> *d5a, Def5<int, const int[13]> *d5b) {
+  d5a->foo();
+  d5b->bar();
+}
+
+template<typename R, typename Arg1, typename Arg2 = Arg1,
+         typename FuncType = R (*)(Arg1, Arg2)>
+  struct Def6;
+
+template<> struct Def6<int, float> { 
+  void foo();
+};
+
+template<> struct Def6<bool, int[5], float(double, double)> {
+  void bar();
+};
+
+bool test_Def6(Def6<int, float, float> *d6a, 
+               Def6<int, float, float, int (*)(float, float)> *d6b,
+               Def6<bool, int[5], float(double, double),
+                    bool(*)(int*, float(*)(double, double))> *d6c) {
+  d6a->foo();
+  d6b->foo();
+  d6c->bar();
+  return d6a == d6b;
+}
diff --git a/test/SemaTemplate/instantiation-default-2.cpp b/test/SemaTemplate/instantiation-default-2.cpp
new file mode 100644
index 0000000..5a744a0
--- /dev/null
+++ b/test/SemaTemplate/instantiation-default-2.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T, T Value> struct Constant; // expected-note{{template parameter is declared here}} \
+// FIXME: bad location expected-error{{a non-type template parameter cannot have type 'float'}}
+
+Constant<int, 5> *c1;
+
+int x;
+float f(int, double);
+
+Constant<int&, x> *c2;
+Constant<int*, &x> *c3;
+Constant<float (*)(int, double), f> *c4;
+Constant<float (*)(int, double), &f> *c5;
+
+Constant<float (*)(int, int), f> *c6; // expected-error{{non-type template argument of type 'float (int, double)' cannot be converted to a value of type 'float (*)(int, int)'}}
+
+Constant<float, 0> *c7; // expected-note{{while substituting}}
diff --git a/test/SemaTemplate/instantiation-default-3.cpp b/test/SemaTemplate/instantiation-default-3.cpp
new file mode 100644
index 0000000..dae6b18
--- /dev/null
+++ b/test/SemaTemplate/instantiation-default-3.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T> struct A { };
+
+template<typename T, typename U = A<T*> >
+  struct B : U { };
+
+template<>
+struct A<int*> { 
+  void foo();
+};
+
+template<>
+struct A<float*> { 
+  void bar();
+};
+
+void test(B<int> *b1, B<float> *b2) {
+  b1->foo();
+  b2->bar();
+}
diff --git a/test/SemaTemplate/instantiation-depth.cpp b/test/SemaTemplate/instantiation-depth.cpp
new file mode 100644
index 0000000..a2b9d2e
--- /dev/null
+++ b/test/SemaTemplate/instantiation-depth.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -ftemplate-depth 5 -ftemplate-backtrace-limit 4 %s
+
+template<typename T> struct X : X<T*> { }; \
+// expected-error{{recursive template instantiation exceeded maximum depth of 5}} \
+// expected-note 3 {{instantiation of template class}} \
+// expected-note {{skipping 2 contexts in backtrace}} \
+// expected-note {{use -ftemplate-depth-N to increase recursive template instantiation depth}}
+
+void test() { 
+  (void)sizeof(X<int>); // expected-note {{instantiation of template class}}
+}
diff --git a/test/SemaTemplate/member-access-expr.cpp b/test/SemaTemplate/member-access-expr.cpp
new file mode 100644
index 0000000..24db791
--- /dev/null
+++ b/test/SemaTemplate/member-access-expr.cpp
@@ -0,0 +1,123 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename T>
+void call_f0(T x) {
+  x.Base::f0();
+}
+
+struct Base {
+  void f0();
+};
+
+struct X0 : Base { 
+  typedef Base CrazyBase;
+};
+
+void test_f0(X0 x0) {
+  call_f0(x0);
+}
+
+template<typename TheBase, typename T>
+void call_f0_through_typedef(T x) {
+  typedef TheBase Base2;
+  x.Base2::f0();
+}
+
+void test_f0_through_typedef(X0 x0) {
+  call_f0_through_typedef<Base>(x0);
+}
+
+template<typename TheBase, typename T>
+void call_f0_through_typedef2(T x) {
+  typedef TheBase CrazyBase; // expected-note{{current scope}}
+  x.CrazyBase::f0(); // expected-error{{ambiguous}} \
+                     // expected-error 2{{no member named}}
+}
+
+struct OtherBase { };
+
+struct X1 : Base, OtherBase { 
+  typedef OtherBase CrazyBase; // expected-note{{object type}}
+};
+
+void test_f0_through_typedef2(X0 x0, X1 x1) {
+  call_f0_through_typedef2<Base>(x0);
+  call_f0_through_typedef2<OtherBase>(x1); // expected-note{{instantiation}}
+  call_f0_through_typedef2<Base>(x1); // expected-note{{instantiation}}
+}
+
+
+struct X2 {
+  operator int() const;
+};
+
+template<typename T, typename U>
+T convert(const U& value) {
+  return value.operator T(); // expected-error{{operator long}}
+}
+
+void test_convert(X2 x2) {
+  convert<int>(x2);
+  convert<long>(x2); // expected-note{{instantiation}}
+}
+
+template<typename T>
+void destruct(T* ptr) {
+  ptr->~T();
+  ptr->T::~T();
+}
+
+template<typename T>
+void destruct_intptr(int *ip) {
+  ip->~T();
+  ip->T::~T();
+}
+
+void test_destruct(X2 *x2p, int *ip) {
+  destruct(x2p);
+  destruct(ip);
+  destruct_intptr<int>(ip);
+}
+
+// PR5220
+class X3 {
+protected:
+  template <int> float* &f0();
+  template <int> const float* &f0() const;
+  void f1() {
+    (void)static_cast<float*>(f0<0>());
+  }
+  void f1() const{
+    (void)f0<0>();
+  }
+};
+
+// Fun with template instantiation and conversions
+struct X4 {
+  int& member();
+  float& member() const;
+};
+
+template<typename T>
+struct X5 {
+  void f(T* ptr) { int& ir = ptr->member(); }
+  void g(T* ptr) { float& fr = ptr->member(); }
+};
+
+void test_X5(X5<X4> x5, X5<const X4> x5c, X4 *xp, const X4 *cxp) {
+  x5.f(xp);
+  x5c.g(cxp);
+}
+
+// In theory we can do overload resolution at template-definition time on this.
+// We should at least not assert.
+namespace test4 {
+  struct Base {
+    template <class T> void foo() {}
+  };
+
+  template <class T> struct Foo : Base {
+    void test() {
+      foo<int>();
+    }
+  };
+}
diff --git a/test/SemaTemplate/member-function-template.cpp b/test/SemaTemplate/member-function-template.cpp
new file mode 100644
index 0000000..aea6285
--- /dev/null
+++ b/test/SemaTemplate/member-function-template.cpp
@@ -0,0 +1,87 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct X {
+  template<typename T> T& f0(T);
+  
+  void g0(int i, double d) {
+    int &ir = f0(i);
+    double &dr = f0(d);
+  }
+  
+  template<typename T> T& f1(T);
+  template<typename T, typename U> U& f1(T, U);
+  
+  void g1(int i, double d) {
+    int &ir1 = f1(i);
+    int &ir2 = f1(d, i);
+    int &ir3 = f1(i, i);
+  }
+};
+
+void test_X_f0(X x, int i, float f) {
+  int &ir = x.f0(i);
+  float &fr = x.f0(f);
+}
+
+void test_X_f1(X x, int i, float f) {
+  int &ir1 = x.f1(i);
+  int &ir2 = x.f1(f, i);
+  int &ir3 = x.f1(i, i);
+}
+
+void test_X_f0_address() {
+  int& (X::*pm1)(int) = &X::f0;
+  float& (X::*pm2)(float) = &X::f0;
+}
+
+void test_X_f1_address() {
+  int& (X::*pm1)(int) = &X::f1;
+  float& (X::*pm2)(float) = &X::f1;
+  int& (X::*pm3)(float, int) = &X::f1;
+}
+
+void test_X_f0_explicit(X x, int i, long l) {
+  int &ir1 = x.f0<int>(i);
+  int &ir2 = x.f0<>(i);
+  long &il1 = x.f0<long>(i);
+}
+
+// PR4608
+class A { template <class x> x a(x z) { return z+y; } int y; };
+
+// PR5419
+struct Functor {
+  template <typename T>
+  bool operator()(const T& v) const {
+    return true;
+  }
+};
+
+void test_Functor(Functor f) {
+  f(1);
+}
+
+// Instantiation on ->
+template<typename T>
+struct X1 {
+  template<typename U> U& get();
+};
+
+template<typename T> struct X2; // expected-note{{here}}
+
+void test_incomplete_access(X1<int> *x1, X2<int> *x2) {
+  float &fr = x1->get<float>();
+  (void)x2->get<float>(); // expected-error{{implicit instantiation of undefined template}}
+}
+
+// Instantiation of template template parameters in a member function
+// template.
+namespace TTP {
+  template<int Dim> struct X {
+    template<template<class> class M, class T> void f(const M<T>&);
+  };
+
+  template<typename T> struct Y { };
+
+  void test_f(X<3> x, Y<int> y) { x.f(y); }
+}
diff --git a/test/SemaTemplate/member-initializers.cpp b/test/SemaTemplate/member-initializers.cpp
new file mode 100644
index 0000000..40f56b3
--- /dev/null
+++ b/test/SemaTemplate/member-initializers.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T> struct A {
+  A() : j(10), i(10) { }
+  
+  int i;
+  int j;
+};
+
+template<typename T> struct B : A<T> {
+  B() : A<T>() { }
+};
+
diff --git a/test/SemaTemplate/member-template-access-expr.cpp b/test/SemaTemplate/member-template-access-expr.cpp
new file mode 100644
index 0000000..ea17cdb
--- /dev/null
+++ b/test/SemaTemplate/member-template-access-expr.cpp
@@ -0,0 +1,125 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename U, typename T>
+U f0(T t) {
+  return t.template get<U>();
+}
+
+template<typename U, typename T>
+int &f1(T t) {
+  // FIXME: When we pretty-print this, we lose the "template" keyword.
+  return t.U::template get<int&>();
+}
+
+struct X {
+  template<typename T> T get();
+};
+
+void test_f0(X x) {
+  int i = f0<int>(x);
+  int &ir = f0<int&>(x);
+}
+
+struct XDerived : public X {
+};
+
+void test_f1(XDerived xd) {
+  int &ir = f1<X>(xd);
+}
+
+// PR5213
+template <class T>
+struct A {};
+
+template<class T>
+class B
+{
+  A<T> a_;
+  
+public:
+  void destroy();
+};
+
+template<class T>
+void
+B<T>::destroy()
+{
+  a_.~A<T>();
+}
+
+void do_destroy_B(B<int> b) {
+  b.destroy();
+}
+
+struct X1 {
+  int* f1(int);
+  template<typename T> float* f1(T);
+  
+  static int* f2(int);
+  template<typename T> static float* f2(T);
+};
+
+void test_X1(X1 x1) {
+  float *fp1 = x1.f1<>(17);
+  float *fp2 = x1.f1<int>(3.14);
+  int *ip1 = x1.f1(17);
+  float *ip2 = x1.f1(3.14);
+  
+  float* (X1::*mf1)(int) = &X1::f1;
+  float* (X1::*mf2)(int) = &X1::f1<>;
+  float* (X1::*mf3)(float) = &X1::f1<float>;
+  
+  float* (*fp3)(int) = &X1::f2;
+  float* (*fp4)(int) = &X1::f2<>;
+  float* (*fp5)(float) = &X1::f2<float>;  
+  float* (*fp6)(int) = X1::f2;
+  float* (*fp7)(int) = X1::f2<>;
+  float* (*fp8)(float) = X1::f2<float>;  
+}
+
+template<int A> struct X2 { 
+  int m;
+};
+
+template<typename T>
+struct X3 : T { };
+
+template<typename T>
+struct X4 {
+  template<typename U>
+  void f(X2<sizeof(X3<U>().U::m)>);
+};
+
+void f(X4<X3<int> > x4i) {
+  X2<sizeof(int)> x2;
+  x4i.f<X2<sizeof(int)> >(x2);
+}
+
+template<typename T>
+struct X5 {
+  template<typename U>
+  void f();
+  
+  void g() {
+    this->f<T*>();
+  }
+};
+
+namespace PR6021 {
+  template< class T1, class T2 >
+  class Outer
+  {
+  public: // Range operations
+    template< class X > X tmpl( const X* = 0 ) const;
+
+    struct Inner
+    {
+      const Outer& o;
+
+      template< class X >
+      operator X() const
+      {
+        return o.tmpl<X>();
+      }
+    };
+  };
+}
diff --git a/test/SemaTemplate/metafun-apply.cpp b/test/SemaTemplate/metafun-apply.cpp
new file mode 100644
index 0000000..3a7408e
--- /dev/null
+++ b/test/SemaTemplate/metafun-apply.cpp
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct add_pointer {
+  template<typename T>
+  struct apply {
+    typedef T* type;
+  };
+};
+
+struct add_reference {
+  template<typename T>
+  struct apply {
+    typedef T& type; // expected-error{{cannot form a reference to 'void'}}
+  };
+};
+
+struct bogus {
+  struct apply {
+    typedef int type;
+  };
+};
+
+template<typename MetaFun, typename T>
+struct apply1 {
+  typedef typename MetaFun::template apply<T>::type type; // expected-note{{in instantiation of template class 'add_reference::apply<void>' requested here}} \
+  // expected-error{{'apply' following the 'template' keyword does not refer to a template}}
+};
+
+int i;
+apply1<add_pointer, int>::type ip = &i;
+apply1<add_reference, int>::type ir = i;
+apply1<add_reference, float>::type fr = i; // expected-error{{non-const lvalue reference to type 'float' cannot bind to a value of unrelated type 'int'}}
+
+void test() {
+  apply1<add_reference, void>::type t; // expected-note{{in instantiation of template class 'apply1<add_reference, void>' requested here}}
+
+  apply1<bogus, int>::type t2; // expected-note{{in instantiation of template class 'apply1<bogus, int>' requested here}}
+}
+
+
diff --git a/test/SemaTemplate/nested-linkage.cpp b/test/SemaTemplate/nested-linkage.cpp
new file mode 100644
index 0000000..6c0791c
--- /dev/null
+++ b/test/SemaTemplate/nested-linkage.cpp
@@ -0,0 +1,3 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+extern "C" { extern "C++" { template<class C> C x(); } }
diff --git a/test/SemaTemplate/nested-name-spec-template.cpp b/test/SemaTemplate/nested-name-spec-template.cpp
new file mode 100644
index 0000000..1691db7
--- /dev/null
+++ b/test/SemaTemplate/nested-name-spec-template.cpp
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace N { 
+  namespace M {
+    template<typename T> struct Promote;
+    
+    template<> struct Promote<short> {
+      typedef int type;
+    };
+    
+    template<> struct Promote<int> {
+      typedef int type;
+    };
+    
+    template<> struct Promote<float> {
+      typedef double type;
+    };
+    
+    Promote<short>::type *ret_intptr(int* ip) { return ip; }
+    Promote<int>::type *ret_intptr2(int* ip) { return ip; }
+  }
+
+  M::Promote<int>::type *ret_intptr3(int* ip) { return ip; }
+  M::template Promote<int>::type *ret_intptr4(int* ip) { return ip; }
+}
+
+N::M::Promote<int>::type *ret_intptr5(int* ip) { return ip; }
+::N::M::Promote<int>::type *ret_intptr6(int* ip) { return ip; }
+
+
+N::M::template; // expected-error{{expected unqualified-id}}
+N::M::template Promote; // expected-error{{expected unqualified-id}}
+
+namespace N {
+  template<typename T> struct A;
+
+  template<>
+  struct A<int> {
+    struct X;
+  };
+
+  struct B;
+}
+
+struct ::N::A<int>::X {
+  int foo;
+};
+
+template<typename T>
+struct TestA {
+  typedef typename N::template B<T>::type type; // expected-error{{'B' following the 'template' keyword does not refer to a template}} \
+                                                // expected-error{{expected member name}}
+};
diff --git a/test/SemaTemplate/nested-template.cpp b/test/SemaTemplate/nested-template.cpp
new file mode 100644
index 0000000..01ede32
--- /dev/null
+++ b/test/SemaTemplate/nested-template.cpp
@@ -0,0 +1,128 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+class A;
+
+class S {
+public:
+   template<typename T> struct A { 
+     struct Nested {
+       typedef T type;
+     };
+   };
+};
+
+int i;
+S::A<int>::Nested::type *ip = &i;
+
+template<typename T>
+struct Outer {
+  template<typename U>
+  class Inner0;
+  
+  template<typename U>
+  class Inner1 {
+    struct ReallyInner;
+    
+    T foo(U);
+    template<typename V> T bar(V);
+    template<typename V> T* bar(V);
+    
+    static T value1;
+    static U value2;
+  };
+};
+
+template<typename X>
+template<typename Y>
+class Outer<X>::Inner0 {
+public:
+  void f(X, Y);
+};
+
+template<typename X>
+template<typename Y>
+void Outer<X>::Inner0<Y>::f(X, Y) {
+}
+
+template<typename X>
+template<typename Y>
+struct Outer<X>::Inner1<Y>::ReallyInner {
+  static Y value3;
+  
+  void g(X, Y);
+};
+
+template<typename X>
+template<typename Y>
+void Outer<X>::Inner1<Y>::ReallyInner::g(X, Y) {
+}
+
+template<typename X>
+template<typename Y>
+X Outer<X>::Inner1<Y>::foo(Y) {
+  return X();
+}
+
+template<typename X>
+template<typename Y>
+template<typename Z>
+X Outer<X>::Inner1<Y>::bar(Z) {
+  return X();
+}
+
+template<typename X>
+template<typename Y>
+template<typename Z>
+X* Outer<X>::Inner1<Y>::bar(Z) {
+  return 0;
+}
+
+template<typename X>
+template<typename Y>
+X Outer<X>::Inner1<Y>::value1 = 0;
+
+template<typename X>
+template<typename Y>
+Y Outer<X>::Inner1<Y>::value2 = Y();
+
+template<typename X>
+template<typename Y>
+Y Outer<X>::Inner1<Y>::ReallyInner::value3 = Y();
+
+template<typename X>
+template<typename Y>
+Y Outer<X>::Inner1<Y*>::ReallyInner::value4; // expected-error{{Outer<X>::Inner1<Y *>::ReallyInner::}}
+
+
+template<typename T>
+struct X0 { };
+
+template<typename T>
+struct X0<T*> {
+  template<typename U>
+  void f(U u = T()) { }
+};
+
+// PR5103
+template<typename>
+struct X1 {
+  template<typename, bool = false> struct B { };
+};
+template struct X1<int>::B<bool>;
+
+// Template template parameters
+template<typename T>
+struct X2 {
+  template<template<class U, T Value> class>  // expected-error{{cannot have type 'float'}} \
+                                              // expected-note{{previous non-type template}}
+    struct Inner { };
+};
+
+template<typename T, 
+         int Value> // expected-note{{template non-type parameter}}
+  struct X2_arg;
+
+X2<int>::Inner<X2_arg> x2i1;
+X2<float> x2a; // expected-note{{instantiation}}
+X2<long>::Inner<X2_arg> x2i3; // expected-error{{template template argument has different}}
+
+
diff --git a/test/SemaTemplate/operator-function-id-template.cpp b/test/SemaTemplate/operator-function-id-template.cpp
new file mode 100644
index 0000000..9a0884e
--- /dev/null
+++ b/test/SemaTemplate/operator-function-id-template.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T>
+struct A { 
+  template<typename U> A<T> operator+(U);
+};
+
+template<int Value, typename T> bool operator==(A<T>, A<T>);
+
+template<> bool operator==<0>(A<int>, A<int>);
+
+bool test_qualified_id(A<int> ai) {
+  return ::operator==<0, int>(ai, ai);
+}
+
+void test_op(A<int> a, int i) {
+  const A<int> &air = a.operator+<int>(i);
+}
+
+template<typename T>
+void test_op_template(A<T> at, T x) {
+  const A<T> &atr = at.template operator+<T>(x);
+  const A<T> &atr2 = at.A::template operator+<T>(x);
+  // FIXME: unrelated template-name instantiation issue
+  //  const A<T> &atr3 = at.template A<T>::template operator+<T>(x);
+}
+
+template void test_op_template<float>(A<float>, float);
diff --git a/test/SemaTemplate/operator-template.cpp b/test/SemaTemplate/operator-template.cpp
new file mode 100644
index 0000000..4300755
--- /dev/null
+++ b/test/SemaTemplate/operator-template.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// Make sure we accept this
+template<class X>struct A{typedef X Y;};
+template<class X>bool operator==(A<X>,typename A<X>::Y);
+int a(A<int> x) { return operator==(x,1); }
+
+int a0(A<int> x) { return x == 1; }
+
+// FIXME: the location information for the note isn't very good
+template<class X>struct B{typedef X Y;};
+template<class X>bool operator==(B<X>*,typename B<X>::Y); // \
+expected-error{{overloaded 'operator==' must have at least one parameter of class or enumeration type}} \
+expected-note{{in instantiation of function template specialization}}
+int a(B<int> x) { return operator==(&x,1); }
+
diff --git a/test/SemaTemplate/overload-uneval.cpp b/test/SemaTemplate/overload-uneval.cpp
new file mode 100644
index 0000000..632d1cd
--- /dev/null
+++ b/test/SemaTemplate/overload-uneval.cpp
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// Tests that overload resolution is treated as an unevaluated context.
+// PR5541
+struct Foo
+{
+    Foo *next;
+};
+
+template <typename>
+struct Bar
+{
+};
+
+
+template <typename T>
+class Wibble
+{
+    typedef Bar<T> B;
+
+    static inline B *concrete(Foo *node) {
+        int a[sizeof(T) ? -1 : -1];
+        return reinterpret_cast<B *>(node);
+    }
+
+public:
+    class It
+    {
+        Foo *i;
+
+    public:
+        inline operator B *() const { return concrete(i); }
+        inline bool operator!=(const It &o) const { return i !=
+o.i; }
+    };
+};
+
+void f() {
+  Wibble<void*>::It a, b;
+
+  a != b;
+}
diff --git a/test/SemaTemplate/partial-spec-instantiate.cpp b/test/SemaTemplate/partial-spec-instantiate.cpp
new file mode 100644
index 0000000..3156892
--- /dev/null
+++ b/test/SemaTemplate/partial-spec-instantiate.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -fsyntax-only %s
+
+// PR4607
+template <class T> struct X {};
+
+template <> struct X<char>
+{
+  static char* g();
+};
+
+template <class T> struct X2 {};
+
+template <class U>
+struct X2<U*> {
+  static void f() {
+    X<U>::g();
+  }
+};
+
+void a(char *a, char *b) {X2<char*>::f();}
diff --git a/test/SemaTemplate/qualified-id.cpp b/test/SemaTemplate/qualified-id.cpp
new file mode 100644
index 0000000..29eab89
--- /dev/null
+++ b/test/SemaTemplate/qualified-id.cpp
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// PR5061
+namespace a {
+  template <typename T> class C {};
+}
+namespace b {
+  template<typename T> void f0(a::C<T> &a0) { }
+}
+
+
+namespace test1 {
+  int a = 0;
+  template <class T> class Base { };
+  template <class T> class Derived : public Base<T> {
+    int foo() {
+      return test1::a;
+    }
+  };
+}
+
+namespace test2 {
+  class Impl {
+  public:
+    int foo();
+  };
+  template <class T> class Magic : public Impl {
+    int foo() {
+      return Impl::foo();
+    }
+  };
+}
+
+namespace PR6063 {
+  template <typename T> void f(T, T);
+  
+  namespace detail 
+  {
+    using PR6063::f;
+  }
+  
+  template <typename T>
+  void g(T a, T b)
+  {
+    detail::f(a, b);
+  }
+}
diff --git a/test/SemaTemplate/qualified-names-diag.cpp b/test/SemaTemplate/qualified-names-diag.cpp
new file mode 100644
index 0000000..b2df47b
--- /dev/null
+++ b/test/SemaTemplate/qualified-names-diag.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace std {
+  template<typename T> class vector { }; // expected-note{{candidate}}
+}
+
+typedef int INT;
+typedef float Real;
+
+void test() {
+  using namespace std;
+
+  std::vector<INT> v1;
+  vector<Real> v2;
+  v1 = v2; // expected-error{{no viable overloaded '='}}
+}
diff --git a/test/SemaTemplate/recursive-template-instantiation.cpp b/test/SemaTemplate/recursive-template-instantiation.cpp
new file mode 100644
index 0000000..d6a0b24
--- /dev/null
+++ b/test/SemaTemplate/recursive-template-instantiation.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T> void f(T* t) { // expected-note{{failed template argument deduction}}
+  f(*t); // expected-error{{no matching function}}\
+         // expected-note 3{{requested here}}
+}
+
+void test_f(int ****p) {
+  f(p); // expected-note{{requested here}}
+}
diff --git a/test/SemaTemplate/temp.cpp b/test/SemaTemplate/temp.cpp
new file mode 100644
index 0000000..961b9c8
--- /dev/null
+++ b/test/SemaTemplate/temp.cpp
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+
+// p3
+template<typename T> int foo(T), bar(T, T); // expected-error{{single entity}}
diff --git a/test/SemaTemplate/temp_arg.cpp b/test/SemaTemplate/temp_arg.cpp
new file mode 100644
index 0000000..5a4c8fc
--- /dev/null
+++ b/test/SemaTemplate/temp_arg.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename T, 
+         int I, 
+         template<typename> class TT>
+  class A; // expected-note 3 {{template is declared here}}
+
+template<typename> class X;
+
+A<int, 0, X> * a1;
+
+A<float, 1, X, double> *a2; // expected-error{{too many template arguments for class template 'A'}}
+A<float, 1> *a3; // expected-error{{too few template arguments for class template 'A'}}
+A a3; // expected-error{{use of class template A requires template arguments}}
+
+namespace test0 {
+  template <class t> class foo {};
+  template <class t> class bar {
+    bar(::test0::foo<tee> *ptr) {} // FIXME(redundant): expected-error 2 {{use of undeclared identifier 'tee'}}
+  };
+}
diff --git a/test/SemaTemplate/temp_arg_nontype.cpp b/test/SemaTemplate/temp_arg_nontype.cpp
new file mode 100644
index 0000000..7b83ff9
--- /dev/null
+++ b/test/SemaTemplate/temp_arg_nontype.cpp
@@ -0,0 +1,195 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++98 -verify %s
+template<int N> struct A; // expected-note 5{{template parameter is declared here}}
+
+A<0> *a0;
+
+A<int()> *a1; // expected-error{{template argument for non-type template parameter is treated as type 'int ()'}}
+
+A<int> *a2; // expected-error{{template argument for non-type template parameter must be an expression}}
+
+A<1 >> 2> *a3; // expected-warning{{use of right-shift operator ('>>') in template argument will require parentheses in C++0x}}
+
+// C++ [temp.arg.nontype]p5:
+A<A> *a4; // expected-error{{must be an expression}}
+
+enum E { Enumerator = 17 };
+A<E> *a5; // expected-error{{template argument for non-type template parameter must be an expression}}
+template<E Value> struct A1; // expected-note{{template parameter is declared here}}
+A1<Enumerator> *a6; // okay
+A1<17> *a7; // expected-error{{non-type template argument of type 'int' cannot be converted to a value of type 'E'}}
+
+const long LongValue = 12345678;
+A<LongValue> *a8;
+const short ShortValue = 17;
+A<ShortValue> *a9;
+
+int f(int);
+A<f(17)> *a10; // expected-error{{non-type template argument of type 'int' is not an integral constant expression}}
+
+class X {
+public:
+  X();
+  X(int, int);
+  operator int() const;
+};
+A<X(17, 42)> *a11; // expected-error{{non-type template argument of type 'X' must have an integral or enumeration type}}
+
+float f(float);
+
+float g(float); // expected-note 2{{candidate function}}
+double g(double); // expected-note 2{{candidate function}}
+
+int h(int);
+float h2(float);
+
+template<int fp(int)> struct A3; // expected-note 1{{template parameter is declared here}}
+A3<h> *a14_1;
+A3<&h> *a14_2;
+A3<f> *a14_3;
+A3<&f> *a14_4;
+A3<h2> *a14_6;  // expected-error{{non-type template argument of type 'float (float)' cannot be converted to a value of type 'int (*)(int)'}}
+A3<g> *a14_7; // expected-error{{address of overloaded function 'g' does not match required type 'int (int)'}}
+
+
+struct Y { } y;
+
+volatile X * X_volatile_ptr;
+template<X const &AnX> struct A4; // expected-note 2{{template parameter is declared here}}
+X an_X;
+A4<an_X> *a15_1; // okay
+A4<*X_volatile_ptr> *a15_2; // expected-error{{non-type template argument does not refer to any declaration}}
+A4<y> *15_3; //  expected-error{{non-type template parameter of reference type 'X const &' cannot bind to template argument of type 'struct Y'}} \
+            // FIXME: expected-error{{expected unqualified-id}}
+
+template<int (&fr)(int)> struct A5; // expected-note{{template parameter is declared here}}
+A5<h> *a16_1;
+A5<f> *a16_3;
+A5<h2> *a16_6;  // expected-error{{non-type template parameter of reference type 'int (&)(int)' cannot bind to template argument of type 'float (float)'}}
+A5<g> *a14_7; // expected-error{{address of overloaded function 'g' does not match required type 'int (int)'}}
+
+struct Z {
+  int foo(int);
+  float bar(float);
+  int bar(int);
+  double baz(double);
+
+  int int_member;
+  float float_member;
+};
+template<int (Z::*pmf)(int)> struct A6; // expected-note{{template parameter is declared here}}
+A6<&Z::foo> *a17_1;
+A6<&Z::bar> *a17_2;
+A6<&Z::baz> *a17_3; // expected-error{{non-type template argument of type 'double (Z::*)(double)' cannot be converted to a value of type 'int (Z::*)(int)'}}
+
+
+template<int Z::*pm> struct A7;  // expected-note{{template parameter is declared here}}
+template<int Z::*pm> struct A7c;
+A7<&Z::int_member> *a18_1;
+A7c<&Z::int_member> *a18_2;
+A7<&Z::float_member> *a18_3; // expected-error{{non-type template argument of type 'float Z::*' cannot be converted to a value of type 'int Z::*'}}
+A7c<(&Z::int_member)> *a18_3; // expected-error{{non-type template argument cannot be surrounded by parentheses}}
+
+template<unsigned char C> struct Overflow; // expected-note{{template parameter is declared here}}
+
+Overflow<5> *overflow1; // okay
+Overflow<255> *overflow2; // okay
+Overflow<256> *overflow3; // expected-warning{{non-type template argument value '256' truncated to '0' for template parameter of type 'unsigned char'}}
+
+
+template<unsigned> struct Signedness; // expected-note{{template parameter is declared here}}
+Signedness<10> *signedness1; // okay
+Signedness<-10> *signedness2; // expected-warning{{non-type template argument with value '-10' converted to '4294967286' for unsigned template parameter of type 'unsigned int'}}
+
+template<signed char C> struct SignedOverflow; // expected-note 3 {{template parameter is declared here}}
+SignedOverflow<1> *signedoverflow1;
+SignedOverflow<-1> *signedoverflow2;
+SignedOverflow<-128> *signedoverflow3;
+SignedOverflow<-129> *signedoverflow4; // expected-warning{{non-type template argument value '-129' truncated to '127' for template parameter of type 'signed char'}}
+SignedOverflow<127> *signedoverflow5;
+SignedOverflow<128> *signedoverflow6; // expected-warning{{non-type template argument value '128' truncated to '-128' for template parameter of type 'signed char'}}
+SignedOverflow<(unsigned char)128> *signedoverflow7; // expected-warning{{non-type template argument value '128' truncated to '-128' for template parameter of type 'signed char'}}
+
+// Check canonicalization of template arguments.
+template<int (*)(int, int)> struct FuncPtr0;
+int func0(int, int);
+extern FuncPtr0<&func0> *fp0;
+template<int (*)(int, int)> struct FuncPtr0;
+extern FuncPtr0<&func0> *fp0;
+int func0(int, int);
+extern FuncPtr0<&func0> *fp0;
+
+// PR5350
+namespace ns {
+  template <typename T>
+  struct Foo {
+    static const bool value = true;
+  };
+  
+  template <bool b>
+  struct Bar {};
+  
+  const bool value = false;
+  
+  Bar<bool(ns::Foo<int>::value)> x;
+}
+
+// PR5349
+namespace ns {
+  enum E { k };
+  
+  template <E e>
+  struct Baz  {};
+  
+  Baz<k> f1;  // This works.
+  Baz<E(0)> f2;  // This too.
+  Baz<static_cast<E>(0)> f3;  // And this.
+  
+  Baz<ns::E(0)> b1;  // This doesn't work.
+  Baz<static_cast<ns::E>(0)> b2;  // This neither.  
+}
+
+// PR5597
+template<int (*)(float)> struct X0 { };
+
+struct X1 {
+    static int pfunc(float);
+};
+void test_X0_X1() {
+  X0<X1::pfunc> x01;
+}
+
+// PR6249
+namespace pr6249 {
+  template<typename T, T (*func)()> T f() {
+    return func();
+  }
+
+  int h();
+  template int f<int, h>();
+}
+
+namespace PR6723 {
+  template<unsigned char C> void f(int (&a)[C]); // expected-note 2{{candidate template ignored}}
+  void g() {
+    int arr512[512];
+    f(arr512); // expected-error{{no matching function for call}}
+    f<512>(arr512); // expected-error{{no matching function for call}}
+  }
+}
+
+// Check that we instantiate declarations whose addresses are taken
+// for non-type template arguments.
+namespace EntityReferenced {
+  template<typename T, void (*)(T)> struct X { };
+
+  template<typename T>
+  struct Y {
+    static void f(T x) { 
+      x = 1; // expected-error{{assigning to 'int *' from incompatible type 'int'}}
+    }
+  };
+
+  void g() {
+    typedef X<int*, Y<int*>::f> x; // expected-note{{in instantiation of}}
+  }
+}
diff --git a/test/SemaTemplate/temp_arg_template.cpp b/test/SemaTemplate/temp_arg_template.cpp
new file mode 100644
index 0000000..6671225
--- /dev/null
+++ b/test/SemaTemplate/temp_arg_template.cpp
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<template<typename T> class X> struct A; // expected-note 2{{previous template template parameter is here}}
+
+template<template<typename T, int I> class X> struct B; // expected-note{{previous template template parameter is here}}
+
+template<template<int I> class X> struct C;  // expected-note{{previous non-type template parameter with type 'int' is here}}
+
+template<class> struct X; // expected-note{{too few template parameters in template template argument}}
+template<int N> struct Y; // expected-note{{template parameter has a different kind in template argument}}
+template<long N> struct Ylong; // expected-note{{template non-type parameter has a different type 'long' in template argument}}
+
+namespace N {
+  template<class> struct Z;
+}
+template<class, class> struct TooMany; // expected-note{{too many template parameters in template template argument}}
+
+
+A<X> *a1; 
+A<N::Z> *a2;
+A< ::N::Z> *a3;
+
+A<Y> *a4; // expected-error{{template template argument has different template parameters than its corresponding template template parameter}}
+A<TooMany> *a5; // expected-error{{template template argument has different template parameters than its corresponding template template parameter}}
+B<X> *a6; // expected-error{{template template argument has different template parameters than its corresponding template template parameter}}
+C<Y> *a7;
+C<Ylong> *a8; // expected-error{{template template argument has different template parameters than its corresponding template template parameter}}
+
+template<typename T> void f(int);
+
+A<f> *a9; // expected-error{{must be a class template}}
+
+// FIXME: The code below is ill-formed, because of the evil digraph '<:'. 
+// We should provide a much better error message than we currently do.
+// A<::N::Z> *a10;
diff --git a/test/SemaTemplate/temp_arg_type.cpp b/test/SemaTemplate/temp_arg_type.cpp
new file mode 100644
index 0000000..3876c25
--- /dev/null
+++ b/test/SemaTemplate/temp_arg_type.cpp
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename T> class A; // expected-note 2 {{template parameter is declared here}} expected-note{{template is declared here}}
+
+// [temp.arg.type]p1
+A<0> *a1; // expected-error{{template argument for template type parameter must be a type}}
+
+A<A> *a2; // expected-error{{use of class template A requires template arguments}}
+
+A<int> *a3;
+A<int()> *a4; 
+A<int(float)> *a5;
+A<A<int> > *a6;
+
+// Pass an overloaded function template:
+template<typename T> void function_tpl(T);
+A<function_tpl> a7;  // expected-error{{template argument for template type parameter must be a type}}
+
+// Pass a qualified name:
+namespace ns {
+template<typename T> class B {};  // expected-note{{template is declared here}}
+}
+A<ns::B> a8; // expected-error{{use of class template ns::B requires template arguments}}
+
+// [temp.arg.type]p2
+void f() {
+  class X { };
+  A<X> * a = 0; // expected-error{{template argument uses local type 'X'}}
+}
+
+struct { int x; } Unnamed; // expected-note{{unnamed type used in template argument was declared here}}
+A<__typeof__(Unnamed)> *a9; // expected-error{{template argument uses unnamed type}}
+
+template<typename T, unsigned N>
+struct Array {
+  typedef struct { T x[N]; } type;
+};
+
+template<typename T> struct A1 { };
+A1<Array<int, 17>::type> ax;
+
+// FIXME: [temp.arg.type]p3. The check doesn't really belong here (it
+// belongs somewhere in the template instantiation section).
diff --git a/test/SemaTemplate/temp_class_order.cpp b/test/SemaTemplate/temp_class_order.cpp
new file mode 100644
index 0000000..fcf0325
--- /dev/null
+++ b/test/SemaTemplate/temp_class_order.cpp
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T, typename U>
+struct X1 {
+  static const int value = 0;
+};
+
+template<typename T, typename U>
+struct X1<T*, U*> {
+  static const int value = 1;
+};
+
+template<typename T>
+struct X1<T*, T*> {
+  static const int value = 2;
+};
+
+template<typename T>
+struct X1<const T*, const T*> {
+  static const int value = 3;
+};
+
+int array0[X1<int, int>::value == 0? 1 : -1];
+int array1[X1<int*, float*>::value == 1? 1 : -1];
+int array2[X1<int*, int*>::value == 2? 1 : -1];
+typedef const int* CIP;
+int array3[X1<const int*, CIP>::value == 3? 1 : -1];
+
+template<typename T, typename U>
+struct X2 { };
+
+template<typename T, typename U>
+struct X2<T*, U> { }; // expected-note{{matches}}
+
+template<typename T, typename U>
+struct X2<T, U*> { }; // expected-note{{matches}}
+
+template<typename T, typename U>
+struct X2<const T*, const U*> { };
+
+X2<int*, int*> x2a; // expected-error{{ambiguous}}
+X2<const int*, const int*> x2b;
diff --git a/test/SemaTemplate/temp_class_spec.cpp b/test/SemaTemplate/temp_class_spec.cpp
new file mode 100644
index 0000000..8a07fd7
--- /dev/null
+++ b/test/SemaTemplate/temp_class_spec.cpp
@@ -0,0 +1,363 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename T>
+struct is_pointer {
+  static const bool value = false;
+};
+
+template<typename T>
+struct is_pointer<T*> {
+  static const bool value = true;
+};
+
+template<typename T>
+struct is_pointer<const T*> {
+  static const bool value = true;
+};
+
+int array0[is_pointer<int>::value? -1 : 1];
+int array1[is_pointer<int*>::value? 1 : -1];
+int array2[is_pointer<const int*>::value? 1 : -1];
+
+template<typename T>
+struct is_lvalue_reference {
+  static const bool value = false;
+};
+
+template<typename T>
+struct is_lvalue_reference<T&> {
+  static const bool value = true;
+};
+
+int lvalue_ref0[is_lvalue_reference<int>::value? -1 : 1];
+int lvalue_ref1[is_lvalue_reference<const int&>::value? 1 : -1];
+
+template<typename T>
+struct is_const {
+  static const bool value = false;
+};
+
+template<typename T>
+struct is_const<const T> {
+  static const bool value = true;
+};
+
+int is_const0[is_const<int>::value? -1 : 1];
+int is_const1[is_const<const int>::value? 1 : -1];
+int is_const2[is_const<const volatile int>::value? 1 : -1];
+int is_const3[is_const<const int [3]>::value? 1 : -1];
+int is_const4[is_const<const volatile int[3]>::value? 1 : -1];
+int is_const5[is_const<volatile int[3]>::value? -1 : 1];
+
+template<typename T>
+struct is_volatile {
+  static const bool value = false;
+};
+
+template<typename T>
+struct is_volatile<volatile T> {
+  static const bool value = true;
+};
+
+int is_volatile0[is_volatile<int>::value? -1 : 1];
+int is_volatile1[is_volatile<volatile int>::value? 1 : -1];
+int is_volatile2[is_volatile<const volatile int>::value? 1 : -1];
+int is_volatile3[is_volatile<volatile char[3]>::value? 1 : -1];
+                 
+template<typename T, typename U>
+struct is_same {
+  static const bool value = false;
+};
+
+template<typename T>
+struct is_same<T, T> {
+  static const bool value = true;
+};
+
+typedef int INT;
+typedef INT* int_ptr;
+
+int is_same0[is_same<int, int>::value? 1 : -1];
+int is_same1[is_same<int, INT>::value? 1 : -1];
+int is_same2[is_same<const int, int>::value? -1 : 1];
+int is_same3[is_same<int_ptr, int>::value? -1 : 1];
+
+template<typename T>
+struct remove_reference {
+  typedef T type;
+};
+
+template<typename T>
+struct remove_reference<T&> {
+  typedef T type;
+};
+
+int remove_ref0[is_same<remove_reference<int>::type, int>::value? 1 : -1];
+int remove_ref1[is_same<remove_reference<int&>::type, int>::value? 1 : -1];
+
+template<typename T>
+struct remove_const {
+  typedef T type;
+};
+
+template<typename T>
+struct remove_const<const T> {
+  typedef T type;
+};
+
+int remove_const0[is_same<remove_const<const int>::type, int>::value? 1 : -1];
+int remove_const1[is_same<remove_const<const int[3]>::type, int[3]>::value? 1 : -1];
+
+template<typename T>
+struct is_incomplete_array {
+  static const bool value = false;
+};
+
+template<typename T>
+struct is_incomplete_array<T[]> {
+  static const bool value = true;
+};
+
+int incomplete_array0[is_incomplete_array<int>::value ? -1 : 1];
+int incomplete_array1[is_incomplete_array<int[1]>::value ? -1 : 1];
+int incomplete_array2[is_incomplete_array<bool[]>::value ? 1 : -1];
+int incomplete_array3[is_incomplete_array<int[]>::value ? 1 : -1];
+
+template<typename T>
+struct is_array_with_4_elements {
+  static const bool value = false;
+};
+
+template<typename T>
+struct is_array_with_4_elements<T[4]> {
+  static const bool value = true;
+};
+
+int array_with_4_elements0[is_array_with_4_elements<int[]>::value ? -1 : 1];
+int array_with_4_elements1[is_array_with_4_elements<int[1]>::value ? -1 : 1];
+int array_with_4_elements2[is_array_with_4_elements<int[4]>::value ? 1 : -1];
+int array_with_4_elements3[is_array_with_4_elements<int[4][2]>::value ? 1 : -1];
+
+template<typename T>
+struct get_array_size;
+
+template<typename T, unsigned N>
+struct get_array_size<T[N]> {
+  static const unsigned value = N;
+};
+
+int array_size0[get_array_size<int[12]>::value == 12? 1 : -1];
+
+template<typename T>
+struct remove_extent {
+  typedef T type;
+};
+
+template<typename T>
+struct remove_extent<T[]> { 
+  typedef T type;
+};
+
+template<typename T, unsigned N>
+struct remove_extent<T[N]> { 
+  typedef T type;
+};
+
+int remove_extent0[is_same<remove_extent<int[][5]>::type, int[5]>::value? 1 : -1];
+int remove_extent1[is_same<remove_extent<const int[][5]>::type, const int[5]>::value? 1 : -1];
+
+template<typename T>
+struct is_unary_function {
+  static const bool value = false;
+};
+
+template<typename T, typename U>
+struct is_unary_function<T (*)(U)> {
+  static const bool value = true;
+};
+
+int is_unary_function0[is_unary_function<int>::value ? -1 : 1];
+int is_unary_function1[is_unary_function<int (*)()>::value ? -1 : 1];
+int is_unary_function2[is_unary_function<int (*)(int, bool)>::value ? -1 : 1];
+int is_unary_function3[is_unary_function<int (*)(bool)>::value ? 1 : -1];
+int is_unary_function4[is_unary_function<int (*)(int)>::value ? 1 : -1];
+
+template<typename T>
+struct is_unary_function_with_same_return_type_as_argument_type {
+  static const bool value = false;
+};
+
+template<typename T>
+struct is_unary_function_with_same_return_type_as_argument_type<T (*)(T)> {
+  static const bool value = true;
+};
+
+int is_unary_function5[is_unary_function_with_same_return_type_as_argument_type<int>::value ? -1 : 1];
+int is_unary_function6[is_unary_function_with_same_return_type_as_argument_type<int (*)()>::value ? -1 : 1];
+int is_unary_function7[is_unary_function_with_same_return_type_as_argument_type<int (*)(int, bool)>::value ? -1 : 1];
+int is_unary_function8[is_unary_function_with_same_return_type_as_argument_type<int (*)(bool)>::value ? -1 : 1];
+int is_unary_function9[is_unary_function_with_same_return_type_as_argument_type<int (*)(int)>::value ? 1 : -1];
+int is_unary_function10[is_unary_function_with_same_return_type_as_argument_type<int (*)(int, ...)>::value ? -1 : 1];
+int is_unary_function11[is_unary_function_with_same_return_type_as_argument_type<int (* const)(int)>::value ? -1 : 1];
+
+template<typename T>
+struct is_binary_function {
+  static const bool value = false;
+};
+
+template<typename R, typename T1, typename T2>
+struct is_binary_function<R(T1, T2)> {
+  static const bool value = true;
+};
+
+int is_binary_function0[is_binary_function<int(float, double)>::value? 1 : -1];
+
+template<typename T>
+struct is_member_pointer {
+  static const bool value = false;
+};
+
+template<typename T, typename Class>
+struct is_member_pointer<T Class::*> {
+  static const bool value = true;
+};
+
+struct X { };
+
+int is_member_pointer0[is_member_pointer<int X::*>::value? 1 : -1];
+int is_member_pointer1[is_member_pointer<const int X::*>::value? 1 : -1];
+int is_member_pointer2[is_member_pointer<int (X::*)()>::value? 1 : -1];
+int is_member_pointer3[is_member_pointer<int (X::*)(int) const>::value? 1 : -1];
+int is_member_pointer4[is_member_pointer<int (X::**)(int) const>::value? -1 : 1];
+int is_member_pointer5[is_member_pointer<int>::value? -1 : 1];
+
+template<typename T>
+struct is_member_function_pointer {
+  static const bool value = false;
+};
+
+template<typename T, typename Class>
+struct is_member_function_pointer<T (Class::*)()> {
+  static const bool value = true;
+};
+
+template<typename T, typename Class>
+struct is_member_function_pointer<T (Class::*)() const> {
+  static const bool value = true;
+};
+
+template<typename T, typename Class>
+struct is_member_function_pointer<T (Class::*)() volatile> {
+  static const bool value = true;
+};
+
+template<typename T, typename Class>
+struct is_member_function_pointer<T (Class::*)() const volatile> {
+  static const bool value = true;
+};
+
+template<typename T, typename Class, typename A1>
+struct is_member_function_pointer<T (Class::*)(A1)> {
+  static const bool value = true;
+};
+
+template<typename T, typename Class, typename A1>
+struct is_member_function_pointer<T (Class::*)(A1) const> {
+  static const bool value = true;
+};
+
+template<typename T, typename Class, typename A1>
+struct is_member_function_pointer<T (Class::*)(A1) volatile> {
+  static const bool value = true;
+};
+
+template<typename T, typename Class, typename A1>
+struct is_member_function_pointer<T (Class::*)(A1) const volatile> {
+  static const bool value = true;
+};
+
+int is_member_function_pointer0[
+                          is_member_function_pointer<int X::*>::value? -1 : 1];
+int is_member_function_pointer1[
+                      is_member_function_pointer<int (X::*)()>::value? 1 : -1];
+int is_member_function_pointer2[
+                      is_member_function_pointer<X (X::*)(X&)>::value? 1 : -1];
+int is_member_function_pointer3[
+           is_member_function_pointer<int (X::*)() const>::value? 1 : -1];
+int is_member_function_pointer4[
+           is_member_function_pointer<int (X::*)(float) const>::value? 1 : -1];
+
+// Test substitution of non-dependent arguments back into the template
+// argument list of the class template partial specialization.
+template<typename T, typename ValueType = T>
+struct is_nested_value_type_identity {
+  static const bool value = false;
+};
+
+template<typename T>
+struct is_nested_value_type_identity<T, typename T::value_type> {
+  static const bool value = true;
+};
+
+template<typename T>
+struct HasValueType {
+  typedef T value_type;
+};
+
+struct HasIdentityValueType {
+  typedef HasIdentityValueType value_type;
+};
+
+struct NoValueType { };
+
+int is_nested_value_type_identity0[
+            is_nested_value_type_identity<HasValueType<int> >::value? -1 : 1];
+int is_nested_value_type_identity1[
+          is_nested_value_type_identity<HasIdentityValueType>::value? 1 : -1];
+int is_nested_value_type_identity2[
+                   is_nested_value_type_identity<NoValueType>::value? -1 : 1];
+
+
+// C++ [temp.class.spec]p4:
+template<class T1, class T2, int I> class A { }; //#1 
+template<class T, int I> class A<T, T*, I> { }; //#2 
+template<class T1, class T2, int I> class A<T1*, T2, I> { }; //#3 
+template<class T> class A<int, T*, 5> { }; //#4 
+template<class T1, class T2, int I> class A<T1, T2*, I> { }; //#5 
+
+// Redefinition of class template partial specializations
+template<typename T, T N, typename U> class A0;
+
+template<typename T, T N> class A0<T, N, int> { }; // expected-note{{here}}
+template<typename T, T N> class A0<T, N, int>;
+template<typename T, T N> class A0<T, N, int> { }; // expected-error{{redef}}
+
+namespace PR6025 {
+  template< int N > struct A;
+
+  namespace N 
+  {
+    template< typename F > 
+    struct B;
+  }
+
+  template< typename Protect, typename Second > 
+  struct C;
+
+  template <class T>
+  struct C< T, A< N::B<T>::value > >
+  {
+  };
+}
+
+namespace PR6181 {
+  template <class T>
+  class a;
+  
+  class s;
+  
+  template <class U>
+  class a<s> // expected-error{{partial specialization of 'a' does not use any of its template parameters}}
+  {
+  };
+  
+}
diff --git a/test/SemaTemplate/temp_class_spec_blocks.cpp b/test/SemaTemplate/temp_class_spec_blocks.cpp
new file mode 100644
index 0000000..b7b96df
--- /dev/null
+++ b/test/SemaTemplate/temp_class_spec_blocks.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -fblocks
+template<typename T>
+struct is_unary_block {
+  static const bool value = false;
+};
+
+template<typename T, typename U>
+struct is_unary_block<T (^)(U)> {
+  static const bool value = true;
+};
+
+int is_unary_block0[is_unary_block<int>::value ? -1 : 1];
+int is_unary_block1[is_unary_block<int (^)()>::value ? -1 : 1];
+int is_unary_block2[is_unary_block<int (^)(int, bool)>::value ? -1 : 1];
+int is_unary_block3[is_unary_block<int (^)(bool)>::value ? 1 : -1];
+int is_unary_block4[is_unary_block<int (^)(int)>::value ? 1 : -1];
+
+template<typename T>
+struct is_unary_block_with_same_return_type_as_argument_type {
+  static const bool value = false;
+};
+
+template<typename T>
+struct is_unary_block_with_same_return_type_as_argument_type<T (^)(T)> {
+  static const bool value = true;
+};
+
+int is_unary_block5[is_unary_block_with_same_return_type_as_argument_type<int>::value ? -1 : 1];
+int is_unary_block6[is_unary_block_with_same_return_type_as_argument_type<int (^)()>::value ? -1 : 1];
+int is_unary_block7[is_unary_block_with_same_return_type_as_argument_type<int (^)(int, bool)>::value ? -1 : 1];
+int is_unary_block8[is_unary_block_with_same_return_type_as_argument_type<int (^)(bool)>::value ? -1 : 1];
+int is_unary_block9[is_unary_block_with_same_return_type_as_argument_type<int (^)(int)>::value ? 1 : -1];
+int is_unary_block10[is_unary_block_with_same_return_type_as_argument_type<int (^)(int, ...)>::value ? -1 : 1];
+int is_unary_block11[is_unary_block_with_same_return_type_as_argument_type<int (^ const)(int)>::value ? -1 : 1];
diff --git a/test/SemaTemplate/temp_class_spec_neg.cpp b/test/SemaTemplate/temp_class_spec_neg.cpp
new file mode 100644
index 0000000..c8e8a57
--- /dev/null
+++ b/test/SemaTemplate/temp_class_spec_neg.cpp
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename T> struct vector;
+
+// C++ [temp.class.spec]p6:
+namespace N {
+  namespace M {
+    template<typename T> struct A; // expected-note{{here}}
+  }
+}
+
+template<typename T>
+struct N::M::A<T*> { }; // expected-error{{originally}}
+
+// C++ [temp.class.spec]p9
+//   bullet 1
+template <int I, int J> struct A {}; 
+template <int I> struct A<I+5, I*2> {}; // expected-error{{depends on}} 
+template <int I, int J> struct B {}; 
+template <int I> struct B<I, I> {}; //OK 
+
+//   bullet 2
+template <class T, T t> struct C {};  // expected-note{{declared here}}
+template <class T> struct C<T, 1>; // expected-error{{specializes}}
+template <class T, T* t> struct C<T*, t>; // okay
+
+template< int X, int (*array_ptr)[X] > class A2 {}; // expected-note{{here}}
+int array[5]; 
+template< int X > class A2<X, &array> { }; // expected-error{{specializes}}
+
+template<typename T, int N, template<typename X> class TT>
+struct Test0;
+
+//   bullet 3
+template<typename T, int N, template<typename X> class TT>
+struct Test0<T, N, TT>; // expected-error{{does not specialize}}
+
+// C++ [temp.class.spec]p10
+template<typename T = int, // expected-error{{default template argument}}
+         int N = 17, // expected-error{{default template argument}}
+         template<typename X> class TT = ::vector> // expected-error{{default template argument}}
+  struct Test0<T*, N, TT> { };
+
+template<typename T> struct Test1;
+template<typename T, typename U>  // expected-note{{non-deducible}}
+  struct Test1<T*> { }; // expected-warning{{never be used}}
diff --git a/test/SemaTemplate/temp_explicit.cpp b/test/SemaTemplate/temp_explicit.cpp
new file mode 100644
index 0000000..fbb41ff
--- /dev/null
+++ b/test/SemaTemplate/temp_explicit.cpp
@@ -0,0 +1,127 @@
+// RUN: %clang_cc1 -fsyntax-only -pedantic -verify %s
+//
+// Tests explicit instantiation of templates.
+template<typename T, typename U = T> class X0 { };
+
+namespace N {
+  template<typename T, typename U = T> class X1 { };
+}
+
+// Check the syntax of explicit instantiations.
+template class X0<int, float>;
+template class X0<int>; // expected-note{{previous}}
+
+template class N::X1<int>;
+template class ::N::X1<int, float>;
+
+using namespace N;
+
+// Check for some bogus syntax that probably means that the user
+// wanted to write an explicit specialization, but forgot the '<>'
+// after 'template'.
+template class X0<double> { }; // expected-error{{explicit specialization}}
+
+// Check for explicit instantiations that come after other kinds of
+// instantiations or declarations.
+template class X0<int, int>; // expected-error{{duplicate}}
+
+template<> class X0<char> { }; // expected-note{{previous}}
+template class X0<char>; // expected-warning{{ignored}}
+
+void foo(X0<short>) { }
+template class X0<short>;
+
+// Check that explicit instantiations actually produce definitions. We
+// determine whether this happens by placing semantic errors in the
+// definition of the template we're instantiating.
+template<typename T> struct X2; // expected-note{{declared here}}
+
+template struct X2<float>; // expected-error{{undefined template}}
+
+template<typename T>
+struct X2 {
+  void f0(T*); // expected-error{{pointer to a reference}}
+};
+
+template struct X2<int>; // okay
+template struct X2<int&>; // expected-note{{in instantiation of}}
+
+// Check that explicit instantiations instantiate member classes.
+template<typename T> struct X3 {
+  struct Inner {
+    void f(T*); // expected-error{{pointer to a reference}}
+  };
+};
+
+void f1(X3<int&>); // okay, Inner, not instantiated
+
+template struct X3<int&>; // expected-note{{instantiation}}
+
+template<typename T> struct X4 {
+  struct Inner {
+    struct VeryInner {
+      void f(T*); // expected-error 2{{pointer to a reference}}
+    };
+  };
+};
+
+void f2(X4<int&>); // okay, Inner, not instantiated
+void f3(X4<int&>::Inner); // okay, Inner::VeryInner, not instantiated
+
+template struct X4<int&>; // expected-note{{instantiation}}
+template struct X4<float&>; // expected-note{{instantiation}}
+
+// Check explicit instantiation of member classes
+namespace N2 {
+
+template<typename T>
+struct X5 {
+  struct Inner1 {
+    void f(T&);
+  };
+
+  struct Inner2 {
+    struct VeryInner {
+      void g(T*); // expected-error 2{{pointer to a reference}}
+    };
+  };
+};
+
+}
+
+template struct N2::X5<void>::Inner2;
+
+using namespace N2;
+template struct X5<int&>::Inner2; // expected-note{{instantiation}}
+
+void f4(X5<float&>::Inner2);
+template struct X5<float&>::Inner2; // expected-note{{instantiation}}
+
+namespace N3 {
+  template struct N2::X5<int>::Inner2;
+}
+
+struct X6 {
+  struct Inner { // expected-note{{here}}
+    void f();
+  };
+};
+
+template struct X6::Inner; // expected-error{{non-templated}}
+
+// PR5559
+template <typename T>
+struct Foo;
+
+template <>
+struct Foo<int> // expected-note{{header not required for explicitly-specialized}}
+{
+    template <typename U>
+    struct Bar
+    {};
+};
+
+template <> // expected-warning{{extraneous template parameter list}}
+template <>
+struct Foo<int>::Bar<void>
+{};
diff --git a/test/SemaTemplate/temp_explicit_cxx0x.cpp b/test/SemaTemplate/temp_explicit_cxx0x.cpp
new file mode 100644
index 0000000..215d2cf
--- /dev/null
+++ b/test/SemaTemplate/temp_explicit_cxx0x.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++0x -verify %s
+namespace N1 {
+
+  template<typename T> struct X0 { }; // expected-note{{here}}
+
+  namespace Inner {
+    template<typename T> struct X1 { };
+  }
+
+  template struct X0<int>;
+  template struct Inner::X1<int>;
+}
+
+template<typename T> struct X2 { }; // expected-note{{here}}
+
+template struct ::N1::Inner::X1<float>;
+
+namespace N2 {
+  using namespace N1;
+
+  template struct X0<double>; // expected-error{{not in a namespace enclosing}}
+
+  template struct X2<float>; // expected-error{{at global scope}}
+}
diff --git a/test/SemaTemplate/temp_func_order.cpp b/test/SemaTemplate/temp_func_order.cpp
new file mode 100644
index 0000000..908354b
--- /dev/null
+++ b/test/SemaTemplate/temp_func_order.cpp
@@ -0,0 +1,95 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename T>
+int &f0(T);
+
+template<typename T>
+float &f0(T*);
+
+void test_f0(int i, int *ip) {
+  int &ir = f0(i);
+  float &fr = f0(ip);
+}
+
+template<typename T, typename U>
+int &f1(T, U);
+
+template<typename T>
+float &f1(T, T);
+
+void test_f1(int i, float f) {
+  int &ir = f1(i, f);
+  float &fr1 = f1(i, i);
+  float &fr2 = f1(f, f);
+}
+
+template<typename T, typename U>
+struct A { };
+
+template<typename T>
+int &f2(T);
+
+template<typename T, typename U>
+float &f2(A<T, U>);
+
+template<typename T>
+double &f2(A<T, T>);
+
+void test_f2(int i, A<int, float> aif, A<int, int> aii) {
+  int &ir = f2(i);
+  float &fr = f2(aif);
+  double &dr = f2(aii);
+}
+
+template<typename T, typename U>
+int &f3(T*, U); // expected-note{{candidate}}
+
+template<typename T, typename U>
+float &f3(T, U*); // expected-note{{candidate}}
+
+void test_f3(int i, int *ip, float *fp) {
+  int &ir = f3(ip, i);
+  float &fr = f3(i, fp);
+  f3(ip, ip); // expected-error{{ambiguous}}
+}
+
+template<typename T>
+int &f4(T&);
+
+template<typename T>
+float &f4(const T&);
+
+void test_f4(int i, const int ic) {
+  int &ir1 = f4(i);
+  float &fr1 = f4(ic);
+}
+
+template<typename T, typename U>
+int &f5(T&, const U&); // expected-note{{candidate}}
+
+template<typename T, typename U>
+float &f5(const T&, U&); // expected-note{{candidate}}
+
+void test_f5(int i, const int ic) {
+  f5(i, i); // expected-error{{ambiguous}}
+}
+
+template<typename T, typename U>
+int &f6(T&, U&);
+
+template<typename T, typename U>
+float &f6(const T&, U&);
+
+void test_f6(int i, const int ic) {
+  int &ir = f6(i, i);
+  float &fr = f6(ic, ic);
+}
+
+struct CrazyFun {
+  template<typename T, typename U> operator A<T, U>();
+  template<typename T> operator A<T, T>();
+};
+
+void fun(CrazyFun cf) {
+  A<int, float> aif = cf;
+  A<int, int> aii = cf;  
+}
diff --git a/test/SemaTemplate/template-class-traits.cpp b/test/SemaTemplate/template-class-traits.cpp
new file mode 100644
index 0000000..4710294
--- /dev/null
+++ b/test/SemaTemplate/template-class-traits.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s 
+#define T(b) (b) ? 1 : -1
+#define F(b) (b) ? -1 : 1
+
+struct HasVirt { virtual void a(); };
+template<class T> struct InheritPolymorph : HasVirt {};
+int t01[T(__is_polymorphic(InheritPolymorph<int>))];
+
diff --git a/test/SemaTemplate/template-decl-fail.cpp b/test/SemaTemplate/template-decl-fail.cpp
new file mode 100644
index 0000000..7c04131
--- /dev/null
+++ b/test/SemaTemplate/template-decl-fail.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T> typedef T X; // expected-error{{typedef cannot be a template}}
+
+template<typename T>
+enum t0 { A = T::x }; // expected-error{{enumeration cannot be a template}} \
+                      // expected-warning{{declaration does not declare anything}}
+
diff --git a/test/SemaTemplate/template-id-expr.cpp b/test/SemaTemplate/template-id-expr.cpp
new file mode 100644
index 0000000..b3f41be
--- /dev/null
+++ b/test/SemaTemplate/template-id-expr.cpp
@@ -0,0 +1,46 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// PR5336
+template<typename FromCl>
+struct isa_impl_cl {
+ template<class ToCl>
+ static void isa(const FromCl &Val) { }
+};
+
+template<class X, class Y>
+void isa(const Y &Val) {   return isa_impl_cl<Y>::template isa<X>(Val); }
+
+class Value;
+void f0(const Value &Val) { isa<Value>(Val); }
+
+// Implicit template-ids.
+template<typename T>
+struct X0 {
+  template<typename U>
+  void f1();
+  
+  template<typename U>
+  void f2(U) {
+    f1<U>();
+  }
+};
+
+void test_X0_int(X0<int> xi, float f) {
+  xi.f2(f);
+}
+
+// Not template-id expressions, but they almost look like it.
+template<typename F>
+struct Y {
+  Y(const F&);
+};
+
+template<int I>
+struct X {
+  X(int, int);
+  void f() { 
+    Y<X<I> >(X<I>(0, 0)); 
+    Y<X<I> >(::X<I>(0, 0)); 
+  }
+};
+
+template struct X<3>;
diff --git a/test/SemaTemplate/template-id-printing.cpp b/test/SemaTemplate/template-id-printing.cpp
new file mode 100644
index 0000000..fcd4974
--- /dev/null
+++ b/test/SemaTemplate/template-id-printing.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fsyntax-only -ast-print %s | FileCheck %s
+namespace N {
+  template<typename T, typename U> void f(U);
+  template<int> void f();
+}
+
+void g() {
+  // CHECK: N::f<int>(3.14
+  N::f<int>(3.14);
+  
+  // CHECK: N::f<double>
+  void (*fp)(int) = N::f<double>;
+}
diff --git a/test/SemaTemplate/typename-specifier-2.cpp b/test/SemaTemplate/typename-specifier-2.cpp
new file mode 100644
index 0000000..551cac3
--- /dev/null
+++ b/test/SemaTemplate/typename-specifier-2.cpp
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename MetaFun, typename T>
+struct bind_metafun {
+  typedef typename MetaFun::template apply<T> type;
+};
+
+struct add_pointer {
+  template<typename T>
+  struct apply {
+    typedef T* type;
+  };
+};
+
+int i;
+// FIXME: if we make the declarator below a pointer (e.g., with *ip),
+// the error message isn't so good because we don't get the handy
+// 'aka' telling us that we're dealing with an int**. Should we fix
+// getDesugaredType to dig through pointers and such?
+bind_metafun<add_pointer, int>::type::type ip = &i;
+bind_metafun<add_pointer, float>::type::type fp = &i; // expected-error{{cannot initialize a variable of type 'bind_metafun<add_pointer, float>::type::type' (aka 'float *') with an rvalue of type 'int *'}}
+
+
+template<typename T>
+struct extract_type_type {
+  typedef typename T::type::type t;
+};
+
+double d;
+extract_type_type<bind_metafun<add_pointer, double> >::t dp = &d;
diff --git a/test/SemaTemplate/typename-specifier-3.cpp b/test/SemaTemplate/typename-specifier-3.cpp
new file mode 100644
index 0000000..a463d88
--- /dev/null
+++ b/test/SemaTemplate/typename-specifier-3.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// PR4364
+template<class T> struct a {
+  T b() {
+    return typename T::x();
+  }
+};
+struct B {
+  typedef B x;
+};
+B c() {
+  a<B> x;
+  return x.b();
+}
+
+// Some extra tests for invalid cases
+template<class T> struct test2 { T b() { return typename T::a; } }; // expected-error{{expected '(' for function-style cast or type construction}}
+template<class T> struct test3 { T b() { return typename a; } }; // expected-error{{expected a qualified name after 'typename'}}
diff --git a/test/SemaTemplate/typename-specifier-4.cpp b/test/SemaTemplate/typename-specifier-4.cpp
new file mode 100644
index 0000000..280a1b4
--- /dev/null
+++ b/test/SemaTemplate/typename-specifier-4.cpp
@@ -0,0 +1,118 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename T, typename U> 
+struct is_same {
+  static const bool value = false;
+};
+
+template<typename T>
+struct is_same<T, T> {
+  static const bool value = true;
+};
+
+template<typename MetaFun, typename T1, typename T2>
+struct metafun_apply2 {
+  typedef typename MetaFun::template apply<T1, T2> inner;
+  typedef typename inner::type type;
+};
+
+template<typename T, typename U> struct pair;
+
+struct make_pair {
+  template<typename T1, typename T2>
+  struct apply {
+    typedef pair<T1, T2> type;
+  };
+};
+
+int a0[is_same<metafun_apply2<make_pair, int, float>::type, 
+               pair<int, float> >::value? 1 : -1];
+int a1[is_same<
+         typename make_pair::template apply<int, float>,
+         make_pair::apply<int, float>
+       >::value? 1 : -1];
+
+template<typename MetaFun>
+struct swap_and_apply2 {
+  template<typename T1, typename T2>
+  struct apply {
+    typedef typename MetaFun::template apply<T2, T1> new_metafun;
+    typedef typename new_metafun::type type;
+  };
+};
+
+int a2[is_same<swap_and_apply2<make_pair>::apply<int, float>::type, 
+               pair<float, int> >::value? 1 : -1];
+
+template<typename MetaFun>
+struct swap_and_apply2b {
+  template<typename T1, typename T2>
+  struct apply {
+    typedef typename MetaFun::template apply<T2, T1>::type type;
+  };
+};
+
+int a3[is_same<swap_and_apply2b<make_pair>::apply<int, float>::type, 
+               pair<float, int> >::value? 1 : -1];
+
+template<typename T>
+struct X0 {
+  template<typename U, typename V>
+  struct Inner;
+  
+  void f0(X0<T>::Inner<T*, T&>); // expected-note{{here}}
+  void f0(typename X0<T>::Inner<T*, T&>); // expected-error{{redecl}}
+
+  void f1(X0<T>::Inner<T*, T&>); // expected-note{{here}}
+  void f1(typename X0<T>::template Inner<T*, T&>); // expected-error{{redecl}}
+
+  void f2(typename X0<T>::Inner<T*, T&>::type); // expected-note{{here}}
+  void f2(typename X0<T>::template Inner<T*, T&>::type); // expected-error{{redecl}}
+};
+
+namespace PR6236 {
+  template<typename T, typename U> struct S { };
+  
+  template<typename T> struct S<T, T> {
+    template<typename U> struct K { };
+    
+    void f() {
+      typedef typename S<T, T>::template K<T> Foo;
+    }
+  };
+}
+
+namespace PR6268 {
+  template <typename T>
+  struct Outer {
+    template <typename U>
+    struct Inner {};
+
+    template <typename U>
+    typename Outer<T>::template Inner<U>
+    foo(typename Outer<T>::template Inner<U>);
+  };
+
+  template <typename T>
+  template <typename U>
+  typename Outer<T>::template Inner<U>
+  Outer<T>::foo(typename Outer<T>::template Inner<U>) {
+    return Inner<U>();
+  }
+}
+
+namespace PR6463 {
+  struct B { typedef int type; }; // expected-note 2{{member found by ambiguous name lookup}}
+  struct C { typedef int type; }; // expected-note 2{{member found by ambiguous name lookup}}
+
+  template<typename T>
+  struct A : B, C { 
+    type& a(); // expected-error{{found in multiple base classes}}
+    int x; 
+  };
+
+  // FIXME: Improve source location info here.
+  template<typename T>
+  typename A<T>::type& A<T>::a() { // expected-error{{found in multiple base classes}}
+    return x;  // expected-error{{undeclared identifier}}
+  }
+}
diff --git a/test/SemaTemplate/typename-specifier.cpp b/test/SemaTemplate/typename-specifier.cpp
new file mode 100644
index 0000000..3f6fe34
--- /dev/null
+++ b/test/SemaTemplate/typename-specifier.cpp
@@ -0,0 +1,70 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+namespace N {
+  struct A {
+    typedef int type;
+  };
+
+  struct B {
+  };
+
+  struct C {
+    struct type { };
+    int type; // expected-note 2{{referenced member 'type' is declared here}}
+  };
+}
+
+int i;
+
+typename N::A::type *ip1 = &i;
+typename N::B::type *ip2 = &i; // expected-error{{no type named 'type' in 'N::B'}}
+typename N::C::type *ip3 = &i; // expected-error{{typename specifier refers to non-type member 'type'}}
+
+void test(double d) {
+  typename N::A::type f(typename N::A::type(a)); // expected-warning{{parentheses were disambiguated as a function declarator}}
+  int five = f(5);
+  
+  using namespace N;
+  for (typename A::type i = 0; i < 10; ++i)
+    five += 1;
+
+  const typename N::A::type f2(d);
+}
+
+namespace N {
+  template<typename T>
+  struct X {
+    typedef typename T::type type; // expected-error {{no type named 'type' in 'N::B'}} \
+    // expected-error {{no type named 'type' in 'B'}} \
+    // FIXME: location info for error above isn't very good \
+    // expected-error 2{{typename specifier refers to non-type member 'type'}} \
+    // expected-error{{type 'int' cannot be used prior to '::' because it has no members}}
+  };
+}
+
+N::X<N::A>::type *ip4 = &i;
+N::X<N::B>::type *ip5 = &i; // expected-note{{in instantiation of template class 'N::X<N::B>' requested here}}
+N::X<N::C>::type *ip6 = &i; // expected-note{{in instantiation of template class 'N::X<N::C>' requested here}}
+
+N::X<int>::type fail1; // expected-note{{in instantiation of template class 'N::X<int>' requested here}}
+
+template<typename T>
+struct Y {
+  typedef typename N::X<T>::type *type; // expected-note{{in instantiation of template class 'N::X<B>' requested here}} \
+  // expected-note{{in instantiation of template class 'N::X<C>' requested here}}
+};
+
+struct A {
+  typedef int type;
+};
+
+struct B {
+};
+
+struct C {
+  struct type { };
+  int type; // expected-note{{referenced member 'type' is declared here}}
+};
+
+::Y<A>::type ip7 = &i;
+::Y<B>::type ip8 = &i; // expected-note{{in instantiation of template class 'Y<B>' requested here}}
+::Y<C>::type ip9 = &i; // expected-note{{in instantiation of template class 'Y<C>' requested here}}
diff --git a/test/SemaTemplate/typo-dependent-name.cpp b/test/SemaTemplate/typo-dependent-name.cpp
new file mode 100644
index 0000000..96554e9
--- /dev/null
+++ b/test/SemaTemplate/typo-dependent-name.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T>
+struct Base {
+  T inner;
+};
+
+template<typename T>
+struct X {
+  template<typename U>
+  struct Inner {
+  };
+
+  bool f(T other) {
+    return this->inner < other;
+  }
+};
diff --git a/test/SemaTemplate/value-dependent-null-pointer-constant.cpp b/test/SemaTemplate/value-dependent-null-pointer-constant.cpp
new file mode 100644
index 0000000..223500e
--- /dev/null
+++ b/test/SemaTemplate/value-dependent-null-pointer-constant.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -fsyntax-only %s
+
+template<typename T, int N>
+struct X0 {
+  const char *f0(bool Cond) {
+    return Cond? "honk" : N;
+  }
+
+  const char *f1(bool Cond) {
+    return Cond? N : "honk";
+  }
+  
+  bool f2(const char *str) {
+    return str == N;
+  }
+};
+
+// PR4996
+template<unsigned I> int f0() { 
+  return __builtin_choose_expr(I, 0, 1); 
+}
+
+// PR5041
+struct A { };
+
+template <typename T> void f(T *t)
+{
+  (void)static_cast<void*>(static_cast<A*>(t));
+}
diff --git a/test/SemaTemplate/variadic-class-template-1.cpp b/test/SemaTemplate/variadic-class-template-1.cpp
new file mode 100644
index 0000000..6da64fb
--- /dev/null
+++ b/test/SemaTemplate/variadic-class-template-1.cpp
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
+
+template<typename ... Args = int> struct S1 { }; // expected-error{{template parameter pack cannot have a default argument}}
+template<typename ... Args, typename T> struct S2 { }; // expected-error{{template parameter pack must be the last template parameter}}
diff --git a/test/SemaTemplate/variadic-class-template-2.cpp b/test/SemaTemplate/variadic-class-template-2.cpp
new file mode 100644
index 0000000..5099771
--- /dev/null
+++ b/test/SemaTemplate/variadic-class-template-2.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
+
+// Type parameters packs
+template <typename ...> struct TS1 {}; // expected-note{{template parameter is declared here}}
+template struct TS1<>;
+template struct TS1<int>;
+template struct TS1<int, int>;
+template struct TS1<int, 10>; // expected-error{{template argument for template type parameter must be a type}}
+
+template <typename, typename ...> struct TS2 {}; // expected-note{{template is declared here}}
+template struct TS2<>; // expected-error{{too few template arguments for class template 'TS2'}}
+template struct TS2<int>;
+template struct TS2<int, int>;
+
+template <typename = int, typename ...> struct TS3 {}; // expected-note{{template parameter is declared here}}
+template struct TS3<>; // expected-note{{previous explicit instantiation is here}}
+template struct TS3<int>; // expected-error{{duplicate explicit instantiation of 'TS3}}
+template struct TS3<int, int>;
+template struct TS3<10>; // expected-error{{template argument for template type parameter must be a type}}
diff --git a/test/SemaTemplate/variadic-parse.cpp b/test/SemaTemplate/variadic-parse.cpp
new file mode 100644
index 0000000..d8b77b3
--- /dev/null
+++ b/test/SemaTemplate/variadic-parse.cpp
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
+
+// Parsing type parameter packs.
+template <typename ... Args> struct T1 {};
+template <typename ... > struct T2 {};
+
diff --git a/test/SemaTemplate/variadic-unsupported.cpp b/test/SemaTemplate/variadic-unsupported.cpp
new file mode 100644
index 0000000..9f2b080
--- /dev/null
+++ b/test/SemaTemplate/variadic-unsupported.cpp
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// Type parameter packs.
+template <typename ... > struct T1 {}; // expected-error{{variadic templates are only allowed in C++0x}}
+
diff --git a/test/SemaTemplate/virtual-member-functions.cpp b/test/SemaTemplate/virtual-member-functions.cpp
new file mode 100644
index 0000000..59df3c2
--- /dev/null
+++ b/test/SemaTemplate/virtual-member-functions.cpp
@@ -0,0 +1,55 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace PR5557 {
+template <class T> struct A {
+  A();
+  virtual void anchor(); // expected-note{{instantiation}}
+  virtual int a(T x);
+};
+template<class T> A<T>::A() {}
+template<class T> void A<T>::anchor() { }
+
+template<class T> int A<T>::a(T x) { 
+  return *x; // expected-error{{requires pointer operand}}
+}
+
+void f(A<int> x) {
+  x.anchor();
+}
+
+template<typename T>
+struct X {
+  virtual void f();
+};
+
+template<>
+void X<int>::f() { }
+}
+
+template<typename T>
+struct Base {
+  virtual ~Base() { 
+    int *ptr = 0;
+    T t = ptr; // expected-error{{cannot initialize}}
+  }
+};
+
+template<typename T>
+struct Derived : Base<T> {
+  virtual void foo() { }
+};
+
+template struct Derived<int>; // expected-note {{in instantiation of member function 'Base<int>::~Base' requested here}}
+
+template<typename T>
+struct HasOutOfLineKey {
+  HasOutOfLineKey() { } // expected-note{{in instantiation of member function 'HasOutOfLineKey<int>::f' requested here}}
+  virtual T *f(float *fp);
+};
+
+template<typename T>
+T *HasOutOfLineKey<T>::f(float *fp) {
+  return fp; // expected-error{{cannot initialize return object of type 'int *' with an lvalue of type 'float *'}}
+}
+
+HasOutOfLineKey<int> out_of_line;
diff --git a/test/TestRunner.sh b/test/TestRunner.sh
new file mode 100755
index 0000000..f96d3d5
--- /dev/null
+++ b/test/TestRunner.sh
@@ -0,0 +1,13 @@
+#!/bin/sh
+#
+# TestRunner.sh - Backward compatible utility for testing an individual file.
+
+# Find where this script is.
+Dir=$(dirname $(which $0))
+AbsDir=$(cd $Dir; pwd)
+
+# Find 'lit', assuming standard layout.
+lit=$AbsDir/../../../utils/lit/lit.py
+
+# Dispatch to lit.
+$lit "$@"
diff --git a/test/cxx-sections.data b/test/cxx-sections.data
new file mode 100644
index 0000000..0edc5f1
--- /dev/null
+++ b/test/cxx-sections.data
@@ -0,0 +1,1943 @@
+1 [intro]
+    1.1 [intro.scope]
+    1.2 [intro.refs]
+    1.3 [intro.defs]
+        1.3.1 [defns.argument]
+        1.3.2 [defns.cond.supp]
+        1.3.3 [defns.diagnostic]
+        1.3.4 [defns.dynamic.type]
+        1.3.5 [defns.ill.formed]
+        1.3.6 [defns.impl.defined]
+        1.3.7 [defns.impl.limits]
+        1.3.8 [defns.locale.specific]
+        1.3.9 [defns.multibyte]
+        1.3.10 [defns.parameter]
+        1.3.11 [defns.signature]
+        1.3.12 [defns.static.type]
+        1.3.13 [defns.undefined]
+        1.3.14 [defns.unspecified]
+        1.3.15 [defns.well.formed]
+    1.4 [intro.compliance]
+    1.5 [intro.structure]
+    1.6 [syntax]
+    1.7 [intro.memory]
+    1.8 [intro.object]
+    1.9 [intro.execution]
+    1.10 [intro.multithread]
+    1.11 [intro.ack]
+2 [lex]
+    2.1 [lex.separate]
+    2.2 [lex.phases]
+    2.3 [lex.charset]
+    2.4 [lex.trigraph]
+    2.5 [lex.pptoken]
+    2.6 [lex.digraph]
+    2.7 [lex.token]
+    2.8 [lex.comment]
+    2.9 [lex.header]
+    2.10 [lex.ppnumber]
+    2.11 [lex.name]
+    2.12 [lex.key]
+    2.13 [lex.operators]
+    2.14 [lex.literal]
+        2.14.1 [lex.literal.kinds]
+        2.14.2 [lex.icon]
+        2.14.3 [lex.ccon]
+        2.14.4 [lex.fcon]
+        2.14.5 [lex.string]
+        2.14.6 [lex.bool]
+        2.14.7 [lex.nullptr]
+        2.14.8 [lex.ext]
+3 [basic]
+    3.1 [basic.def]
+    3.2 [basic.def.odr]
+    3.3 [basic.scope]
+        3.3.1 [basic.scope.declarative]
+        3.3.2 [basic.scope.pdecl]
+        3.3.3 [basic.scope.local]
+        3.3.4 [basic.scope.proto]
+        3.3.5 [basic.funscope]
+        3.3.6 [basic.scope.namespace]
+        3.3.7 [basic.scope.class]
+        3.3.8 [basic.scope.concept]
+        3.3.9 [basic.scope.req]
+        3.3.10 [basic.scope.enum]
+        3.3.11 [basic.scope.hiding]
+    3.4 [basic.lookup]
+        3.4.1 [basic.lookup.unqual]
+        3.4.2 [basic.lookup.argdep]
+        3.4.3 [basic.lookup.qual]
+            3.4.3.1 [class.qual]
+            3.4.3.2 [namespace.qual]
+            3.4.3.3 [concept.qual]
+        3.4.4 [basic.lookup.elab]
+        3.4.5 [basic.lookup.classref]
+        3.4.6 [basic.lookup.udir]
+    3.5 [basic.link]
+    3.6 [basic.start]
+        3.6.1 [basic.start.main]
+        3.6.2 [basic.start.init]
+        3.6.3 [basic.start.term]
+    3.7 [basic.stc]
+        3.7.1 [basic.stc.static]
+        3.7.2 [basic.stc.thread]
+        3.7.3 [basic.stc.auto]
+        3.7.4 [basic.stc.dynamic]
+            3.7.4.1 [basic.stc.dynamic.allocation]
+            3.7.4.2 [basic.stc.dynamic.deallocation]
+            3.7.4.3 [basic.stc.dynamic.safety]
+        3.7.5 [basic.stc.inherit]
+    3.8 [basic.life]
+    3.9 [basic.types]
+        3.9.1 [basic.fundamental]
+        3.9.2 [basic.compound]
+        3.9.3 [basic.type.qualifier]
+    3.10 [basic.lval]
+    3.11 [basic.align]
+4 [conv]
+    4.1 [conv.lval]
+    4.2 [conv.array]
+    4.3 [conv.func]
+    4.4 [conv.qual]
+    4.5 [conv.prom]
+    4.6 [conv.fpprom]
+    4.7 [conv.integral]
+    4.8 [conv.double]
+    4.9 [conv.fpint]
+    4.10 [conv.ptr]
+    4.11 [conv.mem]
+    4.12 [conv.bool]
+    4.13 [conv.rank]
+5 [expr]
+    5.1 [expr.prim]
+        5.1.1 [expr.prim.general]
+        5.1.2 [expr.prim.lambda]
+    5.2 [expr.post]
+        5.2.1 [expr.sub]
+        5.2.2 [expr.call]
+        5.2.3 [expr.type.conv]
+        5.2.4 [expr.pseudo]
+        5.2.5 [expr.ref]
+        5.2.6 [expr.post.incr]
+        5.2.7 [expr.dynamic.cast]
+        5.2.8 [expr.typeid]
+        5.2.9 [expr.static.cast]
+        5.2.10 [expr.reinterpret.cast]
+        5.2.11 [expr.const.cast]
+    5.3 [expr.unary]
+        5.3.1 [expr.unary.op]
+        5.3.2 [expr.pre.incr]
+        5.3.3 [expr.sizeof]
+        5.3.4 [expr.new]
+        5.3.5 [expr.delete]
+        5.3.6 [expr.alignof]
+    5.4 [expr.cast]
+    5.5 [expr.mptr.oper]
+    5.6 [expr.mul]
+    5.7 [expr.add]
+    5.8 [expr.shift]
+    5.9 [expr.rel]
+    5.10 [expr.eq]
+    5.11 [expr.bit.and]
+    5.12 [expr.xor]
+    5.13 [expr.or]
+    5.14 [expr.log.and]
+    5.15 [expr.log.or]
+    5.16 [expr.cond]
+    5.17 [expr.ass]
+    5.18 [expr.comma]
+    5.19 [expr.const]
+6 [stmt.stmt]
+    6.1 [stmt.label]
+    6.2 [stmt.expr]
+    6.3 [stmt.block]
+    6.4 [stmt.select]
+        6.4.1 [stmt.if]
+        6.4.2 [stmt.switch]
+    6.5 [stmt.iter]
+        6.5.1 [stmt.while]
+        6.5.2 [stmt.do]
+        6.5.3 [stmt.for]
+        6.5.4 [stmt.ranged]
+    6.6 [stmt.jump]
+        6.6.1 [stmt.break]
+        6.6.2 [stmt.cont]
+        6.6.3 [stmt.return]
+        6.6.4 [stmt.goto]
+    6.7 [stmt.dcl]
+    6.8 [stmt.ambig]
+    6.9 [stmt.late]
+7 [dcl.dcl]
+    7.1 [dcl.spec]
+        7.1.1 [dcl.stc]
+        7.1.2 [dcl.fct.spec]
+        7.1.3 [dcl.typedef]
+        7.1.4 [dcl.friend]
+        7.1.5 [dcl.constexpr]
+        7.1.6 [dcl.type]
+            7.1.6.1 [dcl.type.cv]
+            7.1.6.2 [dcl.type.simple]
+            7.1.6.3 [dcl.type.elab]
+            7.1.6.4 [dcl.spec.auto]
+    7.2 [dcl.enum]
+    7.3 [basic.namespace]
+        7.3.1 [namespace.def]
+            7.3.1.1 [namespace.unnamed]
+            7.3.1.2 [namespace.memdef]
+        7.3.2 [namespace.alias]
+        7.3.3 [namespace.udecl]
+        7.3.4 [namespace.udir]
+    7.4 [dcl.asm]
+    7.5 [dcl.link]
+    7.6 [dcl.attr]
+        7.6.1 [dcl.attr.grammar]
+        7.6.2 [dcl.align]
+        7.6.3 [dcl.attr.noreturn]
+        7.6.4 [dcl.attr.final]
+        7.6.5 [dcl.attr.depend]
+8 [dcl.decl]
+    8.1 [dcl.name]
+    8.2 [dcl.ambig.res]
+    8.3 [dcl.meaning]
+        8.3.1 [dcl.ptr]
+        8.3.2 [dcl.ref]
+        8.3.3 [dcl.mptr]
+        8.3.4 [dcl.array]
+        8.3.5 [dcl.fct]
+        8.3.6 [dcl.fct.default]
+    8.4 [dcl.fct.def]
+    8.5 [dcl.init]
+        8.5.1 [dcl.init.aggr]
+        8.5.2 [dcl.init.string]
+        8.5.3 [dcl.init.ref]
+        8.5.4 [dcl.init.list]
+9 [class]
+    9.1 [class.name]
+    9.2 [class.mem]
+    9.3 [class.mfct]
+        9.3.1 [class.mfct.non-static]
+        9.3.2 [class.this]
+    9.4 [class.static]
+        9.4.1 [class.static.mfct]
+        9.4.2 [class.static.data]
+    9.5 [class.union]
+    9.6 [class.bit]
+    9.7 [class.nest]
+    9.8 [class.local]
+    9.9 [class.nested.type]
+10 [class.derived]
+    10.1 [class.mi]
+    10.2 [class.member.lookup]
+    10.3 [class.virtual]
+    10.4 [class.abstract]
+11 [class.access]
+    11.1 [class.access.spec]
+    11.2 [class.access.base]
+    11.3 [class.access.dcl]
+    11.4 [class.friend]
+    11.5 [class.protected]
+    11.6 [class.access.virt]
+    11.7 [class.paths]
+    11.8 [class.access.nest]
+12 [special]
+    12.1 [class.ctor]
+    12.2 [class.temporary]
+    12.3 [class.conv]
+        12.3.1 [class.conv.ctor]
+        12.3.2 [class.conv.fct]
+    12.4 [class.dtor]
+    12.5 [class.free]
+    12.6 [class.init]
+        12.6.1 [class.expl.init]
+        12.6.2 [class.base.init]
+    12.7 [class.cdtor]
+    12.8 [class.copy]
+    12.9 [class.inhctor]
+13 [over]
+    13.1 [over.load]
+    13.2 [over.dcl]
+    13.3 [over.match]
+        13.3.1 [over.match.funcs]
+            13.3.1.1 [over.match.call]
+                13.3.1.1.1 [over.call.func]
+                13.3.1.1.2 [over.call.object]
+            13.3.1.2 [over.match.oper]
+            13.3.1.3 [over.match.ctor]
+            13.3.1.4 [over.match.copy]
+            13.3.1.5 [over.match.conv]
+            13.3.1.6 [over.match.ref]
+            13.3.1.7 [over.match.list]
+        13.3.2 [over.match.viable]
+        13.3.3 [over.match.best]
+            13.3.3.1 [over.best.ics]
+                13.3.3.1.1 [over.ics.scs]
+                13.3.3.1.2 [over.ics.user]
+                13.3.3.1.3 [over.ics.ellipsis]
+                13.3.3.1.4 [over.ics.ref]
+                13.3.3.1.5 [over.ics.list]
+            13.3.3.2 [over.ics.rank]
+    13.4 [over.over]
+    13.5 [over.oper]
+        13.5.1 [over.unary]
+        13.5.2 [over.binary]
+        13.5.3 [over.ass]
+        13.5.4 [over.call]
+        13.5.5 [over.sub]
+        13.5.6 [over.ref]
+        13.5.7 [over.inc]
+        13.5.8 [over.literal]
+    13.6 [over.built]
+14 [temp]
+    14.1 [temp.export]
+    14.2 [temp.param]
+    14.3 [temp.names]
+    14.4 [temp.arg]
+        14.4.1 [temp.arg.type]
+        14.4.2 [temp.arg.nontype]
+        14.4.3 [temp.arg.template]
+    14.5 [temp.type]
+    14.6 [temp.decls]
+        14.6.1 [temp.class]
+            14.6.1.1 [temp.mem.func]
+            14.6.1.2 [temp.mem.class]
+            14.6.1.3 [temp.static]
+        14.6.2 [temp.mem]
+        14.6.3 [temp.variadic]
+        14.6.4 [temp.friend]
+        14.6.5 [temp.class.spec]
+            14.6.5.1 [temp.class.spec.match]
+            14.6.5.2 [temp.class.order]
+            14.6.5.3 [temp.class.spec.mfunc]
+        14.6.6 [temp.fct]
+            14.6.6.1 [temp.over.link]
+            14.6.6.2 [temp.func.order]
+        14.6.7 [temp.alias]
+        14.6.8 [temp.concept.map]
+    14.7 [temp.res]
+        14.7.1 [temp.local]
+        14.7.2 [temp.dep]
+            14.7.2.1 [temp.dep.type]
+            14.7.2.2 [temp.dep.expr]
+            14.7.2.3 [temp.dep.constexpr]
+            14.7.2.4 [temp.dep.temp]
+        14.7.3 [temp.nondep]
+        14.7.4 [temp.dep.res]
+            14.7.4.1 [temp.point]
+            14.7.4.2 [temp.dep.candidate]
+        14.7.5 [temp.inject]
+    14.8 [temp.spec]
+        14.8.1 [temp.inst]
+        14.8.2 [temp.explicit]
+        14.8.3 [temp.expl.spec]
+    14.9 [temp.fct.spec]
+        14.9.1 [temp.arg.explicit]
+        14.9.2 [temp.deduct]
+            14.9.2.1 [temp.deduct.call]
+            14.9.2.2 [temp.deduct.funcaddr]
+            14.9.2.3 [temp.deduct.conv]
+            14.9.2.4 [temp.deduct.partial]
+            14.9.2.5 [temp.deduct.type]
+        14.9.3 [temp.over]
+    14.10 [concept]
+        14.10.1 [concept.def]
+            14.10.1.1 [concept.fct]
+            14.10.1.2 [concept.assoc]
+            14.10.1.3 [concept.req]
+            14.10.1.4 [concept.axiom]
+        14.10.2 [concept.map]
+            14.10.2.1 [concept.map.fct]
+            14.10.2.2 [concept.map.assoc]
+        14.10.3 [concept.refine]
+            14.10.3.1 [concept.member.lookup]
+            14.10.3.2 [concept.refine.maps]
+        14.10.4 [concept.support]
+    14.11 [temp.constrained]
+        14.11.1 [temp.req]
+            14.11.1.1 [temp.req.sat]
+            14.11.1.2 [temp.req.impl]
+        14.11.2 [temp.archetype]
+            14.11.2.1 [temp.archetype.assemble]
+        14.11.3 [temp.constrained.set]
+        14.11.4 [temp.constrained.inst]
+15 [except]
+    15.1 [except.throw]
+    15.2 [except.ctor]
+    15.3 [except.handle]
+    15.4 [except.spec]
+    15.5 [except.special]
+        15.5.1 [except.terminate]
+        15.5.2 [except.unexpected]
+        15.5.3 [except.uncaught]
+16 [cpp]
+    16.1 [cpp.cond]
+    16.2 [cpp.include]
+    16.3 [cpp.replace]
+        16.3.1 [cpp.subst]
+        16.3.2 [cpp.stringize]
+        16.3.3 [cpp.concat]
+        16.3.4 [cpp.rescan]
+        16.3.5 [cpp.scope]
+    16.4 [cpp.line]
+    16.5 [cpp.error]
+    16.6 [cpp.pragma]
+    16.7 [cpp.null]
+    16.8 [cpp.predefined]
+    16.9 [cpp.pragma.op]
+17 [library]
+    17.1 [library.general]
+    17.2 [library.c]
+    17.3 [definitions]
+        17.3.1 [defns.arbitrary.stream]
+        17.3.2 [defns.blocked]
+        17.3.3 [defns.character]
+        17.3.4 [defns.character.container]
+        17.3.5 [defns.comparison]
+        17.3.6 [defns.component]
+        17.3.7 [defns.deadlock]
+        17.3.8 [defns.default.behavior]
+        17.3.9 [defns.handler]
+        17.3.10 [defns.iostream.templates]
+        17.3.11 [defns.modifier]
+        17.3.12 [defns.move.assign]
+        17.3.13 [defns.move.assign.op]
+        17.3.14 [defns.move.ctor]
+        17.3.15 [defns.obj.state]
+        17.3.16 [defns.ntcts]
+        17.3.17 [defns.observer]
+        17.3.18 [defns.replacement]
+        17.3.19 [defns.repositional.stream]
+        17.3.20 [defns.required.behavior]
+        17.3.21 [defns.reserved.function]
+        17.3.22 [defns.stable]
+        17.3.23 [defns.traits]
+    17.4 [defns.additional]
+    17.5 [description]
+        17.5.1 [structure]
+            17.5.1.1 [structure.elements]
+            17.5.1.2 [structure.summary]
+            17.5.1.3 [structure.requirements]
+            17.5.1.4 [structure.specifications]
+            17.5.1.5 [structure.see.also]
+        17.5.2 [conventions]
+            17.5.2.1 [type.descriptions]
+                17.5.2.1.1 [type.descriptions.general]
+                17.5.2.1.2 [enumerated.types]
+                17.5.2.1.3 [bitmask.types]
+                17.5.2.1.4 [character.seq]
+                    17.5.2.1.4.1 [byte.strings]
+                    17.5.2.1.4.2 [multibyte.strings]
+                    17.5.2.1.4.3 [char16_t.seq]
+                    17.5.2.1.4.4 [char32_t.seq]
+                    17.5.2.1.4.5 [wide.characters]
+            17.5.2.2 [functions.within.classes]
+            17.5.2.3 [objects.within.classes]
+    17.6 [requirements]
+        17.6.1 [organization]
+            17.6.1.1 [contents]
+            17.6.1.2 [headers]
+            17.6.1.3 [compliance]
+        17.6.2 [using]
+            17.6.2.1 [using.overview]
+            17.6.2.2 [using.headers]
+            17.6.2.3 [using.linkage]
+        17.6.3 [constraints]
+            17.6.3.1 [constraints.overview]
+            17.6.3.2 [namespace.constraints]
+                17.6.3.2.1 [namespace.std]
+                17.6.3.2.2 [namespace.posix]
+            17.6.3.3 [reserved.names]
+                17.6.3.3.1 [macro.names]
+                17.6.3.3.2 [global.names]
+                17.6.3.3.3 [extern.names]
+                17.6.3.3.4 [extern.types]
+                17.6.3.3.5 [usrlit.suffix]
+            17.6.3.4 [alt.headers]
+            17.6.3.5 [derived.classes]
+            17.6.3.6 [replacement.functions]
+            17.6.3.7 [handler.functions]
+            17.6.3.8 [res.on.functions]
+            17.6.3.9 [res.on.arguments]
+            17.6.3.10 [res.on.objects]
+            17.6.3.11 [res.on.required]
+        17.6.4 [conforming]
+            17.6.4.1 [conforming.overview]
+            17.6.4.2 [res.on.headers]
+            17.6.4.3 [res.on.macro.definitions]
+            17.6.4.4 [global.functions]
+            17.6.4.5 [member.functions]
+            17.6.4.6 [reentrancy]
+            17.6.4.7 [res.on.data.races]
+            17.6.4.8 [protection.within.classes]
+            17.6.4.9 [derivation]
+            17.6.4.10 [res.on.exception.handling]
+            17.6.4.11 [res.on.pointer.storage]
+            17.6.4.12 [value.error.codes]
+18 [language.support]
+    18.1 [support.general]
+    18.2 [support.types]
+    18.3 [support.limits]
+        18.3.1 [limits]
+            18.3.1.1 [numeric.limits]
+            18.3.1.2 [numeric.limits.members]
+            18.3.1.3 [round.style]
+            18.3.1.4 [denorm.style]
+            18.3.1.5 [numeric.special]
+        18.3.2 [c.limits]
+    18.4 [cstdint]
+        18.4.1 [cstdint.syn]
+        18.4.2 [stdinth]
+    18.5 [support.start.term]
+    18.6 [support.dynamic]
+        18.6.1 [new.delete]
+            18.6.1.1 [new.delete.single]
+            18.6.1.2 [new.delete.array]
+            18.6.1.3 [new.delete.placement]
+            18.6.1.4 [new.delete.dataraces]
+        18.6.2 [alloc.errors]
+            18.6.2.1 [bad.alloc]
+            18.6.2.2 [new.handler]
+            18.6.2.3 [set.new.handler]
+    18.7 [support.rtti]
+        18.7.1 [type.info]
+        18.7.2 [type.index]
+            18.7.2.1 [type.index.overview]
+            18.7.2.2 [type.index.members]
+            18.7.2.3 [type.index.templ]
+        18.7.3 [bad.cast]
+        18.7.4 [bad.typeid]
+    18.8 [support.exception]
+        18.8.1 [exception]
+        18.8.2 [exception.unexpected]
+            18.8.2.1 [bad.exception]
+            18.8.2.2 [unexpected.handler]
+            18.8.2.3 [set.unexpected]
+            18.8.2.4 [unexpected]
+        18.8.3 [exception.terminate]
+            18.8.3.1 [terminate.handler]
+            18.8.3.2 [set.terminate]
+            18.8.3.3 [terminate]
+        18.8.4 [uncaught]
+        18.8.5 [propagation]
+        18.8.6 [except.nested]
+    18.9 [support.initlist]
+        18.9.1 [support.initlist.cons]
+        18.9.2 [support.initlist.access]
+        18.9.3 [support.initlist.concept]
+    18.10 [support.runtime]
+19 [diagnostics]
+    19.1 [diagnostics.general]
+    19.2 [std.exceptions]
+        19.2.1 [logic.error]
+        19.2.2 [domain.error]
+        19.2.3 [invalid.argument]
+        19.2.4 [length.error]
+        19.2.5 [out.of.range]
+        19.2.6 [runtime.error]
+        19.2.7 [range.error]
+        19.2.8 [overflow.error]
+        19.2.9 [underflow.error]
+    19.3 [assertions]
+    19.4 [errno]
+    19.5 [syserr]
+        19.5.1 [syserr.errcat]
+            19.5.1.1 [syserr.errcat.overview]
+            19.5.1.2 [syserr.errcat.virtuals]
+            19.5.1.3 [syserr.errcat.nonvirtuals]
+            19.5.1.4 [syserr.errcat.derived]
+            19.5.1.5 [syserr.errcat.objects]
+        19.5.2 [syserr.errcode]
+            19.5.2.1 [syserr.errcodeenum]
+            19.5.2.2 [syserr.errcode.overview]
+            19.5.2.3 [syserr.errcode.constructors]
+            19.5.2.4 [syserr.errcode.modifiers]
+            19.5.2.5 [syserr.errcode.observers]
+            19.5.2.6 [syserr.errcode.nonmembers]
+        19.5.3 [syserr.errcondition]
+            19.5.3.1 [syserr.errcondenum]
+            19.5.3.2 [syserr.errcondition.overview]
+            19.5.3.3 [syserr.errcondition.constructors]
+            19.5.3.4 [syserr.errcondition.modifiers]
+            19.5.3.5 [syserr.errcondition.observers]
+            19.5.3.6 [syserr.errcondition.nonmembers]
+        19.5.4 [syserr.compare]
+        19.5.5 [syserr.syserr]
+            19.5.5.1 [syserr.syserr.overview]
+            19.5.5.2 [syserr.syserr.members]
+20 [utilities]
+    20.1 [utilities.general]
+    20.2 [utility.concepts]
+        20.2.1 [concept.transform]
+        20.2.2 [concept.true]
+        20.2.3 [concept.classify]
+        20.2.4 [concept.operator]
+        20.2.5 [concept.predicate]
+        20.2.6 [concept.comparison]
+        20.2.7 [concept.construct]
+        20.2.8 [concept.destruct]
+        20.2.9 [concept.copymove]
+        20.2.10 [concept.memory]
+        20.2.11 [concept.regular]
+        20.2.12 [concept.convertible]
+        20.2.13 [concept.arithmetic]
+    20.3 [utility]
+        20.3.1 [operators]
+        20.3.2 [forward]
+        20.3.3 [pairs]
+        20.3.4 [pair.astuple]
+        20.3.5 [pair.concepts]
+        20.3.6 [template.bitset]
+            20.3.6.1 [bitset.cons]
+            20.3.6.2 [bitset.members]
+            20.3.6.3 [bitset.operators]
+    20.4 [ratio]
+        20.4.1 [ratio.ratio]
+        20.4.2 [ratio.arithmetic]
+        20.4.3 [ratio.comparison]
+        20.4.4 [ratio.si]
+    20.5 [tuple]
+        20.5.1 [tuple.general]
+        20.5.2 [tuple.tuple]
+            20.5.2.1 [tuple.cnstr]
+            20.5.2.2 [tuple.creation]
+            20.5.2.3 [tuple.helper]
+            20.5.2.4 [tuple.elem]
+            20.5.2.5 [tuple.rel]
+            20.5.2.6 [tuple.swap]
+            20.5.2.7 [tuple.special]
+            20.5.2.8 [tuple.concepts]
+    20.6 [meta]
+        20.6.1 [meta.rqmts]
+        20.6.2 [meta.type.synop]
+        20.6.3 [meta.help]
+        20.6.4 [meta.unary]
+            20.6.4.1 [meta.unary.cat]
+            20.6.4.2 [meta.unary.comp]
+            20.6.4.3 [meta.unary.prop]
+        20.6.5 [meta.rel]
+        20.6.6 [meta.trans]
+            20.6.6.1 [meta.trans.cv]
+            20.6.6.2 [meta.trans.ref]
+            20.6.6.3 [meta.trans.sign]
+            20.6.6.4 [meta.trans.arr]
+            20.6.6.5 [meta.trans.ptr]
+        20.6.7 [meta.trans.other]
+    20.7 [function.objects]
+        20.7.1 [func.def]
+        20.7.2 [func.require]
+        20.7.3 [base]
+        20.7.4 [func.ret]
+        20.7.5 [refwrap]
+            20.7.5.1 [refwrap.const]
+            20.7.5.2 [refwrap.assign]
+            20.7.5.3 [refwrap.access]
+            20.7.5.4 [refwrap.invoke]
+            20.7.5.5 [refwrap.helpers]
+        20.7.6 [identity.operation]
+        20.7.7 [arithmetic.operations]
+        20.7.8 [comparisons]
+        20.7.9 [logical.operations]
+        20.7.10 [bitwise.operations]
+        20.7.11 [negators]
+        20.7.12 [bind]
+            20.7.12.1 [func.bind]
+                20.7.12.1.1 [func.bind.isbind]
+                20.7.12.1.2 [func.bind.isplace]
+                20.7.12.1.3 [func.bind.bind]
+                20.7.12.1.4 [func.bind.place]
+        20.7.13 [function.pointer.adaptors]
+        20.7.14 [member.pointer.adaptors]
+        20.7.15 [func.memfn]
+        20.7.16 [func.wrap]
+            20.7.16.1 [func.wrap.badcall]
+                20.7.16.1.1 [func.wrap.badcall.const]
+            20.7.16.2 [func.wrap.func]
+                20.7.16.2.1 [func.wrap.func.con]
+                20.7.16.2.2 [func.wrap.func.mod]
+                20.7.16.2.3 [func.wrap.func.cap]
+                20.7.16.2.4 [func.wrap.func.inv]
+                20.7.16.2.5 [func.wrap.func.targ]
+                20.7.16.2.6 [func.wrap.func.nullptr]
+                20.7.16.2.7 [func.wrap.func.alg]
+        20.7.17 [unord.hash]
+    20.8 [memory]
+        20.8.1 [allocator.tag]
+        20.8.2 [allocator]
+            20.8.2.1 [allocator.general]
+            20.8.2.2 [allocator.concepts]
+            20.8.2.3 [allocator.concepts.legacy]
+            20.8.2.4 [allocator.concepts.members]
+        20.8.3 [allocator.element.concepts]
+        20.8.4 [default.allocator]
+            20.8.4.1 [allocator.members]
+            20.8.4.2 [allocator.globals]
+        20.8.5 [allocator.adaptor]
+            20.8.5.1 [allocator.adaptor.base]
+            20.8.5.2 [allocator.adaptor.cntr]
+            20.8.5.3 [allocator.adaptor2.cntr]
+            20.8.5.4 [allocator.adaptor.members]
+            20.8.5.5 [allocator.adaptor.globals]
+        20.8.6 [storage.iterator]
+        20.8.7 [temporary.buffer]
+        20.8.8 [specialized.algorithms]
+            20.8.8.1 [object.addressof]
+            20.8.8.2 [uninitialized.copy]
+            20.8.8.3 [uninitialized.fill]
+            20.8.8.4 [uninitialized.fill.n]
+        20.8.9 [unique.ptr]
+            20.8.9.1 [unique.ptr.dltr]
+                20.8.9.1.1 [unique.ptr.dltr.dflt]
+                20.8.9.1.2 [unique.ptr.dltr.dflt1]
+            20.8.9.2 [unique.ptr.single]
+                20.8.9.2.1 [unique.ptr.single.ctor]
+                20.8.9.2.2 [unique.ptr.single.dtor]
+                20.8.9.2.3 [unique.ptr.single.asgn]
+                20.8.9.2.4 [unique.ptr.single.observers]
+                20.8.9.2.5 [unique.ptr.single.modifiers]
+            20.8.9.3 [unique.ptr.runtime]
+                20.8.9.3.1 [unique.ptr.runtime.ctor]
+                20.8.9.3.2 [unique.ptr.runtime.observers]
+                20.8.9.3.3 [unique.ptr.runtime.modifiers]
+            20.8.9.4 [unique.ptr.special]
+        20.8.10 [util.smartptr]
+            20.8.10.1 [util.smartptr.weakptr]
+            20.8.10.2 [util.smartptr.shared]
+                20.8.10.2.1 [util.smartptr.shared.const]
+                20.8.10.2.2 [util.smartptr.shared.dest]
+                20.8.10.2.3 [util.smartptr.shared.assign]
+                20.8.10.2.4 [util.smartptr.shared.mod]
+                20.8.10.2.5 [util.smartptr.shared.obs]
+                20.8.10.2.6 [util.smartptr.shared.create]
+                20.8.10.2.7 [util.smartptr.shared.cmp]
+                20.8.10.2.8 [util.smartptr.shared.io]
+                20.8.10.2.9 [util.smartptr.shared.spec]
+                20.8.10.2.10 [util.smartptr.shared.cast]
+                20.8.10.2.11 [util.smartptr.getdeleter]
+            20.8.10.3 [util.smartptr.weak]
+                20.8.10.3.1 [util.smartptr.weak.const]
+                20.8.10.3.2 [util.smartptr.weak.dest]
+                20.8.10.3.3 [util.smartptr.weak.assign]
+                20.8.10.3.4 [util.smartptr.weak.mod]
+                20.8.10.3.5 [util.smartptr.weak.obs]
+                20.8.10.3.6 [util.smartptr.weak.spec]
+            20.8.10.4 [util.smartptr.ownerless]
+            20.8.10.5 [util.smartptr.enab]
+            20.8.10.6 [util.smartptr.shared.atomic]
+            20.8.10.7 [util.dynamic.safety]
+        20.8.11 [ptr.align]
+        20.8.12 [c.malloc]
+    20.9 [time]
+        20.9.1 [time.clock.req]
+        20.9.2 [time.traits]
+            20.9.2.1 [time.traits.is_fp]
+            20.9.2.2 [time.traits.duration_values]
+            20.9.2.3 [time.traits.specializations]
+        20.9.3 [time.duration]
+            20.9.3.1 [time.duration.cons]
+            20.9.3.2 [time.duration.observer]
+            20.9.3.3 [time.duration.arithmetic]
+            20.9.3.4 [time.duration.special]
+            20.9.3.5 [time.duration.nonmember]
+            20.9.3.6 [time.duration.comparisons]
+            20.9.3.7 [time.duration.cast]
+        20.9.4 [time.point]
+            20.9.4.1 [time.point.cons]
+            20.9.4.2 [time.point.observer]
+            20.9.4.3 [time.point.arithmetic]
+            20.9.4.4 [time.point.special]
+            20.9.4.5 [time.point.nonmember]
+            20.9.4.6 [time.point.comparisons]
+            20.9.4.7 [time.point.cast]
+        20.9.5 [time.clock]
+            20.9.5.1 [time.clock.system]
+            20.9.5.2 [time.clock.monotonic]
+            20.9.5.3 [time.clock.hires]
+    20.10 [date.time]
+21 [strings]
+    21.1 [strings.general]
+    21.2 [char.traits]
+        21.2.1 [char.traits.require]
+        21.2.2 [char.traits.typedefs]
+        21.2.3 [char.traits.specializations]
+            21.2.3.1 [char.traits.specializations.char]
+            21.2.3.2 [char.traits.specializations.char16_t]
+            21.2.3.3 [char.traits.specializations.char32_t]
+            21.2.3.4 [char.traits.specializations.wchar.t]
+    21.3 [string.classes]
+    21.4 [basic.string]
+        21.4.1 [string.require]
+        21.4.2 [string.cons]
+        21.4.3 [string.iterators]
+        21.4.4 [string.capacity]
+        21.4.5 [string.access]
+        21.4.6 [string.modifiers]
+            21.4.6.1 [string::op+=]
+            21.4.6.2 [string::append]
+            21.4.6.3 [string::assign]
+            21.4.6.4 [string::insert]
+            21.4.6.5 [string::erase]
+            21.4.6.6 [string::replace]
+            21.4.6.7 [string::copy]
+            21.4.6.8 [string::swap]
+        21.4.7 [string.ops]
+            21.4.7.1 [string.accessors]
+            21.4.7.2 [string::find]
+            21.4.7.3 [string::rfind]
+            21.4.7.4 [string::find.first.of]
+            21.4.7.5 [string::find.last.of]
+            21.4.7.6 [string::find.first.not.of]
+            21.4.7.7 [string::find.last.not.of]
+            21.4.7.8 [string::substr]
+            21.4.7.9 [string::compare]
+        21.4.8 [string.nonmembers]
+            21.4.8.1 [string::op+]
+            21.4.8.2 [string::operator==]
+            21.4.8.3 [string::op!=]
+            21.4.8.4 [string::op&lt;]
+            21.4.8.5 [string::op&gt;]
+            21.4.8.6 [string::op&lt;=]
+            21.4.8.7 [string::op&gt;=]
+            21.4.8.8 [string.special]
+            21.4.8.9 [string.io]
+    21.5 [string.conversions]
+    21.6 [c.strings]
+22 [localization]
+    22.1 [localization.general]
+    22.2 [locale.syn]
+    22.3 [locales]
+        22.3.1 [locale]
+            22.3.1.1 [locale.types]
+                22.3.1.1.1 [locale.category]
+                22.3.1.1.2 [locale.facet]
+                22.3.1.1.3 [locale.id]
+            22.3.1.2 [locale.cons]
+            22.3.1.3 [locale.members]
+            22.3.1.4 [locale.operators]
+            22.3.1.5 [locale.statics]
+        22.3.2 [locale.global.templates]
+        22.3.3 [locale.convenience]
+            22.3.3.1 [classification]
+            22.3.3.2 [conversions]
+                22.3.3.2.1 [conversions.character]
+                22.3.3.2.2 [conversions.string]
+                22.3.3.2.3 [conversions.buffer]
+    22.4 [locale.categories]
+        22.4.1 [category.ctype]
+            22.4.1.1 [locale.ctype]
+                22.4.1.1.1 [locale.ctype.members]
+                22.4.1.1.2 [locale.ctype.virtuals]
+            22.4.1.2 [locale.ctype.byname]
+            22.4.1.3 [facet.ctype.special]
+                22.4.1.3.1 [facet.ctype.char.dtor]
+                22.4.1.3.2 [facet.ctype.char.members]
+                22.4.1.3.3 [facet.ctype.char.statics]
+                22.4.1.3.4 [facet.ctype.char.virtuals]
+            22.4.1.4 [locale.codecvt]
+                22.4.1.4.1 [locale.codecvt.members]
+                22.4.1.4.2 [locale.codecvt.virtuals]
+            22.4.1.5 [locale.codecvt.byname]
+        22.4.2 [category.numeric]
+            22.4.2.1 [locale.num.get]
+                22.4.2.1.1 [facet.num.get.members]
+                22.4.2.1.2 [facet.num.get.virtuals]
+            22.4.2.2 [locale.nm.put]
+                22.4.2.2.1 [facet.num.put.members]
+                22.4.2.2.2 [facet.num.put.virtuals]
+        22.4.3 [facet.numpunct]
+            22.4.3.1 [locale.numpunct]
+                22.4.3.1.1 [facet.numpunct.members]
+                22.4.3.1.2 [facet.numpunct.virtuals]
+            22.4.3.2 [locale.numpunct.byname]
+        22.4.4 [category.collate]
+            22.4.4.1 [locale.collate]
+                22.4.4.1.1 [locale.collate.members]
+                22.4.4.1.2 [locale.collate.virtuals]
+            22.4.4.2 [locale.collate.byname]
+        22.4.5 [category.time]
+            22.4.5.1 [locale.time.get]
+                22.4.5.1.1 [locale.time.get.members]
+                22.4.5.1.2 [locale.time.get.virtuals]
+            22.4.5.2 [locale.time.get.byname]
+            22.4.5.3 [locale.time.put]
+                22.4.5.3.1 [locale.time.put.members]
+                22.4.5.3.2 [locale.time.put.virtuals]
+            22.4.5.4 [locale.time.put.byname]
+        22.4.6 [category.monetary]
+            22.4.6.1 [locale.money.get]
+                22.4.6.1.1 [locale.money.get.members]
+                22.4.6.1.2 [locale.money.get.virtuals]
+            22.4.6.2 [locale.money.put]
+                22.4.6.2.1 [locale.money.put.members]
+                22.4.6.2.2 [locale.money.put.virtuals]
+            22.4.6.3 [locale.moneypunct]
+                22.4.6.3.1 [locale.moneypunct.members]
+                22.4.6.3.2 [locale.moneypunct.virtuals]
+            22.4.6.4 [locale.moneypunct.byname]
+        22.4.7 [category.messages]
+            22.4.7.1 [locale.messages]
+                22.4.7.1.1 [locale.messages.members]
+                22.4.7.1.2 [locale.messages.virtuals]
+            22.4.7.2 [locale.messages.byname]
+        22.4.8 [facets.examples]
+    22.5 [locale.stdcvt]
+    22.6 [c.locales]
+23 [containers]
+    23.1 [containers.general]
+    23.2 [container.requirements]
+        23.2.1 [container.requirements.general]
+        23.2.2 [container.requirements.dataraces]
+        23.2.3 [sequence.reqmts]
+        23.2.4 [associative.reqmts]
+            23.2.4.1 [associative.reqmts.except]
+        23.2.5 [unord.req]
+            23.2.5.1 [unord.req.except]
+        23.2.6 [container.concepts]
+            23.2.6.1 [container.concepts.free]
+            23.2.6.2 [container.concepts.member]
+            23.2.6.3 [container.concepts.maps]
+    23.3 [sequences]
+        23.3.1 [array]
+            23.3.1.1 [array.cons]
+            23.3.1.2 [array.special]
+            23.3.1.3 [array.size]
+            23.3.1.4 [array.data]
+            23.3.1.5 [array.fill]
+            23.3.1.6 [array.zero]
+            23.3.1.7 [array.tuple]
+        23.3.2 [deque]
+            23.3.2.1 [deque.cons]
+            23.3.2.2 [deque.capacity]
+            23.3.2.3 [deque.modifiers]
+            23.3.2.4 [deque.special]
+        23.3.3 [forwardlist]
+            23.3.3.1 [forwardlist.cons]
+            23.3.3.2 [forwardlist.iter]
+            23.3.3.3 [forwardlist.access]
+            23.3.3.4 [forwardlist.modifiers]
+            23.3.3.5 [forwardlist.ops]
+            23.3.3.6 [forwardlist.spec]
+        23.3.4 [list]
+            23.3.4.1 [list.cons]
+            23.3.4.2 [list.capacity]
+            23.3.4.3 [list.modifiers]
+            23.3.4.4 [list.ops]
+            23.3.4.5 [list.special]
+        23.3.5 [container.adaptors]
+            23.3.5.1 [queue]
+                23.3.5.1.1 [queue.defn]
+                23.3.5.1.2 [queue.ops]
+                23.3.5.1.3 [queue.special]
+            23.3.5.2 [priority.queue]
+                23.3.5.2.1 [priqueue.cons]
+                23.3.5.2.2 [priqueue.members]
+                23.3.5.2.3 [priqueue.special]
+            23.3.5.3 [stack]
+                23.3.5.3.1 [stack.defn]
+                23.3.5.3.2 [stack.ops]
+                23.3.5.3.3 [stack.special]
+        23.3.6 [vector]
+            23.3.6.1 [vector.cons]
+            23.3.6.2 [vector.capacity]
+            23.3.6.3 [vector.data]
+            23.3.6.4 [vector.modifiers]
+            23.3.6.5 [vector.special]
+        23.3.7 [vector.bool]
+    23.4 [associative]
+        23.4.1 [map]
+            23.4.1.1 [map.cons]
+            23.4.1.2 [map.access]
+            23.4.1.3 [map.modifiers]
+            23.4.1.4 [map.ops]
+            23.4.1.5 [map.special]
+        23.4.2 [multimap]
+            23.4.2.1 [multimap.cons]
+            23.4.2.2 [multimap.modifiers]
+            23.4.2.3 [multimap.ops]
+            23.4.2.4 [multimap.special]
+        23.4.3 [set]
+            23.4.3.1 [set.cons]
+            23.4.3.2 [set.special]
+        23.4.4 [multiset]
+            23.4.4.1 [multiset.cons]
+            23.4.4.2 [multiset.special]
+    23.5 [unord]
+        23.5.1 [unord.map]
+            23.5.1.1 [unord.map.cnstr]
+            23.5.1.2 [unord.map.elem]
+            23.5.1.3 [unord.map.swap]
+        23.5.2 [unord.multimap]
+            23.5.2.1 [unord.multimap.cnstr]
+            23.5.2.2 [unord.multimap.swap]
+        23.5.3 [unord.set]
+            23.5.3.1 [unord.set.cnstr]
+            23.5.3.2 [unord.set.swap]
+        23.5.4 [unord.multiset]
+            23.5.4.1 [unord.multiset.cnstr]
+            23.5.4.2 [unord.multiset.swap]
+24 [iterators]
+    24.1 [iterators.general]
+    24.2 [iterator.concepts]
+        24.2.1 [iterator.iterators]
+        24.2.2 [input.iterators]
+        24.2.3 [output.iterators]
+        24.2.4 [forward.iterators]
+        24.2.5 [bidirectional.iterators]
+        24.2.6 [random.access.iterators]
+        24.2.7 [shuffle.iterators]
+        24.2.8 [iterator.concepts.range]
+    24.3 [iterator.syn]
+    24.4 [iterator.operations]
+    24.5 [predef.iterators]
+        24.5.1 [reverse.iterators]
+            24.5.1.1 [reverse.iterator]
+            24.5.1.2 [reverse.iter.ops]
+                24.5.1.2.1 [reverse.iter.cons]
+                24.5.1.2.2 [reverse.iter.op=]
+                24.5.1.2.3 [reverse.iter.conv]
+                24.5.1.2.4 [reverse.iter.op.star]
+                24.5.1.2.5 [reverse.iter.opref]
+                24.5.1.2.6 [reverse.iter.op++]
+                24.5.1.2.7 [reverse.iter.op--]
+                24.5.1.2.8 [reverse.iter.op+]
+                24.5.1.2.9 [reverse.iter.op+=]
+                24.5.1.2.10 [reverse.iter.op-]
+                24.5.1.2.11 [reverse.iter.op-=]
+                24.5.1.2.12 [reverse.iter.opindex]
+                24.5.1.2.13 [reverse.iter.op==]
+                24.5.1.2.14 [reverse.iter.op&lt;]
+                24.5.1.2.15 [reverse.iter.op!=]
+                24.5.1.2.16 [reverse.iter.op&gt;]
+                24.5.1.2.17 [reverse.iter.op&gt;=]
+                24.5.1.2.18 [reverse.iter.op&lt;=]
+                24.5.1.2.19 [reverse.iter.opdiff]
+                24.5.1.2.20 [reverse.iter.opsum]
+            24.5.1.3 [reverse.iter.maps]
+        24.5.2 [move.iterators]
+            24.5.2.1 [move.iterator]
+            24.5.2.2 [move.iter.ops]
+                24.5.2.2.1 [move.iter.op.const]
+                24.5.2.2.2 [move.iter.op=]
+                24.5.2.2.3 [move.iter.op.conv]
+                24.5.2.2.4 [move.iter.op.star]
+                24.5.2.2.5 [move.iter.op.ref]
+                24.5.2.2.6 [move.iter.op.incr]
+                24.5.2.2.7 [move.iter.op.decr]
+                24.5.2.2.8 [move.iter.op.+]
+                24.5.2.2.9 [move.iter.op.+=]
+                24.5.2.2.10 [move.iter.op.-]
+                24.5.2.2.11 [move.iter.op.-=]
+                24.5.2.2.12 [move.iter.op.index]
+                24.5.2.2.13 [move.iter.op.comp]
+                24.5.2.2.14 [move.iter.nonmember]
+                24.5.2.2.15 [move.iter.maps]
+    24.6 [stream.iterators]
+        24.6.1 [istream.iterator]
+            24.6.1.1 [istream.iterator.cons]
+            24.6.1.2 [istream.iterator.ops]
+        24.6.2 [ostream.iterator]
+            24.6.2.1 [ostream.iterator.cons.des]
+            24.6.2.2 [ostream.iterator.ops]
+        24.6.3 [istreambuf.iterator]
+            24.6.3.1 [istreambuf.iterator::proxy]
+            24.6.3.2 [istreambuf.iterator.cons]
+            24.6.3.3 [istreambuf.iterator::op*]
+            24.6.3.4 [istreambuf.iterator::op++]
+            24.6.3.5 [istreambuf.iterator::equal]
+            24.6.3.6 [istreambuf.iterator::op==]
+            24.6.3.7 [istreambuf.iterator::op!=]
+        24.6.4 [ostreambuf.iterator]
+            24.6.4.1 [ostreambuf.iter.cons]
+            24.6.4.2 [ostreambuf.iter.ops]
+    24.7 [insert.iterators]
+        24.7.1 [back.insert.iterator]
+        24.7.2 [back.insert.iter.ops]
+            24.7.2.1 [back.insert.iter.cons]
+            24.7.2.2 [back.insert.iter.op=]
+            24.7.2.3 [back.insert.iter.op*]
+            24.7.2.4 [back.insert.iter.op++]
+            24.7.2.5 [back.inserter]
+            24.7.2.6 [back.insert.iter.maps]
+        24.7.3 [front.insert.iterator]
+        24.7.4 [front.insert.iter.ops]
+            24.7.4.1 [front.insert.iter.cons]
+            24.7.4.2 [front.insert.iter.op=]
+            24.7.4.3 [front.insert.iter.op*]
+            24.7.4.4 [front.insert.iter.op++]
+            24.7.4.5 [front.inserter]
+            24.7.4.6 [front.insert.iter.maps]
+        24.7.5 [insert.iterator]
+        24.7.6 [insert.iter.ops]
+            24.7.6.1 [insert.iter.cons]
+            24.7.6.2 [insert.iter.op=]
+            24.7.6.3 [insert.iter.op*]
+            24.7.6.4 [insert.iter.op++]
+            24.7.6.5 [inserter]
+            24.7.6.6 [insert.iter.maps]
+25 [algorithms]
+    25.1 [algorithms.general]
+    25.2 [algorithms.syn]
+    25.3 [alg.nonmodifying]
+        25.3.1 [alg.all_of]
+        25.3.2 [alg.any_of]
+        25.3.3 [alg.none_of]
+        25.3.4 [alg.foreach]
+        25.3.5 [alg.find]
+        25.3.6 [alg.find.end]
+        25.3.7 [alg.find.first.of]
+        25.3.8 [alg.adjacent.find]
+        25.3.9 [alg.count]
+        25.3.10 [mismatch]
+        25.3.11 [alg.equal]
+        25.3.12 [alg.search]
+    25.4 [alg.modifying.operations]
+        25.4.1 [alg.copy]
+        25.4.2 [alg.move]
+        25.4.3 [alg.swap]
+        25.4.4 [alg.transform]
+        25.4.5 [alg.replace]
+        25.4.6 [alg.fill]
+        25.4.7 [alg.generate]
+        25.4.8 [alg.remove]
+        25.4.9 [alg.unique]
+        25.4.10 [alg.reverse]
+        25.4.11 [alg.rotate]
+        25.4.12 [alg.random.shuffle]
+        25.4.13 [alg.partitions]
+    25.5 [alg.sorting]
+        25.5.1 [alg.sort]
+            25.5.1.1 [sort]
+            25.5.1.2 [stable.sort]
+            25.5.1.3 [partial.sort]
+            25.5.1.4 [partial.sort.copy]
+            25.5.1.5 [is.sorted]
+        25.5.2 [alg.nth.element]
+        25.5.3 [alg.binary.search]
+            25.5.3.1 [lower.bound]
+            25.5.3.2 [upper.bound]
+            25.5.3.3 [equal.range]
+            25.5.3.4 [binary.search]
+        25.5.4 [alg.merge]
+        25.5.5 [alg.set.operations]
+            25.5.5.1 [includes]
+            25.5.5.2 [set.union]
+            25.5.5.3 [set.intersection]
+            25.5.5.4 [set.difference]
+            25.5.5.5 [set.symmetric.difference]
+        25.5.6 [alg.heap.operations]
+            25.5.6.1 [push.heap]
+            25.5.6.2 [pop.heap]
+            25.5.6.3 [make.heap]
+            25.5.6.4 [sort.heap]
+            25.5.6.5 [is.heap]
+        25.5.7 [alg.min.max]
+        25.5.8 [alg.lex.comparison]
+        25.5.9 [alg.permutation.generators]
+    25.6 [alg.c.library]
+26 [numerics]
+    26.1 [numerics.general]
+    26.2 [numeric.requirements]
+    26.3 [cfenv]
+        26.3.1 [cfenv.syn]
+        26.3.2 [fenv]
+    26.4 [complex.numbers]
+        26.4.1 [complex.syn]
+        26.4.2 [complex]
+        26.4.3 [complex.special]
+        26.4.4 [complex.members]
+        26.4.5 [complex.member.ops]
+        26.4.6 [complex.ops]
+        26.4.7 [complex.value.ops]
+        26.4.8 [complex.transcendentals]
+        26.4.9 [cmplx.over]
+        26.4.10 [ccmplx]
+        26.4.11 [cmplxh]
+    26.5 [rand]
+        26.5.1 [rand.synopsis]
+        26.5.2 [rand.concept]
+            26.5.2.1 [rand.concept.seedseq]
+            26.5.2.2 [rand.concept.urng]
+            26.5.2.3 [rand.concept.eng]
+            26.5.2.4 [rand.concept.adapt]
+            26.5.2.5 [rand.concept.dist]
+        26.5.3 [rand.eng]
+            26.5.3.1 [rand.eng.lcong]
+            26.5.3.2 [rand.eng.mers]
+            26.5.3.3 [rand.eng.sub]
+        26.5.4 [rand.adapt]
+            26.5.4.1 [rand.adapt.disc]
+            26.5.4.2 [rand.adapt.ibits]
+            26.5.4.3 [rand.adapt.shuf]
+        26.5.5 [rand.predef]
+        26.5.6 [rand.device]
+        26.5.7 [rand.util]
+            26.5.7.1 [rand.util.seedseq]
+            26.5.7.2 [rand.util.canonical]
+        26.5.8 [rand.dist]
+            26.5.8.1 [rand.dist.uni]
+                26.5.8.1.1 [rand.dist.uni.int]
+                26.5.8.1.2 [rand.dist.uni.real]
+            26.5.8.2 [rand.dist.bern]
+                26.5.8.2.1 [rand.dist.bern.bernoulli]
+                26.5.8.2.2 [rand.dist.bern.bin]
+                26.5.8.2.3 [rand.dist.bern.geo]
+                26.5.8.2.4 [rand.dist.bern.negbin]
+            26.5.8.3 [rand.dist.pois]
+                26.5.8.3.1 [rand.dist.pois.poisson]
+                26.5.8.3.2 [rand.dist.pois.exp]
+                26.5.8.3.3 [rand.dist.pois.gamma]
+                26.5.8.3.4 [rand.dist.pois.weibull]
+                26.5.8.3.5 [rand.dist.pois.extreme]
+            26.5.8.4 [rand.dist.norm]
+                26.5.8.4.1 [rand.dist.norm.normal]
+                26.5.8.4.2 [rand.dist.norm.lognormal]
+                26.5.8.4.3 [rand.dist.norm.chisq]
+                26.5.8.4.4 [rand.dist.norm.cauchy]
+                26.5.8.4.5 [rand.dist.norm.f]
+                26.5.8.4.6 [rand.dist.norm.t]
+            26.5.8.5 [rand.dist.samp]
+                26.5.8.5.1 [rand.dist.samp.discrete]
+                26.5.8.5.2 [rand.dist.samp.pconst]
+                26.5.8.5.3 [rand.dist.samp.plinear]
+    26.6 [numarray]
+        26.6.1 [valarray.syn]
+        26.6.2 [template.valarray]
+            26.6.2.1 [valarray.cons]
+            26.6.2.2 [valarray.assign]
+            26.6.2.3 [valarray.access]
+            26.6.2.4 [valarray.sub]
+            26.6.2.5 [valarray.unary]
+            26.6.2.6 [valarray.cassign]
+            26.6.2.7 [valarray.members]
+        26.6.3 [valarray.nonmembers]
+            26.6.3.1 [valarray.binary]
+            26.6.3.2 [valarray.comparison]
+            26.6.3.3 [valarray.transcend]
+            26.6.3.4 [valarray.special]
+        26.6.4 [class.slice]
+            26.6.4.1 [cons.slice]
+            26.6.4.2 [slice.access]
+        26.6.5 [template.slice.array]
+            26.6.5.1 [slice.arr.assign]
+            26.6.5.2 [slice.arr.comp.assign]
+            26.6.5.3 [slice.arr.fill]
+        26.6.6 [class.gslice]
+            26.6.6.1 [gslice.cons]
+            26.6.6.2 [gslice.access]
+        26.6.7 [template.gslice.array]
+            26.6.7.1 [gslice.array.assign]
+            26.6.7.2 [gslice.array.comp.assign]
+            26.6.7.3 [gslice.array.fill]
+        26.6.8 [template.mask.array]
+            26.6.8.1 [mask.array.assign]
+            26.6.8.2 [mask.array.comp.assign]
+            26.6.8.3 [mask.array.fill]
+        26.6.9 [template.indirect.array]
+            26.6.9.1 [indirect.array.assign]
+            26.6.9.2 [indirect.array.comp.assign]
+            26.6.9.3 [indirect.array.fill]
+            26.6.9.4 [valarray.concepts]
+    26.7 [numeric.ops]
+        26.7.1 [accumulate]
+        26.7.2 [inner.product]
+        26.7.3 [partial.sum]
+        26.7.4 [adjacent.difference]
+        26.7.5 [numeric.iota]
+    26.8 [c.math]
+27 [input.output]
+    27.1 [input.output.general]
+    27.2 [iostreams.requirements]
+        27.2.1 [iostream.limits.imbue]
+        27.2.2 [iostreams.limits.pos]
+        27.2.3 [iostreams.threadsafety]
+    27.3 [iostream.forward]
+    27.4 [iostream.objects]
+        27.4.1 [narrow.stream.objects]
+        27.4.2 [wide.stream.objects]
+    27.5 [iostreams.base]
+        27.5.1 [stream.types]
+        27.5.2 [ios.base]
+            27.5.2.1 [ios.types]
+                27.5.2.1.1 [ios::failure]
+                27.5.2.1.2 [ios::fmtflags]
+                27.5.2.1.3 [ios::iostate]
+                27.5.2.1.4 [ios::openmode]
+                27.5.2.1.5 [ios::seekdir]
+                27.5.2.1.6 [ios::Init]
+            27.5.2.2 [fmtflags.state]
+            27.5.2.3 [ios.base.locales]
+            27.5.2.4 [ios.members.static]
+            27.5.2.5 [ios.base.storage]
+            27.5.2.6 [ios.base.callback]
+            27.5.2.7 [ios.base.cons]
+        27.5.3 [fpos]
+            27.5.3.1 [fpos.members]
+            27.5.3.2 [fpos.operations]
+        27.5.4 [ios]
+            27.5.4.1 [basic.ios.cons]
+            27.5.4.2 [basic.ios.members]
+            27.5.4.3 [iostate.flags]
+        27.5.5 [std.ios.manip]
+            27.5.5.1 [fmtflags.manip]
+            27.5.5.2 [adjustfield.manip]
+            27.5.5.3 [basefield.manip]
+            27.5.5.4 [floatfield.manip]
+            27.5.5.5 [error.reporting]
+    27.6 [stream.buffers]
+        27.6.1 [streambuf.reqts]
+        27.6.2 [streambuf]
+            27.6.2.1 [streambuf.cons]
+            27.6.2.2 [streambuf.members]
+                27.6.2.2.1 [streambuf.locales]
+                27.6.2.2.2 [streambuf.buffer]
+                27.6.2.2.3 [streambuf.pub.get]
+                27.6.2.2.4 [streambuf.pub.pback]
+                27.6.2.2.5 [streambuf.pub.put]
+            27.6.2.3 [streambuf.protected]
+                27.6.2.3.1 [streambuf.assign]
+                27.6.2.3.2 [streambuf.get.area]
+                27.6.2.3.3 [streambuf.put.area]
+            27.6.2.4 [streambuf.virtuals]
+                27.6.2.4.1 [streambuf.virt.locales]
+                27.6.2.4.2 [streambuf.virt.buffer]
+                27.6.2.4.3 [streambuf.virt.get]
+                27.6.2.4.4 [streambuf.virt.pback]
+                27.6.2.4.5 [streambuf.virt.put]
+    27.7 [iostream.format]
+        27.7.1 [input.streams]
+            27.7.1.1 [istream]
+                27.7.1.1.1 [istream.cons]
+                27.7.1.1.2 [istream.assign]
+                27.7.1.1.3 [istream::sentry]
+            27.7.1.2 [istream.formatted]
+                27.7.1.2.1 [istream.formatted.reqmts]
+                27.7.1.2.2 [istream.formatted.arithmetic]
+                27.7.1.2.3 [istream::extractors]
+            27.7.1.3 [istream.unformatted]
+            27.7.1.4 [istream.manip]
+            27.7.1.5 [iostreamclass]
+                27.7.1.5.1 [iostream.cons]
+                27.7.1.5.2 [iostream.dest]
+                27.7.1.5.3 [iostream.assign]
+            27.7.1.6 [istream.rvalue]
+        27.7.2 [output.streams]
+            27.7.2.1 [ostream]
+            27.7.2.2 [ostream.cons]
+            27.7.2.3 [ostream.assign]
+            27.7.2.4 [ostream::sentry]
+            27.7.2.5 [ostream.seeks]
+            27.7.2.6 [ostream.formatted]
+                27.7.2.6.1 [ostream.formatted.reqmts]
+                27.7.2.6.2 [ostream.inserters.arithmetic]
+                27.7.2.6.3 [ostream.inserters]
+                27.7.2.6.4 [ostream.inserters.character]
+            27.7.2.7 [ostream.unformatted]
+            27.7.2.8 [ostream.manip]
+            27.7.2.9 [ostream.rvalue]
+        27.7.3 [std.manip]
+        27.7.4 [ext.manip]
+    27.8 [string.streams]
+        27.8.1 [stringbuf]
+            27.8.1.1 [stringbuf.cons]
+            27.8.1.2 [stringbuf.assign]
+            27.8.1.3 [stringbuf.members]
+            27.8.1.4 [stringbuf.virtuals]
+        27.8.2 [istringstream]
+            27.8.2.1 [istringstream.cons]
+            27.8.2.2 [istringstream.assign]
+            27.8.2.3 [istringstream.members]
+        27.8.3 [ostringstream]
+            27.8.3.1 [ostringstream.cons]
+            27.8.3.2 [ostringstream.assign]
+            27.8.3.3 [ostringstream.members]
+        27.8.4 [stringstream]
+        27.8.5 [stringstream.cons]
+            27.8.5.1 [stringstream.assign]
+        27.8.6 [stringstream.members]
+    27.9 [file.streams]
+        27.9.1 [fstreams]
+            27.9.1.1 [filebuf]
+            27.9.1.2 [filebuf.cons]
+            27.9.1.3 [filebuf.assign]
+            27.9.1.4 [filebuf.members]
+            27.9.1.5 [filebuf.virtuals]
+            27.9.1.6 [ifstream]
+            27.9.1.7 [ifstream.cons]
+            27.9.1.8 [ifstream.assign]
+            27.9.1.9 [ifstream.members]
+            27.9.1.10 [ofstream]
+            27.9.1.11 [ofstream.cons]
+            27.9.1.12 [ofstream.assign]
+            27.9.1.13 [ofstream.members]
+            27.9.1.14 [fstream]
+            27.9.1.15 [fstream.cons]
+            27.9.1.16 [fstream.assign]
+            27.9.1.17 [fstream.members]
+        27.9.2 [c.files]
+28 [re]
+    28.1 [re.general]
+    28.2 [re.def]
+        28.2.1 [defns.regex.collating.element]
+        28.2.2 [defns.regex.finite.state.machine]
+        28.2.3 [defns.regex.format.specifier]
+        28.2.4 [defns.regex.matched]
+        28.2.5 [defns.regex.primary.equivalence.class]
+        28.2.6 [defns.regex.regular.expression]
+        28.2.7 [defns.regex.subexpression]
+    28.3 [re.req]
+    28.4 [re.syn]
+    28.5 [re.const]
+        28.5.1 [re.synopt]
+        28.5.2 [re.matchflag]
+        28.5.3 [re.err]
+    28.6 [re.badexp]
+    28.7 [re.traits]
+    28.8 [re.regex]
+        28.8.1 [re.regex.const]
+        28.8.2 [re.regex.construct]
+        28.8.3 [re.regex.assign]
+        28.8.4 [re.regex.operations]
+        28.8.5 [re.regex.locale]
+        28.8.6 [re.regex.swap]
+        28.8.7 [re.regex.nonmemb]
+            28.8.7.1 [re.regex.nmswap]
+    28.9 [re.submatch]
+        28.9.1 [re.submatch.members]
+        28.9.2 [re.submatch.op]
+        28.9.3 [re.submatch.concepts]
+    28.10 [re.results]
+        28.10.1 [re.results.const]
+        28.10.2 [re.results.size]
+        28.10.3 [re.results.acc]
+        28.10.4 [re.results.form]
+        28.10.5 [re.results.all]
+        28.10.6 [re.results.swap]
+        28.10.7 [re.results.nonmember]
+    28.11 [re.alg]
+        28.11.1 [re.except]
+        28.11.2 [re.alg.match]
+        28.11.3 [re.alg.search]
+        28.11.4 [re.alg.replace]
+    28.12 [re.iter]
+        28.12.1 [re.regiter]
+            28.12.1.1 [re.regiter.cnstr]
+            28.12.1.2 [re.regiter.comp]
+            28.12.1.3 [re.regiter.deref]
+            28.12.1.4 [re.regiter.incr]
+        28.12.2 [re.tokiter]
+            28.12.2.1 [re.tokiter.cnstr]
+            28.12.2.2 [re.tokiter.comp]
+            28.12.2.3 [re.tokiter.deref]
+            28.12.2.4 [re.tokiter.incr]
+    28.13 [re.grammar]
+29 [atomics]
+    29.1 [atomics.general]
+    29.2 [atomics.syn]
+    29.3 [atomics.order]
+    29.4 [atomics.lockfree]
+    29.5 [atomics.types]
+        29.5.1 [atomics.types.integral]
+        29.5.2 [atomics.types.address]
+        29.5.3 [atomics.types.generic]
+    29.6 [atomics.types.operations]
+    29.7 [atomics.flag]
+    29.8 [atomics.fences]
+30 [thread]
+    30.1 [thread.general]
+    30.2 [thread.req]
+        30.2.1 [thread.req.paramname]
+        30.2.2 [thread.req.exception]
+        30.2.3 [thread.req.native]
+        30.2.4 [thread.req.timing]
+    30.3 [thread.threads]
+        30.3.1 [thread.thread.class]
+            30.3.1.1 [thread.thread.id]
+            30.3.1.2 [thread.thread.constr]
+            30.3.1.3 [thread.thread.destr]
+            30.3.1.4 [thread.thread.assign]
+            30.3.1.5 [thread.thread.member]
+            30.3.1.6 [thread.thread.static]
+            30.3.1.7 [thread.thread.algorithm]
+        30.3.2 [thread.thread.this]
+    30.4 [thread.mutex]
+        30.4.1 [thread.mutex.requirements]
+            30.4.1.1 [thread.mutex.class]
+            30.4.1.2 [thread.mutex.recursive]
+        30.4.2 [thread.timedmutex.requirements]
+            30.4.2.1 [thread.timedmutex.class]
+            30.4.2.2 [thread.timedmutex.recursive]
+        30.4.3 [thread.lock]
+            30.4.3.1 [thread.lock.guard]
+            30.4.3.2 [thread.lock.unique]
+                30.4.3.2.1 [thread.lock.unique.cons]
+                30.4.3.2.2 [thread.lock.unique.locking]
+                30.4.3.2.3 [thread.lock.unique.mod]
+                30.4.3.2.4 [thread.lock.unique.obs]
+        30.4.4 [thread.lock.algorithm]
+        30.4.5 [thread.once]
+            30.4.5.1 [thread.once.onceflag]
+            30.4.5.2 [thread.once.callonce]
+    30.5 [thread.condition]
+        30.5.1 [thread.condition.condvar]
+        30.5.2 [thread.condition.condvarany]
+    30.6 [futures]
+        30.6.1 [futures.overview]
+        30.6.2 [futures.errors]
+        30.6.3 [futures.future_error]
+        30.6.4 [futures.promise]
+        30.6.5 [futures.unique_future]
+        30.6.6 [future.shared_future]
+        30.6.7 [futures.task]
+A [gram]
+    A.1 [gram.key]
+    A.2 [gram.lex]
+    A.3 [gram.basic]
+    A.4 [gram.expr]
+    A.5 [gram.stmt]
+    A.6 [gram.dcl]
+    A.7 [gram.decl]
+    A.8 [gram.class]
+    A.9 [gram.derived]
+    A.10 [gram.special]
+    A.11 [gram.over]
+    A.12 [gram.temp]
+    A.13 [gram.except]
+    A.14 [gram.cpp]
+B [implimits]
+C [diff]
+    C.1 [diff.iso]
+        C.1.1 [diff.lex]
+        C.1.2 [diff.basic]
+        C.1.3 [diff.expr]
+        C.1.4 [diff.stat]
+        C.1.5 [diff.dcl]
+        C.1.6 [diff.decl]
+        C.1.7 [diff.class]
+        C.1.8 [diff.special]
+        C.1.9 [diff.cpp]
+    C.2 [diff.library]
+        C.2.1 [diff.mods.to.headers]
+        C.2.2 [diff.mods.to.definitions]
+            C.2.2.1 [diff.char16]
+            C.2.2.2 [diff.wchar.t]
+            C.2.2.3 [diff.header.iso646.h]
+            C.2.2.4 [diff.null]
+        C.2.3 [diff.mods.to.declarations]
+        C.2.4 [diff.mods.to.behavior]
+            C.2.4.1 [diff.offsetof]
+            C.2.4.2 [diff.malloc]
+D [depr]
+    D.1 [depr.incr.bool]
+    D.2 [depr.static]
+    D.3 [depr.access.dcl]
+    D.4 [depr.string]
+    D.5 [depr.c.headers]
+    D.6 [depr.ios.members]
+    D.7 [depr.str.strstreams]
+        D.7.1 [depr.strstreambuf]
+            D.7.1.1 [depr.strstreambuf.cons]
+            D.7.1.2 [depr.strstreambuf.members]
+            D.7.1.3 [depr.strstreambuf.virtuals]
+        D.7.2 [depr.istrstream]
+            D.7.2.1 [depr.istrstream.cons]
+            D.7.2.2 [depr.istrstream.members]
+        D.7.3 [depr.ostrstream]
+            D.7.3.1 [depr.ostrstream.cons]
+            D.7.3.2 [depr.ostrstream.members]
+        D.7.4 [depr.strstream]
+            D.7.4.1 [depr.strstream.cons]
+            D.7.4.2 [depr.strstream.dest]
+            D.7.4.3 [depr.strstream.oper]
+    D.8 [depr.lib.binders]
+        D.8.1 [depr.lib.binder.1st]
+        D.8.2 [depr.lib.bind.1st]
+        D.8.3 [depr.lib.binder.2nd]
+        D.8.4 [depr.lib.bind.2nd]
+    D.9 [depr.auto.ptr]
+        D.9.1 [auto.ptr]
+            D.9.1.1 [auto.ptr.cons]
+            D.9.1.2 [auto.ptr.members]
+            D.9.1.3 [auto.ptr.conv]
+    D.10 [depr.lib.iterator.primitives]
+        D.10.1 [iterator.traits]
+        D.10.2 [iterator.basic]
+        D.10.3 [std.iterator.tags]
+        D.10.4 [iterator.backward]
+E [xref]
+
+TR1 1 [tr.intro]
+    TR1 1.1 [tr.description]
+    TR1 1.2 [tr.intro.ext]
+    TR1 1.3 [tr.intro.namespaces]
+TR1 2 [tr.util]
+    TR1 2.1 [tr.util.refwrap]
+        TR1 2.1.1 [tr.util.refwrp.synopsis]
+        TR1 2.1.2 [tr.util.refwrp.refwrp]
+            TR1 2.1.2.1 [tr.util.refwrp.const]
+            TR1 2.1.2.2 [tr.util.refwrp.assign]
+            TR1 2.1.2.3 [tr.util.refwrp.access]
+            TR1 2.1.2.4 [tr.util.refwrp.invoke]
+            TR1 2.1.2.5 [tr.util.refwrp.helpers]
+    TR1 2.2 [tr.util.smartptr]
+        TR1 2.2.1 [tr.util.smartptr.synopsis]
+        TR1 2.2.2 [tr.util.smartptr.weakptr]
+        TR1 2.2.3 [tr.util.smartptr.shared]
+            TR1 2.2.3.1 [tr.util.smartptr.shared.const]
+            TR1 2.2.3.2 [tr.util.smartptr.shared.dest]
+            TR1 2.2.3.3 [tr.util.smartptr.shared.assign]
+            TR1 2.2.3.4 [tr.util.smartptr.shared.mod]
+            TR1 2.2.3.5 [tr.util.smartptr.shared.obs]
+            TR1 2.2.3.6 [tr.util.smartptr.shared.cmp]
+            TR1 2.2.3.7 [tr.util.smartptr.shared.io]
+            TR1 2.2.3.8 [tr.util.smartptr.shared.spec]
+            TR1 2.2.3.9 [tr.util.smartptr.shared.cast]
+            TR1 2.2.3.10 [tr.util.smartptr.getdeleter]
+        TR1 2.2.4 [tr.util.smartptr.weak]
+            TR1 2.2.4.1 [tr.util.smartptr.weak.const]
+            TR1 2.2.4.2 [tr.util.smartptr.weak.dest]
+            TR1 2.2.4.3 [tr.util.smartptr.weak.assign]
+            TR1 2.2.4.4 [tr.util.smartptr.weak.mod]
+            TR1 2.2.4.5 [tr.util.smartptr.weak.obs]
+            TR1 2.2.4.6 [tr.util.smartptr.weak.cmp]
+            TR1 2.2.4.7 [tr.util.smartptr.weak.spec]
+        TR1 2.2.5 [tr.util.smartptr.enab]
+TR1 3 [tr.func]
+    TR1 3.1 [tr.func.def]
+    TR1 3.2 [tr.func.syn]
+    TR1 3.3 [tr.func.require]
+    TR1 3.4 [tr.func.ret]
+    TR1 3.5 [tr.func.memfn]
+    TR1 3.6 [tr.func.bind]
+        TR1 3.6.1 [tr.func.bind.isbind]
+        TR1 3.6.2 [tr.func.bind.isplace]
+        TR1 3.6.3 [tr.func.bind.bind]
+        TR1 3.6.4 [tr.func.bind.place]
+    TR1 3.7 [tr.func.wrap]
+        TR1 3.7.1 [tr.func.wrap.badcall]
+            TR1 3.7.1.1 [tr.func.wrap.badcall.const]
+        TR1 3.7.2 [tr.func.wrap.func]
+            TR1 3.7.2.1 [tr.func.wrap.func.con]
+            TR1 3.7.2.2 [tr.func.wrap.func.mod]
+            TR1 3.7.2.3 [tr.func.wrap.func.cap]
+            TR1 3.7.2.4 [tr.func.wrap.func.inv]
+            TR1 3.7.2.5 [tr.func.wrap.func.targ]
+            TR1 3.7.2.6 [tr.func.wrap.func.undef]
+            TR1 3.7.2.7 [tr.func.wrap.func.nullptr]
+            TR1 3.7.2.8 [tr.func.wrap.func.alg]
+TR1 4 [tr.meta]
+    TR1 4.1 [tr.meta.rqmts]
+    TR1 4.2 [tr.meta.type.synop]
+    TR1 4.3 [tr.meta.help]
+    TR1 4.4 [tr.meta.requirements]
+    TR1 4.5 [tr.meta.unary]
+        TR1 4.5.1 [tr.meta.unary.cat]
+        TR1 4.5.2 [tr.meta.unary.comp]
+        TR1 4.5.3 [tr.meta.unary.prop]
+    TR1 4.6 [tr.meta.rel]
+    TR1 4.7 [tr.meta.trans]
+        TR1 4.7.1 [tr.meta.trans.cv]
+        TR1 4.7.2 [tr.meta.trans.ref]
+        TR1 4.7.3 [tr.meta.trans.arr]
+        TR1 4.7.4 [tr.meta.trans.ptr]
+    TR1 4.8 [tr.meta.trans.other]
+    TR1 4.9 [tr.meta.req]
+TR1 5 [tr.num]
+    TR1 5.1 [tr.rand]
+        TR1 5.1.1 [tr.rand.req]
+        TR1 5.1.2 [tr.rand.synopsis]
+        TR1 5.1.3 [tr.rand.var]
+        TR1 5.1.4 [tr.rand.eng]
+            TR1 5.1.4.1 [tr.rand.eng.lcong]
+            TR1 5.1.4.2 [tr.rand.eng.mers]
+            TR1 5.1.4.3 [tr.rand.eng.sub]
+            TR1 5.1.4.4 [tr.rand.eng.sub1]
+            TR1 5.1.4.5 [tr.rand.eng.disc]
+            TR1 5.1.4.6 [tr.rand.eng.xor]
+        TR1 5.1.5 [tr.rand.predef]
+        TR1 5.1.6 [tr.rand.device]
+        TR1 5.1.7 [tr.rand.dist]
+            TR1 5.1.7.1 [tr.rand.dist.iunif]
+            TR1 5.1.7.2 [tr.rand.dist.bern]
+            TR1 5.1.7.3 [tr.rand.dist.geom]
+            TR1 5.1.7.4 [tr.rand.dist.pois]
+            TR1 5.1.7.5 [tr.rand.dist.bin]
+            TR1 5.1.7.6 [tr.rand.dist.runif]
+            TR1 5.1.7.7 [tr.rand.dist.exp]
+            TR1 5.1.7.8 [tr.rand.dist.norm]
+            TR1 5.1.7.9 [tr.rand.dist.gamma]
+    TR1 5.2 [tr.num.sf]
+        TR1 5.2.1 [tr.num.sf.cmath]
+            TR1 5.2.1.1 [tr.num.sf.Lnm]
+            TR1 5.2.1.2 [tr.num.sf.Plm]
+            TR1 5.2.1.3 [tr.num.sf.beta]
+            TR1 5.2.1.4 [tr.num.sf.ellK]
+            TR1 5.2.1.5 [tr.num.sf.ellEx]
+            TR1 5.2.1.6 [tr.num.sf.ellPx]
+            TR1 5.2.1.7 [tr.num.sf.conhyp]
+            TR1 5.2.1.8 [tr.num.sf.I]
+            TR1 5.2.1.9 [tr.num.sf.J]
+            TR1 5.2.1.10 [tr.num.sf.K]
+            TR1 5.2.1.11 [tr.num.sf.N]
+            TR1 5.2.1.12 [tr.num.sf.ellF]
+            TR1 5.2.1.13 [tr.num.sf.ellE]
+            TR1 5.2.1.14 [tr.num.sf.ellP]
+            TR1 5.2.1.15 [tr.num.sf.ei]
+            TR1 5.2.1.16 [tr.num.sf.Hn]
+            TR1 5.2.1.17 [tr.num.sf.hyper]
+            TR1 5.2.1.18 [tr.num.sf.Ln]
+            TR1 5.2.1.19 [tr.num.sf.Pl]
+            TR1 5.2.1.20 [tr.num.sf.riemannzeta]
+            TR1 5.2.1.21 [tr.num.sf.j]
+            TR1 5.2.1.22 [tr.num.sf.Ylm]
+            TR1 5.2.1.23 [tr.num.sf.n]
+        TR1 5.2.2 [tr.num.sf.mathh]
+TR1 6 [tr.cont]
+    TR1 6.1 [tr.tuple]
+        TR1 6.1.1 [tr.tuple.synopsis]
+        TR1 6.1.2 [tr.tuple.synopsis.pair]
+        TR1 6.1.3 [tr.tuple.tuple]
+            TR1 6.1.3.1 [tr.tuple.cnstr]
+            TR1 6.1.3.2 [tr.tuple.creation]
+            TR1 6.1.3.3 [tr.tuple.helper]
+            TR1 6.1.3.4 [tr.tuple.elem]
+            TR1 6.1.3.5 [tr.tuple.rel]
+        TR1 6.1.4 [tr.tuple.pairs]
+    TR1 6.2 [tr.array]
+        TR1 6.2.1 [tr.array.syn]
+        TR1 6.2.2 [tr.array.array]
+            TR1 6.2.2.1 [tr.array.cons]
+            TR1 6.2.2.2 [tr.array.special]
+            TR1 6.2.2.3 [tr.array.size]
+            TR1 6.2.2.4 [tr.array.zero]
+            TR1 6.2.2.5 [tr.array.tuple]
+    TR1 6.3 [tr.hash]
+        TR1 6.3.1 [tr.unord.req]
+            TR1 6.3.1.1 [tr.unord.req.except]
+        TR1 6.3.2 [tr.unord.fun.syn]
+        TR1 6.3.3 [tr.unord.hash]
+        TR1 6.3.4 [tr.unord.unord]
+            TR1 6.3.4.1 [tr.unord.syn.set]
+            TR1 6.3.4.2 [tr.unord.syn.map]
+            TR1 6.3.4.3 [tr.unord.set]
+                TR1 6.3.4.3.1 [tr.unord.set.cnstr]
+                TR1 6.3.4.3.2 [tr.unord.set.swap]
+            TR1 6.3.4.4 [tr.unord.map]
+                TR1 6.3.4.4.1 [tr.unord.map.cnstr]
+                TR1 6.3.4.4.2 [tr.unord.map.elem]
+                TR1 6.3.4.4.3 [tr.unord.map.swap]
+            TR1 6.3.4.5 [tr.unord.multiset]
+                TR1 6.3.4.5.1 [tr.unord.multiset.cnstr]
+                TR1 6.3.4.5.2 [tr.unord.multiset.swap]
+            TR1 6.3.4.6 [tr.unord.multimap]
+                TR1 6.3.4.6.1 [tr.unord.multimap.cnstr]
+                TR1 6.3.4.6.2 [tr.unord.multimap.swap]
+TR1 7 [tr.re]
+    TR1 7.1 [tr.re.def]
+    TR1 7.2 [tr.re.req]
+    TR1 7.3 [tr.re.sum]
+    TR1 7.4 [tr.re.syn]
+    TR1 7.5 [tr.re.const]
+        TR1 7.5.1 [tr.re.synopt]
+        TR1 7.5.2 [tr.re.matchflag]
+        TR1 7.5.3 [tr.re.err]
+    TR1 7.6 [tr.re.badexp]
+    TR1 7.7 [tr.re.traits]
+    TR1 7.8 [tr.re.regex]
+        TR1 7.8.1 [tr.re.regex.const]
+        TR1 7.8.2 [tr.re.regex.construct]
+        TR1 7.8.3 [tr.re.regex.assign]
+        TR1 7.8.4 [tr.re.regex.operations]
+        TR1 7.8.5 [tr.re.regex.locale]
+        TR1 7.8.6 [tr.re.regex.swap]
+        TR1 7.8.7 [tr.re.regex.nonmemb]
+            TR1 7.8.7.1 [tr.re.regex.nmswap.]
+    TR1 7.9 [tr.re.submatch]
+        TR1 7.9.1 [tr.re.submatch.members]
+        TR1 7.9.2 [tr.re.submatch.op]
+    TR1 7.10 [tr.re.results]
+        TR1 7.10.1 [tr.re.results.const]
+        TR1 7.10.2 [tr.re.results.size]
+        TR1 7.10.3 [tr.re.results.acc]
+        TR1 7.10.4 [tr.re.results.form]
+        TR1 7.10.5 [tr.re.results.all]
+        TR1 7.10.1 [tr.re.results.swap]
+    TR1 7.11 [tr.re.alg]
+        TR1 7.11.1 [tr.re.except]
+        TR1 7.11.2 [tr.re.alg.match]
+        TR1 7.11.3 [tr.re.alg.search]
+        TR1 7.11.4 [tr.re.alg.replace]
+    TR1 7.12 [tr.re.iter]
+        TR1 7.12.1 [tr.re.regiter]
+            TR1 7.12.1.1 [tr.re.regiter.cnstr]
+            TR1 7.12.1.2 [tr.re.regiter.comp]
+            TR1 7.12.1.3 [tr.re.regiter.deref]
+            TR1 7.12.1.4 [tr.re.regiter.incr]
+        TR1 7.12.2 [tr.re.tokiter]
+            TR1 7.12.2.1 [tr.re.tokiter.cnstr]
+            TR1 7.12.2.2 [tr.re.tokiter.comp]
+            TR1 7.12.2.3 [tr.re.tokiter.deref]
+            TR1 7.12.2.4 [tr.re.tokiter.incr]
+    TR1 7.13 [tr.re.grammar]
+TR1 8 [tr.c99]
+    TR1 8.1 [tr.c99.cmplx]
+        TR1 8.1.1 [tr.c99.cmplx.syn]
+        TR1 8.1.2 [tr.c99.cmplx.acos]
+        TR1 8.1.3 [tr.c99.cmplx.asin]
+        TR1 8.1.4 [tr.c99.cmplx.atan]
+        TR1 8.1.5 [tr.c99.cmplx.acosh]
+        TR1 8.1.6 [tr.c99.cmplx.asinh]
+        TR1 8.1.7 [tr.c99.cmplx.atanh]
+        TR1 8.1.8 [tr.c99.cmplx.fabs]
+        TR1 8.1.9 [tr.c99.cmplx.over]
+    TR1 8.2 [tr.c99.ccmplx]
+    TR1 8.3 [tr.c99.cmplxh]
+    TR1 8.4 [tr.c99.cctype]
+        TR1 8.4.1 [tr.c99.cctype.syn]
+        TR1 8.4.2 [tr.c99.cctype.blank]
+    TR1 8.5 [tr.c99.ctypeh]
+    TR1 8.6 [tr.c99.cfenv]
+        TR1 8.6.1 [tr.c99.cfenv.syn]
+        TR1 8.6.2 [tr.c99.cfenv.def]
+    TR1 8.7 [tr.c99.fenv]
+    TR1 8.8 [tr.c99.cfloat]
+    TR1 8.9 [tr.c99.floath]
+    TR1 8.10 [tr.c99.ios]
+        TR1 8.10.1 [tr.c99.ios.syn]
+        TR1 8.10.2 [tr.c99.ios.hex]
+    TR1 8.11 [tr.c99.cinttypes]
+        TR1 8.11.1 [tr.c99.cinttypes.syn]
+        TR1 8.11.2 [tr.c99.cinttypes.def]
+    TR1 8.12 [tr.c99.inttypesh]
+    TR1 8.13 [tr.c99.climits]
+    TR1 8.14 [tr.c99.limitsh]
+    TR1 8.15 [tr.c99.locale]
+    TR1 8.16 [tr.c99.cmath]
+        TR1 8.16.1 [tr.c99.cmath.syn]
+        TR1 8.16.2 [tr.c99.cmath.def]
+        TR1 8.16.3 [tr.c99.cmath.tmpl]
+        TR1 8.16.4 [tr.c99.cmath.over]
+    TR1 8.17 [tr.c99.mathh]
+    TR1 8.18 [tr.c99.cstdarg]
+    TR1 8.19 [tr.c99.stdargh]
+    TR1 8.20 [tr.c99.cbool]
+    TR1 8.21 [tr.c99.boolh]
+    TR1 8.22 [tr.c99.cstdint]
+        TR1 8.22.1 [tr.c99.cstdint.syn]
+        TR1 8.22.2 [tr.c99.cstdint.def]
+    TR1 8.23 [tr.c99.stdinth]
+    TR1 8.24 [tr.c99.cstdio]
+        TR1 8.24.1 [tr.c99.cstdio.syn]
+        TR1 8.24.2 [tr.c99.cstdio.def]
+        TR1 8.24.3 [tr.c99.cstdio.spec]
+        TR1 8.24.4 [tr.c99.stdioh]
+    TR1 8.25 [tr.c99.cstdlib]
+        TR1 8.25.1 [tr.c99.cstdlib.syn]
+        TR1 8.25.2 [tr.c99.cstdlib.def]
+        TR1 8.25.3 [tr.c99.cstdlib.abs]
+        TR1 8.25.4 [tr.c99.cstdlib.div]
+    TR1 8.26 [tr.c99.stdlibh]
+    TR1 8.27 [tr.c99.ctgmath]
+    TR1 8.28 [tr.c99.tgmathh]
+    TR1 8.29 [tr.c99.ctime]
+    TR1 8.30 [tr.c99.cwchar]
+        TR1 8.30.1 [tr.c99.cwchar.syn]
+        TR1 8.30.2 [tr.c99.cwchar.def]
+        TR1 8.30.3 [tr.c99.cwchar.spec]
+    TR1 8.31 [tr.c99.wcharh]
+    TR1 8.32 [tr.c99.cwctype]
+        TR1 8.32.1 [tr.c99.cwctype.syn]
+        TR1 8.32.2 [tr.c99.cwctype.iswblank]
+    TR1 8.33 [tr.c99.wctypeh]
+TR1 A [tr.limits]
+
+TRDecimal 1 [trdec.intro]
+    TRDecimal 1.1 [trdec.model]
+    TRDecimal 1.2 [trdec.encodings]
+    TRDecimal 1.3 [trdec.refs]
+TRDecimal 2 [trdec.conventions]
+    TRDecimal 2.1 [trdec.relation.intro]
+    TRDecimal 2.2 [trdec.relation.tr1]
+    TRDecimal 2.3 [trdec.categories]
+    TRDecimal 2.4 [trdec.namespace]
+TRDecimal 3 [trdec.types]
+    TRDecimal 3.1 [trdec.types.encodings]
+    TRDecimal 3.2 [trdec.types.types]
+        TRDecimal 3.2.1 [trdec.types.types.synopsis]
+        TRDecimal 3.2.2 [trdec.types.types.decimal32]
+            TRDecimal 3.2.2.1 [trdec.types.types.decimal32.cons]
+            TRDecimal 3.2.2.2 [trdec.types.types.decimal32.conv.float]
+            TRDecimal 3.2.2.3 [trdec.types.types.decimal32.conv.from.int]
+            TRDecimal 3.2.2.4 [trdec.types.types.decimal32.conv.to.int]
+            TRDecimal 3.2.2.5 [trdec.types.types.decimal32.incr]
+            TRDecimal 3.2.2.6 [trdec.types.types.decimal32.comp.ass]
+        TRDecimal 3.2.3 [trdec.types.types.decimal64]
+            TRDecimal 3.2.3.1 [trdec.types.types.decimal64.cons]
+            TRDecimal 3.2.3.2 [trdec.types.types.decimal64.float]
+            TRDecimal 3.2.3.3 [trdec.types.types.decimal64.from.int]
+            TRDecimal 3.2.3.4 [trdec.types.types.decimal64.to.int]
+            TRDecimal 3.2.3.5 [trdec.types.types.decimal64.incr]
+            TRDecimal 3.2.3.6 [trdec.types.types.decimal64.comp.ass]
+        TRDecimal 3.2.4 [trdec.types.types.decimal128]
+            TRDecimal 3.2.4.1 [trdec.types.types.decimal128.cons]
+            TRDecimal 3.2.4.2 [trdec.types.types.decimal128.float]
+            TRDecimal 3.2.4.3 [trdec.types.types.decimal128.from.int]
+            TRDecimal 3.2.4.4 [trdec.types.types.decimal128.to.int]
+            TRDecimal 3.2.4.5 [trdec.types.types.decimal128.incr]
+            TRDecimal 3.2.4.6 [trdec.types.types.decimal128.comp.ass]
+        TRDecimal 3.2.5 [trdec.types.types.init]
+        TRDecimal 3.2.6 [trdec.types.types.conv.float]
+        TRDecimal 3.2.7 [trdec.types.types.unary]
+        TRDecimal 3.2.8 [trdec.types.types.binary]
+        TRDecimal 3.2.9 [trdec.types.types.comp]
+        TRDecimal 3.2.10 [trdec.types.types.input]
+        TRDecimal 3.2.11 [trdec.types.types.output]
+    TRDecimal 3.3 [trdec.types.limits]
+    TRDecimal 3.4 [trdec.types.cdecfloat]
+        TRDecimal 3.4.1 [trdec.types.cdecfloat.synopsis]
+        TRDecimal 3.4.2 [trdec.types.decfloat.h.synopsis]
+        TRDecimal 3.4.3 [trdec.types.cdecfloat.max.value]
+        TRDecimal 3.4.4 [trdec.types.cdecfloat.epsilon]
+        TRDecimal 3.4.5 [trdec.types.cdecfloat.min.normal.value]
+        TRDecimal 3.4.6 [trdec.types.cdecfloat.min.subnormal.value]
+        TRDecimal 3.4.7 [trdec.types.cdecfloat.eval.format]
+    TRDecimal 3.5 [trdec.types.cfenv]
+        TRDecimal 3.5.1 [trdec.types.cfenv.synopsis]
+        TRDecimal 3.5.2 [trdec.types.cfenv.round]
+        TRDecimal 3.5.3 [trdec.types.cfenv.fe_dec_getround]
+        TRDecimal 3.5.4 [trdec.types.cfenv.fe_dec_setround]
+        TRDecimal 3.5.5 [trdec.types.cfenv.fenv.h]
+    TRDecimal 3.6 [trdec.types.cmath]
+        TRDecimal 3.6.1 [trdec.types.cmath.synopsis]
+        TRDecimal 3.6.2 [trdec.types.cmath.macros]
+        TRDecimal 3.6.3 [trdec.types.cmath.eval.format]
+        TRDecimal 3.6.4 [trdec.types.cmath.samequantum]
+        TRDecimal 3.6.5 [trdec.types.cmath.quantize]
+        TRDecimal 3.6.6 [trdec.types.cmath.elementary]
+            TRDecimal 3.6.6.1 [trdec.types.cmath.elementary.abs]
+        TRDecimal 3.6.7 [trdec.types.cmath.math.h]
+            TRDecimal 3.6.7.1 [trdec.types.cmath.math.h.synopsis]
+    TRDecimal 3.7 [trdec.types.cstdio]
+    TRDecimal 3.8 [trdec.types.cstdlib]
+        TRDecimal 3.8.1 [trdec.types.cstdlib.synopsis]
+        TRDecimal 3.8.2 [trdec.types.cstdlib.strtod]
+        TRDecimal 3.8.3 [trdec.types.cstdlib.stdlib.h]
+    TRDecimal 3.9 [trdec.types.cwchar]
+        TRDecimal 3.9.1 [trdec.types.cwchar.synopsis]
+        TRDecimal 3.9.2 [trdec.types.cwchar.wcstod]
+        TRDecimal 3.9.3 [trdec.types.cwchar.wchar.h]
+    TRDecimal 3.10 [trdec.types.facets]
+        TRDecimal 3.10.1 [trdec.types.facets.locale]
+        TRDecimal 3.10.2 [trdec.types.facets.extended_num_get]
+            TRDecimal 3.10.2.1 [trdec.types.facets.extended_num_get.mem]
+            TRDecimal 3.10.2.2 [trdec.types.facets.extended_num_get.virt]
+        TRDecimal 3.10.3 [trdec.types.facets.extended_num_put]
+            TRDecimal 3.10.3.1 [trdec.types.facets.extended_num_put.mem]
+            TRDecimal 3.10.3.2 [trdec.types.facets.extended_num_put.virt]
+    TRDecimal 3.11 [trdec.types.traits]
+        TRDecimal 3.11.1 [trdec.types.traits.synopsis]
+        TRDecimal 3.11.2 [trdec.types.traits.is_decimal_floating_point]
+    TRDecimal 3.12 [trdec.types.hash]
+        TRDecimal 3.12.1 [trdec.types.hash.synopsis]
+        TRDecimal 3.12.2 [trdec.types.hash.spec]
+TRDecimal 4 [trdec.compat]
+    TRDecimal 4.1 [trdec.compat.decfloat.h]
+    TRDecimal 4.2 [trdec.compat.literals]
+    TRDecimal 4.3 [trdec.compat.conv]
diff --git a/test/lit.cfg b/test/lit.cfg
new file mode 100644
index 0000000..b306331
--- /dev/null
+++ b/test/lit.cfg
@@ -0,0 +1,144 @@
+# -*- Python -*-
+
+import os
+import platform
+
+# Configuration file for the 'lit' test runner.
+
+# name: The name of this test suite.
+config.name = 'Clang'
+
+# testFormat: The test format to use to interpret tests.
+#
+# For now we require '&&' between commands, until they get globally killed and
+# the test runner updated.
+execute_external = platform.system() != 'Windows'
+config.test_format = lit.formats.ShTest(execute_external)
+
+# suffixes: A list of file extensions to treat as test files.
+config.suffixes = ['.c', '.cpp', '.m', '.mm']
+
+# test_source_root: The root path where tests are located.
+config.test_source_root = os.path.dirname(__file__)
+
+# test_exec_root: The root path where tests should be run.
+clang_obj_root = getattr(config, 'clang_obj_root', None)
+if clang_obj_root is not None:
+    config.test_exec_root = os.path.join(clang_obj_root, 'test')
+
+# Set llvm_{src,obj}_root for use by others.
+config.llvm_src_root = getattr(config, 'llvm_src_root', None)
+config.llvm_obj_root = getattr(config, 'llvm_obj_root', None)
+
+# Tweak the PATH to include the tools dir and the scripts dir.
+if clang_obj_root is not None:
+    llvm_tools_dir = getattr(config, 'llvm_tools_dir', None)
+    if not llvm_tools_dir:
+        lit.fatal('No LLVM tools dir set!')
+    path = os.path.pathsep.join((llvm_tools_dir, config.environment['PATH']))
+    config.environment['PATH'] = path
+
+    llvm_libs_dir = getattr(config, 'llvm_libs_dir', None)
+    if not llvm_libs_dir:
+        lit.fatal('No LLVM libs dir set!')
+    path = os.path.pathsep.join((llvm_libs_dir,
+                                 config.environment.get('LD_LIBRARY_PATH','')))
+    config.environment['LD_LIBRARY_PATH'] = path
+
+###
+
+# Check that the object root is known.
+if config.test_exec_root is None:
+    # Otherwise, we haven't loaded the site specific configuration (the user is
+    # probably trying to run on a test file directly, and either the site
+    # configuration hasn't been created by the build system, or we are in an
+    # out-of-tree build situation).
+
+    # Check for 'clang_site_config' user parameter, and use that if available.
+    site_cfg = lit.params.get('clang_site_config', None)
+    if site_cfg and os.path.exists(site_cfg):
+        lit.load_config(config, site_cfg)
+        raise SystemExit
+
+    # Try to detect the situation where we are using an out-of-tree build by
+    # looking for 'llvm-config'.
+    #
+    # FIXME: I debated (i.e., wrote and threw away) adding logic to
+    # automagically generate the lit.site.cfg if we are in some kind of fresh
+    # build situation. This means knowing how to invoke the build system though,
+    # and I decided it was too much magic. We should solve this by just having
+    # the .cfg files generated during the configuration step.
+
+    llvm_config = lit.util.which('llvm-config', config.environment['PATH'])
+    if not llvm_config:
+        lit.fatal('No site specific configuration available!')
+
+    # Get the source and object roots.
+    llvm_src_root = lit.util.capture(['llvm-config', '--src-root']).strip()
+    llvm_obj_root = lit.util.capture(['llvm-config', '--obj-root']).strip()
+    clang_src_root = os.path.join(llvm_src_root, "tools", "clang")
+    clang_obj_root = os.path.join(llvm_obj_root, "tools", "clang")
+
+    # Validate that we got a tree which points to here, using the standard
+    # tools/clang layout.
+    this_src_root = os.path.dirname(config.test_source_root)
+    if os.path.realpath(clang_src_root) != os.path.realpath(this_src_root):
+        lit.fatal('No site specific configuration available!')
+
+    # Check that the site specific configuration exists.
+    site_cfg = os.path.join(clang_obj_root, 'test', 'lit.site.cfg')
+    if not os.path.exists(site_cfg):
+        lit.fatal('No site specific configuration available!')
+
+    # Okay, that worked. Notify the user of the automagic, and reconfigure.
+    lit.note('using out-of-tree build at %r' % clang_obj_root)
+    lit.load_config(config, site_cfg)
+    raise SystemExit
+
+###
+
+# Discover the 'clang' and 'clangcc' to use.
+
+import os
+
+def inferClang(PATH):
+    # Determine which clang to use.
+    clang = os.getenv('CLANG')
+
+    # If the user set clang in the environment, definitely use that and don't
+    # try to validate.
+    if clang:
+        return clang
+
+    # Otherwise look in the path.
+    clang = lit.util.which('clang', PATH)
+
+    if not clang:
+        lit.fatal("couldn't find 'clang' program, try setting "
+                  "CLANG in your environment")
+
+    return clang
+
+# When running under valgrind, we mangle '-vg' onto the end of the triple so we
+# can check it with XFAIL and XTARGET.
+if lit.useValgrind:
+    config.target_triple += '-vg'
+
+config.clang = inferClang(config.environment['PATH'])
+if not lit.quiet:
+    lit.note('using clang: %r' % config.clang)
+config.substitutions.append( ('%clang_cc1', config.clang + ' -cc1') )
+config.substitutions.append( ('%clangxx', ' ' + config.clang + ' -ccc-cxx'))
+config.substitutions.append( ('%clang', ' ' + config.clang + ' ') )
+
+# FIXME: Find nicer way to prohibit this.
+config.substitutions.append(
+    (' clang ', """*** Do not use 'clang' in tests, use '%clang'. ***""") )
+config.substitutions.append(
+    (' clang++ ', """*** Do not use 'clang++' in tests, use '%clangxx'. ***"""))
+config.substitutions.append(
+    (' clang-cc ',
+     """*** Do not use 'clang-cc' in tests, use '%clang_cc1'. ***""") )
+config.substitutions.append(
+    (' clang -cc1 ',
+     """*** Do not use 'clang -cc1' in tests, use '%clang_cc1'. ***""") )
diff --git a/test/lit.site.cfg.in b/test/lit.site.cfg.in
new file mode 100644
index 0000000..0d452ef
--- /dev/null
+++ b/test/lit.site.cfg.in
@@ -0,0 +1,20 @@
+## Autogenerated by LLVM/Clang configuration.
+# Do not edit!
+config.llvm_src_root = "@LLVM_SOURCE_DIR@"
+config.llvm_obj_root = "@LLVM_BINARY_DIR@"
+config.llvm_tools_dir = "@LLVM_TOOLS_DIR@"
+config.llvm_libs_dir = "@LLVM_LIBS_DIR@"
+config.clang_obj_root = "@CLANG_BINARY_DIR@"
+config.target_triple = "@TARGET_TRIPLE@"
+
+# Support substitution of the tools and libs dirs with user parameters. This is
+# used when we can't determine the tool dir at configuration time.
+try:
+    config.llvm_tools_dir = config.llvm_tools_dir % lit.params
+    config.llvm_libs_dir = config.llvm_libs_dir % lit.params
+except KeyError,e:
+    key, = e.args
+    lit.fatal("unable to find %r parameter, use '--param=%s=VALUE'" % (key,key))
+
+# Let the main config do the real work.
+lit.load_config(config, "@CLANG_SOURCE_DIR@/test/lit.cfg")
diff --git a/test/make_test_dirs.pl b/test/make_test_dirs.pl
new file mode 100755
index 0000000..3a524d2
--- /dev/null
+++ b/test/make_test_dirs.pl
@@ -0,0 +1,27 @@
+#!/usr/bin/perl -w
+#
+# Simple little Perl script that takes the cxx-sections.data file as
+# input and generates a directory structure that mimics the standard's
+# structure.
+use English;
+
+$current_indent_level = -4;
+while ($line = <STDIN>) {
+  $line =~ /^\s*/;
+  $next_indent_level = length($MATCH);
+  if ($line =~ /\[([^\]]*)\]/) {
+    my $section = $1;
+    while ($next_indent_level < $current_indent_level) {
+      chdir("..");
+      $current_indent_level -= 4;
+    }
+
+    if ($next_indent_level == $current_indent_level) {
+      chdir("..");
+    } else {
+      $current_indent_level = $next_indent_level;
+    }
+    mkdir($section);
+    chdir($section);
+  }
+}
diff --git a/tools/CIndex/CIndex.cpp b/tools/CIndex/CIndex.cpp
new file mode 100644
index 0000000..9cdb965
--- /dev/null
+++ b/tools/CIndex/CIndex.cpp
@@ -0,0 +1,2589 @@
+//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the main API hooks in the Clang-C Source Indexing
+// library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CIndexer.h"
+#include "CXCursor.h"
+#include "CXSourceLocation.h"
+#include "CIndexDiagnostic.h"
+
+#include "clang/Basic/Version.h"
+
+#include "clang/AST/DeclVisitor.h"
+#include "clang/AST/StmtVisitor.h"
+#include "clang/AST/TypeLocVisitor.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Frontend/ASTUnit.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Frontend/FrontendDiagnostic.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Lex/PreprocessingRecord.h"
+#include "clang/Lex/Preprocessor.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/System/Program.h"
+#include "llvm/System/Signals.h"
+
+// Needed to define L_TMPNAM on some systems.
+#include <cstdio>
+
+using namespace clang;
+using namespace clang::cxcursor;
+using namespace clang::cxstring;
+
+//===----------------------------------------------------------------------===//
+// Crash Reporting.
+//===----------------------------------------------------------------------===//
+
+#ifdef __APPLE__
+#define USE_CRASHTRACER
+#include "clang/Analysis/Support/SaveAndRestore.h"
+// Integrate with crash reporter.
+extern "C" const char *__crashreporter_info__;
+#define NUM_CRASH_STRINGS 32
+static unsigned crashtracer_counter = 0;
+static unsigned crashtracer_counter_id[NUM_CRASH_STRINGS] = { 0 };
+static const char *crashtracer_strings[NUM_CRASH_STRINGS] = { 0 };
+static const char *agg_crashtracer_strings[NUM_CRASH_STRINGS] = { 0 };
+
+static unsigned SetCrashTracerInfo(const char *str,
+                                   llvm::SmallString<1024> &AggStr) {
+
+  unsigned slot = 0;
+  while (crashtracer_strings[slot]) {
+    if (++slot == NUM_CRASH_STRINGS)
+      slot = 0;
+  }
+  crashtracer_strings[slot] = str;
+  crashtracer_counter_id[slot] = ++crashtracer_counter;
+
+  // We need to create an aggregate string because multiple threads
+  // may be in this method at one time.  The crash reporter string
+  // will attempt to overapproximate the set of in-flight invocations
+  // of this function.  Race conditions can still cause this goal
+  // to not be achieved.
+  {
+    llvm::raw_svector_ostream Out(AggStr);
+    for (unsigned i = 0; i < NUM_CRASH_STRINGS; ++i)
+      if (crashtracer_strings[i]) Out << crashtracer_strings[i] << '\n';
+  }
+  __crashreporter_info__ = agg_crashtracer_strings[slot] =  AggStr.c_str();
+  return slot;
+}
+
+static void ResetCrashTracerInfo(unsigned slot) {
+  unsigned max_slot = 0;
+  unsigned max_value = 0;
+
+  crashtracer_strings[slot] = agg_crashtracer_strings[slot] = 0;
+
+  for (unsigned i = 0 ; i < NUM_CRASH_STRINGS; ++i)
+    if (agg_crashtracer_strings[i] &&
+        crashtracer_counter_id[i] > max_value) {
+      max_slot = i;
+      max_value = crashtracer_counter_id[i];
+    }
+
+  __crashreporter_info__ = agg_crashtracer_strings[max_slot];
+}
+
+namespace {
+class ArgsCrashTracerInfo {
+  llvm::SmallString<1024> CrashString;
+  llvm::SmallString<1024> AggregateString;
+  unsigned crashtracerSlot;
+public:
+  ArgsCrashTracerInfo(llvm::SmallVectorImpl<const char*> &Args)
+    : crashtracerSlot(0)
+  {
+    {
+      llvm::raw_svector_ostream Out(CrashString);
+      Out << "ClangCIndex [" << getClangFullVersion() << "]"
+          << "[createTranslationUnitFromSourceFile]: clang";
+      for (llvm::SmallVectorImpl<const char*>::iterator I=Args.begin(),
+           E=Args.end(); I!=E; ++I)
+        Out << ' ' << *I;
+    }
+    crashtracerSlot = SetCrashTracerInfo(CrashString.c_str(),
+                                         AggregateString);
+  }
+
+  ~ArgsCrashTracerInfo() {
+    ResetCrashTracerInfo(crashtracerSlot);
+  }
+};
+}
+#endif
+
+/// \brief The result of comparing two source ranges.
+enum RangeComparisonResult {
+  /// \brief Either the ranges overlap or one of the ranges is invalid.
+  RangeOverlap,
+
+  /// \brief The first range ends before the second range starts.
+  RangeBefore,
+
+  /// \brief The first range starts after the second range ends.
+  RangeAfter
+};
+
+/// \brief Compare two source ranges to determine their relative position in
+/// the translation unit.
+static RangeComparisonResult RangeCompare(SourceManager &SM,
+                                          SourceRange R1,
+                                          SourceRange R2) {
+  assert(R1.isValid() && "First range is invalid?");
+  assert(R2.isValid() && "Second range is invalid?");
+  if (R1.getEnd() == R2.getBegin() ||
+      SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
+    return RangeBefore;
+  if (R2.getEnd() == R1.getBegin() ||
+      SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
+    return RangeAfter;
+  return RangeOverlap;
+}
+
+/// \brief Translate a Clang source range into a CIndex source range.
+///
+/// Clang internally represents ranges where the end location points to the
+/// start of the token at the end. However, for external clients it is more
+/// useful to have a CXSourceRange be a proper half-open interval. This routine
+/// does the appropriate translation.
+CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
+                                          const LangOptions &LangOpts,
+                                          SourceRange R) {
+  // We want the last character in this location, so we will adjust the
+  // location accordingly.
+  // FIXME: How do do this with a macro instantiation location?
+  SourceLocation EndLoc = R.getEnd();
+  if (!EndLoc.isInvalid() && EndLoc.isFileID()) {
+    unsigned Length = Lexer::MeasureTokenLength(EndLoc, SM, LangOpts);
+    EndLoc = EndLoc.getFileLocWithOffset(Length);
+  }
+
+  CXSourceRange Result = { { (void *)&SM, (void *)&LangOpts },
+                           R.getBegin().getRawEncoding(),
+                           EndLoc.getRawEncoding() };
+  return Result;
+}
+
+//===----------------------------------------------------------------------===//
+// Cursor visitor.
+//===----------------------------------------------------------------------===//
+
+namespace {
+
+// Cursor visitor.
+class CursorVisitor : public DeclVisitor<CursorVisitor, bool>,
+                      public TypeLocVisitor<CursorVisitor, bool>,
+                      public StmtVisitor<CursorVisitor, bool>
+{
+  /// \brief The translation unit we are traversing.
+  ASTUnit *TU;
+
+  /// \brief The parent cursor whose children we are traversing.
+  CXCursor Parent;
+
+  /// \brief The declaration that serves at the parent of any statement or
+  /// expression nodes.
+  Decl *StmtParent;
+
+  /// \brief The visitor function.
+  CXCursorVisitor Visitor;
+
+  /// \brief The opaque client data, to be passed along to the visitor.
+  CXClientData ClientData;
+
+  // MaxPCHLevel - the maximum PCH level of declarations that we will pass on
+  // to the visitor. Declarations with a PCH level greater than this value will
+  // be suppressed.
+  unsigned MaxPCHLevel;
+
+  /// \brief When valid, a source range to which the cursor should restrict
+  /// its search.
+  SourceRange RegionOfInterest;
+
+  using DeclVisitor<CursorVisitor, bool>::Visit;
+  using TypeLocVisitor<CursorVisitor, bool>::Visit;
+  using StmtVisitor<CursorVisitor, bool>::Visit;
+
+  /// \brief Determine whether this particular source range comes before, comes
+  /// after, or overlaps the region of interest.
+  ///
+  /// \param R a half-open source range retrieved from the abstract syntax tree.
+  RangeComparisonResult CompareRegionOfInterest(SourceRange R);
+
+public:
+  CursorVisitor(ASTUnit *TU, CXCursorVisitor Visitor, CXClientData ClientData,
+                unsigned MaxPCHLevel,
+                SourceRange RegionOfInterest = SourceRange())
+    : TU(TU), Visitor(Visitor), ClientData(ClientData),
+      MaxPCHLevel(MaxPCHLevel), RegionOfInterest(RegionOfInterest)
+  {
+    Parent.kind = CXCursor_NoDeclFound;
+    Parent.data[0] = 0;
+    Parent.data[1] = 0;
+    Parent.data[2] = 0;
+    StmtParent = 0;
+  }
+
+  bool Visit(CXCursor Cursor, bool CheckedRegionOfInterest = false);
+  
+  std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
+    getPreprocessedEntities();
+
+  bool VisitChildren(CXCursor Parent);
+
+  // Declaration visitors
+  bool VisitAttributes(Decl *D);
+  bool VisitBlockDecl(BlockDecl *B);
+  bool VisitDeclContext(DeclContext *DC);
+  bool VisitTranslationUnitDecl(TranslationUnitDecl *D);
+  bool VisitTypedefDecl(TypedefDecl *D);
+  bool VisitTagDecl(TagDecl *D);
+  bool VisitEnumConstantDecl(EnumConstantDecl *D);
+  bool VisitDeclaratorDecl(DeclaratorDecl *DD);
+  bool VisitFunctionDecl(FunctionDecl *ND);
+  bool VisitFieldDecl(FieldDecl *D);
+  bool VisitVarDecl(VarDecl *);
+  bool VisitObjCMethodDecl(ObjCMethodDecl *ND);
+  bool VisitObjCContainerDecl(ObjCContainerDecl *D);
+  bool VisitObjCCategoryDecl(ObjCCategoryDecl *ND);
+  bool VisitObjCProtocolDecl(ObjCProtocolDecl *PID);
+  bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
+  bool VisitObjCImplDecl(ObjCImplDecl *D);
+  bool VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D);
+  bool VisitObjCImplementationDecl(ObjCImplementationDecl *D);
+  // FIXME: ObjCPropertyDecl requires TypeSourceInfo, getter/setter locations,
+  // etc.
+  // FIXME: ObjCCompatibleAliasDecl requires aliased-class locations.
+  bool VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D);
+  bool VisitObjCClassDecl(ObjCClassDecl *D);
+
+  // Type visitors
+  // FIXME: QualifiedTypeLoc doesn't provide any location information
+  bool VisitBuiltinTypeLoc(BuiltinTypeLoc TL);
+  bool VisitTypedefTypeLoc(TypedefTypeLoc TL);
+  bool VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL);
+  bool VisitTagTypeLoc(TagTypeLoc TL);
+  // FIXME: TemplateTypeParmTypeLoc doesn't provide any location information
+  bool VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL);
+  bool VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL);
+  bool VisitPointerTypeLoc(PointerTypeLoc TL);
+  bool VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL);
+  bool VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL);
+  bool VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL);
+  bool VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL);
+  bool VisitFunctionTypeLoc(FunctionTypeLoc TL);
+  bool VisitArrayTypeLoc(ArrayTypeLoc TL);
+  // FIXME: Implement for TemplateSpecializationTypeLoc
+  // FIXME: Implement visitors here when the unimplemented TypeLocs get
+  // implemented
+  bool VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL);
+  bool VisitTypeOfTypeLoc(TypeOfTypeLoc TL);
+
+  // Statement visitors
+  bool VisitStmt(Stmt *S);
+  bool VisitDeclStmt(DeclStmt *S);
+  // FIXME: LabelStmt label?
+  bool VisitIfStmt(IfStmt *S);
+  bool VisitSwitchStmt(SwitchStmt *S);
+  bool VisitWhileStmt(WhileStmt *S);
+  bool VisitForStmt(ForStmt *S);
+
+  // Expression visitors
+  bool VisitBlockExpr(BlockExpr *B);
+  bool VisitCompoundLiteralExpr(CompoundLiteralExpr *E);
+  bool VisitExplicitCastExpr(ExplicitCastExpr *E);
+  bool VisitObjCMessageExpr(ObjCMessageExpr *E);
+  bool VisitObjCEncodeExpr(ObjCEncodeExpr *E);
+  bool VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E);
+};
+
+} // end anonymous namespace
+
+RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
+  return RangeCompare(TU->getSourceManager(), R, RegionOfInterest);
+}
+
+/// \brief Visit the given cursor and, if requested by the visitor,
+/// its children.
+///
+/// \param Cursor the cursor to visit.
+///
+/// \param CheckRegionOfInterest if true, then the caller already checked that
+/// this cursor is within the region of interest.
+///
+/// \returns true if the visitation should be aborted, false if it
+/// should continue.
+bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
+  if (clang_isInvalid(Cursor.kind))
+    return false;
+
+  if (clang_isDeclaration(Cursor.kind)) {
+    Decl *D = getCursorDecl(Cursor);
+    assert(D && "Invalid declaration cursor");
+    if (D->getPCHLevel() > MaxPCHLevel)
+      return false;
+
+    if (D->isImplicit())
+      return false;
+  }
+
+  // If we have a range of interest, and this cursor doesn't intersect with it,
+  // we're done.
+  if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
+    SourceRange Range =
+      cxloc::translateCXSourceRange(clang_getCursorExtent(Cursor));
+    if (Range.isInvalid() || CompareRegionOfInterest(Range))
+      return false;
+  }
+
+  switch (Visitor(Cursor, Parent, ClientData)) {
+  case CXChildVisit_Break:
+    return true;
+
+  case CXChildVisit_Continue:
+    return false;
+
+  case CXChildVisit_Recurse:
+    return VisitChildren(Cursor);
+  }
+
+  return false;
+}
+
+std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
+CursorVisitor::getPreprocessedEntities() {
+  PreprocessingRecord &PPRec
+    = *TU->getPreprocessor().getPreprocessingRecord();
+  
+  bool OnlyLocalDecls
+    = !TU->isMainFileAST() && TU->getOnlyLocalDecls();
+  
+  // There is no region of interest; we have to walk everything.
+  if (RegionOfInterest.isInvalid())
+    return std::make_pair(PPRec.begin(OnlyLocalDecls),
+                          PPRec.end(OnlyLocalDecls));
+
+  // Find the file in which the region of interest lands.
+  SourceManager &SM = TU->getSourceManager();
+  std::pair<FileID, unsigned> Begin
+    = SM.getDecomposedInstantiationLoc(RegionOfInterest.getBegin());
+  std::pair<FileID, unsigned> End
+    = SM.getDecomposedInstantiationLoc(RegionOfInterest.getEnd());
+  
+  // The region of interest spans files; we have to walk everything.
+  if (Begin.first != End.first)
+    return std::make_pair(PPRec.begin(OnlyLocalDecls),
+                          PPRec.end(OnlyLocalDecls));
+    
+  ASTUnit::PreprocessedEntitiesByFileMap &ByFileMap
+    = TU->getPreprocessedEntitiesByFile();
+  if (ByFileMap.empty()) {
+    // Build the mapping from files to sets of preprocessed entities.
+    for (PreprocessingRecord::iterator E = PPRec.begin(OnlyLocalDecls),
+                                    EEnd = PPRec.end(OnlyLocalDecls);
+         E != EEnd; ++E) {
+      std::pair<FileID, unsigned> P
+        = SM.getDecomposedInstantiationLoc((*E)->getSourceRange().getBegin());
+      ByFileMap[P.first].push_back(*E);
+    }
+  }
+
+  return std::make_pair(ByFileMap[Begin.first].begin(), 
+                        ByFileMap[Begin.first].end());
+}
+
+/// \brief Visit the children of the given cursor.
+///
+/// \returns true if the visitation should be aborted, false if it
+/// should continue.
+bool CursorVisitor::VisitChildren(CXCursor Cursor) {
+  if (clang_isReference(Cursor.kind)) {
+    // By definition, references have no children.
+    return false;
+  }
+
+  // Set the Parent field to Cursor, then back to its old value once we're
+  // done.
+  class SetParentRAII {
+    CXCursor &Parent;
+    Decl *&StmtParent;
+    CXCursor OldParent;
+
+  public:
+    SetParentRAII(CXCursor &Parent, Decl *&StmtParent, CXCursor NewParent)
+      : Parent(Parent), StmtParent(StmtParent), OldParent(Parent)
+    {
+      Parent = NewParent;
+      if (clang_isDeclaration(Parent.kind))
+        StmtParent = getCursorDecl(Parent);
+    }
+
+    ~SetParentRAII() {
+      Parent = OldParent;
+      if (clang_isDeclaration(Parent.kind))
+        StmtParent = getCursorDecl(Parent);
+    }
+  } SetParent(Parent, StmtParent, Cursor);
+
+  if (clang_isDeclaration(Cursor.kind)) {
+    Decl *D = getCursorDecl(Cursor);
+    assert(D && "Invalid declaration cursor");
+    return VisitAttributes(D) || Visit(D);
+  }
+
+  if (clang_isStatement(Cursor.kind))
+    return Visit(getCursorStmt(Cursor));
+  if (clang_isExpression(Cursor.kind))
+    return Visit(getCursorExpr(Cursor));
+
+  if (clang_isTranslationUnit(Cursor.kind)) {
+    ASTUnit *CXXUnit = getCursorASTUnit(Cursor);
+    if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
+        RegionOfInterest.isInvalid()) {
+      const std::vector<Decl*> &TLDs = CXXUnit->getTopLevelDecls();
+      for (std::vector<Decl*>::const_iterator it = TLDs.begin(),
+           ie = TLDs.end(); it != ie; ++it) {
+        if (Visit(MakeCXCursor(*it, CXXUnit), true))
+          return true;
+      }
+    } else if (VisitDeclContext(
+                            CXXUnit->getASTContext().getTranslationUnitDecl()))
+      return true;
+
+    // Walk the preprocessing record.
+    if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
+      // FIXME: Once we have the ability to deserialize a preprocessing record,
+      // do so.
+      PreprocessingRecord::iterator E, EEnd;
+      for (llvm::tie(E, EEnd) = getPreprocessedEntities(); E != EEnd; ++E) {
+        if (MacroInstantiation *MI = dyn_cast<MacroInstantiation>(*E)) {
+          if (Visit(MakeMacroInstantiationCursor(MI, CXXUnit)))
+            return true;
+          
+          continue;
+        }
+        
+        if (MacroDefinition *MD = dyn_cast<MacroDefinition>(*E)) {
+          if (Visit(MakeMacroDefinitionCursor(MD, CXXUnit)))
+            return true;
+          
+          continue;
+        }
+      }
+    }
+    return false;
+  }
+
+  // Nothing to visit at the moment.
+  return false;
+}
+
+bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
+  for (BlockDecl::param_iterator I=B->param_begin(), E=B->param_end(); I!=E;++I)
+    if (Decl *D = *I)
+      if (Visit(D))
+        return true;
+
+  return Visit(MakeCXCursor(B->getBody(), StmtParent, TU));
+}
+
+bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
+  for (DeclContext::decl_iterator
+       I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I) {
+
+    CXCursor Cursor = MakeCXCursor(*I, TU);
+
+    if (RegionOfInterest.isValid()) {
+      SourceRange Range =
+        cxloc::translateCXSourceRange(clang_getCursorExtent(Cursor));
+      if (Range.isInvalid())
+        continue;
+
+      switch (CompareRegionOfInterest(Range)) {
+      case RangeBefore:
+        // This declaration comes before the region of interest; skip it.
+        continue;
+
+      case RangeAfter:
+        // This declaration comes after the region of interest; we're done.
+        return false;
+
+      case RangeOverlap:
+        // This declaration overlaps the region of interest; visit it.
+        break;
+      }
+    }
+
+    if (Visit(Cursor, true))
+      return true;
+  }
+
+  return false;
+}
+
+bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
+  llvm_unreachable("Translation units are visited directly by Visit()");
+  return false;
+}
+
+bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
+  if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
+    return Visit(TSInfo->getTypeLoc());
+
+  return false;
+}
+
+bool CursorVisitor::VisitTagDecl(TagDecl *D) {
+  return VisitDeclContext(D);
+}
+
+bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
+  if (Expr *Init = D->getInitExpr())
+    return Visit(MakeCXCursor(Init, StmtParent, TU));
+  return false;
+}
+
+bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
+  if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
+    if (Visit(TSInfo->getTypeLoc()))
+      return true;
+
+  return false;
+}
+
+bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
+  if (VisitDeclaratorDecl(ND))
+    return true;
+
+  if (ND->isThisDeclarationADefinition() &&
+      Visit(MakeCXCursor(ND->getBody(), StmtParent, TU)))
+    return true;
+
+  return false;
+}
+
+bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
+  if (VisitDeclaratorDecl(D))
+    return true;
+
+  if (Expr *BitWidth = D->getBitWidth())
+    return Visit(MakeCXCursor(BitWidth, StmtParent, TU));
+
+  return false;
+}
+
+bool CursorVisitor::VisitVarDecl(VarDecl *D) {
+  if (VisitDeclaratorDecl(D))
+    return true;
+
+  if (Expr *Init = D->getInit())
+    return Visit(MakeCXCursor(Init, StmtParent, TU));
+
+  return false;
+}
+
+bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
+  if (TypeSourceInfo *TSInfo = ND->getResultTypeSourceInfo())
+    if (Visit(TSInfo->getTypeLoc()))
+      return true;
+
+  for (ObjCMethodDecl::param_iterator P = ND->param_begin(),
+       PEnd = ND->param_end();
+       P != PEnd; ++P) {
+    if (Visit(MakeCXCursor(*P, TU)))
+      return true;
+  }
+
+  if (ND->isThisDeclarationADefinition() &&
+      Visit(MakeCXCursor(ND->getBody(), StmtParent, TU)))
+    return true;
+
+  return false;
+}
+
+bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
+  return VisitDeclContext(D);
+}
+
+bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
+  if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
+                                   TU)))
+    return true;
+
+  ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
+  for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
+         E = ND->protocol_end(); I != E; ++I, ++PL)
+    if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
+      return true;
+
+  return VisitObjCContainerDecl(ND);
+}
+
+bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
+  ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
+  for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
+       E = PID->protocol_end(); I != E; ++I, ++PL)
+    if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
+      return true;
+
+  return VisitObjCContainerDecl(PID);
+}
+
+bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
+  // Issue callbacks for super class.
+  if (D->getSuperClass() &&
+      Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
+                                        D->getSuperClassLoc(),
+                                        TU)))
+    return true;
+
+  ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
+  for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
+         E = D->protocol_end(); I != E; ++I, ++PL)
+    if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
+      return true;
+
+  return VisitObjCContainerDecl(D);
+}
+
+bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
+  return VisitObjCContainerDecl(D);
+}
+
+bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
+  // 'ID' could be null when dealing with invalid code.
+  if (ObjCInterfaceDecl *ID = D->getClassInterface())
+    if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
+      return true;
+
+  return VisitObjCImplDecl(D);
+}
+
+bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
+#if 0
+  // Issue callbacks for super class.
+  // FIXME: No source location information!
+  if (D->getSuperClass() &&
+      Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
+                                        D->getSuperClassLoc(),
+                                        TU)))
+    return true;
+#endif
+
+  return VisitObjCImplDecl(D);
+}
+
+bool CursorVisitor::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D) {
+  ObjCForwardProtocolDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
+  for (ObjCForwardProtocolDecl::protocol_iterator I = D->protocol_begin(),
+                                                  E = D->protocol_end();
+       I != E; ++I, ++PL)
+    if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
+      return true;
+
+  return false;
+}
+
+bool CursorVisitor::VisitObjCClassDecl(ObjCClassDecl *D) {
+  for (ObjCClassDecl::iterator C = D->begin(), CEnd = D->end(); C != CEnd; ++C)
+    if (Visit(MakeCursorObjCClassRef(C->getInterface(), C->getLocation(), TU)))
+      return true;
+
+  return false;
+}
+
+bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
+  ASTContext &Context = TU->getASTContext();
+
+  // Some builtin types (such as Objective-C's "id", "sel", and
+  // "Class") have associated declarations. Create cursors for those.
+  QualType VisitType;
+  switch (TL.getType()->getAs<BuiltinType>()->getKind()) {
+  case BuiltinType::Void:
+  case BuiltinType::Bool:
+  case BuiltinType::Char_U:
+  case BuiltinType::UChar:
+  case BuiltinType::Char16:
+  case BuiltinType::Char32:
+  case BuiltinType::UShort:
+  case BuiltinType::UInt:
+  case BuiltinType::ULong:
+  case BuiltinType::ULongLong:
+  case BuiltinType::UInt128:
+  case BuiltinType::Char_S:
+  case BuiltinType::SChar:
+  case BuiltinType::WChar:
+  case BuiltinType::Short:
+  case BuiltinType::Int:
+  case BuiltinType::Long:
+  case BuiltinType::LongLong:
+  case BuiltinType::Int128:
+  case BuiltinType::Float:
+  case BuiltinType::Double:
+  case BuiltinType::LongDouble:
+  case BuiltinType::NullPtr:
+  case BuiltinType::Overload:
+  case BuiltinType::Dependent:
+    break;
+
+  case BuiltinType::UndeducedAuto: // FIXME: Deserves a cursor?
+    break;
+
+  case BuiltinType::ObjCId:
+    VisitType = Context.getObjCIdType();
+    break;
+
+  case BuiltinType::ObjCClass:
+    VisitType = Context.getObjCClassType();
+    break;
+
+  case BuiltinType::ObjCSel:
+    VisitType = Context.getObjCSelType();
+    break;
+  }
+
+  if (!VisitType.isNull()) {
+    if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
+      return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
+                                     TU));
+  }
+
+  return false;
+}
+
+bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
+  return Visit(MakeCursorTypeRef(TL.getTypedefDecl(), TL.getNameLoc(), TU));
+}
+
+bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
+  return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
+}
+
+bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
+  return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
+}
+
+bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
+  if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
+    return true;
+
+  for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
+    if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
+                                        TU)))
+      return true;
+  }
+
+  return false;
+}
+
+bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
+  if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseTypeLoc()))
+    return true;
+
+  if (TL.hasProtocolsAsWritten()) {
+    for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
+      if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I),
+                                          TL.getProtocolLoc(I),
+                                          TU)))
+        return true;
+    }
+  }
+
+  return false;
+}
+
+bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
+  return Visit(TL.getPointeeLoc());
+}
+
+bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
+  return Visit(TL.getPointeeLoc());
+}
+
+bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
+  return Visit(TL.getPointeeLoc());
+}
+
+bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
+  return Visit(TL.getPointeeLoc());
+}
+
+bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
+  return Visit(TL.getPointeeLoc());
+}
+
+bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL) {
+  if (Visit(TL.getResultLoc()))
+    return true;
+
+  for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
+    if (Decl *D = TL.getArg(I))
+      if (Visit(MakeCXCursor(D, TU)))
+        return true;
+
+  return false;
+}
+
+bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
+  if (Visit(TL.getElementLoc()))
+    return true;
+
+  if (Expr *Size = TL.getSizeExpr())
+    return Visit(MakeCXCursor(Size, StmtParent, TU));
+
+  return false;
+}
+
+bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
+  return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
+}
+
+bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
+  if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
+    return Visit(TSInfo->getTypeLoc());
+
+  return false;
+}
+
+bool CursorVisitor::VisitStmt(Stmt *S) {
+  for (Stmt::child_iterator Child = S->child_begin(), ChildEnd = S->child_end();
+       Child != ChildEnd; ++Child) {
+    if (*Child && Visit(MakeCXCursor(*Child, StmtParent, TU)))
+      return true;
+  }
+
+  return false;
+}
+
+bool CursorVisitor::VisitDeclStmt(DeclStmt *S) {
+  for (DeclStmt::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
+       D != DEnd; ++D) {
+    if (*D && Visit(MakeCXCursor(*D, TU)))
+      return true;
+  }
+
+  return false;
+}
+
+bool CursorVisitor::VisitIfStmt(IfStmt *S) {
+  if (VarDecl *Var = S->getConditionVariable()) {
+    if (Visit(MakeCXCursor(Var, TU)))
+      return true;
+  }
+
+  if (S->getCond() && Visit(MakeCXCursor(S->getCond(), StmtParent, TU)))
+    return true;
+  if (S->getThen() && Visit(MakeCXCursor(S->getThen(), StmtParent, TU)))
+    return true;
+  if (S->getElse() && Visit(MakeCXCursor(S->getElse(), StmtParent, TU)))
+    return true;
+
+  return false;
+}
+
+bool CursorVisitor::VisitSwitchStmt(SwitchStmt *S) {
+  if (VarDecl *Var = S->getConditionVariable()) {
+    if (Visit(MakeCXCursor(Var, TU)))
+      return true;
+  }
+
+  if (S->getCond() && Visit(MakeCXCursor(S->getCond(), StmtParent, TU)))
+    return true;
+  if (S->getBody() && Visit(MakeCXCursor(S->getBody(), StmtParent, TU)))
+    return true;
+
+  return false;
+}
+
+bool CursorVisitor::VisitWhileStmt(WhileStmt *S) {
+  if (VarDecl *Var = S->getConditionVariable()) {
+    if (Visit(MakeCXCursor(Var, TU)))
+      return true;
+  }
+
+  if (S->getCond() && Visit(MakeCXCursor(S->getCond(), StmtParent, TU)))
+    return true;
+  if (S->getBody() && Visit(MakeCXCursor(S->getBody(), StmtParent, TU)))
+    return true;
+
+  return false;
+}
+
+bool CursorVisitor::VisitForStmt(ForStmt *S) {
+  if (S->getInit() && Visit(MakeCXCursor(S->getInit(), StmtParent, TU)))
+    return true;
+  if (VarDecl *Var = S->getConditionVariable()) {
+    if (Visit(MakeCXCursor(Var, TU)))
+      return true;
+  }
+
+  if (S->getCond() && Visit(MakeCXCursor(S->getCond(), StmtParent, TU)))
+    return true;
+  if (S->getInc() && Visit(MakeCXCursor(S->getInc(), StmtParent, TU)))
+    return true;
+  if (S->getBody() && Visit(MakeCXCursor(S->getBody(), StmtParent, TU)))
+    return true;
+
+  return false;
+}
+
+bool CursorVisitor::VisitBlockExpr(BlockExpr *B) {
+  return Visit(B->getBlockDecl());
+}
+
+bool CursorVisitor::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) {
+  if (E->isArgumentType()) {
+    if (TypeSourceInfo *TSInfo = E->getArgumentTypeInfo())
+      return Visit(TSInfo->getTypeLoc());
+
+    return false;
+  }
+
+  return VisitExpr(E);
+}
+
+bool CursorVisitor::VisitExplicitCastExpr(ExplicitCastExpr *E) {
+  if (TypeSourceInfo *TSInfo = E->getTypeInfoAsWritten())
+    if (Visit(TSInfo->getTypeLoc()))
+      return true;
+
+  return VisitCastExpr(E);
+}
+
+bool CursorVisitor::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
+  if (TypeSourceInfo *TSInfo = E->getTypeSourceInfo())
+    if (Visit(TSInfo->getTypeLoc()))
+      return true;
+
+  return VisitExpr(E);
+}
+
+bool CursorVisitor::VisitObjCMessageExpr(ObjCMessageExpr *E) {
+  if (TypeSourceInfo *TSInfo = E->getClassReceiverTypeInfo())
+    if (Visit(TSInfo->getTypeLoc()))
+      return true;
+
+  return VisitExpr(E);
+}
+
+bool CursorVisitor::VisitObjCEncodeExpr(ObjCEncodeExpr *E) {
+  return Visit(E->getEncodedTypeSourceInfo()->getTypeLoc());
+}
+
+
+bool CursorVisitor::VisitAttributes(Decl *D) {
+  for (const Attr *A = D->getAttrs(); A; A = A->getNext())
+    if (Visit(MakeCXCursor(A, D, TU)))
+        return true;
+
+  return false;
+}
+
+extern "C" {
+CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
+                          int displayDiagnostics) {
+  CIndexer *CIdxr = new CIndexer();
+  if (excludeDeclarationsFromPCH)
+    CIdxr->setOnlyLocalDecls();
+  if (displayDiagnostics)
+    CIdxr->setDisplayDiagnostics();
+  return CIdxr;
+}
+
+void clang_disposeIndex(CXIndex CIdx) {
+  if (CIdx)
+    delete static_cast<CIndexer *>(CIdx);
+}
+
+void clang_setUseExternalASTGeneration(CXIndex CIdx, int value) {
+  if (CIdx) {
+    CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
+    CXXIdx->setUseExternalASTGeneration(value);
+  }
+}
+
+CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
+                                              const char *ast_filename) {
+  if (!CIdx)
+    return 0;
+
+  CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
+
+  llvm::IntrusiveRefCntPtr<Diagnostic> Diags;
+  return ASTUnit::LoadFromPCHFile(ast_filename, Diags,
+                                  CXXIdx->getOnlyLocalDecls(),
+                                  0, 0, true);
+}
+
+CXTranslationUnit
+clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
+                                          const char *source_filename,
+                                          int num_command_line_args,
+                                          const char **command_line_args,
+                                          unsigned num_unsaved_files,
+                                          struct CXUnsavedFile *unsaved_files) {
+  if (!CIdx)
+    return 0;
+
+  CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
+
+  // Configure the diagnostics.
+  DiagnosticOptions DiagOpts;
+  llvm::IntrusiveRefCntPtr<Diagnostic> Diags;
+  Diags = CompilerInstance::createDiagnostics(DiagOpts, 0, 0);
+
+  llvm::SmallVector<ASTUnit::RemappedFile, 4> RemappedFiles;
+  for (unsigned I = 0; I != num_unsaved_files; ++I) {
+    llvm::StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
+    const llvm::MemoryBuffer *Buffer
+      = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
+    RemappedFiles.push_back(std::make_pair(unsaved_files[I].Filename,
+                                           Buffer));
+  }
+
+  if (!CXXIdx->getUseExternalASTGeneration()) {
+    llvm::SmallVector<const char *, 16> Args;
+
+    // The 'source_filename' argument is optional.  If the caller does not
+    // specify it then it is assumed that the source file is specified
+    // in the actual argument list.
+    if (source_filename)
+      Args.push_back(source_filename);
+    Args.insert(Args.end(), command_line_args,
+                command_line_args + num_command_line_args);
+    Args.push_back("-Xclang");
+    Args.push_back("-detailed-preprocessing-record");
+    unsigned NumErrors = Diags->getNumErrors();
+
+#ifdef USE_CRASHTRACER
+    ArgsCrashTracerInfo ACTI(Args);
+#endif
+
+    llvm::OwningPtr<ASTUnit> Unit(
+      ASTUnit::LoadFromCommandLine(Args.data(), Args.data() + Args.size(),
+                                   Diags,
+                                   CXXIdx->getClangResourcesPath(),
+                                   CXXIdx->getOnlyLocalDecls(),
+                                   RemappedFiles.data(),
+                                   RemappedFiles.size(),
+                                   /*CaptureDiagnostics=*/true));
+
+    // FIXME: Until we have broader testing, just drop the entire AST if we
+    // encountered an error.
+    if (NumErrors != Diags->getNumErrors()) {
+      // Make sure to check that 'Unit' is non-NULL.
+      if (CXXIdx->getDisplayDiagnostics() && Unit.get()) {
+        for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(), 
+                                        DEnd = Unit->stored_diag_end();
+             D != DEnd; ++D) {
+          CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOptions());
+          CXString Msg = clang_formatDiagnostic(&Diag,
+                                      clang_defaultDiagnosticDisplayOptions());
+          fprintf(stderr, "%s\n", clang_getCString(Msg));
+          clang_disposeString(Msg);
+        }
+#ifdef LLVM_ON_WIN32
+        // On Windows, force a flush, since there may be multiple copies of
+        // stderr and stdout in the file system, all with different buffers
+        // but writing to the same device.
+        fflush(stderr);
+#endif
+      }
+    }
+
+    return Unit.take();
+  }
+
+  // Build up the arguments for invoking 'clang'.
+  std::vector<const char *> argv;
+
+  // First add the complete path to the 'clang' executable.
+  llvm::sys::Path ClangPath = static_cast<CIndexer *>(CIdx)->getClangPath();
+  argv.push_back(ClangPath.c_str());
+
+  // Add the '-emit-ast' option as our execution mode for 'clang'.
+  argv.push_back("-emit-ast");
+
+  // The 'source_filename' argument is optional.  If the caller does not
+  // specify it then it is assumed that the source file is specified
+  // in the actual argument list.
+  if (source_filename)
+    argv.push_back(source_filename);
+
+  // Generate a temporary name for the AST file.
+  argv.push_back("-o");
+  char astTmpFile[L_tmpnam];
+  argv.push_back(tmpnam(astTmpFile));
+
+  // Remap any unsaved files to temporary files.
+  std::vector<llvm::sys::Path> TemporaryFiles;
+  std::vector<std::string> RemapArgs;
+  if (RemapFiles(num_unsaved_files, unsaved_files, RemapArgs, TemporaryFiles))
+    return 0;
+
+  // The pointers into the elements of RemapArgs are stable because we
+  // won't be adding anything to RemapArgs after this point.
+  for (unsigned i = 0, e = RemapArgs.size(); i != e; ++i)
+    argv.push_back(RemapArgs[i].c_str());
+
+  // Process the compiler options, stripping off '-o', '-c', '-fsyntax-only'.
+  for (int i = 0; i < num_command_line_args; ++i)
+    if (const char *arg = command_line_args[i]) {
+      if (strcmp(arg, "-o") == 0) {
+        ++i; // Also skip the matching argument.
+        continue;
+      }
+      if (strcmp(arg, "-emit-ast") == 0 ||
+          strcmp(arg, "-c") == 0 ||
+          strcmp(arg, "-fsyntax-only") == 0) {
+        continue;
+      }
+
+      // Keep the argument.
+      argv.push_back(arg);
+    }
+
+  // Generate a temporary name for the diagnostics file.
+  char tmpFileResults[L_tmpnam];
+  char *tmpResultsFileName = tmpnam(tmpFileResults);
+  llvm::sys::Path DiagnosticsFile(tmpResultsFileName);
+  TemporaryFiles.push_back(DiagnosticsFile);
+  argv.push_back("-fdiagnostics-binary");
+
+  argv.push_back("-Xclang");
+  argv.push_back("-detailed-preprocessing-record");
+
+  // Add the null terminator.
+  argv.push_back(NULL);
+
+  // Invoke 'clang'.
+  llvm::sys::Path DevNull; // leave empty, causes redirection to /dev/null
+                           // on Unix or NUL (Windows).
+  std::string ErrMsg;
+  const llvm::sys::Path *Redirects[] = { &DevNull, &DevNull, &DiagnosticsFile,
+                                         NULL };
+  llvm::sys::Program::ExecuteAndWait(ClangPath, &argv[0], /* env */ NULL,
+      /* redirects */ &Redirects[0],
+      /* secondsToWait */ 0, /* memoryLimits */ 0, &ErrMsg);
+
+  if (!ErrMsg.empty()) {
+    std::string AllArgs;
+    for (std::vector<const char*>::iterator I = argv.begin(), E = argv.end();
+         I != E; ++I) {
+      AllArgs += ' ';
+      if (*I)
+        AllArgs += *I;
+    }
+
+    Diags->Report(diag::err_fe_invoking) << AllArgs << ErrMsg;
+  }
+
+  ASTUnit *ATU = ASTUnit::LoadFromPCHFile(astTmpFile, Diags,
+                                          CXXIdx->getOnlyLocalDecls(),
+                                          RemappedFiles.data(),
+                                          RemappedFiles.size(),
+                                          /*CaptureDiagnostics=*/true);
+  if (ATU) {
+    LoadSerializedDiagnostics(DiagnosticsFile, 
+                              num_unsaved_files, unsaved_files,
+                              ATU->getFileManager(),
+                              ATU->getSourceManager(),
+                              ATU->getStoredDiagnostics());
+  } else if (CXXIdx->getDisplayDiagnostics()) {
+    // We failed to load the ASTUnit, but we can still deserialize the
+    // diagnostics and emit them.
+    FileManager FileMgr;
+    Diagnostic Diag;
+    SourceManager SourceMgr(Diag);
+    // FIXME: Faked LangOpts!
+    LangOptions LangOpts;
+    llvm::SmallVector<StoredDiagnostic, 4> Diags;
+    LoadSerializedDiagnostics(DiagnosticsFile, 
+                              num_unsaved_files, unsaved_files,
+                              FileMgr, SourceMgr, Diags);
+    for (llvm::SmallVector<StoredDiagnostic, 4>::iterator D = Diags.begin(), 
+                                                       DEnd = Diags.end();
+         D != DEnd; ++D) {
+      CXStoredDiagnostic Diag(*D, LangOpts);
+      CXString Msg = clang_formatDiagnostic(&Diag,
+                                      clang_defaultDiagnosticDisplayOptions());
+      fprintf(stderr, "%s\n", clang_getCString(Msg));
+      clang_disposeString(Msg);
+    }
+    
+#ifdef LLVM_ON_WIN32
+    // On Windows, force a flush, since there may be multiple copies of
+    // stderr and stdout in the file system, all with different buffers
+    // but writing to the same device.
+    fflush(stderr);
+#endif    
+  }
+
+  if (ATU) {
+    // Make the translation unit responsible for destroying all temporary files.
+    for (unsigned i = 0, e = TemporaryFiles.size(); i != e; ++i)
+      ATU->addTemporaryFile(TemporaryFiles[i]);
+    ATU->addTemporaryFile(llvm::sys::Path(ATU->getPCHFileName()));
+  } else {
+    // Destroy all of the temporary files now; they can't be referenced any
+    // longer.
+    llvm::sys::Path(astTmpFile).eraseFromDisk();
+    for (unsigned i = 0, e = TemporaryFiles.size(); i != e; ++i)
+      TemporaryFiles[i].eraseFromDisk();
+  }
+  
+  return ATU;
+}
+
+void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
+  if (CTUnit)
+    delete static_cast<ASTUnit *>(CTUnit);
+}
+
+CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
+  if (!CTUnit)
+    return createCXString("");
+
+  ASTUnit *CXXUnit = static_cast<ASTUnit *>(CTUnit);
+  return createCXString(CXXUnit->getOriginalSourceFileName(), true);
+}
+
+CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
+  CXCursor Result = { CXCursor_TranslationUnit, { 0, 0, TU } };
+  return Result;
+}
+
+} // end: extern "C"
+
+//===----------------------------------------------------------------------===//
+// CXSourceLocation and CXSourceRange Operations.
+//===----------------------------------------------------------------------===//
+
+extern "C" {
+CXSourceLocation clang_getNullLocation() {
+  CXSourceLocation Result = { { 0, 0 }, 0 };
+  return Result;
+}
+
+unsigned clang_equalLocations(CXSourceLocation loc1, CXSourceLocation loc2) {
+  return (loc1.ptr_data[0] == loc2.ptr_data[0] &&
+          loc1.ptr_data[1] == loc2.ptr_data[1] &&
+          loc1.int_data == loc2.int_data);
+}
+
+CXSourceLocation clang_getLocation(CXTranslationUnit tu,
+                                   CXFile file,
+                                   unsigned line,
+                                   unsigned column) {
+  if (!tu)
+    return clang_getNullLocation();
+
+  ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu);
+  SourceLocation SLoc
+    = CXXUnit->getSourceManager().getLocation(
+                                        static_cast<const FileEntry *>(file),
+                                              line, column);
+
+  return cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc);
+}
+
+CXSourceRange clang_getNullRange() {
+  CXSourceRange Result = { { 0, 0 }, 0, 0 };
+  return Result;
+}
+
+CXSourceRange clang_getRange(CXSourceLocation begin, CXSourceLocation end) {
+  if (begin.ptr_data[0] != end.ptr_data[0] ||
+      begin.ptr_data[1] != end.ptr_data[1])
+    return clang_getNullRange();
+
+  CXSourceRange Result = { { begin.ptr_data[0], begin.ptr_data[1] },
+                           begin.int_data, end.int_data };
+  return Result;
+}
+
+void clang_getInstantiationLocation(CXSourceLocation location,
+                                    CXFile *file,
+                                    unsigned *line,
+                                    unsigned *column,
+                                    unsigned *offset) {
+  SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
+
+  if (!location.ptr_data[0] || Loc.isInvalid()) {
+    if (file)
+      *file = 0;
+    if (line)
+      *line = 0;
+    if (column)
+      *column = 0;
+    if (offset)
+      *offset = 0;
+    return;
+  }
+
+  const SourceManager &SM =
+    *static_cast<const SourceManager*>(location.ptr_data[0]);
+  SourceLocation InstLoc = SM.getInstantiationLoc(Loc);
+
+  if (file)
+    *file = (void *)SM.getFileEntryForID(SM.getFileID(InstLoc));
+  if (line)
+    *line = SM.getInstantiationLineNumber(InstLoc);
+  if (column)
+    *column = SM.getInstantiationColumnNumber(InstLoc);
+  if (offset)
+    *offset = SM.getDecomposedLoc(InstLoc).second;
+}
+
+CXSourceLocation clang_getRangeStart(CXSourceRange range) {
+  CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] },
+                              range.begin_int_data };
+  return Result;
+}
+
+CXSourceLocation clang_getRangeEnd(CXSourceRange range) {
+  CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] },
+                              range.end_int_data };
+  return Result;
+}
+
+} // end: extern "C"
+
+//===----------------------------------------------------------------------===//
+// CXFile Operations.
+//===----------------------------------------------------------------------===//
+
+extern "C" {
+CXString clang_getFileName(CXFile SFile) {
+  if (!SFile)
+    return createCXString(NULL);
+
+  FileEntry *FEnt = static_cast<FileEntry *>(SFile);
+  return createCXString(FEnt->getName());
+}
+
+time_t clang_getFileTime(CXFile SFile) {
+  if (!SFile)
+    return 0;
+
+  FileEntry *FEnt = static_cast<FileEntry *>(SFile);
+  return FEnt->getModificationTime();
+}
+
+CXFile clang_getFile(CXTranslationUnit tu, const char *file_name) {
+  if (!tu)
+    return 0;
+
+  ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu);
+
+  FileManager &FMgr = CXXUnit->getFileManager();
+  const FileEntry *File = FMgr.getFile(file_name, file_name+strlen(file_name));
+  return const_cast<FileEntry *>(File);
+}
+
+} // end: extern "C"
+
+//===----------------------------------------------------------------------===//
+// CXCursor Operations.
+//===----------------------------------------------------------------------===//
+
+static Decl *getDeclFromExpr(Stmt *E) {
+  if (DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
+    return RefExpr->getDecl();
+  if (MemberExpr *ME = dyn_cast<MemberExpr>(E))
+    return ME->getMemberDecl();
+  if (ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
+    return RE->getDecl();
+
+  if (CallExpr *CE = dyn_cast<CallExpr>(E))
+    return getDeclFromExpr(CE->getCallee());
+  if (CastExpr *CE = dyn_cast<CastExpr>(E))
+    return getDeclFromExpr(CE->getSubExpr());
+  if (ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
+    return OME->getMethodDecl();
+
+  return 0;
+}
+
+static SourceLocation getLocationFromExpr(Expr *E) {
+  if (ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
+    return /*FIXME:*/Msg->getLeftLoc();
+  if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
+    return DRE->getLocation();
+  if (MemberExpr *Member = dyn_cast<MemberExpr>(E))
+    return Member->getMemberLoc();
+  if (ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
+    return Ivar->getLocation();
+  return E->getLocStart();
+}
+
+extern "C" {
+
+unsigned clang_visitChildren(CXCursor parent,
+                             CXCursorVisitor visitor,
+                             CXClientData client_data) {
+  ASTUnit *CXXUnit = getCursorASTUnit(parent);
+
+  unsigned PCHLevel = Decl::MaxPCHLevel;
+
+  // Set the PCHLevel to filter out unwanted decls if requested.
+  if (CXXUnit->getOnlyLocalDecls()) {
+    PCHLevel = 0;
+
+    // If the main input was an AST, bump the level.
+    if (CXXUnit->isMainFileAST())
+      ++PCHLevel;
+  }
+
+  CursorVisitor CursorVis(CXXUnit, visitor, client_data, PCHLevel);
+  return CursorVis.VisitChildren(parent);
+}
+
+static CXString getDeclSpelling(Decl *D) {
+  NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D);
+  if (!ND)
+    return createCXString("");
+
+  if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
+    return createCXString(OMD->getSelector().getAsString());
+
+  if (ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
+    // No, this isn't the same as the code below. getIdentifier() is non-virtual
+    // and returns different names. NamedDecl returns the class name and
+    // ObjCCategoryImplDecl returns the category name.
+    return createCXString(CIMP->getIdentifier()->getNameStart());
+
+  if (ND->getIdentifier())
+    return createCXString(ND->getIdentifier()->getNameStart());
+
+  return createCXString("");
+}
+
+CXString clang_getCursorSpelling(CXCursor C) {
+  if (clang_isTranslationUnit(C.kind))
+    return clang_getTranslationUnitSpelling(C.data[2]);
+
+  if (clang_isReference(C.kind)) {
+    switch (C.kind) {
+    case CXCursor_ObjCSuperClassRef: {
+      ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
+      return createCXString(Super->getIdentifier()->getNameStart());
+    }
+    case CXCursor_ObjCClassRef: {
+      ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
+      return createCXString(Class->getIdentifier()->getNameStart());
+    }
+    case CXCursor_ObjCProtocolRef: {
+      ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
+      assert(OID && "getCursorSpelling(): Missing protocol decl");
+      return createCXString(OID->getIdentifier()->getNameStart());
+    }
+    case CXCursor_TypeRef: {
+      TypeDecl *Type = getCursorTypeRef(C).first;
+      assert(Type && "Missing type decl");
+
+      return createCXString(getCursorContext(C).getTypeDeclType(Type).
+                              getAsString());
+    }
+
+    default:
+      return createCXString("<not implemented>");
+    }
+  }
+
+  if (clang_isExpression(C.kind)) {
+    Decl *D = getDeclFromExpr(getCursorExpr(C));
+    if (D)
+      return getDeclSpelling(D);
+    return createCXString("");
+  }
+
+  if (C.kind == CXCursor_MacroInstantiation)
+    return createCXString(getCursorMacroInstantiation(C)->getName()
+                                                           ->getNameStart());
+
+  if (C.kind == CXCursor_MacroDefinition)
+    return createCXString(getCursorMacroDefinition(C)->getName()
+                                                           ->getNameStart());
+
+  if (clang_isDeclaration(C.kind))
+    return getDeclSpelling(getCursorDecl(C));
+
+  return createCXString("");
+}
+
+CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
+  switch (Kind) {
+  case CXCursor_FunctionDecl:
+      return createCXString("FunctionDecl");
+  case CXCursor_TypedefDecl:
+      return createCXString("TypedefDecl");
+  case CXCursor_EnumDecl:
+      return createCXString("EnumDecl");
+  case CXCursor_EnumConstantDecl:
+      return createCXString("EnumConstantDecl");
+  case CXCursor_StructDecl:
+      return createCXString("StructDecl");
+  case CXCursor_UnionDecl:
+      return createCXString("UnionDecl");
+  case CXCursor_ClassDecl:
+      return createCXString("ClassDecl");
+  case CXCursor_FieldDecl:
+      return createCXString("FieldDecl");
+  case CXCursor_VarDecl:
+      return createCXString("VarDecl");
+  case CXCursor_ParmDecl:
+      return createCXString("ParmDecl");
+  case CXCursor_ObjCInterfaceDecl:
+      return createCXString("ObjCInterfaceDecl");
+  case CXCursor_ObjCCategoryDecl:
+      return createCXString("ObjCCategoryDecl");
+  case CXCursor_ObjCProtocolDecl:
+      return createCXString("ObjCProtocolDecl");
+  case CXCursor_ObjCPropertyDecl:
+      return createCXString("ObjCPropertyDecl");
+  case CXCursor_ObjCIvarDecl:
+      return createCXString("ObjCIvarDecl");
+  case CXCursor_ObjCInstanceMethodDecl:
+      return createCXString("ObjCInstanceMethodDecl");
+  case CXCursor_ObjCClassMethodDecl:
+      return createCXString("ObjCClassMethodDecl");
+  case CXCursor_ObjCImplementationDecl:
+      return createCXString("ObjCImplementationDecl");
+  case CXCursor_ObjCCategoryImplDecl:
+      return createCXString("ObjCCategoryImplDecl");
+  case CXCursor_CXXMethod:
+      return createCXString("CXXMethod");
+  case CXCursor_UnexposedDecl:
+      return createCXString("UnexposedDecl");
+  case CXCursor_ObjCSuperClassRef:
+      return createCXString("ObjCSuperClassRef");
+  case CXCursor_ObjCProtocolRef:
+      return createCXString("ObjCProtocolRef");
+  case CXCursor_ObjCClassRef:
+      return createCXString("ObjCClassRef");
+  case CXCursor_TypeRef:
+      return createCXString("TypeRef");
+  case CXCursor_UnexposedExpr:
+      return createCXString("UnexposedExpr");
+  case CXCursor_BlockExpr:
+      return createCXString("BlockExpr");
+  case CXCursor_DeclRefExpr:
+      return createCXString("DeclRefExpr");
+  case CXCursor_MemberRefExpr:
+      return createCXString("MemberRefExpr");
+  case CXCursor_CallExpr:
+      return createCXString("CallExpr");
+  case CXCursor_ObjCMessageExpr:
+      return createCXString("ObjCMessageExpr");
+  case CXCursor_UnexposedStmt:
+      return createCXString("UnexposedStmt");
+  case CXCursor_InvalidFile:
+      return createCXString("InvalidFile");
+  case CXCursor_InvalidCode:
+    return createCXString("InvalidCode");
+  case CXCursor_NoDeclFound:
+      return createCXString("NoDeclFound");
+  case CXCursor_NotImplemented:
+      return createCXString("NotImplemented");
+  case CXCursor_TranslationUnit:
+      return createCXString("TranslationUnit");
+  case CXCursor_UnexposedAttr:
+      return createCXString("UnexposedAttr");
+  case CXCursor_IBActionAttr:
+      return createCXString("attribute(ibaction)");
+  case CXCursor_IBOutletAttr:
+     return createCXString("attribute(iboutlet)");
+  case CXCursor_PreprocessingDirective:
+    return createCXString("preprocessing directive");
+  case CXCursor_MacroDefinition:
+    return createCXString("macro definition");
+  case CXCursor_MacroInstantiation:
+    return createCXString("macro instantiation");
+  }
+
+  llvm_unreachable("Unhandled CXCursorKind");
+  return createCXString(NULL);
+}
+
+enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
+                                         CXCursor parent,
+                                         CXClientData client_data) {
+  CXCursor *BestCursor = static_cast<CXCursor *>(client_data);
+  *BestCursor = cursor;
+  return CXChildVisit_Recurse;
+}
+
+CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
+  if (!TU)
+    return clang_getNullCursor();
+
+  ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU);
+
+  ASTUnit::ConcurrencyCheck Check(*CXXUnit);
+
+  SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
+  CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
+  if (SLoc.isValid()) {
+    SourceRange RegionOfInterest(SLoc, SLoc.getFileLocWithOffset(1));
+
+    // FIXME: Would be great to have a "hint" cursor, then walk from that
+    // hint cursor upward until we find a cursor whose source range encloses
+    // the region of interest, rather than starting from the translation unit.
+    CXCursor Parent = clang_getTranslationUnitCursor(CXXUnit);
+    CursorVisitor CursorVis(CXXUnit, GetCursorVisitor, &Result,
+                            Decl::MaxPCHLevel, RegionOfInterest);
+    CursorVis.VisitChildren(Parent);
+  }
+  return Result;
+}
+
+CXCursor clang_getNullCursor(void) {
+  return MakeCXCursorInvalid(CXCursor_InvalidFile);
+}
+
+unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
+  return X == Y;
+}
+
+unsigned clang_isInvalid(enum CXCursorKind K) {
+  return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
+}
+
+unsigned clang_isDeclaration(enum CXCursorKind K) {
+  return K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl;
+}
+
+unsigned clang_isReference(enum CXCursorKind K) {
+  return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
+}
+
+unsigned clang_isExpression(enum CXCursorKind K) {
+  return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
+}
+
+unsigned clang_isStatement(enum CXCursorKind K) {
+  return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
+}
+
+unsigned clang_isTranslationUnit(enum CXCursorKind K) {
+  return K == CXCursor_TranslationUnit;
+}
+
+unsigned clang_isPreprocessing(enum CXCursorKind K) {
+  return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
+}
+  
+unsigned clang_isUnexposed(enum CXCursorKind K) {
+  switch (K) {
+    case CXCursor_UnexposedDecl:
+    case CXCursor_UnexposedExpr:
+    case CXCursor_UnexposedStmt:
+    case CXCursor_UnexposedAttr:
+      return true;
+    default:
+      return false;
+  }
+}
+
+CXCursorKind clang_getCursorKind(CXCursor C) {
+  return C.kind;
+}
+
+CXSourceLocation clang_getCursorLocation(CXCursor C) {
+  if (clang_isReference(C.kind)) {
+    switch (C.kind) {
+    case CXCursor_ObjCSuperClassRef: {
+      std::pair<ObjCInterfaceDecl *, SourceLocation> P
+        = getCursorObjCSuperClassRef(C);
+      return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
+    }
+
+    case CXCursor_ObjCProtocolRef: {
+      std::pair<ObjCProtocolDecl *, SourceLocation> P
+        = getCursorObjCProtocolRef(C);
+      return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
+    }
+
+    case CXCursor_ObjCClassRef: {
+      std::pair<ObjCInterfaceDecl *, SourceLocation> P
+        = getCursorObjCClassRef(C);
+      return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
+    }
+
+    case CXCursor_TypeRef: {
+      std::pair<TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
+      return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
+    }
+
+    default:
+      // FIXME: Need a way to enumerate all non-reference cases.
+      llvm_unreachable("Missed a reference kind");
+    }
+  }
+
+  if (clang_isExpression(C.kind))
+    return cxloc::translateSourceLocation(getCursorContext(C),
+                                   getLocationFromExpr(getCursorExpr(C)));
+
+  if (C.kind == CXCursor_PreprocessingDirective) {
+    SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
+    return cxloc::translateSourceLocation(getCursorContext(C), L);
+  }
+
+  if (C.kind == CXCursor_MacroInstantiation) {
+    SourceLocation L
+      = cxcursor::getCursorMacroInstantiation(C)->getSourceRange().getBegin();
+    return cxloc::translateSourceLocation(getCursorContext(C), L);
+  }
+
+  if (C.kind == CXCursor_MacroDefinition) {
+    SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
+    return cxloc::translateSourceLocation(getCursorContext(C), L);
+  }
+  
+  if (!getCursorDecl(C))
+    return clang_getNullLocation();
+
+  Decl *D = getCursorDecl(C);
+  SourceLocation Loc = D->getLocation();
+  if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(D))
+    Loc = Class->getClassLoc();
+  return cxloc::translateSourceLocation(getCursorContext(C), Loc);
+}
+
+CXSourceRange clang_getCursorExtent(CXCursor C) {
+  if (clang_isReference(C.kind)) {
+    switch (C.kind) {
+      case CXCursor_ObjCSuperClassRef: {
+        std::pair<ObjCInterfaceDecl *, SourceLocation> P
+          = getCursorObjCSuperClassRef(C);
+        return cxloc::translateSourceRange(P.first->getASTContext(), P.second);
+      }
+
+      case CXCursor_ObjCProtocolRef: {
+        std::pair<ObjCProtocolDecl *, SourceLocation> P
+          = getCursorObjCProtocolRef(C);
+        return cxloc::translateSourceRange(P.first->getASTContext(), P.second);
+      }
+
+      case CXCursor_ObjCClassRef: {
+        std::pair<ObjCInterfaceDecl *, SourceLocation> P
+          = getCursorObjCClassRef(C);
+
+        return cxloc::translateSourceRange(P.first->getASTContext(), P.second);
+      }
+
+      case CXCursor_TypeRef: {
+        std::pair<TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
+        return cxloc::translateSourceRange(P.first->getASTContext(), P.second);
+      }
+
+      default:
+        // FIXME: Need a way to enumerate all non-reference cases.
+        llvm_unreachable("Missed a reference kind");
+    }
+  }
+
+  if (clang_isExpression(C.kind))
+    return cxloc::translateSourceRange(getCursorContext(C),
+                                getCursorExpr(C)->getSourceRange());
+
+  if (clang_isStatement(C.kind))
+    return cxloc::translateSourceRange(getCursorContext(C),
+                                getCursorStmt(C)->getSourceRange());
+
+  if (C.kind == CXCursor_PreprocessingDirective) {
+    SourceRange R = cxcursor::getCursorPreprocessingDirective(C);
+    return cxloc::translateSourceRange(getCursorContext(C), R);
+  }
+
+  if (C.kind == CXCursor_MacroInstantiation) {
+    SourceRange R = cxcursor::getCursorMacroInstantiation(C)->getSourceRange();
+    return cxloc::translateSourceRange(getCursorContext(C), R);
+  }
+
+  if (C.kind == CXCursor_MacroDefinition) {
+    SourceRange R = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
+    return cxloc::translateSourceRange(getCursorContext(C), R);
+  }
+  
+  if (!getCursorDecl(C))
+    return clang_getNullRange();
+
+  Decl *D = getCursorDecl(C);
+  return cxloc::translateSourceRange(getCursorContext(C), D->getSourceRange());
+}
+
+CXCursor clang_getCursorReferenced(CXCursor C) {
+  if (clang_isInvalid(C.kind))
+    return clang_getNullCursor();
+
+  ASTUnit *CXXUnit = getCursorASTUnit(C);
+  if (clang_isDeclaration(C.kind))
+    return C;
+
+  if (clang_isExpression(C.kind)) {
+    Decl *D = getDeclFromExpr(getCursorExpr(C));
+    if (D)
+      return MakeCXCursor(D, CXXUnit);
+    return clang_getNullCursor();
+  }
+
+  if (C.kind == CXCursor_MacroInstantiation) {
+    if (MacroDefinition *Def = getCursorMacroInstantiation(C)->getDefinition())
+      return MakeMacroDefinitionCursor(Def, CXXUnit);
+  }
+
+  if (!clang_isReference(C.kind))
+    return clang_getNullCursor();
+
+  switch (C.kind) {
+    case CXCursor_ObjCSuperClassRef:
+      return MakeCXCursor(getCursorObjCSuperClassRef(C).first, CXXUnit);
+
+    case CXCursor_ObjCProtocolRef: {
+      return MakeCXCursor(getCursorObjCProtocolRef(C).first, CXXUnit);
+
+    case CXCursor_ObjCClassRef:
+      return MakeCXCursor(getCursorObjCClassRef(C).first, CXXUnit);
+
+    case CXCursor_TypeRef:
+      return MakeCXCursor(getCursorTypeRef(C).first, CXXUnit);
+
+    default:
+      // We would prefer to enumerate all non-reference cursor kinds here.
+      llvm_unreachable("Unhandled reference cursor kind");
+      break;
+    }
+  }
+
+  return clang_getNullCursor();
+}
+
+CXCursor clang_getCursorDefinition(CXCursor C) {
+  if (clang_isInvalid(C.kind))
+    return clang_getNullCursor();
+
+  ASTUnit *CXXUnit = getCursorASTUnit(C);
+
+  bool WasReference = false;
+  if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
+    C = clang_getCursorReferenced(C);
+    WasReference = true;
+  }
+
+  if (C.kind == CXCursor_MacroInstantiation)
+    return clang_getCursorReferenced(C);
+
+  if (!clang_isDeclaration(C.kind))
+    return clang_getNullCursor();
+
+  Decl *D = getCursorDecl(C);
+  if (!D)
+    return clang_getNullCursor();
+
+  switch (D->getKind()) {
+  // Declaration kinds that don't really separate the notions of
+  // declaration and definition.
+  case Decl::Namespace:
+  case Decl::Typedef:
+  case Decl::TemplateTypeParm:
+  case Decl::EnumConstant:
+  case Decl::Field:
+  case Decl::ObjCIvar:
+  case Decl::ObjCAtDefsField:
+  case Decl::ImplicitParam:
+  case Decl::ParmVar:
+  case Decl::NonTypeTemplateParm:
+  case Decl::TemplateTemplateParm:
+  case Decl::ObjCCategoryImpl:
+  case Decl::ObjCImplementation:
+  case Decl::LinkageSpec:
+  case Decl::ObjCPropertyImpl:
+  case Decl::FileScopeAsm:
+  case Decl::StaticAssert:
+  case Decl::Block:
+    return C;
+
+  // Declaration kinds that don't make any sense here, but are
+  // nonetheless harmless.
+  case Decl::TranslationUnit:
+    break;
+
+  // Declaration kinds for which the definition is not resolvable.
+  case Decl::UnresolvedUsingTypename:
+  case Decl::UnresolvedUsingValue:
+    break;
+
+  case Decl::UsingDirective:
+    return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
+                        CXXUnit);
+
+  case Decl::NamespaceAlias:
+    return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), CXXUnit);
+
+  case Decl::Enum:
+  case Decl::Record:
+  case Decl::CXXRecord:
+  case Decl::ClassTemplateSpecialization:
+  case Decl::ClassTemplatePartialSpecialization:
+    if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
+      return MakeCXCursor(Def, CXXUnit);
+    return clang_getNullCursor();
+
+  case Decl::Function:
+  case Decl::CXXMethod:
+  case Decl::CXXConstructor:
+  case Decl::CXXDestructor:
+  case Decl::CXXConversion: {
+    const FunctionDecl *Def = 0;
+    if (cast<FunctionDecl>(D)->getBody(Def))
+      return MakeCXCursor(const_cast<FunctionDecl *>(Def), CXXUnit);
+    return clang_getNullCursor();
+  }
+
+  case Decl::Var: {
+    // Ask the variable if it has a definition.
+    if (VarDecl *Def = cast<VarDecl>(D)->getDefinition())
+      return MakeCXCursor(Def, CXXUnit);
+    return clang_getNullCursor();
+  }
+
+  case Decl::FunctionTemplate: {
+    const FunctionDecl *Def = 0;
+    if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
+      return MakeCXCursor(Def->getDescribedFunctionTemplate(), CXXUnit);
+    return clang_getNullCursor();
+  }
+
+  case Decl::ClassTemplate: {
+    if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
+                                                            ->getDefinition())
+      return MakeCXCursor(
+                         cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
+                          CXXUnit);
+    return clang_getNullCursor();
+  }
+
+  case Decl::Using: {
+    UsingDecl *Using = cast<UsingDecl>(D);
+    CXCursor Def = clang_getNullCursor();
+    for (UsingDecl::shadow_iterator S = Using->shadow_begin(),
+                                 SEnd = Using->shadow_end();
+         S != SEnd; ++S) {
+      if (Def != clang_getNullCursor()) {
+        // FIXME: We have no way to return multiple results.
+        return clang_getNullCursor();
+      }
+
+      Def = clang_getCursorDefinition(MakeCXCursor((*S)->getTargetDecl(),
+                                                   CXXUnit));
+    }
+
+    return Def;
+  }
+
+  case Decl::UsingShadow:
+    return clang_getCursorDefinition(
+                       MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
+                                    CXXUnit));
+
+  case Decl::ObjCMethod: {
+    ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
+    if (Method->isThisDeclarationADefinition())
+      return C;
+
+    // Dig out the method definition in the associated
+    // @implementation, if we have it.
+    // FIXME: The ASTs should make finding the definition easier.
+    if (ObjCInterfaceDecl *Class
+                       = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
+      if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
+        if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
+                                                  Method->isInstanceMethod()))
+          if (Def->isThisDeclarationADefinition())
+            return MakeCXCursor(Def, CXXUnit);
+
+    return clang_getNullCursor();
+  }
+
+  case Decl::ObjCCategory:
+    if (ObjCCategoryImplDecl *Impl
+                               = cast<ObjCCategoryDecl>(D)->getImplementation())
+      return MakeCXCursor(Impl, CXXUnit);
+    return clang_getNullCursor();
+
+  case Decl::ObjCProtocol:
+    if (!cast<ObjCProtocolDecl>(D)->isForwardDecl())
+      return C;
+    return clang_getNullCursor();
+
+  case Decl::ObjCInterface:
+    // There are two notions of a "definition" for an Objective-C
+    // class: the interface and its implementation. When we resolved a
+    // reference to an Objective-C class, produce the @interface as
+    // the definition; when we were provided with the interface,
+    // produce the @implementation as the definition.
+    if (WasReference) {
+      if (!cast<ObjCInterfaceDecl>(D)->isForwardDecl())
+        return C;
+    } else if (ObjCImplementationDecl *Impl
+                              = cast<ObjCInterfaceDecl>(D)->getImplementation())
+      return MakeCXCursor(Impl, CXXUnit);
+    return clang_getNullCursor();
+
+  case Decl::ObjCProperty:
+    // FIXME: We don't really know where to find the
+    // ObjCPropertyImplDecls that implement this property.
+    return clang_getNullCursor();
+
+  case Decl::ObjCCompatibleAlias:
+    if (ObjCInterfaceDecl *Class
+          = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
+      if (!Class->isForwardDecl())
+        return MakeCXCursor(Class, CXXUnit);
+
+    return clang_getNullCursor();
+
+  case Decl::ObjCForwardProtocol: {
+    ObjCForwardProtocolDecl *Forward = cast<ObjCForwardProtocolDecl>(D);
+    if (Forward->protocol_size() == 1)
+      return clang_getCursorDefinition(
+                                     MakeCXCursor(*Forward->protocol_begin(),
+                                                  CXXUnit));
+
+    // FIXME: Cannot return multiple definitions.
+    return clang_getNullCursor();
+  }
+
+  case Decl::ObjCClass: {
+    ObjCClassDecl *Class = cast<ObjCClassDecl>(D);
+    if (Class->size() == 1) {
+      ObjCInterfaceDecl *IFace = Class->begin()->getInterface();
+      if (!IFace->isForwardDecl())
+        return MakeCXCursor(IFace, CXXUnit);
+      return clang_getNullCursor();
+    }
+
+    // FIXME: Cannot return multiple definitions.
+    return clang_getNullCursor();
+  }
+
+  case Decl::Friend:
+    if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
+      return clang_getCursorDefinition(MakeCXCursor(Friend, CXXUnit));
+    return clang_getNullCursor();
+
+  case Decl::FriendTemplate:
+    if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
+      return clang_getCursorDefinition(MakeCXCursor(Friend, CXXUnit));
+    return clang_getNullCursor();
+  }
+
+  return clang_getNullCursor();
+}
+
+unsigned clang_isCursorDefinition(CXCursor C) {
+  if (!clang_isDeclaration(C.kind))
+    return 0;
+
+  return clang_getCursorDefinition(C) == C;
+}
+
+void clang_getDefinitionSpellingAndExtent(CXCursor C,
+                                          const char **startBuf,
+                                          const char **endBuf,
+                                          unsigned *startLine,
+                                          unsigned *startColumn,
+                                          unsigned *endLine,
+                                          unsigned *endColumn) {
+  assert(getCursorDecl(C) && "CXCursor has null decl");
+  NamedDecl *ND = static_cast<NamedDecl *>(getCursorDecl(C));
+  FunctionDecl *FD = dyn_cast<FunctionDecl>(ND);
+  CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
+
+  SourceManager &SM = FD->getASTContext().getSourceManager();
+  *startBuf = SM.getCharacterData(Body->getLBracLoc());
+  *endBuf = SM.getCharacterData(Body->getRBracLoc());
+  *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
+  *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
+  *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
+  *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
+}
+
+void clang_enableStackTraces(void) {
+  llvm::sys::PrintStackTraceOnErrorSignal();
+}
+
+} // end: extern "C"
+
+//===----------------------------------------------------------------------===//
+// Token-based Operations.
+//===----------------------------------------------------------------------===//
+
+/* CXToken layout:
+ *   int_data[0]: a CXTokenKind
+ *   int_data[1]: starting token location
+ *   int_data[2]: token length
+ *   int_data[3]: reserved
+ *   ptr_data: for identifiers and keywords, an IdentifierInfo*.
+ *   otherwise unused.
+ */
+extern "C" {
+
+CXTokenKind clang_getTokenKind(CXToken CXTok) {
+  return static_cast<CXTokenKind>(CXTok.int_data[0]);
+}
+
+CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
+  switch (clang_getTokenKind(CXTok)) {
+  case CXToken_Identifier:
+  case CXToken_Keyword:
+    // We know we have an IdentifierInfo*, so use that.
+    return createCXString(static_cast<IdentifierInfo *>(CXTok.ptr_data)
+                            ->getNameStart());
+
+  case CXToken_Literal: {
+    // We have stashed the starting pointer in the ptr_data field. Use it.
+    const char *Text = static_cast<const char *>(CXTok.ptr_data);
+    return createCXString(llvm::StringRef(Text, CXTok.int_data[2]));
+  }
+
+  case CXToken_Punctuation:
+  case CXToken_Comment:
+    break;
+  }
+
+  // We have to find the starting buffer pointer the hard way, by
+  // deconstructing the source location.
+  ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU);
+  if (!CXXUnit)
+    return createCXString("");
+
+  SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
+  std::pair<FileID, unsigned> LocInfo
+    = CXXUnit->getSourceManager().getDecomposedLoc(Loc);
+  bool Invalid = false;
+  llvm::StringRef Buffer
+    = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
+  if (Invalid)
+    return createCXString("");
+
+  return createCXString(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
+}
+
+CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
+  ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU);
+  if (!CXXUnit)
+    return clang_getNullLocation();
+
+  return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
+                        SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
+}
+
+CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
+  ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU);
+  if (!CXXUnit)
+    return clang_getNullRange();
+
+  return cxloc::translateSourceRange(CXXUnit->getASTContext(),
+                        SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
+}
+
+void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
+                    CXToken **Tokens, unsigned *NumTokens) {
+  if (Tokens)
+    *Tokens = 0;
+  if (NumTokens)
+    *NumTokens = 0;
+
+  ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU);
+  if (!CXXUnit || !Tokens || !NumTokens)
+    return;
+
+  ASTUnit::ConcurrencyCheck Check(*CXXUnit);
+  
+  SourceRange R = cxloc::translateCXSourceRange(Range);
+  if (R.isInvalid())
+    return;
+
+  SourceManager &SourceMgr = CXXUnit->getSourceManager();
+  std::pair<FileID, unsigned> BeginLocInfo
+    = SourceMgr.getDecomposedLoc(R.getBegin());
+  std::pair<FileID, unsigned> EndLocInfo
+    = SourceMgr.getDecomposedLoc(R.getEnd());
+
+  // Cannot tokenize across files.
+  if (BeginLocInfo.first != EndLocInfo.first)
+    return;
+
+  // Create a lexer
+  bool Invalid = false;
+  llvm::StringRef Buffer
+    = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
+  if (Invalid)
+    return;
+  
+  Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
+            CXXUnit->getASTContext().getLangOptions(),
+            Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
+  Lex.SetCommentRetentionState(true);
+
+  // Lex tokens until we hit the end of the range.
+  const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
+  llvm::SmallVector<CXToken, 32> CXTokens;
+  Token Tok;
+  do {
+    // Lex the next token
+    Lex.LexFromRawLexer(Tok);
+    if (Tok.is(tok::eof))
+      break;
+
+    // Initialize the CXToken.
+    CXToken CXTok;
+
+    //   - Common fields
+    CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
+    CXTok.int_data[2] = Tok.getLength();
+    CXTok.int_data[3] = 0;
+
+    //   - Kind-specific fields
+    if (Tok.isLiteral()) {
+      CXTok.int_data[0] = CXToken_Literal;
+      CXTok.ptr_data = (void *)Tok.getLiteralData();
+    } else if (Tok.is(tok::identifier)) {
+      // Lookup the identifier to determine whether we have a keyword.
+      std::pair<FileID, unsigned> LocInfo
+        = SourceMgr.getDecomposedLoc(Tok.getLocation());
+      bool Invalid = false;
+      llvm::StringRef Buf
+        = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
+      if (Invalid)
+        return;
+      
+      const char *StartPos = Buf.data() + LocInfo.second;
+      IdentifierInfo *II
+        = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok, StartPos);
+      CXTok.int_data[0] = II->getTokenID() == tok::identifier?
+                               CXToken_Identifier
+                             : CXToken_Keyword;
+      CXTok.ptr_data = II;
+    } else if (Tok.is(tok::comment)) {
+      CXTok.int_data[0] = CXToken_Comment;
+      CXTok.ptr_data = 0;
+    } else {
+      CXTok.int_data[0] = CXToken_Punctuation;
+      CXTok.ptr_data = 0;
+    }
+    CXTokens.push_back(CXTok);
+  } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
+
+  if (CXTokens.empty())
+    return;
+
+  *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
+  memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
+  *NumTokens = CXTokens.size();
+}
+
+typedef llvm::DenseMap<unsigned, CXCursor> AnnotateTokensData;
+
+enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
+                                              CXCursor parent,
+                                              CXClientData client_data) {
+  AnnotateTokensData *Data = static_cast<AnnotateTokensData *>(client_data);
+
+  // We only annotate the locations of declarations, simple
+  // references, and expressions which directly reference something.
+  CXCursorKind Kind = clang_getCursorKind(cursor);
+  if (clang_isDeclaration(Kind) || clang_isReference(Kind)) {
+    // Okay: We can annotate the location of this declaration with the
+    // declaration or reference
+  } else if (clang_isExpression(cursor.kind)) {
+    if (Kind != CXCursor_DeclRefExpr &&
+        Kind != CXCursor_MemberRefExpr &&
+        Kind != CXCursor_ObjCMessageExpr)
+      return CXChildVisit_Recurse;
+
+    CXCursor Referenced = clang_getCursorReferenced(cursor);
+    if (Referenced == cursor || Referenced == clang_getNullCursor())
+      return CXChildVisit_Recurse;
+
+    // Okay: we can annotate the location of this expression
+  } else if (clang_isPreprocessing(cursor.kind)) {
+    // We can always annotate a preprocessing directive/macro instantiation.
+  } else {
+    // Nothing to annotate
+    return CXChildVisit_Recurse;
+  }
+
+  CXSourceLocation Loc = clang_getCursorLocation(cursor);
+  (*Data)[Loc.int_data] = cursor;
+  return CXChildVisit_Recurse;
+}
+
+void clang_annotateTokens(CXTranslationUnit TU,
+                          CXToken *Tokens, unsigned NumTokens,
+                          CXCursor *Cursors) {
+  if (NumTokens == 0)
+    return;
+
+  // Any token we don't specifically annotate will have a NULL cursor.
+  for (unsigned I = 0; I != NumTokens; ++I)
+    Cursors[I] = clang_getNullCursor();
+
+  ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU);
+  if (!CXXUnit || !Tokens)
+    return;
+
+  ASTUnit::ConcurrencyCheck Check(*CXXUnit);
+
+  // Determine the region of interest, which contains all of the tokens.
+  SourceRange RegionOfInterest;
+  RegionOfInterest.setBegin(
+        cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
+  SourceLocation End
+    = cxloc::translateSourceLocation(clang_getTokenLocation(TU,
+                                                        Tokens[NumTokens - 1]));
+  RegionOfInterest.setEnd(CXXUnit->getPreprocessor().getLocForEndOfToken(End));
+
+  // A mapping from the source locations found when re-lexing or traversing the
+  // region of interest to the corresponding cursors.
+  AnnotateTokensData Annotated;
+
+  // Relex the tokens within the source range to look for preprocessing 
+  // directives.
+  SourceManager &SourceMgr = CXXUnit->getSourceManager();
+  std::pair<FileID, unsigned> BeginLocInfo
+    = SourceMgr.getDecomposedLoc(RegionOfInterest.getBegin());
+  std::pair<FileID, unsigned> EndLocInfo
+    = SourceMgr.getDecomposedLoc(RegionOfInterest.getEnd());
+  
+  llvm::StringRef Buffer;
+  bool Invalid = false;
+  if (BeginLocInfo.first == EndLocInfo.first &&
+      ((Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid)),true) &&
+      !Invalid) {
+    Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
+              CXXUnit->getASTContext().getLangOptions(),
+              Buffer.begin(), Buffer.data() + BeginLocInfo.second, 
+              Buffer.end());
+    Lex.SetCommentRetentionState(true);
+    
+    // Lex tokens in raw mode until we hit the end of the range, to avoid 
+    // entering #includes or expanding macros.
+    while (true) {
+      Token Tok;
+      Lex.LexFromRawLexer(Tok);
+      
+    reprocess:
+      if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
+        // We have found a preprocessing directive. Gobble it up so that we
+        // don't see it while preprocessing these tokens later, but keep track of
+        // all of the token locations inside this preprocessing directive so that
+        // we can annotate them appropriately.
+        //
+        // FIXME: Some simple tests here could identify macro definitions and
+        // #undefs, to provide specific cursor kinds for those.
+        std::vector<SourceLocation> Locations;
+        do {
+          Locations.push_back(Tok.getLocation());
+          Lex.LexFromRawLexer(Tok);        
+        } while (!Tok.isAtStartOfLine() && !Tok.is(tok::eof));
+        
+        using namespace cxcursor;
+        CXCursor Cursor
+          = MakePreprocessingDirectiveCursor(SourceRange(Locations.front(),
+                                                         Locations.back()),
+                                             CXXUnit);
+        for (unsigned I = 0, N = Locations.size(); I != N; ++I) {
+          Annotated[Locations[I].getRawEncoding()] = Cursor;
+        }
+        
+        if (Tok.isAtStartOfLine())
+          goto reprocess;
+        
+        continue;
+      }
+      
+      if (Tok.is(tok::eof))
+        break;
+    }
+  }
+  
+  // Annotate all of the source locations in the region of interest that map to
+  // a specific cursor.  
+  CXCursor Parent = clang_getTranslationUnitCursor(CXXUnit);
+  CursorVisitor AnnotateVis(CXXUnit, AnnotateTokensVisitor, &Annotated,
+                            Decl::MaxPCHLevel, RegionOfInterest);
+  AnnotateVis.VisitChildren(Parent);
+  
+  for (unsigned I = 0; I != NumTokens; ++I) {
+    // Determine whether we saw a cursor at this token's location.
+    AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]);
+    if (Pos == Annotated.end())
+      continue;
+    
+    Cursors[I] = Pos->second;
+  }  
+}
+
+void clang_disposeTokens(CXTranslationUnit TU,
+                         CXToken *Tokens, unsigned NumTokens) {
+  free(Tokens);
+}
+
+} // end: extern "C"
+
+//===----------------------------------------------------------------------===//
+// Operations for querying linkage of a cursor.
+//===----------------------------------------------------------------------===//
+
+extern "C" {
+CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
+  if (!clang_isDeclaration(cursor.kind))
+    return CXLinkage_Invalid;
+
+  Decl *D = cxcursor::getCursorDecl(cursor);
+  if (NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
+    switch (ND->getLinkage()) {
+      case NoLinkage: return CXLinkage_NoLinkage;
+      case InternalLinkage: return CXLinkage_Internal;
+      case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
+      case ExternalLinkage: return CXLinkage_External;
+    };
+
+  return CXLinkage_Invalid;
+}
+} // end: extern "C"
+
+//===----------------------------------------------------------------------===//
+// Operations for querying language of a cursor.
+//===----------------------------------------------------------------------===//
+
+static CXLanguageKind getDeclLanguage(const Decl *D) {
+  switch (D->getKind()) {
+    default:
+      break;
+    case Decl::ImplicitParam:
+    case Decl::ObjCAtDefsField:
+    case Decl::ObjCCategory:
+    case Decl::ObjCCategoryImpl:
+    case Decl::ObjCClass:
+    case Decl::ObjCCompatibleAlias:
+    case Decl::ObjCForwardProtocol:
+    case Decl::ObjCImplementation:
+    case Decl::ObjCInterface:
+    case Decl::ObjCIvar:
+    case Decl::ObjCMethod:
+    case Decl::ObjCProperty:
+    case Decl::ObjCPropertyImpl:
+    case Decl::ObjCProtocol:
+      return CXLanguage_ObjC;
+    case Decl::CXXConstructor:
+    case Decl::CXXConversion:
+    case Decl::CXXDestructor:
+    case Decl::CXXMethod:
+    case Decl::CXXRecord:
+    case Decl::ClassTemplate:
+    case Decl::ClassTemplatePartialSpecialization:
+    case Decl::ClassTemplateSpecialization:
+    case Decl::Friend:
+    case Decl::FriendTemplate:
+    case Decl::FunctionTemplate:
+    case Decl::LinkageSpec:
+    case Decl::Namespace:
+    case Decl::NamespaceAlias:
+    case Decl::NonTypeTemplateParm:
+    case Decl::StaticAssert:
+    case Decl::TemplateTemplateParm:
+    case Decl::TemplateTypeParm:
+    case Decl::UnresolvedUsingTypename:
+    case Decl::UnresolvedUsingValue:
+    case Decl::Using:
+    case Decl::UsingDirective:
+    case Decl::UsingShadow:
+      return CXLanguage_CPlusPlus;
+  }
+
+  return CXLanguage_C;
+}
+
+extern "C" {
+CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
+  if (clang_isDeclaration(cursor.kind))
+    return getDeclLanguage(cxcursor::getCursorDecl(cursor));
+
+  return CXLanguage_Invalid;
+}
+} // end: extern "C"
+
+//===----------------------------------------------------------------------===//
+// CXString Operations.
+//===----------------------------------------------------------------------===//
+
+extern "C" {
+const char *clang_getCString(CXString string) {
+  return string.Spelling;
+}
+
+void clang_disposeString(CXString string) {
+  if (string.MustFreeString && string.Spelling)
+    free((void*)string.Spelling);
+}
+
+} // end: extern "C"
+
+namespace clang { namespace cxstring {
+CXString createCXString(const char *String, bool DupString){
+  CXString Str;
+  if (DupString) {
+    Str.Spelling = strdup(String);
+    Str.MustFreeString = 1;
+  } else {
+    Str.Spelling = String;
+    Str.MustFreeString = 0;
+  }
+  return Str;
+}
+
+CXString createCXString(llvm::StringRef String, bool DupString) {
+  CXString Result;
+  if (DupString || (!String.empty() && String.data()[String.size()] != 0)) {
+    char *Spelling = (char *)malloc(String.size() + 1);
+    memmove(Spelling, String.data(), String.size());
+    Spelling[String.size()] = 0;
+    Result.Spelling = Spelling;
+    Result.MustFreeString = 1;
+  } else {
+    Result.Spelling = String.data();
+    Result.MustFreeString = 0;
+  }
+  return Result;
+}
+}}
+
+//===----------------------------------------------------------------------===//
+// Misc. utility functions.
+//===----------------------------------------------------------------------===//
+
+extern "C" {
+
+CXString clang_getClangVersion() {
+  return createCXString(getClangFullVersion());
+}
+
+} // end: extern "C"
diff --git a/tools/CIndex/CIndex.darwin.exports b/tools/CIndex/CIndex.darwin.exports
new file mode 100644
index 0000000..b361168
--- /dev/null
+++ b/tools/CIndex/CIndex.darwin.exports
@@ -0,0 +1,81 @@
+_clang_annotateTokens
+_clang_codeComplete
+_clang_codeCompleteGetDiagnostic
+_clang_codeCompleteGetNumDiagnostics
+_clang_constructUSR_ObjCCategory
+_clang_constructUSR_ObjCClass
+_clang_constructUSR_ObjCIvar
+_clang_constructUSR_ObjCMethod
+_clang_constructUSR_ObjCProperty
+_clang_constructUSR_ObjCProtocol
+_clang_createIndex
+_clang_createTranslationUnit
+_clang_createTranslationUnitFromSourceFile
+_clang_defaultDiagnosticDisplayOptions
+_clang_disposeCodeCompleteResults
+_clang_disposeDiagnostic
+_clang_disposeIndex
+_clang_disposeString
+_clang_disposeTokens
+_clang_disposeTranslationUnit
+_clang_enableStackTraces
+_clang_equalCursors
+_clang_equalLocations
+_clang_formatDiagnostic
+_clang_getCString
+_clang_getClangVersion
+_clang_getCompletionChunkCompletionString
+_clang_getCompletionChunkKind
+_clang_getCompletionChunkText
+_clang_getCursor
+_clang_getCursorDefinition
+_clang_getCursorExtent
+_clang_getCursorKind
+_clang_getCursorKindSpelling
+_clang_getCursorLanguage
+_clang_getCursorLinkage
+_clang_getCursorLocation
+_clang_getCursorReferenced
+_clang_getCursorSpelling
+_clang_getCursorUSR
+_clang_getDefinitionSpellingAndExtent
+_clang_getDiagnostic
+_clang_getDiagnosticFixIt
+_clang_getDiagnosticLocation
+_clang_getDiagnosticNumFixIts
+_clang_getDiagnosticNumRanges
+_clang_getDiagnosticRange
+_clang_getDiagnosticSeverity
+_clang_getDiagnosticSpelling
+_clang_getFile
+_clang_getFileName
+_clang_getFileTime
+_clang_getInclusions
+_clang_getInstantiationLocation
+_clang_getLocation
+_clang_getNullCursor
+_clang_getNullLocation
+_clang_getNullRange
+_clang_getNumCompletionChunks
+_clang_getNumDiagnostics
+_clang_getRange
+_clang_getRangeEnd
+_clang_getRangeStart
+_clang_getTokenExtent
+_clang_getTokenKind
+_clang_getTokenLocation
+_clang_getTokenSpelling
+_clang_getTranslationUnitCursor
+_clang_getTranslationUnitSpelling
+_clang_isCursorDefinition
+_clang_isDeclaration
+_clang_isExpression
+_clang_isInvalid
+_clang_isPreprocessing
+_clang_isReference
+_clang_isStatement
+_clang_isTranslationUnit
+_clang_isUnexposed
+_clang_setUseExternalASTGeneration
+_clang_tokenize
+_clang_visitChildren
diff --git a/tools/CIndex/CIndex.exports b/tools/CIndex/CIndex.exports
new file mode 100644
index 0000000..991bb06
--- /dev/null
+++ b/tools/CIndex/CIndex.exports
@@ -0,0 +1,81 @@
+clang_annotateTokens
+clang_codeComplete
+clang_codeCompleteGetDiagnostic
+clang_codeCompleteGetNumDiagnostics
+clang_constructUSR_ObjCCategory
+clang_constructUSR_ObjCClass
+clang_constructUSR_ObjCIvar
+clang_constructUSR_ObjCMethod
+clang_constructUSR_ObjCProperty
+clang_constructUSR_ObjCProtocol
+clang_createIndex
+clang_createTranslationUnit
+clang_createTranslationUnitFromSourceFile
+clang_defaultDiagnosticDisplayOptions
+clang_disposeCodeCompleteResults
+clang_disposeDiagnostic
+clang_disposeIndex
+clang_disposeString
+clang_disposeTokens
+clang_disposeTranslationUnit
+clang_enableStackTraces
+clang_equalCursors
+clang_equalLocations
+clang_formatDiagnostic
+clang_getCString
+clang_getClangVersion
+clang_getCompletionChunkCompletionString
+clang_getCompletionChunkKind
+clang_getCompletionChunkText
+clang_getCursor
+clang_getCursorDefinition
+clang_getCursorExtent
+clang_getCursorKind
+clang_getCursorKindSpelling
+clang_getCursorLanguage
+clang_getCursorLinkage
+clang_getCursorLocation
+clang_getCursorReferenced
+clang_getCursorSpelling
+clang_getCursorUSR
+clang_getDefinitionSpellingAndExtent
+clang_getDiagnostic
+clang_getDiagnosticFixIt
+clang_getDiagnosticLocation
+clang_getDiagnosticNumFixIts
+clang_getDiagnosticNumRanges
+clang_getDiagnosticRange
+clang_getDiagnosticSeverity
+clang_getDiagnosticSpelling
+clang_getFile
+clang_getFileName
+clang_getFileTime
+clang_getInclusions
+clang_getInstantiationLocation
+clang_getLocation
+clang_getNullCursor
+clang_getNullLocation
+clang_getNullRange
+clang_getNumCompletionChunks
+clang_getNumDiagnostics
+clang_getRange
+clang_getRangeEnd
+clang_getRangeStart
+clang_getTokenExtent
+clang_getTokenKind
+clang_getTokenLocation
+clang_getTokenSpelling
+clang_getTranslationUnitCursor
+clang_getTranslationUnitSpelling
+clang_isCursorDefinition
+clang_isDeclaration
+clang_isExpression
+clang_isInvalid
+clang_isPreprocessing
+clang_isReference
+clang_isStatement
+clang_isTranslationUnit
+clang_isUnexposed
+clang_setUseExternalASTGeneration
+clang_tokenize
+clang_visitChildren
diff --git a/tools/CIndex/CIndexCodeCompletion.cpp b/tools/CIndex/CIndexCodeCompletion.cpp
new file mode 100644
index 0000000..a21614c
--- /dev/null
+++ b/tools/CIndex/CIndexCodeCompletion.cpp
@@ -0,0 +1,512 @@
+//===- CIndexCodeCompletion.cpp - Code Completion API hooks ---------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Clang-C Source Indexing library hooks for
+// code completion.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CIndexer.h"
+#include "CIndexDiagnostic.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Frontend/FrontendDiagnostic.h"
+#include "clang/Sema/CodeCompleteConsumer.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/System/Program.h"
+
+#ifdef UDP_CODE_COMPLETION_LOGGER
+#include "clang/Basic/Version.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/Timer.h"
+#include "llvm/Support/raw_ostream.h"
+#include <arpa/inet.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
+#endif
+
+using namespace clang;
+using namespace clang::cxstring;
+
+extern "C" {
+
+enum CXCompletionChunkKind
+clang_getCompletionChunkKind(CXCompletionString completion_string,
+                             unsigned chunk_number) {
+  CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
+  if (!CCStr || chunk_number >= CCStr->size())
+    return CXCompletionChunk_Text;
+
+  switch ((*CCStr)[chunk_number].Kind) {
+  case CodeCompletionString::CK_TypedText:
+    return CXCompletionChunk_TypedText;
+  case CodeCompletionString::CK_Text:
+    return CXCompletionChunk_Text;
+  case CodeCompletionString::CK_Optional:
+    return CXCompletionChunk_Optional;
+  case CodeCompletionString::CK_Placeholder:
+    return CXCompletionChunk_Placeholder;
+  case CodeCompletionString::CK_Informative:
+    return CXCompletionChunk_Informative;
+  case CodeCompletionString::CK_ResultType:
+    return CXCompletionChunk_ResultType;
+  case CodeCompletionString::CK_CurrentParameter:
+    return CXCompletionChunk_CurrentParameter;
+  case CodeCompletionString::CK_LeftParen:
+    return CXCompletionChunk_LeftParen;
+  case CodeCompletionString::CK_RightParen:
+    return CXCompletionChunk_RightParen;
+  case CodeCompletionString::CK_LeftBracket:
+    return CXCompletionChunk_LeftBracket;
+  case CodeCompletionString::CK_RightBracket:
+    return CXCompletionChunk_RightBracket;
+  case CodeCompletionString::CK_LeftBrace:
+    return CXCompletionChunk_LeftBrace;
+  case CodeCompletionString::CK_RightBrace:
+    return CXCompletionChunk_RightBrace;
+  case CodeCompletionString::CK_LeftAngle:
+    return CXCompletionChunk_LeftAngle;
+  case CodeCompletionString::CK_RightAngle:
+    return CXCompletionChunk_RightAngle;
+  case CodeCompletionString::CK_Comma:
+    return CXCompletionChunk_Comma;
+  case CodeCompletionString::CK_Colon:
+    return CXCompletionChunk_Colon;
+  case CodeCompletionString::CK_SemiColon:
+    return CXCompletionChunk_SemiColon;
+  case CodeCompletionString::CK_Equal:
+    return CXCompletionChunk_Equal;
+  case CodeCompletionString::CK_HorizontalSpace:
+    return CXCompletionChunk_HorizontalSpace;
+  case CodeCompletionString::CK_VerticalSpace:
+    return CXCompletionChunk_VerticalSpace;
+  }
+
+  // Should be unreachable, but let's be careful.
+  return CXCompletionChunk_Text;
+}
+
+CXString clang_getCompletionChunkText(CXCompletionString completion_string,
+                                      unsigned chunk_number) {
+  CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
+  if (!CCStr || chunk_number >= CCStr->size())
+    return createCXString(0);
+
+  switch ((*CCStr)[chunk_number].Kind) {
+  case CodeCompletionString::CK_TypedText:
+  case CodeCompletionString::CK_Text:
+  case CodeCompletionString::CK_Placeholder:
+  case CodeCompletionString::CK_CurrentParameter:
+  case CodeCompletionString::CK_Informative:
+  case CodeCompletionString::CK_LeftParen:
+  case CodeCompletionString::CK_RightParen:
+  case CodeCompletionString::CK_LeftBracket:
+  case CodeCompletionString::CK_RightBracket:
+  case CodeCompletionString::CK_LeftBrace:
+  case CodeCompletionString::CK_RightBrace:
+  case CodeCompletionString::CK_LeftAngle:
+  case CodeCompletionString::CK_RightAngle:
+  case CodeCompletionString::CK_Comma:
+  case CodeCompletionString::CK_ResultType:
+  case CodeCompletionString::CK_Colon:
+  case CodeCompletionString::CK_SemiColon:
+  case CodeCompletionString::CK_Equal:
+  case CodeCompletionString::CK_HorizontalSpace:
+  case CodeCompletionString::CK_VerticalSpace:
+    return createCXString((*CCStr)[chunk_number].Text, false);
+
+  case CodeCompletionString::CK_Optional:
+    // Note: treated as an empty text block.
+    return createCXString("");
+  }
+
+  // Should be unreachable, but let's be careful.
+  return createCXString(0);
+}
+
+
+CXCompletionString
+clang_getCompletionChunkCompletionString(CXCompletionString completion_string,
+                                         unsigned chunk_number) {
+  CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
+  if (!CCStr || chunk_number >= CCStr->size())
+    return 0;
+
+  switch ((*CCStr)[chunk_number].Kind) {
+  case CodeCompletionString::CK_TypedText:
+  case CodeCompletionString::CK_Text:
+  case CodeCompletionString::CK_Placeholder:
+  case CodeCompletionString::CK_CurrentParameter:
+  case CodeCompletionString::CK_Informative:
+  case CodeCompletionString::CK_LeftParen:
+  case CodeCompletionString::CK_RightParen:
+  case CodeCompletionString::CK_LeftBracket:
+  case CodeCompletionString::CK_RightBracket:
+  case CodeCompletionString::CK_LeftBrace:
+  case CodeCompletionString::CK_RightBrace:
+  case CodeCompletionString::CK_LeftAngle:
+  case CodeCompletionString::CK_RightAngle:
+  case CodeCompletionString::CK_Comma:
+  case CodeCompletionString::CK_ResultType:
+  case CodeCompletionString::CK_Colon:
+  case CodeCompletionString::CK_SemiColon:
+  case CodeCompletionString::CK_Equal:
+  case CodeCompletionString::CK_HorizontalSpace:
+  case CodeCompletionString::CK_VerticalSpace:
+    return 0;
+
+  case CodeCompletionString::CK_Optional:
+    // Note: treated as an empty text block.
+    return (*CCStr)[chunk_number].Optional;
+  }
+
+  // Should be unreachable, but let's be careful.
+  return 0;
+}
+
+unsigned clang_getNumCompletionChunks(CXCompletionString completion_string) {
+  CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
+  return CCStr? CCStr->size() : 0;
+}
+
+static bool ReadUnsigned(const char *&Memory, const char *MemoryEnd,
+                         unsigned &Value) {
+  if (Memory + sizeof(unsigned) > MemoryEnd)
+    return true;
+
+  memmove(&Value, Memory, sizeof(unsigned));
+  Memory += sizeof(unsigned);
+  return false;
+}
+
+/// \brief The CXCodeCompleteResults structure we allocate internally;
+/// the client only sees the initial CXCodeCompleteResults structure.
+struct AllocatedCXCodeCompleteResults : public CXCodeCompleteResults {
+  AllocatedCXCodeCompleteResults();
+  ~AllocatedCXCodeCompleteResults();
+  
+  /// \brief The memory buffer from which we parsed the results. We
+  /// retain this buffer because the completion strings point into it.
+  llvm::MemoryBuffer *Buffer;
+
+  /// \brief Diagnostics produced while performing code completion.
+  llvm::SmallVector<StoredDiagnostic, 8> Diagnostics;
+
+  /// \brief Diag object
+  Diagnostic Diag;
+  
+  /// \brief Language options used to adjust source locations.
+  LangOptions LangOpts;
+
+  /// \brief Source manager, used for diagnostics.
+  SourceManager SourceMgr;
+  
+  /// \brief File manager, used for diagnostics.
+  FileManager FileMgr;
+  
+  /// \brief Temporary files that should be removed once we have finished
+  /// with the code-completion results.
+  std::vector<llvm::sys::Path> TemporaryFiles;
+};
+
+AllocatedCXCodeCompleteResults::AllocatedCXCodeCompleteResults() 
+  : CXCodeCompleteResults(), Buffer(0), SourceMgr(Diag) { }
+  
+AllocatedCXCodeCompleteResults::~AllocatedCXCodeCompleteResults() {
+  for (unsigned I = 0, N = NumResults; I != N; ++I)
+    delete (CodeCompletionString *)Results[I].CompletionString;
+  delete [] Results;
+  delete Buffer;
+  
+  for (unsigned I = 0, N = TemporaryFiles.size(); I != N; ++I)
+    TemporaryFiles[I].eraseFromDisk();
+}
+  
+CXCodeCompleteResults *clang_codeComplete(CXIndex CIdx,
+                                          const char *source_filename,
+                                          int num_command_line_args,
+                                          const char **command_line_args,
+                                          unsigned num_unsaved_files,
+                                          struct CXUnsavedFile *unsaved_files,
+                                          const char *complete_filename,
+                                          unsigned complete_line,
+                                          unsigned complete_column) {
+#ifdef UDP_CODE_COMPLETION_LOGGER
+#ifdef UDP_CODE_COMPLETION_LOGGER_PORT
+  const llvm::TimeRecord &StartTime =  llvm::TimeRecord::getCurrentTime();
+#endif
+#endif
+
+  // The indexer, which is mainly used to determine where diagnostics go.
+  CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
+
+  // Configure the diagnostics.
+  DiagnosticOptions DiagOpts;
+  llvm::IntrusiveRefCntPtr<Diagnostic> Diags;
+  Diags = CompilerInstance::createDiagnostics(DiagOpts, 0, 0);
+  
+  // The set of temporary files that we've built.
+  std::vector<llvm::sys::Path> TemporaryFiles;
+
+  // Build up the arguments for invoking 'clang'.
+  std::vector<const char *> argv;
+
+  // First add the complete path to the 'clang' executable.
+  llvm::sys::Path ClangPath = CXXIdx->getClangPath();
+  argv.push_back(ClangPath.c_str());
+
+  // Add the '-fsyntax-only' argument so that we only perform a basic
+  // syntax check of the code.
+  argv.push_back("-fsyntax-only");
+
+  // Add the appropriate '-code-completion-at=file:line:column' argument
+  // to perform code completion, with an "-Xclang" preceding it.
+  std::string code_complete_at;
+  code_complete_at += complete_filename;
+  code_complete_at += ":";
+  code_complete_at += llvm::utostr(complete_line);
+  code_complete_at += ":";
+  code_complete_at += llvm::utostr(complete_column);
+  argv.push_back("-Xclang");
+  argv.push_back("-code-completion-at");
+  argv.push_back("-Xclang");
+  argv.push_back(code_complete_at.c_str());
+  argv.push_back("-Xclang");
+  argv.push_back("-no-code-completion-debug-printer");
+  argv.push_back("-Xclang");
+  argv.push_back("-code-completion-macros");
+  argv.push_back("-fdiagnostics-binary");
+
+  // Remap any unsaved files to temporary files.
+  std::vector<std::string> RemapArgs;
+  if (RemapFiles(num_unsaved_files, unsaved_files, RemapArgs, TemporaryFiles))
+    return 0;
+
+  // The pointers into the elements of RemapArgs are stable because we
+  // won't be adding anything to RemapArgs after this point.
+  for (unsigned i = 0, e = RemapArgs.size(); i != e; ++i)
+    argv.push_back(RemapArgs[i].c_str());
+
+  // Add the source file name (FIXME: later, we'll want to build temporary
+  // file from the buffer, or just feed the source text via standard input).
+  if (source_filename)
+    argv.push_back(source_filename);
+
+  // Process the compiler options, stripping off '-o', '-c', '-fsyntax-only'.
+  for (int i = 0; i < num_command_line_args; ++i)
+    if (const char *arg = command_line_args[i]) {
+      if (strcmp(arg, "-o") == 0) {
+        ++i; // Also skip the matching argument.
+        continue;
+      }
+      if (strcmp(arg, "-emit-ast") == 0 ||
+          strcmp(arg, "-c") == 0 ||
+          strcmp(arg, "-fsyntax-only") == 0) {
+        continue;
+      }
+
+      // Keep the argument.
+      argv.push_back(arg);
+    }
+
+  // Add the null terminator.
+  argv.push_back(NULL);
+
+  // Generate a temporary name for the code-completion results file.
+  char tmpFile[L_tmpnam];
+  char *tmpFileName = tmpnam(tmpFile);
+  llvm::sys::Path ResultsFile(tmpFileName);
+  TemporaryFiles.push_back(ResultsFile);
+
+  // Generate a temporary name for the diagnostics file.
+  char tmpFileResults[L_tmpnam];
+  char *tmpResultsFileName = tmpnam(tmpFileResults);
+  llvm::sys::Path DiagnosticsFile(tmpResultsFileName);
+  TemporaryFiles.push_back(DiagnosticsFile);
+
+  // Invoke 'clang'.
+  llvm::sys::Path DevNull; // leave empty, causes redirection to /dev/null
+                           // on Unix or NUL (Windows).
+  std::string ErrMsg;
+  const llvm::sys::Path *Redirects[] = { &DevNull, &ResultsFile, 
+                                         &DiagnosticsFile, 0 };
+  llvm::sys::Program::ExecuteAndWait(ClangPath, &argv[0], /* env */ NULL,
+                                     /* redirects */ &Redirects[0],
+                                     /* secondsToWait */ 0,
+                                     /* memoryLimits */ 0, &ErrMsg);
+
+  if (!ErrMsg.empty()) {
+    std::string AllArgs;
+    for (std::vector<const char*>::iterator I = argv.begin(), E = argv.end();
+         I != E; ++I) {
+      AllArgs += ' ';
+      if (*I)
+        AllArgs += *I;
+    }
+    
+    Diags->Report(diag::err_fe_invoking) << AllArgs << ErrMsg;
+  }
+
+  // Parse the resulting source file to find code-completion results.
+  using llvm::MemoryBuffer;
+  using llvm::StringRef;
+  AllocatedCXCodeCompleteResults *Results = new AllocatedCXCodeCompleteResults;
+  Results->Results = 0;
+  Results->NumResults = 0;
+  Results->Buffer = 0;
+  // FIXME: Set Results->LangOpts!
+  if (MemoryBuffer *F = MemoryBuffer::getFile(ResultsFile.c_str())) {
+    llvm::SmallVector<CXCompletionResult, 4> CompletionResults;
+    StringRef Buffer = F->getBuffer();
+    for (const char *Str = Buffer.data(), *StrEnd = Str + Buffer.size();
+         Str < StrEnd;) {
+      unsigned KindValue;
+      if (ReadUnsigned(Str, StrEnd, KindValue))
+        break;
+
+      CodeCompletionString *CCStr 
+        = CodeCompletionString::Deserialize(Str, StrEnd);
+      if (!CCStr)
+        continue;
+
+      if (!CCStr->empty()) {
+        // Vend the code-completion result to the caller.
+        CXCompletionResult Result;
+        Result.CursorKind = (CXCursorKind)KindValue;
+        Result.CompletionString = CCStr;
+        CompletionResults.push_back(Result);
+      }
+    };
+
+    // Allocate the results.
+    Results->Results = new CXCompletionResult [CompletionResults.size()];
+    Results->NumResults = CompletionResults.size();
+    memcpy(Results->Results, CompletionResults.data(),
+           CompletionResults.size() * sizeof(CXCompletionResult));
+    Results->Buffer = F;
+  }
+
+  LoadSerializedDiagnostics(DiagnosticsFile, num_unsaved_files, unsaved_files,
+                            Results->FileMgr, Results->SourceMgr, 
+                            Results->Diagnostics);
+
+  // Make sure we delete temporary files when the code-completion results are
+  // destroyed.
+  Results->TemporaryFiles.swap(TemporaryFiles);
+
+#ifdef UDP_CODE_COMPLETION_LOGGER
+#ifdef UDP_CODE_COMPLETION_LOGGER_PORT
+  const llvm::TimeRecord &EndTime =  llvm::TimeRecord::getCurrentTime();
+  llvm::SmallString<256> LogResult;
+  llvm::raw_svector_ostream os(LogResult);
+
+  // Figure out the language and whether or not it uses PCH.
+  const char *lang = 0;
+  bool usesPCH = false;
+
+  for (std::vector<const char*>::iterator I = argv.begin(), E = argv.end();
+       I != E; ++I) {
+    if (*I == 0)
+      continue;
+    if (strcmp(*I, "-x") == 0) {
+      if (I + 1 != E) {
+        lang = *(++I);
+        continue;
+      }
+    }
+    else if (strcmp(*I, "-include") == 0) {
+      if (I+1 != E) {
+        const char *arg = *(++I);
+        llvm::SmallString<512> pchName;
+        {
+          llvm::raw_svector_ostream os(pchName);
+          os << arg << ".pth";
+        }
+        pchName.push_back('\0');
+        struct stat stat_results;
+        if (stat(pchName.data(), &stat_results) == 0)
+          usesPCH = true;
+        continue;
+      }
+    }
+  }
+
+  os << "{ ";
+  os << "\"wall\": " << (EndTime.getWallTime() - StartTime.getWallTime());
+  os << ", \"numRes\": " << Results->NumResults;
+  os << ", \"diags\": " << Results->Diagnostics.size();
+  os << ", \"pch\": " << (usesPCH ? "true" : "false");
+  os << ", \"lang\": \"" << (lang ? lang : "<unknown>") << '"';
+  const char *name = getlogin();
+  os << ", \"user\": \"" << (name ? name : "unknown") << '"';
+  os << ", \"clangVer\": \"" << getClangFullVersion() << '"';
+  os << " }";
+
+  llvm::StringRef res = os.str();
+  if (res.size() > 0) {
+    do {
+      // Setup the UDP socket.
+      struct sockaddr_in servaddr;
+      bzero(&servaddr, sizeof(servaddr));
+      servaddr.sin_family = AF_INET;
+      servaddr.sin_port = htons(UDP_CODE_COMPLETION_LOGGER_PORT);
+      if (inet_pton(AF_INET, UDP_CODE_COMPLETION_LOGGER,
+                    &servaddr.sin_addr) <= 0)
+        break;
+
+      int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
+      if (sockfd < 0)
+        break;
+
+      sendto(sockfd, res.data(), res.size(), 0,
+             (struct sockaddr *)&servaddr, sizeof(servaddr));
+      close(sockfd);
+    }
+    while (false);
+  }
+#endif
+#endif
+  return Results;
+}
+
+void clang_disposeCodeCompleteResults(CXCodeCompleteResults *ResultsIn) {
+  if (!ResultsIn)
+    return;
+
+  AllocatedCXCodeCompleteResults *Results
+    = static_cast<AllocatedCXCodeCompleteResults*>(ResultsIn);
+  delete Results;
+}
+
+unsigned 
+clang_codeCompleteGetNumDiagnostics(CXCodeCompleteResults *ResultsIn) {
+  AllocatedCXCodeCompleteResults *Results
+    = static_cast<AllocatedCXCodeCompleteResults*>(ResultsIn);
+  if (!Results)
+    return 0;
+
+  return Results->Diagnostics.size();
+}
+
+CXDiagnostic 
+clang_codeCompleteGetDiagnostic(CXCodeCompleteResults *ResultsIn,
+                                unsigned Index) {
+  AllocatedCXCodeCompleteResults *Results
+    = static_cast<AllocatedCXCodeCompleteResults*>(ResultsIn);
+  if (!Results || Index >= Results->Diagnostics.size())
+    return 0;
+
+  return new CXStoredDiagnostic(Results->Diagnostics[Index], Results->LangOpts);
+}
+
+
+} // end extern "C"
diff --git a/tools/CIndex/CIndexDiagnostic.cpp b/tools/CIndex/CIndexDiagnostic.cpp
new file mode 100644
index 0000000..3db37b9
--- /dev/null
+++ b/tools/CIndex/CIndexDiagnostic.cpp
@@ -0,0 +1,285 @@
+/*===-- CIndexDiagnostics.cpp - Diagnostics C Interface ---------*- C++ -*-===*\
+|*                                                                            *|
+|*                     The LLVM Compiler Infrastructure                       *|
+|*                                                                            *|
+|* This file is distributed under the University of Illinois Open Source      *|
+|* License. See LICENSE.TXT for details.                                      *|
+|*                                                                            *|
+|*===----------------------------------------------------------------------===*|
+|*                                                                            *|
+|* Implements the diagnostic functions of the Clang C interface.              *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+#include "CIndexDiagnostic.h"
+#include "CIndexer.h"
+#include "CXSourceLocation.h"
+
+#include "clang/Frontend/ASTUnit.h"
+#include "clang/Frontend/FrontendDiagnostic.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace clang;
+using namespace clang::cxloc;
+using namespace clang::cxstring;
+using namespace llvm;
+
+//-----------------------------------------------------------------------------
+// C Interface Routines
+//-----------------------------------------------------------------------------
+extern "C" {
+
+unsigned clang_getNumDiagnostics(CXTranslationUnit Unit) {
+  ASTUnit *CXXUnit = static_cast<ASTUnit *>(Unit);
+  return CXXUnit? CXXUnit->stored_diag_size() : 0;
+}
+
+CXDiagnostic clang_getDiagnostic(CXTranslationUnit Unit, unsigned Index) {
+  ASTUnit *CXXUnit = static_cast<ASTUnit *>(Unit);
+  if (!CXXUnit || Index >= CXXUnit->stored_diag_size())
+    return 0;
+
+  return new CXStoredDiagnostic(CXXUnit->stored_diag_begin()[Index],
+                                CXXUnit->getASTContext().getLangOptions());
+}
+
+void clang_disposeDiagnostic(CXDiagnostic Diagnostic) {
+  CXStoredDiagnostic *Stored = static_cast<CXStoredDiagnostic *>(Diagnostic);
+  delete Stored;
+}
+
+CXString clang_formatDiagnostic(CXDiagnostic Diagnostic, unsigned Options) {
+  if (!Diagnostic)
+    return createCXString("");
+
+  CXDiagnosticSeverity Severity = clang_getDiagnosticSeverity(Diagnostic);
+
+  // Ignore diagnostics that should be ignored.
+  if (Severity == CXDiagnostic_Ignored)
+    return createCXString("");
+
+  llvm::SmallString<256> Str;
+  llvm::raw_svector_ostream Out(Str);
+  
+  if (Options & CXDiagnostic_DisplaySourceLocation) {
+    // Print source location (file:line), along with optional column
+    // and source ranges.
+    CXFile File;
+    unsigned Line, Column;
+    clang_getInstantiationLocation(clang_getDiagnosticLocation(Diagnostic),
+                                   &File, &Line, &Column, 0);
+    if (File) {
+      CXString FName = clang_getFileName(File);
+      Out << clang_getCString(FName) << ":" << Line << ":";
+      clang_disposeString(FName);
+      if (Options & CXDiagnostic_DisplayColumn)
+        Out << Column << ":";
+
+      if (Options & CXDiagnostic_DisplaySourceRanges) {
+        unsigned N = clang_getDiagnosticNumRanges(Diagnostic);
+        bool PrintedRange = false;
+        for (unsigned I = 0; I != N; ++I) {
+          CXFile StartFile, EndFile;
+          CXSourceRange Range = clang_getDiagnosticRange(Diagnostic, I);
+          
+          unsigned StartLine, StartColumn, EndLine, EndColumn;
+          clang_getInstantiationLocation(clang_getRangeStart(Range),
+                                         &StartFile, &StartLine, &StartColumn,
+                                         0);
+          clang_getInstantiationLocation(clang_getRangeEnd(Range),
+                                         &EndFile, &EndLine, &EndColumn, 0);
+          
+          if (StartFile != EndFile || StartFile != File)
+            continue;
+          
+          Out << "{" << StartLine << ":" << StartColumn << "-"
+              << EndLine << ":" << EndColumn << "}";
+          PrintedRange = true;
+        }
+        if (PrintedRange)
+          Out << ":";
+      }
+    }
+
+    Out << " ";
+  }
+
+  /* Print warning/error/etc. */
+  switch (Severity) {
+  case CXDiagnostic_Ignored: assert(0 && "impossible"); break;
+  case CXDiagnostic_Note: Out << "note: "; break;
+  case CXDiagnostic_Warning: Out << "warning: "; break;
+  case CXDiagnostic_Error: Out << "error: "; break;
+  case CXDiagnostic_Fatal: Out << "fatal error: "; break;
+  }
+
+  CXString Text = clang_getDiagnosticSpelling(Diagnostic);
+  if (clang_getCString(Text))
+    Out << clang_getCString(Text);
+  else
+    Out << "<no diagnostic text>";
+  clang_disposeString(Text);
+  return createCXString(Out.str(), true);
+}
+
+unsigned clang_defaultDiagnosticDisplayOptions() {
+  return CXDiagnostic_DisplaySourceLocation | CXDiagnostic_DisplayColumn;
+}
+
+enum CXDiagnosticSeverity clang_getDiagnosticSeverity(CXDiagnostic Diag) {
+  CXStoredDiagnostic *StoredDiag = static_cast<CXStoredDiagnostic *>(Diag);
+  if (!StoredDiag)
+    return CXDiagnostic_Ignored;
+
+  switch (StoredDiag->Diag.getLevel()) {
+  case Diagnostic::Ignored: return CXDiagnostic_Ignored;
+  case Diagnostic::Note:    return CXDiagnostic_Note;
+  case Diagnostic::Warning: return CXDiagnostic_Warning;
+  case Diagnostic::Error:   return CXDiagnostic_Error;
+  case Diagnostic::Fatal:   return CXDiagnostic_Fatal;
+  }
+
+  llvm_unreachable("Invalid diagnostic level");
+  return CXDiagnostic_Ignored;
+}
+
+CXSourceLocation clang_getDiagnosticLocation(CXDiagnostic Diag) {
+  CXStoredDiagnostic *StoredDiag = static_cast<CXStoredDiagnostic *>(Diag);
+  if (!StoredDiag || StoredDiag->Diag.getLocation().isInvalid())
+    return clang_getNullLocation();
+
+  return translateSourceLocation(StoredDiag->Diag.getLocation().getManager(),
+                                 StoredDiag->LangOpts,
+                                 StoredDiag->Diag.getLocation());
+}
+
+CXString clang_getDiagnosticSpelling(CXDiagnostic Diag) {
+  CXStoredDiagnostic *StoredDiag = static_cast<CXStoredDiagnostic *>(Diag);
+  if (!StoredDiag)
+    return createCXString("");
+
+  return createCXString(StoredDiag->Diag.getMessage(), false);
+}
+
+unsigned clang_getDiagnosticNumRanges(CXDiagnostic Diag) {
+  CXStoredDiagnostic *StoredDiag = static_cast<CXStoredDiagnostic *>(Diag);
+  if (!StoredDiag || StoredDiag->Diag.getLocation().isInvalid())
+    return 0;
+
+  return StoredDiag->Diag.range_size();
+}
+
+CXSourceRange clang_getDiagnosticRange(CXDiagnostic Diag, unsigned Range) {
+  CXStoredDiagnostic *StoredDiag = static_cast<CXStoredDiagnostic *>(Diag);
+  if (!StoredDiag || Range >= StoredDiag->Diag.range_size() ||
+      StoredDiag->Diag.getLocation().isInvalid())
+    return clang_getNullRange();
+
+  return translateSourceRange(StoredDiag->Diag.getLocation().getManager(),
+                              StoredDiag->LangOpts,
+                              StoredDiag->Diag.range_begin()[Range]);
+}
+
+unsigned clang_getDiagnosticNumFixIts(CXDiagnostic Diag) {
+  CXStoredDiagnostic *StoredDiag = static_cast<CXStoredDiagnostic *>(Diag);
+  if (!StoredDiag)
+    return 0;
+
+  return StoredDiag->Diag.fixit_size();
+}
+
+CXString clang_getDiagnosticFixIt(CXDiagnostic Diagnostic, unsigned FixIt,
+                                  CXSourceRange *ReplacementRange) {
+  CXStoredDiagnostic *StoredDiag
+    = static_cast<CXStoredDiagnostic *>(Diagnostic);
+  if (!StoredDiag || FixIt >= StoredDiag->Diag.fixit_size() ||
+      StoredDiag->Diag.getLocation().isInvalid()) {
+    if (ReplacementRange)
+      *ReplacementRange = clang_getNullRange();
+
+    return createCXString("");
+  }
+
+  const FixItHint &Hint = StoredDiag->Diag.fixit_begin()[FixIt];
+  if (ReplacementRange) {
+    if (Hint.RemoveRange.isInvalid())  {
+      // Create an empty range that refers to a single source
+      // location (which is the insertion point).
+      CXSourceRange Range = { 
+        { (void *)&StoredDiag->Diag.getLocation().getManager(), 
+          (void *)&StoredDiag->LangOpts },
+        Hint.InsertionLoc.getRawEncoding(),
+        Hint.InsertionLoc.getRawEncoding() 
+      };
+
+      *ReplacementRange = Range;
+    } else {
+      // Create a range that covers the entire replacement (or
+      // removal) range, adjusting the end of the range to point to
+      // the end of the token.
+      *ReplacementRange
+          = translateSourceRange(StoredDiag->Diag.getLocation().getManager(),
+                                 StoredDiag->LangOpts,
+                                 Hint.RemoveRange);
+    }
+  }
+
+  return createCXString(Hint.CodeToInsert);
+}
+
+} // end extern "C"
+
+void clang::LoadSerializedDiagnostics(const llvm::sys::Path &DiagnosticsPath,
+                                      unsigned num_unsaved_files,
+                                      struct CXUnsavedFile *unsaved_files,
+                                      FileManager &FileMgr,
+                                      SourceManager &SourceMgr,
+                                     SmallVectorImpl<StoredDiagnostic> &Diags) {
+  using llvm::MemoryBuffer;
+  using llvm::StringRef;
+  MemoryBuffer *F = MemoryBuffer::getFile(DiagnosticsPath.c_str());
+  if (!F)
+    return;
+
+  // Enter the unsaved files into the file manager.
+  for (unsigned I = 0; I != num_unsaved_files; ++I) {
+    const FileEntry *File = FileMgr.getVirtualFile(unsaved_files[I].Filename,
+                                                   unsaved_files[I].Length,
+                                                   0);
+    if (!File) {
+      // FIXME: Hard to localize when we have no diagnostics engine!
+      Diags.push_back(StoredDiagnostic(Diagnostic::Fatal,
+                            (Twine("could not remap from missing file ") +
+                                   unsaved_files[I].Filename).str()));
+      delete F;
+      return;
+    }
+
+    MemoryBuffer *Buffer
+      = MemoryBuffer::getMemBuffer(unsaved_files[I].Contents,
+                           unsaved_files[I].Contents + unsaved_files[I].Length);
+    if (!Buffer) {
+      delete F;
+      return;
+    }
+    
+    SourceMgr.overrideFileContents(File, Buffer);
+    SourceMgr.createFileID(File, SourceLocation(), SrcMgr::C_User);
+  }
+
+  // Parse the diagnostics, emitting them one by one until we've
+  // exhausted the data.
+  StringRef Buffer = F->getBuffer();
+  const char *Memory = Buffer.data(), *MemoryEnd = Memory + Buffer.size();
+  while (Memory != MemoryEnd) {
+    StoredDiagnostic Stored = StoredDiagnostic::Deserialize(FileMgr, SourceMgr,
+                                                            Memory, MemoryEnd);
+    if (!Stored)
+      break;
+
+    Diags.push_back(Stored);
+  }
+  delete F;
+}
diff --git a/tools/CIndex/CIndexDiagnostic.h b/tools/CIndex/CIndexDiagnostic.h
new file mode 100644
index 0000000..919c21c
--- /dev/null
+++ b/tools/CIndex/CIndexDiagnostic.h
@@ -0,0 +1,53 @@
+/*===-- CIndexDiagnostic.h - Diagnostics C Interface ------------*- C++ -*-===*\
+|*                                                                            *|
+|*                     The LLVM Compiler Infrastructure                       *|
+|*                                                                            *|
+|* This file is distributed under the University of Illinois Open Source      *|
+|* License. See LICENSE.TXT for details.                                      *|
+|*                                                                            *|
+|*===----------------------------------------------------------------------===*|
+|*                                                                            *|
+|* Implements the diagnostic functions of the Clang C interface.              *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+#ifndef LLVM_CLANG_CINDEX_DIAGNOSTIC_H
+#define LLVM_CLANG_CINDEX_DIAGNOSTIC_H
+
+struct CXUnsavedFile;
+
+namespace llvm {
+template<typename T> class SmallVectorImpl;
+namespace sys { class Path; }
+}
+
+namespace clang {
+
+class Diagnostic;
+class FileManager;
+class LangOptions;
+class Preprocessor;
+class StoredDiagnostic;
+class SourceManager;
+
+/// \brief The storage behind a CXDiagnostic
+struct CXStoredDiagnostic {
+  const StoredDiagnostic &Diag;
+  const LangOptions &LangOpts;
+  
+  CXStoredDiagnostic(const StoredDiagnostic &Diag,
+                     const LangOptions &LangOpts)
+    : Diag(Diag), LangOpts(LangOpts) { }
+};
+  
+/// \brief Given the path to a file that contains binary, serialized
+/// diagnostics produced by Clang, load those diagnostics.
+void LoadSerializedDiagnostics(const llvm::sys::Path &DiagnosticsPath,
+                               unsigned num_unsaved_files,
+                               struct CXUnsavedFile *unsaved_files,
+                               FileManager &FileMgr,
+                               SourceManager &SourceMgr,
+                               llvm::SmallVectorImpl<StoredDiagnostic> &Diags);
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_CINDEX_DIAGNOSTIC_H
diff --git a/tools/CIndex/CIndexInclusionStack.cpp b/tools/CIndex/CIndexInclusionStack.cpp
new file mode 100644
index 0000000..e863239
--- /dev/null
+++ b/tools/CIndex/CIndexInclusionStack.cpp
@@ -0,0 +1,67 @@
+//===- CIndexInclusionStack.cpp - Clang-C Source Indexing Library ---------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a callback mechanism for clients to get the inclusion
+// stack from a translation unit.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CIndexer.h"
+#include "CXSourceLocation.h"
+#include "clang/AST/DeclVisitor.h"
+#include "clang/Frontend/ASTUnit.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace clang;
+
+extern "C" {
+void clang_getInclusions(CXTranslationUnit TU, CXInclusionVisitor CB,
+                         CXClientData clientData) {
+  
+  ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU);
+  SourceManager &SM = CXXUnit->getSourceManager();
+  ASTContext &Ctx = CXXUnit->getASTContext();
+
+  llvm::SmallVector<CXSourceLocation, 10> InclusionStack;
+  unsigned i = SM.sloc_loaded_entry_size();
+  unsigned n =  SM.sloc_entry_size();
+
+  // In the case where all the SLocEntries are in an external source, traverse
+  // those SLocEntries as well.  This is the case where we are looking
+  // at the inclusion stack of an AST/PCH file.
+  if (i >= n)
+    i = 0;
+  
+  for ( ; i < n ; ++i) {
+
+    const SrcMgr::SLocEntry &SL = SM.getSLocEntry(i);
+    
+    if (!SL.isFile())
+      continue;
+
+    const SrcMgr::FileInfo &FI = SL.getFile();
+    if (!FI.getContentCache()->Entry)
+      continue;
+    
+    // Build the inclusion stack.
+    SourceLocation L = FI.getIncludeLoc();
+    InclusionStack.clear();
+    while (L.isValid()) {
+      PresumedLoc PLoc = SM.getPresumedLoc(L);
+      InclusionStack.push_back(cxloc::translateSourceLocation(Ctx, L));
+      L = PLoc.getIncludeLoc();
+    }
+            
+    // Callback to the client.
+    // FIXME: We should have a function to construct CXFiles.
+    CB((CXFile) FI.getContentCache()->Entry, 
+       InclusionStack.data(), InclusionStack.size(), clientData);
+  }    
+}
+} // end extern C
diff --git a/tools/CIndex/CIndexUSRs.cpp b/tools/CIndex/CIndexUSRs.cpp
new file mode 100644
index 0000000..58870b9
--- /dev/null
+++ b/tools/CIndex/CIndexUSRs.cpp
@@ -0,0 +1,469 @@
+//===- CIndexUSR.cpp - Clang-C Source Indexing Library --------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the generation and use of USRs from CXEntities.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CIndexer.h"
+#include "CXCursor.h"
+#include "clang/AST/DeclVisitor.h"
+#include "clang/Frontend/ASTUnit.h"
+#include "clang/Lex/PreprocessingRecord.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace clang;
+using namespace clang::cxstring;
+
+//===----------------------------------------------------------------------===//
+// USR generation.
+//===----------------------------------------------------------------------===//
+
+namespace {
+class USRGenerator : public DeclVisitor<USRGenerator> {
+  llvm::raw_ostream &Out;
+  bool IgnoreResults;
+  ASTUnit *AU;
+public:
+  USRGenerator(ASTUnit *au, llvm::raw_ostream &out)
+    : Out(out), IgnoreResults(false), AU(au) {}
+
+  bool ignoreResults() const { return IgnoreResults; }
+
+  // Visitation methods from generating USRs from AST elements.
+  void VisitBlockDecl(BlockDecl *D);
+  void VisitDeclContext(DeclContext *D);
+  void VisitFieldDecl(FieldDecl *D);
+  void VisitFunctionDecl(FunctionDecl *D);
+  void VisitNamedDecl(NamedDecl *D);
+  void VisitNamespaceDecl(NamespaceDecl *D);
+  void VisitObjCClassDecl(ObjCClassDecl *CD);
+  void VisitObjCContainerDecl(ObjCContainerDecl *CD);
+  void VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *P);
+  void VisitObjCMethodDecl(ObjCMethodDecl *MD);
+  void VisitObjCPropertyDecl(ObjCPropertyDecl *D);
+  void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D);
+  void VisitTagDecl(TagDecl *D);
+  void VisitTypedefDecl(TypedefDecl *D);
+  void VisitVarDecl(VarDecl *D);
+
+  /// Generate the string component containing the location of the
+  ///  declaration.
+  void GenLoc(const Decl *D);
+
+  /// String generation methods used both by the visitation methods
+  /// and from other clients that want to directly generate USRs.  These
+  /// methods do not construct complete USRs (which incorporate the parents
+  /// of an AST element), but only the fragments concerning the AST element
+  /// itself.
+
+  /// Generate a USR fragment for a named declaration.  This does
+  /// not include the USR component for the parent.
+  void GenNamedDecl(llvm::StringRef name);
+
+  /// Generate a USR for an Objective-C class.
+  void GenObjCClass(llvm::StringRef cls);
+  /// Generate a USR for an Objective-C class category.
+  void GenObjCCategory(llvm::StringRef cls, llvm::StringRef cat);
+  /// Generate a USR fragment for an Objective-C instance variable.  The
+  /// complete USR can be created by concatenating the USR for the
+  /// encompassing class with this USR fragment.
+  void GenObjCIvar(llvm::StringRef ivar);
+  /// Generate a USR fragment for an Objective-C method.
+  void GenObjCMethod(llvm::StringRef sel, bool isInstanceMethod);
+  /// Generate a USR fragment for an Objective-C property.
+  void GenObjCProperty(llvm::StringRef prop);
+  /// Generate a USR for an Objective-C protocol.
+  void GenObjCProtocol(llvm::StringRef prot);
+};
+
+class StringUSRGenerator {
+private:
+  llvm::SmallString<1024> StrBuf;
+  llvm::raw_svector_ostream Out;
+  USRGenerator UG;
+public:
+  StringUSRGenerator(const CXCursor *C = 0)
+    : Out(StrBuf), UG(C ? cxcursor::getCursorASTUnit(*C) : 0, Out) {
+    // Add the USR space prefix.
+    Out << "c:";
+  }
+
+  llvm::StringRef str() {
+    return Out.str();
+  }
+
+  USRGenerator* operator->() { return &UG; }
+
+  template <typename T>
+  llvm::raw_svector_ostream &operator<<(const T &x) {
+    Out << x;
+    return Out;
+  }
+};
+
+} // end anonymous namespace
+
+//===----------------------------------------------------------------------===//
+// Generating USRs from ASTS.
+//===----------------------------------------------------------------------===//
+
+void USRGenerator::VisitBlockDecl(BlockDecl *D) {
+  VisitDeclContext(D->getDeclContext());
+  // FIXME: Better support for anonymous blocks.
+  Out << "@B@anon";
+}
+
+void USRGenerator::VisitDeclContext(DeclContext *DC) {
+  if (NamedDecl *D = dyn_cast<NamedDecl>(DC))
+    Visit(D);
+}
+
+void USRGenerator::VisitFieldDecl(FieldDecl *D) {
+  const std::string &s = D->getNameAsString();
+  if (s.empty()) {
+    // Bit fields can be anonymous.
+    IgnoreResults = true;
+    return;
+  }
+  VisitDeclContext(D->getDeclContext());
+  Out << (isa<ObjCIvarDecl>(D) ? "@" : "@FI@") << s;
+}
+
+void USRGenerator::VisitFunctionDecl(FunctionDecl *D) {
+  VisitDeclContext(D->getDeclContext());
+  Out << "@F@" << D;
+}
+
+void USRGenerator::VisitNamedDecl(NamedDecl *D) {
+  VisitDeclContext(D->getDeclContext());
+  const std::string &s = D->getNameAsString();
+  // The string can be empty if the declaration has no name; e.g., it is
+  // the ParmDecl with no name for declaration of a function pointer type, e.g.:
+  //  	void  (*f)(void *);
+  // In this case, don't generate a USR.
+  if (s.empty())
+    IgnoreResults = true;
+  else
+    GenNamedDecl(s);
+}
+
+void USRGenerator::VisitVarDecl(VarDecl *D) {
+  // VarDecls can be declared 'extern' within a function or method body,
+  // but their enclosing DeclContext is the function, not the TU.  We need
+  // to check the storage class to correctly generate the USR.
+  if (!D->hasExternalStorage())
+    VisitDeclContext(D->getDeclContext());
+
+  const std::string &s = D->getNameAsString();
+  // The string can be empty if the declaration has no name; e.g., it is
+  // the ParmDecl with no name for declaration of a function pointer type, e.g.:
+  //  	void  (*f)(void *);
+  // In this case, don't generate a USR.
+  if (s.empty())
+    IgnoreResults = true;
+  else
+    GenNamedDecl(s);
+}
+
+void USRGenerator::VisitNamespaceDecl(NamespaceDecl *D) {
+  VisitDeclContext(D->getDeclContext());
+  Out << "@N@" << D;
+}
+
+void USRGenerator::VisitObjCMethodDecl(ObjCMethodDecl *D) {
+  Visit(cast<Decl>(D->getDeclContext()));
+  GenObjCMethod(DeclarationName(D->getSelector()).getAsString(),
+                D->isInstanceMethod());
+}
+
+void USRGenerator::VisitObjCClassDecl(ObjCClassDecl *D) {
+  // FIXME: @class declarations can refer to multiple classes.  We need
+  //  to be able to traverse these.
+  IgnoreResults = true;
+}
+
+void USRGenerator::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D) {
+  // FIXME: @protocol declarations can refer to multiple protocols.  We need
+  //  to be able to traverse these.
+  IgnoreResults = true;
+}
+
+void USRGenerator::VisitObjCContainerDecl(ObjCContainerDecl *D) {
+  switch (D->getKind()) {
+    default:
+      assert(false && "Invalid ObjC container.");
+    case Decl::ObjCInterface:
+    case Decl::ObjCImplementation:
+      GenObjCClass(D->getName());
+      break;
+    case Decl::ObjCCategory: {
+      ObjCCategoryDecl *CD = cast<ObjCCategoryDecl>(D);
+      ObjCInterfaceDecl *ID = CD->getClassInterface();
+      if (!ID) {
+        // Handle invalid code where the @interface might not
+        // have been specified.
+        // FIXME: We should be able to generate this USR even if the
+        // @interface isn't available.
+        IgnoreResults = true;
+        return;
+      }
+      GenObjCCategory(ID->getName(), CD->getName());
+      break;
+    }
+    case Decl::ObjCCategoryImpl: {
+      ObjCCategoryImplDecl *CD = cast<ObjCCategoryImplDecl>(D);
+      ObjCInterfaceDecl *ID = CD->getClassInterface();
+      if (!ID) {
+        // Handle invalid code where the @interface might not
+        // have been specified.
+        // FIXME: We should be able to generate this USR even if the
+        // @interface isn't available.
+        IgnoreResults = true;
+        return;
+      }
+      GenObjCCategory(ID->getName(), CD->getName());
+      break;
+    }
+    case Decl::ObjCProtocol:
+      GenObjCProtocol(cast<ObjCProtocolDecl>(D)->getName());
+      break;
+  }
+}
+
+void USRGenerator::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
+  Visit(cast<Decl>(D->getDeclContext()));
+  GenObjCProperty(D->getName());
+}
+
+void USRGenerator::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
+  if (ObjCPropertyDecl *PD = D->getPropertyDecl()) {
+    VisitObjCPropertyDecl(PD);
+    return;
+  }
+
+  IgnoreResults = true;
+}
+
+void USRGenerator::VisitTagDecl(TagDecl *D) {
+  D = D->getCanonicalDecl();
+  VisitDeclContext(D->getDeclContext());
+  switch (D->getTagKind()) {
+    case TagDecl::TK_struct: Out << "@S"; break;
+    case TagDecl::TK_class:  Out << "@C"; break;
+    case TagDecl::TK_union:  Out << "@U"; break;
+    case TagDecl::TK_enum:   Out << "@E"; break;
+  }
+
+  const std::string &s = D->getNameAsString();
+  const TypedefDecl *TD = 0;
+  if (s.empty()) {
+    TD = D->getTypedefForAnonDecl();
+    Out << (TD ? 'A' : 'a');
+  }
+
+  // Add the location of the tag decl to handle resolution across
+  // translation units.
+  if (D->getLinkage() == NoLinkage) {
+    Out << '@';
+    GenLoc(D);
+    if (IgnoreResults)
+      return;
+  }
+
+  if (s.empty()) {
+    if (TD)
+      Out << '@' << TD;
+  }
+  else
+    Out << '@' << s;
+}
+
+void USRGenerator::VisitTypedefDecl(TypedefDecl *D) {
+  DeclContext *DC = D->getDeclContext();
+  if (NamedDecl *DCN = dyn_cast<NamedDecl>(DC))
+    Visit(DCN);
+  Out << "@T@";
+  if (D->getLinkage() == NoLinkage) {
+    GenLoc(D);
+    if (IgnoreResults)
+      return;
+    Out << '@';
+  }
+  Out << D->getName();
+}
+
+void USRGenerator::GenLoc(const Decl *D) {
+  const SourceManager &SM = AU->getSourceManager();
+  SourceLocation L = D->getLocStart();
+  if (L.isInvalid()) {
+    IgnoreResults = true;
+    return;
+  }
+  L = SM.getInstantiationLoc(L);
+  const std::pair<FileID, unsigned> &Decomposed = SM.getDecomposedLoc(L);
+  const FileEntry *FE = SM.getFileEntryForID(Decomposed.first);
+  if (FE) {
+    llvm::sys::Path P(FE->getName());
+    Out << P.getLast();
+  }
+  else {
+    // This case really isn't interesting.
+    IgnoreResults = true;
+    return;
+  }
+  Out << '@'
+      << SM.getLineNumber(Decomposed.first, Decomposed.second) << ':'
+      << SM.getColumnNumber(Decomposed.first, Decomposed.second);
+}
+
+//===----------------------------------------------------------------------===//
+// General purpose USR generation methods.
+//===----------------------------------------------------------------------===//
+
+void USRGenerator::GenNamedDecl(llvm::StringRef name) {
+  Out << "@" << name;
+}
+
+void USRGenerator::GenObjCClass(llvm::StringRef cls) {
+  Out << "objc(cs)" << cls;
+}
+
+void USRGenerator::GenObjCCategory(llvm::StringRef cls, llvm::StringRef cat) {
+  Out << "objc(cy)" << cls << '@' << cat;
+}
+
+void USRGenerator::GenObjCIvar(llvm::StringRef ivar) {
+  GenNamedDecl(ivar);
+}
+
+void USRGenerator::GenObjCMethod(llvm::StringRef meth, bool isInstanceMethod) {
+  Out << (isInstanceMethod ? "(im)" : "(cm)") << meth;
+}
+
+void USRGenerator::GenObjCProperty(llvm::StringRef prop) {
+  Out << "(py)" << prop;
+}
+
+void USRGenerator::GenObjCProtocol(llvm::StringRef prot) {
+  Out << "objc(pl)" << prot;
+}
+
+//===----------------------------------------------------------------------===//
+// API hooks.
+//===----------------------------------------------------------------------===//
+
+static inline llvm::StringRef extractUSRSuffix(llvm::StringRef s) {
+  return s.startswith("c:") ? s.substr(2) : "";
+}
+
+static CXString getDeclCursorUSR(const CXCursor &C) {
+  Decl *D = cxcursor::getCursorDecl(C);
+
+  // Don't generate USRs for things with invalid locations.
+  if (!D || D->getLocStart().isInvalid())
+    return createCXString("");
+
+  // Check if the cursor has 'NoLinkage'.
+  if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
+    switch (ND->getLinkage()) {
+      case ExternalLinkage:
+        // Generate USRs for all entities with external linkage.
+        break;
+      case NoLinkage:
+        // We allow enums, typedefs, and structs that have no linkage to
+        // have USRs that are anchored to the file they were defined in
+        // (e.g., the header).  This is a little gross, but in principal
+        // enums/anonymous structs/etc. defined in a common header file
+        // are referred to across multiple translation units.
+        if (isa<TagDecl>(ND) || isa<TypedefDecl>(ND) ||
+            isa<EnumConstantDecl>(ND) || isa<FieldDecl>(ND))
+          break;
+        // Fall-through.
+      case InternalLinkage:
+      case UniqueExternalLinkage:
+        return createCXString("");
+    }
+
+  StringUSRGenerator SUG(&C);
+  SUG->Visit(D);
+
+  if (SUG->ignoreResults())
+    return createCXString("");
+
+  // For development testing.
+  // assert(SUG.str().size() > 2);
+
+    // Return a copy of the string that must be disposed by the caller.
+  return createCXString(SUG.str(), true);
+}
+
+extern "C" {
+
+CXString clang_getCursorUSR(CXCursor C) {
+  const CXCursorKind &K = clang_getCursorKind(C);
+
+  if (clang_isDeclaration(K))
+      return getDeclCursorUSR(C);
+
+  if (K == CXCursor_MacroDefinition) {
+    StringUSRGenerator SUG(&C);
+    SUG << "macro@"
+        << cxcursor::getCursorMacroDefinition(C)->getName()->getNameStart();
+    return createCXString(SUG.str(), true);
+  }
+
+  return createCXString("");
+}
+
+CXString clang_constructUSR_ObjCIvar(const char *name, CXString classUSR) {
+  StringUSRGenerator SUG;
+  SUG << extractUSRSuffix(clang_getCString(classUSR));
+  SUG->GenObjCIvar(name);
+  return createCXString(SUG.str(), true);
+}
+
+CXString clang_constructUSR_ObjCMethod(const char *name,
+                                       unsigned isInstanceMethod,
+                                       CXString classUSR) {
+  StringUSRGenerator SUG;
+  SUG << extractUSRSuffix(clang_getCString(classUSR));
+  SUG->GenObjCMethod(name, isInstanceMethod);
+  return createCXString(SUG.str(), true);
+}
+
+CXString clang_constructUSR_ObjCClass(const char *name) {
+  StringUSRGenerator SUG;
+  SUG->GenObjCClass(name);
+  return createCXString(SUG.str(), true);
+}
+
+CXString clang_constructUSR_ObjCProtocol(const char *name) {
+  StringUSRGenerator SUG;
+  SUG->GenObjCProtocol(name);
+  return createCXString(SUG.str(), true);
+}
+
+CXString clang_constructUSR_ObjCCategory(const char *class_name,
+                                         const char *category_name) {
+  StringUSRGenerator SUG;
+  SUG->GenObjCCategory(class_name, category_name);
+  return createCXString(SUG.str(), true);
+}
+
+CXString clang_constructUSR_ObjCProperty(const char *property,
+                                         CXString classUSR) {
+  StringUSRGenerator SUG;
+  SUG << extractUSRSuffix(clang_getCString(classUSR));
+  SUG->GenObjCProperty(property);
+  return createCXString(SUG.str(), true);
+}
+
+} // end extern "C"
diff --git a/tools/CIndex/CIndexer.cpp b/tools/CIndex/CIndexer.cpp
new file mode 100644
index 0000000..d5131ff
--- /dev/null
+++ b/tools/CIndex/CIndexer.cpp
@@ -0,0 +1,154 @@
+//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Clang-C Source Indexing library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CIndexer.h"
+
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclVisitor.h"
+#include "clang/AST/StmtVisitor.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/Version.h"
+#include "clang/Sema/CodeCompleteConsumer.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Config/config.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/System/Program.h"
+
+#include <cstdio>
+#include <vector>
+#include <sstream>
+
+#ifdef LLVM_ON_WIN32
+#include <windows.h>
+#else
+#include <dlfcn.h>
+#endif
+
+using namespace clang;
+
+const llvm::sys::Path& CIndexer::getClangPath() {
+  // Did we already compute the path?
+  if (!ClangPath.empty())
+    return ClangPath;
+
+  // Find the location where this library lives (libCIndex.dylib).
+#ifdef LLVM_ON_WIN32
+  MEMORY_BASIC_INFORMATION mbi;
+  char path[MAX_PATH];
+  VirtualQuery((void *)(uintptr_t)clang_createTranslationUnit, &mbi,
+               sizeof(mbi));
+  GetModuleFileNameA((HINSTANCE)mbi.AllocationBase, path, MAX_PATH);
+
+  llvm::sys::Path CIndexPath(path);
+
+  CIndexPath.eraseComponent();
+  CIndexPath.appendComponent("clang");
+  CIndexPath.appendSuffix("exe");
+  CIndexPath.makeAbsolute();
+#else
+  // This silly cast below avoids a C++ warning.
+  Dl_info info;
+  if (dladdr((void *)(uintptr_t)clang_createTranslationUnit, &info) == 0)
+    assert(0 && "Call to dladdr() failed");
+
+  llvm::sys::Path CIndexPath(info.dli_fname);
+
+  // We now have the CIndex directory, locate clang relative to it.
+  CIndexPath.eraseComponent();
+  CIndexPath.appendComponent("..");
+  CIndexPath.appendComponent("bin");
+  CIndexPath.appendComponent("clang");
+#endif
+
+  // Cache our result.
+  ClangPath = CIndexPath;
+  return ClangPath;
+}
+
+std::string CIndexer::getClangResourcesPath() {
+  llvm::sys::Path P = getClangPath();
+
+  if (!P.empty()) {
+    P.eraseComponent();  // Remove /clang from foo/bin/clang
+    P.eraseComponent();  // Remove /bin   from foo/bin
+
+    // Get foo/lib/clang/<version>/include
+    P.appendComponent("lib");
+    P.appendComponent("clang");
+    P.appendComponent(CLANG_VERSION_STRING);
+  }
+
+  return P.str();
+}
+
+static llvm::sys::Path GetTemporaryPath() {
+  // FIXME: This is lame; sys::Path should provide this function (in particular,
+  // it should know how to find the temporary files dir).
+  std::string Error;
+  const char *TmpDir = ::getenv("TMPDIR");
+  if (!TmpDir)
+    TmpDir = ::getenv("TEMP");
+  if (!TmpDir)
+    TmpDir = ::getenv("TMP");
+  if (!TmpDir)
+    TmpDir = "/tmp";
+  llvm::sys::Path P(TmpDir);
+  P.appendComponent("remap");
+  if (P.makeUnique(false, &Error))
+    return llvm::sys::Path("");
+
+  // FIXME: Grumble, makeUnique sometimes leaves the file around!?  PR3837.
+  P.eraseFromDisk(false, 0);
+
+  return P;
+}
+
+bool clang::RemapFiles(unsigned num_unsaved_files,
+                       struct CXUnsavedFile *unsaved_files,
+                       std::vector<std::string> &RemapArgs,
+                       std::vector<llvm::sys::Path> &TemporaryFiles) {
+  for (unsigned i = 0; i != num_unsaved_files; ++i) {
+    // Write the contents of this unsaved file into the temporary file.
+    llvm::sys::Path SavedFile(GetTemporaryPath());
+    if (SavedFile.empty())
+      return true;
+
+    std::string ErrorInfo;
+    llvm::raw_fd_ostream OS(SavedFile.c_str(), ErrorInfo);
+    if (!ErrorInfo.empty())
+      return true;
+    
+    OS.write(unsaved_files[i].Contents, unsaved_files[i].Length);
+    OS.close();
+    if (OS.has_error()) {
+      SavedFile.eraseFromDisk();
+      return true;
+    }
+    
+    // Remap the file.
+    std::string RemapArg = unsaved_files[i].Filename;
+    RemapArg += ';';
+    RemapArg += SavedFile.str();
+    RemapArgs.push_back("-Xclang");
+    RemapArgs.push_back("-remap-file");
+    RemapArgs.push_back("-Xclang");
+    RemapArgs.push_back(RemapArg);
+    TemporaryFiles.push_back(SavedFile);
+  }
+  
+  return false;
+}
+
diff --git a/tools/CIndex/CIndexer.h b/tools/CIndex/CIndexer.h
new file mode 100644
index 0000000..31bf779
--- /dev/null
+++ b/tools/CIndex/CIndexer.h
@@ -0,0 +1,78 @@
+//===- CIndexer.h - Clang-C Source Indexing Library -----------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines CIndexer, a subclass of Indexer that provides extra
+// functionality needed by the CIndex library.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_CINDEXER_H
+#define LLVM_CLANG_CINDEXER_H
+
+#include "clang-c/Index.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/System/Path.h"
+#include <vector>
+
+namespace clang {
+namespace cxstring {
+  CXString createCXString(const char *String, bool DupString = false);
+  CXString createCXString(llvm::StringRef String, bool DupString = true);  
+}
+}
+
+class CIndexer {
+  bool UseExternalASTGeneration;
+  bool OnlyLocalDecls;
+  bool DisplayDiagnostics;
+
+  llvm::sys::Path ClangPath;
+  
+public:
+ CIndexer() 
+   : UseExternalASTGeneration(false), OnlyLocalDecls(false),
+     DisplayDiagnostics(false) { }
+  
+  /// \brief Whether we only want to see "local" declarations (that did not
+  /// come from a previous precompiled header). If false, we want to see all
+  /// declarations.
+  bool getOnlyLocalDecls() const { return OnlyLocalDecls; }
+  void setOnlyLocalDecls(bool Local = true) { OnlyLocalDecls = Local; }
+  
+  bool getDisplayDiagnostics() const { return DisplayDiagnostics; }
+  void setDisplayDiagnostics(bool Display = true) {
+    DisplayDiagnostics = Display;
+  }
+
+  bool getUseExternalASTGeneration() const { return UseExternalASTGeneration; }
+  void setUseExternalASTGeneration(bool Value) {
+    UseExternalASTGeneration = Value;
+  }
+  
+  /// \brief Get the path of the clang binary.
+  const llvm::sys::Path& getClangPath();
+  
+  /// \brief Get the path of the clang resource files.
+  std::string getClangResourcesPath();
+};
+
+namespace clang {
+  /**
+   * \brief Given a set of "unsaved" files, create temporary files and 
+   * construct the clang -cc1 argument list needed to perform the remapping.
+   *
+   * \returns true if an error occurred.
+   */
+  bool RemapFiles(unsigned num_unsaved_files,
+                  struct CXUnsavedFile *unsaved_files,
+                  std::vector<std::string> &RemapArgs,
+                  std::vector<llvm::sys::Path> &TemporaryFiles);
+}
+
+#endif
diff --git a/tools/CIndex/CMakeLists.txt b/tools/CIndex/CMakeLists.txt
new file mode 100644
index 0000000..609719e
--- /dev/null
+++ b/tools/CIndex/CMakeLists.txt
@@ -0,0 +1,56 @@
+set(SHARED_LIBRARY TRUE)
+
+set(LLVM_NO_RTTI 1)
+
+set(LLVM_USED_LIBS
+ clangFrontend
+  clangDriver
+  clangSema
+  clangAnalysis
+  clangAST
+  clangParse
+  clangLex
+  clangBasic)
+
+set( LLVM_LINK_COMPONENTS
+  bitreader
+  mc
+  core
+  )
+
+add_clang_library(CIndex
+  CIndex.cpp
+  CIndexCodeCompletion.cpp
+  CIndexDiagnostic.cpp
+  CIndexInclusionStack.cpp
+  CIndexUSRs.cpp
+  CIndexer.cpp
+  CXCursor.cpp
+  ../../include/clang-c/Index.h
+)
+
+if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
+  # FIXME: Deal with LLVM_SUBMIT_VERSION?
+
+  # FIXME: This uses a special darwin-specific exports file in order to
+  # get underscore-prefixed names. It would be better to have build rules
+  # which know how to produce a darwin-suitable exports file from the
+  # regular exports file.
+  set_target_properties(CIndex
+    PROPERTIES
+    LINK_FLAGS "-avoid-version -Wl,-exported_symbols_list -Wl,${CMAKE_CURRENT_SOURCE_DIR}/CIndex.darwin.exports -Wl,-dead_strip -Wl,-seg1addr -Wl,0xE0000000"
+    INSTALL_NAME_DIR "@executable_path/../lib"
+    )
+endif()
+
+if(MSVC)
+  # windows.h doesn't compile with /Za
+  get_target_property(NON_ANSI_COMPILE_FLAGS CIndex COMPILE_FLAGS)
+  string(REPLACE /Za "" NON_ANSI_COMPILE_FLAGS ${NON_ANSI_COMPILE_FLAGS})
+  set_target_properties(CIndex PROPERTIES COMPILE_FLAGS ${NON_ANSI_COMPILE_FLAGS})
+endif(MSVC)
+
+set_target_properties(CIndex
+  PROPERTIES
+  LINKER_LANGUAGE CXX
+  DEFINE_SYMBOL _CINDEX_LIB_)
diff --git a/tools/CIndex/CXCursor.cpp b/tools/CIndex/CXCursor.cpp
new file mode 100644
index 0000000..3bc5d01
--- /dev/null
+++ b/tools/CIndex/CXCursor.cpp
@@ -0,0 +1,369 @@
+//===- CXCursor.cpp - Routines for manipulating CXCursors -----------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines routines for manipulating CXCursors. It should be the
+// only file that has internal knowledge of the encoding of the data in
+// CXCursor.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CXCursor.h"
+#include "clang/Frontend/ASTUnit.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/Expr.h"
+#include "llvm/Support/ErrorHandling.h"
+
+using namespace clang;
+
+CXCursor cxcursor::MakeCXCursorInvalid(CXCursorKind K) {
+  assert(K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid);
+  CXCursor C = { K, { 0, 0, 0 } };
+  return C;
+}
+
+static CXCursorKind GetCursorKind(Decl *D) {
+  assert(D && "Invalid arguments!");
+  switch (D->getKind()) {
+    case Decl::Enum:               return CXCursor_EnumDecl;
+    case Decl::EnumConstant:       return CXCursor_EnumConstantDecl;
+    case Decl::Field:              return CXCursor_FieldDecl;
+    case Decl::Function:  
+      return CXCursor_FunctionDecl;
+    case Decl::ObjCCategory:       return CXCursor_ObjCCategoryDecl;
+    case Decl::ObjCCategoryImpl:   return CXCursor_ObjCCategoryImplDecl;
+    case Decl::ObjCClass:
+      // FIXME
+      return CXCursor_UnexposedDecl;
+    case Decl::ObjCForwardProtocol:
+      // FIXME
+      return CXCursor_UnexposedDecl;      
+    case Decl::ObjCImplementation: return CXCursor_ObjCImplementationDecl;
+    case Decl::ObjCInterface:      return CXCursor_ObjCInterfaceDecl;
+    case Decl::ObjCIvar:           return CXCursor_ObjCIvarDecl; 
+    case Decl::ObjCMethod:
+      return cast<ObjCMethodDecl>(D)->isInstanceMethod()
+              ? CXCursor_ObjCInstanceMethodDecl : CXCursor_ObjCClassMethodDecl;
+    case Decl::CXXMethod:          return CXCursor_CXXMethod;
+    case Decl::ObjCProperty:       return CXCursor_ObjCPropertyDecl;
+    case Decl::ObjCProtocol:       return CXCursor_ObjCProtocolDecl;
+    case Decl::ParmVar:            return CXCursor_ParmDecl;
+    case Decl::Typedef:            return CXCursor_TypedefDecl;
+    case Decl::Var:                return CXCursor_VarDecl;
+    default:
+      if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
+        switch (TD->getTagKind()) {
+          case TagDecl::TK_struct: return CXCursor_StructDecl;
+          case TagDecl::TK_class:  return CXCursor_ClassDecl;
+          case TagDecl::TK_union:  return CXCursor_UnionDecl;
+          case TagDecl::TK_enum:   return CXCursor_EnumDecl;
+        }
+      }
+
+      return CXCursor_UnexposedDecl;
+  }
+  
+  llvm_unreachable("Invalid Decl");
+  return CXCursor_NotImplemented;  
+}
+
+static CXCursorKind GetCursorKind(const Attr *A) {
+  assert(A && "Invalid arguments!");
+  switch (A->getKind()) {
+    default: break;
+    case Attr::IBActionKind: return CXCursor_IBActionAttr;
+    case Attr::IBOutletKind: return CXCursor_IBOutletAttr;
+  }
+
+  return CXCursor_UnexposedAttr;
+}
+
+CXCursor cxcursor::MakeCXCursor(const Attr *A, Decl *Parent, ASTUnit *TU) {
+  assert(A && Parent && TU && "Invalid arguments!");
+  CXCursor C = { GetCursorKind(A), { Parent, (void*)A, TU } };
+  return C;
+}
+
+CXCursor cxcursor::MakeCXCursor(Decl *D, ASTUnit *TU) {
+  assert(D && TU && "Invalid arguments!");
+  CXCursor C = { GetCursorKind(D), { D, 0, TU } };
+  return C;
+}
+
+CXCursor cxcursor::MakeCXCursor(Stmt *S, Decl *Parent, ASTUnit *TU) {
+  assert(S && TU && "Invalid arguments!");
+  CXCursorKind K = CXCursor_NotImplemented;
+  
+  switch (S->getStmtClass()) {
+  case Stmt::NoStmtClass:
+    break;
+      
+  case Stmt::NullStmtClass:
+  case Stmt::CompoundStmtClass:
+  case Stmt::CaseStmtClass:
+  case Stmt::DefaultStmtClass:
+  case Stmt::LabelStmtClass:       
+  case Stmt::IfStmtClass:          
+  case Stmt::SwitchStmtClass:      
+  case Stmt::WhileStmtClass:       
+  case Stmt::DoStmtClass:          
+  case Stmt::ForStmtClass:        
+  case Stmt::GotoStmtClass:        
+  case Stmt::IndirectGotoStmtClass:
+  case Stmt::ContinueStmtClass:    
+  case Stmt::BreakStmtClass:       
+  case Stmt::ReturnStmtClass:      
+  case Stmt::DeclStmtClass:        
+  case Stmt::SwitchCaseClass:      
+  case Stmt::AsmStmtClass:         
+  case Stmt::ObjCAtTryStmtClass:        
+  case Stmt::ObjCAtCatchStmtClass:      
+  case Stmt::ObjCAtFinallyStmtClass:    
+  case Stmt::ObjCAtThrowStmtClass:      
+  case Stmt::ObjCAtSynchronizedStmtClass: 
+  case Stmt::ObjCForCollectionStmtClass:
+  case Stmt::CXXCatchStmtClass:
+  case Stmt::CXXTryStmtClass:  
+    K = CXCursor_UnexposedStmt;
+    break;
+      
+  case Stmt::PredefinedExprClass:        
+  case Stmt::IntegerLiteralClass:        
+  case Stmt::FloatingLiteralClass:       
+  case Stmt::ImaginaryLiteralClass:      
+  case Stmt::StringLiteralClass:         
+  case Stmt::CharacterLiteralClass:      
+  case Stmt::ParenExprClass:             
+  case Stmt::UnaryOperatorClass:         
+  case Stmt::SizeOfAlignOfExprClass:     
+  case Stmt::ArraySubscriptExprClass:    
+  case Stmt::BinaryOperatorClass:        
+  case Stmt::CompoundAssignOperatorClass:
+  case Stmt::ConditionalOperatorClass:   
+  case Stmt::ImplicitCastExprClass:
+  case Stmt::CStyleCastExprClass:
+  case Stmt::CompoundLiteralExprClass:   
+  case Stmt::ExtVectorElementExprClass:  
+  case Stmt::InitListExprClass:          
+  case Stmt::DesignatedInitExprClass:    
+  case Stmt::ImplicitValueInitExprClass: 
+  case Stmt::ParenListExprClass:         
+  case Stmt::VAArgExprClass:             
+  case Stmt::AddrLabelExprClass:        
+  case Stmt::StmtExprClass:             
+  case Stmt::TypesCompatibleExprClass:  
+  case Stmt::ChooseExprClass:           
+  case Stmt::GNUNullExprClass:          
+  case Stmt::CXXStaticCastExprClass:      
+  case Stmt::CXXDynamicCastExprClass:     
+  case Stmt::CXXReinterpretCastExprClass: 
+  case Stmt::CXXConstCastExprClass:       
+  case Stmt::CXXFunctionalCastExprClass:
+  case Stmt::CXXTypeidExprClass:          
+  case Stmt::CXXBoolLiteralExprClass:     
+  case Stmt::CXXNullPtrLiteralExprClass:  
+  case Stmt::CXXThisExprClass:            
+  case Stmt::CXXThrowExprClass:           
+  case Stmt::CXXDefaultArgExprClass:      
+  case Stmt::CXXZeroInitValueExprClass:   
+  case Stmt::CXXNewExprClass:             
+  case Stmt::CXXDeleteExprClass:          
+  case Stmt::CXXPseudoDestructorExprClass:
+  case Stmt::UnresolvedLookupExprClass:   
+  case Stmt::UnaryTypeTraitExprClass:     
+  case Stmt::DependentScopeDeclRefExprClass:  
+  case Stmt::CXXBindTemporaryExprClass:   
+  case Stmt::CXXBindReferenceExprClass:   
+  case Stmt::CXXExprWithTemporariesClass: 
+  case Stmt::CXXUnresolvedConstructExprClass:
+  case Stmt::CXXDependentScopeMemberExprClass:
+  case Stmt::UnresolvedMemberExprClass:   
+  case Stmt::ObjCStringLiteralClass:    
+  case Stmt::ObjCEncodeExprClass:       
+  case Stmt::ObjCSelectorExprClass:   
+  case Stmt::ObjCProtocolExprClass:   
+  case Stmt::ObjCImplicitSetterGetterRefExprClass: 
+  case Stmt::ObjCSuperExprClass:     
+  case Stmt::ObjCIsaExprClass:       
+  case Stmt::ShuffleVectorExprClass: 
+  case Stmt::BlockExprClass:  
+    K = CXCursor_UnexposedExpr;
+    break;
+  case Stmt::DeclRefExprClass:           
+  case Stmt::BlockDeclRefExprClass:
+    // FIXME: UnresolvedLookupExpr?
+    // FIXME: DependentScopeDeclRefExpr?
+    K = CXCursor_DeclRefExpr;
+    break;
+      
+  case Stmt::MemberExprClass:            
+  case Stmt::ObjCIvarRefExprClass:    
+  case Stmt::ObjCPropertyRefExprClass: 
+    // FIXME: UnresolvedMemberExpr?
+    // FIXME: CXXDependentScopeMemberExpr?
+    K = CXCursor_MemberRefExpr;
+    break;
+      
+  case Stmt::CallExprClass:              
+  case Stmt::CXXOperatorCallExprClass:
+  case Stmt::CXXMemberCallExprClass:
+  case Stmt::CXXConstructExprClass:  
+  case Stmt::CXXTemporaryObjectExprClass:
+    // FIXME: CXXUnresolvedConstructExpr
+    // FIXME: ObjCImplicitSetterGetterRefExpr?
+    K = CXCursor_CallExpr;
+    break;
+      
+  case Stmt::ObjCMessageExprClass:      
+    K = CXCursor_ObjCMessageExpr;
+    break;
+  }
+  
+  CXCursor C = { K, { Parent, S, TU } };
+  return C;
+}
+
+CXCursor cxcursor::MakeCursorObjCSuperClassRef(ObjCInterfaceDecl *Super, 
+                                               SourceLocation Loc, 
+                                               ASTUnit *TU) {
+  assert(Super && TU && "Invalid arguments!");
+  void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
+  CXCursor C = { CXCursor_ObjCSuperClassRef, { Super, RawLoc, TU } };
+  return C;    
+}
+
+std::pair<ObjCInterfaceDecl *, SourceLocation> 
+cxcursor::getCursorObjCSuperClassRef(CXCursor C) {
+  assert(C.kind == CXCursor_ObjCSuperClassRef);
+  return std::make_pair(static_cast<ObjCInterfaceDecl *>(C.data[0]),
+           SourceLocation::getFromRawEncoding(
+                                      reinterpret_cast<uintptr_t>(C.data[1])));
+}
+
+CXCursor cxcursor::MakeCursorObjCProtocolRef(ObjCProtocolDecl *Super, 
+                                             SourceLocation Loc, 
+                                             ASTUnit *TU) {
+  assert(Super && TU && "Invalid arguments!");
+  void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
+  CXCursor C = { CXCursor_ObjCProtocolRef, { Super, RawLoc, TU } };
+  return C;    
+}
+
+std::pair<ObjCProtocolDecl *, SourceLocation> 
+cxcursor::getCursorObjCProtocolRef(CXCursor C) {
+  assert(C.kind == CXCursor_ObjCProtocolRef);
+  return std::make_pair(static_cast<ObjCProtocolDecl *>(C.data[0]),
+           SourceLocation::getFromRawEncoding(
+                                      reinterpret_cast<uintptr_t>(C.data[1])));
+}
+
+CXCursor cxcursor::MakeCursorObjCClassRef(ObjCInterfaceDecl *Class, 
+                                          SourceLocation Loc, 
+                                          ASTUnit *TU) {
+  // 'Class' can be null for invalid code.
+  if (!Class)
+    return MakeCXCursorInvalid(CXCursor_InvalidCode);
+  assert(TU && "Invalid arguments!");
+  void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
+  CXCursor C = { CXCursor_ObjCClassRef, { Class, RawLoc, TU } };
+  return C;    
+}
+
+std::pair<ObjCInterfaceDecl *, SourceLocation> 
+cxcursor::getCursorObjCClassRef(CXCursor C) {
+  assert(C.kind == CXCursor_ObjCClassRef);
+  return std::make_pair(static_cast<ObjCInterfaceDecl *>(C.data[0]),
+           SourceLocation::getFromRawEncoding(
+                                      reinterpret_cast<uintptr_t>(C.data[1])));
+}
+
+CXCursor cxcursor::MakeCursorTypeRef(TypeDecl *Type, SourceLocation Loc, 
+                                     ASTUnit *TU) {
+  assert(Type && TU && "Invalid arguments!");
+  void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
+  CXCursor C = { CXCursor_TypeRef, { Type, RawLoc, TU } };
+  return C;    
+}
+
+std::pair<TypeDecl *, SourceLocation> 
+cxcursor::getCursorTypeRef(CXCursor C) {
+  assert(C.kind == CXCursor_TypeRef);
+  return std::make_pair(static_cast<TypeDecl *>(C.data[0]),
+           SourceLocation::getFromRawEncoding(
+                                      reinterpret_cast<uintptr_t>(C.data[1])));
+}
+
+CXCursor cxcursor::MakePreprocessingDirectiveCursor(SourceRange Range, 
+                                                    ASTUnit *TU) {
+  CXCursor C = { CXCursor_PreprocessingDirective, 
+                 { reinterpret_cast<void *>(Range.getBegin().getRawEncoding()),
+                   reinterpret_cast<void *>(Range.getEnd().getRawEncoding()),
+                   TU }
+               };
+  return C;
+}
+
+SourceRange cxcursor::getCursorPreprocessingDirective(CXCursor C) {
+  assert(C.kind == CXCursor_PreprocessingDirective);
+  return SourceRange(SourceLocation::getFromRawEncoding(
+                                      reinterpret_cast<uintptr_t> (C.data[0])),
+                     SourceLocation::getFromRawEncoding(
+                                      reinterpret_cast<uintptr_t> (C.data[1])));
+}
+
+CXCursor cxcursor::MakeMacroDefinitionCursor(MacroDefinition *MI, ASTUnit *TU) {
+  CXCursor C = { CXCursor_MacroDefinition, { MI, 0, TU } };
+  return C;
+}
+
+MacroDefinition *cxcursor::getCursorMacroDefinition(CXCursor C) {
+  assert(C.kind == CXCursor_MacroDefinition);
+  return static_cast<MacroDefinition *>(C.data[0]);
+}
+
+CXCursor cxcursor::MakeMacroInstantiationCursor(MacroInstantiation *MI, 
+                                                ASTUnit *TU) {
+  CXCursor C = { CXCursor_MacroInstantiation, { MI, 0, TU } };
+  return C;
+}
+
+MacroInstantiation *cxcursor::getCursorMacroInstantiation(CXCursor C) {
+  assert(C.kind == CXCursor_MacroInstantiation);
+  return static_cast<MacroInstantiation *>(C.data[0]);
+}
+
+Decl *cxcursor::getCursorDecl(CXCursor Cursor) {
+  return (Decl *)Cursor.data[0];
+}
+
+Expr *cxcursor::getCursorExpr(CXCursor Cursor) {
+  return dyn_cast_or_null<Expr>(getCursorStmt(Cursor));
+}
+
+Stmt *cxcursor::getCursorStmt(CXCursor Cursor) {
+  if (Cursor.kind == CXCursor_ObjCSuperClassRef ||
+      Cursor.kind == CXCursor_ObjCProtocolRef ||
+      Cursor.kind == CXCursor_ObjCClassRef)
+    return 0;
+
+  return (Stmt *)Cursor.data[1];
+}
+
+ASTContext &cxcursor::getCursorContext(CXCursor Cursor) {
+  return getCursorASTUnit(Cursor)->getASTContext();
+}
+
+ASTUnit *cxcursor::getCursorASTUnit(CXCursor Cursor) {
+  return static_cast<ASTUnit *>(Cursor.data[2]);
+}
+
+bool cxcursor::operator==(CXCursor X, CXCursor Y) {
+  return X.kind == Y.kind && X.data[0] == Y.data[0] && X.data[1] == Y.data[1] &&
+         X.data[2] == Y.data[2];
+}
diff --git a/tools/CIndex/CXCursor.h b/tools/CIndex/CXCursor.h
new file mode 100644
index 0000000..1664f5a
--- /dev/null
+++ b/tools/CIndex/CXCursor.h
@@ -0,0 +1,112 @@
+//===- CXCursor.h - Routines for manipulating CXCursors -------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines routines for manipulating CXCursors.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_CXCURSOR_H
+#define LLVM_CLANG_CXCURSOR_H
+
+#include "clang-c/Index.h"
+#include "clang/Basic/SourceLocation.h"
+#include <utility>
+
+namespace clang {
+
+class ASTContext;
+class ASTUnit;
+class Attr;
+class Decl;
+class Expr;
+class MacroDefinition;
+class MacroInstantiation;
+class NamedDecl;
+class ObjCInterfaceDecl;
+class ObjCProtocolDecl;
+class Stmt;
+class TypeDecl;
+
+namespace cxcursor {
+  
+CXCursor MakeCXCursor(const clang::Attr *A, clang::Decl *Parent, ASTUnit *TU);
+CXCursor MakeCXCursor(clang::Decl *D, ASTUnit *TU);
+CXCursor MakeCXCursor(clang::Stmt *S, clang::Decl *Parent, ASTUnit *TU);
+CXCursor MakeCXCursorInvalid(CXCursorKind K);
+
+/// \brief Create an Objective-C superclass reference at the given location.
+CXCursor MakeCursorObjCSuperClassRef(ObjCInterfaceDecl *Super, 
+                                     SourceLocation Loc, 
+                                     ASTUnit *TU);
+
+/// \brief Unpack an ObjCSuperClassRef cursor into the interface it references
+/// and optionally the location where the reference occurred.
+std::pair<ObjCInterfaceDecl *, SourceLocation> 
+  getCursorObjCSuperClassRef(CXCursor C);
+
+/// \brief Create an Objective-C protocol reference at the given location.
+CXCursor MakeCursorObjCProtocolRef(ObjCProtocolDecl *Proto, SourceLocation Loc, 
+                                   ASTUnit *TU);
+
+/// \brief Unpack an ObjCProtocolRef cursor into the protocol it references
+/// and optionally the location where the reference occurred.
+std::pair<ObjCProtocolDecl *, SourceLocation> 
+  getCursorObjCProtocolRef(CXCursor C);
+
+/// \brief Create an Objective-C class reference at the given location.
+CXCursor MakeCursorObjCClassRef(ObjCInterfaceDecl *Class, SourceLocation Loc, 
+                                ASTUnit *TU);
+
+/// \brief Unpack an ObjCClassRef cursor into the class it references
+/// and optionally the location where the reference occurred.
+std::pair<ObjCInterfaceDecl *, SourceLocation> 
+  getCursorObjCClassRef(CXCursor C);
+
+/// \brief Create a type reference at the given location.
+CXCursor MakeCursorTypeRef(TypeDecl *Type, SourceLocation Loc, ASTUnit *TU);
+
+/// \brief Unpack a TypeRef cursor into the class it references
+/// and optionally the location where the reference occurred.
+std::pair<TypeDecl *, SourceLocation> getCursorTypeRef(CXCursor C);
+
+/// \brief Create a preprocessing directive cursor.
+CXCursor MakePreprocessingDirectiveCursor(SourceRange Range, ASTUnit *TU);
+
+/// \brief Unpack a given preprocessing directive to retrieve its source range.
+SourceRange getCursorPreprocessingDirective(CXCursor C);
+
+/// \brief Create a macro definition cursor.
+CXCursor MakeMacroDefinitionCursor(MacroDefinition *, ASTUnit *TU);
+
+/// \brief Unpack a given macro definition cursor to retrieve its
+/// source range.
+MacroDefinition *getCursorMacroDefinition(CXCursor C);
+
+/// \brief Create a macro instantiation cursor.
+CXCursor MakeMacroInstantiationCursor(MacroInstantiation *, ASTUnit *TU);
+
+/// \brief Unpack a given macro instantiation cursor to retrieve its
+/// source range.
+MacroInstantiation *getCursorMacroInstantiation(CXCursor C);
+
+Decl *getCursorDecl(CXCursor Cursor);
+Expr *getCursorExpr(CXCursor Cursor);
+Stmt *getCursorStmt(CXCursor Cursor);
+ASTContext &getCursorContext(CXCursor Cursor);
+ASTUnit *getCursorASTUnit(CXCursor Cursor);
+  
+bool operator==(CXCursor X, CXCursor Y);
+  
+inline bool operator!=(CXCursor X, CXCursor Y) {
+  return !(X == Y);
+}
+
+}} // end namespace: clang::cxcursor
+
+#endif
diff --git a/tools/CIndex/CXSourceLocation.h b/tools/CIndex/CXSourceLocation.h
new file mode 100644
index 0000000..66566c1
--- /dev/null
+++ b/tools/CIndex/CXSourceLocation.h
@@ -0,0 +1,75 @@
+//===- CXSourceLocation.h - CXSourceLocations Utilities ---------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines routines for manipulating CXSourceLocations.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_CXSOURCELOCATION_H
+#define LLVM_CLANG_CXSOURCELOCATION_H
+
+#include "clang-c/Index.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/AST/ASTContext.h"
+
+namespace clang {
+
+class SourceManager;
+
+namespace cxloc {
+
+/// \brief Translate a Clang source location into a CIndex source location.
+static inline CXSourceLocation 
+translateSourceLocation(const SourceManager &SM, const LangOptions &LangOpts,
+                        SourceLocation Loc) {
+  CXSourceLocation Result = { { (void*) &SM, (void*) &LangOpts, },
+                              Loc.getRawEncoding() };
+  return Result;
+}
+  
+/// \brief Translate a Clang source location into a CIndex source location.
+static inline CXSourceLocation translateSourceLocation(ASTContext &Context,
+                                                       SourceLocation Loc) {
+  return translateSourceLocation(Context.getSourceManager(),
+                                 Context.getLangOptions(),
+                                 Loc);
+}
+
+/// \brief Translate a Clang source range into a CIndex source range.
+///
+/// Clang internally represents ranges where the end location points to the
+/// start of the token at the end. However, for external clients it is more
+/// useful to have a CXSourceRange be a proper half-open interval. This routine
+/// does the appropriate translation.
+CXSourceRange translateSourceRange(const SourceManager &SM, 
+                                   const LangOptions &LangOpts,
+                                   SourceRange R);
+  
+/// \brief Translate a Clang source range into a CIndex source range.
+static inline CXSourceRange translateSourceRange(ASTContext &Context,
+                                                 SourceRange R) {
+  return translateSourceRange(Context.getSourceManager(),
+                              Context.getLangOptions(),
+                              R);
+}
+
+static inline SourceLocation translateSourceLocation(CXSourceLocation L) {
+  return SourceLocation::getFromRawEncoding(L.int_data);
+}
+
+static inline SourceRange translateCXSourceRange(CXSourceRange R) {
+  return SourceRange(SourceLocation::getFromRawEncoding(R.begin_int_data),
+                     SourceLocation::getFromRawEncoding(R.end_int_data));
+}
+
+
+}} // end namespace: clang::cxloc
+
+#endif
diff --git a/tools/CIndex/Makefile b/tools/CIndex/Makefile
new file mode 100644
index 0000000..391746d
--- /dev/null
+++ b/tools/CIndex/Makefile
@@ -0,0 +1,55 @@
+##===- tools/CIndex/Makefile -------------------------------*- Makefile -*-===##
+# 
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+# 
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../../../..
+LIBRARYNAME = CIndex
+
+EXPORTED_SYMBOL_FILE = $(PROJ_SRC_DIR)/CIndex.exports
+
+CPP.Flags += -I$(PROJ_SRC_DIR)/../../include -I$(PROJ_OBJ_DIR)/../../include
+
+# Include this here so we can get the configuration of the targets
+# that have been configured for construction. We have to do this 
+# early so we can set up LINK_COMPONENTS before including Makefile.rules
+include $(LEVEL)/Makefile.config
+
+LINK_LIBS_IN_SHARED = 1
+SHARED_LIBRARY = 1
+
+LINK_COMPONENTS := bitreader mc core
+USEDLIBS = clangFrontend.a clangDriver.a clangSema.a \
+	   clangAnalysis.a clangAST.a clangParse.a clangLex.a clangBasic.a
+
+include $(LEVEL)/Makefile.common
+
+##===----------------------------------------------------------------------===##
+# FIXME: This is copied from the 'lto' makefile.  Should we share this?
+##===----------------------------------------------------------------------===##
+
+ifeq ($(HOST_OS),Darwin)
+    # set dylib internal version number to llvmCore submission number
+    ifdef LLVM_SUBMIT_VERSION
+        LLVMLibsOptions := $(LLVMLibsOptions) -Wl,-current_version \
+                        -Wl,$(LLVM_SUBMIT_VERSION).$(LLVM_SUBMIT_SUBVERSION) \
+                        -Wl,-compatibility_version -Wl,1
+    endif
+    # extra options to override libtool defaults 
+    LLVMLibsOptions    := $(LLVMLibsOptions)  \
+                         -avoid-version \
+                         -Wl,-dead_strip \
+                         -Wl,-seg1addr -Wl,0xE0000000 
+
+    # Mac OS X 10.4 and earlier tools do not allow a second -install_name on command line
+    DARWIN_VERS := $(shell echo $(TARGET_TRIPLE) | sed 's/.*darwin\([0-9]*\).*/\1/')
+    ifneq ($(DARWIN_VERS),8)
+       LLVMLibsOptions    := $(LLVMLibsOptions)  \
+                            -no-undefined -Wl,-install_name \
+                            -Wl,"@executable_path/../lib/lib$(LIBRARYNAME)$(SHLIBEXT)"
+    endif
+endif
diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt
new file mode 100644
index 0000000..64c3a21
--- /dev/null
+++ b/tools/CMakeLists.txt
@@ -0,0 +1,3 @@
+add_subdirectory(CIndex)
+add_subdirectory(c-index-test)
+add_subdirectory(driver)
diff --git a/tools/Makefile b/tools/Makefile
new file mode 100644
index 0000000..bfd5ad1
--- /dev/null
+++ b/tools/Makefile
@@ -0,0 +1,19 @@
+##===- tools/Makefile --------------------------------------*- Makefile -*-===##
+#
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL := ../../..
+DIRS := driver CIndex c-index-test
+
+include $(LEVEL)/Makefile.config
+
+ifeq ($(OS), $(filter $(OS), Cygwin MingW))
+DIRS := $(filter-out CIndex c-index-test, $(DIRS))
+endif
+
+include $(LEVEL)/Makefile.common
diff --git a/tools/c-index-test/CMakeLists.txt b/tools/c-index-test/CMakeLists.txt
new file mode 100644
index 0000000..f0a34a5
--- /dev/null
+++ b/tools/c-index-test/CMakeLists.txt
@@ -0,0 +1,29 @@
+set(LLVM_NO_RTTI 1)
+
+set( LLVM_USED_LIBS
+  CIndex
+  clangIndex
+  clangFrontend
+  clangDriver
+  clangSema
+  clangAnalysis
+  clangAST
+  clangParse
+  clangLex
+  clangBasic
+  )
+
+set( LLVM_LINK_COMPONENTS
+  bitreader
+  mc
+  core
+  )
+
+add_clang_executable(c-index-test
+  c-index-test.c
+  )
+
+set_target_properties(c-index-test
+  PROPERTIES
+  LINKER_LANGUAGE CXX)
+
diff --git a/tools/c-index-test/Makefile b/tools/c-index-test/Makefile
new file mode 100644
index 0000000..e9ba174
--- /dev/null
+++ b/tools/c-index-test/Makefile
@@ -0,0 +1,24 @@
+##===- tools/index-test/Makefile ---------------------------*- Makefile -*-===##
+# 
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+# 
+##===----------------------------------------------------------------------===##
+LEVEL = ../../../..
+
+TOOLNAME = c-index-test
+CPPFLAGS += -I$(PROJ_SRC_DIR)/../../include -I$(PROJ_OBJ_DIR)/../../include
+NO_INSTALL = 1
+
+# No plugins, optimize startup time.
+TOOL_NO_EXPORTS = 1
+
+include $(LEVEL)/Makefile.config
+
+LINK_COMPONENTS := bitreader mc core
+USEDLIBS = CIndex.a clangIndex.a clangFrontend.a clangDriver.a clangSema.a \
+	   clangAnalysis.a clangAST.a clangParse.a clangLex.a clangBasic.a
+
+include $(LLVM_SRC_ROOT)/Makefile.rules
diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c
new file mode 100644
index 0000000..4941816
--- /dev/null
+++ b/tools/c-index-test/c-index-test.c
@@ -0,0 +1,1239 @@
+/* c-index-test.c */
+
+#include "clang-c/Index.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+/******************************************************************************/
+/* Utility functions.                                                         */
+/******************************************************************************/
+
+#ifdef _MSC_VER
+char *basename(const char* path)
+{
+    char* base1 = (char*)strrchr(path, '/');
+    char* base2 = (char*)strrchr(path, '\\');
+    if (base1 && base2)
+        return((base1 > base2) ? base1 + 1 : base2 + 1);
+    else if (base1)
+        return(base1 + 1);
+    else if (base2)
+        return(base2 + 1);
+
+    return((char*)path);
+}
+#else
+extern char *basename(const char *);
+#endif
+
+static void PrintExtent(FILE *out, unsigned begin_line, unsigned begin_column,
+                        unsigned end_line, unsigned end_column) {
+  fprintf(out, "[%d:%d - %d:%d]", begin_line, begin_column,
+          end_line, end_column);
+}
+
+static unsigned CreateTranslationUnit(CXIndex Idx, const char *file,
+                                      CXTranslationUnit *TU) {
+
+  *TU = clang_createTranslationUnit(Idx, file);
+  if (!TU) {
+    fprintf(stderr, "Unable to load translation unit from '%s'!\n", file);
+    return 0;
+  }
+  return 1;
+}
+
+void free_remapped_files(struct CXUnsavedFile *unsaved_files,
+                         int num_unsaved_files) {
+  int i;
+  for (i = 0; i != num_unsaved_files; ++i) {
+    free((char *)unsaved_files[i].Filename);
+    free((char *)unsaved_files[i].Contents);
+  }
+}
+
+int parse_remapped_files(int argc, const char **argv, int start_arg,
+                         struct CXUnsavedFile **unsaved_files,
+                         int *num_unsaved_files) {
+  int i;
+  int arg;
+  int prefix_len = strlen("-remap-file=");
+  *unsaved_files = 0;
+  *num_unsaved_files = 0;
+
+  /* Count the number of remapped files. */
+  for (arg = start_arg; arg < argc; ++arg) {
+    if (strncmp(argv[arg], "-remap-file=", prefix_len))
+      break;
+
+    ++*num_unsaved_files;
+  }
+
+  if (*num_unsaved_files == 0)
+    return 0;
+
+  *unsaved_files
+  = (struct CXUnsavedFile *)malloc(sizeof(struct CXUnsavedFile) *
+                                   *num_unsaved_files);
+  for (arg = start_arg, i = 0; i != *num_unsaved_files; ++i, ++arg) {
+    struct CXUnsavedFile *unsaved = *unsaved_files + i;
+    const char *arg_string = argv[arg] + prefix_len;
+    int filename_len;
+    char *filename;
+    char *contents;
+    FILE *to_file;
+    const char *semi = strchr(arg_string, ';');
+    if (!semi) {
+      fprintf(stderr,
+              "error: -remap-file=from;to argument is missing semicolon\n");
+      free_remapped_files(*unsaved_files, i);
+      *unsaved_files = 0;
+      *num_unsaved_files = 0;
+      return -1;
+    }
+
+    /* Open the file that we're remapping to. */
+    to_file = fopen(semi + 1, "r");
+    if (!to_file) {
+      fprintf(stderr, "error: cannot open file %s that we are remapping to\n",
+              semi + 1);
+      free_remapped_files(*unsaved_files, i);
+      *unsaved_files = 0;
+      *num_unsaved_files = 0;
+      return -1;
+    }
+
+    /* Determine the length of the file we're remapping to. */
+    fseek(to_file, 0, SEEK_END);
+    unsaved->Length = ftell(to_file);
+    fseek(to_file, 0, SEEK_SET);
+
+    /* Read the contents of the file we're remapping to. */
+    contents = (char *)malloc(unsaved->Length + 1);
+    if (fread(contents, 1, unsaved->Length, to_file) != unsaved->Length) {
+      fprintf(stderr, "error: unexpected %s reading 'to' file %s\n",
+              (feof(to_file) ? "EOF" : "error"), semi + 1);
+      fclose(to_file);
+      free_remapped_files(*unsaved_files, i);
+      *unsaved_files = 0;
+      *num_unsaved_files = 0;
+      return -1;
+    }
+    contents[unsaved->Length] = 0;
+    unsaved->Contents = contents;
+
+    /* Close the file. */
+    fclose(to_file);
+
+    /* Copy the file name that we're remapping from. */
+    filename_len = semi - arg_string;
+    filename = (char *)malloc(filename_len + 1);
+    memcpy(filename, arg_string, filename_len);
+    filename[filename_len] = 0;
+    unsaved->Filename = filename;
+  }
+
+  return 0;
+}
+
+/******************************************************************************/
+/* Pretty-printing.                                                           */
+/******************************************************************************/
+
+static void PrintCursor(CXCursor Cursor) {
+  if (clang_isInvalid(Cursor.kind)) {
+    CXString ks = clang_getCursorKindSpelling(Cursor.kind);
+    printf("Invalid Cursor => %s", clang_getCString(ks));
+    clang_disposeString(ks);
+  }
+  else {
+    CXString string, ks;
+    CXCursor Referenced;
+    unsigned line, column;
+
+    ks = clang_getCursorKindSpelling(Cursor.kind);
+    string = clang_getCursorSpelling(Cursor);
+    printf("%s=%s", clang_getCString(ks),
+                    clang_getCString(string));
+    clang_disposeString(ks);
+    clang_disposeString(string);
+
+    Referenced = clang_getCursorReferenced(Cursor);
+    if (!clang_equalCursors(Referenced, clang_getNullCursor())) {
+      CXSourceLocation Loc = clang_getCursorLocation(Referenced);
+      clang_getInstantiationLocation(Loc, 0, &line, &column, 0);
+      printf(":%d:%d", line, column);
+    }
+
+    if (clang_isCursorDefinition(Cursor))
+      printf(" (Definition)");
+  }
+}
+
+static const char* GetCursorSource(CXCursor Cursor) {
+  CXSourceLocation Loc = clang_getCursorLocation(Cursor);
+  CXString source;
+  CXFile file;
+  clang_getInstantiationLocation(Loc, &file, 0, 0, 0);
+  source = clang_getFileName(file);
+  if (!clang_getCString(source)) {
+    clang_disposeString(source);
+    return "<invalid loc>";
+  }
+  else {
+    const char *b = basename(clang_getCString(source));
+    clang_disposeString(source);
+    return b;
+  }
+}
+
+/******************************************************************************/
+/* Callbacks.                                                                 */
+/******************************************************************************/
+
+typedef void (*PostVisitTU)(CXTranslationUnit);
+
+void PrintDiagnostic(CXDiagnostic Diagnostic) {
+  FILE *out = stderr;
+  CXFile file;
+  CXString Msg;
+  unsigned display_opts = CXDiagnostic_DisplaySourceLocation
+    | CXDiagnostic_DisplayColumn | CXDiagnostic_DisplaySourceRanges;
+  unsigned i, num_fixits;
+
+  if (clang_getDiagnosticSeverity(Diagnostic) == CXDiagnostic_Ignored)
+    return;
+
+  Msg = clang_formatDiagnostic(Diagnostic, display_opts);
+  fprintf(stderr, "%s\n", clang_getCString(Msg));
+  clang_disposeString(Msg);
+
+  clang_getInstantiationLocation(clang_getDiagnosticLocation(Diagnostic),
+                                 &file, 0, 0, 0);
+  if (!file)
+    return;
+
+  num_fixits = clang_getDiagnosticNumFixIts(Diagnostic);
+  for (i = 0; i != num_fixits; ++i) {
+    CXSourceRange range;
+    CXString insertion_text = clang_getDiagnosticFixIt(Diagnostic, i, &range);
+    CXSourceLocation start = clang_getRangeStart(range);
+    CXSourceLocation end = clang_getRangeEnd(range);
+    unsigned start_line, start_column, end_line, end_column;
+    CXFile start_file, end_file;
+    clang_getInstantiationLocation(start, &start_file, &start_line,
+                                   &start_column, 0);
+    clang_getInstantiationLocation(end, &end_file, &end_line, &end_column, 0);
+    if (clang_equalLocations(start, end)) {
+      /* Insertion. */
+      if (start_file == file)
+        fprintf(out, "FIX-IT: Insert \"%s\" at %d:%d\n",
+                clang_getCString(insertion_text), start_line, start_column);
+    } else if (strcmp(clang_getCString(insertion_text), "") == 0) {
+      /* Removal. */
+      if (start_file == file && end_file == file) {
+        fprintf(out, "FIX-IT: Remove ");
+        PrintExtent(out, start_line, start_column, end_line, end_column);
+        fprintf(out, "\n");
+      }
+    } else {
+      /* Replacement. */
+      if (start_file == end_file) {
+        fprintf(out, "FIX-IT: Replace ");
+        PrintExtent(out, start_line, start_column, end_line, end_column);
+        fprintf(out, " with \"%s\"\n", clang_getCString(insertion_text));
+      }
+      break;
+    }
+    clang_disposeString(insertion_text);
+  }
+}
+
+void PrintDiagnostics(CXTranslationUnit TU) {
+  int i, n = clang_getNumDiagnostics(TU);
+  for (i = 0; i != n; ++i) {
+    CXDiagnostic Diag = clang_getDiagnostic(TU, i);
+    PrintDiagnostic(Diag);
+    clang_disposeDiagnostic(Diag);
+  }
+}
+
+/******************************************************************************/
+/* Logic for testing traversal.                                               */
+/******************************************************************************/
+
+static const char *FileCheckPrefix = "CHECK";
+
+static void PrintCursorExtent(CXCursor C) {
+  CXSourceRange extent = clang_getCursorExtent(C);
+  CXFile begin_file, end_file;
+  unsigned begin_line, begin_column, end_line, end_column;
+
+  clang_getInstantiationLocation(clang_getRangeStart(extent),
+                                 &begin_file, &begin_line, &begin_column, 0);
+  clang_getInstantiationLocation(clang_getRangeEnd(extent),
+                                 &end_file, &end_line, &end_column, 0);
+  if (!begin_file || !end_file)
+    return;
+
+  printf(" Extent=");
+  PrintExtent(stdout, begin_line, begin_column, end_line, end_column);
+}
+
+/* Data used by all of the visitors. */
+typedef struct  {
+  CXTranslationUnit TU;
+  enum CXCursorKind *Filter;
+} VisitorData;
+
+
+enum CXChildVisitResult FilteredPrintingVisitor(CXCursor Cursor,
+                                                CXCursor Parent,
+                                                CXClientData ClientData) {
+  VisitorData *Data = (VisitorData *)ClientData;
+  if (!Data->Filter || (Cursor.kind == *(enum CXCursorKind *)Data->Filter)) {
+    CXSourceLocation Loc = clang_getCursorLocation(Cursor);
+    unsigned line, column;
+    clang_getInstantiationLocation(Loc, 0, &line, &column, 0);
+    printf("// %s: %s:%d:%d: ", FileCheckPrefix,
+           GetCursorSource(Cursor), line, column);
+    PrintCursor(Cursor);
+    PrintCursorExtent(Cursor);
+    printf("\n");
+    return CXChildVisit_Recurse;
+  }
+
+  return CXChildVisit_Continue;
+}
+
+static enum CXChildVisitResult FunctionScanVisitor(CXCursor Cursor,
+                                                   CXCursor Parent,
+                                                   CXClientData ClientData) {
+  const char *startBuf, *endBuf;
+  unsigned startLine, startColumn, endLine, endColumn, curLine, curColumn;
+  CXCursor Ref;
+  VisitorData *Data = (VisitorData *)ClientData;
+
+  if (Cursor.kind != CXCursor_FunctionDecl ||
+      !clang_isCursorDefinition(Cursor))
+    return CXChildVisit_Continue;
+
+  clang_getDefinitionSpellingAndExtent(Cursor, &startBuf, &endBuf,
+                                       &startLine, &startColumn,
+                                       &endLine, &endColumn);
+  /* Probe the entire body, looking for both decls and refs. */
+  curLine = startLine;
+  curColumn = startColumn;
+
+  while (startBuf < endBuf) {
+    CXSourceLocation Loc;
+    CXFile file;
+    CXString source;
+
+    if (*startBuf == '\n') {
+      startBuf++;
+      curLine++;
+      curColumn = 1;
+    } else if (*startBuf != '\t')
+      curColumn++;
+
+    Loc = clang_getCursorLocation(Cursor);
+    clang_getInstantiationLocation(Loc, &file, 0, 0, 0);
+
+    source = clang_getFileName(file);
+    if (clang_getCString(source)) {
+      CXSourceLocation RefLoc
+        = clang_getLocation(Data->TU, file, curLine, curColumn);
+      Ref = clang_getCursor(Data->TU, RefLoc);
+      if (Ref.kind == CXCursor_NoDeclFound) {
+        /* Nothing found here; that's fine. */
+      } else if (Ref.kind != CXCursor_FunctionDecl) {
+        printf("// %s: %s:%d:%d: ", FileCheckPrefix, GetCursorSource(Ref),
+               curLine, curColumn);
+        PrintCursor(Ref);
+        printf("\n");
+      }
+    }
+    clang_disposeString(source);
+    startBuf++;
+  }
+
+  return CXChildVisit_Continue;
+}
+
+/******************************************************************************/
+/* USR testing.                                                               */
+/******************************************************************************/
+
+enum CXChildVisitResult USRVisitor(CXCursor C, CXCursor parent,
+                                   CXClientData ClientData) {
+  VisitorData *Data = (VisitorData *)ClientData;
+  if (!Data->Filter || (C.kind == *(enum CXCursorKind *)Data->Filter)) {
+    CXString USR = clang_getCursorUSR(C);
+    const char *cstr = clang_getCString(USR);
+    if (!cstr || cstr[0] == '\0') {
+      clang_disposeString(USR);
+      return CXChildVisit_Recurse;
+    }
+    printf("// %s: %s %s", FileCheckPrefix, GetCursorSource(C), cstr);
+
+    PrintCursorExtent(C);
+    printf("\n");
+    clang_disposeString(USR);
+
+    return CXChildVisit_Recurse;
+  }
+
+  return CXChildVisit_Continue;
+}
+
+/******************************************************************************/
+/* Inclusion stack testing.                                                   */
+/******************************************************************************/
+
+void InclusionVisitor(CXFile includedFile, CXSourceLocation *includeStack,
+                      unsigned includeStackLen, CXClientData data) {
+
+  unsigned i;
+  CXString fname;
+
+  fname = clang_getFileName(includedFile);
+  printf("file: %s\nincluded by:\n", clang_getCString(fname));
+  clang_disposeString(fname);
+
+  for (i = 0; i < includeStackLen; ++i) {
+    CXFile includingFile;
+    unsigned line, column;
+    clang_getInstantiationLocation(includeStack[i], &includingFile, &line,
+                                   &column, 0);
+    fname = clang_getFileName(includingFile);
+    printf("  %s:%d:%d\n", clang_getCString(fname), line, column);
+    clang_disposeString(fname);
+  }
+  printf("\n");
+}
+
+void PrintInclusionStack(CXTranslationUnit TU) {
+  clang_getInclusions(TU, InclusionVisitor, NULL);
+}
+
+/******************************************************************************/
+/* Linkage testing.                                                           */
+/******************************************************************************/
+
+static enum CXChildVisitResult PrintLinkage(CXCursor cursor, CXCursor p,
+                                            CXClientData d) {
+  const char *linkage = 0;
+
+  if (clang_isInvalid(clang_getCursorKind(cursor)))
+    return CXChildVisit_Recurse;
+
+  switch (clang_getCursorLinkage(cursor)) {
+    case CXLinkage_Invalid: break;
+    case CXLinkage_NoLinkage: linkage = "NoLinkage"; break;
+    case CXLinkage_Internal: linkage = "Internal"; break;
+    case CXLinkage_UniqueExternal: linkage = "UniqueExternal"; break;
+    case CXLinkage_External: linkage = "External"; break;
+  }
+
+  if (linkage) {
+    PrintCursor(cursor);
+    printf("linkage=%s\n", linkage);
+  }
+
+  return CXChildVisit_Recurse;
+}
+
+/******************************************************************************/
+/* Loading ASTs/source.                                                       */
+/******************************************************************************/
+
+static int perform_test_load(CXIndex Idx, CXTranslationUnit TU,
+                             const char *filter, const char *prefix,
+                             CXCursorVisitor Visitor,
+                             PostVisitTU PV) {
+
+  if (prefix)
+    FileCheckPrefix = prefix;
+
+  if (Visitor) {
+    enum CXCursorKind K = CXCursor_NotImplemented;
+    enum CXCursorKind *ck = &K;
+    VisitorData Data;
+
+    /* Perform some simple filtering. */
+    if (!strcmp(filter, "all") || !strcmp(filter, "local")) ck = NULL;
+    else if (!strcmp(filter, "none")) K = (enum CXCursorKind) ~0;
+    else if (!strcmp(filter, "category")) K = CXCursor_ObjCCategoryDecl;
+    else if (!strcmp(filter, "interface")) K = CXCursor_ObjCInterfaceDecl;
+    else if (!strcmp(filter, "protocol")) K = CXCursor_ObjCProtocolDecl;
+    else if (!strcmp(filter, "function")) K = CXCursor_FunctionDecl;
+    else if (!strcmp(filter, "typedef")) K = CXCursor_TypedefDecl;
+    else if (!strcmp(filter, "scan-function")) Visitor = FunctionScanVisitor;
+    else {
+      fprintf(stderr, "Unknown filter for -test-load-tu: %s\n", filter);
+      return 1;
+    }
+
+    Data.TU = TU;
+    Data.Filter = ck;
+    clang_visitChildren(clang_getTranslationUnitCursor(TU), Visitor, &Data);
+  }
+
+  if (PV)
+    PV(TU);
+
+  PrintDiagnostics(TU);
+  clang_disposeTranslationUnit(TU);
+  return 0;
+}
+
+int perform_test_load_tu(const char *file, const char *filter,
+                         const char *prefix, CXCursorVisitor Visitor,
+                         PostVisitTU PV) {
+  CXIndex Idx;
+  CXTranslationUnit TU;
+  int result;
+  Idx = clang_createIndex(/* excludeDeclsFromPCH */
+                          !strcmp(filter, "local") ? 1 : 0,
+                          /* displayDiagnosics=*/1);
+
+  if (!CreateTranslationUnit(Idx, file, &TU)) {
+    clang_disposeIndex(Idx);
+    return 1;
+  }
+
+  result = perform_test_load(Idx, TU, filter, prefix, Visitor, PV);
+  clang_disposeIndex(Idx);
+  return result;
+}
+
+int perform_test_load_source(int argc, const char **argv,
+                             const char *filter, CXCursorVisitor Visitor,
+                             PostVisitTU PV) {
+  const char *UseExternalASTs =
+    getenv("CINDEXTEST_USE_EXTERNAL_AST_GENERATION");
+  CXIndex Idx;
+  CXTranslationUnit TU;
+  struct CXUnsavedFile *unsaved_files = 0;
+  int num_unsaved_files = 0;
+  int result;
+
+  Idx = clang_createIndex(/* excludeDeclsFromPCH */
+                          !strcmp(filter, "local") ? 1 : 0,
+                          /* displayDiagnosics=*/1);
+
+  if (UseExternalASTs && strlen(UseExternalASTs))
+    clang_setUseExternalASTGeneration(Idx, 1);
+
+  if (parse_remapped_files(argc, argv, 0, &unsaved_files, &num_unsaved_files)) {
+    clang_disposeIndex(Idx);
+    return -1;
+  }
+
+  TU = clang_createTranslationUnitFromSourceFile(Idx, 0,
+                                                 argc - num_unsaved_files,
+                                                 argv + num_unsaved_files,
+                                                 num_unsaved_files,
+                                                 unsaved_files);
+  if (!TU) {
+    fprintf(stderr, "Unable to load translation unit!\n");
+    clang_disposeIndex(Idx);
+    return 1;
+  }
+
+  result = perform_test_load(Idx, TU, filter, NULL, Visitor, PV);
+  free_remapped_files(unsaved_files, num_unsaved_files);
+  clang_disposeIndex(Idx);
+  return result;
+}
+
+/******************************************************************************/
+/* Logic for testing clang_getCursor().                                       */
+/******************************************************************************/
+
+static void print_cursor_file_scan(CXCursor cursor,
+                                   unsigned start_line, unsigned start_col,
+                                   unsigned end_line, unsigned end_col,
+                                   const char *prefix) {
+  printf("// %s: ", FileCheckPrefix);
+  if (prefix)
+    printf("-%s", prefix);
+  PrintExtent(stdout, start_line, start_col, end_line, end_col);
+  printf(" ");
+  PrintCursor(cursor);
+  printf("\n");
+}
+
+static int perform_file_scan(const char *ast_file, const char *source_file,
+                             const char *prefix) {
+  CXIndex Idx;
+  CXTranslationUnit TU;
+  FILE *fp;
+  CXCursor prevCursor = clang_getNullCursor();
+  CXFile file;
+  unsigned line = 1, col = 1;
+  unsigned start_line = 1, start_col = 1;
+
+  if (!(Idx = clang_createIndex(/* excludeDeclsFromPCH */ 1,
+                                /* displayDiagnosics=*/1))) {
+    fprintf(stderr, "Could not create Index\n");
+    return 1;
+  }
+
+  if (!CreateTranslationUnit(Idx, ast_file, &TU))
+    return 1;
+
+  if ((fp = fopen(source_file, "r")) == NULL) {
+    fprintf(stderr, "Could not open '%s'\n", source_file);
+    return 1;
+  }
+
+  file = clang_getFile(TU, source_file);
+  for (;;) {
+    CXCursor cursor;
+    int c = fgetc(fp);
+
+    if (c == '\n') {
+      ++line;
+      col = 1;
+    } else
+      ++col;
+
+    /* Check the cursor at this position, and dump the previous one if we have
+     * found something new.
+     */
+    cursor = clang_getCursor(TU, clang_getLocation(TU, file, line, col));
+    if ((c == EOF || !clang_equalCursors(cursor, prevCursor)) &&
+        prevCursor.kind != CXCursor_InvalidFile) {
+      print_cursor_file_scan(prevCursor, start_line, start_col,
+                             line, col, prefix);
+      start_line = line;
+      start_col = col;
+    }
+    if (c == EOF)
+      break;
+
+    prevCursor = cursor;
+  }
+
+  fclose(fp);
+  return 0;
+}
+
+/******************************************************************************/
+/* Logic for testing clang_codeComplete().                                    */
+/******************************************************************************/
+
+/* Parse file:line:column from the input string. Returns 0 on success, non-zero
+   on failure. If successful, the pointer *filename will contain newly-allocated
+   memory (that will be owned by the caller) to store the file name. */
+int parse_file_line_column(const char *input, char **filename, unsigned *line,
+                           unsigned *column, unsigned *second_line,
+                           unsigned *second_column) {
+  /* Find the second colon. */
+  const char *last_colon = strrchr(input, ':');
+  unsigned values[4], i;
+  unsigned num_values = (second_line && second_column)? 4 : 2;
+
+  char *endptr = 0;
+  if (!last_colon || last_colon == input) {
+    if (num_values == 4)
+      fprintf(stderr, "could not parse filename:line:column:line:column in "
+              "'%s'\n", input);
+    else
+      fprintf(stderr, "could not parse filename:line:column in '%s'\n", input);
+    return 1;
+  }
+
+  for (i = 0; i != num_values; ++i) {
+    const char *prev_colon;
+
+    /* Parse the next line or column. */
+    values[num_values - i - 1] = strtol(last_colon + 1, &endptr, 10);
+    if (*endptr != 0 && *endptr != ':') {
+      fprintf(stderr, "could not parse %s in '%s'\n",
+              (i % 2 ? "column" : "line"), input);
+      return 1;
+    }
+
+    if (i + 1 == num_values)
+      break;
+
+    /* Find the previous colon. */
+    prev_colon = last_colon - 1;
+    while (prev_colon != input && *prev_colon != ':')
+      --prev_colon;
+    if (prev_colon == input) {
+      fprintf(stderr, "could not parse %s in '%s'\n",
+              (i % 2 == 0? "column" : "line"), input);
+      return 1;
+    }
+
+    last_colon = prev_colon;
+  }
+
+  *line = values[0];
+  *column = values[1];
+
+  if (second_line && second_column) {
+    *second_line = values[2];
+    *second_column = values[3];
+  }
+
+  /* Copy the file name. */
+  *filename = (char*)malloc(last_colon - input + 1);
+  memcpy(*filename, input, last_colon - input);
+  (*filename)[last_colon - input] = 0;
+  return 0;
+}
+
+const char *
+clang_getCompletionChunkKindSpelling(enum CXCompletionChunkKind Kind) {
+  switch (Kind) {
+  case CXCompletionChunk_Optional: return "Optional";
+  case CXCompletionChunk_TypedText: return "TypedText";
+  case CXCompletionChunk_Text: return "Text";
+  case CXCompletionChunk_Placeholder: return "Placeholder";
+  case CXCompletionChunk_Informative: return "Informative";
+  case CXCompletionChunk_CurrentParameter: return "CurrentParameter";
+  case CXCompletionChunk_LeftParen: return "LeftParen";
+  case CXCompletionChunk_RightParen: return "RightParen";
+  case CXCompletionChunk_LeftBracket: return "LeftBracket";
+  case CXCompletionChunk_RightBracket: return "RightBracket";
+  case CXCompletionChunk_LeftBrace: return "LeftBrace";
+  case CXCompletionChunk_RightBrace: return "RightBrace";
+  case CXCompletionChunk_LeftAngle: return "LeftAngle";
+  case CXCompletionChunk_RightAngle: return "RightAngle";
+  case CXCompletionChunk_Comma: return "Comma";
+  case CXCompletionChunk_ResultType: return "ResultType";
+  case CXCompletionChunk_Colon: return "Colon";
+  case CXCompletionChunk_SemiColon: return "SemiColon";
+  case CXCompletionChunk_Equal: return "Equal";
+  case CXCompletionChunk_HorizontalSpace: return "HorizontalSpace";
+  case CXCompletionChunk_VerticalSpace: return "VerticalSpace";
+  }
+
+  return "Unknown";
+}
+
+void print_completion_string(CXCompletionString completion_string, FILE *file) {
+  int I, N;
+
+  N = clang_getNumCompletionChunks(completion_string);
+  for (I = 0; I != N; ++I) {
+    CXString text;
+    const char *cstr;
+    enum CXCompletionChunkKind Kind
+      = clang_getCompletionChunkKind(completion_string, I);
+
+    if (Kind == CXCompletionChunk_Optional) {
+      fprintf(file, "{Optional ");
+      print_completion_string(
+                clang_getCompletionChunkCompletionString(completion_string, I),
+                              file);
+      fprintf(file, "}");
+      continue;
+    }
+
+    text = clang_getCompletionChunkText(completion_string, I);
+    cstr = clang_getCString(text);
+    fprintf(file, "{%s %s}",
+            clang_getCompletionChunkKindSpelling(Kind),
+            cstr ? cstr : "");
+    clang_disposeString(text);
+  }
+
+}
+
+void print_completion_result(CXCompletionResult *completion_result,
+                             CXClientData client_data) {
+  FILE *file = (FILE *)client_data;
+  CXString ks = clang_getCursorKindSpelling(completion_result->CursorKind);
+
+  fprintf(file, "%s:", clang_getCString(ks));
+  clang_disposeString(ks);
+
+  print_completion_string(completion_result->CompletionString, file);
+  fprintf(file, "\n");
+}
+
+int perform_code_completion(int argc, const char **argv) {
+  const char *input = argv[1];
+  char *filename = 0;
+  unsigned line;
+  unsigned column;
+  CXIndex CIdx;
+  int errorCode;
+  struct CXUnsavedFile *unsaved_files = 0;
+  int num_unsaved_files = 0;
+  CXCodeCompleteResults *results = 0;
+
+  input += strlen("-code-completion-at=");
+  if ((errorCode = parse_file_line_column(input, &filename, &line, &column,
+                                          0, 0)))
+    return errorCode;
+
+  if (parse_remapped_files(argc, argv, 2, &unsaved_files, &num_unsaved_files))
+    return -1;
+
+  CIdx = clang_createIndex(0, 1);
+  results = clang_codeComplete(CIdx,
+                               argv[argc - 1], argc - num_unsaved_files - 3,
+                               argv + num_unsaved_files + 2,
+                               num_unsaved_files, unsaved_files,
+                               filename, line, column);
+
+  if (results) {
+    unsigned i, n = results->NumResults;
+    for (i = 0; i != n; ++i)
+      print_completion_result(results->Results + i, stdout);
+    n = clang_codeCompleteGetNumDiagnostics(results);
+    for (i = 0; i != n; ++i) {
+      CXDiagnostic diag = clang_codeCompleteGetDiagnostic(results, i);
+      PrintDiagnostic(diag);
+      clang_disposeDiagnostic(diag);
+    }
+    clang_disposeCodeCompleteResults(results);
+  }
+
+  clang_disposeIndex(CIdx);
+  free(filename);
+
+  free_remapped_files(unsaved_files, num_unsaved_files);
+
+  return 0;
+}
+
+typedef struct {
+  char *filename;
+  unsigned line;
+  unsigned column;
+} CursorSourceLocation;
+
+int inspect_cursor_at(int argc, const char **argv) {
+  CXIndex CIdx;
+  int errorCode;
+  struct CXUnsavedFile *unsaved_files = 0;
+  int num_unsaved_files = 0;
+  CXTranslationUnit TU;
+  CXCursor Cursor;
+  CursorSourceLocation *Locations = 0;
+  unsigned NumLocations = 0, Loc;
+
+  /* Count the number of locations. */
+  while (strstr(argv[NumLocations+1], "-cursor-at=") == argv[NumLocations+1])
+    ++NumLocations;
+
+  /* Parse the locations. */
+  assert(NumLocations > 0 && "Unable to count locations?");
+  Locations = (CursorSourceLocation *)malloc(
+                                  NumLocations * sizeof(CursorSourceLocation));
+  for (Loc = 0; Loc < NumLocations; ++Loc) {
+    const char *input = argv[Loc + 1] + strlen("-cursor-at=");
+    if ((errorCode = parse_file_line_column(input, &Locations[Loc].filename,
+                                            &Locations[Loc].line,
+                                            &Locations[Loc].column, 0, 0)))
+      return errorCode;
+  }
+
+  if (parse_remapped_files(argc, argv, NumLocations + 1, &unsaved_files,
+                           &num_unsaved_files))
+    return -1;
+
+  CIdx = clang_createIndex(0, 1);
+  TU = clang_createTranslationUnitFromSourceFile(CIdx, argv[argc - 1],
+                                  argc - num_unsaved_files - 2 - NumLocations,
+                                   argv + num_unsaved_files + 1 + NumLocations,
+                                                 num_unsaved_files,
+                                                 unsaved_files);
+  if (!TU) {
+    fprintf(stderr, "unable to parse input\n");
+    return -1;
+  }
+
+  for (Loc = 0; Loc < NumLocations; ++Loc) {
+    CXFile file = clang_getFile(TU, Locations[Loc].filename);
+    if (!file)
+      continue;
+
+    Cursor = clang_getCursor(TU,
+                             clang_getLocation(TU, file, Locations[Loc].line,
+                                               Locations[Loc].column));
+    PrintCursor(Cursor);
+    printf("\n");
+    free(Locations[Loc].filename);
+  }
+
+  PrintDiagnostics(TU);
+  clang_disposeTranslationUnit(TU);
+  clang_disposeIndex(CIdx);
+  free(Locations);
+  free_remapped_files(unsaved_files, num_unsaved_files);
+  return 0;
+}
+
+int perform_token_annotation(int argc, const char **argv) {
+  const char *input = argv[1];
+  char *filename = 0;
+  unsigned line, second_line;
+  unsigned column, second_column;
+  CXIndex CIdx;
+  CXTranslationUnit TU = 0;
+  int errorCode;
+  struct CXUnsavedFile *unsaved_files = 0;
+  int num_unsaved_files = 0;
+  CXToken *tokens;
+  unsigned num_tokens;
+  CXSourceRange range;
+  CXSourceLocation startLoc, endLoc;
+  CXFile file = 0;
+  CXCursor *cursors = 0;
+  unsigned i;
+
+  input += strlen("-test-annotate-tokens=");
+  if ((errorCode = parse_file_line_column(input, &filename, &line, &column,
+                                          &second_line, &second_column)))
+    return errorCode;
+
+  if (parse_remapped_files(argc, argv, 2, &unsaved_files, &num_unsaved_files))
+    return -1;
+
+  CIdx = clang_createIndex(0, 1);
+  TU = clang_createTranslationUnitFromSourceFile(CIdx, argv[argc - 1],
+                                                 argc - num_unsaved_files - 3,
+                                                 argv + num_unsaved_files + 2,
+                                                 num_unsaved_files,
+                                                 unsaved_files);
+  if (!TU) {
+    fprintf(stderr, "unable to parse input\n");
+    clang_disposeIndex(CIdx);
+    free(filename);
+    free_remapped_files(unsaved_files, num_unsaved_files);
+    return -1;
+  }
+  errorCode = 0;
+
+  file = clang_getFile(TU, filename);
+  if (!file) {
+    fprintf(stderr, "file %s is not in this translation unit\n", filename);
+    errorCode = -1;
+    goto teardown;
+  }
+
+  startLoc = clang_getLocation(TU, file, line, column);
+  if (clang_equalLocations(clang_getNullLocation(), startLoc)) {
+    fprintf(stderr, "invalid source location %s:%d:%d\n", filename, line,
+            column);
+    errorCode = -1;
+    goto teardown;
+  }
+
+  endLoc = clang_getLocation(TU, file, second_line, second_column);
+  if (clang_equalLocations(clang_getNullLocation(), endLoc)) {
+    fprintf(stderr, "invalid source location %s:%d:%d\n", filename,
+            second_line, second_column);
+    errorCode = -1;
+    goto teardown;
+  }
+
+  range = clang_getRange(startLoc, endLoc);
+  clang_tokenize(TU, range, &tokens, &num_tokens);
+  cursors = (CXCursor *)malloc(num_tokens * sizeof(CXCursor));
+  clang_annotateTokens(TU, tokens, num_tokens, cursors);
+  for (i = 0; i != num_tokens; ++i) {
+    const char *kind = "<unknown>";
+    CXString spelling = clang_getTokenSpelling(TU, tokens[i]);
+    CXSourceRange extent = clang_getTokenExtent(TU, tokens[i]);
+    unsigned start_line, start_column, end_line, end_column;
+
+    switch (clang_getTokenKind(tokens[i])) {
+    case CXToken_Punctuation: kind = "Punctuation"; break;
+    case CXToken_Keyword: kind = "Keyword"; break;
+    case CXToken_Identifier: kind = "Identifier"; break;
+    case CXToken_Literal: kind = "Literal"; break;
+    case CXToken_Comment: kind = "Comment"; break;
+    }
+    clang_getInstantiationLocation(clang_getRangeStart(extent),
+                                   0, &start_line, &start_column, 0);
+    clang_getInstantiationLocation(clang_getRangeEnd(extent),
+                                   0, &end_line, &end_column, 0);
+    printf("%s: \"%s\" ", kind, clang_getCString(spelling));
+    PrintExtent(stdout, start_line, start_column, end_line, end_column);
+    if (!clang_isInvalid(cursors[i].kind)) {
+      printf(" ");
+      PrintCursor(cursors[i]);
+    }
+    printf("\n");
+  }
+  free(cursors);
+
+ teardown:
+  PrintDiagnostics(TU);
+  clang_disposeTranslationUnit(TU);
+  clang_disposeIndex(CIdx);
+  free(filename);
+  free_remapped_files(unsaved_files, num_unsaved_files);
+  return errorCode;
+}
+
+/******************************************************************************/
+/* USR printing.                                                              */
+/******************************************************************************/
+
+static int insufficient_usr(const char *kind, const char *usage) {
+  fprintf(stderr, "USR for '%s' requires: %s\n", kind, usage);
+  return 1;
+}
+
+static unsigned isUSR(const char *s) {
+  return s[0] == 'c' && s[1] == ':';
+}
+
+static int not_usr(const char *s, const char *arg) {
+  fprintf(stderr, "'%s' argument ('%s') is not a USR\n", s, arg);
+  return 1;
+}
+
+static void print_usr(CXString usr) {
+  const char *s = clang_getCString(usr);
+  printf("%s\n", s);
+  clang_disposeString(usr);
+}
+
+static void display_usrs() {
+  fprintf(stderr, "-print-usrs options:\n"
+        " ObjCCategory <class name> <category name>\n"
+        " ObjCClass <class name>\n"
+        " ObjCIvar <ivar name> <class USR>\n"
+        " ObjCMethod <selector> [0=class method|1=instance method] "
+            "<class USR>\n"
+          " ObjCProperty <property name> <class USR>\n"
+          " ObjCProtocol <protocol name>\n");
+}
+
+int print_usrs(const char **I, const char **E) {
+  while (I != E) {
+    const char *kind = *I;
+    unsigned len = strlen(kind);
+    switch (len) {
+      case 8:
+        if (memcmp(kind, "ObjCIvar", 8) == 0) {
+          if (I + 2 >= E)
+            return insufficient_usr(kind, "<ivar name> <class USR>");
+          if (!isUSR(I[2]))
+            return not_usr("<class USR>", I[2]);
+          else {
+            CXString x;
+            x.Spelling = I[2];
+            x.MustFreeString = 0;
+            print_usr(clang_constructUSR_ObjCIvar(I[1], x));
+          }
+
+          I += 3;
+          continue;
+        }
+        break;
+      case 9:
+        if (memcmp(kind, "ObjCClass", 9) == 0) {
+          if (I + 1 >= E)
+            return insufficient_usr(kind, "<class name>");
+          print_usr(clang_constructUSR_ObjCClass(I[1]));
+          I += 2;
+          continue;
+        }
+        break;
+      case 10:
+        if (memcmp(kind, "ObjCMethod", 10) == 0) {
+          if (I + 3 >= E)
+            return insufficient_usr(kind, "<method selector> "
+                "[0=class method|1=instance method] <class USR>");
+          if (!isUSR(I[3]))
+            return not_usr("<class USR>", I[3]);
+          else {
+            CXString x;
+            x.Spelling = I[3];
+            x.MustFreeString = 0;
+            print_usr(clang_constructUSR_ObjCMethod(I[1], atoi(I[2]), x));
+          }
+          I += 4;
+          continue;
+        }
+        break;
+      case 12:
+        if (memcmp(kind, "ObjCCategory", 12) == 0) {
+          if (I + 2 >= E)
+            return insufficient_usr(kind, "<class name> <category name>");
+          print_usr(clang_constructUSR_ObjCCategory(I[1], I[2]));
+          I += 3;
+          continue;
+        }
+        if (memcmp(kind, "ObjCProtocol", 12) == 0) {
+          if (I + 1 >= E)
+            return insufficient_usr(kind, "<protocol name>");
+          print_usr(clang_constructUSR_ObjCProtocol(I[1]));
+          I += 2;
+          continue;
+        }
+        if (memcmp(kind, "ObjCProperty", 12) == 0) {
+          if (I + 2 >= E)
+            return insufficient_usr(kind, "<property name> <class USR>");
+          if (!isUSR(I[2]))
+            return not_usr("<class USR>", I[2]);
+          else {
+            CXString x;
+            x.Spelling = I[2];
+            x.MustFreeString = 0;
+            print_usr(clang_constructUSR_ObjCProperty(I[1], x));
+          }
+          I += 3;
+          continue;
+        }
+        break;
+      default:
+        break;
+    }
+    break;
+  }
+
+  if (I != E) {
+    fprintf(stderr, "Invalid USR kind: %s\n", *I);
+    display_usrs();
+    return 1;
+  }
+  return 0;
+}
+
+int print_usrs_file(const char *file_name) {
+  char line[2048];
+  const char *args[128];
+  unsigned numChars = 0;
+
+  FILE *fp = fopen(file_name, "r");
+  if (!fp) {
+    fprintf(stderr, "error: cannot open '%s'\n", file_name);
+    return 1;
+  }
+
+  /* This code is not really all that safe, but it works fine for testing. */
+  while (!feof(fp)) {
+    char c = fgetc(fp);
+    if (c == '\n') {
+      unsigned i = 0;
+      const char *s = 0;
+
+      if (numChars == 0)
+        continue;
+
+      line[numChars] = '\0';
+      numChars = 0;
+
+      if (line[0] == '/' && line[1] == '/')
+        continue;
+
+      s = strtok(line, " ");
+      while (s) {
+        args[i] = s;
+        ++i;
+        s = strtok(0, " ");
+      }
+      if (print_usrs(&args[0], &args[i]))
+        return 1;
+    }
+    else
+      line[numChars++] = c;
+  }
+
+  fclose(fp);
+  return 0;
+}
+
+/******************************************************************************/
+/* Command line processing.                                                   */
+/******************************************************************************/
+
+static CXCursorVisitor GetVisitor(const char *s) {
+  if (s[0] == '\0')
+    return FilteredPrintingVisitor;
+  if (strcmp(s, "-usrs") == 0)
+    return USRVisitor;
+  return NULL;
+}
+
+static void print_usage(void) {
+  fprintf(stderr,
+    "usage: c-index-test -code-completion-at=<site> <compiler arguments>\n"
+    "       c-index-test -cursor-at=<site> <compiler arguments>\n"
+    "       c-index-test -test-file-scan <AST file> <source file> "
+          "[FileCheck prefix]\n"
+    "       c-index-test -test-load-tu <AST file> <symbol filter> "
+          "[FileCheck prefix]\n"
+    "       c-index-test -test-load-tu-usrs <AST file> <symbol filter> "
+           "[FileCheck prefix]\n"
+    "       c-index-test -test-load-source <symbol filter> {<args>}*\n"
+    "       c-index-test -test-load-source-usrs <symbol filter> {<args>}*\n");
+  fprintf(stderr,
+    "       c-index-test -test-annotate-tokens=<range> {<args>}*\n"
+    "       c-index-test -test-inclusion-stack-source {<args>}*\n"
+    "       c-index-test -test-inclusion-stack-tu <AST file>\n"
+    "       c-index-test -test-print-linkage-source {<args>}*\n"
+    "       c-index-test -print-usr [<CursorKind> {<args>}]*\n"
+    "       c-index-test -print-usr-file <file>\n\n"
+    " <symbol filter> values:\n%s",
+    "   all - load all symbols, including those from PCH\n"
+    "   local - load all symbols except those in PCH\n"
+    "   category - only load ObjC categories (non-PCH)\n"
+    "   interface - only load ObjC interfaces (non-PCH)\n"
+    "   protocol - only load ObjC protocols (non-PCH)\n"
+    "   function - only load functions (non-PCH)\n"
+    "   typedef - only load typdefs (non-PCH)\n"
+    "   scan-function - scan function bodies (non-PCH)\n\n");
+}
+
+int main(int argc, const char **argv) {
+  clang_enableStackTraces();
+  if (argc > 2 && strstr(argv[1], "-code-completion-at=") == argv[1])
+    return perform_code_completion(argc, argv);
+  if (argc > 2 && strstr(argv[1], "-cursor-at=") == argv[1])
+    return inspect_cursor_at(argc, argv);
+  else if (argc >= 4 && strncmp(argv[1], "-test-load-tu", 13) == 0) {
+    CXCursorVisitor I = GetVisitor(argv[1] + 13);
+    if (I)
+      return perform_test_load_tu(argv[2], argv[3], argc >= 5 ? argv[4] : 0, I,
+                                  NULL);
+  }
+  else if (argc >= 4 && strncmp(argv[1], "-test-load-source", 17) == 0) {
+    CXCursorVisitor I = GetVisitor(argv[1] + 17);
+    if (I)
+      return perform_test_load_source(argc - 3, argv + 3, argv[2], I, NULL);
+  }
+  else if (argc >= 4 && strcmp(argv[1], "-test-file-scan") == 0)
+    return perform_file_scan(argv[2], argv[3],
+                             argc >= 5 ? argv[4] : 0);
+  else if (argc > 2 && strstr(argv[1], "-test-annotate-tokens=") == argv[1])
+    return perform_token_annotation(argc, argv);
+  else if (argc > 2 && strcmp(argv[1], "-test-inclusion-stack-source") == 0)
+    return perform_test_load_source(argc - 2, argv + 2, "all", NULL,
+                                    PrintInclusionStack);
+  else if (argc > 2 && strcmp(argv[1], "-test-inclusion-stack-tu") == 0)
+    return perform_test_load_tu(argv[2], "all", NULL, NULL,
+                                PrintInclusionStack);
+  else if (argc > 2 && strcmp(argv[1], "-test-print-linkage-source") == 0)
+    return perform_test_load_source(argc - 2, argv + 2, "all", PrintLinkage,
+                                    NULL);
+  else if (argc > 1 && strcmp(argv[1], "-print-usr") == 0) {
+    if (argc > 2)
+      return print_usrs(argv + 2, argv + argc);
+    else {
+      display_usrs();
+      return 1;
+    }
+  }
+  else if (argc > 2 && strcmp(argv[1], "-print-usr-file") == 0)
+    return print_usrs_file(argv[2]);
+
+  print_usage();
+  return 1;
+}
diff --git a/tools/driver/CMakeLists.txt b/tools/driver/CMakeLists.txt
new file mode 100644
index 0000000..c4320b0
--- /dev/null
+++ b/tools/driver/CMakeLists.txt
@@ -0,0 +1,48 @@
+set(LLVM_NO_RTTI 1)
+
+set( LLVM_USED_LIBS
+  clangFrontend
+  clangDriver
+  clangCodeGen
+  clangSema
+  clangChecker
+  clangAnalysis
+  clangRewrite
+  clangAST
+  clangParse
+  clangLex
+  clangBasic
+  )
+
+set( LLVM_LINK_COMPONENTS
+  ${LLVM_TARGETS_TO_BUILD}
+  bitreader
+  bitwriter
+  codegen
+  ipo
+  selectiondag
+  )
+
+add_clang_executable(clang
+  driver.cpp
+  cc1_main.cpp
+  )
+
+if(UNIX)
+  set(CLANGXX_LINK_OR_COPY create_symlink)
+else()
+  set(CLANGXX_LINK_OR_COPY copy)
+endif()
+
+# Create the clang++ symlink in the build directory.
+add_custom_target(clang++ ALL
+  ${CMAKE_COMMAND} -E ${CLANGXX_LINK_OR_COPY}
+    "${LLVM_BINARY_DIR}/bin/${CMAKE_CFG_INTDIR}/clang${CMAKE_EXECUTABLE_SUFFIX}"
+    "${LLVM_BINARY_DIR}/bin/${CMAKE_CFG_INTDIR}/clang++${CMAKE_EXECUTABLE_SUFFIX}"
+  DEPENDS clang)
+
+install(TARGETS clang
+  RUNTIME DESTINATION bin)
+
+# Create the clang++ symlink at installation time.
+install(CODE "execute_process(COMMAND \"${CMAKE_COMMAND}\" -E ${CLANGXX_LINK_OR_COPY} \"${CMAKE_INSTALL_PREFIX}/bin/clang${CMAKE_EXECUTABLE_SUFFIX}\" \"\$ENV{DESTDIR}/\${CMAKE_INSTALL_PREFIX}/bin/clang++${CMAKE_EXECUTABLE_SUFFIX}\")")
diff --git a/tools/driver/Makefile b/tools/driver/Makefile
new file mode 100644
index 0000000..f88d229
--- /dev/null
+++ b/tools/driver/Makefile
@@ -0,0 +1,42 @@
+##===- tools/driver/Makefile -------------------------------*- Makefile -*-===##
+#
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+LEVEL = ../../../..
+
+TOOLNAME = clang
+ifndef CLANG_IS_PRODUCTION
+TOOLALIAS = clang++
+else
+  ifdef CLANGXX_IS_PRODUCTION
+    TOOLALIAS = clang++
+  endif
+endif
+CPP.Flags += -I$(PROJ_SRC_DIR)/../../include -I$(PROJ_OBJ_DIR)/../../include
+
+# Clang tool has no plugins, optimize startup time.
+TOOL_NO_EXPORTS = 1
+
+# Include this here so we can get the configuration of the targets that have
+# been configured for construction. We have to do this early so we can set up
+# LINK_COMPONENTS before including Makefile.rules
+include $(LEVEL)/Makefile.config
+
+LINK_COMPONENTS := $(TARGETS_TO_BUILD) bitreader bitwriter codegen ipo selectiondag
+USEDLIBS = clangFrontend.a clangDriver.a clangCodeGen.a clangSema.a \
+           clangChecker.a clangAnalysis.a clangRewrite.a  clangAST.a \
+           clangParse.a clangLex.a clangBasic.a
+
+include $(LLVM_SRC_ROOT)/Makefile.rules
+
+# Translate make variable to define when building a "production" clang.
+ifdef CLANG_IS_PRODUCTION
+CPP.Defines += -DCLANG_IS_PRODUCTION
+endif
+ifdef CLANGXX_IS_PRODUCTION
+CPP.Defines += -DCLANGXX_IS_PRODUCTION
+endif
diff --git a/tools/driver/cc1_main.cpp b/tools/driver/cc1_main.cpp
new file mode 100644
index 0000000..144a734
--- /dev/null
+++ b/tools/driver/cc1_main.cpp
@@ -0,0 +1,307 @@
+//===-- cc1_main.cpp - Clang CC1 Driver -----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This is the entry point to the clang -cc1 functionality, which implements the
+// core compiler functionality along with a number of additional tools for
+// demonstration and testing purposes.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Driver/Arg.h"
+#include "clang/Driver/ArgList.h"
+#include "clang/Driver/CC1Options.h"
+#include "clang/Driver/DriverDiagnostic.h"
+#include "clang/Driver/OptTable.h"
+#include "clang/Frontend/CodeGenAction.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Frontend/CompilerInvocation.h"
+#include "clang/Frontend/FrontendActions.h"
+#include "clang/Frontend/FrontendDiagnostic.h"
+#include "clang/Frontend/FrontendPluginRegistry.h"
+#include "clang/Frontend/TextDiagnosticBuffer.h"
+#include "clang/Frontend/TextDiagnosticPrinter.h"
+#include "llvm/LLVMContext.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/Timer.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/System/DynamicLibrary.h"
+#include "llvm/Target/TargetSelect.h"
+#include <cstdio>
+using namespace clang;
+
+//===----------------------------------------------------------------------===//
+// Main driver
+//===----------------------------------------------------------------------===//
+
+void LLVMErrorHandler(void *UserData, const std::string &Message) {
+  Diagnostic &Diags = *static_cast<Diagnostic*>(UserData);
+
+  Diags.Report(diag::err_fe_error_backend) << Message;
+
+  // We cannot recover from llvm errors.
+  exit(1);
+}
+
+static FrontendAction *CreateFrontendBaseAction(CompilerInstance &CI) {
+  using namespace clang::frontend;
+
+  switch (CI.getFrontendOpts().ProgramAction) {
+  default:
+    llvm_unreachable("Invalid program action!");
+
+  case ASTDump:                return new ASTDumpAction();
+  case ASTPrint:               return new ASTPrintAction();
+  case ASTPrintXML:            return new ASTPrintXMLAction();
+  case ASTView:                return new ASTViewAction();
+  case DumpRawTokens:          return new DumpRawTokensAction();
+  case DumpTokens:             return new DumpTokensAction();
+  case EmitAssembly:           return new EmitAssemblyAction();
+  case EmitBC:                 return new EmitBCAction();
+  case EmitHTML:               return new HTMLPrintAction();
+  case EmitLLVM:               return new EmitLLVMAction();
+  case EmitLLVMOnly:           return new EmitLLVMOnlyAction();
+  case EmitObj:                return new EmitObjAction();
+  case FixIt:                  return new FixItAction();
+  case GeneratePCH:            return new GeneratePCHAction();
+  case GeneratePTH:            return new GeneratePTHAction();
+  case InheritanceView:        return new InheritanceViewAction();
+  case InitOnly:               return new InitOnlyAction();
+  case ParseNoop:              return new ParseOnlyAction();
+  case ParsePrintCallbacks:    return new PrintParseAction();
+  case ParseSyntaxOnly:        return new SyntaxOnlyAction();
+
+  case PluginAction: {
+    if (CI.getFrontendOpts().ActionName == "help") {
+      llvm::errs() << "clang -cc1 plugins:\n";
+      for (FrontendPluginRegistry::iterator it =
+             FrontendPluginRegistry::begin(),
+             ie = FrontendPluginRegistry::end();
+           it != ie; ++it)
+        llvm::errs() << "  " << it->getName() << " - " << it->getDesc() << "\n";
+      return 0;
+    }
+
+    for (FrontendPluginRegistry::iterator it =
+           FrontendPluginRegistry::begin(), ie = FrontendPluginRegistry::end();
+         it != ie; ++it) {
+      if (it->getName() == CI.getFrontendOpts().ActionName)
+        return it->instantiate();
+    }
+
+    CI.getDiagnostics().Report(diag::err_fe_invalid_plugin_name)
+      << CI.getFrontendOpts().ActionName;
+    return 0;
+  }
+
+  case PrintDeclContext:       return new DeclContextPrintAction();
+  case PrintPreprocessedInput: return new PrintPreprocessedAction();
+  case RewriteMacros:          return new RewriteMacrosAction();
+  case RewriteObjC:            return new RewriteObjCAction();
+  case RewriteTest:            return new RewriteTestAction();
+  case RunAnalysis:            return new AnalysisAction();
+  case RunPreprocessorOnly:    return new PreprocessOnlyAction();
+  }
+}
+
+static FrontendAction *CreateFrontendAction(CompilerInstance &CI) {
+  // Create the underlying action.
+  FrontendAction *Act = CreateFrontendBaseAction(CI);
+  if (!Act)
+    return 0;
+
+  // If there are any AST files to merge, create a frontend action
+  // adaptor to perform the merge.
+  if (!CI.getFrontendOpts().ASTMergeFiles.empty())
+    Act = new ASTMergeAction(Act, &CI.getFrontendOpts().ASTMergeFiles[0],
+                             CI.getFrontendOpts().ASTMergeFiles.size());
+
+  return Act;
+}
+
+// FIXME: Define the need for this testing away.
+static int cc1_test(Diagnostic &Diags,
+                    const char **ArgBegin, const char **ArgEnd) {
+  using namespace clang::driver;
+
+  llvm::errs() << "cc1 argv:";
+  for (const char **i = ArgBegin; i != ArgEnd; ++i)
+    llvm::errs() << " \"" << *i << '"';
+  llvm::errs() << "\n";
+
+  // Parse the arguments.
+  OptTable *Opts = createCC1OptTable();
+  unsigned MissingArgIndex, MissingArgCount;
+  InputArgList *Args = Opts->ParseArgs(ArgBegin, ArgEnd,
+                                       MissingArgIndex, MissingArgCount);
+
+  // Check for missing argument error.
+  if (MissingArgCount)
+    Diags.Report(clang::diag::err_drv_missing_argument)
+      << Args->getArgString(MissingArgIndex) << MissingArgCount;
+
+  // Dump the parsed arguments.
+  llvm::errs() << "cc1 parsed options:\n";
+  for (ArgList::const_iterator it = Args->begin(), ie = Args->end();
+       it != ie; ++it)
+    (*it)->dump();
+
+  // Create a compiler invocation.
+  llvm::errs() << "cc1 creating invocation.\n";
+  CompilerInvocation Invocation;
+  CompilerInvocation::CreateFromArgs(Invocation, ArgBegin, ArgEnd, Diags);
+
+  // Convert the invocation back to argument strings.
+  std::vector<std::string> InvocationArgs;
+  Invocation.toArgs(InvocationArgs);
+
+  // Dump the converted arguments.
+  llvm::SmallVector<const char*, 32> Invocation2Args;
+  llvm::errs() << "invocation argv :";
+  for (unsigned i = 0, e = InvocationArgs.size(); i != e; ++i) {
+    Invocation2Args.push_back(InvocationArgs[i].c_str());
+    llvm::errs() << " \"" << InvocationArgs[i] << '"';
+  }
+  llvm::errs() << "\n";
+
+  // Convert those arguments to another invocation, and check that we got the
+  // same thing.
+  CompilerInvocation Invocation2;
+  CompilerInvocation::CreateFromArgs(Invocation2, Invocation2Args.begin(),
+                                     Invocation2Args.end(), Diags);
+
+  // FIXME: Implement CompilerInvocation comparison.
+  if (true) {
+    //llvm::errs() << "warning: Invocations differ!\n";
+
+    std::vector<std::string> Invocation2Args;
+    Invocation2.toArgs(Invocation2Args);
+    llvm::errs() << "invocation2 argv:";
+    for (unsigned i = 0, e = Invocation2Args.size(); i != e; ++i)
+      llvm::errs() << " \"" << Invocation2Args[i] << '"';
+    llvm::errs() << "\n";
+  }
+
+  return 0;
+}
+
+int cc1_main(const char **ArgBegin, const char **ArgEnd,
+             const char *Argv0, void *MainAddr) {
+  llvm::OwningPtr<CompilerInstance> Clang(new CompilerInstance());
+
+  Clang->setLLVMContext(new llvm::LLVMContext());
+
+  // Run clang -cc1 test.
+  if (ArgBegin != ArgEnd && llvm::StringRef(ArgBegin[0]) == "-cc1test") {
+    TextDiagnosticPrinter DiagClient(llvm::errs(), DiagnosticOptions());
+    Diagnostic Diags(&DiagClient);
+    return cc1_test(Diags, ArgBegin + 1, ArgEnd);
+  }
+
+  // Initialize targets first, so that --version shows registered targets.
+  llvm::InitializeAllTargets();
+  llvm::InitializeAllAsmPrinters();
+  llvm::InitializeAllAsmParsers();
+
+  // Buffer diagnostics from argument parsing so that we can output them using a
+  // well formed diagnostic object.
+  TextDiagnosticBuffer DiagsBuffer;
+  Diagnostic Diags(&DiagsBuffer);
+  CompilerInvocation::CreateFromArgs(Clang->getInvocation(), ArgBegin, ArgEnd,
+                                     Diags);
+
+  // Infer the builtin include path if unspecified.
+  if (Clang->getHeaderSearchOpts().UseBuiltinIncludes &&
+      Clang->getHeaderSearchOpts().ResourceDir.empty())
+    Clang->getHeaderSearchOpts().ResourceDir =
+      CompilerInvocation::GetResourcesPath(Argv0, MainAddr);
+
+  // Honor -help.
+  if (Clang->getFrontendOpts().ShowHelp) {
+    llvm::OwningPtr<driver::OptTable> Opts(driver::createCC1OptTable());
+    Opts->PrintHelp(llvm::outs(), "clang -cc1",
+                    "LLVM 'Clang' Compiler: http://clang.llvm.org");
+    return 0;
+  }
+
+  // Honor -version.
+  //
+  // FIXME: Use a better -version message?
+  if (Clang->getFrontendOpts().ShowVersion) {
+    llvm::cl::PrintVersionMessage();
+    return 0;
+  }
+
+  // Honor -mllvm.
+  //
+  // FIXME: Remove this, one day.
+  if (!Clang->getFrontendOpts().LLVMArgs.empty()) {
+    unsigned NumArgs = Clang->getFrontendOpts().LLVMArgs.size();
+    const char **Args = new const char*[NumArgs + 2];
+    Args[0] = "clang (LLVM option parsing)";
+    for (unsigned i = 0; i != NumArgs; ++i)
+      Args[i + 1] = Clang->getFrontendOpts().LLVMArgs[i].c_str();
+    Args[NumArgs + 1] = 0;
+    llvm::cl::ParseCommandLineOptions(NumArgs + 1, const_cast<char **>(Args));
+  }
+
+  // Create the actual diagnostics engine.
+  Clang->createDiagnostics(ArgEnd - ArgBegin, const_cast<char**>(ArgBegin));
+  if (!Clang->hasDiagnostics())
+    return 1;
+
+  // Set an error handler, so that any LLVM backend diagnostics go through our
+  // error handler.
+  llvm::install_fatal_error_handler(LLVMErrorHandler,
+                                  static_cast<void*>(&Clang->getDiagnostics()));
+
+  DiagsBuffer.FlushDiagnostics(Clang->getDiagnostics());
+
+  // Load any requested plugins.
+  for (unsigned i = 0,
+         e = Clang->getFrontendOpts().Plugins.size(); i != e; ++i) {
+    const std::string &Path = Clang->getFrontendOpts().Plugins[i];
+    std::string Error;
+    if (llvm::sys::DynamicLibrary::LoadLibraryPermanently(Path.c_str(), &Error))
+      Diags.Report(diag::err_fe_unable_to_load_plugin) << Path << Error;
+  }
+
+  // If there were errors in processing arguments, don't do anything else.
+  bool Success = false;
+  if (!Clang->getDiagnostics().getNumErrors()) {
+    // Create and execute the frontend action.
+    llvm::OwningPtr<FrontendAction> Act(CreateFrontendAction(*Clang));
+    if (Act) {
+      Success = Clang->ExecuteAction(*Act);
+      if (Clang->getFrontendOpts().DisableFree)
+        Act.take();
+    }
+  }
+
+  // If any timers were active but haven't been destroyed yet, print their
+  // results now.  This happens in -disable-free mode.
+  llvm::TimerGroup::printAll(llvm::errs());
+  
+  // When running with -disable-free, don't do any destruction or shutdown.
+  if (Clang->getFrontendOpts().DisableFree) {
+    if (Clang->getFrontendOpts().ShowStats)
+      llvm::PrintStatistics();
+    Clang.take();
+    return !Success;
+  }
+
+  // Managed static deconstruction. Useful for making things like
+  // -time-passes usable.
+  llvm::llvm_shutdown();
+
+  return !Success;
+}
diff --git a/tools/driver/driver.cpp b/tools/driver/driver.cpp
new file mode 100644
index 0000000..3f1cca1
--- /dev/null
+++ b/tools/driver/driver.cpp
@@ -0,0 +1,285 @@
+//===-- driver.cpp - Clang GCC-Compatible Driver --------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This is the entry point to the clang driver; it is a thin wrapper
+// for functionality in the Driver clang library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Driver/Compilation.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/Option.h"
+#include "clang/Frontend/DiagnosticOptions.h"
+#include "clang/Frontend/TextDiagnosticPrinter.h"
+
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/Config/config.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/PrettyStackTrace.h"
+#include "llvm/Support/Regex.h"
+#include "llvm/Support/Timer.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/System/Host.h"
+#include "llvm/System/Path.h"
+#include "llvm/System/Signals.h"
+using namespace clang;
+using namespace clang::driver;
+
+llvm::sys::Path GetExecutablePath(const char *Argv0, bool CanonicalPrefixes) {
+  if (!CanonicalPrefixes)
+    return llvm::sys::Path(Argv0);
+
+  // This just needs to be some symbol in the binary; C++ doesn't
+  // allow taking the address of ::main however.
+  void *P = (void*) (intptr_t) GetExecutablePath;
+  return llvm::sys::Path::GetMainExecutable(Argv0, P);
+}
+
+static const char *SaveStringInSet(std::set<std::string> &SavedStrings,
+                                   llvm::StringRef S) {
+  return SavedStrings.insert(S).first->c_str();
+}
+
+/// ApplyQAOverride - Apply a list of edits to the input argument lists.
+///
+/// The input string is a space separate list of edits to perform,
+/// they are applied in order to the input argument lists. Edits
+/// should be one of the following forms:
+///
+///  '#': Silence information about the changes to the command line arguments.
+///
+///  '^': Add FOO as a new argument at the beginning of the command line.
+///
+///  '+': Add FOO as a new argument at the end of the command line.
+///
+///  's/XXX/YYY/': Substitute the regular expression XXX with YYY in the command
+///  line.
+///
+///  'xOPTION': Removes all instances of the literal argument OPTION.
+///
+///  'XOPTION': Removes all instances of the literal argument OPTION,
+///  and the following argument.
+///
+///  'Ox': Removes all flags matching 'O' or 'O[sz0-9]' and adds 'Ox'
+///  at the end of the command line.
+///
+/// \param OS - The stream to write edit information to.
+/// \param Args - The vector of command line arguments.
+/// \param Edit - The override command to perform.
+/// \param SavedStrings - Set to use for storing string representations.
+static void ApplyOneQAOverride(llvm::raw_ostream &OS,
+                               std::vector<const char*> &Args,
+                               llvm::StringRef Edit,
+                               std::set<std::string> &SavedStrings) {
+  // This does not need to be efficient.
+
+  if (Edit[0] == '^') {
+    const char *Str =
+      SaveStringInSet(SavedStrings, Edit.substr(1));
+    OS << "### Adding argument " << Str << " at beginning\n";
+    Args.insert(Args.begin() + 1, Str);
+  } else if (Edit[0] == '+') {
+    const char *Str =
+      SaveStringInSet(SavedStrings, Edit.substr(1));
+    OS << "### Adding argument " << Str << " at end\n";
+    Args.push_back(Str);
+  } else if (Edit[0] == 's' && Edit[1] == '/' && Edit.endswith("/") &&
+             Edit.slice(2, Edit.size()-1).find('/') != llvm::StringRef::npos) {
+    llvm::StringRef MatchPattern = Edit.substr(2).split('/').first;
+    llvm::StringRef ReplPattern = Edit.substr(2).split('/').second;
+    ReplPattern = ReplPattern.slice(0, ReplPattern.size()-1);
+
+    for (unsigned i = 1, e = Args.size(); i != e; ++i) {
+      std::string Repl = llvm::Regex(MatchPattern).sub(ReplPattern, Args[i]);
+
+      if (Repl != Args[i]) {
+        OS << "### Replacing '" << Args[i] << "' with '" << Repl << "'\n";
+        Args[i] = SaveStringInSet(SavedStrings, Repl);
+      }
+    }
+  } else if (Edit[0] == 'x' || Edit[0] == 'X') {
+    std::string Option = Edit.substr(1, std::string::npos);
+    for (unsigned i = 1; i < Args.size();) {
+      if (Option == Args[i]) {
+        OS << "### Deleting argument " << Args[i] << '\n';
+        Args.erase(Args.begin() + i);
+        if (Edit[0] == 'X') {
+          if (i < Args.size()) {
+            OS << "### Deleting argument " << Args[i] << '\n';
+            Args.erase(Args.begin() + i);
+          } else
+            OS << "### Invalid X edit, end of command line!\n";
+        }
+      } else
+        ++i;
+    }
+  } else if (Edit[0] == 'O') {
+    for (unsigned i = 1; i < Args.size();) {
+      const char *A = Args[i];
+      if (A[0] == '-' && A[1] == 'O' &&
+          (A[2] == '\0' ||
+           (A[3] == '\0' && (A[2] == 's' || A[2] == 'z' ||
+                             ('0' <= A[2] && A[2] <= '9'))))) {
+        OS << "### Deleting argument " << Args[i] << '\n';
+        Args.erase(Args.begin() + i);
+      } else
+        ++i;
+    }
+    OS << "### Adding argument " << Edit << " at end\n";
+    Args.push_back(SaveStringInSet(SavedStrings, '-' + Edit.str()));
+  } else {
+    OS << "### Unrecognized edit: " << Edit << "\n";
+  }
+}
+
+/// ApplyQAOverride - Apply a comma separate list of edits to the
+/// input argument lists. See ApplyOneQAOverride.
+static void ApplyQAOverride(std::vector<const char*> &Args,
+                            const char *OverrideStr,
+                            std::set<std::string> &SavedStrings) {
+  llvm::raw_ostream *OS = &llvm::errs();
+
+  if (OverrideStr[0] == '#') {
+    ++OverrideStr;
+    OS = &llvm::nulls();
+  }
+
+  *OS << "### QA_OVERRIDE_GCC3_OPTIONS: " << OverrideStr << "\n";
+
+  // This does not need to be efficient.
+
+  const char *S = OverrideStr;
+  while (*S) {
+    const char *End = ::strchr(S, ' ');
+    if (!End)
+      End = S + strlen(S);
+    if (End != S)
+      ApplyOneQAOverride(*OS, Args, std::string(S, End), SavedStrings);
+    S = End;
+    if (*S != '\0')
+      ++S;
+  }
+}
+
+extern int cc1_main(const char **ArgBegin, const char **ArgEnd,
+                    const char *Argv0, void *MainAddr);
+
+int main(int argc, const char **argv) {
+  llvm::sys::PrintStackTraceOnErrorSignal();
+  llvm::PrettyStackTraceProgram X(argc, argv);
+
+  // Dispatch to cc1_main if appropriate.
+  if (argc > 1 && llvm::StringRef(argv[1]) == "-cc1")
+    return cc1_main(argv+2, argv+argc, argv[0],
+                    (void*) (intptr_t) GetExecutablePath);
+
+  bool CanonicalPrefixes = true;
+  for (int i = 1; i < argc; ++i) {
+    if (llvm::StringRef(argv[i]) == "-no-canonical-prefixes") {
+      CanonicalPrefixes = false;
+      break;
+    }
+  }
+
+  llvm::sys::Path Path = GetExecutablePath(argv[0], CanonicalPrefixes);
+
+  TextDiagnosticPrinter DiagClient(llvm::errs(), DiagnosticOptions());
+  DiagClient.setPrefix(Path.getBasename());
+
+  Diagnostic Diags(&DiagClient);
+
+#ifdef CLANG_IS_PRODUCTION
+  const bool IsProduction = true;
+#  ifdef CLANGXX_IS_PRODUCTION
+  const bool CXXIsProduction = true;
+#  else
+  const bool CXXIsProduction = false;
+#  endif
+#else
+  const bool IsProduction = false;
+  const bool CXXIsProduction = false;
+#endif
+  Driver TheDriver(Path.getBasename(), Path.getDirname(),
+                   llvm::sys::getHostTriple(),
+                   "a.out", IsProduction, CXXIsProduction,
+                   Diags);
+
+  // Check for ".*++" or ".*++-[^-]*" to determine if we are a C++
+  // compiler. This matches things like "c++", "clang++", and "clang++-1.1".
+  //
+  // Note that we intentionally want to use argv[0] here, to support "clang++"
+  // being a symlink.
+  //
+  // We use *argv instead of argv[0] to work around a bogus g++ warning.
+  std::string ProgName(llvm::sys::Path(*argv).getBasename());
+  if (llvm::StringRef(ProgName).endswith("++") ||
+      llvm::StringRef(ProgName).rsplit('-').first.endswith("++")) {
+    TheDriver.CCCIsCXX = true;
+    TheDriver.CCCGenericGCCName = "g++";
+  }
+
+  llvm::OwningPtr<Compilation> C;
+
+  // Handle CC_PRINT_OPTIONS and CC_PRINT_OPTIONS_FILE.
+  TheDriver.CCPrintOptions = !!::getenv("CC_PRINT_OPTIONS");
+  if (TheDriver.CCPrintOptions)
+    TheDriver.CCPrintOptionsFilename = ::getenv("CC_PRINT_OPTIONS_FILE");
+
+  // Handle QA_OVERRIDE_GCC3_OPTIONS and CCC_ADD_ARGS, used for editing a
+  // command line behind the scenes.
+  std::set<std::string> SavedStrings;
+  if (const char *OverrideStr = ::getenv("QA_OVERRIDE_GCC3_OPTIONS")) {
+    // FIXME: Driver shouldn't take extra initial argument.
+    std::vector<const char*> StringPointers(argv, argv + argc);
+
+    ApplyQAOverride(StringPointers, OverrideStr, SavedStrings);
+
+    C.reset(TheDriver.BuildCompilation(StringPointers.size(),
+                                       &StringPointers[0]));
+  } else if (const char *Cur = ::getenv("CCC_ADD_ARGS")) {
+    std::vector<const char*> StringPointers;
+
+    // FIXME: Driver shouldn't take extra initial argument.
+    StringPointers.push_back(argv[0]);
+
+    for (;;) {
+      const char *Next = strchr(Cur, ',');
+
+      if (Next) {
+        StringPointers.push_back(SaveStringInSet(SavedStrings,
+                                                 std::string(Cur, Next)));
+        Cur = Next + 1;
+      } else {
+        if (*Cur != '\0')
+          StringPointers.push_back(SaveStringInSet(SavedStrings, Cur));
+        break;
+      }
+    }
+
+    StringPointers.insert(StringPointers.end(), argv + 1, argv + argc);
+
+    C.reset(TheDriver.BuildCompilation(StringPointers.size(),
+                                       &StringPointers[0]));
+  } else
+    C.reset(TheDriver.BuildCompilation(argc, argv));
+
+  int Res = 0;
+  if (C.get())
+    Res = TheDriver.ExecuteCompilation(*C);
+
+  
+  // If any timers were active but haven't been destroyed yet, print their
+  // results now.  This happens in -disable-free mode.
+  llvm::TimerGroup::printAll(llvm::errs());
+  
+  llvm::llvm_shutdown();
+
+  return Res;
+}
diff --git a/tools/scan-build/c++-analyzer b/tools/scan-build/c++-analyzer
new file mode 120000
index 0000000..ca10bf5
--- /dev/null
+++ b/tools/scan-build/c++-analyzer
@@ -0,0 +1 @@
+ccc-analyzer
\ No newline at end of file
diff --git a/tools/scan-build/ccc-analyzer b/tools/scan-build/ccc-analyzer
new file mode 100755
index 0000000..391ea57
--- /dev/null
+++ b/tools/scan-build/ccc-analyzer
@@ -0,0 +1,658 @@
+#!/usr/bin/env perl
+#
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+#
+#  A script designed to interpose between the build system and gcc.  It invokes
+#  both gcc and the static analyzer.
+#
+##===----------------------------------------------------------------------===##
+
+use strict;
+use warnings;
+use FindBin;
+use Cwd qw/ getcwd abs_path /;
+use File::Temp qw/ tempfile /;
+use File::Path qw / mkpath /;
+use File::Basename;
+use Text::ParseWords;
+
+##===----------------------------------------------------------------------===##
+# Compiler command setup.
+##===----------------------------------------------------------------------===##
+
+my $Compiler;
+my $Clang;
+
+if ($FindBin::Script =~ /c\+\+-analyzer/) {
+  $Compiler = $ENV{'CCC_CXX'};
+  if (!defined $Compiler) { $Compiler = "g++"; }
+  
+  $Clang = $ENV{'CLANG_CXX'};
+  if (!defined $Clang) { $Clang = 'clang++'; }
+}
+else {
+  $Compiler = $ENV{'CCC_CC'};
+  if (!defined $Compiler) { $Compiler = "gcc"; }
+
+  $Clang = $ENV{'CLANG'};
+  if (!defined $Clang) { $Clang = 'clang'; }
+}
+
+##===----------------------------------------------------------------------===##
+# Cleanup.
+##===----------------------------------------------------------------------===##
+
+my $ReportFailures = $ENV{'CCC_REPORT_FAILURES'};
+if (!defined $ReportFailures) { $ReportFailures = 1; }
+
+my $CleanupFile;
+my $ResultFile;
+
+# Remove any stale files at exit.
+END { 
+  if (defined $CleanupFile && -z $CleanupFile) {
+    `rm -f $CleanupFile`;
+  }
+}
+
+##----------------------------------------------------------------------------##
+#  Process Clang Crashes.
+##----------------------------------------------------------------------------##
+
+sub GetPPExt {
+  my $Lang = shift;
+  if ($Lang =~ /objective-c\+\+/) { return ".mii" };
+  if ($Lang =~ /objective-c/) { return ".mi"; }
+  if ($Lang =~ /c\+\+/) { return ".ii"; }
+  return ".i";
+}
+
+# Set this to 1 if we want to include 'parser rejects' files.
+my $IncludeParserRejects = 0;
+my $ParserRejects = "Parser Rejects";
+
+my $AttributeIgnored = "Attribute Ignored";
+
+sub ProcessClangFailure {
+  my ($Clang, $Lang, $file, $Args, $HtmlDir, $ErrorType, $ofile) = @_;
+  my $Dir = "$HtmlDir/failures";
+  mkpath $Dir;
+  
+  my $prefix = "clang_crash";
+  if ($ErrorType eq $ParserRejects) {
+    $prefix = "clang_parser_rejects";
+  }
+  elsif ($ErrorType eq $AttributeIgnored) {
+    $prefix = "clang_attribute_ignored";
+  }
+
+  # Generate the preprocessed file with Clang.
+  my ($PPH, $PPFile) = tempfile( $prefix . "_XXXXXX",
+                                 SUFFIX => GetPPExt($Lang),
+                                 DIR => $Dir);
+  system $Clang, @$Args, "-E", "-o", $PPFile;
+  close ($PPH);
+  
+  # Create the info file.
+  open (OUT, ">", "$PPFile.info.txt") or die "Cannot open $PPFile.info.txt\n";
+  print OUT abs_path($file), "\n";
+  print OUT "$ErrorType\n";
+  print OUT "@$Args\n";
+  close OUT;
+  `uname -a >> $PPFile.info.txt 2>&1`;
+  `$Compiler -v >> $PPFile.info.txt 2>&1`;
+  system 'mv',$ofile,"$PPFile.stderr.txt";
+  return (basename $PPFile);
+}
+
+##----------------------------------------------------------------------------##
+#  Running the analyzer.
+##----------------------------------------------------------------------------##
+
+sub GetCCArgs {
+  my $Args = shift;
+  
+  pipe (FROM_CHILD, TO_PARENT);
+  my $pid = fork();
+  if ($pid == 0) {
+    close FROM_CHILD;
+    open(STDOUT,">&", \*TO_PARENT);
+    open(STDERR,">&", \*TO_PARENT);
+    exec $Clang, "-###", "-fsyntax-only", @$Args;
+  }  
+  close(TO_PARENT);
+  my $line;
+  while (<FROM_CHILD>) {
+    next if (!/-cc1/);
+    $line = $_;
+  }
+
+  waitpid($pid,0);
+  close(FROM_CHILD);
+  
+  die "could not find clang line\n" if (!defined $line);
+  # Strip the newline and initial whitspace
+  chomp $line;  
+  $line =~ s/^\s+//;
+  my @items = quotewords('\s+', 0, $line);
+  my $cmd = shift @items;
+  die "cannot find 'clang' in 'clang' command\n" if (!($cmd =~ /clang/));
+  return \@items;
+}
+
+sub Analyze {
+  my ($Clang, $Args, $AnalyzeArgs, $Lang, $Output, $Verbose, $HtmlDir,
+      $file, $Analyses) = @_;
+  
+  $Args = GetCCArgs($Args);
+
+  my $RunAnalyzer = 0;
+  my $Cmd;
+  my @CmdArgs;
+  my @CmdArgsSansAnalyses;
+  
+  if ($Lang =~ /header/) {
+    exit 0 if (!defined ($Output));
+    $Cmd = 'cp';
+    push @CmdArgs,$file;
+    # Remove the PCH extension.
+    $Output =~ s/[.]gch$//;
+    push @CmdArgs,$Output;
+    @CmdArgsSansAnalyses = @CmdArgs;    
+  }
+  else {
+    $Cmd = $Clang;
+    push @CmdArgs, "-cc1";
+    push @CmdArgs,'-DIBOutlet=__attribute__((iboutlet))';
+    push @CmdArgs, @$Args;
+    @CmdArgsSansAnalyses = @CmdArgs;
+    push @CmdArgs,'-analyze';
+    push @CmdArgs,"-analyzer-display-progress";
+    push @CmdArgs,"-analyzer-eagerly-assume";
+    push @CmdArgs,"-analyzer-opt-analyze-nested-blocks";
+    push @CmdArgs,(split /\s/,$Analyses);
+    
+    if (defined $ENV{"CCC_EXPERIMENTAL_CHECKS"}) {
+      push @CmdArgs,"-analyzer-experimental-internal-checks";
+      push @CmdArgs,"-analyzer-experimental-checks";
+    }
+    
+    $RunAnalyzer = 1;
+  }
+  
+  # Add the analysis arguments passed down from scan-build.
+  foreach my $Arg (@$AnalyzeArgs) {
+    push @CmdArgs, $Arg;
+  }
+  
+  my @PrintArgs;
+  my $dir;
+
+  if ($RunAnalyzer) {
+    if (defined $ResultFile) {
+      push @CmdArgs,'-o';
+      push @CmdArgs, $ResultFile;
+    }
+    elsif (defined $HtmlDir) {
+      push @CmdArgs,'-o';
+      push @CmdArgs, $HtmlDir;
+    }
+  }
+  
+  if ($Verbose) {
+    $dir = getcwd();
+    print STDERR "\n[LOCATION]: $dir\n";
+    push @PrintArgs,"'$Cmd'";
+    foreach my $arg (@CmdArgs) { push @PrintArgs,"\'$arg\'"; }
+  }
+  
+  if ($Verbose == 1) {
+    # We MUST print to stderr.  Some clients use the stdout output of
+    # gcc for various purposes. 
+    print STDERR join(' ',@PrintArgs);
+    print STDERR "\n";
+  }
+  elsif ($Verbose == 2) {
+    print STDERR "#SHELL (cd '$dir' && @PrintArgs)\n";
+  }
+  
+  if (defined $ENV{'CCC_UBI'}) {   
+    push @CmdArgs,"--analyzer-viz-egraph-ubigraph";
+  }
+  
+  # Capture the STDERR of clang and send it to a temporary file.
+  # Capture the STDOUT of clang and reroute it to ccc-analyzer's STDERR.
+  # We save the output file in the 'crashes' directory if clang encounters
+  # any problems with the file.  
+  pipe (FROM_CHILD, TO_PARENT);
+  my $pid = fork();
+  if ($pid == 0) {
+    close FROM_CHILD;
+    open(STDOUT,">&", \*TO_PARENT);
+    open(STDERR,">&", \*TO_PARENT);
+    exec $Cmd, @CmdArgs;
+  }
+  
+  close TO_PARENT;
+  my ($ofh, $ofile) = tempfile("clang_output_XXXXXX", DIR => $HtmlDir);
+  
+  while (<FROM_CHILD>) {
+    print $ofh $_;
+    print STDERR $_;    
+  }
+
+  waitpid($pid,0);
+  close(FROM_CHILD);
+  my $Result = $?;
+
+  # Did the command die because of a signal?
+  if ($ReportFailures) {
+    if ($Result & 127 and $Cmd eq $Clang and defined $HtmlDir) {
+      ProcessClangFailure($Clang, $Lang, $file, \@CmdArgsSansAnalyses,
+                          $HtmlDir, "Crash", $ofile);
+    }
+    elsif ($Result) {
+      if ($IncludeParserRejects && !($file =~/conftest/)) {
+        ProcessClangFailure($Clang, $Lang, $file, \@CmdArgsSansAnalyses,
+                            $HtmlDir, $ParserRejects, $ofile);
+      }
+    }
+    else {
+      # Check if there were any unhandled attributes.
+      if (open(CHILD, $ofile)) {
+        my %attributes_not_handled;
+      
+        # Don't flag warnings about the following attributes that we
+        # know are currently not supported by Clang.
+        $attributes_not_handled{"cdecl"} = 1;
+      
+        my $ppfile;
+        while (<CHILD>) {
+          next if (! /warning: '([^\']+)' attribute ignored/);
+
+          # Have we already spotted this unhandled attribute?
+          next if (defined $attributes_not_handled{$1});
+          $attributes_not_handled{$1} = 1;
+        
+          # Get the name of the attribute file.
+          my $dir = "$HtmlDir/failures";
+          my $afile = "$dir/attribute_ignored_$1.txt";
+        
+          # Only create another preprocessed file if the attribute file
+          # doesn't exist yet.
+          next if (-e $afile);
+        
+          # Add this file to the list of files that contained this attribute.
+          # Generate a preprocessed file if we haven't already.
+          if (!(defined $ppfile)) {
+            $ppfile = ProcessClangFailure($Clang, $Lang, $file,
+                                          \@CmdArgsSansAnalyses,
+                                          $HtmlDir, $AttributeIgnored, $ofile);
+          }
+
+          mkpath $dir;
+          open(AFILE, ">$afile");
+          print AFILE "$ppfile\n";
+          close(AFILE);
+        }
+        close CHILD;
+      }
+    }
+  }
+  
+  unlink($ofile);
+}
+
+##----------------------------------------------------------------------------##
+#  Lookup tables.
+##----------------------------------------------------------------------------##
+
+my %CompileOptionMap = (
+  '-nostdinc' => 0,
+  '-fblocks' => 0,
+  '-fobjc-gc-only' => 0,
+  '-fobjc-gc' => 0,
+  '-ffreestanding' => 0,
+  '-include' => 1,
+  '-idirafter' => 1,
+  '-iprefix' => 1,
+  '-iquote' => 1,
+  '-isystem' => 1,
+  '-iwithprefix' => 1,
+  '-iwithprefixbefore' => 1
+);
+
+my %LinkerOptionMap = (
+  '-framework' => 1
+);
+
+my %CompilerLinkerOptionMap = (
+  '-isysroot' => 1,
+  '-arch' => 1,
+  '-m32' => 0,
+  '-m64' => 0,
+  '-v' => 0,
+  '-fpascal-strings' => 0,
+  '-mmacosx-version-min' => 0, # This is really a 1 argument, but always has '='
+  '-miphoneos-version-min' => 0 # This is really a 1 argument, but always has '='
+);
+
+my %IgnoredOptionMap = (
+  '-MT' => 1,  # Ignore these preprocessor options.
+  '-MF' => 1,
+
+  '-fsyntax-only' => 0,
+  '-save-temps' => 0,
+  '-install_name' => 1,
+  '-exported_symbols_list' => 1,
+  '-current_version' => 1,
+  '-compatibility_version' => 1,
+  '-init' => 1,
+  '-e' => 1,
+  '-seg1addr' => 1,
+  '-bundle_loader' => 1,
+  '-multiply_defined' => 1,
+  '-sectorder' => 3,
+  '--param' => 1,
+  '-u' => 1
+);
+
+my %LangMap = (
+  'c'   => 'c',
+  'cpp' => 'c++',
+  'cc'  => 'c++',
+  'i'   => 'c-cpp-output',
+  'm'   => 'objective-c',
+  'mi'  => 'objective-c-cpp-output'
+);
+
+my %UniqueOptions = (
+  '-isysroot' => 0  
+);
+
+##----------------------------------------------------------------------------##
+# Languages accepted.
+##----------------------------------------------------------------------------##
+
+my %LangsAccepted = (
+  "objective-c" => 1,
+  "c" => 1
+);
+
+if (defined $ENV{'CCC_ANALYZER_CPLUSPLUS'}) {
+  $LangsAccepted{"c++"} = 1;
+  $LangsAccepted{"objective-c++"} = 1;
+}
+
+##----------------------------------------------------------------------------##
+#  Main Logic.
+##----------------------------------------------------------------------------##
+
+my $Action = 'link';
+my @CompileOpts;
+my @LinkOpts;
+my @Files;
+my $Lang;
+my $Output;
+my %Uniqued;
+
+# Forward arguments to gcc.
+my $Status = system($Compiler,@ARGV);
+if ($Status) { exit($Status >> 8); }
+
+# Get the analysis options.
+my $Analyses = $ENV{'CCC_ANALYZER_ANALYSIS'};
+if (!defined($Analyses)) { $Analyses = '-analyzer-check-objc-mem'; }
+
+# Get the store model.
+my $StoreModel = $ENV{'CCC_ANALYZER_STORE_MODEL'};
+if (!defined $StoreModel) { $StoreModel = "region"; }
+
+# Get the constraints engine.
+my $ConstraintsModel = $ENV{'CCC_ANALYZER_CONSTRAINTS_MODEL'};
+if (!defined $ConstraintsModel) { $ConstraintsModel = "range"; }
+
+# Get the output format.
+my $OutputFormat = $ENV{'CCC_ANALYZER_OUTPUT_FORMAT'};
+if (!defined $OutputFormat) { $OutputFormat = "html"; }
+
+# Determine the level of verbosity.
+my $Verbose = 0;
+if (defined $ENV{CCC_ANALYZER_VERBOSE}) { $Verbose = 1; }
+if (defined $ENV{CCC_ANALYZER_LOG}) { $Verbose = 2; }
+
+# Get the HTML output directory.
+my $HtmlDir = $ENV{'CCC_ANALYZER_HTML'};
+
+my %DisabledArchs = ('ppc' => 1, 'ppc64' => 1);
+my %ArchsSeen;
+my $HadArch = 0;
+
+# Process the arguments.
+foreach (my $i = 0; $i < scalar(@ARGV); ++$i) {
+  my $Arg = $ARGV[$i];  
+  my ($ArgKey) = split /=/,$Arg,2;
+
+  # Modes ccc-analyzer supports
+  if ($Arg =~ /^-(E|MM?)$/) { $Action = 'preprocess'; }
+  elsif ($Arg eq '-c') { $Action = 'compile'; }
+  elsif ($Arg =~ /^-print-prog-name/) { exit 0; }
+
+  # Specially handle duplicate cases of -arch
+  if ($Arg eq "-arch") {
+    my $arch = $ARGV[$i+1];
+    # We don't want to process 'ppc' because of Clang's lack of support
+    # for Altivec (also some #defines won't likely be defined correctly, etc.)
+    if (!(defined $DisabledArchs{$arch})) { $ArchsSeen{$arch} = 1; }
+    $HadArch = 1;
+    ++$i;
+    next;
+  }
+
+  # Options with possible arguments that should pass through to compiler.
+  if (defined $CompileOptionMap{$ArgKey}) {
+    my $Cnt = $CompileOptionMap{$ArgKey};
+    push @CompileOpts,$Arg;
+    while ($Cnt > 0) { ++$i; --$Cnt; push @CompileOpts, $ARGV[$i]; }
+    next;
+  }
+
+  # Options with possible arguments that should pass through to linker.
+  if (defined $LinkerOptionMap{$ArgKey}) {
+    my $Cnt = $LinkerOptionMap{$ArgKey};
+    push @LinkOpts,$Arg;
+    while ($Cnt > 0) { ++$i; --$Cnt; push @LinkOpts, $ARGV[$i]; }
+    next;
+  }
+
+  # Options with possible arguments that should pass through to both compiler
+  # and the linker.
+  if (defined $CompilerLinkerOptionMap{$ArgKey}) {
+    my $Cnt = $CompilerLinkerOptionMap{$ArgKey};
+    
+    # Check if this is an option that should have a unique value, and if so
+    # determine if the value was checked before.
+    if ($UniqueOptions{$Arg}) {
+      if (defined $Uniqued{$Arg}) {
+        $i += $Cnt;
+        next;
+      }
+      $Uniqued{$Arg} = 1;
+    }
+    
+    push @CompileOpts,$Arg;    
+    push @LinkOpts,$Arg;
+
+    while ($Cnt > 0) {
+      ++$i; --$Cnt;
+      push @CompileOpts, $ARGV[$i];
+      push @LinkOpts, $ARGV[$i];
+    }
+    next;
+  }
+  
+  # Ignored options.
+  if (defined $IgnoredOptionMap{$ArgKey}) {
+    my $Cnt = $IgnoredOptionMap{$ArgKey};
+    while ($Cnt > 0) {
+      ++$i; --$Cnt;
+    }
+    next;
+  }
+  
+  # Compile mode flags.
+  if ($Arg =~ /^-[D,I,U](.*)$/) {
+    my $Tmp = $Arg;    
+    if ($1 eq '') {
+      # FIXME: Check if we are going off the end.
+      ++$i;
+      $Tmp = $Arg . $ARGV[$i];
+    }
+    push @CompileOpts,$Tmp;
+    next;
+  }
+  
+  # Language.
+  if ($Arg eq '-x') {
+    $Lang = $ARGV[$i+1];
+    ++$i; next;
+  }
+
+  # Output file.
+  if ($Arg eq '-o') {
+    ++$i;
+    $Output = $ARGV[$i];
+    next;
+  }
+  
+  # Get the link mode.
+  if ($Arg =~ /^-[l,L,O]/) {
+    if ($Arg eq '-O') { push @LinkOpts,'-O1'; }
+    elsif ($Arg eq '-Os') { push @LinkOpts,'-O2'; }
+    else { push @LinkOpts,$Arg; }
+    next;
+  }
+  
+  if ($Arg =~ /^-std=/) {
+    push @CompileOpts,$Arg;
+    next;
+  }
+  
+#  if ($Arg =~ /^-f/) {
+#    # FIXME: Not sure if the remaining -fxxxx options have no arguments.
+#    push @CompileOpts,$Arg;
+#    push @LinkOpts,$Arg;  # FIXME: Not sure if these are link opts.
+#  }
+  
+  # Get the compiler/link mode.
+  if ($Arg =~ /^-F(.+)$/) {
+    my $Tmp = $Arg;
+    if ($1 eq '') {
+      # FIXME: Check if we are going off the end.
+      ++$i;
+      $Tmp = $Arg . $ARGV[$i];
+    }
+    push @CompileOpts,$Tmp;
+    push @LinkOpts,$Tmp;
+    next;
+  }
+
+  # Input files.
+  if ($Arg eq '-filelist') {
+    # FIXME: Make sure we aren't walking off the end.
+    open(IN, $ARGV[$i+1]);
+    while (<IN>) { s/\015?\012//; push @Files,$_; }
+    close(IN);
+    ++$i;
+    next;
+  }
+  
+  # Handle -Wno-.  We don't care about extra warnings, but
+  # we should suppress ones that we don't want to see.
+  if ($Arg =~ /^-Wno-/) {
+    push @CompileOpts, $Arg;
+    next;
+  }
+
+  if (!($Arg =~ /^-/)) {
+    push @Files, $Arg;
+    next;
+  }
+}
+
+if ($Action eq 'compile' or $Action eq 'link') {
+  my @Archs = keys %ArchsSeen;
+  # Skip the file if we don't support the architectures specified.
+  exit 0 if ($HadArch && scalar(@Archs) == 0);
+  
+  foreach my $file (@Files) {
+    # Determine the language for the file.
+    my $FileLang = $Lang;
+
+    if (!defined($FileLang)) {
+      # Infer the language from the extension.
+      if ($file =~ /[.]([^.]+)$/) {
+        $FileLang = $LangMap{$1};
+      }
+    }
+    
+    # FileLang still not defined?  Skip the file.
+    next if (!defined $FileLang);
+
+    # Language not accepted?
+    next if (!defined $LangsAccepted{$FileLang});
+
+    my @CmdArgs;
+    my @AnalyzeArgs;    
+    
+    if ($FileLang ne 'unknown') {
+      push @CmdArgs,'-x';
+      push @CmdArgs,$FileLang;
+    }
+
+    if (defined $StoreModel) {
+      push @AnalyzeArgs, "-analyzer-store=$StoreModel";
+    }
+
+    if (defined $ConstraintsModel) {
+      push @AnalyzeArgs, "-analyzer-constraints=$ConstraintsModel";
+    }
+
+    if (defined $OutputFormat) {
+      push @AnalyzeArgs, "-analyzer-output=" . $OutputFormat;
+      if ($OutputFormat =~ /plist/) {
+        # Change "Output" to be a file.
+        my ($h, $f) = tempfile("report-XXXXXX", SUFFIX => ".plist",
+                               DIR => $HtmlDir);
+        $ResultFile = $f;
+        $CleanupFile = $f;
+      }
+    }
+
+    push @CmdArgs,@CompileOpts;
+    push @CmdArgs,$file;
+
+    if (scalar @Archs) {
+      foreach my $arch (@Archs) {
+        my @NewArgs;
+        push @NewArgs, '-arch';
+        push @NewArgs, $arch;
+        push @NewArgs, @CmdArgs;
+        Analyze($Clang, \@NewArgs, \@AnalyzeArgs, $FileLang, $Output,
+                $Verbose, $HtmlDir, $file, $Analyses);
+      }
+    }
+    else {
+      Analyze($Clang, \@CmdArgs, \@AnalyzeArgs, $FileLang, $Output,
+              $Verbose, $HtmlDir, $file, $Analyses);
+    }
+  }
+}
+
+exit($Status >> 8);
+
diff --git a/tools/scan-build/scan-build b/tools/scan-build/scan-build
new file mode 100755
index 0000000..8a7afbb
--- /dev/null
+++ b/tools/scan-build/scan-build
@@ -0,0 +1,1265 @@
+#!/usr/bin/env perl
+#
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+#
+# A script designed to wrap a build so that all calls to gcc are intercepted
+# and piped to the static analyzer.
+#
+##===----------------------------------------------------------------------===##
+
+use strict;
+use warnings;
+use FindBin qw($RealBin);
+use Digest::MD5;
+use File::Basename;
+use Term::ANSIColor;
+use Term::ANSIColor qw(:constants);
+use Cwd qw/ getcwd abs_path /;
+use Sys::Hostname;
+
+my $Verbose = 0;       # Verbose output from this script.
+my $Prog = "scan-build";
+my $BuildName;
+my $BuildDate;
+
+my $TERM = $ENV{'TERM'};
+my $UseColor = (defined $TERM and $TERM eq 'xterm-color' and -t STDOUT
+                and defined $ENV{'SCAN_BUILD_COLOR'});
+
+my $UserName = HtmlEscape(getpwuid($<) || 'unknown');
+my $HostName = HtmlEscape(hostname() || 'unknown');
+my $CurrentDir = HtmlEscape(getcwd());
+my $CurrentDirSuffix = basename($CurrentDir);
+
+my $CmdArgs;
+
+my $HtmlTitle;
+
+my $Date = localtime();
+
+##----------------------------------------------------------------------------##
+# Diagnostics
+##----------------------------------------------------------------------------##
+
+sub Diag {
+  if ($UseColor) {
+    print BOLD, MAGENTA "$Prog: @_";
+    print RESET;
+  }
+  else {
+    print "$Prog: @_";
+  }  
+}
+
+sub DiagCrashes {
+  my $Dir = shift;
+  Diag ("The analyzer encountered problems on some source files.\n");
+  Diag ("Preprocessed versions of these sources were deposited in '$Dir/failures'.\n");
+  Diag ("Please consider submitting a bug report using these files:\n");
+  Diag ("  http://clang.llvm.org/StaticAnalysisUsage.html#filingbugs\n")
+}
+
+sub DieDiag {
+  if ($UseColor) {
+    print BOLD, RED "$Prog: ";
+    print RESET, RED @_;
+    print RESET;
+  }
+  else {
+    print "$Prog: ", @_;
+  }
+  exit(0);
+}
+
+##----------------------------------------------------------------------------##
+# Some initial preprocessing of Clang options.
+##----------------------------------------------------------------------------##
+
+# Find 'clang'
+my $ClangSB = Cwd::realpath("$RealBin/bin/clang");
+if (!defined $ClangSB || ! -x $ClangSB) {
+  $ClangSB = Cwd::realpath("$RealBin/clang");
+}
+my $Clang;
+if (!defined $ClangSB || ! -x $ClangSB) {
+  # Default to looking for 'clang' in the path.
+  $Clang = `which clang`;
+  chomp $Clang;
+  if ($Clang eq "") {
+    DieDiag("No 'clang' executable found in path.");
+  }
+}
+else {
+  $Clang = $ClangSB;
+}
+my $ClangCXX = $Clang . "++";
+
+my %AvailableAnalyses;
+
+# Query clang for analysis options.
+open(PIPE, "-|", $Clang, "-cc1", "-help") or
+  DieDiag("Cannot execute '$Clang'\n");
+
+while(<PIPE>) {
+  if (/(-analyzer-check-[^\s]+)/) {
+    $AvailableAnalyses{$1} = 1;
+    next;
+  }  
+}
+close (PIPE);
+
+my %AnalysesDefaultEnabled = (
+  '-analyzer-check-dead-stores' => 1,
+  '-analyzer-check-objc-mem' => 1,
+  '-analyzer-check-objc-methodsigs' => 1,
+  # Do not enable the missing -dealloc check by default.
+  #  '-analyzer-check-objc-missing-dealloc' => 1,
+  '-analyzer-check-objc-unused-ivars' => 1,
+  '-analyzer-check-security-syntactic' => 1
+);
+
+##----------------------------------------------------------------------------##
+# GetHTMLRunDir - Construct an HTML directory name for the current sub-run.
+##----------------------------------------------------------------------------##
+
+sub GetHTMLRunDir {  
+  die "Not enough arguments." if (@_ == 0);  
+  my $Dir = shift @_;    
+  my $TmpMode = 0;
+  if (!defined $Dir) {
+    if (`uname` =~ /Darwin/) {
+      $Dir = $ENV{'TMPDIR'};
+      if (!defined $Dir) { $Dir = "/tmp"; }
+    }
+    else {
+      $Dir = "/tmp";
+    }    
+    $TmpMode = 1;
+  }
+  
+  # Chop off any trailing '/' characters.
+  while ($Dir =~ /\/$/) { chop $Dir; }
+
+  # Get current date and time.
+  my @CurrentTime = localtime();  
+  my $year  = $CurrentTime[5] + 1900;
+  my $day   = $CurrentTime[3];
+  my $month = $CurrentTime[4] + 1;
+  my $DateString = sprintf("%d-%02d-%02d", $year, $month, $day);
+  
+  # Determine the run number.  
+  my $RunNumber;
+  
+  if (-d $Dir) {    
+    if (! -r $Dir) {
+      DieDiag("directory '$Dir' exists but is not readable.\n");
+    }    
+    # Iterate over all files in the specified directory.    
+    my $max = 0;    
+    opendir(DIR, $Dir);
+    my @FILES = grep { -d "$Dir/$_" } readdir(DIR);
+    closedir(DIR);
+
+    foreach my $f (@FILES) {
+      # Strip the prefix '$Prog-' if we are dumping files to /tmp.
+      if ($TmpMode) {
+        next if (!($f =~ /^$Prog-(.+)/));
+        $f = $1;
+      }
+
+      my @x = split/-/, $f;
+      next if (scalar(@x) != 4);
+      next if ($x[0] != $year);
+      next if ($x[1] != $month);
+      next if ($x[2] != $day);
+      
+      if ($x[3] > $max) {
+        $max = $x[3];
+      }      
+    }
+    
+    $RunNumber = $max + 1;
+  }
+  else {
+    
+    if (-x $Dir) {
+      DieDiag("'$Dir' exists but is not a directory.\n");
+    }
+
+    if ($TmpMode) {
+      DieDiag("The directory '/tmp' does not exist or cannot be accessed.\n");
+    }
+
+    # $Dir does not exist.  It will be automatically created by the 
+    # clang driver.  Set the run number to 1.  
+
+    $RunNumber = 1;
+  }
+  
+  die "RunNumber must be defined!" if (!defined $RunNumber);
+  
+  # Append the run number.
+  my $NewDir;
+  if ($TmpMode) {
+    $NewDir = "$Dir/$Prog-$DateString-$RunNumber";
+  }
+  else {
+    $NewDir = "$Dir/$DateString-$RunNumber";
+  }
+  system 'mkdir','-p',$NewDir;
+  return $NewDir;
+}
+
+sub SetHtmlEnv {
+  
+  die "Wrong number of arguments." if (scalar(@_) != 2);
+  
+  my $Args = shift;
+  my $Dir = shift;
+  
+  die "No build command." if (scalar(@$Args) == 0);
+  
+  my $Cmd = $$Args[0];
+  
+  if ($Cmd =~ /configure/) {
+    return;
+  }
+  
+  if ($Verbose) {
+    Diag("Emitting reports for this run to '$Dir'.\n");
+  }
+  
+  $ENV{'CCC_ANALYZER_HTML'} = $Dir;
+}
+
+##----------------------------------------------------------------------------##
+# ComputeDigest - Compute a digest of the specified file.
+##----------------------------------------------------------------------------##
+
+sub ComputeDigest {
+  my $FName = shift;
+  DieDiag("Cannot read $FName to compute Digest.\n") if (! -r $FName);  
+  
+  # Use Digest::MD5.  We don't have to be cryptographically secure.  We're
+  # just looking for duplicate files that come from a non-malicious source.
+  # We use Digest::MD5 because it is a standard Perl module that should
+  # come bundled on most systems.  
+  open(FILE, $FName) or DieDiag("Cannot open $FName when computing Digest.\n");
+  binmode FILE;
+  my $Result = Digest::MD5->new->addfile(*FILE)->hexdigest;
+  close(FILE);
+  
+  # Return the digest.  
+  return $Result;
+}
+
+##----------------------------------------------------------------------------##
+#  UpdatePrefix - Compute the common prefix of files.
+##----------------------------------------------------------------------------##
+
+my $Prefix;
+
+sub UpdatePrefix {
+  my $x = shift;
+  my $y = basename($x);
+  $x =~ s/\Q$y\E$//;
+
+  if (!defined $Prefix) {
+    $Prefix = $x;
+    return;
+  }
+  
+  chop $Prefix while (!($x =~ /^\Q$Prefix/));
+}
+
+sub GetPrefix {
+  return $Prefix;
+}
+
+##----------------------------------------------------------------------------##
+#  UpdateInFilePath - Update the path in the report file.
+##----------------------------------------------------------------------------##
+
+sub UpdateInFilePath {
+  my $fname = shift;
+  my $regex = shift;
+  my $newtext = shift;
+
+  open (RIN, $fname) or die "cannot open $fname";
+  open (ROUT, ">", "$fname.tmp") or die "cannot open $fname.tmp";
+
+  while (<RIN>) {
+    s/$regex/$newtext/;
+    print ROUT $_;
+  }
+
+  close (ROUT);
+  close (RIN);
+  system("mv", "$fname.tmp", $fname);
+}
+
+##----------------------------------------------------------------------------##
+# ScanFile - Scan a report file for various identifying attributes.
+##----------------------------------------------------------------------------##
+
+# Sometimes a source file is scanned more than once, and thus produces
+# multiple error reports.  We use a cache to solve this problem.
+
+my %AlreadyScanned;
+
+sub ScanFile {
+  
+  my $Index = shift;
+  my $Dir = shift;
+  my $FName = shift;
+  
+  # Compute a digest for the report file.  Determine if we have already
+  # scanned a file that looks just like it.
+  
+  my $digest = ComputeDigest("$Dir/$FName");
+
+  if (defined $AlreadyScanned{$digest}) {
+    # Redundant file.  Remove it.
+    system ("rm", "-f", "$Dir/$FName");
+    return;
+  }
+  
+  $AlreadyScanned{$digest} = 1;
+  
+  # At this point the report file is not world readable.  Make it happen.
+  system ("chmod", "644", "$Dir/$FName");
+  
+  # Scan the report file for tags.
+  open(IN, "$Dir/$FName") or DieDiag("Cannot open '$Dir/$FName'\n");
+
+  my $BugType = "";
+  my $BugFile = "";
+  my $BugCategory;
+  my $BugPathLength = 1;
+  my $BugLine = 0;
+
+  while (<IN>) {
+    last if (/<!-- BUGMETAEND -->/);
+
+    if (/<!-- BUGTYPE (.*) -->$/) {
+      $BugType = $1;
+    }
+    elsif (/<!-- BUGFILE (.*) -->$/) {
+      $BugFile = abs_path($1);
+      UpdatePrefix($BugFile);
+    }
+    elsif (/<!-- BUGPATHLENGTH (.*) -->$/) {
+      $BugPathLength = $1;
+    }
+    elsif (/<!-- BUGLINE (.*) -->$/) {
+      $BugLine = $1;    
+    }
+    elsif (/<!-- BUGCATEGORY (.*) -->$/) {
+      $BugCategory = $1;
+    }
+  }
+
+  close(IN);
+  
+  if (!defined $BugCategory) {
+    $BugCategory = "Other";
+  }
+    
+  push @$Index,[ $FName, $BugCategory, $BugType, $BugFile, $BugLine,
+                 $BugPathLength ];
+}
+
+##----------------------------------------------------------------------------##
+# CopyFiles - Copy resource files to target directory.
+##----------------------------------------------------------------------------##
+
+sub CopyFiles {
+
+  my $Dir = shift;
+
+  my $JS = Cwd::realpath("$RealBin/sorttable.js");
+  
+  DieDiag("Cannot find 'sorttable.js'.\n")
+    if (! -r $JS);  
+
+  system ("cp", $JS, "$Dir");
+
+  DieDiag("Could not copy 'sorttable.js' to '$Dir'.\n")
+    if (! -r "$Dir/sorttable.js");
+    
+  my $CSS = Cwd::realpath("$RealBin/scanview.css");
+  
+  DieDiag("Cannot find 'scanview.css'.\n")
+    if (! -r $CSS);
+
+  system ("cp", $CSS, "$Dir");
+
+  DieDiag("Could not copy 'scanview.css' to '$Dir'.\n")
+    if (! -r $CSS);
+}
+
+##----------------------------------------------------------------------------##
+# Postprocess - Postprocess the results of an analysis scan.
+##----------------------------------------------------------------------------##
+
+sub Postprocess {
+  
+  my $Dir = shift;
+  my $BaseDir = shift;
+  
+  die "No directory specified." if (!defined $Dir);
+  
+  if (! -d $Dir) {
+    Diag("No bugs found.\n");
+    return 0;
+  }
+  
+  opendir(DIR, $Dir);
+  my @files = grep { /^report-.*\.html$/ } readdir(DIR);
+  closedir(DIR);
+
+  if (scalar(@files) == 0 and ! -e "$Dir/failures") {
+    Diag("Removing directory '$Dir' because it contains no reports.\n");
+    system ("rm", "-fR", $Dir);
+    return 0;
+  }
+  
+  # Scan each report file and build an index.  
+  my @Index;    
+  foreach my $file (@files) { ScanFile(\@Index, $Dir, $file); }
+  
+  # Scan the failures directory and use the information in the .info files
+  # to update the common prefix directory.
+  my @failures;
+  my @attributes_ignored;
+  if (-d "$Dir/failures") {
+    opendir(DIR, "$Dir/failures");
+    @failures = grep { /[.]info.txt$/ && !/attribute_ignored/; } readdir(DIR);
+    closedir(DIR);
+    opendir(DIR, "$Dir/failures");        
+    @attributes_ignored = grep { /^attribute_ignored/; } readdir(DIR);
+    closedir(DIR);
+    foreach my $file (@failures) {
+      open IN, "$Dir/failures/$file" or DieDiag("cannot open $file\n");
+      my $Path = <IN>;
+      if (defined $Path) { UpdatePrefix($Path); }
+      close IN;
+    }    
+  }
+  
+  # Generate an index.html file.  
+  my $FName = "$Dir/index.html";  
+  open(OUT, ">", $FName) or DieDiag("Cannot create file '$FName'\n");
+  
+  # Print out the header.
+  
+print OUT <<ENDTEXT;
+<html>
+<head>
+<title>${HtmlTitle}</title>
+<link type="text/css" rel="stylesheet" href="scanview.css"/>
+<script src="sorttable.js"></script>
+<script language='javascript' type="text/javascript">
+function SetDisplay(RowClass, DisplayVal)
+{
+  var Rows = document.getElementsByTagName("tr");
+  for ( var i = 0 ; i < Rows.length; ++i ) {
+    if (Rows[i].className == RowClass) {
+      Rows[i].style.display = DisplayVal;
+    }
+  }
+}
+
+function CopyCheckedStateToCheckButtons(SummaryCheckButton) {
+  var Inputs = document.getElementsByTagName("input");
+  for ( var i = 0 ; i < Inputs.length; ++i ) {
+    if (Inputs[i].type == "checkbox") {
+      if(Inputs[i] != SummaryCheckButton) {
+        Inputs[i].checked = SummaryCheckButton.checked;
+        Inputs[i].onclick();
+	  }
+    }
+  }
+}
+
+function returnObjById( id ) {
+    if (document.getElementById) 
+        var returnVar = document.getElementById(id);
+    else if (document.all)
+        var returnVar = document.all[id];
+    else if (document.layers) 
+        var returnVar = document.layers[id];
+    return returnVar; 
+}
+
+var NumUnchecked = 0;
+
+function ToggleDisplay(CheckButton, ClassName) {
+  if (CheckButton.checked) {
+    SetDisplay(ClassName, "");
+    if (--NumUnchecked == 0) {
+      returnObjById("AllBugsCheck").checked = true;
+    }
+  }
+  else {
+    SetDisplay(ClassName, "none");
+    NumUnchecked++;
+    returnObjById("AllBugsCheck").checked = false;
+  }
+}
+</script>
+<!-- SUMMARYENDHEAD -->
+</head>
+<body>
+<h1>${HtmlTitle}</h1>
+
+<table>
+<tr><th>User:</th><td>${UserName}\@${HostName}</td></tr>
+<tr><th>Working Directory:</th><td>${CurrentDir}</td></tr>
+<tr><th>Command Line:</th><td>${CmdArgs}</td></tr>
+<tr><th>Date:</th><td>${Date}</td></tr>
+ENDTEXT
+
+print OUT "<tr><th>Version:</th><td>${BuildName} (${BuildDate})</td></tr>\n"
+  if (defined($BuildName) && defined($BuildDate));
+
+print OUT <<ENDTEXT;
+</table>
+ENDTEXT
+
+  if (scalar(@files)) {
+    # Print out the summary table.
+    my %Totals;
+
+    for my $row ( @Index ) {
+      my $bug_type = ($row->[2]);
+      my $bug_category = ($row->[1]);
+      my $key = "$bug_category:$bug_type";
+
+      if (!defined $Totals{$key}) { $Totals{$key} = [1,$bug_category,$bug_type]; }
+      else { $Totals{$key}->[0]++; }
+    }
+
+    print OUT "<h2>Bug Summary</h2>";
+
+    if (defined $BuildName) {
+      print OUT "\n<p>Results in this analysis run are based on analyzer build <b>$BuildName</b>.</p>\n"
+    }
+  
+  my $TotalBugs = scalar(@Index);
+print OUT <<ENDTEXT;
+<table>
+<thead><tr><td>Bug Type</td><td>Quantity</td><td class="sorttable_nosort">Display?</td></tr></thead>
+<tr style="font-weight:bold"><td class="SUMM_DESC">All Bugs</td><td class="Q">$TotalBugs</td><td><center><input type="checkbox" id="AllBugsCheck" onClick="CopyCheckedStateToCheckButtons(this);" checked/></center></td></tr>
+ENDTEXT
+  
+    my $last_category;
+
+    for my $key (
+      sort {
+        my $x = $Totals{$a};
+        my $y = $Totals{$b};
+        my $res = $x->[1] cmp $y->[1];
+        $res = $x->[2] cmp $y->[2] if ($res == 0);
+        $res
+      } keys %Totals ) 
+    {
+      my $val = $Totals{$key};
+      my $category = $val->[1];
+      if (!defined $last_category or $last_category ne $category) {
+        $last_category = $category;
+        print OUT "<tr><th>$category</th><th colspan=2></th></tr>\n";
+      }      
+      my $x = lc $key;
+      $x =~ s/[ ,'":\/()]+/_/g;
+      print OUT "<tr><td class=\"SUMM_DESC\">";
+      print OUT $val->[2];
+      print OUT "</td><td class=\"Q\">";
+      print OUT $val->[0];
+      print OUT "</td><td><center><input type=\"checkbox\" onClick=\"ToggleDisplay(this,'bt_$x');\" checked/></center></td></tr>\n";
+    }
+
+  # Print out the table of errors.
+
+print OUT <<ENDTEXT;
+</table>
+<h2>Reports</h2>
+
+<table class="sortable" style="table-layout:automatic">
+<thead><tr>
+  <td>Bug Group</td>
+  <td class="sorttable_sorted">Bug Type<span id="sorttable_sortfwdind">&nbsp;&#x25BE;</span></td>
+  <td>File</td>
+  <td class="Q">Line</td>
+  <td class="Q">Path Length</td>
+  <td class="sorttable_nosort"></td>
+  <!-- REPORTBUGCOL -->
+</tr></thead>
+<tbody>
+ENDTEXT
+
+    my $prefix = GetPrefix();
+    my $regex;
+    my $InFileRegex;
+    my $InFilePrefix = "File:</td><td>";
+  
+    if (defined $prefix) { 
+      $regex = qr/^\Q$prefix\E/is;    
+      $InFileRegex = qr/\Q$InFilePrefix$prefix\E/is;
+    }    
+
+    for my $row ( sort { $a->[2] cmp $b->[2] } @Index ) {
+      my $x = "$row->[1]:$row->[2]";
+      $x = lc $x;
+      $x =~ s/[ ,'":\/()]+/_/g;
+    
+      my $ReportFile = $row->[0];
+          
+      print OUT "<tr class=\"bt_$x\">";
+      print OUT "<td class=\"DESC\">";
+      print OUT $row->[1];
+      print OUT "</td>";
+      print OUT "<td class=\"DESC\">";
+      print OUT $row->[2];
+      print OUT "</td>";
+      
+      # Update the file prefix.      
+      my $fname = $row->[3];
+
+      if (defined $regex) {
+        $fname =~ s/$regex//;
+        UpdateInFilePath("$Dir/$ReportFile", $InFileRegex, $InFilePrefix)
+      }
+      
+      print OUT "<td>";      
+      my @fname = split /\//,$fname;
+      if ($#fname > 0) {
+        while ($#fname >= 0) {
+          my $x = shift @fname;
+          print OUT $x;
+          if ($#fname >= 0) {
+            print OUT "<span class=\"W\"> </span>/";
+          }
+        }
+      }
+      else {
+        print OUT $fname;
+      }      
+      print OUT "</td>";
+      
+      # Print out the quantities.
+      for my $j ( 4 .. 5 ) {
+        print OUT "<td class=\"Q\">$row->[$j]</td>";        
+      }
+      
+      # Print the rest of the columns.
+      for (my $j = 6; $j <= $#{$row}; ++$j) {
+        print OUT "<td>$row->[$j]</td>"
+      }
+
+      # Emit the "View" link.
+      print OUT "<td><a href=\"$ReportFile#EndPath\">View Report</a></td>";
+        
+      # Emit REPORTBUG markers.
+      print OUT "\n<!-- REPORTBUG id=\"$ReportFile\" -->\n";
+        
+      # End the row.
+      print OUT "</tr>\n";
+    }
+  
+    print OUT "</tbody>\n</table>\n\n";
+  }
+
+  if (scalar (@failures) || scalar(@attributes_ignored)) {
+    print OUT "<h2>Analyzer Failures</h2>\n";
+    
+    if (scalar @attributes_ignored) {
+      print OUT "The analyzer's parser ignored the following attributes:<p>\n";
+      print OUT "<table>\n";
+      print OUT "<thead><tr><td>Attribute</td><td>Source File</td><td>Preprocessed File</td><td>STDERR Output</td></tr></thead>\n";
+      foreach my $file (sort @attributes_ignored) {
+        die "cannot demangle attribute name\n" if (! ($file =~ /^attribute_ignored_(.+).txt/));
+        my $attribute = $1;
+        # Open the attribute file to get the first file that failed.
+        next if (!open (ATTR, "$Dir/failures/$file"));
+        my $ppfile = <ATTR>;
+        chomp $ppfile;
+        close ATTR;
+        next if (! -e "$Dir/failures/$ppfile");
+        # Open the info file and get the name of the source file.
+        open (INFO, "$Dir/failures/$ppfile.info.txt") or
+          die "Cannot open $Dir/failures/$ppfile.info.txt\n";
+        my $srcfile = <INFO>;
+        chomp $srcfile;
+        close (INFO);
+        # Print the information in the table.
+        my $prefix = GetPrefix();
+        if (defined $prefix) { $srcfile =~ s/^\Q$prefix//; }
+        print OUT "<tr><td>$attribute</td><td>$srcfile</td><td><a href=\"failures/$ppfile\">$ppfile</a></td><td><a href=\"failures/$ppfile.stderr.txt\">$ppfile.stderr.txt</a></td></tr>\n";
+        my $ppfile_clang = $ppfile;
+        $ppfile_clang =~ s/[.](.+)$/.clang.$1/;
+        print OUT "  <!-- REPORTPROBLEM src=\"$srcfile\" file=\"failures/$ppfile\" clangfile=\"failures/$ppfile_clang\" stderr=\"failures/$ppfile.stderr.txt\" info=\"failures/$ppfile.info.txt\" -->\n";
+      }
+      print OUT "</table>\n";
+    }
+    
+    if (scalar @failures) {
+      print OUT "<p>The analyzer had problems processing the following files:</p>\n";
+      print OUT "<table>\n";
+      print OUT "<thead><tr><td>Problem</td><td>Source File</td><td>Preprocessed File</td><td>STDERR Output</td></tr></thead>\n";
+      foreach my $file (sort @failures) {
+        $file =~ /(.+).info.txt$/;
+        # Get the preprocessed file.
+        my $ppfile = $1;
+        # Open the info file and get the name of the source file.
+        open (INFO, "$Dir/failures/$file") or
+          die "Cannot open $Dir/failures/$file\n";
+        my $srcfile = <INFO>;
+        chomp $srcfile;
+        my $problem = <INFO>;
+        chomp $problem;
+        close (INFO);
+        # Print the information in the table.
+        my $prefix = GetPrefix();
+        if (defined $prefix) { $srcfile =~ s/^\Q$prefix//; }
+        print OUT "<tr><td>$problem</td><td>$srcfile</td><td><a href=\"failures/$ppfile\">$ppfile</a></td><td><a href=\"failures/$ppfile.stderr.txt\">$ppfile.stderr.txt</a></td></tr>\n";
+        my $ppfile_clang = $ppfile;
+        $ppfile_clang =~ s/[.](.+)$/.clang.$1/;
+        print OUT "  <!-- REPORTPROBLEM src=\"$srcfile\" file=\"failures/$ppfile\" clangfile=\"failures/$ppfile_clang\" stderr=\"failures/$ppfile.stderr.txt\" info=\"failures/$ppfile.info.txt\" -->\n";
+      }
+      print OUT "</table>\n";
+    }    
+    print OUT "<p>Please consider submitting preprocessed files as <a href=\"http://clang.llvm.org/StaticAnalysisUsage.html#filingbugs\">bug reports</a>. <!-- REPORTCRASHES --> </p>\n";
+  }
+  
+  print OUT "</body></html>\n";  
+  close(OUT);
+  CopyFiles($Dir);
+
+  # Make sure $Dir and $BaseDir are world readable/executable.
+  system("chmod", "755", $Dir);
+  if (defined $BaseDir) { system("chmod", "755", $BaseDir); }
+
+  my $Num = scalar(@Index);
+  Diag("$Num bugs found.\n");
+  if ($Num > 0 && -r "$Dir/index.html") {
+    Diag("Run 'scan-view $Dir' to examine bug reports.\n");
+  }
+  
+  DiagCrashes($Dir) if (scalar @failures || scalar @attributes_ignored);
+  
+  return $Num;
+}
+
+##----------------------------------------------------------------------------##
+# RunBuildCommand - Run the build command.
+##----------------------------------------------------------------------------##
+
+sub AddIfNotPresent {
+  my $Args = shift;
+  my $Arg = shift;  
+  my $found = 0;
+  
+  foreach my $k (@$Args) {
+    if ($k eq $Arg) {
+      $found = 1;
+      last;
+    }
+  }
+  
+  if ($found == 0) {
+    push @$Args, $Arg;
+  }
+}
+
+sub RunBuildCommand {
+  
+  my $Args = shift;
+  my $IgnoreErrors = shift;
+  my $Cmd = $Args->[0];
+  my $CCAnalyzer = shift;
+  my $CXXAnalyzer = shift;
+  
+  # Get only the part of the command after the last '/'.
+  if ($Cmd =~ /\/([^\/]+)$/) {
+    $Cmd = $1;
+  }
+  
+  if ($Cmd =~ /(.*\/?gcc[^\/]*$)/ or 
+      $Cmd =~ /(.*\/?cc[^\/]*$)/ or
+      $Cmd =~ /(.*\/?llvm-gcc[^\/]*$)/ or
+      $Cmd =~ /(.*\/?ccc-analyzer[^\/]*$)/) {
+
+    if (!($Cmd =~ /ccc-analyzer/) and !defined $ENV{"CCC_CC"}) {
+      $ENV{"CCC_CC"} = $1;      
+    }
+        
+    shift @$Args;
+    unshift @$Args, $CCAnalyzer;
+  }
+  elsif ($Cmd =~ /(.*\/?g\+\+[^\/]*$)/ or 
+        $Cmd =~ /(.*\/?c\+\+[^\/]*$)/ or
+        $Cmd =~ /(.*\/?llvm-g\+\+[^\/]*$)/ or
+        $Cmd =~ /(.*\/?c\+\+-analyzer[^\/]*$)/) {
+    if (!($Cmd =~ /c\+\+-analyzer/) and !defined $ENV{"CCC_CXX"}) {
+      $ENV{"CCC_CXX"} = $1;      
+    }        
+    shift @$Args;
+    unshift @$Args, $CXXAnalyzer;
+  }
+  elsif ($IgnoreErrors) {
+    if ($Cmd eq "make" or $Cmd eq "gmake") {
+      AddIfNotPresent($Args, "CC=$CCAnalyzer");
+      AddIfNotPresent($Args, "CXX=$CXXAnalyzer");
+      AddIfNotPresent($Args,"-k");
+      AddIfNotPresent($Args,"-i");
+    }
+    elsif ($Cmd eq "xcodebuild") {
+      AddIfNotPresent($Args,"-PBXBuildsContinueAfterErrors=YES");
+    }
+  } 
+  
+  if ($Cmd eq "xcodebuild") {
+    # Check if using iPhone SDK 3.0 (simulator).  If so the compiler being
+    # used should be gcc-4.2.
+    if (!defined $ENV{"CCC_CC"}) {
+      for (my $i = 0 ; $i < scalar(@$Args); ++$i) {
+        if ($Args->[$i] eq "-sdk" && $i + 1 < scalar(@$Args)) {
+          if (@$Args[$i+1] =~ /^iphonesimulator3/) {
+            $ENV{"CCC_CC"} = "gcc-4.2";
+            $ENV{"CCC_CXX"} = "g++-4.2";            
+          }
+        }
+      }
+    }
+
+    # Disable distributed builds for xcodebuild.
+    AddIfNotPresent($Args,"-nodistribute");
+
+    # Disable PCH files until clang supports them.
+    AddIfNotPresent($Args,"GCC_PRECOMPILE_PREFIX_HEADER=NO");
+    
+    # When 'CC' is set, xcodebuild uses it to do all linking, even if we are
+    # linking C++ object files.  Set 'LDPLUSPLUS' so that xcodebuild uses 'g++'
+    # (via c++-analyzer) when linking such files.
+    $ENV{"LDPLUSPLUS"} = $CXXAnalyzer;
+  }
+  
+  return (system(@$Args) >> 8);
+}
+
+##----------------------------------------------------------------------------##
+# DisplayHelp - Utility function to display all help options.
+##----------------------------------------------------------------------------##
+
+sub DisplayHelp {
+  
+print <<ENDTEXT;
+USAGE: $Prog [options] <build command> [build options]
+
+ENDTEXT
+
+  if (defined $BuildName) {
+    print "ANALYZER BUILD: $BuildName ($BuildDate)\n\n";
+  }
+
+print <<ENDTEXT;
+OPTIONS:
+
+ -analyze-headers - Also analyze functions in #included files.
+ 
+ --experimental-checks - Enable experimental checks that are currently in heavy testing
+
+ -o             - Target directory for HTML report files.  Subdirectories
+                  will be created as needed to represent separate "runs" of
+                  the analyzer.  If this option is not specified, a directory
+                  is created in /tmp (TMPDIR on Mac OS X) to store the reports.
+                  
+ -h             - Display this message.
+ --help
+
+ -k             - Add a "keep on going" option to the specified build command.
+ --keep-going     This option currently supports make and xcodebuild.
+                  This is a convenience option; one can specify this
+                  behavior directly using build options.
+
+ --html-title [title]       - Specify the title used on generated HTML pages.
+ --html-title=[title]         If not specified, a default title will be used.
+
+ -plist         - By default the output of scan-build is a set of HTML files.
+                  This option outputs the results as a set of .plist files.
+
+ --status-bugs  - By default, the exit status of $Prog is the same as the
+                  executed build command.  Specifying this option causes the
+                  exit status of $Prog to be 1 if it found potential bugs
+                  and 0 otherwise.
+
+ --use-cc [compiler path]   - By default, $Prog uses 'gcc' to compile and link
+ --use-cc=[compiler path]     your C and Objective-C code. Use this option
+                              to specify an alternate compiler.
+
+ --use-c++ [compiler path]  - By default, $Prog uses 'g++' to compile and link
+ --use-c++=[compiler path]    your C++ and Objective-C++ code. Use this option
+                              to specify an alternate compiler.
+
+ -v             - Verbose output from $Prog and the analyzer.
+                  A second and third '-v' increases verbosity.
+
+ -V             - View analysis results in a web browser when the build
+ --view           completes.
+
+ADVANCED OPTIONS:
+
+ -constraints [model] - Specify the contraint engine used by the analyzer.
+                        By default the 'range' model is used.  Specifying 
+                        'basic' uses a simpler, less powerful constraint model
+                        used by checker-0.160 and earlier.
+
+ -store [model] - Specify the store model used by the analyzer. By default,
+                  the 'region' store model is used. 'region' specifies a field-
+                  sensitive store model. Users can also specify 'basic', which
+                  is far less precise but can more quickly analyze code.
+                  'basic' was the default store model for checker-0.221 and
+                  earlier.
+
+ -no-failure-reports - Do not create a 'failures' subdirectory that includes
+                       analyzer crash reports and preprocessed source files.
+
+AVAILABLE ANALYSES (multiple analyses may be specified):
+
+ENDTEXT
+
+  foreach my $Analysis (sort keys %AvailableAnalyses) {
+    if (defined $AnalysesDefaultEnabled{$Analysis}) {
+      print " (+)";
+    }
+    else {
+      print "    ";
+    }
+    
+    print " $Analysis\n";
+  }
+  
+print <<ENDTEXT
+
+ NOTE: "(+)" indicates that an analysis is enabled by default unless one
+       or more analysis options are specified
+
+BUILD OPTIONS
+
+ You can specify any build option acceptable to the build command.
+
+EXAMPLE
+
+ $Prog -o /tmp/myhtmldir make -j4
+     
+ The above example causes analysis reports to be deposited into
+ a subdirectory of "/tmp/myhtmldir" and to run "make" with the "-j4" option.
+ A different subdirectory is created each time $Prog analyzes a project.
+ The analyzer should support most parallel builds, but not distributed builds.
+
+ENDTEXT
+}
+
+##----------------------------------------------------------------------------##
+# HtmlEscape - HTML entity encode characters that are special in HTML
+##----------------------------------------------------------------------------##
+
+sub HtmlEscape {
+  # copy argument to new variable so we don't clobber the original
+  my $arg = shift || '';
+  my $tmp = $arg;
+  $tmp =~ s/&/&amp;/g;
+  $tmp =~ s/</&lt;/g;
+  $tmp =~ s/>/&gt;/g;
+  return $tmp;
+}
+
+##----------------------------------------------------------------------------##
+# ShellEscape - backslash escape characters that are special to the shell
+##----------------------------------------------------------------------------##
+
+sub ShellEscape {
+  # copy argument to new variable so we don't clobber the original
+  my $arg = shift || '';
+  if ($arg =~ /["\s]/) { return "'" . $arg . "'"; }
+  return $arg;
+}
+
+##----------------------------------------------------------------------------##
+# Process command-line arguments.
+##----------------------------------------------------------------------------##
+
+my $AnalyzeHeaders = 0;
+my $HtmlDir;           # Parent directory to store HTML files.
+my $IgnoreErrors = 0;  # Ignore build errors.
+my $ViewResults  = 0;  # View results when the build terminates.
+my $ExitStatusFoundBugs = 0; # Exit status reflects whether bugs were found
+my @AnalysesToRun;
+my $StoreModel;
+my $ConstraintsModel;
+my $OutputFormat = "html";
+
+if (!@ARGV) {
+  DisplayHelp();
+  exit 1;
+}
+
+while (@ARGV) {
+  
+  # Scan for options we recognize.
+  
+  my $arg = $ARGV[0];
+
+  if ($arg eq "-h" or $arg eq "--help") {
+    DisplayHelp();
+    exit 0;
+  }
+  
+  if ($arg eq '-analyze-headers') {
+    shift @ARGV;    
+    $AnalyzeHeaders = 1;
+    next;
+  }
+  
+  if (defined $AvailableAnalyses{$arg}) {
+    shift @ARGV;
+    push @AnalysesToRun, $arg;
+    next;
+  }
+  
+  if ($arg eq "-o") {
+    shift @ARGV;
+        
+    if (!@ARGV) {
+      DieDiag("'-o' option requires a target directory name.\n");
+    }
+    
+    # Construct an absolute path.  Uses the current working directory
+    # as a base if the original path was not absolute.
+    $HtmlDir = abs_path(shift @ARGV);
+    
+    next;
+  }
+
+  if ($arg =~ /^--html-title(=(.+))?$/) {
+    shift @ARGV;
+
+    if (!defined $2 || $2 eq '') {
+      if (!@ARGV) {
+        DieDiag("'--html-title' option requires a string.\n");
+      }
+
+      $HtmlTitle = shift @ARGV;
+    } else {
+      $HtmlTitle = $2;
+    }
+
+    next;
+  }
+  
+  if ($arg eq "-k" or $arg eq "--keep-going") {
+    shift @ARGV;
+    $IgnoreErrors = 1;
+    next;
+  }
+  
+  if ($arg eq "--experimental-checks") {
+    shift @ARGV;
+    $ENV{"CCC_EXPERIMENTAL_CHECKS"} = 1;
+    next;
+  }
+  
+  if ($arg =~ /^--use-cc(=(.+))?$/) {
+    shift @ARGV;
+    my $cc;
+    
+    if (!defined $2 || $2 eq "") {
+      if (!@ARGV) {
+        DieDiag("'--use-cc' option requires a compiler executable name.\n");
+      }
+      $cc = shift @ARGV;
+    }
+    else {
+      $cc = $2;
+    }
+    
+    $ENV{"CCC_CC"} = $cc;
+    next;
+  }
+  
+  if ($arg =~ /^--use-c\+\+(=(.+))?$/) {
+    shift @ARGV;
+    my $cxx;    
+    
+    if (!defined $2 || $2 eq "") {
+      if (!@ARGV) {
+        DieDiag("'--use-c++' option requires a compiler executable name.\n");
+      }
+      $cxx = shift @ARGV;
+    }
+    else {
+      $cxx = $2;
+    }
+    
+    $ENV{"CCC_CXX"} = $cxx;
+    next;
+  }
+  
+  if ($arg eq "-v") {
+    shift @ARGV;
+    $Verbose++;
+    next;
+  }
+  
+  if ($arg eq "-V" or $arg eq "--view") {
+    shift @ARGV;
+    $ViewResults = 1;    
+    next;
+  }
+  
+  if ($arg eq "--status-bugs") {
+    shift @ARGV;
+    $ExitStatusFoundBugs = 1;
+    next;
+  }
+
+  if ($arg eq "-store") {
+    shift @ARGV;
+    $StoreModel = shift @ARGV;
+    next;
+  }
+  
+  if ($arg eq "-constraints") {
+    shift @ARGV;
+    $ConstraintsModel = shift @ARGV;
+    next;
+  }
+  
+  if ($arg eq "-plist") {
+    shift @ARGV;
+    $OutputFormat = "plist";
+    next;
+  }
+  if ($arg eq "-plist-html") {
+    shift @ARGV;
+    $OutputFormat = "plist-html";
+    next;
+  }
+  
+  if ($arg eq "-no-failure-reports") {
+    $ENV{"CCC_REPORT_FAILURES"} = 0;
+    next;
+  }
+
+  DieDiag("unrecognized option '$arg'\n") if ($arg =~ /^-/);
+  
+  last;
+}
+
+if (!@ARGV) {
+  Diag("No build command specified.\n\n");
+  DisplayHelp();
+  exit 1;
+}
+
+$CmdArgs = HtmlEscape(join(' ', map(ShellEscape($_), @ARGV)));
+$HtmlTitle = "${CurrentDirSuffix} - scan-build results"
+  unless (defined($HtmlTitle));
+
+# Determine the output directory for the HTML reports.
+my $BaseDir = $HtmlDir;
+$HtmlDir = GetHTMLRunDir($HtmlDir);
+
+# Set the appropriate environment variables.
+SetHtmlEnv(\@ARGV, $HtmlDir);
+
+my $AbsRealBin = Cwd::realpath($RealBin);
+my $Cmd = "$AbsRealBin/libexec/ccc-analyzer";
+my $CmdCXX = "$AbsRealBin/libexec/c++-analyzer";
+
+if (!defined $Cmd || ! -x $Cmd) {
+  $Cmd = "$AbsRealBin/ccc-analyzer";
+  DieDiag("Executable 'ccc-analyzer' does not exist at '$Cmd'\n") if(! -x $Cmd);
+}
+if (!defined $CmdCXX || ! -x $CmdCXX) {
+  $CmdCXX = "$AbsRealBin/c++-analyzer";
+  DieDiag("Executable 'c++-analyzer' does not exist at '$CmdCXX'\n") if(! -x $CmdCXX);
+}
+
+if (!defined $ClangSB || ! -x $ClangSB) {
+  Diag("'clang' executable not found in '$RealBin/bin'.\n");
+  Diag("Using 'clang' from path: $Clang\n");
+}
+
+$ENV{'CC'} = $Cmd;
+$ENV{'CXX'} = $CmdCXX;
+$ENV{'CLANG'} = $Clang;
+$ENV{'CLANG_CXX'} = $ClangCXX;
+
+if ($Verbose >= 2) {
+  $ENV{'CCC_ANALYZER_VERBOSE'} = 1;
+}
+
+if ($Verbose >= 3) {
+  $ENV{'CCC_ANALYZER_LOG'} = 1;
+}
+
+if (scalar(@AnalysesToRun) == 0) {
+  foreach my $key (keys %AnalysesDefaultEnabled) {
+    push @AnalysesToRun,$key;
+  }
+}
+
+if ($AnalyzeHeaders) {
+  push @AnalysesToRun,"-analyzer-opt-analyze-headers";  
+}
+
+$ENV{'CCC_ANALYZER_ANALYSIS'} = join ' ',@AnalysesToRun;
+
+if (defined $StoreModel) {
+  $ENV{'CCC_ANALYZER_STORE_MODEL'} = $StoreModel;
+}
+
+if (defined $ConstraintsModel) {
+  $ENV{'CCC_ANALYZER_CONSTRAINTS_MODEL'} = $ConstraintsModel;
+}
+
+if (defined $OutputFormat) {
+  $ENV{'CCC_ANALYZER_OUTPUT_FORMAT'} = $OutputFormat;
+}
+
+# Run the build.
+my $ExitStatus = RunBuildCommand(\@ARGV, $IgnoreErrors, $Cmd, $CmdCXX);
+
+if (defined $OutputFormat) {
+  if ($OutputFormat =~ /plist/) {
+    Diag "Analysis run complete.\n";
+    Diag "Analysis results (plist files) deposited in '$HtmlDir'\n";
+  }
+  elsif ($OutputFormat =~ /html/) {
+    # Postprocess the HTML directory.
+    my $NumBugs = Postprocess($HtmlDir, $BaseDir);
+
+    if ($ViewResults and -r "$HtmlDir/index.html") {
+      Diag "Analysis run complete.\n";
+      Diag "Viewing analysis results in '$HtmlDir' using scan-view.\n";
+      my $ScanView = Cwd::realpath("$RealBin/scan-view");
+      if (! -x $ScanView) { $ScanView = "scan-view"; }
+      exec $ScanView, "$HtmlDir";
+    }
+
+    if ($ExitStatusFoundBugs) {
+      exit 1 if ($NumBugs > 0);
+      exit 0;
+    }
+  }
+}
+
+exit $ExitStatus;
+
diff --git a/tools/scan-build/scanview.css b/tools/scan-build/scanview.css
new file mode 100644
index 0000000..a0406f3
--- /dev/null
+++ b/tools/scan-build/scanview.css
@@ -0,0 +1,62 @@
+body { color:#000000; background-color:#ffffff }
+body { font-family: Helvetica, sans-serif; font-size:9pt }
+h1 { font-size: 14pt; }
+h2 { font-size: 12pt; }
+table { font-size:9pt }
+table { border-spacing: 0px; border: 1px solid black }
+th, table thead {
+  background-color:#eee; color:#666666;
+  font-weight: bold; cursor: default;
+  text-align:center;
+  font-weight: bold; font-family: Verdana;
+  white-space:nowrap;
+} 
+.W { font-size:0px }
+th, td { padding:5px; padding-left:8px; text-align:left }
+td.SUMM_DESC { padding-left:12px }
+td.DESC { white-space:pre }
+td.Q { text-align:right }
+td { text-align:left }
+tbody.scrollContent { overflow:auto }
+
+table.form_group {
+    background-color: #ccc;
+    border: 1px solid #333; 
+    padding: 2px;
+}
+
+table.form_inner_group {
+    background-color: #ccc;
+    border: 1px solid #333;
+    padding: 0px;
+}
+
+table.form {
+    background-color: #999;
+    border: 1px solid #333; 
+    padding: 2px;
+}
+
+td.form_label {
+    text-align: right;
+    vertical-align: top;
+}
+/* For one line entires */
+td.form_clabel {
+    text-align: right;
+    vertical-align: center;
+}
+td.form_value {
+    text-align: left;
+    vertical-align: top;
+}
+td.form_submit {
+    text-align: right;
+    vertical-align: top;
+}
+
+h1.SubmitFail {
+    color: #f00;
+}
+h1.SubmitOk {
+}
diff --git a/tools/scan-build/set-xcode-analyzer b/tools/scan-build/set-xcode-analyzer
new file mode 100755
index 0000000..cc068a5
--- /dev/null
+++ b/tools/scan-build/set-xcode-analyzer
@@ -0,0 +1,77 @@
+#!/usr/bin/env python
+
+import os
+import sys
+import re
+import tempfile
+import shutil
+import stat
+from AppKit import *
+
+def FindClangSpecs(path):
+  for root, dirs, files in os.walk(path):
+    for f in files:
+      if f.endswith(".xcspec") and f.startswith("Clang LLVM"):
+        yield os.path.join(root, f)
+
+def ModifySpec(path, pathToChecker):
+  t = tempfile.NamedTemporaryFile(delete=False)
+  foundAnalyzer = False
+  with open(path) as f:
+    for line in f:
+      if not foundAnalyzer:
+        if line.find("Static Analyzer") >= 0:
+          foundAnalyzer = True
+      else:
+        m = re.search('^(\s*ExecPath\s*=\s*")', line)
+        if m:
+          line = "".join([m.group(0), pathToChecker, '";\n'])
+      t.write(line)
+  t.close()
+  print "(+) processing:", path
+  try:
+    shutil.copy(t.name, path)
+    os.chmod(path, stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH)
+  except IOError, why:
+    print "    (-) Cannot update file:", why, "\n"
+  except OSError, why:
+    print "    (-) Cannot update file:", why, "\n"
+  os.unlink(t.name)
+
+def main():
+  from optparse import OptionParser
+  parser = OptionParser('usage: %prog [options]')
+  parser.set_description(__doc__)
+  parser.add_option("--use-checker-build", dest="path",
+                    help="Use the Clang located at the provided absolute path, e.g. /Users/foo/checker-1")
+  parser.add_option("--use-xcode-clang", action="store_const", 
+                    const="$(CLANG)", dest="default",
+                    help="Use the Clang bundled with Xcode")
+  (options, args) = parser.parse_args()
+  if options.path is None and options.default is None:
+    parser.error("You must specify a version of Clang to use for static analysis.  Specify '-h' for details")
+
+  # determine if Xcode is running
+  for x in NSWorkspace.sharedWorkspace().runningApplications():
+    if x.localizedName().find("Xcode") >= 0:
+      print "(-) You must quit Xcode first before modifying its configuration files."
+      return
+
+  if options.path:
+    # Expand tildes.
+    path = os.path.expanduser(options.path)
+    if not path.endswith("clang"):
+      print "(+) Using Clang bundled with checker build:", path
+      path = os.path.join(path, "bin", "clang");
+    else:
+      print "(+) Using Clang located at:", path
+  else:
+    print "(+) Using the Clang bundled with Xcode"
+    path = options.default
+  
+  for x in FindClangSpecs('/Developer'):
+    ModifySpec(x, path)
+
+if __name__ == '__main__':
+  main()
+
diff --git a/tools/scan-build/sorttable.js b/tools/scan-build/sorttable.js
new file mode 100644
index 0000000..4352d3b
--- /dev/null
+++ b/tools/scan-build/sorttable.js
@@ -0,0 +1,493 @@
+/*
+  SortTable
+  version 2
+  7th April 2007
+  Stuart Langridge, http://www.kryogenix.org/code/browser/sorttable/
+  
+  Instructions:
+  Download this file
+  Add <script src="sorttable.js"></script> to your HTML
+  Add class="sortable" to any table you'd like to make sortable
+  Click on the headers to sort
+  
+  Thanks to many, many people for contributions and suggestions.
+  Licenced as X11: http://www.kryogenix.org/code/browser/licence.html
+  This basically means: do what you want with it.
+*/
+
+ 
+var stIsIE = /*@cc_on!@*/false;
+
+sorttable = {
+  init: function() {
+    // quit if this function has already been called
+    if (arguments.callee.done) return;
+    // flag this function so we don't do the same thing twice
+    arguments.callee.done = true;
+    // kill the timer
+    if (_timer) clearInterval(_timer);
+    
+    if (!document.createElement || !document.getElementsByTagName) return;
+    
+    sorttable.DATE_RE = /^(\d\d?)[\/\.-](\d\d?)[\/\.-]((\d\d)?\d\d)$/;
+    
+    forEach(document.getElementsByTagName('table'), function(table) {
+      if (table.className.search(/\bsortable\b/) != -1) {
+        sorttable.makeSortable(table);
+      }
+    });
+    
+  },
+  
+  makeSortable: function(table) {
+    if (table.getElementsByTagName('thead').length == 0) {
+      // table doesn't have a tHead. Since it should have, create one and
+      // put the first table row in it.
+      the = document.createElement('thead');
+      the.appendChild(table.rows[0]);
+      table.insertBefore(the,table.firstChild);
+    }
+    // Safari doesn't support table.tHead, sigh
+    if (table.tHead == null) table.tHead = table.getElementsByTagName('thead')[0];
+    
+    if (table.tHead.rows.length != 1) return; // can't cope with two header rows
+    
+    // Sorttable v1 put rows with a class of "sortbottom" at the bottom (as
+    // "total" rows, for example). This is B&R, since what you're supposed
+    // to do is put them in a tfoot. So, if there are sortbottom rows,
+    // for backwards compatibility, move them to tfoot (creating it if needed).
+    sortbottomrows = [];
+    for (var i=0; i<table.rows.length; i++) {
+      if (table.rows[i].className.search(/\bsortbottom\b/) != -1) {
+        sortbottomrows[sortbottomrows.length] = table.rows[i];
+      }
+    }
+    if (sortbottomrows) {
+      if (table.tFoot == null) {
+        // table doesn't have a tfoot. Create one.
+        tfo = document.createElement('tfoot');
+        table.appendChild(tfo);
+      }
+      for (var i=0; i<sortbottomrows.length; i++) {
+        tfo.appendChild(sortbottomrows[i]);
+      }
+      delete sortbottomrows;
+    }
+    
+    // work through each column and calculate its type
+    headrow = table.tHead.rows[0].cells;
+    for (var i=0; i<headrow.length; i++) {
+      // manually override the type with a sorttable_type attribute
+      if (!headrow[i].className.match(/\bsorttable_nosort\b/)) { // skip this col
+        mtch = headrow[i].className.match(/\bsorttable_([a-z0-9]+)\b/);
+        if (mtch) { override = mtch[1]; }
+	      if (mtch && typeof sorttable["sort_"+override] == 'function') {
+	        headrow[i].sorttable_sortfunction = sorttable["sort_"+override];
+	      } else {
+	        headrow[i].sorttable_sortfunction = sorttable.guessType(table,i);
+	      }
+	      // make it clickable to sort
+	      headrow[i].sorttable_columnindex = i;
+	      headrow[i].sorttable_tbody = table.tBodies[0];
+	      dean_addEvent(headrow[i],"click", function(e) {
+
+          if (this.className.search(/\bsorttable_sorted\b/) != -1) {
+            // if we're already sorted by this column, just 
+            // reverse the table, which is quicker
+            sorttable.reverse(this.sorttable_tbody);
+            this.className = this.className.replace('sorttable_sorted',
+                                                    'sorttable_sorted_reverse');
+            this.removeChild(document.getElementById('sorttable_sortfwdind'));
+            sortrevind = document.createElement('span');
+            sortrevind.id = "sorttable_sortrevind";
+            sortrevind.innerHTML = stIsIE ? '&nbsp<font face="webdings">5</font>' : '&nbsp;&#x25B4;';
+            this.appendChild(sortrevind);
+            return;
+          }
+          if (this.className.search(/\bsorttable_sorted_reverse\b/) != -1) {
+            // if we're already sorted by this column in reverse, just 
+            // re-reverse the table, which is quicker
+            sorttable.reverse(this.sorttable_tbody);
+            this.className = this.className.replace('sorttable_sorted_reverse',
+                                                    'sorttable_sorted');
+            this.removeChild(document.getElementById('sorttable_sortrevind'));
+            sortfwdind = document.createElement('span');
+            sortfwdind.id = "sorttable_sortfwdind";
+            sortfwdind.innerHTML = stIsIE ? '&nbsp<font face="webdings">6</font>' : '&nbsp;&#x25BE;';
+            this.appendChild(sortfwdind);
+            return;
+          }
+          
+          // remove sorttable_sorted classes
+          theadrow = this.parentNode;
+          forEach(theadrow.childNodes, function(cell) {
+            if (cell.nodeType == 1) { // an element
+              cell.className = cell.className.replace('sorttable_sorted_reverse','');
+              cell.className = cell.className.replace('sorttable_sorted','');
+            }
+          });
+          sortfwdind = document.getElementById('sorttable_sortfwdind');
+          if (sortfwdind) { sortfwdind.parentNode.removeChild(sortfwdind); }
+          sortrevind = document.getElementById('sorttable_sortrevind');
+          if (sortrevind) { sortrevind.parentNode.removeChild(sortrevind); }
+          
+          this.className += ' sorttable_sorted';
+          sortfwdind = document.createElement('span');
+          sortfwdind.id = "sorttable_sortfwdind";
+          sortfwdind.innerHTML = stIsIE ? '&nbsp<font face="webdings">6</font>' : '&nbsp;&#x25BE;';
+          this.appendChild(sortfwdind);
+
+	        // build an array to sort. This is a Schwartzian transform thing,
+	        // i.e., we "decorate" each row with the actual sort key,
+	        // sort based on the sort keys, and then put the rows back in order
+	        // which is a lot faster because you only do getInnerText once per row
+	        row_array = [];
+	        col = this.sorttable_columnindex;
+	        rows = this.sorttable_tbody.rows;
+	        for (var j=0; j<rows.length; j++) {
+	          row_array[row_array.length] = [sorttable.getInnerText(rows[j].cells[col]), rows[j]];
+	        }
+	        /* If you want a stable sort, uncomment the following line */
+	        sorttable.shaker_sort(row_array, this.sorttable_sortfunction);
+	        /* and comment out this one */
+	        //row_array.sort(this.sorttable_sortfunction);
+	        
+	        tb = this.sorttable_tbody;
+	        for (var j=0; j<row_array.length; j++) {
+	          tb.appendChild(row_array[j][1]);
+	        }
+	        
+	        delete row_array;
+	      });
+	    }
+    }
+  },
+  
+  guessType: function(table, column) {
+    // guess the type of a column based on its first non-blank row
+    sortfn = sorttable.sort_alpha;
+    for (var i=0; i<table.tBodies[0].rows.length; i++) {
+      text = sorttable.getInnerText(table.tBodies[0].rows[i].cells[column]);
+      if (text != '') {
+        if (text.match(/^-?[£$¤]?[\d,.]+%?$/)) {
+          return sorttable.sort_numeric;
+        }
+        // check for a date: dd/mm/yyyy or dd/mm/yy 
+        // can have / or . or - as separator
+        // can be mm/dd as well
+        possdate = text.match(sorttable.DATE_RE)
+        if (possdate) {
+          // looks like a date
+          first = parseInt(possdate[1]);
+          second = parseInt(possdate[2]);
+          if (first > 12) {
+            // definitely dd/mm
+            return sorttable.sort_ddmm;
+          } else if (second > 12) {
+            return sorttable.sort_mmdd;
+          } else {
+            // looks like a date, but we can't tell which, so assume
+            // that it's dd/mm (English imperialism!) and keep looking
+            sortfn = sorttable.sort_ddmm;
+          }
+        }
+      }
+    }
+    return sortfn;
+  },
+  
+  getInnerText: function(node) {
+    // gets the text we want to use for sorting for a cell.
+    // strips leading and trailing whitespace.
+    // this is *not* a generic getInnerText function; it's special to sorttable.
+    // for example, you can override the cell text with a customkey attribute.
+    // it also gets .value for <input> fields.
+    
+    hasInputs = (typeof node.getElementsByTagName == 'function') &&
+                 node.getElementsByTagName('input').length;
+    
+    if (node.getAttribute("sorttable_customkey") != null) {
+      return node.getAttribute("sorttable_customkey");
+    }
+    else if (typeof node.textContent != 'undefined' && !hasInputs) {
+      return node.textContent.replace(/^\s+|\s+$/g, '');
+    }
+    else if (typeof node.innerText != 'undefined' && !hasInputs) {
+      return node.innerText.replace(/^\s+|\s+$/g, '');
+    }
+    else if (typeof node.text != 'undefined' && !hasInputs) {
+      return node.text.replace(/^\s+|\s+$/g, '');
+    }
+    else {
+      switch (node.nodeType) {
+        case 3:
+          if (node.nodeName.toLowerCase() == 'input') {
+            return node.value.replace(/^\s+|\s+$/g, '');
+          }
+        case 4:
+          return node.nodeValue.replace(/^\s+|\s+$/g, '');
+          break;
+        case 1:
+        case 11:
+          var innerText = '';
+          for (var i = 0; i < node.childNodes.length; i++) {
+            innerText += sorttable.getInnerText(node.childNodes[i]);
+          }
+          return innerText.replace(/^\s+|\s+$/g, '');
+          break;
+        default:
+          return '';
+      }
+    }
+  },
+  
+  reverse: function(tbody) {
+    // reverse the rows in a tbody
+    newrows = [];
+    for (var i=0; i<tbody.rows.length; i++) {
+      newrows[newrows.length] = tbody.rows[i];
+    }
+    for (var i=newrows.length-1; i>=0; i--) {
+       tbody.appendChild(newrows[i]);
+    }
+    delete newrows;
+  },
+  
+  /* sort functions
+     each sort function takes two parameters, a and b
+     you are comparing a[0] and b[0] */
+  sort_numeric: function(a,b) {
+    aa = parseFloat(a[0].replace(/[^0-9.-]/g,''));
+    if (isNaN(aa)) aa = 0;
+    bb = parseFloat(b[0].replace(/[^0-9.-]/g,'')); 
+    if (isNaN(bb)) bb = 0;
+    return aa-bb;
+  },
+  sort_alpha: function(a,b) {
+    if (a[0]==b[0]) return 0;
+    if (a[0]<b[0]) return -1;
+    return 1;
+  },
+  sort_ddmm: function(a,b) {
+    mtch = a[0].match(sorttable.DATE_RE);
+    y = mtch[3]; m = mtch[2]; d = mtch[1];
+    if (m.length == 1) m = '0'+m;
+    if (d.length == 1) d = '0'+d;
+    dt1 = y+m+d;
+    mtch = b[0].match(sorttable.DATE_RE);
+    y = mtch[3]; m = mtch[2]; d = mtch[1];
+    if (m.length == 1) m = '0'+m;
+    if (d.length == 1) d = '0'+d;
+    dt2 = y+m+d;
+    if (dt1==dt2) return 0;
+    if (dt1<dt2) return -1;
+    return 1;
+  },
+  sort_mmdd: function(a,b) {
+    mtch = a[0].match(sorttable.DATE_RE);
+    y = mtch[3]; d = mtch[2]; m = mtch[1];
+    if (m.length == 1) m = '0'+m;
+    if (d.length == 1) d = '0'+d;
+    dt1 = y+m+d;
+    mtch = b[0].match(sorttable.DATE_RE);
+    y = mtch[3]; d = mtch[2]; m = mtch[1];
+    if (m.length == 1) m = '0'+m;
+    if (d.length == 1) d = '0'+d;
+    dt2 = y+m+d;
+    if (dt1==dt2) return 0;
+    if (dt1<dt2) return -1;
+    return 1;
+  },
+  
+  shaker_sort: function(list, comp_func) {
+    // A stable sort function to allow multi-level sorting of data
+    // see: http://en.wikipedia.org/wiki/Cocktail_sort
+    // thanks to Joseph Nahmias
+    var b = 0;
+    var t = list.length - 1;
+    var swap = true;
+
+    while(swap) {
+        swap = false;
+        for(var i = b; i < t; ++i) {
+            if ( comp_func(list[i], list[i+1]) > 0 ) {
+                var q = list[i]; list[i] = list[i+1]; list[i+1] = q;
+                swap = true;
+            }
+        } // for
+        t--;
+
+        if (!swap) break;
+
+        for(var i = t; i > b; --i) {
+            if ( comp_func(list[i], list[i-1]) < 0 ) {
+                var q = list[i]; list[i] = list[i-1]; list[i-1] = q;
+                swap = true;
+            }
+        } // for
+        b++;
+
+    } // while(swap)
+  }  
+}
+
+/* ******************************************************************
+   Supporting functions: bundled here to avoid depending on a library
+   ****************************************************************** */
+
+// Dean Edwards/Matthias Miller/John Resig
+
+/* for Mozilla/Opera9 */
+if (document.addEventListener) {
+    document.addEventListener("DOMContentLoaded", sorttable.init, false);
+}
+
+/* for Internet Explorer */
+/*@cc_on @*/
+/*@if (@_win32)
+    document.write("<script id=__ie_onload defer src=javascript:void(0)><\/script>");
+    var script = document.getElementById("__ie_onload");
+    script.onreadystatechange = function() {
+        if (this.readyState == "complete") {
+            sorttable.init(); // call the onload handler
+        }
+    };
+/*@end @*/
+
+/* for Safari */
+if (/WebKit/i.test(navigator.userAgent)) { // sniff
+    var _timer = setInterval(function() {
+        if (/loaded|complete/.test(document.readyState)) {
+            sorttable.init(); // call the onload handler
+        }
+    }, 10);
+}
+
+/* for other browsers */
+window.onload = sorttable.init;
+
+// written by Dean Edwards, 2005
+// with input from Tino Zijdel, Matthias Miller, Diego Perini
+
+// http://dean.edwards.name/weblog/2005/10/add-event/
+
+function dean_addEvent(element, type, handler) {
+	if (element.addEventListener) {
+		element.addEventListener(type, handler, false);
+	} else {
+		// assign each event handler a unique ID
+		if (!handler.$$guid) handler.$$guid = dean_addEvent.guid++;
+		// create a hash table of event types for the element
+		if (!element.events) element.events = {};
+		// create a hash table of event handlers for each element/event pair
+		var handlers = element.events[type];
+		if (!handlers) {
+			handlers = element.events[type] = {};
+			// store the existing event handler (if there is one)
+			if (element["on" + type]) {
+				handlers[0] = element["on" + type];
+			}
+		}
+		// store the event handler in the hash table
+		handlers[handler.$$guid] = handler;
+		// assign a global event handler to do all the work
+		element["on" + type] = handleEvent;
+	}
+};
+// a counter used to create unique IDs
+dean_addEvent.guid = 1;
+
+function removeEvent(element, type, handler) {
+	if (element.removeEventListener) {
+		element.removeEventListener(type, handler, false);
+	} else {
+		// delete the event handler from the hash table
+		if (element.events && element.events[type]) {
+			delete element.events[type][handler.$$guid];
+		}
+	}
+};
+
+function handleEvent(event) {
+	var returnValue = true;
+	// grab the event object (IE uses a global event object)
+	event = event || fixEvent(((this.ownerDocument || this.document || this).parentWindow || window).event);
+	// get a reference to the hash table of event handlers
+	var handlers = this.events[event.type];
+	// execute each event handler
+	for (var i in handlers) {
+		this.$$handleEvent = handlers[i];
+		if (this.$$handleEvent(event) === false) {
+			returnValue = false;
+		}
+	}
+	return returnValue;
+};
+
+function fixEvent(event) {
+	// add W3C standard event methods
+	event.preventDefault = fixEvent.preventDefault;
+	event.stopPropagation = fixEvent.stopPropagation;
+	return event;
+};
+fixEvent.preventDefault = function() {
+	this.returnValue = false;
+};
+fixEvent.stopPropagation = function() {
+  this.cancelBubble = true;
+}
+
+// Dean's forEach: http://dean.edwards.name/base/forEach.js
+/*
+	forEach, version 1.0
+	Copyright 2006, Dean Edwards
+	License: http://www.opensource.org/licenses/mit-license.php
+*/
+
+// array-like enumeration
+if (!Array.forEach) { // mozilla already supports this
+	Array.forEach = function(array, block, context) {
+		for (var i = 0; i < array.length; i++) {
+			block.call(context, array[i], i, array);
+		}
+	};
+}
+
+// generic enumeration
+Function.prototype.forEach = function(object, block, context) {
+	for (var key in object) {
+		if (typeof this.prototype[key] == "undefined") {
+			block.call(context, object[key], key, object);
+		}
+	}
+};
+
+// character enumeration
+String.forEach = function(string, block, context) {
+	Array.forEach(string.split(""), function(chr, index) {
+		block.call(context, chr, index, string);
+	});
+};
+
+// globally resolve forEach enumeration
+var forEach = function(object, block, context) {
+	if (object) {
+		var resolve = Object; // default
+		if (object instanceof Function) {
+			// functions have a "length" property
+			resolve = Function;
+		} else if (object.forEach instanceof Function) {
+			// the object implements a custom forEach method so use that
+			object.forEach(block, context);
+			return;
+		} else if (typeof object == "string") {
+			// the object is a string
+			resolve = String;
+		} else if (typeof object.length == "number") {
+			// the object is array-like
+			resolve = Array;
+		}
+		resolve.forEach(object, block, context);
+	}
+};
+
diff --git a/tools/scan-view/Reporter.py b/tools/scan-view/Reporter.py
new file mode 100644
index 0000000..9560fc1
--- /dev/null
+++ b/tools/scan-view/Reporter.py
@@ -0,0 +1,248 @@
+"""Methods for reporting bugs."""
+
+import subprocess, sys, os
+
+__all__ = ['ReportFailure', 'BugReport', 'getReporters']
+
+#
+
+class ReportFailure(Exception):
+    """Generic exception for failures in bug reporting."""
+    def __init__(self, value):        
+        self.value = value
+
+# Collect information about a bug.
+
+class BugReport:
+    def __init__(self, title, description, files):
+        self.title = title
+        self.description = description
+        self.files = files
+
+# Reporter interfaces.
+
+import os
+
+import email, mimetypes, smtplib
+from email import encoders
+from email.message import Message
+from email.mime.base import MIMEBase
+from email.mime.multipart import MIMEMultipart
+from email.mime.text import MIMEText
+
+#===------------------------------------------------------------------------===#
+# ReporterParameter
+#===------------------------------------------------------------------------===#
+
+class ReporterParameter:
+  def __init__(self, n):
+    self.name = n
+  def getName(self):
+    return self.name
+  def getValue(self,r,bugtype,getConfigOption):
+     return getConfigOption(r.getName(),self.getName())
+  def saveConfigValue(self):
+    return True
+
+class TextParameter (ReporterParameter):
+  def getHTML(self,r,bugtype,getConfigOption):
+    return """\
+<tr>
+<td class="form_clabel">%s:</td>
+<td class="form_value"><input type="text" name="%s_%s" value="%s"></td>
+</tr>"""%(self.getName(),r.getName(),self.getName(),self.getValue(r,bugtype,getConfigOption))
+
+class SelectionParameter (ReporterParameter):
+  def __init__(self, n, values):
+    ReporterParameter.__init__(self,n)
+    self.values = values
+    
+  def getHTML(self,r,bugtype,getConfigOption):
+    default = self.getValue(r,bugtype,getConfigOption)
+    return """\
+<tr>
+<td class="form_clabel">%s:</td><td class="form_value"><select name="%s_%s">
+%s
+</select></td>"""%(self.getName(),r.getName(),self.getName(),'\n'.join(["""\
+<option value="%s"%s>%s</option>"""%(o[0],
+                                     o[0] == default and ' selected="selected"' or '',
+                                     o[1]) for o in self.values]))
+
+#===------------------------------------------------------------------------===#
+# Reporters
+#===------------------------------------------------------------------------===#
+
+class EmailReporter:
+    def getName(self):
+        return 'Email'
+
+    def getParameters(self):
+        return map(lambda x:TextParameter(x),['To', 'From', 'SMTP Server', 'SMTP Port'])
+
+    # Lifted from python email module examples.
+    def attachFile(self, outer, path):
+        # Guess the content type based on the file's extension.  Encoding
+        # will be ignored, although we should check for simple things like
+        # gzip'd or compressed files.
+        ctype, encoding = mimetypes.guess_type(path)
+        if ctype is None or encoding is not None:
+            # No guess could be made, or the file is encoded (compressed), so
+            # use a generic bag-of-bits type.
+            ctype = 'application/octet-stream'
+        maintype, subtype = ctype.split('/', 1)
+        if maintype == 'text':
+            fp = open(path)
+            # Note: we should handle calculating the charset
+            msg = MIMEText(fp.read(), _subtype=subtype)
+            fp.close()
+        else:
+            fp = open(path, 'rb')
+            msg = MIMEBase(maintype, subtype)
+            msg.set_payload(fp.read())
+            fp.close()
+            # Encode the payload using Base64
+            encoders.encode_base64(msg)
+        # Set the filename parameter
+        msg.add_header('Content-Disposition', 'attachment', filename=os.path.basename(path))
+        outer.attach(msg)
+
+    def fileReport(self, report, parameters):
+        mainMsg = """\
+BUG REPORT
+---
+Title: %s
+Description: %s
+"""%(report.title, report.description)
+
+        if not parameters.get('To'):
+            raise ReportFailure('No "To" address specified.')
+        if not parameters.get('From'):
+            raise ReportFailure('No "From" address specified.')
+
+        msg = MIMEMultipart()
+        msg['Subject'] = 'BUG REPORT: %s'%(report.title)
+        # FIXME: Get config parameters
+        msg['To'] = parameters.get('To')
+        msg['From'] = parameters.get('From')
+        msg.preamble = mainMsg
+
+        msg.attach(MIMEText(mainMsg, _subtype='text/plain'))
+        for file in report.files:
+            self.attachFile(msg, file)
+
+        try:
+            s = smtplib.SMTP(host=parameters.get('SMTP Server'),
+                             port=parameters.get('SMTP Port'))
+            s.sendmail(msg['From'], msg['To'], msg.as_string())
+            s.close()
+        except:
+            raise ReportFailure('Unable to send message via SMTP.')
+
+        return "Message sent!"
+
+class BugzillaReporter:
+    def getName(self):
+        return 'Bugzilla'
+    
+    def getParameters(self):
+        return map(lambda x:TextParameter(x),['URL','Product'])
+
+    def fileReport(self, report, parameters):
+        raise NotImplementedError
+ 
+
+class RadarClassificationParameter(SelectionParameter):
+  def __init__(self):
+    SelectionParameter.__init__(self,"Classification",
+            [['1', 'Security'], ['2', 'Crash/Hang/Data Loss'],
+             ['3', 'Performance'], ['4', 'UI/Usability'], 
+             ['6', 'Serious Bug'], ['7', 'Other']])
+
+  def saveConfigValue(self):
+    return False
+    
+  def getValue(self,r,bugtype,getConfigOption):
+    if bugtype.find("leak") != -1:
+      return '3'
+    elif bugtype.find("dereference") != -1:
+      return '2'
+    elif bugtype.find("missing ivar release") != -1:
+      return '3'
+    else:
+      return '7'
+
+class RadarReporter:
+    @staticmethod
+    def isAvailable():
+        # FIXME: Find this .scpt better
+        path = os.path.join(os.path.dirname(__file__),'Resources/GetRadarVersion.scpt')
+        try:
+          p = subprocess.Popen(['osascript',path], 
+          stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+        except:
+            return False
+        data,err = p.communicate()
+        res = p.wait()
+        # FIXME: Check version? Check for no errors?
+        return res == 0
+
+    def getName(self):
+        return 'Radar'
+
+    def getParameters(self):
+        return [ TextParameter('Component'), TextParameter('Component Version'),
+                 RadarClassificationParameter() ]
+
+    def fileReport(self, report, parameters):
+        component = parameters.get('Component', '')
+        componentVersion = parameters.get('Component Version', '')
+        classification = parameters.get('Classification', '')
+        personID = ""
+        diagnosis = ""
+        config = ""
+
+        if not component.strip():
+            component = 'Bugs found by clang Analyzer'
+        if not componentVersion.strip():
+            componentVersion = 'X'
+
+        script = os.path.join(os.path.dirname(__file__),'Resources/FileRadar.scpt')
+        args = ['osascript', script, component, componentVersion, classification, personID, report.title,
+                report.description, diagnosis, config] + map(os.path.abspath, report.files)
+#        print >>sys.stderr, args
+        try:
+          p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+        except:
+            raise ReportFailure("Unable to file radar (AppleScript failure).")
+        data, err = p.communicate()
+        res = p.wait()
+
+        if res:
+            raise ReportFailure("Unable to file radar (AppleScript failure).")
+
+        try:
+            values = eval(data)
+        except:
+            raise ReportFailure("Unable to process radar results.")
+
+        # We expect (int: bugID, str: message)
+        if len(values) != 2 or not isinstance(values[0], int):
+            raise ReportFailure("Unable to process radar results.")
+
+        bugID,message = values
+        bugID = int(bugID)
+        
+        if not bugID:
+            raise ReportFailure(message)
+        
+        return "Filed: <a href=\"rdar://%d/\">%d</a>"%(bugID,bugID)
+
+###
+
+def getReporters():
+    reporters = []
+    if RadarReporter.isAvailable():
+        reporters.append(RadarReporter())
+    reporters.append(EmailReporter())
+    return reporters
+
diff --git a/tools/scan-view/Resources/FileRadar.scpt b/tools/scan-view/Resources/FileRadar.scpt
new file mode 100644
index 0000000..1c74552
--- /dev/null
+++ b/tools/scan-view/Resources/FileRadar.scpt
Binary files differ
diff --git a/tools/scan-view/Resources/GetRadarVersion.scpt b/tools/scan-view/Resources/GetRadarVersion.scpt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tools/scan-view/Resources/GetRadarVersion.scpt
diff --git a/tools/scan-view/Resources/bugcatcher.ico b/tools/scan-view/Resources/bugcatcher.ico
new file mode 100644
index 0000000..22d39b5
--- /dev/null
+++ b/tools/scan-view/Resources/bugcatcher.ico
Binary files differ
diff --git a/tools/scan-view/ScanView.py b/tools/scan-view/ScanView.py
new file mode 100644
index 0000000..837adae
--- /dev/null
+++ b/tools/scan-view/ScanView.py
@@ -0,0 +1,770 @@
+import BaseHTTPServer
+import SimpleHTTPServer
+import os
+import sys
+import urllib, urlparse
+import posixpath
+import StringIO
+import re
+import shutil
+import threading
+import time
+import socket
+import itertools
+
+import Reporter
+import ConfigParser
+
+###
+# Various patterns matched or replaced by server.
+
+kReportFileRE = re.compile('(.*/)?report-(.*)\\.html')
+
+kBugKeyValueRE = re.compile('<!-- BUG([^ ]*) (.*) -->')
+
+#  <!-- REPORTPROBLEM file="crashes/clang_crash_ndSGF9.mi" stderr="crashes/clang_crash_ndSGF9.mi.stderr.txt" info="crashes/clang_crash_ndSGF9.mi.info" -->
+
+kReportCrashEntryRE = re.compile('<!-- REPORTPROBLEM (.*?)-->')
+kReportCrashEntryKeyValueRE = re.compile(' ?([^=]+)="(.*?)"')
+
+kReportReplacements = []
+
+# Add custom javascript.
+kReportReplacements.append((re.compile('<!-- SUMMARYENDHEAD -->'), """\
+<script language="javascript" type="text/javascript">
+function load(url) {
+  if (window.XMLHttpRequest) {
+    req = new XMLHttpRequest();
+  } else if (window.ActiveXObject) {
+    req = new ActiveXObject("Microsoft.XMLHTTP");
+  }
+  if (req != undefined) {
+    req.open("GET", url, true);
+    req.send("");
+  }
+}
+</script>"""))
+
+# Insert additional columns.
+kReportReplacements.append((re.compile('<!-- REPORTBUGCOL -->'), 
+                            '<td></td><td></td>'))
+
+# Insert report bug and open file links.
+kReportReplacements.append((re.compile('<!-- REPORTBUG id="report-(.*)\\.html" -->'),
+                            ('<td class="Button"><a href="report/\\1">Report Bug</a></td>' + 
+                             '<td class="Button"><a href="javascript:load(\'open/\\1\')">Open File</a></td>')))
+
+kReportReplacements.append((re.compile('<!-- REPORTHEADER -->'),
+                                       '<h3><a href="/">Summary</a> > Report %(report)s</h3>'))
+
+kReportReplacements.append((re.compile('<!-- REPORTSUMMARYEXTRA -->'),
+                            '<td class="Button"><a href="report/%(report)s">Report Bug</a></td>'))
+
+# Insert report crashes link.
+
+# Disabled for the time being until we decide exactly when this should
+# be enabled. Also the radar reporter needs to be fixed to report
+# multiple files.
+
+#kReportReplacements.append((re.compile('<!-- REPORTCRASHES -->'),
+#                            '<br>These files will automatically be attached to ' +
+#                            'reports filed here: <a href="report_crashes">Report Crashes</a>.'))
+
+###
+# Other simple parameters
+
+kResources = posixpath.join(posixpath.dirname(__file__), 'Resources')
+kConfigPath = os.path.expanduser('~/.scanview.cfg')
+
+###
+
+__version__ = "0.1"
+
+__all__ = ["create_server"]
+
+class ReporterThread(threading.Thread):
+    def __init__(self, report, reporter, parameters, server):
+        threading.Thread.__init__(self)
+        self.report = report
+        self.server = server
+        self.reporter = reporter
+        self.parameters = parameters
+        self.success = False
+        self.status = None
+
+    def run(self):
+        result = None
+        try:
+            if self.server.options.debug:
+                print >>sys.stderr, "%s: SERVER: submitting bug."%(sys.argv[0],)
+            self.status = self.reporter.fileReport(self.report, self.parameters)
+            self.success = True
+            time.sleep(3)
+            if self.server.options.debug:
+                print >>sys.stderr, "%s: SERVER: submission complete."%(sys.argv[0],)
+        except Reporter.ReportFailure,e:
+            self.status = e.value
+        except Exception,e:
+            s = StringIO.StringIO()
+            import traceback
+            print >>s,'<b>Unhandled Exception</b><br><pre>'
+            traceback.print_exc(e,file=s)
+            print >>s,'</pre>'
+            self.status = s.getvalue()
+
+class ScanViewServer(BaseHTTPServer.HTTPServer):
+    def __init__(self, address, handler, root, reporters, options):
+        BaseHTTPServer.HTTPServer.__init__(self, address, handler)
+        self.root = root
+        self.reporters = reporters
+        self.options = options        
+        self.halted = False
+        self.config = None
+        self.load_config()
+
+    def load_config(self):
+        self.config = ConfigParser.RawConfigParser()
+
+        # Add defaults
+        self.config.add_section('ScanView')
+        for r in self.reporters:
+            self.config.add_section(r.getName())
+            for p in r.getParameters():
+              if p.saveConfigValue():
+                self.config.set(r.getName(), p.getName(), '')
+
+        # Ignore parse errors
+        try:
+            self.config.read([kConfigPath])
+        except:
+            pass
+
+        # Save on exit
+        import atexit
+        atexit.register(lambda: self.save_config())
+        
+    def save_config(self):
+        # Ignore errors (only called on exit).
+        try:
+            f = open(kConfigPath,'w')
+            self.config.write(f)
+            f.close()
+        except:
+            pass
+        
+    def halt(self):
+        self.halted = True
+        if self.options.debug:
+            print >>sys.stderr, "%s: SERVER: halting." % (sys.argv[0],)
+
+    def serve_forever(self):
+        while not self.halted:
+            if self.options.debug > 1:
+                print >>sys.stderr, "%s: SERVER: waiting..." % (sys.argv[0],)
+            try:
+                self.handle_request()
+            except OSError,e:
+                print 'OSError',e.errno
+
+    def finish_request(self, request, client_address):
+        if self.options.autoReload:
+            import ScanView
+            self.RequestHandlerClass = reload(ScanView).ScanViewRequestHandler
+        BaseHTTPServer.HTTPServer.finish_request(self, request, client_address)
+
+    def handle_error(self, request, client_address):
+        # Ignore socket errors
+        info = sys.exc_info()
+        if info and isinstance(info[1], socket.error):
+            if self.options.debug > 1:
+                print >>sys.stderr, "%s: SERVER: ignored socket error." % (sys.argv[0],)
+            return
+        BaseHTTPServer.HTTPServer.handle_error(self, request, client_address)
+
+# Borrowed from Quixote, with simplifications.
+def parse_query(qs, fields=None):
+    if fields is None:
+        fields = {}
+    for chunk in filter(None, qs.split('&')):
+        if '=' not in chunk:
+            name = chunk
+            value = ''
+        else:
+            name, value = chunk.split('=', 1)
+        name = urllib.unquote(name.replace('+', ' '))
+        value = urllib.unquote(value.replace('+', ' '))
+        item = fields.get(name)
+        if item is None:
+            fields[name] = [value]
+        else:
+            item.append(value)
+    return fields
+
+class ScanViewRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
+    server_version = "ScanViewServer/" + __version__
+    dynamic_mtime = time.time()
+
+    def do_HEAD(self):
+        try:
+            SimpleHTTPServer.SimpleHTTPRequestHandler.do_HEAD(self)
+        except Exception,e:
+            self.handle_exception(e)
+            
+    def do_GET(self):
+        try:
+            SimpleHTTPServer.SimpleHTTPRequestHandler.do_GET(self)
+        except Exception,e:
+            self.handle_exception(e)
+            
+    def do_POST(self):
+        """Serve a POST request."""
+        try:
+            length = self.headers.getheader('content-length') or "0"
+            try:
+                length = int(length)
+            except:
+                length = 0
+            content = self.rfile.read(length)
+            fields = parse_query(content)
+            f = self.send_head(fields)
+            if f:
+                self.copyfile(f, self.wfile)
+                f.close()
+        except Exception,e:
+            self.handle_exception(e)            
+
+    def log_message(self, format, *args):
+        if self.server.options.debug:
+            sys.stderr.write("%s: SERVER: %s - - [%s] %s\n" %
+                             (sys.argv[0],
+                              self.address_string(),
+                              self.log_date_time_string(),
+                              format%args))
+
+    def load_report(self, report):
+        path = os.path.join(self.server.root, 'report-%s.html'%report)
+        data = open(path).read()
+        keys = {}
+        for item in kBugKeyValueRE.finditer(data):
+            k,v = item.groups()
+            keys[k] = v
+        return keys
+
+    def load_crashes(self):
+        path = posixpath.join(self.server.root, 'index.html')
+        data = open(path).read()
+        problems = []
+        for item in kReportCrashEntryRE.finditer(data):
+            fieldData = item.group(1)
+            fields = dict([i.groups() for i in 
+                           kReportCrashEntryKeyValueRE.finditer(fieldData)])
+            problems.append(fields)
+        return problems
+
+    def handle_exception(self, exc):
+        import traceback
+        s = StringIO.StringIO()
+        print >>s, "INTERNAL ERROR\n"
+        traceback.print_exc(exc, s)
+        f = self.send_string(s.getvalue(), 'text/plain')
+        if f:
+            self.copyfile(f, self.wfile)
+            f.close()        
+            
+    def get_scalar_field(self, name):
+        if name in self.fields:
+            return self.fields[name][0]
+        else:
+            return None
+
+    def submit_bug(self, c):
+        title = self.get_scalar_field('title')
+        description = self.get_scalar_field('description')
+        report = self.get_scalar_field('report')
+        reporterIndex = self.get_scalar_field('reporter')
+        files = []
+        for fileID in self.fields.get('files',[]):
+            try:
+                i = int(fileID)
+            except:
+                i = None
+            if i is None or i<0 or i>=len(c.files):
+                return (False, 'Invalid file ID')
+            files.append(c.files[i])
+        
+        if not title:
+            return (False, "Missing title.")
+        if not description:
+            return (False, "Missing description.")
+        try:
+            reporterIndex = int(reporterIndex)
+        except:
+            return (False, "Invalid report method.")
+        
+        # Get the reporter and parameters.
+        reporter = self.server.reporters[reporterIndex]
+        parameters = {}
+        for o in reporter.getParameters():
+            name = '%s_%s'%(reporter.getName(),o.getName())
+            if name not in self.fields:
+                return (False, 
+                        'Missing field "%s" for %s report method.'%(name,
+                                                                    reporter.getName()))
+            parameters[o.getName()] = self.get_scalar_field(name)
+
+        # Update config defaults.
+        if report != 'None':
+            self.server.config.set('ScanView', 'reporter', reporterIndex)
+            for o in reporter.getParameters():
+              if o.saveConfigValue():
+                name = o.getName()
+                self.server.config.set(reporter.getName(), name, parameters[name])
+
+        # Create the report.
+        bug = Reporter.BugReport(title, description, files)
+
+        # Kick off a reporting thread.
+        t = ReporterThread(bug, reporter, parameters, self.server)
+        t.start()
+
+        # Wait for thread to die...
+        while t.isAlive():
+            time.sleep(.25)
+        submitStatus = t.status
+
+        return (t.success, t.status)
+
+    def send_report_submit(self):
+        report = self.get_scalar_field('report')
+        c = self.get_report_context(report)
+        if c.reportSource is None:
+            reportingFor = "Report Crashes > "
+            fileBug = """\
+<a href="/report_crashes">File Bug</a> > """%locals()
+        else:
+            reportingFor = '<a href="/%s">Report %s</a> > ' % (c.reportSource, 
+                                                                   report)
+            fileBug = '<a href="/report/%s">File Bug</a> > ' % report
+        title = self.get_scalar_field('title')
+        description = self.get_scalar_field('description')
+
+        res,message = self.submit_bug(c)
+
+        if res:
+            statusClass = 'SubmitOk'
+            statusName = 'Succeeded'
+        else:
+            statusClass = 'SubmitFail'
+            statusName = 'Failed'
+
+        result = """
+<head>
+  <title>Bug Submission</title>
+  <link rel="stylesheet" type="text/css" href="/scanview.css" />
+</head>
+<body>
+<h3>
+<a href="/">Summary</a> > 
+%(reportingFor)s
+%(fileBug)s
+Submit</h3>
+<form name="form" action="">
+<table class="form">
+<tr><td>
+<table class="form_group">
+<tr>
+  <td class="form_clabel">Title:</td>
+  <td class="form_value">
+    <input type="text" name="title" size="50" value="%(title)s" disabled>
+  </td>
+</tr>
+<tr>
+  <td class="form_label">Description:</td>
+  <td class="form_value">
+<textarea rows="10" cols="80" name="description" disabled>
+%(description)s
+</textarea>
+  </td>
+</table>
+</td></tr>
+</table>
+</form>
+<h1 class="%(statusClass)s">Submission %(statusName)s</h1>
+%(message)s
+<p>
+<hr>
+<a href="/">Return to Summary</a>
+</body>
+</html>"""%locals()
+        return self.send_string(result)
+
+    def send_open_report(self, report):
+        try:
+            keys = self.load_report(report)
+        except IOError:
+            return self.send_error(400, 'Invalid report.')
+
+        file = keys.get('FILE')
+        if not file or not posixpath.exists(file):
+            return self.send_error(400, 'File does not exist: "%s"' % file)
+
+        import startfile
+        if self.server.options.debug:
+            print >>sys.stderr, '%s: SERVER: opening "%s"'%(sys.argv[0],
+                                                            file)
+
+        status = startfile.open(file)
+        if status:
+            res = 'Opened: "%s"' % file
+        else:
+            res = 'Open failed: "%s"' % file
+
+        return self.send_string(res, 'text/plain')
+
+    def get_report_context(self, report):
+        class Context:
+            pass
+        if report is None or report == 'None':
+            data = self.load_crashes()
+            # Don't allow empty reports.
+            if not data:
+                raise ValueError, 'No crashes detected!'
+            c = Context()
+            c.title = 'clang static analyzer failures'
+
+            stderrSummary = ""
+            for item in data:
+                if 'stderr' in item:
+                    path = posixpath.join(self.server.root, item['stderr'])
+                    if os.path.exists(path):
+                        lns = itertools.islice(open(path), 0, 10)
+                        stderrSummary += '%s\n--\n%s' % (item.get('src', 
+                                                                  '<unknown>'),
+                                                         ''.join(lns))
+
+            c.description = """\
+The clang static analyzer failed on these inputs:
+%s
+
+STDERR Summary
+--------------
+%s
+""" % ('\n'.join([item.get('src','<unknown>') for item in data]),
+       stderrSummary)
+            c.reportSource = None
+            c.navMarkup = "Report Crashes > "
+            c.files = []
+            for item in data:                
+                c.files.append(item.get('src',''))
+                c.files.append(posixpath.join(self.server.root,
+                                              item.get('file','')))
+                c.files.append(posixpath.join(self.server.root,
+                                              item.get('clangfile','')))
+                c.files.append(posixpath.join(self.server.root,
+                                              item.get('stderr','')))
+                c.files.append(posixpath.join(self.server.root,
+                                              item.get('info','')))
+            # Just in case something failed, ignore files which don't
+            # exist.
+            c.files = [f for f in c.files
+                       if os.path.exists(f) and os.path.isfile(f)]
+        else:
+            # Check that this is a valid report.            
+            path = posixpath.join(self.server.root, 'report-%s.html' % report)
+            if not posixpath.exists(path):
+                raise ValueError, 'Invalid report ID'
+            keys = self.load_report(report)
+            c = Context()
+            c.title = keys.get('DESC','clang error (unrecognized')
+            c.description = """\
+Bug reported by the clang static analyzer.
+
+Description: %s
+File: %s
+Line: %s
+"""%(c.title, keys.get('FILE','<unknown>'), keys.get('LINE', '<unknown>'))
+            c.reportSource = 'report-%s.html' % report
+            c.navMarkup = """<a href="/%s">Report %s</a> > """ % (c.reportSource,
+                                                                  report)
+
+            c.files = [path]
+        return c
+
+    def send_report(self, report, configOverrides=None):
+        def getConfigOption(section, field):            
+            if (configOverrides is not None and
+                section in configOverrides and
+                field in configOverrides[section]):
+                return configOverrides[section][field]
+            return self.server.config.get(section, field)
+
+        # report is None is used for crashes
+        try:
+            c = self.get_report_context(report)
+        except ValueError, e:
+            return self.send_error(400, e.message)
+
+        title = c.title
+        description= c.description
+        reportingFor = c.navMarkup
+        if c.reportSource is None:
+            extraIFrame = ""
+        else:
+            extraIFrame = """\
+<iframe src="/%s" width="100%%" height="40%%"
+        scrolling="auto" frameborder="1">
+  <a href="/%s">View Bug Report</a>
+</iframe>""" % (c.reportSource, c.reportSource)
+
+        reporterSelections = []
+        reporterOptions = []
+
+        try:
+            active = int(getConfigOption('ScanView','reporter'))
+        except:
+            active = 0
+        for i,r in enumerate(self.server.reporters):
+            selected = (i == active)
+            if selected:
+                selectedStr = ' selected'
+            else:
+                selectedStr = ''
+            reporterSelections.append('<option value="%d"%s>%s</option>'%(i,selectedStr,r.getName()))
+            options = '\n'.join([ o.getHTML(r,title,getConfigOption) for o in r.getParameters()])
+            display = ('none','')[selected]
+            reporterOptions.append("""\
+<tr id="%sReporterOptions" style="display:%s">
+  <td class="form_label">%s Options</td>
+  <td class="form_value">
+    <table class="form_inner_group">
+%s
+    </table>
+  </td>
+</tr>
+"""%(r.getName(),display,r.getName(),options))
+        reporterSelections = '\n'.join(reporterSelections)
+        reporterOptionsDivs = '\n'.join(reporterOptions)
+        reportersArray = '[%s]'%(','.join([`r.getName()` for r in self.server.reporters]))
+
+        if c.files:
+            fieldSize = min(5, len(c.files))
+            attachFileOptions = '\n'.join(["""\
+<option value="%d" selected>%s</option>""" % (i,v) for i,v in enumerate(c.files)])
+            attachFileRow = """\
+<tr>
+  <td class="form_label">Attach:</td>
+  <td class="form_value">
+<select style="width:100%%" name="files" multiple size=%d>
+%s
+</select>
+  </td>
+</tr>
+""" % (min(5, len(c.files)), attachFileOptions)
+        else:
+            attachFileRow = ""
+
+        result = """<html>
+<head>
+  <title>File Bug</title>
+  <link rel="stylesheet" type="text/css" href="/scanview.css" />
+</head>
+<script language="javascript" type="text/javascript">
+var reporters = %(reportersArray)s;
+function updateReporterOptions() {
+  index = document.getElementById('reporter').selectedIndex;
+  for (var i=0; i < reporters.length; ++i) {
+    o = document.getElementById(reporters[i] + "ReporterOptions");
+    if (i == index) {
+      o.style.display = "";
+    } else {
+      o.style.display = "none";
+    }
+  }
+}
+</script>
+<body onLoad="updateReporterOptions()">
+<h3>
+<a href="/">Summary</a> > 
+%(reportingFor)s
+File Bug</h3>
+<form name="form" action="/report_submit" method="post">
+<input type="hidden" name="report" value="%(report)s">
+
+<table class="form">
+<tr><td>
+<table class="form_group">
+<tr>
+  <td class="form_clabel">Title:</td>
+  <td class="form_value">
+    <input type="text" name="title" size="50" value="%(title)s">
+  </td>
+</tr>
+<tr>
+  <td class="form_label">Description:</td>
+  <td class="form_value">
+<textarea rows="10" cols="80" name="description">
+%(description)s
+</textarea>
+  </td>
+</tr>
+
+%(attachFileRow)s
+
+</table>
+<br>
+<table class="form_group">
+<tr>
+  <td class="form_clabel">Method:</td>
+  <td class="form_value">
+    <select id="reporter" name="reporter" onChange="updateReporterOptions()">
+    %(reporterSelections)s
+    </select>
+  </td>
+</tr>
+%(reporterOptionsDivs)s
+</table>
+<br>
+</td></tr>
+<tr><td class="form_submit">
+  <input align="right" type="submit" name="Submit" value="Submit">
+</td></tr>
+</table>
+</form>
+
+%(extraIFrame)s
+
+</body>
+</html>"""%locals()
+
+        return self.send_string(result)
+
+    def send_head(self, fields=None):
+        if (self.server.options.onlyServeLocal and
+            self.client_address[0] != '127.0.0.1'):
+            return self.send_error('401', 'Unauthorized host.')
+
+        if fields is None:
+            fields = {}
+        self.fields = fields
+
+        o = urlparse.urlparse(self.path)
+        self.fields = parse_query(o.query, fields)
+        path = posixpath.normpath(urllib.unquote(o.path))
+
+        # Split the components and strip the root prefix.
+        components = path.split('/')[1:]
+        
+        # Special case some top-level entries.
+        if components:
+            name = components[0]
+            if len(components)==2:
+                if name=='report':
+                    return self.send_report(components[1])
+                elif name=='open':
+                    return self.send_open_report(components[1])
+            elif len(components)==1:
+                if name=='quit':
+                    self.server.halt()
+                    return self.send_string('Goodbye.', 'text/plain')
+                elif name=='report_submit':
+                    return self.send_report_submit()
+                elif name=='report_crashes':
+                    overrides = { 'ScanView' : {},
+                                  'Radar' : {},
+                                  'Email' : {} }
+                    for i,r in enumerate(self.server.reporters):
+                        if r.getName() == 'Radar':
+                            overrides['ScanView']['reporter'] = i
+                            break
+                    overrides['Radar']['Component'] = 'llvm - checker'
+                    overrides['Radar']['Component Version'] = 'X'
+                    return self.send_report(None, overrides)
+                elif name=='favicon.ico':
+                    return self.send_path(posixpath.join(kResources,'bugcatcher.ico'))
+        
+        # Match directory entries.
+        if components[-1] == '':
+            components[-1] = 'index.html'
+
+        suffix = '/'.join(components)
+
+        # The summary may reference source files on disk using rooted
+        # paths. Make sure these resolve correctly for now.
+        # FIXME: This isn't a very good idea... we should probably
+        # mark rooted paths somehow.        
+        if os.path.exists(posixpath.join('/', suffix)):
+            path = posixpath.join('/', suffix)
+        else:
+            path = posixpath.join(self.server.root, suffix)
+
+        if self.server.options.debug > 1:
+            print >>sys.stderr, '%s: SERVER: sending path "%s"'%(sys.argv[0],
+                                                                 path)
+        return self.send_path(path)
+
+    def send_404(self):
+        self.send_error(404, "File not found")
+        return None
+
+    def send_path(self, path):
+        ctype = self.guess_type(path)
+        if ctype.startswith('text/'):
+            # Patch file instead
+            return self.send_patched_file(path, ctype)
+        else:
+            mode = 'rb'
+        try:
+            f = open(path, mode)
+        except IOError:
+            return self.send_404()
+        return self.send_file(f, ctype)
+
+    def send_file(self, f, ctype):
+        # Patch files to add links, but skip binary files.
+        self.send_response(200)
+        self.send_header("Content-type", ctype)
+        fs = os.fstat(f.fileno())
+        self.send_header("Content-Length", str(fs[6]))
+        self.send_header("Last-Modified", self.date_time_string(fs.st_mtime))
+        self.end_headers()
+        return f
+
+    def send_string(self, s, ctype='text/html', headers=True, mtime=None):
+        if headers:
+            self.send_response(200)
+            self.send_header("Content-type", ctype)
+            self.send_header("Content-Length", str(len(s)))
+            if mtime is None:
+                mtime = self.dynamic_mtime
+            self.send_header("Last-Modified", self.date_time_string(mtime))
+            self.end_headers()
+        return StringIO.StringIO(s)
+
+    def send_patched_file(self, path, ctype):
+        # Allow a very limited set of variables. This is pretty gross.
+        variables = {}
+        variables['report'] = ''
+        m = kReportFileRE.match(path)
+        if m:
+            variables['report'] = m.group(2)
+
+        try:
+            f = open(path,'r')
+        except IOError:
+            return self.send_404()
+        fs = os.fstat(f.fileno())
+        data = f.read()
+        for a,b in kReportReplacements:
+            data = a.sub(b % variables, data)
+        return self.send_string(data, ctype, mtime=fs.st_mtime)
+
+
+def create_server(address, options, root):
+    import Reporter
+
+    reporters = Reporter.getReporters()
+
+    return ScanViewServer(address, ScanViewRequestHandler,
+                          root,
+                          reporters,
+                          options)
diff --git a/tools/scan-view/scan-view b/tools/scan-view/scan-view
new file mode 100755
index 0000000..fb27da6
--- /dev/null
+++ b/tools/scan-view/scan-view
@@ -0,0 +1,131 @@
+#!/usr/bin/env python
+
+"""The clang static analyzer results viewer.
+"""
+
+import sys
+import posixpath
+import thread
+import time
+import urllib
+import webbrowser
+
+# How long to wait for server to start.
+kSleepTimeout = .05
+kMaxSleeps = int(60 / kSleepTimeout)
+
+# Default server parameters
+
+kDefaultHost = '127.0.0.1'
+kDefaultPort = 8181
+kMaxPortsToTry = 100
+
+###
+
+def url_is_up(url):
+    try:
+        o = urllib.urlopen(url)
+    except IOError:
+        return False
+    o.close()
+    return True
+
+def start_browser(port, options):
+    import urllib, webbrowser
+
+    url = 'http://%s:%d'%(options.host, port)
+    
+    # Wait for server to start...
+    if options.debug:
+        sys.stderr.write('%s: Waiting for server.' % sys.argv[0])
+        sys.stderr.flush()
+    for i in range(kMaxSleeps):
+        if url_is_up(url):
+            break
+        if options.debug:
+            sys.stderr.write('.')
+            sys.stderr.flush()
+        time.sleep(kSleepTimeout)
+    else:
+        print >>sys.stderr,'WARNING: Unable to detect that server started.'
+
+    if options.debug:
+        print >>sys.stderr,'%s: Starting webbrowser...' % sys.argv[0]
+    webbrowser.open(url)
+
+def run(port, options, root):
+    import ScanView
+    try:
+        print 'Starting scan-view at: http://%s:%d'%(options.host,
+                                                     port)
+        print '  Use Ctrl-C to exit.'
+        httpd = ScanView.create_server((options.host, port),
+                                       options, root)
+        httpd.serve_forever()
+    except KeyboardInterrupt:
+        pass
+
+def port_is_open(port):
+    import SocketServer
+    try:
+        t = SocketServer.TCPServer((kDefaultHost,port),None)
+    except:
+        return False
+    t.server_close()
+    return True
+
+def main():    
+    from optparse import OptionParser
+    parser = OptionParser('usage: %prog [options] <results directory>')
+    parser.set_description(__doc__)
+    parser.add_option(
+        '--host', dest="host", default=kDefaultHost, type="string",
+        help="Host interface to listen on. (default=%s)" % kDefaultHost)
+    parser.add_option(
+        '--port', dest="port", default=None, type="int",
+        help="Port to listen on. (default=%s)" % kDefaultPort)
+    parser.add_option("--debug", dest="debug", default=0, 
+                      action="count",
+                      help="Print additional debugging information.")
+    parser.add_option("--auto-reload", dest="autoReload", default=False, 
+                      action="store_true",
+                      help="Automatically update module for each request.")
+    parser.add_option("--no-browser", dest="startBrowser", default=True, 
+                      action="store_false",
+                      help="Don't open a webbrowser on startup.")
+    parser.add_option("--allow-all-hosts", dest="onlyServeLocal", default=True, 
+                      action="store_false",
+                      help='Allow connections from any host (access restricted to "127.0.0.1" by default)')
+    (options, args) = parser.parse_args()
+
+    if len(args) != 1:
+        parser.error('No results directory specified.')
+    root, = args
+
+    # Make sure this directory is in a reasonable state to view.
+    if not posixpath.exists(posixpath.join(root,'index.html')):
+        parser.error('Invalid directory, analysis results not found!')
+
+    # Find an open port. We aren't particularly worried about race
+    # conditions here. Note that if the user specified a port we only
+    # use that one.
+    if options.port is not None:
+        port = options.port
+    else:    
+        for i in range(kMaxPortsToTry):
+            if port_is_open(kDefaultPort + i):
+                port = kDefaultPort + i
+                break
+        else:
+            parser.error('Unable to find usable port in [%d,%d)'%(kDefaultPort,
+                                                                  kDefaultPort+kMaxPortsToTry))
+
+    # Kick off thread to wait for server and start web browser, if
+    # requested.
+    if options.startBrowser:
+        t = thread.start_new_thread(start_browser, (port,options))
+
+    run(port, options, root)
+
+if __name__ == '__main__':
+    main()
diff --git a/tools/scan-view/startfile.py b/tools/scan-view/startfile.py
new file mode 100644
index 0000000..e8fbe2d
--- /dev/null
+++ b/tools/scan-view/startfile.py
@@ -0,0 +1,203 @@
+"""Utility for opening a file using the default application in a cross-platform
+manner. Modified from http://code.activestate.com/recipes/511443/.
+"""
+
+__version__ = '1.1x'
+__all__ = ['open']
+
+import os
+import sys
+import webbrowser
+import subprocess
+
+_controllers = {}
+_open = None
+
+
+class BaseController(object):
+    '''Base class for open program controllers.'''
+
+    def __init__(self, name):
+        self.name = name
+
+    def open(self, filename):
+        raise NotImplementedError
+
+
+class Controller(BaseController):
+    '''Controller for a generic open program.'''
+
+    def __init__(self, *args):
+        super(Controller, self).__init__(os.path.basename(args[0]))
+        self.args = list(args)
+
+    def _invoke(self, cmdline):
+        if sys.platform[:3] == 'win':
+            closefds = False
+            startupinfo = subprocess.STARTUPINFO()
+            startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
+        else:
+            closefds = True
+            startupinfo = None
+
+        if (os.environ.get('DISPLAY') or sys.platform[:3] == 'win' or
+                                                    sys.platform == 'darwin'):
+            inout = file(os.devnull, 'r+')
+        else:
+            # for TTY programs, we need stdin/out
+            inout = None
+
+        # if possible, put the child precess in separate process group,
+        # so keyboard interrupts don't affect child precess as well as
+        # Python
+        setsid = getattr(os, 'setsid', None)
+        if not setsid:
+            setsid = getattr(os, 'setpgrp', None)
+
+        pipe = subprocess.Popen(cmdline, stdin=inout, stdout=inout,
+                                stderr=inout, close_fds=closefds,
+                                preexec_fn=setsid, startupinfo=startupinfo)
+
+        # It is assumed that this kind of tools (gnome-open, kfmclient,
+        # exo-open, xdg-open and open for OSX) immediately exit after lauching
+        # the specific application
+        returncode = pipe.wait()
+        if hasattr(self, 'fixreturncode'):
+            returncode = self.fixreturncode(returncode)
+        return not returncode
+
+    def open(self, filename):
+        if isinstance(filename, basestring):
+            cmdline = self.args + [filename]
+        else:
+            # assume it is a sequence
+            cmdline = self.args + filename
+        try:
+            return self._invoke(cmdline)
+        except OSError:
+            return False
+
+
+# Platform support for Windows
+if sys.platform[:3] == 'win':
+
+    class Start(BaseController):
+        '''Controller for the win32 start progam through os.startfile.'''
+
+        def open(self, filename):
+            try:
+                os.startfile(filename)
+            except WindowsError:
+                # [Error 22] No application is associated with the specified
+                # file for this operation: '<URL>'
+                return False
+            else:
+                return True
+
+    _controllers['windows-default'] = Start('start')
+    _open = _controllers['windows-default'].open
+
+
+# Platform support for MacOS
+elif sys.platform == 'darwin':
+    _controllers['open']= Controller('open')
+    _open = _controllers['open'].open
+
+
+# Platform support for Unix
+else:
+
+    import commands
+
+    # @WARNING: use the private API of the webbrowser module
+    from webbrowser import _iscommand
+
+    class KfmClient(Controller):
+        '''Controller for the KDE kfmclient program.'''
+
+        def __init__(self, kfmclient='kfmclient'):
+            super(KfmClient, self).__init__(kfmclient, 'exec')
+            self.kde_version = self.detect_kde_version()
+
+        def detect_kde_version(self):
+            kde_version = None
+            try:
+                info = commands.getoutput('kde-config --version')
+
+                for line in info.splitlines():
+                    if line.startswith('KDE'):
+                        kde_version = line.split(':')[-1].strip()
+                        break
+            except (OSError, RuntimeError):
+                pass
+
+            return kde_version
+
+        def fixreturncode(self, returncode):
+            if returncode is not None and self.kde_version > '3.5.4':
+                return returncode
+            else:
+                return os.EX_OK
+
+    def detect_desktop_environment():
+        '''Checks for known desktop environments
+
+        Return the desktop environments name, lowercase (kde, gnome, xfce)
+        or "generic"
+
+        '''
+
+        desktop_environment = 'generic'
+
+        if os.environ.get('KDE_FULL_SESSION') == 'true':
+            desktop_environment = 'kde'
+        elif os.environ.get('GNOME_DESKTOP_SESSION_ID'):
+            desktop_environment = 'gnome'
+        else:
+            try:
+                info = commands.getoutput('xprop -root _DT_SAVE_MODE')
+                if ' = "xfce4"' in info:
+                    desktop_environment = 'xfce'
+            except (OSError, RuntimeError):
+                pass
+
+        return desktop_environment
+
+
+    def register_X_controllers():
+        if _iscommand('kfmclient'):
+            _controllers['kde-open'] = KfmClient()
+
+        for command in ('gnome-open', 'exo-open', 'xdg-open'):
+            if _iscommand(command):
+                _controllers[command] = Controller(command)
+
+    def get():
+        controllers_map = {
+            'gnome': 'gnome-open',
+            'kde': 'kde-open',
+            'xfce': 'exo-open',
+        }
+
+        desktop_environment = detect_desktop_environment()
+
+        try:
+            controller_name = controllers_map[desktop_environment]
+            return _controllers[controller_name].open
+
+        except KeyError:
+            if _controllers.has_key('xdg-open'):
+                return _controllers['xdg-open'].open
+            else:
+                return webbrowser.open
+
+
+    if os.environ.get("DISPLAY"):
+        register_X_controllers()
+    _open = get()
+
+
+def open(filename):
+    '''Open a file or an URL in the registered default application.'''
+
+    return _open(filename)
diff --git a/utils/ABITest/ABITestGen.py b/utils/ABITest/ABITestGen.py
new file mode 100755
index 0000000..c45a0c3
--- /dev/null
+++ b/utils/ABITest/ABITestGen.py
@@ -0,0 +1,653 @@
+#!/usr/bin/env python
+
+from pprint import pprint
+import random, atexit, time
+from random import randrange
+import re
+
+from Enumeration import *
+from TypeGen import *
+
+####
+
+class TypePrinter:
+    def __init__(self, output, outputHeader=None, 
+                 outputTests=None, outputDriver=None,
+                 headerName=None, info=None):
+        self.output = output
+        self.outputHeader = outputHeader
+        self.outputTests = outputTests
+        self.outputDriver = outputDriver
+        self.writeBody = outputHeader or outputTests or outputDriver
+        self.types = {}
+        self.testValues = {}
+        self.testReturnValues = {}
+        self.layoutTests = []
+
+        if info:
+            for f in (self.output,self.outputHeader,self.outputTests,self.outputDriver):
+                if f:
+                    print >>f,info
+
+        if self.writeBody:
+            print >>self.output, '#include <stdio.h>\n'
+            if self.outputTests:
+                print >>self.outputTests, '#include <stdio.h>'
+                print >>self.outputTests, '#include <string.h>'
+                print >>self.outputTests, '#include <assert.h>\n'
+
+        if headerName:
+            for f in (self.output,self.outputTests,self.outputDriver):
+                if f is not None:
+                    print >>f, '#include "%s"\n'%(headerName,)
+        
+        if self.outputDriver:
+            print >>self.outputDriver, '#include <stdio.h>'
+            print >>self.outputDriver, '#include <stdlib.h>\n'
+            print >>self.outputDriver, 'int main(int argc, char **argv) {'
+            print >>self.outputDriver, '  int index = -1;'
+            print >>self.outputDriver, '  if (argc > 1) index = atoi(argv[1]);'
+            
+    def finish(self):
+        if self.layoutTests:
+            print >>self.output, 'int main(int argc, char **argv) {'
+            print >>self.output, '  int index = -1;'
+            print >>self.output, '  if (argc > 1) index = atoi(argv[1]);'
+            for i,f in self.layoutTests:
+                print >>self.output, '  if (index == -1 || index == %d)' % i
+                print >>self.output, '    %s();' % f
+            print >>self.output, '  return 0;'
+            print >>self.output, '}' 
+
+        if self.outputDriver:
+            print >>self.outputDriver, '  printf("DONE\\n");'
+            print >>self.outputDriver, '  return 0;'
+            print >>self.outputDriver, '}'        
+
+    def getTypeName(self, T):
+        if isinstance(T,BuiltinType):
+            return T.name
+        name = self.types.get(T)
+        if name is None:            
+            name = 'T%d'%(len(self.types),)
+            # Reserve slot
+            self.types[T] = None
+            if self.outputHeader:
+                print >>self.outputHeader,T.getTypedefDef(name, self)
+            else:
+                print >>self.output,T.getTypedefDef(name, self)
+                if self.outputTests:
+                    print >>self.outputTests,T.getTypedefDef(name, self)
+            self.types[T] = name
+        return name
+    
+    def writeLayoutTest(self, i, ty):
+        tyName = self.getTypeName(ty)
+        tyNameClean = tyName.replace(' ','_').replace('*','star')
+        fnName = 'test_%s' % tyNameClean
+            
+        print >>self.output,'void %s(void) {' % fnName
+        self.printSizeOfType('    %s'%fnName, tyName, ty, self.output)
+        self.printAlignOfType('    %s'%fnName, tyName, ty, self.output)
+        self.printOffsetsOfType('    %s'%fnName, tyName, ty, self.output)
+        print >>self.output,'}'
+        print >>self.output
+        
+        self.layoutTests.append((i,fnName))
+        
+    def writeFunction(self, i, FT):
+        args = ', '.join(['%s arg%d'%(self.getTypeName(t),i) for i,t in enumerate(FT.argTypes)])
+        if not args:
+            args = 'void'
+
+        if FT.returnType is None:
+            retvalName = None
+            retvalTypeName = 'void'
+        else:
+            retvalTypeName = self.getTypeName(FT.returnType)
+            if self.writeBody or self.outputTests:
+                retvalName = self.getTestReturnValue(FT.returnType)
+
+        fnName = 'fn%d'%(FT.index,)
+        if self.outputHeader:
+            print >>self.outputHeader,'%s %s(%s);'%(retvalTypeName, fnName, args)
+        elif self.outputTests:
+            print >>self.outputTests,'%s %s(%s);'%(retvalTypeName, fnName, args)
+            
+        print >>self.output,'%s %s(%s)'%(retvalTypeName, fnName, args),
+        if self.writeBody:
+            print >>self.output, '{'
+            
+            for i,t in enumerate(FT.argTypes):
+                self.printValueOfType('    %s'%fnName, 'arg%d'%i, t)
+
+            if retvalName is not None:
+                print >>self.output, '  return %s;'%(retvalName,)
+            print >>self.output, '}'
+        else:
+            print >>self.output, '{}'
+        print >>self.output
+
+        if self.outputDriver:
+            print >>self.outputDriver, '  if (index == -1 || index == %d) {' % i
+            print >>self.outputDriver, '    extern void test_%s(void);' % fnName
+            print >>self.outputDriver, '    test_%s();' % fnName
+            print >>self.outputDriver, '   }'
+            
+        if self.outputTests:
+            if self.outputHeader:
+                print >>self.outputHeader, 'void test_%s(void);'%(fnName,)
+
+            if retvalName is None:
+                retvalTests = None
+            else:
+                retvalTests = self.getTestValuesArray(FT.returnType)
+            tests = map(self.getTestValuesArray, FT.argTypes)
+            print >>self.outputTests, 'void test_%s(void) {'%(fnName,)
+
+            if retvalTests is not None:
+                print >>self.outputTests, '  printf("%s: testing return.\\n");'%(fnName,)
+                print >>self.outputTests, '  for (int i=0; i<%d; ++i) {'%(retvalTests[1],)
+                args = ', '.join(['%s[%d]'%(t,randrange(l)) for t,l in tests])
+                print >>self.outputTests, '    %s RV;'%(retvalTypeName,)
+                print >>self.outputTests, '    %s = %s[i];'%(retvalName, retvalTests[0])
+                print >>self.outputTests, '    RV = %s(%s);'%(fnName, args)
+                self.printValueOfType('  %s_RV'%fnName, 'RV', FT.returnType, output=self.outputTests, indent=4)
+                self.checkTypeValues('RV', '%s[i]' % retvalTests[0], FT.returnType, output=self.outputTests, indent=4)
+                print >>self.outputTests, '  }'
+            
+            if tests:
+                print >>self.outputTests, '  printf("%s: testing arguments.\\n");'%(fnName,)
+            for i,(array,length) in enumerate(tests):
+                for j in range(length):
+                    args = ['%s[%d]'%(t,randrange(l)) for t,l in tests]
+                    args[i] = '%s[%d]'%(array,j)
+                    print >>self.outputTests, '  %s(%s);'%(fnName, ', '.join(args),)
+            print >>self.outputTests, '}'
+
+    def getTestReturnValue(self, type):
+        typeName = self.getTypeName(type)        
+        info = self.testReturnValues.get(typeName)
+        if info is None:
+            name = '%s_retval'%(typeName.replace(' ','_').replace('*','star'),)
+            print >>self.output, '%s %s;'%(typeName,name)
+            if self.outputHeader:
+                print >>self.outputHeader, 'extern %s %s;'%(typeName,name)
+            elif self.outputTests:                
+                print >>self.outputTests, 'extern %s %s;'%(typeName,name)
+            info = self.testReturnValues[typeName] = name
+        return info
+
+    def getTestValuesArray(self, type):
+        typeName = self.getTypeName(type)        
+        info = self.testValues.get(typeName)
+        if info is None:
+            name = '%s_values'%(typeName.replace(' ','_').replace('*','star'),)
+            print >>self.outputTests, 'static %s %s[] = {'%(typeName,name)
+            length = 0
+            for item in self.getTestValues(type):
+                print >>self.outputTests, '\t%s,'%(item,)
+                length += 1
+            print >>self.outputTests,'};'
+            info = self.testValues[typeName] = (name,length)
+        return info
+
+    def getTestValues(self, t):
+        if isinstance(t, BuiltinType):
+            if t.name=='float':
+                for i in ['0.0','-1.0','1.0']:
+                    yield i+'f'
+            elif t.name=='double':
+                for i in ['0.0','-1.0','1.0']:
+                    yield i
+            elif t.name in ('void *'):
+                yield '(void*) 0'
+                yield '(void*) -1'
+            else:
+                yield '(%s) 0'%(t.name,)
+                yield '(%s) -1'%(t.name,)
+                yield '(%s) 1'%(t.name,)
+        elif isinstance(t, EnumType):
+            for i in range(0, len(t.enumerators)):
+                yield 'enum%dval%d' % (t.index, i)
+        elif isinstance(t, RecordType):
+            nonPadding = [f for f in t.fields 
+                          if not f.isPaddingBitField()]
+
+            if not nonPadding:
+                yield '{ }'
+                return
+
+            # FIXME: Use designated initializers to access non-first
+            # fields of unions.
+            if t.isUnion:
+                for v in self.getTestValues(nonPadding[0]):
+                    yield '{ %s }' % v
+                return
+
+            fieldValues = map(list, map(self.getTestValues, nonPadding))
+            for i,values in enumerate(fieldValues):
+                for v in values:
+                    elements = map(random.choice,fieldValues)
+                    elements[i] = v
+                    yield '{ %s }'%(', '.join(elements))
+
+        elif isinstance(t, ComplexType):
+            for t in self.getTestValues(t.elementType):
+                yield '%s + %s * 1i'%(t,t)
+        elif isinstance(t, ArrayType):
+            values = list(self.getTestValues(t.elementType))
+            if not values:
+                yield '{ }'
+            for i in range(t.numElements):
+                for v in values:
+                    elements = [random.choice(values) for i in range(t.numElements)]
+                    elements[i] = v
+                    yield '{ %s }'%(', '.join(elements))
+        else:
+            raise NotImplementedError,'Cannot make tests values of type: "%s"'%(t,)
+
+    def printSizeOfType(self, prefix, name, t, output=None, indent=2):
+        print >>output, '%*sprintf("%s: sizeof(%s) = %%ld\\n", (long)sizeof(%s));'%(indent, '', prefix, name, name) 
+    def printAlignOfType(self, prefix, name, t, output=None, indent=2):
+        print >>output, '%*sprintf("%s: __alignof__(%s) = %%ld\\n", (long)__alignof__(%s));'%(indent, '', prefix, name, name) 
+    def printOffsetsOfType(self, prefix, name, t, output=None, indent=2):
+        if isinstance(t, RecordType):
+            for i,f in enumerate(t.fields):
+                if f.isBitField():
+                    continue
+                fname = 'field%d' % i
+                print >>output, '%*sprintf("%s: __builtin_offsetof(%s, %s) = %%ld\\n", (long)__builtin_offsetof(%s, %s));'%(indent, '', prefix, name, fname, name, fname) 
+                
+    def printValueOfType(self, prefix, name, t, output=None, indent=2):
+        if output is None:
+            output = self.output
+        if isinstance(t, BuiltinType):
+            if t.name.endswith('long long'):
+                code = 'lld'
+            elif t.name.endswith('long'):
+                code = 'ld'
+            elif t.name.split(' ')[-1] in ('_Bool','char','short','int'):
+                code = 'd'
+            elif t.name in ('float','double'):
+                code = 'f'
+            elif t.name == 'long double':
+                code = 'Lf'
+            else:
+                code = 'p'
+            print >>output, '%*sprintf("%s: %s = %%%s\\n", %s);'%(indent, '', prefix, name, code, name) 
+        elif isinstance(t, EnumType):
+            print >>output, '%*sprintf("%s: %s = %%d\\n", %s);'%(indent, '', prefix, name, name)
+        elif isinstance(t, RecordType):
+            if not t.fields:
+                print >>output, '%*sprintf("%s: %s (empty)\\n");'%(indent, '', prefix, name) 
+            for i,f in enumerate(t.fields):
+                if f.isPaddingBitField():
+                    continue
+                fname = '%s.field%d'%(name,i)
+                self.printValueOfType(prefix, fname, f, output=output, indent=indent)
+        elif isinstance(t, ComplexType):
+            self.printValueOfType(prefix, '(__real %s)'%name, t.elementType, output=output,indent=indent)
+            self.printValueOfType(prefix, '(__imag %s)'%name, t.elementType, output=output,indent=indent)
+        elif isinstance(t, ArrayType):
+            for i in range(t.numElements):
+                # Access in this fashion as a hackish way to portably
+                # access vectors.
+                if t.isVector:
+                    self.printValueOfType(prefix, '((%s*) &%s)[%d]'%(t.elementType,name,i), t.elementType, output=output,indent=indent)
+                else:
+                    self.printValueOfType(prefix, '%s[%d]'%(name,i), t.elementType, output=output,indent=indent)                    
+        else:
+            raise NotImplementedError,'Cannot print value of type: "%s"'%(t,)
+
+    def checkTypeValues(self, nameLHS, nameRHS, t, output=None, indent=2):
+        prefix = 'foo'
+        if output is None:
+            output = self.output
+        if isinstance(t, BuiltinType):
+            print >>output, '%*sassert(%s == %s);' % (indent, '', nameLHS, nameRHS)
+        elif isinstance(t, EnumType):
+            print >>output, '%*sassert(%s == %s);' % (indent, '', nameLHS, nameRHS)
+        elif isinstance(t, RecordType):
+            for i,f in enumerate(t.fields):
+                if f.isPaddingBitField():
+                    continue
+                self.checkTypeValues('%s.field%d'%(nameLHS,i), '%s.field%d'%(nameRHS,i), 
+                                     f, output=output, indent=indent)
+                if t.isUnion:
+                    break
+        elif isinstance(t, ComplexType):
+            self.checkTypeValues('(__real %s)'%nameLHS, '(__real %s)'%nameRHS, t.elementType, output=output,indent=indent)
+            self.checkTypeValues('(__imag %s)'%nameLHS, '(__imag %s)'%nameRHS, t.elementType, output=output,indent=indent)
+        elif isinstance(t, ArrayType):
+            for i in range(t.numElements):
+                # Access in this fashion as a hackish way to portably
+                # access vectors.
+                if t.isVector:
+                    self.checkTypeValues('((%s*) &%s)[%d]'%(t.elementType,nameLHS,i), 
+                                         '((%s*) &%s)[%d]'%(t.elementType,nameRHS,i), 
+                                         t.elementType, output=output,indent=indent)
+                else:
+                    self.checkTypeValues('%s[%d]'%(nameLHS,i), '%s[%d]'%(nameRHS,i), 
+                                         t.elementType, output=output,indent=indent)                    
+        else:
+            raise NotImplementedError,'Cannot print value of type: "%s"'%(t,)
+
+import sys
+
+def main():
+    from optparse import OptionParser, OptionGroup
+    parser = OptionParser("%prog [options] {indices}")
+    parser.add_option("", "--mode", dest="mode",
+                      help="autogeneration mode (random or linear) [default %default]",
+                      type='choice', choices=('random','linear'), default='linear')
+    parser.add_option("", "--count", dest="count",
+                      help="autogenerate COUNT functions according to MODE",
+                      type=int, default=0)
+    parser.add_option("", "--min", dest="minIndex", metavar="N",
+                      help="start autogeneration with the Nth function type  [default %default]",
+                      type=int, default=0)
+    parser.add_option("", "--max", dest="maxIndex", metavar="N",
+                      help="maximum index for random autogeneration  [default %default]",
+                      type=int, default=10000000)
+    parser.add_option("", "--seed", dest="seed",
+                      help="random number generator seed [default %default]",
+                      type=int, default=1)
+    parser.add_option("", "--use-random-seed", dest="useRandomSeed",
+                      help="use random value for initial random number generator seed",
+                      action='store_true', default=False)
+    parser.add_option("-o", "--output", dest="output", metavar="FILE",
+                      help="write output to FILE  [default %default]",
+                      type=str, default='-')
+    parser.add_option("-O", "--output-header", dest="outputHeader", metavar="FILE",
+                      help="write header file for output to FILE  [default %default]",
+                      type=str, default=None)
+    parser.add_option("-T", "--output-tests", dest="outputTests", metavar="FILE",
+                      help="write function tests to FILE  [default %default]",
+                      type=str, default=None)
+    parser.add_option("-D", "--output-driver", dest="outputDriver", metavar="FILE",
+                      help="write test driver to FILE  [default %default]",
+                      type=str, default=None)
+    parser.add_option("", "--test-layout", dest="testLayout", metavar="FILE",
+                      help="test structure layout",
+                      action='store_true', default=False)
+
+    group = OptionGroup(parser, "Type Enumeration Options")
+    # Builtins - Ints
+    group.add_option("", "--no-char", dest="useChar",
+                     help="do not generate char types",
+                     action="store_false", default=True)
+    group.add_option("", "--no-short", dest="useShort",
+                     help="do not generate short types",
+                     action="store_false", default=True)
+    group.add_option("", "--no-int", dest="useInt",
+                     help="do not generate int types",
+                     action="store_false", default=True)
+    group.add_option("", "--no-long", dest="useLong",
+                     help="do not generate long types",
+                     action="store_false", default=True)
+    group.add_option("", "--no-long-long", dest="useLongLong",
+                     help="do not generate long long types",
+                     action="store_false", default=True)
+    group.add_option("", "--no-unsigned", dest="useUnsigned",
+                     help="do not generate unsigned integer types",
+                     action="store_false", default=True)
+
+    # Other builtins
+    group.add_option("", "--no-bool", dest="useBool",
+                     help="do not generate bool types",
+                     action="store_false", default=True)
+    group.add_option("", "--no-float", dest="useFloat",
+                     help="do not generate float types",
+                     action="store_false", default=True)
+    group.add_option("", "--no-double", dest="useDouble",
+                     help="do not generate double types",
+                     action="store_false", default=True)
+    group.add_option("", "--no-long-double", dest="useLongDouble",
+                     help="do not generate long double types",
+                     action="store_false", default=True)
+    group.add_option("", "--no-void-pointer", dest="useVoidPointer",
+                     help="do not generate void* types",
+                     action="store_false", default=True)
+
+    # Enumerations
+    group.add_option("", "--no-enums", dest="useEnum",
+                     help="do not generate enum types",
+                     action="store_false", default=True)
+
+    # Derived types
+    group.add_option("", "--no-array", dest="useArray",
+                     help="do not generate record types",
+                     action="store_false", default=True)
+    group.add_option("", "--no-complex", dest="useComplex",
+                     help="do not generate complex types",
+                     action="store_false", default=True)
+    group.add_option("", "--no-record", dest="useRecord",
+                     help="do not generate record types",
+                     action="store_false", default=True)
+    group.add_option("", "--no-union", dest="recordUseUnion",
+                     help="do not generate union types",
+                     action="store_false", default=True)
+    group.add_option("", "--no-vector", dest="useVector",
+                     help="do not generate vector types",
+                     action="store_false", default=True)
+    group.add_option("", "--no-bit-field", dest="useBitField",
+                     help="do not generate bit-field record members",
+                     action="store_false", default=True)
+    group.add_option("", "--no-builtins", dest="useBuiltins",
+                     help="do not use any types",
+                     action="store_false", default=True)
+
+    # Tuning 
+    group.add_option("", "--no-function-return", dest="functionUseReturn",
+                     help="do not generate return types for functions",
+                     action="store_false", default=True)
+    group.add_option("", "--vector-types", dest="vectorTypes",
+                     help="comma separated list of vector types (e.g., v2i32) [default %default]",
+                     action="store", type=str, default='v2i16, v1i64, v2i32, v4i16, v8i8, v2f32, v2i64, v4i32, v8i16, v16i8, v2f64, v4f32, v16f32', metavar="N")
+    group.add_option("", "--bit-fields", dest="bitFields",
+                     help="comma separated list 'type:width' bit-field specifiers [default %default]",
+                     action="store", type=str, default="char:0,char:4,unsigned:0,unsigned:4,unsigned:13,unsigned:24")
+    group.add_option("", "--max-args", dest="functionMaxArgs",
+                     help="maximum number of arguments per function [default %default]",
+                     action="store", type=int, default=4, metavar="N")
+    group.add_option("", "--max-array", dest="arrayMaxSize",
+                     help="maximum array size [default %default]",
+                     action="store", type=int, default=4, metavar="N")
+    group.add_option("", "--max-record", dest="recordMaxSize",
+                     help="maximum number of fields per record [default %default]",
+                     action="store", type=int, default=4, metavar="N")
+    group.add_option("", "--max-record-depth", dest="recordMaxDepth",
+                     help="maximum nested structure depth [default %default]",
+                     action="store", type=int, default=None, metavar="N")
+    parser.add_option_group(group)
+    (opts, args) = parser.parse_args()
+
+    if not opts.useRandomSeed:
+        random.seed(opts.seed)
+
+    # Contruct type generator
+    builtins = []
+    if opts.useBuiltins:
+        ints = []
+        if opts.useChar: ints.append(('char',1))
+        if opts.useShort: ints.append(('short',2))
+        if opts.useInt: ints.append(('int',4))
+        # FIXME: Wrong size.
+        if opts.useLong: ints.append(('long',4))
+        if opts.useLongLong: ints.append(('long long',8))
+        if opts.useUnsigned: 
+            ints = ([('unsigned %s'%i,s) for i,s in ints] + 
+                    [('signed %s'%i,s) for i,s in ints])
+        builtins.extend(ints)
+
+        if opts.useBool: builtins.append(('_Bool',1))
+        if opts.useFloat: builtins.append(('float',4))
+        if opts.useDouble: builtins.append(('double',8))
+        if opts.useLongDouble: builtins.append(('long double',16))
+        # FIXME: Wrong size.
+        if opts.useVoidPointer:  builtins.append(('void*',4))
+
+    btg = FixedTypeGenerator([BuiltinType(n,s) for n,s in builtins])
+
+    bitfields = []
+    for specifier in opts.bitFields.split(','):
+        if not specifier.strip():
+            continue
+        name,width = specifier.strip().split(':', 1)
+        bitfields.append(BuiltinType(name,None,int(width)))
+    bftg = FixedTypeGenerator(bitfields)
+
+    charType = BuiltinType('char',1)
+    shortType = BuiltinType('short',2)
+    intType = BuiltinType('int',4)
+    longlongType = BuiltinType('long long',8)
+    floatType = BuiltinType('float',4)
+    doubleType = BuiltinType('double',8)
+    sbtg = FixedTypeGenerator([charType, intType, floatType, doubleType])
+
+    atg = AnyTypeGenerator()
+    artg = AnyTypeGenerator()
+    def makeGenerator(atg, subgen, subfieldgen, useRecord, useArray, useBitField):
+        atg.addGenerator(btg)
+        if useBitField and opts.useBitField:
+            atg.addGenerator(bftg)
+        if useRecord and opts.useRecord:
+            assert subgen 
+            atg.addGenerator(RecordTypeGenerator(subfieldgen, opts.recordUseUnion, 
+                                                 opts.recordMaxSize))
+        if opts.useComplex:
+            # FIXME: Allow overriding builtins here
+            atg.addGenerator(ComplexTypeGenerator(sbtg))
+        if useArray and opts.useArray:
+            assert subgen 
+            atg.addGenerator(ArrayTypeGenerator(subgen, opts.arrayMaxSize))
+        if opts.useVector:
+            vTypes = []
+            for i,t in enumerate(opts.vectorTypes.split(',')):
+                m = re.match('v([1-9][0-9]*)([if][1-9][0-9]*)', t.strip())
+                if not m:
+                    parser.error('Invalid vector type: %r' % t)
+                count,kind = m.groups()
+                count = int(count)
+                type = { 'i8'  : charType, 
+                         'i16' : shortType, 
+                         'i32' : intType, 
+                         'i64' : longlongType,
+                         'f32' : floatType, 
+                         'f64' : doubleType,
+                         }.get(kind)
+                if not type:
+                    parser.error('Invalid vector type: %r' % t)
+                vTypes.append(ArrayType(i, True, type, count * type.size))
+                
+            atg.addGenerator(FixedTypeGenerator(vTypes))
+        if opts.useEnum:
+            atg.addGenerator(EnumTypeGenerator([None, '-1', '1', '1u'], 1, 4))
+
+    if opts.recordMaxDepth is None: 
+        # Fully recursive, just avoid top-level arrays.
+        subFTG = AnyTypeGenerator()
+        subTG = AnyTypeGenerator()
+        atg = AnyTypeGenerator()
+        makeGenerator(subFTG, atg, atg, True, True, True)
+        makeGenerator(subTG, atg, subFTG, True, True, False)
+        makeGenerator(atg, subTG, subFTG, True, False, False)
+    else:
+        # Make a chain of type generators, each builds smaller
+        # structures.
+        base = AnyTypeGenerator()
+        fbase = AnyTypeGenerator()
+        makeGenerator(base, None, None, False, False, False)
+        makeGenerator(fbase, None, None, False, False, True)
+        for i in range(opts.recordMaxDepth):
+            n = AnyTypeGenerator()
+            fn = AnyTypeGenerator()
+            makeGenerator(n, base, fbase, True, True, False)
+            makeGenerator(fn, base, fbase, True, True, True)
+            base = n
+            fbase = fn
+        atg = AnyTypeGenerator()
+        makeGenerator(atg, base, fbase, True, False, False)
+
+    if opts.testLayout:
+        ftg = atg
+    else:
+        ftg = FunctionTypeGenerator(atg, opts.functionUseReturn, opts.functionMaxArgs)
+
+    # Override max,min,count if finite
+    if opts.maxIndex is None:
+        if ftg.cardinality is aleph0:
+            opts.maxIndex = 10000000
+        else:
+            opts.maxIndex = ftg.cardinality
+    opts.maxIndex = min(opts.maxIndex, ftg.cardinality)
+    opts.minIndex = max(0,min(opts.maxIndex-1, opts.minIndex))
+    if not opts.mode=='random':
+        opts.count = min(opts.count, opts.maxIndex-opts.minIndex)
+
+    if opts.output=='-':
+        output = sys.stdout
+    else:
+        output = open(opts.output,'w')
+        atexit.register(lambda: output.close())
+        
+    outputHeader = None
+    if opts.outputHeader:
+        outputHeader = open(opts.outputHeader,'w')
+        atexit.register(lambda: outputHeader.close())
+        
+    outputTests = None
+    if opts.outputTests:
+        outputTests = open(opts.outputTests,'w')
+        atexit.register(lambda: outputTests.close())
+
+    outputDriver = None
+    if opts.outputDriver:
+        outputDriver = open(opts.outputDriver,'w')
+        atexit.register(lambda: outputDriver.close())
+
+    info = ''
+    info += '// %s\n'%(' '.join(sys.argv),)
+    info += '// Generated: %s\n'%(time.strftime('%Y-%m-%d %H:%M'),)
+    info += '// Cardinality of function generator: %s\n'%(ftg.cardinality,)
+    info += '// Cardinality of type generator: %s\n'%(atg.cardinality,)
+
+    if opts.testLayout:
+        info += '\n#include <stdio.h>'
+    
+    P = TypePrinter(output, 
+                    outputHeader=outputHeader,
+                    outputTests=outputTests,
+                    outputDriver=outputDriver,
+                    headerName=opts.outputHeader,                    
+                    info=info)
+
+    def write(N):
+        try:
+            FT = ftg.get(N)
+        except RuntimeError,e:
+            if e.args[0]=='maximum recursion depth exceeded':
+                print >>sys.stderr,'WARNING: Skipped %d, recursion limit exceeded (bad arguments?)'%(N,)
+                return
+            raise
+        if opts.testLayout:
+            P.writeLayoutTest(N, FT)
+        else:
+            P.writeFunction(N, FT)
+
+    if args:
+        [write(int(a)) for a in args]
+
+    for i in range(opts.count):
+        if opts.mode=='linear':
+            index = opts.minIndex + i
+        else:
+            index = opts.minIndex + int((opts.maxIndex-opts.minIndex) * random.random())
+        write(index)
+
+    P.finish()
+
+if __name__=='__main__':
+    main()
+
diff --git a/utils/ABITest/Enumeration.py b/utils/ABITest/Enumeration.py
new file mode 100644
index 0000000..47e4702
--- /dev/null
+++ b/utils/ABITest/Enumeration.py
@@ -0,0 +1,276 @@
+"""Utilities for enumeration of finite and countably infinite sets.
+"""
+###
+# Countable iteration
+
+# Simplifies some calculations
+class Aleph0(int):
+    _singleton = None
+    def __new__(type):
+        if type._singleton is None:
+            type._singleton = int.__new__(type)
+        return type._singleton
+    def __repr__(self): return '<aleph0>'
+    def __str__(self): return 'inf'
+    
+    def __cmp__(self, b):
+        return 1
+
+    def __sub__(self, b):
+        raise ValueError,"Cannot subtract aleph0"
+    __rsub__ = __sub__
+
+    def __add__(self, b): 
+        return self
+    __radd__ = __add__
+
+    def __mul__(self, b): 
+        if b == 0: return b            
+        return self
+    __rmul__ = __mul__
+
+    def __floordiv__(self, b):
+        if b == 0: raise ZeroDivisionError
+        return self
+    __rfloordiv__ = __floordiv__
+    __truediv__ = __floordiv__
+    __rtuediv__ = __floordiv__
+    __div__ = __floordiv__
+    __rdiv__ = __floordiv__
+
+    def __pow__(self, b):
+        if b == 0: return 1
+        return self
+aleph0 = Aleph0()
+
+def base(line):
+    return line*(line+1)//2
+
+def pairToN((x,y)):
+    line,index = x+y,y
+    return base(line)+index
+
+def getNthPairInfo(N):
+    # Avoid various singularities
+    if N==0:
+        return (0,0)
+
+    # Gallop to find bounds for line
+    line = 1
+    next = 2
+    while base(next)<=N:
+        line = next
+        next = line << 1
+    
+    # Binary search for starting line
+    lo = line
+    hi = line<<1
+    while lo + 1 != hi:
+        #assert base(lo) <= N < base(hi)
+        mid = (lo + hi)>>1
+        if base(mid)<=N:
+            lo = mid
+        else:
+            hi = mid
+
+    line = lo
+    return line, N - base(line)
+
+def getNthPair(N):
+    line,index = getNthPairInfo(N)
+    return (line - index, index)
+
+def getNthPairBounded(N,W=aleph0,H=aleph0,useDivmod=False):
+    """getNthPairBounded(N, W, H) -> (x, y)
+    
+    Return the N-th pair such that 0 <= x < W and 0 <= y < H."""
+
+    if W <= 0 or H <= 0:
+        raise ValueError,"Invalid bounds"
+    elif N >= W*H:
+        raise ValueError,"Invalid input (out of bounds)"
+
+    # Simple case...
+    if W is aleph0 and H is aleph0:
+        return getNthPair(N)
+
+    # Otherwise simplify by assuming W < H
+    if H < W:
+        x,y = getNthPairBounded(N,H,W,useDivmod=useDivmod)
+        return y,x
+
+    if useDivmod:
+        return N%W,N//W
+    else:
+        # Conceptually we want to slide a diagonal line across a
+        # rectangle. This gives more interesting results for large
+        # bounds than using divmod.
+        
+        # If in lower left, just return as usual
+        cornerSize = base(W)
+        if N < cornerSize:
+            return getNthPair(N)
+
+        # Otherwise if in upper right, subtract from corner
+        if H is not aleph0:
+            M = W*H - N - 1
+            if M < cornerSize:
+                x,y = getNthPair(M)
+                return (W-1-x,H-1-y)
+
+        # Otherwise, compile line and index from number of times we
+        # wrap.
+        N = N - cornerSize
+        index,offset = N%W,N//W
+        # p = (W-1, 1+offset) + (-1,1)*index
+        return (W-1-index, 1+offset+index)
+def getNthPairBoundedChecked(N,W=aleph0,H=aleph0,useDivmod=False,GNP=getNthPairBounded):
+    x,y = GNP(N,W,H,useDivmod)
+    assert 0 <= x < W and 0 <= y < H
+    return x,y
+
+def getNthNTuple(N, W, H=aleph0, useLeftToRight=False):
+    """getNthNTuple(N, W, H) -> (x_0, x_1, ..., x_W)
+
+    Return the N-th W-tuple, where for 0 <= x_i < H."""
+
+    if useLeftToRight:
+        elts = [None]*W
+        for i in range(W):
+            elts[i],N = getNthPairBounded(N, H)
+        return tuple(elts)
+    else:
+        if W==0:
+            return ()
+        elif W==1:
+            return (N,)
+        elif W==2:
+            return getNthPairBounded(N, H, H)
+        else:
+            LW,RW = W//2, W - (W//2)
+            L,R = getNthPairBounded(N, H**LW, H**RW)
+            return (getNthNTuple(L,LW,H=H,useLeftToRight=useLeftToRight) + 
+                    getNthNTuple(R,RW,H=H,useLeftToRight=useLeftToRight))
+def getNthNTupleChecked(N, W, H=aleph0, useLeftToRight=False, GNT=getNthNTuple):
+    t = GNT(N,W,H,useLeftToRight)
+    assert len(t) == W
+    for i in t:
+        assert i < H
+    return t
+
+def getNthTuple(N, maxSize=aleph0, maxElement=aleph0, useDivmod=False, useLeftToRight=False):
+    """getNthTuple(N, maxSize, maxElement) -> x
+
+    Return the N-th tuple where len(x) < maxSize and for y in x, 0 <=
+    y < maxElement."""
+
+    # All zero sized tuples are isomorphic, don't ya know.
+    if N == 0:
+        return ()
+    N -= 1
+    if maxElement is not aleph0:
+        if maxSize is aleph0:
+            raise NotImplementedError,'Max element size without max size unhandled'
+        bounds = [maxElement**i for i in range(1, maxSize+1)]
+        S,M = getNthPairVariableBounds(N, bounds)
+    else:
+        S,M = getNthPairBounded(N, maxSize, useDivmod=useDivmod)
+    return getNthNTuple(M, S+1, maxElement, useLeftToRight=useLeftToRight)
+def getNthTupleChecked(N, maxSize=aleph0, maxElement=aleph0, 
+                       useDivmod=False, useLeftToRight=False, GNT=getNthTuple):
+    # FIXME: maxsize is inclusive
+    t = GNT(N,maxSize,maxElement,useDivmod,useLeftToRight)
+    assert len(t) <= maxSize
+    for i in t:
+        assert i < maxElement
+    return t
+
+def getNthPairVariableBounds(N, bounds):
+    """getNthPairVariableBounds(N, bounds) -> (x, y)
+
+    Given a finite list of bounds (which may be finite or aleph0),
+    return the N-th pair such that 0 <= x < len(bounds) and 0 <= y <
+    bounds[x]."""
+
+    if not bounds:
+        raise ValueError,"Invalid bounds"
+    if not (0 <= N < sum(bounds)):
+        raise ValueError,"Invalid input (out of bounds)"
+
+    level = 0
+    active = range(len(bounds))
+    active.sort(key=lambda i: bounds[i])
+    prevLevel = 0
+    for i,index in enumerate(active):
+        level = bounds[index]
+        W = len(active) - i
+        if level is aleph0:
+            H = aleph0
+        else:
+            H = level - prevLevel
+        levelSize = W*H
+        if N<levelSize: # Found the level
+            idelta,delta = getNthPairBounded(N, W, H)
+            return active[i+idelta],prevLevel+delta
+        else:
+            N -= levelSize
+            prevLevel = level
+    else:
+        raise RuntimError,"Unexpected loop completion"
+
+def getNthPairVariableBoundsChecked(N, bounds, GNVP=getNthPairVariableBounds):
+    x,y = GNVP(N,bounds)
+    assert 0 <= x < len(bounds) and 0 <= y < bounds[x]
+    return (x,y)
+
+###
+
+def testPairs():
+    W = 3
+    H = 6
+    a = [['  ' for x in range(10)] for y in range(10)]
+    b = [['  ' for x in range(10)] for y in range(10)]
+    for i in range(min(W*H,40)):
+        x,y = getNthPairBounded(i,W,H)
+        x2,y2 = getNthPairBounded(i,W,H,useDivmod=True)
+        print i,(x,y),(x2,y2)
+        a[y][x] = '%2d'%i
+        b[y2][x2] = '%2d'%i
+
+    print '-- a --'
+    for ln in a[::-1]:
+        if ''.join(ln).strip():
+            print '  '.join(ln)
+    print '-- b --'
+    for ln in b[::-1]:
+        if ''.join(ln).strip():
+            print '  '.join(ln)
+
+def testPairsVB():
+    bounds = [2,2,4,aleph0,5,aleph0]
+    a = [['  ' for x in range(15)] for y in range(15)]
+    b = [['  ' for x in range(15)] for y in range(15)]
+    for i in range(min(sum(bounds),40)):
+        x,y = getNthPairVariableBounds(i, bounds)
+        print i,(x,y)
+        a[y][x] = '%2d'%i
+
+    print '-- a --'
+    for ln in a[::-1]:
+        if ''.join(ln).strip():
+            print '  '.join(ln)
+
+###
+
+# Toggle to use checked versions of enumeration routines.
+if False:
+    getNthPairVariableBounds = getNthPairVariableBoundsChecked
+    getNthPairBounded = getNthPairBoundedChecked
+    getNthNTuple = getNthNTupleChecked
+    getNthTuple = getNthTupleChecked
+
+if __name__ == '__main__':
+    testPairs()
+
+    testPairsVB()
+
diff --git a/utils/ABITest/Makefile.test.common b/utils/ABITest/Makefile.test.common
new file mode 100644
index 0000000..3c208ad
--- /dev/null
+++ b/utils/ABITest/Makefile.test.common
@@ -0,0 +1,170 @@
+# -*- Makefile -*-
+
+# Usage: make test.N.report 
+#
+# COUNT can be over-ridden to change the number of tests generated per
+# file, and TESTARGS is used to change the type generation. Make sure
+# to 'make clean' after changing either of these parameters.
+
+TESTARGS := --no-unsigned --no-vector --no-complex --no-bool
+
+COUNT := 1
+TIMEOUT := 5
+
+CFLAGS := -std=gnu99
+
+X_COMPILER := gcc
+X_LL_CFLAGS := -emit-llvm -S
+Y_COMPILER := clang
+Y_LL_CFLAGS := -emit-llvm -S
+CC := gcc
+
+###
+
+ABITESTGEN := ../ABITestGen.py
+
+ifndef VERBOSE
+  Verb := @
+endif
+
+.PHONY: test.%.report
+test.%.report: temps/test.%.xx.diff temps/test.%.xy.diff temps/test.%.yx.diff temps/test.%.yy.diff
+	@ok=1;\
+	for t in $^; do \
+		if [ -s $$t ]; then \
+			echo "TEST $*: $$t failed"; \
+			ok=0;\
+		fi; \
+	done; \
+	if [ $$ok -eq 1 ]; then \
+		true; \
+	else \
+		false; \
+	fi
+
+
+.PHONY: test.%.defs-report
+test.%.defs-report: temps/test.%.defs.diff
+	@for t in $^; do \
+		if [ -s $$t ]; then \
+			echo "TEST $*: $$t failed"; \
+			cat $$t; \
+		fi; \
+	done
+
+.PHONY: test.%.build
+test.%.build: temps/test.%.ref temps/test.%.xx temps/test.%.xy temps/test.%.yx temps/test.%.yy temps/test.%.x.defs temps/test.%.y.defs
+	@true
+
+###
+
+# Diffs and output
+
+.PRECIOUS: temps/.dir
+
+.PRECIOUS: temps/test.%.xx.diff
+temps/test.%.xx.diff: temps/test.%.ref.out temps/test.%.xx.out
+	$(Verb) diff $^ > $@ || true
+.PRECIOUS: temps/test.%.xy.diff
+temps/test.%.xy.diff: temps/test.%.ref.out temps/test.%.xy.out
+	$(Verb) diff $^ > $@ || true
+.PRECIOUS: temps/test.%.yx.diff
+temps/test.%.yx.diff: temps/test.%.ref.out temps/test.%.yx.out
+	$(Verb) diff $^ > $@ || true
+.PRECIOUS: temps/test.%.yy.diff
+temps/test.%.yy.diff: temps/test.%.ref.out temps/test.%.yy.out
+	$(Verb) diff $^ > $@ || true
+.PRECIOUS: temps/test.%.defs.diff
+temps/test.%.defs.diff: temps/test.%.x.defs temps/test.%.y.defs
+	$(Verb) zipdifflines \
+	  --replace "%struct.T[0-9]+" "%struct.s" \
+	  --replace "%union.T[0-9]+" "%struct.s" \
+	  --replace "byval align [0-9]+" "byval" \
+	  $^ > $@
+
+.PRECIOUS: temps/test.%.out
+temps/test.%.out: temps/test.%
+	-$(Verb) ./$< > $@
+
+# Executables
+
+.PRECIOUS: temps/test.%.ref
+temps/test.%.ref: temps/test.%.driver.ref.o temps/test.%.a.ref.o temps/test.%.b.ref.o
+	$(Verb) $(CC) $(CFLAGS) $(CC_CFLAGS) -O3 -o $@ $^
+.PRECIOUS: temps/test.%.xx
+temps/test.%.xx: temps/test.%.driver.ref.o temps/test.%.a.x.o temps/test.%.b.x.o
+	$(Verb) $(CC) $(CFLAGS) $(CC_CFLAGS) -O3  -o $@ $^
+.PRECIOUS: temps/test.%.xy
+temps/test.%.xy: temps/test.%.driver.ref.o temps/test.%.a.x.o temps/test.%.b.y.o
+	$(Verb) $(CC) $(CFLAGS) $(CC_CFLAGS) -O3  -o $@ $^
+.PRECIOUS: temps/test.%.yx
+temps/test.%.yx: temps/test.%.driver.ref.o temps/test.%.a.y.o temps/test.%.b.x.o
+	$(Verb) $(CC) $(CFLAGS) $(CC_CFLAGS) -O3  -o $@ $^
+.PRECIOUS: temps/test.%.yy
+temps/test.%.yy: temps/test.%.driver.ref.o temps/test.%.a.y.o temps/test.%.b.y.o
+	$(Verb) $(CC) $(CFLAGS) $(CC_CFLAGS) -O3  -o $@ $^
+
+# Object files
+
+.PRECIOUS: temps/test.%.ref.o
+temps/test.%.ref.o: inputs/test.%.c temps/.dir
+	$(Verb) $(CC) -c $(CFLAGS) $(CC_CFLAGS) -o $@ $<
+.PRECIOUS: temps/test.%.x.o
+temps/test.%.x.o: inputs/test.%.c temps/.dir
+	$(Verb) $(X_COMPILER) -c $(CFLAGS) $(X_CFLAGS) -o $@ $<
+.PRECIOUS: temps/test.%.y.o
+temps/test.%.y.o: inputs/test.%.c temps/.dir
+	$(Verb) $(Y_COMPILER) -c $(CFLAGS) $(Y_CFLAGS) -o $@ $<
+
+.PRECIOUS: temps/test.%.x.defs
+temps/test.%.x.defs: temps/test.%.a.x.ll temps/.dir
+	-$(Verb) -grep '^define ' $< > $@
+.PRECIOUS: temps/test.%.y.defs
+temps/test.%.y.defs: temps/test.%.a.y.ll temps/.dir
+	-$(Verb) -grep '^define ' $< > $@
+
+.PRECIOUS: temps/test.%.a.x.ll
+temps/test.%.a.x.ll: inputs/test.%.a.c temps/.dir
+	$(Verb) $(X_COMPILER) $(CFLAGS) $(X_LL_CFLAGS) $(X_CFLAGS) -o $@ $<
+.PRECIOUS: temps/test.%.b.x.ll
+temps/test.%.b.x.ll: inputs/test.%.b.c temps/.dir
+	$(Verb) $(X_COMPILER) $(CFLAGS) $(X_LL_CFLAGS) $(X_CFLAGS) -o $@ $<
+.PRECIOUS: temps/test.%.a.y.ll
+temps/test.%.a.y.ll: inputs/test.%.a.c temps/.dir
+	$(Verb) $(Y_COMPILER) $(CFLAGS) $(Y_LL_CFLAGS) $(Y_CFLAGS) -o $@ $<
+.PRECIOUS: temps/test.%.b.y.ll
+temps/test.%.b.y.ll: inputs/test.%.b.c temps/.dir
+	$(Verb) $(Y_COMPILER) $(CFLAGS) $(Y_LL_CFLAGS) $(Y_CFLAGS) -o $@ $<
+
+# Input generation
+
+.PHONY: test.%.top
+test.%.top: inputs/test.%.a.c inputs/test.%.b.c inputs/test.%.driver.c
+	@true
+
+.PRECIOUS: inputs/test.%.a.c inputs/test.%.b.c inputs/test.%.driver.c
+inputs/test.%.a.c: test.%.generate
+	@true
+inputs/test.%.b.c: test.%.generate
+	@true
+inputs/test.%.driver.c: test.%.generate
+	@true
+
+.PHONY: test.%.generate
+.PRECIOUS: inputs/.dir
+test.%.generate: $(ABITESTGEN) inputs/.dir
+	$(Verb) $(ABITESTGEN) $(TESTARGS) -o inputs/test.$*.a.c -T inputs/test.$*.b.c -D inputs/test.$*.driver.c --min=$(shell expr $* '*' $(COUNT))  --count=$(COUNT)
+
+# Cleaning
+
+clean-temps:
+	$(Verb) rm -rf temps
+
+clean:
+	$(Verb) rm -rf temps inputs
+
+# Etc.
+
+%/.dir:
+	$(Verb) mkdir -p $* > /dev/null
+	$(Verb) $(DATE) > $@
diff --git a/utils/ABITest/TypeGen.py b/utils/ABITest/TypeGen.py
new file mode 100644
index 0000000..40ea791
--- /dev/null
+++ b/utils/ABITest/TypeGen.py
@@ -0,0 +1,462 @@
+"""Flexible enumeration of C types."""
+
+from Enumeration import *
+
+# TODO:
+
+#  - struct improvements (flexible arrays, packed &
+#    unpacked, alignment)
+#  - objective-c qualified id
+#  - anonymous / transparent unions
+#  - VLAs
+#  - block types
+#  - K&R functions
+#  - pass arguments of different types (test extension, transparent union)
+#  - varargs
+
+###
+# Actual type types
+
+class Type:
+    def isBitField(self):
+        return False
+
+    def isPaddingBitField(self):
+        return False
+
+class BuiltinType(Type):
+    def __init__(self, name, size, bitFieldSize=None):
+        self.name = name
+        self.size = size
+        self.bitFieldSize = bitFieldSize
+
+    def isBitField(self):
+        return self.bitFieldSize is not None
+
+    def isPaddingBitField(self):
+        return self.bitFieldSize is 0
+
+    def getBitFieldSize(self):
+        assert self.isBitField()
+        return self.bitFieldSize
+
+    def sizeof(self):
+        return self.size
+
+    def __str__(self):
+        return self.name
+
+class EnumType(Type):
+    def __init__(self, index, enumerators):
+        self.index = index
+        self.enumerators = enumerators
+
+    def getEnumerators(self):
+        result = ''
+        for i, init in enumerate(self.enumerators):
+            if i > 0:
+                result = result + ', '
+            result = result + 'enum%dval%d' % (self.index, i)
+            if init:
+                result = result + ' = %s' % (init)
+
+        return result
+
+    def __str__(self):
+        return 'enum { %s }' % (self.getEnumerators())
+
+    def getTypedefDef(self, name, printer):
+        return 'typedef enum %s { %s } %s;'%(name, self.getEnumerators(), name)
+
+class RecordType(Type):
+    def __init__(self, index, isUnion, fields):
+        self.index = index
+        self.isUnion = isUnion
+        self.fields = fields
+        self.name = None
+
+    def __str__(self):
+        def getField(t):
+            if t.isBitField():
+                return "%s : %d;" % (t, t.getBitFieldSize())
+            else:
+                return "%s;" % t
+
+        return '%s { %s }'%(('struct','union')[self.isUnion],
+                            ' '.join(map(getField, self.fields)))
+
+    def getTypedefDef(self, name, printer):
+        def getField((i, t)):
+            if t.isBitField():
+                if t.isPaddingBitField():
+                    return '%s : 0;'%(printer.getTypeName(t),)
+                else:
+                    return '%s field%d : %d;'%(printer.getTypeName(t),i,
+                                               t.getBitFieldSize())
+            else:
+                return '%s field%d;'%(printer.getTypeName(t),i)
+        fields = map(getField, enumerate(self.fields))
+        # Name the struct for more readable LLVM IR.
+        return 'typedef %s %s { %s } %s;'%(('struct','union')[self.isUnion],
+                                           name, ' '.join(fields), name)
+                                           
+class ArrayType(Type):
+    def __init__(self, index, isVector, elementType, size):
+        if isVector:
+            # Note that for vectors, this is the size in bytes.
+            assert size > 0
+        else:
+            assert size is None or size >= 0
+        self.index = index
+        self.isVector = isVector
+        self.elementType = elementType
+        self.size = size
+        if isVector:
+            eltSize = self.elementType.sizeof()
+            assert not (self.size % eltSize)
+            self.numElements = self.size // eltSize
+        else:
+            self.numElements = self.size
+
+    def __str__(self):
+        if self.isVector:
+            return 'vector (%s)[%d]'%(self.elementType,self.size)
+        elif self.size is not None:
+            return '(%s)[%d]'%(self.elementType,self.size)
+        else:
+            return '(%s)[]'%(self.elementType,)
+
+    def getTypedefDef(self, name, printer):
+        elementName = printer.getTypeName(self.elementType)
+        if self.isVector:
+            return 'typedef %s %s __attribute__ ((vector_size (%d)));'%(elementName,
+                                                                        name,
+                                                                        self.size)
+        else:
+            if self.size is None:
+                sizeStr = ''
+            else:
+                sizeStr = str(self.size)
+            return 'typedef %s %s[%s];'%(elementName, name, sizeStr)
+
+class ComplexType(Type):
+    def __init__(self, index, elementType):
+        self.index = index
+        self.elementType = elementType
+
+    def __str__(self):
+        return '_Complex (%s)'%(self.elementType)
+
+    def getTypedefDef(self, name, printer):
+        return 'typedef _Complex %s %s;'%(printer.getTypeName(self.elementType), name)
+
+class FunctionType(Type):
+    def __init__(self, index, returnType, argTypes):
+        self.index = index
+        self.returnType = returnType
+        self.argTypes = argTypes
+
+    def __str__(self):
+        if self.returnType is None:
+            rt = 'void'
+        else:
+            rt = str(self.returnType)
+        if not self.argTypes:
+            at = 'void'
+        else:
+            at = ', '.join(map(str, self.argTypes))
+        return '%s (*)(%s)'%(rt, at)
+
+    def getTypedefDef(self, name, printer):
+        if self.returnType is None:
+            rt = 'void'
+        else:
+            rt = str(self.returnType)
+        if not self.argTypes:
+            at = 'void'
+        else:
+            at = ', '.join(map(str, self.argTypes))
+        return 'typedef %s (*%s)(%s);'%(rt, name, at)
+
+###
+# Type enumerators
+
+class TypeGenerator(object):
+    def __init__(self):
+        self.cache = {}
+
+    def setCardinality(self):
+        abstract
+
+    def get(self, N):
+        T = self.cache.get(N)
+        if T is None:
+            assert 0 <= N < self.cardinality
+            T = self.cache[N] = self.generateType(N)
+        return T
+
+    def generateType(self, N):
+        abstract
+
+class FixedTypeGenerator(TypeGenerator):
+    def __init__(self, types):
+        TypeGenerator.__init__(self)
+        self.types = types
+        self.setCardinality()
+
+    def setCardinality(self):
+        self.cardinality = len(self.types)
+
+    def generateType(self, N):
+        return self.types[N]
+
+# Factorial
+def fact(n):
+    result = 1
+    while n > 0:
+        result = result * n
+        n = n - 1
+    return result
+
+# Compute the number of combinations (n choose k)
+def num_combinations(n, k): 
+    return fact(n) / (fact(k) * fact(n - k))
+
+# Enumerate the combinations choosing k elements from the list of values
+def combinations(values, k):
+    # From ActiveState Recipe 190465: Generator for permutations,
+    # combinations, selections of a sequence
+    if k==0: yield []
+    else:
+        for i in xrange(len(values)-k+1):
+            for cc in combinations(values[i+1:],k-1):
+                yield [values[i]]+cc
+
+class EnumTypeGenerator(TypeGenerator):
+    def __init__(self, values, minEnumerators, maxEnumerators):
+        TypeGenerator.__init__(self)
+        self.values = values
+        self.minEnumerators = minEnumerators
+        self.maxEnumerators = maxEnumerators
+        self.setCardinality()
+
+    def setCardinality(self):
+        self.cardinality = 0
+        for num in range(self.minEnumerators, self.maxEnumerators + 1):
+            self.cardinality += num_combinations(len(self.values), num)
+
+    def generateType(self, n):
+        # Figure out the number of enumerators in this type
+        numEnumerators = self.minEnumerators
+        valuesCovered = 0
+        while numEnumerators < self.maxEnumerators:
+            comb = num_combinations(len(self.values), numEnumerators)
+            if valuesCovered + comb > n:
+                break
+            numEnumerators = numEnumerators + 1
+            valuesCovered += comb
+
+        # Find the requested combination of enumerators and build a
+        # type from it.
+        i = 0
+        for enumerators in combinations(self.values, numEnumerators):
+            if i == n - valuesCovered:
+                return EnumType(n, enumerators)
+                
+            i = i + 1
+
+        assert False
+
+class ComplexTypeGenerator(TypeGenerator):
+    def __init__(self, typeGen):
+        TypeGenerator.__init__(self)
+        self.typeGen = typeGen
+        self.setCardinality()
+    
+    def setCardinality(self):
+        self.cardinality = self.typeGen.cardinality
+
+    def generateType(self, N):
+        return ComplexType(N, self.typeGen.get(N))
+
+class VectorTypeGenerator(TypeGenerator):
+    def __init__(self, typeGen, sizes):
+        TypeGenerator.__init__(self)
+        self.typeGen = typeGen
+        self.sizes = tuple(map(int,sizes))
+        self.setCardinality()
+
+    def setCardinality(self):
+        self.cardinality = len(self.sizes)*self.typeGen.cardinality
+
+    def generateType(self, N):
+        S,T = getNthPairBounded(N, len(self.sizes), self.typeGen.cardinality)
+        return ArrayType(N, True, self.typeGen.get(T), self.sizes[S])
+
+class FixedArrayTypeGenerator(TypeGenerator):
+    def __init__(self, typeGen, sizes):
+        TypeGenerator.__init__(self)
+        self.typeGen = typeGen
+        self.sizes = tuple(size)
+        self.setCardinality()
+
+    def setCardinality(self):
+        self.cardinality = len(self.sizes)*self.typeGen.cardinality
+
+    def generateType(self, N):
+        S,T = getNthPairBounded(N, len(self.sizes), self.typeGen.cardinality)
+        return ArrayType(N, false, self.typeGen.get(T), self.sizes[S])
+
+class ArrayTypeGenerator(TypeGenerator):
+    def __init__(self, typeGen, maxSize, useIncomplete=False, useZero=False):
+        TypeGenerator.__init__(self)
+        self.typeGen = typeGen
+        self.useIncomplete = useIncomplete
+        self.useZero = useZero
+        self.maxSize = int(maxSize)
+        self.W = useIncomplete + useZero + self.maxSize
+        self.setCardinality()
+
+    def setCardinality(self):
+        self.cardinality = self.W * self.typeGen.cardinality
+
+    def generateType(self, N):
+        S,T = getNthPairBounded(N, self.W, self.typeGen.cardinality)
+        if self.useIncomplete:
+            if S==0:
+                size = None
+                S = None
+            else:
+                S = S - 1
+        if S is not None:
+            if self.useZero:
+                size = S
+            else:
+                size = S + 1        
+        return ArrayType(N, False, self.typeGen.get(T), size)
+
+class RecordTypeGenerator(TypeGenerator):
+    def __init__(self, typeGen, useUnion, maxSize):
+        TypeGenerator.__init__(self)
+        self.typeGen = typeGen
+        self.useUnion = bool(useUnion)
+        self.maxSize = int(maxSize)
+        self.setCardinality()
+
+    def setCardinality(self):
+        M = 1 + self.useUnion
+        if self.maxSize is aleph0:
+            S =  aleph0 * self.typeGen.cardinality
+        else:
+            S = 0
+            for i in range(self.maxSize+1):
+                S += M * (self.typeGen.cardinality ** i)
+        self.cardinality = S
+
+    def generateType(self, N):
+        isUnion,I = False,N
+        if self.useUnion:
+            isUnion,I = (I&1),I>>1
+        fields = map(self.typeGen.get,getNthTuple(I,self.maxSize,self.typeGen.cardinality))
+        return RecordType(N, isUnion, fields)
+
+class FunctionTypeGenerator(TypeGenerator):
+    def __init__(self, typeGen, useReturn, maxSize):
+        TypeGenerator.__init__(self)
+        self.typeGen = typeGen
+        self.useReturn = useReturn
+        self.maxSize = maxSize
+        self.setCardinality()
+    
+    def setCardinality(self):
+        if self.maxSize is aleph0:
+            S = aleph0 * self.typeGen.cardinality()
+        elif self.useReturn:
+            S = 0
+            for i in range(1,self.maxSize+1+1):
+                S += self.typeGen.cardinality ** i
+        else:
+            S = 0
+            for i in range(self.maxSize+1):
+                S += self.typeGen.cardinality ** i
+        self.cardinality = S
+    
+    def generateType(self, N):
+        if self.useReturn:
+            # Skip the empty tuple
+            argIndices = getNthTuple(N+1, self.maxSize+1, self.typeGen.cardinality)
+            retIndex,argIndices = argIndices[0],argIndices[1:]
+            retTy = self.typeGen.get(retIndex)
+        else:
+            retTy = None
+            argIndices = getNthTuple(N, self.maxSize, self.typeGen.cardinality)
+        args = map(self.typeGen.get, argIndices)
+        return FunctionType(N, retTy, args)
+
+class AnyTypeGenerator(TypeGenerator):
+    def __init__(self):
+        TypeGenerator.__init__(self)
+        self.generators = []
+        self.bounds = []
+        self.setCardinality()
+        self._cardinality = None
+        
+    def getCardinality(self):
+        if self._cardinality is None:
+            return aleph0
+        else:
+            return self._cardinality
+    def setCardinality(self):
+        self.bounds = [g.cardinality for g in self.generators]
+        self._cardinality = sum(self.bounds)
+    cardinality = property(getCardinality, None)
+
+    def addGenerator(self, g):
+        self.generators.append(g)
+        for i in range(100):
+            prev = self._cardinality
+            self._cardinality = None
+            for g in self.generators:
+                g.setCardinality()
+            self.setCardinality()
+            if (self._cardinality is aleph0) or prev==self._cardinality:
+                break
+        else:
+            raise RuntimeError,"Infinite loop in setting cardinality"
+
+    def generateType(self, N):
+        index,M = getNthPairVariableBounds(N, self.bounds)
+        return self.generators[index].get(M)
+
+def test():
+    fbtg = FixedTypeGenerator([BuiltinType('char', 4),
+                               BuiltinType('char', 4, 0),
+                               BuiltinType('int',  4, 5)])
+
+    fields1 = AnyTypeGenerator()
+    fields1.addGenerator( fbtg )
+
+    fields0 = AnyTypeGenerator()
+    fields0.addGenerator( fbtg )
+#    fields0.addGenerator( RecordTypeGenerator(fields1, False, 4) )
+
+    btg = FixedTypeGenerator([BuiltinType('char', 4),
+                              BuiltinType('int',  4)])
+    etg = EnumTypeGenerator([None, '-1', '1', '1u'], 0, 3)
+
+    atg = AnyTypeGenerator()
+    atg.addGenerator( btg )
+    atg.addGenerator( RecordTypeGenerator(fields0, False, 4) )
+    atg.addGenerator( etg )
+    print 'Cardinality:',atg.cardinality
+    for i in range(100):
+        if i == atg.cardinality:
+            try:
+                atg.get(i)
+                raise RuntimeError,"Cardinality was wrong"
+            except AssertionError:
+                break
+        print '%4d: %s'%(i, atg.get(i))
+
+if __name__ == '__main__':
+    test()
diff --git a/utils/ABITest/build-and-summarize-all.sh b/utils/ABITest/build-and-summarize-all.sh
new file mode 100755
index 0000000..23e34a4
--- /dev/null
+++ b/utils/ABITest/build-and-summarize-all.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+set -eu
+
+if [ $# != 1 ]; then
+    echo "usage: $0 <num-tests>"
+    exit 1
+fi
+
+for bits in 32 64; do
+    for kind in return-types single-args; do
+        echo "-- $kind-$bits --"
+        (cd $kind-$bits && ../build-and-summarize.sh $1)
+    done
+done
diff --git a/utils/ABITest/build-and-summarize.sh b/utils/ABITest/build-and-summarize.sh
new file mode 100755
index 0000000..602728b
--- /dev/null
+++ b/utils/ABITest/build-and-summarize.sh
@@ -0,0 +1,14 @@
+#!/bin/sh
+
+set -eu
+
+if [ $# != 1 ]; then
+    echo "usage: $0 <num-tests>"
+    exit 1
+fi
+
+dir=$(dirname $0)
+$dir/build.sh $1 &> /dev/null || true
+../summarize.sh $1 &> fails-x.txt
+cat fails-x.txt
+wc -l fails-x.txt
diff --git a/utils/ABITest/build.sh b/utils/ABITest/build.sh
new file mode 100755
index 0000000..a50d14a
--- /dev/null
+++ b/utils/ABITest/build.sh
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+set -eu
+
+if [ $# != 1 ]; then
+    echo "usage: $0 <num-tests>"
+    exit 1
+fi
+
+CPUS=2
+make -j $CPUS \
+  $(for i in $(seq 0 $1); do echo test.$i.report; done) -k
diff --git a/utils/ABITest/layout/Makefile b/utils/ABITest/layout/Makefile
new file mode 100644
index 0000000..0520625
--- /dev/null
+++ b/utils/ABITest/layout/Makefile
@@ -0,0 +1,68 @@
+# Usage: make test.N.report 
+#
+# COUNT can be over-ridden to change the number of tests generated per
+# file, and TESTARGS is used to change the type generation. Make sure
+# to 'make clean' after changing either of these parameters.
+
+ABITESTGEN := ../ABITestGen.py
+TESTARGS := --max-args 0 --test-layout
+COUNT := 1000
+TIMEOUT := 5
+
+CFLAGS := -std=gnu99
+
+X_COMPILER := llvm-gcc
+Y_COMPILER := clang
+CC := gcc
+
+ifeq (0, 0)
+X_CFLAGS := -m32
+Y_CFLAGS := -m32
+CC_CFLAGS := -m32
+else
+X_CFLAGS := -m64
+Y_CFLAGS := -m64
+CC_CFLAGS := -m64
+endif
+
+.PHONY: test.%.report
+test.%.report: test.%.x.diff test.%.y.diff
+	@for t in $^; do \
+		if [ -s $$t ]; then \
+			echo "TEST $*: $$t failed"; \
+		fi; \
+	done
+
+.PHONY: test.%.build
+test.%.build: test.%.ref test.%.x test.%.y
+	@true
+
+###
+
+.PRECIOUS: test.%.x.diff
+test.%.x.diff: test.%.ref.out test.%.x.out
+	-diff $^ > $@
+.PRECIOUS: test.%.y.diff
+test.%.y.diff: test.%.ref.out test.%.y.out
+	-diff $^ > $@
+
+.PRECIOUS: test.%.out
+test.%.out: test.%
+	-./$< > $@
+
+.PRECIOUS: test.%.ref
+test.%.ref: test.%.c
+	$(CC) $(CFLAGS) $(CC_CFLAGS) -o $@ $^
+.PRECIOUS: test.%.x
+test.%.x: test.%.c
+	$(X_COMPILER) $(CFLAGS) $(X_CFLAGS) -o $@ $^
+.PRECIOUS: test.%.y
+test.%.y: test.%.c
+	$(Y_COMPILER) $(CFLAGS) $(Y_CFLAGS) -o $@ $^
+
+.PRECIOUS: test.%.c
+test.%.c: $(ABITESTGEN)
+	$(ABITESTGEN) $(TESTARGS) -o $@ --min=$(shell expr $* '*' $(COUNT))  --count=$(COUNT)
+
+clean:	
+	rm -f test.* *~
diff --git a/utils/ABITest/return-types-32/Makefile b/utils/ABITest/return-types-32/Makefile
new file mode 100644
index 0000000..df1c53f
--- /dev/null
+++ b/utils/ABITest/return-types-32/Makefile
@@ -0,0 +1,7 @@
+X_CFLAGS := -m32
+Y_CFLAGS := -m32
+CC_CFLAGS := -m32
+
+include ../Makefile.test.common
+
+TESTARGS += --max-args 0
diff --git a/utils/ABITest/return-types-64/Makefile b/utils/ABITest/return-types-64/Makefile
new file mode 100644
index 0000000..9616e45
--- /dev/null
+++ b/utils/ABITest/return-types-64/Makefile
@@ -0,0 +1,7 @@
+X_CFLAGS := -m64
+Y_CFLAGS := -m64
+CC_CFLAGS := -m64
+
+include ../Makefile.test.common
+
+TESTARGS += --max-args 0
diff --git a/utils/ABITest/single-args-32/Makefile b/utils/ABITest/single-args-32/Makefile
new file mode 100644
index 0000000..9ff417f
--- /dev/null
+++ b/utils/ABITest/single-args-32/Makefile
@@ -0,0 +1,7 @@
+X_CFLAGS := -m32
+Y_CFLAGS := -m32
+CC_CFLAGS := -m32
+
+include ../Makefile.test.common
+
+TESTARGS += --no-function-return --max-args 1
diff --git a/utils/ABITest/single-args-64/Makefile b/utils/ABITest/single-args-64/Makefile
new file mode 100644
index 0000000..b8acb70
--- /dev/null
+++ b/utils/ABITest/single-args-64/Makefile
@@ -0,0 +1,13 @@
+# Usage: make test.N.report 
+#
+# COUNT can be over-ridden to change the number of tests generated per
+# file, and TESTARGS is used to change the type generation. Make sure
+# to 'make clean' after changing either of these parameters.
+
+X_CFLAGS := -m64
+Y_CFLAGS := -m64
+CC_CFLAGS := -m64
+
+include ../Makefile.test.common
+
+TESTARGS += --no-function-return --max-args 1
diff --git a/utils/ABITest/summarize.sh b/utils/ABITest/summarize.sh
new file mode 100755
index 0000000..3efb52b
--- /dev/null
+++ b/utils/ABITest/summarize.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+set -eu
+
+if [ $# != 1 ]; then
+    echo "usage: $0 <num-tests>"
+    exit 1
+fi
+
+for i in $(seq 0 $1); do 
+    if (! make test.$i.report &> /dev/null); then 
+        echo "FAIL: $i";
+    fi; 
+done
+
diff --git a/utils/C++Tests/Clang-Code-Compile/lit.local.cfg b/utils/C++Tests/Clang-Code-Compile/lit.local.cfg
new file mode 100644
index 0000000..59d3466
--- /dev/null
+++ b/utils/C++Tests/Clang-Code-Compile/lit.local.cfg
@@ -0,0 +1,26 @@
+# -*- Python -*-
+
+# Configuration file for the 'lit' test runner.
+
+def getRoot(config):
+    if not config.parent:
+        return config
+    return getRoot(config.parent)
+
+root = getRoot(config)
+
+# testFormat: The test format to use to interpret tests.
+cxxflags = ['-D__STDC_LIMIT_MACROS',
+            '-D__STDC_CONSTANT_MACROS',
+            '-Wno-sign-compare',
+            '-I%s/include' % root.llvm_src_root,
+            '-I%s/include' % root.llvm_obj_root,
+            '-I%s/tools/clang/include' % root.llvm_src_root,
+            '-I%s/tools/clang/include' % root.llvm_obj_root]
+config.test_format = \
+  lit.formats.OneCommandPerFileTest(command=[root.clang, '-emit-llvm', '-c',
+                                             '-o', '/dev/null'] + cxxflags,
+                                    dir='%s/tools/clang/lib' % root.llvm_src_root,
+                                    recursive=True,
+                                    pattern='^(.*\\.cpp)$')
+
diff --git a/utils/C++Tests/Clang-Code-Syntax/lit.local.cfg b/utils/C++Tests/Clang-Code-Syntax/lit.local.cfg
new file mode 100644
index 0000000..8f00c8d
--- /dev/null
+++ b/utils/C++Tests/Clang-Code-Syntax/lit.local.cfg
@@ -0,0 +1,25 @@
+# -*- Python -*-
+
+# Configuration file for the 'lit' test runner.
+
+def getRoot(config):
+    if not config.parent:
+        return config
+    return getRoot(config.parent)
+
+root = getRoot(config)
+
+# testFormat: The test format to use to interpret tests.
+cxxflags = ['-D__STDC_LIMIT_MACROS',
+            '-D__STDC_CONSTANT_MACROS',
+            '-Wno-sign-compare',
+            '-I%s/include' % root.llvm_src_root,
+            '-I%s/include' % root.llvm_obj_root,
+            '-I%s/tools/clang/include' % root.llvm_src_root,
+            '-I%s/tools/clang/include' % root.llvm_obj_root]
+config.test_format = \
+  lit.formats.OneCommandPerFileTest(command=[root.clang,
+                                             '-fsyntax-only'] + cxxflags,
+                                    dir='%s/tools/clang/lib' % root.llvm_src_root,
+                                    recursive=True,
+                                    pattern='^(.*\\.cpp)$')
diff --git a/utils/C++Tests/Clang-Syntax/lit.local.cfg b/utils/C++Tests/Clang-Syntax/lit.local.cfg
new file mode 100644
index 0000000..89fdd8e
--- /dev/null
+++ b/utils/C++Tests/Clang-Syntax/lit.local.cfg
@@ -0,0 +1,24 @@
+# -*- Python -*-
+
+# Configuration file for the 'lit' test runner.
+
+def getRoot(config):
+    if not config.parent:
+        return config
+    return getRoot(config.parent)
+
+root = getRoot(config)
+
+# testFormat: The test format to use to interpret tests.
+config.test_format = lit.formats.SyntaxCheckTest(compiler=root.clang,
+                                                 dir='%s/tools/clang/include/clang' % root.llvm_src_root,
+                                                 recursive=True,
+                                                 pattern='^(.*\\.h)$',
+                                                 extra_cxx_args=['-D__STDC_LIMIT_MACROS',
+                                                                 '-D__STDC_CONSTANT_MACROS',
+                                                                 '-Wno-sign-compare',
+                                                                 '-Werror',
+                                                                 '-I%s/include' % root.llvm_src_root,
+                                                                 '-I%s/include' % root.llvm_obj_root,
+                                                                 '-I%s/tools/clang/include' % root.llvm_src_root,
+                                                                 '-I%s/tools/clang/include' % root.llvm_obj_root])
diff --git a/utils/C++Tests/LLVM-Code-Compile/lit.local.cfg b/utils/C++Tests/LLVM-Code-Compile/lit.local.cfg
new file mode 100644
index 0000000..6676e31
--- /dev/null
+++ b/utils/C++Tests/LLVM-Code-Compile/lit.local.cfg
@@ -0,0 +1,56 @@
+# -*- Python -*-
+
+# Configuration file for the 'lit' test runner.
+
+def getRoot(config):
+    if not config.parent:
+        return config
+    return getRoot(config.parent)
+
+root = getRoot(config)
+
+# testFormat: The test format to use to interpret tests.
+target_obj_root = root.llvm_obj_root
+cxxflags = ['-D__STDC_LIMIT_MACROS',
+            '-D__STDC_CONSTANT_MACROS',
+            '-Wno-sign-compare',
+            '-I%s/include' % root.llvm_src_root,
+            '-I%s/include' % root.llvm_obj_root,
+            '-I%s/lib/Target/Alpha' % root.llvm_src_root,
+            '-I%s/lib/Target/ARM' % root.llvm_src_root,
+            '-I%s/lib/Target/Blackfin' % root.llvm_src_root,
+            '-I%s/lib/Target/CBackend' % root.llvm_src_root,
+            '-I%s/lib/Target/CellSPU' % root.llvm_src_root,
+            '-I%s/lib/Target/CppBackend' % root.llvm_src_root,
+            '-I%s/lib/Target/Mips' % root.llvm_src_root,
+            '-I%s/lib/Target/MSIL' % root.llvm_src_root,
+            '-I%s/lib/Target/MSP430' % root.llvm_src_root,
+            '-I%s/lib/Target/PIC16' % root.llvm_src_root,
+            '-I%s/lib/Target/PowerPC' % root.llvm_src_root,
+            '-I%s/lib/Target/Sparc' % root.llvm_src_root,
+            '-I%s/lib/Target/SystemZ' % root.llvm_src_root,
+            '-I%s/lib/Target/X86' % root.llvm_src_root,
+            '-I%s/lib/Target/XCore' % root.llvm_src_root,
+            '-I%s/lib/Target/Alpha' % target_obj_root,
+            '-I%s/lib/Target/ARM' % target_obj_root,
+            '-I%s/lib/Target/Blackfin' % target_obj_root,
+            '-I%s/lib/Target/CBackend' % target_obj_root,
+            '-I%s/lib/Target/CellSPU' % target_obj_root,
+            '-I%s/lib/Target/CppBackend' % target_obj_root,
+            '-I%s/lib/Target/Mips' % target_obj_root,
+            '-I%s/lib/Target/MSIL' % target_obj_root,
+            '-I%s/lib/Target/MSP430' % target_obj_root,
+            '-I%s/lib/Target/PIC16' % target_obj_root,
+            '-I%s/lib/Target/PowerPC' % target_obj_root,
+            '-I%s/lib/Target/Sparc' % target_obj_root,
+            '-I%s/lib/Target/SystemZ' % target_obj_root,
+            '-I%s/lib/Target/X86' % target_obj_root,
+            '-I%s/lib/Target/XCore' % target_obj_root];
+
+config.test_format = \
+  lit.formats.OneCommandPerFileTest(command=[root.clang, '-emit-llvm', '-c',
+                                             '-o', '/dev/null'] + cxxflags,
+                                    dir='%s/lib' % root.llvm_src_root,
+                                    recursive=True,
+                                    pattern='^(.*\\.cpp)$')
+
diff --git a/utils/C++Tests/LLVM-Code-Symbols/check-symbols b/utils/C++Tests/LLVM-Code-Symbols/check-symbols
new file mode 100755
index 0000000..cd54eed
--- /dev/null
+++ b/utils/C++Tests/LLVM-Code-Symbols/check-symbols
@@ -0,0 +1,54 @@
+#!/usr/bin/env python
+
+import subprocess
+import difflib
+
+def capture_2(args0, args1):
+    import subprocess
+    p0 = subprocess.Popen(args0, stdin=None, stdout=subprocess.PIPE,
+                          stderr=subprocess.PIPE)
+    p1 = subprocess.Popen(args1, stdin=p0.stdout, stdout=subprocess.PIPE,
+                          stderr=subprocess.PIPE)
+    out,_ = p1.communicate()
+    return out
+
+def normalize_nm(data):    
+    lines = data.split('\n')
+    lines.sort()
+
+    # FIXME: Ignore common symbols for now.
+    lines = [ln for ln in lines
+             if not ln.startswith('         C')]
+
+    return lines
+
+def main():
+    import sys
+    clang = sys.argv[1]
+    flags = sys.argv[2:]
+
+    # FIXME: Relax to include undefined symbols.
+    nm_args = ["llvm-nm", "-extern-only", "-defined-only"]
+
+    llvmgcc_args = ["llvm-gcc"] + flags + ["-emit-llvm","-c","-o","-"]
+    clang_args = [clang] + flags + ["-emit-llvm","-c","-o","-"]
+
+    llvmgcc_nm = capture_2(llvmgcc_args, nm_args)
+    clang_nm = capture_2(clang_args, nm_args)
+
+    llvmgcc_nm = normalize_nm(llvmgcc_nm)
+    clang_nm = normalize_nm(clang_nm)
+
+    if llvmgcc_nm == clang_nm:
+        sys.exit(0)
+
+    print ' '.join(llvmgcc_args), '|', ' '.join(nm_args)
+    print ' '.join(clang_args), '|', ' '.join(nm_args)
+    for line in difflib.unified_diff(llvmgcc_nm, clang_nm,
+                                     fromfile="llvm-gcc symbols",
+                                     tofile="clang symbols"):
+        print line
+    sys.exit(1)
+
+if __name__ == '__main__':
+    main()
diff --git a/utils/C++Tests/LLVM-Code-Symbols/lit.local.cfg b/utils/C++Tests/LLVM-Code-Symbols/lit.local.cfg
new file mode 100644
index 0000000..c328a25
--- /dev/null
+++ b/utils/C++Tests/LLVM-Code-Symbols/lit.local.cfg
@@ -0,0 +1,56 @@
+# -*- Python -*-
+
+# Configuration file for the 'lit' test runner.
+
+def getRoot(config):
+    if not config.parent:
+        return config
+    return getRoot(config.parent)
+
+root = getRoot(config)
+
+# testFormat: The test format to use to interpret tests.
+target_obj_root = root.llvm_obj_root
+cxxflags = ['-D__STDC_LIMIT_MACROS',
+            '-D__STDC_CONSTANT_MACROS',
+            '-Wno-sign-compare',
+            '-I%s/include' % root.llvm_src_root,
+            '-I%s/include' % root.llvm_obj_root,
+            '-I%s/lib/Target/Alpha' % root.llvm_src_root,
+            '-I%s/lib/Target/ARM' % root.llvm_src_root,
+            '-I%s/lib/Target/Blackfin' % root.llvm_src_root,
+            '-I%s/lib/Target/CBackend' % root.llvm_src_root,
+            '-I%s/lib/Target/CellSPU' % root.llvm_src_root,
+            '-I%s/lib/Target/CppBackend' % root.llvm_src_root,
+            '-I%s/lib/Target/Mips' % root.llvm_src_root,
+            '-I%s/lib/Target/MSIL' % root.llvm_src_root,
+            '-I%s/lib/Target/MSP430' % root.llvm_src_root,
+            '-I%s/lib/Target/PIC16' % root.llvm_src_root,
+            '-I%s/lib/Target/PowerPC' % root.llvm_src_root,
+            '-I%s/lib/Target/Sparc' % root.llvm_src_root,
+            '-I%s/lib/Target/SystemZ' % root.llvm_src_root,
+            '-I%s/lib/Target/X86' % root.llvm_src_root,
+            '-I%s/lib/Target/XCore' % root.llvm_src_root,
+            '-I%s/lib/Target/Alpha' % target_obj_root,
+            '-I%s/lib/Target/ARM' % target_obj_root,
+            '-I%s/lib/Target/Blackfin' % target_obj_root,
+            '-I%s/lib/Target/CBackend' % target_obj_root,
+            '-I%s/lib/Target/CellSPU' % target_obj_root,
+            '-I%s/lib/Target/CppBackend' % target_obj_root,
+            '-I%s/lib/Target/Mips' % target_obj_root,
+            '-I%s/lib/Target/MSIL' % target_obj_root,
+            '-I%s/lib/Target/MSP430' % target_obj_root,
+            '-I%s/lib/Target/PIC16' % target_obj_root,
+            '-I%s/lib/Target/PowerPC' % target_obj_root,
+            '-I%s/lib/Target/Sparc' % target_obj_root,
+            '-I%s/lib/Target/SystemZ' % target_obj_root,
+            '-I%s/lib/Target/X86' % target_obj_root,
+            '-I%s/lib/Target/XCore' % target_obj_root];
+
+kScript = os.path.join(os.path.dirname(__file__), "check-symbols")
+config.test_format = \
+  lit.formats.OneCommandPerFileTest(command=[kScript, root.clang] + cxxflags,
+                                    dir='%s/lib' % root.llvm_src_root,
+                                    recursive=True,
+                                    pattern='^(.*\\.cpp)$')
+
diff --git a/utils/C++Tests/LLVM-Code-Syntax/lit.local.cfg b/utils/C++Tests/LLVM-Code-Syntax/lit.local.cfg
new file mode 100644
index 0000000..6e67965
--- /dev/null
+++ b/utils/C++Tests/LLVM-Code-Syntax/lit.local.cfg
@@ -0,0 +1,54 @@
+# -*- Python -*-
+
+# Configuration file for the 'lit' test runner.
+
+def getRoot(config):
+    if not config.parent:
+        return config
+    return getRoot(config.parent)
+
+root = getRoot(config)
+
+# testFormat: The test format to use to interpret tests.
+target_obj_root = root.llvm_obj_root
+cxxflags = ['-D__STDC_LIMIT_MACROS',
+            '-D__STDC_CONSTANT_MACROS',
+            '-I%s/include' % root.llvm_src_root,
+            '-I%s/include' % root.llvm_obj_root,
+            '-I%s/lib/Target/Alpha' % root.llvm_src_root,
+            '-I%s/lib/Target/ARM' % root.llvm_src_root,
+            '-I%s/lib/Target/Blackfin' % root.llvm_src_root,
+            '-I%s/lib/Target/CBackend' % root.llvm_src_root,
+            '-I%s/lib/Target/CellSPU' % root.llvm_src_root,
+            '-I%s/lib/Target/CppBackend' % root.llvm_src_root,
+            '-I%s/lib/Target/Mips' % root.llvm_src_root,
+            '-I%s/lib/Target/MSIL' % root.llvm_src_root,
+            '-I%s/lib/Target/MSP430' % root.llvm_src_root,
+            '-I%s/lib/Target/PIC16' % root.llvm_src_root,
+            '-I%s/lib/Target/PowerPC' % root.llvm_src_root,
+            '-I%s/lib/Target/Sparc' % root.llvm_src_root,
+            '-I%s/lib/Target/SystemZ' % root.llvm_src_root,
+            '-I%s/lib/Target/X86' % root.llvm_src_root,
+            '-I%s/lib/Target/XCore' % root.llvm_src_root,
+            '-I%s/lib/Target/Alpha' % target_obj_root,
+            '-I%s/lib/Target/ARM' % target_obj_root,
+            '-I%s/lib/Target/Blackfin' % target_obj_root,
+            '-I%s/lib/Target/CBackend' % target_obj_root,
+            '-I%s/lib/Target/CellSPU' % target_obj_root,
+            '-I%s/lib/Target/CppBackend' % target_obj_root,
+            '-I%s/lib/Target/Mips' % target_obj_root,
+            '-I%s/lib/Target/MSIL' % target_obj_root,
+            '-I%s/lib/Target/MSP430' % target_obj_root,
+            '-I%s/lib/Target/PIC16' % target_obj_root,
+            '-I%s/lib/Target/PowerPC' % target_obj_root,
+            '-I%s/lib/Target/Sparc' % target_obj_root,
+            '-I%s/lib/Target/SystemZ' % target_obj_root,
+            '-I%s/lib/Target/X86' % target_obj_root,
+            '-I%s/lib/Target/XCore' % target_obj_root];
+
+config.test_format = \
+  lit.formats.OneCommandPerFileTest(command=[root.clang,
+                                             '-fsyntax-only'] + cxxflags,
+                                    dir='%s/lib' % root.llvm_src_root,
+                                    recursive=True,
+                                    pattern='^(.*\\.cpp)$')
diff --git a/utils/C++Tests/LLVM-Syntax/lit.local.cfg b/utils/C++Tests/LLVM-Syntax/lit.local.cfg
new file mode 100644
index 0000000..cb0e566
--- /dev/null
+++ b/utils/C++Tests/LLVM-Syntax/lit.local.cfg
@@ -0,0 +1,24 @@
+# -*- Python -*-
+
+# Configuration file for the 'lit' test runner.
+
+def getRoot(config):
+    if not config.parent:
+        return config
+    return getRoot(config.parent)
+
+root = getRoot(config)
+
+# testFormat: The test format to use to interpret tests.
+config.test_format = lit.formats.SyntaxCheckTest(compiler=root.clang,
+                                                 dir='%s/include/llvm' % root.llvm_src_root,
+                                                 recursive=True,
+                                                 pattern='^(.*\\.h|[^.]*)$',
+                                                 extra_cxx_args=['-D__STDC_LIMIT_MACROS',
+                                                                 '-D__STDC_CONSTANT_MACROS',
+                                                                 '-Werror',
+                                                                 '-I%s/include' % root.llvm_src_root,
+                                                                 '-I%s/include' % root.llvm_obj_root])
+
+config.excludes = ['AbstractTypeUser.h', 'DAGISelHeader.h',
+                   'AIXDataTypesFix.h', 'Solaris.h']
diff --git a/utils/C++Tests/lit.cfg b/utils/C++Tests/lit.cfg
new file mode 100644
index 0000000..274ca10
--- /dev/null
+++ b/utils/C++Tests/lit.cfg
@@ -0,0 +1,27 @@
+# -*- Python -*-
+
+# Configuration file for the 'lit' test runner.
+
+# Load the main clang test config so we can leech its clang finding logic.
+lit.load_config(config, os.path.join(os.path.dirname(__file__),
+                                     '..', '..', 'test', 'lit.cfg'))
+assert config.clang, "Failed to set clang!?"
+
+# name: The name of this test suite.
+config.name = 'Clang++'
+
+# suffixes: A list of file extensions to treat as test files, this is actually
+# set by on_clone().
+config.suffixes = []
+
+# Reset these from the Clang config.
+config.test_source_root = config.test_exec_root = None
+
+# Don't run Clang and LLVM code checks by default.
+config.excludes = []
+if not lit.params.get('run_clang_all'):
+    config.excludes.append('Clang-Code-Syntax')
+    config.excludes.append('Clang-Code-Compile')
+    config.excludes.append('LLVM-Code-Syntax')
+    config.excludes.append('LLVM-Code-Compile')
+    config.excludes.append('LLVM-Code-Symbols')
diff --git a/utils/C++Tests/stdc++-Syntax/lit.local.cfg b/utils/C++Tests/stdc++-Syntax/lit.local.cfg
new file mode 100644
index 0000000..eb04866
--- /dev/null
+++ b/utils/C++Tests/stdc++-Syntax/lit.local.cfg
@@ -0,0 +1,17 @@
+# -*- Python -*-
+
+# Configuration file for the 'lit' test runner.
+
+def getRoot(config):
+    if not config.parent:
+        return config
+    return getRoot(config.parent)
+
+root = getRoot(config)
+
+# testFormat: The test format to use to interpret tests.
+config.test_format = lit.formats.SyntaxCheckTest(compiler=root.clang,
+                                                 dir='/usr/include/c++/4.2.1',
+                                                 recursive=False,
+                                                 pattern='^(.*\\.h|[^.]*)$')
+
diff --git a/utils/CIndex/completion_logger_server.py b/utils/CIndex/completion_logger_server.py
new file mode 100755
index 0000000..0652b1f
--- /dev/null
+++ b/utils/CIndex/completion_logger_server.py
@@ -0,0 +1,44 @@
+#!/usr/bin/env python
+import sys
+from socket import *
+from time import strftime
+import datetime
+
+def main():
+  if len(sys.argv) < 4:
+    print "completion_logger_server.py <listen address> <listen port> <log file>"
+    exit(1)
+
+  host = sys.argv[1]
+  port = int(sys.argv[2])
+  buf = 1024 * 8
+  addr = (host,port)
+  
+  # Create socket and bind to address
+  UDPSock = socket(AF_INET,SOCK_DGRAM)
+  UDPSock.bind(addr)
+  
+  print "Listing on {0}:{1} and logging to '{2}'".format(host, port, sys.argv[3])
+
+  # Open the logging file.
+  f = open(sys.argv[3], "a")
+
+  # Receive messages
+  while 1:
+    data,addr = UDPSock.recvfrom(buf)
+    if not data:
+      break
+    else:
+      f.write("{ ");
+      f.write("\"time\": \"{0}\"".format(datetime.datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S')))
+      f.write(", \"sender\": \"{0}\" ".format(addr[0]))
+      f.write(", \"data\": ")
+      f.write(data)
+      f.write(" }\n")
+      f.flush()
+
+  # Close socket
+  UDPSock.close()
+
+if __name__ == '__main__':
+  main()
diff --git a/utils/CaptureCmd b/utils/CaptureCmd
new file mode 100755
index 0000000..705585c
--- /dev/null
+++ b/utils/CaptureCmd
@@ -0,0 +1,73 @@
+#!/usr/bin/env python
+
+"""CaptureCmd - A generic tool for capturing information about the
+invocations of another program.
+
+Usage
+--
+1. Move the original tool to a safe known location.
+
+2. Link CaptureCmd to the original tool's location.
+
+3. Define CAPTURE_CMD_PROGRAM to the known location of the original
+tool; this must be an absolute path.
+
+4. Define CAPTURE_CMD_DIR to a directory to write invocation
+information to.
+"""
+
+import hashlib
+import os
+import sys
+import time
+
+def saveCaptureData(prefix, dir, object):
+    string = repr(object) + '\n'
+    key = hashlib.sha1(string).hexdigest()
+    path = os.path.join(dir,
+                        prefix + key)
+    if not os.path.exists(path):
+        f = open(path, 'wb')
+        f.write(string)
+        f.close()
+    return prefix + key
+
+def main():
+    program = os.getenv('CAPTURE_CMD_PROGRAM')
+    dir = os.getenv('CAPTURE_CMD_DIR')
+    fallback = os.getenv('CAPTURE_CMD_FALLBACK')
+    if not program:
+        raise ValueError('CAPTURE_CMD_PROGRAM is not defined!')
+    if not dir:
+        raise ValueError('CAPTURE_CMD_DIR is not defined!')
+
+    # Make the output directory if it doesn't already exist.
+    if not os.path.exists(dir):
+        os.mkdir(dir, 0700)
+
+    # Get keys for various data.
+    env = os.environ.items()
+    env.sort()
+    envKey = saveCaptureData('env-', dir, env)
+    cwdKey = saveCaptureData('cwd-', dir, os.getcwd())
+    argvKey = saveCaptureData('argv-', dir, sys.argv)
+    entry = (time.time(), envKey, cwdKey, argvKey)
+    saveCaptureData('cmd-', dir, entry)
+
+    if fallback:
+        pid = os.fork()
+        if not pid:
+            os.execv(program, sys.argv)
+            os._exit(1)
+        else:
+            res = os.waitpid(pid, 0)
+            if not res:
+                os.execv(fallback, sys.argv)
+                os._exit(1)
+            os._exit(res)                
+    else:
+        os.execv(program, sys.argv)
+        os._exit(1)
+
+if __name__ == '__main__':
+    main()
diff --git a/utils/CmpDriver b/utils/CmpDriver
new file mode 100755
index 0000000..16b1081
--- /dev/null
+++ b/utils/CmpDriver
@@ -0,0 +1,210 @@
+#!/usr/bin/env python
+
+import subprocess
+
+def splitArgs(s):
+    it = iter(s)
+    current = ''
+    inQuote = False
+    for c in it:
+        if c == '"':
+            if inQuote:
+                inQuote = False
+                yield current + '"'
+            else:
+                inQuote = True
+                current = '"'
+        elif inQuote:
+            if c == '\\':
+                current += c
+                current += it.next()
+            else:
+                current += c
+        elif not c.isspace():
+            yield c
+
+def insertMinimumPadding(a, b, dist):
+    """insertMinimumPadding(a,b) -> (a',b')
+
+    Return two lists of equal length, where some number of Nones have
+    been inserted into the shorter list such that sum(map(dist, a',
+    b')) is minimized.
+
+    Assumes dist(X, Y) -> int and non-negative.
+    """
+    
+    def cost(a, b):
+        return sum(map(dist, a + [None] * (len(b) - len(a)), b))
+
+    # Normalize so a is shortest.
+    if len(b) < len(a):
+        b, a = insertMinimumPadding(b, a, dist)
+        return a,b
+
+    # For each None we have to insert...
+    for i in range(len(b) - len(a)):
+        # For each position we could insert it...
+        current = cost(a, b)
+        best = None
+        for j in range(len(a) + 1):
+            a_0 = a[:j] + [None] + a[j:]
+            candidate = cost(a_0, b)
+            if best is None or candidate < best[0]:
+                best = (candidate, a_0, j)
+        a = best[1]
+    return a,b
+
+class ZipperDiff(object):
+    """ZipperDiff - Simple (slow) diff only accomodating inserts."""
+    
+    def __init__(self, a, b):
+        self.a = a
+        self.b = b
+
+    def dist(self, a, b):
+        return a != b
+
+    def getDiffs(self):
+        a,b =  insertMinimumPadding(self.a, self.b, self.dist)
+        for aElt,bElt in zip(a,b):
+            if self.dist(aElt, bElt):
+                yield aElt,bElt
+
+class DriverZipperDiff(ZipperDiff):
+    def isTempFile(self, filename):
+        if filename[0] != '"' or filename[-1] != '"':
+            return False
+        return (filename.startswith('/tmp/', 1) or
+                filename.startswith('/var/', 1))
+
+    def dist(self, a, b):
+        if a and b and self.isTempFile(a) and self.isTempFile(b):
+            return 0
+        return super(DriverZipperDiff, self).dist(a,b)        
+
+class CompileInfo:
+    def __init__(self, out, err, res):
+        self.commands = []
+        
+        # Standard out isn't used for much.
+        self.stdout = out
+        self.stderr = ''
+
+        # FIXME: Compare error messages as well.
+        for ln in err.split('\n'):
+            if (ln == 'Using built-in specs.' or
+                ln.startswith('Target: ') or
+                ln.startswith('Configured with: ') or
+                ln.startswith('Thread model: ') or
+                ln.startswith('gcc version') or
+                ln.startswith('clang version')):
+                pass
+            elif ln.strip().startswith('"'):
+                self.commands.append(list(splitArgs(ln)))
+            else:
+                self.stderr += ln + '\n'
+        
+        self.stderr = self.stderr.strip()
+        self.exitCode = res
+
+def captureDriverInfo(cmd, args):
+    p = subprocess.Popen([cmd,'-###'] + args,
+                         stdin=None,
+                         stdout=subprocess.PIPE,
+                         stderr=subprocess.PIPE)
+    out,err = p.communicate()
+    res = p.wait()
+    return CompileInfo(out,err,res)
+
+def main():
+    import os, sys
+
+    args = sys.argv[1:]
+    driverA = os.getenv('DRIVER_A') or 'gcc'
+    driverB = os.getenv('DRIVER_B') or 'clang'
+
+    infoA = captureDriverInfo(driverA, args)
+    infoB = captureDriverInfo(driverB, args)
+
+    differ = False
+
+    # Compare stdout.
+    if infoA.stdout != infoB.stdout:
+        print '-- STDOUT DIFFERS -'
+        print 'A OUTPUT: ',infoA.stdout
+        print 'B OUTPUT: ',infoB.stdout
+        print
+
+        diff = ZipperDiff(infoA.stdout.split('\n'),
+                          infoB.stdout.split('\n'))
+        for i,(aElt,bElt) in enumerate(diff.getDiffs()):
+            if aElt is None:
+                print 'A missing: %s' % bElt
+            elif bElt is None:
+                print 'B missing: %s' % aElt
+            else:
+                print 'mismatch: A: %s' % aElt
+                print '          B: %s' % bElt
+
+        differ = True
+
+    # Compare stderr.
+    if infoA.stderr != infoB.stderr:
+        print '-- STDERR DIFFERS -'
+        print 'A STDERR: ',infoA.stderr
+        print 'B STDERR: ',infoB.stderr
+        print
+
+        diff = ZipperDiff(infoA.stderr.split('\n'),
+                          infoB.stderr.split('\n'))
+        for i,(aElt,bElt) in enumerate(diff.getDiffs()):
+            if aElt is None:
+                print 'A missing: %s' % bElt
+            elif bElt is None:
+                print 'B missing: %s' % aElt
+            else:
+                print 'mismatch: A: %s' % aElt
+                print '          B: %s' % bElt
+
+        differ = True
+
+    # Compare commands.
+    for i,(a,b) in enumerate(map(None, infoA.commands, infoB.commands)):
+        if a is None:
+            print 'A MISSING:',' '.join(b)
+            differ = True
+            continue
+        elif b is None:
+            print 'B MISSING:',' '.join(a)
+            differ = True
+            continue
+
+        diff = DriverZipperDiff(a,b)
+        diffs = list(diff.getDiffs())
+        if diffs:
+            print '-- COMMAND %d DIFFERS -' % i
+            print 'A COMMAND:',' '.join(a)
+            print 'B COMMAND:',' '.join(b)
+            print
+            for i,(aElt,bElt) in enumerate(diffs):
+                if aElt is None:
+                    print 'A missing: %s' % bElt
+                elif bElt is None:
+                    print 'B missing: %s' % aElt
+                else:
+                    print 'mismatch: A: %s' % aElt
+                    print '          B: %s' % bElt
+            differ = True
+    
+    # Compare result codes.
+    if infoA.exitCode != infoB.exitCode:
+        print '-- EXIT CODES DIFFER -'
+        print 'A: ',infoA.exitCode
+        print 'B: ',infoB.exitCode
+        differ = True
+
+    if differ:
+        sys.exit(1)
+
+if __name__ == '__main__':
+    main()
diff --git a/utils/FindSpecRefs b/utils/FindSpecRefs
new file mode 100755
index 0000000..9097f93
--- /dev/null
+++ b/utils/FindSpecRefs
@@ -0,0 +1,910 @@
+#!/usr/bin/env python
+
+import os
+import re
+import time
+from pprint import pprint
+
+###
+
+c99URL = 'http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf'
+c99TOC = [('Foreword', 'xi'),
+('Introduction', 'xiv'),
+('1. Scope', '1'),
+('2. Normative references', '2'),
+('3. Terms, definitions, and symbols', '3'),
+('4. Conformance', '7'),
+('5. Environment', '9'),
+('5.1 Conceptual models', '9'),
+('5.1.1 Translation environment', '9'),
+('5.1.2 Execution environments', '11'),
+('5.2 Environmental considerations', '17'),
+('5.2.1 Character sets', '17'),
+('5.2.2 Character display semantics', '19'),
+('5.2.3 Signals and interrupts', '20'),
+('5.2.4 Environmental limits', '20'),
+('6. Language', '29'),
+('6.1 Notation', '29'),
+('6.2 Concepts', '29'),
+('6.2.1 Scopes of identifiers', '29'),
+('6.2.2 Linkages of identifiers', '30'),
+('6.2.3 Name spaces of identifiers', '31'),
+('6.2.4 Storage durations of objects', '32'),
+('6.2.5 Types', '33'),
+('6.2.6 Representations of types', '37'),
+('6.2.7 Compatible type and composite type', '40'),
+('6.3 Conversions', '42'),
+('6.3.1 Arithmetic operands', '42'),
+('6.3.2 Other operands', '46'),
+('6.4 Lexical elements', '49'),
+('6.4.1 Keywords', '50'),
+('6.4.2 Identifiers', '51'),
+('6.4.3 Universal character names', '53'),
+('6.4.4 Constants', '54'),
+('6.4.5 String literals', '62'),
+('6.4.6 Punctuators', '63'),
+('6.4.7 Header names', '64'),
+('6.4.8 Preprocessing numbers', '65'),
+('6.4.9 Comments', '66'),
+('6.5 Expressions', '67'),
+('6.5.1 Primary expressions', '69'),
+('6.5.2 Postfix operators', '69'),
+('6.5.3 Unary operators', '78'),
+('6.5.4 Cast operators', '81'),
+('6.5.5 Multiplicative operators', '82'),
+('6.5.6 Additive operators', '82'),
+('6.5.7 Bitwise shift operators', '84'),
+('6.5.8 Relational operators', '85'),
+('6.5.9 Equality operators', '86'),
+('6.5.10 Bitwise AND operator', '87'),
+('6.5.11 Bitwise exclusive OR operator', '88'),
+('6.5.12 Bitwise inclusive OR operator', '88'),
+('6.5.13 Logical AND operator', '89'),
+('6.5.14 Logical OR operator', '89'),
+('6.5.15 Conditional operator', '90'),
+('6.5.16 Assignment operators', '91'),
+('6.5.17 Comma operator', '94'),
+('6.6 Constant expressions', '95'),
+('6.7 Declarations', '97'),
+('6.7.1 Storage-class specifiers', '98'),
+('6.7.2 Type specifiers', '99'),
+('6.7.3 Type qualifiers', '108'),
+('6.7.4 Function specifiers', '112'),
+('6.7.5 Declarators', '114'),
+('6.7.6 Type names', '122'),
+('6.7.7 Type definitions', '123'),
+('6.7.8 Initialization', '125'),
+('6.8 Statements and blocks', '131'),
+('6.8.1 Labeled statements', '131'),
+('6.8.2 Compound statement', '132'),
+('6.8.3 Expression and null statements', '132'),
+('6.8.4 Selection statements', '133'),
+('6.8.5 Iteration statements', '135'),
+('6.8.6 Jump statements', '136'),
+('6.9 External definitions', '140'),
+('6.9.1 Function definitions', '141'),
+('6.9.2 External object definitions', '143'),
+('6.10 Preprocessing directives', '145'),
+('6.10.1 Conditional inclusion', '147'),
+('6.10.2 Source file inclusion', '149'),
+('6.10.3 Macro replacement', '151'),
+('6.10.4 Line control', '158'),
+('6.10.5 Error directive', '159'),
+('6.10.6 Pragma directive', '159'),
+('6.10.7 Null directive', '160'),
+('6.10.8 Predefined macro names', '160'),
+('6.10.9 Pragma operator', '161'),
+('6.11 Future language directions', '163'),
+('6.11.1 Floating types', '163'),
+('6.11.2 Linkages of identifiers', '163'),
+('6.11.3 External names', '163'),
+('6.11.4 Character escape sequences', '163'),
+('6.11.5 Storage-class specifiers', '163'),
+('6.11.6 Function declarators', '163'),
+('6.11.7 Function definitions', '163'),
+('6.11.8 Pragma directives', '163'),
+('6.11.9 Predefined macro names', '163'),
+('7. Library', '164'),
+('7.1 Introduction', '164'),
+('7.1.1 Definitions of terms', '164'),
+('7.1.2 Standard headers', '165'),
+('7.1.3 Reserved identifiers', '166'),
+('7.1.4 Use of library functions', '166'),
+('7.2 Diagnostics <assert.h>', '169'),
+('7.2.1 Program diagnostics', '169'),
+('7.3 Complex arithmetic <complex.h>', '170'),
+('7.3.1 Introduction', '170'),
+('7.3.2 Conventions', '170'),
+('7.3.3 Branch cuts', '171'),
+('7.3.4 The CX_LIMITED_RANGE pragma', '171'),
+('7.3.5 Trigonometric functions', '172'),
+('7.3.6 Hyperbolic functions', '174'),
+('7.3.7 Exponential and logarithmic functions', '176'),
+('7.3.8 Power and absolute-value functions', '177'),
+('7.3.9 Manipulation functions', '178'),
+('7.4 Character handling <ctype.h>', '181'),
+('7.4.1 Character classification functions', '181'),
+('7.4.2 Character case mapping functions', '184'),
+('7.5 Errors <errno.h>', '186'),
+('7.6 Floating-point environment <fenv.h>', '187'),
+('7.6.1 The FENV_ACCESS pragma', '189'),
+('7.6.2 Floating-point exceptions', '190'),
+('7.6.3 Rounding', '193'),
+('7.6.4 Environment', '194'),
+('7.7 Characteristics of floating types <float.h>', '197'),
+('7.8 Format conversion of integer types <inttypes.h>', '198'),
+('7.8.1 Macros for format specifiers', '198'),
+('7.8.2 Functions for greatest-width integer types', '199'),
+('7.9 Alternative spellings <iso646.h>', '202'),
+('7.10 Sizes of integer types <limits.h>', '203'),
+('7.11 Localization <locale.h>', '204'),
+('7.11.1 Locale control', '205'),
+('7.11.2 Numeric formatting convention inquiry', '206'),
+('7.12 Mathematics <math.h>', '212'),
+('7.12.1 Treatment of error conditions', '214'),
+('7.12.2 The FP_CONTRACT pragma', '215'),
+('7.12.3 Classification macros', '216'),
+('7.12.4 Trigonometric functions', '218'),
+('7.12.5 Hyperbolic functions', '221'),
+('7.12.6 Exponential and logarithmic functions', '223'),
+('7.12.7 Power and absolute-value functions', '228'),
+('7.12.8 Error and gamma functions', '230'),
+('7.12.9 Nearest integer functions', '231'),
+('7.12.10 Remainder functions', '235'),
+('7.12.11 Manipulation functions', '236'),
+('7.12.12 Maximum, minimum, and positive difference functions', '238'),
+('7.12.13 Floating multiply-add', '239'),
+('7.12.14 Comparison macros', '240'),
+('7.13 Nonlocal jumps <setjmp.h>', '243'),
+('7.13.1 Save calling environment', '243'),
+('7.13.2 Restore calling environment', '244'),
+('7.14 Signal handling <signal.h>', '246'),
+('7.14.1 Specify signal handling', '247'),
+('7.14.2 Send signal', '248'),
+('7.15 Variable arguments <stdarg.h>', '249'),
+('7.15.1 Variable argument list access macros', '249'),
+('7.16 Boolean type and values <stdbool.h>', '253'),
+('7.17 Common definitions <stddef.h>', '254'),
+('7.18 Integer types <stdint.h>', '255'),
+('7.18.1 Integer types', '255'),
+('7.18.2 Limits of specified-width integer types', '257'),
+('7.18.3 Limits of other integer types', '259'),
+('7.18.4 Macros for integer constants', '260'),
+('7.19 Input/output <stdio.h>', '262'),
+('7.19.1 Introduction', '262'),
+('7.19.2 Streams', '264'),
+('7.19.3 Files', '266'),
+('7.19.4 Operations on files', '268'),
+('7.19.5 File access functions', '270'),
+('7.19.6 Formatted input/output functions', '274'),
+('7.19.7 Character input/output functions', '296'),
+('7.19.8 Direct input/output functions', '301'),
+('7.19.9 File positioning functions', '302'),
+('7.19.10 Error-handling functions', '304'),
+('7.20 General utilities <stdlib.h>', '306'),
+('7.20.1 Numeric conversion functions', '307'),
+('7.20.2 Pseudo-random sequence generation functions', '312'),
+('7.20.3 Memory management functions', '313'),
+('7.20.4 Communication with the environment', '315'),
+('7.20.5 Searching and sorting utilities', '318'),
+('7.20.6 Integer arithmetic functions', '320'),
+('7.20.7 Multibyte/wide character conversion functions', '321'),
+('7.20.8 Multibyte/wide string conversion functions', '323'),
+('7.21 String handling <string.h>', '325'),
+('7.21.1 String function conventions', '325'),
+('7.21.2 Copying functions', '325'),
+('7.21.3 Concatenation functions', '327'),
+('7.21.4 Comparison functions', '328'),
+('7.21.5 Search functions', '330'),
+('7.21.6 Miscellaneous functions', '333'),
+('7.22 Type-generic math <tgmath.h>', '335'),
+('7.23 Date and time <time.h>', '338'),
+('7.23.1 Components of time', '338'),
+('7.23.2 Time manipulation functions', '339'),
+('7.23.3 Time conversion functions', '341'),
+('7.24 Extended multibyte and wide character utilities <wchar.h>', '348'),
+('7.24.1 Introduction', '348'),
+('7.24.2 Formatted wide character input/output functions', '349'),
+('7.24.3 Wide character input/output functions', '367'),
+('7.24.4 General wide string utilities', '371'),
+('7.24.5 Wide character time conversion functions', '385'),
+('7.24.6 Extended multibyte/wide character conversion utilities', '386'),
+('7.25 Wide character classification and mapping utilities <wctype.h>',
+  '393'),
+('7.25.1 Introduction', '393'),
+('7.25.2 Wide character classification utilities', '394'),
+('7.25.3 Wide character case mapping utilities', '399'),
+('7.26 Future library directions', '401'),
+('7.26.1 Complex arithmetic <complex.h>', '401'),
+('7.26.2 Character handling <ctype.h>', '401'),
+('7.26.3 Errors <errno.h>', '401'),
+('7.26.4 Format conversion of integer types <inttypes.h>', '401'),
+('7.26.5 Localization <locale.h>', '401'),
+('7.26.6 Signal handling <signal.h>', '401'),
+('7.26.7 Boolean type and values <stdbool.h>', '401'),
+('7.26.8 Integer types <stdint.h>', '401'),
+('7.26.9 Input/output <stdio.h>', '402'),
+('7.26.10 General utilities <stdlib.h>', '402'),
+('7.26.11 String handling <string.h>', '402'),
+('<wchar.h>', '402'),
+('<wctype.h>', '402'),
+('Annex A (informative) Language syntax summary', '403'),
+('A.1 Lexical grammar', '403'),
+('A.2 Phrase structure grammar', '409'),
+('A.3 Preprocessing directives', '416'),
+('Annex B (informative) Library summary', '418'),
+('B.1 Diagnostics <assert.h>', '418'),
+('B.2 Complex <complex.h>', '418'),
+('B.3 Character handling <ctype.h>', '420'),
+('B.4 Errors <errno.h>', '420'),
+('B.5 Floating-point environment <fenv.h>', '420'),
+('B.6 Characteristics of floating types <float.h>', '421'),
+('B.7 Format conversion of integer types <inttypes.h>', '421'),
+('B.8 Alternative spellings <iso646.h>', '422'),
+('B.9 Sizes of integer types <limits.h>', '422'),
+('B.10 Localization <locale.h>', '422'),
+('B.11 Mathematics <math.h>', '422'),
+('B.12 Nonlocal jumps <setjmp.h>', '427'),
+('B.13 Signal handling <signal.h>', '427'),
+('B.14 Variable arguments <stdarg.h>', '427'),
+('B.15 Boolean type and values <stdbool.h>', '427'),
+('B.16 Common definitions <stddef.h>', '428'),
+('B.17 Integer types <stdint.h>', '428'),
+('B.18 Input/output <stdio.h>', '428'),
+('B.19 General utilities <stdlib.h>', '430'),
+('B.20 String handling <string.h>', '432'),
+('B.21 Type-generic math <tgmath.h>', '433'),
+('B.22 Date and time <time.h>', '433'),
+('B.23 Extended multibyte/wide character utilities <wchar.h>', '434'),
+('B.24 Wide character classification and mapping utilities <wctype.h>',
+  '436'),
+('Annex C (informative) Sequence points', '438'),
+('Annex D (normative) Universal character names for identifiers', '439'),
+('Annex E (informative) Implementation limits', '441'),
+('Annex F (normative) IEC 60559 floating-point arithmetic', '443'),
+('F.1 Introduction', '443'),
+('F.2 Types', '443'),
+('F.3 Operators and functions', '444'),
+('F.4 Floating to integer conversion', '446'),
+('F.5 Binary-decimal conversion', '446'),
+('F.6 Contracted expressions', '447'),
+('F.7 Floating-point environment', '447'),
+('F.8 Optimization', '450'),
+('F.9 Mathematics <math.h>', '453'),
+('Annex G (informative) IEC 60559-compatible complex arithmetic', '466'),
+('G.1 Introduction', '466'),
+('G.2 Types', '466'),
+('G.3 Conventions', '466'),
+('G.4 Conversions', '467'),
+('G.5 Binary operators', '467'),
+('G.6 Complex arithmetic <complex.h>', '471'),
+('G.7 Type-generic math <tgmath.h>', '479'),
+('Annex H (informative) Language independent arithmetic', '480'),
+('H.1 Introduction', '480'),
+('H.2 Types', '480'),
+('H.3 Notification', '484'),
+('Annex I (informative) Common warnings', '486'),
+('Annex J (informative) Portability issues', '488'),
+('J.1 Unspecified behavior', '488'),
+('J.2 Undefined behavior', '491'),
+('J.3 Implementation-defined behavior', '504'),
+('J.4 Locale-specific behavior', '511'),
+('J.5 Common extensions', '512'),
+('Bibliography', '515'),
+('Index', '517')]
+
+cXXURL = 'http://open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2723.pdf'
+cXXTOC = [('Contents', 'ii'),
+('List of Tables', 'ix'),
+('1 General', '1'),
+('1.1 Scope', '1'),
+('1.2 Normative references', '1'),
+('1.3 Definitions', '2'),
+('1.4 Implementation compliance', '4'),
+('1.5 Structure of this International Standard', '5'),
+('1.6 Syntax notation', '5'),
+('1.7 The C++ memory model', '6'),
+('1.8 The C++ object model', '6'),
+('1.9 Program execution', '7'),
+('1.10 Multi-threaded executions and data races', '10'),
+('1.11 Acknowledgments', '13'),
+('2 Lexical conventions', '15'),
+('2.1 Phases of translation', '15'),
+('2.2 Character sets', '16'),
+('2.3 Trigraph sequences', '17'),
+('2.4 Preprocessing tokens', '17'),
+('2.5 Alternative tokens', '18'),
+('2.6 Tokens', '19'),
+('2.7 Comments', '19'),
+('2.8 Header names', '19'),
+('2.9 Preprocessing numbers', '20'),
+('2.10 Identifiers', '20'),
+('2.11 Keywords', '20'),
+('2.12 Operators and punctuators', '21'),
+('2.13 Literals', '21'),
+('3 Basic concepts', '29'),
+('3.1 Declarations and definitions', '29'),
+('3.2 One definition rule', '31'),
+('3.3 Declarative regions and scopes', '33'),
+('3.4 Name lookup', '38'),
+('3.5 Program and linkage', '51'),
+('3.6 Start and termination', '54'),
+('3.7 Storage duration', '58'),
+('3.8 Object Lifetime', '62'),
+('3.9 Types', '65'),
+('3.10 Lvalues and rvalues', '70'),
+('3.11 Alignment', '72'),
+('4 Standard conversions', '73'),
+('4.1 Lvalue-to-rvalue conversion', '74'),
+('4.2 Array-to-pointer conversion', '74'),
+('4.3 Function-to-pointer conversion', '74'),
+('4.4 Qualification conversions', '74'),
+('4.5 Integral promotions', '75'),
+('4.6 Floating point promotion', '76'),
+('4.7 Integral conversions', '76'),
+('4.8 Floating point conversions', '76'),
+('4.9 Floating-integral conversions', '77'),
+('4.10 Pointer conversions', '77'),
+('4.11 Pointer to member conversions', '77'),
+('4.12 Boolean conversions', '78'),
+('4.13 Integer conversion rank', '78'),
+('5 Expressions', '79'),
+('5.1 Primary expressions', '80'),
+('5.2 Postfix expressions', '85'),
+('5.3 Unary expressions', '96'),
+('5.4 Explicit type conversion (cast notation)', '104'),
+('5.5 Pointer-to-member operators', '105'),
+('5.6 Multiplicative operators', '106'),
+('5.7 Additive operators', '106'),
+('5.8 Shift operators', '107'),
+('5.9 Relational operators', '108'),
+('5.10 Equality operators', '109'),
+('5.11 Bitwise AND operator', '110'),
+('5.12 Bitwise exclusive OR operator', '110'),
+('5.13 Bitwise inclusive OR operator', '110'),
+('5.14 Logical AND operator', '110'),
+('5.15 Logical OR operator', '110'),
+('5.16 Conditional operator', '111'),
+('5.17 Assignment and compound assignment operators', '112'),
+('5.18 Comma operator', '113'),
+('5.19 Constant expressions', '113'),
+('6 Statements', '116'),
+('6.1 Labeled statement', '116'),
+('6.2 Expression statement', '116'),
+('6.3 Compound statement or block', '116'),
+('6.4 Selection statements', '117'),
+('6.5 Iteration statements', '118'),
+('6.6 Jump statements', '121'),
+('6.7 Declaration statement', '122'),
+('6.8 Ambiguity resolution', '123'),
+('7 Declarations', '125'),
+('7.1 Specifiers', '126'),
+('7.2 Enumeration declarations', '140'),
+('7.3 Namespaces', '143'),
+('7.4 The asm declaration', '156'),
+('7.5 Linkage specifications', '156'),
+('8 Declarators', '160'),
+('8.1 Type names', '161'),
+('8.2 Ambiguity resolution', '161'),
+('8.3 Meaning of declarators', '163'),
+('8.4 Function definitions', '175'),
+('8.5 Initializers', '177'),
+('9 Classes', '191'),
+('9.1 Class names', '193'),
+('9.2 Class members', '194'),
+('9.3 Member functions', '197'),
+('9.4 Static members', '200'),
+('9.5 Unions', '202'),
+('9.6 Bit-fields', '203'),
+('9.7 Nested class declarations', '204'),
+('9.8 Local class declarations', '205'),
+('9.9 Nested type names', '206'),
+('10 Derived classes', '207'),
+('10.1 Multiple base classes', '208'),
+('10.2 Member name lookup', '210'),
+('10.3 Virtual functions', '213'),
+('10.4 Abstract classes', '217'),
+('11 Member access control', '219'),
+('11.1 Access specifiers', '221'),
+('11.2 Accessibility of base classes and base class members', '222'),
+('11.3 Access declarations', '224'),
+('11.4 Friends', '225'),
+('11.5 Protected member access', '228'),
+('11.6 Access to virtual functions', '229'),
+('11.7 Multiple access', '230'),
+('11.8 Nested classes', '230'),
+('12 Special member functions', '231'),
+('12.1 Constructors', '231'),
+('12.2 Temporary objects', '233'),
+('12.3 Conversions', '235'),
+('12.4 Destructors', '238'),
+('12.5 Free store', '240'),
+('12.6 Initialization', '242'),
+('12.7 Construction and destruction', '247'),
+('12.8 Copying class objects', '250'),
+('12.9 Inheriting Constructors', '255'),
+('13 Overloading', '259'),
+('13.1 Overloadable declarations', '259'),
+('13.2 Declaration matching', '261'),
+('13.3 Overload resolution', '262'),
+('13.4 Address of overloaded function', '281'),
+('13.5 Overloaded operators', '282'),
+('13.6 Built-in operators', '286'),
+('14 Templates', '290'),
+('14.1 Template parameters', '291'),
+('14.2 Names of template specializations', '294'),
+('14.3 Template arguments', '296'),
+('14.4 Type equivalence', '302'),
+('14.5 Template declarations', '303'),
+('14.6 Name resolution', '318'),
+('14.7 Template instantiation and specialization', '331'),
+('14.8 Function template specializations', '343'),
+('15 Exception handling', '363'),
+('15.1 Throwing an exception', '364'),
+('15.2 Constructors and destructors', '366'),
+('15.3 Handling an exception', '366'),
+('15.4 Exception specifications', '368'),
+('15.5 Special functions', '371'),
+('15.6 Exceptions and access', '372'),
+('16 Preprocessing directives', '373'),
+('16.1 Conditional inclusion', '375'),
+('16.2 Source file inclusion', '376'),
+('16.3 Macro replacement', '377'),
+('16.4 Line control', '382'),
+('16.5 Error directive', '383'),
+('16.6 Pragma directive', '383'),
+('16.7 Null directive', '383'),
+('16.8 Predefined macro names', '383'),
+('16.9 Pragma operator', '384'),
+('17 Library introduction', '386'),
+('17.1 General', '386'),
+('17.2 Overview', '386'),
+('17.3 Definitions', '386'),
+('17.4 Additional definitions', '390'),
+('17.5 Method of description (Informative)', '390'),
+('17.6 Library-wide requirements', '396'),
+('18 Language support library', '407'),
+('18.1 Types', '407'),
+('18.2 Implementation properties', '408'),
+('18.3 Integer types', '417'),
+('18.4 Start and termination', '418'),
+('18.5 Dynamic memory management', '420'),
+('18.6 Type identification', '424'),
+('18.7 Exception handling', '427'),
+('18.8 Initializer lists', '432'),
+('18.9 Other runtime support', '434'),
+('19 Diagnostics library', '435'),
+('19.1 Exception classes', '435'),
+('19.2 Assertions', '439'),
+('19.3 Error numbers', '440'),
+('19.4 System error support', '440'),
+('20 General utilities library', '452'),
+('20.1 Requirements', '452'),
+('20.2 Utility components', '457'),
+('20.3 Compile-time rational arithmetic', '463'),
+('20.4 Tuples', '465'),
+('20.5 Metaprogramming and type traits', '473'),
+('20.6 Function objects', '486'),
+('20.7 Memory', '509'),
+('20.8 Time utilities', '548'),
+('20.9 Date and time functions', '562'),
+('21 Strings library', '563'),
+('21.1 Character traits', '563'),
+('21.2 String classes', '569'),
+('21.3 Class template basic_string', '572'),
+('21.4 Numeric Conversions', '599'),
+('21.5 Null-terminated sequence utilities', '600'),
+('22 Localization library', '604'),
+('22.1 Locales', '604'),
+('22.2 Standard locale categories', '617'),
+('22.3 Standard code conversion facets', '657'),
+('22.4 C Library Locales', '659'),
+('23 Containers library', '660'),
+('23.1 Container requirements', '660'),
+('23.2 Sequence containers', '681'),
+('23.3 Associative containers', '719'),
+('23.4 Unordered associative containers', '744'),
+('24 Iterators library', '759'),
+('24.1 Iterator requirements', '759'),
+('24.2 Header <iterator> synopsis', '764'),
+('24.3 Iterator primitives', '767'),
+('24.4 Predefined iterators', '770'),
+('24.5 Stream iterators', '784'),
+('25 Algorithms library', '792'),
+('25.1 Non-modifying sequence operations', '802'),
+('25.2 Mutating sequence operations', '806'),
+('25.3 Sorting and related operations', '815'),
+('25.4 C library algorithms', '829'),
+('26 Numerics library', '831'),
+('26.1 Numeric type requirements', '831'),
+('26.2 The floating-point environment', '832'),
+('26.3 Complex numbers', '833'),
+('26.4 Random number generation', '842'),
+('26.5 Numeric arrays', '884'),
+('26.6 Generalized numeric operations', '904'),
+('26.7 C Library', '907'),
+('27 Input/output library', '912'),
+('27.1 Iostreams requirements', '912'),
+('27.2 Forward declarations', '912'),
+('27.3 Standard iostream objects', '915'),
+('27.4 Iostreams base classes', '916'),
+('27.5 Stream buffers', '934'),
+('27.6 Formatting and manipulators', '944'),
+('27.7 String-based streams', '972'),
+('27.8 File-based streams', '984'),
+('28 Regular expressions library', '1000'),
+('28.1 Definitions', '1000'),
+('28.2 Requirements', '1000'),
+('28.3 Regular expressions summary', '1002'),
+('28.4 Header <regex> synopsis', '1003'),
+('28.5 Namespace std::regex_constants', '1009'),
+('28.6 Class regex_error', '1012'),
+('28.7 Class template regex_traits', '1012'),
+('28.8 Class template basic_regex', '1015'),
+('28.9 Class template sub_match', '1020'),
+('28.10Class template match_results', '1025'),
+('28.11Regular expression algorithms', '1029'),
+('28.12Regular expression Iterators', '1033'),
+('28.13Modified ECMAScript regular expression grammar', '1039'),
+('29 Atomic operations library', '1042'),
+('29.1 Order and Consistency', '1044'),
+('29.2 Lock-free Property', '1046'),
+('29.3 Atomic Types', '1046'),
+('29.4 Operations on Atomic Types', '1051'),
+('29.5 Flag Type and Operations', '1054'),
+('30 Thread support library', '1057'),
+('30.1 Requirements', '1057'),
+('30.2 Threads', '1058'),
+('30.3 Mutual exclusion', '1063'),
+('30.4 Condition variables', '1077'),
+('A Grammar summary', '1085'),
+('A.1 Keywords', '1085'),
+('A.2 Lexical conventions', '1085'),
+('A.3 Basic concepts', '1089'),
+('A.4 Expressions', '1090'),
+('A.5 Statements', '1093'),
+('A.6 Declarations', '1094'),
+('A.7 Declarators', '1097'),
+('A.8 Classes', '1098'),
+('A.9 Derived classes', '1099'),
+('A.10 Special member functions', '1099'),
+('A.11 Overloading', '1100'),
+('A.12 Templates', '1100'),
+('A.13 Exception handling', '1101'),
+('A.14 Preprocessing directives', '1101'),
+('B Implementation quantities', '1103'),
+('C Compatibility', '1105'),
+('C.1 C++ and ISO C', '1105'),
+('C.2 Standard C library', '1114'),
+('D Compatibility features', '1119'),
+('D.1 Increment operator with bool operand', '1119'),
+('D.2 static keyword', '1119'),
+('D.3 Access declarations', '1119'),
+('D.4 Implicit conversion from const strings', '1119'),
+('D.5 C standard library headers', '1119'),
+('D.6 Old iostreams members', '1120'),
+('D.7 char* streams', '1121'),
+('D.8 Binders', '1130'),
+('D.9 auto_ptr', '1132'),
+('E Universal-character-names', '1135'),
+('F Cross references', '1137'),
+('Index', '1153')]
+
+kDocuments = {
+    'C99' : (c99URL, c99TOC, 12),
+    'C++' : (cXXURL, cXXTOC, 12),
+}
+
+def findClosestTOCEntry(data, target):
+    # FIXME: Fix for named spec references
+    if isinstance(target[0],str):
+        return ('.'.join(target),'<named>',1)
+
+    offset = data[2]
+    best = None
+    for (name,page) in data[1]:
+        if ' ' in name:
+            section,name = name.split(' ',1)
+            if section == 'Annex':
+                section,name = name.split(' ',1)
+                section = 'Annex '+section
+        else:
+            section = None
+        try:
+            page = int(page) + offset
+        except:
+            page = 1
+        try:
+            spec = SpecIndex.fromstring(section)
+        except:
+            spec = None
+
+        # Meh, could be better...
+        if spec is not None:
+            dist = spec - target
+            if best is None or dist < best[0]:
+                best = (dist, (section, name, page))
+    return best[1]
+
+# What a hack. Slow to boot.
+doxyLineRefRE = re.compile(r"<a name=\"l([0-9]+)\"></a>")
+def findClosestLineReference(clangRoot, doxyName, target):
+    try:
+        f = open(os.path.join(clangRoot, 'docs', 'doxygen', 'html', doxyName))
+    except:
+        return None
+    
+    best = None
+    for m in doxyLineRefRE.finditer(f.read()):
+        line = int(m.group(1), 10)
+        dist = abs(line - target)
+        if best is None or dist < best[0]:
+            best = (dist,'l'+m.group(1))
+    f.close()
+    if best is not None:
+        return best[1]
+    return None
+
+###
+
+nameAndSpecRefRE = re.compile(r"(C99|C90|C\+\+|H\&S) ((([0-9]+)(\.[0-9]+)*|\[[^]]+\])(p[0-9]+)?)")
+loneSpecRefRE = re.compile(r" (([0-9]+)(\.[0-9]+){2,100}(p[0-9]+)?)")
+def scanFile(path, filename):
+    try:
+        f = open(path)
+    except IOError:
+        print >>sys.stderr,'WARNING: Unable to open:',path
+        return
+
+    for i,ln in enumerate(f):
+        ignore = set()
+        for m in nameAndSpecRefRE.finditer(ln):
+            section = m.group(2)
+            name = m.group(1)
+            if section.endswith('.'):
+                section = section[:-1]
+            yield RefItem(name, section, filename, path, i+1)
+            ignore.add(section)
+        for m in loneSpecRefRE.finditer(ln):
+            section = m.group(1)
+            if section.endswith('.'):
+                section = section[:-1]
+            if section not in ignore:
+                yield RefItem(None, section, filename, path, i+1)
+
+###
+
+class SpecIndex:
+    @staticmethod
+    def fromstring(str):
+        # Check for named sections
+        if str[0] == '[':
+            assert ']' in str
+            secs = str[1:str.index(']')].split('.')
+            tail = str[str.index(']')+1:]
+            if tail:
+                assert tail[0] == 'p'
+                paragraph = int(tail[1:])
+            else:
+                paragraph = None
+            indices = secs
+        else:
+            secs = str.split('.')
+            paragraph = None
+            if 'p' in secs[-1]:
+                secs[-1],p = secs[-1].split('p',1)
+                paragraph = int(p)
+            indices = map(int, secs)
+        return SpecIndex(indices, paragraph)
+
+    def __init__(self, indices, paragraph=None):
+        assert len(indices)>0
+        self.indices = tuple(indices)
+        self.paragraph = paragraph
+
+    def __str__(self):
+        s =  '.'.join(map(str,self.indices))
+        if self.paragraph is not None:
+            s += '.p%d'%(self.paragraph,)
+        return s                            
+
+    def __repr__(self):
+        return 'SpecIndex(%s, %s)'%(self.indices, self.paragraph)
+
+    def __cmp__(self, b):
+        return cmp((self.indices,self.paragraph),
+                   (b.indices,b.paragraph))
+
+    def __hash__(self):
+        return hash((self.indices,self.paragraph))
+
+    def __sub__(self, indices):
+        def sub(a,b):
+            a = a or 0
+            b = b or 0
+            return abs(a-b)
+        return map(sub,self.indices,indices)
+
+class RefItem:
+    def __init__(self, name, section, filename, path, line):
+        self.name = name
+        self.section = SpecIndex.fromstring(section)
+        self.filename = filename
+        self.path = path
+        self.line = line
+    
+    def __str__(self):
+        if self.name is not None:
+            return '%s %s'%(self.name, self.section)
+        else:
+            return '--- %s'%(self.section,)
+
+    def __repr__(self):
+        return 'RefItem(%s, %r, "%s", "%s", %d)'%(self.name, 
+                                              self.section,
+                                              self.filename,
+                                              self.path,
+                                              self.line)
+
+    def __cmp__(self, b):
+        return cmp((self.name,self.section,self.filename,self.path,self.line),
+                   (b.name,b.section,self.filename,self.path,self.line))
+
+    def __hash__(self):
+        return hash((self.name,self.section,self.filename,self.path,self.line))
+
+###
+
+def sorted(l):
+    l = list(l)
+    l.sort()
+    return l
+
+def getRevision(path):
+    import subprocess
+    p = subprocess.Popen(['svn', 'info', path],
+                         stdin=open('/dev/null','r'), 
+                         stdout=subprocess.PIPE)
+    for ln in p.stdout.read(1024).split('\n'):
+        if ln.startswith('Revision:'):
+            return ln.split(':',1)[1].strip()
+    return None
+
+def buildRefTree(references):
+    root = (None, {}, [])
+
+    def getNode(keys):
+        if not keys:
+            return root
+        key,parent = keys[-1],getNode(keys[:-1])
+        node = parent[1].get(key)
+        if node is None:
+            parent[1][key] = node = (key, {}, [])
+        return node
+            
+    for ref in references:
+        n = getNode((ref.name,) + ref.section.indices)
+        n[2].append(ref)
+
+    def flatten((key, children, data)):
+        children = sorted(map(flatten,children.values()))
+        return (key, children, sorted(data))
+
+    return flatten(root)
+
+def preorder(node,parents=(),first=True):
+    (key,children,data) = node
+    if first:
+        yield parents+(node,)
+    for c in children:
+        for item in preorder(c, parents+(node,)):
+            yield item
+
+def main():
+    global options
+    from optparse import OptionParser
+    parser = OptionParser("usage: %prog [options] CLANG_ROOT <output-dir>")
+    parser.add_option("", "--debug", dest="debug",
+                      help="Print extra debugging output",
+                      action="store_true",
+                      default=False)    
+    (opts, args) = parser.parse_args()
+
+    if len(args) != 2:
+        parser.error("incorrect number of arguments")
+
+    references = []
+    root,outputDir = args
+    if os.path.isdir(root):
+        for (dirpath, dirnames, filenames) in os.walk(root):
+            for filename in filenames:
+                name,ext = os.path.splitext(filename)
+                if ext in ('.c', '.cpp', '.h', '.def'):
+                    fullpath = os.path.join(dirpath, filename)                
+                    references.extend(list(scanFile(fullpath, filename)))
+    else:
+        references.extend(list(scanFile(root, root)))
+
+    refTree = buildRefTree(references)
+
+    specs = {}
+    for ref in references:
+        spec = specs[ref.name] = specs.get(ref.name,{})
+        items = spec[ref.section] = spec.get(ref.section,[])
+        items.append(ref)
+
+    print 'Found %d references.'%(len(references),)
+
+    if opts.debug:
+        pprint(refTree)
+
+    referencesPath = os.path.join(outputDir,'references.html')
+    print 'Writing: %s'%(referencesPath,)
+    f = open(referencesPath,'w')   
+    print >>f, '<html><head><title>clang: Specification References</title></head>'
+    print >>f, '<body>'
+    print >>f, '\t<h2>Specification References</h2>'
+    for i,node in enumerate(refTree[1]):
+        specName = node[0] or 'Unknown'
+        print >>f, '<a href="#spec%d">%s</a><br>'%(i,specName)
+    for i,node in enumerate(refTree[1]):
+        specName = node[0] or 'Unknown'
+        print >>f, '<hr>'
+        print >>f, '<a name="spec%d">'%(i,)
+        print >>f, '<h3>Document: %s</h3>'%(specName or 'Unknown',)
+        print >>f, '<table border="1" cellspacing="2" width="80%">'
+        print >>f, '<tr><th width="20%">Name</th><th>References</th></tr>'
+        docData = kDocuments.get(specName)
+        for path in preorder(node,first=False):
+            if not path[-1][2]:
+                continue
+            components = '.'.join([str(p[0]) for p in path[1:]])
+            print >>f, '\t<tr>'
+            tocEntry = None            
+            if docData is not None:
+                tocEntry = findClosestTOCEntry(docData, [p[0] for p in path[1:]])
+            if tocEntry is not None:
+                section,name,page = tocEntry
+                # If section is exact print the TOC name
+                if page is not None:
+                    linkStr = '<a href="%s#page=%d">%s</a> (pg.%d)'%(docData[0],page,components,page)
+                else:
+                    linkStr = components
+                if section == components:
+                    print >>f, '\t\t<td valign=top>%s<br>%s</td>'%(linkStr,name)
+                else:
+                    print >>f, '\t\t<td valign=top>%s</td>'%(linkStr,)
+            else:
+                print >>f, '\t\t<td valign=top>%s</td>'%(components,)
+            print >>f, '\t\t<td valign=top>'
+            for item in path[-1][2]:
+                # XXX total hack
+                relativePath = item.path[len(root):]
+                if relativePath.startswith('/'):
+                    relativePath = relativePath[1:]
+                # XXX this is broken, how does doxygen mangle w/ multiple
+                # refs? Can we just read its map?
+                filename = os.path.basename(relativePath)
+                doxyName = '%s-source.html'%(filename.replace('.','_8'),)
+                # Grrr, why can't doxygen write line number references.
+                lineReference = findClosestLineReference(root,doxyName,item.line)
+                if lineReference is not None:
+                    linkStr = 'http://clang.llvm.org/doxygen/%s#%s'%(doxyName,lineReference)
+                else:
+                    linkStr = 'http://clang.llvm.org/doxygen/%s'%(doxyName,)
+                if item.section.paragraph is not None:
+                    paraText = '&nbsp;(p%d)'%(item.section.paragraph,)
+                else:
+                    paraText = ''
+                print >>f,'<a href="%s">%s:%d</a>%s<br>'%(linkStr,relativePath,item.line,paraText)
+            print >>f, '\t\t</td>'
+            print >>f, '\t</tr>'
+        print >>f, '</table>'
+    print >>f, '<hr>'
+    print >>f, 'Generated: %s<br>'%(time.strftime('%Y-%m-%d %H:%M'),)
+    print >>f, 'SVN Revision: %s'%(getRevision(root),)
+    print >>f, '</body>'
+    f.close()
+    
+if __name__=='__main__':
+   main()
diff --git a/utils/OptionalTests/Extra/README.txt b/utils/OptionalTests/Extra/README.txt
new file mode 100644
index 0000000..565241b
--- /dev/null
+++ b/utils/OptionalTests/Extra/README.txt
@@ -0,0 +1,3 @@
+This directory is for extra unit style tests following the structure of
+clang/tests, but which are not portable or not suitable for inclusion in the
+regular test suite.
diff --git a/utils/OptionalTests/Extra/Runtime/darwin-clang_rt.c b/utils/OptionalTests/Extra/Runtime/darwin-clang_rt.c
new file mode 100644
index 0000000..d22c0bd
--- /dev/null
+++ b/utils/OptionalTests/Extra/Runtime/darwin-clang_rt.c
@@ -0,0 +1,338 @@
+/* This file tests that we can succesfully call each compiler-rt function. It is
+   designed to check that the runtime libraries are available for linking and
+   that they contain the expected contents. It is not designed to test the
+   correctness of the individual functions in compiler-rt.
+
+   This test is assumed to be run on a 10.6 machine. The two environment
+   variables below should be set to 10.4 and 10.5 machines which can be directly
+   ssh/rsync'd to in order to actually test the executables can run on the
+   desired targets.
+*/
+
+// RUN: export TENFOUR_X86_MACHINE=localhost
+// RUN: export TENFIVE_X86_MACHINE=localhost
+// RUN: export ARM_MACHINE=localhost
+// RUN: export ARM_SYSROOT=$(xcodebuild -sdk iphoneos -version Path)
+
+// RUN: echo iPhoneOS, ARM, v6, thumb
+// RUN: %clang -isysroot $ARM_SYSROOT -arch armv6 -mthumb -c %s -o %t.o
+// RUN: %clang -isysroot $ARM_SYSROOT -arch armv6 -mthumb -v -Wl,-t,-v -o %t %t.o 1>&2
+// RUN: rsync -arv %t $ARM_MACHINE:/tmp/a.out
+// RUN: ssh $ARM_MACHINE /tmp/a.out
+// RUN: echo
+
+// RUN: echo iPhoneOS, ARM, v6, no-thumb
+// RUN: %clang -isysroot $ARM_SYSROOT -arch armv6 -mno-thumb -c %s -o %t.o
+// RUN: %clang -isysroot $ARM_SYSROOT -arch armv6 -mno-thumb -v -Wl,-t,-v -o %t %t.o 1>&2
+// RUN: rsync -arv %t $ARM_MACHINE:/tmp/a.out
+// RUN: ssh $ARM_MACHINE /tmp/a.out
+// RUN: echo
+
+// RUN: echo iPhoneOS, ARM, v7, thumb
+// RUN: %clang -isysroot $ARM_SYSROOT -arch armv7 -mthumb -c %s -o %t.o
+// RUN: %clang -isysroot $ARM_SYSROOT -arch armv7 -mthumb -v -Wl,-t,-v -o %t %t.o 1>&2
+// RUN: rsync -arv %t $ARM_MACHINE:/tmp/a.out
+// RUN: ssh $ARM_MACHINE /tmp/a.out
+// RUN: echo
+
+// RUN: echo iPhoneOS, ARM, v7, no-thumb
+// RUN: %clang -isysroot $ARM_SYSROOT -arch armv7 -mno-thumb -c %s -o %t.o
+// RUN: %clang -isysroot $ARM_SYSROOT -arch armv7 -mno-thumb -v -Wl,-t,-v -o %t %t.o 1>&2
+// RUN: rsync -arv %t $ARM_MACHINE:/tmp/a.out
+// RUN: ssh $ARM_MACHINE /tmp/a.out
+// RUN: echo
+
+// RUN: echo 10.4, i386
+// RUN: %clang -arch i386 -mmacosx-version-min=10.4 -c %s -o %t.o
+// RUN: %clang -arch i386 -mmacosx-version-min=10.4 -v -Wl,-t,-v -o %t %t.o 1>&2
+// RUN: %t
+// RUN: echo
+
+// RUN: rsync -arv %t $TENFOUR_X86_MACHINE:/tmp/a.out
+// RUN: ssh $TENFOUR_X86_MACHINE /tmp/a.out
+// RUN: echo
+
+// RUX: rsync -arv %t $TENFIVE_X86_MACHINE:/tmp/a.out
+// RUX: ssh $TENFIVE_X86_MACHINE /tmp/a.out
+// RUN: echo
+
+// RUN: echo 10.5, i386
+// RUN: %clang -arch i386 -mmacosx-version-min=10.5 -c %s -o %t.o
+// RUN: %clang -arch i386 -mmacosx-version-min=10.5 -v -Wl,-t,-v -o %t %t.o 1>&2
+// RUN: %t
+// RUN: echo
+
+// RUN: rsync -arv %t $TENFIVE_X86_MACHINE:/tmp/a.out
+// RUN: ssh $TENFIVE_X86_MACHINE /tmp/a.out
+// RUN: echo
+
+// RUN: echo 10.6, i386
+// RUN: %clang -arch i386 -mmacosx-version-min=10.6 -c %s -o %t.o
+// RUN: %clang -arch i386 -mmacosx-version-min=10.6 -v -Wl,-t,-v -o %t %t.o 1>&2
+// RUN: %t
+// RUN: echo
+
+// RUN: echo 10.4, x86_64
+// RUN: %clang -arch x86_64 -mmacosx-version-min=10.4 -c %s -o %t.o
+// RUN: %clang -arch x86_64 -mmacosx-version-min=10.4 -v -Wl,-t,-v -o %t %t.o 1>&2
+// RUN: %t
+// RUN: echo
+
+// RUN: rsync -arv %t $TENFOUR_X86_MACHINE:/tmp/a.out
+// RUN: ssh $TENFOUR_X86_MACHINE /tmp/a.out
+// RUN: echo
+
+// RUN: rsync -arv %t $TENFIVE_X86_MACHINE:/tmp/a.out
+// RUN: ssh $TENFIVE_X86_MACHINE /tmp/a.out
+// RUN: echo
+
+// RUN: echo 10.5, x86_64
+// RUN: %clang -arch x86_64 -mmacosx-version-min=10.5 -c %s -o %t.o
+// RUN: %clang -arch x86_64 -mmacosx-version-min=10.5 -v -Wl,-t,-v -o %t %t.o 1>&2
+// RUN: %t
+// RUN: echo
+
+// RUN: rsync -arv %t $TENFIVE_X86_MACHINE:/tmp/a.out
+// RUN: ssh $TENFIVE_X86_MACHINE /tmp/a.out
+// RUN: echo
+
+// RUN: echo 10.6, x86_64
+// RUN: %clang -arch x86_64 -mmacosx-version-min=10.6 -c %s -o %t.o
+// RUN: %clang -arch x86_64 -mmacosx-version-min=10.6 -v -Wl,-t,-v -o %t %t.o 1>&2
+// RUN: %t
+// RUN: echo
+
+#include <assert.h>
+#include <stdio.h>
+#include <sys/utsname.h>
+
+typedef int si_int;
+typedef unsigned su_int;
+
+typedef long long di_int;
+typedef unsigned long long du_int;
+
+// Integral bit manipulation
+
+di_int __ashldi3(di_int a, si_int b);      // a << b
+di_int __ashrdi3(di_int a, si_int b);      // a >> b  arithmetic (sign fill)
+di_int __lshrdi3(di_int a, si_int b);      // a >> b  logical    (zero fill)
+
+si_int __clzsi2(si_int a);  // count leading zeros
+si_int __clzdi2(di_int a);  // count leading zeros
+si_int __ctzsi2(si_int a);  // count trailing zeros
+si_int __ctzdi2(di_int a);  // count trailing zeros
+
+si_int __ffsdi2(di_int a);  // find least significant 1 bit
+
+si_int __paritysi2(si_int a);  // bit parity
+si_int __paritydi2(di_int a);  // bit parity
+
+si_int __popcountsi2(si_int a);  // bit population
+si_int __popcountdi2(di_int a);  // bit population
+
+// Integral arithmetic
+
+di_int __negdi2    (di_int a);                         // -a
+di_int __muldi3    (di_int a, di_int b);               // a * b
+di_int __divdi3    (di_int a, di_int b);               // a / b   signed
+du_int __udivdi3   (du_int a, du_int b);               // a / b   unsigned
+di_int __moddi3    (di_int a, di_int b);               // a % b   signed
+du_int __umoddi3   (du_int a, du_int b);               // a % b   unsigned
+du_int __udivmoddi4(du_int a, du_int b, du_int* rem);  // a / b, *rem = a % b
+
+//  Integral arithmetic with trapping overflow
+
+si_int __absvsi2(si_int a);           // abs(a)
+di_int __absvdi2(di_int a);           // abs(a)
+
+si_int __negvsi2(si_int a);           // -a
+di_int __negvdi2(di_int a);           // -a
+
+si_int __addvsi3(si_int a, si_int b);  // a + b
+di_int __addvdi3(di_int a, di_int b);  // a + b
+
+si_int __subvsi3(si_int a, si_int b);  // a - b
+di_int __subvdi3(di_int a, di_int b);  // a - b
+
+si_int __mulvsi3(si_int a, si_int b);  // a * b
+di_int __mulvdi3(di_int a, di_int b);  // a * b
+
+//  Integral comparison: a  < b -> 0
+//                       a == b -> 1
+//                       a  > b -> 2
+
+si_int __cmpdi2 (di_int a, di_int b);
+si_int __ucmpdi2(du_int a, du_int b);
+
+//  Integral / floating point conversion
+
+di_int __fixsfdi(      float a);
+di_int __fixdfdi(     double a);
+di_int __fixxfdi(long double a);
+
+su_int __fixunssfsi(      float a);
+su_int __fixunsdfsi(     double a);
+su_int __fixunsxfsi(long double a);
+
+du_int __fixunssfdi(      float a);
+du_int __fixunsdfdi(     double a);
+du_int __fixunsxfdi(long double a);
+
+float       __floatdisf(di_int a);
+double      __floatdidf(di_int a);
+long double __floatdixf(di_int a);
+
+float       __floatundisf(du_int a);
+double      __floatundidf(du_int a);
+long double __floatundixf(du_int a);
+
+//  Floating point raised to integer power
+
+float       __powisf2(      float a, si_int b);  // a ^ b
+double      __powidf2(     double a, si_int b);  // a ^ b
+long double __powixf2(long double a, si_int b);  // a ^ b
+
+//  Complex arithmetic
+
+//  (a + ib) * (c + id)
+
+      float _Complex __mulsc3( float a,  float b,  float c,  float d);
+     double _Complex __muldc3(double a, double b, double c, double d);
+long double _Complex __mulxc3(long double a, long double b,
+                              long double c, long double d);
+
+//  (a + ib) / (c + id)
+
+      float _Complex __divsc3( float a,  float b,  float c,  float d);
+     double _Complex __divdc3(double a, double b, double c, double d);
+long double _Complex __divxc3(long double a, long double b,
+                              long double c, long double d);
+
+#ifndef __arm
+#define HAS_LONG_DOUBLE
+#endif
+
+int main(int argc, char **argv) {
+  du_int du_tmp;
+  struct utsname name;
+#ifdef __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__
+  const char *target_name = "OS X";
+  unsigned target_version = __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__;
+  unsigned target_maj = target_version / 100;
+  unsigned target_min = (target_version / 10) % 10;
+  unsigned target_micro = target_version % 10;
+#else
+  const char *target_name = "iPhoneOS";
+  unsigned target_version = __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__;
+  unsigned target_maj = target_version / 10000;
+  unsigned target_min = (target_version / 100) % 100;
+  unsigned target_micro = target_version % 100;
+#endif
+
+  if (uname(&name))
+    return 1;
+
+  fprintf(stderr, "%s: clang_rt test:\n", argv[0]);
+  fprintf(stderr, "  target  : %s %d.%d.%d\n\n", target_name,
+          target_maj, target_min, target_micro);
+  fprintf(stderr, "  sysname : %s\n", name.sysname);
+  fprintf(stderr, "  nodename: %s\n", name.nodename);
+  fprintf(stderr, "  release : %s\n", name.release);
+  fprintf(stderr, "  version : %s\n", name.version);
+  fprintf(stderr, "  machine : %s\n", name.machine);
+
+  assert(__ashldi3(1, 1) == 2);
+  assert(__ashrdi3(2, 1) == 1);
+  assert(__lshrdi3(2, 1) == 1);
+  assert(__clzsi2(1) == 31);
+  assert(__clzdi2(1) == 63);
+  assert(__ctzsi2(2) == 1);
+  assert(__ctzdi2(2) == 1);
+  assert(__ffsdi2(12) == 3);
+  assert(__paritysi2(13) == 1);
+  assert(__paritydi2(13) == 1);
+  assert(__popcountsi2(13) == 3);
+  assert(__popcountdi2(13) == 3);
+  assert(__negdi2(3) == -3);
+  assert(__muldi3(2,2) == 4);
+  assert(__divdi3(-4,2) == -2);
+  assert(__udivdi3(4,2) == 2);
+  assert(__moddi3(3,2) == 1);
+  assert(__umoddi3(3,2) == 1);
+  assert(__udivmoddi4(5,2,&du_tmp) == 2 && du_tmp == 1);
+  assert(__absvsi2(-2) == 2);
+  assert(__absvdi2(-2) == 2);
+  assert(__negvsi2(2) == -2);
+  assert(__negvdi2(2) == -2);
+  assert(__addvsi3(2, 3) == 5);
+  assert(__addvdi3(2, 3) == 5);
+  assert(__subvsi3(2, 3) == -1);
+  assert(__subvdi3(2, 3) == -1);
+  assert(__mulvsi3(2, 3) == 6);
+  assert(__mulvdi3(2, 3) == 6);
+  assert(__cmpdi2(3, 2) == 2);
+  assert(__ucmpdi2(3, 2) == 2);
+  assert(__fixsfdi(2.0) == 2);
+  assert(__fixdfdi(2.0) == 2);
+  assert(__fixunssfsi(2.0) == 2);
+  assert(__fixunsdfsi(2.0) == 2);
+  assert(__fixunssfdi(2.0) == 2);
+  assert(__fixunsdfdi(2.0) == 2);
+  assert(__floatdisf(2) == 2.0);
+  assert(__floatdidf(2) == 2.0);
+  assert(__floatundisf(2) == 2.0);
+  assert(__floatundidf(2) == 2.0);
+  assert(__powisf2(2.0, 2) == 4.0);
+  assert(__powidf2(2.0, 2) == 4.0);
+
+  // FIXME: Clang/LLVM seems to be miscompiling _Complex currently, probably an
+  // ABI issue.
+#ifndef __arm
+  {
+    _Complex float a = __mulsc3(1.0, 2.0, 4.0, 8.0);
+    _Complex float b = (-12.0 + 16.0j);
+    fprintf(stderr, "a: (%f + %f), b: (%f + %f)\n",
+            __real a, __imag a, __real b, __imag b);
+  }
+  assert(__mulsc3(1.0, 2.0, 4.0, 8.0) == (-12.0 + 16.0j));
+  assert(__muldc3(1.0, 2.0, 4.0, 8.0) == (-12.0 + 16.0j));
+  assert(__divsc3(1.0, 2.0, 4.0, 8.0) == (0.25 + 0j));
+  assert(__divdc3(1.0, 2.0, 4.0, 8.0) == (0.25 + 0j));
+#endif
+
+#ifdef HAS_LONG_DOUBLE
+  assert(__divxc3(1.0, 2.0, 4.0, 8.0) == (0.25 + 0j));
+  assert(__fixunsxfdi(2.0) == 2);
+  assert(__fixunsxfsi(2.0) == 2);
+  assert(__fixxfdi(2.0) == 2);
+  assert(__floatdixf(2) == 2.0);
+  assert(__floatundixf(2) == 2);
+  assert(__mulxc3(1.0, 2.0, 4.0, 8.0) == (-12.0 + 16.0j));
+  assert(__powixf2(2.0, 2) == 4.0);
+#endif
+
+  // Test some calls which are used on armv6/thumb. The calls/prototypes are
+  // fake, it would be nice to test correctness, but mostly we just want to
+  // make sure we resolve symbols correctly.
+#if defined(__arm) && defined(__ARM_ARCH_6K__) && defined(__thumb__)
+  if (argc == 100) {
+    extern void __restore_vfp_d8_d15_regs(void), __save_vfp_d8_d15_regs(void);
+    extern void __switch8(void), __switchu8(void),
+      __switch16(void), __switch32(void);
+    extern void __addsf3vfp(void);
+
+    __addsf3vfp();
+    __restore_vfp_d8_d15_regs();
+    __save_vfp_d8_d15_regs();
+    __switch8();
+    __switchu8();
+    __switch16();
+    __switch32();
+  }
+#endif
+
+  fprintf(stderr, "    OK!\n");
+
+  return 0;
+}
diff --git a/utils/OptionalTests/README.txt b/utils/OptionalTests/README.txt
new file mode 100644
index 0000000..4ffdb3b
--- /dev/null
+++ b/utils/OptionalTests/README.txt
@@ -0,0 +1,4 @@
+This is a dumping ground for additional tests which do not fit cleanly into the
+clang regression tests. For example, tests which are not portable, require
+additional software or configuration, take an excessive time to run, or are
+flaky can be kept here.
diff --git a/utils/OptionalTests/lit.cfg b/utils/OptionalTests/lit.cfg
new file mode 100644
index 0000000..592c424
--- /dev/null
+++ b/utils/OptionalTests/lit.cfg
@@ -0,0 +1,26 @@
+# -*- Python -*-
+
+# Configuration file for the 'lit' test runner.
+
+# Load the main clang test config so we can leech its clang finding logic.
+lit.load_config(config, os.path.join(os.path.dirname(__file__),
+                                     '..', '..', 'test', 'lit.cfg'))
+assert config.clang, "Failed to set clang!?"
+
+# name: The name of this test suite.
+config.name = 'Clang-Opt-Tests'
+
+# suffixes: A list of file extensions to treat as test files.
+config.suffixes = []
+
+# Reset these from the Clang config.
+
+# test_source_root: The root path where tests are located.
+config.test_source_root = os.path.dirname(__file__)
+
+# test_exec_root: The root path where tests should be run.
+clang_obj_root = getattr(config, 'clang_obj_root', None)
+if clang_obj_root is not None:
+    config.test_exec_root = os.path.join(clang_obj_root, 'utils',
+                                         'OptionalTests')
+
diff --git a/utils/SummarizeErrors b/utils/SummarizeErrors
new file mode 100755
index 0000000..b6e9122
--- /dev/null
+++ b/utils/SummarizeErrors
@@ -0,0 +1,117 @@
+#!/usr/bin/env python
+
+import os, sys, re
+
+class multidict:
+    def __init__(self, elts=()):
+        self.data = {}
+        for key,value in elts:
+            self[key] = value
+    
+    def __getitem__(self, item):
+        return self.data[item]
+    def __setitem__(self, key, value):
+        if key in self.data:
+            self.data[key].append(value)
+        else:
+            self.data[key] = [value]
+    def items(self):
+        return self.data.items()
+    def values(self):
+        return self.data.values()
+    def keys(self):
+        return self.data.keys()
+    def __len__(self):
+        return len(self.data)
+
+kDiagnosticRE = re.compile(': (error|warning): (.*)')
+kAssertionRE = re.compile('Assertion failed: (.*, function .*, file .*, line [0-9]+\\.)')
+
+def readInfo(path, opts):
+    lastProgress = [-100,0]
+    def progress(pos):
+        pct = (100. * pos) / (size * 2)
+        if (pct - lastProgress[0]) >= 10:
+            lastProgress[0] = pct
+            print '%d/%d = %.2f%%' % (pos, size*2, pct)
+
+    f = open(path)
+    data = f.read()
+    f.close()
+
+    if opts.truncate != -1:
+        data = data[:opts.truncate]
+
+    size = len(data)
+    warnings = multidict()
+    errors = multidict()
+    for m in kDiagnosticRE.finditer(data):
+        progress(m.end())
+        if m.group(1) == 'error':
+            d = errors
+        else:
+            d = warnings
+        d[m.group(2)] = m
+    warnings = warnings.items()
+    errors = errors.items()
+    assertions = multidict()
+    for m in kAssertionRE.finditer(data):
+        print '%d/%d = %.2f%%' % (size + m.end(), size, (float(m.end()) / (size*2)) * 100.)
+        assertions[m.group(1)] = m
+    assertions = assertions.items()
+
+    # Manual scan for stack traces
+    aborts = multidict()
+    if 0:
+        prevLine = None
+        lnIter = iter(data.split('\n'))
+        for ln in lnIter:
+            m = kStackDumpLineRE.match(ln)
+            if m:
+                stack = [m.group(2)]
+                for ln in lnIter:
+                    m = kStackDumpLineRE.match(ln)
+                    if not m:
+                        break
+                    stack.append(m.group(2))
+                if prevLine is None or not kAssertionRE.match(prevLine):
+                    aborts[tuple(stack)] = stack
+            prevLine = ln
+
+    sections = [
+        (warnings, 'Warnings'),
+        (errors, 'Errors'),
+        (assertions, 'Assertions'),
+        (aborts.items(), 'Aborts'),
+        ]
+
+    if opts.ascending:
+        sections.reverse()
+
+    for l,title in sections:
+        l.sort(key = lambda (a,b): -len(b))
+        if l:
+            print '-- %d %s (%d kinds) --' % (sum([len(b) for a,b in l]), title, len(l))
+            for name,elts in l:
+                print '%5d:' % len(elts), name
+
+def main():
+    global options
+    from optparse import OptionParser
+    parser = OptionParser("usage: %prog [options] {inputs}")
+    parser.add_option("", "--ascending", dest="ascending",
+                      help="Print output in ascending order of severity.",
+                      action="store_true", default=False)
+    parser.add_option("", "--truncate", dest="truncate",
+                      help="Truncate input file (for testing).",
+                      type=int, action="store", default=-1)
+    (opts, args) = parser.parse_args()
+    
+    if not args:
+        parser.error('No inputs specified')
+
+    for arg in args:
+        readInfo(arg, opts)
+
+if __name__=='__main__':
+    main()
diff --git a/utils/TestUtils/deep-stack.py b/utils/TestUtils/deep-stack.py
new file mode 100755
index 0000000..1750a5f
--- /dev/null
+++ b/utils/TestUtils/deep-stack.py
@@ -0,0 +1,24 @@
+#!/usr/bin/env python
+
+def pcall(f, N):
+    if N == 0:
+        print >>f, '    f(0)'
+        return
+
+    print >>f, '    f('
+    pcall(f, N - 1)
+    print >>f, '     )'
+
+def main():
+    f = open('t.c','w')
+    print >>f, 'int f(int n) { return n; }'
+    print >>f, 'int t() {'
+    print >>f, '  return'
+    pcall(f, 10000)
+    print >>f, '  ;'
+    print >>f, '}'
+
+if __name__ == "__main__":
+    import sys
+    sys.setrecursionlimit(100000)
+    main()
diff --git a/utils/TestUtils/pch-test.pl b/utils/TestUtils/pch-test.pl
new file mode 100755
index 0000000..e097c5c
--- /dev/null
+++ b/utils/TestUtils/pch-test.pl
@@ -0,0 +1,61 @@
+#!/usr/bin/perl -w
+
+# This tiny little script, which should be run from the clang
+# directory (with clang in your patch), tries to take each
+# compilable Clang test and build a PCH file from that test, then read
+# and dump the contents of the PCH file just created.
+use POSIX;
+
+$exitcode = 0;
+sub testfiles($$) {
+  my $suffix = shift;
+  my $language = shift;
+  my $passed = 0;
+  my $failed = 0;
+  my $skipped = 0;
+
+  @files = `ls test/*/*.$suffix`;
+  foreach $file (@files) {
+    chomp($file);
+    my $code = system("clang- -fsyntax-only -x $language $file > /dev/null 2>&1");
+    if ($code == 0) {
+      print(".");
+      $code = system("clang -cc1 -emit-pch -x $language -o $file.pch $file > /dev/null 2>&1");
+      if ($code == 0) {
+        $code = system("clang -cc1 -include-pch $file.pch -x $language -ast-dump /dev/null > /dev/null 2>&1");
+        if ($code == 0) {
+          $passed++;
+        } elsif (($code & 0xFF) == SIGINT) {
+          exit($exitcode);
+        } else {
+          print("\n---Failed to dump AST file for \"$file\"---\n");
+          $exitcode = 1;
+          $failed++;
+        }
+        unlink "$file.pch";
+      } elsif (($code & 0xFF) == SIGINT) {
+        exit($exitcode);
+      } else {
+        print("\n---Failed to build PCH file for \"$file\"---\n");
+        $exitcode = 1;
+          $failed++;
+      }
+    } elsif (($code & 0xFF) == SIGINT) {
+      exit($exitcode);
+    } else {
+      print("x");
+      $skipped++;
+    }
+  }
+
+  print("\n\n$passed tests passed\n");
+  print("$failed tests failed\n");
+  print("$skipped tests skipped ('x')\n")
+}
+
+printf("-----Testing precompiled headers for C-----\n");
+testfiles("c", "c");
+printf("\n-----Testing precompiled headers for Objective-C-----\n");
+testfiles("m", "objective-c");
+print("\n");
+exit($exitcode);
diff --git a/utils/VtableTest/Makefile b/utils/VtableTest/Makefile
new file mode 100644
index 0000000..dd615ae
--- /dev/null
+++ b/utils/VtableTest/Makefile
@@ -0,0 +1,24 @@
+GXX := llvm-g++-4.2
+CLANGXX := clang++
+
+all: one
+
+test.cc: gen.cc
+	g++ gen.cc -o gen
+	./gen >test.cc
+
+test-gcc.sum: test.cc
+	time $(GXX) test.cc -o test-gcc.s -S
+	$(GXX) test-gcc.s -o test-gcc
+	./test-gcc >test-gcc.sum
+
+test-clang.sum: test.cc
+	time $(CLANGXX) test.cc -o test-clang.s -S
+	$(CLANGXX) test-clang.s -o test-clang
+	./test-clang >test-clang.sum
+
+one: test-gcc.sum test-clang.sum
+	cmp test-gcc.sum test-clang.sum
+
+clean:
+	rm -f gen test-gcc test-clang test.cc test-gcc.sum test-clang.sum test-gcc.s test-clang.s
diff --git a/utils/VtableTest/check-zti b/utils/VtableTest/check-zti
new file mode 100755
index 0000000..bf5b045
--- /dev/null
+++ b/utils/VtableTest/check-zti
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+N_STRUCTS=300
+
+# Utility routine to "hand" check type infos.
+
+let i=1;
+while [ $i != $N_STRUCTS ]; do
+  sed -n "/^__ZTI.*s$i:/,/\.[sg][el]/p" test-clang.s |
+    grep -v '\.[sg][el]' | sed 's/(\([0-9][0-9]*\))/\1/' >test-clang-zti
+  sed -n "/^__ZTI.*s$i:/,/\.[sg][el]/p" test-gcc.s |
+    grep -v '\.[sg][el]' | sed 's/(\([0-9][0-9]*\))/\1/' >test-gcc-zti
+  diff -U3 test-gcc-zti test-clang-zti
+  if [ $? != 0 ]; then
+     echo "FAIL: s$i type info"
+  else
+     echo "PASS: s$i type info"
+  fi
+  let i=i+1
+done
diff --git a/utils/VtableTest/check-ztt b/utils/VtableTest/check-ztt
new file mode 100755
index 0000000..4a83c55
--- /dev/null
+++ b/utils/VtableTest/check-ztt
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+N_STRUCTS=300
+
+# Utility routine to "hand" check VTTs.
+
+let i=1;
+while [ $i != $N_STRUCTS ]; do
+  sed -n "/^__ZTT.*s$i:/,/\.[sgm][elo]/p" test-clang.s |
+    grep -v '\.[sgm][elo]' | sed -e 's/[()]//g' -e '/^$/d'  >test-clang-ztt
+  sed -n "/^__ZTT.*s$i:/,/\.[sgm][elo]/p" test-gcc.s |
+    grep -v '\.[sgm][elo]' | sed -e 's/[()]//g' -e 's/ + /+/'  >test-gcc-ztt
+  diff -U3 test-gcc-ztt test-clang-ztt
+  if [ $? != 0 ]; then
+     echo "FAIL: s$i VTT"
+  else
+     echo "PASS: s$i VTT"
+  fi
+  let i=i+1
+done
diff --git a/utils/VtableTest/check-zvt b/utils/VtableTest/check-zvt
new file mode 100755
index 0000000..d8b93bd
--- /dev/null
+++ b/utils/VtableTest/check-zvt
@@ -0,0 +1,18 @@
+#!/bin/sh
+
+N_STRUCTS=300
+
+# Utility routine to "hand" check vtables.
+
+let i=1;
+while [ $i != $N_STRUCTS ]; do
+  sed -n "/^__ZTV.*s$i:/,/\.[sg][el]/p" test-clang.s | grep -v '\.[sg][el]' >test-clang-ztv
+  sed -n "/^__ZTV.*s$i:/,/\.[sg][el]/p" test-gcc.s | grep -v '\.[sg][el]' >test-gcc-ztv
+  diff -U3 test-gcc-ztv test-clang-ztv
+  if [ $? != 0 ]; then
+     echo "FAIL: s$i vtable"
+  else
+     echo "PASS: s$i vtable"
+  fi
+  let i=i+1
+done
diff --git a/utils/VtableTest/gen.cc b/utils/VtableTest/gen.cc
new file mode 100644
index 0000000..8396f8d
--- /dev/null
+++ b/utils/VtableTest/gen.cc
@@ -0,0 +1,350 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#define N_FIELDS 7
+#define N_FUNCS 128
+#define FUNCSPACING 20
+#define N_STRUCTS 180 /* 1280 */
+#define N_BASES 6
+#define COVARIANT 0
+
+const char *simple_types[] = { "bool", "char", "short", "int", "float",
+			       "double", "long double", "wchar_t", "void *",
+			       "char *"
+};
+
+void gl(const char *c) {
+  printf("%s\n", c);
+}
+
+void g(const char *c) {
+  printf("%s", c);
+}
+
+void g(int i) {
+  printf("%d", i);
+}
+
+int uuid = 0;
+char base_present[N_STRUCTS][N_STRUCTS];
+
+// The return type for each function when doing covariant testcase generation.
+short ret_types[N_STRUCTS][N_FUNCS*FUNCSPACING];
+
+bool is_ambiguous(int s, int base) {
+  for (int i = 0; i < N_STRUCTS; ++i) {
+    if ((base_present[base][i] & base_present[s][i]) == 1)
+      return true;
+  }
+  return false;
+}
+
+void add_bases(int s, int base) {
+  for (int i = 0; i < N_STRUCTS; ++i)
+    base_present[s][i] |= base_present[base][i];
+  if (!COVARIANT)
+    return;
+  for (int i = 0; i < N_FUNCS*FUNCSPACING; ++i) {
+    if (!ret_types[base][i])
+      continue;
+    if (!ret_types[s][i]) {
+      ret_types[s][i] = ret_types[base][i];
+      continue;
+    }
+    if (base_present[ret_types[base][i]][ret_types[s][i]])
+      // If the return type of the function from this base dominates
+      ret_types[s][i] = ret_types[base][i];
+    if (base_present[ret_types[s][i]][ret_types[base][i]])
+      // If a previous base dominates
+      continue;
+    // If neither dominates, we'll use this class.
+    ret_types[s][i] = s;
+  }
+}
+
+// This contains the class that has the final override for
+// each class, for each function.
+short final_override[N_STRUCTS][N_FUNCS*FUNCSPACING];
+
+void gs(int s) {
+  bool polymorphic = false;
+
+  static int bases[N_BASES];
+  int i_bases = random() % (N_BASES*2);
+  if (i_bases >= N_BASES)
+    // PARAM: 1/2 of all clases should have no bases
+    i_bases = 0;
+  int n_bases = 0;
+  bool first_base = true;
+  
+  // PARAM: 3/4 of all should be class, the rest are structs
+  if (random() % 4 == 0)
+    g("struct s");
+  else
+    g("class s");
+  g(s);
+  int old_base = -1;
+  if (s == 0 || s == 1)
+    i_bases = 0;
+  while (i_bases) {
+    --i_bases;
+    int base = random() % (s-1) + 1;
+    if (!base_present[s][base]) {
+      if (is_ambiguous(s, base))
+	continue;
+      if (first_base) {
+	first_base = false;
+	g(": ");
+      } else
+	g(", ");
+      int base_type = 1;
+      if (random()%8 == 0) {
+	// PARAM: 1/8th the bases are virtual
+	g("virtual ");
+        // We have a vtable and rtti, but technically we're not polymorphic
+	// polymorphic = true;
+	base_type = 3;
+      }
+      // PARAM: 1/4 are public, 1/8 are privare, 1/8 are protected, the reset, default
+      int base_protection = 0;
+      if (!COVARIANT)
+        base_protection = random()%8;
+      switch (base_protection) {
+      case 0:
+      case 1:
+	g("public "); break;
+      case 2:
+      case 3:
+      case 4:
+      case 5:
+	break;
+      case 6:
+	g("private "); break;
+      case 7:
+	g("protected "); break;
+      }
+      g("s");
+      add_bases(s, base);
+      bases[n_bases] = base;
+      base_present[s][base] = base_type;
+      ++n_bases;
+      g(base);
+      old_base = base;
+    }
+  }
+  gl(" {");
+
+  /* Fields */
+  int n_fields = N_FIELDS == 0 ? 0 : random() % (N_FIELDS*4);
+  // PARAM: 3/4 of all structs should have no members
+  if (n_fields >= N_FIELDS)
+    n_fields = 0;
+  for (int i = 0; i < n_fields; ++i) {
+    int t = random() % (sizeof(simple_types) / sizeof(simple_types[0]));
+    g("  "); g(simple_types[t]); g(" field"); g(i); gl(";");
+  }
+
+  /* Virtual functions */
+  static int funcs[N_FUNCS*FUNCSPACING];
+  // PARAM: 1/2 of all structs should have no virtual functions
+  int n_funcs = random() % (N_FUNCS*2);
+  if (n_funcs > N_FUNCS)
+    n_funcs = 0;
+  int old_func = -1;
+  for (int i = 0; i < n_funcs; ++i) {
+    int fn = old_func + random() % FUNCSPACING + 1;
+    funcs[i] = fn;
+    int ret_type = 0;
+    if (COVARIANT) {
+      ret_type = random() % s + 1;
+      if (!base_present[s][ret_type]
+          || !base_present[ret_type][ret_types[s][fn]])
+        if (ret_types[s][fn]) {
+          printf("  // Found one for s%d for s%d* fun%d.\n", s,
+                 ret_types[s][fn], fn);
+          ret_type = ret_types[s][fn];
+        } else
+          ret_type = s;
+      else
+        printf("  // Wow found one for s%d for fun%d.\n", s, fn);
+      ret_types[s][fn] = ret_type;
+    }
+    if (ret_type) {
+      g("  virtual s"); g(ret_type); g("* fun");
+    } else
+      g("  virtual void fun");
+    g(fn); g("(char *t) { mix(\"vfn this offset\", (char *)this - t); mix(\"vfn uuid\", "); g(++uuid);
+    if (ret_type)
+      gl("); return 0; }");
+    else
+      gl("); }");
+    final_override[s][fn] = s;
+    old_func = fn;
+  }
+
+  // Add required overriders for correctness
+  for (int i = 0; i < n_bases; ++i) {
+    // For each base
+    int base = bases[i];
+    for (int fn = 0; fn < N_FUNCS*FUNCSPACING; ++fn) {
+      // For each possible function
+      int new_base = final_override[base][fn];
+      if (new_base == 0)
+        // If the base didn't have a final overrider, skip
+        continue;
+
+      int prev_base = final_override[s][fn];
+      if (prev_base == s)
+        // Skip functions defined in this class
+        continue;
+
+      // If we don't want to change the info, skip
+      if (prev_base == new_base)
+        continue;
+      
+      if (prev_base == 0) {
+        // record the final override
+        final_override[s][fn] = new_base;
+        continue;
+      }
+        
+      if (base_present[prev_base][new_base]) {
+        // The previous base dominates the new base, no update necessary
+        printf("  // No override for fun%d in s%d as s%d dominates s%d.\n",
+               fn, s, prev_base, new_base);
+        continue;
+      }
+
+      if (base_present[new_base][prev_base]) {
+        // The new base dominates the old base, no override necessary
+        printf("  // No override for fun%d in s%d as s%d dominates s%d.\n",
+               fn, s, new_base, prev_base);
+        // record the final override
+        final_override[s][fn] = new_base;
+        continue;
+      }
+
+      printf("  // Found we needed override for fun%d in s%d.\n", fn, s);
+
+      // record the final override
+      funcs[n_funcs++] = fn;
+      if (n_funcs == (N_FUNCS*FUNCSPACING-1))
+        abort();
+      int ret_type = 0;
+      if (COVARIANT) {
+        if (!ret_types[s][fn]) {
+          ret_types[s][fn] = ret_type = s;
+        } else {
+          ret_type = ret_types[s][fn];
+          if (ret_type != s)
+            printf("  // Calculated return type in s%d as s%d* fun%d.\n",
+                   s, ret_type, fn);
+        }
+      }
+      if (ret_type) {
+        g("  virtual s"); g(ret_type); g("* fun");
+      } else
+        g("  virtual void fun");
+      g(fn); g("(char *t) { mix(\"vfn this offset\", (char *)this - t); mix(\"vfn uuid\", "); g(++uuid);
+      if (ret_type)
+        gl("); return 0; }");
+      else
+        gl("); }");
+      final_override[s][fn] = s;
+    }
+  }
+
+  gl("public:");
+  gl("  void calc(char *t) {");
+
+  // mix in the type number
+  g("    mix(\"type num\", "); g(s); gl(");");
+  // mix in the size
+  g("    mix(\"type size\", sizeof (s"); g(s); gl("));");
+  // mix in the this offset
+  gl("    mix(\"subobject offset\", (char *)this - t);");
+  if (n_funcs)
+    polymorphic = true;
+  if (polymorphic) {
+    // mix in offset to the complete object under construction
+    gl("    mix(\"real top v current top\", t - (char *)dynamic_cast<void*>(this));");
+  }
+
+  /* check base layout and overrides */
+  for (int i = 0; i < n_bases; ++i) {
+    g("    calc_s"); g(bases[i]); gl("(t);");
+  }
+
+  if (polymorphic) {
+    /* check dynamic_cast to each direct base */
+    for (int i = 0; i < n_bases; ++i) {
+      g("    if ((char *)dynamic_cast<s"); g(bases[i]); gl("*>(this))");
+      g("      mix(\"base dyn cast\", t - (char *)dynamic_cast<s"); g(bases[i]); gl("*>(this));");
+      g("    else mix(\"no dyncast\", "); g(++uuid); gl(");");
+    }
+  }
+
+  /* check field layout */
+  for (int i = 0; i < n_fields; ++i) {
+    g("    mix(\"field offset\", (char *)&field"); g(i); gl(" - (char *)this);");
+  }
+  if (n_fields == 0) {
+    g("    mix(\"no fields\", "); g(++uuid); gl(");");
+  }
+
+  /* check functions */
+  for (int i = 0; i < n_funcs; ++i) {
+    g("    fun"); g(funcs[i]); gl("(t);");
+  }
+  if (n_funcs == 0) {
+    g("    mix(\"no funcs\", "); g(++uuid); gl(");");
+  }
+
+  gl("  }");
+
+  // default ctor
+  g("  s"); g(s); g("() ");
+  first_base = true;
+  for (int i = 0; i < n_bases; ++i) {
+    if (first_base) {
+      g(": ");
+      first_base = false;
+    } else
+      g(", ");
+    g("s"); g(bases[i]); g("((char *)this)");
+  }
+  gl(" { calc((char *)this); }");
+  g("  ~s"); g(s); gl("() { calc((char *)this); }");
+
+ // ctor with this to the complete object
+  g("  s"); g(s); gl("(char *t) { calc(t); }");
+  g("  void calc_s"); g(s); gl("(char *t) { calc(t); }");
+  g("} a"); g(s); gl(";");
+}
+
+main(int argc, char **argv) {
+  unsigned seed = 0;
+  char state[16];
+  if (argc > 1)
+    seed = atol(argv[1]);
+
+  initstate(seed, state, sizeof(state));
+  gl("extern \"C\" int printf(const char *...);");
+  gl("");
+  gl("long long sum;");
+  gl("void mix(const char *desc, long long i) {");
+  // If this ever becomes too slow, we can remove this after we improve the
+  // mixing function
+  gl("  printf(\"%s: %lld\\n\", desc, i);");
+  gl("  sum += ((sum ^ i) << 3) + (sum<<1) - i;");
+  gl("}");
+  gl("");
+  // PARAM: Randomly size testcases or large testcases?
+  int n_structs = /* random() % */ N_STRUCTS;
+  for (int i = 1; i < n_structs; ++i)
+    gs(i);
+  gl("int main() {");
+  gl("  printf(\"%llx\\n\", sum);");
+  gl("}");
+  return 0;
+}
diff --git a/utils/analyzer/CmpRuns b/utils/analyzer/CmpRuns
new file mode 100755
index 0000000..739d584
--- /dev/null
+++ b/utils/analyzer/CmpRuns
@@ -0,0 +1,230 @@
+#!/usr/bin/env python
+
+"""
+CmpRuns - A simple tool for comparing two static analyzer runs to determine
+which reports have been added, removed, or changed.
+
+This is designed to support automated testing using the static analyzer, from
+two perspectives: 
+  1. To monitor changes in the static analyzer's reports on real code bases, for
+     regression testing.
+
+  2. For use by end users who want to integrate regular static analyzer testing
+     into a buildbot like environment.
+"""
+
+import os
+import plistlib
+
+#
+
+class multidict:
+    def __init__(self, elts=()):
+        self.data = {}
+        for key,value in elts:
+            self[key] = value
+    
+    def __getitem__(self, item):
+        return self.data[item]
+    def __setitem__(self, key, value):
+        if key in self.data:
+            self.data[key].append(value)
+        else:
+            self.data[key] = [value]
+    def items(self):
+        return self.data.items()
+    def values(self):
+        return self.data.values()
+    def keys(self):
+        return self.data.keys()
+    def __len__(self):
+        return len(self.data)
+    def get(self, key, default=None):
+        return self.data.get(key, default)
+    
+#
+
+class AnalysisReport:
+    def __init__(self, run, files):
+        self.run = run
+        self.files = files
+
+class AnalysisDiagnostic:
+    def __init__(self, data, report, htmlReport):
+        self.data = data
+        self.report = report
+        self.htmlReport = htmlReport
+
+    def getReadableName(self):
+        loc = self.data['location']
+        filename = self.report.run.getSourceName(self.report.files[loc['file']])
+        line = loc['line']
+        column = loc['col']
+
+        # FIXME: Get a report number based on this key, to 'distinguish'
+        # reports, or something.
+        
+        return '%s:%d:%d' % (filename, line, column)
+
+    def getReportData(self):
+        if self.htmlReport is None:
+            return "This diagnostic does not have any report data."
+
+        return open(os.path.join(self.report.run.path,
+                                 self.htmlReport), "rb").read() 
+
+class AnalysisRun:
+    def __init__(self, path, opts):
+        self.path = path
+        self.reports = []
+        self.diagnostics = []
+        self.opts = opts
+
+    def getSourceName(self, path):
+        if path.startswith(self.opts.root):
+            return path[len(self.opts.root):]
+        return path
+
+def loadResults(path, opts):
+    run = AnalysisRun(path, opts)
+
+    for f in os.listdir(path):
+        if (not f.startswith('report') or
+            not f.endswith('plist')):
+            continue
+
+        p = os.path.join(path, f)
+        data = plistlib.readPlist(p)
+
+        # Ignore empty reports.
+        if not data['files']:
+            continue
+
+        # Extract the HTML reports, if they exists.
+        if 'HTMLDiagnostics_files' in data['diagnostics'][0]:
+            htmlFiles = []
+            for d in data['diagnostics']:
+                # FIXME: Why is this named files, when does it have multiple
+                # files?
+                assert len(d['HTMLDiagnostics_files']) == 1
+                htmlFiles.append(d.pop('HTMLDiagnostics_files')[0])
+        else:
+            htmlFiles = [None] * len(data['diagnostics'])
+            
+        report = AnalysisReport(run, data.pop('files'))
+        diagnostics = [AnalysisDiagnostic(d, report, h) 
+                       for d,h in zip(data.pop('diagnostics'),
+                                      htmlFiles)]
+
+        assert not data
+
+        run.reports.append(report)
+        run.diagnostics.extend(diagnostics)
+
+    return run
+
+def compareResults(A, B):
+    """
+    compareResults - Generate a relation from diagnostics in run A to
+    diagnostics in run B.
+
+    The result is the relation as a list of triples (a, b, confidence) where
+    each element {a,b} is None or an element from the respective run, and
+    confidence is a measure of the match quality (where 0 indicates equality,
+    and None is used if either element is None).
+    """
+
+    res = []
+
+    # Quickly eliminate equal elements.
+    neqA = []
+    neqB = []
+    eltsA = list(A.diagnostics)
+    eltsB = list(B.diagnostics)
+    eltsA.sort(key = lambda d: d.data)
+    eltsB.sort(key = lambda d: d.data)
+    while eltsA and eltsB:
+        a = eltsA.pop()
+        b = eltsB.pop()
+        if a.data == b.data:
+            res.append((a, b, 0))
+        elif a.data > b.data:
+            neqA.append(a)
+            eltsB.append(b)
+        else:
+            neqB.append(b)
+            eltsA.append(a)
+    neqA.extend(eltsA)
+    neqB.extend(eltsB)
+
+    # FIXME: Add fuzzy matching. One simple and possible effective idea would be
+    # to bin the diagnostics, print them in a normalized form (based solely on
+    # the structure of the diagnostic), compute the diff, then use that as the
+    # basis for matching. This has the nice property that we don't depend in any
+    # way on the diagnostic format.
+
+    for a in neqA:
+        res.append((a, None, None))
+    for b in neqB:
+        res.append((None, b, None))
+
+    return res
+
+def main():
+    from optparse import OptionParser
+    parser = OptionParser("usage: %prog [options] [dir A] [dir B]")
+    parser.add_option("", "--root", dest="root",
+                      help="Prefix to ignore on source files",
+                      action="store", type=str, default="")
+    parser.add_option("", "--verbose-log", dest="verboseLog",
+                      help="Write additional information to LOG [default=None]",
+                      action="store", type=str, default=None,
+                      metavar="LOG")
+    (opts, args) = parser.parse_args()
+
+    if len(args) != 2:
+        parser.error("invalid number of arguments")
+
+    dirA,dirB = args
+
+    # Load the run results.
+    resultsA = loadResults(dirA, opts)
+    resultsB = loadResults(dirB, opts)
+    
+    # Open the verbose log, if given.
+    if opts.verboseLog:
+        auxLog = open(opts.verboseLog, "wb")
+    else:
+        auxLog = None
+
+    diff = compareResults(resultsA, resultsB)
+    for res in diff:
+        a,b,confidence = res
+        if a is None:
+            print "ADDED: %r" % b.getReadableName()
+            if auxLog:
+                print >>auxLog, ("('ADDED', %r, %r)" % (b.getReadableName(),
+                                                        b.getReportData()))
+        elif b is None:
+            print "REMOVED: %r" % a.getReadableName()
+            if auxLog:
+                print >>auxLog, ("('REMOVED', %r, %r)" % (a.getReadableName(),
+                                                          a.getReportData()))
+        elif confidence:
+            print "CHANGED: %r to %r" % (a.getReadableName(),
+                                         b.getReadableName())
+            if auxLog:
+                print >>auxLog, ("('CHANGED', %r, %r, %r, %r)" 
+                                 % (a.getReadableName(),
+                                    b.getReadableName(),
+                                    a.getReportData(),
+                                    b.getReportData()))
+        else:
+            pass
+
+    print "TOTAL REPORTS: %r" % len(resultsB.diagnostics)
+    if auxLog:
+        print >>auxLog, "('TOTAL', %r)" % len(resultsB.diagnostics)
+
+if __name__ == '__main__':
+    main()
diff --git a/utils/analyzer/ubiviz b/utils/analyzer/ubiviz
new file mode 100755
index 0000000..1582797
--- /dev/null
+++ b/utils/analyzer/ubiviz
@@ -0,0 +1,74 @@
+#!/usr/bin/env python
+#
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+#
+# This script reads visualization data emitted by the static analyzer for
+# display in Ubigraph.
+#
+##===----------------------------------------------------------------------===##
+
+import xmlrpclib
+import sys
+
+def Error(message):
+    print >> sys.stderr, 'ubiviz: ' + message
+    sys.exit(1)
+    
+def StreamData(filename):
+  file = open(filename)
+  for ln in file:
+    yield eval(ln)
+  file.close()
+
+def Display(G, data):
+  action = data[0]
+  if action == 'vertex':
+    vertex = data[1]
+    G.new_vertex_w_id(vertex)
+    for attribute in data[2:]:
+      G.set_vertex_attribute(vertex, attribute[0], attribute[1])
+  elif action == 'edge':
+    src = data[1]
+    dst = data[2]
+    edge = G.new_edge(src,dst)
+    for attribute in data[3:]:
+      G.set_edge_attribute(edge, attribute[0], attribute[1])
+  elif action == "vertex_style":
+    style_id = data[1]
+    parent_id = data[2]
+    G.new_vertex_style_w_id(style_id, parent_id)
+    for attribute in data[3:]:
+      G.set_vertex_style_attribute(style_id, attribute[0], attribute[1])
+  elif action == "vertex_style_attribute":
+    style_id = data[1]
+    for attribute in data[2:]:
+      G.set_vertex_style_attribute(style_id, attribute[0], attribute[1])
+  elif action == "change_vertex_style":
+     vertex_id = data[1]
+     style_id = data[2]
+     G.change_vertex_style(vertex_id,style_id)
+
+def main(args):
+  if len(args) == 0:
+    Error('no input files')    
+
+  server = xmlrpclib.Server('http://127.0.0.1:20738/RPC2')
+  G = server.ubigraph
+            
+  for arg in args:
+    G.clear()
+    for x in StreamData(arg):
+      Display(G,x)
+  
+  sys.exit(0)
+  
+
+if __name__ == '__main__':
+    main(sys.argv[1:])
+    
+    
\ No newline at end of file
diff --git a/utils/builtin-defines.c b/utils/builtin-defines.c
new file mode 100644
index 0000000..9bbe5be
--- /dev/null
+++ b/utils/builtin-defines.c
@@ -0,0 +1,85 @@
+/* 
+This is a clang style test case for checking that preprocessor
+defines match gcc.
+*/
+
+/*
+RUN: for arch in -m32 -m64; do \
+RUN:   for lang in -std=gnu89 -ansi -std=c99 -std=gnu99; do \
+RUN:     for input in c objective-c; do \
+RUN:       for opts in "-O0" "-O1 -dynamic" "-O2 -static" "-Os"; do     \
+RUN:         echo "-- $arch, $lang, $input, $opts --"; \
+RUN:         for cc in 0 1; do \
+RUN:           if [ "$cc" == 0 ]; then \
+RUN:             cc_prog=clang; \
+RUN:             output=%t0; \
+RUN:           else \
+RUN:             cc_prog=gcc; \
+RUN:             output=%t1; \
+RUN:           fi; \
+RUN:           $cc_prog $arch $lang $opts -march=core2 -dM -E -x $input %s | sort > $output; \
+RUN:          done; \
+RUN:          if (! diff %t0 %t1); then exit 1; fi; \
+RUN:       done; \
+RUN:     done; \
+RUN:   done; \
+RUN: done;
+*/
+
+/* We don't care about this difference */
+#ifdef __PIC__
+#if __PIC__ == 1
+#undef __PIC__
+#undef __pic__
+#define __PIC__ 2
+#define __pic__ 2
+#endif
+#endif
+
+/* Undefine things we don't expect to match. */
+#undef __core2
+#undef __core2__
+#undef __SSSE3__
+
+/* Undefine things we don't expect to match. */
+#undef __DEC_EVAL_METHOD__
+#undef __INT16_TYPE__
+#undef __INT32_TYPE__
+#undef __INT64_TYPE__
+#undef __INT8_TYPE__
+#undef __SSP__
+#undef __APPLE_CC__
+#undef __VERSION__
+#undef __clang__
+#undef __llvm__
+#undef __nocona
+#undef __nocona__
+#undef __k8
+#undef __k8__
+#undef __tune_nocona__
+#undef __tune_core2__
+#undef __POINTER_WIDTH__
+#undef __INTPTR_TYPE__
+#undef __NO_MATH_INLINES
+
+#undef __DEC128_DEN__
+#undef __DEC128_EPSILON__
+#undef __DEC128_MANT_DIG__
+#undef __DEC128_MAX_EXP__
+#undef __DEC128_MAX__
+#undef __DEC128_MIN_EXP__
+#undef __DEC128_MIN__
+#undef __DEC32_DEN__
+#undef __DEC32_EPSILON__
+#undef __DEC32_MANT_DIG__
+#undef __DEC32_MAX_EXP__
+#undef __DEC32_MAX__
+#undef __DEC32_MIN_EXP__
+#undef __DEC32_MIN__
+#undef __DEC64_DEN__
+#undef __DEC64_EPSILON__
+#undef __DEC64_MANT_DIG__
+#undef __DEC64_MAX_EXP__
+#undef __DEC64_MAX__
+#undef __DEC64_MIN_EXP__
+#undef __DEC64_MIN__
diff --git a/utils/clang-completion-mode.el b/utils/clang-completion-mode.el
new file mode 100644
index 0000000..873127f
--- /dev/null
+++ b/utils/clang-completion-mode.el
@@ -0,0 +1,257 @@
+;;; Clang Code-Completion minor mode, for use with C/Objective-C/C++.
+
+;;; Commentary:
+
+;; This minor mode uses Clang's command line interface for code
+;; completion to provide code completion results for C, Objective-C,
+;; and C++ source files. When enabled, Clang will provide
+;; code-completion results in a secondary buffer based on the code
+;; being typed. For example, after typing "struct " (triggered via the
+;; space), Clang will provide the names of all structs visible from
+;; the current scope. After typing "p->" (triggered via the ">"),
+;; Clang will provide the names of all of the members of whatever
+;; class/struct/union "p" points to. Note that this minor mode isn't
+;; meant for serious use: it is meant to help experiment with code
+;; completion based on Clang. It needs your help to make it better!
+;;
+;; To use the Clang code completion mode, first make sure that the
+;; "clang" variable below refers to the "clang" executable,
+;; which is typically installed in libexec/. Then, place
+;; clang-completion-mode.el somewhere in your Emacs load path. You can
+;; add a new load path to Emacs by adding some like the following to
+;; your .emacs:
+;;
+;;   (setq load-path (cons "~/.emacs.d" load-path))
+;;
+;; Then, use
+;;
+;;   M-x load-library
+;;
+;; to load the library in your Emacs session or add the following to
+;; your .emacs to always load this mode (not recommended):
+;;
+;;   (load-library "clang-completion-mode")
+;;
+;; Finally, to try Clang-based code completion in a particular buffer,
+;; use M-x clang-completion-mode. When "Clang-CC" shows up in the mode
+;; line, Clang's code-completion is enabled.
+;;
+;; Clang's code completion is based on parsing the complete source
+;; file up to the point where the cursor is located. Therefore, Clang
+;; needs all of the various compilation flags (include paths, dialect
+;; options, etc.) to provide code-completion results. Currently, these
+;; need to be placed into the clang-flags variable in a format
+;; acceptable to clang. This is a hack: patches are welcome to
+;; improve the interface between this Emacs mode and Clang! 
+;;
+
+;;; Code:
+;;; The clang executable
+(defcustom clang "clang"
+  "The location of the Clang compiler executable"
+  :type 'file
+  :group 'clang-completion-mode)
+
+;;; Extra compilation flags to pass to clang.
+(defcustom clang-flags ""
+  "Extra flags to pass to the Clang executable.
+This variable will typically contain include paths, e.g., -I~/MyProject."
+  :type 'string
+  :group 'clang-completion-mode)
+
+;;; The prefix header to use with Clang code completion. 
+(setq clang-completion-prefix-header "")
+
+;;; The substring we will use to filter completion results
+(setq clang-completion-substring "")
+
+;;; The current completion buffer
+(setq clang-completion-buffer nil)
+
+(setq clang-result-string "")
+
+;;; Compute the current line in the buffer	
+(defun current-line ()
+  "Return the vertical position of point..."
+  (+ (count-lines (point-min) (point))
+     (if (= (current-column) 0) 1 0)
+     -1))
+
+;;; Set the Clang prefix header
+(defun clang-prefix-header ()
+  (interactive)
+  (setq clang-completion-prefix-header
+        (read-string "Clang prefix header> " "" clang-completion-prefix-header
+                     "")))
+
+;; Process "filter" that keeps track of the code-completion results
+;; produced. We store all of the results in a string, then the
+;; sentinel processes the entire string at once.
+(defun clang-completion-stash-filter (proc string)
+  (setq clang-result-string (concat clang-result-string string)))
+
+;; Filter the given list based on a predicate.
+(defun filter (condp lst)
+    (delq nil
+          (mapcar (lambda (x) (and (funcall condp x) x)) lst)))
+
+;; Determine whether 
+(defun is-completion-line (line)
+  (or (string-match "OVERLOAD:" line)
+      (string-match (concat "COMPLETION: " clang-completion-substring) line)))
+
+(defun clang-completion-display (buffer)
+  (let* ((all-lines (split-string clang-result-string "\n"))
+         (completion-lines (filter 'is-completion-line all-lines)))
+    (if (consp completion-lines)
+        (progn
+         ;; Erase the process buffer
+         (let ((cur (current-buffer)))
+           (set-buffer buffer)
+           (goto-char (point-min))
+           (erase-buffer)
+           (set-buffer cur))
+         
+         ;; Display the process buffer
+         (display-buffer buffer)
+         
+         ;; Insert the code-completion string into the process buffer.
+         (with-current-buffer buffer
+           (insert (mapconcat 'identity completion-lines "\n")))
+         ))))
+
+;; Process "sentinal" that, on successful code completion, replaces the 
+;; contents of the code-completion buffer with the new code-completion results
+;; and ensures that the buffer is visible.
+(defun clang-completion-sentinel (proc event)
+  (let* ((all-lines (split-string clang-result-string "\n"))
+         (completion-lines (filter 'is-completion-line all-lines)))
+    (if (consp completion-lines)
+        (progn
+         ;; Erase the process buffer
+         (let ((cur (current-buffer)))
+           (set-buffer (process-buffer proc))
+           (goto-char (point-min))
+           (erase-buffer)
+           (set-buffer cur))
+         
+         ;; Display the process buffer
+         (display-buffer (process-buffer proc))
+         
+         ;; Insert the code-completion string into the process buffer.
+         (with-current-buffer (process-buffer proc)
+           (insert (mapconcat 'identity completion-lines "\n")))
+         ))))
+
+(defun clang-complete ()
+  (let* ((cc-point (concat (buffer-file-name)
+                           ":"
+                           (number-to-string (+ 1 (current-line)))
+                           ":"
+                           (number-to-string (+ 1 (current-column)))))
+         (cc-pch (if (equal clang-completion-prefix-header "") nil
+                   (list "-include-pch"
+                         (concat clang-completion-prefix-header ".pch"))))
+         (cc-flags (if (listp clang-flags) clang-flags nil))
+         (cc-command (append `(,clang "-cc1" "-fsyntax-only")
+                             cc-flags
+                             cc-pch
+                             `("-code-completion-at" ,cc-point)
+                             (list (buffer-file-name))))
+         (cc-buffer-name (concat "*Clang Completion for " (buffer-name) "*")))
+    ;; Start the code-completion process
+    (if (buffer-file-name)
+        (progn
+          ;; If there is already a code-completion process, kill it first.
+          (let ((cc-proc (get-process "Clang Code-Completion")))
+            (if cc-proc
+                (delete-process cc-proc)))
+
+          (setq clang-completion-substring "")
+          (setq clang-result-string "")
+          (setq clang-completion-buffer cc-buffer-name)
+            
+          (let ((cc-proc (apply 'start-process
+                                (append (list "Clang Code-Completion" cc-buffer-name)
+                                        cc-command))))
+            (set-process-filter cc-proc 'clang-completion-stash-filter)
+            (set-process-sentinel cc-proc 'clang-completion-sentinel)
+            )))))
+
+;; Code-completion when one of the trigger characters is typed into
+;; the buffer, e.g., '(', ',' or '.'.
+(defun clang-complete-self-insert (arg)
+  (interactive "p")
+  (self-insert-command arg)
+  (save-buffer)
+  (clang-complete))
+
+;; When the user has typed a character that requires the filter to be
+;; updated, do so (and update the display of results).
+(defun clang-update-filter ()
+  (setq clang-completion-substring (thing-at-point 'symbol))
+  (if (get-process "Clang Code-Completion")
+      ()
+    (clang-completion-display clang-completion-buffer)
+    ))
+  
+;; Invoked when the user types an alphanumeric character or "_" to
+;; update the filter for the currently-active code completion.
+(defun clang-filter-self-insert (arg)
+  (interactive "p")
+  (self-insert-command arg)
+  (clang-update-filter)
+  )
+
+;; Invoked when the user types the backspace key to update the filter
+;; for the currently-active code completion.
+(defun clang-backspace ()
+  (interactive)
+  (delete-backward-char 1)
+  (clang-update-filter))
+
+;; Invoked when the user types the delete key to update the filter
+;; for the currently-active code completion.
+(defun clang-delete ()
+  (interactive)
+  (delete-backward-char 1)
+  (clang-update-filter))
+
+;; Set up the keymap for the Clang minor mode.
+(defvar clang-completion-mode-map nil
+  "Keymap for Clang Completion Mode.")
+
+(if (null clang-completion-mode-map)
+    (fset 'clang-completion-mode-map 
+          (setq clang-completion-mode-map (make-sparse-keymap))))
+
+(if (not (assq 'clang-completion-mode minor-mode-map-alist))
+    (setq minor-mode-map-alist
+          (cons (cons 'clang-completion-mode clang-completion-mode-map)
+                minor-mode-map-alist)))
+
+;; Punctuation characters trigger code completion.
+(dolist (char '("(" "," "." ">" ":" "=" ")" " "))
+  (define-key clang-completion-mode-map char 'clang-complete-self-insert))
+
+;; Alphanumeric characters (and "_") filter the results of the
+;; currently-active code completion.
+(dolist (char '("A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N" "O"
+                "P" "Q" "R" "S" "T" "U" "V" "W" "X" "Y" "Z"
+                "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o"
+                "p" "q" "r" "s" "t" "u" "v" "w" "x" "y" "z"
+                "_" "0" "1" "2" "3" "4" "5" "6" "7" "8" "9"))
+  (define-key clang-completion-mode-map char 'clang-filter-self-insert))
+
+;; Delete and backspace filter the results of the currently-active
+;; code completion.
+(define-key clang-completion-mode-map [(backspace)] 'clang-backspace)
+(define-key clang-completion-mode-map [(delete)] 'clang-delete)
+
+;; Set up the Clang minor mode.
+(define-minor-mode clang-completion-mode 
+  "Clang code-completion mode"
+  nil
+  " Clang"
+  clang-completion-mode-map)
+
diff --git a/utils/token-delta.py b/utils/token-delta.py
new file mode 100755
index 0000000..327fa92
--- /dev/null
+++ b/utils/token-delta.py
@@ -0,0 +1,251 @@
+#!/usr/bin/env python
+
+import os
+import re
+import subprocess
+import sys
+import tempfile
+
+###
+
+class DeltaAlgorithm(object):
+    def __init__(self):
+        self.cache = set()
+
+    def test(self, changes):
+        abstract
+
+    ###
+
+    def getTestResult(self, changes):
+        # There is no reason to cache successful tests because we will
+        # always reduce the changeset when we see one.
+
+        changeset = frozenset(changes)
+        if changeset in self.cache:
+            return False
+        elif not self.test(changes):
+            self.cache.add(changeset)
+            return False
+        else:
+            return True
+
+    def run(self, changes, force=False):
+        # Make sure the initial test passes, if not then (a) either
+        # the user doesn't expect monotonicity, and we may end up
+        # doing O(N^2) tests, or (b) the test is wrong. Avoid the
+        # O(N^2) case unless user requests it.
+        if not force:
+            if not self.getTestResult(changes):
+                raise ValueError,'Initial test passed to delta fails.'
+
+        # Check empty set first to quickly find poor test functions.
+        if self.getTestResult(set()):
+            return set()
+        else:
+            return self.delta(changes, self.split(changes))
+
+    def split(self, S):
+        """split(set) -> [sets]
+
+        Partition a set into one or two pieces.
+        """
+
+        # There are many ways to split, we could do a better job with more
+        # context information (but then the API becomes grosser).
+        L = list(S)
+        mid = len(L)//2
+        if mid==0:
+            return L,
+        else:
+            return L[:mid],L[mid:]
+    
+    def delta(self, c, sets):
+        # assert(reduce(set.union, sets, set()) == c)
+
+        # If there is nothing left we can remove, we are done.
+        if len(sets) <= 1:
+            return c
+        
+        # Look for a passing subset.
+        res = self.search(c, sets)
+        if res is not None:
+            return res
+
+        # Otherwise, partition sets if possible; if not we are done.
+        refined = sum(map(list, map(self.split, sets)), [])
+        if len(refined) == len(sets):
+            return c
+        
+        return self.delta(c, refined)
+
+    def search(self, c, sets):
+        for i,S in enumerate(sets):
+            # If test passes on this subset alone, recurse.
+            if self.getTestResult(S):
+                return self.delta(S, self.split(S))
+
+            # Otherwise if we have more than two sets, see if test
+            # pases without this subset.
+            if len(sets) > 2:
+                complement = sum(sets[:i] + sets[i+1:],[])
+                if self.getTestResult(complement):
+                    return self.delta(complement, sets[:i] + sets[i+1:])
+
+###
+
+class Token:
+    def __init__(self, type, data, flags, file, line, column):
+        self.type   = type
+        self.data   = data
+        self.flags  = flags
+        self.file   = file
+        self.line   = line
+        self.column = column
+        
+kTokenRE = re.compile(r"""([a-z_]+) '(.*)'\t(.*)\tLoc=<(.*):(.*):(.*)>""",
+                      re.DOTALL | re.MULTILINE)
+
+def getTokens(path):
+    p = subprocess.Popen(['clang','-dump-raw-tokens',path],
+                         stdin=subprocess.PIPE,
+                         stdout=subprocess.PIPE,
+                         stderr=subprocess.PIPE)
+    out,err = p.communicate()
+
+    tokens = []
+    collect = None
+    for ln in err.split('\n'):
+        # Silly programmers refuse to print in simple machine readable
+        # formats. Whatever.
+        if collect is None:
+            collect = ln
+        else:
+            collect = collect + '\n' + ln
+        if 'Loc=<' in ln and ln.endswith('>'):
+            ln,collect = collect,None
+            tokens.append(Token(*kTokenRE.match(ln).groups()))
+
+    return tokens
+
+###
+
+class TMBDDelta(DeltaAlgorithm):
+    def __init__(self, testProgram, tokenLists, log):
+        def patchName(name, suffix):
+            base,ext = os.path.splitext(name)
+            return base + '.' + suffix + ext
+        super(TMBDDelta, self).__init__()
+        self.testProgram = testProgram
+        self.tokenLists = tokenLists
+        self.tempFiles = [patchName(f,'tmp')
+                            for f,_ in self.tokenLists]
+        self.targetFiles = [patchName(f,'ok')
+                            for f,_ in self.tokenLists]
+        self.log = log
+        self.numTests = 0
+
+    def writeFiles(self, changes, fileNames):
+        assert len(fileNames) == len(self.tokenLists)
+        byFile = [[] for i in self.tokenLists]
+        for i,j in changes:
+            byFile[i].append(j)
+
+        for i,(file,tokens) in enumerate(self.tokenLists):
+            f = open(fileNames[i],'w')
+            for j in byFile[i]:
+                f.write(tokens[j])
+            f.close()
+
+        return byFile
+
+    def test(self, changes):
+        self.numTests += 1
+
+        byFile = self.writeFiles(changes, self.tempFiles)
+
+        if self.log:
+            print >>sys.stderr, 'TEST - ',
+            if self.log > 1:
+                for i,(file,_) in enumerate(self.tokenLists):
+                    indices = byFile[i]
+                    if i:
+                        sys.stderr.write('\n      ')
+                    sys.stderr.write('%s:%d tokens: [' % (file,len(byFile[i])))
+                    prev = None
+                    for j in byFile[i]:
+                        if prev is None or j != prev + 1:
+                            if prev:
+                                sys.stderr.write('%d][' % prev)
+                            sys.stderr.write(str(j))
+                            sys.stderr.write(':')
+                        prev = j
+                    if byFile[i]:
+                        sys.stderr.write(str(byFile[i][-1]))
+                    sys.stderr.write('] ')
+            else:
+                print >>sys.stderr, ', '.join(['%s:%d tokens' % (file, len(byFile[i]))
+                                               for i,(file,_) in enumerate(self.tokenLists)]),
+
+        p = subprocess.Popen([self.testProgram] + self.tempFiles)
+        res = p.wait() == 0
+
+        if res:
+            self.writeFiles(changes, self.targetFiles)
+
+        if self.log:
+            print >>sys.stderr, '=> %s' % res
+        else:
+            if res:
+                print '\nSUCCESS (%d tokens)' % len(changes)
+            else:                
+                sys.stderr.write('.')
+
+        return res
+
+    def run(self):
+        res = super(TMBDDelta, self).run([(i,j)
+                                          for i,(file,tokens) in enumerate(self.tokenLists)
+                                          for j in range(len(tokens))])
+        self.writeFiles(res, self.targetFiles)
+        if not self.log:
+            print >>sys.stderr
+        return res
+
+def tokenBasedMultiDelta(program, files, log):            
+    # Read in the lists of tokens.
+    tokenLists = [(file, [t.data for t in getTokens(file)])
+                  for file in files]
+
+    numTokens = sum([len(tokens) for _,tokens in tokenLists])
+    print "Delta on %s with %d tokens." % (', '.join(files), numTokens)
+    
+    tbmd = TMBDDelta(program, tokenLists, log)
+
+    res = tbmd.run()
+
+    print "Finished %s with %d tokens (in %d tests)." % (', '.join(tbmd.targetFiles),
+                                                         len(res),
+                                                         tbmd.numTests)
+        
+def main():
+    from optparse import OptionParser, OptionGroup
+    parser = OptionParser("%prog <test program> {files+}")
+    parser.add_option("", "--debug", dest="debugLevel",
+                     help="set debug level [default %default]",
+                     action="store", type=int, default=0)
+    (opts, args) = parser.parse_args()
+
+    if len(args) <= 1:
+        parser.error('Invalid number of arguments.')
+        
+    program,files = args[0],args[1:]
+
+    md = tokenBasedMultiDelta(program, files, log=opts.debugLevel)
+        
+if __name__ == '__main__':
+    try:
+        main()
+    except KeyboardInterrupt:
+        print >>sys.stderr,'Interrupted.'
+        os._exit(1) # Avoid freeing our giant cache.
diff --git a/utils/valgrind/x86_64-pc-linux-gnu_gcc-4.3.3.supp b/utils/valgrind/x86_64-pc-linux-gnu_gcc-4.3.3.supp
new file mode 100644
index 0000000..a86be6c
--- /dev/null
+++ b/utils/valgrind/x86_64-pc-linux-gnu_gcc-4.3.3.supp
@@ -0,0 +1,23 @@
+{
+   libstdcxx_overlapped_memcpy_in_stable_sort_1
+   Memcheck:Overlap
+   fun:memcpy
+   ...
+   fun:_ZSt11stable_sortIN9__gnu_cxx17__normal_iteratorIPSt4pairIPKN4llvm5ValueEjESt6vectorIS7_SaIS7_EEEEN12_GLOBAL__N_116CstSortPredicateEEvT_SF_T0_
+}
+
+{
+   libstdcxx_overlapped_memcpy_in_stable_sort_2
+   Memcheck:Overlap
+   fun:memcpy
+   ...
+   fun:_ZSt11stable_sortIN9__gnu_cxx17__normal_iteratorIPSt4pairIPKN4llvm5ValueEjESt6vectorIS7_SaIS7_EEEEN12_GLOBAL__N_116CstSortPredicateEEvT_SF_T0_
+}
+
+{
+   libstdcxx_overlapped_memcpy_in_stable_sort_3
+   Memcheck:Overlap
+   fun:memcpy
+   ...
+   fun:_ZSt11stable_sortIN9__gnu_cxx17__normal_iteratorIPSt4pairIPKN4llvm4TypeEjESt6vectorIS7_SaIS7_EEEEPFbRKS7_SE_EEvT_SH_T0_
+}
diff --git a/www/CheckerNotes.html b/www/CheckerNotes.html
new file mode 100644
index 0000000..523048d
--- /dev/null
+++ b/www/CheckerNotes.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+<title>Static Analysis</title>
+<meta http-equiv="REFRESH" content="0;url=http://clang.llvm.org/StaticAnalysis.html"></HEAD>
+<BODY>
+This page has relocated: <a href="http://clang.llvm.org/StaticAnalysis.html">http://clang.llvm.org/StaticAnalysis.html</a>.
+</BODY>
+</HTML>
diff --git a/www/OpenProjects.html b/www/OpenProjects.html
new file mode 100644
index 0000000..46d9716
--- /dev/null
+++ b/www/OpenProjects.html
@@ -0,0 +1,114 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+          "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+  <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
+  <title>Clang - Get Involved</title>
+  <link type="text/css" rel="stylesheet" href="menu.css" />
+  <link type="text/css" rel="stylesheet" href="content.css" />
+</head>
+<body>
+
+<!--#include virtual="menu.html.incl"-->
+
+<div id="content">
+
+<h1>Open Clang Projects</h1>
+
+<p>Here are a few tasks that are available for newcomers to work on, depending
+on what your interests are.  This list is provided to generate ideas, it is not
+intended to be comprehensive.  Please ask on cfe-dev for more specifics or to
+verify that one of these isn't already completed. :)</p>
+
+<ul>
+<li><b>Compile your favorite C/ObjC project with Clang</b>:
+Clang's type-checking and code generation is very close to complete (but not bug free!) for C and Objective-C. We appreciate all reports of code that is
+rejected or miscompiled by the front-end. If you notice invalid code that is not rejected, or poor diagnostics when code is rejected, that is also very important to us.  For make-based projects,
+the <a href="get_started.html#driver"><code>clang</code></a> driver works as a drop-in replacement for GCC.</li>
+
+<li><b>Undefined behavior checking</b>: CodeGen could
+insert runtime checks for all sorts of different undefined behaviors, from 
+reading uninitialized variables, buffer overflows, and many other things.  This
+checking would be expensive, but the optimizers could eliminate many of the 
+checks in some cases, and it would be very interesting to test code in this mode
+for certain crowds of people.  Because the inserted code is coming from clang,
+the "abort" message could be very detailed about exactly what went wrong.</li>
+
+<li><b>Improve target support</b>: The current target interfaces are heavily
+stubbed out and need to be implemented fully.  See the FIXME's in TargetInfo.
+Additionally, the actual target implementations (instances of TargetInfoImpl)
+also need to be completed.</li>
+
+<li><b>Implement an tool to generate code documentation</b>: Clang's
+library-based design allows it to be used by a variety of tools that reason
+about source code. One great application of Clang would be to build an
+auto-documentation system like doxygen that generates code documentation from
+source code. The advantage of using Clang for such a tool is that the tool would
+use the same preprocessor/parser/ASTs as the compiler itself, giving it a very
+rich understanding of the code.</li> 
+
+<li><b>Use clang libraries to implement better versions of existing tools</b>:
+Clang is built as a set of libraries, which means that it is possible to
+implement capabilities similar to other source language tools, improving them
+in various ways.  Two examples are <a href="http://distcc.samba.org/">distcc</a>
+and the <a href="http://delta.tigris.org/">delta testcase reduction tool</a>.
+The former can be improved to scale better and be more efficient.  The latter
+could also be faster and more efficient at reducing C-family programs if built
+on the clang preprocessor.</li>
+
+<li><b>Use clang libraries to extend Ragel with a JIT</b>: <a 
+href="http://research.cs.queensu.ca/~thurston/ragel/">Ragel</a> is a state
+machine compiler that lets you embed C code into state machines and generate
+C code.  It would be relatively easy to turn this into a JIT compiler using
+LLVM.</li>
+
+<li><b>Self-testing using clang</b>: There are several neat ways to
+improve the quality of clang by self-testing. Some examples:
+<ul>
+  <li>Improve the reliability of AST printing and serialization by
+  ensuring that the AST produced by clang on an input doesn't change
+  when it is reparsed or unserialized.
+
+  <li>Improve parser reliability and error generation by automatically
+  or randomly changing the input checking that clang doesn't crash and
+  that it doesn't generate excessive errors for small input
+  changes. Manipulating the input at both the text and token levels is
+  likely to produce interesting test cases.
+</ul>
+</li>
+
+<li><b>Continue work on C++ support</b>: Implementing all of C++ is a very big
+job, but there are lots of little pieces that can be picked off and implemented. Here are some small- to mid-sized C++ implementation projects:
+<ul>
+  <li>Fix bugs: there are a number of XFAIL'd test cases in Clang's repository (particularly in the CXX subdirectory). Pick a test case and fix Clang to make it work!</li>
+  <li>Write tests: the CXX test subdirectory in Clang's repository has placeholders for tests of every paragraph in the C++ standard. Pick a paragraph, write a few tests, and see if they work! Even if they don't we'd still like the new tests (with XFAIL'd) so that we know what to fix.</li>
+  <li>Parsing and semantic analysis for using declarations in classes</li>
+  <li>Inherited conversion functions</li>
+  <li>Improved diagnostics for overloading failures and ambiguities</li>
+  <li>Improved template error messages, e.g., with more informative backtraces</li>
+</ul>
+  
+Also, see the <a href="cxx_status.html">C++ status report page</a> to
+find out what is missing and what is already at least partially
+supported.</li>
+</ul>
+
+<p>If you hit a bug with clang, it is very useful for us if you reduce the code
+that demonstrates the problem down to something small.  There are many ways to
+do this; ask on cfe-dev for advice.</p>
+
+<li><b>StringRef'ize APIs</b>: A thankless but incredibly useful project is
+StringRef'izing (converting to use <tt>llvm::StringRef</tt> instead of <tt>const
+char *</tt> or <tt>std::string</tt>) various clang interfaces. This generally
+simplifies the code and makes it more efficient.</li>
+
+<li><b>Universal Driver</b>: Clang is inherently a cross compiler. We would like
+to define a new model for cross compilation which provides a great user
+experience -- it should be easy to cross compile applications, install support
+for new architectures, access different compilers and tools, and be consistent
+across different platforms. See the <a href="UniversalDriver.html">Universal
+Driver</a> web page for more information.</li>
+
+</div>
+</body>
+</html>
diff --git a/www/StaticAnalysis.html b/www/StaticAnalysis.html
new file mode 100644
index 0000000..a701c0f
--- /dev/null
+++ b/www/StaticAnalysis.html
@@ -0,0 +1,21 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+          "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+  <meta HTTP-EQUIV="REFRESH" content="0; url=http://clang-analyzer.llvm.org">
+  <title>LLVM/Clang Static Analyzer</title>
+  <link type="text/css" rel="stylesheet" href="menu.css" />
+  <link type="text/css" rel="stylesheet" href="content.css" />
+</head>
+<body>
+
+<!--#include virtual="menu.html.incl"-->
+
+<div id="content">
+
+<p>This page has moved: <a href="http://clang-analyzer.llvm.org">clang.analyzer.llvm.org</a>.</p>
+
+</div>
+</body>
+</html>
+
diff --git a/www/StaticAnalysisUsage.html b/www/StaticAnalysisUsage.html
new file mode 100644
index 0000000..a701c0f
--- /dev/null
+++ b/www/StaticAnalysisUsage.html
@@ -0,0 +1,21 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+          "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+  <meta HTTP-EQUIV="REFRESH" content="0; url=http://clang-analyzer.llvm.org">
+  <title>LLVM/Clang Static Analyzer</title>
+  <link type="text/css" rel="stylesheet" href="menu.css" />
+  <link type="text/css" rel="stylesheet" href="content.css" />
+</head>
+<body>
+
+<!--#include virtual="menu.html.incl"-->
+
+<div id="content">
+
+<p>This page has moved: <a href="http://clang-analyzer.llvm.org">clang.analyzer.llvm.org</a>.</p>
+
+</div>
+</body>
+</html>
+
diff --git a/www/UniversalDriver.html b/www/UniversalDriver.html
new file mode 100644
index 0000000..82ccc8d
--- /dev/null
+++ b/www/UniversalDriver.html
@@ -0,0 +1,87 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+          "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+  <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
+  <title>Clang - Universal Driver</title>
+  <link type="text/css" rel="stylesheet" href="menu.css" />
+  <link type="text/css" rel="stylesheet" href="content.css" />
+</head>
+<body>
+
+<!--#include virtual="menu.html.incl"-->
+
+<div id="content">
+
+<h1>The Clang Universal Driver Project</h1>
+
+<p>Clang is inherently a cross compiler, in that it is always capable of
+building code for targets which are a different architecture or even operating
+system from the one running the compiler. However, actually cross compiling in
+practice involves much more than just generating the right assembly code for a
+target, it also requires having an appropriate tool chain (assemblers, linkers),
+access to header files and libraries for the target, and many other details (for
+example, the calling convention or whether software floating point is in
+use). Traditionally, compilers and development environments provide little
+assistance with this process, so users do not have easy access to the powerful
+underlying cross-compilation abilities of clang.</p>
+
+<p>We would like to solve this problem by defining a new model for how cross
+compilation is done, based on the idea of a <i>universal driver</i>. The key
+point of this model is that the user would always access the compiler through a
+single entry point (e.g., <tt>/usr/bin/cc</tt>) and provide an argument
+specifying the <i>configuration</i> they would like to target. Under the hood
+this entry point (the universal driver) would have access to all the information
+that the driver, compiler, and other tools need to build applications for that
+target.</p>
+
+<p>This is a large and open-ended project. It's eventual success depends not
+just on implementing the model, but also on getting buy-in from compiler
+developers, operating system distribution vendors and the development community
+at large. Our plan is to begin by defining a clear list of the problems we want
+to solve and a proposed implementation (from the user perspective).</p>
+
+<p>This project is in the very early (i.e., thought experiment) stages of
+development. Stay tuned for more information, and of course, patches
+welcome!</p>
+
+<p>See also <a href="http://llvm.org/PR4127">PR4127</a>.</p>
+
+<h2>Existing Solutions and Related Work</h2>
+
+<ul>
+  <li>gcc's command line arguments <tt>-V</tt>, <tt>-B</tt>, <tt>-b</tt> are
+    generic but limited solutions to related problems. Similarly, <tt>-m32</tt>
+    and <tt>-m64</tt> solve a small subset of the problem for specific
+    architectures.</li>
+
+  <li>gcc's <a href="http://www.airs.com/ian/configure/configure_8.html">multilibs</a>
+    solve the part of the problem that relates to finding appropriate libraries
+    and include files based on particular feature support (soft float,
+    etc.).</li>
+
+  <li>Apple's "driver driver" supported by gcc and clang solve a subset of the
+    problem by supporting <tt>-arch</tt>. Apple also provides a tool chain which
+    supports <a href="http://en.wikipedia.org/wiki/Universal_binary">universal
+    binaries</a> and object files which may include data for multiple
+    architectures. See <a href="http://developer.apple.com/mac/library/technotes/tn2005/tn2137.html">TN2137</a>
+    for an example of how this is used.</li>
+
+  <li>Many operating systems and environments solve the problem by installing
+    complete development environments (including the IDE, tools, header files,
+    and libraries) for a single tool chain. This is cumbersome for users and
+    does not match well with tools which are inherently capable of cross
+    compiling.</li>
+
+  <li>The Debian <a href="http://wiki.debian.org/ArmEabiPort">ArmEabiPort</a>
+    wiki page for their work to support the ARM EABI provide an interesting
+    glimpse into how related issues impact the operating system distribution.</li>
+
+  <li><a href="http://icculus.org/fatelf/">FatELF</a> is a proposal for bringing
+    Mac OS X like "Universal Binary" support to ELF based platforms.</li>
+
+</ul>
+
+</div>
+</body>
+</html>
diff --git a/www/analyzer/annotations.html b/www/analyzer/annotations.html
new file mode 100644
index 0000000..6204713
--- /dev/null
+++ b/www/analyzer/annotations.html
@@ -0,0 +1,396 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+          "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+  <title>Source Annotations</title>
+  <link type="text/css" rel="stylesheet" href="menu.css" />
+  <link type="text/css" rel="stylesheet" href="content.css" />
+  <script type="text/javascript" src="scripts/menu.js"></script>
+  <script type="text/javascript" src="scripts/dbtree.js"></script>
+</head>
+<body>
+
+<div id="page">
+<!--#include virtual="menu.html.incl"-->
+
+<div id="content">
+
+<h1>Source Annotations</h1>
+
+<p>The Clang frontend supports several source-level annotations in the form of
+<a href="http://gcc.gnu.org/onlinedocs/gcc/Attribute-Syntax.html">GCC-style
+attributes</a> and pragmas that can help make using the Clang Static Analyzer
+more useful. These annotations can both help suppress false positives as well as
+enhance the analyzer's ability to find bugs.</p>
+
+<p>This page gives a practical overview of such annotations. For more technical
+specifics regarding Clang-specific annotations please see the Clang's list of <a
+href="http://clang.llvm.org/docs/LanguageExtensions.html">language
+extensions</a>. Details of &quot;standard&quot; GCC attributes (that Clang also
+supports) can be found in the <a href="http://gcc.gnu.org/onlinedocs/gcc/">GCC
+manual</a>, with the majority of the relevant attributes being in the section on
+<a href="http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html">function
+attributes</a>.</p>
+
+<p>Note that attributes that are labeled <b>Clang-specific</b> are not
+recognized by GCC. Their use can be conditioned using preprocessor macros
+(examples included on this page).</p>
+
+<h4>Specific Topics</h4>
+
+<ul id="collapsetree" class="dbtree onclick multiple">
+<li><a href="#generic">Annotations to Enhance Generic Checks</a>
+  <ul>
+    <li><a href="#null_checking"><span>Null Pointer Checking</span></a>
+    <ul>
+      <li><a href="#attr_nonnull"><span>Attribute 'nonnull'</span></a></li>
+    </ul>
+    </li>
+  </ul>
+</li>
+<li><a href="#macosx">Mac OS X API Annotations</a>
+  <ul>
+    <li><a href="#cocoa_mem">Cocoa &amp; Core Foundation Memory Management Annotations</a>
+    <ul>
+      <li><a href="#attr_ns_returns_retained">Attribute 'ns_returns_retained'</a></li>
+      <li><a href="#attr_cf_returns_retained">Attribute 'cf_returns_retained'</a></li>
+    </ul>
+    </li>
+  </ul>
+</li>
+<li><a href="#custom_assertions">Custom Assertion Handlers</a>
+  <ul>
+    <li><a href="#attr_noreturn">Attribute 'noreturn'</a></li>
+    <li><a href="#attr_analyzer_noreturn">Attribute 'analyzer_noreturn'</a></li>
+  </ul>
+  </li>
+</ul>
+
+<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+<h2 id="generic">Annotations to Enhance Generic Checks</h2>
+<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+<h3 id="null_checking">Null Pointer Checking</h3>
+
+<h4 id="attr_nonnull">Attribute 'nonnull'</h4>
+
+<p>The analyzer recognizes the GCC attribute 'nonnull', which indicates that a
+function expects that a given function parameter is not a null pointer. Specific
+details of the syntax of using the 'nonnull' attribute can be found in <a
+href="http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html#index-g_t_0040code_007bnonnull_007d-function-attribute-2263">GCC's
+documentation</a>.</p>
+
+<p>Both the Clang compiler and GCC will flag warnings for simple cases where a
+null pointer is directly being passed to a function with a 'nonnull' parameter
+(e.g., as a constant). The analyzer extends this checking by using its deeper
+symbolic analysis to track what pointer values are potentially null and then
+flag warnings when they are passed in a function call via a 'nonnull'
+parameter.</p>
+
+<p><b>Example</b></p>
+
+<pre class="code_example">
+<span class="command">$ cat test.m</span>
+int bar(int*p, int q, int *r) __attribute__((nonnull(1,3)));
+
+int foo(int *p, int *q) {
+   return !p ? bar(q, 2, p) 
+             : bar(p, 2, q);
+}
+</pre>
+
+<p>Running <tt>scan-build</tt> over this source produces the following
+output:</p>
+
+<img src="images/example_attribute_nonnull.png">
+
+<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+<h2 id="macosx">Mac OS X API Annotations</h2>
+<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+<h3 id="cocoa_mem">Cocoa &amp; Core Foundation Memory Management
+Annotations</h3>
+
+<!--
+<p>As described in <a href="/available_checks.html#retain_release">Available
+Checks</a>,
+-->
+<p>The analyzer supports the proper management of retain counts for
+both Cocoa and Core Foundation objects. This checking is largely based on
+enforcing Cocoa and Core Foundation naming conventions for Objective-C methods
+(Cocoa) and C functions (Core Foundation). Not strictly following these
+conventions can cause the analyzer to miss bugs or flag false positives.</p>
+
+<p>One can educate the analyzer (and others who read your code) about methods or
+functions that deviate from the Cocoa and Core Foundation conventions using the
+attributes described here.</p>
+
+<h4 id="attr_ns_returns_retained">Attribute 'ns_returns_retained'
+(Clang-specific)</h4>
+
+<p>The GCC-style (Clang-specific) attribute 'ns_returns_retained' allows one to
+annotate an Objective-C method or C function as returning a retained Cocoa
+object that the caller is responsible for releasing (via sending a
+<tt>release</tt> message to the object).</p>
+
+<p><b>Placing on Objective-C methods</b>: For Objective-C methods, this
+annotation essentially tells the analyzer to treat the method as if its name
+begins with &quot;alloc&quot; or &quot;new&quot; or contais the word
+&quot;copy&quot;.</p>
+
+<p><b>Placing on C functions</b>: For C functions returning Cocoa objects, the
+analyzer typically does not make any assumptions about whether or not the object
+is returned retained. Explicitly adding the 'ns_returns_retained' attribute to C
+functions allows the analyzer to perform extra checking.</p>
+
+<p><b>Important note when using Garbage Collection</b>: Note that the analyzer
+interprets this attribute slightly differently when using Objective-C garbage
+collection (available on Mac OS 10.5+). When analyzing Cocoa code that uses
+garbage collection, &quot;alloc&quot; methods are assumed to return an object
+that is managed by the garbage collector (and thus doesn't have a retain count
+the caller must balance). These same assumptions are applied to methods or
+functions annotated with 'ns_returns_retained'. If you are returning a Core
+Foundation object (which may not be managed by the garbage collector) you should
+use 'cf_returns_retained'.</p>
+
+<p><b>Example</b></p>
+
+<pre class="code_example">
+<span class="command">$ cat test.m</span>
+#import &lt;Foundation/Foundation.h&gt;
+
+#ifndef __has_feature      // Optional.
+#define __has_feature(x) 0 // Compatibility with non-clang compilers.
+#endif
+
+#ifndef NS_RETURNS_RETAINED
+#if __has_feature(attribute_ns_returns_retained)
+<span class="code_highlight">#define NS_RETURNS_RETAINED __attribute__((ns_returns_retained))</span>
+#else
+#define NS_RETURNS_RETAINED
+#endif
+#endif
+
+@interface MyClass : NSObject {}
+- (NSString*) returnsRetained <span class="code_highlight">NS_RETURNS_RETAINED</span>;
+- (NSString*) alsoReturnsRetained;
+@end
+
+@implementation MyClass
+- (NSString*) returnsRetained {
+  return [[NSString alloc] initWithCString:"no leak here"];
+}
+- (NSString*) alsoReturnsRetained {
+  return [[NSString alloc] initWithCString:"flag a leak"];
+}
+@end
+</pre>
+
+<p>Running <tt>scan-build</tt> on this source file produces the following output:</p>
+
+<img src="images/example_ns_returns_retained.png">
+
+<h4 id="attr_cf_returns_retained">Attribute 'cf_returns_retained'
+(Clang-specific)</h4>
+
+<p>The GCC-style (Clang-specific) attribute 'cf_returns_retained' allows one to
+annotate an Objective-C method or C function as returning a retained Core
+Foundation object that the caller is responsible for releasing. 
+
+<p><b>Placing on Objective-C methods</b>: With respect to Objective-C methods.,
+this attribute is identical in its behavior and usage to 'ns_returns_retained'
+except for the distinction of returning a Core Foundation object instead of a
+Cocoa object. This distinction is important for two reasons:</p>
+
+<ul>
+  <li>Core Foundation objects are not automatically managed by the Objective-C
+  garbage collector.</li>
+  <li>Because Core Foundation is a C API, the analyzer cannot always tell that a
+  pointer return value refers to a Core Foundation object. In contrast, it is
+  trivial for the analyzer to recognize if a pointer refers to a Cocoa object
+  (given the Objective-C type system).</p>
+</ul>
+
+<p><b>Placing on C functions</b>: When placing the attribute
+'cf_returns_retained' on the declarations of C functions, the analyzer
+interprets the function as:</p>
+
+<ol>
+  <li>Returning a Core Foundation Object</li>
+  <li>Treating the function as if it its name
+contained the keywords &quot;create&quot; or &quot;copy&quot;. This means the
+returned object as a +1 retain count that must be released by the caller, either
+by sending a <tt>release</tt> message (via toll-free bridging to an Objective-C
+object pointer), calling <tt>CFRelease</tt> (or similar function), or using
+<tt>CFMakeCollectable</tt> to register the object with the Objective-C garbage
+collector.</li>
+</ol>
+
+<p><b>Example</b></p>
+
+<p>In this example, observe the difference in output when the code is compiled
+to not use garbage collection versus when it is compiled to only use garbage
+collection (<tt>-fobjc-gc-only</tt>).</p>
+
+<pre class="code_example">
+<span class="command">$ cat test.m</span>
+$ cat test.m
+#import &lt;Cocoa/Cocoa.h&gt;
+
+#ifndef __has_feature      // Optional.
+#define __has_feature(x) 0 // Compatibility with non-clang compilers.
+#endif
+
+#ifndef CF_RETURNS_RETAINED
+#if __has_feature(attribute_cf_returns_retained)
+<span class="code_highlight">#define CF_RETURNS_RETAINED __attribute__((cf_returns_retained))</span>
+#else
+#define CF_RETURNS_RETAINED
+#endif
+#endif
+
+@interface MyClass : NSObject {}
+- (NSDate*) returnsCFRetained <span class="code_highlight">CF_RETURNS_RETAINED</span>;
+- (NSDate*) alsoReturnsRetained;
+- (NSDate*) returnsNSRetained <span class="code_highlight">NS_RETURNS_RETAINED</span>;
+@end
+
+<span class="code_highlight">CF_RETURNS_RETAINED</span>
+CFDateRef returnsRetainedCFDate()  {
+  return CFDateCreate(0, CFAbsoluteTimeGetCurrent());
+}
+
+@implementation MyClass
+- (NSDate*) returnsCFRetained {
+  return (NSDate*) returnsRetainedCFDate(); // No leak.
+}
+
+- (NSDate*) alsoReturnsRetained {
+  return (NSDate*) returnsRetainedCFDate(); // Always report a leak.
+}
+
+- (NSDate*) returnsNSRetained {
+  return (NSDate*) returnsRetainedCFDate(); // Report a leak when using GC.  
+}
+@end
+</pre>
+
+<p>Running <tt>scan-build</tt> on this example produces the following output:</p>
+
+<img src="images/example_cf_returns_retained.png">
+
+</p>When the above code is compiled using Objective-C garbage collection (i.e.,
+code is compiled with the flag <tt>-fobjc-gc</tt> or <tt>-fobjc-gc-only</tt>),
+<tt>scan-build</tt> produces both the above error (with slightly different text
+to indicate the code uses garbage collection) as well as the following warning,
+which indicates a leak that occurs <em>only</em> when using garbage
+collection:</p>
+
+<img src="images/example_cf_returns_retained_gc.png">
+
+<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+<h2 id="custom_assertions">Custom Assertion Handlers</h2>
+<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+<p>The analyzer exploits code assertions by pruning off paths where the
+assertion condition is false. The idea is capture any program invariants
+specified in the assertion that the developer may know but is not immediately
+apparent in the code itself. In this way assertions make implicit assumptions
+explicit in the code, which not only makes the analyzer more accurate when
+finding bugs, but can help others better able to understand your code as well.
+It can also help remove certain kinds of analyzer false positives by pruning off
+false paths.</p>
+
+<p>In order to exploit assertions, however, the analyzer must understand when it
+encounters an &quot;assertion handler.&quot; Typically assertions are
+implemented with a macro, with the macro performing a check for the assertion
+condition and, when the check fails, calling an assertion handler.  For example, consider the following code
+fragment:</p>
+
+<pre class="code_example">
+void foo(int *p) {
+  assert(p != NULL);
+}
+</pre>
+
+<p>When this code is preprocessed on Mac OS X it expands to the following:</p>
+
+<pre class="code_example">
+void foo(int *p) {
+  (__builtin_expect(!(p != NULL), 0) ? __assert_rtn(__func__, "t.c", 4, "p != NULL") : (void)0);
+}
+</pre>
+
+<p>In this example, the assertion handler is <tt>__assert_rtn</tt>. When called,
+most assertion handlers typically print an error and terminate the program. The
+analyzer can exploit such semantics by ending the analysis of a path once it
+hits a call to an assertion handler.</p>
+
+<p>The trick, however, is that the analyzer needs to know that a called function
+is an assertion handler; otherwise the analyzer might assume the function call
+returns and it will continue analyzing the path where the assertion condition
+failed. This can lead to false positives, as the assertion condition usually
+implies a safety condition (e.g., a pointer is not null) prior to performing
+some action that depends on that condition (e.g., dereferencing a pointer).</p>
+
+<p>The analyzer knows about several well-known assertion handlers, but can
+automatically infer if a function should be treated as an assertion handler if
+it is annotated with the 'noreturn' attribute or the (Clang-specific)
+'analyzer_noreturn' attribute.</p>
+
+<h4 id="attr_noreturn">Attribute 'noreturn'</h4>
+
+<p>The 'noreturn' attribute is a GCC-attribute that can be placed on the
+declarations of functions. It means exactly what its name implies: a function
+with a 'noreturn' attribute should never return.</p>
+
+<p>Specific details of the syntax of using the 'noreturn' attribute can be found
+in <a
+href="http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html#index-g_t_0040code_007bnoreturn_007d-function-attribute-2264">GCC's
+documentation</a>.</p>
+
+<p>Not only does the analyzer exploit this information when pruning false paths,
+but the compiler also takes it seriously and will generate different code (and
+possibly better optimized) under the assumption that the function does not
+return.</p>
+
+<p><b>Example</b></p>
+
+<p>On Mac OS X, the function prototype for <tt>__assert_rtn</tt> (declared in
+<tt>assert.h</tt>) is specifically annotated with the 'noreturn' attribute:</p>
+
+<pre class="code_example">
+void __assert_rtn(const char *, const char *, int, const char *) <span class="code_highlight">__attribute__((__noreturn__))</span>;
+</pre>
+
+<h4 id="attr_analyzer_noreturn">Attribute 'analyzer_noreturn' (Clang-specific)</h4>
+
+<p>The Clang-specific 'analyzer_noreturn' attribute is almost identical to
+'noreturn' except that it is ignored by the compiler for the purposes of code
+generation.</p>
+
+<p>This attribute is useful for annotating assertion handlers that actually
+<em>can</em> return, but for the purpose of using the analyzer we want to
+pretend that such functions do not return.</p>
+
+<p>Because this attribute is Clang-specific, its use should be conditioned with
+the use of preprocessor macros.</p>
+
+<p><b>Example</b>
+
+<pre class="code_example">
+#ifndef CLANG_ANALYZER_NORETURN
+#if __clang__
+<span class="code_highlight">#define CLANG_ANALYZER_NORETURN __attribute__((analyzer_noreturn))</span>
+#else
+#define CLANG_ANALYZER_NORETURN
+#endif
+
+void my_assert_rtn(const char *, const char *, int, const char *) <span class="code_highlight">CLANG_ANALYZER_NORETURN</span>;
+</pre>
+
+</div>
+</div>
+</body>
+</html>
+
diff --git a/www/analyzer/available_checks.html b/www/analyzer/available_checks.html
new file mode 100644
index 0000000..7af0865
--- /dev/null
+++ b/www/analyzer/available_checks.html
@@ -0,0 +1,37 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+          "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+  <title>Available Checks</title>
+  <link type="text/css" rel="stylesheet" href="menu.css" />
+  <link type="text/css" rel="stylesheet" href="content.css" />
+  <script type="text/javascript" src="scripts/menu.js"></script>
+</head>
+<body>
+
+<div id="page">
+<!--#include virtual="menu.html.incl"-->
+
+<div id="content">
+
+<h1>Available Checks</h1>
+
+<p>This page is slated to contain a list of the current checks the analyzer
+performs along with some self-contained code examples. In the meantime, please
+check out any of the following writeups about the analyzer that contain examples
+of some of the bugs that it finds:</p>
+
+<ul>
+<li><a href="http://www.mobileorchard.com/bug-finding-with-clang-5-resources-to-get-you-started/">Bug Finding With Clang: 5 Resources To Get You Started</a></li>
+<li><a href="http://fruitstandsoftware.com/blog/index.php/2008/08/finding-memory-leaks-with-the-llvmclang-static-analyzer/#comment-2">Finding Memory Leaks With The LLVM/Clang Static Analyzer</a></li>
+<li><a href="http://www.therareair.com/howto-static-analyze-your-objective-c-code-using-the-clang-static-analyzer-tool-gallery/">HOWTO: Static Analyze Your Objective-C Code Using the Clang Static Analyzer Tool Gallery</a></li>
+<li><a href="http://www.rogueamoeba.com/utm/2008/07/14/the-clang-static-analyzer/">Under the Microscope - The Clang Static Analyzer</a></li>
+<li><a href="http://www.mikeash.com/?page=pyblog/friday-qa-2009-03-06-using-the-clang-static-analyzer.html">Mike Ash - Using the Clang Static Analyzer</a></li>
+</ul>
+
+
+</div>
+</div>
+</body>
+</html>
+
diff --git a/www/analyzer/content.css b/www/analyzer/content.css
new file mode 100644
index 0000000..b22cca9
--- /dev/null
+++ b/www/analyzer/content.css
@@ -0,0 +1,79 @@
+html { margin: 0px; } body { margin: 8px; }
+
+html, body {
+  padding:0px;
+  margin:0px;
+  font-size:small; font-family:"Lucida Grande", "Lucida Sans Unicode", Arial, Verdana, Helvetica, sans-serif; background-color: #fff; color: #222;
+  line-height:1.5;
+  background-color: #808080;
+  
+}
+
+h1, h2, h3, tt { color: #000 }
+
+h1 { padding-top:0px; margin-top:0px;}
+h2 { color:#333333; padding-top:0.5em; }
+h3 { padding-top: 0.5em; margin-bottom: -0.25em; color:#2d58b7 }
+h4 { color:#2d58b7 }
+li { padding-bottom: 0.5em }
+ul { padding-left:1.5em; }
+
+.command { font-weight:bold }
+.code_highlight { font-weight:bold; color:#2d58b7 }
+.code_example { border-width:1px; border-style:solid; border-color:#cccccc; 
+                background-color:#eeeeee; padding:10px }
+
+/* Slides */
+IMG.img_slide {
+    display: block;
+    margin-left: auto;
+    margin-right: auto
+}
+
+#page { width:930px;  text-align: left; margin: 0 auto; padding:0;
+        background-color: white; height:100%;
+        border-left: 1px solid #EBF0FA;
+}
+
+#content {
+  clear: left;
+  padding: 1em 2em 0 2em;
+  background-color: #ffffff;
+}
+
+.itemTitle { color:#2d58b7 }
+
+
+/* Tables */
+tr { vertical-align:top }
+
+table.options thead {
+  background-color:#eee; color:#666666;
+  font-weight: bold; cursor: default;
+  text-align:left;
+  border-top: 2px solid #cccccc;
+  border-bottom: 2px solid #cccccc;
+  font-weight: bold; font-family: Verdana
+}
+table.options { border: 1px #cccccc solid }
+table.options { border-collapse: collapse; border-spacing: 0px }
+table.options { margin-left:0px; margin-top:20px; margin-bottom:20px }
+table.options td { border-bottom: 1px #cccccc dotted }
+table.options td { padding:5px; padding-left:8px; padding-right:8px }
+table.options td { text-align:left; font-size:9pt }
+
+/* Collapsing Trees: http://dbtree.megalingo.com/web/demo/simple-collapsible-tree.cfm  */
+#collapsetree, #collapsetree a:link, #collapsetree li a:link, #collapsetree a:visited, #collapsetree li a:visited{color:#000;text-decoration:none}
+#collapsetree,#collapsetree ul{list-style-type:none; width:auto; margin:0; padding:0}
+#collapsetree ul{padding-left:20px;display:none;overflow:auto}
+#collapsetree li ul{margin:0 auto}
+#collapsetree li{display:block;width:100%;line-height:20px;white-space:nowrap}
+#collapsetree li a{display:block;padding-left:20px;color:#000;text-decoration:none;background:url(images/tree/bullet.gif) center left no-repeat;white-space:nowrap}
+#collapsetree li a:hover{text-decoration:underline;background-color:transparent;color:#000}
+#collapsetree li ul.click{display:block}
+#collapsetree li.click a{background:url(images/tree/bullet.gif) center left no-repeat}
+#collapsetree ul li.click a{background:url(images/tree/bullet.gif) center left no-repeat}
+#collapsetree li a.subMenu,#collapsetree ul li a.subMenu{background:url(images/tree/plus.gif) center left no-repeat}
+#collapsetree li a.click{background:url(images/tree/minus.gif) center left no-repeat}
+#collapsetree ul li a.click{background:url(images/tree/minus.gif) center left no-repeat}
+
diff --git a/www/analyzer/dev_cxx.html b/www/analyzer/dev_cxx.html
new file mode 100644
index 0000000..b5ef2b1
--- /dev/null
+++ b/www/analyzer/dev_cxx.html
@@ -0,0 +1,52 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+          "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+  <title>Analyzer Development: C++ Support</title>
+  <link type="text/css" rel="stylesheet" href="menu.css" />
+  <link type="text/css" rel="stylesheet" href="content.css" />
+  <script type="text/javascript" src="scripts/menu.js"></script>  
+</head>
+<body>
+
+<div id="page">
+<!--#include virtual="menu.html.incl"-->
+<div id="content">
+
+<h1>C++ Support</h1>
+
+<p>The Clang frontend
+now <a href="http://clang.llvm.org/cxx_status.html">supports the
+majority of C++</a>.  Support in the frontend for C++ language
+features, however, does not automatically translate into support for
+those features in the static analyzer.  Language features need to be
+specifically modeled in the static analyzer so their semantics can be
+properly analyzed.  Support for analyzing C++ and Objective-C++ files
+is currently extremely limited, and we are only encouraging those who
+are interested in contributing to the development of the analyzer to
+try this functionality out at this time.</p>
+
+<p>Listed here are a set of open tasks that are prerequisites for
+decent analysis of C++.  This list is also not complete; new tasks
+will be added as deemed necessary.</p>
+
+<ul>
+  <li>Control-Flow Graph Enhancements:</li>
+  <ul>
+    <li>Model C++ destructors</li>
+    <li>Model C++ initializers (in constructors)</li>
+  </ul>
+  <li>Path-Sensitive Analysis Engine (GRExprEngine):</li>
+  <ul>
+    <li>Model C++ casts</li>
+    <li>Model C++ constructors</li>
+    <li>Model C++ destructors</li>
+    <li>Model <tt>new</tt> and <tt>delete</tt></li>
+  </ul>
+</ul>
+
+</div>
+</div>
+</body>
+</html>
+
diff --git a/www/analyzer/filing_bugs.html b/www/analyzer/filing_bugs.html
new file mode 100644
index 0000000..746f1cb
--- /dev/null
+++ b/www/analyzer/filing_bugs.html
@@ -0,0 +1,62 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+          "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+  <title>Filing Bugs and Feature Requests</title>
+  <link type="text/css" rel="stylesheet" href="menu.css" />
+  <link type="text/css" rel="stylesheet" href="content.css" />
+  <script type="text/javascript" src="scripts/menu.js"></script>  
+</head>
+<body>
+
+<div id="page">
+<!--#include virtual="menu.html.incl"-->
+<div id="content">
+
+<h1>Filing Bugs and Feature Requests</h1>
+
+<p>We encourage users to file bug reports for any problems that they encounter.
+We also welcome feature requests. When filing a bug report, please do the
+following:</p>
+
+<ul>  
+
+<li>Include the checker build (for prebuilt Mac OS X binaries) or the SVN
+revision number.</li>
+
+<li>Provide a self-contained, reduced test case that exhibits the issue you are
+experiencing.</li>
+
+<li>Test cases don't tell us everything. Please briefly describe the problem you
+are seeing, including what you thought should have been the expected behavior
+and why.</li>
+
+</ul>
+
+<h2>Outside of Apple</h2>
+
+<h3>Bugzilla</h3>
+
+<p>Please <a href="http://llvm.org/bugs/enter_bug.cgi?product=clang">file
+bugs</a> in LLVM's Bugzilla database against the Clang <b>Static Analyzer</b>
+component.</p>
+
+<h3>Bugreporter.apple.com</h3>
+
+<p>If you are using the analyzer to analyze code associated with an Apple NDA
+(e.g., preview versions of SDKs or seed releases of Mac OS X) please file bug
+reports to Apple's <a href="http://bugreporter.apple.com">Bug Reporter</a> web
+site.</p>
+
+<p>You are free to always file bugs through this website, but this option is less
+attractive than filing bug reports through Bugzilla as not everyone who works on
+the analyzer has access to that bug database.</p>
+
+<h2>Apple-internal Users</h2>
+
+<p>Please file bugs in Radar against the <b>llvm - checker</b> component.</p>
+</div>
+</div>
+</body>
+</html>
+
diff --git a/www/analyzer/images/analyzer_html.png b/www/analyzer/images/analyzer_html.png
new file mode 100644
index 0000000..607ea18
--- /dev/null
+++ b/www/analyzer/images/analyzer_html.png
Binary files differ
diff --git a/www/analyzer/images/analyzer_xcode.png b/www/analyzer/images/analyzer_xcode.png
new file mode 100644
index 0000000..84c6980
--- /dev/null
+++ b/www/analyzer/images/analyzer_xcode.png
Binary files differ
diff --git a/www/analyzer/images/example_attribute_nonnull.png b/www/analyzer/images/example_attribute_nonnull.png
new file mode 100644
index 0000000..919af61
--- /dev/null
+++ b/www/analyzer/images/example_attribute_nonnull.png
Binary files differ
diff --git a/www/analyzer/images/example_cf_returns_retained.png b/www/analyzer/images/example_cf_returns_retained.png
new file mode 100644
index 0000000..4bee499
--- /dev/null
+++ b/www/analyzer/images/example_cf_returns_retained.png
Binary files differ
diff --git a/www/analyzer/images/example_cf_returns_retained_gc.png b/www/analyzer/images/example_cf_returns_retained_gc.png
new file mode 100644
index 0000000..023f1a2
--- /dev/null
+++ b/www/analyzer/images/example_cf_returns_retained_gc.png
Binary files differ
diff --git a/www/analyzer/images/example_ns_returns_retained.png b/www/analyzer/images/example_ns_returns_retained.png
new file mode 100644
index 0000000..61316e1
--- /dev/null
+++ b/www/analyzer/images/example_ns_returns_retained.png
Binary files differ
diff --git a/www/analyzer/images/scan_build_cmd.png b/www/analyzer/images/scan_build_cmd.png
new file mode 100644
index 0000000..464fd4e
--- /dev/null
+++ b/www/analyzer/images/scan_build_cmd.png
Binary files differ
diff --git a/www/analyzer/images/tree/bullet.gif b/www/analyzer/images/tree/bullet.gif
new file mode 100644
index 0000000..de15348
--- /dev/null
+++ b/www/analyzer/images/tree/bullet.gif
Binary files differ
diff --git a/www/analyzer/images/tree/minus.gif b/www/analyzer/images/tree/minus.gif
new file mode 100644
index 0000000..225f40d
--- /dev/null
+++ b/www/analyzer/images/tree/minus.gif
Binary files differ
diff --git a/www/analyzer/images/tree/plus.gif b/www/analyzer/images/tree/plus.gif
new file mode 100644
index 0000000..5398c80
--- /dev/null
+++ b/www/analyzer/images/tree/plus.gif
Binary files differ
diff --git a/www/analyzer/index.html b/www/analyzer/index.html
new file mode 100644
index 0000000..082d35f
--- /dev/null
+++ b/www/analyzer/index.html
@@ -0,0 +1,227 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+          "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+  <title>Clang Static Analyzer</title>
+  <link type="text/css" rel="stylesheet" href="content.css" />
+  <link type="text/css" rel="stylesheet" href="menu.css" />
+  <script type="text/javascript" src="scripts/menu.js"></script>  
+</head>
+<body>
+
+<div id="page">
+<!--#include virtual="menu.html.incl"-->
+<div id="content">
+
+
+<table style="margin-top:0px" width="100%" border="0" cellpadding="0px" cellspacing="0">
+<tr><td>
+
+<h1>Clang Static Analyzer</h1>  
+
+<p>The Clang Static Analyzer is source code analysis tool that find bugs in C
+and Objective-C programs.</p>
+
+<p>Currently it can be run either as a <a href="/scan-build.html">standalone
+tool</a> or <a href="/xcode.html">within Xcode</a>. The standalone tool is
+invoked from the command-line, and is intended to be run in tandem with a build
+of a codebase.</p>
+
+<p>The analyzer is 100% open source and is part of the <a
+href="http://clang.llvm.org">Clang</a> project. Like the rest of Clang, the
+analyzer is implemented as a C++ library that can be used by other tools and
+applications.</p>
+
+<h2>Download</h2>
+
+<!-- Generated from: http://www.spiffycorners.com/index.php -->
+
+<style type="text/css">
+.spiffy{display:block}
+.spiffy *{
+  display:block;
+  height:1px;
+  overflow:hidden;
+  font-size:.01em;
+  background:#EBF0FA}
+.spiffy1{
+  margin-left:3px;
+  margin-right:3px;
+  padding-left:1px;
+  padding-right:1px;
+  border-left:1px solid #f6f8fc;
+  border-right:1px solid #f6f8fc;
+  background:#f0f3fb}
+.spiffy2{
+  margin-left:1px;
+  margin-right:1px;
+  padding-right:1px;
+  padding-left:1px;
+  border-left:1px solid #fdfdfe;
+  border-right:1px solid #fdfdfe;
+  background:#eef2fa}
+.spiffy3{
+  margin-left:1px;
+  margin-right:1px;
+  border-left:1px solid #eef2fa;
+  border-right:1px solid #eef2fa;}
+.spiffy4{
+  border-left:1px solid #f6f8fc;
+  border-right:1px solid #f6f8fc}
+.spiffy5{
+  border-left:1px solid #f0f3fb;
+  border-right:1px solid #f0f3fb}
+.spiffyfg{
+  background:#EBF0FA}
+  
+.spiffyfg h2 {
+  margin:0px;  padding:10px;
+}
+</style>
+
+<style type="text/css">
+  #left { float:left; }
+  #left h2 { margin:1px; padding-top:0px; }
+  #right { float:left; margin-left:20px; margin-right:20px; padding:0px ;}
+  #right h2 { padding:0px; margin:0px; }
+  #wrappedcontent { padding:15px;}
+</style>
+
+<div style="padding:0px; font-size: 90%">
+ <b class="spiffy">
+ <b class="spiffy1"><b></b></b>
+ <b class="spiffy2"><b></b></b>
+ <b class="spiffy3"></b>
+ <b class="spiffy4"></b>
+ <b class="spiffy5"></b></b>
+ <div class="spiffyfg">
+  <div style="padding:15px">
+   <h3 style="margin:0px;padding:0px">Mac OS X</h3>
+   <ul>
+    <li>Latest build (Universal binary, 10.5+):<br>
+     <!--#include virtual="latest_checker.html.incl"-->
+    </li>
+    <li>Can be used both from the command line and within Xcode</li>
+    <li><a href="/installation.html">Installation</a> and <a
+    href="/scan-build.html">usage</a></li>
+   </ul>
+  </div>
+ </div>
+ <b class="spiffy">
+ <b class="spiffy5"></b>
+ <b class="spiffy4"></b>
+ <b class="spiffy3"></b>
+ <b class="spiffy2"><b></b></b>
+ <b class="spiffy1"><b></b></b></b>
+</div>
+
+<div style="padding:0; margin-top:10px; font-size: 90%">
+ <b class="spiffy">
+ <b class="spiffy1"><b></b></b>
+ <b class="spiffy2"><b></b></b>
+ <b class="spiffy3"></b>
+ <b class="spiffy4"></b>
+ <b class="spiffy5"></b></b>
+ <div class="spiffyfg">
+  <div style="padding:15px">
+   <h3 style="margin:0px;padding:0px">Other Platforms</h3>    
+   <p>For other platforms, please follow the instructions for <a
+   href="/installation#OtherPlatforms">building the analyzer</a> from
+   source code.<p>
+  </div>
+ </div>
+ <b class="spiffy">
+ <b class="spiffy5"></b>
+ <b class="spiffy4"></b>
+ <b class="spiffy3"></b>
+ <b class="spiffy2"><b></b></b>
+ <b class="spiffy1"><b></b></b></b>
+</div>
+
+
+</td><td style="padding-left:10px">
+<a href="images/analyzer_xcode.png"><img src="images/analyzer_xcode.png" width="450x" border=0></a>
+<center><b>Viewing static analyzer results in Xcode 3.2</b></center>
+<a href="images/analyzer_html.png"><img src="images/analyzer_html.png" width="450px" border=0></a>
+<center><b>Viewing static analyzer results in a web browser</b></center>
+</td></tr></table>
+
+<h2 id="StaticAnalysis">What is Static Analysis?</h2>
+
+<p>The term &quot;static analysis&quot; is conflated, but here we use it to mean
+a collection of algorithms and techniques used to analyze source code in order
+to automatically find bugs. The idea is similar in spirit to compiler warnings
+(which can be useful for finding coding errors) but to take that idea a step
+further and find bugs that are traditionally found using run-time debugging
+techniques such as testing.</p>
+
+<p>Static analysis bug-finding tools have evolved over the last several decades
+from basic syntactic checkers to those that find deep bugs by reasoning about
+the semantics of code. The goal of the Clang Static Analyzer is to provide a
+industrial-quality static analysis framework for analyzing C and Objective-C
+programs that is freely available, extensible, and has a high quality of
+implementation.</p>
+
+<h3 id="Clang">Part of Clang and LLVM</h3>
+
+<p>As its name implies, the Clang Static Analyzer is built on top of <a
+href="http://clang.llvm.org">Clang</a> and <a href="http://llvm.org">LLVM</a>.
+Strictly speaking, the analyzer is part of Clang, as Clang consists of a set of
+reusable C++ libraries for building powerful source-level tools. The static
+analysis engine used by the Clang Static Analyzer is a Clang library, and has
+the capability to be reused in different contexts and by different clients.</p>
+
+<h2>Important Points to Consider</h2>
+
+<p>While we believe that the static analyzer is already very useful for finding
+bugs, we ask you to bear in mind a few points when using it.</p>
+
+<h3>Work-in-Progress</h3>
+
+<p>The analyzer is a continuous work-in-progress.
+There are many planned enhancements to improve both the precision and scope of
+its analysis algorithms as well as the kinds bugs it will find. While there are
+fundamental limitations to what static analysis can do, we have a long way to go
+before hitting that wall.</p>
+
+<h3>Slower than Compilation</h3>
+
+<p>Operationally, using static analysis to
+automatically find deep program bugs is about trading CPU time for the hardening
+of code. Because of the deep analysis performed by state-of-the-art static
+analysis tools, static analysis can be much slower than compilation.</p>
+
+<p>While the Clang Static Analyzer is being designed to be as fast and
+light-weight as possible, please do not expect it to be as fast as compiling a
+program (even with optimizations enabled). Some of the algorithms needed to find
+bugs require in the worst case exponential time.</p>
+
+<p>The Clang Static Analyzer runs in a reasonable amount of time by both
+bounding the amount of checking work it will do as well as using clever
+algorithms to reduce the amount of work it must do to find bugs.</p></li>
+
+<h3>False Positives</h3>
+
+<p>Static analysis is not perfect. It can falsely flag bugs in a program where
+the code behaves correctly. Because some code checks require more analysis
+precision than others, the frequency of false positives can vary widely between
+different checks. Our long-term goal is to have the analyzer have a low false
+positive rate for most code on all checks.</p>
+
+<p>Please help us in this endeavor by <a href="filing_bugs.html">reporting false
+positives</a>. False positives cannot be addressed unless we know about
+them.</p>
+
+<h3>More Checks</h3>
+
+<p>Static analysis is not magic; a static analyzer can only find bugs that it
+has been specifically engineered to find. If there are specific kinds of bugs
+you would like the Clang Static Analyzer to find, please feel free to
+file <a href="filing_bugs.html">feature requests</a> or contribute your own
+patches.</p>
+
+</div>
+</div>
+</body>
+</html>
+
diff --git a/www/analyzer/installation.html b/www/analyzer/installation.html
new file mode 100644
index 0000000..b84f263
--- /dev/null
+++ b/www/analyzer/installation.html
@@ -0,0 +1,114 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+          "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+  <title>Obtaining the Static Analyzer</title>
+  <link type="text/css" rel="stylesheet" href="menu.css" />
+  <link type="text/css" rel="stylesheet" href="content.css" />
+  <script type="text/javascript" src="scripts/menu.js"></script>  
+</head>
+<body>
+
+<div id="page">
+<!--#include virtual="menu.html.incl"-->
+<div id="content">
+
+<h1>Obtaining the Static Analyzer</h1>
+
+<p>This page describes how to download and install the analyzer.  Once
+the analyzer is installed, follow the <a
+href="/scan-build.html">instructions</a> on using <tt>scan-build</tt> to
+get started analyzing your code.</p>
+
+<h2>Packaged Builds (Mac OS X)</h2>
+
+<p>Semi-regular pre-built binaries of the analyzer are available on Mac
+OS X.  These are built to run on Mac OS 10.5 and later.</p>
+
+<p>Builds are released frequently.  Often the differences between build
+numbers being a few bug fixes or minor feature improvements.  When using
+the analyzer, we recommend that you check back here occasionally for new
+builds, especially if the build you are using is more than a couple
+weeks old.</p>
+
+<p>The latest build is: 
+  <!--#include virtual="latest_checker.html.incl"-->
+</p>
+
+<p>Packaged builds for other platforms may eventually be provided, but
+we need volunteers who are willing to help provide such regular builds.
+If you wish to help contribute regular builds of the analyzer on other
+platforms, please email the <a
+href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev">Clang
+Developers' mailing list</a>.</p>
+
+<h3>Using Packaged Builds</h3>
+
+<p>To use a package build, simply unpack it anywhere.  If the build
+archive has the name <b><tt>checker-XXX.tar.bz2</tt></b> then the
+archive will expand to a directory called <b><tt>checker-XXX</tt></b>.
+You do not need to place this directory or the contents of this
+directory in any special place.  Uninstalling the analyzer is as simple
+as deleting this directory.</p>
+
+<p>Most of the files in the <b><tt>checker-XXX</tt></b> directory will
+be supporting files for the analyzer that you can simply ignore.  Most
+users will only care about two files, which are located at the top of
+the <b><tt>checker-XXX</tt></b> directory:</p>
+
+<ul>
+<li><b>scan-build</b>: <tt>scan-build</tt> is the high-level command line utility for running the analyzer</li>
+<li><b>scan-view</b>: <tt>scan-view</tt> a companion comannd line
+utility to <tt>scan-build</tt>, <tt>scan-view</tt> is used to view
+analysis results generated by <tt>scan-build</tt>.  There is an option
+that one can pass to <tt>scan-build</tt> to cause <tt>scan-view</tt> to
+run as soon as it the analysis of a build completes</li>
+</ul>
+
+<h4>Running scan-build</h4>
+
+<p>For specific details on using <tt>scan-build</tt>, please see
+<tt>scan-build</tt>'s <a href="/scan-build">documentation</a>.</p>
+
+<p>To run <tt>scan-build</tt>, either add the
+<b><tt>checker-XXX</tt></b> directory to your path or specify a complete
+path for <tt>scan-build</tt> when running it. It is also possible to use
+a symbolic link to <tt>scan-build</tt>, such one located in a directory
+in your path. When <tt>scan-build</tt> runs it will automatically
+determine where to find its accompanying files.</p>
+
+<h2 id="OtherPlatforms">Other Platforms (Building the Analyzer from Source)</h2>
+
+<p>For other platforms, you must build Clang and LLVM manually.  To do
+so, please follow the instructions for <a
+href="http://clang.llvm.org/get_started.html#build">building Clang from
+source code</a>.<p>
+
+<p>Once the Clang is built, you need to add the following to your path:</p>
+
+<ul>
+
+<li>The location of the <tt>clang</tt> binary.
+
+<p>For example, if you built a <em>Debug</em> build of LLVM/Clang, the
+resultant<tt>clang</tt> binary will be in $(OBJDIR)/Debug
+(where <tt>$(OBJDIR)</tt> is often the same as the root source directory).  You
+can also do <tt>make install</tt> to install the LLVM/Clang libaries and
+binaries to the installation directory of your choice (specified when you run
+<tt>configure</tt>).</p></li>
+
+<li>The locations of the <tt>scan-build</tt> and <tt>scan-view</tt>
+programs.
+
+<p>Currently these are not installed using <tt>make install</tt>, and
+are located in <tt>$(SRCDIR)/tools/clang/tools/scan-build</tt> and
+<tt>$(SRCDIR)/tools/clang/tools/scan-view</tt> respectively (where
+<tt>$(SRCDIR)</tt> is the root LLVM source directory).  These locations
+are subject to change.</p></li>
+
+</ul>
+</div>
+</div>
+</body>
+</html>
+
diff --git a/www/analyzer/latest_checker.html.incl b/www/analyzer/latest_checker.html.incl
new file mode 100644
index 0000000..4131306
--- /dev/null
+++ b/www/analyzer/latest_checker.html.incl
@@ -0,0 +1 @@
+<b><a href="http://checker.minormatter.com/checker-240.tar.bz2">checker-240.tar.bz2</a></b> (built April 11, 2010)
diff --git a/www/analyzer/menu.css b/www/analyzer/menu.css
new file mode 100644
index 0000000..05c1bbf
--- /dev/null
+++ b/www/analyzer/menu.css
@@ -0,0 +1,52 @@
+/* From 'A list apart', 'dropdowns' */
+
+#nav {
+  clear: left;
+  margin:0;
+  padding:0;
+  font-weight: bold;
+  width:100%;
+  background-color: #EBF0FA;
+  border-bottom: 1px solid;
+  font-size: 80%;
+}
+#nav a {
+  text-decoration: none;
+}  
+#nav a:hover {
+  text-decoration: underline;
+}
+.menubar ul {
+  list-style: none inside;
+}
+.menubar li {
+  margin: 0;
+  padding: 5px;  
+  text-align: left;
+  text-indent: 0px;
+  list-style-position: inside;
+  list-style:none;
+  float: left;
+  position: relative;
+  width: 13em;
+  cursor: default;
+  background-color: #EBF0FA;
+}
+.menubar li ul /* second level lists */ {
+  display: none;
+  position: absolute; 
+  left: 0;
+}
+.menubar li>ul {
+  border-left: 1px solid;
+  border-right: 1px solid;
+  border-bottom: 1px solid;
+  padding: 0;
+  margin: 5px 0;
+  left:auto;
+  font-weight: normal;
+}
+.menubar li:hover ul, li.over ul { /* lists nested under hovered list items */
+  display: block;
+}
+
diff --git a/www/analyzer/menu.html.incl b/www/analyzer/menu.html.incl
new file mode 100644
index 0000000..a06eb58
--- /dev/null
+++ b/www/analyzer/menu.html.incl
@@ -0,0 +1,40 @@
+<table width="100%" id="nav" cellspacing=0 cellpadding=0>
+<tr><td>
+<ul style="margin:0; padding:0" class="menubar">
+<li style="padding-left:5em">
+  <a href="/index.html">About</a>
+  <ul class="menubar">
+    <li><a href="/index.html">About the Analyzer</a></li>
+    <li><a href="http://llvm.org/">LLVM Project</a></li>
+    <li><a href="http://clang.llvm.org/">Clang Project</a></li>
+  </ul>
+</li>
+<li>
+  <a href="/filing_bugs.html">Filing Bugs</a>
+</li>
+<li>
+  User Manual
+  <ul>
+    <li><a href="/installation.html">Obtaining the Analyzer</a></li>
+    <li><a href="/scan-build.html">Command line usage</a></li>
+    <li><a href="/xcode.html">Using within Xcode</a></li>
+    <li><a href="/available_checks.html">Available Checks</a></li>
+    <li><a href="/annotations.html">Source-level Annotations</a></li>
+  </ul>
+</li>
+<li>
+  Development
+  <ul>
+    <li><a href="/dev_cxx.html">Analysis support for C++</a></li>
+  </ul>
+</li>
+<li>
+  Mailing Lists
+  <ul>
+    <li><a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev">cfe-dev</a></li>
+    <li><a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits">cfe-commits</a></li>
+  </ul>
+</li>
+</ul>
+</td></tr>
+</table>
diff --git a/www/analyzer/scan-build.html b/www/analyzer/scan-build.html
new file mode 100644
index 0000000..1db15fe
--- /dev/null
+++ b/www/analyzer/scan-build.html
@@ -0,0 +1,346 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+          "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+  <title>scan-build: running the analyzer from the command line</title>
+  <link type="text/css" rel="stylesheet" href="content.css" />
+  <link type="text/css" rel="stylesheet" href="menu.css" />
+  <script type="text/javascript" src="scripts/menu.js"></script>
+  <script type="text/javascript" src="scripts/dbtree.js"></script>
+</head>
+<body>
+
+<div id="page">
+<!--#include virtual="menu.html.incl"-->
+<div id="content">
+
+<h1>scan-build: running the analyzer from the command line</h1>
+
+<table style="margin-top:0px" width="100%" border="0" cellpadding="0px" cellspacing="0">
+<tr><td>
+
+<h3>What is it?</h3>
+<p><b>scan-build</b> is a command line utility that enables a user to run the
+static analyzer over their codebase as part of performing a regular build (from
+the command line).</p>
+
+<h3>How does it work?</h3>
+<p>During a project build, as source files are compiled they are also analyzed
+in tandem by the static analyzer.</p>
+
+<p>Upon completion of the build, results are then presented to the user within a
+web browser.</p>
+
+<h3>Will it work with any build system?</h3>
+<p><b>scan-build</b> has little or no knowledge about how you build your code.
+It works by overriding the <tt>CC</tt> and <tt>CXX</tt> environment variables to
+(hopefully) change your build to use a &quot;fake&quot; compiler instead of the
+one that would normally build your project. By default, this fake compiler
+executes <tt>gcc</tt> to compile your code (assuming that <tt>gcc</tt> is your
+compiler) and then executes the static analyzer to analyze your code.</p>
+
+<p>This &quot;poor man's interposition&quot; works amazingly well in many cases
+and falls down in others. Please consult the information on this page on making
+the best use of <b>scan-build</b>, which includes getting it to work when the
+aforementioned hack fails to work.</p>
+
+</td>
+<td style="padding-left:10px">
+<center>
+  <img src="images/scan_build_cmd.png" width="450px" border=0><br>
+  <a href="images/analyzer_html.png"><img src="images/analyzer_html.png" width="450px" border=0></a>
+<br><b>Viewing static analyzer results in a web browser</b></center>
+</td></tr></table>
+
+<h2>Contents</h2>
+
+<ul id="collapsetree" class="dbtree onclick multiple">
+<li><a href="#scanbuild">Getting Started</a>
+ <ul>
+  <li><a href="#scanbuild_basicusage">Basic Usage</a></li>
+  <li><a href="#scanbuild_otheroptions">Other Options</a></li>
+  <li><a href="#scanbuild_output">Output of scan-build</a></li>
+ </ul>
+</li>
+<li><a href="#recommendedguidelines">Recommended Usage Guidelines</a>
+ <ul>
+  <li><a href="#recommended_debug">Always Analyze a Project in its &quot;Debug&quot; Configuration</a></li>
+  <li><a href="#recommended_verbose">Use Verbose Output when Debugging scan-build</a></li>
+  <li><a href="#recommended_autoconf">Run './configure' through scan-build</a></li>
+ </ul>
+</li>
+<li><a href="#iphone">Analyzing iPhone Projects</a></li>
+</ul>
+
+<h2 id="scanbuild">Getting Started</h2>
+
+<p>The <tt>scan-build</tt> command can be used to analyze an entire project by
+essentially interposing on a project's build process. This means that to run the
+analyzer using <tt>scan-build</tt>, you will use <tt>scan-build</tt> to analyze
+the source files compiled by <tt>gcc</tt> during a project build. This means
+that any files that are not compiled will also not be analyzed.</p>
+
+<h3 id="scanbuild_basicusage">Basic Usage</h3>
+
+<p>Basic usage of <tt>scan-build</tt> is designed to be simple: just place the
+word &quot;scan-build&quot; in front of your build command:</p>
+
+<pre class="code_example">
+$ <span class="code_highlight">scan-build</span> make
+$ <span class="code_highlight">scan-build</span> xcodebuild
+</pre>
+
+<p>In the first case <tt>scan-build</tt> analyzes the code of a project built
+with <tt>make</tt> and in the second case <tt>scan-build</tt> analyzes a project
+built using <tt>xcodebuild</tt>.<p>
+  
+<p>Here is the general format for invoking <tt>scan-build</tt>:</p>
+
+<pre class="code_example">
+$ <span class="code_highlight">scan-build</span> <i>[scan-build options]</i> <span class="code_highlight">&lt;command&gt;</span> <i>[command options]</i>
+</pre>
+
+<p>Operationally, <tt>scan-build</tt> literally runs &lt;command&gt; with all of the
+subsequent options passed to it. For example, one can pass <nobr><tt>-j4</tt></nobr> to
+<tt>make</tt> get a parallel build over 4 cores:</p>
+
+<pre class="code_example">
+$ scan-build make <span class="code_highlight">-j4</span>
+</pre>
+
+<p>In almost all cases, <tt>scan-build</tt> makes no effort to interpret the
+options after the build command; it simply passes them through. In general,
+<tt>scan-build</tt> should support parallel builds, but <b>not distributed
+builds</b>.</p>
+
+<p>It is also possible to use <tt>scan-build</tt> to analyze specific
+files:</p>
+
+<pre class="code_example">
+ $ scan-build gcc -c <span class="code_highlight">t1.c t2.c</span>
+</pre>
+
+<p>This example causes the files <tt>t1.c</tt> and <tt>t2.c</tt> to be analyzed.
+</p>
+
+<h3 id="scanbuild_otheroptions">Other Options</h3>
+
+<p>As mentioned above, extra options can be passed to <tt>scan-build</tt>. These
+options prefix the build command. For example:</p>
+
+<pre class="code_example">
+ $ scan-build <span class="code_highlight">-k -V</span> make
+ $ scan-build <span class="code_highlight">-k -V</span> xcodebuild
+</pre>
+
+<p>Here is a subset of useful options:</p>
+
+<table class="options">
+<thead><tr><td>Option</td><td>Description</td></tr></thead>
+
+<tr><td><b>-o</b></td><td>Target directory for HTML report files. Subdirectories
+will be created as needed to represent separate "runs" of the analyzer. If this
+option is not specified, a directory is created in <tt>/tmp</tt> to store the
+reports.</td><tr>
+
+<tr><td><b>-h</b><br><i><nobr>(or no arguments)</nobr></i></td><td>Display all
+<tt>scan-build</tt> options.</td></tr>
+
+<tr><td><b>-k</b><br><nobr><b>--keep-going</b></nobr></td><td>Add a "keep on
+going" option to the specified build command. <p>This option currently supports
+<tt>make</tt> and <tt>xcodebuild</tt>.</p> <p>This is a convenience option; one
+can specify this behavior directly using build options.</p></td></tr>
+
+<tr><td><b>-v<b></td><td>Verbose output from scan-build and the analyzer. <b>A
+second and third "-v" increases verbosity</b>, and is useful for filing bug
+reports against the analyzer.</td></tr>
+
+<tr><td><b>-V</b></td><td>View analysis results in a web browser when the build
+command completes.</td></tr> </table>
+
+<p>A complete list of options can be obtained by running <tt>scan-build</tt>
+with no arguments.</p>
+
+<h3 id="scanbuild_output">Output of scan-build</h3>
+
+<p>
+The output of scan-build is a set of HTML files, each one which represents a
+separate bug report. A single <tt>index.html</tt> file is generated for
+surveying all of the bugs. You can then just open <tt>index.html</tt> in a web
+browser to view the bug reports.
+</p>
+
+<p>
+Where the HTML files are generated is specified with a <b>-o</b> option to
+<tt>scan-build</tt>. If <b>-o</b> isn't specified, a directory in <tt>/tmp</tt>
+is created to store the files (<tt>scan-build</tt> will print a message telling
+you where they are). If you want to view the reports immediately after the build
+completes, pass <b>-V</b> to <tt>scan-build</tt>.
+</p>
+
+
+<h2 id="recommendedguidelines">Recommended Usage Guidelines</h2>
+
+<p>This section describes a few recommendations with running the analyzer.</p>
+
+<h3 id="recommended_debug">ALWAYS analyze a project in its &quot;debug&quot; configuration</h3>
+
+<p>Most projects can be built in a &quot;debug&quot; mode that enables assertions.
+Assertions are picked up by the static analyzer to prune infeasible paths, which
+in some cases can greatly reduce the number of false positives (bogus error
+reports) emitted by the tool.</p>
+
+<h3 id="recommend_verbose">Use verbose output when debugging scan-build</h3>
+
+<p><tt>scan-build</tt> takes a <b>-v</b> option to emit verbose output about
+what it's doing; two <b>-v</b> options emit more information. Redirecting the
+output of <tt>scan-build</tt> to a text file (make sure to redirect standard
+error) is useful for filing bug reports against <tt>scan-build</tt> or the
+analyzer, as we can see the exact options (and files) passed to the analyzer.
+For more comprehensible logs, don't perform a parallel build.</p>
+
+<h3 id="recommended_autoconf">Run './configure' through scan-build</h3>
+
+<p>If an analyzed project uses an autoconf generated <tt>configure</tt> script,
+you will probably need to run <tt>configure</tt> script through
+<tt>scan-build</tt> in order to analyze the project.</p>
+
+<p><b>Example</b></p>
+
+<pre class="code_example">
+$ scan-build ./configure
+$ scan-build make
+</pre>
+
+<p>The reason <tt>configure</tt> also needs to be run through
+<tt>scan-build</tt> is because <tt>scan-build</tt> scans your source files by
+<i>interposing</i> on the compiler. This interposition is currently done by
+<tt>scan-build</tt> temporarily setting the environment variable <tt>CC</tt> to
+<tt>ccc-analyzer</tt>. The program <tt>ccc-analyzer</tt> acts like a fake
+compiler, forwarding its command line arguments over to <tt>gcc</tt> to perform
+regular compilation and <tt>clang</tt> to perform static analysis.</p>
+
+<p>Running <tt>configure</tt> typically generates makefiles that have hardwired
+paths to the compiler, and by running <tt>configure</tt> through
+<tt>scan-build</tt> that path is set to <tt>ccc-analyzer</tt>.</p.>
+
+<!-- 
+<h2 id="Debugging">Debugging the Analyzer</h2>
+
+<p>This section provides information on debugging the analyzer, and troubleshooting
+it when you have problems analyzing a particular project.</p>
+
+<h3>How it Works</h3>
+
+<p>To analyze a project, <tt>scan-build</tt> simply sets the environment variable
+<tt>CC</tt> to the full path to <tt>ccc-analyzer</tt>. It also sets a few other
+environment variables to communicate to <tt>ccc-analyzer</tt> where to dump HTML
+report files.</p>
+
+<p>Some Makefiles (or equivalent project files) hardcode the compiler; for such
+projects simply overriding <tt>CC</tt> won't cause <tt>ccc-analyzer</tt> to be
+called. This will cause the compiled code <b>to not be analyzed.</b></p> If you
+find that your code isn't being analyzed, check to see if <tt>CC</tt> is
+hardcoded. If this is the case, you can hardcode it instead to the <b>full
+path</b> to <tt>ccc-analyzer</tt>.</p>
+
+<p>When applicable, you can also run <tt>./configure</tt> for a project through
+<tt>scan-build</tt> so that configure sets up the location of <tt>CC</tt> based
+on the environment passed in from <tt>scan-build</tt>:
+
+<pre>
+  $ scan-build <b>./configure</b>
+</pre>
+
+<p><tt>scan-build</tt> has special knowledge about <tt>configure</tt>, so it in
+most cases will not actually analyze the configure tests run by
+<tt>configure</tt>.</p>
+
+<p>Under the hood, <tt>ccc-analyzer</tt> directly invokes <tt>gcc</tt> to
+compile the actual code in addition to running the analyzer (which occurs by it
+calling <tt>clang</tt>). <tt>ccc-analyzer</tt> tries to correctly forward all
+the arguments over to <tt>gcc</tt>, but this may not work perfectly (please
+report bugs of this kind).
+ -->
+
+<h2 id="iphone">Analyzing iPhone Projects</h2>
+
+<p>Conceptually Xcode projects for iPhone applications are nearly the same as
+their cousins for desktop applications. <b>scan-build</b> can analyze these
+projects as well, but users often encounter problems with just building their
+iPhone projects from the command line because there are a few extra preparative
+steps they need to take (e.g., setup code signing).</p>
+
+<h3>Recommendation: use &quot;Build and Analyze&quot;</h3>
+
+<p>The absolute easiest way to analyze iPhone projects is to use the <a
+href="http://developer.apple.com/mac/library/featuredarticles/StaticAnalysis/index.html"><i>Build
+and Analyze</i> feature in Xcode 3.2</a> (which is based on the Clang Static
+Analyzer). There a user can analyze their project with the click of a button
+without most of the setup described later.</p>
+
+<p><a href="/xcode.html">Instructions are available</a> on this
+website on how to use open source builds of the analyzer as a replacement for
+the one bundled with Xcode.</p>
+
+<h3>Using scan-build directly</h3>
+
+<p>If you wish to use <b>scan-build</b> with your iPhone project, keep the
+following things in mind:</p>
+
+<ul>
+ <li>Analyze your project in the <tt>Debug</tt> configuration, either by setting
+this as your configuration with Xcode or by passing <tt>-configuration
+Debug</tt> to <tt>xcodebuild</tt>.</li>
+ <li>Analyze your project using the <tt>Simulator</tt> as your base SDK. It is
+possible to analyze your code when targetting the device, but this is much
+easier to do when using Xcode's <i>Build and Analyze</i> feature.</li>
+ <li>Check that your code signing SDK is set to the simulator SDK as well, and make sure this option is set to <tt>Don't Code Sign</tt>.</li>
+</ul>
+
+<p>Note that you can most of this without actually modifying your project. For
+example, if your application targets iPhoneOS 2.2, you could run
+<b>scan-build</b> in the following manner from the command line:</p>
+
+<pre class="code_example">
+$ scan-build xcodebuild -configuration Debug -sdk iphonesimulator2.2
+</pre>
+
+Alternatively, if your application targets iPhoneOS 3.0:
+
+<pre class="code_example">
+$ scan-build xcodebuild -configuration Debug -sdk iphonesimulator3.0
+</pre>
+
+<h3>Gotcha: using the right compiler</h3>
+
+<p>Recall that <b>scan-build</b> analyzes your project by using <tt>gcc</tt> to
+compile the project and <tt>clang</tt> to analyze your project. When analyzing
+iPhone projects, <b>scan-build</b> may pick the wrong compiler than the one
+Xcode would use to build your project. This is because multiple versions of
+<tt>gcc</tt> may be installed on your system, especially if you are developing
+for the iPhone.</p>
+
+<p>Where this particularly might be a problem is if you are using Mac OS 10.5
+(Leopard) to develop for iPhone OS 3.0. The default desktop compiler on Leopard
+is gcc-4.0, while the compiler for iPhone OS 3.0 is gcc-4.2. When compiling your
+application to run on the simulator, it is important that <b>scan-build</b>
+finds the correct version of <tt>gcc</tt>. Otherwise, you may see strange build
+errors that only happen when you run <tt>scan-build</tt>.
+
+<p><b>scan-build</b> provides the <tt>--use-cc</tt> and <tt>--use-c++</tt>
+options to hardwire which compiler scan-build should use for building your code.
+Note that although you are chiefly interested in analyzing your project, keep in
+mind that running the analyzer is intimately tied to the build, and not being
+able to compile your code means it won't get fully analyzed (if at all).</p>
+
+<p>If you aren't certain which compiler Xcode uses to build your project, try
+just running <tt>xcodebuild</tt> (without <b>scan-build</b>). You should see the
+full path to the compiler that Xcode is using, and use that as an argument to
+<tt>--use-cc</tt>.</p>
+
+</div>
+</div>
+</body>
+</html>
+
diff --git a/www/analyzer/scripts/dbtree.js b/www/analyzer/scripts/dbtree.js
new file mode 100644
index 0000000..5face5d
--- /dev/null
+++ b/www/analyzer/scripts/dbtree.js
@@ -0,0 +1 @@
+eval(function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('7 5,r,Q,u;7 17=[];5=H;1i();9(!1Z.1j.20){1Z.1j.20=k(a){C[C.D]=a}}7 19=\'35+/\';k 36(a){7 b,R=\'\',i=0;I(;i<a.D;i+=4){b=(19.1k(a.1l(i))&1a)<<18|(19.1k(a.1l(i+1))&1a)<<12|(19.1k(a.1l(i+2))&1a)<<6|19.1k(a.1l(i+3))&1a;R+=37.38((b&39)>>16,(b&3a)>>8,b&1a)}9(a.21(i-2)==22)1m=R.23(0,R.D-2);s 9(a.21(i-1)==22)1m=R.23(0,R.D-1);s 1m=R;z 3b(1m)}7 A={24:k(){7 a=l.E(\'X\');I(7 i=0;i<a.D;i++){9(a[i].h.F(/\\1n\\b/)==-1)3c;7 b=a[i];9(b.h.F(/\\1E\\b/)!=-1){7 c=b.E(\'a\');I(7 j=0;j<c.D;j++){m.B(c[j],\'25\',1F,o);m.B(c[j],\'26\',1G,o);m.B(c[j],\'1o\',1b,o);c[j].Y=\'1H:1I(0)\'}}7 d=b.E(\'X\');I(7 j=0;j<d.D;j++){7 e=d[j].p;e.27=J;9(b.h.F(/\\3d\\b/)!=-1){m.B(e,\'w\',A.w,o);9(b.h.F(/\\3e\\b/)==-1){e.E(\'a\')[0].Y=\'1H:1I(0)\'}}s{7 t=b.h.3f(/1J(.*)1J/);t=t?t[1]:H;m.B(e,\'3g\',A.28(e,t),o);m.B(e,\'3h\',A.29(e),o)}e.E(\'a\')[0].h+=\' 2a\'}9(b.h.F(/\\3i\\b/)!=-1)A.2b(b.v)}},2b:k(a){7 b=l.G(a+\'3j\');9(b){A.1p(b);b=b.p;1c(!!b&&(b.v!=a)){9((!b.h)||(b.h==\'\')){b.h=\'w\'}s{b.h+=\' w\'}9(b.1d.K.L()==\'a\')b.1d.h+=\' w\';b=b.p}}},29:k(a){z k(){A.1p(a)}},28:k(a,b){z k(){A.2c(a,b)}},1p:k(a){7 b=a;3k(b.2d);I(7 i=0;i<b.S.D;i++){7 c=b.S[i];9(c.K.L()==\'X\'){b.E(\'a\')[0].h+=\' w\';b.h+=\' w\';c.h+=\' w\'}}},2c:k(a,b){7 c=a;c.2d=3l(k(){A.1q(c)},b)},1q:k(a){I(7 i=0;i<a.S.D;i++){7 b=a.S[i];9(b.K.L()==\'X\'){a.E(\'a\')[0].h=a.E(\'a\')[0].h.1K(/w/g,\'\');b.h=b.h.1K(/w/g,\'\');a.h=a.h.1K(/w/g,\'\')}}},w:k(e){9(M.T){M.T.1L=J}9(e&&e.1r){e.1r()}7 a=(M.T)?M.T.2e:(e)?e.1M:H;9(!a||!(a=A.1N(a,\'2f\')))z;9(a.E(\'a\')[0].h.F(/\\2g\\b/)==-1){7 b=1e(a);9(2h(b)){9(l.G(b).h.F(/\\3m\\b/)==-1){I(n=0;n<a.p.S.D;n++){N=a.p.S[n];9(N.K.L()==\'2f\'){9(N.h.F(/\\2g\\b/)!=-1)A.1q(a.p.S[n])}}}}A.1p(a)}s{A.1q(a)}9(2h(1e(a))){z J}s{z o}},1N:k(a,b){9(a.K.L()!=b&&a.K.L()!=\'U\'){z A.1N(a.p,b)}s 9(a.K.L()==\'U\'){z H}s{z a}}};k 1i(){3n{u=M.2i?O 2i():O 3o(\'3p.3q\')}3r(e){2j(\'2k 2l: 3s 3t 3u 3v 3w-3x!\')}}k 1O(a,x){a.1f.3y=x+\'2m\'}k 1P(a,y){a.1f.3z=y+\'2m\'}k 1e(a){1c(a.h.F(/\\1n\\b/)==-1){a=a.p}9((a.h.F(/\\1n\\b/)!=-1)&&(a.h.F(/\\1E\\b/)!=-1)){I(i=0;i<17.D;i++){9(a.v==17[i].q)z i}}z a.v}k 1G(a){a=O m(a);r=a.P.p.p.v;7 b=r.1s(\'Z\');r=b[1];5=17[1e(a.P)];7 c=l.G(5.q+\'10\').3A(J);7 d=l.G(5.q+\'10\');d.p.2n(d);c.v=5.q+\'10\';l.U.2o(c);1O(c,a.x);1P(c,a.y);c.1f.1Q=\'2p\';a.1t();m.B(l,\'1u\',1R,o);z o}k 1R(c){c=O m(c);7 e;7 a=c.P;7 b=a;1c((b!=H)&&(b.K.L()!=\'U\')){9(b.v==5.q+\'10\')1g;b=b.p}9((b!=H)&&(b.v==5.q+\'10\')){3B(a.p.h){1S\'3C\':a.Y=5.V+\'11=1T&N=\'+5.13;1g;1S\'1T\':a.Y=5.V+\'11=1T&N=\'+r;1g;1S\'2q\':a.Y=5.V+\'11=2q&N=\'+r;1g;3D:e=5.2r+\'?q=\'+5.q;e+=\'&13=\'+5.13;9(a.p.h==\'3E\'){e+=\'&11=2s&N=\'+r+\'&2t=\'+5.13}s{e+=\'&11=\'+a.p.h+\'&N=\'+r}7 d=O 2u();7 f=d.2v();e+=\'&2w=\'+f;e+=\'&1v=\'+5.1v;e+=\'&1w=\'+5.1w;e+=\'&1x=\'+5.1x;e+=\'&1y=\'+5.1y;e+=\'&1z=\'+5.1z;e+=\'&1A=\'+5.1A;e+=\'&v=\'+5.v;e+=\'&1B=\'+5.1B;e+=\'&1C=\'+5.1C;e+=\'&V=\'+5.V;u.2x=1U;u.1V(\'2y\',e,J);u.14(\'2z\',\'2A-2B\');u.14(\'2C-2D\',\'2E-2F\');u.14(\'2G-2H-2I\',l.2J);u.2K(H)}}7 g=l.G(5.q+\'10\');9(g){g.1f.1Q=\'3F\'};m.1h(l,\'1u\',1R,o)}k 1F(a){a=O m(a);r=a.P.p.p.v;7 b=r.1s(\'Z\');r=b[1];5=17[1e(a.P)];9(!l.G(5.q+\'15\')){7 c=(!l.G(5.q+\'15\'))?l.3G(\'3H\'):l.G(5.q+\'15\');c.v=5.q+\'15\';c.2L=a.P.1d.3I;l.U.2o(c)}m.B(l,\'2M\',1W,o);m.B(l,\'1u\',1X,o);m.B(l,\'1o\',1b,o);a.1t();z o}k 1b(a){9(!a&&M.T)a=M.T;9(a!=H){9(3J(a.1Y)==\'k\')a.1Y();s a.2N=o}z o}k 1W(a){a=O m(a);7 b=l.G(5.q+\'15\');1O(b,a.x);1P(b,a.y);b.1f.1Q=\'2p\';a.1t();z o}k 1X(a){a=O m(a);7 b=a.P.p;9(b.K.L()==\'a\'){r=5.q+\'Z\'+r;9(r!=b.p.v){7 c=J;7 d=b.p;1c(!!d&&(d.v!=5.q)){9(d.v==r){c=o;1g}s{d=d.p}}9(c==J){7 e=r.1s(\'Z\');r=e[1];Q=b.p.v;7 f=Q.1s(\'Z\');Q=f[1];2O(a)}}}7 g=l.G(5.q+\'15\');9(g){g.p.2n(g)};m.1h(l,\'2M\',1W,o);m.1h(l,\'1u\',1X,o);m.1h(l,\'1o\',1b,o)}k 2O(a){7 d=O 2u();7 b=d.2v();7 c;c=5.2r+\'?q=\'+5.q+\'&11=2s&13=\'+5.13+\'&N=\'+r+\'&2t=\'+Q+\'&2w=\'+b;c+=\'&1v=\'+5.1v;c+=\'&1w=\'+5.1w;c+=\'&1x=\'+5.1x;c+=\'&1y=\'+5.1y;c+=\'&1z=\'+5.1z;c+=\'&1A=\'+5.1A;c+=\'&v=\'+5.v;c+=\'&1B=\'+5.1B;c+=\'&1C=\'+5.1C;c+=\'&V=\'+5.V;u.2x=1U;u.1V(\'2y\',c,J);u.14(\'2z\',\'2A-2B\');u.14(\'2C-2D\',\'2E-2F\');u.14(\'2G-2H-2I\',l.2J);u.2K(H)}k 2P(){7 a=(!!Q)?Q:r;a=5.q+\'Z\'+a;a=l.G(a);9(a){a=a.E(\'X\')[0];1c(!!a&&(a.h.F(/\\1n\\b/)==-1)&&(a.h.F(/\\1E\\b/)==-1)){9((!a.h)||(a.h==\'\')){a.h=\'w\'}s{a.h+=\' w\'}9(a.1d.K.L()==\'a\')a.1d.h+=\' w\';a=a.p}}}k 3K(a,b){9(a!=\'3L\'){3M(a+".3N=\'"+b.2Q[b.2R].2S+"\'")}s{M.1V(b.2Q[b.2R].2S)}}k 2T(a){7 b=l.G(a);7 c=b.E(\'X\');I(7 j=0;j<c.D;j++){7 d=c[j].p;d.27=J;m.B(d,\'w\',A.w,o);d.E(\'a\')[0].h+=\' 2a\'}7 e=b.E(\'a\');I(7 j=0;j<e.D;j++){m.B(e[j],\'25\',1F,o);m.B(e[j],\'26\',1G,o);m.B(e[j],\'1o\',1b,o);e[j].Y=\'1H:1I(0)\'}}k 1U(){9(u.3O==4){9(u.3P==3Q){l.G(5.q+\'3R\').2L=u.3S;2T(5.q);2P();1i()}s{2j(\'2k 2l: 3T, 3U 3V 1J 3W a 3X 3Y 3Z 40:\\n\'+u.41);1i()}}}k m(a){C.W=a?a:M.T;C.P=a.1M?a.1M:a.2e;C.x=a.2U?(a.2U):(a.42+2V.2W(l.U.2X,l.2Y.2X));C.y=a.2Z?(a.2Z):(a.43+2V.2W(l.U.30,l.2Y.30))}m.1j.44=k(){z\'m [ x = \'+C.x+\', y = \'+C.y+\' ]\'};m.1j.1t=k(){9(C.W.1r){C.W.1r();C.W.1Y()}s 9(C.W.1L){C.W.1L=J;C.W.2N=o}};m.B=k(a,b,c,d){9(l.31){a.31(b,c,d)}s 9(l.32){a.32(\'1D\'+b,c,d)}s{a[\'1D\'+b]=c}};m.1h=k(a,b,c,d){9(l.33){a.33(b,c,d)}s 9(l.34){a.34(\'1D\'+b,c,d)}s{a[\'1D\'+b]=H}};m.B(M,\'45\',A.24,o);',62,254,'|||||instance||var||if||||||||className|||function|document|Evt||false|parentNode|instanceName|nid|else||client|id|click|||return|dbTree|addEvent|this|length|getElementsByTagName|search|getElementById|null|for|true|nodeName|toLowerCase|window|node|new|source|nto|decOut|childNodes|event|body|editpage|evt|ul|href|_|_options|action||rootnode|setRequestHeader|_tip||dbtreeObj||b64s|0xff|PreventDefault|while|firstChild|getObj|style|break|removeEvent|createClient|prototype|indexOf|charAt|undecOut|bdbtree|selectstart|mOver|mOut|stopPropagation|split|consume|mouseup|type|query|datasource|username|password|table|parent|contentfield|on|bedit|dragPress|contextMenu|javascript|void|to|replace|cancelBubble|target|getTarget|setX|setY|display|contextAction|case|add|callback|open|dragMove|dragRelease|preventDefault|Array|push|charCodeAt|61|substring|init|mousedown|contextmenu|hasSubMenu|getMoutFor|getMoverFor|subMenu|mExp|mTimeout|timeout|srcElement|li|bclick|isNaN|XMLHttpRequest|alert|DBTree|Error|px|removeChild|appendChild|block|edit|tagpath|move|nodeto|Date|getTime|time|onreadystatechange|get|Pragma|no|cache|Cache|Control|must|revalidate|If|Modified|Since|lastModified|send|innerHTML|mousemove|returnValue|dragBoxDropped|expandtree|options|selectedIndex|value|reinit|pageX|Math|max|scrollLeft|documentElement|pageY|scrollTop|addEventListener|attachEvent|removeEventListener|detachEvent|ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789|decode|String|fromCharCode|0xff0000|0xff00|unescape|continue|bonclick|blinkparent|match|mouseout|mouseover|bexpand|_active|clearTimeout|setTimeout|bmultiple|try|ActiveXObject|Microsoft|XMLHTTP|catch|Your|browser|is|not|Ajax|enabled|left|top|cloneNode|switch|addroot|default|moveroot|none|createElement|div|nodeValue|typeof|jumpTo|blank|eval|location|readyState|status|200|_edit|responseText|Sorry|there|seems|be|problem|retrieving|the|response|statusText|clientX|clientY|toString|load'.split('|'),0,{}))
diff --git a/www/analyzer/scripts/menu.js b/www/analyzer/scripts/menu.js
new file mode 100644
index 0000000..6b393c0
--- /dev/null
+++ b/www/analyzer/scripts/menu.js
@@ -0,0 +1,17 @@
+startList = function() {
+  if (document.all&&document.getElementById) {
+    navRoot = document.getElementById("nav");
+    for (i=0; i<navRoot.childNodes.length; i++) {
+      node = navRoot.childNodes[i];
+      if (node.nodeName=="LI") {
+        node.onmouseover=function() {
+          this.className+=" over";
+        }
+        node.onmouseout=function() {
+          this.className=this.className.replace(" over", "");
+        }
+      }
+    }
+  }
+}
+window.onload=startList;
diff --git a/www/analyzer/xcode.html b/www/analyzer/xcode.html
new file mode 100644
index 0000000..474156e
--- /dev/null
+++ b/www/analyzer/xcode.html
@@ -0,0 +1,136 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+          "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+  <title>Build and Analyze: running the analyzer within Xcode</title>
+  <link type="text/css" rel="stylesheet" href="content.css" />
+  <link type="text/css" rel="stylesheet" href="menu.css" />
+  <script type="text/javascript" src="scripts/menu.js"></script>
+  <script type="text/javascript" src="scripts/dbtree.js"></script>  
+</head>
+<body>
+
+<div id="page">
+<!--#include virtual="menu.html.incl"-->
+<div id="content">
+
+<h1>Build and Analyze: running the analyzer within Xcode</h1>
+
+<table style="margin-top:0px" width="100%" border="0" cellpadding="0px" cellspacing="0">
+<tr><td>
+
+<h3>What is it?</h3>
+<p><i>Build and Analyze</i> is an Xcode feature (introduced in Xcode 3.2) that
+allows users to run the Clang Static Analyzer <a
+href="http://developer.apple.com/mac/library/featuredarticles/StaticAnalysis/index.html">directly
+within Xcode</a>.</p>
+
+<p>It integrates directly with the Xcode build system and
+presents analysis results directly within Xcode's editor.</p>
+
+<h3>Can I use the open source analyzer builds with Xcode?</h3>
+
+<p><b>Yes</b>. Instructions are included below.</p>
+
+</td>
+<td style="padding-left:10px">
+<center>
+  <a href="images/analyzer_xcode.png"><img src="images/analyzer_xcode.png" width="620px" border=0></a>
+<br><b>Viewing static analyzer results in Xcode</b></center>
+</td></tr></table>
+
+<h3>Key features:</h3>
+<ul>
+  <li><b>Integrated workflow:</b> Results are integrated within Xcode. There is
+  no experience of using a separate tool, and activating the analyzer requires a
+  single keystroke or mouse click.</li>
+  <li><b>Transparency:</b> Works effortlessly with Xcode projects (including iPhone projects).
+  <li><b>Cons:</b> Doesn't work well with non-Xcode projects. For those,
+  consider using <a href="/scan-build.html"><b>scan-build</b></a>.
+</ul>
+
+
+<h2>Getting Started</h2>
+
+<p>Xcode 3.2 is available as a free download from Apple, with <a
+href="http://developer.apple.com/mac/library/featuredarticles/StaticAnalysis/index.html">instructions available</a>
+for using <i>Build and Analyze</i>.</p>
+
+<h2>Using open source analyzer builds with <i>Build and Analyze</i></h2>
+
+<p>By default, Xcode uses the version of <tt>clang</tt> that came bundled with
+it to provide the results for <i>Build and Analyze</i>. It is possible to change
+Xcode's behavior to use an alternate version of <tt>clang</tt> for this purpose
+while continuing to use the <tt>clang</tt> that came with Xcode for compiling
+projects.</p>
+
+<h3>Why try open source builds?</h3>
+
+<p>The advantage of using open source analyzer builds (provided on this website)
+is that they are often newer than the analyzer provided with Xcode, and thus can
+contain bug fixes, new checks, or simply better analysis.</p>
+
+<p>On the other hand, new checks can be experimental, with results of variable
+quality. Users are encouraged to <a href="filing_bugs.html">file bug reports</a>
+(for any version of the analyzer) where they encounter false positives or other
+issues.</p>
+
+<h3>set-xcode-analyzer</h3>
+
+<p>Starting with analyzer build checker-234, analyzer builds contain a command
+line utility called <tt>set-xcode-analyzer</tt> that allows users to change what
+copy of <tt>clang</tt> that Xcode uses for <i>Build and Analyze</i>:</p>
+
+<pre class="code_example">
+$ <b>set-xcode-analyzer -h</b>
+Usage: set-xcode-analyzer [options]
+
+Options:
+  -h, --help            show this help message and exit
+  --use-checker-build=PATH
+                        Use the Clang located at the provided absolute path,
+                        e.g. /Users/foo/checker-1
+  --use-xcode-clang     Use the Clang bundled with Xcode
+</pre>
+
+<p>Operationally, <b>set-xcode-analyzer</b> edits Xcode's configuration files
+(in <tt>/Developer</tt>) to point it to use the version of <tt>clang</tt> you
+specify for static analysis.  Within this model it provides you two basic modes:</p>
+
+<ul>
+  <li><b>--use-xcode-clang</b>: Switch Xcode (back) to using the <tt>clang</tt> that came bundled with it for static analysis.</li>
+  <li><b>--use-checker-build</b>: Switch Xcode to using the <tt>clang</tt> provided by the specified analyzer build.</li>
+</ul>
+
+<h4>Examples</h4>
+
+<p><b>Example 1</b>: Telling Xcode to use checker-235 for <i>Build and Analyze</i>:</p>
+
+<pre class="code_example">
+$ pwd
+/tmp
+$ tar xjf checker-235.tar.bz2
+$ checker-235/set-xcode-analyzer --use-checker-build=/tmp/checker-235
+</pre>
+
+<p>Note that you typically won't install an analyzer build in <tt>/tmp</tt>, but
+the point of this example is that <tt>set-xcode-analyzer</tt> just wants a full
+path to an untarred analyzer build.</p>
+
+<p><b>Example 2</b>: Telling Xcode to use a very specific version of <tt>clang</tt>:</p>
+
+<pre class="code_example">
+$ set-xcode-analyzer --use-checker-build=~/mycrazyclangbuild/bin/clang
+</pre>
+
+<p><b>Example 3</b>: Resetting Xcode to its default behavior:</p>
+
+<pre class="code_example">
+$ set-xcode-analyzer --use-xcode-clang
+</pre>
+
+</div>
+</div>
+</body>
+</html>
+
diff --git a/www/carbon-compile.png b/www/carbon-compile.png
new file mode 100644
index 0000000..e8516c7
--- /dev/null
+++ b/www/carbon-compile.png
Binary files differ
diff --git a/www/clang_video-05-25-2007.html b/www/clang_video-05-25-2007.html
new file mode 100644
index 0000000..a85cadc
--- /dev/null
+++ b/www/clang_video-05-25-2007.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!-- Material used from: HTML 4.01 specs: http://www.w3.org/TR/html401/ -->
+<html>
+<head>
+	<META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
+	<title>2007 LLVM Developer's Meeting</title>
+	<link type="text/css" rel="stylesheet" href="menu.css" />
+	<link type="text/css" rel="stylesheet" href="content.css" />
+</head>
+<body>
+	<!--#include virtual="menu.html.incl"-->
+	<div id="content">
+		<h1>2007 LLVM Developer's Meeting</h1>
+		Discussion about Clang at the <a href="http://llvm.org/devmtg/2007-05/">2007 LLVM Developer's Meeting</a>.
+		<h2>About:</h2>
+		<p>In this video, Steve Naroff introduces the Clang project and talks about some of the goals and motivations for starting the project.
+		<br><br>
+		<p><b>Details:</b> New LLVM C Front-end - This talk describes a new from-scratch C frontend (which is aiming to support Objective C and C++ someday) for LLVM, built as a native part of the LLVM system and in the LLVM design style.
+		<h2>The Presentation:</h2>
+		<p>You can download a copy of the presentation in mov format.  However, due to the picture quality, it is recommended that you also download the lecture slides for viewing while you watch the video.
+		<ul>
+			<li><a href="http://llvm.org/devmtg/2007-05/09-Naroff-CFE.mov">Video (mov file)</a>
+			<li><a href="http://llvm.org/devmtg/2007-05/09-Naroff-CFE.pdf">Lecture slides (PDF)</a>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/www/clang_video-07-25-2007.html b/www/clang_video-07-25-2007.html
new file mode 100644
index 0000000..179e499
--- /dev/null
+++ b/www/clang_video-07-25-2007.html
@@ -0,0 +1,30 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!-- Material used from: HTML 4.01 specs: http://www.w3.org/TR/html401/ -->
+<html>
+<head>
+	<META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
+	<title>LLVM 2.0 and Beyond!</title>
+	<link type="text/css" rel="stylesheet" href="menu.css" />
+	<link type="text/css" rel="stylesheet" href="content.css" />
+</head>
+<body>
+	<!--#include virtual="menu.html.incl"-->
+	<div id="content">
+		<h1>LLVM 2.0 and Beyond!</h1>
+		A Google Techtalk by <a href="http://www.nondot.org/sabre/">Chris Lattner</a>
+		<h2>About:</h2>
+		<p>In this video, Chris Lattner talks about some of the features of Clang, especially in regards to performance.
+		<br><br>
+		<p><b>Details:</b> The LLVM 2.0 release brings a number of new features and capabilities to the LLVM toolset. This talk briefly describes those features, then moves on to talk about what is next: llvm 2.1, llvm-gcc 4.2, and puts a special emphasis on the 'clang' C front-end. This describes how the 'clang' preprocessor can be used to improve the scalability of distcc by up to 4.4x.
+		<h2>The Presentation:</h2>
+		<p>You can view the presentation through google video. In addition, the slides from the presentation are also available, if you wish to retain a copy.
+		<ul>
+			<li><a href="http://video.google.com/videoplay?docid=1921156852099786640">Google Tech Talk Video (19:00-)</a> (Note: the Clang lecture starts at 19 minutes into the video.)
+			<li><a href="http://llvm.org/pubs/2007-07-25-LLVM-2.0-and-Beyond.pdf">LLVM 2.0 and Beyond! slides (PDF)</a>
+		</ul>
+		<h2>Publishing Information:</h2>
+		"LLVM 2.0 and Beyond!", Chris Lattner,<br>
+		<i>Google Tech Talk</i>, Mountain View, CA, July 2007.
+	</div>
+</body>
+</html>
diff --git a/www/comparison.html b/www/comparison.html
new file mode 100644
index 0000000..0a6a7c8
--- /dev/null
+++ b/www/comparison.html
@@ -0,0 +1,189 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" 
+          "http://www.w3.org/TR/html4/strict.dtd">
+<!-- Material used from: HTML 4.01 specs: http://www.w3.org/TR/html401/ -->
+<html>
+<head>
+  <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
+  <title>Comparing clang to other open source compilers</title>
+  <link type="text/css" rel="stylesheet" href="menu.css" />
+  <link type="text/css" rel="stylesheet" href="content.css" />
+</head>
+<body>
+  <!--#include virtual="menu.html.incl"-->
+  <div id="content">
+    <h1>Clang vs Other Open Source Compilers</h1>
+    
+    <p>Building an entirely new compiler front-end is a big task, and it isn't
+       always clear to people why we decided to do this.  Here we compare clang
+       and its goals to other open source compiler front-ends that are
+       available.  We restrict the discussion to very specific objective points
+       to avoid controversy where possible.  Also, software is infinitely
+       mutable, so we don't talk about little details that can be fixed with 
+       a reasonable amount of effort: we'll talk about issues that are 
+       difficult to fix for architectural or political reasons.</p>
+       
+    <p>The goal of this list is to describe how differences in goals lead to
+       different strengths and weaknesses, not to make some compiler look bad.
+       This will hopefully help you to evaluate whether using clang is a good
+       idea for your personal goals.  Because we don't know specifically what
+       <em>you</em> want to do, we describe the features of these compilers in
+       terms of <em>our</em> goals: if you are only interested in static
+       analysis, you may not care that something lacks codegen support, for
+       example.</p>
+       
+    <p>Please email cfe-dev if you think we should add another compiler to this
+       list or if you think some characterization is unfair here.</p>
+    
+    <ul>
+    <li><a href="#gcc">Clang vs GCC</a> (GNU Compiler Collection)</li>
+    <li><a href="#elsa">Clang vs Elsa</a> (Elkhound-based C++ Parser)</li>
+    <li><a href="#pcc">Clang vs PCC</a> (Portable C Compiler)</li>
+    </ul>
+    
+    
+    <!--=====================================================================-->
+    <h2><a name="gcc">Clang vs GCC (GNU Compiler Collection)</a></h2>
+    <!--=====================================================================-->
+    
+    <p>Pro's of GCC vs clang:</p>
+    
+    <ul>
+    <li>GCC supports languages that clang does not aim to, such as Java, Ada,
+        FORTRAN, etc.</li>
+    <li>GCC front-ends are very mature and already support C++.
+        <a href="cxx_status.html">clang's support for C++</a> is further behind.</li>
+    <li>GCC supports more targets than LLVM.</li>
+    <li>GCC is popular and widely adopted.</li>
+    <li>GCC does not require a C++ compiler to build it.</li>
+    </ul>
+    
+    <p>Pro's of clang vs GCC:</p>
+    
+    <ul>
+    <li>The Clang ASTs and design are intended to be <a 
+        href="features.html#simplecode">easily understandable</a> by
+        anyone who is familiar with the languages involved and who has a basic
+        understanding of how a compiler works.  GCC has a very old codebase
+        which presents a steep learning curve to new developers.</li>
+    <li>Clang is designed as an API from its inception, allowing it to be reused
+        by source analysis tools, refactoring, IDEs (etc) as well as for code
+        generation.  GCC is built as a monolithic static compiler, which makes
+        it extremely difficult to use as an API and integrate into other tools.
+        Further, its historic design and <a 
+        href="http://gcc.gnu.org/ml/gcc/2007-11/msg00460.html">current</a>
+        <a href="http://gcc.gnu.org/ml/gcc/2004-12/msg00888.html">policy</a> 
+        makes it difficult to decouple the front-end from the rest of the
+        compiler. </li>
+    <li>Various GCC design decisions make it very difficult to reuse: its build
+        system is difficult to modify, you can't link multiple targets into one
+        binary, you can't link multiple front-ends into one binary, it uses a
+        custom garbage collector, uses global variables extensively, is not
+        reentrant or multi-threadable, etc.  Clang has none of these problems.
+        </li>
+    <li>For every token, clang tracks information about where it was written and
+        where it was ultimately expanded into if it was involved in a macro.
+        GCC does not track information about macro instantiations when parsing
+        source code.  This makes it very difficult for source rewriting tools
+        (e.g. for refactoring) to work in the presence of (even simple) 
+        macros.</li>
+    <li>Clang does not implicitly simplify code as it parses it like GCC does.
+        Doing so causes many problems for source analysis tools: as one simple
+        example, if you write "x-x" in your source code, the GCC AST will
+        contain "0", with no mention of 'x'.  This is extremely bad for a
+        refactoring tool that wants to rename 'x'.</li>
+    <li>Clang can serialize its AST out to disk and read it back into another 
+        program, which is useful for whole program analysis.  GCC does not have
+        this.  GCC's PCH mechanism (which is just a dump of the compiler 
+        memory image) is related, but is architecturally only 
+        able to read the dump back into the exact same executable as the one 
+        that produced it (it is not a structured format).</li>
+    <li>Clang is <a href="features.html#performance">much faster and uses far
+        less memory</a> than GCC.</li>
+    <li>Clang aims to provide extremely clear and concise diagnostics (error and
+        warning messages), and includes support for <a
+        href="diagnostics.html">expressive diagnostics</a>.  GCC's warnings are 
+        sometimes acceptable, but are often confusing and it does not support
+        expressive diagnostics.  Clang also preserves typedefs in diagnostics
+        consistently, showing macro expansions and many other features.</li>
+    <li>GCC is licensed under the GPL license.  clang uses a BSD license, which
+        allows it to be used by projects that do not themselves want to be
+        GPL.</li>
+    <li>Clang inherits a number of features from its use of LLVM as a backend,
+        including support for a bytecode representation for intermediate code,
+        pluggable optimizers, link-time optimization support, Just-In-Time
+        compilation, ability to link in multiple code generators, etc.</li>
+    </ul>
+
+    <!--=====================================================================-->
+    <h2><a name="elsa">Clang vs Elsa (Elkhound-based C++ Parser)</a></h2>
+    <!--=====================================================================-->
+    
+    <p>Pro's of Elsa vs clang:</p>
+    
+    <ul>
+    <li>Elsa's parser and AST is designed to be easily extensible by adding
+        grammar rules.  Clang has a very simple and easily hackable parser,
+        but requires you to write C++ code to do it.</li>
+    </ul>
+    
+    <p>Pro's of clang vs Elsa:</p>
+    
+    <ul>
+    <li>The Elsa community is extremely small and major development work seems
+        to have ceased in 2005. Work continued to be used by other small 
+        projects (e.g. Oink), but Oink is apparently dead now too.  Clang has a
+        vibrant community including developers that
+        are paid to work on it full time.  In practice this means that you can
+        file bugs against Clang and they will often be fixed for you.  If you
+        use Elsa, you are (mostly) on your own for bug fixes and feature
+        enhancements.</li>
+    <li>Elsa is not built as a stack of reusable libraries like clang is.  It is
+        very difficult to use part of Elsa without the whole front-end.  For
+        example, you cannot use Elsa to parse C/ObjC code without building an
+        AST.  You can do this in Clang and it is much faster than building an
+        AST.</li>
+    <li>Elsa does not have an integrated preprocessor, which makes it extremely
+        difficult to accurately map from a source location in the AST back to
+        its original position before preprocessing.  Like GCC, it does not keep
+        track of macro expansions.</li>
+    <li>Elsa is even slower and uses more memory than GCC, which itself requires 
+        far more space and time than clang.</li>
+    <li>Elsa only does partial semantic analysis.  It is intended to work on
+        code that is already validated by GCC, so it does not do many semantic
+        checks required by the languages it implements.</li>
+    <li>Elsa does not support Objective-C.</li>
+    <li>Elsa does not support native code generation.</li>
+    </ul>
+    
+    <p>Note that there is a fork of Elsa known as "Pork". It addresses some of
+       these shortcomings by loosely integrating a preprocessor. This allows it
+       to map from a source location in the AST to the original position before
+       preprocessing, providing it better support for static analysis and
+       refactoring.  Note that Pork is in stasis now too.</p>
+
+    
+    <!--=====================================================================-->
+    <h2><a name="pcc">Clang vs PCC (Portable C Compiler)</a></h2>
+    <!--=====================================================================-->
+    
+    <p>Pro's of PCC vs clang:</p>
+    
+    <ul>
+    <li>The PCC source base is very small and builds quickly with just a C
+        compiler.</li>
+    </ul>
+    
+    <p>Pro's of clang vs PCC:</p>
+    
+    <ul>
+    <li>PCC dates from the 1970's and has been dormant for most of that time.
+        The clang + llvm communities are very active.</li>
+    <li>PCC doesn't support Objective-C or C++ and doesn't aim to support
+        C++.</li>
+    <li>PCC's code generation is very limited compared to LLVM.  It produces very
+        inefficient code and does not support many important targets.</li>
+    <li>Like Elsa, PCC's does not have an integrated preprocessor, making it
+        extremely difficult to use it for source analysis tools.</li>
+  </div>
+</body>
+</html>
diff --git a/www/content.css b/www/content.css
new file mode 100644
index 0000000..dca6a32
--- /dev/null
+++ b/www/content.css
@@ -0,0 +1,27 @@
+html { margin: 0px; } body { margin: 8px; }
+
+html, body {
+  padding:0px;
+  font-size:small; font-family:"Lucida Grande", "Lucida Sans Unicode", Arial, Verdana, Helvetica, sans-serif; background-color: #fff; color: #222;
+  line-height:1.5;
+}
+
+h1, h2, h3, tt { color: #000 }
+
+h1 { padding-top:0px; margin-top:0px;}
+h2 { color:#333333; padding-top:0.5em; }
+h3 { padding-top: 0.5em; margin-bottom: -0.25em; color:#2d58b7}
+li { padding-bottom: 0.5em; }
+ul { padding-left:1.5em; }
+
+/* Slides */
+IMG.img_slide {
+    display: block;
+    margin-left: auto;
+    margin-right: auto
+}
+
+.itemTitle { color:#2d58b7 }
+
+/* Tables */
+tr { vertical-align:top }
diff --git a/www/cxx_compatibility.html b/www/cxx_compatibility.html
new file mode 100644
index 0000000..bd48c6c
--- /dev/null
+++ b/www/cxx_compatibility.html
@@ -0,0 +1,292 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+          "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+  <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
+  <title>Clang - C++ Compatibility</title>
+  <link type="text/css" rel="stylesheet" href="menu.css" />
+  <link type="text/css" rel="stylesheet" href="content.css" />
+  <style type="text/css">
+</style>
+</head>
+<body>
+
+<!--#include virtual="menu.html.incl"-->
+
+<div id="content">
+
+<!-- ======================================================================= -->
+<h1>Clang's C++ Compatibility</h1>
+<!-- ======================================================================= -->
+
+<ul>
+<li><a href="#intro">Introduction</a></li>
+<li><a href="#vla">Variable-length arrays</a></li>
+<li><a href="#init_static_const">Initialization of non-integral static const data members within a class definition</a></li>
+<li><a href="#dep_lookup">Unqualified lookup in templates</a></li>
+<li><a href="#dep_lookup_bases">Unqualified lookup into dependent bases of class templates</a></li>
+<li><a href="#bad_templates">Templates with no valid instantiations</a></li>
+<li><a href="#default_init_const">Default initialization of const variable of a class type requires user-defined default constructor</a></li>
+</ul>
+
+<!-- ======================================================================= -->
+<h2 id="intro">Introduction</h2>
+<!-- ======================================================================= -->
+
+<p>Clang strives to strictly conform to the C++ standard.  That means
+it will reject invalid C++ code that another compiler may accept.
+This page helps you decide whether a Clang error message means a
+C++-conformance bug in your code and how you can fix it.</p>
+
+<!-- ======================================================================= -->
+<h2 id="vla">Variable-length arrays</h2>
+<!-- ======================================================================= -->
+
+<p>GCC allows an array's size to be determined at run time. This,
+however, is not standard C++. Furthermore, it is a potential security
+hole as an incorrect array size may overflow the stack. If Clang tells
+you <tt>"variable length arrays are not permitted in C++"</tt>, here
+are some ways in which you can fix it:</p>
+
+<ol>
+<li>replace it with a fixed-size array if you can determine a
+    reasonable upper bound at compile time; sometimes this is as
+    simple as changing <tt>int size = ...;</tt> to <tt>const int size
+    = ...;</tt> (if the definition of <tt>size</tt> is a compile-time
+    integral constant);</li>
+<li>use an <tt>std::string</tt> instead of a <tt>char []</tt>;</li>
+<li>use <tt>std::vector</tt> or some other suitable container type;
+    or</li>
+<li>allocate the array on the heap instead using <tt>new Type[]</tt> -
+    just remember to <tt>delete[]</tt> it.</li>
+</ol>
+
+<!-- ======================================================================= -->
+<h2 id="init_static_const">Initialization of non-integral static const data members within a class definition</h2>
+<!-- ======================================================================= -->
+
+The following code is ill-formed in C++'03:
+
+<pre>
+class SomeClass {
+ public:
+  static const double SomeConstant = 0.5;
+};
+
+const double SomeClass::SomeConstant;
+</pre>
+
+Clang errors with something similar to:
+
+<pre>
+.../your_file.h:42:42: error: 'SomeConstant' can only be initialized if it is a static const integral data member
+  static const double SomeConstant = 0.5;
+                      ^              ~~~
+</pre>
+
+Only <i>integral</i> constant expressions are allowed as initializers
+within the class definition. See C++'03 [class.static.data] p4 for the
+details of this restriction.  The fix here is straightforward: move
+the initializer to the definition of the static data member, which
+must exist outside of the class definition:
+
+<pre>
+class SomeClass {
+ public:
+  static const double SomeConstant;
+};
+
+const double SomeClass::SomeConstant<b> = 0.5</b>;
+</pre>
+
+Note that the forthcoming C++0x standard will allow this.
+
+<!-- ======================================================================= -->
+<h2 id="dep_lookup">Unqualified lookup in templates</h2>
+<!-- ======================================================================= -->
+
+Some versions of GCC accept the following invalid code:
+
+<pre>
+template &lt;typename T&gt; struct Foo {
+  void Work(T x) {
+    func(x);
+  }
+};
+...
+void func(int x);
+...
+template struct Foo&lt;int&gt;; // or anything else that instantiates Foo&lt;int&gt;::Work
+</pre>
+
+The standard says that unqualified names like <tt>func</tt> are looked up
+when the template is defined, not when it's instantiated.  Since
+<tt>void func(int)</tt> was not declared yet when <tt>Foo</tt> was
+defined, it's not considered.  The fix is usually to
+declare <tt>func</tt> before <tt>Foo</tt>.
+
+<p>This is complicated by <i>argument-dependent lookup</i> (ADL),
+which is done when unqualified names are called as functions,
+like <tt>func(x)</tt> above.  The standard says that ADL is performed
+in both places if any of the arguments are type-dependent, like
+<tt>x</tt> is in this example.  However, ADL does nothing for builtin
+types like <tt>int</tt>, so the example is still invalid.  See
+[basic.lookup.argdep] for more information.
+
+<!-- ======================================================================= -->
+<h2 id="dep_lookup_bases">Unqualified lookup into dependent bases of class templates</h2>
+<!-- ======================================================================= -->
+
+Some versions of GCC accept the following invalid code:
+
+<pre>
+template &lt;typename T&gt; struct Base {
+  void DoThis(T x) {}
+  static void DoThat(T x) {}
+};
+
+template &lt;typename T&gt; struct Derived : public Base&lt;T&gt; {
+  void Work(T x) {
+    DoThis(x);  // Invalid!
+    DoThat(x);  // Invalid!
+  }
+};
+</pre>
+
+Clang correctly rejects it with the following errors
+(when <tt>Derived</tt> is eventually instantiated):
+
+<pre>
+my_file.cpp:8:5: error: use of undeclared identifier 'DoThis'
+    DoThis(x);
+    ^
+    this-&gt;
+my_file.cpp:2:8: note: must qualify identifier to find this declaration in dependent base class
+  void DoThis(T x) {}
+       ^
+my_file.cpp:9:5: error: use of undeclared identifier 'DoThat'
+    DoThat(x);
+    ^
+    this-&gt;
+my_file.cpp:3:15: note: must qualify identifier to find this declaration in dependent base class
+  static void DoThat(T x) {}
+</pre>
+
+Like we said <a href="#dep_lookup">above</a>, unqualified names like
+<tt>DoThis</tt> and <tt>DoThat</tt> are looked up when the template
+<tt>Derived</tt> is defined, not when it's instantiated.  When we look
+up a name used in a class, we usually look into the base classes.
+However, we can't look into the base class <tt>Base&lt;T&gt;</tt>
+because its type depends on the template argument <tt>T</tt>, so the
+standard says we should just ignore it.  See [temp.dep]p3 for details.
+
+<p>The fix, as Clang tells you, is to tell the compiler that we want a
+class member by prefixing the calls with <tt>this-&gt;</tt>:
+
+<pre>
+  void Work(T x) {
+    <b>this-&gt;</b>DoThis(x);
+    <b>this-&gt;</b>DoThat(x);
+  }
+</pre>
+
+Alternatively, you can tell the compiler exactly where to look:
+
+<pre>
+  void Work(T x) {
+    <b>Base&lt;T&gt;</b>::DoThis(x);
+    <b>Base&lt;T&gt;</b>::DoThat(x);
+  }
+</pre>
+
+This works whether the methods are static or not, but be careful:
+if <tt>DoThis</tt> is virtual, calling it this way will bypass virtual
+dispatch!
+
+<!-- ======================================================================= -->
+<h2 id="bad_templates">Templates with no valid instantiations</h2>
+<!-- ======================================================================= -->
+
+The following code contains a typo: the programmer
+meant <tt>init()</tt> but wrote <tt>innit()</tt> instead.
+
+<pre>
+  template &lt;class T&gt; class Processor {
+    ...
+    void init();
+    ...
+  };
+  ...
+  template &lt;class T&gt; void process() {
+    Processor&lt;T&gt; processor;
+    processor.innit();       // <-- should be 'init()'
+    ...
+  }
+</pre>
+
+Unfortunately, we can't flag this mistake as soon as we see it: inside
+a template, we're not allowed to make assumptions about "dependent
+types" like <tt>Processor&lt;T&gt;</tt>.  Suppose that later on in
+this file the programmer adds an explicit specialization
+of <tt>Processor</tt>, like so:
+
+<pre>
+  template &lt;&gt; class Processor&lt;char*&gt; {
+    void innit();
+  };
+</pre>
+
+Now the program will work &mdash; as long as the programmer only ever
+instantiates <tt>process()</tt> with <tt>T = char*</tt>!  This is why
+it's hard, and sometimes impossible, to diagnose mistakes in a
+template definition before it's instantiated.
+
+<p>The standard says that a template with no valid instantiations is
+ill-formed.  Clang tries to do as much checking as possible at
+definition-time instead of instantiation-time: not only does this
+produce clearer diagnostics, but it also substantially improves
+compile times when using pre-compiled headers.  The downside to this
+philosophy is that Clang sometimes fails to process files because they
+contain broken templates that are no longer used.  The solution is
+simple: since the code is unused, just remove it.
+
+<!-- ======================================================================= -->
+<h2 id="default_init_const">Default initialization of const variable of a class type requires user-defined default constructor</h2>
+<!-- ======================================================================= -->
+
+If a <tt>class</tt> or <tt>struct</tt> has no user-defined default
+constructor, C++ doesn't allow you to default construct a <tt>const</tt>
+instance of it like this ([dcl.init], p9):
+
+<pre>
+class Foo {
+ public:
+  // The compiler-supplied default constructor works fine, so we
+  // don't bother with defining one.
+  ...
+};
+
+void Bar() {
+  const Foo foo;  // Error!
+  ...
+}
+</pre>
+
+To fix this, you can define a default constructor for the class:
+
+<pre>
+class Foo {
+ public:
+  Foo() {}
+  ...
+};
+
+void Bar() {
+  const Foo foo;  // Now the compiler is happy.
+  ...
+}
+</pre>
+
+</div>
+</body>
+</html>
diff --git a/www/cxx_status.html b/www/cxx_status.html
new file mode 100644
index 0000000..2fb0271
--- /dev/null
+++ b/www/cxx_status.html
@@ -0,0 +1,2421 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+          "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+  <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+  <title>Clang - C++ Support</title>
+  <link type="text/css" rel="stylesheet" href="menu.css">
+  <link type="text/css" rel="stylesheet" href="content.css">
+  <style type="text/css">
+    .na { background-color: #C0C0C0; text-align: center; }
+    .broken { background-color: #C11B17 }
+    .basic  { background-color: #F88017 }
+    .medium { background-color: #FDD017 }
+    .advanced { background-color: #347C17 }
+    .complete { background-color: #00FF00 }
+  </style>
+</head>
+<body>
+
+<!--#include virtual="menu.html.incl"-->
+
+<div id="content">
+
+<!--*************************************************************************-->
+<h1>C++ Support in Clang</h1>
+<!--*************************************************************************-->
+<p>Last updated: $Date: 2010-04-13 00:01:38 +0800 (二, 13  4月 2010) $</p>
+
+<h1>Clang C++ Status</h1>
+
+  <ul>
+    <li><a href="#projects">Projects Building with Clang</a></li>
+    <li><a href="#specification">Implementation Status by Section</a></li>
+    <li><a href="#cxx0x">C++0x Status</a></li>
+  </ul>
+  
+<p>Clang currently implements nearly all of the ISO C++ 1998 standard (including the defects addressed in the ISO C++ 2003 standard). However, the implementation of Clang C++ is still quite immature, with many remaining bugs that are likely to cause compiler crashes, erroneous errors and warnings, and miscompiled code. The <a href="http://llvm.org/bugs/">LLVM bug tracker</a> contains a Clang C++ component that tracks known Clang C++ bugs.</p>
+
+ <h2 id="projects">Projects Building with Clang</h2>
+
+  <p>Clang is now capable of compiling some language C++ projects, or
+large pieces of such projects. The following table describes various
+projects that we have attempted to compile with Clang along with the results of that attempt.</p>
+
+  <p> At this point in time, each new C++ project typically uncovers
+new bugs. We keep track of these in the <a
+ href="http://llvm.org/bugs/">LLVM bug tracker</a> via tracking bugs,
+which are used to relate all of the bugs known to affect that
+particular project. Introducing a new project in this list typically requires a liason familiar with LLVM or Clang development, who is able to provide detailed bug reports and track progress for the particular project.</p>
+
+<table width="689" border="1" cellspacing="0">
+  <tr>
+    <th>Project</th>
+    <th>Status</th>
+    <th>Last Tested</th>
+    <th>Tracking Bug</th>
+  </tr>
+  <tr>
+    <td><a href="http://clang.llvm.org">Clang</a> and <a href="http://llvm.org">LLVM</a></td>
+    <td>Successful self-hosting achieved</td>
+    <td>Continually</td>
+    <td></td>
+  </tr>
+  <tr>
+    <td><a href="http://www.cmake.org">CMake</a></td>
+    <td>Compiles, passes regression tests (debug build)</td>
+    <td>February 9, 2010</td>
+    <td></td>
+  </tr>
+  <tr>
+    <td><a href="http://qt.nokia.com">Qt</a></td>
+    <td>Partially compiles; miscompilation of uic prevents complete compilation, qmake works, some small examples also.</td>
+    <td>February 9, 2010</td>
+    <td><a href="http://llvm.org/bugs/show_bug.cgi?id=5881">PR5881</a></td>
+  </tr>
+  <tr>
+    <td><a href="http://www.boost.org">Boost</a></td>
+    <td>Some libraries (e.g., Boost.MPL) successfully build and pass regression tests, the majority still fail.</td>
+    <td>February 5, 2010</td>
+    <td><a href="http://llvm.org/bugs/show_bug.cgi?id=6023">PR6023</a></td>
+  </tr>
+</table>
+  
+  <h2 id="specification">Implementation Status by Section</h2>
+
+
+<!-- Within this table: The colors we're using to color-code our level
+of support for a given section:
+
+       White (no background): not considered/tested.
+       #C11B17: Broken.
+       #F88017: Some useful examples work
+       #FDD017: Many examples work
+       #347C17: Nearly everything works
+       #00FF00 + check mark: Implementation complete!
+  -->
+
+<p>The following table is used to help track our implementation
+  progress toward implementing the complete C++03 standard. We use a
+  simple, somewhat arbitrary color-coding scheme to describe the
+  relative completeness of features by section:</p>
+
+<table width="689" border="1" cellspacing="0">
+  <tr>
+    <th>Not started/not evaluated</th>
+    <th>Not Applicable</th>
+    <th>Broken</th>
+    <th>Some examples work</th>
+    <th>Many examples work</th>
+    <th>Nearly everything works</th>
+    <th>Complete</th>
+    <th>Complete (with tests for each paragraph)</th>
+  </tr>
+  <tr>
+    <td></td>
+    <td class="na">N/A</td>
+    <td class="broken"></td>
+    <td class="basic"></td>
+    <td class="medium"></td>
+    <td class="advanced"></td>
+    <td class="complete"></td>
+    <td class="complete" align="center">&#x2713;</td>
+  </tr>
+</table>
+
+<p>A feature is "complete" when the appropriate Clang component (Parse, AST,
+Sema, CodeGen) implements the behavior described in all of the
+paragraphs in the relevant C++ standard. Note that many C++ features are
+actually described in several different sections within the standard. The major components are:</p>
+
+<dl>
+  <dt>Parse</dt>
+  <dd>Clang is able to parse the grammar of this feature (or the grammar described by this section), but does not necessarily do anything with the parsed result. Use Clang's <code>-fsyntax-only</code> option to parse C++ programs.</dd>
+
+  <dt>AST</dt>
+  <dd>Clang builds an abstract syntax tree (AST) for the feature, but does not necessarily perform any type-checking. Use Clang's <code>-ast-print</code> option to print the resulting ASTs.</dd>
+
+  <dt>Sema</dt>
+  <dd>Clang parses and type-checks this feature and provides a well-formed AST  annotated with types. Use Clang's <code>-fsyntax-only</code> to type-check code.</dd>
+
+  <dt>CodeGen</dt>
+  <dd>Clang parses, type-checks, and generates code for this feature, allowing one to compile and execute programs.</dd>
+</dl>
+
+<p>Updates to this table are welcome! Since Clang already supports
+much of C, and therefore much C++, many of the currently-white cells
+could be filled in. If you wish to do so, please compare Clang's
+implementation against the C++ standard and provide a patch that
+updates the table accordingly. Tests for the various features are also
+welcome!</p>
+
+<table width="689" border="1" cellspacing="0">
+  <tr>
+    <th>Section</th>
+    <th>Parse</th>
+    <th>AST</th>
+    <th>Sema</th>
+    <th>CodeGen</th>
+    <th>Notes</th>
+  </tr>
+<tr>
+  <td>2 [lex]</td>
+  <td class="complete" align="center"></td>
+  <td class="na">N/A</td>
+  <td class="na">N/A</td>
+  <td class="na">N/A</td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;2.1 [lex.phases]</td>
+  <td class="advanced" align="center"></td>
+  <td class="na">N/A</td>
+  <td class="na">N/A</td>
+  <td class="na">N/A</td>
+  <td>Extended characters aren't handled.</td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;2.2 [lex.charset]</td>
+  <td class="basic"></td>
+  <td class="na">N/A</td>
+  <td class="na">N/A</td>
+  <td class="na">N/A</td>
+  <td>No support for extended characters.</td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;2.3 [lex.trigraph]</td>
+  <td class="complete" align="center"></td>
+  <td class="na">N/A</td>
+  <td class="na">N/A</td>
+  <td class="na">N/A</td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;2.4 [lex.pptoken]</td>
+  <td class="complete" align="center"></td>
+  <td class="na">N/A</td>
+  <td class="na">N/A</td>
+  <td class="na">N/A</td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;2.5 [lex.digraph]</td>
+  <td class="complete" align="center"></td>
+  <td class="na">N/A</td>
+  <td class="na">N/A</td>
+  <td class="na">N/A</td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;2.6 [lex.token]</td>
+  <td class="complete" align="center"></td>
+  <td class="na">N/A</td>
+  <td class="na">N/A</td>
+  <td class="na">N/A</td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;2.7 [lex.comment]</td>
+  <td class="advanced" align="center"></td>
+  <td></td>
+  <td class="na">N/A</td>
+  <td class="na">N/A</td>
+  <td>NDR "form feed or vtab in comment" is not diagnosed.</td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;2.8 [lex.header]</td>
+  <td class="complete" align="center"></td>
+  <td class="na">N/A</td>
+  <td class="na">N/A</td>
+  <td class="na">N/A</td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;2.9 [lex.ppnumber]</td>
+  <td class="complete" align="center"></td>
+  <td class="na">N/A</td>
+  <td class="na">N/A</td>
+  <td class="na">N/A</td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;2.10 [lex.name]</td>
+  <td class="advanced" align="center"></td>
+  <td class="na">N/A</td>
+  <td class="na">N/A</td>
+  <td class="na">N/A</td>
+  <td>No support for extended characters</td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;2.11 [lex.key]</td>
+  <td class="complete" align="center"></td>
+  <td class="na">N/A</td>
+  <td class="na">N/A</td>
+  <td class="na">N/A</td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;2.12 [lex.operators]</td>
+  <td class="complete" align="center"></td>
+  <td class="na">N/A</td>
+  <td class="na">N/A</td>
+  <td class="na">N/A</td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;2.13 [lex.literal]</td>
+  <td class="complete" align="center"></td>
+  <td class="na">N/A</td>
+  <td class="na">N/A</td>
+  <td class="na">N/A</td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;2.13.1 [lex.icon]</td>
+  <td class="complete" align="center"></td>
+  <td class="na">N/A</td>
+  <td class="na">N/A</td>
+  <td class="na">N/A</td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;2.13.2 [lex.ccon]</td>
+  <td class="advanced" align="center"></td>
+  <td class="na">N/A</td>
+  <td class="na">N/A</td>
+  <td class="na">N/A</td>
+  <td>Poor support for extended characters</td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;2.13.3 [lex.fcon]</td>
+  <td class="complete" align="center"></td>
+  <td class="na">N/A</td>
+  <td class="na">N/A</td>
+  <td class="na">N/A</td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;2.13.4 [lex.string]</td>
+  <td class="advanced" align="center"></td>
+  <td class="na">N/A</td>
+  <td class="na">N/A</td>
+  <td class="na">N/A</td>
+  <td>Poor support for extended characters</td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;2.13.5 [lex.bool]</td>
+  <td class="complete" align="center"></td>
+  <td class="na">N/A</td>
+  <td class="na">N/A</td>
+  <td class="na">N/A</td>
+  <td></td>
+</tr>
+<tr>
+<td>3 [basic]</td>
+  <td class="na">N/A</td>
+  <td class="na">N/A</td>
+  <td class="na">N/A</td>
+  <td class="na">N/A</td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;3.1 [basic.def]</td>
+  <td></td>
+  <td></td>
+  <td></td>
+  <td class="na">N/A</td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;3.2 [basic.def.odr]</td>
+  <td></td>
+  <td></td>
+  <td></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;3.3 [basic.scope]</td>
+  <td class="na">N/A</td>
+  <td class="na">N/A</td>
+  <td class="complete" align="center"></td>
+  <td class="na">N/A</td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;3.3.1 [basic.scope.pdecl]</td>
+  <td class="na">N/A</td>
+  <td class="na">N/A</td>
+  <td class="complete" align="center"></td>
+  <td class="na">N/A</td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;3.3.2 [basic.scope.local]</td>
+  <td class="na">N/A</td>
+  <td class="na">N/A</td>
+  <td class="complete" align="center"></td>
+  <td class="na">N/A</td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;3.3.3 [basic.scope.proto]</td>
+  <td class="na">N/A</td>
+  <td class="na">N/A</td>
+  <td class="complete" align="center"></td>
+  <td class="na">N/A</td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;3.3.4 [basic.funscope]</td>
+  <td class="na">N/A</td>
+  <td class="na">N/A</td>
+  <td class="complete" align="center"></td>
+  <td class="na">N/A</td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;3.3.5 [basic.scope.namespace]</td>
+  <td class="na">N/A</td>
+  <td class="na">N/A</td>
+  <td class="complete"></td>
+  <td class="na">N/A</td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;3.3.6 [basic.scope.class]</td>
+  <td class="na">N/A</td>
+  <td class="na">N/A</td>
+  <td class="advanced"></td>
+  <td class="na">N/A</td>
+  <td>Does not check that reordering the members of a class maintains semantics.</td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;3.3.7 [basic.scope.hiding]</td>
+  <td class="na">N/A</td>
+  <td class="na">N/A</td>
+  <td class="complete" align="center"></td>
+  <td class="na">N/A</td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;3.4 [basic.lookup]</td>
+  <td class="na">N/A</td>
+  <td class="na">N/A</td>
+  <td class="complete" align="center"></td>
+  <td class="na">N/A</td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;3.4.1 [basic.lookup.unqual]</td>
+  <td class="na">N/A</td>
+  <td class="na">N/A</td>
+  <td class="advanced"></td>
+  <td class="na">N/A</td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;3.4.2 [basic.lookup.argdep]</td>
+  <td class="na">N/A</td>
+  <td class="na">N/A</td>
+  <td class="complete"></td>
+  <td class="na">N/A</td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;3.4.3 [basic.lookup.qual]</td>
+  <td class="na">N/A</td>
+  <td class="na">N/A</td>
+  <td class="advanced"></td>
+  <td class="na">N/A</td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3.4.3.1 [class.qual]</td>
+  <td class="na">N/A</td>
+  <td class="na">N/A</td>
+  <td class="advanced"></td>
+  <td class="na">N/A</td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3.4.3.2 [namespace.qual]</td>
+  <td class="na">N/A</td>
+  <td class="na">N/A</td>
+  <td class="advanced"></td>
+  <td class="na">N/A</td>
+  <td></td>  
+</tr>
+<tr><td>&nbsp;&nbsp;&nbsp;&nbsp;3.4.4 [basic.lookup.elab]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;3.4.5 [basic.lookup.classref]</td>
+  <td class="na">N/A</td>
+  <td class="na">N/A</td>
+  <td class="advanced"></td>
+  <td class="na">N/A</td>
+  <td>Missing ambiguity/consistency checks for paragraphs 3 (~type-name) and 7 (conversion-type-id)</td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;3.4.6 [basic.lookup.udir]</td>
+  <td class="na">N/A</td>
+  <td class="na">N/A</td>
+  <td class="medium"></td>
+  <td class="na">N/A</td>
+  <td></td>
+</tr>
+<tr><td>&nbsp;&nbsp;3.5 [basic.link]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;3.6 [basic.start]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;&nbsp;&nbsp;3.6.1 [basic.start.main]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;&nbsp;&nbsp;3.6.2 [basic.start.init]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;&nbsp;&nbsp;3.6.3 [basic.start.term]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;3.7 [basic.stc]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;&nbsp;&nbsp;3.7.1 [basic.stc.static]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;&nbsp;&nbsp;3.7.2 [basic.stc.auto]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;&nbsp;&nbsp;3.7.3 [basic.stc.dynamic]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3.7.3.1 [basic.stc.dynamic.allocation]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3.7.3.2 [basic.stc.dynamic.deallocation]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;&nbsp;&nbsp;3.7.4 [basic.stc.inherit]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;3.8 [basic.life]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;3.9 [basic.types]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;&nbsp;&nbsp;3.9.1 [basic.fundamental]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;&nbsp;&nbsp;3.9.2 [basic.compound]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;&nbsp;&nbsp;3.9.3 [basic.type.qualifier]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;3.10 [basic.lval]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr>
+  <td>4 [conv]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;4.1 [conv.lval]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="advanced" align="center"></td> <!-- p2: sizeof -->
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;4.2 [conv.array]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;4.3 [conv.func]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;4.4 [conv.qual]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;4.5 [conv.prom]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;4.6 [conv.fpprom]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;4.7 [conv.integral]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;4.8 [conv.double]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;4.9 [conv.fpint]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;4.10 [conv.ptr]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;4.11 [conv.mem]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;4.12 [conv.bool]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>5 [expr]</td>
+  <td class="na">N/A</td>
+  <td class="na">N/A</td>
+  <td class="complete" align="center">&#x2713;</td>
+  <td class="na">N/A</td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;5.1 [expr.prim]</td>
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr><td>&nbsp;&nbsp;5.2 [expr.post]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;5.2.1 [expr.sub]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;5.2.2 [expr.call]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;5.2.3 [expr.type.conv]</td>
+  <td class="complete" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="advanced"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;5.2.4 [expr.pseudo]</td>
+  <td class="complete"></td>
+  <td class="complete"></td>
+  <td class="complete"></td>
+  <td class="complete"></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;5.2.5 [expr.ref]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete"></td>
+  <td class="complete"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;5.2.6 [expr.post.incr]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;5.2.7 [expr.dynamic.cast]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;5.2.8 [expr.typeid]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;5.2.9 [expr.static.cast]</td>
+  <td class="complete" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;5.2.10 [expr.reinterpret.cast]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;5.2.11 [expr.const.cast]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr><td>&nbsp;&nbsp;5.3 [expr.unary]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;&nbsp;&nbsp;5.3.1 [expr.unary.op]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;5.3.1p1 Unary *</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;5.3.1p2-5 Unary &amp;</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;5.3.1p6 Unary +</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;5.3.1p7 Unary -</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;5.3.1p8 Unary !</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;5.3.1p9 Unary ~</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;5.3.2 [expr.pre.incr]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;5.3.3 [expr.sizeof]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;5.3.4 [expr.new]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td></td>
+  <td>operator delete is not looked up, initialization not quite correct</td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;5.3.5 [expr.delete]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;5.4 [expr.cast]</td>
+  <td class="complete" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="advanced"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;5.5 [expr.mptr.oper]</td>
+  <td class="complete" align="center"></td>
+  <td class="advanced"></td>
+  <td class="advanced"></td>
+  <td></td>
+  <td>Dereferenced member function pointers have the wrong type(see FIXME in CheckPointerToMemberOperands).</td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;5.6 [expr.mul]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;5.7 [expr.add]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;5.8 [expr.shift]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;5.9 [expr.rel]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;5.10 [expr.eq]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;5.11 [expr.bit.and]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;5.12 [expr.xor]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;5.13 [expr.or]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;5.14 [expr.log.and]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;5.15 [expr.log.or]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;5.16 [expr.cond]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+  <td>some invalid hierarchy casts still accepted, but that's a general problem</td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;5.17 [expr.ass]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;5.18 [expr.comma]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;5.19 [expr.const]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="basic"></td>
+  <td></td>
+  <td>Uses C semantics</td>
+</tr>
+<tr>
+  <td>6 [stmt.stmt]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;6.1 [stmt.label]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;6.2 [stmt.expr]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;6.3 [stmt.block]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;6.4 [stmt.select]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td></td>
+  <td>Conversion of declarations to required types not really supported.</td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;6.4.1 [stmt.if]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;6.4.2 [stmt.switch]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;6.5 [stmt.iter]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td></td>
+  <td>Conversion of declarations to required types not really supported.</td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;6.5.1 [stmt.while]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;6.5.2 [stmt.do]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;6.5.3 [stmt.for]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;6.6 [stmt.jump]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;6.6.1 [stmt.break]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;6.6.2 [stmt.cont]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;6.6.3 [stmt.return]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;6.6.4 [stmt.goto]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;6.7 [stmt.dcl]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td></td>
+  <td>Existence and accessibility of destructors is not tested for.</td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;6.8 [stmt.ambig]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr><td>7 [dcl.dcl]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>
+  &nbsp;&nbsp;7.1 [dcl.spec]</td>
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;7.1.1 [dcl.stc]</td>
+  <td class="complete" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td></td>
+  <td>Linkage merging has some errors.</td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;7.1.2 [dcl.fct.spec]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;7.1.3 [dcl.typedef]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;7.1.4 [dcl.friend]</td>
+  <td class="medium"></td>
+  <td class="medium"></td>
+  <td class="medium"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;7.1.5 [dcl.type]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;7.1.5.1 [dcl.type.cv]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;7.1.5.2 [dcl.type.simple]</td>
+  <td class="advanced"></td>
+  <td class="advanced"></td>
+  <td class="advanced"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;7.1.5.3 [dcl.type.elab]</td>
+  <td class="advanced"></td>
+  <td class="advanced"></td>
+  <td class="advanced"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;7.2 [dcl.enum]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;7.3 [basic.namespace]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;7.3.1 [namespace.def]</td>
+  <td class="advanced"></td>
+  <td class="advanced"></td>
+  <td class="advanced"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;7.3.1.1 [namespace.unnamed]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;7.3.1.2 [namespace.memdef]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="advanced"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;7.3.2 [namespace.alias]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="na">N/A</td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;7.3.3 [namespace.udecl]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="na">N/A</td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;7.3.4[namespace.udir]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="advanced"></td>
+  <td class="broken" align="center"></td>
+  <td>Example in p4 fails.</td>
+</tr>
+<tr><td>
+  &nbsp;&nbsp;7.4 [dcl.asm]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;7.5 [dcl.link]</td>
+  <td class="complete" align="center"></td>
+  <td class="medium"></td>
+  <td class="medium"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>8 [dcl.decl]</td><td></td><td></td><td></td><td></td><td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;8.1 [dcl.name]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="na">N/A</td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;8.2 [dcl.ambig.res]</td>
+  <td class="complete" align="center">&#x2713;</td>
+  <td class="na" align="center">N/A</td>
+  <td class="complete" align="center">&#x2713;</td>
+  <td class="na">N/A</td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;8.3 [dcl.meaning]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="na">N/A</td>
+  <td></td>
+</tr>
+  <tr>
+    <td>&nbsp;&nbsp;&nbsp;&nbsp;8.3.1 [dcl.ptr]</td>
+    <td class="complete" align="center"></td>
+    <td class="complete" align="center"></td>
+    <td class="complete" align="center"></td>
+    <td class="na">N/A</td>
+    <td></td>
+  </tr>
+  <tr>
+    <td>&nbsp;&nbsp;&nbsp;&nbsp;8.3.2 [dcl.ref]</td>
+    <td class="complete" align="center"></td>
+    <td class="complete" align="center"></td>
+    <td class="complete" align="center"></td>
+    <td class="na">N/A</td>
+    <td></td>
+  </tr>
+  <tr>
+    <td>&nbsp;&nbsp;&nbsp;&nbsp;8.3.3 [dcl.mptr]</td>
+    <td class="complete" align="center"></td>
+    <td class="complete" align="center"></td>
+    <td class="complete" align="center"></td>
+    <td class="na">N/A</td>
+    <td></td>
+  </tr>
+  <tr>
+    <td>&nbsp;&nbsp;&nbsp;&nbsp;8.3.4 [dcl.array]</td>
+    <td class="complete" align="center"></td>
+    <td class="complete" align="center"></td>
+    <td class="complete" align="center"></td>
+    <td class="na">N/A</td>
+    <td></td>
+  </tr>
+  <tr>
+    <td>&nbsp;&nbsp;&nbsp;&nbsp;8.3.5 [dcl.fct]</td>
+    <td class="complete" align="center"></td>
+    <td class="complete" align="center"></td>
+    <td class="complete" align="center"></td>
+    <td class="na">N/A</td>
+    <td></td>
+  </tr>
+  <tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;8.3.6 [dcl.fct.default]</td>
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="na">N/A</td>
+  <td>Partial support for default arguments of templates.</td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;8.4 [dcl.fct.def]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="medium" align="center"></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;8.5 [dcl.init]</td>
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="medium" align="center"></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;8.5.1[dcl.init.aggr]</td>
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="medium" align="center"></td>
+  <td class="basic" align="center"></td>
+  <td>No CodeGen for dynamic initialization.</td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;8.5.2[dcl.init.string]</td>
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="medium" align="center"></td>
+  <td class="basic" align="center"></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;8.5.3 [dcl.init.ref]</td>
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="medium" align="center"></td>
+  <td class="basic" align="center"></td>
+  <td></td>
+</tr>
+<tr>
+  <td>9 [class]</td>
+  <td class="advanced" align="center"></td>
+  <td></td>
+  <td></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;9.1 [class.name]</td>
+  <td class="complete" align="center"></td>  
+  <td class="complete" align="center"></td>  
+  <td class="complete" align="center"></td>  
+  <td class="na" align="center">N/A</td>  
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;9.2 [class.mem]</td>
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="medium" align="center"></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;9.3 [class.mfct]</td>
+  <td class="complete" align="center"></td>  
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="basic" align="center"></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;9.3.1 [class.mfct.non-static]</td>
+  <td class="complete" align="center"></td>  
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="basic" align="center"></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;9.3.2 [class.this]</td>
+  <td class="complete" align="center"></td>  
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="basic"></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;9.4 [class.static]</td>
+  <td class="complete" align="center"></td>  
+  <td class="complete" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="basic"></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;9.4.1 [class.static.mfct]</td>
+  <td class="complete" align="center"></td>  
+  <td class="complete" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="basic"></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;9.4.2 [class.static.data]</td>
+  <td class="complete" align="center"></td>  
+  <td class="complete" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="basic"></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;9.5 [class.union]</td>
+  <td class="complete" align="center"></td>  
+  <td class="complete" align="center"></td>
+  <td class="complete"></td>
+  <td class="complete"></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;9.6 [class.bit]</td>
+  <td class="complete" align="center"></td>  
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;9.7 [class.nest]</td>
+  <td class="complete" align="center"></td>  
+  <td class="advanced"></td>
+  <td class="advanced"></td>
+  <td class="na" align="center">N/A</td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;9.8 [class.local]</td>
+  <td class="complete" align="center">&#x2713;</td>
+  <td class="complete" align="center">&#x2713;</td>
+  <td class="complete" align="center">&#x2713;</td>
+  <td class="na" align="center">N/A</td>  
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;9.9 [class.nested.type]</td>
+  <td class="complete" align="center">&#x2713;</td>
+  <td class="complete" align="center">&#x2713;</td>
+  <td class="complete" align="center">&#x2713;</td>
+  <td class="na" align="center">N/A</td>  
+  <td></td>
+</tr>
+<tr>
+  <td>10 [class.derived]</td>
+  <td class="advanced" align="center"></td>  
+  <td class="advanced" align="center"></td>  
+  <td class="advanced" align="center"></td>  
+  <td class="medium" align="center"></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;10.1 [class.mi]</td>
+  <td class="advanced" align="center"></td>  
+  <td class="advanced" align="center"></td>  
+  <td class="advanced" align="center"></td>  
+  <td class="medium" align="center"></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;10.2 [class.member.lookup]</td>
+  <td class="complete" align="center"></td>  
+  <td class="complete" align="center"></td>  
+  <td class="complete" align="center"></td>  
+  <td class="na" align="center">N/A</td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;10.3 [class.virtual]</td>
+  <td class="advanced" align="center"></td>  
+  <td class="advanced" align="center"></td>  
+  <td class="advanced" align="center"></td>  
+  <td class="medium" align="center"></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;10.4 [class.abstract]</td>
+  <td class="complete" align="center"></td>  
+  <td class="complete" align="center"></td>  
+  <td class="complete" align="center"></td>  
+  <td class="na" align="center">N/A</td>
+  <td></td>
+ </tr>
+<tr>
+  <td>11 [class.access]</td>
+  <td class="medium" align="center"></td>  
+  <td class="medium" align="center"></td>  
+  <td class="broken" align="center"></td>  
+  <td class="na" align="center">N/A</td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;11.1 [class.access.spec]</td>
+  <td class="complete" align="center"></td>  
+  <td class="advanced" align="center"></td>  
+  <td class="complete" align="center"></td>  
+  <td class="na" align="center">N/A</td>
+  <td></td>  
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;11.2 [class.access.base]</td>
+  <td class="complete" align="center"></td>  
+  <td class="complete" align="center"></td>  
+  <td class="broken" align="center"></td>  
+  <td class="na" align="center">N/A</td>
+  <td></td>  
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;11.3 [class.access.dcl]</td>
+  <td class="broken" align="center"></td>  
+  <td class="broken" align="center"></td>  
+  <td class="broken" align="center"></td>  
+  <td class="na" align="center">N/A</td>
+  <td></td>  
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;11.4 [class.friend]</td>
+  <td class="medium" align="center"></td>  
+  <td class="medium" align="center"></td>  
+  <td class="medium" align="center"></td>  
+  <td class="na" align="center">N/A</td>
+  <td></td>  
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;11.5 [class.protected]</td>
+  <td class="na" align="center"></td>  
+  <td class="complete" align="center"></td>  
+  <td class="broken" align="center"></td>  
+  <td class="na" align="center">N/A</td>
+  <td></td>  
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;11.6 [class.access.virt]</td>
+  <td class="na" align="center"></td>  
+  <td class="na" align="center"></td>  
+  <td class="broken" align="center"></td>  
+  <td class="na" align="center">N/A</td>
+  <td></td>  
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;11.7 [class.paths]</td>
+  <td class="na" align="center"></td>  
+  <td class="na" align="center"></td>  
+  <td class="broken" align="center"></td>  
+  <td class="na" align="center">N/A</td>
+  <td></td>  
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;11.8 [class.access.nest]</td>
+  <td class="na" align="center"></td>  
+  <td class="na" align="center"></td>  
+  <td class="broken" align="center"></td>  
+  <td class="na" align="center">N/A</td>
+  <td></td>  
+</tr>
+<tr><td>12 [special]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr>
+  <td>&nbsp;&nbsp;12.1 [class.ctor]</td>
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;12.2 [class.temporary]</td>
+  <td class="na" align="center">N/A</td>
+  <td class="medium" align="center"></td>
+  <td class="medium" align="center"></td>
+  <td class="medium" align="center"></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;12.3 [class.conv]</td>
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;12.3.1 [class.conv.ctor]</td>
+  <td class="complete" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;12.3.2 [class.conv.fct]</td>
+  <td class="complete" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;12.4 [class.dtor]</td>
+  <td class="advanced" align="center"></td>
+  <td class="medium" align="center"></td>
+  <td class="medium" align="center"></td>
+  <td class="medium" align="center"></td>
+  <td></td>
+</tr>
+<tr><td>&nbsp;&nbsp;12.5 [class.free]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;12.6 [class.init]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;&nbsp;&nbsp;12.6.1 [class.expl.init]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;12.6.2 [class.base.init]</td>
+  <td class="advanced" align="center"></td>
+  <td class="medium" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td>Most of the semantics of base initializations are implemented.</td>
+</tr>
+<tr><td>&nbsp;&nbsp;12.7 [class.cdtor]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr>
+  <td>&nbsp;&nbsp;12.8 [class.copy]</td>
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td>Most of the semantics of copy constructors are implemented.</td>
+</tr>
+
+<tr><td>13 [over]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr>
+  <td>&nbsp;&nbsp;13.1 [over.load]</td>
+  <td class="na" align="center">N/A</td>  
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="medium" align="center"></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;13.2 [over.dcl]</td>
+  <td class="na" align="center">N/A</td>  
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="na" align="center">N/A</td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;13.3 [over.match]</td>
+  <td class="na" align="center">N/A</td>  
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="na" align="center">N/A</td>  
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;13.3.1 [over.match.funcs]</td>
+  <td class="na" align="center">N/A</td>  
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="na" align="center">N/A</td>  
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;13.3.1.1 [over.match.call]</td>
+  <td class="na" align="center">N/A</td>  
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="na" align="center">N/A</td>  
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;13.3.1.1.1 [over.call.func]</td>
+  <td class="na" align="center">N/A</td>  
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="na" align="center">N/A</td>  
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;13.3.1.1.2 [over.call.object]</td>
+  <td class="na" align="center">N/A</td>  
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="na" align="center">N/A</td>  
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;13.3.1.2 [over.match.oper]</td>
+  <td class="na" align="center">N/A</td>  
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="na" align="center">N/A</td>  
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;13.3.1.3 [over.match.ctor]</td>
+  <td class="na" align="center">N/A</td>  
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="na" align="center">N/A</td>  
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;13.3.1.4 [over.match.copy]</td>
+  <td class="na" align="center">N/A</td>  
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="na" align="center">N/A</td>  
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;13.3.1.5 [over.match.conv]</td>
+  <td class="na" align="center">N/A</td>  
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="na" align="center">N/A</td>  
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;13.3.1.6 [over.match.ref]</td>
+  <td class="na" align="center">N/A</td>  
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="na" align="center">N/A</td>  
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;13.3.2 [over.match.viable]</td>
+  <td class="na" align="center">N/A</td>  
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="na" align="center">N/A</td>  
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;13.3.3 [over.match.best]</td>
+  <td class="na" align="center">N/A</td>  
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="na" align="center">N/A</td>  
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;13.3.3.1 [over.best.ics]</td>
+  <td class="na" align="center">N/A</td>  
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="na" align="center">N/A</td>  
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;13.3.3.1.1 [over.ics.scs]</td>
+  <td class="na" align="center">N/A</td>  
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="na" align="center">N/A</td>  
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;13.3.3.1.2 [over.ics.user]</td>
+  <td class="na" align="center">N/A</td>  
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="na" align="center">N/A</td>  
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;13.3.3.1.3 [over.ics.ellipsis]</td>
+  <td class="na" align="center">N/A</td>  
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="na" align="center">N/A</td>  
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;13.3.3.1.4 [over.ics.ref]</td>
+  <td class="na" align="center">N/A</td>  
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="na" align="center">N/A</td>  
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;13.3.3.2 [over.ics.rank]</td>
+  <td class="na" align="center">N/A</td>  
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="na" align="center">N/A</td>  
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;13.4 [over.over]</td>
+  <td class="na" align="center">N/A</td>  
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="na" align="center">N/A</td>  
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;13.5 [over.oper]</td>
+  <td class="advanced" align="center"></td>  
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="na" align="center">N/A</td>  
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;13.5.1 [over.unary]</td>
+  <td class="na" align="center">N/A</td>  
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="na" align="center">N/A</td>  
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;13.5.2 [over.binary]</td>
+  <td class="na" align="center">N/A</td>  
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="na" align="center">N/A</td>  
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;13.5.3 [over.ass]</td>
+  <td class="na" align="center">N/A</td>  
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="na" align="center">N/A</td>  
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;13.5.4 [over.call]</td>
+  <td class="na" align="center">N/A</td>  
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="na" align="center">N/A</td>  
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;13.5.5 [over.sub]</td>
+  <td class="na" align="center">N/A</td>  
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="na" align="center">N/A</td>  
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;13.5.6 [over.ref]</td>
+  <td class="na" align="center">N/A</td>  
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="na" align="center">N/A</td>  
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;13.5.7 [over.inc]</td>
+  <td class="na" align="center">N/A</td>  
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="na" align="center">N/A</td>  
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;13.6 [over.built]</td>
+  <td class="na" align="center">N/A</td>  
+  <td class="advanced" align="center"></td>
+  <td class="medium" align="center"></td>
+  <td class="na" align="center">N/A</td>  
+  <td>Missing support for the ternary operator (p24, p25).</td>
+</tr>
+<tr>
+  <td>14 [temp]</td>
+  <td class="medium" align="center"></td>  
+  <td class="basic" align="center"></td>
+  <td class="basic" align="center"></td>
+  <td class="broken" align="center"></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;14.1 [temp.param]</td>
+  <td class="complete" align="center">&#x2713;</td>  
+  <td class="complete" align="center">&#x2713;</td>
+  <td class="medium" align="center"></td>
+  <td class="na" align="center">N/A</td>
+  <td></td>  
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;14.2 [temp.names]</td>
+  <td class="complete" align="center"></td>  
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="na" align="center">N/A</td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;14.3 [temp.arg]</td>
+  <td class="complete" align="center"></td>  
+  <td class="complete" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="na" align="center">N/A</td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;14.3.1 [temp.arg.type]</td>
+  <td class="complete" align="center">&#x2713;</td>  
+  <td class="complete" align="center">&#x2713;</td>
+  <td class="complete" align="center"></td>
+  <td class="na" align="center">N/A</td>
+  <td>Paragraph 3 will be tested elsewhere</td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;14.3.2 [temp.arg.nontype]</td>
+  <td class="complete" align="center"></td>  
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="na" align="center">N/A</td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;14.3.3 [temp.arg.template]</td>
+  <td class="complete" align="center"></td>  
+  <td class="medium" align="center"></td>
+  <td class="basic" align="center"></td>
+  <td class="na" align="center">N/A</td>
+  <td></td>  
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;14.4 [temp.type]</td>
+  <td class="na" align="center">N/A</td>  
+  <td class="complete" align="center">&#x2713;</td>
+  <td class="complete" align="center">&#x2713;</td>
+  <td class="na" align="center">N/A</td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;14.5 [temp.decls]</td><td></td><td></td><td></td><td></td><td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;14.5.1 [temp.class]</td>
+  <td class="advanced" align="center"></td>  
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="medium" align="center"></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;14.5.1.1 [temp.mem.func]</td>
+  <td class="advanced" align="center"></td>  
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="medium" align="center"></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;14.5.1.2 [temp.mem.class]</td>
+  <td class="advanced" align="center"></td>  
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="medium" align="center"></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;14.5.1.3 [temp.static]</td>
+  <td class="advanced" align="center"></td>  
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="medium" align="center"></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;14.5.2 [temp.mem]</td>
+  <td class="advanced" align="center"></td>  
+  <td class="medium" align="center"></td>
+  <td class="medium" align="center"></td>
+  <td class="na" align="center"></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;14.5.3 [temp.friend]</td>
+  <td class="medium" align="center"></td>  
+  <td class="medium" align="center"></td>
+  <td class="broken" align="center"></td>
+  <td class="na" align="center">N/A</td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;14.5.4 [temp.class.spec]</td>
+  <td class="complete" align="center"></td>  
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="na" align="center">N/A</td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;14.5.4.1 [temp.class.spec.match]</td>
+  <td class="na" align="center">N/A</td>  
+  <td class="na" align="center">N/A</td>
+  <td class="complete" align="center"></td>
+  <td class="na" align="center">N/A</td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;14.5.4.2 [temp.class.order]</td>
+  <td class="na" align="center"></td>  
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="na" align="center">N/A</td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;14.5.5.3 [temp.class.spec.mfunc]</td>
+  <td class="advanced" align="center"></td>  
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="na" align="center">N/A</td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;14.5.5 [temp.fct]</td>
+  <td class="advanced" align="center"></td>  
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="medium" align="center"></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;14.5.5.1 [temp.over.link]</td>
+  <td class="na" align="center"></td>  
+  <td class="complete" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="na" align="center">N/A</td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;14.5.5.2 [temp.func.order]</td>
+  <td class="na" align="center"></td>  
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="na" align="center">N/A</td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;14.6 [temp.res]</td>
+  <td class="advanced" align="center"></td>  
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="na" align="center"></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;14.6.1 [temp.local]</td>
+  <td class="advanced" align="center"></td>  
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="na" align="center"></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;14.6.2 [temp.dep]</td>
+  <td class="na" align="center">N/A</td>  
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="na" align="center"></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;14.6.2.1 [temp.dep.type]</td>
+  <td class="na" align="center">N/A</td>  
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="na" align="center"></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;14.6.2.2 [temp.dep.expr]</td>
+  <td class="na" align="center">N/A</td>  
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="na" align="center"></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;14.6.2.3 [temp.dep.constexpr]</td>
+  <td class="na" align="center">N/A</td>
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="na" align="center"></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;14.6.2.4 [temp.dep.temp]</td>
+  <td class="na" align="center">N/A</td>
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="na" align="center"></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;14.6.3 [temp.nondep]</td>
+  <td class="na" align="center">N/A</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="na" align="center"></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;14.6.4 [temp.dep.res]</td>
+  <td class="na" align="center">N/A</td>
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="na" align="center"></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;14.6.4.1 [temp.point]</td>
+  <td class="na" align="center">N/A</td>
+  <td class="medium" align="center"></td>
+  <td class="medium" align="center"></td>
+  <td class="medium" align="center"></td>
+  <td></td>  
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;14.6.4.2 [temp.dep.candidate]</td>
+  <td class="na" align="center">N/A</td>
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="na" align="center"></td>
+  <td>Not restricted to functions with external linkage</td>  
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;14.6.5 [temp.inject]</td>
+  <td class="na" align="center">N/A</td>
+  <td class="basic" align="center"></td>
+  <td class="basic" align="center"></td>
+  <td class="na" align="center"></td>
+  <td></td>  
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;14.7 [temp.spec]</td>
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td></td>  
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;14.7.1 [temp.inst]</td>
+  <td class="na" align="center">N/A</td>
+  <td class="na" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td></td>  
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;14.7.2 [temp.explicit]</td>
+  <td class="complete" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td>Cannot test paragraph 11 until access control is implemented.<br/>
+    ASTs do not carry enough information to reproduce source code accurately.</td>  
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;14.7.3 [temp.expl.spec]</td>
+  <td class="complete" align="center">&#x2713;</td>
+  <td class="advanced" align="center"></td>
+  <td class="complete" align="center">&#x2713;</td>
+  <td class="complete" align="center"></td>
+  <td>ASTs do not carry enough information to reproduce source code accurately</td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;14.8 [temp.fct.spec]</td>
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;14.8.1 [temp.arg.explicit]</td>
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="na" align="center"></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;14.8.2 [temp.deduct]</td>
+  <td class="na" align="center">N/A</td>
+  <td class="na" align="center">N/A</td>
+  <td class="advanced" align="center"></td>
+  <td class="na" align="center">N/A</td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;14.8.2.1 [temp.deduct.call]</td>
+  <td class="na" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="na" align="center"></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;14.8.2.2 [temp.deduct.funcaddr]</td>
+  <td class="na" align="center">N/A</td>
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="na" align="center">N/A</td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;14.8.2.3 [temp.deduct.conv]</td>
+  <td class="na" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="na" align="center"></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;14.8.2.4 [temp.deduct.type]</td>
+  <td class="na" align="center">N/A</td>
+  <td class="complete" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="na" align="center">N/A</td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;14.8.3 [temp.over]</td>
+  <td class="na" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="na" align="center"></td>
+  <td></td>
+</tr>
+<tr>
+  <td>15 [except]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;15.1 [except.throw]</td>
+  <td class="na" align="center">N/A</td>
+  <td class="na" align="center">N/A</td>
+  <td class="advanced" align="center"></td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;15.2 [except.ctor]</td>
+  <td class="na" align="center">N/A</td>
+  <td class="na" align="center">N/A</td>
+  <td class="na" align="center">N/A</td>
+  <td></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;15.3 [except.handle]</td>
+  <td class="na" align="center">N/A</td>
+  <td class="na" align="center">N/A</td>
+  <td class="advanced" align="center"></td>
+  <td></td>
+  <td>Not all constraints are checked</td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;15.4 [except.spec]</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="broken"></td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;15.5 [except.special]</td>
+  <td class="na" align="center">N/A</td>
+  <td class="na" align="center">N/A</td>
+  <td class="na" align="center">N/A</td>
+  <td class="na" align="center">N/A</td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;15.5.1 [except.terminate]</td>
+  <td class="na" align="center">N/A</td>
+  <td class="na" align="center">N/A</td>
+  <td class="na" align="center">N/A</td>
+  <td class="na" align="center">N/A</td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;15.5.2 [except.unexpected]</td>
+  <td class="na" align="center">N/A</td>
+  <td class="na" align="center">N/A</td>
+  <td class="na" align="center">N/A</td>
+  <td class="na" align="center">N/A</td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;&nbsp;&nbsp;15.5.3 [except.uncaught]</td>
+  <td class="na" align="center">N/A</td>
+  <td class="na" align="center">N/A</td>
+  <td class="na" align="center">N/A</td>
+  <td class="na" align="center">N/A</td>
+  <td></td>
+</tr>
+<tr>
+  <td>&nbsp;&nbsp;15.6 [except.access]</td>
+  <td class="na" align="center">N/A</td>
+  <td class="na" align="center">N/A</td>
+  <td class="na" align="center">N/A</td>
+  <td class="na" align="center">N/A</td>
+  <td>Redundant - struck from C++0x</td>
+</tr>
+<tr><td>16 [cpp]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;16.1 [cpp.cond]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;16.2 [cpp.include]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;16.3 [cpp.replace]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;&nbsp;&nbsp;16.3.1 [cpp.subst]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;&nbsp;&nbsp;16.3.2 [cpp.stringize]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;&nbsp;&nbsp;16.3.3 [cpp.concat]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;&nbsp;&nbsp;16.3.4 [cpp.rescan]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;&nbsp;&nbsp;16.3.5 [cpp.scope]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;16.4 [cpp.line]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;16.5 [cpp.error]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;16.6 [cpp.pragma]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;16.7 [cpp.null]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;16.8 [cpp.predefined]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>A [gram]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;A.1 [gram.key]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;A.2 [gram.lex]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;A.3 [gram.basic]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;A.4 [gram.expr]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;A.5 [gram.stmt]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;A.6 [gram.dcl]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;A.7 [gram.decl]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;A.8 [gram.class]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;A.9 [gram.derived]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;A.10 [gram.special]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;A.11 [gram.over]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;A.12 [gram.temp]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;A.13 [gram.except]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;A.14 [gram.cpp]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>B [implimits]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>C [diff]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;C.1 [diff.iso]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;&nbsp;&nbsp;C.1.1 [diff.lex]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;&nbsp;&nbsp;C.1.2 [diff.basic]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;&nbsp;&nbsp;C.1.3 [diff.expr]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;&nbsp;&nbsp;C.1.4 [diff.stat]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;&nbsp;&nbsp;C.1.5 [diff.dcl]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;&nbsp;&nbsp;C.1.6 [diff.decl]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;&nbsp;&nbsp;C.1.7 [diff.class]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;&nbsp;&nbsp;C.1.8 [diff.special]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;&nbsp;&nbsp;C.1.9 [diff.cpp]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;C.2 [diff.library]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;&nbsp;&nbsp;C.2.1 [diff.mods.to.headers]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;&nbsp;&nbsp;C.2.2 [diff.mods.to.definitions]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;C.2.2.2 [diff.wchar.t]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;C.2.2.3 [diff.header.iso646.h]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;C.2.2.4 [diff.null]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;&nbsp;&nbsp;C.2.3 [diff.mods.to.declarations]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;&nbsp;&nbsp;C.2.4 [diff.mods.to.behavior]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;C.2.4.1 [diff.offsetof]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;C.2.4.2 [diff.malloc]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>D [depr]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;D.1 [depr.incr.bool]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;D.2 [depr.static]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;D.3 [depr.access.dcl]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;D.4 [depr.string]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>&nbsp;&nbsp;D.5 [depr.c.headers]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td>E [extendid]</td><td></td><td></td><td></td><td></td><td></td></tr>
+<tr>
+</table>
+
+  <h2 id="cxx0x">C++0x Implementation status</h2>
+<p>Clang's development effort is focused primarily on supporting the current ISO C++ standard (1998/2003). This section tracks the status of various C++0x features. In general, the implementations of these features are far less developed than C++98/03 features.</p>
+
+<table width="689" border="1" cellspacing="0">
+  <td colspan="6" align="center" bgcolor="#ffffcc">C++0x Features</td>
+</tr>
+<tr>
+  <td>Explicit conversion operators (<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2437.pdf">N2437</a>)</td>
+  <td class="complete" align="center"></td>
+  <td class="medium" align="center"></td>
+  <td class="advanced" align="center"></td>
+  <td class="broken"></td>
+  <td>No name mangling; ASTs don't contain calls to conversion operators</td>
+</tr>
+<tr>
+  <td>Static assertions (<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1720.pdf">N1720</a>)</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="na">N/A</td>
+  <td></td>
+</tr>
+<tr>
+  <td>Deleted functions (<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2346.htm">N2346</a>)</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="na">N/A</td>
+  <td></td>
+</tr>
+<tr>
+  <td>Rvalue references (<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2118.html">N2118</a> + <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2831.html">N2831</a>)</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="broken"></td>
+  <td></td>
+</tr>
+<tr>
+  <td>nullptr (<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2431.pdf">N2431</a>)</td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="complete" align="center"></td>
+  <td class="broken"></td>
+  <td></td>
+</tr>
+<tr>
+  <td>Right angle brackets (<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1757.html">N1757</a>)</td>
+  <td class="complete" align="center"></td>
+  <td class="na" align="center">N/A</td>
+  <td class="na" align="center">N/A</td>
+  <td class="na">N/A</td>
+  <td></td>
+</tr>
+<tr>
+  <td>Decltype (<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2343.pdf">N2343</a>)</td>
+  <td class="complete" align="center">&#x2713;</td>
+  <td class="complete" align="center">&#x2713;</td>
+  <td class="complete" align="center">&#x2713;</td>
+  <td class="na">N/A</td>
+  <td></td>
+</tr>
+</table>
+<br />
+</div>
+</body>
+</html>
diff --git a/www/demo/DemoInfo.html b/www/demo/DemoInfo.html
new file mode 100644
index 0000000..54a5afa
--- /dev/null
+++ b/www/demo/DemoInfo.html
@@ -0,0 +1,83 @@
+
+<html>
+<head>
+<title>
+Demo page information
+</title>
+</head>
+
+<body>
+
+<h1>Demo page information</h1>
+
+<p>Press "back" or <a href=".">click here</a> to return to the demo 
+page.</p>
+
+<h2><a name="hints">Hints and Advice</a></h2>
+
+<ul>
+<li>The generated LLVM code will be easier to read if
+you use stdio (e.g., printf) than iostreams (e.g., std::cout).</li>
+
+<li>Unused inline functions and methods are not generated.  Instead 
+of '<tt>class foo { void bar() {}};</tt>',
+try writing '<tt>class foo { void bar(); }; void foo::bar() {}</tt>'.</li>
+
+<li>If you want to try out a file that uses non-standard header files,  you should
+  preprocess it (e.g., with the <tt>-save-temps</tt> or <tt>-E</tt> options to
+  <tt>gcc</tt>) then upload the result.</li>
+
+</ul>
+
+
+<h2><a name="demangle">Demangle C++ names with C++ filt</a></h2>
+
+<p>
+Select this option if you want to run the output LLVM IR through "c++filt", 
+which converts 'mangled' C++ names to their unmangled version. 
+Note that LLVM code produced will not be lexically valid, but it will 
+be easier to understand.
+</p>
+
+<h2><a name="lto">Run link-time optimizer</a></h2>
+
+<p>
+Select this option to run the LLVM link-time optimizer, which is designed to
+optimize across files in your application.  Since the demo page doesn't allow
+you to upload multiple files at once, and does not link in any libraries, we
+configured the demo page optimizer to assume there are no calls 
+coming in from outside the source file, allowing it to optimize more 
+aggressively.</p>
+
+<p>Note that you have to define 'main' in your program for this 
+to make much of a difference.
+</p>
+
+<h2><a name="stats">Show detailed pass statistics</a></h2>
+
+<p>
+Select this option to enable compilation timings and statistics from various
+optimizers.</p>
+
+
+<h2><a name="bcanalyzer">Analyze generated bytecode</a></h2>
+
+<p>
+Select this option to run the <a 
+href="http://llvm.org/cmds/llvm-bcanalyzer.html">llvm-bcanalyzer</a> tool
+on the generated bytecode, which introspects into the format of the .bc file
+itself.  </p>
+
+
+<h2><a name="llvm2cpp">Show C++ API code</a></h2>
+
+<p>
+Select this option to run the <a 
+href="http://llvm.org/cmds/llvm2cpp.html">llvm2cpp</a> tool
+on the generated bytecode, which auto generates the C++ API calls that could
+be used to create the .bc file.
+</p>
+
+</body>
+</html>
+
diff --git a/www/demo/cathead.png b/www/demo/cathead.png
new file mode 100644
index 0000000..3bf1a45
--- /dev/null
+++ b/www/demo/cathead.png
Binary files differ
diff --git a/www/demo/index.cgi b/www/demo/index.cgi
new file mode 100644
index 0000000..b29efb6
--- /dev/null
+++ b/www/demo/index.cgi
@@ -0,0 +1,461 @@
+#!/usr/dcs/software/supported/bin/perl -w
+# LLVM Web Demo script
+#
+
+use strict;
+use CGI;
+use POSIX;
+use Mail::Send;
+
+$| = 1;
+
+my $ROOT = "/tmp/webcompile";
+#my $ROOT = "/home/vadve/lattner/webcompile";
+
+open( STDERR, ">&STDOUT" ) or die "can't redirect stderr to stdout";
+
+if ( !-d $ROOT ) { mkdir( $ROOT, 0777 ); }
+
+my $LOGFILE         = "$ROOT/log.txt";
+my $FORM_URL        = 'index.cgi';
+my $MAILADDR        = 'sabre@nondot.org';
+my $CONTACT_ADDRESS = 'Questions or comments?  Email the <a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev">LLVMdev mailing list</a>.';
+my $LOGO_IMAGE_URL  = 'cathead.png';
+my $TIMEOUTAMOUNT   = 20;
+$ENV{'LD_LIBRARY_PATH'} = '/home/vadve/shared/localtools/fc1/lib/';
+
+my @PREPENDPATHDIRS =
+  (  
+    '/home/vadve/shared/llvm-gcc4.0-2.1/bin/',
+    '/home/vadve/shared/llvm-2.1/Release/bin');
+
+my $defaultsrc = "#include <stdio.h>\n#include <stdlib.h>\n\n" .
+                 "int power(int X) {\n  if (X == 0) return 1;\n" .
+                 "  return X*power(X-1);\n}\n\n" .
+                 "int main(int argc, char **argv) {\n" .
+                 "  printf(\"%d\\n\", power(atoi(argv[0])));\n}\n";
+
+sub getname {
+    my ($extension) = @_;
+    for ( my $count = 0 ; ; $count++ ) {
+        my $name =
+          sprintf( "$ROOT/_%d_%d%s", $$, $count, $extension );
+        if ( !-f $name ) { return $name; }
+    }
+}
+
+my $c;
+
+sub barf {
+    print "<b>", @_, "</b>\n";
+    print $c->end_html;
+    system("rm -f $ROOT/locked");
+    exit 1;
+}
+
+sub writeIntoFile {
+    my $extension = shift @_;
+    my $contents  = join "", @_;
+    my $name      = getname($extension);
+    local (*FILE);
+    open( FILE, ">$name" ) or barf("Can't write to $name: $!");
+    print FILE $contents;
+    close FILE;
+    return $name;
+}
+
+sub addlog {
+    my ( $source, $pid, $result ) = @_;
+    open( LOG, ">>$LOGFILE" );
+    my $time       = scalar localtime;
+    my $remotehost = $ENV{'REMOTE_ADDR'};
+    print LOG "[$time] [$remotehost]: $pid\n";
+    print LOG "<<<\n$source\n>>>\nResult is: <<<\n$result\n>>>\n";
+    close LOG;
+}
+
+sub dumpFile {
+    my ( $header, $file ) = @_;
+    my $result;
+    open( FILE, "$file" ) or barf("Can't read $file: $!");
+    while (<FILE>) {
+        $result .= $_;
+    }
+    close FILE;
+    my $UnhilightedResult = $result;
+    my $HtmlResult        =
+      "<h3>$header</h3>\n<pre>\n" . $c->escapeHTML($result) . "\n</pre>\n";
+    if (wantarray) {
+        return ( $UnhilightedResult, $HtmlResult );
+    }
+    else {
+        return $HtmlResult;
+    }
+}
+
+sub syntaxHighlightLLVM {
+  my ($input) = @_;
+  $input =~ s@\b(void|i8|i1|i16|i32|i64|float|double|type|label|opaque)\b@<span class="llvm_type">$1</span>@g;
+  $input =~ s@\b(add|sub|mul|div|rem|and|or|xor|setne|seteq|setlt|setgt|setle|setge|phi|tail|call|cast|to|shl|shr|vaarg|vanext|ret|br|switch|invoke|unwind|malloc|alloca|free|load|store|getelementptr|begin|end|true|false|declare|global|constant|const|internal|uninitialized|external|implementation|linkonce|weak|appending|null|to|except|not|target|endian|pointersize|big|little|volatile)\b@<span class="llvm_keyword">$1</span>@g;
+
+  # Add links to the FAQ.
+  $input =~ s@(_ZNSt8ios_base4Init[DC]1Ev)@<a href="../docs/FAQ.html#iosinit">$1</a>@g;
+  $input =~ s@\bundef\b@<a href="../docs/FAQ.html#undef">undef</a>@g;
+  return $input;
+}
+
+sub mailto {
+    my ( $recipient, $body ) = @_;
+    my $msg =
+      new Mail::Send( Subject => "LLVM Demo Page Run", To => $recipient );
+    my $fh = $msg->open();
+    print $fh $body;
+    $fh->close();
+}
+
+$c = new CGI;
+print $c->header;
+
+print <<EOF;
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+  <title>Try out LLVM in your browser!</title>
+  <style>
+    \@import url("syntax.css");
+    \@import url("http://llvm.org/llvm.css");
+  </style>
+</head>
+<body leftmargin="10" marginwidth="10">
+
+<div class="www_sectiontitle">
+  Try out LLVM in your browser!
+</div>
+
+<table border=0><tr><td>
+<img align=right width=100 height=111 src="$LOGO_IMAGE_URL">
+</td><td>
+EOF
+
+if ( -f "$ROOT/locked" ) {
+  my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$locktime) = 
+    stat("$ROOT/locked");
+  my $currtime = time();
+  if ($locktime + 60 > $currtime) {
+    print "This page is already in use by someone else at this ";
+    print "time, try reloading in a second or two.  Meow!</td></tr></table>'\n";
+    exit 0;
+  }
+}
+
+system("touch $ROOT/locked");
+
+print <<END;
+Bitter Melon the cat says, paste a C/C++ program in the text box or upload
+one from your computer, and you can see LLVM compile it, meow!!
+</td></tr></table><p>
+END
+
+print $c->start_multipart_form( 'POST', $FORM_URL );
+
+my $source = $c->param('source');
+
+
+# Start the user out with something valid if no code.
+$source = $defaultsrc if (!defined($source));
+
+print '<table border="0"><tr><td>';
+
+print "Type your source code in below: (<a href='DemoInfo.html#hints'>hints and 
+advice</a>)<br>\n";
+
+print $c->textarea(
+    -name    => "source",
+    -rows    => 16,
+    -columns => 60,
+    -default => $source
+), "<br>";
+
+print "Or upload a file: ";
+print $c->filefield( -name => 'uploaded_file', -default => '' );
+
+print "<p />\n";
+
+
+print '<p></td><td valign=top>';
+
+print "<center><h3>General Options</h3></center>";
+
+print "Source language: ",
+  $c->radio_group(
+    -name    => 'language',
+    -values  => [ 'C', 'C++' ],
+    -default => 'C'
+  ), "<p>";
+
+print $c->checkbox(
+    -name  => 'linkopt',
+    -label => 'Run link-time optimizer',
+    -checked => 'checked'
+  ),' <a href="DemoInfo.html#lto">?</a><br>';
+
+print $c->checkbox(
+    -name  => 'showstats',
+    -label => 'Show detailed pass statistics'
+  ), ' <a href="DemoInfo.html#stats">?</a><br>';
+
+print $c->checkbox(
+    -name  => 'cxxdemangle',
+    -label => 'Demangle C++ names'
+  ),' <a href="DemoInfo.html#demangle">?</a><p>';
+
+
+print "<center><h3>Output Options</h3></center>";
+
+print $c->checkbox(
+    -name => 'showbcanalysis',
+    -label => 'Show detailed bytecode analysis'
+  ),' <a href="DemoInfo.html#bcanalyzer">?</a><br>';
+
+print $c->checkbox(
+    -name => 'showllvm2cpp',
+    -label => 'Show LLVM C++ API code'
+  ), ' <a href="DemoInfo.html#llvm2cpp">?</a>';
+
+print "</td></tr></table>";
+
+print "<center>", $c->submit(-value=> 'Compile Source Code'), 
+      "</center>\n", $c->endform;
+
+print "\n<p>If you have questions about the LLVM code generated by the
+front-end, please check the <a href='/docs/FAQ.html#cfe_code'>FAQ</a> and
+the demo page <a href='DemoInfo.html#hints'>hints section</a>.
+</p>\n";
+
+$ENV{'PATH'} = ( join ( ':', @PREPENDPATHDIRS ) ) . ":" . $ENV{'PATH'};
+
+sub sanitychecktools {
+    my $sanitycheckfail = '';
+
+    # insert tool-specific sanity checks here
+    $sanitycheckfail .= ' llvm-dis'
+      if `llvm-dis --help 2>&1` !~ /ll disassembler/;
+
+    $sanitycheckfail .= ' llvm-gcc'
+      if ( `llvm-gcc --version 2>&1` !~ /Free Software Foundation/ );
+
+    $sanitycheckfail .= ' llvm-ld'
+      if `llvm-ld --help 2>&1` !~ /llvm linker/;
+
+    $sanitycheckfail .= ' llvm-bcanalyzer'
+      if `llvm-bcanalyzer --help 2>&1` !~ /bcanalyzer/;
+
+    barf(
+"<br/>The demo page is currently unavailable. [tools: ($sanitycheckfail ) failed sanity check]"
+      )
+      if $sanitycheckfail;
+}
+
+sanitychecktools();
+
+sub try_run {
+    my ( $program, $commandline, $outputFile ) = @_;
+    my $retcode = 0;
+
+    eval {
+        local $SIG{ALRM} = sub { die "timeout"; };
+        alarm $TIMEOUTAMOUNT;
+        $retcode = system($commandline);
+        alarm 0;
+    };
+    if ( $@ and $@ =~ /timeout/ ) { 
+      barf("Program $program took too long, compile time limited for the web script, sorry!.\n"); 
+    }
+    if ( -s $outputFile ) {
+        print scalar dumpFile( "Output from $program", $outputFile );
+    }
+    #print "<p>Finished dumping command output.</p>\n";
+    if ( WIFEXITED($retcode) && WEXITSTATUS($retcode) != 0 ) {
+        barf(
+"$program exited with an error. Please correct source and resubmit.<p>\n" .
+"Please note that this form only allows fully formed and correct source" .
+" files.  It will not compile fragments of code.<p>"
+        );
+    }
+    if ( WIFSIGNALED($retcode) != 0 ) {
+        my $sig = WTERMSIG($retcode);
+        barf(
+            "Ouch, $program caught signal $sig. Sorry, better luck next time!\n"
+        );
+    }
+}
+
+my %suffixes = (
+    'Java'             => '.java',
+    'JO99'             => '.jo9',
+    'C'                => '.c',
+    'C++'              => '.cc',
+    'Stacker'          => '.st',
+    'preprocessed C'   => '.i',
+    'preprocessed C++' => '.ii'
+);
+my %languages = (
+    '.jo9'  => 'JO99',
+    '.java' => 'Java',
+    '.c'    => 'C',
+    '.i'    => 'preprocessed C',
+    '.ii'   => 'preprocessed C++',
+    '.cc'   => 'C++',
+    '.cpp'  => 'C++',
+    '.st'   => 'Stacker'
+);
+
+my $uploaded_file_name = $c->param('uploaded_file');
+if ($uploaded_file_name) {
+    if ($source) {
+        barf(
+"You must choose between uploading a file and typing code in. You can't do both at the same time."
+        );
+    }
+    $uploaded_file_name =~ s/^.*(\.[A-Za-z]+)$/$1/;
+    my $language = $languages{$uploaded_file_name};
+    $c->param( 'language', $language );
+
+    print "<p>Processing uploaded file. It looks like $language.</p>\n";
+    my $fh = $c->upload('uploaded_file');
+    if ( !$fh ) {
+        barf( "Error uploading file: " . $c->cgi_error );
+    }
+    while (<$fh>) {
+        $source .= $_;
+    }
+    close $fh;
+}
+
+if ($c->param('source')) {
+    print $c->hr;
+    my $extension = $suffixes{ $c->param('language') };
+    barf "Unknown language; can't compile\n" unless $extension;
+
+    # Add a newline to the source here to avoid a warning from gcc.
+    $source .= "\n";
+
+    # Avoid security hole due to #including bad stuff.
+    $source =~
+s@(\n)?#include.*[<"](.*\.\..*)[">].*\n@$1#error "invalid #include file $2 detected"\n@g;
+
+    my $inputFile = writeIntoFile( $extension, $source );
+    my $pid       = $$;
+
+    my $bytecodeFile = getname(".bc");
+    my $outputFile   = getname(".llvm-gcc.out");
+    my $timerFile    = getname(".llvm-gcc.time");
+
+    my $stats = '';
+    if ( $extension eq ".st" ) {
+      $stats = "-stats -time-passes "
+	if ( $c->param('showstats') );
+      try_run( "llvm Stacker front-end (stkrc)",
+        "stkrc $stats -o $bytecodeFile $inputFile > $outputFile 2>&1",
+        $outputFile );
+    } else {
+      #$stats = "-Wa,--stats,--time-passes,--info-output-file=$timerFile"
+      $stats = "-ftime-report"
+	if ( $c->param('showstats') );
+      try_run( "llvm C/C++ front-end (llvm-gcc)",
+	"llvm-gcc -emit-llvm -W -Wall -O2 $stats -o $bytecodeFile -c $inputFile > $outputFile 2>&1",
+        $outputFile );
+    }
+
+    if ( $c->param('showstats') && -s $timerFile ) {
+        my ( $UnhilightedResult, $HtmlResult ) =
+          dumpFile( "Statistics for front-end compilation", $timerFile );
+        print "$HtmlResult\n";
+    }
+
+    if ( $c->param('linkopt') ) {
+        my $stats      = '';
+        my $outputFile = getname(".gccld.out");
+        my $timerFile  = getname(".gccld.time");
+        $stats = "--stats --time-passes --info-output-file=$timerFile"
+          if ( $c->param('showstats') );
+        my $tmpFile = getname(".bc");
+        try_run(
+            "optimizing linker (llvm-ld)",
+"llvm-ld $stats -o=$tmpFile $bytecodeFile > $outputFile 2>&1",
+            $outputFile
+        );
+        system("mv $tmpFile.bc $bytecodeFile");
+        system("rm $tmpFile");
+
+        if ( $c->param('showstats') && -s $timerFile ) {
+            my ( $UnhilightedResult, $HtmlResult ) =
+              dumpFile( "Statistics for optimizing linker", $timerFile );
+            print "$HtmlResult\n";
+        }
+    }
+
+    print " Bytecode size is ", -s $bytecodeFile, " bytes.\n";
+
+    my $disassemblyFile = getname(".ll");
+    try_run( "llvm-dis",
+        "llvm-dis -o=$disassemblyFile $bytecodeFile > $outputFile 2>&1",
+        $outputFile );
+
+    if ( $c->param('cxxdemangle') ) {
+        print " Demangling disassembler output.\n";
+        my $tmpFile = getname(".ll");
+        system("c++filt < $disassemblyFile > $tmpFile 2>&1");
+        system("mv $tmpFile $disassemblyFile");
+    }
+
+    my ( $UnhilightedResult, $HtmlResult );
+    if ( -s $disassemblyFile ) {
+        ( $UnhilightedResult, $HtmlResult ) =
+          dumpFile( "Output from LLVM disassembler", $disassemblyFile );
+        print syntaxHighlightLLVM($HtmlResult);
+    }
+    else {
+        print "<p>Hmm, that's weird, llvm-dis didn't produce any output.</p>\n";
+    }
+
+    if ( $c->param('showbcanalysis') ) {
+      my $analFile = getname(".bca");
+      try_run( "llvm-bcanalyzer", "llvm-bcanalyzer $bytecodeFile > $analFile 2>&1", 
+        $analFile);
+    }
+    if ($c->param('showllvm2cpp') ) {
+      my $l2cppFile = getname(".l2cpp");
+      try_run("llvm2cpp","llvm2cpp $bytecodeFile -o $l2cppFile 2>&1",
+        $l2cppFile);
+    }
+
+    # Get the source presented by the user to CGI, convert newline sequences to simple \n.
+    my $actualsrc = $c->param('source');
+    $actualsrc =~ s/\015\012/\n/go;
+    # Don't log this or mail it if it is the default code.
+    if ($actualsrc ne $defaultsrc) {
+    addlog( $source, $pid, $UnhilightedResult );
+
+    my ( $ip, $host, $lg, $lines );
+    chomp( $lines = `wc -l < $inputFile` );
+    $lg = $c->param('language');
+    $ip = $c->remote_addr();
+    chomp( $host = `host $ip` ) if $ip;
+    mailto( $MAILADDR,
+        "--- Query: ---\nFrom: ($ip) $host\nInput: $lines lines of $lg\n"
+          . "C++ demangle = "
+          . ( $c->param('cxxdemangle') ? 1 : 0 )
+          . ", Link opt = "
+          . ( $c->param('linkopt') ? 1 : 0 ) . "\n\n"
+          . ", Show stats = "
+          . ( $c->param('showstats') ? 1 : 0 ) . "\n\n"
+          . "--- Source: ---\n$source\n"
+          . "--- Result: ---\n$UnhilightedResult\n" );
+    }
+    unlink( $inputFile, $bytecodeFile, $outputFile, $disassemblyFile );
+}
+
+print $c->hr, "<address>$CONTACT_ADDRESS</address>", $c->end_html;
+system("rm $ROOT/locked");
+exit 0;
diff --git a/www/demo/syntax.css b/www/demo/syntax.css
new file mode 100644
index 0000000..90daf5f
--- /dev/null
+++ b/www/demo/syntax.css
@@ -0,0 +1,4 @@
+/* LLVM syntax highlighting for the Web */
+
+.llvm_type    { font-style: oblique; color: green }
+.llvm_keyword { font-weight: bold; color: blue }
diff --git a/www/demo/what is this directory.txt b/www/demo/what is this directory.txt
new file mode 100644
index 0000000..a1306ac
--- /dev/null
+++ b/www/demo/what is this directory.txt
@@ -0,0 +1,15 @@
+This is for the LLVM+Clang browser based demo.
+It is supposed to work like the LLVM+GCC demo here: http://llvm.org/demo/ but for the BSD licensed Clang instead.
+
+Perhaps it could also be used for getting crash information and details on errors....  I'm not sure if this would require some major changes or not to report this info.  Maybe also adding ways that people can use it to test for errors and a way to report such errors would also be good.
+
+Status:
+Anyways, right now, these file a basically just a copy of the LLVM+GCC demo (no changes have been made).  The files don't even work right in this location on the server.  As such, someone will need to edit the file or rewrite it.
+
+If nobody in the LLVM community has the skills, one suggestion would be to post a request on a friendly Perl forum and see if anybody might be interested in taking on the challenge.
+
+Alternatively, you could try a PHP, Python, Ruby, or Lisp mailing list and see if there are any takers who would be interested (and willing to do a rewrite to their language of choice).
+
+--
+BTW, once this feature was working, my intention was to link to it from the index.html page in the section entitled:
+Try Clang
\ No newline at end of file
diff --git a/www/diagnostics.html b/www/diagnostics.html
new file mode 100644
index 0000000..4f7d025
--- /dev/null
+++ b/www/diagnostics.html
@@ -0,0 +1,349 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+          "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+  <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
+  <title>Clang - Expressive Diagnostics</title>
+  <link type="text/css" rel="stylesheet" href="menu.css" />
+  <link type="text/css" rel="stylesheet" href="content.css" />
+  <style type="text/css">
+</style>
+</head>
+<body>
+
+<!--#include virtual="menu.html.incl"-->
+
+<div id="content">
+
+
+<!--=======================================================================-->
+<h1>Expressive Diagnostics</h1>
+<!--=======================================================================-->
+
+<p>In addition to being fast and functional, we aim to make Clang extremely user
+friendly.  As far as a command-line compiler goes, this basically boils down to
+making the diagnostics (error and warning messages) generated by the compiler
+be as useful as possible.  There are several ways that we do this.  This section
+talks about the experience provided by the command line compiler, contrasting
+Clang output to GCC 4.2's output in several examples.
+<!--
+Other clients
+that embed Clang and extract equivalent information through internal APIs.-->
+</p>
+
+<h2>Column Numbers and Caret Diagnostics</h2>
+
+<p>First, all diagnostics produced by clang include full column number
+information, and use this to print "caret diagnostics".  This is a feature
+provided by many commercial compilers, but is generally missing from open source
+compilers.  This is nice because it makes it very easy to understand exactly
+what is wrong in a particular piece of code, an example is:</p>
+
+<pre>
+  $ <b>gcc-4.2 -fsyntax-only -Wformat format-strings.c</b>
+  format-strings.c:91: warning: too few arguments for format
+  $ <b>clang -fsyntax-only format-strings.c</b>
+  format-strings.c:91:13: <font color="magenta">warning:</font> '.*' specified field precision is missing a matching 'int' argument
+  <font color="darkgreen">  printf("%.*d");</font>
+  <font color="blue">            ^</font>
+</pre>
+
+<p>The caret (the blue "^" character) exactly shows where the problem is, even
+inside of the string.  This makes it really easy to jump to the problem and
+helps when multiple instances of the same character occur on a line.  We'll
+revisit this more in following examples.</p>
+
+<h2>Range Highlighting for Related Text</h2>
+
+<p>Clang captures and accurately tracks range information for expressions,
+statements, and other constructs in your program and uses this to make
+diagnostics highlight related information.  For example, here's a somewhat
+nonsensical example to illustrate this:</p>
+
+<pre>
+  $ <b>gcc-4.2 -fsyntax-only t.c</b>
+  t.c:7: error: invalid operands to binary + (have 'int' and 'struct A')
+  $ <b>clang -fsyntax-only t.c</b>
+  t.c:7:39: <font color="red">error:</font> invalid operands to binary expression ('int' and 'struct A')
+  <font color="darkgreen">  return y + func(y ? ((SomeA.X + 40) + SomeA) / 42 + SomeA.X : SomeA.X);</font>
+  <font color="blue">                       ~~~~~~~~~~~~~~ ^ ~~~~~</font>
+</pre>
+
+<p>Here you can see that you don't even need to see the original source code to
+understand what is wrong based on the Clang error: Because clang prints a
+caret, you know exactly <em>which</em> plus it is complaining about.  The range
+information highlights the left and right side of the plus which makes it
+immediately obvious what the compiler is talking about, which is very useful for
+cases involving precedence issues and many other cases.</p>
+
+<h2>Precision in Wording</h2>
+
+<p>A detail is that we have tried really hard to make the diagnostics that come
+out of clang contain exactly the pertinent information about what is wrong and
+why.  In the example above, we tell you what the inferred types are for
+the left and right hand sides, and we don't repeat what is obvious from the
+caret (that this is a "binary +").  Many other examples abound, here is a simple
+one:</p>
+
+<pre>
+  $ <b>gcc-4.2 -fsyntax-only t.c</b>
+  t.c:5: error: invalid type argument of 'unary *'
+  $ <b>clang -fsyntax-only t.c</b>
+  t.c:5:11: <font color="red">error:</font> indirection requires pointer operand ('int' invalid)
+  <font color="darkgreen">  int y = *SomeA.X;</font>
+  <font color="blue">          ^~~~~~~~</font>
+</pre>
+
+<p>In this example, not only do we tell you that there is a problem with the *
+and point to it, we say exactly why and tell you what the type is (in case it is
+a complicated subexpression, such as a call to an overloaded function).  This
+sort of attention to detail makes it much easier to understand and fix problems
+quickly.</p>
+
+<h2>No Pretty Printing of Expressions in Diagnostics</h2>
+
+<p>Since Clang has range highlighting, it never needs to pretty print your code
+back out to you.  This is particularly bad in G++ (which often emits errors
+containing lowered vtable references), but even GCC can produce
+inscrutible error messages in some cases when it tries to do this.  In this
+example P and Q have type "int*":</p>
+
+<pre>
+  $ <b>gcc-4.2 -fsyntax-only t.c</b>
+  #'exact_div_expr' not supported by pp_c_expression#'t.c:12: error: called object  is not a function
+  $ <b>clang -fsyntax-only t.c</b>
+  t.c:12:8: <font color="red">error:</font> called object type 'int' is not a function or function pointer
+  <font color="darkgreen">  (P-Q)();</font>
+  <font color="blue">  ~~~~~^</font>
+</pre>
+
+
+<h2>Typedef Preservation and Selective Unwrapping</h2>
+
+<p>Many programmers use high-level user defined types, typedefs, and other
+syntactic sugar to refer to types in their program.  This is useful because they
+can abbreviate otherwise very long types and it is useful to preserve the
+typename in diagnostics.  However, sometimes very simple typedefs can wrap
+trivial types and it is important to strip off the typedef to understand what
+is going on.  Clang aims to handle both cases well.<p>
+
+<p>For example, here is an example that shows where it is important to preserve
+a typedef in C:</p>
+
+<pre>
+  $ <b>gcc-4.2 -fsyntax-only t.c</b>
+  t.c:15: error: invalid operands to binary / (have 'float __vector__' and 'const int *')
+  $ <b>clang -fsyntax-only t.c</b>
+  t.c:15:11: <font color="red">error:</font> can't convert between vector values of different size ('__m128' and 'int const *')
+  <font color="darkgreen">  myvec[1]/P;</font>
+  <font color="blue">  ~~~~~~~~^~</font>
+</pre>
+
+<p>Here the type printed by GCC isn't even valid, but if the error were about a
+very long and complicated type (as often happens in C++) the error message would
+be ugly just because it was long and hard to read.  Here's an example where it
+is useful for the compiler to expose underlying details of a typedef:</p>
+
+<pre>
+  $ <b>gcc-4.2 -fsyntax-only t.c</b>
+  t.c:13: error: request for member 'x' in something not a structure or union
+  $ <b>clang -fsyntax-only t.c</b>
+  t.c:13:9: <font color="red">error:</font> member reference base type 'pid_t' (aka 'int') is not a structure or union
+  <font color="darkgreen">  myvar = myvar.x;</font>
+  <font color="blue">          ~~~~~ ^</font>
+</pre>
+
+<p>If the user was somehow confused about how the system "pid_t" typedef is
+defined, Clang helpfully displays it with "aka".</p>
+
+<p>In C++, type preservation includes retaining any qualification written into type names. For example, if we take a small snippet of code such as:
+
+<blockquote>
+<pre>
+namespace services {
+  struct WebService {  };
+}
+namespace myapp {
+  namespace servers {
+    struct Server {  };
+  }
+}
+
+using namespace myapp;
+void addHTTPService(servers::Server const &server, ::services::WebService const *http) {
+  server += http;
+}
+</pre>
+</blockquote>
+
+<p>and then compile it, we see that Clang is both providing more accurate information and is retaining the types as written by the user (e.g., "servers::Server", "::services::WebService"):
+
+<pre>
+  $ <b>g++-4.2 -fsyntax-only t.cpp</b>
+  t.cpp:9: error: no match for 'operator+=' in 'server += http'
+  $ <b>clang -fsyntax-only t.cpp</b>
+  t.cpp:9:10: <font color="red">error:</font> invalid operands to binary expression ('servers::Server const' and '::services::WebService const *')
+    <font color="darkgreen">server += http;</font>
+    <font color="blue">~~~~~~ ^  ~~~~</font>
+</pre>
+
+<p>Naturally, type preservation extends to uses of templates, and Clang retains information about how a particular template specialization (like <code>std::vector&lt;Real&gt;</code>) was spelled within the source code. For example:</p>
+
+<pre>
+  $ <b>g++-4.2 -fsyntax-only t.cpp</b>
+  t.cpp:12: error: no match for 'operator=' in 'str = vec'
+  $ <b>clang -fsyntax-only t.cpp</b>
+  t.cpp:12:7: <font color="red">error:</font> incompatible type assigning 'vector&lt;Real&gt;', expected 'std::string' (aka 'class std::basic_string&lt;char&gt;')
+    <font color="darkgreen">str = vec</font>;
+        <font color="blue">^ ~~~</font>
+</pre>
+
+<h2>Fix-it Hints</h2>
+
+<p>"Fix-it" hints provide advice for fixing small, localized problems
+in source code. When Clang produces a diagnostic about a particular
+problem that it can work around (e.g., non-standard or redundant
+syntax, missing keywords, common mistakes, etc.), it may also provide
+specific guidance in the form of a code transformation to correct the
+problem. For example, here Clang warns about the use of a GCC
+extension that has been considered obsolete since 1993:</p>
+
+<pre>
+  $ <b>clang t.c</b>
+  t.c:5:28: <font color="magenta">warning:</font> use of GNU old-style field designator extension
+  <font color="darkgreen">struct point origin = { x: 0.0, y: 0.0 };</font>
+                          <font color="red">~~</font> <font color="blue">^</font>
+                          <font color="darkgreen">.x = </font>
+  t.c:5:36: <font color="magenta">warning:</font> use of GNU old-style field designator extension
+  <font color="darkgreen">struct point origin = { x: 0.0, y: 0.0 };</font>
+                                  <font color="red">~~</font> <font color="blue">^</font>
+                                  <font color="darkgreen">.y = </font>
+</pre>
+
+<p>The underlined code should be removed, then replaced with the code below the
+caret line (".x =" or ".y =", respectively). "Fix-it" hints are most useful for
+working around common user errors and misconceptions. For example, C++ users
+commonly forget the syntax for explicit specialization of class templates,
+as in the following error:</p>
+
+<pre>
+  $ <b>clang t.cpp</b>
+  t.cpp:9:3: <font color="red">error:</font> template specialization requires 'template&lt;&gt;'
+    struct iterator_traits&lt;file_iterator&gt; {
+    <font color="blue">^</font>
+    <font color="darkgreen">template&lt;&gt; </font>
+</pre>
+
+<p>Again, after describing the problem, Clang provides the fix--add <code>template&lt;&gt;</code>--as part of the diagnostic.<p>
+
+<h2>Automatic Macro Expansion</h2>
+
+<p>Many errors happen in macros that are sometimes deeply nested.  With
+traditional compilers, you need to dig deep into the definition of the macro to
+understand how you got into trouble.  Here's a simple example that shows how
+Clang helps you out:</p>
+
+<pre>
+  $ <b>gcc-4.2 -fsyntax-only t.c</b>
+  t.c: In function 'test':
+  t.c:80: error: invalid operands to binary &lt; (have 'struct mystruct' and 'float')
+  $ <b>clang -fsyntax-only t.c</b>
+  t.c:80:3: <font color="red">error:</font> invalid operands to binary expression ('typeof(P)' (aka 'struct mystruct') and 'typeof(F)' (aka 'float'))
+  <font color="darkgreen">  X = MYMAX(P, F);</font>
+  <font color="blue">      ^~~~~~~~~~~</font>
+  t.c:76:94: note: instantiated from:
+  <font color="darkgreen">#define MYMAX(A,B)    __extension__ ({ __typeof__(A) __a = (A); __typeof__(B) __b = (B); __a &lt; __b ? __b : __a; })</font>
+  <font color="blue">                                                                                         ~~~ ^ ~~~</font>
+</pre>
+
+<p>This shows how clang automatically prints instantiation information and
+nested range information for diagnostics as they are instantiated through macros
+and also shows how some of the other pieces work in a bigger example.  Here's
+another real world warning that occurs in the "window" Unix package (which
+implements the "wwopen" class of APIs):</p>
+
+<pre>
+  $ <b>clang -fsyntax-only t.c</b>
+  t.c:22:2: <font color="magenta">warning:</font> type specifier missing, defaults to 'int'
+  <font color="darkgreen">        ILPAD();</font>
+  <font color="blue">        ^</font>
+  t.c:17:17: note: instantiated from:
+  <font color="darkgreen">#define ILPAD() PAD((NROW - tt.tt_row) * 10)    /* 1 ms per char */</font>
+  <font color="blue">                ^</font>
+  t.c:14:2: note: instantiated from:
+  <font color="darkgreen">        register i; \</font>
+  <font color="blue">        ^</font>
+</pre>
+
+<p>In practice, we've found that this is actually more useful in multiply nested
+macros that in simple ones.</p>
+
+<h2>Quality of Implementation and Attention to Detail</h2>
+
+<p>Finally, we have put a lot of work polishing the little things, because
+little things add up over time and contribute to a great user experience.  Three
+examples are:</p>
+
+<pre>
+  $ <b>gcc-4.2 t.c</b>
+  t.c: In function 'foo':
+  t.c:5: error: expected ';' before '}' token
+  $ <b>clang t.c</b>
+  t.c:4:8: <font color="red">error:</font> expected ';' after expression
+  <font color="darkgreen">  bar()</font>
+  <font color="blue">       ^</font>
+  <font color="blue">       ;</font>
+</pre>
+
+<p>This shows a trivial little tweak, where we tell you to put the semicolon at
+the end of the line that is missing it (line 4) instead of at the beginning of
+the following line (line 5).  This is particularly important with fixit hints
+and caret diagnostics, because otherwise you don't get the important context.
+</p>
+
+<pre>
+  $ <b>gcc-4.2 t.c</b>
+  t.c:3: error: expected '=', ',', ';', 'asm' or '__attribute__' before '*' token
+  $ <b>clang t.c</b>
+  t.c:3:1: <font color="red">error:</font> unknown type name 'foo_t'
+  <font color="darkgreen">foo_t *P = 0;</font>
+  <font color="blue">^</font>
+</pre>
+
+<p>This shows an example of much better error recovery.  The message coming out
+of GCC is completely useless for diagnosing the problem, Clang tries much harder
+and produces a much more useful diagnosis of the problem.</p>
+
+<pre>
+  $ <b>cat t.cc</b>
+  template&lt;class T&gt;
+  class a {}
+  class temp {};
+  a&lt;temp&gt; b;
+  struct b {
+  }
+  $ <b>gcc-4.2 t.cc</b>
+  t.cc:3: error: multiple types in one declaration
+  t.cc:4: error: non-template type 'a' used as a template
+  t.cc:4: error: invalid type in declaration before ';' token
+  t.cc:6: error: expected unqualified-id at end of input
+  $ <b>clang t.cc</b>
+  t.cc:2:11: <font color="red">error:</font> expected ';' after class
+  <font color="darkgreen">class a {}</font>
+  <font color="blue">          ^</font>
+  <font color="blue">          ;</font>
+  t.cc:6:2: <font color="red">error:</font> expected ';' after struct
+  <font color="darkgreen">}</font>
+  <font color="blue"> ^</font>
+  <font color="blue"> ;</font>
+</pre>
+
+<p>This shows that we recover from the simple case of forgetting a ; after
+a struct definition much better than GCC.</p>
+
+<p>While each of these details is minor, we feel that they all add up to provide
+a much more polished experience.</p>
+
+</div>
+</body>
+</html>
diff --git a/www/distclang_status.html b/www/distclang_status.html
new file mode 100644
index 0000000..26ba314
--- /dev/null
+++ b/www/distclang_status.html
@@ -0,0 +1,30 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+          "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+  <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
+  <title>Clang - Distributed Compilation Support</title>
+  <link type="text/css" rel="stylesheet" href="menu.css" />
+  <link type="text/css" rel="stylesheet" href="content.css" />
+  <style type="text/css">
+</style>
+</head>
+<body>
+
+<!--#include virtual="menu.html.incl"-->
+
+<div id="content">
+
+<!--*************************************************************************-->
+<h1>Distributed Compilation Support in Clang</h1>
+<!--*************************************************************************-->
+
+<p>
+This page tracks the status of Distributed Compilation support in Clang.<br>
+Currently some basic features are working but the code is under heavy
+development. </p>
+
+
+</div>
+</body>
+</html>
diff --git a/www/feature-compile1.png b/www/feature-compile1.png
new file mode 100644
index 0000000..cec7c48
--- /dev/null
+++ b/www/feature-compile1.png
Binary files differ
diff --git a/www/feature-compile2.png b/www/feature-compile2.png
new file mode 100644
index 0000000..0eb9300
--- /dev/null
+++ b/www/feature-compile2.png
Binary files differ
diff --git a/www/feature-memory1.png b/www/feature-memory1.png
new file mode 100644
index 0000000..29368aa
--- /dev/null
+++ b/www/feature-memory1.png
Binary files differ
diff --git a/www/features.html b/www/features.html
new file mode 100644
index 0000000..6034ae7
--- /dev/null
+++ b/www/features.html
@@ -0,0 +1,424 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+          "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+  <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
+  <title>Clang - Features and Goals</title>
+  <link type="text/css" rel="stylesheet" href="menu.css" />
+  <link type="text/css" rel="stylesheet" href="content.css" />
+  <style type="text/css">
+</style>
+</head>
+<body>
+
+<!--#include virtual="menu.html.incl"-->
+
+<div id="content">
+
+<!--*************************************************************************-->
+<h1>Clang - Features and Goals</h1>
+<!--*************************************************************************-->
+
+<p>
+This page describes the <a href="index.html#goals">features and goals</a> of
+Clang in more detail and gives a more broad explanation about what we mean.
+These features are:
+</p>
+
+<p>End-User Features:</p>
+
+<ul>
+<li><a href="#performance">Fast compiles and low memory use</a></li>
+<li><a href="#expressivediags">Expressive diagnostics</a></li>
+<li><a href="#gcccompat">GCC compatibility</a></li>
+</ul>
+
+<p>Utility and Applications:</p>
+
+<ul>
+<li><a href="#libraryarch">Library based architecture</a></li>
+<li><a href="#diverseclients">Support diverse clients</a></li>
+<li><a href="#ideintegration">Integration with IDEs</a></li>
+<li><a href="#license">Use the LLVM 'BSD' License</a></li>
+</ul>
+
+<p>Internal Design and Implementation:</p>
+
+<ul>
+<li><a href="#real">A real-world, production quality compiler</a></li>
+<li><a href="#simplecode">A simple and hackable code base</a></li>
+<li><a href="#unifiedparser">A single unified parser for C, Objective C, C++,
+    and Objective C++</a></li>
+<li><a href="#conformance">Conformance with C/C++/ObjC and their
+    variants</a></li>
+</ul>
+
+<!--*************************************************************************-->
+<h2><a name="enduser">End-User Features</a></h2>
+<!--*************************************************************************-->
+
+
+<!--=======================================================================-->
+<h3><a name="performance">Fast compiles and Low Memory Use</a></h3>
+<!--=======================================================================-->
+
+<p>A major focus of our work on clang is to make it fast, light and scalable.
+The library-based architecture of clang makes it straight-forward to time and
+profile the cost of each layer of the stack, and the driver has a number of
+options for performance analysis.</p>
+
+<p>While there is still much that can be done, we find that the clang front-end
+is significantly quicker than gcc and uses less memory  For example, when
+compiling "Carbon.h" on Mac OS/X, we see that clang is 2.5x faster than GCC:</p>
+
+<img class="img_slide" src="feature-compile1.png" width="400" height="300" />
+
+<p>Carbon.h is a monster: it transitively includes 558 files, 12.3M of code,
+declares 10000 functions, has 2000 struct definitions, 8000 fields, 20000 enum
+constants, etc (see slide 25+ of the <a href="clang_video-07-25-2007.html">clang 
+talk</a> for more information). It is also #include'd into almost every C file
+in a GUI app on the Mac, so its compile time is very important.</p>
+
+<p>From the slide above, you can see that we can measure the time to preprocess
+the file independently from the time to parse it, and independently from the
+time to build the ASTs for the code.  GCC doesn't provide a way to measure the
+parser without AST building (it only provides -fsyntax-only).  In our
+measurements, we find that clang's preprocessor is consistently 40% faster than
+GCCs, and the parser + AST builder is ~4x faster than GCC's.  If you have
+sources that do not depend as heavily on the preprocessor (or if you 
+use Precompiled Headers) you may see a much bigger speedup from clang.
+</p>
+
+<p>Compile time performance is important, but when using clang as an API, often
+memory use is even moreso: the less memory the code takes the more code you can
+fit into memory at a time (useful for whole program analysis tools, for
+example).</p>
+
+<img class="img_slide" src="feature-memory1.png" width="400" height="300" />
+
+<p>Here we see a huge advantage of clang: its ASTs take <b>5x less memory</b>
+than GCC's syntax trees, despite the fact that clang's ASTs capture far more 
+source-level information than GCC's trees do.  This feat is accomplished through
+the use of carefully designed APIs and efficient representations.</p>
+
+<p>In addition to being efficient when pitted head-to-head against GCC in batch
+mode, clang is built with a <a href="#libraryarch">library based 
+architecture</a> that makes it relatively easy to adapt it and build new tools
+with it.  This means that it is often possible to apply out-of-the-box thinking
+and novel techniques to improve compilation in various ways.</p> 
+  
+<img class="img_slide" src="feature-compile2.png" width="400" height="300" />
+
+<p>This slide shows how the clang preprocessor can be used to make "distcc"
+parallelization <b>3x</b> more scalable than when using the GCC preprocessor.
+"distcc" quickly bottlenecks on the preprocessor running on the central driver
+machine, so a fast preprocessor is very useful.  Comparing the first two bars
+of each group shows how a ~40% faster preprocessor can reduce preprocessing time
+of these large C++ apps by about 40% (shocking!).</p>
+
+<p>The third bar on the slide is the interesting part: it shows how trivial
+caching of file system accesses across invocations of the preprocessor allows 
+clang to reduce time spent in the kernel by 10x, making distcc over 3x more
+scalable.  This is obviously just one simple hack, doing more interesting things
+(like caching tokens across preprocessed files) would yield another substantial
+speedup.</p>
+
+<p>The clean framework-based design of clang means that many things are possible
+that would be very difficult in other systems, for example incremental
+compilation, multithreading, intelligent caching, etc.  We are only starting
+to tap the full potential of the clang design.</p>
+
+
+<!--=======================================================================-->
+<h3><a name="expressivediags">Expressive Diagnostics</a></h3>
+<!--=======================================================================-->
+
+<p>In addition to being fast and functional, we aim to make Clang extremely user
+friendly.  As far as a command-line compiler goes, this basically boils down to
+making the diagnostics (error and warning messages) generated by the compiler
+be as useful as possible.  There are several ways that we do this, but the
+most important are pinpointing exactly what is wrong in the program,
+highlighting related information so that it is easy to understand at a glance,
+and making the wording as clear as possible.</p>
+
+<p>Here is one simple example that illustrates the difference between a typical
+GCC and Clang diagnostic:</p>
+
+<pre>
+  $ <b>gcc-4.2 -fsyntax-only t.c</b>
+  t.c:7: error: invalid operands to binary + (have 'int' and 'struct A')
+  $ <b>clang -fsyntax-only t.c</b>
+  t.c:7:39: error: invalid operands to binary expression ('int' and 'struct A')
+  <font color="darkgreen">  return y + func(y ? ((SomeA.X + 40) + SomeA) / 42 + SomeA.X : SomeA.X);</font>
+  <font color="blue">                       ~~~~~~~~~~~~~~ ^ ~~~~~</font>
+</pre>
+
+<p>Here you can see that you don't even need to see the original source code to
+understand what is wrong based on the Clang error: Because clang prints a
+caret, you know exactly <em>which</em> plus it is complaining about.  The range
+information highlights the left and right side of the plus which makes it
+immediately obvious what the compiler is talking about, which is very useful for
+cases involving precedence issues and many other situations.</p>
+
+<p>Clang diagnostics are very polished and have many features.  For more 
+information and examples, please see the <a href="diagnostics.html">Expressive
+Diagnostics</a> page.</p>
+
+<!--=======================================================================-->
+<h3><a name="gcccompat">GCC Compatibility</a></h3>
+<!--=======================================================================-->
+
+<p>GCC is currently the defacto-standard open source compiler today, and it
+routinely compiles a huge volume of code.  GCC supports a huge number of
+extensions and features (many of which are undocumented) and a lot of 
+code and header files depend on these features in order to build.</p>
+
+<p>While it would be nice to be able to ignore these extensions and focus on
+implementing the language standards to the letter, pragmatics force us to
+support the GCC extensions that see the most use.  Many users just want their
+code to compile, they don't care to argue about whether it is pedantically C99
+or not.</p>
+
+<p>As mentioned above, all
+extensions are explicitly recognized as such and marked with extension
+diagnostics, which can be mapped to warnings, errors, or just ignored.
+</p>
+
+
+<!--*************************************************************************-->
+<h2><a name="applications">Utility and Applications</a></h2>
+<!--*************************************************************************-->
+
+<!--=======================================================================-->
+<h3><a name="libraryarch">Library Based Architecture</a></h3>
+<!--=======================================================================-->
+
+<p>A major design concept for clang is its use of a library-based
+architecture.  In this design, various parts of the front-end can be cleanly
+divided into separate libraries which can then be mixed up for different needs
+and uses.  In addition, the library-based approach encourages good interfaces
+and makes it easier for new developers to get involved (because they only need
+to understand small pieces of the big picture).</p>
+
+<blockquote>
+"The world needs better compiler tools, tools which are built as libraries.
+This design point allows reuse of the tools in new and novel ways. However,
+building the tools as libraries isn't enough: they must have clean APIs, be as
+decoupled from each other as possible, and be easy to modify/extend. This
+requires clean layering, decent design, and keeping the libraries independent of
+any specific client."</blockquote>
+
+<p>
+Currently, clang is divided into the following libraries and tool:
+</p>
+
+<ul>
+<li><b>libsupport</b> - Basic support library, from LLVM.</li>
+<li><b>libsystem</b> - System abstraction library, from LLVM.</li>
+<li><b>libbasic</b> - Diagnostics, SourceLocations, SourceBuffer abstraction,
+    file system caching for input source files.</li>
+<li><b>libast</b> - Provides classes to represent the C AST, the C type system,
+    builtin functions, and various helpers for analyzing and manipulating the
+    AST (visitors, pretty printers, etc).</li>
+<li><b>liblex</b> - Lexing and preprocessing, identifier hash table, pragma
+    handling, tokens, and macro expansion.</li>
+<li><b>libparse</b> - Parsing. This library invokes coarse-grained 'Actions'
+    provided by the client (e.g. libsema builds ASTs) but knows nothing about
+    ASTs or other client-specific data structures.</li>
+<li><b>libsema</b> - Semantic Analysis.  This provides a set of parser actions
+    to build a standardized AST for programs.</li>
+<li><b>libcodegen</b> - Lower the AST to LLVM IR for optimization &amp; code
+    generation.</li>
+<li><b>librewrite</b> - Editing of text buffers (important for code rewriting
+    transformation, like refactoring).</li>
+<li><b>libanalysis</b> - Static analysis support.</li>
+<li><b><a href="docs/libIndex.html">libindex</a></b> - Cross-translation-unit infrastructure and indexing support.</li>
+<li><b>clang</b> - A driver program, client of the libraries at various
+    levels.</li>
+</ul>
+
+<p>As an example of the power of this library based design....  If you wanted to
+build a preprocessor, you would take the Basic and Lexer libraries. If you want
+an indexer, you would take the previous two and add the Parser library and
+some actions for indexing. If you want a refactoring, static analysis, or
+source-to-source compiler tool, you would then add the AST building and
+semantic analyzer libraries.</p>
+
+<p>For more information about the low-level implementation details of the
+various clang libraries, please see the <a href="docs/InternalsManual.html">
+clang Internals Manual</a>.</p>
+
+<!--=======================================================================-->
+<h3><a name="diverseclients">Support Diverse Clients</a></h3>
+<!--=======================================================================-->
+
+<p>Clang is designed and built with many grand plans for how we can use it.  The
+driving force is the fact that we use C and C++ daily, and have to suffer due to
+a lack of good tools available for it.  We believe that the C and C++ tools
+ecosystem has been significantly limited by how difficult it is to parse and
+represent the source code for these languages, and we aim to rectify this
+problem in clang.</p>
+
+<p>The problem with this goal is that different clients have very different
+requirements.  Consider code generation, for example: a simple front-end that
+parses for code generation must analyze the code for validity and emit code
+in some intermediate form to pass off to a optimizer or backend.  Because
+validity analysis and code generation can largely be done on the fly, there is
+not hard requirement that the front-end actually build up a full AST for all
+the expressions and statements in the code.  TCC and GCC are examples of
+compilers that either build no real AST (in the former case) or build a stripped
+down and simplified AST (in the later case) because they focus primarily on
+codegen.</p>
+
+<p>On the opposite side of the spectrum, some clients (like refactoring) want
+highly detailed information about the original source code and want a complete
+AST to describe it with.  Refactoring wants to have information about macro
+expansions, the location of every paren expression '(((x)))' vs 'x', full
+position information, and much more.  Further, refactoring wants to look
+<em>across the whole program</em> to ensure that it is making transformations
+that are safe.  Making this efficient and getting this right requires a
+significant amount of engineering and algorithmic work that simply are
+unnecessary for a simple static compiler.</p>
+
+<p>The beauty of the clang approach is that it does not restrict how you use it.
+In particular, it is possible to use the clang preprocessor and parser to build
+an extremely quick and light-weight on-the-fly code generator (similar to TCC)
+that does not build an AST at all.   As an intermediate step, clang supports
+using the current AST generation and semantic analysis code and having a code 
+generation client free the AST for each function after code generation. Finally,
+clang provides support for building and retaining fully-fledged ASTs, and even
+supports writing them out to disk.</p>
+
+<p>Designing the libraries with clean and simple APIs allows these high-level
+policy decisions to be determined in the client, instead of forcing "one true
+way" in the implementation of any of these libraries.  Getting this right is
+hard, and we don't always get it right the first time, but we fix any problems
+when we realize we made a mistake.</p>
+
+<!--=======================================================================-->
+<h3><a name="ideintegration">Integration with IDEs</h3>
+<!--=======================================================================-->
+
+<p>
+We believe that Integrated Development Environments (IDE's) are a great way
+to pull together various pieces of the development puzzle, and aim to make clang
+work well in such an environment.  The chief advantage of an IDE is that they
+typically have visibility across your entire project and are long-lived
+processes, whereas stand-alone compiler tools are typically invoked on each
+individual file in the project, and thus have limited scope.</p>
+
+<p>There are many implications of this difference, but a significant one has to
+do with efficiency and caching: sharing an address space across different files
+in a project, means that you can use intelligent caching and other techniques to
+dramatically reduce analysis/compilation time.</p>
+
+<p>A further difference between IDEs and batch compiler is that they often
+impose very different requirements on the front-end: they depend on high
+performance in order to provide a "snappy" experience, and thus really want
+techniques like "incremental compilation", "fuzzy parsing", etc.  Finally, IDEs
+often have very different requirements than code generation, often requiring
+information that a codegen-only frontend can throw away.  Clang is
+specifically designed and built to capture this information.
+</p>
+
+
+<!--=======================================================================-->
+<h3><a name="license">Use the LLVM 'BSD' License</a></h3>
+<!--=======================================================================-->
+
+<p>We actively indend for clang (and a LLVM as a whole) to be used for
+commercial projects, and the BSD license is the simplest way to allow this.  We
+feel that the license encourages contributors to pick up the source and work
+with it, and believe that those individuals and organizations will contribute
+back their work if they do not want to have to maintain a fork forever (which is
+time consuming and expensive when merges are involved).  Further, nobody makes
+money on compilers these days, but many people need them to get bigger goals
+accomplished: it makes sense for everyone to work together.</p>
+
+<p>For more information about the LLVM/clang license, please see the <a 
+href="http://llvm.org/docs/DeveloperPolicy.html#license">LLVM License 
+Description</a> for more information.</p>
+
+
+
+<!--*************************************************************************-->
+<h2><a name="design">Internal Design and Implementation</a></h2>
+<!--*************************************************************************-->
+
+<!--=======================================================================-->
+<h3><a name="real">A real-world, production quality compiler</a></h3>
+<!--=======================================================================-->
+
+<p>
+Clang is designed and built by experienced compiler developers who
+are increasingly frustrated with the problems that <a 
+href="comparison.html">existing open source compilers</a> have.  Clang is
+carefully and thoughtfully designed and built to provide the foundation of a
+whole new generation of C/C++/Objective C development tools, and we intend for
+it to be production quality.</p>
+
+<p>Being a production quality compiler means many things: it means being high
+performance, being solid and (relatively) bug free, and it means eventually
+being used and depended on by a broad range of people.  While we are still in
+the early development stages, we strongly believe that this will become a
+reality.</p>
+
+<!--=======================================================================-->
+<h3><a name="simplecode">A simple and hackable code base</a></h3>
+<!--=======================================================================-->
+
+<p>Our goal is to make it possible for anyone with a basic understanding
+of compilers and working knowledge of the C/C++/ObjC languages to understand and
+extend the clang source base.  A large part of this falls out of our decision to
+make the AST mirror the languages as closely as possible: you have your friendly
+if statement, for statement, parenthesis expression, structs, unions, etc, all
+represented in a simple and explicit way.</p>
+
+<p>In addition to a simple design, we work to make the source base approachable
+by commenting it well, including citations of the language standards where
+appropriate, and designing the code for simplicity.  Beyond that, clang offers
+a set of AST dumpers, printers, and visualizers that make it easy to put code in
+and see how it is represented.</p>
+
+<!--=======================================================================-->
+<h3><a name="unifiedparser">A single unified parser for C, Objective C, C++,
+and Objective C++</a></h3>
+<!--=======================================================================-->
+
+<p>Clang is the "C Language Family Front-end", which means we intend to support
+the most popular members of the C family.  We are convinced that the right
+parsing technology for this class of languages is a hand-built recursive-descent
+parser.  Because it is plain C++ code, recursive descent makes it very easy for
+new developers to understand the code, it easily supports ad-hoc rules and other
+strange hacks required by C/C++, and makes it straight-forward to implement
+excellent diagnostics and error recovery.</p>
+
+<p>We believe that implementing C/C++/ObjC in a single unified parser makes the
+end result easier to maintain and evolve than maintaining a separate C and C++
+parser which must be bugfixed and maintained independently of each other.</p>
+
+<!--=======================================================================-->
+<h3><a name="conformance">Conformance with C/C++/ObjC and their
+ variants</a></h3>
+<!--=======================================================================-->
+
+<p>When you start work on implementing a language, you find out that there is a
+huge gap between how the language works and how most people understand it to
+work.  This gap is the difference between a normal programmer and a (scary?
+super-natural?) "language lawyer", who knows the ins and outs of the language
+and can grok standardese with ease.</p>
+
+<p>In practice, being conformant with the languages means that we aim to support
+the full language, including the dark and dusty corners (like trigraphs,
+preprocessor arcana, C99 VLAs, etc).  Where we support extensions above and
+beyond what the standard officially allows, we make an effort to explicitly call
+this out in the code and emit warnings about it (which are disabled by default,
+but can optionally be mapped to either warnings or errors), allowing you to use
+clang in "strict" mode if you desire.</p>
+
+<p>We also intend to support "dialects" of these languages, such as C89, K&amp;R
+C, C++'03, Objective-C 2, etc.</p>
+
+</div>
+</body>
+</html>
diff --git a/www/get_involved.html b/www/get_involved.html
new file mode 100644
index 0000000..a383d70
--- /dev/null
+++ b/www/get_involved.html
@@ -0,0 +1,61 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+          "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+  <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
+  <title>Clang - Get Involved</title>
+  <link type="text/css" rel="stylesheet" href="menu.css" />
+  <link type="text/css" rel="stylesheet" href="content.css" />
+</head>
+<body>
+
+<!--#include virtual="menu.html.incl"-->
+
+<div id="content">
+
+<h1>Getting Involved with the Clang Project</h1>
+
+<p>Once you have <a href="get_started.html">checked out and built</a> clang and
+played around with it, you might be wondering what you can do to make it better
+and contribute to its development.  Alternatively, maybe you just want to follow
+the development of the project to see it progress.
+</p>
+
+<h2>Follow what's going on</h2>
+
+<p>Clang is a subproject of the <a href="http://llvm.org">LLVM Project</a>, but
+has its own mailing lists because the communities have people with different
+interests.  The two clang lists are:</p>
+
+<ul>
+<li><a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits">cfe-commits
+</a> - This list is for patch submission/discussion.</li>
+
+<li><a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev">cfe-dev</a> - 
+This list is for everything else clang related (questions and answers, bug
+reports, etc).</li>
+
+</ul>
+
+<p>If you are interested in clang only, these two lists should be all
+you need.  If you are interested in the LLVM optimizer and code generator,
+please consider signing up for <a 
+href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev">llvmdev</a> and <a
+href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits">llvm-commits</a>
+as well.</p>
+
+
+<p>The best way to talk with other developers on the project is through the <a
+href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev">cfe-dev mailing
+list</a>.  The clang mailing list is a very friendly place and we welcome
+newcomers.  In addition to the cfe-dev list, a significant amount of design
+discussion takes place on the <a 
+href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits">cfe-commits mailing
+list</a>.  All of these lists have archives, so you can browse through previous
+discussions or follow the list development on the web if you prefer.</p>
+
+<p>If you're looking for something to work on, check out our <a href="OpenProjects.html">Open Projects</a> page or go look through the <a href="http://llvm.org/bugs/">Bugzilla bug database.</p>
+
+</div>
+</body>
+</html>
diff --git a/www/get_started.html b/www/get_started.html
new file mode 100644
index 0000000..141698f
--- /dev/null
+++ b/www/get_started.html
@@ -0,0 +1,270 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+          "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+  <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
+  <title>Clang - Getting Started</title>
+  <link type="text/css" rel="stylesheet" href="menu.css" />
+  <link type="text/css" rel="stylesheet" href="content.css" />
+</head>
+<body>
+
+<!--#include virtual="menu.html.incl"-->
+
+<div id="content">
+
+<h1>Getting Started: Building and Running Clang</h1>
+
+<p>This page gives you the shortest path to checking out Clang and demos a few
+options.  This should get you up and running with the minimum of muss and fuss.
+If you like what you see, please consider <a href="get_involved.html">getting
+involved</a> with the Clang community.  If you run into problems, please file
+bugs in <a href="http://llvm.org/bugs/">LLVM Bugzilla</a> or bring up the issue
+on the
+<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev">Clang development 
+mailing list</a>.</p>
+
+<h2 id="build">Building Clang and Working with the Code</h2>
+
+<h3 id="buildNix">On Unix-like Systems</h3>
+
+<p>If you would like to check out and build Clang, the current procedure is as
+follows:</p>
+
+<ol>
+  <li>Get the required tools.
+  <ul>
+    <li>See
+      <a href="http://llvm.org/docs/GettingStarted.html#requirements">
+      Getting Started with the LLVM System - Requirements</a>.</li>
+    <li>Note also that Python is needed for running the test suite.
+      Get it at: <a href="http://www.python.org/download">
+      http://www.python.org/download</a></li>
+  </ul>
+
+  <li>Checkout LLVM:</li>
+  <ul>
+    <li>Change directory to where you want the llvm directory placed.</li>
+    <li><tt>svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm</tt></li>
+  </ul>
+  <li>Checkout Clang:</li>
+  <ul>
+    <li><tt>cd llvm/tools</tt>
+    <li><tt>svn co http://llvm.org/svn/llvm-project/cfe/trunk clang</tt></li>
+  </ul>
+  <li>Build LLVM and Clang:</li>
+  <ul>
+    <li><tt>cd ..</tt>  (back to llvm)</li>
+    <li><tt>./configure</tt></li>
+    <li><tt>make</tt></li>
+    <li>This builds both LLVM and Clang for debug mode.</li>
+    <li>Note: For subsequent Clang development, you can just do make at the
+    clang directory level.</li>
+  </ul>
+  <li>If you intend to work on Clang C++ support, you may need to tell it how
+      to find your C++ standard library headers.  If Clang cannot find your 
+      system libstdc++ headers, please follow these instructions:</li>
+  <ul>
+    <li>'<tt>gcc -v -x c++ /dev/null -fsyntax-only</tt>' to get the
+    path.</li>
+    <li>Look for the comment "FIXME: temporary hack:
+    hard-coded paths" in <tt>clang/lib/Frontend/InitHeaderSearch.cpp</tt> and
+    change the lines below to include that path.</li>
+  </ul>
+  <li>Try it out (assuming you add llvm/Debug/bin to your path):</li>
+  <ul>
+    <li><tt>clang --help</tt></li>
+    <li><tt>clang file.c -fsyntax-only</tt> (check for correctness)</li>
+    <li><tt>clang file.c -S -emit-llvm -o -</tt> (print out unoptimized llvm code)</li>
+    <li><tt>clang file.c -S -emit-llvm -o - -O3</tt></li>
+    <li><tt>clang file.c -S -O3 -o -</tt> (output native machine code)</li>
+  </ul>
+</ol>
+
+<p>Note that the C front-end uses LLVM, but does not depend on llvm-gcc. If you
+encounter problems with building Clang, make sure you have the latest SVN
+version of LLVM. LLVM contains support libraries for Clang that will be updated
+as well as development on Clang progresses.</p>
+  
+<h3>Simultaneously Building Clang and LLVM:</h3>
+
+<p>Once you have checked out Clang into the llvm source tree it will build along
+with the rest of <tt>llvm</tt>. To build all of LLVM and Clang together all at
+once simply run <tt>make</tt> from the root LLVM directory.</p>
+    
+<p><em>Note:</em> Observe that Clang is technically part of a separate
+Subversion repository. As mentioned above, the latest Clang sources are tied to
+the latest sources in the LLVM tree. You can update your toplevel LLVM project
+and all (possibly unrelated) projects inside it with <tt><b>make
+update</b></tt>. This will run <tt>svn update</tt> on all subdirectories related
+to subversion. </p>
+
+<h3 id="buildWindows">Using Visual Studio</h3>
+
+<p>The following details setting up for and building Clang on Windows using
+Visual Studio:</p>
+
+<ol>
+  <li>Get the required tools:</li>
+  <ul>
+    <li><b>Subversion</b>.  Source code control program.  Get it from:
+        <a href="http://subversion.tigris.org/getting.html">
+        http://subversion.tigris.org/getting.html</a></li>
+    <li><b>cmake</b>.  This is used for generating Visual Studio solution and
+        project files.  Get it from:
+        <a href="http://www.cmake.org/cmake/resources/software.html">
+        http://www.cmake.org/cmake/resources/software.html</a></li>
+    <li><b>Visual Studio 2005 or 2008</b></li>
+    <li><b>Python</b>.  This is needed only if you will be running the tests
+        (which is essential, if you will be developing for clang).
+        Get it from:
+        <a href="http://www.python.org/download">
+        http://www.python.org/download</a></li>
+    <li><b>GnuWin32 tools</b>
+        These are also necessary for running the tests.
+        (Note that the grep from MSYS or Cygwin doesn't work with the tests
+        because of embedded double-quotes in the search strings.  The GNU
+        grep does work in this case.)
+        Get them from <a href="http://getgnuwin32.sourceforge.net">
+        http://getgnuwin32.sourceforge.net</a>.</li>
+  </ul>
+
+  <li>Checkout LLVM:</li>
+  <ul>
+    <li><tt>svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm</tt></li>
+  </ul>
+  <li>Checkout Clang:</li>
+  <ul>
+     <li><tt>cd llvm\tools</tt>
+     <li><tt>svn co http://llvm.org/svn/llvm-project/cfe/trunk clang</tt></li>
+  </ul>
+  <li>Run cmake to generate the Visual Studio solution and project files:</li>
+  <ul>
+    <li><tt>cd ..</tt>  (Change directory back to the llvm top.)</li>
+    <li>If you are using Visual Studio 2005:  <tt>cmake .</tt></li>
+    <li>Or if you are using Visual Studio 2008:  <tt>cmake -G "Visual Studio 9 2008" .</tt></li>
+    <li>The above, if successful, will have created an LLVM.sln file in the
+       llvm directory.
+  </ul>
+  <li>Build Clang:</li>
+  <ul>
+    <li>Open LLVM.sln in Visual Studio.</li>
+    <li>Build the "clang" project for just the compiler driver and front end, or
+      the "ALL_BUILD" project to build everything, including tools.</li>
+  </ul>
+  <li>Try it out (assuming you added llvm/debug/bin to your path).  (See the
+    running examples from above.)</li>
+  <li>See <a href="hacking.html#testingWindows">
+     Hacking on clang - Testing using Visual Studio on Windows</a> for information
+     on running regression tests on Windows.</li>
+</ol>
+
+<p>Note that once you have checked out both llvm and clang, to synchronize
+to the latest code base, use the <tt>svn update</tt> command in both the
+llvm and llvm\tools\clang directories, as they are separate repositories.</p>
+
+<a name="driver"><h2>Clang Compiler Driver (Drop-in Substitute for GCC)</h2></a>
+
+<p>The <tt>clang</tt> tool is the compiler driver and front-end, which is
+designed to be a drop-in replacement for the <tt>gcc</tt> command.  Here are
+some examples of how to use the high-level driver:
+</p>
+
+<pre class="code">
+$ <b>cat t.c</b>
+#include &lt;stdio.h&gt;
+int main(int argc, char **argv) { printf("hello world\n"); }
+$ <b>clang t.c</b>
+$ <b>./a.out</b>
+hello world
+</pre>
+
+<p>The 'clang' driver is designed to work as closely to GCC as possible to
+  maximize portability.  The only major difference between the two is that
+  Clang defaults to gnu99 mode while GCC defaults to gnu89 mode.  If you see
+  weird link-time errors relating to inline functions, try passing -std=gnu89
+  to clang.</p>
+
+<h2>Examples of using Clang</h2>
+
+<!-- Thanks to
+ http://shiflett.org/blog/2006/oct/formatting-and-highlighting-php-code-listings
+Site suggested using pre in CSS, but doesn't work in IE, so went for the <pre>
+tag. -->
+
+<pre class="code">
+$ <b>cat ~/t.c</b>
+typedef float V __attribute__((vector_size(16)));
+V foo(V a, V b) { return a+b*a; }
+</pre>
+
+
+<h3>Preprocessing:</h3>
+
+<pre class="code">
+$ <b>clang ~/t.c -E</b>
+# 1 "/Users/sabre/t.c" 1
+
+typedef float V __attribute__((vector_size(16)));
+
+V foo(V a, V b) { return a+b*a; }
+</pre>
+
+
+<h3>Type checking:</h3>
+
+<pre class="code">
+$ <b>clang -fsyntax-only ~/t.c</b>
+</pre>
+
+
+<h3>GCC options:</h3>
+
+<pre class="code">
+$ <b>clang -fsyntax-only ~/t.c -pedantic</b>
+/Users/sabre/t.c:2:17: warning: extension used
+typedef float V __attribute__((vector_size(16)));
+                ^
+1 diagnostic generated.
+</pre>
+
+
+<h3>Pretty printing from the AST:</h3>
+
+<p>Note, the <tt>-cc1</tt> argument indicates the the compiler front-end, and
+not the driver, should be run. The compiler front-end has several additional
+Clang specific features which are not exposed through the GCC compatible driver
+interface.</p>
+
+<pre class="code">
+$ <b>clang -cc1 ~/t.c -ast-print</b>
+typedef float V __attribute__(( vector_size(16) ));
+V foo(V a, V b) {
+   return a + b * a;
+}
+</pre>
+
+
+<h3>Code generation with LLVM:</h3>
+
+<pre class="code">
+$ <b>clang ~/t.c -S -emit-llvm -o -</b>
+define &lt;4 x float&gt; @foo(&lt;4 x float&gt; %a, &lt;4 x float&gt; %b) {
+entry:
+         %mul = mul &lt;4 x float&gt; %b, %a
+         %add = add &lt;4 x float&gt; %mul, %a
+         ret &lt;4 x float&gt; %add
+}
+$ <b>clang -fomit-frame-pointer -O3 -S -o - t.c</b> <i># On x86_64</i>
+...
+_foo:
+Leh_func_begin1:
+	mulps	%xmm0, %xmm1
+	addps	%xmm1, %xmm0
+	ret
+Leh_func_end1:
+</pre>
+
+</div>
+</body>
+</html>
diff --git a/www/hacking.html b/www/hacking.html
new file mode 100644
index 0000000..3bbc0ea
--- /dev/null
+++ b/www/hacking.html
@@ -0,0 +1,270 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" 
+          "http://www.w3.org/TR/html4/strict.dtd">
+<!-- Material used from: HTML 4.01 specs: http://www.w3.org/TR/html401/ -->
+<html>
+<head>
+  <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
+  <title>Hacking on clang</title>
+  <link type="text/css" rel="stylesheet" href="menu.css" />
+  <link type="text/css" rel="stylesheet" href="content.css" />
+</head>
+<body>
+<!--#include virtual="menu.html.incl"-->
+<div id="content">
+  <!--*********************************************************************-->
+  <h1>Hacking on Clang</h1>
+  <!--*********************************************************************-->
+  
+  <p>This document provides some hints for how to get started hacking
+  on Clang for developers who are new to the Clang and/or LLVM
+  codebases.</p>
+    <ul>
+      <li><a href="#style">Coding Standards</a></li>
+      <li><a href="#docs">Developer Documentation</a></li>
+      <li><a href="#debugging">Debugging</a></li>
+      <li><a href="#testing">Testing</a></li>
+      <ul>
+	    <li><a href="#testingNonWindows">Testing on Unix-like Systems</a></li>
+	    <li><a href="#testingWindows">Testing using Visual Studio on Windows</a></li>
+	  </ul>
+      <li><a href="#patches">Creating Patch Files</a></li>
+      <li><a href="#irgen">LLVM IR Generation</a></li>
+    </ul>
+    
+  <!--=====================================================================-->
+  <h2 id="docs">Coding Standards</h2>
+  <!--=====================================================================-->
+  
+  <p>Clang follows the
+  LLVM <a href="http://llvm.org/docs/CodingStandards.html">Coding
+  Standards</a>. When submitting patches, please take care to follow these standards
+  and to match the style of the code to that present in Clang (for example, in
+  terms of indentation, bracing, and statement spacing).</p>
+
+  <p>Clang has a few additional coding standards:</p>
+  <ul>
+    <li><i>cstdio is forbidden</i>: library code should not output diagnostics
+      or other information using <tt>cstdio</tt>; debugging routines should
+      use <tt>llvm::errs()</tt>. Other uses of <tt>cstdio</tt> impose behavior
+      upon clients and block integrating Clang as a library. Libraries should
+      support <tt>raw_ostream</tt> based interfaces for textual
+      output. See <a href="http://llvm.org/docs/CodingStandards.html#ll_raw_ostream">Coding
+      Standards</a>.</li>
+  </ul>
+
+  <!--=====================================================================-->
+  <h2 id="docs">Developer Documentation</h2>
+  <!--=====================================================================-->
+  
+  <p>Both Clang and LLVM use doxygen to provide API documentation. Their
+  respective web pages (generated nightly) are here:</p>
+    <ul>
+      <li><a href="http://clang.llvm.org/doxygen">Clang</a></li>
+      <li><a href="http://llvm.org/doxygen">LLVM</a></li>
+    </ul>
+      
+  <p>For work on the LLVM IR generation, the LLVM assembly language
+  <a href="http://llvm.org/docs/LangRef.html">reference manual</a> is
+  also useful.</p>
+
+  <!--=====================================================================-->
+  <h2 id="debugging">Debugging</h2>
+  <!--=====================================================================-->
+  
+  <p>Inspecting data structures in a debugger:</p>
+    <ul>
+      <li>Many LLVM and Clang data structures provide
+        a <tt>dump()</tt> method which will print a description of the
+        data structure to <tt>stderr</tt>.</li>
+      <li>The <a href="docs/InternalsManual.html#QualType"><tt>QualType</tt></a>
+      structure is used pervasively. This is a simple value class for
+      wrapping types with qualifiers; you can use
+      the <tt>isConstQualified()</tt>, for example, to get one of the
+      qualifiers, and the <tt>getTypePtr()</tt> method to get the
+      wrapped <tt>Type*</tt> which you can then dump.</li>
+    </ul>
+  
+  <!--=====================================================================-->
+  <h2 id="testing">Testing</h2>
+  <!--=====================================================================-->
+  
+  <p><i>[Note: The test running mechanism is currently under revision, so the
+  following might change shortly.]</i></p>
+  
+  <!--=====================================================================-->
+  <h3 id="testingNonWindows">Testing on Unix-like Systems</h3>
+  <!--=====================================================================-->
+  
+  <p>Clang includes a basic regression suite in the tree which can be
+  run with <tt>make test</tt> from the top-level clang directory, or
+  just <tt>make</tt> in the <em>test</em> sub-directory.
+  <tt>make VERBOSE=1</tt> can be used to show more detail
+  about what is being run.</p>
+
+  <p>The tests primarily consist of a test runner script running the compiler
+  under test on individual test files grouped in the directories under the
+  test directory.  The individual test files include comments at the
+  beginning indicating the Clang compile options to use, to be read
+  by the test runner. Embedded comments also can do things like telling
+  the test runner that an error is expected at the current line.
+  Any output files produced by the test will be placed under
+  a created Output directory.</p>
+  
+  <p>During the run of <tt>make test</tt>, the terminal output will
+  display a line similar to the following:</p>
+  
+  <ul><tt>--- Running clang tests for i686-pc-linux-gnu ---</tt></ul>
+  
+  <p>followed by a line continually overwritten with the current test
+  file being compiled, and an overall completion percentage.</p>
+  
+  <p>After the <tt>make test</tt> run completes, the absence of any
+  <tt>Failing Tests (count):</tt> message indicates that no tests
+  failed unexpectedly.  If any tests did fail, the
+  <tt>Failing Tests (count):</tt> message will be followed by a list
+  of the test source file paths that failed.  For example:</p>
+
+  <tt><pre>
+  Failing Tests (3):
+      /home/john/llvm/tools/clang/test/SemaCXX/member-name-lookup.cpp
+      /home/john/llvm/tools/clang/test/SemaCXX/namespace-alias.cpp
+      /home/john/llvm/tools/clang/test/SemaCXX/using-directive.cpp
+  </pre></tt>
+
+  <p>If you used the <tt>make VERBOSE=1</tt> option, the terminal
+  output will reflect the error messages from the compiler and
+  test runner.</p>
+
+  <p>The regression suite can also be run with Valgrind by running
+  <tt>make test VG=1</tt> in the top-level clang directory.</p>
+
+  <p>For more intensive changes, running
+  the <a href="http://llvm.org/docs/TestingGuide.html#testsuiterun">LLVM
+  Test Suite</a> with clang is recommended. Currently the best way to
+  override LLVMGCC, as in: <tt>make LLVMGCC="clang -std=gnu89"
+  TEST=nightly report</tt> (make sure <tt>clang</tt> is in your PATH or use the
+  full path).</p>
+  
+  <!--=====================================================================-->
+  <h3 id="testingWindows">Testing using Visual Studio on Windows</h3>
+  <!--=====================================================================-->
+
+  <p>The Clang test suite can be run from either Visual Studio or
+  the command line.</p>
+  
+  <p>Note that the test runner is based on
+  Python, which must be installed.  Find Python at:
+  <a href="http://www.python.org/download">http://www.python.org/download</a>.
+  Download the latest stable version (2.6.2 at the time of this writing).</p>
+  
+  <p>The GnuWin32 tools are also necessary for running the tests.
+  (Note that the grep from MSYS or Cygwin doesn't work with the tests
+  because of embedded double-quotes in the search strings.  The GNU
+  grep does work in this case.)
+  Get them from <a href="http://getgnuwin32.sourceforge.net">
+  http://getgnuwin32.sourceforge.net</a>.</p>
+  
+  <p>The cmake build tool is set up to create Visual Studio project files
+  for running the tests, "clang-test" being the root.  Therefore, to
+  run the test from Visual Studio, right-click the clang-test project
+  and select "Build".</p>
+  
+  <p>To run all the tests from the command line, execute a command like
+  the following:</p>
+  
+  <tt>
+  python (path to llvm)/llvm/utils/lit/lit.py -sv --no-progress-bar
+ (path to llvm)/llvm/tools/clang/test
+  </tt>
+
+  <p>To run a single test:</p>
+  
+  <tt>
+  python (path to llvm)/llvm/utils/lit/lit.py -sv --no-progress-bar
+ (path to llvm)/llvm/tools/clang/test/(dir)/(test)
+  </tt>
+
+  <p>For example:</p>
+  
+  <tt>
+  python C:/Tools/llvm/utils/lit/lit.py -sv --no-progress-bar
+  C:/Tools/llvm/tools/clang/test/Sema/wchar.c
+  </tt>
+
+  <p>The -sv option above tells the runner to show the test output if
+  any tests failed, to help you determine the cause of failure.</p>
+
+  <p>Note that a few tests currently fail on Windows.  We are working to
+  correct this. Therefore your output might look something like this:</p>
+
+<tt><pre>lit.py: lit.cfg:152: note: using clang: 'C:/Tools/llvm/bin/Debug\\clang.EXE'
+-- Testing: 1723 tests, 2 threads --
+FAIL: Clang::(test path) (659 of 1723)
+******************** TEST 'Clang::(test path)' FAILED ********************
+Script:
+  (commands run)
+Command Output (stdout):
+  (output here)
+Command Output (stderr):
+  (output here)
+********************
+Testing Time: 83.66s
+********************
+Failing Tests (1):
+    Clang::(test path)
+  Expected Passes    : 1704
+  Expected Failures  : 18
+  Unexpected Failures: 1
+</pre></tt>  
+
+  <p>The last statistic, "Unexpected Failures", is the important one.</p>
+
+  <!--=====================================================================-->
+  <h2 id="patches">Creating Patch Files</h2>
+  <!--=====================================================================-->
+
+  <p>To return changes to the Clang team, unless you have checkin
+  privileges, the prefered way is to send patch files to the
+  cfe-commits mailing list, with an explanation of what the patch is for.
+  Or, if you have questions, or want to have a wider discussion of what
+  you are doing, such as if you are new to Clang development, you can use
+  the cfe-dev mailing list also.
+  </p>
+  
+  <p>To create these patch files, change directory
+  to the llvm/tools/clang root and run:</p>
+  
+  <ul><tt>svn diff (relative path) >(patch file name)</tt></ul>
+
+  <p>For example, for getting the diffs of all of clang:</p>
+  
+  <ul><tt>svn diff . >~/mypatchfile.patch</tt></ul>
+
+  <p>For example, for getting the diffs of a single file:</p>
+  
+  <ul><tt>svn diff lib/Parse/ParseDeclCXX.cpp >~/ParseDeclCXX.patch</tt></ul>
+
+  <p>Note that the paths embedded in the patch depend on where you run it,
+  so changing directory to the llvm/tools/clang directory is recommended.</p>
+
+  <!--=====================================================================-->
+  <h2 id="irgen">LLVM IR Generation</h2>
+  <!--=====================================================================-->
+
+  <p>The LLVM IR generation part of clang handles conversion of the
+    AST nodes output by the Sema module to the LLVM Intermediate
+    Representation (IR). Historically, this was referred to as
+    "codegen", and the Clang code for this lives
+    in <tt>lib/CodeGen</tt>.</p>
+  
+  <p>The output is most easily inspected using the <tt>-emit-llvm</tt>
+    option to clang (possibly in conjunction with <tt>-o -</tt>). You
+    can also use <tt>-emit-llvm-bc</tt> to write an LLVM bitcode file
+    which can be processed by the suite of LLVM tools
+    like <tt>llvm-dis</tt>, <tt>llvm-nm</tt>, etc. See the LLVM
+    <a href="http://llvm.org/docs/CommandGuide/">Command Guide</a>
+    for more information.</p>
+
+</div>
+</body>
+</html>
diff --git a/www/index.html b/www/index.html
new file mode 100644
index 0000000..9adf640
--- /dev/null
+++ b/www/index.html
@@ -0,0 +1,119 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" 
+          "http://www.w3.org/TR/html4/strict.dtd">
+<!-- Material used from: HTML 4.01 specs: http://www.w3.org/TR/html401/ -->
+<html>
+<head>
+  <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+  <title>"clang" C Language Family Frontend for LLVM</title>
+  <link type="text/css" rel="stylesheet" href="menu.css">
+  <link type="text/css" rel="stylesheet" href="content.css">
+</head>
+<body>
+<!--#include virtual="menu.html.incl"-->
+<div id="content">
+  <!--*********************************************************************-->
+  <h1>clang: a C language family frontend for LLVM</h1>
+  <!--*********************************************************************-->
+  
+  <p>The goal of the Clang project is to create a new C, C++, Objective C and
+  Objective C++ front-end for the <a href="http://www.llvm.org/">LLVM</a>
+  compiler.  You can <a href="get_started.html">get and build</a> the source
+  today.</p>
+  
+  <!--=====================================================================-->
+  <h2 id="goals">Features and Goals</h2>
+  <!--=====================================================================-->
+  
+  <p>Some of the goals for the project include the following:</p>
+  
+  <p><b><a href="features.html#enduser">End-User Features</a></b>:</p>
+
+  <ul>
+  <li>Fast compiles and low memory use</li>
+  <li>Expressive diagnostics (<a href="diagnostics.html">examples</a>)</li>
+  <li>GCC compatibility</li>
+  </ul>
+
+  <p><b><a href="features.html#applications">Utility and 
+     Applications</a></b>:</p>
+
+  <ul>
+  <li>Modular library based architecture</li>
+  <li>Support diverse clients (refactoring, static analysis, code generation,
+   etc)</li>
+  <li>Allow tight integration with IDEs</li>
+  <li>Use the LLVM 'BSD' License</li>
+  </ul>
+
+  <p><b><a href="features.html#design">Internal Design and 
+     Implementation</a></b>:</p>
+
+  <ul>
+  <li>A real-world, production quality compiler</li>
+  <li>A simple and hackable code base</li>
+  <li>A single unified parser for C, Objective C, C++, and Objective C++</li>
+  <li>Conformance with C/C++/ObjC and their variants</li>
+  </ul>
+
+  <p>Of course this is only a rough outline of the goals and features of
+     Clang.  To get a true sense of what it is all about, see the <a 
+     href="features.html">Features</a> section, which breaks
+     each of these down and explains them in more detail.</p>
+
+     
+  <!--=====================================================================-->
+  <h2>Why?</h2>
+  <!--=====================================================================-->
+  
+  <p>The development of a new front-end was started out of a need -- a need
+     for a compiler that allows better diagnostics, better integration with
+     IDEs, a license that is compatible with commercial products, and a
+     nimble compiler that is easy to develop and maintain.  All of these were
+     motivations for starting work on a new front-end that could
+     meet these needs.</p>
+     
+  <p>A good (but quite dated) introduction to Clang can be found in the
+     following video lectures:</p>
+     
+  <ul>
+    <li><a href="clang_video-05-25-2007.html">Clang Introduction</a>
+        (May 2007)</li>
+    <li><a href="clang_video-07-25-2007.html">Features and Performance of 
+        Clang</a>  (July 2007)</li>
+  </ul>
+  
+  <p>For a more detailed comparison between Clang and other compilers, please
+     see the <a href="comparison.html">clang comparison page</a>.</p>
+  
+  <!--=====================================================================-->
+  <h2>Current Status</h2>
+  <!--=====================================================================-->
+  
+  <p>Clang is still under heavy development.  Clang is considered to
+   be a production quality C and Objective-C compiler when targetting
+   X86-32 and X86-64 (other targets may have caveats, but are usually
+   easy to fix).  If you are looking for source analysis or
+   source-to-source transformation tools, clang is probably a great
+   solution for you.  Clang's C++ support is currently alpha quality
+   at best, but is evolving rapidly: see the <a
+    href="cxx_status.html">C++ status</a> page for more
+   information.</p>
+
+  <!--=====================================================================-->
+  <h2>Get it and get involved!</h2>
+  <!--=====================================================================-->
+  
+  <p>Start by <a href="get_started.html">getting the code, building it, and
+     playing with it</a>.  This will show you the sorts of things we can do
+     today and will let you have the "clang experience" first hand: hopefully
+     it will "resonate" with you. :)</p>
+  
+  <p>Once you've done that, please consider <a href="get_involved.html">getting
+     involved in the clang community</a>.  The clang developers include numerous
+     volunteer contributors with a variety of backgrounds.  If you're 
+     interested in
+     following the development of clang, signing up for a mailing list is a good
+     way to learn about how the project works.</p>
+</div>
+</body>
+</html>
diff --git a/www/menu.css b/www/menu.css
new file mode 100644
index 0000000..4a887b1
--- /dev/null
+++ b/www/menu.css
@@ -0,0 +1,39 @@
+/***************/
+/* page layout */
+/***************/
+
+[id=menu] {
+	position:fixed;
+	width:25ex;
+}
+[id=content] {
+	/* *****  EDIT THIS VALUE IF CONTENT OVERLAPS MENU ***** */
+	position:absolute;
+  left:29ex;
+	padding-right:4ex;
+}
+
+/**************/
+/* menu style */
+/**************/
+
+#menu .submenu {
+	padding-top:1em;
+	display:block;
+}
+
+#menu label {
+	display:block;
+	font-weight: bold;
+	text-align: center;
+	background-color: rgb(192,192,192);
+}
+#menu a {
+	padding:0 .2em;
+	display:block;
+	text-align: center;
+	background-color: rgb(235,235,235);
+}
+#menu a:visited {
+	color:rgb(100,50,100);
+}
diff --git a/www/menu.html.incl b/www/menu.html.incl
new file mode 100644
index 0000000..29ed3a3
--- /dev/null
+++ b/www/menu.html.incl
@@ -0,0 +1,58 @@
+<div id="menu">
+  <div>
+    <a href="http://llvm.org/">LLVM Home</a>
+  </div>
+  
+  <div class="submenu">
+    <label>Clang Info</label>
+    <a href="/index.html">About</a>
+    <a href="/features.html">Features</a>
+    <a href="/comparison.html">Comparisons</a>
+    <a href="/docs/UsersManual.html">Users Manual</a>
+    <a href="/docs/LanguageExtensions.html">Language&nbsp;Extensions</a>
+    <a href="/cxx_status.html">C++ Status</a>
+  </div>
+
+  <div class="submenu">
+    <label>Clang Development</label>
+    <a href="/get_started.html">Get&nbsp;Started</a>
+    <a href="/get_involved.html">Get&nbsp;Involved</a>
+    <a href="/OpenProjects.html">Open&nbsp;Projects</a>
+    <a href="/docs/InternalsManual.html">Clang&nbsp;Internals</a>
+    <a href="/hacking.html">Hacking on Clang</a>
+    <a href="/performance.html">Performance</a>
+  </div>
+  
+  <div class="submenu">
+    <label>Clang Tools</label>
+    <a href="http://clang-analyzer.llvm.org">Automatic Bug-Finding</a>
+  </div>
+  
+  <div class="submenu">
+    <label>Communication</label>
+    <a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev">cfe-dev List</a>
+    <a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits">cfe-commit List</a>
+    <a href="irc://irc.oftc.net/llvm">IRC: irc.oftc.net#llvm</a>
+    <a href="http://llvm.org/bugs/">Bug Reports</a>
+  </div>
+
+  <div class="submenu">
+    <label>The Code</label>
+    <a href="/get_started.html#build">Check Out SVN</a>
+    <a href="http://llvm.org/svn/llvm-project/cfe/trunk/">Browse SVN</a>
+    <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/">Browse ViewVC</a>
+    <a href="http://clang.llvm.org/doxygen/">doxygen</a>
+  </div>
+
+  <div class="submenu">
+    <label>Quick Links</label>
+    <a href="http://t1.minormatter.com/~ddunbar/clang-cov/">Testing Coverage</a>
+    <a href="http://t1.minormatter.com/~ddunbar/references.html">Spec. References</a>
+  </div>
+  
+  <div class="submenu">
+    <label>Events</label>
+    <a href="http://llvm.org/devmtg/2009-10/">October 2, 2009 - LLVM/Clang Developer Meeting</a>
+  </div>
+
+</div>
diff --git a/www/performance-2008-10-31.html b/www/performance-2008-10-31.html
new file mode 100644
index 0000000..5246ac3
--- /dev/null
+++ b/www/performance-2008-10-31.html
@@ -0,0 +1,134 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+          "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+  <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
+  <title>Clang - Performance</title>
+  <link type="text/css" rel="stylesheet" href="menu.css" />
+  <link type="text/css" rel="stylesheet" href="content.css" />
+  <style type="text/css">
+</style>
+</head>
+<body>
+
+<!--#include virtual="menu.html.incl"-->
+
+<div id="content">
+
+<!--*************************************************************************-->
+<h1>Clang - Performance</h1>
+<!--*************************************************************************-->
+
+<p>This page tracks the compile time performance of Clang on two
+interesting benchmarks:
+<ul>
+  <li><i>Sketch</i>: The Objective-C example application shipped on
+    Mac OS X as part of Xcode. <i>Sketch</i> is indicative of a
+    "typical" Objective-C app. The source itself has a relatively
+    small amount of code (~7,500 lines of source code), but it relies
+    on the extensive Cocoa APIs to build its functionality. Like many
+    Objective-C applications, it includes
+    <tt>Cocoa/Cocoa.h</tt> in all of its source files, which represents a
+    significant stress test of the front-end's performance on lexing,
+    preprocessing, parsing, and syntax analysis.</li>
+  <li><i>176.gcc</i>: This is the gcc-2.7.2.2 code base as present in
+  SPECINT 2000. In contrast to Sketch, <i>176.gcc</i> consists of a
+  large amount of C source code (~220,000 lines) with few system
+  dependencies. This stresses the back-end's performance on generating
+  assembly code and debug information.</li>
+</ul>
+</p>
+
+<!--*************************************************************************-->
+<h2><a name="enduser">Experiments</a></h2>
+<!--*************************************************************************-->
+
+<p>Measurements are done by serially processing each file in the
+respective benchmark, using Clang, gcc, and llvm-gcc as compilers. In
+order to track the performance of various subsystems the timings have
+been broken down into separate stages where possible:
+
+<ul>
+  <li><tt>-Eonly</tt>: This option runs the preprocessor but does not
+    perform any output. For gcc and llvm-gcc, the -MM option is used
+    as a rough equivalent to this step.</li>
+  <li><tt>-parse-noop</tt>: This option runs the parser on the input,
+    but without semantic analysis or any output. gcc and llvm-gcc have
+    no equivalent for this option.</li>
+  <li><tt>-fsyntax-only</tt>: This option runs the parser with semantic
+    analysis.</li>
+  <li><tt>-emit-llvm -O0</tt>: For Clang and llvm-gcc, this option
+    converts to the LLVM intermediate representation but doesn't
+    generate native code.</li>
+  <li><tt>-S -O0</tt>: Perform actual code generation to produce a
+    native assembler file.</li>
+  <li><tt>-S -O0 -g</tt>: This adds emission of debug information to
+    the assembly output.</li>
+</ul>
+</p>
+
+<p>This set of stages is chosen to be approximately additive, that is
+each subsequent stage simply adds some additional processing. The
+timings measure the delta of the given stage from the previous
+one. For example, the timings for <tt>-fsyntax-only</tt> below show
+the difference of running with <tt>-fsyntax-only</tt> versus running
+with <tt>-parse-noop</tt> (for clang) or <tt>-MM</tt> with gcc and
+llvm-gcc. This amounts to a fairly accurate measure of only the time
+to perform semantic analysis (and parsing, in the case of gcc and llvm-gcc).</p>
+
+<p>These timings are chosen to break down the compilation process for
+clang as much as possible. The graphs below show these numbers
+combined so that it is easy to see how the time for a particular task
+is divided among various components. For example, <tt>-S -O0</tt>
+includes the time of <tt>-fsyntax-only</tt> and <tt>-emit-llvm -O0</tt>.</p>
+
+<p>Note that we already know that the LLVM optimizers are substantially (30-40%)
+faster than the GCC optimizers at a given -O level, so we only focus on -O0
+compile time here.</p>
+
+<!--*************************************************************************-->
+<h2><a name="enduser">Timing Results</a></h2>
+<!--*************************************************************************-->
+
+<!--=======================================================================-->
+<h3><a name="2008-10-31">2008-10-31</a></h3>
+<!--=======================================================================-->
+
+<center><h4>Sketch</h4></center>
+<img class="img_slide" 
+     src="timing-data/2008-10-31/sketch.png" alt="Sketch Timings"/>
+
+<p>This shows Clang's substantial performance improvements in
+preprocessing and semantic analysis; over 90% faster on
+-fsyntax-only. As expected, time spent in code generation for this
+benchmark is relatively small. One caveat, Clang's debug information
+generation for Objective-C is very incomplete; this means the <tt>-S
+-O0 -g</tt> numbers are unfair since Clang is generating substantially
+less output.</p>
+
+<p>This chart also shows the effect of using precompiled headers (PCH)
+on compiler time. gcc and llvm-gcc see a large performance improvement
+with PCH; about 4x in wall time. Unfortunately, Clang does not yet
+have an implementation of PCH-style optimizations, but we are actively
+working to address this.</p>
+
+<center><h4>176.gcc</h4></center>
+<img class="img_slide" 
+     src="timing-data/2008-10-31/176.gcc.png" alt="176.gcc Timings"/>
+
+<p>Unlike the <i>Sketch</i> timings, compilation of <i>176.gcc</i>
+involves a large amount of code generation. The time spent in Clang's
+LLVM IR generation and code generation is on par with gcc's code
+generation time but the improved parsing & semantic analysis
+performance means Clang still comes in at ~29% faster versus gcc
+on <tt>-S -O0 -g</tt> and ~20% faster versus llvm-gcc.</p>
+
+<p>These numbers indicate that Clang still has room for improvement in
+several areas, notably our LLVM IR generation is significantly slower
+than that of llvm-gcc, and both Clang and llvm-gcc incur a
+significantly higher cost for adding debugging information compared to
+gcc.</p>
+
+</div>
+</body>
+</html>
diff --git a/www/performance-2009-03-02.html b/www/performance-2009-03-02.html
new file mode 100644
index 0000000..f76fc7a
--- /dev/null
+++ b/www/performance-2009-03-02.html
@@ -0,0 +1,112 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+          "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+  <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
+  <title>Clang - Performance</title>
+  <link type="text/css" rel="stylesheet" href="menu.css" />
+  <link type="text/css" rel="stylesheet" href="content.css" />
+  <style type="text/css">
+</style>
+</head>
+<body>
+
+<!--#include virtual="menu.html.incl"-->
+
+<div id="content">
+
+<!--*************************************************************************-->
+<h1>Clang - Performance</h1>
+<!--*************************************************************************-->
+
+<p>This page shows the compile time performance of Clang on two
+interesting benchmarks:
+<ul>
+  <li><i>Sketch</i>: The Objective-C example application shipped on
+    Mac OS X as part of Xcode. <i>Sketch</i> is indicative of a
+    "typical" Objective-C app. The source itself has a relatively
+    small amount of code (~7,500 lines of source code), but it relies
+    on the extensive Cocoa APIs to build its functionality. Like many
+    Objective-C applications, it includes <tt>Cocoa/Cocoa.h</tt> in
+    all of its source files, which represents a significant stress
+    test of the front-end's performance on lexing, preprocessing,
+    parsing, and syntax analysis.</li>
+  <li><i>176.gcc</i>: This is the gcc-2.7.2.2 code base as present in
+    SPECINT 2000. In contrast to Sketch, <i>176.gcc</i> consists of a
+    large amount of C source code (~200,000 lines) with few system
+    dependencies. This stresses the back-end's performance on generating
+    assembly code and debug information.</li>
+</ul>
+</p>
+
+<p>
+For previous performance numbers, please
+go <a href="performance-2008-10-31.html">here</a>.
+</p>
+
+<!--*************************************************************************-->
+<h2><a name="experiments">Experiments</a></h2>
+<!--*************************************************************************-->
+
+<p>Measurements are done by running a full build (using xcodebuild or
+make for Sketch and 176.gcc respectively) using Clang and gcc 4.2 as
+compilers; gcc is run both with and without the new clang driver (ccc)
+in order to evaluate the overhead of the driver itself.</p>
+
+<p>In order to track the performance of various subsystems the timings
+have been broken down into separate stages where possible. This is
+done by over-riding the CC environment variable used during the build
+to point to one of a few simple shell scripts which may skip part of
+the build.
+
+<ul>
+  <li><tt>non-compiler</tt>: The overhead of the build system itself;
+    for Sketch this also includes the time to build/copy various
+    non-source code resource files.</li>
+  <li><tt>+ driver</tt>: Add execution of the driver, but do not execute any
+    commands (by using the -### driver option).</li>
+  <li><tt>+ pch gen</tt>: Add generation of PCH files.</li>
+  <li><tt>+ cpp</tt>: Add preprocessing of source files (this time is
+    include in syntax for gcc).</li>
+  <li><tt>+ parse</tt>: Add parsing of source files (this time is
+    include in syntax for gcc).</li>
+  <li><tt>+ syntax</tt>: Add semantic checking of source files (for
+    gcc, this includes preprocessing and parsing as well).</li>
+  <li><tt>+ IRgen</tt>: Add generation of LLVM IR (gcc has no
+    corresponding phase).</li>
+  <li><tt>+ codegen</tt>: Add generation of assembler files.</li>
+  <li><tt>+ assembler</tt>: Add assembler time to generate .o files.</li>
+  <li><tt>+ linker</tt>: Add linker time.</li>
+</ul>
+</p>
+
+<p>This set of stages is chosen to be approximately additive, that is
+each subsequent stage simply adds some additional processing. The
+timings measure the delta of the given stage from the previous
+one. For example, the timings for <tt>+ syntax</tt> below show the
+difference of running with <tt>+ syntax</tt> versus running with <tt>+
+parse</tt> (for clang) or <tt>+ driver</tt> with gcc. This amounts to
+a fairly accurate measure of only the time to perform semantic
+analysis (and preprocessing/parsing, in the case of gcc).</p>
+
+<!--*************************************************************************-->
+<h2><a name="timings">Timing Results</a></h2>
+<!--*************************************************************************-->
+
+<!--=======================================================================-->
+<h3><a name="2009-03-02">2009-03-02</a></h3>
+<!--=======================================================================-->
+
+<a href="timing-data/2009-03-02/sketch.pdf">
+<img class="img_slide" 
+     src="timing-data/2009-03-02/sketch.png" alt="Sketch Timings"/>
+</a>
+
+<a href="timing-data/2009-03-02/176.gcc.pdf">
+<img class="img_slide" 
+     src="timing-data/2009-03-02/176.gcc.png" alt="176.gcc Timings"/>
+</a>
+
+</div>
+</body>
+</html>
diff --git a/www/performance.html b/www/performance.html
new file mode 100644
index 0000000..2bb8fe2
--- /dev/null
+++ b/www/performance.html
@@ -0,0 +1,106 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+          "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+  <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
+  <title>Clang - Performance</title>
+  <link type="text/css" rel="stylesheet" href="menu.css" />
+  <link type="text/css" rel="stylesheet" href="content.css" />
+  <style type="text/css">
+</style>
+</head>
+<body>
+
+<!--#include virtual="menu.html.incl"-->
+
+<div id="content">
+
+<!--*************************************************************************-->
+<h1>Clang - Performance</h1>
+<!--*************************************************************************-->
+
+<p>This page shows the compile time performance of Clang on two
+interesting benchmarks:
+<ul>
+  <li><i>Sketch</i>: The Objective-C example application shipped on
+    Mac OS X as part of Xcode. <i>Sketch</i> is indicative of a
+    "typical" Objective-C app. The source itself has a relatively
+    small amount of code (~7,500 lines of source code), but it relies
+    on the extensive Cocoa APIs to build its functionality. Like many
+    Objective-C applications, it includes <tt>Cocoa/Cocoa.h</tt> in
+    all of its source files, which represents a significant stress
+    test of the front-end's performance on lexing, preprocessing,
+    parsing, and syntax analysis.</li>
+  <li><i>176.gcc</i>: This is the gcc-2.7.2.2 code base as present in
+    SPECINT 2000. In contrast to Sketch, <i>176.gcc</i> consists of a
+    large amount of C source code (~200,000 lines) with few system
+    dependencies. This stresses the back-end's performance on generating
+    assembly code and debug information.</li>
+</ul>
+</p>
+
+<p>
+For previous performance numbers, please
+go <a href="performance-2009-03-02.html">here</a>.
+</p>
+
+<!--*************************************************************************-->
+<h2><a name="experiments">Experiments</a></h2>
+<!--*************************************************************************-->
+
+<p>Measurements are done by running a full build (using xcodebuild or
+make for Sketch and 176.gcc respectively) using Clang and gcc 4.2 as
+compilers.</p>
+
+<p>In order to track the performance of various subsystems the timings
+have been broken down into separate stages where possible. This is
+done by over-riding the CC environment variable used during the build
+to point to one of a few simple shell scripts which may skip part of
+the build.
+
+<ul>
+  <li><tt>non-compiler</tt>: The overhead of the build system itself;
+    for Sketch this also includes the time to build/copy various
+    non-source code resource files.</li>
+  <li><tt>+ driver</tt>: Add execution of the driver, but do not execute any
+    commands (by using the -### driver option).</li>
+  <li><tt>+ pch gen</tt>: Add generation of PCH files (if used).</li>
+  <li><tt>+ syntax</tt>: Add preprocessing, parsing, and semantic checking of
+    source files.</li>
+  <li><tt>+ IRgen</tt>: Add generation of LLVM IR (gcc has no
+    corresponding phase).</li>
+  <li><tt>+ codegen</tt>: Add generation of assembler files.</li>
+  <li><tt>+ assembler</tt>: Add assembler time to generate .o files.</li>
+  <li><tt>+ linker</tt>: Add linker time.</li>
+</ul>
+</p>
+
+<p>This set of stages is chosen to be approximately additive, that is each
+subsequent stage simply adds some additional processing. The timings measure the
+delta of the given stage from the previous one. For example, the timings
+for <tt>+ syntax</tt> below show the difference of running with <tt>+
+syntax</tt> versus the times for <tt>+ pch gen</tt>. This amounts to a fairly
+accurate measure of only the time to perform preprocessing, parsing, and
+semantic analysis after PCH generation is done.</p>
+
+<!--*************************************************************************-->
+<h2><a name="timings">Timing Results</a></h2>
+<!--*************************************************************************-->
+
+<!--=======================================================================-->
+<h3><a name="2009-06-26">2009-06-26</a></h3>
+<!--=======================================================================-->
+
+<a href="timing-data/2009-06-26/sketch.pdf">
+<img class="img_slide" 
+     src="timing-data/2009-06-26/sketch.png" alt="Sketch Timings"/>
+</a>
+
+<a href="timing-data/2009-06-26/176.gcc.pdf">
+<img class="img_slide" 
+     src="timing-data/2009-06-26/176.gcc.png" alt="176.gcc Timings"/>
+</a>
+
+</div>
+</body>
+</html>
diff --git a/www/timing-data/2008-10-31/176.gcc-01.txt b/www/timing-data/2008-10-31/176.gcc-01.txt
new file mode 100644
index 0000000..3809e0d
--- /dev/null
+++ b/www/timing-data/2008-10-31/176.gcc-01.txt
@@ -0,0 +1,135 @@
+Title:	176.gcc Timings
+Timestamp:	2008-10-31_17-10
+Uname:	Darwin lordcrumb.apple.com 10.0.0d3 Darwin Kernel Version 10.0.0d3: Fri Oct 24 02:12:11 PDT 2008; root:xnu-1353~2/RELEASE_I386 i386
+Path:	/Users/ddunbar/nightlytest/176.gcc
+Runs:	3
+
+LLVM SVN Rev.:	 58536
+
+clang:	/Users/ddunbar/llvm/Release-Asserts/bin//clang
+gcc:	/usr/bin/gcc-4.2
+llvm-gcc:	/Users/ddunbar/llvm-gcc/install/bin/llvm-gcc
+
+Mode:	Eonly	Compiler:	clang	PCH:	0	Flags:	
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 0.8321	 0.8274	 0.8274	 0.8435	 0.0080	 2.4964
+ sys	 0.4209	 0.4140	 0.4140	 0.4307	 0.0071	 1.2626
+wall	 1.2965	 1.2829	 1.2829	 1.3176	 0.0152	 3.8894
+
+Mode:	Eonly	Compiler:	gcc	PCH:	0	Flags:	
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 0.8534	 0.8465	 0.8563	 0.8575	 0.0050	 2.5603
+ sys	 0.5327	 0.5200	 0.5291	 0.5490	 0.0121	 1.5980
+wall	 1.4336	 1.4104	 1.4330	 1.4575	 0.0192	 4.3009
+
+Mode:	Eonly	Compiler:	llvm-gcc	PCH:	0	Flags:	
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 1.1313	 1.1277	 1.1304	 1.1359	 0.0034	 3.3940
+ sys	 0.5579	 0.5530	 0.5539	 0.5669	 0.0063	 1.6738
+wall	 1.7860	 1.7669	 1.7890	 1.8020	 0.0145	 5.3580
+
+
+Mode:	parse-noop	Compiler:	clang	PCH:	0	Flags:	
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 0.9276	 0.9267	 0.9269	 0.9292	 0.0011	 2.7827
+ sys	 0.4284	 0.4244	 0.4255	 0.4353	 0.0049	 1.2852
+wall	 1.3994	 1.3941	 1.3954	 1.4086	 0.0066	 4.1981
+
+
+Mode:	disable-free	Compiler:	clang	PCH:	0	Flags:	
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 1.2716	 1.2497	 1.2713	 1.2937	 0.0180	 3.8147
+ sys	 0.4835	 0.4815	 0.4738	 0.4953	 0.0089	 1.4506
+wall	 1.8149	 1.7838	 1.8137	 1.8471	 0.0259	 5.4446
+
+
+Mode:	syntax	Compiler:	clang	PCH:	0	Flags:	
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 1.4042	 1.4031	 1.4044	 1.4044	 0.0009	 4.2127
+ sys	 0.4818	 0.4802	 0.4838	 0.4838	 0.0015	 1.4454
+wall	 1.9359	 1.9333	 1.9376	 1.9376	 0.0019	 5.8077
+
+Mode:	syntax	Compiler:	gcc	PCH:	0	Flags:	
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 3.9188	 3.8766	 3.8846	 3.9951	 0.0541	11.7563
+ sys	 1.0207	 1.0195	 1.0141	 1.0285	 0.0059	 3.0622
+wall	 5.0500	 5.0023	 5.0092	 5.1386	 0.0627	15.1500
+
+Mode:	syntax	Compiler:	llvm-gcc	PCH:	0	Flags:	
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 3.8854	 3.8647	 3.8868	 3.9048	 0.0164	11.6563
+ sys	 0.8548	 0.8436	 0.8455	 0.8753	 0.0145	 2.5644
+wall	 4.8695	 4.8369	 4.8614	 4.9103	 0.0305	14.6086
+
+
+Mode:	llvm	Compiler:	clang	PCH:	0	Flags:	-O0
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 2.7903	 2.7606	 2.8026	 2.8079	 0.0211	 8.3710
+ sys	 0.6645	 0.6509	 0.6759	 0.6667	 0.0104	 1.9935
+wall	 3.5577	 3.4894	 3.5650	 3.6186	 0.0530	10.6730
+
+Mode:	llvm	Compiler:	llvm-gcc	PCH:	0	Flags:	-O0
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 4.1711	 4.1389	 4.1729	 4.2015	 0.0256	12.5133
+ sys	 0.9335	 0.9339	 0.9218	 0.9448	 0.0094	 2.8004
+wall	 5.2380	 5.1985	 5.2417	 5.2738	 0.0309	15.7140
+
+
+Mode:	asm	Compiler:	clang	PCH:	0	Flags:	-O0
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 5.2797	 5.1709	 5.2643	 5.4040	 0.0958	15.8392
+ sys	 0.7739	 0.7547	 0.7726	 0.7944	 0.0162	 2.3217
+wall	 6.1807	 6.1082	 6.1174	 6.3165	 0.0961	18.5421
+	Asm Lines:	  735931
+
+Mode:	asm	Compiler:	gcc	PCH:	0	Flags:	-O0
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 8.2410	 8.1034	 8.2230	 8.3965	 0.1203	24.7230
+ sys	 1.1924	 1.1576	 1.2112	 1.2082	 0.0246	 3.5771
+wall	 9.6010	 9.3792	 9.6800	 9.7438	 0.1590	28.8030
+	Asm Lines:	  514962
+
+Mode:	asm	Compiler:	llvm-gcc	PCH:	0	Flags:	-O0
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 6.3978	 6.3894	 6.3894	 6.4726	 0.0579	19.1935
+ sys	 1.0638	 1.0562	 1.0562	 1.0861	 0.0160	 3.1914
+wall	 7.6185	 7.5807	 7.5807	 7.6876	 0.0489	22.8555
+	Asm Lines:	  597193
+
+
+Mode:	llvm	Compiler:	clang	PCH:	0	Flags:	-O0 -g
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 3.9798	 3.9728	 3.9752	 3.9914	 0.0083	11.9393
+ sys	 0.7313	 0.7260	 0.7326	 0.7353	 0.0039	 2.1938
+wall	 4.7915	 4.7799	 4.7878	 4.8066	 0.0112	14.3744
+
+Mode:	llvm	Compiler:	llvm-gcc	PCH:	0	Flags:	-O0 -g
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 5.4838	 5.4701	 5.4701	 5.5172	 0.0238	16.4513
+ sys	 1.0527	 1.0401	 1.0401	 1.0757	 0.0163	 3.1581
+wall	 6.7059	 6.6768	 6.6768	 6.7254	 0.0210	20.1177
+
+
+Mode:	asm	Compiler:	clang	PCH:	0	Flags:	-O0 -g
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 6.8213	 6.7836	 6.8060	 6.8743	 0.0386	20.4639
+ sys	 0.8527	 0.8376	 0.8598	 0.8607	 0.0107	 2.5582
+wall	 7.8055	 7.7154	 7.8109	 7.8902	 0.0714	23.4165
+	Asm Lines:	 1581804
+
+Mode:	asm	Compiler:	gcc	PCH:	0	Flags:	-O0 -g
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 8.7962	 8.6334	 8.7861	 8.9691	 0.1373	26.3887
+ sys	 1.2758	 1.2395	 1.2780	 1.3100	 0.0288	 3.8275
+wall	10.2714	10.1274	10.2232	10.4635	 0.1414	30.8142
+	Asm Lines:	 1403421
+
+Mode:	asm	Compiler:	llvm-gcc	PCH:	0	Flags:	-O0 -g
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 7.9903	 7.9383	 7.9821	 8.0504	 0.0461	23.9708
+ sys	 1.1587	 1.1374	 1.1592	 1.1794	 0.0171	 3.4760
+wall	 9.3711	 9.2555	 9.2884	 9.5692	 0.1408	28.1132
+	Asm Lines:	 1580849
+
+
+	Done:	2008-10-31_17-16
diff --git a/www/timing-data/2008-10-31/176.gcc-02.txt b/www/timing-data/2008-10-31/176.gcc-02.txt
new file mode 100644
index 0000000..dd898c1
--- /dev/null
+++ b/www/timing-data/2008-10-31/176.gcc-02.txt
@@ -0,0 +1,135 @@
+Title:	176.gcc Timings
+Timestamp:	2008-10-31_17-17
+Uname:	Darwin lordcrumb.apple.com 10.0.0d3 Darwin Kernel Version 10.0.0d3: Fri Oct 24 02:12:11 PDT 2008; root:xnu-1353~2/RELEASE_I386 i386
+Path:	/Users/ddunbar/nightlytest/176.gcc
+Runs:	3
+
+LLVM SVN Rev.:	 58536
+
+clang:	/Users/ddunbar/llvm/Release-Asserts/bin//clang
+gcc:	/usr/bin/gcc-4.2
+llvm-gcc:	/Users/ddunbar/llvm-gcc/install/bin/llvm-gcc
+
+Mode:	Eonly	Compiler:	clang	PCH:	0	Flags:	
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 0.8238	 0.8184	 0.8187	 0.8342	 0.0074	 2.4713
+ sys	 0.4030	 0.3891	 0.3953	 0.4247	 0.0155	 1.2091
+wall	 1.2731	 1.2477	 1.2565	 1.3152	 0.0299	 3.8194
+
+Mode:	Eonly	Compiler:	gcc	PCH:	0	Flags:	
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 0.8584	 0.8501	 0.8560	 0.8692	 0.0080	 2.5753
+ sys	 0.5426	 0.5268	 0.5453	 0.5556	 0.0119	 1.6277
+wall	 1.4485	 1.4214	 1.4503	 1.4737	 0.0214	 4.3454
+
+Mode:	Eonly	Compiler:	llvm-gcc	PCH:	0	Flags:	
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 1.1289	 1.1338	 1.1322	 1.1207	 0.0058	 3.3866
+ sys	 0.5857	 0.5787	 0.5734	 0.6051	 0.0138	 1.7572
+wall	 1.8195	 1.8110	 1.8124	 1.8350	 0.0110	 5.4585
+
+
+Mode:	parse-noop	Compiler:	clang	PCH:	0	Flags:	
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 0.9286	 0.9250	 0.9250	 0.9370	 0.0059	 2.7859
+ sys	 0.4255	 0.4163	 0.4163	 0.4417	 0.0115	 1.2764
+wall	 1.3970	 1.3826	 1.3826	 1.4241	 0.0192	 4.1910
+
+
+Mode:	disable-free	Compiler:	clang	PCH:	0	Flags:	
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 1.2962	 1.2963	 1.2963	 1.3114	 0.0125	 3.8885
+ sys	 0.4842	 0.4864	 0.4864	 0.4901	 0.0059	 1.4527
+wall	 1.8424	 1.8356	 1.8356	 1.8534	 0.0078	 5.5273
+
+
+Mode:	syntax	Compiler:	clang	PCH:	0	Flags:	
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 1.4120	 1.4055	 1.4118	 1.4188	 0.0054	 4.2360
+ sys	 0.4824	 0.4786	 0.4821	 0.4864	 0.0032	 1.4471
+wall	 1.9573	 1.9467	 1.9570	 1.9682	 0.0088	 5.8719
+
+Mode:	syntax	Compiler:	gcc	PCH:	0	Flags:	
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 3.9243	 3.8431	 3.9624	 3.9675	 0.0575	11.7730
+ sys	 1.0094	 0.9967	 1.0135	 1.0180	 0.0091	 3.0282
+wall	 5.0495	 4.9447	 5.1012	 5.1025	 0.0741	15.1484
+
+Mode:	syntax	Compiler:	llvm-gcc	PCH:	0	Flags:	
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 3.9287	 3.8760	 3.9226	 3.9874	 0.0457	11.7860
+ sys	 0.8949	 0.8684	 0.9014	 0.9147	 0.0195	 2.6846
+wall	 4.9625	 4.8722	 4.9601	 5.0550	 0.0747	14.8874
+
+
+Mode:	llvm	Compiler:	clang	PCH:	0	Flags:	-O0
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 2.8082	 2.7806	 2.8106	 2.8334	 0.0216	 8.4246
+ sys	 0.6608	 0.6564	 0.6582	 0.6677	 0.0049	 1.9823
+wall	 3.5453	 3.5150	 3.5559	 3.5650	 0.0218	10.6359
+
+Mode:	llvm	Compiler:	llvm-gcc	PCH:	0	Flags:	-O0
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 4.1471	 4.1512	 4.1505	 4.1395	 0.0053	12.4413
+ sys	 0.9221	 0.9069	 0.9203	 0.9391	 0.0132	 2.7663
+wall	 5.2138	 5.1919	 5.2001	 5.2495	 0.0255	15.6415
+
+
+Mode:	asm	Compiler:	clang	PCH:	0	Flags:	-O0
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 5.1674	 5.1537	 5.1637	 5.1637	 0.0129	15.5022
+ sys	 0.7424	 0.7404	 0.7376	 0.7376	 0.0049	 2.2271
+wall	 6.0284	 5.9844	 6.0964	 6.0964	 0.0487	18.0852
+	Asm Lines:	  735931
+
+Mode:	asm	Compiler:	gcc	PCH:	0	Flags:	-O0
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 8.0945	 8.0259	 8.1235	 8.1342	 0.0487	24.2835
+ sys	 1.1599	 1.1517	 1.1626	 1.1654	 0.0059	 3.4796
+wall	 9.4120	 9.2935	 9.4036	 9.5390	 0.1004	28.2361
+	Asm Lines:	  514962
+
+Mode:	asm	Compiler:	llvm-gcc	PCH:	0	Flags:	-O0
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 6.4405	 6.3577	 6.4623	 6.5014	 0.0607	19.3214
+ sys	 1.0571	 1.0454	 1.0359	 1.0902	 0.0237	 3.1714
+wall	 7.6688	 7.5631	 7.6376	 7.8058	 0.1015	23.0065
+	Asm Lines:	  597193
+
+
+Mode:	llvm	Compiler:	clang	PCH:	0	Flags:	-O0 -g
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 3.9883	 3.9539	 3.9626	 4.0485	 0.0427	11.9650
+ sys	 0.7333	 0.7209	 0.7377	 0.7413	 0.0089	 2.1998
+wall	 4.8088	 4.7485	 4.7821	 4.8957	 0.0630	14.4263
+
+Mode:	llvm	Compiler:	llvm-gcc	PCH:	0	Flags:	-O0 -g
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 5.4875	 5.4528	 5.5017	 5.5017	 0.0247	16.4626
+ sys	 1.0308	 1.0231	 1.0248	 1.0248	 0.0097	 3.0923
+wall	 6.6781	 6.6372	 6.7006	 6.7006	 0.0290	20.0342
+
+
+Mode:	asm	Compiler:	clang	PCH:	0	Flags:	-O0 -g
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 6.7945	 6.6664	 6.7352	 6.9819	 0.1355	20.3835
+ sys	 0.8359	 0.8172	 0.8329	 0.8577	 0.0167	 2.5077
+wall	 7.7458	 7.6003	 7.7080	 7.9290	 0.1368	23.2374
+	Asm Lines:	 1581804
+
+Mode:	asm	Compiler:	gcc	PCH:	0	Flags:	-O0 -g
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 8.7280	 8.6884	 8.7084	 8.7870	 0.0426	26.1839
+ sys	 1.3031	 1.2940	 1.3118	 1.3037	 0.0073	 3.9094
+wall	10.2039	10.1039	10.1162	10.3916	 0.1328	30.6116
+	Asm Lines:	 1403421
+
+Mode:	asm	Compiler:	llvm-gcc	PCH:	0	Flags:	-O0 -g
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 7.9987	 7.9805	 7.9805	 8.0493	 0.0362	23.9962
+ sys	 1.1561	 1.1523	 1.1523	 1.1626	 0.0047	 3.4682
+wall	 9.3154	 9.2801	 9.2801	 9.3606	 0.0336	27.9463
+	Asm Lines:	 1580849
+
+
+	Done:	2008-10-31_17-23
diff --git a/www/timing-data/2008-10-31/176.gcc.png b/www/timing-data/2008-10-31/176.gcc.png
new file mode 100644
index 0000000..53efd87
--- /dev/null
+++ b/www/timing-data/2008-10-31/176.gcc.png
Binary files differ
diff --git a/www/timing-data/2008-10-31/sketch-01.txt b/www/timing-data/2008-10-31/sketch-01.txt
new file mode 100644
index 0000000..ff5d83e
--- /dev/null
+++ b/www/timing-data/2008-10-31/sketch-01.txt
@@ -0,0 +1,187 @@
+Title:	Sketch Timings
+Timestamp:	2008-10-31_16-46
+Uname:	Darwin lordcrumb.apple.com 10.0.0d3 Darwin Kernel Version 10.0.0d3: Fri Oct 24 02:12:11 PDT 2008; root:xnu-1353~2/RELEASE_I386 i386
+Path:	/Users/ddunbar/nightlytest/Sketch.ref
+Runs:	3
+
+LLVM SVN Rev.:	 58536
+
+clang:	/Users/ddunbar/llvm/Release-Asserts/bin//clang
+gcc:	/usr/bin/gcc-4.2
+llvm-gcc:	/Users/ddunbar/llvm-gcc/install/bin/llvm-gcc
+
+Mode:	Eonly	Compiler:	clang	PCH:	0	Flags:	
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 1.3762	 1.3711	 1.3724	 1.3849	 0.0062	 4.1285
+ sys	 0.8306	 0.8276	 0.8274	 0.8367	 0.0044	 2.4917
+wall	 2.2290	 2.2207	 2.2219	 2.2445	 0.0109	 6.6870
+
+Mode:	Eonly	Compiler:	gcc	PCH:	0	Flags:	
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 2.2970	 2.2352	 2.2374	 2.4184	 0.0858	 6.8910
+ sys	 1.0716	 1.0338	 1.0342	 1.1470	 0.0533	 3.2149
+wall	 3.4039	 3.3027	 3.3046	 3.6043	 0.1417	10.2116
+
+Mode:	Eonly	Compiler:	llvm-gcc	PCH:	0	Flags:	
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 2.8472	 2.7770	 2.7770	 2.9893	 0.1005	 8.5416
+ sys	 1.3153	 1.2699	 1.2699	 1.4079	 0.0655	 3.9460
+wall	 4.2134	 4.0909	 4.0909	 4.4421	 0.1618	12.6403
+
+
+Mode:	parse-noop	Compiler:	clang	PCH:	0	Flags:	
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 1.7295	 1.7228	 1.7237	 1.7421	 0.0089	 5.1886
+ sys	 0.8510	 0.8468	 0.8448	 0.8615	 0.0074	 2.5530
+wall	 2.6034	 2.5913	 2.5914	 2.6277	 0.0172	 7.8103
+
+
+Mode:	disable-free	Compiler:	clang	PCH:	0	Flags:	
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 2.7310	 2.7274	 2.7288	 2.7288	 0.0042	 8.1930
+ sys	 0.9950	 0.9890	 0.9917	 0.9917	 0.0068	 2.9851
+wall	 3.7720	 3.7515	 3.7866	 3.7866	 0.0150	11.3161
+
+
+Mode:	syntax	Compiler:	clang	PCH:	0	Flags:	
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 3.1817	 3.1284	 3.1620	 3.2547	 0.0534	 9.5451
+ sys	 1.0815	 1.0569	 1.0737	 1.1138	 0.0239	 3.2444
+wall	 4.2918	 4.2129	 4.2635	 4.3991	 0.0786	12.8755
+
+Mode:	syntax	Compiler:	gcc	PCH:	0	Flags:	
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 6.4086	 6.3289	 6.4012	 6.4956	 0.0682	19.2258
+ sys	 1.7617	 1.7257	 1.7615	 1.7979	 0.0295	 5.2851
+wall	 8.2403	 8.1235	 8.2432	 8.3541	 0.0942	24.7208
+
+Mode:	syntax	Compiler:	llvm-gcc	PCH:	0	Flags:	
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 6.9711	 6.8657	 6.9738	 7.0739	 0.0850	20.9133
+ sys	 1.7577	 1.7226	 1.7801	 1.7702	 0.0251	 5.2730
+wall	 8.8020	 8.6601	 8.8243	 8.9216	 0.1079	26.4061
+
+Mode:	syntax	Compiler:	gcc	PCH:	1	Flags:	
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 0.6082	 0.6078	 0.6083	 0.6085	 0.0003	 1.8245
+ sys	 0.8901	 0.8826	 0.8949	 0.8927	 0.0053	 2.6702
+wall	 1.5593	 1.5558	 1.5605	 1.5617	 0.0025	 4.6780
+
+Mode:	syntax	Compiler:	llvm-gcc	PCH:	1	Flags:	
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 0.6413	 0.6409	 0.6409	 0.6407	 0.0008	 1.9240
+ sys	 0.7872	 0.7805	 0.7805	 0.7954	 0.0062	 2.3615
+wall	 1.4837	 1.4760	 1.4760	 1.4877	 0.0054	 4.4510
+
+
+Mode:	llvm	Compiler:	clang	PCH:	0	Flags:	-O0
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 3.3512	 3.2800	 3.3205	 3.4530	 0.0739	10.0535
+ sys	 1.0991	 1.0690	 1.0833	 1.1450	 0.0330	 3.2974
+wall	 4.4934	 4.4015	 4.4394	 4.6392	 0.1043	13.4801
+
+Mode:	llvm	Compiler:	llvm-gcc	PCH:	0	Flags:	-O0
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 7.1104	 7.0581	 7.1061	 7.1670	 0.0446	21.3311
+ sys	 1.7621	 1.7462	 1.7556	 1.7845	 0.0163	 5.2863
+wall	 8.9510	 8.8993	 8.9352	 9.0187	 0.0500	26.8531
+
+Mode:	llvm	Compiler:	llvm-gcc	PCH:	1	Flags:	-O0
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 0.8446	 0.8300	 0.8499	 0.8538	 0.0104	 2.5338
+ sys	 0.8742	 0.8366	 0.8861	 0.9000	 0.0272	 2.6227
+wall	 1.7871	 1.7366	 1.8046	 1.8201	 0.0362	 5.3613
+
+
+Mode:	asm	Compiler:	clang	PCH:	0	Flags:	-O0
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 3.4794	 3.4750	 3.4794	 3.4794	 0.0035	10.4381
+ sys	 1.0876	 1.0817	 1.0874	 1.0874	 0.0049	 3.2628
+wall	 4.6112	 4.5958	 4.6223	 4.6223	 0.0112	13.8337
+	Asm Lines:	   46279
+
+Mode:	asm	Compiler:	gcc	PCH:	0	Flags:	-O0
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 6.8875	 6.7735	 6.8748	 7.0143	 0.0987	20.6626
+ sys	 1.8035	 1.7586	 1.8049	 1.8472	 0.0362	 5.4106
+wall	 8.7785	 8.6100	 8.7574	 8.9682	 0.1470	26.3356
+	Asm Lines:	   41008
+
+Mode:	asm	Compiler:	llvm-gcc	PCH:	0	Flags:	-O0
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 7.3392	 7.2327	 7.3071	 7.4779	 0.1026	22.0176
+ sys	 1.8018	 1.7703	 1.7930	 1.8420	 0.0299	 5.4053
+wall	 9.2274	 9.0793	 9.1968	 9.4062	 0.1352	27.6823
+	Asm Lines:	   47243
+
+Mode:	asm	Compiler:	gcc	PCH:	1	Flags:	-O0
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 1.0485	 1.0361	 1.0429	 1.0666	 0.0131	 3.1456
+ sys	 1.0277	 1.0097	 1.0437	 1.0296	 0.0140	 3.0830
+wall	 2.1621	 2.1181	 2.1496	 2.2185	 0.0419	 6.4862
+	Asm Lines:	   41001
+
+Mode:	asm	Compiler:	llvm-gcc	PCH:	1	Flags:	-O0
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 0.9927	 0.9898	 0.9932	 0.9951	 0.0022	 2.9781
+ sys	 0.8640	 0.8529	 0.8610	 0.8781	 0.0105	 2.5920
+wall	 1.9183	 1.9041	 1.9193	 1.9315	 0.0112	 5.7550
+	Asm Lines:	   47238
+
+
+Mode:	llvm	Compiler:	clang	PCH:	0	Flags:	-O0 -g
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 3.3843	 3.3639	 3.3719	 3.4173	 0.0235	10.1530
+ sys	 1.0862	 1.0743	 1.0789	 1.1053	 0.0136	 3.2585
+wall	 4.5248	 4.4754	 4.4906	 4.6084	 0.0595	13.5744
+
+Mode:	llvm	Compiler:	llvm-gcc	PCH:	0	Flags:	-O0 -g
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 7.4463	 7.3855	 7.3897	 7.5638	 0.0831	22.3390
+ sys	 1.7927	 1.7653	 1.7841	 1.8286	 0.0265	 5.3780
+wall	 9.3259	 9.2350	 9.2660	 9.4767	 0.1074	27.9777
+
+Mode:	llvm	Compiler:	llvm-gcc	PCH:	1	Flags:	-O0 -g
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 1.1532	 1.1527	 1.1527	 1.1556	 0.0018	 3.4596
+ sys	 0.8746	 0.8663	 0.8663	 0.8774	 0.0060	 2.6238
+wall	 2.1168	 2.0914	 2.0914	 2.1464	 0.0226	 6.3503
+
+
+Mode:	asm	Compiler:	clang	PCH:	0	Flags:	-O0 -g
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 3.6819	 3.5955	 3.7080	 3.7422	 0.0627	11.0458
+ sys	 1.1386	 1.0879	 1.1480	 1.1798	 0.0381	 3.4158
+wall	 4.8606	 4.7204	 4.8947	 4.9668	 0.1034	14.5819
+	Asm Lines:	  106056
+
+Mode:	asm	Compiler:	gcc	PCH:	0	Flags:	-O0 -g
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 7.9271	 7.8581	 7.8581	 8.0696	 0.1008	23.7814
+ sys	 2.0275	 1.9943	 1.9943	 2.0711	 0.0322	 6.0826
+wall	10.0313	 9.9266	 9.9266	10.2314	 0.1415	30.0939
+	Asm Lines:	  177342
+
+Mode:	asm	Compiler:	llvm-gcc	PCH:	0	Flags:	-O0 -g
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 7.7083	 7.6793	 7.6941	 7.6941	 0.0312	23.1249
+ sys	 1.8122	 1.7971	 1.8204	 1.8204	 0.0107	 5.4365
+wall	 9.6227	 9.5591	 9.6555	 9.6555	 0.0450	28.8682
+	Asm Lines:	  203358
+
+Mode:	asm	Compiler:	gcc	PCH:	1	Flags:	-O0 -g
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 1.2589	 1.2129	 1.2130	 1.3509	 0.0650	 3.7767
+ sys	 1.2141	 1.1467	 1.1601	 1.3355	 0.0860	 3.6423
+wall	 2.5426	 2.4325	 2.4357	 2.7596	 0.1534	 7.6278
+	Asm Lines:	  177335
+
+Mode:	asm	Compiler:	llvm-gcc	PCH:	1	Flags:	-O0 -g
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 1.4234	 1.3843	 1.4009	 1.4849	 0.0440	 4.2701
+ sys	 0.9822	 0.9153	 0.9446	 1.0867	 0.0749	 2.9466
+wall	 2.4856	 2.3713	 2.4482	 2.6372	 0.1117	 7.4567
+	Asm Lines:	  203353
+
+
+	Done:	2008-10-31_16-55
diff --git a/www/timing-data/2008-10-31/sketch-02.txt b/www/timing-data/2008-10-31/sketch-02.txt
new file mode 100644
index 0000000..88af326
--- /dev/null
+++ b/www/timing-data/2008-10-31/sketch-02.txt
@@ -0,0 +1,187 @@
+Title:	Sketch Timings
+Timestamp:	2008-10-31_16-59
+Uname:	Darwin lordcrumb.apple.com 10.0.0d3 Darwin Kernel Version 10.0.0d3: Fri Oct 24 02:12:11 PDT 2008; root:xnu-1353~2/RELEASE_I386 i386
+Path:	/Users/ddunbar/nightlytest/Sketch.ref
+Runs:	3
+
+LLVM SVN Rev.:	 58536
+
+clang:	/Users/ddunbar/llvm/Release-Asserts/bin//clang
+gcc:	/usr/bin/gcc-4.2
+llvm-gcc:	/Users/ddunbar/llvm-gcc/install/bin/llvm-gcc
+
+Mode:	Eonly	Compiler:	clang	PCH:	0	Flags:	
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 1.4030	 1.3765	 1.3887	 1.4437	 0.0293	 4.2089
+ sys	 0.8561	 0.8388	 0.8497	 0.8796	 0.0173	 2.5682
+wall	 2.2809	 2.2373	 2.2586	 2.3468	 0.0474	 6.8426
+
+Mode:	Eonly	Compiler:	gcc	PCH:	0	Flags:	
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 2.3041	 2.2821	 2.2821	 2.3563	 0.0371	 6.9123
+ sys	 1.0772	 1.0593	 1.0593	 1.0976	 0.0157	 3.2316
+wall	 3.4323	 3.3918	 3.3918	 3.4905	 0.0422	10.2970
+
+Mode:	Eonly	Compiler:	llvm-gcc	PCH:	0	Flags:	
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 2.7593	 2.7038	 2.7831	 2.7831	 0.0393	 8.2778
+ sys	 1.2805	 1.2605	 1.2868	 1.2868	 0.0144	 3.8414
+wall	 4.0893	 4.0056	 4.1319	 4.1319	 0.0592	12.2679
+
+
+Mode:	parse-noop	Compiler:	clang	PCH:	0	Flags:	
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 1.7430	 1.7252	 1.7429	 1.7610	 0.0146	 5.2291
+ sys	 0.8573	 0.8457	 0.8605	 0.8656	 0.0085	 2.5718
+wall	 2.6237	 2.5942	 2.6266	 2.6504	 0.0230	 7.8711
+
+
+Mode:	disable-free	Compiler:	clang	PCH:	0	Flags:	
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 2.7684	 2.7291	 2.7310	 2.8450	 0.0542	 8.3051
+ sys	 1.0088	 0.9948	 0.9960	 1.0356	 0.0189	 3.0263
+wall	 3.8203	 3.7581	 3.7635	 3.9394	 0.0842	11.4610
+
+
+Mode:	syntax	Compiler:	clang	PCH:	0	Flags:	
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 3.1106	 3.1115	 3.1107	 3.1095	 0.0008	 9.3317
+ sys	 1.0674	 1.0630	 1.0672	 1.0721	 0.0037	 3.2022
+wall	 4.2059	 4.2015	 4.2077	 4.2085	 0.0031	12.6176
+
+Mode:	syntax	Compiler:	gcc	PCH:	0	Flags:	
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 6.4166	 6.3461	 6.4479	 6.4559	 0.0500	19.2499
+ sys	 1.7649	 1.7256	 1.7836	 1.7854	 0.0278	 5.2946
+wall	 8.2536	 8.1547	 8.3018	 8.3045	 0.0700	24.7609
+
+Mode:	syntax	Compiler:	llvm-gcc	PCH:	0	Flags:	
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 7.0297	 6.9018	 7.0003	 7.1869	 0.1182	21.0890
+ sys	 1.7782	 1.7336	 1.7875	 1.8136	 0.0333	 5.3347
+wall	 8.8942	 8.7128	 8.8699	 9.0999	 0.1590	26.6826
+
+Mode:	syntax	Compiler:	gcc	PCH:	1	Flags:	
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 0.6133	 0.6065	 0.6089	 0.6244	 0.0079	 1.8398
+ sys	 0.9115	 0.8880	 0.9019	 0.9446	 0.0241	 2.7345
+wall	 1.5864	 1.5593	 1.5669	 1.6330	 0.0331	 4.7592
+
+Mode:	syntax	Compiler:	llvm-gcc	PCH:	1	Flags:	
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 0.6412	 0.6387	 0.6387	 0.6477	 0.0047	 1.9235
+ sys	 0.7820	 0.7654	 0.7654	 0.7955	 0.0125	 2.3461
+wall	 1.4909	 1.4783	 1.4783	 1.5124	 0.0153	 4.4726
+
+
+Mode:	llvm	Compiler:	clang	PCH:	0	Flags:	-O0
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 3.2926	 3.2939	 3.2939	 3.2998	 0.0065	 9.8778
+ sys	 1.0746	 1.0728	 1.0728	 1.0793	 0.0034	 3.2237
+wall	 4.4097	 4.4045	 4.4045	 4.4150	 0.0043	13.2290
+
+Mode:	llvm	Compiler:	llvm-gcc	PCH:	0	Flags:	-O0
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 7.3232	 7.2559	 7.3145	 7.3991	 0.0588	21.9695
+ sys	 1.8050	 1.7967	 1.7982	 1.8201	 0.0107	 5.4151
+wall	 9.2155	 9.1243	 9.2130	 9.3092	 0.0755	27.6465
+
+Mode:	llvm	Compiler:	llvm-gcc	PCH:	1	Flags:	-O0
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 0.8337	 0.8288	 0.8288	 0.8444	 0.0076	 2.5011
+ sys	 0.8575	 0.8484	 0.8484	 0.8773	 0.0140	 2.5725
+wall	 1.7973	 1.7406	 1.7406	 1.9054	 0.0764	 5.3919
+
+
+Mode:	asm	Compiler:	clang	PCH:	0	Flags:	-O0
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 3.4909	 3.4823	 3.4896	 3.4896	 0.0077	10.4728
+ sys	 1.0997	 1.1027	 1.1028	 1.1028	 0.0043	 3.2991
+wall	 4.6332	 4.6179	 4.6483	 4.6483	 0.0124	13.8996
+	Asm Lines:	   46279
+
+Mode:	asm	Compiler:	gcc	PCH:	0	Flags:	-O0
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 6.8956	 6.7882	 6.9057	 6.9929	 0.0839	20.6868
+ sys	 1.7978	 1.7703	 1.7928	 1.8302	 0.0247	 5.3933
+wall	 8.7724	 8.6360	 8.7818	 8.8994	 0.1077	26.3172
+	Asm Lines:	   41008
+
+Mode:	asm	Compiler:	llvm-gcc	PCH:	0	Flags:	-O0
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 7.2722	 7.2087	 7.3014	 7.3014	 0.0450	21.8167
+ sys	 1.8020	 1.7828	 1.8083	 1.8083	 0.0139	 5.4060
+wall	 9.1527	 9.0609	 9.2011	 9.2011	 0.0650	27.4582
+	Asm Lines:	   47243
+
+Mode:	asm	Compiler:	gcc	PCH:	1	Flags:	-O0
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 1.0563	 1.0337	 1.0373	 1.0979	 0.0294	 3.1689
+ sys	 1.0249	 0.9862	 0.9837	 1.1048	 0.0565	 3.0747
+wall	 2.1458	 2.0764	 2.0838	 2.2772	 0.0930	 6.4374
+	Asm Lines:	   41001
+
+Mode:	asm	Compiler:	llvm-gcc	PCH:	1	Flags:	-O0
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 0.9983	 0.9929	 0.9929	 1.0110	 0.0090	 2.9950
+ sys	 0.8616	 0.8525	 0.8525	 0.8822	 0.0146	 2.5849
+wall	 1.9268	 1.9061	 1.9061	 1.9632	 0.0259	 5.7804
+	Asm Lines:	   47238
+
+
+Mode:	llvm	Compiler:	clang	PCH:	0	Flags:	-O0 -g
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 3.4344	 3.3999	 3.4302	 3.4730	 0.0300	10.3032
+ sys	 1.1155	 1.0881	 1.1394	 1.1191	 0.0211	 3.3466
+wall	 4.5875	 4.5279	 4.6054	 4.6292	 0.0432	13.7626
+
+Mode:	llvm	Compiler:	llvm-gcc	PCH:	0	Flags:	-O0 -g
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 7.5996	 7.5021	 7.5389	 7.7578	 0.1129	22.7988
+ sys	 1.8546	 1.8469	 1.8262	 1.8908	 0.0270	 5.5639
+wall	 9.5392	 9.4246	 9.4575	 9.7353	 0.1394	28.6175
+
+Mode:	llvm	Compiler:	llvm-gcc	PCH:	1	Flags:	-O0 -g
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 1.1556	 1.1512	 1.1542	 1.1542	 0.0042	 3.4667
+ sys	 0.9021	 0.8890	 0.8971	 0.8971	 0.0131	 2.7062
+wall	 2.1308	 2.1126	 2.1487	 2.1487	 0.0147	 6.3924
+
+
+Mode:	asm	Compiler:	clang	PCH:	0	Flags:	-O0 -g
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 3.6020	 3.5895	 3.5904	 3.6259	 0.0169	10.8059
+ sys	 1.0967	 1.0879	 1.0879	 1.1143	 0.0124	 3.2901
+wall	 4.7362	 4.7169	 4.7182	 4.7736	 0.0264	14.2087
+	Asm Lines:	  106056
+
+Mode:	asm	Compiler:	gcc	PCH:	0	Flags:	-O0 -g
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 8.0264	 7.8409	 8.0350	 8.2033	 0.1481	24.0792
+ sys	 2.0315	 1.9767	 2.0315	 2.0864	 0.0448	 6.0946
+wall	10.1477	 9.9000	10.1584	10.3846	 0.1980	30.4430
+	Asm Lines:	  177342
+
+Mode:	asm	Compiler:	llvm-gcc	PCH:	0	Flags:	-O0 -g
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 7.8449	 7.8189	 7.8471	 7.8687	 0.0204	23.5346
+ sys	 1.8727	 1.8768	 1.8539	 1.8874	 0.0140	 5.6181
+wall	 9.8164	 9.7803	 9.8029	 9.8661	 0.0363	29.4492
+	Asm Lines:	  203358
+
+Mode:	asm	Compiler:	gcc	PCH:	1	Flags:	-O0 -g
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 1.2216	 1.2137	 1.2168	 1.2342	 0.0090	 3.6647
+ sys	 1.1771	 1.1627	 1.1630	 1.2055	 0.0201	 3.5312
+wall	 2.4619	 2.4419	 2.4429	 2.5008	 0.0275	 7.3856
+	Asm Lines:	  177335
+
+Mode:	asm	Compiler:	llvm-gcc	PCH:	1	Flags:	-O0 -g
+name	  avg  	  min  	  med  	  max  	   SD  	 total 
+user	 1.3980	 1.3682	 1.3688	 1.4569	 0.0416	 4.1939
+ sys	 0.9354	 0.8951	 0.9181	 0.9930	 0.0418	 2.8062
+wall	 2.4380	 2.3312	 2.3606	 2.6224	 0.1309	 7.3141
+	Asm Lines:	  203353
+
+
+	Done:	2008-10-31_17-08
diff --git a/www/timing-data/2008-10-31/sketch.png b/www/timing-data/2008-10-31/sketch.png
new file mode 100644
index 0000000..5ce3b11
--- /dev/null
+++ b/www/timing-data/2008-10-31/sketch.png
Binary files differ
diff --git a/www/timing-data/2009-03-02/176.gcc.pdf b/www/timing-data/2009-03-02/176.gcc.pdf
new file mode 100644
index 0000000..0b2e610
--- /dev/null
+++ b/www/timing-data/2009-03-02/176.gcc.pdf
Binary files differ
diff --git a/www/timing-data/2009-03-02/176.gcc.png b/www/timing-data/2009-03-02/176.gcc.png
new file mode 100644
index 0000000..4ae08e1
--- /dev/null
+++ b/www/timing-data/2009-03-02/176.gcc.png
Binary files differ
diff --git a/www/timing-data/2009-03-02/176.gcc.txt b/www/timing-data/2009-03-02/176.gcc.txt
new file mode 100644
index 0000000..f965e97
--- /dev/null
+++ b/www/timing-data/2009-03-02/176.gcc.txt
@@ -0,0 +1,1120 @@
+ccc_path = """/Volumes/Data/ddunbar/llvm.install/bin/ccc"""
+ccc_clang = """/Volumes/Data/ddunbar/zorg/xcb_scripts/cc/xcc.fb"""
+ccc_gcc = """/Volumes/Data/ddunbar/zorg/xcb_scripts/cc/xcc.fb -ccc-no-clang"""
+gcc = """/usr/bin/gcc-4.2"""
+ccc_clang_info = """
+ccc version 1.0 (https://ddunbar@llvm.org/svn/llvm-project/cfe/trunk)
+ "/Volumes/Data/ddunbar/llvm.install/bin/clang" "-S" "-disable-free" "--relocation-model=pic" "--disable-fp-elim" "--nozero-initialized-in-bss" "--unwind-tables=1" "--mcpu=core2" "--fmath-errno=0" "-mmacosx-version-min=10.6.0" "-arch" "x86_64" "-o" "/tmp/tmp62ee6x.s" "-x" "c" "/dev/null"
+ "/usr/libexec/gcc/i686-apple-darwin10/4.2.1/as" "-arch" "x86_64" "-force_cpusubtype_ALL" "-o" "/tmp/tmpyLxO26.o" "/tmp/tmp62ee6x.s"
+ "/usr/libexec/gcc/i686-apple-darwin10/4.2.1/collect2" "-dynamic" "-arch" "x86_64" "-macosx_version_min" "10.6.0" "-weak_reference_mismatches" "non-weak" "-o" "a.out" "-lcrt1.10.5.o" "-L/usr/lib/gcc/i686-apple-darwin10/4.2.1/x86_64" "-L/usr/lib/gcc/i686-apple-darwin10/4.2.1/x86_64" "-L/usr/lib/i686-apple-darwin10/4.2.1" "-L/usr/lib/gcc/i686-apple-darwin10/4.2.1" "-L/usr/lib/gcc/i686-apple-darwin10/4.2.1" "-L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../../i686-apple-darwin10/4.2.1" "-L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../.." "/tmp/tmpyLxO26.o" "-lgcc_s.10.5" "-lgcc" "-lSystem"
+"""
+ccc_gcc_info = """
+ccc version 1.0 (https://ddunbar@llvm.org/svn/llvm-project/cfe/trunk)
+ "/usr/libexec/gcc/i686-apple-darwin10/4.2.1/cc1" "-quiet" "-imultilib" "x86_64" "-D__DYNAMIC__" "/dev/null" "-fPIC" "-quiet" "-dumpbase" "null" "-mmacosx-version-min=10.6.0" "-m64" "-mtune=core2" "-auxbase" "null" "-o" "/tmp/tmpDx0Rtr.s"
+ "/usr/libexec/gcc/i686-apple-darwin10/4.2.1/as" "-arch" "x86_64" "-force_cpusubtype_ALL" "-o" "/tmp/tmpNbvYrM.o" "/tmp/tmpDx0Rtr.s"
+ "/usr/libexec/gcc/i686-apple-darwin10/4.2.1/collect2" "-dynamic" "-arch" "x86_64" "-macosx_version_min" "10.6.0" "-weak_reference_mismatches" "non-weak" "-o" "a.out" "-lcrt1.10.5.o" "-L/usr/lib/gcc/i686-apple-darwin10/4.2.1/x86_64" "-L/usr/lib/gcc/i686-apple-darwin10/4.2.1/x86_64" "-L/usr/lib/i686-apple-darwin10/4.2.1" "-L/usr/lib/gcc/i686-apple-darwin10/4.2.1" "-L/usr/lib/gcc/i686-apple-darwin10/4.2.1" "-L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../../i686-apple-darwin10/4.2.1" "-L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../.." "/tmp/tmpNbvYrM.o" "-lgcc_s.10.5" "-lgcc" "-lSystem"
+"""
+gcc_info = """
+Using built-in specs.
+Target: i686-apple-darwin10
+Configured with: /var/tmp/gcc/gcc-5641~3/src/configure --disable-checking --enable-werror --prefix=/usr --mandir=/share/man --enable-languages=c,objc,c++,obj-c++ --program-transform-name=/^[cg][^.-]*$/s/$/-4.2/ --with-slibdir=/usr/lib --build=i686-apple-darwin10 --with-gxx-include-dir=/include/c++/4.2.1 --program-prefix=i686-apple-darwin10- --host=x86_64-apple-darwin10 --target=i686-apple-darwin10
+Thread model: posix
+gcc version 4.2.1 (Apple Inc. build 5641)
+ "/usr/libexec/gcc/i686-apple-darwin10/4.2.1/cc1" "-quiet" "-imultilib" "x86_64" "-D__DYNAMIC__" "/dev/null" "-fPIC" "-quiet" "-dumpbase" "null" "-mmacosx-version-min=10.6.0" "-m64" "-mtune=core2" "-auxbase" "null" "-o" "/var/tmp//ccDnCoVC.s"
+ "/usr/libexec/gcc/i686-apple-darwin10/4.2.1/as" "-arch" "x86_64" "-force_cpusubtype_ALL" "-o" "/var/tmp//ccwsOXBR.o" "/var/tmp//ccDnCoVC.s"
+ "/usr/libexec/gcc/i686-apple-darwin10/4.2.1/collect2" "-dynamic" "-arch" "x86_64" "-macosx_version_min" "10.6.0" "-weak_reference_mismatches" "non-weak" "-o" "a.out" "-lcrt1.10.6.o" "-L/usr/lib/gcc/i686-apple-darwin10/4.2.1/x86_64" "-L/usr/lib/gcc/i686-apple-darwin10/4.2.1/x86_64" "-L/usr/lib/i686-apple-darwin10/4.2.1" "-L/usr/lib/gcc/i686-apple-darwin10/4.2.1" "-L/usr/lib/gcc/i686-apple-darwin10/4.2.1" "-L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../../i686-apple-darwin10/4.2.1" "-L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../.." "/var/tmp//ccwsOXBR.o" "-lgcc" "-lSystem"
+"""
+style = """make"""
+runs = []
+runs.append(( { 'cc':"ccc_clang",
+                'script':"null",
+                'threads':"1",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.041626, 0.067272, 0.122191),
+	(1, 0.041643, 0.067045, 0.122192),
+	(2, 0.041655, 0.067055, 0.121649),
+	(3, 0.041562, 0.066648, 0.121432),
+	(4, 0.041613, 0.066810, 0.121305),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"null",
+                'threads':"1",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.041606, 0.066993, 0.121704),
+	(1, 0.041581, 0.066630, 0.121471),
+	(2, 0.041602, 0.066922, 0.121765),
+	(3, 0.041581, 0.066859, 0.121405),
+	(4, 0.041689, 0.066980, 0.124326),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"null",
+                'threads':"1",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.041675, 0.067138, 0.121728),
+	(1, 0.041612, 0.066859, 0.121205),
+	(2, 0.041580, 0.066483, 0.120964),
+	(3, 0.041594, 0.066483, 0.120985),
+	(4, 0.041568, 0.066532, 0.120499),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"###",
+                'threads':"1",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 2.186639, 1.937014, 4.437061),
+	(1, 2.186681, 1.945610, 4.433872),
+	(2, 2.188041, 1.947231, 4.462319),
+	(3, 2.188190, 1.943516, 4.470365),
+	(4, 2.187020, 1.950682, 4.436890),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"###",
+                'threads':"1",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 2.195748, 1.947951, 4.443053),
+	(1, 2.194402, 1.940449, 4.432535),
+	(2, 2.195423, 1.943498, 4.447053),
+	(3, 2.196253, 1.950332, 4.448664),
+	(4, 2.195660, 1.942226, 4.437071),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"###",
+                'threads':"1",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.136111, 0.313413, 0.499384),
+	(1, 0.136203, 0.313310, 0.500697),
+	(2, 0.136639, 0.314917, 0.558877),
+	(3, 0.136173, 0.313843, 0.501008),
+	(4, 0.135965, 0.312723, 0.498594),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"cpp",
+                'threads':"1",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 2.819676, 2.374582, 5.801642),
+	(1, 2.819568, 2.375962, 5.525720),
+	(2, 2.819725, 2.377977, 5.526612),
+	(3, 2.819563, 2.374766, 5.525245),
+	(4, 2.820020, 2.378179, 5.531853),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"parse",
+                'threads':"1",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 2.979842, 2.393759, 5.773241),
+	(1, 2.978360, 2.388217, 5.699588),
+	(2, 2.979615, 2.392749, 5.713015),
+	(3, 2.978055, 2.388861, 5.697303),
+	(4, 2.979260, 2.390138, 5.710568),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"syntax",
+                'threads':"1",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 3.525414, 2.495433, 6.457547),
+	(1, 3.523990, 2.498728, 6.378505),
+	(2, 3.523183, 2.492712, 6.370535),
+	(3, 3.523363, 2.494413, 6.376960),
+	(4, 3.525216, 2.501657, 6.413753),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"syntax",
+                'threads':"1",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 6.143927, 2.857721, 9.407785),
+	(1, 6.144766, 2.871091, 9.396498),
+	(2, 6.143893, 2.860256, 9.392155),
+	(3, 6.146454, 2.866420, 9.447510),
+	(4, 6.146771, 2.864488, 9.664806),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"syntax",
+                'threads':"1",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 3.975961, 1.044303, 5.199328),
+	(1, 3.976843, 1.044060, 5.209434),
+	(2, 3.976622, 1.043787, 5.223585),
+	(3, 3.975836, 1.043403, 5.198575),
+	(4, 3.975980, 1.035674, 5.196275),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"irgen",
+                'threads':"1",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 5.707728, 2.859466, 9.115580),
+	(1, 5.709064, 2.858221, 9.094858),
+	(2, 5.707868, 2.868881, 9.006296),
+	(3, 5.706836, 2.856589, 8.998487),
+	(4, 5.706603, 2.857047, 9.028045),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"only_asm",
+                'threads':"1",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 7.855523, 3.041195, 11.679531),
+	(1, 7.855184, 3.046897, 11.389012),
+	(2, 7.855530, 3.039149, 11.435265),
+	(3, 7.856299, 3.037483, 11.382391),
+	(4, 7.854147, 3.043133, 11.373174),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"only_asm",
+                'threads':"1",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 10.926280, 3.168833, 14.542014),
+	(1, 10.931726, 3.174573, 14.573554),
+	(2, 10.933809, 3.163183, 14.857843),
+	(3, 10.927966, 3.164824, 14.543822),
+	(4, 10.927423, 3.166222, 14.658131),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"only_asm",
+                'threads':"1",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 8.755856, 1.342961, 10.311273),
+	(1, 8.756782, 1.346296, 10.314137),
+	(2, 8.760167, 1.338744, 10.442545),
+	(3, 8.759031, 1.346241, 10.333765),
+	(4, 8.758174, 1.339294, 10.328992),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"only_compile",
+                'threads':"1",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 9.159773, 3.431851, 13.319311),
+	(1, 9.156190, 3.421113, 13.203571),
+	(2, 9.157752, 3.417859, 13.220865),
+	(3, 9.156178, 3.413504, 13.204341),
+	(4, 9.150167, 3.412242, 13.252471),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"only_compile",
+                'threads':"1",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 12.062994, 3.497204, 16.184210),
+	(1, 12.065757, 3.486858, 16.503552),
+	(2, 12.063830, 3.499430, 16.171503),
+	(3, 12.065427, 3.500838, 16.268848),
+	(4, 12.063384, 3.503007, 16.164980),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"only_compile",
+                'threads':"1",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 9.836694, 1.570806, 11.863629),
+	(1, 9.835162, 1.580921, 11.762224),
+	(2, 9.836416, 1.572111, 11.893337),
+	(3, 9.835066, 1.571860, 11.751330),
+	(4, 9.836771, 1.575158, 11.783299),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"all",
+                'threads':"1",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 9.262905, 3.437217, 13.459870),
+	(1, 9.262539, 3.446216, 13.349994),
+	(2, 9.260750, 3.445077, 13.357125),
+	(3, 9.263932, 3.448647, 13.366228),
+	(4, 9.258133, 3.443125, 13.369278),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"all",
+                'threads':"1",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 12.163348, 3.513017, 16.559292),
+	(1, 12.159476, 3.526493, 16.430252),
+	(2, 12.157784, 3.513763, 16.306505),
+	(3, 12.159307, 3.530832, 16.495815),
+	(4, 12.160843, 3.516564, 16.331499),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"all",
+                'threads':"1",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 9.945925, 1.592199, 11.971326),
+	(1, 9.944375, 1.603629, 11.899797),
+	(2, 9.945863, 1.601172, 11.917642),
+	(3, 9.946878, 1.601530, 12.113196),
+	(4, 9.943168, 1.596300, 11.910257),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"null",
+                'threads':"2",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.042234, 0.072110, 0.068216),
+	(1, 0.042155, 0.071582, 0.067917),
+	(2, 0.042120, 0.071280, 0.067838),
+	(3, 0.042134, 0.071281, 0.067688),
+	(4, 0.042182, 0.071185, 0.068571),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"null",
+                'threads':"2",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.042195, 0.072394, 0.067753),
+	(1, 0.042154, 0.071378, 0.067667),
+	(2, 0.042126, 0.071503, 0.067645),
+	(3, 0.042142, 0.071525, 0.067641),
+	(4, 0.042137, 0.071263, 0.067512),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"null",
+                'threads':"2",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.042117, 0.071863, 0.067866),
+	(1, 0.042095, 0.071587, 0.067778),
+	(2, 0.042123, 0.071824, 0.067718),
+	(3, 0.042017, 0.071448, 0.067336),
+	(4, 0.042098, 0.071669, 0.067649),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"###",
+                'threads':"2",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 2.312764, 2.250083, 2.579668),
+	(1, 2.313524, 2.255599, 2.581617),
+	(2, 2.314576, 2.236269, 2.751308),
+	(3, 2.313798, 2.247632, 2.576000),
+	(4, 2.308146, 2.127675, 2.449384),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"###",
+                'threads':"2",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 2.319161, 2.248583, 2.579843),
+	(1, 2.320569, 2.254949, 2.582595),
+	(2, 2.319615, 2.254838, 2.582868),
+	(3, 2.317640, 2.234440, 2.566378),
+	(4, 2.319468, 2.253768, 2.582185),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"###",
+                'threads':"2",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.138760, 0.342468, 0.274713),
+	(1, 0.138529, 0.338083, 0.270603),
+	(2, 0.138419, 0.339997, 0.272035),
+	(3, 0.138474, 0.339942, 0.271676),
+	(4, 0.138476, 0.339545, 0.271208),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"cpp",
+                'threads':"2",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 2.927601, 2.621882, 3.040263),
+	(1, 2.928817, 2.618327, 3.042979),
+	(2, 2.925842, 2.616328, 3.034669),
+	(3, 2.933845, 2.642455, 3.077028),
+	(4, 2.947212, 2.620121, 3.167388),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"parse",
+                'threads':"2",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 3.095391, 2.632837, 3.130378),
+	(1, 3.096120, 2.626309, 3.120448),
+	(2, 3.095708, 2.622912, 3.125333),
+	(3, 3.096435, 2.628234, 3.124718),
+	(4, 3.095836, 2.623590, 3.124194),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"syntax",
+                'threads':"2",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 3.674570, 2.716479, 3.444615),
+	(1, 3.673243, 2.720120, 3.443432),
+	(2, 3.673080, 2.709820, 3.443546),
+	(3, 3.673200, 2.709185, 3.426130),
+	(4, 3.670534, 2.711744, 3.427015),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"syntax",
+                'threads':"2",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 6.389665, 3.072630, 4.983543),
+	(1, 6.385878, 3.080763, 4.975980),
+	(2, 6.389956, 3.069652, 4.982242),
+	(3, 6.388396, 3.078156, 4.977871),
+	(4, 6.391305, 3.090905, 4.994381),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"syntax",
+                'threads':"2",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 4.079359, 1.112710, 2.692685),
+	(1, 4.077052, 1.114109, 2.689234),
+	(2, 4.078218, 1.119202, 2.693919),
+	(3, 4.077124, 1.108491, 2.690559),
+	(4, 4.077296, 1.112142, 2.684408),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"irgen",
+                'threads':"2",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 6.043907, 3.082369, 4.874229),
+	(1, 6.044110, 3.072240, 4.860724),
+	(2, 6.049991, 3.085666, 4.927778),
+	(3, 6.050681, 3.087747, 4.866959),
+	(4, 6.046383, 3.081174, 4.865700),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"only_asm",
+                'threads':"2",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 8.277376, 3.241075, 6.041627),
+	(1, 8.274767, 3.246052, 6.032635),
+	(2, 8.273632, 3.240323, 6.034355),
+	(3, 8.283322, 3.235898, 6.055232),
+	(4, 8.279572, 3.237813, 6.040545),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"only_asm",
+                'threads':"2",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 11.267468, 3.368598, 7.582008),
+	(1, 11.264991, 3.356817, 7.573902),
+	(2, 11.258736, 3.371794, 7.616322),
+	(3, 11.272174, 3.375177, 7.750662),
+	(4, 11.265369, 3.355828, 7.569228),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"only_asm",
+                'threads':"2",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 8.948892, 1.408841, 5.346675),
+	(1, 8.947425, 1.388794, 5.341078),
+	(2, 8.959290, 1.397633, 5.703015),
+	(3, 8.948915, 1.391639, 5.351654),
+	(4, 8.946706, 1.404458, 5.345449),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"only_compile",
+                'threads':"2",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 9.576401, 3.659016, 6.972346),
+	(1, 9.577255, 3.641158, 6.953448),
+	(2, 9.572443, 3.647954, 7.051130),
+	(3, 9.571615, 3.646782, 6.956555),
+	(4, 9.572963, 3.653229, 6.957711),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"only_compile",
+                'threads':"2",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 12.425333, 3.720605, 8.468826),
+	(1, 12.420657, 3.729020, 8.648778),
+	(2, 12.424221, 3.709511, 8.467562),
+	(3, 12.425595, 3.726297, 8.449276),
+	(4, 12.422584, 3.718660, 8.713483),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"only_compile",
+                'threads':"2",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 10.042865, 1.647364, 6.147098),
+	(1, 10.038624, 1.646965, 6.107788),
+	(2, 10.036193, 1.643319, 6.100944),
+	(3, 10.037764, 1.637319, 6.121365),
+	(4, 10.044532, 1.648919, 6.354301),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"all",
+                'threads':"2",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 9.686781, 3.657538, 7.098294),
+	(1, 9.679355, 3.674326, 7.109849),
+	(2, 9.678938, 3.659032, 7.093127),
+	(3, 9.683371, 3.655282, 7.396885),
+	(4, 9.677578, 3.661111, 7.086666),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"all",
+                'threads':"2",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 12.511083, 3.753316, 8.574587),
+	(1, 12.517391, 3.745202, 8.579089),
+	(2, 12.515167, 3.747517, 8.906780),
+	(3, 12.510503, 3.744116, 8.561728),
+	(4, 12.516263, 3.740046, 8.578455),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"all",
+                'threads':"2",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 10.139224, 1.659640, 6.213839),
+	(1, 10.144829, 1.668260, 6.423697),
+	(2, 10.144182, 1.670476, 6.213931),
+	(3, 10.144068, 1.658834, 6.211693),
+	(4, 10.138223, 1.667654, 6.222308),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"null",
+                'threads':"4",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.044057, 0.093485, 0.045956),
+	(1, 0.044004, 0.092769, 0.045605),
+	(2, 0.043901, 0.092551, 0.045247),
+	(3, 0.043818, 0.091785, 0.045295),
+	(4, 0.043924, 0.091899, 0.045216),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"null",
+                'threads':"4",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.043938, 0.092531, 0.045317),
+	(1, 0.043985, 0.092990, 0.045413),
+	(2, 0.043847, 0.091943, 0.044986),
+	(3, 0.043889, 0.091626, 0.045207),
+	(4, 0.043936, 0.091446, 0.045068),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"null",
+                'threads':"4",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.043935, 0.092137, 0.045550),
+	(1, 0.044036, 0.092432, 0.045443),
+	(2, 0.043907, 0.092597, 0.045207),
+	(3, 0.043906, 0.092773, 0.045220),
+	(4, 0.043932, 0.092273, 0.045162),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"###",
+                'threads':"4",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 2.510229, 2.524326, 1.447378),
+	(1, 2.511153, 2.582682, 1.463158),
+	(2, 2.509131, 2.551808, 1.443700),
+	(3, 2.530506, 2.606601, 1.631594),
+	(4, 2.525546, 2.556516, 1.460912),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"###",
+                'threads':"4",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 2.519330, 2.572381, 1.455862),
+	(1, 2.519059, 2.662137, 1.521106),
+	(2, 2.506144, 2.556738, 1.456221),
+	(3, 2.511366, 2.577441, 1.459606),
+	(4, 2.526218, 2.553722, 1.574747),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"###",
+                'threads':"4",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.147023, 0.430956, 0.176525),
+	(1, 0.147430, 0.429136, 0.175834),
+	(2, 0.146893, 0.428812, 0.175145),
+	(3, 0.147174, 0.429968, 0.175169),
+	(4, 0.147492, 0.431385, 0.174682),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"cpp",
+                'threads':"4",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 3.167799, 3.158706, 1.805685),
+	(1, 3.167239, 3.135936, 1.802571),
+	(2, 3.157960, 3.130196, 1.803330),
+	(3, 3.146711, 3.153077, 1.813078),
+	(4, 3.149927, 3.152081, 1.801526),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"parse",
+                'threads':"4",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 3.342516, 3.109718, 1.823208),
+	(1, 3.353297, 3.103074, 1.819566),
+	(2, 3.333260, 3.149734, 1.829796),
+	(3, 3.338234, 3.103725, 1.822010),
+	(4, 3.336550, 3.100652, 1.832110),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"syntax",
+                'threads':"4",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 3.970523, 3.209725, 1.991844),
+	(1, 3.937210, 3.198855, 1.976041),
+	(2, 3.955488, 3.206959, 1.989544),
+	(3, 3.946574, 3.198149, 1.980601),
+	(4, 3.948581, 3.205880, 1.983994),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"syntax",
+                'threads':"4",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 6.732216, 3.619584, 2.782476),
+	(1, 6.745420, 3.616948, 2.790903),
+	(2, 6.750526, 3.594650, 2.790881),
+	(3, 6.738845, 3.612443, 2.790569),
+	(4, 6.747457, 3.617553, 2.788687),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"syntax",
+                'threads':"4",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 4.194680, 1.292044, 1.444048),
+	(1, 4.190321, 1.300927, 1.441506),
+	(2, 4.198820, 1.293219, 1.444174),
+	(3, 4.209445, 1.289162, 1.447259),
+	(4, 4.187489, 1.282234, 1.440277),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"irgen",
+                'threads':"4",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 6.517757, 3.615464, 2.854763),
+	(1, 6.519460, 3.617775, 2.756124),
+	(2, 6.498704, 3.602169, 2.756365),
+	(3, 6.509982, 3.621462, 2.745702),
+	(4, 6.489827, 3.608797, 2.747793),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"only_asm",
+                'threads':"4",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 8.825143, 3.794072, 3.362608),
+	(1, 8.824013, 3.765690, 3.355471),
+	(2, 8.813541, 3.783641, 3.357039),
+	(3, 8.786371, 3.786659, 3.345793),
+	(4, 8.772730, 3.771638, 3.454307),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"only_asm",
+                'threads':"4",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 11.738484, 3.836784, 4.120546),
+	(1, 11.739288, 3.848616, 4.125808),
+	(2, 11.738261, 3.837534, 4.136642),
+	(3, 11.735003, 3.844597, 4.120444),
+	(4, 11.761638, 3.862457, 4.145417),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"only_asm",
+                'threads':"4",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 9.155087, 1.561075, 2.833868),
+	(1, 9.154934, 1.538791, 2.833134),
+	(2, 9.183035, 1.553281, 2.902132),
+	(3, 9.151130, 1.546822, 2.879777),
+	(4, 9.151844, 1.542450, 2.825560),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"only_compile",
+                'threads':"4",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 10.166988, 4.242308, 3.894601),
+	(1, 10.218686, 4.265537, 3.896997),
+	(2, 10.208211, 4.256174, 3.905990),
+	(3, 10.182169, 4.254989, 4.094963),
+	(4, 10.165336, 4.239672, 3.873703),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"only_compile",
+                'threads':"4",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 12.960833, 4.319633, 4.628599),
+	(1, 12.997509, 4.323695, 4.942418),
+	(2, 12.940625, 4.326994, 4.624419),
+	(3, 12.947641, 4.300034, 4.597456),
+	(4, 12.942562, 4.308688, 4.619190),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"only_compile",
+                'threads':"4",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 10.300396, 1.823967, 3.250894),
+	(1, 10.305252, 1.822285, 3.244746),
+	(2, 10.307011, 1.845773, 3.260861),
+	(3, 10.319953, 1.831435, 3.500671),
+	(4, 10.320805, 1.834782, 3.246639),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"all",
+                'threads':"4",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 10.297812, 4.264184, 4.013061),
+	(1, 10.315407, 4.293257, 4.021099),
+	(2, 10.257966, 4.265659, 4.006248),
+	(3, 10.307857, 4.273741, 4.044614),
+	(4, 10.273398, 4.260286, 4.216469),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"all",
+                'threads':"4",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 13.040233, 4.302015, 4.719135),
+	(1, 13.046999, 4.316412, 5.773880),
+	(2, 13.081143, 4.324329, 4.745519),
+	(3, 13.025611, 4.311093, 4.738916),
+	(4, 13.063041, 4.336277, 4.771969),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"all",
+                'threads':"4",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 10.419745, 1.855515, 3.343652),
+	(1, 10.447391, 1.858839, 3.374031),
+	(2, 10.428436, 1.866242, 3.381289),
+	(3, 10.428931, 1.879273, 3.582034),
+	(4, 10.410715, 1.836761, 3.371333),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"null",
+                'threads':"8",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.044629, 0.104236, 0.047124),
+	(1, 0.044357, 0.101072, 0.046054),
+	(2, 0.044261, 0.099350, 0.045512),
+	(3, 0.044279, 0.099032, 0.045401),
+	(4, 0.044291, 0.098233, 0.045262),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"null",
+                'threads':"8",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.044388, 0.101047, 0.045972),
+	(1, 0.044267, 0.100816, 0.045836),
+	(2, 0.044319, 0.100931, 0.045829),
+	(3, 0.044242, 0.102208, 0.046286),
+	(4, 0.044197, 0.101894, 0.046310),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"null",
+                'threads':"8",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.044199, 0.099476, 0.045336),
+	(1, 0.044064, 0.099032, 0.045431),
+	(2, 0.044081, 0.097169, 0.044910),
+	(3, 0.044055, 0.099088, 0.044957),
+	(4, 0.044322, 0.099454, 0.045563),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"###",
+                'threads':"8",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 2.768949, 3.566605, 1.008622),
+	(1, 2.753933, 3.515221, 1.011067),
+	(2, 2.790210, 3.581213, 1.006835),
+	(3, 2.742393, 3.612996, 1.065939),
+	(4, 2.783563, 3.457715, 0.977203),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"###",
+                'threads':"8",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 2.803126, 3.542212, 1.140376),
+	(1, 2.794538, 3.523127, 1.000266),
+	(2, 2.821545, 3.533185, 0.996633),
+	(3, 2.754702, 3.604113, 1.127400),
+	(4, 2.773800, 3.590831, 1.023085),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"###",
+                'threads':"8",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.162694, 0.629660, 0.131824),
+	(1, 0.162231, 0.630903, 0.131937),
+	(2, 0.162713, 0.636833, 0.133010),
+	(3, 0.163527, 0.627696, 0.130973),
+	(4, 0.162591, 0.628073, 0.128269),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"cpp",
+                'threads':"8",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 3.398995, 4.386961, 1.222372),
+	(1, 3.433913, 4.302404, 1.191109),
+	(2, 3.403972, 4.249079, 1.179600),
+	(3, 3.430418, 4.241026, 1.173406),
+	(4, 3.405708, 4.295249, 1.192367),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"parse",
+                'threads':"8",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 3.589608, 4.234909, 1.206952),
+	(1, 3.595580, 4.250801, 1.195809),
+	(2, 3.598782, 4.186360, 1.189533),
+	(3, 3.576135, 4.210771, 1.192198),
+	(4, 3.596508, 4.272774, 1.195682),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"syntax",
+                'threads':"8",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 4.188318, 4.323380, 1.272841),
+	(1, 4.204432, 4.301331, 1.276169),
+	(2, 4.232123, 4.359346, 1.308850),
+	(3, 4.254709, 4.295013, 1.277959),
+	(4, 4.214074, 4.293825, 1.275462),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"syntax",
+                'threads':"8",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 7.056727, 4.672983, 1.677022),
+	(1, 7.064183, 4.697158, 1.685536),
+	(2, 7.013256, 4.653804, 1.669026),
+	(3, 7.077917, 4.720479, 1.692836),
+	(4, 7.028864, 4.654591, 1.674130),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"syntax",
+                'threads':"8",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 4.250811, 1.598520, 0.822128),
+	(1, 4.255341, 1.616523, 0.819562),
+	(2, 4.282720, 1.628032, 0.823764),
+	(3, 4.296236, 1.628292, 0.828753),
+	(4, 4.263254, 1.614337, 0.822968),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"irgen",
+                'threads':"8",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 6.828563, 4.698920, 1.665128),
+	(1, 6.887088, 4.678607, 1.660858),
+	(2, 6.867776, 4.703203, 1.657673),
+	(3, 6.841523, 4.645255, 1.637169),
+	(4, 6.904172, 4.682556, 1.690968),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"only_asm",
+                'threads':"8",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 9.164624, 4.728257, 2.026243),
+	(1, 9.258789, 4.757386, 1.996115),
+	(2, 9.215979, 4.740186, 1.995604),
+	(3, 9.241390, 4.750833, 2.007054),
+	(4, 9.161773, 4.742841, 1.987729),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"only_asm",
+                'threads':"8",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 12.113609, 4.726450, 2.385739),
+	(1, 12.121322, 4.784194, 2.416434),
+	(2, 12.095256, 4.762198, 2.394130),
+	(3, 12.125848, 4.743744, 2.386863),
+	(4, 12.117883, 4.759723, 2.384746),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"only_asm",
+                'threads':"8",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 9.196017, 1.794764, 1.538604),
+	(1, 9.293693, 1.830825, 1.559088),
+	(2, 9.210498, 1.813935, 1.538989),
+	(3, 9.207860, 1.799598, 1.536893),
+	(4, 9.202729, 1.797648, 1.530905),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"only_compile",
+                'threads':"8",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 10.574802, 5.298921, 2.539728),
+	(1, 10.657320, 5.376201, 2.329437),
+	(2, 10.650595, 5.345177, 2.311878),
+	(3, 10.611628, 5.366770, 2.319432),
+	(4, 10.599574, 5.358888, 2.479782),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"only_compile",
+                'threads':"8",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 13.432160, 5.417611, 2.691172),
+	(1, 13.443341, 5.377409, 2.678012),
+	(2, 13.343336, 5.338212, 2.812471),
+	(3, 13.333183, 5.333529, 2.687594),
+	(4, 13.384371, 5.414969, 2.837339),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"only_compile",
+                'threads':"8",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 10.381974, 2.152140, 1.786428),
+	(1, 10.378996, 2.143003, 1.774503),
+	(2, 10.453921, 2.187323, 1.794154),
+	(3, 10.398109, 2.212740, 2.013101),
+	(4, 10.435604, 2.197729, 1.779200),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"all",
+                'threads':"8",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 10.786656, 5.383657, 2.435159),
+	(1, 10.689933, 5.362047, 2.435158),
+	(2, 10.761754, 5.406655, 2.462640),
+	(3, 10.760319, 5.401706, 2.571526),
+	(4, 10.666932, 5.361587, 2.444485),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"all",
+                'threads':"8",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 13.519919, 5.421898, 2.821722),
+	(1, 13.447262, 5.364940, 2.926024),
+	(2, 13.464838, 5.369476, 2.802961),
+	(3, 13.514555, 5.440290, 2.831226),
+	(4, 13.443975, 5.410124, 2.947296),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"all",
+                'threads':"8",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 10.498388, 2.171118, 2.153460),
+	(1, 10.524313, 2.175829, 1.899075),
+	(2, 10.502688, 2.185754, 1.894639),
+	(3, 10.498667, 2.201617, 1.888811),
+	(4, 10.488970, 2.166527, 1.885400),
+]}
+))
diff --git a/www/timing-data/2009-03-02/sketch.pdf b/www/timing-data/2009-03-02/sketch.pdf
new file mode 100644
index 0000000..3b98a3d
--- /dev/null
+++ b/www/timing-data/2009-03-02/sketch.pdf
Binary files differ
diff --git a/www/timing-data/2009-03-02/sketch.png b/www/timing-data/2009-03-02/sketch.png
new file mode 100644
index 0000000..3d1bc14
--- /dev/null
+++ b/www/timing-data/2009-03-02/sketch.png
Binary files differ
diff --git a/www/timing-data/2009-03-02/sketch.txt b/www/timing-data/2009-03-02/sketch.txt
new file mode 100644
index 0000000..d2270e4
--- /dev/null
+++ b/www/timing-data/2009-03-02/sketch.txt
@@ -0,0 +1,2368 @@
+ccc_path = """/Volumes/Data/ddunbar/llvm.install/bin/ccc"""
+ccc_clang = """/Volumes/Data/ddunbar/zorg/xcb_scripts/cc/xcc.fb"""
+ccc_gcc = """/Volumes/Data/ddunbar/zorg/xcb_scripts/cc/xcc.fb -ccc-no-clang"""
+gcc = """/usr/bin/gcc-4.2"""
+ccc_clang_info = """
+ccc version 1.0 (https://ddunbar@llvm.org/svn/llvm-project/cfe/trunk)
+ "/Volumes/Data/ddunbar/llvm.install/bin/clang" "-S" "-disable-free" "--relocation-model=pic" "--disable-fp-elim" "--nozero-initialized-in-bss" "--unwind-tables=1" "--mcpu=core2" "--fmath-errno=0" "-mmacosx-version-min=10.6.0" "-arch" "x86_64" "-o" "/tmp/tmpugUQni.s" "-x" "c" "/dev/null"
+ "/usr/libexec/gcc/i686-apple-darwin10/4.2.1/as" "-arch" "x86_64" "-force_cpusubtype_ALL" "-o" "/tmp/tmpH8AOZI.o" "/tmp/tmpugUQni.s"
+ "/usr/libexec/gcc/i686-apple-darwin10/4.2.1/collect2" "-dynamic" "-arch" "x86_64" "-macosx_version_min" "10.6.0" "-weak_reference_mismatches" "non-weak" "-o" "a.out" "-lcrt1.10.5.o" "-L/usr/lib/gcc/i686-apple-darwin10/4.2.1/x86_64" "-L/usr/lib/gcc/i686-apple-darwin10/4.2.1/x86_64" "-L/usr/lib/i686-apple-darwin10/4.2.1" "-L/usr/lib/gcc/i686-apple-darwin10/4.2.1" "-L/usr/lib/gcc/i686-apple-darwin10/4.2.1" "-L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../../i686-apple-darwin10/4.2.1" "-L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../.." "/tmp/tmpH8AOZI.o" "-lgcc_s.10.5" "-lgcc" "-lSystem"
+"""
+ccc_gcc_info = """
+ccc version 1.0 (https://ddunbar@llvm.org/svn/llvm-project/cfe/trunk)
+ "/usr/libexec/gcc/i686-apple-darwin10/4.2.1/cc1" "-quiet" "-imultilib" "x86_64" "-D__DYNAMIC__" "/dev/null" "-fPIC" "-quiet" "-dumpbase" "null" "-mmacosx-version-min=10.6.0" "-m64" "-mtune=core2" "-auxbase" "null" "-o" "/tmp/tmpTiOyJZ.s"
+ "/usr/libexec/gcc/i686-apple-darwin10/4.2.1/as" "-arch" "x86_64" "-force_cpusubtype_ALL" "-o" "/tmp/tmpTi0lCN.o" "/tmp/tmpTiOyJZ.s"
+ "/usr/libexec/gcc/i686-apple-darwin10/4.2.1/collect2" "-dynamic" "-arch" "x86_64" "-macosx_version_min" "10.6.0" "-weak_reference_mismatches" "non-weak" "-o" "a.out" "-lcrt1.10.5.o" "-L/usr/lib/gcc/i686-apple-darwin10/4.2.1/x86_64" "-L/usr/lib/gcc/i686-apple-darwin10/4.2.1/x86_64" "-L/usr/lib/i686-apple-darwin10/4.2.1" "-L/usr/lib/gcc/i686-apple-darwin10/4.2.1" "-L/usr/lib/gcc/i686-apple-darwin10/4.2.1" "-L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../../i686-apple-darwin10/4.2.1" "-L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../.." "/tmp/tmpTi0lCN.o" "-lgcc_s.10.5" "-lgcc" "-lSystem"
+"""
+gcc_info = """
+Using built-in specs.
+Target: i686-apple-darwin10
+Configured with: /var/tmp/gcc/gcc-5630~5/src/configure --disable-checking --enable-werror --prefix=/usr --mandir=/share/man --enable-languages=c,objc,c++,obj-c++ --program-transform-name=/^[cg][^.-]*$/s/$/-4.2/ --with-slibdir=/usr/lib --build=i686-apple-darwin10 --with-gxx-include-dir=/include/c++/4.2.1 --program-prefix=i686-apple-darwin10- --host=x86_64-apple-darwin10 --target=i686-apple-darwin10
+Thread model: posix
+gcc version 4.2.1 (Apple Inc. build 5630)
+ "/usr/libexec/gcc/i686-apple-darwin10/4.2.1/cc1" "-quiet" "-imultilib" "x86_64" "-D__DYNAMIC__" "/dev/null" "-fPIC" "-quiet" "-dumpbase" "null" "-mmacosx-version-min=10.6.0" "-m64" "-mtune=core2" "-auxbase" "null" "-o" "/var/tmp//ccuvh82w.s"
+ "/usr/libexec/gcc/i686-apple-darwin10/4.2.1/as" "-arch" "x86_64" "-force_cpusubtype_ALL" "-o" "/var/tmp//ccb3T8Fr.o" "/var/tmp//ccuvh82w.s"
+ "/usr/libexec/gcc/i686-apple-darwin10/4.2.1/collect2" "-dynamic" "-arch" "x86_64" "-macosx_version_min" "10.6.0" "-weak_reference_mismatches" "non-weak" "-o" "a.out" "-lcrt1.10.5.o" "-L/usr/lib/gcc/i686-apple-darwin10/4.2.1/x86_64" "-L/usr/lib/gcc/i686-apple-darwin10/4.2.1/x86_64" "-L/usr/lib/i686-apple-darwin10/4.2.1" "-L/usr/lib/gcc/i686-apple-darwin10/4.2.1" "-L/usr/lib/gcc/i686-apple-darwin10/4.2.1" "-L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../../i686-apple-darwin10/4.2.1" "-L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../.." "/var/tmp//ccb3T8Fr.o" "-lgcc_s.10.5" "-lgcc" "-lSystem"
+"""
+style = """xcb"""
+runs = []
+runs.append(( { 'cc':"ccc_clang",
+                'script':"null",
+                'threads':"1",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.405425, 0.222438, 0.698198),
+	(1, 0.403472, 0.218381, 0.695599),
+	(2, 0.403354, 0.217344, 0.695414),
+	(3, 0.403856, 0.218787, 0.703370),
+	(4, 0.404353, 0.221186, 0.695619),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"null",
+                'threads':"1",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.393260, 0.212802, 0.656048),
+	(1, 0.393075, 0.211285, 0.654796),
+	(2, 0.394300, 0.213498, 0.695105),
+	(3, 0.393851, 0.213657, 0.695272),
+	(4, 0.395458, 0.213304, 0.695908),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"null",
+                'threads':"1",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.403360, 0.216918, 0.704434),
+	(1, 0.403818, 0.219731, 0.696158),
+	(2, 0.402206, 0.218530, 0.697751),
+	(3, 0.403133, 0.218441, 0.695443),
+	(4, 0.403311, 0.218882, 0.695080),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"null",
+                'threads':"1",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.395200, 0.213912, 0.696117),
+	(1, 0.395331, 0.213822, 0.695887),
+	(2, 0.395293, 0.212402, 0.697557),
+	(3, 0.395446, 0.213684, 0.695732),
+	(4, 0.394667, 0.213321, 0.656472),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"null",
+                'threads':"1",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.403665, 0.217763, 0.694820),
+	(1, 0.403482, 0.217606, 0.695959),
+	(2, 0.404965, 0.219817, 0.819840),
+	(3, 0.404437, 0.217515, 0.695675),
+	(4, 0.402886, 0.216456, 0.703275),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"null",
+                'threads':"1",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.393583, 0.212237, 0.655196),
+	(1, 0.394063, 0.212744, 0.695220),
+	(2, 0.393998, 0.212889, 0.695448),
+	(3, 0.394364, 0.213507, 0.695090),
+	(4, 0.395886, 0.214974, 0.696254),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"###",
+                'threads':"1",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 1.129656, 0.771133, 2.056006),
+	(1, 1.129855, 0.772644, 2.055649),
+	(2, 1.130559, 0.768629, 2.055976),
+	(3, 1.130291, 0.769030, 2.059280),
+	(4, 1.130861, 0.771000, 2.055720),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"###",
+                'threads':"1",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 1.086760, 0.741197, 1.976344),
+	(1, 1.087919, 0.739640, 1.975560),
+	(2, 1.087589, 0.739815, 2.015386),
+	(3, 1.087730, 0.738847, 1.976232),
+	(4, 1.088193, 0.739529, 2.016033),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"###",
+                'threads':"1",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 1.138506, 0.768675, 2.064631),
+	(1, 1.138085, 0.770549, 2.097210),
+	(2, 1.138889, 0.771511, 2.096435),
+	(3, 1.138765, 0.770142, 2.064291),
+	(4, 1.138779, 0.768611, 2.095530),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"###",
+                'threads':"1",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 1.096902, 0.741661, 2.015757),
+	(1, 1.097165, 0.740449, 2.015432),
+	(2, 1.096494, 0.740608, 2.016453),
+	(3, 1.096410, 0.739960, 1.975427),
+	(4, 1.096579, 0.743114, 2.016444),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"###",
+                'threads':"1",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.444144, 0.284384, 0.814217),
+	(1, 0.445853, 0.286540, 0.816314),
+	(2, 0.446338, 0.287002, 0.814997),
+	(3, 0.445384, 0.284369, 0.823090),
+	(4, 0.444071, 0.284531, 0.815854),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"###",
+                'threads':"1",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.435113, 0.278547, 0.817260),
+	(1, 0.433108, 0.275659, 0.775024),
+	(2, 0.434473, 0.276611, 0.784047),
+	(3, 0.434224, 0.275786, 0.775677),
+	(4, 0.433396, 0.276622, 0.775240),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"only_pch",
+                'threads':"1",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 1.328464, 0.973747, 2.577016),
+	(1, 1.324318, 0.855290, 2.424347),
+	(2, 1.323693, 0.856675, 2.416951),
+	(3, 1.323004, 0.857324, 2.417132),
+	(4, 1.323843, 0.856000, 2.415804),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"only_pch",
+                'threads':"1",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 2.748207, 1.141266, 4.576484),
+	(1, 2.744640, 1.137930, 4.416237),
+	(2, 2.745616, 1.136230, 4.495978),
+	(3, 2.746108, 1.139037, 4.496219),
+	(4, 2.746059, 1.137958, 4.416920),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"only_pch",
+                'threads':"1",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 2.051374, 0.650962, 3.144706),
+	(1, 2.050914, 0.648174, 3.215974),
+	(2, 2.050343, 0.649010, 3.176205),
+	(3, 2.051910, 0.648745, 3.176613),
+	(4, 2.051386, 0.648306, 3.217578),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"cpp",
+                'threads':"1",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 1.835919, 1.148648, 3.257076),
+	(1, 1.835307, 1.146862, 3.264809),
+	(2, 1.834812, 1.147964, 3.257005),
+	(3, 1.835016, 1.144979, 3.256861),
+	(4, 1.836571, 1.148836, 3.256094),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"cpp",
+                'threads':"1",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 2.288802, 1.569778, 4.095720),
+	(1, 2.288176, 1.573356, 4.176816),
+	(2, 2.287878, 1.573807, 4.096939),
+	(3, 2.288041, 1.571541, 4.097750),
+	(4, 2.288190, 1.569398, 4.097146),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"parse",
+                'threads':"1",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 2.220738, 1.167367, 3.657062),
+	(1, 2.219840, 1.170754, 3.657627),
+	(2, 2.220897, 1.172925, 3.657043),
+	(3, 2.221644, 1.167701, 3.656328),
+	(4, 2.223199, 1.171444, 3.657134),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"parse",
+                'threads':"1",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 2.717655, 1.602645, 4.536037),
+	(1, 2.716324, 1.603188, 4.536210),
+	(2, 2.718783, 1.605672, 4.576816),
+	(3, 2.718146, 1.602360, 4.536958),
+	(4, 2.718544, 1.606428, 4.577367),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"syntax",
+                'threads':"1",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 3.453390, 1.390902, 5.176330),
+	(1, 3.453408, 1.394547, 5.176325),
+	(2, 3.453141, 1.392043, 5.176946),
+	(3, 3.457040, 1.390031, 5.257617),
+	(4, 3.453262, 1.395063, 5.138977),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"syntax",
+                'threads':"1",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 4.077200, 1.866592, 6.223139),
+	(1, 4.076044, 1.873001, 6.214158),
+	(2, 4.079719, 1.869271, 6.235665),
+	(3, 4.078223, 1.866927, 6.217922),
+	(4, 4.076013, 1.867985, 6.204512),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"syntax",
+                'threads':"1",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 3.397072, 2.178746, 6.177185),
+	(1, 3.397804, 2.167804, 6.177276),
+	(2, 3.398193, 2.168075, 6.250655),
+	(3, 3.397029, 2.165686, 6.184421),
+	(4, 3.397568, 2.178013, 6.179279),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"syntax",
+                'threads':"1",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 7.486708, 2.445768, 10.254543),
+	(1, 7.491379, 2.458432, 10.337225),
+	(2, 7.486408, 2.433698, 10.257034),
+	(3, 7.487016, 2.456457, 10.270939),
+	(4, 7.487323, 2.439337, 10.258257),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"syntax",
+                'threads':"1",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 2.670173, 1.622433, 4.897808),
+	(1, 2.666760, 1.609756, 4.776822),
+	(2, 2.667040, 1.610998, 4.856885),
+	(3, 2.671149, 1.594163, 4.816301),
+	(4, 2.669699, 1.607578, 4.866539),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"syntax",
+                'threads':"1",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 6.803057, 1.908280, 8.963127),
+	(1, 6.805076, 1.939662, 8.969825),
+	(2, 6.802844, 1.921782, 8.970996),
+	(3, 6.805031, 1.913186, 8.967523),
+	(4, 6.805252, 1.919294, 8.959788),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"irgen",
+                'threads':"1",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 3.627373, 1.415978, 5.377556),
+	(1, 3.625026, 1.415306, 5.337455),
+	(2, 3.624699, 1.411942, 5.377834),
+	(3, 3.627468, 1.422229, 5.376680),
+	(4, 3.625721, 1.421354, 5.377509),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"irgen",
+                'threads':"1",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 4.249780, 1.891114, 6.438770),
+	(1, 4.248041, 1.893114, 6.416578),
+	(2, 4.248877, 1.890255, 6.422580),
+	(3, 4.248459, 1.891867, 6.425267),
+	(4, 4.251042, 1.896335, 6.438381),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"only_asm",
+                'threads':"1",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 3.813308, 1.436255, 5.577048),
+	(1, 3.812973, 1.436260, 5.577759),
+	(2, 3.814667, 1.436329, 5.576892),
+	(3, 3.814164, 1.439684, 5.577863),
+	(4, 3.816874, 1.432057, 5.625098),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"only_asm",
+                'threads':"1",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 4.438589, 1.914821, 6.634438),
+	(1, 4.436802, 1.913064, 6.628424),
+	(2, 4.438023, 1.918364, 6.632666),
+	(3, 4.438494, 1.922851, 6.645062),
+	(4, 4.439727, 1.920331, 6.685016),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"only_asm",
+                'threads':"1",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 3.975290, 2.296164, 6.913135),
+	(1, 3.977464, 2.309821, 6.916908),
+	(2, 3.976537, 2.309954, 6.848258),
+	(3, 3.977155, 2.305060, 7.357985),
+	(4, 3.974276, 2.289059, 6.862249),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"only_asm",
+                'threads':"1",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 8.928091, 2.684142, 11.969055),
+	(1, 8.929295, 2.683263, 11.988445),
+	(2, 8.929175, 2.678390, 11.956474),
+	(3, 8.926613, 2.665122, 11.965071),
+	(4, 8.926613, 2.680630, 11.964381),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"only_asm",
+                'threads':"1",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 3.249871, 1.745454, 5.497846),
+	(1, 3.249460, 1.737577, 5.538376),
+	(2, 3.253966, 1.727548, 5.616847),
+	(3, 3.251405, 1.725884, 5.496698),
+	(4, 3.250563, 1.721386, 5.536694),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"only_asm",
+                'threads':"1",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 8.249350, 2.147359, 10.672894),
+	(1, 8.252421, 2.146136, 10.687439),
+	(2, 8.252766, 2.142015, 10.683719),
+	(3, 8.279512, 2.152184, 11.070527),
+	(4, 8.250015, 2.161431, 10.703253),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"only_compile",
+                'threads':"1",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 3.917675, 1.531758, 5.777717),
+	(1, 3.917453, 1.532169, 5.777704),
+	(2, 3.920630, 1.538518, 5.857605),
+	(3, 3.917549, 1.535710, 5.776730),
+	(4, 3.917673, 1.529128, 5.776450),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"only_compile",
+                'threads':"1",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 4.536313, 2.003164, 6.831313),
+	(1, 4.537451, 2.014513, 6.846562),
+	(2, 4.540679, 2.016759, 6.865437),
+	(3, 4.538081, 2.008899, 6.845811),
+	(4, 4.538438, 2.009600, 6.836498),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"only_compile",
+                'threads':"1",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 4.123486, 2.383752, 7.115483),
+	(1, 4.127545, 2.372840, 7.151675),
+	(2, 4.125900, 2.381678, 7.138942),
+	(3, 4.123891, 2.369579, 7.127788),
+	(4, 4.125164, 2.370661, 7.117664),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"only_compile",
+                'threads':"1",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 9.076157, 2.771491, 12.341310),
+	(1, 9.074681, 2.764608, 12.205139),
+	(2, 9.076881, 2.766755, 12.228073),
+	(3, 9.073910, 2.771638, 12.204252),
+	(4, 9.076773, 2.777037, 12.235749),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"only_compile",
+                'threads':"1",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 3.388061, 1.779190, 5.737793),
+	(1, 3.387862, 1.790856, 5.697850),
+	(2, 3.387800, 1.789477, 5.780238),
+	(3, 3.387509, 1.788586, 5.743236),
+	(4, 3.388152, 1.784450, 6.178092),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"only_compile",
+                'threads':"1",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 8.376118, 2.205600, 10.877337),
+	(1, 8.372512, 2.219382, 10.868894),
+	(2, 8.375968, 2.225479, 10.996566),
+	(3, 8.379525, 2.215791, 10.910221),
+	(4, 8.375433, 2.210534, 10.890280),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"all",
+                'threads':"1",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 3.948571, 1.553366, 5.857777),
+	(1, 3.946872, 1.549844, 5.817926),
+	(2, 3.948643, 1.545410, 5.817794),
+	(3, 3.947022, 1.548687, 5.816790),
+	(4, 3.951557, 1.560511, 5.937022),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"all",
+                'threads':"1",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 4.568105, 2.037309, 6.888153),
+	(1, 4.567872, 2.037818, 6.893678),
+	(2, 4.569582, 2.037795, 6.894469),
+	(3, 4.571991, 2.042292, 6.920444),
+	(4, 4.568506, 2.036233, 6.895221),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"all",
+                'threads':"1",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 4.153075, 2.389230, 7.183219),
+	(1, 4.150947, 2.401330, 7.175264),
+	(2, 4.150807, 2.390926, 7.237253),
+	(3, 4.152335, 2.393576, 7.265347),
+	(4, 4.154240, 2.408743, 7.201345),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"all",
+                'threads':"1",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 9.104507, 2.799196, 12.284425),
+	(1, 9.102214, 2.804734, 12.263326),
+	(2, 9.102799, 2.797758, 12.263314),
+	(3, 9.102472, 2.797718, 12.283471),
+	(4, 9.101655, 2.799231, 12.257987),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"all",
+                'threads':"1",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 3.412096, 1.803347, 5.817859),
+	(1, 3.412334, 1.792039, 5.897059),
+	(2, 3.413608, 1.789291, 5.817810),
+	(3, 3.413812, 1.785669, 5.827047),
+	(4, 3.413291, 1.782601, 5.738213),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"all",
+                'threads':"1",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 8.402455, 2.228676, 10.943842),
+	(1, 8.396442, 2.225608, 10.902714),
+	(2, 8.401735, 2.220712, 10.918381),
+	(3, 8.400619, 2.226284, 10.926158),
+	(4, 8.398896, 2.221540, 10.901292),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"null",
+                'threads':"2",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.421126, 0.234655, 0.534969),
+	(1, 0.418396, 0.232067, 0.536121),
+	(2, 0.419512, 0.236062, 0.536636),
+	(3, 0.420755, 0.236390, 0.535508),
+	(4, 0.421343, 0.234614, 0.537189),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"null",
+                'threads':"2",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.411128, 0.230994, 0.499097),
+	(1, 0.412593, 0.231427, 0.536123),
+	(2, 0.407668, 0.229908, 0.495794),
+	(3, 0.410890, 0.229289, 0.535618),
+	(4, 0.412812, 0.229662, 0.535043),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"null",
+                'threads':"2",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.421792, 0.234957, 0.536236),
+	(1, 0.421073, 0.235668, 0.538946),
+	(2, 0.418909, 0.236416, 0.535464),
+	(3, 0.420363, 0.235692, 0.535257),
+	(4, 0.419598, 0.234400, 0.534633),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"null",
+                'threads':"2",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.409040, 0.230090, 0.534802),
+	(1, 0.411753, 0.232552, 0.537293),
+	(2, 0.415536, 0.231495, 0.536877),
+	(3, 0.410714, 0.227612, 0.535090),
+	(4, 0.409547, 0.230152, 0.497187),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"null",
+                'threads':"2",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.421181, 0.235033, 0.535407),
+	(1, 0.420747, 0.236700, 0.535928),
+	(2, 0.418786, 0.235032, 0.534312),
+	(3, 0.420015, 0.233378, 0.535452),
+	(4, 0.421154, 0.235218, 0.535269),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"null",
+                'threads':"2",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.411356, 0.231786, 0.537593),
+	(1, 0.412772, 0.230723, 0.537039),
+	(2, 0.410034, 0.228264, 0.494194),
+	(3, 0.412693, 0.230932, 0.536339),
+	(4, 0.411372, 0.228262, 0.497113),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"###",
+                'threads':"2",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 1.185856, 0.840347, 1.416460),
+	(1, 1.186435, 0.854091, 1.415674),
+	(2, 1.183343, 0.844916, 1.415643),
+	(3, 1.181560, 0.857296, 1.415242),
+	(4, 1.187699, 0.853918, 1.415647),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"###",
+                'threads':"2",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 1.138810, 0.818035, 1.335935),
+	(1, 1.141064, 0.827249, 1.337062),
+	(2, 1.138410, 0.811996, 1.335346),
+	(3, 1.142644, 0.820159, 1.337486),
+	(4, 1.138460, 0.815423, 1.335647),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"###",
+                'threads':"2",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 1.194684, 0.841290, 1.415885),
+	(1, 1.195720, 0.844873, 1.416552),
+	(2, 1.194440, 0.850513, 1.415595),
+	(3, 1.191931, 0.850890, 1.414722),
+	(4, 1.192481, 0.853052, 1.416102),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"###",
+                'threads':"2",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 1.148891, 0.817183, 1.335717),
+	(1, 1.149617, 0.823096, 1.336040),
+	(2, 1.149791, 0.805679, 1.337424),
+	(3, 1.150876, 0.814239, 1.336748),
+	(4, 1.153157, 0.809177, 1.336246),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"###",
+                'threads':"2",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.463514, 0.310817, 0.614767),
+	(1, 0.464612, 0.310198, 0.618455),
+	(2, 0.463460, 0.308990, 0.616282),
+	(3, 0.463413, 0.311280, 0.617026),
+	(4, 0.467009, 0.310382, 0.857752),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"###",
+                'threads':"2",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.453517, 0.301571, 0.575912),
+	(1, 0.452100, 0.300588, 0.576359),
+	(2, 0.448456, 0.297936, 0.575121),
+	(3, 0.451645, 0.298907, 0.577323),
+	(4, 0.450964, 0.301582, 0.574520),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"only_pch",
+                'threads':"2",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 1.381350, 0.944251, 1.776275),
+	(1, 1.380373, 0.930919, 1.775617),
+	(2, 1.379352, 0.937129, 1.736723),
+	(3, 1.380977, 0.944068, 1.737369),
+	(4, 1.381796, 0.938486, 1.776093),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"only_pch",
+                'threads':"2",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 2.805408, 1.220930, 3.697693),
+	(1, 2.804236, 1.204836, 3.657105),
+	(2, 2.803037, 1.210121, 3.696933),
+	(3, 2.807280, 1.219531, 3.779261),
+	(4, 2.802821, 1.208316, 3.736487),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"only_pch",
+                'threads':"2",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 2.076567, 0.672051, 2.896169),
+	(1, 2.070465, 0.668786, 2.895749),
+	(2, 2.077549, 0.673245, 2.896393),
+	(3, 2.075634, 0.671026, 2.976119),
+	(4, 2.074463, 0.671262, 2.975937),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"cpp",
+                'threads':"2",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 1.909827, 1.258607, 2.215806),
+	(1, 1.910547, 1.261354, 2.255924),
+	(2, 1.907436, 1.262299, 2.216659),
+	(3, 1.908875, 1.254564, 2.256077),
+	(4, 1.906568, 1.264632, 2.215638),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"cpp",
+                'threads':"2",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 2.384586, 1.708563, 2.495874),
+	(1, 2.386876, 1.705256, 2.456596),
+	(2, 2.383560, 1.707485, 2.456364),
+	(3, 2.388580, 1.714631, 2.496008),
+	(4, 2.383943, 1.709754, 2.455848),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"parse",
+                'threads':"2",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 2.296978, 1.274825, 2.415106),
+	(1, 2.303460, 1.279010, 2.456151),
+	(2, 2.300862, 1.277879, 2.536542),
+	(3, 2.297727, 1.277312, 2.416137),
+	(4, 2.299045, 1.281014, 2.457338),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"parse",
+                'threads':"2",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 2.823962, 1.752509, 2.738192),
+	(1, 2.825617, 1.738546, 2.736478),
+	(2, 2.825608, 1.744360, 2.735298),
+	(3, 2.822577, 1.756988, 2.735053),
+	(4, 2.828362, 1.751245, 2.737930),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"syntax",
+                'threads':"2",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 3.586428, 1.498329, 3.258357),
+	(1, 3.581922, 1.510793, 3.258049),
+	(2, 3.584574, 1.523963, 3.256754),
+	(3, 3.585929, 1.525886, 3.296728),
+	(4, 3.583339, 1.509529, 3.255773),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"syntax",
+                'threads':"2",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 4.249019, 2.030066, 3.658088),
+	(1, 4.244427, 1.997319, 3.618002),
+	(2, 4.247446, 2.034549, 3.656419),
+	(3, 4.250734, 1.984081, 3.616241),
+	(4, 4.247304, 2.029095, 3.656926),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"syntax",
+                'threads':"2",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 3.533690, 2.339185, 4.777496),
+	(1, 3.542505, 2.348833, 4.697715),
+	(2, 3.544757, 2.349717, 4.658518),
+	(3, 3.542116, 2.342489, 4.697843),
+	(4, 3.532830, 2.358614, 4.777230),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"syntax",
+                'threads':"2",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 7.911000, 2.638922, 5.859227),
+	(1, 7.898019, 2.606325, 5.856922),
+	(2, 7.905536, 2.635740, 5.857377),
+	(3, 7.904312, 2.612189, 5.858381),
+	(4, 7.905098, 2.630487, 5.896411),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"syntax",
+                'threads':"2",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 2.751623, 1.803556, 3.817713),
+	(1, 2.747727, 1.810833, 3.816503),
+	(2, 2.748505, 1.805853, 3.937231),
+	(3, 2.751082, 1.785040, 3.856857),
+	(4, 2.712181, 1.628194, 4.458047),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"syntax",
+                'threads':"2",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 7.130218, 2.046734, 5.375091),
+	(1, 7.178329, 2.050762, 5.101087),
+	(2, 7.169060, 2.043104, 5.099096),
+	(3, 7.173283, 2.044239, 5.098124),
+	(4, 7.175252, 2.051192, 5.098199),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"irgen",
+                'threads':"2",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 3.789165, 1.527458, 3.336326),
+	(1, 3.777274, 1.538660, 3.375557),
+	(2, 3.784557, 1.519313, 3.376128),
+	(3, 3.787602, 1.522217, 3.335926),
+	(4, 3.787288, 1.526795, 3.337409),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"irgen",
+                'threads':"2",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 4.447726, 2.033431, 3.740433),
+	(1, 4.442726, 2.033703, 3.738224),
+	(2, 4.442734, 2.032771, 3.738289),
+	(3, 4.444849, 2.031724, 3.737305),
+	(4, 4.447839, 2.041379, 3.737854),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"only_asm",
+                'threads':"2",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 3.976113, 1.536616, 3.457503),
+	(1, 3.982885, 1.550541, 3.459236),
+	(2, 3.980745, 1.542500, 3.418313),
+	(3, 3.983197, 1.534735, 3.416768),
+	(4, 3.984319, 1.549369, 3.456912),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"only_asm",
+                'threads':"2",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 4.646497, 2.058736, 3.857968),
+	(1, 4.645902, 2.056331, 3.816948),
+	(2, 4.644425, 2.042617, 3.817483),
+	(3, 4.650170, 2.053945, 3.816996),
+	(4, 4.652057, 2.054087, 3.817612),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"only_asm",
+                'threads':"2",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 4.227559, 2.531595, 5.137862),
+	(1, 4.227397, 2.523166, 5.177460),
+	(2, 4.221999, 2.507393, 5.217410),
+	(3, 4.222567, 2.526250, 5.217654),
+	(4, 4.227901, 2.540431, 5.098870),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"only_asm",
+                'threads':"2",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 9.519619, 2.893774, 6.844787),
+	(1, 9.519173, 2.909991, 6.855886),
+	(2, 9.510792, 2.877242, 6.838998),
+	(3, 9.510783, 2.891383, 6.824785),
+	(4, 9.519126, 2.885516, 6.833841),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"only_asm",
+                'threads':"2",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 3.451087, 1.898383, 4.336398),
+	(1, 3.449852, 1.892527, 4.337959),
+	(2, 3.454374, 1.893303, 4.658079),
+	(3, 3.455111, 1.882656, 4.378217),
+	(4, 3.450626, 1.869007, 4.337978),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"only_asm",
+                'threads':"2",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 8.787702, 2.320593, 6.058270),
+	(1, 8.789275, 2.306274, 6.057923),
+	(2, 8.784843, 2.316817, 6.057423),
+	(3, 8.783675, 2.311861, 6.060013),
+	(4, 8.781261, 2.313746, 6.057873),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"only_compile",
+                'threads':"2",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 4.083893, 1.630474, 3.536216),
+	(1, 4.087591, 1.635289, 3.497630),
+	(2, 4.085695, 1.632900, 3.538942),
+	(3, 4.091750, 1.621504, 3.537607),
+	(4, 4.083429, 1.624206, 3.538044),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"only_compile",
+                'threads':"2",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 4.741063, 2.114975, 3.939181),
+	(1, 4.742471, 2.134199, 3.937271),
+	(2, 4.751861, 2.134679, 3.937887),
+	(3, 4.748915, 2.139128, 3.937938),
+	(4, 4.744369, 2.118603, 4.016509),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"only_compile",
+                'threads':"2",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 4.373580, 2.603582, 5.297729),
+	(1, 4.375890, 2.576323, 5.258865),
+	(2, 4.371432, 2.583884, 5.297363),
+	(3, 4.374495, 2.589453, 5.257298),
+	(4, 4.369606, 2.606228, 5.257661),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"only_compile",
+                'threads':"2",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 9.661360, 2.976421, 7.177350),
+	(1, 9.668097, 2.986125, 6.963308),
+	(2, 9.667800, 2.983053, 6.959276),
+	(3, 9.663941, 2.979323, 6.939242),
+	(4, 9.662299, 2.970007, 6.988974),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"only_compile",
+                'threads':"2",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 3.579784, 1.946620, 4.378033),
+	(1, 3.579704, 1.964725, 4.377985),
+	(2, 3.584964, 1.951670, 4.376971),
+	(3, 3.576692, 1.920906, 4.418008),
+	(4, 3.590239, 1.966765, 4.377119),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"only_compile",
+                'threads':"2",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 8.908318, 2.358443, 6.137820),
+	(1, 8.900847, 2.342913, 6.137705),
+	(2, 8.902168, 2.355932, 6.179136),
+	(3, 8.903369, 2.363490, 6.097751),
+	(4, 8.896827, 2.364196, 6.098246),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"all",
+                'threads':"2",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 4.122590, 1.633583, 3.696664),
+	(1, 4.114949, 1.638141, 3.578111),
+	(2, 4.114996, 1.631617, 3.536742),
+	(3, 4.118038, 1.641230, 3.578327),
+	(4, 4.112972, 1.639592, 3.575918),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"all",
+                'threads':"2",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 4.774701, 2.146296, 3.977572),
+	(1, 4.775361, 2.153011, 3.979860),
+	(2, 4.767364, 2.152865, 4.057217),
+	(3, 4.762550, 2.149360, 3.979342),
+	(4, 4.778981, 2.139902, 3.978489),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"all",
+                'threads':"2",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 4.400574, 2.604084, 5.299578),
+	(1, 4.404470, 2.623904, 5.338578),
+	(2, 4.396282, 2.608549, 5.297828),
+	(3, 4.410117, 2.614698, 5.340116),
+	(4, 4.406122, 2.619452, 5.337443),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"all",
+                'threads':"2",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 9.691876, 2.983326, 7.028989),
+	(1, 9.686101, 2.995257, 6.984466),
+	(2, 9.699200, 2.989842, 7.028152),
+	(3, 9.694729, 2.989742, 6.973924),
+	(4, 9.684670, 2.977108, 6.989194),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"all",
+                'threads':"2",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 3.603234, 1.964083, 4.458006),
+	(1, 3.607074, 1.941178, 4.417525),
+	(2, 3.603034, 1.943612, 4.737094),
+	(3, 3.602477, 1.935710, 4.378785),
+	(4, 3.603014, 1.920944, 4.496731),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"all",
+                'threads':"2",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 8.919863, 2.380177, 6.178527),
+	(1, 8.915304, 2.377547, 6.139442),
+	(2, 8.912262, 2.361640, 6.382166),
+	(3, 8.928109, 2.368477, 6.192743),
+	(4, 8.926360, 2.372693, 6.196191),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"null",
+                'threads':"4",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.433816, 0.270779, 0.497217),
+	(1, 0.435460, 0.270028, 0.496532),
+	(2, 0.433553, 0.269600, 0.496135),
+	(3, 0.444402, 0.277012, 0.497745),
+	(4, 0.435023, 0.270357, 0.496884),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"null",
+                'threads':"4",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.427882, 0.266594, 0.456246),
+	(1, 0.436036, 0.268734, 0.457465),
+	(2, 0.432485, 0.268278, 0.495730),
+	(3, 0.431188, 0.269520, 0.457981),
+	(4, 0.429806, 0.265927, 0.457372),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"null",
+                'threads':"4",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.439986, 0.271715, 0.496550),
+	(1, 0.433586, 0.270013, 0.496199),
+	(2, 0.432029, 0.268060, 0.497939),
+	(3, 0.439059, 0.272464, 0.497620),
+	(4, 0.434181, 0.272563, 0.497461),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"null",
+                'threads':"4",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.432427, 0.269396, 0.457136),
+	(1, 0.428288, 0.270302, 0.737128),
+	(2, 0.431231, 0.268325, 0.456252),
+	(3, 0.427926, 0.267086, 0.456874),
+	(4, 0.420557, 0.264270, 0.457617),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"null",
+                'threads':"4",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.434424, 0.272190, 0.498161),
+	(1, 0.434165, 0.269235, 0.494824),
+	(2, 0.432662, 0.270415, 0.500255),
+	(3, 0.438368, 0.274265, 0.496769),
+	(4, 0.436696, 0.274610, 0.495729),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"null",
+                'threads':"4",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.433117, 0.267209, 0.457335),
+	(1, 0.431207, 0.267527, 0.457362),
+	(2, 0.427488, 0.263088, 0.456154),
+	(3, 0.424716, 0.264632, 0.456745),
+	(4, 0.430324, 0.266478, 0.457237),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"###",
+                'threads':"4",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 1.243380, 0.979720, 1.137169),
+	(1, 1.278996, 0.992319, 1.137506),
+	(2, 1.287192, 0.993761, 1.138362),
+	(3, 1.287132, 0.979672, 1.137975),
+	(4, 1.280673, 0.991069, 1.134803),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"###",
+                'threads':"4",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 1.199258, 0.944011, 1.056302),
+	(1, 1.238243, 0.967198, 1.055378),
+	(2, 1.251064, 0.952736, 1.058118),
+	(3, 1.238275, 0.953812, 1.056281),
+	(4, 1.230085, 0.961011, 1.058278),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"###",
+                'threads':"4",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 1.303555, 1.002749, 1.177122),
+	(1, 1.297516, 0.987769, 1.179257),
+	(2, 1.291316, 0.989683, 1.134877),
+	(3, 1.297521, 0.998087, 1.177932),
+	(4, 1.298070, 0.996104, 1.136646),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"###",
+                'threads':"4",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 1.242426, 0.951754, 1.054691),
+	(1, 1.251845, 0.955747, 1.055754),
+	(2, 1.216099, 0.939568, 1.057614),
+	(3, 1.252534, 0.953115, 1.057181),
+	(4, 1.255139, 0.957134, 1.056560),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"###",
+                'threads':"4",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.480008, 0.367388, 0.535985),
+	(1, 0.482634, 0.363998, 0.537057),
+	(2, 0.487524, 0.362915, 0.536461),
+	(3, 0.486824, 0.371502, 0.536601),
+	(4, 0.486100, 0.368487, 0.536231),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"###",
+                'threads':"4",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.471967, 0.356792, 0.537280),
+	(1, 0.471389, 0.351906, 0.537328),
+	(2, 0.476653, 0.364830, 0.536856),
+	(3, 0.473745, 0.360644, 0.536245),
+	(4, 0.471692, 0.358740, 0.536919),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"only_pch",
+                'threads':"4",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 1.488745, 1.084366, 1.498790),
+	(1, 1.477772, 1.072057, 1.497152),
+	(2, 1.481656, 1.079815, 1.497487),
+	(3, 1.488131, 1.086291, 1.497713),
+	(4, 1.484908, 1.083611, 1.497307),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"only_pch",
+                'threads':"4",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 2.892219, 1.358115, 3.416973),
+	(1, 2.908085, 1.361083, 3.458190),
+	(2, 2.911845, 1.363507, 3.498229),
+	(3, 2.861631, 1.340626, 3.497350),
+	(4, 2.902695, 1.349841, 3.498252),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"only_pch",
+                'threads':"4",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 2.094289, 0.731166, 2.856787),
+	(1, 2.094159, 0.727149, 3.098345),
+	(2, 2.099123, 0.725737, 2.857987),
+	(3, 2.099356, 0.725484, 2.857824),
+	(4, 2.092198, 0.722902, 2.856964),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"cpp",
+                'threads':"4",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 2.072042, 1.472173, 1.777206),
+	(1, 2.082600, 1.489627, 1.777280),
+	(2, 2.056884, 1.488123, 1.817614),
+	(3, 2.070744, 1.497244, 1.776597),
+	(4, 2.067240, 1.482836, 1.777571),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"cpp",
+                'threads':"4",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 2.533060, 2.043311, 1.777522),
+	(1, 2.628373, 2.047752, 1.777593),
+	(2, 2.630915, 2.051977, 1.777852),
+	(3, 2.630455, 2.065881, 1.777911),
+	(4, 2.631787, 2.049902, 1.778263),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"parse",
+                'threads':"4",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 2.505337, 1.496155, 1.898006),
+	(1, 2.495744, 1.488942, 1.897842),
+	(2, 2.515831, 1.484552, 1.897723),
+	(3, 2.498317, 1.488449, 1.897741),
+	(4, 2.515904, 1.484614, 1.897771),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"parse",
+                'threads':"4",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 3.125124, 2.066737, 1.896962),
+	(1, 3.066430, 2.061710, 1.897127),
+	(2, 2.951498, 2.032558, 1.899777),
+	(3, 3.102248, 2.072226, 1.938907),
+	(4, 2.965375, 2.034301, 1.901575),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"syntax",
+                'threads':"4",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 3.959637, 1.775658, 2.417471),
+	(1, 3.731703, 1.768139, 2.338378),
+	(2, 3.938876, 1.797903, 2.376989),
+	(3, 3.942618, 1.776899, 2.376468),
+	(4, 3.955662, 1.784850, 2.417537),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"syntax",
+                'threads':"4",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 4.711232, 2.418611, 2.457315),
+	(1, 4.710700, 2.405150, 2.458243),
+	(2, 4.701677, 2.393935, 2.458244),
+	(3, 4.700064, 2.411945, 2.458502),
+	(4, 4.435552, 2.373475, 2.417904),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"syntax",
+                'threads':"4",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 3.765235, 3.147148, 4.457806),
+	(1, 3.792075, 3.092380, 4.138512),
+	(2, 3.755530, 3.109232, 4.099198),
+	(3, 3.775577, 3.132702, 4.259349),
+	(4, 3.765380, 3.153395, 4.138279),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"syntax",
+                'threads':"4",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 8.733600, 3.141350, 3.819429),
+	(1, 8.729315, 3.130464, 3.818712),
+	(2, 8.758360, 3.153188, 3.898371),
+	(3, 8.284330, 3.049157, 3.698701),
+	(4, 8.287672, 3.024545, 3.697567),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"syntax",
+                'threads':"4",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 2.874930, 2.387032, 3.537592),
+	(1, 2.912332, 2.467479, 3.577891),
+	(2, 2.864476, 2.410851, 3.499089),
+	(3, 2.907625, 2.451013, 3.618200),
+	(4, 2.911261, 2.404477, 4.099524),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"syntax",
+                'threads':"4",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 7.915458, 2.450591, 3.219913),
+	(1, 7.956233, 2.439542, 3.300366),
+	(2, 7.913691, 2.473252, 3.218957),
+	(3, 7.509113, 2.397069, 3.138018),
+	(4, 7.904014, 2.456804, 3.218425),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"irgen",
+                'threads':"4",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 3.942240, 1.800567, 2.417458),
+	(1, 4.154844, 1.814089, 2.457805),
+	(2, 4.176584, 1.830900, 2.457020),
+	(3, 4.158194, 1.830085, 2.778865),
+	(4, 4.150232, 1.830750, 2.459318),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"irgen",
+                'threads':"4",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 4.905547, 2.434522, 2.537988),
+	(1, 4.924605, 2.457269, 2.538644),
+	(2, 4.657417, 2.378047, 2.458053),
+	(3, 4.911690, 2.470984, 2.537993),
+	(4, 4.929673, 2.455544, 2.538190),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"only_asm",
+                'threads':"4",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 4.418219, 1.850523, 2.536990),
+	(1, 4.366724, 1.852566, 2.538399),
+	(2, 4.384926, 1.854429, 2.539958),
+	(3, 4.394250, 1.842192, 2.539435),
+	(4, 4.397239, 1.838145, 2.540060),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"only_asm",
+                'threads':"4",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 5.130585, 2.493244, 2.579148),
+	(1, 5.162982, 2.497135, 2.578713),
+	(2, 5.129066, 2.472889, 2.619872),
+	(3, 4.874468, 2.405774, 2.497419),
+	(4, 5.128376, 2.467295, 2.578880),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"only_asm",
+                'threads':"4",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 4.630875, 3.227827, 4.420094),
+	(1, 4.603130, 3.292521, 4.698425),
+	(2, 4.637749, 3.169974, 4.378697),
+	(3, 4.662829, 3.216485, 4.459226),
+	(4, 4.661186, 3.194321, 4.459337),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"only_asm",
+                'threads':"4",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 10.094412, 3.382733, 4.299690),
+	(1, 10.607728, 3.485426, 4.420339),
+	(2, 10.672437, 3.500697, 4.499281),
+	(3, 10.081432, 3.369802, 4.260940),
+	(4, 10.637020, 3.507006, 4.419349),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"only_asm",
+                'threads':"4",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 3.756469, 2.606486, 3.858024),
+	(1, 3.742525, 2.585514, 3.860432),
+	(2, 3.763984, 2.594155, 3.858338),
+	(3, 3.750329, 2.597445, 3.861970),
+	(4, 3.780330, 2.594397, 4.178249),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"only_asm",
+                'threads':"4",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 9.783391, 2.778921, 3.858346),
+	(1, 9.291026, 2.713206, 3.741779),
+	(2, 9.763105, 2.769221, 3.818018),
+	(3, 9.781831, 2.771892, 3.860051),
+	(4, 9.795868, 2.814192, 3.861095),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"only_compile",
+                'threads':"4",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 4.526822, 1.970779, 2.579904),
+	(1, 4.516155, 1.962200, 2.579553),
+	(2, 4.502726, 1.967558, 2.657639),
+	(3, 4.475255, 1.944838, 2.578810),
+	(4, 4.552333, 1.965428, 2.620439),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"only_compile",
+                'threads':"4",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 5.260314, 2.603498, 2.660341),
+	(1, 4.995161, 2.487917, 2.539731),
+	(2, 5.272310, 2.582304, 2.619170),
+	(3, 5.297074, 2.584287, 2.659045),
+	(4, 5.276844, 2.591704, 2.658579),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"only_compile",
+                'threads':"4",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 4.820446, 3.357945, 4.457265),
+	(1, 4.695519, 3.299694, 4.700489),
+	(2, 4.802906, 3.355605, 4.499002),
+	(3, 4.790937, 3.298910, 4.497635),
+	(4, 4.807253, 3.403019, 4.538081),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"only_compile",
+                'threads':"4",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 10.775635, 3.627255, 4.498454),
+	(1, 10.819002, 3.627111, 4.498795),
+	(2, 10.777939, 3.603335, 4.579594),
+	(3, 10.261991, 3.489692, 4.340296),
+	(4, 10.783511, 3.603470, 4.497803),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"only_compile",
+                'threads':"4",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 3.926690, 2.635944, 3.858194),
+	(1, 3.904631, 2.622227, 3.819312),
+	(2, 3.902995, 2.656935, 3.899565),
+	(3, 3.842353, 2.559599, 3.939178),
+	(4, 3.912334, 2.629019, 3.858092),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"only_compile",
+                'threads':"4",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 9.417663, 2.778879, 3.779754),
+	(1, 9.981881, 2.854902, 3.981156),
+	(2, 9.922719, 2.849422, 3.895627),
+	(3, 9.932923, 2.851789, 3.899661),
+	(4, 9.882651, 2.809967, 3.860299),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"all",
+                'threads':"4",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 4.524352, 1.986189, 2.979131),
+	(1, 4.571793, 1.979632, 2.617329),
+	(2, 4.551874, 1.976839, 2.657311),
+	(3, 4.535069, 1.982461, 2.660565),
+	(4, 4.517949, 1.967234, 2.619985),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"all",
+                'threads':"4",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 5.308971, 2.608535, 2.660880),
+	(1, 5.300322, 2.591561, 2.698928),
+	(2, 5.007866, 2.516937, 2.617425),
+	(3, 5.004273, 2.518780, 2.620204),
+	(4, 5.298584, 2.603459, 2.697609),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"all",
+                'threads':"4",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 4.829605, 3.306560, 4.499574),
+	(1, 4.834964, 3.359516, 4.499708),
+	(2, 4.848950, 3.406535, 4.500607),
+	(3, 4.846305, 3.301867, 4.501270),
+	(4, 4.841747, 3.311314, 4.460786),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"all",
+                'threads':"4",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 10.261230, 3.487758, 4.377307),
+	(1, 10.821449, 3.608144, 4.579734),
+	(2, 10.818690, 3.639902, 4.538873),
+	(3, 10.288671, 3.520532, 4.378760),
+	(4, 10.827655, 3.621076, 4.540632),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"all",
+                'threads':"4",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 3.945245, 2.727926, 4.020004),
+	(1, 3.927023, 2.718237, 3.937944),
+	(2, 3.864097, 2.645215, 4.258710),
+	(3, 3.959593, 2.659668, 3.857486),
+	(4, 3.949860, 2.636461, 3.860314),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"all",
+                'threads':"4",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 9.988320, 2.894515, 3.979462),
+	(1, 9.984554, 2.865497, 3.978603),
+	(2, 9.969262, 2.894911, 3.940909),
+	(3, 9.971215, 2.860655, 3.939045),
+	(4, 9.928752, 2.859610, 4.140611),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"null",
+                'threads':"8",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.437223, 0.305541, 0.456598),
+	(1, 0.437365, 0.302782, 0.455612),
+	(2, 0.444941, 0.302766, 0.458539),
+	(3, 0.443284, 0.309348, 0.457267),
+	(4, 0.438558, 0.302788, 0.456867),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"null",
+                'threads':"8",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.433141, 0.299426, 0.457566),
+	(1, 0.433713, 0.302028, 0.456971),
+	(2, 0.432310, 0.301072, 0.457115),
+	(3, 0.431210, 0.298571, 0.456809),
+	(4, 0.432891, 0.306442, 0.458554),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"null",
+                'threads':"8",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.440129, 0.307891, 0.457005),
+	(1, 0.441966, 0.305756, 0.456712),
+	(2, 0.444503, 0.310015, 0.457176),
+	(3, 0.439473, 0.304319, 0.457442),
+	(4, 0.443194, 0.306398, 0.457362),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"null",
+                'threads':"8",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.431106, 0.301673, 0.458410),
+	(1, 0.434829, 0.302589, 0.456891),
+	(2, 0.430545, 0.302707, 0.457500),
+	(3, 0.436609, 0.301462, 0.456980),
+	(4, 0.429837, 0.300629, 0.456958),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"null",
+                'threads':"8",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.441827, 0.306401, 0.457803),
+	(1, 0.440791, 0.307818, 0.456863),
+	(2, 0.441486, 0.306428, 0.456280),
+	(3, 0.441639, 0.303644, 0.457488),
+	(4, 0.435752, 0.302272, 0.456606),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"null",
+                'threads':"8",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.434382, 0.299908, 0.458576),
+	(1, 0.430466, 0.299767, 0.458895),
+	(2, 0.433482, 0.301923, 0.457146),
+	(3, 0.437816, 0.305736, 0.460591),
+	(4, 0.433787, 0.300150, 0.457657),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"###",
+                'threads':"8",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 1.248580, 1.078897, 1.137297),
+	(1, 1.240939, 1.052455, 1.415574),
+	(2, 1.241209, 1.084570, 1.136554),
+	(3, 1.240406, 1.093724, 1.136429),
+	(4, 1.240385, 1.082323, 1.136401),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"###",
+                'threads':"8",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 1.290192, 1.199382, 0.936326),
+	(1, 1.276522, 1.198278, 0.936272),
+	(2, 1.273170, 1.185225, 0.935751),
+	(3, 1.281657, 1.188458, 0.934154),
+	(4, 1.285165, 1.186782, 0.935658),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"###",
+                'threads':"8",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 1.261013, 1.087419, 1.135864),
+	(1, 1.261208, 1.088418, 1.134847),
+	(2, 1.243520, 1.091952, 1.135702),
+	(3, 1.256916, 1.061697, 1.138041),
+	(4, 1.262088, 1.105355, 1.137939),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"###",
+                'threads':"8",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 1.304031, 1.188856, 0.937909),
+	(1, 1.293276, 1.188637, 0.935459),
+	(2, 1.278288, 1.189283, 0.936833),
+	(3, 1.302987, 1.181945, 0.936069),
+	(4, 1.293851, 1.192556, 0.936999),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"###",
+                'threads':"8",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.490107, 0.418154, 0.575664),
+	(1, 0.489843, 0.413785, 0.535501),
+	(2, 0.487683, 0.415899, 0.535610),
+	(3, 0.484014, 0.413119, 0.535279),
+	(4, 0.491381, 0.413503, 0.537277),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"###",
+                'threads':"8",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.486695, 0.445844, 0.494296),
+	(1, 0.481367, 0.455675, 0.497159),
+	(2, 0.481974, 0.481187, 0.496221),
+	(3, 0.479369, 0.425384, 0.495441),
+	(4, 0.478301, 0.457115, 0.494315),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"only_pch",
+                'threads':"8",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 1.434857, 1.168123, 1.455765),
+	(1, 1.436208, 1.190995, 1.496024),
+	(2, 1.439552, 1.161674, 1.455066),
+	(3, 1.436967, 1.180953, 1.494596),
+	(4, 1.435067, 1.162529, 1.456440),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"only_pch",
+                'threads':"8",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 2.854271, 1.448036, 3.456023),
+	(1, 2.864284, 1.464534, 3.456831),
+	(2, 2.860290, 1.477350, 3.377527),
+	(3, 2.857286, 1.458217, 3.417068),
+	(4, 2.855595, 1.464395, 3.376247),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"only_pch",
+                'threads':"8",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 2.095114, 0.776987, 2.855911),
+	(1, 2.099607, 0.795455, 2.856180),
+	(2, 2.095073, 0.792649, 2.896811),
+	(3, 2.094082, 0.789727, 2.897515),
+	(4, 2.100236, 0.781259, 2.774968),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"cpp",
+                'threads':"8",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 1.999042, 1.594807, 1.777251),
+	(1, 1.990498, 1.601683, 1.736392),
+	(2, 2.006314, 1.599276, 1.897380),
+	(3, 1.994969, 1.622299, 1.775973),
+	(4, 1.988203, 1.577170, 1.736153),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"cpp",
+                'threads':"8",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 2.703651, 2.613281, 1.374149),
+	(1, 2.700635, 2.658189, 1.415542),
+	(2, 2.723514, 2.623613, 1.375880),
+	(3, 2.698653, 2.597336, 1.376495),
+	(4, 2.682678, 2.616761, 1.377316),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"parse",
+                'threads':"8",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 2.415923, 1.586213, 1.856706),
+	(1, 2.413466, 1.580113, 1.854297),
+	(2, 2.415569, 1.611288, 1.856562),
+	(3, 2.398350, 1.569858, 1.855165),
+	(4, 2.394427, 1.597305, 1.856311),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"parse",
+                'threads':"8",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 3.166052, 2.593652, 1.456512),
+	(1, 3.196717, 2.604754, 1.456743),
+	(2, 3.101508, 2.536190, 1.456607),
+	(3, 3.174828, 2.591447, 1.456659),
+	(4, 3.201618, 2.596692, 1.457126),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"syntax",
+                'threads':"8",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 3.712949, 1.873531, 2.336073),
+	(1, 3.691984, 1.870964, 2.297376),
+	(2, 3.733735, 1.860346, 2.296816),
+	(3, 3.702759, 1.885194, 2.336534),
+	(4, 3.725368, 1.861191, 2.296488),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"syntax",
+                'threads':"8",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 4.674568, 2.896322, 1.777463),
+	(1, 4.751183, 2.932167, 1.774656),
+	(2, 4.619575, 2.943985, 1.775820),
+	(3, 4.831743, 2.966127, 1.785376),
+	(4, 4.696926, 2.918956, 1.774947),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"syntax",
+                'threads':"8",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 3.619956, 3.111231, 4.057294),
+	(1, 3.634434, 3.079039, 4.176458),
+	(2, 3.619489, 3.150783, 4.138602),
+	(3, 3.621266, 3.104540, 4.058816),
+	(4, 3.608454, 3.122193, 4.057912),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"syntax",
+                'threads':"8",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 8.685876, 3.735123, 2.538354),
+	(1, 8.928202, 3.820031, 2.775907),
+	(2, 9.001593, 3.780341, 2.615105),
+	(3, 8.914982, 3.802006, 2.576587),
+	(4, 8.672801, 3.745031, 2.537300),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"syntax",
+                'threads':"8",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 2.804784, 2.299355, 3.497193),
+	(1, 2.837757, 2.362386, 3.538558),
+	(2, 2.872059, 2.437397, 3.497046),
+	(3, 2.822245, 2.354290, 3.416766),
+	(4, 2.852352, 2.360742, 3.536904),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"syntax",
+                'threads':"8",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 7.840658, 2.912237, 2.176625),
+	(1, 7.786177, 2.867490, 2.098460),
+	(2, 8.029733, 2.900113, 2.094914),
+	(3, 7.787848, 2.850907, 2.096058),
+	(4, 8.009086, 2.890278, 2.097071),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"irgen",
+                'threads':"8",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 3.924865, 1.882098, 2.377105),
+	(1, 3.946578, 1.907070, 2.377384),
+	(2, 3.942964, 1.879682, 2.376026),
+	(3, 3.891159, 1.892699, 2.377748),
+	(4, 3.967042, 1.868087, 2.417171),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"irgen",
+                'threads':"8",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 4.959364, 2.975161, 1.817129),
+	(1, 5.054176, 2.984549, 1.817835),
+	(2, 4.919681, 2.991480, 1.815857),
+	(3, 4.910313, 2.971126, 1.816666),
+	(4, 4.951734, 2.972542, 1.815437),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"only_asm",
+                'threads':"8",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 4.101830, 1.911448, 2.454536),
+	(1, 4.134987, 1.907901, 2.417187),
+	(2, 4.137531, 1.889402, 2.416253),
+	(3, 4.106261, 1.900297, 2.418632),
+	(4, 4.116540, 1.914047, 2.415859),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"only_asm",
+                'threads':"8",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 5.144013, 2.981688, 1.855810),
+	(1, 5.084562, 2.953167, 1.816353),
+	(2, 5.123251, 2.985708, 1.937743),
+	(3, 5.218549, 3.005248, 1.816337),
+	(4, 5.121341, 2.958136, 1.817163),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"only_asm",
+                'threads':"8",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 4.391211, 3.194895, 4.297978),
+	(1, 4.320212, 3.215877, 4.336974),
+	(2, 4.317236, 3.185048, 4.297096),
+	(3, 4.347551, 3.210930, 4.337750),
+	(4, 4.340133, 3.158959, 4.298051),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"only_asm",
+                'threads':"8",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 10.533776, 4.099156, 2.857560),
+	(1, 10.875003, 4.167712, 2.978028),
+	(2, 10.559224, 4.084177, 2.898004),
+	(3, 10.529217, 4.091320, 2.857602),
+	(4, 10.531274, 4.079794, 2.857786),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"only_asm",
+                'threads':"8",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 3.572211, 2.564058, 3.657172),
+	(1, 3.610311, 2.554201, 3.738315),
+	(2, 3.503969, 2.457425, 3.656664),
+	(3, 3.497522, 2.477225, 3.776817),
+	(4, 3.516315, 2.450350, 3.697352),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"only_asm",
+                'threads':"8",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 9.667563, 3.247271, 2.416874),
+	(1, 9.737532, 3.221747, 2.496587),
+	(2, 9.683672, 3.255651, 2.416956),
+	(3, 9.897372, 3.270324, 2.457738),
+	(4, 9.960110, 3.282960, 2.536374),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"only_compile",
+                'threads':"8",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 4.216047, 2.040267, 2.417042),
+	(1, 4.198596, 2.057673, 2.417291),
+	(2, 4.355761, 2.050442, 2.456578),
+	(3, 4.269654, 2.046761, 2.414728),
+	(4, 4.258278, 2.065794, 2.415867),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"only_compile",
+                'threads':"8",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 5.364820, 3.155647, 1.856490),
+	(1, 5.380241, 3.164256, 1.895779),
+	(2, 5.258991, 3.099702, 1.858494),
+	(3, 5.408499, 3.143804, 1.858232),
+	(4, 5.433442, 3.172182, 1.896951),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"only_compile",
+                'threads':"8",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 4.509842, 3.336711, 4.298495),
+	(1, 4.493119, 3.342058, 4.338363),
+	(2, 4.497302, 3.391293, 4.376365),
+	(3, 4.552023, 3.326395, 4.296523),
+	(4, 4.511749, 3.315174, 4.258914),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"only_compile",
+                'threads':"8",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 11.063909, 4.331076, 2.975250),
+	(1, 10.750918, 4.265164, 2.897127),
+	(2, 10.773158, 4.274519, 2.858005),
+	(3, 10.989661, 4.295921, 2.937906),
+	(4, 10.991448, 4.334725, 2.977596),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"only_compile",
+                'threads':"8",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 3.668731, 2.619398, 3.657468),
+	(1, 3.654504, 2.592248, 3.696077),
+	(2, 3.665061, 2.625732, 3.699196),
+	(3, 3.673349, 2.573183, 3.697462),
+	(4, 3.682111, 2.613733, 3.738984),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"only_compile",
+                'threads':"8",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 9.810406, 3.300637, 2.416778),
+	(1, 10.048934, 3.350114, 2.496649),
+	(2, 9.875004, 3.340279, 2.537774),
+	(3, 10.160045, 3.376951, 2.619453),
+	(4, 10.115032, 3.362591, 2.537008),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"all",
+                'threads':"8",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 4.241536, 2.082256, 2.455986),
+	(1, 4.286330, 2.067488, 2.496313),
+	(2, 4.291944, 2.084961, 2.496839),
+	(3, 4.299382, 2.050242, 2.497274),
+	(4, 4.256038, 2.063266, 2.497293),
+]}
+))
+runs.append(( { 'cc':"ccc_clang",
+                'script':"all",
+                'threads':"8",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 5.421218, 3.170845, 1.936421),
+	(1, 5.384884, 3.153992, 1.897806),
+	(2, 5.296851, 3.153219, 1.951468),
+	(3, 5.260795, 3.139369, 2.177163),
+	(4, 5.278498, 3.141780, 1.895288),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"all",
+                'threads':"8",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 4.484287, 3.364861, 4.377941),
+	(1, 4.531560, 3.308326, 4.377562),
+	(2, 4.578896, 3.345062, 4.377173),
+	(3, 4.566615, 3.446052, 4.417550),
+	(4, 4.515315, 3.375575, 4.336788),
+]}
+))
+runs.append(( { 'cc':"ccc_gcc",
+                'script':"all",
+                'threads':"8",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 10.788959, 4.299290, 2.977905),
+	(1, 11.090341, 4.345425, 3.058836),
+	(2, 11.066430, 4.319885, 2.976521),
+	(3, 10.779432, 4.283670, 3.018155),
+	(4, 10.788091, 4.327036, 2.978633),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"all",
+                'threads':"8",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 3.682013, 2.568734, 3.737019),
+	(1, 3.782095, 2.599814, 3.777516),
+	(2, 3.694371, 2.626584, 3.858657),
+	(3, 3.701257, 2.616141, 4.138741),
+	(4, 3.772297, 2.652233, 3.697378),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"all",
+                'threads':"8",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 10.129212, 3.382389, 2.576426),
+	(1, 10.165855, 3.362136, 2.579688),
+	(2, 10.085414, 3.375557, 2.539346),
+	(3, 10.106707, 3.375161, 2.777265),
+	(4, 10.163243, 3.374295, 2.579247),
+]}
+))
diff --git a/www/timing-data/2009-06-26/176.gcc.pdf b/www/timing-data/2009-06-26/176.gcc.pdf
new file mode 100644
index 0000000..50a8bc3
--- /dev/null
+++ b/www/timing-data/2009-06-26/176.gcc.pdf
Binary files differ
diff --git a/www/timing-data/2009-06-26/176.gcc.png b/www/timing-data/2009-06-26/176.gcc.png
new file mode 100644
index 0000000..da10f11
--- /dev/null
+++ b/www/timing-data/2009-06-26/176.gcc.png
Binary files differ
diff --git a/www/timing-data/2009-06-26/176.gcc.txt b/www/timing-data/2009-06-26/176.gcc.txt
new file mode 100644
index 0000000..e8b9c44
--- /dev/null
+++ b/www/timing-data/2009-06-26/176.gcc.txt
@@ -0,0 +1,699 @@
+start = """2009-06-26_10-19"""
+clang  = """/Volumes/Data/ddunbar/llvm.install/bin/clang"""
+gcc = """/usr/bin/gcc-4.2"""
+clang_info = """
+clang version 1.0 (https://ddunbar@llvm.org/svn/llvm-project/cfe/trunk 70266M)
+Target: x86_64-apple-darwin10
+ "/Volumes/Data/ddunbar/llvm.install/bin/../libexec/clang-cc" "-triple" "x86_64-apple-darwin10" "-S" "-disable-free" "-main-file-name" "null" "--relocation-model" "pic" "-pic-level=1" "--disable-fp-elim" "--unwind-tables=1" "--fmath-errno=0" "-mmacosx-version-min=10.6.0" "-fdiagnostics-show-option" "-o" "/var/folders/cl/clrOX6SaG+moCeRKEI4PtU+++TI/-Tmp-/cc-CVKyzP.s" "-x" "c" "/dev/null"
+ "/usr/libexec/gcc/i686-apple-darwin10/4.2.1/as" "-arch" "x86_64" "-force_cpusubtype_ALL" "-o" "/var/folders/cl/clrOX6SaG+moCeRKEI4PtU+++TI/-Tmp-/cc-yeTCzJ.o" "/var/folders/cl/clrOX6SaG+moCeRKEI4PtU+++TI/-Tmp-/cc-CVKyzP.s"
+ "/usr/libexec/gcc/i686-apple-darwin10/4.2.1/ld" "-dynamic" "-arch" "x86_64" "-macosx_version_min" "10.6.0" "-weak_reference_mismatches" "non-weak" "-o" "a.out" "-lcrt1.10.6.o" "-L/usr/lib/gcc/i686-apple-darwin10/4.2.1/x86_64" "-L/usr/lib/gcc/i686-apple-darwin10/4.2.1/x86_64" "-L/usr/lib/i686-apple-darwin10/4.2.1" "-L/usr/lib/gcc/i686-apple-darwin10/4.2.1" "-L/usr/lib/gcc/i686-apple-darwin10/4.2.1" "-L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../../i686-apple-darwin10/4.2.1" "-L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../.." "/var/folders/cl/clrOX6SaG+moCeRKEI4PtU+++TI/-Tmp-/cc-yeTCzJ.o" "-lSystem" "-lgcc"
+"""
+gcc_info = """
+Using built-in specs.
+Target: i686-apple-darwin10
+Configured with: /var/tmp/gcc/gcc-5646~6/src/configure --disable-checking --enable-werror --prefix=/usr --mandir=/share/man --enable-languages=c,objc,c++,obj-c++ --program-transform-name=/^[cg][^.-]*$/s/$/-4.2/ --with-slibdir=/usr/lib --build=i686-apple-darwin10 --with-gxx-include-dir=/include/c++/4.2.1 --program-prefix=i686-apple-darwin10- --host=x86_64-apple-darwin10 --target=i686-apple-darwin10
+Thread model: posix
+gcc version 4.2.1 (Apple Inc. build 5646)
+ "/usr/libexec/gcc/i686-apple-darwin10/4.2.1/cc1" "-quiet" "-imultilib" "x86_64" "-D__DYNAMIC__" "/dev/null" "-fPIC" "-quiet" "-dumpbase" "null" "-mmacosx-version-min=10.6.0" "-m64" "-mtune=core2" "-auxbase" "null" "-o" "/var/folders/cl/clrOX6SaG+moCeRKEI4PtU+++TI/-Tmp-//cc1kQh9M.s"
+ "/usr/libexec/gcc/i686-apple-darwin10/4.2.1/as" "-arch" "x86_64" "-force_cpusubtype_ALL" "-o" "/var/folders/cl/clrOX6SaG+moCeRKEI4PtU+++TI/-Tmp-//ccQcv4DT.o" "/var/folders/cl/clrOX6SaG+moCeRKEI4PtU+++TI/-Tmp-//cc1kQh9M.s"
+ "/usr/libexec/gcc/i686-apple-darwin10/4.2.1/collect2" "-dynamic" "-arch" "x86_64" "-macosx_version_min" "10.6.0" "-weak_reference_mismatches" "non-weak" "-o" "a.out" "-lcrt1.10.6.o" "-L/usr/lib/gcc/i686-apple-darwin10/4.2.1/x86_64" "-L/usr/lib/gcc/i686-apple-darwin10/4.2.1/x86_64" "-L/usr/lib/i686-apple-darwin10/4.2.1" "-L/usr/lib/gcc/i686-apple-darwin10/4.2.1" "-L/usr/lib/gcc/i686-apple-darwin10/4.2.1" "-L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../../i686-apple-darwin10/4.2.1" "-L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../.." "/var/folders/cl/clrOX6SaG+moCeRKEI4PtU+++TI/-Tmp-//ccQcv4DT.o" "-lSystem" "-lgcc" "-lSystem"
+"""
+style = """make"""
+runs = []
+runs.append(( { 'cc':"clang_pch",
+                'script':"null",
+                'threads':"8",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.065445, 0.110578, 0.041286),
+	(1, 0.064915, 0.107837, 0.038992),
+	(2, 0.065191, 0.106475, 0.039233),
+	(3, 0.064924, 0.107004, 0.039142),
+	(4, 0.065260, 0.108901, 0.038903),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"null",
+                'threads':"8",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.066126, 0.112036, 0.040769),
+	(1, 0.065207, 0.108471, 0.038945),
+	(2, 0.065186, 0.107970, 0.038926),
+	(3, 0.065149, 0.108577, 0.039189),
+	(4, 0.065456, 0.109348, 0.039253),
+]}
+))
+runs.append(( { 'cc':"clang_pch",
+                'script':"###",
+                'threads':"8",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.206667, 0.425607, 0.110976),
+	(1, 0.204719, 0.410080, 0.107065),
+	(2, 0.204989, 0.410953, 0.108714),
+	(3, 0.204985, 0.407392, 0.107438),
+	(4, 0.203424, 0.408111, 0.108717),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"###",
+                'threads':"8",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.265631, 0.798950, 0.161461),
+	(1, 0.263615, 0.805888, 0.160308),
+	(2, 0.263824, 0.686335, 0.145542),
+	(3, 0.262625, 0.949966, 0.177774),
+	(4, 0.263458, 0.820937, 0.162473),
+]}
+))
+runs.append(( { 'cc':"clang_pch",
+                'script':"syntax",
+                'threads':"8",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 1.464727, 0.818916, 0.657338),
+	(1, 1.492318, 0.850179, 0.351025),
+	(2, 1.492530, 0.861113, 0.349530),
+	(3, 1.515402, 0.868510, 0.354163),
+	(4, 1.501033, 0.855415, 0.351763),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"syntax",
+                'threads':"8",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 4.339387, 1.362012, 0.808105),
+	(1, 4.327148, 1.319992, 0.794006),
+	(2, 4.327374, 1.320020, 0.793893),
+	(3, 4.319876, 1.319808, 0.787893),
+	(4, 4.329951, 1.344321, 0.796930),
+]}
+))
+runs.append(( { 'cc':"clang_pch",
+                'script':"irgen",
+                'threads':"8",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 3.977307, 1.244670, 0.754129),
+	(1, 3.948981, 1.236009, 0.751078),
+	(2, 3.987417, 1.247336, 0.750608),
+	(3, 3.973621, 1.227822, 0.746016),
+	(4, 3.947019, 1.234332, 0.741703),
+]}
+))
+runs.append(( { 'cc':"clang_pch",
+                'script':"only_asm",
+                'threads':"8",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 6.749291, 1.404829, 1.149195),
+	(1, 6.750589, 1.434406, 1.151828),
+	(2, 6.744767, 1.415306, 1.146994),
+	(3, 6.738192, 1.425966, 1.147283),
+	(4, 6.755475, 1.410701, 1.147945),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"only_asm",
+                'threads':"8",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 9.403397, 1.560103, 1.539962),
+	(1, 9.398348, 1.540148, 1.526404),
+	(2, 9.421496, 1.551876, 1.744563),
+	(3, 9.456310, 1.589165, 1.539901),
+	(4, 9.417963, 1.545186, 1.528347),
+]}
+))
+runs.append(( { 'cc':"clang_pch",
+                'script':"only_compile",
+                'threads':"8",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 8.032359, 1.747400, 1.467280),
+	(1, 7.962687, 1.720919, 1.391892),
+	(2, 7.986155, 1.694753, 1.426921),
+	(3, 7.978081, 1.695359, 1.416691),
+	(4, 7.977982, 1.687328, 1.419240),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"only_compile",
+                'threads':"8",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 10.750102, 1.794398, 1.729777),
+	(1, 10.730841, 1.801150, 1.728536),
+	(2, 10.723943, 1.779271, 1.701177),
+	(3, 10.730824, 1.778987, 1.705904),
+	(4, 10.741052, 1.819326, 1.724089),
+]}
+))
+runs.append(( { 'cc':"clang_pch",
+                'script':"all",
+                'threads':"8",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 8.070440, 1.732707, 1.518658),
+	(1, 8.111095, 1.739793, 1.542162),
+	(2, 8.106386, 1.751412, 1.552584),
+	(3, 8.062847, 1.723786, 1.540230),
+	(4, 8.075670, 1.701288, 1.509957),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"all",
+                'threads':"8",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 10.803240, 1.832409, 1.822466),
+	(1, 10.797956, 1.833142, 1.875121),
+	(2, 10.815192, 1.818826, 1.835845),
+	(3, 10.826268, 1.809307, 1.823997),
+	(4, 10.815709, 1.809185, 1.840403),
+]}
+))
+runs.append(( { 'cc':"clang_pch",
+                'script':"null",
+                'threads':"1",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.060892, 0.065833, 0.155946),
+	(1, 0.060517, 0.064263, 0.133922),
+	(2, 0.060487, 0.064208, 0.133807),
+	(3, 0.060484, 0.063849, 0.134039),
+	(4, 0.060465, 0.064026, 0.133506),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"null",
+                'threads':"1",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.060780, 0.064833, 0.136229),
+	(1, 0.060581, 0.064090, 0.134156),
+	(2, 0.060534, 0.064191, 0.133656),
+	(3, 0.060524, 0.064027, 0.133635),
+	(4, 0.060523, 0.063964, 0.133708),
+]}
+))
+runs.append(( { 'cc':"clang_pch",
+                'script':"###",
+                'threads':"1",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.182177, 0.218261, 0.480256),
+	(1, 0.181253, 0.215086, 0.446808),
+	(2, 0.181503, 0.215725, 0.450776),
+	(3, 0.181187, 0.215330, 0.447765),
+	(4, 0.181176, 0.215050, 0.446595),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"###",
+                'threads':"1",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.236347, 0.301491, 0.583495),
+	(1, 0.235946, 0.299452, 0.568506),
+	(2, 0.235676, 0.298048, 0.559954),
+	(3, 0.235782, 0.298448, 0.561808),
+	(4, 0.235882, 0.299948, 0.563575),
+]}
+))
+runs.append(( { 'cc':"clang_pch",
+                'script':"syntax",
+                'threads':"1",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 1.355242, 0.589876, 2.134110),
+	(1, 1.354939, 0.586215, 2.111487),
+	(2, 1.354329, 0.589784, 2.109410),
+	(3, 1.355080, 0.586192, 2.122027),
+	(4, 1.354042, 0.581133, 2.111260),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"syntax",
+                'threads':"1",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 4.044141, 0.951252, 5.162733),
+	(1, 4.043237, 0.954487, 5.147568),
+	(2, 4.043888, 0.952179, 5.146153),
+	(3, 4.043125, 0.948038, 5.147289),
+	(4, 4.043883, 0.943084, 5.147096),
+]}
+))
+runs.append(( { 'cc':"clang_pch",
+                'script':"irgen",
+                'threads':"1",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 3.444049, 0.848918, 4.534581),
+	(1, 3.444084, 0.854620, 4.525171),
+	(2, 3.444498, 0.862757, 4.598576),
+	(3, 3.442347, 0.856215, 4.518719),
+	(4, 3.443622, 0.866269, 4.532286),
+]}
+))
+runs.append(( { 'cc':"clang_pch",
+                'script':"only_asm",
+                'threads':"1",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 6.065809, 1.034261, 7.390113),
+	(1, 6.064420, 1.027780, 7.396403),
+	(2, 6.065132, 1.030652, 7.471856),
+	(3, 6.060587, 1.031604, 7.337894),
+	(4, 6.064466, 1.050338, 7.360592),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"only_asm",
+                'threads':"1",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 8.960646, 1.236906, 10.456741),
+	(1, 8.957264, 1.234577, 10.357447),
+	(2, 8.956407, 1.237590, 10.352680),
+	(3, 8.957027, 1.241364, 10.398440),
+	(4, 8.956120, 1.239588, 10.355988),
+]}
+))
+runs.append(( { 'cc':"clang_pch",
+                'script':"only_compile",
+                'threads':"1",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 7.277301, 1.238993, 8.973009),
+	(1, 7.277048, 1.246566, 9.027985),
+	(2, 7.277032, 1.226791, 8.944300),
+	(3, 7.277537, 1.242752, 8.970441),
+	(4, 7.278972, 1.238938, 8.989529),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"only_compile",
+                'threads':"1",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 10.081783, 1.335714, 11.707981),
+	(1, 10.081742, 1.344538, 11.682596),
+	(2, 10.079740, 1.330281, 11.681210),
+	(3, 10.074737, 1.324856, 11.632253),
+	(4, 10.075030, 1.350316, 11.633475),
+]}
+))
+runs.append(( { 'cc':"clang_pch",
+                'script':"all",
+                'threads':"1",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 7.377028, 1.265309, 9.283505),
+	(1, 7.376723, 1.253489, 9.102278),
+	(2, 7.376104, 1.255404, 9.094650),
+	(3, 7.376589, 1.260461, 9.246790),
+	(4, 7.377455, 1.255013, 9.095294),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"all",
+                'threads':"1",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 10.172422, 1.355756, 11.797816),
+	(1, 10.173442, 1.357210, 11.808185),
+	(2, 10.173484, 1.346743, 11.781768),
+	(3, 10.170524, 1.352371, 11.749764),
+	(4, 10.171428, 1.362057, 11.760581),
+]}
+))
+runs.append(( { 'cc':"clang_pch",
+                'script':"null",
+                'threads':"2",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.061930, 0.070826, 0.090142),
+	(1, 0.061012, 0.067330, 0.073687),
+	(2, 0.060994, 0.067246, 0.073681),
+	(3, 0.061099, 0.067234, 0.074369),
+	(4, 0.061022, 0.066989, 0.073428),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"null",
+                'threads':"2",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.061591, 0.069558, 0.083641),
+	(1, 0.061059, 0.067184, 0.073565),
+	(2, 0.061076, 0.067165, 0.073724),
+	(3, 0.061096, 0.066990, 0.073567),
+	(4, 0.061062, 0.067199, 0.073221),
+]}
+))
+runs.append(( { 'cc':"clang_pch",
+                'script':"###",
+                'threads':"2",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.185243, 0.234231, 0.256557),
+	(1, 0.184673, 0.232841, 0.245015),
+	(2, 0.184453, 0.232130, 0.244661),
+	(3, 0.184370, 0.230836, 0.243152),
+	(4, 0.184320, 0.231212, 0.244266),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"###",
+                'threads':"2",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.239474, 0.325816, 0.314883),
+	(1, 0.238393, 0.326431, 0.306354),
+	(2, 0.238299, 0.326449, 0.307918),
+	(3, 0.237867, 0.325013, 0.305753),
+	(4, 0.238329, 0.326355, 0.306446),
+]}
+))
+runs.append(( { 'cc':"clang_pch",
+                'script':"syntax",
+                'threads':"2",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 1.386532, 0.594929, 1.083410),
+	(1, 1.385214, 0.591925, 1.071299),
+	(2, 1.385670, 0.596527, 1.071159),
+	(3, 1.385205, 0.595489, 1.071494),
+	(4, 1.385904, 0.590797, 1.067600),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"syntax",
+                'threads':"2",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 4.154845, 0.996239, 2.665919),
+	(1, 4.149680, 0.998786, 2.651533),
+	(2, 4.150974, 1.006984, 2.655142),
+	(3, 4.152007, 1.008280, 2.659809),
+	(4, 4.152938, 1.003288, 2.658114),
+]}
+))
+runs.append(( { 'cc':"clang_pch",
+                'script':"irgen",
+                'threads':"2",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 3.644865, 0.892229, 2.404722),
+	(1, 3.639556, 0.887595, 2.387664),
+	(2, 3.643246, 0.880541, 2.387287),
+	(3, 3.643391, 0.883751, 2.401062),
+	(4, 3.644145, 0.886052, 2.392286),
+]}
+))
+runs.append(( { 'cc':"clang_pch",
+                'script':"only_asm",
+                'threads':"2",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 6.307048, 1.072104, 3.873967),
+	(1, 6.313464, 1.064256, 3.870116),
+	(2, 6.307031, 1.064902, 3.865455),
+	(3, 6.309147, 1.070336, 3.900830),
+	(4, 6.307909, 1.066836, 3.868847),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"only_asm",
+                'threads':"2",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 9.143474, 1.275600, 5.365390),
+	(1, 9.141933, 1.276966, 5.352204),
+	(2, 9.141995, 1.270270, 5.353590),
+	(3, 9.143375, 1.285837, 5.356607),
+	(4, 9.144897, 1.283080, 5.494642),
+]}
+))
+runs.append(( { 'cc':"clang_pch",
+                'script':"only_compile",
+                'threads':"2",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 7.533151, 1.293809, 4.718994),
+	(1, 7.528865, 1.295241, 4.726586),
+	(2, 7.528888, 1.303576, 4.729746),
+	(3, 7.525020, 1.295358, 4.716415),
+	(4, 7.528346, 1.289752, 4.721087),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"only_compile",
+                'threads':"2",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 10.287174, 1.382953, 6.031426),
+	(1, 10.283068, 1.389433, 6.021822),
+	(2, 10.283543, 1.392869, 6.004187),
+	(3, 10.284358, 1.377433, 5.997940),
+	(4, 10.289169, 1.391765, 6.007507),
+]}
+))
+runs.append(( { 'cc':"clang_pch",
+                'script':"all",
+                'threads':"2",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 7.619409, 1.304847, 4.862155),
+	(1, 7.623702, 1.312795, 4.906194),
+	(2, 7.621269, 1.306275, 4.840736),
+	(3, 7.621495, 1.319364, 4.862966),
+	(4, 7.621999, 1.304611, 4.860783),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"all",
+                'threads':"2",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 10.367482, 1.401449, 6.145377),
+	(1, 10.373043, 1.412685, 6.172106),
+	(2, 10.373049, 1.398992, 6.103300),
+	(3, 10.373781, 1.396096, 6.107375),
+	(4, 10.366926, 1.406716, 6.112696),
+]}
+))
+runs.append(( { 'cc':"clang_pch",
+                'script':"null",
+                'threads':"4",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.064425, 0.090165, 0.056533),
+	(1, 0.062985, 0.083843, 0.047935),
+	(2, 0.062983, 0.083616, 0.047921),
+	(3, 0.063039, 0.084145, 0.048157),
+	(4, 0.063026, 0.084462, 0.048349),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"null",
+                'threads':"4",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.064141, 0.088108, 0.053766),
+	(1, 0.063195, 0.084658, 0.048108),
+	(2, 0.063350, 0.085147, 0.049666),
+	(3, 0.063052, 0.083725, 0.047925),
+	(4, 0.063048, 0.083896, 0.048249),
+]}
+))
+runs.append(( { 'cc':"clang_pch",
+                'script':"###",
+                'threads':"4",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.195147, 0.299573, 0.157355),
+	(1, 0.193085, 0.296310, 0.156304),
+	(2, 0.193189, 0.295669, 0.155085),
+	(3, 0.193301, 0.292950, 0.152589),
+	(4, 0.193210, 0.292226, 0.154638),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"###",
+                'threads':"4",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.250242, 0.409797, 0.192336),
+	(1, 0.248762, 0.398072, 0.187157),
+	(2, 0.248680, 0.433130, 0.196985),
+	(3, 0.248853, 0.398547, 0.187603),
+	(4, 0.248648, 0.405913, 0.188482),
+]}
+))
+runs.append(( { 'cc':"clang_pch",
+                'script':"syntax",
+                'threads':"4",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 1.451387, 0.687142, 0.597211),
+	(1, 1.446637, 0.676693, 0.591064),
+	(2, 1.449276, 0.677468, 0.591800),
+	(3, 1.444318, 0.671687, 0.589322),
+	(4, 1.444476, 0.681194, 0.592248),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"syntax",
+                'threads':"4",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 4.264736, 1.132651, 1.424788),
+	(1, 4.261695, 1.143089, 1.416857),
+	(2, 4.264731, 1.138831, 1.422684),
+	(3, 4.264711, 1.140477, 1.417779),
+	(4, 4.260991, 1.147619, 1.419141),
+]}
+))
+runs.append(( { 'cc':"clang_pch",
+                'script':"irgen",
+                'threads':"4",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 3.837203, 1.035623, 1.327415),
+	(1, 3.869828, 1.033702, 1.331966),
+	(2, 3.878679, 1.043199, 1.336928),
+	(3, 3.865577, 1.033086, 1.330496),
+	(4, 3.854501, 1.024146, 1.328011),
+]}
+))
+runs.append(( { 'cc':"clang_pch",
+                'script':"only_asm",
+                'threads':"4",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 6.576067, 1.224910, 2.082887),
+	(1, 6.555647, 1.214275, 2.066679),
+	(2, 6.564496, 1.225676, 2.082281),
+	(3, 6.563023, 1.202289, 2.074234),
+	(4, 6.574312, 1.203879, 2.075939),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"only_asm",
+                'threads':"4",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 9.320291, 1.388042, 2.820785),
+	(1, 9.321238, 1.374025, 2.817582),
+	(2, 9.312721, 1.370752, 2.815972),
+	(3, 9.321560, 1.382464, 2.905396),
+	(4, 9.315155, 1.367614, 2.814303),
+]}
+))
+runs.append(( { 'cc':"clang_pch",
+                'script':"only_compile",
+                'threads':"4",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 7.799699, 1.445598, 2.532217),
+	(1, 7.793440, 1.427494, 2.537293),
+	(2, 7.794819, 1.451267, 2.540644),
+	(3, 7.802867, 1.449885, 2.537256),
+	(4, 7.811558, 1.454217, 2.549762),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"only_compile",
+                'threads':"4",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 10.518288, 1.557086, 3.158364),
+	(1, 10.524251, 1.541390, 3.138438),
+	(2, 10.526541, 1.538375, 3.142480),
+	(3, 10.516332, 1.562218, 3.192590),
+	(4, 10.526898, 1.540009, 3.152245),
+]}
+))
+runs.append(( { 'cc':"clang_pch",
+                'script':"all",
+                'threads':"4",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 7.894470, 1.472428, 2.647063),
+	(1, 7.880948, 1.497803, 2.666059),
+	(2, 7.877924, 1.457295, 2.623934),
+	(3, 7.880090, 1.463151, 2.671976),
+	(4, 7.876586, 1.463586, 2.653038),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"all",
+                'threads':"4",
+                'pch':"no_pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 10.608510, 1.562882, 3.262625),
+	(1, 10.609805, 1.556848, 3.285292),
+	(2, 10.618056, 1.550407, 3.276770),
+	(3, 10.618343, 1.584988, 3.335703),
+	(4, 10.613029, 1.560418, 3.287023),
+]}
+))
+finished = """2009-06-26_10-31"""
diff --git a/www/timing-data/2009-06-26/sketch.pdf b/www/timing-data/2009-06-26/sketch.pdf
new file mode 100644
index 0000000..0bcf4c3
--- /dev/null
+++ b/www/timing-data/2009-06-26/sketch.pdf
Binary files differ
diff --git a/www/timing-data/2009-06-26/sketch.png b/www/timing-data/2009-06-26/sketch.png
new file mode 100644
index 0000000..02a6321
--- /dev/null
+++ b/www/timing-data/2009-06-26/sketch.png
Binary files differ
diff --git a/www/timing-data/2009-06-26/sketch.txt b/www/timing-data/2009-06-26/sketch.txt
new file mode 100644
index 0000000..5e2331c
--- /dev/null
+++ b/www/timing-data/2009-06-26/sketch.txt
@@ -0,0 +1,803 @@
+start = """2009-06-26_10-04"""
+clang  = """/Volumes/Data/ddunbar/llvm.install/bin/clang"""
+gcc = """/usr/bin/gcc-4.2"""
+clang_info = """
+clang version 1.0 (https://ddunbar@llvm.org/svn/llvm-project/cfe/trunk 70266M)
+Target: x86_64-apple-darwin10
+ "/Volumes/Data/ddunbar/llvm.install/bin/../libexec/clang-cc" "-triple" "x86_64-apple-darwin10" "-S" "-disable-free" "-main-file-name" "null" "--relocation-model" "pic" "-pic-level=1" "--disable-fp-elim" "--unwind-tables=1" "--fmath-errno=0" "-mmacosx-version-min=10.6.0" "-fdiagnostics-show-option" "-o" "/var/folders/cl/clrOX6SaG+moCeRKEI4PtU+++TI/-Tmp-/cc-vpL9h3.s" "-x" "c" "/dev/null"
+ "/usr/libexec/gcc/i686-apple-darwin10/4.2.1/as" "-arch" "x86_64" "-force_cpusubtype_ALL" "-o" "/var/folders/cl/clrOX6SaG+moCeRKEI4PtU+++TI/-Tmp-/cc-qdRbcC.o" "/var/folders/cl/clrOX6SaG+moCeRKEI4PtU+++TI/-Tmp-/cc-vpL9h3.s"
+ "/usr/libexec/gcc/i686-apple-darwin10/4.2.1/ld" "-dynamic" "-arch" "x86_64" "-macosx_version_min" "10.6.0" "-weak_reference_mismatches" "non-weak" "-o" "a.out" "-lcrt1.10.6.o" "-L/usr/lib/gcc/i686-apple-darwin10/4.2.1/x86_64" "-L/usr/lib/gcc/i686-apple-darwin10/4.2.1/x86_64" "-L/usr/lib/i686-apple-darwin10/4.2.1" "-L/usr/lib/gcc/i686-apple-darwin10/4.2.1" "-L/usr/lib/gcc/i686-apple-darwin10/4.2.1" "-L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../../i686-apple-darwin10/4.2.1" "-L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../.." "/var/folders/cl/clrOX6SaG+moCeRKEI4PtU+++TI/-Tmp-/cc-qdRbcC.o" "-lSystem" "-lgcc"
+"""
+gcc_info = """
+Using built-in specs.
+Target: i686-apple-darwin10
+Configured with: /var/tmp/gcc/gcc-5646~6/src/configure --disable-checking --enable-werror --prefix=/usr --mandir=/share/man --enable-languages=c,objc,c++,obj-c++ --program-transform-name=/^[cg][^.-]*$/s/$/-4.2/ --with-slibdir=/usr/lib --build=i686-apple-darwin10 --with-gxx-include-dir=/include/c++/4.2.1 --program-prefix=i686-apple-darwin10- --host=x86_64-apple-darwin10 --target=i686-apple-darwin10
+Thread model: posix
+gcc version 4.2.1 (Apple Inc. build 5646)
+ "/usr/libexec/gcc/i686-apple-darwin10/4.2.1/cc1" "-quiet" "-imultilib" "x86_64" "-D__DYNAMIC__" "/dev/null" "-fPIC" "-quiet" "-dumpbase" "null" "-mmacosx-version-min=10.6.0" "-m64" "-mtune=core2" "-auxbase" "null" "-o" "/var/folders/cl/clrOX6SaG+moCeRKEI4PtU+++TI/-Tmp-//ccvaleXF.s"
+ "/usr/libexec/gcc/i686-apple-darwin10/4.2.1/as" "-arch" "x86_64" "-force_cpusubtype_ALL" "-o" "/var/folders/cl/clrOX6SaG+moCeRKEI4PtU+++TI/-Tmp-//ccV9sWHa.o" "/var/folders/cl/clrOX6SaG+moCeRKEI4PtU+++TI/-Tmp-//ccvaleXF.s"
+ "/usr/libexec/gcc/i686-apple-darwin10/4.2.1/collect2" "-dynamic" "-arch" "x86_64" "-macosx_version_min" "10.6.0" "-weak_reference_mismatches" "non-weak" "-o" "a.out" "-lcrt1.10.6.o" "-L/usr/lib/gcc/i686-apple-darwin10/4.2.1/x86_64" "-L/usr/lib/gcc/i686-apple-darwin10/4.2.1/x86_64" "-L/usr/lib/i686-apple-darwin10/4.2.1" "-L/usr/lib/gcc/i686-apple-darwin10/4.2.1" "-L/usr/lib/gcc/i686-apple-darwin10/4.2.1" "-L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../../i686-apple-darwin10/4.2.1" "-L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../.." "/var/folders/cl/clrOX6SaG+moCeRKEI4PtU+++TI/-Tmp-//ccV9sWHa.o" "-lSystem" "-lgcc" "-lSystem"
+"""
+style = """xcb"""
+runs = []
+runs.append(( { 'cc':"clang_pch",
+                'script':"null",
+                'threads':"8",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.454775, 0.429118, 0.894442),
+	(1, 0.456816, 0.263663, 0.473584),
+	(2, 0.455418, 0.263616, 0.471947),
+	(3, 0.457123, 0.264847, 0.476358),
+	(4, 0.455484, 0.265836, 0.472721),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"null",
+                'threads':"8",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.456015, 0.267448, 0.475121),
+	(1, 0.457929, 0.266122, 0.474585),
+	(2, 0.457145, 0.265216, 0.474808),
+	(3, 0.458294, 0.263764, 0.475413),
+	(4, 0.457468, 0.262464, 0.475923),
+]}
+))
+runs.append(( { 'cc':"clang_pch",
+                'script':"###",
+                'threads':"8",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.486632, 0.345058, 0.560472),
+	(1, 0.493027, 0.344064, 0.516340),
+	(2, 0.492830, 0.342958, 0.515723),
+	(3, 0.490442, 0.345107, 0.516254),
+	(4, 0.496280, 0.343245, 0.518030),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"###",
+                'threads':"8",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.514260, 0.372418, 0.544621),
+	(1, 0.513040, 0.372859, 0.536797),
+	(2, 0.512094, 0.370682, 0.534324),
+	(3, 0.512872, 0.373514, 0.535788),
+	(4, 0.514620, 0.371925, 0.536016),
+]}
+))
+runs.append(( { 'cc':"clang_pch",
+                'script':"only_pch",
+                'threads':"8",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.913210, 0.501577, 4.006777),
+	(1, 0.887095, 0.443278, 1.071434),
+	(2, 0.889139, 0.440980, 1.078436),
+	(3, 0.887708, 0.443451, 1.070797),
+	(4, 0.890721, 0.442759, 1.079390),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"only_pch",
+                'threads':"8",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 2.388931, 0.727417, 3.522403),
+	(1, 2.383308, 0.731864, 3.460458),
+	(2, 2.387928, 0.735731, 3.453216),
+	(3, 2.378387, 0.727654, 3.672474),
+	(4, 2.381366, 0.724858, 3.474937),
+]}
+))
+runs.append(( { 'cc':"clang_pch",
+                'script':"syntax",
+                'threads':"8",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 1.037409, 0.613406, 1.215209),
+	(1, 1.040770, 0.634141, 1.205919),
+	(2, 1.034234, 0.618161, 1.210088),
+	(3, 1.035743, 0.626183, 1.194313),
+	(4, 1.035466, 0.621088, 1.181653),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"syntax",
+                'threads':"8",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 3.151380, 2.414929, 4.130644),
+	(1, 3.152197, 2.432369, 4.145959),
+	(2, 3.169057, 2.386287, 4.135253),
+	(3, 3.146057, 2.403489, 4.493451),
+	(4, 3.152363, 2.441579, 4.118788),
+]}
+))
+runs.append(( { 'cc':"clang_pch",
+                'script':"irgen",
+                'threads':"8",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 1.400262, 0.704892, 1.375730),
+	(1, 1.404950, 0.676989, 1.295341),
+	(2, 1.395974, 0.686132, 1.318555),
+	(3, 1.402644, 0.668249, 1.302908),
+	(4, 1.394704, 0.675209, 1.326093),
+]}
+))
+runs.append(( { 'cc':"clang_pch",
+                'script':"only_asm",
+                'threads':"8",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 1.616115, 0.717480, 1.452331),
+	(1, 1.624647, 0.706313, 1.364950),
+	(2, 1.621780, 0.711227, 1.364399),
+	(3, 1.615129, 0.708090, 1.350312),
+	(4, 1.627133, 0.705681, 1.380502),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"only_asm",
+                'threads':"8",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 4.021269, 2.613351, 4.403274),
+	(1, 3.972482, 2.627701, 4.451196),
+	(2, 3.966213, 2.540204, 4.303024),
+	(3, 3.951820, 2.599589, 4.339412),
+	(4, 3.980372, 2.566508, 4.337338),
+]}
+))
+runs.append(( { 'cc':"clang_pch",
+                'script':"only_compile",
+                'threads':"8",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 1.735196, 0.782129, 1.452587),
+	(1, 1.739009, 0.764330, 1.425707),
+	(2, 1.740858, 0.769880, 1.437086),
+	(3, 1.741419, 0.762191, 1.403820),
+	(4, 1.747043, 0.780665, 1.420343),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"only_compile",
+                'threads':"8",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 4.102902, 2.665367, 4.390574),
+	(1, 4.097269, 2.666010, 4.359247),
+	(2, 4.147762, 2.644022, 4.382155),
+	(3, 4.196482, 2.724179, 4.465809),
+	(4, 4.137713, 2.652589, 4.396584),
+]}
+))
+runs.append(( { 'cc':"clang_pch",
+                'script':"all",
+                'threads':"8",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 1.778593, 0.860038, 1.933043),
+	(1, 1.783723, 0.779371, 1.463440),
+	(2, 1.776279, 0.782745, 1.449608),
+	(3, 1.776952, 0.782233, 1.478619),
+	(4, 1.770755, 0.782444, 1.652835),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"all",
+                'threads':"8",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 4.133649, 2.666723, 4.502220),
+	(1, 4.164545, 2.606363, 4.423237),
+	(2, 4.141087, 2.729139, 4.466176),
+	(3, 4.186804, 2.692518, 4.448523),
+	(4, 4.135804, 2.680580, 4.428858),
+]}
+))
+runs.append(( { 'cc':"clang_pch",
+                'script':"null",
+                'threads':"1",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.645824, 0.336540, 1.040349),
+	(1, 0.758601, 0.377669, 1.198545),
+	(2, 0.802384, 0.385620, 1.256802),
+	(3, 0.667186, 0.257789, 0.986552),
+	(4, 0.677381, 0.323771, 1.067715),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"null",
+                'threads':"1",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.654302, 0.326431, 1.043052),
+	(1, 0.610937, 0.202433, 0.879312),
+	(2, 0.821695, 0.241481, 1.127804),
+	(3, 0.633888, 0.315185, 1.009161),
+	(4, 0.606823, 0.209530, 0.874705),
+]}
+))
+runs.append(( { 'cc':"clang_pch",
+                'script':"###",
+                'threads':"1",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.543719, 0.249359, 0.878529),
+	(1, 0.864268, 0.407639, 1.357842),
+	(2, 0.505443, 0.253217, 0.842801),
+	(3, 1.168525, 0.628933, 1.885143),
+	(4, 0.860483, 0.294474, 1.244566),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"###",
+                'threads':"1",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.730678, 0.350816, 1.158314),
+	(1, 0.833076, 0.402332, 1.310570),
+	(2, 0.626271, 0.280957, 0.987633),
+	(3, 0.705011, 0.360332, 1.149777),
+	(4, 0.708342, 0.304606, 1.086816),
+]}
+))
+runs.append(( { 'cc':"clang_pch",
+                'script':"only_pch",
+                'threads':"1",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 1.243931, 0.544136, 1.943868),
+	(1, 1.178064, 0.357476, 1.703040),
+	(2, 0.921374, 0.438177, 1.525808),
+	(3, 1.153771, 0.486733, 1.796961),
+	(4, 0.968192, 0.355170, 1.483673),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"only_pch",
+                'threads':"1",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 2.493859, 0.712226, 4.011872),
+	(1, 2.940300, 0.921172, 4.652497),
+	(2, 2.715094, 0.893861, 4.490923),
+	(3, 2.610419, 0.709403, 4.118227),
+	(4, 2.526798, 0.679792, 3.994116),
+]}
+))
+runs.append(( { 'cc':"clang_pch",
+                'script':"syntax",
+                'threads':"1",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 1.458838, 0.694208, 2.378138),
+	(1, 1.817837, 0.740143, 2.805735),
+	(2, 1.300085, 0.703071, 2.229211),
+	(3, 1.262175, 0.539189, 2.048597),
+	(4, 1.191437, 0.497072, 1.923328),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"syntax",
+                'threads':"1",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 3.120749, 1.789574, 5.789810),
+	(1, 3.273377, 1.967923, 6.133188),
+	(2, 3.037123, 1.733381, 5.596823),
+	(3, 3.042984, 1.730581, 5.650857),
+	(4, 3.188306, 1.759639, 5.884737),
+]}
+))
+runs.append(( { 'cc':"clang_pch",
+                'script':"irgen",
+                'threads':"1",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 1.542473, 0.612384, 2.425046),
+	(1, 1.545307, 0.697333, 2.515996),
+	(2, 1.600507, 0.604696, 2.460228),
+	(3, 1.632270, 0.718514, 2.592235),
+	(4, 1.928976, 0.629692, 2.794199),
+]}
+))
+runs.append(( { 'cc':"clang_pch",
+                'script':"only_asm",
+                'threads':"1",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 1.770525, 0.684705, 2.712227),
+	(1, 1.887006, 0.676721, 2.808092),
+	(2, 1.625953, 0.651827, 2.513331),
+	(3, 1.773543, 0.671273, 2.695842),
+	(4, 1.601478, 0.621009, 2.649159),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"only_asm",
+                'threads':"1",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 4.114128, 2.094426, 7.063334),
+	(1, 4.025352, 1.957465, 6.838969),
+	(2, 3.821735, 1.946024, 6.632936),
+	(3, 3.907138, 2.007547, 7.016114),
+	(4, 4.024595, 2.043679, 6.922250),
+]}
+))
+runs.append(( { 'cc':"clang_pch",
+                'script':"only_compile",
+                'threads':"1",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 2.056124, 0.710399, 3.025185),
+	(1, 1.804336, 0.726053, 2.772563),
+	(2, 1.967191, 0.656225, 2.892478),
+	(3, 2.201167, 1.485126, 3.955987),
+	(4, 1.994297, 0.676570, 2.914002),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"only_compile",
+                'threads':"1",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 4.153794, 1.918740, 6.996844),
+	(1, 4.211883, 1.937034, 7.076586),
+	(2, 4.084567, 1.959342, 6.944548),
+	(3, 4.648222, 2.460079, 7.979059),
+	(4, 4.136109, 1.985068, 6.960107),
+]}
+))
+runs.append(( { 'cc':"clang_pch",
+                'script':"all",
+                'threads':"1",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 2.028821, 0.718882, 3.022737),
+	(1, 1.843870, 0.711606, 2.811073),
+	(2, 1.985330, 0.640222, 2.873062),
+	(3, 2.060936, 0.694181, 3.004850),
+	(4, 1.897412, 0.741471, 2.895000),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"all",
+                'threads':"1",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 4.126488, 1.921937, 7.213964),
+	(1, 4.030952, 2.008876, 6.892632),
+	(2, 4.003183, 1.903866, 6.818411),
+	(3, 4.002316, 1.899865, 6.714604),
+	(4, 4.241685, 2.074201, 7.178083),
+]}
+))
+runs.append(( { 'cc':"clang_pch",
+                'script':"null",
+                'threads':"2",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.438307, 0.207037, 0.506107),
+	(1, 0.443102, 0.205874, 0.504716),
+	(2, 0.439711, 0.209035, 0.506141),
+	(3, 0.436863, 0.206002, 0.504331),
+	(4, 0.439627, 0.206224, 0.505025),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"null",
+                'threads':"2",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.439477, 0.207192, 0.504912),
+	(1, 0.437463, 0.209372, 0.504820),
+	(2, 0.437903, 0.206376, 0.506661),
+	(3, 0.442930, 0.207493, 0.505236),
+	(4, 0.437359, 0.206906, 0.505647),
+]}
+))
+runs.append(( { 'cc':"clang_pch",
+                'script':"###",
+                'threads':"2",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.476966, 0.260986, 0.572957),
+	(1, 0.478184, 0.263035, 0.573059),
+	(2, 0.469230, 0.262187, 0.571016),
+	(3, 0.469081, 0.262310, 0.570270),
+	(4, 0.487872, 0.261247, 0.573296),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"###",
+                'threads':"2",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.500065, 0.287104, 0.600696),
+	(1, 0.490454, 0.288579, 0.599350),
+	(2, 0.489178, 0.290420, 0.595453),
+	(3, 0.504358, 0.305761, 0.621200),
+	(4, 0.488484, 0.284586, 0.593988),
+]}
+))
+runs.append(( { 'cc':"clang_pch",
+                'script':"only_pch",
+                'threads':"2",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.863838, 0.365213, 1.134056),
+	(1, 0.879504, 0.384604, 1.159071),
+	(2, 0.865340, 0.363764, 1.135322),
+	(3, 0.870478, 0.367344, 1.160674),
+	(4, 0.872049, 0.365320, 1.137567),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"only_pch",
+                'threads':"2",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 2.356240, 0.639645, 3.459472),
+	(1, 2.360200, 0.659262, 3.524492),
+	(2, 2.357683, 0.643919, 3.503642),
+	(3, 2.356418, 0.645647, 3.487224),
+	(4, 2.373107, 0.644771, 3.481359),
+]}
+))
+runs.append(( { 'cc':"clang_pch",
+                'script':"syntax",
+                'threads':"2",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 1.020421, 0.527766, 1.342095),
+	(1, 1.015704, 0.514000, 1.336929),
+	(2, 1.012705, 0.511238, 1.355272),
+	(3, 1.017781, 0.525921, 1.395570),
+	(4, 1.018256, 0.517513, 1.810392),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"syntax",
+                'threads':"2",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 3.236664, 1.833475, 5.064647),
+	(1, 3.116394, 1.846229, 4.585106),
+	(2, 3.109082, 1.861524, 4.545915),
+	(3, 3.105011, 1.846408, 4.555086),
+	(4, 3.098872, 1.865976, 4.564655),
+]}
+))
+runs.append(( { 'cc':"clang_pch",
+                'script':"irgen",
+                'threads':"2",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 1.380699, 0.583314, 1.565867),
+	(1, 1.388951, 0.550808, 1.551250),
+	(2, 1.413442, 0.605844, 2.090865),
+	(3, 1.387903, 0.560118, 1.544868),
+	(4, 1.380258, 0.556370, 1.545919),
+]}
+))
+runs.append(( { 'cc':"clang_pch",
+                'script':"only_asm",
+                'threads':"2",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 1.594818, 0.585227, 1.667099),
+	(1, 1.592606, 0.587092, 1.672961),
+	(2, 1.593256, 0.589412, 1.669080),
+	(3, 1.593986, 0.587601, 1.669540),
+	(4, 1.596080, 0.588672, 1.661919),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"only_asm",
+                'threads':"2",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 3.936649, 2.035445, 5.031351),
+	(1, 3.945642, 1.975630, 5.060494),
+	(2, 3.944102, 1.986388, 5.217065),
+	(3, 3.942765, 1.958722, 5.007943),
+	(4, 3.942774, 1.998893, 5.220903),
+]}
+))
+runs.append(( { 'cc':"clang_pch",
+                'script':"only_compile",
+                'threads':"2",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 1.712580, 0.646710, 1.767951),
+	(1, 1.726718, 0.639926, 1.762359),
+	(2, 1.715856, 0.663728, 1.801439),
+	(3, 1.710717, 0.642142, 1.748022),
+	(4, 1.711775, 0.639969, 1.762574),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"only_compile",
+                'threads':"2",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 4.100132, 2.051387, 5.193869),
+	(1, 4.080168, 2.011265, 5.256560),
+	(2, 4.081965, 2.023322, 5.162267),
+	(3, 4.095547, 2.044797, 5.131689),
+	(4, 4.083693, 2.027487, 5.067421),
+]}
+))
+runs.append(( { 'cc':"clang_pch",
+                'script':"all",
+                'threads':"2",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 1.750192, 0.645773, 1.781508),
+	(1, 1.751823, 0.651023, 1.799043),
+	(2, 1.746203, 0.648456, 1.799824),
+	(3, 1.743422, 0.650594, 1.813096),
+	(4, 1.743223, 0.647433, 1.804423),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"all",
+                'threads':"2",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 4.112210, 2.030036, 5.210062),
+	(1, 4.134068, 2.036290, 5.134560),
+	(2, 4.106223, 2.031620, 5.167160),
+	(3, 4.111138, 2.067136, 5.242598),
+	(4, 4.114321, 2.105259, 5.219405),
+]}
+))
+runs.append(( { 'cc':"clang_pch",
+                'script':"null",
+                'threads':"4",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.450242, 0.234466, 0.468920),
+	(1, 0.452251, 0.234237, 0.472734),
+	(2, 0.449428, 0.230498, 0.469181),
+	(3, 0.451854, 0.234653, 0.471594),
+	(4, 0.450034, 0.233853, 0.470746),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"null",
+                'threads':"4",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.451976, 0.237066, 0.471837),
+	(1, 0.451032, 0.232549, 0.469509),
+	(2, 0.450837, 0.235248, 0.469812),
+	(3, 0.451435, 0.236156, 0.471181),
+	(4, 0.454297, 0.235811, 0.472732),
+]}
+))
+runs.append(( { 'cc':"clang_pch",
+                'script':"###",
+                'threads':"4",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.487874, 0.301226, 0.520971),
+	(1, 0.485966, 0.302353, 0.522738),
+	(2, 0.487933, 0.320309, 0.538211),
+	(3, 0.484292, 0.301703, 0.518200),
+	(4, 0.485094, 0.300915, 0.519927),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"###",
+                'threads':"4",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.507246, 0.328269, 0.538592),
+	(1, 0.504679, 0.327246, 0.536575),
+	(2, 0.506116, 0.325455, 0.534917),
+	(3, 0.504966, 0.325033, 0.535512),
+	(4, 0.504264, 0.325877, 0.537850),
+]}
+))
+runs.append(( { 'cc':"clang_pch",
+                'script':"only_pch",
+                'threads':"4",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 0.878871, 0.406325, 1.083290),
+	(1, 0.881664, 0.406706, 1.089465),
+	(2, 0.879953, 0.403525, 1.089816),
+	(3, 0.880059, 0.403838, 1.081420),
+	(4, 0.882767, 0.404104, 1.081738),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"only_pch",
+                'threads':"4",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 2.376690, 0.683461, 3.481408),
+	(1, 2.371811, 0.678423, 3.554769),
+	(2, 2.373430, 0.687361, 3.496073),
+	(3, 2.371478, 0.675612, 3.438700),
+	(4, 2.377505, 0.688872, 3.424400),
+]}
+))
+runs.append(( { 'cc':"clang_pch",
+                'script':"syntax",
+                'threads':"4",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 1.042312, 0.579073, 1.213381),
+	(1, 1.044438, 0.584515, 1.205995),
+	(2, 1.038797, 0.582026, 1.219606),
+	(3, 1.040786, 0.577159, 1.215521),
+	(4, 1.043000, 0.577868, 1.223773),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"syntax",
+                'threads':"4",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 3.231130, 2.567647, 4.158387),
+	(1, 3.235798, 2.498238, 4.418977),
+	(2, 3.238465, 2.529717, 4.211575),
+	(3, 3.239709, 2.495562, 4.156266),
+	(4, 3.231558, 2.493020, 4.108168),
+]}
+))
+runs.append(( { 'cc':"clang_pch",
+                'script':"irgen",
+                'threads':"4",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 1.421647, 0.642906, 1.341418),
+	(1, 1.421549, 0.646429, 1.343189),
+	(2, 1.433072, 0.641680, 1.327081),
+	(3, 1.428600, 0.639478, 1.332256),
+	(4, 1.427077, 0.643784, 1.322933),
+]}
+))
+runs.append(( { 'cc':"clang_pch",
+                'script':"only_asm",
+                'threads':"4",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 1.654124, 0.663628, 1.402498),
+	(1, 1.643467, 0.662131, 1.386214),
+	(2, 1.653972, 0.671458, 1.393807),
+	(3, 1.646365, 0.671024, 1.395913),
+	(4, 1.651021, 0.662302, 1.404011),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"only_asm",
+                'threads':"4",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 4.297588, 2.725803, 4.463298),
+	(1, 4.286029, 2.678946, 4.487945),
+	(2, 4.280374, 2.696217, 4.492516),
+	(3, 4.305121, 2.681000, 4.491615),
+	(4, 4.290141, 2.697022, 4.485084),
+]}
+))
+runs.append(( { 'cc':"clang_pch",
+                'script':"only_compile",
+                'threads':"4",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 1.763493, 0.720256, 1.438810),
+	(1, 1.766202, 0.720674, 1.581947),
+	(2, 1.766634, 0.722865, 1.439302),
+	(3, 1.767231, 0.726466, 1.455122),
+	(4, 1.765071, 0.725319, 1.443411),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"only_compile",
+                'threads':"4",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 4.439486, 2.767478, 4.493862),
+	(1, 4.450584, 2.723827, 4.523759),
+	(2, 4.446754, 2.728436, 4.522514),
+	(3, 4.418589, 2.747071, 4.539960),
+	(4, 4.449233, 2.763071, 4.578583),
+]}
+))
+runs.append(( { 'cc':"clang_pch",
+                'script':"all",
+                'threads':"4",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 1.796239, 0.738339, 1.484091),
+	(1, 1.804887, 0.734832, 1.484408),
+	(2, 1.799010, 0.745599, 1.487400),
+	(3, 1.795834, 0.735356, 1.480006),
+	(4, 1.806408, 0.745381, 1.483771),
+]}
+))
+runs.append(( { 'cc':"gcc",
+                'script':"all",
+                'threads':"4",
+                'pch':"pch" }, 
+{ 'version' : 0,
+  'samples' : [
+	(0, 4.450745, 2.820108, 4.598335),
+	(1, 4.492508, 2.802745, 4.608004),
+	(2, 4.484814, 2.762586, 4.664950),
+	(3, 4.428110, 2.724648, 4.700769),
+	(4, 4.451598, 2.814003, 4.559797),
+]}
+))
+finished = """2009-06-26_10-19"""